Merge "BtHelper: handle BT crash" into main am: e05cc57c9e am: 33f7cab399

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/3163916

Change-Id: I5c921f1409d71e137a3aa90f8e57243d0b427feb
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__riscv64_CtsShimPriv_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__riscv64_CtsShimPriv_apk.asciipb
index e898091..e8e7ec9 100644
--- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__riscv64_CtsShimPriv_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__riscv64_CtsShimPriv_apk.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "9653376"
+    build_id: "11947186"
     target: "CtsShim"
     source_file: "aosp_riscv64/CtsShimPriv.apk"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/frameworks/base"
-  git_branch: "master"
+  git_branch: "main"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__riscv64_CtsShim_apk.asciipb b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__riscv64_CtsShim_apk.asciipb
index 04092366..6113b6a 100644
--- a/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__riscv64_CtsShim_apk.asciipb
+++ b/.prebuilt_info/prebuilt_info_packages_CtsShim_apk__riscv64_CtsShim_apk.asciipb
@@ -1,6 +1,6 @@
 drops {
   android_build_drop {
-    build_id: "9653376"
+    build_id: "11947186"
     target: "CtsShim"
     source_file: "aosp_riscv64/CtsShim.apk"
   }
@@ -8,7 +8,7 @@
   version: ""
   version_group: ""
   git_project: "platform/frameworks/base"
-  git_branch: "master"
+  git_branch: "main"
   transform: TRANSFORM_NONE
   transform_options {
   }
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 96d6f32..a16aa2d 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -405,6 +405,19 @@
     aconfig_declarations: "android.companion.virtualdevice.flags-aconfig",
 }
 
+cc_aconfig_library {
+    name: "android.companion.virtualdevice.flags-aconfig-cc-host",
+    aconfig_declarations: "android.companion.virtualdevice.flags-aconfig",
+    host_supported: true,
+}
+
+cc_aconfig_library {
+    name: "android.companion.virtualdevice.flags-aconfig-cc-test",
+    aconfig_declarations: "android.companion.virtualdevice.flags-aconfig",
+    host_supported: true,
+    mode: "test",
+}
+
 java_aconfig_library {
     name: "android.companion.virtualdevice.flags-aconfig-java",
     aconfig_declarations: "android.companion.virtualdevice.flags-aconfig",
diff --git a/Ravenwood.bp b/Ravenwood.bp
index 11da20a..87f1124 100644
--- a/Ravenwood.bp
+++ b/Ravenwood.bp
@@ -38,8 +38,8 @@
 
         "--out-impl-jar $(location ravenwood.jar) " +
 
-        "--gen-keep-all-file $(location hoststubgen_keep_all.txt) " +
-        "--gen-input-dump-file $(location hoststubgen_dump.txt) " +
+        "--gen-keep-all-file $(location hoststubgen_framework-minus-apex_keep_all.txt) " +
+        "--gen-input-dump-file $(location hoststubgen_framework-minus-apex_dump.txt) " +
 
         "--in-jar $(location :framework-minus-apex-for-hoststubgen) " +
         "--policy-override-file $(location :ravenwood-framework-policies) " +
@@ -54,14 +54,14 @@
         "ravenwood.jar",
 
         // Following files are created just as FYI.
-        "hoststubgen_keep_all.txt",
-        "hoststubgen_dump.txt",
+        "hoststubgen_framework-minus-apex_keep_all.txt",
+        "hoststubgen_framework-minus-apex_dump.txt",
 
         "hoststubgen_framework-minus-apex.log",
         "hoststubgen_framework-minus-apex_stats.csv",
         "hoststubgen_framework-minus-apex_apis.csv",
     ],
-    visibility: ["//visibility:private"],
+    defaults: ["ravenwood-internal-only-visibility-genrule"],
 }
 
 // Extract the impl jar from "framework-minus-apex.ravenwood-base" for subsequent build rules.
@@ -79,43 +79,6 @@
     ],
 }
 
-// Extract the stats file.
-genrule {
-    name: "framework-minus-apex.ravenwood.stats",
-    defaults: ["ravenwood-internal-only-visibility-genrule"],
-    cmd: "cp $(in) $(out)",
-    srcs: [
-        ":framework-minus-apex.ravenwood-base{hoststubgen_framework-minus-apex_stats.csv}",
-    ],
-    out: [
-        "hoststubgen_framework-minus-apex_stats.csv",
-    ],
-}
-
-genrule {
-    name: "framework-minus-apex.ravenwood.apis",
-    defaults: ["ravenwood-internal-only-visibility-genrule"],
-    cmd: "cp $(in) $(out)",
-    srcs: [
-        ":framework-minus-apex.ravenwood-base{hoststubgen_framework-minus-apex_apis.csv}",
-    ],
-    out: [
-        "hoststubgen_framework-minus-apex_apis.csv",
-    ],
-}
-
-genrule {
-    name: "framework-minus-apex.ravenwood.keep_all",
-    defaults: ["ravenwood-internal-only-visibility-genrule"],
-    cmd: "cp $(in) $(out)",
-    srcs: [
-        ":framework-minus-apex.ravenwood-base{hoststubgen_keep_all.txt}",
-    ],
-    out: [
-        "hoststubgen_framework-minus-apex_keep_all.txt",
-    ],
-}
-
 java_library {
     name: "services.core-for-hoststubgen",
     installable: false, // host only jar.
@@ -138,8 +101,8 @@
 
         "--out-impl-jar $(location ravenwood.jar) " +
 
-        "--gen-keep-all-file $(location hoststubgen_keep_all.txt) " +
-        "--gen-input-dump-file $(location hoststubgen_dump.txt) " +
+        "--gen-keep-all-file $(location hoststubgen_services.core_keep_all.txt) " +
+        "--gen-input-dump-file $(location hoststubgen_services.core_dump.txt) " +
 
         "--in-jar $(location :services.core-for-hoststubgen) " +
         "--policy-override-file $(location :ravenwood-services-policies) " +
@@ -154,14 +117,14 @@
         "ravenwood.jar",
 
         // Following files are created just as FYI.
-        "hoststubgen_keep_all.txt",
-        "hoststubgen_dump.txt",
+        "hoststubgen_services.core_keep_all.txt",
+        "hoststubgen_services.core_dump.txt",
 
         "hoststubgen_services.core.log",
         "hoststubgen_services.core_stats.csv",
         "hoststubgen_services.core_apis.csv",
     ],
-    visibility: ["//visibility:private"],
+    defaults: ["ravenwood-internal-only-visibility-genrule"],
 }
 
 java_genrule {
@@ -176,150 +139,42 @@
     ],
 }
 
-// Extract the stats file.
-genrule {
-    name: "services.core.ravenwood.stats",
-    defaults: ["ravenwood-internal-only-visibility-genrule"],
-    cmd: "cp $(in) $(out)",
-    srcs: [
-        ":services.core.ravenwood-base{hoststubgen_services.core_stats.csv}",
-    ],
-    out: [
-        "hoststubgen_services.core_stats.csv",
-    ],
-}
-
-genrule {
-    name: "services.core.ravenwood.apis",
-    defaults: ["ravenwood-internal-only-visibility-genrule"],
-    cmd: "cp $(in) $(out)",
-    srcs: [
-        ":services.core.ravenwood-base{hoststubgen_services.core_apis.csv}",
-    ],
-    out: [
-        "hoststubgen_services.core_apis.csv",
-    ],
-}
-
-genrule {
-    name: "services.core.ravenwood.keep_all",
-    defaults: ["ravenwood-internal-only-visibility-genrule"],
-    cmd: "cp $(in) $(out)",
-    srcs: [
-        ":services.core.ravenwood-base{hoststubgen_keep_all.txt}",
-    ],
-    out: [
-        "hoststubgen_services.core_keep_all.txt",
-    ],
-}
-
 java_library {
     name: "services.core.ravenwood-jarjar",
+    defaults: ["ravenwood-internal-only-visibility-java"],
     installable: false,
     static_libs: [
         "services.core.ravenwood",
     ],
     jarjar_rules: ":ravenwood-services-jarjar-rules",
-    visibility: ["//visibility:private"],
-}
-
-java_library {
-    name: "services.fakes.ravenwood-jarjar",
-    installable: false,
-    srcs: [":services.fakes-sources"],
-    libs: [
-        "ravenwood-framework",
-        "services.core.ravenwood",
-    ],
-    jarjar_rules: ":ravenwood-services-jarjar-rules",
-    visibility: ["//visibility:private"],
-}
-
-java_library {
-    name: "mockito-ravenwood-prebuilt",
-    installable: false,
-    static_libs: [
-        "mockito-robolectric-prebuilt",
-    ],
-}
-
-java_library {
-    name: "inline-mockito-ravenwood-prebuilt",
-    installable: false,
-    static_libs: [
-        "inline-mockito-robolectric-prebuilt",
-    ],
 }
 
 // Jars in "ravenwood-runtime" are set to the classpath, sorted alphabetically.
 // Rename some of the dependencies to make sure they're included in the intended order.
-java_genrule {
+// Also apply jarjar.
+java_library {
     name: "100-framework-minus-apex.ravenwood",
-    cmd: "cp $(in) $(out)",
-    srcs: [":framework-minus-apex.ravenwood"],
-    out: ["100-framework-minus-apex.ravenwood.jar"],
-    visibility: ["//visibility:private"],
+    defaults: ["ravenwood-internal-only-visibility-java"],
+    static_libs: [
+        "framework-minus-apex.ravenwood",
+    ],
+    sdk_version: "core_platform",
+    jarjar_rules: ":ravenwood-framework-jarjar-rules",
 }
 
 java_genrule {
     // Use 200 to make sure it comes before the mainline stub ("all-updatable...").
     name: "200-kxml2-android",
+    defaults: ["ravenwood-internal-only-visibility-genrule"],
     cmd: "cp $(in) $(out)",
     srcs: [":kxml2-android"],
     out: ["200-kxml2-android.jar"],
-    visibility: ["//visibility:private"],
 }
 
 java_genrule {
     name: "z00-all-updatable-modules-system-stubs",
+    defaults: ["ravenwood-internal-only-visibility-genrule"],
     cmd: "cp $(in) $(out)",
     srcs: [":all-updatable-modules-system-stubs"],
     out: ["z00-all-updatable-modules-system-stubs.jar"],
-    visibility: ["//visibility:private"],
-}
-
-android_ravenwood_libgroup {
-    name: "ravenwood-runtime",
-    libs: [
-        "100-framework-minus-apex.ravenwood",
-        "200-kxml2-android",
-
-        "ravenwood-runtime-common-ravenwood",
-
-        "android.test.mock.ravenwood",
-        "ravenwood-helper-runtime",
-        "hoststubgen-helper-runtime.ravenwood",
-        "services.core.ravenwood-jarjar",
-        "services.fakes.ravenwood-jarjar",
-
-        // Provide runtime versions of utils linked in below
-        "junit",
-        "truth",
-        "flag-junit",
-        "ravenwood-framework",
-        "ravenwood-junit-impl",
-        "ravenwood-junit-impl-flag",
-        "mockito-ravenwood-prebuilt",
-        "inline-mockito-ravenwood-prebuilt",
-
-        // It's a stub, so it should be towards the end.
-        "z00-all-updatable-modules-system-stubs",
-    ],
-    jni_libs: [
-        "libandroid_runtime",
-        "libravenwood_runtime",
-    ],
-}
-
-android_ravenwood_libgroup {
-    name: "ravenwood-utils",
-    libs: [
-        "junit",
-        "truth",
-        "flag-junit",
-        "ravenwood-framework",
-        "ravenwood-junit",
-        "mockito-ravenwood-prebuilt",
-        "inline-mockito-ravenwood-prebuilt",
-    ],
 }
diff --git a/SQLITE_OWNERS b/SQLITE_OWNERS
index 1ff72e7..783a0b6 100644
--- a/SQLITE_OWNERS
+++ b/SQLITE_OWNERS
@@ -1,2 +1,9 @@
+# Android platform SQLite owners are responsible for:
+# 1. Periodically updating libsqlite from upstream sqlite.org.
+# 2. Escalating libsqlite bug reports to upstream sqlite.org.
+# 3. Addressing bugs, performance regressions, and feature requests
+#    in Android SDK SQLite wrappers (android.database.sqlite.*).
+# 4. Reviewing proposed changes to said Android SDK SQLite wrappers.
+
 shayba@google.com
 shombert@google.com
diff --git a/WEAR_OWNERS b/WEAR_OWNERS
index 4ffb239..52c07e0 100644
--- a/WEAR_OWNERS
+++ b/WEAR_OWNERS
@@ -12,3 +12,4 @@
 shijianli@google.com
 latkin@google.com
 djsollen@google.com
+hdhabu@google.com
\ No newline at end of file
diff --git a/apct-tests/perftests/core/src/android/permission/AppOpsPerfTest.kt b/apct-tests/perftests/core/src/android/permission/AppOpsPerfTest.kt
deleted file mode 100644
index daf991c..0000000
--- a/apct-tests/perftests/core/src/android/permission/AppOpsPerfTest.kt
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.permission
-
-import android.app.AppOpsManager
-import android.content.Context
-import android.perftests.utils.PerfStatusReporter
-import androidx.test.core.app.ApplicationProvider
-import androidx.test.filters.LargeTest
-import org.junit.Before
-import org.junit.Rule
-import org.junit.Test
-
-@LargeTest
-/**
- * Performance unit tests for app ops APIs.
- *
- * The APIs under test are used for checking permissions and tracking permission accesses and are
- * therefore invoked frequently by the system for all permission-protected data accesses, hence
- * these APIs should be monitored closely for performance.
- */
-class AppOpsPerfTest {
-    @get:Rule val perfStatusReporter = PerfStatusReporter()
-    private lateinit var appOpsManager: AppOpsManager
-    private lateinit var opPackageName: String
-    private var opPackageUid: Int = 0
-
-    @Before
-    fun setUp() {
-        val context: Context = ApplicationProvider.getApplicationContext()
-        appOpsManager = context.getSystemService<AppOpsManager>(AppOpsManager::class.java)!!
-        opPackageName = context.getOpPackageName()
-        opPackageUid = context.getPackageManager().getPackageUid(opPackageName, 0)
-    }
-
-    @Test
-    fun testNoteOp() {
-        val state = perfStatusReporter.benchmarkState
-        while (state.keepRunning()) {
-            appOpsManager.noteOp(
-                    AppOpsManager.OPSTR_FINE_LOCATION,
-                    opPackageUid,
-                    opPackageName,
-                    null,
-                    null
-            )
-        }
-    }
-
-    @Test
-    fun testUnsafeCheckOp() {
-        val state = perfStatusReporter.benchmarkState
-        while (state.keepRunning()) {
-            appOpsManager.unsafeCheckOp(
-                    AppOpsManager.OPSTR_FINE_LOCATION,
-                    opPackageUid,
-                    opPackageName
-            )
-        }
-    }
-}
diff --git a/apct-tests/perftests/core/src/android/permission/OWNERS b/apct-tests/perftests/core/src/android/permission/OWNERS
deleted file mode 100644
index b4b2b9e..0000000
--- a/apct-tests/perftests/core/src/android/permission/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-# Bug component: 137825
-
-include platform/frameworks/base:/core/java/android/permission/OWNERS
\ No newline at end of file
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
index 762e2af..0750c8d 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
@@ -145,7 +145,9 @@
                 Intent.ACTION_USER_STARTED,
                 Intent.ACTION_MEDIA_MOUNTED,
                 Intent.ACTION_USER_UNLOCKED,
-                Intent.ACTION_USER_STOPPED);
+                Intent.ACTION_USER_STOPPED,
+                Intent.ACTION_PROFILE_AVAILABLE,
+                Intent.ACTION_PROFILE_UNAVAILABLE);
         mUserSwitchWaiter = new UserSwitchWaiter(TAG, TIMEOUT_IN_SECOND);
         removeAnyPreviousTestUsers();
         if (mAm.getCurrentUser() != UserHandle.USER_SYSTEM) {
@@ -1230,6 +1232,255 @@
         }
     }
 
+    /** Tests creating a private profile. */
+    @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+    public void createPrivateProfile() throws RemoteException {
+        while (mRunner.keepRunning()) {
+            Log.i(TAG, "Starting timer");
+
+            final int userId = createPrivateProfileUser();
+
+            mRunner.pauseTiming();
+            Log.i(TAG, "Stopping timer");
+            removeUser(userId);
+            waitCoolDownPeriod();
+            mRunner.resumeTimingForNextIteration();
+        }
+    }
+
+    /**
+     * Tests creating and starting a newly created private profile. This test waits for the
+     * {@link Intent.ACTION_USER_STARTED} to be received.
+     */
+    @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+    public void createAndStartPrivateProfile_realistic() throws RemoteException {
+        while (mRunner.keepRunning()) {
+            Log.i(TAG, "Starting timer");
+            final int userId = createPrivateProfileUser();
+
+            // Don't use this.startUserInBackgroundAndWaitForUnlock() since only waiting until
+            // ACTION_USER_STARTED.
+            runThenWaitForBroadcasts(userId, () -> {
+                mIam.startUserInBackground(userId);
+            }, Intent.ACTION_USER_STARTED);
+
+            mRunner.pauseTiming();
+            Log.i(TAG, "Stopping timer");
+            removeUser(userId);
+            waitCoolDownPeriod();
+            mRunner.resumeTimingForNextIteration();
+        }
+    }
+
+    /** Tests for stopping the private profile. */
+    @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+    public void privateProfileStopped() throws RemoteException {
+        while (mRunner.keepRunning()) {
+            mRunner.pauseTiming();
+            final int userId = createPrivateProfileUser();
+            runThenWaitForBroadcasts(userId, () -> {
+                startUserInBackgroundAndWaitForUnlock(userId);
+            }, Intent.ACTION_MEDIA_MOUNTED);
+
+            mRunner.resumeTiming();
+            Log.i(TAG, "Starting timer");
+
+            stopUser(userId);
+
+            mRunner.pauseTiming();
+            Log.i(TAG, "Stopping timer");
+            removeUser(userId);
+            mRunner.resumeTimingForNextIteration();
+        }
+    }
+
+    /**
+     * Tests unlocking a newly-created private profile using the
+     * {@link UserManager#requestQuietModeEnabled} api.
+     */
+    @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+    public void privateProfileUnlock() throws RemoteException {
+
+        while (mRunner.keepRunning()) {
+            mRunner.pauseTiming();
+            final int userId = createPrivateProfileUser();
+            startUserInBackgroundAndWaitForUnlock(userId);
+            mUm.requestQuietModeEnabled(true, UserHandle.of(userId));
+            waitCoolDownPeriod();
+            mRunner.resumeTiming();
+            Log.i(TAG, "Starting timer");
+
+            mUm.requestQuietModeEnabled(false, UserHandle.of(userId));
+
+            mRunner.pauseTiming();
+            Log.i(TAG, "Stopping timer");
+            removeUser(userId);
+            mRunner.resumeTimingForNextIteration();
+        }
+    }
+
+    /**
+     * Tests unlocking a newly-created private profile using the
+     * {@link UserManager#requestQuietModeEnabled} api and waiting for the
+     * {@link Intent.ACTION_PROFILE_AVAILABLE} to be received.
+     */
+    @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+    public void privateProfileUnlock_realistic() throws RemoteException {
+
+        while (mRunner.keepRunning()) {
+            mRunner.pauseTiming();
+            final int userId = createPrivateProfileUser();
+            startUserInBackgroundAndWaitForUnlock(userId);
+            mUm.requestQuietModeEnabled(true, UserHandle.of(userId));
+            waitCoolDownPeriod();
+            mRunner.resumeTiming();
+            Log.i(TAG, "Starting timer");
+
+            runThenWaitForBroadcasts(userId, () -> {
+                mUm.requestQuietModeEnabled(false, UserHandle.of(userId));
+            }, Intent.ACTION_PROFILE_AVAILABLE);
+
+            mRunner.pauseTiming();
+            Log.i(TAG, "Stopping timer");
+            removeUser(userId);
+            mRunner.resumeTimingForNextIteration();
+        }
+    }
+
+    /**
+     * Tests locking a newly-created private profile using the
+     * {@link UserManager#requestQuietModeEnabled} api.
+     */
+    @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+    public void privateProfileLock() throws RemoteException {
+
+        while (mRunner.keepRunning()) {
+            mRunner.pauseTiming();
+            final int userId = createPrivateProfileUser();
+            startUserInBackgroundAndWaitForUnlock(userId);
+            mRunner.resumeTiming();
+            Log.i(TAG, "Starting timer");
+
+            mUm.requestQuietModeEnabled(true, UserHandle.of(userId));
+
+            mRunner.pauseTiming();
+            Log.i(TAG, "Stopping timer");
+            removeUser(userId);
+            mRunner.resumeTimingForNextIteration();
+        }
+    }
+
+    /**
+     * Tests locking a newly-created private profile using the
+     * {@link UserManager#requestQuietModeEnabled} api and waiting for the
+     * {@link Intent.ACTION_PROFILE_UNAVAILABLE} to be received.
+     */
+    @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+    public void privateProfileLock_realistic() throws RemoteException {
+
+        while (mRunner.keepRunning()) {
+            mRunner.pauseTiming();
+            final int userId = createPrivateProfileUser();
+            startUserInBackgroundAndWaitForUnlock(userId);
+            mRunner.resumeTiming();
+            Log.i(TAG, "Starting timer");
+
+            runThenWaitForBroadcasts(userId, () -> {
+                mUm.requestQuietModeEnabled(true, UserHandle.of(userId));
+            }, Intent.ACTION_PROFILE_UNAVAILABLE);
+
+
+            mRunner.pauseTiming();
+            Log.i(TAG, "Stopping timer");
+            removeUser(userId);
+            mRunner.resumeTimingForNextIteration();
+        }
+    }
+
+    /** Tests removing a newly-created private profile */
+    @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+    public void privateProfileRemove() throws RemoteException {
+        while (mRunner.keepRunning()) {
+            mRunner.pauseTiming();
+            final int userId = createPrivateProfileUser();
+            mRunner.resumeTiming();
+            Log.i(TAG, "Starting timer");
+            removeUser(userId);
+            mRunner.pauseTiming();
+            Log.i(TAG, "Stopping timer");
+            mRunner.resumeTimingForNextIteration();
+        }
+    }
+
+    /** Tests installing a pre-existing app in a private profile. */
+    @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+    public void privateProfileInstall() throws RemoteException {
+        while (mRunner.keepRunning()) {
+            mRunner.pauseTiming();
+            final int userId = createPrivateProfileUser();
+            startUserInBackgroundAndWaitForUnlock(userId);
+            mRunner.resumeTiming();
+            Log.i(TAG, "Starting timer");
+
+            installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
+
+            mRunner.pauseTiming();
+            Log.i(TAG, "Stopping timer");
+            removeUser(userId);
+            waitCoolDownPeriod();
+            mRunner.resumeTimingForNextIteration();
+        }
+    }
+
+    /**
+     * Tests creating a new private profile, starting it, installing an app, and launching that app
+     * in it.
+     */
+    @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+    public void privateProfileCreateStartInstallAndLaunchApp() throws RemoteException {
+        while (mRunner.keepRunning()) {
+            mRunner.pauseTiming();
+            WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null);
+            mRunner.resumeTiming();
+            Log.i(TAG, "Starting timer");
+
+            final int userId = createPrivateProfileUser();
+            startUserInBackgroundAndWaitForUnlock(userId);
+            installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
+            startApp(userId, DUMMY_PACKAGE_NAME);
+
+            mRunner.pauseTiming();
+            Log.i(TAG, "Stopping timer");
+            removeUser(userId);
+            waitCoolDownPeriod();
+            mRunner.resumeTimingForNextIteration();
+        }
+    }
+
+    /**
+     * Tests starting & launching an already-installed app in a private profile.
+     */
+    @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS)
+    public void privateProfileStartAndLaunchApp() throws RemoteException {
+        while (mRunner.keepRunning()) {
+            mRunner.pauseTiming();
+            final int userId = createPrivateProfileUser();
+            WindowManagerGlobal.getWindowManagerService().dismissKeyguard(null, null);
+            installPreexistingApp(userId, DUMMY_PACKAGE_NAME);
+            mRunner.resumeTiming();
+            Log.i(TAG, "Starting timer");
+
+            startUserInBackgroundAndWaitForUnlock(userId);
+            startApp(userId, DUMMY_PACKAGE_NAME);
+
+            mRunner.pauseTiming();
+            Log.i(TAG, "Stopping timer");
+            removeUser(userId);
+            waitCoolDownPeriod();
+            mRunner.resumeTimingForNextIteration();
+        }
+    }
+
     /** Creates a new user, returning its userId. */
     private int createUserNoFlags() {
         return createUserWithFlags(/* flags= */ 0);
@@ -1252,6 +1503,18 @@
         return userInfo.id;
     }
 
+    /** Creates a private profile under the current user, returning its userId. */
+    private int createPrivateProfileUser() {
+        final UserInfo userInfo = mUm.createProfileForUser(TEST_USER_NAME,
+                UserManager.USER_TYPE_PROFILE_PRIVATE, /* flags */ 0, mAm.getCurrentUser());
+        attestFalse(
+                "Creating a private profile failed. Most likely there is already a pre-existing "
+                        + "private profile on the device.",
+                userInfo == null);
+        mUsersToRemove.add(userInfo.id);
+        return userInfo.id;
+    }
+
     /**
      * Start user in background and wait for it to unlock by waiting for
      * UserState.mUnlockProgress.finish().
diff --git a/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java b/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java
index d80d3c8..b955032 100644
--- a/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java
+++ b/apct-tests/perftests/windowmanager/src/android/wm/RelayoutPerfTest.java
@@ -18,11 +18,8 @@
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
-import static com.android.window.flags.Flags.windowSessionRelayoutInfo;
-
 import android.app.Activity;
 import android.content.Context;
-import android.os.Bundle;
 import android.os.RemoteException;
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
@@ -131,7 +128,6 @@
         final MergedConfiguration mOutMergedConfiguration = new MergedConfiguration();
         final InsetsState mOutInsetsState = new InsetsState();
         final InsetsSourceControl.Array mOutControls = new InsetsSourceControl.Array();
-        final Bundle mOutBundle = windowSessionRelayoutInfo() ? null : new Bundle();
         final WindowRelayoutResult mOutRelayoutResult;
         final IWindow mWindow;
         final View mView;
@@ -152,26 +148,16 @@
             mHeight = mView.getMeasuredHeight();
             mOutSurfaceControl = mView.getViewRootImpl().getSurfaceControl();
             mViewVisibility = visibilitySupplier;
-            mOutRelayoutResult = windowSessionRelayoutInfo()
-                    ? new WindowRelayoutResult(mOutFrames, mOutMergedConfiguration,
-                            mOutSurfaceControl, mOutInsetsState, mOutControls)
-                    : null;
+            mOutRelayoutResult = new WindowRelayoutResult(mOutFrames, mOutMergedConfiguration,
+                            mOutSurfaceControl, mOutInsetsState, mOutControls);
         }
 
         void runBenchmark(BenchmarkState state) throws RemoteException {
             final IWindowSession session = WindowManagerGlobal.getWindowSession();
             while (state.keepRunning()) {
                 mRelayoutSeq++;
-                if (windowSessionRelayoutInfo()) {
-                    session.relayout(mWindow, mParams, mWidth, mHeight,
-                            mViewVisibility.getAsInt(), mFlags, mRelayoutSeq, 0 /* lastSyncSeqId */,
-                            mOutRelayoutResult);
-                } else {
-                    session.relayoutLegacy(mWindow, mParams, mWidth, mHeight,
-                            mViewVisibility.getAsInt(), mFlags, mRelayoutSeq, 0 /* lastSyncSeqId */,
-                            mOutFrames, mOutMergedConfiguration, mOutSurfaceControl,
-                            mOutInsetsState, mOutControls, mOutBundle);
-                }
+                session.relayout(mWindow, mParams, mWidth, mHeight, mViewVisibility.getAsInt(),
+                        mFlags, mRelayoutSeq, 0 /* lastSyncSeqId */, mOutRelayoutResult);
             }
         }
     }
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 b982d12..dfa7206 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -4925,7 +4925,6 @@
             sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
             sdFilter.addAction(Intent.ACTION_USER_STOPPED);
             if (mStartUserBeforeScheduledAlarms) {
-                sdFilter.addAction(Intent.ACTION_LOCKED_BOOT_COMPLETED);
                 sdFilter.addAction(Intent.ACTION_USER_REMOVED);
             }
             sdFilter.addAction(Intent.ACTION_UID_REMOVED);
@@ -4958,14 +4957,6 @@
                             mTemporaryQuotaReserve.removeForUser(userHandle);
                         }
                         return;
-                    case Intent.ACTION_LOCKED_BOOT_COMPLETED:
-                        final int handle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
-                        if (handle >= 0) {
-                            if (mStartUserBeforeScheduledAlarms) {
-                                mUserWakeupStore.onUserStarted(handle);
-                            }
-                        }
-                        return;
                     case Intent.ACTION_USER_REMOVED:
                         final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
                         if (user >= 0) {
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/UserWakeupStore.java b/apex/jobscheduler/service/java/com/android/server/alarm/UserWakeupStore.java
index 7fc630c..dc5e341 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/UserWakeupStore.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/UserWakeupStore.java
@@ -98,12 +98,7 @@
      */
     @GuardedBy("mUserWakeupLock")
     private final SparseLongArray mUserStarts = new SparseLongArray();
-    /**
-     * A list of users that are in a phase after they have been started but before alarms were
-     * initialized.
-     */
-    @GuardedBy("mUserWakeupLock")
-    private final SparseLongArray mStartingUsers = new SparseLongArray();
+
     private Executor mBackgroundExecutor;
     private static final File USER_WAKEUP_DIR = new File(Environment.getDataSystemDirectory(),
             ROOT_DIR_NAME);
@@ -124,9 +119,6 @@
      */
     public void addUserWakeup(int userId, long alarmTime) {
         synchronized (mUserWakeupLock) {
-            // This should not be needed, but if an app in the user is scheduling an alarm clock, we
-            // consider the user start complete. There is a dedicated removal when user is started.
-            mStartingUsers.delete(userId);
             mUserStarts.put(userId, alarmTime - BUFFER_TIME_MS + getUserWakeupOffset());
         }
         updateUserListFile();
@@ -192,23 +184,10 @@
     }
 
     /**
-     * Move user from wakeup list to starting user list.
+     * Remove scheduled user wakeup from the list when it is started.
      */
     public void onUserStarting(int userId) {
-        synchronized (mUserWakeupLock) {
-            final long wakeup = getWakeupTimeForUser(userId);
-            if (wakeup >= 0) {
-                mStartingUsers.put(userId, wakeup);
-                mUserStarts.delete(userId);
-            }
-        }
-    }
-
-    /**
-     * Remove userId from starting user list once start is complete.
-     */
-    public void onUserStarted(int userId) {
-        if (deleteWakeupFromStartingUsers(userId)) {
+        if (deleteWakeupFromUserStarts(userId)) {
             updateUserListFile();
         }
     }
@@ -217,7 +196,7 @@
      * Remove userId from the store when the user is removed.
      */
     public void onUserRemoved(int userId) {
-        if (deleteWakeupFromUserStarts(userId) || deleteWakeupFromStartingUsers(userId)) {
+        if (deleteWakeupFromUserStarts(userId)) {
             updateUserListFile();
         }
     }
@@ -227,29 +206,14 @@
      * @return true if an entry is found and the list of wakeups changes.
      */
     private boolean deleteWakeupFromUserStarts(int userId) {
-        int index;
         synchronized (mUserWakeupLock) {
-            index = mUserStarts.indexOfKey(userId);
+            final int index = mUserStarts.indexOfKey(userId);
             if (index >= 0) {
                 mUserStarts.removeAt(index);
+                return true;
             }
+            return false;
         }
-        return index >= 0;
-    }
-
-    /**
-     * Remove wakeup for a given userId from mStartingUsers.
-     * @return true if an entry is found and the list of wakeups changes.
-     */
-    private boolean deleteWakeupFromStartingUsers(int userId) {
-        int index;
-        synchronized (mUserWakeupLock) {
-            index = mStartingUsers.indexOfKey(userId);
-            if (index >= 0) {
-                mStartingUsers.removeAt(index);
-            }
-        }
-        return index >= 0;
     }
 
     /**
@@ -299,9 +263,6 @@
                 for (int i = 0; i < mUserStarts.size(); i++) {
                     listOfUsers.add(new Pair<>(mUserStarts.keyAt(i), mUserStarts.valueAt(i)));
                 }
-                for (int i = 0; i < mStartingUsers.size(); i++) {
-                    listOfUsers.add(new Pair<>(mStartingUsers.keyAt(i), mStartingUsers.valueAt(i)));
-                }
             }
             Collections.sort(listOfUsers, Comparator.comparingLong(pair -> pair.second));
             for (int i = 0; i < listOfUsers.size(); i++) {
@@ -329,7 +290,6 @@
         }
         synchronized (mUserWakeupLock) {
             mUserStarts.clear();
-            mStartingUsers.clear();
         }
         try (FileInputStream fis = userWakeupFile.openRead()) {
             final TypedXmlPullParser parser = Xml.resolvePullParser(fis);
@@ -396,14 +356,6 @@
                 TimeUtils.formatDuration(mUserStarts.valueAt(i), nowELAPSED, pw);
                 pw.println();
             }
-            pw.println(mStartingUsers.size() + " starting users: ");
-            for (int i = 0; i < mStartingUsers.size(); i++) {
-                pw.print("UserId: ");
-                pw.print(mStartingUsers.keyAt(i));
-                pw.print(", userStartTime: ");
-                TimeUtils.formatDuration(mStartingUsers.valueAt(i), nowELAPSED, pw);
-                pw.println();
-            }
             pw.decreaseIndent();
         }
     }
diff --git a/boot/boot-image-profile.txt b/boot/boot-image-profile.txt
index 1a31612..854d4ee 100644
--- a/boot/boot-image-profile.txt
+++ b/boot/boot-image-profile.txt
@@ -26,6 +26,7 @@
 HSPLandroid/accounts/Account;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/accounts/Account;->equals(Ljava/lang/Object;)Z
 HSPLandroid/accounts/Account;->hashCode()I
+HSPLandroid/accounts/Account;->onAccountAccessed(Ljava/lang/String;)V
 HSPLandroid/accounts/Account;->toString()Ljava/lang/String;
 HSPLandroid/accounts/Account;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/accounts/AccountManager$10;-><init>(Landroid/accounts/AccountManager;Landroid/app/Activity;Landroid/os/Handler;Landroid/accounts/AccountManagerCallback;Landroid/accounts/Account;Ljava/lang/String;ZLandroid/os/Bundle;)V
@@ -125,13 +126,13 @@
 HSPLandroid/animation/AnimationHandler$1;-><init>(Landroid/animation/AnimationHandler;)V
 HSPLandroid/animation/AnimationHandler$1;->doFrame(J)V+]Landroid/animation/AnimationHandler$AnimationFrameCallbackProvider;Landroid/animation/AnimationHandler$MyFrameCallbackProvider;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;-><init>(Landroid/animation/AnimationHandler;)V
-HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;->getFrameTime()J
-HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;->postFrameCallback(Landroid/view/Choreographer$FrameCallback;)V
+HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;->getFrameTime()J+]Landroid/view/Choreographer;Landroid/view/Choreographer;
+HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;->postFrameCallback(Landroid/view/Choreographer$FrameCallback;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
 HSPLandroid/animation/AnimationHandler;-><init>()V
-HSPLandroid/animation/AnimationHandler;->addAnimationFrameCallback(Landroid/animation/AnimationHandler$AnimationFrameCallback;J)V+]Landroid/animation/AnimationHandler$AnimationFrameCallbackProvider;Landroid/animation/AnimationHandler$MyFrameCallbackProvider;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/animation/AnimationHandler;->autoCancelBasedOn(Landroid/animation/ObjectAnimator;)V
-HSPLandroid/animation/AnimationHandler;->cleanUpList()V
-HSPLandroid/animation/AnimationHandler;->doAnimationFrame(J)V+]Landroid/animation/AnimationHandler$AnimationFrameCallback;Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;,Lcom/android/internal/dynamicanimation/animation/SpringAnimation;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimationHandler;->addAnimationFrameCallback(Landroid/animation/AnimationHandler$AnimationFrameCallback;J)V
+HSPLandroid/animation/AnimationHandler;->autoCancelBasedOn(Landroid/animation/ObjectAnimator;)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimationHandler;->cleanUpList()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimationHandler;->doAnimationFrame(J)V+]Landroid/animation/AnimationHandler$AnimationFrameCallback;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;,Lcom/android/internal/dynamicanimation/animation/SpringAnimation;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/animation/AnimationHandler;->getAnimationCount()I
 HSPLandroid/animation/AnimationHandler;->getInstance()Landroid/animation/AnimationHandler;
 HSPLandroid/animation/AnimationHandler;->getProvider()Landroid/animation/AnimationHandler$AnimationFrameCallbackProvider;
@@ -156,18 +157,18 @@
 HSPLandroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda6;->call(Ljava/lang/Object;Ljava/lang/Object;Z)V
 HSPLandroid/animation/Animator$AnimatorCaller;-><clinit>()V
 HSPLandroid/animation/Animator$AnimatorCaller;->lambda$static$0(Landroid/animation/Animator$AnimatorListener;Landroid/animation/Animator;Z)V
-HSPLandroid/animation/Animator$AnimatorCaller;->lambda$static$4(Landroid/animation/ValueAnimator$AnimatorUpdateListener;Landroid/animation/ValueAnimator;Z)V
+HSPLandroid/animation/Animator$AnimatorCaller;->lambda$static$4(Landroid/animation/ValueAnimator$AnimatorUpdateListener;Landroid/animation/ValueAnimator;Z)V+]Landroid/animation/ValueAnimator$AnimatorUpdateListener;missing_types
 HSPLandroid/animation/Animator$AnimatorConstantState;-><init>(Landroid/animation/Animator;)V
 HSPLandroid/animation/Animator$AnimatorConstantState;->getChangingConfigurations()I
 HSPLandroid/animation/Animator$AnimatorConstantState;->newInstance()Landroid/animation/Animator;
 HSPLandroid/animation/Animator$AnimatorConstantState;->newInstance()Ljava/lang/Object;
-HSPLandroid/animation/Animator$AnimatorListener;->onAnimationEnd(Landroid/animation/Animator;Z)V+]Landroid/animation/Animator$AnimatorListener;megamorphic_types
-HSPLandroid/animation/Animator$AnimatorListener;->onAnimationStart(Landroid/animation/Animator;Z)V+]Landroid/animation/Animator$AnimatorListener;megamorphic_types
+HSPLandroid/animation/Animator$AnimatorListener;->onAnimationEnd(Landroid/animation/Animator;Z)V+]Landroid/animation/Animator$AnimatorListener;missing_types
+HSPLandroid/animation/Animator$AnimatorListener;->onAnimationStart(Landroid/animation/Animator;Z)V+]Landroid/animation/Animator$AnimatorListener;missing_types
 HSPLandroid/animation/Animator;-><init>()V
-HSPLandroid/animation/Animator;->addListener(Landroid/animation/Animator$AnimatorListener;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/Animator;->addListener(Landroid/animation/Animator$AnimatorListener;)V
 HSPLandroid/animation/Animator;->addPauseListener(Landroid/animation/Animator$AnimatorPauseListener;)V
 HSPLandroid/animation/Animator;->appendChangingConfigurations(I)V
-HSPLandroid/animation/Animator;->callOnList(Ljava/util/ArrayList;Landroid/animation/Animator$AnimatorCaller;Ljava/lang/Object;Z)V+]Landroid/animation/Animator$AnimatorCaller;megamorphic_types]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/concurrent/atomic/AtomicReference;Ljava/util/concurrent/atomic/AtomicReference;
+HSPLandroid/animation/Animator;->callOnList(Ljava/util/ArrayList;Landroid/animation/Animator$AnimatorCaller;Ljava/lang/Object;Z)V+]Landroid/animation/Animator$AnimatorCaller;Landroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda1;,Landroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda0;,Landroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda6;,Landroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda2;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/concurrent/atomic/AtomicReference;Ljava/util/concurrent/atomic/AtomicReference;
 HSPLandroid/animation/Animator;->clone()Landroid/animation/Animator;
 HSPLandroid/animation/Animator;->createConstantState()Landroid/content/res/ConstantState;
 HSPLandroid/animation/Animator;->getBackgroundPauseDelay()J
@@ -176,10 +177,10 @@
 HSPLandroid/animation/Animator;->getStartAndEndTimes(Landroid/util/LongArray;J)V
 HSPLandroid/animation/Animator;->notifyEndListeners(Z)V
 HSPLandroid/animation/Animator;->notifyListeners(Landroid/animation/Animator$AnimatorCaller;Z)V
-HSPLandroid/animation/Animator;->notifyStartListeners(Z)V+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/Animator;->notifyStartListeners(Z)V
 HSPLandroid/animation/Animator;->pause()V
 HSPLandroid/animation/Animator;->removeAllListeners()V
-HSPLandroid/animation/Animator;->removeListener(Landroid/animation/Animator$AnimatorListener;)V
+HSPLandroid/animation/Animator;->removeListener(Landroid/animation/Animator$AnimatorListener;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/animation/Animator;->setAllowRunningAsynchronously(Z)V
 HSPLandroid/animation/AnimatorInflater$PathDataEvaluator;->evaluate(FLandroid/util/PathParser$PathData;Landroid/util/PathParser$PathData;)Landroid/util/PathParser$PathData;
 HSPLandroid/animation/AnimatorInflater$PathDataEvaluator;->evaluate(FLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
@@ -201,53 +202,53 @@
 HSPLandroid/animation/AnimatorListenerAdapter;->onAnimationEnd(Landroid/animation/Animator;)V
 HSPLandroid/animation/AnimatorListenerAdapter;->onAnimationStart(Landroid/animation/Animator;)V
 HSPLandroid/animation/AnimatorSet$1;-><init>(Landroid/animation/AnimatorSet;)V
-HSPLandroid/animation/AnimatorSet$1;->onAnimationEnd(Landroid/animation/Animator;)V
+HSPLandroid/animation/AnimatorSet$1;->onAnimationEnd(Landroid/animation/Animator;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
 HSPLandroid/animation/AnimatorSet$2;-><init>(Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;)V
 HSPLandroid/animation/AnimatorSet$2;->onAnimationEnd(Landroid/animation/Animator;)V
 HSPLandroid/animation/AnimatorSet$3;-><init>(Landroid/animation/AnimatorSet;)V
-HSPLandroid/animation/AnimatorSet$3;->compare(Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;)I
+HSPLandroid/animation/AnimatorSet$3;->compare(Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;)I+]Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;
 HSPLandroid/animation/AnimatorSet$3;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
 HSPLandroid/animation/AnimatorSet$AnimationEvent;-><init>(Landroid/animation/AnimatorSet$Node;I)V
-HSPLandroid/animation/AnimatorSet$AnimationEvent;->getTime()J
+HSPLandroid/animation/AnimatorSet$AnimationEvent;->getTime()J+]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;
 HSPLandroid/animation/AnimatorSet$Builder;-><init>(Landroid/animation/AnimatorSet;Landroid/animation/Animator;)V
 HSPLandroid/animation/AnimatorSet$Builder;->after(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
 HSPLandroid/animation/AnimatorSet$Builder;->before(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
 HSPLandroid/animation/AnimatorSet$Builder;->with(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
 HSPLandroid/animation/AnimatorSet$Node;-><init>(Landroid/animation/Animator;)V
 HSPLandroid/animation/AnimatorSet$Node;->addChild(Landroid/animation/AnimatorSet$Node;)V
-HSPLandroid/animation/AnimatorSet$Node;->addParent(Landroid/animation/AnimatorSet$Node;)V
+HSPLandroid/animation/AnimatorSet$Node;->addParent(Landroid/animation/AnimatorSet$Node;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;
 HSPLandroid/animation/AnimatorSet$Node;->addParents(Ljava/util/ArrayList;)V
-HSPLandroid/animation/AnimatorSet$Node;->addSibling(Landroid/animation/AnimatorSet$Node;)V
-HSPLandroid/animation/AnimatorSet$Node;->clone()Landroid/animation/AnimatorSet$Node;+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet$Node;->addSibling(Landroid/animation/AnimatorSet$Node;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;
+HSPLandroid/animation/AnimatorSet$Node;->clone()Landroid/animation/AnimatorSet$Node;+]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
 HSPLandroid/animation/AnimatorSet$SeekState;-><init>(Landroid/animation/AnimatorSet;)V
 HSPLandroid/animation/AnimatorSet$SeekState;->getPlayTimeNormalized()J
 HSPLandroid/animation/AnimatorSet$SeekState;->isActive()Z
 HSPLandroid/animation/AnimatorSet$SeekState;->reset()V
-HSPLandroid/animation/AnimatorSet;-><init>()V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;-><init>()V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
 HSPLandroid/animation/AnimatorSet;->addAnimationCallback(J)V
-HSPLandroid/animation/AnimatorSet;->addAnimationEndListener()V
+HSPLandroid/animation/AnimatorSet;->addAnimationEndListener()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
 HSPLandroid/animation/AnimatorSet;->cancel()V
 HSPLandroid/animation/AnimatorSet;->clone()Landroid/animation/Animator;
-HSPLandroid/animation/AnimatorSet;->clone()Landroid/animation/AnimatorSet;+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/HashMap;Ljava/util/HashMap;
-HSPLandroid/animation/AnimatorSet;->createDependencyGraph()V+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;]Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;->clone()Landroid/animation/AnimatorSet;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet;->createDependencyGraph()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;
 HSPLandroid/animation/AnimatorSet;->doAnimationFrame(J)Z+]Landroid/animation/AnimatorSet$SeekState;Landroid/animation/AnimatorSet$SeekState;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/animation/AnimatorSet;->end()V
-HSPLandroid/animation/AnimatorSet;->endAnimation()V
+HSPLandroid/animation/AnimatorSet;->end()V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;
+HSPLandroid/animation/AnimatorSet;->endAnimation()V+]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Landroid/animation/AnimatorSet$SeekState;Landroid/animation/AnimatorSet$SeekState;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/animation/AnimatorSet;->ensureChildStartAndEndTimes()[J
 HSPLandroid/animation/AnimatorSet;->findLatestEventIdForTime(J)I
 HSPLandroid/animation/AnimatorSet;->findNextIndex(J[J)I
 HSPLandroid/animation/AnimatorSet;->findSiblings(Landroid/animation/AnimatorSet$Node;Ljava/util/ArrayList;)V
 HSPLandroid/animation/AnimatorSet;->getChangingConfigurations()I
-HSPLandroid/animation/AnimatorSet;->getChildAnimations()Ljava/util/ArrayList;
-HSPLandroid/animation/AnimatorSet;->getNodeForAnimation(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Node;
+HSPLandroid/animation/AnimatorSet;->getChildAnimations()Ljava/util/ArrayList;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;->getNodeForAnimation(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Node;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/animation/AnimatorSet;->getStartAndEndTimes(Landroid/util/LongArray;J)V
 HSPLandroid/animation/AnimatorSet;->getStartDelay()J
 HSPLandroid/animation/AnimatorSet;->getTotalDuration()J
-HSPLandroid/animation/AnimatorSet;->handleAnimationEvents(IIJ)V
-HSPLandroid/animation/AnimatorSet;->initAnimation()V
+HSPLandroid/animation/AnimatorSet;->handleAnimationEvents(IIJ)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet;->initAnimation()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
 HSPLandroid/animation/AnimatorSet;->initChildren()V
-HSPLandroid/animation/AnimatorSet;->isEmptySet(Landroid/animation/AnimatorSet;)Z
-HSPLandroid/animation/AnimatorSet;->isInitialized()Z
+HSPLandroid/animation/AnimatorSet;->isEmptySet(Landroid/animation/AnimatorSet;)Z+]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;->isInitialized()Z+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
 HSPLandroid/animation/AnimatorSet;->isRunning()Z
 HSPLandroid/animation/AnimatorSet;->isStarted()Z
 HSPLandroid/animation/AnimatorSet;->play(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
@@ -257,46 +258,46 @@
 HSPLandroid/animation/AnimatorSet;->pulseAnimationFrame(J)Z
 HSPLandroid/animation/AnimatorSet;->pulseFrame(Landroid/animation/AnimatorSet$Node;J)V
 HSPLandroid/animation/AnimatorSet;->removeAnimationCallback()V
-HSPLandroid/animation/AnimatorSet;->removeAnimationEndListener()V
+HSPLandroid/animation/AnimatorSet;->removeAnimationEndListener()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
 HSPLandroid/animation/AnimatorSet;->setDuration(J)Landroid/animation/Animator;
 HSPLandroid/animation/AnimatorSet;->setDuration(J)Landroid/animation/AnimatorSet;
 HSPLandroid/animation/AnimatorSet;->setInterpolator(Landroid/animation/TimeInterpolator;)V
 HSPLandroid/animation/AnimatorSet;->setStartDelay(J)V
-HSPLandroid/animation/AnimatorSet;->setTarget(Ljava/lang/Object;)V
+HSPLandroid/animation/AnimatorSet;->setTarget(Ljava/lang/Object;)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/animation/AnimatorSet;->shouldPlayTogether()Z
 HSPLandroid/animation/AnimatorSet;->skipToEndValue(Z)V
-HSPLandroid/animation/AnimatorSet;->sortAnimationEvents()V+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;->sortAnimationEvents()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;
 HSPLandroid/animation/AnimatorSet;->start()V
-HSPLandroid/animation/AnimatorSet;->start(ZZ)V
-HSPLandroid/animation/AnimatorSet;->startAnimation()V
+HSPLandroid/animation/AnimatorSet;->start(ZZ)V+]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet;->startAnimation()V+]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Landroid/animation/AnimatorSet$SeekState;Landroid/animation/AnimatorSet$SeekState;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
 HSPLandroid/animation/AnimatorSet;->startWithoutPulsing(Z)V
-HSPLandroid/animation/AnimatorSet;->updateAnimatorsDuration()V
-HSPLandroid/animation/AnimatorSet;->updatePlayTime(Landroid/animation/AnimatorSet$Node;Ljava/util/ArrayList;)V
+HSPLandroid/animation/AnimatorSet;->updateAnimatorsDuration()V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet;->updatePlayTime(Landroid/animation/AnimatorSet$Node;Ljava/util/ArrayList;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;
 HSPLandroid/animation/ArgbEvaluator;-><init>()V
-HSPLandroid/animation/ArgbEvaluator;->evaluate(FLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+]Ljava/lang/Integer;Ljava/lang/Integer;
+HSPLandroid/animation/ArgbEvaluator;->evaluate(FLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/animation/ArgbEvaluator;->getInstance()Landroid/animation/ArgbEvaluator;
 HSPLandroid/animation/FloatKeyframeSet;-><init>([Landroid/animation/Keyframe$FloatKeyframe;)V
 HSPLandroid/animation/FloatKeyframeSet;->clone()Landroid/animation/FloatKeyframeSet;
 HSPLandroid/animation/FloatKeyframeSet;->clone()Landroid/animation/Keyframes;
-HSPLandroid/animation/FloatKeyframeSet;->getFloatValue(F)F+]Landroid/animation/Keyframe$FloatKeyframe;Landroid/animation/Keyframe$FloatKeyframe;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/FloatKeyframeSet;->getFloatValue(F)F+]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Landroid/animation/Keyframe$FloatKeyframe;Landroid/animation/Keyframe$FloatKeyframe;
 HSPLandroid/animation/FloatKeyframeSet;->getValue(F)Ljava/lang/Object;
 HSPLandroid/animation/IntKeyframeSet;-><init>([Landroid/animation/Keyframe$IntKeyframe;)V
-HSPLandroid/animation/IntKeyframeSet;->clone()Landroid/animation/IntKeyframeSet;+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/IntKeyframeSet;->clone()Landroid/animation/IntKeyframeSet;+]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;
 HSPLandroid/animation/IntKeyframeSet;->clone()Landroid/animation/Keyframes;
-HSPLandroid/animation/IntKeyframeSet;->getIntValue(F)I+]Landroid/animation/Keyframe$IntKeyframe;Landroid/animation/Keyframe$IntKeyframe;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/IntKeyframeSet;->getIntValue(F)I
 HSPLandroid/animation/Keyframe$FloatKeyframe;-><init>(F)V
 HSPLandroid/animation/Keyframe$FloatKeyframe;-><init>(FF)V
 HSPLandroid/animation/Keyframe$FloatKeyframe;->clone()Landroid/animation/Keyframe$FloatKeyframe;+]Landroid/animation/Keyframe$FloatKeyframe;Landroid/animation/Keyframe$FloatKeyframe;
 HSPLandroid/animation/Keyframe$FloatKeyframe;->clone()Landroid/animation/Keyframe;
 HSPLandroid/animation/Keyframe$FloatKeyframe;->getFloatValue()F
 HSPLandroid/animation/Keyframe$FloatKeyframe;->getValue()Ljava/lang/Object;
-HSPLandroid/animation/Keyframe$FloatKeyframe;->setValue(Ljava/lang/Object;)V
+HSPLandroid/animation/Keyframe$FloatKeyframe;->setValue(Ljava/lang/Object;)V+]Ljava/lang/Object;Ljava/lang/Float;]Ljava/lang/Float;Ljava/lang/Float;
 HSPLandroid/animation/Keyframe$IntKeyframe;-><init>(FI)V
-HSPLandroid/animation/Keyframe$IntKeyframe;->clone()Landroid/animation/Keyframe$IntKeyframe;+]Landroid/animation/Keyframe$IntKeyframe;Landroid/animation/Keyframe$IntKeyframe;
+HSPLandroid/animation/Keyframe$IntKeyframe;->clone()Landroid/animation/Keyframe$IntKeyframe;
 HSPLandroid/animation/Keyframe$IntKeyframe;->clone()Landroid/animation/Keyframe;
 HSPLandroid/animation/Keyframe$IntKeyframe;->getIntValue()I
 HSPLandroid/animation/Keyframe$IntKeyframe;->getValue()Ljava/lang/Object;
-HSPLandroid/animation/Keyframe$IntKeyframe;->setValue(Ljava/lang/Object;)V+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/lang/Object;Ljava/lang/Integer;
+HSPLandroid/animation/Keyframe$IntKeyframe;->setValue(Ljava/lang/Object;)V
 HSPLandroid/animation/Keyframe$ObjectKeyframe;-><init>(FLjava/lang/Object;)V
 HSPLandroid/animation/Keyframe$ObjectKeyframe;->clone()Landroid/animation/Keyframe$ObjectKeyframe;
 HSPLandroid/animation/Keyframe$ObjectKeyframe;->clone()Landroid/animation/Keyframe;
@@ -312,17 +313,17 @@
 HSPLandroid/animation/Keyframe;->setInterpolator(Landroid/animation/TimeInterpolator;)V
 HSPLandroid/animation/Keyframe;->setValueWasSetOnStart(Z)V
 HSPLandroid/animation/Keyframe;->valueWasSetOnStart()Z
-HSPLandroid/animation/KeyframeSet;-><init>([Landroid/animation/Keyframe;)V+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$FloatKeyframe;,Landroid/animation/Keyframe$IntKeyframe;,Landroid/animation/Keyframe$ObjectKeyframe;
+HSPLandroid/animation/KeyframeSet;-><init>([Landroid/animation/Keyframe;)V+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$ObjectKeyframe;,Landroid/animation/Keyframe$IntKeyframe;,Landroid/animation/Keyframe$FloatKeyframe;
 HSPLandroid/animation/KeyframeSet;->clone()Landroid/animation/KeyframeSet;
 HSPLandroid/animation/KeyframeSet;->clone()Landroid/animation/Keyframes;
 HSPLandroid/animation/KeyframeSet;->getKeyframes()Ljava/util/List;
-HSPLandroid/animation/KeyframeSet;->getValue(F)Ljava/lang/Object;+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$ObjectKeyframe;]Landroid/animation/TypeEvaluator;Landroid/animation/ArgbEvaluator;
+HSPLandroid/animation/KeyframeSet;->getValue(F)Ljava/lang/Object;+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$ObjectKeyframe;
 HSPLandroid/animation/KeyframeSet;->ofFloat([F)Landroid/animation/KeyframeSet;
 HSPLandroid/animation/KeyframeSet;->ofInt([I)Landroid/animation/KeyframeSet;
 HSPLandroid/animation/KeyframeSet;->ofObject([Ljava/lang/Object;)Landroid/animation/KeyframeSet;
 HSPLandroid/animation/KeyframeSet;->setEvaluator(Landroid/animation/TypeEvaluator;)V
 HSPLandroid/animation/LayoutTransition$1;->onAnimationEnd(Landroid/animation/Animator;)V
-HSPLandroid/animation/LayoutTransition$2;->onLayoutChange(Landroid/view/View;IIIIIIII)V+]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Ljava/lang/Object;Ljava/lang/Integer;]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/util/LinkedHashMap;Ljava/util/LinkedHashMap;
+HSPLandroid/animation/LayoutTransition$2;->onLayoutChange(Landroid/view/View;IIIIIIII)V
 HSPLandroid/animation/LayoutTransition$3;->onAnimationEnd(Landroid/animation/Animator;)V
 HSPLandroid/animation/LayoutTransition$3;->onAnimationStart(Landroid/animation/Animator;)V
 HSPLandroid/animation/LayoutTransition$4;->onAnimationEnd(Landroid/animation/Animator;)V
@@ -350,20 +351,20 @@
 HSPLandroid/animation/LayoutTransition;->setDuration(J)V
 HSPLandroid/animation/LayoutTransition;->setInterpolator(ILandroid/animation/TimeInterpolator;)V
 HSPLandroid/animation/LayoutTransition;->setStartDelay(IJ)V
-HSPLandroid/animation/LayoutTransition;->setupChangeAnimation(Landroid/view/ViewGroup;ILandroid/animation/Animator;JLandroid/view/View;)V+]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/view/View;missing_types]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/animation/LayoutTransition;->setupChangeAnimation(Landroid/view/ViewGroup;ILandroid/animation/Animator;JLandroid/view/View;)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/view/View;missing_types]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;
 HSPLandroid/animation/LayoutTransition;->showChild(Landroid/view/ViewGroup;Landroid/view/View;I)V
 HSPLandroid/animation/LayoutTransition;->startChangingAnimations()V
 HSPLandroid/animation/ObjectAnimator;-><init>()V
 HSPLandroid/animation/ObjectAnimator;-><init>(Ljava/lang/Object;Landroid/util/Property;)V
 HSPLandroid/animation/ObjectAnimator;-><init>(Ljava/lang/Object;Ljava/lang/String;)V
-HSPLandroid/animation/ObjectAnimator;->animateValue(F)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
+HSPLandroid/animation/ObjectAnimator;->animateValue(F)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
 HSPLandroid/animation/ObjectAnimator;->clone()Landroid/animation/Animator;
 HSPLandroid/animation/ObjectAnimator;->clone()Landroid/animation/ObjectAnimator;
-HSPLandroid/animation/ObjectAnimator;->getNameForTrace()Ljava/lang/String;+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/animation/ObjectAnimator;->getPropertyName()Ljava/lang/String;+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/animation/ObjectAnimator;->getTarget()Ljava/lang/Object;+]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/animation/ObjectAnimator;->getNameForTrace()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;
+HSPLandroid/animation/ObjectAnimator;->getPropertyName()Ljava/lang/String;+]Landroid/util/Property;missing_types
+HSPLandroid/animation/ObjectAnimator;->getTarget()Ljava/lang/Object;
 HSPLandroid/animation/ObjectAnimator;->hasSameTargetAndProperties(Landroid/animation/Animator;)Z
-HSPLandroid/animation/ObjectAnimator;->initAnimation()V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
+HSPLandroid/animation/ObjectAnimator;->initAnimation()V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
 HSPLandroid/animation/ObjectAnimator;->isInitialized()Z
 HSPLandroid/animation/ObjectAnimator;->ofFloat(Ljava/lang/Object;Landroid/util/Property;[F)Landroid/animation/ObjectAnimator;
 HSPLandroid/animation/ObjectAnimator;->ofFloat(Ljava/lang/Object;Ljava/lang/String;[F)Landroid/animation/ObjectAnimator;
@@ -376,7 +377,7 @@
 HSPLandroid/animation/ObjectAnimator;->setDuration(J)Landroid/animation/Animator;
 HSPLandroid/animation/ObjectAnimator;->setDuration(J)Landroid/animation/ObjectAnimator;
 HSPLandroid/animation/ObjectAnimator;->setDuration(J)Landroid/animation/ValueAnimator;
-HSPLandroid/animation/ObjectAnimator;->setFloatValues([F)V
+HSPLandroid/animation/ObjectAnimator;->setFloatValues([F)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;
 HSPLandroid/animation/ObjectAnimator;->setIntValues([I)V
 HSPLandroid/animation/ObjectAnimator;->setObjectValues([Ljava/lang/Object;)V
 HSPLandroid/animation/ObjectAnimator;->setProperty(Landroid/util/Property;)V
@@ -402,50 +403,50 @@
 HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;
 HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;
 HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->getAnimatedValue()Ljava/lang/Object;
-HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V+]Landroid/util/FloatProperty;Landroid/view/View$12;,Landroid/view/View$13;]Landroid/util/Property;missing_types
+HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V+]Landroid/util/FloatProperty;Landroid/view/View$2;,Landroid/view/View$12;,Landroid/view/View$13;,Landroid/view/View$5;
 HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setFloatValues([F)V
 HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setProperty(Landroid/util/Property;)V
-HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setupSetter(Ljava/lang/Class;)V
+HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setupSetter(Ljava/lang/Class;)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Long;Ljava/lang/Long;
 HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;-><init>(Ljava/lang/String;[I)V
-HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->calculateValue(F)V
+HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->calculateValue(F)V+]Landroid/animation/Keyframes$IntKeyframes;Landroid/animation/IntKeyframeSet;
 HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;
-HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;+]Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;
+HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;
 HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->getAnimatedValue()Ljava/lang/Object;
 HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V
 HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->setIntValues([I)V
-HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->setupSetter(Ljava/lang/Class;)V+]Ljava/lang/Long;Ljava/lang/Long;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->setupSetter(Ljava/lang/Class;)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Long;Ljava/lang/Long;
 HSPLandroid/animation/PropertyValuesHolder$PropertyValues;-><init>()V
-HSPLandroid/animation/PropertyValuesHolder;-><init>(Landroid/util/Property;)V
+HSPLandroid/animation/PropertyValuesHolder;-><init>(Landroid/util/Property;)V+]Landroid/util/Property;missing_types
 HSPLandroid/animation/PropertyValuesHolder;-><init>(Ljava/lang/String;)V
 HSPLandroid/animation/PropertyValuesHolder;-><init>(Ljava/lang/String;Landroid/animation/PropertyValuesHolder-IA;)V
-HSPLandroid/animation/PropertyValuesHolder;->calculateValue(F)V
-HSPLandroid/animation/PropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;+]Landroid/animation/Keyframes;Landroid/animation/FloatKeyframeSet;,Landroid/animation/IntKeyframeSet;,Landroid/animation/KeyframeSet;
+HSPLandroid/animation/PropertyValuesHolder;->calculateValue(F)V+]Landroid/animation/Keyframes;Landroid/animation/KeyframeSet;
+HSPLandroid/animation/PropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;+]Landroid/animation/Keyframes;Landroid/animation/KeyframeSet;,Landroid/animation/IntKeyframeSet;,Landroid/animation/FloatKeyframeSet;
 HSPLandroid/animation/PropertyValuesHolder;->convertBack(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/animation/PropertyValuesHolder;->getAnimatedValue()Ljava/lang/Object;
 HSPLandroid/animation/PropertyValuesHolder;->getMethodName(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/animation/PropertyValuesHolder;->getPropertyFunction(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/reflect/Method;
 HSPLandroid/animation/PropertyValuesHolder;->getPropertyName()Ljava/lang/String;
-HSPLandroid/animation/PropertyValuesHolder;->getPropertyValues(Landroid/animation/PropertyValuesHolder$PropertyValues;)V+]Landroid/animation/Keyframes;Landroid/animation/FloatKeyframeSet;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/PropertyValuesHolder;->getPropertyValues(Landroid/animation/PropertyValuesHolder$PropertyValues;)V
 HSPLandroid/animation/PropertyValuesHolder;->getValueType()Ljava/lang/Class;
-HSPLandroid/animation/PropertyValuesHolder;->init()V+]Landroid/animation/Keyframes;Landroid/animation/KeyframeSet;
+HSPLandroid/animation/PropertyValuesHolder;->init()V
 HSPLandroid/animation/PropertyValuesHolder;->ofFloat(Landroid/util/Property;[F)Landroid/animation/PropertyValuesHolder;
 HSPLandroid/animation/PropertyValuesHolder;->ofFloat(Ljava/lang/String;[F)Landroid/animation/PropertyValuesHolder;
 HSPLandroid/animation/PropertyValuesHolder;->ofInt(Ljava/lang/String;[I)Landroid/animation/PropertyValuesHolder;
 HSPLandroid/animation/PropertyValuesHolder;->ofKeyframes(Ljava/lang/String;Landroid/animation/Keyframes;)Landroid/animation/PropertyValuesHolder;
 HSPLandroid/animation/PropertyValuesHolder;->ofObject(Ljava/lang/String;Landroid/animation/TypeEvaluator;[Ljava/lang/Object;)Landroid/animation/PropertyValuesHolder;
-HSPLandroid/animation/PropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V
+HSPLandroid/animation/PropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder;
 HSPLandroid/animation/PropertyValuesHolder;->setEvaluator(Landroid/animation/TypeEvaluator;)V
 HSPLandroid/animation/PropertyValuesHolder;->setFloatValues([F)V
 HSPLandroid/animation/PropertyValuesHolder;->setIntValues([I)V
 HSPLandroid/animation/PropertyValuesHolder;->setObjectValues([Ljava/lang/Object;)V
 HSPLandroid/animation/PropertyValuesHolder;->setProperty(Landroid/util/Property;)V
 HSPLandroid/animation/PropertyValuesHolder;->setPropertyName(Ljava/lang/String;)V
-HSPLandroid/animation/PropertyValuesHolder;->setupEndValue(Ljava/lang/Object;)V+]Landroid/animation/Keyframes;Landroid/animation/IntKeyframeSet;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/PropertyValuesHolder;->setupEndValue(Ljava/lang/Object;)V
 HSPLandroid/animation/PropertyValuesHolder;->setupGetter(Ljava/lang/Class;)V
-HSPLandroid/animation/PropertyValuesHolder;->setupSetterAndGetter(Ljava/lang/Object;)V+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$FloatKeyframe;,Landroid/animation/Keyframe$IntKeyframe;,Landroid/animation/Keyframe$ObjectKeyframe;]Landroid/animation/Keyframes;Landroid/animation/FloatKeyframeSet;,Landroid/animation/IntKeyframeSet;,Landroid/animation/KeyframeSet;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;]Ljava/lang/Object;missing_types]Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
-HSPLandroid/animation/PropertyValuesHolder;->setupSetterOrGetter(Ljava/lang/Class;Ljava/util/HashMap;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/reflect/Method;+]Ljava/util/HashMap;Ljava/util/HashMap;
-HSPLandroid/animation/PropertyValuesHolder;->setupStartValue(Ljava/lang/Object;)V+]Landroid/animation/Keyframes;Landroid/animation/IntKeyframeSet;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
-HSPLandroid/animation/PropertyValuesHolder;->setupValue(Ljava/lang/Object;Landroid/animation/Keyframe;)V+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;]Ljava/lang/Object;missing_types]Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;
+HSPLandroid/animation/PropertyValuesHolder;->setupSetterAndGetter(Ljava/lang/Object;)V+]Ljava/lang/Object;missing_types]Landroid/animation/Keyframes;Landroid/animation/IntKeyframeSet;,Landroid/animation/FloatKeyframeSet;,Landroid/animation/KeyframeSet;]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;,Landroid/animation/Keyframe$FloatKeyframe;,Landroid/animation/Keyframe$ObjectKeyframe;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;]Landroid/util/Property;missing_types]Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;
+HSPLandroid/animation/PropertyValuesHolder;->setupSetterOrGetter(Ljava/lang/Class;Ljava/util/HashMap;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/reflect/Method;
+HSPLandroid/animation/PropertyValuesHolder;->setupStartValue(Ljava/lang/Object;)V
+HSPLandroid/animation/PropertyValuesHolder;->setupValue(Ljava/lang/Object;Landroid/animation/Keyframe;)V+]Ljava/lang/Object;missing_types]Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;
 HSPLandroid/animation/StateListAnimator$1;-><init>(Landroid/animation/StateListAnimator;)V
 HSPLandroid/animation/StateListAnimator$1;->onAnimationEnd(Landroid/animation/Animator;)V
 HSPLandroid/animation/StateListAnimator$StateListAnimatorConstantState;-><init>(Landroid/animation/StateListAnimator;)V
@@ -453,10 +454,10 @@
 HSPLandroid/animation/StateListAnimator$StateListAnimatorConstantState;->newInstance()Ljava/lang/Object;
 HSPLandroid/animation/StateListAnimator$Tuple;-><init>([ILandroid/animation/Animator;)V
 HSPLandroid/animation/StateListAnimator;-><init>()V
-HSPLandroid/animation/StateListAnimator;->addState([ILandroid/animation/Animator;)V+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/StateListAnimator;->addState([ILandroid/animation/Animator;)V
 HSPLandroid/animation/StateListAnimator;->appendChangingConfigurations(I)V
 HSPLandroid/animation/StateListAnimator;->clearTarget()V
-HSPLandroid/animation/StateListAnimator;->clone()Landroid/animation/StateListAnimator;+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;]Landroid/animation/StateListAnimator;Landroid/animation/StateListAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/StateListAnimator;->clone()Landroid/animation/StateListAnimator;
 HSPLandroid/animation/StateListAnimator;->createConstantState()Landroid/content/res/ConstantState;
 HSPLandroid/animation/StateListAnimator;->getChangingConfigurations()I
 HSPLandroid/animation/StateListAnimator;->getTarget()Landroid/view/View;
@@ -472,17 +473,17 @@
 HSPLandroid/animation/ValueAnimator;->addAnimationCallback(J)V
 HSPLandroid/animation/ValueAnimator;->addUpdateListener(Landroid/animation/ValueAnimator$AnimatorUpdateListener;)V
 HSPLandroid/animation/ValueAnimator;->animateBasedOnTime(J)Z+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
-HSPLandroid/animation/ValueAnimator;->animateValue(F)V+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;]Landroid/animation/TimeInterpolator;missing_types]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->animateValue(F)V+]Landroid/animation/TimeInterpolator;missing_types]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;,Landroid/animation/ObjectAnimator;
 HSPLandroid/animation/ValueAnimator;->areAnimatorsEnabled()Z
 HSPLandroid/animation/ValueAnimator;->cancel()V
 HSPLandroid/animation/ValueAnimator;->clampFraction(F)F
 HSPLandroid/animation/ValueAnimator;->clone()Landroid/animation/Animator;
-HSPLandroid/animation/ValueAnimator;->clone()Landroid/animation/ValueAnimator;+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;]Ljava/util/HashMap;Ljava/util/HashMap;
-HSPLandroid/animation/ValueAnimator;->doAnimationFrame(J)Z+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->clone()Landroid/animation/ValueAnimator;+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
+HSPLandroid/animation/ValueAnimator;->doAnimationFrame(J)Z+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;,Landroid/animation/ObjectAnimator;
 HSPLandroid/animation/ValueAnimator;->end()V
-HSPLandroid/animation/ValueAnimator;->endAnimation()V+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->endAnimation()V
 HSPLandroid/animation/ValueAnimator;->getAnimatedFraction()F
-HSPLandroid/animation/ValueAnimator;->getAnimatedValue()Ljava/lang/Object;+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
+HSPLandroid/animation/ValueAnimator;->getAnimatedValue()Ljava/lang/Object;+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;
 HSPLandroid/animation/ValueAnimator;->getAnimationHandler()Landroid/animation/AnimationHandler;
 HSPLandroid/animation/ValueAnimator;->getCurrentAnimationsCount()I
 HSPLandroid/animation/ValueAnimator;->getCurrentIteration(F)I
@@ -513,25 +514,25 @@
 HSPLandroid/animation/ValueAnimator;->resolveDurationScale()F
 HSPLandroid/animation/ValueAnimator;->setAllowRunningAsynchronously(Z)V
 HSPLandroid/animation/ValueAnimator;->setAnimationHandler(Landroid/animation/AnimationHandler;)V
-HSPLandroid/animation/ValueAnimator;->setCurrentFraction(F)V+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->setCurrentFraction(F)V
 HSPLandroid/animation/ValueAnimator;->setCurrentPlayTime(J)V
 HSPLandroid/animation/ValueAnimator;->setDuration(J)Landroid/animation/Animator;
 HSPLandroid/animation/ValueAnimator;->setDuration(J)Landroid/animation/ValueAnimator;
 HSPLandroid/animation/ValueAnimator;->setDurationScale(F)V
 HSPLandroid/animation/ValueAnimator;->setEvaluator(Landroid/animation/TypeEvaluator;)V
-HSPLandroid/animation/ValueAnimator;->setFloatValues([F)V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->setFloatValues([F)V
 HSPLandroid/animation/ValueAnimator;->setIntValues([I)V
 HSPLandroid/animation/ValueAnimator;->setInterpolator(Landroid/animation/TimeInterpolator;)V
 HSPLandroid/animation/ValueAnimator;->setObjectValues([Ljava/lang/Object;)V
 HSPLandroid/animation/ValueAnimator;->setRepeatCount(I)V
 HSPLandroid/animation/ValueAnimator;->setRepeatMode(I)V
 HSPLandroid/animation/ValueAnimator;->setStartDelay(J)V
-HSPLandroid/animation/ValueAnimator;->setValues([Landroid/animation/PropertyValuesHolder;)V+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/animation/ValueAnimator;->setValues([Landroid/animation/PropertyValuesHolder;)V
 HSPLandroid/animation/ValueAnimator;->shouldPlayBackward(IZ)Z
 HSPLandroid/animation/ValueAnimator;->skipToEndValue(Z)V
 HSPLandroid/animation/ValueAnimator;->start()V
-HSPLandroid/animation/ValueAnimator;->start(Z)V+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
-HSPLandroid/animation/ValueAnimator;->startAnimation()V+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->start(Z)V
+HSPLandroid/animation/ValueAnimator;->startAnimation()V
 HSPLandroid/animation/ValueAnimator;->startWithoutPulsing(Z)V
 HSPLandroid/app/Activity$1;-><init>(Landroid/app/Activity;)V
 HSPLandroid/app/Activity$1;->isTaskRoot()Z
@@ -545,7 +546,7 @@
 HSPLandroid/app/Activity;->attach(Landroid/content/Context;Landroid/app/ActivityThread;Landroid/app/Instrumentation;Landroid/os/IBinder;ILandroid/app/Application;Landroid/content/Intent;Landroid/content/pm/ActivityInfo;Ljava/lang/CharSequence;Landroid/app/Activity;Ljava/lang/String;Landroid/app/Activity$NonConfigurationInstances;Landroid/content/res/Configuration;Ljava/lang/String;Lcom/android/internal/app/IVoiceInteractor;Landroid/view/Window;Landroid/view/ViewRootImpl$ActivityConfigCallback;Landroid/os/IBinder;Landroid/os/IBinder;)V
 HSPLandroid/app/Activity;->attachBaseContext(Landroid/content/Context;)V
 HSPLandroid/app/Activity;->cancelInputsAndStartExitTransition(Landroid/os/Bundle;)V
-HSPLandroid/app/Activity;->collectActivityLifecycleCallbacks()[Ljava/lang/Object;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/app/Activity;->collectActivityLifecycleCallbacks()[Ljava/lang/Object;
 HSPLandroid/app/Activity;->dispatchActivityCreated(Landroid/os/Bundle;)V
 HSPLandroid/app/Activity;->dispatchActivityPostCreated(Landroid/os/Bundle;)V
 HSPLandroid/app/Activity;->dispatchActivityPostResumed()V
@@ -608,7 +609,7 @@
 HSPLandroid/app/Activity;->onCreateDescription()Ljava/lang/CharSequence;
 HSPLandroid/app/Activity;->onCreateOptionsMenu(Landroid/view/Menu;)Z
 HSPLandroid/app/Activity;->onCreatePanelMenu(ILandroid/view/Menu;)Z
-HSPLandroid/app/Activity;->onCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;+]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/app/Activity;->onCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
 HSPLandroid/app/Activity;->onCreateView(Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
 HSPLandroid/app/Activity;->onDestroy()V
 HSPLandroid/app/Activity;->onDetachedFromWindow()V
@@ -639,7 +640,7 @@
 HSPLandroid/app/Activity;->onTrimMemory(I)V
 HSPLandroid/app/Activity;->onUserInteraction()V
 HSPLandroid/app/Activity;->onUserLeaveHint()V
-HSPLandroid/app/Activity;->onWindowAttributesChanged(Landroid/view/WindowManager$LayoutParams;)V
+HSPLandroid/app/Activity;->onWindowAttributesChanged(Landroid/view/WindowManager$LayoutParams;)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/view/WindowManager;Landroid/view/WindowManagerImpl;
 HSPLandroid/app/Activity;->onWindowFocusChanged(Z)V
 HSPLandroid/app/Activity;->overridePendingTransition(II)V
 HSPLandroid/app/Activity;->overridePendingTransition(III)V
@@ -689,10 +690,10 @@
 HSPLandroid/app/ActivityClient;->activityStopped(Landroid/os/IBinder;Landroid/os/Bundle;Landroid/os/PersistableBundle;Ljava/lang/CharSequence;)V
 HSPLandroid/app/ActivityClient;->activityTopResumedStateLost()V
 HSPLandroid/app/ActivityClient;->finishActivity(Landroid/os/IBinder;ILandroid/content/Intent;I)Z
-HSPLandroid/app/ActivityClient;->getActivityClientController()Landroid/app/IActivityClientController;+]Landroid/app/ActivityClient$ActivityClientControllerSingleton;Landroid/app/ActivityClient$ActivityClientControllerSingleton;
+HSPLandroid/app/ActivityClient;->getActivityClientController()Landroid/app/IActivityClientController;
 HSPLandroid/app/ActivityClient;->getCallingActivity(Landroid/os/IBinder;)Landroid/content/ComponentName;
 HSPLandroid/app/ActivityClient;->getDisplayId(Landroid/os/IBinder;)I
-HSPLandroid/app/ActivityClient;->getInstance()Landroid/app/ActivityClient;+]Landroid/util/Singleton;Landroid/app/ActivityClient$1;
+HSPLandroid/app/ActivityClient;->getInstance()Landroid/app/ActivityClient;
 HSPLandroid/app/ActivityClient;->getTaskForActivity(Landroid/os/IBinder;Z)I
 HSPLandroid/app/ActivityClient;->overridePendingTransition(Landroid/os/IBinder;Ljava/lang/String;III)V
 HSPLandroid/app/ActivityClient;->reportActivityFullyDrawn(Landroid/os/IBinder;Z)V
@@ -868,7 +869,7 @@
 HSPLandroid/app/ActivityThread$GcIdler;-><init>(Landroid/app/ActivityThread;)V
 HSPLandroid/app/ActivityThread$GcIdler;->queueIdle()Z
 HSPLandroid/app/ActivityThread$H;-><init>(Landroid/app/ActivityThread;)V
-HSPLandroid/app/ActivityThread$H;->handleMessage(Landroid/os/Message;)V
+HSPLandroid/app/ActivityThread$H;->handleMessage(Landroid/os/Message;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/app/ActivityThread;Landroid/app/ActivityThread;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/app/servertransaction/TransactionExecutor;Landroid/app/servertransaction/TransactionExecutor;
 HSPLandroid/app/ActivityThread$Idler;-><init>(Landroid/app/ActivityThread;)V
 HSPLandroid/app/ActivityThread$Idler;-><init>(Landroid/app/ActivityThread;Landroid/app/ActivityThread$Idler-IA;)V
 HSPLandroid/app/ActivityThread$Idler;->queueIdle()Z
@@ -924,8 +925,8 @@
 HSPLandroid/app/ActivityThread;->deliverResults(Landroid/app/ActivityThread$ActivityClientRecord;Ljava/util/List;Ljava/lang/String;)V
 HSPLandroid/app/ActivityThread;->dumpMemoryInfo(Landroid/util/proto/ProtoOutputStream;JLjava/lang/String;IIIIIIZIII)V
 HSPLandroid/app/ActivityThread;->getActivitiesToBeDestroyed()Ljava/util/Map;
-HSPLandroid/app/ActivityThread;->getActivity(Landroid/os/IBinder;)Landroid/app/Activity;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
-HSPLandroid/app/ActivityThread;->getActivityClient(Landroid/os/IBinder;)Landroid/app/ActivityThread$ActivityClientRecord;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/app/ActivityThread;->getActivity(Landroid/os/IBinder;)Landroid/app/Activity;
+HSPLandroid/app/ActivityThread;->getActivityClient(Landroid/os/IBinder;)Landroid/app/ActivityThread$ActivityClientRecord;
 HSPLandroid/app/ActivityThread;->getApplication()Landroid/app/Application;
 HSPLandroid/app/ActivityThread;->getApplicationThread()Landroid/app/ActivityThread$ApplicationThread;
 HSPLandroid/app/ActivityThread;->getBackupAgentName(Landroid/app/ActivityThread$CreateBackupAgentData;)Ljava/lang/String;
@@ -935,7 +936,7 @@
 HSPLandroid/app/ActivityThread;->getGetProviderKey(Ljava/lang/String;I)Landroid/app/ActivityThread$ProviderKey;
 HSPLandroid/app/ActivityThread;->getHandler()Landroid/os/Handler;
 HSPLandroid/app/ActivityThread;->getInstrumentation()Landroid/app/Instrumentation;
-HSPLandroid/app/ActivityThread;->getIntCoreSetting(Ljava/lang/String;I)I
+HSPLandroid/app/ActivityThread;->getIntCoreSetting(Ljava/lang/String;I)I+]Landroid/os/Bundle;Landroid/os/Bundle;
 HSPLandroid/app/ActivityThread;->getIntentBeingBroadcast()Landroid/content/Intent;
 HSPLandroid/app/ActivityThread;->getLooper()Landroid/os/Looper;
 HSPLandroid/app/ActivityThread;->getOperationTypeFromBackupMode(I)I
@@ -957,7 +958,7 @@
 HSPLandroid/app/ActivityThread;->handleBindService(Landroid/app/ActivityThread$BindServiceData;)V
 HSPLandroid/app/ActivityThread;->handleConfigurationChanged(Landroid/content/res/Configuration;I)V
 HSPLandroid/app/ActivityThread;->handleCreateBackupAgent(Landroid/app/ActivityThread$CreateBackupAgentData;)V
-HSPLandroid/app/ActivityThread;->handleCreateService(Landroid/app/ActivityThread$CreateServiceData;)V
+HSPLandroid/app/ActivityThread;->handleCreateService(Landroid/app/ActivityThread$CreateServiceData;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/app/ActivityThread;Landroid/app/ActivityThread;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Ljava/util/List;Ljava/util/Collections$EmptyList;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/IActivityManager;Landroid/app/IActivityManager$Stub$Proxy;
 HSPLandroid/app/ActivityThread;->handleDestroyBackupAgent(Landroid/app/ActivityThread$CreateBackupAgentData;)V
 HSPLandroid/app/ActivityThread;->handleDispatchPackageBroadcast(I[Ljava/lang/String;)V
 HSPLandroid/app/ActivityThread;->handleDumpGfxInfo(Landroid/app/ActivityThread$DumpComponentInfo;)V
@@ -997,10 +998,11 @@
 HSPLandroid/app/ActivityThread;->isProtectedComponent(Landroid/content/pm/ComponentInfo;Ljava/lang/String;)Z
 HSPLandroid/app/ActivityThread;->isProtectedComponent(Landroid/content/pm/ServiceInfo;)Z
 HSPLandroid/app/ActivityThread;->isSystem()Z
+HSPLandroid/app/ActivityThread;->lambda$getGetProviderKey$3(Landroid/app/ActivityThread$ProviderKey;)Landroid/app/ActivityThread$ProviderKey;
 HSPLandroid/app/ActivityThread;->main([Ljava/lang/String;)V
 HSPLandroid/app/ActivityThread;->onCoreSettingsChange()V
 HSPLandroid/app/ActivityThread;->peekPackageInfo(Ljava/lang/String;Z)Landroid/app/LoadedApk;
-HSPLandroid/app/ActivityThread;->performLaunchActivity(Landroid/app/ActivityThread$ActivityClientRecord;Landroid/content/Intent;)Landroid/app/Activity;+]Landroid/app/ActivityThread$ActivityClientRecord;Landroid/app/ActivityThread$ActivityClientRecord;]Landroid/app/ActivityThread;Landroid/app/ActivityThread;]Landroid/app/ConfigurationController;Landroid/app/ConfigurationController;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/app/Instrumentation;Landroid/app/Instrumentation;]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/ComponentName;Landroid/content/ComponentName;]Landroid/content/Intent;Landroid/content/Intent;]Landroid/content/pm/ActivityInfo;Landroid/content/pm/ActivityInfo;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/List;Ljava/util/Collections$EmptyList;
+HSPLandroid/app/ActivityThread;->performLaunchActivity(Landroid/app/ActivityThread$ActivityClientRecord;Landroid/content/Intent;)Landroid/app/Activity;
 HSPLandroid/app/ActivityThread;->performPauseActivity(Landroid/app/ActivityThread$ActivityClientRecord;ZLjava/lang/String;Landroid/app/servertransaction/PendingTransactionActions;)Landroid/os/Bundle;
 HSPLandroid/app/ActivityThread;->performPauseActivityIfNeeded(Landroid/app/ActivityThread$ActivityClientRecord;Ljava/lang/String;)V
 HSPLandroid/app/ActivityThread;->performRestartActivity(Landroid/app/ActivityThread$ActivityClientRecord;Z)V
@@ -1071,7 +1073,7 @@
 HSPLandroid/app/AppComponentFactory;->instantiateReceiver(Ljava/lang/ClassLoader;Ljava/lang/String;Landroid/content/Intent;)Landroid/content/BroadcastReceiver;
 HSPLandroid/app/AppComponentFactory;->instantiateService(Ljava/lang/ClassLoader;Ljava/lang/String;Landroid/content/Intent;)Landroid/app/Service;
 HSPLandroid/app/AppGlobals;->getInitialApplication()Landroid/app/Application;
-HSPLandroid/app/AppGlobals;->getIntCoreSetting(Ljava/lang/String;I)I
+HSPLandroid/app/AppGlobals;->getIntCoreSetting(Ljava/lang/String;I)I+]Landroid/app/ActivityThread;Landroid/app/ActivityThread;
 HSPLandroid/app/AppGlobals;->getPackageManager()Landroid/content/pm/IPackageManager;
 HSPLandroid/app/AppOpsManager$1;->onNoted(Landroid/app/SyncNotedAppOp;)V
 HSPLandroid/app/AppOpsManager$1;->onSelfNoted(Landroid/app/SyncNotedAppOp;)V
@@ -1164,7 +1166,7 @@
 HSPLandroid/app/Application$ActivityLifecycleCallbacks;->onActivityPreStopped(Landroid/app/Activity;)V
 HSPLandroid/app/Application;-><init>()V
 HSPLandroid/app/Application;->attach(Landroid/content/Context;)V
-HSPLandroid/app/Application;->collectActivityLifecycleCallbacks()[Ljava/lang/Object;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/app/Application;->collectActivityLifecycleCallbacks()[Ljava/lang/Object;
 HSPLandroid/app/Application;->dispatchActivityCreated(Landroid/app/Activity;Landroid/os/Bundle;)V
 HSPLandroid/app/Application;->dispatchActivityDestroyed(Landroid/app/Activity;)V
 HSPLandroid/app/Application;->dispatchActivityPaused(Landroid/app/Activity;)V
@@ -1264,7 +1266,7 @@
 HSPLandroid/app/ApplicationPackageManager;->getInstalledPackagesAsUser(II)Ljava/util/List;
 HSPLandroid/app/ApplicationPackageManager;->getInstalledPackagesAsUser(Landroid/content/pm/PackageManager$PackageInfoFlags;I)Ljava/util/List;
 HSPLandroid/app/ApplicationPackageManager;->getInstallerPackageName(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/app/ApplicationPackageManager;->getLaunchIntentForPackage(Ljava/lang/String;)Landroid/content/Intent;+]Landroid/app/ApplicationPackageManager;Landroid/app/ApplicationPackageManager;]Landroid/content/Intent;Landroid/content/Intent;]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/app/ApplicationPackageManager;->getLaunchIntentForPackage(Ljava/lang/String;)Landroid/content/Intent;+]Ljava/util/List;Ljava/util/ArrayList;]Landroid/app/ApplicationPackageManager;Landroid/app/ApplicationPackageManager;]Landroid/content/Intent;Landroid/content/Intent;
 HSPLandroid/app/ApplicationPackageManager;->getModuleInfo(Ljava/lang/String;I)Landroid/content/pm/ModuleInfo;
 HSPLandroid/app/ApplicationPackageManager;->getNameForUid(I)Ljava/lang/String;
 HSPLandroid/app/ApplicationPackageManager;->getPackageInfo(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;
@@ -1288,7 +1290,7 @@
 HSPLandroid/app/ApplicationPackageManager;->getReceiverInfo(Landroid/content/ComponentName;I)Landroid/content/pm/ActivityInfo;
 HSPLandroid/app/ApplicationPackageManager;->getReceiverInfo(Landroid/content/ComponentName;Landroid/content/pm/PackageManager$ComponentInfoFlags;)Landroid/content/pm/ActivityInfo;
 HSPLandroid/app/ApplicationPackageManager;->getResourcesForApplication(Landroid/content/pm/ApplicationInfo;)Landroid/content/res/Resources;
-HSPLandroid/app/ApplicationPackageManager;->getResourcesForApplication(Landroid/content/pm/ApplicationInfo;Landroid/content/res/Configuration;)Landroid/content/res/Resources;
+HSPLandroid/app/ApplicationPackageManager;->getResourcesForApplication(Landroid/content/pm/ApplicationInfo;Landroid/content/res/Configuration;)Landroid/content/res/Resources;+]Landroid/app/ActivityThread;Landroid/app/ActivityThread;]Ljava/lang/Object;Ljava/lang/String;
 HSPLandroid/app/ApplicationPackageManager;->getResourcesForApplication(Ljava/lang/String;)Landroid/content/res/Resources;
 HSPLandroid/app/ApplicationPackageManager;->getServiceInfo(Landroid/content/ComponentName;I)Landroid/content/pm/ServiceInfo;
 HSPLandroid/app/ApplicationPackageManager;->getServiceInfo(Landroid/content/ComponentName;Landroid/content/pm/PackageManager$ComponentInfoFlags;)Landroid/content/pm/ServiceInfo;
@@ -1298,7 +1300,7 @@
 HSPLandroid/app/ApplicationPackageManager;->getText(Ljava/lang/String;ILandroid/content/pm/ApplicationInfo;)Ljava/lang/CharSequence;
 HSPLandroid/app/ApplicationPackageManager;->getUserBadgeColor(Landroid/os/UserHandle;Z)I
 HSPLandroid/app/ApplicationPackageManager;->getUserBadgedIcon(Landroid/graphics/drawable/Drawable;Landroid/os/UserHandle;)Landroid/graphics/drawable/Drawable;
-HSPLandroid/app/ApplicationPackageManager;->getUserId()I
+HSPLandroid/app/ApplicationPackageManager;->getUserId()I+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
 HSPLandroid/app/ApplicationPackageManager;->getUserManager()Landroid/os/UserManager;
 HSPLandroid/app/ApplicationPackageManager;->getXml(Ljava/lang/String;ILandroid/content/pm/ApplicationInfo;)Landroid/content/res/XmlResourceParser;
 HSPLandroid/app/ApplicationPackageManager;->handlePackageBroadcast(I[Ljava/lang/String;Z)V
@@ -1323,7 +1325,7 @@
 HSPLandroid/app/ApplicationPackageManager;->queryIntentActivities(Landroid/content/Intent;I)Ljava/util/List;
 HSPLandroid/app/ApplicationPackageManager;->queryIntentActivities(Landroid/content/Intent;Landroid/content/pm/PackageManager$ResolveInfoFlags;)Ljava/util/List;
 HSPLandroid/app/ApplicationPackageManager;->queryIntentActivitiesAsUser(Landroid/content/Intent;II)Ljava/util/List;
-HSPLandroid/app/ApplicationPackageManager;->queryIntentActivitiesAsUser(Landroid/content/Intent;Landroid/content/pm/PackageManager$ResolveInfoFlags;I)Ljava/util/List;+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/content/Intent;Landroid/content/Intent;]Landroid/content/pm/IPackageManager;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/content/pm/PackageManager$ResolveInfoFlags;Landroid/content/pm/PackageManager$ResolveInfoFlags;]Landroid/content/pm/ParceledListSlice;Landroid/content/pm/ParceledListSlice;
+HSPLandroid/app/ApplicationPackageManager;->queryIntentActivitiesAsUser(Landroid/content/Intent;Landroid/content/pm/PackageManager$ResolveInfoFlags;I)Ljava/util/List;+]Landroid/content/pm/IPackageManager;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/content/pm/PackageManager$ResolveInfoFlags;Landroid/content/pm/PackageManager$ResolveInfoFlags;]Landroid/content/pm/ParceledListSlice;Landroid/content/pm/ParceledListSlice;]Landroid/content/Intent;Landroid/content/Intent;
 HSPLandroid/app/ApplicationPackageManager;->queryIntentContentProviders(Landroid/content/Intent;I)Ljava/util/List;
 HSPLandroid/app/ApplicationPackageManager;->queryIntentContentProviders(Landroid/content/Intent;Landroid/content/pm/PackageManager$ResolveInfoFlags;)Ljava/util/List;
 HSPLandroid/app/ApplicationPackageManager;->queryIntentContentProvidersAsUser(Landroid/content/Intent;II)Ljava/util/List;
@@ -1411,7 +1413,7 @@
 HSPLandroid/app/ContextImpl$ApplicationContentResolver;->releaseUnstableProvider(Landroid/content/IContentProvider;)Z
 HSPLandroid/app/ContextImpl$ApplicationContentResolver;->resolveUserIdFromAuthority(Ljava/lang/String;)I
 HSPLandroid/app/ContextImpl$ApplicationContentResolver;->unstableProviderDied(Landroid/content/IContentProvider;)V
-HSPLandroid/app/ContextImpl;-><init>(Landroid/app/ContextImpl;Landroid/app/ActivityThread;Landroid/app/LoadedApk;Landroid/content/ContextParams;Ljava/lang/String;Landroid/content/AttributionSource;Ljava/lang/String;Landroid/os/IBinder;Landroid/os/UserHandle;ILjava/lang/ClassLoader;Ljava/lang/String;IZ)V+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/content/ContextParams;Landroid/content/ContextParams;
+HSPLandroid/app/ContextImpl;-><init>(Landroid/app/ContextImpl;Landroid/app/ActivityThread;Landroid/app/LoadedApk;Landroid/content/ContextParams;Ljava/lang/String;Landroid/content/AttributionSource;Ljava/lang/String;Landroid/os/IBinder;Landroid/os/UserHandle;ILjava/lang/ClassLoader;Ljava/lang/String;IZ)V+]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/content/ContextParams;Landroid/content/ContextParams;
 HSPLandroid/app/ContextImpl;->bindIsolatedService(Landroid/content/Intent;ILjava/lang/String;Ljava/util/concurrent/Executor;Landroid/content/ServiceConnection;)Z
 HSPLandroid/app/ContextImpl;->bindService(Landroid/content/Intent;Landroid/content/ServiceConnection;I)Z
 HSPLandroid/app/ContextImpl;->bindServiceAsUser(Landroid/content/Intent;Landroid/content/ServiceConnection;ILandroid/os/Handler;Landroid/os/UserHandle;)Z
@@ -1431,7 +1433,7 @@
 HSPLandroid/app/ContextImpl;->createAppContext(Landroid/app/ActivityThread;Landroid/app/LoadedApk;Ljava/lang/String;)Landroid/app/ContextImpl;
 HSPLandroid/app/ContextImpl;->createApplicationContext(Landroid/content/pm/ApplicationInfo;I)Landroid/content/Context;
 HSPLandroid/app/ContextImpl;->createAttributionContext(Ljava/lang/String;)Landroid/content/Context;
-HSPLandroid/app/ContextImpl;->createAttributionSource(Ljava/lang/String;Landroid/content/AttributionSource;Ljava/util/Set;ZI)Landroid/content/AttributionSource;+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/permission/PermissionManager;Landroid/permission/PermissionManager;]Ljava/util/Set;missing_types
+HSPLandroid/app/ContextImpl;->createAttributionSource(Ljava/lang/String;Landroid/content/AttributionSource;Ljava/util/Set;ZI)Landroid/content/AttributionSource;+]Ljava/util/Set;missing_types]Landroid/permission/PermissionManager;Landroid/permission/PermissionManager;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
 HSPLandroid/app/ContextImpl;->createConfigurationContext(Landroid/content/res/Configuration;)Landroid/content/Context;
 HSPLandroid/app/ContextImpl;->createContext(Landroid/content/ContextParams;)Landroid/content/Context;
 HSPLandroid/app/ContextImpl;->createContextAsUser(Landroid/os/UserHandle;I)Landroid/content/Context;
@@ -1510,11 +1512,11 @@
 HSPLandroid/app/ContextImpl;->getPreferencesDir()Ljava/io/File;
 HSPLandroid/app/ContextImpl;->getReceiverRestrictedContext()Landroid/content/Context;
 HSPLandroid/app/ContextImpl;->getResources()Landroid/content/res/Resources;
-HSPLandroid/app/ContextImpl;->getSharedPreferences(Ljava/io/File;I)Landroid/content/SharedPreferences;
-HSPLandroid/app/ContextImpl;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;
-HSPLandroid/app/ContextImpl;->getSharedPreferencesCacheLocked()Landroid/util/ArrayMap;
+HSPLandroid/app/ContextImpl;->getSharedPreferences(Ljava/io/File;I)Landroid/content/SharedPreferences;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
+HSPLandroid/app/ContextImpl;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
+HSPLandroid/app/ContextImpl;->getSharedPreferencesCacheLocked()Landroid/util/ArrayMap;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
 HSPLandroid/app/ContextImpl;->getSharedPreferencesPath(Ljava/lang/String;)Ljava/io/File;
-HSPLandroid/app/ContextImpl;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
+HSPLandroid/app/ContextImpl;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;+]Ljava/lang/Object;Ljava/lang/String;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
 HSPLandroid/app/ContextImpl;->getSystemServiceName(Ljava/lang/Class;)Ljava/lang/String;
 HSPLandroid/app/ContextImpl;->getTheme()Landroid/content/res/Resources$Theme;
 HSPLandroid/app/ContextImpl;->getThemeResId()I
@@ -1733,13 +1735,13 @@
 HSPLandroid/app/FragmentManagerImpl;->addFragment(Landroid/app/Fragment;Z)V
 HSPLandroid/app/FragmentManagerImpl;->attachController(Landroid/app/FragmentHostCallback;Landroid/app/FragmentContainer;Landroid/app/Fragment;)V
 HSPLandroid/app/FragmentManagerImpl;->beginTransaction()Landroid/app/FragmentTransaction;
-HSPLandroid/app/FragmentManagerImpl;->burpActive()V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/app/FragmentManagerImpl;->burpActive()V
 HSPLandroid/app/FragmentManagerImpl;->checkStateLoss()V
 HSPLandroid/app/FragmentManagerImpl;->cleanupExec()V
 HSPLandroid/app/FragmentManagerImpl;->dispatchActivityCreated()V
 HSPLandroid/app/FragmentManagerImpl;->dispatchCreate()V
 HSPLandroid/app/FragmentManagerImpl;->dispatchCreateOptionsMenu(Landroid/view/Menu;Landroid/view/MenuInflater;)Z
-HSPLandroid/app/FragmentManagerImpl;->dispatchMoveToState(I)V+]Landroid/app/FragmentManagerImpl;Landroid/app/FragmentManagerImpl;
+HSPLandroid/app/FragmentManagerImpl;->dispatchMoveToState(I)V
 HSPLandroid/app/FragmentManagerImpl;->dispatchOnFragmentActivityCreated(Landroid/app/Fragment;Landroid/os/Bundle;Z)V
 HSPLandroid/app/FragmentManagerImpl;->dispatchOnFragmentAttached(Landroid/app/Fragment;Landroid/content/Context;Z)V
 HSPLandroid/app/FragmentManagerImpl;->dispatchOnFragmentCreated(Landroid/app/Fragment;Landroid/os/Bundle;Z)V
@@ -1762,9 +1764,9 @@
 HSPLandroid/app/FragmentManagerImpl;->doPendingDeferredStart()V
 HSPLandroid/app/FragmentManagerImpl;->endAnimatingAwayFragments()V
 HSPLandroid/app/FragmentManagerImpl;->enqueueAction(Landroid/app/FragmentManagerImpl$OpGenerator;Z)V
-HSPLandroid/app/FragmentManagerImpl;->ensureExecReady(Z)V+]Landroid/app/FragmentHostCallback;Landroid/app/Activity$HostCallbacks;]Landroid/os/Handler;Landroid/os/Handler;
+HSPLandroid/app/FragmentManagerImpl;->ensureExecReady(Z)V
 HSPLandroid/app/FragmentManagerImpl;->ensureInflatedFragmentView(Landroid/app/Fragment;)V
-HSPLandroid/app/FragmentManagerImpl;->execPendingActions()Z+]Landroid/app/FragmentManagerImpl;Landroid/app/FragmentManagerImpl;
+HSPLandroid/app/FragmentManagerImpl;->execPendingActions()Z
 HSPLandroid/app/FragmentManagerImpl;->executeOps(Ljava/util/ArrayList;Ljava/util/ArrayList;II)V
 HSPLandroid/app/FragmentManagerImpl;->executeOpsTogether(Ljava/util/ArrayList;Ljava/util/ArrayList;II)V
 HSPLandroid/app/FragmentManagerImpl;->executePendingTransactions()Z
@@ -1782,9 +1784,9 @@
 HSPLandroid/app/FragmentManagerImpl;->makeInactive(Landroid/app/Fragment;)V
 HSPLandroid/app/FragmentManagerImpl;->makeRemovedFragmentsInvisible(Landroid/util/ArraySet;)V
 HSPLandroid/app/FragmentManagerImpl;->moveFragmentToExpectedState(Landroid/app/Fragment;)V
-HSPLandroid/app/FragmentManagerImpl;->moveToState(IZ)V+]Landroid/app/FragmentManagerImpl;Landroid/app/FragmentManagerImpl;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/app/FragmentManagerImpl;->moveToState(IZ)V
 HSPLandroid/app/FragmentManagerImpl;->moveToState(Landroid/app/Fragment;IIIZ)V
-HSPLandroid/app/FragmentManagerImpl;->noteStateNotSaved()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/app/FragmentManagerImpl;->noteStateNotSaved()V
 HSPLandroid/app/FragmentManagerImpl;->onCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
 HSPLandroid/app/FragmentManagerImpl;->performPendingDeferredStart(Landroid/app/Fragment;)V
 HSPLandroid/app/FragmentManagerImpl;->popBackStackImmediate()Z
@@ -1798,7 +1800,7 @@
 HSPLandroid/app/FragmentManagerImpl;->saveNonConfig()V
 HSPLandroid/app/FragmentManagerImpl;->scheduleCommit()V
 HSPLandroid/app/FragmentManagerImpl;->setRetaining(Landroid/app/FragmentManagerNonConfig;)V
-HSPLandroid/app/FragmentManagerImpl;->startPendingDeferredFragments()V+]Landroid/app/FragmentManagerImpl;Landroid/app/FragmentManagerImpl;]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/app/FragmentManagerImpl;->startPendingDeferredFragments()V
 HSPLandroid/app/FragmentManagerState$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/FragmentManagerState;
 HSPLandroid/app/FragmentManagerState$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/app/FragmentManagerState;-><init>(Landroid/os/Parcel;)V
@@ -1841,11 +1843,12 @@
 HSPLandroid/app/IActivityManager$Stub$Proxy;->attachApplication(Landroid/app/IApplicationThread;J)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->backupAgentCreated(Ljava/lang/String;Landroid/os/IBinder;I)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->bindServiceInstance(Landroid/app/IApplicationThread;Landroid/os/IBinder;Landroid/content/Intent;Ljava/lang/String;Landroid/app/IServiceConnection;JLjava/lang/String;Ljava/lang/String;I)I
-HSPLandroid/app/IActivityManager$Stub$Proxy;->broadcastIntentWithFeature(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/content/IIntentReceiver;ILjava/lang/String;Landroid/os/Bundle;[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;ILandroid/os/Bundle;ZZI)I+]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/IActivityManager$Stub$Proxy;->broadcastIntentWithFeature(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/content/IIntentReceiver;ILjava/lang/String;Landroid/os/Bundle;[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;ILandroid/os/Bundle;ZZI)I
 HSPLandroid/app/IActivityManager$Stub$Proxy;->cancelIntentSender(Landroid/content/IIntentSender;)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->checkPermission(Ljava/lang/String;II)I
-HSPLandroid/app/IActivityManager$Stub$Proxy;->checkPermissionForDevice(Ljava/lang/String;III)I+]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/IActivityManager$Stub$Proxy;->checkPermissionForDevice(Ljava/lang/String;III)I+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/app/IActivityManager$Stub$Proxy;->checkUriPermission(Landroid/net/Uri;IIIILandroid/os/IBinder;)I
+HSPLandroid/app/IActivityManager$Stub$Proxy;->finishAttachApplication(J)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->finishReceiver(Landroid/os/IBinder;ILjava/lang/String;Landroid/os/Bundle;ZI)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->getContentProvider(Landroid/app/IApplicationThread;Ljava/lang/String;Ljava/lang/String;IZ)Landroid/app/ContentProviderHolder;
 HSPLandroid/app/IActivityManager$Stub$Proxy;->getCurrentUser()Landroid/content/pm/UserInfo;
@@ -1872,7 +1875,7 @@
 HSPLandroid/app/IActivityManager$Stub$Proxy;->registerUidObserver(Landroid/app/IUidObserver;IILjava/lang/String;)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->removeContentProvider(Landroid/os/IBinder;Z)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->revokeUriPermission(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/net/Uri;II)V
-HSPLandroid/app/IActivityManager$Stub$Proxy;->serviceDoneExecuting(Landroid/os/IBinder;IIILandroid/content/Intent;)V+]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/IActivityManager$Stub$Proxy;->serviceDoneExecuting(Landroid/os/IBinder;IIILandroid/content/Intent;)V+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/app/IActivityManager$Stub$Proxy;->setRenderThread(I)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->setServiceForeground(Landroid/content/ComponentName;Landroid/os/IBinder;ILandroid/app/Notification;II)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->startService(Landroid/app/IApplicationThread;Landroid/content/Intent;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;I)Landroid/content/ComponentName;
@@ -1931,7 +1934,7 @@
 HSPLandroid/app/INotificationManager$Stub$Proxy;->areNotificationsEnabled(Ljava/lang/String;)Z
 HSPLandroid/app/INotificationManager$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/app/INotificationManager$Stub$Proxy;->cancelAllNotifications(Ljava/lang/String;I)V
-HSPLandroid/app/INotificationManager$Stub$Proxy;->cancelNotificationWithTag(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;II)V+]Landroid/app/INotificationManager$Stub$Proxy;Landroid/app/INotificationManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/INotificationManager$Stub$Proxy;->cancelNotificationWithTag(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;II)V
 HSPLandroid/app/INotificationManager$Stub$Proxy;->createNotificationChannelGroups(Ljava/lang/String;Landroid/content/pm/ParceledListSlice;)V
 HSPLandroid/app/INotificationManager$Stub$Proxy;->createNotificationChannels(Ljava/lang/String;Landroid/content/pm/ParceledListSlice;)V
 HSPLandroid/app/INotificationManager$Stub$Proxy;->deleteNotificationChannel(Ljava/lang/String;Ljava/lang/String;)V
@@ -2035,7 +2038,7 @@
 HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args$$ExternalSyntheticLambda0;->run()V
 HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args;-><init>(Landroid/app/LoadedApk$ReceiverDispatcher;Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZZIILjava/lang/String;)V
 HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args;->getRunnable()Ljava/lang/Runnable;
-HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args;->lambda$getRunnable$0()V+]Landroid/app/LoadedApk$ReceiverDispatcher$Args;Landroid/app/LoadedApk$ReceiverDispatcher$Args;]Landroid/content/Intent;Landroid/content/Intent;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args;->lambda$getRunnable$0()V
 HSPLandroid/app/LoadedApk$ReceiverDispatcher$InnerReceiver;->performReceive(Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZI)V
 HSPLandroid/app/LoadedApk$ReceiverDispatcher$InnerReceiver;->performReceive(Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZZIILjava/lang/String;)V
 HSPLandroid/app/LoadedApk$ReceiverDispatcher;-><init>(Landroid/app/IApplicationThread;Landroid/content/BroadcastReceiver;Landroid/content/Context;Landroid/os/Handler;Landroid/app/Instrumentation;Z)V
@@ -2263,7 +2266,7 @@
 HSPLandroid/app/Notification$Style;->setBuilder(Landroid/app/Notification$Builder;)V
 HSPLandroid/app/Notification$Style;->validate(Landroid/content/Context;)V
 HSPLandroid/app/Notification;-><init>()V
-HSPLandroid/app/Notification;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/app/Notification;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/app/Notification;->addFieldsFromContext(Landroid/content/Context;Landroid/app/Notification;)V
 HSPLandroid/app/Notification;->addFieldsFromContext(Landroid/content/pm/ApplicationInfo;Landroid/app/Notification;)V
 HSPLandroid/app/Notification;->areStyledNotificationsVisiblyDifferent(Landroid/app/Notification$Builder;Landroid/app/Notification$Builder;)Z
@@ -2288,7 +2291,7 @@
 HSPLandroid/app/Notification;->isGroupChild()Z
 HSPLandroid/app/Notification;->isGroupSummary()Z
 HSPLandroid/app/Notification;->isMediaNotification()Z
-HSPLandroid/app/Notification;->readFromParcelImpl(Landroid/os/Parcel;)V
+HSPLandroid/app/Notification;->readFromParcelImpl(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/graphics/drawable/Icon$1;,Landroid/app/PendingIntent$1;,Landroid/media/AudioAttributes$1;]Landroid/graphics/drawable/Icon;Landroid/graphics/drawable/Icon;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/app/Notification;->reduceImageSizes(Landroid/content/Context;)V
 HSPLandroid/app/Notification;->reduceImageSizesForRemoteView(Landroid/widget/RemoteViews;Landroid/content/Context;Z)V
 HSPLandroid/app/Notification;->removeTextSizeSpans(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
@@ -2298,10 +2301,10 @@
 HSPLandroid/app/Notification;->toString()Ljava/lang/String;
 HSPLandroid/app/Notification;->visibilityToString(I)Ljava/lang/String;
 HSPLandroid/app/Notification;->writeToParcel(Landroid/os/Parcel;I)V
-HSPLandroid/app/Notification;->writeToParcelImpl(Landroid/os/Parcel;I)V
+HSPLandroid/app/Notification;->writeToParcelImpl(Landroid/os/Parcel;I)V+]Landroid/app/PendingIntent;Landroid/app/PendingIntent;]Landroid/media/AudioAttributes;Landroid/media/AudioAttributes;]Landroid/graphics/drawable/Icon;Landroid/graphics/drawable/Icon;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/app/NotificationChannel$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/NotificationChannel;
-HSPLandroid/app/NotificationChannel$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/app/NotificationChannel;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/app/NotificationChannel$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/app/NotificationChannel$1;Landroid/app/NotificationChannel$1;
+HSPLandroid/app/NotificationChannel;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/net/Uri$1;,Landroid/media/AudioAttributes$1;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
 HSPLandroid/app/NotificationChannel;-><init>(Ljava/lang/String;Ljava/lang/CharSequence;I)V
 HSPLandroid/app/NotificationChannel;->canBubble()Z
 HSPLandroid/app/NotificationChannel;->canBypassDnd()Z
@@ -2320,7 +2323,7 @@
 HSPLandroid/app/NotificationChannel;->getName()Ljava/lang/CharSequence;
 HSPLandroid/app/NotificationChannel;->getOriginalImportance()I
 HSPLandroid/app/NotificationChannel;->getSound()Landroid/net/Uri;
-HSPLandroid/app/NotificationChannel;->getTrimmedString(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/app/NotificationChannel;->getTrimmedString(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/app/NotificationChannel;->getUserLockedFields()I
 HSPLandroid/app/NotificationChannel;->getVibrationPattern()[J
 HSPLandroid/app/NotificationChannel;->hasUserSetImportance()Z
@@ -2363,7 +2366,7 @@
 HSPLandroid/app/NotificationManager;->cancel(I)V
 HSPLandroid/app/NotificationManager;->cancel(Ljava/lang/String;I)V
 HSPLandroid/app/NotificationManager;->cancelAll()V
-HSPLandroid/app/NotificationManager;->cancelAsUser(Ljava/lang/String;ILandroid/os/UserHandle;)V+]Landroid/app/INotificationManager;Landroid/app/INotificationManager$Stub$Proxy;]Landroid/content/Context;Landroid/view/ContextThemeWrapper;]Landroid/os/UserHandle;Landroid/os/UserHandle;
+HSPLandroid/app/NotificationManager;->cancelAsUser(Ljava/lang/String;ILandroid/os/UserHandle;)V
 HSPLandroid/app/NotificationManager;->createNotificationChannel(Landroid/app/NotificationChannel;)V
 HSPLandroid/app/NotificationManager;->createNotificationChannelGroup(Landroid/app/NotificationChannelGroup;)V
 HSPLandroid/app/NotificationManager;->createNotificationChannelGroups(Ljava/util/List;)V
@@ -2386,6 +2389,7 @@
 HSPLandroid/app/NotificationManager;->notify(Ljava/lang/String;ILandroid/app/Notification;)V
 HSPLandroid/app/NotificationManager;->notifyAsUser(Ljava/lang/String;ILandroid/app/Notification;Landroid/os/UserHandle;)V
 HSPLandroid/app/NotificationManager;->zenModeToInterruptionFilter(I)I
+HSPLandroid/app/PendingIntent$$ExternalSyntheticLambda3;->get()Ljava/lang/Object;
 HSPLandroid/app/PendingIntent$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/PendingIntent;
 HSPLandroid/app/PendingIntent$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/app/PendingIntent$FinishedDispatcher;-><init>(Landroid/app/PendingIntent;Landroid/app/PendingIntent$OnFinished;Landroid/os/Handler;)V
@@ -2443,7 +2447,7 @@
 HSPLandroid/app/PictureInPictureParams$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/app/PictureInPictureParams;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/app/PropertyInvalidatedCache$1;-><init>(Landroid/app/PropertyInvalidatedCache;IFZ)V
-HSPLandroid/app/PropertyInvalidatedCache$1;->removeEldestEntry(Ljava/util/Map$Entry;)Z+]Landroid/app/PropertyInvalidatedCache$1;Landroid/app/PropertyInvalidatedCache$1;
+HSPLandroid/app/PropertyInvalidatedCache$1;->removeEldestEntry(Ljava/util/Map$Entry;)Z
 HSPLandroid/app/PropertyInvalidatedCache$DefaultComputer;-><init>(Landroid/app/PropertyInvalidatedCache;)V
 HSPLandroid/app/PropertyInvalidatedCache$NoPreloadHolder;-><clinit>()V
 HSPLandroid/app/PropertyInvalidatedCache$NoPreloadHolder;->next()J
@@ -2470,7 +2474,7 @@
 HSPLandroid/app/PropertyInvalidatedCache;->isDisabled()Z
 HSPLandroid/app/PropertyInvalidatedCache;->isReservedNonce(J)Z
 HSPLandroid/app/PropertyInvalidatedCache;->maybeCheckConsistency(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
-HSPLandroid/app/PropertyInvalidatedCache;->query(Ljava/lang/Object;)Ljava/lang/Object;+]Landroid/app/PropertyInvalidatedCache;megamorphic_types]Ljava/util/LinkedHashMap;Landroid/app/PropertyInvalidatedCache$1;
+HSPLandroid/app/PropertyInvalidatedCache;->query(Ljava/lang/Object;)Ljava/lang/Object;+]Ljava/util/LinkedHashMap;Landroid/app/PropertyInvalidatedCache$1;]Landroid/app/PropertyInvalidatedCache;megamorphic_types
 HSPLandroid/app/PropertyInvalidatedCache;->recompute(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/app/PropertyInvalidatedCache;->refresh(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/app/PropertyInvalidatedCache;->registerCache()V
@@ -2539,7 +2543,7 @@
 HSPLandroid/app/ResourcesManager;->createResourcesForActivity(Landroid/os/IBinder;Landroid/content/res/ResourcesKey;Landroid/content/res/Configuration;Ljava/lang/Integer;Ljava/lang/ClassLoader;Landroid/app/ResourcesManager$ApkAssetsSupplier;)Landroid/content/res/Resources;
 HSPLandroid/app/ResourcesManager;->createResourcesForActivityLocked(Landroid/os/IBinder;Landroid/content/res/Configuration;Ljava/lang/Integer;Ljava/lang/ClassLoader;Landroid/content/res/ResourcesImpl;Landroid/content/res/CompatibilityInfo;)Landroid/content/res/Resources;
 HSPLandroid/app/ResourcesManager;->createResourcesImpl(Landroid/content/res/ResourcesKey;Landroid/app/ResourcesManager$ApkAssetsSupplier;)Landroid/content/res/ResourcesImpl;
-HSPLandroid/app/ResourcesManager;->createResourcesLocked(Ljava/lang/ClassLoader;Landroid/content/res/ResourcesImpl;Landroid/content/res/CompatibilityInfo;)Landroid/content/res/Resources;
+HSPLandroid/app/ResourcesManager;->createResourcesLocked(Ljava/lang/ClassLoader;Landroid/content/res/ResourcesImpl;Landroid/content/res/CompatibilityInfo;)Landroid/content/res/Resources;+]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/app/ResourcesManager;->extractApkKeys(Landroid/content/res/ResourcesKey;)Ljava/util/ArrayList;+]Ljava/lang/String;Ljava/lang/String;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/app/ResourcesManager;->findKeyForResourceImplLocked(Landroid/content/res/ResourcesImpl;)Landroid/content/res/ResourcesKey;
 HSPLandroid/app/ResourcesManager;->findOrCreateResourcesImplForKeyLocked(Landroid/content/res/ResourcesKey;)Landroid/content/res/ResourcesImpl;
@@ -2561,7 +2565,7 @@
 HSPLandroid/app/ResourcesManager;->isSameResourcesOverrideConfig(Landroid/os/IBinder;Landroid/content/res/Configuration;)Z
 HSPLandroid/app/ResourcesManager;->lambda$cleanupReferences$1(Ljava/util/function/Function;Ljava/util/HashSet;Ljava/lang/Object;)Z
 HSPLandroid/app/ResourcesManager;->lambda$createResourcesForActivityLocked$0(Landroid/app/ResourcesManager$ActivityResource;)Ljava/lang/ref/WeakReference;
-HSPLandroid/app/ResourcesManager;->loadApkAssets(Landroid/app/ResourcesManager$ApkKey;)Landroid/content/res/ApkAssets;+]Landroid/content/res/ApkAssets;Landroid/content/res/ApkAssets;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/app/ResourcesManager;->loadApkAssets(Landroid/app/ResourcesManager$ApkKey;)Landroid/content/res/ApkAssets;
 HSPLandroid/app/ResourcesManager;->overlayPathToIdmapPath(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/app/ResourcesManager;->rebaseActivityOverrideConfig(Landroid/app/ResourcesManager$ActivityResource;Landroid/content/res/Configuration;I)Landroid/content/res/ResourcesKey;
 HSPLandroid/app/ResourcesManager;->rebaseKeyForActivity(Landroid/os/IBinder;Landroid/content/res/ResourcesKey;Z)V
@@ -2613,7 +2617,7 @@
 HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->apply()V
 HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->clear()Landroid/content/SharedPreferences$Editor;
 HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->commit()Z
-HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->commitToMemory()Landroid/app/SharedPreferencesImpl$MemoryCommitResult;
+HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->commitToMemory()Landroid/app/SharedPreferencesImpl$MemoryCommitResult;+]Ljava/util/Map$Entry;Ljava/util/HashMap$Node;]Ljava/lang/Object;Ljava/lang/String;,Ljava/lang/Boolean;,Ljava/lang/Long;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;]Ljava/util/Map;Ljava/util/HashMap;]Ljava/util/Iterator;Ljava/util/HashMap$EntryIterator;]Ljava/util/Set;Ljava/util/HashMap$EntrySet;
 HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->notifyListeners(Landroid/app/SharedPreferencesImpl$MemoryCommitResult;)V
 HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->putBoolean(Ljava/lang/String;Z)Landroid/content/SharedPreferences$Editor;
 HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->putFloat(Ljava/lang/String;F)Landroid/content/SharedPreferences$Editor;
@@ -2658,7 +2662,7 @@
 HSPLandroid/app/SharedPreferencesImpl;->startLoadFromDisk()V
 HSPLandroid/app/SharedPreferencesImpl;->startReloadIfChangedUnexpectedly()V
 HSPLandroid/app/SharedPreferencesImpl;->unregisterOnSharedPreferenceChangeListener(Landroid/content/SharedPreferences$OnSharedPreferenceChangeListener;)V
-HSPLandroid/app/SharedPreferencesImpl;->writeToFile(Landroid/app/SharedPreferencesImpl$MemoryCommitResult;Z)V
+HSPLandroid/app/SharedPreferencesImpl;->writeToFile(Landroid/app/SharedPreferencesImpl$MemoryCommitResult;Z)V+]Ljava/io/File;Ljava/io/File;]Lcom/android/internal/util/ExponentiallyBucketedHistogram;Lcom/android/internal/util/ExponentiallyBucketedHistogram;]Landroid/app/SharedPreferencesImpl$MemoryCommitResult;Landroid/app/SharedPreferencesImpl$MemoryCommitResult;]Ljava/io/FileOutputStream;Ljava/io/FileOutputStream;
 HSPLandroid/app/StackTrace;-><init>(Ljava/lang/String;)V
 HSPLandroid/app/StatusBarManager;-><init>(Landroid/content/Context;)V
 HSPLandroid/app/SyncNotedAppOp$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/SyncNotedAppOp;
@@ -2743,9 +2747,11 @@
 HSPLandroid/app/SystemServiceRegistry$3;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$40;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$41;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$42;->createService(Landroid/app/ContextImpl;)Landroid/hardware/SensorManager;
 HSPLandroid/app/SystemServiceRegistry$42;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$43;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$44;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$45;->createService(Landroid/app/ContextImpl;)Landroid/os/storage/StorageManager;
 HSPLandroid/app/SystemServiceRegistry$45;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$46;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$47;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
@@ -2764,6 +2770,7 @@
 HSPLandroid/app/SystemServiceRegistry$57;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$58;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$59;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$60;->createService(Landroid/app/ContextImpl;)Landroid/view/WindowManager;
 HSPLandroid/app/SystemServiceRegistry$60;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$61;->createService(Landroid/app/ContextImpl;)Landroid/os/UserManager;
 HSPLandroid/app/SystemServiceRegistry$61;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
@@ -2774,6 +2781,7 @@
 HSPLandroid/app/SystemServiceRegistry$65;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$66;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$67;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$68;->createService(Landroid/app/ContextImpl;)Landroid/companion/virtual/VirtualDeviceManager;+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/content/res/Resources;Landroid/content/res/Resources;
 HSPLandroid/app/SystemServiceRegistry$68;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$71;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$74;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
@@ -2802,7 +2810,7 @@
 HSPLandroid/app/SystemServiceRegistry$98;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$99;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$9;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
-HSPLandroid/app/SystemServiceRegistry$CachedServiceFetcher;->getService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$CachedServiceFetcher;->getService(Landroid/app/ContextImpl;)Ljava/lang/Object;+]Landroid/app/SystemServiceRegistry$CachedServiceFetcher;megamorphic_types]Ljava/lang/Object;[Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$StaticServiceFetcher;->getService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry;->createServiceCache()[Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry;->getSystemService(Landroid/app/ContextImpl;Ljava/lang/String;)Ljava/lang/Object;+]Landroid/app/SystemServiceRegistry$ServiceFetcher;megamorphic_types
@@ -2857,6 +2865,7 @@
 HSPLandroid/app/WindowConfiguration;-><init>()V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
 HSPLandroid/app/WindowConfiguration;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/app/WindowConfiguration;->activityTypeToString(I)Ljava/lang/String;
+HSPLandroid/app/WindowConfiguration;->areConfigurationsEqualForDisplay(Landroid/content/res/Configuration;Landroid/content/res/Configuration;)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
 HSPLandroid/app/WindowConfiguration;->canReceiveKeys()Z
 HSPLandroid/app/WindowConfiguration;->compareTo(Landroid/app/WindowConfiguration;)I
 HSPLandroid/app/WindowConfiguration;->diff(Landroid/app/WindowConfiguration;Z)J+]Landroid/graphics/Rect;Landroid/graphics/Rect;
@@ -2868,17 +2877,19 @@
 HSPLandroid/app/WindowConfiguration;->getMaxBounds()Landroid/graphics/Rect;
 HSPLandroid/app/WindowConfiguration;->getRotation()I
 HSPLandroid/app/WindowConfiguration;->getWindowingMode()I
+HSPLandroid/app/WindowConfiguration;->hasWindowDecorCaption()Z
 HSPLandroid/app/WindowConfiguration;->hasWindowShadow()Z
 HSPLandroid/app/WindowConfiguration;->inMultiWindowMode(I)Z
 HSPLandroid/app/WindowConfiguration;->isFloating(I)Z
-HSPLandroid/app/WindowConfiguration;->readFromParcel(Landroid/os/Parcel;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/WindowConfiguration;->readFromParcel(Landroid/os/Parcel;)V
 HSPLandroid/app/WindowConfiguration;->setActivityType(I)V
 HSPLandroid/app/WindowConfiguration;->setAlwaysOnTop(I)V
-HSPLandroid/app/WindowConfiguration;->setAppBounds(IIII)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
-HSPLandroid/app/WindowConfiguration;->setAppBounds(Landroid/graphics/Rect;)V
-HSPLandroid/app/WindowConfiguration;->setBounds(Landroid/graphics/Rect;)V
+HSPLandroid/app/WindowConfiguration;->setAppBounds(IIII)V
+HSPLandroid/app/WindowConfiguration;->setAppBounds(Landroid/graphics/Rect;)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
+HSPLandroid/app/WindowConfiguration;->setBounds(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
 HSPLandroid/app/WindowConfiguration;->setDisplayRotation(I)V
-HSPLandroid/app/WindowConfiguration;->setMaxBounds(Landroid/graphics/Rect;)V
+HSPLandroid/app/WindowConfiguration;->setDisplayWindowingMode(I)V
+HSPLandroid/app/WindowConfiguration;->setMaxBounds(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
 HSPLandroid/app/WindowConfiguration;->setRotation(I)V
 HSPLandroid/app/WindowConfiguration;->setTo(Landroid/app/WindowConfiguration;)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
 HSPLandroid/app/WindowConfiguration;->setTo(Landroid/app/WindowConfiguration;I)V
@@ -2887,7 +2898,7 @@
 HSPLandroid/app/WindowConfiguration;->tasksAreFloating()Z
 HSPLandroid/app/WindowConfiguration;->toString()Ljava/lang/String;
 HSPLandroid/app/WindowConfiguration;->unset()V
-HSPLandroid/app/WindowConfiguration;->updateFrom(Landroid/app/WindowConfiguration;)I+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/app/WindowConfiguration;->updateFrom(Landroid/app/WindowConfiguration;)I+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
 HSPLandroid/app/WindowConfiguration;->windowingModeToString(I)Ljava/lang/String;
 HSPLandroid/app/WindowConfiguration;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/app/admin/DevicePolicyManager$$ExternalSyntheticLambda5;-><init>(Landroid/app/admin/DevicePolicyManager;)V
@@ -3153,10 +3164,10 @@
 HSPLandroid/app/job/JobInfo$TriggerContentUri$1;->newArray(I)[Ljava/lang/Object;
 HSPLandroid/app/job/JobInfo$TriggerContentUri;-><init>(Landroid/net/Uri;I)V
 HSPLandroid/app/job/JobInfo$TriggerContentUri;->writeToParcel(Landroid/os/Parcel;I)V
-HSPLandroid/app/job/JobInfo;-><init>(Landroid/app/job/JobInfo$Builder;)V
+HSPLandroid/app/job/JobInfo;-><init>(Landroid/app/job/JobInfo$Builder;)V+]Landroid/os/PersistableBundle;Landroid/os/PersistableBundle;]Landroid/os/Bundle;Landroid/os/Bundle;
 HSPLandroid/app/job/JobInfo;-><init>(Landroid/app/job/JobInfo$Builder;Landroid/app/job/JobInfo-IA;)V
-HSPLandroid/app/job/JobInfo;-><init>(Landroid/os/Parcel;)V
-HSPLandroid/app/job/JobInfo;->enforceValidity(ZZZZ)V+]Landroid/content/ComponentName;Landroid/content/ComponentName;]Landroid/net/NetworkRequest;Landroid/net/NetworkRequest;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/app/job/JobInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/net/NetworkRequest$1;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/job/JobInfo;->enforceValidity(ZZZZ)V+]Landroid/net/NetworkRequest;Landroid/net/NetworkRequest;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/content/ComponentName;Landroid/content/ComponentName;
 HSPLandroid/app/job/JobInfo;->getExtras()Landroid/os/PersistableBundle;
 HSPLandroid/app/job/JobInfo;->getFlags()I
 HSPLandroid/app/job/JobInfo;->getFlexMillis()J
@@ -3175,7 +3186,7 @@
 HSPLandroid/app/job/JobInfo;->isRequireCharging()Z
 HSPLandroid/app/job/JobInfo;->isRequireDeviceIdle()Z
 HSPLandroid/app/job/JobInfo;->validateTraceTag(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/app/job/JobInfo;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/app/job/JobInfo;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/net/NetworkRequest;Landroid/net/NetworkRequest;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/app/job/JobParameters$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/job/JobParameters;
 HSPLandroid/app/job/JobParameters$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/app/job/JobParameters;-><init>(Landroid/os/Parcel;)V
@@ -3263,13 +3274,14 @@
 HSPLandroid/app/servertransaction/ActivityTransactionItem;-><init>()V
 HSPLandroid/app/servertransaction/ClientTransaction$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/servertransaction/ClientTransaction;
 HSPLandroid/app/servertransaction/ClientTransaction$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/app/servertransaction/ClientTransaction;-><init>(Landroid/os/Parcel;)V+]Landroid/app/servertransaction/ClientTransactionItem;megamorphic_types]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;Landroid/app/servertransaction/ClientTransaction;]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/app/servertransaction/ClientTransaction;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/app/servertransaction/ClientTransaction;-><init>(Landroid/os/Parcel;Landroid/app/servertransaction/ClientTransaction-IA;)V
 HSPLandroid/app/servertransaction/ClientTransaction;->getCallbacks()Ljava/util/List;
 HSPLandroid/app/servertransaction/ClientTransaction;->getLifecycleStateRequest()Landroid/app/servertransaction/ActivityLifecycleItem;
-HSPLandroid/app/servertransaction/ClientTransaction;->preExecute(Landroid/app/ClientTransactionHandler;)V+]Landroid/app/servertransaction/ClientTransactionItem;megamorphic_types]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/app/servertransaction/ClientTransaction;->preExecute(Landroid/app/ClientTransactionHandler;)V
 HSPLandroid/app/servertransaction/ClientTransactionItem;-><init>()V
 HSPLandroid/app/servertransaction/ClientTransactionItem;->getPostExecutionState()I
+HSPLandroid/app/servertransaction/ClientTransactionItem;->isActivityLifecycleItem()Z
 HSPLandroid/app/servertransaction/ClientTransactionItem;->shouldHaveDefinedPreExecutionState()Z
 HSPLandroid/app/servertransaction/ConfigurationChangeItem$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/servertransaction/ConfigurationChangeItem;
 HSPLandroid/app/servertransaction/ConfigurationChangeItem$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -3330,11 +3342,13 @@
 HSPLandroid/app/servertransaction/TransactionExecutor;->execute(Landroid/app/servertransaction/ClientTransaction;)V
 HSPLandroid/app/servertransaction/TransactionExecutor;->executeCallbacks(Landroid/app/servertransaction/ClientTransaction;)V
 HSPLandroid/app/servertransaction/TransactionExecutor;->executeLifecycleState(Landroid/app/servertransaction/ClientTransaction;)V
-HSPLandroid/app/servertransaction/TransactionExecutor;->performLifecycleSequence(Landroid/app/ActivityThread$ActivityClientRecord;Landroid/util/IntArray;Landroid/app/servertransaction/ClientTransaction;)V+]Landroid/app/ClientTransactionHandler;Landroid/app/ActivityThread;]Landroid/util/IntArray;Landroid/util/IntArray;
+HSPLandroid/app/servertransaction/TransactionExecutor;->executeNonLifecycleItem(Landroid/app/servertransaction/ClientTransaction;Landroid/app/servertransaction/ClientTransactionItem;Z)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/servertransaction/TransactionExecutorHelper;Landroid/app/servertransaction/TransactionExecutorHelper;]Landroid/app/ClientTransactionHandler;Landroid/app/ActivityThread;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/servertransaction/ClientTransactionItem;megamorphic_types]Landroid/content/Context;missing_types]Ljava/util/Map;Ljava/util/Collections$SynchronizedMap;]Landroid/app/servertransaction/TransactionExecutor;Landroid/app/servertransaction/TransactionExecutor;
+HSPLandroid/app/servertransaction/TransactionExecutor;->executeTransactionItems(Landroid/app/servertransaction/ClientTransaction;)V+]Landroid/app/servertransaction/ClientTransaction;Landroid/app/servertransaction/ClientTransaction;]Ljava/util/List;Ljava/util/ArrayList;]Landroid/app/servertransaction/ClientTransactionItem;megamorphic_types
+HSPLandroid/app/servertransaction/TransactionExecutor;->performLifecycleSequence(Landroid/app/ActivityThread$ActivityClientRecord;Landroid/util/IntArray;Landroid/app/servertransaction/ClientTransaction;)V
 HSPLandroid/app/servertransaction/TransactionExecutorHelper;-><init>()V
 HSPLandroid/app/servertransaction/TransactionExecutorHelper;->getClosestOfStates(Landroid/app/ActivityThread$ActivityClientRecord;[I)I
 HSPLandroid/app/servertransaction/TransactionExecutorHelper;->getClosestPreExecutionState(Landroid/app/ActivityThread$ActivityClientRecord;I)I
-HSPLandroid/app/servertransaction/TransactionExecutorHelper;->getLifecyclePath(IIZ)Landroid/util/IntArray;+]Landroid/util/IntArray;Landroid/util/IntArray;
+HSPLandroid/app/servertransaction/TransactionExecutorHelper;->getLifecyclePath(IIZ)Landroid/util/IntArray;
 HSPLandroid/app/servertransaction/TransactionExecutorHelper;->lastCallbackRequestingState(Landroid/app/servertransaction/ClientTransaction;)I
 HSPLandroid/app/slice/ISliceManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 HSPLandroid/app/slice/ISliceManager$Stub$Proxy;->getPinnedSlices(Ljava/lang/String;)[Landroid/net/Uri;
@@ -3426,10 +3440,10 @@
 HSPLandroid/app/usage/UsageEvents;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/app/usage/UsageEvents;->getNextEvent(Landroid/app/usage/UsageEvents$Event;)Z
 HSPLandroid/app/usage/UsageEvents;->hasNextEvent()Z
-HSPLandroid/app/usage/UsageEvents;->readEventFromParcel(Landroid/os/Parcel;Landroid/app/usage/UsageEvents$Event;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/content/res/Configuration$1;
-HSPLandroid/app/usage/UsageStats$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/usage/UsageStats;+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
-HSPLandroid/app/usage/UsageStats$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/app/usage/UsageStats$1;Landroid/app/usage/UsageStats$1;
-HSPLandroid/app/usage/UsageStats$1;->readBundleToEventMap(Landroid/os/Bundle;Landroid/util/ArrayMap;)V+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
+HSPLandroid/app/usage/UsageEvents;->readEventFromParcel(Landroid/os/Parcel;Landroid/app/usage/UsageEvents$Event;)V
+HSPLandroid/app/usage/UsageStats$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/usage/UsageStats;+]Landroid/os/Bundle;Landroid/os/Bundle;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
+HSPLandroid/app/usage/UsageStats$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/app/usage/UsageStats$1;->readBundleToEventMap(Landroid/os/Bundle;Landroid/util/ArrayMap;)V
 HSPLandroid/app/usage/UsageStats;-><init>()V
 HSPLandroid/app/usage/UsageStats;->getPackageName()Ljava/lang/String;
 HSPLandroid/app/usage/UsageStats;->update(Ljava/lang/String;JII)V
@@ -3452,7 +3466,7 @@
 HSPLandroid/appwidget/AppWidgetProvider;->onReceive(Landroid/content/Context;Landroid/content/Intent;)V
 HSPLandroid/appwidget/AppWidgetProviderInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/appwidget/AppWidgetProviderInfo;
 HSPLandroid/appwidget/AppWidgetProviderInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/appwidget/AppWidgetProviderInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/appwidget/AppWidgetProviderInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/appwidget/AppWidgetProviderInfo;->getProfile()Landroid/os/UserHandle;
 HSPLandroid/appwidget/AppWidgetProviderInfo;->updateDimensions(Landroid/util/DisplayMetrics;)V
 HSPLandroid/appwidget/AppWidgetProviderInfo;->writeToParcel(Landroid/os/Parcel;I)V
@@ -3463,6 +3477,10 @@
 HSPLandroid/companion/virtual/IVirtualDeviceManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/companion/virtual/IVirtualDeviceManager;
 HSPLandroid/companion/virtual/VirtualDeviceManager;-><init>(Landroid/companion/virtual/IVirtualDeviceManager;Landroid/content/Context;)V
 HSPLandroid/companion/virtual/VirtualDeviceManager;->getDeviceIdForDisplayId(I)I
+HSPLandroid/companion/virtual/flags/FeatureFlagsImpl;-><init>()V
+HSPLandroid/companion/virtual/flags/FeatureFlagsImpl;->enableNativeVdm()Z
+HSPLandroid/companion/virtual/flags/Flags;-><clinit>()V
+HSPLandroid/companion/virtual/flags/Flags;->enableNativeVdm()Z+]Landroid/companion/virtual/flags/FeatureFlags;Landroid/companion/virtual/flags/FeatureFlagsImpl;
 HSPLandroid/content/AbstractThreadedSyncAdapter$ISyncAdapterImpl;->cancelSync(Landroid/content/ISyncContext;)V
 HSPLandroid/content/AbstractThreadedSyncAdapter$ISyncAdapterImpl;->isCallerSystem()Z
 HSPLandroid/content/AbstractThreadedSyncAdapter$ISyncAdapterImpl;->startSync(Landroid/content/ISyncContext;Ljava/lang/String;Landroid/accounts/Account;Landroid/os/Bundle;)V
@@ -3489,6 +3507,7 @@
 HSPLandroid/content/AttributionSource$ScopedParcelState;->getParcel()Landroid/os/Parcel;
 HSPLandroid/content/AttributionSource;-><clinit>()V
 HSPLandroid/content/AttributionSource;-><init>(IILjava/lang/String;Ljava/lang/String;Landroid/os/IBinder;[Ljava/lang/String;ILandroid/content/AttributionSource;)V
+HSPLandroid/content/AttributionSource;-><init>(IILjava/lang/String;Ljava/lang/String;Landroid/os/IBinder;[Ljava/lang/String;Landroid/content/AttributionSource;)V
 HSPLandroid/content/AttributionSource;-><init>(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;ILandroid/content/AttributionSource;)V
 HSPLandroid/content/AttributionSource;-><init>(ILjava/lang/String;Ljava/lang/String;)V
 HSPLandroid/content/AttributionSource;-><init>(ILjava/lang/String;Ljava/lang/String;Landroid/os/IBinder;)V
@@ -3600,20 +3619,22 @@
 HSPLandroid/content/ComponentName;->getPackageName()Ljava/lang/String;
 HSPLandroid/content/ComponentName;->getShortClassName()Ljava/lang/String;
 HSPLandroid/content/ComponentName;->hashCode()I
-HSPLandroid/content/ComponentName;->readFromParcel(Landroid/os/Parcel;)Landroid/content/ComponentName;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/ComponentName;->readFromParcel(Landroid/os/Parcel;)Landroid/content/ComponentName;
 HSPLandroid/content/ComponentName;->toShortString()Ljava/lang/String;
 HSPLandroid/content/ComponentName;->toString()Ljava/lang/String;
-HSPLandroid/content/ComponentName;->unflattenFromString(Ljava/lang/String;)Landroid/content/ComponentName;
+HSPLandroid/content/ComponentName;->unflattenFromString(Ljava/lang/String;)Landroid/content/ComponentName;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/content/ComponentName;->writeToParcel(Landroid/content/ComponentName;Landroid/os/Parcel;)V
 HSPLandroid/content/ComponentName;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/ContentCaptureOptions$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/ContentCaptureOptions;
 HSPLandroid/content/ContentCaptureOptions$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda1;-><init>()V
 HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda1;->apply(I)Ljava/lang/Object;
+HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda2;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda2;->accept(Ljava/lang/Object;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->-$$Nest$smcreateFromParcel(Landroid/os/Parcel;)Landroid/content/ContentCaptureOptions$ContentProtectionOptions;
 HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;-><init>(ZILjava/util/List;Ljava/util/List;I)V
 HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->createFromParcel(Landroid/os/Parcel;)Landroid/content/ContentCaptureOptions$ContentProtectionOptions;
-HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->createGroupsFromParcel(Landroid/os/Parcel;)Ljava/util/List;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/stream/IntStream;Ljava/util/stream/IntPipeline$Head;]Ljava/util/stream/Stream;Ljava/util/stream/IntPipeline$4;,Ljava/util/stream/ReferencePipeline$11;
+HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->createGroupsFromParcel(Landroid/os/Parcel;)Ljava/util/List;+]Ljava/util/stream/Stream;Ljava/util/stream/IntPipeline$4;,Ljava/util/stream/ReferencePipeline$11;,Ljava/util/stream/ReferencePipeline$15;,Ljava/util/stream/IntPipeline$1;]Ljava/util/stream/IntStream;Ljava/util/stream/IntPipeline$Head;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->lambda$createGroupsFromParcel$0(I)Ljava/util/ArrayList;
 HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->writeToParcel(Landroid/os/Parcel;)V
 HSPLandroid/content/ContentCaptureOptions;-><init>(IIIIILandroid/util/ArraySet;)V
@@ -3648,6 +3669,7 @@
 HSPLandroid/content/ContentProvider;->clearCallingIdentity()Landroid/content/ContentProvider$CallingIdentity;
 HSPLandroid/content/ContentProvider;->coerceToLocalContentProvider(Landroid/content/IContentProvider;)Landroid/content/ContentProvider;
 HSPLandroid/content/ContentProvider;->delete(Landroid/net/Uri;Landroid/os/Bundle;)I
+HSPLandroid/content/ContentProvider;->deniedAccessSystemUserOnlyProvider(IZ)Z
 HSPLandroid/content/ContentProvider;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
 HSPLandroid/content/ContentProvider;->enforceReadPermissionInner(Landroid/net/Uri;Landroid/content/AttributionSource;)I
 HSPLandroid/content/ContentProvider;->enforceWritePermissionInner(Landroid/net/Uri;Landroid/content/AttributionSource;)I
@@ -3724,7 +3746,7 @@
 HSPLandroid/content/ContentProviderOperation$Builder;->withValues(Landroid/content/ContentValues;)Landroid/content/ContentProviderOperation$Builder;
 HSPLandroid/content/ContentProviderOperation;-><init>(Landroid/content/ContentProviderOperation$Builder;)V
 HSPLandroid/content/ContentProviderOperation;->apply(Landroid/content/ContentProvider;[Landroid/content/ContentProviderResult;I)Landroid/content/ContentProviderResult;
-HSPLandroid/content/ContentProviderOperation;->applyInternal(Landroid/content/ContentProvider;[Landroid/content/ContentProviderResult;I)Landroid/content/ContentProviderResult;
+HSPLandroid/content/ContentProviderOperation;->applyInternal(Landroid/content/ContentProvider;[Landroid/content/ContentProviderResult;I)Landroid/content/ContentProviderResult;+]Landroid/content/ContentProviderOperation;Landroid/content/ContentProviderOperation;
 HSPLandroid/content/ContentProviderOperation;->getUri()Landroid/net/Uri;
 HSPLandroid/content/ContentProviderOperation;->isInsert()Z
 HSPLandroid/content/ContentProviderOperation;->isReadOperation()Z
@@ -3736,7 +3758,7 @@
 HSPLandroid/content/ContentProviderOperation;->newUpdate(Landroid/net/Uri;)Landroid/content/ContentProviderOperation$Builder;
 HSPLandroid/content/ContentProviderOperation;->resolveExtrasBackReferences([Landroid/content/ContentProviderResult;I)Landroid/os/Bundle;
 HSPLandroid/content/ContentProviderOperation;->resolveSelectionArgsBackReferences([Landroid/content/ContentProviderResult;I)[Ljava/lang/String;
-HSPLandroid/content/ContentProviderOperation;->resolveValueBackReferences([Landroid/content/ContentProviderResult;I)Landroid/content/ContentValues;
+HSPLandroid/content/ContentProviderOperation;->resolveValueBackReferences([Landroid/content/ContentProviderResult;I)Landroid/content/ContentValues;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/content/ContentValues;Landroid/content/ContentValues;
 HSPLandroid/content/ContentProviderOperation;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/ContentProviderProxy;-><init>(Landroid/os/IBinder;)V
 HSPLandroid/content/ContentProviderProxy;->asBinder()Landroid/os/IBinder;
@@ -3745,7 +3767,7 @@
 HSPLandroid/content/ContentProviderProxy;->delete(Landroid/content/AttributionSource;Landroid/net/Uri;Landroid/os/Bundle;)I
 HSPLandroid/content/ContentProviderProxy;->insert(Landroid/content/AttributionSource;Landroid/net/Uri;Landroid/content/ContentValues;Landroid/os/Bundle;)Landroid/net/Uri;
 HSPLandroid/content/ContentProviderProxy;->openTypedAssetFile(Landroid/content/AttributionSource;Landroid/net/Uri;Ljava/lang/String;Landroid/os/Bundle;Landroid/os/ICancellationSignal;)Landroid/content/res/AssetFileDescriptor;
-HSPLandroid/content/ContentProviderProxy;->query(Landroid/content/AttributionSource;Landroid/net/Uri;[Ljava/lang/String;Landroid/os/Bundle;Landroid/os/ICancellationSignal;)Landroid/database/Cursor;
+HSPLandroid/content/ContentProviderProxy;->query(Landroid/content/AttributionSource;Landroid/net/Uri;[Ljava/lang/String;Landroid/os/Bundle;Landroid/os/ICancellationSignal;)Landroid/database/Cursor;+]Landroid/content/AttributionSource;Landroid/content/AttributionSource;]Landroid/os/Parcelable$Creator;Landroid/database/BulkCursorDescriptor$1;]Landroid/database/IBulkCursor;Landroid/database/BulkCursorProxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/ICancellationSignal;Landroid/os/ICancellationSignal$Stub$Proxy;]Landroid/database/BulkCursorToCursorAdaptor;Landroid/database/BulkCursorToCursorAdaptor;]Landroid/database/IContentObserver;Landroid/database/ContentObserver$Transport;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/net/Uri;Landroid/net/Uri$HierarchicalUri;,Landroid/net/Uri$StringUri;
 HSPLandroid/content/ContentProviderProxy;->update(Landroid/content/AttributionSource;Landroid/net/Uri;Landroid/content/ContentValues;Landroid/os/Bundle;)I
 HSPLandroid/content/ContentProviderResult$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/ContentProviderResult;
 HSPLandroid/content/ContentProviderResult$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -3862,7 +3884,7 @@
 HSPLandroid/content/ContentValues;->putObject(Ljava/lang/String;Ljava/lang/Object;)V
 HSPLandroid/content/ContentValues;->remove(Ljava/lang/String;)V
 HSPLandroid/content/ContentValues;->size()I
-HSPLandroid/content/ContentValues;->toString()Ljava/lang/String;+]Landroid/content/ContentValues;Landroid/content/ContentValues;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
+HSPLandroid/content/ContentValues;->toString()Ljava/lang/String;
 HSPLandroid/content/ContentValues;->valueSet()Ljava/util/Set;
 HSPLandroid/content/ContentValues;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/Context;-><init>()V
@@ -3876,11 +3898,11 @@
 HSPLandroid/content/Context;->getSystemService(Ljava/lang/Class;)Ljava/lang/Object;
 HSPLandroid/content/Context;->getText(I)Ljava/lang/CharSequence;
 HSPLandroid/content/Context;->getToken(Landroid/content/Context;)Landroid/os/IBinder;
-HSPLandroid/content/Context;->isAutofillCompatibilityEnabled()Z+]Landroid/content/Context;missing_types
-HSPLandroid/content/Context;->obtainStyledAttributes(I[I)Landroid/content/res/TypedArray;+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
-HSPLandroid/content/Context;->obtainStyledAttributes(Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
-HSPLandroid/content/Context;->obtainStyledAttributes(Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
-HSPLandroid/content/Context;->obtainStyledAttributes([I)Landroid/content/res/TypedArray;+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
+HSPLandroid/content/Context;->isAutofillCompatibilityEnabled()Z
+HSPLandroid/content/Context;->obtainStyledAttributes(I[I)Landroid/content/res/TypedArray;
+HSPLandroid/content/Context;->obtainStyledAttributes(Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;
+HSPLandroid/content/Context;->obtainStyledAttributes(Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/Context;missing_types
+HSPLandroid/content/Context;->obtainStyledAttributes([I)Landroid/content/res/TypedArray;
 HSPLandroid/content/Context;->registerComponentCallbacks(Landroid/content/ComponentCallbacks;)V
 HSPLandroid/content/Context;->unregisterComponentCallbacks(Landroid/content/ComponentCallbacks;)V
 HSPLandroid/content/ContextParams$Builder;-><init>()V
@@ -3927,25 +3949,25 @@
 HSPLandroid/content/ContextWrapper;->enforcePermission(Ljava/lang/String;IILjava/lang/String;)V
 HSPLandroid/content/ContextWrapper;->fileList()[Ljava/lang/String;
 HSPLandroid/content/ContextWrapper;->getActivityToken()Landroid/os/IBinder;
-HSPLandroid/content/ContextWrapper;->getApplicationContext()Landroid/content/Context;+]Landroid/content/Context;missing_types
+HSPLandroid/content/ContextWrapper;->getApplicationContext()Landroid/content/Context;
 HSPLandroid/content/ContextWrapper;->getApplicationInfo()Landroid/content/pm/ApplicationInfo;+]Landroid/content/Context;missing_types
 HSPLandroid/content/ContextWrapper;->getAssets()Landroid/content/res/AssetManager;
 HSPLandroid/content/ContextWrapper;->getAttributionSource()Landroid/content/AttributionSource;
 HSPLandroid/content/ContextWrapper;->getAttributionTag()Ljava/lang/String;
 HSPLandroid/content/ContextWrapper;->getAutofillClient()Landroid/view/autofill/AutofillManager$AutofillClient;
-HSPLandroid/content/ContextWrapper;->getAutofillOptions()Landroid/content/AutofillOptions;+]Landroid/content/Context;missing_types
+HSPLandroid/content/ContextWrapper;->getAutofillOptions()Landroid/content/AutofillOptions;
 HSPLandroid/content/ContextWrapper;->getBaseContext()Landroid/content/Context;
 HSPLandroid/content/ContextWrapper;->getBasePackageName()Ljava/lang/String;
 HSPLandroid/content/ContextWrapper;->getCacheDir()Ljava/io/File;
 HSPLandroid/content/ContextWrapper;->getClassLoader()Ljava/lang/ClassLoader;
 HSPLandroid/content/ContextWrapper;->getContentCaptureOptions()Landroid/content/ContentCaptureOptions;
-HSPLandroid/content/ContextWrapper;->getContentResolver()Landroid/content/ContentResolver;
+HSPLandroid/content/ContextWrapper;->getContentResolver()Landroid/content/ContentResolver;+]Landroid/content/Context;missing_types
 HSPLandroid/content/ContextWrapper;->getDataDir()Ljava/io/File;
 HSPLandroid/content/ContextWrapper;->getDatabasePath(Ljava/lang/String;)Ljava/io/File;
 HSPLandroid/content/ContextWrapper;->getDeviceId()I
 HSPLandroid/content/ContextWrapper;->getDir(Ljava/lang/String;I)Ljava/io/File;
 HSPLandroid/content/ContextWrapper;->getDisplay()Landroid/view/Display;
-HSPLandroid/content/ContextWrapper;->getDisplayId()I
+HSPLandroid/content/ContextWrapper;->getDisplayId()I+]Landroid/content/Context;missing_types
 HSPLandroid/content/ContextWrapper;->getDisplayNoVerify()Landroid/view/Display;
 HSPLandroid/content/ContextWrapper;->getExternalCacheDir()Ljava/io/File;
 HSPLandroid/content/ContextWrapper;->getExternalCacheDirs()[Ljava/io/File;
@@ -3961,21 +3983,21 @@
 HSPLandroid/content/ContextWrapper;->getNoBackupFilesDir()Ljava/io/File;
 HSPLandroid/content/ContextWrapper;->getOpPackageName()Ljava/lang/String;
 HSPLandroid/content/ContextWrapper;->getPackageCodePath()Ljava/lang/String;
-HSPLandroid/content/ContextWrapper;->getPackageManager()Landroid/content/pm/PackageManager;
+HSPLandroid/content/ContextWrapper;->getPackageManager()Landroid/content/pm/PackageManager;+]Landroid/content/Context;missing_types
 HSPLandroid/content/ContextWrapper;->getPackageName()Ljava/lang/String;
 HSPLandroid/content/ContextWrapper;->getPackageResourcePath()Ljava/lang/String;
 HSPLandroid/content/ContextWrapper;->getResources()Landroid/content/res/Resources;
-HSPLandroid/content/ContextWrapper;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;
+HSPLandroid/content/ContextWrapper;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;+]Landroid/content/Context;missing_types
 HSPLandroid/content/ContextWrapper;->getSharedPreferencesPath(Ljava/lang/String;)Ljava/io/File;
-HSPLandroid/content/ContextWrapper;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
+HSPLandroid/content/ContextWrapper;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;+]Landroid/content/Context;missing_types
 HSPLandroid/content/ContextWrapper;->getSystemServiceName(Ljava/lang/Class;)Ljava/lang/String;+]Landroid/content/Context;missing_types
-HSPLandroid/content/ContextWrapper;->getTheme()Landroid/content/res/Resources$Theme;
+HSPLandroid/content/ContextWrapper;->getTheme()Landroid/content/res/Resources$Theme;+]Landroid/content/Context;missing_types
 HSPLandroid/content/ContextWrapper;->getUser()Landroid/os/UserHandle;
 HSPLandroid/content/ContextWrapper;->getUserId()I
 HSPLandroid/content/ContextWrapper;->getWindowContextToken()Landroid/os/IBinder;
 HSPLandroid/content/ContextWrapper;->grantUriPermission(Ljava/lang/String;Landroid/net/Uri;I)V
 HSPLandroid/content/ContextWrapper;->isDeviceProtectedStorage()Z
-HSPLandroid/content/ContextWrapper;->isRestricted()Z+]Landroid/content/Context;missing_types
+HSPLandroid/content/ContextWrapper;->isRestricted()Z
 HSPLandroid/content/ContextWrapper;->isUiContext()Z
 HSPLandroid/content/ContextWrapper;->openFileInput(Ljava/lang/String;)Ljava/io/FileInputStream;
 HSPLandroid/content/ContextWrapper;->openFileOutput(Ljava/lang/String;I)Ljava/io/FileOutputStream;
@@ -4061,7 +4083,7 @@
 HSPLandroid/content/Intent;-><init>(Ljava/lang/String;)V
 HSPLandroid/content/Intent;-><init>(Ljava/lang/String;Landroid/net/Uri;)V
 HSPLandroid/content/Intent;-><init>(Ljava/lang/String;Landroid/net/Uri;Landroid/content/Context;Ljava/lang/Class;)V
-HSPLandroid/content/Intent;->addCategory(Ljava/lang/String;)Landroid/content/Intent;+]Landroid/util/ArraySet;Landroid/util/ArraySet;]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/content/Intent;->addCategory(Ljava/lang/String;)Landroid/content/Intent;+]Ljava/lang/String;Ljava/lang/String;]Landroid/util/ArraySet;Landroid/util/ArraySet;
 HSPLandroid/content/Intent;->addFlags(I)Landroid/content/Intent;
 HSPLandroid/content/Intent;->cloneFilter()Landroid/content/Intent;
 HSPLandroid/content/Intent;->filterEquals(Landroid/content/Intent;)Z
@@ -4126,8 +4148,8 @@
 HSPLandroid/content/Intent;->putExtras(Landroid/os/Bundle;)Landroid/content/Intent;
 HSPLandroid/content/Intent;->putParcelableArrayListExtra(Ljava/lang/String;Ljava/util/ArrayList;)Landroid/content/Intent;
 HSPLandroid/content/Intent;->putStringArrayListExtra(Ljava/lang/String;Ljava/util/ArrayList;)Landroid/content/Intent;
-HSPLandroid/content/Intent;->readFromParcel(Landroid/os/Parcel;)V
-HSPLandroid/content/Intent;->removeCategory(Ljava/lang/String;)V
+HSPLandroid/content/Intent;->readFromParcel(Landroid/os/Parcel;)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/os/Parcelable$Creator;Landroid/net/Uri$1;,Landroid/graphics/Rect$1;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/content/Intent;Landroid/content/Intent;
+HSPLandroid/content/Intent;->removeCategory(Ljava/lang/String;)V+]Landroid/util/ArraySet;Landroid/util/ArraySet;
 HSPLandroid/content/Intent;->removeExtra(Ljava/lang/String;)V
 HSPLandroid/content/Intent;->replaceExtras(Landroid/os/Bundle;)Landroid/content/Intent;
 HSPLandroid/content/Intent;->resolveActivity(Landroid/content/pm/PackageManager;)Landroid/content/ComponentName;
@@ -4152,13 +4174,13 @@
 HSPLandroid/content/Intent;->setSelector(Landroid/content/Intent;)V
 HSPLandroid/content/Intent;->setSourceBounds(Landroid/graphics/Rect;)V
 HSPLandroid/content/Intent;->setType(Ljava/lang/String;)Landroid/content/Intent;
-HSPLandroid/content/Intent;->toShortString(Ljava/lang/StringBuilder;ZZZZ)V
+HSPLandroid/content/Intent;->toShortString(Ljava/lang/StringBuilder;ZZZZ)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/content/ComponentName;Landroid/content/ComponentName;
 HSPLandroid/content/Intent;->toString()Ljava/lang/String;
 HSPLandroid/content/Intent;->toString(Ljava/lang/StringBuilder;)V
 HSPLandroid/content/Intent;->toUri(I)Ljava/lang/String;
 HSPLandroid/content/Intent;->toUriFragment(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V
 HSPLandroid/content/Intent;->toUriInner(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V
-HSPLandroid/content/Intent;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/Intent;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/IntentFilter$$ExternalSyntheticLambda0;->accept(Ljava/lang/Object;Ljava/lang/Object;)V
 HSPLandroid/content/IntentFilter$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/IntentFilter;
 HSPLandroid/content/IntentFilter$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -4222,7 +4244,7 @@
 HSPLandroid/content/IntentFilter;->setPriority(I)V
 HSPLandroid/content/IntentFilter;->setVisibilityToInstantApp(I)V
 HSPLandroid/content/IntentFilter;->typesIterator()Ljava/util/Iterator;
-HSPLandroid/content/IntentFilter;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/IntentFilter;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/content/IntentFilter;Landroid/content/IntentFilter;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/IntentSender;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/LocusId$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/LocusId;
 HSPLandroid/content/LocusId$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -4298,7 +4320,7 @@
 HSPLandroid/content/UriMatcher;-><init>(ILjava/lang/String;)V
 HSPLandroid/content/UriMatcher;->addURI(Ljava/lang/String;Ljava/lang/String;I)V
 HSPLandroid/content/UriMatcher;->createChild(Ljava/lang/String;)Landroid/content/UriMatcher;
-HSPLandroid/content/UriMatcher;->match(Landroid/net/Uri;)I
+HSPLandroid/content/UriMatcher;->match(Landroid/net/Uri;)I+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/Object;Ljava/lang/String;]Ljava/util/List;Landroid/net/Uri$PathSegments;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/net/Uri;Landroid/net/Uri$HierarchicalUri;
 HSPLandroid/content/om/OverlayInfo;->ensureValidState()V
 HSPLandroid/content/om/OverlayInfo;->isEnabled()Z
 HSPLandroid/content/pm/ActivityInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/ActivityInfo;
@@ -4306,7 +4328,7 @@
 HSPLandroid/content/pm/ActivityInfo$1;->newArray(I)[Landroid/content/pm/ActivityInfo;
 HSPLandroid/content/pm/ActivityInfo$1;->newArray(I)[Ljava/lang/Object;
 HSPLandroid/content/pm/ActivityInfo$WindowLayout;-><init>(Landroid/os/Parcel;)V
-HSPLandroid/content/pm/ActivityInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Ljava/util/Set;Landroid/util/ArraySet;
+HSPLandroid/content/pm/ActivityInfo;-><init>(Landroid/os/Parcel;)V+]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/Set;Landroid/util/ArraySet;
 HSPLandroid/content/pm/ActivityInfo;->activityInfoConfigNativeToJava(I)I
 HSPLandroid/content/pm/ActivityInfo;->getRealConfigChanged()I
 HSPLandroid/content/pm/ActivityInfo;->getThemeResource()I
@@ -4325,7 +4347,7 @@
 HSPLandroid/content/pm/ApplicationInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/content/pm/ApplicationInfo;-><init>()V
 HSPLandroid/content/pm/ApplicationInfo;-><init>(Landroid/content/pm/ApplicationInfo;)V
-HSPLandroid/content/pm/ApplicationInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Landroid/os/Parcel;Landroid/os/Parcel;]Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Ljava/util/Set;Ljava/util/Collections$EmptySet;
+HSPLandroid/content/pm/ApplicationInfo;-><init>(Landroid/os/Parcel;)V+]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/Set;Ljava/util/Collections$EmptySet;
 HSPLandroid/content/pm/ApplicationInfo;-><init>(Landroid/os/Parcel;Landroid/content/pm/ApplicationInfo-IA;)V
 HSPLandroid/content/pm/ApplicationInfo;->getAllApkPaths()[Ljava/lang/String;
 HSPLandroid/content/pm/ApplicationInfo;->getApplicationInfo()Landroid/content/pm/ApplicationInfo;
@@ -4362,16 +4384,16 @@
 HSPLandroid/content/pm/ApplicationInfo;->setSplitResourcePaths([Ljava/lang/String;)V
 HSPLandroid/content/pm/ApplicationInfo;->setVersionCode(J)V
 HSPLandroid/content/pm/ApplicationInfo;->toString()Ljava/lang/String;
-HSPLandroid/content/pm/ApplicationInfo;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/pm/ApplicationInfo;->writeToParcel(Landroid/os/Parcel;I)V+]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/UUID;Ljava/util/UUID;
 HSPLandroid/content/pm/Attribution$1;-><init>()V
 HSPLandroid/content/pm/Attribution;-><clinit>()V
 HSPLandroid/content/pm/BaseParceledListSlice$1;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
-HSPLandroid/content/pm/BaseParceledListSlice;-><init>(Landroid/os/Parcel;Ljava/lang/ClassLoader;)V
+HSPLandroid/content/pm/BaseParceledListSlice;-><init>(Landroid/os/Parcel;Ljava/lang/ClassLoader;)V+]Landroid/content/pm/BaseParceledListSlice;Landroid/content/pm/ParceledListSlice;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/BaseParceledListSlice;-><init>(Ljava/util/List;)V
 HSPLandroid/content/pm/BaseParceledListSlice;->getList()Ljava/util/List;
 HSPLandroid/content/pm/BaseParceledListSlice;->readCreator(Landroid/os/Parcelable$Creator;Landroid/os/Parcel;Ljava/lang/ClassLoader;)Ljava/lang/Object;
-HSPLandroid/content/pm/BaseParceledListSlice;->readVerifyAndAddElement(Landroid/os/Parcelable$Creator;Landroid/os/Parcel;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;
-HSPLandroid/content/pm/BaseParceledListSlice;->verifySameType(Ljava/lang/Class;Ljava/lang/Class;)V+]Ljava/lang/Object;Ljava/lang/Class;
+HSPLandroid/content/pm/BaseParceledListSlice;->readVerifyAndAddElement(Landroid/os/Parcelable$Creator;Landroid/os/Parcel;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;+]Ljava/lang/Object;megamorphic_types]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/content/pm/BaseParceledListSlice;->verifySameType(Ljava/lang/Class;Ljava/lang/Class;)V
 HSPLandroid/content/pm/BaseParceledListSlice;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/pm/Checksum$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/Checksum;
 HSPLandroid/content/pm/Checksum$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -4380,12 +4402,12 @@
 HSPLandroid/content/pm/Checksum;->getValue()[B
 HSPLandroid/content/pm/ComponentInfo;-><init>()V
 HSPLandroid/content/pm/ComponentInfo;-><init>(Landroid/content/pm/ComponentInfo;)V
-HSPLandroid/content/pm/ComponentInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/ComponentInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/content/pm/ApplicationInfo$1;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/ComponentInfo;->getApplicationInfo()Landroid/content/pm/ApplicationInfo;
 HSPLandroid/content/pm/ComponentInfo;->getComponentName()Landroid/content/ComponentName;
 HSPLandroid/content/pm/ComponentInfo;->getIconResource()I
 HSPLandroid/content/pm/ComponentInfo;->isEnabled()Z
-HSPLandroid/content/pm/ComponentInfo;->loadUnsafeLabel(Landroid/content/pm/PackageManager;)Ljava/lang/CharSequence;
+HSPLandroid/content/pm/ComponentInfo;->loadUnsafeLabel(Landroid/content/pm/PackageManager;)Ljava/lang/CharSequence;+]Landroid/content/pm/PackageManager;Landroid/app/ApplicationPackageManager;
 HSPLandroid/content/pm/ComponentInfo;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/pm/ConfigurationInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/ConfigurationInfo;
 HSPLandroid/content/pm/ConfigurationInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -4394,9 +4416,13 @@
 HSPLandroid/content/pm/CrossProfileApps;->getTargetUserProfiles()Ljava/util/List;
 HSPLandroid/content/pm/FallbackCategoryProvider;->getFallbackCategory(Ljava/lang/String;)I
 HSPLandroid/content/pm/FallbackCategoryProvider;->loadFallbacks()V
+HSPLandroid/content/pm/FeatureFlagsImpl;-><init>()V
+HSPLandroid/content/pm/FeatureFlagsImpl;->relativeReferenceIntentFilters()Z
 HSPLandroid/content/pm/FeatureInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/FeatureInfo;
 HSPLandroid/content/pm/FeatureInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/content/pm/FeatureInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/Flags;-><clinit>()V
+HSPLandroid/content/pm/Flags;->relativeReferenceIntentFilters()Z+]Landroid/content/pm/FeatureFlags;Landroid/content/pm/FeatureFlagsImpl;
 HSPLandroid/content/pm/ICrossProfileApps$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/content/pm/ICrossProfileApps$Stub$Proxy;->getTargetUserProfiles(Ljava/lang/String;)Ljava/util/List;
 HSPLandroid/content/pm/ICrossProfileApps$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/ICrossProfileApps;
@@ -4418,15 +4444,15 @@
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->checkPermission(Ljava/lang/String;Ljava/lang/String;I)I
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getActivityInfo(Landroid/content/ComponentName;JI)Landroid/content/pm/ActivityInfo;
-HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getApplicationEnabledSetting(Ljava/lang/String;I)I+]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getApplicationInfo(Ljava/lang/String;JI)Landroid/content/pm/ApplicationInfo;+]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getApplicationEnabledSetting(Ljava/lang/String;I)I+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getApplicationInfo(Ljava/lang/String;JI)Landroid/content/pm/ApplicationInfo;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getComponentEnabledSetting(Landroid/content/ComponentName;I)I
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getHomeActivities(Ljava/util/List;)Landroid/content/ComponentName;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getInstalledApplications(JI)Landroid/content/pm/ParceledListSlice;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getInstalledPackages(JI)Landroid/content/pm/ParceledListSlice;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getInstallerPackageName(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getNameForUid(I)Ljava/lang/String;
-HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInfo(Ljava/lang/String;JI)Landroid/content/pm/PackageInfo;+]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInfo(Ljava/lang/String;JI)Landroid/content/pm/PackageInfo;+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInstaller()Landroid/content/pm/IPackageInstaller;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackageUid(Ljava/lang/String;JI)I
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackagesForUid(I)[Ljava/lang/String;
@@ -4444,7 +4470,7 @@
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->notifyDexLoad(Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;)V
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->notifyPackageUse(Ljava/lang/String;I)V
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->notifyPackagesReplacedReceived([Ljava/lang/String;)V
-HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentActivities(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentActivities(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentContentProviders(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentReceivers(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentServices(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;
@@ -4496,7 +4522,7 @@
 HSPLandroid/content/pm/PackageInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/PackageInfo;
 HSPLandroid/content/pm/PackageInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/content/pm/PackageInfo;-><init>()V
-HSPLandroid/content/pm/PackageInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/content/pm/ApplicationInfo$1;,Landroid/content/pm/SigningInfo$1;
+HSPLandroid/content/pm/PackageInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/content/pm/ApplicationInfo$1;,Landroid/content/pm/SigningInfo$1;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/PackageInfo;-><init>(Landroid/os/Parcel;Landroid/content/pm/PackageInfo-IA;)V
 HSPLandroid/content/pm/PackageInfo;->composeLongVersionCode(II)J
 HSPLandroid/content/pm/PackageInfo;->getLongVersionCode()J
@@ -4520,7 +4546,7 @@
 HSPLandroid/content/pm/PackageInstaller;->registerSessionCallback(Landroid/content/pm/PackageInstaller$SessionCallback;Landroid/os/Handler;)V
 HSPLandroid/content/pm/PackageItemInfo;-><init>()V
 HSPLandroid/content/pm/PackageItemInfo;-><init>(Landroid/content/pm/PackageItemInfo;)V
-HSPLandroid/content/pm/PackageItemInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/PackageItemInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/text/TextUtils$1;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/PackageItemInfo;->forceSafeLabels()V
 HSPLandroid/content/pm/PackageItemInfo;->loadIcon(Landroid/content/pm/PackageManager;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/content/pm/PackageItemInfo;->loadLabel(Landroid/content/pm/PackageManager;)Ljava/lang/CharSequence;
@@ -4678,7 +4704,7 @@
 HSPLandroid/content/pm/ResolveInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/ResolveInfo;
 HSPLandroid/content/pm/ResolveInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/content/pm/ResolveInfo;-><init>()V
-HSPLandroid/content/pm/ResolveInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/ResolveInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/content/pm/ServiceInfo$1;,Landroid/content/pm/ActivityInfo$1;,Landroid/text/TextUtils$1;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/ResolveInfo;-><init>(Landroid/os/Parcel;Landroid/content/pm/ResolveInfo-IA;)V
 HSPLandroid/content/pm/ResolveInfo;->getComponentInfo()Landroid/content/pm/ComponentInfo;
 HSPLandroid/content/pm/ResolveInfo;->loadIcon(Landroid/content/pm/PackageManager;)Landroid/graphics/drawable/Drawable;
@@ -4691,8 +4717,8 @@
 HSPLandroid/content/pm/ServiceInfo;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/pm/ServiceInfo;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/pm/SharedLibraryInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/SharedLibraryInfo;
-HSPLandroid/content/pm/SharedLibraryInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/SharedLibraryInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;
+HSPLandroid/content/pm/SharedLibraryInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/content/pm/SharedLibraryInfo$1;Landroid/content/pm/SharedLibraryInfo$1;
+HSPLandroid/content/pm/SharedLibraryInfo;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/SharedLibraryInfo;-><init>(Landroid/os/Parcel;Landroid/content/pm/SharedLibraryInfo-IA;)V
 HSPLandroid/content/pm/SharedLibraryInfo;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;JILandroid/content/pm/VersionedPackage;Ljava/util/List;Ljava/util/List;Z)V
 HSPLandroid/content/pm/SharedLibraryInfo;->addDependency(Landroid/content/pm/SharedLibraryInfo;)V
@@ -4702,7 +4728,7 @@
 HSPLandroid/content/pm/SharedLibraryInfo;->getPath()Ljava/lang/String;
 HSPLandroid/content/pm/SharedLibraryInfo;->isNative()Z
 HSPLandroid/content/pm/SharedLibraryInfo;->isSdk()Z
-HSPLandroid/content/pm/SharedLibraryInfo;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/pm/SharedLibraryInfo;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/ShortcutInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/ShortcutInfo;
 HSPLandroid/content/pm/ShortcutInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/content/pm/ShortcutInfo$Builder;-><init>(Landroid/content/Context;Ljava/lang/String;)V
@@ -4715,7 +4741,7 @@
 HSPLandroid/content/pm/ShortcutInfo$Builder;->setLongLived(Z)Landroid/content/pm/ShortcutInfo$Builder;
 HSPLandroid/content/pm/ShortcutInfo$Builder;->setRank(I)Landroid/content/pm/ShortcutInfo$Builder;
 HSPLandroid/content/pm/ShortcutInfo$Builder;->setShortLabel(Ljava/lang/CharSequence;)Landroid/content/pm/ShortcutInfo$Builder;
-HSPLandroid/content/pm/ShortcutInfo;-><init>(Landroid/content/pm/ShortcutInfo$Builder;)V
+HSPLandroid/content/pm/ShortcutInfo;-><init>(Landroid/content/pm/ShortcutInfo$Builder;)V+]Landroid/content/pm/ShortcutInfo;Landroid/content/pm/ShortcutInfo;
 HSPLandroid/content/pm/ShortcutInfo;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/pm/ShortcutInfo;->addFlags(I)V
 HSPLandroid/content/pm/ShortcutInfo;->cloneCapabilityBindings(Ljava/util/Map;)Ljava/util/Map;
@@ -4766,7 +4792,7 @@
 HSPLandroid/content/pm/Signature$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/content/pm/Signature$1;->newArray(I)[Landroid/content/pm/Signature;
 HSPLandroid/content/pm/Signature$1;->newArray(I)[Ljava/lang/Object;
-HSPLandroid/content/pm/Signature;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/Signature;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/pm/Signature;-><init>(Landroid/os/Parcel;Landroid/content/pm/Signature-IA;)V
 HSPLandroid/content/pm/Signature;-><init>(Ljava/lang/String;)V
 HSPLandroid/content/pm/Signature;-><init>([B)V
@@ -4779,11 +4805,11 @@
 HSPLandroid/content/pm/Signature;->toCharsString()Ljava/lang/String;
 HSPLandroid/content/pm/SigningDetails$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/SigningDetails;
 HSPLandroid/content/pm/SigningDetails$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/SigningDetails;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;
+HSPLandroid/content/pm/SigningDetails;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/SigningDetails;->getSignatures()[Landroid/content/pm/Signature;
 HSPLandroid/content/pm/SigningInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/SigningInfo;
 HSPLandroid/content/pm/SigningInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/SigningInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/content/pm/SigningDetails$1;
+HSPLandroid/content/pm/SigningInfo;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/pm/SigningInfo;->getApkContentsSigners()[Landroid/content/pm/Signature;
 HSPLandroid/content/pm/SigningInfo;->getSigningCertificateHistory()[Landroid/content/pm/Signature;
 HSPLandroid/content/pm/SigningInfo;->hasMultipleSigners()Z
@@ -4793,7 +4819,7 @@
 HSPLandroid/content/pm/StringParceledListSlice;->getList()Ljava/util/List;
 HSPLandroid/content/pm/UserInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/UserInfo;
 HSPLandroid/content/pm/UserInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/UserInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/UserInfo;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/pm/UserInfo;->getUserHandle()Landroid/os/UserHandle;
 HSPLandroid/content/pm/UserInfo;->isAdmin()Z
 HSPLandroid/content/pm/UserInfo;->isEnabled()Z
@@ -4812,8 +4838,8 @@
 HSPLandroid/content/pm/UserPackage;->of(ILjava/lang/String;)Landroid/content/pm/UserPackage;
 HSPLandroid/content/pm/UserProperties;->isPresent(J)Z
 HSPLandroid/content/pm/VersionedPackage$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/VersionedPackage;
-HSPLandroid/content/pm/VersionedPackage$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/VersionedPackage;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/VersionedPackage$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/content/pm/VersionedPackage$1;Landroid/content/pm/VersionedPackage$1;
+HSPLandroid/content/pm/VersionedPackage;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/VersionedPackage;-><init>(Landroid/os/Parcel;Landroid/content/pm/VersionedPackage-IA;)V
 HSPLandroid/content/pm/VersionedPackage;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/pm/dex/ArtManager;->getCurrentProfilePath(Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String;
@@ -4930,7 +4956,7 @@
 HSPLandroid/content/res/AssetManager;->getResourceValue(IILandroid/util/TypedValue;Z)Z+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
 HSPLandroid/content/res/AssetManager;->getSizeConfigurations()[Landroid/content/res/Configuration;
 HSPLandroid/content/res/AssetManager;->getSystem()Landroid/content/res/AssetManager;
-HSPLandroid/content/res/AssetManager;->getThemeValue(JILandroid/util/TypedValue;Z)Z+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
+HSPLandroid/content/res/AssetManager;->getThemeValue(JILandroid/util/TypedValue;Z)Z
 HSPLandroid/content/res/AssetManager;->incRefsLocked(J)V
 HSPLandroid/content/res/AssetManager;->isUpToDate()Z
 HSPLandroid/content/res/AssetManager;->list(Ljava/lang/String;)[Ljava/lang/String;
@@ -4969,13 +4995,13 @@
 HSPLandroid/content/res/ColorStateList;->getColorForState([II)I
 HSPLandroid/content/res/ColorStateList;->getConstantState()Landroid/content/res/ConstantState;
 HSPLandroid/content/res/ColorStateList;->getDefaultColor()I
-HSPLandroid/content/res/ColorStateList;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/util/AttributeSet;Landroid/content/res/XmlBlock$Parser;]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/content/res/ColorStateList;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
 HSPLandroid/content/res/ColorStateList;->isStateful()Z
 HSPLandroid/content/res/ColorStateList;->modulateColor(IFF)I
 HSPLandroid/content/res/ColorStateList;->obtainForTheme(Landroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;
 HSPLandroid/content/res/ColorStateList;->obtainForTheme(Landroid/content/res/Resources$Theme;)Landroid/content/res/ComplexColor;
 HSPLandroid/content/res/ColorStateList;->onColorsChanged()V
-HSPLandroid/content/res/ColorStateList;->valueOf(I)Landroid/content/res/ColorStateList;+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/content/res/ColorStateList;->valueOf(I)Landroid/content/res/ColorStateList;
 HSPLandroid/content/res/ColorStateList;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/res/CompatibilityInfo$2;->createFromParcel(Landroid/os/Parcel;)Landroid/content/res/CompatibilityInfo;
 HSPLandroid/content/res/CompatibilityInfo$2;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -5007,11 +5033,11 @@
 HSPLandroid/content/res/Configuration;-><init>(Landroid/os/Parcel;Landroid/content/res/Configuration-IA;)V
 HSPLandroid/content/res/Configuration;->compareTo(Landroid/content/res/Configuration;)I
 HSPLandroid/content/res/Configuration;->diff(Landroid/content/res/Configuration;)I
-HSPLandroid/content/res/Configuration;->diff(Landroid/content/res/Configuration;ZZ)I+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/os/LocaleList;Landroid/os/LocaleList;
+HSPLandroid/content/res/Configuration;->diff(Landroid/content/res/Configuration;ZZ)I
 HSPLandroid/content/res/Configuration;->diffPublicOnly(Landroid/content/res/Configuration;)I
 HSPLandroid/content/res/Configuration;->equals(Landroid/content/res/Configuration;)Z
 HSPLandroid/content/res/Configuration;->equals(Ljava/lang/Object;)Z
-HSPLandroid/content/res/Configuration;->fixUpLocaleList()V+]Landroid/os/LocaleList;Landroid/os/LocaleList;]Ljava/lang/Object;Ljava/util/Locale;
+HSPLandroid/content/res/Configuration;->fixUpLocaleList()V
 HSPLandroid/content/res/Configuration;->generateDelta(Landroid/content/res/Configuration;Landroid/content/res/Configuration;)Landroid/content/res/Configuration;
 HSPLandroid/content/res/Configuration;->getGrammaticalGender()I
 HSPLandroid/content/res/Configuration;->getLayoutDirection()I
@@ -5023,19 +5049,19 @@
 HSPLandroid/content/res/Configuration;->isScreenRound()Z
 HSPLandroid/content/res/Configuration;->isScreenWideColorGamut()Z
 HSPLandroid/content/res/Configuration;->needNewResources(II)Z
-HSPLandroid/content/res/Configuration;->readFromParcel(Landroid/os/Parcel;)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/res/Configuration;->readFromParcel(Landroid/os/Parcel;)V
 HSPLandroid/content/res/Configuration;->readFromProto(Landroid/util/proto/ProtoInputStream;J)V
 HSPLandroid/content/res/Configuration;->reduceScreenLayout(III)I
 HSPLandroid/content/res/Configuration;->resetScreenLayout(I)I
 HSPLandroid/content/res/Configuration;->setLayoutDirection(Ljava/util/Locale;)V
 HSPLandroid/content/res/Configuration;->setLocale(Ljava/util/Locale;)V
 HSPLandroid/content/res/Configuration;->setLocales(Landroid/os/LocaleList;)V
-HSPLandroid/content/res/Configuration;->setTo(Landroid/content/res/Configuration;)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;
+HSPLandroid/content/res/Configuration;->setTo(Landroid/content/res/Configuration;)V+]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
 HSPLandroid/content/res/Configuration;->setTo(Landroid/content/res/Configuration;II)V
 HSPLandroid/content/res/Configuration;->setToDefaults()V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
 HSPLandroid/content/res/Configuration;->toString()Ljava/lang/String;
 HSPLandroid/content/res/Configuration;->unset()V
-HSPLandroid/content/res/Configuration;->updateFrom(Landroid/content/res/Configuration;)I+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;
+HSPLandroid/content/res/Configuration;->updateFrom(Landroid/content/res/Configuration;)I+]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
 HSPLandroid/content/res/Configuration;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/res/ConfigurationBoundResourceCache;-><init>()V
 HSPLandroid/content/res/ConfigurationBoundResourceCache;->get(JLandroid/content/res/Resources$Theme;)Ljava/lang/Object;
@@ -5054,10 +5080,10 @@
 HSPLandroid/content/res/DrawableCache;->shouldInvalidateEntry(Landroid/graphics/drawable/Drawable$ConstantState;I)Z
 HSPLandroid/content/res/DrawableCache;->shouldInvalidateEntry(Ljava/lang/Object;I)Z
 HSPLandroid/content/res/FeatureFlagsImpl;->defaultLocale()Z
-HSPLandroid/content/res/Flags;->defaultLocale()Z
+HSPLandroid/content/res/Flags;->defaultLocale()Z+]Landroid/content/res/FeatureFlags;Landroid/content/res/FeatureFlagsImpl;
 HSPLandroid/content/res/FontResourcesParser;->parse(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;
-HSPLandroid/content/res/FontResourcesParser;->readFamilies(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;+]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
-HSPLandroid/content/res/FontResourcesParser;->readFamily(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Ljava/util/List;Ljava/util/ArrayList;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/content/res/FontResourcesParser;->readFamilies(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;
+HSPLandroid/content/res/FontResourcesParser;->readFamily(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;
 HSPLandroid/content/res/FontScaleConverterFactory;->forScale(F)Landroid/content/res/FontScaleConverter;
 HSPLandroid/content/res/FontScaleConverterFactory;->isNonLinearFontScalingActive(F)Z
 HSPLandroid/content/res/GradientColor;-><init>()V
@@ -5076,28 +5102,28 @@
 HSPLandroid/content/res/Resources$Theme;-><init>(Landroid/content/res/Resources;)V
 HSPLandroid/content/res/Resources$Theme;-><init>(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme-IA;)V
 HSPLandroid/content/res/Resources$Theme;->applyStyle(IZ)V
-HSPLandroid/content/res/Resources$Theme;->equals(Ljava/lang/Object;)Z+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;]Ljava/lang/Object;Landroid/content/res/Resources$Theme;
+HSPLandroid/content/res/Resources$Theme;->equals(Ljava/lang/Object;)Z
 HSPLandroid/content/res/Resources$Theme;->getAppliedStyleResId()I
 HSPLandroid/content/res/Resources$Theme;->getChangingConfigurations()I
-HSPLandroid/content/res/Resources$Theme;->getKey()Landroid/content/res/Resources$ThemeKey;+]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
+HSPLandroid/content/res/Resources$Theme;->getKey()Landroid/content/res/Resources$ThemeKey;
 HSPLandroid/content/res/Resources$Theme;->getParentThemeIdentifier(I)I
 HSPLandroid/content/res/Resources$Theme;->getResources()Landroid/content/res/Resources;
 HSPLandroid/content/res/Resources$Theme;->getTheme()[Ljava/lang/String;
 HSPLandroid/content/res/Resources$Theme;->hashCode()I
-HSPLandroid/content/res/Resources$Theme;->obtainStyledAttributes(I[I)Landroid/content/res/TypedArray;+]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
+HSPLandroid/content/res/Resources$Theme;->obtainStyledAttributes(I[I)Landroid/content/res/TypedArray;
 HSPLandroid/content/res/Resources$Theme;->obtainStyledAttributes(Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
 HSPLandroid/content/res/Resources$Theme;->obtainStyledAttributes([I)Landroid/content/res/TypedArray;
 HSPLandroid/content/res/Resources$Theme;->rebase()V
 HSPLandroid/content/res/Resources$Theme;->rebase(Landroid/content/res/ResourcesImpl;)V
-HSPLandroid/content/res/Resources$Theme;->resolveAttribute(ILandroid/util/TypedValue;Z)Z+]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
+HSPLandroid/content/res/Resources$Theme;->resolveAttribute(ILandroid/util/TypedValue;Z)Z
 HSPLandroid/content/res/Resources$Theme;->resolveAttributes([I[I)Landroid/content/res/TypedArray;
 HSPLandroid/content/res/Resources$Theme;->setImpl(Landroid/content/res/ResourcesImpl$ThemeImpl;)V
 HSPLandroid/content/res/Resources$Theme;->setTo(Landroid/content/res/Resources$Theme;)V
-HSPLandroid/content/res/Resources$Theme;->toString()Ljava/lang/String;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/content/res/Resources$Theme;->toString()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources;Landroid/content/res/Resources;
 HSPLandroid/content/res/Resources$ThemeKey;-><init>()V
 HSPLandroid/content/res/Resources$ThemeKey;->append(IZ)V
 HSPLandroid/content/res/Resources$ThemeKey;->clone()Landroid/content/res/Resources$ThemeKey;
-HSPLandroid/content/res/Resources$ThemeKey;->equals(Ljava/lang/Object;)Z+]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;]Ljava/lang/Object;Landroid/content/res/Resources$ThemeKey;
+HSPLandroid/content/res/Resources$ThemeKey;->equals(Ljava/lang/Object;)Z+]Ljava/lang/Object;Landroid/content/res/Resources$ThemeKey;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;
 HSPLandroid/content/res/Resources$ThemeKey;->hashCode()I
 HSPLandroid/content/res/Resources$ThemeKey;->moveToLast(I)V
 HSPLandroid/content/res/Resources$ThemeKey;->setTo(Landroid/content/res/Resources$ThemeKey;)V+][I[I][Z[Z
@@ -5116,12 +5142,12 @@
 HSPLandroid/content/res/Resources;->getBoolean(I)Z
 HSPLandroid/content/res/Resources;->getClassLoader()Ljava/lang/ClassLoader;
 HSPLandroid/content/res/Resources;->getColor(I)I
-HSPLandroid/content/res/Resources;->getColor(ILandroid/content/res/Resources$Theme;)I+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getColor(ILandroid/content/res/Resources$Theme;)I
 HSPLandroid/content/res/Resources;->getColorStateList(I)Landroid/content/res/ColorStateList;
 HSPLandroid/content/res/Resources;->getColorStateList(ILandroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;
 HSPLandroid/content/res/Resources;->getCompatibilityInfo()Landroid/content/res/CompatibilityInfo;
 HSPLandroid/content/res/Resources;->getConfiguration()Landroid/content/res/Configuration;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
-HSPLandroid/content/res/Resources;->getDimension(I)F+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getDimension(I)F
 HSPLandroid/content/res/Resources;->getDimensionPixelOffset(I)I
 HSPLandroid/content/res/Resources;->getDimensionPixelSize(I)I
 HSPLandroid/content/res/Resources;->getDisplayAdjustments()Landroid/view/DisplayAdjustments;
@@ -5129,7 +5155,7 @@
 HSPLandroid/content/res/Resources;->getDrawable(I)Landroid/graphics/drawable/Drawable;
 HSPLandroid/content/res/Resources;->getDrawable(ILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/content/res/Resources;->getDrawableForDensity(II)Landroid/graphics/drawable/Drawable;
-HSPLandroid/content/res/Resources;->getDrawableForDensity(IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getDrawableForDensity(IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/content/res/Resources;->getDrawableInflater()Landroid/graphics/drawable/DrawableInflater;
 HSPLandroid/content/res/Resources;->getFloat(I)F
 HSPLandroid/content/res/Resources;->getFont(Landroid/util/TypedValue;I)Landroid/graphics/Typeface;
@@ -5143,7 +5169,7 @@
 HSPLandroid/content/res/Resources;->getQuantityString(II)Ljava/lang/String;
 HSPLandroid/content/res/Resources;->getQuantityString(II[Ljava/lang/Object;)Ljava/lang/String;
 HSPLandroid/content/res/Resources;->getQuantityText(II)Ljava/lang/CharSequence;
-HSPLandroid/content/res/Resources;->getResourceEntryName(I)Ljava/lang/String;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getResourceEntryName(I)Ljava/lang/String;
 HSPLandroid/content/res/Resources;->getResourceName(I)Ljava/lang/String;
 HSPLandroid/content/res/Resources;->getResourcePackageName(I)Ljava/lang/String;
 HSPLandroid/content/res/Resources;->getResourceTypeName(I)Ljava/lang/String;
@@ -5151,24 +5177,24 @@
 HSPLandroid/content/res/Resources;->getStateListAnimatorCache()Landroid/content/res/ConfigurationBoundResourceCache;
 HSPLandroid/content/res/Resources;->getString(I)Ljava/lang/String;
 HSPLandroid/content/res/Resources;->getString(I[Ljava/lang/Object;)Ljava/lang/String;
-HSPLandroid/content/res/Resources;->getStringArray(I)[Ljava/lang/String;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getStringArray(I)[Ljava/lang/String;
 HSPLandroid/content/res/Resources;->getSystem()Landroid/content/res/Resources;
 HSPLandroid/content/res/Resources;->getText(I)Ljava/lang/CharSequence;
 HSPLandroid/content/res/Resources;->getTextArray(I)[Ljava/lang/CharSequence;
-HSPLandroid/content/res/Resources;->getValue(ILandroid/util/TypedValue;Z)V+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getValue(ILandroid/util/TypedValue;Z)V
 HSPLandroid/content/res/Resources;->getValueForDensity(IILandroid/util/TypedValue;Z)V
 HSPLandroid/content/res/Resources;->getXml(I)Landroid/content/res/XmlResourceParser;
 HSPLandroid/content/res/Resources;->hasOverrideDisplayAdjustments()Z
-HSPLandroid/content/res/Resources;->loadColorStateList(Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->loadColorStateList(Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;
 HSPLandroid/content/res/Resources;->loadComplexColor(Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ComplexColor;
 HSPLandroid/content/res/Resources;->loadDrawable(Landroid/util/TypedValue;IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
-HSPLandroid/content/res/Resources;->loadXmlResourceParser(ILjava/lang/String;)Landroid/content/res/XmlResourceParser;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Ljava/lang/CharSequence;Ljava/lang/String;
-HSPLandroid/content/res/Resources;->loadXmlResourceParser(Ljava/lang/String;IILjava/lang/String;)Landroid/content/res/XmlResourceParser;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
-HSPLandroid/content/res/Resources;->newTheme()Landroid/content/res/Resources$Theme;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/content/res/Resources;->loadXmlResourceParser(ILjava/lang/String;)Landroid/content/res/XmlResourceParser;
+HSPLandroid/content/res/Resources;->loadXmlResourceParser(Ljava/lang/String;IILjava/lang/String;)Landroid/content/res/XmlResourceParser;
+HSPLandroid/content/res/Resources;->newTheme()Landroid/content/res/Resources$Theme;
 HSPLandroid/content/res/Resources;->obtainAttributes(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;
-HSPLandroid/content/res/Resources;->obtainAttributes(Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->obtainAttributes(Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
 HSPLandroid/content/res/Resources;->obtainTempTypedValue()Landroid/util/TypedValue;
-HSPLandroid/content/res/Resources;->obtainTypedArray(I)Landroid/content/res/TypedArray;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->obtainTypedArray(I)Landroid/content/res/TypedArray;
 HSPLandroid/content/res/Resources;->openRawResource(I)Ljava/io/InputStream;
 HSPLandroid/content/res/Resources;->openRawResource(ILandroid/util/TypedValue;)Ljava/io/InputStream;
 HSPLandroid/content/res/Resources;->openRawResourceFd(I)Landroid/content/res/AssetFileDescriptor;
@@ -5198,26 +5224,26 @@
 HSPLandroid/content/res/ResourcesImpl$LookupStack;->contains(I)Z
 HSPLandroid/content/res/ResourcesImpl$LookupStack;->pop()V
 HSPLandroid/content/res/ResourcesImpl$LookupStack;->push(I)V
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;-><init>(Landroid/content/res/ResourcesImpl;)V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->applyStyle(IZ)V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;-><init>(Landroid/content/res/ResourcesImpl;)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->applyStyle(IZ)V
 HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->finalize()V
 HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getAppliedStyleResId()I
 HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getChangingConfigurations()I
 HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getKey()Landroid/content/res/Resources$ThemeKey;
 HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getParentThemeIdentifier(I)I
 HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getTheme()[Ljava/lang/String;
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->obtainStyledAttributes(Landroid/content/res/Resources$Theme;Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->obtainStyledAttributes(Landroid/content/res/Resources$Theme;Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
 HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->rebase()V
 HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->rebase(Landroid/content/res/AssetManager;)V
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->resolveAttribute(ILandroid/util/TypedValue;Z)Z+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->resolveAttribute(ILandroid/util/TypedValue;Z)Z
 HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->resolveAttributes(Landroid/content/res/Resources$Theme;[I[I)Landroid/content/res/TypedArray;
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->setTo(Landroid/content/res/ResourcesImpl$ThemeImpl;)V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->setTo(Landroid/content/res/ResourcesImpl$ThemeImpl;)V
 HSPLandroid/content/res/ResourcesImpl;->-$$Nest$sfgetsThemeRegistry()Llibcore/util/NativeAllocationRegistry;
-HSPLandroid/content/res/ResourcesImpl;-><init>(Landroid/content/res/AssetManager;Landroid/util/DisplayMetrics;Landroid/content/res/Configuration;Landroid/view/DisplayAdjustments;)V+]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;
+HSPLandroid/content/res/ResourcesImpl;-><init>(Landroid/content/res/AssetManager;Landroid/util/DisplayMetrics;Landroid/content/res/Configuration;Landroid/view/DisplayAdjustments;)V+]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
 HSPLandroid/content/res/ResourcesImpl;->adjustLanguageTag(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/content/res/ResourcesImpl;->attrForQuantityCode(Ljava/lang/String;)I
-HSPLandroid/content/res/ResourcesImpl;->cacheDrawable(Landroid/util/TypedValue;ZLandroid/content/res/DrawableCache;Landroid/content/res/Resources$Theme;ZJLandroid/graphics/drawable/Drawable;I)V
-HSPLandroid/content/res/ResourcesImpl;->calcConfigChanges(Landroid/content/res/Configuration;)I+]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;
+HSPLandroid/content/res/ResourcesImpl;->cacheDrawable(Landroid/util/TypedValue;ZLandroid/content/res/DrawableCache;Landroid/content/res/Resources$Theme;ZJLandroid/graphics/drawable/Drawable;I)V+]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/graphics/drawable/Drawable;megamorphic_types
+HSPLandroid/content/res/ResourcesImpl;->calcConfigChanges(Landroid/content/res/Configuration;)I
 HSPLandroid/content/res/ResourcesImpl;->decodeImageDrawable(Landroid/content/res/AssetManager$AssetInputStream;Landroid/content/res/Resources;Landroid/util/TypedValue;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/content/res/ResourcesImpl;->dump(Ljava/io/PrintWriter;Ljava/lang/String;)V
 HSPLandroid/content/res/ResourcesImpl;->finishPreloading()V
@@ -5225,7 +5251,7 @@
 HSPLandroid/content/res/ResourcesImpl;->getAnimatorCache()Landroid/content/res/ConfigurationBoundResourceCache;
 HSPLandroid/content/res/ResourcesImpl;->getAssets()Landroid/content/res/AssetManager;
 HSPLandroid/content/res/ResourcesImpl;->getAttributeSetSourceResId(Landroid/util/AttributeSet;)I
-HSPLandroid/content/res/ResourcesImpl;->getColorStateListFromInt(Landroid/util/TypedValue;J)Landroid/content/res/ColorStateList;+]Landroid/content/res/ConstantState;Landroid/content/res/ColorStateList$ColorStateListFactory;]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;
+HSPLandroid/content/res/ResourcesImpl;->getColorStateListFromInt(Landroid/util/TypedValue;J)Landroid/content/res/ColorStateList;
 HSPLandroid/content/res/ResourcesImpl;->getCompatibilityInfo()Landroid/content/res/CompatibilityInfo;
 HSPLandroid/content/res/ResourcesImpl;->getConfiguration()Landroid/content/res/Configuration;
 HSPLandroid/content/res/ResourcesImpl;->getDisplayAdjustments()Landroid/view/DisplayAdjustments;
@@ -5239,7 +5265,7 @@
 HSPLandroid/content/res/ResourcesImpl;->getResourceTypeName(I)Ljava/lang/String;
 HSPLandroid/content/res/ResourcesImpl;->getSizeConfigurations()[Landroid/content/res/Configuration;
 HSPLandroid/content/res/ResourcesImpl;->getStateListAnimatorCache()Landroid/content/res/ConfigurationBoundResourceCache;
-HSPLandroid/content/res/ResourcesImpl;->getValue(ILandroid/util/TypedValue;Z)V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
+HSPLandroid/content/res/ResourcesImpl;->getValue(ILandroid/util/TypedValue;Z)V
 HSPLandroid/content/res/ResourcesImpl;->getValueForDensity(IILandroid/util/TypedValue;Z)V
 HSPLandroid/content/res/ResourcesImpl;->isIntLike(Ljava/lang/String;)Z
 HSPLandroid/content/res/ResourcesImpl;->lambda$decodeImageDrawable$1(Landroid/graphics/ImageDecoder;Landroid/graphics/ImageDecoder$ImageInfo;Landroid/graphics/ImageDecoder$Source;)V
@@ -5247,18 +5273,18 @@
 HSPLandroid/content/res/ResourcesImpl;->loadColorStateList(Landroid/content/res/Resources;Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;
 HSPLandroid/content/res/ResourcesImpl;->loadComplexColor(Landroid/content/res/Resources;Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ComplexColor;
 HSPLandroid/content/res/ResourcesImpl;->loadComplexColorForCookie(Landroid/content/res/Resources;Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ComplexColor;
-HSPLandroid/content/res/ResourcesImpl;->loadComplexColorFromName(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Landroid/util/TypedValue;I)Landroid/content/res/ComplexColor;+]Landroid/content/res/ComplexColor;Landroid/content/res/ColorStateList;,Landroid/content/res/GradientColor;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;]Landroid/content/res/ConstantState;Landroid/content/res/ColorStateList$ColorStateListFactory;]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;
-HSPLandroid/content/res/ResourcesImpl;->loadDrawable(Landroid/content/res/Resources;Landroid/util/TypedValue;IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/graphics/drawable/Drawable$ConstantState;megamorphic_types]Landroid/graphics/drawable/Drawable;megamorphic_types]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;
-HSPLandroid/content/res/ResourcesImpl;->loadDrawableForCookie(Landroid/content/res/Resources;Landroid/util/TypedValue;II)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/ResourcesImpl$LookupStack;Landroid/content/res/ResourcesImpl$LookupStack;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Ljava/lang/CharSequence;Ljava/lang/String;]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;
-HSPLandroid/content/res/ResourcesImpl;->loadFont(Landroid/content/res/Resources;Landroid/util/TypedValue;I)Landroid/graphics/Typeface;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Ljava/lang/CharSequence;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/content/res/ResourcesImpl;->loadComplexColorFromName(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Landroid/util/TypedValue;I)Landroid/content/res/ComplexColor;+]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;
+HSPLandroid/content/res/ResourcesImpl;->loadDrawable(Landroid/content/res/Resources;Landroid/util/TypedValue;IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;+]Landroid/graphics/drawable/Drawable$ConstantState;megamorphic_types]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/graphics/drawable/Drawable;megamorphic_types
+HSPLandroid/content/res/ResourcesImpl;->loadDrawableForCookie(Landroid/content/res/Resources;Landroid/util/TypedValue;II)Landroid/graphics/drawable/Drawable;
+HSPLandroid/content/res/ResourcesImpl;->loadFont(Landroid/content/res/Resources;Landroid/util/TypedValue;I)Landroid/graphics/Typeface;
 HSPLandroid/content/res/ResourcesImpl;->loadXmlDrawable(Landroid/content/res/Resources;Landroid/util/TypedValue;IILjava/lang/String;)Landroid/graphics/drawable/Drawable;
-HSPLandroid/content/res/ResourcesImpl;->loadXmlResourceParser(Ljava/lang/String;IILjava/lang/String;)Landroid/content/res/XmlResourceParser;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/XmlBlock;Landroid/content/res/XmlBlock;]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/content/res/ResourcesImpl;->loadXmlResourceParser(Ljava/lang/String;IILjava/lang/String;)Landroid/content/res/XmlResourceParser;+]Ljava/lang/Object;Ljava/lang/String;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/XmlBlock;Landroid/content/res/XmlBlock;
 HSPLandroid/content/res/ResourcesImpl;->newThemeImpl()Landroid/content/res/ResourcesImpl$ThemeImpl;
 HSPLandroid/content/res/ResourcesImpl;->openRawResource(ILandroid/util/TypedValue;)Ljava/io/InputStream;
 HSPLandroid/content/res/ResourcesImpl;->openRawResourceFd(ILandroid/util/TypedValue;)Landroid/content/res/AssetFileDescriptor;
 HSPLandroid/content/res/ResourcesImpl;->startPreloading()V
-HSPLandroid/content/res/ResourcesImpl;->updateConfiguration(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;)V+]Landroid/app/ResourcesManager;Landroid/app/ResourcesManager;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Ljava/util/Locale;Ljava/util/Locale;
-HSPLandroid/content/res/ResourcesImpl;->updateConfigurationImpl(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Z)V+]Landroid/app/ResourcesManager;Landroid/app/ResourcesManager;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;
+HSPLandroid/content/res/ResourcesImpl;->updateConfiguration(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;)V+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/app/ResourcesManager;Landroid/app/ResourcesManager;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Ljava/util/Locale;Ljava/util/Locale;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;
+HSPLandroid/content/res/ResourcesImpl;->updateConfigurationImpl(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Z)V+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/app/ResourcesManager;Landroid/app/ResourcesManager;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Ljava/util/Locale;Ljava/util/Locale;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;]Ljava/lang/Object;Ljava/util/Locale;
 HSPLandroid/content/res/ResourcesImpl;->verifyPreloadConfig(IIILjava/lang/String;)Z
 HSPLandroid/content/res/ResourcesKey;-><init>(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;ILandroid/content/res/Configuration;Landroid/content/res/CompatibilityInfo;[Landroid/content/res/loader/ResourcesLoader;)V
 HSPLandroid/content/res/ResourcesKey;->equals(Ljava/lang/Object;)Z
@@ -5271,9 +5297,9 @@
 HSPLandroid/content/res/StringBlock;->get(I)Ljava/lang/CharSequence;
 HSPLandroid/content/res/StringBlock;->getSequence(I)Ljava/lang/CharSequence;+]Landroid/util/SparseArray;Landroid/util/SparseArray;
 HSPLandroid/content/res/ThemedResourceCache;-><init>()V
-HSPLandroid/content/res/ThemedResourceCache;->get(JLandroid/content/res/Resources$Theme;)Ljava/lang/Object;+]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/content/res/ThemedResourceCache;->get(JLandroid/content/res/Resources$Theme;)Ljava/lang/Object;
 HSPLandroid/content/res/ThemedResourceCache;->getGeneration()I
-HSPLandroid/content/res/ThemedResourceCache;->getThemedLocked(Landroid/content/res/Resources$Theme;Z)Landroid/util/LongSparseArray;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/content/res/ThemedResourceCache;->getThemedLocked(Landroid/content/res/Resources$Theme;Z)Landroid/util/LongSparseArray;
 HSPLandroid/content/res/ThemedResourceCache;->getUnthemedLocked(Z)Landroid/util/LongSparseArray;
 HSPLandroid/content/res/ThemedResourceCache;->onConfigurationChange(I)V
 HSPLandroid/content/res/ThemedResourceCache;->pruneEntriesLocked(Landroid/util/LongSparseArray;I)Z
@@ -5285,24 +5311,24 @@
 HSPLandroid/content/res/TypedArray;->extractThemeAttrs([I)[I
 HSPLandroid/content/res/TypedArray;->getBoolean(IZ)Z
 HSPLandroid/content/res/TypedArray;->getChangingConfigurations()I+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
-HSPLandroid/content/res/TypedArray;->getColor(II)I+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/content/res/TypedArray;->getColor(II)I
 HSPLandroid/content/res/TypedArray;->getColorStateList(I)Landroid/content/res/ColorStateList;+]Landroid/content/res/Resources;Landroid/content/res/Resources;
 HSPLandroid/content/res/TypedArray;->getComplexColor(I)Landroid/content/res/ComplexColor;
 HSPLandroid/content/res/TypedArray;->getDimension(IF)F
 HSPLandroid/content/res/TypedArray;->getDimensionPixelOffset(II)I
 HSPLandroid/content/res/TypedArray;->getDimensionPixelSize(II)I
-HSPLandroid/content/res/TypedArray;->getDrawable(I)Landroid/graphics/drawable/Drawable;
+HSPLandroid/content/res/TypedArray;->getDrawable(I)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
 HSPLandroid/content/res/TypedArray;->getDrawableForDensity(II)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/Resources;Landroid/content/res/Resources;
 HSPLandroid/content/res/TypedArray;->getFloat(IF)F
-HSPLandroid/content/res/TypedArray;->getFont(I)Landroid/graphics/Typeface;+]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/content/res/TypedArray;->getFont(I)Landroid/graphics/Typeface;
 HSPLandroid/content/res/TypedArray;->getFraction(IIIF)F
 HSPLandroid/content/res/TypedArray;->getIndex(I)I
 HSPLandroid/content/res/TypedArray;->getIndexCount()I
 HSPLandroid/content/res/TypedArray;->getInt(II)I
 HSPLandroid/content/res/TypedArray;->getInteger(II)I
 HSPLandroid/content/res/TypedArray;->getLayoutDimension(II)I
-HSPLandroid/content/res/TypedArray;->getLayoutDimension(ILjava/lang/String;)I+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/content/res/TypedArray;->getNonConfigurationString(II)Ljava/lang/String;
+HSPLandroid/content/res/TypedArray;->getLayoutDimension(ILjava/lang/String;)I
+HSPLandroid/content/res/TypedArray;->getNonConfigurationString(II)Ljava/lang/String;+]Ljava/lang/CharSequence;Ljava/lang/String;
 HSPLandroid/content/res/TypedArray;->getNonResourceString(I)Ljava/lang/String;
 HSPLandroid/content/res/TypedArray;->getPositionDescription()Ljava/lang/String;
 HSPLandroid/content/res/TypedArray;->getResourceId(II)I
@@ -5316,7 +5342,7 @@
 HSPLandroid/content/res/TypedArray;->hasValue(I)Z
 HSPLandroid/content/res/TypedArray;->hasValueOrEmpty(I)Z
 HSPLandroid/content/res/TypedArray;->length()I
-HSPLandroid/content/res/TypedArray;->loadStringValueAt(I)Ljava/lang/CharSequence;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/content/res/TypedArray;->loadStringValueAt(I)Ljava/lang/CharSequence;+]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Validator;Landroid/content/res/Validator;
 HSPLandroid/content/res/TypedArray;->obtain(Landroid/content/res/Resources;I)Landroid/content/res/TypedArray;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
 HSPLandroid/content/res/TypedArray;->peekValue(I)Landroid/util/TypedValue;
 HSPLandroid/content/res/TypedArray;->recycle()V+]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
@@ -5333,7 +5359,7 @@
 HSPLandroid/content/res/XmlBlock$Parser;->getAttributeNameResource(I)I
 HSPLandroid/content/res/XmlBlock$Parser;->getAttributeResourceValue(II)I
 HSPLandroid/content/res/XmlBlock$Parser;->getAttributeResourceValue(Ljava/lang/String;Ljava/lang/String;I)I
-HSPLandroid/content/res/XmlBlock$Parser;->getAttributeValue(I)Ljava/lang/String;
+HSPLandroid/content/res/XmlBlock$Parser;->getAttributeValue(I)Ljava/lang/String;+]Landroid/content/res/StringBlock;Landroid/content/res/StringBlock;
 HSPLandroid/content/res/XmlBlock$Parser;->getAttributeValue(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/content/res/XmlBlock$Parser;->getClassAttribute()Ljava/lang/String;
 HSPLandroid/content/res/XmlBlock$Parser;->getDepth()I
@@ -5342,14 +5368,14 @@
 HSPLandroid/content/res/XmlBlock$Parser;->getName()Ljava/lang/String;+]Landroid/content/res/StringBlock;Landroid/content/res/StringBlock;
 HSPLandroid/content/res/XmlBlock$Parser;->getPooledString(I)Ljava/lang/CharSequence;+]Landroid/content/res/StringBlock;Landroid/content/res/StringBlock;
 HSPLandroid/content/res/XmlBlock$Parser;->getPositionDescription()Ljava/lang/String;
-HSPLandroid/content/res/XmlBlock$Parser;->getSequenceString(Ljava/lang/CharSequence;)Ljava/lang/String;+]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/content/res/XmlBlock$Parser;->getSequenceString(Ljava/lang/CharSequence;)Ljava/lang/String;
 HSPLandroid/content/res/XmlBlock$Parser;->getSourceResId()I
 HSPLandroid/content/res/XmlBlock$Parser;->getText()Ljava/lang/String;
 HSPLandroid/content/res/XmlBlock$Parser;->isEmptyElementTag()Z
-HSPLandroid/content/res/XmlBlock$Parser;->next()I+]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/content/res/XmlBlock$Parser;->next()I+]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;]Landroid/content/res/Validator;Landroid/content/res/Validator;
 HSPLandroid/content/res/XmlBlock$Parser;->nextTag()I
 HSPLandroid/content/res/XmlBlock$Parser;->nextText()Ljava/lang/String;
-HSPLandroid/content/res/XmlBlock$Parser;->require(ILjava/lang/String;Ljava/lang/String;)V+]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/content/res/XmlBlock$Parser;->require(ILjava/lang/String;Ljava/lang/String;)V
 HSPLandroid/content/res/XmlBlock;->-$$Nest$fgetmOpenCount(Landroid/content/res/XmlBlock;)I
 HSPLandroid/content/res/XmlBlock;->-$$Nest$fputmOpenCount(Landroid/content/res/XmlBlock;I)V
 HSPLandroid/content/res/XmlBlock;->-$$Nest$smnativeGetAttributeCount(J)I
@@ -5363,7 +5389,7 @@
 HSPLandroid/content/res/XmlBlock;->-$$Nest$smnativeGetText(J)I
 HSPLandroid/content/res/XmlBlock;-><init>(Landroid/content/res/AssetManager;J)V
 HSPLandroid/content/res/XmlBlock;->close()V
-HSPLandroid/content/res/XmlBlock;->decOpenCountLocked()V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/StringBlock;Landroid/content/res/StringBlock;]Ljava/lang/Object;Landroid/content/res/XmlBlock;
+HSPLandroid/content/res/XmlBlock;->decOpenCountLocked()V
 HSPLandroid/content/res/XmlBlock;->finalize()V
 HSPLandroid/content/res/XmlBlock;->newParser()Landroid/content/res/XmlResourceParser;
 HSPLandroid/content/res/XmlBlock;->newParser(I)Landroid/content/res/XmlResourceParser;
@@ -5373,29 +5399,29 @@
 HSPLandroid/content/type/DefaultMimeMapFactory;->parseTypes(Llibcore/content/type/MimeMap$Builder;Ljava/util/function/Function;Ljava/lang/String;)V
 HSPLandroid/database/AbstractCursor$SelfContentObserver;-><init>(Landroid/database/AbstractCursor;)V
 HSPLandroid/database/AbstractCursor$SelfContentObserver;->onChange(Z)V
-HSPLandroid/database/AbstractCursor;-><init>()V
-HSPLandroid/database/AbstractCursor;->checkPosition()V+]Landroid/database/AbstractCursor;Landroid/database/BulkCursorToCursorAdaptor;,Landroid/database/sqlite/SQLiteCursor;
-HSPLandroid/database/AbstractCursor;->close()V
+HSPLandroid/database/AbstractCursor;-><init>()V+]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
+HSPLandroid/database/AbstractCursor;->checkPosition()V+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;
+HSPLandroid/database/AbstractCursor;->close()V+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;,Landroid/database/MatrixCursor;]Landroid/database/ContentObservable;Landroid/database/ContentObservable;]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
 HSPLandroid/database/AbstractCursor;->fillWindow(ILandroid/database/CursorWindow;)V
 HSPLandroid/database/AbstractCursor;->finalize()V+]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
-HSPLandroid/database/AbstractCursor;->getColumnCount()I
+HSPLandroid/database/AbstractCursor;->getColumnCount()I+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;
 HSPLandroid/database/AbstractCursor;->getColumnIndex(Ljava/lang/String;)I
 HSPLandroid/database/AbstractCursor;->getColumnIndexOrThrow(Ljava/lang/String;)I
-HSPLandroid/database/AbstractCursor;->getColumnName(I)Ljava/lang/String;
+HSPLandroid/database/AbstractCursor;->getColumnName(I)Ljava/lang/String;+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;
 HSPLandroid/database/AbstractCursor;->getExtras()Landroid/os/Bundle;
 HSPLandroid/database/AbstractCursor;->getPosition()I
 HSPLandroid/database/AbstractCursor;->getWantsAllOnMoveCalls()Z
 HSPLandroid/database/AbstractCursor;->getWindow()Landroid/database/CursorWindow;
-HSPLandroid/database/AbstractCursor;->isAfterLast()Z
+HSPLandroid/database/AbstractCursor;->isAfterLast()Z+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;
 HSPLandroid/database/AbstractCursor;->isClosed()Z
 HSPLandroid/database/AbstractCursor;->isLast()Z
 HSPLandroid/database/AbstractCursor;->move(I)Z
 HSPLandroid/database/AbstractCursor;->moveToFirst()Z
 HSPLandroid/database/AbstractCursor;->moveToLast()Z
-HSPLandroid/database/AbstractCursor;->moveToNext()Z
-HSPLandroid/database/AbstractCursor;->moveToPosition(I)Z
+HSPLandroid/database/AbstractCursor;->moveToNext()Z+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/MatrixCursor;,Landroid/database/BulkCursorToCursorAdaptor;
+HSPLandroid/database/AbstractCursor;->moveToPosition(I)Z+]Landroid/database/AbstractCursor;missing_types
 HSPLandroid/database/AbstractCursor;->onChange(Z)V
-HSPLandroid/database/AbstractCursor;->onDeactivateOrClose()V
+HSPLandroid/database/AbstractCursor;->onDeactivateOrClose()V+]Landroid/database/DataSetObservable;Landroid/database/DataSetObservable;
 HSPLandroid/database/AbstractCursor;->onMove(II)Z
 HSPLandroid/database/AbstractCursor;->registerContentObserver(Landroid/database/ContentObserver;)V
 HSPLandroid/database/AbstractCursor;->registerDataSetObserver(Landroid/database/DataSetObserver;)V
@@ -5406,18 +5432,18 @@
 HSPLandroid/database/AbstractWindowedCursor;-><init>()V
 HSPLandroid/database/AbstractWindowedCursor;->checkPosition()V
 HSPLandroid/database/AbstractWindowedCursor;->clearOrCreateWindow(Ljava/lang/String;)V
-HSPLandroid/database/AbstractWindowedCursor;->closeWindow()V
+HSPLandroid/database/AbstractWindowedCursor;->closeWindow()V+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
 HSPLandroid/database/AbstractWindowedCursor;->getBlob(I)[B
-HSPLandroid/database/AbstractWindowedCursor;->getDouble(I)D
+HSPLandroid/database/AbstractWindowedCursor;->getDouble(I)D+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
 HSPLandroid/database/AbstractWindowedCursor;->getFloat(I)F
-HSPLandroid/database/AbstractWindowedCursor;->getInt(I)I+]Landroid/database/AbstractWindowedCursor;Landroid/database/BulkCursorToCursorAdaptor;,Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
-HSPLandroid/database/AbstractWindowedCursor;->getLong(I)J+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
-HSPLandroid/database/AbstractWindowedCursor;->getString(I)Ljava/lang/String;+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
+HSPLandroid/database/AbstractWindowedCursor;->getInt(I)I+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
+HSPLandroid/database/AbstractWindowedCursor;->getLong(I)J+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
+HSPLandroid/database/AbstractWindowedCursor;->getString(I)Ljava/lang/String;+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
 HSPLandroid/database/AbstractWindowedCursor;->getType(I)I
 HSPLandroid/database/AbstractWindowedCursor;->getWindow()Landroid/database/CursorWindow;
 HSPLandroid/database/AbstractWindowedCursor;->hasWindow()Z
 HSPLandroid/database/AbstractWindowedCursor;->isNull(I)Z+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
-HSPLandroid/database/AbstractWindowedCursor;->onDeactivateOrClose()V
+HSPLandroid/database/AbstractWindowedCursor;->onDeactivateOrClose()V+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;
 HSPLandroid/database/AbstractWindowedCursor;->setWindow(Landroid/database/CursorWindow;)V
 HSPLandroid/database/BulkCursorDescriptor$1;->createFromParcel(Landroid/os/Parcel;)Landroid/database/BulkCursorDescriptor;
 HSPLandroid/database/BulkCursorDescriptor$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -5438,7 +5464,7 @@
 HSPLandroid/database/BulkCursorToCursorAdaptor;->getCount()I
 HSPLandroid/database/BulkCursorToCursorAdaptor;->getObserver()Landroid/database/IContentObserver;
 HSPLandroid/database/BulkCursorToCursorAdaptor;->initialize(Landroid/database/BulkCursorDescriptor;)V
-HSPLandroid/database/BulkCursorToCursorAdaptor;->onMove(II)Z
+HSPLandroid/database/BulkCursorToCursorAdaptor;->onMove(II)Z+]Landroid/database/IBulkCursor;Landroid/database/BulkCursorProxy;]Landroid/database/BulkCursorToCursorAdaptor;Landroid/database/BulkCursorToCursorAdaptor;
 HSPLandroid/database/BulkCursorToCursorAdaptor;->throwIfCursorIsClosed()V
 HSPLandroid/database/ContentObservable;-><init>()V
 HSPLandroid/database/ContentObservable;->dispatchChange(ZLandroid/net/Uri;)V
@@ -5477,18 +5503,18 @@
 HSPLandroid/database/CursorWindow;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/database/CursorWindow;-><init>(Landroid/os/Parcel;Landroid/database/CursorWindow-IA;)V
 HSPLandroid/database/CursorWindow;-><init>(Ljava/lang/String;)V
-HSPLandroid/database/CursorWindow;-><init>(Ljava/lang/String;J)V
+HSPLandroid/database/CursorWindow;-><init>(Ljava/lang/String;J)V+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/database/CursorWindow;->allocRow()Z
 HSPLandroid/database/CursorWindow;->clear()V
-HSPLandroid/database/CursorWindow;->dispose()V
-HSPLandroid/database/CursorWindow;->finalize()V
-HSPLandroid/database/CursorWindow;->getBlob(II)[B+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
+HSPLandroid/database/CursorWindow;->dispose()V+]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
+HSPLandroid/database/CursorWindow;->finalize()V+]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
+HSPLandroid/database/CursorWindow;->getBlob(II)[B
 HSPLandroid/database/CursorWindow;->getCursorWindowSize()I
-HSPLandroid/database/CursorWindow;->getDouble(II)D
+HSPLandroid/database/CursorWindow;->getDouble(II)D+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
 HSPLandroid/database/CursorWindow;->getFloat(II)F
-HSPLandroid/database/CursorWindow;->getInt(II)I
+HSPLandroid/database/CursorWindow;->getInt(II)I+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
 HSPLandroid/database/CursorWindow;->getLong(II)J+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
-HSPLandroid/database/CursorWindow;->getNumRows()I
+HSPLandroid/database/CursorWindow;->getNumRows()I+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
 HSPLandroid/database/CursorWindow;->getStartPosition()I
 HSPLandroid/database/CursorWindow;->getString(II)Ljava/lang/String;+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
 HSPLandroid/database/CursorWindow;->getType(II)I+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
@@ -5510,16 +5536,16 @@
 HSPLandroid/database/CursorWrapper;->getColumnNames()[Ljava/lang/String;
 HSPLandroid/database/CursorWrapper;->getCount()I
 HSPLandroid/database/CursorWrapper;->getExtras()Landroid/os/Bundle;
-HSPLandroid/database/CursorWrapper;->getInt(I)I
+HSPLandroid/database/CursorWrapper;->getInt(I)I+]Landroid/database/Cursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/content/ContentProviderClient$CursorWrapperInner;,Landroid/database/BulkCursorToCursorAdaptor;
 HSPLandroid/database/CursorWrapper;->getLong(I)J
 HSPLandroid/database/CursorWrapper;->getPosition()I
 HSPLandroid/database/CursorWrapper;->getString(I)Ljava/lang/String;
 HSPLandroid/database/CursorWrapper;->getType(I)I
 HSPLandroid/database/CursorWrapper;->getWrappedCursor()Landroid/database/Cursor;
-HSPLandroid/database/CursorWrapper;->isAfterLast()Z
+HSPLandroid/database/CursorWrapper;->isAfterLast()Z+]Landroid/database/Cursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/content/ContentProviderClient$CursorWrapperInner;,Landroid/database/BulkCursorToCursorAdaptor;
 HSPLandroid/database/CursorWrapper;->isClosed()Z
 HSPLandroid/database/CursorWrapper;->isLast()Z
-HSPLandroid/database/CursorWrapper;->isNull(I)Z
+HSPLandroid/database/CursorWrapper;->isNull(I)Z+]Landroid/database/Cursor;Landroid/database/BulkCursorToCursorAdaptor;
 HSPLandroid/database/CursorWrapper;->moveToFirst()Z
 HSPLandroid/database/CursorWrapper;->moveToLast()Z
 HSPLandroid/database/CursorWrapper;->moveToNext()Z
@@ -5527,9 +5553,9 @@
 HSPLandroid/database/CursorWrapper;->registerContentObserver(Landroid/database/ContentObserver;)V
 HSPLandroid/database/DataSetObservable;-><init>()V
 HSPLandroid/database/DataSetObservable;->notifyChanged()V
-HSPLandroid/database/DataSetObservable;->notifyInvalidated()V
+HSPLandroid/database/DataSetObservable;->notifyInvalidated()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/database/DataSetObserver;-><init>()V
-HSPLandroid/database/DatabaseUtils;->appendEscapedSQLString(Ljava/lang/StringBuilder;Ljava/lang/String;)V
+HSPLandroid/database/DatabaseUtils;->appendEscapedSQLString(Ljava/lang/StringBuilder;Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/database/DatabaseUtils;->categorizeStatement(Ljava/lang/String;Ljava/lang/String;)I+]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/database/DatabaseUtils;->cursorFillWindow(Landroid/database/Cursor;ILandroid/database/CursorWindow;)V
 HSPLandroid/database/DatabaseUtils;->getSqlStatementPrefixSimple(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
@@ -5584,16 +5610,16 @@
 HSPLandroid/database/MergeCursor;->onMove(II)Z
 HSPLandroid/database/Observable;-><init>()V
 HSPLandroid/database/Observable;->registerObserver(Ljava/lang/Object;)V
-HSPLandroid/database/Observable;->unregisterAll()V
+HSPLandroid/database/Observable;->unregisterAll()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/database/Observable;->unregisterObserver(Ljava/lang/Object;)V
 HSPLandroid/database/sqlite/FeatureFlagsImpl;-><init>()V
 HSPLandroid/database/sqlite/FeatureFlagsImpl;->sqliteAllowTempTables()Z
 HSPLandroid/database/sqlite/Flags;-><clinit>()V
-HSPLandroid/database/sqlite/Flags;->sqliteAllowTempTables()Z
+HSPLandroid/database/sqlite/Flags;->sqliteAllowTempTables()Z+]Landroid/database/sqlite/FeatureFlags;Landroid/database/sqlite/FeatureFlagsImpl;
 HSPLandroid/database/sqlite/SQLiteClosable;-><init>()V
 HSPLandroid/database/sqlite/SQLiteClosable;->acquireReference()V
-HSPLandroid/database/sqlite/SQLiteClosable;->close()V
-HSPLandroid/database/sqlite/SQLiteClosable;->releaseReference()V+]Landroid/database/sqlite/SQLiteClosable;Landroid/database/CursorWindow;,Landroid/database/sqlite/SQLiteDatabase;,Landroid/database/sqlite/SQLiteQuery;,Landroid/database/sqlite/SQLiteStatement;
+HSPLandroid/database/sqlite/SQLiteClosable;->close()V+]Landroid/database/sqlite/SQLiteClosable;Landroid/database/CursorWindow;,Landroid/database/sqlite/SQLiteStatement;,Landroid/database/sqlite/SQLiteDatabase;,Landroid/database/sqlite/SQLiteQuery;
+HSPLandroid/database/sqlite/SQLiteClosable;->releaseReference()V+]Landroid/database/sqlite/SQLiteClosable;Landroid/database/CursorWindow;,Landroid/database/sqlite/SQLiteStatement;,Landroid/database/sqlite/SQLiteDatabase;,Landroid/database/sqlite/SQLiteQuery;
 HSPLandroid/database/sqlite/SQLiteCompatibilityWalFlags;->getTruncateSize()J
 HSPLandroid/database/sqlite/SQLiteCompatibilityWalFlags;->init(Ljava/lang/String;)V
 HSPLandroid/database/sqlite/SQLiteCompatibilityWalFlags;->initIfNeeded()V
@@ -5607,7 +5633,7 @@
 HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->dump(Landroid/util/Printer;)V
 HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->endOperation(I)V
 HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->endOperationDeferLog(I)Z
-HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->endOperationDeferLogLocked(I)Z
+HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->endOperationDeferLogLocked(I)Z+]Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteConnectionPool;
 HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->failOperation(ILjava/lang/Exception;)V
 HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->getOperationLocked(I)Landroid/database/sqlite/SQLiteConnection$Operation;
 HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->newOperationCookieLocked(I)I
@@ -5623,38 +5649,38 @@
 HSPLandroid/database/sqlite/SQLiteConnection;->-$$Nest$fgetmConnectionPtr(Landroid/database/sqlite/SQLiteConnection;)J
 HSPLandroid/database/sqlite/SQLiteConnection;->-$$Nest$mfinalizePreparedStatement(Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
 HSPLandroid/database/sqlite/SQLiteConnection;->-$$Nest$smnativePrepareStatement(JLjava/lang/String;)J
-HSPLandroid/database/sqlite/SQLiteConnection;-><init>(Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteDatabaseConfiguration;IZ)V
+HSPLandroid/database/sqlite/SQLiteConnection;-><init>(Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteDatabaseConfiguration;IZ)V+]Landroid/database/sqlite/SQLiteDatabaseConfiguration;Landroid/database/sqlite/SQLiteDatabaseConfiguration;]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
 HSPLandroid/database/sqlite/SQLiteConnection;->acquirePreparedStatement(Ljava/lang/String;)Landroid/database/sqlite/SQLiteConnection$PreparedStatement;
 HSPLandroid/database/sqlite/SQLiteConnection;->acquirePreparedStatementLI(Ljava/lang/String;)Landroid/database/sqlite/SQLiteConnection$PreparedStatement;+]Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;
-HSPLandroid/database/sqlite/SQLiteConnection;->applyBlockGuardPolicy(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
-HSPLandroid/database/sqlite/SQLiteConnection;->attachCancellationSignal(Landroid/os/CancellationSignal;)V
-HSPLandroid/database/sqlite/SQLiteConnection;->bindArguments(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;[Ljava/lang/Object;)V+]Ljava/lang/Number;Ljava/lang/Double;,Ljava/lang/Integer;,Ljava/lang/Long;]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteConnection;->applyBlockGuardPolicy(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V+]Landroid/database/sqlite/SQLiteDatabaseConfiguration;Landroid/database/sqlite/SQLiteDatabaseConfiguration;]Ldalvik/system/BlockGuard$Policy;Ldalvik/system/BlockGuard$1;,Landroid/os/StrictMode$AndroidBlockGuardPolicy;
+HSPLandroid/database/sqlite/SQLiteConnection;->attachCancellationSignal(Landroid/os/CancellationSignal;)V+]Landroid/os/CancellationSignal;Landroid/os/CancellationSignal;
+HSPLandroid/database/sqlite/SQLiteConnection;->bindArguments(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;[Ljava/lang/Object;)V+]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/Number;Ljava/lang/Integer;,Ljava/lang/Double;,Ljava/lang/Long;
 HSPLandroid/database/sqlite/SQLiteConnection;->canonicalizeSyncMode(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteConnection;->checkDatabaseWiped()V
 HSPLandroid/database/sqlite/SQLiteConnection;->close()V
 HSPLandroid/database/sqlite/SQLiteConnection;->collectDbStats(Ljava/util/ArrayList;)V
-HSPLandroid/database/sqlite/SQLiteConnection;->detachCancellationSignal(Landroid/os/CancellationSignal;)V
+HSPLandroid/database/sqlite/SQLiteConnection;->detachCancellationSignal(Landroid/os/CancellationSignal;)V+]Landroid/os/CancellationSignal;Landroid/os/CancellationSignal;
 HSPLandroid/database/sqlite/SQLiteConnection;->dispose(Z)V
 HSPLandroid/database/sqlite/SQLiteConnection;->dumpUnsafe(Landroid/util/Printer;Z)V
-HSPLandroid/database/sqlite/SQLiteConnection;->execute(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)V+]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
-HSPLandroid/database/sqlite/SQLiteConnection;->executeForChangedRowCount(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)I
-HSPLandroid/database/sqlite/SQLiteConnection;->executeForCursorWindow(Ljava/lang/String;[Ljava/lang/Object;Landroid/database/CursorWindow;IIZLandroid/os/CancellationSignal;)I
+HSPLandroid/database/sqlite/SQLiteConnection;->execute(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
+HSPLandroid/database/sqlite/SQLiteConnection;->executeForChangedRowCount(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)I+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
+HSPLandroid/database/sqlite/SQLiteConnection;->executeForCursorWindow(Ljava/lang/String;[Ljava/lang/Object;Landroid/database/CursorWindow;IIZLandroid/os/CancellationSignal;)I+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
 HSPLandroid/database/sqlite/SQLiteConnection;->executeForLastInsertedRowId(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)J
-HSPLandroid/database/sqlite/SQLiteConnection;->executeForLong(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)J+]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
-HSPLandroid/database/sqlite/SQLiteConnection;->executeForString(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteConnection;->executeForLong(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)J+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
+HSPLandroid/database/sqlite/SQLiteConnection;->executeForString(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)Ljava/lang/String;+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
 HSPLandroid/database/sqlite/SQLiteConnection;->executePerConnectionSqlFromConfiguration(I)V
 HSPLandroid/database/sqlite/SQLiteConnection;->finalize()V
 HSPLandroid/database/sqlite/SQLiteConnection;->finalizePreparedStatement(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
 HSPLandroid/database/sqlite/SQLiteConnection;->getConnectionId()I
 HSPLandroid/database/sqlite/SQLiteConnection;->getMainDbStatsUnsafe(IJJ)Landroid/database/sqlite/SQLiteDebug$DbStats;
 HSPLandroid/database/sqlite/SQLiteConnection;->isCacheable(I)Z
-HSPLandroid/database/sqlite/SQLiteConnection;->isPreparedStatementInCache(Ljava/lang/String;)Z
+HSPLandroid/database/sqlite/SQLiteConnection;->isPreparedStatementInCache(Ljava/lang/String;)Z+]Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;
 HSPLandroid/database/sqlite/SQLiteConnection;->isPrimaryConnection()Z
 HSPLandroid/database/sqlite/SQLiteConnection;->maybeTruncateWalFile()V
 HSPLandroid/database/sqlite/SQLiteConnection;->obtainPreparedStatement(Ljava/lang/String;JIIZJ)Landroid/database/sqlite/SQLiteConnection$PreparedStatement;
-HSPLandroid/database/sqlite/SQLiteConnection;->open()V
+HSPLandroid/database/sqlite/SQLiteConnection;->open()V+]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
 HSPLandroid/database/sqlite/SQLiteConnection;->open(Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteDatabaseConfiguration;IZ)Landroid/database/sqlite/SQLiteConnection;
-HSPLandroid/database/sqlite/SQLiteConnection;->prepare(Ljava/lang/String;Landroid/database/sqlite/SQLiteStatementInfo;)V
+HSPLandroid/database/sqlite/SQLiteConnection;->prepare(Ljava/lang/String;Landroid/database/sqlite/SQLiteStatementInfo;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
 HSPLandroid/database/sqlite/SQLiteConnection;->reconfigure(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V
 HSPLandroid/database/sqlite/SQLiteConnection;->recyclePreparedStatement(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
 HSPLandroid/database/sqlite/SQLiteConnection;->releasePreparedStatement(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
@@ -5679,6 +5705,7 @@
 HSPLandroid/database/sqlite/SQLiteConnectionPool$IdleConnectionHandler;->handleMessage(Landroid/os/Message;)V
 HSPLandroid/database/sqlite/SQLiteConnectionPool;-><init>(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->acquireConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->clearAcquiredConnectionsPreparedStatementCache()V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;]Ljava/util/Iterator;Ljava/util/WeakHashMap$KeyIterator;]Ljava/util/Set;Ljava/util/WeakHashMap$KeySet;
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->close()V
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->closeAvailableConnectionLocked(I)Z
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->closeAvailableConnectionsAndLogExceptionsLocked()V
@@ -5692,13 +5719,13 @@
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->dispose(Z)V
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->dump(Landroid/util/Printer;ZLandroid/util/ArraySet;)V
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->finalize()V
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->finishAcquireConnectionLocked(Landroid/database/sqlite/SQLiteConnection;I)V
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->finishAcquireConnectionLocked(Landroid/database/sqlite/SQLiteConnection;I)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->getPath()Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->getPriority(I)I
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->isSessionBlockingImportantConnectionWaitersLocked(ZI)Z
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->markAcquiredConnectionsLocked(Landroid/database/sqlite/SQLiteConnectionPool$AcquiredConnectionStatus;)V
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->obtainConnectionWaiterLocked(Ljava/lang/Thread;JIZLjava/lang/String;I)Landroid/database/sqlite/SQLiteConnectionPool$ConnectionWaiter;
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->onStatementExecuted(J)V
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->onStatementExecuted(J)V+]Ljava/util/concurrent/atomic/AtomicLong;Ljava/util/concurrent/atomic/AtomicLong;
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->open()V
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->open(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)Landroid/database/sqlite/SQLiteConnectionPool;
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->openConnectionLocked(Landroid/database/sqlite/SQLiteDatabaseConfiguration;Z)Landroid/database/sqlite/SQLiteConnection;
@@ -5706,23 +5733,23 @@
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->reconfigureAllConnectionsLocked()V
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->recycleConnectionLocked(Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnectionPool$AcquiredConnectionStatus;)Z
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->recycleConnectionWaiterLocked(Landroid/database/sqlite/SQLiteConnectionPool$ConnectionWaiter;)V
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->releaseConnection(Landroid/database/sqlite/SQLiteConnection;)V
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->releaseConnection(Landroid/database/sqlite/SQLiteConnection;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->setMaxConnectionPoolSizeLocked()V
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->shouldYieldConnection(Landroid/database/sqlite/SQLiteConnection;I)Z
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->throwIfClosedLocked()V
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->tryAcquireNonPrimaryConnectionLocked(Ljava/lang/String;I)Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->tryAcquireNonPrimaryConnectionLocked(Ljava/lang/String;I)Landroid/database/sqlite/SQLiteConnection;+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->tryAcquirePrimaryConnectionLocked(I)Landroid/database/sqlite/SQLiteConnection;
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->waitForConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->waitForConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)Landroid/database/sqlite/SQLiteConnection;+]Ljava/util/concurrent/atomic/AtomicBoolean;Ljava/util/concurrent/atomic/AtomicBoolean;
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->wakeConnectionWaitersLocked()V
 HSPLandroid/database/sqlite/SQLiteConstraintException;-><init>(Ljava/lang/String;)V
-HSPLandroid/database/sqlite/SQLiteCursor;-><init>(Landroid/database/sqlite/SQLiteCursorDriver;Ljava/lang/String;Landroid/database/sqlite/SQLiteQuery;)V
-HSPLandroid/database/sqlite/SQLiteCursor;->close()V
-HSPLandroid/database/sqlite/SQLiteCursor;->fillWindow(I)V
+HSPLandroid/database/sqlite/SQLiteCursor;-><init>(Landroid/database/sqlite/SQLiteCursorDriver;Ljava/lang/String;Landroid/database/sqlite/SQLiteQuery;)V+]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
+HSPLandroid/database/sqlite/SQLiteCursor;->close()V+]Landroid/database/sqlite/SQLiteCursorDriver;Landroid/database/sqlite/SQLiteDirectCursorDriver;]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
+HSPLandroid/database/sqlite/SQLiteCursor;->fillWindow(I)V+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;]Landroid/database/sqlite/SQLiteCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteCursor;->finalize()V
-HSPLandroid/database/sqlite/SQLiteCursor;->getColumnIndex(Ljava/lang/String;)I
+HSPLandroid/database/sqlite/SQLiteCursor;->getColumnIndex(Ljava/lang/String;)I+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/Map;Ljava/util/HashMap;
 HSPLandroid/database/sqlite/SQLiteCursor;->getColumnNames()[Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteCursor;->getCount()I
-HSPLandroid/database/sqlite/SQLiteCursor;->getDatabase()Landroid/database/sqlite/SQLiteDatabase;
+HSPLandroid/database/sqlite/SQLiteCursor;->getDatabase()Landroid/database/sqlite/SQLiteDatabase;+]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
 HSPLandroid/database/sqlite/SQLiteCursor;->onMove(II)Z+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
 HSPLandroid/database/sqlite/SQLiteDatabase$$ExternalSyntheticLambda0;-><init>(Landroid/database/sqlite/SQLiteDatabase;)V
 HSPLandroid/database/sqlite/SQLiteDatabase$$ExternalSyntheticLambda0;->get()Ljava/lang/Object;
@@ -5749,13 +5776,13 @@
 HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;->-$$Nest$fgetmSyncMode(Landroid/database/sqlite/SQLiteDatabase$OpenParams;)Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;-><init>(ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;IIJLjava/lang/String;Ljava/lang/String;)V
 HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;-><init>(ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;IIJLjava/lang/String;Ljava/lang/String;Landroid/database/sqlite/SQLiteDatabase$OpenParams-IA;)V
-HSPLandroid/database/sqlite/SQLiteDatabase;-><init>(Ljava/lang/String;ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;IIJLjava/lang/String;Ljava/lang/String;)V
+HSPLandroid/database/sqlite/SQLiteDatabase;-><init>(Ljava/lang/String;ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;IIJLjava/lang/String;Ljava/lang/String;)V+]Landroid/database/sqlite/SQLiteDatabaseConfiguration;Landroid/database/sqlite/SQLiteDatabaseConfiguration;
 HSPLandroid/database/sqlite/SQLiteDatabase;->beginTransaction()V
 HSPLandroid/database/sqlite/SQLiteDatabase;->beginTransaction(Landroid/database/sqlite/SQLiteTransactionListener;Z)V
 HSPLandroid/database/sqlite/SQLiteDatabase;->beginTransactionNonExclusive()V
 HSPLandroid/database/sqlite/SQLiteDatabase;->beginTransactionWithListener(Landroid/database/sqlite/SQLiteTransactionListener;)V
 HSPLandroid/database/sqlite/SQLiteDatabase;->collectDbStats(Ljava/util/ArrayList;)V
-HSPLandroid/database/sqlite/SQLiteDatabase;->compileStatement(Ljava/lang/String;)Landroid/database/sqlite/SQLiteStatement;+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
+HSPLandroid/database/sqlite/SQLiteDatabase;->compileStatement(Ljava/lang/String;)Landroid/database/sqlite/SQLiteStatement;
 HSPLandroid/database/sqlite/SQLiteDatabase;->createSession()Landroid/database/sqlite/SQLiteSession;
 HSPLandroid/database/sqlite/SQLiteDatabase;->delete(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)I
 HSPLandroid/database/sqlite/SQLiteDatabase;->deleteDatabase(Ljava/io/File;)Z
@@ -5770,7 +5797,7 @@
 HSPLandroid/database/sqlite/SQLiteDatabase;->execSQL(Ljava/lang/String;[Ljava/lang/Object;)V
 HSPLandroid/database/sqlite/SQLiteDatabase;->executeSql(Ljava/lang/String;[Ljava/lang/Object;)I
 HSPLandroid/database/sqlite/SQLiteDatabase;->finalize()V
-HSPLandroid/database/sqlite/SQLiteDatabase;->findEditTable(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteDatabase;->findEditTable(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteDatabase;->getActiveDatabasePools()Ljava/util/ArrayList;
 HSPLandroid/database/sqlite/SQLiteDatabase;->getActiveDatabases()Ljava/util/ArrayList;
 HSPLandroid/database/sqlite/SQLiteDatabase;->getFileTimestamps(Ljava/lang/String;)Ljava/lang/String;
@@ -5778,12 +5805,12 @@
 HSPLandroid/database/sqlite/SQLiteDatabase;->getPageSize()J
 HSPLandroid/database/sqlite/SQLiteDatabase;->getPath()Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteDatabase;->getThreadDefaultConnectionFlags(Z)I
-HSPLandroid/database/sqlite/SQLiteDatabase;->getThreadSession()Landroid/database/sqlite/SQLiteSession;
+HSPLandroid/database/sqlite/SQLiteDatabase;->getThreadSession()Landroid/database/sqlite/SQLiteSession;+]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;
 HSPLandroid/database/sqlite/SQLiteDatabase;->getVersion()I
-HSPLandroid/database/sqlite/SQLiteDatabase;->inTransaction()Z
+HSPLandroid/database/sqlite/SQLiteDatabase;->inTransaction()Z+]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteDatabase;->insert(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;)J
 HSPLandroid/database/sqlite/SQLiteDatabase;->insertOrThrow(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;)J
-HSPLandroid/database/sqlite/SQLiteDatabase;->insertWithOnConflict(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;I)J+]Landroid/content/ContentValues;Landroid/content/ContentValues;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;]Landroid/database/sqlite/SQLiteStatement;Landroid/database/sqlite/SQLiteStatement;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
+HSPLandroid/database/sqlite/SQLiteDatabase;->insertWithOnConflict(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;I)J
 HSPLandroid/database/sqlite/SQLiteDatabase;->isMainThread()Z
 HSPLandroid/database/sqlite/SQLiteDatabase;->isOpen()Z
 HSPLandroid/database/sqlite/SQLiteDatabase;->isReadOnly()Z
@@ -5801,11 +5828,11 @@
 HSPLandroid/database/sqlite/SQLiteDatabase;->query(Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
 HSPLandroid/database/sqlite/SQLiteDatabase;->query(ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
 HSPLandroid/database/sqlite/SQLiteDatabase;->query(ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
-HSPLandroid/database/sqlite/SQLiteDatabase;->queryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
+HSPLandroid/database/sqlite/SQLiteDatabase;->queryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteDatabase;->rawQuery(Ljava/lang/String;[Ljava/lang/String;)Landroid/database/Cursor;
 HSPLandroid/database/sqlite/SQLiteDatabase;->rawQuery(Ljava/lang/String;[Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
-HSPLandroid/database/sqlite/SQLiteDatabase;->rawQueryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
-HSPLandroid/database/sqlite/SQLiteDatabase;->rawQueryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
+HSPLandroid/database/sqlite/SQLiteDatabase;->rawQueryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
+HSPLandroid/database/sqlite/SQLiteDatabase;->rawQueryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;+]Landroid/database/sqlite/SQLiteCursorDriver;Landroid/database/sqlite/SQLiteDirectCursorDriver;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteDatabase;->releaseMemory()I
 HSPLandroid/database/sqlite/SQLiteDatabase;->replace(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;)J
 HSPLandroid/database/sqlite/SQLiteDatabase;->replaceOrThrow(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;)J
@@ -5813,26 +5840,26 @@
 HSPLandroid/database/sqlite/SQLiteDatabase;->setTransactionSuccessful()V
 HSPLandroid/database/sqlite/SQLiteDatabase;->throwIfNotOpenLocked()V
 HSPLandroid/database/sqlite/SQLiteDatabase;->update(Ljava/lang/String;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;)I
-HSPLandroid/database/sqlite/SQLiteDatabase;->updateWithOnConflict(Ljava/lang/String;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;I)I
+HSPLandroid/database/sqlite/SQLiteDatabase;->updateWithOnConflict(Ljava/lang/String;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;I)I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/content/ContentValues;Landroid/content/ContentValues;]Landroid/database/sqlite/SQLiteStatement;Landroid/database/sqlite/SQLiteStatement;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
 HSPLandroid/database/sqlite/SQLiteDatabase;->validateSql(Ljava/lang/String;Landroid/os/CancellationSignal;)V
 HSPLandroid/database/sqlite/SQLiteDatabase;->yieldIfContendedHelper(ZJ)Z
 HSPLandroid/database/sqlite/SQLiteDatabase;->yieldIfContendedSafely(J)Z
 HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;-><init>(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V
 HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;-><init>(Ljava/lang/String;I)V
-HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isInMemoryDb()Z
+HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isInMemoryDb()Z+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isLegacyCompatibilityWalEnabled()Z
 HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isReadOnlyDatabase()Z
 HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isWalEnabledInternal()Z
 HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->resolveJournalMode()Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->resolveSyncMode()Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->stripPathForLogs(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->updateParametersFrom(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V
+HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->updateParametersFrom(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Object;Ljava/lang/String;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/database/sqlite/SQLiteDebug$NoPreloadHolder;-><clinit>()V
 HSPLandroid/database/sqlite/SQLiteDebug;->getDatabaseInfo()Landroid/database/sqlite/SQLiteDebug$PagerStats;
 HSPLandroid/database/sqlite/SQLiteDebug;->shouldLogSlowQuery(J)Z
 HSPLandroid/database/sqlite/SQLiteDirectCursorDriver;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)V
 HSPLandroid/database/sqlite/SQLiteDirectCursorDriver;->cursorClosed()V
-HSPLandroid/database/sqlite/SQLiteDirectCursorDriver;->query(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;[Ljava/lang/String;)Landroid/database/Cursor;
+HSPLandroid/database/sqlite/SQLiteDirectCursorDriver;->query(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;[Ljava/lang/String;)Landroid/database/Cursor;+]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
 HSPLandroid/database/sqlite/SQLiteException;-><init>(Ljava/lang/String;)V
 HSPLandroid/database/sqlite/SQLiteGlobal;->checkDbWipe()Z
 HSPLandroid/database/sqlite/SQLiteGlobal;->getDefaultJournalMode()Ljava/lang/String;
@@ -5849,7 +5876,7 @@
 HSPLandroid/database/sqlite/SQLiteOpenHelper;-><init>(Landroid/content/Context;Ljava/lang/String;Landroid/database/sqlite/SQLiteDatabase$CursorFactory;IILandroid/database/DatabaseErrorHandler;)V
 HSPLandroid/database/sqlite/SQLiteOpenHelper;-><init>(Landroid/content/Context;Ljava/lang/String;Landroid/database/sqlite/SQLiteDatabase$CursorFactory;ILandroid/database/DatabaseErrorHandler;)V
 HSPLandroid/database/sqlite/SQLiteOpenHelper;->close()V
-HSPLandroid/database/sqlite/SQLiteOpenHelper;->getDatabaseLocked(Z)Landroid/database/sqlite/SQLiteDatabase;
+HSPLandroid/database/sqlite/SQLiteOpenHelper;->getDatabaseLocked(Z)Landroid/database/sqlite/SQLiteDatabase;+]Ljava/io/File;Ljava/io/File;]Landroid/database/sqlite/SQLiteDatabase$OpenParams$Builder;Landroid/database/sqlite/SQLiteDatabase$OpenParams$Builder;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteOpenHelper;->getDatabaseName()Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteOpenHelper;->getReadableDatabase()Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteOpenHelper;->getWritableDatabase()Landroid/database/sqlite/SQLiteDatabase;
@@ -5859,9 +5886,9 @@
 HSPLandroid/database/sqlite/SQLiteOpenHelper;->setIdleConnectionTimeout(J)V
 HSPLandroid/database/sqlite/SQLiteOpenHelper;->setOpenParamsBuilder(Landroid/database/sqlite/SQLiteDatabase$OpenParams$Builder;)V
 HSPLandroid/database/sqlite/SQLiteOpenHelper;->setWriteAheadLoggingEnabled(Z)V
-HSPLandroid/database/sqlite/SQLiteProgram;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)V
+HSPLandroid/database/sqlite/SQLiteProgram;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteProgram;->bind(ILjava/lang/Object;)V
-HSPLandroid/database/sqlite/SQLiteProgram;->bindAllArgsAsStrings([Ljava/lang/String;)V
+HSPLandroid/database/sqlite/SQLiteProgram;->bindAllArgsAsStrings([Ljava/lang/String;)V+]Landroid/database/sqlite/SQLiteProgram;Landroid/database/sqlite/SQLiteQuery;,Landroid/database/sqlite/SQLiteStatement;
 HSPLandroid/database/sqlite/SQLiteProgram;->bindBlob(I[B)V
 HSPLandroid/database/sqlite/SQLiteProgram;->bindDouble(ID)V
 HSPLandroid/database/sqlite/SQLiteProgram;->bindLong(IJ)V
@@ -5870,19 +5897,19 @@
 HSPLandroid/database/sqlite/SQLiteProgram;->clearBindings()V
 HSPLandroid/database/sqlite/SQLiteProgram;->getBindArgs()[Ljava/lang/Object;
 HSPLandroid/database/sqlite/SQLiteProgram;->getColumnNames()[Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteProgram;->getConnectionFlags()I
+HSPLandroid/database/sqlite/SQLiteProgram;->getConnectionFlags()I+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteProgram;->getDatabase()Landroid/database/sqlite/SQLiteDatabase;
-HSPLandroid/database/sqlite/SQLiteProgram;->getSession()Landroid/database/sqlite/SQLiteSession;
+HSPLandroid/database/sqlite/SQLiteProgram;->getSession()Landroid/database/sqlite/SQLiteSession;+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteProgram;->getSql()Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteProgram;->onAllReferencesReleased()V
+HSPLandroid/database/sqlite/SQLiteProgram;->onAllReferencesReleased()V+]Landroid/database/sqlite/SQLiteProgram;Landroid/database/sqlite/SQLiteStatement;,Landroid/database/sqlite/SQLiteQuery;
 HSPLandroid/database/sqlite/SQLiteQuery;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;Landroid/os/CancellationSignal;)V
-HSPLandroid/database/sqlite/SQLiteQuery;->fillWindow(Landroid/database/CursorWindow;IIZ)I
+HSPLandroid/database/sqlite/SQLiteQuery;->fillWindow(Landroid/database/CursorWindow;IIZ)I+]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
 HSPLandroid/database/sqlite/SQLiteQueryBuilder;-><init>()V
-HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendClause(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/String;)V
-HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendColumns(Ljava/lang/StringBuilder;[Ljava/lang/String;)V
+HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendClause(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/String;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendColumns(Ljava/lang/StringBuilder;[Ljava/lang/String;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendWhere(Ljava/lang/CharSequence;)V
 HSPLandroid/database/sqlite/SQLiteQueryBuilder;->buildQuery([Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteQueryBuilder;->buildQueryString(ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteQueryBuilder;->buildQueryString(ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/database/sqlite/SQLiteQueryBuilder;->computeProjection([Ljava/lang/String;)[Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteQueryBuilder;->computeSingleProjection(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteQueryBuilder;->computeSingleProjectionOrThrow(Ljava/lang/String;)Ljava/lang/String;
@@ -5902,25 +5929,25 @@
 HSPLandroid/database/sqlite/SQLiteSession$Transaction;-><init>()V
 HSPLandroid/database/sqlite/SQLiteSession$Transaction;-><init>(Landroid/database/sqlite/SQLiteSession$Transaction-IA;)V
 HSPLandroid/database/sqlite/SQLiteSession;-><init>(Landroid/database/sqlite/SQLiteConnectionPool;)V
-HSPLandroid/database/sqlite/SQLiteSession;->acquireConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)V
+HSPLandroid/database/sqlite/SQLiteSession;->acquireConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)V+]Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteConnectionPool;
 HSPLandroid/database/sqlite/SQLiteSession;->beginTransaction(ILandroid/database/sqlite/SQLiteTransactionListener;ILandroid/os/CancellationSignal;)V
 HSPLandroid/database/sqlite/SQLiteSession;->beginTransactionUnchecked(ILandroid/database/sqlite/SQLiteTransactionListener;ILandroid/os/CancellationSignal;)V
 HSPLandroid/database/sqlite/SQLiteSession;->closeOpenDependents()V+]Ljava/util/ArrayDeque;Ljava/util/ArrayDeque;
 HSPLandroid/database/sqlite/SQLiteSession;->endTransaction(Landroid/os/CancellationSignal;)V
 HSPLandroid/database/sqlite/SQLiteSession;->endTransactionUnchecked(Landroid/os/CancellationSignal;Z)V
-HSPLandroid/database/sqlite/SQLiteSession;->execute(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)V
-HSPLandroid/database/sqlite/SQLiteSession;->executeForChangedRowCount(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)I
-HSPLandroid/database/sqlite/SQLiteSession;->executeForCursorWindow(Ljava/lang/String;[Ljava/lang/Object;Landroid/database/CursorWindow;IIZILandroid/os/CancellationSignal;)I
+HSPLandroid/database/sqlite/SQLiteSession;->execute(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteSession;->executeForChangedRowCount(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)I+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteSession;->executeForCursorWindow(Ljava/lang/String;[Ljava/lang/Object;Landroid/database/CursorWindow;IIZILandroid/os/CancellationSignal;)I+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
 HSPLandroid/database/sqlite/SQLiteSession;->executeForLastInsertedRowId(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)J
 HSPLandroid/database/sqlite/SQLiteSession;->executeForLong(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)J
 HSPLandroid/database/sqlite/SQLiteSession;->executeForString(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteSession;->executeSpecial(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)Z
+HSPLandroid/database/sqlite/SQLiteSession;->executeSpecial(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)Z+]Landroid/os/CancellationSignal;Landroid/os/CancellationSignal;
 HSPLandroid/database/sqlite/SQLiteSession;->hasNestedTransaction()Z
 HSPLandroid/database/sqlite/SQLiteSession;->hasTransaction()Z
 HSPLandroid/database/sqlite/SQLiteSession;->obtainTransaction(ILandroid/database/sqlite/SQLiteTransactionListener;)Landroid/database/sqlite/SQLiteSession$Transaction;
-HSPLandroid/database/sqlite/SQLiteSession;->prepare(Ljava/lang/String;ILandroid/os/CancellationSignal;Landroid/database/sqlite/SQLiteStatementInfo;)V
+HSPLandroid/database/sqlite/SQLiteSession;->prepare(Ljava/lang/String;ILandroid/os/CancellationSignal;Landroid/database/sqlite/SQLiteStatementInfo;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/os/CancellationSignal;Landroid/os/CancellationSignal;
 HSPLandroid/database/sqlite/SQLiteSession;->recycleTransaction(Landroid/database/sqlite/SQLiteSession$Transaction;)V
-HSPLandroid/database/sqlite/SQLiteSession;->releaseConnection()V
+HSPLandroid/database/sqlite/SQLiteSession;->releaseConnection()V+]Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteConnectionPool;
 HSPLandroid/database/sqlite/SQLiteSession;->setTransactionSuccessful()V
 HSPLandroid/database/sqlite/SQLiteSession;->throwIfNestedTransaction()V
 HSPLandroid/database/sqlite/SQLiteSession;->throwIfNoTransaction()V
@@ -5930,7 +5957,7 @@
 HSPLandroid/database/sqlite/SQLiteStatement;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;[Ljava/lang/Object;)V
 HSPLandroid/database/sqlite/SQLiteStatement;->execute()V+]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/sqlite/SQLiteStatement;Landroid/database/sqlite/SQLiteStatement;
 HSPLandroid/database/sqlite/SQLiteStatement;->executeInsert()J
-HSPLandroid/database/sqlite/SQLiteStatement;->executeUpdateDelete()I
+HSPLandroid/database/sqlite/SQLiteStatement;->executeUpdateDelete()I+]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/sqlite/SQLiteStatement;Landroid/database/sqlite/SQLiteStatement;
 HSPLandroid/database/sqlite/SQLiteStatement;->simpleQueryForLong()J
 HSPLandroid/database/sqlite/SQLiteStatement;->simpleQueryForString()Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteStatementInfo;-><init>()V
@@ -5965,33 +5992,33 @@
 HSPLandroid/graphics/BaseCanvas;->drawBitmap(Landroid/graphics/Bitmap;Landroid/graphics/Rect;Landroid/graphics/RectF;Landroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseCanvas;->drawColor(I)V
 HSPLandroid/graphics/BaseCanvas;->drawLine(FFFFLandroid/graphics/Paint;)V
-HSPLandroid/graphics/BaseCanvas;->drawPath(Landroid/graphics/Path;Landroid/graphics/Paint;)V+]Landroid/graphics/Path;Landroid/graphics/Path;
+HSPLandroid/graphics/BaseCanvas;->drawPath(Landroid/graphics/Path;Landroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseCanvas;->drawText(Ljava/lang/CharSequence;IIFFLandroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseCanvas;->drawTextRun(Ljava/lang/CharSequence;IIIIFFZLandroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseCanvas;->throwIfCannotDraw(Landroid/graphics/Bitmap;)V
-HSPLandroid/graphics/BaseCanvas;->throwIfHasHwFeaturesInSwMode(Landroid/graphics/Paint;)V+]Landroid/graphics/BaseCanvas;Landroid/graphics/Canvas;
+HSPLandroid/graphics/BaseCanvas;->throwIfHasHwFeaturesInSwMode(Landroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseCanvas;->throwIfHasHwFeaturesInSwMode(Landroid/graphics/Shader;)V
 HSPLandroid/graphics/BaseCanvas;->throwIfHwBitmapInSwMode(Landroid/graphics/Bitmap;)V
 HSPLandroid/graphics/BaseRecordingCanvas;-><init>(J)V
-HSPLandroid/graphics/BaseRecordingCanvas;->drawArc(Landroid/graphics/RectF;FFZLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawArc(Landroid/graphics/RectF;FFZLandroid/graphics/Paint;)V+]Landroid/graphics/BaseRecordingCanvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/graphics/BaseRecordingCanvas;->drawBitmap(Landroid/graphics/Bitmap;FFLandroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawBitmap(Landroid/graphics/Bitmap;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Paint;)V
-HSPLandroid/graphics/BaseRecordingCanvas;->drawCircle(FFFLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawCircle(FFFLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;
 HSPLandroid/graphics/BaseRecordingCanvas;->drawColor(I)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawColor(ILandroid/graphics/PorterDuff$Mode;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawLine(FFFFLandroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawOval(FFFFLandroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawOval(Landroid/graphics/RectF;Landroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawPatch(Landroid/graphics/NinePatch;Landroid/graphics/Rect;Landroid/graphics/Paint;)V
-HSPLandroid/graphics/BaseRecordingCanvas;->drawPath(Landroid/graphics/Path;Landroid/graphics/Paint;)V+]Landroid/graphics/Paint;missing_types]Landroid/graphics/Path;Landroid/graphics/Path;
+HSPLandroid/graphics/BaseRecordingCanvas;->drawPath(Landroid/graphics/Path;Landroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/Path;Landroid/graphics/Path;
 HSPLandroid/graphics/BaseRecordingCanvas;->drawRect(FFFFLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;
 HSPLandroid/graphics/BaseRecordingCanvas;->drawRect(Landroid/graphics/Rect;Landroid/graphics/Paint;)V+]Landroid/graphics/BaseRecordingCanvas;Landroid/graphics/RecordingCanvas;
-HSPLandroid/graphics/BaseRecordingCanvas;->drawRect(Landroid/graphics/RectF;Landroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;
+HSPLandroid/graphics/BaseRecordingCanvas;->drawRect(Landroid/graphics/RectF;Landroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawRoundRect(FFFFFFLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;
-HSPLandroid/graphics/BaseRecordingCanvas;->drawRoundRect(Landroid/graphics/RectF;FFLandroid/graphics/Paint;)V+]Landroid/graphics/BaseRecordingCanvas;Landroid/graphics/RecordingCanvas;
-HSPLandroid/graphics/BaseRecordingCanvas;->drawText(Ljava/lang/CharSequence;IIFFLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawRoundRect(Landroid/graphics/RectF;FFLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawText(Ljava/lang/CharSequence;IIFFLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/Layout$Ellipsizer;
 HSPLandroid/graphics/BaseRecordingCanvas;->drawText(Ljava/lang/String;FFLandroid/graphics/Paint;)V
-HSPLandroid/graphics/BaseRecordingCanvas;->drawTextRun(Ljava/lang/CharSequence;IIIIFFZLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawTextRun(Ljava/lang/CharSequence;IIIIFFZLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Landroid/text/SpannableString;
 HSPLandroid/graphics/BaseRecordingCanvas;->drawTextRun([CIIIIFFZLandroid/graphics/Paint;)V
 HSPLandroid/graphics/Bitmap$1;->createFromParcel(Landroid/os/Parcel;)Landroid/graphics/Bitmap;
 HSPLandroid/graphics/Bitmap$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -6072,7 +6099,7 @@
 HSPLandroid/graphics/BitmapShader;-><init>(Landroid/graphics/Bitmap;Landroid/graphics/Shader$TileMode;Landroid/graphics/Shader$TileMode;)V
 HSPLandroid/graphics/BitmapShader;->createNativeInstance(JZ)J
 HSPLandroid/graphics/BitmapShader;->shouldDiscardNativeInstance(Z)Z
-HSPLandroid/graphics/BlendMode;->blendModeToPorterDuffMode(Landroid/graphics/BlendMode;)Landroid/graphics/PorterDuff$Mode;+]Landroid/graphics/BlendMode;Landroid/graphics/BlendMode;
+HSPLandroid/graphics/BlendMode;->blendModeToPorterDuffMode(Landroid/graphics/BlendMode;)Landroid/graphics/PorterDuff$Mode;
 HSPLandroid/graphics/BlendMode;->fromValue(I)Landroid/graphics/BlendMode;
 HSPLandroid/graphics/BlendMode;->getXfermode()Landroid/graphics/Xfermode;
 HSPLandroid/graphics/BlendMode;->toValue(Landroid/graphics/BlendMode;)I
@@ -6136,8 +6163,8 @@
 HSPLandroid/graphics/Canvas;->save()I
 HSPLandroid/graphics/Canvas;->save(I)I
 HSPLandroid/graphics/Canvas;->saveLayer(FFFFLandroid/graphics/Paint;I)I
-HSPLandroid/graphics/Canvas;->saveLayer(Landroid/graphics/RectF;Landroid/graphics/Paint;)I+]Landroid/graphics/Canvas;Landroid/graphics/Canvas;,Landroid/graphics/RecordingCanvas;
-HSPLandroid/graphics/Canvas;->saveLayer(Landroid/graphics/RectF;Landroid/graphics/Paint;I)I+]Landroid/graphics/Canvas;Landroid/graphics/Canvas;,Landroid/graphics/RecordingCanvas;
+HSPLandroid/graphics/Canvas;->saveLayer(Landroid/graphics/RectF;Landroid/graphics/Paint;)I
+HSPLandroid/graphics/Canvas;->saveLayer(Landroid/graphics/RectF;Landroid/graphics/Paint;I)I
 HSPLandroid/graphics/Canvas;->saveLayerAlpha(FFFFI)I
 HSPLandroid/graphics/Canvas;->saveLayerAlpha(FFFFII)I
 HSPLandroid/graphics/Canvas;->saveUnclippedLayer(IIII)I
@@ -6170,7 +6197,7 @@
 HSPLandroid/graphics/Color;->green(I)I
 HSPLandroid/graphics/Color;->green(J)F
 HSPLandroid/graphics/Color;->luminance()F
-HSPLandroid/graphics/Color;->pack(FFFFLandroid/graphics/ColorSpace;)J+]Landroid/graphics/ColorSpace;Landroid/graphics/ColorSpace$Rgb;
+HSPLandroid/graphics/Color;->pack(FFFFLandroid/graphics/ColorSpace;)J
 HSPLandroid/graphics/Color;->pack(I)J
 HSPLandroid/graphics/Color;->parseColor(Ljava/lang/String;)I
 HSPLandroid/graphics/Color;->red()F
@@ -6296,8 +6323,8 @@
 HSPLandroid/graphics/HardwareRendererObserver$$ExternalSyntheticLambda0;->run()V
 HSPLandroid/graphics/HardwareRendererObserver;-><init>(Landroid/graphics/HardwareRendererObserver$OnFrameMetricsAvailableListener;[JLandroid/os/Handler;Z)V
 HSPLandroid/graphics/HardwareRendererObserver;->getNativeInstance()J
-HSPLandroid/graphics/HardwareRendererObserver;->invokeDataAvailable(Ljava/lang/ref/WeakReference;)Z
-HSPLandroid/graphics/HardwareRendererObserver;->notifyDataAvailable()V
+HSPLandroid/graphics/HardwareRendererObserver;->invokeDataAvailable(Ljava/lang/ref/WeakReference;)Z+]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/graphics/HardwareRendererObserver;->notifyDataAvailable()V+]Landroid/os/Handler;Landroid/os/Handler;,Landroid/view/ViewRootImpl$ViewRootHandler;
 HSPLandroid/graphics/ImageDecoder$AssetInputStreamSource;-><init>(Landroid/content/res/AssetManager$AssetInputStream;Landroid/content/res/Resources;Landroid/util/TypedValue;)V
 HSPLandroid/graphics/ImageDecoder$AssetInputStreamSource;->createImageDecoder(Z)Landroid/graphics/ImageDecoder;
 HSPLandroid/graphics/ImageDecoder$AssetInputStreamSource;->getDensity()I
@@ -6362,18 +6389,18 @@
 HSPLandroid/graphics/LinearGradient;-><init>(FFFFIILandroid/graphics/Shader$TileMode;)V
 HSPLandroid/graphics/LinearGradient;-><init>(FFFFJJLandroid/graphics/Shader$TileMode;)V
 HSPLandroid/graphics/LinearGradient;-><init>(FFFF[I[FLandroid/graphics/Shader$TileMode;)V
-HSPLandroid/graphics/LinearGradient;-><init>(FFFF[J[FLandroid/graphics/Shader$TileMode;)V
+HSPLandroid/graphics/LinearGradient;-><init>(FFFF[J[FLandroid/graphics/Shader$TileMode;)V+][J[J
 HSPLandroid/graphics/LinearGradient;-><init>(FFFF[J[FLandroid/graphics/Shader$TileMode;Landroid/graphics/ColorSpace;)V
-HSPLandroid/graphics/LinearGradient;->createNativeInstance(JZ)J+]Landroid/graphics/ColorSpace;Landroid/graphics/ColorSpace$Rgb;]Landroid/graphics/LinearGradient;Landroid/graphics/LinearGradient;
+HSPLandroid/graphics/LinearGradient;->createNativeInstance(JZ)J
 HSPLandroid/graphics/MaskFilter;->finalize()V
 HSPLandroid/graphics/Matrix;-><init>()V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
-HSPLandroid/graphics/Matrix;-><init>(Landroid/graphics/Matrix;)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/Matrix;-><init>(Landroid/graphics/Matrix;)V
 HSPLandroid/graphics/Matrix;->checkPointArrays([FI[FII)V
 HSPLandroid/graphics/Matrix;->equals(Ljava/lang/Object;)Z
 HSPLandroid/graphics/Matrix;->getValues([F)V
 HSPLandroid/graphics/Matrix;->invert(Landroid/graphics/Matrix;)Z
 HSPLandroid/graphics/Matrix;->isIdentity()Z
-HSPLandroid/graphics/Matrix;->mapPoints([F)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
+HSPLandroid/graphics/Matrix;->mapPoints([F)V
 HSPLandroid/graphics/Matrix;->mapPoints([FI[FII)V
 HSPLandroid/graphics/Matrix;->mapRect(Landroid/graphics/RectF;)Z+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
 HSPLandroid/graphics/Matrix;->mapRect(Landroid/graphics/RectF;Landroid/graphics/RectF;)Z
@@ -6411,18 +6438,18 @@
 HSPLandroid/graphics/Outline;->isEmpty()Z
 HSPLandroid/graphics/Outline;->setAlpha(F)V
 HSPLandroid/graphics/Outline;->setConvexPath(Landroid/graphics/Path;)V
-HSPLandroid/graphics/Outline;->setEmpty()V+]Landroid/graphics/Path;Landroid/graphics/Path;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/graphics/Outline;->setEmpty()V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
 HSPLandroid/graphics/Outline;->setOval(IIII)V
 HSPLandroid/graphics/Outline;->setOval(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/Outline;->setPath(Landroid/graphics/Path;)V
-HSPLandroid/graphics/Outline;->setRect(IIII)V
+HSPLandroid/graphics/Outline;->setRect(IIII)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;
 HSPLandroid/graphics/Outline;->setRect(Landroid/graphics/Rect;)V
-HSPLandroid/graphics/Outline;->setRoundRect(IIIIF)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;]Landroid/graphics/Rect;Landroid/graphics/Rect;
-HSPLandroid/graphics/Outline;->setRoundRect(Landroid/graphics/Rect;F)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;
+HSPLandroid/graphics/Outline;->setRoundRect(IIIIF)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/Outline;Landroid/graphics/Outline;
+HSPLandroid/graphics/Outline;->setRoundRect(Landroid/graphics/Rect;F)V
 HSPLandroid/graphics/Paint$FontMetrics;-><init>()V
 HSPLandroid/graphics/Paint$FontMetricsInt;-><init>()V
 HSPLandroid/graphics/Paint;-><init>()V
-HSPLandroid/graphics/Paint;-><init>(I)V+]Landroid/graphics/Paint;missing_types]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/Paint;-><init>(I)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;,Landroid/text/TextPaint;]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
 HSPLandroid/graphics/Paint;-><init>(Landroid/graphics/Paint;)V
 HSPLandroid/graphics/Paint;->ascent()F
 HSPLandroid/graphics/Paint;->descent()F
@@ -6434,17 +6461,18 @@
 HSPLandroid/graphics/Paint;->getFontFeatureSettings()Ljava/lang/String;
 HSPLandroid/graphics/Paint;->getFontMetrics()Landroid/graphics/Paint$FontMetrics;
 HSPLandroid/graphics/Paint;->getFontMetrics(Landroid/graphics/Paint$FontMetrics;)F
-HSPLandroid/graphics/Paint;->getFontMetricsInt()Landroid/graphics/Paint$FontMetricsInt;
+HSPLandroid/graphics/Paint;->getFontMetricsInt()Landroid/graphics/Paint$FontMetricsInt;+]Landroid/graphics/Paint;Landroid/text/TextPaint;
 HSPLandroid/graphics/Paint;->getFontMetricsInt(Landroid/graphics/Paint$FontMetricsInt;)I
-HSPLandroid/graphics/Paint;->getFontMetricsInt(Ljava/lang/CharSequence;IIIIZLandroid/graphics/Paint$FontMetricsInt;)V+]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/graphics/Paint;->getFontMetricsInt(Ljava/lang/CharSequence;IIIIZLandroid/graphics/Paint$FontMetricsInt;)V
 HSPLandroid/graphics/Paint;->getFontVariationSettings()Ljava/lang/String;
 HSPLandroid/graphics/Paint;->getHinting()I
 HSPLandroid/graphics/Paint;->getLetterSpacing()F
 HSPLandroid/graphics/Paint;->getMaskFilter()Landroid/graphics/MaskFilter;
-HSPLandroid/graphics/Paint;->getNativeInstance()J+]Landroid/graphics/ColorFilter;Landroid/graphics/BlendModeColorFilter;,Landroid/graphics/PorterDuffColorFilter;]Landroid/graphics/Paint;missing_types]Landroid/graphics/Shader;Landroid/graphics/BitmapShader;,Landroid/graphics/LinearGradient;,Landroid/graphics/drawable/RippleShader;
+HSPLandroid/graphics/Paint;->getNativeInstance()J+]Landroid/graphics/ColorFilter;Landroid/graphics/PorterDuffColorFilter;,Landroid/graphics/BlendModeColorFilter;]Landroid/graphics/Paint;missing_types]Landroid/graphics/Shader;Landroid/graphics/LinearGradient;,Landroid/graphics/drawable/RippleShader;,Landroid/graphics/BitmapShader;,Landroid/graphics/RadialGradient;
 HSPLandroid/graphics/Paint;->getRunAdvance(Ljava/lang/CharSequence;IIIIZI)F
 HSPLandroid/graphics/Paint;->getRunAdvance([CIIIIZI)F
 HSPLandroid/graphics/Paint;->getRunCharacterAdvance(Ljava/lang/CharSequence;IIIIZI[FI)F
+HSPLandroid/graphics/Paint;->getRunCharacterAdvance(Ljava/lang/CharSequence;IIIIZI[FILandroid/graphics/RectF;Landroid/graphics/Paint$RunInfo;)F+]Landroid/graphics/Paint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;megamorphic_types
 HSPLandroid/graphics/Paint;->getRunCharacterAdvance([CIIIIZI[FI)F
 HSPLandroid/graphics/Paint;->getShader()Landroid/graphics/Shader;
 HSPLandroid/graphics/Paint;->getShadowLayerColor()I
@@ -6458,7 +6486,7 @@
 HSPLandroid/graphics/Paint;->getStrokeWidth()F
 HSPLandroid/graphics/Paint;->getStyle()Landroid/graphics/Paint$Style;
 HSPLandroid/graphics/Paint;->getTextAlign()Landroid/graphics/Paint$Align;
-HSPLandroid/graphics/Paint;->getTextBounds(Ljava/lang/CharSequence;IILandroid/graphics/Rect;)V
+HSPLandroid/graphics/Paint;->getTextBounds(Ljava/lang/CharSequence;IILandroid/graphics/Rect;)V+]Landroid/graphics/Paint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Landroid/text/SpannableString;
 HSPLandroid/graphics/Paint;->getTextBounds(Ljava/lang/String;IILandroid/graphics/Rect;)V
 HSPLandroid/graphics/Paint;->getTextBounds([CIILandroid/graphics/Rect;)V
 HSPLandroid/graphics/Paint;->getTextLocale()Ljava/util/Locale;
@@ -6504,7 +6532,7 @@
 HSPLandroid/graphics/Paint;->setPathEffect(Landroid/graphics/PathEffect;)Landroid/graphics/PathEffect;
 HSPLandroid/graphics/Paint;->setShader(Landroid/graphics/Shader;)Landroid/graphics/Shader;
 HSPLandroid/graphics/Paint;->setShadowLayer(FFFI)V
-HSPLandroid/graphics/Paint;->setShadowLayer(FFFJ)V+]Landroid/graphics/ColorSpace;Landroid/graphics/ColorSpace$Rgb;
+HSPLandroid/graphics/Paint;->setShadowLayer(FFFJ)V
 HSPLandroid/graphics/Paint;->setStartHyphenEdit(I)V
 HSPLandroid/graphics/Paint;->setStrokeCap(Landroid/graphics/Paint$Cap;)V
 HSPLandroid/graphics/Paint;->setStrokeJoin(Landroid/graphics/Paint$Join;)V
@@ -6519,9 +6547,9 @@
 HSPLandroid/graphics/Paint;->setTypeface(Landroid/graphics/Typeface;)Landroid/graphics/Typeface;
 HSPLandroid/graphics/Paint;->setUnderlineText(Z)V
 HSPLandroid/graphics/Paint;->setXfermode(Landroid/graphics/Xfermode;)Landroid/graphics/Xfermode;
-HSPLandroid/graphics/Paint;->syncTextLocalesWithMinikin()V+]Landroid/os/LocaleList;Landroid/os/LocaleList;]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/graphics/Paint;->syncTextLocalesWithMinikin()V+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Integer;Ljava/lang/Integer;]Landroid/os/LocaleList;Landroid/os/LocaleList;
 HSPLandroid/graphics/PaintFlagsDrawFilter;-><init>(II)V
-HSPLandroid/graphics/Path;-><init>()V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/Path;-><init>()V
 HSPLandroid/graphics/Path;-><init>(Landroid/graphics/Path;)V
 HSPLandroid/graphics/Path;->addArc(FFFFFF)V
 HSPLandroid/graphics/Path;->addArc(Landroid/graphics/RectF;FF)V
@@ -6530,7 +6558,7 @@
 HSPLandroid/graphics/Path;->addOval(Landroid/graphics/RectF;Landroid/graphics/Path$Direction;)V
 HSPLandroid/graphics/Path;->addPath(Landroid/graphics/Path;Landroid/graphics/Matrix;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
 HSPLandroid/graphics/Path;->addRect(FFFFLandroid/graphics/Path$Direction;)V
-HSPLandroid/graphics/Path;->addRect(Landroid/graphics/RectF;Landroid/graphics/Path$Direction;)V+]Landroid/graphics/Path;Landroid/graphics/Path;
+HSPLandroid/graphics/Path;->addRect(Landroid/graphics/RectF;Landroid/graphics/Path$Direction;)V
 HSPLandroid/graphics/Path;->addRoundRect(FFFFFFLandroid/graphics/Path$Direction;)V
 HSPLandroid/graphics/Path;->addRoundRect(FFFF[FLandroid/graphics/Path$Direction;)V
 HSPLandroid/graphics/Path;->addRoundRect(Landroid/graphics/RectF;FFLandroid/graphics/Path$Direction;)V
@@ -6548,8 +6576,8 @@
 HSPLandroid/graphics/Path;->lineTo(FF)V
 HSPLandroid/graphics/Path;->moveTo(FF)V
 HSPLandroid/graphics/Path;->offset(FF)V
-HSPLandroid/graphics/Path;->op(Landroid/graphics/Path;Landroid/graphics/Path$Op;)Z+]Landroid/graphics/Path;Landroid/graphics/Path;
-HSPLandroid/graphics/Path;->op(Landroid/graphics/Path;Landroid/graphics/Path;Landroid/graphics/Path$Op;)Z+]Landroid/graphics/Path$Op;Landroid/graphics/Path$Op;
+HSPLandroid/graphics/Path;->op(Landroid/graphics/Path;Landroid/graphics/Path$Op;)Z
+HSPLandroid/graphics/Path;->op(Landroid/graphics/Path;Landroid/graphics/Path;Landroid/graphics/Path$Op;)Z
 HSPLandroid/graphics/Path;->rLineTo(FF)V
 HSPLandroid/graphics/Path;->readOnlyNI()J
 HSPLandroid/graphics/Path;->reset()V+]Landroid/graphics/Path;Landroid/graphics/Path;
@@ -6589,7 +6617,7 @@
 HSPLandroid/graphics/PointF;-><init>()V
 HSPLandroid/graphics/PointF;-><init>(FF)V
 HSPLandroid/graphics/PointF;->equals(FF)Z
-HSPLandroid/graphics/PointF;->equals(Ljava/lang/Object;)Z+]Ljava/lang/Object;Landroid/graphics/PointF;
+HSPLandroid/graphics/PointF;->equals(Ljava/lang/Object;)Z
 HSPLandroid/graphics/PointF;->length()F
 HSPLandroid/graphics/PointF;->length(FF)F
 HSPLandroid/graphics/PointF;->set(FF)V
@@ -6616,8 +6644,8 @@
 HSPLandroid/graphics/RecordingCanvas;->obtain(Landroid/graphics/RenderNode;II)Landroid/graphics/RecordingCanvas;+]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
 HSPLandroid/graphics/RecordingCanvas;->recycle()V+]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
 HSPLandroid/graphics/RecordingCanvas;->throwIfCannotDraw(Landroid/graphics/Bitmap;)V
-HSPLandroid/graphics/Rect$1;->createFromParcel(Landroid/os/Parcel;)Landroid/graphics/Rect;+]Landroid/graphics/Rect;Landroid/graphics/Rect;
-HSPLandroid/graphics/Rect$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/graphics/Rect$1;Landroid/graphics/Rect$1;
+HSPLandroid/graphics/Rect$1;->createFromParcel(Landroid/os/Parcel;)Landroid/graphics/Rect;
+HSPLandroid/graphics/Rect$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/graphics/Rect$1;->newArray(I)[Landroid/graphics/Rect;
 HSPLandroid/graphics/Rect$1;->newArray(I)[Ljava/lang/Object;
 HSPLandroid/graphics/Rect;-><init>()V
@@ -6644,7 +6672,7 @@
 HSPLandroid/graphics/Rect;->isValid()Z
 HSPLandroid/graphics/Rect;->offset(II)V
 HSPLandroid/graphics/Rect;->offsetTo(II)V
-HSPLandroid/graphics/Rect;->readFromParcel(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/graphics/Rect;->readFromParcel(Landroid/os/Parcel;)V
 HSPLandroid/graphics/Rect;->scale(F)V
 HSPLandroid/graphics/Rect;->set(IIII)V
 HSPLandroid/graphics/Rect;->set(Landroid/graphics/Rect;)V
@@ -6653,7 +6681,7 @@
 HSPLandroid/graphics/Rect;->toShortString(Ljava/lang/StringBuilder;)Ljava/lang/String;
 HSPLandroid/graphics/Rect;->toString()Ljava/lang/String;
 HSPLandroid/graphics/Rect;->union(IIII)V
-HSPLandroid/graphics/Rect;->union(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/graphics/Rect;->union(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/Rect;->width()I
 HSPLandroid/graphics/Rect;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/graphics/RectF;-><init>()V
@@ -6707,7 +6735,7 @@
 HSPLandroid/graphics/RenderNode$PositionUpdateListener;->callPositionChanged(Ljava/lang/ref/WeakReference;JIIII)Z
 HSPLandroid/graphics/RenderNode$PositionUpdateListener;->callPositionLost(Ljava/lang/ref/WeakReference;J)Z
 HSPLandroid/graphics/RenderNode;-><init>(J)V
-HSPLandroid/graphics/RenderNode;-><init>(Ljava/lang/String;Landroid/graphics/RenderNode$AnimationHost;)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/RenderNode;-><init>(Ljava/lang/String;Landroid/graphics/RenderNode$AnimationHost;)V
 HSPLandroid/graphics/RenderNode;->addPositionUpdateListener(Landroid/graphics/RenderNode$PositionUpdateListener;)V
 HSPLandroid/graphics/RenderNode;->adopt(J)Landroid/graphics/RenderNode;
 HSPLandroid/graphics/RenderNode;->beginRecording(II)Landroid/graphics/RecordingCanvas;
@@ -6717,7 +6745,7 @@
 HSPLandroid/graphics/RenderNode;->endRecording()V+]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/graphics/RenderNode;->getClipToOutline()Z
 HSPLandroid/graphics/RenderNode;->getElevation()F
-HSPLandroid/graphics/RenderNode;->getMatrix(Landroid/graphics/Matrix;)V
+HSPLandroid/graphics/RenderNode;->getMatrix(Landroid/graphics/Matrix;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
 HSPLandroid/graphics/RenderNode;->getPivotY()F
 HSPLandroid/graphics/RenderNode;->getRotationX()F
 HSPLandroid/graphics/RenderNode;->getRotationY()F
@@ -6734,7 +6762,7 @@
 HSPLandroid/graphics/RenderNode;->removePositionUpdateListener(Landroid/graphics/RenderNode$PositionUpdateListener;)V
 HSPLandroid/graphics/RenderNode;->setAlpha(F)Z
 HSPLandroid/graphics/RenderNode;->setAmbientShadowColor(I)Z
-HSPLandroid/graphics/RenderNode;->setAnimationMatrix(Landroid/graphics/Matrix;)Z+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
+HSPLandroid/graphics/RenderNode;->setAnimationMatrix(Landroid/graphics/Matrix;)Z
 HSPLandroid/graphics/RenderNode;->setClipToBounds(Z)Z
 HSPLandroid/graphics/RenderNode;->setClipToOutline(Z)Z
 HSPLandroid/graphics/RenderNode;->setElevation(F)Z
@@ -6771,7 +6799,7 @@
 HSPLandroid/graphics/Shader;->discardNativeInstance()V
 HSPLandroid/graphics/Shader;->discardNativeInstanceLocked()V
 HSPLandroid/graphics/Shader;->getNativeInstance()J
-HSPLandroid/graphics/Shader;->getNativeInstance(Z)J+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/Shader;Landroid/graphics/BitmapShader;,Landroid/graphics/LinearGradient;,Landroid/graphics/drawable/RippleShader;]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/Shader;->getNativeInstance(Z)J
 HSPLandroid/graphics/Shader;->setLocalMatrix(Landroid/graphics/Matrix;)V
 HSPLandroid/graphics/Shader;->shouldDiscardNativeInstance(Z)Z
 HSPLandroid/graphics/SurfaceTexture$1;->handleMessage(Landroid/os/Message;)V
@@ -6789,7 +6817,7 @@
 HSPLandroid/graphics/TextureLayer;->close()V
 HSPLandroid/graphics/TextureLayer;->detachSurfaceTexture()V
 HSPLandroid/graphics/Typeface$Builder;->build()Landroid/graphics/Typeface;
-HSPLandroid/graphics/Typeface$Builder;->createAssetUid(Landroid/content/res/AssetManager;Ljava/lang/String;I[Landroid/graphics/fonts/FontVariationAxis;IILjava/lang/String;)Ljava/lang/String;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/graphics/Typeface$Builder;->createAssetUid(Landroid/content/res/AssetManager;Ljava/lang/String;I[Landroid/graphics/fonts/FontVariationAxis;IILjava/lang/String;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
 HSPLandroid/graphics/Typeface$CustomFallbackBuilder;-><init>(Landroid/graphics/fonts/FontFamily;)V
 HSPLandroid/graphics/Typeface$CustomFallbackBuilder;->build()Landroid/graphics/Typeface;
 HSPLandroid/graphics/Typeface$CustomFallbackBuilder;->setStyle(Landroid/graphics/fonts/FontStyle;)Landroid/graphics/Typeface$CustomFallbackBuilder;
@@ -6803,9 +6831,9 @@
 HSPLandroid/graphics/Typeface;->defaultFromStyle(I)Landroid/graphics/Typeface;
 HSPLandroid/graphics/Typeface;->deserializeFontMap(Ljava/nio/ByteBuffer;Ljava/util/Map;)[J
 HSPLandroid/graphics/Typeface;->equals(Ljava/lang/Object;)Z
-HSPLandroid/graphics/Typeface;->findFromCache(Landroid/content/res/AssetManager;Ljava/lang/String;)Landroid/graphics/Typeface;+]Landroid/util/LruCache;Landroid/util/LruCache;
+HSPLandroid/graphics/Typeface;->findFromCache(Landroid/content/res/AssetManager;Ljava/lang/String;)Landroid/graphics/Typeface;
 HSPLandroid/graphics/Typeface;->getStyle()I
-HSPLandroid/graphics/Typeface;->getSystemDefaultTypeface(Ljava/lang/String;)Landroid/graphics/Typeface;+]Ljava/util/Map;Landroid/util/ArrayMap;
+HSPLandroid/graphics/Typeface;->getSystemDefaultTypeface(Ljava/lang/String;)Landroid/graphics/Typeface;
 HSPLandroid/graphics/Typeface;->getSystemFontFamilyName()Ljava/lang/String;
 HSPLandroid/graphics/Typeface;->hasFontFamily(Ljava/lang/String;)Z
 HSPLandroid/graphics/Typeface;->readString(Ljava/nio/ByteBuffer;)Ljava/lang/String;
@@ -6914,7 +6942,7 @@
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable$2;->onAnimationStart(Landroid/animation/Animator;)V
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState$PendingAnimator;-><init>(IFLjava/lang/String;)V
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState$PendingAnimator;->newInstance(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;)Landroid/animation/Animator;
-HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;-><init>(Landroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;Landroid/graphics/drawable/Drawable$Callback;Landroid/content/res/Resources;)V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;-><init>(Landroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;Landroid/graphics/drawable/Drawable$Callback;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/Drawable$ConstantState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;->addPendingAnimator(IFLjava/lang/String;)V
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;->addTargetAnimator(Ljava/lang/String;Landroid/animation/Animator;)V
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;->canApplyTheme()Z
@@ -7068,7 +7096,7 @@
 HSPLandroid/graphics/drawable/ColorDrawable;-><init>(Landroid/graphics/drawable/ColorDrawable$ColorState;Landroid/content/res/Resources;Landroid/graphics/drawable/ColorDrawable-IA;)V
 HSPLandroid/graphics/drawable/ColorDrawable;->canApplyTheme()Z
 HSPLandroid/graphics/drawable/ColorDrawable;->clearMutated()V
-HSPLandroid/graphics/drawable/ColorDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/drawable/ColorDrawable;Landroid/graphics/drawable/ColorDrawable;
+HSPLandroid/graphics/drawable/ColorDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/drawable/ColorDrawable;Landroid/graphics/drawable/ColorDrawable;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/graphics/drawable/ColorDrawable;->getAlpha()I
 HSPLandroid/graphics/drawable/ColorDrawable;->getChangingConfigurations()I
 HSPLandroid/graphics/drawable/ColorDrawable;->getColor()I
@@ -7083,7 +7111,7 @@
 HSPLandroid/graphics/drawable/ColorDrawable;->setColor(I)V
 HSPLandroid/graphics/drawable/ColorDrawable;->setColorFilter(Landroid/graphics/ColorFilter;)V
 HSPLandroid/graphics/drawable/ColorDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
-HSPLandroid/graphics/drawable/ColorDrawable;->updateLocalState(Landroid/content/res/Resources;)V
+HSPLandroid/graphics/drawable/ColorDrawable;->updateLocalState(Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/ColorDrawable;Landroid/graphics/drawable/ColorDrawable;
 HSPLandroid/graphics/drawable/ColorDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/Drawable$ConstantState;-><init>()V
 HSPLandroid/graphics/drawable/Drawable$ConstantState;->canApplyTheme()Z
@@ -7094,7 +7122,7 @@
 HSPLandroid/graphics/drawable/Drawable;->canApplyTheme()Z
 HSPLandroid/graphics/drawable/Drawable;->clearColorFilter()V
 HSPLandroid/graphics/drawable/Drawable;->clearMutated()V
-HSPLandroid/graphics/drawable/Drawable;->copyBounds(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/graphics/drawable/Drawable;->copyBounds(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/drawable/Drawable;->createFromXmlForDensity(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;ILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/Drawable;->createFromXmlInner(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/Drawable;->createFromXmlInnerForDensity(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;ILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
@@ -7110,7 +7138,7 @@
 HSPLandroid/graphics/drawable/Drawable;->getLayoutDirection()I
 HSPLandroid/graphics/drawable/Drawable;->getLevel()I
 HSPLandroid/graphics/drawable/Drawable;->getMinimumHeight()I+]Landroid/graphics/drawable/Drawable;missing_types
-HSPLandroid/graphics/drawable/Drawable;->getMinimumWidth()I+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/ColorDrawable;,Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/graphics/drawable/Drawable;->getMinimumWidth()I+]Landroid/graphics/drawable/Drawable;missing_types
 HSPLandroid/graphics/drawable/Drawable;->getOutline(Landroid/graphics/Outline;)V
 HSPLandroid/graphics/drawable/Drawable;->getPadding(Landroid/graphics/Rect;)Z
 HSPLandroid/graphics/drawable/Drawable;->getState()[I
@@ -7127,13 +7155,13 @@
 HSPLandroid/graphics/drawable/Drawable;->onLevelChange(I)Z
 HSPLandroid/graphics/drawable/Drawable;->onStateChange([I)Z
 HSPLandroid/graphics/drawable/Drawable;->parseBlendMode(ILandroid/graphics/BlendMode;)Landroid/graphics/BlendMode;
-HSPLandroid/graphics/drawable/Drawable;->resolveDensity(Landroid/content/res/Resources;I)I+]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/graphics/drawable/Drawable;->resolveDensity(Landroid/content/res/Resources;I)I
 HSPLandroid/graphics/drawable/Drawable;->resolveOpacity(II)I
 HSPLandroid/graphics/drawable/Drawable;->scaleFromDensity(FII)F
 HSPLandroid/graphics/drawable/Drawable;->scaleFromDensity(IIIZ)I
 HSPLandroid/graphics/drawable/Drawable;->scheduleSelf(Ljava/lang/Runnable;J)V
 HSPLandroid/graphics/drawable/Drawable;->setAutoMirrored(Z)V
-HSPLandroid/graphics/drawable/Drawable;->setBounds(IIII)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/Drawable;->setBounds(IIII)V
 HSPLandroid/graphics/drawable/Drawable;->setBounds(Landroid/graphics/Rect;)V+]Landroid/graphics/drawable/Drawable;megamorphic_types
 HSPLandroid/graphics/drawable/Drawable;->setCallback(Landroid/graphics/drawable/Drawable$Callback;)V
 HSPLandroid/graphics/drawable/Drawable;->setChangingConfigurations(I)V
@@ -7143,20 +7171,20 @@
 HSPLandroid/graphics/drawable/Drawable;->setLayoutDirection(I)Z
 HSPLandroid/graphics/drawable/Drawable;->setLevel(I)Z
 HSPLandroid/graphics/drawable/Drawable;->setSrcDensityOverride(I)V
-HSPLandroid/graphics/drawable/Drawable;->setState([I)Z+]Landroid/graphics/drawable/Drawable;megamorphic_types
+HSPLandroid/graphics/drawable/Drawable;->setState([I)Z+]Landroid/graphics/drawable/Drawable;missing_types
 HSPLandroid/graphics/drawable/Drawable;->setTint(I)V
 HSPLandroid/graphics/drawable/Drawable;->setTintList(Landroid/content/res/ColorStateList;)V
 HSPLandroid/graphics/drawable/Drawable;->setTintMode(Landroid/graphics/PorterDuff$Mode;)V
-HSPLandroid/graphics/drawable/Drawable;->setVisible(ZZ)Z+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/Drawable;->setVisible(ZZ)Z
 HSPLandroid/graphics/drawable/Drawable;->unscheduleSelf(Ljava/lang/Runnable;)V
-HSPLandroid/graphics/drawable/Drawable;->updateBlendModeFilter(Landroid/graphics/BlendModeColorFilter;Landroid/content/res/ColorStateList;Landroid/graphics/BlendMode;)Landroid/graphics/BlendModeColorFilter;+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/BlendModeColorFilter;Landroid/graphics/BlendModeColorFilter;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;,Landroid/graphics/drawable/ShapeDrawable;,Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/graphics/drawable/Drawable;->updateBlendModeFilter(Landroid/graphics/BlendModeColorFilter;Landroid/content/res/ColorStateList;Landroid/graphics/BlendMode;)Landroid/graphics/BlendModeColorFilter;+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/BlendModeColorFilter;Landroid/graphics/BlendModeColorFilter;]Landroid/graphics/drawable/Drawable;megamorphic_types
 HSPLandroid/graphics/drawable/Drawable;->updateTintFilter(Landroid/graphics/PorterDuffColorFilter;Landroid/content/res/ColorStateList;Landroid/graphics/PorterDuff$Mode;)Landroid/graphics/PorterDuffColorFilter;
 HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;-><init>()V
 HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;-><init>(Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback-IA;)V
 HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;->unwrap()Landroid/graphics/drawable/Drawable$Callback;
 HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;->wrap(Landroid/graphics/drawable/Drawable$Callback;)Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;
-HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;-><init>(Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;Landroid/graphics/drawable/DrawableContainer;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/Drawable;megamorphic_types]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;-><init>(Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;Landroid/graphics/drawable/DrawableContainer;Landroid/content/res/Resources;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/graphics/drawable/Drawable;megamorphic_types
 HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;->addChild(Landroid/graphics/drawable/Drawable;)I
 HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;->applyTheme(Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;->canApplyTheme()Z
@@ -7199,11 +7227,11 @@
 HSPLandroid/graphics/drawable/DrawableContainer;->getOpticalInsets()Landroid/graphics/Insets;
 HSPLandroid/graphics/drawable/DrawableContainer;->getOutline(Landroid/graphics/Outline;)V
 HSPLandroid/graphics/drawable/DrawableContainer;->getPadding(Landroid/graphics/Rect;)Z
-HSPLandroid/graphics/drawable/DrawableContainer;->initializeDrawableForDisplay(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;]Landroid/graphics/drawable/DrawableContainer;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/StateListDrawable;,Lcom/android/internal/graphics/drawable/AnimationScaleListDrawable;
+HSPLandroid/graphics/drawable/DrawableContainer;->initializeDrawableForDisplay(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;]Landroid/graphics/drawable/DrawableContainer;Landroid/graphics/drawable/AnimatedStateListDrawable;,Lcom/android/internal/graphics/drawable/AnimationScaleListDrawable;,Landroid/graphics/drawable/StateListDrawable;]Landroid/graphics/drawable/Drawable;megamorphic_types
 HSPLandroid/graphics/drawable/DrawableContainer;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/graphics/drawable/DrawableContainer;->isAutoMirrored()Z
 HSPLandroid/graphics/drawable/DrawableContainer;->isStateful()Z
-HSPLandroid/graphics/drawable/DrawableContainer;->jumpToCurrentState()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/DrawableContainer;->jumpToCurrentState()V
 HSPLandroid/graphics/drawable/DrawableContainer;->mutate()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/DrawableContainer;->needsMirroring()Z
 HSPLandroid/graphics/drawable/DrawableContainer;->onBoundsChange(Landroid/graphics/Rect;)V
@@ -7237,27 +7265,27 @@
 HSPLandroid/graphics/drawable/DrawableWrapper;->canApplyTheme()Z
 HSPLandroid/graphics/drawable/DrawableWrapper;->clearMutated()V
 HSPLandroid/graphics/drawable/DrawableWrapper;->draw(Landroid/graphics/Canvas;)V
-HSPLandroid/graphics/drawable/DrawableWrapper;->getChangingConfigurations()I+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;Landroid/graphics/drawable/InsetDrawable$InsetState;
+HSPLandroid/graphics/drawable/DrawableWrapper;->getChangingConfigurations()I
 HSPLandroid/graphics/drawable/DrawableWrapper;->getColorFilter()Landroid/graphics/ColorFilter;
 HSPLandroid/graphics/drawable/DrawableWrapper;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
 HSPLandroid/graphics/drawable/DrawableWrapper;->getDrawable()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/DrawableWrapper;->getIntrinsicHeight()I
 HSPLandroid/graphics/drawable/DrawableWrapper;->getIntrinsicWidth()I
 HSPLandroid/graphics/drawable/DrawableWrapper;->getOpacity()I
-HSPLandroid/graphics/drawable/DrawableWrapper;->getPadding(Landroid/graphics/Rect;)Z+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/DrawableWrapper;->getPadding(Landroid/graphics/Rect;)Z
 HSPLandroid/graphics/drawable/DrawableWrapper;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/DrawableWrapper;->inflateChildDrawable(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
-HSPLandroid/graphics/drawable/DrawableWrapper;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable$Callback;Landroid/graphics/drawable/RippleDrawable;]Landroid/graphics/drawable/DrawableWrapper;Landroid/graphics/drawable/InsetDrawable;
+HSPLandroid/graphics/drawable/DrawableWrapper;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/graphics/drawable/DrawableWrapper;->isStateful()Z
 HSPLandroid/graphics/drawable/DrawableWrapper;->jumpToCurrentState()V
 HSPLandroid/graphics/drawable/DrawableWrapper;->mutate()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/DrawableWrapper;->mutateConstantState()Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;
 HSPLandroid/graphics/drawable/DrawableWrapper;->onBoundsChange(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/drawable/DrawableWrapper;->onLevelChange(I)Z
-HSPLandroid/graphics/drawable/DrawableWrapper;->onStateChange([I)Z+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/DrawableWrapper;missing_types
+HSPLandroid/graphics/drawable/DrawableWrapper;->onStateChange([I)Z
 HSPLandroid/graphics/drawable/DrawableWrapper;->setAlpha(I)V
 HSPLandroid/graphics/drawable/DrawableWrapper;->setColorFilter(Landroid/graphics/ColorFilter;)V
-HSPLandroid/graphics/drawable/DrawableWrapper;->setDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/DrawableWrapper;missing_types
+HSPLandroid/graphics/drawable/DrawableWrapper;->setDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/graphics/drawable/DrawableWrapper;->setHotspot(FF)V
 HSPLandroid/graphics/drawable/DrawableWrapper;->setTintBlendMode(Landroid/graphics/BlendMode;)V
 HSPLandroid/graphics/drawable/DrawableWrapper;->setTintList(Landroid/content/res/ColorStateList;)V
@@ -7266,7 +7294,7 @@
 HSPLandroid/graphics/drawable/DrawableWrapper;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/GradientDrawable$GradientState;->-$$Nest$mcomputeOpacity(Landroid/graphics/drawable/GradientDrawable$GradientState;)V
 HSPLandroid/graphics/drawable/GradientDrawable$GradientState;-><init>(Landroid/graphics/drawable/GradientDrawable$GradientState;Landroid/content/res/Resources;)V
-HSPLandroid/graphics/drawable/GradientDrawable$GradientState;-><init>(Landroid/graphics/drawable/GradientDrawable$Orientation;[I)V
+HSPLandroid/graphics/drawable/GradientDrawable$GradientState;-><init>(Landroid/graphics/drawable/GradientDrawable$Orientation;[I)V+]Landroid/graphics/drawable/GradientDrawable$GradientState;Landroid/graphics/drawable/GradientDrawable$GradientState;
 HSPLandroid/graphics/drawable/GradientDrawable$GradientState;->applyDensityScaling(II)V
 HSPLandroid/graphics/drawable/GradientDrawable$GradientState;->canApplyTheme()Z
 HSPLandroid/graphics/drawable/GradientDrawable$GradientState;->computeOpacity()V
@@ -7287,8 +7315,8 @@
 HSPLandroid/graphics/drawable/GradientDrawable;->applyThemeChildElements(Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/GradientDrawable;->canApplyTheme()Z
 HSPLandroid/graphics/drawable/GradientDrawable;->clearMutated()V
-HSPLandroid/graphics/drawable/GradientDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Paint;Landroid/graphics/Paint;
-HSPLandroid/graphics/drawable/GradientDrawable;->ensureValidRect()Z+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/graphics/drawable/GradientDrawable;Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/graphics/drawable/GradientDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;,Landroid/graphics/Canvas;
+HSPLandroid/graphics/drawable/GradientDrawable;->ensureValidRect()Z
 HSPLandroid/graphics/drawable/GradientDrawable;->getChangingConfigurations()I
 HSPLandroid/graphics/drawable/GradientDrawable;->getColorFilter()Landroid/graphics/ColorFilter;
 HSPLandroid/graphics/drawable/GradientDrawable;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
@@ -7308,7 +7336,7 @@
 HSPLandroid/graphics/drawable/GradientDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/drawable/GradientDrawable;->onLevelChange(I)Z
 HSPLandroid/graphics/drawable/GradientDrawable;->onStateChange([I)Z
-HSPLandroid/graphics/drawable/GradientDrawable;->setAlpha(I)V
+HSPLandroid/graphics/drawable/GradientDrawable;->setAlpha(I)V+]Landroid/graphics/drawable/GradientDrawable;Landroid/graphics/drawable/GradientDrawable;
 HSPLandroid/graphics/drawable/GradientDrawable;->setColor(I)V
 HSPLandroid/graphics/drawable/GradientDrawable;->setColor(Landroid/content/res/ColorStateList;)V
 HSPLandroid/graphics/drawable/GradientDrawable;->setColorFilter(Landroid/graphics/ColorFilter;)V
@@ -7329,7 +7357,7 @@
 HSPLandroid/graphics/drawable/GradientDrawable;->updateGradientDrawableSize(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/GradientDrawable;->updateGradientDrawableSolid(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/GradientDrawable;->updateGradientDrawableStroke(Landroid/content/res/TypedArray;)V
-HSPLandroid/graphics/drawable/GradientDrawable;->updateLocalState(Landroid/content/res/Resources;)V+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/drawable/GradientDrawable;Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/graphics/drawable/GradientDrawable;->updateLocalState(Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/GradientDrawable;Landroid/graphics/drawable/GradientDrawable;]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/Paint;Landroid/graphics/Paint;
 HSPLandroid/graphics/drawable/GradientDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/Icon$1;->createFromParcel(Landroid/os/Parcel;)Landroid/graphics/drawable/Icon;
 HSPLandroid/graphics/drawable/Icon$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -7354,7 +7382,7 @@
 HSPLandroid/graphics/drawable/Icon;->setTint(I)Landroid/graphics/drawable/Icon;
 HSPLandroid/graphics/drawable/Icon;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/graphics/drawable/InsetDrawable$InsetState;->-$$Nest$fputmThemeAttrs(Landroid/graphics/drawable/InsetDrawable$InsetState;[I)V
-HSPLandroid/graphics/drawable/InsetDrawable$InsetState;-><init>(Landroid/graphics/drawable/InsetDrawable$InsetState;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/InsetDrawable$InsetValue;Landroid/graphics/drawable/InsetDrawable$InsetValue;
+HSPLandroid/graphics/drawable/InsetDrawable$InsetState;-><init>(Landroid/graphics/drawable/InsetDrawable$InsetState;Landroid/content/res/Resources;)V
 HSPLandroid/graphics/drawable/InsetDrawable$InsetState;->applyDensityScaling(II)V
 HSPLandroid/graphics/drawable/InsetDrawable$InsetState;->newDrawable(Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/InsetDrawable$InsetState;->onDensityChanged(II)V
@@ -7370,19 +7398,19 @@
 HSPLandroid/graphics/drawable/InsetDrawable;-><init>(Landroid/graphics/drawable/InsetDrawable$InsetState;Landroid/content/res/Resources;Landroid/graphics/drawable/InsetDrawable-IA;)V
 HSPLandroid/graphics/drawable/InsetDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/InsetDrawable;->getInset(Landroid/content/res/TypedArray;ILandroid/graphics/drawable/InsetDrawable$InsetValue;)Landroid/graphics/drawable/InsetDrawable$InsetValue;
-HSPLandroid/graphics/drawable/InsetDrawable;->getInsets(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/InsetDrawable$InsetValue;Landroid/graphics/drawable/InsetDrawable$InsetValue;]Landroid/graphics/drawable/InsetDrawable;missing_types
-HSPLandroid/graphics/drawable/InsetDrawable;->getIntrinsicHeight()I+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/InsetDrawable;missing_types
-HSPLandroid/graphics/drawable/InsetDrawable;->getIntrinsicWidth()I+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/InsetDrawable;missing_types
+HSPLandroid/graphics/drawable/InsetDrawable;->getInsets(Landroid/graphics/Rect;)V+]Landroid/graphics/drawable/InsetDrawable;Landroid/graphics/drawable/InsetDrawable;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/InsetDrawable$InsetValue;Landroid/graphics/drawable/InsetDrawable$InsetValue;
+HSPLandroid/graphics/drawable/InsetDrawable;->getIntrinsicHeight()I
+HSPLandroid/graphics/drawable/InsetDrawable;->getIntrinsicWidth()I
 HSPLandroid/graphics/drawable/InsetDrawable;->getOpacity()I
-HSPLandroid/graphics/drawable/InsetDrawable;->getOutline(Landroid/graphics/Outline;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/InsetDrawable;missing_types
+HSPLandroid/graphics/drawable/InsetDrawable;->getOutline(Landroid/graphics/Outline;)V
 HSPLandroid/graphics/drawable/InsetDrawable;->getPadding(Landroid/graphics/Rect;)Z
 HSPLandroid/graphics/drawable/InsetDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/InsetDrawable;->mutateConstantState()Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;
-HSPLandroid/graphics/drawable/InsetDrawable;->onBoundsChange(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/InsetDrawable$InsetValue;Landroid/graphics/drawable/InsetDrawable$InsetValue;
+HSPLandroid/graphics/drawable/InsetDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/drawable/InsetDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/InsetDrawable;->verifyRequiredAttributes(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;-><init>(I)V
-HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;-><init>(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;Landroid/graphics/drawable/LayerDrawable;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/Drawable$ConstantState;megamorphic_types]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;-><init>(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;Landroid/graphics/drawable/LayerDrawable;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/Drawable$ConstantState;missing_types]Landroid/graphics/drawable/Drawable;missing_types
 HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;->applyDensityScaling(II)V
 HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;->canApplyTheme()Z
 HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;->setDensity(I)V
@@ -7402,11 +7430,11 @@
 HSPLandroid/graphics/drawable/LayerDrawable$LayerState;->onDensityChanged(II)V
 HSPLandroid/graphics/drawable/LayerDrawable$LayerState;->setDensity(I)V
 HSPLandroid/graphics/drawable/LayerDrawable;-><init>()V
-HSPLandroid/graphics/drawable/LayerDrawable;-><init>(Landroid/graphics/drawable/LayerDrawable$LayerState;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/LayerDrawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;-><init>(Landroid/graphics/drawable/LayerDrawable$LayerState;Landroid/content/res/Resources;)V
 HSPLandroid/graphics/drawable/LayerDrawable;-><init>([Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/graphics/drawable/LayerDrawable;-><init>([Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/LayerDrawable$LayerState;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->addLayer(Landroid/graphics/drawable/Drawable;[IIIIII)Landroid/graphics/drawable/LayerDrawable$ChildDrawable;+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/LayerDrawable;missing_types
-HSPLandroid/graphics/drawable/LayerDrawable;->addLayer(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;)I+]Landroid/graphics/drawable/LayerDrawable$LayerState;Landroid/graphics/drawable/RippleDrawable$RippleState;
+HSPLandroid/graphics/drawable/LayerDrawable;->addLayer(Landroid/graphics/drawable/Drawable;[IIIIII)Landroid/graphics/drawable/LayerDrawable$ChildDrawable;
+HSPLandroid/graphics/drawable/LayerDrawable;->addLayer(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;)I
 HSPLandroid/graphics/drawable/LayerDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/LayerDrawable;->canApplyTheme()Z
 HSPLandroid/graphics/drawable/LayerDrawable;->clearMutated()V
@@ -7420,23 +7448,23 @@
 HSPLandroid/graphics/drawable/LayerDrawable;->getChangingConfigurations()I
 HSPLandroid/graphics/drawable/LayerDrawable;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
 HSPLandroid/graphics/drawable/LayerDrawable;->getDrawable(I)Landroid/graphics/drawable/Drawable;
-HSPLandroid/graphics/drawable/LayerDrawable;->getIntrinsicHeight()I+]Landroid/graphics/drawable/Drawable;missing_types
-HSPLandroid/graphics/drawable/LayerDrawable;->getIntrinsicWidth()I+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/LayerDrawable;Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/LayerDrawable;->getIntrinsicHeight()I
+HSPLandroid/graphics/drawable/LayerDrawable;->getIntrinsicWidth()I
 HSPLandroid/graphics/drawable/LayerDrawable;->getNumberOfLayers()I
 HSPLandroid/graphics/drawable/LayerDrawable;->getOpacity()I
-HSPLandroid/graphics/drawable/LayerDrawable;->getOutline(Landroid/graphics/Outline;)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;
-HSPLandroid/graphics/drawable/LayerDrawable;->getPadding(Landroid/graphics/Rect;)Z+]Landroid/graphics/drawable/LayerDrawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->getOutline(Landroid/graphics/Outline;)V
+HSPLandroid/graphics/drawable/LayerDrawable;->getPadding(Landroid/graphics/Rect;)Z
 HSPLandroid/graphics/drawable/LayerDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/LayerDrawable;->inflateLayers(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/LayerDrawable$LayerState;Landroid/graphics/drawable/LayerDrawable$LayerState;,Landroid/graphics/drawable/RippleDrawable$RippleState;]Landroid/graphics/drawable/LayerDrawable;Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/LayerDrawable;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/graphics/drawable/LayerDrawable;->isAutoMirrored()Z
 HSPLandroid/graphics/drawable/LayerDrawable;->isProjected()Z
 HSPLandroid/graphics/drawable/LayerDrawable;->isStateful()Z
-HSPLandroid/graphics/drawable/LayerDrawable;->jumpToCurrentState()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->jumpToCurrentState()V
 HSPLandroid/graphics/drawable/LayerDrawable;->mutate()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/LayerDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->onStateChange([I)Z+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/LayerDrawable;Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;
-HSPLandroid/graphics/drawable/LayerDrawable;->refreshChildPadding(ILandroid/graphics/drawable/LayerDrawable$ChildDrawable;)Z+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->onStateChange([I)Z
+HSPLandroid/graphics/drawable/LayerDrawable;->refreshChildPadding(ILandroid/graphics/drawable/LayerDrawable$ChildDrawable;)Z
 HSPLandroid/graphics/drawable/LayerDrawable;->refreshPadding()V
 HSPLandroid/graphics/drawable/LayerDrawable;->resolveGravity(IIIII)I
 HSPLandroid/graphics/drawable/LayerDrawable;->resumeChildInvalidation()V
@@ -7452,10 +7480,10 @@
 HSPLandroid/graphics/drawable/LayerDrawable;->setPaddingMode(I)V
 HSPLandroid/graphics/drawable/LayerDrawable;->setTintBlendMode(Landroid/graphics/BlendMode;)V
 HSPLandroid/graphics/drawable/LayerDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->setVisible(ZZ)Z+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->setVisible(ZZ)Z
 HSPLandroid/graphics/drawable/LayerDrawable;->suspendChildInvalidation()V
 HSPLandroid/graphics/drawable/LayerDrawable;->updateLayerBounds(Landroid/graphics/Rect;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->updateLayerBoundsInternal(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/LayerDrawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->updateLayerBoundsInternal(Landroid/graphics/Rect;)V+]Landroid/graphics/drawable/LayerDrawable;Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;missing_types
 HSPLandroid/graphics/drawable/LayerDrawable;->updateLayerFromTypedArray(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/LayerDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/NinePatchDrawable$$ExternalSyntheticLambda0;->onHeaderDecoded(Landroid/graphics/ImageDecoder;Landroid/graphics/ImageDecoder$ImageInfo;Landroid/graphics/ImageDecoder$Source;)V
@@ -7552,12 +7580,12 @@
 HSPLandroid/graphics/drawable/RippleDrawable$RippleState;->newDrawable(Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/RippleDrawable$RippleState;->onDensityChanged(II)V
 HSPLandroid/graphics/drawable/RippleDrawable;-><init>()V
-HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/content/res/ColorStateList;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/RippleDrawable;missing_types
-HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/graphics/drawable/RippleDrawable$RippleState;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/content/res/ColorStateList;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/graphics/drawable/RippleDrawable$RippleState;Landroid/content/res/Resources;)V
 HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/graphics/drawable/RippleDrawable$RippleState;Landroid/content/res/Resources;Landroid/graphics/drawable/RippleDrawable-IA;)V
 HSPLandroid/graphics/drawable/RippleDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/RippleDrawable;->canApplyTheme()Z
-HSPLandroid/graphics/drawable/RippleDrawable;->cancelExitingRipples()V+]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/RippleDrawable;->cancelExitingRipples()V
 HSPLandroid/graphics/drawable/RippleDrawable;->clearHotspots()V
 HSPLandroid/graphics/drawable/RippleDrawable;->computeRadius()F
 HSPLandroid/graphics/drawable/RippleDrawable;->createAnimationProperties(FFFFFF)Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;
@@ -7566,27 +7594,27 @@
 HSPLandroid/graphics/drawable/RippleDrawable;->draw(Landroid/graphics/Canvas;)V
 HSPLandroid/graphics/drawable/RippleDrawable;->drawBackgroundAndRipples(Landroid/graphics/Canvas;)V
 HSPLandroid/graphics/drawable/RippleDrawable;->drawContent(Landroid/graphics/Canvas;)V
-HSPLandroid/graphics/drawable/RippleDrawable;->drawPatterned(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;]Landroid/graphics/drawable/RippleAnimationSession;Landroid/graphics/drawable/RippleAnimationSession;]Landroid/graphics/drawable/RippleDrawable;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/RippleDrawable;->drawPatterned(Landroid/graphics/Canvas;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/RippleAnimationSession;Landroid/graphics/drawable/RippleAnimationSession;
 HSPLandroid/graphics/drawable/RippleDrawable;->drawPatternedBackground(Landroid/graphics/Canvas;FF)V
 HSPLandroid/graphics/drawable/RippleDrawable;->exitPatternedAnimation()V
-HSPLandroid/graphics/drawable/RippleDrawable;->exitPatternedBackgroundAnimation()V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/graphics/drawable/RippleDrawable;missing_types
+HSPLandroid/graphics/drawable/RippleDrawable;->exitPatternedBackgroundAnimation()V
 HSPLandroid/graphics/drawable/RippleDrawable;->getComputedRadius()I
 HSPLandroid/graphics/drawable/RippleDrawable;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
-HSPLandroid/graphics/drawable/RippleDrawable;->getDirtyBounds()Landroid/graphics/Rect;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleDrawable;missing_types
+HSPLandroid/graphics/drawable/RippleDrawable;->getDirtyBounds()Landroid/graphics/Rect;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
 HSPLandroid/graphics/drawable/RippleDrawable;->getMaskType()I
 HSPLandroid/graphics/drawable/RippleDrawable;->getOpacity()I
 HSPLandroid/graphics/drawable/RippleDrawable;->getOutline(Landroid/graphics/Outline;)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/InsetDrawable;,Landroid/graphics/drawable/StateListDrawable;
 HSPLandroid/graphics/drawable/RippleDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
-HSPLandroid/graphics/drawable/RippleDrawable;->invalidateSelf()V+]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/RippleDrawable;->invalidateSelf()V
 HSPLandroid/graphics/drawable/RippleDrawable;->invalidateSelf(Z)V
-HSPLandroid/graphics/drawable/RippleDrawable;->isBounded()Z+]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/RippleDrawable;->isBounded()Z
 HSPLandroid/graphics/drawable/RippleDrawable;->isProjected()Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
 HSPLandroid/graphics/drawable/RippleDrawable;->isStateful()Z
 HSPLandroid/graphics/drawable/RippleDrawable;->jumpToCurrentState()V
 HSPLandroid/graphics/drawable/RippleDrawable;->mutate()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/RippleDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/drawable/RippleDrawable;->onHotspotBoundsChanged()V
-HSPLandroid/graphics/drawable/RippleDrawable;->onStateChange([I)Z+]Landroid/graphics/drawable/RippleDrawable;missing_types
+HSPLandroid/graphics/drawable/RippleDrawable;->onStateChange([I)Z
 HSPLandroid/graphics/drawable/RippleDrawable;->pruneRipples()V
 HSPLandroid/graphics/drawable/RippleDrawable;->setBackgroundActive(ZZZZ)V
 HSPLandroid/graphics/drawable/RippleDrawable;->setColor(Landroid/content/res/ColorStateList;)V
@@ -7595,11 +7623,11 @@
 HSPLandroid/graphics/drawable/RippleDrawable;->setPaddingMode(I)V
 HSPLandroid/graphics/drawable/RippleDrawable;->setRippleActive(Z)V
 HSPLandroid/graphics/drawable/RippleDrawable;->setVisible(ZZ)Z
-HSPLandroid/graphics/drawable/RippleDrawable;->startBackgroundAnimation()V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
+HSPLandroid/graphics/drawable/RippleDrawable;->startBackgroundAnimation()V
 HSPLandroid/graphics/drawable/RippleDrawable;->tryRippleEnter()V
 HSPLandroid/graphics/drawable/RippleDrawable;->updateLocalState()V
 HSPLandroid/graphics/drawable/RippleDrawable;->updateMaskShaderIfNeeded()V
-HSPLandroid/graphics/drawable/RippleDrawable;->updateRipplePaint()Landroid/graphics/Paint;+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/BitmapShader;Landroid/graphics/BitmapShader;]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/PorterDuffColorFilter;Landroid/graphics/PorterDuffColorFilter;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;]Landroid/graphics/drawable/RippleAnimationSession;Landroid/graphics/drawable/RippleAnimationSession;]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;]Landroid/graphics/drawable/RippleShader;Landroid/graphics/drawable/RippleShader;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/RippleDrawable;->updateRipplePaint()Landroid/graphics/Paint;
 HSPLandroid/graphics/drawable/RippleDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/RippleDrawable;->verifyRequiredAttributes(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/RippleForeground$1;->onAnimationEnd(Landroid/animation/Animator;)V
@@ -7659,7 +7687,7 @@
 HSPLandroid/graphics/drawable/ScaleDrawable;->getPercent(Landroid/content/res/TypedArray;IF)F
 HSPLandroid/graphics/drawable/ScaleDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/ScaleDrawable;->mutateConstantState()Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;
-HSPLandroid/graphics/drawable/ScaleDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
+HSPLandroid/graphics/drawable/ScaleDrawable;->onBoundsChange(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/ScaleDrawable;Landroid/graphics/drawable/ScaleDrawable;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/StateListDrawable;
 HSPLandroid/graphics/drawable/ScaleDrawable;->onLevelChange(I)Z
 HSPLandroid/graphics/drawable/ScaleDrawable;->updateLocalState()V
 HSPLandroid/graphics/drawable/ScaleDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
@@ -7677,7 +7705,7 @@
 HSPLandroid/graphics/drawable/ShapeDrawable;->getOutline(Landroid/graphics/Outline;)V
 HSPLandroid/graphics/drawable/ShapeDrawable;->getPadding(Landroid/graphics/Rect;)Z
 HSPLandroid/graphics/drawable/ShapeDrawable;->getPaint()Landroid/graphics/Paint;
-HSPLandroid/graphics/drawable/ShapeDrawable;->isStateful()Z+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;
+HSPLandroid/graphics/drawable/ShapeDrawable;->isStateful()Z
 HSPLandroid/graphics/drawable/ShapeDrawable;->mutate()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/ShapeDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/drawable/ShapeDrawable;->onDraw(Landroid/graphics/drawable/shapes/Shape;Landroid/graphics/Canvas;Landroid/graphics/Paint;)V
@@ -7687,7 +7715,7 @@
 HSPLandroid/graphics/drawable/ShapeDrawable;->setShape(Landroid/graphics/drawable/shapes/Shape;)V
 HSPLandroid/graphics/drawable/ShapeDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
 HSPLandroid/graphics/drawable/ShapeDrawable;->updateLocalState()V
-HSPLandroid/graphics/drawable/ShapeDrawable;->updateShape()V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/ShapeDrawable;Landroid/graphics/drawable/PaintDrawable;]Landroid/graphics/drawable/shapes/Shape;Landroid/graphics/drawable/shapes/OvalShape;,Landroid/graphics/drawable/shapes/RoundRectShape;
+HSPLandroid/graphics/drawable/ShapeDrawable;->updateShape()V
 HSPLandroid/graphics/drawable/StateListDrawable$StateListState;-><init>(Landroid/graphics/drawable/StateListDrawable$StateListState;Landroid/graphics/drawable/StateListDrawable;Landroid/content/res/Resources;)V
 HSPLandroid/graphics/drawable/StateListDrawable$StateListState;->addStateSet([ILandroid/graphics/drawable/Drawable;)I
 HSPLandroid/graphics/drawable/StateListDrawable$StateListState;->canApplyTheme()Z
@@ -7736,23 +7764,23 @@
 HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->getPropertyIndex(Ljava/lang/String;)I
 HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->inflate(Landroid/content/res/Resources;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->isStateful()Z
-HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->onStateChange([I)Z+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/drawable/VectorDrawable$VFullPath;Landroid/graphics/drawable/VectorDrawable$VFullPath;
-HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V+]Landroid/content/res/ComplexColor;Landroid/content/res/ColorStateList;,Landroid/content/res/GradientColor;]Landroid/content/res/GradientColor;Landroid/content/res/GradientColor;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/Shader;Landroid/graphics/LinearGradient;]Ljava/lang/String;Ljava/lang/String;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
+HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->onStateChange([I)Z
+HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/content/res/ComplexColor;Landroid/content/res/ColorStateList;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->-$$Nest$fgetmChangingConfigurations(Landroid/graphics/drawable/VectorDrawable$VGroup;)I
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->-$$Nest$fgetmNativePtr(Landroid/graphics/drawable/VectorDrawable$VGroup;)J
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;-><init>()V
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;-><init>(Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/util/ArrayMap;)V+]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->addChild(Landroid/graphics/drawable/VectorDrawable$VObject;)V+]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VClipPath;,Landroid/graphics/drawable/VectorDrawable$VFullPath;,Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;-><init>(Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/util/ArrayMap;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->addChild(Landroid/graphics/drawable/VectorDrawable$VObject;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VGroup;,Landroid/graphics/drawable/VectorDrawable$VFullPath;
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->applyTheme(Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->canApplyTheme()Z
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getGroupName()Ljava/lang/String;
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getNativePtr()J
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getNativeSize()I+]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VClipPath;,Landroid/graphics/drawable/VectorDrawable$VFullPath;,Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getNativeSize()I
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getProperty(Ljava/lang/String;)Landroid/util/Property;
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->inflate(Landroid/content/res/Resources;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->isStateful()Z
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->onStateChange([I)Z+]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VFullPath;,Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->setTree(Lcom/android/internal/util/VirtualRefBasePtr;)V+]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VClipPath;,Landroid/graphics/drawable/VectorDrawable$VFullPath;,Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->onStateChange([I)Z
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->setTree(Lcom/android/internal/util/VirtualRefBasePtr;)V
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/VectorDrawable$VObject;-><init>()V
 HSPLandroid/graphics/drawable/VectorDrawable$VObject;->isTreeValid()Z
@@ -7766,21 +7794,21 @@
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->applyDensityScaling(II)V
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->applyTheme(Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->canApplyTheme()Z
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->canReuseCache()Z+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->canReuseCache()Z
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->createNativeTree(Landroid/graphics/drawable/VectorDrawable$VGroup;)V
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->createNativeTreeFromCopy(Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VGroup;)V+]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->createNativeTreeFromCopy(Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VGroup;)V
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->finalize()V
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getAlpha()F+]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getAlpha()F
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getChangingConfigurations()I
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getNativeRenderer()J+]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->isStateful()Z+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getNativeRenderer()J
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->isStateful()Z
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->newDrawable()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->newDrawable(Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->onStateChange([I)Z
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->onTreeConstructionFinished()V+]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->onTreeConstructionFinished()V+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->setAlpha(F)Z
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->setDensity(I)Z
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->setViewportSize(FF)V+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->setViewportSize(FF)V
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->updateCacheStates()V
 HSPLandroid/graphics/drawable/VectorDrawable;->-$$Nest$smnAddChild(JJ)V
 HSPLandroid/graphics/drawable/VectorDrawable;->-$$Nest$smnCreateFullPath()J
@@ -7803,37 +7831,37 @@
 HSPLandroid/graphics/drawable/VectorDrawable;-><init>()V
 HSPLandroid/graphics/drawable/VectorDrawable;-><init>(Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/content/res/Resources;)V
 HSPLandroid/graphics/drawable/VectorDrawable;-><init>(Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/content/res/Resources;Landroid/graphics/drawable/VectorDrawable-IA;)V
-HSPLandroid/graphics/drawable/VectorDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V
+HSPLandroid/graphics/drawable/VectorDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
 HSPLandroid/graphics/drawable/VectorDrawable;->canApplyTheme()Z
 HSPLandroid/graphics/drawable/VectorDrawable;->clearMutated()V
 HSPLandroid/graphics/drawable/VectorDrawable;->computeVectorSize()V
-HSPLandroid/graphics/drawable/VectorDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/ColorFilter;Landroid/graphics/BlendModeColorFilter;,Landroid/graphics/PorterDuffColorFilter;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
-HSPLandroid/graphics/drawable/VectorDrawable;->getAlpha()I+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable;->draw(Landroid/graphics/Canvas;)V
+HSPLandroid/graphics/drawable/VectorDrawable;->getAlpha()I
 HSPLandroid/graphics/drawable/VectorDrawable;->getChangingConfigurations()I
 HSPLandroid/graphics/drawable/VectorDrawable;->getColorFilter()Landroid/graphics/ColorFilter;
 HSPLandroid/graphics/drawable/VectorDrawable;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
 HSPLandroid/graphics/drawable/VectorDrawable;->getIntrinsicHeight()I
-HSPLandroid/graphics/drawable/VectorDrawable;->getIntrinsicWidth()I+]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/graphics/drawable/VectorDrawable;->getIntrinsicWidth()I
 HSPLandroid/graphics/drawable/VectorDrawable;->getNativeTree()J
 HSPLandroid/graphics/drawable/VectorDrawable;->getOpacity()I
 HSPLandroid/graphics/drawable/VectorDrawable;->getPixelSize()F
 HSPLandroid/graphics/drawable/VectorDrawable;->getTargetByName(Ljava/lang/String;)Ljava/lang/Object;
-HSPLandroid/graphics/drawable/VectorDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
-HSPLandroid/graphics/drawable/VectorDrawable;->inflateChildElements(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/graphics/drawable/VectorDrawable$VClipPath;Landroid/graphics/drawable/VectorDrawable$VClipPath;]Landroid/graphics/drawable/VectorDrawable$VFullPath;Landroid/graphics/drawable/VectorDrawable$VFullPath;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/lang/Object;Ljava/lang/String;]Ljava/util/Stack;Ljava/util/Stack;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/graphics/drawable/VectorDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;
+HSPLandroid/graphics/drawable/VectorDrawable;->inflateChildElements(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;]Ljava/lang/Object;Ljava/lang/String;]Ljava/util/Stack;Ljava/util/Stack;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Landroid/graphics/drawable/VectorDrawable$VFullPath;Landroid/graphics/drawable/VectorDrawable$VFullPath;
 HSPLandroid/graphics/drawable/VectorDrawable;->isAutoMirrored()Z
-HSPLandroid/graphics/drawable/VectorDrawable;->isStateful()Z+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable;->isStateful()Z
 HSPLandroid/graphics/drawable/VectorDrawable;->mutate()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/VectorDrawable;->needMirroring()Z
-HSPLandroid/graphics/drawable/VectorDrawable;->onStateChange([I)Z+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/graphics/drawable/VectorDrawable;->onStateChange([I)Z
 HSPLandroid/graphics/drawable/VectorDrawable;->setAllowCaching(Z)V
 HSPLandroid/graphics/drawable/VectorDrawable;->setAlpha(I)V
 HSPLandroid/graphics/drawable/VectorDrawable;->setAutoMirrored(Z)V
 HSPLandroid/graphics/drawable/VectorDrawable;->setColorFilter(Landroid/graphics/ColorFilter;)V
 HSPLandroid/graphics/drawable/VectorDrawable;->setTintBlendMode(Landroid/graphics/BlendMode;)V
-HSPLandroid/graphics/drawable/VectorDrawable;->setTintList(Landroid/content/res/ColorStateList;)V+]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
-HSPLandroid/graphics/drawable/VectorDrawable;->updateColorFilters(Landroid/graphics/BlendMode;Landroid/content/res/ColorStateList;)V+]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/graphics/drawable/VectorDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
+HSPLandroid/graphics/drawable/VectorDrawable;->updateColorFilters(Landroid/graphics/BlendMode;Landroid/content/res/ColorStateList;)V
 HSPLandroid/graphics/drawable/VectorDrawable;->updateLocalState(Landroid/content/res/Resources;)V
-HSPLandroid/graphics/drawable/VectorDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
 HSPLandroid/graphics/drawable/shapes/OvalShape;-><init>()V
 HSPLandroid/graphics/drawable/shapes/OvalShape;->draw(Landroid/graphics/Canvas;Landroid/graphics/Paint;)V
 HSPLandroid/graphics/drawable/shapes/OvalShape;->getOutline(Landroid/graphics/Outline;)V
@@ -7910,13 +7938,13 @@
 HSPLandroid/graphics/text/MeasuredText$Builder;-><init>([C)V
 HSPLandroid/graphics/text/MeasuredText$Builder;->appendReplacementRun(Landroid/graphics/Paint;IF)Landroid/graphics/text/MeasuredText$Builder;
 HSPLandroid/graphics/text/MeasuredText$Builder;->appendStyleRun(Landroid/graphics/Paint;IZ)Landroid/graphics/text/MeasuredText$Builder;
-HSPLandroid/graphics/text/MeasuredText$Builder;->appendStyleRun(Landroid/graphics/Paint;Landroid/graphics/text/LineBreakConfig;IZ)Landroid/graphics/text/MeasuredText$Builder;+]Landroid/graphics/Paint;Landroid/text/TextPaint;
+HSPLandroid/graphics/text/MeasuredText$Builder;->appendStyleRun(Landroid/graphics/Paint;Landroid/graphics/text/LineBreakConfig;IZ)Landroid/graphics/text/MeasuredText$Builder;
 HSPLandroid/graphics/text/MeasuredText$Builder;->build()Landroid/graphics/text/MeasuredText;
 HSPLandroid/graphics/text/MeasuredText$Builder;->ensureNativePtrNoReuse()V
 HSPLandroid/graphics/text/MeasuredText$Builder;->setComputeHyphenation(I)Landroid/graphics/text/MeasuredText$Builder;
 HSPLandroid/graphics/text/MeasuredText$Builder;->setComputeHyphenation(Z)Landroid/graphics/text/MeasuredText$Builder;
 HSPLandroid/graphics/text/MeasuredText$Builder;->setComputeLayout(Z)Landroid/graphics/text/MeasuredText$Builder;
-HSPLandroid/graphics/text/MeasuredText;->getCharWidthAt(I)F+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/graphics/text/MeasuredText;->getCharWidthAt(I)F
 HSPLandroid/graphics/text/MeasuredText;->getChars()[C
 HSPLandroid/graphics/text/MeasuredText;->getNativePtr()J
 HSPLandroid/hardware/Camera$CameraInfo;-><init>()V
@@ -7939,6 +7967,7 @@
 HSPLandroid/hardware/ICameraService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 HSPLandroid/hardware/ICameraService$Stub$Proxy;->addListener(Landroid/hardware/ICameraServiceListener;)[Landroid/hardware/CameraStatus;
 HSPLandroid/hardware/ICameraService$Stub$Proxy;->asBinder()Landroid/os/IBinder;
+HSPLandroid/hardware/ICameraService$Stub$Proxy;->getCameraCharacteristics(Ljava/lang/String;IZ)Landroid/hardware/camera2/impl/CameraMetadataNative;
 HSPLandroid/hardware/ICameraService$Stub$Proxy;->getConcurrentCameraIds()[Landroid/hardware/camera2/utils/ConcurrentCameraIdCombination;
 HSPLandroid/hardware/ICameraService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/ICameraService;
 HSPLandroid/hardware/ICameraServiceListener$Stub;->getMaxTransactionId()I
@@ -7986,7 +8015,7 @@
 HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;-><init>(Landroid/hardware/SensorEventListener;Landroid/os/Looper;Landroid/hardware/SystemSensorManager;Ljava/lang/String;)V
 HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->addSensorEvent(Landroid/hardware/Sensor;)V
 HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->dispatchAdditionalInfoEvent(III[F[I)V
-HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->dispatchSensorEvent(I[FIJ)V+]Landroid/hardware/Sensor;Landroid/hardware/Sensor;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->dispatchSensorEvent(I[FIJ)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Landroid/hardware/Sensor;Landroid/hardware/Sensor;]Landroid/util/SparseArray;Landroid/util/SparseArray;
 HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->removeSensorEvent(Landroid/hardware/Sensor;)V
 HSPLandroid/hardware/SystemSensorManager$TriggerEventQueue;->addSensorEvent(Landroid/hardware/Sensor;)V
 HSPLandroid/hardware/SystemSensorManager$TriggerEventQueue;->dispatchSensorEvent(I[FIJ)V
@@ -8021,11 +8050,19 @@
 HSPLandroid/hardware/camera2/CameraManager$AvailabilityCallback;-><init>()V
 HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
 HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal$1;->compare(Ljava/lang/String;Ljava/lang/String;)I
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal$3;-><init>(Landroid/hardware/camera2/CameraManager$CameraManagerGlobal;Landroid/hardware/camera2/CameraManager$AvailabilityCallback;)V
 HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->asBinder()Landroid/os/IBinder;
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->cameraIdHasConcurrentStreamsLocked(Ljava/lang/String;)Z
 HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->connectCameraServiceLocked()V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->extractCameraIdListLocked()[Ljava/lang/String;
 HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->get()Landroid/hardware/camera2/CameraManager$CameraManagerGlobal;
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->getCameraIdList()[Ljava/lang/String;
 HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->getCameraService()Landroid/hardware/ICameraService;
 HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onCameraAccessPrioritiesChanged()V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onStatusChanged(ILjava/lang/String;)V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onStatusChangedLocked(ILjava/lang/String;)V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onTorchStatusChanged(ILjava/lang/String;)V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onTorchStatusChangedLocked(ILjava/lang/String;)V
 HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->postSingleAccessPriorityChangeUpdate(Landroid/hardware/camera2/CameraManager$AvailabilityCallback;Ljava/util/concurrent/Executor;)V
 HSPLandroid/hardware/camera2/CameraManager$FoldStateListener;->addDeviceStateListener(Landroid/hardware/camera2/CameraManager$DeviceStateListener;)V
 HSPLandroid/hardware/camera2/CameraManager$FoldStateListener;->handleStateChange(I)V
@@ -8035,6 +8072,7 @@
 HSPLandroid/hardware/camera2/CameraManager;->getDisplaySize()Landroid/util/Size;
 HSPLandroid/hardware/camera2/CameraManager;->getPhysicalCameraMultiResolutionConfigs(Ljava/lang/String;Landroid/hardware/camera2/impl/CameraMetadataNative;Landroid/hardware/ICameraService;)Ljava/util/Map;
 HSPLandroid/hardware/camera2/CameraManager;->registerDeviceStateListener(Landroid/hardware/camera2/CameraCharacteristics;)V
+HSPLandroid/hardware/camera2/CameraManager;->shouldOverrideToPortrait(Landroid/content/Context;)Z
 HSPLandroid/hardware/camera2/CameraMetadata;-><init>()V
 HSPLandroid/hardware/camera2/CameraMetadata;->setNativeInstance(Landroid/hardware/camera2/impl/CameraMetadataNative;)V
 HSPLandroid/hardware/camera2/impl/CameraDeviceImpl$CameraHandlerExecutor;->execute(Ljava/lang/Runnable;)V
@@ -8181,7 +8219,9 @@
 HSPLandroid/hardware/display/DisplayManagerGlobal$1;->recompute(Ljava/lang/Integer;)Landroid/view/DisplayInfo;
 HSPLandroid/hardware/display/DisplayManagerGlobal$1;->recompute(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayListenerDelegate$$ExternalSyntheticLambda0;->run()V
+HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayListenerDelegate;-><init>(Landroid/hardware/display/DisplayManager$DisplayListener;Ljava/util/concurrent/Executor;JLjava/lang/String;)V
 HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayListenerDelegate;->clearEvents()V
+HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayListenerDelegate;->handleDisplayEventInner(IILandroid/view/DisplayInfo;Z)V+]Landroid/view/DisplayInfo;Landroid/view/DisplayInfo;]Landroid/hardware/display/DisplayManager$DisplayListener;missing_types
 HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayManagerCallback;-><init>(Landroid/hardware/display/DisplayManagerGlobal;)V
 HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayManagerCallback;-><init>(Landroid/hardware/display/DisplayManagerGlobal;Landroid/hardware/display/DisplayManagerGlobal$DisplayManagerCallback-IA;)V
 HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayManagerCallback;->onDisplayEvent(II)V
@@ -8202,6 +8242,7 @@
 HSPLandroid/hardware/display/DisplayManagerGlobal;->getStableDisplaySize()Landroid/graphics/Point;
 HSPLandroid/hardware/display/DisplayManagerGlobal;->getWifiDisplayStatus()Landroid/hardware/display/WifiDisplayStatus;
 HSPLandroid/hardware/display/DisplayManagerGlobal;->initExtraLogging()Z
+HSPLandroid/hardware/display/DisplayManagerGlobal;->maybeLogAllDisplayListeners()V
 HSPLandroid/hardware/display/DisplayManagerGlobal;->registerCallbackIfNeededLocked()V
 HSPLandroid/hardware/display/DisplayManagerGlobal;->registerDisplayListener(Landroid/hardware/display/DisplayManager$DisplayListener;Ljava/util/concurrent/Executor;JLjava/lang/String;)V+]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;
 HSPLandroid/hardware/display/DisplayManagerGlobal;->registerNativeChoreographerForRefreshRateCallbacks()V
@@ -8321,7 +8362,7 @@
 HSPLandroid/hardware/location/NanoAppMessage;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/hardware/location/NanoAppState$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/location/NanoAppState;
 HSPLandroid/hardware/location/NanoAppState$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/hardware/location/NanoAppState;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/hardware/location/NanoAppState;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/hardware/location/NanoAppState;->getNanoAppId()J
 HSPLandroid/hardware/security/keymint/KeyParameter$1;-><init>()V
 HSPLandroid/hardware/security/keymint/KeyParameter$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/security/keymint/KeyParameter;
@@ -8434,7 +8475,7 @@
 HSPLandroid/icu/impl/FormattedStringBuilder;->fieldAt(I)Ljava/lang/Object;
 HSPLandroid/icu/impl/FormattedStringBuilder;->getCapacity()I
 HSPLandroid/icu/impl/FormattedStringBuilder;->insert(ILjava/lang/CharSequence;IILjava/lang/Object;)I
-HSPLandroid/icu/impl/FormattedStringBuilder;->insert(ILjava/lang/CharSequence;Ljava/lang/Object;)I
+HSPLandroid/icu/impl/FormattedStringBuilder;->insert(ILjava/lang/CharSequence;Ljava/lang/Object;)I+]Ljava/lang/CharSequence;Ljava/lang/String;
 HSPLandroid/icu/impl/FormattedStringBuilder;->insert(I[C[Ljava/lang/Object;)I
 HSPLandroid/icu/impl/FormattedStringBuilder;->insertCodePoint(IILjava/lang/Object;)I
 HSPLandroid/icu/impl/FormattedStringBuilder;->length()I
@@ -8445,7 +8486,7 @@
 HSPLandroid/icu/impl/FormattedStringBuilder;->toString()Ljava/lang/String;
 HSPLandroid/icu/impl/FormattedStringBuilder;->unwrapField(Ljava/lang/Object;)Ljava/text/Format$Field;
 HSPLandroid/icu/impl/FormattedValueStringBuilderImpl;->isIntOrGroup(Ljava/lang/Object;)Z
-HSPLandroid/icu/impl/FormattedValueStringBuilderImpl;->nextFieldPosition(Landroid/icu/impl/FormattedStringBuilder;Ljava/text/FieldPosition;)Z
+HSPLandroid/icu/impl/FormattedValueStringBuilderImpl;->nextFieldPosition(Landroid/icu/impl/FormattedStringBuilder;Ljava/text/FieldPosition;)Z+]Landroid/icu/text/ConstrainedFieldPosition;Landroid/icu/text/ConstrainedFieldPosition;]Ljava/text/FieldPosition;Ljava/text/DontCareFieldPosition;
 HSPLandroid/icu/impl/FormattedValueStringBuilderImpl;->nextPosition(Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/text/ConstrainedFieldPosition;Ljava/text/Format$Field;)Z+]Landroid/icu/text/ConstrainedFieldPosition;Landroid/icu/text/ConstrainedFieldPosition;
 HSPLandroid/icu/impl/Grego;->dayOfWeek(J)I
 HSPLandroid/icu/impl/Grego;->dayToFields(J[I)[I
@@ -8466,7 +8507,7 @@
 HSPLandroid/icu/impl/ICUBinary$PackageDataFile;->getData(Ljava/lang/String;)Ljava/nio/ByteBuffer;
 HSPLandroid/icu/impl/ICUBinary;->addBaseNamesInFileFolder(Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;)V
 HSPLandroid/icu/impl/ICUBinary;->compareKeys(Ljava/lang/CharSequence;Ljava/nio/ByteBuffer;I)I
-HSPLandroid/icu/impl/ICUBinary;->compareKeys(Ljava/lang/CharSequence;[BI)I
+HSPLandroid/icu/impl/ICUBinary;->compareKeys(Ljava/lang/CharSequence;[BI)I+]Ljava/lang/CharSequence;Ljava/lang/String;
 HSPLandroid/icu/impl/ICUBinary;->getBytes(Ljava/nio/ByteBuffer;II)[B
 HSPLandroid/icu/impl/ICUBinary;->getChars(Ljava/nio/ByteBuffer;II)[C
 HSPLandroid/icu/impl/ICUBinary;->getData(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;)Ljava/nio/ByteBuffer;
@@ -8502,7 +8543,7 @@
 HSPLandroid/icu/impl/ICUCurrencyMetaInfo$UniqueList;->create()Landroid/icu/impl/ICUCurrencyMetaInfo$UniqueList;
 HSPLandroid/icu/impl/ICUCurrencyMetaInfo$UniqueList;->list()Ljava/util/List;
 HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->collect(Landroid/icu/impl/ICUCurrencyMetaInfo$Collector;Landroid/icu/text/CurrencyMetaInfo$CurrencyFilter;)Ljava/util/List;
-HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->collectRegion(Landroid/icu/impl/ICUCurrencyMetaInfo$Collector;Landroid/icu/text/CurrencyMetaInfo$CurrencyFilter;ILandroid/icu/impl/ICUResourceBundle;)V
+HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->collectRegion(Landroid/icu/impl/ICUCurrencyMetaInfo$Collector;Landroid/icu/text/CurrencyMetaInfo$CurrencyFilter;ILandroid/icu/impl/ICUResourceBundle;)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/ICUResourceBundle;Landroid/icu/impl/ICUResourceBundleImpl$ResourceString;,Landroid/icu/impl/ICUResourceBundleImpl$ResourceTable;,Landroid/icu/impl/ICUResourceBundleImpl$ResourceArray;]Landroid/icu/impl/ICUCurrencyMetaInfo$Collector;Landroid/icu/impl/ICUCurrencyMetaInfo$CurrencyCollector;
 HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->currencies(Landroid/icu/text/CurrencyMetaInfo$CurrencyFilter;)Ljava/util/List;
 HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->currencyDigits(Ljava/lang/String;Landroid/icu/util/Currency$CurrencyUsage;)Landroid/icu/text/CurrencyMetaInfo$CurrencyDigits;
 HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->getDate(Landroid/icu/impl/ICUResourceBundle;JZ)J
@@ -8510,9 +8551,9 @@
 HSPLandroid/icu/impl/ICUData;->getStream(Ljava/lang/ClassLoader;Ljava/lang/String;Z)Ljava/io/InputStream;
 HSPLandroid/icu/impl/ICULocaleService$ICUResourceBundleFactory;->getSupportedIDs()Ljava/util/Set;
 HSPLandroid/icu/impl/ICULocaleService$ICUResourceBundleFactory;->loader()Ljava/lang/ClassLoader;
-HSPLandroid/icu/impl/ICULocaleService$LocaleKey;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V
+HSPLandroid/icu/impl/ICULocaleService$LocaleKey;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->createWithCanonical(Landroid/icu/util/ULocale;Ljava/lang/String;I)Landroid/icu/impl/ICULocaleService$LocaleKey;
-HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->currentDescriptor()Ljava/lang/String;
+HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->currentDescriptor()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/icu/impl/ICULocaleService$LocaleKey;Landroid/icu/impl/ICULocaleService$LocaleKey;
 HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->currentID()Ljava/lang/String;
 HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->currentLocale()Landroid/icu/util/ULocale;
 HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->fallback()Z
@@ -8544,20 +8585,21 @@
 HSPLandroid/icu/impl/ICUResourceBundle$WholeBundle;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;Landroid/icu/impl/ICUResourceBundleReader;)V
 HSPLandroid/icu/impl/ICUResourceBundle;->-$$Nest$mgetNoFallback(Landroid/icu/impl/ICUResourceBundle;)Z
 HSPLandroid/icu/impl/ICUResourceBundle;->-$$Nest$sfgetDEBUG()Z
+HSPLandroid/icu/impl/ICUResourceBundle;->-$$Nest$smgetParentLocaleID(Ljava/lang/String;Ljava/lang/String;Landroid/icu/impl/ICUResourceBundle$OpenType;)Ljava/lang/String;
 HSPLandroid/icu/impl/ICUResourceBundle;->-$$Nest$sminstantiateBundle(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;Landroid/icu/impl/ICUResourceBundle$OpenType;)Landroid/icu/impl/ICUResourceBundle;
 HSPLandroid/icu/impl/ICUResourceBundle;-><init>(Landroid/icu/impl/ICUResourceBundle$WholeBundle;)V
 HSPLandroid/icu/impl/ICUResourceBundle;-><init>(Landroid/icu/impl/ICUResourceBundle;Ljava/lang/String;)V
 HSPLandroid/icu/impl/ICUResourceBundle;->addBundleBaseNamesFromClassLoader(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/util/Set;)V
 HSPLandroid/icu/impl/ICUResourceBundle;->at(I)Landroid/icu/impl/ICUResourceBundle;
 HSPLandroid/icu/impl/ICUResourceBundle;->at(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle;
-HSPLandroid/icu/impl/ICUResourceBundle;->countPathKeys(Ljava/lang/String;)I
+HSPLandroid/icu/impl/ICUResourceBundle;->countPathKeys(Ljava/lang/String;)I+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/icu/impl/ICUResourceBundle;->createBundle(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)Landroid/icu/impl/ICUResourceBundle;
 HSPLandroid/icu/impl/ICUResourceBundle;->createFullLocaleNameSet(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/util/Set;
 HSPLandroid/icu/impl/ICUResourceBundle;->equals(Ljava/lang/Object;)Z
 HSPLandroid/icu/impl/ICUResourceBundle;->findResourceWithFallback(Ljava/lang/String;Landroid/icu/util/UResourceBundle;Landroid/icu/util/UResourceBundle;)Landroid/icu/impl/ICUResourceBundle;
 HSPLandroid/icu/impl/ICUResourceBundle;->findResourceWithFallback([Ljava/lang/String;ILandroid/icu/impl/ICUResourceBundle;Landroid/icu/util/UResourceBundle;)Landroid/icu/impl/ICUResourceBundle;
 HSPLandroid/icu/impl/ICUResourceBundle;->findStringWithFallback(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/icu/impl/ICUResourceBundle;->findStringWithFallback(Ljava/lang/String;Landroid/icu/util/UResourceBundle;Landroid/icu/util/UResourceBundle;)Ljava/lang/String;
+HSPLandroid/icu/impl/ICUResourceBundle;->findStringWithFallback(Ljava/lang/String;Landroid/icu/util/UResourceBundle;Landroid/icu/util/UResourceBundle;)Ljava/lang/String;+]Landroid/icu/impl/ICUResourceBundleReader$Container;Landroid/icu/impl/ICUResourceBundleReader$Table;,Landroid/icu/impl/ICUResourceBundleReader$Table1632;,Landroid/icu/impl/ICUResourceBundleReader$Table16;]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/ICUResourceBundle;Landroid/icu/impl/ICUResourceBundleImpl$ResourceTable;]Landroid/icu/impl/ICUResourceBundleReader;Landroid/icu/impl/ICUResourceBundleReader;
 HSPLandroid/icu/impl/ICUResourceBundle;->findTopLevel(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle;
 HSPLandroid/icu/impl/ICUResourceBundle;->findTopLevel(Ljava/lang/String;)Landroid/icu/util/UResourceBundle;
 HSPLandroid/icu/impl/ICUResourceBundle;->findWithFallback(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle;
@@ -8590,7 +8632,7 @@
 HSPLandroid/icu/impl/ICUResourceBundle;->getStringWithFallback(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/icu/impl/ICUResourceBundle;->getULocale()Landroid/icu/util/ULocale;
 HSPLandroid/icu/impl/ICUResourceBundle;->getWithFallback(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle;
-HSPLandroid/icu/impl/ICUResourceBundle;->instantiateBundle(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;Landroid/icu/impl/ICUResourceBundle$OpenType;)Landroid/icu/impl/ICUResourceBundle;
+HSPLandroid/icu/impl/ICUResourceBundle;->instantiateBundle(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;Landroid/icu/impl/ICUResourceBundle$OpenType;)Landroid/icu/impl/ICUResourceBundle;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/icu/impl/ICUResourceBundle$OpenType;Landroid/icu/impl/ICUResourceBundle$OpenType;]Landroid/icu/impl/CacheBase;Landroid/icu/impl/ICUResourceBundle$1;
 HSPLandroid/icu/impl/ICUResourceBundle;->setParent(Ljava/util/ResourceBundle;)V
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceArray;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceArray;->getStringArray()[Ljava/lang/String;
@@ -8602,22 +8644,22 @@
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;-><init>(Landroid/icu/impl/ICUResourceBundle$WholeBundle;)V
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->createBundleObject(ILjava/lang/String;Ljava/util/HashMap;Landroid/icu/util/UResourceBundle;)Landroid/icu/util/UResourceBundle;
-HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->getContainerResource(I)I
+HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->getContainerResource(I)I+]Landroid/icu/impl/ICUResourceBundleReader$Container;Landroid/icu/impl/ICUResourceBundleReader$Table1632;,Landroid/icu/impl/ICUResourceBundleReader$Table16;
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->getSize()I
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->getString(I)Ljava/lang/String;
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceInt;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceInt;->getInt()I
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceIntVector;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceIntVector;->getIntVector()[I
-HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceString;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
+HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceString;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/ICUResourceBundleReader;Landroid/icu/impl/ICUResourceBundleReader;
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceString;->getString()Ljava/lang/String;
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceString;->getType()I
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;-><init>(Landroid/icu/impl/ICUResourceBundle$WholeBundle;I)V
-HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
+HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V+]Landroid/icu/impl/ICUResourceBundleReader;Landroid/icu/impl/ICUResourceBundleReader;
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->findString(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->getType()I
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->handleGet(ILjava/util/HashMap;Landroid/icu/util/UResourceBundle;)Landroid/icu/util/UResourceBundle;
-HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->handleGet(Ljava/lang/String;Ljava/util/HashMap;Landroid/icu/util/UResourceBundle;)Landroid/icu/util/UResourceBundle;
+HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->handleGet(Ljava/lang/String;Ljava/util/HashMap;Landroid/icu/util/UResourceBundle;)Landroid/icu/util/UResourceBundle;+]Landroid/icu/impl/ICUResourceBundleImpl$ResourceTable;Landroid/icu/impl/ICUResourceBundleImpl$ResourceTable;]Landroid/icu/impl/ICUResourceBundleReader$Table;Landroid/icu/impl/ICUResourceBundleReader$Table;,Landroid/icu/impl/ICUResourceBundleReader$Table1632;,Landroid/icu/impl/ICUResourceBundleReader$Table16;
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->handleGetObject(Ljava/lang/String;)Ljava/lang/Object;
 HSPLandroid/icu/impl/ICUResourceBundleImpl;-><init>(Landroid/icu/impl/ICUResourceBundle$WholeBundle;)V
 HSPLandroid/icu/impl/ICUResourceBundleImpl;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
@@ -8648,13 +8690,13 @@
 HSPLandroid/icu/impl/ICUResourceBundleReader$ReaderValue;->getStringArray(Landroid/icu/impl/ICUResourceBundleReader$Array;)[Ljava/lang/String;
 HSPLandroid/icu/impl/ICUResourceBundleReader$ReaderValue;->getTable()Landroid/icu/impl/UResource$Table;
 HSPLandroid/icu/impl/ICUResourceBundleReader$ReaderValue;->getType()I
-HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;->get(I)Ljava/lang/Object;
-HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;->putIfAbsent(ILjava/lang/Object;I)Ljava/lang/Object;
+HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;->get(I)Ljava/lang/Object;+]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;
+HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;->putIfAbsent(ILjava/lang/Object;I)Ljava/lang/Object;+]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;
 HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;-><init>(I)V
 HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->findSimple(I)I
-HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->get(I)Ljava/lang/Object;
+HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->get(I)Ljava/lang/Object;+]Ljava/lang/ref/SoftReference;Ljava/lang/ref/SoftReference;]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;
 HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->makeKey(I)I
-HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->putIfAbsent(ILjava/lang/Object;I)Ljava/lang/Object;
+HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->putIfAbsent(ILjava/lang/Object;I)Ljava/lang/Object;+]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;
 HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->putIfCleared([Ljava/lang/Object;ILjava/lang/Object;I)Ljava/lang/Object;
 HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->storeDirectly(I)Z
 HSPLandroid/icu/impl/ICUResourceBundleReader$Table1632;-><init>(Landroid/icu/impl/ICUResourceBundleReader;I)V
@@ -8664,7 +8706,7 @@
 HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->findTableItem(Landroid/icu/impl/ICUResourceBundleReader;Ljava/lang/CharSequence;)I
 HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->findValue(Ljava/lang/CharSequence;Landroid/icu/impl/UResource$Value;)Z
 HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->getKey(Landroid/icu/impl/ICUResourceBundleReader;I)Ljava/lang/String;
-HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->getKeyAndValue(ILandroid/icu/impl/UResource$Key;Landroid/icu/impl/UResource$Value;)Z
+HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->getKeyAndValue(ILandroid/icu/impl/UResource$Key;Landroid/icu/impl/UResource$Value;)Z+]Landroid/icu/impl/ICUResourceBundleReader$Table;Landroid/icu/impl/ICUResourceBundleReader$Table1632;,Landroid/icu/impl/ICUResourceBundleReader$Table16;
 HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->getResource(Landroid/icu/impl/ICUResourceBundleReader;Ljava/lang/String;)I
 HSPLandroid/icu/impl/ICUResourceBundleReader;->-$$Nest$fgetb16BitUnits(Landroid/icu/impl/ICUResourceBundleReader;)Ljava/nio/CharBuffer;
 HSPLandroid/icu/impl/ICUResourceBundleReader;->-$$Nest$fgetpoolStringIndex16Limit(Landroid/icu/impl/ICUResourceBundleReader;)I
@@ -8688,7 +8730,7 @@
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getArray(I)Landroid/icu/impl/ICUResourceBundleReader$Array;
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getBinary(I[B)[B
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getChars(II)[C
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getFullName(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getFullName(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getIndexesInt(I)I
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getInt(I)I
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getIntVector(I)[I
@@ -8698,10 +8740,10 @@
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getReader(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)Landroid/icu/impl/ICUResourceBundleReader;
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getResourceByteOffset(I)I
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getRootResource()I
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getString(I)Ljava/lang/String;
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getStringV2(I)Ljava/lang/String;
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getTable(I)Landroid/icu/impl/ICUResourceBundleReader$Table;
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getTable16KeyOffsets(I)[C
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getString(I)Ljava/lang/String;+]Landroid/icu/impl/ICUResourceBundleReader;Landroid/icu/impl/ICUResourceBundleReader;
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getStringV2(I)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache;]Ljava/nio/CharBuffer;Ljava/nio/ByteBufferAsCharBuffer;]Ljava/lang/CharSequence;Ljava/nio/ByteBufferAsCharBuffer;
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getTable(I)Landroid/icu/impl/ICUResourceBundleReader$Table;+]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache;]Landroid/icu/impl/ICUResourceBundleReader$Table;Landroid/icu/impl/ICUResourceBundleReader$Table16;,Landroid/icu/impl/ICUResourceBundleReader$Table1632;
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getTable16KeyOffsets(I)[C+]Ljava/nio/CharBuffer;Ljava/nio/ByteBufferAsCharBuffer;
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getTableKeyOffsets(I)[C
 HSPLandroid/icu/impl/ICUResourceBundleReader;->init(Ljava/nio/ByteBuffer;)V
 HSPLandroid/icu/impl/ICUResourceBundleReader;->makeKeyStringFromBytes([BI)Ljava/lang/String;
@@ -8711,10 +8753,10 @@
 HSPLandroid/icu/impl/ICUService$Key;-><init>(Ljava/lang/String;)V
 HSPLandroid/icu/impl/ICUService;->clearServiceCache()V
 HSPLandroid/icu/impl/ICUService;->getKey(Landroid/icu/impl/ICUService$Key;[Ljava/lang/String;)Ljava/lang/Object;
-HSPLandroid/icu/impl/ICUService;->getKey(Landroid/icu/impl/ICUService$Key;[Ljava/lang/String;Landroid/icu/impl/ICUService$Factory;)Ljava/lang/Object;
+HSPLandroid/icu/impl/ICUService;->getKey(Landroid/icu/impl/ICUService$Key;[Ljava/lang/String;Landroid/icu/impl/ICUService$Factory;)Ljava/lang/Object;+]Ljava/lang/String;Ljava/lang/String;]Ljava/util/List;Ljava/util/ArrayList;]Ljava/util/Map;Ljava/util/concurrent/ConcurrentHashMap;]Landroid/icu/impl/ICURWLock;Landroid/icu/impl/ICURWLock;]Landroid/icu/impl/ICUService$Key;Landroid/icu/impl/ICULocaleService$LocaleKey;
 HSPLandroid/icu/impl/ICUService;->isDefault()Z
-HSPLandroid/icu/impl/IDNA2003;->convertIDNToASCII(Ljava/lang/String;I)Ljava/lang/StringBuffer;
-HSPLandroid/icu/impl/IDNA2003;->convertToASCII(Landroid/icu/text/UCharacterIterator;I)Ljava/lang/StringBuffer;
+HSPLandroid/icu/impl/IDNA2003;->convertIDNToASCII(Ljava/lang/String;I)Ljava/lang/StringBuffer;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;
+HSPLandroid/icu/impl/IDNA2003;->convertToASCII(Landroid/icu/text/UCharacterIterator;I)Ljava/lang/StringBuffer;+]Landroid/icu/text/UCharacterIterator;Landroid/icu/impl/ReplaceableUCharacterIterator;]Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;
 HSPLandroid/icu/impl/IDNA2003;->getSeparatorIndex([CII)I
 HSPLandroid/icu/impl/IDNA2003;->isLDHChar(I)Z
 HSPLandroid/icu/impl/IDNA2003;->isLabelSeparator(I)Z
@@ -8722,9 +8764,9 @@
 HSPLandroid/icu/impl/LocaleIDParser$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
 HSPLandroid/icu/impl/LocaleIDParser$1;->compare(Ljava/lang/String;Ljava/lang/String;)I
 HSPLandroid/icu/impl/LocaleIDParser;-><init>(Ljava/lang/String;)V
-HSPLandroid/icu/impl/LocaleIDParser;-><init>(Ljava/lang/String;Z)V
+HSPLandroid/icu/impl/LocaleIDParser;-><init>(Ljava/lang/String;Z)V+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/icu/impl/LocaleIDParser;->addSeparator()V
-HSPLandroid/icu/impl/LocaleIDParser;->append(C)V
+HSPLandroid/icu/impl/LocaleIDParser;->append(C)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/icu/impl/LocaleIDParser;->append(Ljava/lang/String;)V
 HSPLandroid/icu/impl/LocaleIDParser;->atTerminator()Z
 HSPLandroid/icu/impl/LocaleIDParser;->getBaseName()Ljava/lang/String;
@@ -8748,10 +8790,10 @@
 HSPLandroid/icu/impl/LocaleIDParser;->isTerminatorOrIDSeparator(C)Z
 HSPLandroid/icu/impl/LocaleIDParser;->next()C
 HSPLandroid/icu/impl/LocaleIDParser;->parseBaseName()V
-HSPLandroid/icu/impl/LocaleIDParser;->parseCountry()I
+HSPLandroid/icu/impl/LocaleIDParser;->parseCountry()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/icu/impl/LocaleIDParser;->parseKeywords()I
-HSPLandroid/icu/impl/LocaleIDParser;->parseLanguage()I
-HSPLandroid/icu/impl/LocaleIDParser;->parseScript()I
+HSPLandroid/icu/impl/LocaleIDParser;->parseLanguage()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/icu/impl/LocaleIDParser;->parseScript()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/icu/impl/LocaleIDParser;->parseVariant()I
 HSPLandroid/icu/impl/LocaleIDParser;->reset()V
 HSPLandroid/icu/impl/LocaleIDParser;->setKeywordValue(Ljava/lang/String;Ljava/lang/String;)V
@@ -8780,7 +8822,7 @@
 HSPLandroid/icu/impl/Normalizer2Impl;->addToStartSet(Landroid/icu/util/MutableCodePointTrie;II)V
 HSPLandroid/icu/impl/Normalizer2Impl;->composeQuickCheck(Ljava/lang/CharSequence;IIZZ)I
 HSPLandroid/icu/impl/Normalizer2Impl;->decompose(IILandroid/icu/impl/Normalizer2Impl$ReorderingBuffer;)V
-HSPLandroid/icu/impl/Normalizer2Impl;->decompose(Ljava/lang/CharSequence;IILandroid/icu/impl/Normalizer2Impl$ReorderingBuffer;)I
+HSPLandroid/icu/impl/Normalizer2Impl;->decompose(Ljava/lang/CharSequence;IILandroid/icu/impl/Normalizer2Impl$ReorderingBuffer;)I+]Ljava/lang/CharSequence;Ljava/lang/String;
 HSPLandroid/icu/impl/Normalizer2Impl;->decomposeAndAppend(Ljava/lang/CharSequence;ZLandroid/icu/impl/Normalizer2Impl$ReorderingBuffer;)V
 HSPLandroid/icu/impl/Normalizer2Impl;->ensureCanonIterData()Landroid/icu/impl/Normalizer2Impl;
 HSPLandroid/icu/impl/Normalizer2Impl;->getRawNorm16(I)I
@@ -8810,11 +8852,11 @@
 HSPLandroid/icu/impl/OlsonTimeZone;->initialRawOffset()I
 HSPLandroid/icu/impl/OlsonTimeZone;->isFrozen()Z
 HSPLandroid/icu/impl/OlsonTimeZone;->loadRule(Landroid/icu/util/UResourceBundle;Ljava/lang/String;)Landroid/icu/util/UResourceBundle;
-HSPLandroid/icu/impl/OlsonTimeZone;->toString()Ljava/lang/String;
+HSPLandroid/icu/impl/OlsonTimeZone;->toString()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/icu/impl/PatternProps;->isWhiteSpace(I)Z
 HSPLandroid/icu/impl/PatternProps;->skipWhiteSpace(Ljava/lang/CharSequence;I)I
 HSPLandroid/icu/impl/PatternTokenizer;-><init>()V
-HSPLandroid/icu/impl/PatternTokenizer;->next(Ljava/lang/StringBuffer;)I
+HSPLandroid/icu/impl/PatternTokenizer;->next(Ljava/lang/StringBuffer;)I+]Landroid/icu/text/UnicodeSet;Landroid/icu/text/UnicodeSet;
 HSPLandroid/icu/impl/PatternTokenizer;->quoteLiteral(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/icu/impl/PatternTokenizer;->setExtraQuotingCharacters(Landroid/icu/text/UnicodeSet;)Landroid/icu/impl/PatternTokenizer;
 HSPLandroid/icu/impl/PatternTokenizer;->setPattern(Ljava/lang/String;)Landroid/icu/impl/PatternTokenizer;
@@ -8835,7 +8877,7 @@
 HSPLandroid/icu/impl/ReplaceableUCharacterIterator;-><init>(Ljava/lang/String;)V
 HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->getLength()I
 HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->getText([CI)I
-HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->next()I
+HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->next()I+]Landroid/icu/text/Replaceable;Landroid/icu/text/ReplaceableString;
 HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->setIndex(I)V
 HSPLandroid/icu/impl/RuleCharacterIterator;->_advance(I)V
 HSPLandroid/icu/impl/RuleCharacterIterator;->_current()I
@@ -8862,14 +8904,14 @@
 HSPLandroid/icu/impl/StaticUnicodeSets;->get(Landroid/icu/impl/StaticUnicodeSets$Key;)Landroid/icu/text/UnicodeSet;
 HSPLandroid/icu/impl/StringSegment;-><init>(Ljava/lang/String;Z)V
 HSPLandroid/icu/impl/StringSegment;->adjustOffset(I)V
-HSPLandroid/icu/impl/StringSegment;->charAt(I)C+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/icu/impl/StringSegment;->charAt(I)C
 HSPLandroid/icu/impl/StringSegment;->codePointsEqual(IIZ)Z
-HSPLandroid/icu/impl/StringSegment;->getCodePoint()I+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/icu/impl/StringSegment;->getCodePoint()I
 HSPLandroid/icu/impl/StringSegment;->getCommonPrefixLength(Ljava/lang/CharSequence;)I
 HSPLandroid/icu/impl/StringSegment;->getOffset()I
-HSPLandroid/icu/impl/StringSegment;->getPrefixLengthInternal(Ljava/lang/CharSequence;Z)I+]Landroid/icu/impl/StringSegment;Landroid/icu/impl/StringSegment;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/icu/impl/StringSegment;->getPrefixLengthInternal(Ljava/lang/CharSequence;Z)I
 HSPLandroid/icu/impl/StringSegment;->length()I
-HSPLandroid/icu/impl/StringSegment;->startsWith(Landroid/icu/text/UnicodeSet;)Z+]Landroid/icu/impl/StringSegment;Landroid/icu/impl/StringSegment;]Landroid/icu/text/UnicodeSet;Landroid/icu/text/UnicodeSet;
+HSPLandroid/icu/impl/StringSegment;->startsWith(Landroid/icu/text/UnicodeSet;)Z
 HSPLandroid/icu/impl/StringSegment;->startsWith(Ljava/lang/CharSequence;)Z
 HSPLandroid/icu/impl/TextTrieMap$Node;-><init>(Landroid/icu/impl/TextTrieMap;)V
 HSPLandroid/icu/impl/TextTrieMap;-><init>(Z)V
@@ -8927,7 +8969,7 @@
 HSPLandroid/icu/impl/Trie2_32;->getFromU16SingleLead(C)I
 HSPLandroid/icu/impl/UBiDiProps;->getClass(I)I
 HSPLandroid/icu/impl/UBiDiProps;->getClassFromProps(I)I
-HSPLandroid/icu/impl/UCaseProps;->fold(II)I+]Landroid/icu/impl/Trie2_16;Landroid/icu/impl/Trie2_16;
+HSPLandroid/icu/impl/UCaseProps;->fold(II)I
 HSPLandroid/icu/impl/UCaseProps;->getCaseLocale(Ljava/lang/String;)I
 HSPLandroid/icu/impl/UCaseProps;->getCaseLocale(Ljava/util/Locale;)I
 HSPLandroid/icu/impl/UCaseProps;->getDelta(I)I
@@ -8959,7 +9001,7 @@
 HSPLandroid/icu/impl/UResource$Value;-><init>()V
 HSPLandroid/icu/impl/UResource$Value;->toString()Ljava/lang/String;
 HSPLandroid/icu/impl/Utility;->addExact(II)I
-HSPLandroid/icu/impl/Utility;->appendTo(Ljava/lang/CharSequence;Ljava/lang/Appendable;)Ljava/lang/Appendable;
+HSPLandroid/icu/impl/Utility;->appendTo(Ljava/lang/CharSequence;Ljava/lang/Appendable;)Ljava/lang/Appendable;+]Ljava/lang/Appendable;Ljava/lang/StringBuffer;
 HSPLandroid/icu/impl/Utility;->arrayEquals([BLjava/lang/Object;)Z
 HSPLandroid/icu/impl/Utility;->arrayRegionMatches([BI[BII)Z
 HSPLandroid/icu/impl/Utility;->sameObjects(Ljava/lang/Object;Ljava/lang/Object;)Z
@@ -9090,9 +9132,9 @@
 HSPLandroid/icu/impl/locale/BaseLocale$Key;->-$$Nest$fget_vart(Landroid/icu/impl/locale/BaseLocale$Key;)Ljava/lang/String;
 HSPLandroid/icu/impl/locale/BaseLocale$Key;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/icu/impl/locale/BaseLocale$Key;->equals(Ljava/lang/Object;)Z
-HSPLandroid/icu/impl/locale/BaseLocale$Key;->hashCode()I
+HSPLandroid/icu/impl/locale/BaseLocale$Key;->hashCode()I+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/icu/impl/locale/BaseLocale$Key;->normalize(Landroid/icu/impl/locale/BaseLocale$Key;)Landroid/icu/impl/locale/BaseLocale$Key;
-HSPLandroid/icu/impl/locale/BaseLocale;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+HSPLandroid/icu/impl/locale/BaseLocale;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/icu/impl/locale/BaseLocale;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/icu/impl/locale/BaseLocale-IA;)V
 HSPLandroid/icu/impl/locale/BaseLocale;->getInstance(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/icu/impl/locale/BaseLocale;
 HSPLandroid/icu/impl/locale/BaseLocale;->getLanguage()Ljava/lang/String;
@@ -9113,7 +9155,7 @@
 HSPLandroid/icu/impl/locale/LocaleObjectCache;->get(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/icu/impl/number/AdoptingModifierStore$1;-><clinit>()V
 HSPLandroid/icu/impl/number/AdoptingModifierStore;-><init>(Landroid/icu/impl/number/Modifier;Landroid/icu/impl/number/Modifier;Landroid/icu/impl/number/Modifier;Landroid/icu/impl/number/Modifier;)V
-HSPLandroid/icu/impl/number/AdoptingModifierStore;->getModifierWithoutPlural(Landroid/icu/impl/number/Modifier$Signum;)Landroid/icu/impl/number/Modifier;
+HSPLandroid/icu/impl/number/AdoptingModifierStore;->getModifierWithoutPlural(Landroid/icu/impl/number/Modifier$Signum;)Landroid/icu/impl/number/Modifier;+]Landroid/icu/impl/number/Modifier$Signum;Landroid/icu/impl/number/Modifier$Signum;
 HSPLandroid/icu/impl/number/AffixUtils;->containsType(Ljava/lang/CharSequence;I)Z
 HSPLandroid/icu/impl/number/AffixUtils;->escape(Ljava/lang/CharSequence;)Ljava/lang/String;
 HSPLandroid/icu/impl/number/AffixUtils;->getFieldForType(I)Landroid/icu/text/NumberFormat$Field;
@@ -9128,14 +9170,14 @@
 HSPLandroid/icu/impl/number/AffixUtils;->nextToken(JLjava/lang/CharSequence;)J
 HSPLandroid/icu/impl/number/AffixUtils;->unescape(Ljava/lang/CharSequence;Landroid/icu/impl/FormattedStringBuilder;ILandroid/icu/impl/number/AffixUtils$SymbolProvider;Landroid/icu/text/NumberFormat$Field;)I
 HSPLandroid/icu/impl/number/AffixUtils;->unescapedCount(Ljava/lang/CharSequence;ZLandroid/icu/impl/number/AffixUtils$SymbolProvider;)I
-HSPLandroid/icu/impl/number/ConstantAffixModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I
+HSPLandroid/icu/impl/number/ConstantAffixModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I+]Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;
 HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;-><init>(Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;ZZ)V
 HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;-><init>(Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;ZZLandroid/icu/impl/number/Modifier$Parameters;)V
-HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I
+HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I+]Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;
 HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;->getPrefixLength()I
 HSPLandroid/icu/impl/number/CurrencySpacingEnabledModifier;->applyCurrencySpacing(Landroid/icu/impl/FormattedStringBuilder;IIIILandroid/icu/text/DecimalFormatSymbols;)I
 HSPLandroid/icu/impl/number/CurrencySpacingEnabledModifier;->applyCurrencySpacingAffix(Landroid/icu/impl/FormattedStringBuilder;IBLandroid/icu/text/DecimalFormatSymbols;)I
-HSPLandroid/icu/impl/number/CustomSymbolCurrency;->resolve(Landroid/icu/util/Currency;Landroid/icu/util/ULocale;Landroid/icu/text/DecimalFormatSymbols;)Landroid/icu/util/Currency;
+HSPLandroid/icu/impl/number/CustomSymbolCurrency;->resolve(Landroid/icu/util/Currency;Landroid/icu/util/ULocale;Landroid/icu/text/DecimalFormatSymbols;)Landroid/icu/util/Currency;+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/util/Currency;Landroid/icu/util/Currency;
 HSPLandroid/icu/impl/number/DecimalFormatProperties;-><init>()V
 HSPLandroid/icu/impl/number/DecimalFormatProperties;->_clear()Landroid/icu/impl/number/DecimalFormatProperties;
 HSPLandroid/icu/impl/number/DecimalFormatProperties;->_copyFrom(Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/impl/number/DecimalFormatProperties;
@@ -9215,14 +9257,14 @@
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToBigDecimal(Ljava/math/BigDecimal;)V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToBigInteger(Ljava/math/BigInteger;)V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToDoubleFast(D)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToLong(J)V
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToLong(J)V+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->adjustMagnitude(I)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->appendDigit(BIZ)V+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->appendDigit(BIZ)V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->applyMaxInteger(I)V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->convertToAccurateDouble()V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->copyFrom(Landroid/icu/impl/number/DecimalQuantity;)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->fitsInLong()Z+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getDigit(I)B
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->fitsInLong()Z
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getDigit(I)B+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getLowerDisplayMagnitude()I
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getMagnitude()I
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getPluralOperand(Landroid/icu/text/PluralRules$Operand;)D
@@ -9235,18 +9277,18 @@
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->negate()V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->populateUFieldPosition(Ljava/text/FieldPosition;)V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->roundToMagnitude(ILjava/math/MathContext;)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->roundToMagnitude(ILjava/math/MathContext;Z)V
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->roundToMagnitude(ILjava/math/MathContext;Z)V+]Ljava/math/MathContext;Ljava/math/MathContext;]Ljava/math/RoundingMode;Ljava/math/RoundingMode;]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->safeSubtract(II)I
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setMinFraction(I)V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setMinInteger(I)V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToBigDecimal(Ljava/math/BigDecimal;)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToDouble(D)V
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToDouble(D)V+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToInt(I)V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToLong(J)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->signum()Landroid/icu/impl/number/Modifier$Signum;
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->toLong(Z)J+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
-HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>()V+]Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
-HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(D)V
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->signum()Landroid/icu/impl/number/Modifier$Signum;+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->toLong(Z)J
+HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>()V
+HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(D)V+]Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
 HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(I)V
 HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(J)V
 HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(Ljava/lang/Number;)V
@@ -9278,14 +9320,14 @@
 HSPLandroid/icu/impl/number/MacroProps;->fallback(Landroid/icu/impl/number/MacroProps;)V
 HSPLandroid/icu/impl/number/MicroProps;-><init>(Z)V
 HSPLandroid/icu/impl/number/MicroProps;->clone()Ljava/lang/Object;
-HSPLandroid/icu/impl/number/MicroProps;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/impl/number/MicroProps;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/MicroProps;
 HSPLandroid/icu/impl/number/Modifier$Signum;->values()[Landroid/icu/impl/number/Modifier$Signum;
 HSPLandroid/icu/impl/number/MultiplierFormatHandler;-><init>(Landroid/icu/number/Scale;Landroid/icu/impl/number/MicroPropsGenerator;)V
 HSPLandroid/icu/impl/number/MultiplierFormatHandler;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
 HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;-><init>(Landroid/icu/impl/number/AdoptingModifierStore;Landroid/icu/text/PluralRules;)V
 HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->addToChain(Landroid/icu/impl/number/MicroPropsGenerator;)Landroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;
-HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->applyToMicros(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;)V
-HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->applyToMicros(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;)V+]Landroid/icu/impl/number/AdoptingModifierStore;Landroid/icu/impl/number/AdoptingModifierStore;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/impl/number/MicroPropsGenerator;Landroid/icu/impl/number/MicroProps;]Landroid/icu/number/Precision;Landroid/icu/number/Precision$FractionRounderImpl;]Landroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;Landroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;
 HSPLandroid/icu/impl/number/MutablePatternModifier;-><init>(Z)V
 HSPLandroid/icu/impl/number/MutablePatternModifier;->addToChain(Landroid/icu/impl/number/MicroPropsGenerator;)Landroid/icu/impl/number/MicroPropsGenerator;
 HSPLandroid/icu/impl/number/MutablePatternModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I
@@ -9315,7 +9357,7 @@
 HSPLandroid/icu/impl/number/PatternStringParser;->consumeExponent(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V
 HSPLandroid/icu/impl/number/PatternStringParser;->consumeFormat(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V
 HSPLandroid/icu/impl/number/PatternStringParser;->consumeFractionFormat(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V
-HSPLandroid/icu/impl/number/PatternStringParser;->consumeIntegerFormat(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V
+HSPLandroid/icu/impl/number/PatternStringParser;->consumeIntegerFormat(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V+]Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParserState;
 HSPLandroid/icu/impl/number/PatternStringParser;->consumeLiteral(Landroid/icu/impl/number/PatternStringParser$ParserState;)V
 HSPLandroid/icu/impl/number/PatternStringParser;->consumePadding(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;Landroid/icu/impl/number/Padder$PadPosition;)V
 HSPLandroid/icu/impl/number/PatternStringParser;->consumePattern(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedPatternInfo;)V
@@ -9328,9 +9370,9 @@
 HSPLandroid/icu/impl/number/PatternStringUtils$PatternSignType;-><init>(Ljava/lang/String;I)V
 HSPLandroid/icu/impl/number/PatternStringUtils$PatternSignType;->values()[Landroid/icu/impl/number/PatternStringUtils$PatternSignType;
 HSPLandroid/icu/impl/number/PatternStringUtils;->patternInfoToStringBuilder(Landroid/icu/impl/number/AffixPatternProvider;ZLandroid/icu/impl/number/PatternStringUtils$PatternSignType;ZLandroid/icu/impl/StandardPlural;ZLjava/lang/StringBuilder;)V
-HSPLandroid/icu/impl/number/PatternStringUtils;->propertiesToPatternString(Landroid/icu/impl/number/DecimalFormatProperties;)Ljava/lang/String;
+HSPLandroid/icu/impl/number/PatternStringUtils;->propertiesToPatternString(Landroid/icu/impl/number/DecimalFormatProperties;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;
 HSPLandroid/icu/impl/number/PatternStringUtils;->resolveSignDisplay(Landroid/icu/number/NumberFormatter$SignDisplay;Landroid/icu/impl/number/Modifier$Signum;)Landroid/icu/impl/number/PatternStringUtils$PatternSignType;
-HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;-><init>(Landroid/icu/impl/number/DecimalFormatProperties;)V
+HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;-><init>(Landroid/icu/impl/number/DecimalFormatProperties;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;
 HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->charAt(II)C
 HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->containsSymbolType(I)Z
 HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->currencyAsDecimal()Z
@@ -9338,7 +9380,7 @@
 HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->getString(I)Ljava/lang/String;
 HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->hasBody()Z
 HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->hasCurrencySign()Z
-HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->hasNegativeSubpattern()Z
+HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->hasNegativeSubpattern()Z+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->length(I)I
 HSPLandroid/icu/impl/number/RoundingUtils;->getMathContextOr34Digits(Landroid/icu/impl/number/DecimalFormatProperties;)Ljava/math/MathContext;
 HSPLandroid/icu/impl/number/RoundingUtils;->getMathContextOrUnlimited(Landroid/icu/impl/number/DecimalFormatProperties;)Ljava/math/MathContext;
@@ -9350,14 +9392,14 @@
 HSPLandroid/icu/impl/number/parse/AffixMatcher$1;->compare(Landroid/icu/impl/number/parse/AffixMatcher;Landroid/icu/impl/number/parse/AffixMatcher;)I
 HSPLandroid/icu/impl/number/parse/AffixMatcher$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
 HSPLandroid/icu/impl/number/parse/AffixMatcher;-><init>(Landroid/icu/impl/number/parse/AffixPatternMatcher;Landroid/icu/impl/number/parse/AffixPatternMatcher;I)V
-HSPLandroid/icu/impl/number/parse/AffixMatcher;->createMatchers(Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/parse/NumberParserImpl;Landroid/icu/impl/number/parse/AffixTokenMatcherFactory;Landroid/icu/impl/number/parse/IgnorablesMatcher;I)V+]Landroid/icu/impl/number/parse/NumberParserImpl;Landroid/icu/impl/number/parse/NumberParserImpl;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/icu/impl/number/parse/AffixMatcher;->createMatchers(Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/parse/NumberParserImpl;Landroid/icu/impl/number/parse/AffixTokenMatcherFactory;Landroid/icu/impl/number/parse/IgnorablesMatcher;I)V
 HSPLandroid/icu/impl/number/parse/AffixMatcher;->getInstance(Landroid/icu/impl/number/parse/AffixPatternMatcher;Landroid/icu/impl/number/parse/AffixPatternMatcher;I)Landroid/icu/impl/number/parse/AffixMatcher;
 HSPLandroid/icu/impl/number/parse/AffixMatcher;->isInteresting(Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/parse/IgnorablesMatcher;I)Z
 HSPLandroid/icu/impl/number/parse/AffixMatcher;->length(Landroid/icu/impl/number/parse/AffixPatternMatcher;)I
 HSPLandroid/icu/impl/number/parse/AffixMatcher;->match(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;)Z
 HSPLandroid/icu/impl/number/parse/AffixMatcher;->matched(Landroid/icu/impl/number/parse/AffixPatternMatcher;Ljava/lang/String;)Z
 HSPLandroid/icu/impl/number/parse/AffixMatcher;->postProcess(Landroid/icu/impl/number/parse/ParsedNumber;)V
-HSPLandroid/icu/impl/number/parse/AffixMatcher;->smokeTest(Landroid/icu/impl/StringSegment;)Z+]Landroid/icu/impl/number/parse/AffixPatternMatcher;Landroid/icu/impl/number/parse/AffixPatternMatcher;
+HSPLandroid/icu/impl/number/parse/AffixMatcher;->smokeTest(Landroid/icu/impl/StringSegment;)Z
 HSPLandroid/icu/impl/number/parse/AffixPatternMatcher;-><init>(Ljava/lang/String;)V
 HSPLandroid/icu/impl/number/parse/AffixPatternMatcher;->consumeToken(I)V
 HSPLandroid/icu/impl/number/parse/AffixPatternMatcher;->equals(Ljava/lang/Object;)Z
@@ -9365,10 +9407,10 @@
 HSPLandroid/icu/impl/number/parse/AffixPatternMatcher;->getPattern()Ljava/lang/String;
 HSPLandroid/icu/impl/number/parse/AffixTokenMatcherFactory;-><init>()V
 HSPLandroid/icu/impl/number/parse/AffixTokenMatcherFactory;->minusSign()Landroid/icu/impl/number/parse/MinusSignMatcher;
-HSPLandroid/icu/impl/number/parse/DecimalMatcher;-><init>(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;I)V+]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;
+HSPLandroid/icu/impl/number/parse/DecimalMatcher;-><init>(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;I)V
 HSPLandroid/icu/impl/number/parse/DecimalMatcher;->getInstance(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;I)Landroid/icu/impl/number/parse/DecimalMatcher;
 HSPLandroid/icu/impl/number/parse/DecimalMatcher;->match(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;)Z
-HSPLandroid/icu/impl/number/parse/DecimalMatcher;->match(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;I)Z
+HSPLandroid/icu/impl/number/parse/DecimalMatcher;->match(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;I)Z+]Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/number/parse/ParsedNumber;Landroid/icu/impl/number/parse/ParsedNumber;]Landroid/icu/text/UnicodeSet;Landroid/icu/text/UnicodeSet;]Landroid/icu/impl/StringSegment;Landroid/icu/impl/StringSegment;
 HSPLandroid/icu/impl/number/parse/DecimalMatcher;->postProcess(Landroid/icu/impl/number/parse/ParsedNumber;)V
 HSPLandroid/icu/impl/number/parse/DecimalMatcher;->smokeTest(Landroid/icu/impl/StringSegment;)Z
 HSPLandroid/icu/impl/number/parse/DecimalMatcher;->validateGroup(IIZ)Z
@@ -9379,14 +9421,14 @@
 HSPLandroid/icu/impl/number/parse/NumberParserImpl;-><init>(I)V
 HSPLandroid/icu/impl/number/parse/NumberParserImpl;->addMatcher(Landroid/icu/impl/number/parse/NumberParseMatcher;)V
 HSPLandroid/icu/impl/number/parse/NumberParserImpl;->addMatchers(Ljava/util/Collection;)V
-HSPLandroid/icu/impl/number/parse/NumberParserImpl;->createParserFromProperties(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Z)Landroid/icu/impl/number/parse/NumberParserImpl;
+HSPLandroid/icu/impl/number/parse/NumberParserImpl;->createParserFromProperties(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Z)Landroid/icu/impl/number/parse/NumberParserImpl;+]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/impl/number/parse/NumberParserImpl;Landroid/icu/impl/number/parse/NumberParserImpl;]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;
 HSPLandroid/icu/impl/number/parse/NumberParserImpl;->freeze()V
 HSPLandroid/icu/impl/number/parse/NumberParserImpl;->getParseFlags()I
 HSPLandroid/icu/impl/number/parse/NumberParserImpl;->parse(Ljava/lang/String;IZLandroid/icu/impl/number/parse/ParsedNumber;)V
 HSPLandroid/icu/impl/number/parse/NumberParserImpl;->parseGreedy(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;)V
 HSPLandroid/icu/impl/number/parse/ParsedNumber;-><init>()V
 HSPLandroid/icu/impl/number/parse/ParsedNumber;->clear()V
-HSPLandroid/icu/impl/number/parse/ParsedNumber;->getNumber(I)Ljava/lang/Number;+]Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/impl/number/parse/ParsedNumber;->getNumber(I)Ljava/lang/Number;
 HSPLandroid/icu/impl/number/parse/ParsedNumber;->postProcess()V
 HSPLandroid/icu/impl/number/parse/ParsedNumber;->seenNumber()Z
 HSPLandroid/icu/impl/number/parse/ParsedNumber;->setCharsConsumed(Landroid/icu/impl/StringSegment;)V
@@ -9395,7 +9437,7 @@
 HSPLandroid/icu/impl/number/parse/RequireAffixValidator;->postProcess(Landroid/icu/impl/number/parse/ParsedNumber;)V
 HSPLandroid/icu/impl/number/parse/RequireNumberValidator;-><init>()V
 HSPLandroid/icu/impl/number/parse/RequireNumberValidator;->postProcess(Landroid/icu/impl/number/parse/ParsedNumber;)V
-HSPLandroid/icu/impl/number/parse/ScientificMatcher;-><init>(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;)V+]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/text/UnicodeSet;Landroid/icu/text/UnicodeSet;
+HSPLandroid/icu/impl/number/parse/ScientificMatcher;-><init>(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;)V
 HSPLandroid/icu/impl/number/parse/ScientificMatcher;->getInstance(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;)Landroid/icu/impl/number/parse/ScientificMatcher;
 HSPLandroid/icu/impl/number/parse/ScientificMatcher;->minusSignSet()Landroid/icu/text/UnicodeSet;
 HSPLandroid/icu/impl/number/parse/ScientificMatcher;->plusSignSet()Landroid/icu/text/UnicodeSet;
@@ -9423,7 +9465,7 @@
 HSPLandroid/icu/impl/number/range/StandardPluralRanges;->setCapacity(I)V
 HSPLandroid/icu/lang/UCharacter;->codePointAt(Ljava/lang/CharSequence;I)I
 HSPLandroid/icu/lang/UCharacter;->digit(I)I
-HSPLandroid/icu/lang/UCharacter;->foldCase(II)I+]Landroid/icu/impl/UCaseProps;Landroid/icu/impl/UCaseProps;
+HSPLandroid/icu/lang/UCharacter;->foldCase(II)I
 HSPLandroid/icu/lang/UCharacter;->foldCase(IZ)I
 HSPLandroid/icu/lang/UCharacter;->getPropertyValueEnumNoThrow(ILjava/lang/CharSequence;)I
 HSPLandroid/icu/lang/UCharacter;->getType(I)I
@@ -9439,33 +9481,33 @@
 HSPLandroid/icu/number/IntegerWidth;->truncateAt(I)Landroid/icu/number/IntegerWidth;
 HSPLandroid/icu/number/IntegerWidth;->zeroFillTo(I)Landroid/icu/number/IntegerWidth;
 HSPLandroid/icu/number/LocalizedNumberFormatter;-><init>(Landroid/icu/number/NumberFormatterSettings;ILjava/lang/Object;)V
-HSPLandroid/icu/number/LocalizedNumberFormatter;->computeCompiled()Z
+HSPLandroid/icu/number/LocalizedNumberFormatter;->computeCompiled()Z+]Ljava/util/concurrent/atomic/AtomicLongFieldUpdater;Ljava/util/concurrent/atomic/AtomicLongFieldUpdater$CASUpdater;]Landroid/icu/number/LocalizedNumberFormatter;Landroid/icu/number/LocalizedNumberFormatter;]Ljava/lang/Long;Ljava/lang/Long;
 HSPLandroid/icu/number/LocalizedNumberFormatter;->create(ILjava/lang/Object;)Landroid/icu/number/LocalizedNumberFormatter;
 HSPLandroid/icu/number/LocalizedNumberFormatter;->create(ILjava/lang/Object;)Landroid/icu/number/NumberFormatterSettings;
 HSPLandroid/icu/number/LocalizedNumberFormatter;->format(D)Landroid/icu/number/FormattedNumber;
 HSPLandroid/icu/number/LocalizedNumberFormatter;->format(J)Landroid/icu/number/FormattedNumber;
 HSPLandroid/icu/number/LocalizedNumberFormatter;->format(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/number/FormattedNumber;
-HSPLandroid/icu/number/LocalizedNumberFormatter;->formatImpl(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/number/LocalizedNumberFormatter;->formatImpl(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/number/NumberFormatterImpl;Landroid/icu/number/NumberFormatterImpl;
 HSPLandroid/icu/number/LocalizedNumberFormatter;->getAffixImpl(ZZ)Ljava/lang/String;
 HSPLandroid/icu/number/NumberFormatter;->fromDecimalFormat(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/number/UnlocalizedNumberFormatter;
 HSPLandroid/icu/number/NumberFormatter;->with()Landroid/icu/number/UnlocalizedNumberFormatter;
 HSPLandroid/icu/number/NumberFormatterImpl;-><init>(Landroid/icu/impl/number/MacroProps;)V
-HSPLandroid/icu/number/NumberFormatterImpl;->format(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/number/NumberFormatterImpl;->format(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/number/NumberFormatterImpl;Landroid/icu/number/NumberFormatterImpl;
 HSPLandroid/icu/number/NumberFormatterImpl;->formatStatic(Landroid/icu/impl/number/MacroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;
 HSPLandroid/icu/number/NumberFormatterImpl;->getPrefixSuffix(BLandroid/icu/impl/StandardPlural;Landroid/icu/impl/FormattedStringBuilder;)I
 HSPLandroid/icu/number/NumberFormatterImpl;->getPrefixSuffixImpl(Landroid/icu/impl/number/MicroPropsGenerator;BLandroid/icu/impl/FormattedStringBuilder;)I
 HSPLandroid/icu/number/NumberFormatterImpl;->getPrefixSuffixStatic(Landroid/icu/impl/number/MacroProps;BLandroid/icu/impl/StandardPlural;Landroid/icu/impl/FormattedStringBuilder;)I
-HSPLandroid/icu/number/NumberFormatterImpl;->macrosToMicroGenerator(Landroid/icu/impl/number/MacroProps;Landroid/icu/impl/number/MicroProps;Z)Landroid/icu/impl/number/MicroPropsGenerator;+]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/impl/number/MutablePatternModifier;Landroid/icu/impl/number/MutablePatternModifier;]Landroid/icu/number/Precision;Landroid/icu/number/Precision$FractionRounderImpl;]Landroid/icu/text/NumberingSystem;Landroid/icu/text/NumberingSystem;
-HSPLandroid/icu/number/NumberFormatterImpl;->preProcess(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/number/NumberFormatterImpl;->macrosToMicroGenerator(Landroid/icu/impl/number/MacroProps;Landroid/icu/impl/number/MicroProps;Z)Landroid/icu/impl/number/MicroPropsGenerator;+]Landroid/icu/impl/number/MutablePatternModifier;Landroid/icu/impl/number/MutablePatternModifier;]Landroid/icu/text/NumberingSystem;Landroid/icu/text/NumberingSystem;]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/number/Precision;Landroid/icu/number/Precision$FractionRounderImpl;
+HSPLandroid/icu/number/NumberFormatterImpl;->preProcess(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/impl/number/MicroPropsGenerator;Landroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
 HSPLandroid/icu/number/NumberFormatterImpl;->preProcessUnsafe(Landroid/icu/impl/number/MacroProps;Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
 HSPLandroid/icu/number/NumberFormatterImpl;->unitIsBaseUnit(Landroid/icu/util/MeasureUnit;)Z
 HSPLandroid/icu/number/NumberFormatterImpl;->unitIsCurrency(Landroid/icu/util/MeasureUnit;)Z
 HSPLandroid/icu/number/NumberFormatterImpl;->unitIsPercent(Landroid/icu/util/MeasureUnit;)Z
 HSPLandroid/icu/number/NumberFormatterImpl;->unitIsPermille(Landroid/icu/util/MeasureUnit;)Z
-HSPLandroid/icu/number/NumberFormatterImpl;->writeAffixes(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/FormattedStringBuilder;II)I
-HSPLandroid/icu/number/NumberFormatterImpl;->writeFractionDigits(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I
-HSPLandroid/icu/number/NumberFormatterImpl;->writeIntegerDigits(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I
-HSPLandroid/icu/number/NumberFormatterImpl;->writeNumber(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I
+HSPLandroid/icu/number/NumberFormatterImpl;->writeAffixes(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/FormattedStringBuilder;II)I+]Landroid/icu/impl/number/Padder;Landroid/icu/impl/number/Padder;]Landroid/icu/impl/number/Modifier;Landroid/icu/impl/number/ConstantMultiFieldModifier;,Landroid/icu/impl/number/ConstantAffixModifier;
+HSPLandroid/icu/number/NumberFormatterImpl;->writeFractionDigits(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I+]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/number/NumberFormatterImpl;->writeIntegerDigits(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I+]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/number/NumberFormatterImpl;->writeNumber(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I+]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
 HSPLandroid/icu/number/NumberFormatterSettings;-><init>(Landroid/icu/number/NumberFormatterSettings;ILjava/lang/Object;)V
 HSPLandroid/icu/number/NumberFormatterSettings;->macros(Landroid/icu/impl/number/MacroProps;)Landroid/icu/number/NumberFormatterSettings;
 HSPLandroid/icu/number/NumberFormatterSettings;->perUnit(Landroid/icu/util/MeasureUnit;)Landroid/icu/number/NumberFormatterSettings;
@@ -9473,9 +9515,9 @@
 HSPLandroid/icu/number/NumberFormatterSettings;->unit(Landroid/icu/util/MeasureUnit;)Landroid/icu/number/NumberFormatterSettings;
 HSPLandroid/icu/number/NumberFormatterSettings;->unitWidth(Landroid/icu/number/NumberFormatter$UnitWidth;)Landroid/icu/number/NumberFormatterSettings;
 HSPLandroid/icu/number/NumberPropertyMapper;->create(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/number/UnlocalizedNumberFormatter;
-HSPLandroid/icu/number/NumberPropertyMapper;->oldToNew(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/impl/number/MacroProps;
+HSPLandroid/icu/number/NumberPropertyMapper;->oldToNew(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/impl/number/MacroProps;+]Ljava/math/MathContext;Ljava/math/MathContext;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/number/Precision;Landroid/icu/number/Precision$FractionRounderImpl;,Landroid/icu/number/Precision$CurrencyRounderImpl;]Landroid/icu/number/IntegerWidth;Landroid/icu/number/IntegerWidth;]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;]Landroid/icu/number/CurrencyPrecision;Landroid/icu/number/Precision$CurrencyRounderImpl;]Landroid/icu/util/Currency;Landroid/icu/util/Currency;
 HSPLandroid/icu/number/Precision$FractionRounderImpl;-><init>(II)V
-HSPLandroid/icu/number/Precision$FractionRounderImpl;->apply(Landroid/icu/impl/number/DecimalQuantity;)V
+HSPLandroid/icu/number/Precision$FractionRounderImpl;->apply(Landroid/icu/impl/number/DecimalQuantity;)V+]Landroid/icu/number/Precision$FractionRounderImpl;Landroid/icu/number/Precision$FractionRounderImpl;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
 HSPLandroid/icu/number/Precision$FractionRounderImpl;->createCopy()Landroid/icu/number/Precision$FractionRounderImpl;
 HSPLandroid/icu/number/Precision$FractionRounderImpl;->createCopy()Landroid/icu/number/Precision;
 HSPLandroid/icu/number/Precision;->-$$Nest$smgetDisplayMagnitudeFraction(I)I
@@ -9486,7 +9528,7 @@
 HSPLandroid/icu/number/Precision;->constructFromCurrency(Landroid/icu/number/CurrencyPrecision;Landroid/icu/util/Currency;)Landroid/icu/number/Precision;
 HSPLandroid/icu/number/Precision;->getDisplayMagnitudeFraction(I)I
 HSPLandroid/icu/number/Precision;->getRoundingMagnitudeFraction(I)I
-HSPLandroid/icu/number/Precision;->setResolvedMinFraction(Landroid/icu/impl/number/DecimalQuantity;I)V
+HSPLandroid/icu/number/Precision;->setResolvedMinFraction(Landroid/icu/impl/number/DecimalQuantity;I)V+]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
 HSPLandroid/icu/number/Precision;->withLocaleData(Landroid/icu/util/Currency;)Landroid/icu/number/Precision;
 HSPLandroid/icu/number/Precision;->withMode(Ljava/math/MathContext;)Landroid/icu/number/Precision;
 HSPLandroid/icu/number/Scale;->applyTo(Landroid/icu/impl/number/DecimalQuantity;)V
@@ -9535,7 +9577,7 @@
 HSPLandroid/icu/text/Collator$ServiceShim;-><init>()V
 HSPLandroid/icu/text/Collator;-><init>()V
 HSPLandroid/icu/text/Collator;->clone()Ljava/lang/Object;
-HSPLandroid/icu/text/Collator;->getInstance(Landroid/icu/util/ULocale;)Landroid/icu/text/Collator;
+HSPLandroid/icu/text/Collator;->getInstance(Landroid/icu/util/ULocale;)Landroid/icu/text/Collator;+]Landroid/icu/text/Collator$ServiceShim;Landroid/icu/text/CollatorServiceShim;]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/util/ULocale;Landroid/icu/util/ULocale;
 HSPLandroid/icu/text/Collator;->getInstance(Ljava/util/Locale;)Landroid/icu/text/Collator;
 HSPLandroid/icu/text/Collator;->getShim()Landroid/icu/text/Collator$ServiceShim;
 HSPLandroid/icu/text/CollatorServiceShim$CService$1CollatorFactory;->handleCreate(Landroid/icu/util/ULocale;ILandroid/icu/impl/ICUService;)Ljava/lang/Object;
@@ -9543,13 +9585,13 @@
 HSPLandroid/icu/text/CollatorServiceShim;-><init>()V
 HSPLandroid/icu/text/CollatorServiceShim;->getInstance(Landroid/icu/util/ULocale;)Landroid/icu/text/Collator;
 HSPLandroid/icu/text/CollatorServiceShim;->makeInstance(Landroid/icu/util/ULocale;)Landroid/icu/text/Collator;
-HSPLandroid/icu/text/ConstrainedFieldPosition;-><init>()V
+HSPLandroid/icu/text/ConstrainedFieldPosition;-><init>()V+]Landroid/icu/text/ConstrainedFieldPosition;Landroid/icu/text/ConstrainedFieldPosition;
 HSPLandroid/icu/text/ConstrainedFieldPosition;->constrainField(Ljava/text/Format$Field;)V
 HSPLandroid/icu/text/ConstrainedFieldPosition;->getField()Ljava/text/Format$Field;
 HSPLandroid/icu/text/ConstrainedFieldPosition;->getFieldValue()Ljava/lang/Object;
 HSPLandroid/icu/text/ConstrainedFieldPosition;->getLimit()I
 HSPLandroid/icu/text/ConstrainedFieldPosition;->getStart()I
-HSPLandroid/icu/text/ConstrainedFieldPosition;->matchesField(Ljava/text/Format$Field;Ljava/lang/Object;)Z
+HSPLandroid/icu/text/ConstrainedFieldPosition;->matchesField(Ljava/text/Format$Field;Ljava/lang/Object;)Z+]Landroid/icu/text/ConstrainedFieldPosition$ConstraintType;Landroid/icu/text/ConstrainedFieldPosition$ConstraintType;
 HSPLandroid/icu/text/ConstrainedFieldPosition;->reset()V
 HSPLandroid/icu/text/ConstrainedFieldPosition;->setState(Ljava/text/Format$Field;Ljava/lang/Object;II)V
 HSPLandroid/icu/text/CurrencyDisplayNames;-><init>()V
@@ -9602,6 +9644,7 @@
 HSPLandroid/icu/text/DateFormatSymbols;->initializeData(Landroid/icu/util/ULocale;Landroid/icu/impl/ICUResourceBundle;Ljava/lang/String;)V
 HSPLandroid/icu/text/DateFormatSymbols;->initializeData(Landroid/icu/util/ULocale;Landroid/icu/impl/ICUResourceBundle;Ljava/lang/String;Landroid/icu/text/DateFormatSymbols$AospExtendedDateFormatSymbols;)V
 HSPLandroid/icu/text/DateFormatSymbols;->initializeData(Landroid/icu/util/ULocale;Ljava/lang/String;)V
+HSPLandroid/icu/text/DateFormatSymbols;->loadDayPeriodStrings(Ljava/util/Map;)[Ljava/lang/String;
 HSPLandroid/icu/text/DateFormatSymbols;->setLocale(Landroid/icu/util/ULocale;Landroid/icu/util/ULocale;)V
 HSPLandroid/icu/text/DateFormatSymbols;->setTimeSeparatorString(Ljava/lang/String;)V
 HSPLandroid/icu/text/DateIntervalFormat;-><init>(Ljava/lang/String;Landroid/icu/util/ULocale;Landroid/icu/text/SimpleDateFormat;)V
@@ -9647,7 +9690,7 @@
 HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->getBasePattern()Ljava/lang/String;
 HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->getDistance(Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;ILandroid/icu/text/DateTimePatternGenerator$DistanceInfo;)I
 HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->getFieldMask()I
-HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->set(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$FormatParser;Z)Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;
+HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->set(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$FormatParser;Z)Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/text/DateTimePatternGenerator$VariableField;Landroid/icu/text/DateTimePatternGenerator$VariableField;]Landroid/icu/text/DateTimePatternGenerator$FormatParser;Landroid/icu/text/DateTimePatternGenerator$FormatParser;]Landroid/icu/text/DateTimePatternGenerator$SkeletonFields;Landroid/icu/text/DateTimePatternGenerator$SkeletonFields;]Ljava/util/List;Ljava/util/ArrayList;]Ljava/util/Iterator;Ljava/util/ArrayList$Itr;
 HSPLandroid/icu/text/DateTimePatternGenerator$DisplayWidth;->cldrKey()Ljava/lang/String;
 HSPLandroid/icu/text/DateTimePatternGenerator$DistanceInfo;-><init>()V
 HSPLandroid/icu/text/DateTimePatternGenerator$DistanceInfo;->addExtra(I)V
@@ -9659,7 +9702,7 @@
 HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->getItems()Ljava/util/List;
 HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->quoteLiteral(Ljava/lang/String;)Ljava/lang/Object;
 HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->set(Ljava/lang/String;)Landroid/icu/text/DateTimePatternGenerator$FormatParser;
-HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->set(Ljava/lang/String;Z)Landroid/icu/text/DateTimePatternGenerator$FormatParser;
+HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->set(Ljava/lang/String;Z)Landroid/icu/text/DateTimePatternGenerator$FormatParser;+]Ljava/lang/String;Ljava/lang/String;]Ljava/util/List;Ljava/util/ArrayList;]Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;]Landroid/icu/impl/PatternTokenizer;Landroid/icu/impl/PatternTokenizer;
 HSPLandroid/icu/text/DateTimePatternGenerator$PatternInfo;-><init>()V
 HSPLandroid/icu/text/DateTimePatternGenerator$PatternWithMatcher;-><init>(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;)V
 HSPLandroid/icu/text/DateTimePatternGenerator$PatternWithSkeletonFlag;-><init>(Ljava/lang/String;Z)V
@@ -9702,9 +9745,9 @@
 HSPLandroid/icu/text/DateTimePatternGenerator;->getBestPattern(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;I)Ljava/lang/String;
 HSPLandroid/icu/text/DateTimePatternGenerator;->getBestPattern(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;IZ)Ljava/lang/String;
 HSPLandroid/icu/text/DateTimePatternGenerator;->getBestRaw(Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;ILandroid/icu/text/DateTimePatternGenerator$DistanceInfo;Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;)Landroid/icu/text/DateTimePatternGenerator$PatternWithMatcher;
-HSPLandroid/icu/text/DateTimePatternGenerator;->getCLDRFieldAndWidthNumber(Landroid/icu/impl/UResource$Key;)I
+HSPLandroid/icu/text/DateTimePatternGenerator;->getCLDRFieldAndWidthNumber(Landroid/icu/impl/UResource$Key;)I+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/UResource$Key;Landroid/icu/impl/UResource$Key;
 HSPLandroid/icu/text/DateTimePatternGenerator;->getCalendarTypeToUse(Landroid/icu/util/ULocale;)Ljava/lang/String;
-HSPLandroid/icu/text/DateTimePatternGenerator;->getCanonicalIndex(Ljava/lang/String;Z)I
+HSPLandroid/icu/text/DateTimePatternGenerator;->getCanonicalIndex(Ljava/lang/String;Z)I+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/icu/text/DateTimePatternGenerator;->getDateTimeFormat()Ljava/lang/String;
 HSPLandroid/icu/text/DateTimePatternGenerator;->getFieldDisplayName(ILandroid/icu/text/DateTimePatternGenerator$DisplayWidth;)Ljava/lang/String;
 HSPLandroid/icu/text/DateTimePatternGenerator;->getFilteredPattern(Landroid/icu/text/DateTimePatternGenerator$FormatParser;Ljava/util/BitSet;)Ljava/lang/String;
@@ -9727,8 +9770,8 @@
 HSPLandroid/icu/text/DecimalFormat;-><init>(Ljava/lang/String;Landroid/icu/text/DecimalFormatSymbols;)V
 HSPLandroid/icu/text/DecimalFormat;-><init>(Ljava/lang/String;Landroid/icu/text/DecimalFormatSymbols;I)V
 HSPLandroid/icu/text/DecimalFormat;->clone()Ljava/lang/Object;
-HSPLandroid/icu/text/DecimalFormat;->fieldPositionHelper(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;Ljava/text/FieldPosition;I)V
-HSPLandroid/icu/text/DecimalFormat;->format(DLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;
+HSPLandroid/icu/text/DecimalFormat;->fieldPositionHelper(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;Ljava/text/FieldPosition;I)V+]Ljava/text/FieldPosition;Ljava/text/DontCareFieldPosition;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/text/DecimalFormat;->format(DLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;+]Landroid/icu/number/LocalizedNumberFormatter;Landroid/icu/number/LocalizedNumberFormatter;]Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;
 HSPLandroid/icu/text/DecimalFormat;->format(JLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;
 HSPLandroid/icu/text/DecimalFormat;->getDecimalFormatSymbols()Landroid/icu/text/DecimalFormatSymbols;
 HSPLandroid/icu/text/DecimalFormat;->getMaximumFractionDigits()I
@@ -9743,7 +9786,7 @@
 HSPLandroid/icu/text/DecimalFormat;->isParseBigDecimal()Z
 HSPLandroid/icu/text/DecimalFormat;->isParseIntegerOnly()Z
 HSPLandroid/icu/text/DecimalFormat;->parse(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/lang/Number;
-HSPLandroid/icu/text/DecimalFormat;->refreshFormatter()V
+HSPLandroid/icu/text/DecimalFormat;->refreshFormatter()V+]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/number/UnlocalizedNumberFormatter;Landroid/icu/number/UnlocalizedNumberFormatter;]Landroid/icu/text/DecimalFormat;Landroid/icu/text/DecimalFormat;
 HSPLandroid/icu/text/DecimalFormat;->setCurrency(Landroid/icu/util/Currency;)V
 HSPLandroid/icu/text/DecimalFormat;->setDecimalSeparatorAlwaysShown(Z)V
 HSPLandroid/icu/text/DecimalFormat;->setGroupingUsed(Z)V
@@ -9755,7 +9798,7 @@
 HSPLandroid/icu/text/DecimalFormat;->setParseStrictMode(Landroid/icu/impl/number/DecimalFormatProperties$ParseMode;)V
 HSPLandroid/icu/text/DecimalFormat;->setPropertiesFromPattern(Ljava/lang/String;I)V
 HSPLandroid/icu/text/DecimalFormat;->toNumberFormatter()Landroid/icu/number/LocalizedNumberFormatter;
-HSPLandroid/icu/text/DecimalFormat;->toPattern()Ljava/lang/String;+]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;
+HSPLandroid/icu/text/DecimalFormat;->toPattern()Ljava/lang/String;
 HSPLandroid/icu/text/DecimalFormatSymbols$1;->createInstance(Landroid/icu/util/ULocale;Ljava/lang/Void;)Landroid/icu/text/DecimalFormatSymbols$CacheData;
 HSPLandroid/icu/text/DecimalFormatSymbols$1;->createInstance(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/icu/text/DecimalFormatSymbols$CacheData;-><init>(Landroid/icu/util/ULocale;[Ljava/lang/String;[Ljava/lang/String;)V
@@ -9797,7 +9840,7 @@
 HSPLandroid/icu/text/DecimalFormatSymbols;->getULocale()Landroid/icu/util/ULocale;
 HSPLandroid/icu/text/DecimalFormatSymbols;->getZeroDigit()C
 HSPLandroid/icu/text/DecimalFormatSymbols;->initSpacingInfo(Landroid/icu/impl/CurrencyData$CurrencySpacingInfo;)V
-HSPLandroid/icu/text/DecimalFormatSymbols;->initialize(Landroid/icu/util/ULocale;Landroid/icu/text/NumberingSystem;)V
+HSPLandroid/icu/text/DecimalFormatSymbols;->initialize(Landroid/icu/util/ULocale;Landroid/icu/text/NumberingSystem;)V+]Landroid/icu/impl/CurrencyData$CurrencyDisplayInfoProvider;Landroid/icu/impl/ICUCurrencyDisplayInfoProvider;]Landroid/icu/util/ULocale;Landroid/icu/util/ULocale;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/impl/CurrencyData$CurrencyDisplayInfo;Landroid/icu/impl/ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo;
 HSPLandroid/icu/text/DecimalFormatSymbols;->loadData(Landroid/icu/util/ULocale;)Landroid/icu/text/DecimalFormatSymbols$CacheData;
 HSPLandroid/icu/text/DecimalFormatSymbols;->setApproximatelySignString(Ljava/lang/String;)V
 HSPLandroid/icu/text/DecimalFormatSymbols;->setCurrency(Landroid/icu/util/Currency;)V
@@ -9993,7 +10036,7 @@
 HSPLandroid/icu/text/RuleBasedCollator;->clone()Ljava/lang/Object;
 HSPLandroid/icu/text/RuleBasedCollator;->cloneAsThawed()Landroid/icu/text/RuleBasedCollator;
 HSPLandroid/icu/text/RuleBasedCollator;->compare(Ljava/lang/String;Ljava/lang/String;)I
-HSPLandroid/icu/text/RuleBasedCollator;->doCompare(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)I
+HSPLandroid/icu/text/RuleBasedCollator;->doCompare(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)I+]Landroid/icu/impl/coll/CollationData;Landroid/icu/impl/coll/CollationData;]Landroid/icu/impl/coll/SharedObject$Reference;Landroid/icu/impl/coll/SharedObject$Reference;]Ljava/lang/CharSequence;Ljava/lang/String;]Landroid/icu/impl/coll/CollationSettings;Landroid/icu/impl/coll/CollationSettings;
 HSPLandroid/icu/text/RuleBasedCollator;->freeze()Landroid/icu/text/Collator;
 HSPLandroid/icu/text/RuleBasedCollator;->getCollationBuffer()Landroid/icu/text/RuleBasedCollator$CollationBuffer;
 HSPLandroid/icu/text/RuleBasedCollator;->getCollationKey(Ljava/lang/String;)Landroid/icu/text/CollationKey;
@@ -10071,7 +10114,7 @@
 HSPLandroid/icu/text/UnicodeSet;->clear()Landroid/icu/text/UnicodeSet;
 HSPLandroid/icu/text/UnicodeSet;->clone()Ljava/lang/Object;
 HSPLandroid/icu/text/UnicodeSet;->compact()Landroid/icu/text/UnicodeSet;
-HSPLandroid/icu/text/UnicodeSet;->contains(I)Z
+HSPLandroid/icu/text/UnicodeSet;->contains(I)Z+]Landroid/icu/impl/BMPSet;Landroid/icu/impl/BMPSet;
 HSPLandroid/icu/text/UnicodeSet;->contains(Ljava/lang/CharSequence;)Z
 HSPLandroid/icu/text/UnicodeSet;->containsAll(Ljava/lang/String;)Z
 HSPLandroid/icu/text/UnicodeSet;->findCodePoint(I)I
@@ -10372,17 +10415,19 @@
 HSPLandroid/icu/util/ULocale$Builder;->setRegion(Ljava/lang/String;)Landroid/icu/util/ULocale$Builder;
 HSPLandroid/icu/util/ULocale$JDKLocaleHelper;->getDefault(Landroid/icu/util/ULocale$Category;)Ljava/util/Locale;
 HSPLandroid/icu/util/ULocale$JDKLocaleHelper;->toLocale(Landroid/icu/util/ULocale;)Ljava/util/Locale;
-HSPLandroid/icu/util/ULocale$JDKLocaleHelper;->toULocale(Ljava/util/Locale;)Landroid/icu/util/ULocale;
+HSPLandroid/icu/util/ULocale$JDKLocaleHelper;->toULocale(Ljava/util/Locale;)Landroid/icu/util/ULocale;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/Locale;Ljava/util/Locale;]Ljava/util/Set;Ljava/util/Collections$EmptySet;
 HSPLandroid/icu/util/ULocale;->-$$Nest$smgetInstance(Landroid/icu/impl/locale/BaseLocale;Landroid/icu/impl/locale/LocaleExtensions;)Landroid/icu/util/ULocale;
 HSPLandroid/icu/util/ULocale;-><init>(Ljava/lang/String;)V
 HSPLandroid/icu/util/ULocale;-><init>(Ljava/lang/String;Ljava/util/Locale;)V
 HSPLandroid/icu/util/ULocale;-><init>(Ljava/lang/String;Ljava/util/Locale;Landroid/icu/util/ULocale-IA;)V
 HSPLandroid/icu/util/ULocale;->addLikelySubtags(Landroid/icu/util/ULocale;)Landroid/icu/util/ULocale;
 HSPLandroid/icu/util/ULocale;->appendTag(Ljava/lang/String;Ljava/lang/StringBuilder;)V
-HSPLandroid/icu/util/ULocale;->base()Landroid/icu/impl/locale/BaseLocale;
+HSPLandroid/icu/util/ULocale;->base()Landroid/icu/impl/locale/BaseLocale;+]Landroid/icu/util/ULocale;Landroid/icu/util/ULocale;]Landroid/icu/impl/LocaleIDParser;Landroid/icu/impl/LocaleIDParser;
 HSPLandroid/icu/util/ULocale;->canonicalize(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/icu/util/ULocale;->createCanonical(Ljava/lang/String;)Landroid/icu/util/ULocale;
+HSPLandroid/icu/util/ULocale;->createLikelySubtagsString(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/icu/util/ULocale;->createTagString(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/icu/util/ULocale;->createTagString(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/icu/util/ULocale;->equals(Ljava/lang/Object;)Z
 HSPLandroid/icu/util/ULocale;->forLocale(Ljava/util/Locale;)Landroid/icu/util/ULocale;
 HSPLandroid/icu/util/ULocale;->getBaseName()Ljava/lang/String;
@@ -10397,7 +10442,7 @@
 HSPLandroid/icu/util/ULocale;->getKeywords(Ljava/lang/String;)Ljava/util/Iterator;
 HSPLandroid/icu/util/ULocale;->getLanguage()Ljava/lang/String;
 HSPLandroid/icu/util/ULocale;->getName()Ljava/lang/String;
-HSPLandroid/icu/util/ULocale;->getName(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/icu/util/ULocale;->getName(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/CacheBase;Landroid/icu/util/ULocale$1;
 HSPLandroid/icu/util/ULocale;->getRegionForSupplementalData(Landroid/icu/util/ULocale;Z)Ljava/lang/String;
 HSPLandroid/icu/util/ULocale;->getScript()Ljava/lang/String;
 HSPLandroid/icu/util/ULocale;->getScript(Ljava/lang/String;)Ljava/lang/String;
@@ -10408,6 +10453,7 @@
 HSPLandroid/icu/util/ULocale;->isEmptyString(Ljava/lang/String;)Z
 HSPLandroid/icu/util/ULocale;->isKnownCanonicalizedLocale(Ljava/lang/String;)Z
 HSPLandroid/icu/util/ULocale;->isRightToLeft()Z
+HSPLandroid/icu/util/ULocale;->lookupLikelySubtags(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/icu/util/ULocale;->lscvToID(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/icu/util/ULocale;->parseTagString(Ljava/lang/String;[Ljava/lang/String;)I
 HSPLandroid/icu/util/ULocale;->setKeywordValue(Ljava/lang/String;Ljava/lang/String;)Landroid/icu/util/ULocale;
@@ -10480,7 +10526,7 @@
 HSPLandroid/location/Location;->toString()Ljava/lang/String;
 HSPLandroid/location/Location;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/media/AudioAttributes$1;->createFromParcel(Landroid/os/Parcel;)Landroid/media/AudioAttributes;
-HSPLandroid/media/AudioAttributes$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/media/AudioAttributes$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/media/AudioAttributes$1;Landroid/media/AudioAttributes$1;
 HSPLandroid/media/AudioAttributes$Builder;-><init>()V
 HSPLandroid/media/AudioAttributes$Builder;-><init>(Landroid/media/AudioAttributes;)V
 HSPLandroid/media/AudioAttributes$Builder;->addTag(Ljava/lang/String;)Landroid/media/AudioAttributes$Builder;
@@ -10506,7 +10552,7 @@
 HSPLandroid/media/AudioAttributes;->-$$Nest$fputmUsage(Landroid/media/AudioAttributes;I)V
 HSPLandroid/media/AudioAttributes;-><init>()V
 HSPLandroid/media/AudioAttributes;-><init>(Landroid/media/AudioAttributes-IA;)V
-HSPLandroid/media/AudioAttributes;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/media/AudioAttributes;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/media/AudioAttributes;->areHapticChannelsMuted()Z
 HSPLandroid/media/AudioAttributes;->equals(Ljava/lang/Object;)Z
 HSPLandroid/media/AudioAttributes;->getAllFlags()I
@@ -10642,7 +10688,7 @@
 HSPLandroid/media/AudioPlaybackConfiguration;->getAudioAttributes()Landroid/media/AudioAttributes;
 HSPLandroid/media/AudioPlaybackConfiguration;->isActive()Z
 HSPLandroid/media/AudioPort$$ExternalSyntheticLambda0;->applyAsInt(Ljava/lang/Object;)I
-HSPLandroid/media/AudioPort;-><init>(Landroid/media/AudioHandle;ILjava/lang/String;Ljava/util/List;[Landroid/media/AudioGain;Ljava/util/List;)V
+HSPLandroid/media/AudioPort;-><init>(Landroid/media/AudioHandle;ILjava/lang/String;Ljava/util/List;[Landroid/media/AudioGain;Ljava/util/List;)V+]Ljava/util/List;Ljava/util/ArrayList;]Ljava/util/stream/Stream;Ljava/util/stream/IntPipeline$4;,Ljava/util/stream/ReferencePipeline$Head;]Ljava/util/stream/IntStream;Ljava/util/stream/IntPipeline$Head;,Ljava/util/stream/ReferencePipeline$4;]Ljava/util/Iterator;Ljava/util/ArrayList$Itr;]Landroid/media/AudioProfile;Landroid/media/AudioProfile;]Ljava/util/Set;Ljava/util/HashSet;
 HSPLandroid/media/AudioPort;-><init>(Landroid/media/AudioHandle;ILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V
 HSPLandroid/media/AudioPort;->handle()Landroid/media/AudioHandle;
 HSPLandroid/media/AudioPort;->id()I
@@ -10762,8 +10808,8 @@
 HSPLandroid/media/MediaCodec$BufferMap;-><init>()V
 HSPLandroid/media/MediaCodec$BufferMap;-><init>(Landroid/media/MediaCodec$BufferMap-IA;)V
 HSPLandroid/media/MediaCodec$BufferMap;->clear()V
-HSPLandroid/media/MediaCodec$BufferMap;->put(ILjava/nio/ByteBuffer;)V
-HSPLandroid/media/MediaCodec$BufferMap;->remove(I)V
+HSPLandroid/media/MediaCodec$BufferMap;->put(ILjava/nio/ByteBuffer;)V+]Landroid/media/MediaCodec$BufferMap$CodecBuffer;Landroid/media/MediaCodec$BufferMap$CodecBuffer;]Ljava/util/Map;Ljava/util/HashMap;
+HSPLandroid/media/MediaCodec$BufferMap;->remove(I)V+]Landroid/media/MediaCodec$BufferMap$CodecBuffer;Landroid/media/MediaCodec$BufferMap$CodecBuffer;]Ljava/util/Map;Ljava/util/HashMap;
 HSPLandroid/media/MediaCodec$CryptoInfo$Pattern;-><init>(II)V
 HSPLandroid/media/MediaCodec$CryptoInfo$Pattern;->set(II)V
 HSPLandroid/media/MediaCodec$CryptoInfo;-><init>()V
@@ -10775,18 +10821,18 @@
 HSPLandroid/media/MediaCodec;->configure(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;Landroid/os/IHwBinder;I)V
 HSPLandroid/media/MediaCodec;->createByCodecName(Ljava/lang/String;)Landroid/media/MediaCodec;
 HSPLandroid/media/MediaCodec;->dequeueInputBuffer(J)I
-HSPLandroid/media/MediaCodec;->dequeueOutputBuffer(Landroid/media/MediaCodec$BufferInfo;J)I
+HSPLandroid/media/MediaCodec;->dequeueOutputBuffer(Landroid/media/MediaCodec$BufferInfo;J)I+]Landroid/media/MediaCodec$BufferInfo;Landroid/media/MediaCodec$BufferInfo;]Ljava/util/Map;Ljava/util/HashMap;
 HSPLandroid/media/MediaCodec;->finalize()V
 HSPLandroid/media/MediaCodec;->freeAllTrackedBuffers()V
-HSPLandroid/media/MediaCodec;->getInputBuffer(I)Ljava/nio/ByteBuffer;
-HSPLandroid/media/MediaCodec;->getOutputBuffer(I)Ljava/nio/ByteBuffer;
+HSPLandroid/media/MediaCodec;->getInputBuffer(I)Ljava/nio/ByteBuffer;+]Landroid/media/MediaCodec$BufferMap;Landroid/media/MediaCodec$BufferMap;
+HSPLandroid/media/MediaCodec;->getOutputBuffer(I)Ljava/nio/ByteBuffer;+]Landroid/media/MediaCodec$BufferMap;Landroid/media/MediaCodec$BufferMap;
 HSPLandroid/media/MediaCodec;->getOutputFormat()Landroid/media/MediaFormat;
-HSPLandroid/media/MediaCodec;->lockAndGetContext()J
-HSPLandroid/media/MediaCodec;->queueInputBuffer(IIIJI)V
+HSPLandroid/media/MediaCodec;->lockAndGetContext()J+]Ljava/util/concurrent/locks/Lock;Ljava/util/concurrent/locks/ReentrantLock;
+HSPLandroid/media/MediaCodec;->queueInputBuffer(IIIJI)V+]Landroid/media/MediaCodec$BufferMap;Landroid/media/MediaCodec$BufferMap;
 HSPLandroid/media/MediaCodec;->release()V
 HSPLandroid/media/MediaCodec;->releaseOutputBuffer(IZ)V
-HSPLandroid/media/MediaCodec;->releaseOutputBufferInternal(IZZJ)V
-HSPLandroid/media/MediaCodec;->setAndUnlockContext(J)V
+HSPLandroid/media/MediaCodec;->releaseOutputBufferInternal(IZZJ)V+]Landroid/media/MediaCodec$BufferMap;Landroid/media/MediaCodec$BufferMap;]Ljava/util/Map;Ljava/util/HashMap;
+HSPLandroid/media/MediaCodec;->setAndUnlockContext(J)V+]Ljava/util/concurrent/locks/Lock;Ljava/util/concurrent/locks/ReentrantLock;
 HSPLandroid/media/MediaCodec;->start()V
 HSPLandroid/media/MediaCodec;->stop()V
 HSPLandroid/media/MediaCodecInfo$AudioCapabilities;->applyLevelLimits()V
@@ -11281,6 +11327,10 @@
 HSPLandroid/metrics/LogMaker;->setComponentName(Landroid/content/ComponentName;)Landroid/metrics/LogMaker;
 HSPLandroid/metrics/LogMaker;->setSubtype(I)Landroid/metrics/LogMaker;
 HSPLandroid/metrics/LogMaker;->setType(I)Landroid/metrics/LogMaker;
+HSPLandroid/multiuser/FeatureFlagsImpl;-><init>()V
+HSPLandroid/multiuser/FeatureFlagsImpl;->enableSystemUserOnlyForServicesAndProviders()Z
+HSPLandroid/multiuser/Flags;-><clinit>()V
+HSPLandroid/multiuser/Flags;->enableSystemUserOnlyForServicesAndProviders()Z+]Landroid/multiuser/FeatureFlags;Landroid/multiuser/FeatureFlagsImpl;
 HSPLandroid/net/Credentials;-><init>(III)V
 HSPLandroid/net/Credentials;->getPid()I
 HSPLandroid/net/Credentials;->getUid()I
@@ -11373,8 +11423,8 @@
 HSPLandroid/net/TelephonyNetworkSpecifier;->hashCode()I
 HSPLandroid/net/TelephonyNetworkSpecifier;->toString()Ljava/lang/String;
 HSPLandroid/net/TelephonyNetworkSpecifier;->writeToParcel(Landroid/os/Parcel;I)V
-HSPLandroid/net/Uri$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/Uri;
-HSPLandroid/net/Uri$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/net/Uri$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/Uri;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/net/Uri$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/net/Uri$1;Landroid/net/Uri$1;
 HSPLandroid/net/Uri$1;->newArray(I)[Landroid/net/Uri;
 HSPLandroid/net/Uri$1;->newArray(I)[Ljava/lang/Object;
 HSPLandroid/net/Uri$AbstractHierarchicalUri;-><init>()V
@@ -11409,11 +11459,11 @@
 HSPLandroid/net/Uri$Builder;->path(Ljava/lang/String;)Landroid/net/Uri$Builder;
 HSPLandroid/net/Uri$Builder;->query(Landroid/net/Uri$Part;)Landroid/net/Uri$Builder;
 HSPLandroid/net/Uri$Builder;->scheme(Ljava/lang/String;)Landroid/net/Uri$Builder;
-HSPLandroid/net/Uri$Builder;->toString()Ljava/lang/String;
+HSPLandroid/net/Uri$Builder;->toString()Ljava/lang/String;+]Landroid/net/Uri$Builder;Landroid/net/Uri$Builder;]Landroid/net/Uri;Landroid/net/Uri$HierarchicalUri;
 HSPLandroid/net/Uri$HierarchicalUri;-><init>(Ljava/lang/String;Landroid/net/Uri$Part;Landroid/net/Uri$PathPart;Landroid/net/Uri$Part;Landroid/net/Uri$Part;)V
-HSPLandroid/net/Uri$HierarchicalUri;->appendSspTo(Ljava/lang/StringBuilder;)V
-HSPLandroid/net/Uri$HierarchicalUri;->buildUpon()Landroid/net/Uri$Builder;
-HSPLandroid/net/Uri$HierarchicalUri;->generatePath(Landroid/net/Uri$PathPart;)Landroid/net/Uri$PathPart;+]Landroid/net/Uri$Part;Landroid/net/Uri$Part$EmptyPart;,Landroid/net/Uri$Part;
+HSPLandroid/net/Uri$HierarchicalUri;->appendSspTo(Ljava/lang/StringBuilder;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/net/Uri$Part;Landroid/net/Uri$Part;,Landroid/net/Uri$Part$EmptyPart;]Landroid/net/Uri$PathPart;Landroid/net/Uri$PathPart;
+HSPLandroid/net/Uri$HierarchicalUri;->buildUpon()Landroid/net/Uri$Builder;+]Landroid/net/Uri$Builder;Landroid/net/Uri$Builder;
+HSPLandroid/net/Uri$HierarchicalUri;->generatePath(Landroid/net/Uri$PathPart;)Landroid/net/Uri$PathPart;+]Landroid/net/Uri$Part;Landroid/net/Uri$Part$EmptyPart;,Landroid/net/Uri$Part;]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/net/Uri$HierarchicalUri;->getAuthority()Ljava/lang/String;
 HSPLandroid/net/Uri$HierarchicalUri;->getEncodedAuthority()Ljava/lang/String;
 HSPLandroid/net/Uri$HierarchicalUri;->getEncodedFragment()Ljava/lang/String;
@@ -11426,7 +11476,7 @@
 HSPLandroid/net/Uri$HierarchicalUri;->getScheme()Ljava/lang/String;
 HSPLandroid/net/Uri$HierarchicalUri;->getSchemeSpecificPart()Ljava/lang/String;
 HSPLandroid/net/Uri$HierarchicalUri;->isHierarchical()Z
-HSPLandroid/net/Uri$HierarchicalUri;->makeUriString()Ljava/lang/String;
+HSPLandroid/net/Uri$HierarchicalUri;->makeUriString()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/net/Uri$Part;Landroid/net/Uri$Part$EmptyPart;
 HSPLandroid/net/Uri$HierarchicalUri;->readFrom(Landroid/os/Parcel;)Landroid/net/Uri;
 HSPLandroid/net/Uri$HierarchicalUri;->toString()Ljava/lang/String;
 HSPLandroid/net/Uri$HierarchicalUri;->writeToParcel(Landroid/os/Parcel;I)V
@@ -11447,13 +11497,13 @@
 HSPLandroid/net/Uri$Part;->nonNull(Landroid/net/Uri$Part;)Landroid/net/Uri$Part;
 HSPLandroid/net/Uri$PathPart;-><init>(Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/net/Uri$PathPart;->appendDecodedSegment(Landroid/net/Uri$PathPart;Ljava/lang/String;)Landroid/net/Uri$PathPart;
-HSPLandroid/net/Uri$PathPart;->appendEncodedSegment(Landroid/net/Uri$PathPart;Ljava/lang/String;)Landroid/net/Uri$PathPart;
+HSPLandroid/net/Uri$PathPart;->appendEncodedSegment(Landroid/net/Uri$PathPart;Ljava/lang/String;)Landroid/net/Uri$PathPart;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/net/Uri$PathPart;Landroid/net/Uri$PathPart;
 HSPLandroid/net/Uri$PathPart;->from(Ljava/lang/String;Ljava/lang/String;)Landroid/net/Uri$PathPart;
 HSPLandroid/net/Uri$PathPart;->fromDecoded(Ljava/lang/String;)Landroid/net/Uri$PathPart;
 HSPLandroid/net/Uri$PathPart;->fromEncoded(Ljava/lang/String;)Landroid/net/Uri$PathPart;
 HSPLandroid/net/Uri$PathPart;->getEncoded()Ljava/lang/String;
-HSPLandroid/net/Uri$PathPart;->getPathSegments()Landroid/net/Uri$PathSegments;
-HSPLandroid/net/Uri$PathPart;->makeAbsolute(Landroid/net/Uri$PathPart;)Landroid/net/Uri$PathPart;
+HSPLandroid/net/Uri$PathPart;->getPathSegments()Landroid/net/Uri$PathSegments;+]Ljava/lang/String;Ljava/lang/String;]Landroid/net/Uri$PathSegmentsBuilder;Landroid/net/Uri$PathSegmentsBuilder;]Landroid/net/Uri$PathPart;Landroid/net/Uri$PathPart;
+HSPLandroid/net/Uri$PathPart;->makeAbsolute(Landroid/net/Uri$PathPart;)Landroid/net/Uri$PathPart;+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/net/Uri$PathSegments;-><init>([Ljava/lang/String;I)V
 HSPLandroid/net/Uri$PathSegments;->get(I)Ljava/lang/Object;
 HSPLandroid/net/Uri$PathSegments;->get(I)Ljava/lang/String;
@@ -11462,9 +11512,9 @@
 HSPLandroid/net/Uri$PathSegmentsBuilder;->build()Landroid/net/Uri$PathSegments;
 HSPLandroid/net/Uri$StringUri;-><init>(Ljava/lang/String;)V
 HSPLandroid/net/Uri$StringUri;-><init>(Ljava/lang/String;Landroid/net/Uri$StringUri-IA;)V
-HSPLandroid/net/Uri$StringUri;->buildUpon()Landroid/net/Uri$Builder;
-HSPLandroid/net/Uri$StringUri;->findFragmentSeparator()I
-HSPLandroid/net/Uri$StringUri;->findSchemeSeparator()I
+HSPLandroid/net/Uri$StringUri;->buildUpon()Landroid/net/Uri$Builder;+]Landroid/net/Uri$Builder;Landroid/net/Uri$Builder;]Landroid/net/Uri$StringUri;Landroid/net/Uri$StringUri;
+HSPLandroid/net/Uri$StringUri;->findFragmentSeparator()I+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/net/Uri$StringUri;->findSchemeSeparator()I+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->getAuthority()Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->getAuthorityPart()Landroid/net/Uri$Part;
 HSPLandroid/net/Uri$StringUri;->getEncodedAuthority()Ljava/lang/String;
@@ -11482,11 +11532,11 @@
 HSPLandroid/net/Uri$StringUri;->getSchemeSpecificPart()Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->isHierarchical()Z
 HSPLandroid/net/Uri$StringUri;->isRelative()Z
-HSPLandroid/net/Uri$StringUri;->parseAuthority(Ljava/lang/String;I)Ljava/lang/String;
+HSPLandroid/net/Uri$StringUri;->parseAuthority(Ljava/lang/String;I)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->parseFragment()Ljava/lang/String;
-HSPLandroid/net/Uri$StringUri;->parsePath()Ljava/lang/String;
+HSPLandroid/net/Uri$StringUri;->parsePath()Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->parsePath(Ljava/lang/String;I)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
-HSPLandroid/net/Uri$StringUri;->parseQuery()Ljava/lang/String;
+HSPLandroid/net/Uri$StringUri;->parseQuery()Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->parseScheme()Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->toString()Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->writeToParcel(Landroid/os/Parcel;I)V
@@ -11503,8 +11553,8 @@
 HSPLandroid/net/Uri;->fromFile(Ljava/io/File;)Landroid/net/Uri;
 HSPLandroid/net/Uri;->fromParts(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/net/Uri;
 HSPLandroid/net/Uri;->getBooleanQueryParameter(Ljava/lang/String;Z)Z
-HSPLandroid/net/Uri;->getQueryParameter(Ljava/lang/String;)Ljava/lang/String;+]Landroid/net/Uri;Landroid/net/Uri$StringUri;]Ljava/lang/String;Ljava/lang/String;
-HSPLandroid/net/Uri;->getQueryParameterNames()Ljava/util/Set;+]Landroid/net/Uri;Landroid/net/Uri$StringUri;]Ljava/lang/String;Ljava/lang/String;]Ljava/util/Set;Ljava/util/LinkedHashSet;
+HSPLandroid/net/Uri;->getQueryParameter(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
+HSPLandroid/net/Uri;->getQueryParameterNames()Ljava/util/Set;+]Ljava/lang/String;Ljava/lang/String;]Ljava/util/Set;Ljava/util/LinkedHashSet;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
 HSPLandroid/net/Uri;->hashCode()I
 HSPLandroid/net/Uri;->isAbsolute()Z
 HSPLandroid/net/Uri;->isAllowed(CLjava/lang/String;)Z+]Ljava/lang/String;Ljava/lang/String;
@@ -11514,9 +11564,9 @@
 HSPLandroid/net/Uri;->toSafeString()Ljava/lang/String;
 HSPLandroid/net/Uri;->withAppendedPath(Landroid/net/Uri;Ljava/lang/String;)Landroid/net/Uri;
 HSPLandroid/net/Uri;->writeToParcel(Landroid/os/Parcel;Landroid/net/Uri;)V
-HSPLandroid/net/UriCodec;->appendDecoded(Ljava/lang/StringBuilder;Ljava/lang/String;ZLjava/nio/charset/Charset;Z)V+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;]Ljava/nio/charset/Charset;Lcom/android/icu/charset/CharsetICU;]Ljava/nio/charset/CharsetDecoder;Lcom/android/icu/charset/CharsetDecoderICU;
+HSPLandroid/net/UriCodec;->appendDecoded(Ljava/lang/StringBuilder;Ljava/lang/String;ZLjava/nio/charset/Charset;Z)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/String;Ljava/lang/String;]Ljava/nio/charset/Charset;Lcom/android/icu/charset/CharsetICU;]Ljava/nio/charset/CharsetDecoder;Lcom/android/icu/charset/CharsetDecoderICU;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
 HSPLandroid/net/UriCodec;->decode(Ljava/lang/String;ZLjava/nio/charset/Charset;Z)Ljava/lang/String;
-HSPLandroid/net/UriCodec;->flushDecodingByteAccumulator(Ljava/lang/StringBuilder;Ljava/nio/charset/CharsetDecoder;Ljava/nio/ByteBuffer;Z)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;]Ljava/nio/charset/CharsetDecoder;Lcom/android/icu/charset/CharsetDecoderICU;
+HSPLandroid/net/UriCodec;->flushDecodingByteAccumulator(Ljava/lang/StringBuilder;Ljava/nio/charset/CharsetDecoder;Ljava/nio/ByteBuffer;Z)V+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/nio/charset/CharsetDecoder;Lcom/android/icu/charset/CharsetDecoderICU;
 HSPLandroid/net/UriCodec;->getNextCharacter(Ljava/lang/String;IILjava/lang/String;)C
 HSPLandroid/net/UriCodec;->hexCharToValue(C)I
 HSPLandroid/net/WebAddress;-><init>(Ljava/lang/String;)V
@@ -11533,6 +11583,7 @@
 HSPLandroid/net/vcn/VcnTransportInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/vcn/VcnTransportInfo;
 HSPLandroid/net/vcn/VcnTransportInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/net/vcn/VcnTransportInfo;-><clinit>()V
+HSPLandroid/nfc/NfcFrameworkInitializer;->setNfcServiceManager(Landroid/nfc/NfcServiceManager;)V
 HSPLandroid/nfc/NfcServiceManager;-><init>()V
 HSPLandroid/nfc/cardemulation/AidGroup$1;->createFromParcel(Landroid/os/Parcel;)Landroid/nfc/cardemulation/AidGroup;
 HSPLandroid/nfc/cardemulation/AidGroup$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -11584,13 +11635,13 @@
 HSPLandroid/os/BaseBundle;-><init>()V
 HSPLandroid/os/BaseBundle;-><init>(I)V
 HSPLandroid/os/BaseBundle;-><init>(Landroid/os/BaseBundle;)V
-HSPLandroid/os/BaseBundle;-><init>(Landroid/os/BaseBundle;Z)V
+HSPLandroid/os/BaseBundle;-><init>(Landroid/os/BaseBundle;Z)V+]Landroid/os/BaseBundle;Landroid/os/Bundle;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/BaseBundle;-><init>(Landroid/os/Parcel;I)V
-HSPLandroid/os/BaseBundle;-><init>(Ljava/lang/ClassLoader;I)V+]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;-><init>(Ljava/lang/ClassLoader;I)V+]Ljava/lang/Object;Landroid/os/Bundle;,Landroid/os/PersistableBundle;]Ljava/lang/Class;Ljava/lang/Class;
 HSPLandroid/os/BaseBundle;->clear()V
 HSPLandroid/os/BaseBundle;->containsKey(Ljava/lang/String;)Z
 HSPLandroid/os/BaseBundle;->deepCopyValue(Ljava/lang/Object;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->get(Ljava/lang/String;)Ljava/lang/Object;
+HSPLandroid/os/BaseBundle;->get(Ljava/lang/String;)Ljava/lang/Object;+]Landroid/os/BaseBundle;Landroid/os/Bundle;
 HSPLandroid/os/BaseBundle;->get(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
 HSPLandroid/os/BaseBundle;->getArrayList(Ljava/lang/String;Ljava/lang/Class;)Ljava/util/ArrayList;
 HSPLandroid/os/BaseBundle;->getBoolean(Ljava/lang/String;)Z
@@ -11599,9 +11650,9 @@
 HSPLandroid/os/BaseBundle;->getByteArray(Ljava/lang/String;)[B
 HSPLandroid/os/BaseBundle;->getCharSequence(Ljava/lang/String;)Ljava/lang/CharSequence;
 HSPLandroid/os/BaseBundle;->getCharSequenceArray(Ljava/lang/String;)[Ljava/lang/CharSequence;
-HSPLandroid/os/BaseBundle;->getFloat(Ljava/lang/String;F)F
+HSPLandroid/os/BaseBundle;->getFloat(Ljava/lang/String;F)F+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Float;Ljava/lang/Float;]Landroid/os/BaseBundle;Landroid/os/Bundle;
 HSPLandroid/os/BaseBundle;->getInt(Ljava/lang/String;)I
-HSPLandroid/os/BaseBundle;->getInt(Ljava/lang/String;I)I
+HSPLandroid/os/BaseBundle;->getInt(Ljava/lang/String;I)I+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Integer;Ljava/lang/Integer;]Landroid/os/BaseBundle;Landroid/os/Bundle;
 HSPLandroid/os/BaseBundle;->getIntArray(Ljava/lang/String;)[I
 HSPLandroid/os/BaseBundle;->getIntegerArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
 HSPLandroid/os/BaseBundle;->getLong(Ljava/lang/String;)J
@@ -11611,18 +11662,18 @@
 HSPLandroid/os/BaseBundle;->getSerializable(Ljava/lang/String;Ljava/lang/Class;)Ljava/io/Serializable;
 HSPLandroid/os/BaseBundle;->getString(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/os/BaseBundle;->getString(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/os/BaseBundle;->getStringArray(Ljava/lang/String;)[Ljava/lang/String;
+HSPLandroid/os/BaseBundle;->getStringArray(Ljava/lang/String;)[Ljava/lang/String;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
 HSPLandroid/os/BaseBundle;->getStringArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
-HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->getValueAt(ILjava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->initializeFromParcelLocked(Landroid/os/Parcel;ZZ)V
-HSPLandroid/os/BaseBundle;->isEmpty()Z
+HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;)Ljava/lang/Object;+]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->getValueAt(ILjava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Class;Ljava/lang/Class;
+HSPLandroid/os/BaseBundle;->initializeFromParcelLocked(Landroid/os/Parcel;ZZ)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/BaseBundle;->isEmpty()Z+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
 HSPLandroid/os/BaseBundle;->isEmptyParcel()Z
 HSPLandroid/os/BaseBundle;->isEmptyParcel(Landroid/os/Parcel;)Z
 HSPLandroid/os/BaseBundle;->isParcelled()Z
-HSPLandroid/os/BaseBundle;->keySet()Ljava/util/Set;+]Landroid/os/BaseBundle;Landroid/os/Bundle;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/os/BaseBundle;->keySet()Ljava/util/Set;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
 HSPLandroid/os/BaseBundle;->putAll(Landroid/os/PersistableBundle;)V
 HSPLandroid/os/BaseBundle;->putAll(Landroid/util/ArrayMap;)V
 HSPLandroid/os/BaseBundle;->putBoolean(Ljava/lang/String;Z)V
@@ -11631,7 +11682,7 @@
 HSPLandroid/os/BaseBundle;->putCharSequence(Ljava/lang/String;Ljava/lang/CharSequence;)V
 HSPLandroid/os/BaseBundle;->putCharSequenceArray(Ljava/lang/String;[Ljava/lang/CharSequence;)V
 HSPLandroid/os/BaseBundle;->putDouble(Ljava/lang/String;D)V
-HSPLandroid/os/BaseBundle;->putFloat(Ljava/lang/String;F)V
+HSPLandroid/os/BaseBundle;->putFloat(Ljava/lang/String;F)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
 HSPLandroid/os/BaseBundle;->putInt(Ljava/lang/String;I)V
 HSPLandroid/os/BaseBundle;->putIntArray(Ljava/lang/String;[I)V
 HSPLandroid/os/BaseBundle;->putLong(Ljava/lang/String;J)V
@@ -11641,16 +11692,16 @@
 HSPLandroid/os/BaseBundle;->putStringArray(Ljava/lang/String;[Ljava/lang/String;)V
 HSPLandroid/os/BaseBundle;->putStringArrayList(Ljava/lang/String;Ljava/util/ArrayList;)V
 HSPLandroid/os/BaseBundle;->readFromParcelInner(Landroid/os/Parcel;)V
-HSPLandroid/os/BaseBundle;->readFromParcelInner(Landroid/os/Parcel;I)V
-HSPLandroid/os/BaseBundle;->recycleParcel(Landroid/os/Parcel;)V
+HSPLandroid/os/BaseBundle;->readFromParcelInner(Landroid/os/Parcel;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/BaseBundle;->recycleParcel(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/BaseBundle;->remove(Ljava/lang/String;)V
 HSPLandroid/os/BaseBundle;->setClassLoader(Ljava/lang/ClassLoader;)V
 HSPLandroid/os/BaseBundle;->setShouldDefuse(Z)V
-HSPLandroid/os/BaseBundle;->size()I
-HSPLandroid/os/BaseBundle;->unparcel()V+]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->size()I+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->unparcel()V+]Landroid/os/BaseBundle;Landroid/os/Bundle;,Landroid/os/PersistableBundle;
 HSPLandroid/os/BaseBundle;->unparcel(Z)V
-HSPLandroid/os/BaseBundle;->unwrapLazyValueFromMapLocked(ILjava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;]Ljava/util/function/BiFunction;Landroid/os/Parcel$LazyValue;
-HSPLandroid/os/BaseBundle;->writeToParcelInner(Landroid/os/Parcel;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/os/BaseBundle;->unwrapLazyValueFromMapLocked(ILjava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/function/BiFunction;Landroid/os/Parcel$LazyValue;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/os/BaseBundle;->writeToParcelInner(Landroid/os/Parcel;I)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/BatteryManager;-><init>(Landroid/content/Context;Lcom/android/internal/app/IBatteryStats;Landroid/os/IBatteryPropertiesRegistrar;)V
 HSPLandroid/os/BatteryManager;->getIntProperty(I)I
 HSPLandroid/os/BatteryManager;->getLongProperty(I)J
@@ -11717,12 +11768,12 @@
 HSPLandroid/os/Binder;->transact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/os/Binder;->unlinkToDeath(Landroid/os/IBinder$DeathRecipient;I)Z
 HSPLandroid/os/Binder;->withCleanCallingIdentity(Lcom/android/internal/util/FunctionalUtils$ThrowingRunnable;)V
-HSPLandroid/os/BinderProxy$ProxyMap;->get(J)Landroid/os/BinderProxy;+]Ljava/lang/Long;Ljava/lang/Long;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/os/BinderProxy$ProxyMap;->get(J)Landroid/os/BinderProxy;
 HSPLandroid/os/BinderProxy$ProxyMap;->hash(J)I
 HSPLandroid/os/BinderProxy$ProxyMap;->remove(II)V
 HSPLandroid/os/BinderProxy$ProxyMap;->set(JLandroid/os/BinderProxy;)V
 HSPLandroid/os/BinderProxy;-><init>(J)V
-HSPLandroid/os/BinderProxy;->getInstance(JJ)Landroid/os/BinderProxy;+]Landroid/os/BinderProxy$ProxyMap;Landroid/os/BinderProxy$ProxyMap;]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/os/BinderProxy;->getInstance(JJ)Landroid/os/BinderProxy;
 HSPLandroid/os/BinderProxy;->linkToDeath(Landroid/os/IBinder$DeathRecipient;I)V+]Ljava/util/List;Ljava/util/Collections$SynchronizedRandomAccessList;
 HSPLandroid/os/BinderProxy;->queryLocalInterface(Ljava/lang/String;)Landroid/os/IInterface;
 HSPLandroid/os/BinderProxy;->sendDeathNotice(Landroid/os/IBinder$DeathRecipient;Landroid/os/IBinder;)V
@@ -11761,7 +11812,7 @@
 HSPLandroid/os/Bundle;->getIntegerArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
 HSPLandroid/os/Bundle;->getParcelable(Ljava/lang/String;)Landroid/os/Parcelable;
 HSPLandroid/os/Bundle;->getParcelable(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/Bundle;->getParcelableArray(Ljava/lang/String;)[Landroid/os/Parcelable;
+HSPLandroid/os/Bundle;->getParcelableArray(Ljava/lang/String;)[Landroid/os/Parcelable;+]Landroid/os/Bundle;Landroid/os/Bundle;
 HSPLandroid/os/Bundle;->getParcelableArray(Ljava/lang/String;Ljava/lang/Class;)[Ljava/lang/Object;
 HSPLandroid/os/Bundle;->getParcelableArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
 HSPLandroid/os/Bundle;->getSerializable(Ljava/lang/String;)Ljava/io/Serializable;
@@ -11769,10 +11820,10 @@
 HSPLandroid/os/Bundle;->getSparseParcelableArray(Ljava/lang/String;)Landroid/util/SparseArray;
 HSPLandroid/os/Bundle;->getStringArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
 HSPLandroid/os/Bundle;->hasFileDescriptors()Z
-HSPLandroid/os/Bundle;->maybePrefillHasFds()V
+HSPLandroid/os/Bundle;->maybePrefillHasFds()V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Bundle;->putAll(Landroid/os/Bundle;)V
 HSPLandroid/os/Bundle;->putBinder(Ljava/lang/String;Landroid/os/IBinder;)V
-HSPLandroid/os/Bundle;->putBundle(Ljava/lang/String;Landroid/os/Bundle;)V+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/os/Bundle;->putBundle(Ljava/lang/String;Landroid/os/Bundle;)V
 HSPLandroid/os/Bundle;->putByteArray(Ljava/lang/String;[B)V
 HSPLandroid/os/Bundle;->putCharSequence(Ljava/lang/String;Ljava/lang/CharSequence;)V
 HSPLandroid/os/Bundle;->putCharSequenceArray(Ljava/lang/String;[Ljava/lang/CharSequence;)V
@@ -11939,7 +11990,7 @@
 HSPLandroid/os/FileObserver;-><init>(Ljava/lang/String;I)V
 HSPLandroid/os/FileObserver;-><init>(Ljava/util/List;I)V
 HSPLandroid/os/FileObserver;->startWatching()V
-HSPLandroid/os/FileUtils;->buildValidExtFilename(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/os/FileUtils;->buildValidExtFilename(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/Object;Ljava/lang/String;
 HSPLandroid/os/FileUtils;->bytesToFile(Ljava/lang/String;[B)V
 HSPLandroid/os/FileUtils;->closeQuietly(Ljava/lang/AutoCloseable;)V
 HSPLandroid/os/FileUtils;->contains(Ljava/io/File;Ljava/io/File;)Z
@@ -12011,7 +12062,7 @@
 HSPLandroid/os/Handler;->obtainMessage(ILjava/lang/Object;)Landroid/os/Message;
 HSPLandroid/os/Handler;->post(Ljava/lang/Runnable;)Z+]Landroid/os/Handler;missing_types
 HSPLandroid/os/Handler;->postAtFrontOfQueue(Ljava/lang/Runnable;)Z
-HSPLandroid/os/Handler;->postAtTime(Ljava/lang/Runnable;J)Z
+HSPLandroid/os/Handler;->postAtTime(Ljava/lang/Runnable;J)Z+]Landroid/os/Handler;Landroid/view/ViewRootImpl$ViewRootHandler;
 HSPLandroid/os/Handler;->postAtTime(Ljava/lang/Runnable;Ljava/lang/Object;J)Z
 HSPLandroid/os/Handler;->postDelayed(Ljava/lang/Runnable;IJ)Z
 HSPLandroid/os/Handler;->postDelayed(Ljava/lang/Runnable;J)Z
@@ -12024,7 +12075,7 @@
 HSPLandroid/os/Handler;->sendEmptyMessage(I)Z
 HSPLandroid/os/Handler;->sendEmptyMessageAtTime(IJ)Z
 HSPLandroid/os/Handler;->sendEmptyMessageDelayed(IJ)Z
-HSPLandroid/os/Handler;->sendMessage(Landroid/os/Message;)Z
+HSPLandroid/os/Handler;->sendMessage(Landroid/os/Message;)Z+]Landroid/os/Handler;missing_types
 HSPLandroid/os/Handler;->sendMessageAtFrontOfQueue(Landroid/os/Message;)Z
 HSPLandroid/os/Handler;->sendMessageAtTime(Landroid/os/Message;J)Z
 HSPLandroid/os/Handler;->sendMessageDelayed(Landroid/os/Message;J)Z+]Landroid/os/Handler;missing_types
@@ -12070,6 +12121,7 @@
 HSPLandroid/os/IDeviceIdleController$Stub$Proxy;->isPowerSaveWhitelistApp(Ljava/lang/String;)Z
 HSPLandroid/os/IDeviceIdleController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IDeviceIdleController;
 HSPLandroid/os/IHintManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+HSPLandroid/os/IHintManager$Stub$Proxy;->createHintSession(Landroid/os/IBinder;[IJ)Landroid/os/IHintSession;
 HSPLandroid/os/IHintManager$Stub$Proxy;->getHintSessionPreferredRate()J
 HSPLandroid/os/IHintManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IHintManager;
 HSPLandroid/os/IHintSession$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IHintSession;
@@ -12164,14 +12216,14 @@
 HSPLandroid/os/IpcDataCache;-><init>(Landroid/os/IpcDataCache$Config;Landroid/os/IpcDataCache$QueryHandler;)V
 HSPLandroid/os/IpcDataCache;-><init>(Landroid/os/IpcDataCache$Config;Landroid/os/IpcDataCache$RemoteCall;)V
 HSPLandroid/os/IpcDataCache;->query(Ljava/lang/Object;)Ljava/lang/Object;
-HSPLandroid/os/LocaleList$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/LocaleList;+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/os/LocaleList$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/os/LocaleList$1;Landroid/os/LocaleList$1;
-HSPLandroid/os/LocaleList;-><init>([Ljava/util/Locale;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/HashSet;Ljava/util/HashSet;]Ljava/util/Locale;Ljava/util/Locale;
+HSPLandroid/os/LocaleList$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/LocaleList;
+HSPLandroid/os/LocaleList$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/os/LocaleList;-><init>([Ljava/util/Locale;)V
 HSPLandroid/os/LocaleList;->computeFirstMatch(Ljava/util/Collection;Z)Ljava/util/Locale;
 HSPLandroid/os/LocaleList;->computeFirstMatchIndex(Ljava/util/Collection;Z)I
-HSPLandroid/os/LocaleList;->equals(Ljava/lang/Object;)Z
+HSPLandroid/os/LocaleList;->equals(Ljava/lang/Object;)Z+]Ljava/lang/Object;Ljava/util/Locale;
 HSPLandroid/os/LocaleList;->findFirstMatchIndex(Ljava/util/Locale;)I
-HSPLandroid/os/LocaleList;->forLanguageTags(Ljava/lang/String;)Landroid/os/LocaleList;+]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/os/LocaleList;->forLanguageTags(Ljava/lang/String;)Landroid/os/LocaleList;
 HSPLandroid/os/LocaleList;->get(I)Ljava/util/Locale;
 HSPLandroid/os/LocaleList;->getAdjustedDefault()Landroid/os/LocaleList;
 HSPLandroid/os/LocaleList;->getDefault()Landroid/os/LocaleList;+]Ljava/lang/Object;Ljava/util/Locale;
@@ -12193,10 +12245,10 @@
 HSPLandroid/os/Looper;->getMainLooper()Landroid/os/Looper;
 HSPLandroid/os/Looper;->getQueue()Landroid/os/MessageQueue;
 HSPLandroid/os/Looper;->getThread()Ljava/lang/Thread;
-HSPLandroid/os/Looper;->getThresholdOverride()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/Thread;Landroid/os/HandlerThread;
+HSPLandroid/os/Looper;->getThresholdOverride()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/Thread;missing_types
 HSPLandroid/os/Looper;->isCurrentThread()Z
 HSPLandroid/os/Looper;->loop()V
-HSPLandroid/os/Looper;->loopOnce(Landroid/os/Looper;JI)Z+]Landroid/os/Handler;missing_types]Landroid/os/Message;Landroid/os/Message;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;
+HSPLandroid/os/Looper;->loopOnce(Landroid/os/Looper;JI)Z+]Landroid/os/Handler;megamorphic_types]Landroid/os/Message;Landroid/os/Message;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;
 HSPLandroid/os/Looper;->myLooper()Landroid/os/Looper;+]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal;
 HSPLandroid/os/Looper;->myQueue()Landroid/os/MessageQueue;
 HSPLandroid/os/Looper;->prepare()V
@@ -12230,7 +12282,7 @@
 HSPLandroid/os/Message;->readFromParcel(Landroid/os/Parcel;)V
 HSPLandroid/os/Message;->recycle()V
 HSPLandroid/os/Message;->recycleUnchecked()V
-HSPLandroid/os/Message;->sendToTarget()V
+HSPLandroid/os/Message;->sendToTarget()V+]Landroid/os/Handler;megamorphic_types
 HSPLandroid/os/Message;->setAsynchronous(Z)V
 HSPLandroid/os/Message;->setCallback(Ljava/lang/Runnable;)Landroid/os/Message;
 HSPLandroid/os/Message;->setData(Landroid/os/Bundle;)V
@@ -12249,13 +12301,13 @@
 HSPLandroid/os/MessageQueue;->finalize()V
 HSPLandroid/os/MessageQueue;->hasMessages(Landroid/os/Handler;ILjava/lang/Object;)Z
 HSPLandroid/os/MessageQueue;->hasMessages(Landroid/os/Handler;Ljava/lang/Runnable;Ljava/lang/Object;)Z
-HSPLandroid/os/MessageQueue;->next()Landroid/os/Message;+]Landroid/os/Message;Landroid/os/Message;]Landroid/os/MessageQueue$IdleHandler;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/os/MessageQueue;->next()Landroid/os/Message;+]Landroid/os/MessageQueue$IdleHandler;missing_types]Landroid/os/Message;Landroid/os/Message;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/os/MessageQueue;->postSyncBarrier()I
 HSPLandroid/os/MessageQueue;->postSyncBarrier(J)I+]Landroid/os/Message;Landroid/os/Message;
 HSPLandroid/os/MessageQueue;->quit(Z)V
 HSPLandroid/os/MessageQueue;->removeAllFutureMessagesLocked()V
 HSPLandroid/os/MessageQueue;->removeAllMessagesLocked()V
-HSPLandroid/os/MessageQueue;->removeCallbacksAndMessages(Landroid/os/Handler;Ljava/lang/Object;)V+]Landroid/os/Message;Landroid/os/Message;
+HSPLandroid/os/MessageQueue;->removeCallbacksAndMessages(Landroid/os/Handler;Ljava/lang/Object;)V
 HSPLandroid/os/MessageQueue;->removeIdleHandler(Landroid/os/MessageQueue$IdleHandler;)V
 HSPLandroid/os/MessageQueue;->removeMessages(Landroid/os/Handler;ILjava/lang/Object;)V+]Landroid/os/Message;Landroid/os/Message;
 HSPLandroid/os/MessageQueue;->removeMessages(Landroid/os/Handler;Ljava/lang/Runnable;Ljava/lang/Object;)V+]Landroid/os/Message;Landroid/os/Message;
@@ -12276,12 +12328,12 @@
 HSPLandroid/os/Parcel$2;->resolveClass(Ljava/io/ObjectStreamClass;)Ljava/lang/Class;+]Ljava/io/ObjectStreamClass;Ljava/io/ObjectStreamClass;
 HSPLandroid/os/Parcel$LazyValue;-><init>(Landroid/os/Parcel;IIILjava/lang/ClassLoader;)V
 HSPLandroid/os/Parcel$LazyValue;->apply(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/os/Parcel$LazyValue;->apply(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/os/Parcel$LazyValue;->apply(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+]Landroid/os/Parcel$LazyValue;Landroid/os/Parcel$LazyValue;
 HSPLandroid/os/Parcel$LazyValue;->writeToParcel(Landroid/os/Parcel;)V
 HSPLandroid/os/Parcel$ReadWriteHelper;->readString16(Landroid/os/Parcel;)Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel$ReadWriteHelper;->readString8(Landroid/os/Parcel;)Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel$ReadWriteHelper;->writeString16(Landroid/os/Parcel;Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/os/Parcel$ReadWriteHelper;->writeString8(Landroid/os/Parcel;Ljava/lang/String;)V
+HSPLandroid/os/Parcel$ReadWriteHelper;->writeString8(Landroid/os/Parcel;Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->-$$Nest$mreadValue(Landroid/os/Parcel;Ljava/lang/ClassLoader;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;
 HSPLandroid/os/Parcel;-><init>(J)V
 HSPLandroid/os/Parcel;->adoptClassCookies(Landroid/os/Parcel;)V
@@ -12294,21 +12346,21 @@
 HSPLandroid/os/Parcel;->createByteArray()[B
 HSPLandroid/os/Parcel;->createException(ILjava/lang/String;)Ljava/lang/Exception;
 HSPLandroid/os/Parcel;->createExceptionOrNull(ILjava/lang/String;)Ljava/lang/Exception;
-HSPLandroid/os/Parcel;->createFloatArray()[F+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->createFloatArray()[F
 HSPLandroid/os/Parcel;->createIntArray()[I+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/os/Parcel;->createLongArray()[J
+HSPLandroid/os/Parcel;->createLongArray()[J+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->createString16Array()[Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->createString8Array()[Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->createStringArray()[Ljava/lang/String;
-HSPLandroid/os/Parcel;->createStringArrayList()Ljava/util/ArrayList;
-HSPLandroid/os/Parcel;->createTypedArray(Landroid/os/Parcelable$Creator;)[Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;missing_types
-HSPLandroid/os/Parcel;->createTypedArrayList(Landroid/os/Parcelable$Creator;)Ljava/util/ArrayList;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/os/Parcel;->createStringArrayList()Ljava/util/ArrayList;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->createTypedArray(Landroid/os/Parcelable$Creator;)[Ljava/lang/Object;+]Landroid/os/Parcelable$Creator;missing_types]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->createTypedArrayList(Landroid/os/Parcelable$Creator;)Ljava/util/ArrayList;+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->dataAvail()I
 HSPLandroid/os/Parcel;->dataPosition()I
 HSPLandroid/os/Parcel;->dataSize()I
 HSPLandroid/os/Parcel;->destroy()V
 HSPLandroid/os/Parcel;->enforceInterface(Ljava/lang/String;)V
-HSPLandroid/os/Parcel;->enforceNoDataAvail()V
+HSPLandroid/os/Parcel;->enforceNoDataAvail()V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->ensureReadSquashableParcelables()V
 HSPLandroid/os/Parcel;->ensureWithinMemoryLimit(II)V
 HSPLandroid/os/Parcel;->finalize()V
@@ -12330,33 +12382,33 @@
 HSPLandroid/os/Parcel;->pushAllowFds(Z)Z
 HSPLandroid/os/Parcel;->readArrayList(Ljava/lang/ClassLoader;)Ljava/util/ArrayList;
 HSPLandroid/os/Parcel;->readArrayList(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/ArrayList;
-HSPLandroid/os/Parcel;->readArrayListInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/ArrayList;
-HSPLandroid/os/Parcel;->readArrayMap(Landroid/util/ArrayMap;IZZLjava/lang/ClassLoader;)I
+HSPLandroid/os/Parcel;->readArrayListInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/ArrayList;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readArrayMap(Landroid/util/ArrayMap;IZZLjava/lang/ClassLoader;)I+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readArrayMap(Landroid/util/ArrayMap;Ljava/lang/ClassLoader;)V
 HSPLandroid/os/Parcel;->readArrayMapInternal(Landroid/util/ArrayMap;ILjava/lang/ClassLoader;)V
-HSPLandroid/os/Parcel;->readArraySet(Ljava/lang/ClassLoader;)Landroid/util/ArraySet;+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/ArraySet;Landroid/util/ArraySet;
+HSPLandroid/os/Parcel;->readArraySet(Ljava/lang/ClassLoader;)Landroid/util/ArraySet;
 HSPLandroid/os/Parcel;->readBinderList(Ljava/util/List;)V
 HSPLandroid/os/Parcel;->readBlob()[B
 HSPLandroid/os/Parcel;->readBoolean()Z+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readBooleanArray([Z)V
-HSPLandroid/os/Parcel;->readBundle()Landroid/os/Bundle;
-HSPLandroid/os/Parcel;->readBundle(Ljava/lang/ClassLoader;)Landroid/os/Bundle;
-HSPLandroid/os/Parcel;->readByte()B
+HSPLandroid/os/Parcel;->readBundle()Landroid/os/Bundle;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readBundle(Ljava/lang/ClassLoader;)Landroid/os/Bundle;+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readByte()B+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readByteArray([B)V
 HSPLandroid/os/Parcel;->readCallingWorkSourceUid()I
-HSPLandroid/os/Parcel;->readCharSequence()Ljava/lang/CharSequence;
+HSPLandroid/os/Parcel;->readCharSequence()Ljava/lang/CharSequence;+]Landroid/os/Parcelable$Creator;Landroid/text/TextUtils$1;
 HSPLandroid/os/Parcel;->readCharSequenceArray()[Ljava/lang/CharSequence;
 HSPLandroid/os/Parcel;->readDouble()D
-HSPLandroid/os/Parcel;->readException()V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readException()V
 HSPLandroid/os/Parcel;->readException(ILjava/lang/String;)V
-HSPLandroid/os/Parcel;->readExceptionCode()I+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readExceptionCode()I
 HSPLandroid/os/Parcel;->readFloat()F
 HSPLandroid/os/Parcel;->readFloatArray([F)V
 HSPLandroid/os/Parcel;->readHashMap(Ljava/lang/ClassLoader;)Ljava/util/HashMap;
 HSPLandroid/os/Parcel;->readHashMapInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;Ljava/lang/Class;)Ljava/util/HashMap;
 HSPLandroid/os/Parcel;->readInt()I
 HSPLandroid/os/Parcel;->readIntArray([I)V
-HSPLandroid/os/Parcel;->readLazyValue(Ljava/lang/ClassLoader;)Ljava/lang/Object;
+HSPLandroid/os/Parcel;->readLazyValue(Ljava/lang/ClassLoader;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readList(Ljava/util/List;Ljava/lang/ClassLoader;)V
 HSPLandroid/os/Parcel;->readList(Ljava/util/List;Ljava/lang/ClassLoader;Ljava/lang/Class;)V
 HSPLandroid/os/Parcel;->readListInternal(Ljava/util/List;ILjava/lang/ClassLoader;)V
@@ -12370,25 +12422,25 @@
 HSPLandroid/os/Parcel;->readParcelable(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;
 HSPLandroid/os/Parcel;->readParcelableArray(Ljava/lang/ClassLoader;)[Landroid/os/Parcelable;
 HSPLandroid/os/Parcel;->readParcelableArray(Ljava/lang/ClassLoader;Ljava/lang/Class;)[Ljava/lang/Object;
-HSPLandroid/os/Parcel;->readParcelableArrayInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)[Ljava/lang/Object;
+HSPLandroid/os/Parcel;->readParcelableArrayInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)[Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readParcelableCreator(Ljava/lang/ClassLoader;)Landroid/os/Parcelable$Creator;
-HSPLandroid/os/Parcel;->readParcelableCreatorInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Landroid/os/Parcelable$Creator;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/reflect/Field;Ljava/lang/reflect/Field;]Ljava/util/HashMap;Ljava/util/HashMap;
-HSPLandroid/os/Parcel;->readParcelableInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcelable$Creator;megamorphic_types
+HSPLandroid/os/Parcel;->readParcelableCreatorInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Landroid/os/Parcelable$Creator;+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Object;Landroid/os/Parcel;]Ljava/lang/reflect/Field;Ljava/lang/reflect/Field;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readParcelableInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcelable$Creator;megamorphic_types]Landroid/os/Parcelable$ClassLoaderCreator;Landroid/content/pm/ParceledListSlice$1;
 HSPLandroid/os/Parcel;->readParcelableList(Ljava/util/List;Ljava/lang/ClassLoader;)Ljava/util/List;
 HSPLandroid/os/Parcel;->readParcelableList(Ljava/util/List;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/List;
-HSPLandroid/os/Parcel;->readParcelableListInternal(Ljava/util/List;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/List;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/os/Parcel;->readParcelableListInternal(Ljava/util/List;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/List;+]Ljava/util/List;Ljava/util/ArrayList;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readPersistableBundle()Landroid/os/PersistableBundle;
 HSPLandroid/os/Parcel;->readPersistableBundle(Ljava/lang/ClassLoader;)Landroid/os/PersistableBundle;
 HSPLandroid/os/Parcel;->readRawFileDescriptor()Ljava/io/FileDescriptor;
 HSPLandroid/os/Parcel;->readSerializable()Ljava/io/Serializable;
-HSPLandroid/os/Parcel;->readSerializableInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/io/ObjectInputStream;Landroid/os/Parcel$2;
+HSPLandroid/os/Parcel;->readSerializableInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;+]Ljava/io/ObjectInputStream;Landroid/os/Parcel$2;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readSize()Landroid/util/Size;
 HSPLandroid/os/Parcel;->readSparseArray(Ljava/lang/ClassLoader;)Landroid/util/SparseArray;
 HSPLandroid/os/Parcel;->readSparseArray(Ljava/lang/ClassLoader;Ljava/lang/Class;)Landroid/util/SparseArray;
 HSPLandroid/os/Parcel;->readSparseArrayInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Landroid/util/SparseArray;
 HSPLandroid/os/Parcel;->readSparseIntArray()Landroid/util/SparseIntArray;
 HSPLandroid/os/Parcel;->readSparseIntArrayInternal(Landroid/util/SparseIntArray;I)V
-HSPLandroid/os/Parcel;->readSquashed(Landroid/os/Parcel$SquashReadHelper;)Landroid/os/Parcelable;
+HSPLandroid/os/Parcel;->readSquashed(Landroid/os/Parcel$SquashReadHelper;)Landroid/os/Parcelable;+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/os/Parcel$SquashReadHelper;Landroid/content/pm/ApplicationInfo$1$$ExternalSyntheticLambda0;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readString()Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readString16()Ljava/lang/String;+]Landroid/os/Parcel$ReadWriteHelper;Landroid/os/Parcel$ReadWriteHelper;
 HSPLandroid/os/Parcel;->readString16Array([Ljava/lang/String;)V
@@ -12399,11 +12451,11 @@
 HSPLandroid/os/Parcel;->readStringArray([Ljava/lang/String;)V
 HSPLandroid/os/Parcel;->readStringList(Ljava/util/List;)V
 HSPLandroid/os/Parcel;->readStrongBinder()Landroid/os/IBinder;
-HSPLandroid/os/Parcel;->readTypedArray([Ljava/lang/Object;Landroid/os/Parcelable$Creator;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readTypedArray([Ljava/lang/Object;Landroid/os/Parcelable$Creator;)V
 HSPLandroid/os/Parcel;->readTypedList(Ljava/util/List;Landroid/os/Parcelable$Creator;)V
-HSPLandroid/os/Parcel;->readTypedObject(Landroid/os/Parcelable$Creator;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;megamorphic_types
+HSPLandroid/os/Parcel;->readTypedObject(Landroid/os/Parcelable$Creator;)Ljava/lang/Object;+]Landroid/os/Parcelable$Creator;megamorphic_types]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readValue(ILjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/Parcel;->readValue(ILjava/lang/ClassLoader;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;
+HSPLandroid/os/Parcel;->readValue(ILjava/lang/ClassLoader;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readValue(Ljava/lang/ClassLoader;)Ljava/lang/Object;
 HSPLandroid/os/Parcel;->readValue(Ljava/lang/ClassLoader;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->recycle()V
@@ -12415,11 +12467,11 @@
 HSPLandroid/os/Parcel;->setReadWriteHelper(Landroid/os/Parcel$ReadWriteHelper;)V
 HSPLandroid/os/Parcel;->unmarshall([BII)V
 HSPLandroid/os/Parcel;->writeArrayMap(Landroid/util/ArrayMap;)V
-HSPLandroid/os/Parcel;->writeArrayMapInternal(Landroid/util/ArrayMap;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/os/Parcel;->writeArrayMapInternal(Landroid/util/ArrayMap;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->writeArraySet(Landroid/util/ArraySet;)V
 HSPLandroid/os/Parcel;->writeBinderList(Ljava/util/List;)V
 HSPLandroid/os/Parcel;->writeBlob([B)V
-HSPLandroid/os/Parcel;->writeBoolean(Z)V
+HSPLandroid/os/Parcel;->writeBoolean(Z)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->writeBooleanArray([Z)V
 HSPLandroid/os/Parcel;->writeBundle(Landroid/os/Bundle;)V+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->writeByte(B)V
@@ -12434,38 +12486,38 @@
 HSPLandroid/os/Parcel;->writeInt(I)V
 HSPLandroid/os/Parcel;->writeIntArray([I)V
 HSPLandroid/os/Parcel;->writeInterfaceToken(Ljava/lang/String;)V
-HSPLandroid/os/Parcel;->writeList(Ljava/util/List;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/os/Parcel;->writeList(Ljava/util/List;)V
 HSPLandroid/os/Parcel;->writeLong(J)V
 HSPLandroid/os/Parcel;->writeLongArray([J)V
 HSPLandroid/os/Parcel;->writeMap(Ljava/util/Map;)V
 HSPLandroid/os/Parcel;->writeMapInternal(Ljava/util/Map;)V
 HSPLandroid/os/Parcel;->writeNoException()V
-HSPLandroid/os/Parcel;->writeParcelable(Landroid/os/Parcelable;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable;missing_types
-HSPLandroid/os/Parcel;->writeParcelableArray([Landroid/os/Parcelable;I)V
-HSPLandroid/os/Parcel;->writeParcelableCreator(Landroid/os/Parcelable;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;missing_types
+HSPLandroid/os/Parcel;->writeParcelable(Landroid/os/Parcelable;I)V+]Landroid/os/Parcelable;missing_types]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->writeParcelableArray([Landroid/os/Parcelable;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->writeParcelableCreator(Landroid/os/Parcelable;)V+]Ljava/lang/Object;missing_types]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->writeParcelableList(Ljava/util/List;I)V
 HSPLandroid/os/Parcel;->writePersistableBundle(Landroid/os/PersistableBundle;)V
 HSPLandroid/os/Parcel;->writeSerializable(Ljava/io/Serializable;)V
-HSPLandroid/os/Parcel;->writeSparseArray(Landroid/util/SparseArray;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/os/Parcel;->writeSparseArray(Landroid/util/SparseArray;)V
 HSPLandroid/os/Parcel;->writeSparseBooleanArray(Landroid/util/SparseBooleanArray;)V
 HSPLandroid/os/Parcel;->writeSparseIntArray(Landroid/util/SparseIntArray;)V
 HSPLandroid/os/Parcel;->writeString(Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->writeString16(Ljava/lang/String;)V+]Landroid/os/Parcel$ReadWriteHelper;Landroid/os/Parcel$ReadWriteHelper;
-HSPLandroid/os/Parcel;->writeString16Array([Ljava/lang/String;)V
+HSPLandroid/os/Parcel;->writeString16Array([Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->writeString16NoHelper(Ljava/lang/String;)V
-HSPLandroid/os/Parcel;->writeString8(Ljava/lang/String;)V
+HSPLandroid/os/Parcel;->writeString8(Ljava/lang/String;)V+]Landroid/os/Parcel$ReadWriteHelper;Landroid/os/Parcel$ReadWriteHelper;
 HSPLandroid/os/Parcel;->writeString8Array([Ljava/lang/String;)V
 HSPLandroid/os/Parcel;->writeString8NoHelper(Ljava/lang/String;)V
-HSPLandroid/os/Parcel;->writeStringArray([Ljava/lang/String;)V
+HSPLandroid/os/Parcel;->writeStringArray([Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->writeStringList(Ljava/util/List;)V
 HSPLandroid/os/Parcel;->writeStrongBinder(Landroid/os/IBinder;)V
-HSPLandroid/os/Parcel;->writeStrongInterface(Landroid/os/IInterface;)V
-HSPLandroid/os/Parcel;->writeTypedArray([Landroid/os/Parcelable;I)V
+HSPLandroid/os/Parcel;->writeStrongInterface(Landroid/os/IInterface;)V+]Landroid/os/IInterface;Landroid/app/LoadedApk$ServiceDispatcher$InnerConnection;,Landroid/app/ActivityThread$ApplicationThread;,Landroid/view/ViewRootImpl$W;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->writeTypedArray([Landroid/os/Parcelable;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->writeTypedArrayMap(Landroid/util/ArrayMap;I)V
 HSPLandroid/os/Parcel;->writeTypedList(Ljava/util/List;)V
 HSPLandroid/os/Parcel;->writeTypedList(Ljava/util/List;I)V
-HSPLandroid/os/Parcel;->writeTypedObject(Landroid/os/Parcelable;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable;Landroid/app/FragmentState;,Landroid/content/Intent;,Landroid/os/Bundle;,Landroid/view/SurfaceControl$Transaction;
-HSPLandroid/os/Parcel;->writeValue(ILjava/lang/Object;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Integer;Ljava/lang/Integer;
+HSPLandroid/os/Parcel;->writeTypedObject(Landroid/os/Parcelable;I)V+]Landroid/os/Parcelable;Landroid/view/WindowManager$LayoutParams;,Landroid/content/Intent;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->writeValue(ILjava/lang/Object;)V+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/lang/Boolean;Ljava/lang/Boolean;]Ljava/lang/Long;Ljava/lang/Long;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->writeValue(Ljava/lang/Object;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/ParcelFileDescriptor$2;->createFromParcel(Landroid/os/Parcel;)Landroid/os/ParcelFileDescriptor;
 HSPLandroid/os/ParcelFileDescriptor$2;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -12655,7 +12707,7 @@
 HSPLandroid/os/ServiceManager;->getServiceOrThrow(Ljava/lang/String;)Landroid/os/IBinder;
 HSPLandroid/os/ServiceManager;->initServiceCache(Ljava/util/Map;)V
 HSPLandroid/os/ServiceManager;->isDeclared(Ljava/lang/String;)Z
-HSPLandroid/os/ServiceManager;->rawGetService(Ljava/lang/String;)Landroid/os/IBinder;+]Landroid/os/IServiceManager;Landroid/os/ServiceManagerProxy;]Lcom/android/internal/util/StatLogger;Lcom/android/internal/util/StatLogger;
+HSPLandroid/os/ServiceManager;->rawGetService(Ljava/lang/String;)Landroid/os/IBinder;+]Lcom/android/internal/util/StatLogger;Lcom/android/internal/util/StatLogger;]Landroid/os/IServiceManager;Landroid/os/ServiceManagerProxy;
 HSPLandroid/os/ServiceManager;->waitForDeclaredService(Ljava/lang/String;)Landroid/os/IBinder;
 HSPLandroid/os/ServiceManagerProxy;->addService(Ljava/lang/String;Landroid/os/IBinder;ZI)V
 HSPLandroid/os/ServiceManagerProxy;->checkService(Ljava/lang/String;)Landroid/os/IBinder;
@@ -12714,7 +12766,7 @@
 HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->lambda$handleViolationWithTimingAttempt$0(Landroid/view/IWindowManager;Ljava/util/ArrayList;)V
 HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onCustomSlowCall(Ljava/lang/String;)V
 HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onNetwork()V
-HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onReadFromDisk()V
+HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onReadFromDisk()V+]Landroid/os/StrictMode$AndroidBlockGuardPolicy;Landroid/os/StrictMode$AndroidBlockGuardPolicy;
 HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onThreadPolicyViolation(Landroid/os/StrictMode$ViolationInfo;)V
 HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onUnbufferedIO()V
 HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onWriteToDisk()V
@@ -12756,7 +12808,7 @@
 HSPLandroid/os/StrictMode$UnsafeIntentStrictModeCallback;-><init>()V
 HSPLandroid/os/StrictMode$UnsafeIntentStrictModeCallback;-><init>(Landroid/os/StrictMode$UnsafeIntentStrictModeCallback-IA;)V
 HSPLandroid/os/StrictMode$ViolationInfo;->-$$Nest$fgetmViolation(Landroid/os/StrictMode$ViolationInfo;)Landroid/os/strictmode/Violation;
-HSPLandroid/os/StrictMode$ViolationInfo;-><init>(Landroid/os/Parcel;Z)V
+HSPLandroid/os/StrictMode$ViolationInfo;-><init>(Landroid/os/Parcel;Z)V+]Ljava/util/Deque;Ljava/util/ArrayDeque;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/StrictMode$ViolationInfo;-><init>(Landroid/os/strictmode/Violation;I)V
 HSPLandroid/os/StrictMode$ViolationInfo;->getStackTrace()Ljava/lang/String;
 HSPLandroid/os/StrictMode$ViolationInfo;->hashCode()I
@@ -13084,7 +13136,7 @@
 HSPLandroid/os/storage/StorageManager;->allocateBytes(Ljava/io/FileDescriptor;JI)V
 HSPLandroid/os/storage/StorageManager;->allocateBytes(Ljava/util/UUID;JI)V
 HSPLandroid/os/storage/StorageManager;->convert(Ljava/lang/String;)Ljava/util/UUID;
-HSPLandroid/os/storage/StorageManager;->convert(Ljava/util/UUID;)Ljava/lang/String;
+HSPLandroid/os/storage/StorageManager;->convert(Ljava/util/UUID;)Ljava/lang/String;+]Ljava/lang/Object;Ljava/util/UUID;
 HSPLandroid/os/storage/StorageManager;->getAllocatableBytes(Ljava/util/UUID;I)J
 HSPLandroid/os/storage/StorageManager;->getStorageVolume(Ljava/io/File;I)Landroid/os/storage/StorageVolume;
 HSPLandroid/os/storage/StorageManager;->getStorageVolume([Landroid/os/storage/StorageVolume;Ljava/io/File;)Landroid/os/storage/StorageVolume;
@@ -13173,9 +13225,10 @@
 HSPLandroid/permission/PermissionManager;-><clinit>()V
 HSPLandroid/permission/PermissionManager;-><init>(Landroid/content/Context;)V
 HSPLandroid/permission/PermissionManager;->addOnPermissionsChangeListener(Landroid/content/pm/PackageManager$OnPermissionsChangedListener;)V
-HSPLandroid/permission/PermissionManager;->checkPermissionUncached(Ljava/lang/String;III)I+]Landroid/app/IActivityManager;Landroid/app/IActivityManager$Stub$Proxy;
+HSPLandroid/permission/PermissionManager;->checkPermissionUncached(Ljava/lang/String;III)I+]Landroid/app/IActivityManager;Landroid/app/IActivityManager$Stub$Proxy;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/permission/PermissionManager;->getPermissionFlags(Ljava/lang/String;Ljava/lang/String;Landroid/os/UserHandle;)I
 HSPLandroid/permission/PermissionManager;->getPermissionInfo(Ljava/lang/String;I)Landroid/content/pm/PermissionInfo;
+HSPLandroid/permission/PermissionManager;->getPersistentDeviceId(I)Ljava/lang/String;
 HSPLandroid/permission/PermissionManager;->getSplitPermissions()Ljava/util/List;
 HSPLandroid/permission/PermissionManager;->removeOnPermissionsChangeListener(Landroid/content/pm/PackageManager$OnPermissionsChangedListener;)V
 HSPLandroid/permission/PermissionManager;->splitPermissionInfoListToNonParcelableList(Ljava/util/List;)Ljava/util/List;
@@ -13235,15 +13288,15 @@
 HSPLandroid/provider/Settings$Global;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
 HSPLandroid/provider/Settings$Global;->getLong(Landroid/content/ContentResolver;Ljava/lang/String;J)J
 HSPLandroid/provider/Settings$Global;->getString(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/provider/Settings$Global;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
+HSPLandroid/provider/Settings$Global;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;+]Landroid/provider/Settings$NameValueCache;Landroid/provider/Settings$NameValueCache;]Ljava/util/HashSet;Ljava/util/HashSet;
 HSPLandroid/provider/Settings$Global;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
 HSPLandroid/provider/Settings$Global;->putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z
 HSPLandroid/provider/Settings$Global;->putLong(Landroid/content/ContentResolver;Ljava/lang/String;J)Z
 HSPLandroid/provider/Settings$Global;->putString(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;)Z
 HSPLandroid/provider/Settings$Global;->putStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZIZ)Z
 HSPLandroid/provider/Settings$NameValueCache$$ExternalSyntheticLambda0;-><init>(Landroid/provider/Settings$NameValueCache;)V
-HSPLandroid/provider/Settings$NameValueCache;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
-HSPLandroid/provider/Settings$NameValueCache;->getStringsForPrefixStripPrefix(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/util/List;)Ljava/util/Map;+]Landroid/content/ContentResolver;Landroid/app/ContextImpl$ApplicationContentResolver;]Landroid/content/IContentProvider;Landroid/content/ContentProvider$Transport;,Landroid/content/ContentProviderProxy;]Landroid/net/Uri;Landroid/net/Uri$StringUri;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/provider/Settings$ContentProviderHolder;Landroid/provider/Settings$ContentProviderHolder;]Landroid/provider/Settings$GenerationTracker;Landroid/provider/Settings$GenerationTracker;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/String;Ljava/lang/String;]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/util/Iterator;Ljava/util/Arrays$ArrayItr;,Ljava/util/HashMap$EntryIterator;]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Ljava/util/Map$Entry;Ljava/util/HashMap$Node;]Ljava/util/Set;Ljava/util/HashMap$EntrySet;
+HSPLandroid/provider/Settings$NameValueCache;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/content/IContentProvider;Landroid/content/ContentProviderProxy;]Landroid/provider/Settings$GenerationTracker;Landroid/provider/Settings$GenerationTracker;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/provider/Settings$ContentProviderHolder;Landroid/provider/Settings$ContentProviderHolder;]Landroid/content/ContentResolver;Landroid/app/ContextImpl$ApplicationContentResolver;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
+HSPLandroid/provider/Settings$NameValueCache;->getStringsForPrefixStripPrefix(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/util/List;)Ljava/util/Map;+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/Map$Entry;Ljava/util/HashMap$Node;]Landroid/provider/Settings$GenerationTracker;Landroid/provider/Settings$GenerationTracker;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/provider/Settings$ContentProviderHolder;Landroid/provider/Settings$ContentProviderHolder;]Ljava/util/Set;Ljava/util/HashMap$EntrySet;]Ljava/lang/String;Ljava/lang/String;]Landroid/content/IContentProvider;Landroid/content/ContentProviderProxy;,Landroid/content/ContentProvider$Transport;]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Landroid/content/ContentResolver;Landroid/app/ContextImpl$ApplicationContentResolver;]Ljava/util/Iterator;Ljava/util/HashMap$EntryIterator;,Ljava/util/Arrays$ArrayItr;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
 HSPLandroid/provider/Settings$NameValueCache;->isCallerExemptFromReadableRestriction()Z
 HSPLandroid/provider/Settings$NameValueCache;->putStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZIZ)Z
 HSPLandroid/provider/Settings$NameValueTable;->getUriFor(Landroid/net/Uri;Ljava/lang/String;)Landroid/net/Uri;
@@ -13254,7 +13307,7 @@
 HSPLandroid/provider/Settings$Secure;->getIntForUser(Landroid/content/ContentResolver;Ljava/lang/String;II)I
 HSPLandroid/provider/Settings$Secure;->getLong(Landroid/content/ContentResolver;Ljava/lang/String;J)J
 HSPLandroid/provider/Settings$Secure;->getLongForUser(Landroid/content/ContentResolver;Ljava/lang/String;JI)J
-HSPLandroid/provider/Settings$Secure;->getString(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/provider/Settings$Secure;->getString(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;+]Landroid/content/ContentResolver;Landroid/app/ContextImpl$ApplicationContentResolver;
 HSPLandroid/provider/Settings$Secure;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
 HSPLandroid/provider/Settings$Secure;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
 HSPLandroid/provider/Settings$Secure;->putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z
@@ -13269,7 +13322,7 @@
 HSPLandroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
 HSPLandroid/provider/Settings$System;->getIntForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)I
 HSPLandroid/provider/Settings$System;->getIntForUser(Landroid/content/ContentResolver;Ljava/lang/String;II)I
-HSPLandroid/provider/Settings$System;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
+HSPLandroid/provider/Settings$System;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;+]Landroid/provider/Settings$NameValueCache;Landroid/provider/Settings$NameValueCache;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/HashSet;Ljava/util/HashSet;
 HSPLandroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
 HSPLandroid/provider/Settings$System;->putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z
 HSPLandroid/provider/Settings$System;->putIntForUser(Landroid/content/ContentResolver;Ljava/lang/String;II)Z
@@ -13288,6 +13341,8 @@
 HSPLandroid/provider/Telephony$Sms;->getDefaultSmsPackage(Landroid/content/Context;)Ljava/lang/String;
 HSPLandroid/renderscript/RenderScriptCacheDir;->setupDiskCache(Ljava/io/File;)V
 HSPLandroid/se/omapi/SeServiceManager;-><init>()V
+HSPLandroid/security/FeatureFlagsImpl;-><init>()V
+HSPLandroid/security/Flags;-><clinit>()V
 HSPLandroid/security/KeyChain$1;-><init>(Ljava/util/concurrent/atomic/AtomicReference;Ljava/util/concurrent/CountDownLatch;)V
 HSPLandroid/security/KeyChain$1;->onServiceConnected(Landroid/content/ComponentName;Landroid/os/IBinder;)V
 HSPLandroid/security/KeyChain$KeyChainConnection;-><init>(Landroid/content/Context;Landroid/content/ServiceConnection;Landroid/security/IKeyChainService;)V
@@ -13304,6 +13359,7 @@
 HSPLandroid/security/KeyStore2;->getKeyStoreException(ILjava/lang/String;)Landroid/security/KeyStoreException;
 HSPLandroid/security/KeyStore2;->getService(Z)Landroid/system/keystore2/IKeystoreService;
 HSPLandroid/security/KeyStore2;->handleRemoteExceptionWithRetry(Landroid/security/KeyStore2$CheckedRemoteRequest;)Ljava/lang/Object;
+HSPLandroid/security/KeyStore;->getInstance()Landroid/security/KeyStore;
 HSPLandroid/security/KeyStoreException;-><init>(ILjava/lang/String;)V
 HSPLandroid/security/KeyStoreException;-><init>(ILjava/lang/String;Ljava/lang/String;)V
 HSPLandroid/security/KeyStoreException;->getErrorCode()I
@@ -13633,18 +13689,18 @@
 HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onListenerConnected(Landroid/service/notification/NotificationRankingUpdate;)V
 HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationChannelGroupModification(Ljava/lang/String;Landroid/os/UserHandle;Landroid/app/NotificationChannelGroup;I)V
 HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationChannelModification(Ljava/lang/String;Landroid/os/UserHandle;Landroid/app/NotificationChannel;I)V
-HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationPosted(Landroid/service/notification/IStatusBarNotificationHolder;Landroid/service/notification/NotificationRankingUpdate;)V
+HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationPosted(Landroid/service/notification/IStatusBarNotificationHolder;Landroid/service/notification/NotificationRankingUpdate;)V+]Landroid/os/Handler;Landroid/service/notification/NotificationListenerService$MyHandler;]Landroid/service/notification/IStatusBarNotificationHolder;Landroid/service/notification/IStatusBarNotificationHolder$Stub$Proxy;]Landroid/service/notification/StatusBarNotification;Landroid/service/notification/StatusBarNotification;]Landroid/os/Message;Landroid/os/Message;
 HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationRankingUpdate(Landroid/service/notification/NotificationRankingUpdate;)V
 HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationRemoved(Landroid/service/notification/IStatusBarNotificationHolder;Landroid/service/notification/NotificationRankingUpdate;Landroid/service/notification/NotificationStats;I)V
 HSPLandroid/service/notification/NotificationListenerService$Ranking;-><init>()V
-HSPLandroid/service/notification/NotificationListenerService$Ranking;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/service/notification/NotificationListenerService$Ranking;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Object;Landroid/service/notification/NotificationListenerService$Ranking;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/service/notification/NotificationListenerService$Ranking;->getChannel()Landroid/app/NotificationChannel;
 HSPLandroid/service/notification/NotificationListenerService$Ranking;->getKey()Ljava/lang/String;
-HSPLandroid/service/notification/NotificationListenerService$Ranking;->populate(Landroid/service/notification/NotificationListenerService$Ranking;)V
+HSPLandroid/service/notification/NotificationListenerService$Ranking;->populate(Landroid/service/notification/NotificationListenerService$Ranking;)V+]Landroid/service/notification/NotificationListenerService$Ranking;Landroid/service/notification/NotificationListenerService$Ranking;
 HSPLandroid/service/notification/NotificationListenerService$Ranking;->populate(Ljava/lang/String;IZIIILjava/lang/CharSequence;Ljava/lang/String;Landroid/app/NotificationChannel;Ljava/util/ArrayList;Ljava/util/ArrayList;ZIZJZLjava/util/ArrayList;Ljava/util/ArrayList;ZZZLandroid/content/pm/ShortcutInfo;IZIZ)V
 HSPLandroid/service/notification/NotificationListenerService$RankingMap$1;->createFromParcel(Landroid/os/Parcel;)Landroid/service/notification/NotificationListenerService$RankingMap;
 HSPLandroid/service/notification/NotificationListenerService$RankingMap$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/service/notification/NotificationListenerService$RankingMap;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/service/notification/NotificationListenerService$RankingMap;-><init>(Landroid/os/Parcel;)V+]Landroid/service/notification/NotificationListenerService$Ranking;Landroid/service/notification/NotificationListenerService$Ranking;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Object;Landroid/service/notification/NotificationListenerService$RankingMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/service/notification/NotificationListenerService$RankingMap;->getOrderedKeys()[Ljava/lang/String;
 HSPLandroid/service/notification/NotificationListenerService$RankingMap;->getRanking(Ljava/lang/String;Landroid/service/notification/NotificationListenerService$Ranking;)Z
 HSPLandroid/service/notification/NotificationListenerService;-><init>()V
@@ -13673,7 +13729,7 @@
 HSPLandroid/service/notification/NotificationRankingUpdate;->getRankingMap()Landroid/service/notification/NotificationListenerService$RankingMap;
 HSPLandroid/service/notification/StatusBarNotification$1;->createFromParcel(Landroid/os/Parcel;)Landroid/service/notification/StatusBarNotification;
 HSPLandroid/service/notification/StatusBarNotification$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/service/notification/StatusBarNotification;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/service/notification/StatusBarNotification;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Lcom/android/internal/logging/InstanceId$1;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/service/notification/StatusBarNotification;->getGroupKey()Ljava/lang/String;
 HSPLandroid/service/notification/StatusBarNotification;->getId()I
 HSPLandroid/service/notification/StatusBarNotification;->getInstanceId()Lcom/android/internal/logging/InstanceId;
@@ -13692,7 +13748,7 @@
 HSPLandroid/service/notification/StatusBarNotification;->isAppGroup()Z
 HSPLandroid/service/notification/StatusBarNotification;->isGroup()Z
 HSPLandroid/service/notification/StatusBarNotification;->isOngoing()Z
-HSPLandroid/service/notification/StatusBarNotification;->key()Ljava/lang/String;
+HSPLandroid/service/notification/StatusBarNotification;->key()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/os/UserHandle;Landroid/os/UserHandle;
 HSPLandroid/service/notification/ZenModeConfig$ZenRule$1;->createFromParcel(Landroid/os/Parcel;)Landroid/service/notification/ZenModeConfig$ZenRule;
 HSPLandroid/service/notification/ZenModeConfig$ZenRule$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/service/notification/ZenModeConfig$ZenRule;-><init>(Landroid/os/Parcel;)V
@@ -13940,7 +13996,7 @@
 HSPLandroid/telecom/PhoneAccountHandle;->getId()Ljava/lang/String;
 HSPLandroid/telecom/PhoneAccountHandle;->getUserHandle()Landroid/os/UserHandle;
 HSPLandroid/telecom/PhoneAccountHandle;->hashCode()I
-HSPLandroid/telecom/PhoneAccountHandle;->toString()Ljava/lang/String;
+HSPLandroid/telecom/PhoneAccountHandle;->toString()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/content/ComponentName;Landroid/content/ComponentName;
 HSPLandroid/telecom/PhoneAccountHandle;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/telecom/TelecomManager;-><init>(Landroid/content/Context;)V
 HSPLandroid/telecom/TelecomManager;-><init>(Landroid/content/Context;Lcom/android/internal/telecom/ITelecomService;)V
@@ -14079,7 +14135,7 @@
 HSPLandroid/telephony/NetworkRegistrationInfo$$ExternalSyntheticLambda0;->apply(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/telephony/NetworkRegistrationInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telephony/NetworkRegistrationInfo;
 HSPLandroid/telephony/NetworkRegistrationInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/telephony/NetworkRegistrationInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/telephony/NetworkRegistrationInfo;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/telephony/NetworkRegistrationInfo;-><init>(Landroid/telephony/NetworkRegistrationInfo;)V
 HSPLandroid/telephony/NetworkRegistrationInfo;->domainToString(I)Ljava/lang/String;
 HSPLandroid/telephony/NetworkRegistrationInfo;->getAccessNetworkTechnology()I
@@ -14103,7 +14159,7 @@
 HSPLandroid/telephony/PhoneNumberUtils;->getMinMatch()I
 HSPLandroid/telephony/PhoneNumberUtils;->isDialable(C)Z
 HSPLandroid/telephony/PhoneNumberUtils;->isNonSeparator(C)Z
-HSPLandroid/telephony/PhoneNumberUtils;->normalizeNumber(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/telephony/PhoneNumberUtils;->normalizeNumber(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/telephony/PhoneNumberUtils;->stripSeparators(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/telephony/PhoneStateListener$IPhoneStateListenerStub$$ExternalSyntheticLambda10;->runOrThrow()V
 HSPLandroid/telephony/PhoneStateListener$IPhoneStateListenerStub$$ExternalSyntheticLambda19;->runOrThrow()V
@@ -14135,7 +14191,7 @@
 HSPLandroid/telephony/ServiceState$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telephony/ServiceState;
 HSPLandroid/telephony/ServiceState$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/telephony/ServiceState;-><init>()V
-HSPLandroid/telephony/ServiceState;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/telephony/ServiceState;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/telephony/ServiceState;-><init>(Landroid/telephony/ServiceState;)V
 HSPLandroid/telephony/ServiceState;->copyFrom(Landroid/telephony/ServiceState;)V
 HSPLandroid/telephony/ServiceState;->createLocationInfoSanitizedCopy(Z)Landroid/telephony/ServiceState;
@@ -14175,7 +14231,7 @@
 HSPLandroid/telephony/SignalStrength;->getLevel()I
 HSPLandroid/telephony/SignalStrength;->getPrimary()Landroid/telephony/CellSignalStrength;
 HSPLandroid/telephony/SignalStrength;->writeToParcel(Landroid/os/Parcel;I)V
-HSPLandroid/telephony/SubscriptionInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telephony/SubscriptionInfo;+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/text/TextUtils$1;]Landroid/telephony/SubscriptionInfo$Builder;Landroid/telephony/SubscriptionInfo$Builder;
+HSPLandroid/telephony/SubscriptionInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telephony/SubscriptionInfo;+]Landroid/os/Parcelable$Creator;Landroid/text/TextUtils$1;]Landroid/telephony/SubscriptionInfo$Builder;Landroid/telephony/SubscriptionInfo$Builder;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/telephony/SubscriptionInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/telephony/SubscriptionInfo$Builder;->-$$Nest$fgetmAreUiccApplicationsEnabled(Landroid/telephony/SubscriptionInfo$Builder;)Z
 HSPLandroid/telephony/SubscriptionInfo$Builder;->-$$Nest$fgetmCardId(Landroid/telephony/SubscriptionInfo$Builder;)I
@@ -14258,6 +14314,8 @@
 HSPLandroid/telephony/SubscriptionInfo;->isEmbedded()Z
 HSPLandroid/telephony/SubscriptionInfo;->isOpportunistic()Z
 HSPLandroid/telephony/SubscriptionInfo;->toString()Ljava/lang/String;
+HSPLandroid/telephony/SubscriptionManager$$ExternalSyntheticLambda10;->applyOrThrow(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/telephony/SubscriptionManager$$ExternalSyntheticLambda15;->applyOrThrow(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/telephony/SubscriptionManager$$ExternalSyntheticLambda9;->applyOrThrow(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/telephony/SubscriptionManager$IntegerPropertyInvalidatedCache;->query(Ljava/lang/Integer;)Ljava/lang/Object;
 HSPLandroid/telephony/SubscriptionManager$IntegerPropertyInvalidatedCache;->recompute(Ljava/lang/Integer;)Ljava/lang/Object;
@@ -14368,6 +14426,7 @@
 HSPLandroid/telephony/TelephonyManager;->getServiceState()Landroid/telephony/ServiceState;
 HSPLandroid/telephony/TelephonyManager;->getServiceState(I)Landroid/telephony/ServiceState;
 HSPLandroid/telephony/TelephonyManager;->getServiceStateForSubscriber(I)Landroid/telephony/ServiceState;
+HSPLandroid/telephony/TelephonyManager;->getServiceStateForSubscriber(IZZ)Landroid/telephony/ServiceState;
 HSPLandroid/telephony/TelephonyManager;->getSignalStrength()Landroid/telephony/SignalStrength;
 HSPLandroid/telephony/TelephonyManager;->getSimCarrierId()I
 HSPLandroid/telephony/TelephonyManager;->getSimCountryIso()Ljava/lang/String;
@@ -14480,7 +14539,7 @@
 HSPLandroid/telephony/data/ApnSetting;->getApnTypeBitmask()I
 HSPLandroid/telephony/data/ApnSetting;->getApnTypesStringFromBitmask(I)Ljava/lang/String;
 HSPLandroid/telephony/data/ApnSetting;->portToString(I)Ljava/lang/String;
-HSPLandroid/telephony/data/ApnSetting;->toString()Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/Map;Landroid/util/ArrayMap;
+HSPLandroid/telephony/data/ApnSetting;->toString()Ljava/lang/String;
 HSPLandroid/telephony/euicc/EuiccManager;->getIEuiccController()Lcom/android/internal/telephony/euicc/IEuiccController;
 HSPLandroid/telephony/euicc/EuiccManager;->isEnabled()Z
 HSPLandroid/telephony/ims/ImsMmTelManager;->createForSubscriptionId(I)Landroid/telephony/ims/ImsMmTelManager;
@@ -14529,7 +14588,7 @@
 HSPLandroid/text/BidiFormatter;->unicodeWrap(Ljava/lang/CharSequence;Landroid/text/TextDirectionHeuristic;Z)Ljava/lang/CharSequence;
 HSPLandroid/text/BoringLayout$Metrics;->-$$Nest$mreset(Landroid/text/BoringLayout$Metrics;)V
 HSPLandroid/text/BoringLayout$Metrics;-><init>()V
-HSPLandroid/text/BoringLayout$Metrics;->reset()V+]Landroid/graphics/RectF;Landroid/graphics/RectF;
+HSPLandroid/text/BoringLayout$Metrics;->reset()V
 HSPLandroid/text/BoringLayout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FFLandroid/text/BoringLayout$Metrics;Z)V
 HSPLandroid/text/BoringLayout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FFLandroid/text/BoringLayout$Metrics;ZLandroid/text/TextUtils$TruncateAt;I)V
 HSPLandroid/text/BoringLayout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FFLandroid/text/BoringLayout$Metrics;ZLandroid/text/TextUtils$TruncateAt;IZ)V
@@ -14544,13 +14603,14 @@
 HSPLandroid/text/BoringLayout;->getLineDescent(I)I
 HSPLandroid/text/BoringLayout;->getLineDirections(I)Landroid/text/Layout$Directions;
 HSPLandroid/text/BoringLayout;->getLineMax(I)F
-HSPLandroid/text/BoringLayout;->getLineStart(I)I+]Landroid/text/BoringLayout;Landroid/text/BoringLayout;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/text/BoringLayout;->getLineStart(I)I
 HSPLandroid/text/BoringLayout;->getLineTop(I)I
 HSPLandroid/text/BoringLayout;->getLineWidth(I)F
 HSPLandroid/text/BoringLayout;->getParagraphDirection(I)I
 HSPLandroid/text/BoringLayout;->hasAnyInterestingChars(Ljava/lang/CharSequence;I)Z
 HSPLandroid/text/BoringLayout;->init(Ljava/lang/CharSequence;Landroid/text/TextPaint;Landroid/text/Layout$Alignment;Landroid/text/BoringLayout$Metrics;ZZZ)V+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Ljava/lang/CharSequence;Ljava/lang/String;
 HSPLandroid/text/BoringLayout;->isBoring(Ljava/lang/CharSequence;Landroid/text/TextPaint;Landroid/text/TextDirectionHeuristic;Landroid/text/BoringLayout$Metrics;)Landroid/text/BoringLayout$Metrics;
+HSPLandroid/text/BoringLayout;->isBoring(Ljava/lang/CharSequence;Landroid/text/TextPaint;Landroid/text/TextDirectionHeuristic;ZLandroid/graphics/Paint$FontMetrics;Landroid/text/BoringLayout$Metrics;)Landroid/text/BoringLayout$Metrics;+]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/Spanned;megamorphic_types]Ljava/lang/CharSequence;megamorphic_types]Landroid/text/TextDirectionHeuristic;Landroid/text/TextDirectionHeuristics$TextDirectionHeuristicLocale;,Landroid/text/TextDirectionHeuristics$TextDirectionHeuristicInternal;
 HSPLandroid/text/BoringLayout;->isBoring(Ljava/lang/CharSequence;Landroid/text/TextPaint;Landroid/text/TextDirectionHeuristic;ZLandroid/text/BoringLayout$Metrics;)Landroid/text/BoringLayout$Metrics;
 HSPLandroid/text/BoringLayout;->isFallbackLineSpacingEnabled()Z
 HSPLandroid/text/BoringLayout;->make(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FFLandroid/text/BoringLayout$Metrics;Z)Landroid/text/BoringLayout;
@@ -14565,7 +14625,8 @@
 HSPLandroid/text/CharSequenceCharacterIterator;->getIndex()I
 HSPLandroid/text/CharSequenceCharacterIterator;->next()C
 HSPLandroid/text/CharSequenceCharacterIterator;->setIndex(I)C
-HSPLandroid/text/DynamicLayout$Builder;->obtain(Ljava/lang/CharSequence;Landroid/text/TextPaint;I)Landroid/text/DynamicLayout$Builder;
+HSPLandroid/text/ClientFlags;->icuBidiMigration()Z
+HSPLandroid/text/DynamicLayout$Builder;->obtain(Ljava/lang/CharSequence;Landroid/text/TextPaint;I)Landroid/text/DynamicLayout$Builder;+]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
 HSPLandroid/text/DynamicLayout$ChangeWatcher;->afterTextChanged(Landroid/text/Editable;)V
 HSPLandroid/text/DynamicLayout$ChangeWatcher;->beforeTextChanged(Ljava/lang/CharSequence;III)V
 HSPLandroid/text/DynamicLayout$ChangeWatcher;->onSpanAdded(Landroid/text/Spannable;Ljava/lang/Object;II)V
@@ -14573,29 +14634,29 @@
 HSPLandroid/text/DynamicLayout$ChangeWatcher;->onSpanRemoved(Landroid/text/Spannable;Ljava/lang/Object;II)V
 HSPLandroid/text/DynamicLayout$ChangeWatcher;->onTextChanged(Ljava/lang/CharSequence;III)V
 HSPLandroid/text/DynamicLayout;-><init>(Landroid/text/DynamicLayout$Builder;)V
-HSPLandroid/text/DynamicLayout;->addBlockAtOffset(I)V
-HSPLandroid/text/DynamicLayout;->contentMayProtrudeFromLineTopOrBottom(Ljava/lang/CharSequence;II)Z
+HSPLandroid/text/DynamicLayout;->addBlockAtOffset(I)V+]Landroid/text/DynamicLayout;Landroid/text/DynamicLayout;
+HSPLandroid/text/DynamicLayout;->contentMayProtrudeFromLineTopOrBottom(Ljava/lang/CharSequence;II)Z+]Landroid/text/DynamicLayout;Landroid/text/DynamicLayout;]Landroid/graphics/Paint;Landroid/text/TextPaint;]Landroid/text/Spanned;Landroid/text/SpannableString;
 HSPLandroid/text/DynamicLayout;->createBlocks()V
-HSPLandroid/text/DynamicLayout;->generate(Landroid/text/DynamicLayout$Builder;)V
+HSPLandroid/text/DynamicLayout;->generate(Landroid/text/DynamicLayout$Builder;)V+]Landroid/text/DynamicLayout;Landroid/text/DynamicLayout;]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;]Landroid/text/PackedObjectVector;Landroid/text/PackedObjectVector;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Landroid/text/method/ReplacementTransformationMethod$SpannedReplacementCharSequence;,Landroid/text/SpannableStringBuilder;]Landroid/text/Spannable;Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/DynamicLayout;->getBlockEndLines()[I
 HSPLandroid/text/DynamicLayout;->getBlockIndices()[I
 HSPLandroid/text/DynamicLayout;->getBlocksAlwaysNeedToBeRedrawn()Landroid/util/ArraySet;
 HSPLandroid/text/DynamicLayout;->getEllipsisCount(I)I
 HSPLandroid/text/DynamicLayout;->getEllipsisStart(I)I
 HSPLandroid/text/DynamicLayout;->getEllipsizedWidth()I
-HSPLandroid/text/DynamicLayout;->getEndHyphenEdit(I)I
+HSPLandroid/text/DynamicLayout;->getEndHyphenEdit(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
 HSPLandroid/text/DynamicLayout;->getIndexFirstChangedBlock()I
-HSPLandroid/text/DynamicLayout;->getLineContainsTab(I)Z
-HSPLandroid/text/DynamicLayout;->getLineCount()I
-HSPLandroid/text/DynamicLayout;->getLineDescent(I)I
-HSPLandroid/text/DynamicLayout;->getLineDirections(I)Landroid/text/Layout$Directions;
+HSPLandroid/text/DynamicLayout;->getLineContainsTab(I)Z+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getLineCount()I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getLineDescent(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getLineDirections(I)Landroid/text/Layout$Directions;+]Landroid/text/PackedObjectVector;Landroid/text/PackedObjectVector;
 HSPLandroid/text/DynamicLayout;->getLineExtra(I)I
-HSPLandroid/text/DynamicLayout;->getLineStart(I)I
-HSPLandroid/text/DynamicLayout;->getLineTop(I)I
+HSPLandroid/text/DynamicLayout;->getLineStart(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getLineTop(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
 HSPLandroid/text/DynamicLayout;->getNumberOfBlocks()I
-HSPLandroid/text/DynamicLayout;->getParagraphDirection(I)I
-HSPLandroid/text/DynamicLayout;->getStartHyphenEdit(I)I
-HSPLandroid/text/DynamicLayout;->reflow(Ljava/lang/CharSequence;III)V
+HSPLandroid/text/DynamicLayout;->getParagraphDirection(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getStartHyphenEdit(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->reflow(Ljava/lang/CharSequence;III)V+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;]Landroid/text/DynamicLayout;Landroid/text/DynamicLayout;]Landroid/text/PackedObjectVector;Landroid/text/PackedObjectVector;]Landroid/text/StaticLayout;Landroid/text/StaticLayout;]Landroid/text/Spanned;Landroid/text/SpannableString;]Ljava/lang/CharSequence;Landroid/text/SpannableString;]Landroid/text/StaticLayout$Builder;Landroid/text/StaticLayout$Builder;
 HSPLandroid/text/DynamicLayout;->setIndexFirstChangedBlock(I)V
 HSPLandroid/text/DynamicLayout;->updateAlwaysNeedsToBeRedrawn(I)V
 HSPLandroid/text/DynamicLayout;->updateBlocks(III)V
@@ -14610,7 +14671,7 @@
 HSPLandroid/text/Html;->fromHtml(Ljava/lang/String;I)Landroid/text/Spanned;
 HSPLandroid/text/Html;->fromHtml(Ljava/lang/String;ILandroid/text/Html$ImageGetter;Landroid/text/Html$TagHandler;)Landroid/text/Spanned;
 HSPLandroid/text/HtmlToSpannedConverter;-><init>(Ljava/lang/String;Landroid/text/Html$ImageGetter;Landroid/text/Html$TagHandler;Lorg/ccil/cowan/tagsoup/Parser;I)V
-HSPLandroid/text/HtmlToSpannedConverter;->characters([CII)V+]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/text/HtmlToSpannedConverter;->characters([CII)V
 HSPLandroid/text/HtmlToSpannedConverter;->convert()Landroid/text/Spanned;
 HSPLandroid/text/HtmlToSpannedConverter;->end(Landroid/text/Editable;Ljava/lang/Class;Ljava/lang/Object;)V
 HSPLandroid/text/HtmlToSpannedConverter;->endA(Landroid/text/Editable;)V
@@ -14619,8 +14680,8 @@
 HSPLandroid/text/HtmlToSpannedConverter;->endPrefixMapping(Ljava/lang/String;)V
 HSPLandroid/text/HtmlToSpannedConverter;->getLast(Landroid/text/Spanned;Ljava/lang/Class;)Ljava/lang/Object;
 HSPLandroid/text/HtmlToSpannedConverter;->handleBr(Landroid/text/Editable;)V
-HSPLandroid/text/HtmlToSpannedConverter;->handleEndTag(Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;
-HSPLandroid/text/HtmlToSpannedConverter;->handleStartTag(Ljava/lang/String;Lorg/xml/sax/Attributes;)V+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/text/HtmlToSpannedConverter;->handleEndTag(Ljava/lang/String;)V
+HSPLandroid/text/HtmlToSpannedConverter;->handleStartTag(Ljava/lang/String;Lorg/xml/sax/Attributes;)V
 HSPLandroid/text/HtmlToSpannedConverter;->setDocumentLocator(Lorg/xml/sax/Locator;)V
 HSPLandroid/text/HtmlToSpannedConverter;->setSpanFromMark(Landroid/text/Spannable;Ljava/lang/Object;[Ljava/lang/Object;)V
 HSPLandroid/text/HtmlToSpannedConverter;->start(Landroid/text/Editable;Ljava/lang/Object;)V
@@ -14638,7 +14699,7 @@
 HSPLandroid/text/Layout$Directions;->isRunRtl(I)Z
 HSPLandroid/text/Layout$Ellipsizer;-><init>(Ljava/lang/CharSequence;)V
 HSPLandroid/text/Layout$Ellipsizer;->charAt(I)C
-HSPLandroid/text/Layout$Ellipsizer;->getChars(II[CI)V+]Landroid/text/Layout;Landroid/text/StaticLayout;
+HSPLandroid/text/Layout$Ellipsizer;->getChars(II[CI)V
 HSPLandroid/text/Layout$Ellipsizer;->length()I
 HSPLandroid/text/Layout$HorizontalMeasurementProvider;->init()V
 HSPLandroid/text/Layout$SpannedEllipsizer;->getSpanEnd(Ljava/lang/Object;)I
@@ -14647,12 +14708,13 @@
 HSPLandroid/text/Layout$SpannedEllipsizer;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;
 HSPLandroid/text/Layout$SpannedEllipsizer;->nextSpanTransition(IILjava/lang/Class;)I
 HSPLandroid/text/Layout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FF)V
+HSPLandroid/text/Layout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;Landroid/text/TextDirectionHeuristic;FFZZILandroid/text/TextUtils$TruncateAt;III[I[IILandroid/graphics/text/LineBreakConfig;ZZLandroid/graphics/Paint$FontMetrics;)V
 HSPLandroid/text/Layout;->addSelection(IIIIILandroid/text/Layout$SelectionRectangleConsumer;)V
 HSPLandroid/text/Layout;->draw(Landroid/graphics/Canvas;)V
 HSPLandroid/text/Layout;->draw(Landroid/graphics/Canvas;Landroid/graphics/Path;Landroid/graphics/Paint;I)V
-HSPLandroid/text/Layout;->draw(Landroid/graphics/Canvas;Ljava/util/List;Ljava/util/List;Landroid/graphics/Path;Landroid/graphics/Paint;I)V
+HSPLandroid/text/Layout;->draw(Landroid/graphics/Canvas;Ljava/util/List;Ljava/util/List;Landroid/graphics/Path;Landroid/graphics/Paint;I)V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;
 HSPLandroid/text/Layout;->drawBackground(Landroid/graphics/Canvas;II)V
-HSPLandroid/text/Layout;->drawText(Landroid/graphics/Canvas;II)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/text/Spanned;Landroid/text/Layout$SpannedEllipsizer;,Landroid/text/SpannableString;]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Landroid/text/Layout$SpannedEllipsizer;,Landroid/text/SpannableString;
+HSPLandroid/text/Layout;->drawText(Landroid/graphics/Canvas;II)V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;,Landroid/text/DynamicLayout;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/Spanned;Landroid/text/SpannableString;]Ljava/lang/CharSequence;Landroid/text/SpannableString;
 HSPLandroid/text/Layout;->drawWithoutText(Landroid/graphics/Canvas;Ljava/util/List;Ljava/util/List;Landroid/graphics/Path;Landroid/graphics/Paint;III)V
 HSPLandroid/text/Layout;->ellipsize(III[CILandroid/text/TextUtils$TruncateAt;)V
 HSPLandroid/text/Layout;->getCursorPath(ILandroid/graphics/Path;Ljava/lang/CharSequence;)V
@@ -14664,30 +14726,30 @@
 HSPLandroid/text/Layout;->getHorizontal(IZ)F
 HSPLandroid/text/Layout;->getHorizontal(IZIZ)F
 HSPLandroid/text/Layout;->getIndentAdjust(ILandroid/text/Layout$Alignment;)I
-HSPLandroid/text/Layout;->getLineBaseline(I)I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;
+HSPLandroid/text/Layout;->getLineBaseline(I)I
 HSPLandroid/text/Layout;->getLineBottom(I)I
 HSPLandroid/text/Layout;->getLineBottom(IZ)I
-HSPLandroid/text/Layout;->getLineEnd(I)I
-HSPLandroid/text/Layout;->getLineExtent(ILandroid/text/Layout$TabStops;Z)F+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/TextPaint;Landroid/text/TextPaint;
+HSPLandroid/text/Layout;->getLineEnd(I)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;,Landroid/text/StaticLayout;
+HSPLandroid/text/Layout;->getLineExtent(ILandroid/text/Layout$TabStops;Z)F
 HSPLandroid/text/Layout;->getLineExtent(IZ)F
-HSPLandroid/text/Layout;->getLineForOffset(I)I+]Landroid/text/Layout;Landroid/text/StaticLayout;
-HSPLandroid/text/Layout;->getLineForVertical(I)I+]Landroid/text/Layout;Landroid/text/BoringLayout;
+HSPLandroid/text/Layout;->getLineForOffset(I)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;
+HSPLandroid/text/Layout;->getLineForVertical(I)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;
 HSPLandroid/text/Layout;->getLineLeft(I)F
 HSPLandroid/text/Layout;->getLineMax(I)F
-HSPLandroid/text/Layout;->getLineRangeForDraw(Landroid/graphics/Canvas;)J+]Landroid/graphics/Canvas;missing_types]Landroid/text/Layout;Landroid/text/StaticLayout;
+HSPLandroid/text/Layout;->getLineRangeForDraw(Landroid/graphics/Canvas;)J+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/text/Layout;->getLineRight(I)F
 HSPLandroid/text/Layout;->getLineStartPos(III)I
 HSPLandroid/text/Layout;->getLineVisibleEnd(I)I
 HSPLandroid/text/Layout;->getLineWidth(I)F
 HSPLandroid/text/Layout;->getOffsetAtStartOf(I)I
 HSPLandroid/text/Layout;->getOffsetForHorizontal(IF)I
-HSPLandroid/text/Layout;->getOffsetForHorizontal(IFZ)I
+HSPLandroid/text/Layout;->getOffsetForHorizontal(IFZ)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/Layout$HorizontalMeasurementProvider;Landroid/text/Layout$HorizontalMeasurementProvider;
 HSPLandroid/text/Layout;->getPaint()Landroid/text/TextPaint;
-HSPLandroid/text/Layout;->getParagraphAlignment(I)Landroid/text/Layout$Alignment;
-HSPLandroid/text/Layout;->getParagraphLeadingMargin(I)I
+HSPLandroid/text/Layout;->getParagraphAlignment(I)Landroid/text/Layout$Alignment;+]Landroid/text/Layout;Landroid/text/DynamicLayout;
+HSPLandroid/text/Layout;->getParagraphLeadingMargin(I)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;]Landroid/text/Spanned;missing_types
 HSPLandroid/text/Layout;->getParagraphLeft(I)I
 HSPLandroid/text/Layout;->getParagraphRight(I)I
-HSPLandroid/text/Layout;->getParagraphSpans(Landroid/text/Spanned;IILjava/lang/Class;)[Ljava/lang/Object;
+HSPLandroid/text/Layout;->getParagraphSpans(Landroid/text/Spanned;IILjava/lang/Class;)[Ljava/lang/Object;+]Landroid/text/Spanned;Landroid/text/SpannableString;
 HSPLandroid/text/Layout;->getPrimaryHorizontal(I)F
 HSPLandroid/text/Layout;->getPrimaryHorizontal(IZ)F
 HSPLandroid/text/Layout;->getSelection(IILandroid/text/Layout$SelectionRectangleConsumer;)V
@@ -14706,7 +14768,8 @@
 HSPLandroid/text/Layout;->replaceWith(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FF)V
 HSPLandroid/text/Layout;->shouldClampCursor(I)Z
 HSPLandroid/text/MeasuredParagraph;-><init>()V
-HSPLandroid/text/MeasuredParagraph;->applyMetricsAffectingSpan(Landroid/text/TextPaint;Landroid/graphics/text/LineBreakConfig;[Landroid/text/style/MetricAffectingSpan;[Landroid/text/style/LineBreakConfigSpan;IILandroid/graphics/text/MeasuredText$Builder;Landroid/text/MeasuredParagraph$StyleRunCallback;)V+]Landroid/graphics/text/LineBreakConfig$Builder;Landroid/graphics/text/LineBreakConfig$Builder;]Landroid/text/AutoGrowArray$IntArray;Landroid/text/AutoGrowArray$IntArray;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/text/style/MetricAffectingSpan;missing_types
+HSPLandroid/text/MeasuredParagraph;->applyMetricsAffectingSpan(Landroid/text/TextPaint;Landroid/graphics/text/LineBreakConfig;[Landroid/text/style/MetricAffectingSpan;[Landroid/text/style/LineBreakConfigSpan;IILandroid/graphics/text/MeasuredText$Builder;Landroid/text/MeasuredParagraph$StyleRunCallback;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/graphics/text/LineBreakConfig$Builder;Landroid/graphics/text/LineBreakConfig$Builder;]Landroid/text/AutoGrowArray$IntArray;Landroid/text/AutoGrowArray$IntArray;]Landroid/text/style/MetricAffectingSpan;missing_types
+HSPLandroid/text/MeasuredParagraph;->applyStyleRun(IILandroid/text/TextPaint;Landroid/graphics/text/LineBreakConfig;Landroid/graphics/text/MeasuredText$Builder;Landroid/text/MeasuredParagraph$StyleRunCallback;)V+]Landroid/text/AutoGrowArray$FloatArray;Landroid/text/AutoGrowArray$FloatArray;]Landroid/graphics/text/MeasuredText$Builder;Landroid/graphics/text/MeasuredText$Builder;]Landroid/text/AutoGrowArray$ByteArray;Landroid/text/AutoGrowArray$ByteArray;]Landroid/text/TextPaint;Landroid/text/TextPaint;
 HSPLandroid/text/MeasuredParagraph;->breakText(IZF)I
 HSPLandroid/text/MeasuredParagraph;->buildForBidi(Ljava/lang/CharSequence;IILandroid/text/TextDirectionHeuristic;Landroid/text/MeasuredParagraph;)Landroid/text/MeasuredParagraph;
 HSPLandroid/text/MeasuredParagraph;->buildForMeasurement(Landroid/text/TextPaint;Ljava/lang/CharSequence;IILandroid/text/TextDirectionHeuristic;Landroid/text/MeasuredParagraph;)Landroid/text/MeasuredParagraph;
@@ -14725,9 +14788,9 @@
 HSPLandroid/text/MeasuredParagraph;->resetAndAnalyzeBidi(Ljava/lang/CharSequence;IILandroid/text/TextDirectionHeuristic;)V
 HSPLandroid/text/PackedIntVector;->adjustValuesBelow(III)V
 HSPLandroid/text/PackedIntVector;->deleteAt(II)V
-HSPLandroid/text/PackedIntVector;->getValue(II)I
+HSPLandroid/text/PackedIntVector;->getValue(II)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
 HSPLandroid/text/PackedIntVector;->growBuffer()V
-HSPLandroid/text/PackedIntVector;->insertAt(I[I)V
+HSPLandroid/text/PackedIntVector;->insertAt(I[I)V+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
 HSPLandroid/text/PackedIntVector;->moveRowGapTo(I)V
 HSPLandroid/text/PackedIntVector;->moveValueGapTo(II)V
 HSPLandroid/text/PackedIntVector;->size()I
@@ -14735,7 +14798,7 @@
 HSPLandroid/text/PackedObjectVector;->deleteAt(II)V
 HSPLandroid/text/PackedObjectVector;->getValue(II)Ljava/lang/Object;
 HSPLandroid/text/PackedObjectVector;->growBuffer()V
-HSPLandroid/text/PackedObjectVector;->insertAt(I[Ljava/lang/Object;)V
+HSPLandroid/text/PackedObjectVector;->insertAt(I[Ljava/lang/Object;)V+]Landroid/text/PackedObjectVector;Landroid/text/PackedObjectVector;
 HSPLandroid/text/PackedObjectVector;->moveRowGapTo(I)V
 HSPLandroid/text/PackedObjectVector;->setValue(IILjava/lang/Object;)V
 HSPLandroid/text/PackedObjectVector;->size()I
@@ -14746,7 +14809,7 @@
 HSPLandroid/text/PrecomputedText$Params;->getTextDirection()Landroid/text/TextDirectionHeuristic;
 HSPLandroid/text/PrecomputedText$Params;->getTextPaint()Landroid/text/TextPaint;
 HSPLandroid/text/Selection;->getSelectionEnd(Ljava/lang/CharSequence;)I
-HSPLandroid/text/Selection;->getSelectionStart(Ljava/lang/CharSequence;)I
+HSPLandroid/text/Selection;->getSelectionStart(Ljava/lang/CharSequence;)I+]Landroid/text/Spanned;missing_types
 HSPLandroid/text/Selection;->removeMemory(Landroid/text/Spannable;)V
 HSPLandroid/text/Selection;->removeSelection(Landroid/text/Spannable;)V
 HSPLandroid/text/Selection;->setSelection(Landroid/text/Spannable;I)V
@@ -14756,7 +14819,7 @@
 HSPLandroid/text/SpanSet;-><init>(Ljava/lang/Class;)V
 HSPLandroid/text/SpanSet;->getNextTransition(II)I
 HSPLandroid/text/SpanSet;->hasSpansIntersecting(II)Z
-HSPLandroid/text/SpanSet;->init(Landroid/text/Spanned;II)V
+HSPLandroid/text/SpanSet;->init(Landroid/text/Spanned;II)V+]Landroid/text/Spanned;Landroid/text/SpannableString;
 HSPLandroid/text/SpanSet;->recycle()V
 HSPLandroid/text/Spannable$Factory;->getInstance()Landroid/text/Spannable$Factory;
 HSPLandroid/text/Spannable$Factory;->newSpannable(Ljava/lang/CharSequence;)Landroid/text/Spannable;
@@ -14774,32 +14837,32 @@
 HSPLandroid/text/SpannableString;->subSequence(II)Ljava/lang/CharSequence;
 HSPLandroid/text/SpannableString;->valueOf(Ljava/lang/CharSequence;)Landroid/text/SpannableString;
 HSPLandroid/text/SpannableStringBuilder;-><init>()V
-HSPLandroid/text/SpannableStringBuilder;-><init>(Ljava/lang/CharSequence;)V
+HSPLandroid/text/SpannableStringBuilder;-><init>(Ljava/lang/CharSequence;)V+]Ljava/lang/CharSequence;missing_types
 HSPLandroid/text/SpannableStringBuilder;-><init>(Ljava/lang/CharSequence;II)V
 HSPLandroid/text/SpannableStringBuilder;->append(C)Landroid/text/Editable;
 HSPLandroid/text/SpannableStringBuilder;->append(C)Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringBuilder;->append(Ljava/lang/CharSequence;)Landroid/text/Editable;
-HSPLandroid/text/SpannableStringBuilder;->append(Ljava/lang/CharSequence;)Landroid/text/SpannableStringBuilder;
+HSPLandroid/text/SpannableStringBuilder;->append(Ljava/lang/CharSequence;)Landroid/text/SpannableStringBuilder;+]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/SpannedString;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringBuilder;->append(Ljava/lang/CharSequence;II)Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringBuilder;->calcMax(I)I
-HSPLandroid/text/SpannableStringBuilder;->change(IILjava/lang/CharSequence;II)V
+HSPLandroid/text/SpannableStringBuilder;->change(IILjava/lang/CharSequence;II)V+]Landroid/text/Spanned;Landroid/text/SpannedString;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringBuilder;->charAt(I)C
-HSPLandroid/text/SpannableStringBuilder;->checkRange(Ljava/lang/String;II)V
+HSPLandroid/text/SpannableStringBuilder;->checkRange(Ljava/lang/String;II)V+]Landroid/text/SpannableStringBuilder;missing_types
 HSPLandroid/text/SpannableStringBuilder;->checkSortBuffer([II)[I
 HSPLandroid/text/SpannableStringBuilder;->clear()V
 HSPLandroid/text/SpannableStringBuilder;->compareSpans(II[I[I)I
-HSPLandroid/text/SpannableStringBuilder;->countSpans(IILjava/lang/Class;I)I
+HSPLandroid/text/SpannableStringBuilder;->countSpans(IILjava/lang/Class;I)I+]Ljava/lang/Class;Ljava/lang/Class;
 HSPLandroid/text/SpannableStringBuilder;->delete(II)Landroid/text/Editable;
 HSPLandroid/text/SpannableStringBuilder;->delete(II)Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringBuilder;->drawTextRun(Landroid/graphics/BaseCanvas;IIIIFFZLandroid/graphics/Paint;)V
 HSPLandroid/text/SpannableStringBuilder;->equals(Ljava/lang/Object;)Z
 HSPLandroid/text/SpannableStringBuilder;->getChars(II[CI)V
-HSPLandroid/text/SpannableStringBuilder;->getSpanEnd(Ljava/lang/Object;)I
-HSPLandroid/text/SpannableStringBuilder;->getSpanFlags(Ljava/lang/Object;)I
-HSPLandroid/text/SpannableStringBuilder;->getSpanStart(Ljava/lang/Object;)I
-HSPLandroid/text/SpannableStringBuilder;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;
+HSPLandroid/text/SpannableStringBuilder;->getSpanEnd(Ljava/lang/Object;)I+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
+HSPLandroid/text/SpannableStringBuilder;->getSpanFlags(Ljava/lang/Object;)I+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
+HSPLandroid/text/SpannableStringBuilder;->getSpanStart(Ljava/lang/Object;)I+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
+HSPLandroid/text/SpannableStringBuilder;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;+]Landroid/text/SpannableStringBuilder;missing_types
 HSPLandroid/text/SpannableStringBuilder;->getSpans(IILjava/lang/Class;Z)[Ljava/lang/Object;
-HSPLandroid/text/SpannableStringBuilder;->getSpansRec(IILjava/lang/Class;I[Ljava/lang/Object;[I[IIZ)I
+HSPLandroid/text/SpannableStringBuilder;->getSpansRec(IILjava/lang/Class;I[Ljava/lang/Object;[I[IIZ)I+]Ljava/lang/Class;Ljava/lang/Class;
 HSPLandroid/text/SpannableStringBuilder;->getTextWatcherDepth()I
 HSPLandroid/text/SpannableStringBuilder;->hasNonExclusiveExclusiveSpanAt(Ljava/lang/CharSequence;I)Z
 HSPLandroid/text/SpannableStringBuilder;->insert(ILjava/lang/CharSequence;)Landroid/text/SpannableStringBuilder;
@@ -14818,48 +14881,48 @@
 HSPLandroid/text/SpannableStringBuilder;->removeSpansForChange(IIZI)Z
 HSPLandroid/text/SpannableStringBuilder;->replace(IILjava/lang/CharSequence;)Landroid/text/Editable;
 HSPLandroid/text/SpannableStringBuilder;->replace(IILjava/lang/CharSequence;)Landroid/text/SpannableStringBuilder;
-HSPLandroid/text/SpannableStringBuilder;->replace(IILjava/lang/CharSequence;II)Landroid/text/SpannableStringBuilder;
+HSPLandroid/text/SpannableStringBuilder;->replace(IILjava/lang/CharSequence;II)Landroid/text/SpannableStringBuilder;+]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringBuilder;->resizeFor(I)V
 HSPLandroid/text/SpannableStringBuilder;->resolveGap(I)I
-HSPLandroid/text/SpannableStringBuilder;->restoreInvariants()V
+HSPLandroid/text/SpannableStringBuilder;->restoreInvariants()V+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
 HSPLandroid/text/SpannableStringBuilder;->rightChild(I)I
 HSPLandroid/text/SpannableStringBuilder;->sendAfterTextChanged([Landroid/text/TextWatcher;)V
 HSPLandroid/text/SpannableStringBuilder;->sendBeforeTextChanged([Landroid/text/TextWatcher;III)V
-HSPLandroid/text/SpannableStringBuilder;->sendSpanAdded(Ljava/lang/Object;II)V
+HSPLandroid/text/SpannableStringBuilder;->sendSpanAdded(Ljava/lang/Object;II)V+]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringBuilder;->sendSpanChanged(Ljava/lang/Object;IIII)V
 HSPLandroid/text/SpannableStringBuilder;->sendSpanRemoved(Ljava/lang/Object;II)V
 HSPLandroid/text/SpannableStringBuilder;->sendTextChanged([Landroid/text/TextWatcher;III)V
 HSPLandroid/text/SpannableStringBuilder;->sendToSpanWatchers(III)V
 HSPLandroid/text/SpannableStringBuilder;->setFilters([Landroid/text/InputFilter;)V
 HSPLandroid/text/SpannableStringBuilder;->setSpan(Ljava/lang/Object;III)V
-HSPLandroid/text/SpannableStringBuilder;->setSpan(ZLjava/lang/Object;IIIZ)V
+HSPLandroid/text/SpannableStringBuilder;->setSpan(ZLjava/lang/Object;IIIZ)V+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
 HSPLandroid/text/SpannableStringBuilder;->siftDown(I[Ljava/lang/Object;I[I[I)V
 HSPLandroid/text/SpannableStringBuilder;->sort([Ljava/lang/Object;[I[I)V
 HSPLandroid/text/SpannableStringBuilder;->subSequence(II)Ljava/lang/CharSequence;
-HSPLandroid/text/SpannableStringBuilder;->toString()Ljava/lang/String;
+HSPLandroid/text/SpannableStringBuilder;->toString()Ljava/lang/String;+]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringBuilder;->treeRoot()I
 HSPLandroid/text/SpannableStringBuilder;->updatedIntervalBound(IIIIZZ)I
-HSPLandroid/text/SpannableStringInternal;-><init>(Ljava/lang/CharSequence;IIZ)V
-HSPLandroid/text/SpannableStringInternal;->charAt(I)C
-HSPLandroid/text/SpannableStringInternal;->checkRange(Ljava/lang/String;II)V
-HSPLandroid/text/SpannableStringInternal;->copySpansFromInternal(Landroid/text/SpannableStringInternal;IIZ)V
-HSPLandroid/text/SpannableStringInternal;->copySpansFromSpanned(Landroid/text/Spanned;IIZ)V
+HSPLandroid/text/SpannableStringInternal;-><init>(Ljava/lang/CharSequence;IIZ)V+]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/SpannedString;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;
+HSPLandroid/text/SpannableStringInternal;->charAt(I)C+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/text/SpannableStringInternal;->checkRange(Ljava/lang/String;II)V+]Landroid/text/SpannableStringInternal;Landroid/text/SpannedString;,Landroid/text/SpannableString;
+HSPLandroid/text/SpannableStringInternal;->copySpansFromInternal(Landroid/text/SpannableStringInternal;IIZ)V+]Landroid/text/SpannableStringInternal;Landroid/text/SpannedString;,Landroid/text/SpannableString;
+HSPLandroid/text/SpannableStringInternal;->copySpansFromSpanned(Landroid/text/Spanned;IIZ)V+]Landroid/text/Spanned;Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringInternal;->equals(Ljava/lang/Object;)Z
-HSPLandroid/text/SpannableStringInternal;->getChars(II[CI)V
+HSPLandroid/text/SpannableStringInternal;->getChars(II[CI)V+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/text/SpannableStringInternal;->getSpanEnd(Ljava/lang/Object;)I
 HSPLandroid/text/SpannableStringInternal;->getSpanFlags(Ljava/lang/Object;)I
 HSPLandroid/text/SpannableStringInternal;->getSpanStart(Ljava/lang/Object;)I
-HSPLandroid/text/SpannableStringInternal;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;
-HSPLandroid/text/SpannableStringInternal;->length()I
+HSPLandroid/text/SpannableStringInternal;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/text/SpannableStringInternal;Landroid/text/SpannableString;
+HSPLandroid/text/SpannableStringInternal;->length()I+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/text/SpannableStringInternal;->nextSpanTransition(IILjava/lang/Class;)I
 HSPLandroid/text/SpannableStringInternal;->removeSpan(Ljava/lang/Object;I)V
-HSPLandroid/text/SpannableStringInternal;->sendSpanAdded(Ljava/lang/Object;II)V
+HSPLandroid/text/SpannableStringInternal;->sendSpanAdded(Ljava/lang/Object;II)V+]Landroid/text/SpanWatcher;Landroid/text/DynamicLayout$ChangeWatcher;,Landroid/widget/Editor$SpanController;,Landroid/widget/TextView$ChangeWatcher;]Landroid/text/SpannableStringInternal;Landroid/text/SpannableString;
 HSPLandroid/text/SpannableStringInternal;->sendSpanChanged(Ljava/lang/Object;IIII)V
 HSPLandroid/text/SpannableStringInternal;->setSpan(Ljava/lang/Object;III)V
 HSPLandroid/text/SpannableStringInternal;->setSpan(Ljava/lang/Object;IIIZ)V
 HSPLandroid/text/SpannableStringInternal;->toString()Ljava/lang/String;
 HSPLandroid/text/SpannedString;-><init>(Ljava/lang/CharSequence;)V
-HSPLandroid/text/SpannedString;-><init>(Ljava/lang/CharSequence;Z)V
+HSPLandroid/text/SpannedString;-><init>(Ljava/lang/CharSequence;Z)V+]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannedString;->equals(Ljava/lang/Object;)Z
 HSPLandroid/text/SpannedString;->getSpanEnd(Ljava/lang/Object;)I
 HSPLandroid/text/SpannedString;->getSpanFlags(Ljava/lang/Object;)I
@@ -14902,8 +14965,9 @@
 HSPLandroid/text/StaticLayout$Builder;->setMaxLines(I)Landroid/text/StaticLayout$Builder;
 HSPLandroid/text/StaticLayout$Builder;->setTextDirection(Landroid/text/TextDirectionHeuristic;)Landroid/text/StaticLayout$Builder;
 HSPLandroid/text/StaticLayout$Builder;->setUseLineSpacingFromFallbacks(Z)Landroid/text/StaticLayout$Builder;
+HSPLandroid/text/StaticLayout;-><init>(Landroid/text/StaticLayout$Builder;ZI)V+]Landroid/text/StaticLayout;Landroid/text/StaticLayout;
 HSPLandroid/text/StaticLayout;->calculateEllipsis(IILandroid/text/MeasuredParagraph;IFLandroid/text/TextUtils$TruncateAt;IFLandroid/text/TextPaint;Z)V
-HSPLandroid/text/StaticLayout;->generate(Landroid/text/StaticLayout$Builder;ZZ)V+]Landroid/graphics/text/LineBreaker$Builder;Landroid/graphics/text/LineBreaker$Builder;]Landroid/graphics/text/LineBreaker$ParagraphConstraints;Landroid/graphics/text/LineBreaker$ParagraphConstraints;]Landroid/graphics/text/LineBreaker$Result;Landroid/graphics/text/LineBreaker$Result;]Landroid/graphics/text/LineBreaker;Landroid/graphics/text/LineBreaker;]Landroid/text/AutoGrowArray$IntArray;Landroid/text/AutoGrowArray$IntArray;]Landroid/text/MeasuredParagraph;Landroid/text/MeasuredParagraph;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/text/StaticLayout;->generate(Landroid/text/StaticLayout$Builder;ZZ)V+]Landroid/text/MeasuredParagraph;Landroid/text/MeasuredParagraph;]Landroid/graphics/text/LineBreaker$Builder;Landroid/graphics/text/LineBreaker$Builder;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/graphics/text/LineBreaker;Landroid/graphics/text/LineBreaker;]Ljava/lang/CharSequence;Landroid/text/SpannableString;]Landroid/graphics/text/LineBreaker$ParagraphConstraints;Landroid/graphics/text/LineBreaker$ParagraphConstraints;]Landroid/graphics/text/LineBreaker$Result;Landroid/graphics/text/LineBreaker$Result;]Landroid/text/AutoGrowArray$IntArray;Landroid/text/AutoGrowArray$IntArray;
 HSPLandroid/text/StaticLayout;->getBottomPadding()I
 HSPLandroid/text/StaticLayout;->getEllipsisCount(I)I
 HSPLandroid/text/StaticLayout;->getEllipsisStart(I)I
@@ -14913,7 +14977,7 @@
 HSPLandroid/text/StaticLayout;->getLineContainsTab(I)Z
 HSPLandroid/text/StaticLayout;->getLineCount()I
 HSPLandroid/text/StaticLayout;->getLineDescent(I)I
-HSPLandroid/text/StaticLayout;->getLineDirections(I)Landroid/text/Layout$Directions;
+HSPLandroid/text/StaticLayout;->getLineDirections(I)Landroid/text/Layout$Directions;+]Landroid/text/StaticLayout;Landroid/text/StaticLayout;
 HSPLandroid/text/StaticLayout;->getLineExtra(I)I
 HSPLandroid/text/StaticLayout;->getLineForVertical(I)I
 HSPLandroid/text/StaticLayout;->getLineStart(I)I
@@ -14922,38 +14986,43 @@
 HSPLandroid/text/StaticLayout;->getStartHyphenEdit(I)I
 HSPLandroid/text/StaticLayout;->getTopPadding()I
 HSPLandroid/text/StaticLayout;->getTotalInsets(I)F
-HSPLandroid/text/StaticLayout;->out(Ljava/lang/CharSequence;IIIIIIIFF[Landroid/text/style/LineHeightSpan;[ILandroid/graphics/Paint$FontMetricsInt;ZIZLandroid/text/MeasuredParagraph;IZZZ[CILandroid/text/TextUtils$TruncateAt;FFLandroid/text/TextPaint;Z)I
+HSPLandroid/text/StaticLayout;->out(Ljava/lang/CharSequence;IIIIIIIFF[Landroid/text/style/LineHeightSpan;[ILandroid/graphics/Paint$FontMetricsInt;ZIZLandroid/text/MeasuredParagraph;IZZZ[CILandroid/text/TextUtils$TruncateAt;FFLandroid/text/TextPaint;Z)I+]Landroid/text/MeasuredParagraph;Landroid/text/MeasuredParagraph;]Ljava/lang/CharSequence;Landroid/text/SpannableString;
 HSPLandroid/text/StaticLayout;->packHyphenEdit(II)I
 HSPLandroid/text/StaticLayout;->unpackEndHyphenEdit(I)I
 HSPLandroid/text/StaticLayout;->unpackStartHyphenEdit(I)I
 HSPLandroid/text/TextDirectionHeuristics$FirstStrong;->checkRtl(Ljava/lang/CharSequence;II)I
-HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;->doCheck(Ljava/lang/CharSequence;II)Z+]Landroid/text/TextDirectionHeuristics$TextDirectionAlgorithm;Landroid/text/TextDirectionHeuristics$FirstStrong;]Landroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;Landroid/text/TextDirectionHeuristics$TextDirectionHeuristicInternal;
+HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;->doCheck(Ljava/lang/CharSequence;II)Z
 HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;->isRtl(Ljava/lang/CharSequence;II)Z
 HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;->isRtl([CII)Z
 HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicInternal;->defaultIsRtl()Z
 HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicLocale;->defaultIsRtl()Z
 HSPLandroid/text/TextDirectionHeuristics;->isRtlCodePoint(I)I
 HSPLandroid/text/TextFlags;->getKeyForFlag(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/text/TextFlags;->isFeatureEnabled(Ljava/lang/String;)Z
 HSPLandroid/text/TextLine$DecorationInfo;-><init>()V
 HSPLandroid/text/TextLine$DecorationInfo;->copyInfo()Landroid/text/TextLine$DecorationInfo;
 HSPLandroid/text/TextLine$DecorationInfo;->hasDecoration()Z
 HSPLandroid/text/TextLine;-><init>()V
 HSPLandroid/text/TextLine;->adjustEndHyphenEdit(II)I
 HSPLandroid/text/TextLine;->adjustStartHyphenEdit(II)I
-HSPLandroid/text/TextLine;->draw(Landroid/graphics/Canvas;FIII)V
+HSPLandroid/text/TextLine;->draw(Landroid/graphics/Canvas;FIII)V+]Landroid/text/Layout$Directions;Landroid/text/Layout$Directions;
 HSPLandroid/text/TextLine;->drawStroke(Landroid/text/TextPaint;Landroid/graphics/Canvas;IFFFFF)V
-HSPLandroid/text/TextLine;->drawTextRun(Landroid/graphics/Canvas;Landroid/text/TextPaint;IIIIZFI)V
+HSPLandroid/text/TextLine;->drawTextRun(Landroid/graphics/Canvas;Landroid/text/TextPaint;IIIIZFI)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/text/TextLine;->equalAttributes(Landroid/text/TextPaint;Landroid/text/TextPaint;)Z
-HSPLandroid/text/TextLine;->expandMetricsFromPaint(Landroid/graphics/Paint$FontMetricsInt;Landroid/text/TextPaint;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
+HSPLandroid/text/TextLine;->expandMetricsFromPaint(Landroid/graphics/Paint$FontMetricsInt;Landroid/text/TextPaint;)V
 HSPLandroid/text/TextLine;->expandMetricsFromPaint(Landroid/text/TextPaint;IIIIZLandroid/graphics/Paint$FontMetricsInt;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
 HSPLandroid/text/TextLine;->extractDecorationInfo(Landroid/text/TextPaint;Landroid/text/TextLine$DecorationInfo;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
-HSPLandroid/text/TextLine;->getOffsetBeforeAfter(IIIZIZ)I
+HSPLandroid/text/TextLine;->getOffsetBeforeAfter(IIIZIZ)I+]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/text/Spanned;Landroid/text/SpannableString;
 HSPLandroid/text/TextLine;->getOffsetToLeftRightOf(IZ)I
+HSPLandroid/text/TextLine;->getRunAdvance(Landroid/text/TextPaint;IIIIZI[FILandroid/graphics/RectF;Landroid/text/TextLine$LineInfo;)F+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/text/PrecomputedText;Landroid/text/PrecomputedText;]Landroid/text/TextPaint;Landroid/text/TextPaint;
 HSPLandroid/text/TextLine;->handleReplacement(Landroid/text/style/ReplacementSpan;Landroid/text/TextPaint;IIZLandroid/graphics/Canvas;FIIILandroid/graphics/Paint$FontMetricsInt;Z)F
+HSPLandroid/text/TextLine;->handleRun(IIIZLandroid/graphics/Canvas;Landroid/text/TextShaper$GlyphsConsumer;FIIILandroid/graphics/Paint$FontMetricsInt;Landroid/graphics/RectF;Z[FILandroid/text/TextLine$LineInfo;I)F+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/text/style/MetricAffectingSpan;megamorphic_types]Landroid/text/style/CharacterStyle;megamorphic_types]Landroid/text/TextPaint;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/text/TextLine$DecorationInfo;Landroid/text/TextLine$DecorationInfo;]Landroid/text/SpanSet;Landroid/text/SpanSet;
+HSPLandroid/text/TextLine;->handleText(Landroid/text/TextPaint;IIIIZLandroid/graphics/Canvas;Landroid/text/TextShaper$GlyphsConsumer;FIIILandroid/graphics/Paint$FontMetricsInt;Landroid/graphics/RectF;ZILjava/util/ArrayList;[FILandroid/text/TextLine$LineInfo;I)F+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;,Landroid/graphics/Canvas;,Landroid/view/Surface$CompatibleCanvas;
 HSPLandroid/text/TextLine;->isLineEndSpace(C)Z
+HSPLandroid/text/TextLine;->measure(IZLandroid/graphics/Paint$FontMetricsInt;Landroid/graphics/RectF;Landroid/text/TextLine$LineInfo;)F+]Landroid/text/Layout$Directions;Landroid/text/Layout$Directions;]Landroid/text/TextLine;Landroid/text/TextLine;
 HSPLandroid/text/TextLine;->obtain()Landroid/text/TextLine;
 HSPLandroid/text/TextLine;->recycle(Landroid/text/TextLine;)Landroid/text/TextLine;+]Landroid/text/SpanSet;Landroid/text/SpanSet;
-HSPLandroid/text/TextLine;->set(Landroid/text/TextPaint;Ljava/lang/CharSequence;IIILandroid/text/Layout$Directions;ZLandroid/text/Layout$TabStops;IIZ)V
+HSPLandroid/text/TextLine;->set(Landroid/text/TextPaint;Ljava/lang/CharSequence;IIILandroid/text/Layout$Directions;ZLandroid/text/Layout$TabStops;IIZ)V+]Landroid/text/SpanSet;Landroid/text/SpanSet;
 HSPLandroid/text/TextLine;->updateMetrics(Landroid/graphics/Paint$FontMetricsInt;IIIII)V
 HSPLandroid/text/TextPaint;-><init>()V
 HSPLandroid/text/TextPaint;-><init>(I)V
@@ -14961,8 +15030,8 @@
 HSPLandroid/text/TextPaint;->getUnderlineThickness()F
 HSPLandroid/text/TextPaint;->set(Landroid/text/TextPaint;)V
 HSPLandroid/text/TextPaint;->setUnderlineText(IF)V
-HSPLandroid/text/TextUtils$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/CharSequence;
-HSPLandroid/text/TextUtils$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/text/TextUtils$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/CharSequence;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/text/TextUtils$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/text/TextUtils$1;Landroid/text/TextUtils$1;
 HSPLandroid/text/TextUtils$SimpleStringSplitter;-><init>(C)V
 HSPLandroid/text/TextUtils$SimpleStringSplitter;->hasNext()Z
 HSPLandroid/text/TextUtils$SimpleStringSplitter;->iterator()Ljava/util/Iterator;
@@ -14970,7 +15039,7 @@
 HSPLandroid/text/TextUtils$SimpleStringSplitter;->next()Ljava/lang/String;
 HSPLandroid/text/TextUtils$SimpleStringSplitter;->setString(Ljava/lang/String;)V
 HSPLandroid/text/TextUtils$StringWithRemovedChars;->toString()Ljava/lang/String;
-HSPLandroid/text/TextUtils;->concat([Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
+HSPLandroid/text/TextUtils;->concat([Ljava/lang/CharSequence;)Ljava/lang/CharSequence;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/TextUtils;->copySpansFrom(Landroid/text/Spanned;IILjava/lang/Class;Landroid/text/Spannable;I)V
 HSPLandroid/text/TextUtils;->couldAffectRtl(C)Z
 HSPLandroid/text/TextUtils;->doesNotNeedBidi([CII)Z
@@ -14978,23 +15047,23 @@
 HSPLandroid/text/TextUtils;->ellipsize(Ljava/lang/CharSequence;Landroid/text/TextPaint;FLandroid/text/TextUtils$TruncateAt;ZLandroid/text/TextUtils$EllipsizeCallback;)Ljava/lang/CharSequence;
 HSPLandroid/text/TextUtils;->ellipsize(Ljava/lang/CharSequence;Landroid/text/TextPaint;FLandroid/text/TextUtils$TruncateAt;ZLandroid/text/TextUtils$EllipsizeCallback;Landroid/text/TextDirectionHeuristic;Ljava/lang/String;)Ljava/lang/CharSequence;
 HSPLandroid/text/TextUtils;->emptyIfNull(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/text/TextUtils;->equals(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Z
+HSPLandroid/text/TextUtils;->equals(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Z+]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/CharSequence;Ljava/lang/String;
 HSPLandroid/text/TextUtils;->expandTemplate(Ljava/lang/CharSequence;[Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
-HSPLandroid/text/TextUtils;->formatSimple(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;+]Ljava/lang/Boolean;Ljava/lang/Boolean;]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/text/TextUtils;->formatSimple(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/Boolean;Ljava/lang/Boolean;
 HSPLandroid/text/TextUtils;->getCapsMode(Ljava/lang/CharSequence;II)I
-HSPLandroid/text/TextUtils;->getChars(Ljava/lang/CharSequence;II[CI)V+]Landroid/text/GetChars;Landroid/text/Layout$Ellipsizer;,Landroid/text/Layout$SpannedEllipsizer;,Landroid/text/SpannableString;]Ljava/lang/Object;megamorphic_types]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/text/TextUtils;->getChars(Ljava/lang/CharSequence;II[CI)V+]Ljava/lang/Object;Landroid/text/SpannableString;]Landroid/text/GetChars;Landroid/text/SpannableString;
 HSPLandroid/text/TextUtils;->getEllipsisString(Landroid/text/TextUtils$TruncateAt;)Ljava/lang/String;
 HSPLandroid/text/TextUtils;->getLayoutDirectionFromLocale(Ljava/util/Locale;)I
 HSPLandroid/text/TextUtils;->getTrimmedLength(Ljava/lang/CharSequence;)I
 HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;C)I
 HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;CI)I
-HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;CII)I
+HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;CII)I+]Ljava/lang/Object;Landroid/text/SpannableString;
 HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)I
 HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;Ljava/lang/CharSequence;II)I
 HSPLandroid/text/TextUtils;->isDigitsOnly(Ljava/lang/CharSequence;)Z
-HSPLandroid/text/TextUtils;->isEmpty(Ljava/lang/CharSequence;)Z+]Ljava/lang/CharSequence;Landroid/text/SpannableStringBuilder;,Ljava/lang/String;
+HSPLandroid/text/TextUtils;->isEmpty(Ljava/lang/CharSequence;)Z+]Ljava/lang/CharSequence;Ljava/lang/String;
 HSPLandroid/text/TextUtils;->isGraphic(Ljava/lang/CharSequence;)Z
-HSPLandroid/text/TextUtils;->join(Ljava/lang/CharSequence;Ljava/lang/Iterable;)Ljava/lang/String;
+HSPLandroid/text/TextUtils;->join(Ljava/lang/CharSequence;Ljava/lang/Iterable;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/Iterable;missing_types]Ljava/util/Iterator;missing_types
 HSPLandroid/text/TextUtils;->join(Ljava/lang/CharSequence;[Ljava/lang/Object;)Ljava/lang/String;
 HSPLandroid/text/TextUtils;->lastIndexOf(Ljava/lang/CharSequence;CI)I
 HSPLandroid/text/TextUtils;->lastIndexOf(Ljava/lang/CharSequence;CII)I
@@ -15007,14 +15076,14 @@
 HSPLandroid/text/TextUtils;->safeIntern(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/text/TextUtils;->split(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;
 HSPLandroid/text/TextUtils;->stringOrSpannedString(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
-HSPLandroid/text/TextUtils;->substring(Ljava/lang/CharSequence;II)Ljava/lang/String;
+HSPLandroid/text/TextUtils;->substring(Ljava/lang/CharSequence;II)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/text/TextUtils;->toUpperCase(Ljava/util/Locale;Ljava/lang/CharSequence;Z)Ljava/lang/CharSequence;
 HSPLandroid/text/TextUtils;->trimNoCopySpans(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
 HSPLandroid/text/TextUtils;->trimToParcelableSize(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
 HSPLandroid/text/TextUtils;->trimToSize(Ljava/lang/CharSequence;I)Ljava/lang/CharSequence;
 HSPLandroid/text/TextUtils;->unpackRangeEndFromLong(J)I
 HSPLandroid/text/TextUtils;->unpackRangeStartFromLong(J)I
-HSPLandroid/text/TextUtils;->writeToParcel(Ljava/lang/CharSequence;Landroid/os/Parcel;I)V
+HSPLandroid/text/TextUtils;->writeToParcel(Ljava/lang/CharSequence;Landroid/os/Parcel;I)V+]Ljava/lang/CharSequence;Ljava/lang/String;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/text/format/DateFormat;->format(Ljava/lang/CharSequence;J)Ljava/lang/CharSequence;
 HSPLandroid/text/format/DateFormat;->format(Ljava/lang/CharSequence;Ljava/util/Calendar;)Ljava/lang/CharSequence;
 HSPLandroid/text/format/DateFormat;->format(Ljava/lang/CharSequence;Ljava/util/Date;)Ljava/lang/CharSequence;
@@ -15121,7 +15190,7 @@
 HSPLandroid/text/method/TextKeyListener;->onSpanChanged(Landroid/text/Spannable;Ljava/lang/Object;IIII)V
 HSPLandroid/text/method/TextKeyListener;->onSpanRemoved(Landroid/text/Spannable;Ljava/lang/Object;II)V
 HSPLandroid/text/method/TextKeyListener;->updatePrefs(Landroid/content/ContentResolver;)V
-HSPLandroid/text/method/Touch;->onTouchEvent(Landroid/widget/TextView;Landroid/text/Spannable;Landroid/view/MotionEvent;)Z
+HSPLandroid/text/method/Touch;->onTouchEvent(Landroid/widget/TextView;Landroid/text/Spannable;Landroid/view/MotionEvent;)Z+]Landroid/text/Layout;Landroid/text/DynamicLayout;]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/text/Spannable;Landroid/text/SpannableString;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
 HSPLandroid/text/method/WordIterator;-><init>(Ljava/util/Locale;)V
 HSPLandroid/text/method/WordIterator;->checkOffsetIsValid(I)V
 HSPLandroid/text/method/WordIterator;->following(I)I
@@ -15140,7 +15209,7 @@
 HSPLandroid/text/style/DynamicDrawableSpan;-><init>(I)V
 HSPLandroid/text/style/ForegroundColorSpan;-><init>(I)V
 HSPLandroid/text/style/ForegroundColorSpan;->getSpanTypeIdInternal()I
-HSPLandroid/text/style/ForegroundColorSpan;->updateDrawState(Landroid/text/TextPaint;)V
+HSPLandroid/text/style/ForegroundColorSpan;->updateDrawState(Landroid/text/TextPaint;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
 HSPLandroid/text/style/ForegroundColorSpan;->writeToParcelInternal(Landroid/os/Parcel;I)V
 HSPLandroid/text/style/ImageSpan;-><init>(Landroid/graphics/drawable/Drawable;I)V
 HSPLandroid/text/style/ImageSpan;->getDrawable()Landroid/graphics/drawable/Drawable;
@@ -15206,7 +15275,7 @@
 HSPLandroid/transition/Transition$2;->onAnimationStart(Landroid/animation/Animator;)V
 HSPLandroid/transition/Transition$3;->onAnimationEnd(Landroid/animation/Animator;)V
 HSPLandroid/transition/Transition;-><init>()V
-HSPLandroid/transition/Transition;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;megamorphic_types
+HSPLandroid/transition/Transition;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Ljava/lang/Object;megamorphic_types]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Ljava/lang/Class;Ljava/lang/Class;
 HSPLandroid/transition/Transition;->addListener(Landroid/transition/Transition$TransitionListener;)Landroid/transition/Transition;
 HSPLandroid/transition/Transition;->addTarget(Landroid/view/View;)Landroid/transition/Transition;
 HSPLandroid/transition/Transition;->addUnmatched(Landroid/util/ArrayMap;Landroid/util/ArrayMap;)V
@@ -15237,7 +15306,7 @@
 HSPLandroid/transition/Transition;->start()V
 HSPLandroid/transition/TransitionInflater;-><init>(Landroid/content/Context;)V
 HSPLandroid/transition/TransitionInflater;->createCustom(Landroid/util/AttributeSet;Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Object;
-HSPLandroid/transition/TransitionInflater;->createTransitionFromXml(Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/transition/Transition;)Landroid/transition/Transition;+]Landroid/transition/TransitionSet;Landroid/transition/TransitionSet;]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/transition/TransitionInflater;->createTransitionFromXml(Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/transition/Transition;)Landroid/transition/Transition;
 HSPLandroid/transition/TransitionInflater;->from(Landroid/content/Context;)Landroid/transition/TransitionInflater;
 HSPLandroid/transition/TransitionInflater;->inflateTransition(I)Landroid/transition/Transition;
 HSPLandroid/transition/TransitionListenerAdapter;-><init>()V
@@ -15318,7 +15387,7 @@
 HSPLandroid/util/ArrayMap;->indexOfValue(Ljava/lang/Object;)I
 HSPLandroid/util/ArrayMap;->isEmpty()Z
 HSPLandroid/util/ArrayMap;->keyAt(I)Ljava/lang/Object;
-HSPLandroid/util/ArrayMap;->keySet()Ljava/util/Set;
+HSPLandroid/util/ArrayMap;->keySet()Ljava/util/Set;+]Landroid/util/MapCollections;Landroid/util/ArrayMap$1;
 HSPLandroid/util/ArrayMap;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Object;megamorphic_types
 HSPLandroid/util/ArrayMap;->putAll(Landroid/util/ArrayMap;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
 HSPLandroid/util/ArrayMap;->putAll(Ljava/util/Map;)V
@@ -15341,11 +15410,11 @@
 HSPLandroid/util/ArraySet;-><init>(Landroid/util/ArraySet;)V
 HSPLandroid/util/ArraySet;-><init>(Ljava/util/Collection;)V
 HSPLandroid/util/ArraySet;-><init>([Ljava/lang/Object;)V
-HSPLandroid/util/ArraySet;->add(Ljava/lang/Object;)Z
+HSPLandroid/util/ArraySet;->add(Ljava/lang/Object;)Z+]Ljava/lang/Object;Ljava/lang/String;,Landroid/accounts/Account;,Landroid/window/SurfaceSyncGroup$2;,Landroid/net/UidRange;
 HSPLandroid/util/ArraySet;->addAll(Landroid/util/ArraySet;)V
 HSPLandroid/util/ArraySet;->addAll(Ljava/util/Collection;)Z
 HSPLandroid/util/ArraySet;->allocArrays(I)V
-HSPLandroid/util/ArraySet;->append(Ljava/lang/Object;)V+]Landroid/util/ArraySet;Landroid/util/ArraySet;]Ljava/lang/Object;Landroid/app/PendingIntent;,Lcom/android/org/conscrypt/OpenSSLRSAPublicKey;
+HSPLandroid/util/ArraySet;->append(Ljava/lang/Object;)V+]Ljava/lang/Object;Lcom/android/org/conscrypt/OpenSSLRSAPublicKey;,Lcom/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey;
 HSPLandroid/util/ArraySet;->binarySearch([II)I
 HSPLandroid/util/ArraySet;->clear()V
 HSPLandroid/util/ArraySet;->contains(Ljava/lang/Object;)Z
@@ -15383,11 +15452,11 @@
 HSPLandroid/util/Base64$Decoder;->process([BIIZ)Z
 HSPLandroid/util/Base64$Encoder;-><init>(I[B)V
 HSPLandroid/util/Base64$Encoder;->process([BIIZ)Z
-HSPLandroid/util/Base64;->decode(Ljava/lang/String;I)[B+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/util/Base64;->decode(Ljava/lang/String;I)[B
 HSPLandroid/util/Base64;->decode([BI)[B
 HSPLandroid/util/Base64;->decode([BIII)[B+]Landroid/util/Base64$Decoder;Landroid/util/Base64$Decoder;
 HSPLandroid/util/Base64;->encode([BI)[B
-HSPLandroid/util/Base64;->encode([BIII)[B+]Landroid/util/Base64$Encoder;Landroid/util/Base64$Encoder;
+HSPLandroid/util/Base64;->encode([BIII)[B
 HSPLandroid/util/Base64;->encodeToString([BI)Ljava/lang/String;
 HSPLandroid/util/Base64;->encodeToString([BIII)Ljava/lang/String;
 HSPLandroid/util/CloseGuard;-><init>()V
@@ -15403,7 +15472,7 @@
 HSPLandroid/util/DisplayMetrics;->setToDefaults()V
 HSPLandroid/util/DisplayUtils;->getDisplayUniqueIdConfigIndex(Landroid/content/res/Resources;Ljava/lang/String;)I
 HSPLandroid/util/EventLog$Event;-><init>([B)V
-HSPLandroid/util/EventLog$Event;->decodeObject()Ljava/lang/Object;
+HSPLandroid/util/EventLog$Event;->decodeObject()Ljava/lang/Object;+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
 HSPLandroid/util/EventLog$Event;->getData()Ljava/lang/Object;
 HSPLandroid/util/EventLog$Event;->getHeaderSize()I
 HSPLandroid/util/EventLog$Event;->getUid()I
@@ -15431,7 +15500,7 @@
 HSPLandroid/util/IndentingPrintWriter;->write([CII)V
 HSPLandroid/util/IntArray;-><init>()V
 HSPLandroid/util/IntArray;-><init>(I)V
-HSPLandroid/util/IntArray;->add(I)V+]Landroid/util/IntArray;Landroid/util/IntArray;
+HSPLandroid/util/IntArray;->add(I)V
 HSPLandroid/util/IntArray;->add(II)V
 HSPLandroid/util/IntArray;->addAll(Landroid/util/IntArray;)V
 HSPLandroid/util/IntArray;->binarySearch(I)I
@@ -15488,9 +15557,9 @@
 HSPLandroid/util/JsonWriter;->name(Ljava/lang/String;)Landroid/util/JsonWriter;
 HSPLandroid/util/JsonWriter;->newline()V
 HSPLandroid/util/JsonWriter;->open(Landroid/util/JsonScope;Ljava/lang/String;)Landroid/util/JsonWriter;
-HSPLandroid/util/JsonWriter;->peek()Landroid/util/JsonScope;
-HSPLandroid/util/JsonWriter;->replaceTop(Landroid/util/JsonScope;)V
-HSPLandroid/util/JsonWriter;->string(Ljava/lang/String;)V
+HSPLandroid/util/JsonWriter;->peek()Landroid/util/JsonScope;+]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/util/JsonWriter;->replaceTop(Landroid/util/JsonScope;)V+]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/util/JsonWriter;->string(Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;]Ljava/io/Writer;Ljava/io/BufferedWriter;
 HSPLandroid/util/JsonWriter;->value(J)Landroid/util/JsonWriter;
 HSPLandroid/util/JsonWriter;->value(Ljava/lang/String;)Landroid/util/JsonWriter;
 HSPLandroid/util/JsonWriter;->value(Z)Landroid/util/JsonWriter;
@@ -15563,21 +15632,21 @@
 HSPLandroid/util/LruCache;->create(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/util/LruCache;->entryRemoved(ZLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
 HSPLandroid/util/LruCache;->evictAll()V
-HSPLandroid/util/LruCache;->get(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/util/LruCache;->get(Ljava/lang/Object;)Ljava/lang/Object;+]Ljava/util/LinkedHashMap;Ljava/util/LinkedHashMap;]Landroid/util/LruCache;missing_types
 HSPLandroid/util/LruCache;->hitCount()I
 HSPLandroid/util/LruCache;->maxSize()I
 HSPLandroid/util/LruCache;->missCount()I
-HSPLandroid/util/LruCache;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/util/LruCache;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+]Ljava/util/LinkedHashMap;Ljava/util/LinkedHashMap;]Landroid/util/LruCache;Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;,Landroid/util/LruCache;
 HSPLandroid/util/LruCache;->remove(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/util/LruCache;->resize(I)V
 HSPLandroid/util/LruCache;->safeSizeOf(Ljava/lang/Object;Ljava/lang/Object;)I
 HSPLandroid/util/LruCache;->size()I
 HSPLandroid/util/LruCache;->sizeOf(Ljava/lang/Object;Ljava/lang/Object;)I
 HSPLandroid/util/LruCache;->snapshot()Ljava/util/Map;
-HSPLandroid/util/LruCache;->trimToSize(I)V
-HSPLandroid/util/MapCollections$ArrayIterator;-><init>(Landroid/util/MapCollections;I)V
+HSPLandroid/util/LruCache;->trimToSize(I)V+]Ljava/util/LinkedHashMap;Ljava/util/LinkedHashMap;]Landroid/util/LruCache;Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;
+HSPLandroid/util/MapCollections$ArrayIterator;-><init>(Landroid/util/MapCollections;I)V+]Landroid/util/MapCollections;Landroid/util/ArraySet$1;,Landroid/util/ArrayMap$1;
 HSPLandroid/util/MapCollections$ArrayIterator;->hasNext()Z
-HSPLandroid/util/MapCollections$ArrayIterator;->next()Ljava/lang/Object;
+HSPLandroid/util/MapCollections$ArrayIterator;->next()Ljava/lang/Object;+]Landroid/util/MapCollections$ArrayIterator;Landroid/util/MapCollections$ArrayIterator;]Landroid/util/MapCollections;Landroid/util/ArraySet$1;,Landroid/util/ArrayMap$1;
 HSPLandroid/util/MapCollections$ArrayIterator;->remove()V
 HSPLandroid/util/MapCollections$EntrySet;-><init>(Landroid/util/MapCollections;)V
 HSPLandroid/util/MapCollections$EntrySet;->iterator()Ljava/util/Iterator;
@@ -15699,16 +15768,16 @@
 HSPLandroid/util/SparseArray;->clear()V
 HSPLandroid/util/SparseArray;->clone()Landroid/util/SparseArray;
 HSPLandroid/util/SparseArray;->contains(I)Z
-HSPLandroid/util/SparseArray;->contentEquals(Landroid/util/SparseArray;)Z+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/util/SparseArray;->contentEquals(Landroid/util/SparseArray;)Z
 HSPLandroid/util/SparseArray;->delete(I)V
 HSPLandroid/util/SparseArray;->gc()V
-HSPLandroid/util/SparseArray;->get(I)Ljava/lang/Object;+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/util/SparseArray;->get(I)Ljava/lang/Object;+]Landroid/util/SparseArray;missing_types
 HSPLandroid/util/SparseArray;->get(ILjava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/util/SparseArray;->indexOfKey(I)I
 HSPLandroid/util/SparseArray;->indexOfValue(Ljava/lang/Object;)I
 HSPLandroid/util/SparseArray;->keyAt(I)I
 HSPLandroid/util/SparseArray;->put(ILjava/lang/Object;)V
-HSPLandroid/util/SparseArray;->remove(I)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/util/SparseArray;->remove(I)V
 HSPLandroid/util/SparseArray;->removeAt(I)V
 HSPLandroid/util/SparseArray;->removeReturnOld(I)Ljava/lang/Object;
 HSPLandroid/util/SparseArray;->setValueAt(ILjava/lang/Object;)V
@@ -15874,7 +15943,7 @@
 HSPLandroid/view/AbsSavedState$2;->createFromParcel(Landroid/os/Parcel;Ljava/lang/ClassLoader;)Ljava/lang/Object;
 HSPLandroid/view/AbsSavedState;-><init>(Landroid/os/Parcelable;)V
 HSPLandroid/view/AbsSavedState;->getSuperState()Landroid/os/Parcelable;
-HSPLandroid/view/AbsSavedState;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/view/AbsSavedState;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/view/Choreographer$1;->initialValue()Landroid/view/Choreographer;
 HSPLandroid/view/Choreographer$1;->initialValue()Ljava/lang/Object;
 HSPLandroid/view/Choreographer$2;->initialValue()Landroid/view/Choreographer;
@@ -15886,8 +15955,8 @@
 HSPLandroid/view/Choreographer$CallbackQueue;->removeCallbacksLocked(Ljava/lang/Object;Ljava/lang/Object;)V
 HSPLandroid/view/Choreographer$CallbackRecord;-><init>()V
 HSPLandroid/view/Choreographer$CallbackRecord;-><init>(Landroid/view/Choreographer$CallbackRecord-IA;)V
-HSPLandroid/view/Choreographer$CallbackRecord;->run(J)V+]Landroid/view/Choreographer$FrameCallback;missing_types]Ljava/lang/Runnable;Landroid/view/ViewPropertyAnimator$1;,Landroid/view/ViewRootImpl$ConsumeBatchedInputRunnable;,Landroid/view/ViewRootImpl$TraversalRunnable;,Lcom/android/internal/util/function/pooled/PooledLambdaImpl;
-HSPLandroid/view/Choreographer$CallbackRecord;->run(Landroid/view/Choreographer$FrameData;)V+]Landroid/view/Choreographer$CallbackRecord;Landroid/view/Choreographer$CallbackRecord;]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;
+HSPLandroid/view/Choreographer$CallbackRecord;->run(J)V+]Landroid/view/Choreographer$FrameCallback;missing_types]Ljava/lang/Runnable;missing_types
+HSPLandroid/view/Choreographer$CallbackRecord;->run(Landroid/view/Choreographer$FrameData;)V+]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;]Landroid/view/Choreographer$CallbackRecord;Landroid/view/Choreographer$CallbackRecord;
 HSPLandroid/view/Choreographer$FrameData;->-$$Nest$fgetmFrameTimeNanos(Landroid/view/Choreographer$FrameData;)J
 HSPLandroid/view/Choreographer$FrameData;-><init>()V
 HSPLandroid/view/Choreographer$FrameData;->allocateFrameTimelines(I)V
@@ -15900,7 +15969,7 @@
 HSPLandroid/view/Choreographer$FrameData;->update(JLandroid/view/DisplayEventReceiver$VsyncEventData;)Landroid/view/Choreographer$FrameTimeline;+]Landroid/view/Choreographer$FrameTimeline;Landroid/view/Choreographer$FrameTimeline;
 HSPLandroid/view/Choreographer$FrameData;->update(JLandroid/view/DisplayEventReceiver;J)Landroid/view/Choreographer$FrameTimeline;
 HSPLandroid/view/Choreographer$FrameDisplayEventReceiver;-><init>(Landroid/view/Choreographer;Landroid/os/Looper;IJ)V
-HSPLandroid/view/Choreographer$FrameDisplayEventReceiver;->onVsync(JJILandroid/view/DisplayEventReceiver$VsyncEventData;)V+]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;]Landroid/view/DisplayEventReceiver$VsyncEventData;Landroid/view/DisplayEventReceiver$VsyncEventData;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/Choreographer$FrameDisplayEventReceiver;->onVsync(JJILandroid/view/DisplayEventReceiver$VsyncEventData;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;]Landroid/view/DisplayEventReceiver$VsyncEventData;Landroid/view/DisplayEventReceiver$VsyncEventData;
 HSPLandroid/view/Choreographer$FrameDisplayEventReceiver;->run()V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
 HSPLandroid/view/Choreographer$FrameHandler;-><init>(Landroid/view/Choreographer;Landroid/os/Looper;)V
 HSPLandroid/view/Choreographer$FrameHandler;->handleMessage(Landroid/os/Message;)V
@@ -15919,13 +15988,13 @@
 HSPLandroid/view/Choreographer;-><init>(Landroid/os/Looper;IJ)V
 HSPLandroid/view/Choreographer;-><init>(Landroid/os/Looper;ILandroid/view/Choreographer-IA;)V
 HSPLandroid/view/Choreographer;->doCallbacks(IJ)V+]Landroid/view/Choreographer$CallbackQueue;Landroid/view/Choreographer$CallbackQueue;]Landroid/view/Choreographer$CallbackRecord;Landroid/view/Choreographer$CallbackRecord;]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;
-HSPLandroid/view/Choreographer;->doFrame(JILandroid/view/DisplayEventReceiver$VsyncEventData;)V+]Landroid/graphics/FrameInfo;Landroid/graphics/FrameInfo;]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/DisplayEventReceiver$VsyncEventData;Landroid/view/DisplayEventReceiver$VsyncEventData;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/Choreographer;->doFrame(JILandroid/view/DisplayEventReceiver$VsyncEventData;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;]Landroid/graphics/FrameInfo;Landroid/graphics/FrameInfo;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/DisplayEventReceiver$VsyncEventData;Landroid/view/DisplayEventReceiver$VsyncEventData;
 HSPLandroid/view/Choreographer;->doScheduleCallback(I)V
 HSPLandroid/view/Choreographer;->doScheduleVsync()V
 HSPLandroid/view/Choreographer;->getFrameIntervalNanos()J
-HSPLandroid/view/Choreographer;->getFrameTime()J
+HSPLandroid/view/Choreographer;->getFrameTime()J+]Landroid/view/Choreographer;Landroid/view/Choreographer;
 HSPLandroid/view/Choreographer;->getFrameTimeNanos()J
-HSPLandroid/view/Choreographer;->getInstance()Landroid/view/Choreographer;+]Ljava/lang/ThreadLocal;Landroid/view/Choreographer$1;
+HSPLandroid/view/Choreographer;->getInstance()Landroid/view/Choreographer;
 HSPLandroid/view/Choreographer;->getMainThreadInstance()Landroid/view/Choreographer;
 HSPLandroid/view/Choreographer;->getRefreshRate()F
 HSPLandroid/view/Choreographer;->getSfInstance()Landroid/view/Choreographer;
@@ -15934,14 +16003,14 @@
 HSPLandroid/view/Choreographer;->obtainCallbackLocked(JLjava/lang/Object;Ljava/lang/Object;)Landroid/view/Choreographer$CallbackRecord;
 HSPLandroid/view/Choreographer;->postCallback(ILjava/lang/Runnable;Ljava/lang/Object;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
 HSPLandroid/view/Choreographer;->postCallbackDelayed(ILjava/lang/Runnable;Ljava/lang/Object;J)V
-HSPLandroid/view/Choreographer;->postCallbackDelayedInternal(ILjava/lang/Object;Ljava/lang/Object;J)V+]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$CallbackQueue;Landroid/view/Choreographer$CallbackQueue;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;
+HSPLandroid/view/Choreographer;->postCallbackDelayedInternal(ILjava/lang/Object;Ljava/lang/Object;J)V+]Landroid/view/Choreographer$CallbackQueue;Landroid/view/Choreographer$CallbackQueue;]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;
 HSPLandroid/view/Choreographer;->postFrameCallback(Landroid/view/Choreographer$FrameCallback;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
 HSPLandroid/view/Choreographer;->postFrameCallbackDelayed(Landroid/view/Choreographer$FrameCallback;J)V
 HSPLandroid/view/Choreographer;->recycleCallbackLocked(Landroid/view/Choreographer$CallbackRecord;)V
 HSPLandroid/view/Choreographer;->removeCallbacks(ILjava/lang/Runnable;Ljava/lang/Object;)V
-HSPLandroid/view/Choreographer;->removeCallbacksInternal(ILjava/lang/Object;Ljava/lang/Object;)V+]Landroid/view/Choreographer$CallbackQueue;Landroid/view/Choreographer$CallbackQueue;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;
+HSPLandroid/view/Choreographer;->removeCallbacksInternal(ILjava/lang/Object;Ljava/lang/Object;)V
 HSPLandroid/view/Choreographer;->removeFrameCallback(Landroid/view/Choreographer$FrameCallback;)V
-HSPLandroid/view/Choreographer;->scheduleFrameLocked(J)V+]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;
+HSPLandroid/view/Choreographer;->scheduleFrameLocked(J)V
 HSPLandroid/view/Choreographer;->scheduleVsyncLocked()V+]Landroid/view/Choreographer$FrameDisplayEventReceiver;Landroid/view/Choreographer$FrameDisplayEventReceiver;
 HSPLandroid/view/Choreographer;->setFPSDivisor(I)V
 HSPLandroid/view/ContextThemeWrapper;-><init>()V
@@ -15954,7 +16023,7 @@
 HSPLandroid/view/ContextThemeWrapper;->getResourcesInternal()Landroid/content/res/Resources;
 HSPLandroid/view/ContextThemeWrapper;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
 HSPLandroid/view/ContextThemeWrapper;->getTheme()Landroid/content/res/Resources$Theme;+]Landroid/view/ContextThemeWrapper;Landroid/view/ContextThemeWrapper;
-HSPLandroid/view/ContextThemeWrapper;->initializeTheme()V+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/view/ContextThemeWrapper;Landroid/view/ContextThemeWrapper;
+HSPLandroid/view/ContextThemeWrapper;->initializeTheme()V
 HSPLandroid/view/ContextThemeWrapper;->onApplyThemeResource(Landroid/content/res/Resources$Theme;IZ)V
 HSPLandroid/view/ContextThemeWrapper;->setTheme(I)V
 HSPLandroid/view/CrossWindowBlurListeners;-><clinit>()V
@@ -15982,7 +16051,7 @@
 HSPLandroid/view/Display$Mode;->toString()Ljava/lang/String;
 HSPLandroid/view/Display;-><init>(Landroid/hardware/display/DisplayManagerGlobal;ILandroid/view/DisplayInfo;Landroid/content/res/Resources;)V
 HSPLandroid/view/Display;-><init>(Landroid/hardware/display/DisplayManagerGlobal;ILandroid/view/DisplayInfo;Landroid/view/DisplayAdjustments;)V
-HSPLandroid/view/Display;-><init>(Landroid/hardware/display/DisplayManagerGlobal;ILandroid/view/DisplayInfo;Landroid/view/DisplayAdjustments;Landroid/content/res/Resources;)V+]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/view/Display;-><init>(Landroid/hardware/display/DisplayManagerGlobal;ILandroid/view/DisplayInfo;Landroid/view/DisplayAdjustments;Landroid/content/res/Resources;)V
 HSPLandroid/view/Display;->getAppVsyncOffsetNanos()J
 HSPLandroid/view/Display;->getCutout()Landroid/view/DisplayCutout;
 HSPLandroid/view/Display;->getDisplayAdjustments()Landroid/view/DisplayAdjustments;
@@ -15992,7 +16061,7 @@
 HSPLandroid/view/Display;->getHdrSdrRatio()F
 HSPLandroid/view/Display;->getHeight()I
 HSPLandroid/view/Display;->getInstallOrientation()I
-HSPLandroid/view/Display;->getLocalRotation()I
+HSPLandroid/view/Display;->getLocalRotation()I+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
 HSPLandroid/view/Display;->getMetrics(Landroid/util/DisplayMetrics;)V
 HSPLandroid/view/Display;->getMode()Landroid/view/Display$Mode;
 HSPLandroid/view/Display;->getName()Ljava/lang/String;
@@ -16038,7 +16107,7 @@
 HSPLandroid/view/DisplayCutout$Bounds;->getRects()[Landroid/graphics/Rect;
 HSPLandroid/view/DisplayCutout$Bounds;->isEmpty()Z
 HSPLandroid/view/DisplayCutout$CutoutPathParserInfo;-><init>(IIIIFLjava/lang/String;IFF)V
-HSPLandroid/view/DisplayCutout$CutoutPathParserInfo;->equals(Ljava/lang/Object;)Z+]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/view/DisplayCutout$CutoutPathParserInfo;->equals(Ljava/lang/Object;)Z
 HSPLandroid/view/DisplayCutout$ParcelableWrapper$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/DisplayCutout$ParcelableWrapper;
 HSPLandroid/view/DisplayCutout$ParcelableWrapper$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/view/DisplayCutout$ParcelableWrapper;-><init>()V
@@ -16066,7 +16135,7 @@
 HSPLandroid/view/DisplayCutout;->inset(IIII)Landroid/view/DisplayCutout;
 HSPLandroid/view/DisplayCutout;->insetInsets(IIIILandroid/graphics/Rect;)Landroid/graphics/Rect;
 HSPLandroid/view/DisplayCutout;->isBoundsEmpty()Z
-HSPLandroid/view/DisplayCutout;->isEmpty()Z
+HSPLandroid/view/DisplayCutout;->isEmpty()Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;
 HSPLandroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;-><init>()V
 HSPLandroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;-><init>(JJJ)V
 HSPLandroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;->copyFrom(Landroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;)V
@@ -16085,19 +16154,19 @@
 HSPLandroid/view/DisplayInfo;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/view/DisplayInfo;-><init>(Landroid/os/Parcel;Landroid/view/DisplayInfo-IA;)V
 HSPLandroid/view/DisplayInfo;->copyFrom(Landroid/view/DisplayInfo;)V
-HSPLandroid/view/DisplayInfo;->equals(Landroid/view/DisplayInfo;)Z
+HSPLandroid/view/DisplayInfo;->equals(Landroid/view/DisplayInfo;)Z+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/DisplayInfo;Landroid/view/DisplayInfo;
 HSPLandroid/view/DisplayInfo;->findMode(I)Landroid/view/Display$Mode;
 HSPLandroid/view/DisplayInfo;->flagsToString(I)Ljava/lang/String;
 HSPLandroid/view/DisplayInfo;->getAppMetrics(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;)V
 HSPLandroid/view/DisplayInfo;->getAppMetrics(Landroid/util/DisplayMetrics;Landroid/view/DisplayAdjustments;)V
 HSPLandroid/view/DisplayInfo;->getLogicalMetrics(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;)V
 HSPLandroid/view/DisplayInfo;->getMaxBoundsMetrics(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;)V
-HSPLandroid/view/DisplayInfo;->getMetricsWithSize(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;II)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/view/DisplayInfo;->getMetricsWithSize(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;II)V+]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
 HSPLandroid/view/DisplayInfo;->getMode()Landroid/view/Display$Mode;
 HSPLandroid/view/DisplayInfo;->getRefreshRate()F
 HSPLandroid/view/DisplayInfo;->hasAccess(I)Z
 HSPLandroid/view/DisplayInfo;->isWideColorGamut()Z
-HSPLandroid/view/DisplayInfo;->readFromParcel(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/view/Display$Mode$1;
+HSPLandroid/view/DisplayInfo;->readFromParcel(Landroid/os/Parcel;)V
 HSPLandroid/view/DisplayInfo;->toString()Ljava/lang/String;
 HSPLandroid/view/DisplayInfo;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/view/DisplayShape$1;-><init>()V
@@ -16181,6 +16250,7 @@
 HSPLandroid/view/HandwritingInitiator;->onInputConnectionCreated(Landroid/view/View;)V
 HSPLandroid/view/HandwritingInitiator;->onTouchEvent(Landroid/view/MotionEvent;)Z
 HSPLandroid/view/HandwritingInitiator;->updateHandwritingAreasForView(Landroid/view/View;)V
+HSPLandroid/view/HdrRenderState;->updateForFrame(J)Z
 HSPLandroid/view/IGraphicsStats$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 HSPLandroid/view/IGraphicsStats$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/view/IGraphicsStats$Stub$Proxy;->requestBufferForProcess(Ljava/lang/String;Landroid/view/IGraphicsStatsCallback;)Landroid/os/ParcelFileDescriptor;
@@ -16213,7 +16283,8 @@
 HSPLandroid/view/IWindowSession$Stub$Proxy;->getWindowId(Landroid/os/IBinder;)Landroid/view/IWindowId;
 HSPLandroid/view/IWindowSession$Stub$Proxy;->onRectangleOnScreenRequested(Landroid/os/IBinder;Landroid/graphics/Rect;)V
 HSPLandroid/view/IWindowSession$Stub$Proxy;->pokeDrawLock(Landroid/os/IBinder;)V
-HSPLandroid/view/IWindowSession$Stub$Proxy;->relayoutAsync(Landroid/view/IWindow;Landroid/view/WindowManager$LayoutParams;IIIIII)V
+HSPLandroid/view/IWindowSession$Stub$Proxy;->relayout(Landroid/view/IWindow;Landroid/view/WindowManager$LayoutParams;IIIIIILandroid/window/ClientWindowFrames;Landroid/util/MergedConfiguration;Landroid/view/SurfaceControl;Landroid/view/InsetsState;Landroid/view/InsetsSourceControl$Array;Landroid/os/Bundle;)I
+HSPLandroid/view/IWindowSession$Stub$Proxy;->relayoutAsync(Landroid/view/IWindow;Landroid/view/WindowManager$LayoutParams;IIIIII)V+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/view/IWindowSession$Stub$Proxy;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/view/IWindowSession$Stub$Proxy;->reportSystemGestureExclusionChanged(Landroid/view/IWindow;Ljava/util/List;)V
 HSPLandroid/view/IWindowSession$Stub$Proxy;->setInsets(Landroid/view/IWindow;ILandroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Region;)V
 HSPLandroid/view/IWindowSession$Stub$Proxy;->setOnBackInvokedCallbackInfo(Landroid/view/IWindow;Landroid/window/OnBackInvokedCallbackInfo;)V
@@ -16229,7 +16300,7 @@
 HSPLandroid/view/ImeFocusController;->onPreWindowFocus(ZLandroid/view/WindowManager$LayoutParams;)V
 HSPLandroid/view/ImeFocusController;->onProcessImeInputStage(Ljava/lang/Object;Landroid/view/InputEvent;Landroid/view/WindowManager$LayoutParams;Landroid/view/inputmethod/InputMethodManager$FinishedInputEventCallback;)I
 HSPLandroid/view/ImeFocusController;->onTraversal(ZLandroid/view/WindowManager$LayoutParams;)V
-HSPLandroid/view/ImeFocusController;->onViewDetachedFromWindow(Landroid/view/View;)V+]Landroid/view/ImeFocusController$InputMethodManagerDelegate;Landroid/view/inputmethod/InputMethodManager$DelegateImpl;
+HSPLandroid/view/ImeFocusController;->onViewDetachedFromWindow(Landroid/view/View;)V
 HSPLandroid/view/ImeFocusController;->onViewFocusChanged(Landroid/view/View;Z)V
 HSPLandroid/view/ImeFocusController;->onWindowDismissed()V
 HSPLandroid/view/ImeInsetsSourceConsumer;-><init>(ILandroid/view/InsetsState;Ljava/util/function/Supplier;Landroid/view/InsetsController;)V
@@ -16261,7 +16332,7 @@
 HSPLandroid/view/InputDevice;->isVirtual()Z
 HSPLandroid/view/InputEvent;-><init>()V
 HSPLandroid/view/InputEvent;->getSequenceNumber()I
-HSPLandroid/view/InputEvent;->isFromSource(I)Z
+HSPLandroid/view/InputEvent;->isFromSource(I)Z+]Landroid/view/InputEvent;Landroid/view/MotionEvent;
 HSPLandroid/view/InputEvent;->prepareForReuse()V
 HSPLandroid/view/InputEvent;->recycle()V
 HSPLandroid/view/InputEvent;->recycleIfNeededAfterDispatch()V
@@ -16273,7 +16344,7 @@
 HSPLandroid/view/InputEventConsistencyVerifier;->isInstrumentationEnabled()Z
 HSPLandroid/view/InputEventReceiver;-><init>(Landroid/view/InputChannel;Landroid/os/Looper;)V
 HSPLandroid/view/InputEventReceiver;->consumeBatchedInputEvents(J)Z
-HSPLandroid/view/InputEventReceiver;->dispatchInputEvent(ILandroid/view/InputEvent;)V+]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Landroid/view/InputEvent;Landroid/view/MotionEvent;]Landroid/view/InputEventReceiver;Landroid/view/ViewRootImpl$WindowInputEventReceiver;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/InputEventReceiver;->dispatchInputEvent(ILandroid/view/InputEvent;)V
 HSPLandroid/view/InputEventReceiver;->dispose()V
 HSPLandroid/view/InputEventReceiver;->dispose(Z)V
 HSPLandroid/view/InputEventReceiver;->finalize()V
@@ -16349,6 +16420,9 @@
 HSPLandroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda0;->onAnimationUpdate(Landroid/animation/ValueAnimator;)V
 HSPLandroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda3;->getInterpolation(F)F
 HSPLandroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda4;->getInterpolation(F)F
+HSPLandroid/view/InsetsController$InternalAnimationControlListener$1;->initialValue()Landroid/animation/AnimationHandler;
+HSPLandroid/view/InsetsController$InternalAnimationControlListener$1;->initialValue()Ljava/lang/Object;
+HSPLandroid/view/InsetsController$InternalAnimationControlListener$2;->onAnimationEnd(Landroid/animation/Animator;)V
 HSPLandroid/view/InsetsController$InternalAnimationControlListener;-><init>(ZZIIZILandroid/view/WindowInsetsAnimationControlListener;Landroid/view/inputmethod/ImeTracker$InputMethodJankContext;)V
 HSPLandroid/view/InsetsController$InternalAnimationControlListener;->calculateDurationMs()J
 HSPLandroid/view/InsetsController$InternalAnimationControlListener;->getAlphaInterpolator()Landroid/view/animation/Interpolator;
@@ -16375,6 +16449,7 @@
 HSPLandroid/view/InsetsController;->cancelAnimation(Landroid/view/InsetsAnimationControlRunner;Z)V
 HSPLandroid/view/InsetsController;->cancelExistingAnimations()V
 HSPLandroid/view/InsetsController;->cancelExistingControllers(I)V
+HSPLandroid/view/InsetsController;->captionInsetsUnchanged()Z
 HSPLandroid/view/InsetsController;->collectSourceControls(ZILandroid/util/SparseArray;ILandroid/view/inputmethod/ImeTracker$Token;)Landroid/util/Pair;
 HSPLandroid/view/InsetsController;->controlAnimationUncheckedInner(ILandroid/os/CancellationSignal;Landroid/view/WindowInsetsAnimationControlListener;Landroid/graphics/Rect;ZJLandroid/view/animation/Interpolator;IIZLandroid/view/inputmethod/ImeTracker$Token;)V
 HSPLandroid/view/InsetsController;->dispatchAnimationEnd(Landroid/view/WindowInsetsAnimation;)V
@@ -16392,8 +16467,8 @@
 HSPLandroid/view/InsetsController;->notifyControlRevoked(Landroid/view/InsetsSourceConsumer;)V
 HSPLandroid/view/InsetsController;->notifyFinished(Landroid/view/InsetsAnimationControlRunner;Z)V
 HSPLandroid/view/InsetsController;->notifyVisibilityChanged()V
-HSPLandroid/view/InsetsController;->onControlsChanged([Landroid/view/InsetsSourceControl;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/InsetsSourceConsumer;Landroid/view/ImeInsetsSourceConsumer;,Landroid/view/InsetsSourceConsumer;]Landroid/view/InsetsSourceControl;Landroid/view/InsetsSourceControl;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/view/InsetsController;->onFrameChanged(Landroid/graphics/Rect;)V
+HSPLandroid/view/InsetsController;->onControlsChanged([Landroid/view/InsetsSourceControl;)V
+HSPLandroid/view/InsetsController;->onFrameChanged(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
 HSPLandroid/view/InsetsController;->onStateChanged(Landroid/view/InsetsState;)Z
 HSPLandroid/view/InsetsController;->onWindowFocusGained(Z)V
 HSPLandroid/view/InsetsController;->onWindowFocusLost()V
@@ -16406,15 +16481,15 @@
 HSPLandroid/view/InsetsController;->updateState(Landroid/view/InsetsState;)V
 HSPLandroid/view/InsetsFlags;-><init>()V
 HSPLandroid/view/InsetsSource$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/InsetsSource;
-HSPLandroid/view/InsetsSource$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/view/InsetsSource$1;Landroid/view/InsetsSource$1;
+HSPLandroid/view/InsetsSource$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/view/InsetsSource;-><init>(II)V
-HSPLandroid/view/InsetsSource;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/graphics/Rect$1;
+HSPLandroid/view/InsetsSource;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/view/InsetsSource;-><init>(Landroid/view/InsetsSource;)V
-HSPLandroid/view/InsetsSource;->calculateInsets(Landroid/graphics/Rect;Landroid/graphics/Rect;Z)Landroid/graphics/Insets;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsSource;->calculateInsets(Landroid/graphics/Rect;Landroid/graphics/Rect;Z)Landroid/graphics/Insets;+]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/graphics/Rect;Landroid/graphics/Rect;
 HSPLandroid/view/InsetsSource;->calculateInsets(Landroid/graphics/Rect;Z)Landroid/graphics/Insets;
 HSPLandroid/view/InsetsSource;->calculateVisibleInsets(Landroid/graphics/Rect;)Landroid/graphics/Insets;
-HSPLandroid/view/InsetsSource;->equals(Ljava/lang/Object;)Z+]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
-HSPLandroid/view/InsetsSource;->equals(Ljava/lang/Object;Z)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Ljava/lang/Object;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsSource;->equals(Ljava/lang/Object;)Z
+HSPLandroid/view/InsetsSource;->equals(Ljava/lang/Object;Z)Z
 HSPLandroid/view/InsetsSource;->getFlags()I
 HSPLandroid/view/InsetsSource;->getFrame()Landroid/graphics/Rect;
 HSPLandroid/view/InsetsSource;->getId()I
@@ -16468,30 +16543,30 @@
 HSPLandroid/view/InsetsState;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/view/InsetsState;-><init>(Landroid/view/InsetsState;Z)V
 HSPLandroid/view/InsetsState;->addSource(Landroid/view/InsetsSource;)V
-HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;II)Landroid/graphics/Insets;
-HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;IZ)Landroid/graphics/Insets;
+HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;II)Landroid/graphics/Insets;+]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;IZ)Landroid/graphics/Insets;+]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/util/SparseArray;Landroid/util/SparseArray;
 HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;Landroid/view/InsetsState;ZIIIIILandroid/util/SparseIntArray;)Landroid/view/WindowInsets;
 HSPLandroid/view/InsetsState;->calculateRelativeCutout(Landroid/graphics/Rect;)Landroid/view/DisplayCutout;
 HSPLandroid/view/InsetsState;->calculateRelativeDisplayShape(Landroid/graphics/Rect;)Landroid/view/DisplayShape;
 HSPLandroid/view/InsetsState;->calculateRelativePrivacyIndicatorBounds(Landroid/graphics/Rect;)Landroid/view/PrivacyIndicatorBounds;
 HSPLandroid/view/InsetsState;->calculateRelativeRoundedCorners(Landroid/graphics/Rect;)Landroid/view/RoundedCorners;
-HSPLandroid/view/InsetsState;->calculateUncontrollableInsetsFromFrame(Landroid/graphics/Rect;)I+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsState;->calculateUncontrollableInsetsFromFrame(Landroid/graphics/Rect;)I
 HSPLandroid/view/InsetsState;->calculateVisibleInsets(Landroid/graphics/Rect;IIII)Landroid/graphics/Insets;
-HSPLandroid/view/InsetsState;->canControlSource(Landroid/graphics/Rect;Landroid/view/InsetsSource;)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsState;->canControlSource(Landroid/graphics/Rect;Landroid/view/InsetsSource;)Z
 HSPLandroid/view/InsetsState;->clearsCompatInsets(IIII)Z
 HSPLandroid/view/InsetsState;->equals(Ljava/lang/Object;)Z
 HSPLandroid/view/InsetsState;->equals(Ljava/lang/Object;ZZ)Z
-HSPLandroid/view/InsetsState;->getDisplayCutout()Landroid/view/DisplayCutout;
-HSPLandroid/view/InsetsState;->getDisplayCutoutSafe(Landroid/graphics/Rect;)V
+HSPLandroid/view/InsetsState;->getDisplayCutout()Landroid/view/DisplayCutout;+]Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/view/DisplayCutout$ParcelableWrapper;
+HSPLandroid/view/InsetsState;->getDisplayCutoutSafe(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/DisplayCutout;Landroid/view/DisplayCutout;]Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/view/DisplayCutout$ParcelableWrapper;
 HSPLandroid/view/InsetsState;->getDisplayFrame()Landroid/graphics/Rect;
 HSPLandroid/view/InsetsState;->getDisplayShape()Landroid/view/DisplayShape;
 HSPLandroid/view/InsetsState;->getPrivacyIndicatorBounds()Landroid/view/PrivacyIndicatorBounds;
 HSPLandroid/view/InsetsState;->getRoundedCorners()Landroid/view/RoundedCorners;
 HSPLandroid/view/InsetsState;->isSourceOrDefaultVisible(II)Z
 HSPLandroid/view/InsetsState;->peekSource(I)Landroid/view/InsetsSource;
-HSPLandroid/view/InsetsState;->readFromParcel(Landroid/os/Parcel;)Landroid/util/SparseArray;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/view/DisplayCutout$ParcelableWrapper;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsState;->readFromParcel(Landroid/os/Parcel;)Landroid/util/SparseArray;
 HSPLandroid/view/InsetsState;->set(Landroid/view/InsetsState;I)V
-HSPLandroid/view/InsetsState;->set(Landroid/view/InsetsState;Z)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/view/DisplayCutout$ParcelableWrapper;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/view/InsetsState;Landroid/view/InsetsState;
+HSPLandroid/view/InsetsState;->set(Landroid/view/InsetsState;Z)V
 HSPLandroid/view/InsetsState;->setDisplayCutout(Landroid/view/DisplayCutout;)V
 HSPLandroid/view/InsetsState;->setDisplayFrame(Landroid/graphics/Rect;)V
 HSPLandroid/view/InsetsState;->setPrivacyIndicatorBounds(Landroid/view/PrivacyIndicatorBounds;)V
@@ -16550,28 +16625,28 @@
 HSPLandroid/view/LayoutInflater;-><init>(Landroid/view/LayoutInflater;Landroid/content/Context;)V
 HSPLandroid/view/LayoutInflater;->advanceToRootNode(Lorg/xmlpull/v1/XmlPullParser;)V
 HSPLandroid/view/LayoutInflater;->consumeChildElements(Lorg/xmlpull/v1/XmlPullParser;)V
-HSPLandroid/view/LayoutInflater;->createView(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;+]Landroid/content/Context;missing_types]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/view/ViewStub;Landroid/view/ViewStub;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/reflect/Constructor;Ljava/lang/reflect/Constructor;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/view/LayoutInflater;->createView(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
 HSPLandroid/view/LayoutInflater;->createView(Ljava/lang/String;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
 HSPLandroid/view/LayoutInflater;->createViewFromTag(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
-HSPLandroid/view/LayoutInflater;->createViewFromTag(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;Z)Landroid/view/View;+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/util/AttributeSet;Landroid/content/res/XmlBlock$Parser;]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/view/LayoutInflater;->createViewFromTag(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;Z)Landroid/view/View;
 HSPLandroid/view/LayoutInflater;->from(Landroid/content/Context;)Landroid/view/LayoutInflater;
 HSPLandroid/view/LayoutInflater;->getContext()Landroid/content/Context;
 HSPLandroid/view/LayoutInflater;->getFactory()Landroid/view/LayoutInflater$Factory;
 HSPLandroid/view/LayoutInflater;->getFactory2()Landroid/view/LayoutInflater$Factory2;
 HSPLandroid/view/LayoutInflater;->inflate(ILandroid/view/ViewGroup;)Landroid/view/View;
 HSPLandroid/view/LayoutInflater;->inflate(ILandroid/view/ViewGroup;Z)Landroid/view/View;
-HSPLandroid/view/LayoutInflater;->inflate(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/ViewGroup;Z)Landroid/view/View;+]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/view/LayoutInflater;->inflate(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/ViewGroup;Z)Landroid/view/View;
 HSPLandroid/view/LayoutInflater;->onCreateView(Landroid/content/Context;Landroid/view/View;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
 HSPLandroid/view/LayoutInflater;->onCreateView(Landroid/view/View;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
 HSPLandroid/view/LayoutInflater;->onCreateView(Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
-HSPLandroid/view/LayoutInflater;->parseInclude(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/Context;Landroid/view/View;Landroid/util/AttributeSet;)V
-HSPLandroid/view/LayoutInflater;->rInflate(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/View;Landroid/content/Context;Landroid/util/AttributeSet;Z)V+]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
-HSPLandroid/view/LayoutInflater;->rInflateChildren(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/View;Landroid/util/AttributeSet;Z)V+]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/view/View;missing_types
+HSPLandroid/view/LayoutInflater;->parseInclude(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/Context;Landroid/view/View;Landroid/util/AttributeSet;)V+]Landroid/util/AttributeSet;Landroid/content/res/XmlBlock$Parser;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;Landroid/widget/FrameLayout;,Landroid/widget/LinearLayout;]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Ljava/lang/Object;Ljava/lang/String;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/content/res/XmlResourceParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/view/LayoutInflater;->rInflate(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/View;Landroid/content/Context;Landroid/util/AttributeSet;Z)V+]Landroid/view/View;missing_types]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;]Landroid/view/ViewGroup;Landroid/widget/RelativeLayout;,Landroid/widget/FrameLayout;,Landroid/widget/LinearLayout;]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/view/LayoutInflater;->rInflateChildren(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/View;Landroid/util/AttributeSet;Z)V
 HSPLandroid/view/LayoutInflater;->setFactory2(Landroid/view/LayoutInflater$Factory2;)V
 HSPLandroid/view/LayoutInflater;->setFilter(Landroid/view/LayoutInflater$Filter;)V
 HSPLandroid/view/LayoutInflater;->setPrivateFactory(Landroid/view/LayoutInflater$Factory2;)V
-HSPLandroid/view/LayoutInflater;->tryCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;+]Landroid/view/LayoutInflater$Factory2;missing_types]Ljava/lang/Object;Ljava/lang/String;
-HSPLandroid/view/LayoutInflater;->verifyClassLoader(Ljava/lang/reflect/Constructor;)Z+]Landroid/content/Context;missing_types]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/reflect/Constructor;Ljava/lang/reflect/Constructor;
+HSPLandroid/view/LayoutInflater;->tryCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
+HSPLandroid/view/LayoutInflater;->verifyClassLoader(Ljava/lang/reflect/Constructor;)Z
 HSPLandroid/view/MenuInflater;-><init>(Landroid/content/Context;)V
 HSPLandroid/view/MotionEvent$PointerCoords;-><init>()V
 HSPLandroid/view/MotionEvent$PointerProperties;-><init>()V
@@ -16612,7 +16687,7 @@
 HSPLandroid/view/MotionEvent;->getY()F
 HSPLandroid/view/MotionEvent;->getY(I)F
 HSPLandroid/view/MotionEvent;->initialize(IIIIIIIIIFFFFJJI[Landroid/view/MotionEvent$PointerProperties;[Landroid/view/MotionEvent$PointerCoords;)Z
-HSPLandroid/view/MotionEvent;->isTargetAccessibilityFocus()Z
+HSPLandroid/view/MotionEvent;->isTargetAccessibilityFocus()Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
 HSPLandroid/view/MotionEvent;->isTouchEvent()Z
 HSPLandroid/view/MotionEvent;->obtain()Landroid/view/MotionEvent;
 HSPLandroid/view/MotionEvent;->obtain(JJIFFFFIFFII)Landroid/view/MotionEvent;
@@ -16623,7 +16698,7 @@
 HSPLandroid/view/MotionEvent;->recycle()V
 HSPLandroid/view/MotionEvent;->setAction(I)V
 HSPLandroid/view/MotionEvent;->setLocation(FF)V
-HSPLandroid/view/MotionEvent;->setTargetAccessibilityFocus(Z)V
+HSPLandroid/view/MotionEvent;->setTargetAccessibilityFocus(Z)V+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
 HSPLandroid/view/MotionEvent;->split(I)Landroid/view/MotionEvent;
 HSPLandroid/view/MotionEvent;->transform(Landroid/graphics/Matrix;)V
 HSPLandroid/view/MotionEvent;->updateCursorPosition()V
@@ -16659,12 +16734,12 @@
 HSPLandroid/view/RemoteAnimationAdapter;-><init>(Landroid/view/IRemoteAnimationRunner;JJ)V
 HSPLandroid/view/RemoteAnimationAdapter;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/view/RoundedCorner$1;-><init>()V
-HSPLandroid/view/RoundedCorner$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/RoundedCorner;+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/view/RoundedCorner$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/view/RoundedCorner$1;Landroid/view/RoundedCorner$1;
+HSPLandroid/view/RoundedCorner$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/RoundedCorner;
+HSPLandroid/view/RoundedCorner$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/view/RoundedCorner;-><clinit>()V
 HSPLandroid/view/RoundedCorner;-><init>(I)V
 HSPLandroid/view/RoundedCorner;-><init>(IIII)V
-HSPLandroid/view/RoundedCorner;->equals(Ljava/lang/Object;)Z+]Landroid/graphics/Point;Landroid/graphics/Point;
+HSPLandroid/view/RoundedCorner;->equals(Ljava/lang/Object;)Z
 HSPLandroid/view/RoundedCorner;->getCenter()Landroid/graphics/Point;
 HSPLandroid/view/RoundedCorner;->getRadius()I
 HSPLandroid/view/RoundedCorner;->isEmpty()Z
@@ -16727,7 +16802,7 @@
 HSPLandroid/view/SurfaceControl$Builder;->setParent(Landroid/view/SurfaceControl;)Landroid/view/SurfaceControl$Builder;
 HSPLandroid/view/SurfaceControl$Builder;->unsetBufferSize()V
 HSPLandroid/view/SurfaceControl$Transaction;-><init>()V
-HSPLandroid/view/SurfaceControl$Transaction;-><init>(J)V
+HSPLandroid/view/SurfaceControl$Transaction;-><init>(J)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
 HSPLandroid/view/SurfaceControl$Transaction;->apply()V
 HSPLandroid/view/SurfaceControl$Transaction;->apply(Z)V
 HSPLandroid/view/SurfaceControl$Transaction;->applyResizedSurfaces()V
@@ -16735,7 +16810,7 @@
 HSPLandroid/view/SurfaceControl$Transaction;->clear()V
 HSPLandroid/view/SurfaceControl$Transaction;->close()V
 HSPLandroid/view/SurfaceControl$Transaction;->hide(Landroid/view/SurfaceControl;)Landroid/view/SurfaceControl$Transaction;
-HSPLandroid/view/SurfaceControl$Transaction;->merge(Landroid/view/SurfaceControl$Transaction;)Landroid/view/SurfaceControl$Transaction;
+HSPLandroid/view/SurfaceControl$Transaction;->merge(Landroid/view/SurfaceControl$Transaction;)Landroid/view/SurfaceControl$Transaction;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
 HSPLandroid/view/SurfaceControl$Transaction;->notifyReparentedSurfaces()V
 HSPLandroid/view/SurfaceControl$Transaction;->remove(Landroid/view/SurfaceControl;)Landroid/view/SurfaceControl$Transaction;
 HSPLandroid/view/SurfaceControl$Transaction;->reparent(Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;)Landroid/view/SurfaceControl$Transaction;
@@ -16745,7 +16820,7 @@
 HSPLandroid/view/SurfaceControl$Transaction;->setColor(Landroid/view/SurfaceControl;[F)Landroid/view/SurfaceControl$Transaction;
 HSPLandroid/view/SurfaceControl$Transaction;->setCornerRadius(Landroid/view/SurfaceControl;F)Landroid/view/SurfaceControl$Transaction;
 HSPLandroid/view/SurfaceControl$Transaction;->setDesintationFrame(Landroid/view/SurfaceControl;II)Landroid/view/SurfaceControl$Transaction;
-HSPLandroid/view/SurfaceControl$Transaction;->setExtendedRangeBrightness(Landroid/view/SurfaceControl;FF)Landroid/view/SurfaceControl$Transaction;
+HSPLandroid/view/SurfaceControl$Transaction;->setExtendedRangeBrightness(Landroid/view/SurfaceControl;FF)Landroid/view/SurfaceControl$Transaction;+]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;
 HSPLandroid/view/SurfaceControl$Transaction;->setFrameTimelineVsync(J)Landroid/view/SurfaceControl$Transaction;
 HSPLandroid/view/SurfaceControl$Transaction;->setLayer(Landroid/view/SurfaceControl;I)Landroid/view/SurfaceControl$Transaction;
 HSPLandroid/view/SurfaceControl$Transaction;->setMatrix(Landroid/view/SurfaceControl;FFFF)Landroid/view/SurfaceControl$Transaction;
@@ -16813,6 +16888,7 @@
 HSPLandroid/view/SurfaceView;->onSetSurfacePositionAndScale(Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl;IIFF)V
 HSPLandroid/view/SurfaceView;->onWindowVisibilityChanged(I)V
 HSPLandroid/view/SurfaceView;->performDrawFinished()V
+HSPLandroid/view/SurfaceView;->performSurfaceTransaction(Landroid/view/ViewRootImpl;Landroid/content/res/CompatibilityInfo$Translator;ZZZZLandroid/view/SurfaceControl$Transaction;)Z
 HSPLandroid/view/SurfaceView;->releaseSurfaces(Z)V
 HSPLandroid/view/SurfaceView;->replacePositionUpdateListener(II)V
 HSPLandroid/view/SurfaceView;->requiresSurfaceControlCreation(ZZ)Z
@@ -16853,8 +16929,8 @@
 HSPLandroid/view/ThreadedRenderer$1$$ExternalSyntheticLambda0;-><init>(Ljava/util/ArrayList;)V
 HSPLandroid/view/ThreadedRenderer$1$$ExternalSyntheticLambda0;->onFrameCommit(Z)V
 HSPLandroid/view/ThreadedRenderer$1;-><init>(Landroid/view/ThreadedRenderer;Ljava/util/ArrayList;)V
-HSPLandroid/view/ThreadedRenderer$1;->lambda$onFrameDraw$0(Ljava/util/ArrayList;Z)V
-HSPLandroid/view/ThreadedRenderer$1;->onFrameDraw(IJ)Landroid/graphics/HardwareRenderer$FrameCommitCallback;
+HSPLandroid/view/ThreadedRenderer$1;->lambda$onFrameDraw$0(Ljava/util/ArrayList;Z)V+]Landroid/graphics/HardwareRenderer$FrameCommitCallback;Landroid/view/ViewRootImpl$7$$ExternalSyntheticLambda0;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ThreadedRenderer$1;->onFrameDraw(IJ)Landroid/graphics/HardwareRenderer$FrameCommitCallback;+]Landroid/graphics/HardwareRenderer$FrameDrawingCallback;Landroid/view/ViewRootImpl$3;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/ThreadedRenderer$WebViewOverlayProvider;->-$$Nest$fgetmSurfaceControl(Landroid/view/ThreadedRenderer$WebViewOverlayProvider;)Landroid/view/SurfaceControl;
 HSPLandroid/view/ThreadedRenderer$WebViewOverlayProvider;-><clinit>()V
 HSPLandroid/view/ThreadedRenderer$WebViewOverlayProvider;-><init>()V
@@ -16869,7 +16945,7 @@
 HSPLandroid/view/ThreadedRenderer;->destroy()V
 HSPLandroid/view/ThreadedRenderer;->destroyHardwareResources(Landroid/view/View;)V
 HSPLandroid/view/ThreadedRenderer;->destroyResources(Landroid/view/View;)V
-HSPLandroid/view/ThreadedRenderer;->draw(Landroid/view/View;Landroid/view/View$AttachInfo;Landroid/view/ThreadedRenderer$DrawCallbacks;)V
+HSPLandroid/view/ThreadedRenderer;->draw(Landroid/view/View;Landroid/view/View$AttachInfo;Landroid/view/ThreadedRenderer$DrawCallbacks;)V+]Landroid/view/ViewFrameInfo;Landroid/view/ViewFrameInfo;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
 HSPLandroid/view/ThreadedRenderer;->dumpArgsToFlags([Ljava/lang/String;)I
 HSPLandroid/view/ThreadedRenderer;->getHeight()I
 HSPLandroid/view/ThreadedRenderer;->getWidth()I
@@ -16880,20 +16956,20 @@
 HSPLandroid/view/ThreadedRenderer;->isEnabled()Z
 HSPLandroid/view/ThreadedRenderer;->isRequested()Z
 HSPLandroid/view/ThreadedRenderer;->loadSystemProperties()Z
-HSPLandroid/view/ThreadedRenderer;->registerRtFrameCallback(Landroid/graphics/HardwareRenderer$FrameDrawingCallback;)V
+HSPLandroid/view/ThreadedRenderer;->registerRtFrameCallback(Landroid/graphics/HardwareRenderer$FrameDrawingCallback;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/ThreadedRenderer;->rendererOwnsSurfaceControlOpacity()Z
 HSPLandroid/view/ThreadedRenderer;->setEnabled(Z)V
 HSPLandroid/view/ThreadedRenderer;->setLightCenter(Landroid/view/View$AttachInfo;)V
 HSPLandroid/view/ThreadedRenderer;->setRequested(Z)V
 HSPLandroid/view/ThreadedRenderer;->setSurface(Landroid/view/Surface;)V
-HSPLandroid/view/ThreadedRenderer;->setSurfaceControl(Landroid/view/SurfaceControl;Landroid/graphics/BLASTBufferQueue;)V
+HSPLandroid/view/ThreadedRenderer;->setSurfaceControl(Landroid/view/SurfaceControl;Landroid/graphics/BLASTBufferQueue;)V+]Landroid/view/ThreadedRenderer$WebViewOverlayProvider;Landroid/view/ThreadedRenderer$WebViewOverlayProvider;
 HSPLandroid/view/ThreadedRenderer;->setSurfaceControlOpaque(Z)Z
 HSPLandroid/view/ThreadedRenderer;->setup(IILandroid/view/View$AttachInfo;Landroid/graphics/Rect;)V
 HSPLandroid/view/ThreadedRenderer;->updateEnabledState(Landroid/view/Surface;)V
-HSPLandroid/view/ThreadedRenderer;->updateRootDisplayList(Landroid/view/View;Landroid/view/ThreadedRenderer$DrawCallbacks;)V
+HSPLandroid/view/ThreadedRenderer;->updateRootDisplayList(Landroid/view/View;Landroid/view/ThreadedRenderer$DrawCallbacks;)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/ThreadedRenderer$DrawCallbacks;Landroid/view/ViewRootImpl;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/view/ThreadedRenderer;->updateSurface(Landroid/view/Surface;)V
-HSPLandroid/view/ThreadedRenderer;->updateViewTreeDisplayList(Landroid/view/View;)V
-HSPLandroid/view/ThreadedRenderer;->updateWebViewOverlayCallbacks()V
+HSPLandroid/view/ThreadedRenderer;->updateViewTreeDisplayList(Landroid/view/View;)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ThreadedRenderer;->updateWebViewOverlayCallbacks()V+]Landroid/view/ThreadedRenderer$WebViewOverlayProvider;Landroid/view/ThreadedRenderer$WebViewOverlayProvider;
 HSPLandroid/view/TouchDelegate;-><init>(Landroid/graphics/Rect;Landroid/view/View;)V
 HSPLandroid/view/VelocityTracker;-><init>(I)V
 HSPLandroid/view/VelocityTracker;->addMovement(Landroid/view/MotionEvent;)V
@@ -16915,7 +16991,7 @@
 HSPLandroid/view/View$12;->get(Landroid/view/View;)Ljava/lang/Float;
 HSPLandroid/view/View$12;->get(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/view/View$12;->setValue(Landroid/view/View;F)V
-HSPLandroid/view/View$12;->setValue(Ljava/lang/Object;F)V
+HSPLandroid/view/View$12;->setValue(Ljava/lang/Object;F)V+]Landroid/view/View$12;Landroid/view/View$12;
 HSPLandroid/view/View$13;->get(Landroid/view/View;)Ljava/lang/Float;
 HSPLandroid/view/View$13;->get(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/view/View$13;->setValue(Landroid/view/View;F)V
@@ -16969,31 +17045,31 @@
 HSPLandroid/view/View$MeasureSpec;->makeSafeMeasureSpec(II)I
 HSPLandroid/view/View$PerformClick;->run()V
 HSPLandroid/view/View$ScrollabilityCache;-><init>(Landroid/view/ViewConfiguration;Landroid/view/View;)V
-HSPLandroid/view/View$ScrollabilityCache;->run()V
+HSPLandroid/view/View$ScrollabilityCache;->run()V+]Landroid/graphics/Interpolator;Landroid/graphics/Interpolator;]Landroid/view/View;missing_types
 HSPLandroid/view/View$TintInfo;-><init>()V
 HSPLandroid/view/View$TransformationInfo;-><init>()V
 HSPLandroid/view/View$UnsetPressedState;->run()V
 HSPLandroid/view/View$VisibilityChangeForAutofillHandler;->handleMessage(Landroid/os/Message;)V
-HSPLandroid/view/View;-><init>(Landroid/content/Context;)V+]Landroid/content/Context;missing_types]Landroid/view/View;missing_types]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;missing_types
+HSPLandroid/view/View;-><init>(Landroid/content/Context;)V+]Landroid/view/View;missing_types]Ljava/lang/Object;missing_types]Landroid/content/Context;missing_types]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Ljava/lang/Class;Ljava/lang/Class;
 HSPLandroid/view/View;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/view/View;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/view/View;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types
+HSPLandroid/view/View;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/view/View;missing_types]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
 HSPLandroid/view/View;->addFocusables(Ljava/util/ArrayList;I)V
 HSPLandroid/view/View;->addFocusables(Ljava/util/ArrayList;II)V
 HSPLandroid/view/View;->addFrameMetricsListener(Landroid/view/Window;Landroid/view/Window$OnFrameMetricsAvailableListener;Landroid/os/Handler;)V
 HSPLandroid/view/View;->addOnAttachStateChangeListener(Landroid/view/View$OnAttachStateChangeListener;)V
-HSPLandroid/view/View;->addOnLayoutChangeListener(Landroid/view/View$OnLayoutChangeListener;)V+]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/View;->addOnLayoutChangeListener(Landroid/view/View$OnLayoutChangeListener;)V
 HSPLandroid/view/View;->animate()Landroid/view/ViewPropertyAnimator;
 HSPLandroid/view/View;->announceForAccessibility(Ljava/lang/CharSequence;)V
 HSPLandroid/view/View;->appendId(Ljava/lang/StringBuilder;)V
 HSPLandroid/view/View;->applyBackgroundTint()V
 HSPLandroid/view/View;->applyForegroundTint()V
 HSPLandroid/view/View;->applyInsets(Landroid/graphics/Rect;)V
-HSPLandroid/view/View;->applyLegacyAnimation(Landroid/view/ViewGroup;JLandroid/view/animation/Animation;Z)Z+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/view/View;missing_types]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;
+HSPLandroid/view/View;->applyLegacyAnimation(Landroid/view/ViewGroup;JLandroid/view/animation/Animation;Z)Z
 HSPLandroid/view/View;->areDrawablesResolved()Z
 HSPLandroid/view/View;->assignParent(Landroid/view/ViewParent;)V
 HSPLandroid/view/View;->awakenScrollBars()Z
-HSPLandroid/view/View;->awakenScrollBars(IZ)Z+]Landroid/os/Handler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->awakenScrollBars(IZ)Z+]Landroid/os/Handler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/view/View;Landroid/widget/ImageView;,Landroid/widget/TextView;,Landroid/widget/LinearLayout;
 HSPLandroid/view/View;->bringToFront()V
 HSPLandroid/view/View;->buildDrawingCache(Z)V
 HSPLandroid/view/View;->buildDrawingCacheImpl(Z)V
@@ -17001,7 +17077,7 @@
 HSPLandroid/view/View;->calculateAccessibilityDataSensitive()V
 HSPLandroid/view/View;->calculateIsImportantForContentCapture()Z
 HSPLandroid/view/View;->canHaveDisplayList()Z
-HSPLandroid/view/View;->canNotifyAutofillEnterExitEvent()Z+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->canNotifyAutofillEnterExitEvent()Z
 HSPLandroid/view/View;->canReceivePointerEvents()Z
 HSPLandroid/view/View;->canResolveLayoutDirection()Z+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
 HSPLandroid/view/View;->canResolveTextDirection()Z+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
@@ -17013,8 +17089,8 @@
 HSPLandroid/view/View;->cancelPendingInputEvents()V
 HSPLandroid/view/View;->checkForLongClick(JFFI)V
 HSPLandroid/view/View;->checkInputConnectionProxy(Landroid/view/View;)Z
-HSPLandroid/view/View;->cleanupDraw()V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
-HSPLandroid/view/View;->clearAccessibilityFocus()V+]Landroid/view/View;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/View;->cleanupDraw()V
+HSPLandroid/view/View;->clearAccessibilityFocus()V
 HSPLandroid/view/View;->clearAccessibilityFocusNoCallbacks(I)V
 HSPLandroid/view/View;->clearAccessibilityThrottles()V
 HSPLandroid/view/View;->clearAnimation()V
@@ -17023,7 +17099,7 @@
 HSPLandroid/view/View;->clearParentsWantFocus()V
 HSPLandroid/view/View;->clearTranslationState()V
 HSPLandroid/view/View;->clearViewTranslationResponse()V
-HSPLandroid/view/View;->collectPreferKeepClearRects()Ljava/util/List;+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->collectPreferKeepClearRects()Ljava/util/List;
 HSPLandroid/view/View;->collectUnrestrictedPreferKeepClearRects()Ljava/util/List;
 HSPLandroid/view/View;->combineMeasuredStates(II)I
 HSPLandroid/view/View;->combineVisibility(II)I
@@ -17031,21 +17107,21 @@
 HSPLandroid/view/View;->computeHorizontalScrollExtent()I
 HSPLandroid/view/View;->computeHorizontalScrollOffset()I
 HSPLandroid/view/View;->computeHorizontalScrollRange()I
-HSPLandroid/view/View;->computeOpaqueFlags()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/view/View;->computeOpaqueFlags()V
 HSPLandroid/view/View;->computeScroll()V
 HSPLandroid/view/View;->computeSystemWindowInsets(Landroid/view/WindowInsets;Landroid/graphics/Rect;)Landroid/view/WindowInsets;
-HSPLandroid/view/View;->computeVerticalScrollExtent()I
+HSPLandroid/view/View;->computeVerticalScrollExtent()I+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->computeVerticalScrollOffset()I
-HSPLandroid/view/View;->computeVerticalScrollRange()I
-HSPLandroid/view/View;->damageInParent()V+]Landroid/view/ViewParent;missing_types
+HSPLandroid/view/View;->computeVerticalScrollRange()I+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->damageInParent()V
 HSPLandroid/view/View;->destroyDrawingCache()V
 HSPLandroid/view/View;->destroyHardwareResources()V
-HSPLandroid/view/View;->dispatchApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V+]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Landroid/view/View;missing_types]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/Iterator;Ljava/util/concurrent/CopyOnWriteArrayList$COWIterator;]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;
-HSPLandroid/view/View;->dispatchCancelPendingInputEvents()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->dispatchApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
+HSPLandroid/view/View;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V+]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/View;missing_types]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;]Ljava/util/Iterator;Ljava/util/concurrent/CopyOnWriteArrayList$COWIterator;
+HSPLandroid/view/View;->dispatchCancelPendingInputEvents()V
 HSPLandroid/view/View;->dispatchCollectViewAttributes(Landroid/view/View$AttachInfo;I)V+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->dispatchConfigurationChanged(Landroid/content/res/Configuration;)V
-HSPLandroid/view/View;->dispatchDetachedFromWindow()V+]Landroid/view/ImeFocusController;Landroid/view/ImeFocusController;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;Landroid/view/ViewOverlay$OverlayViewGroup;]Landroid/view/ViewOverlay;Landroid/view/ViewGroupOverlay;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/Iterator;Ljava/util/concurrent/CopyOnWriteArrayList$COWIterator;]Ljava/util/List;Ljava/util/Collections$EmptyList;]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;
+HSPLandroid/view/View;->dispatchDetachedFromWindow()V+]Landroid/view/View;missing_types]Ljava/util/List;Ljava/util/Collections$EmptyList;]Landroid/view/ImeFocusController;Landroid/view/ImeFocusController;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/View;->dispatchDraw(Landroid/graphics/Canvas;)V
 HSPLandroid/view/View;->dispatchDrawableHotspotChanged(FF)V
 HSPLandroid/view/View;->dispatchFinishTemporaryDetach()V
@@ -17061,7 +17137,7 @@
 HSPLandroid/view/View;->dispatchProvideContentCaptureStructure()V
 HSPLandroid/view/View;->dispatchProvideStructure(Landroid/view/ViewStructure;II)V
 HSPLandroid/view/View;->dispatchRestoreInstanceState(Landroid/util/SparseArray;)V
-HSPLandroid/view/View;->dispatchSaveInstanceState(Landroid/util/SparseArray;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/view/View;->dispatchSaveInstanceState(Landroid/util/SparseArray;)V
 HSPLandroid/view/View;->dispatchScreenStateChanged(I)V
 HSPLandroid/view/View;->dispatchSetActivated(Z)V
 HSPLandroid/view/View;->dispatchSetPressed(Z)V
@@ -17070,18 +17146,18 @@
 HSPLandroid/view/View;->dispatchSystemUiVisibilityChanged(I)V
 HSPLandroid/view/View;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z
 HSPLandroid/view/View;->dispatchVisibilityAggregated(Z)Z+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->dispatchVisibilityChanged(Landroid/view/View;I)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->dispatchVisibilityChanged(Landroid/view/View;I)V
 HSPLandroid/view/View;->dispatchWindowFocusChanged(Z)V
 HSPLandroid/view/View;->dispatchWindowInsetsAnimationEnd(Landroid/view/WindowInsetsAnimation;)V
 HSPLandroid/view/View;->dispatchWindowSystemUiVisiblityChanged(I)V
-HSPLandroid/view/View;->dispatchWindowVisibilityChanged(I)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->dispatchWindowVisibilityChanged(I)V
 HSPLandroid/view/View;->draw(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->draw(Landroid/graphics/Canvas;Landroid/view/ViewGroup;J)Z+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/AnimationSet;,Landroid/view/animation/RotateAnimation;]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;
-HSPLandroid/view/View;->drawAutofilledHighlight(Landroid/graphics/Canvas;)V
-HSPLandroid/view/View;->drawBackground(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->draw(Landroid/graphics/Canvas;Landroid/view/ViewGroup;J)Z+]Landroid/view/View;missing_types]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/view/ViewGroup;Landroid/widget/FrameLayout;]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;]Landroid/view/animation/Animation;Landroid/view/animation/TranslateAnimation;,Landroid/view/animation/AlphaAnimation;
+HSPLandroid/view/View;->drawAutofilledHighlight(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->drawBackground(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/view/View;->drawDefaultFocusHighlight(Landroid/graphics/Canvas;)V
 HSPLandroid/view/View;->drawableHotspotChanged(FF)V
-HSPLandroid/view/View;->drawableStateChanged()V+]Landroid/animation/StateListAnimator;Landroid/animation/StateListAnimator;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types
+HSPLandroid/view/View;->drawableStateChanged()V+]Landroid/animation/StateListAnimator;Landroid/animation/StateListAnimator;]Landroid/view/View;missing_types]Landroid/graphics/drawable/Drawable;Landroid/widget/ScrollBarDrawable;,Landroid/graphics/drawable/RippleDrawable;,Landroid/graphics/drawable/InsetDrawable;,Landroid/graphics/drawable/StateListDrawable;,Landroid/graphics/drawable/ColorDrawable;
 HSPLandroid/view/View;->drawsWithRenderNode(Landroid/graphics/Canvas;)Z+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/view/View;->ensureTransformationInfo()V
 HSPLandroid/view/View;->findAccessibilityFocusHost(Z)Landroid/view/View;
@@ -17091,7 +17167,7 @@
 HSPLandroid/view/View;->findOnBackInvokedDispatcher()Landroid/window/OnBackInvokedDispatcher;
 HSPLandroid/view/View;->findUserSetNextFocus(Landroid/view/View;I)Landroid/view/View;
 HSPLandroid/view/View;->findViewByAutofillIdTraversal(I)Landroid/view/View;
-HSPLandroid/view/View;->findViewById(I)Landroid/view/View;+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->findViewById(I)Landroid/view/View;
 HSPLandroid/view/View;->findViewTraversal(I)Landroid/view/View;
 HSPLandroid/view/View;->findViewWithTag(Ljava/lang/Object;)Landroid/view/View;
 HSPLandroid/view/View;->findViewWithTagTraversal(Ljava/lang/Object;)Landroid/view/View;
@@ -17126,7 +17202,7 @@
 HSPLandroid/view/View;->getContext()Landroid/content/Context;
 HSPLandroid/view/View;->getDefaultSize(II)I
 HSPLandroid/view/View;->getDisplay()Landroid/view/Display;
-HSPLandroid/view/View;->getDrawableRenderNode(Landroid/graphics/drawable/Drawable;Landroid/graphics/RenderNode;)Landroid/graphics/RenderNode;+]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/drawable/Drawable;missing_types]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;missing_types
+HSPLandroid/view/View;->getDrawableRenderNode(Landroid/graphics/drawable/Drawable;Landroid/graphics/RenderNode;)Landroid/graphics/RenderNode;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/Drawable;missing_types]Ljava/lang/Object;missing_types]Ljava/lang/Class;Ljava/lang/Class;
 HSPLandroid/view/View;->getDrawableState()[I+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->getDrawingCache(Z)Landroid/graphics/Bitmap;
 HSPLandroid/view/View;->getDrawingRect(Landroid/graphics/Rect;)V
@@ -17156,16 +17232,16 @@
 HSPLandroid/view/View;->getInverseMatrix()Landroid/graphics/Matrix;
 HSPLandroid/view/View;->getKeyDispatcherState()Landroid/view/KeyEvent$DispatcherState;
 HSPLandroid/view/View;->getLayerType()I
-HSPLandroid/view/View;->getLayoutDirection()I+]Landroid/content/Context;missing_types]Landroid/view/View;missing_types
+HSPLandroid/view/View;->getLayoutDirection()I+]Landroid/view/View;missing_types]Landroid/content/Context;missing_types
 HSPLandroid/view/View;->getLayoutParams()Landroid/view/ViewGroup$LayoutParams;
 HSPLandroid/view/View;->getLeft()I
 HSPLandroid/view/View;->getListenerInfo()Landroid/view/View$ListenerInfo;
 HSPLandroid/view/View;->getLocalVisibleRect(Landroid/graphics/Rect;)Z
 HSPLandroid/view/View;->getLocationInSurface([I)V
-HSPLandroid/view/View;->getLocationInWindow([I)V
+HSPLandroid/view/View;->getLocationInWindow([I)V+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->getLocationOnScreen()[I
-HSPLandroid/view/View;->getLocationOnScreen([I)V
-HSPLandroid/view/View;->getMatrix()Landroid/graphics/Matrix;
+HSPLandroid/view/View;->getLocationOnScreen([I)V+]Landroid/view/View;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/View;->getMatrix()Landroid/graphics/Matrix;+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->getMeasuredHeight()I
 HSPLandroid/view/View;->getMeasuredState()I
 HSPLandroid/view/View;->getMeasuredWidth()I
@@ -17177,9 +17253,9 @@
 HSPLandroid/view/View;->getOverScrollMode()I
 HSPLandroid/view/View;->getPaddingBottom()I
 HSPLandroid/view/View;->getPaddingEnd()I
-HSPLandroid/view/View;->getPaddingLeft()I+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->getPaddingLeft()I
 HSPLandroid/view/View;->getPaddingRight()I
-HSPLandroid/view/View;->getPaddingStart()I+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->getPaddingStart()I
 HSPLandroid/view/View;->getPaddingTop()I
 HSPLandroid/view/View;->getParent()Landroid/view/ViewParent;
 HSPLandroid/view/View;->getPivotX()F
@@ -17197,8 +17273,8 @@
 HSPLandroid/view/View;->getRotationX()F
 HSPLandroid/view/View;->getRotationY()F
 HSPLandroid/view/View;->getRunQueue()Landroid/view/HandlerActionQueue;
-HSPLandroid/view/View;->getScaleX()F
-HSPLandroid/view/View;->getScaleY()F
+HSPLandroid/view/View;->getScaleX()F+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->getScaleY()F+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->getScrollX()I
 HSPLandroid/view/View;->getScrollY()I
 HSPLandroid/view/View;->getSolidColor()I
@@ -17217,7 +17293,7 @@
 HSPLandroid/view/View;->getTransitionAlpha()F
 HSPLandroid/view/View;->getTransitionName()Ljava/lang/String;
 HSPLandroid/view/View;->getTranslationX()F
-HSPLandroid/view/View;->getTranslationY()F
+HSPLandroid/view/View;->getTranslationY()F+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->getTranslationZ()F
 HSPLandroid/view/View;->getVerticalFadingEdgeLength()I
 HSPLandroid/view/View;->getVerticalScrollbarWidth()I+]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;
@@ -17228,11 +17304,11 @@
 HSPLandroid/view/View;->getWidth()I
 HSPLandroid/view/View;->getWindowAttachCount()I
 HSPLandroid/view/View;->getWindowId()Landroid/view/WindowId;
-HSPLandroid/view/View;->getWindowInsetsController()Landroid/view/WindowInsetsController;
+HSPLandroid/view/View;->getWindowInsetsController()Landroid/view/WindowInsetsController;+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
 HSPLandroid/view/View;->getWindowSystemUiVisibility()I
 HSPLandroid/view/View;->getWindowToken()Landroid/os/IBinder;
 HSPLandroid/view/View;->getWindowVisibility()I
-HSPLandroid/view/View;->getWindowVisibleDisplayFrame(Landroid/graphics/Rect;)V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/View;->getWindowVisibleDisplayFrame(Landroid/graphics/Rect;)V
 HSPLandroid/view/View;->getX()F
 HSPLandroid/view/View;->getY()F
 HSPLandroid/view/View;->getZ()F
@@ -17250,7 +17326,7 @@
 HSPLandroid/view/View;->hasNestedScrollingParent()Z
 HSPLandroid/view/View;->hasOnClickListeners()Z
 HSPLandroid/view/View;->hasOverlappingRendering()Z
-HSPLandroid/view/View;->hasRtlSupport()Z+]Landroid/content/Context;missing_types]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;
+HSPLandroid/view/View;->hasRtlSupport()Z
 HSPLandroid/view/View;->hasSize()Z
 HSPLandroid/view/View;->hasTransientState()Z
 HSPLandroid/view/View;->hasTranslationTransientState()Z
@@ -17263,22 +17339,22 @@
 HSPLandroid/view/View;->includeForAccessibility(Z)Z
 HSPLandroid/view/View;->inflate(Landroid/content/Context;ILandroid/view/ViewGroup;)Landroid/view/View;
 HSPLandroid/view/View;->initScrollCache()V
-HSPLandroid/view/View;->initialAwakenScrollBars()Z+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->initialAwakenScrollBars()Z+]Landroid/view/View;Landroid/widget/ScrollView;
 HSPLandroid/view/View;->initializeFadingEdgeInternal(Landroid/content/res/TypedArray;)V
 HSPLandroid/view/View;->initializeScrollIndicatorsInternal()V
 HSPLandroid/view/View;->initializeScrollbarsInternal(Landroid/content/res/TypedArray;)V
-HSPLandroid/view/View;->internalSetPadding(IIII)V+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->invalidate()V
+HSPLandroid/view/View;->internalSetPadding(IIII)V
+HSPLandroid/view/View;->invalidate()V+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->invalidate(IIII)V+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->invalidate(Landroid/graphics/Rect;)V
+HSPLandroid/view/View;->invalidate(Landroid/graphics/Rect;)V+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->invalidate(Z)V+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types
-HSPLandroid/view/View;->invalidateInternal(IIIIZZ)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
-HSPLandroid/view/View;->invalidateOutline()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/view/View;missing_types]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/view/View;->invalidateInternal(IIIIZZ)V+]Landroid/view/View;megamorphic_types]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewParent;missing_types]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/view/View;->invalidateOutline()V
 HSPLandroid/view/View;->invalidateParentCaches()V
 HSPLandroid/view/View;->invalidateParentIfNeeded()V
 HSPLandroid/view/View;->invalidateParentIfNeededAndWasQuickRejected()V
-HSPLandroid/view/View;->invalidateViewProperty(ZZ)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->invalidateViewProperty(ZZ)V
 HSPLandroid/view/View;->isAccessibilityFocused()Z
 HSPLandroid/view/View;->isAccessibilityFocusedViewOrHost()Z
 HSPLandroid/view/View;->isAccessibilityPane()Z
@@ -17313,7 +17389,7 @@
 HSPLandroid/view/View;->isInTouchMode()Z
 HSPLandroid/view/View;->isKeyboardNavigationCluster()Z
 HSPLandroid/view/View;->isLaidOut()Z
-HSPLandroid/view/View;->isLayoutDirectionInherited()Z+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->isLayoutDirectionInherited()Z
 HSPLandroid/view/View;->isLayoutDirectionResolved()Z
 HSPLandroid/view/View;->isLayoutModeOptical(Ljava/lang/Object;)Z+]Landroid/view/ViewGroup;missing_types
 HSPLandroid/view/View;->isLayoutRequested()Z
@@ -17326,7 +17402,7 @@
 HSPLandroid/view/View;->isPressed()Z
 HSPLandroid/view/View;->isProjectionReceiver()Z
 HSPLandroid/view/View;->isRootNamespace()Z
-HSPLandroid/view/View;->isRtlCompatibilityMode()Z+]Landroid/content/Context;missing_types]Landroid/view/View;missing_types
+HSPLandroid/view/View;->isRtlCompatibilityMode()Z
 HSPLandroid/view/View;->isSelected()Z
 HSPLandroid/view/View;->isShowingLayoutBounds()Z
 HSPLandroid/view/View;->isShown()Z
@@ -17342,44 +17418,44 @@
 HSPLandroid/view/View;->isViewIdGenerated(I)Z
 HSPLandroid/view/View;->isVisibleToUser()Z
 HSPLandroid/view/View;->isVisibleToUser(Landroid/graphics/Rect;)Z
-HSPLandroid/view/View;->jumpDrawablesToCurrentState()V+]Landroid/animation/StateListAnimator;Landroid/animation/StateListAnimator;]Landroid/graphics/drawable/Drawable;missing_types
-HSPLandroid/view/View;->layout(IIII)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->jumpDrawablesToCurrentState()V
+HSPLandroid/view/View;->layout(IIII)V+]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/View;->makeFrameworkOptionalFitsSystemWindows()V
 HSPLandroid/view/View;->makeOptionalFitsSystemWindows()V
 HSPLandroid/view/View;->mapRectFromViewToScreenCoords(Landroid/graphics/RectF;Z)V
 HSPLandroid/view/View;->mapRectFromViewToWindowCoords(Landroid/graphics/RectF;Z)V
-HSPLandroid/view/View;->measure(II)V+]Landroid/util/LongSparseLongArray;Landroid/util/LongSparseLongArray;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->measure(II)V+]Landroid/view/View;megamorphic_types]Landroid/util/LongSparseLongArray;Landroid/util/LongSparseLongArray;
 HSPLandroid/view/View;->mergeDrawableStates([I[I)[I
 HSPLandroid/view/View;->needGlobalAttributesUpdate(Z)V
 HSPLandroid/view/View;->needRtlPropertiesResolution()Z
 HSPLandroid/view/View;->notifyAppearedOrDisappearedForContentCaptureIfNeeded(Z)V
 HSPLandroid/view/View;->notifyAutofillManagerOnClick()V
-HSPLandroid/view/View;->notifyEnterOrExitForAutoFillIfNeeded(Z)V+]Landroid/view/View;missing_types]Landroid/view/autofill/AutofillManager;Landroid/view/autofill/AutofillManager;
+HSPLandroid/view/View;->notifyEnterOrExitForAutoFillIfNeeded(Z)V
 HSPLandroid/view/View;->notifyGlobalFocusCleared(Landroid/view/View;)V
 HSPLandroid/view/View;->notifySubtreeAccessibilityStateChangedByParentIfNeeded()V
-HSPLandroid/view/View;->notifySubtreeAccessibilityStateChangedIfNeeded()V+]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;
-HSPLandroid/view/View;->notifyViewAccessibilityStateChangedIfNeeded(I)V+]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;
+HSPLandroid/view/View;->notifySubtreeAccessibilityStateChangedIfNeeded()V
+HSPLandroid/view/View;->notifyViewAccessibilityStateChangedIfNeeded(I)V
 HSPLandroid/view/View;->offsetLeftAndRight(I)V
 HSPLandroid/view/View;->offsetTopAndBottom(I)V
 HSPLandroid/view/View;->onAnimationEnd()V
 HSPLandroid/view/View;->onAnimationStart()V
 HSPLandroid/view/View;->onApplyFrameworkOptionalFitSystemWindows(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
 HSPLandroid/view/View;->onApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
-HSPLandroid/view/View;->onAttachedToWindow()V+]Landroid/view/View;missing_types]Landroid/view/accessibility/AccessibilityNodeIdManager;Landroid/view/accessibility/AccessibilityNodeIdManager;
-HSPLandroid/view/View;->onCancelPendingInputEvents()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->onAttachedToWindow()V+]Landroid/view/accessibility/AccessibilityNodeIdManager;Landroid/view/accessibility/AccessibilityNodeIdManager;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->onCancelPendingInputEvents()V
 HSPLandroid/view/View;->onCheckIsTextEditor()Z
 HSPLandroid/view/View;->onCloseSystemDialogs(Ljava/lang/String;)V
 HSPLandroid/view/View;->onConfigurationChanged(Landroid/content/res/Configuration;)V
 HSPLandroid/view/View;->onCreateDrawableState(I)[I+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->onCreateInputConnection(Landroid/view/inputmethod/EditorInfo;)Landroid/view/inputmethod/InputConnection;
 HSPLandroid/view/View;->onDetachedFromWindow()V
-HSPLandroid/view/View;->onDetachedFromWindowInternal()V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types]Landroid/view/accessibility/AccessibilityNodeIdManager;Landroid/view/accessibility/AccessibilityNodeIdManager;
+HSPLandroid/view/View;->onDetachedFromWindowInternal()V+]Landroid/view/accessibility/AccessibilityNodeIdManager;Landroid/view/accessibility/AccessibilityNodeIdManager;]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->onDraw(Landroid/graphics/Canvas;)V
 HSPLandroid/view/View;->onDrawForeground(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->onDrawHorizontalScrollBar(Landroid/graphics/Canvas;Landroid/graphics/drawable/Drawable;IIII)V
-HSPLandroid/view/View;->onDrawScrollBars(Landroid/graphics/Canvas;)V
+HSPLandroid/view/View;->onDrawScrollBars(Landroid/graphics/Canvas;)V+]Landroid/graphics/Interpolator;Landroid/graphics/Interpolator;]Landroid/view/View;missing_types]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;
 HSPLandroid/view/View;->onDrawScrollIndicators(Landroid/graphics/Canvas;)V
-HSPLandroid/view/View;->onDrawVerticalScrollBar(Landroid/graphics/Canvas;Landroid/graphics/drawable/Drawable;IIII)V
+HSPLandroid/view/View;->onDrawVerticalScrollBar(Landroid/graphics/Canvas;Landroid/graphics/drawable/Drawable;IIII)V+]Landroid/graphics/drawable/Drawable;Landroid/widget/ScrollBarDrawable;
 HSPLandroid/view/View;->onFilterTouchEventForSecurity(Landroid/view/MotionEvent;)Z
 HSPLandroid/view/View;->onFinishInflate()V
 HSPLandroid/view/View;->onFinishTemporaryDetach()V
@@ -17389,7 +17465,7 @@
 HSPLandroid/view/View;->onKeyPreIme(ILandroid/view/KeyEvent;)Z
 HSPLandroid/view/View;->onKeyUp(ILandroid/view/KeyEvent;)Z
 HSPLandroid/view/View;->onLayout(ZIIII)V
-HSPLandroid/view/View;->onMeasure(II)V+]Landroid/view/View;Landroid/view/View;
+HSPLandroid/view/View;->onMeasure(II)V+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->onProvideAutofillStructure(Landroid/view/ViewStructure;I)V
 HSPLandroid/view/View;->onProvideAutofillVirtualStructure(Landroid/view/ViewStructure;I)V
 HSPLandroid/view/View;->onProvideContentCaptureStructure(Landroid/view/ViewStructure;I)V
@@ -17399,14 +17475,14 @@
 HSPLandroid/view/View;->onRtlPropertiesChanged(I)V
 HSPLandroid/view/View;->onSaveInstanceState()Landroid/os/Parcelable;
 HSPLandroid/view/View;->onScreenStateChanged(I)V
-HSPLandroid/view/View;->onScrollChanged(IIII)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->onScrollChanged(IIII)V
 HSPLandroid/view/View;->onSetAlpha(I)Z
 HSPLandroid/view/View;->onSizeChanged(IIII)V
 HSPLandroid/view/View;->onStartTemporaryDetach()V
 HSPLandroid/view/View;->onTouchEvent(Landroid/view/MotionEvent;)Z
-HSPLandroid/view/View;->onVisibilityAggregated(Z)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types]Ljava/util/List;Ljava/util/Collections$EmptyList;
+HSPLandroid/view/View;->onVisibilityAggregated(Z)V+]Landroid/view/View;megamorphic_types]Ljava/util/List;Ljava/util/Collections$EmptyList;,Ljava/util/ArrayList;]Landroid/graphics/drawable/Drawable;missing_types
 HSPLandroid/view/View;->onVisibilityChanged(Landroid/view/View;I)V
-HSPLandroid/view/View;->onWindowFocusChanged(Z)V+]Landroid/view/View;megamorphic_types
+HSPLandroid/view/View;->onWindowFocusChanged(Z)V
 HSPLandroid/view/View;->onWindowSystemUiVisibilityChanged(I)V
 HSPLandroid/view/View;->onWindowVisibilityChanged(I)V
 HSPLandroid/view/View;->overScrollBy(IIIIIIIIZ)Z
@@ -17430,9 +17506,9 @@
 HSPLandroid/view/View;->postOnAnimationDelayed(Ljava/lang/Runnable;J)V
 HSPLandroid/view/View;->postSendViewScrolledAccessibilityEventCallback(II)V
 HSPLandroid/view/View;->postUpdate(Ljava/lang/Runnable;)V
-HSPLandroid/view/View;->rebuildOutline()V+]Landroid/graphics/Outline;Landroid/graphics/Outline;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/ViewOutlineProvider;missing_types
+HSPLandroid/view/View;->rebuildOutline()V+]Landroid/view/ViewOutlineProvider;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/Outline;Landroid/graphics/Outline;
 HSPLandroid/view/View;->recomputePadding()V
-HSPLandroid/view/View;->refreshDrawableState()V+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
+HSPLandroid/view/View;->refreshDrawableState()V
 HSPLandroid/view/View;->registerPendingFrameMetricsObservers()V
 HSPLandroid/view/View;->removeCallbacks(Ljava/lang/Runnable;)Z
 HSPLandroid/view/View;->removeFrameMetricsListener(Landroid/view/Window$OnFrameMetricsAvailableListener;)V
@@ -17448,30 +17524,30 @@
 HSPLandroid/view/View;->requestFocus(I)Z
 HSPLandroid/view/View;->requestFocus(ILandroid/graphics/Rect;)Z
 HSPLandroid/view/View;->requestFocusNoSearch(ILandroid/graphics/Rect;)Z
-HSPLandroid/view/View;->requestLayout()V+]Landroid/util/LongSparseLongArray;Landroid/util/LongSparseLongArray;]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/View;->requestLayout()V+]Landroid/view/View;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/util/LongSparseLongArray;Landroid/util/LongSparseLongArray;]Landroid/view/ViewParent;missing_types
 HSPLandroid/view/View;->requestRectangleOnScreen(Landroid/graphics/Rect;)Z
 HSPLandroid/view/View;->requestRectangleOnScreen(Landroid/graphics/Rect;Z)Z
 HSPLandroid/view/View;->requireViewById(I)Landroid/view/View;
-HSPLandroid/view/View;->resetDisplayList()V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->resetDisplayList()V
 HSPLandroid/view/View;->resetPressedState()V
-HSPLandroid/view/View;->resetResolvedDrawables()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->resetResolvedDrawables()V
 HSPLandroid/view/View;->resetResolvedDrawablesInternal()V
 HSPLandroid/view/View;->resetResolvedLayoutDirection()V
-HSPLandroid/view/View;->resetResolvedPadding()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->resetResolvedPadding()V
 HSPLandroid/view/View;->resetResolvedPaddingInternal()V
 HSPLandroid/view/View;->resetResolvedTextAlignment()V
 HSPLandroid/view/View;->resetResolvedTextDirection()V
-HSPLandroid/view/View;->resetRtlProperties()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->resetRtlProperties()V
 HSPLandroid/view/View;->resetSubtreeAccessibilityStateChanged()V
-HSPLandroid/view/View;->resolveDrawables()V+]Landroid/graphics/drawable/Drawable;megamorphic_types]Landroid/view/View;missing_types
-HSPLandroid/view/View;->resolveLayoutDirection()Z+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
+HSPLandroid/view/View;->resolveDrawables()V
+HSPLandroid/view/View;->resolveLayoutDirection()Z
 HSPLandroid/view/View;->resolveLayoutParams()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup$LayoutParams;missing_types
-HSPLandroid/view/View;->resolvePadding()V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;
+HSPLandroid/view/View;->resolvePadding()V+]Landroid/view/View;missing_types]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/InsetDrawable;,Landroid/graphics/drawable/RippleDrawable;,Landroid/graphics/drawable/ColorDrawable;
 HSPLandroid/view/View;->resolveRtlPropertiesIfNeeded()Z+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->resolveSize(II)I
 HSPLandroid/view/View;->resolveSizeAndState(III)I
-HSPLandroid/view/View;->resolveTextAlignment()Z+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->resolveTextDirection()Z+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
+HSPLandroid/view/View;->resolveTextAlignment()Z
+HSPLandroid/view/View;->resolveTextDirection()Z
 HSPLandroid/view/View;->restoreHierarchyState(Landroid/util/SparseArray;)V
 HSPLandroid/view/View;->retrieveExplicitStyle(Landroid/content/res/Resources$Theme;Landroid/util/AttributeSet;)V
 HSPLandroid/view/View;->rootViewRequestFocus()Z
@@ -17493,53 +17569,53 @@
 HSPLandroid/view/View;->setActivated(Z)V
 HSPLandroid/view/View;->setAlpha(F)V
 HSPLandroid/view/View;->setAlphaInternal(F)V
-HSPLandroid/view/View;->setAlphaNoInvalidation(F)Z+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setAlphaNoInvalidation(F)Z
 HSPLandroid/view/View;->setAnimation(Landroid/view/animation/Animation;)V
 HSPLandroid/view/View;->setAutoHandwritingEnabled(Z)V
 HSPLandroid/view/View;->setAutofilled(ZZ)V
 HSPLandroid/view/View;->setBackground(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/view/View;->setBackgroundBounds()V+]Landroid/graphics/drawable/Drawable;missing_types
 HSPLandroid/view/View;->setBackgroundColor(I)V
-HSPLandroid/view/View;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;
+HSPLandroid/view/View;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/view/View;missing_types]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;,Landroid/graphics/drawable/RippleDrawable;,Landroid/graphics/drawable/ColorDrawable;
 HSPLandroid/view/View;->setBackgroundRenderNodeProperties(Landroid/graphics/RenderNode;)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->setBackgroundResource(I)V
 HSPLandroid/view/View;->setBackgroundTintList(Landroid/content/res/ColorStateList;)V
-HSPLandroid/view/View;->setBottom(I)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->setBottom(I)V
 HSPLandroid/view/View;->setClickable(Z)V
 HSPLandroid/view/View;->setClipBounds(Landroid/graphics/Rect;)V
 HSPLandroid/view/View;->setClipToOutline(Z)V
 HSPLandroid/view/View;->setContentDescription(Ljava/lang/CharSequence;)V
 HSPLandroid/view/View;->setDefaultFocusHighlightEnabled(Z)V
 HSPLandroid/view/View;->setDetached(Z)V
-HSPLandroid/view/View;->setDisplayListProperties(Landroid/graphics/RenderNode;)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setDisplayListProperties(Landroid/graphics/RenderNode;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->setDrawingCacheEnabled(Z)V
 HSPLandroid/view/View;->setElevation(F)V
 HSPLandroid/view/View;->setEnabled(Z)V
 HSPLandroid/view/View;->setFitsSystemWindows(Z)V
-HSPLandroid/view/View;->setFlags(II)V+]Landroid/view/View;megamorphic_types]Landroid/view/ViewGroup;missing_types]Landroid/view/ViewParent;missing_types]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;
+HSPLandroid/view/View;->setFlags(II)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/view/ViewParent;missing_types
 HSPLandroid/view/View;->setFocusable(I)V
 HSPLandroid/view/View;->setFocusable(Z)V
 HSPLandroid/view/View;->setFocusableInTouchMode(Z)V
 HSPLandroid/view/View;->setForeground(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/view/View;->setForegroundGravity(I)V
-HSPLandroid/view/View;->setFrame(IIII)Z+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setFrame(IIII)Z+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->setHandwritingArea(Landroid/graphics/Rect;)V
 HSPLandroid/view/View;->setHapticFeedbackEnabled(Z)V
 HSPLandroid/view/View;->setHasTransientState(Z)V
 HSPLandroid/view/View;->setHorizontalFadingEdgeEnabled(Z)V
 HSPLandroid/view/View;->setHorizontalScrollBarEnabled(Z)V
 HSPLandroid/view/View;->setId(I)V
-HSPLandroid/view/View;->setImportantForAccessibility(I)V+]Landroid/view/View;megamorphic_types
+HSPLandroid/view/View;->setImportantForAccessibility(I)V
 HSPLandroid/view/View;->setImportantForAutofill(I)V
 HSPLandroid/view/View;->setImportantForContentCapture(I)V
 HSPLandroid/view/View;->setIsRootNamespace(Z)V
 HSPLandroid/view/View;->setKeepScreenOn(Z)V
 HSPLandroid/view/View;->setKeyboardNavigationCluster(Z)V
-HSPLandroid/view/View;->setKeyedTag(ILjava/lang/Object;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/view/View;->setKeyedTag(ILjava/lang/Object;)V
 HSPLandroid/view/View;->setLayerPaint(Landroid/graphics/Paint;)V
 HSPLandroid/view/View;->setLayerType(ILandroid/graphics/Paint;)V
 HSPLandroid/view/View;->setLayoutDirection(I)V
-HSPLandroid/view/View;->setLayoutParams(Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/View;->setLayoutParams(Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;Lcom/android/internal/policy/DecorView;
 HSPLandroid/view/View;->setLeft(I)V
 HSPLandroid/view/View;->setLeftTopRightBottom(IIII)V
 HSPLandroid/view/View;->setLongClickable(Z)V
@@ -17564,21 +17640,21 @@
 HSPLandroid/view/View;->setOutlineProviderFromAttribute(I)V
 HSPLandroid/view/View;->setOutlineSpotShadowColor(I)V
 HSPLandroid/view/View;->setOverScrollMode(I)V
-HSPLandroid/view/View;->setPadding(IIII)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->setPadding(IIII)V
 HSPLandroid/view/View;->setPaddingRelative(IIII)V
 HSPLandroid/view/View;->setPivotX(F)V
 HSPLandroid/view/View;->setPivotY(F)V
 HSPLandroid/view/View;->setPointerIcon(Landroid/view/PointerIcon;)V
 HSPLandroid/view/View;->setPressed(Z)V
 HSPLandroid/view/View;->setRenderEffect(Landroid/graphics/RenderEffect;)V
-HSPLandroid/view/View;->setRight(I)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setRight(I)V
 HSPLandroid/view/View;->setRotation(F)V
 HSPLandroid/view/View;->setRotationX(F)V
 HSPLandroid/view/View;->setRotationY(F)V
 HSPLandroid/view/View;->setSaveEnabled(Z)V
 HSPLandroid/view/View;->setSaveFromParentEnabled(Z)V
-HSPLandroid/view/View;->setScaleX(F)V
-HSPLandroid/view/View;->setScaleY(F)V
+HSPLandroid/view/View;->setScaleX(F)V+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setScaleY(F)V+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->setScrollContainer(Z)V
 HSPLandroid/view/View;->setScrollIndicators(II)V
 HSPLandroid/view/View;->setScrollX(I)V
@@ -17601,40 +17677,41 @@
 HSPLandroid/view/View;->setTransitionVisibility(I)V
 HSPLandroid/view/View;->setTranslationX(F)V
 HSPLandroid/view/View;->setTranslationY(F)V
-HSPLandroid/view/View;->setTranslationZ(F)V
+HSPLandroid/view/View;->setTranslationZ(F)V+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->setVerticalScrollBarEnabled(Z)V
-HSPLandroid/view/View;->setVisibility(I)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->setVisibility(I)V
 HSPLandroid/view/View;->setWillNotDraw(Z)V
 HSPLandroid/view/View;->setX(F)V
 HSPLandroid/view/View;->setY(F)V
-HSPLandroid/view/View;->shouldDrawRoundScrollbar()Z+]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/Resources;Landroid/content/res/Resources;
-HSPLandroid/view/View;->sizeChange(IIII)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/ViewOverlay;Landroid/view/ViewGroupOverlay;
+HSPLandroid/view/View;->shouldDrawRoundScrollbar()Z+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;
+HSPLandroid/view/View;->sizeChange(IIII)V
 HSPLandroid/view/View;->skipInvalidate()Z+]Landroid/view/ViewGroup;missing_types
 HSPLandroid/view/View;->startAnimation(Landroid/view/animation/Animation;)V
 HSPLandroid/view/View;->startNestedScroll(I)Z
 HSPLandroid/view/View;->stopNestedScroll()V
 HSPLandroid/view/View;->switchDefaultFocusHighlight()V
 HSPLandroid/view/View;->toString()Ljava/lang/String;
-HSPLandroid/view/View;->transformFromViewToWindowSpace([I)V
+HSPLandroid/view/View;->transformFromViewToWindowSpace([I)V+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->unFocus(Landroid/view/View;)V
-HSPLandroid/view/View;->unscheduleDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
+HSPLandroid/view/View;->unscheduleDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/view/View;->unscheduleDrawable(Landroid/graphics/drawable/Drawable;Ljava/lang/Runnable;)V
-HSPLandroid/view/View;->updateDisplayListIfDirty()Landroid/graphics/RenderNode;+]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;Landroid/view/ViewOverlay$OverlayViewGroup;]Landroid/view/ViewOverlay;Landroid/view/ViewGroupOverlay;
+HSPLandroid/view/View;->updateDisplayListIfDirty()Landroid/graphics/RenderNode;+]Landroid/view/View;megamorphic_types]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->updateFocusedInCluster(Landroid/view/View;I)V
 HSPLandroid/view/View;->updateHandwritingArea()V
 HSPLandroid/view/View;->updateKeepClearRects()V
 HSPLandroid/view/View;->updateLocalSystemUiVisibility(II)Z
 HSPLandroid/view/View;->updatePflags3AndNotifyA11yIfChanged(IZ)V
-HSPLandroid/view/View;->updatePositionUpdateListener()V+]Landroid/view/View;missing_types]Ljava/util/List;Ljava/util/Collections$EmptyList;
+HSPLandroid/view/View;->updatePositionUpdateListener()V
 HSPLandroid/view/View;->updatePreferKeepClearForFocus()V
 HSPLandroid/view/View;->updateSystemGestureExclusionRects()V
 HSPLandroid/view/View;->verifyDrawable(Landroid/graphics/drawable/Drawable;)Z
 HSPLandroid/view/View;->willNotDraw()Z
 HSPLandroid/view/ViewAnimationHostBridge;-><init>(Landroid/view/View;)V
 HSPLandroid/view/ViewAnimationHostBridge;->isAttached()Z
+HSPLandroid/view/ViewAnimationHostBridge;->registerAnimatingRenderNode(Landroid/graphics/RenderNode;)V
 HSPLandroid/view/ViewAnimationHostBridge;->registerVectorDrawableAnimator(Landroid/view/NativeVectorDrawableAnimator;)V
 HSPLandroid/view/ViewConfiguration;-><init>(Landroid/content/Context;)V
-HSPLandroid/view/ViewConfiguration;->get(Landroid/content/Context;)Landroid/view/ViewConfiguration;+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/view/ViewConfiguration;->get(Landroid/content/Context;)Landroid/view/ViewConfiguration;
 HSPLandroid/view/ViewConfiguration;->getDoubleTapTimeout()I
 HSPLandroid/view/ViewConfiguration;->getLongPressTimeout()I
 HSPLandroid/view/ViewConfiguration;->getPressedStateDuration()I
@@ -17681,9 +17758,9 @@
 HSPLandroid/view/ViewGroup$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/view/ViewGroup$LayoutParams;-><init>(Landroid/view/ViewGroup$LayoutParams;)V
 HSPLandroid/view/ViewGroup$LayoutParams;->resolveLayoutDirection(I)V
-HSPLandroid/view/ViewGroup$LayoutParams;->setBaseAttributes(Landroid/content/res/TypedArray;II)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
+HSPLandroid/view/ViewGroup$LayoutParams;->setBaseAttributes(Landroid/content/res/TypedArray;II)V
 HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(II)V
-HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/Context;missing_types]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/view/ViewGroup$MarginLayoutParams;missing_types
+HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/view/ViewGroup$MarginLayoutParams;missing_types]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
 HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(Landroid/view/ViewGroup$LayoutParams;)V
 HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(Landroid/view/ViewGroup$MarginLayoutParams;)V
 HSPLandroid/view/ViewGroup$MarginLayoutParams;->doResolveMargins()V
@@ -17709,12 +17786,12 @@
 HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;I)V
 HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;II)V
-HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V
 HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
 HSPLandroid/view/ViewGroup;->addViewInLayout(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)Z
 HSPLandroid/view/ViewGroup;->addViewInLayout(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;Z)Z
-HSPLandroid/view/ViewGroup;->addViewInner(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;Z)V+]Landroid/animation/LayoutTransition;Landroid/animation/LayoutTransition;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->attachViewToParent(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->addViewInner(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;Z)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->attachViewToParent(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V
 HSPLandroid/view/ViewGroup;->bringChildToFront(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->buildOrderedChildList()Ljava/util/ArrayList;
 HSPLandroid/view/ViewGroup;->buildTouchDispatchChildList()Ljava/util/ArrayList;
@@ -17731,20 +17808,20 @@
 HSPLandroid/view/ViewGroup;->clearFocus()V
 HSPLandroid/view/ViewGroup;->clearFocusedInCluster()V
 HSPLandroid/view/ViewGroup;->clearTouchTargets()V
-HSPLandroid/view/ViewGroup;->destroyHardwareResources()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->destroyHardwareResources()V
 HSPLandroid/view/ViewGroup;->detachAllViewsFromParent()V
 HSPLandroid/view/ViewGroup;->detachViewFromParent(I)V
 HSPLandroid/view/ViewGroup;->dispatchApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
-HSPLandroid/view/ViewGroup;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->dispatchCancelPendingInputEvents()V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V
+HSPLandroid/view/ViewGroup;->dispatchCancelPendingInputEvents()V
 HSPLandroid/view/ViewGroup;->dispatchCollectViewAttributes(Landroid/view/View$AttachInfo;I)V+]Landroid/view/View;missing_types
 HSPLandroid/view/ViewGroup;->dispatchConfigurationChanged(Landroid/content/res/Configuration;)V
 HSPLandroid/view/ViewGroup;->dispatchDetachedFromWindow()V
-HSPLandroid/view/ViewGroup;->dispatchDraw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/animation/LayoutAnimationController;Landroid/view/animation/LayoutAnimationController;
+HSPLandroid/view/ViewGroup;->dispatchDraw(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/view/ViewGroup;->dispatchDrawableHotspotChanged(FF)V
 HSPLandroid/view/ViewGroup;->dispatchFinishTemporaryDetach()V
 HSPLandroid/view/ViewGroup;->dispatchFreezeSelfOnly(Landroid/util/SparseArray;)V
-HSPLandroid/view/ViewGroup;->dispatchGetDisplayList()V+]Landroid/view/View;missing_types]Landroid/view/ViewOverlay;Landroid/view/ViewGroupOverlay;
+HSPLandroid/view/ViewGroup;->dispatchGetDisplayList()V+]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/ViewGroup;->dispatchKeyEvent(Landroid/view/KeyEvent;)Z
 HSPLandroid/view/ViewGroup;->dispatchKeyEventPreIme(Landroid/view/KeyEvent;)Z
 HSPLandroid/view/ViewGroup;->dispatchProvideAutofillStructure(Landroid/view/ViewStructure;I)V
@@ -17758,17 +17835,17 @@
 HSPLandroid/view/ViewGroup;->dispatchStartTemporaryDetach()V
 HSPLandroid/view/ViewGroup;->dispatchSystemUiVisibilityChanged(I)V
 HSPLandroid/view/ViewGroup;->dispatchThawSelfOnly(Landroid/util/SparseArray;)V
-HSPLandroid/view/ViewGroup;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/view/ViewGroup;->dispatchTransformedTouchEvent(Landroid/view/MotionEvent;ZLandroid/view/View;I)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z+]Landroid/view/ViewGroup$TouchTarget;Landroid/view/ViewGroup$TouchTarget;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
+HSPLandroid/view/ViewGroup;->dispatchTransformedTouchEvent(Landroid/view/MotionEvent;ZLandroid/view/View;I)Z+]Landroid/view/View;missing_types]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
 HSPLandroid/view/ViewGroup;->dispatchUnhandledKeyEvent(Landroid/view/KeyEvent;)Landroid/view/View;
-HSPLandroid/view/ViewGroup;->dispatchViewAdded(Landroid/view/View;)V+]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->dispatchViewAdded(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->dispatchViewRemoved(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->dispatchVisibilityAggregated(Z)Z+]Landroid/view/View;missing_types
-HSPLandroid/view/ViewGroup;->dispatchVisibilityChanged(Landroid/view/View;I)V+]Landroid/view/View;missing_types
-HSPLandroid/view/ViewGroup;->dispatchWindowFocusChanged(Z)V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->dispatchVisibilityChanged(Landroid/view/View;I)V
+HSPLandroid/view/ViewGroup;->dispatchWindowFocusChanged(Z)V
 HSPLandroid/view/ViewGroup;->dispatchWindowInsetsAnimationEnd(Landroid/view/WindowInsetsAnimation;)V
 HSPLandroid/view/ViewGroup;->dispatchWindowSystemUiVisiblityChanged(I)V
-HSPLandroid/view/ViewGroup;->dispatchWindowVisibilityChanged(I)V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->dispatchWindowVisibilityChanged(I)V
 HSPLandroid/view/ViewGroup;->drawChild(Landroid/graphics/Canvas;Landroid/view/View;J)Z+]Landroid/view/View;missing_types
 HSPLandroid/view/ViewGroup;->drawableStateChanged()V
 HSPLandroid/view/ViewGroup;->endViewTransition(Landroid/view/View;)V
@@ -17778,7 +17855,7 @@
 HSPLandroid/view/ViewGroup;->findOnBackInvokedDispatcherForChild(Landroid/view/View;Landroid/view/View;)Landroid/window/OnBackInvokedDispatcher;
 HSPLandroid/view/ViewGroup;->findViewByAutofillIdTraversal(I)Landroid/view/View;
 HSPLandroid/view/ViewGroup;->findViewByPredicateTraversal(Ljava/util/function/Predicate;Landroid/view/View;)Landroid/view/View;
-HSPLandroid/view/ViewGroup;->findViewTraversal(I)Landroid/view/View;+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->findViewTraversal(I)Landroid/view/View;
 HSPLandroid/view/ViewGroup;->findViewWithTagTraversal(Ljava/lang/Object;)Landroid/view/View;
 HSPLandroid/view/ViewGroup;->finishAnimatingView(Landroid/view/View;Landroid/view/animation/Animation;)V
 HSPLandroid/view/ViewGroup;->focusSearch(Landroid/view/View;I)Landroid/view/View;
@@ -17794,7 +17871,7 @@
 HSPLandroid/view/ViewGroup;->getChildMeasureSpec(III)I
 HSPLandroid/view/ViewGroup;->getChildTransformation()Landroid/view/animation/Transformation;
 HSPLandroid/view/ViewGroup;->getChildVisibleRect(Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;)Z
-HSPLandroid/view/ViewGroup;->getChildVisibleRect(Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;Z)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/ViewParent;Landroid/view/ViewRootImpl;
+HSPLandroid/view/ViewGroup;->getChildVisibleRect(Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;Z)Z+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewParent;Landroid/view/ViewRootImpl;
 HSPLandroid/view/ViewGroup;->getChildrenForAutofill(I)Landroid/view/ViewGroup$ChildListForAutoFillOrContentCapture;
 HSPLandroid/view/ViewGroup;->getChildrenForContentCapture()Landroid/view/ViewGroup$ChildListForAutoFillOrContentCapture;
 HSPLandroid/view/ViewGroup;->getClipChildren()Z
@@ -17820,8 +17897,8 @@
 HSPLandroid/view/ViewGroup;->hasUnhandledKeyListener()Z
 HSPLandroid/view/ViewGroup;->hasWindowInsetsAnimationCallback()Z
 HSPLandroid/view/ViewGroup;->indexOfChild(Landroid/view/View;)I
-HSPLandroid/view/ViewGroup;->initFromAttributes(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->initViewGroup()V+]Landroid/content/Context;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->initFromAttributes(Landroid/content/Context;Landroid/util/AttributeSet;II)V
+HSPLandroid/view/ViewGroup;->initViewGroup()V
 HSPLandroid/view/ViewGroup;->internalSetPadding(IIII)V
 HSPLandroid/view/ViewGroup;->invalidateChild(Landroid/view/View;Landroid/graphics/Rect;)V+]Landroid/view/ViewGroup;missing_types
 HSPLandroid/view/ViewGroup;->invalidateChildInParent([ILandroid/graphics/Rect;)Landroid/view/ViewParent;
@@ -17830,7 +17907,7 @@
 HSPLandroid/view/ViewGroup;->isLayoutSuppressed()Z
 HSPLandroid/view/ViewGroup;->isTransformedTouchPointInView(FFLandroid/view/View;Landroid/graphics/PointF;)Z
 HSPLandroid/view/ViewGroup;->isViewTransitioning(Landroid/view/View;)Z
-HSPLandroid/view/ViewGroup;->jumpDrawablesToCurrentState()V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->jumpDrawablesToCurrentState()V
 HSPLandroid/view/ViewGroup;->layout(IIII)V
 HSPLandroid/view/ViewGroup;->makeFrameworkOptionalFitsSystemWindows()V
 HSPLandroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V
@@ -17847,9 +17924,9 @@
 HSPLandroid/view/ViewGroup;->onDescendantInvalidated(Landroid/view/View;Landroid/view/View;)V+]Landroid/view/ViewParent;missing_types
 HSPLandroid/view/ViewGroup;->onDescendantUnbufferedRequested()V
 HSPLandroid/view/ViewGroup;->onDetachedFromWindow()V
-HSPLandroid/view/ViewGroup;->onInterceptTouchEvent(Landroid/view/MotionEvent;)Z
+HSPLandroid/view/ViewGroup;->onInterceptTouchEvent(Landroid/view/MotionEvent;)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
 HSPLandroid/view/ViewGroup;->onRequestFocusInDescendants(ILandroid/graphics/Rect;)Z
-HSPLandroid/view/ViewGroup;->onSetLayoutParams(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->onSetLayoutParams(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
 HSPLandroid/view/ViewGroup;->onStartNestedScroll(Landroid/view/View;Landroid/view/View;I)Z
 HSPLandroid/view/ViewGroup;->onViewAdded(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->onViewRemoved(Landroid/view/View;)V
@@ -17870,22 +17947,22 @@
 HSPLandroid/view/ViewGroup;->removeViewInternal(Landroid/view/View;)Z
 HSPLandroid/view/ViewGroup;->requestChildFocus(Landroid/view/View;Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->requestChildRectangleOnScreen(Landroid/view/View;Landroid/graphics/Rect;Z)Z
-HSPLandroid/view/ViewGroup;->requestDisallowInterceptTouchEvent(Z)V
+HSPLandroid/view/ViewGroup;->requestDisallowInterceptTouchEvent(Z)V+]Landroid/view/ViewParent;missing_types
 HSPLandroid/view/ViewGroup;->requestFocus(ILandroid/graphics/Rect;)Z
 HSPLandroid/view/ViewGroup;->requestTransitionStart(Landroid/animation/LayoutTransition;)V
 HSPLandroid/view/ViewGroup;->requestTransparentRegion(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->resetCancelNextUpFlag(Landroid/view/View;)Z
-HSPLandroid/view/ViewGroup;->resetResolvedDrawables()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetResolvedLayoutDirection()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetResolvedPadding()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetResolvedTextAlignment()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetResolvedTextDirection()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetSubtreeAccessibilityStateChanged()V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->resetResolvedDrawables()V
+HSPLandroid/view/ViewGroup;->resetResolvedLayoutDirection()V
+HSPLandroid/view/ViewGroup;->resetResolvedPadding()V
+HSPLandroid/view/ViewGroup;->resetResolvedTextAlignment()V
+HSPLandroid/view/ViewGroup;->resetResolvedTextDirection()V
+HSPLandroid/view/ViewGroup;->resetSubtreeAccessibilityStateChanged()V
 HSPLandroid/view/ViewGroup;->resetTouchState()V
 HSPLandroid/view/ViewGroup;->resolveDrawables()V
 HSPLandroid/view/ViewGroup;->resolveLayoutDirection()Z
 HSPLandroid/view/ViewGroup;->resolveLayoutParams()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resolvePadding()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->resolvePadding()V
 HSPLandroid/view/ViewGroup;->resolveRtlPropertiesIfNeeded()Z+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
 HSPLandroid/view/ViewGroup;->resolveTextAlignment()Z
 HSPLandroid/view/ViewGroup;->resolveTextDirection()Z
@@ -17906,7 +17983,7 @@
 HSPLandroid/view/ViewGroup;->shouldDelayChildPressedState()Z
 HSPLandroid/view/ViewGroup;->startViewTransition(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->suppressLayout(Z)V
-HSPLandroid/view/ViewGroup;->touchAccessibilityNodeProviderIfNeeded(Landroid/view/View;)V+]Landroid/content/Context;missing_types
+HSPLandroid/view/ViewGroup;->touchAccessibilityNodeProviderIfNeeded(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->transformPointToViewLocal([FLandroid/view/View;)V
 HSPLandroid/view/ViewGroup;->unFocus(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->updateLocalSystemUiVisibility(II)Z
@@ -17938,7 +18015,7 @@
 HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationCancel(Landroid/animation/Animator;)V
 HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationEnd(Landroid/animation/Animator;)V
 HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationStart(Landroid/animation/Animator;)V
-HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationUpdate(Landroid/animation/ValueAnimator;)V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationUpdate(Landroid/animation/ValueAnimator;)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/view/View;Landroid/widget/LinearLayout;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
 HSPLandroid/view/ViewPropertyAnimator$NameValuesHolder;-><init>(IFF)V
 HSPLandroid/view/ViewPropertyAnimator$PropertyBundle;-><init>(ILjava/util/ArrayList;)V
 HSPLandroid/view/ViewPropertyAnimator$PropertyBundle;->cancel(I)Z
@@ -17962,6 +18039,7 @@
 HSPLandroid/view/ViewPropertyAnimator;->withEndAction(Ljava/lang/Runnable;)Landroid/view/ViewPropertyAnimator;
 HSPLandroid/view/ViewPropertyAnimator;->withLayer()Landroid/view/ViewPropertyAnimator;
 HSPLandroid/view/ViewPropertyAnimator;->withStartAction(Ljava/lang/Runnable;)Landroid/view/ViewPropertyAnimator;
+HSPLandroid/view/ViewRootImpl$$ExternalSyntheticLambda0;->run()V
 HSPLandroid/view/ViewRootImpl$$ExternalSyntheticLambda17;-><init>(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/ViewRootImpl$$ExternalSyntheticLambda3;->run()V
 HSPLandroid/view/ViewRootImpl$AccessibilityInteractionConnectionManager;-><init>(Landroid/view/ViewRootImpl;)V
@@ -17978,13 +18056,13 @@
 HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
 HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->processKeyEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
 HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->processMotionEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
-HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->processPointerEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/autofill/AutofillManager;Landroid/view/autofill/AutofillManager;
+HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->processPointerEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
 HSPLandroid/view/ViewRootImpl$HighContrastTextManager;-><init>(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/ViewRootImpl$ImeInputStage;-><init>(Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl$InputStage;Ljava/lang/String;)V
 HSPLandroid/view/ViewRootImpl$ImeInputStage;->onFinishedInputEvent(Ljava/lang/Object;Z)V
 HSPLandroid/view/ViewRootImpl$ImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
 HSPLandroid/view/ViewRootImpl$InputMetricsListener;-><init>(Landroid/view/ViewRootImpl;)V
-HSPLandroid/view/ViewRootImpl$InputMetricsListener;->onFrameMetricsAvailable(I)V
+HSPLandroid/view/ViewRootImpl$InputMetricsListener;->onFrameMetricsAvailable(I)V+]Landroid/view/ViewRootImpl$WindowInputEventReceiver;Landroid/view/ViewRootImpl$WindowInputEventReceiver;
 HSPLandroid/view/ViewRootImpl$InputStage;-><init>(Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl$InputStage;)V
 HSPLandroid/view/ViewRootImpl$InputStage;->apply(Landroid/view/ViewRootImpl$QueuedInputEvent;I)V
 HSPLandroid/view/ViewRootImpl$InputStage;->deliver(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
@@ -17993,12 +18071,12 @@
 HSPLandroid/view/ViewRootImpl$InputStage;->onDeliverToNext(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
 HSPLandroid/view/ViewRootImpl$InputStage;->onDetachedFromWindow()V
 HSPLandroid/view/ViewRootImpl$InputStage;->onWindowFocusChanged(Z)V
-HSPLandroid/view/ViewRootImpl$InputStage;->shouldDropInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)Z+]Landroid/view/InputEvent;Landroid/view/MotionEvent;
-HSPLandroid/view/ViewRootImpl$InputStage;->traceEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;J)V+]Landroid/view/InputEvent;Landroid/view/MotionEvent;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;Landroid/view/ViewRootImpl$EarlyPostImeInputStage;,Landroid/view/ViewRootImpl$NativePostImeInputStage;,Landroid/view/ViewRootImpl$SyntheticInputStage;,Landroid/view/ViewRootImpl$ViewPostImeInputStage;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/ViewRootImpl$InputStage;->shouldDropInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)Z
+HSPLandroid/view/ViewRootImpl$InputStage;->traceEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;J)V
 HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;-><init>(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->addView(Landroid/view/View;)V+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->postIfNeededLocked()V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
-HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->removeView(Landroid/view/View;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->removeView(Landroid/view/View;)V
 HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->run()V+]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/ViewRootImpl$NativePostImeInputStage;-><init>(Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl$InputStage;Ljava/lang/String;)V
 HSPLandroid/view/ViewRootImpl$NativePostImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
@@ -18017,6 +18095,7 @@
 HSPLandroid/view/ViewRootImpl$SyntheticJoystickHandler;-><init>(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/ViewRootImpl$SyntheticJoystickHandler;->cancel()V
 HSPLandroid/view/ViewRootImpl$SyntheticKeyboardHandler;-><init>(Landroid/view/ViewRootImpl;)V
+HSPLandroid/view/ViewRootImpl$SyntheticTouchNavigationHandler$1;-><init>(Landroid/view/ViewRootImpl$SyntheticTouchNavigationHandler;)V
 HSPLandroid/view/ViewRootImpl$SyntheticTouchNavigationHandler;-><init>(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/ViewRootImpl$SyntheticTrackballHandler;-><init>(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/ViewRootImpl$SystemUiVisibilityInfo;-><init>()V
@@ -18033,7 +18112,7 @@
 HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->onDeliverToNext(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
 HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
 HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->processKeyEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
-HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->processPointerEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I+]Landroid/view/HandwritingInitiator;Landroid/view/HandwritingInitiator;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->processPointerEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
 HSPLandroid/view/ViewRootImpl$ViewPreImeInputStage;-><init>(Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl$InputStage;)V
 HSPLandroid/view/ViewRootImpl$ViewPreImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
 HSPLandroid/view/ViewRootImpl$ViewRootHandler;-><init>(Landroid/view/ViewRootImpl;)V
@@ -18045,6 +18124,7 @@
 HSPLandroid/view/ViewRootImpl$W;->closeSystemDialogs(Ljava/lang/String;)V
 HSPLandroid/view/ViewRootImpl$W;->dispatchAppVisibility(Z)V
 HSPLandroid/view/ViewRootImpl$W;->dispatchWindowShown()V
+HSPLandroid/view/ViewRootImpl$W;->insetsControlChanged(Landroid/view/InsetsState;[Landroid/view/InsetsSourceControl;)V
 HSPLandroid/view/ViewRootImpl$W;->moved(II)V
 HSPLandroid/view/ViewRootImpl$WindowInputEventReceiver;-><init>(Landroid/view/ViewRootImpl;Landroid/view/InputChannel;Landroid/os/Looper;)V
 HSPLandroid/view/ViewRootImpl$WindowInputEventReceiver;->dispose()V
@@ -18053,27 +18133,29 @@
 HSPLandroid/view/ViewRootImpl$WindowInputEventReceiver;->onInputEvent(Landroid/view/InputEvent;)V
 HSPLandroid/view/ViewRootImpl;->-$$Nest$fgetmBlastBufferQueue(Landroid/view/ViewRootImpl;)Landroid/graphics/BLASTBufferQueue;
 HSPLandroid/view/ViewRootImpl;->-$$Nest$fputmProfileRendering(Landroid/view/ViewRootImpl;Z)V
+HSPLandroid/view/ViewRootImpl;->-$$Nest$mdispatchInsetsControlChanged(Landroid/view/ViewRootImpl;Landroid/view/InsetsState;[Landroid/view/InsetsSourceControl;)V
 HSPLandroid/view/ViewRootImpl;->-$$Nest$mprofileRendering(Landroid/view/ViewRootImpl;Z)V
 HSPLandroid/view/ViewRootImpl;-><init>(Landroid/content/Context;Landroid/view/Display;)V
-HSPLandroid/view/ViewRootImpl;-><init>(Landroid/content/Context;Landroid/view/Display;Landroid/view/IWindowSession;Landroid/view/WindowLayout;)V+]Landroid/content/Context;missing_types]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/WindowLeaked;Landroid/view/WindowLeaked;]Ljava/lang/String;Ljava/lang/String;]Ljava/util/Optional;Ljava/util/Optional;
+HSPLandroid/view/ViewRootImpl;-><init>(Landroid/content/Context;Landroid/view/Display;Landroid/view/IWindowSession;Landroid/view/WindowLayout;)V
 HSPLandroid/view/ViewRootImpl;->addConfigCallback(Landroid/view/ViewRootImpl$ConfigChangedCallback;)V
-HSPLandroid/view/ViewRootImpl;->addFrameCommitCallbackIfNeeded()V
+HSPLandroid/view/ViewRootImpl;->addFrameCommitCallbackIfNeeded()V+]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
 HSPLandroid/view/ViewRootImpl;->addSurfaceChangedCallback(Landroid/view/ViewRootImpl$SurfaceChangedCallback;)V
 HSPLandroid/view/ViewRootImpl;->addWindowCallbacks(Landroid/view/WindowCallbacks;)V
+HSPLandroid/view/ViewRootImpl;->adjustLayoutParamsForCompatibility(Landroid/view/WindowManager$LayoutParams;)V
 HSPLandroid/view/ViewRootImpl;->applyKeepScreenOnFlag(Landroid/view/WindowManager$LayoutParams;)V
-HSPLandroid/view/ViewRootImpl;->applyTransactionOnDraw(Landroid/view/SurfaceControl$Transaction;)Z
+HSPLandroid/view/ViewRootImpl;->applyTransactionOnDraw(Landroid/view/SurfaceControl$Transaction;)Z+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
 HSPLandroid/view/ViewRootImpl;->canResolveTextDirection()Z
-HSPLandroid/view/ViewRootImpl;->cancelInvalidate(Landroid/view/View;)V+]Landroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;Landroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;
+HSPLandroid/view/ViewRootImpl;->cancelInvalidate(Landroid/view/View;)V
 HSPLandroid/view/ViewRootImpl;->checkForLeavingTouchModeAndConsume(Landroid/view/KeyEvent;)Z
 HSPLandroid/view/ViewRootImpl;->checkThread()V
 HSPLandroid/view/ViewRootImpl;->childDrawableStateChanged(Landroid/view/View;)V
 HSPLandroid/view/ViewRootImpl;->childHasTransientStateChanged(Landroid/view/View;Z)V
 HSPLandroid/view/ViewRootImpl;->clearChildFocus(Landroid/view/View;)V
 HSPLandroid/view/ViewRootImpl;->clearLowProfileModeIfNeeded(IZ)V
-HSPLandroid/view/ViewRootImpl;->collectViewAttributes()Z+]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl;->collectViewAttributes()Z+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
 HSPLandroid/view/ViewRootImpl;->controlInsetsForCompatibility(Landroid/view/WindowManager$LayoutParams;)V
-HSPLandroid/view/ViewRootImpl;->createSyncIfNeeded()V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/window/SurfaceSyncGroup;Landroid/window/SurfaceSyncGroup;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/view/ViewRootImpl;->deliverInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)V+]Landroid/view/InputEvent;Landroid/view/MotionEvent;]Landroid/view/ViewRootImpl$InputStage;Landroid/view/ViewRootImpl$EarlyPostImeInputStage;]Landroid/view/ViewRootImpl$QueuedInputEvent;Landroid/view/ViewRootImpl$QueuedInputEvent;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/ViewRootImpl;->createSyncIfNeeded()V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/window/SurfaceSyncGroup;Landroid/window/SurfaceSyncGroup;
+HSPLandroid/view/ViewRootImpl;->deliverInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
 HSPLandroid/view/ViewRootImpl;->destroyHardwareRenderer()V
 HSPLandroid/view/ViewRootImpl;->destroyHardwareResources()V
 HSPLandroid/view/ViewRootImpl;->destroySurface()V
@@ -18085,14 +18167,15 @@
 HSPLandroid/view/ViewRootImpl;->dispatchDetachedFromWindow()V
 HSPLandroid/view/ViewRootImpl;->dispatchDispatchSystemUiVisibilityChanged()V
 HSPLandroid/view/ViewRootImpl;->dispatchFocusEvent(ZZ)V
+HSPLandroid/view/ViewRootImpl;->dispatchInsetsControlChanged(Landroid/view/InsetsState;[Landroid/view/InsetsSourceControl;)V
 HSPLandroid/view/ViewRootImpl;->dispatchInvalidateDelayed(Landroid/view/View;J)V
-HSPLandroid/view/ViewRootImpl;->dispatchInvalidateOnAnimation(Landroid/view/View;)V
+HSPLandroid/view/ViewRootImpl;->dispatchInvalidateOnAnimation(Landroid/view/View;)V+]Landroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;Landroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;
 HSPLandroid/view/ViewRootImpl;->dispatchMoved(II)V
 HSPLandroid/view/ViewRootImpl;->doConsumeBatchedInput(J)Z
 HSPLandroid/view/ViewRootImpl;->doDie()V
-HSPLandroid/view/ViewRootImpl;->doProcessInputEvents()V+]Landroid/view/InputEventAssigner;Landroid/view/InputEventAssigner;]Landroid/view/ViewFrameInfo;Landroid/view/ViewFrameInfo;
-HSPLandroid/view/ViewRootImpl;->doTraversal()V+]Landroid/os/Looper;Landroid/os/Looper;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;
-HSPLandroid/view/ViewRootImpl;->draw(ZLandroid/window/SurfaceSyncGroup;Z)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/HdrRenderState;Landroid/view/HdrRenderState;]Landroid/view/Surface;Landroid/view/Surface;]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;
+HSPLandroid/view/ViewRootImpl;->doProcessInputEvents()V
+HSPLandroid/view/ViewRootImpl;->doTraversal()V+]Landroid/os/Looper;Landroid/os/Looper;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;
+HSPLandroid/view/ViewRootImpl;->draw(ZLandroid/window/SurfaceSyncGroup;Z)Z+]Landroid/view/Surface;Landroid/view/Surface;]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/HdrRenderState;Landroid/view/HdrRenderState;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;
 HSPLandroid/view/ViewRootImpl;->drawAccessibilityFocusedDrawableIfNeeded(Landroid/graphics/Canvas;)V
 HSPLandroid/view/ViewRootImpl;->drawSoftware(Landroid/view/Surface;Landroid/view/View$AttachInfo;IIZLandroid/graphics/Rect;Landroid/graphics/Rect;)Z
 HSPLandroid/view/ViewRootImpl;->enableHardwareAcceleration(Landroid/view/WindowManager$LayoutParams;)V
@@ -18114,10 +18197,10 @@
 HSPLandroid/view/ViewRootImpl;->getBufferTransformHint()I
 HSPLandroid/view/ViewRootImpl;->getChildVisibleRect(Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;)Z
 HSPLandroid/view/ViewRootImpl;->getCompatWindowConfiguration()Landroid/app/WindowConfiguration;
-HSPLandroid/view/ViewRootImpl;->getConfiguration()Landroid/content/res/Configuration;+]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/view/ViewRootImpl;->getConfiguration()Landroid/content/res/Configuration;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;
 HSPLandroid/view/ViewRootImpl;->getDisplayId()I
 HSPLandroid/view/ViewRootImpl;->getHandwritingInitiator()Landroid/view/HandwritingInitiator;
-HSPLandroid/view/ViewRootImpl;->getHostVisibility()I+]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl;->getHostVisibility()I+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
 HSPLandroid/view/ViewRootImpl;->getImeFocusController()Landroid/view/ImeFocusController;
 HSPLandroid/view/ViewRootImpl;->getImpliedSystemUiVisibility(Landroid/view/WindowManager$LayoutParams;)I
 HSPLandroid/view/ViewRootImpl;->getInsetsController()Landroid/view/InsetsController;
@@ -18131,14 +18214,14 @@
 HSPLandroid/view/ViewRootImpl;->getSurfaceSequenceId()I
 HSPLandroid/view/ViewRootImpl;->getTextDirection()I
 HSPLandroid/view/ViewRootImpl;->getTitle()Ljava/lang/CharSequence;
-HSPLandroid/view/ViewRootImpl;->getUpdatedFrameInfo()Landroid/graphics/FrameInfo;
+HSPLandroid/view/ViewRootImpl;->getUpdatedFrameInfo()Landroid/graphics/FrameInfo;+]Landroid/view/InputEventAssigner;Landroid/view/InputEventAssigner;]Landroid/view/ViewFrameInfo;Landroid/view/ViewFrameInfo;
 HSPLandroid/view/ViewRootImpl;->getValidLayoutRequesters(Ljava/util/ArrayList;Z)Ljava/util/ArrayList;
 HSPLandroid/view/ViewRootImpl;->getView()Landroid/view/View;
 HSPLandroid/view/ViewRootImpl;->getViewBoundsSandboxingEnabled()Z
 HSPLandroid/view/ViewRootImpl;->getWindowBoundsInsetSystemBars()Landroid/graphics/Rect;
 HSPLandroid/view/ViewRootImpl;->getWindowFlags()I
-HSPLandroid/view/ViewRootImpl;->getWindowInsets(Z)Landroid/view/WindowInsets;+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/graphics/Insets;Landroid/graphics/Insets;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/WindowInsets;Landroid/view/WindowInsets;
-HSPLandroid/view/ViewRootImpl;->getWindowVisibleDisplayFrame(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/ViewRootImpl;->getWindowInsets(Z)Landroid/view/WindowInsets;
+HSPLandroid/view/ViewRootImpl;->getWindowVisibleDisplayFrame(Landroid/graphics/Rect;)V
 HSPLandroid/view/ViewRootImpl;->handleAppVisibility(Z)V
 HSPLandroid/view/ViewRootImpl;->handleContentCaptureFlush()V
 HSPLandroid/view/ViewRootImpl;->handleDispatchSystemUiVisibilityChanged()V
@@ -18147,6 +18230,7 @@
 HSPLandroid/view/ViewRootImpl;->invalidateChild(Landroid/view/View;Landroid/graphics/Rect;)V
 HSPLandroid/view/ViewRootImpl;->invalidateChildInParent([ILandroid/graphics/Rect;)Landroid/view/ViewParent;
 HSPLandroid/view/ViewRootImpl;->invalidateRectOnScreen(Landroid/graphics/Rect;)V
+HSPLandroid/view/ViewRootImpl;->isAccessibilityFocusDirty()Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
 HSPLandroid/view/ViewRootImpl;->isContentCaptureEnabled()Z
 HSPLandroid/view/ViewRootImpl;->isContentCaptureReallyEnabled()Z
 HSPLandroid/view/ViewRootImpl;->isHardwareEnabled()Z+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
@@ -18164,10 +18248,10 @@
 HSPLandroid/view/ViewRootImpl;->lambda$new$2(Landroid/view/View;)Ljava/util/List;
 HSPLandroid/view/ViewRootImpl;->loadSystemProperties()V
 HSPLandroid/view/ViewRootImpl;->maybeFireAccessibilityWindowStateChangedEvent()V
-HSPLandroid/view/ViewRootImpl;->maybeHandleWindowMove(Landroid/graphics/Rect;)V+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
+HSPLandroid/view/ViewRootImpl;->maybeHandleWindowMove(Landroid/graphics/Rect;)V
 HSPLandroid/view/ViewRootImpl;->maybeUpdateTooltip(Landroid/view/MotionEvent;)V
-HSPLandroid/view/ViewRootImpl;->measureHierarchy(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;Landroid/content/res/Resources;IIZ)Z+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/util/TypedValue;Landroid/util/TypedValue;]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
-HSPLandroid/view/ViewRootImpl;->mergeWithNextTransaction(Landroid/view/SurfaceControl$Transaction;J)V
+HSPLandroid/view/ViewRootImpl;->measureHierarchy(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;Landroid/content/res/Resources;IIZ)Z+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl;->mergeWithNextTransaction(Landroid/view/SurfaceControl$Transaction;J)V+]Landroid/graphics/BLASTBufferQueue;Landroid/graphics/BLASTBufferQueue;
 HSPLandroid/view/ViewRootImpl;->notifyContentCaptureEvents()V
 HSPLandroid/view/ViewRootImpl;->notifyDrawStarted(Z)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/ViewRootImpl;->notifyInsetsChanged()V
@@ -18182,24 +18266,24 @@
 HSPLandroid/view/ViewRootImpl;->onPreDraw(Landroid/graphics/RecordingCanvas;)V
 HSPLandroid/view/ViewRootImpl;->onStartNestedScroll(Landroid/view/View;Landroid/view/View;I)Z
 HSPLandroid/view/ViewRootImpl;->performContentCaptureInitialReport()V
-HSPLandroid/view/ViewRootImpl;->performDraw(Landroid/window/SurfaceSyncGroup;)Z+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/view/ViewRootImpl;->performLayout(Landroid/view/WindowManager$LayoutParams;II)V+]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/view/ViewRootImpl;->performMeasure(II)V+]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
-HSPLandroid/view/ViewRootImpl;->performTraversals()V+]Landroid/content/Context;missing_types]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/Region;Landroid/graphics/Region;]Landroid/util/MergedConfiguration;Landroid/util/MergedConfiguration;]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Landroid/view/ImeFocusController;Landroid/view/ImeFocusController;]Landroid/view/Surface;Landroid/view/Surface;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/window/SurfaceSyncGroup;Landroid/window/SurfaceSyncGroup;]Landroid/window/WindowOnBackInvokedDispatcher;Landroid/window/WindowOnBackInvokedDispatcher;]Lcom/android/internal/view/RootViewSurfaceTaker;Lcom/android/internal/policy/DecorView;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ViewRootImpl;->performDraw(Landroid/window/SurfaceSyncGroup;)Z+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
+HSPLandroid/view/ViewRootImpl;->performLayout(Landroid/view/WindowManager$LayoutParams;II)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ViewRootImpl;->performMeasure(II)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl;->performTraversals()V+]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/View;missing_types]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/Surface;Landroid/view/Surface;]Landroid/util/MergedConfiguration;Landroid/util/MergedConfiguration;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ImeFocusController;Landroid/view/ImeFocusController;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/content/Context;Landroid/view/ContextThemeWrapper;,Lcom/android/internal/policy/DecorContext;]Lcom/android/internal/view/RootViewSurfaceTaker;Lcom/android/internal/policy/DecorView;]Landroid/graphics/Region;Landroid/graphics/Region;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/window/SurfaceSyncGroup;Landroid/window/SurfaceSyncGroup;]Landroid/window/WindowOnBackInvokedDispatcher;Landroid/window/WindowOnBackInvokedDispatcher;
 HSPLandroid/view/ViewRootImpl;->playSoundEffect(I)V
 HSPLandroid/view/ViewRootImpl;->pokeDrawLockIfNeeded()V
-HSPLandroid/view/ViewRootImpl;->prepareSurfaces()V
+HSPLandroid/view/ViewRootImpl;->prepareSurfaces()V+]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
 HSPLandroid/view/ViewRootImpl;->profileRendering(Z)V
 HSPLandroid/view/ViewRootImpl;->recomputeViewAttributes(Landroid/view/View;)V
 HSPLandroid/view/ViewRootImpl;->recycleQueuedInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
 HSPLandroid/view/ViewRootImpl;->registerAnimatingRenderNode(Landroid/graphics/RenderNode;)V
 HSPLandroid/view/ViewRootImpl;->registerBackCallbackOnWindow()V
-HSPLandroid/view/ViewRootImpl;->registerCallbackForPendingTransactions()V
+HSPLandroid/view/ViewRootImpl;->registerCallbackForPendingTransactions()V+]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
 HSPLandroid/view/ViewRootImpl;->registerCallbacksForSync(ZLandroid/window/SurfaceSyncGroup;)V
 HSPLandroid/view/ViewRootImpl;->registerCompatOnBackInvokedCallback()V
 HSPLandroid/view/ViewRootImpl;->registerListeners()V
-HSPLandroid/view/ViewRootImpl;->registerRtFrameCallback(Landroid/graphics/HardwareRenderer$FrameDrawingCallback;)V
-HSPLandroid/view/ViewRootImpl;->relayoutWindow(Landroid/view/WindowManager$LayoutParams;IZ)I+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/MergedConfiguration;Landroid/util/MergedConfiguration;]Landroid/view/Display;Landroid/view/Display;]Landroid/view/HdrRenderState;Landroid/view/HdrRenderState;]Landroid/view/IWindowSession;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/InsetsSourceControl$Array;Landroid/view/InsetsSourceControl$Array;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/ViewRootImpl;->registerRtFrameCallback(Landroid/graphics/HardwareRenderer$FrameDrawingCallback;)V+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
+HSPLandroid/view/ViewRootImpl;->relayoutWindow(Landroid/view/WindowManager$LayoutParams;IZ)I+]Landroid/view/IWindowSession;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/view/InsetsState;Landroid/view/InsetsState;]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/HdrRenderState;Landroid/view/HdrRenderState;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/WindowLayout;Landroid/view/WindowLayout;]Landroid/util/MergedConfiguration;Landroid/util/MergedConfiguration;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/view/Display;Landroid/view/Display;
 HSPLandroid/view/ViewRootImpl;->removeSendWindowContentChangedCallback()V
 HSPLandroid/view/ViewRootImpl;->removeSurfaceChangedCallback(Landroid/view/ViewRootImpl$SurfaceChangedCallback;)V
 HSPLandroid/view/ViewRootImpl;->removeWindowCallbacks(Landroid/view/WindowCallbacks;)V
@@ -18212,28 +18296,31 @@
 HSPLandroid/view/ViewRootImpl;->requestLayout()V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
 HSPLandroid/view/ViewRootImpl;->requestLayoutDuringLayout(Landroid/view/View;)Z
 HSPLandroid/view/ViewRootImpl;->requestTransparentRegion(Landroid/view/View;)V
-HSPLandroid/view/ViewRootImpl;->scheduleConsumeBatchedInput()V+]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
-HSPLandroid/view/ViewRootImpl;->scheduleTraversals()V+]Landroid/os/Looper;Landroid/os/Looper;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/ViewRootImpl;->scheduleConsumeBatchedInput()V
+HSPLandroid/view/ViewRootImpl;->scheduleTraversals()V+]Landroid/os/Looper;Landroid/os/Looper;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/Choreographer;Landroid/view/Choreographer;
 HSPLandroid/view/ViewRootImpl;->scrollToRectOrFocus(Landroid/graphics/Rect;Z)Z
 HSPLandroid/view/ViewRootImpl;->sendBackKeyEvent(I)V
 HSPLandroid/view/ViewRootImpl;->setAccessibilityFocus(Landroid/view/View;Landroid/view/accessibility/AccessibilityNodeInfo;)V
 HSPLandroid/view/ViewRootImpl;->setAccessibilityWindowAttributesIfNeeded()V
 HSPLandroid/view/ViewRootImpl;->setActivityConfigCallback(Landroid/view/ViewRootImpl$ActivityConfigCallback;)V
 HSPLandroid/view/ViewRootImpl;->setBoundsLayerCrop(Landroid/view/SurfaceControl$Transaction;)V
-HSPLandroid/view/ViewRootImpl;->setFrame(Landroid/graphics/Rect;Z)V
-HSPLandroid/view/ViewRootImpl;->setLayoutParams(Landroid/view/WindowManager$LayoutParams;Z)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;
+HSPLandroid/view/ViewRootImpl;->setFrame(Landroid/graphics/Rect;Z)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/InsetsController;Landroid/view/InsetsController;
+HSPLandroid/view/ViewRootImpl;->setLayoutParams(Landroid/view/WindowManager$LayoutParams;Z)V+]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
 HSPLandroid/view/ViewRootImpl;->setOnContentApplyWindowInsetsListener(Landroid/view/Window$OnContentApplyWindowInsetsListener;)V
 HSPLandroid/view/ViewRootImpl;->setTag()V
-HSPLandroid/view/ViewRootImpl;->setView(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;Landroid/view/View;I)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/Display;Landroid/view/Display;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/view/FallbackEventHandler;Lcom/android/internal/policy/PhoneFallbackEventHandler;]Landroid/view/IWindowSession;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/InsetsSourceControl$Array;Landroid/view/InsetsSourceControl$Array;]Landroid/view/InsetsState;Landroid/view/InsetsState;]Landroid/view/PendingInsetsController;Landroid/view/PendingInsetsController;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/WindowLayout;Landroid/view/WindowLayout;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Lcom/android/internal/view/RootViewSurfaceTaker;Lcom/android/internal/policy/DecorView;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/ViewRootImpl;->setView(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;Landroid/view/View;I)V+]Landroid/view/IWindowSession;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/view/InsetsState;Landroid/view/InsetsState;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/InsetsSourceControl$Array;Landroid/view/InsetsSourceControl$Array;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/PendingInsetsController;Landroid/view/PendingInsetsController;]Lcom/android/internal/view/RootViewSurfaceTaker;Lcom/android/internal/policy/DecorView;]Landroid/view/FallbackEventHandler;Lcom/android/internal/policy/PhoneFallbackEventHandler;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/WindowLayout;Landroid/view/WindowLayout;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/view/Display;Landroid/view/Display;
 HSPLandroid/view/ViewRootImpl;->setWindowStopped(Z)V
 HSPLandroid/view/ViewRootImpl;->shouldDispatchCutout()Z
 HSPLandroid/view/ViewRootImpl;->shouldOptimizeMeasure(Landroid/view/WindowManager$LayoutParams;)Z
+HSPLandroid/view/ViewRootImpl;->shouldSetFrameRate()Z+]Landroid/view/Surface;Landroid/view/Surface;
+HSPLandroid/view/ViewRootImpl;->shouldSetFrameRateCategory()Z+]Landroid/view/Surface;Landroid/view/Surface;
 HSPLandroid/view/ViewRootImpl;->shouldUseDisplaySize(Landroid/view/WindowManager$LayoutParams;)Z
 HSPLandroid/view/ViewRootImpl;->systemGestureExclusionChanged()V
 HSPLandroid/view/ViewRootImpl;->unscheduleConsumeBatchedInput()V
 HSPLandroid/view/ViewRootImpl;->unscheduleTraversals()V
-HSPLandroid/view/ViewRootImpl;->updateBlastSurfaceIfNeeded()V
+HSPLandroid/view/ViewRootImpl;->updateBlastSurfaceIfNeeded()V+]Landroid/graphics/BLASTBufferQueue;Landroid/graphics/BLASTBufferQueue;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;
 HSPLandroid/view/ViewRootImpl;->updateBoundsLayer(Landroid/view/SurfaceControl$Transaction;)Z
+HSPLandroid/view/ViewRootImpl;->updateCaptionInsets()Z
 HSPLandroid/view/ViewRootImpl;->updateCompatSysUiVisibility(III)V
 HSPLandroid/view/ViewRootImpl;->updateCompatSystemUiVisibilityInfo(IIII)V
 HSPLandroid/view/ViewRootImpl;->updateConfiguration(I)V
@@ -18256,6 +18343,7 @@
 HSPLandroid/view/ViewRootInsetsControllerHost;->getTranslator()Landroid/content/res/CompatibilityInfo$Translator;
 HSPLandroid/view/ViewRootInsetsControllerHost;->getWindowToken()Landroid/os/IBinder;
 HSPLandroid/view/ViewRootInsetsControllerHost;->hasAnimationCallbacks()Z
+HSPLandroid/view/ViewRootInsetsControllerHost;->isSystemBarsAppearanceControlled()Z
 HSPLandroid/view/ViewRootInsetsControllerHost;->notifyInsetsChanged()V
 HSPLandroid/view/ViewRootInsetsControllerHost;->updateCompatSysUiVisibility(III)V
 HSPLandroid/view/ViewRootRectTracker$ViewInfo;-><init>(Landroid/view/ViewRootRectTracker;Landroid/view/View;)V
@@ -18278,16 +18366,16 @@
 HSPLandroid/view/ViewStub;->setOnInflateListener(Landroid/view/ViewStub$OnInflateListener;)V
 HSPLandroid/view/ViewStub;->setVisibility(I)V
 HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray$Access;-><init>()V
-HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray$Access;->get(I)Ljava/lang/Object;
+HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray$Access;->get(I)Ljava/lang/Object;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray$Access;->size()I
 HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;-><init>()V
 HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->add(Ljava/lang/Object;)V
 HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->addAll(Landroid/view/ViewTreeObserver$CopyOnWriteArray;)V
-HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->end()V
+HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->end()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->getArray()Ljava/util/ArrayList;
 HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->remove(Ljava/lang/Object;)V
-HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->size()I
-HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->start()Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;
+HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->size()I+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->start()Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/ViewTreeObserver$InternalInsetsInfo;-><init>()V
 HSPLandroid/view/ViewTreeObserver$InternalInsetsInfo;->equals(Ljava/lang/Object;)Z
 HSPLandroid/view/ViewTreeObserver$InternalInsetsInfo;->isEmpty()Z
@@ -18303,10 +18391,10 @@
 HSPLandroid/view/ViewTreeObserver;->captureFrameCommitCallbacks()Ljava/util/ArrayList;
 HSPLandroid/view/ViewTreeObserver;->checkIsAlive()V
 HSPLandroid/view/ViewTreeObserver;->dispatchOnComputeInternalInsets(Landroid/view/ViewTreeObserver$InternalInsetsInfo;)V
-HSPLandroid/view/ViewTreeObserver;->dispatchOnDraw()V
+HSPLandroid/view/ViewTreeObserver;->dispatchOnDraw()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/view/ViewTreeObserver$OnDrawListener;Landroid/widget/Editor$2;
 HSPLandroid/view/ViewTreeObserver;->dispatchOnEnterAnimationComplete()V
-HSPLandroid/view/ViewTreeObserver;->dispatchOnGlobalLayout()V
-HSPLandroid/view/ViewTreeObserver;->dispatchOnPreDraw()Z
+HSPLandroid/view/ViewTreeObserver;->dispatchOnGlobalLayout()V+]Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;]Landroid/view/ViewTreeObserver$CopyOnWriteArray;Landroid/view/ViewTreeObserver$CopyOnWriteArray;
+HSPLandroid/view/ViewTreeObserver;->dispatchOnPreDraw()Z+]Landroid/view/ViewTreeObserver$OnPreDrawListener;missing_types]Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;]Landroid/view/ViewTreeObserver$CopyOnWriteArray;Landroid/view/ViewTreeObserver$CopyOnWriteArray;
 HSPLandroid/view/ViewTreeObserver;->dispatchOnScrollChanged()V
 HSPLandroid/view/ViewTreeObserver;->dispatchOnSystemGestureExclusionRectsChanged(Ljava/util/List;)V
 HSPLandroid/view/ViewTreeObserver;->dispatchOnTouchModeChanged(Z)V
@@ -18354,7 +18442,7 @@
 HSPLandroid/view/Window;->onDrawLegacyNavigationBarBackgroundChanged(Z)Z
 HSPLandroid/view/Window;->removeOnFrameMetricsAvailableListener(Landroid/view/Window$OnFrameMetricsAvailableListener;)V
 HSPLandroid/view/Window;->requestFeature(I)Z
-HSPLandroid/view/Window;->setAttributes(Landroid/view/WindowManager$LayoutParams;)V
+HSPLandroid/view/Window;->setAttributes(Landroid/view/WindowManager$LayoutParams;)V+]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/Window;Lcom/android/internal/policy/PhoneWindow;
 HSPLandroid/view/Window;->setBackgroundBlurRadius(I)V
 HSPLandroid/view/Window;->setCallback(Landroid/view/Window$Callback;)V
 HSPLandroid/view/Window;->setCloseOnTouchOutside(Z)V
@@ -18389,6 +18477,7 @@
 HSPLandroid/view/WindowInsets$Type;->systemBars()I
 HSPLandroid/view/WindowInsets$Type;->systemGestures()I
 HSPLandroid/view/WindowInsets$Type;->toString(I)Ljava/lang/String;
+HSPLandroid/view/WindowInsets;-><init>([Landroid/graphics/Insets;[Landroid/graphics/Insets;[ZZIILandroid/view/DisplayCutout;Landroid/view/RoundedCorners;Landroid/view/PrivacyIndicatorBounds;Landroid/view/DisplayShape;IZ[[Landroid/graphics/Rect;[[Landroid/graphics/Rect;II)V+]Landroid/view/DisplayCutout;Landroid/view/DisplayCutout;][Landroid/graphics/Insets;[Landroid/graphics/Insets;][[Landroid/graphics/Rect;[[Landroid/graphics/Rect;
 HSPLandroid/view/WindowInsets;->assignCompatInsets([Landroid/graphics/Insets;Landroid/graphics/Rect;)V
 HSPLandroid/view/WindowInsets;->consumeDisplayCutout()Landroid/view/WindowInsets;
 HSPLandroid/view/WindowInsets;->consumeStableInsets()Landroid/view/WindowInsets;
@@ -18410,13 +18499,13 @@
 HSPLandroid/view/WindowInsets;->getSystemWindowInsetLeft()I
 HSPLandroid/view/WindowInsets;->getSystemWindowInsetRight()I
 HSPLandroid/view/WindowInsets;->getSystemWindowInsetTop()I
-HSPLandroid/view/WindowInsets;->getSystemWindowInsets()Landroid/graphics/Insets;+]Landroid/view/WindowInsets;Landroid/view/WindowInsets;
+HSPLandroid/view/WindowInsets;->getSystemWindowInsets()Landroid/graphics/Insets;
 HSPLandroid/view/WindowInsets;->getSystemWindowInsetsAsRect()Landroid/graphics/Rect;
 HSPLandroid/view/WindowInsets;->inset(IIII)Landroid/view/WindowInsets;
 HSPLandroid/view/WindowInsets;->inset(Landroid/graphics/Insets;)Landroid/view/WindowInsets;
 HSPLandroid/view/WindowInsets;->insetInsets(Landroid/graphics/Insets;IIII)Landroid/graphics/Insets;
 HSPLandroid/view/WindowInsets;->insetInsets([Landroid/graphics/Insets;IIII)[Landroid/graphics/Insets;
-HSPLandroid/view/WindowInsets;->insetUnchecked(IIII)Landroid/view/WindowInsets;+]Landroid/view/PrivacyIndicatorBounds;Landroid/view/PrivacyIndicatorBounds;]Landroid/view/RoundedCorners;Landroid/view/RoundedCorners;
+HSPLandroid/view/WindowInsets;->insetUnchecked(IIII)Landroid/view/WindowInsets;
 HSPLandroid/view/WindowInsets;->isConsumed()Z
 HSPLandroid/view/WindowInsets;->isRound()Z
 HSPLandroid/view/WindowInsets;->replaceSystemWindowInsets(IIII)Landroid/view/WindowInsets;
@@ -18427,8 +18516,8 @@
 HSPLandroid/view/WindowInsetsAnimation;->setAlpha(F)V
 HSPLandroid/view/WindowLayout;-><clinit>()V
 HSPLandroid/view/WindowLayout;-><init>()V
-HSPLandroid/view/WindowLayout;->computeFrames(Landroid/view/WindowManager$LayoutParams;Landroid/view/InsetsState;Landroid/graphics/Rect;Landroid/graphics/Rect;IIIIFLandroid/window/ClientWindowFrames;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/DisplayCutout;Landroid/view/DisplayCutout;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/view/InsetsState;Landroid/view/InsetsState;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;
-HSPLandroid/view/WindowLayout;->computeSurfaceSize(Landroid/view/WindowManager$LayoutParams;Landroid/graphics/Rect;IILandroid/graphics/Rect;ZLandroid/graphics/Point;)V
+HSPLandroid/view/WindowLayout;->computeFrames(Landroid/view/WindowManager$LayoutParams;Landroid/view/InsetsState;Landroid/graphics/Rect;Landroid/graphics/Rect;IIIIFLandroid/window/ClientWindowFrames;)V+]Landroid/view/InsetsState;Landroid/view/InsetsState;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/DisplayCutout;Landroid/view/DisplayCutout;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/view/WindowLayout;->computeSurfaceSize(Landroid/view/WindowManager$LayoutParams;Landroid/graphics/Rect;IILandroid/graphics/Rect;ZLandroid/graphics/Point;)V+]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/graphics/Rect;Landroid/graphics/Rect;
 HSPLandroid/view/WindowLeaked;-><init>(Ljava/lang/String;)V
 HSPLandroid/view/WindowManager$LayoutParams$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/WindowManager$LayoutParams;
 HSPLandroid/view/WindowManager$LayoutParams$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -18463,7 +18552,7 @@
 HSPLandroid/view/WindowManagerGlobal;->closeAllExceptView(Landroid/os/IBinder;Landroid/view/View;Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/view/WindowManagerGlobal;->doRemoveView(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/WindowManagerGlobal;->dumpGfxInfo(Ljava/io/FileDescriptor;[Ljava/lang/String;)V
-HSPLandroid/view/WindowManagerGlobal;->findViewLocked(Landroid/view/View;Z)I
+HSPLandroid/view/WindowManagerGlobal;->findViewLocked(Landroid/view/View;Z)I+]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/WindowManagerGlobal;->getInstance()Landroid/view/WindowManagerGlobal;
 HSPLandroid/view/WindowManagerGlobal;->getRootViews(Landroid/os/IBinder;)Ljava/util/ArrayList;
 HSPLandroid/view/WindowManagerGlobal;->getWindowManagerService()Landroid/view/IWindowManager;
@@ -18473,9 +18562,9 @@
 HSPLandroid/view/WindowManagerGlobal;->peekWindowSession()Landroid/view/IWindowSession;
 HSPLandroid/view/WindowManagerGlobal;->removeView(Landroid/view/View;Z)V
 HSPLandroid/view/WindowManagerGlobal;->removeViewLocked(IZ)V
-HSPLandroid/view/WindowManagerGlobal;->setStoppedState(Landroid/os/IBinder;Z)V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/WindowManagerGlobal;Landroid/view/WindowManagerGlobal;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/WindowManagerGlobal;->setStoppedState(Landroid/os/IBinder;Z)V
 HSPLandroid/view/WindowManagerGlobal;->trimMemory(I)V
-HSPLandroid/view/WindowManagerGlobal;->updateViewLayout(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
+HSPLandroid/view/WindowManagerGlobal;->updateViewLayout(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/WindowManagerImpl;-><init>(Landroid/content/Context;)V
 HSPLandroid/view/WindowManagerImpl;-><init>(Landroid/content/Context;Landroid/view/Window;Landroid/os/IBinder;)V
 HSPLandroid/view/WindowManagerImpl;->addView(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
@@ -18488,7 +18577,7 @@
 HSPLandroid/view/WindowManagerImpl;->getMaximumWindowMetrics()Landroid/view/WindowMetrics;
 HSPLandroid/view/WindowManagerImpl;->removeView(Landroid/view/View;)V
 HSPLandroid/view/WindowManagerImpl;->removeViewImmediate(Landroid/view/View;)V
-HSPLandroid/view/WindowManagerImpl;->updateViewLayout(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
+HSPLandroid/view/WindowManagerImpl;->updateViewLayout(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/WindowManagerGlobal;Landroid/view/WindowManagerGlobal;
 HSPLandroid/view/WindowMetrics;-><init>(Landroid/graphics/Rect;Landroid/view/WindowInsets;)V
 HSPLandroid/view/WindowMetrics;-><init>(Landroid/graphics/Rect;Ljava/util/function/Supplier;F)V
 HSPLandroid/view/WindowMetrics;->getBounds()Landroid/graphics/Rect;
@@ -18530,8 +18619,8 @@
 HSPLandroid/view/accessibility/AccessibilityManager;->updateUiTimeout(J)V
 HSPLandroid/view/accessibility/AccessibilityNodeIdManager;-><init>()V
 HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->getInstance()Landroid/view/accessibility/AccessibilityNodeIdManager;
-HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->registerViewWithId(Landroid/view/View;I)V+]Landroid/view/accessibility/WeakSparseArray;Landroid/view/accessibility/WeakSparseArray;
-HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->unregisterViewWithId(I)V+]Landroid/view/accessibility/WeakSparseArray;Landroid/view/accessibility/WeakSparseArray;
+HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->registerViewWithId(Landroid/view/View;I)V
+HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->unregisterViewWithId(I)V
 HSPLandroid/view/accessibility/AccessibilityNodeInfo$AccessibilityAction;-><init>(ILjava/lang/CharSequence;)V
 HSPLandroid/view/accessibility/AccessibilityNodeInfo$AccessibilityAction;->equals(Ljava/lang/Object;)Z
 HSPLandroid/view/accessibility/AccessibilityNodeInfo$AccessibilityAction;->getId()I
@@ -18571,9 +18660,9 @@
 HSPLandroid/view/accessibility/IAccessibilityManagerClient$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/view/accessibility/WeakSparseArray$WeakReferenceWithId;-><init>(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;I)V
 HSPLandroid/view/accessibility/WeakSparseArray;-><init>()V
-HSPLandroid/view/accessibility/WeakSparseArray;->append(ILjava/lang/Object;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
-HSPLandroid/view/accessibility/WeakSparseArray;->remove(I)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
-HSPLandroid/view/accessibility/WeakSparseArray;->removeUnreachableValues()V+]Ljava/lang/ref/ReferenceQueue;Ljava/lang/ref/ReferenceQueue;
+HSPLandroid/view/accessibility/WeakSparseArray;->append(ILjava/lang/Object;)V
+HSPLandroid/view/accessibility/WeakSparseArray;->remove(I)V
+HSPLandroid/view/accessibility/WeakSparseArray;->removeUnreachableValues()V
 HSPLandroid/view/animation/AccelerateDecelerateInterpolator;-><init>()V
 HSPLandroid/view/animation/AccelerateDecelerateInterpolator;->createNativeInterpolator()J
 HSPLandroid/view/animation/AccelerateDecelerateInterpolator;->getInterpolation(F)F
@@ -18583,7 +18672,7 @@
 HSPLandroid/view/animation/AccelerateInterpolator;->getInterpolation(F)F
 HSPLandroid/view/animation/AlphaAnimation;-><init>(FF)V
 HSPLandroid/view/animation/AlphaAnimation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
-HSPLandroid/view/animation/AlphaAnimation;->applyTransformation(FLandroid/view/animation/Transformation;)V+]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;
+HSPLandroid/view/animation/AlphaAnimation;->applyTransformation(FLandroid/view/animation/Transformation;)V
 HSPLandroid/view/animation/AlphaAnimation;->hasAlpha()Z
 HSPLandroid/view/animation/AlphaAnimation;->willChangeBounds()Z
 HSPLandroid/view/animation/AlphaAnimation;->willChangeTransformationMatrix()Z
@@ -18592,7 +18681,7 @@
 HSPLandroid/view/animation/Animation$Description;-><init>()V
 HSPLandroid/view/animation/Animation$Description;->parseValue(Landroid/util/TypedValue;Landroid/content/Context;)Landroid/view/animation/Animation$Description;
 HSPLandroid/view/animation/Animation;-><init>()V
-HSPLandroid/view/animation/Animation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;
+HSPLandroid/view/animation/Animation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/view/animation/Animation;->cancel()V
 HSPLandroid/view/animation/Animation;->detach()V
 HSPLandroid/view/animation/Animation;->dispatchAnimationEnd()V
@@ -18601,12 +18690,12 @@
 HSPLandroid/view/animation/Animation;->finalize()V
 HSPLandroid/view/animation/Animation;->getDuration()J
 HSPLandroid/view/animation/Animation;->getFillAfter()Z
-HSPLandroid/view/animation/Animation;->getInvalidateRegion(IIIILandroid/graphics/RectF;Landroid/view/animation/Transformation;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;
+HSPLandroid/view/animation/Animation;->getInvalidateRegion(IIIILandroid/graphics/RectF;Landroid/view/animation/Transformation;)V
 HSPLandroid/view/animation/Animation;->getScaleFactor()F
 HSPLandroid/view/animation/Animation;->getStartOffset()J
-HSPLandroid/view/animation/Animation;->getTransformation(JLandroid/view/animation/Transformation;)Z+]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
-HSPLandroid/view/animation/Animation;->getTransformation(JLandroid/view/animation/Transformation;F)Z+]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;
-HSPLandroid/view/animation/Animation;->getTransformationAt(FLandroid/view/animation/Transformation;)V+]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;]Landroid/view/animation/Interpolator;Landroid/view/animation/AccelerateDecelerateInterpolator;,Landroid/view/animation/LinearInterpolator;
+HSPLandroid/view/animation/Animation;->getTransformation(JLandroid/view/animation/Transformation;)Z
+HSPLandroid/view/animation/Animation;->getTransformation(JLandroid/view/animation/Transformation;F)Z
+HSPLandroid/view/animation/Animation;->getTransformationAt(FLandroid/view/animation/Transformation;)V
 HSPLandroid/view/animation/Animation;->hasAlpha()Z
 HSPLandroid/view/animation/Animation;->hasEnded()Z
 HSPLandroid/view/animation/Animation;->hasStarted()Z
@@ -18663,7 +18752,7 @@
 HSPLandroid/view/animation/AnimationUtils$AnimationState;-><init>(Landroid/view/animation/AnimationUtils$AnimationState-IA;)V
 HSPLandroid/view/animation/AnimationUtils;->createAnimationFromXml(Landroid/content/Context;Lorg/xmlpull/v1/XmlPullParser;)Landroid/view/animation/Animation;
 HSPLandroid/view/animation/AnimationUtils;->createAnimationFromXml(Landroid/content/Context;Lorg/xmlpull/v1/XmlPullParser;Landroid/view/animation/AnimationSet;Landroid/util/AttributeSet;)Landroid/view/animation/Animation;
-HSPLandroid/view/animation/AnimationUtils;->createInterpolatorFromXml(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Lorg/xmlpull/v1/XmlPullParser;)Landroid/view/animation/Interpolator;+]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/view/animation/AnimationUtils;->createInterpolatorFromXml(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Lorg/xmlpull/v1/XmlPullParser;)Landroid/view/animation/Interpolator;
 HSPLandroid/view/animation/AnimationUtils;->currentAnimationTimeMillis()J
 HSPLandroid/view/animation/AnimationUtils;->loadAnimation(Landroid/content/Context;I)Landroid/view/animation/Animation;
 HSPLandroid/view/animation/AnimationUtils;->loadInterpolator(Landroid/content/Context;I)Landroid/view/animation/Interpolator;
@@ -18689,7 +18778,7 @@
 HSPLandroid/view/animation/PathInterpolator;->createNativeInterpolator()J
 HSPLandroid/view/animation/PathInterpolator;->getInterpolation(F)F
 HSPLandroid/view/animation/PathInterpolator;->initCubic(FFFF)V
-HSPLandroid/view/animation/PathInterpolator;->initPath(Landroid/graphics/Path;)V
+HSPLandroid/view/animation/PathInterpolator;->initPath(Landroid/graphics/Path;)V+]Landroid/graphics/Path;Landroid/graphics/Path;
 HSPLandroid/view/animation/PathInterpolator;->parseInterpolatorFromTypeArray(Landroid/content/res/TypedArray;)V
 HSPLandroid/view/animation/ScaleAnimation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/view/animation/ScaleAnimation;->applyTransformation(FLandroid/view/animation/Transformation;)V
@@ -18697,13 +18786,13 @@
 HSPLandroid/view/animation/ScaleAnimation;->initializePivotPoint()V
 HSPLandroid/view/animation/ScaleAnimation;->resolveScale(FIIII)F
 HSPLandroid/view/animation/Transformation;-><init>()V
-HSPLandroid/view/animation/Transformation;->clear()V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/view/animation/Transformation;->clear()V
 HSPLandroid/view/animation/Transformation;->compose(Landroid/view/animation/Transformation;)V
 HSPLandroid/view/animation/Transformation;->getAlpha()F
 HSPLandroid/view/animation/Transformation;->getInsets()Landroid/graphics/Insets;
 HSPLandroid/view/animation/Transformation;->getMatrix()Landroid/graphics/Matrix;
 HSPLandroid/view/animation/Transformation;->getTransformationType()I
-HSPLandroid/view/animation/Transformation;->set(Landroid/view/animation/Transformation;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;
+HSPLandroid/view/animation/Transformation;->set(Landroid/view/animation/Transformation;)V
 HSPLandroid/view/animation/Transformation;->setAlpha(F)V
 HSPLandroid/view/animation/Transformation;->setInsets(Landroid/graphics/Insets;)V
 HSPLandroid/view/animation/TranslateAnimation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
@@ -18776,7 +18865,7 @@
 HSPLandroid/view/autofill/AutofillManager;->isActiveLocked()Z
 HSPLandroid/view/autofill/AutofillManager;->isDisabledByServiceLocked()Z
 HSPLandroid/view/autofill/AutofillManager;->isEnabled()Z
-HSPLandroid/view/autofill/AutofillManager;->notifyValueChanged(Landroid/view/View;)V+]Landroid/view/autofill/AutofillManager;Landroid/view/autofill/AutofillManager;
+HSPLandroid/view/autofill/AutofillManager;->notifyValueChanged(Landroid/view/View;)V
 HSPLandroid/view/autofill/AutofillManager;->notifyViewEntered(Landroid/view/View;I)V
 HSPLandroid/view/autofill/AutofillManager;->notifyViewEnteredForAugmentedAutofill(Landroid/view/View;)V
 HSPLandroid/view/autofill/AutofillManager;->notifyViewEnteredForFillDialog(Landroid/view/View;)V
@@ -18808,6 +18897,7 @@
 HSPLandroid/view/autofill/IAugmentedAutofillManagerClient$Stub;->asBinder()Landroid/os/IBinder;
 HSPLandroid/view/autofill/IAugmentedAutofillManagerClient$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;->addClient(Landroid/view/autofill/IAutoFillManagerClient;Landroid/content/ComponentName;ILcom/android/internal/os/IResultReceiver;)V
 HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;->cancelSession(II)V
 HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;->getAutofillServiceComponentName(Lcom/android/internal/os/IResultReceiver;)V
@@ -19048,7 +19138,7 @@
 HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onPostWindowGainedFocus(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;)V
 HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onPreWindowGainedFocus(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onScheduledCheckFocus(Landroid/view/ViewRootImpl;)V
-HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onViewDetachedFromWindow(Landroid/view/View;Landroid/view/ViewRootImpl;)V+]Landroid/view/View;missing_types
+HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onViewDetachedFromWindow(Landroid/view/View;Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onWindowDismissed(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->setCurrentRootViewLocked(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/inputmethod/InputMethodManager$H$$ExternalSyntheticLambda0;->run()V
@@ -19375,17 +19465,17 @@
 HSPLandroid/widget/AbsListView$DeviceConfigChangeListener;-><init>()V
 HSPLandroid/widget/AbsListView$DeviceConfigChangeListener;-><init>(Landroid/widget/AbsListView$DeviceConfigChangeListener-IA;)V
 HSPLandroid/widget/AbsListView$PerformClick;->run()V
-HSPLandroid/widget/AbsListView$RecycleBin;->addScrapView(Landroid/view/View;I)V+]Landroid/view/View;Landroid/widget/LinearLayout;]Landroid/widget/AbsListView$RecycleBin;Landroid/widget/AbsListView$RecycleBin;]Landroid/widget/AbsListView;Landroid/widget/ListView;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/AbsListView$RecycleBin;->addScrapView(Landroid/view/View;I)V
 HSPLandroid/widget/AbsListView$RecycleBin;->clear()V
 HSPLandroid/widget/AbsListView$RecycleBin;->clearTransientStateViews()V
 HSPLandroid/widget/AbsListView$RecycleBin;->fillActiveViews(II)V
 HSPLandroid/widget/AbsListView$RecycleBin;->getActiveView(I)Landroid/view/View;
-HSPLandroid/widget/AbsListView$RecycleBin;->getScrapView(I)Landroid/view/View;+]Landroid/widget/ListAdapter;missing_types
+HSPLandroid/widget/AbsListView$RecycleBin;->getScrapView(I)Landroid/view/View;
 HSPLandroid/widget/AbsListView$RecycleBin;->getTransientStateView(I)Landroid/view/View;
 HSPLandroid/widget/AbsListView$RecycleBin;->markChildrenDirty()V
 HSPLandroid/widget/AbsListView$RecycleBin;->pruneScrapViews()V
 HSPLandroid/widget/AbsListView$RecycleBin;->removeSkippedScrap()V
-HSPLandroid/widget/AbsListView$RecycleBin;->retrieveFromScrap(Ljava/util/ArrayList;I)Landroid/view/View;+]Landroid/view/View;Landroid/widget/LinearLayout;]Landroid/widget/ListAdapter;Landroid/preference/PreferenceGroupAdapter;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/AbsListView$RecycleBin;->retrieveFromScrap(Ljava/util/ArrayList;I)Landroid/view/View;
 HSPLandroid/widget/AbsListView$RecycleBin;->scrapActiveViews()V
 HSPLandroid/widget/AbsListView$RecycleBin;->setViewTypeCount(I)V
 HSPLandroid/widget/AbsListView$RecycleBin;->shouldRecycleViewType(I)Z
@@ -19395,12 +19485,12 @@
 HSPLandroid/widget/AbsListView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V
 HSPLandroid/widget/AbsListView;->checkLayoutParams(Landroid/view/ViewGroup$LayoutParams;)Z
 HSPLandroid/widget/AbsListView;->clearChoices()V
-HSPLandroid/widget/AbsListView;->computeVerticalScrollExtent()I+]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/widget/AbsListView;missing_types
-HSPLandroid/widget/AbsListView;->computeVerticalScrollOffset()I+]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/widget/AbsListView;missing_types
+HSPLandroid/widget/AbsListView;->computeVerticalScrollExtent()I
+HSPLandroid/widget/AbsListView;->computeVerticalScrollOffset()I
 HSPLandroid/widget/AbsListView;->computeVerticalScrollRange()I
 HSPLandroid/widget/AbsListView;->dispatchDraw(Landroid/graphics/Canvas;)V
 HSPLandroid/widget/AbsListView;->dispatchSetPressed(Z)V
-HSPLandroid/widget/AbsListView;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/widget/AbsListView;missing_types]Landroid/widget/EdgeEffect;Landroid/widget/EdgeEffect;
+HSPLandroid/widget/AbsListView;->draw(Landroid/graphics/Canvas;)V
 HSPLandroid/widget/AbsListView;->drawableStateChanged()V
 HSPLandroid/widget/AbsListView;->generateDefaultLayoutParams()Landroid/view/ViewGroup$LayoutParams;
 HSPLandroid/widget/AbsListView;->generateLayoutParams(Landroid/util/AttributeSet;)Landroid/view/ViewGroup$LayoutParams;
@@ -19418,7 +19508,7 @@
 HSPLandroid/widget/AbsListView;->isInFilterMode()Z
 HSPLandroid/widget/AbsListView;->isVerticalScrollBarHidden()Z
 HSPLandroid/widget/AbsListView;->jumpDrawablesToCurrentState()V
-HSPLandroid/widget/AbsListView;->obtainView(I[Z)Landroid/view/View;+]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/widget/AbsListView$RecycleBin;Landroid/widget/AbsListView$RecycleBin;]Landroid/widget/ListAdapter;missing_types
+HSPLandroid/widget/AbsListView;->obtainView(I[Z)Landroid/view/View;
 HSPLandroid/widget/AbsListView;->onAttachedToWindow()V
 HSPLandroid/widget/AbsListView;->onCancelPendingInputEvents()V
 HSPLandroid/widget/AbsListView;->onDetachedFromWindow()V
@@ -19428,9 +19518,9 @@
 HSPLandroid/widget/AbsListView;->onRtlPropertiesChanged(I)V
 HSPLandroid/widget/AbsListView;->onSaveInstanceState()Landroid/os/Parcelable;
 HSPLandroid/widget/AbsListView;->onTouchDown(Landroid/view/MotionEvent;)V
-HSPLandroid/widget/AbsListView;->onTouchEvent(Landroid/view/MotionEvent;)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/VelocityTracker;Landroid/view/VelocityTracker;]Landroid/widget/AbsListView;Landroid/widget/ListView;
+HSPLandroid/widget/AbsListView;->onTouchEvent(Landroid/view/MotionEvent;)Z
 HSPLandroid/widget/AbsListView;->onTouchModeChanged(Z)V
-HSPLandroid/widget/AbsListView;->onTouchMove(Landroid/view/MotionEvent;Landroid/view/MotionEvent;)V+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/View;Landroid/widget/LinearLayout;]Landroid/widget/AbsListView;Landroid/widget/ListView;
+HSPLandroid/widget/AbsListView;->onTouchMove(Landroid/view/MotionEvent;Landroid/view/MotionEvent;)V
 HSPLandroid/widget/AbsListView;->onTouchUp(Landroid/view/MotionEvent;)V
 HSPLandroid/widget/AbsListView;->onWindowFocusChanged(Z)V
 HSPLandroid/widget/AbsListView;->performItemClick(Landroid/view/View;IJ)Z
@@ -19445,7 +19535,7 @@
 HSPLandroid/widget/AbsListView;->setFastScrollEnabled(Z)V
 HSPLandroid/widget/AbsListView;->setFastScrollStyle(I)V
 HSPLandroid/widget/AbsListView;->setFrame(IIII)Z
-HSPLandroid/widget/AbsListView;->setItemViewLayoutParams(Landroid/view/View;I)V+]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/widget/AbsListView;missing_types]Landroid/widget/ListAdapter;missing_types
+HSPLandroid/widget/AbsListView;->setItemViewLayoutParams(Landroid/view/View;I)V
 HSPLandroid/widget/AbsListView;->setOnScrollListener(Landroid/widget/AbsListView$OnScrollListener;)V
 HSPLandroid/widget/AbsListView;->setScrollingCacheEnabled(Z)V
 HSPLandroid/widget/AbsListView;->setSelectionFromTop(II)V
@@ -19585,7 +19675,7 @@
 HSPLandroid/widget/EdgeEffect;->isFinished()Z
 HSPLandroid/widget/EdgeEffect;->onAbsorb(I)V
 HSPLandroid/widget/EdgeEffect;->onPull(FF)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
-HSPLandroid/widget/EdgeEffect;->onPullDistance(FF)F+]Landroid/widget/EdgeEffect;Landroid/widget/EdgeEffect;
+HSPLandroid/widget/EdgeEffect;->onPullDistance(FF)F
 HSPLandroid/widget/EdgeEffect;->onRelease()V
 HSPLandroid/widget/EdgeEffect;->setSize(II)V
 HSPLandroid/widget/EdgeEffect;->update()V
@@ -19610,7 +19700,7 @@
 HSPLandroid/widget/Editor$Blink;->cancel()V
 HSPLandroid/widget/Editor$Blink;->run()V
 HSPLandroid/widget/Editor$Blink;->uncancel()V
-HSPLandroid/widget/Editor$CursorAnchorInfoNotifier;->updatePosition(IIZZ)V
+HSPLandroid/widget/Editor$CursorAnchorInfoNotifier;->updatePosition(IIZZ)V+]Landroid/view/inputmethod/InputMethodManager;Landroid/view/inputmethod/InputMethodManager;
 HSPLandroid/widget/Editor$EditOperation;-><init>(Landroid/widget/Editor;Ljava/lang/String;ILjava/lang/String;Z)V
 HSPLandroid/widget/Editor$EditOperation;->commit()V
 HSPLandroid/widget/Editor$EditOperation;->forceMergeWith(Landroid/widget/Editor$EditOperation;)V
@@ -19654,10 +19744,10 @@
 HSPLandroid/widget/Editor$InsertionPointCursorController;->onTouchEvent(Landroid/view/MotionEvent;)V
 HSPLandroid/widget/Editor$InsertionPointCursorController;->show()V
 HSPLandroid/widget/Editor$PositionListener;->addSubscriber(Landroid/widget/Editor$TextViewPositionListener;Z)V
-HSPLandroid/widget/Editor$PositionListener;->onPreDraw()Z
+HSPLandroid/widget/Editor$PositionListener;->onPreDraw()Z+]Landroid/widget/Editor$TextViewPositionListener;Landroid/widget/Editor$CursorAnchorInfoNotifier;,Landroid/widget/Editor$InsertionHandleView;
 HSPLandroid/widget/Editor$PositionListener;->onScrollChanged()V
 HSPLandroid/widget/Editor$PositionListener;->removeSubscriber(Landroid/widget/Editor$TextViewPositionListener;)V
-HSPLandroid/widget/Editor$PositionListener;->updatePosition()V
+HSPLandroid/widget/Editor$PositionListener;->updatePosition()V+]Landroid/widget/TextView;Landroid/widget/EditText;
 HSPLandroid/widget/Editor$ProcessTextIntentActionsHandler;-><init>(Landroid/widget/Editor;)V
 HSPLandroid/widget/Editor$SelectionModifierCursorController;->getMinTouchOffset()I
 HSPLandroid/widget/Editor$SelectionModifierCursorController;->hide()V
@@ -19666,7 +19756,7 @@
 HSPLandroid/widget/Editor$SelectionModifierCursorController;->isDragAcceleratorActive()Z
 HSPLandroid/widget/Editor$SelectionModifierCursorController;->isSelectionStartDragged()Z
 HSPLandroid/widget/Editor$SelectionModifierCursorController;->onDetached()V
-HSPLandroid/widget/Editor$SelectionModifierCursorController;->onTouchEvent(Landroid/view/MotionEvent;)V
+HSPLandroid/widget/Editor$SelectionModifierCursorController;->onTouchEvent(Landroid/view/MotionEvent;)V+]Landroid/widget/EditorTouchState;Landroid/widget/EditorTouchState;]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/widget/Editor$SelectionModifierCursorController;Landroid/widget/Editor$SelectionModifierCursorController;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
 HSPLandroid/widget/Editor$SelectionModifierCursorController;->resetDragAcceleratorState()V
 HSPLandroid/widget/Editor$SelectionModifierCursorController;->resetTouchOffsets()V
 HSPLandroid/widget/Editor$SelectionModifierCursorController;->updateSelection(Landroid/view/MotionEvent;)V
@@ -19674,7 +19764,7 @@
 HSPLandroid/widget/Editor$SpanController;->onSpanAdded(Landroid/text/Spannable;Ljava/lang/Object;II)V
 HSPLandroid/widget/Editor$SpanController;->onSpanChanged(Landroid/text/Spannable;Ljava/lang/Object;IIII)V
 HSPLandroid/widget/Editor$SpanController;->onSpanRemoved(Landroid/text/Spannable;Ljava/lang/Object;II)V
-HSPLandroid/widget/Editor$TextRenderNode;->needsRecord()Z
+HSPLandroid/widget/Editor$TextRenderNode;->needsRecord()Z+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/widget/Editor$UndoInputFilter;->beginBatchEdit()V
 HSPLandroid/widget/Editor$UndoInputFilter;->canUndoEdit(Ljava/lang/CharSequence;IILandroid/text/Spanned;II)Z
 HSPLandroid/widget/Editor$UndoInputFilter;->endBatchEdit()V
@@ -19695,7 +19785,7 @@
 HSPLandroid/widget/Editor;->createInputMethodStateIfNeeded()V
 HSPLandroid/widget/Editor;->discardTextDisplayLists()V
 HSPLandroid/widget/Editor;->downgradeEasyCorrectionSpans()V
-HSPLandroid/widget/Editor;->drawHardwareAcceleratedInner(Landroid/graphics/Canvas;Landroid/text/Layout;Landroid/graphics/Path;Landroid/graphics/Paint;I[I[IIII)I
+HSPLandroid/widget/Editor;->drawHardwareAcceleratedInner(Landroid/graphics/Canvas;Landroid/text/Layout;Landroid/graphics/Path;Landroid/graphics/Paint;I[I[IIII)I+]Landroid/widget/Editor$TextRenderNode;Landroid/widget/Editor$TextRenderNode;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/text/Layout;Landroid/text/DynamicLayout;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/widget/Editor;->endBatchEdit()V
 HSPLandroid/widget/Editor;->ensureEndedBatchEdit()V
 HSPLandroid/widget/Editor;->ensureNoSelectionIfNonSelectable()V
@@ -19731,10 +19821,10 @@
 HSPLandroid/widget/Editor;->onLocaleChanged()V
 HSPLandroid/widget/Editor;->onScreenStateChanged(I)V
 HSPLandroid/widget/Editor;->onScrollChanged()V
-HSPLandroid/widget/Editor;->onTouchEvent(Landroid/view/MotionEvent;)V
+HSPLandroid/widget/Editor;->onTouchEvent(Landroid/view/MotionEvent;)V+]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/EditorTouchState;Landroid/widget/EditorTouchState;]Landroid/widget/Editor$SelectionModifierCursorController;Landroid/widget/Editor$SelectionModifierCursorController;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
 HSPLandroid/widget/Editor;->onTouchUpEvent(Landroid/view/MotionEvent;)V
 HSPLandroid/widget/Editor;->onWindowFocusChanged(Z)V
-HSPLandroid/widget/Editor;->prepareCursorControllers()V
+HSPLandroid/widget/Editor;->prepareCursorControllers()V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/widget/Editor;Landroid/widget/Editor;
 HSPLandroid/widget/Editor;->refreshTextActionMode()V
 HSPLandroid/widget/Editor;->reportExtractedText()Z
 HSPLandroid/widget/Editor;->restoreInstanceState(Landroid/os/ParcelableParcel;)V
@@ -19759,19 +19849,19 @@
 HSPLandroid/widget/EditorTouchState;->isMovedEnoughForDrag()Z
 HSPLandroid/widget/EditorTouchState;->isMultiTap()Z
 HSPLandroid/widget/EditorTouchState;->isMultiTapInSameArea()Z
-HSPLandroid/widget/EditorTouchState;->update(Landroid/view/MotionEvent;Landroid/view/ViewConfiguration;)V
+HSPLandroid/widget/EditorTouchState;->update(Landroid/view/MotionEvent;Landroid/view/ViewConfiguration;)V+]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
 HSPLandroid/widget/Filter;-><init>()V
 HSPLandroid/widget/ForwardingListener;-><init>(Landroid/view/View;)V
 HSPLandroid/widget/ForwardingListener;->onViewAttachedToWindow(Landroid/view/View;)V
 HSPLandroid/widget/ForwardingListener;->onViewDetachedFromWindow(Landroid/view/View;)V
 HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(II)V
 HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(III)V
-HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
+HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(Landroid/view/ViewGroup$LayoutParams;)V
 HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;)V
 HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/widget/FrameLayout;missing_types
+HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V
 HSPLandroid/widget/FrameLayout;->checkLayoutParams(Landroid/view/ViewGroup$LayoutParams;)Z
 HSPLandroid/widget/FrameLayout;->generateDefaultLayoutParams()Landroid/view/ViewGroup$LayoutParams;
 HSPLandroid/widget/FrameLayout;->generateDefaultLayoutParams()Landroid/widget/FrameLayout$LayoutParams;
@@ -19785,7 +19875,7 @@
 HSPLandroid/widget/FrameLayout;->getPaddingTopWithForeground()I+]Landroid/widget/FrameLayout;missing_types
 HSPLandroid/widget/FrameLayout;->layoutChildren(IIIIZ)V+]Landroid/view/View;missing_types]Landroid/widget/FrameLayout;missing_types
 HSPLandroid/widget/FrameLayout;->onLayout(ZIIII)V+]Landroid/widget/FrameLayout;missing_types
-HSPLandroid/widget/FrameLayout;->onMeasure(II)V+]Landroid/view/View;missing_types]Landroid/widget/FrameLayout;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/FrameLayout;->onMeasure(II)V+]Landroid/widget/FrameLayout;missing_types]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/widget/FrameLayout;->setForegroundGravity(I)V
 HSPLandroid/widget/FrameLayout;->setMeasureAllChildren(Z)V
 HSPLandroid/widget/FrameLayout;->shouldDelayChildPressedState()Z
@@ -19882,13 +19972,13 @@
 HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;)V
 HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
 HSPLandroid/widget/ImageView;->applyAlpha()V
 HSPLandroid/widget/ImageView;->applyColorFilter()V
-HSPLandroid/widget/ImageView;->applyImageTint()V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/widget/ImageView;->applyImageTint()V
 HSPLandroid/widget/ImageView;->applyXfermode()V
 HSPLandroid/widget/ImageView;->clearColorFilter()V
-HSPLandroid/widget/ImageView;->configureBounds()V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->configureBounds()V
 HSPLandroid/widget/ImageView;->drawableHotspotChanged(FF)V
 HSPLandroid/widget/ImageView;->drawableStateChanged()V
 HSPLandroid/widget/ImageView;->getAccessibilityClassName()Ljava/lang/CharSequence;
@@ -19897,21 +19987,21 @@
 HSPLandroid/widget/ImageView;->getImageMatrix()Landroid/graphics/Matrix;
 HSPLandroid/widget/ImageView;->getScaleType()Landroid/widget/ImageView$ScaleType;
 HSPLandroid/widget/ImageView;->hasOverlappingRendering()Z
-HSPLandroid/widget/ImageView;->initImageView()V+]Landroid/widget/ImageView;missing_types
-HSPLandroid/widget/ImageView;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->initImageView()V
+HSPLandroid/widget/ImageView;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/ImageView;->isFilledByImage()Z
-HSPLandroid/widget/ImageView;->isOpaque()Z+]Landroid/graphics/drawable/Drawable;megamorphic_types
-HSPLandroid/widget/ImageView;->jumpDrawablesToCurrentState()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/widget/ImageView;->isOpaque()Z
+HSPLandroid/widget/ImageView;->jumpDrawablesToCurrentState()V
 HSPLandroid/widget/ImageView;->onAttachedToWindow()V
 HSPLandroid/widget/ImageView;->onCreateDrawableState(I)[I
 HSPLandroid/widget/ImageView;->onDetachedFromWindow()V
-HSPLandroid/widget/ImageView;->onDraw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/Drawable;missing_types
-HSPLandroid/widget/ImageView;->onMeasure(II)V+]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->onDraw(Landroid/graphics/Canvas;)V
+HSPLandroid/widget/ImageView;->onMeasure(II)V
 HSPLandroid/widget/ImageView;->onRtlPropertiesChanged(I)V
-HSPLandroid/widget/ImageView;->onVisibilityAggregated(Z)V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/widget/ImageView;->onVisibilityAggregated(Z)V
 HSPLandroid/widget/ImageView;->resizeFromDrawable()V
 HSPLandroid/widget/ImageView;->resolveAdjustedSize(III)I
-HSPLandroid/widget/ImageView;->resolveUri()V+]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->resolveUri()V
 HSPLandroid/widget/ImageView;->scaleTypeToScaleToFit(Landroid/widget/ImageView$ScaleType;)Landroid/graphics/Matrix$ScaleToFit;
 HSPLandroid/widget/ImageView;->setAdjustViewBounds(Z)V
 HSPLandroid/widget/ImageView;->setAlpha(I)V
@@ -19922,9 +20012,9 @@
 HSPLandroid/widget/ImageView;->setFrame(IIII)Z
 HSPLandroid/widget/ImageView;->setImageAlpha(I)V
 HSPLandroid/widget/ImageView;->setImageBitmap(Landroid/graphics/Bitmap;)V
-HSPLandroid/widget/ImageView;->setImageDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/widget/ImageView;missing_types
-HSPLandroid/widget/ImageView;->setImageMatrix(Landroid/graphics/Matrix;)V
-HSPLandroid/widget/ImageView;->setImageResource(I)V+]Landroid/widget/ImageView;Landroid/widget/ImageView;
+HSPLandroid/widget/ImageView;->setImageDrawable(Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/widget/ImageView;->setImageMatrix(Landroid/graphics/Matrix;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
+HSPLandroid/widget/ImageView;->setImageResource(I)V
 HSPLandroid/widget/ImageView;->setImageTintBlendMode(Landroid/graphics/BlendMode;)V
 HSPLandroid/widget/ImageView;->setImageTintList(Landroid/content/res/ColorStateList;)V
 HSPLandroid/widget/ImageView;->setMaxHeight(I)V
@@ -19932,16 +20022,16 @@
 HSPLandroid/widget/ImageView;->setScaleType(Landroid/widget/ImageView$ScaleType;)V
 HSPLandroid/widget/ImageView;->setSelected(Z)V
 HSPLandroid/widget/ImageView;->setVisibility(I)V
-HSPLandroid/widget/ImageView;->updateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->updateDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/ImageView;->verifyDrawable(Landroid/graphics/drawable/Drawable;)Z
 HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(II)V
 HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(IIF)V
-HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
+HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(Landroid/view/ViewGroup$LayoutParams;)V
 HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;)V
 HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/widget/LinearLayout;missing_types
+HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/widget/LinearLayout;Landroid/widget/LinearLayout;
 HSPLandroid/widget/LinearLayout;->allViewsAreGoneBefore(I)Z
 HSPLandroid/widget/LinearLayout;->checkLayoutParams(Landroid/view/ViewGroup$LayoutParams;)Z
 HSPLandroid/widget/LinearLayout;->forceUniformHeight(II)V
@@ -19963,8 +20053,8 @@
 HSPLandroid/widget/LinearLayout;->getVirtualChildAt(I)Landroid/view/View;+]Landroid/widget/LinearLayout;missing_types
 HSPLandroid/widget/LinearLayout;->getVirtualChildCount()I+]Landroid/widget/LinearLayout;missing_types
 HSPLandroid/widget/LinearLayout;->hasDividerBeforeChildAt(I)Z
-HSPLandroid/widget/LinearLayout;->layoutHorizontal(IIII)V+]Landroid/view/View;missing_types]Landroid/widget/LinearLayout;Landroid/widget/LinearLayout;
-HSPLandroid/widget/LinearLayout;->layoutVertical(IIII)V+]Landroid/view/View;megamorphic_types]Landroid/widget/LinearLayout;missing_types
+HSPLandroid/widget/LinearLayout;->layoutHorizontal(IIII)V
+HSPLandroid/widget/LinearLayout;->layoutVertical(IIII)V+]Landroid/view/View;missing_types]Landroid/widget/LinearLayout;missing_types
 HSPLandroid/widget/LinearLayout;->measureChildBeforeLayout(Landroid/view/View;IIIII)V+]Landroid/widget/LinearLayout;missing_types
 HSPLandroid/widget/LinearLayout;->measureHorizontal(II)V+]Landroid/view/View;missing_types]Landroid/widget/LinearLayout;Landroid/widget/LinearLayout;
 HSPLandroid/widget/LinearLayout;->measureVertical(II)V+]Landroid/view/View;megamorphic_types]Landroid/widget/LinearLayout;missing_types
@@ -19997,7 +20087,7 @@
 HSPLandroid/widget/ListView;->adjustViewsUpOrDown()V
 HSPLandroid/widget/ListView;->clearRecycledState(Ljava/util/ArrayList;)V
 HSPLandroid/widget/ListView;->correctTooHigh(I)V
-HSPLandroid/widget/ListView;->dispatchDraw(Landroid/graphics/Canvas;)V+]Landroid/view/View;Landroid/widget/LinearLayout;]Landroid/widget/ListAdapter;Landroid/preference/PreferenceGroupAdapter;]Landroid/widget/ListView;Landroid/widget/ListView;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/ListView;->dispatchDraw(Landroid/graphics/Canvas;)V
 HSPLandroid/widget/ListView;->drawChild(Landroid/graphics/Canvas;Landroid/view/View;J)Z
 HSPLandroid/widget/ListView;->fillDown(II)Landroid/view/View;
 HSPLandroid/widget/ListView;->fillFromTop(I)Landroid/view/View;
@@ -20013,8 +20103,8 @@
 HSPLandroid/widget/ListView;->layoutChildren()V
 HSPLandroid/widget/ListView;->lookForSelectablePosition(IZ)I
 HSPLandroid/widget/ListView;->makeAndAddView(IIZIZ)Landroid/view/View;
-HSPLandroid/widget/ListView;->measureHeightOfChildren(IIIII)I+]Landroid/view/View;Landroid/widget/CheckedTextView;]Landroid/widget/AbsListView$RecycleBin;Landroid/widget/AbsListView$RecycleBin;
-HSPLandroid/widget/ListView;->measureScrapChild(Landroid/view/View;III)V+]Landroid/view/View;Landroid/widget/CheckedTextView;
+HSPLandroid/widget/ListView;->measureHeightOfChildren(IIIII)I
+HSPLandroid/widget/ListView;->measureScrapChild(Landroid/view/View;III)V
 HSPLandroid/widget/ListView;->onDetachedFromWindow()V
 HSPLandroid/widget/ListView;->onFinishInflate()V
 HSPLandroid/widget/ListView;->onMeasure(II)V
@@ -20026,8 +20116,8 @@
 HSPLandroid/widget/ListView;->setCacheColorHint(I)V
 HSPLandroid/widget/ListView;->setDivider(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/ListView;->setSelection(I)V
-HSPLandroid/widget/ListView;->setupChild(Landroid/view/View;IIZIZZ)V+]Landroid/util/SparseBooleanArray;Landroid/util/SparseBooleanArray;]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/widget/Checkable;Landroid/widget/CheckedTextView;]Landroid/widget/ListAdapter;missing_types]Landroid/widget/ListView;missing_types
-HSPLandroid/widget/OverScroller$SplineOverScroller;-><init>(Landroid/content/Context;)V
+HSPLandroid/widget/ListView;->setupChild(Landroid/view/View;IIZIZZ)V
+HSPLandroid/widget/OverScroller$SplineOverScroller;-><init>(Landroid/content/Context;)V+]Landroid/content/res/Resources;Landroid/content/res/Resources;
 HSPLandroid/widget/OverScroller$SplineOverScroller;->adjustDuration(III)V
 HSPLandroid/widget/OverScroller$SplineOverScroller;->continueWhenFinished()Z
 HSPLandroid/widget/OverScroller$SplineOverScroller;->finish()V
@@ -20039,13 +20129,14 @@
 HSPLandroid/widget/OverScroller$SplineOverScroller;->startScroll(III)V
 HSPLandroid/widget/OverScroller$SplineOverScroller;->startSpringback(III)V
 HSPLandroid/widget/OverScroller$SplineOverScroller;->update()Z
+HSPLandroid/widget/OverScroller$SplineOverScroller;->updateScroll(F)V
 HSPLandroid/widget/OverScroller;-><init>(Landroid/content/Context;)V
 HSPLandroid/widget/OverScroller;-><init>(Landroid/content/Context;Landroid/view/animation/Interpolator;)V
 HSPLandroid/widget/OverScroller;-><init>(Landroid/content/Context;Landroid/view/animation/Interpolator;Z)V
 HSPLandroid/widget/OverScroller;->abortAnimation()V
 HSPLandroid/widget/OverScroller;->computeScrollOffset()Z
 HSPLandroid/widget/OverScroller;->fling(IIIIIIII)V
-HSPLandroid/widget/OverScroller;->fling(IIIIIIIIII)V
+HSPLandroid/widget/OverScroller;->fling(IIIIIIIIII)V+]Landroid/widget/OverScroller;Landroid/widget/OverScroller;]Landroid/widget/OverScroller$SplineOverScroller;Landroid/widget/OverScroller$SplineOverScroller;
 HSPLandroid/widget/OverScroller;->forceFinished(Z)V
 HSPLandroid/widget/OverScroller;->getCurrVelocity()F
 HSPLandroid/widget/OverScroller;->getCurrX()I
@@ -20133,7 +20224,7 @@
 HSPLandroid/widget/ProgressBar;->getProgress()I
 HSPLandroid/widget/ProgressBar;->getProgressDrawable()Landroid/graphics/drawable/Drawable;
 HSPLandroid/widget/ProgressBar;->initProgressBar()V
-HSPLandroid/widget/ProgressBar;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/widget/ProgressBar;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/GradientDrawable;,Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;
 HSPLandroid/widget/ProgressBar;->isIndeterminate()Z
 HSPLandroid/widget/ProgressBar;->jumpDrawablesToCurrentState()V
 HSPLandroid/widget/ProgressBar;->needsTileify(Landroid/graphics/drawable/Drawable;)Z
@@ -20173,8 +20264,8 @@
 HSPLandroid/widget/RelativeLayout$DependencyGraph;-><init>()V
 HSPLandroid/widget/RelativeLayout$DependencyGraph;->add(Landroid/view/View;)V
 HSPLandroid/widget/RelativeLayout$DependencyGraph;->clear()V
-HSPLandroid/widget/RelativeLayout$DependencyGraph;->findRoots([I)Ljava/util/ArrayDeque;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/View;Landroid/widget/TextView;]Ljava/util/ArrayDeque;Ljava/util/ArrayDeque;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/widget/RelativeLayout$DependencyGraph;->getSortedViews([Landroid/view/View;[I)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/View;Landroid/widget/TextView;]Ljava/util/ArrayDeque;Ljava/util/ArrayDeque;
+HSPLandroid/widget/RelativeLayout$DependencyGraph;->findRoots([I)Ljava/util/ArrayDeque;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayDeque;Ljava/util/ArrayDeque;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/RelativeLayout$DependencyGraph;->getSortedViews([Landroid/view/View;[I)V
 HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fgetmBottom(Landroid/widget/RelativeLayout$LayoutParams;)I
 HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fgetmLeft(Landroid/widget/RelativeLayout$LayoutParams;)I
 HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fgetmRight(Landroid/widget/RelativeLayout$LayoutParams;)I
@@ -20182,7 +20273,7 @@
 HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fputmBottom(Landroid/widget/RelativeLayout$LayoutParams;I)V
 HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fputmTop(Landroid/widget/RelativeLayout$LayoutParams;I)V
 HSPLandroid/widget/RelativeLayout$LayoutParams;-><init>(II)V
-HSPLandroid/widget/RelativeLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
+HSPLandroid/widget/RelativeLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
 HSPLandroid/widget/RelativeLayout$LayoutParams;->addRule(I)V
 HSPLandroid/widget/RelativeLayout$LayoutParams;->addRule(II)V
 HSPLandroid/widget/RelativeLayout$LayoutParams;->getRules()[I
@@ -20209,21 +20300,21 @@
 HSPLandroid/widget/RelativeLayout;->getAccessibilityClassName()Ljava/lang/CharSequence;
 HSPLandroid/widget/RelativeLayout;->getBaseline()I
 HSPLandroid/widget/RelativeLayout;->getChildMeasureSpec(IIIIIIII)I
-HSPLandroid/widget/RelativeLayout;->getRelatedView([II)Landroid/view/View;+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/View;Landroid/widget/TextView;
+HSPLandroid/widget/RelativeLayout;->getRelatedView([II)Landroid/view/View;
 HSPLandroid/widget/RelativeLayout;->getRelatedViewBaselineOffset([I)I
 HSPLandroid/widget/RelativeLayout;->getRelatedViewParams([II)Landroid/widget/RelativeLayout$LayoutParams;
 HSPLandroid/widget/RelativeLayout;->initFromAttributes(Landroid/content/Context;Landroid/util/AttributeSet;II)V
-HSPLandroid/widget/RelativeLayout;->measureChild(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;II)V+]Landroid/view/View;Landroid/widget/TextView;
-HSPLandroid/widget/RelativeLayout;->measureChildHorizontal(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;II)V+]Landroid/view/View;Landroid/widget/TextView;
+HSPLandroid/widget/RelativeLayout;->measureChild(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;II)V
+HSPLandroid/widget/RelativeLayout;->measureChildHorizontal(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;II)V
 HSPLandroid/widget/RelativeLayout;->onLayout(ZIIII)V
-HSPLandroid/widget/RelativeLayout;->onMeasure(II)V+]Landroid/view/View;Landroid/widget/TextView;]Landroid/widget/RelativeLayout$LayoutParams;Landroid/widget/RelativeLayout$LayoutParams;]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;
+HSPLandroid/widget/RelativeLayout;->onMeasure(II)V+]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;]Landroid/view/View;Landroid/widget/TextView;]Landroid/widget/RelativeLayout$LayoutParams;Landroid/widget/RelativeLayout$LayoutParams;
 HSPLandroid/widget/RelativeLayout;->positionAtEdge(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;I)V
-HSPLandroid/widget/RelativeLayout;->positionChildHorizontal(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;IZ)Z+]Landroid/view/View;Landroid/widget/TextView;]Landroid/widget/RelativeLayout$LayoutParams;Landroid/widget/RelativeLayout$LayoutParams;]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;
-HSPLandroid/widget/RelativeLayout;->positionChildVertical(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;IZ)Z+]Landroid/view/View;Landroid/widget/TextView;]Landroid/widget/RelativeLayout$LayoutParams;Landroid/widget/RelativeLayout$LayoutParams;
+HSPLandroid/widget/RelativeLayout;->positionChildHorizontal(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;IZ)Z
+HSPLandroid/widget/RelativeLayout;->positionChildVertical(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;IZ)Z
 HSPLandroid/widget/RelativeLayout;->queryCompatibilityModes(Landroid/content/Context;)V
 HSPLandroid/widget/RelativeLayout;->requestLayout()V
 HSPLandroid/widget/RelativeLayout;->shouldDelayChildPressedState()Z
-HSPLandroid/widget/RelativeLayout;->sortChildren()V+]Landroid/widget/RelativeLayout$DependencyGraph;Landroid/widget/RelativeLayout$DependencyGraph;]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;
+HSPLandroid/widget/RelativeLayout;->sortChildren()V+]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;]Landroid/widget/RelativeLayout$DependencyGraph;Landroid/widget/RelativeLayout$DependencyGraph;
 HSPLandroid/widget/RemoteViews$2;->createFromParcel(Landroid/os/Parcel;)Landroid/widget/RemoteViews;
 HSPLandroid/widget/RemoteViews$2;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/widget/RemoteViews$Action;-><init>()V
@@ -20299,15 +20390,15 @@
 HSPLandroid/widget/RtlSpacingHelper;->setDirection(Z)V
 HSPLandroid/widget/RtlSpacingHelper;->setRelative(II)V
 HSPLandroid/widget/ScrollBarDrawable;-><init>()V
-HSPLandroid/widget/ScrollBarDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;
-HSPLandroid/widget/ScrollBarDrawable;->drawThumb(Landroid/graphics/Canvas;Landroid/graphics/Rect;IIZ)V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
-HSPLandroid/widget/ScrollBarDrawable;->getSize(Z)I
-HSPLandroid/widget/ScrollBarDrawable;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
-HSPLandroid/widget/ScrollBarDrawable;->isStateful()Z
-HSPLandroid/widget/ScrollBarDrawable;->mutate()Landroid/widget/ScrollBarDrawable;
+HSPLandroid/widget/ScrollBarDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/widget/ScrollBarDrawable;->drawThumb(Landroid/graphics/Canvas;Landroid/graphics/Rect;IIZ)V
+HSPLandroid/widget/ScrollBarDrawable;->getSize(Z)I+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/widget/ScrollBarDrawable;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;
+HSPLandroid/widget/ScrollBarDrawable;->isStateful()Z+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/widget/ScrollBarDrawable;->mutate()Landroid/widget/ScrollBarDrawable;+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
 HSPLandroid/widget/ScrollBarDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
 HSPLandroid/widget/ScrollBarDrawable;->onStateChange([I)Z
-HSPLandroid/widget/ScrollBarDrawable;->propagateCurrentState(Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/widget/ScrollBarDrawable;->propagateCurrentState(Landroid/graphics/drawable/Drawable;)V+]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
 HSPLandroid/widget/ScrollBarDrawable;->setAlpha(I)V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
 HSPLandroid/widget/ScrollBarDrawable;->setAlwaysDrawVerticalTrack(Z)V
 HSPLandroid/widget/ScrollBarDrawable;->setHorizontalThumbDrawable(Landroid/graphics/drawable/Drawable;)V
@@ -20422,34 +20513,34 @@
 HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;)V
 HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/util/TypedValue;Landroid/util/TypedValue;]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/content/Context;missing_types]Landroid/widget/TextView;missing_types
 HSPLandroid/widget/TextView;->addSearchHighlightPaths()V
 HSPLandroid/widget/TextView;->addTextChangedListener(Landroid/text/TextWatcher;)V
 HSPLandroid/widget/TextView;->applyCompoundDrawableTint()V
 HSPLandroid/widget/TextView;->applySingleLine(ZZZZ)V
-HSPLandroid/widget/TextView;->applyTextAppearance(Landroid/widget/TextView$TextAppearanceAttributes;)V+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->applyTextAppearance(Landroid/widget/TextView$TextAppearanceAttributes;)V
 HSPLandroid/widget/TextView;->assumeLayout()V
 HSPLandroid/widget/TextView;->autoSizeText()V
 HSPLandroid/widget/TextView;->beginBatchEdit()V
 HSPLandroid/widget/TextView;->bringPointIntoView(I)Z
 HSPLandroid/widget/TextView;->bringPointIntoView(IZ)Z
-HSPLandroid/widget/TextView;->bringTextIntoView()Z+]Landroid/text/Layout;Landroid/text/BoringLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->bringTextIntoView()Z
 HSPLandroid/widget/TextView;->canMarquee()Z
 HSPLandroid/widget/TextView;->cancelLongPress()V
-HSPLandroid/widget/TextView;->checkForRelayout()V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->checkForRelayout()V
 HSPLandroid/widget/TextView;->checkForResize()V
 HSPLandroid/widget/TextView;->cleanupAutoSizePresetSizes([I)[I
-HSPLandroid/widget/TextView;->compressText(F)Z+]Landroid/text/Layout;Landroid/text/BoringLayout;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/widget/TextView;Landroid/widget/CheckedTextView;,Landroid/widget/TextView;
+HSPLandroid/widget/TextView;->compressText(F)Z
 HSPLandroid/widget/TextView;->computeHorizontalScrollRange()I
 HSPLandroid/widget/TextView;->computeScroll()V
-HSPLandroid/widget/TextView;->computeVerticalScrollExtent()I
-HSPLandroid/widget/TextView;->computeVerticalScrollRange()I
+HSPLandroid/widget/TextView;->computeVerticalScrollExtent()I+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->computeVerticalScrollRange()I+]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;
 HSPLandroid/widget/TextView;->convertToLocalHorizontalCoordinate(F)F
 HSPLandroid/widget/TextView;->createEditorIfNeeded()V
 HSPLandroid/widget/TextView;->didTouchFocusSelect()Z
 HSPLandroid/widget/TextView;->doKeyDown(ILandroid/view/KeyEvent;Landroid/view/KeyEvent;)I
 HSPLandroid/widget/TextView;->drawableHotspotChanged(FF)V
-HSPLandroid/widget/TextView;->drawableStateChanged()V+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->drawableStateChanged()V
 HSPLandroid/widget/TextView;->endBatchEdit()V
 HSPLandroid/widget/TextView;->findLargestTextSizeWhichFits(Landroid/graphics/RectF;)I
 HSPLandroid/widget/TextView;->fixFocusableAndClickableSettings()V
@@ -20458,10 +20549,10 @@
 HSPLandroid/widget/TextView;->getAutofillHints()[Ljava/lang/String;
 HSPLandroid/widget/TextView;->getAutofillType()I
 HSPLandroid/widget/TextView;->getAutofillValue()Landroid/view/autofill/AutofillValue;
-HSPLandroid/widget/TextView;->getBaseline()I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
-HSPLandroid/widget/TextView;->getBaselineOffset()I+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getBaseline()I
+HSPLandroid/widget/TextView;->getBaselineOffset()I
 HSPLandroid/widget/TextView;->getBottomVerticalOffset(Z)I
-HSPLandroid/widget/TextView;->getBoxHeight(Landroid/text/Layout;)I+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getBoxHeight(Landroid/text/Layout;)I+]Landroid/widget/TextView;Landroid/widget/EditText;,Landroid/widget/Button;
 HSPLandroid/widget/TextView;->getBreakStrategy()I
 HSPLandroid/widget/TextView;->getCompoundDrawablePadding()I
 HSPLandroid/widget/TextView;->getCompoundDrawables()[Landroid/graphics/drawable/Drawable;
@@ -20474,12 +20565,12 @@
 HSPLandroid/widget/TextView;->getDefaultEditable()Z
 HSPLandroid/widget/TextView;->getDefaultMovementMethod()Landroid/text/method/MovementMethod;
 HSPLandroid/widget/TextView;->getDesiredHeight()I
-HSPLandroid/widget/TextView;->getDesiredHeight(Landroid/text/Layout;Z)I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getDesiredHeight(Landroid/text/Layout;Z)I+]Landroid/text/Layout;Landroid/text/BoringLayout;]Landroid/widget/TextView;Landroid/widget/TextView;
 HSPLandroid/widget/TextView;->getEditableText()Landroid/text/Editable;
 HSPLandroid/widget/TextView;->getEllipsize()Landroid/text/TextUtils$TruncateAt;
 HSPLandroid/widget/TextView;->getError()Ljava/lang/CharSequence;
-HSPLandroid/widget/TextView;->getExtendedPaddingBottom()I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
-HSPLandroid/widget/TextView;->getExtendedPaddingTop()I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getExtendedPaddingBottom()I+]Landroid/text/Layout;Landroid/text/StaticLayout;]Landroid/widget/TextView;Landroid/widget/TextView;
+HSPLandroid/widget/TextView;->getExtendedPaddingTop()I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;,Landroid/text/DynamicLayout;]Landroid/widget/TextView;Landroid/widget/TextView;,Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/Button;
 HSPLandroid/widget/TextView;->getFilters()[Landroid/text/InputFilter;
 HSPLandroid/widget/TextView;->getFocusedRect(Landroid/graphics/Rect;)V
 HSPLandroid/widget/TextView;->getFreezesText()Z
@@ -20495,7 +20586,7 @@
 HSPLandroid/widget/TextView;->getJustificationMode()I
 HSPLandroid/widget/TextView;->getKeyListener()Landroid/text/method/KeyListener;
 HSPLandroid/widget/TextView;->getLayout()Landroid/text/Layout;
-HSPLandroid/widget/TextView;->getLayoutAlignment()Landroid/text/Layout$Alignment;+]Landroid/widget/TextView;Landroid/widget/TextView;
+HSPLandroid/widget/TextView;->getLayoutAlignment()Landroid/text/Layout$Alignment;
 HSPLandroid/widget/TextView;->getLineAtCoordinate(F)I
 HSPLandroid/widget/TextView;->getLineAtCoordinateUnclamped(F)I
 HSPLandroid/widget/TextView;->getLineCount()I
@@ -20511,14 +20602,14 @@
 HSPLandroid/widget/TextView;->getPaint()Landroid/text/TextPaint;
 HSPLandroid/widget/TextView;->getSelectionEnd()I
 HSPLandroid/widget/TextView;->getSelectionEndTransformed()I
-HSPLandroid/widget/TextView;->getSelectionStart()I
+HSPLandroid/widget/TextView;->getSelectionStart()I+]Landroid/widget/TextView;missing_types
 HSPLandroid/widget/TextView;->getSelectionStartTransformed()I
 HSPLandroid/widget/TextView;->getServiceManagerForUser(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
 HSPLandroid/widget/TextView;->getSpellCheckerLocale()Ljava/util/Locale;
 HSPLandroid/widget/TextView;->getText()Ljava/lang/CharSequence;
 HSPLandroid/widget/TextView;->getTextColors()Landroid/content/res/ColorStateList;
 HSPLandroid/widget/TextView;->getTextCursorDrawable()Landroid/graphics/drawable/Drawable;
-HSPLandroid/widget/TextView;->getTextDirectionHeuristic()Landroid/text/TextDirectionHeuristic;+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getTextDirectionHeuristic()Landroid/text/TextDirectionHeuristic;
 HSPLandroid/widget/TextView;->getTextLocale()Ljava/util/Locale;
 HSPLandroid/widget/TextView;->getTextLocales()Landroid/os/LocaleList;
 HSPLandroid/widget/TextView;->getTextSelectHandle()Landroid/graphics/drawable/Drawable;
@@ -20532,53 +20623,53 @@
 HSPLandroid/widget/TextView;->getTransformationMethod()Landroid/text/method/TransformationMethod;
 HSPLandroid/widget/TextView;->getTypeface()Landroid/graphics/Typeface;
 HSPLandroid/widget/TextView;->getTypefaceStyle()I
-HSPLandroid/widget/TextView;->getUpdatedHighlightPath()Landroid/graphics/Path;+]Landroid/widget/TextView;missing_types
-HSPLandroid/widget/TextView;->getVerticalOffset(Z)I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/widget/TextView;->getUpdatedHighlightPath()Landroid/graphics/Path;
+HSPLandroid/widget/TextView;->getVerticalOffset(Z)I
 HSPLandroid/widget/TextView;->handleBackInTextActionModeIfNeeded(Landroid/view/KeyEvent;)Z
 HSPLandroid/widget/TextView;->handleTextChanged(Ljava/lang/CharSequence;III)V
 HSPLandroid/widget/TextView;->hasGesturePreviewHighlight()Z
-HSPLandroid/widget/TextView;->hasOverlappingRendering()Z+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/widget/TextView;->hasOverlappingRendering()Z
 HSPLandroid/widget/TextView;->hasPasswordTransformationMethod()Z
 HSPLandroid/widget/TextView;->hasSelection()Z
 HSPLandroid/widget/TextView;->hideErrorIfUnchanged()V
 HSPLandroid/widget/TextView;->invalidateCursor()V
 HSPLandroid/widget/TextView;->invalidateCursorPath()V
-HSPLandroid/widget/TextView;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/ColorDrawable;,Landroid/graphics/drawable/GradientDrawable;,Landroid/graphics/drawable/RippleDrawable;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/widget/TextView;Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/Button;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/InsetDrawable;,Landroid/graphics/drawable/RippleDrawable;,Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/VectorDrawable;
 HSPLandroid/widget/TextView;->invalidateRegion(IIZ)V
 HSPLandroid/widget/TextView;->isAnyPasswordInputType()Z
 HSPLandroid/widget/TextView;->isAutoSizeEnabled()Z
 HSPLandroid/widget/TextView;->isAutofillable()Z
 HSPLandroid/widget/TextView;->isFallbackLineSpacingForStaticLayout()Z
-HSPLandroid/widget/TextView;->isFromPrimePointer(Landroid/view/MotionEvent;Z)Z
+HSPLandroid/widget/TextView;->isFromPrimePointer(Landroid/view/MotionEvent;Z)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
 HSPLandroid/widget/TextView;->isInBatchEditMode()Z
 HSPLandroid/widget/TextView;->isInExtractedMode()Z
 HSPLandroid/widget/TextView;->isInputMethodTarget()Z
 HSPLandroid/widget/TextView;->isMarqueeFadeEnabled()Z
 HSPLandroid/widget/TextView;->isMultilineInputType(I)Z
 HSPLandroid/widget/TextView;->isPasswordInputType(I)Z
-HSPLandroid/widget/TextView;->isPositionVisible(FF)Z
+HSPLandroid/widget/TextView;->isPositionVisible(FF)Z+]Landroid/view/View;missing_types]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
 HSPLandroid/widget/TextView;->isShowingHint()Z
 HSPLandroid/widget/TextView;->isSuggestionsEnabled()Z
 HSPLandroid/widget/TextView;->isTextAutofillable()Z
 HSPLandroid/widget/TextView;->isTextEditable()Z
 HSPLandroid/widget/TextView;->isTextSelectable()Z
 HSPLandroid/widget/TextView;->isVisibleToAccessibility()Z
-HSPLandroid/widget/TextView;->jumpDrawablesToCurrentState()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/widget/TextView;->jumpDrawablesToCurrentState()V
 HSPLandroid/widget/TextView;->length()I
-HSPLandroid/widget/TextView;->makeNewLayout(IILandroid/text/BoringLayout$Metrics;Landroid/text/BoringLayout$Metrics;IZ)V+]Landroid/text/Layout;Landroid/text/BoringLayout;]Landroid/widget/TextView;missing_types
-HSPLandroid/widget/TextView;->makeSingleLayout(ILandroid/text/BoringLayout$Metrics;ILandroid/text/Layout$Alignment;ZLandroid/text/TextUtils$TruncateAt;Z)Landroid/text/Layout;+]Landroid/text/BoringLayout;Landroid/text/BoringLayout;]Landroid/text/StaticLayout$Builder;Landroid/text/StaticLayout$Builder;]Landroid/widget/TextView;missing_types]Ljava/lang/CharSequence;Ljava/lang/String;
-HSPLandroid/widget/TextView;->maybeUpdateHighlightPaths()V+]Landroid/widget/TextView;missing_types]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/widget/TextView;->makeNewLayout(IILandroid/text/BoringLayout$Metrics;Landroid/text/BoringLayout$Metrics;IZ)V+]Landroid/text/BoringLayout;Landroid/text/BoringLayout;]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/TextView;Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/TextView;,Landroid/widget/Button;
+HSPLandroid/widget/TextView;->makeSingleLayout(ILandroid/text/BoringLayout$Metrics;ILandroid/text/Layout$Alignment;ZLandroid/text/TextUtils$TruncateAt;Z)Landroid/text/Layout;+]Landroid/text/DynamicLayout$Builder;Landroid/text/DynamicLayout$Builder;]Landroid/text/BoringLayout;Landroid/text/BoringLayout;]Landroid/widget/TextView;Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/TextView;]Ljava/lang/CharSequence;Ljava/lang/String;]Landroid/text/StaticLayout$Builder;Landroid/text/StaticLayout$Builder;
+HSPLandroid/widget/TextView;->maybeUpdateHighlightPaths()V
 HSPLandroid/widget/TextView;->notifyContentCaptureTextChanged()V
-HSPLandroid/widget/TextView;->notifyListeningManagersAfterTextChanged()V+]Landroid/view/autofill/AutofillManager;Landroid/view/autofill/AutofillManager;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->notifyListeningManagersAfterTextChanged()V
 HSPLandroid/widget/TextView;->nullLayouts()V
 HSPLandroid/widget/TextView;->onAttachedToWindow()V
 HSPLandroid/widget/TextView;->onBeginBatchEdit()V
 HSPLandroid/widget/TextView;->onCheckIsTextEditor()Z
 HSPLandroid/widget/TextView;->onConfigurationChanged(Landroid/content/res/Configuration;)V
-HSPLandroid/widget/TextView;->onCreateDrawableState(I)[I+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->onCreateDrawableState(I)[I
 HSPLandroid/widget/TextView;->onCreateInputConnection(Landroid/view/inputmethod/EditorInfo;)Landroid/view/inputmethod/InputConnection;
 HSPLandroid/widget/TextView;->onDetachedFromWindowInternal()V
-HSPLandroid/widget/TextView;->onDraw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->onDraw(Landroid/graphics/Canvas;)V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;,Landroid/text/DynamicLayout;]Landroid/widget/TextView;missing_types]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/widget/Editor;Landroid/widget/Editor;]Ljava/lang/CharSequence;Landroid/text/SpannableStringBuilder;
 HSPLandroid/widget/TextView;->onEditorAction(I)V
 HSPLandroid/widget/TextView;->onEndBatchEdit()V
 HSPLandroid/widget/TextView;->onFocusChanged(ZILandroid/graphics/Rect;)V
@@ -20589,7 +20680,7 @@
 HSPLandroid/widget/TextView;->onKeyUp(ILandroid/view/KeyEvent;)Z
 HSPLandroid/widget/TextView;->onLayout(ZIIII)V
 HSPLandroid/widget/TextView;->onLocaleChanged()V
-HSPLandroid/widget/TextView;->onMeasure(II)V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/DynamicLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->onMeasure(II)V+]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/TextView;,Landroid/widget/Button;
 HSPLandroid/widget/TextView;->onPreDraw()Z
 HSPLandroid/widget/TextView;->onProvideStructure(Landroid/view/ViewStructure;II)V
 HSPLandroid/widget/TextView;->onResolveDrawables(I)V
@@ -20606,7 +20697,7 @@
 HSPLandroid/widget/TextView;->onWindowFocusChanged(Z)V
 HSPLandroid/widget/TextView;->originalToTransformed(II)I
 HSPLandroid/widget/TextView;->preloadFontCache()V
-HSPLandroid/widget/TextView;->readTextAppearance(Landroid/content/Context;Landroid/content/res/TypedArray;Landroid/widget/TextView$TextAppearanceAttributes;Z)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Landroid/util/TypedValue;Landroid/util/TypedValue;
+HSPLandroid/widget/TextView;->readTextAppearance(Landroid/content/Context;Landroid/content/res/TypedArray;Landroid/widget/TextView$TextAppearanceAttributes;Z)V+]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Landroid/util/TypedValue;Landroid/util/TypedValue;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/content/Context;missing_types
 HSPLandroid/widget/TextView;->registerForPreDraw()V
 HSPLandroid/widget/TextView;->removeAdjacentSuggestionSpans(I)V
 HSPLandroid/widget/TextView;->removeIntersectingNonAdjacentSpans(IILjava/lang/Class;)V
@@ -20626,7 +20717,7 @@
 HSPLandroid/widget/TextView;->setBreakStrategy(I)V
 HSPLandroid/widget/TextView;->setCompoundDrawablePadding(I)V
 HSPLandroid/widget/TextView;->setCompoundDrawableTintList(Landroid/content/res/ColorStateList;)V
-HSPLandroid/widget/TextView;->setCompoundDrawables(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->setCompoundDrawables(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/TextView;->setCompoundDrawablesRelative(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/TextView;->setCompoundDrawablesRelativeWithIntrinsicBounds(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/TextView;->setCompoundDrawablesWithIntrinsicBounds(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
@@ -20656,7 +20747,7 @@
 HSPLandroid/widget/TextView;->setInputTypeSingleLine(Z)V
 HSPLandroid/widget/TextView;->setKeyListener(Landroid/text/method/KeyListener;)V
 HSPLandroid/widget/TextView;->setKeyListenerOnly(Landroid/text/method/KeyListener;)V
-HSPLandroid/widget/TextView;->setLetterSpacing(F)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
+HSPLandroid/widget/TextView;->setLetterSpacing(F)V
 HSPLandroid/widget/TextView;->setLineHeight(I)V
 HSPLandroid/widget/TextView;->setLineSpacing(FF)V
 HSPLandroid/widget/TextView;->setLines(I)V
@@ -20673,7 +20764,7 @@
 HSPLandroid/widget/TextView;->setPaddingRelative(IIII)V
 HSPLandroid/widget/TextView;->setPrivateImeOptions(Ljava/lang/String;)V
 HSPLandroid/widget/TextView;->setRawInputType(I)V
-HSPLandroid/widget/TextView;->setRawTextSize(FZ)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
+HSPLandroid/widget/TextView;->setRawTextSize(FZ)V
 HSPLandroid/widget/TextView;->setRelativeDrawablesIfNeeded(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/TextView;->setSelected(Z)V
 HSPLandroid/widget/TextView;->setShadowLayer(FFFI)V
@@ -20682,7 +20773,7 @@
 HSPLandroid/widget/TextView;->setText(I)V
 HSPLandroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
 HSPLandroid/widget/TextView;->setText(Ljava/lang/CharSequence;Landroid/widget/TextView$BufferType;)V
-HSPLandroid/widget/TextView;->setText(Ljava/lang/CharSequence;Landroid/widget/TextView$BufferType;ZI)V+]Landroid/text/Editable$Factory;Landroid/text/Editable$Factory;]Landroid/text/InputFilter;Landroid/text/InputFilter$LengthFilter;]Landroid/text/Spannable$Factory;Landroid/text/Spannable$Factory;]Landroid/text/Spannable;Landroid/text/SpannableString;,Landroid/text/SpannableStringBuilder;]Landroid/text/Spanned;Landroid/text/SpannableStringBuilder;,Landroid/text/SpannedString;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/text/method/MovementMethod;Landroid/text/method/ArrowKeyMovementMethod;,Landroid/text/method/LinkMovementMethod;]Landroid/text/method/TransformationMethod;Landroid/text/method/AllCapsTransformationMethod;,Landroid/text/method/SingleLineTransformationMethod;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/TextView;missing_types]Ljava/lang/CharSequence;Landroid/text/SpannableString;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannedString;,Ljava/lang/String;
+HSPLandroid/widget/TextView;->setText(Ljava/lang/CharSequence;Landroid/widget/TextView$BufferType;ZI)V+]Landroid/text/Editable$Factory;Landroid/text/Editable$Factory;]Landroid/text/method/MovementMethod;Landroid/text/method/ArrowKeyMovementMethod;,Landroid/text/method/ScrollingMovementMethod;]Landroid/text/method/TransformationMethod;Landroid/text/method/SingleLineTransformationMethod;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/text/InputFilter;Landroid/text/InputFilter$LengthFilter;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/text/Spanned;Landroid/text/SpannableString;]Landroid/text/Spannable$Factory;Landroid/text/Spannable$Factory;]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/text/Spannable;Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;
 HSPLandroid/widget/TextView;->setTextAppearance(I)V
 HSPLandroid/widget/TextView;->setTextAppearance(Landroid/content/Context;I)V
 HSPLandroid/widget/TextView;->setTextColor(I)V
@@ -20694,14 +20785,14 @@
 HSPLandroid/widget/TextView;->setTextSizeInternal(IFZ)V
 HSPLandroid/widget/TextView;->setTransformationMethod(Landroid/text/method/TransformationMethod;)V
 HSPLandroid/widget/TextView;->setTransformationMethodInternal(Landroid/text/method/TransformationMethod;Z)V
-HSPLandroid/widget/TextView;->setTypeface(Landroid/graphics/Typeface;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
-HSPLandroid/widget/TextView;->setTypeface(Landroid/graphics/Typeface;I)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->setTypeface(Landroid/graphics/Typeface;)V
+HSPLandroid/widget/TextView;->setTypeface(Landroid/graphics/Typeface;I)V
 HSPLandroid/widget/TextView;->setTypefaceFromAttrs(Landroid/graphics/Typeface;Ljava/lang/String;III)V
 HSPLandroid/widget/TextView;->setupAutoSizeText()Z
 HSPLandroid/widget/TextView;->setupAutoSizeUniformPresetSizesConfiguration()Z
 HSPLandroid/widget/TextView;->shouldAdvanceFocusOnEnter()Z
 HSPLandroid/widget/TextView;->spanChange(Landroid/text/Spanned;Ljava/lang/Object;IIII)V
-HSPLandroid/widget/TextView;->startMarquee()V+]Landroid/widget/TextView;Landroid/widget/CheckedTextView;,Landroid/widget/TextView;
+HSPLandroid/widget/TextView;->startMarquee()V
 HSPLandroid/widget/TextView;->startStopMarquee(Z)V
 HSPLandroid/widget/TextView;->stopMarquee()V
 HSPLandroid/widget/TextView;->stopTextActionMode()V
@@ -20711,8 +20802,8 @@
 HSPLandroid/widget/TextView;->unregisterForPreDraw()V
 HSPLandroid/widget/TextView;->updateAfterEdit()V
 HSPLandroid/widget/TextView;->updateCursorVisibleInternal()V
-HSPLandroid/widget/TextView;->updateTextColors()V+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/TextView;missing_types]Ljava/lang/CharSequence;Ljava/lang/String;
-HSPLandroid/widget/TextView;->useDynamicLayout()Z+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->updateTextColors()V
+HSPLandroid/widget/TextView;->useDynamicLayout()Z
 HSPLandroid/widget/TextView;->validateAndSetAutoSizeTextTypeUniformConfiguration(FFF)V
 HSPLandroid/widget/TextView;->verifyDrawable(Landroid/graphics/drawable/Drawable;)Z
 HSPLandroid/widget/TextView;->viewClicked(Landroid/view/inputmethod/InputMethodManager;)V
@@ -20773,6 +20864,7 @@
 HSPLandroid/widget/inline/InlinePresentationSpec;-><clinit>()V
 HSPLandroid/widget/inline/InlinePresentationSpec;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/widget/inline/InlinePresentationSpec;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/window/BackProgressAnimator;-><init>()V+]Lcom/android/internal/dynamicanimation/animation/SpringAnimation;Lcom/android/internal/dynamicanimation/animation/SpringAnimation;]Lcom/android/internal/dynamicanimation/animation/SpringForce;Lcom/android/internal/dynamicanimation/animation/SpringForce;
 HSPLandroid/window/ClientWindowFrames$1;-><init>()V
 HSPLandroid/window/ClientWindowFrames$1;->createFromParcel(Landroid/os/Parcel;)Landroid/window/ClientWindowFrames;
 HSPLandroid/window/ClientWindowFrames$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -20890,6 +20982,8 @@
 HSPLandroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper;->onBackCancelled()V
 HSPLandroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper;->onBackInvoked()V
 HSPLandroid/window/WindowOnBackInvokedDispatcher;-><clinit>()V
+HSPLandroid/window/WindowOnBackInvokedDispatcher;-><init>(Landroid/content/Context;)V
+HSPLandroid/window/WindowOnBackInvokedDispatcher;->attachToWindow(Landroid/view/IWindowSession;Landroid/view/IWindow;)V
 HSPLandroid/window/WindowOnBackInvokedDispatcher;->clear()V
 HSPLandroid/window/WindowOnBackInvokedDispatcher;->detachFromWindow()V
 HSPLandroid/window/WindowOnBackInvokedDispatcher;->getTopCallback()Landroid/window/OnBackInvokedCallback;
@@ -20925,12 +21019,12 @@
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getMetadataForRegionOrCallingCode(ILjava/lang/String;)Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNationalSignificantNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Ljava/lang/String;
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNumberDescByType(Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;)Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;
-HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNumberTypeHelper(Ljava/lang/String;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;)Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
+HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNumberTypeHelper(Ljava/lang/String;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;)Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;+]Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;]Lcom/android/i18n/phonenumbers/PhoneNumberUtil;Lcom/android/i18n/phonenumbers/PhoneNumberUtil;
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForCountryCode(I)Ljava/lang/String;
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Ljava/lang/String;
-HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForNumberFromRegionList(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;Ljava/util/List;)Ljava/lang/String;
+HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForNumberFromRegionList(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;Ljava/util/List;)Ljava/lang/String;+]Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;]Ljava/util/List;Ljava/util/ArrayList;]Lcom/android/i18n/phonenumbers/PhoneNumberUtil;Lcom/android/i18n/phonenumbers/PhoneNumberUtil;]Ljava/util/Iterator;Ljava/util/ArrayList$Itr;
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->hasFormattingPatternForNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Z
-HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isNumberMatchingDesc(Ljava/lang/String;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;)Z
+HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isNumberMatchingDesc(Ljava/lang/String;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;)Z+]Ljava/lang/String;Ljava/lang/String;]Lcom/android/i18n/phonenumbers/internal/MatcherApi;Lcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;]Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;]Ljava/util/List;Ljava/util/ArrayList;
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isValidNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Z
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isValidNumberForRegion(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;Ljava/lang/String;)Z
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isValidRegionCode(Ljava/lang/String;)Z
@@ -21035,8 +21129,8 @@
 HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->setCountryCodeSource(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource;)Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;
 HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->setNationalNumber(J)Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;
 HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->setRawInput(Ljava/lang/String;)Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;
-HSPLcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;->match(Ljava/lang/CharSequence;Ljava/util/regex/Pattern;Z)Z
-HSPLcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;->matchNationalNumber(Ljava/lang/CharSequence;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;Z)Z
+HSPLcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;->match(Ljava/lang/CharSequence;Ljava/util/regex/Pattern;Z)Z+]Ljava/util/regex/Matcher;Ljava/util/regex/Matcher;]Ljava/util/regex/Pattern;Ljava/util/regex/Pattern;
+HSPLcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;->matchNationalNumber(Ljava/lang/CharSequence;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;Z)Z+]Ljava/lang/String;Ljava/lang/String;]Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;]Lcom/android/i18n/phonenumbers/internal/RegexCache;Lcom/android/i18n/phonenumbers/internal/RegexCache;
 HSPLcom/android/i18n/phonenumbers/internal/RegexCache$LRUCache$1;->removeEldestEntry(Ljava/util/Map$Entry;)Z
 HSPLcom/android/i18n/phonenumbers/internal/RegexCache$LRUCache;->get(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLcom/android/i18n/phonenumbers/internal/RegexCache$LRUCache;->put(Ljava/lang/Object;Ljava/lang/Object;)V
@@ -21114,10 +21208,10 @@
 HSPLcom/android/i18n/timezone/internal/NioBufferIterator;->readLongArray([JII)V
 HSPLcom/android/i18n/timezone/internal/NioBufferIterator;->skip(I)V
 HSPLcom/android/icu/charset/CharsetDecoderICU;-><init>(Ljava/nio/charset/Charset;FJ)V
-HSPLcom/android/icu/charset/CharsetDecoderICU;->decodeLoop(Ljava/nio/ByteBuffer;Ljava/nio/CharBuffer;)Ljava/nio/charset/CoderResult;
-HSPLcom/android/icu/charset/CharsetDecoderICU;->getArray(Ljava/nio/ByteBuffer;)I
-HSPLcom/android/icu/charset/CharsetDecoderICU;->getArray(Ljava/nio/CharBuffer;)I
-HSPLcom/android/icu/charset/CharsetDecoderICU;->implFlush(Ljava/nio/CharBuffer;)Ljava/nio/charset/CoderResult;
+HSPLcom/android/icu/charset/CharsetDecoderICU;->decodeLoop(Ljava/nio/ByteBuffer;Ljava/nio/CharBuffer;)Ljava/nio/charset/CoderResult;+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
+HSPLcom/android/icu/charset/CharsetDecoderICU;->getArray(Ljava/nio/ByteBuffer;)I+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
+HSPLcom/android/icu/charset/CharsetDecoderICU;->getArray(Ljava/nio/CharBuffer;)I+]Ljava/nio/CharBuffer;Ljava/nio/HeapCharBuffer;
+HSPLcom/android/icu/charset/CharsetDecoderICU;->implFlush(Ljava/nio/CharBuffer;)Ljava/nio/charset/CoderResult;+]Lcom/android/icu/charset/CharsetDecoderICU;Lcom/android/icu/charset/CharsetDecoderICU;
 HSPLcom/android/icu/charset/CharsetDecoderICU;->implOnMalformedInput(Ljava/nio/charset/CodingErrorAction;)V
 HSPLcom/android/icu/charset/CharsetDecoderICU;->implOnUnmappableCharacter(Ljava/nio/charset/CodingErrorAction;)V
 HSPLcom/android/icu/charset/CharsetDecoderICU;->implReplaceWith(Ljava/lang/String;)V
@@ -21127,16 +21221,16 @@
 HSPLcom/android/icu/charset/CharsetDecoderICU;->setPosition(Ljava/nio/CharBuffer;)V
 HSPLcom/android/icu/charset/CharsetDecoderICU;->updateCallback()V
 HSPLcom/android/icu/charset/CharsetEncoderICU;-><init>(Ljava/nio/charset/Charset;FF[BJ)V
-HSPLcom/android/icu/charset/CharsetEncoderICU;->encodeLoop(Ljava/nio/CharBuffer;Ljava/nio/ByteBuffer;)Ljava/nio/charset/CoderResult;
-HSPLcom/android/icu/charset/CharsetEncoderICU;->getArray(Ljava/nio/ByteBuffer;)I
-HSPLcom/android/icu/charset/CharsetEncoderICU;->getArray(Ljava/nio/CharBuffer;)I
+HSPLcom/android/icu/charset/CharsetEncoderICU;->encodeLoop(Ljava/nio/CharBuffer;Ljava/nio/ByteBuffer;)Ljava/nio/charset/CoderResult;+]Ljava/nio/CharBuffer;Ljava/nio/HeapCharBuffer;
+HSPLcom/android/icu/charset/CharsetEncoderICU;->getArray(Ljava/nio/ByteBuffer;)I+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
+HSPLcom/android/icu/charset/CharsetEncoderICU;->getArray(Ljava/nio/CharBuffer;)I+]Ljava/nio/CharBuffer;Ljava/nio/HeapCharBuffer;
 HSPLcom/android/icu/charset/CharsetEncoderICU;->implFlush(Ljava/nio/ByteBuffer;)Ljava/nio/charset/CoderResult;
 HSPLcom/android/icu/charset/CharsetEncoderICU;->implOnMalformedInput(Ljava/nio/charset/CodingErrorAction;)V
 HSPLcom/android/icu/charset/CharsetEncoderICU;->implOnUnmappableCharacter(Ljava/nio/charset/CodingErrorAction;)V
 HSPLcom/android/icu/charset/CharsetEncoderICU;->implReset()V
 HSPLcom/android/icu/charset/CharsetEncoderICU;->makeReplacement(Ljava/lang/String;J)[B
 HSPLcom/android/icu/charset/CharsetEncoderICU;->newInstance(Ljava/nio/charset/Charset;Ljava/lang/String;)Lcom/android/icu/charset/CharsetEncoderICU;
-HSPLcom/android/icu/charset/CharsetEncoderICU;->setPosition(Ljava/nio/ByteBuffer;)V
+HSPLcom/android/icu/charset/CharsetEncoderICU;->setPosition(Ljava/nio/ByteBuffer;)V+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
 HSPLcom/android/icu/charset/CharsetEncoderICU;->setPosition(Ljava/nio/CharBuffer;)V
 HSPLcom/android/icu/charset/CharsetEncoderICU;->updateCallback()V
 HSPLcom/android/icu/charset/CharsetFactory;->create(Ljava/lang/String;)Ljava/nio/charset/Charset;
@@ -21176,7 +21270,7 @@
 HSPLcom/android/icu/util/LocaleNative;->getDisplayCountry(Ljava/util/Locale;Ljava/util/Locale;)Ljava/lang/String;
 HSPLcom/android/icu/util/LocaleNative;->getDisplayLanguage(Ljava/util/Locale;Ljava/util/Locale;)Ljava/lang/String;
 HSPLcom/android/icu/util/LocaleNative;->setDefault(Ljava/lang/String;)V
-HSPLcom/android/icu/util/regex/MatcherNative;-><init>(Lcom/android/icu/util/regex/PatternNative;)V
+HSPLcom/android/icu/util/regex/MatcherNative;-><init>(Lcom/android/icu/util/regex/PatternNative;)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;]Lcom/android/icu/util/regex/PatternNative;Lcom/android/icu/util/regex/PatternNative;
 HSPLcom/android/icu/util/regex/MatcherNative;->create(Lcom/android/icu/util/regex/PatternNative;)Lcom/android/icu/util/regex/MatcherNative;
 HSPLcom/android/icu/util/regex/MatcherNative;->find(I[I)Z
 HSPLcom/android/icu/util/regex/MatcherNative;->findNext([I)Z
@@ -21188,7 +21282,7 @@
 HSPLcom/android/icu/util/regex/MatcherNative;->setInput(Ljava/lang/String;II)V
 HSPLcom/android/icu/util/regex/MatcherNative;->useAnchoringBounds(Z)V
 HSPLcom/android/icu/util/regex/MatcherNative;->useTransparentBounds(Z)V
-HSPLcom/android/icu/util/regex/PatternNative;-><init>(Ljava/lang/String;I)V
+HSPLcom/android/icu/util/regex/PatternNative;-><init>(Ljava/lang/String;I)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
 HSPLcom/android/icu/util/regex/PatternNative;->create(Ljava/lang/String;I)Lcom/android/icu/util/regex/PatternNative;
 HSPLcom/android/icu/util/regex/PatternNative;->openMatcher()J
 HSPLcom/android/internal/app/AlertController;-><init>(Landroid/content/Context;Landroid/content/DialogInterface;Landroid/view/Window;)V
@@ -21272,6 +21366,8 @@
 HSPLcom/android/internal/content/ReferrerIntent$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLcom/android/internal/display/BrightnessSynchronizer;-><clinit>()V
 HSPLcom/android/internal/display/BrightnessSynchronizer;->floatEquals(FF)Z
+HSPLcom/android/internal/dynamicanimation/animation/DynamicAnimation;-><init>(Ljava/lang/Object;Landroid/util/FloatProperty;)V
+HSPLcom/android/internal/dynamicanimation/animation/SpringForce;-><init>()V
 HSPLcom/android/internal/graphics/ColorUtils;->HSLToColor([F)I
 HSPLcom/android/internal/graphics/ColorUtils;->RGBToHSL(III[F)V
 HSPLcom/android/internal/graphics/ColorUtils;->colorToHSL(I[F)V
@@ -21400,7 +21496,7 @@
 HSPLcom/android/internal/listeners/ListenerExecutor$ListenerOperation;->onPostExecute(Z)V
 HSPLcom/android/internal/listeners/ListenerExecutor$ListenerOperation;->onPreExecute()V
 HSPLcom/android/internal/listeners/ListenerExecutor;->executeSafely(Ljava/util/concurrent/Executor;Ljava/util/function/Supplier;Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;)V
-HSPLcom/android/internal/listeners/ListenerExecutor;->executeSafely(Ljava/util/concurrent/Executor;Ljava/util/function/Supplier;Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;Lcom/android/internal/listeners/ListenerExecutor$FailureCallback;)V+]Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;Landroid/telephony/TelephonyRegistryManager$CarrierPrivilegesCallbackWrapper$$ExternalSyntheticLambda2;,Landroid/telephony/TelephonyRegistryManager$CarrierPrivilegesCallbackWrapper$$ExternalSyntheticLambda3;]Ljava/util/concurrent/Executor;Landroid/net/connectivity/com/android/modules/utils/HandlerExecutor;,Landroid/os/HandlerExecutor;,Lcom/android/wifi/x/com/android/modules/utils/HandlerExecutor;]Ljava/util/function/Supplier;Landroid/telephony/TelephonyRegistryManager$CarrierPrivilegesCallbackWrapper$$ExternalSyntheticLambda1;
+HSPLcom/android/internal/listeners/ListenerExecutor;->executeSafely(Ljava/util/concurrent/Executor;Ljava/util/function/Supplier;Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;Lcom/android/internal/listeners/ListenerExecutor$FailureCallback;)V
 HSPLcom/android/internal/listeners/ListenerExecutor;->lambda$executeSafely$0(Ljava/lang/Object;Ljava/util/function/Supplier;Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;Lcom/android/internal/listeners/ListenerExecutor$FailureCallback;)V
 HSPLcom/android/internal/logging/AndroidConfig;-><init>()V
 HSPLcom/android/internal/logging/AndroidHandler$1;->format(Ljava/util/logging/LogRecord;)Ljava/lang/String;
@@ -21641,33 +21737,42 @@
 HSPLcom/android/internal/policy/DecorView$ColorViewAttributes;->isVisible(ZIIZ)Z
 HSPLcom/android/internal/policy/DecorView$ColorViewState;-><init>(Lcom/android/internal/policy/DecorView$ColorViewAttributes;)V
 HSPLcom/android/internal/policy/DecorView;-><init>(Landroid/content/Context;ILcom/android/internal/policy/PhoneWindow;Landroid/view/WindowManager$LayoutParams;)V
-HSPLcom/android/internal/policy/DecorView;->calculateNavigationBarColor(I)I
-HSPLcom/android/internal/policy/DecorView;->calculateStatusBarColor(I)I
+HSPLcom/android/internal/policy/DecorView;->calculateNavigationBarColor(I)I+]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
+HSPLcom/android/internal/policy/DecorView;->calculateStatusBarColor(I)I+]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
+HSPLcom/android/internal/policy/DecorView;->createDecorCaptionView(Landroid/view/LayoutInflater;)Lcom/android/internal/widget/DecorCaptionView;
 HSPLcom/android/internal/policy/DecorView;->dispatchKeyEvent(Landroid/view/KeyEvent;)Z
 HSPLcom/android/internal/policy/DecorView;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z
 HSPLcom/android/internal/policy/DecorView;->draw(Landroid/graphics/Canvas;)V
 HSPLcom/android/internal/policy/DecorView;->drawLegacyNavigationBarBackground(Landroid/graphics/RecordingCanvas;)V
 HSPLcom/android/internal/policy/DecorView;->drawableChanged()V
+HSPLcom/android/internal/policy/DecorView;->enableCaption(Z)V
+HSPLcom/android/internal/policy/DecorView;->enforceNonTranslucentBackground(Landroid/graphics/drawable/Drawable;Z)Landroid/graphics/drawable/Drawable;
 HSPLcom/android/internal/policy/DecorView;->finishChanging()V
+HSPLcom/android/internal/policy/DecorView;->gatherTransparentRegion(Landroid/graphics/Region;)Z
+HSPLcom/android/internal/policy/DecorView;->gatherTransparentRegion(Lcom/android/internal/policy/DecorView$ColorViewState;Landroid/graphics/Region;)Z
 HSPLcom/android/internal/policy/DecorView;->getAccessibilityViewId()I
 HSPLcom/android/internal/policy/DecorView;->getBackground()Landroid/graphics/drawable/Drawable;
+HSPLcom/android/internal/policy/DecorView;->getCaptionHeight()I
+HSPLcom/android/internal/policy/DecorView;->getCaptionInsetsHeight()I
 HSPLcom/android/internal/policy/DecorView;->getNavBarSize(III)I
-HSPLcom/android/internal/policy/DecorView;->getResources()Landroid/content/res/Resources;+]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
-HSPLcom/android/internal/policy/DecorView;->getTitleSuffix(Landroid/view/WindowManager$LayoutParams;)Ljava/lang/String;
-HSPLcom/android/internal/policy/DecorView;->getWindowInsetsController()Landroid/view/WindowInsetsController;
+HSPLcom/android/internal/policy/DecorView;->getResources()Landroid/content/res/Resources;+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Landroid/content/Context;Landroid/view/ContextThemeWrapper;,Lcom/android/internal/policy/DecorContext;
+HSPLcom/android/internal/policy/DecorView;->getTitleSuffix(Landroid/view/WindowManager$LayoutParams;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLcom/android/internal/policy/DecorView;->getWindowInsetsController()Landroid/view/WindowInsetsController;+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
 HSPLcom/android/internal/policy/DecorView;->initializeElevation()V
 HSPLcom/android/internal/policy/DecorView;->isNavBarToLeftEdge(II)Z
 HSPLcom/android/internal/policy/DecorView;->isNavBarToRightEdge(II)Z
+HSPLcom/android/internal/policy/DecorView;->isResizing()Z
+HSPLcom/android/internal/policy/DecorView;->isShowingCaption()Z
 HSPLcom/android/internal/policy/DecorView;->onApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
 HSPLcom/android/internal/policy/DecorView;->onAttachedToWindow()V
 HSPLcom/android/internal/policy/DecorView;->onCloseSystemDialogs(Ljava/lang/String;)V
 HSPLcom/android/internal/policy/DecorView;->onConfigurationChanged(Landroid/content/res/Configuration;)V
 HSPLcom/android/internal/policy/DecorView;->onContentDrawn(IIII)Z
 HSPLcom/android/internal/policy/DecorView;->onDetachedFromWindow()V
-HSPLcom/android/internal/policy/DecorView;->onDraw(Landroid/graphics/Canvas;)V
+HSPLcom/android/internal/policy/DecorView;->onDraw(Landroid/graphics/Canvas;)V+]Lcom/android/internal/widget/BackgroundFallback;Lcom/android/internal/widget/BackgroundFallback;
 HSPLcom/android/internal/policy/DecorView;->onInterceptTouchEvent(Landroid/view/MotionEvent;)Z
-HSPLcom/android/internal/policy/DecorView;->onLayout(ZIIII)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
-HSPLcom/android/internal/policy/DecorView;->onMeasure(II)V+]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/util/TypedValue;Landroid/util/TypedValue;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
+HSPLcom/android/internal/policy/DecorView;->onLayout(ZIIII)V
+HSPLcom/android/internal/policy/DecorView;->onMeasure(II)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Landroid/content/Context;Landroid/view/ContextThemeWrapper;,Lcom/android/internal/policy/DecorContext;]Landroid/content/res/Resources;Landroid/content/res/Resources;
 HSPLcom/android/internal/policy/DecorView;->onPostDraw(Landroid/graphics/RecordingCanvas;)V
 HSPLcom/android/internal/policy/DecorView;->onResourcesLoaded(Landroid/view/LayoutInflater;I)V
 HSPLcom/android/internal/policy/DecorView;->onRootViewScrollYChanged(I)V
@@ -21676,12 +21781,13 @@
 HSPLcom/android/internal/policy/DecorView;->onWindowFocusChanged(Z)V
 HSPLcom/android/internal/policy/DecorView;->onWindowSystemUiVisibilityChanged(I)V
 HSPLcom/android/internal/policy/DecorView;->providePendingInsetsController()Landroid/view/PendingInsetsController;
+HSPLcom/android/internal/policy/DecorView;->releaseThreadedRenderer()V
 HSPLcom/android/internal/policy/DecorView;->removeBackgroundBlurDrawable()V
 HSPLcom/android/internal/policy/DecorView;->sendAccessibilityEvent(I)V
 HSPLcom/android/internal/policy/DecorView;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLcom/android/internal/policy/DecorView;->setBackgroundFallback(Landroid/graphics/drawable/Drawable;)V
 HSPLcom/android/internal/policy/DecorView;->setColor(Landroid/view/View;IIZZ)V
-HSPLcom/android/internal/policy/DecorView;->setFrame(IIII)Z+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/ColorDrawable;,Landroid/graphics/drawable/GradientDrawable;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
+HSPLcom/android/internal/policy/DecorView;->setFrame(IIII)Z+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/ColorDrawable;
 HSPLcom/android/internal/policy/DecorView;->setWindow(Lcom/android/internal/policy/PhoneWindow;)V
 HSPLcom/android/internal/policy/DecorView;->setWindowBackground(Landroid/graphics/drawable/Drawable;)V
 HSPLcom/android/internal/policy/DecorView;->setWindowFrame(Landroid/graphics/drawable/Drawable;)V
@@ -21689,12 +21795,13 @@
 HSPLcom/android/internal/policy/DecorView;->superDispatchKeyEvent(Landroid/view/KeyEvent;)Z
 HSPLcom/android/internal/policy/DecorView;->superDispatchTouchEvent(Landroid/view/MotionEvent;)Z
 HSPLcom/android/internal/policy/DecorView;->updateBackgroundBlurRadius()V
-HSPLcom/android/internal/policy/DecorView;->updateBackgroundDrawable()V
-HSPLcom/android/internal/policy/DecorView;->updateColorViewInt(Lcom/android/internal/policy/DecorView$ColorViewState;IIIZZIZZI)V+]Landroid/view/View;Landroid/view/View;]Landroid/view/ViewPropertyAnimator;Landroid/view/ViewPropertyAnimator;]Lcom/android/internal/policy/DecorView$ColorViewAttributes;Lcom/android/internal/policy/DecorView$ColorViewAttributes;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
+HSPLcom/android/internal/policy/DecorView;->updateBackgroundDrawable()V+]Landroid/graphics/Insets;Landroid/graphics/Insets;
+HSPLcom/android/internal/policy/DecorView;->updateColorViewInt(Lcom/android/internal/policy/DecorView$ColorViewState;IIIZZIZZI)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;]Landroid/view/View;Landroid/view/View;]Landroid/view/ViewPropertyAnimator;Landroid/view/ViewPropertyAnimator;]Lcom/android/internal/policy/DecorView$ColorViewAttributes;Lcom/android/internal/policy/DecorView$ColorViewAttributes;
 HSPLcom/android/internal/policy/DecorView;->updateColorViewTranslations()V
-HSPLcom/android/internal/policy/DecorView;->updateColorViews(Landroid/view/WindowInsets;Z)Landroid/view/WindowInsets;+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/view/ViewGroup;Landroid/widget/LinearLayout;]Landroid/view/WindowInsets;Landroid/view/WindowInsets;]Landroid/view/WindowInsetsController;Landroid/view/InsetsController;,Landroid/view/PendingInsetsController;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
-HSPLcom/android/internal/policy/DecorView;->updateElevation()V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
-HSPLcom/android/internal/policy/DecorView;->updateLogTag(Landroid/view/WindowManager$LayoutParams;)V
+HSPLcom/android/internal/policy/DecorView;->updateColorViews(Landroid/view/WindowInsets;Z)Landroid/view/WindowInsets;+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;]Landroid/view/ViewGroup;Landroid/widget/LinearLayout;]Landroid/view/WindowInsetsController;Landroid/view/InsetsController;,Landroid/view/PendingInsetsController;]Landroid/view/WindowInsets;Landroid/view/WindowInsets;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
+HSPLcom/android/internal/policy/DecorView;->updateDecorCaptionStatus(Landroid/content/res/Configuration;)V
+HSPLcom/android/internal/policy/DecorView;->updateElevation()V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
+HSPLcom/android/internal/policy/DecorView;->updateLogTag(Landroid/view/WindowManager$LayoutParams;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLcom/android/internal/policy/DecorView;->updateStatusGuard(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
 HSPLcom/android/internal/policy/DecorView;->willYouTakeTheInputQueue()Landroid/view/InputQueue$Callback;
 HSPLcom/android/internal/policy/DecorView;->willYouTakeTheSurface()Landroid/view/SurfaceHolder$Callback2;
@@ -21728,10 +21835,10 @@
 HSPLcom/android/internal/policy/PhoneWindow;->closeAllPanels()V
 HSPLcom/android/internal/policy/PhoneWindow;->closeContextMenu()V
 HSPLcom/android/internal/policy/PhoneWindow;->closePanel(Lcom/android/internal/policy/PhoneWindow$PanelFeatureState;Z)V
-HSPLcom/android/internal/policy/PhoneWindow;->dispatchWindowAttributesChanged(Landroid/view/WindowManager$LayoutParams;)V
+HSPLcom/android/internal/policy/PhoneWindow;->dispatchWindowAttributesChanged(Landroid/view/WindowManager$LayoutParams;)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
 HSPLcom/android/internal/policy/PhoneWindow;->doInvalidatePanelMenu(I)V
 HSPLcom/android/internal/policy/PhoneWindow;->generateDecor(I)Lcom/android/internal/policy/DecorView;
-HSPLcom/android/internal/policy/PhoneWindow;->generateLayout(Lcom/android/internal/policy/DecorView;)Landroid/view/ViewGroup;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;]Ljava/lang/Boolean;Ljava/lang/Boolean;
+HSPLcom/android/internal/policy/PhoneWindow;->generateLayout(Lcom/android/internal/policy/DecorView;)Landroid/view/ViewGroup;
 HSPLcom/android/internal/policy/PhoneWindow;->getCurrentFocus()Landroid/view/View;
 HSPLcom/android/internal/policy/PhoneWindow;->getDecorView()Landroid/view/View;
 HSPLcom/android/internal/policy/PhoneWindow;->getLayoutInflater()Landroid/view/LayoutInflater;
@@ -21759,7 +21866,7 @@
 HSPLcom/android/internal/policy/PhoneWindow;->requestFeature(I)Z
 HSPLcom/android/internal/policy/PhoneWindow;->restoreHierarchyState(Landroid/os/Bundle;)V
 HSPLcom/android/internal/policy/PhoneWindow;->saveHierarchyState()Landroid/os/Bundle;
-HSPLcom/android/internal/policy/PhoneWindow;->setAttributes(Landroid/view/WindowManager$LayoutParams;)V
+HSPLcom/android/internal/policy/PhoneWindow;->setAttributes(Landroid/view/WindowManager$LayoutParams;)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
 HSPLcom/android/internal/policy/PhoneWindow;->setBackgroundBlurRadius(I)V
 HSPLcom/android/internal/policy/PhoneWindow;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLcom/android/internal/policy/PhoneWindow;->setContentView(I)V
@@ -21832,6 +21939,7 @@
 HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultDataSubId()I
 HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultSmsSubId()I
 HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultSubId()I
+HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultSubIdAsUser(I)I
 HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultVoiceSubId()I
 HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getPhoneId(I)I
 HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getSlotIndex(I)I
@@ -21917,7 +22025,7 @@
 HSPLcom/android/internal/util/ArrayUtils;->deepToString(Ljava/lang/Object;)Ljava/lang/String;
 HSPLcom/android/internal/util/ArrayUtils;->defeatNullable([Ljava/io/File;)[Ljava/io/File;
 HSPLcom/android/internal/util/ArrayUtils;->defeatNullable([Ljava/lang/String;)[Ljava/lang/String;
-HSPLcom/android/internal/util/ArrayUtils;->emptyArray(Ljava/lang/Class;)[Ljava/lang/Object;
+HSPLcom/android/internal/util/ArrayUtils;->emptyArray(Ljava/lang/Class;)[Ljava/lang/Object;+]Ljava/lang/Object;Ljava/lang/Class;]Ljava/lang/Class;Ljava/lang/Class;
 HSPLcom/android/internal/util/ArrayUtils;->emptyIfNull([Ljava/lang/Object;Ljava/lang/Class;)[Ljava/lang/Object;
 HSPLcom/android/internal/util/ArrayUtils;->filter([Ljava/lang/Object;Ljava/util/function/IntFunction;Ljava/util/function/Predicate;)[Ljava/lang/Object;
 HSPLcom/android/internal/util/ArrayUtils;->getOrNull([Ljava/lang/Object;I)Ljava/lang/Object;
@@ -21925,14 +22033,14 @@
 HSPLcom/android/internal/util/ArrayUtils;->isEmpty(Ljava/util/Collection;)Z
 HSPLcom/android/internal/util/ArrayUtils;->isEmpty([I)Z
 HSPLcom/android/internal/util/ArrayUtils;->isEmpty([Ljava/lang/Object;)Z
-HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedArray(Ljava/lang/Class;I)[Ljava/lang/Object;
+HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedArray(Ljava/lang/Class;I)[Ljava/lang/Object;+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
 HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedBooleanArray(I)[Z
 HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedByteArray(I)[B
-HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedCharArray(I)[C
+HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedCharArray(I)[C+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
 HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedFloatArray(I)[F
-HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedIntArray(I)[I
+HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedIntArray(I)[I+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
 HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedLongArray(I)[J
-HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedObjectArray(I)[Ljava/lang/Object;
+HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedObjectArray(I)[Ljava/lang/Object;+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
 HSPLcom/android/internal/util/ArrayUtils;->remove(Ljava/util/ArrayList;Ljava/lang/Object;)Ljava/util/ArrayList;
 HSPLcom/android/internal/util/ArrayUtils;->removeElement(Ljava/lang/Class;[Ljava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;
 HSPLcom/android/internal/util/ArrayUtils;->size([Ljava/lang/Object;)I
@@ -21973,13 +22081,13 @@
 HSPLcom/android/internal/util/FastPrintWriter;->print(Ljava/lang/String;)V
 HSPLcom/android/internal/util/FastPrintWriter;->println()V
 HSPLcom/android/internal/util/FastPrintWriter;->write(I)V
-HSPLcom/android/internal/util/FastPrintWriter;->write(Ljava/lang/String;)V
+HSPLcom/android/internal/util/FastPrintWriter;->write(Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;
 HSPLcom/android/internal/util/FastPrintWriter;->write([CII)V
 HSPLcom/android/internal/util/FastXmlSerializer;-><init>()V
 HSPLcom/android/internal/util/FastXmlSerializer;-><init>(I)V
 HSPLcom/android/internal/util/FastXmlSerializer;->append(C)V
 HSPLcom/android/internal/util/FastXmlSerializer;->append(Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;
-HSPLcom/android/internal/util/FastXmlSerializer;->append(Ljava/lang/String;II)V+]Ljava/lang/String;Ljava/lang/String;
+HSPLcom/android/internal/util/FastXmlSerializer;->append(Ljava/lang/String;II)V+]Ljava/lang/String;Ljava/lang/String;]Lcom/android/internal/util/FastXmlSerializer;Lcom/android/internal/util/FastXmlSerializer;
 HSPLcom/android/internal/util/FastXmlSerializer;->appendIndent(I)V+]Ljava/lang/String;Ljava/lang/String;
 HSPLcom/android/internal/util/FastXmlSerializer;->attribute(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/xmlpull/v1/XmlSerializer;
 HSPLcom/android/internal/util/FastXmlSerializer;->endDocument()V
@@ -22001,12 +22109,12 @@
 HSPLcom/android/internal/util/FrameworkStatsLog;->write(ILjava/lang/String;IIF)V
 HSPLcom/android/internal/util/GrowingArrayUtils;->append([III)[I
 HSPLcom/android/internal/util/GrowingArrayUtils;->append([JIJ)[J
-HSPLcom/android/internal/util/GrowingArrayUtils;->append([Ljava/lang/Object;ILjava/lang/Object;)[Ljava/lang/Object;
+HSPLcom/android/internal/util/GrowingArrayUtils;->append([Ljava/lang/Object;ILjava/lang/Object;)[Ljava/lang/Object;+]Ljava/lang/Object;missing_types]Ljava/lang/Class;Ljava/lang/Class;
 HSPLcom/android/internal/util/GrowingArrayUtils;->append([ZIZ)[Z
 HSPLcom/android/internal/util/GrowingArrayUtils;->growSize(I)I
 HSPLcom/android/internal/util/GrowingArrayUtils;->insert([IIII)[I
 HSPLcom/android/internal/util/GrowingArrayUtils;->insert([JIIJ)[J
-HSPLcom/android/internal/util/GrowingArrayUtils;->insert([Ljava/lang/Object;IILjava/lang/Object;)[Ljava/lang/Object;+]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;[Ljava/lang/Object;
+HSPLcom/android/internal/util/GrowingArrayUtils;->insert([Ljava/lang/Object;IILjava/lang/Object;)[Ljava/lang/Object;+]Ljava/lang/Object;[Ljava/lang/Object;]Ljava/lang/Class;Ljava/lang/Class;
 HSPLcom/android/internal/util/GrowingArrayUtils;->insert([ZIIZ)[Z
 HSPLcom/android/internal/util/IndentingPrintWriter;->decreaseIndent()Lcom/android/internal/util/IndentingPrintWriter;
 HSPLcom/android/internal/util/IndentingPrintWriter;->increaseIndent()Lcom/android/internal/util/IndentingPrintWriter;
@@ -22076,7 +22184,7 @@
 HSPLcom/android/internal/util/ProcFileReader;->finishLine()V
 HSPLcom/android/internal/util/ScreenshotHelper;-><init>(Landroid/content/Context;)V
 HSPLcom/android/internal/util/StatLogger;->getTime()J
-HSPLcom/android/internal/util/StatLogger;->logDurationStat(IJ)J+]Lcom/android/internal/util/StatLogger;Lcom/android/internal/util/StatLogger;
+HSPLcom/android/internal/util/StatLogger;->logDurationStat(IJ)J
 HSPLcom/android/internal/util/State;-><init>()V
 HSPLcom/android/internal/util/State;->enter()V
 HSPLcom/android/internal/util/StateMachine$LogRecords;->add(Lcom/android/internal/util/StateMachine;Landroid/os/Message;Ljava/lang/String;Lcom/android/internal/util/IState;Lcom/android/internal/util/IState;Lcom/android/internal/util/IState;)V
@@ -22128,7 +22236,7 @@
 HSPLcom/android/internal/util/XmlSerializerWrapper;->setFeature(Ljava/lang/String;Z)V
 HSPLcom/android/internal/util/XmlSerializerWrapper;->setOutput(Ljava/io/OutputStream;Ljava/lang/String;)V
 HSPLcom/android/internal/util/XmlSerializerWrapper;->startDocument(Ljava/lang/String;Ljava/lang/Boolean;)V
-HSPLcom/android/internal/util/XmlSerializerWrapper;->startTag(Ljava/lang/String;Ljava/lang/String;)Lorg/xmlpull/v1/XmlSerializer;+]Lorg/xmlpull/v1/XmlSerializer;Lcom/android/internal/util/FastXmlSerializer;
+HSPLcom/android/internal/util/XmlSerializerWrapper;->startTag(Ljava/lang/String;Ljava/lang/String;)Lorg/xmlpull/v1/XmlSerializer;
 HSPLcom/android/internal/util/XmlSerializerWrapper;->text(Ljava/lang/String;)Lorg/xmlpull/v1/XmlSerializer;
 HSPLcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;-><init>(Lorg/xmlpull/v1/XmlPullParser;)V
 HSPLcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;->getAttributeBoolean(I)Z
@@ -22151,19 +22259,19 @@
 HSPLcom/android/internal/util/XmlUtils;->readLongAttribute(Lorg/xmlpull/v1/XmlPullParser;Ljava/lang/String;J)J
 HSPLcom/android/internal/util/XmlUtils;->readMapXml(Ljava/io/InputStream;)Ljava/util/HashMap;
 HSPLcom/android/internal/util/XmlUtils;->readStringAttribute(Lorg/xmlpull/v1/XmlPullParser;Ljava/lang/String;)Ljava/lang/String;
-HSPLcom/android/internal/util/XmlUtils;->readThisMapXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;)Ljava/util/HashMap;
-HSPLcom/android/internal/util/XmlUtils;->readThisPrimitiveValueXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;)Ljava/lang/Object;
+HSPLcom/android/internal/util/XmlUtils;->readThisMapXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;)Ljava/util/HashMap;+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Object;Ljava/lang/String;]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
+HSPLcom/android/internal/util/XmlUtils;->readThisPrimitiveValueXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;)Ljava/lang/Object;+]Ljava/lang/Object;Ljava/lang/String;]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
 HSPLcom/android/internal/util/XmlUtils;->readThisSetXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;Z)Ljava/util/HashSet;
-HSPLcom/android/internal/util/XmlUtils;->readThisValueXml(Lcom/android/modules/utils/TypedXmlPullParser;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;Z)Ljava/lang/Object;
+HSPLcom/android/internal/util/XmlUtils;->readThisValueXml(Lcom/android/modules/utils/TypedXmlPullParser;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;Z)Ljava/lang/Object;+]Ljava/lang/Object;Ljava/lang/String;]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Lcom/android/internal/util/XmlUtils$ReadMapCallback;Landroid/os/PersistableBundle$MyReadMapCallback;
 HSPLcom/android/internal/util/XmlUtils;->readValueXml(Lcom/android/modules/utils/TypedXmlPullParser;[Ljava/lang/String;)Ljava/lang/Object;
 HSPLcom/android/internal/util/XmlUtils;->skipCurrentTag(Lorg/xmlpull/v1/XmlPullParser;)V
-HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V+]Ljava/util/Iterator;Ljava/util/HashMap$EntryIterator;]Ljava/util/Map$Entry;Ljava/util/HashMap$Node;]Ljava/util/Map;Ljava/util/HashMap;]Ljava/util/Set;Ljava/util/HashMap$EntrySet;
+HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V
 HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Ljava/io/OutputStream;)V
 HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;)V
 HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V
 HSPLcom/android/internal/util/XmlUtils;->writeSetXml(Ljava/util/Set;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;)V
 HSPLcom/android/internal/util/XmlUtils;->writeValueXml(Ljava/lang/Object;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;)V
-HSPLcom/android/internal/util/XmlUtils;->writeValueXml(Ljava/lang/Object;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V+]Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlSerializer;]Ljava/lang/Boolean;Ljava/lang/Boolean;]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/lang/Long;Ljava/lang/Long;]Ljava/lang/Object;Ljava/lang/String;
+HSPLcom/android/internal/util/XmlUtils;->writeValueXml(Ljava/lang/Object;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V+]Ljava/lang/Integer;Ljava/lang/Integer;]Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlSerializer;]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/Boolean;Ljava/lang/Boolean;]Ljava/lang/Long;Ljava/lang/Long;]Ljava/lang/Float;Ljava/lang/Float;
 HSPLcom/android/internal/util/function/pooled/OmniFunction;->run()V
 HSPLcom/android/internal/util/function/pooled/PooledLambda;->obtainMessage(Lcom/android/internal/util/function/HexConsumer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Landroid/os/Message;
 HSPLcom/android/internal/util/function/pooled/PooledLambda;->obtainMessage(Lcom/android/internal/util/function/QuadConsumer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Landroid/os/Message;
@@ -22199,6 +22307,7 @@
 HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->addClient(Lcom/android/internal/inputmethod/IInputMethodClient;Lcom/android/internal/inputmethod/IRemoteInputConnection;I)V
 HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->asBinder()Landroid/os/IBinder;
+HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->getEnabledInputMethodList(I)Ljava/util/List;
 HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->getImeTrackerService()Lcom/android/internal/inputmethod/IImeTracker;
 HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->isImeTraceEnabled()Z
 HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->removeImeSurfaceFromWindowAsync(Landroid/os/IBinder;)V
@@ -22243,7 +22352,7 @@
 HSPLcom/android/internal/widget/AlertDialogLayout;->setChildFrame(Landroid/view/View;IIII)V
 HSPLcom/android/internal/widget/AlertDialogLayout;->tryOnMeasure(II)Z
 HSPLcom/android/internal/widget/BackgroundFallback;-><init>()V
-HSPLcom/android/internal/widget/BackgroundFallback;->draw(Landroid/view/ViewGroup;Landroid/view/ViewGroup;Landroid/graphics/Canvas;Landroid/view/View;Landroid/view/View;Landroid/view/View;)V
+HSPLcom/android/internal/widget/BackgroundFallback;->draw(Landroid/view/ViewGroup;Landroid/view/ViewGroup;Landroid/graphics/Canvas;Landroid/view/View;Landroid/view/View;Landroid/view/View;)V+]Lcom/android/internal/widget/BackgroundFallback;Lcom/android/internal/widget/BackgroundFallback;
 HSPLcom/android/internal/widget/BackgroundFallback;->hasFallback()Z
 HSPLcom/android/internal/widget/BackgroundFallback;->setDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLcom/android/internal/widget/ButtonBarLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
@@ -22262,6 +22371,7 @@
 HSPLcom/android/internal/widget/LockPatternUtils$StrongAuthTracker;->isNonStrongBiometricAllowedAfterIdleTimeout(I)Z
 HSPLcom/android/internal/widget/LockPatternUtils$StrongAuthTracker;->onIsNonStrongBiometricAllowedChanged(I)V
 HSPLcom/android/internal/widget/LockPatternUtils;-><init>(Landroid/content/Context;)V
+HSPLcom/android/internal/widget/LockPatternUtils;-><init>(Landroid/content/Context;Lcom/android/internal/widget/ILockSettings;)V+]Landroid/content/Context;Landroid/app/ContextImpl;,Landroid/app/ReceiverRestrictedContext;
 HSPLcom/android/internal/widget/LockPatternUtils;->credentialTypeToPasswordQuality(I)I
 HSPLcom/android/internal/widget/LockPatternUtils;->getBoolean(Ljava/lang/String;ZI)Z
 HSPLcom/android/internal/widget/LockPatternUtils;->getCredentialTypeForUser(I)I
@@ -22277,8 +22387,8 @@
 HSPLcom/android/internal/widget/LockPatternUtils;->isSecure(I)Z
 HSPLcom/android/internal/widget/LockPatternUtils;->isSeparateProfileChallengeEnabled(I)Z
 HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeBoolean(Ljava/lang/String;Ljava/lang/String;)Z+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
-HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeFloat(Ljava/lang/String;Ljava/lang/String;)F+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
-HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeIndex(Ljava/lang/String;Ljava/lang/String;)I+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;]Ljava/lang/Object;Ljava/lang/String;
+HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeFloat(Ljava/lang/String;Ljava/lang/String;)F
+HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeIndex(Ljava/lang/String;Ljava/lang/String;)I+]Ljava/lang/Object;Ljava/lang/String;]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
 HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeIndexOrThrow(Ljava/lang/String;Ljava/lang/String;)I+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
 HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeInt(Ljava/lang/String;Ljava/lang/String;)I+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
 HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeLong(Ljava/lang/String;Ljava/lang/String;)J+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
@@ -22297,6 +22407,12 @@
 HSPLcom/android/telephony/Rlog;->log(ILjava/lang/String;Ljava/lang/String;)I
 HSPLcom/android/telephony/Rlog;->pii(ZLjava/lang/Object;)Ljava/lang/String;
 HSPLcom/android/telephony/Rlog;->w(Ljava/lang/String;Ljava/lang/String;)I
+HSPLcom/android/text/flags/FeatureFlagsImpl;-><init>()V
+HSPLcom/android/text/flags/Flags;-><clinit>()V
+HSPLcom/android/window/flags/FeatureFlagsImpl;-><init>()V
+HSPLcom/android/window/flags/FeatureFlagsImpl;->bundleClientTransactionFlag()Z
+HSPLcom/android/window/flags/Flags;-><clinit>()V
+HSPLcom/android/window/flags/Flags;->bundleClientTransactionFlag()Z+]Lcom/android/window/flags/FeatureFlags;Lcom/android/window/flags/FeatureFlagsImpl;
 HSPLcom/google/android/collect/Lists;->newArrayList()Ljava/util/ArrayList;
 HSPLcom/google/android/collect/Lists;->newArrayList([Ljava/lang/Object;)Ljava/util/ArrayList;
 HSPLcom/google/android/collect/Maps;->newHashMap()Ljava/util/HashMap;
@@ -22330,8 +22446,8 @@
 HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->getValue(I)Ljava/lang/String;
 HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->getValue(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->removeAttribute(I)V
-HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->setAttributes(Lorg/xml/sax/Attributes;)V+]Lorg/ccil/cowan/tagsoup/AttributesImpl;Lorg/ccil/cowan/tagsoup/AttributesImpl;]Lorg/xml/sax/Attributes;Lorg/ccil/cowan/tagsoup/AttributesImpl;
-HSPLorg/ccil/cowan/tagsoup/Element;-><init>(Lorg/ccil/cowan/tagsoup/ElementType;Z)V+]Lorg/ccil/cowan/tagsoup/ElementType;Lorg/ccil/cowan/tagsoup/ElementType;
+HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->setAttributes(Lorg/xml/sax/Attributes;)V
+HSPLorg/ccil/cowan/tagsoup/Element;-><init>(Lorg/ccil/cowan/tagsoup/ElementType;Z)V
 HSPLorg/ccil/cowan/tagsoup/Element;->atts()Lorg/ccil/cowan/tagsoup/AttributesImpl;
 HSPLorg/ccil/cowan/tagsoup/Element;->canContain(Lorg/ccil/cowan/tagsoup/Element;)Z
 HSPLorg/ccil/cowan/tagsoup/Element;->clean()V
@@ -22360,10 +22476,10 @@
 HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->mark()V
 HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->resetDocumentLocator(Ljava/lang/String;Ljava/lang/String;)V
 HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->save(ILorg/ccil/cowan/tagsoup/ScanHandler;)V
-HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->scan(Ljava/io/Reader;Lorg/ccil/cowan/tagsoup/ScanHandler;)V+]Ljava/io/PushbackReader;Ljava/io/PushbackReader;]Lorg/ccil/cowan/tagsoup/ScanHandler;Lorg/ccil/cowan/tagsoup/Parser;
+HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->scan(Ljava/io/Reader;Lorg/ccil/cowan/tagsoup/ScanHandler;)V
 HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->unread(Ljava/io/PushbackReader;I)V
 HSPLorg/ccil/cowan/tagsoup/Parser$1;-><init>(Lorg/ccil/cowan/tagsoup/Parser;)V
-HSPLorg/ccil/cowan/tagsoup/Parser;-><init>()V+]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLorg/ccil/cowan/tagsoup/Parser;-><init>()V
 HSPLorg/ccil/cowan/tagsoup/Parser;->aname([CII)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->aval([CII)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->entity([CII)V
@@ -22378,16 +22494,16 @@
 HSPLorg/ccil/cowan/tagsoup/Parser;->gi([CII)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->lookupEntity([CII)I
 HSPLorg/ccil/cowan/tagsoup/Parser;->makeName([CII)Ljava/lang/String;
-HSPLorg/ccil/cowan/tagsoup/Parser;->parse(Lorg/xml/sax/InputSource;)V+]Ljava/lang/Object;Ljava/lang/String;]Lorg/ccil/cowan/tagsoup/Scanner;Lorg/ccil/cowan/tagsoup/HTMLScanner;]Lorg/ccil/cowan/tagsoup/Schema;Lorg/ccil/cowan/tagsoup/HTMLSchema;]Lorg/xml/sax/ContentHandler;Landroid/text/HtmlToSpannedConverter;]Lorg/xml/sax/InputSource;Lorg/xml/sax/InputSource;
+HSPLorg/ccil/cowan/tagsoup/Parser;->parse(Lorg/xml/sax/InputSource;)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->pcdata([CII)V
-HSPLorg/ccil/cowan/tagsoup/Parser;->pop()V+]Lorg/ccil/cowan/tagsoup/Element;Lorg/ccil/cowan/tagsoup/Element;]Lorg/xml/sax/Attributes;Lorg/ccil/cowan/tagsoup/AttributesImpl;]Lorg/xml/sax/ContentHandler;Landroid/text/HtmlToSpannedConverter;
+HSPLorg/ccil/cowan/tagsoup/Parser;->pop()V
 HSPLorg/ccil/cowan/tagsoup/Parser;->prefixOf(Ljava/lang/String;)Ljava/lang/String;
-HSPLorg/ccil/cowan/tagsoup/Parser;->push(Lorg/ccil/cowan/tagsoup/Element;)V+]Ljava/lang/String;Ljava/lang/String;]Lorg/ccil/cowan/tagsoup/Element;Lorg/ccil/cowan/tagsoup/Element;]Lorg/xml/sax/Attributes;Lorg/ccil/cowan/tagsoup/AttributesImpl;]Lorg/xml/sax/ContentHandler;Landroid/text/HtmlToSpannedConverter;
-HSPLorg/ccil/cowan/tagsoup/Parser;->rectify(Lorg/ccil/cowan/tagsoup/Element;)V+]Ljava/lang/Object;Ljava/lang/String;]Lorg/ccil/cowan/tagsoup/Element;Lorg/ccil/cowan/tagsoup/Element;
+HSPLorg/ccil/cowan/tagsoup/Parser;->push(Lorg/ccil/cowan/tagsoup/Element;)V
+HSPLorg/ccil/cowan/tagsoup/Parser;->rectify(Lorg/ccil/cowan/tagsoup/Element;)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->restart(Lorg/ccil/cowan/tagsoup/Element;)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->setContentHandler(Lorg/xml/sax/ContentHandler;)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->setProperty(Ljava/lang/String;Ljava/lang/Object;)V
-HSPLorg/ccil/cowan/tagsoup/Parser;->setup()V+]Lorg/ccil/cowan/tagsoup/Schema;Lorg/ccil/cowan/tagsoup/HTMLSchema;
+HSPLorg/ccil/cowan/tagsoup/Parser;->setup()V
 HSPLorg/ccil/cowan/tagsoup/Parser;->stagc([CII)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->truthValue(Z)Ljava/lang/Boolean;
 HSPLorg/ccil/cowan/tagsoup/Schema;->getElementType(Ljava/lang/String;)Lorg/ccil/cowan/tagsoup/ElementType;
@@ -22447,6 +22563,7 @@
 Landroid/accounts/AuthenticatorDescription-IA;
 Landroid/accounts/AuthenticatorDescription;
 Landroid/accounts/AuthenticatorException;
+Landroid/accounts/IAccountAuthenticator$Stub$Proxy;
 Landroid/accounts/IAccountAuthenticator$Stub;
 Landroid/accounts/IAccountAuthenticator;
 Landroid/accounts/IAccountAuthenticatorResponse$Stub$Proxy;
@@ -22455,6 +22572,7 @@
 Landroid/accounts/IAccountManager$Stub$Proxy;
 Landroid/accounts/IAccountManager$Stub;
 Landroid/accounts/IAccountManager;
+Landroid/accounts/IAccountManagerResponse$Stub$Proxy;
 Landroid/accounts/IAccountManagerResponse$Stub;
 Landroid/accounts/IAccountManagerResponse;
 Landroid/accounts/NetworkErrorException;
@@ -22583,6 +22701,7 @@
 Landroid/app/ActivityClient$ActivityClientControllerSingleton;
 Landroid/app/ActivityClient-IA;
 Landroid/app/ActivityClient;
+Landroid/app/ActivityManager$1;
 Landroid/app/ActivityManager$2;
 Landroid/app/ActivityManager$3;
 Landroid/app/ActivityManager$AppTask;
@@ -22615,7 +22734,6 @@
 Landroid/app/ActivityOptions$1;
 Landroid/app/ActivityOptions$2;
 Landroid/app/ActivityOptions$OnAnimationStartedListener;
-Landroid/app/ActivityOptions$SceneTransitionInfo$1;
 Landroid/app/ActivityOptions$SceneTransitionInfo;
 Landroid/app/ActivityOptions$SourceInfo$1;
 Landroid/app/ActivityOptions$SourceInfo;
@@ -22677,7 +22795,6 @@
 Landroid/app/AlertDialog$Builder;
 Landroid/app/AlertDialog;
 Landroid/app/AppCompatCallbacks;
-Landroid/app/AppCompatTaskInfo$1;
 Landroid/app/AppCompatTaskInfo;
 Landroid/app/AppComponentFactory;
 Landroid/app/AppDetailsActivity;
@@ -22690,6 +22807,7 @@
 Landroid/app/AppOpsManager$$ExternalSyntheticLambda5;
 Landroid/app/AppOpsManager$$ExternalSyntheticLambda6;
 Landroid/app/AppOpsManager$1;
+Landroid/app/AppOpsManager$2;
 Landroid/app/AppOpsManager$3;
 Landroid/app/AppOpsManager$4;
 Landroid/app/AppOpsManager$AppOpsCollector;
@@ -22766,11 +22884,9 @@
 Landroid/app/BackStackRecord;
 Landroid/app/BackStackState$1;
 Landroid/app/BackStackState;
-Landroid/app/BackgroundInstallControlManager;
 Landroid/app/BackgroundServiceStartNotAllowedException$1;
 Landroid/app/BackgroundServiceStartNotAllowedException;
 Landroid/app/BroadcastOptions;
-Landroid/app/CameraCompatTaskInfo;
 Landroid/app/ClientTransactionHandler;
 Landroid/app/ComponentCaller;
 Landroid/app/ComponentOptions;
@@ -22915,6 +23031,7 @@
 Landroid/app/IStopUserCallback$Stub$Proxy;
 Landroid/app/IStopUserCallback$Stub;
 Landroid/app/IStopUserCallback;
+Landroid/app/ITaskStackListener$Stub$Proxy;
 Landroid/app/ITaskStackListener$Stub;
 Landroid/app/ITaskStackListener;
 Landroid/app/ITransientNotification$Stub$Proxy;
@@ -23037,6 +23154,7 @@
 Landroid/app/PendingIntent$1;
 Landroid/app/PendingIntent$CancelListener;
 Landroid/app/PendingIntent$CanceledException;
+Landroid/app/PendingIntent$FinishedDispatcher;
 Landroid/app/PendingIntent$OnFinished;
 Landroid/app/PendingIntent$OnMarshaledListener;
 Landroid/app/PendingIntent;
@@ -23086,7 +23204,6 @@
 Landroid/app/ResourcesManager$ActivityResources;
 Landroid/app/ResourcesManager$ApkAssetsSupplier;
 Landroid/app/ResourcesManager$ApkKey;
-Landroid/app/ResourcesManager$SharedLibraryAssets;
 Landroid/app/ResourcesManager$UpdateHandler-IA;
 Landroid/app/ResourcesManager$UpdateHandler;
 Landroid/app/ResourcesManager;
@@ -23118,6 +23235,7 @@
 Landroid/app/SharedPreferencesImpl$MemoryCommitResult-IA;
 Landroid/app/SharedPreferencesImpl$MemoryCommitResult;
 Landroid/app/SharedPreferencesImpl$SharedPreferencesThreadFactory;
+Landroid/app/SharedPreferencesImpl;
 Landroid/app/StackTrace;
 Landroid/app/StatusBarManager;
 Landroid/app/SyncNotedAppOp$1;
@@ -23168,12 +23286,8 @@
 Landroid/app/SystemServiceRegistry$139;
 Landroid/app/SystemServiceRegistry$13;
 Landroid/app/SystemServiceRegistry$140;
-Landroid/app/SystemServiceRegistry$141;
-Landroid/app/SystemServiceRegistry$142;
 Landroid/app/SystemServiceRegistry$143;
 Landroid/app/SystemServiceRegistry$144;
-Landroid/app/SystemServiceRegistry$145;
-Landroid/app/SystemServiceRegistry$146;
 Landroid/app/SystemServiceRegistry$14;
 Landroid/app/SystemServiceRegistry$15;
 Landroid/app/SystemServiceRegistry$16;
@@ -23481,13 +23595,13 @@
 Landroid/app/contentsuggestions/SelectionsRequest$Builder;
 Landroid/app/contentsuggestions/SelectionsRequest-IA;
 Landroid/app/contentsuggestions/SelectionsRequest;
-Landroid/app/contextualsearch/ContextualSearchManager;
 Landroid/app/job/IJobCallback$Stub$Proxy;
 Landroid/app/job/IJobCallback$Stub;
 Landroid/app/job/IJobCallback;
 Landroid/app/job/IJobScheduler$Stub$Proxy;
 Landroid/app/job/IJobScheduler$Stub;
 Landroid/app/job/IJobScheduler;
+Landroid/app/job/IJobService$Stub$Proxy;
 Landroid/app/job/IJobService$Stub;
 Landroid/app/job/IJobService;
 Landroid/app/job/IUserVisibleJobObserver;
@@ -23506,14 +23620,15 @@
 Landroid/app/job/JobSchedulerFrameworkInitializer$$ExternalSyntheticLambda1;
 Landroid/app/job/JobSchedulerFrameworkInitializer$$ExternalSyntheticLambda2;
 Landroid/app/job/JobSchedulerFrameworkInitializer$$ExternalSyntheticLambda3;
+Landroid/app/job/JobSchedulerFrameworkInitializer$$ExternalSyntheticLambda4;
 Landroid/app/job/JobSchedulerFrameworkInitializer;
 Landroid/app/job/JobService$1;
 Landroid/app/job/JobService;
 Landroid/app/job/JobServiceEngine$JobHandler;
+Landroid/app/job/JobServiceEngine$JobInterface;
 Landroid/app/job/JobServiceEngine;
 Landroid/app/job/JobWorkItem$1;
 Landroid/app/job/JobWorkItem;
-Landroid/app/ondeviceintelligence/OnDeviceIntelligenceManager;
 Landroid/app/people/IPeopleManager$Stub$Proxy;
 Landroid/app/people/IPeopleManager$Stub;
 Landroid/app/people/IPeopleManager;
@@ -23593,6 +23708,7 @@
 Landroid/app/servertransaction/TopResumedActivityChangeItem;
 Landroid/app/servertransaction/TransactionExecutor;
 Landroid/app/servertransaction/TransactionExecutorHelper;
+Landroid/app/servertransaction/WindowStateResizeItem$ResizeListener;
 Landroid/app/slice/ISliceManager$Stub$Proxy;
 Landroid/app/slice/ISliceManager$Stub;
 Landroid/app/slice/ISliceManager;
@@ -23644,6 +23760,7 @@
 Landroid/app/smartspace/uitemplatedata/TapAction;
 Landroid/app/smartspace/uitemplatedata/Text$1;
 Landroid/app/smartspace/uitemplatedata/Text;
+Landroid/app/tare/EconomyManager;
 Landroid/app/time/ITimeZoneDetectorListener$Stub$Proxy;
 Landroid/app/time/ITimeZoneDetectorListener$Stub;
 Landroid/app/time/ITimeZoneDetectorListener;
@@ -23705,8 +23822,6 @@
 Landroid/app/usage/EventList;
 Landroid/app/usage/ExternalStorageStats$1;
 Landroid/app/usage/ExternalStorageStats;
-Landroid/app/usage/FeatureFlags;
-Landroid/app/usage/FeatureFlagsImpl;
 Landroid/app/usage/Flags;
 Landroid/app/usage/ICacheQuotaService$Stub$Proxy;
 Landroid/app/usage/ICacheQuotaService$Stub;
@@ -23746,8 +23861,6 @@
 Landroid/appwidget/AppWidgetProviderInfo;
 Landroid/appwidget/PendingHostUpdate$1;
 Landroid/appwidget/PendingHostUpdate;
-Landroid/appwidget/flags/FeatureFlags;
-Landroid/appwidget/flags/FeatureFlagsImpl;
 Landroid/appwidget/flags/Flags;
 Landroid/attention/AttentionManagerInternal$AttentionCallbackInternal;
 Landroid/attention/AttentionManagerInternal;
@@ -23766,7 +23879,6 @@
 Landroid/companion/virtual/IVirtualDeviceManager$Stub$Proxy;
 Landroid/companion/virtual/IVirtualDeviceManager$Stub;
 Landroid/companion/virtual/IVirtualDeviceManager;
-Landroid/companion/virtual/VirtualDevice;
 Landroid/companion/virtual/VirtualDeviceManager;
 Landroid/companion/virtual/flags/FeatureFlags;
 Landroid/companion/virtual/flags/FeatureFlagsImpl;
@@ -23814,8 +23926,8 @@
 Landroid/content/ComponentName$WithComponentName;
 Landroid/content/ComponentName;
 Landroid/content/ContentCaptureOptions$1;
+Landroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda0;
 Landroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda1;
-Landroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda2;
 Landroid/content/ContentCaptureOptions$ContentProtectionOptions;
 Landroid/content/ContentCaptureOptions;
 Landroid/content/ContentInterface;
@@ -23836,10 +23948,12 @@
 Landroid/content/ContentProviderOperation$Builder;
 Landroid/content/ContentProviderOperation-IA;
 Landroid/content/ContentProviderOperation;
+Landroid/content/ContentProviderProxy;
 Landroid/content/ContentProviderResult$1;
 Landroid/content/ContentProviderResult;
 Landroid/content/ContentResolver$1;
 Landroid/content/ContentResolver$2;
+Landroid/content/ContentResolver$CursorWrapperInner;
 Landroid/content/ContentResolver$OpenResourceIdResult;
 Landroid/content/ContentResolver$ParcelFileDescriptorInner;
 Landroid/content/ContentResolver$ResultListener-IA;
@@ -23891,6 +24005,7 @@
 Landroid/content/ISyncContext$Stub$Proxy;
 Landroid/content/ISyncContext$Stub;
 Landroid/content/ISyncContext;
+Landroid/content/ISyncStatusObserver$Stub$Proxy;
 Landroid/content/ISyncStatusObserver$Stub;
 Landroid/content/ISyncStatusObserver;
 Landroid/content/Intent$1;
@@ -23993,7 +24108,6 @@
 Landroid/content/pm/ApplicationInfo$1;
 Landroid/content/pm/ApplicationInfo-IA;
 Landroid/content/pm/ApplicationInfo;
-Landroid/content/pm/ArchivedPackageParcel$1;
 Landroid/content/pm/ArchivedPackageParcel;
 Landroid/content/pm/Attribution$1;
 Landroid/content/pm/Attribution;
@@ -24017,6 +24131,8 @@
 Landroid/content/pm/DataLoaderParamsParcel$1;
 Landroid/content/pm/DataLoaderParamsParcel;
 Landroid/content/pm/FallbackCategoryProvider;
+Landroid/content/pm/FeatureFlags;
+Landroid/content/pm/FeatureFlagsImpl;
 Landroid/content/pm/FeatureGroupInfo$1;
 Landroid/content/pm/FeatureGroupInfo;
 Landroid/content/pm/FeatureInfo$1;
@@ -24024,6 +24140,7 @@
 Landroid/content/pm/FeatureInfo;
 Landroid/content/pm/FileSystemControlParcel$1;
 Landroid/content/pm/FileSystemControlParcel;
+Landroid/content/pm/Flags;
 Landroid/content/pm/ICrossProfileApps$Stub$Proxy;
 Landroid/content/pm/ICrossProfileApps$Stub;
 Landroid/content/pm/ICrossProfileApps;
@@ -24040,6 +24157,7 @@
 Landroid/content/pm/ILauncherApps$Stub$Proxy;
 Landroid/content/pm/ILauncherApps$Stub;
 Landroid/content/pm/ILauncherApps;
+Landroid/content/pm/IOnAppsChangedListener$Stub$Proxy;
 Landroid/content/pm/IOnAppsChangedListener$Stub;
 Landroid/content/pm/IOnAppsChangedListener;
 Landroid/content/pm/IOnChecksumsReadyListener$Stub$Proxy;
@@ -24407,7 +24525,6 @@
 Landroid/content/type/DefaultMimeMapFactory$$ExternalSyntheticLambda0;
 Landroid/content/type/DefaultMimeMapFactory;
 Landroid/credentials/CredentialManager;
-Landroid/credentials/GetCredentialResponse$1;
 Landroid/credentials/GetCredentialResponse;
 Landroid/database/AbstractCursor$SelfContentObserver;
 Landroid/database/AbstractCursor;
@@ -24472,6 +24589,7 @@
 Landroid/database/sqlite/SQLiteConnectionPool$IdleConnectionHandler;
 Landroid/database/sqlite/SQLiteConnectionPool;
 Landroid/database/sqlite/SQLiteConstraintException;
+Landroid/database/sqlite/SQLiteCursor;
 Landroid/database/sqlite/SQLiteCursorDriver;
 Landroid/database/sqlite/SQLiteCustomFunction;
 Landroid/database/sqlite/SQLiteDatabase$$ExternalSyntheticLambda0;
@@ -24644,7 +24762,6 @@
 Landroid/graphics/LinearGradient;
 Landroid/graphics/MaskFilter;
 Landroid/graphics/Matrix$1;
-Landroid/graphics/Matrix$ExtraNatives;
 Landroid/graphics/Matrix$NoImagePreloadHolder;
 Landroid/graphics/Matrix$ScaleToFit;
 Landroid/graphics/Matrix;
@@ -24668,7 +24785,6 @@
 Landroid/graphics/PaintFlagsDrawFilter;
 Landroid/graphics/Path$Direction;
 Landroid/graphics/Path$FillType;
-Landroid/graphics/Path$NoImagePreloadHolder;
 Landroid/graphics/Path$Op;
 Landroid/graphics/Path;
 Landroid/graphics/PathDashPathEffect;
@@ -24879,7 +24995,6 @@
 Landroid/graphics/drawable/shapes/RoundRectShape;
 Landroid/graphics/drawable/shapes/Shape;
 Landroid/graphics/fonts/Font$Builder;
-Landroid/graphics/fonts/Font$NoImagePreloadHolder;
 Landroid/graphics/fonts/Font;
 Landroid/graphics/fonts/FontCustomizationParser$Result;
 Landroid/graphics/fonts/FontCustomizationParser;
@@ -24924,7 +25039,6 @@
 Landroid/hardware/CameraStatus$1;
 Landroid/hardware/CameraStatus;
 Landroid/hardware/ConsumerIrManager;
-Landroid/hardware/DataSpace;
 Landroid/hardware/GeomagneticField$LegendreTable;
 Landroid/hardware/GeomagneticField;
 Landroid/hardware/HardwareBuffer$1;
@@ -24972,6 +25086,7 @@
 Landroid/hardware/SystemSensorManager$BaseEventQueue;
 Landroid/hardware/SystemSensorManager$SensorEventQueue;
 Landroid/hardware/SystemSensorManager$TriggerEventQueue;
+Landroid/hardware/SystemSensorManager;
 Landroid/hardware/TriggerEvent;
 Landroid/hardware/TriggerEventListener;
 Landroid/hardware/biometrics/BiometricAuthenticator$AuthenticationCallback;
@@ -25038,10 +25153,13 @@
 Landroid/hardware/camera2/CameraDevice$StateCallback;
 Landroid/hardware/camera2/CameraDevice;
 Landroid/hardware/camera2/CameraManager$AvailabilityCallback;
-Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$$ExternalSyntheticLambda0;
 Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$$ExternalSyntheticLambda2;
 Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$1;
-Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$DeviceCameraInfo;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$3;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$4;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$5;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$6;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$7;
 Landroid/hardware/camera2/CameraManager$CameraManagerGlobal;
 Landroid/hardware/camera2/CameraManager$DeviceStateListener;
 Landroid/hardware/camera2/CameraManager$FoldStateListener$$ExternalSyntheticLambda0;
@@ -25198,7 +25316,6 @@
 Landroid/hardware/contexthub/V1_0/NanoAppBinary;
 Landroid/hardware/contexthub/V1_0/PhysicalSensor;
 Landroid/hardware/contexthub/V1_1/Setting;
-Landroid/hardware/devicestate/DeviceState$Configuration;
 Landroid/hardware/devicestate/DeviceState;
 Landroid/hardware/devicestate/DeviceStateInfo$1;
 Landroid/hardware/devicestate/DeviceStateInfo;
@@ -25313,9 +25430,12 @@
 Landroid/hardware/fingerprint/Fingerprint;
 Landroid/hardware/fingerprint/FingerprintManager$1;
 Landroid/hardware/fingerprint/FingerprintManager$2;
+Landroid/hardware/fingerprint/FingerprintManager$3;
 Landroid/hardware/fingerprint/FingerprintManager$AuthenticationCallback;
 Landroid/hardware/fingerprint/FingerprintManager$AuthenticationResult;
 Landroid/hardware/fingerprint/FingerprintManager$LockoutResetCallback;
+Landroid/hardware/fingerprint/FingerprintManager$MyHandler-IA;
+Landroid/hardware/fingerprint/FingerprintManager$MyHandler;
 Landroid/hardware/fingerprint/FingerprintManager;
 Landroid/hardware/fingerprint/FingerprintSensorPropertiesInternal$1;
 Landroid/hardware/fingerprint/FingerprintSensorPropertiesInternal;
@@ -25801,9 +25921,13 @@
 Landroid/icu/impl/CalType;
 Landroid/icu/impl/CalendarAstronomer$1;
 Landroid/icu/impl/CalendarAstronomer$2;
+Landroid/icu/impl/CalendarAstronomer$3;
+Landroid/icu/impl/CalendarAstronomer$4;
 Landroid/icu/impl/CalendarAstronomer$AngleFunc;
+Landroid/icu/impl/CalendarAstronomer$CoordFunc;
 Landroid/icu/impl/CalendarAstronomer$Ecliptic;
 Landroid/icu/impl/CalendarAstronomer$Equatorial;
+Landroid/icu/impl/CalendarAstronomer$Horizon;
 Landroid/icu/impl/CalendarAstronomer$MoonAge;
 Landroid/icu/impl/CalendarAstronomer$SolarLongitude;
 Landroid/icu/impl/CalendarAstronomer;
@@ -25840,7 +25964,6 @@
 Landroid/icu/impl/DayPeriodRules-IA;
 Landroid/icu/impl/DayPeriodRules;
 Landroid/icu/impl/DontCareFieldPosition;
-Landroid/icu/impl/EmojiProps$IsAcceptable;
 Landroid/icu/impl/EmojiProps;
 Landroid/icu/impl/EraRules;
 Landroid/icu/impl/FormattedStringBuilder$FieldWrapper;
@@ -26116,8 +26239,6 @@
 Landroid/icu/impl/UCharacterProperty$25;
 Landroid/icu/impl/UCharacterProperty$26;
 Landroid/icu/impl/UCharacterProperty$27;
-Landroid/icu/impl/UCharacterProperty$28;
-Landroid/icu/impl/UCharacterProperty$29;
 Landroid/icu/impl/UCharacterProperty$2;
 Landroid/icu/impl/UCharacterProperty$3;
 Landroid/icu/impl/UCharacterProperty$4;
@@ -26135,7 +26256,6 @@
 Landroid/icu/impl/UCharacterProperty$IsAcceptable;
 Landroid/icu/impl/UCharacterProperty$LayoutProps$IsAcceptable;
 Landroid/icu/impl/UCharacterProperty$LayoutProps;
-Landroid/icu/impl/UCharacterProperty$MathCompatBinaryProperty;
 Landroid/icu/impl/UCharacterProperty$NormInertBinaryProperty;
 Landroid/icu/impl/UCharacterProperty$NormQuickCheckIntProperty;
 Landroid/icu/impl/UCharacterProperty;
@@ -26320,15 +26440,8 @@
 Landroid/icu/impl/locale/KeyTypeData$TypeInfoType;
 Landroid/icu/impl/locale/KeyTypeData$ValueType;
 Landroid/icu/impl/locale/KeyTypeData;
-Landroid/icu/impl/locale/LSR$CachedDecoder$$ExternalSyntheticLambda0;
-Landroid/icu/impl/locale/LSR$CachedDecoder$$ExternalSyntheticLambda1;
-Landroid/icu/impl/locale/LSR$CachedDecoder$$ExternalSyntheticLambda2;
-Landroid/icu/impl/locale/LSR$CachedDecoder;
 Landroid/icu/impl/locale/LSR;
 Landroid/icu/impl/locale/LanguageTag;
-Landroid/icu/impl/locale/LikelySubtags$1;
-Landroid/icu/impl/locale/LikelySubtags$Data;
-Landroid/icu/impl/locale/LikelySubtags;
 Landroid/icu/impl/locale/LocaleDistance$Data;
 Landroid/icu/impl/locale/LocaleDistance;
 Landroid/icu/impl/locale/LocaleExtensions;
@@ -26359,6 +26472,9 @@
 Landroid/icu/impl/locale/XCldrStub$Splitter;
 Landroid/icu/impl/locale/XCldrStub$TreeMultimap;
 Landroid/icu/impl/locale/XCldrStub;
+Landroid/icu/impl/locale/XLikelySubtags$1;
+Landroid/icu/impl/locale/XLikelySubtags$Data;
+Landroid/icu/impl/locale/XLikelySubtags;
 Landroid/icu/impl/number/AdoptingModifierStore$1;
 Landroid/icu/impl/number/AdoptingModifierStore;
 Landroid/icu/impl/number/AffixPatternProvider$Flags;
@@ -26489,7 +26605,6 @@
 Landroid/icu/lang/UCharacter$EastAsianWidth;
 Landroid/icu/lang/UCharacter$GraphemeClusterBreak;
 Landroid/icu/lang/UCharacter$HangulSyllableType;
-Landroid/icu/lang/UCharacter$IdentifierType;
 Landroid/icu/lang/UCharacter$IndicPositionalCategory;
 Landroid/icu/lang/UCharacter$IndicSyllabicCategory;
 Landroid/icu/lang/UCharacter$JoiningGroup;
@@ -27035,7 +27150,6 @@
 Landroid/icu/text/Transform;
 Landroid/icu/text/TransliterationRule;
 Landroid/icu/text/TransliterationRuleSet;
-Landroid/icu/text/Transliterator$$ExternalSyntheticLambda0;
 Landroid/icu/text/Transliterator$Factory;
 Landroid/icu/text/Transliterator$Position;
 Landroid/icu/text/Transliterator;
@@ -27082,7 +27196,6 @@
 Landroid/icu/text/UnicodeSet$EntryRangeIterator;
 Landroid/icu/text/UnicodeSet$Filter;
 Landroid/icu/text/UnicodeSet$GeneralCategoryMaskFilter;
-Landroid/icu/text/UnicodeSet$IdentifierTypeFilter;
 Landroid/icu/text/UnicodeSet$IntPropertyFilter;
 Landroid/icu/text/UnicodeSet$NumericValueFilter;
 Landroid/icu/text/UnicodeSet$ScriptExtensionsFilter;
@@ -27189,12 +27302,7 @@
 Landroid/icu/util/IllformedLocaleException;
 Landroid/icu/util/IndianCalendar;
 Landroid/icu/util/InitialTimeZoneRule;
-Landroid/icu/util/IslamicCalendar$Algorithm;
 Landroid/icu/util/IslamicCalendar$CalculationType;
-Landroid/icu/util/IslamicCalendar$CivilAlgorithm;
-Landroid/icu/util/IslamicCalendar$IslamicAlgorithm;
-Landroid/icu/util/IslamicCalendar$TBLAAlgorithm;
-Landroid/icu/util/IslamicCalendar$UmalquraAlgorithm;
 Landroid/icu/util/IslamicCalendar;
 Landroid/icu/util/JapaneseCalendar;
 Landroid/icu/util/LocaleData$MeasurementSystem;
@@ -27544,8 +27652,6 @@
 Landroid/media/ImageWriter$WriterSurfaceImage;
 Landroid/media/ImageWriter;
 Landroid/media/JetPlayer;
-Landroid/media/MediaCodec$$ExternalSyntheticLambda6;
-Landroid/media/MediaCodec$$ExternalSyntheticLambda7;
 Landroid/media/MediaCodec$BufferInfo;
 Landroid/media/MediaCodec$BufferMap$CodecBuffer-IA;
 Landroid/media/MediaCodec$BufferMap$CodecBuffer;
@@ -27770,8 +27876,6 @@
 Landroid/media/VolumeShaper$State$1;
 Landroid/media/VolumeShaper$State;
 Landroid/media/VolumeShaper;
-Landroid/media/audio/FeatureFlags;
-Landroid/media/audio/FeatureFlagsImpl;
 Landroid/media/audio/Flags;
 Landroid/media/audio/common/AidlConversion;
 Landroid/media/audio/common/HeadTracking$SensorData$Tag;
@@ -28220,7 +28324,6 @@
 Landroid/net/wifi/nl80211/WifiNl80211Manager$SignalPollResult;
 Landroid/net/wifi/nl80211/WifiNl80211Manager;
 Landroid/net/wifi/sharedconnectivity/app/SharedConnectivityManager;
-Landroid/nfc/NfcAdapter;
 Landroid/nfc/NfcFrameworkInitializer$$ExternalSyntheticLambda0;
 Landroid/nfc/NfcFrameworkInitializer;
 Landroid/nfc/NfcManager;
@@ -28471,6 +28574,7 @@
 Landroid/os/IIncidentManager$Stub$Proxy;
 Landroid/os/IIncidentManager$Stub;
 Landroid/os/IIncidentManager;
+Landroid/os/IInstalld$Stub$Proxy;
 Landroid/os/IInstalld$Stub;
 Landroid/os/IInstalld;
 Landroid/os/IInterface;
@@ -28693,6 +28797,7 @@
 Landroid/os/StrictMode$2;
 Landroid/os/StrictMode$3;
 Landroid/os/StrictMode$4;
+Landroid/os/StrictMode$5;
 Landroid/os/StrictMode$6;
 Landroid/os/StrictMode$7;
 Landroid/os/StrictMode$8;
@@ -28723,6 +28828,7 @@
 Landroid/os/SynchronousResultReceiver$Result;
 Landroid/os/SynchronousResultReceiver;
 Landroid/os/SystemClock$2;
+Landroid/os/SystemClock$3;
 Landroid/os/SystemClock;
 Landroid/os/SystemConfigManager;
 Landroid/os/SystemProperties$Handle-IA;
@@ -28881,8 +28987,6 @@
 Landroid/os/strictmode/UntaggedSocketViolation;
 Landroid/os/strictmode/Violation;
 Landroid/os/strictmode/WebViewMethodCalledOnWrongThreadViolation;
-Landroid/os/vibrator/FeatureFlags;
-Landroid/os/vibrator/FeatureFlagsImpl;
 Landroid/os/vibrator/Flags;
 Landroid/os/vibrator/PrebakedSegment$1;
 Landroid/os/vibrator/PrebakedSegment;
@@ -28916,13 +29020,15 @@
 Landroid/permission/PermissionControllerManager;
 Landroid/permission/PermissionManager$1;
 Landroid/permission/PermissionManager$2;
-Landroid/permission/PermissionManager$OnPermissionsChangeListenerDelegate;
 Landroid/permission/PermissionManager$PackageNamePermissionQuery;
 Landroid/permission/PermissionManager$PermissionQuery;
 Landroid/permission/PermissionManager$SplitPermissionInfo-IA;
 Landroid/permission/PermissionManager$SplitPermissionInfo;
 Landroid/permission/PermissionManager;
 Landroid/permission/PermissionManagerInternal;
+Landroid/permission/flags/FeatureFlags;
+Landroid/permission/flags/FeatureFlagsImpl;
+Landroid/permission/flags/Flags;
 Landroid/preference/DialogPreference;
 Landroid/preference/GenericInflater$Parent;
 Landroid/preference/GenericInflater;
@@ -29151,6 +29257,7 @@
 Landroid/security/KeyStore2$$ExternalSyntheticLambda8;
 Landroid/security/KeyStore2$CheckedRemoteRequest;
 Landroid/security/KeyStore2;
+Landroid/security/KeyStore;
 Landroid/security/KeyStoreException$PublicErrorInformation;
 Landroid/security/KeyStoreException;
 Landroid/security/KeyStoreOperation$$ExternalSyntheticLambda0;
@@ -29321,8 +29428,6 @@
 Landroid/service/autofill/AutofillServiceInfo;
 Landroid/service/autofill/Dataset$1;
 Landroid/service/autofill/Dataset;
-Landroid/service/autofill/FeatureFlags;
-Landroid/service/autofill/FeatureFlagsImpl;
 Landroid/service/autofill/FieldClassificationUserData;
 Landroid/service/autofill/FillContext$1;
 Landroid/service/autofill/FillContext;
@@ -29459,7 +29564,6 @@
 Landroid/service/media/MediaBrowserService$ServiceBinder$$ExternalSyntheticLambda1;
 Landroid/service/media/MediaBrowserService$ServiceBinder-IA;
 Landroid/service/media/MediaBrowserService$ServiceBinder;
-Landroid/service/media/MediaBrowserService$ServiceState-IA;
 Landroid/service/media/MediaBrowserService$ServiceState;
 Landroid/service/media/MediaBrowserService;
 Landroid/service/notification/Adjustment$1;
@@ -29498,7 +29602,6 @@
 Landroid/service/notification/SnoozeCriterion;
 Landroid/service/notification/StatusBarNotification$1;
 Landroid/service/notification/StatusBarNotification;
-Landroid/service/notification/ZenDeviceEffects$1;
 Landroid/service/notification/ZenDeviceEffects;
 Landroid/service/notification/ZenModeConfig$1;
 Landroid/service/notification/ZenModeConfig$EventInfo;
@@ -29885,6 +29988,7 @@
 Landroid/telephony/ICellInfoCallback$Stub$Proxy;
 Landroid/telephony/ICellInfoCallback$Stub;
 Landroid/telephony/ICellInfoCallback;
+Landroid/telephony/INetworkService$Stub$Proxy;
 Landroid/telephony/INetworkService$Stub;
 Landroid/telephony/INetworkService;
 Landroid/telephony/INetworkServiceCallback$Stub$Proxy;
@@ -29920,6 +30024,7 @@
 Landroid/telephony/NetworkScan;
 Landroid/telephony/NetworkScanRequest$1;
 Landroid/telephony/NetworkScanRequest;
+Landroid/telephony/NetworkService$INetworkServiceWrapper;
 Landroid/telephony/NetworkService$NetworkServiceHandler;
 Landroid/telephony/NetworkService$NetworkServiceProvider;
 Landroid/telephony/NetworkService;
@@ -30056,7 +30161,6 @@
 Landroid/telephony/TelephonyCallback$CallForwardingIndicatorListener;
 Landroid/telephony/TelephonyCallback$CallStateListener;
 Landroid/telephony/TelephonyCallback$CarrierNetworkListener;
-Landroid/telephony/TelephonyCallback$CarrierRoamingNtnModeListener;
 Landroid/telephony/TelephonyCallback$CellInfoListener;
 Landroid/telephony/TelephonyCallback$CellLocationListener;
 Landroid/telephony/TelephonyCallback$DataActivationStateListener;
@@ -30357,6 +30461,7 @@
 Landroid/telephony/ims/aidl/IImsConfigCallback$Stub$Proxy;
 Landroid/telephony/ims/aidl/IImsConfigCallback$Stub;
 Landroid/telephony/ims/aidl/IImsConfigCallback;
+Landroid/telephony/ims/aidl/IImsMmTelFeature$Stub$Proxy;
 Landroid/telephony/ims/aidl/IImsMmTelFeature$Stub;
 Landroid/telephony/ims/aidl/IImsMmTelFeature;
 Landroid/telephony/ims/aidl/IImsMmTelListener$Stub$Proxy;
@@ -30366,6 +30471,7 @@
 Landroid/telephony/ims/aidl/IImsRcsController;
 Landroid/telephony/ims/aidl/IImsRcsFeature$Stub;
 Landroid/telephony/ims/aidl/IImsRcsFeature;
+Landroid/telephony/ims/aidl/IImsRegistration$Stub$Proxy;
 Landroid/telephony/ims/aidl/IImsRegistration$Stub;
 Landroid/telephony/ims/aidl/IImsRegistration;
 Landroid/telephony/ims/aidl/IImsRegistrationCallback$Stub$Proxy;
@@ -30504,7 +30610,6 @@
 Landroid/text/Layout$TabStops;
 Landroid/text/Layout$TextInclusionStrategy;
 Landroid/text/Layout;
-Landroid/text/MeasuredParagraph$StyleRunCallback;
 Landroid/text/MeasuredParagraph;
 Landroid/text/NoCopySpan$Concrete;
 Landroid/text/NoCopySpan;
@@ -30545,7 +30650,6 @@
 Landroid/text/TextFlags;
 Landroid/text/TextLine$DecorationInfo-IA;
 Landroid/text/TextLine$DecorationInfo;
-Landroid/text/TextLine$LineInfo;
 Landroid/text/TextLine;
 Landroid/text/TextPaint;
 Landroid/text/TextShaper$GlyphsConsumer;
@@ -30630,7 +30734,6 @@
 Landroid/text/style/LeadingMarginSpan;
 Landroid/text/style/LineBackgroundSpan$Standard;
 Landroid/text/style/LineBackgroundSpan;
-Landroid/text/style/LineBreakConfigSpan$1;
 Landroid/text/style/LineBreakConfigSpan;
 Landroid/text/style/LineHeightSpan$Standard;
 Landroid/text/style/LineHeightSpan$WithDensity;
@@ -30684,7 +30787,6 @@
 Landroid/timezone/TelephonyNetwork;
 Landroid/timezone/TelephonyNetworkFinder;
 Landroid/timezone/TimeZoneFinder;
-Landroid/tracing/Flags;
 Landroid/tracing/perfetto/CreateIncrementalStateArgs;
 Landroid/tracing/perfetto/CreateTlsStateArgs;
 Landroid/tracing/perfetto/DataSource;
@@ -30884,6 +30986,7 @@
 Landroid/util/SparseLongArray;
 Landroid/util/SparseSetArray;
 Landroid/util/Spline$LinearSpline;
+Landroid/util/Spline$MonotoneCubicSpline;
 Landroid/util/Spline;
 Landroid/util/StateSet;
 Landroid/util/StringBuilderPrinter;
@@ -31110,7 +31213,6 @@
 Landroid/view/IScrollCaptureResponseListener$Stub$Proxy;
 Landroid/view/IScrollCaptureResponseListener$Stub;
 Landroid/view/IScrollCaptureResponseListener;
-Landroid/view/ISensitiveContentProtectionManager$Stub$Proxy;
 Landroid/view/ISensitiveContentProtectionManager$Stub;
 Landroid/view/ISensitiveContentProtectionManager;
 Landroid/view/ISurfaceControlViewHost;
@@ -31137,7 +31239,6 @@
 Landroid/view/IWindowSessionCallback$Stub$Proxy;
 Landroid/view/IWindowSessionCallback$Stub;
 Landroid/view/IWindowSessionCallback;
-Landroid/view/ImeBackAnimationController;
 Landroid/view/ImeFocusController$InputMethodManagerDelegate;
 Landroid/view/ImeFocusController;
 Landroid/view/ImeInsetsSourceConsumer;
@@ -31199,6 +31300,7 @@
 Landroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda3;
 Landroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda4;
 Landroid/view/InsetsController$InternalAnimationControlListener$1;
+Landroid/view/InsetsController$InternalAnimationControlListener$2;
 Landroid/view/InsetsController$InternalAnimationControlListener;
 Landroid/view/InsetsController$PendingControlRequest;
 Landroid/view/InsetsController$RunningAnimation;
@@ -31287,7 +31389,6 @@
 Landroid/view/ScaleGestureDetector$OnScaleGestureListener;
 Landroid/view/ScaleGestureDetector$SimpleOnScaleGestureListener;
 Landroid/view/ScaleGestureDetector;
-Landroid/view/ScrollCaptureSearchResults$$ExternalSyntheticLambda0;
 Landroid/view/ScrollCaptureSearchResults;
 Landroid/view/ScrollFeedbackProvider;
 Landroid/view/SearchEvent;
@@ -31306,7 +31407,6 @@
 Landroid/view/SurfaceControl$DisplayMode;
 Landroid/view/SurfaceControl$DisplayPrimaries;
 Landroid/view/SurfaceControl$DynamicDisplayInfo;
-Landroid/view/SurfaceControl$IdleScreenRefreshRateConfig;
 Landroid/view/SurfaceControl$JankData;
 Landroid/view/SurfaceControl$OnJankDataListener;
 Landroid/view/SurfaceControl$OnReparentListener;
@@ -31615,14 +31715,12 @@
 Landroid/view/WindowManagerGlobal$$ExternalSyntheticLambda0;
 Landroid/view/WindowManagerGlobal$1;
 Landroid/view/WindowManagerGlobal$2;
-Landroid/view/WindowManagerGlobal$TrustedPresentationListener-IA;
 Landroid/view/WindowManagerGlobal$TrustedPresentationListener;
 Landroid/view/WindowManagerGlobal;
 Landroid/view/WindowManagerImpl;
 Landroid/view/WindowManagerPolicyConstants$PointerEventListener;
 Landroid/view/WindowManagerPolicyConstants;
 Landroid/view/WindowMetrics;
-Landroid/view/WindowRelayoutResult;
 Landroid/view/WindowlessWindowLayout;
 Landroid/view/WindowlessWindowManager;
 Landroid/view/accessibility/AccessibilityCache$AccessibilityNodeRefresher;
@@ -31666,8 +31764,6 @@
 Landroid/view/accessibility/CaptioningManager$MyContentObserver;
 Landroid/view/accessibility/CaptioningManager;
 Landroid/view/accessibility/DirectAccessibilityConnection;
-Landroid/view/accessibility/FeatureFlags;
-Landroid/view/accessibility/FeatureFlagsImpl;
 Landroid/view/accessibility/Flags;
 Landroid/view/accessibility/IAccessibilityEmbeddedConnection;
 Landroid/view/accessibility/IAccessibilityInteractionConnection$Stub$Proxy;
@@ -31793,6 +31889,7 @@
 Landroid/view/contentcapture/IContentCaptureManager;
 Landroid/view/contentcapture/IContentCaptureOptionsCallback$Stub;
 Landroid/view/contentcapture/IContentCaptureOptionsCallback;
+Landroid/view/contentcapture/IDataShareWriteAdapter$Stub$Proxy;
 Landroid/view/contentcapture/IDataShareWriteAdapter$Stub;
 Landroid/view/contentcapture/IDataShareWriteAdapter;
 Landroid/view/contentcapture/MainContentCaptureSession$$ExternalSyntheticLambda0;
@@ -31847,8 +31944,6 @@
 Landroid/view/inputmethod/ExtractedText;
 Landroid/view/inputmethod/ExtractedTextRequest$1;
 Landroid/view/inputmethod/ExtractedTextRequest;
-Landroid/view/inputmethod/FeatureFlags;
-Landroid/view/inputmethod/FeatureFlagsImpl;
 Landroid/view/inputmethod/Flags;
 Landroid/view/inputmethod/HandwritingGesture;
 Landroid/view/inputmethod/IAccessibilityInputMethodSessionInvoker$$ExternalSyntheticLambda0;
@@ -32449,7 +32544,6 @@
 Landroid/widget/RemoteViews$BitmapCache;
 Landroid/widget/RemoteViews$BitmapReflectionAction;
 Landroid/widget/RemoteViews$ComplexUnitDimensionReflectionAction;
-Landroid/widget/RemoteViews$DrawInstructions;
 Landroid/widget/RemoteViews$HierarchyRootData;
 Landroid/widget/RemoteViews$InteractionHandler;
 Landroid/widget/RemoteViews$LayoutParamAction;
@@ -32608,12 +32702,10 @@
 Landroid/widget/ViewFlipper;
 Landroid/widget/ViewSwitcher;
 Landroid/widget/WrapperListAdapter;
-Landroid/widget/flags/Flags;
 Landroid/widget/inline/InlinePresentationSpec$1;
 Landroid/widget/inline/InlinePresentationSpec$BaseBuilder;
 Landroid/widget/inline/InlinePresentationSpec$Builder;
 Landroid/widget/inline/InlinePresentationSpec;
-Landroid/window/ActivityWindowInfo$1;
 Landroid/window/ActivityWindowInfo;
 Landroid/window/BackAnimationAdapter$1;
 Landroid/window/BackAnimationAdapter;
@@ -32622,12 +32714,9 @@
 Landroid/window/BackMotionEvent;
 Landroid/window/BackNavigationInfo$1;
 Landroid/window/BackNavigationInfo;
-Landroid/window/BackProgressAnimator$$ExternalSyntheticLambda0;
 Landroid/window/BackProgressAnimator$1;
 Landroid/window/BackProgressAnimator$ProgressCallback;
 Landroid/window/BackProgressAnimator;
-Landroid/window/BackTouchTracker$TouchTrackerState;
-Landroid/window/BackTouchTracker;
 Landroid/window/ClientWindowFrames$1;
 Landroid/window/ClientWindowFrames-IA;
 Landroid/window/ClientWindowFrames;
@@ -32661,6 +32750,7 @@
 Landroid/window/ITaskFragmentOrganizer;
 Landroid/window/ITaskFragmentOrganizerController$Stub;
 Landroid/window/ITaskFragmentOrganizerController;
+Landroid/window/ITaskOrganizer$Stub$Proxy;
 Landroid/window/ITaskOrganizer$Stub;
 Landroid/window/ITaskOrganizer;
 Landroid/window/ITaskOrganizerController$Stub$Proxy;
@@ -32684,11 +32774,8 @@
 Landroid/window/ImeOnBackInvokedDispatcher$$ExternalSyntheticLambda0;
 Landroid/window/ImeOnBackInvokedDispatcher$1;
 Landroid/window/ImeOnBackInvokedDispatcher$2;
-Landroid/window/ImeOnBackInvokedDispatcher$DefaultImeOnBackAnimationCallback;
 Landroid/window/ImeOnBackInvokedDispatcher$ImeOnBackInvokedCallback;
 Landroid/window/ImeOnBackInvokedDispatcher;
-Landroid/window/InputTransferToken$1;
-Landroid/window/InputTransferToken;
 Landroid/window/OnBackAnimationCallback;
 Landroid/window/OnBackInvokedCallback;
 Landroid/window/OnBackInvokedCallbackInfo$1;
@@ -32712,7 +32799,6 @@
 Landroid/window/SizeConfigurationBuckets;
 Landroid/window/SplashScreen$SplashScreenManagerGlobal$1;
 Landroid/window/SplashScreen$SplashScreenManagerGlobal;
-Landroid/window/SplashScreen;
 Landroid/window/SplashScreenView$SplashScreenViewParcelable$1;
 Landroid/window/SplashScreenView$SplashScreenViewParcelable;
 Landroid/window/SplashScreenView;
@@ -32740,7 +32826,6 @@
 Landroid/window/TaskFragmentOrganizer;
 Landroid/window/TaskFragmentOrganizerToken$1;
 Landroid/window/TaskFragmentOrganizerToken;
-Landroid/window/TaskFragmentTransaction$1;
 Landroid/window/TaskFragmentTransaction;
 Landroid/window/TaskOrganizer$1;
 Landroid/window/TaskOrganizer;
@@ -32775,6 +32860,7 @@
 Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$$ExternalSyntheticLambda2;
 Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$$ExternalSyntheticLambda3;
 Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$$ExternalSyntheticLambda4;
+Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$$ExternalSyntheticLambda5;
 Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$CallbackRef;
 Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper;
 Landroid/window/WindowOnBackInvokedDispatcher;
@@ -32859,9 +32945,6 @@
 Lcom/android/framework/protobuf/nano/InvalidProtocolBufferNanoException;
 Lcom/android/framework/protobuf/nano/MessageNano;
 Lcom/android/framework/protobuf/nano/WireFormatNano;
-Lcom/android/graphics/flags/Flags;
-Lcom/android/graphics/hwui/flags/FeatureFlags;
-Lcom/android/graphics/hwui/flags/FeatureFlagsImpl;
 Lcom/android/graphics/hwui/flags/Flags;
 Lcom/android/i18n/phonenumbers/AlternateFormatsCountryCodeSet;
 Lcom/android/i18n/phonenumbers/AsYouTypeFormatter;
@@ -32981,7 +33064,6 @@
 Lcom/android/i18n/timezone/internal/MemoryMappedFile;
 Lcom/android/i18n/timezone/internal/NioBufferIterator;
 Lcom/android/i18n/util/Log;
-Lcom/android/icu/charset/CharsetDecoderICU;
 Lcom/android/icu/charset/CharsetEncoderICU;
 Lcom/android/icu/charset/CharsetFactory;
 Lcom/android/icu/charset/NativeConverter;
@@ -33051,6 +33133,7 @@
 Lcom/android/ims/ImsManager$$ExternalSyntheticLambda3;
 Lcom/android/ims/ImsManager$$ExternalSyntheticLambda4;
 Lcom/android/ims/ImsManager$$ExternalSyntheticLambda5;
+Lcom/android/ims/ImsManager$$ExternalSyntheticLambda6;
 Lcom/android/ims/ImsManager$$ExternalSyntheticLambda7;
 Lcom/android/ims/ImsManager$$ExternalSyntheticLambda8;
 Lcom/android/ims/ImsManager$$ExternalSyntheticLambda9;
@@ -33129,6 +33212,7 @@
 Lcom/android/ims/internal/IImsRegistrationListener;
 Lcom/android/ims/internal/IImsServiceController$Stub;
 Lcom/android/ims/internal/IImsServiceController;
+Lcom/android/ims/internal/IImsServiceFeatureCallback$Stub$Proxy;
 Lcom/android/ims/internal/IImsServiceFeatureCallback$Stub;
 Lcom/android/ims/internal/IImsServiceFeatureCallback;
 Lcom/android/ims/internal/IImsStreamMediaSession;
@@ -33383,8 +33467,6 @@
 Lcom/android/ims/rcs/uce/util/FeatureTags;
 Lcom/android/ims/rcs/uce/util/NetworkSipCode;
 Lcom/android/ims/rcs/uce/util/UceUtils;
-Lcom/android/input/flags/FeatureFlags;
-Lcom/android/input/flags/FeatureFlagsImpl;
 Lcom/android/input/flags/Flags;
 Lcom/android/internal/R$attr;
 Lcom/android/internal/R$dimen;
@@ -33412,6 +33494,7 @@
 Lcom/android/internal/app/IAppOpsActiveCallback;
 Lcom/android/internal/app/IAppOpsAsyncNotedCallback$Stub;
 Lcom/android/internal/app/IAppOpsAsyncNotedCallback;
+Lcom/android/internal/app/IAppOpsCallback$Stub$Proxy;
 Lcom/android/internal/app/IAppOpsCallback$Stub;
 Lcom/android/internal/app/IAppOpsCallback;
 Lcom/android/internal/app/IAppOpsNotedCallback$Stub;
@@ -33506,7 +33589,6 @@
 Lcom/android/internal/colorextraction/types/Tonal$TonalPalette;
 Lcom/android/internal/colorextraction/types/Tonal;
 Lcom/android/internal/compat/AndroidBuildClassifier;
-Lcom/android/internal/compat/ChangeReporter$$ExternalSyntheticLambda0;
 Lcom/android/internal/compat/ChangeReporter$ChangeReport;
 Lcom/android/internal/compat/ChangeReporter;
 Lcom/android/internal/compat/CompatibilityChangeConfig$1;
@@ -33520,9 +33602,6 @@
 Lcom/android/internal/compat/IPlatformCompat;
 Lcom/android/internal/compat/IPlatformCompatNative$Stub;
 Lcom/android/internal/compat/IPlatformCompatNative;
-Lcom/android/internal/compat/flags/FeatureFlags;
-Lcom/android/internal/compat/flags/FeatureFlagsImpl;
-Lcom/android/internal/compat/flags/Flags;
 Lcom/android/internal/config/appcloning/AppCloningDeviceConfigHelper$$ExternalSyntheticLambda0;
 Lcom/android/internal/config/appcloning/AppCloningDeviceConfigHelper;
 Lcom/android/internal/config/sysui/SystemUiSystemPropertiesFlags$DebugResolver;
@@ -33571,7 +33650,6 @@
 Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$8;
 Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$9;
 Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$MassState;
-Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$OnAnimationEndListener;
 Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$ViewProperty;
 Lcom/android/internal/dynamicanimation/animation/DynamicAnimation;
 Lcom/android/internal/dynamicanimation/animation/Force;
@@ -33591,15 +33669,6 @@
 Lcom/android/internal/graphics/drawable/BackgroundBlurDrawable$BlurRegion;
 Lcom/android/internal/graphics/drawable/BackgroundBlurDrawable-IA;
 Lcom/android/internal/graphics/drawable/BackgroundBlurDrawable;
-Lcom/android/internal/hidden_from_bootclasspath/android/app/job/Flags;
-Lcom/android/internal/hidden_from_bootclasspath/android/content/pm/FeatureFlags;
-Lcom/android/internal/hidden_from_bootclasspath/android/content/pm/FeatureFlagsImpl;
-Lcom/android/internal/hidden_from_bootclasspath/android/content/pm/Flags;
-Lcom/android/internal/hidden_from_bootclasspath/android/os/FeatureFlags;
-Lcom/android/internal/hidden_from_bootclasspath/android/os/FeatureFlagsImpl;
-Lcom/android/internal/hidden_from_bootclasspath/android/os/Flags;
-Lcom/android/internal/hidden_from_bootclasspath/android/service/notification/FeatureFlags;
-Lcom/android/internal/hidden_from_bootclasspath/android/service/notification/FeatureFlagsImpl;
 Lcom/android/internal/hidden_from_bootclasspath/android/service/notification/Flags;
 Lcom/android/internal/infra/AbstractMultiplePendingRequestsRemoteService;
 Lcom/android/internal/infra/AbstractRemoteService$AsyncRequest;
@@ -33763,7 +33832,8 @@
 Lcom/android/internal/os/BinderDeathDispatcher$RecipientsInfo-IA;
 Lcom/android/internal/os/BinderDeathDispatcher$RecipientsInfo;
 Lcom/android/internal/os/BinderDeathDispatcher;
-Lcom/android/internal/os/BinderInternal$BinderProxyCountEventListenerDelegate;
+Lcom/android/internal/os/BinderInternal$BinderProxyLimitListener;
+Lcom/android/internal/os/BinderInternal$BinderProxyLimitListenerDelegate;
 Lcom/android/internal/os/BinderInternal$CallSession;
 Lcom/android/internal/os/BinderInternal$CallStatsObserver;
 Lcom/android/internal/os/BinderInternal$GcWatcher;
@@ -33782,9 +33852,6 @@
 Lcom/android/internal/os/CachedDeviceState;
 Lcom/android/internal/os/ClassLoaderFactory;
 Lcom/android/internal/os/Clock;
-Lcom/android/internal/os/FeatureFlags;
-Lcom/android/internal/os/FeatureFlagsImpl;
-Lcom/android/internal/os/Flags;
 Lcom/android/internal/os/FuseAppLoop$1;
 Lcom/android/internal/os/FuseAppLoop;
 Lcom/android/internal/os/FuseUnavailableMountException;
@@ -33891,11 +33958,10 @@
 Lcom/android/internal/os/logging/MetricsLoggerWrapper;
 Lcom/android/internal/pm/parsing/PackageParser2$Callback;
 Lcom/android/internal/pm/parsing/PackageParserException;
-Lcom/android/internal/pm/pkg/component/flags/FeatureFlags;
-Lcom/android/internal/pm/pkg/component/flags/FeatureFlagsImpl;
 Lcom/android/internal/pm/pkg/component/flags/Flags;
 Lcom/android/internal/pm/pkg/parsing/ParsingPackageUtils$Callback;
 Lcom/android/internal/policy/AttributeCache;
+Lcom/android/internal/policy/BackdropFrameRenderer;
 Lcom/android/internal/policy/DecorContext;
 Lcom/android/internal/policy/DecorView$$ExternalSyntheticLambda0;
 Lcom/android/internal/policy/DecorView$$ExternalSyntheticLambda1;
@@ -33962,6 +34028,7 @@
 Lcom/android/internal/protolog/common/LogDataType;
 Lcom/android/internal/security/VerityUtils;
 Lcom/android/internal/statusbar/IAddTileResultCallback;
+Lcom/android/internal/statusbar/IStatusBar$Stub$Proxy;
 Lcom/android/internal/statusbar/IStatusBar$Stub;
 Lcom/android/internal/statusbar/IStatusBar;
 Lcom/android/internal/statusbar/IStatusBarService$Stub$Proxy;
@@ -34044,8 +34111,6 @@
 Lcom/android/internal/telephony/CarrierInfoManager;
 Lcom/android/internal/telephony/CarrierKeyDownloadManager$1;
 Lcom/android/internal/telephony/CarrierKeyDownloadManager$2;
-Lcom/android/internal/telephony/CarrierKeyDownloadManager$3;
-Lcom/android/internal/telephony/CarrierKeyDownloadManager$DefaultNetworkCallback;
 Lcom/android/internal/telephony/CarrierKeyDownloadManager;
 Lcom/android/internal/telephony/CarrierPrivilegesTracker$1;
 Lcom/android/internal/telephony/CarrierPrivilegesTracker;
@@ -34200,6 +34265,7 @@
 Lcom/android/internal/telephony/ISub$Stub$Proxy;
 Lcom/android/internal/telephony/ISub$Stub;
 Lcom/android/internal/telephony/ISub;
+Lcom/android/internal/telephony/ITelephony$Stub$Proxy;
 Lcom/android/internal/telephony/ITelephony$Stub;
 Lcom/android/internal/telephony/ITelephony;
 Lcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy;
@@ -34374,6 +34440,7 @@
 Lcom/android/internal/telephony/RILConstants$$ExternalSyntheticLambda0;
 Lcom/android/internal/telephony/RILConstants$$ExternalSyntheticLambda1;
 Lcom/android/internal/telephony/RILConstants;
+Lcom/android/internal/telephony/RILRequest$$ExternalSyntheticLambda0;
 Lcom/android/internal/telephony/RILRequest;
 Lcom/android/internal/telephony/RadioBugDetector;
 Lcom/android/internal/telephony/RadioCapability;
@@ -35025,7 +35092,6 @@
 Lcom/android/internal/telephony/nano/PersistAtomsProto$CellularDataServiceSwitch;
 Lcom/android/internal/telephony/nano/PersistAtomsProto$CellularServiceState;
 Lcom/android/internal/telephony/nano/PersistAtomsProto$DataCallSession;
-Lcom/android/internal/telephony/nano/PersistAtomsProto$DataNetworkValidation;
 Lcom/android/internal/telephony/nano/PersistAtomsProto$EmergencyNumbersInfo;
 Lcom/android/internal/telephony/nano/PersistAtomsProto$GbaEvent;
 Lcom/android/internal/telephony/nano/PersistAtomsProto$ImsDedicatedBearerEvent;
@@ -35681,6 +35747,7 @@
 Lcom/android/internal/widget/ConversationLayout$1;
 Lcom/android/internal/widget/ConversationLayout$TouchDelegateComposite;
 Lcom/android/internal/widget/ConversationLayout;
+Lcom/android/internal/widget/DecorCaptionView;
 Lcom/android/internal/widget/DecorContentParent;
 Lcom/android/internal/widget/DecorToolbar;
 Lcom/android/internal/widget/DialogTitle;
@@ -35745,11 +35812,8 @@
 Lcom/android/internal/widget/floatingtoolbar/FloatingToolbar$$ExternalSyntheticLambda1;
 Lcom/android/internal/widget/floatingtoolbar/FloatingToolbar;
 Lcom/android/internal/widget/floatingtoolbar/FloatingToolbarPopup;
-Lcom/android/media/flags/FeatureFlags;
-Lcom/android/media/flags/FeatureFlagsImpl;
 Lcom/android/media/flags/Flags;
 Lcom/android/modules/expresslog/Counter;
-Lcom/android/modules/expresslog/MetricIds$MetricInfo;
 Lcom/android/modules/expresslog/MetricIds;
 Lcom/android/modules/expresslog/StatsExpressLog;
 Lcom/android/modules/utils/BasicShellCommandHandler;
@@ -35783,16 +35847,12 @@
 Lcom/android/phone/ecc/nano/ProtobufEccData$EccInfo;
 Lcom/android/phone/ecc/nano/UnknownFieldData;
 Lcom/android/phone/ecc/nano/WireFormatNano;
-Lcom/android/sdksandbox/flags/FeatureFlags;
-Lcom/android/sdksandbox/flags/FeatureFlagsImpl;
 Lcom/android/sdksandbox/flags/Flags;
 Lcom/android/server/AppWidgetBackupBridge;
 Lcom/android/server/LocalServices;
 Lcom/android/server/WidgetBackupProvider;
 Lcom/android/server/am/nano/Capabilities;
 Lcom/android/server/am/nano/Capability;
-Lcom/android/server/am/nano/FrameworkCapability;
-Lcom/android/server/am/nano/VMCapability;
 Lcom/android/server/backup/AccountManagerBackupHelper;
 Lcom/android/server/backup/AccountSyncSettingsBackupHelper;
 Lcom/android/server/backup/NotificationBackupHelper;
@@ -35821,7 +35881,6 @@
 Lcom/android/server/criticalevents/nano/CriticalEventLogProto;
 Lcom/android/server/criticalevents/nano/CriticalEventLogStorageProto;
 Lcom/android/server/criticalevents/nano/CriticalEventProto$AppNotResponding;
-Lcom/android/server/criticalevents/nano/CriticalEventProto$ExcessiveBinderCalls;
 Lcom/android/server/criticalevents/nano/CriticalEventProto$HalfWatchdog;
 Lcom/android/server/criticalevents/nano/CriticalEventProto$InstallPackages;
 Lcom/android/server/criticalevents/nano/CriticalEventProto$JavaCrash;
@@ -35872,9 +35931,6 @@
 Lcom/android/server/sip/SipWakeupTimer$MyEvent;
 Lcom/android/server/sip/SipWakeupTimer$MyEventComparator;
 Lcom/android/server/sip/SipWakeupTimer;
-Lcom/android/server/telecom/flags/FeatureFlags;
-Lcom/android/server/telecom/flags/FeatureFlagsImpl;
-Lcom/android/server/telecom/flags/Flags;
 Lcom/android/server/usage/AppStandbyInternal$AppIdleStateChangeListener;
 Lcom/android/server/usage/AppStandbyInternal;
 Lcom/android/server/wm/nano/WindowManagerProtos$TaskSnapshotProto;
@@ -36344,6 +36400,7 @@
 Lgov/nist/javax/sip/stack/UDPMessageChannel$PingBackTimerTask;
 Lgov/nist/javax/sip/stack/UDPMessageChannel;
 Lgov/nist/javax/sip/stack/UDPMessageProcessor;
+Ljava/io/InterruptedIOException;
 Ljavax/microedition/khronos/egl/EGL10;
 Ljavax/microedition/khronos/egl/EGL11;
 Ljavax/microedition/khronos/egl/EGL;
@@ -36592,8 +36649,6 @@
 [Landroid/graphics/fonts/FontVariationAxis;
 [Landroid/hardware/CameraStatus;
 [Landroid/hardware/biometrics/BiometricSourceType;
-[Landroid/hardware/camera2/CameraCharacteristics$Key;
-[Landroid/hardware/camera2/marshal/MarshalQueryable;
 [Landroid/hardware/camera2/params/Capability;
 [Landroid/hardware/camera2/params/Face;
 [Landroid/hardware/camera2/params/HighSpeedVideoConfiguration;
@@ -36655,7 +36710,6 @@
 [Landroid/icu/impl/units/MeasureUnitImpl$InitialCompoundPart;
 [Landroid/icu/impl/units/MeasureUnitImpl$PowerPart;
 [Landroid/icu/impl/units/MeasureUnitImpl$UnitsParser$Token$Type;
-[Landroid/icu/lang/UCharacter$IdentifierType;
 [Landroid/icu/lang/UCharacter$UnicodeBlock;
 [Landroid/icu/lang/UScript$ScriptUsage;
 [Landroid/icu/lang/UScriptRun$ParenStackEntry;
@@ -36910,7 +36964,6 @@
 [Landroid/widget/SpellChecker$SpellParser;
 [Landroid/widget/TextView$BufferType;
 [Landroid/widget/TextView$ChangeWatcher;
-[Landroid/window/BackTouchTracker$TouchTrackerState;
 [Landroid/window/TransitionFilter$Requirement;
 [Lcom/android/framework/protobuf/GeneratedMessageLite$MethodToInvoke;
 [Lcom/android/framework/protobuf/MessageInfoFactory;
@@ -36998,4 +37051,4 @@
 [[Landroid/graphics/Rect;
 [[Landroid/media/ExifInterface$ExifTag;
 [[Landroid/widget/GridLayout$Arc;
-[[Lcom/android/internal/widget/LockPatternView$Cell;
+[[Lcom/android/internal/widget/LockPatternView$Cell;
\ No newline at end of file
diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt
index c830a7b..ee417e8 100644
--- a/config/boot-image-profile.txt
+++ b/config/boot-image-profile.txt
@@ -26,6 +26,7 @@
 HSPLandroid/accounts/Account;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/accounts/Account;->equals(Ljava/lang/Object;)Z
 HSPLandroid/accounts/Account;->hashCode()I
+HSPLandroid/accounts/Account;->onAccountAccessed(Ljava/lang/String;)V
 HSPLandroid/accounts/Account;->toString()Ljava/lang/String;
 HSPLandroid/accounts/Account;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/accounts/AccountManager$10;-><init>(Landroid/accounts/AccountManager;Landroid/app/Activity;Landroid/os/Handler;Landroid/accounts/AccountManagerCallback;Landroid/accounts/Account;Ljava/lang/String;ZLandroid/os/Bundle;)V
@@ -125,13 +126,13 @@
 HSPLandroid/animation/AnimationHandler$1;-><init>(Landroid/animation/AnimationHandler;)V
 HSPLandroid/animation/AnimationHandler$1;->doFrame(J)V+]Landroid/animation/AnimationHandler$AnimationFrameCallbackProvider;Landroid/animation/AnimationHandler$MyFrameCallbackProvider;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;-><init>(Landroid/animation/AnimationHandler;)V
-HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;->getFrameTime()J
-HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;->postFrameCallback(Landroid/view/Choreographer$FrameCallback;)V
+HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;->getFrameTime()J+]Landroid/view/Choreographer;Landroid/view/Choreographer;
+HSPLandroid/animation/AnimationHandler$MyFrameCallbackProvider;->postFrameCallback(Landroid/view/Choreographer$FrameCallback;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
 HSPLandroid/animation/AnimationHandler;-><init>()V
-HSPLandroid/animation/AnimationHandler;->addAnimationFrameCallback(Landroid/animation/AnimationHandler$AnimationFrameCallback;J)V+]Landroid/animation/AnimationHandler$AnimationFrameCallbackProvider;Landroid/animation/AnimationHandler$MyFrameCallbackProvider;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/animation/AnimationHandler;->autoCancelBasedOn(Landroid/animation/ObjectAnimator;)V
-HSPLandroid/animation/AnimationHandler;->cleanUpList()V
-HSPLandroid/animation/AnimationHandler;->doAnimationFrame(J)V+]Landroid/animation/AnimationHandler$AnimationFrameCallback;Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;,Lcom/android/internal/dynamicanimation/animation/SpringAnimation;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimationHandler;->addAnimationFrameCallback(Landroid/animation/AnimationHandler$AnimationFrameCallback;J)V
+HSPLandroid/animation/AnimationHandler;->autoCancelBasedOn(Landroid/animation/ObjectAnimator;)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimationHandler;->cleanUpList()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimationHandler;->doAnimationFrame(J)V+]Landroid/animation/AnimationHandler$AnimationFrameCallback;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;,Lcom/android/internal/dynamicanimation/animation/SpringAnimation;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/animation/AnimationHandler;->getAnimationCount()I
 HSPLandroid/animation/AnimationHandler;->getInstance()Landroid/animation/AnimationHandler;
 HSPLandroid/animation/AnimationHandler;->getProvider()Landroid/animation/AnimationHandler$AnimationFrameCallbackProvider;
@@ -156,18 +157,18 @@
 HSPLandroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda6;->call(Ljava/lang/Object;Ljava/lang/Object;Z)V
 HSPLandroid/animation/Animator$AnimatorCaller;-><clinit>()V
 HSPLandroid/animation/Animator$AnimatorCaller;->lambda$static$0(Landroid/animation/Animator$AnimatorListener;Landroid/animation/Animator;Z)V
-HSPLandroid/animation/Animator$AnimatorCaller;->lambda$static$4(Landroid/animation/ValueAnimator$AnimatorUpdateListener;Landroid/animation/ValueAnimator;Z)V
+HSPLandroid/animation/Animator$AnimatorCaller;->lambda$static$4(Landroid/animation/ValueAnimator$AnimatorUpdateListener;Landroid/animation/ValueAnimator;Z)V+]Landroid/animation/ValueAnimator$AnimatorUpdateListener;missing_types
 HSPLandroid/animation/Animator$AnimatorConstantState;-><init>(Landroid/animation/Animator;)V
 HSPLandroid/animation/Animator$AnimatorConstantState;->getChangingConfigurations()I
 HSPLandroid/animation/Animator$AnimatorConstantState;->newInstance()Landroid/animation/Animator;
 HSPLandroid/animation/Animator$AnimatorConstantState;->newInstance()Ljava/lang/Object;
-HSPLandroid/animation/Animator$AnimatorListener;->onAnimationEnd(Landroid/animation/Animator;Z)V+]Landroid/animation/Animator$AnimatorListener;megamorphic_types
-HSPLandroid/animation/Animator$AnimatorListener;->onAnimationStart(Landroid/animation/Animator;Z)V+]Landroid/animation/Animator$AnimatorListener;megamorphic_types
+HSPLandroid/animation/Animator$AnimatorListener;->onAnimationEnd(Landroid/animation/Animator;Z)V+]Landroid/animation/Animator$AnimatorListener;missing_types
+HSPLandroid/animation/Animator$AnimatorListener;->onAnimationStart(Landroid/animation/Animator;Z)V+]Landroid/animation/Animator$AnimatorListener;missing_types
 HSPLandroid/animation/Animator;-><init>()V
-HSPLandroid/animation/Animator;->addListener(Landroid/animation/Animator$AnimatorListener;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/Animator;->addListener(Landroid/animation/Animator$AnimatorListener;)V
 HSPLandroid/animation/Animator;->addPauseListener(Landroid/animation/Animator$AnimatorPauseListener;)V
 HSPLandroid/animation/Animator;->appendChangingConfigurations(I)V
-HSPLandroid/animation/Animator;->callOnList(Ljava/util/ArrayList;Landroid/animation/Animator$AnimatorCaller;Ljava/lang/Object;Z)V+]Landroid/animation/Animator$AnimatorCaller;megamorphic_types]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/concurrent/atomic/AtomicReference;Ljava/util/concurrent/atomic/AtomicReference;
+HSPLandroid/animation/Animator;->callOnList(Ljava/util/ArrayList;Landroid/animation/Animator$AnimatorCaller;Ljava/lang/Object;Z)V+]Landroid/animation/Animator$AnimatorCaller;Landroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda1;,Landroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda0;,Landroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda6;,Landroid/animation/Animator$AnimatorCaller$$ExternalSyntheticLambda2;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/concurrent/atomic/AtomicReference;Ljava/util/concurrent/atomic/AtomicReference;
 HSPLandroid/animation/Animator;->clone()Landroid/animation/Animator;
 HSPLandroid/animation/Animator;->createConstantState()Landroid/content/res/ConstantState;
 HSPLandroid/animation/Animator;->getBackgroundPauseDelay()J
@@ -176,10 +177,10 @@
 HSPLandroid/animation/Animator;->getStartAndEndTimes(Landroid/util/LongArray;J)V
 HSPLandroid/animation/Animator;->notifyEndListeners(Z)V
 HSPLandroid/animation/Animator;->notifyListeners(Landroid/animation/Animator$AnimatorCaller;Z)V
-HSPLandroid/animation/Animator;->notifyStartListeners(Z)V+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/Animator;->notifyStartListeners(Z)V
 HSPLandroid/animation/Animator;->pause()V
 HSPLandroid/animation/Animator;->removeAllListeners()V
-HSPLandroid/animation/Animator;->removeListener(Landroid/animation/Animator$AnimatorListener;)V
+HSPLandroid/animation/Animator;->removeListener(Landroid/animation/Animator$AnimatorListener;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/animation/Animator;->setAllowRunningAsynchronously(Z)V
 HSPLandroid/animation/AnimatorInflater$PathDataEvaluator;->evaluate(FLandroid/util/PathParser$PathData;Landroid/util/PathParser$PathData;)Landroid/util/PathParser$PathData;
 HSPLandroid/animation/AnimatorInflater$PathDataEvaluator;->evaluate(FLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
@@ -201,53 +202,53 @@
 HSPLandroid/animation/AnimatorListenerAdapter;->onAnimationEnd(Landroid/animation/Animator;)V
 HSPLandroid/animation/AnimatorListenerAdapter;->onAnimationStart(Landroid/animation/Animator;)V
 HSPLandroid/animation/AnimatorSet$1;-><init>(Landroid/animation/AnimatorSet;)V
-HSPLandroid/animation/AnimatorSet$1;->onAnimationEnd(Landroid/animation/Animator;)V
+HSPLandroid/animation/AnimatorSet$1;->onAnimationEnd(Landroid/animation/Animator;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
 HSPLandroid/animation/AnimatorSet$2;-><init>(Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;)V
 HSPLandroid/animation/AnimatorSet$2;->onAnimationEnd(Landroid/animation/Animator;)V
 HSPLandroid/animation/AnimatorSet$3;-><init>(Landroid/animation/AnimatorSet;)V
-HSPLandroid/animation/AnimatorSet$3;->compare(Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;)I
+HSPLandroid/animation/AnimatorSet$3;->compare(Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;)I+]Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;
 HSPLandroid/animation/AnimatorSet$3;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
 HSPLandroid/animation/AnimatorSet$AnimationEvent;-><init>(Landroid/animation/AnimatorSet$Node;I)V
-HSPLandroid/animation/AnimatorSet$AnimationEvent;->getTime()J
+HSPLandroid/animation/AnimatorSet$AnimationEvent;->getTime()J+]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;
 HSPLandroid/animation/AnimatorSet$Builder;-><init>(Landroid/animation/AnimatorSet;Landroid/animation/Animator;)V
 HSPLandroid/animation/AnimatorSet$Builder;->after(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
 HSPLandroid/animation/AnimatorSet$Builder;->before(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
 HSPLandroid/animation/AnimatorSet$Builder;->with(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
 HSPLandroid/animation/AnimatorSet$Node;-><init>(Landroid/animation/Animator;)V
 HSPLandroid/animation/AnimatorSet$Node;->addChild(Landroid/animation/AnimatorSet$Node;)V
-HSPLandroid/animation/AnimatorSet$Node;->addParent(Landroid/animation/AnimatorSet$Node;)V
+HSPLandroid/animation/AnimatorSet$Node;->addParent(Landroid/animation/AnimatorSet$Node;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;
 HSPLandroid/animation/AnimatorSet$Node;->addParents(Ljava/util/ArrayList;)V
-HSPLandroid/animation/AnimatorSet$Node;->addSibling(Landroid/animation/AnimatorSet$Node;)V
-HSPLandroid/animation/AnimatorSet$Node;->clone()Landroid/animation/AnimatorSet$Node;+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet$Node;->addSibling(Landroid/animation/AnimatorSet$Node;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;
+HSPLandroid/animation/AnimatorSet$Node;->clone()Landroid/animation/AnimatorSet$Node;+]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
 HSPLandroid/animation/AnimatorSet$SeekState;-><init>(Landroid/animation/AnimatorSet;)V
 HSPLandroid/animation/AnimatorSet$SeekState;->getPlayTimeNormalized()J
 HSPLandroid/animation/AnimatorSet$SeekState;->isActive()Z
 HSPLandroid/animation/AnimatorSet$SeekState;->reset()V
-HSPLandroid/animation/AnimatorSet;-><init>()V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;-><init>()V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
 HSPLandroid/animation/AnimatorSet;->addAnimationCallback(J)V
-HSPLandroid/animation/AnimatorSet;->addAnimationEndListener()V
+HSPLandroid/animation/AnimatorSet;->addAnimationEndListener()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
 HSPLandroid/animation/AnimatorSet;->cancel()V
 HSPLandroid/animation/AnimatorSet;->clone()Landroid/animation/Animator;
-HSPLandroid/animation/AnimatorSet;->clone()Landroid/animation/AnimatorSet;+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/HashMap;Ljava/util/HashMap;
-HSPLandroid/animation/AnimatorSet;->createDependencyGraph()V+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;]Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;->clone()Landroid/animation/AnimatorSet;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet;->createDependencyGraph()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/AnimatorSet$AnimationEvent;Landroid/animation/AnimatorSet$AnimationEvent;]Landroid/animation/AnimatorSet$Node;Landroid/animation/AnimatorSet$Node;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;
 HSPLandroid/animation/AnimatorSet;->doAnimationFrame(J)Z+]Landroid/animation/AnimatorSet$SeekState;Landroid/animation/AnimatorSet$SeekState;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/animation/AnimatorSet;->end()V
-HSPLandroid/animation/AnimatorSet;->endAnimation()V
+HSPLandroid/animation/AnimatorSet;->end()V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;
+HSPLandroid/animation/AnimatorSet;->endAnimation()V+]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Landroid/animation/AnimatorSet$SeekState;Landroid/animation/AnimatorSet$SeekState;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/animation/AnimatorSet;->ensureChildStartAndEndTimes()[J
 HSPLandroid/animation/AnimatorSet;->findLatestEventIdForTime(J)I
 HSPLandroid/animation/AnimatorSet;->findNextIndex(J[J)I
 HSPLandroid/animation/AnimatorSet;->findSiblings(Landroid/animation/AnimatorSet$Node;Ljava/util/ArrayList;)V
 HSPLandroid/animation/AnimatorSet;->getChangingConfigurations()I
-HSPLandroid/animation/AnimatorSet;->getChildAnimations()Ljava/util/ArrayList;
-HSPLandroid/animation/AnimatorSet;->getNodeForAnimation(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Node;
+HSPLandroid/animation/AnimatorSet;->getChildAnimations()Ljava/util/ArrayList;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;->getNodeForAnimation(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Node;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/animation/AnimatorSet;->getStartAndEndTimes(Landroid/util/LongArray;J)V
 HSPLandroid/animation/AnimatorSet;->getStartDelay()J
 HSPLandroid/animation/AnimatorSet;->getTotalDuration()J
-HSPLandroid/animation/AnimatorSet;->handleAnimationEvents(IIJ)V
-HSPLandroid/animation/AnimatorSet;->initAnimation()V
+HSPLandroid/animation/AnimatorSet;->handleAnimationEvents(IIJ)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet;->initAnimation()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
 HSPLandroid/animation/AnimatorSet;->initChildren()V
-HSPLandroid/animation/AnimatorSet;->isEmptySet(Landroid/animation/AnimatorSet;)Z
-HSPLandroid/animation/AnimatorSet;->isInitialized()Z
+HSPLandroid/animation/AnimatorSet;->isEmptySet(Landroid/animation/AnimatorSet;)Z+]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;->isInitialized()Z+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
 HSPLandroid/animation/AnimatorSet;->isRunning()Z
 HSPLandroid/animation/AnimatorSet;->isStarted()Z
 HSPLandroid/animation/AnimatorSet;->play(Landroid/animation/Animator;)Landroid/animation/AnimatorSet$Builder;
@@ -257,46 +258,46 @@
 HSPLandroid/animation/AnimatorSet;->pulseAnimationFrame(J)Z
 HSPLandroid/animation/AnimatorSet;->pulseFrame(Landroid/animation/AnimatorSet$Node;J)V
 HSPLandroid/animation/AnimatorSet;->removeAnimationCallback()V
-HSPLandroid/animation/AnimatorSet;->removeAnimationEndListener()V
+HSPLandroid/animation/AnimatorSet;->removeAnimationEndListener()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
 HSPLandroid/animation/AnimatorSet;->setDuration(J)Landroid/animation/Animator;
 HSPLandroid/animation/AnimatorSet;->setDuration(J)Landroid/animation/AnimatorSet;
 HSPLandroid/animation/AnimatorSet;->setInterpolator(Landroid/animation/TimeInterpolator;)V
 HSPLandroid/animation/AnimatorSet;->setStartDelay(J)V
-HSPLandroid/animation/AnimatorSet;->setTarget(Ljava/lang/Object;)V
+HSPLandroid/animation/AnimatorSet;->setTarget(Ljava/lang/Object;)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/animation/AnimatorSet;->shouldPlayTogether()Z
 HSPLandroid/animation/AnimatorSet;->skipToEndValue(Z)V
-HSPLandroid/animation/AnimatorSet;->sortAnimationEvents()V+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/AnimatorSet;->sortAnimationEvents()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;
 HSPLandroid/animation/AnimatorSet;->start()V
-HSPLandroid/animation/AnimatorSet;->start(ZZ)V
-HSPLandroid/animation/AnimatorSet;->startAnimation()V
+HSPLandroid/animation/AnimatorSet;->start(ZZ)V+]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet;->startAnimation()V+]Landroid/animation/AnimatorSet;Landroid/animation/AnimatorSet;]Landroid/animation/AnimatorSet$SeekState;Landroid/animation/AnimatorSet$SeekState;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
 HSPLandroid/animation/AnimatorSet;->startWithoutPulsing(Z)V
-HSPLandroid/animation/AnimatorSet;->updateAnimatorsDuration()V
-HSPLandroid/animation/AnimatorSet;->updatePlayTime(Landroid/animation/AnimatorSet$Node;Ljava/util/ArrayList;)V
+HSPLandroid/animation/AnimatorSet;->updateAnimatorsDuration()V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
+HSPLandroid/animation/AnimatorSet;->updatePlayTime(Landroid/animation/AnimatorSet$Node;Ljava/util/ArrayList;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;,Landroid/animation/AnimatorSet;,Landroid/animation/ValueAnimator;
 HSPLandroid/animation/ArgbEvaluator;-><init>()V
-HSPLandroid/animation/ArgbEvaluator;->evaluate(FLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+]Ljava/lang/Integer;Ljava/lang/Integer;
+HSPLandroid/animation/ArgbEvaluator;->evaluate(FLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/animation/ArgbEvaluator;->getInstance()Landroid/animation/ArgbEvaluator;
 HSPLandroid/animation/FloatKeyframeSet;-><init>([Landroid/animation/Keyframe$FloatKeyframe;)V
 HSPLandroid/animation/FloatKeyframeSet;->clone()Landroid/animation/FloatKeyframeSet;
 HSPLandroid/animation/FloatKeyframeSet;->clone()Landroid/animation/Keyframes;
-HSPLandroid/animation/FloatKeyframeSet;->getFloatValue(F)F+]Landroid/animation/Keyframe$FloatKeyframe;Landroid/animation/Keyframe$FloatKeyframe;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/FloatKeyframeSet;->getFloatValue(F)F+]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Landroid/animation/Keyframe$FloatKeyframe;Landroid/animation/Keyframe$FloatKeyframe;
 HSPLandroid/animation/FloatKeyframeSet;->getValue(F)Ljava/lang/Object;
 HSPLandroid/animation/IntKeyframeSet;-><init>([Landroid/animation/Keyframe$IntKeyframe;)V
-HSPLandroid/animation/IntKeyframeSet;->clone()Landroid/animation/IntKeyframeSet;+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/IntKeyframeSet;->clone()Landroid/animation/IntKeyframeSet;+]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;
 HSPLandroid/animation/IntKeyframeSet;->clone()Landroid/animation/Keyframes;
-HSPLandroid/animation/IntKeyframeSet;->getIntValue(F)I+]Landroid/animation/Keyframe$IntKeyframe;Landroid/animation/Keyframe$IntKeyframe;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/IntKeyframeSet;->getIntValue(F)I
 HSPLandroid/animation/Keyframe$FloatKeyframe;-><init>(F)V
 HSPLandroid/animation/Keyframe$FloatKeyframe;-><init>(FF)V
 HSPLandroid/animation/Keyframe$FloatKeyframe;->clone()Landroid/animation/Keyframe$FloatKeyframe;+]Landroid/animation/Keyframe$FloatKeyframe;Landroid/animation/Keyframe$FloatKeyframe;
 HSPLandroid/animation/Keyframe$FloatKeyframe;->clone()Landroid/animation/Keyframe;
 HSPLandroid/animation/Keyframe$FloatKeyframe;->getFloatValue()F
 HSPLandroid/animation/Keyframe$FloatKeyframe;->getValue()Ljava/lang/Object;
-HSPLandroid/animation/Keyframe$FloatKeyframe;->setValue(Ljava/lang/Object;)V
+HSPLandroid/animation/Keyframe$FloatKeyframe;->setValue(Ljava/lang/Object;)V+]Ljava/lang/Object;Ljava/lang/Float;]Ljava/lang/Float;Ljava/lang/Float;
 HSPLandroid/animation/Keyframe$IntKeyframe;-><init>(FI)V
-HSPLandroid/animation/Keyframe$IntKeyframe;->clone()Landroid/animation/Keyframe$IntKeyframe;+]Landroid/animation/Keyframe$IntKeyframe;Landroid/animation/Keyframe$IntKeyframe;
+HSPLandroid/animation/Keyframe$IntKeyframe;->clone()Landroid/animation/Keyframe$IntKeyframe;
 HSPLandroid/animation/Keyframe$IntKeyframe;->clone()Landroid/animation/Keyframe;
 HSPLandroid/animation/Keyframe$IntKeyframe;->getIntValue()I
 HSPLandroid/animation/Keyframe$IntKeyframe;->getValue()Ljava/lang/Object;
-HSPLandroid/animation/Keyframe$IntKeyframe;->setValue(Ljava/lang/Object;)V+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/lang/Object;Ljava/lang/Integer;
+HSPLandroid/animation/Keyframe$IntKeyframe;->setValue(Ljava/lang/Object;)V
 HSPLandroid/animation/Keyframe$ObjectKeyframe;-><init>(FLjava/lang/Object;)V
 HSPLandroid/animation/Keyframe$ObjectKeyframe;->clone()Landroid/animation/Keyframe$ObjectKeyframe;
 HSPLandroid/animation/Keyframe$ObjectKeyframe;->clone()Landroid/animation/Keyframe;
@@ -312,17 +313,17 @@
 HSPLandroid/animation/Keyframe;->setInterpolator(Landroid/animation/TimeInterpolator;)V
 HSPLandroid/animation/Keyframe;->setValueWasSetOnStart(Z)V
 HSPLandroid/animation/Keyframe;->valueWasSetOnStart()Z
-HSPLandroid/animation/KeyframeSet;-><init>([Landroid/animation/Keyframe;)V+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$FloatKeyframe;,Landroid/animation/Keyframe$IntKeyframe;,Landroid/animation/Keyframe$ObjectKeyframe;
+HSPLandroid/animation/KeyframeSet;-><init>([Landroid/animation/Keyframe;)V+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$ObjectKeyframe;,Landroid/animation/Keyframe$IntKeyframe;,Landroid/animation/Keyframe$FloatKeyframe;
 HSPLandroid/animation/KeyframeSet;->clone()Landroid/animation/KeyframeSet;
 HSPLandroid/animation/KeyframeSet;->clone()Landroid/animation/Keyframes;
 HSPLandroid/animation/KeyframeSet;->getKeyframes()Ljava/util/List;
-HSPLandroid/animation/KeyframeSet;->getValue(F)Ljava/lang/Object;+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$ObjectKeyframe;]Landroid/animation/TypeEvaluator;Landroid/animation/ArgbEvaluator;
+HSPLandroid/animation/KeyframeSet;->getValue(F)Ljava/lang/Object;+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$ObjectKeyframe;
 HSPLandroid/animation/KeyframeSet;->ofFloat([F)Landroid/animation/KeyframeSet;
 HSPLandroid/animation/KeyframeSet;->ofInt([I)Landroid/animation/KeyframeSet;
 HSPLandroid/animation/KeyframeSet;->ofObject([Ljava/lang/Object;)Landroid/animation/KeyframeSet;
 HSPLandroid/animation/KeyframeSet;->setEvaluator(Landroid/animation/TypeEvaluator;)V
 HSPLandroid/animation/LayoutTransition$1;->onAnimationEnd(Landroid/animation/Animator;)V
-HSPLandroid/animation/LayoutTransition$2;->onLayoutChange(Landroid/view/View;IIIIIIII)V+]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Ljava/lang/Object;Ljava/lang/Integer;]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/util/LinkedHashMap;Ljava/util/LinkedHashMap;
+HSPLandroid/animation/LayoutTransition$2;->onLayoutChange(Landroid/view/View;IIIIIIII)V
 HSPLandroid/animation/LayoutTransition$3;->onAnimationEnd(Landroid/animation/Animator;)V
 HSPLandroid/animation/LayoutTransition$3;->onAnimationStart(Landroid/animation/Animator;)V
 HSPLandroid/animation/LayoutTransition$4;->onAnimationEnd(Landroid/animation/Animator;)V
@@ -350,20 +351,20 @@
 HSPLandroid/animation/LayoutTransition;->setDuration(J)V
 HSPLandroid/animation/LayoutTransition;->setInterpolator(ILandroid/animation/TimeInterpolator;)V
 HSPLandroid/animation/LayoutTransition;->setStartDelay(IJ)V
-HSPLandroid/animation/LayoutTransition;->setupChangeAnimation(Landroid/view/ViewGroup;ILandroid/animation/Animator;JLandroid/view/View;)V+]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/view/View;missing_types]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/animation/LayoutTransition;->setupChangeAnimation(Landroid/view/ViewGroup;ILandroid/animation/Animator;JLandroid/view/View;)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/view/View;missing_types]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/animation/Animator;Landroid/animation/ObjectAnimator;
 HSPLandroid/animation/LayoutTransition;->showChild(Landroid/view/ViewGroup;Landroid/view/View;I)V
 HSPLandroid/animation/LayoutTransition;->startChangingAnimations()V
 HSPLandroid/animation/ObjectAnimator;-><init>()V
 HSPLandroid/animation/ObjectAnimator;-><init>(Ljava/lang/Object;Landroid/util/Property;)V
 HSPLandroid/animation/ObjectAnimator;-><init>(Ljava/lang/Object;Ljava/lang/String;)V
-HSPLandroid/animation/ObjectAnimator;->animateValue(F)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
+HSPLandroid/animation/ObjectAnimator;->animateValue(F)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
 HSPLandroid/animation/ObjectAnimator;->clone()Landroid/animation/Animator;
 HSPLandroid/animation/ObjectAnimator;->clone()Landroid/animation/ObjectAnimator;
-HSPLandroid/animation/ObjectAnimator;->getNameForTrace()Ljava/lang/String;+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/animation/ObjectAnimator;->getPropertyName()Ljava/lang/String;+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/animation/ObjectAnimator;->getTarget()Ljava/lang/Object;+]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/animation/ObjectAnimator;->getNameForTrace()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;
+HSPLandroid/animation/ObjectAnimator;->getPropertyName()Ljava/lang/String;+]Landroid/util/Property;missing_types
+HSPLandroid/animation/ObjectAnimator;->getTarget()Ljava/lang/Object;
 HSPLandroid/animation/ObjectAnimator;->hasSameTargetAndProperties(Landroid/animation/Animator;)Z
-HSPLandroid/animation/ObjectAnimator;->initAnimation()V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
+HSPLandroid/animation/ObjectAnimator;->initAnimation()V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
 HSPLandroid/animation/ObjectAnimator;->isInitialized()Z
 HSPLandroid/animation/ObjectAnimator;->ofFloat(Ljava/lang/Object;Landroid/util/Property;[F)Landroid/animation/ObjectAnimator;
 HSPLandroid/animation/ObjectAnimator;->ofFloat(Ljava/lang/Object;Ljava/lang/String;[F)Landroid/animation/ObjectAnimator;
@@ -376,7 +377,7 @@
 HSPLandroid/animation/ObjectAnimator;->setDuration(J)Landroid/animation/Animator;
 HSPLandroid/animation/ObjectAnimator;->setDuration(J)Landroid/animation/ObjectAnimator;
 HSPLandroid/animation/ObjectAnimator;->setDuration(J)Landroid/animation/ValueAnimator;
-HSPLandroid/animation/ObjectAnimator;->setFloatValues([F)V
+HSPLandroid/animation/ObjectAnimator;->setFloatValues([F)V+]Landroid/animation/ObjectAnimator;Landroid/animation/ObjectAnimator;
 HSPLandroid/animation/ObjectAnimator;->setIntValues([I)V
 HSPLandroid/animation/ObjectAnimator;->setObjectValues([Ljava/lang/Object;)V
 HSPLandroid/animation/ObjectAnimator;->setProperty(Landroid/util/Property;)V
@@ -402,50 +403,50 @@
 HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;
 HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;
 HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->getAnimatedValue()Ljava/lang/Object;
-HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V+]Landroid/util/FloatProperty;Landroid/view/View$12;,Landroid/view/View$13;]Landroid/util/Property;missing_types
+HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V+]Landroid/util/FloatProperty;Landroid/view/View$2;,Landroid/view/View$12;,Landroid/view/View$13;,Landroid/view/View$5;
 HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setFloatValues([F)V
 HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setProperty(Landroid/util/Property;)V
-HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setupSetter(Ljava/lang/Class;)V
+HSPLandroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;->setupSetter(Ljava/lang/Class;)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Long;Ljava/lang/Long;
 HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;-><init>(Ljava/lang/String;[I)V
-HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->calculateValue(F)V
+HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->calculateValue(F)V+]Landroid/animation/Keyframes$IntKeyframes;Landroid/animation/IntKeyframeSet;
 HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;
-HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;+]Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;
+HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;
 HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->getAnimatedValue()Ljava/lang/Object;
 HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V
 HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->setIntValues([I)V
-HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->setupSetter(Ljava/lang/Class;)V+]Ljava/lang/Long;Ljava/lang/Long;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;->setupSetter(Ljava/lang/Class;)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Long;Ljava/lang/Long;
 HSPLandroid/animation/PropertyValuesHolder$PropertyValues;-><init>()V
-HSPLandroid/animation/PropertyValuesHolder;-><init>(Landroid/util/Property;)V
+HSPLandroid/animation/PropertyValuesHolder;-><init>(Landroid/util/Property;)V+]Landroid/util/Property;missing_types
 HSPLandroid/animation/PropertyValuesHolder;-><init>(Ljava/lang/String;)V
 HSPLandroid/animation/PropertyValuesHolder;-><init>(Ljava/lang/String;Landroid/animation/PropertyValuesHolder-IA;)V
-HSPLandroid/animation/PropertyValuesHolder;->calculateValue(F)V
-HSPLandroid/animation/PropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;+]Landroid/animation/Keyframes;Landroid/animation/FloatKeyframeSet;,Landroid/animation/IntKeyframeSet;,Landroid/animation/KeyframeSet;
+HSPLandroid/animation/PropertyValuesHolder;->calculateValue(F)V+]Landroid/animation/Keyframes;Landroid/animation/KeyframeSet;
+HSPLandroid/animation/PropertyValuesHolder;->clone()Landroid/animation/PropertyValuesHolder;+]Landroid/animation/Keyframes;Landroid/animation/KeyframeSet;,Landroid/animation/IntKeyframeSet;,Landroid/animation/FloatKeyframeSet;
 HSPLandroid/animation/PropertyValuesHolder;->convertBack(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/animation/PropertyValuesHolder;->getAnimatedValue()Ljava/lang/Object;
 HSPLandroid/animation/PropertyValuesHolder;->getMethodName(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/animation/PropertyValuesHolder;->getPropertyFunction(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/reflect/Method;
 HSPLandroid/animation/PropertyValuesHolder;->getPropertyName()Ljava/lang/String;
-HSPLandroid/animation/PropertyValuesHolder;->getPropertyValues(Landroid/animation/PropertyValuesHolder$PropertyValues;)V+]Landroid/animation/Keyframes;Landroid/animation/FloatKeyframeSet;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/PropertyValuesHolder;->getPropertyValues(Landroid/animation/PropertyValuesHolder$PropertyValues;)V
 HSPLandroid/animation/PropertyValuesHolder;->getValueType()Ljava/lang/Class;
-HSPLandroid/animation/PropertyValuesHolder;->init()V+]Landroid/animation/Keyframes;Landroid/animation/KeyframeSet;
+HSPLandroid/animation/PropertyValuesHolder;->init()V
 HSPLandroid/animation/PropertyValuesHolder;->ofFloat(Landroid/util/Property;[F)Landroid/animation/PropertyValuesHolder;
 HSPLandroid/animation/PropertyValuesHolder;->ofFloat(Ljava/lang/String;[F)Landroid/animation/PropertyValuesHolder;
 HSPLandroid/animation/PropertyValuesHolder;->ofInt(Ljava/lang/String;[I)Landroid/animation/PropertyValuesHolder;
 HSPLandroid/animation/PropertyValuesHolder;->ofKeyframes(Ljava/lang/String;Landroid/animation/Keyframes;)Landroid/animation/PropertyValuesHolder;
 HSPLandroid/animation/PropertyValuesHolder;->ofObject(Ljava/lang/String;Landroid/animation/TypeEvaluator;[Ljava/lang/Object;)Landroid/animation/PropertyValuesHolder;
-HSPLandroid/animation/PropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V
+HSPLandroid/animation/PropertyValuesHolder;->setAnimatedValue(Ljava/lang/Object;)V+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder;
 HSPLandroid/animation/PropertyValuesHolder;->setEvaluator(Landroid/animation/TypeEvaluator;)V
 HSPLandroid/animation/PropertyValuesHolder;->setFloatValues([F)V
 HSPLandroid/animation/PropertyValuesHolder;->setIntValues([I)V
 HSPLandroid/animation/PropertyValuesHolder;->setObjectValues([Ljava/lang/Object;)V
 HSPLandroid/animation/PropertyValuesHolder;->setProperty(Landroid/util/Property;)V
 HSPLandroid/animation/PropertyValuesHolder;->setPropertyName(Ljava/lang/String;)V
-HSPLandroid/animation/PropertyValuesHolder;->setupEndValue(Ljava/lang/Object;)V+]Landroid/animation/Keyframes;Landroid/animation/IntKeyframeSet;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
+HSPLandroid/animation/PropertyValuesHolder;->setupEndValue(Ljava/lang/Object;)V
 HSPLandroid/animation/PropertyValuesHolder;->setupGetter(Ljava/lang/Class;)V
-HSPLandroid/animation/PropertyValuesHolder;->setupSetterAndGetter(Ljava/lang/Object;)V+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$FloatKeyframe;,Landroid/animation/Keyframe$IntKeyframe;,Landroid/animation/Keyframe$ObjectKeyframe;]Landroid/animation/Keyframes;Landroid/animation/FloatKeyframeSet;,Landroid/animation/IntKeyframeSet;,Landroid/animation/KeyframeSet;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;]Ljava/lang/Object;missing_types]Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
-HSPLandroid/animation/PropertyValuesHolder;->setupSetterOrGetter(Ljava/lang/Class;Ljava/util/HashMap;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/reflect/Method;+]Ljava/util/HashMap;Ljava/util/HashMap;
-HSPLandroid/animation/PropertyValuesHolder;->setupStartValue(Ljava/lang/Object;)V+]Landroid/animation/Keyframes;Landroid/animation/IntKeyframeSet;]Ljava/util/List;Ljava/util/Arrays$ArrayList;
-HSPLandroid/animation/PropertyValuesHolder;->setupValue(Ljava/lang/Object;Landroid/animation/Keyframe;)V+]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;]Ljava/lang/Object;missing_types]Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;
+HSPLandroid/animation/PropertyValuesHolder;->setupSetterAndGetter(Ljava/lang/Object;)V+]Ljava/lang/Object;missing_types]Landroid/animation/Keyframes;Landroid/animation/IntKeyframeSet;,Landroid/animation/FloatKeyframeSet;,Landroid/animation/KeyframeSet;]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;,Landroid/animation/Keyframe$FloatKeyframe;,Landroid/animation/Keyframe$ObjectKeyframe;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;]Landroid/util/Property;missing_types]Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;
+HSPLandroid/animation/PropertyValuesHolder;->setupSetterOrGetter(Ljava/lang/Class;Ljava/util/HashMap;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/reflect/Method;
+HSPLandroid/animation/PropertyValuesHolder;->setupStartValue(Ljava/lang/Object;)V
+HSPLandroid/animation/PropertyValuesHolder;->setupValue(Ljava/lang/Object;Landroid/animation/Keyframe;)V+]Ljava/lang/Object;missing_types]Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;]Landroid/animation/Keyframe;Landroid/animation/Keyframe$IntKeyframe;
 HSPLandroid/animation/StateListAnimator$1;-><init>(Landroid/animation/StateListAnimator;)V
 HSPLandroid/animation/StateListAnimator$1;->onAnimationEnd(Landroid/animation/Animator;)V
 HSPLandroid/animation/StateListAnimator$StateListAnimatorConstantState;-><init>(Landroid/animation/StateListAnimator;)V
@@ -453,10 +454,10 @@
 HSPLandroid/animation/StateListAnimator$StateListAnimatorConstantState;->newInstance()Ljava/lang/Object;
 HSPLandroid/animation/StateListAnimator$Tuple;-><init>([ILandroid/animation/Animator;)V
 HSPLandroid/animation/StateListAnimator;-><init>()V
-HSPLandroid/animation/StateListAnimator;->addState([ILandroid/animation/Animator;)V+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/StateListAnimator;->addState([ILandroid/animation/Animator;)V
 HSPLandroid/animation/StateListAnimator;->appendChangingConfigurations(I)V
 HSPLandroid/animation/StateListAnimator;->clearTarget()V
-HSPLandroid/animation/StateListAnimator;->clone()Landroid/animation/StateListAnimator;+]Landroid/animation/Animator;Landroid/animation/AnimatorSet;,Landroid/animation/ObjectAnimator;]Landroid/animation/StateListAnimator;Landroid/animation/StateListAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/animation/StateListAnimator;->clone()Landroid/animation/StateListAnimator;
 HSPLandroid/animation/StateListAnimator;->createConstantState()Landroid/content/res/ConstantState;
 HSPLandroid/animation/StateListAnimator;->getChangingConfigurations()I
 HSPLandroid/animation/StateListAnimator;->getTarget()Landroid/view/View;
@@ -472,17 +473,17 @@
 HSPLandroid/animation/ValueAnimator;->addAnimationCallback(J)V
 HSPLandroid/animation/ValueAnimator;->addUpdateListener(Landroid/animation/ValueAnimator$AnimatorUpdateListener;)V
 HSPLandroid/animation/ValueAnimator;->animateBasedOnTime(J)Z+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
-HSPLandroid/animation/ValueAnimator;->animateValue(F)V+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;]Landroid/animation/TimeInterpolator;missing_types]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->animateValue(F)V+]Landroid/animation/TimeInterpolator;missing_types]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;,Landroid/animation/ObjectAnimator;
 HSPLandroid/animation/ValueAnimator;->areAnimatorsEnabled()Z
 HSPLandroid/animation/ValueAnimator;->cancel()V
 HSPLandroid/animation/ValueAnimator;->clampFraction(F)F
 HSPLandroid/animation/ValueAnimator;->clone()Landroid/animation/Animator;
-HSPLandroid/animation/ValueAnimator;->clone()Landroid/animation/ValueAnimator;+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;]Ljava/util/HashMap;Ljava/util/HashMap;
-HSPLandroid/animation/ValueAnimator;->doAnimationFrame(J)Z+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->clone()Landroid/animation/ValueAnimator;+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
+HSPLandroid/animation/ValueAnimator;->doAnimationFrame(J)Z+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;,Landroid/animation/ObjectAnimator;
 HSPLandroid/animation/ValueAnimator;->end()V
-HSPLandroid/animation/ValueAnimator;->endAnimation()V+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->endAnimation()V
 HSPLandroid/animation/ValueAnimator;->getAnimatedFraction()F
-HSPLandroid/animation/ValueAnimator;->getAnimatedValue()Ljava/lang/Object;+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;
+HSPLandroid/animation/ValueAnimator;->getAnimatedValue()Ljava/lang/Object;+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;
 HSPLandroid/animation/ValueAnimator;->getAnimationHandler()Landroid/animation/AnimationHandler;
 HSPLandroid/animation/ValueAnimator;->getCurrentAnimationsCount()I
 HSPLandroid/animation/ValueAnimator;->getCurrentIteration(F)I
@@ -513,25 +514,25 @@
 HSPLandroid/animation/ValueAnimator;->resolveDurationScale()F
 HSPLandroid/animation/ValueAnimator;->setAllowRunningAsynchronously(Z)V
 HSPLandroid/animation/ValueAnimator;->setAnimationHandler(Landroid/animation/AnimationHandler;)V
-HSPLandroid/animation/ValueAnimator;->setCurrentFraction(F)V+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->setCurrentFraction(F)V
 HSPLandroid/animation/ValueAnimator;->setCurrentPlayTime(J)V
 HSPLandroid/animation/ValueAnimator;->setDuration(J)Landroid/animation/Animator;
 HSPLandroid/animation/ValueAnimator;->setDuration(J)Landroid/animation/ValueAnimator;
 HSPLandroid/animation/ValueAnimator;->setDurationScale(F)V
 HSPLandroid/animation/ValueAnimator;->setEvaluator(Landroid/animation/TypeEvaluator;)V
-HSPLandroid/animation/ValueAnimator;->setFloatValues([F)V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->setFloatValues([F)V
 HSPLandroid/animation/ValueAnimator;->setIntValues([I)V
 HSPLandroid/animation/ValueAnimator;->setInterpolator(Landroid/animation/TimeInterpolator;)V
 HSPLandroid/animation/ValueAnimator;->setObjectValues([Ljava/lang/Object;)V
 HSPLandroid/animation/ValueAnimator;->setRepeatCount(I)V
 HSPLandroid/animation/ValueAnimator;->setRepeatMode(I)V
 HSPLandroid/animation/ValueAnimator;->setStartDelay(J)V
-HSPLandroid/animation/ValueAnimator;->setValues([Landroid/animation/PropertyValuesHolder;)V+]Landroid/animation/PropertyValuesHolder;Landroid/animation/PropertyValuesHolder$FloatPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder$IntPropertyValuesHolder;,Landroid/animation/PropertyValuesHolder;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/animation/ValueAnimator;->setValues([Landroid/animation/PropertyValuesHolder;)V
 HSPLandroid/animation/ValueAnimator;->shouldPlayBackward(IZ)Z
 HSPLandroid/animation/ValueAnimator;->skipToEndValue(Z)V
 HSPLandroid/animation/ValueAnimator;->start()V
-HSPLandroid/animation/ValueAnimator;->start(Z)V+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
-HSPLandroid/animation/ValueAnimator;->startAnimation()V+]Landroid/animation/ValueAnimator;Landroid/animation/ObjectAnimator;,Landroid/animation/ValueAnimator;
+HSPLandroid/animation/ValueAnimator;->start(Z)V
+HSPLandroid/animation/ValueAnimator;->startAnimation()V
 HSPLandroid/animation/ValueAnimator;->startWithoutPulsing(Z)V
 HSPLandroid/app/Activity$1;-><init>(Landroid/app/Activity;)V
 HSPLandroid/app/Activity$1;->isTaskRoot()Z
@@ -545,7 +546,7 @@
 HSPLandroid/app/Activity;->attach(Landroid/content/Context;Landroid/app/ActivityThread;Landroid/app/Instrumentation;Landroid/os/IBinder;ILandroid/app/Application;Landroid/content/Intent;Landroid/content/pm/ActivityInfo;Ljava/lang/CharSequence;Landroid/app/Activity;Ljava/lang/String;Landroid/app/Activity$NonConfigurationInstances;Landroid/content/res/Configuration;Ljava/lang/String;Lcom/android/internal/app/IVoiceInteractor;Landroid/view/Window;Landroid/view/ViewRootImpl$ActivityConfigCallback;Landroid/os/IBinder;Landroid/os/IBinder;)V
 HSPLandroid/app/Activity;->attachBaseContext(Landroid/content/Context;)V
 HSPLandroid/app/Activity;->cancelInputsAndStartExitTransition(Landroid/os/Bundle;)V
-HSPLandroid/app/Activity;->collectActivityLifecycleCallbacks()[Ljava/lang/Object;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/app/Activity;->collectActivityLifecycleCallbacks()[Ljava/lang/Object;
 HSPLandroid/app/Activity;->dispatchActivityCreated(Landroid/os/Bundle;)V
 HSPLandroid/app/Activity;->dispatchActivityPostCreated(Landroid/os/Bundle;)V
 HSPLandroid/app/Activity;->dispatchActivityPostResumed()V
@@ -608,7 +609,7 @@
 HSPLandroid/app/Activity;->onCreateDescription()Ljava/lang/CharSequence;
 HSPLandroid/app/Activity;->onCreateOptionsMenu(Landroid/view/Menu;)Z
 HSPLandroid/app/Activity;->onCreatePanelMenu(ILandroid/view/Menu;)Z
-HSPLandroid/app/Activity;->onCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;+]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/app/Activity;->onCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
 HSPLandroid/app/Activity;->onCreateView(Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
 HSPLandroid/app/Activity;->onDestroy()V
 HSPLandroid/app/Activity;->onDetachedFromWindow()V
@@ -639,7 +640,7 @@
 HSPLandroid/app/Activity;->onTrimMemory(I)V
 HSPLandroid/app/Activity;->onUserInteraction()V
 HSPLandroid/app/Activity;->onUserLeaveHint()V
-HSPLandroid/app/Activity;->onWindowAttributesChanged(Landroid/view/WindowManager$LayoutParams;)V
+HSPLandroid/app/Activity;->onWindowAttributesChanged(Landroid/view/WindowManager$LayoutParams;)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/view/WindowManager;Landroid/view/WindowManagerImpl;
 HSPLandroid/app/Activity;->onWindowFocusChanged(Z)V
 HSPLandroid/app/Activity;->overridePendingTransition(II)V
 HSPLandroid/app/Activity;->overridePendingTransition(III)V
@@ -689,10 +690,10 @@
 HSPLandroid/app/ActivityClient;->activityStopped(Landroid/os/IBinder;Landroid/os/Bundle;Landroid/os/PersistableBundle;Ljava/lang/CharSequence;)V
 HSPLandroid/app/ActivityClient;->activityTopResumedStateLost()V
 HSPLandroid/app/ActivityClient;->finishActivity(Landroid/os/IBinder;ILandroid/content/Intent;I)Z
-HSPLandroid/app/ActivityClient;->getActivityClientController()Landroid/app/IActivityClientController;+]Landroid/app/ActivityClient$ActivityClientControllerSingleton;Landroid/app/ActivityClient$ActivityClientControllerSingleton;
+HSPLandroid/app/ActivityClient;->getActivityClientController()Landroid/app/IActivityClientController;
 HSPLandroid/app/ActivityClient;->getCallingActivity(Landroid/os/IBinder;)Landroid/content/ComponentName;
 HSPLandroid/app/ActivityClient;->getDisplayId(Landroid/os/IBinder;)I
-HSPLandroid/app/ActivityClient;->getInstance()Landroid/app/ActivityClient;+]Landroid/util/Singleton;Landroid/app/ActivityClient$1;
+HSPLandroid/app/ActivityClient;->getInstance()Landroid/app/ActivityClient;
 HSPLandroid/app/ActivityClient;->getTaskForActivity(Landroid/os/IBinder;Z)I
 HSPLandroid/app/ActivityClient;->overridePendingTransition(Landroid/os/IBinder;Ljava/lang/String;III)V
 HSPLandroid/app/ActivityClient;->reportActivityFullyDrawn(Landroid/os/IBinder;Z)V
@@ -868,7 +869,7 @@
 HSPLandroid/app/ActivityThread$GcIdler;-><init>(Landroid/app/ActivityThread;)V
 HSPLandroid/app/ActivityThread$GcIdler;->queueIdle()Z
 HSPLandroid/app/ActivityThread$H;-><init>(Landroid/app/ActivityThread;)V
-HSPLandroid/app/ActivityThread$H;->handleMessage(Landroid/os/Message;)V
+HSPLandroid/app/ActivityThread$H;->handleMessage(Landroid/os/Message;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/app/ActivityThread;Landroid/app/ActivityThread;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/app/servertransaction/TransactionExecutor;Landroid/app/servertransaction/TransactionExecutor;
 HSPLandroid/app/ActivityThread$Idler;-><init>(Landroid/app/ActivityThread;)V
 HSPLandroid/app/ActivityThread$Idler;-><init>(Landroid/app/ActivityThread;Landroid/app/ActivityThread$Idler-IA;)V
 HSPLandroid/app/ActivityThread$Idler;->queueIdle()Z
@@ -924,8 +925,8 @@
 HSPLandroid/app/ActivityThread;->deliverResults(Landroid/app/ActivityThread$ActivityClientRecord;Ljava/util/List;Ljava/lang/String;)V
 HSPLandroid/app/ActivityThread;->dumpMemoryInfo(Landroid/util/proto/ProtoOutputStream;JLjava/lang/String;IIIIIIZIII)V
 HSPLandroid/app/ActivityThread;->getActivitiesToBeDestroyed()Ljava/util/Map;
-HSPLandroid/app/ActivityThread;->getActivity(Landroid/os/IBinder;)Landroid/app/Activity;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
-HSPLandroid/app/ActivityThread;->getActivityClient(Landroid/os/IBinder;)Landroid/app/ActivityThread$ActivityClientRecord;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/app/ActivityThread;->getActivity(Landroid/os/IBinder;)Landroid/app/Activity;
+HSPLandroid/app/ActivityThread;->getActivityClient(Landroid/os/IBinder;)Landroid/app/ActivityThread$ActivityClientRecord;
 HSPLandroid/app/ActivityThread;->getApplication()Landroid/app/Application;
 HSPLandroid/app/ActivityThread;->getApplicationThread()Landroid/app/ActivityThread$ApplicationThread;
 HSPLandroid/app/ActivityThread;->getBackupAgentName(Landroid/app/ActivityThread$CreateBackupAgentData;)Ljava/lang/String;
@@ -935,7 +936,7 @@
 HSPLandroid/app/ActivityThread;->getGetProviderKey(Ljava/lang/String;I)Landroid/app/ActivityThread$ProviderKey;
 HSPLandroid/app/ActivityThread;->getHandler()Landroid/os/Handler;
 HSPLandroid/app/ActivityThread;->getInstrumentation()Landroid/app/Instrumentation;
-HSPLandroid/app/ActivityThread;->getIntCoreSetting(Ljava/lang/String;I)I
+HSPLandroid/app/ActivityThread;->getIntCoreSetting(Ljava/lang/String;I)I+]Landroid/os/Bundle;Landroid/os/Bundle;
 HSPLandroid/app/ActivityThread;->getIntentBeingBroadcast()Landroid/content/Intent;
 HSPLandroid/app/ActivityThread;->getLooper()Landroid/os/Looper;
 HSPLandroid/app/ActivityThread;->getOperationTypeFromBackupMode(I)I
@@ -957,7 +958,7 @@
 HSPLandroid/app/ActivityThread;->handleBindService(Landroid/app/ActivityThread$BindServiceData;)V
 HSPLandroid/app/ActivityThread;->handleConfigurationChanged(Landroid/content/res/Configuration;I)V
 HSPLandroid/app/ActivityThread;->handleCreateBackupAgent(Landroid/app/ActivityThread$CreateBackupAgentData;)V
-HSPLandroid/app/ActivityThread;->handleCreateService(Landroid/app/ActivityThread$CreateServiceData;)V
+HSPLandroid/app/ActivityThread;->handleCreateService(Landroid/app/ActivityThread$CreateServiceData;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/app/ActivityThread;Landroid/app/ActivityThread;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Ljava/util/List;Ljava/util/Collections$EmptyList;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/IActivityManager;Landroid/app/IActivityManager$Stub$Proxy;
 HSPLandroid/app/ActivityThread;->handleDestroyBackupAgent(Landroid/app/ActivityThread$CreateBackupAgentData;)V
 HSPLandroid/app/ActivityThread;->handleDispatchPackageBroadcast(I[Ljava/lang/String;)V
 HSPLandroid/app/ActivityThread;->handleDumpGfxInfo(Landroid/app/ActivityThread$DumpComponentInfo;)V
@@ -997,10 +998,11 @@
 HSPLandroid/app/ActivityThread;->isProtectedComponent(Landroid/content/pm/ComponentInfo;Ljava/lang/String;)Z
 HSPLandroid/app/ActivityThread;->isProtectedComponent(Landroid/content/pm/ServiceInfo;)Z
 HSPLandroid/app/ActivityThread;->isSystem()Z
+HSPLandroid/app/ActivityThread;->lambda$getGetProviderKey$3(Landroid/app/ActivityThread$ProviderKey;)Landroid/app/ActivityThread$ProviderKey;
 HSPLandroid/app/ActivityThread;->main([Ljava/lang/String;)V
 HSPLandroid/app/ActivityThread;->onCoreSettingsChange()V
 HSPLandroid/app/ActivityThread;->peekPackageInfo(Ljava/lang/String;Z)Landroid/app/LoadedApk;
-HSPLandroid/app/ActivityThread;->performLaunchActivity(Landroid/app/ActivityThread$ActivityClientRecord;Landroid/content/Intent;)Landroid/app/Activity;+]Landroid/app/ActivityThread$ActivityClientRecord;Landroid/app/ActivityThread$ActivityClientRecord;]Landroid/app/ActivityThread;Landroid/app/ActivityThread;]Landroid/app/ConfigurationController;Landroid/app/ConfigurationController;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/app/Instrumentation;Landroid/app/Instrumentation;]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/ComponentName;Landroid/content/ComponentName;]Landroid/content/Intent;Landroid/content/Intent;]Landroid/content/pm/ActivityInfo;Landroid/content/pm/ActivityInfo;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/List;Ljava/util/Collections$EmptyList;
+HSPLandroid/app/ActivityThread;->performLaunchActivity(Landroid/app/ActivityThread$ActivityClientRecord;Landroid/content/Intent;)Landroid/app/Activity;
 HSPLandroid/app/ActivityThread;->performPauseActivity(Landroid/app/ActivityThread$ActivityClientRecord;ZLjava/lang/String;Landroid/app/servertransaction/PendingTransactionActions;)Landroid/os/Bundle;
 HSPLandroid/app/ActivityThread;->performPauseActivityIfNeeded(Landroid/app/ActivityThread$ActivityClientRecord;Ljava/lang/String;)V
 HSPLandroid/app/ActivityThread;->performRestartActivity(Landroid/app/ActivityThread$ActivityClientRecord;Z)V
@@ -1071,7 +1073,7 @@
 HSPLandroid/app/AppComponentFactory;->instantiateReceiver(Ljava/lang/ClassLoader;Ljava/lang/String;Landroid/content/Intent;)Landroid/content/BroadcastReceiver;
 HSPLandroid/app/AppComponentFactory;->instantiateService(Ljava/lang/ClassLoader;Ljava/lang/String;Landroid/content/Intent;)Landroid/app/Service;
 HSPLandroid/app/AppGlobals;->getInitialApplication()Landroid/app/Application;
-HSPLandroid/app/AppGlobals;->getIntCoreSetting(Ljava/lang/String;I)I
+HSPLandroid/app/AppGlobals;->getIntCoreSetting(Ljava/lang/String;I)I+]Landroid/app/ActivityThread;Landroid/app/ActivityThread;
 HSPLandroid/app/AppGlobals;->getPackageManager()Landroid/content/pm/IPackageManager;
 HSPLandroid/app/AppOpsManager$1;->onNoted(Landroid/app/SyncNotedAppOp;)V
 HSPLandroid/app/AppOpsManager$1;->onSelfNoted(Landroid/app/SyncNotedAppOp;)V
@@ -1164,7 +1166,7 @@
 HSPLandroid/app/Application$ActivityLifecycleCallbacks;->onActivityPreStopped(Landroid/app/Activity;)V
 HSPLandroid/app/Application;-><init>()V
 HSPLandroid/app/Application;->attach(Landroid/content/Context;)V
-HSPLandroid/app/Application;->collectActivityLifecycleCallbacks()[Ljava/lang/Object;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/app/Application;->collectActivityLifecycleCallbacks()[Ljava/lang/Object;
 HSPLandroid/app/Application;->dispatchActivityCreated(Landroid/app/Activity;Landroid/os/Bundle;)V
 HSPLandroid/app/Application;->dispatchActivityDestroyed(Landroid/app/Activity;)V
 HSPLandroid/app/Application;->dispatchActivityPaused(Landroid/app/Activity;)V
@@ -1264,7 +1266,7 @@
 HSPLandroid/app/ApplicationPackageManager;->getInstalledPackagesAsUser(II)Ljava/util/List;
 HSPLandroid/app/ApplicationPackageManager;->getInstalledPackagesAsUser(Landroid/content/pm/PackageManager$PackageInfoFlags;I)Ljava/util/List;
 HSPLandroid/app/ApplicationPackageManager;->getInstallerPackageName(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/app/ApplicationPackageManager;->getLaunchIntentForPackage(Ljava/lang/String;)Landroid/content/Intent;+]Landroid/app/ApplicationPackageManager;Landroid/app/ApplicationPackageManager;]Landroid/content/Intent;Landroid/content/Intent;]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/app/ApplicationPackageManager;->getLaunchIntentForPackage(Ljava/lang/String;)Landroid/content/Intent;+]Ljava/util/List;Ljava/util/ArrayList;]Landroid/app/ApplicationPackageManager;Landroid/app/ApplicationPackageManager;]Landroid/content/Intent;Landroid/content/Intent;
 HSPLandroid/app/ApplicationPackageManager;->getModuleInfo(Ljava/lang/String;I)Landroid/content/pm/ModuleInfo;
 HSPLandroid/app/ApplicationPackageManager;->getNameForUid(I)Ljava/lang/String;
 HSPLandroid/app/ApplicationPackageManager;->getPackageInfo(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;
@@ -1288,7 +1290,7 @@
 HSPLandroid/app/ApplicationPackageManager;->getReceiverInfo(Landroid/content/ComponentName;I)Landroid/content/pm/ActivityInfo;
 HSPLandroid/app/ApplicationPackageManager;->getReceiverInfo(Landroid/content/ComponentName;Landroid/content/pm/PackageManager$ComponentInfoFlags;)Landroid/content/pm/ActivityInfo;
 HSPLandroid/app/ApplicationPackageManager;->getResourcesForApplication(Landroid/content/pm/ApplicationInfo;)Landroid/content/res/Resources;
-HSPLandroid/app/ApplicationPackageManager;->getResourcesForApplication(Landroid/content/pm/ApplicationInfo;Landroid/content/res/Configuration;)Landroid/content/res/Resources;
+HSPLandroid/app/ApplicationPackageManager;->getResourcesForApplication(Landroid/content/pm/ApplicationInfo;Landroid/content/res/Configuration;)Landroid/content/res/Resources;+]Landroid/app/ActivityThread;Landroid/app/ActivityThread;]Ljava/lang/Object;Ljava/lang/String;
 HSPLandroid/app/ApplicationPackageManager;->getResourcesForApplication(Ljava/lang/String;)Landroid/content/res/Resources;
 HSPLandroid/app/ApplicationPackageManager;->getServiceInfo(Landroid/content/ComponentName;I)Landroid/content/pm/ServiceInfo;
 HSPLandroid/app/ApplicationPackageManager;->getServiceInfo(Landroid/content/ComponentName;Landroid/content/pm/PackageManager$ComponentInfoFlags;)Landroid/content/pm/ServiceInfo;
@@ -1298,7 +1300,7 @@
 HSPLandroid/app/ApplicationPackageManager;->getText(Ljava/lang/String;ILandroid/content/pm/ApplicationInfo;)Ljava/lang/CharSequence;
 HSPLandroid/app/ApplicationPackageManager;->getUserBadgeColor(Landroid/os/UserHandle;Z)I
 HSPLandroid/app/ApplicationPackageManager;->getUserBadgedIcon(Landroid/graphics/drawable/Drawable;Landroid/os/UserHandle;)Landroid/graphics/drawable/Drawable;
-HSPLandroid/app/ApplicationPackageManager;->getUserId()I
+HSPLandroid/app/ApplicationPackageManager;->getUserId()I+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
 HSPLandroid/app/ApplicationPackageManager;->getUserManager()Landroid/os/UserManager;
 HSPLandroid/app/ApplicationPackageManager;->getXml(Ljava/lang/String;ILandroid/content/pm/ApplicationInfo;)Landroid/content/res/XmlResourceParser;
 HSPLandroid/app/ApplicationPackageManager;->handlePackageBroadcast(I[Ljava/lang/String;Z)V
@@ -1323,7 +1325,7 @@
 HSPLandroid/app/ApplicationPackageManager;->queryIntentActivities(Landroid/content/Intent;I)Ljava/util/List;
 HSPLandroid/app/ApplicationPackageManager;->queryIntentActivities(Landroid/content/Intent;Landroid/content/pm/PackageManager$ResolveInfoFlags;)Ljava/util/List;
 HSPLandroid/app/ApplicationPackageManager;->queryIntentActivitiesAsUser(Landroid/content/Intent;II)Ljava/util/List;
-HSPLandroid/app/ApplicationPackageManager;->queryIntentActivitiesAsUser(Landroid/content/Intent;Landroid/content/pm/PackageManager$ResolveInfoFlags;I)Ljava/util/List;+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/content/Intent;Landroid/content/Intent;]Landroid/content/pm/IPackageManager;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/content/pm/PackageManager$ResolveInfoFlags;Landroid/content/pm/PackageManager$ResolveInfoFlags;]Landroid/content/pm/ParceledListSlice;Landroid/content/pm/ParceledListSlice;
+HSPLandroid/app/ApplicationPackageManager;->queryIntentActivitiesAsUser(Landroid/content/Intent;Landroid/content/pm/PackageManager$ResolveInfoFlags;I)Ljava/util/List;+]Landroid/content/pm/IPackageManager;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/content/pm/PackageManager$ResolveInfoFlags;Landroid/content/pm/PackageManager$ResolveInfoFlags;]Landroid/content/pm/ParceledListSlice;Landroid/content/pm/ParceledListSlice;]Landroid/content/Intent;Landroid/content/Intent;
 HSPLandroid/app/ApplicationPackageManager;->queryIntentContentProviders(Landroid/content/Intent;I)Ljava/util/List;
 HSPLandroid/app/ApplicationPackageManager;->queryIntentContentProviders(Landroid/content/Intent;Landroid/content/pm/PackageManager$ResolveInfoFlags;)Ljava/util/List;
 HSPLandroid/app/ApplicationPackageManager;->queryIntentContentProvidersAsUser(Landroid/content/Intent;II)Ljava/util/List;
@@ -1411,7 +1413,7 @@
 HSPLandroid/app/ContextImpl$ApplicationContentResolver;->releaseUnstableProvider(Landroid/content/IContentProvider;)Z
 HSPLandroid/app/ContextImpl$ApplicationContentResolver;->resolveUserIdFromAuthority(Ljava/lang/String;)I
 HSPLandroid/app/ContextImpl$ApplicationContentResolver;->unstableProviderDied(Landroid/content/IContentProvider;)V
-HSPLandroid/app/ContextImpl;-><init>(Landroid/app/ContextImpl;Landroid/app/ActivityThread;Landroid/app/LoadedApk;Landroid/content/ContextParams;Ljava/lang/String;Landroid/content/AttributionSource;Ljava/lang/String;Landroid/os/IBinder;Landroid/os/UserHandle;ILjava/lang/ClassLoader;Ljava/lang/String;IZ)V+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/content/ContextParams;Landroid/content/ContextParams;
+HSPLandroid/app/ContextImpl;-><init>(Landroid/app/ContextImpl;Landroid/app/ActivityThread;Landroid/app/LoadedApk;Landroid/content/ContextParams;Ljava/lang/String;Landroid/content/AttributionSource;Ljava/lang/String;Landroid/os/IBinder;Landroid/os/UserHandle;ILjava/lang/ClassLoader;Ljava/lang/String;IZ)V+]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/content/ContextParams;Landroid/content/ContextParams;
 HSPLandroid/app/ContextImpl;->bindIsolatedService(Landroid/content/Intent;ILjava/lang/String;Ljava/util/concurrent/Executor;Landroid/content/ServiceConnection;)Z
 HSPLandroid/app/ContextImpl;->bindService(Landroid/content/Intent;Landroid/content/ServiceConnection;I)Z
 HSPLandroid/app/ContextImpl;->bindServiceAsUser(Landroid/content/Intent;Landroid/content/ServiceConnection;ILandroid/os/Handler;Landroid/os/UserHandle;)Z
@@ -1431,7 +1433,7 @@
 HSPLandroid/app/ContextImpl;->createAppContext(Landroid/app/ActivityThread;Landroid/app/LoadedApk;Ljava/lang/String;)Landroid/app/ContextImpl;
 HSPLandroid/app/ContextImpl;->createApplicationContext(Landroid/content/pm/ApplicationInfo;I)Landroid/content/Context;
 HSPLandroid/app/ContextImpl;->createAttributionContext(Ljava/lang/String;)Landroid/content/Context;
-HSPLandroid/app/ContextImpl;->createAttributionSource(Ljava/lang/String;Landroid/content/AttributionSource;Ljava/util/Set;ZI)Landroid/content/AttributionSource;+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/permission/PermissionManager;Landroid/permission/PermissionManager;]Ljava/util/Set;missing_types
+HSPLandroid/app/ContextImpl;->createAttributionSource(Ljava/lang/String;Landroid/content/AttributionSource;Ljava/util/Set;ZI)Landroid/content/AttributionSource;+]Ljava/util/Set;missing_types]Landroid/permission/PermissionManager;Landroid/permission/PermissionManager;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
 HSPLandroid/app/ContextImpl;->createConfigurationContext(Landroid/content/res/Configuration;)Landroid/content/Context;
 HSPLandroid/app/ContextImpl;->createContext(Landroid/content/ContextParams;)Landroid/content/Context;
 HSPLandroid/app/ContextImpl;->createContextAsUser(Landroid/os/UserHandle;I)Landroid/content/Context;
@@ -1510,11 +1512,11 @@
 HSPLandroid/app/ContextImpl;->getPreferencesDir()Ljava/io/File;
 HSPLandroid/app/ContextImpl;->getReceiverRestrictedContext()Landroid/content/Context;
 HSPLandroid/app/ContextImpl;->getResources()Landroid/content/res/Resources;
-HSPLandroid/app/ContextImpl;->getSharedPreferences(Ljava/io/File;I)Landroid/content/SharedPreferences;
-HSPLandroid/app/ContextImpl;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;
-HSPLandroid/app/ContextImpl;->getSharedPreferencesCacheLocked()Landroid/util/ArrayMap;
+HSPLandroid/app/ContextImpl;->getSharedPreferences(Ljava/io/File;I)Landroid/content/SharedPreferences;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
+HSPLandroid/app/ContextImpl;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/LoadedApk;Landroid/app/LoadedApk;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
+HSPLandroid/app/ContextImpl;->getSharedPreferencesCacheLocked()Landroid/util/ArrayMap;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
 HSPLandroid/app/ContextImpl;->getSharedPreferencesPath(Ljava/lang/String;)Ljava/io/File;
-HSPLandroid/app/ContextImpl;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
+HSPLandroid/app/ContextImpl;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;+]Ljava/lang/Object;Ljava/lang/String;]Landroid/app/ContextImpl;Landroid/app/ContextImpl;
 HSPLandroid/app/ContextImpl;->getSystemServiceName(Ljava/lang/Class;)Ljava/lang/String;
 HSPLandroid/app/ContextImpl;->getTheme()Landroid/content/res/Resources$Theme;
 HSPLandroid/app/ContextImpl;->getThemeResId()I
@@ -1733,13 +1735,13 @@
 HSPLandroid/app/FragmentManagerImpl;->addFragment(Landroid/app/Fragment;Z)V
 HSPLandroid/app/FragmentManagerImpl;->attachController(Landroid/app/FragmentHostCallback;Landroid/app/FragmentContainer;Landroid/app/Fragment;)V
 HSPLandroid/app/FragmentManagerImpl;->beginTransaction()Landroid/app/FragmentTransaction;
-HSPLandroid/app/FragmentManagerImpl;->burpActive()V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/app/FragmentManagerImpl;->burpActive()V
 HSPLandroid/app/FragmentManagerImpl;->checkStateLoss()V
 HSPLandroid/app/FragmentManagerImpl;->cleanupExec()V
 HSPLandroid/app/FragmentManagerImpl;->dispatchActivityCreated()V
 HSPLandroid/app/FragmentManagerImpl;->dispatchCreate()V
 HSPLandroid/app/FragmentManagerImpl;->dispatchCreateOptionsMenu(Landroid/view/Menu;Landroid/view/MenuInflater;)Z
-HSPLandroid/app/FragmentManagerImpl;->dispatchMoveToState(I)V+]Landroid/app/FragmentManagerImpl;Landroid/app/FragmentManagerImpl;
+HSPLandroid/app/FragmentManagerImpl;->dispatchMoveToState(I)V
 HSPLandroid/app/FragmentManagerImpl;->dispatchOnFragmentActivityCreated(Landroid/app/Fragment;Landroid/os/Bundle;Z)V
 HSPLandroid/app/FragmentManagerImpl;->dispatchOnFragmentAttached(Landroid/app/Fragment;Landroid/content/Context;Z)V
 HSPLandroid/app/FragmentManagerImpl;->dispatchOnFragmentCreated(Landroid/app/Fragment;Landroid/os/Bundle;Z)V
@@ -1762,9 +1764,9 @@
 HSPLandroid/app/FragmentManagerImpl;->doPendingDeferredStart()V
 HSPLandroid/app/FragmentManagerImpl;->endAnimatingAwayFragments()V
 HSPLandroid/app/FragmentManagerImpl;->enqueueAction(Landroid/app/FragmentManagerImpl$OpGenerator;Z)V
-HSPLandroid/app/FragmentManagerImpl;->ensureExecReady(Z)V+]Landroid/app/FragmentHostCallback;Landroid/app/Activity$HostCallbacks;]Landroid/os/Handler;Landroid/os/Handler;
+HSPLandroid/app/FragmentManagerImpl;->ensureExecReady(Z)V
 HSPLandroid/app/FragmentManagerImpl;->ensureInflatedFragmentView(Landroid/app/Fragment;)V
-HSPLandroid/app/FragmentManagerImpl;->execPendingActions()Z+]Landroid/app/FragmentManagerImpl;Landroid/app/FragmentManagerImpl;
+HSPLandroid/app/FragmentManagerImpl;->execPendingActions()Z
 HSPLandroid/app/FragmentManagerImpl;->executeOps(Ljava/util/ArrayList;Ljava/util/ArrayList;II)V
 HSPLandroid/app/FragmentManagerImpl;->executeOpsTogether(Ljava/util/ArrayList;Ljava/util/ArrayList;II)V
 HSPLandroid/app/FragmentManagerImpl;->executePendingTransactions()Z
@@ -1782,9 +1784,9 @@
 HSPLandroid/app/FragmentManagerImpl;->makeInactive(Landroid/app/Fragment;)V
 HSPLandroid/app/FragmentManagerImpl;->makeRemovedFragmentsInvisible(Landroid/util/ArraySet;)V
 HSPLandroid/app/FragmentManagerImpl;->moveFragmentToExpectedState(Landroid/app/Fragment;)V
-HSPLandroid/app/FragmentManagerImpl;->moveToState(IZ)V+]Landroid/app/FragmentManagerImpl;Landroid/app/FragmentManagerImpl;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/app/FragmentManagerImpl;->moveToState(IZ)V
 HSPLandroid/app/FragmentManagerImpl;->moveToState(Landroid/app/Fragment;IIIZ)V
-HSPLandroid/app/FragmentManagerImpl;->noteStateNotSaved()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/app/FragmentManagerImpl;->noteStateNotSaved()V
 HSPLandroid/app/FragmentManagerImpl;->onCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
 HSPLandroid/app/FragmentManagerImpl;->performPendingDeferredStart(Landroid/app/Fragment;)V
 HSPLandroid/app/FragmentManagerImpl;->popBackStackImmediate()Z
@@ -1798,7 +1800,7 @@
 HSPLandroid/app/FragmentManagerImpl;->saveNonConfig()V
 HSPLandroid/app/FragmentManagerImpl;->scheduleCommit()V
 HSPLandroid/app/FragmentManagerImpl;->setRetaining(Landroid/app/FragmentManagerNonConfig;)V
-HSPLandroid/app/FragmentManagerImpl;->startPendingDeferredFragments()V+]Landroid/app/FragmentManagerImpl;Landroid/app/FragmentManagerImpl;]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/app/FragmentManagerImpl;->startPendingDeferredFragments()V
 HSPLandroid/app/FragmentManagerState$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/FragmentManagerState;
 HSPLandroid/app/FragmentManagerState$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/app/FragmentManagerState;-><init>(Landroid/os/Parcel;)V
@@ -1841,11 +1843,12 @@
 HSPLandroid/app/IActivityManager$Stub$Proxy;->attachApplication(Landroid/app/IApplicationThread;J)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->backupAgentCreated(Ljava/lang/String;Landroid/os/IBinder;I)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->bindServiceInstance(Landroid/app/IApplicationThread;Landroid/os/IBinder;Landroid/content/Intent;Ljava/lang/String;Landroid/app/IServiceConnection;JLjava/lang/String;Ljava/lang/String;I)I
-HSPLandroid/app/IActivityManager$Stub$Proxy;->broadcastIntentWithFeature(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/content/IIntentReceiver;ILjava/lang/String;Landroid/os/Bundle;[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;ILandroid/os/Bundle;ZZI)I+]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/IActivityManager$Stub$Proxy;->broadcastIntentWithFeature(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/content/IIntentReceiver;ILjava/lang/String;Landroid/os/Bundle;[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;ILandroid/os/Bundle;ZZI)I
 HSPLandroid/app/IActivityManager$Stub$Proxy;->cancelIntentSender(Landroid/content/IIntentSender;)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->checkPermission(Ljava/lang/String;II)I
-HSPLandroid/app/IActivityManager$Stub$Proxy;->checkPermissionForDevice(Ljava/lang/String;III)I+]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/IActivityManager$Stub$Proxy;->checkPermissionForDevice(Ljava/lang/String;III)I+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/app/IActivityManager$Stub$Proxy;->checkUriPermission(Landroid/net/Uri;IIIILandroid/os/IBinder;)I
+HSPLandroid/app/IActivityManager$Stub$Proxy;->finishAttachApplication(J)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->finishReceiver(Landroid/os/IBinder;ILjava/lang/String;Landroid/os/Bundle;ZI)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->getContentProvider(Landroid/app/IApplicationThread;Ljava/lang/String;Ljava/lang/String;IZ)Landroid/app/ContentProviderHolder;
 HSPLandroid/app/IActivityManager$Stub$Proxy;->getCurrentUser()Landroid/content/pm/UserInfo;
@@ -1872,7 +1875,7 @@
 HSPLandroid/app/IActivityManager$Stub$Proxy;->registerUidObserver(Landroid/app/IUidObserver;IILjava/lang/String;)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->removeContentProvider(Landroid/os/IBinder;Z)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->revokeUriPermission(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/net/Uri;II)V
-HSPLandroid/app/IActivityManager$Stub$Proxy;->serviceDoneExecuting(Landroid/os/IBinder;IIILandroid/content/Intent;)V+]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/IActivityManager$Stub$Proxy;->serviceDoneExecuting(Landroid/os/IBinder;IIILandroid/content/Intent;)V+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/app/IActivityManager$Stub$Proxy;Landroid/app/IActivityManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/app/IActivityManager$Stub$Proxy;->setRenderThread(I)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->setServiceForeground(Landroid/content/ComponentName;Landroid/os/IBinder;ILandroid/app/Notification;II)V
 HSPLandroid/app/IActivityManager$Stub$Proxy;->startService(Landroid/app/IApplicationThread;Landroid/content/Intent;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;I)Landroid/content/ComponentName;
@@ -1931,7 +1934,7 @@
 HSPLandroid/app/INotificationManager$Stub$Proxy;->areNotificationsEnabled(Ljava/lang/String;)Z
 HSPLandroid/app/INotificationManager$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/app/INotificationManager$Stub$Proxy;->cancelAllNotifications(Ljava/lang/String;I)V
-HSPLandroid/app/INotificationManager$Stub$Proxy;->cancelNotificationWithTag(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;II)V+]Landroid/app/INotificationManager$Stub$Proxy;Landroid/app/INotificationManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/INotificationManager$Stub$Proxy;->cancelNotificationWithTag(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;II)V
 HSPLandroid/app/INotificationManager$Stub$Proxy;->createNotificationChannelGroups(Ljava/lang/String;Landroid/content/pm/ParceledListSlice;)V
 HSPLandroid/app/INotificationManager$Stub$Proxy;->createNotificationChannels(Ljava/lang/String;Landroid/content/pm/ParceledListSlice;)V
 HSPLandroid/app/INotificationManager$Stub$Proxy;->deleteNotificationChannel(Ljava/lang/String;Ljava/lang/String;)V
@@ -2035,7 +2038,7 @@
 HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args$$ExternalSyntheticLambda0;->run()V
 HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args;-><init>(Landroid/app/LoadedApk$ReceiverDispatcher;Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZZIILjava/lang/String;)V
 HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args;->getRunnable()Ljava/lang/Runnable;
-HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args;->lambda$getRunnable$0()V+]Landroid/app/LoadedApk$ReceiverDispatcher$Args;Landroid/app/LoadedApk$ReceiverDispatcher$Args;]Landroid/content/Intent;Landroid/content/Intent;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/app/LoadedApk$ReceiverDispatcher$Args;->lambda$getRunnable$0()V
 HSPLandroid/app/LoadedApk$ReceiverDispatcher$InnerReceiver;->performReceive(Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZI)V
 HSPLandroid/app/LoadedApk$ReceiverDispatcher$InnerReceiver;->performReceive(Landroid/content/Intent;ILjava/lang/String;Landroid/os/Bundle;ZZZIILjava/lang/String;)V
 HSPLandroid/app/LoadedApk$ReceiverDispatcher;-><init>(Landroid/app/IApplicationThread;Landroid/content/BroadcastReceiver;Landroid/content/Context;Landroid/os/Handler;Landroid/app/Instrumentation;Z)V
@@ -2263,7 +2266,7 @@
 HSPLandroid/app/Notification$Style;->setBuilder(Landroid/app/Notification$Builder;)V
 HSPLandroid/app/Notification$Style;->validate(Landroid/content/Context;)V
 HSPLandroid/app/Notification;-><init>()V
-HSPLandroid/app/Notification;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/app/Notification;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/app/Notification;->addFieldsFromContext(Landroid/content/Context;Landroid/app/Notification;)V
 HSPLandroid/app/Notification;->addFieldsFromContext(Landroid/content/pm/ApplicationInfo;Landroid/app/Notification;)V
 HSPLandroid/app/Notification;->areStyledNotificationsVisiblyDifferent(Landroid/app/Notification$Builder;Landroid/app/Notification$Builder;)Z
@@ -2288,7 +2291,7 @@
 HSPLandroid/app/Notification;->isGroupChild()Z
 HSPLandroid/app/Notification;->isGroupSummary()Z
 HSPLandroid/app/Notification;->isMediaNotification()Z
-HSPLandroid/app/Notification;->readFromParcelImpl(Landroid/os/Parcel;)V
+HSPLandroid/app/Notification;->readFromParcelImpl(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/graphics/drawable/Icon$1;,Landroid/app/PendingIntent$1;,Landroid/media/AudioAttributes$1;]Landroid/graphics/drawable/Icon;Landroid/graphics/drawable/Icon;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/app/Notification;->reduceImageSizes(Landroid/content/Context;)V
 HSPLandroid/app/Notification;->reduceImageSizesForRemoteView(Landroid/widget/RemoteViews;Landroid/content/Context;Z)V
 HSPLandroid/app/Notification;->removeTextSizeSpans(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
@@ -2298,10 +2301,10 @@
 HSPLandroid/app/Notification;->toString()Ljava/lang/String;
 HSPLandroid/app/Notification;->visibilityToString(I)Ljava/lang/String;
 HSPLandroid/app/Notification;->writeToParcel(Landroid/os/Parcel;I)V
-HSPLandroid/app/Notification;->writeToParcelImpl(Landroid/os/Parcel;I)V
+HSPLandroid/app/Notification;->writeToParcelImpl(Landroid/os/Parcel;I)V+]Landroid/app/PendingIntent;Landroid/app/PendingIntent;]Landroid/media/AudioAttributes;Landroid/media/AudioAttributes;]Landroid/graphics/drawable/Icon;Landroid/graphics/drawable/Icon;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/app/NotificationChannel$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/NotificationChannel;
-HSPLandroid/app/NotificationChannel$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/app/NotificationChannel;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/app/NotificationChannel$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/app/NotificationChannel$1;Landroid/app/NotificationChannel$1;
+HSPLandroid/app/NotificationChannel;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/net/Uri$1;,Landroid/media/AudioAttributes$1;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
 HSPLandroid/app/NotificationChannel;-><init>(Ljava/lang/String;Ljava/lang/CharSequence;I)V
 HSPLandroid/app/NotificationChannel;->canBubble()Z
 HSPLandroid/app/NotificationChannel;->canBypassDnd()Z
@@ -2320,7 +2323,7 @@
 HSPLandroid/app/NotificationChannel;->getName()Ljava/lang/CharSequence;
 HSPLandroid/app/NotificationChannel;->getOriginalImportance()I
 HSPLandroid/app/NotificationChannel;->getSound()Landroid/net/Uri;
-HSPLandroid/app/NotificationChannel;->getTrimmedString(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/app/NotificationChannel;->getTrimmedString(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/app/NotificationChannel;->getUserLockedFields()I
 HSPLandroid/app/NotificationChannel;->getVibrationPattern()[J
 HSPLandroid/app/NotificationChannel;->hasUserSetImportance()Z
@@ -2363,7 +2366,7 @@
 HSPLandroid/app/NotificationManager;->cancel(I)V
 HSPLandroid/app/NotificationManager;->cancel(Ljava/lang/String;I)V
 HSPLandroid/app/NotificationManager;->cancelAll()V
-HSPLandroid/app/NotificationManager;->cancelAsUser(Ljava/lang/String;ILandroid/os/UserHandle;)V+]Landroid/app/INotificationManager;Landroid/app/INotificationManager$Stub$Proxy;]Landroid/content/Context;Landroid/view/ContextThemeWrapper;]Landroid/os/UserHandle;Landroid/os/UserHandle;
+HSPLandroid/app/NotificationManager;->cancelAsUser(Ljava/lang/String;ILandroid/os/UserHandle;)V
 HSPLandroid/app/NotificationManager;->createNotificationChannel(Landroid/app/NotificationChannel;)V
 HSPLandroid/app/NotificationManager;->createNotificationChannelGroup(Landroid/app/NotificationChannelGroup;)V
 HSPLandroid/app/NotificationManager;->createNotificationChannelGroups(Ljava/util/List;)V
@@ -2386,6 +2389,7 @@
 HSPLandroid/app/NotificationManager;->notify(Ljava/lang/String;ILandroid/app/Notification;)V
 HSPLandroid/app/NotificationManager;->notifyAsUser(Ljava/lang/String;ILandroid/app/Notification;Landroid/os/UserHandle;)V
 HSPLandroid/app/NotificationManager;->zenModeToInterruptionFilter(I)I
+HSPLandroid/app/PendingIntent$$ExternalSyntheticLambda3;->get()Ljava/lang/Object;
 HSPLandroid/app/PendingIntent$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/PendingIntent;
 HSPLandroid/app/PendingIntent$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/app/PendingIntent$FinishedDispatcher;-><init>(Landroid/app/PendingIntent;Landroid/app/PendingIntent$OnFinished;Landroid/os/Handler;)V
@@ -2443,7 +2447,7 @@
 HSPLandroid/app/PictureInPictureParams$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/app/PictureInPictureParams;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/app/PropertyInvalidatedCache$1;-><init>(Landroid/app/PropertyInvalidatedCache;IFZ)V
-HSPLandroid/app/PropertyInvalidatedCache$1;->removeEldestEntry(Ljava/util/Map$Entry;)Z+]Landroid/app/PropertyInvalidatedCache$1;Landroid/app/PropertyInvalidatedCache$1;
+HSPLandroid/app/PropertyInvalidatedCache$1;->removeEldestEntry(Ljava/util/Map$Entry;)Z
 HSPLandroid/app/PropertyInvalidatedCache$DefaultComputer;-><init>(Landroid/app/PropertyInvalidatedCache;)V
 HSPLandroid/app/PropertyInvalidatedCache$NoPreloadHolder;-><clinit>()V
 HSPLandroid/app/PropertyInvalidatedCache$NoPreloadHolder;->next()J
@@ -2470,7 +2474,7 @@
 HSPLandroid/app/PropertyInvalidatedCache;->isDisabled()Z
 HSPLandroid/app/PropertyInvalidatedCache;->isReservedNonce(J)Z
 HSPLandroid/app/PropertyInvalidatedCache;->maybeCheckConsistency(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
-HSPLandroid/app/PropertyInvalidatedCache;->query(Ljava/lang/Object;)Ljava/lang/Object;+]Landroid/app/PropertyInvalidatedCache;megamorphic_types]Ljava/util/LinkedHashMap;Landroid/app/PropertyInvalidatedCache$1;
+HSPLandroid/app/PropertyInvalidatedCache;->query(Ljava/lang/Object;)Ljava/lang/Object;+]Ljava/util/LinkedHashMap;Landroid/app/PropertyInvalidatedCache$1;]Landroid/app/PropertyInvalidatedCache;megamorphic_types
 HSPLandroid/app/PropertyInvalidatedCache;->recompute(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/app/PropertyInvalidatedCache;->refresh(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/app/PropertyInvalidatedCache;->registerCache()V
@@ -2539,7 +2543,7 @@
 HSPLandroid/app/ResourcesManager;->createResourcesForActivity(Landroid/os/IBinder;Landroid/content/res/ResourcesKey;Landroid/content/res/Configuration;Ljava/lang/Integer;Ljava/lang/ClassLoader;Landroid/app/ResourcesManager$ApkAssetsSupplier;)Landroid/content/res/Resources;
 HSPLandroid/app/ResourcesManager;->createResourcesForActivityLocked(Landroid/os/IBinder;Landroid/content/res/Configuration;Ljava/lang/Integer;Ljava/lang/ClassLoader;Landroid/content/res/ResourcesImpl;Landroid/content/res/CompatibilityInfo;)Landroid/content/res/Resources;
 HSPLandroid/app/ResourcesManager;->createResourcesImpl(Landroid/content/res/ResourcesKey;Landroid/app/ResourcesManager$ApkAssetsSupplier;)Landroid/content/res/ResourcesImpl;
-HSPLandroid/app/ResourcesManager;->createResourcesLocked(Ljava/lang/ClassLoader;Landroid/content/res/ResourcesImpl;Landroid/content/res/CompatibilityInfo;)Landroid/content/res/Resources;
+HSPLandroid/app/ResourcesManager;->createResourcesLocked(Ljava/lang/ClassLoader;Landroid/content/res/ResourcesImpl;Landroid/content/res/CompatibilityInfo;)Landroid/content/res/Resources;+]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/app/ResourcesManager;->extractApkKeys(Landroid/content/res/ResourcesKey;)Ljava/util/ArrayList;+]Ljava/lang/String;Ljava/lang/String;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/app/ResourcesManager;->findKeyForResourceImplLocked(Landroid/content/res/ResourcesImpl;)Landroid/content/res/ResourcesKey;
 HSPLandroid/app/ResourcesManager;->findOrCreateResourcesImplForKeyLocked(Landroid/content/res/ResourcesKey;)Landroid/content/res/ResourcesImpl;
@@ -2561,7 +2565,7 @@
 HSPLandroid/app/ResourcesManager;->isSameResourcesOverrideConfig(Landroid/os/IBinder;Landroid/content/res/Configuration;)Z
 HSPLandroid/app/ResourcesManager;->lambda$cleanupReferences$1(Ljava/util/function/Function;Ljava/util/HashSet;Ljava/lang/Object;)Z
 HSPLandroid/app/ResourcesManager;->lambda$createResourcesForActivityLocked$0(Landroid/app/ResourcesManager$ActivityResource;)Ljava/lang/ref/WeakReference;
-HSPLandroid/app/ResourcesManager;->loadApkAssets(Landroid/app/ResourcesManager$ApkKey;)Landroid/content/res/ApkAssets;+]Landroid/content/res/ApkAssets;Landroid/content/res/ApkAssets;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/app/ResourcesManager;->loadApkAssets(Landroid/app/ResourcesManager$ApkKey;)Landroid/content/res/ApkAssets;
 HSPLandroid/app/ResourcesManager;->overlayPathToIdmapPath(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/app/ResourcesManager;->rebaseActivityOverrideConfig(Landroid/app/ResourcesManager$ActivityResource;Landroid/content/res/Configuration;I)Landroid/content/res/ResourcesKey;
 HSPLandroid/app/ResourcesManager;->rebaseKeyForActivity(Landroid/os/IBinder;Landroid/content/res/ResourcesKey;Z)V
@@ -2613,7 +2617,7 @@
 HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->apply()V
 HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->clear()Landroid/content/SharedPreferences$Editor;
 HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->commit()Z
-HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->commitToMemory()Landroid/app/SharedPreferencesImpl$MemoryCommitResult;
+HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->commitToMemory()Landroid/app/SharedPreferencesImpl$MemoryCommitResult;+]Ljava/util/Map$Entry;Ljava/util/HashMap$Node;]Ljava/lang/Object;Ljava/lang/String;,Ljava/lang/Boolean;,Ljava/lang/Long;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;]Ljava/util/Map;Ljava/util/HashMap;]Ljava/util/Iterator;Ljava/util/HashMap$EntryIterator;]Ljava/util/Set;Ljava/util/HashMap$EntrySet;
 HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->notifyListeners(Landroid/app/SharedPreferencesImpl$MemoryCommitResult;)V
 HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->putBoolean(Ljava/lang/String;Z)Landroid/content/SharedPreferences$Editor;
 HSPLandroid/app/SharedPreferencesImpl$EditorImpl;->putFloat(Ljava/lang/String;F)Landroid/content/SharedPreferences$Editor;
@@ -2658,7 +2662,7 @@
 HSPLandroid/app/SharedPreferencesImpl;->startLoadFromDisk()V
 HSPLandroid/app/SharedPreferencesImpl;->startReloadIfChangedUnexpectedly()V
 HSPLandroid/app/SharedPreferencesImpl;->unregisterOnSharedPreferenceChangeListener(Landroid/content/SharedPreferences$OnSharedPreferenceChangeListener;)V
-HSPLandroid/app/SharedPreferencesImpl;->writeToFile(Landroid/app/SharedPreferencesImpl$MemoryCommitResult;Z)V
+HSPLandroid/app/SharedPreferencesImpl;->writeToFile(Landroid/app/SharedPreferencesImpl$MemoryCommitResult;Z)V+]Ljava/io/File;Ljava/io/File;]Lcom/android/internal/util/ExponentiallyBucketedHistogram;Lcom/android/internal/util/ExponentiallyBucketedHistogram;]Landroid/app/SharedPreferencesImpl$MemoryCommitResult;Landroid/app/SharedPreferencesImpl$MemoryCommitResult;]Ljava/io/FileOutputStream;Ljava/io/FileOutputStream;
 HSPLandroid/app/StackTrace;-><init>(Ljava/lang/String;)V
 HSPLandroid/app/StatusBarManager;-><init>(Landroid/content/Context;)V
 HSPLandroid/app/SyncNotedAppOp$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/SyncNotedAppOp;
@@ -2743,9 +2747,11 @@
 HSPLandroid/app/SystemServiceRegistry$3;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$40;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$41;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$42;->createService(Landroid/app/ContextImpl;)Landroid/hardware/SensorManager;
 HSPLandroid/app/SystemServiceRegistry$42;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$43;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$44;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$45;->createService(Landroid/app/ContextImpl;)Landroid/os/storage/StorageManager;
 HSPLandroid/app/SystemServiceRegistry$45;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$46;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$47;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
@@ -2764,6 +2770,7 @@
 HSPLandroid/app/SystemServiceRegistry$57;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$58;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$59;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$60;->createService(Landroid/app/ContextImpl;)Landroid/view/WindowManager;
 HSPLandroid/app/SystemServiceRegistry$60;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$61;->createService(Landroid/app/ContextImpl;)Landroid/os/UserManager;
 HSPLandroid/app/SystemServiceRegistry$61;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
@@ -2774,6 +2781,7 @@
 HSPLandroid/app/SystemServiceRegistry$65;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$66;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$67;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$68;->createService(Landroid/app/ContextImpl;)Landroid/companion/virtual/VirtualDeviceManager;+]Landroid/app/ContextImpl;Landroid/app/ContextImpl;]Landroid/content/res/Resources;Landroid/content/res/Resources;
 HSPLandroid/app/SystemServiceRegistry$68;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$71;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$74;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
@@ -2802,7 +2810,7 @@
 HSPLandroid/app/SystemServiceRegistry$98;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$99;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$9;->createService(Landroid/app/ContextImpl;)Ljava/lang/Object;
-HSPLandroid/app/SystemServiceRegistry$CachedServiceFetcher;->getService(Landroid/app/ContextImpl;)Ljava/lang/Object;
+HSPLandroid/app/SystemServiceRegistry$CachedServiceFetcher;->getService(Landroid/app/ContextImpl;)Ljava/lang/Object;+]Landroid/app/SystemServiceRegistry$CachedServiceFetcher;megamorphic_types]Ljava/lang/Object;[Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry$StaticServiceFetcher;->getService(Landroid/app/ContextImpl;)Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry;->createServiceCache()[Ljava/lang/Object;
 HSPLandroid/app/SystemServiceRegistry;->getSystemService(Landroid/app/ContextImpl;Ljava/lang/String;)Ljava/lang/Object;+]Landroid/app/SystemServiceRegistry$ServiceFetcher;megamorphic_types
@@ -2857,6 +2865,7 @@
 HSPLandroid/app/WindowConfiguration;-><init>()V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
 HSPLandroid/app/WindowConfiguration;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/app/WindowConfiguration;->activityTypeToString(I)Ljava/lang/String;
+HSPLandroid/app/WindowConfiguration;->areConfigurationsEqualForDisplay(Landroid/content/res/Configuration;Landroid/content/res/Configuration;)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
 HSPLandroid/app/WindowConfiguration;->canReceiveKeys()Z
 HSPLandroid/app/WindowConfiguration;->compareTo(Landroid/app/WindowConfiguration;)I
 HSPLandroid/app/WindowConfiguration;->diff(Landroid/app/WindowConfiguration;Z)J+]Landroid/graphics/Rect;Landroid/graphics/Rect;
@@ -2868,17 +2877,19 @@
 HSPLandroid/app/WindowConfiguration;->getMaxBounds()Landroid/graphics/Rect;
 HSPLandroid/app/WindowConfiguration;->getRotation()I
 HSPLandroid/app/WindowConfiguration;->getWindowingMode()I
+HSPLandroid/app/WindowConfiguration;->hasWindowDecorCaption()Z
 HSPLandroid/app/WindowConfiguration;->hasWindowShadow()Z
 HSPLandroid/app/WindowConfiguration;->inMultiWindowMode(I)Z
 HSPLandroid/app/WindowConfiguration;->isFloating(I)Z
-HSPLandroid/app/WindowConfiguration;->readFromParcel(Landroid/os/Parcel;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/WindowConfiguration;->readFromParcel(Landroid/os/Parcel;)V
 HSPLandroid/app/WindowConfiguration;->setActivityType(I)V
 HSPLandroid/app/WindowConfiguration;->setAlwaysOnTop(I)V
-HSPLandroid/app/WindowConfiguration;->setAppBounds(IIII)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
-HSPLandroid/app/WindowConfiguration;->setAppBounds(Landroid/graphics/Rect;)V
-HSPLandroid/app/WindowConfiguration;->setBounds(Landroid/graphics/Rect;)V
+HSPLandroid/app/WindowConfiguration;->setAppBounds(IIII)V
+HSPLandroid/app/WindowConfiguration;->setAppBounds(Landroid/graphics/Rect;)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
+HSPLandroid/app/WindowConfiguration;->setBounds(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
 HSPLandroid/app/WindowConfiguration;->setDisplayRotation(I)V
-HSPLandroid/app/WindowConfiguration;->setMaxBounds(Landroid/graphics/Rect;)V
+HSPLandroid/app/WindowConfiguration;->setDisplayWindowingMode(I)V
+HSPLandroid/app/WindowConfiguration;->setMaxBounds(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
 HSPLandroid/app/WindowConfiguration;->setRotation(I)V
 HSPLandroid/app/WindowConfiguration;->setTo(Landroid/app/WindowConfiguration;)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
 HSPLandroid/app/WindowConfiguration;->setTo(Landroid/app/WindowConfiguration;I)V
@@ -2887,7 +2898,7 @@
 HSPLandroid/app/WindowConfiguration;->tasksAreFloating()Z
 HSPLandroid/app/WindowConfiguration;->toString()Ljava/lang/String;
 HSPLandroid/app/WindowConfiguration;->unset()V
-HSPLandroid/app/WindowConfiguration;->updateFrom(Landroid/app/WindowConfiguration;)I+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/app/WindowConfiguration;->updateFrom(Landroid/app/WindowConfiguration;)I+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
 HSPLandroid/app/WindowConfiguration;->windowingModeToString(I)Ljava/lang/String;
 HSPLandroid/app/WindowConfiguration;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/app/admin/DevicePolicyManager$$ExternalSyntheticLambda5;-><init>(Landroid/app/admin/DevicePolicyManager;)V
@@ -3153,10 +3164,10 @@
 HSPLandroid/app/job/JobInfo$TriggerContentUri$1;->newArray(I)[Ljava/lang/Object;
 HSPLandroid/app/job/JobInfo$TriggerContentUri;-><init>(Landroid/net/Uri;I)V
 HSPLandroid/app/job/JobInfo$TriggerContentUri;->writeToParcel(Landroid/os/Parcel;I)V
-HSPLandroid/app/job/JobInfo;-><init>(Landroid/app/job/JobInfo$Builder;)V
+HSPLandroid/app/job/JobInfo;-><init>(Landroid/app/job/JobInfo$Builder;)V+]Landroid/os/PersistableBundle;Landroid/os/PersistableBundle;]Landroid/os/Bundle;Landroid/os/Bundle;
 HSPLandroid/app/job/JobInfo;-><init>(Landroid/app/job/JobInfo$Builder;Landroid/app/job/JobInfo-IA;)V
-HSPLandroid/app/job/JobInfo;-><init>(Landroid/os/Parcel;)V
-HSPLandroid/app/job/JobInfo;->enforceValidity(ZZZZ)V+]Landroid/content/ComponentName;Landroid/content/ComponentName;]Landroid/net/NetworkRequest;Landroid/net/NetworkRequest;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/app/job/JobInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/net/NetworkRequest$1;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/app/job/JobInfo;->enforceValidity(ZZZZ)V+]Landroid/net/NetworkRequest;Landroid/net/NetworkRequest;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/content/ComponentName;Landroid/content/ComponentName;
 HSPLandroid/app/job/JobInfo;->getExtras()Landroid/os/PersistableBundle;
 HSPLandroid/app/job/JobInfo;->getFlags()I
 HSPLandroid/app/job/JobInfo;->getFlexMillis()J
@@ -3175,7 +3186,7 @@
 HSPLandroid/app/job/JobInfo;->isRequireCharging()Z
 HSPLandroid/app/job/JobInfo;->isRequireDeviceIdle()Z
 HSPLandroid/app/job/JobInfo;->validateTraceTag(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/app/job/JobInfo;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/app/job/JobInfo;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/net/NetworkRequest;Landroid/net/NetworkRequest;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/app/job/JobParameters$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/job/JobParameters;
 HSPLandroid/app/job/JobParameters$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/app/job/JobParameters;-><init>(Landroid/os/Parcel;)V
@@ -3263,13 +3274,14 @@
 HSPLandroid/app/servertransaction/ActivityTransactionItem;-><init>()V
 HSPLandroid/app/servertransaction/ClientTransaction$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/servertransaction/ClientTransaction;
 HSPLandroid/app/servertransaction/ClientTransaction$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/app/servertransaction/ClientTransaction;-><init>(Landroid/os/Parcel;)V+]Landroid/app/servertransaction/ClientTransactionItem;megamorphic_types]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;Landroid/app/servertransaction/ClientTransaction;]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/app/servertransaction/ClientTransaction;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/app/servertransaction/ClientTransaction;-><init>(Landroid/os/Parcel;Landroid/app/servertransaction/ClientTransaction-IA;)V
 HSPLandroid/app/servertransaction/ClientTransaction;->getCallbacks()Ljava/util/List;
 HSPLandroid/app/servertransaction/ClientTransaction;->getLifecycleStateRequest()Landroid/app/servertransaction/ActivityLifecycleItem;
-HSPLandroid/app/servertransaction/ClientTransaction;->preExecute(Landroid/app/ClientTransactionHandler;)V+]Landroid/app/servertransaction/ClientTransactionItem;megamorphic_types]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/app/servertransaction/ClientTransaction;->preExecute(Landroid/app/ClientTransactionHandler;)V
 HSPLandroid/app/servertransaction/ClientTransactionItem;-><init>()V
 HSPLandroid/app/servertransaction/ClientTransactionItem;->getPostExecutionState()I
+HSPLandroid/app/servertransaction/ClientTransactionItem;->isActivityLifecycleItem()Z
 HSPLandroid/app/servertransaction/ClientTransactionItem;->shouldHaveDefinedPreExecutionState()Z
 HSPLandroid/app/servertransaction/ConfigurationChangeItem$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/servertransaction/ConfigurationChangeItem;
 HSPLandroid/app/servertransaction/ConfigurationChangeItem$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -3330,11 +3342,13 @@
 HSPLandroid/app/servertransaction/TransactionExecutor;->execute(Landroid/app/servertransaction/ClientTransaction;)V
 HSPLandroid/app/servertransaction/TransactionExecutor;->executeCallbacks(Landroid/app/servertransaction/ClientTransaction;)V
 HSPLandroid/app/servertransaction/TransactionExecutor;->executeLifecycleState(Landroid/app/servertransaction/ClientTransaction;)V
-HSPLandroid/app/servertransaction/TransactionExecutor;->performLifecycleSequence(Landroid/app/ActivityThread$ActivityClientRecord;Landroid/util/IntArray;Landroid/app/servertransaction/ClientTransaction;)V+]Landroid/app/ClientTransactionHandler;Landroid/app/ActivityThread;]Landroid/util/IntArray;Landroid/util/IntArray;
+HSPLandroid/app/servertransaction/TransactionExecutor;->executeNonLifecycleItem(Landroid/app/servertransaction/ClientTransaction;Landroid/app/servertransaction/ClientTransactionItem;Z)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/app/servertransaction/TransactionExecutorHelper;Landroid/app/servertransaction/TransactionExecutorHelper;]Landroid/app/ClientTransactionHandler;Landroid/app/ActivityThread;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/servertransaction/ClientTransactionItem;megamorphic_types]Landroid/content/Context;missing_types]Ljava/util/Map;Ljava/util/Collections$SynchronizedMap;]Landroid/app/servertransaction/TransactionExecutor;Landroid/app/servertransaction/TransactionExecutor;
+HSPLandroid/app/servertransaction/TransactionExecutor;->executeTransactionItems(Landroid/app/servertransaction/ClientTransaction;)V+]Landroid/app/servertransaction/ClientTransaction;Landroid/app/servertransaction/ClientTransaction;]Ljava/util/List;Ljava/util/ArrayList;]Landroid/app/servertransaction/ClientTransactionItem;megamorphic_types
+HSPLandroid/app/servertransaction/TransactionExecutor;->performLifecycleSequence(Landroid/app/ActivityThread$ActivityClientRecord;Landroid/util/IntArray;Landroid/app/servertransaction/ClientTransaction;)V
 HSPLandroid/app/servertransaction/TransactionExecutorHelper;-><init>()V
 HSPLandroid/app/servertransaction/TransactionExecutorHelper;->getClosestOfStates(Landroid/app/ActivityThread$ActivityClientRecord;[I)I
 HSPLandroid/app/servertransaction/TransactionExecutorHelper;->getClosestPreExecutionState(Landroid/app/ActivityThread$ActivityClientRecord;I)I
-HSPLandroid/app/servertransaction/TransactionExecutorHelper;->getLifecyclePath(IIZ)Landroid/util/IntArray;+]Landroid/util/IntArray;Landroid/util/IntArray;
+HSPLandroid/app/servertransaction/TransactionExecutorHelper;->getLifecyclePath(IIZ)Landroid/util/IntArray;
 HSPLandroid/app/servertransaction/TransactionExecutorHelper;->lastCallbackRequestingState(Landroid/app/servertransaction/ClientTransaction;)I
 HSPLandroid/app/slice/ISliceManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 HSPLandroid/app/slice/ISliceManager$Stub$Proxy;->getPinnedSlices(Ljava/lang/String;)[Landroid/net/Uri;
@@ -3426,10 +3440,10 @@
 HSPLandroid/app/usage/UsageEvents;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/app/usage/UsageEvents;->getNextEvent(Landroid/app/usage/UsageEvents$Event;)Z
 HSPLandroid/app/usage/UsageEvents;->hasNextEvent()Z
-HSPLandroid/app/usage/UsageEvents;->readEventFromParcel(Landroid/os/Parcel;Landroid/app/usage/UsageEvents$Event;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/content/res/Configuration$1;
-HSPLandroid/app/usage/UsageStats$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/usage/UsageStats;+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
-HSPLandroid/app/usage/UsageStats$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/app/usage/UsageStats$1;Landroid/app/usage/UsageStats$1;
-HSPLandroid/app/usage/UsageStats$1;->readBundleToEventMap(Landroid/os/Bundle;Landroid/util/ArrayMap;)V+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
+HSPLandroid/app/usage/UsageEvents;->readEventFromParcel(Landroid/os/Parcel;Landroid/app/usage/UsageEvents$Event;)V
+HSPLandroid/app/usage/UsageStats$1;->createFromParcel(Landroid/os/Parcel;)Landroid/app/usage/UsageStats;+]Landroid/os/Bundle;Landroid/os/Bundle;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
+HSPLandroid/app/usage/UsageStats$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/app/usage/UsageStats$1;->readBundleToEventMap(Landroid/os/Bundle;Landroid/util/ArrayMap;)V
 HSPLandroid/app/usage/UsageStats;-><init>()V
 HSPLandroid/app/usage/UsageStats;->getPackageName()Ljava/lang/String;
 HSPLandroid/app/usage/UsageStats;->update(Ljava/lang/String;JII)V
@@ -3452,7 +3466,7 @@
 HSPLandroid/appwidget/AppWidgetProvider;->onReceive(Landroid/content/Context;Landroid/content/Intent;)V
 HSPLandroid/appwidget/AppWidgetProviderInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/appwidget/AppWidgetProviderInfo;
 HSPLandroid/appwidget/AppWidgetProviderInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/appwidget/AppWidgetProviderInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/appwidget/AppWidgetProviderInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/appwidget/AppWidgetProviderInfo;->getProfile()Landroid/os/UserHandle;
 HSPLandroid/appwidget/AppWidgetProviderInfo;->updateDimensions(Landroid/util/DisplayMetrics;)V
 HSPLandroid/appwidget/AppWidgetProviderInfo;->writeToParcel(Landroid/os/Parcel;I)V
@@ -3463,6 +3477,10 @@
 HSPLandroid/companion/virtual/IVirtualDeviceManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/companion/virtual/IVirtualDeviceManager;
 HSPLandroid/companion/virtual/VirtualDeviceManager;-><init>(Landroid/companion/virtual/IVirtualDeviceManager;Landroid/content/Context;)V
 HSPLandroid/companion/virtual/VirtualDeviceManager;->getDeviceIdForDisplayId(I)I
+HSPLandroid/companion/virtual/flags/FeatureFlagsImpl;-><init>()V
+HSPLandroid/companion/virtual/flags/FeatureFlagsImpl;->enableNativeVdm()Z
+HSPLandroid/companion/virtual/flags/Flags;-><clinit>()V
+HSPLandroid/companion/virtual/flags/Flags;->enableNativeVdm()Z+]Landroid/companion/virtual/flags/FeatureFlags;Landroid/companion/virtual/flags/FeatureFlagsImpl;
 HSPLandroid/compat/Compatibility$BehaviorChangeDelegate;->isChangeEnabled(J)Z
 HSPLandroid/compat/Compatibility;->isChangeEnabled(J)Z
 HSPLandroid/compat/Compatibility;->setBehaviorChangeDelegate(Landroid/compat/Compatibility$BehaviorChangeDelegate;)V
@@ -3492,6 +3510,7 @@
 HSPLandroid/content/AttributionSource$ScopedParcelState;->getParcel()Landroid/os/Parcel;
 HSPLandroid/content/AttributionSource;-><clinit>()V
 HSPLandroid/content/AttributionSource;-><init>(IILjava/lang/String;Ljava/lang/String;Landroid/os/IBinder;[Ljava/lang/String;ILandroid/content/AttributionSource;)V
+HSPLandroid/content/AttributionSource;-><init>(IILjava/lang/String;Ljava/lang/String;Landroid/os/IBinder;[Ljava/lang/String;Landroid/content/AttributionSource;)V
 HSPLandroid/content/AttributionSource;-><init>(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;ILandroid/content/AttributionSource;)V
 HSPLandroid/content/AttributionSource;-><init>(ILjava/lang/String;Ljava/lang/String;)V
 HSPLandroid/content/AttributionSource;-><init>(ILjava/lang/String;Ljava/lang/String;Landroid/os/IBinder;)V
@@ -3603,20 +3622,22 @@
 HSPLandroid/content/ComponentName;->getPackageName()Ljava/lang/String;
 HSPLandroid/content/ComponentName;->getShortClassName()Ljava/lang/String;
 HSPLandroid/content/ComponentName;->hashCode()I
-HSPLandroid/content/ComponentName;->readFromParcel(Landroid/os/Parcel;)Landroid/content/ComponentName;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/ComponentName;->readFromParcel(Landroid/os/Parcel;)Landroid/content/ComponentName;
 HSPLandroid/content/ComponentName;->toShortString()Ljava/lang/String;
 HSPLandroid/content/ComponentName;->toString()Ljava/lang/String;
-HSPLandroid/content/ComponentName;->unflattenFromString(Ljava/lang/String;)Landroid/content/ComponentName;
+HSPLandroid/content/ComponentName;->unflattenFromString(Ljava/lang/String;)Landroid/content/ComponentName;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/content/ComponentName;->writeToParcel(Landroid/content/ComponentName;Landroid/os/Parcel;)V
 HSPLandroid/content/ComponentName;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/ContentCaptureOptions$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/ContentCaptureOptions;
 HSPLandroid/content/ContentCaptureOptions$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda1;-><init>()V
 HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda1;->apply(I)Ljava/lang/Object;
+HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda2;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda2;->accept(Ljava/lang/Object;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->-$$Nest$smcreateFromParcel(Landroid/os/Parcel;)Landroid/content/ContentCaptureOptions$ContentProtectionOptions;
 HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;-><init>(ZILjava/util/List;Ljava/util/List;I)V
 HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->createFromParcel(Landroid/os/Parcel;)Landroid/content/ContentCaptureOptions$ContentProtectionOptions;
-HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->createGroupsFromParcel(Landroid/os/Parcel;)Ljava/util/List;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/stream/IntStream;Ljava/util/stream/IntPipeline$Head;]Ljava/util/stream/Stream;Ljava/util/stream/IntPipeline$4;,Ljava/util/stream/ReferencePipeline$11;
+HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->createGroupsFromParcel(Landroid/os/Parcel;)Ljava/util/List;+]Ljava/util/stream/Stream;Ljava/util/stream/IntPipeline$4;,Ljava/util/stream/ReferencePipeline$11;,Ljava/util/stream/ReferencePipeline$15;,Ljava/util/stream/IntPipeline$1;]Ljava/util/stream/IntStream;Ljava/util/stream/IntPipeline$Head;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->lambda$createGroupsFromParcel$0(I)Ljava/util/ArrayList;
 HSPLandroid/content/ContentCaptureOptions$ContentProtectionOptions;->writeToParcel(Landroid/os/Parcel;)V
 HSPLandroid/content/ContentCaptureOptions;-><init>(IIIIILandroid/util/ArraySet;)V
@@ -3651,6 +3672,7 @@
 HSPLandroid/content/ContentProvider;->clearCallingIdentity()Landroid/content/ContentProvider$CallingIdentity;
 HSPLandroid/content/ContentProvider;->coerceToLocalContentProvider(Landroid/content/IContentProvider;)Landroid/content/ContentProvider;
 HSPLandroid/content/ContentProvider;->delete(Landroid/net/Uri;Landroid/os/Bundle;)I
+HSPLandroid/content/ContentProvider;->deniedAccessSystemUserOnlyProvider(IZ)Z
 HSPLandroid/content/ContentProvider;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
 HSPLandroid/content/ContentProvider;->enforceReadPermissionInner(Landroid/net/Uri;Landroid/content/AttributionSource;)I
 HSPLandroid/content/ContentProvider;->enforceWritePermissionInner(Landroid/net/Uri;Landroid/content/AttributionSource;)I
@@ -3727,7 +3749,7 @@
 HSPLandroid/content/ContentProviderOperation$Builder;->withValues(Landroid/content/ContentValues;)Landroid/content/ContentProviderOperation$Builder;
 HSPLandroid/content/ContentProviderOperation;-><init>(Landroid/content/ContentProviderOperation$Builder;)V
 HSPLandroid/content/ContentProviderOperation;->apply(Landroid/content/ContentProvider;[Landroid/content/ContentProviderResult;I)Landroid/content/ContentProviderResult;
-HSPLandroid/content/ContentProviderOperation;->applyInternal(Landroid/content/ContentProvider;[Landroid/content/ContentProviderResult;I)Landroid/content/ContentProviderResult;
+HSPLandroid/content/ContentProviderOperation;->applyInternal(Landroid/content/ContentProvider;[Landroid/content/ContentProviderResult;I)Landroid/content/ContentProviderResult;+]Landroid/content/ContentProviderOperation;Landroid/content/ContentProviderOperation;
 HSPLandroid/content/ContentProviderOperation;->getUri()Landroid/net/Uri;
 HSPLandroid/content/ContentProviderOperation;->isInsert()Z
 HSPLandroid/content/ContentProviderOperation;->isReadOperation()Z
@@ -3739,7 +3761,7 @@
 HSPLandroid/content/ContentProviderOperation;->newUpdate(Landroid/net/Uri;)Landroid/content/ContentProviderOperation$Builder;
 HSPLandroid/content/ContentProviderOperation;->resolveExtrasBackReferences([Landroid/content/ContentProviderResult;I)Landroid/os/Bundle;
 HSPLandroid/content/ContentProviderOperation;->resolveSelectionArgsBackReferences([Landroid/content/ContentProviderResult;I)[Ljava/lang/String;
-HSPLandroid/content/ContentProviderOperation;->resolveValueBackReferences([Landroid/content/ContentProviderResult;I)Landroid/content/ContentValues;
+HSPLandroid/content/ContentProviderOperation;->resolveValueBackReferences([Landroid/content/ContentProviderResult;I)Landroid/content/ContentValues;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/content/ContentValues;Landroid/content/ContentValues;
 HSPLandroid/content/ContentProviderOperation;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/ContentProviderProxy;-><init>(Landroid/os/IBinder;)V
 HSPLandroid/content/ContentProviderProxy;->asBinder()Landroid/os/IBinder;
@@ -3748,7 +3770,7 @@
 HSPLandroid/content/ContentProviderProxy;->delete(Landroid/content/AttributionSource;Landroid/net/Uri;Landroid/os/Bundle;)I
 HSPLandroid/content/ContentProviderProxy;->insert(Landroid/content/AttributionSource;Landroid/net/Uri;Landroid/content/ContentValues;Landroid/os/Bundle;)Landroid/net/Uri;
 HSPLandroid/content/ContentProviderProxy;->openTypedAssetFile(Landroid/content/AttributionSource;Landroid/net/Uri;Ljava/lang/String;Landroid/os/Bundle;Landroid/os/ICancellationSignal;)Landroid/content/res/AssetFileDescriptor;
-HSPLandroid/content/ContentProviderProxy;->query(Landroid/content/AttributionSource;Landroid/net/Uri;[Ljava/lang/String;Landroid/os/Bundle;Landroid/os/ICancellationSignal;)Landroid/database/Cursor;
+HSPLandroid/content/ContentProviderProxy;->query(Landroid/content/AttributionSource;Landroid/net/Uri;[Ljava/lang/String;Landroid/os/Bundle;Landroid/os/ICancellationSignal;)Landroid/database/Cursor;+]Landroid/content/AttributionSource;Landroid/content/AttributionSource;]Landroid/os/Parcelable$Creator;Landroid/database/BulkCursorDescriptor$1;]Landroid/database/IBulkCursor;Landroid/database/BulkCursorProxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/ICancellationSignal;Landroid/os/ICancellationSignal$Stub$Proxy;]Landroid/database/BulkCursorToCursorAdaptor;Landroid/database/BulkCursorToCursorAdaptor;]Landroid/database/IContentObserver;Landroid/database/ContentObserver$Transport;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/net/Uri;Landroid/net/Uri$HierarchicalUri;,Landroid/net/Uri$StringUri;
 HSPLandroid/content/ContentProviderProxy;->update(Landroid/content/AttributionSource;Landroid/net/Uri;Landroid/content/ContentValues;Landroid/os/Bundle;)I
 HSPLandroid/content/ContentProviderResult$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/ContentProviderResult;
 HSPLandroid/content/ContentProviderResult$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -3865,7 +3887,7 @@
 HSPLandroid/content/ContentValues;->putObject(Ljava/lang/String;Ljava/lang/Object;)V
 HSPLandroid/content/ContentValues;->remove(Ljava/lang/String;)V
 HSPLandroid/content/ContentValues;->size()I
-HSPLandroid/content/ContentValues;->toString()Ljava/lang/String;+]Landroid/content/ContentValues;Landroid/content/ContentValues;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
+HSPLandroid/content/ContentValues;->toString()Ljava/lang/String;
 HSPLandroid/content/ContentValues;->valueSet()Ljava/util/Set;
 HSPLandroid/content/ContentValues;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/Context;-><init>()V
@@ -3879,11 +3901,11 @@
 HSPLandroid/content/Context;->getSystemService(Ljava/lang/Class;)Ljava/lang/Object;
 HSPLandroid/content/Context;->getText(I)Ljava/lang/CharSequence;
 HSPLandroid/content/Context;->getToken(Landroid/content/Context;)Landroid/os/IBinder;
-HSPLandroid/content/Context;->isAutofillCompatibilityEnabled()Z+]Landroid/content/Context;missing_types
-HSPLandroid/content/Context;->obtainStyledAttributes(I[I)Landroid/content/res/TypedArray;+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
-HSPLandroid/content/Context;->obtainStyledAttributes(Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
-HSPLandroid/content/Context;->obtainStyledAttributes(Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
-HSPLandroid/content/Context;->obtainStyledAttributes([I)Landroid/content/res/TypedArray;+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
+HSPLandroid/content/Context;->isAutofillCompatibilityEnabled()Z
+HSPLandroid/content/Context;->obtainStyledAttributes(I[I)Landroid/content/res/TypedArray;
+HSPLandroid/content/Context;->obtainStyledAttributes(Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;
+HSPLandroid/content/Context;->obtainStyledAttributes(Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/Context;missing_types
+HSPLandroid/content/Context;->obtainStyledAttributes([I)Landroid/content/res/TypedArray;
 HSPLandroid/content/Context;->registerComponentCallbacks(Landroid/content/ComponentCallbacks;)V
 HSPLandroid/content/Context;->unregisterComponentCallbacks(Landroid/content/ComponentCallbacks;)V
 HSPLandroid/content/ContextParams$Builder;-><init>()V
@@ -3930,25 +3952,25 @@
 HSPLandroid/content/ContextWrapper;->enforcePermission(Ljava/lang/String;IILjava/lang/String;)V
 HSPLandroid/content/ContextWrapper;->fileList()[Ljava/lang/String;
 HSPLandroid/content/ContextWrapper;->getActivityToken()Landroid/os/IBinder;
-HSPLandroid/content/ContextWrapper;->getApplicationContext()Landroid/content/Context;+]Landroid/content/Context;missing_types
+HSPLandroid/content/ContextWrapper;->getApplicationContext()Landroid/content/Context;
 HSPLandroid/content/ContextWrapper;->getApplicationInfo()Landroid/content/pm/ApplicationInfo;+]Landroid/content/Context;missing_types
 HSPLandroid/content/ContextWrapper;->getAssets()Landroid/content/res/AssetManager;
 HSPLandroid/content/ContextWrapper;->getAttributionSource()Landroid/content/AttributionSource;
 HSPLandroid/content/ContextWrapper;->getAttributionTag()Ljava/lang/String;
 HSPLandroid/content/ContextWrapper;->getAutofillClient()Landroid/view/autofill/AutofillManager$AutofillClient;
-HSPLandroid/content/ContextWrapper;->getAutofillOptions()Landroid/content/AutofillOptions;+]Landroid/content/Context;missing_types
+HSPLandroid/content/ContextWrapper;->getAutofillOptions()Landroid/content/AutofillOptions;
 HSPLandroid/content/ContextWrapper;->getBaseContext()Landroid/content/Context;
 HSPLandroid/content/ContextWrapper;->getBasePackageName()Ljava/lang/String;
 HSPLandroid/content/ContextWrapper;->getCacheDir()Ljava/io/File;
 HSPLandroid/content/ContextWrapper;->getClassLoader()Ljava/lang/ClassLoader;
 HSPLandroid/content/ContextWrapper;->getContentCaptureOptions()Landroid/content/ContentCaptureOptions;
-HSPLandroid/content/ContextWrapper;->getContentResolver()Landroid/content/ContentResolver;
+HSPLandroid/content/ContextWrapper;->getContentResolver()Landroid/content/ContentResolver;+]Landroid/content/Context;missing_types
 HSPLandroid/content/ContextWrapper;->getDataDir()Ljava/io/File;
 HSPLandroid/content/ContextWrapper;->getDatabasePath(Ljava/lang/String;)Ljava/io/File;
 HSPLandroid/content/ContextWrapper;->getDeviceId()I
 HSPLandroid/content/ContextWrapper;->getDir(Ljava/lang/String;I)Ljava/io/File;
 HSPLandroid/content/ContextWrapper;->getDisplay()Landroid/view/Display;
-HSPLandroid/content/ContextWrapper;->getDisplayId()I
+HSPLandroid/content/ContextWrapper;->getDisplayId()I+]Landroid/content/Context;missing_types
 HSPLandroid/content/ContextWrapper;->getDisplayNoVerify()Landroid/view/Display;
 HSPLandroid/content/ContextWrapper;->getExternalCacheDir()Ljava/io/File;
 HSPLandroid/content/ContextWrapper;->getExternalCacheDirs()[Ljava/io/File;
@@ -3964,21 +3986,21 @@
 HSPLandroid/content/ContextWrapper;->getNoBackupFilesDir()Ljava/io/File;
 HSPLandroid/content/ContextWrapper;->getOpPackageName()Ljava/lang/String;
 HSPLandroid/content/ContextWrapper;->getPackageCodePath()Ljava/lang/String;
-HSPLandroid/content/ContextWrapper;->getPackageManager()Landroid/content/pm/PackageManager;
+HSPLandroid/content/ContextWrapper;->getPackageManager()Landroid/content/pm/PackageManager;+]Landroid/content/Context;missing_types
 HSPLandroid/content/ContextWrapper;->getPackageName()Ljava/lang/String;
 HSPLandroid/content/ContextWrapper;->getPackageResourcePath()Ljava/lang/String;
 HSPLandroid/content/ContextWrapper;->getResources()Landroid/content/res/Resources;
-HSPLandroid/content/ContextWrapper;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;
+HSPLandroid/content/ContextWrapper;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;+]Landroid/content/Context;missing_types
 HSPLandroid/content/ContextWrapper;->getSharedPreferencesPath(Ljava/lang/String;)Ljava/io/File;
-HSPLandroid/content/ContextWrapper;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
+HSPLandroid/content/ContextWrapper;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;+]Landroid/content/Context;missing_types
 HSPLandroid/content/ContextWrapper;->getSystemServiceName(Ljava/lang/Class;)Ljava/lang/String;+]Landroid/content/Context;missing_types
-HSPLandroid/content/ContextWrapper;->getTheme()Landroid/content/res/Resources$Theme;
+HSPLandroid/content/ContextWrapper;->getTheme()Landroid/content/res/Resources$Theme;+]Landroid/content/Context;missing_types
 HSPLandroid/content/ContextWrapper;->getUser()Landroid/os/UserHandle;
 HSPLandroid/content/ContextWrapper;->getUserId()I
 HSPLandroid/content/ContextWrapper;->getWindowContextToken()Landroid/os/IBinder;
 HSPLandroid/content/ContextWrapper;->grantUriPermission(Ljava/lang/String;Landroid/net/Uri;I)V
 HSPLandroid/content/ContextWrapper;->isDeviceProtectedStorage()Z
-HSPLandroid/content/ContextWrapper;->isRestricted()Z+]Landroid/content/Context;missing_types
+HSPLandroid/content/ContextWrapper;->isRestricted()Z
 HSPLandroid/content/ContextWrapper;->isUiContext()Z
 HSPLandroid/content/ContextWrapper;->openFileInput(Ljava/lang/String;)Ljava/io/FileInputStream;
 HSPLandroid/content/ContextWrapper;->openFileOutput(Ljava/lang/String;I)Ljava/io/FileOutputStream;
@@ -4064,7 +4086,7 @@
 HSPLandroid/content/Intent;-><init>(Ljava/lang/String;)V
 HSPLandroid/content/Intent;-><init>(Ljava/lang/String;Landroid/net/Uri;)V
 HSPLandroid/content/Intent;-><init>(Ljava/lang/String;Landroid/net/Uri;Landroid/content/Context;Ljava/lang/Class;)V
-HSPLandroid/content/Intent;->addCategory(Ljava/lang/String;)Landroid/content/Intent;+]Landroid/util/ArraySet;Landroid/util/ArraySet;]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/content/Intent;->addCategory(Ljava/lang/String;)Landroid/content/Intent;+]Ljava/lang/String;Ljava/lang/String;]Landroid/util/ArraySet;Landroid/util/ArraySet;
 HSPLandroid/content/Intent;->addFlags(I)Landroid/content/Intent;
 HSPLandroid/content/Intent;->cloneFilter()Landroid/content/Intent;
 HSPLandroid/content/Intent;->filterEquals(Landroid/content/Intent;)Z
@@ -4129,8 +4151,8 @@
 HSPLandroid/content/Intent;->putExtras(Landroid/os/Bundle;)Landroid/content/Intent;
 HSPLandroid/content/Intent;->putParcelableArrayListExtra(Ljava/lang/String;Ljava/util/ArrayList;)Landroid/content/Intent;
 HSPLandroid/content/Intent;->putStringArrayListExtra(Ljava/lang/String;Ljava/util/ArrayList;)Landroid/content/Intent;
-HSPLandroid/content/Intent;->readFromParcel(Landroid/os/Parcel;)V
-HSPLandroid/content/Intent;->removeCategory(Ljava/lang/String;)V
+HSPLandroid/content/Intent;->readFromParcel(Landroid/os/Parcel;)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/os/Parcelable$Creator;Landroid/net/Uri$1;,Landroid/graphics/Rect$1;]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/content/Intent;Landroid/content/Intent;
+HSPLandroid/content/Intent;->removeCategory(Ljava/lang/String;)V+]Landroid/util/ArraySet;Landroid/util/ArraySet;
 HSPLandroid/content/Intent;->removeExtra(Ljava/lang/String;)V
 HSPLandroid/content/Intent;->replaceExtras(Landroid/os/Bundle;)Landroid/content/Intent;
 HSPLandroid/content/Intent;->resolveActivity(Landroid/content/pm/PackageManager;)Landroid/content/ComponentName;
@@ -4155,13 +4177,13 @@
 HSPLandroid/content/Intent;->setSelector(Landroid/content/Intent;)V
 HSPLandroid/content/Intent;->setSourceBounds(Landroid/graphics/Rect;)V
 HSPLandroid/content/Intent;->setType(Ljava/lang/String;)Landroid/content/Intent;
-HSPLandroid/content/Intent;->toShortString(Ljava/lang/StringBuilder;ZZZZ)V
+HSPLandroid/content/Intent;->toShortString(Ljava/lang/StringBuilder;ZZZZ)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/content/ComponentName;Landroid/content/ComponentName;
 HSPLandroid/content/Intent;->toString()Ljava/lang/String;
 HSPLandroid/content/Intent;->toString(Ljava/lang/StringBuilder;)V
 HSPLandroid/content/Intent;->toUri(I)Ljava/lang/String;
 HSPLandroid/content/Intent;->toUriFragment(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V
 HSPLandroid/content/Intent;->toUriInner(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V
-HSPLandroid/content/Intent;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/Intent;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/IntentFilter$$ExternalSyntheticLambda0;->accept(Ljava/lang/Object;Ljava/lang/Object;)V
 HSPLandroid/content/IntentFilter$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/IntentFilter;
 HSPLandroid/content/IntentFilter$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -4225,7 +4247,7 @@
 HSPLandroid/content/IntentFilter;->setPriority(I)V
 HSPLandroid/content/IntentFilter;->setVisibilityToInstantApp(I)V
 HSPLandroid/content/IntentFilter;->typesIterator()Ljava/util/Iterator;
-HSPLandroid/content/IntentFilter;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/IntentFilter;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/util/ArraySet;Landroid/util/ArraySet;]Landroid/content/IntentFilter;Landroid/content/IntentFilter;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/IntentSender;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/LocusId$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/LocusId;
 HSPLandroid/content/LocusId$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -4301,7 +4323,7 @@
 HSPLandroid/content/UriMatcher;-><init>(ILjava/lang/String;)V
 HSPLandroid/content/UriMatcher;->addURI(Ljava/lang/String;Ljava/lang/String;I)V
 HSPLandroid/content/UriMatcher;->createChild(Ljava/lang/String;)Landroid/content/UriMatcher;
-HSPLandroid/content/UriMatcher;->match(Landroid/net/Uri;)I
+HSPLandroid/content/UriMatcher;->match(Landroid/net/Uri;)I+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/Object;Ljava/lang/String;]Ljava/util/List;Landroid/net/Uri$PathSegments;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/net/Uri;Landroid/net/Uri$HierarchicalUri;
 HSPLandroid/content/om/OverlayInfo;->ensureValidState()V
 HSPLandroid/content/om/OverlayInfo;->isEnabled()Z
 HSPLandroid/content/pm/ActivityInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/ActivityInfo;
@@ -4309,7 +4331,7 @@
 HSPLandroid/content/pm/ActivityInfo$1;->newArray(I)[Landroid/content/pm/ActivityInfo;
 HSPLandroid/content/pm/ActivityInfo$1;->newArray(I)[Ljava/lang/Object;
 HSPLandroid/content/pm/ActivityInfo$WindowLayout;-><init>(Landroid/os/Parcel;)V
-HSPLandroid/content/pm/ActivityInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Ljava/util/Set;Landroid/util/ArraySet;
+HSPLandroid/content/pm/ActivityInfo;-><init>(Landroid/os/Parcel;)V+]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/Set;Landroid/util/ArraySet;
 HSPLandroid/content/pm/ActivityInfo;->activityInfoConfigNativeToJava(I)I
 HSPLandroid/content/pm/ActivityInfo;->getRealConfigChanged()I
 HSPLandroid/content/pm/ActivityInfo;->getThemeResource()I
@@ -4328,7 +4350,7 @@
 HSPLandroid/content/pm/ApplicationInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/content/pm/ApplicationInfo;-><init>()V
 HSPLandroid/content/pm/ApplicationInfo;-><init>(Landroid/content/pm/ApplicationInfo;)V
-HSPLandroid/content/pm/ApplicationInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Landroid/os/Parcel;Landroid/os/Parcel;]Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Ljava/util/Set;Ljava/util/Collections$EmptySet;
+HSPLandroid/content/pm/ApplicationInfo;-><init>(Landroid/os/Parcel;)V+]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/Set;Ljava/util/Collections$EmptySet;
 HSPLandroid/content/pm/ApplicationInfo;-><init>(Landroid/os/Parcel;Landroid/content/pm/ApplicationInfo-IA;)V
 HSPLandroid/content/pm/ApplicationInfo;->getAllApkPaths()[Ljava/lang/String;
 HSPLandroid/content/pm/ApplicationInfo;->getApplicationInfo()Landroid/content/pm/ApplicationInfo;
@@ -4365,16 +4387,16 @@
 HSPLandroid/content/pm/ApplicationInfo;->setSplitResourcePaths([Ljava/lang/String;)V
 HSPLandroid/content/pm/ApplicationInfo;->setVersionCode(J)V
 HSPLandroid/content/pm/ApplicationInfo;->toString()Ljava/lang/String;
-HSPLandroid/content/pm/ApplicationInfo;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/pm/ApplicationInfo;->writeToParcel(Landroid/os/Parcel;I)V+]Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;Lcom/android/internal/util/Parcelling$BuiltIn$ForStringSet;]Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;Lcom/android/internal/util/Parcelling$BuiltIn$ForBoolean;]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/UUID;Ljava/util/UUID;
 HSPLandroid/content/pm/Attribution$1;-><init>()V
 HSPLandroid/content/pm/Attribution;-><clinit>()V
 HSPLandroid/content/pm/BaseParceledListSlice$1;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
-HSPLandroid/content/pm/BaseParceledListSlice;-><init>(Landroid/os/Parcel;Ljava/lang/ClassLoader;)V
+HSPLandroid/content/pm/BaseParceledListSlice;-><init>(Landroid/os/Parcel;Ljava/lang/ClassLoader;)V+]Landroid/content/pm/BaseParceledListSlice;Landroid/content/pm/ParceledListSlice;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/BaseParceledListSlice;-><init>(Ljava/util/List;)V
 HSPLandroid/content/pm/BaseParceledListSlice;->getList()Ljava/util/List;
 HSPLandroid/content/pm/BaseParceledListSlice;->readCreator(Landroid/os/Parcelable$Creator;Landroid/os/Parcel;Ljava/lang/ClassLoader;)Ljava/lang/Object;
-HSPLandroid/content/pm/BaseParceledListSlice;->readVerifyAndAddElement(Landroid/os/Parcelable$Creator;Landroid/os/Parcel;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;
-HSPLandroid/content/pm/BaseParceledListSlice;->verifySameType(Ljava/lang/Class;Ljava/lang/Class;)V+]Ljava/lang/Object;Ljava/lang/Class;
+HSPLandroid/content/pm/BaseParceledListSlice;->readVerifyAndAddElement(Landroid/os/Parcelable$Creator;Landroid/os/Parcel;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;+]Ljava/lang/Object;megamorphic_types]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/content/pm/BaseParceledListSlice;->verifySameType(Ljava/lang/Class;Ljava/lang/Class;)V
 HSPLandroid/content/pm/BaseParceledListSlice;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/pm/Checksum$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/Checksum;
 HSPLandroid/content/pm/Checksum$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -4383,12 +4405,12 @@
 HSPLandroid/content/pm/Checksum;->getValue()[B
 HSPLandroid/content/pm/ComponentInfo;-><init>()V
 HSPLandroid/content/pm/ComponentInfo;-><init>(Landroid/content/pm/ComponentInfo;)V
-HSPLandroid/content/pm/ComponentInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/ComponentInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/content/pm/ApplicationInfo$1;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/ComponentInfo;->getApplicationInfo()Landroid/content/pm/ApplicationInfo;
 HSPLandroid/content/pm/ComponentInfo;->getComponentName()Landroid/content/ComponentName;
 HSPLandroid/content/pm/ComponentInfo;->getIconResource()I
 HSPLandroid/content/pm/ComponentInfo;->isEnabled()Z
-HSPLandroid/content/pm/ComponentInfo;->loadUnsafeLabel(Landroid/content/pm/PackageManager;)Ljava/lang/CharSequence;
+HSPLandroid/content/pm/ComponentInfo;->loadUnsafeLabel(Landroid/content/pm/PackageManager;)Ljava/lang/CharSequence;+]Landroid/content/pm/PackageManager;Landroid/app/ApplicationPackageManager;
 HSPLandroid/content/pm/ComponentInfo;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/pm/ConfigurationInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/ConfigurationInfo;
 HSPLandroid/content/pm/ConfigurationInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -4397,9 +4419,13 @@
 HSPLandroid/content/pm/CrossProfileApps;->getTargetUserProfiles()Ljava/util/List;
 HSPLandroid/content/pm/FallbackCategoryProvider;->getFallbackCategory(Ljava/lang/String;)I
 HSPLandroid/content/pm/FallbackCategoryProvider;->loadFallbacks()V
+HSPLandroid/content/pm/FeatureFlagsImpl;-><init>()V
+HSPLandroid/content/pm/FeatureFlagsImpl;->relativeReferenceIntentFilters()Z
 HSPLandroid/content/pm/FeatureInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/FeatureInfo;
 HSPLandroid/content/pm/FeatureInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/content/pm/FeatureInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/Flags;-><clinit>()V
+HSPLandroid/content/pm/Flags;->relativeReferenceIntentFilters()Z+]Landroid/content/pm/FeatureFlags;Landroid/content/pm/FeatureFlagsImpl;
 HSPLandroid/content/pm/ICrossProfileApps$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/content/pm/ICrossProfileApps$Stub$Proxy;->getTargetUserProfiles(Ljava/lang/String;)Ljava/util/List;
 HSPLandroid/content/pm/ICrossProfileApps$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/ICrossProfileApps;
@@ -4421,15 +4447,15 @@
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->checkPermission(Ljava/lang/String;Ljava/lang/String;I)I
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getActivityInfo(Landroid/content/ComponentName;JI)Landroid/content/pm/ActivityInfo;
-HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getApplicationEnabledSetting(Ljava/lang/String;I)I+]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getApplicationInfo(Ljava/lang/String;JI)Landroid/content/pm/ApplicationInfo;+]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getApplicationEnabledSetting(Ljava/lang/String;I)I+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getApplicationInfo(Ljava/lang/String;JI)Landroid/content/pm/ApplicationInfo;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getComponentEnabledSetting(Landroid/content/ComponentName;I)I
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getHomeActivities(Ljava/util/List;)Landroid/content/ComponentName;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getInstalledApplications(JI)Landroid/content/pm/ParceledListSlice;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getInstalledPackages(JI)Landroid/content/pm/ParceledListSlice;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getInstallerPackageName(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getNameForUid(I)Ljava/lang/String;
-HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInfo(Ljava/lang/String;JI)Landroid/content/pm/PackageInfo;+]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInfo(Ljava/lang/String;JI)Landroid/content/pm/PackageInfo;+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInstaller()Landroid/content/pm/IPackageInstaller;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackageUid(Ljava/lang/String;JI)I
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->getPackagesForUid(I)[Ljava/lang/String;
@@ -4447,7 +4473,7 @@
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->notifyDexLoad(Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;)V
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->notifyPackageUse(Ljava/lang/String;I)V
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->notifyPackagesReplacedReceived([Ljava/lang/String;)V
-HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentActivities(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;
+HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentActivities(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/content/pm/IPackageManager$Stub$Proxy;Landroid/content/pm/IPackageManager$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentContentProviders(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentReceivers(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;
 HSPLandroid/content/pm/IPackageManager$Stub$Proxy;->queryIntentServices(Landroid/content/Intent;Ljava/lang/String;JI)Landroid/content/pm/ParceledListSlice;
@@ -4499,7 +4525,7 @@
 HSPLandroid/content/pm/PackageInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/PackageInfo;
 HSPLandroid/content/pm/PackageInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/content/pm/PackageInfo;-><init>()V
-HSPLandroid/content/pm/PackageInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/content/pm/ApplicationInfo$1;,Landroid/content/pm/SigningInfo$1;
+HSPLandroid/content/pm/PackageInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/content/pm/ApplicationInfo$1;,Landroid/content/pm/SigningInfo$1;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/PackageInfo;-><init>(Landroid/os/Parcel;Landroid/content/pm/PackageInfo-IA;)V
 HSPLandroid/content/pm/PackageInfo;->composeLongVersionCode(II)J
 HSPLandroid/content/pm/PackageInfo;->getLongVersionCode()J
@@ -4523,7 +4549,7 @@
 HSPLandroid/content/pm/PackageInstaller;->registerSessionCallback(Landroid/content/pm/PackageInstaller$SessionCallback;Landroid/os/Handler;)V
 HSPLandroid/content/pm/PackageItemInfo;-><init>()V
 HSPLandroid/content/pm/PackageItemInfo;-><init>(Landroid/content/pm/PackageItemInfo;)V
-HSPLandroid/content/pm/PackageItemInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/PackageItemInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/text/TextUtils$1;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/PackageItemInfo;->forceSafeLabels()V
 HSPLandroid/content/pm/PackageItemInfo;->loadIcon(Landroid/content/pm/PackageManager;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/content/pm/PackageItemInfo;->loadLabel(Landroid/content/pm/PackageManager;)Ljava/lang/CharSequence;
@@ -4681,7 +4707,7 @@
 HSPLandroid/content/pm/ResolveInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/ResolveInfo;
 HSPLandroid/content/pm/ResolveInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/content/pm/ResolveInfo;-><init>()V
-HSPLandroid/content/pm/ResolveInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/ResolveInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/content/pm/ServiceInfo$1;,Landroid/content/pm/ActivityInfo$1;,Landroid/text/TextUtils$1;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/ResolveInfo;-><init>(Landroid/os/Parcel;Landroid/content/pm/ResolveInfo-IA;)V
 HSPLandroid/content/pm/ResolveInfo;->getComponentInfo()Landroid/content/pm/ComponentInfo;
 HSPLandroid/content/pm/ResolveInfo;->loadIcon(Landroid/content/pm/PackageManager;)Landroid/graphics/drawable/Drawable;
@@ -4694,8 +4720,8 @@
 HSPLandroid/content/pm/ServiceInfo;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/pm/ServiceInfo;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/pm/SharedLibraryInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/SharedLibraryInfo;
-HSPLandroid/content/pm/SharedLibraryInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/SharedLibraryInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;
+HSPLandroid/content/pm/SharedLibraryInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/content/pm/SharedLibraryInfo$1;Landroid/content/pm/SharedLibraryInfo$1;
+HSPLandroid/content/pm/SharedLibraryInfo;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/SharedLibraryInfo;-><init>(Landroid/os/Parcel;Landroid/content/pm/SharedLibraryInfo-IA;)V
 HSPLandroid/content/pm/SharedLibraryInfo;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;JILandroid/content/pm/VersionedPackage;Ljava/util/List;Ljava/util/List;Z)V
 HSPLandroid/content/pm/SharedLibraryInfo;->addDependency(Landroid/content/pm/SharedLibraryInfo;)V
@@ -4705,7 +4731,7 @@
 HSPLandroid/content/pm/SharedLibraryInfo;->getPath()Ljava/lang/String;
 HSPLandroid/content/pm/SharedLibraryInfo;->isNative()Z
 HSPLandroid/content/pm/SharedLibraryInfo;->isSdk()Z
-HSPLandroid/content/pm/SharedLibraryInfo;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/content/pm/SharedLibraryInfo;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/ShortcutInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/ShortcutInfo;
 HSPLandroid/content/pm/ShortcutInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/content/pm/ShortcutInfo$Builder;-><init>(Landroid/content/Context;Ljava/lang/String;)V
@@ -4718,7 +4744,7 @@
 HSPLandroid/content/pm/ShortcutInfo$Builder;->setLongLived(Z)Landroid/content/pm/ShortcutInfo$Builder;
 HSPLandroid/content/pm/ShortcutInfo$Builder;->setRank(I)Landroid/content/pm/ShortcutInfo$Builder;
 HSPLandroid/content/pm/ShortcutInfo$Builder;->setShortLabel(Ljava/lang/CharSequence;)Landroid/content/pm/ShortcutInfo$Builder;
-HSPLandroid/content/pm/ShortcutInfo;-><init>(Landroid/content/pm/ShortcutInfo$Builder;)V
+HSPLandroid/content/pm/ShortcutInfo;-><init>(Landroid/content/pm/ShortcutInfo$Builder;)V+]Landroid/content/pm/ShortcutInfo;Landroid/content/pm/ShortcutInfo;
 HSPLandroid/content/pm/ShortcutInfo;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/pm/ShortcutInfo;->addFlags(I)V
 HSPLandroid/content/pm/ShortcutInfo;->cloneCapabilityBindings(Ljava/util/Map;)Ljava/util/Map;
@@ -4769,7 +4795,7 @@
 HSPLandroid/content/pm/Signature$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/content/pm/Signature$1;->newArray(I)[Landroid/content/pm/Signature;
 HSPLandroid/content/pm/Signature$1;->newArray(I)[Ljava/lang/Object;
-HSPLandroid/content/pm/Signature;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/Signature;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/pm/Signature;-><init>(Landroid/os/Parcel;Landroid/content/pm/Signature-IA;)V
 HSPLandroid/content/pm/Signature;-><init>(Ljava/lang/String;)V
 HSPLandroid/content/pm/Signature;-><init>([B)V
@@ -4782,11 +4808,11 @@
 HSPLandroid/content/pm/Signature;->toCharsString()Ljava/lang/String;
 HSPLandroid/content/pm/SigningDetails$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/SigningDetails;
 HSPLandroid/content/pm/SigningDetails$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/SigningDetails;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;
+HSPLandroid/content/pm/SigningDetails;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/SigningDetails;->getSignatures()[Landroid/content/pm/Signature;
 HSPLandroid/content/pm/SigningInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/SigningInfo;
 HSPLandroid/content/pm/SigningInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/SigningInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Landroid/content/pm/SigningDetails$1;
+HSPLandroid/content/pm/SigningInfo;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/pm/SigningInfo;->getApkContentsSigners()[Landroid/content/pm/Signature;
 HSPLandroid/content/pm/SigningInfo;->getSigningCertificateHistory()[Landroid/content/pm/Signature;
 HSPLandroid/content/pm/SigningInfo;->hasMultipleSigners()Z
@@ -4796,7 +4822,7 @@
 HSPLandroid/content/pm/StringParceledListSlice;->getList()Ljava/util/List;
 HSPLandroid/content/pm/UserInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/UserInfo;
 HSPLandroid/content/pm/UserInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/UserInfo;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/pm/UserInfo;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/content/pm/UserInfo;->getUserHandle()Landroid/os/UserHandle;
 HSPLandroid/content/pm/UserInfo;->isAdmin()Z
 HSPLandroid/content/pm/UserInfo;->isEnabled()Z
@@ -4815,8 +4841,8 @@
 HSPLandroid/content/pm/UserPackage;->of(ILjava/lang/String;)Landroid/content/pm/UserPackage;
 HSPLandroid/content/pm/UserProperties;->isPresent(J)Z
 HSPLandroid/content/pm/VersionedPackage$1;->createFromParcel(Landroid/os/Parcel;)Landroid/content/pm/VersionedPackage;
-HSPLandroid/content/pm/VersionedPackage$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/content/pm/VersionedPackage;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/content/pm/VersionedPackage$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/content/pm/VersionedPackage$1;Landroid/content/pm/VersionedPackage$1;
+HSPLandroid/content/pm/VersionedPackage;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/content/pm/VersionedPackage;-><init>(Landroid/os/Parcel;Landroid/content/pm/VersionedPackage-IA;)V
 HSPLandroid/content/pm/VersionedPackage;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/pm/dex/ArtManager;->getCurrentProfilePath(Ljava/lang/String;ILjava/lang/String;)Ljava/lang/String;
@@ -4933,7 +4959,7 @@
 HSPLandroid/content/res/AssetManager;->getResourceValue(IILandroid/util/TypedValue;Z)Z+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
 HSPLandroid/content/res/AssetManager;->getSizeConfigurations()[Landroid/content/res/Configuration;
 HSPLandroid/content/res/AssetManager;->getSystem()Landroid/content/res/AssetManager;
-HSPLandroid/content/res/AssetManager;->getThemeValue(JILandroid/util/TypedValue;Z)Z+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
+HSPLandroid/content/res/AssetManager;->getThemeValue(JILandroid/util/TypedValue;Z)Z
 HSPLandroid/content/res/AssetManager;->incRefsLocked(J)V
 HSPLandroid/content/res/AssetManager;->isUpToDate()Z
 HSPLandroid/content/res/AssetManager;->list(Ljava/lang/String;)[Ljava/lang/String;
@@ -4972,13 +4998,13 @@
 HSPLandroid/content/res/ColorStateList;->getColorForState([II)I
 HSPLandroid/content/res/ColorStateList;->getConstantState()Landroid/content/res/ConstantState;
 HSPLandroid/content/res/ColorStateList;->getDefaultColor()I
-HSPLandroid/content/res/ColorStateList;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/util/AttributeSet;Landroid/content/res/XmlBlock$Parser;]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/content/res/ColorStateList;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
 HSPLandroid/content/res/ColorStateList;->isStateful()Z
 HSPLandroid/content/res/ColorStateList;->modulateColor(IFF)I
 HSPLandroid/content/res/ColorStateList;->obtainForTheme(Landroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;
 HSPLandroid/content/res/ColorStateList;->obtainForTheme(Landroid/content/res/Resources$Theme;)Landroid/content/res/ComplexColor;
 HSPLandroid/content/res/ColorStateList;->onColorsChanged()V
-HSPLandroid/content/res/ColorStateList;->valueOf(I)Landroid/content/res/ColorStateList;+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/content/res/ColorStateList;->valueOf(I)Landroid/content/res/ColorStateList;
 HSPLandroid/content/res/ColorStateList;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/res/CompatibilityInfo$2;->createFromParcel(Landroid/os/Parcel;)Landroid/content/res/CompatibilityInfo;
 HSPLandroid/content/res/CompatibilityInfo$2;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -5010,11 +5036,11 @@
 HSPLandroid/content/res/Configuration;-><init>(Landroid/os/Parcel;Landroid/content/res/Configuration-IA;)V
 HSPLandroid/content/res/Configuration;->compareTo(Landroid/content/res/Configuration;)I
 HSPLandroid/content/res/Configuration;->diff(Landroid/content/res/Configuration;)I
-HSPLandroid/content/res/Configuration;->diff(Landroid/content/res/Configuration;ZZ)I+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/os/LocaleList;Landroid/os/LocaleList;
+HSPLandroid/content/res/Configuration;->diff(Landroid/content/res/Configuration;ZZ)I
 HSPLandroid/content/res/Configuration;->diffPublicOnly(Landroid/content/res/Configuration;)I
 HSPLandroid/content/res/Configuration;->equals(Landroid/content/res/Configuration;)Z
 HSPLandroid/content/res/Configuration;->equals(Ljava/lang/Object;)Z
-HSPLandroid/content/res/Configuration;->fixUpLocaleList()V+]Landroid/os/LocaleList;Landroid/os/LocaleList;]Ljava/lang/Object;Ljava/util/Locale;
+HSPLandroid/content/res/Configuration;->fixUpLocaleList()V
 HSPLandroid/content/res/Configuration;->generateDelta(Landroid/content/res/Configuration;Landroid/content/res/Configuration;)Landroid/content/res/Configuration;
 HSPLandroid/content/res/Configuration;->getGrammaticalGender()I
 HSPLandroid/content/res/Configuration;->getLayoutDirection()I
@@ -5026,19 +5052,19 @@
 HSPLandroid/content/res/Configuration;->isScreenRound()Z
 HSPLandroid/content/res/Configuration;->isScreenWideColorGamut()Z
 HSPLandroid/content/res/Configuration;->needNewResources(II)Z
-HSPLandroid/content/res/Configuration;->readFromParcel(Landroid/os/Parcel;)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/content/res/Configuration;->readFromParcel(Landroid/os/Parcel;)V
 HSPLandroid/content/res/Configuration;->readFromProto(Landroid/util/proto/ProtoInputStream;J)V
 HSPLandroid/content/res/Configuration;->reduceScreenLayout(III)I
 HSPLandroid/content/res/Configuration;->resetScreenLayout(I)I
 HSPLandroid/content/res/Configuration;->setLayoutDirection(Ljava/util/Locale;)V
 HSPLandroid/content/res/Configuration;->setLocale(Ljava/util/Locale;)V
 HSPLandroid/content/res/Configuration;->setLocales(Landroid/os/LocaleList;)V
-HSPLandroid/content/res/Configuration;->setTo(Landroid/content/res/Configuration;)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;
+HSPLandroid/content/res/Configuration;->setTo(Landroid/content/res/Configuration;)V+]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
 HSPLandroid/content/res/Configuration;->setTo(Landroid/content/res/Configuration;II)V
 HSPLandroid/content/res/Configuration;->setToDefaults()V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
 HSPLandroid/content/res/Configuration;->toString()Ljava/lang/String;
 HSPLandroid/content/res/Configuration;->unset()V
-HSPLandroid/content/res/Configuration;->updateFrom(Landroid/content/res/Configuration;)I+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;
+HSPLandroid/content/res/Configuration;->updateFrom(Landroid/content/res/Configuration;)I+]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
 HSPLandroid/content/res/Configuration;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/content/res/ConfigurationBoundResourceCache;-><init>()V
 HSPLandroid/content/res/ConfigurationBoundResourceCache;->get(JLandroid/content/res/Resources$Theme;)Ljava/lang/Object;
@@ -5057,10 +5083,10 @@
 HSPLandroid/content/res/DrawableCache;->shouldInvalidateEntry(Landroid/graphics/drawable/Drawable$ConstantState;I)Z
 HSPLandroid/content/res/DrawableCache;->shouldInvalidateEntry(Ljava/lang/Object;I)Z
 HSPLandroid/content/res/FeatureFlagsImpl;->defaultLocale()Z
-HSPLandroid/content/res/Flags;->defaultLocale()Z
+HSPLandroid/content/res/Flags;->defaultLocale()Z+]Landroid/content/res/FeatureFlags;Landroid/content/res/FeatureFlagsImpl;
 HSPLandroid/content/res/FontResourcesParser;->parse(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;
-HSPLandroid/content/res/FontResourcesParser;->readFamilies(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;+]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
-HSPLandroid/content/res/FontResourcesParser;->readFamily(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Ljava/util/List;Ljava/util/ArrayList;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/content/res/FontResourcesParser;->readFamilies(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;
+HSPLandroid/content/res/FontResourcesParser;->readFamily(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/Resources;)Landroid/content/res/FontResourcesParser$FamilyResourceEntry;
 HSPLandroid/content/res/FontScaleConverterFactory;->forScale(F)Landroid/content/res/FontScaleConverter;
 HSPLandroid/content/res/FontScaleConverterFactory;->isNonLinearFontScalingActive(F)Z
 HSPLandroid/content/res/GradientColor;-><init>()V
@@ -5079,28 +5105,28 @@
 HSPLandroid/content/res/Resources$Theme;-><init>(Landroid/content/res/Resources;)V
 HSPLandroid/content/res/Resources$Theme;-><init>(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme-IA;)V
 HSPLandroid/content/res/Resources$Theme;->applyStyle(IZ)V
-HSPLandroid/content/res/Resources$Theme;->equals(Ljava/lang/Object;)Z+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;]Ljava/lang/Object;Landroid/content/res/Resources$Theme;
+HSPLandroid/content/res/Resources$Theme;->equals(Ljava/lang/Object;)Z
 HSPLandroid/content/res/Resources$Theme;->getAppliedStyleResId()I
 HSPLandroid/content/res/Resources$Theme;->getChangingConfigurations()I
-HSPLandroid/content/res/Resources$Theme;->getKey()Landroid/content/res/Resources$ThemeKey;+]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
+HSPLandroid/content/res/Resources$Theme;->getKey()Landroid/content/res/Resources$ThemeKey;
 HSPLandroid/content/res/Resources$Theme;->getParentThemeIdentifier(I)I
 HSPLandroid/content/res/Resources$Theme;->getResources()Landroid/content/res/Resources;
 HSPLandroid/content/res/Resources$Theme;->getTheme()[Ljava/lang/String;
 HSPLandroid/content/res/Resources$Theme;->hashCode()I
-HSPLandroid/content/res/Resources$Theme;->obtainStyledAttributes(I[I)Landroid/content/res/TypedArray;+]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
+HSPLandroid/content/res/Resources$Theme;->obtainStyledAttributes(I[I)Landroid/content/res/TypedArray;
 HSPLandroid/content/res/Resources$Theme;->obtainStyledAttributes(Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
 HSPLandroid/content/res/Resources$Theme;->obtainStyledAttributes([I)Landroid/content/res/TypedArray;
 HSPLandroid/content/res/Resources$Theme;->rebase()V
 HSPLandroid/content/res/Resources$Theme;->rebase(Landroid/content/res/ResourcesImpl;)V
-HSPLandroid/content/res/Resources$Theme;->resolveAttribute(ILandroid/util/TypedValue;Z)Z+]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
+HSPLandroid/content/res/Resources$Theme;->resolveAttribute(ILandroid/util/TypedValue;Z)Z
 HSPLandroid/content/res/Resources$Theme;->resolveAttributes([I[I)Landroid/content/res/TypedArray;
 HSPLandroid/content/res/Resources$Theme;->setImpl(Landroid/content/res/ResourcesImpl$ThemeImpl;)V
 HSPLandroid/content/res/Resources$Theme;->setTo(Landroid/content/res/Resources$Theme;)V
-HSPLandroid/content/res/Resources$Theme;->toString()Ljava/lang/String;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/content/res/Resources$Theme;->toString()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources;Landroid/content/res/Resources;
 HSPLandroid/content/res/Resources$ThemeKey;-><init>()V
 HSPLandroid/content/res/Resources$ThemeKey;->append(IZ)V
 HSPLandroid/content/res/Resources$ThemeKey;->clone()Landroid/content/res/Resources$ThemeKey;
-HSPLandroid/content/res/Resources$ThemeKey;->equals(Ljava/lang/Object;)Z+]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;]Ljava/lang/Object;Landroid/content/res/Resources$ThemeKey;
+HSPLandroid/content/res/Resources$ThemeKey;->equals(Ljava/lang/Object;)Z+]Ljava/lang/Object;Landroid/content/res/Resources$ThemeKey;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;
 HSPLandroid/content/res/Resources$ThemeKey;->hashCode()I
 HSPLandroid/content/res/Resources$ThemeKey;->moveToLast(I)V
 HSPLandroid/content/res/Resources$ThemeKey;->setTo(Landroid/content/res/Resources$ThemeKey;)V+][I[I][Z[Z
@@ -5119,12 +5145,12 @@
 HSPLandroid/content/res/Resources;->getBoolean(I)Z
 HSPLandroid/content/res/Resources;->getClassLoader()Ljava/lang/ClassLoader;
 HSPLandroid/content/res/Resources;->getColor(I)I
-HSPLandroid/content/res/Resources;->getColor(ILandroid/content/res/Resources$Theme;)I+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getColor(ILandroid/content/res/Resources$Theme;)I
 HSPLandroid/content/res/Resources;->getColorStateList(I)Landroid/content/res/ColorStateList;
 HSPLandroid/content/res/Resources;->getColorStateList(ILandroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;
 HSPLandroid/content/res/Resources;->getCompatibilityInfo()Landroid/content/res/CompatibilityInfo;
 HSPLandroid/content/res/Resources;->getConfiguration()Landroid/content/res/Configuration;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
-HSPLandroid/content/res/Resources;->getDimension(I)F+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getDimension(I)F
 HSPLandroid/content/res/Resources;->getDimensionPixelOffset(I)I
 HSPLandroid/content/res/Resources;->getDimensionPixelSize(I)I
 HSPLandroid/content/res/Resources;->getDisplayAdjustments()Landroid/view/DisplayAdjustments;
@@ -5132,7 +5158,7 @@
 HSPLandroid/content/res/Resources;->getDrawable(I)Landroid/graphics/drawable/Drawable;
 HSPLandroid/content/res/Resources;->getDrawable(ILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/content/res/Resources;->getDrawableForDensity(II)Landroid/graphics/drawable/Drawable;
-HSPLandroid/content/res/Resources;->getDrawableForDensity(IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getDrawableForDensity(IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/content/res/Resources;->getDrawableInflater()Landroid/graphics/drawable/DrawableInflater;
 HSPLandroid/content/res/Resources;->getFloat(I)F
 HSPLandroid/content/res/Resources;->getFont(Landroid/util/TypedValue;I)Landroid/graphics/Typeface;
@@ -5146,7 +5172,7 @@
 HSPLandroid/content/res/Resources;->getQuantityString(II)Ljava/lang/String;
 HSPLandroid/content/res/Resources;->getQuantityString(II[Ljava/lang/Object;)Ljava/lang/String;
 HSPLandroid/content/res/Resources;->getQuantityText(II)Ljava/lang/CharSequence;
-HSPLandroid/content/res/Resources;->getResourceEntryName(I)Ljava/lang/String;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getResourceEntryName(I)Ljava/lang/String;
 HSPLandroid/content/res/Resources;->getResourceName(I)Ljava/lang/String;
 HSPLandroid/content/res/Resources;->getResourcePackageName(I)Ljava/lang/String;
 HSPLandroid/content/res/Resources;->getResourceTypeName(I)Ljava/lang/String;
@@ -5154,24 +5180,24 @@
 HSPLandroid/content/res/Resources;->getStateListAnimatorCache()Landroid/content/res/ConfigurationBoundResourceCache;
 HSPLandroid/content/res/Resources;->getString(I)Ljava/lang/String;
 HSPLandroid/content/res/Resources;->getString(I[Ljava/lang/Object;)Ljava/lang/String;
-HSPLandroid/content/res/Resources;->getStringArray(I)[Ljava/lang/String;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getStringArray(I)[Ljava/lang/String;
 HSPLandroid/content/res/Resources;->getSystem()Landroid/content/res/Resources;
 HSPLandroid/content/res/Resources;->getText(I)Ljava/lang/CharSequence;
 HSPLandroid/content/res/Resources;->getTextArray(I)[Ljava/lang/CharSequence;
-HSPLandroid/content/res/Resources;->getValue(ILandroid/util/TypedValue;Z)V+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->getValue(ILandroid/util/TypedValue;Z)V
 HSPLandroid/content/res/Resources;->getValueForDensity(IILandroid/util/TypedValue;Z)V
 HSPLandroid/content/res/Resources;->getXml(I)Landroid/content/res/XmlResourceParser;
 HSPLandroid/content/res/Resources;->hasOverrideDisplayAdjustments()Z
-HSPLandroid/content/res/Resources;->loadColorStateList(Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->loadColorStateList(Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;
 HSPLandroid/content/res/Resources;->loadComplexColor(Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ComplexColor;
 HSPLandroid/content/res/Resources;->loadDrawable(Landroid/util/TypedValue;IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
-HSPLandroid/content/res/Resources;->loadXmlResourceParser(ILjava/lang/String;)Landroid/content/res/XmlResourceParser;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Ljava/lang/CharSequence;Ljava/lang/String;
-HSPLandroid/content/res/Resources;->loadXmlResourceParser(Ljava/lang/String;IILjava/lang/String;)Landroid/content/res/XmlResourceParser;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
-HSPLandroid/content/res/Resources;->newTheme()Landroid/content/res/Resources$Theme;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/content/res/Resources;->loadXmlResourceParser(ILjava/lang/String;)Landroid/content/res/XmlResourceParser;
+HSPLandroid/content/res/Resources;->loadXmlResourceParser(Ljava/lang/String;IILjava/lang/String;)Landroid/content/res/XmlResourceParser;
+HSPLandroid/content/res/Resources;->newTheme()Landroid/content/res/Resources$Theme;
 HSPLandroid/content/res/Resources;->obtainAttributes(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;
-HSPLandroid/content/res/Resources;->obtainAttributes(Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->obtainAttributes(Landroid/util/AttributeSet;[I)Landroid/content/res/TypedArray;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
 HSPLandroid/content/res/Resources;->obtainTempTypedValue()Landroid/util/TypedValue;
-HSPLandroid/content/res/Resources;->obtainTypedArray(I)Landroid/content/res/TypedArray;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
+HSPLandroid/content/res/Resources;->obtainTypedArray(I)Landroid/content/res/TypedArray;
 HSPLandroid/content/res/Resources;->openRawResource(I)Ljava/io/InputStream;
 HSPLandroid/content/res/Resources;->openRawResource(ILandroid/util/TypedValue;)Ljava/io/InputStream;
 HSPLandroid/content/res/Resources;->openRawResourceFd(I)Landroid/content/res/AssetFileDescriptor;
@@ -5201,26 +5227,26 @@
 HSPLandroid/content/res/ResourcesImpl$LookupStack;->contains(I)Z
 HSPLandroid/content/res/ResourcesImpl$LookupStack;->pop()V
 HSPLandroid/content/res/ResourcesImpl$LookupStack;->push(I)V
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;-><init>(Landroid/content/res/ResourcesImpl;)V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->applyStyle(IZ)V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;-><init>(Landroid/content/res/ResourcesImpl;)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->applyStyle(IZ)V
 HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->finalize()V
 HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getAppliedStyleResId()I
 HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getChangingConfigurations()I
 HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getKey()Landroid/content/res/Resources$ThemeKey;
 HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getParentThemeIdentifier(I)I
 HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->getTheme()[Ljava/lang/String;
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->obtainStyledAttributes(Landroid/content/res/Resources$Theme;Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->obtainStyledAttributes(Landroid/content/res/Resources$Theme;Landroid/util/AttributeSet;[III)Landroid/content/res/TypedArray;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
 HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->rebase()V
 HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->rebase(Landroid/content/res/AssetManager;)V
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->resolveAttribute(ILandroid/util/TypedValue;Z)Z+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->resolveAttribute(ILandroid/util/TypedValue;Z)Z
 HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->resolveAttributes(Landroid/content/res/Resources$Theme;[I[I)Landroid/content/res/TypedArray;
-HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->setTo(Landroid/content/res/ResourcesImpl$ThemeImpl;)V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;]Landroid/content/res/ResourcesImpl$ThemeImpl;Landroid/content/res/ResourcesImpl$ThemeImpl;
+HSPLandroid/content/res/ResourcesImpl$ThemeImpl;->setTo(Landroid/content/res/ResourcesImpl$ThemeImpl;)V
 HSPLandroid/content/res/ResourcesImpl;->-$$Nest$sfgetsThemeRegistry()Llibcore/util/NativeAllocationRegistry;
-HSPLandroid/content/res/ResourcesImpl;-><init>(Landroid/content/res/AssetManager;Landroid/util/DisplayMetrics;Landroid/content/res/Configuration;Landroid/view/DisplayAdjustments;)V+]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;
+HSPLandroid/content/res/ResourcesImpl;-><init>(Landroid/content/res/AssetManager;Landroid/util/DisplayMetrics;Landroid/content/res/Configuration;Landroid/view/DisplayAdjustments;)V+]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;
 HSPLandroid/content/res/ResourcesImpl;->adjustLanguageTag(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/content/res/ResourcesImpl;->attrForQuantityCode(Ljava/lang/String;)I
-HSPLandroid/content/res/ResourcesImpl;->cacheDrawable(Landroid/util/TypedValue;ZLandroid/content/res/DrawableCache;Landroid/content/res/Resources$Theme;ZJLandroid/graphics/drawable/Drawable;I)V
-HSPLandroid/content/res/ResourcesImpl;->calcConfigChanges(Landroid/content/res/Configuration;)I+]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;
+HSPLandroid/content/res/ResourcesImpl;->cacheDrawable(Landroid/util/TypedValue;ZLandroid/content/res/DrawableCache;Landroid/content/res/Resources$Theme;ZJLandroid/graphics/drawable/Drawable;I)V+]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/graphics/drawable/Drawable;megamorphic_types
+HSPLandroid/content/res/ResourcesImpl;->calcConfigChanges(Landroid/content/res/Configuration;)I
 HSPLandroid/content/res/ResourcesImpl;->decodeImageDrawable(Landroid/content/res/AssetManager$AssetInputStream;Landroid/content/res/Resources;Landroid/util/TypedValue;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/content/res/ResourcesImpl;->dump(Ljava/io/PrintWriter;Ljava/lang/String;)V
 HSPLandroid/content/res/ResourcesImpl;->finishPreloading()V
@@ -5228,7 +5254,7 @@
 HSPLandroid/content/res/ResourcesImpl;->getAnimatorCache()Landroid/content/res/ConfigurationBoundResourceCache;
 HSPLandroid/content/res/ResourcesImpl;->getAssets()Landroid/content/res/AssetManager;
 HSPLandroid/content/res/ResourcesImpl;->getAttributeSetSourceResId(Landroid/util/AttributeSet;)I
-HSPLandroid/content/res/ResourcesImpl;->getColorStateListFromInt(Landroid/util/TypedValue;J)Landroid/content/res/ColorStateList;+]Landroid/content/res/ConstantState;Landroid/content/res/ColorStateList$ColorStateListFactory;]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;
+HSPLandroid/content/res/ResourcesImpl;->getColorStateListFromInt(Landroid/util/TypedValue;J)Landroid/content/res/ColorStateList;
 HSPLandroid/content/res/ResourcesImpl;->getCompatibilityInfo()Landroid/content/res/CompatibilityInfo;
 HSPLandroid/content/res/ResourcesImpl;->getConfiguration()Landroid/content/res/Configuration;
 HSPLandroid/content/res/ResourcesImpl;->getDisplayAdjustments()Landroid/view/DisplayAdjustments;
@@ -5242,7 +5268,7 @@
 HSPLandroid/content/res/ResourcesImpl;->getResourceTypeName(I)Ljava/lang/String;
 HSPLandroid/content/res/ResourcesImpl;->getSizeConfigurations()[Landroid/content/res/Configuration;
 HSPLandroid/content/res/ResourcesImpl;->getStateListAnimatorCache()Landroid/content/res/ConfigurationBoundResourceCache;
-HSPLandroid/content/res/ResourcesImpl;->getValue(ILandroid/util/TypedValue;Z)V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
+HSPLandroid/content/res/ResourcesImpl;->getValue(ILandroid/util/TypedValue;Z)V
 HSPLandroid/content/res/ResourcesImpl;->getValueForDensity(IILandroid/util/TypedValue;Z)V
 HSPLandroid/content/res/ResourcesImpl;->isIntLike(Ljava/lang/String;)Z
 HSPLandroid/content/res/ResourcesImpl;->lambda$decodeImageDrawable$1(Landroid/graphics/ImageDecoder;Landroid/graphics/ImageDecoder$ImageInfo;Landroid/graphics/ImageDecoder$Source;)V
@@ -5250,18 +5276,18 @@
 HSPLandroid/content/res/ResourcesImpl;->loadColorStateList(Landroid/content/res/Resources;Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ColorStateList;
 HSPLandroid/content/res/ResourcesImpl;->loadComplexColor(Landroid/content/res/Resources;Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ComplexColor;
 HSPLandroid/content/res/ResourcesImpl;->loadComplexColorForCookie(Landroid/content/res/Resources;Landroid/util/TypedValue;ILandroid/content/res/Resources$Theme;)Landroid/content/res/ComplexColor;
-HSPLandroid/content/res/ResourcesImpl;->loadComplexColorFromName(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Landroid/util/TypedValue;I)Landroid/content/res/ComplexColor;+]Landroid/content/res/ComplexColor;Landroid/content/res/ColorStateList;,Landroid/content/res/GradientColor;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;]Landroid/content/res/ConstantState;Landroid/content/res/ColorStateList$ColorStateListFactory;]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;
-HSPLandroid/content/res/ResourcesImpl;->loadDrawable(Landroid/content/res/Resources;Landroid/util/TypedValue;IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/graphics/drawable/Drawable$ConstantState;megamorphic_types]Landroid/graphics/drawable/Drawable;megamorphic_types]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;
-HSPLandroid/content/res/ResourcesImpl;->loadDrawableForCookie(Landroid/content/res/Resources;Landroid/util/TypedValue;II)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/ResourcesImpl$LookupStack;Landroid/content/res/ResourcesImpl$LookupStack;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Ljava/lang/CharSequence;Ljava/lang/String;]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;
-HSPLandroid/content/res/ResourcesImpl;->loadFont(Landroid/content/res/Resources;Landroid/util/TypedValue;I)Landroid/graphics/Typeface;+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Ljava/lang/CharSequence;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/content/res/ResourcesImpl;->loadComplexColorFromName(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Landroid/util/TypedValue;I)Landroid/content/res/ComplexColor;+]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;
+HSPLandroid/content/res/ResourcesImpl;->loadDrawable(Landroid/content/res/Resources;Landroid/util/TypedValue;IILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;+]Landroid/graphics/drawable/Drawable$ConstantState;megamorphic_types]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/graphics/drawable/Drawable;megamorphic_types
+HSPLandroid/content/res/ResourcesImpl;->loadDrawableForCookie(Landroid/content/res/Resources;Landroid/util/TypedValue;II)Landroid/graphics/drawable/Drawable;
+HSPLandroid/content/res/ResourcesImpl;->loadFont(Landroid/content/res/Resources;Landroid/util/TypedValue;I)Landroid/graphics/Typeface;
 HSPLandroid/content/res/ResourcesImpl;->loadXmlDrawable(Landroid/content/res/Resources;Landroid/util/TypedValue;IILjava/lang/String;)Landroid/graphics/drawable/Drawable;
-HSPLandroid/content/res/ResourcesImpl;->loadXmlResourceParser(Ljava/lang/String;IILjava/lang/String;)Landroid/content/res/XmlResourceParser;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/XmlBlock;Landroid/content/res/XmlBlock;]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/content/res/ResourcesImpl;->loadXmlResourceParser(Ljava/lang/String;IILjava/lang/String;)Landroid/content/res/XmlResourceParser;+]Ljava/lang/Object;Ljava/lang/String;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/XmlBlock;Landroid/content/res/XmlBlock;
 HSPLandroid/content/res/ResourcesImpl;->newThemeImpl()Landroid/content/res/ResourcesImpl$ThemeImpl;
 HSPLandroid/content/res/ResourcesImpl;->openRawResource(ILandroid/util/TypedValue;)Ljava/io/InputStream;
 HSPLandroid/content/res/ResourcesImpl;->openRawResourceFd(ILandroid/util/TypedValue;)Landroid/content/res/AssetFileDescriptor;
 HSPLandroid/content/res/ResourcesImpl;->startPreloading()V
-HSPLandroid/content/res/ResourcesImpl;->updateConfiguration(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;)V+]Landroid/app/ResourcesManager;Landroid/app/ResourcesManager;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Ljava/util/Locale;Ljava/util/Locale;
-HSPLandroid/content/res/ResourcesImpl;->updateConfigurationImpl(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Z)V+]Landroid/app/ResourcesManager;Landroid/app/ResourcesManager;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Ljava/lang/Object;Ljava/util/Locale;]Ljava/util/Locale;Ljava/util/Locale;
+HSPLandroid/content/res/ResourcesImpl;->updateConfiguration(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;)V+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/app/ResourcesManager;Landroid/app/ResourcesManager;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Ljava/util/Locale;Ljava/util/Locale;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;
+HSPLandroid/content/res/ResourcesImpl;->updateConfigurationImpl(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Z)V+]Landroid/content/res/ResourcesImpl;Landroid/content/res/ResourcesImpl;]Landroid/app/ResourcesManager;Landroid/app/ResourcesManager;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Ljava/util/Locale;Ljava/util/Locale;]Landroid/content/res/DrawableCache;Landroid/content/res/DrawableCache;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/os/LocaleList;Landroid/os/LocaleList;]Landroid/util/DisplayMetrics;Landroid/util/DisplayMetrics;]Landroid/content/res/ConfigurationBoundResourceCache;Landroid/content/res/ConfigurationBoundResourceCache;]Ljava/lang/Object;Ljava/util/Locale;
 HSPLandroid/content/res/ResourcesImpl;->verifyPreloadConfig(IIILjava/lang/String;)Z
 HSPLandroid/content/res/ResourcesKey;-><init>(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;ILandroid/content/res/Configuration;Landroid/content/res/CompatibilityInfo;[Landroid/content/res/loader/ResourcesLoader;)V
 HSPLandroid/content/res/ResourcesKey;->equals(Ljava/lang/Object;)Z
@@ -5274,9 +5300,9 @@
 HSPLandroid/content/res/StringBlock;->get(I)Ljava/lang/CharSequence;
 HSPLandroid/content/res/StringBlock;->getSequence(I)Ljava/lang/CharSequence;+]Landroid/util/SparseArray;Landroid/util/SparseArray;
 HSPLandroid/content/res/ThemedResourceCache;-><init>()V
-HSPLandroid/content/res/ThemedResourceCache;->get(JLandroid/content/res/Resources$Theme;)Ljava/lang/Object;+]Landroid/util/LongSparseArray;Landroid/util/LongSparseArray;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/content/res/ThemedResourceCache;->get(JLandroid/content/res/Resources$Theme;)Ljava/lang/Object;
 HSPLandroid/content/res/ThemedResourceCache;->getGeneration()I
-HSPLandroid/content/res/ThemedResourceCache;->getThemedLocked(Landroid/content/res/Resources$Theme;Z)Landroid/util/LongSparseArray;+]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources$ThemeKey;Landroid/content/res/Resources$ThemeKey;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/content/res/ThemedResourceCache;->getThemedLocked(Landroid/content/res/Resources$Theme;Z)Landroid/util/LongSparseArray;
 HSPLandroid/content/res/ThemedResourceCache;->getUnthemedLocked(Z)Landroid/util/LongSparseArray;
 HSPLandroid/content/res/ThemedResourceCache;->onConfigurationChange(I)V
 HSPLandroid/content/res/ThemedResourceCache;->pruneEntriesLocked(Landroid/util/LongSparseArray;I)Z
@@ -5288,24 +5314,24 @@
 HSPLandroid/content/res/TypedArray;->extractThemeAttrs([I)[I
 HSPLandroid/content/res/TypedArray;->getBoolean(IZ)Z
 HSPLandroid/content/res/TypedArray;->getChangingConfigurations()I+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
-HSPLandroid/content/res/TypedArray;->getColor(II)I+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/content/res/TypedArray;->getColor(II)I
 HSPLandroid/content/res/TypedArray;->getColorStateList(I)Landroid/content/res/ColorStateList;+]Landroid/content/res/Resources;Landroid/content/res/Resources;
 HSPLandroid/content/res/TypedArray;->getComplexColor(I)Landroid/content/res/ComplexColor;
 HSPLandroid/content/res/TypedArray;->getDimension(IF)F
 HSPLandroid/content/res/TypedArray;->getDimensionPixelOffset(II)I
 HSPLandroid/content/res/TypedArray;->getDimensionPixelSize(II)I
-HSPLandroid/content/res/TypedArray;->getDrawable(I)Landroid/graphics/drawable/Drawable;
+HSPLandroid/content/res/TypedArray;->getDrawable(I)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
 HSPLandroid/content/res/TypedArray;->getDrawableForDensity(II)Landroid/graphics/drawable/Drawable;+]Landroid/content/res/Resources;Landroid/content/res/Resources;
 HSPLandroid/content/res/TypedArray;->getFloat(IF)F
-HSPLandroid/content/res/TypedArray;->getFont(I)Landroid/graphics/Typeface;+]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/content/res/TypedArray;->getFont(I)Landroid/graphics/Typeface;
 HSPLandroid/content/res/TypedArray;->getFraction(IIIF)F
 HSPLandroid/content/res/TypedArray;->getIndex(I)I
 HSPLandroid/content/res/TypedArray;->getIndexCount()I
 HSPLandroid/content/res/TypedArray;->getInt(II)I
 HSPLandroid/content/res/TypedArray;->getInteger(II)I
 HSPLandroid/content/res/TypedArray;->getLayoutDimension(II)I
-HSPLandroid/content/res/TypedArray;->getLayoutDimension(ILjava/lang/String;)I+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/content/res/TypedArray;->getNonConfigurationString(II)Ljava/lang/String;
+HSPLandroid/content/res/TypedArray;->getLayoutDimension(ILjava/lang/String;)I
+HSPLandroid/content/res/TypedArray;->getNonConfigurationString(II)Ljava/lang/String;+]Ljava/lang/CharSequence;Ljava/lang/String;
 HSPLandroid/content/res/TypedArray;->getNonResourceString(I)Ljava/lang/String;
 HSPLandroid/content/res/TypedArray;->getPositionDescription()Ljava/lang/String;
 HSPLandroid/content/res/TypedArray;->getResourceId(II)I
@@ -5319,7 +5345,7 @@
 HSPLandroid/content/res/TypedArray;->hasValue(I)Z
 HSPLandroid/content/res/TypedArray;->hasValueOrEmpty(I)Z
 HSPLandroid/content/res/TypedArray;->length()I
-HSPLandroid/content/res/TypedArray;->loadStringValueAt(I)Ljava/lang/CharSequence;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/content/res/TypedArray;->loadStringValueAt(I)Ljava/lang/CharSequence;+]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/Validator;Landroid/content/res/Validator;
 HSPLandroid/content/res/TypedArray;->obtain(Landroid/content/res/Resources;I)Landroid/content/res/TypedArray;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
 HSPLandroid/content/res/TypedArray;->peekValue(I)Landroid/util/TypedValue;
 HSPLandroid/content/res/TypedArray;->recycle()V+]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
@@ -5336,7 +5362,7 @@
 HSPLandroid/content/res/XmlBlock$Parser;->getAttributeNameResource(I)I
 HSPLandroid/content/res/XmlBlock$Parser;->getAttributeResourceValue(II)I
 HSPLandroid/content/res/XmlBlock$Parser;->getAttributeResourceValue(Ljava/lang/String;Ljava/lang/String;I)I
-HSPLandroid/content/res/XmlBlock$Parser;->getAttributeValue(I)Ljava/lang/String;
+HSPLandroid/content/res/XmlBlock$Parser;->getAttributeValue(I)Ljava/lang/String;+]Landroid/content/res/StringBlock;Landroid/content/res/StringBlock;
 HSPLandroid/content/res/XmlBlock$Parser;->getAttributeValue(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/content/res/XmlBlock$Parser;->getClassAttribute()Ljava/lang/String;
 HSPLandroid/content/res/XmlBlock$Parser;->getDepth()I
@@ -5345,14 +5371,14 @@
 HSPLandroid/content/res/XmlBlock$Parser;->getName()Ljava/lang/String;+]Landroid/content/res/StringBlock;Landroid/content/res/StringBlock;
 HSPLandroid/content/res/XmlBlock$Parser;->getPooledString(I)Ljava/lang/CharSequence;+]Landroid/content/res/StringBlock;Landroid/content/res/StringBlock;
 HSPLandroid/content/res/XmlBlock$Parser;->getPositionDescription()Ljava/lang/String;
-HSPLandroid/content/res/XmlBlock$Parser;->getSequenceString(Ljava/lang/CharSequence;)Ljava/lang/String;+]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/content/res/XmlBlock$Parser;->getSequenceString(Ljava/lang/CharSequence;)Ljava/lang/String;
 HSPLandroid/content/res/XmlBlock$Parser;->getSourceResId()I
 HSPLandroid/content/res/XmlBlock$Parser;->getText()Ljava/lang/String;
 HSPLandroid/content/res/XmlBlock$Parser;->isEmptyElementTag()Z
-HSPLandroid/content/res/XmlBlock$Parser;->next()I+]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/content/res/XmlBlock$Parser;->next()I+]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;]Landroid/content/res/Validator;Landroid/content/res/Validator;
 HSPLandroid/content/res/XmlBlock$Parser;->nextTag()I
 HSPLandroid/content/res/XmlBlock$Parser;->nextText()Ljava/lang/String;
-HSPLandroid/content/res/XmlBlock$Parser;->require(ILjava/lang/String;Ljava/lang/String;)V+]Landroid/content/res/XmlBlock$Parser;Landroid/content/res/XmlBlock$Parser;]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/content/res/XmlBlock$Parser;->require(ILjava/lang/String;Ljava/lang/String;)V
 HSPLandroid/content/res/XmlBlock;->-$$Nest$fgetmOpenCount(Landroid/content/res/XmlBlock;)I
 HSPLandroid/content/res/XmlBlock;->-$$Nest$fputmOpenCount(Landroid/content/res/XmlBlock;I)V
 HSPLandroid/content/res/XmlBlock;->-$$Nest$smnativeGetAttributeCount(J)I
@@ -5366,7 +5392,7 @@
 HSPLandroid/content/res/XmlBlock;->-$$Nest$smnativeGetText(J)I
 HSPLandroid/content/res/XmlBlock;-><init>(Landroid/content/res/AssetManager;J)V
 HSPLandroid/content/res/XmlBlock;->close()V
-HSPLandroid/content/res/XmlBlock;->decOpenCountLocked()V+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/content/res/StringBlock;Landroid/content/res/StringBlock;]Ljava/lang/Object;Landroid/content/res/XmlBlock;
+HSPLandroid/content/res/XmlBlock;->decOpenCountLocked()V
 HSPLandroid/content/res/XmlBlock;->finalize()V
 HSPLandroid/content/res/XmlBlock;->newParser()Landroid/content/res/XmlResourceParser;
 HSPLandroid/content/res/XmlBlock;->newParser(I)Landroid/content/res/XmlResourceParser;
@@ -5376,29 +5402,29 @@
 HSPLandroid/content/type/DefaultMimeMapFactory;->parseTypes(Llibcore/content/type/MimeMap$Builder;Ljava/util/function/Function;Ljava/lang/String;)V
 HSPLandroid/database/AbstractCursor$SelfContentObserver;-><init>(Landroid/database/AbstractCursor;)V
 HSPLandroid/database/AbstractCursor$SelfContentObserver;->onChange(Z)V
-HSPLandroid/database/AbstractCursor;-><init>()V
-HSPLandroid/database/AbstractCursor;->checkPosition()V+]Landroid/database/AbstractCursor;Landroid/database/BulkCursorToCursorAdaptor;,Landroid/database/sqlite/SQLiteCursor;
-HSPLandroid/database/AbstractCursor;->close()V
+HSPLandroid/database/AbstractCursor;-><init>()V+]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
+HSPLandroid/database/AbstractCursor;->checkPosition()V+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;
+HSPLandroid/database/AbstractCursor;->close()V+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;,Landroid/database/MatrixCursor;]Landroid/database/ContentObservable;Landroid/database/ContentObservable;]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
 HSPLandroid/database/AbstractCursor;->fillWindow(ILandroid/database/CursorWindow;)V
 HSPLandroid/database/AbstractCursor;->finalize()V+]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
-HSPLandroid/database/AbstractCursor;->getColumnCount()I
+HSPLandroid/database/AbstractCursor;->getColumnCount()I+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;
 HSPLandroid/database/AbstractCursor;->getColumnIndex(Ljava/lang/String;)I
 HSPLandroid/database/AbstractCursor;->getColumnIndexOrThrow(Ljava/lang/String;)I
-HSPLandroid/database/AbstractCursor;->getColumnName(I)Ljava/lang/String;
+HSPLandroid/database/AbstractCursor;->getColumnName(I)Ljava/lang/String;+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;
 HSPLandroid/database/AbstractCursor;->getExtras()Landroid/os/Bundle;
 HSPLandroid/database/AbstractCursor;->getPosition()I
 HSPLandroid/database/AbstractCursor;->getWantsAllOnMoveCalls()Z
 HSPLandroid/database/AbstractCursor;->getWindow()Landroid/database/CursorWindow;
-HSPLandroid/database/AbstractCursor;->isAfterLast()Z
+HSPLandroid/database/AbstractCursor;->isAfterLast()Z+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;
 HSPLandroid/database/AbstractCursor;->isClosed()Z
 HSPLandroid/database/AbstractCursor;->isLast()Z
 HSPLandroid/database/AbstractCursor;->move(I)Z
 HSPLandroid/database/AbstractCursor;->moveToFirst()Z
 HSPLandroid/database/AbstractCursor;->moveToLast()Z
-HSPLandroid/database/AbstractCursor;->moveToNext()Z
-HSPLandroid/database/AbstractCursor;->moveToPosition(I)Z
+HSPLandroid/database/AbstractCursor;->moveToNext()Z+]Landroid/database/AbstractCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/MatrixCursor;,Landroid/database/BulkCursorToCursorAdaptor;
+HSPLandroid/database/AbstractCursor;->moveToPosition(I)Z+]Landroid/database/AbstractCursor;missing_types
 HSPLandroid/database/AbstractCursor;->onChange(Z)V
-HSPLandroid/database/AbstractCursor;->onDeactivateOrClose()V
+HSPLandroid/database/AbstractCursor;->onDeactivateOrClose()V+]Landroid/database/DataSetObservable;Landroid/database/DataSetObservable;
 HSPLandroid/database/AbstractCursor;->onMove(II)Z
 HSPLandroid/database/AbstractCursor;->registerContentObserver(Landroid/database/ContentObserver;)V
 HSPLandroid/database/AbstractCursor;->registerDataSetObserver(Landroid/database/DataSetObserver;)V
@@ -5409,18 +5435,18 @@
 HSPLandroid/database/AbstractWindowedCursor;-><init>()V
 HSPLandroid/database/AbstractWindowedCursor;->checkPosition()V
 HSPLandroid/database/AbstractWindowedCursor;->clearOrCreateWindow(Ljava/lang/String;)V
-HSPLandroid/database/AbstractWindowedCursor;->closeWindow()V
+HSPLandroid/database/AbstractWindowedCursor;->closeWindow()V+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
 HSPLandroid/database/AbstractWindowedCursor;->getBlob(I)[B
-HSPLandroid/database/AbstractWindowedCursor;->getDouble(I)D
+HSPLandroid/database/AbstractWindowedCursor;->getDouble(I)D+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
 HSPLandroid/database/AbstractWindowedCursor;->getFloat(I)F
-HSPLandroid/database/AbstractWindowedCursor;->getInt(I)I+]Landroid/database/AbstractWindowedCursor;Landroid/database/BulkCursorToCursorAdaptor;,Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
-HSPLandroid/database/AbstractWindowedCursor;->getLong(I)J+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
-HSPLandroid/database/AbstractWindowedCursor;->getString(I)Ljava/lang/String;+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
+HSPLandroid/database/AbstractWindowedCursor;->getInt(I)I+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
+HSPLandroid/database/AbstractWindowedCursor;->getLong(I)J+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
+HSPLandroid/database/AbstractWindowedCursor;->getString(I)Ljava/lang/String;+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
 HSPLandroid/database/AbstractWindowedCursor;->getType(I)I
 HSPLandroid/database/AbstractWindowedCursor;->getWindow()Landroid/database/CursorWindow;
 HSPLandroid/database/AbstractWindowedCursor;->hasWindow()Z
 HSPLandroid/database/AbstractWindowedCursor;->isNull(I)Z+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
-HSPLandroid/database/AbstractWindowedCursor;->onDeactivateOrClose()V
+HSPLandroid/database/AbstractWindowedCursor;->onDeactivateOrClose()V+]Landroid/database/AbstractWindowedCursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/database/BulkCursorToCursorAdaptor;
 HSPLandroid/database/AbstractWindowedCursor;->setWindow(Landroid/database/CursorWindow;)V
 HSPLandroid/database/BulkCursorDescriptor$1;->createFromParcel(Landroid/os/Parcel;)Landroid/database/BulkCursorDescriptor;
 HSPLandroid/database/BulkCursorDescriptor$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -5441,7 +5467,7 @@
 HSPLandroid/database/BulkCursorToCursorAdaptor;->getCount()I
 HSPLandroid/database/BulkCursorToCursorAdaptor;->getObserver()Landroid/database/IContentObserver;
 HSPLandroid/database/BulkCursorToCursorAdaptor;->initialize(Landroid/database/BulkCursorDescriptor;)V
-HSPLandroid/database/BulkCursorToCursorAdaptor;->onMove(II)Z
+HSPLandroid/database/BulkCursorToCursorAdaptor;->onMove(II)Z+]Landroid/database/IBulkCursor;Landroid/database/BulkCursorProxy;]Landroid/database/BulkCursorToCursorAdaptor;Landroid/database/BulkCursorToCursorAdaptor;
 HSPLandroid/database/BulkCursorToCursorAdaptor;->throwIfCursorIsClosed()V
 HSPLandroid/database/ContentObservable;-><init>()V
 HSPLandroid/database/ContentObservable;->dispatchChange(ZLandroid/net/Uri;)V
@@ -5480,18 +5506,18 @@
 HSPLandroid/database/CursorWindow;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/database/CursorWindow;-><init>(Landroid/os/Parcel;Landroid/database/CursorWindow-IA;)V
 HSPLandroid/database/CursorWindow;-><init>(Ljava/lang/String;)V
-HSPLandroid/database/CursorWindow;-><init>(Ljava/lang/String;J)V
+HSPLandroid/database/CursorWindow;-><init>(Ljava/lang/String;J)V+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/database/CursorWindow;->allocRow()Z
 HSPLandroid/database/CursorWindow;->clear()V
-HSPLandroid/database/CursorWindow;->dispose()V
-HSPLandroid/database/CursorWindow;->finalize()V
-HSPLandroid/database/CursorWindow;->getBlob(II)[B+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
+HSPLandroid/database/CursorWindow;->dispose()V+]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
+HSPLandroid/database/CursorWindow;->finalize()V+]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
+HSPLandroid/database/CursorWindow;->getBlob(II)[B
 HSPLandroid/database/CursorWindow;->getCursorWindowSize()I
-HSPLandroid/database/CursorWindow;->getDouble(II)D
+HSPLandroid/database/CursorWindow;->getDouble(II)D+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
 HSPLandroid/database/CursorWindow;->getFloat(II)F
-HSPLandroid/database/CursorWindow;->getInt(II)I
+HSPLandroid/database/CursorWindow;->getInt(II)I+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
 HSPLandroid/database/CursorWindow;->getLong(II)J+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
-HSPLandroid/database/CursorWindow;->getNumRows()I
+HSPLandroid/database/CursorWindow;->getNumRows()I+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
 HSPLandroid/database/CursorWindow;->getStartPosition()I
 HSPLandroid/database/CursorWindow;->getString(II)Ljava/lang/String;+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
 HSPLandroid/database/CursorWindow;->getType(II)I+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
@@ -5513,16 +5539,16 @@
 HSPLandroid/database/CursorWrapper;->getColumnNames()[Ljava/lang/String;
 HSPLandroid/database/CursorWrapper;->getCount()I
 HSPLandroid/database/CursorWrapper;->getExtras()Landroid/os/Bundle;
-HSPLandroid/database/CursorWrapper;->getInt(I)I
+HSPLandroid/database/CursorWrapper;->getInt(I)I+]Landroid/database/Cursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/content/ContentProviderClient$CursorWrapperInner;,Landroid/database/BulkCursorToCursorAdaptor;
 HSPLandroid/database/CursorWrapper;->getLong(I)J
 HSPLandroid/database/CursorWrapper;->getPosition()I
 HSPLandroid/database/CursorWrapper;->getString(I)Ljava/lang/String;
 HSPLandroid/database/CursorWrapper;->getType(I)I
 HSPLandroid/database/CursorWrapper;->getWrappedCursor()Landroid/database/Cursor;
-HSPLandroid/database/CursorWrapper;->isAfterLast()Z
+HSPLandroid/database/CursorWrapper;->isAfterLast()Z+]Landroid/database/Cursor;Landroid/database/sqlite/SQLiteCursor;,Landroid/content/ContentProviderClient$CursorWrapperInner;,Landroid/database/BulkCursorToCursorAdaptor;
 HSPLandroid/database/CursorWrapper;->isClosed()Z
 HSPLandroid/database/CursorWrapper;->isLast()Z
-HSPLandroid/database/CursorWrapper;->isNull(I)Z
+HSPLandroid/database/CursorWrapper;->isNull(I)Z+]Landroid/database/Cursor;Landroid/database/BulkCursorToCursorAdaptor;
 HSPLandroid/database/CursorWrapper;->moveToFirst()Z
 HSPLandroid/database/CursorWrapper;->moveToLast()Z
 HSPLandroid/database/CursorWrapper;->moveToNext()Z
@@ -5530,9 +5556,9 @@
 HSPLandroid/database/CursorWrapper;->registerContentObserver(Landroid/database/ContentObserver;)V
 HSPLandroid/database/DataSetObservable;-><init>()V
 HSPLandroid/database/DataSetObservable;->notifyChanged()V
-HSPLandroid/database/DataSetObservable;->notifyInvalidated()V
+HSPLandroid/database/DataSetObservable;->notifyInvalidated()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/database/DataSetObserver;-><init>()V
-HSPLandroid/database/DatabaseUtils;->appendEscapedSQLString(Ljava/lang/StringBuilder;Ljava/lang/String;)V
+HSPLandroid/database/DatabaseUtils;->appendEscapedSQLString(Ljava/lang/StringBuilder;Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/database/DatabaseUtils;->categorizeStatement(Ljava/lang/String;Ljava/lang/String;)I+]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/database/DatabaseUtils;->cursorFillWindow(Landroid/database/Cursor;ILandroid/database/CursorWindow;)V
 HSPLandroid/database/DatabaseUtils;->getSqlStatementPrefixSimple(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
@@ -5587,16 +5613,16 @@
 HSPLandroid/database/MergeCursor;->onMove(II)Z
 HSPLandroid/database/Observable;-><init>()V
 HSPLandroid/database/Observable;->registerObserver(Ljava/lang/Object;)V
-HSPLandroid/database/Observable;->unregisterAll()V
+HSPLandroid/database/Observable;->unregisterAll()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/database/Observable;->unregisterObserver(Ljava/lang/Object;)V
 HSPLandroid/database/sqlite/FeatureFlagsImpl;-><init>()V
 HSPLandroid/database/sqlite/FeatureFlagsImpl;->sqliteAllowTempTables()Z
 HSPLandroid/database/sqlite/Flags;-><clinit>()V
-HSPLandroid/database/sqlite/Flags;->sqliteAllowTempTables()Z
+HSPLandroid/database/sqlite/Flags;->sqliteAllowTempTables()Z+]Landroid/database/sqlite/FeatureFlags;Landroid/database/sqlite/FeatureFlagsImpl;
 HSPLandroid/database/sqlite/SQLiteClosable;-><init>()V
 HSPLandroid/database/sqlite/SQLiteClosable;->acquireReference()V
-HSPLandroid/database/sqlite/SQLiteClosable;->close()V
-HSPLandroid/database/sqlite/SQLiteClosable;->releaseReference()V+]Landroid/database/sqlite/SQLiteClosable;Landroid/database/CursorWindow;,Landroid/database/sqlite/SQLiteDatabase;,Landroid/database/sqlite/SQLiteQuery;,Landroid/database/sqlite/SQLiteStatement;
+HSPLandroid/database/sqlite/SQLiteClosable;->close()V+]Landroid/database/sqlite/SQLiteClosable;Landroid/database/CursorWindow;,Landroid/database/sqlite/SQLiteStatement;,Landroid/database/sqlite/SQLiteDatabase;,Landroid/database/sqlite/SQLiteQuery;
+HSPLandroid/database/sqlite/SQLiteClosable;->releaseReference()V+]Landroid/database/sqlite/SQLiteClosable;Landroid/database/CursorWindow;,Landroid/database/sqlite/SQLiteStatement;,Landroid/database/sqlite/SQLiteDatabase;,Landroid/database/sqlite/SQLiteQuery;
 HSPLandroid/database/sqlite/SQLiteCompatibilityWalFlags;->getTruncateSize()J
 HSPLandroid/database/sqlite/SQLiteCompatibilityWalFlags;->init(Ljava/lang/String;)V
 HSPLandroid/database/sqlite/SQLiteCompatibilityWalFlags;->initIfNeeded()V
@@ -5610,7 +5636,7 @@
 HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->dump(Landroid/util/Printer;)V
 HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->endOperation(I)V
 HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->endOperationDeferLog(I)Z
-HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->endOperationDeferLogLocked(I)Z
+HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->endOperationDeferLogLocked(I)Z+]Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteConnectionPool;
 HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->failOperation(ILjava/lang/Exception;)V
 HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->getOperationLocked(I)Landroid/database/sqlite/SQLiteConnection$Operation;
 HSPLandroid/database/sqlite/SQLiteConnection$OperationLog;->newOperationCookieLocked(I)I
@@ -5626,38 +5652,38 @@
 HSPLandroid/database/sqlite/SQLiteConnection;->-$$Nest$fgetmConnectionPtr(Landroid/database/sqlite/SQLiteConnection;)J
 HSPLandroid/database/sqlite/SQLiteConnection;->-$$Nest$mfinalizePreparedStatement(Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
 HSPLandroid/database/sqlite/SQLiteConnection;->-$$Nest$smnativePrepareStatement(JLjava/lang/String;)J
-HSPLandroid/database/sqlite/SQLiteConnection;-><init>(Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteDatabaseConfiguration;IZ)V
+HSPLandroid/database/sqlite/SQLiteConnection;-><init>(Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteDatabaseConfiguration;IZ)V+]Landroid/database/sqlite/SQLiteDatabaseConfiguration;Landroid/database/sqlite/SQLiteDatabaseConfiguration;]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
 HSPLandroid/database/sqlite/SQLiteConnection;->acquirePreparedStatement(Ljava/lang/String;)Landroid/database/sqlite/SQLiteConnection$PreparedStatement;
 HSPLandroid/database/sqlite/SQLiteConnection;->acquirePreparedStatementLI(Ljava/lang/String;)Landroid/database/sqlite/SQLiteConnection$PreparedStatement;+]Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;
-HSPLandroid/database/sqlite/SQLiteConnection;->applyBlockGuardPolicy(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
-HSPLandroid/database/sqlite/SQLiteConnection;->attachCancellationSignal(Landroid/os/CancellationSignal;)V
-HSPLandroid/database/sqlite/SQLiteConnection;->bindArguments(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;[Ljava/lang/Object;)V+]Ljava/lang/Number;Ljava/lang/Double;,Ljava/lang/Integer;,Ljava/lang/Long;]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteConnection;->applyBlockGuardPolicy(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V+]Landroid/database/sqlite/SQLiteDatabaseConfiguration;Landroid/database/sqlite/SQLiteDatabaseConfiguration;]Ldalvik/system/BlockGuard$Policy;Ldalvik/system/BlockGuard$1;,Landroid/os/StrictMode$AndroidBlockGuardPolicy;
+HSPLandroid/database/sqlite/SQLiteConnection;->attachCancellationSignal(Landroid/os/CancellationSignal;)V+]Landroid/os/CancellationSignal;Landroid/os/CancellationSignal;
+HSPLandroid/database/sqlite/SQLiteConnection;->bindArguments(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;[Ljava/lang/Object;)V+]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/Number;Ljava/lang/Integer;,Ljava/lang/Double;,Ljava/lang/Long;
 HSPLandroid/database/sqlite/SQLiteConnection;->canonicalizeSyncMode(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteConnection;->checkDatabaseWiped()V
 HSPLandroid/database/sqlite/SQLiteConnection;->close()V
 HSPLandroid/database/sqlite/SQLiteConnection;->collectDbStats(Ljava/util/ArrayList;)V
-HSPLandroid/database/sqlite/SQLiteConnection;->detachCancellationSignal(Landroid/os/CancellationSignal;)V
+HSPLandroid/database/sqlite/SQLiteConnection;->detachCancellationSignal(Landroid/os/CancellationSignal;)V+]Landroid/os/CancellationSignal;Landroid/os/CancellationSignal;
 HSPLandroid/database/sqlite/SQLiteConnection;->dispose(Z)V
 HSPLandroid/database/sqlite/SQLiteConnection;->dumpUnsafe(Landroid/util/Printer;Z)V
-HSPLandroid/database/sqlite/SQLiteConnection;->execute(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)V+]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
-HSPLandroid/database/sqlite/SQLiteConnection;->executeForChangedRowCount(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)I
-HSPLandroid/database/sqlite/SQLiteConnection;->executeForCursorWindow(Ljava/lang/String;[Ljava/lang/Object;Landroid/database/CursorWindow;IIZLandroid/os/CancellationSignal;)I
+HSPLandroid/database/sqlite/SQLiteConnection;->execute(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
+HSPLandroid/database/sqlite/SQLiteConnection;->executeForChangedRowCount(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)I+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
+HSPLandroid/database/sqlite/SQLiteConnection;->executeForCursorWindow(Ljava/lang/String;[Ljava/lang/Object;Landroid/database/CursorWindow;IIZLandroid/os/CancellationSignal;)I+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
 HSPLandroid/database/sqlite/SQLiteConnection;->executeForLastInsertedRowId(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)J
-HSPLandroid/database/sqlite/SQLiteConnection;->executeForLong(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)J+]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
-HSPLandroid/database/sqlite/SQLiteConnection;->executeForString(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteConnection;->executeForLong(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)J+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
+HSPLandroid/database/sqlite/SQLiteConnection;->executeForString(Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)Ljava/lang/String;+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
 HSPLandroid/database/sqlite/SQLiteConnection;->executePerConnectionSqlFromConfiguration(I)V
 HSPLandroid/database/sqlite/SQLiteConnection;->finalize()V
 HSPLandroid/database/sqlite/SQLiteConnection;->finalizePreparedStatement(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
 HSPLandroid/database/sqlite/SQLiteConnection;->getConnectionId()I
 HSPLandroid/database/sqlite/SQLiteConnection;->getMainDbStatsUnsafe(IJJ)Landroid/database/sqlite/SQLiteDebug$DbStats;
 HSPLandroid/database/sqlite/SQLiteConnection;->isCacheable(I)Z
-HSPLandroid/database/sqlite/SQLiteConnection;->isPreparedStatementInCache(Ljava/lang/String;)Z
+HSPLandroid/database/sqlite/SQLiteConnection;->isPreparedStatementInCache(Ljava/lang/String;)Z+]Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;
 HSPLandroid/database/sqlite/SQLiteConnection;->isPrimaryConnection()Z
 HSPLandroid/database/sqlite/SQLiteConnection;->maybeTruncateWalFile()V
 HSPLandroid/database/sqlite/SQLiteConnection;->obtainPreparedStatement(Ljava/lang/String;JIIZJ)Landroid/database/sqlite/SQLiteConnection$PreparedStatement;
-HSPLandroid/database/sqlite/SQLiteConnection;->open()V
+HSPLandroid/database/sqlite/SQLiteConnection;->open()V+]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
 HSPLandroid/database/sqlite/SQLiteConnection;->open(Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteDatabaseConfiguration;IZ)Landroid/database/sqlite/SQLiteConnection;
-HSPLandroid/database/sqlite/SQLiteConnection;->prepare(Ljava/lang/String;Landroid/database/sqlite/SQLiteStatementInfo;)V
+HSPLandroid/database/sqlite/SQLiteConnection;->prepare(Ljava/lang/String;Landroid/database/sqlite/SQLiteStatementInfo;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/database/sqlite/SQLiteConnection$OperationLog;Landroid/database/sqlite/SQLiteConnection$OperationLog;
 HSPLandroid/database/sqlite/SQLiteConnection;->reconfigure(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V
 HSPLandroid/database/sqlite/SQLiteConnection;->recyclePreparedStatement(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
 HSPLandroid/database/sqlite/SQLiteConnection;->releasePreparedStatement(Landroid/database/sqlite/SQLiteConnection$PreparedStatement;)V
@@ -5682,6 +5708,7 @@
 HSPLandroid/database/sqlite/SQLiteConnectionPool$IdleConnectionHandler;->handleMessage(Landroid/os/Message;)V
 HSPLandroid/database/sqlite/SQLiteConnectionPool;-><init>(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->acquireConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->clearAcquiredConnectionsPreparedStatementCache()V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;]Ljava/util/Iterator;Ljava/util/WeakHashMap$KeyIterator;]Ljava/util/Set;Ljava/util/WeakHashMap$KeySet;
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->close()V
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->closeAvailableConnectionLocked(I)Z
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->closeAvailableConnectionsAndLogExceptionsLocked()V
@@ -5695,13 +5722,13 @@
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->dispose(Z)V
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->dump(Landroid/util/Printer;ZLandroid/util/ArraySet;)V
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->finalize()V
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->finishAcquireConnectionLocked(Landroid/database/sqlite/SQLiteConnection;I)V
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->finishAcquireConnectionLocked(Landroid/database/sqlite/SQLiteConnection;I)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->getPath()Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->getPriority(I)I
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->isSessionBlockingImportantConnectionWaitersLocked(ZI)Z
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->markAcquiredConnectionsLocked(Landroid/database/sqlite/SQLiteConnectionPool$AcquiredConnectionStatus;)V
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->obtainConnectionWaiterLocked(Ljava/lang/Thread;JIZLjava/lang/String;I)Landroid/database/sqlite/SQLiteConnectionPool$ConnectionWaiter;
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->onStatementExecuted(J)V
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->onStatementExecuted(J)V+]Ljava/util/concurrent/atomic/AtomicLong;Ljava/util/concurrent/atomic/AtomicLong;
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->open()V
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->open(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)Landroid/database/sqlite/SQLiteConnectionPool;
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->openConnectionLocked(Landroid/database/sqlite/SQLiteDatabaseConfiguration;Z)Landroid/database/sqlite/SQLiteConnection;
@@ -5709,23 +5736,23 @@
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->reconfigureAllConnectionsLocked()V
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->recycleConnectionLocked(Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnectionPool$AcquiredConnectionStatus;)Z
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->recycleConnectionWaiterLocked(Landroid/database/sqlite/SQLiteConnectionPool$ConnectionWaiter;)V
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->releaseConnection(Landroid/database/sqlite/SQLiteConnection;)V
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->releaseConnection(Landroid/database/sqlite/SQLiteConnection;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->setMaxConnectionPoolSizeLocked()V
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->shouldYieldConnection(Landroid/database/sqlite/SQLiteConnection;I)Z
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->throwIfClosedLocked()V
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->tryAcquireNonPrimaryConnectionLocked(Ljava/lang/String;I)Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->tryAcquireNonPrimaryConnectionLocked(Ljava/lang/String;I)Landroid/database/sqlite/SQLiteConnection;+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Ljava/util/WeakHashMap;Ljava/util/WeakHashMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->tryAcquirePrimaryConnectionLocked(I)Landroid/database/sqlite/SQLiteConnection;
-HSPLandroid/database/sqlite/SQLiteConnectionPool;->waitForConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteConnectionPool;->waitForConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)Landroid/database/sqlite/SQLiteConnection;+]Ljava/util/concurrent/atomic/AtomicBoolean;Ljava/util/concurrent/atomic/AtomicBoolean;
 HSPLandroid/database/sqlite/SQLiteConnectionPool;->wakeConnectionWaitersLocked()V
 HSPLandroid/database/sqlite/SQLiteConstraintException;-><init>(Ljava/lang/String;)V
-HSPLandroid/database/sqlite/SQLiteCursor;-><init>(Landroid/database/sqlite/SQLiteCursorDriver;Ljava/lang/String;Landroid/database/sqlite/SQLiteQuery;)V
-HSPLandroid/database/sqlite/SQLiteCursor;->close()V
-HSPLandroid/database/sqlite/SQLiteCursor;->fillWindow(I)V
+HSPLandroid/database/sqlite/SQLiteCursor;-><init>(Landroid/database/sqlite/SQLiteCursorDriver;Ljava/lang/String;Landroid/database/sqlite/SQLiteQuery;)V+]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
+HSPLandroid/database/sqlite/SQLiteCursor;->close()V+]Landroid/database/sqlite/SQLiteCursorDriver;Landroid/database/sqlite/SQLiteDirectCursorDriver;]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
+HSPLandroid/database/sqlite/SQLiteCursor;->fillWindow(I)V+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;]Landroid/database/sqlite/SQLiteCursor;Landroid/database/sqlite/SQLiteCursor;]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteCursor;->finalize()V
-HSPLandroid/database/sqlite/SQLiteCursor;->getColumnIndex(Ljava/lang/String;)I
+HSPLandroid/database/sqlite/SQLiteCursor;->getColumnIndex(Ljava/lang/String;)I+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/Map;Ljava/util/HashMap;
 HSPLandroid/database/sqlite/SQLiteCursor;->getColumnNames()[Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteCursor;->getCount()I
-HSPLandroid/database/sqlite/SQLiteCursor;->getDatabase()Landroid/database/sqlite/SQLiteDatabase;
+HSPLandroid/database/sqlite/SQLiteCursor;->getDatabase()Landroid/database/sqlite/SQLiteDatabase;+]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
 HSPLandroid/database/sqlite/SQLiteCursor;->onMove(II)Z+]Landroid/database/CursorWindow;Landroid/database/CursorWindow;
 HSPLandroid/database/sqlite/SQLiteDatabase$$ExternalSyntheticLambda0;-><init>(Landroid/database/sqlite/SQLiteDatabase;)V
 HSPLandroid/database/sqlite/SQLiteDatabase$$ExternalSyntheticLambda0;->get()Ljava/lang/Object;
@@ -5752,13 +5779,13 @@
 HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;->-$$Nest$fgetmSyncMode(Landroid/database/sqlite/SQLiteDatabase$OpenParams;)Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;-><init>(ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;IIJLjava/lang/String;Ljava/lang/String;)V
 HSPLandroid/database/sqlite/SQLiteDatabase$OpenParams;-><init>(ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;IIJLjava/lang/String;Ljava/lang/String;Landroid/database/sqlite/SQLiteDatabase$OpenParams-IA;)V
-HSPLandroid/database/sqlite/SQLiteDatabase;-><init>(Ljava/lang/String;ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;IIJLjava/lang/String;Ljava/lang/String;)V
+HSPLandroid/database/sqlite/SQLiteDatabase;-><init>(Ljava/lang/String;ILandroid/database/sqlite/SQLiteDatabase$CursorFactory;Landroid/database/DatabaseErrorHandler;IIJLjava/lang/String;Ljava/lang/String;)V+]Landroid/database/sqlite/SQLiteDatabaseConfiguration;Landroid/database/sqlite/SQLiteDatabaseConfiguration;
 HSPLandroid/database/sqlite/SQLiteDatabase;->beginTransaction()V
 HSPLandroid/database/sqlite/SQLiteDatabase;->beginTransaction(Landroid/database/sqlite/SQLiteTransactionListener;Z)V
 HSPLandroid/database/sqlite/SQLiteDatabase;->beginTransactionNonExclusive()V
 HSPLandroid/database/sqlite/SQLiteDatabase;->beginTransactionWithListener(Landroid/database/sqlite/SQLiteTransactionListener;)V
 HSPLandroid/database/sqlite/SQLiteDatabase;->collectDbStats(Ljava/util/ArrayList;)V
-HSPLandroid/database/sqlite/SQLiteDatabase;->compileStatement(Ljava/lang/String;)Landroid/database/sqlite/SQLiteStatement;+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
+HSPLandroid/database/sqlite/SQLiteDatabase;->compileStatement(Ljava/lang/String;)Landroid/database/sqlite/SQLiteStatement;
 HSPLandroid/database/sqlite/SQLiteDatabase;->createSession()Landroid/database/sqlite/SQLiteSession;
 HSPLandroid/database/sqlite/SQLiteDatabase;->delete(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)I
 HSPLandroid/database/sqlite/SQLiteDatabase;->deleteDatabase(Ljava/io/File;)Z
@@ -5773,7 +5800,7 @@
 HSPLandroid/database/sqlite/SQLiteDatabase;->execSQL(Ljava/lang/String;[Ljava/lang/Object;)V
 HSPLandroid/database/sqlite/SQLiteDatabase;->executeSql(Ljava/lang/String;[Ljava/lang/Object;)I
 HSPLandroid/database/sqlite/SQLiteDatabase;->finalize()V
-HSPLandroid/database/sqlite/SQLiteDatabase;->findEditTable(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteDatabase;->findEditTable(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteDatabase;->getActiveDatabasePools()Ljava/util/ArrayList;
 HSPLandroid/database/sqlite/SQLiteDatabase;->getActiveDatabases()Ljava/util/ArrayList;
 HSPLandroid/database/sqlite/SQLiteDatabase;->getFileTimestamps(Ljava/lang/String;)Ljava/lang/String;
@@ -5781,12 +5808,12 @@
 HSPLandroid/database/sqlite/SQLiteDatabase;->getPageSize()J
 HSPLandroid/database/sqlite/SQLiteDatabase;->getPath()Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteDatabase;->getThreadDefaultConnectionFlags(Z)I
-HSPLandroid/database/sqlite/SQLiteDatabase;->getThreadSession()Landroid/database/sqlite/SQLiteSession;
+HSPLandroid/database/sqlite/SQLiteDatabase;->getThreadSession()Landroid/database/sqlite/SQLiteSession;+]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;
 HSPLandroid/database/sqlite/SQLiteDatabase;->getVersion()I
-HSPLandroid/database/sqlite/SQLiteDatabase;->inTransaction()Z
+HSPLandroid/database/sqlite/SQLiteDatabase;->inTransaction()Z+]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteDatabase;->insert(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;)J
 HSPLandroid/database/sqlite/SQLiteDatabase;->insertOrThrow(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;)J
-HSPLandroid/database/sqlite/SQLiteDatabase;->insertWithOnConflict(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;I)J+]Landroid/content/ContentValues;Landroid/content/ContentValues;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;]Landroid/database/sqlite/SQLiteStatement;Landroid/database/sqlite/SQLiteStatement;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
+HSPLandroid/database/sqlite/SQLiteDatabase;->insertWithOnConflict(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;I)J
 HSPLandroid/database/sqlite/SQLiteDatabase;->isMainThread()Z
 HSPLandroid/database/sqlite/SQLiteDatabase;->isOpen()Z
 HSPLandroid/database/sqlite/SQLiteDatabase;->isReadOnly()Z
@@ -5804,11 +5831,11 @@
 HSPLandroid/database/sqlite/SQLiteDatabase;->query(Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
 HSPLandroid/database/sqlite/SQLiteDatabase;->query(ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
 HSPLandroid/database/sqlite/SQLiteDatabase;->query(ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
-HSPLandroid/database/sqlite/SQLiteDatabase;->queryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
+HSPLandroid/database/sqlite/SQLiteDatabase;->queryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteDatabase;->rawQuery(Ljava/lang/String;[Ljava/lang/String;)Landroid/database/Cursor;
 HSPLandroid/database/sqlite/SQLiteDatabase;->rawQuery(Ljava/lang/String;[Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
-HSPLandroid/database/sqlite/SQLiteDatabase;->rawQueryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
-HSPLandroid/database/sqlite/SQLiteDatabase;->rawQueryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;
+HSPLandroid/database/sqlite/SQLiteDatabase;->rawQueryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
+HSPLandroid/database/sqlite/SQLiteDatabase;->rawQueryWithFactory(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)Landroid/database/Cursor;+]Landroid/database/sqlite/SQLiteCursorDriver;Landroid/database/sqlite/SQLiteDirectCursorDriver;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteDatabase;->releaseMemory()I
 HSPLandroid/database/sqlite/SQLiteDatabase;->replace(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;)J
 HSPLandroid/database/sqlite/SQLiteDatabase;->replaceOrThrow(Ljava/lang/String;Ljava/lang/String;Landroid/content/ContentValues;)J
@@ -5816,26 +5843,26 @@
 HSPLandroid/database/sqlite/SQLiteDatabase;->setTransactionSuccessful()V
 HSPLandroid/database/sqlite/SQLiteDatabase;->throwIfNotOpenLocked()V
 HSPLandroid/database/sqlite/SQLiteDatabase;->update(Ljava/lang/String;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;)I
-HSPLandroid/database/sqlite/SQLiteDatabase;->updateWithOnConflict(Ljava/lang/String;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;I)I
+HSPLandroid/database/sqlite/SQLiteDatabase;->updateWithOnConflict(Ljava/lang/String;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;I)I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/content/ContentValues;Landroid/content/ContentValues;]Landroid/database/sqlite/SQLiteStatement;Landroid/database/sqlite/SQLiteStatement;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;]Ljava/util/Set;Landroid/util/MapCollections$KeySet;
 HSPLandroid/database/sqlite/SQLiteDatabase;->validateSql(Ljava/lang/String;Landroid/os/CancellationSignal;)V
 HSPLandroid/database/sqlite/SQLiteDatabase;->yieldIfContendedHelper(ZJ)Z
 HSPLandroid/database/sqlite/SQLiteDatabase;->yieldIfContendedSafely(J)Z
 HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;-><init>(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V
 HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;-><init>(Ljava/lang/String;I)V
-HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isInMemoryDb()Z
+HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isInMemoryDb()Z+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isLegacyCompatibilityWalEnabled()Z
 HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isReadOnlyDatabase()Z
 HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->isWalEnabledInternal()Z
 HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->resolveJournalMode()Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->resolveSyncMode()Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->stripPathForLogs(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->updateParametersFrom(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V
+HSPLandroid/database/sqlite/SQLiteDatabaseConfiguration;->updateParametersFrom(Landroid/database/sqlite/SQLiteDatabaseConfiguration;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Object;Ljava/lang/String;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/database/sqlite/SQLiteDebug$NoPreloadHolder;-><clinit>()V
 HSPLandroid/database/sqlite/SQLiteDebug;->getDatabaseInfo()Landroid/database/sqlite/SQLiteDebug$PagerStats;
 HSPLandroid/database/sqlite/SQLiteDebug;->shouldLogSlowQuery(J)Z
 HSPLandroid/database/sqlite/SQLiteDirectCursorDriver;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;Ljava/lang/String;Landroid/os/CancellationSignal;)V
 HSPLandroid/database/sqlite/SQLiteDirectCursorDriver;->cursorClosed()V
-HSPLandroid/database/sqlite/SQLiteDirectCursorDriver;->query(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;[Ljava/lang/String;)Landroid/database/Cursor;
+HSPLandroid/database/sqlite/SQLiteDirectCursorDriver;->query(Landroid/database/sqlite/SQLiteDatabase$CursorFactory;[Ljava/lang/String;)Landroid/database/Cursor;+]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
 HSPLandroid/database/sqlite/SQLiteException;-><init>(Ljava/lang/String;)V
 HSPLandroid/database/sqlite/SQLiteGlobal;->checkDbWipe()Z
 HSPLandroid/database/sqlite/SQLiteGlobal;->getDefaultJournalMode()Ljava/lang/String;
@@ -5852,7 +5879,7 @@
 HSPLandroid/database/sqlite/SQLiteOpenHelper;-><init>(Landroid/content/Context;Ljava/lang/String;Landroid/database/sqlite/SQLiteDatabase$CursorFactory;IILandroid/database/DatabaseErrorHandler;)V
 HSPLandroid/database/sqlite/SQLiteOpenHelper;-><init>(Landroid/content/Context;Ljava/lang/String;Landroid/database/sqlite/SQLiteDatabase$CursorFactory;ILandroid/database/DatabaseErrorHandler;)V
 HSPLandroid/database/sqlite/SQLiteOpenHelper;->close()V
-HSPLandroid/database/sqlite/SQLiteOpenHelper;->getDatabaseLocked(Z)Landroid/database/sqlite/SQLiteDatabase;
+HSPLandroid/database/sqlite/SQLiteOpenHelper;->getDatabaseLocked(Z)Landroid/database/sqlite/SQLiteDatabase;+]Ljava/io/File;Ljava/io/File;]Landroid/database/sqlite/SQLiteDatabase$OpenParams$Builder;Landroid/database/sqlite/SQLiteDatabase$OpenParams$Builder;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteOpenHelper;->getDatabaseName()Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteOpenHelper;->getReadableDatabase()Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteOpenHelper;->getWritableDatabase()Landroid/database/sqlite/SQLiteDatabase;
@@ -5862,9 +5889,9 @@
 HSPLandroid/database/sqlite/SQLiteOpenHelper;->setIdleConnectionTimeout(J)V
 HSPLandroid/database/sqlite/SQLiteOpenHelper;->setOpenParamsBuilder(Landroid/database/sqlite/SQLiteDatabase$OpenParams$Builder;)V
 HSPLandroid/database/sqlite/SQLiteOpenHelper;->setWriteAheadLoggingEnabled(Z)V
-HSPLandroid/database/sqlite/SQLiteProgram;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)V
+HSPLandroid/database/sqlite/SQLiteProgram;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;[Ljava/lang/Object;Landroid/os/CancellationSignal;)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteProgram;->bind(ILjava/lang/Object;)V
-HSPLandroid/database/sqlite/SQLiteProgram;->bindAllArgsAsStrings([Ljava/lang/String;)V
+HSPLandroid/database/sqlite/SQLiteProgram;->bindAllArgsAsStrings([Ljava/lang/String;)V+]Landroid/database/sqlite/SQLiteProgram;Landroid/database/sqlite/SQLiteQuery;,Landroid/database/sqlite/SQLiteStatement;
 HSPLandroid/database/sqlite/SQLiteProgram;->bindBlob(I[B)V
 HSPLandroid/database/sqlite/SQLiteProgram;->bindDouble(ID)V
 HSPLandroid/database/sqlite/SQLiteProgram;->bindLong(IJ)V
@@ -5873,19 +5900,19 @@
 HSPLandroid/database/sqlite/SQLiteProgram;->clearBindings()V
 HSPLandroid/database/sqlite/SQLiteProgram;->getBindArgs()[Ljava/lang/Object;
 HSPLandroid/database/sqlite/SQLiteProgram;->getColumnNames()[Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteProgram;->getConnectionFlags()I
+HSPLandroid/database/sqlite/SQLiteProgram;->getConnectionFlags()I+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteProgram;->getDatabase()Landroid/database/sqlite/SQLiteDatabase;
-HSPLandroid/database/sqlite/SQLiteProgram;->getSession()Landroid/database/sqlite/SQLiteSession;
+HSPLandroid/database/sqlite/SQLiteProgram;->getSession()Landroid/database/sqlite/SQLiteSession;+]Landroid/database/sqlite/SQLiteDatabase;Landroid/database/sqlite/SQLiteDatabase;
 HSPLandroid/database/sqlite/SQLiteProgram;->getSql()Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteProgram;->onAllReferencesReleased()V
+HSPLandroid/database/sqlite/SQLiteProgram;->onAllReferencesReleased()V+]Landroid/database/sqlite/SQLiteProgram;Landroid/database/sqlite/SQLiteStatement;,Landroid/database/sqlite/SQLiteQuery;
 HSPLandroid/database/sqlite/SQLiteQuery;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;Landroid/os/CancellationSignal;)V
-HSPLandroid/database/sqlite/SQLiteQuery;->fillWindow(Landroid/database/CursorWindow;IIZ)I
+HSPLandroid/database/sqlite/SQLiteQuery;->fillWindow(Landroid/database/CursorWindow;IIZ)I+]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/CursorWindow;Landroid/database/CursorWindow;]Landroid/database/sqlite/SQLiteQuery;Landroid/database/sqlite/SQLiteQuery;
 HSPLandroid/database/sqlite/SQLiteQueryBuilder;-><init>()V
-HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendClause(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/String;)V
-HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendColumns(Ljava/lang/StringBuilder;[Ljava/lang/String;)V
+HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendClause(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/lang/String;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendColumns(Ljava/lang/StringBuilder;[Ljava/lang/String;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/database/sqlite/SQLiteQueryBuilder;->appendWhere(Ljava/lang/CharSequence;)V
 HSPLandroid/database/sqlite/SQLiteQueryBuilder;->buildQuery([Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteQueryBuilder;->buildQueryString(ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/database/sqlite/SQLiteQueryBuilder;->buildQueryString(ZLjava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/database/sqlite/SQLiteQueryBuilder;->computeProjection([Ljava/lang/String;)[Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteQueryBuilder;->computeSingleProjection(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteQueryBuilder;->computeSingleProjectionOrThrow(Ljava/lang/String;)Ljava/lang/String;
@@ -5905,25 +5932,25 @@
 HSPLandroid/database/sqlite/SQLiteSession$Transaction;-><init>()V
 HSPLandroid/database/sqlite/SQLiteSession$Transaction;-><init>(Landroid/database/sqlite/SQLiteSession$Transaction-IA;)V
 HSPLandroid/database/sqlite/SQLiteSession;-><init>(Landroid/database/sqlite/SQLiteConnectionPool;)V
-HSPLandroid/database/sqlite/SQLiteSession;->acquireConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)V
+HSPLandroid/database/sqlite/SQLiteSession;->acquireConnection(Ljava/lang/String;ILandroid/os/CancellationSignal;)V+]Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteConnectionPool;
 HSPLandroid/database/sqlite/SQLiteSession;->beginTransaction(ILandroid/database/sqlite/SQLiteTransactionListener;ILandroid/os/CancellationSignal;)V
 HSPLandroid/database/sqlite/SQLiteSession;->beginTransactionUnchecked(ILandroid/database/sqlite/SQLiteTransactionListener;ILandroid/os/CancellationSignal;)V
 HSPLandroid/database/sqlite/SQLiteSession;->closeOpenDependents()V+]Ljava/util/ArrayDeque;Ljava/util/ArrayDeque;
 HSPLandroid/database/sqlite/SQLiteSession;->endTransaction(Landroid/os/CancellationSignal;)V
 HSPLandroid/database/sqlite/SQLiteSession;->endTransactionUnchecked(Landroid/os/CancellationSignal;Z)V
-HSPLandroid/database/sqlite/SQLiteSession;->execute(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)V
-HSPLandroid/database/sqlite/SQLiteSession;->executeForChangedRowCount(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)I
-HSPLandroid/database/sqlite/SQLiteSession;->executeForCursorWindow(Ljava/lang/String;[Ljava/lang/Object;Landroid/database/CursorWindow;IIZILandroid/os/CancellationSignal;)I
+HSPLandroid/database/sqlite/SQLiteSession;->execute(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteSession;->executeForChangedRowCount(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)I+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
+HSPLandroid/database/sqlite/SQLiteSession;->executeForCursorWindow(Ljava/lang/String;[Ljava/lang/Object;Landroid/database/CursorWindow;IIZILandroid/os/CancellationSignal;)I+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;
 HSPLandroid/database/sqlite/SQLiteSession;->executeForLastInsertedRowId(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)J
 HSPLandroid/database/sqlite/SQLiteSession;->executeForLong(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)J
 HSPLandroid/database/sqlite/SQLiteSession;->executeForString(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)Ljava/lang/String;
-HSPLandroid/database/sqlite/SQLiteSession;->executeSpecial(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)Z
+HSPLandroid/database/sqlite/SQLiteSession;->executeSpecial(Ljava/lang/String;[Ljava/lang/Object;ILandroid/os/CancellationSignal;)Z+]Landroid/os/CancellationSignal;Landroid/os/CancellationSignal;
 HSPLandroid/database/sqlite/SQLiteSession;->hasNestedTransaction()Z
 HSPLandroid/database/sqlite/SQLiteSession;->hasTransaction()Z
 HSPLandroid/database/sqlite/SQLiteSession;->obtainTransaction(ILandroid/database/sqlite/SQLiteTransactionListener;)Landroid/database/sqlite/SQLiteSession$Transaction;
-HSPLandroid/database/sqlite/SQLiteSession;->prepare(Ljava/lang/String;ILandroid/os/CancellationSignal;Landroid/database/sqlite/SQLiteStatementInfo;)V
+HSPLandroid/database/sqlite/SQLiteSession;->prepare(Ljava/lang/String;ILandroid/os/CancellationSignal;Landroid/database/sqlite/SQLiteStatementInfo;)V+]Landroid/database/sqlite/SQLiteConnection;Landroid/database/sqlite/SQLiteConnection;]Landroid/os/CancellationSignal;Landroid/os/CancellationSignal;
 HSPLandroid/database/sqlite/SQLiteSession;->recycleTransaction(Landroid/database/sqlite/SQLiteSession$Transaction;)V
-HSPLandroid/database/sqlite/SQLiteSession;->releaseConnection()V
+HSPLandroid/database/sqlite/SQLiteSession;->releaseConnection()V+]Landroid/database/sqlite/SQLiteConnectionPool;Landroid/database/sqlite/SQLiteConnectionPool;
 HSPLandroid/database/sqlite/SQLiteSession;->setTransactionSuccessful()V
 HSPLandroid/database/sqlite/SQLiteSession;->throwIfNestedTransaction()V
 HSPLandroid/database/sqlite/SQLiteSession;->throwIfNoTransaction()V
@@ -5933,7 +5960,7 @@
 HSPLandroid/database/sqlite/SQLiteStatement;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;[Ljava/lang/Object;)V
 HSPLandroid/database/sqlite/SQLiteStatement;->execute()V+]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/sqlite/SQLiteStatement;Landroid/database/sqlite/SQLiteStatement;
 HSPLandroid/database/sqlite/SQLiteStatement;->executeInsert()J
-HSPLandroid/database/sqlite/SQLiteStatement;->executeUpdateDelete()I
+HSPLandroid/database/sqlite/SQLiteStatement;->executeUpdateDelete()I+]Landroid/database/sqlite/SQLiteSession;Landroid/database/sqlite/SQLiteSession;]Landroid/database/sqlite/SQLiteStatement;Landroid/database/sqlite/SQLiteStatement;
 HSPLandroid/database/sqlite/SQLiteStatement;->simpleQueryForLong()J
 HSPLandroid/database/sqlite/SQLiteStatement;->simpleQueryForString()Ljava/lang/String;
 HSPLandroid/database/sqlite/SQLiteStatementInfo;-><init>()V
@@ -5968,33 +5995,33 @@
 HSPLandroid/graphics/BaseCanvas;->drawBitmap(Landroid/graphics/Bitmap;Landroid/graphics/Rect;Landroid/graphics/RectF;Landroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseCanvas;->drawColor(I)V
 HSPLandroid/graphics/BaseCanvas;->drawLine(FFFFLandroid/graphics/Paint;)V
-HSPLandroid/graphics/BaseCanvas;->drawPath(Landroid/graphics/Path;Landroid/graphics/Paint;)V+]Landroid/graphics/Path;Landroid/graphics/Path;
+HSPLandroid/graphics/BaseCanvas;->drawPath(Landroid/graphics/Path;Landroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseCanvas;->drawText(Ljava/lang/CharSequence;IIFFLandroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseCanvas;->drawTextRun(Ljava/lang/CharSequence;IIIIFFZLandroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseCanvas;->throwIfCannotDraw(Landroid/graphics/Bitmap;)V
-HSPLandroid/graphics/BaseCanvas;->throwIfHasHwFeaturesInSwMode(Landroid/graphics/Paint;)V+]Landroid/graphics/BaseCanvas;Landroid/graphics/Canvas;
+HSPLandroid/graphics/BaseCanvas;->throwIfHasHwFeaturesInSwMode(Landroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseCanvas;->throwIfHasHwFeaturesInSwMode(Landroid/graphics/Shader;)V
 HSPLandroid/graphics/BaseCanvas;->throwIfHwBitmapInSwMode(Landroid/graphics/Bitmap;)V
 HSPLandroid/graphics/BaseRecordingCanvas;-><init>(J)V
-HSPLandroid/graphics/BaseRecordingCanvas;->drawArc(Landroid/graphics/RectF;FFZLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawArc(Landroid/graphics/RectF;FFZLandroid/graphics/Paint;)V+]Landroid/graphics/BaseRecordingCanvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/graphics/BaseRecordingCanvas;->drawBitmap(Landroid/graphics/Bitmap;FFLandroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawBitmap(Landroid/graphics/Bitmap;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Paint;)V
-HSPLandroid/graphics/BaseRecordingCanvas;->drawCircle(FFFLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawCircle(FFFLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;
 HSPLandroid/graphics/BaseRecordingCanvas;->drawColor(I)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawColor(ILandroid/graphics/PorterDuff$Mode;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawLine(FFFFLandroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawOval(FFFFLandroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawOval(Landroid/graphics/RectF;Landroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawPatch(Landroid/graphics/NinePatch;Landroid/graphics/Rect;Landroid/graphics/Paint;)V
-HSPLandroid/graphics/BaseRecordingCanvas;->drawPath(Landroid/graphics/Path;Landroid/graphics/Paint;)V+]Landroid/graphics/Paint;missing_types]Landroid/graphics/Path;Landroid/graphics/Path;
+HSPLandroid/graphics/BaseRecordingCanvas;->drawPath(Landroid/graphics/Path;Landroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/Path;Landroid/graphics/Path;
 HSPLandroid/graphics/BaseRecordingCanvas;->drawRect(FFFFLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;
 HSPLandroid/graphics/BaseRecordingCanvas;->drawRect(Landroid/graphics/Rect;Landroid/graphics/Paint;)V+]Landroid/graphics/BaseRecordingCanvas;Landroid/graphics/RecordingCanvas;
-HSPLandroid/graphics/BaseRecordingCanvas;->drawRect(Landroid/graphics/RectF;Landroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;
+HSPLandroid/graphics/BaseRecordingCanvas;->drawRect(Landroid/graphics/RectF;Landroid/graphics/Paint;)V
 HSPLandroid/graphics/BaseRecordingCanvas;->drawRoundRect(FFFFFFLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;
-HSPLandroid/graphics/BaseRecordingCanvas;->drawRoundRect(Landroid/graphics/RectF;FFLandroid/graphics/Paint;)V+]Landroid/graphics/BaseRecordingCanvas;Landroid/graphics/RecordingCanvas;
-HSPLandroid/graphics/BaseRecordingCanvas;->drawText(Ljava/lang/CharSequence;IIFFLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawRoundRect(Landroid/graphics/RectF;FFLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawText(Ljava/lang/CharSequence;IIFFLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/Layout$Ellipsizer;
 HSPLandroid/graphics/BaseRecordingCanvas;->drawText(Ljava/lang/String;FFLandroid/graphics/Paint;)V
-HSPLandroid/graphics/BaseRecordingCanvas;->drawTextRun(Ljava/lang/CharSequence;IIIIFFZLandroid/graphics/Paint;)V
+HSPLandroid/graphics/BaseRecordingCanvas;->drawTextRun(Ljava/lang/CharSequence;IIIIFFZLandroid/graphics/Paint;)V+]Landroid/graphics/Paint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Landroid/text/SpannableString;
 HSPLandroid/graphics/BaseRecordingCanvas;->drawTextRun([CIIIIFFZLandroid/graphics/Paint;)V
 HSPLandroid/graphics/Bitmap$1;->createFromParcel(Landroid/os/Parcel;)Landroid/graphics/Bitmap;
 HSPLandroid/graphics/Bitmap$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -6075,7 +6102,7 @@
 HSPLandroid/graphics/BitmapShader;-><init>(Landroid/graphics/Bitmap;Landroid/graphics/Shader$TileMode;Landroid/graphics/Shader$TileMode;)V
 HSPLandroid/graphics/BitmapShader;->createNativeInstance(JZ)J
 HSPLandroid/graphics/BitmapShader;->shouldDiscardNativeInstance(Z)Z
-HSPLandroid/graphics/BlendMode;->blendModeToPorterDuffMode(Landroid/graphics/BlendMode;)Landroid/graphics/PorterDuff$Mode;+]Landroid/graphics/BlendMode;Landroid/graphics/BlendMode;
+HSPLandroid/graphics/BlendMode;->blendModeToPorterDuffMode(Landroid/graphics/BlendMode;)Landroid/graphics/PorterDuff$Mode;
 HSPLandroid/graphics/BlendMode;->fromValue(I)Landroid/graphics/BlendMode;
 HSPLandroid/graphics/BlendMode;->getXfermode()Landroid/graphics/Xfermode;
 HSPLandroid/graphics/BlendMode;->toValue(Landroid/graphics/BlendMode;)I
@@ -6139,8 +6166,8 @@
 HSPLandroid/graphics/Canvas;->save()I
 HSPLandroid/graphics/Canvas;->save(I)I
 HSPLandroid/graphics/Canvas;->saveLayer(FFFFLandroid/graphics/Paint;I)I
-HSPLandroid/graphics/Canvas;->saveLayer(Landroid/graphics/RectF;Landroid/graphics/Paint;)I+]Landroid/graphics/Canvas;Landroid/graphics/Canvas;,Landroid/graphics/RecordingCanvas;
-HSPLandroid/graphics/Canvas;->saveLayer(Landroid/graphics/RectF;Landroid/graphics/Paint;I)I+]Landroid/graphics/Canvas;Landroid/graphics/Canvas;,Landroid/graphics/RecordingCanvas;
+HSPLandroid/graphics/Canvas;->saveLayer(Landroid/graphics/RectF;Landroid/graphics/Paint;)I
+HSPLandroid/graphics/Canvas;->saveLayer(Landroid/graphics/RectF;Landroid/graphics/Paint;I)I
 HSPLandroid/graphics/Canvas;->saveLayerAlpha(FFFFI)I
 HSPLandroid/graphics/Canvas;->saveLayerAlpha(FFFFII)I
 HSPLandroid/graphics/Canvas;->saveUnclippedLayer(IIII)I
@@ -6173,7 +6200,7 @@
 HSPLandroid/graphics/Color;->green(I)I
 HSPLandroid/graphics/Color;->green(J)F
 HSPLandroid/graphics/Color;->luminance()F
-HSPLandroid/graphics/Color;->pack(FFFFLandroid/graphics/ColorSpace;)J+]Landroid/graphics/ColorSpace;Landroid/graphics/ColorSpace$Rgb;
+HSPLandroid/graphics/Color;->pack(FFFFLandroid/graphics/ColorSpace;)J
 HSPLandroid/graphics/Color;->pack(I)J
 HSPLandroid/graphics/Color;->parseColor(Ljava/lang/String;)I
 HSPLandroid/graphics/Color;->red()F
@@ -6299,8 +6326,8 @@
 HSPLandroid/graphics/HardwareRendererObserver$$ExternalSyntheticLambda0;->run()V
 HSPLandroid/graphics/HardwareRendererObserver;-><init>(Landroid/graphics/HardwareRendererObserver$OnFrameMetricsAvailableListener;[JLandroid/os/Handler;Z)V
 HSPLandroid/graphics/HardwareRendererObserver;->getNativeInstance()J
-HSPLandroid/graphics/HardwareRendererObserver;->invokeDataAvailable(Ljava/lang/ref/WeakReference;)Z
-HSPLandroid/graphics/HardwareRendererObserver;->notifyDataAvailable()V
+HSPLandroid/graphics/HardwareRendererObserver;->invokeDataAvailable(Ljava/lang/ref/WeakReference;)Z+]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/graphics/HardwareRendererObserver;->notifyDataAvailable()V+]Landroid/os/Handler;Landroid/os/Handler;,Landroid/view/ViewRootImpl$ViewRootHandler;
 HSPLandroid/graphics/ImageDecoder$AssetInputStreamSource;-><init>(Landroid/content/res/AssetManager$AssetInputStream;Landroid/content/res/Resources;Landroid/util/TypedValue;)V
 HSPLandroid/graphics/ImageDecoder$AssetInputStreamSource;->createImageDecoder(Z)Landroid/graphics/ImageDecoder;
 HSPLandroid/graphics/ImageDecoder$AssetInputStreamSource;->getDensity()I
@@ -6365,18 +6392,18 @@
 HSPLandroid/graphics/LinearGradient;-><init>(FFFFIILandroid/graphics/Shader$TileMode;)V
 HSPLandroid/graphics/LinearGradient;-><init>(FFFFJJLandroid/graphics/Shader$TileMode;)V
 HSPLandroid/graphics/LinearGradient;-><init>(FFFF[I[FLandroid/graphics/Shader$TileMode;)V
-HSPLandroid/graphics/LinearGradient;-><init>(FFFF[J[FLandroid/graphics/Shader$TileMode;)V
+HSPLandroid/graphics/LinearGradient;-><init>(FFFF[J[FLandroid/graphics/Shader$TileMode;)V+][J[J
 HSPLandroid/graphics/LinearGradient;-><init>(FFFF[J[FLandroid/graphics/Shader$TileMode;Landroid/graphics/ColorSpace;)V
-HSPLandroid/graphics/LinearGradient;->createNativeInstance(JZ)J+]Landroid/graphics/ColorSpace;Landroid/graphics/ColorSpace$Rgb;]Landroid/graphics/LinearGradient;Landroid/graphics/LinearGradient;
+HSPLandroid/graphics/LinearGradient;->createNativeInstance(JZ)J
 HSPLandroid/graphics/MaskFilter;->finalize()V
 HSPLandroid/graphics/Matrix;-><init>()V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
-HSPLandroid/graphics/Matrix;-><init>(Landroid/graphics/Matrix;)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/Matrix;-><init>(Landroid/graphics/Matrix;)V
 HSPLandroid/graphics/Matrix;->checkPointArrays([FI[FII)V
 HSPLandroid/graphics/Matrix;->equals(Ljava/lang/Object;)Z
 HSPLandroid/graphics/Matrix;->getValues([F)V
 HSPLandroid/graphics/Matrix;->invert(Landroid/graphics/Matrix;)Z
 HSPLandroid/graphics/Matrix;->isIdentity()Z
-HSPLandroid/graphics/Matrix;->mapPoints([F)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
+HSPLandroid/graphics/Matrix;->mapPoints([F)V
 HSPLandroid/graphics/Matrix;->mapPoints([FI[FII)V
 HSPLandroid/graphics/Matrix;->mapRect(Landroid/graphics/RectF;)Z+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
 HSPLandroid/graphics/Matrix;->mapRect(Landroid/graphics/RectF;Landroid/graphics/RectF;)Z
@@ -6414,18 +6441,18 @@
 HSPLandroid/graphics/Outline;->isEmpty()Z
 HSPLandroid/graphics/Outline;->setAlpha(F)V
 HSPLandroid/graphics/Outline;->setConvexPath(Landroid/graphics/Path;)V
-HSPLandroid/graphics/Outline;->setEmpty()V+]Landroid/graphics/Path;Landroid/graphics/Path;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/graphics/Outline;->setEmpty()V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
 HSPLandroid/graphics/Outline;->setOval(IIII)V
 HSPLandroid/graphics/Outline;->setOval(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/Outline;->setPath(Landroid/graphics/Path;)V
-HSPLandroid/graphics/Outline;->setRect(IIII)V
+HSPLandroid/graphics/Outline;->setRect(IIII)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;
 HSPLandroid/graphics/Outline;->setRect(Landroid/graphics/Rect;)V
-HSPLandroid/graphics/Outline;->setRoundRect(IIIIF)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;]Landroid/graphics/Rect;Landroid/graphics/Rect;
-HSPLandroid/graphics/Outline;->setRoundRect(Landroid/graphics/Rect;F)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;
+HSPLandroid/graphics/Outline;->setRoundRect(IIIIF)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/Outline;Landroid/graphics/Outline;
+HSPLandroid/graphics/Outline;->setRoundRect(Landroid/graphics/Rect;F)V
 HSPLandroid/graphics/Paint$FontMetrics;-><init>()V
 HSPLandroid/graphics/Paint$FontMetricsInt;-><init>()V
 HSPLandroid/graphics/Paint;-><init>()V
-HSPLandroid/graphics/Paint;-><init>(I)V+]Landroid/graphics/Paint;missing_types]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/Paint;-><init>(I)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;,Landroid/text/TextPaint;]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
 HSPLandroid/graphics/Paint;-><init>(Landroid/graphics/Paint;)V
 HSPLandroid/graphics/Paint;->ascent()F
 HSPLandroid/graphics/Paint;->descent()F
@@ -6437,17 +6464,18 @@
 HSPLandroid/graphics/Paint;->getFontFeatureSettings()Ljava/lang/String;
 HSPLandroid/graphics/Paint;->getFontMetrics()Landroid/graphics/Paint$FontMetrics;
 HSPLandroid/graphics/Paint;->getFontMetrics(Landroid/graphics/Paint$FontMetrics;)F
-HSPLandroid/graphics/Paint;->getFontMetricsInt()Landroid/graphics/Paint$FontMetricsInt;
+HSPLandroid/graphics/Paint;->getFontMetricsInt()Landroid/graphics/Paint$FontMetricsInt;+]Landroid/graphics/Paint;Landroid/text/TextPaint;
 HSPLandroid/graphics/Paint;->getFontMetricsInt(Landroid/graphics/Paint$FontMetricsInt;)I
-HSPLandroid/graphics/Paint;->getFontMetricsInt(Ljava/lang/CharSequence;IIIIZLandroid/graphics/Paint$FontMetricsInt;)V+]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/graphics/Paint;->getFontMetricsInt(Ljava/lang/CharSequence;IIIIZLandroid/graphics/Paint$FontMetricsInt;)V
 HSPLandroid/graphics/Paint;->getFontVariationSettings()Ljava/lang/String;
 HSPLandroid/graphics/Paint;->getHinting()I
 HSPLandroid/graphics/Paint;->getLetterSpacing()F
 HSPLandroid/graphics/Paint;->getMaskFilter()Landroid/graphics/MaskFilter;
-HSPLandroid/graphics/Paint;->getNativeInstance()J+]Landroid/graphics/ColorFilter;Landroid/graphics/BlendModeColorFilter;,Landroid/graphics/PorterDuffColorFilter;]Landroid/graphics/Paint;missing_types]Landroid/graphics/Shader;Landroid/graphics/BitmapShader;,Landroid/graphics/LinearGradient;,Landroid/graphics/drawable/RippleShader;
+HSPLandroid/graphics/Paint;->getNativeInstance()J+]Landroid/graphics/ColorFilter;Landroid/graphics/PorterDuffColorFilter;,Landroid/graphics/BlendModeColorFilter;]Landroid/graphics/Paint;missing_types]Landroid/graphics/Shader;Landroid/graphics/LinearGradient;,Landroid/graphics/drawable/RippleShader;,Landroid/graphics/BitmapShader;,Landroid/graphics/RadialGradient;
 HSPLandroid/graphics/Paint;->getRunAdvance(Ljava/lang/CharSequence;IIIIZI)F
 HSPLandroid/graphics/Paint;->getRunAdvance([CIIIIZI)F
 HSPLandroid/graphics/Paint;->getRunCharacterAdvance(Ljava/lang/CharSequence;IIIIZI[FI)F
+HSPLandroid/graphics/Paint;->getRunCharacterAdvance(Ljava/lang/CharSequence;IIIIZI[FILandroid/graphics/RectF;Landroid/graphics/Paint$RunInfo;)F+]Landroid/graphics/Paint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;megamorphic_types
 HSPLandroid/graphics/Paint;->getRunCharacterAdvance([CIIIIZI[FI)F
 HSPLandroid/graphics/Paint;->getShader()Landroid/graphics/Shader;
 HSPLandroid/graphics/Paint;->getShadowLayerColor()I
@@ -6461,7 +6489,7 @@
 HSPLandroid/graphics/Paint;->getStrokeWidth()F
 HSPLandroid/graphics/Paint;->getStyle()Landroid/graphics/Paint$Style;
 HSPLandroid/graphics/Paint;->getTextAlign()Landroid/graphics/Paint$Align;
-HSPLandroid/graphics/Paint;->getTextBounds(Ljava/lang/CharSequence;IILandroid/graphics/Rect;)V
+HSPLandroid/graphics/Paint;->getTextBounds(Ljava/lang/CharSequence;IILandroid/graphics/Rect;)V+]Landroid/graphics/Paint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Landroid/text/SpannableString;
 HSPLandroid/graphics/Paint;->getTextBounds(Ljava/lang/String;IILandroid/graphics/Rect;)V
 HSPLandroid/graphics/Paint;->getTextBounds([CIILandroid/graphics/Rect;)V
 HSPLandroid/graphics/Paint;->getTextLocale()Ljava/util/Locale;
@@ -6507,7 +6535,7 @@
 HSPLandroid/graphics/Paint;->setPathEffect(Landroid/graphics/PathEffect;)Landroid/graphics/PathEffect;
 HSPLandroid/graphics/Paint;->setShader(Landroid/graphics/Shader;)Landroid/graphics/Shader;
 HSPLandroid/graphics/Paint;->setShadowLayer(FFFI)V
-HSPLandroid/graphics/Paint;->setShadowLayer(FFFJ)V+]Landroid/graphics/ColorSpace;Landroid/graphics/ColorSpace$Rgb;
+HSPLandroid/graphics/Paint;->setShadowLayer(FFFJ)V
 HSPLandroid/graphics/Paint;->setStartHyphenEdit(I)V
 HSPLandroid/graphics/Paint;->setStrokeCap(Landroid/graphics/Paint$Cap;)V
 HSPLandroid/graphics/Paint;->setStrokeJoin(Landroid/graphics/Paint$Join;)V
@@ -6522,9 +6550,9 @@
 HSPLandroid/graphics/Paint;->setTypeface(Landroid/graphics/Typeface;)Landroid/graphics/Typeface;
 HSPLandroid/graphics/Paint;->setUnderlineText(Z)V
 HSPLandroid/graphics/Paint;->setXfermode(Landroid/graphics/Xfermode;)Landroid/graphics/Xfermode;
-HSPLandroid/graphics/Paint;->syncTextLocalesWithMinikin()V+]Landroid/os/LocaleList;Landroid/os/LocaleList;]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/graphics/Paint;->syncTextLocalesWithMinikin()V+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Integer;Ljava/lang/Integer;]Landroid/os/LocaleList;Landroid/os/LocaleList;
 HSPLandroid/graphics/PaintFlagsDrawFilter;-><init>(II)V
-HSPLandroid/graphics/Path;-><init>()V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/Path;-><init>()V
 HSPLandroid/graphics/Path;-><init>(Landroid/graphics/Path;)V
 HSPLandroid/graphics/Path;->addArc(FFFFFF)V
 HSPLandroid/graphics/Path;->addArc(Landroid/graphics/RectF;FF)V
@@ -6533,7 +6561,7 @@
 HSPLandroid/graphics/Path;->addOval(Landroid/graphics/RectF;Landroid/graphics/Path$Direction;)V
 HSPLandroid/graphics/Path;->addPath(Landroid/graphics/Path;Landroid/graphics/Matrix;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
 HSPLandroid/graphics/Path;->addRect(FFFFLandroid/graphics/Path$Direction;)V
-HSPLandroid/graphics/Path;->addRect(Landroid/graphics/RectF;Landroid/graphics/Path$Direction;)V+]Landroid/graphics/Path;Landroid/graphics/Path;
+HSPLandroid/graphics/Path;->addRect(Landroid/graphics/RectF;Landroid/graphics/Path$Direction;)V
 HSPLandroid/graphics/Path;->addRoundRect(FFFFFFLandroid/graphics/Path$Direction;)V
 HSPLandroid/graphics/Path;->addRoundRect(FFFF[FLandroid/graphics/Path$Direction;)V
 HSPLandroid/graphics/Path;->addRoundRect(Landroid/graphics/RectF;FFLandroid/graphics/Path$Direction;)V
@@ -6551,8 +6579,8 @@
 HSPLandroid/graphics/Path;->lineTo(FF)V
 HSPLandroid/graphics/Path;->moveTo(FF)V
 HSPLandroid/graphics/Path;->offset(FF)V
-HSPLandroid/graphics/Path;->op(Landroid/graphics/Path;Landroid/graphics/Path$Op;)Z+]Landroid/graphics/Path;Landroid/graphics/Path;
-HSPLandroid/graphics/Path;->op(Landroid/graphics/Path;Landroid/graphics/Path;Landroid/graphics/Path$Op;)Z+]Landroid/graphics/Path$Op;Landroid/graphics/Path$Op;
+HSPLandroid/graphics/Path;->op(Landroid/graphics/Path;Landroid/graphics/Path$Op;)Z
+HSPLandroid/graphics/Path;->op(Landroid/graphics/Path;Landroid/graphics/Path;Landroid/graphics/Path$Op;)Z
 HSPLandroid/graphics/Path;->rLineTo(FF)V
 HSPLandroid/graphics/Path;->readOnlyNI()J
 HSPLandroid/graphics/Path;->reset()V+]Landroid/graphics/Path;Landroid/graphics/Path;
@@ -6592,7 +6620,7 @@
 HSPLandroid/graphics/PointF;-><init>()V
 HSPLandroid/graphics/PointF;-><init>(FF)V
 HSPLandroid/graphics/PointF;->equals(FF)Z
-HSPLandroid/graphics/PointF;->equals(Ljava/lang/Object;)Z+]Ljava/lang/Object;Landroid/graphics/PointF;
+HSPLandroid/graphics/PointF;->equals(Ljava/lang/Object;)Z
 HSPLandroid/graphics/PointF;->length()F
 HSPLandroid/graphics/PointF;->length(FF)F
 HSPLandroid/graphics/PointF;->set(FF)V
@@ -6619,8 +6647,8 @@
 HSPLandroid/graphics/RecordingCanvas;->obtain(Landroid/graphics/RenderNode;II)Landroid/graphics/RecordingCanvas;+]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
 HSPLandroid/graphics/RecordingCanvas;->recycle()V+]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
 HSPLandroid/graphics/RecordingCanvas;->throwIfCannotDraw(Landroid/graphics/Bitmap;)V
-HSPLandroid/graphics/Rect$1;->createFromParcel(Landroid/os/Parcel;)Landroid/graphics/Rect;+]Landroid/graphics/Rect;Landroid/graphics/Rect;
-HSPLandroid/graphics/Rect$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/graphics/Rect$1;Landroid/graphics/Rect$1;
+HSPLandroid/graphics/Rect$1;->createFromParcel(Landroid/os/Parcel;)Landroid/graphics/Rect;
+HSPLandroid/graphics/Rect$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/graphics/Rect$1;->newArray(I)[Landroid/graphics/Rect;
 HSPLandroid/graphics/Rect$1;->newArray(I)[Ljava/lang/Object;
 HSPLandroid/graphics/Rect;-><init>()V
@@ -6647,7 +6675,7 @@
 HSPLandroid/graphics/Rect;->isValid()Z
 HSPLandroid/graphics/Rect;->offset(II)V
 HSPLandroid/graphics/Rect;->offsetTo(II)V
-HSPLandroid/graphics/Rect;->readFromParcel(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/graphics/Rect;->readFromParcel(Landroid/os/Parcel;)V
 HSPLandroid/graphics/Rect;->scale(F)V
 HSPLandroid/graphics/Rect;->set(IIII)V
 HSPLandroid/graphics/Rect;->set(Landroid/graphics/Rect;)V
@@ -6656,7 +6684,7 @@
 HSPLandroid/graphics/Rect;->toShortString(Ljava/lang/StringBuilder;)Ljava/lang/String;
 HSPLandroid/graphics/Rect;->toString()Ljava/lang/String;
 HSPLandroid/graphics/Rect;->union(IIII)V
-HSPLandroid/graphics/Rect;->union(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/graphics/Rect;->union(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/Rect;->width()I
 HSPLandroid/graphics/Rect;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/graphics/RectF;-><init>()V
@@ -6710,7 +6738,7 @@
 HSPLandroid/graphics/RenderNode$PositionUpdateListener;->callPositionChanged(Ljava/lang/ref/WeakReference;JIIII)Z
 HSPLandroid/graphics/RenderNode$PositionUpdateListener;->callPositionLost(Ljava/lang/ref/WeakReference;J)Z
 HSPLandroid/graphics/RenderNode;-><init>(J)V
-HSPLandroid/graphics/RenderNode;-><init>(Ljava/lang/String;Landroid/graphics/RenderNode$AnimationHost;)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/RenderNode;-><init>(Ljava/lang/String;Landroid/graphics/RenderNode$AnimationHost;)V
 HSPLandroid/graphics/RenderNode;->addPositionUpdateListener(Landroid/graphics/RenderNode$PositionUpdateListener;)V
 HSPLandroid/graphics/RenderNode;->adopt(J)Landroid/graphics/RenderNode;
 HSPLandroid/graphics/RenderNode;->beginRecording(II)Landroid/graphics/RecordingCanvas;
@@ -6720,7 +6748,7 @@
 HSPLandroid/graphics/RenderNode;->endRecording()V+]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/graphics/RenderNode;->getClipToOutline()Z
 HSPLandroid/graphics/RenderNode;->getElevation()F
-HSPLandroid/graphics/RenderNode;->getMatrix(Landroid/graphics/Matrix;)V
+HSPLandroid/graphics/RenderNode;->getMatrix(Landroid/graphics/Matrix;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
 HSPLandroid/graphics/RenderNode;->getPivotY()F
 HSPLandroid/graphics/RenderNode;->getRotationX()F
 HSPLandroid/graphics/RenderNode;->getRotationY()F
@@ -6737,7 +6765,7 @@
 HSPLandroid/graphics/RenderNode;->removePositionUpdateListener(Landroid/graphics/RenderNode$PositionUpdateListener;)V
 HSPLandroid/graphics/RenderNode;->setAlpha(F)Z
 HSPLandroid/graphics/RenderNode;->setAmbientShadowColor(I)Z
-HSPLandroid/graphics/RenderNode;->setAnimationMatrix(Landroid/graphics/Matrix;)Z+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
+HSPLandroid/graphics/RenderNode;->setAnimationMatrix(Landroid/graphics/Matrix;)Z
 HSPLandroid/graphics/RenderNode;->setClipToBounds(Z)Z
 HSPLandroid/graphics/RenderNode;->setClipToOutline(Z)Z
 HSPLandroid/graphics/RenderNode;->setElevation(F)Z
@@ -6774,7 +6802,7 @@
 HSPLandroid/graphics/Shader;->discardNativeInstance()V
 HSPLandroid/graphics/Shader;->discardNativeInstanceLocked()V
 HSPLandroid/graphics/Shader;->getNativeInstance()J
-HSPLandroid/graphics/Shader;->getNativeInstance(Z)J+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/Shader;Landroid/graphics/BitmapShader;,Landroid/graphics/LinearGradient;,Landroid/graphics/drawable/RippleShader;]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/graphics/Shader;->getNativeInstance(Z)J
 HSPLandroid/graphics/Shader;->setLocalMatrix(Landroid/graphics/Matrix;)V
 HSPLandroid/graphics/Shader;->shouldDiscardNativeInstance(Z)Z
 HSPLandroid/graphics/SurfaceTexture$1;->handleMessage(Landroid/os/Message;)V
@@ -6792,7 +6820,7 @@
 HSPLandroid/graphics/TextureLayer;->close()V
 HSPLandroid/graphics/TextureLayer;->detachSurfaceTexture()V
 HSPLandroid/graphics/Typeface$Builder;->build()Landroid/graphics/Typeface;
-HSPLandroid/graphics/Typeface$Builder;->createAssetUid(Landroid/content/res/AssetManager;Ljava/lang/String;I[Landroid/graphics/fonts/FontVariationAxis;IILjava/lang/String;)Ljava/lang/String;+]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/graphics/Typeface$Builder;->createAssetUid(Landroid/content/res/AssetManager;Ljava/lang/String;I[Landroid/graphics/fonts/FontVariationAxis;IILjava/lang/String;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/content/res/AssetManager;Landroid/content/res/AssetManager;
 HSPLandroid/graphics/Typeface$CustomFallbackBuilder;-><init>(Landroid/graphics/fonts/FontFamily;)V
 HSPLandroid/graphics/Typeface$CustomFallbackBuilder;->build()Landroid/graphics/Typeface;
 HSPLandroid/graphics/Typeface$CustomFallbackBuilder;->setStyle(Landroid/graphics/fonts/FontStyle;)Landroid/graphics/Typeface$CustomFallbackBuilder;
@@ -6806,9 +6834,9 @@
 HSPLandroid/graphics/Typeface;->defaultFromStyle(I)Landroid/graphics/Typeface;
 HSPLandroid/graphics/Typeface;->deserializeFontMap(Ljava/nio/ByteBuffer;Ljava/util/Map;)[J
 HSPLandroid/graphics/Typeface;->equals(Ljava/lang/Object;)Z
-HSPLandroid/graphics/Typeface;->findFromCache(Landroid/content/res/AssetManager;Ljava/lang/String;)Landroid/graphics/Typeface;+]Landroid/util/LruCache;Landroid/util/LruCache;
+HSPLandroid/graphics/Typeface;->findFromCache(Landroid/content/res/AssetManager;Ljava/lang/String;)Landroid/graphics/Typeface;
 HSPLandroid/graphics/Typeface;->getStyle()I
-HSPLandroid/graphics/Typeface;->getSystemDefaultTypeface(Ljava/lang/String;)Landroid/graphics/Typeface;+]Ljava/util/Map;Landroid/util/ArrayMap;
+HSPLandroid/graphics/Typeface;->getSystemDefaultTypeface(Ljava/lang/String;)Landroid/graphics/Typeface;
 HSPLandroid/graphics/Typeface;->getSystemFontFamilyName()Ljava/lang/String;
 HSPLandroid/graphics/Typeface;->hasFontFamily(Ljava/lang/String;)Z
 HSPLandroid/graphics/Typeface;->readString(Ljava/nio/ByteBuffer;)Ljava/lang/String;
@@ -6917,7 +6945,7 @@
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable$2;->onAnimationStart(Landroid/animation/Animator;)V
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState$PendingAnimator;-><init>(IFLjava/lang/String;)V
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState$PendingAnimator;->newInstance(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;)Landroid/animation/Animator;
-HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;-><init>(Landroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;Landroid/graphics/drawable/Drawable$Callback;Landroid/content/res/Resources;)V
+HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;-><init>(Landroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;Landroid/graphics/drawable/Drawable$Callback;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/Drawable$ConstantState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;->addPendingAnimator(IFLjava/lang/String;)V
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;->addTargetAnimator(Ljava/lang/String;Landroid/animation/Animator;)V
 HSPLandroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;->canApplyTheme()Z
@@ -7071,7 +7099,7 @@
 HSPLandroid/graphics/drawable/ColorDrawable;-><init>(Landroid/graphics/drawable/ColorDrawable$ColorState;Landroid/content/res/Resources;Landroid/graphics/drawable/ColorDrawable-IA;)V
 HSPLandroid/graphics/drawable/ColorDrawable;->canApplyTheme()Z
 HSPLandroid/graphics/drawable/ColorDrawable;->clearMutated()V
-HSPLandroid/graphics/drawable/ColorDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/drawable/ColorDrawable;Landroid/graphics/drawable/ColorDrawable;
+HSPLandroid/graphics/drawable/ColorDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/drawable/ColorDrawable;Landroid/graphics/drawable/ColorDrawable;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/graphics/drawable/ColorDrawable;->getAlpha()I
 HSPLandroid/graphics/drawable/ColorDrawable;->getChangingConfigurations()I
 HSPLandroid/graphics/drawable/ColorDrawable;->getColor()I
@@ -7086,7 +7114,7 @@
 HSPLandroid/graphics/drawable/ColorDrawable;->setColor(I)V
 HSPLandroid/graphics/drawable/ColorDrawable;->setColorFilter(Landroid/graphics/ColorFilter;)V
 HSPLandroid/graphics/drawable/ColorDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
-HSPLandroid/graphics/drawable/ColorDrawable;->updateLocalState(Landroid/content/res/Resources;)V
+HSPLandroid/graphics/drawable/ColorDrawable;->updateLocalState(Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/ColorDrawable;Landroid/graphics/drawable/ColorDrawable;
 HSPLandroid/graphics/drawable/ColorDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/Drawable$ConstantState;-><init>()V
 HSPLandroid/graphics/drawable/Drawable$ConstantState;->canApplyTheme()Z
@@ -7097,7 +7125,7 @@
 HSPLandroid/graphics/drawable/Drawable;->canApplyTheme()Z
 HSPLandroid/graphics/drawable/Drawable;->clearColorFilter()V
 HSPLandroid/graphics/drawable/Drawable;->clearMutated()V
-HSPLandroid/graphics/drawable/Drawable;->copyBounds(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/graphics/drawable/Drawable;->copyBounds(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/drawable/Drawable;->createFromXmlForDensity(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;ILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/Drawable;->createFromXmlInner(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/Drawable;->createFromXmlInnerForDensity(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;ILandroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
@@ -7113,7 +7141,7 @@
 HSPLandroid/graphics/drawable/Drawable;->getLayoutDirection()I
 HSPLandroid/graphics/drawable/Drawable;->getLevel()I
 HSPLandroid/graphics/drawable/Drawable;->getMinimumHeight()I+]Landroid/graphics/drawable/Drawable;missing_types
-HSPLandroid/graphics/drawable/Drawable;->getMinimumWidth()I+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/ColorDrawable;,Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/graphics/drawable/Drawable;->getMinimumWidth()I+]Landroid/graphics/drawable/Drawable;missing_types
 HSPLandroid/graphics/drawable/Drawable;->getOutline(Landroid/graphics/Outline;)V
 HSPLandroid/graphics/drawable/Drawable;->getPadding(Landroid/graphics/Rect;)Z
 HSPLandroid/graphics/drawable/Drawable;->getState()[I
@@ -7130,13 +7158,13 @@
 HSPLandroid/graphics/drawable/Drawable;->onLevelChange(I)Z
 HSPLandroid/graphics/drawable/Drawable;->onStateChange([I)Z
 HSPLandroid/graphics/drawable/Drawable;->parseBlendMode(ILandroid/graphics/BlendMode;)Landroid/graphics/BlendMode;
-HSPLandroid/graphics/drawable/Drawable;->resolveDensity(Landroid/content/res/Resources;I)I+]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/graphics/drawable/Drawable;->resolveDensity(Landroid/content/res/Resources;I)I
 HSPLandroid/graphics/drawable/Drawable;->resolveOpacity(II)I
 HSPLandroid/graphics/drawable/Drawable;->scaleFromDensity(FII)F
 HSPLandroid/graphics/drawable/Drawable;->scaleFromDensity(IIIZ)I
 HSPLandroid/graphics/drawable/Drawable;->scheduleSelf(Ljava/lang/Runnable;J)V
 HSPLandroid/graphics/drawable/Drawable;->setAutoMirrored(Z)V
-HSPLandroid/graphics/drawable/Drawable;->setBounds(IIII)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/Drawable;->setBounds(IIII)V
 HSPLandroid/graphics/drawable/Drawable;->setBounds(Landroid/graphics/Rect;)V+]Landroid/graphics/drawable/Drawable;megamorphic_types
 HSPLandroid/graphics/drawable/Drawable;->setCallback(Landroid/graphics/drawable/Drawable$Callback;)V
 HSPLandroid/graphics/drawable/Drawable;->setChangingConfigurations(I)V
@@ -7146,20 +7174,20 @@
 HSPLandroid/graphics/drawable/Drawable;->setLayoutDirection(I)Z
 HSPLandroid/graphics/drawable/Drawable;->setLevel(I)Z
 HSPLandroid/graphics/drawable/Drawable;->setSrcDensityOverride(I)V
-HSPLandroid/graphics/drawable/Drawable;->setState([I)Z+]Landroid/graphics/drawable/Drawable;megamorphic_types
+HSPLandroid/graphics/drawable/Drawable;->setState([I)Z+]Landroid/graphics/drawable/Drawable;missing_types
 HSPLandroid/graphics/drawable/Drawable;->setTint(I)V
 HSPLandroid/graphics/drawable/Drawable;->setTintList(Landroid/content/res/ColorStateList;)V
 HSPLandroid/graphics/drawable/Drawable;->setTintMode(Landroid/graphics/PorterDuff$Mode;)V
-HSPLandroid/graphics/drawable/Drawable;->setVisible(ZZ)Z+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/Drawable;->setVisible(ZZ)Z
 HSPLandroid/graphics/drawable/Drawable;->unscheduleSelf(Ljava/lang/Runnable;)V
-HSPLandroid/graphics/drawable/Drawable;->updateBlendModeFilter(Landroid/graphics/BlendModeColorFilter;Landroid/content/res/ColorStateList;Landroid/graphics/BlendMode;)Landroid/graphics/BlendModeColorFilter;+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/BlendModeColorFilter;Landroid/graphics/BlendModeColorFilter;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;,Landroid/graphics/drawable/ShapeDrawable;,Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/graphics/drawable/Drawable;->updateBlendModeFilter(Landroid/graphics/BlendModeColorFilter;Landroid/content/res/ColorStateList;Landroid/graphics/BlendMode;)Landroid/graphics/BlendModeColorFilter;+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/BlendModeColorFilter;Landroid/graphics/BlendModeColorFilter;]Landroid/graphics/drawable/Drawable;megamorphic_types
 HSPLandroid/graphics/drawable/Drawable;->updateTintFilter(Landroid/graphics/PorterDuffColorFilter;Landroid/content/res/ColorStateList;Landroid/graphics/PorterDuff$Mode;)Landroid/graphics/PorterDuffColorFilter;
 HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;-><init>()V
 HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;-><init>(Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback-IA;)V
 HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;->unwrap()Landroid/graphics/drawable/Drawable$Callback;
 HSPLandroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;->wrap(Landroid/graphics/drawable/Drawable$Callback;)Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;
-HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;-><init>(Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;Landroid/graphics/drawable/DrawableContainer;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/Drawable;megamorphic_types]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;-><init>(Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;Landroid/graphics/drawable/DrawableContainer;Landroid/content/res/Resources;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/graphics/drawable/Drawable;megamorphic_types
 HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;->addChild(Landroid/graphics/drawable/Drawable;)I
 HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;->applyTheme(Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/DrawableContainer$DrawableContainerState;->canApplyTheme()Z
@@ -7202,11 +7230,11 @@
 HSPLandroid/graphics/drawable/DrawableContainer;->getOpticalInsets()Landroid/graphics/Insets;
 HSPLandroid/graphics/drawable/DrawableContainer;->getOutline(Landroid/graphics/Outline;)V
 HSPLandroid/graphics/drawable/DrawableContainer;->getPadding(Landroid/graphics/Rect;)Z
-HSPLandroid/graphics/drawable/DrawableContainer;->initializeDrawableForDisplay(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;]Landroid/graphics/drawable/DrawableContainer;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/StateListDrawable;,Lcom/android/internal/graphics/drawable/AnimationScaleListDrawable;
+HSPLandroid/graphics/drawable/DrawableContainer;->initializeDrawableForDisplay(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;Landroid/graphics/drawable/DrawableContainer$BlockInvalidateCallback;]Landroid/graphics/drawable/DrawableContainer;Landroid/graphics/drawable/AnimatedStateListDrawable;,Lcom/android/internal/graphics/drawable/AnimationScaleListDrawable;,Landroid/graphics/drawable/StateListDrawable;]Landroid/graphics/drawable/Drawable;megamorphic_types
 HSPLandroid/graphics/drawable/DrawableContainer;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/graphics/drawable/DrawableContainer;->isAutoMirrored()Z
 HSPLandroid/graphics/drawable/DrawableContainer;->isStateful()Z
-HSPLandroid/graphics/drawable/DrawableContainer;->jumpToCurrentState()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/DrawableContainer;->jumpToCurrentState()V
 HSPLandroid/graphics/drawable/DrawableContainer;->mutate()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/DrawableContainer;->needsMirroring()Z
 HSPLandroid/graphics/drawable/DrawableContainer;->onBoundsChange(Landroid/graphics/Rect;)V
@@ -7240,27 +7268,27 @@
 HSPLandroid/graphics/drawable/DrawableWrapper;->canApplyTheme()Z
 HSPLandroid/graphics/drawable/DrawableWrapper;->clearMutated()V
 HSPLandroid/graphics/drawable/DrawableWrapper;->draw(Landroid/graphics/Canvas;)V
-HSPLandroid/graphics/drawable/DrawableWrapper;->getChangingConfigurations()I+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;Landroid/graphics/drawable/InsetDrawable$InsetState;
+HSPLandroid/graphics/drawable/DrawableWrapper;->getChangingConfigurations()I
 HSPLandroid/graphics/drawable/DrawableWrapper;->getColorFilter()Landroid/graphics/ColorFilter;
 HSPLandroid/graphics/drawable/DrawableWrapper;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
 HSPLandroid/graphics/drawable/DrawableWrapper;->getDrawable()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/DrawableWrapper;->getIntrinsicHeight()I
 HSPLandroid/graphics/drawable/DrawableWrapper;->getIntrinsicWidth()I
 HSPLandroid/graphics/drawable/DrawableWrapper;->getOpacity()I
-HSPLandroid/graphics/drawable/DrawableWrapper;->getPadding(Landroid/graphics/Rect;)Z+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/DrawableWrapper;->getPadding(Landroid/graphics/Rect;)Z
 HSPLandroid/graphics/drawable/DrawableWrapper;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/DrawableWrapper;->inflateChildDrawable(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
-HSPLandroid/graphics/drawable/DrawableWrapper;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable$Callback;Landroid/graphics/drawable/RippleDrawable;]Landroid/graphics/drawable/DrawableWrapper;Landroid/graphics/drawable/InsetDrawable;
+HSPLandroid/graphics/drawable/DrawableWrapper;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/graphics/drawable/DrawableWrapper;->isStateful()Z
 HSPLandroid/graphics/drawable/DrawableWrapper;->jumpToCurrentState()V
 HSPLandroid/graphics/drawable/DrawableWrapper;->mutate()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/DrawableWrapper;->mutateConstantState()Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;
 HSPLandroid/graphics/drawable/DrawableWrapper;->onBoundsChange(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/drawable/DrawableWrapper;->onLevelChange(I)Z
-HSPLandroid/graphics/drawable/DrawableWrapper;->onStateChange([I)Z+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/DrawableWrapper;missing_types
+HSPLandroid/graphics/drawable/DrawableWrapper;->onStateChange([I)Z
 HSPLandroid/graphics/drawable/DrawableWrapper;->setAlpha(I)V
 HSPLandroid/graphics/drawable/DrawableWrapper;->setColorFilter(Landroid/graphics/ColorFilter;)V
-HSPLandroid/graphics/drawable/DrawableWrapper;->setDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/DrawableWrapper;missing_types
+HSPLandroid/graphics/drawable/DrawableWrapper;->setDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/graphics/drawable/DrawableWrapper;->setHotspot(FF)V
 HSPLandroid/graphics/drawable/DrawableWrapper;->setTintBlendMode(Landroid/graphics/BlendMode;)V
 HSPLandroid/graphics/drawable/DrawableWrapper;->setTintList(Landroid/content/res/ColorStateList;)V
@@ -7269,7 +7297,7 @@
 HSPLandroid/graphics/drawable/DrawableWrapper;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/GradientDrawable$GradientState;->-$$Nest$mcomputeOpacity(Landroid/graphics/drawable/GradientDrawable$GradientState;)V
 HSPLandroid/graphics/drawable/GradientDrawable$GradientState;-><init>(Landroid/graphics/drawable/GradientDrawable$GradientState;Landroid/content/res/Resources;)V
-HSPLandroid/graphics/drawable/GradientDrawable$GradientState;-><init>(Landroid/graphics/drawable/GradientDrawable$Orientation;[I)V
+HSPLandroid/graphics/drawable/GradientDrawable$GradientState;-><init>(Landroid/graphics/drawable/GradientDrawable$Orientation;[I)V+]Landroid/graphics/drawable/GradientDrawable$GradientState;Landroid/graphics/drawable/GradientDrawable$GradientState;
 HSPLandroid/graphics/drawable/GradientDrawable$GradientState;->applyDensityScaling(II)V
 HSPLandroid/graphics/drawable/GradientDrawable$GradientState;->canApplyTheme()Z
 HSPLandroid/graphics/drawable/GradientDrawable$GradientState;->computeOpacity()V
@@ -7290,8 +7318,8 @@
 HSPLandroid/graphics/drawable/GradientDrawable;->applyThemeChildElements(Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/GradientDrawable;->canApplyTheme()Z
 HSPLandroid/graphics/drawable/GradientDrawable;->clearMutated()V
-HSPLandroid/graphics/drawable/GradientDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Paint;Landroid/graphics/Paint;
-HSPLandroid/graphics/drawable/GradientDrawable;->ensureValidRect()Z+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/graphics/drawable/GradientDrawable;Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/graphics/drawable/GradientDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;,Landroid/graphics/Canvas;
+HSPLandroid/graphics/drawable/GradientDrawable;->ensureValidRect()Z
 HSPLandroid/graphics/drawable/GradientDrawable;->getChangingConfigurations()I
 HSPLandroid/graphics/drawable/GradientDrawable;->getColorFilter()Landroid/graphics/ColorFilter;
 HSPLandroid/graphics/drawable/GradientDrawable;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
@@ -7311,7 +7339,7 @@
 HSPLandroid/graphics/drawable/GradientDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/drawable/GradientDrawable;->onLevelChange(I)Z
 HSPLandroid/graphics/drawable/GradientDrawable;->onStateChange([I)Z
-HSPLandroid/graphics/drawable/GradientDrawable;->setAlpha(I)V
+HSPLandroid/graphics/drawable/GradientDrawable;->setAlpha(I)V+]Landroid/graphics/drawable/GradientDrawable;Landroid/graphics/drawable/GradientDrawable;
 HSPLandroid/graphics/drawable/GradientDrawable;->setColor(I)V
 HSPLandroid/graphics/drawable/GradientDrawable;->setColor(Landroid/content/res/ColorStateList;)V
 HSPLandroid/graphics/drawable/GradientDrawable;->setColorFilter(Landroid/graphics/ColorFilter;)V
@@ -7332,7 +7360,7 @@
 HSPLandroid/graphics/drawable/GradientDrawable;->updateGradientDrawableSize(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/GradientDrawable;->updateGradientDrawableSolid(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/GradientDrawable;->updateGradientDrawableStroke(Landroid/content/res/TypedArray;)V
-HSPLandroid/graphics/drawable/GradientDrawable;->updateLocalState(Landroid/content/res/Resources;)V+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/drawable/GradientDrawable;Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/graphics/drawable/GradientDrawable;->updateLocalState(Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/GradientDrawable;Landroid/graphics/drawable/GradientDrawable;]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/Paint;Landroid/graphics/Paint;
 HSPLandroid/graphics/drawable/GradientDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/Icon$1;->createFromParcel(Landroid/os/Parcel;)Landroid/graphics/drawable/Icon;
 HSPLandroid/graphics/drawable/Icon$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -7357,7 +7385,7 @@
 HSPLandroid/graphics/drawable/Icon;->setTint(I)Landroid/graphics/drawable/Icon;
 HSPLandroid/graphics/drawable/Icon;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/graphics/drawable/InsetDrawable$InsetState;->-$$Nest$fputmThemeAttrs(Landroid/graphics/drawable/InsetDrawable$InsetState;[I)V
-HSPLandroid/graphics/drawable/InsetDrawable$InsetState;-><init>(Landroid/graphics/drawable/InsetDrawable$InsetState;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/InsetDrawable$InsetValue;Landroid/graphics/drawable/InsetDrawable$InsetValue;
+HSPLandroid/graphics/drawable/InsetDrawable$InsetState;-><init>(Landroid/graphics/drawable/InsetDrawable$InsetState;Landroid/content/res/Resources;)V
 HSPLandroid/graphics/drawable/InsetDrawable$InsetState;->applyDensityScaling(II)V
 HSPLandroid/graphics/drawable/InsetDrawable$InsetState;->newDrawable(Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/InsetDrawable$InsetState;->onDensityChanged(II)V
@@ -7373,19 +7401,19 @@
 HSPLandroid/graphics/drawable/InsetDrawable;-><init>(Landroid/graphics/drawable/InsetDrawable$InsetState;Landroid/content/res/Resources;Landroid/graphics/drawable/InsetDrawable-IA;)V
 HSPLandroid/graphics/drawable/InsetDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/InsetDrawable;->getInset(Landroid/content/res/TypedArray;ILandroid/graphics/drawable/InsetDrawable$InsetValue;)Landroid/graphics/drawable/InsetDrawable$InsetValue;
-HSPLandroid/graphics/drawable/InsetDrawable;->getInsets(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/InsetDrawable$InsetValue;Landroid/graphics/drawable/InsetDrawable$InsetValue;]Landroid/graphics/drawable/InsetDrawable;missing_types
-HSPLandroid/graphics/drawable/InsetDrawable;->getIntrinsicHeight()I+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/InsetDrawable;missing_types
-HSPLandroid/graphics/drawable/InsetDrawable;->getIntrinsicWidth()I+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/InsetDrawable;missing_types
+HSPLandroid/graphics/drawable/InsetDrawable;->getInsets(Landroid/graphics/Rect;)V+]Landroid/graphics/drawable/InsetDrawable;Landroid/graphics/drawable/InsetDrawable;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/InsetDrawable$InsetValue;Landroid/graphics/drawable/InsetDrawable$InsetValue;
+HSPLandroid/graphics/drawable/InsetDrawable;->getIntrinsicHeight()I
+HSPLandroid/graphics/drawable/InsetDrawable;->getIntrinsicWidth()I
 HSPLandroid/graphics/drawable/InsetDrawable;->getOpacity()I
-HSPLandroid/graphics/drawable/InsetDrawable;->getOutline(Landroid/graphics/Outline;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/InsetDrawable;missing_types
+HSPLandroid/graphics/drawable/InsetDrawable;->getOutline(Landroid/graphics/Outline;)V
 HSPLandroid/graphics/drawable/InsetDrawable;->getPadding(Landroid/graphics/Rect;)Z
 HSPLandroid/graphics/drawable/InsetDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/InsetDrawable;->mutateConstantState()Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;
-HSPLandroid/graphics/drawable/InsetDrawable;->onBoundsChange(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/InsetDrawable$InsetValue;Landroid/graphics/drawable/InsetDrawable$InsetValue;
+HSPLandroid/graphics/drawable/InsetDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/drawable/InsetDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/InsetDrawable;->verifyRequiredAttributes(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;-><init>(I)V
-HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;-><init>(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;Landroid/graphics/drawable/LayerDrawable;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/Drawable$ConstantState;megamorphic_types]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;-><init>(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;Landroid/graphics/drawable/LayerDrawable;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/Drawable$ConstantState;missing_types]Landroid/graphics/drawable/Drawable;missing_types
 HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;->applyDensityScaling(II)V
 HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;->canApplyTheme()Z
 HSPLandroid/graphics/drawable/LayerDrawable$ChildDrawable;->setDensity(I)V
@@ -7405,11 +7433,11 @@
 HSPLandroid/graphics/drawable/LayerDrawable$LayerState;->onDensityChanged(II)V
 HSPLandroid/graphics/drawable/LayerDrawable$LayerState;->setDensity(I)V
 HSPLandroid/graphics/drawable/LayerDrawable;-><init>()V
-HSPLandroid/graphics/drawable/LayerDrawable;-><init>(Landroid/graphics/drawable/LayerDrawable$LayerState;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/LayerDrawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;-><init>(Landroid/graphics/drawable/LayerDrawable$LayerState;Landroid/content/res/Resources;)V
 HSPLandroid/graphics/drawable/LayerDrawable;-><init>([Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/graphics/drawable/LayerDrawable;-><init>([Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/LayerDrawable$LayerState;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->addLayer(Landroid/graphics/drawable/Drawable;[IIIIII)Landroid/graphics/drawable/LayerDrawable$ChildDrawable;+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/LayerDrawable;missing_types
-HSPLandroid/graphics/drawable/LayerDrawable;->addLayer(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;)I+]Landroid/graphics/drawable/LayerDrawable$LayerState;Landroid/graphics/drawable/RippleDrawable$RippleState;
+HSPLandroid/graphics/drawable/LayerDrawable;->addLayer(Landroid/graphics/drawable/Drawable;[IIIIII)Landroid/graphics/drawable/LayerDrawable$ChildDrawable;
+HSPLandroid/graphics/drawable/LayerDrawable;->addLayer(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;)I
 HSPLandroid/graphics/drawable/LayerDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/LayerDrawable;->canApplyTheme()Z
 HSPLandroid/graphics/drawable/LayerDrawable;->clearMutated()V
@@ -7423,23 +7451,23 @@
 HSPLandroid/graphics/drawable/LayerDrawable;->getChangingConfigurations()I
 HSPLandroid/graphics/drawable/LayerDrawable;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
 HSPLandroid/graphics/drawable/LayerDrawable;->getDrawable(I)Landroid/graphics/drawable/Drawable;
-HSPLandroid/graphics/drawable/LayerDrawable;->getIntrinsicHeight()I+]Landroid/graphics/drawable/Drawable;missing_types
-HSPLandroid/graphics/drawable/LayerDrawable;->getIntrinsicWidth()I+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/LayerDrawable;Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/LayerDrawable;->getIntrinsicHeight()I
+HSPLandroid/graphics/drawable/LayerDrawable;->getIntrinsicWidth()I
 HSPLandroid/graphics/drawable/LayerDrawable;->getNumberOfLayers()I
 HSPLandroid/graphics/drawable/LayerDrawable;->getOpacity()I
-HSPLandroid/graphics/drawable/LayerDrawable;->getOutline(Landroid/graphics/Outline;)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;
-HSPLandroid/graphics/drawable/LayerDrawable;->getPadding(Landroid/graphics/Rect;)Z+]Landroid/graphics/drawable/LayerDrawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->getOutline(Landroid/graphics/Outline;)V
+HSPLandroid/graphics/drawable/LayerDrawable;->getPadding(Landroid/graphics/Rect;)Z
 HSPLandroid/graphics/drawable/LayerDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/LayerDrawable;->inflateLayers(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/LayerDrawable$LayerState;Landroid/graphics/drawable/LayerDrawable$LayerState;,Landroid/graphics/drawable/RippleDrawable$RippleState;]Landroid/graphics/drawable/LayerDrawable;Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/LayerDrawable;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/graphics/drawable/LayerDrawable;->isAutoMirrored()Z
 HSPLandroid/graphics/drawable/LayerDrawable;->isProjected()Z
 HSPLandroid/graphics/drawable/LayerDrawable;->isStateful()Z
-HSPLandroid/graphics/drawable/LayerDrawable;->jumpToCurrentState()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->jumpToCurrentState()V
 HSPLandroid/graphics/drawable/LayerDrawable;->mutate()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/LayerDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->onStateChange([I)Z+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/LayerDrawable;Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;
-HSPLandroid/graphics/drawable/LayerDrawable;->refreshChildPadding(ILandroid/graphics/drawable/LayerDrawable$ChildDrawable;)Z+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->onStateChange([I)Z
+HSPLandroid/graphics/drawable/LayerDrawable;->refreshChildPadding(ILandroid/graphics/drawable/LayerDrawable$ChildDrawable;)Z
 HSPLandroid/graphics/drawable/LayerDrawable;->refreshPadding()V
 HSPLandroid/graphics/drawable/LayerDrawable;->resolveGravity(IIIII)I
 HSPLandroid/graphics/drawable/LayerDrawable;->resumeChildInvalidation()V
@@ -7455,10 +7483,10 @@
 HSPLandroid/graphics/drawable/LayerDrawable;->setPaddingMode(I)V
 HSPLandroid/graphics/drawable/LayerDrawable;->setTintBlendMode(Landroid/graphics/BlendMode;)V
 HSPLandroid/graphics/drawable/LayerDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->setVisible(ZZ)Z+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->setVisible(ZZ)Z
 HSPLandroid/graphics/drawable/LayerDrawable;->suspendChildInvalidation()V
 HSPLandroid/graphics/drawable/LayerDrawable;->updateLayerBounds(Landroid/graphics/Rect;)V
-HSPLandroid/graphics/drawable/LayerDrawable;->updateLayerBoundsInternal(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/graphics/drawable/LayerDrawable;missing_types
+HSPLandroid/graphics/drawable/LayerDrawable;->updateLayerBoundsInternal(Landroid/graphics/Rect;)V+]Landroid/graphics/drawable/LayerDrawable;Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;missing_types
 HSPLandroid/graphics/drawable/LayerDrawable;->updateLayerFromTypedArray(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/LayerDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/NinePatchDrawable$$ExternalSyntheticLambda0;->onHeaderDecoded(Landroid/graphics/ImageDecoder;Landroid/graphics/ImageDecoder$ImageInfo;Landroid/graphics/ImageDecoder$Source;)V
@@ -7555,12 +7583,12 @@
 HSPLandroid/graphics/drawable/RippleDrawable$RippleState;->newDrawable(Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/RippleDrawable$RippleState;->onDensityChanged(II)V
 HSPLandroid/graphics/drawable/RippleDrawable;-><init>()V
-HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/content/res/ColorStateList;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/RippleDrawable;missing_types
-HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/graphics/drawable/RippleDrawable$RippleState;Landroid/content/res/Resources;)V+]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/content/res/ColorStateList;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/graphics/drawable/RippleDrawable$RippleState;Landroid/content/res/Resources;)V
 HSPLandroid/graphics/drawable/RippleDrawable;-><init>(Landroid/graphics/drawable/RippleDrawable$RippleState;Landroid/content/res/Resources;Landroid/graphics/drawable/RippleDrawable-IA;)V
 HSPLandroid/graphics/drawable/RippleDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/RippleDrawable;->canApplyTheme()Z
-HSPLandroid/graphics/drawable/RippleDrawable;->cancelExitingRipples()V+]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/RippleDrawable;->cancelExitingRipples()V
 HSPLandroid/graphics/drawable/RippleDrawable;->clearHotspots()V
 HSPLandroid/graphics/drawable/RippleDrawable;->computeRadius()F
 HSPLandroid/graphics/drawable/RippleDrawable;->createAnimationProperties(FFFFFF)Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;
@@ -7569,27 +7597,27 @@
 HSPLandroid/graphics/drawable/RippleDrawable;->draw(Landroid/graphics/Canvas;)V
 HSPLandroid/graphics/drawable/RippleDrawable;->drawBackgroundAndRipples(Landroid/graphics/Canvas;)V
 HSPLandroid/graphics/drawable/RippleDrawable;->drawContent(Landroid/graphics/Canvas;)V
-HSPLandroid/graphics/drawable/RippleDrawable;->drawPatterned(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;]Landroid/graphics/drawable/RippleAnimationSession;Landroid/graphics/drawable/RippleAnimationSession;]Landroid/graphics/drawable/RippleDrawable;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/RippleDrawable;->drawPatterned(Landroid/graphics/Canvas;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/RippleAnimationSession;Landroid/graphics/drawable/RippleAnimationSession;
 HSPLandroid/graphics/drawable/RippleDrawable;->drawPatternedBackground(Landroid/graphics/Canvas;FF)V
 HSPLandroid/graphics/drawable/RippleDrawable;->exitPatternedAnimation()V
-HSPLandroid/graphics/drawable/RippleDrawable;->exitPatternedBackgroundAnimation()V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Landroid/graphics/drawable/RippleDrawable;missing_types
+HSPLandroid/graphics/drawable/RippleDrawable;->exitPatternedBackgroundAnimation()V
 HSPLandroid/graphics/drawable/RippleDrawable;->getComputedRadius()I
 HSPLandroid/graphics/drawable/RippleDrawable;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
-HSPLandroid/graphics/drawable/RippleDrawable;->getDirtyBounds()Landroid/graphics/Rect;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleDrawable;missing_types
+HSPLandroid/graphics/drawable/RippleDrawable;->getDirtyBounds()Landroid/graphics/Rect;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
 HSPLandroid/graphics/drawable/RippleDrawable;->getMaskType()I
 HSPLandroid/graphics/drawable/RippleDrawable;->getOpacity()I
 HSPLandroid/graphics/drawable/RippleDrawable;->getOutline(Landroid/graphics/Outline;)V+]Landroid/graphics/Outline;Landroid/graphics/Outline;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/InsetDrawable;,Landroid/graphics/drawable/StateListDrawable;
 HSPLandroid/graphics/drawable/RippleDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
-HSPLandroid/graphics/drawable/RippleDrawable;->invalidateSelf()V+]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/RippleDrawable;->invalidateSelf()V
 HSPLandroid/graphics/drawable/RippleDrawable;->invalidateSelf(Z)V
-HSPLandroid/graphics/drawable/RippleDrawable;->isBounded()Z+]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/graphics/drawable/RippleDrawable;->isBounded()Z
 HSPLandroid/graphics/drawable/RippleDrawable;->isProjected()Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;
 HSPLandroid/graphics/drawable/RippleDrawable;->isStateful()Z
 HSPLandroid/graphics/drawable/RippleDrawable;->jumpToCurrentState()V
 HSPLandroid/graphics/drawable/RippleDrawable;->mutate()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/RippleDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/drawable/RippleDrawable;->onHotspotBoundsChanged()V
-HSPLandroid/graphics/drawable/RippleDrawable;->onStateChange([I)Z+]Landroid/graphics/drawable/RippleDrawable;missing_types
+HSPLandroid/graphics/drawable/RippleDrawable;->onStateChange([I)Z
 HSPLandroid/graphics/drawable/RippleDrawable;->pruneRipples()V
 HSPLandroid/graphics/drawable/RippleDrawable;->setBackgroundActive(ZZZZ)V
 HSPLandroid/graphics/drawable/RippleDrawable;->setColor(Landroid/content/res/ColorStateList;)V
@@ -7598,11 +7626,11 @@
 HSPLandroid/graphics/drawable/RippleDrawable;->setPaddingMode(I)V
 HSPLandroid/graphics/drawable/RippleDrawable;->setRippleActive(Z)V
 HSPLandroid/graphics/drawable/RippleDrawable;->setVisible(ZZ)Z
-HSPLandroid/graphics/drawable/RippleDrawable;->startBackgroundAnimation()V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
+HSPLandroid/graphics/drawable/RippleDrawable;->startBackgroundAnimation()V
 HSPLandroid/graphics/drawable/RippleDrawable;->tryRippleEnter()V
 HSPLandroid/graphics/drawable/RippleDrawable;->updateLocalState()V
 HSPLandroid/graphics/drawable/RippleDrawable;->updateMaskShaderIfNeeded()V
-HSPLandroid/graphics/drawable/RippleDrawable;->updateRipplePaint()Landroid/graphics/Paint;+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/BitmapShader;Landroid/graphics/BitmapShader;]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/graphics/PorterDuffColorFilter;Landroid/graphics/PorterDuffColorFilter;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;Landroid/graphics/drawable/RippleAnimationSession$AnimationProperties;]Landroid/graphics/drawable/RippleAnimationSession;Landroid/graphics/drawable/RippleAnimationSession;]Landroid/graphics/drawable/RippleDrawable;Landroid/graphics/drawable/RippleDrawable;]Landroid/graphics/drawable/RippleShader;Landroid/graphics/drawable/RippleShader;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/RippleDrawable;->updateRipplePaint()Landroid/graphics/Paint;
 HSPLandroid/graphics/drawable/RippleDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/RippleDrawable;->verifyRequiredAttributes(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/RippleForeground$1;->onAnimationEnd(Landroid/animation/Animator;)V
@@ -7662,7 +7690,7 @@
 HSPLandroid/graphics/drawable/ScaleDrawable;->getPercent(Landroid/content/res/TypedArray;IF)F
 HSPLandroid/graphics/drawable/ScaleDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/ScaleDrawable;->mutateConstantState()Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;
-HSPLandroid/graphics/drawable/ScaleDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
+HSPLandroid/graphics/drawable/ScaleDrawable;->onBoundsChange(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/ScaleDrawable;Landroid/graphics/drawable/ScaleDrawable;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/StateListDrawable;
 HSPLandroid/graphics/drawable/ScaleDrawable;->onLevelChange(I)Z
 HSPLandroid/graphics/drawable/ScaleDrawable;->updateLocalState()V
 HSPLandroid/graphics/drawable/ScaleDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
@@ -7680,7 +7708,7 @@
 HSPLandroid/graphics/drawable/ShapeDrawable;->getOutline(Landroid/graphics/Outline;)V
 HSPLandroid/graphics/drawable/ShapeDrawable;->getPadding(Landroid/graphics/Rect;)Z
 HSPLandroid/graphics/drawable/ShapeDrawable;->getPaint()Landroid/graphics/Paint;
-HSPLandroid/graphics/drawable/ShapeDrawable;->isStateful()Z+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;
+HSPLandroid/graphics/drawable/ShapeDrawable;->isStateful()Z
 HSPLandroid/graphics/drawable/ShapeDrawable;->mutate()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/ShapeDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
 HSPLandroid/graphics/drawable/ShapeDrawable;->onDraw(Landroid/graphics/drawable/shapes/Shape;Landroid/graphics/Canvas;Landroid/graphics/Paint;)V
@@ -7690,7 +7718,7 @@
 HSPLandroid/graphics/drawable/ShapeDrawable;->setShape(Landroid/graphics/drawable/shapes/Shape;)V
 HSPLandroid/graphics/drawable/ShapeDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
 HSPLandroid/graphics/drawable/ShapeDrawable;->updateLocalState()V
-HSPLandroid/graphics/drawable/ShapeDrawable;->updateShape()V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/ShapeDrawable;Landroid/graphics/drawable/PaintDrawable;]Landroid/graphics/drawable/shapes/Shape;Landroid/graphics/drawable/shapes/OvalShape;,Landroid/graphics/drawable/shapes/RoundRectShape;
+HSPLandroid/graphics/drawable/ShapeDrawable;->updateShape()V
 HSPLandroid/graphics/drawable/StateListDrawable$StateListState;-><init>(Landroid/graphics/drawable/StateListDrawable$StateListState;Landroid/graphics/drawable/StateListDrawable;Landroid/content/res/Resources;)V
 HSPLandroid/graphics/drawable/StateListDrawable$StateListState;->addStateSet([ILandroid/graphics/drawable/Drawable;)I
 HSPLandroid/graphics/drawable/StateListDrawable$StateListState;->canApplyTheme()Z
@@ -7739,23 +7767,23 @@
 HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->getPropertyIndex(Ljava/lang/String;)I
 HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->inflate(Landroid/content/res/Resources;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->isStateful()Z
-HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->onStateChange([I)Z+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/drawable/VectorDrawable$VFullPath;Landroid/graphics/drawable/VectorDrawable$VFullPath;
-HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V+]Landroid/content/res/ComplexColor;Landroid/content/res/ColorStateList;,Landroid/content/res/GradientColor;]Landroid/content/res/GradientColor;Landroid/content/res/GradientColor;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/Shader;Landroid/graphics/LinearGradient;]Ljava/lang/String;Ljava/lang/String;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
+HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->onStateChange([I)Z
+HSPLandroid/graphics/drawable/VectorDrawable$VFullPath;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/content/res/ComplexColor;Landroid/content/res/ColorStateList;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->-$$Nest$fgetmChangingConfigurations(Landroid/graphics/drawable/VectorDrawable$VGroup;)I
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->-$$Nest$fgetmNativePtr(Landroid/graphics/drawable/VectorDrawable$VGroup;)J
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;-><init>()V
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;-><init>(Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/util/ArrayMap;)V+]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->addChild(Landroid/graphics/drawable/VectorDrawable$VObject;)V+]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VClipPath;,Landroid/graphics/drawable/VectorDrawable$VFullPath;,Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;-><init>(Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/util/ArrayMap;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->addChild(Landroid/graphics/drawable/VectorDrawable$VObject;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VGroup;,Landroid/graphics/drawable/VectorDrawable$VFullPath;
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->applyTheme(Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->canApplyTheme()Z
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getGroupName()Ljava/lang/String;
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getNativePtr()J
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getNativeSize()I+]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VClipPath;,Landroid/graphics/drawable/VectorDrawable$VFullPath;,Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getNativeSize()I
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->getProperty(Ljava/lang/String;)Landroid/util/Property;
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->inflate(Landroid/content/res/Resources;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->isStateful()Z
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->onStateChange([I)Z+]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VFullPath;,Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->setTree(Lcom/android/internal/util/VirtualRefBasePtr;)V+]Landroid/graphics/drawable/VectorDrawable$VObject;Landroid/graphics/drawable/VectorDrawable$VClipPath;,Landroid/graphics/drawable/VectorDrawable$VFullPath;,Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->onStateChange([I)Z
+HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->setTree(Lcom/android/internal/util/VirtualRefBasePtr;)V
 HSPLandroid/graphics/drawable/VectorDrawable$VGroup;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
 HSPLandroid/graphics/drawable/VectorDrawable$VObject;-><init>()V
 HSPLandroid/graphics/drawable/VectorDrawable$VObject;->isTreeValid()Z
@@ -7769,21 +7797,21 @@
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->applyDensityScaling(II)V
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->applyTheme(Landroid/content/res/Resources$Theme;)V
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->canApplyTheme()Z
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->canReuseCache()Z+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->canReuseCache()Z
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->createNativeTree(Landroid/graphics/drawable/VectorDrawable$VGroup;)V
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->createNativeTreeFromCopy(Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VGroup;)V+]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->createNativeTreeFromCopy(Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VGroup;)V
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->finalize()V
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getAlpha()F+]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getAlpha()F
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getChangingConfigurations()I
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getNativeRenderer()J+]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->isStateful()Z+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->getNativeRenderer()J
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->isStateful()Z
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->newDrawable()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->newDrawable(Landroid/content/res/Resources;)Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->onStateChange([I)Z
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->onTreeConstructionFinished()V+]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->onTreeConstructionFinished()V+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->setAlpha(F)Z
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->setDensity(I)Z
-HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->setViewportSize(FF)V+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->setViewportSize(FF)V
 HSPLandroid/graphics/drawable/VectorDrawable$VectorDrawableState;->updateCacheStates()V
 HSPLandroid/graphics/drawable/VectorDrawable;->-$$Nest$smnAddChild(JJ)V
 HSPLandroid/graphics/drawable/VectorDrawable;->-$$Nest$smnCreateFullPath()J
@@ -7806,37 +7834,37 @@
 HSPLandroid/graphics/drawable/VectorDrawable;-><init>()V
 HSPLandroid/graphics/drawable/VectorDrawable;-><init>(Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/content/res/Resources;)V
 HSPLandroid/graphics/drawable/VectorDrawable;-><init>(Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/content/res/Resources;Landroid/graphics/drawable/VectorDrawable-IA;)V
-HSPLandroid/graphics/drawable/VectorDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V
+HSPLandroid/graphics/drawable/VectorDrawable;->applyTheme(Landroid/content/res/Resources$Theme;)V+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
 HSPLandroid/graphics/drawable/VectorDrawable;->canApplyTheme()Z
 HSPLandroid/graphics/drawable/VectorDrawable;->clearMutated()V
 HSPLandroid/graphics/drawable/VectorDrawable;->computeVectorSize()V
-HSPLandroid/graphics/drawable/VectorDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/ColorFilter;Landroid/graphics/BlendModeColorFilter;,Landroid/graphics/PorterDuffColorFilter;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
-HSPLandroid/graphics/drawable/VectorDrawable;->getAlpha()I+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable;->draw(Landroid/graphics/Canvas;)V
+HSPLandroid/graphics/drawable/VectorDrawable;->getAlpha()I
 HSPLandroid/graphics/drawable/VectorDrawable;->getChangingConfigurations()I
 HSPLandroid/graphics/drawable/VectorDrawable;->getColorFilter()Landroid/graphics/ColorFilter;
 HSPLandroid/graphics/drawable/VectorDrawable;->getConstantState()Landroid/graphics/drawable/Drawable$ConstantState;
 HSPLandroid/graphics/drawable/VectorDrawable;->getIntrinsicHeight()I
-HSPLandroid/graphics/drawable/VectorDrawable;->getIntrinsicWidth()I+]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/graphics/drawable/VectorDrawable;->getIntrinsicWidth()I
 HSPLandroid/graphics/drawable/VectorDrawable;->getNativeTree()J
 HSPLandroid/graphics/drawable/VectorDrawable;->getOpacity()I
 HSPLandroid/graphics/drawable/VectorDrawable;->getPixelSize()F
 HSPLandroid/graphics/drawable/VectorDrawable;->getTargetByName(Ljava/lang/String;)Ljava/lang/Object;
-HSPLandroid/graphics/drawable/VectorDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
-HSPLandroid/graphics/drawable/VectorDrawable;->inflateChildElements(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/graphics/drawable/VectorDrawable$VClipPath;Landroid/graphics/drawable/VectorDrawable$VClipPath;]Landroid/graphics/drawable/VectorDrawable$VFullPath;Landroid/graphics/drawable/VectorDrawable$VFullPath;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Ljava/lang/Object;Ljava/lang/String;]Ljava/util/Stack;Ljava/util/Stack;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/graphics/drawable/VectorDrawable;->inflate(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;]Lcom/android/internal/util/VirtualRefBasePtr;Lcom/android/internal/util/VirtualRefBasePtr;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;
+HSPLandroid/graphics/drawable/VectorDrawable;->inflateChildElements(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/content/res/Resources$Theme;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;]Ljava/lang/Object;Ljava/lang/String;]Ljava/util/Stack;Ljava/util/Stack;]Landroid/graphics/drawable/VectorDrawable$VGroup;Landroid/graphics/drawable/VectorDrawable$VGroup;]Landroid/graphics/drawable/VectorDrawable$VFullPath;Landroid/graphics/drawable/VectorDrawable$VFullPath;
 HSPLandroid/graphics/drawable/VectorDrawable;->isAutoMirrored()Z
-HSPLandroid/graphics/drawable/VectorDrawable;->isStateful()Z+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable;->isStateful()Z
 HSPLandroid/graphics/drawable/VectorDrawable;->mutate()Landroid/graphics/drawable/Drawable;
 HSPLandroid/graphics/drawable/VectorDrawable;->needMirroring()Z
-HSPLandroid/graphics/drawable/VectorDrawable;->onStateChange([I)Z+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/graphics/drawable/VectorDrawable;->onStateChange([I)Z
 HSPLandroid/graphics/drawable/VectorDrawable;->setAllowCaching(Z)V
 HSPLandroid/graphics/drawable/VectorDrawable;->setAlpha(I)V
 HSPLandroid/graphics/drawable/VectorDrawable;->setAutoMirrored(Z)V
 HSPLandroid/graphics/drawable/VectorDrawable;->setColorFilter(Landroid/graphics/ColorFilter;)V
 HSPLandroid/graphics/drawable/VectorDrawable;->setTintBlendMode(Landroid/graphics/BlendMode;)V
-HSPLandroid/graphics/drawable/VectorDrawable;->setTintList(Landroid/content/res/ColorStateList;)V+]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
-HSPLandroid/graphics/drawable/VectorDrawable;->updateColorFilters(Landroid/graphics/BlendMode;Landroid/content/res/ColorStateList;)V+]Landroid/graphics/drawable/VectorDrawable;Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/graphics/drawable/VectorDrawable;->setTintList(Landroid/content/res/ColorStateList;)V
+HSPLandroid/graphics/drawable/VectorDrawable;->updateColorFilters(Landroid/graphics/BlendMode;Landroid/content/res/ColorStateList;)V
 HSPLandroid/graphics/drawable/VectorDrawable;->updateLocalState(Landroid/content/res/Resources;)V
-HSPLandroid/graphics/drawable/VectorDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;
+HSPLandroid/graphics/drawable/VectorDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V+]Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;Landroid/graphics/drawable/VectorDrawable$VectorDrawableState;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
 HSPLandroid/graphics/drawable/shapes/OvalShape;-><init>()V
 HSPLandroid/graphics/drawable/shapes/OvalShape;->draw(Landroid/graphics/Canvas;Landroid/graphics/Paint;)V
 HSPLandroid/graphics/drawable/shapes/OvalShape;->getOutline(Landroid/graphics/Outline;)V
@@ -7913,13 +7941,13 @@
 HSPLandroid/graphics/text/MeasuredText$Builder;-><init>([C)V
 HSPLandroid/graphics/text/MeasuredText$Builder;->appendReplacementRun(Landroid/graphics/Paint;IF)Landroid/graphics/text/MeasuredText$Builder;
 HSPLandroid/graphics/text/MeasuredText$Builder;->appendStyleRun(Landroid/graphics/Paint;IZ)Landroid/graphics/text/MeasuredText$Builder;
-HSPLandroid/graphics/text/MeasuredText$Builder;->appendStyleRun(Landroid/graphics/Paint;Landroid/graphics/text/LineBreakConfig;IZ)Landroid/graphics/text/MeasuredText$Builder;+]Landroid/graphics/Paint;Landroid/text/TextPaint;
+HSPLandroid/graphics/text/MeasuredText$Builder;->appendStyleRun(Landroid/graphics/Paint;Landroid/graphics/text/LineBreakConfig;IZ)Landroid/graphics/text/MeasuredText$Builder;
 HSPLandroid/graphics/text/MeasuredText$Builder;->build()Landroid/graphics/text/MeasuredText;
 HSPLandroid/graphics/text/MeasuredText$Builder;->ensureNativePtrNoReuse()V
 HSPLandroid/graphics/text/MeasuredText$Builder;->setComputeHyphenation(I)Landroid/graphics/text/MeasuredText$Builder;
 HSPLandroid/graphics/text/MeasuredText$Builder;->setComputeHyphenation(Z)Landroid/graphics/text/MeasuredText$Builder;
 HSPLandroid/graphics/text/MeasuredText$Builder;->setComputeLayout(Z)Landroid/graphics/text/MeasuredText$Builder;
-HSPLandroid/graphics/text/MeasuredText;->getCharWidthAt(I)F+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/graphics/text/MeasuredText;->getCharWidthAt(I)F
 HSPLandroid/graphics/text/MeasuredText;->getChars()[C
 HSPLandroid/graphics/text/MeasuredText;->getNativePtr()J
 HSPLandroid/hardware/Camera$CameraInfo;-><init>()V
@@ -7942,6 +7970,7 @@
 HSPLandroid/hardware/ICameraService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 HSPLandroid/hardware/ICameraService$Stub$Proxy;->addListener(Landroid/hardware/ICameraServiceListener;)[Landroid/hardware/CameraStatus;
 HSPLandroid/hardware/ICameraService$Stub$Proxy;->asBinder()Landroid/os/IBinder;
+HSPLandroid/hardware/ICameraService$Stub$Proxy;->getCameraCharacteristics(Ljava/lang/String;IZ)Landroid/hardware/camera2/impl/CameraMetadataNative;
 HSPLandroid/hardware/ICameraService$Stub$Proxy;->getConcurrentCameraIds()[Landroid/hardware/camera2/utils/ConcurrentCameraIdCombination;
 HSPLandroid/hardware/ICameraService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/ICameraService;
 HSPLandroid/hardware/ICameraServiceListener$Stub;->getMaxTransactionId()I
@@ -7989,7 +8018,7 @@
 HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;-><init>(Landroid/hardware/SensorEventListener;Landroid/os/Looper;Landroid/hardware/SystemSensorManager;Ljava/lang/String;)V
 HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->addSensorEvent(Landroid/hardware/Sensor;)V
 HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->dispatchAdditionalInfoEvent(III[F[I)V
-HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->dispatchSensorEvent(I[FIJ)V+]Landroid/hardware/Sensor;Landroid/hardware/Sensor;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->dispatchSensorEvent(I[FIJ)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Landroid/hardware/Sensor;Landroid/hardware/Sensor;]Landroid/util/SparseArray;Landroid/util/SparseArray;
 HSPLandroid/hardware/SystemSensorManager$SensorEventQueue;->removeSensorEvent(Landroid/hardware/Sensor;)V
 HSPLandroid/hardware/SystemSensorManager$TriggerEventQueue;->addSensorEvent(Landroid/hardware/Sensor;)V
 HSPLandroid/hardware/SystemSensorManager$TriggerEventQueue;->dispatchSensorEvent(I[FIJ)V
@@ -8024,11 +8053,19 @@
 HSPLandroid/hardware/camera2/CameraManager$AvailabilityCallback;-><init>()V
 HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
 HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal$1;->compare(Ljava/lang/String;Ljava/lang/String;)I
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal$3;-><init>(Landroid/hardware/camera2/CameraManager$CameraManagerGlobal;Landroid/hardware/camera2/CameraManager$AvailabilityCallback;)V
 HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->asBinder()Landroid/os/IBinder;
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->cameraIdHasConcurrentStreamsLocked(Ljava/lang/String;)Z
 HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->connectCameraServiceLocked()V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->extractCameraIdListLocked()[Ljava/lang/String;
 HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->get()Landroid/hardware/camera2/CameraManager$CameraManagerGlobal;
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->getCameraIdList()[Ljava/lang/String;
 HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->getCameraService()Landroid/hardware/ICameraService;
 HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onCameraAccessPrioritiesChanged()V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onStatusChanged(ILjava/lang/String;)V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onStatusChangedLocked(ILjava/lang/String;)V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onTorchStatusChanged(ILjava/lang/String;)V
+HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->onTorchStatusChangedLocked(ILjava/lang/String;)V
 HSPLandroid/hardware/camera2/CameraManager$CameraManagerGlobal;->postSingleAccessPriorityChangeUpdate(Landroid/hardware/camera2/CameraManager$AvailabilityCallback;Ljava/util/concurrent/Executor;)V
 HSPLandroid/hardware/camera2/CameraManager$FoldStateListener;->addDeviceStateListener(Landroid/hardware/camera2/CameraManager$DeviceStateListener;)V
 HSPLandroid/hardware/camera2/CameraManager$FoldStateListener;->handleStateChange(I)V
@@ -8038,6 +8075,7 @@
 HSPLandroid/hardware/camera2/CameraManager;->getDisplaySize()Landroid/util/Size;
 HSPLandroid/hardware/camera2/CameraManager;->getPhysicalCameraMultiResolutionConfigs(Ljava/lang/String;Landroid/hardware/camera2/impl/CameraMetadataNative;Landroid/hardware/ICameraService;)Ljava/util/Map;
 HSPLandroid/hardware/camera2/CameraManager;->registerDeviceStateListener(Landroid/hardware/camera2/CameraCharacteristics;)V
+HSPLandroid/hardware/camera2/CameraManager;->shouldOverrideToPortrait(Landroid/content/Context;)Z
 HSPLandroid/hardware/camera2/CameraMetadata;-><init>()V
 HSPLandroid/hardware/camera2/CameraMetadata;->setNativeInstance(Landroid/hardware/camera2/impl/CameraMetadataNative;)V
 HSPLandroid/hardware/camera2/impl/CameraDeviceImpl$CameraHandlerExecutor;->execute(Ljava/lang/Runnable;)V
@@ -8184,7 +8222,9 @@
 HSPLandroid/hardware/display/DisplayManagerGlobal$1;->recompute(Ljava/lang/Integer;)Landroid/view/DisplayInfo;
 HSPLandroid/hardware/display/DisplayManagerGlobal$1;->recompute(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayListenerDelegate$$ExternalSyntheticLambda0;->run()V
+HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayListenerDelegate;-><init>(Landroid/hardware/display/DisplayManager$DisplayListener;Ljava/util/concurrent/Executor;JLjava/lang/String;)V
 HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayListenerDelegate;->clearEvents()V
+HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayListenerDelegate;->handleDisplayEventInner(IILandroid/view/DisplayInfo;Z)V+]Landroid/view/DisplayInfo;Landroid/view/DisplayInfo;]Landroid/hardware/display/DisplayManager$DisplayListener;missing_types
 HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayManagerCallback;-><init>(Landroid/hardware/display/DisplayManagerGlobal;)V
 HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayManagerCallback;-><init>(Landroid/hardware/display/DisplayManagerGlobal;Landroid/hardware/display/DisplayManagerGlobal$DisplayManagerCallback-IA;)V
 HSPLandroid/hardware/display/DisplayManagerGlobal$DisplayManagerCallback;->onDisplayEvent(II)V
@@ -8205,6 +8245,7 @@
 HSPLandroid/hardware/display/DisplayManagerGlobal;->getStableDisplaySize()Landroid/graphics/Point;
 HSPLandroid/hardware/display/DisplayManagerGlobal;->getWifiDisplayStatus()Landroid/hardware/display/WifiDisplayStatus;
 HSPLandroid/hardware/display/DisplayManagerGlobal;->initExtraLogging()Z
+HSPLandroid/hardware/display/DisplayManagerGlobal;->maybeLogAllDisplayListeners()V
 HSPLandroid/hardware/display/DisplayManagerGlobal;->registerCallbackIfNeededLocked()V
 HSPLandroid/hardware/display/DisplayManagerGlobal;->registerDisplayListener(Landroid/hardware/display/DisplayManager$DisplayListener;Ljava/util/concurrent/Executor;JLjava/lang/String;)V+]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;
 HSPLandroid/hardware/display/DisplayManagerGlobal;->registerNativeChoreographerForRefreshRateCallbacks()V
@@ -8324,7 +8365,7 @@
 HSPLandroid/hardware/location/NanoAppMessage;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/hardware/location/NanoAppState$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/location/NanoAppState;
 HSPLandroid/hardware/location/NanoAppState$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/hardware/location/NanoAppState;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/hardware/location/NanoAppState;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/hardware/location/NanoAppState;->getNanoAppId()J
 HSPLandroid/hardware/security/keymint/KeyParameter$1;-><init>()V
 HSPLandroid/hardware/security/keymint/KeyParameter$1;->createFromParcel(Landroid/os/Parcel;)Landroid/hardware/security/keymint/KeyParameter;
@@ -8437,7 +8478,7 @@
 HSPLandroid/icu/impl/FormattedStringBuilder;->fieldAt(I)Ljava/lang/Object;
 HSPLandroid/icu/impl/FormattedStringBuilder;->getCapacity()I
 HSPLandroid/icu/impl/FormattedStringBuilder;->insert(ILjava/lang/CharSequence;IILjava/lang/Object;)I
-HSPLandroid/icu/impl/FormattedStringBuilder;->insert(ILjava/lang/CharSequence;Ljava/lang/Object;)I
+HSPLandroid/icu/impl/FormattedStringBuilder;->insert(ILjava/lang/CharSequence;Ljava/lang/Object;)I+]Ljava/lang/CharSequence;Ljava/lang/String;
 HSPLandroid/icu/impl/FormattedStringBuilder;->insert(I[C[Ljava/lang/Object;)I
 HSPLandroid/icu/impl/FormattedStringBuilder;->insertCodePoint(IILjava/lang/Object;)I
 HSPLandroid/icu/impl/FormattedStringBuilder;->length()I
@@ -8448,7 +8489,7 @@
 HSPLandroid/icu/impl/FormattedStringBuilder;->toString()Ljava/lang/String;
 HSPLandroid/icu/impl/FormattedStringBuilder;->unwrapField(Ljava/lang/Object;)Ljava/text/Format$Field;
 HSPLandroid/icu/impl/FormattedValueStringBuilderImpl;->isIntOrGroup(Ljava/lang/Object;)Z
-HSPLandroid/icu/impl/FormattedValueStringBuilderImpl;->nextFieldPosition(Landroid/icu/impl/FormattedStringBuilder;Ljava/text/FieldPosition;)Z
+HSPLandroid/icu/impl/FormattedValueStringBuilderImpl;->nextFieldPosition(Landroid/icu/impl/FormattedStringBuilder;Ljava/text/FieldPosition;)Z+]Landroid/icu/text/ConstrainedFieldPosition;Landroid/icu/text/ConstrainedFieldPosition;]Ljava/text/FieldPosition;Ljava/text/DontCareFieldPosition;
 HSPLandroid/icu/impl/FormattedValueStringBuilderImpl;->nextPosition(Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/text/ConstrainedFieldPosition;Ljava/text/Format$Field;)Z+]Landroid/icu/text/ConstrainedFieldPosition;Landroid/icu/text/ConstrainedFieldPosition;
 HSPLandroid/icu/impl/Grego;->dayOfWeek(J)I
 HSPLandroid/icu/impl/Grego;->dayToFields(J[I)[I
@@ -8469,7 +8510,7 @@
 HSPLandroid/icu/impl/ICUBinary$PackageDataFile;->getData(Ljava/lang/String;)Ljava/nio/ByteBuffer;
 HSPLandroid/icu/impl/ICUBinary;->addBaseNamesInFileFolder(Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;)V
 HSPLandroid/icu/impl/ICUBinary;->compareKeys(Ljava/lang/CharSequence;Ljava/nio/ByteBuffer;I)I
-HSPLandroid/icu/impl/ICUBinary;->compareKeys(Ljava/lang/CharSequence;[BI)I
+HSPLandroid/icu/impl/ICUBinary;->compareKeys(Ljava/lang/CharSequence;[BI)I+]Ljava/lang/CharSequence;Ljava/lang/String;
 HSPLandroid/icu/impl/ICUBinary;->getBytes(Ljava/nio/ByteBuffer;II)[B
 HSPLandroid/icu/impl/ICUBinary;->getChars(Ljava/nio/ByteBuffer;II)[C
 HSPLandroid/icu/impl/ICUBinary;->getData(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;)Ljava/nio/ByteBuffer;
@@ -8505,7 +8546,7 @@
 HSPLandroid/icu/impl/ICUCurrencyMetaInfo$UniqueList;->create()Landroid/icu/impl/ICUCurrencyMetaInfo$UniqueList;
 HSPLandroid/icu/impl/ICUCurrencyMetaInfo$UniqueList;->list()Ljava/util/List;
 HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->collect(Landroid/icu/impl/ICUCurrencyMetaInfo$Collector;Landroid/icu/text/CurrencyMetaInfo$CurrencyFilter;)Ljava/util/List;
-HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->collectRegion(Landroid/icu/impl/ICUCurrencyMetaInfo$Collector;Landroid/icu/text/CurrencyMetaInfo$CurrencyFilter;ILandroid/icu/impl/ICUResourceBundle;)V
+HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->collectRegion(Landroid/icu/impl/ICUCurrencyMetaInfo$Collector;Landroid/icu/text/CurrencyMetaInfo$CurrencyFilter;ILandroid/icu/impl/ICUResourceBundle;)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/ICUResourceBundle;Landroid/icu/impl/ICUResourceBundleImpl$ResourceString;,Landroid/icu/impl/ICUResourceBundleImpl$ResourceTable;,Landroid/icu/impl/ICUResourceBundleImpl$ResourceArray;]Landroid/icu/impl/ICUCurrencyMetaInfo$Collector;Landroid/icu/impl/ICUCurrencyMetaInfo$CurrencyCollector;
 HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->currencies(Landroid/icu/text/CurrencyMetaInfo$CurrencyFilter;)Ljava/util/List;
 HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->currencyDigits(Ljava/lang/String;Landroid/icu/util/Currency$CurrencyUsage;)Landroid/icu/text/CurrencyMetaInfo$CurrencyDigits;
 HSPLandroid/icu/impl/ICUCurrencyMetaInfo;->getDate(Landroid/icu/impl/ICUResourceBundle;JZ)J
@@ -8513,9 +8554,9 @@
 HSPLandroid/icu/impl/ICUData;->getStream(Ljava/lang/ClassLoader;Ljava/lang/String;Z)Ljava/io/InputStream;
 HSPLandroid/icu/impl/ICULocaleService$ICUResourceBundleFactory;->getSupportedIDs()Ljava/util/Set;
 HSPLandroid/icu/impl/ICULocaleService$ICUResourceBundleFactory;->loader()Ljava/lang/ClassLoader;
-HSPLandroid/icu/impl/ICULocaleService$LocaleKey;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V
+HSPLandroid/icu/impl/ICULocaleService$LocaleKey;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->createWithCanonical(Landroid/icu/util/ULocale;Ljava/lang/String;I)Landroid/icu/impl/ICULocaleService$LocaleKey;
-HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->currentDescriptor()Ljava/lang/String;
+HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->currentDescriptor()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/icu/impl/ICULocaleService$LocaleKey;Landroid/icu/impl/ICULocaleService$LocaleKey;
 HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->currentID()Ljava/lang/String;
 HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->currentLocale()Landroid/icu/util/ULocale;
 HSPLandroid/icu/impl/ICULocaleService$LocaleKey;->fallback()Z
@@ -8547,20 +8588,21 @@
 HSPLandroid/icu/impl/ICUResourceBundle$WholeBundle;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;Landroid/icu/impl/ICUResourceBundleReader;)V
 HSPLandroid/icu/impl/ICUResourceBundle;->-$$Nest$mgetNoFallback(Landroid/icu/impl/ICUResourceBundle;)Z
 HSPLandroid/icu/impl/ICUResourceBundle;->-$$Nest$sfgetDEBUG()Z
+HSPLandroid/icu/impl/ICUResourceBundle;->-$$Nest$smgetParentLocaleID(Ljava/lang/String;Ljava/lang/String;Landroid/icu/impl/ICUResourceBundle$OpenType;)Ljava/lang/String;
 HSPLandroid/icu/impl/ICUResourceBundle;->-$$Nest$sminstantiateBundle(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;Landroid/icu/impl/ICUResourceBundle$OpenType;)Landroid/icu/impl/ICUResourceBundle;
 HSPLandroid/icu/impl/ICUResourceBundle;-><init>(Landroid/icu/impl/ICUResourceBundle$WholeBundle;)V
 HSPLandroid/icu/impl/ICUResourceBundle;-><init>(Landroid/icu/impl/ICUResourceBundle;Ljava/lang/String;)V
 HSPLandroid/icu/impl/ICUResourceBundle;->addBundleBaseNamesFromClassLoader(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/util/Set;)V
 HSPLandroid/icu/impl/ICUResourceBundle;->at(I)Landroid/icu/impl/ICUResourceBundle;
 HSPLandroid/icu/impl/ICUResourceBundle;->at(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle;
-HSPLandroid/icu/impl/ICUResourceBundle;->countPathKeys(Ljava/lang/String;)I
+HSPLandroid/icu/impl/ICUResourceBundle;->countPathKeys(Ljava/lang/String;)I+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/icu/impl/ICUResourceBundle;->createBundle(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)Landroid/icu/impl/ICUResourceBundle;
 HSPLandroid/icu/impl/ICUResourceBundle;->createFullLocaleNameSet(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/util/Set;
 HSPLandroid/icu/impl/ICUResourceBundle;->equals(Ljava/lang/Object;)Z
 HSPLandroid/icu/impl/ICUResourceBundle;->findResourceWithFallback(Ljava/lang/String;Landroid/icu/util/UResourceBundle;Landroid/icu/util/UResourceBundle;)Landroid/icu/impl/ICUResourceBundle;
 HSPLandroid/icu/impl/ICUResourceBundle;->findResourceWithFallback([Ljava/lang/String;ILandroid/icu/impl/ICUResourceBundle;Landroid/icu/util/UResourceBundle;)Landroid/icu/impl/ICUResourceBundle;
 HSPLandroid/icu/impl/ICUResourceBundle;->findStringWithFallback(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/icu/impl/ICUResourceBundle;->findStringWithFallback(Ljava/lang/String;Landroid/icu/util/UResourceBundle;Landroid/icu/util/UResourceBundle;)Ljava/lang/String;
+HSPLandroid/icu/impl/ICUResourceBundle;->findStringWithFallback(Ljava/lang/String;Landroid/icu/util/UResourceBundle;Landroid/icu/util/UResourceBundle;)Ljava/lang/String;+]Landroid/icu/impl/ICUResourceBundleReader$Container;Landroid/icu/impl/ICUResourceBundleReader$Table;,Landroid/icu/impl/ICUResourceBundleReader$Table1632;,Landroid/icu/impl/ICUResourceBundleReader$Table16;]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/ICUResourceBundle;Landroid/icu/impl/ICUResourceBundleImpl$ResourceTable;]Landroid/icu/impl/ICUResourceBundleReader;Landroid/icu/impl/ICUResourceBundleReader;
 HSPLandroid/icu/impl/ICUResourceBundle;->findTopLevel(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle;
 HSPLandroid/icu/impl/ICUResourceBundle;->findTopLevel(Ljava/lang/String;)Landroid/icu/util/UResourceBundle;
 HSPLandroid/icu/impl/ICUResourceBundle;->findWithFallback(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle;
@@ -8593,7 +8635,7 @@
 HSPLandroid/icu/impl/ICUResourceBundle;->getStringWithFallback(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/icu/impl/ICUResourceBundle;->getULocale()Landroid/icu/util/ULocale;
 HSPLandroid/icu/impl/ICUResourceBundle;->getWithFallback(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle;
-HSPLandroid/icu/impl/ICUResourceBundle;->instantiateBundle(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;Landroid/icu/impl/ICUResourceBundle$OpenType;)Landroid/icu/impl/ICUResourceBundle;
+HSPLandroid/icu/impl/ICUResourceBundle;->instantiateBundle(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;Landroid/icu/impl/ICUResourceBundle$OpenType;)Landroid/icu/impl/ICUResourceBundle;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/icu/impl/ICUResourceBundle$OpenType;Landroid/icu/impl/ICUResourceBundle$OpenType;]Landroid/icu/impl/CacheBase;Landroid/icu/impl/ICUResourceBundle$1;
 HSPLandroid/icu/impl/ICUResourceBundle;->setParent(Ljava/util/ResourceBundle;)V
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceArray;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceArray;->getStringArray()[Ljava/lang/String;
@@ -8605,22 +8647,22 @@
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;-><init>(Landroid/icu/impl/ICUResourceBundle$WholeBundle;)V
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->createBundleObject(ILjava/lang/String;Ljava/util/HashMap;Landroid/icu/util/UResourceBundle;)Landroid/icu/util/UResourceBundle;
-HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->getContainerResource(I)I
+HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->getContainerResource(I)I+]Landroid/icu/impl/ICUResourceBundleReader$Container;Landroid/icu/impl/ICUResourceBundleReader$Table1632;,Landroid/icu/impl/ICUResourceBundleReader$Table16;
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->getSize()I
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceContainer;->getString(I)Ljava/lang/String;
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceInt;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceInt;->getInt()I
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceIntVector;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceIntVector;->getIntVector()[I
-HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceString;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
+HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceString;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/ICUResourceBundleReader;Landroid/icu/impl/ICUResourceBundleReader;
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceString;->getString()Ljava/lang/String;
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceString;->getType()I
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;-><init>(Landroid/icu/impl/ICUResourceBundle$WholeBundle;I)V
-HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
+HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V+]Landroid/icu/impl/ICUResourceBundleReader;Landroid/icu/impl/ICUResourceBundleReader;
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->findString(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->getType()I
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->handleGet(ILjava/util/HashMap;Landroid/icu/util/UResourceBundle;)Landroid/icu/util/UResourceBundle;
-HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->handleGet(Ljava/lang/String;Ljava/util/HashMap;Landroid/icu/util/UResourceBundle;)Landroid/icu/util/UResourceBundle;
+HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->handleGet(Ljava/lang/String;Ljava/util/HashMap;Landroid/icu/util/UResourceBundle;)Landroid/icu/util/UResourceBundle;+]Landroid/icu/impl/ICUResourceBundleImpl$ResourceTable;Landroid/icu/impl/ICUResourceBundleImpl$ResourceTable;]Landroid/icu/impl/ICUResourceBundleReader$Table;Landroid/icu/impl/ICUResourceBundleReader$Table;,Landroid/icu/impl/ICUResourceBundleReader$Table1632;,Landroid/icu/impl/ICUResourceBundleReader$Table16;
 HSPLandroid/icu/impl/ICUResourceBundleImpl$ResourceTable;->handleGetObject(Ljava/lang/String;)Ljava/lang/Object;
 HSPLandroid/icu/impl/ICUResourceBundleImpl;-><init>(Landroid/icu/impl/ICUResourceBundle$WholeBundle;)V
 HSPLandroid/icu/impl/ICUResourceBundleImpl;-><init>(Landroid/icu/impl/ICUResourceBundleImpl;Ljava/lang/String;I)V
@@ -8651,13 +8693,13 @@
 HSPLandroid/icu/impl/ICUResourceBundleReader$ReaderValue;->getStringArray(Landroid/icu/impl/ICUResourceBundleReader$Array;)[Ljava/lang/String;
 HSPLandroid/icu/impl/ICUResourceBundleReader$ReaderValue;->getTable()Landroid/icu/impl/UResource$Table;
 HSPLandroid/icu/impl/ICUResourceBundleReader$ReaderValue;->getType()I
-HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;->get(I)Ljava/lang/Object;
-HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;->putIfAbsent(ILjava/lang/Object;I)Ljava/lang/Object;
+HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;->get(I)Ljava/lang/Object;+]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;
+HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;->putIfAbsent(ILjava/lang/Object;I)Ljava/lang/Object;+]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;
 HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;-><init>(I)V
 HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->findSimple(I)I
-HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->get(I)Ljava/lang/Object;
+HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->get(I)Ljava/lang/Object;+]Ljava/lang/ref/SoftReference;Ljava/lang/ref/SoftReference;]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;
 HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->makeKey(I)I
-HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->putIfAbsent(ILjava/lang/Object;I)Ljava/lang/Object;
+HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->putIfAbsent(ILjava/lang/Object;I)Ljava/lang/Object;+]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache$Level;
 HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->putIfCleared([Ljava/lang/Object;ILjava/lang/Object;I)Ljava/lang/Object;
 HSPLandroid/icu/impl/ICUResourceBundleReader$ResourceCache;->storeDirectly(I)Z
 HSPLandroid/icu/impl/ICUResourceBundleReader$Table1632;-><init>(Landroid/icu/impl/ICUResourceBundleReader;I)V
@@ -8667,7 +8709,7 @@
 HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->findTableItem(Landroid/icu/impl/ICUResourceBundleReader;Ljava/lang/CharSequence;)I
 HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->findValue(Ljava/lang/CharSequence;Landroid/icu/impl/UResource$Value;)Z
 HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->getKey(Landroid/icu/impl/ICUResourceBundleReader;I)Ljava/lang/String;
-HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->getKeyAndValue(ILandroid/icu/impl/UResource$Key;Landroid/icu/impl/UResource$Value;)Z
+HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->getKeyAndValue(ILandroid/icu/impl/UResource$Key;Landroid/icu/impl/UResource$Value;)Z+]Landroid/icu/impl/ICUResourceBundleReader$Table;Landroid/icu/impl/ICUResourceBundleReader$Table1632;,Landroid/icu/impl/ICUResourceBundleReader$Table16;
 HSPLandroid/icu/impl/ICUResourceBundleReader$Table;->getResource(Landroid/icu/impl/ICUResourceBundleReader;Ljava/lang/String;)I
 HSPLandroid/icu/impl/ICUResourceBundleReader;->-$$Nest$fgetb16BitUnits(Landroid/icu/impl/ICUResourceBundleReader;)Ljava/nio/CharBuffer;
 HSPLandroid/icu/impl/ICUResourceBundleReader;->-$$Nest$fgetpoolStringIndex16Limit(Landroid/icu/impl/ICUResourceBundleReader;)I
@@ -8691,7 +8733,7 @@
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getArray(I)Landroid/icu/impl/ICUResourceBundleReader$Array;
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getBinary(I[B)[B
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getChars(II)[C
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getFullName(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getFullName(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getIndexesInt(I)I
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getInt(I)I
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getIntVector(I)[I
@@ -8701,10 +8743,10 @@
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getReader(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)Landroid/icu/impl/ICUResourceBundleReader;
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getResourceByteOffset(I)I
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getRootResource()I
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getString(I)Ljava/lang/String;
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getStringV2(I)Ljava/lang/String;
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getTable(I)Landroid/icu/impl/ICUResourceBundleReader$Table;
-HSPLandroid/icu/impl/ICUResourceBundleReader;->getTable16KeyOffsets(I)[C
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getString(I)Ljava/lang/String;+]Landroid/icu/impl/ICUResourceBundleReader;Landroid/icu/impl/ICUResourceBundleReader;
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getStringV2(I)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache;]Ljava/nio/CharBuffer;Ljava/nio/ByteBufferAsCharBuffer;]Ljava/lang/CharSequence;Ljava/nio/ByteBufferAsCharBuffer;
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getTable(I)Landroid/icu/impl/ICUResourceBundleReader$Table;+]Landroid/icu/impl/ICUResourceBundleReader$ResourceCache;Landroid/icu/impl/ICUResourceBundleReader$ResourceCache;]Landroid/icu/impl/ICUResourceBundleReader$Table;Landroid/icu/impl/ICUResourceBundleReader$Table16;,Landroid/icu/impl/ICUResourceBundleReader$Table1632;
+HSPLandroid/icu/impl/ICUResourceBundleReader;->getTable16KeyOffsets(I)[C+]Ljava/nio/CharBuffer;Ljava/nio/ByteBufferAsCharBuffer;
 HSPLandroid/icu/impl/ICUResourceBundleReader;->getTableKeyOffsets(I)[C
 HSPLandroid/icu/impl/ICUResourceBundleReader;->init(Ljava/nio/ByteBuffer;)V
 HSPLandroid/icu/impl/ICUResourceBundleReader;->makeKeyStringFromBytes([BI)Ljava/lang/String;
@@ -8714,10 +8756,10 @@
 HSPLandroid/icu/impl/ICUService$Key;-><init>(Ljava/lang/String;)V
 HSPLandroid/icu/impl/ICUService;->clearServiceCache()V
 HSPLandroid/icu/impl/ICUService;->getKey(Landroid/icu/impl/ICUService$Key;[Ljava/lang/String;)Ljava/lang/Object;
-HSPLandroid/icu/impl/ICUService;->getKey(Landroid/icu/impl/ICUService$Key;[Ljava/lang/String;Landroid/icu/impl/ICUService$Factory;)Ljava/lang/Object;
+HSPLandroid/icu/impl/ICUService;->getKey(Landroid/icu/impl/ICUService$Key;[Ljava/lang/String;Landroid/icu/impl/ICUService$Factory;)Ljava/lang/Object;+]Ljava/lang/String;Ljava/lang/String;]Ljava/util/List;Ljava/util/ArrayList;]Ljava/util/Map;Ljava/util/concurrent/ConcurrentHashMap;]Landroid/icu/impl/ICURWLock;Landroid/icu/impl/ICURWLock;]Landroid/icu/impl/ICUService$Key;Landroid/icu/impl/ICULocaleService$LocaleKey;
 HSPLandroid/icu/impl/ICUService;->isDefault()Z
-HSPLandroid/icu/impl/IDNA2003;->convertIDNToASCII(Ljava/lang/String;I)Ljava/lang/StringBuffer;
-HSPLandroid/icu/impl/IDNA2003;->convertToASCII(Landroid/icu/text/UCharacterIterator;I)Ljava/lang/StringBuffer;
+HSPLandroid/icu/impl/IDNA2003;->convertIDNToASCII(Ljava/lang/String;I)Ljava/lang/StringBuffer;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;
+HSPLandroid/icu/impl/IDNA2003;->convertToASCII(Landroid/icu/text/UCharacterIterator;I)Ljava/lang/StringBuffer;+]Landroid/icu/text/UCharacterIterator;Landroid/icu/impl/ReplaceableUCharacterIterator;]Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;
 HSPLandroid/icu/impl/IDNA2003;->getSeparatorIndex([CII)I
 HSPLandroid/icu/impl/IDNA2003;->isLDHChar(I)Z
 HSPLandroid/icu/impl/IDNA2003;->isLabelSeparator(I)Z
@@ -8725,9 +8767,9 @@
 HSPLandroid/icu/impl/LocaleIDParser$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
 HSPLandroid/icu/impl/LocaleIDParser$1;->compare(Ljava/lang/String;Ljava/lang/String;)I
 HSPLandroid/icu/impl/LocaleIDParser;-><init>(Ljava/lang/String;)V
-HSPLandroid/icu/impl/LocaleIDParser;-><init>(Ljava/lang/String;Z)V
+HSPLandroid/icu/impl/LocaleIDParser;-><init>(Ljava/lang/String;Z)V+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/icu/impl/LocaleIDParser;->addSeparator()V
-HSPLandroid/icu/impl/LocaleIDParser;->append(C)V
+HSPLandroid/icu/impl/LocaleIDParser;->append(C)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/icu/impl/LocaleIDParser;->append(Ljava/lang/String;)V
 HSPLandroid/icu/impl/LocaleIDParser;->atTerminator()Z
 HSPLandroid/icu/impl/LocaleIDParser;->getBaseName()Ljava/lang/String;
@@ -8751,10 +8793,10 @@
 HSPLandroid/icu/impl/LocaleIDParser;->isTerminatorOrIDSeparator(C)Z
 HSPLandroid/icu/impl/LocaleIDParser;->next()C
 HSPLandroid/icu/impl/LocaleIDParser;->parseBaseName()V
-HSPLandroid/icu/impl/LocaleIDParser;->parseCountry()I
+HSPLandroid/icu/impl/LocaleIDParser;->parseCountry()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/icu/impl/LocaleIDParser;->parseKeywords()I
-HSPLandroid/icu/impl/LocaleIDParser;->parseLanguage()I
-HSPLandroid/icu/impl/LocaleIDParser;->parseScript()I
+HSPLandroid/icu/impl/LocaleIDParser;->parseLanguage()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/icu/impl/LocaleIDParser;->parseScript()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/icu/impl/LocaleIDParser;->parseVariant()I
 HSPLandroid/icu/impl/LocaleIDParser;->reset()V
 HSPLandroid/icu/impl/LocaleIDParser;->setKeywordValue(Ljava/lang/String;Ljava/lang/String;)V
@@ -8783,7 +8825,7 @@
 HSPLandroid/icu/impl/Normalizer2Impl;->addToStartSet(Landroid/icu/util/MutableCodePointTrie;II)V
 HSPLandroid/icu/impl/Normalizer2Impl;->composeQuickCheck(Ljava/lang/CharSequence;IIZZ)I
 HSPLandroid/icu/impl/Normalizer2Impl;->decompose(IILandroid/icu/impl/Normalizer2Impl$ReorderingBuffer;)V
-HSPLandroid/icu/impl/Normalizer2Impl;->decompose(Ljava/lang/CharSequence;IILandroid/icu/impl/Normalizer2Impl$ReorderingBuffer;)I
+HSPLandroid/icu/impl/Normalizer2Impl;->decompose(Ljava/lang/CharSequence;IILandroid/icu/impl/Normalizer2Impl$ReorderingBuffer;)I+]Ljava/lang/CharSequence;Ljava/lang/String;
 HSPLandroid/icu/impl/Normalizer2Impl;->decomposeAndAppend(Ljava/lang/CharSequence;ZLandroid/icu/impl/Normalizer2Impl$ReorderingBuffer;)V
 HSPLandroid/icu/impl/Normalizer2Impl;->ensureCanonIterData()Landroid/icu/impl/Normalizer2Impl;
 HSPLandroid/icu/impl/Normalizer2Impl;->getRawNorm16(I)I
@@ -8813,11 +8855,11 @@
 HSPLandroid/icu/impl/OlsonTimeZone;->initialRawOffset()I
 HSPLandroid/icu/impl/OlsonTimeZone;->isFrozen()Z
 HSPLandroid/icu/impl/OlsonTimeZone;->loadRule(Landroid/icu/util/UResourceBundle;Ljava/lang/String;)Landroid/icu/util/UResourceBundle;
-HSPLandroid/icu/impl/OlsonTimeZone;->toString()Ljava/lang/String;
+HSPLandroid/icu/impl/OlsonTimeZone;->toString()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/icu/impl/PatternProps;->isWhiteSpace(I)Z
 HSPLandroid/icu/impl/PatternProps;->skipWhiteSpace(Ljava/lang/CharSequence;I)I
 HSPLandroid/icu/impl/PatternTokenizer;-><init>()V
-HSPLandroid/icu/impl/PatternTokenizer;->next(Ljava/lang/StringBuffer;)I
+HSPLandroid/icu/impl/PatternTokenizer;->next(Ljava/lang/StringBuffer;)I+]Landroid/icu/text/UnicodeSet;Landroid/icu/text/UnicodeSet;
 HSPLandroid/icu/impl/PatternTokenizer;->quoteLiteral(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/icu/impl/PatternTokenizer;->setExtraQuotingCharacters(Landroid/icu/text/UnicodeSet;)Landroid/icu/impl/PatternTokenizer;
 HSPLandroid/icu/impl/PatternTokenizer;->setPattern(Ljava/lang/String;)Landroid/icu/impl/PatternTokenizer;
@@ -8838,7 +8880,7 @@
 HSPLandroid/icu/impl/ReplaceableUCharacterIterator;-><init>(Ljava/lang/String;)V
 HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->getLength()I
 HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->getText([CI)I
-HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->next()I
+HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->next()I+]Landroid/icu/text/Replaceable;Landroid/icu/text/ReplaceableString;
 HSPLandroid/icu/impl/ReplaceableUCharacterIterator;->setIndex(I)V
 HSPLandroid/icu/impl/RuleCharacterIterator;->_advance(I)V
 HSPLandroid/icu/impl/RuleCharacterIterator;->_current()I
@@ -8865,14 +8907,14 @@
 HSPLandroid/icu/impl/StaticUnicodeSets;->get(Landroid/icu/impl/StaticUnicodeSets$Key;)Landroid/icu/text/UnicodeSet;
 HSPLandroid/icu/impl/StringSegment;-><init>(Ljava/lang/String;Z)V
 HSPLandroid/icu/impl/StringSegment;->adjustOffset(I)V
-HSPLandroid/icu/impl/StringSegment;->charAt(I)C+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/icu/impl/StringSegment;->charAt(I)C
 HSPLandroid/icu/impl/StringSegment;->codePointsEqual(IIZ)Z
-HSPLandroid/icu/impl/StringSegment;->getCodePoint()I+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/icu/impl/StringSegment;->getCodePoint()I
 HSPLandroid/icu/impl/StringSegment;->getCommonPrefixLength(Ljava/lang/CharSequence;)I
 HSPLandroid/icu/impl/StringSegment;->getOffset()I
-HSPLandroid/icu/impl/StringSegment;->getPrefixLengthInternal(Ljava/lang/CharSequence;Z)I+]Landroid/icu/impl/StringSegment;Landroid/icu/impl/StringSegment;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/icu/impl/StringSegment;->getPrefixLengthInternal(Ljava/lang/CharSequence;Z)I
 HSPLandroid/icu/impl/StringSegment;->length()I
-HSPLandroid/icu/impl/StringSegment;->startsWith(Landroid/icu/text/UnicodeSet;)Z+]Landroid/icu/impl/StringSegment;Landroid/icu/impl/StringSegment;]Landroid/icu/text/UnicodeSet;Landroid/icu/text/UnicodeSet;
+HSPLandroid/icu/impl/StringSegment;->startsWith(Landroid/icu/text/UnicodeSet;)Z
 HSPLandroid/icu/impl/StringSegment;->startsWith(Ljava/lang/CharSequence;)Z
 HSPLandroid/icu/impl/TextTrieMap$Node;-><init>(Landroid/icu/impl/TextTrieMap;)V
 HSPLandroid/icu/impl/TextTrieMap;-><init>(Z)V
@@ -8930,7 +8972,7 @@
 HSPLandroid/icu/impl/Trie2_32;->getFromU16SingleLead(C)I
 HSPLandroid/icu/impl/UBiDiProps;->getClass(I)I
 HSPLandroid/icu/impl/UBiDiProps;->getClassFromProps(I)I
-HSPLandroid/icu/impl/UCaseProps;->fold(II)I+]Landroid/icu/impl/Trie2_16;Landroid/icu/impl/Trie2_16;
+HSPLandroid/icu/impl/UCaseProps;->fold(II)I
 HSPLandroid/icu/impl/UCaseProps;->getCaseLocale(Ljava/lang/String;)I
 HSPLandroid/icu/impl/UCaseProps;->getCaseLocale(Ljava/util/Locale;)I
 HSPLandroid/icu/impl/UCaseProps;->getDelta(I)I
@@ -8962,7 +9004,7 @@
 HSPLandroid/icu/impl/UResource$Value;-><init>()V
 HSPLandroid/icu/impl/UResource$Value;->toString()Ljava/lang/String;
 HSPLandroid/icu/impl/Utility;->addExact(II)I
-HSPLandroid/icu/impl/Utility;->appendTo(Ljava/lang/CharSequence;Ljava/lang/Appendable;)Ljava/lang/Appendable;
+HSPLandroid/icu/impl/Utility;->appendTo(Ljava/lang/CharSequence;Ljava/lang/Appendable;)Ljava/lang/Appendable;+]Ljava/lang/Appendable;Ljava/lang/StringBuffer;
 HSPLandroid/icu/impl/Utility;->arrayEquals([BLjava/lang/Object;)Z
 HSPLandroid/icu/impl/Utility;->arrayRegionMatches([BI[BII)Z
 HSPLandroid/icu/impl/Utility;->sameObjects(Ljava/lang/Object;Ljava/lang/Object;)Z
@@ -9093,9 +9135,9 @@
 HSPLandroid/icu/impl/locale/BaseLocale$Key;->-$$Nest$fget_vart(Landroid/icu/impl/locale/BaseLocale$Key;)Ljava/lang/String;
 HSPLandroid/icu/impl/locale/BaseLocale$Key;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/icu/impl/locale/BaseLocale$Key;->equals(Ljava/lang/Object;)Z
-HSPLandroid/icu/impl/locale/BaseLocale$Key;->hashCode()I
+HSPLandroid/icu/impl/locale/BaseLocale$Key;->hashCode()I+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/icu/impl/locale/BaseLocale$Key;->normalize(Landroid/icu/impl/locale/BaseLocale$Key;)Landroid/icu/impl/locale/BaseLocale$Key;
-HSPLandroid/icu/impl/locale/BaseLocale;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+HSPLandroid/icu/impl/locale/BaseLocale;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/icu/impl/locale/BaseLocale;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/icu/impl/locale/BaseLocale-IA;)V
 HSPLandroid/icu/impl/locale/BaseLocale;->getInstance(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/icu/impl/locale/BaseLocale;
 HSPLandroid/icu/impl/locale/BaseLocale;->getLanguage()Ljava/lang/String;
@@ -9116,7 +9158,7 @@
 HSPLandroid/icu/impl/locale/LocaleObjectCache;->get(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/icu/impl/number/AdoptingModifierStore$1;-><clinit>()V
 HSPLandroid/icu/impl/number/AdoptingModifierStore;-><init>(Landroid/icu/impl/number/Modifier;Landroid/icu/impl/number/Modifier;Landroid/icu/impl/number/Modifier;Landroid/icu/impl/number/Modifier;)V
-HSPLandroid/icu/impl/number/AdoptingModifierStore;->getModifierWithoutPlural(Landroid/icu/impl/number/Modifier$Signum;)Landroid/icu/impl/number/Modifier;
+HSPLandroid/icu/impl/number/AdoptingModifierStore;->getModifierWithoutPlural(Landroid/icu/impl/number/Modifier$Signum;)Landroid/icu/impl/number/Modifier;+]Landroid/icu/impl/number/Modifier$Signum;Landroid/icu/impl/number/Modifier$Signum;
 HSPLandroid/icu/impl/number/AffixUtils;->containsType(Ljava/lang/CharSequence;I)Z
 HSPLandroid/icu/impl/number/AffixUtils;->escape(Ljava/lang/CharSequence;)Ljava/lang/String;
 HSPLandroid/icu/impl/number/AffixUtils;->getFieldForType(I)Landroid/icu/text/NumberFormat$Field;
@@ -9131,14 +9173,14 @@
 HSPLandroid/icu/impl/number/AffixUtils;->nextToken(JLjava/lang/CharSequence;)J
 HSPLandroid/icu/impl/number/AffixUtils;->unescape(Ljava/lang/CharSequence;Landroid/icu/impl/FormattedStringBuilder;ILandroid/icu/impl/number/AffixUtils$SymbolProvider;Landroid/icu/text/NumberFormat$Field;)I
 HSPLandroid/icu/impl/number/AffixUtils;->unescapedCount(Ljava/lang/CharSequence;ZLandroid/icu/impl/number/AffixUtils$SymbolProvider;)I
-HSPLandroid/icu/impl/number/ConstantAffixModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I
+HSPLandroid/icu/impl/number/ConstantAffixModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I+]Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;
 HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;-><init>(Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;ZZ)V
 HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;-><init>(Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;ZZLandroid/icu/impl/number/Modifier$Parameters;)V
-HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I
+HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I+]Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;
 HSPLandroid/icu/impl/number/ConstantMultiFieldModifier;->getPrefixLength()I
 HSPLandroid/icu/impl/number/CurrencySpacingEnabledModifier;->applyCurrencySpacing(Landroid/icu/impl/FormattedStringBuilder;IIIILandroid/icu/text/DecimalFormatSymbols;)I
 HSPLandroid/icu/impl/number/CurrencySpacingEnabledModifier;->applyCurrencySpacingAffix(Landroid/icu/impl/FormattedStringBuilder;IBLandroid/icu/text/DecimalFormatSymbols;)I
-HSPLandroid/icu/impl/number/CustomSymbolCurrency;->resolve(Landroid/icu/util/Currency;Landroid/icu/util/ULocale;Landroid/icu/text/DecimalFormatSymbols;)Landroid/icu/util/Currency;
+HSPLandroid/icu/impl/number/CustomSymbolCurrency;->resolve(Landroid/icu/util/Currency;Landroid/icu/util/ULocale;Landroid/icu/text/DecimalFormatSymbols;)Landroid/icu/util/Currency;+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/util/Currency;Landroid/icu/util/Currency;
 HSPLandroid/icu/impl/number/DecimalFormatProperties;-><init>()V
 HSPLandroid/icu/impl/number/DecimalFormatProperties;->_clear()Landroid/icu/impl/number/DecimalFormatProperties;
 HSPLandroid/icu/impl/number/DecimalFormatProperties;->_copyFrom(Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/impl/number/DecimalFormatProperties;
@@ -9218,14 +9260,14 @@
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToBigDecimal(Ljava/math/BigDecimal;)V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToBigInteger(Ljava/math/BigInteger;)V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToDoubleFast(D)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToLong(J)V
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->_setToLong(J)V+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->adjustMagnitude(I)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->appendDigit(BIZ)V+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->appendDigit(BIZ)V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->applyMaxInteger(I)V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->convertToAccurateDouble()V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->copyFrom(Landroid/icu/impl/number/DecimalQuantity;)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->fitsInLong()Z+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getDigit(I)B
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->fitsInLong()Z
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getDigit(I)B+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getLowerDisplayMagnitude()I
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getMagnitude()I
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->getPluralOperand(Landroid/icu/text/PluralRules$Operand;)D
@@ -9238,18 +9280,18 @@
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->negate()V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->populateUFieldPosition(Ljava/text/FieldPosition;)V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->roundToMagnitude(ILjava/math/MathContext;)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->roundToMagnitude(ILjava/math/MathContext;Z)V
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->roundToMagnitude(ILjava/math/MathContext;Z)V+]Ljava/math/MathContext;Ljava/math/MathContext;]Ljava/math/RoundingMode;Ljava/math/RoundingMode;]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->safeSubtract(II)I
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setMinFraction(I)V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setMinInteger(I)V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToBigDecimal(Ljava/math/BigDecimal;)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToDouble(D)V
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToDouble(D)V+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToInt(I)V
 HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->setToLong(J)V
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->signum()Landroid/icu/impl/number/Modifier$Signum;
-HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->toLong(Z)J+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
-HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>()V+]Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
-HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(D)V
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->signum()Landroid/icu/impl/number/Modifier$Signum;+]Landroid/icu/impl/number/DecimalQuantity_AbstractBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/impl/number/DecimalQuantity_AbstractBCD;->toLong(Z)J
+HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>()V
+HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(D)V+]Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
 HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(I)V
 HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(J)V
 HSPLandroid/icu/impl/number/DecimalQuantity_DualStorageBCD;-><init>(Ljava/lang/Number;)V
@@ -9281,14 +9323,14 @@
 HSPLandroid/icu/impl/number/MacroProps;->fallback(Landroid/icu/impl/number/MacroProps;)V
 HSPLandroid/icu/impl/number/MicroProps;-><init>(Z)V
 HSPLandroid/icu/impl/number/MicroProps;->clone()Ljava/lang/Object;
-HSPLandroid/icu/impl/number/MicroProps;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/impl/number/MicroProps;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/MicroProps;
 HSPLandroid/icu/impl/number/Modifier$Signum;->values()[Landroid/icu/impl/number/Modifier$Signum;
 HSPLandroid/icu/impl/number/MultiplierFormatHandler;-><init>(Landroid/icu/number/Scale;Landroid/icu/impl/number/MicroPropsGenerator;)V
 HSPLandroid/icu/impl/number/MultiplierFormatHandler;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
 HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;-><init>(Landroid/icu/impl/number/AdoptingModifierStore;Landroid/icu/text/PluralRules;)V
 HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->addToChain(Landroid/icu/impl/number/MicroPropsGenerator;)Landroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;
-HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->applyToMicros(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;)V
-HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->applyToMicros(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;)V+]Landroid/icu/impl/number/AdoptingModifierStore;Landroid/icu/impl/number/AdoptingModifierStore;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;->processQuantity(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/impl/number/MicroPropsGenerator;Landroid/icu/impl/number/MicroProps;]Landroid/icu/number/Precision;Landroid/icu/number/Precision$FractionRounderImpl;]Landroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;Landroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;
 HSPLandroid/icu/impl/number/MutablePatternModifier;-><init>(Z)V
 HSPLandroid/icu/impl/number/MutablePatternModifier;->addToChain(Landroid/icu/impl/number/MicroPropsGenerator;)Landroid/icu/impl/number/MicroPropsGenerator;
 HSPLandroid/icu/impl/number/MutablePatternModifier;->apply(Landroid/icu/impl/FormattedStringBuilder;II)I
@@ -9318,7 +9360,7 @@
 HSPLandroid/icu/impl/number/PatternStringParser;->consumeExponent(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V
 HSPLandroid/icu/impl/number/PatternStringParser;->consumeFormat(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V
 HSPLandroid/icu/impl/number/PatternStringParser;->consumeFractionFormat(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V
-HSPLandroid/icu/impl/number/PatternStringParser;->consumeIntegerFormat(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V
+HSPLandroid/icu/impl/number/PatternStringParser;->consumeIntegerFormat(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;)V+]Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParserState;
 HSPLandroid/icu/impl/number/PatternStringParser;->consumeLiteral(Landroid/icu/impl/number/PatternStringParser$ParserState;)V
 HSPLandroid/icu/impl/number/PatternStringParser;->consumePadding(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedSubpatternInfo;Landroid/icu/impl/number/Padder$PadPosition;)V
 HSPLandroid/icu/impl/number/PatternStringParser;->consumePattern(Landroid/icu/impl/number/PatternStringParser$ParserState;Landroid/icu/impl/number/PatternStringParser$ParsedPatternInfo;)V
@@ -9331,9 +9373,9 @@
 HSPLandroid/icu/impl/number/PatternStringUtils$PatternSignType;-><init>(Ljava/lang/String;I)V
 HSPLandroid/icu/impl/number/PatternStringUtils$PatternSignType;->values()[Landroid/icu/impl/number/PatternStringUtils$PatternSignType;
 HSPLandroid/icu/impl/number/PatternStringUtils;->patternInfoToStringBuilder(Landroid/icu/impl/number/AffixPatternProvider;ZLandroid/icu/impl/number/PatternStringUtils$PatternSignType;ZLandroid/icu/impl/StandardPlural;ZLjava/lang/StringBuilder;)V
-HSPLandroid/icu/impl/number/PatternStringUtils;->propertiesToPatternString(Landroid/icu/impl/number/DecimalFormatProperties;)Ljava/lang/String;
+HSPLandroid/icu/impl/number/PatternStringUtils;->propertiesToPatternString(Landroid/icu/impl/number/DecimalFormatProperties;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;
 HSPLandroid/icu/impl/number/PatternStringUtils;->resolveSignDisplay(Landroid/icu/number/NumberFormatter$SignDisplay;Landroid/icu/impl/number/Modifier$Signum;)Landroid/icu/impl/number/PatternStringUtils$PatternSignType;
-HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;-><init>(Landroid/icu/impl/number/DecimalFormatProperties;)V
+HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;-><init>(Landroid/icu/impl/number/DecimalFormatProperties;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;
 HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->charAt(II)C
 HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->containsSymbolType(I)Z
 HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->currencyAsDecimal()Z
@@ -9341,7 +9383,7 @@
 HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->getString(I)Ljava/lang/String;
 HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->hasBody()Z
 HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->hasCurrencySign()Z
-HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->hasNegativeSubpattern()Z
+HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->hasNegativeSubpattern()Z+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/icu/impl/number/PropertiesAffixPatternProvider;->length(I)I
 HSPLandroid/icu/impl/number/RoundingUtils;->getMathContextOr34Digits(Landroid/icu/impl/number/DecimalFormatProperties;)Ljava/math/MathContext;
 HSPLandroid/icu/impl/number/RoundingUtils;->getMathContextOrUnlimited(Landroid/icu/impl/number/DecimalFormatProperties;)Ljava/math/MathContext;
@@ -9353,14 +9395,14 @@
 HSPLandroid/icu/impl/number/parse/AffixMatcher$1;->compare(Landroid/icu/impl/number/parse/AffixMatcher;Landroid/icu/impl/number/parse/AffixMatcher;)I
 HSPLandroid/icu/impl/number/parse/AffixMatcher$1;->compare(Ljava/lang/Object;Ljava/lang/Object;)I
 HSPLandroid/icu/impl/number/parse/AffixMatcher;-><init>(Landroid/icu/impl/number/parse/AffixPatternMatcher;Landroid/icu/impl/number/parse/AffixPatternMatcher;I)V
-HSPLandroid/icu/impl/number/parse/AffixMatcher;->createMatchers(Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/parse/NumberParserImpl;Landroid/icu/impl/number/parse/AffixTokenMatcherFactory;Landroid/icu/impl/number/parse/IgnorablesMatcher;I)V+]Landroid/icu/impl/number/parse/NumberParserImpl;Landroid/icu/impl/number/parse/NumberParserImpl;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/icu/impl/number/parse/AffixMatcher;->createMatchers(Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/parse/NumberParserImpl;Landroid/icu/impl/number/parse/AffixTokenMatcherFactory;Landroid/icu/impl/number/parse/IgnorablesMatcher;I)V
 HSPLandroid/icu/impl/number/parse/AffixMatcher;->getInstance(Landroid/icu/impl/number/parse/AffixPatternMatcher;Landroid/icu/impl/number/parse/AffixPatternMatcher;I)Landroid/icu/impl/number/parse/AffixMatcher;
 HSPLandroid/icu/impl/number/parse/AffixMatcher;->isInteresting(Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/parse/IgnorablesMatcher;I)Z
 HSPLandroid/icu/impl/number/parse/AffixMatcher;->length(Landroid/icu/impl/number/parse/AffixPatternMatcher;)I
 HSPLandroid/icu/impl/number/parse/AffixMatcher;->match(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;)Z
 HSPLandroid/icu/impl/number/parse/AffixMatcher;->matched(Landroid/icu/impl/number/parse/AffixPatternMatcher;Ljava/lang/String;)Z
 HSPLandroid/icu/impl/number/parse/AffixMatcher;->postProcess(Landroid/icu/impl/number/parse/ParsedNumber;)V
-HSPLandroid/icu/impl/number/parse/AffixMatcher;->smokeTest(Landroid/icu/impl/StringSegment;)Z+]Landroid/icu/impl/number/parse/AffixPatternMatcher;Landroid/icu/impl/number/parse/AffixPatternMatcher;
+HSPLandroid/icu/impl/number/parse/AffixMatcher;->smokeTest(Landroid/icu/impl/StringSegment;)Z
 HSPLandroid/icu/impl/number/parse/AffixPatternMatcher;-><init>(Ljava/lang/String;)V
 HSPLandroid/icu/impl/number/parse/AffixPatternMatcher;->consumeToken(I)V
 HSPLandroid/icu/impl/number/parse/AffixPatternMatcher;->equals(Ljava/lang/Object;)Z
@@ -9368,10 +9410,10 @@
 HSPLandroid/icu/impl/number/parse/AffixPatternMatcher;->getPattern()Ljava/lang/String;
 HSPLandroid/icu/impl/number/parse/AffixTokenMatcherFactory;-><init>()V
 HSPLandroid/icu/impl/number/parse/AffixTokenMatcherFactory;->minusSign()Landroid/icu/impl/number/parse/MinusSignMatcher;
-HSPLandroid/icu/impl/number/parse/DecimalMatcher;-><init>(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;I)V+]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;
+HSPLandroid/icu/impl/number/parse/DecimalMatcher;-><init>(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;I)V
 HSPLandroid/icu/impl/number/parse/DecimalMatcher;->getInstance(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;I)Landroid/icu/impl/number/parse/DecimalMatcher;
 HSPLandroid/icu/impl/number/parse/DecimalMatcher;->match(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;)Z
-HSPLandroid/icu/impl/number/parse/DecimalMatcher;->match(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;I)Z
+HSPLandroid/icu/impl/number/parse/DecimalMatcher;->match(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;I)Z+]Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/number/parse/ParsedNumber;Landroid/icu/impl/number/parse/ParsedNumber;]Landroid/icu/text/UnicodeSet;Landroid/icu/text/UnicodeSet;]Landroid/icu/impl/StringSegment;Landroid/icu/impl/StringSegment;
 HSPLandroid/icu/impl/number/parse/DecimalMatcher;->postProcess(Landroid/icu/impl/number/parse/ParsedNumber;)V
 HSPLandroid/icu/impl/number/parse/DecimalMatcher;->smokeTest(Landroid/icu/impl/StringSegment;)Z
 HSPLandroid/icu/impl/number/parse/DecimalMatcher;->validateGroup(IIZ)Z
@@ -9382,14 +9424,14 @@
 HSPLandroid/icu/impl/number/parse/NumberParserImpl;-><init>(I)V
 HSPLandroid/icu/impl/number/parse/NumberParserImpl;->addMatcher(Landroid/icu/impl/number/parse/NumberParseMatcher;)V
 HSPLandroid/icu/impl/number/parse/NumberParserImpl;->addMatchers(Ljava/util/Collection;)V
-HSPLandroid/icu/impl/number/parse/NumberParserImpl;->createParserFromProperties(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Z)Landroid/icu/impl/number/parse/NumberParserImpl;
+HSPLandroid/icu/impl/number/parse/NumberParserImpl;->createParserFromProperties(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Z)Landroid/icu/impl/number/parse/NumberParserImpl;+]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/impl/number/parse/NumberParserImpl;Landroid/icu/impl/number/parse/NumberParserImpl;]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;
 HSPLandroid/icu/impl/number/parse/NumberParserImpl;->freeze()V
 HSPLandroid/icu/impl/number/parse/NumberParserImpl;->getParseFlags()I
 HSPLandroid/icu/impl/number/parse/NumberParserImpl;->parse(Ljava/lang/String;IZLandroid/icu/impl/number/parse/ParsedNumber;)V
 HSPLandroid/icu/impl/number/parse/NumberParserImpl;->parseGreedy(Landroid/icu/impl/StringSegment;Landroid/icu/impl/number/parse/ParsedNumber;)V
 HSPLandroid/icu/impl/number/parse/ParsedNumber;-><init>()V
 HSPLandroid/icu/impl/number/parse/ParsedNumber;->clear()V
-HSPLandroid/icu/impl/number/parse/ParsedNumber;->getNumber(I)Ljava/lang/Number;+]Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/impl/number/parse/ParsedNumber;->getNumber(I)Ljava/lang/Number;
 HSPLandroid/icu/impl/number/parse/ParsedNumber;->postProcess()V
 HSPLandroid/icu/impl/number/parse/ParsedNumber;->seenNumber()Z
 HSPLandroid/icu/impl/number/parse/ParsedNumber;->setCharsConsumed(Landroid/icu/impl/StringSegment;)V
@@ -9398,7 +9440,7 @@
 HSPLandroid/icu/impl/number/parse/RequireAffixValidator;->postProcess(Landroid/icu/impl/number/parse/ParsedNumber;)V
 HSPLandroid/icu/impl/number/parse/RequireNumberValidator;-><init>()V
 HSPLandroid/icu/impl/number/parse/RequireNumberValidator;->postProcess(Landroid/icu/impl/number/parse/ParsedNumber;)V
-HSPLandroid/icu/impl/number/parse/ScientificMatcher;-><init>(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;)V+]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/text/UnicodeSet;Landroid/icu/text/UnicodeSet;
+HSPLandroid/icu/impl/number/parse/ScientificMatcher;-><init>(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;)V
 HSPLandroid/icu/impl/number/parse/ScientificMatcher;->getInstance(Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/Grouper;)Landroid/icu/impl/number/parse/ScientificMatcher;
 HSPLandroid/icu/impl/number/parse/ScientificMatcher;->minusSignSet()Landroid/icu/text/UnicodeSet;
 HSPLandroid/icu/impl/number/parse/ScientificMatcher;->plusSignSet()Landroid/icu/text/UnicodeSet;
@@ -9426,7 +9468,7 @@
 HSPLandroid/icu/impl/number/range/StandardPluralRanges;->setCapacity(I)V
 HSPLandroid/icu/lang/UCharacter;->codePointAt(Ljava/lang/CharSequence;I)I
 HSPLandroid/icu/lang/UCharacter;->digit(I)I
-HSPLandroid/icu/lang/UCharacter;->foldCase(II)I+]Landroid/icu/impl/UCaseProps;Landroid/icu/impl/UCaseProps;
+HSPLandroid/icu/lang/UCharacter;->foldCase(II)I
 HSPLandroid/icu/lang/UCharacter;->foldCase(IZ)I
 HSPLandroid/icu/lang/UCharacter;->getPropertyValueEnumNoThrow(ILjava/lang/CharSequence;)I
 HSPLandroid/icu/lang/UCharacter;->getType(I)I
@@ -9442,33 +9484,33 @@
 HSPLandroid/icu/number/IntegerWidth;->truncateAt(I)Landroid/icu/number/IntegerWidth;
 HSPLandroid/icu/number/IntegerWidth;->zeroFillTo(I)Landroid/icu/number/IntegerWidth;
 HSPLandroid/icu/number/LocalizedNumberFormatter;-><init>(Landroid/icu/number/NumberFormatterSettings;ILjava/lang/Object;)V
-HSPLandroid/icu/number/LocalizedNumberFormatter;->computeCompiled()Z
+HSPLandroid/icu/number/LocalizedNumberFormatter;->computeCompiled()Z+]Ljava/util/concurrent/atomic/AtomicLongFieldUpdater;Ljava/util/concurrent/atomic/AtomicLongFieldUpdater$CASUpdater;]Landroid/icu/number/LocalizedNumberFormatter;Landroid/icu/number/LocalizedNumberFormatter;]Ljava/lang/Long;Ljava/lang/Long;
 HSPLandroid/icu/number/LocalizedNumberFormatter;->create(ILjava/lang/Object;)Landroid/icu/number/LocalizedNumberFormatter;
 HSPLandroid/icu/number/LocalizedNumberFormatter;->create(ILjava/lang/Object;)Landroid/icu/number/NumberFormatterSettings;
 HSPLandroid/icu/number/LocalizedNumberFormatter;->format(D)Landroid/icu/number/FormattedNumber;
 HSPLandroid/icu/number/LocalizedNumberFormatter;->format(J)Landroid/icu/number/FormattedNumber;
 HSPLandroid/icu/number/LocalizedNumberFormatter;->format(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/number/FormattedNumber;
-HSPLandroid/icu/number/LocalizedNumberFormatter;->formatImpl(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/number/LocalizedNumberFormatter;->formatImpl(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/number/NumberFormatterImpl;Landroid/icu/number/NumberFormatterImpl;
 HSPLandroid/icu/number/LocalizedNumberFormatter;->getAffixImpl(ZZ)Ljava/lang/String;
 HSPLandroid/icu/number/NumberFormatter;->fromDecimalFormat(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/number/UnlocalizedNumberFormatter;
 HSPLandroid/icu/number/NumberFormatter;->with()Landroid/icu/number/UnlocalizedNumberFormatter;
 HSPLandroid/icu/number/NumberFormatterImpl;-><init>(Landroid/icu/impl/number/MacroProps;)V
-HSPLandroid/icu/number/NumberFormatterImpl;->format(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/number/NumberFormatterImpl;->format(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/number/NumberFormatterImpl;Landroid/icu/number/NumberFormatterImpl;
 HSPLandroid/icu/number/NumberFormatterImpl;->formatStatic(Landroid/icu/impl/number/MacroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;)Landroid/icu/impl/number/MicroProps;
 HSPLandroid/icu/number/NumberFormatterImpl;->getPrefixSuffix(BLandroid/icu/impl/StandardPlural;Landroid/icu/impl/FormattedStringBuilder;)I
 HSPLandroid/icu/number/NumberFormatterImpl;->getPrefixSuffixImpl(Landroid/icu/impl/number/MicroPropsGenerator;BLandroid/icu/impl/FormattedStringBuilder;)I
 HSPLandroid/icu/number/NumberFormatterImpl;->getPrefixSuffixStatic(Landroid/icu/impl/number/MacroProps;BLandroid/icu/impl/StandardPlural;Landroid/icu/impl/FormattedStringBuilder;)I
-HSPLandroid/icu/number/NumberFormatterImpl;->macrosToMicroGenerator(Landroid/icu/impl/number/MacroProps;Landroid/icu/impl/number/MicroProps;Z)Landroid/icu/impl/number/MicroPropsGenerator;+]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/impl/number/MutablePatternModifier;Landroid/icu/impl/number/MutablePatternModifier;]Landroid/icu/number/Precision;Landroid/icu/number/Precision$FractionRounderImpl;]Landroid/icu/text/NumberingSystem;Landroid/icu/text/NumberingSystem;
-HSPLandroid/icu/number/NumberFormatterImpl;->preProcess(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
+HSPLandroid/icu/number/NumberFormatterImpl;->macrosToMicroGenerator(Landroid/icu/impl/number/MacroProps;Landroid/icu/impl/number/MicroProps;Z)Landroid/icu/impl/number/MicroPropsGenerator;+]Landroid/icu/impl/number/MutablePatternModifier;Landroid/icu/impl/number/MutablePatternModifier;]Landroid/icu/text/NumberingSystem;Landroid/icu/text/NumberingSystem;]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/number/Precision;Landroid/icu/number/Precision$FractionRounderImpl;
+HSPLandroid/icu/number/NumberFormatterImpl;->preProcess(Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;+]Landroid/icu/impl/number/MicroPropsGenerator;Landroid/icu/impl/number/MutablePatternModifier$ImmutablePatternModifier;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
 HSPLandroid/icu/number/NumberFormatterImpl;->preProcessUnsafe(Landroid/icu/impl/number/MacroProps;Landroid/icu/impl/number/DecimalQuantity;)Landroid/icu/impl/number/MicroProps;
 HSPLandroid/icu/number/NumberFormatterImpl;->unitIsBaseUnit(Landroid/icu/util/MeasureUnit;)Z
 HSPLandroid/icu/number/NumberFormatterImpl;->unitIsCurrency(Landroid/icu/util/MeasureUnit;)Z
 HSPLandroid/icu/number/NumberFormatterImpl;->unitIsPercent(Landroid/icu/util/MeasureUnit;)Z
 HSPLandroid/icu/number/NumberFormatterImpl;->unitIsPermille(Landroid/icu/util/MeasureUnit;)Z
-HSPLandroid/icu/number/NumberFormatterImpl;->writeAffixes(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/FormattedStringBuilder;II)I
-HSPLandroid/icu/number/NumberFormatterImpl;->writeFractionDigits(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I
-HSPLandroid/icu/number/NumberFormatterImpl;->writeIntegerDigits(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I
-HSPLandroid/icu/number/NumberFormatterImpl;->writeNumber(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I
+HSPLandroid/icu/number/NumberFormatterImpl;->writeAffixes(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/FormattedStringBuilder;II)I+]Landroid/icu/impl/number/Padder;Landroid/icu/impl/number/Padder;]Landroid/icu/impl/number/Modifier;Landroid/icu/impl/number/ConstantMultiFieldModifier;,Landroid/icu/impl/number/ConstantAffixModifier;
+HSPLandroid/icu/number/NumberFormatterImpl;->writeFractionDigits(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I+]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/number/NumberFormatterImpl;->writeIntegerDigits(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I+]Landroid/icu/impl/number/Grouper;Landroid/icu/impl/number/Grouper;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/impl/FormattedStringBuilder;Landroid/icu/impl/FormattedStringBuilder;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/number/NumberFormatterImpl;->writeNumber(Landroid/icu/impl/number/MicroProps;Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;I)I+]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
 HSPLandroid/icu/number/NumberFormatterSettings;-><init>(Landroid/icu/number/NumberFormatterSettings;ILjava/lang/Object;)V
 HSPLandroid/icu/number/NumberFormatterSettings;->macros(Landroid/icu/impl/number/MacroProps;)Landroid/icu/number/NumberFormatterSettings;
 HSPLandroid/icu/number/NumberFormatterSettings;->perUnit(Landroid/icu/util/MeasureUnit;)Landroid/icu/number/NumberFormatterSettings;
@@ -9476,9 +9518,9 @@
 HSPLandroid/icu/number/NumberFormatterSettings;->unit(Landroid/icu/util/MeasureUnit;)Landroid/icu/number/NumberFormatterSettings;
 HSPLandroid/icu/number/NumberFormatterSettings;->unitWidth(Landroid/icu/number/NumberFormatter$UnitWidth;)Landroid/icu/number/NumberFormatterSettings;
 HSPLandroid/icu/number/NumberPropertyMapper;->create(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/number/UnlocalizedNumberFormatter;
-HSPLandroid/icu/number/NumberPropertyMapper;->oldToNew(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/impl/number/MacroProps;
+HSPLandroid/icu/number/NumberPropertyMapper;->oldToNew(Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/impl/number/DecimalFormatProperties;)Landroid/icu/impl/number/MacroProps;+]Ljava/math/MathContext;Ljava/math/MathContext;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/impl/number/AffixPatternProvider;Landroid/icu/impl/number/PropertiesAffixPatternProvider;]Landroid/icu/number/Precision;Landroid/icu/number/Precision$FractionRounderImpl;,Landroid/icu/number/Precision$CurrencyRounderImpl;]Landroid/icu/number/IntegerWidth;Landroid/icu/number/IntegerWidth;]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;]Landroid/icu/number/CurrencyPrecision;Landroid/icu/number/Precision$CurrencyRounderImpl;]Landroid/icu/util/Currency;Landroid/icu/util/Currency;
 HSPLandroid/icu/number/Precision$FractionRounderImpl;-><init>(II)V
-HSPLandroid/icu/number/Precision$FractionRounderImpl;->apply(Landroid/icu/impl/number/DecimalQuantity;)V
+HSPLandroid/icu/number/Precision$FractionRounderImpl;->apply(Landroid/icu/impl/number/DecimalQuantity;)V+]Landroid/icu/number/Precision$FractionRounderImpl;Landroid/icu/number/Precision$FractionRounderImpl;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
 HSPLandroid/icu/number/Precision$FractionRounderImpl;->createCopy()Landroid/icu/number/Precision$FractionRounderImpl;
 HSPLandroid/icu/number/Precision$FractionRounderImpl;->createCopy()Landroid/icu/number/Precision;
 HSPLandroid/icu/number/Precision;->-$$Nest$smgetDisplayMagnitudeFraction(I)I
@@ -9489,7 +9531,7 @@
 HSPLandroid/icu/number/Precision;->constructFromCurrency(Landroid/icu/number/CurrencyPrecision;Landroid/icu/util/Currency;)Landroid/icu/number/Precision;
 HSPLandroid/icu/number/Precision;->getDisplayMagnitudeFraction(I)I
 HSPLandroid/icu/number/Precision;->getRoundingMagnitudeFraction(I)I
-HSPLandroid/icu/number/Precision;->setResolvedMinFraction(Landroid/icu/impl/number/DecimalQuantity;I)V
+HSPLandroid/icu/number/Precision;->setResolvedMinFraction(Landroid/icu/impl/number/DecimalQuantity;I)V+]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
 HSPLandroid/icu/number/Precision;->withLocaleData(Landroid/icu/util/Currency;)Landroid/icu/number/Precision;
 HSPLandroid/icu/number/Precision;->withMode(Ljava/math/MathContext;)Landroid/icu/number/Precision;
 HSPLandroid/icu/number/Scale;->applyTo(Landroid/icu/impl/number/DecimalQuantity;)V
@@ -9538,7 +9580,7 @@
 HSPLandroid/icu/text/Collator$ServiceShim;-><init>()V
 HSPLandroid/icu/text/Collator;-><init>()V
 HSPLandroid/icu/text/Collator;->clone()Ljava/lang/Object;
-HSPLandroid/icu/text/Collator;->getInstance(Landroid/icu/util/ULocale;)Landroid/icu/text/Collator;
+HSPLandroid/icu/text/Collator;->getInstance(Landroid/icu/util/ULocale;)Landroid/icu/text/Collator;+]Landroid/icu/text/Collator$ServiceShim;Landroid/icu/text/CollatorServiceShim;]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/util/ULocale;Landroid/icu/util/ULocale;
 HSPLandroid/icu/text/Collator;->getInstance(Ljava/util/Locale;)Landroid/icu/text/Collator;
 HSPLandroid/icu/text/Collator;->getShim()Landroid/icu/text/Collator$ServiceShim;
 HSPLandroid/icu/text/CollatorServiceShim$CService$1CollatorFactory;->handleCreate(Landroid/icu/util/ULocale;ILandroid/icu/impl/ICUService;)Ljava/lang/Object;
@@ -9546,13 +9588,13 @@
 HSPLandroid/icu/text/CollatorServiceShim;-><init>()V
 HSPLandroid/icu/text/CollatorServiceShim;->getInstance(Landroid/icu/util/ULocale;)Landroid/icu/text/Collator;
 HSPLandroid/icu/text/CollatorServiceShim;->makeInstance(Landroid/icu/util/ULocale;)Landroid/icu/text/Collator;
-HSPLandroid/icu/text/ConstrainedFieldPosition;-><init>()V
+HSPLandroid/icu/text/ConstrainedFieldPosition;-><init>()V+]Landroid/icu/text/ConstrainedFieldPosition;Landroid/icu/text/ConstrainedFieldPosition;
 HSPLandroid/icu/text/ConstrainedFieldPosition;->constrainField(Ljava/text/Format$Field;)V
 HSPLandroid/icu/text/ConstrainedFieldPosition;->getField()Ljava/text/Format$Field;
 HSPLandroid/icu/text/ConstrainedFieldPosition;->getFieldValue()Ljava/lang/Object;
 HSPLandroid/icu/text/ConstrainedFieldPosition;->getLimit()I
 HSPLandroid/icu/text/ConstrainedFieldPosition;->getStart()I
-HSPLandroid/icu/text/ConstrainedFieldPosition;->matchesField(Ljava/text/Format$Field;Ljava/lang/Object;)Z
+HSPLandroid/icu/text/ConstrainedFieldPosition;->matchesField(Ljava/text/Format$Field;Ljava/lang/Object;)Z+]Landroid/icu/text/ConstrainedFieldPosition$ConstraintType;Landroid/icu/text/ConstrainedFieldPosition$ConstraintType;
 HSPLandroid/icu/text/ConstrainedFieldPosition;->reset()V
 HSPLandroid/icu/text/ConstrainedFieldPosition;->setState(Ljava/text/Format$Field;Ljava/lang/Object;II)V
 HSPLandroid/icu/text/CurrencyDisplayNames;-><init>()V
@@ -9605,6 +9647,7 @@
 HSPLandroid/icu/text/DateFormatSymbols;->initializeData(Landroid/icu/util/ULocale;Landroid/icu/impl/ICUResourceBundle;Ljava/lang/String;)V
 HSPLandroid/icu/text/DateFormatSymbols;->initializeData(Landroid/icu/util/ULocale;Landroid/icu/impl/ICUResourceBundle;Ljava/lang/String;Landroid/icu/text/DateFormatSymbols$AospExtendedDateFormatSymbols;)V
 HSPLandroid/icu/text/DateFormatSymbols;->initializeData(Landroid/icu/util/ULocale;Ljava/lang/String;)V
+HSPLandroid/icu/text/DateFormatSymbols;->loadDayPeriodStrings(Ljava/util/Map;)[Ljava/lang/String;
 HSPLandroid/icu/text/DateFormatSymbols;->setLocale(Landroid/icu/util/ULocale;Landroid/icu/util/ULocale;)V
 HSPLandroid/icu/text/DateFormatSymbols;->setTimeSeparatorString(Ljava/lang/String;)V
 HSPLandroid/icu/text/DateIntervalFormat;-><init>(Ljava/lang/String;Landroid/icu/util/ULocale;Landroid/icu/text/SimpleDateFormat;)V
@@ -9650,7 +9693,7 @@
 HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->getBasePattern()Ljava/lang/String;
 HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->getDistance(Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;ILandroid/icu/text/DateTimePatternGenerator$DistanceInfo;)I
 HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->getFieldMask()I
-HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->set(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$FormatParser;Z)Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;
+HSPLandroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;->set(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$FormatParser;Z)Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/text/DateTimePatternGenerator$VariableField;Landroid/icu/text/DateTimePatternGenerator$VariableField;]Landroid/icu/text/DateTimePatternGenerator$FormatParser;Landroid/icu/text/DateTimePatternGenerator$FormatParser;]Landroid/icu/text/DateTimePatternGenerator$SkeletonFields;Landroid/icu/text/DateTimePatternGenerator$SkeletonFields;]Ljava/util/List;Ljava/util/ArrayList;]Ljava/util/Iterator;Ljava/util/ArrayList$Itr;
 HSPLandroid/icu/text/DateTimePatternGenerator$DisplayWidth;->cldrKey()Ljava/lang/String;
 HSPLandroid/icu/text/DateTimePatternGenerator$DistanceInfo;-><init>()V
 HSPLandroid/icu/text/DateTimePatternGenerator$DistanceInfo;->addExtra(I)V
@@ -9662,7 +9705,7 @@
 HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->getItems()Ljava/util/List;
 HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->quoteLiteral(Ljava/lang/String;)Ljava/lang/Object;
 HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->set(Ljava/lang/String;)Landroid/icu/text/DateTimePatternGenerator$FormatParser;
-HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->set(Ljava/lang/String;Z)Landroid/icu/text/DateTimePatternGenerator$FormatParser;
+HSPLandroid/icu/text/DateTimePatternGenerator$FormatParser;->set(Ljava/lang/String;Z)Landroid/icu/text/DateTimePatternGenerator$FormatParser;+]Ljava/lang/String;Ljava/lang/String;]Ljava/util/List;Ljava/util/ArrayList;]Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;]Landroid/icu/impl/PatternTokenizer;Landroid/icu/impl/PatternTokenizer;
 HSPLandroid/icu/text/DateTimePatternGenerator$PatternInfo;-><init>()V
 HSPLandroid/icu/text/DateTimePatternGenerator$PatternWithMatcher;-><init>(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;)V
 HSPLandroid/icu/text/DateTimePatternGenerator$PatternWithSkeletonFlag;-><init>(Ljava/lang/String;Z)V
@@ -9705,9 +9748,9 @@
 HSPLandroid/icu/text/DateTimePatternGenerator;->getBestPattern(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;I)Ljava/lang/String;
 HSPLandroid/icu/text/DateTimePatternGenerator;->getBestPattern(Ljava/lang/String;Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;IZ)Ljava/lang/String;
 HSPLandroid/icu/text/DateTimePatternGenerator;->getBestRaw(Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;ILandroid/icu/text/DateTimePatternGenerator$DistanceInfo;Landroid/icu/text/DateTimePatternGenerator$DateTimeMatcher;)Landroid/icu/text/DateTimePatternGenerator$PatternWithMatcher;
-HSPLandroid/icu/text/DateTimePatternGenerator;->getCLDRFieldAndWidthNumber(Landroid/icu/impl/UResource$Key;)I
+HSPLandroid/icu/text/DateTimePatternGenerator;->getCLDRFieldAndWidthNumber(Landroid/icu/impl/UResource$Key;)I+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/UResource$Key;Landroid/icu/impl/UResource$Key;
 HSPLandroid/icu/text/DateTimePatternGenerator;->getCalendarTypeToUse(Landroid/icu/util/ULocale;)Ljava/lang/String;
-HSPLandroid/icu/text/DateTimePatternGenerator;->getCanonicalIndex(Ljava/lang/String;Z)I
+HSPLandroid/icu/text/DateTimePatternGenerator;->getCanonicalIndex(Ljava/lang/String;Z)I+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/icu/text/DateTimePatternGenerator;->getDateTimeFormat()Ljava/lang/String;
 HSPLandroid/icu/text/DateTimePatternGenerator;->getFieldDisplayName(ILandroid/icu/text/DateTimePatternGenerator$DisplayWidth;)Ljava/lang/String;
 HSPLandroid/icu/text/DateTimePatternGenerator;->getFilteredPattern(Landroid/icu/text/DateTimePatternGenerator$FormatParser;Ljava/util/BitSet;)Ljava/lang/String;
@@ -9730,8 +9773,8 @@
 HSPLandroid/icu/text/DecimalFormat;-><init>(Ljava/lang/String;Landroid/icu/text/DecimalFormatSymbols;)V
 HSPLandroid/icu/text/DecimalFormat;-><init>(Ljava/lang/String;Landroid/icu/text/DecimalFormatSymbols;I)V
 HSPLandroid/icu/text/DecimalFormat;->clone()Ljava/lang/Object;
-HSPLandroid/icu/text/DecimalFormat;->fieldPositionHelper(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;Ljava/text/FieldPosition;I)V
-HSPLandroid/icu/text/DecimalFormat;->format(DLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;
+HSPLandroid/icu/text/DecimalFormat;->fieldPositionHelper(Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/FormattedStringBuilder;Ljava/text/FieldPosition;I)V+]Ljava/text/FieldPosition;Ljava/text/DontCareFieldPosition;]Landroid/icu/impl/number/DecimalQuantity;Landroid/icu/impl/number/DecimalQuantity_DualStorageBCD;
+HSPLandroid/icu/text/DecimalFormat;->format(DLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;+]Landroid/icu/number/LocalizedNumberFormatter;Landroid/icu/number/LocalizedNumberFormatter;]Ljava/lang/StringBuffer;Ljava/lang/StringBuffer;
 HSPLandroid/icu/text/DecimalFormat;->format(JLjava/lang/StringBuffer;Ljava/text/FieldPosition;)Ljava/lang/StringBuffer;
 HSPLandroid/icu/text/DecimalFormat;->getDecimalFormatSymbols()Landroid/icu/text/DecimalFormatSymbols;
 HSPLandroid/icu/text/DecimalFormat;->getMaximumFractionDigits()I
@@ -9746,7 +9789,7 @@
 HSPLandroid/icu/text/DecimalFormat;->isParseBigDecimal()Z
 HSPLandroid/icu/text/DecimalFormat;->isParseIntegerOnly()Z
 HSPLandroid/icu/text/DecimalFormat;->parse(Ljava/lang/String;Ljava/text/ParsePosition;)Ljava/lang/Number;
-HSPLandroid/icu/text/DecimalFormat;->refreshFormatter()V
+HSPLandroid/icu/text/DecimalFormat;->refreshFormatter()V+]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/number/UnlocalizedNumberFormatter;Landroid/icu/number/UnlocalizedNumberFormatter;]Landroid/icu/text/DecimalFormat;Landroid/icu/text/DecimalFormat;
 HSPLandroid/icu/text/DecimalFormat;->setCurrency(Landroid/icu/util/Currency;)V
 HSPLandroid/icu/text/DecimalFormat;->setDecimalSeparatorAlwaysShown(Z)V
 HSPLandroid/icu/text/DecimalFormat;->setGroupingUsed(Z)V
@@ -9758,7 +9801,7 @@
 HSPLandroid/icu/text/DecimalFormat;->setParseStrictMode(Landroid/icu/impl/number/DecimalFormatProperties$ParseMode;)V
 HSPLandroid/icu/text/DecimalFormat;->setPropertiesFromPattern(Ljava/lang/String;I)V
 HSPLandroid/icu/text/DecimalFormat;->toNumberFormatter()Landroid/icu/number/LocalizedNumberFormatter;
-HSPLandroid/icu/text/DecimalFormat;->toPattern()Ljava/lang/String;+]Landroid/icu/impl/number/DecimalFormatProperties;Landroid/icu/impl/number/DecimalFormatProperties;
+HSPLandroid/icu/text/DecimalFormat;->toPattern()Ljava/lang/String;
 HSPLandroid/icu/text/DecimalFormatSymbols$1;->createInstance(Landroid/icu/util/ULocale;Ljava/lang/Void;)Landroid/icu/text/DecimalFormatSymbols$CacheData;
 HSPLandroid/icu/text/DecimalFormatSymbols$1;->createInstance(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/icu/text/DecimalFormatSymbols$CacheData;-><init>(Landroid/icu/util/ULocale;[Ljava/lang/String;[Ljava/lang/String;)V
@@ -9800,7 +9843,7 @@
 HSPLandroid/icu/text/DecimalFormatSymbols;->getULocale()Landroid/icu/util/ULocale;
 HSPLandroid/icu/text/DecimalFormatSymbols;->getZeroDigit()C
 HSPLandroid/icu/text/DecimalFormatSymbols;->initSpacingInfo(Landroid/icu/impl/CurrencyData$CurrencySpacingInfo;)V
-HSPLandroid/icu/text/DecimalFormatSymbols;->initialize(Landroid/icu/util/ULocale;Landroid/icu/text/NumberingSystem;)V
+HSPLandroid/icu/text/DecimalFormatSymbols;->initialize(Landroid/icu/util/ULocale;Landroid/icu/text/NumberingSystem;)V+]Landroid/icu/impl/CurrencyData$CurrencyDisplayInfoProvider;Landroid/icu/impl/ICUCurrencyDisplayInfoProvider;]Landroid/icu/util/ULocale;Landroid/icu/util/ULocale;]Landroid/icu/text/DecimalFormatSymbols;Landroid/icu/text/DecimalFormatSymbols;]Landroid/icu/impl/CurrencyData$CurrencyDisplayInfo;Landroid/icu/impl/ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo;
 HSPLandroid/icu/text/DecimalFormatSymbols;->loadData(Landroid/icu/util/ULocale;)Landroid/icu/text/DecimalFormatSymbols$CacheData;
 HSPLandroid/icu/text/DecimalFormatSymbols;->setApproximatelySignString(Ljava/lang/String;)V
 HSPLandroid/icu/text/DecimalFormatSymbols;->setCurrency(Landroid/icu/util/Currency;)V
@@ -9996,7 +10039,7 @@
 HSPLandroid/icu/text/RuleBasedCollator;->clone()Ljava/lang/Object;
 HSPLandroid/icu/text/RuleBasedCollator;->cloneAsThawed()Landroid/icu/text/RuleBasedCollator;
 HSPLandroid/icu/text/RuleBasedCollator;->compare(Ljava/lang/String;Ljava/lang/String;)I
-HSPLandroid/icu/text/RuleBasedCollator;->doCompare(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)I
+HSPLandroid/icu/text/RuleBasedCollator;->doCompare(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)I+]Landroid/icu/impl/coll/CollationData;Landroid/icu/impl/coll/CollationData;]Landroid/icu/impl/coll/SharedObject$Reference;Landroid/icu/impl/coll/SharedObject$Reference;]Ljava/lang/CharSequence;Ljava/lang/String;]Landroid/icu/impl/coll/CollationSettings;Landroid/icu/impl/coll/CollationSettings;
 HSPLandroid/icu/text/RuleBasedCollator;->freeze()Landroid/icu/text/Collator;
 HSPLandroid/icu/text/RuleBasedCollator;->getCollationBuffer()Landroid/icu/text/RuleBasedCollator$CollationBuffer;
 HSPLandroid/icu/text/RuleBasedCollator;->getCollationKey(Ljava/lang/String;)Landroid/icu/text/CollationKey;
@@ -10074,7 +10117,7 @@
 HSPLandroid/icu/text/UnicodeSet;->clear()Landroid/icu/text/UnicodeSet;
 HSPLandroid/icu/text/UnicodeSet;->clone()Ljava/lang/Object;
 HSPLandroid/icu/text/UnicodeSet;->compact()Landroid/icu/text/UnicodeSet;
-HSPLandroid/icu/text/UnicodeSet;->contains(I)Z
+HSPLandroid/icu/text/UnicodeSet;->contains(I)Z+]Landroid/icu/impl/BMPSet;Landroid/icu/impl/BMPSet;
 HSPLandroid/icu/text/UnicodeSet;->contains(Ljava/lang/CharSequence;)Z
 HSPLandroid/icu/text/UnicodeSet;->containsAll(Ljava/lang/String;)Z
 HSPLandroid/icu/text/UnicodeSet;->findCodePoint(I)I
@@ -10375,17 +10418,19 @@
 HSPLandroid/icu/util/ULocale$Builder;->setRegion(Ljava/lang/String;)Landroid/icu/util/ULocale$Builder;
 HSPLandroid/icu/util/ULocale$JDKLocaleHelper;->getDefault(Landroid/icu/util/ULocale$Category;)Ljava/util/Locale;
 HSPLandroid/icu/util/ULocale$JDKLocaleHelper;->toLocale(Landroid/icu/util/ULocale;)Ljava/util/Locale;
-HSPLandroid/icu/util/ULocale$JDKLocaleHelper;->toULocale(Ljava/util/Locale;)Landroid/icu/util/ULocale;
+HSPLandroid/icu/util/ULocale$JDKLocaleHelper;->toULocale(Ljava/util/Locale;)Landroid/icu/util/ULocale;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/Locale;Ljava/util/Locale;]Ljava/util/Set;Ljava/util/Collections$EmptySet;
 HSPLandroid/icu/util/ULocale;->-$$Nest$smgetInstance(Landroid/icu/impl/locale/BaseLocale;Landroid/icu/impl/locale/LocaleExtensions;)Landroid/icu/util/ULocale;
 HSPLandroid/icu/util/ULocale;-><init>(Ljava/lang/String;)V
 HSPLandroid/icu/util/ULocale;-><init>(Ljava/lang/String;Ljava/util/Locale;)V
 HSPLandroid/icu/util/ULocale;-><init>(Ljava/lang/String;Ljava/util/Locale;Landroid/icu/util/ULocale-IA;)V
 HSPLandroid/icu/util/ULocale;->addLikelySubtags(Landroid/icu/util/ULocale;)Landroid/icu/util/ULocale;
 HSPLandroid/icu/util/ULocale;->appendTag(Ljava/lang/String;Ljava/lang/StringBuilder;)V
-HSPLandroid/icu/util/ULocale;->base()Landroid/icu/impl/locale/BaseLocale;
+HSPLandroid/icu/util/ULocale;->base()Landroid/icu/impl/locale/BaseLocale;+]Landroid/icu/util/ULocale;Landroid/icu/util/ULocale;]Landroid/icu/impl/LocaleIDParser;Landroid/icu/impl/LocaleIDParser;
 HSPLandroid/icu/util/ULocale;->canonicalize(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/icu/util/ULocale;->createCanonical(Ljava/lang/String;)Landroid/icu/util/ULocale;
+HSPLandroid/icu/util/ULocale;->createLikelySubtagsString(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/icu/util/ULocale;->createTagString(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/icu/util/ULocale;->createTagString(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/icu/util/ULocale;->equals(Ljava/lang/Object;)Z
 HSPLandroid/icu/util/ULocale;->forLocale(Ljava/util/Locale;)Landroid/icu/util/ULocale;
 HSPLandroid/icu/util/ULocale;->getBaseName()Ljava/lang/String;
@@ -10400,7 +10445,7 @@
 HSPLandroid/icu/util/ULocale;->getKeywords(Ljava/lang/String;)Ljava/util/Iterator;
 HSPLandroid/icu/util/ULocale;->getLanguage()Ljava/lang/String;
 HSPLandroid/icu/util/ULocale;->getName()Ljava/lang/String;
-HSPLandroid/icu/util/ULocale;->getName(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/icu/util/ULocale;->getName(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Landroid/icu/impl/CacheBase;Landroid/icu/util/ULocale$1;
 HSPLandroid/icu/util/ULocale;->getRegionForSupplementalData(Landroid/icu/util/ULocale;Z)Ljava/lang/String;
 HSPLandroid/icu/util/ULocale;->getScript()Ljava/lang/String;
 HSPLandroid/icu/util/ULocale;->getScript(Ljava/lang/String;)Ljava/lang/String;
@@ -10411,6 +10456,7 @@
 HSPLandroid/icu/util/ULocale;->isEmptyString(Ljava/lang/String;)Z
 HSPLandroid/icu/util/ULocale;->isKnownCanonicalizedLocale(Ljava/lang/String;)Z
 HSPLandroid/icu/util/ULocale;->isRightToLeft()Z
+HSPLandroid/icu/util/ULocale;->lookupLikelySubtags(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/icu/util/ULocale;->lscvToID(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/icu/util/ULocale;->parseTagString(Ljava/lang/String;[Ljava/lang/String;)I
 HSPLandroid/icu/util/ULocale;->setKeywordValue(Ljava/lang/String;Ljava/lang/String;)Landroid/icu/util/ULocale;
@@ -10483,7 +10529,7 @@
 HSPLandroid/location/Location;->toString()Ljava/lang/String;
 HSPLandroid/location/Location;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/media/AudioAttributes$1;->createFromParcel(Landroid/os/Parcel;)Landroid/media/AudioAttributes;
-HSPLandroid/media/AudioAttributes$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/media/AudioAttributes$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/media/AudioAttributes$1;Landroid/media/AudioAttributes$1;
 HSPLandroid/media/AudioAttributes$Builder;-><init>()V
 HSPLandroid/media/AudioAttributes$Builder;-><init>(Landroid/media/AudioAttributes;)V
 HSPLandroid/media/AudioAttributes$Builder;->addTag(Ljava/lang/String;)Landroid/media/AudioAttributes$Builder;
@@ -10509,7 +10555,7 @@
 HSPLandroid/media/AudioAttributes;->-$$Nest$fputmUsage(Landroid/media/AudioAttributes;I)V
 HSPLandroid/media/AudioAttributes;-><init>()V
 HSPLandroid/media/AudioAttributes;-><init>(Landroid/media/AudioAttributes-IA;)V
-HSPLandroid/media/AudioAttributes;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/media/AudioAttributes;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/media/AudioAttributes;->areHapticChannelsMuted()Z
 HSPLandroid/media/AudioAttributes;->equals(Ljava/lang/Object;)Z
 HSPLandroid/media/AudioAttributes;->getAllFlags()I
@@ -10645,7 +10691,7 @@
 HSPLandroid/media/AudioPlaybackConfiguration;->getAudioAttributes()Landroid/media/AudioAttributes;
 HSPLandroid/media/AudioPlaybackConfiguration;->isActive()Z
 HSPLandroid/media/AudioPort$$ExternalSyntheticLambda0;->applyAsInt(Ljava/lang/Object;)I
-HSPLandroid/media/AudioPort;-><init>(Landroid/media/AudioHandle;ILjava/lang/String;Ljava/util/List;[Landroid/media/AudioGain;Ljava/util/List;)V
+HSPLandroid/media/AudioPort;-><init>(Landroid/media/AudioHandle;ILjava/lang/String;Ljava/util/List;[Landroid/media/AudioGain;Ljava/util/List;)V+]Ljava/util/List;Ljava/util/ArrayList;]Ljava/util/stream/Stream;Ljava/util/stream/IntPipeline$4;,Ljava/util/stream/ReferencePipeline$Head;]Ljava/util/stream/IntStream;Ljava/util/stream/IntPipeline$Head;,Ljava/util/stream/ReferencePipeline$4;]Ljava/util/Iterator;Ljava/util/ArrayList$Itr;]Landroid/media/AudioProfile;Landroid/media/AudioProfile;]Ljava/util/Set;Ljava/util/HashSet;
 HSPLandroid/media/AudioPort;-><init>(Landroid/media/AudioHandle;ILjava/lang/String;[I[I[I[I[Landroid/media/AudioGain;)V
 HSPLandroid/media/AudioPort;->handle()Landroid/media/AudioHandle;
 HSPLandroid/media/AudioPort;->id()I
@@ -10765,8 +10811,8 @@
 HSPLandroid/media/MediaCodec$BufferMap;-><init>()V
 HSPLandroid/media/MediaCodec$BufferMap;-><init>(Landroid/media/MediaCodec$BufferMap-IA;)V
 HSPLandroid/media/MediaCodec$BufferMap;->clear()V
-HSPLandroid/media/MediaCodec$BufferMap;->put(ILjava/nio/ByteBuffer;)V
-HSPLandroid/media/MediaCodec$BufferMap;->remove(I)V
+HSPLandroid/media/MediaCodec$BufferMap;->put(ILjava/nio/ByteBuffer;)V+]Landroid/media/MediaCodec$BufferMap$CodecBuffer;Landroid/media/MediaCodec$BufferMap$CodecBuffer;]Ljava/util/Map;Ljava/util/HashMap;
+HSPLandroid/media/MediaCodec$BufferMap;->remove(I)V+]Landroid/media/MediaCodec$BufferMap$CodecBuffer;Landroid/media/MediaCodec$BufferMap$CodecBuffer;]Ljava/util/Map;Ljava/util/HashMap;
 HSPLandroid/media/MediaCodec$CryptoInfo$Pattern;-><init>(II)V
 HSPLandroid/media/MediaCodec$CryptoInfo$Pattern;->set(II)V
 HSPLandroid/media/MediaCodec$CryptoInfo;-><init>()V
@@ -10778,18 +10824,18 @@
 HSPLandroid/media/MediaCodec;->configure(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/MediaCrypto;Landroid/os/IHwBinder;I)V
 HSPLandroid/media/MediaCodec;->createByCodecName(Ljava/lang/String;)Landroid/media/MediaCodec;
 HSPLandroid/media/MediaCodec;->dequeueInputBuffer(J)I
-HSPLandroid/media/MediaCodec;->dequeueOutputBuffer(Landroid/media/MediaCodec$BufferInfo;J)I
+HSPLandroid/media/MediaCodec;->dequeueOutputBuffer(Landroid/media/MediaCodec$BufferInfo;J)I+]Landroid/media/MediaCodec$BufferInfo;Landroid/media/MediaCodec$BufferInfo;]Ljava/util/Map;Ljava/util/HashMap;
 HSPLandroid/media/MediaCodec;->finalize()V
 HSPLandroid/media/MediaCodec;->freeAllTrackedBuffers()V
-HSPLandroid/media/MediaCodec;->getInputBuffer(I)Ljava/nio/ByteBuffer;
-HSPLandroid/media/MediaCodec;->getOutputBuffer(I)Ljava/nio/ByteBuffer;
+HSPLandroid/media/MediaCodec;->getInputBuffer(I)Ljava/nio/ByteBuffer;+]Landroid/media/MediaCodec$BufferMap;Landroid/media/MediaCodec$BufferMap;
+HSPLandroid/media/MediaCodec;->getOutputBuffer(I)Ljava/nio/ByteBuffer;+]Landroid/media/MediaCodec$BufferMap;Landroid/media/MediaCodec$BufferMap;
 HSPLandroid/media/MediaCodec;->getOutputFormat()Landroid/media/MediaFormat;
-HSPLandroid/media/MediaCodec;->lockAndGetContext()J
-HSPLandroid/media/MediaCodec;->queueInputBuffer(IIIJI)V
+HSPLandroid/media/MediaCodec;->lockAndGetContext()J+]Ljava/util/concurrent/locks/Lock;Ljava/util/concurrent/locks/ReentrantLock;
+HSPLandroid/media/MediaCodec;->queueInputBuffer(IIIJI)V+]Landroid/media/MediaCodec$BufferMap;Landroid/media/MediaCodec$BufferMap;
 HSPLandroid/media/MediaCodec;->release()V
 HSPLandroid/media/MediaCodec;->releaseOutputBuffer(IZ)V
-HSPLandroid/media/MediaCodec;->releaseOutputBufferInternal(IZZJ)V
-HSPLandroid/media/MediaCodec;->setAndUnlockContext(J)V
+HSPLandroid/media/MediaCodec;->releaseOutputBufferInternal(IZZJ)V+]Landroid/media/MediaCodec$BufferMap;Landroid/media/MediaCodec$BufferMap;]Ljava/util/Map;Ljava/util/HashMap;
+HSPLandroid/media/MediaCodec;->setAndUnlockContext(J)V+]Ljava/util/concurrent/locks/Lock;Ljava/util/concurrent/locks/ReentrantLock;
 HSPLandroid/media/MediaCodec;->start()V
 HSPLandroid/media/MediaCodec;->stop()V
 HSPLandroid/media/MediaCodecInfo$AudioCapabilities;->applyLevelLimits()V
@@ -11284,6 +11330,10 @@
 HSPLandroid/metrics/LogMaker;->setComponentName(Landroid/content/ComponentName;)Landroid/metrics/LogMaker;
 HSPLandroid/metrics/LogMaker;->setSubtype(I)Landroid/metrics/LogMaker;
 HSPLandroid/metrics/LogMaker;->setType(I)Landroid/metrics/LogMaker;
+HSPLandroid/multiuser/FeatureFlagsImpl;-><init>()V
+HSPLandroid/multiuser/FeatureFlagsImpl;->enableSystemUserOnlyForServicesAndProviders()Z
+HSPLandroid/multiuser/Flags;-><clinit>()V
+HSPLandroid/multiuser/Flags;->enableSystemUserOnlyForServicesAndProviders()Z+]Landroid/multiuser/FeatureFlags;Landroid/multiuser/FeatureFlagsImpl;
 HSPLandroid/net/Credentials;-><init>(III)V
 HSPLandroid/net/Credentials;->getPid()I
 HSPLandroid/net/Credentials;->getUid()I
@@ -11376,8 +11426,8 @@
 HSPLandroid/net/TelephonyNetworkSpecifier;->hashCode()I
 HSPLandroid/net/TelephonyNetworkSpecifier;->toString()Ljava/lang/String;
 HSPLandroid/net/TelephonyNetworkSpecifier;->writeToParcel(Landroid/os/Parcel;I)V
-HSPLandroid/net/Uri$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/Uri;
-HSPLandroid/net/Uri$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/net/Uri$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/Uri;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/net/Uri$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/net/Uri$1;Landroid/net/Uri$1;
 HSPLandroid/net/Uri$1;->newArray(I)[Landroid/net/Uri;
 HSPLandroid/net/Uri$1;->newArray(I)[Ljava/lang/Object;
 HSPLandroid/net/Uri$AbstractHierarchicalUri;-><init>()V
@@ -11412,11 +11462,11 @@
 HSPLandroid/net/Uri$Builder;->path(Ljava/lang/String;)Landroid/net/Uri$Builder;
 HSPLandroid/net/Uri$Builder;->query(Landroid/net/Uri$Part;)Landroid/net/Uri$Builder;
 HSPLandroid/net/Uri$Builder;->scheme(Ljava/lang/String;)Landroid/net/Uri$Builder;
-HSPLandroid/net/Uri$Builder;->toString()Ljava/lang/String;
+HSPLandroid/net/Uri$Builder;->toString()Ljava/lang/String;+]Landroid/net/Uri$Builder;Landroid/net/Uri$Builder;]Landroid/net/Uri;Landroid/net/Uri$HierarchicalUri;
 HSPLandroid/net/Uri$HierarchicalUri;-><init>(Ljava/lang/String;Landroid/net/Uri$Part;Landroid/net/Uri$PathPart;Landroid/net/Uri$Part;Landroid/net/Uri$Part;)V
-HSPLandroid/net/Uri$HierarchicalUri;->appendSspTo(Ljava/lang/StringBuilder;)V
-HSPLandroid/net/Uri$HierarchicalUri;->buildUpon()Landroid/net/Uri$Builder;
-HSPLandroid/net/Uri$HierarchicalUri;->generatePath(Landroid/net/Uri$PathPart;)Landroid/net/Uri$PathPart;+]Landroid/net/Uri$Part;Landroid/net/Uri$Part$EmptyPart;,Landroid/net/Uri$Part;
+HSPLandroid/net/Uri$HierarchicalUri;->appendSspTo(Ljava/lang/StringBuilder;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/net/Uri$Part;Landroid/net/Uri$Part;,Landroid/net/Uri$Part$EmptyPart;]Landroid/net/Uri$PathPart;Landroid/net/Uri$PathPart;
+HSPLandroid/net/Uri$HierarchicalUri;->buildUpon()Landroid/net/Uri$Builder;+]Landroid/net/Uri$Builder;Landroid/net/Uri$Builder;
+HSPLandroid/net/Uri$HierarchicalUri;->generatePath(Landroid/net/Uri$PathPart;)Landroid/net/Uri$PathPart;+]Landroid/net/Uri$Part;Landroid/net/Uri$Part$EmptyPart;,Landroid/net/Uri$Part;]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/net/Uri$HierarchicalUri;->getAuthority()Ljava/lang/String;
 HSPLandroid/net/Uri$HierarchicalUri;->getEncodedAuthority()Ljava/lang/String;
 HSPLandroid/net/Uri$HierarchicalUri;->getEncodedFragment()Ljava/lang/String;
@@ -11429,7 +11479,7 @@
 HSPLandroid/net/Uri$HierarchicalUri;->getScheme()Ljava/lang/String;
 HSPLandroid/net/Uri$HierarchicalUri;->getSchemeSpecificPart()Ljava/lang/String;
 HSPLandroid/net/Uri$HierarchicalUri;->isHierarchical()Z
-HSPLandroid/net/Uri$HierarchicalUri;->makeUriString()Ljava/lang/String;
+HSPLandroid/net/Uri$HierarchicalUri;->makeUriString()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/net/Uri$Part;Landroid/net/Uri$Part$EmptyPart;
 HSPLandroid/net/Uri$HierarchicalUri;->readFrom(Landroid/os/Parcel;)Landroid/net/Uri;
 HSPLandroid/net/Uri$HierarchicalUri;->toString()Ljava/lang/String;
 HSPLandroid/net/Uri$HierarchicalUri;->writeToParcel(Landroid/os/Parcel;I)V
@@ -11450,13 +11500,13 @@
 HSPLandroid/net/Uri$Part;->nonNull(Landroid/net/Uri$Part;)Landroid/net/Uri$Part;
 HSPLandroid/net/Uri$PathPart;-><init>(Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/net/Uri$PathPart;->appendDecodedSegment(Landroid/net/Uri$PathPart;Ljava/lang/String;)Landroid/net/Uri$PathPart;
-HSPLandroid/net/Uri$PathPart;->appendEncodedSegment(Landroid/net/Uri$PathPart;Ljava/lang/String;)Landroid/net/Uri$PathPart;
+HSPLandroid/net/Uri$PathPart;->appendEncodedSegment(Landroid/net/Uri$PathPart;Ljava/lang/String;)Landroid/net/Uri$PathPart;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/net/Uri$PathPart;Landroid/net/Uri$PathPart;
 HSPLandroid/net/Uri$PathPart;->from(Ljava/lang/String;Ljava/lang/String;)Landroid/net/Uri$PathPart;
 HSPLandroid/net/Uri$PathPart;->fromDecoded(Ljava/lang/String;)Landroid/net/Uri$PathPart;
 HSPLandroid/net/Uri$PathPart;->fromEncoded(Ljava/lang/String;)Landroid/net/Uri$PathPart;
 HSPLandroid/net/Uri$PathPart;->getEncoded()Ljava/lang/String;
-HSPLandroid/net/Uri$PathPart;->getPathSegments()Landroid/net/Uri$PathSegments;
-HSPLandroid/net/Uri$PathPart;->makeAbsolute(Landroid/net/Uri$PathPart;)Landroid/net/Uri$PathPart;
+HSPLandroid/net/Uri$PathPart;->getPathSegments()Landroid/net/Uri$PathSegments;+]Ljava/lang/String;Ljava/lang/String;]Landroid/net/Uri$PathSegmentsBuilder;Landroid/net/Uri$PathSegmentsBuilder;]Landroid/net/Uri$PathPart;Landroid/net/Uri$PathPart;
+HSPLandroid/net/Uri$PathPart;->makeAbsolute(Landroid/net/Uri$PathPart;)Landroid/net/Uri$PathPart;+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/net/Uri$PathSegments;-><init>([Ljava/lang/String;I)V
 HSPLandroid/net/Uri$PathSegments;->get(I)Ljava/lang/Object;
 HSPLandroid/net/Uri$PathSegments;->get(I)Ljava/lang/String;
@@ -11465,9 +11515,9 @@
 HSPLandroid/net/Uri$PathSegmentsBuilder;->build()Landroid/net/Uri$PathSegments;
 HSPLandroid/net/Uri$StringUri;-><init>(Ljava/lang/String;)V
 HSPLandroid/net/Uri$StringUri;-><init>(Ljava/lang/String;Landroid/net/Uri$StringUri-IA;)V
-HSPLandroid/net/Uri$StringUri;->buildUpon()Landroid/net/Uri$Builder;
-HSPLandroid/net/Uri$StringUri;->findFragmentSeparator()I
-HSPLandroid/net/Uri$StringUri;->findSchemeSeparator()I
+HSPLandroid/net/Uri$StringUri;->buildUpon()Landroid/net/Uri$Builder;+]Landroid/net/Uri$Builder;Landroid/net/Uri$Builder;]Landroid/net/Uri$StringUri;Landroid/net/Uri$StringUri;
+HSPLandroid/net/Uri$StringUri;->findFragmentSeparator()I+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/net/Uri$StringUri;->findSchemeSeparator()I+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->getAuthority()Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->getAuthorityPart()Landroid/net/Uri$Part;
 HSPLandroid/net/Uri$StringUri;->getEncodedAuthority()Ljava/lang/String;
@@ -11485,11 +11535,11 @@
 HSPLandroid/net/Uri$StringUri;->getSchemeSpecificPart()Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->isHierarchical()Z
 HSPLandroid/net/Uri$StringUri;->isRelative()Z
-HSPLandroid/net/Uri$StringUri;->parseAuthority(Ljava/lang/String;I)Ljava/lang/String;
+HSPLandroid/net/Uri$StringUri;->parseAuthority(Ljava/lang/String;I)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->parseFragment()Ljava/lang/String;
-HSPLandroid/net/Uri$StringUri;->parsePath()Ljava/lang/String;
+HSPLandroid/net/Uri$StringUri;->parsePath()Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->parsePath(Ljava/lang/String;I)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
-HSPLandroid/net/Uri$StringUri;->parseQuery()Ljava/lang/String;
+HSPLandroid/net/Uri$StringUri;->parseQuery()Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->parseScheme()Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->toString()Ljava/lang/String;
 HSPLandroid/net/Uri$StringUri;->writeToParcel(Landroid/os/Parcel;I)V
@@ -11506,8 +11556,8 @@
 HSPLandroid/net/Uri;->fromFile(Ljava/io/File;)Landroid/net/Uri;
 HSPLandroid/net/Uri;->fromParts(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/net/Uri;
 HSPLandroid/net/Uri;->getBooleanQueryParameter(Ljava/lang/String;Z)Z
-HSPLandroid/net/Uri;->getQueryParameter(Ljava/lang/String;)Ljava/lang/String;+]Landroid/net/Uri;Landroid/net/Uri$StringUri;]Ljava/lang/String;Ljava/lang/String;
-HSPLandroid/net/Uri;->getQueryParameterNames()Ljava/util/Set;+]Landroid/net/Uri;Landroid/net/Uri$StringUri;]Ljava/lang/String;Ljava/lang/String;]Ljava/util/Set;Ljava/util/LinkedHashSet;
+HSPLandroid/net/Uri;->getQueryParameter(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
+HSPLandroid/net/Uri;->getQueryParameterNames()Ljava/util/Set;+]Ljava/lang/String;Ljava/lang/String;]Ljava/util/Set;Ljava/util/LinkedHashSet;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
 HSPLandroid/net/Uri;->hashCode()I
 HSPLandroid/net/Uri;->isAbsolute()Z
 HSPLandroid/net/Uri;->isAllowed(CLjava/lang/String;)Z+]Ljava/lang/String;Ljava/lang/String;
@@ -11517,9 +11567,9 @@
 HSPLandroid/net/Uri;->toSafeString()Ljava/lang/String;
 HSPLandroid/net/Uri;->withAppendedPath(Landroid/net/Uri;Ljava/lang/String;)Landroid/net/Uri;
 HSPLandroid/net/Uri;->writeToParcel(Landroid/os/Parcel;Landroid/net/Uri;)V
-HSPLandroid/net/UriCodec;->appendDecoded(Ljava/lang/StringBuilder;Ljava/lang/String;ZLjava/nio/charset/Charset;Z)V+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;]Ljava/nio/charset/Charset;Lcom/android/icu/charset/CharsetICU;]Ljava/nio/charset/CharsetDecoder;Lcom/android/icu/charset/CharsetDecoderICU;
+HSPLandroid/net/UriCodec;->appendDecoded(Ljava/lang/StringBuilder;Ljava/lang/String;ZLjava/nio/charset/Charset;Z)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/String;Ljava/lang/String;]Ljava/nio/charset/Charset;Lcom/android/icu/charset/CharsetICU;]Ljava/nio/charset/CharsetDecoder;Lcom/android/icu/charset/CharsetDecoderICU;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
 HSPLandroid/net/UriCodec;->decode(Ljava/lang/String;ZLjava/nio/charset/Charset;Z)Ljava/lang/String;
-HSPLandroid/net/UriCodec;->flushDecodingByteAccumulator(Ljava/lang/StringBuilder;Ljava/nio/charset/CharsetDecoder;Ljava/nio/ByteBuffer;Z)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;]Ljava/nio/charset/CharsetDecoder;Lcom/android/icu/charset/CharsetDecoderICU;
+HSPLandroid/net/UriCodec;->flushDecodingByteAccumulator(Ljava/lang/StringBuilder;Ljava/nio/charset/CharsetDecoder;Ljava/nio/ByteBuffer;Z)V+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/nio/charset/CharsetDecoder;Lcom/android/icu/charset/CharsetDecoderICU;
 HSPLandroid/net/UriCodec;->getNextCharacter(Ljava/lang/String;IILjava/lang/String;)C
 HSPLandroid/net/UriCodec;->hexCharToValue(C)I
 HSPLandroid/net/WebAddress;-><init>(Ljava/lang/String;)V
@@ -11536,6 +11586,7 @@
 HSPLandroid/net/vcn/VcnTransportInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/net/vcn/VcnTransportInfo;
 HSPLandroid/net/vcn/VcnTransportInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/net/vcn/VcnTransportInfo;-><clinit>()V
+HSPLandroid/nfc/NfcFrameworkInitializer;->setNfcServiceManager(Landroid/nfc/NfcServiceManager;)V
 HSPLandroid/nfc/NfcServiceManager;-><init>()V
 HSPLandroid/nfc/cardemulation/AidGroup$1;->createFromParcel(Landroid/os/Parcel;)Landroid/nfc/cardemulation/AidGroup;
 HSPLandroid/nfc/cardemulation/AidGroup$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -11587,13 +11638,13 @@
 HSPLandroid/os/BaseBundle;-><init>()V
 HSPLandroid/os/BaseBundle;-><init>(I)V
 HSPLandroid/os/BaseBundle;-><init>(Landroid/os/BaseBundle;)V
-HSPLandroid/os/BaseBundle;-><init>(Landroid/os/BaseBundle;Z)V
+HSPLandroid/os/BaseBundle;-><init>(Landroid/os/BaseBundle;Z)V+]Landroid/os/BaseBundle;Landroid/os/Bundle;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/BaseBundle;-><init>(Landroid/os/Parcel;I)V
-HSPLandroid/os/BaseBundle;-><init>(Ljava/lang/ClassLoader;I)V+]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;-><init>(Ljava/lang/ClassLoader;I)V+]Ljava/lang/Object;Landroid/os/Bundle;,Landroid/os/PersistableBundle;]Ljava/lang/Class;Ljava/lang/Class;
 HSPLandroid/os/BaseBundle;->clear()V
 HSPLandroid/os/BaseBundle;->containsKey(Ljava/lang/String;)Z
 HSPLandroid/os/BaseBundle;->deepCopyValue(Ljava/lang/Object;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->get(Ljava/lang/String;)Ljava/lang/Object;
+HSPLandroid/os/BaseBundle;->get(Ljava/lang/String;)Ljava/lang/Object;+]Landroid/os/BaseBundle;Landroid/os/Bundle;
 HSPLandroid/os/BaseBundle;->get(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
 HSPLandroid/os/BaseBundle;->getArrayList(Ljava/lang/String;Ljava/lang/Class;)Ljava/util/ArrayList;
 HSPLandroid/os/BaseBundle;->getBoolean(Ljava/lang/String;)Z
@@ -11602,9 +11653,9 @@
 HSPLandroid/os/BaseBundle;->getByteArray(Ljava/lang/String;)[B
 HSPLandroid/os/BaseBundle;->getCharSequence(Ljava/lang/String;)Ljava/lang/CharSequence;
 HSPLandroid/os/BaseBundle;->getCharSequenceArray(Ljava/lang/String;)[Ljava/lang/CharSequence;
-HSPLandroid/os/BaseBundle;->getFloat(Ljava/lang/String;F)F
+HSPLandroid/os/BaseBundle;->getFloat(Ljava/lang/String;F)F+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Float;Ljava/lang/Float;]Landroid/os/BaseBundle;Landroid/os/Bundle;
 HSPLandroid/os/BaseBundle;->getInt(Ljava/lang/String;)I
-HSPLandroid/os/BaseBundle;->getInt(Ljava/lang/String;I)I
+HSPLandroid/os/BaseBundle;->getInt(Ljava/lang/String;I)I+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Integer;Ljava/lang/Integer;]Landroid/os/BaseBundle;Landroid/os/Bundle;
 HSPLandroid/os/BaseBundle;->getIntArray(Ljava/lang/String;)[I
 HSPLandroid/os/BaseBundle;->getIntegerArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
 HSPLandroid/os/BaseBundle;->getLong(Ljava/lang/String;)J
@@ -11614,18 +11665,18 @@
 HSPLandroid/os/BaseBundle;->getSerializable(Ljava/lang/String;Ljava/lang/Class;)Ljava/io/Serializable;
 HSPLandroid/os/BaseBundle;->getString(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/os/BaseBundle;->getString(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/os/BaseBundle;->getStringArray(Ljava/lang/String;)[Ljava/lang/String;
+HSPLandroid/os/BaseBundle;->getStringArray(Ljava/lang/String;)[Ljava/lang/String;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
 HSPLandroid/os/BaseBundle;->getStringArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
-HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->getValueAt(ILjava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/BaseBundle;->initializeFromParcelLocked(Landroid/os/Parcel;ZZ)V
-HSPLandroid/os/BaseBundle;->isEmpty()Z
+HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;)Ljava/lang/Object;+]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->getValue(Ljava/lang/String;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->getValueAt(ILjava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Class;Ljava/lang/Class;
+HSPLandroid/os/BaseBundle;->initializeFromParcelLocked(Landroid/os/Parcel;ZZ)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/BaseBundle;->isEmpty()Z+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
 HSPLandroid/os/BaseBundle;->isEmptyParcel()Z
 HSPLandroid/os/BaseBundle;->isEmptyParcel(Landroid/os/Parcel;)Z
 HSPLandroid/os/BaseBundle;->isParcelled()Z
-HSPLandroid/os/BaseBundle;->keySet()Ljava/util/Set;+]Landroid/os/BaseBundle;Landroid/os/Bundle;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/os/BaseBundle;->keySet()Ljava/util/Set;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
 HSPLandroid/os/BaseBundle;->putAll(Landroid/os/PersistableBundle;)V
 HSPLandroid/os/BaseBundle;->putAll(Landroid/util/ArrayMap;)V
 HSPLandroid/os/BaseBundle;->putBoolean(Ljava/lang/String;Z)V
@@ -11634,7 +11685,7 @@
 HSPLandroid/os/BaseBundle;->putCharSequence(Ljava/lang/String;Ljava/lang/CharSequence;)V
 HSPLandroid/os/BaseBundle;->putCharSequenceArray(Ljava/lang/String;[Ljava/lang/CharSequence;)V
 HSPLandroid/os/BaseBundle;->putDouble(Ljava/lang/String;D)V
-HSPLandroid/os/BaseBundle;->putFloat(Ljava/lang/String;F)V
+HSPLandroid/os/BaseBundle;->putFloat(Ljava/lang/String;F)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
 HSPLandroid/os/BaseBundle;->putInt(Ljava/lang/String;I)V
 HSPLandroid/os/BaseBundle;->putIntArray(Ljava/lang/String;[I)V
 HSPLandroid/os/BaseBundle;->putLong(Ljava/lang/String;J)V
@@ -11644,16 +11695,16 @@
 HSPLandroid/os/BaseBundle;->putStringArray(Ljava/lang/String;[Ljava/lang/String;)V
 HSPLandroid/os/BaseBundle;->putStringArrayList(Ljava/lang/String;Ljava/util/ArrayList;)V
 HSPLandroid/os/BaseBundle;->readFromParcelInner(Landroid/os/Parcel;)V
-HSPLandroid/os/BaseBundle;->readFromParcelInner(Landroid/os/Parcel;I)V
-HSPLandroid/os/BaseBundle;->recycleParcel(Landroid/os/Parcel;)V
+HSPLandroid/os/BaseBundle;->readFromParcelInner(Landroid/os/Parcel;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/BaseBundle;->recycleParcel(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/BaseBundle;->remove(Ljava/lang/String;)V
 HSPLandroid/os/BaseBundle;->setClassLoader(Ljava/lang/ClassLoader;)V
 HSPLandroid/os/BaseBundle;->setShouldDefuse(Z)V
-HSPLandroid/os/BaseBundle;->size()I
-HSPLandroid/os/BaseBundle;->unparcel()V+]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->size()I+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/BaseBundle;Landroid/os/Bundle;
+HSPLandroid/os/BaseBundle;->unparcel()V+]Landroid/os/BaseBundle;Landroid/os/Bundle;,Landroid/os/PersistableBundle;
 HSPLandroid/os/BaseBundle;->unparcel(Z)V
-HSPLandroid/os/BaseBundle;->unwrapLazyValueFromMapLocked(ILjava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;]Ljava/util/function/BiFunction;Landroid/os/Parcel$LazyValue;
-HSPLandroid/os/BaseBundle;->writeToParcelInner(Landroid/os/Parcel;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/os/BaseBundle;->unwrapLazyValueFromMapLocked(ILjava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/function/BiFunction;Landroid/os/Parcel$LazyValue;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;
+HSPLandroid/os/BaseBundle;->writeToParcelInner(Landroid/os/Parcel;I)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/BatteryManager;-><init>(Landroid/content/Context;Lcom/android/internal/app/IBatteryStats;Landroid/os/IBatteryPropertiesRegistrar;)V
 HSPLandroid/os/BatteryManager;->getIntProperty(I)I
 HSPLandroid/os/BatteryManager;->getLongProperty(I)J
@@ -11720,12 +11771,12 @@
 HSPLandroid/os/Binder;->transact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/os/Binder;->unlinkToDeath(Landroid/os/IBinder$DeathRecipient;I)Z
 HSPLandroid/os/Binder;->withCleanCallingIdentity(Lcom/android/internal/util/FunctionalUtils$ThrowingRunnable;)V
-HSPLandroid/os/BinderProxy$ProxyMap;->get(J)Landroid/os/BinderProxy;+]Ljava/lang/Long;Ljava/lang/Long;]Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/os/BinderProxy$ProxyMap;->get(J)Landroid/os/BinderProxy;
 HSPLandroid/os/BinderProxy$ProxyMap;->hash(J)I
 HSPLandroid/os/BinderProxy$ProxyMap;->remove(II)V
 HSPLandroid/os/BinderProxy$ProxyMap;->set(JLandroid/os/BinderProxy;)V
 HSPLandroid/os/BinderProxy;-><init>(J)V
-HSPLandroid/os/BinderProxy;->getInstance(JJ)Landroid/os/BinderProxy;+]Landroid/os/BinderProxy$ProxyMap;Landroid/os/BinderProxy$ProxyMap;]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
+HSPLandroid/os/BinderProxy;->getInstance(JJ)Landroid/os/BinderProxy;
 HSPLandroid/os/BinderProxy;->linkToDeath(Landroid/os/IBinder$DeathRecipient;I)V+]Ljava/util/List;Ljava/util/Collections$SynchronizedRandomAccessList;
 HSPLandroid/os/BinderProxy;->queryLocalInterface(Ljava/lang/String;)Landroid/os/IInterface;
 HSPLandroid/os/BinderProxy;->sendDeathNotice(Landroid/os/IBinder$DeathRecipient;Landroid/os/IBinder;)V
@@ -11764,7 +11815,7 @@
 HSPLandroid/os/Bundle;->getIntegerArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
 HSPLandroid/os/Bundle;->getParcelable(Ljava/lang/String;)Landroid/os/Parcelable;
 HSPLandroid/os/Bundle;->getParcelable(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/Bundle;->getParcelableArray(Ljava/lang/String;)[Landroid/os/Parcelable;
+HSPLandroid/os/Bundle;->getParcelableArray(Ljava/lang/String;)[Landroid/os/Parcelable;+]Landroid/os/Bundle;Landroid/os/Bundle;
 HSPLandroid/os/Bundle;->getParcelableArray(Ljava/lang/String;Ljava/lang/Class;)[Ljava/lang/Object;
 HSPLandroid/os/Bundle;->getParcelableArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
 HSPLandroid/os/Bundle;->getSerializable(Ljava/lang/String;)Ljava/io/Serializable;
@@ -11772,10 +11823,10 @@
 HSPLandroid/os/Bundle;->getSparseParcelableArray(Ljava/lang/String;)Landroid/util/SparseArray;
 HSPLandroid/os/Bundle;->getStringArrayList(Ljava/lang/String;)Ljava/util/ArrayList;
 HSPLandroid/os/Bundle;->hasFileDescriptors()Z
-HSPLandroid/os/Bundle;->maybePrefillHasFds()V
+HSPLandroid/os/Bundle;->maybePrefillHasFds()V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Bundle;->putAll(Landroid/os/Bundle;)V
 HSPLandroid/os/Bundle;->putBinder(Ljava/lang/String;Landroid/os/IBinder;)V
-HSPLandroid/os/Bundle;->putBundle(Ljava/lang/String;Landroid/os/Bundle;)V+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/os/Bundle;->putBundle(Ljava/lang/String;Landroid/os/Bundle;)V
 HSPLandroid/os/Bundle;->putByteArray(Ljava/lang/String;[B)V
 HSPLandroid/os/Bundle;->putCharSequence(Ljava/lang/String;Ljava/lang/CharSequence;)V
 HSPLandroid/os/Bundle;->putCharSequenceArray(Ljava/lang/String;[Ljava/lang/CharSequence;)V
@@ -11942,7 +11993,7 @@
 HSPLandroid/os/FileObserver;-><init>(Ljava/lang/String;I)V
 HSPLandroid/os/FileObserver;-><init>(Ljava/util/List;I)V
 HSPLandroid/os/FileObserver;->startWatching()V
-HSPLandroid/os/FileUtils;->buildValidExtFilename(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/os/FileUtils;->buildValidExtFilename(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/Object;Ljava/lang/String;
 HSPLandroid/os/FileUtils;->bytesToFile(Ljava/lang/String;[B)V
 HSPLandroid/os/FileUtils;->closeQuietly(Ljava/lang/AutoCloseable;)V
 HSPLandroid/os/FileUtils;->contains(Ljava/io/File;Ljava/io/File;)Z
@@ -12014,7 +12065,7 @@
 HSPLandroid/os/Handler;->obtainMessage(ILjava/lang/Object;)Landroid/os/Message;
 HSPLandroid/os/Handler;->post(Ljava/lang/Runnable;)Z+]Landroid/os/Handler;missing_types
 HSPLandroid/os/Handler;->postAtFrontOfQueue(Ljava/lang/Runnable;)Z
-HSPLandroid/os/Handler;->postAtTime(Ljava/lang/Runnable;J)Z
+HSPLandroid/os/Handler;->postAtTime(Ljava/lang/Runnable;J)Z+]Landroid/os/Handler;Landroid/view/ViewRootImpl$ViewRootHandler;
 HSPLandroid/os/Handler;->postAtTime(Ljava/lang/Runnable;Ljava/lang/Object;J)Z
 HSPLandroid/os/Handler;->postDelayed(Ljava/lang/Runnable;IJ)Z
 HSPLandroid/os/Handler;->postDelayed(Ljava/lang/Runnable;J)Z
@@ -12027,7 +12078,7 @@
 HSPLandroid/os/Handler;->sendEmptyMessage(I)Z
 HSPLandroid/os/Handler;->sendEmptyMessageAtTime(IJ)Z
 HSPLandroid/os/Handler;->sendEmptyMessageDelayed(IJ)Z
-HSPLandroid/os/Handler;->sendMessage(Landroid/os/Message;)Z
+HSPLandroid/os/Handler;->sendMessage(Landroid/os/Message;)Z+]Landroid/os/Handler;missing_types
 HSPLandroid/os/Handler;->sendMessageAtFrontOfQueue(Landroid/os/Message;)Z
 HSPLandroid/os/Handler;->sendMessageAtTime(Landroid/os/Message;J)Z
 HSPLandroid/os/Handler;->sendMessageDelayed(Landroid/os/Message;J)Z+]Landroid/os/Handler;missing_types
@@ -12073,6 +12124,7 @@
 HSPLandroid/os/IDeviceIdleController$Stub$Proxy;->isPowerSaveWhitelistApp(Ljava/lang/String;)Z
 HSPLandroid/os/IDeviceIdleController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IDeviceIdleController;
 HSPLandroid/os/IHintManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+HSPLandroid/os/IHintManager$Stub$Proxy;->createHintSession(Landroid/os/IBinder;[IJ)Landroid/os/IHintSession;
 HSPLandroid/os/IHintManager$Stub$Proxy;->getHintSessionPreferredRate()J
 HSPLandroid/os/IHintManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IHintManager;
 HSPLandroid/os/IHintSession$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IHintSession;
@@ -12167,14 +12219,14 @@
 HSPLandroid/os/IpcDataCache;-><init>(Landroid/os/IpcDataCache$Config;Landroid/os/IpcDataCache$QueryHandler;)V
 HSPLandroid/os/IpcDataCache;-><init>(Landroid/os/IpcDataCache$Config;Landroid/os/IpcDataCache$RemoteCall;)V
 HSPLandroid/os/IpcDataCache;->query(Ljava/lang/Object;)Ljava/lang/Object;
-HSPLandroid/os/LocaleList$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/LocaleList;+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/os/LocaleList$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/os/LocaleList$1;Landroid/os/LocaleList$1;
-HSPLandroid/os/LocaleList;-><init>([Ljava/util/Locale;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/HashSet;Ljava/util/HashSet;]Ljava/util/Locale;Ljava/util/Locale;
+HSPLandroid/os/LocaleList$1;->createFromParcel(Landroid/os/Parcel;)Landroid/os/LocaleList;
+HSPLandroid/os/LocaleList$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/os/LocaleList;-><init>([Ljava/util/Locale;)V
 HSPLandroid/os/LocaleList;->computeFirstMatch(Ljava/util/Collection;Z)Ljava/util/Locale;
 HSPLandroid/os/LocaleList;->computeFirstMatchIndex(Ljava/util/Collection;Z)I
-HSPLandroid/os/LocaleList;->equals(Ljava/lang/Object;)Z
+HSPLandroid/os/LocaleList;->equals(Ljava/lang/Object;)Z+]Ljava/lang/Object;Ljava/util/Locale;
 HSPLandroid/os/LocaleList;->findFirstMatchIndex(Ljava/util/Locale;)I
-HSPLandroid/os/LocaleList;->forLanguageTags(Ljava/lang/String;)Landroid/os/LocaleList;+]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/os/LocaleList;->forLanguageTags(Ljava/lang/String;)Landroid/os/LocaleList;
 HSPLandroid/os/LocaleList;->get(I)Ljava/util/Locale;
 HSPLandroid/os/LocaleList;->getAdjustedDefault()Landroid/os/LocaleList;
 HSPLandroid/os/LocaleList;->getDefault()Landroid/os/LocaleList;+]Ljava/lang/Object;Ljava/util/Locale;
@@ -12196,10 +12248,10 @@
 HSPLandroid/os/Looper;->getMainLooper()Landroid/os/Looper;
 HSPLandroid/os/Looper;->getQueue()Landroid/os/MessageQueue;
 HSPLandroid/os/Looper;->getThread()Ljava/lang/Thread;
-HSPLandroid/os/Looper;->getThresholdOverride()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/Thread;Landroid/os/HandlerThread;
+HSPLandroid/os/Looper;->getThresholdOverride()I+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/Thread;missing_types
 HSPLandroid/os/Looper;->isCurrentThread()Z
 HSPLandroid/os/Looper;->loop()V
-HSPLandroid/os/Looper;->loopOnce(Landroid/os/Looper;JI)Z+]Landroid/os/Handler;missing_types]Landroid/os/Message;Landroid/os/Message;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;
+HSPLandroid/os/Looper;->loopOnce(Landroid/os/Looper;JI)Z+]Landroid/os/Handler;megamorphic_types]Landroid/os/Message;Landroid/os/Message;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;
 HSPLandroid/os/Looper;->myLooper()Landroid/os/Looper;+]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal;
 HSPLandroid/os/Looper;->myQueue()Landroid/os/MessageQueue;
 HSPLandroid/os/Looper;->prepare()V
@@ -12233,7 +12285,7 @@
 HSPLandroid/os/Message;->readFromParcel(Landroid/os/Parcel;)V
 HSPLandroid/os/Message;->recycle()V
 HSPLandroid/os/Message;->recycleUnchecked()V
-HSPLandroid/os/Message;->sendToTarget()V
+HSPLandroid/os/Message;->sendToTarget()V+]Landroid/os/Handler;megamorphic_types
 HSPLandroid/os/Message;->setAsynchronous(Z)V
 HSPLandroid/os/Message;->setCallback(Ljava/lang/Runnable;)Landroid/os/Message;
 HSPLandroid/os/Message;->setData(Landroid/os/Bundle;)V
@@ -12252,13 +12304,13 @@
 HSPLandroid/os/MessageQueue;->finalize()V
 HSPLandroid/os/MessageQueue;->hasMessages(Landroid/os/Handler;ILjava/lang/Object;)Z
 HSPLandroid/os/MessageQueue;->hasMessages(Landroid/os/Handler;Ljava/lang/Runnable;Ljava/lang/Object;)Z
-HSPLandroid/os/MessageQueue;->next()Landroid/os/Message;+]Landroid/os/Message;Landroid/os/Message;]Landroid/os/MessageQueue$IdleHandler;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/os/MessageQueue;->next()Landroid/os/Message;+]Landroid/os/MessageQueue$IdleHandler;missing_types]Landroid/os/Message;Landroid/os/Message;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/os/MessageQueue;->postSyncBarrier()I
 HSPLandroid/os/MessageQueue;->postSyncBarrier(J)I+]Landroid/os/Message;Landroid/os/Message;
 HSPLandroid/os/MessageQueue;->quit(Z)V
 HSPLandroid/os/MessageQueue;->removeAllFutureMessagesLocked()V
 HSPLandroid/os/MessageQueue;->removeAllMessagesLocked()V
-HSPLandroid/os/MessageQueue;->removeCallbacksAndMessages(Landroid/os/Handler;Ljava/lang/Object;)V+]Landroid/os/Message;Landroid/os/Message;
+HSPLandroid/os/MessageQueue;->removeCallbacksAndMessages(Landroid/os/Handler;Ljava/lang/Object;)V
 HSPLandroid/os/MessageQueue;->removeIdleHandler(Landroid/os/MessageQueue$IdleHandler;)V
 HSPLandroid/os/MessageQueue;->removeMessages(Landroid/os/Handler;ILjava/lang/Object;)V+]Landroid/os/Message;Landroid/os/Message;
 HSPLandroid/os/MessageQueue;->removeMessages(Landroid/os/Handler;Ljava/lang/Runnable;Ljava/lang/Object;)V+]Landroid/os/Message;Landroid/os/Message;
@@ -12279,12 +12331,12 @@
 HSPLandroid/os/Parcel$2;->resolveClass(Ljava/io/ObjectStreamClass;)Ljava/lang/Class;+]Ljava/io/ObjectStreamClass;Ljava/io/ObjectStreamClass;
 HSPLandroid/os/Parcel$LazyValue;-><init>(Landroid/os/Parcel;IIILjava/lang/ClassLoader;)V
 HSPLandroid/os/Parcel$LazyValue;->apply(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/os/Parcel$LazyValue;->apply(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/os/Parcel$LazyValue;->apply(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+]Landroid/os/Parcel$LazyValue;Landroid/os/Parcel$LazyValue;
 HSPLandroid/os/Parcel$LazyValue;->writeToParcel(Landroid/os/Parcel;)V
 HSPLandroid/os/Parcel$ReadWriteHelper;->readString16(Landroid/os/Parcel;)Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel$ReadWriteHelper;->readString8(Landroid/os/Parcel;)Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel$ReadWriteHelper;->writeString16(Landroid/os/Parcel;Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/os/Parcel$ReadWriteHelper;->writeString8(Landroid/os/Parcel;Ljava/lang/String;)V
+HSPLandroid/os/Parcel$ReadWriteHelper;->writeString8(Landroid/os/Parcel;Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->-$$Nest$mreadValue(Landroid/os/Parcel;Ljava/lang/ClassLoader;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;
 HSPLandroid/os/Parcel;-><init>(J)V
 HSPLandroid/os/Parcel;->adoptClassCookies(Landroid/os/Parcel;)V
@@ -12297,21 +12349,21 @@
 HSPLandroid/os/Parcel;->createByteArray()[B
 HSPLandroid/os/Parcel;->createException(ILjava/lang/String;)Ljava/lang/Exception;
 HSPLandroid/os/Parcel;->createExceptionOrNull(ILjava/lang/String;)Ljava/lang/Exception;
-HSPLandroid/os/Parcel;->createFloatArray()[F+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->createFloatArray()[F
 HSPLandroid/os/Parcel;->createIntArray()[I+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/os/Parcel;->createLongArray()[J
+HSPLandroid/os/Parcel;->createLongArray()[J+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->createString16Array()[Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->createString8Array()[Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->createStringArray()[Ljava/lang/String;
-HSPLandroid/os/Parcel;->createStringArrayList()Ljava/util/ArrayList;
-HSPLandroid/os/Parcel;->createTypedArray(Landroid/os/Parcelable$Creator;)[Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;missing_types
-HSPLandroid/os/Parcel;->createTypedArrayList(Landroid/os/Parcelable$Creator;)Ljava/util/ArrayList;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/os/Parcel;->createStringArrayList()Ljava/util/ArrayList;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->createTypedArray(Landroid/os/Parcelable$Creator;)[Ljava/lang/Object;+]Landroid/os/Parcelable$Creator;missing_types]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->createTypedArrayList(Landroid/os/Parcelable$Creator;)Ljava/util/ArrayList;+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->dataAvail()I
 HSPLandroid/os/Parcel;->dataPosition()I
 HSPLandroid/os/Parcel;->dataSize()I
 HSPLandroid/os/Parcel;->destroy()V
 HSPLandroid/os/Parcel;->enforceInterface(Ljava/lang/String;)V
-HSPLandroid/os/Parcel;->enforceNoDataAvail()V
+HSPLandroid/os/Parcel;->enforceNoDataAvail()V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->ensureReadSquashableParcelables()V
 HSPLandroid/os/Parcel;->ensureWithinMemoryLimit(II)V
 HSPLandroid/os/Parcel;->finalize()V
@@ -12333,33 +12385,33 @@
 HSPLandroid/os/Parcel;->pushAllowFds(Z)Z
 HSPLandroid/os/Parcel;->readArrayList(Ljava/lang/ClassLoader;)Ljava/util/ArrayList;
 HSPLandroid/os/Parcel;->readArrayList(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/ArrayList;
-HSPLandroid/os/Parcel;->readArrayListInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/ArrayList;
-HSPLandroid/os/Parcel;->readArrayMap(Landroid/util/ArrayMap;IZZLjava/lang/ClassLoader;)I
+HSPLandroid/os/Parcel;->readArrayListInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/ArrayList;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readArrayMap(Landroid/util/ArrayMap;IZZLjava/lang/ClassLoader;)I+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readArrayMap(Landroid/util/ArrayMap;Ljava/lang/ClassLoader;)V
 HSPLandroid/os/Parcel;->readArrayMapInternal(Landroid/util/ArrayMap;ILjava/lang/ClassLoader;)V
-HSPLandroid/os/Parcel;->readArraySet(Ljava/lang/ClassLoader;)Landroid/util/ArraySet;+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/ArraySet;Landroid/util/ArraySet;
+HSPLandroid/os/Parcel;->readArraySet(Ljava/lang/ClassLoader;)Landroid/util/ArraySet;
 HSPLandroid/os/Parcel;->readBinderList(Ljava/util/List;)V
 HSPLandroid/os/Parcel;->readBlob()[B
 HSPLandroid/os/Parcel;->readBoolean()Z+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readBooleanArray([Z)V
-HSPLandroid/os/Parcel;->readBundle()Landroid/os/Bundle;
-HSPLandroid/os/Parcel;->readBundle(Ljava/lang/ClassLoader;)Landroid/os/Bundle;
-HSPLandroid/os/Parcel;->readByte()B
+HSPLandroid/os/Parcel;->readBundle()Landroid/os/Bundle;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readBundle(Ljava/lang/ClassLoader;)Landroid/os/Bundle;+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readByte()B+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readByteArray([B)V
 HSPLandroid/os/Parcel;->readCallingWorkSourceUid()I
-HSPLandroid/os/Parcel;->readCharSequence()Ljava/lang/CharSequence;
+HSPLandroid/os/Parcel;->readCharSequence()Ljava/lang/CharSequence;+]Landroid/os/Parcelable$Creator;Landroid/text/TextUtils$1;
 HSPLandroid/os/Parcel;->readCharSequenceArray()[Ljava/lang/CharSequence;
 HSPLandroid/os/Parcel;->readDouble()D
-HSPLandroid/os/Parcel;->readException()V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readException()V
 HSPLandroid/os/Parcel;->readException(ILjava/lang/String;)V
-HSPLandroid/os/Parcel;->readExceptionCode()I+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readExceptionCode()I
 HSPLandroid/os/Parcel;->readFloat()F
 HSPLandroid/os/Parcel;->readFloatArray([F)V
 HSPLandroid/os/Parcel;->readHashMap(Ljava/lang/ClassLoader;)Ljava/util/HashMap;
 HSPLandroid/os/Parcel;->readHashMapInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;Ljava/lang/Class;)Ljava/util/HashMap;
 HSPLandroid/os/Parcel;->readInt()I
 HSPLandroid/os/Parcel;->readIntArray([I)V
-HSPLandroid/os/Parcel;->readLazyValue(Ljava/lang/ClassLoader;)Ljava/lang/Object;
+HSPLandroid/os/Parcel;->readLazyValue(Ljava/lang/ClassLoader;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readList(Ljava/util/List;Ljava/lang/ClassLoader;)V
 HSPLandroid/os/Parcel;->readList(Ljava/util/List;Ljava/lang/ClassLoader;Ljava/lang/Class;)V
 HSPLandroid/os/Parcel;->readListInternal(Ljava/util/List;ILjava/lang/ClassLoader;)V
@@ -12373,25 +12425,25 @@
 HSPLandroid/os/Parcel;->readParcelable(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;
 HSPLandroid/os/Parcel;->readParcelableArray(Ljava/lang/ClassLoader;)[Landroid/os/Parcelable;
 HSPLandroid/os/Parcel;->readParcelableArray(Ljava/lang/ClassLoader;Ljava/lang/Class;)[Ljava/lang/Object;
-HSPLandroid/os/Parcel;->readParcelableArrayInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)[Ljava/lang/Object;
+HSPLandroid/os/Parcel;->readParcelableArrayInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)[Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readParcelableCreator(Ljava/lang/ClassLoader;)Landroid/os/Parcelable$Creator;
-HSPLandroid/os/Parcel;->readParcelableCreatorInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Landroid/os/Parcelable$Creator;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/reflect/Field;Ljava/lang/reflect/Field;]Ljava/util/HashMap;Ljava/util/HashMap;
-HSPLandroid/os/Parcel;->readParcelableInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcelable$Creator;megamorphic_types
+HSPLandroid/os/Parcel;->readParcelableCreatorInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Landroid/os/Parcelable$Creator;+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Object;Landroid/os/Parcel;]Ljava/lang/reflect/Field;Ljava/lang/reflect/Field;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readParcelableInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcelable$Creator;megamorphic_types]Landroid/os/Parcelable$ClassLoaderCreator;Landroid/content/pm/ParceledListSlice$1;
 HSPLandroid/os/Parcel;->readParcelableList(Ljava/util/List;Ljava/lang/ClassLoader;)Ljava/util/List;
 HSPLandroid/os/Parcel;->readParcelableList(Ljava/util/List;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/List;
-HSPLandroid/os/Parcel;->readParcelableListInternal(Ljava/util/List;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/List;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/os/Parcel;->readParcelableListInternal(Ljava/util/List;Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/util/List;+]Ljava/util/List;Ljava/util/ArrayList;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readPersistableBundle()Landroid/os/PersistableBundle;
 HSPLandroid/os/Parcel;->readPersistableBundle(Ljava/lang/ClassLoader;)Landroid/os/PersistableBundle;
 HSPLandroid/os/Parcel;->readRawFileDescriptor()Ljava/io/FileDescriptor;
 HSPLandroid/os/Parcel;->readSerializable()Ljava/io/Serializable;
-HSPLandroid/os/Parcel;->readSerializableInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/io/ObjectInputStream;Landroid/os/Parcel$2;
+HSPLandroid/os/Parcel;->readSerializableInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;+]Ljava/io/ObjectInputStream;Landroid/os/Parcel$2;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readSize()Landroid/util/Size;
 HSPLandroid/os/Parcel;->readSparseArray(Ljava/lang/ClassLoader;)Landroid/util/SparseArray;
 HSPLandroid/os/Parcel;->readSparseArray(Ljava/lang/ClassLoader;Ljava/lang/Class;)Landroid/util/SparseArray;
 HSPLandroid/os/Parcel;->readSparseArrayInternal(Ljava/lang/ClassLoader;Ljava/lang/Class;)Landroid/util/SparseArray;
 HSPLandroid/os/Parcel;->readSparseIntArray()Landroid/util/SparseIntArray;
 HSPLandroid/os/Parcel;->readSparseIntArrayInternal(Landroid/util/SparseIntArray;I)V
-HSPLandroid/os/Parcel;->readSquashed(Landroid/os/Parcel$SquashReadHelper;)Landroid/os/Parcelable;
+HSPLandroid/os/Parcel;->readSquashed(Landroid/os/Parcel$SquashReadHelper;)Landroid/os/Parcelable;+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/os/Parcel$SquashReadHelper;Landroid/content/pm/ApplicationInfo$1$$ExternalSyntheticLambda0;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readString()Ljava/lang/String;+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readString16()Ljava/lang/String;+]Landroid/os/Parcel$ReadWriteHelper;Landroid/os/Parcel$ReadWriteHelper;
 HSPLandroid/os/Parcel;->readString16Array([Ljava/lang/String;)V
@@ -12402,11 +12454,11 @@
 HSPLandroid/os/Parcel;->readStringArray([Ljava/lang/String;)V
 HSPLandroid/os/Parcel;->readStringList(Ljava/util/List;)V
 HSPLandroid/os/Parcel;->readStrongBinder()Landroid/os/IBinder;
-HSPLandroid/os/Parcel;->readTypedArray([Ljava/lang/Object;Landroid/os/Parcelable$Creator;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->readTypedArray([Ljava/lang/Object;Landroid/os/Parcelable$Creator;)V
 HSPLandroid/os/Parcel;->readTypedList(Ljava/util/List;Landroid/os/Parcelable$Creator;)V
-HSPLandroid/os/Parcel;->readTypedObject(Landroid/os/Parcelable$Creator;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;megamorphic_types
+HSPLandroid/os/Parcel;->readTypedObject(Landroid/os/Parcelable$Creator;)Ljava/lang/Object;+]Landroid/os/Parcelable$Creator;megamorphic_types]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readValue(ILjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Object;
-HSPLandroid/os/Parcel;->readValue(ILjava/lang/ClassLoader;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;
+HSPLandroid/os/Parcel;->readValue(ILjava/lang/ClassLoader;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->readValue(Ljava/lang/ClassLoader;)Ljava/lang/Object;
 HSPLandroid/os/Parcel;->readValue(Ljava/lang/ClassLoader;Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/Object;+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->recycle()V
@@ -12418,11 +12470,11 @@
 HSPLandroid/os/Parcel;->setReadWriteHelper(Landroid/os/Parcel$ReadWriteHelper;)V
 HSPLandroid/os/Parcel;->unmarshall([BII)V
 HSPLandroid/os/Parcel;->writeArrayMap(Landroid/util/ArrayMap;)V
-HSPLandroid/os/Parcel;->writeArrayMapInternal(Landroid/util/ArrayMap;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
+HSPLandroid/os/Parcel;->writeArrayMapInternal(Landroid/util/ArrayMap;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->writeArraySet(Landroid/util/ArraySet;)V
 HSPLandroid/os/Parcel;->writeBinderList(Ljava/util/List;)V
 HSPLandroid/os/Parcel;->writeBlob([B)V
-HSPLandroid/os/Parcel;->writeBoolean(Z)V
+HSPLandroid/os/Parcel;->writeBoolean(Z)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->writeBooleanArray([Z)V
 HSPLandroid/os/Parcel;->writeBundle(Landroid/os/Bundle;)V+]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->writeByte(B)V
@@ -12437,38 +12489,38 @@
 HSPLandroid/os/Parcel;->writeInt(I)V
 HSPLandroid/os/Parcel;->writeIntArray([I)V
 HSPLandroid/os/Parcel;->writeInterfaceToken(Ljava/lang/String;)V
-HSPLandroid/os/Parcel;->writeList(Ljava/util/List;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/os/Parcel;->writeList(Ljava/util/List;)V
 HSPLandroid/os/Parcel;->writeLong(J)V
 HSPLandroid/os/Parcel;->writeLongArray([J)V
 HSPLandroid/os/Parcel;->writeMap(Ljava/util/Map;)V
 HSPLandroid/os/Parcel;->writeMapInternal(Ljava/util/Map;)V
 HSPLandroid/os/Parcel;->writeNoException()V
-HSPLandroid/os/Parcel;->writeParcelable(Landroid/os/Parcelable;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable;missing_types
-HSPLandroid/os/Parcel;->writeParcelableArray([Landroid/os/Parcelable;I)V
-HSPLandroid/os/Parcel;->writeParcelableCreator(Landroid/os/Parcelable;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;missing_types
+HSPLandroid/os/Parcel;->writeParcelable(Landroid/os/Parcelable;I)V+]Landroid/os/Parcelable;missing_types]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->writeParcelableArray([Landroid/os/Parcelable;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->writeParcelableCreator(Landroid/os/Parcelable;)V+]Ljava/lang/Object;missing_types]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->writeParcelableList(Ljava/util/List;I)V
 HSPLandroid/os/Parcel;->writePersistableBundle(Landroid/os/PersistableBundle;)V
 HSPLandroid/os/Parcel;->writeSerializable(Ljava/io/Serializable;)V
-HSPLandroid/os/Parcel;->writeSparseArray(Landroid/util/SparseArray;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/os/Parcel;->writeSparseArray(Landroid/util/SparseArray;)V
 HSPLandroid/os/Parcel;->writeSparseBooleanArray(Landroid/util/SparseBooleanArray;)V
 HSPLandroid/os/Parcel;->writeSparseIntArray(Landroid/util/SparseIntArray;)V
 HSPLandroid/os/Parcel;->writeString(Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->writeString16(Ljava/lang/String;)V+]Landroid/os/Parcel$ReadWriteHelper;Landroid/os/Parcel$ReadWriteHelper;
-HSPLandroid/os/Parcel;->writeString16Array([Ljava/lang/String;)V
+HSPLandroid/os/Parcel;->writeString16Array([Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->writeString16NoHelper(Ljava/lang/String;)V
-HSPLandroid/os/Parcel;->writeString8(Ljava/lang/String;)V
+HSPLandroid/os/Parcel;->writeString8(Ljava/lang/String;)V+]Landroid/os/Parcel$ReadWriteHelper;Landroid/os/Parcel$ReadWriteHelper;
 HSPLandroid/os/Parcel;->writeString8Array([Ljava/lang/String;)V
 HSPLandroid/os/Parcel;->writeString8NoHelper(Ljava/lang/String;)V
-HSPLandroid/os/Parcel;->writeStringArray([Ljava/lang/String;)V
+HSPLandroid/os/Parcel;->writeStringArray([Ljava/lang/String;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->writeStringList(Ljava/util/List;)V
 HSPLandroid/os/Parcel;->writeStrongBinder(Landroid/os/IBinder;)V
-HSPLandroid/os/Parcel;->writeStrongInterface(Landroid/os/IInterface;)V
-HSPLandroid/os/Parcel;->writeTypedArray([Landroid/os/Parcelable;I)V
+HSPLandroid/os/Parcel;->writeStrongInterface(Landroid/os/IInterface;)V+]Landroid/os/IInterface;Landroid/app/LoadedApk$ServiceDispatcher$InnerConnection;,Landroid/app/ActivityThread$ApplicationThread;,Landroid/view/ViewRootImpl$W;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->writeTypedArray([Landroid/os/Parcelable;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->writeTypedArrayMap(Landroid/util/ArrayMap;I)V
 HSPLandroid/os/Parcel;->writeTypedList(Ljava/util/List;)V
 HSPLandroid/os/Parcel;->writeTypedList(Ljava/util/List;I)V
-HSPLandroid/os/Parcel;->writeTypedObject(Landroid/os/Parcelable;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable;Landroid/app/FragmentState;,Landroid/content/Intent;,Landroid/os/Bundle;,Landroid/view/SurfaceControl$Transaction;
-HSPLandroid/os/Parcel;->writeValue(ILjava/lang/Object;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Ljava/lang/Integer;Ljava/lang/Integer;
+HSPLandroid/os/Parcel;->writeTypedObject(Landroid/os/Parcelable;I)V+]Landroid/os/Parcelable;Landroid/view/WindowManager$LayoutParams;,Landroid/content/Intent;]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/os/Parcel;->writeValue(ILjava/lang/Object;)V+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/lang/Boolean;Ljava/lang/Boolean;]Ljava/lang/Long;Ljava/lang/Long;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/Parcel;->writeValue(Ljava/lang/Object;)V+]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/ParcelFileDescriptor$2;->createFromParcel(Landroid/os/Parcel;)Landroid/os/ParcelFileDescriptor;
 HSPLandroid/os/ParcelFileDescriptor$2;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -12658,7 +12710,7 @@
 HSPLandroid/os/ServiceManager;->getServiceOrThrow(Ljava/lang/String;)Landroid/os/IBinder;
 HSPLandroid/os/ServiceManager;->initServiceCache(Ljava/util/Map;)V
 HSPLandroid/os/ServiceManager;->isDeclared(Ljava/lang/String;)Z
-HSPLandroid/os/ServiceManager;->rawGetService(Ljava/lang/String;)Landroid/os/IBinder;+]Landroid/os/IServiceManager;Landroid/os/ServiceManagerProxy;]Lcom/android/internal/util/StatLogger;Lcom/android/internal/util/StatLogger;
+HSPLandroid/os/ServiceManager;->rawGetService(Ljava/lang/String;)Landroid/os/IBinder;+]Lcom/android/internal/util/StatLogger;Lcom/android/internal/util/StatLogger;]Landroid/os/IServiceManager;Landroid/os/ServiceManagerProxy;
 HSPLandroid/os/ServiceManager;->waitForDeclaredService(Ljava/lang/String;)Landroid/os/IBinder;
 HSPLandroid/os/ServiceManagerProxy;->addService(Ljava/lang/String;Landroid/os/IBinder;ZI)V
 HSPLandroid/os/ServiceManagerProxy;->checkService(Ljava/lang/String;)Landroid/os/IBinder;
@@ -12717,7 +12769,7 @@
 HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->lambda$handleViolationWithTimingAttempt$0(Landroid/view/IWindowManager;Ljava/util/ArrayList;)V
 HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onCustomSlowCall(Ljava/lang/String;)V
 HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onNetwork()V
-HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onReadFromDisk()V
+HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onReadFromDisk()V+]Landroid/os/StrictMode$AndroidBlockGuardPolicy;Landroid/os/StrictMode$AndroidBlockGuardPolicy;
 HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onThreadPolicyViolation(Landroid/os/StrictMode$ViolationInfo;)V
 HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onUnbufferedIO()V
 HSPLandroid/os/StrictMode$AndroidBlockGuardPolicy;->onWriteToDisk()V
@@ -12759,7 +12811,7 @@
 HSPLandroid/os/StrictMode$UnsafeIntentStrictModeCallback;-><init>()V
 HSPLandroid/os/StrictMode$UnsafeIntentStrictModeCallback;-><init>(Landroid/os/StrictMode$UnsafeIntentStrictModeCallback-IA;)V
 HSPLandroid/os/StrictMode$ViolationInfo;->-$$Nest$fgetmViolation(Landroid/os/StrictMode$ViolationInfo;)Landroid/os/strictmode/Violation;
-HSPLandroid/os/StrictMode$ViolationInfo;-><init>(Landroid/os/Parcel;Z)V
+HSPLandroid/os/StrictMode$ViolationInfo;-><init>(Landroid/os/Parcel;Z)V+]Ljava/util/Deque;Ljava/util/ArrayDeque;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/os/StrictMode$ViolationInfo;-><init>(Landroid/os/strictmode/Violation;I)V
 HSPLandroid/os/StrictMode$ViolationInfo;->getStackTrace()Ljava/lang/String;
 HSPLandroid/os/StrictMode$ViolationInfo;->hashCode()I
@@ -13087,7 +13139,7 @@
 HSPLandroid/os/storage/StorageManager;->allocateBytes(Ljava/io/FileDescriptor;JI)V
 HSPLandroid/os/storage/StorageManager;->allocateBytes(Ljava/util/UUID;JI)V
 HSPLandroid/os/storage/StorageManager;->convert(Ljava/lang/String;)Ljava/util/UUID;
-HSPLandroid/os/storage/StorageManager;->convert(Ljava/util/UUID;)Ljava/lang/String;
+HSPLandroid/os/storage/StorageManager;->convert(Ljava/util/UUID;)Ljava/lang/String;+]Ljava/lang/Object;Ljava/util/UUID;
 HSPLandroid/os/storage/StorageManager;->getAllocatableBytes(Ljava/util/UUID;I)J
 HSPLandroid/os/storage/StorageManager;->getStorageVolume(Ljava/io/File;I)Landroid/os/storage/StorageVolume;
 HSPLandroid/os/storage/StorageManager;->getStorageVolume([Landroid/os/storage/StorageVolume;Ljava/io/File;)Landroid/os/storage/StorageVolume;
@@ -13176,9 +13228,10 @@
 HSPLandroid/permission/PermissionManager;-><clinit>()V
 HSPLandroid/permission/PermissionManager;-><init>(Landroid/content/Context;)V
 HSPLandroid/permission/PermissionManager;->addOnPermissionsChangeListener(Landroid/content/pm/PackageManager$OnPermissionsChangedListener;)V
-HSPLandroid/permission/PermissionManager;->checkPermissionUncached(Ljava/lang/String;III)I+]Landroid/app/IActivityManager;Landroid/app/IActivityManager$Stub$Proxy;
+HSPLandroid/permission/PermissionManager;->checkPermissionUncached(Ljava/lang/String;III)I+]Landroid/app/IActivityManager;Landroid/app/IActivityManager$Stub$Proxy;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/permission/PermissionManager;->getPermissionFlags(Ljava/lang/String;Ljava/lang/String;Landroid/os/UserHandle;)I
 HSPLandroid/permission/PermissionManager;->getPermissionInfo(Ljava/lang/String;I)Landroid/content/pm/PermissionInfo;
+HSPLandroid/permission/PermissionManager;->getPersistentDeviceId(I)Ljava/lang/String;
 HSPLandroid/permission/PermissionManager;->getSplitPermissions()Ljava/util/List;
 HSPLandroid/permission/PermissionManager;->removeOnPermissionsChangeListener(Landroid/content/pm/PackageManager$OnPermissionsChangedListener;)V
 HSPLandroid/permission/PermissionManager;->splitPermissionInfoListToNonParcelableList(Ljava/util/List;)Ljava/util/List;
@@ -13238,15 +13291,15 @@
 HSPLandroid/provider/Settings$Global;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
 HSPLandroid/provider/Settings$Global;->getLong(Landroid/content/ContentResolver;Ljava/lang/String;J)J
 HSPLandroid/provider/Settings$Global;->getString(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/provider/Settings$Global;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
+HSPLandroid/provider/Settings$Global;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;+]Landroid/provider/Settings$NameValueCache;Landroid/provider/Settings$NameValueCache;]Ljava/util/HashSet;Ljava/util/HashSet;
 HSPLandroid/provider/Settings$Global;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
 HSPLandroid/provider/Settings$Global;->putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z
 HSPLandroid/provider/Settings$Global;->putLong(Landroid/content/ContentResolver;Ljava/lang/String;J)Z
 HSPLandroid/provider/Settings$Global;->putString(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;)Z
 HSPLandroid/provider/Settings$Global;->putStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZIZ)Z
 HSPLandroid/provider/Settings$NameValueCache$$ExternalSyntheticLambda0;-><init>(Landroid/provider/Settings$NameValueCache;)V
-HSPLandroid/provider/Settings$NameValueCache;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
-HSPLandroid/provider/Settings$NameValueCache;->getStringsForPrefixStripPrefix(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/util/List;)Ljava/util/Map;+]Landroid/content/ContentResolver;Landroid/app/ContextImpl$ApplicationContentResolver;]Landroid/content/IContentProvider;Landroid/content/ContentProvider$Transport;,Landroid/content/ContentProviderProxy;]Landroid/net/Uri;Landroid/net/Uri$StringUri;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/provider/Settings$ContentProviderHolder;Landroid/provider/Settings$ContentProviderHolder;]Landroid/provider/Settings$GenerationTracker;Landroid/provider/Settings$GenerationTracker;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/String;Ljava/lang/String;]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/util/Iterator;Ljava/util/Arrays$ArrayItr;,Ljava/util/HashMap$EntryIterator;]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Ljava/util/Map$Entry;Ljava/util/HashMap$Node;]Ljava/util/Set;Ljava/util/HashMap$EntrySet;
+HSPLandroid/provider/Settings$NameValueCache;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/content/IContentProvider;Landroid/content/ContentProviderProxy;]Landroid/provider/Settings$GenerationTracker;Landroid/provider/Settings$GenerationTracker;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/provider/Settings$ContentProviderHolder;Landroid/provider/Settings$ContentProviderHolder;]Landroid/content/ContentResolver;Landroid/app/ContextImpl$ApplicationContentResolver;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
+HSPLandroid/provider/Settings$NameValueCache;->getStringsForPrefixStripPrefix(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/util/List;)Ljava/util/Map;+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/Map$Entry;Ljava/util/HashMap$Node;]Landroid/provider/Settings$GenerationTracker;Landroid/provider/Settings$GenerationTracker;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/provider/Settings$ContentProviderHolder;Landroid/provider/Settings$ContentProviderHolder;]Ljava/util/Set;Ljava/util/HashMap$EntrySet;]Ljava/lang/String;Ljava/lang/String;]Landroid/content/IContentProvider;Landroid/content/ContentProviderProxy;,Landroid/content/ContentProvider$Transport;]Ljava/util/List;Ljava/util/Arrays$ArrayList;]Landroid/content/ContentResolver;Landroid/app/ContextImpl$ApplicationContentResolver;]Ljava/util/Iterator;Ljava/util/HashMap$EntryIterator;,Ljava/util/Arrays$ArrayItr;]Landroid/net/Uri;Landroid/net/Uri$StringUri;
 HSPLandroid/provider/Settings$NameValueCache;->isCallerExemptFromReadableRestriction()Z
 HSPLandroid/provider/Settings$NameValueCache;->putStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZIZ)Z
 HSPLandroid/provider/Settings$NameValueTable;->getUriFor(Landroid/net/Uri;Ljava/lang/String;)Landroid/net/Uri;
@@ -13257,7 +13310,7 @@
 HSPLandroid/provider/Settings$Secure;->getIntForUser(Landroid/content/ContentResolver;Ljava/lang/String;II)I
 HSPLandroid/provider/Settings$Secure;->getLong(Landroid/content/ContentResolver;Ljava/lang/String;J)J
 HSPLandroid/provider/Settings$Secure;->getLongForUser(Landroid/content/ContentResolver;Ljava/lang/String;JI)J
-HSPLandroid/provider/Settings$Secure;->getString(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/provider/Settings$Secure;->getString(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;+]Landroid/content/ContentResolver;Landroid/app/ContextImpl$ApplicationContentResolver;
 HSPLandroid/provider/Settings$Secure;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
 HSPLandroid/provider/Settings$Secure;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
 HSPLandroid/provider/Settings$Secure;->putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z
@@ -13272,7 +13325,7 @@
 HSPLandroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
 HSPLandroid/provider/Settings$System;->getIntForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)I
 HSPLandroid/provider/Settings$System;->getIntForUser(Landroid/content/ContentResolver;Ljava/lang/String;II)I
-HSPLandroid/provider/Settings$System;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
+HSPLandroid/provider/Settings$System;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;+]Landroid/provider/Settings$NameValueCache;Landroid/provider/Settings$NameValueCache;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/HashSet;Ljava/util/HashSet;
 HSPLandroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
 HSPLandroid/provider/Settings$System;->putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z
 HSPLandroid/provider/Settings$System;->putIntForUser(Landroid/content/ContentResolver;Ljava/lang/String;II)Z
@@ -13291,6 +13344,8 @@
 HSPLandroid/provider/Telephony$Sms;->getDefaultSmsPackage(Landroid/content/Context;)Ljava/lang/String;
 HSPLandroid/renderscript/RenderScriptCacheDir;->setupDiskCache(Ljava/io/File;)V
 HSPLandroid/se/omapi/SeServiceManager;-><init>()V
+HSPLandroid/security/FeatureFlagsImpl;-><init>()V
+HSPLandroid/security/Flags;-><clinit>()V
 HSPLandroid/security/KeyChain$1;-><init>(Ljava/util/concurrent/atomic/AtomicReference;Ljava/util/concurrent/CountDownLatch;)V
 HSPLandroid/security/KeyChain$1;->onServiceConnected(Landroid/content/ComponentName;Landroid/os/IBinder;)V
 HSPLandroid/security/KeyChain$KeyChainConnection;-><init>(Landroid/content/Context;Landroid/content/ServiceConnection;Landroid/security/IKeyChainService;)V
@@ -13307,6 +13362,7 @@
 HSPLandroid/security/KeyStore2;->getKeyStoreException(ILjava/lang/String;)Landroid/security/KeyStoreException;
 HSPLandroid/security/KeyStore2;->getService(Z)Landroid/system/keystore2/IKeystoreService;
 HSPLandroid/security/KeyStore2;->handleRemoteExceptionWithRetry(Landroid/security/KeyStore2$CheckedRemoteRequest;)Ljava/lang/Object;
+HSPLandroid/security/KeyStore;->getInstance()Landroid/security/KeyStore;
 HSPLandroid/security/KeyStoreException;-><init>(ILjava/lang/String;)V
 HSPLandroid/security/KeyStoreException;-><init>(ILjava/lang/String;Ljava/lang/String;)V
 HSPLandroid/security/KeyStoreException;->getErrorCode()I
@@ -13636,18 +13692,18 @@
 HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onListenerConnected(Landroid/service/notification/NotificationRankingUpdate;)V
 HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationChannelGroupModification(Ljava/lang/String;Landroid/os/UserHandle;Landroid/app/NotificationChannelGroup;I)V
 HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationChannelModification(Ljava/lang/String;Landroid/os/UserHandle;Landroid/app/NotificationChannel;I)V
-HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationPosted(Landroid/service/notification/IStatusBarNotificationHolder;Landroid/service/notification/NotificationRankingUpdate;)V
+HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationPosted(Landroid/service/notification/IStatusBarNotificationHolder;Landroid/service/notification/NotificationRankingUpdate;)V+]Landroid/os/Handler;Landroid/service/notification/NotificationListenerService$MyHandler;]Landroid/service/notification/IStatusBarNotificationHolder;Landroid/service/notification/IStatusBarNotificationHolder$Stub$Proxy;]Landroid/service/notification/StatusBarNotification;Landroid/service/notification/StatusBarNotification;]Landroid/os/Message;Landroid/os/Message;
 HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationRankingUpdate(Landroid/service/notification/NotificationRankingUpdate;)V
 HSPLandroid/service/notification/NotificationListenerService$NotificationListenerWrapper;->onNotificationRemoved(Landroid/service/notification/IStatusBarNotificationHolder;Landroid/service/notification/NotificationRankingUpdate;Landroid/service/notification/NotificationStats;I)V
 HSPLandroid/service/notification/NotificationListenerService$Ranking;-><init>()V
-HSPLandroid/service/notification/NotificationListenerService$Ranking;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/service/notification/NotificationListenerService$Ranking;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Object;Landroid/service/notification/NotificationListenerService$Ranking;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/service/notification/NotificationListenerService$Ranking;->getChannel()Landroid/app/NotificationChannel;
 HSPLandroid/service/notification/NotificationListenerService$Ranking;->getKey()Ljava/lang/String;
-HSPLandroid/service/notification/NotificationListenerService$Ranking;->populate(Landroid/service/notification/NotificationListenerService$Ranking;)V
+HSPLandroid/service/notification/NotificationListenerService$Ranking;->populate(Landroid/service/notification/NotificationListenerService$Ranking;)V+]Landroid/service/notification/NotificationListenerService$Ranking;Landroid/service/notification/NotificationListenerService$Ranking;
 HSPLandroid/service/notification/NotificationListenerService$Ranking;->populate(Ljava/lang/String;IZIIILjava/lang/CharSequence;Ljava/lang/String;Landroid/app/NotificationChannel;Ljava/util/ArrayList;Ljava/util/ArrayList;ZIZJZLjava/util/ArrayList;Ljava/util/ArrayList;ZZZLandroid/content/pm/ShortcutInfo;IZIZ)V
 HSPLandroid/service/notification/NotificationListenerService$RankingMap$1;->createFromParcel(Landroid/os/Parcel;)Landroid/service/notification/NotificationListenerService$RankingMap;
 HSPLandroid/service/notification/NotificationListenerService$RankingMap$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/service/notification/NotificationListenerService$RankingMap;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/service/notification/NotificationListenerService$RankingMap;-><init>(Landroid/os/Parcel;)V+]Landroid/service/notification/NotificationListenerService$Ranking;Landroid/service/notification/NotificationListenerService$Ranking;]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Object;Landroid/service/notification/NotificationListenerService$RankingMap;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/service/notification/NotificationListenerService$RankingMap;->getOrderedKeys()[Ljava/lang/String;
 HSPLandroid/service/notification/NotificationListenerService$RankingMap;->getRanking(Ljava/lang/String;Landroid/service/notification/NotificationListenerService$Ranking;)Z
 HSPLandroid/service/notification/NotificationListenerService;-><init>()V
@@ -13676,7 +13732,7 @@
 HSPLandroid/service/notification/NotificationRankingUpdate;->getRankingMap()Landroid/service/notification/NotificationListenerService$RankingMap;
 HSPLandroid/service/notification/StatusBarNotification$1;->createFromParcel(Landroid/os/Parcel;)Landroid/service/notification/StatusBarNotification;
 HSPLandroid/service/notification/StatusBarNotification$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/service/notification/StatusBarNotification;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/service/notification/StatusBarNotification;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcelable$Creator;Lcom/android/internal/logging/InstanceId$1;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/service/notification/StatusBarNotification;->getGroupKey()Ljava/lang/String;
 HSPLandroid/service/notification/StatusBarNotification;->getId()I
 HSPLandroid/service/notification/StatusBarNotification;->getInstanceId()Lcom/android/internal/logging/InstanceId;
@@ -13695,7 +13751,7 @@
 HSPLandroid/service/notification/StatusBarNotification;->isAppGroup()Z
 HSPLandroid/service/notification/StatusBarNotification;->isGroup()Z
 HSPLandroid/service/notification/StatusBarNotification;->isOngoing()Z
-HSPLandroid/service/notification/StatusBarNotification;->key()Ljava/lang/String;
+HSPLandroid/service/notification/StatusBarNotification;->key()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/os/UserHandle;Landroid/os/UserHandle;
 HSPLandroid/service/notification/ZenModeConfig$ZenRule$1;->createFromParcel(Landroid/os/Parcel;)Landroid/service/notification/ZenModeConfig$ZenRule;
 HSPLandroid/service/notification/ZenModeConfig$ZenRule$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/service/notification/ZenModeConfig$ZenRule;-><init>(Landroid/os/Parcel;)V
@@ -14004,7 +14060,7 @@
 HSPLandroid/telecom/PhoneAccountHandle;->getId()Ljava/lang/String;
 HSPLandroid/telecom/PhoneAccountHandle;->getUserHandle()Landroid/os/UserHandle;
 HSPLandroid/telecom/PhoneAccountHandle;->hashCode()I
-HSPLandroid/telecom/PhoneAccountHandle;->toString()Ljava/lang/String;
+HSPLandroid/telecom/PhoneAccountHandle;->toString()Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/content/ComponentName;Landroid/content/ComponentName;
 HSPLandroid/telecom/PhoneAccountHandle;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/telecom/TelecomManager;-><init>(Landroid/content/Context;)V
 HSPLandroid/telecom/TelecomManager;-><init>(Landroid/content/Context;Lcom/android/internal/telecom/ITelecomService;)V
@@ -14143,7 +14199,7 @@
 HSPLandroid/telephony/NetworkRegistrationInfo$$ExternalSyntheticLambda0;->apply(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/telephony/NetworkRegistrationInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telephony/NetworkRegistrationInfo;
 HSPLandroid/telephony/NetworkRegistrationInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
-HSPLandroid/telephony/NetworkRegistrationInfo;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/telephony/NetworkRegistrationInfo;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/telephony/NetworkRegistrationInfo;-><init>(Landroid/telephony/NetworkRegistrationInfo;)V
 HSPLandroid/telephony/NetworkRegistrationInfo;->domainToString(I)Ljava/lang/String;
 HSPLandroid/telephony/NetworkRegistrationInfo;->getAccessNetworkTechnology()I
@@ -14167,7 +14223,7 @@
 HSPLandroid/telephony/PhoneNumberUtils;->getMinMatch()I
 HSPLandroid/telephony/PhoneNumberUtils;->isDialable(C)Z
 HSPLandroid/telephony/PhoneNumberUtils;->isNonSeparator(C)Z
-HSPLandroid/telephony/PhoneNumberUtils;->normalizeNumber(Ljava/lang/String;)Ljava/lang/String;
+HSPLandroid/telephony/PhoneNumberUtils;->normalizeNumber(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLandroid/telephony/PhoneNumberUtils;->stripSeparators(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/telephony/PhoneStateListener$IPhoneStateListenerStub$$ExternalSyntheticLambda10;->runOrThrow()V
 HSPLandroid/telephony/PhoneStateListener$IPhoneStateListenerStub$$ExternalSyntheticLambda19;->runOrThrow()V
@@ -14199,7 +14255,7 @@
 HSPLandroid/telephony/ServiceState$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telephony/ServiceState;
 HSPLandroid/telephony/ServiceState$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/telephony/ServiceState;-><init>()V
-HSPLandroid/telephony/ServiceState;-><init>(Landroid/os/Parcel;)V
+HSPLandroid/telephony/ServiceState;-><init>(Landroid/os/Parcel;)V+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/telephony/ServiceState;-><init>(Landroid/telephony/ServiceState;)V
 HSPLandroid/telephony/ServiceState;->copyFrom(Landroid/telephony/ServiceState;)V
 HSPLandroid/telephony/ServiceState;->createLocationInfoSanitizedCopy(Z)Landroid/telephony/ServiceState;
@@ -14239,7 +14295,7 @@
 HSPLandroid/telephony/SignalStrength;->getLevel()I
 HSPLandroid/telephony/SignalStrength;->getPrimary()Landroid/telephony/CellSignalStrength;
 HSPLandroid/telephony/SignalStrength;->writeToParcel(Landroid/os/Parcel;I)V
-HSPLandroid/telephony/SubscriptionInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telephony/SubscriptionInfo;+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/text/TextUtils$1;]Landroid/telephony/SubscriptionInfo$Builder;Landroid/telephony/SubscriptionInfo$Builder;
+HSPLandroid/telephony/SubscriptionInfo$1;->createFromParcel(Landroid/os/Parcel;)Landroid/telephony/SubscriptionInfo;+]Landroid/os/Parcelable$Creator;Landroid/text/TextUtils$1;]Landroid/telephony/SubscriptionInfo$Builder;Landroid/telephony/SubscriptionInfo$Builder;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/telephony/SubscriptionInfo$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/telephony/SubscriptionInfo$Builder;->-$$Nest$fgetmAreUiccApplicationsEnabled(Landroid/telephony/SubscriptionInfo$Builder;)Z
 HSPLandroid/telephony/SubscriptionInfo$Builder;->-$$Nest$fgetmCardId(Landroid/telephony/SubscriptionInfo$Builder;)I
@@ -14322,6 +14378,8 @@
 HSPLandroid/telephony/SubscriptionInfo;->isEmbedded()Z
 HSPLandroid/telephony/SubscriptionInfo;->isOpportunistic()Z
 HSPLandroid/telephony/SubscriptionInfo;->toString()Ljava/lang/String;
+HSPLandroid/telephony/SubscriptionManager$$ExternalSyntheticLambda10;->applyOrThrow(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/telephony/SubscriptionManager$$ExternalSyntheticLambda15;->applyOrThrow(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/telephony/SubscriptionManager$$ExternalSyntheticLambda9;->applyOrThrow(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/telephony/SubscriptionManager$IntegerPropertyInvalidatedCache;->query(Ljava/lang/Integer;)Ljava/lang/Object;
 HSPLandroid/telephony/SubscriptionManager$IntegerPropertyInvalidatedCache;->recompute(Ljava/lang/Integer;)Ljava/lang/Object;
@@ -14432,6 +14490,7 @@
 HSPLandroid/telephony/TelephonyManager;->getServiceState()Landroid/telephony/ServiceState;
 HSPLandroid/telephony/TelephonyManager;->getServiceState(I)Landroid/telephony/ServiceState;
 HSPLandroid/telephony/TelephonyManager;->getServiceStateForSubscriber(I)Landroid/telephony/ServiceState;
+HSPLandroid/telephony/TelephonyManager;->getServiceStateForSubscriber(IZZ)Landroid/telephony/ServiceState;
 HSPLandroid/telephony/TelephonyManager;->getSignalStrength()Landroid/telephony/SignalStrength;
 HSPLandroid/telephony/TelephonyManager;->getSimCarrierId()I
 HSPLandroid/telephony/TelephonyManager;->getSimCountryIso()Ljava/lang/String;
@@ -14544,7 +14603,7 @@
 HSPLandroid/telephony/data/ApnSetting;->getApnTypeBitmask()I
 HSPLandroid/telephony/data/ApnSetting;->getApnTypesStringFromBitmask(I)Ljava/lang/String;
 HSPLandroid/telephony/data/ApnSetting;->portToString(I)Ljava/lang/String;
-HSPLandroid/telephony/data/ApnSetting;->toString()Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/util/Map;Landroid/util/ArrayMap;
+HSPLandroid/telephony/data/ApnSetting;->toString()Ljava/lang/String;
 HSPLandroid/telephony/euicc/EuiccManager;->getIEuiccController()Lcom/android/internal/telephony/euicc/IEuiccController;
 HSPLandroid/telephony/euicc/EuiccManager;->isEnabled()Z
 HSPLandroid/telephony/ims/ImsMmTelManager;->createForSubscriptionId(I)Landroid/telephony/ims/ImsMmTelManager;
@@ -14593,7 +14652,7 @@
 HSPLandroid/text/BidiFormatter;->unicodeWrap(Ljava/lang/CharSequence;Landroid/text/TextDirectionHeuristic;Z)Ljava/lang/CharSequence;
 HSPLandroid/text/BoringLayout$Metrics;->-$$Nest$mreset(Landroid/text/BoringLayout$Metrics;)V
 HSPLandroid/text/BoringLayout$Metrics;-><init>()V
-HSPLandroid/text/BoringLayout$Metrics;->reset()V+]Landroid/graphics/RectF;Landroid/graphics/RectF;
+HSPLandroid/text/BoringLayout$Metrics;->reset()V
 HSPLandroid/text/BoringLayout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FFLandroid/text/BoringLayout$Metrics;Z)V
 HSPLandroid/text/BoringLayout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FFLandroid/text/BoringLayout$Metrics;ZLandroid/text/TextUtils$TruncateAt;I)V
 HSPLandroid/text/BoringLayout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FFLandroid/text/BoringLayout$Metrics;ZLandroid/text/TextUtils$TruncateAt;IZ)V
@@ -14608,13 +14667,14 @@
 HSPLandroid/text/BoringLayout;->getLineDescent(I)I
 HSPLandroid/text/BoringLayout;->getLineDirections(I)Landroid/text/Layout$Directions;
 HSPLandroid/text/BoringLayout;->getLineMax(I)F
-HSPLandroid/text/BoringLayout;->getLineStart(I)I+]Landroid/text/BoringLayout;Landroid/text/BoringLayout;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/text/BoringLayout;->getLineStart(I)I
 HSPLandroid/text/BoringLayout;->getLineTop(I)I
 HSPLandroid/text/BoringLayout;->getLineWidth(I)F
 HSPLandroid/text/BoringLayout;->getParagraphDirection(I)I
 HSPLandroid/text/BoringLayout;->hasAnyInterestingChars(Ljava/lang/CharSequence;I)Z
 HSPLandroid/text/BoringLayout;->init(Ljava/lang/CharSequence;Landroid/text/TextPaint;Landroid/text/Layout$Alignment;Landroid/text/BoringLayout$Metrics;ZZZ)V+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Ljava/lang/CharSequence;Ljava/lang/String;
 HSPLandroid/text/BoringLayout;->isBoring(Ljava/lang/CharSequence;Landroid/text/TextPaint;Landroid/text/TextDirectionHeuristic;Landroid/text/BoringLayout$Metrics;)Landroid/text/BoringLayout$Metrics;
+HSPLandroid/text/BoringLayout;->isBoring(Ljava/lang/CharSequence;Landroid/text/TextPaint;Landroid/text/TextDirectionHeuristic;ZLandroid/graphics/Paint$FontMetrics;Landroid/text/BoringLayout$Metrics;)Landroid/text/BoringLayout$Metrics;+]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/Spanned;megamorphic_types]Ljava/lang/CharSequence;megamorphic_types]Landroid/text/TextDirectionHeuristic;Landroid/text/TextDirectionHeuristics$TextDirectionHeuristicLocale;,Landroid/text/TextDirectionHeuristics$TextDirectionHeuristicInternal;
 HSPLandroid/text/BoringLayout;->isBoring(Ljava/lang/CharSequence;Landroid/text/TextPaint;Landroid/text/TextDirectionHeuristic;ZLandroid/text/BoringLayout$Metrics;)Landroid/text/BoringLayout$Metrics;
 HSPLandroid/text/BoringLayout;->isFallbackLineSpacingEnabled()Z
 HSPLandroid/text/BoringLayout;->make(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FFLandroid/text/BoringLayout$Metrics;Z)Landroid/text/BoringLayout;
@@ -14629,7 +14689,8 @@
 HSPLandroid/text/CharSequenceCharacterIterator;->getIndex()I
 HSPLandroid/text/CharSequenceCharacterIterator;->next()C
 HSPLandroid/text/CharSequenceCharacterIterator;->setIndex(I)C
-HSPLandroid/text/DynamicLayout$Builder;->obtain(Ljava/lang/CharSequence;Landroid/text/TextPaint;I)Landroid/text/DynamicLayout$Builder;
+HSPLandroid/text/ClientFlags;->icuBidiMigration()Z
+HSPLandroid/text/DynamicLayout$Builder;->obtain(Ljava/lang/CharSequence;Landroid/text/TextPaint;I)Landroid/text/DynamicLayout$Builder;+]Landroid/util/Pools$SynchronizedPool;Landroid/util/Pools$SynchronizedPool;
 HSPLandroid/text/DynamicLayout$ChangeWatcher;->afterTextChanged(Landroid/text/Editable;)V
 HSPLandroid/text/DynamicLayout$ChangeWatcher;->beforeTextChanged(Ljava/lang/CharSequence;III)V
 HSPLandroid/text/DynamicLayout$ChangeWatcher;->onSpanAdded(Landroid/text/Spannable;Ljava/lang/Object;II)V
@@ -14637,29 +14698,29 @@
 HSPLandroid/text/DynamicLayout$ChangeWatcher;->onSpanRemoved(Landroid/text/Spannable;Ljava/lang/Object;II)V
 HSPLandroid/text/DynamicLayout$ChangeWatcher;->onTextChanged(Ljava/lang/CharSequence;III)V
 HSPLandroid/text/DynamicLayout;-><init>(Landroid/text/DynamicLayout$Builder;)V
-HSPLandroid/text/DynamicLayout;->addBlockAtOffset(I)V
-HSPLandroid/text/DynamicLayout;->contentMayProtrudeFromLineTopOrBottom(Ljava/lang/CharSequence;II)Z
+HSPLandroid/text/DynamicLayout;->addBlockAtOffset(I)V+]Landroid/text/DynamicLayout;Landroid/text/DynamicLayout;
+HSPLandroid/text/DynamicLayout;->contentMayProtrudeFromLineTopOrBottom(Ljava/lang/CharSequence;II)Z+]Landroid/text/DynamicLayout;Landroid/text/DynamicLayout;]Landroid/graphics/Paint;Landroid/text/TextPaint;]Landroid/text/Spanned;Landroid/text/SpannableString;
 HSPLandroid/text/DynamicLayout;->createBlocks()V
-HSPLandroid/text/DynamicLayout;->generate(Landroid/text/DynamicLayout$Builder;)V
+HSPLandroid/text/DynamicLayout;->generate(Landroid/text/DynamicLayout$Builder;)V+]Landroid/text/DynamicLayout;Landroid/text/DynamicLayout;]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;]Landroid/text/PackedObjectVector;Landroid/text/PackedObjectVector;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Landroid/text/method/ReplacementTransformationMethod$SpannedReplacementCharSequence;,Landroid/text/SpannableStringBuilder;]Landroid/text/Spannable;Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/DynamicLayout;->getBlockEndLines()[I
 HSPLandroid/text/DynamicLayout;->getBlockIndices()[I
 HSPLandroid/text/DynamicLayout;->getBlocksAlwaysNeedToBeRedrawn()Landroid/util/ArraySet;
 HSPLandroid/text/DynamicLayout;->getEllipsisCount(I)I
 HSPLandroid/text/DynamicLayout;->getEllipsisStart(I)I
 HSPLandroid/text/DynamicLayout;->getEllipsizedWidth()I
-HSPLandroid/text/DynamicLayout;->getEndHyphenEdit(I)I
+HSPLandroid/text/DynamicLayout;->getEndHyphenEdit(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
 HSPLandroid/text/DynamicLayout;->getIndexFirstChangedBlock()I
-HSPLandroid/text/DynamicLayout;->getLineContainsTab(I)Z
-HSPLandroid/text/DynamicLayout;->getLineCount()I
-HSPLandroid/text/DynamicLayout;->getLineDescent(I)I
-HSPLandroid/text/DynamicLayout;->getLineDirections(I)Landroid/text/Layout$Directions;
+HSPLandroid/text/DynamicLayout;->getLineContainsTab(I)Z+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getLineCount()I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getLineDescent(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getLineDirections(I)Landroid/text/Layout$Directions;+]Landroid/text/PackedObjectVector;Landroid/text/PackedObjectVector;
 HSPLandroid/text/DynamicLayout;->getLineExtra(I)I
-HSPLandroid/text/DynamicLayout;->getLineStart(I)I
-HSPLandroid/text/DynamicLayout;->getLineTop(I)I
+HSPLandroid/text/DynamicLayout;->getLineStart(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getLineTop(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
 HSPLandroid/text/DynamicLayout;->getNumberOfBlocks()I
-HSPLandroid/text/DynamicLayout;->getParagraphDirection(I)I
-HSPLandroid/text/DynamicLayout;->getStartHyphenEdit(I)I
-HSPLandroid/text/DynamicLayout;->reflow(Ljava/lang/CharSequence;III)V
+HSPLandroid/text/DynamicLayout;->getParagraphDirection(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->getStartHyphenEdit(I)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
+HSPLandroid/text/DynamicLayout;->reflow(Ljava/lang/CharSequence;III)V+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;]Landroid/text/DynamicLayout;Landroid/text/DynamicLayout;]Landroid/text/PackedObjectVector;Landroid/text/PackedObjectVector;]Landroid/text/StaticLayout;Landroid/text/StaticLayout;]Landroid/text/Spanned;Landroid/text/SpannableString;]Ljava/lang/CharSequence;Landroid/text/SpannableString;]Landroid/text/StaticLayout$Builder;Landroid/text/StaticLayout$Builder;
 HSPLandroid/text/DynamicLayout;->setIndexFirstChangedBlock(I)V
 HSPLandroid/text/DynamicLayout;->updateAlwaysNeedsToBeRedrawn(I)V
 HSPLandroid/text/DynamicLayout;->updateBlocks(III)V
@@ -14674,7 +14735,7 @@
 HSPLandroid/text/Html;->fromHtml(Ljava/lang/String;I)Landroid/text/Spanned;
 HSPLandroid/text/Html;->fromHtml(Ljava/lang/String;ILandroid/text/Html$ImageGetter;Landroid/text/Html$TagHandler;)Landroid/text/Spanned;
 HSPLandroid/text/HtmlToSpannedConverter;-><init>(Ljava/lang/String;Landroid/text/Html$ImageGetter;Landroid/text/Html$TagHandler;Lorg/ccil/cowan/tagsoup/Parser;I)V
-HSPLandroid/text/HtmlToSpannedConverter;->characters([CII)V+]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/text/HtmlToSpannedConverter;->characters([CII)V
 HSPLandroid/text/HtmlToSpannedConverter;->convert()Landroid/text/Spanned;
 HSPLandroid/text/HtmlToSpannedConverter;->end(Landroid/text/Editable;Ljava/lang/Class;Ljava/lang/Object;)V
 HSPLandroid/text/HtmlToSpannedConverter;->endA(Landroid/text/Editable;)V
@@ -14683,8 +14744,8 @@
 HSPLandroid/text/HtmlToSpannedConverter;->endPrefixMapping(Ljava/lang/String;)V
 HSPLandroid/text/HtmlToSpannedConverter;->getLast(Landroid/text/Spanned;Ljava/lang/Class;)Ljava/lang/Object;
 HSPLandroid/text/HtmlToSpannedConverter;->handleBr(Landroid/text/Editable;)V
-HSPLandroid/text/HtmlToSpannedConverter;->handleEndTag(Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;
-HSPLandroid/text/HtmlToSpannedConverter;->handleStartTag(Ljava/lang/String;Lorg/xml/sax/Attributes;)V+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/text/HtmlToSpannedConverter;->handleEndTag(Ljava/lang/String;)V
+HSPLandroid/text/HtmlToSpannedConverter;->handleStartTag(Ljava/lang/String;Lorg/xml/sax/Attributes;)V
 HSPLandroid/text/HtmlToSpannedConverter;->setDocumentLocator(Lorg/xml/sax/Locator;)V
 HSPLandroid/text/HtmlToSpannedConverter;->setSpanFromMark(Landroid/text/Spannable;Ljava/lang/Object;[Ljava/lang/Object;)V
 HSPLandroid/text/HtmlToSpannedConverter;->start(Landroid/text/Editable;Ljava/lang/Object;)V
@@ -14702,7 +14763,7 @@
 HSPLandroid/text/Layout$Directions;->isRunRtl(I)Z
 HSPLandroid/text/Layout$Ellipsizer;-><init>(Ljava/lang/CharSequence;)V
 HSPLandroid/text/Layout$Ellipsizer;->charAt(I)C
-HSPLandroid/text/Layout$Ellipsizer;->getChars(II[CI)V+]Landroid/text/Layout;Landroid/text/StaticLayout;
+HSPLandroid/text/Layout$Ellipsizer;->getChars(II[CI)V
 HSPLandroid/text/Layout$Ellipsizer;->length()I
 HSPLandroid/text/Layout$HorizontalMeasurementProvider;->init()V
 HSPLandroid/text/Layout$SpannedEllipsizer;->getSpanEnd(Ljava/lang/Object;)I
@@ -14711,12 +14772,13 @@
 HSPLandroid/text/Layout$SpannedEllipsizer;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;
 HSPLandroid/text/Layout$SpannedEllipsizer;->nextSpanTransition(IILjava/lang/Class;)I
 HSPLandroid/text/Layout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FF)V
+HSPLandroid/text/Layout;-><init>(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;Landroid/text/TextDirectionHeuristic;FFZZILandroid/text/TextUtils$TruncateAt;III[I[IILandroid/graphics/text/LineBreakConfig;ZZLandroid/graphics/Paint$FontMetrics;)V
 HSPLandroid/text/Layout;->addSelection(IIIIILandroid/text/Layout$SelectionRectangleConsumer;)V
 HSPLandroid/text/Layout;->draw(Landroid/graphics/Canvas;)V
 HSPLandroid/text/Layout;->draw(Landroid/graphics/Canvas;Landroid/graphics/Path;Landroid/graphics/Paint;I)V
-HSPLandroid/text/Layout;->draw(Landroid/graphics/Canvas;Ljava/util/List;Ljava/util/List;Landroid/graphics/Path;Landroid/graphics/Paint;I)V
+HSPLandroid/text/Layout;->draw(Landroid/graphics/Canvas;Ljava/util/List;Ljava/util/List;Landroid/graphics/Path;Landroid/graphics/Paint;I)V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;
 HSPLandroid/text/Layout;->drawBackground(Landroid/graphics/Canvas;II)V
-HSPLandroid/text/Layout;->drawText(Landroid/graphics/Canvas;II)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/text/Spanned;Landroid/text/Layout$SpannedEllipsizer;,Landroid/text/SpannableString;]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Ljava/lang/CharSequence;Landroid/text/Layout$SpannedEllipsizer;,Landroid/text/SpannableString;
+HSPLandroid/text/Layout;->drawText(Landroid/graphics/Canvas;II)V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;,Landroid/text/DynamicLayout;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/Spanned;Landroid/text/SpannableString;]Ljava/lang/CharSequence;Landroid/text/SpannableString;
 HSPLandroid/text/Layout;->drawWithoutText(Landroid/graphics/Canvas;Ljava/util/List;Ljava/util/List;Landroid/graphics/Path;Landroid/graphics/Paint;III)V
 HSPLandroid/text/Layout;->ellipsize(III[CILandroid/text/TextUtils$TruncateAt;)V
 HSPLandroid/text/Layout;->getCursorPath(ILandroid/graphics/Path;Ljava/lang/CharSequence;)V
@@ -14728,30 +14790,30 @@
 HSPLandroid/text/Layout;->getHorizontal(IZ)F
 HSPLandroid/text/Layout;->getHorizontal(IZIZ)F
 HSPLandroid/text/Layout;->getIndentAdjust(ILandroid/text/Layout$Alignment;)I
-HSPLandroid/text/Layout;->getLineBaseline(I)I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;
+HSPLandroid/text/Layout;->getLineBaseline(I)I
 HSPLandroid/text/Layout;->getLineBottom(I)I
 HSPLandroid/text/Layout;->getLineBottom(IZ)I
-HSPLandroid/text/Layout;->getLineEnd(I)I
-HSPLandroid/text/Layout;->getLineExtent(ILandroid/text/Layout$TabStops;Z)F+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/TextPaint;Landroid/text/TextPaint;
+HSPLandroid/text/Layout;->getLineEnd(I)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;,Landroid/text/StaticLayout;
+HSPLandroid/text/Layout;->getLineExtent(ILandroid/text/Layout$TabStops;Z)F
 HSPLandroid/text/Layout;->getLineExtent(IZ)F
-HSPLandroid/text/Layout;->getLineForOffset(I)I+]Landroid/text/Layout;Landroid/text/StaticLayout;
-HSPLandroid/text/Layout;->getLineForVertical(I)I+]Landroid/text/Layout;Landroid/text/BoringLayout;
+HSPLandroid/text/Layout;->getLineForOffset(I)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;
+HSPLandroid/text/Layout;->getLineForVertical(I)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;
 HSPLandroid/text/Layout;->getLineLeft(I)F
 HSPLandroid/text/Layout;->getLineMax(I)F
-HSPLandroid/text/Layout;->getLineRangeForDraw(Landroid/graphics/Canvas;)J+]Landroid/graphics/Canvas;missing_types]Landroid/text/Layout;Landroid/text/StaticLayout;
+HSPLandroid/text/Layout;->getLineRangeForDraw(Landroid/graphics/Canvas;)J+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/text/Layout;->getLineRight(I)F
 HSPLandroid/text/Layout;->getLineStartPos(III)I
 HSPLandroid/text/Layout;->getLineVisibleEnd(I)I
 HSPLandroid/text/Layout;->getLineWidth(I)F
 HSPLandroid/text/Layout;->getOffsetAtStartOf(I)I
 HSPLandroid/text/Layout;->getOffsetForHorizontal(IF)I
-HSPLandroid/text/Layout;->getOffsetForHorizontal(IFZ)I
+HSPLandroid/text/Layout;->getOffsetForHorizontal(IFZ)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;]Landroid/text/TextLine;Landroid/text/TextLine;]Landroid/text/Layout$HorizontalMeasurementProvider;Landroid/text/Layout$HorizontalMeasurementProvider;
 HSPLandroid/text/Layout;->getPaint()Landroid/text/TextPaint;
-HSPLandroid/text/Layout;->getParagraphAlignment(I)Landroid/text/Layout$Alignment;
-HSPLandroid/text/Layout;->getParagraphLeadingMargin(I)I
+HSPLandroid/text/Layout;->getParagraphAlignment(I)Landroid/text/Layout$Alignment;+]Landroid/text/Layout;Landroid/text/DynamicLayout;
+HSPLandroid/text/Layout;->getParagraphLeadingMargin(I)I+]Landroid/text/Layout;Landroid/text/DynamicLayout;]Landroid/text/Spanned;missing_types
 HSPLandroid/text/Layout;->getParagraphLeft(I)I
 HSPLandroid/text/Layout;->getParagraphRight(I)I
-HSPLandroid/text/Layout;->getParagraphSpans(Landroid/text/Spanned;IILjava/lang/Class;)[Ljava/lang/Object;
+HSPLandroid/text/Layout;->getParagraphSpans(Landroid/text/Spanned;IILjava/lang/Class;)[Ljava/lang/Object;+]Landroid/text/Spanned;Landroid/text/SpannableString;
 HSPLandroid/text/Layout;->getPrimaryHorizontal(I)F
 HSPLandroid/text/Layout;->getPrimaryHorizontal(IZ)F
 HSPLandroid/text/Layout;->getSelection(IILandroid/text/Layout$SelectionRectangleConsumer;)V
@@ -14770,7 +14832,8 @@
 HSPLandroid/text/Layout;->replaceWith(Ljava/lang/CharSequence;Landroid/text/TextPaint;ILandroid/text/Layout$Alignment;FF)V
 HSPLandroid/text/Layout;->shouldClampCursor(I)Z
 HSPLandroid/text/MeasuredParagraph;-><init>()V
-HSPLandroid/text/MeasuredParagraph;->applyMetricsAffectingSpan(Landroid/text/TextPaint;Landroid/graphics/text/LineBreakConfig;[Landroid/text/style/MetricAffectingSpan;[Landroid/text/style/LineBreakConfigSpan;IILandroid/graphics/text/MeasuredText$Builder;Landroid/text/MeasuredParagraph$StyleRunCallback;)V+]Landroid/graphics/text/LineBreakConfig$Builder;Landroid/graphics/text/LineBreakConfig$Builder;]Landroid/text/AutoGrowArray$IntArray;Landroid/text/AutoGrowArray$IntArray;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/text/style/MetricAffectingSpan;missing_types
+HSPLandroid/text/MeasuredParagraph;->applyMetricsAffectingSpan(Landroid/text/TextPaint;Landroid/graphics/text/LineBreakConfig;[Landroid/text/style/MetricAffectingSpan;[Landroid/text/style/LineBreakConfigSpan;IILandroid/graphics/text/MeasuredText$Builder;Landroid/text/MeasuredParagraph$StyleRunCallback;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/graphics/text/LineBreakConfig$Builder;Landroid/graphics/text/LineBreakConfig$Builder;]Landroid/text/AutoGrowArray$IntArray;Landroid/text/AutoGrowArray$IntArray;]Landroid/text/style/MetricAffectingSpan;missing_types
+HSPLandroid/text/MeasuredParagraph;->applyStyleRun(IILandroid/text/TextPaint;Landroid/graphics/text/LineBreakConfig;Landroid/graphics/text/MeasuredText$Builder;Landroid/text/MeasuredParagraph$StyleRunCallback;)V+]Landroid/text/AutoGrowArray$FloatArray;Landroid/text/AutoGrowArray$FloatArray;]Landroid/graphics/text/MeasuredText$Builder;Landroid/graphics/text/MeasuredText$Builder;]Landroid/text/AutoGrowArray$ByteArray;Landroid/text/AutoGrowArray$ByteArray;]Landroid/text/TextPaint;Landroid/text/TextPaint;
 HSPLandroid/text/MeasuredParagraph;->breakText(IZF)I
 HSPLandroid/text/MeasuredParagraph;->buildForBidi(Ljava/lang/CharSequence;IILandroid/text/TextDirectionHeuristic;Landroid/text/MeasuredParagraph;)Landroid/text/MeasuredParagraph;
 HSPLandroid/text/MeasuredParagraph;->buildForMeasurement(Landroid/text/TextPaint;Ljava/lang/CharSequence;IILandroid/text/TextDirectionHeuristic;Landroid/text/MeasuredParagraph;)Landroid/text/MeasuredParagraph;
@@ -14789,9 +14852,9 @@
 HSPLandroid/text/MeasuredParagraph;->resetAndAnalyzeBidi(Ljava/lang/CharSequence;IILandroid/text/TextDirectionHeuristic;)V
 HSPLandroid/text/PackedIntVector;->adjustValuesBelow(III)V
 HSPLandroid/text/PackedIntVector;->deleteAt(II)V
-HSPLandroid/text/PackedIntVector;->getValue(II)I
+HSPLandroid/text/PackedIntVector;->getValue(II)I+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
 HSPLandroid/text/PackedIntVector;->growBuffer()V
-HSPLandroid/text/PackedIntVector;->insertAt(I[I)V
+HSPLandroid/text/PackedIntVector;->insertAt(I[I)V+]Landroid/text/PackedIntVector;Landroid/text/PackedIntVector;
 HSPLandroid/text/PackedIntVector;->moveRowGapTo(I)V
 HSPLandroid/text/PackedIntVector;->moveValueGapTo(II)V
 HSPLandroid/text/PackedIntVector;->size()I
@@ -14799,7 +14862,7 @@
 HSPLandroid/text/PackedObjectVector;->deleteAt(II)V
 HSPLandroid/text/PackedObjectVector;->getValue(II)Ljava/lang/Object;
 HSPLandroid/text/PackedObjectVector;->growBuffer()V
-HSPLandroid/text/PackedObjectVector;->insertAt(I[Ljava/lang/Object;)V
+HSPLandroid/text/PackedObjectVector;->insertAt(I[Ljava/lang/Object;)V+]Landroid/text/PackedObjectVector;Landroid/text/PackedObjectVector;
 HSPLandroid/text/PackedObjectVector;->moveRowGapTo(I)V
 HSPLandroid/text/PackedObjectVector;->setValue(IILjava/lang/Object;)V
 HSPLandroid/text/PackedObjectVector;->size()I
@@ -14810,7 +14873,7 @@
 HSPLandroid/text/PrecomputedText$Params;->getTextDirection()Landroid/text/TextDirectionHeuristic;
 HSPLandroid/text/PrecomputedText$Params;->getTextPaint()Landroid/text/TextPaint;
 HSPLandroid/text/Selection;->getSelectionEnd(Ljava/lang/CharSequence;)I
-HSPLandroid/text/Selection;->getSelectionStart(Ljava/lang/CharSequence;)I
+HSPLandroid/text/Selection;->getSelectionStart(Ljava/lang/CharSequence;)I+]Landroid/text/Spanned;missing_types
 HSPLandroid/text/Selection;->removeMemory(Landroid/text/Spannable;)V
 HSPLandroid/text/Selection;->removeSelection(Landroid/text/Spannable;)V
 HSPLandroid/text/Selection;->setSelection(Landroid/text/Spannable;I)V
@@ -14820,7 +14883,7 @@
 HSPLandroid/text/SpanSet;-><init>(Ljava/lang/Class;)V
 HSPLandroid/text/SpanSet;->getNextTransition(II)I
 HSPLandroid/text/SpanSet;->hasSpansIntersecting(II)Z
-HSPLandroid/text/SpanSet;->init(Landroid/text/Spanned;II)V
+HSPLandroid/text/SpanSet;->init(Landroid/text/Spanned;II)V+]Landroid/text/Spanned;Landroid/text/SpannableString;
 HSPLandroid/text/SpanSet;->recycle()V
 HSPLandroid/text/Spannable$Factory;->getInstance()Landroid/text/Spannable$Factory;
 HSPLandroid/text/Spannable$Factory;->newSpannable(Ljava/lang/CharSequence;)Landroid/text/Spannable;
@@ -14838,32 +14901,32 @@
 HSPLandroid/text/SpannableString;->subSequence(II)Ljava/lang/CharSequence;
 HSPLandroid/text/SpannableString;->valueOf(Ljava/lang/CharSequence;)Landroid/text/SpannableString;
 HSPLandroid/text/SpannableStringBuilder;-><init>()V
-HSPLandroid/text/SpannableStringBuilder;-><init>(Ljava/lang/CharSequence;)V
+HSPLandroid/text/SpannableStringBuilder;-><init>(Ljava/lang/CharSequence;)V+]Ljava/lang/CharSequence;missing_types
 HSPLandroid/text/SpannableStringBuilder;-><init>(Ljava/lang/CharSequence;II)V
 HSPLandroid/text/SpannableStringBuilder;->append(C)Landroid/text/Editable;
 HSPLandroid/text/SpannableStringBuilder;->append(C)Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringBuilder;->append(Ljava/lang/CharSequence;)Landroid/text/Editable;
-HSPLandroid/text/SpannableStringBuilder;->append(Ljava/lang/CharSequence;)Landroid/text/SpannableStringBuilder;
+HSPLandroid/text/SpannableStringBuilder;->append(Ljava/lang/CharSequence;)Landroid/text/SpannableStringBuilder;+]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/SpannedString;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringBuilder;->append(Ljava/lang/CharSequence;II)Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringBuilder;->calcMax(I)I
-HSPLandroid/text/SpannableStringBuilder;->change(IILjava/lang/CharSequence;II)V
+HSPLandroid/text/SpannableStringBuilder;->change(IILjava/lang/CharSequence;II)V+]Landroid/text/Spanned;Landroid/text/SpannedString;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringBuilder;->charAt(I)C
-HSPLandroid/text/SpannableStringBuilder;->checkRange(Ljava/lang/String;II)V
+HSPLandroid/text/SpannableStringBuilder;->checkRange(Ljava/lang/String;II)V+]Landroid/text/SpannableStringBuilder;missing_types
 HSPLandroid/text/SpannableStringBuilder;->checkSortBuffer([II)[I
 HSPLandroid/text/SpannableStringBuilder;->clear()V
 HSPLandroid/text/SpannableStringBuilder;->compareSpans(II[I[I)I
-HSPLandroid/text/SpannableStringBuilder;->countSpans(IILjava/lang/Class;I)I
+HSPLandroid/text/SpannableStringBuilder;->countSpans(IILjava/lang/Class;I)I+]Ljava/lang/Class;Ljava/lang/Class;
 HSPLandroid/text/SpannableStringBuilder;->delete(II)Landroid/text/Editable;
 HSPLandroid/text/SpannableStringBuilder;->delete(II)Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringBuilder;->drawTextRun(Landroid/graphics/BaseCanvas;IIIIFFZLandroid/graphics/Paint;)V
 HSPLandroid/text/SpannableStringBuilder;->equals(Ljava/lang/Object;)Z
 HSPLandroid/text/SpannableStringBuilder;->getChars(II[CI)V
-HSPLandroid/text/SpannableStringBuilder;->getSpanEnd(Ljava/lang/Object;)I
-HSPLandroid/text/SpannableStringBuilder;->getSpanFlags(Ljava/lang/Object;)I
-HSPLandroid/text/SpannableStringBuilder;->getSpanStart(Ljava/lang/Object;)I
-HSPLandroid/text/SpannableStringBuilder;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;
+HSPLandroid/text/SpannableStringBuilder;->getSpanEnd(Ljava/lang/Object;)I+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
+HSPLandroid/text/SpannableStringBuilder;->getSpanFlags(Ljava/lang/Object;)I+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
+HSPLandroid/text/SpannableStringBuilder;->getSpanStart(Ljava/lang/Object;)I+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
+HSPLandroid/text/SpannableStringBuilder;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;+]Landroid/text/SpannableStringBuilder;missing_types
 HSPLandroid/text/SpannableStringBuilder;->getSpans(IILjava/lang/Class;Z)[Ljava/lang/Object;
-HSPLandroid/text/SpannableStringBuilder;->getSpansRec(IILjava/lang/Class;I[Ljava/lang/Object;[I[IIZ)I
+HSPLandroid/text/SpannableStringBuilder;->getSpansRec(IILjava/lang/Class;I[Ljava/lang/Object;[I[IIZ)I+]Ljava/lang/Class;Ljava/lang/Class;
 HSPLandroid/text/SpannableStringBuilder;->getTextWatcherDepth()I
 HSPLandroid/text/SpannableStringBuilder;->hasNonExclusiveExclusiveSpanAt(Ljava/lang/CharSequence;I)Z
 HSPLandroid/text/SpannableStringBuilder;->insert(ILjava/lang/CharSequence;)Landroid/text/SpannableStringBuilder;
@@ -14882,48 +14945,48 @@
 HSPLandroid/text/SpannableStringBuilder;->removeSpansForChange(IIZI)Z
 HSPLandroid/text/SpannableStringBuilder;->replace(IILjava/lang/CharSequence;)Landroid/text/Editable;
 HSPLandroid/text/SpannableStringBuilder;->replace(IILjava/lang/CharSequence;)Landroid/text/SpannableStringBuilder;
-HSPLandroid/text/SpannableStringBuilder;->replace(IILjava/lang/CharSequence;II)Landroid/text/SpannableStringBuilder;
+HSPLandroid/text/SpannableStringBuilder;->replace(IILjava/lang/CharSequence;II)Landroid/text/SpannableStringBuilder;+]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringBuilder;->resizeFor(I)V
 HSPLandroid/text/SpannableStringBuilder;->resolveGap(I)I
-HSPLandroid/text/SpannableStringBuilder;->restoreInvariants()V
+HSPLandroid/text/SpannableStringBuilder;->restoreInvariants()V+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
 HSPLandroid/text/SpannableStringBuilder;->rightChild(I)I
 HSPLandroid/text/SpannableStringBuilder;->sendAfterTextChanged([Landroid/text/TextWatcher;)V
 HSPLandroid/text/SpannableStringBuilder;->sendBeforeTextChanged([Landroid/text/TextWatcher;III)V
-HSPLandroid/text/SpannableStringBuilder;->sendSpanAdded(Ljava/lang/Object;II)V
+HSPLandroid/text/SpannableStringBuilder;->sendSpanAdded(Ljava/lang/Object;II)V+]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringBuilder;->sendSpanChanged(Ljava/lang/Object;IIII)V
 HSPLandroid/text/SpannableStringBuilder;->sendSpanRemoved(Ljava/lang/Object;II)V
 HSPLandroid/text/SpannableStringBuilder;->sendTextChanged([Landroid/text/TextWatcher;III)V
 HSPLandroid/text/SpannableStringBuilder;->sendToSpanWatchers(III)V
 HSPLandroid/text/SpannableStringBuilder;->setFilters([Landroid/text/InputFilter;)V
 HSPLandroid/text/SpannableStringBuilder;->setSpan(Ljava/lang/Object;III)V
-HSPLandroid/text/SpannableStringBuilder;->setSpan(ZLjava/lang/Object;IIIZ)V
+HSPLandroid/text/SpannableStringBuilder;->setSpan(ZLjava/lang/Object;IIIZ)V+]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/util/IdentityHashMap;Ljava/util/IdentityHashMap;
 HSPLandroid/text/SpannableStringBuilder;->siftDown(I[Ljava/lang/Object;I[I[I)V
 HSPLandroid/text/SpannableStringBuilder;->sort([Ljava/lang/Object;[I[I)V
 HSPLandroid/text/SpannableStringBuilder;->subSequence(II)Ljava/lang/CharSequence;
-HSPLandroid/text/SpannableStringBuilder;->toString()Ljava/lang/String;
+HSPLandroid/text/SpannableStringBuilder;->toString()Ljava/lang/String;+]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringBuilder;->treeRoot()I
 HSPLandroid/text/SpannableStringBuilder;->updatedIntervalBound(IIIIZZ)I
-HSPLandroid/text/SpannableStringInternal;-><init>(Ljava/lang/CharSequence;IIZ)V
-HSPLandroid/text/SpannableStringInternal;->charAt(I)C
-HSPLandroid/text/SpannableStringInternal;->checkRange(Ljava/lang/String;II)V
-HSPLandroid/text/SpannableStringInternal;->copySpansFromInternal(Landroid/text/SpannableStringInternal;IIZ)V
-HSPLandroid/text/SpannableStringInternal;->copySpansFromSpanned(Landroid/text/Spanned;IIZ)V
+HSPLandroid/text/SpannableStringInternal;-><init>(Ljava/lang/CharSequence;IIZ)V+]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/SpannedString;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;
+HSPLandroid/text/SpannableStringInternal;->charAt(I)C+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/text/SpannableStringInternal;->checkRange(Ljava/lang/String;II)V+]Landroid/text/SpannableStringInternal;Landroid/text/SpannedString;,Landroid/text/SpannableString;
+HSPLandroid/text/SpannableStringInternal;->copySpansFromInternal(Landroid/text/SpannableStringInternal;IIZ)V+]Landroid/text/SpannableStringInternal;Landroid/text/SpannedString;,Landroid/text/SpannableString;
+HSPLandroid/text/SpannableStringInternal;->copySpansFromSpanned(Landroid/text/Spanned;IIZ)V+]Landroid/text/Spanned;Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannableStringInternal;->equals(Ljava/lang/Object;)Z
-HSPLandroid/text/SpannableStringInternal;->getChars(II[CI)V
+HSPLandroid/text/SpannableStringInternal;->getChars(II[CI)V+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/text/SpannableStringInternal;->getSpanEnd(Ljava/lang/Object;)I
 HSPLandroid/text/SpannableStringInternal;->getSpanFlags(Ljava/lang/Object;)I
 HSPLandroid/text/SpannableStringInternal;->getSpanStart(Ljava/lang/Object;)I
-HSPLandroid/text/SpannableStringInternal;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;
-HSPLandroid/text/SpannableStringInternal;->length()I
+HSPLandroid/text/SpannableStringInternal;->getSpans(IILjava/lang/Class;)[Ljava/lang/Object;+]Ljava/lang/Class;Ljava/lang/Class;]Landroid/text/SpannableStringInternal;Landroid/text/SpannableString;
+HSPLandroid/text/SpannableStringInternal;->length()I+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/text/SpannableStringInternal;->nextSpanTransition(IILjava/lang/Class;)I
 HSPLandroid/text/SpannableStringInternal;->removeSpan(Ljava/lang/Object;I)V
-HSPLandroid/text/SpannableStringInternal;->sendSpanAdded(Ljava/lang/Object;II)V
+HSPLandroid/text/SpannableStringInternal;->sendSpanAdded(Ljava/lang/Object;II)V+]Landroid/text/SpanWatcher;Landroid/text/DynamicLayout$ChangeWatcher;,Landroid/widget/Editor$SpanController;,Landroid/widget/TextView$ChangeWatcher;]Landroid/text/SpannableStringInternal;Landroid/text/SpannableString;
 HSPLandroid/text/SpannableStringInternal;->sendSpanChanged(Ljava/lang/Object;IIII)V
 HSPLandroid/text/SpannableStringInternal;->setSpan(Ljava/lang/Object;III)V
 HSPLandroid/text/SpannableStringInternal;->setSpan(Ljava/lang/Object;IIIZ)V
 HSPLandroid/text/SpannableStringInternal;->toString()Ljava/lang/String;
 HSPLandroid/text/SpannedString;-><init>(Ljava/lang/CharSequence;)V
-HSPLandroid/text/SpannedString;-><init>(Ljava/lang/CharSequence;Z)V
+HSPLandroid/text/SpannedString;-><init>(Ljava/lang/CharSequence;Z)V+]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/SpannedString;->equals(Ljava/lang/Object;)Z
 HSPLandroid/text/SpannedString;->getSpanEnd(Ljava/lang/Object;)I
 HSPLandroid/text/SpannedString;->getSpanFlags(Ljava/lang/Object;)I
@@ -14966,8 +15029,9 @@
 HSPLandroid/text/StaticLayout$Builder;->setMaxLines(I)Landroid/text/StaticLayout$Builder;
 HSPLandroid/text/StaticLayout$Builder;->setTextDirection(Landroid/text/TextDirectionHeuristic;)Landroid/text/StaticLayout$Builder;
 HSPLandroid/text/StaticLayout$Builder;->setUseLineSpacingFromFallbacks(Z)Landroid/text/StaticLayout$Builder;
+HSPLandroid/text/StaticLayout;-><init>(Landroid/text/StaticLayout$Builder;ZI)V+]Landroid/text/StaticLayout;Landroid/text/StaticLayout;
 HSPLandroid/text/StaticLayout;->calculateEllipsis(IILandroid/text/MeasuredParagraph;IFLandroid/text/TextUtils$TruncateAt;IFLandroid/text/TextPaint;Z)V
-HSPLandroid/text/StaticLayout;->generate(Landroid/text/StaticLayout$Builder;ZZ)V+]Landroid/graphics/text/LineBreaker$Builder;Landroid/graphics/text/LineBreaker$Builder;]Landroid/graphics/text/LineBreaker$ParagraphConstraints;Landroid/graphics/text/LineBreaker$ParagraphConstraints;]Landroid/graphics/text/LineBreaker$Result;Landroid/graphics/text/LineBreaker$Result;]Landroid/graphics/text/LineBreaker;Landroid/graphics/text/LineBreaker;]Landroid/text/AutoGrowArray$IntArray;Landroid/text/AutoGrowArray$IntArray;]Landroid/text/MeasuredParagraph;Landroid/text/MeasuredParagraph;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/text/StaticLayout;->generate(Landroid/text/StaticLayout$Builder;ZZ)V+]Landroid/text/MeasuredParagraph;Landroid/text/MeasuredParagraph;]Landroid/graphics/text/LineBreaker$Builder;Landroid/graphics/text/LineBreaker$Builder;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/graphics/text/LineBreaker;Landroid/graphics/text/LineBreaker;]Ljava/lang/CharSequence;Landroid/text/SpannableString;]Landroid/graphics/text/LineBreaker$ParagraphConstraints;Landroid/graphics/text/LineBreaker$ParagraphConstraints;]Landroid/graphics/text/LineBreaker$Result;Landroid/graphics/text/LineBreaker$Result;]Landroid/text/AutoGrowArray$IntArray;Landroid/text/AutoGrowArray$IntArray;
 HSPLandroid/text/StaticLayout;->getBottomPadding()I
 HSPLandroid/text/StaticLayout;->getEllipsisCount(I)I
 HSPLandroid/text/StaticLayout;->getEllipsisStart(I)I
@@ -14977,7 +15041,7 @@
 HSPLandroid/text/StaticLayout;->getLineContainsTab(I)Z
 HSPLandroid/text/StaticLayout;->getLineCount()I
 HSPLandroid/text/StaticLayout;->getLineDescent(I)I
-HSPLandroid/text/StaticLayout;->getLineDirections(I)Landroid/text/Layout$Directions;
+HSPLandroid/text/StaticLayout;->getLineDirections(I)Landroid/text/Layout$Directions;+]Landroid/text/StaticLayout;Landroid/text/StaticLayout;
 HSPLandroid/text/StaticLayout;->getLineExtra(I)I
 HSPLandroid/text/StaticLayout;->getLineForVertical(I)I
 HSPLandroid/text/StaticLayout;->getLineStart(I)I
@@ -14986,38 +15050,43 @@
 HSPLandroid/text/StaticLayout;->getStartHyphenEdit(I)I
 HSPLandroid/text/StaticLayout;->getTopPadding()I
 HSPLandroid/text/StaticLayout;->getTotalInsets(I)F
-HSPLandroid/text/StaticLayout;->out(Ljava/lang/CharSequence;IIIIIIIFF[Landroid/text/style/LineHeightSpan;[ILandroid/graphics/Paint$FontMetricsInt;ZIZLandroid/text/MeasuredParagraph;IZZZ[CILandroid/text/TextUtils$TruncateAt;FFLandroid/text/TextPaint;Z)I
+HSPLandroid/text/StaticLayout;->out(Ljava/lang/CharSequence;IIIIIIIFF[Landroid/text/style/LineHeightSpan;[ILandroid/graphics/Paint$FontMetricsInt;ZIZLandroid/text/MeasuredParagraph;IZZZ[CILandroid/text/TextUtils$TruncateAt;FFLandroid/text/TextPaint;Z)I+]Landroid/text/MeasuredParagraph;Landroid/text/MeasuredParagraph;]Ljava/lang/CharSequence;Landroid/text/SpannableString;
 HSPLandroid/text/StaticLayout;->packHyphenEdit(II)I
 HSPLandroid/text/StaticLayout;->unpackEndHyphenEdit(I)I
 HSPLandroid/text/StaticLayout;->unpackStartHyphenEdit(I)I
 HSPLandroid/text/TextDirectionHeuristics$FirstStrong;->checkRtl(Ljava/lang/CharSequence;II)I
-HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;->doCheck(Ljava/lang/CharSequence;II)Z+]Landroid/text/TextDirectionHeuristics$TextDirectionAlgorithm;Landroid/text/TextDirectionHeuristics$FirstStrong;]Landroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;Landroid/text/TextDirectionHeuristics$TextDirectionHeuristicInternal;
+HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;->doCheck(Ljava/lang/CharSequence;II)Z
 HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;->isRtl(Ljava/lang/CharSequence;II)Z
 HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicImpl;->isRtl([CII)Z
 HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicInternal;->defaultIsRtl()Z
 HSPLandroid/text/TextDirectionHeuristics$TextDirectionHeuristicLocale;->defaultIsRtl()Z
 HSPLandroid/text/TextDirectionHeuristics;->isRtlCodePoint(I)I
 HSPLandroid/text/TextFlags;->getKeyForFlag(Ljava/lang/String;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/text/TextFlags;->isFeatureEnabled(Ljava/lang/String;)Z
 HSPLandroid/text/TextLine$DecorationInfo;-><init>()V
 HSPLandroid/text/TextLine$DecorationInfo;->copyInfo()Landroid/text/TextLine$DecorationInfo;
 HSPLandroid/text/TextLine$DecorationInfo;->hasDecoration()Z
 HSPLandroid/text/TextLine;-><init>()V
 HSPLandroid/text/TextLine;->adjustEndHyphenEdit(II)I
 HSPLandroid/text/TextLine;->adjustStartHyphenEdit(II)I
-HSPLandroid/text/TextLine;->draw(Landroid/graphics/Canvas;FIII)V
+HSPLandroid/text/TextLine;->draw(Landroid/graphics/Canvas;FIII)V+]Landroid/text/Layout$Directions;Landroid/text/Layout$Directions;
 HSPLandroid/text/TextLine;->drawStroke(Landroid/text/TextPaint;Landroid/graphics/Canvas;IFFFFF)V
-HSPLandroid/text/TextLine;->drawTextRun(Landroid/graphics/Canvas;Landroid/text/TextPaint;IIIIZFI)V
+HSPLandroid/text/TextLine;->drawTextRun(Landroid/graphics/Canvas;Landroid/text/TextPaint;IIIIZFI)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/text/TextLine;->equalAttributes(Landroid/text/TextPaint;Landroid/text/TextPaint;)Z
-HSPLandroid/text/TextLine;->expandMetricsFromPaint(Landroid/graphics/Paint$FontMetricsInt;Landroid/text/TextPaint;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
+HSPLandroid/text/TextLine;->expandMetricsFromPaint(Landroid/graphics/Paint$FontMetricsInt;Landroid/text/TextPaint;)V
 HSPLandroid/text/TextLine;->expandMetricsFromPaint(Landroid/text/TextPaint;IIIIZLandroid/graphics/Paint$FontMetricsInt;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
 HSPLandroid/text/TextLine;->extractDecorationInfo(Landroid/text/TextPaint;Landroid/text/TextLine$DecorationInfo;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
-HSPLandroid/text/TextLine;->getOffsetBeforeAfter(IIIZIZ)I
+HSPLandroid/text/TextLine;->getOffsetBeforeAfter(IIIZIZ)I+]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/text/Spanned;Landroid/text/SpannableString;
 HSPLandroid/text/TextLine;->getOffsetToLeftRightOf(IZ)I
+HSPLandroid/text/TextLine;->getRunAdvance(Landroid/text/TextPaint;IIIIZI[FILandroid/graphics/RectF;Landroid/text/TextLine$LineInfo;)F+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/text/PrecomputedText;Landroid/text/PrecomputedText;]Landroid/text/TextPaint;Landroid/text/TextPaint;
 HSPLandroid/text/TextLine;->handleReplacement(Landroid/text/style/ReplacementSpan;Landroid/text/TextPaint;IIZLandroid/graphics/Canvas;FIIILandroid/graphics/Paint$FontMetricsInt;Z)F
+HSPLandroid/text/TextLine;->handleRun(IIIZLandroid/graphics/Canvas;Landroid/text/TextShaper$GlyphsConsumer;FIIILandroid/graphics/Paint$FontMetricsInt;Landroid/graphics/RectF;Z[FILandroid/text/TextLine$LineInfo;I)F+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/text/style/MetricAffectingSpan;megamorphic_types]Landroid/text/style/CharacterStyle;megamorphic_types]Landroid/text/TextPaint;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/text/TextLine$DecorationInfo;Landroid/text/TextLine$DecorationInfo;]Landroid/text/SpanSet;Landroid/text/SpanSet;
+HSPLandroid/text/TextLine;->handleText(Landroid/text/TextPaint;IIIIZLandroid/graphics/Canvas;Landroid/text/TextShaper$GlyphsConsumer;FIIILandroid/graphics/Paint$FontMetricsInt;Landroid/graphics/RectF;ZILjava/util/ArrayList;[FILandroid/text/TextLine$LineInfo;I)F+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;,Landroid/graphics/Canvas;,Landroid/view/Surface$CompatibleCanvas;
 HSPLandroid/text/TextLine;->isLineEndSpace(C)Z
+HSPLandroid/text/TextLine;->measure(IZLandroid/graphics/Paint$FontMetricsInt;Landroid/graphics/RectF;Landroid/text/TextLine$LineInfo;)F+]Landroid/text/Layout$Directions;Landroid/text/Layout$Directions;]Landroid/text/TextLine;Landroid/text/TextLine;
 HSPLandroid/text/TextLine;->obtain()Landroid/text/TextLine;
 HSPLandroid/text/TextLine;->recycle(Landroid/text/TextLine;)Landroid/text/TextLine;+]Landroid/text/SpanSet;Landroid/text/SpanSet;
-HSPLandroid/text/TextLine;->set(Landroid/text/TextPaint;Ljava/lang/CharSequence;IIILandroid/text/Layout$Directions;ZLandroid/text/Layout$TabStops;IIZ)V
+HSPLandroid/text/TextLine;->set(Landroid/text/TextPaint;Ljava/lang/CharSequence;IIILandroid/text/Layout$Directions;ZLandroid/text/Layout$TabStops;IIZ)V+]Landroid/text/SpanSet;Landroid/text/SpanSet;
 HSPLandroid/text/TextLine;->updateMetrics(Landroid/graphics/Paint$FontMetricsInt;IIIII)V
 HSPLandroid/text/TextPaint;-><init>()V
 HSPLandroid/text/TextPaint;-><init>(I)V
@@ -15025,8 +15094,8 @@
 HSPLandroid/text/TextPaint;->getUnderlineThickness()F
 HSPLandroid/text/TextPaint;->set(Landroid/text/TextPaint;)V
 HSPLandroid/text/TextPaint;->setUnderlineText(IF)V
-HSPLandroid/text/TextUtils$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/CharSequence;
-HSPLandroid/text/TextUtils$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
+HSPLandroid/text/TextUtils$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/CharSequence;+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/text/TextUtils$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/text/TextUtils$1;Landroid/text/TextUtils$1;
 HSPLandroid/text/TextUtils$SimpleStringSplitter;-><init>(C)V
 HSPLandroid/text/TextUtils$SimpleStringSplitter;->hasNext()Z
 HSPLandroid/text/TextUtils$SimpleStringSplitter;->iterator()Ljava/util/Iterator;
@@ -15034,7 +15103,7 @@
 HSPLandroid/text/TextUtils$SimpleStringSplitter;->next()Ljava/lang/String;
 HSPLandroid/text/TextUtils$SimpleStringSplitter;->setString(Ljava/lang/String;)V
 HSPLandroid/text/TextUtils$StringWithRemovedChars;->toString()Ljava/lang/String;
-HSPLandroid/text/TextUtils;->concat([Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
+HSPLandroid/text/TextUtils;->concat([Ljava/lang/CharSequence;)Ljava/lang/CharSequence;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/text/SpannableStringBuilder;Landroid/text/SpannableStringBuilder;
 HSPLandroid/text/TextUtils;->copySpansFrom(Landroid/text/Spanned;IILjava/lang/Class;Landroid/text/Spannable;I)V
 HSPLandroid/text/TextUtils;->couldAffectRtl(C)Z
 HSPLandroid/text/TextUtils;->doesNotNeedBidi([CII)Z
@@ -15042,23 +15111,23 @@
 HSPLandroid/text/TextUtils;->ellipsize(Ljava/lang/CharSequence;Landroid/text/TextPaint;FLandroid/text/TextUtils$TruncateAt;ZLandroid/text/TextUtils$EllipsizeCallback;)Ljava/lang/CharSequence;
 HSPLandroid/text/TextUtils;->ellipsize(Ljava/lang/CharSequence;Landroid/text/TextPaint;FLandroid/text/TextUtils$TruncateAt;ZLandroid/text/TextUtils$EllipsizeCallback;Landroid/text/TextDirectionHeuristic;Ljava/lang/String;)Ljava/lang/CharSequence;
 HSPLandroid/text/TextUtils;->emptyIfNull(Ljava/lang/String;)Ljava/lang/String;
-HSPLandroid/text/TextUtils;->equals(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Z
+HSPLandroid/text/TextUtils;->equals(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Z+]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/CharSequence;Ljava/lang/String;
 HSPLandroid/text/TextUtils;->expandTemplate(Ljava/lang/CharSequence;[Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
-HSPLandroid/text/TextUtils;->formatSimple(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;+]Ljava/lang/Boolean;Ljava/lang/Boolean;]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/text/TextUtils;->formatSimple(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/Boolean;Ljava/lang/Boolean;
 HSPLandroid/text/TextUtils;->getCapsMode(Ljava/lang/CharSequence;II)I
-HSPLandroid/text/TextUtils;->getChars(Ljava/lang/CharSequence;II[CI)V+]Landroid/text/GetChars;Landroid/text/Layout$Ellipsizer;,Landroid/text/Layout$SpannedEllipsizer;,Landroid/text/SpannableString;]Ljava/lang/Object;megamorphic_types]Ljava/lang/String;Ljava/lang/String;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/text/TextUtils;->getChars(Ljava/lang/CharSequence;II[CI)V+]Ljava/lang/Object;Landroid/text/SpannableString;]Landroid/text/GetChars;Landroid/text/SpannableString;
 HSPLandroid/text/TextUtils;->getEllipsisString(Landroid/text/TextUtils$TruncateAt;)Ljava/lang/String;
 HSPLandroid/text/TextUtils;->getLayoutDirectionFromLocale(Ljava/util/Locale;)I
 HSPLandroid/text/TextUtils;->getTrimmedLength(Ljava/lang/CharSequence;)I
 HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;C)I
 HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;CI)I
-HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;CII)I
+HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;CII)I+]Ljava/lang/Object;Landroid/text/SpannableString;
 HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)I
 HSPLandroid/text/TextUtils;->indexOf(Ljava/lang/CharSequence;Ljava/lang/CharSequence;II)I
 HSPLandroid/text/TextUtils;->isDigitsOnly(Ljava/lang/CharSequence;)Z
-HSPLandroid/text/TextUtils;->isEmpty(Ljava/lang/CharSequence;)Z+]Ljava/lang/CharSequence;Landroid/text/SpannableStringBuilder;,Ljava/lang/String;
+HSPLandroid/text/TextUtils;->isEmpty(Ljava/lang/CharSequence;)Z+]Ljava/lang/CharSequence;Ljava/lang/String;
 HSPLandroid/text/TextUtils;->isGraphic(Ljava/lang/CharSequence;)Z
-HSPLandroid/text/TextUtils;->join(Ljava/lang/CharSequence;Ljava/lang/Iterable;)Ljava/lang/String;
+HSPLandroid/text/TextUtils;->join(Ljava/lang/CharSequence;Ljava/lang/Iterable;)Ljava/lang/String;+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/Iterable;missing_types]Ljava/util/Iterator;missing_types
 HSPLandroid/text/TextUtils;->join(Ljava/lang/CharSequence;[Ljava/lang/Object;)Ljava/lang/String;
 HSPLandroid/text/TextUtils;->lastIndexOf(Ljava/lang/CharSequence;CI)I
 HSPLandroid/text/TextUtils;->lastIndexOf(Ljava/lang/CharSequence;CII)I
@@ -15071,14 +15140,14 @@
 HSPLandroid/text/TextUtils;->safeIntern(Ljava/lang/String;)Ljava/lang/String;
 HSPLandroid/text/TextUtils;->split(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;
 HSPLandroid/text/TextUtils;->stringOrSpannedString(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
-HSPLandroid/text/TextUtils;->substring(Ljava/lang/CharSequence;II)Ljava/lang/String;
+HSPLandroid/text/TextUtils;->substring(Ljava/lang/CharSequence;II)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;
 HSPLandroid/text/TextUtils;->toUpperCase(Ljava/util/Locale;Ljava/lang/CharSequence;Z)Ljava/lang/CharSequence;
 HSPLandroid/text/TextUtils;->trimNoCopySpans(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
 HSPLandroid/text/TextUtils;->trimToParcelableSize(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
 HSPLandroid/text/TextUtils;->trimToSize(Ljava/lang/CharSequence;I)Ljava/lang/CharSequence;
 HSPLandroid/text/TextUtils;->unpackRangeEndFromLong(J)I
 HSPLandroid/text/TextUtils;->unpackRangeStartFromLong(J)I
-HSPLandroid/text/TextUtils;->writeToParcel(Ljava/lang/CharSequence;Landroid/os/Parcel;I)V
+HSPLandroid/text/TextUtils;->writeToParcel(Ljava/lang/CharSequence;Landroid/os/Parcel;I)V+]Ljava/lang/CharSequence;Ljava/lang/String;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/text/format/DateFormat;->format(Ljava/lang/CharSequence;J)Ljava/lang/CharSequence;
 HSPLandroid/text/format/DateFormat;->format(Ljava/lang/CharSequence;Ljava/util/Calendar;)Ljava/lang/CharSequence;
 HSPLandroid/text/format/DateFormat;->format(Ljava/lang/CharSequence;Ljava/util/Date;)Ljava/lang/CharSequence;
@@ -15185,7 +15254,7 @@
 HSPLandroid/text/method/TextKeyListener;->onSpanChanged(Landroid/text/Spannable;Ljava/lang/Object;IIII)V
 HSPLandroid/text/method/TextKeyListener;->onSpanRemoved(Landroid/text/Spannable;Ljava/lang/Object;II)V
 HSPLandroid/text/method/TextKeyListener;->updatePrefs(Landroid/content/ContentResolver;)V
-HSPLandroid/text/method/Touch;->onTouchEvent(Landroid/widget/TextView;Landroid/text/Spannable;Landroid/view/MotionEvent;)Z
+HSPLandroid/text/method/Touch;->onTouchEvent(Landroid/widget/TextView;Landroid/text/Spannable;Landroid/view/MotionEvent;)Z+]Landroid/text/Layout;Landroid/text/DynamicLayout;]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/text/Spannable;Landroid/text/SpannableString;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
 HSPLandroid/text/method/WordIterator;-><init>(Ljava/util/Locale;)V
 HSPLandroid/text/method/WordIterator;->checkOffsetIsValid(I)V
 HSPLandroid/text/method/WordIterator;->following(I)I
@@ -15204,7 +15273,7 @@
 HSPLandroid/text/style/DynamicDrawableSpan;-><init>(I)V
 HSPLandroid/text/style/ForegroundColorSpan;-><init>(I)V
 HSPLandroid/text/style/ForegroundColorSpan;->getSpanTypeIdInternal()I
-HSPLandroid/text/style/ForegroundColorSpan;->updateDrawState(Landroid/text/TextPaint;)V
+HSPLandroid/text/style/ForegroundColorSpan;->updateDrawState(Landroid/text/TextPaint;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
 HSPLandroid/text/style/ForegroundColorSpan;->writeToParcelInternal(Landroid/os/Parcel;I)V
 HSPLandroid/text/style/ImageSpan;-><init>(Landroid/graphics/drawable/Drawable;I)V
 HSPLandroid/text/style/ImageSpan;->getDrawable()Landroid/graphics/drawable/Drawable;
@@ -15270,7 +15339,7 @@
 HSPLandroid/transition/Transition$2;->onAnimationStart(Landroid/animation/Animator;)V
 HSPLandroid/transition/Transition$3;->onAnimationEnd(Landroid/animation/Animator;)V
 HSPLandroid/transition/Transition;-><init>()V
-HSPLandroid/transition/Transition;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;megamorphic_types
+HSPLandroid/transition/Transition;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Ljava/lang/Object;megamorphic_types]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Ljava/lang/Class;Ljava/lang/Class;
 HSPLandroid/transition/Transition;->addListener(Landroid/transition/Transition$TransitionListener;)Landroid/transition/Transition;
 HSPLandroid/transition/Transition;->addTarget(Landroid/view/View;)Landroid/transition/Transition;
 HSPLandroid/transition/Transition;->addUnmatched(Landroid/util/ArrayMap;Landroid/util/ArrayMap;)V
@@ -15301,7 +15370,7 @@
 HSPLandroid/transition/Transition;->start()V
 HSPLandroid/transition/TransitionInflater;-><init>(Landroid/content/Context;)V
 HSPLandroid/transition/TransitionInflater;->createCustom(Landroid/util/AttributeSet;Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Object;
-HSPLandroid/transition/TransitionInflater;->createTransitionFromXml(Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/transition/Transition;)Landroid/transition/Transition;+]Landroid/transition/TransitionSet;Landroid/transition/TransitionSet;]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/transition/TransitionInflater;->createTransitionFromXml(Lorg/xmlpull/v1/XmlPullParser;Landroid/util/AttributeSet;Landroid/transition/Transition;)Landroid/transition/Transition;
 HSPLandroid/transition/TransitionInflater;->from(Landroid/content/Context;)Landroid/transition/TransitionInflater;
 HSPLandroid/transition/TransitionInflater;->inflateTransition(I)Landroid/transition/Transition;
 HSPLandroid/transition/TransitionListenerAdapter;-><init>()V
@@ -15382,7 +15451,7 @@
 HSPLandroid/util/ArrayMap;->indexOfValue(Ljava/lang/Object;)I
 HSPLandroid/util/ArrayMap;->isEmpty()Z
 HSPLandroid/util/ArrayMap;->keyAt(I)Ljava/lang/Object;
-HSPLandroid/util/ArrayMap;->keySet()Ljava/util/Set;
+HSPLandroid/util/ArrayMap;->keySet()Ljava/util/Set;+]Landroid/util/MapCollections;Landroid/util/ArrayMap$1;
 HSPLandroid/util/ArrayMap;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/lang/Object;megamorphic_types
 HSPLandroid/util/ArrayMap;->putAll(Landroid/util/ArrayMap;)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
 HSPLandroid/util/ArrayMap;->putAll(Ljava/util/Map;)V
@@ -15405,11 +15474,11 @@
 HSPLandroid/util/ArraySet;-><init>(Landroid/util/ArraySet;)V
 HSPLandroid/util/ArraySet;-><init>(Ljava/util/Collection;)V
 HSPLandroid/util/ArraySet;-><init>([Ljava/lang/Object;)V
-HSPLandroid/util/ArraySet;->add(Ljava/lang/Object;)Z
+HSPLandroid/util/ArraySet;->add(Ljava/lang/Object;)Z+]Ljava/lang/Object;Ljava/lang/String;,Landroid/accounts/Account;,Landroid/window/SurfaceSyncGroup$2;,Landroid/net/UidRange;
 HSPLandroid/util/ArraySet;->addAll(Landroid/util/ArraySet;)V
 HSPLandroid/util/ArraySet;->addAll(Ljava/util/Collection;)Z
 HSPLandroid/util/ArraySet;->allocArrays(I)V
-HSPLandroid/util/ArraySet;->append(Ljava/lang/Object;)V+]Landroid/util/ArraySet;Landroid/util/ArraySet;]Ljava/lang/Object;Landroid/app/PendingIntent;,Lcom/android/org/conscrypt/OpenSSLRSAPublicKey;
+HSPLandroid/util/ArraySet;->append(Ljava/lang/Object;)V+]Ljava/lang/Object;Lcom/android/org/conscrypt/OpenSSLRSAPublicKey;,Lcom/android/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey;
 HSPLandroid/util/ArraySet;->binarySearch([II)I
 HSPLandroid/util/ArraySet;->clear()V
 HSPLandroid/util/ArraySet;->contains(Ljava/lang/Object;)Z
@@ -15447,11 +15516,11 @@
 HSPLandroid/util/Base64$Decoder;->process([BIIZ)Z
 HSPLandroid/util/Base64$Encoder;-><init>(I[B)V
 HSPLandroid/util/Base64$Encoder;->process([BIIZ)Z
-HSPLandroid/util/Base64;->decode(Ljava/lang/String;I)[B+]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/util/Base64;->decode(Ljava/lang/String;I)[B
 HSPLandroid/util/Base64;->decode([BI)[B
 HSPLandroid/util/Base64;->decode([BIII)[B+]Landroid/util/Base64$Decoder;Landroid/util/Base64$Decoder;
 HSPLandroid/util/Base64;->encode([BI)[B
-HSPLandroid/util/Base64;->encode([BIII)[B+]Landroid/util/Base64$Encoder;Landroid/util/Base64$Encoder;
+HSPLandroid/util/Base64;->encode([BIII)[B
 HSPLandroid/util/Base64;->encodeToString([BI)Ljava/lang/String;
 HSPLandroid/util/Base64;->encodeToString([BIII)Ljava/lang/String;
 HSPLandroid/util/CloseGuard;-><init>()V
@@ -15467,7 +15536,7 @@
 HSPLandroid/util/DisplayMetrics;->setToDefaults()V
 HSPLandroid/util/DisplayUtils;->getDisplayUniqueIdConfigIndex(Landroid/content/res/Resources;Ljava/lang/String;)I
 HSPLandroid/util/EventLog$Event;-><init>([B)V
-HSPLandroid/util/EventLog$Event;->decodeObject()Ljava/lang/Object;
+HSPLandroid/util/EventLog$Event;->decodeObject()Ljava/lang/Object;+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
 HSPLandroid/util/EventLog$Event;->getData()Ljava/lang/Object;
 HSPLandroid/util/EventLog$Event;->getHeaderSize()I
 HSPLandroid/util/EventLog$Event;->getUid()I
@@ -15495,7 +15564,7 @@
 HSPLandroid/util/IndentingPrintWriter;->write([CII)V
 HSPLandroid/util/IntArray;-><init>()V
 HSPLandroid/util/IntArray;-><init>(I)V
-HSPLandroid/util/IntArray;->add(I)V+]Landroid/util/IntArray;Landroid/util/IntArray;
+HSPLandroid/util/IntArray;->add(I)V
 HSPLandroid/util/IntArray;->add(II)V
 HSPLandroid/util/IntArray;->addAll(Landroid/util/IntArray;)V
 HSPLandroid/util/IntArray;->binarySearch(I)I
@@ -15552,9 +15621,9 @@
 HSPLandroid/util/JsonWriter;->name(Ljava/lang/String;)Landroid/util/JsonWriter;
 HSPLandroid/util/JsonWriter;->newline()V
 HSPLandroid/util/JsonWriter;->open(Landroid/util/JsonScope;Ljava/lang/String;)Landroid/util/JsonWriter;
-HSPLandroid/util/JsonWriter;->peek()Landroid/util/JsonScope;
-HSPLandroid/util/JsonWriter;->replaceTop(Landroid/util/JsonScope;)V
-HSPLandroid/util/JsonWriter;->string(Ljava/lang/String;)V
+HSPLandroid/util/JsonWriter;->peek()Landroid/util/JsonScope;+]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/util/JsonWriter;->replaceTop(Landroid/util/JsonScope;)V+]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/util/JsonWriter;->string(Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;]Ljava/io/Writer;Ljava/io/BufferedWriter;
 HSPLandroid/util/JsonWriter;->value(J)Landroid/util/JsonWriter;
 HSPLandroid/util/JsonWriter;->value(Ljava/lang/String;)Landroid/util/JsonWriter;
 HSPLandroid/util/JsonWriter;->value(Z)Landroid/util/JsonWriter;
@@ -15627,21 +15696,21 @@
 HSPLandroid/util/LruCache;->create(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/util/LruCache;->entryRemoved(ZLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V
 HSPLandroid/util/LruCache;->evictAll()V
-HSPLandroid/util/LruCache;->get(Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/util/LruCache;->get(Ljava/lang/Object;)Ljava/lang/Object;+]Ljava/util/LinkedHashMap;Ljava/util/LinkedHashMap;]Landroid/util/LruCache;missing_types
 HSPLandroid/util/LruCache;->hitCount()I
 HSPLandroid/util/LruCache;->maxSize()I
 HSPLandroid/util/LruCache;->missCount()I
-HSPLandroid/util/LruCache;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+HSPLandroid/util/LruCache;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+]Ljava/util/LinkedHashMap;Ljava/util/LinkedHashMap;]Landroid/util/LruCache;Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;,Landroid/util/LruCache;
 HSPLandroid/util/LruCache;->remove(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/util/LruCache;->resize(I)V
 HSPLandroid/util/LruCache;->safeSizeOf(Ljava/lang/Object;Ljava/lang/Object;)I
 HSPLandroid/util/LruCache;->size()I
 HSPLandroid/util/LruCache;->sizeOf(Ljava/lang/Object;Ljava/lang/Object;)I
 HSPLandroid/util/LruCache;->snapshot()Ljava/util/Map;
-HSPLandroid/util/LruCache;->trimToSize(I)V
-HSPLandroid/util/MapCollections$ArrayIterator;-><init>(Landroid/util/MapCollections;I)V
+HSPLandroid/util/LruCache;->trimToSize(I)V+]Ljava/util/LinkedHashMap;Ljava/util/LinkedHashMap;]Landroid/util/LruCache;Landroid/database/sqlite/SQLiteConnection$PreparedStatementCache;
+HSPLandroid/util/MapCollections$ArrayIterator;-><init>(Landroid/util/MapCollections;I)V+]Landroid/util/MapCollections;Landroid/util/ArraySet$1;,Landroid/util/ArrayMap$1;
 HSPLandroid/util/MapCollections$ArrayIterator;->hasNext()Z
-HSPLandroid/util/MapCollections$ArrayIterator;->next()Ljava/lang/Object;
+HSPLandroid/util/MapCollections$ArrayIterator;->next()Ljava/lang/Object;+]Landroid/util/MapCollections$ArrayIterator;Landroid/util/MapCollections$ArrayIterator;]Landroid/util/MapCollections;Landroid/util/ArraySet$1;,Landroid/util/ArrayMap$1;
 HSPLandroid/util/MapCollections$ArrayIterator;->remove()V
 HSPLandroid/util/MapCollections$EntrySet;-><init>(Landroid/util/MapCollections;)V
 HSPLandroid/util/MapCollections$EntrySet;->iterator()Ljava/util/Iterator;
@@ -15763,16 +15832,16 @@
 HSPLandroid/util/SparseArray;->clear()V
 HSPLandroid/util/SparseArray;->clone()Landroid/util/SparseArray;
 HSPLandroid/util/SparseArray;->contains(I)Z
-HSPLandroid/util/SparseArray;->contentEquals(Landroid/util/SparseArray;)Z+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/util/SparseArray;->contentEquals(Landroid/util/SparseArray;)Z
 HSPLandroid/util/SparseArray;->delete(I)V
 HSPLandroid/util/SparseArray;->gc()V
-HSPLandroid/util/SparseArray;->get(I)Ljava/lang/Object;+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/util/SparseArray;->get(I)Ljava/lang/Object;+]Landroid/util/SparseArray;missing_types
 HSPLandroid/util/SparseArray;->get(ILjava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/util/SparseArray;->indexOfKey(I)I
 HSPLandroid/util/SparseArray;->indexOfValue(Ljava/lang/Object;)I
 HSPLandroid/util/SparseArray;->keyAt(I)I
 HSPLandroid/util/SparseArray;->put(ILjava/lang/Object;)V
-HSPLandroid/util/SparseArray;->remove(I)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/util/SparseArray;->remove(I)V
 HSPLandroid/util/SparseArray;->removeAt(I)V
 HSPLandroid/util/SparseArray;->removeReturnOld(I)Ljava/lang/Object;
 HSPLandroid/util/SparseArray;->setValueAt(ILjava/lang/Object;)V
@@ -15938,7 +16007,7 @@
 HSPLandroid/view/AbsSavedState$2;->createFromParcel(Landroid/os/Parcel;Ljava/lang/ClassLoader;)Ljava/lang/Object;
 HSPLandroid/view/AbsSavedState;-><init>(Landroid/os/Parcelable;)V
 HSPLandroid/view/AbsSavedState;->getSuperState()Landroid/os/Parcelable;
-HSPLandroid/view/AbsSavedState;->writeToParcel(Landroid/os/Parcel;I)V+]Landroid/os/Parcel;Landroid/os/Parcel;
+HSPLandroid/view/AbsSavedState;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/view/Choreographer$1;->initialValue()Landroid/view/Choreographer;
 HSPLandroid/view/Choreographer$1;->initialValue()Ljava/lang/Object;
 HSPLandroid/view/Choreographer$2;->initialValue()Landroid/view/Choreographer;
@@ -15950,8 +16019,8 @@
 HSPLandroid/view/Choreographer$CallbackQueue;->removeCallbacksLocked(Ljava/lang/Object;Ljava/lang/Object;)V
 HSPLandroid/view/Choreographer$CallbackRecord;-><init>()V
 HSPLandroid/view/Choreographer$CallbackRecord;-><init>(Landroid/view/Choreographer$CallbackRecord-IA;)V
-HSPLandroid/view/Choreographer$CallbackRecord;->run(J)V+]Landroid/view/Choreographer$FrameCallback;missing_types]Ljava/lang/Runnable;Landroid/view/ViewPropertyAnimator$1;,Landroid/view/ViewRootImpl$ConsumeBatchedInputRunnable;,Landroid/view/ViewRootImpl$TraversalRunnable;,Lcom/android/internal/util/function/pooled/PooledLambdaImpl;
-HSPLandroid/view/Choreographer$CallbackRecord;->run(Landroid/view/Choreographer$FrameData;)V+]Landroid/view/Choreographer$CallbackRecord;Landroid/view/Choreographer$CallbackRecord;]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;
+HSPLandroid/view/Choreographer$CallbackRecord;->run(J)V+]Landroid/view/Choreographer$FrameCallback;missing_types]Ljava/lang/Runnable;missing_types
+HSPLandroid/view/Choreographer$CallbackRecord;->run(Landroid/view/Choreographer$FrameData;)V+]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;]Landroid/view/Choreographer$CallbackRecord;Landroid/view/Choreographer$CallbackRecord;
 HSPLandroid/view/Choreographer$FrameData;->-$$Nest$fgetmFrameTimeNanos(Landroid/view/Choreographer$FrameData;)J
 HSPLandroid/view/Choreographer$FrameData;-><init>()V
 HSPLandroid/view/Choreographer$FrameData;->allocateFrameTimelines(I)V
@@ -15964,7 +16033,7 @@
 HSPLandroid/view/Choreographer$FrameData;->update(JLandroid/view/DisplayEventReceiver$VsyncEventData;)Landroid/view/Choreographer$FrameTimeline;+]Landroid/view/Choreographer$FrameTimeline;Landroid/view/Choreographer$FrameTimeline;
 HSPLandroid/view/Choreographer$FrameData;->update(JLandroid/view/DisplayEventReceiver;J)Landroid/view/Choreographer$FrameTimeline;
 HSPLandroid/view/Choreographer$FrameDisplayEventReceiver;-><init>(Landroid/view/Choreographer;Landroid/os/Looper;IJ)V
-HSPLandroid/view/Choreographer$FrameDisplayEventReceiver;->onVsync(JJILandroid/view/DisplayEventReceiver$VsyncEventData;)V+]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;]Landroid/view/DisplayEventReceiver$VsyncEventData;Landroid/view/DisplayEventReceiver$VsyncEventData;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/Choreographer$FrameDisplayEventReceiver;->onVsync(JJILandroid/view/DisplayEventReceiver$VsyncEventData;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;]Landroid/view/DisplayEventReceiver$VsyncEventData;Landroid/view/DisplayEventReceiver$VsyncEventData;
 HSPLandroid/view/Choreographer$FrameDisplayEventReceiver;->run()V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
 HSPLandroid/view/Choreographer$FrameHandler;-><init>(Landroid/view/Choreographer;Landroid/os/Looper;)V
 HSPLandroid/view/Choreographer$FrameHandler;->handleMessage(Landroid/os/Message;)V
@@ -15983,13 +16052,13 @@
 HSPLandroid/view/Choreographer;-><init>(Landroid/os/Looper;IJ)V
 HSPLandroid/view/Choreographer;-><init>(Landroid/os/Looper;ILandroid/view/Choreographer-IA;)V
 HSPLandroid/view/Choreographer;->doCallbacks(IJ)V+]Landroid/view/Choreographer$CallbackQueue;Landroid/view/Choreographer$CallbackQueue;]Landroid/view/Choreographer$CallbackRecord;Landroid/view/Choreographer$CallbackRecord;]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;
-HSPLandroid/view/Choreographer;->doFrame(JILandroid/view/DisplayEventReceiver$VsyncEventData;)V+]Landroid/graphics/FrameInfo;Landroid/graphics/FrameInfo;]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/DisplayEventReceiver$VsyncEventData;Landroid/view/DisplayEventReceiver$VsyncEventData;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/Choreographer;->doFrame(JILandroid/view/DisplayEventReceiver$VsyncEventData;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/Choreographer$FrameData;Landroid/view/Choreographer$FrameData;]Landroid/graphics/FrameInfo;Landroid/graphics/FrameInfo;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/DisplayEventReceiver$VsyncEventData;Landroid/view/DisplayEventReceiver$VsyncEventData;
 HSPLandroid/view/Choreographer;->doScheduleCallback(I)V
 HSPLandroid/view/Choreographer;->doScheduleVsync()V
 HSPLandroid/view/Choreographer;->getFrameIntervalNanos()J
-HSPLandroid/view/Choreographer;->getFrameTime()J
+HSPLandroid/view/Choreographer;->getFrameTime()J+]Landroid/view/Choreographer;Landroid/view/Choreographer;
 HSPLandroid/view/Choreographer;->getFrameTimeNanos()J
-HSPLandroid/view/Choreographer;->getInstance()Landroid/view/Choreographer;+]Ljava/lang/ThreadLocal;Landroid/view/Choreographer$1;
+HSPLandroid/view/Choreographer;->getInstance()Landroid/view/Choreographer;
 HSPLandroid/view/Choreographer;->getMainThreadInstance()Landroid/view/Choreographer;
 HSPLandroid/view/Choreographer;->getRefreshRate()F
 HSPLandroid/view/Choreographer;->getSfInstance()Landroid/view/Choreographer;
@@ -15998,14 +16067,14 @@
 HSPLandroid/view/Choreographer;->obtainCallbackLocked(JLjava/lang/Object;Ljava/lang/Object;)Landroid/view/Choreographer$CallbackRecord;
 HSPLandroid/view/Choreographer;->postCallback(ILjava/lang/Runnable;Ljava/lang/Object;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
 HSPLandroid/view/Choreographer;->postCallbackDelayed(ILjava/lang/Runnable;Ljava/lang/Object;J)V
-HSPLandroid/view/Choreographer;->postCallbackDelayedInternal(ILjava/lang/Object;Ljava/lang/Object;J)V+]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$CallbackQueue;Landroid/view/Choreographer$CallbackQueue;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;
+HSPLandroid/view/Choreographer;->postCallbackDelayedInternal(ILjava/lang/Object;Ljava/lang/Object;J)V+]Landroid/view/Choreographer$CallbackQueue;Landroid/view/Choreographer$CallbackQueue;]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;
 HSPLandroid/view/Choreographer;->postFrameCallback(Landroid/view/Choreographer$FrameCallback;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
 HSPLandroid/view/Choreographer;->postFrameCallbackDelayed(Landroid/view/Choreographer$FrameCallback;J)V
 HSPLandroid/view/Choreographer;->recycleCallbackLocked(Landroid/view/Choreographer$CallbackRecord;)V
 HSPLandroid/view/Choreographer;->removeCallbacks(ILjava/lang/Runnable;Ljava/lang/Object;)V
-HSPLandroid/view/Choreographer;->removeCallbacksInternal(ILjava/lang/Object;Ljava/lang/Object;)V+]Landroid/view/Choreographer$CallbackQueue;Landroid/view/Choreographer$CallbackQueue;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;
+HSPLandroid/view/Choreographer;->removeCallbacksInternal(ILjava/lang/Object;Ljava/lang/Object;)V
 HSPLandroid/view/Choreographer;->removeFrameCallback(Landroid/view/Choreographer$FrameCallback;)V
-HSPLandroid/view/Choreographer;->scheduleFrameLocked(J)V+]Landroid/os/Message;Landroid/os/Message;]Landroid/view/Choreographer$FrameHandler;Landroid/view/Choreographer$FrameHandler;
+HSPLandroid/view/Choreographer;->scheduleFrameLocked(J)V
 HSPLandroid/view/Choreographer;->scheduleVsyncLocked()V+]Landroid/view/Choreographer$FrameDisplayEventReceiver;Landroid/view/Choreographer$FrameDisplayEventReceiver;
 HSPLandroid/view/Choreographer;->setFPSDivisor(I)V
 HSPLandroid/view/ContextThemeWrapper;-><init>()V
@@ -16018,7 +16087,7 @@
 HSPLandroid/view/ContextThemeWrapper;->getResourcesInternal()Landroid/content/res/Resources;
 HSPLandroid/view/ContextThemeWrapper;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
 HSPLandroid/view/ContextThemeWrapper;->getTheme()Landroid/content/res/Resources$Theme;+]Landroid/view/ContextThemeWrapper;Landroid/view/ContextThemeWrapper;
-HSPLandroid/view/ContextThemeWrapper;->initializeTheme()V+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/view/ContextThemeWrapper;Landroid/view/ContextThemeWrapper;
+HSPLandroid/view/ContextThemeWrapper;->initializeTheme()V
 HSPLandroid/view/ContextThemeWrapper;->onApplyThemeResource(Landroid/content/res/Resources$Theme;IZ)V
 HSPLandroid/view/ContextThemeWrapper;->setTheme(I)V
 HSPLandroid/view/CrossWindowBlurListeners;-><clinit>()V
@@ -16046,7 +16115,7 @@
 HSPLandroid/view/Display$Mode;->toString()Ljava/lang/String;
 HSPLandroid/view/Display;-><init>(Landroid/hardware/display/DisplayManagerGlobal;ILandroid/view/DisplayInfo;Landroid/content/res/Resources;)V
 HSPLandroid/view/Display;-><init>(Landroid/hardware/display/DisplayManagerGlobal;ILandroid/view/DisplayInfo;Landroid/view/DisplayAdjustments;)V
-HSPLandroid/view/Display;-><init>(Landroid/hardware/display/DisplayManagerGlobal;ILandroid/view/DisplayInfo;Landroid/view/DisplayAdjustments;Landroid/content/res/Resources;)V+]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/view/Display;-><init>(Landroid/hardware/display/DisplayManagerGlobal;ILandroid/view/DisplayInfo;Landroid/view/DisplayAdjustments;Landroid/content/res/Resources;)V
 HSPLandroid/view/Display;->getAppVsyncOffsetNanos()J
 HSPLandroid/view/Display;->getCutout()Landroid/view/DisplayCutout;
 HSPLandroid/view/Display;->getDisplayAdjustments()Landroid/view/DisplayAdjustments;
@@ -16056,7 +16125,7 @@
 HSPLandroid/view/Display;->getHdrSdrRatio()F
 HSPLandroid/view/Display;->getHeight()I
 HSPLandroid/view/Display;->getInstallOrientation()I
-HSPLandroid/view/Display;->getLocalRotation()I
+HSPLandroid/view/Display;->getLocalRotation()I+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
 HSPLandroid/view/Display;->getMetrics(Landroid/util/DisplayMetrics;)V
 HSPLandroid/view/Display;->getMode()Landroid/view/Display$Mode;
 HSPLandroid/view/Display;->getName()Ljava/lang/String;
@@ -16102,7 +16171,7 @@
 HSPLandroid/view/DisplayCutout$Bounds;->getRects()[Landroid/graphics/Rect;
 HSPLandroid/view/DisplayCutout$Bounds;->isEmpty()Z
 HSPLandroid/view/DisplayCutout$CutoutPathParserInfo;-><init>(IIIIFLjava/lang/String;IFF)V
-HSPLandroid/view/DisplayCutout$CutoutPathParserInfo;->equals(Ljava/lang/Object;)Z+]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/view/DisplayCutout$CutoutPathParserInfo;->equals(Ljava/lang/Object;)Z
 HSPLandroid/view/DisplayCutout$ParcelableWrapper$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/DisplayCutout$ParcelableWrapper;
 HSPLandroid/view/DisplayCutout$ParcelableWrapper$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/view/DisplayCutout$ParcelableWrapper;-><init>()V
@@ -16130,7 +16199,7 @@
 HSPLandroid/view/DisplayCutout;->inset(IIII)Landroid/view/DisplayCutout;
 HSPLandroid/view/DisplayCutout;->insetInsets(IIIILandroid/graphics/Rect;)Landroid/graphics/Rect;
 HSPLandroid/view/DisplayCutout;->isBoundsEmpty()Z
-HSPLandroid/view/DisplayCutout;->isEmpty()Z
+HSPLandroid/view/DisplayCutout;->isEmpty()Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;
 HSPLandroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;-><init>()V
 HSPLandroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;-><init>(JJJ)V
 HSPLandroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;->copyFrom(Landroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;)V
@@ -16149,19 +16218,19 @@
 HSPLandroid/view/DisplayInfo;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/view/DisplayInfo;-><init>(Landroid/os/Parcel;Landroid/view/DisplayInfo-IA;)V
 HSPLandroid/view/DisplayInfo;->copyFrom(Landroid/view/DisplayInfo;)V
-HSPLandroid/view/DisplayInfo;->equals(Landroid/view/DisplayInfo;)Z
+HSPLandroid/view/DisplayInfo;->equals(Landroid/view/DisplayInfo;)Z+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/DisplayInfo;Landroid/view/DisplayInfo;
 HSPLandroid/view/DisplayInfo;->findMode(I)Landroid/view/Display$Mode;
 HSPLandroid/view/DisplayInfo;->flagsToString(I)Ljava/lang/String;
 HSPLandroid/view/DisplayInfo;->getAppMetrics(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;)V
 HSPLandroid/view/DisplayInfo;->getAppMetrics(Landroid/util/DisplayMetrics;Landroid/view/DisplayAdjustments;)V
 HSPLandroid/view/DisplayInfo;->getLogicalMetrics(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;)V
 HSPLandroid/view/DisplayInfo;->getMaxBoundsMetrics(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;)V
-HSPLandroid/view/DisplayInfo;->getMetricsWithSize(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;II)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/view/DisplayInfo;->getMetricsWithSize(Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;Landroid/content/res/Configuration;II)V+]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
 HSPLandroid/view/DisplayInfo;->getMode()Landroid/view/Display$Mode;
 HSPLandroid/view/DisplayInfo;->getRefreshRate()F
 HSPLandroid/view/DisplayInfo;->hasAccess(I)Z
 HSPLandroid/view/DisplayInfo;->isWideColorGamut()Z
-HSPLandroid/view/DisplayInfo;->readFromParcel(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/view/Display$Mode$1;
+HSPLandroid/view/DisplayInfo;->readFromParcel(Landroid/os/Parcel;)V
 HSPLandroid/view/DisplayInfo;->toString()Ljava/lang/String;
 HSPLandroid/view/DisplayInfo;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/view/DisplayShape$1;-><init>()V
@@ -16245,6 +16314,7 @@
 HSPLandroid/view/HandwritingInitiator;->onInputConnectionCreated(Landroid/view/View;)V
 HSPLandroid/view/HandwritingInitiator;->onTouchEvent(Landroid/view/MotionEvent;)Z
 HSPLandroid/view/HandwritingInitiator;->updateHandwritingAreasForView(Landroid/view/View;)V
+HSPLandroid/view/HdrRenderState;->updateForFrame(J)Z
 HSPLandroid/view/IGraphicsStats$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 HSPLandroid/view/IGraphicsStats$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/view/IGraphicsStats$Stub$Proxy;->requestBufferForProcess(Ljava/lang/String;Landroid/view/IGraphicsStatsCallback;)Landroid/os/ParcelFileDescriptor;
@@ -16277,7 +16347,8 @@
 HSPLandroid/view/IWindowSession$Stub$Proxy;->getWindowId(Landroid/os/IBinder;)Landroid/view/IWindowId;
 HSPLandroid/view/IWindowSession$Stub$Proxy;->onRectangleOnScreenRequested(Landroid/os/IBinder;Landroid/graphics/Rect;)V
 HSPLandroid/view/IWindowSession$Stub$Proxy;->pokeDrawLock(Landroid/os/IBinder;)V
-HSPLandroid/view/IWindowSession$Stub$Proxy;->relayoutAsync(Landroid/view/IWindow;Landroid/view/WindowManager$LayoutParams;IIIIII)V
+HSPLandroid/view/IWindowSession$Stub$Proxy;->relayout(Landroid/view/IWindow;Landroid/view/WindowManager$LayoutParams;IIIIIILandroid/window/ClientWindowFrames;Landroid/util/MergedConfiguration;Landroid/view/SurfaceControl;Landroid/view/InsetsState;Landroid/view/InsetsSourceControl$Array;Landroid/os/Bundle;)I
+HSPLandroid/view/IWindowSession$Stub$Proxy;->relayoutAsync(Landroid/view/IWindow;Landroid/view/WindowManager$LayoutParams;IIIIII)V+]Landroid/os/IBinder;Landroid/os/BinderProxy;]Landroid/view/IWindowSession$Stub$Proxy;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/os/Parcel;Landroid/os/Parcel;
 HSPLandroid/view/IWindowSession$Stub$Proxy;->reportSystemGestureExclusionChanged(Landroid/view/IWindow;Ljava/util/List;)V
 HSPLandroid/view/IWindowSession$Stub$Proxy;->setInsets(Landroid/view/IWindow;ILandroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Region;)V
 HSPLandroid/view/IWindowSession$Stub$Proxy;->setOnBackInvokedCallbackInfo(Landroid/view/IWindow;Landroid/window/OnBackInvokedCallbackInfo;)V
@@ -16293,7 +16364,7 @@
 HSPLandroid/view/ImeFocusController;->onPreWindowFocus(ZLandroid/view/WindowManager$LayoutParams;)V
 HSPLandroid/view/ImeFocusController;->onProcessImeInputStage(Ljava/lang/Object;Landroid/view/InputEvent;Landroid/view/WindowManager$LayoutParams;Landroid/view/inputmethod/InputMethodManager$FinishedInputEventCallback;)I
 HSPLandroid/view/ImeFocusController;->onTraversal(ZLandroid/view/WindowManager$LayoutParams;)V
-HSPLandroid/view/ImeFocusController;->onViewDetachedFromWindow(Landroid/view/View;)V+]Landroid/view/ImeFocusController$InputMethodManagerDelegate;Landroid/view/inputmethod/InputMethodManager$DelegateImpl;
+HSPLandroid/view/ImeFocusController;->onViewDetachedFromWindow(Landroid/view/View;)V
 HSPLandroid/view/ImeFocusController;->onViewFocusChanged(Landroid/view/View;Z)V
 HSPLandroid/view/ImeFocusController;->onWindowDismissed()V
 HSPLandroid/view/ImeInsetsSourceConsumer;-><init>(ILandroid/view/InsetsState;Ljava/util/function/Supplier;Landroid/view/InsetsController;)V
@@ -16325,7 +16396,7 @@
 HSPLandroid/view/InputDevice;->isVirtual()Z
 HSPLandroid/view/InputEvent;-><init>()V
 HSPLandroid/view/InputEvent;->getSequenceNumber()I
-HSPLandroid/view/InputEvent;->isFromSource(I)Z
+HSPLandroid/view/InputEvent;->isFromSource(I)Z+]Landroid/view/InputEvent;Landroid/view/MotionEvent;
 HSPLandroid/view/InputEvent;->prepareForReuse()V
 HSPLandroid/view/InputEvent;->recycle()V
 HSPLandroid/view/InputEvent;->recycleIfNeededAfterDispatch()V
@@ -16337,7 +16408,7 @@
 HSPLandroid/view/InputEventConsistencyVerifier;->isInstrumentationEnabled()Z
 HSPLandroid/view/InputEventReceiver;-><init>(Landroid/view/InputChannel;Landroid/os/Looper;)V
 HSPLandroid/view/InputEventReceiver;->consumeBatchedInputEvents(J)Z
-HSPLandroid/view/InputEventReceiver;->dispatchInputEvent(ILandroid/view/InputEvent;)V+]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Landroid/view/InputEvent;Landroid/view/MotionEvent;]Landroid/view/InputEventReceiver;Landroid/view/ViewRootImpl$WindowInputEventReceiver;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/InputEventReceiver;->dispatchInputEvent(ILandroid/view/InputEvent;)V
 HSPLandroid/view/InputEventReceiver;->dispose()V
 HSPLandroid/view/InputEventReceiver;->dispose(Z)V
 HSPLandroid/view/InputEventReceiver;->finalize()V
@@ -16413,6 +16484,9 @@
 HSPLandroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda0;->onAnimationUpdate(Landroid/animation/ValueAnimator;)V
 HSPLandroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda3;->getInterpolation(F)F
 HSPLandroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda4;->getInterpolation(F)F
+HSPLandroid/view/InsetsController$InternalAnimationControlListener$1;->initialValue()Landroid/animation/AnimationHandler;
+HSPLandroid/view/InsetsController$InternalAnimationControlListener$1;->initialValue()Ljava/lang/Object;
+HSPLandroid/view/InsetsController$InternalAnimationControlListener$2;->onAnimationEnd(Landroid/animation/Animator;)V
 HSPLandroid/view/InsetsController$InternalAnimationControlListener;-><init>(ZZIIZILandroid/view/WindowInsetsAnimationControlListener;Landroid/view/inputmethod/ImeTracker$InputMethodJankContext;)V
 HSPLandroid/view/InsetsController$InternalAnimationControlListener;->calculateDurationMs()J
 HSPLandroid/view/InsetsController$InternalAnimationControlListener;->getAlphaInterpolator()Landroid/view/animation/Interpolator;
@@ -16439,6 +16513,7 @@
 HSPLandroid/view/InsetsController;->cancelAnimation(Landroid/view/InsetsAnimationControlRunner;Z)V
 HSPLandroid/view/InsetsController;->cancelExistingAnimations()V
 HSPLandroid/view/InsetsController;->cancelExistingControllers(I)V
+HSPLandroid/view/InsetsController;->captionInsetsUnchanged()Z
 HSPLandroid/view/InsetsController;->collectSourceControls(ZILandroid/util/SparseArray;ILandroid/view/inputmethod/ImeTracker$Token;)Landroid/util/Pair;
 HSPLandroid/view/InsetsController;->controlAnimationUncheckedInner(ILandroid/os/CancellationSignal;Landroid/view/WindowInsetsAnimationControlListener;Landroid/graphics/Rect;ZJLandroid/view/animation/Interpolator;IIZLandroid/view/inputmethod/ImeTracker$Token;)V
 HSPLandroid/view/InsetsController;->dispatchAnimationEnd(Landroid/view/WindowInsetsAnimation;)V
@@ -16456,8 +16531,8 @@
 HSPLandroid/view/InsetsController;->notifyControlRevoked(Landroid/view/InsetsSourceConsumer;)V
 HSPLandroid/view/InsetsController;->notifyFinished(Landroid/view/InsetsAnimationControlRunner;Z)V
 HSPLandroid/view/InsetsController;->notifyVisibilityChanged()V
-HSPLandroid/view/InsetsController;->onControlsChanged([Landroid/view/InsetsSourceControl;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/InsetsSourceConsumer;Landroid/view/ImeInsetsSourceConsumer;,Landroid/view/InsetsSourceConsumer;]Landroid/view/InsetsSourceControl;Landroid/view/InsetsSourceControl;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/view/InsetsController;->onFrameChanged(Landroid/graphics/Rect;)V
+HSPLandroid/view/InsetsController;->onControlsChanged([Landroid/view/InsetsSourceControl;)V
+HSPLandroid/view/InsetsController;->onFrameChanged(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
 HSPLandroid/view/InsetsController;->onStateChanged(Landroid/view/InsetsState;)Z
 HSPLandroid/view/InsetsController;->onWindowFocusGained(Z)V
 HSPLandroid/view/InsetsController;->onWindowFocusLost()V
@@ -16470,15 +16545,15 @@
 HSPLandroid/view/InsetsController;->updateState(Landroid/view/InsetsState;)V
 HSPLandroid/view/InsetsFlags;-><init>()V
 HSPLandroid/view/InsetsSource$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/InsetsSource;
-HSPLandroid/view/InsetsSource$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/view/InsetsSource$1;Landroid/view/InsetsSource$1;
+HSPLandroid/view/InsetsSource$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/view/InsetsSource;-><init>(II)V
-HSPLandroid/view/InsetsSource;-><init>(Landroid/os/Parcel;)V+]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/os/Parcelable$Creator;Landroid/graphics/Rect$1;
+HSPLandroid/view/InsetsSource;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/view/InsetsSource;-><init>(Landroid/view/InsetsSource;)V
-HSPLandroid/view/InsetsSource;->calculateInsets(Landroid/graphics/Rect;Landroid/graphics/Rect;Z)Landroid/graphics/Insets;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsSource;->calculateInsets(Landroid/graphics/Rect;Landroid/graphics/Rect;Z)Landroid/graphics/Insets;+]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/graphics/Rect;Landroid/graphics/Rect;
 HSPLandroid/view/InsetsSource;->calculateInsets(Landroid/graphics/Rect;Z)Landroid/graphics/Insets;
 HSPLandroid/view/InsetsSource;->calculateVisibleInsets(Landroid/graphics/Rect;)Landroid/graphics/Insets;
-HSPLandroid/view/InsetsSource;->equals(Ljava/lang/Object;)Z+]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
-HSPLandroid/view/InsetsSource;->equals(Ljava/lang/Object;Z)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Ljava/lang/Object;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsSource;->equals(Ljava/lang/Object;)Z
+HSPLandroid/view/InsetsSource;->equals(Ljava/lang/Object;Z)Z
 HSPLandroid/view/InsetsSource;->getFlags()I
 HSPLandroid/view/InsetsSource;->getFrame()Landroid/graphics/Rect;
 HSPLandroid/view/InsetsSource;->getId()I
@@ -16532,30 +16607,30 @@
 HSPLandroid/view/InsetsState;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/view/InsetsState;-><init>(Landroid/view/InsetsState;Z)V
 HSPLandroid/view/InsetsState;->addSource(Landroid/view/InsetsSource;)V
-HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;II)Landroid/graphics/Insets;
-HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;IZ)Landroid/graphics/Insets;
+HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;II)Landroid/graphics/Insets;+]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;IZ)Landroid/graphics/Insets;+]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/util/SparseArray;Landroid/util/SparseArray;
 HSPLandroid/view/InsetsState;->calculateInsets(Landroid/graphics/Rect;Landroid/view/InsetsState;ZIIIIILandroid/util/SparseIntArray;)Landroid/view/WindowInsets;
 HSPLandroid/view/InsetsState;->calculateRelativeCutout(Landroid/graphics/Rect;)Landroid/view/DisplayCutout;
 HSPLandroid/view/InsetsState;->calculateRelativeDisplayShape(Landroid/graphics/Rect;)Landroid/view/DisplayShape;
 HSPLandroid/view/InsetsState;->calculateRelativePrivacyIndicatorBounds(Landroid/graphics/Rect;)Landroid/view/PrivacyIndicatorBounds;
 HSPLandroid/view/InsetsState;->calculateRelativeRoundedCorners(Landroid/graphics/Rect;)Landroid/view/RoundedCorners;
-HSPLandroid/view/InsetsState;->calculateUncontrollableInsetsFromFrame(Landroid/graphics/Rect;)I+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsState;->calculateUncontrollableInsetsFromFrame(Landroid/graphics/Rect;)I
 HSPLandroid/view/InsetsState;->calculateVisibleInsets(Landroid/graphics/Rect;IIII)Landroid/graphics/Insets;
-HSPLandroid/view/InsetsState;->canControlSource(Landroid/graphics/Rect;Landroid/view/InsetsSource;)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsState;->canControlSource(Landroid/graphics/Rect;Landroid/view/InsetsSource;)Z
 HSPLandroid/view/InsetsState;->clearsCompatInsets(IIII)Z
 HSPLandroid/view/InsetsState;->equals(Ljava/lang/Object;)Z
 HSPLandroid/view/InsetsState;->equals(Ljava/lang/Object;ZZ)Z
-HSPLandroid/view/InsetsState;->getDisplayCutout()Landroid/view/DisplayCutout;
-HSPLandroid/view/InsetsState;->getDisplayCutoutSafe(Landroid/graphics/Rect;)V
+HSPLandroid/view/InsetsState;->getDisplayCutout()Landroid/view/DisplayCutout;+]Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/view/DisplayCutout$ParcelableWrapper;
+HSPLandroid/view/InsetsState;->getDisplayCutoutSafe(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/DisplayCutout;Landroid/view/DisplayCutout;]Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/view/DisplayCutout$ParcelableWrapper;
 HSPLandroid/view/InsetsState;->getDisplayFrame()Landroid/graphics/Rect;
 HSPLandroid/view/InsetsState;->getDisplayShape()Landroid/view/DisplayShape;
 HSPLandroid/view/InsetsState;->getPrivacyIndicatorBounds()Landroid/view/PrivacyIndicatorBounds;
 HSPLandroid/view/InsetsState;->getRoundedCorners()Landroid/view/RoundedCorners;
 HSPLandroid/view/InsetsState;->isSourceOrDefaultVisible(II)Z
 HSPLandroid/view/InsetsState;->peekSource(I)Landroid/view/InsetsSource;
-HSPLandroid/view/InsetsState;->readFromParcel(Landroid/os/Parcel;)Landroid/util/SparseArray;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/os/Parcel;Landroid/os/Parcel;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/view/DisplayCutout$ParcelableWrapper;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;
+HSPLandroid/view/InsetsState;->readFromParcel(Landroid/os/Parcel;)Landroid/util/SparseArray;
 HSPLandroid/view/InsetsState;->set(Landroid/view/InsetsState;I)V
-HSPLandroid/view/InsetsState;->set(Landroid/view/InsetsState;Z)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/view/DisplayCutout$ParcelableWrapper;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/view/InsetsState;Landroid/view/InsetsState;
+HSPLandroid/view/InsetsState;->set(Landroid/view/InsetsState;Z)V
 HSPLandroid/view/InsetsState;->setDisplayCutout(Landroid/view/DisplayCutout;)V
 HSPLandroid/view/InsetsState;->setDisplayFrame(Landroid/graphics/Rect;)V
 HSPLandroid/view/InsetsState;->setPrivacyIndicatorBounds(Landroid/view/PrivacyIndicatorBounds;)V
@@ -16614,28 +16689,28 @@
 HSPLandroid/view/LayoutInflater;-><init>(Landroid/view/LayoutInflater;Landroid/content/Context;)V
 HSPLandroid/view/LayoutInflater;->advanceToRootNode(Lorg/xmlpull/v1/XmlPullParser;)V
 HSPLandroid/view/LayoutInflater;->consumeChildElements(Lorg/xmlpull/v1/XmlPullParser;)V
-HSPLandroid/view/LayoutInflater;->createView(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;+]Landroid/content/Context;missing_types]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/view/ViewStub;Landroid/view/ViewStub;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Ljava/lang/reflect/Constructor;Ljava/lang/reflect/Constructor;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/view/LayoutInflater;->createView(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
 HSPLandroid/view/LayoutInflater;->createView(Ljava/lang/String;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
 HSPLandroid/view/LayoutInflater;->createViewFromTag(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
-HSPLandroid/view/LayoutInflater;->createViewFromTag(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;Z)Landroid/view/View;+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/util/AttributeSet;Landroid/content/res/XmlBlock$Parser;]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/String;Ljava/lang/String;
+HSPLandroid/view/LayoutInflater;->createViewFromTag(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;Z)Landroid/view/View;
 HSPLandroid/view/LayoutInflater;->from(Landroid/content/Context;)Landroid/view/LayoutInflater;
 HSPLandroid/view/LayoutInflater;->getContext()Landroid/content/Context;
 HSPLandroid/view/LayoutInflater;->getFactory()Landroid/view/LayoutInflater$Factory;
 HSPLandroid/view/LayoutInflater;->getFactory2()Landroid/view/LayoutInflater$Factory2;
 HSPLandroid/view/LayoutInflater;->inflate(ILandroid/view/ViewGroup;)Landroid/view/View;
 HSPLandroid/view/LayoutInflater;->inflate(ILandroid/view/ViewGroup;Z)Landroid/view/View;
-HSPLandroid/view/LayoutInflater;->inflate(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/ViewGroup;Z)Landroid/view/View;+]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/view/LayoutInflater;->inflate(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/ViewGroup;Z)Landroid/view/View;
 HSPLandroid/view/LayoutInflater;->onCreateView(Landroid/content/Context;Landroid/view/View;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
 HSPLandroid/view/LayoutInflater;->onCreateView(Landroid/view/View;Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
 HSPLandroid/view/LayoutInflater;->onCreateView(Ljava/lang/String;Landroid/util/AttributeSet;)Landroid/view/View;
-HSPLandroid/view/LayoutInflater;->parseInclude(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/Context;Landroid/view/View;Landroid/util/AttributeSet;)V
-HSPLandroid/view/LayoutInflater;->rInflate(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/View;Landroid/content/Context;Landroid/util/AttributeSet;Z)V+]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
-HSPLandroid/view/LayoutInflater;->rInflateChildren(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/View;Landroid/util/AttributeSet;Z)V+]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/view/View;missing_types
+HSPLandroid/view/LayoutInflater;->parseInclude(Lorg/xmlpull/v1/XmlPullParser;Landroid/content/Context;Landroid/view/View;Landroid/util/AttributeSet;)V+]Landroid/util/AttributeSet;Landroid/content/res/XmlBlock$Parser;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;Landroid/widget/FrameLayout;,Landroid/widget/LinearLayout;]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Ljava/lang/Object;Ljava/lang/String;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/content/res/XmlResourceParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/view/LayoutInflater;->rInflate(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/View;Landroid/content/Context;Landroid/util/AttributeSet;Z)V+]Landroid/view/View;missing_types]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;]Landroid/view/ViewGroup;Landroid/widget/RelativeLayout;,Landroid/widget/FrameLayout;,Landroid/widget/LinearLayout;]Landroid/view/LayoutInflater;Lcom/android/internal/policy/PhoneLayoutInflater;]Ljava/lang/Object;Ljava/lang/String;
+HSPLandroid/view/LayoutInflater;->rInflateChildren(Lorg/xmlpull/v1/XmlPullParser;Landroid/view/View;Landroid/util/AttributeSet;Z)V
 HSPLandroid/view/LayoutInflater;->setFactory2(Landroid/view/LayoutInflater$Factory2;)V
 HSPLandroid/view/LayoutInflater;->setFilter(Landroid/view/LayoutInflater$Filter;)V
 HSPLandroid/view/LayoutInflater;->setPrivateFactory(Landroid/view/LayoutInflater$Factory2;)V
-HSPLandroid/view/LayoutInflater;->tryCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;+]Landroid/view/LayoutInflater$Factory2;missing_types]Ljava/lang/Object;Ljava/lang/String;
-HSPLandroid/view/LayoutInflater;->verifyClassLoader(Ljava/lang/reflect/Constructor;)Z+]Landroid/content/Context;missing_types]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/reflect/Constructor;Ljava/lang/reflect/Constructor;
+HSPLandroid/view/LayoutInflater;->tryCreateView(Landroid/view/View;Ljava/lang/String;Landroid/content/Context;Landroid/util/AttributeSet;)Landroid/view/View;
+HSPLandroid/view/LayoutInflater;->verifyClassLoader(Ljava/lang/reflect/Constructor;)Z
 HSPLandroid/view/MenuInflater;-><init>(Landroid/content/Context;)V
 HSPLandroid/view/MotionEvent$PointerCoords;-><init>()V
 HSPLandroid/view/MotionEvent$PointerProperties;-><init>()V
@@ -16676,7 +16751,7 @@
 HSPLandroid/view/MotionEvent;->getY()F
 HSPLandroid/view/MotionEvent;->getY(I)F
 HSPLandroid/view/MotionEvent;->initialize(IIIIIIIIIFFFFJJI[Landroid/view/MotionEvent$PointerProperties;[Landroid/view/MotionEvent$PointerCoords;)Z
-HSPLandroid/view/MotionEvent;->isTargetAccessibilityFocus()Z
+HSPLandroid/view/MotionEvent;->isTargetAccessibilityFocus()Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
 HSPLandroid/view/MotionEvent;->isTouchEvent()Z
 HSPLandroid/view/MotionEvent;->obtain()Landroid/view/MotionEvent;
 HSPLandroid/view/MotionEvent;->obtain(JJIFFFFIFFII)Landroid/view/MotionEvent;
@@ -16687,7 +16762,7 @@
 HSPLandroid/view/MotionEvent;->recycle()V
 HSPLandroid/view/MotionEvent;->setAction(I)V
 HSPLandroid/view/MotionEvent;->setLocation(FF)V
-HSPLandroid/view/MotionEvent;->setTargetAccessibilityFocus(Z)V
+HSPLandroid/view/MotionEvent;->setTargetAccessibilityFocus(Z)V+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
 HSPLandroid/view/MotionEvent;->split(I)Landroid/view/MotionEvent;
 HSPLandroid/view/MotionEvent;->transform(Landroid/graphics/Matrix;)V
 HSPLandroid/view/MotionEvent;->updateCursorPosition()V
@@ -16723,12 +16798,12 @@
 HSPLandroid/view/RemoteAnimationAdapter;-><init>(Landroid/view/IRemoteAnimationRunner;JJ)V
 HSPLandroid/view/RemoteAnimationAdapter;->writeToParcel(Landroid/os/Parcel;I)V
 HSPLandroid/view/RoundedCorner$1;-><init>()V
-HSPLandroid/view/RoundedCorner$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/RoundedCorner;+]Landroid/os/Parcel;Landroid/os/Parcel;
-HSPLandroid/view/RoundedCorner$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;+]Landroid/view/RoundedCorner$1;Landroid/view/RoundedCorner$1;
+HSPLandroid/view/RoundedCorner$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/RoundedCorner;
+HSPLandroid/view/RoundedCorner$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/view/RoundedCorner;-><clinit>()V
 HSPLandroid/view/RoundedCorner;-><init>(I)V
 HSPLandroid/view/RoundedCorner;-><init>(IIII)V
-HSPLandroid/view/RoundedCorner;->equals(Ljava/lang/Object;)Z+]Landroid/graphics/Point;Landroid/graphics/Point;
+HSPLandroid/view/RoundedCorner;->equals(Ljava/lang/Object;)Z
 HSPLandroid/view/RoundedCorner;->getCenter()Landroid/graphics/Point;
 HSPLandroid/view/RoundedCorner;->getRadius()I
 HSPLandroid/view/RoundedCorner;->isEmpty()Z
@@ -16791,7 +16866,7 @@
 HSPLandroid/view/SurfaceControl$Builder;->setParent(Landroid/view/SurfaceControl;)Landroid/view/SurfaceControl$Builder;
 HSPLandroid/view/SurfaceControl$Builder;->unsetBufferSize()V
 HSPLandroid/view/SurfaceControl$Transaction;-><init>()V
-HSPLandroid/view/SurfaceControl$Transaction;-><init>(J)V
+HSPLandroid/view/SurfaceControl$Transaction;-><init>(J)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
 HSPLandroid/view/SurfaceControl$Transaction;->apply()V
 HSPLandroid/view/SurfaceControl$Transaction;->apply(Z)V
 HSPLandroid/view/SurfaceControl$Transaction;->applyResizedSurfaces()V
@@ -16799,7 +16874,7 @@
 HSPLandroid/view/SurfaceControl$Transaction;->clear()V
 HSPLandroid/view/SurfaceControl$Transaction;->close()V
 HSPLandroid/view/SurfaceControl$Transaction;->hide(Landroid/view/SurfaceControl;)Landroid/view/SurfaceControl$Transaction;
-HSPLandroid/view/SurfaceControl$Transaction;->merge(Landroid/view/SurfaceControl$Transaction;)Landroid/view/SurfaceControl$Transaction;
+HSPLandroid/view/SurfaceControl$Transaction;->merge(Landroid/view/SurfaceControl$Transaction;)Landroid/view/SurfaceControl$Transaction;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;
 HSPLandroid/view/SurfaceControl$Transaction;->notifyReparentedSurfaces()V
 HSPLandroid/view/SurfaceControl$Transaction;->remove(Landroid/view/SurfaceControl;)Landroid/view/SurfaceControl$Transaction;
 HSPLandroid/view/SurfaceControl$Transaction;->reparent(Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;)Landroid/view/SurfaceControl$Transaction;
@@ -16809,7 +16884,7 @@
 HSPLandroid/view/SurfaceControl$Transaction;->setColor(Landroid/view/SurfaceControl;[F)Landroid/view/SurfaceControl$Transaction;
 HSPLandroid/view/SurfaceControl$Transaction;->setCornerRadius(Landroid/view/SurfaceControl;F)Landroid/view/SurfaceControl$Transaction;
 HSPLandroid/view/SurfaceControl$Transaction;->setDesintationFrame(Landroid/view/SurfaceControl;II)Landroid/view/SurfaceControl$Transaction;
-HSPLandroid/view/SurfaceControl$Transaction;->setExtendedRangeBrightness(Landroid/view/SurfaceControl;FF)Landroid/view/SurfaceControl$Transaction;
+HSPLandroid/view/SurfaceControl$Transaction;->setExtendedRangeBrightness(Landroid/view/SurfaceControl;FF)Landroid/view/SurfaceControl$Transaction;+]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;
 HSPLandroid/view/SurfaceControl$Transaction;->setFrameTimelineVsync(J)Landroid/view/SurfaceControl$Transaction;
 HSPLandroid/view/SurfaceControl$Transaction;->setLayer(Landroid/view/SurfaceControl;I)Landroid/view/SurfaceControl$Transaction;
 HSPLandroid/view/SurfaceControl$Transaction;->setMatrix(Landroid/view/SurfaceControl;FFFF)Landroid/view/SurfaceControl$Transaction;
@@ -16877,6 +16952,7 @@
 HSPLandroid/view/SurfaceView;->onSetSurfacePositionAndScale(Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl;IIFF)V
 HSPLandroid/view/SurfaceView;->onWindowVisibilityChanged(I)V
 HSPLandroid/view/SurfaceView;->performDrawFinished()V
+HSPLandroid/view/SurfaceView;->performSurfaceTransaction(Landroid/view/ViewRootImpl;Landroid/content/res/CompatibilityInfo$Translator;ZZZZLandroid/view/SurfaceControl$Transaction;)Z
 HSPLandroid/view/SurfaceView;->releaseSurfaces(Z)V
 HSPLandroid/view/SurfaceView;->replacePositionUpdateListener(II)V
 HSPLandroid/view/SurfaceView;->requiresSurfaceControlCreation(ZZ)Z
@@ -16917,8 +16993,8 @@
 HSPLandroid/view/ThreadedRenderer$1$$ExternalSyntheticLambda0;-><init>(Ljava/util/ArrayList;)V
 HSPLandroid/view/ThreadedRenderer$1$$ExternalSyntheticLambda0;->onFrameCommit(Z)V
 HSPLandroid/view/ThreadedRenderer$1;-><init>(Landroid/view/ThreadedRenderer;Ljava/util/ArrayList;)V
-HSPLandroid/view/ThreadedRenderer$1;->lambda$onFrameDraw$0(Ljava/util/ArrayList;Z)V
-HSPLandroid/view/ThreadedRenderer$1;->onFrameDraw(IJ)Landroid/graphics/HardwareRenderer$FrameCommitCallback;
+HSPLandroid/view/ThreadedRenderer$1;->lambda$onFrameDraw$0(Ljava/util/ArrayList;Z)V+]Landroid/graphics/HardwareRenderer$FrameCommitCallback;Landroid/view/ViewRootImpl$7$$ExternalSyntheticLambda0;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ThreadedRenderer$1;->onFrameDraw(IJ)Landroid/graphics/HardwareRenderer$FrameCommitCallback;+]Landroid/graphics/HardwareRenderer$FrameDrawingCallback;Landroid/view/ViewRootImpl$3;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/ThreadedRenderer$WebViewOverlayProvider;->-$$Nest$fgetmSurfaceControl(Landroid/view/ThreadedRenderer$WebViewOverlayProvider;)Landroid/view/SurfaceControl;
 HSPLandroid/view/ThreadedRenderer$WebViewOverlayProvider;-><clinit>()V
 HSPLandroid/view/ThreadedRenderer$WebViewOverlayProvider;-><init>()V
@@ -16933,7 +17009,7 @@
 HSPLandroid/view/ThreadedRenderer;->destroy()V
 HSPLandroid/view/ThreadedRenderer;->destroyHardwareResources(Landroid/view/View;)V
 HSPLandroid/view/ThreadedRenderer;->destroyResources(Landroid/view/View;)V
-HSPLandroid/view/ThreadedRenderer;->draw(Landroid/view/View;Landroid/view/View$AttachInfo;Landroid/view/ThreadedRenderer$DrawCallbacks;)V
+HSPLandroid/view/ThreadedRenderer;->draw(Landroid/view/View;Landroid/view/View$AttachInfo;Landroid/view/ThreadedRenderer$DrawCallbacks;)V+]Landroid/view/ViewFrameInfo;Landroid/view/ViewFrameInfo;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
 HSPLandroid/view/ThreadedRenderer;->dumpArgsToFlags([Ljava/lang/String;)I
 HSPLandroid/view/ThreadedRenderer;->getHeight()I
 HSPLandroid/view/ThreadedRenderer;->getWidth()I
@@ -16944,20 +17020,20 @@
 HSPLandroid/view/ThreadedRenderer;->isEnabled()Z
 HSPLandroid/view/ThreadedRenderer;->isRequested()Z
 HSPLandroid/view/ThreadedRenderer;->loadSystemProperties()Z
-HSPLandroid/view/ThreadedRenderer;->registerRtFrameCallback(Landroid/graphics/HardwareRenderer$FrameDrawingCallback;)V
+HSPLandroid/view/ThreadedRenderer;->registerRtFrameCallback(Landroid/graphics/HardwareRenderer$FrameDrawingCallback;)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/ThreadedRenderer;->rendererOwnsSurfaceControlOpacity()Z
 HSPLandroid/view/ThreadedRenderer;->setEnabled(Z)V
 HSPLandroid/view/ThreadedRenderer;->setLightCenter(Landroid/view/View$AttachInfo;)V
 HSPLandroid/view/ThreadedRenderer;->setRequested(Z)V
 HSPLandroid/view/ThreadedRenderer;->setSurface(Landroid/view/Surface;)V
-HSPLandroid/view/ThreadedRenderer;->setSurfaceControl(Landroid/view/SurfaceControl;Landroid/graphics/BLASTBufferQueue;)V
+HSPLandroid/view/ThreadedRenderer;->setSurfaceControl(Landroid/view/SurfaceControl;Landroid/graphics/BLASTBufferQueue;)V+]Landroid/view/ThreadedRenderer$WebViewOverlayProvider;Landroid/view/ThreadedRenderer$WebViewOverlayProvider;
 HSPLandroid/view/ThreadedRenderer;->setSurfaceControlOpaque(Z)Z
 HSPLandroid/view/ThreadedRenderer;->setup(IILandroid/view/View$AttachInfo;Landroid/graphics/Rect;)V
 HSPLandroid/view/ThreadedRenderer;->updateEnabledState(Landroid/view/Surface;)V
-HSPLandroid/view/ThreadedRenderer;->updateRootDisplayList(Landroid/view/View;Landroid/view/ThreadedRenderer$DrawCallbacks;)V
+HSPLandroid/view/ThreadedRenderer;->updateRootDisplayList(Landroid/view/View;Landroid/view/ThreadedRenderer$DrawCallbacks;)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/ThreadedRenderer$DrawCallbacks;Landroid/view/ViewRootImpl;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/view/ThreadedRenderer;->updateSurface(Landroid/view/Surface;)V
-HSPLandroid/view/ThreadedRenderer;->updateViewTreeDisplayList(Landroid/view/View;)V
-HSPLandroid/view/ThreadedRenderer;->updateWebViewOverlayCallbacks()V
+HSPLandroid/view/ThreadedRenderer;->updateViewTreeDisplayList(Landroid/view/View;)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ThreadedRenderer;->updateWebViewOverlayCallbacks()V+]Landroid/view/ThreadedRenderer$WebViewOverlayProvider;Landroid/view/ThreadedRenderer$WebViewOverlayProvider;
 HSPLandroid/view/TouchDelegate;-><init>(Landroid/graphics/Rect;Landroid/view/View;)V
 HSPLandroid/view/VelocityTracker;-><init>(I)V
 HSPLandroid/view/VelocityTracker;->addMovement(Landroid/view/MotionEvent;)V
@@ -16979,7 +17055,7 @@
 HSPLandroid/view/View$12;->get(Landroid/view/View;)Ljava/lang/Float;
 HSPLandroid/view/View$12;->get(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/view/View$12;->setValue(Landroid/view/View;F)V
-HSPLandroid/view/View$12;->setValue(Ljava/lang/Object;F)V
+HSPLandroid/view/View$12;->setValue(Ljava/lang/Object;F)V+]Landroid/view/View$12;Landroid/view/View$12;
 HSPLandroid/view/View$13;->get(Landroid/view/View;)Ljava/lang/Float;
 HSPLandroid/view/View$13;->get(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLandroid/view/View$13;->setValue(Landroid/view/View;F)V
@@ -17033,31 +17109,31 @@
 HSPLandroid/view/View$MeasureSpec;->makeSafeMeasureSpec(II)I
 HSPLandroid/view/View$PerformClick;->run()V
 HSPLandroid/view/View$ScrollabilityCache;-><init>(Landroid/view/ViewConfiguration;Landroid/view/View;)V
-HSPLandroid/view/View$ScrollabilityCache;->run()V
+HSPLandroid/view/View$ScrollabilityCache;->run()V+]Landroid/graphics/Interpolator;Landroid/graphics/Interpolator;]Landroid/view/View;missing_types
 HSPLandroid/view/View$TintInfo;-><init>()V
 HSPLandroid/view/View$TransformationInfo;-><init>()V
 HSPLandroid/view/View$UnsetPressedState;->run()V
 HSPLandroid/view/View$VisibilityChangeForAutofillHandler;->handleMessage(Landroid/os/Message;)V
-HSPLandroid/view/View;-><init>(Landroid/content/Context;)V+]Landroid/content/Context;missing_types]Landroid/view/View;missing_types]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;missing_types
+HSPLandroid/view/View;-><init>(Landroid/content/Context;)V+]Landroid/view/View;missing_types]Ljava/lang/Object;missing_types]Landroid/content/Context;missing_types]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Ljava/lang/Class;Ljava/lang/Class;
 HSPLandroid/view/View;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/view/View;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/view/View;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types
+HSPLandroid/view/View;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/view/View;missing_types]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
 HSPLandroid/view/View;->addFocusables(Ljava/util/ArrayList;I)V
 HSPLandroid/view/View;->addFocusables(Ljava/util/ArrayList;II)V
 HSPLandroid/view/View;->addFrameMetricsListener(Landroid/view/Window;Landroid/view/Window$OnFrameMetricsAvailableListener;Landroid/os/Handler;)V
 HSPLandroid/view/View;->addOnAttachStateChangeListener(Landroid/view/View$OnAttachStateChangeListener;)V
-HSPLandroid/view/View;->addOnLayoutChangeListener(Landroid/view/View$OnLayoutChangeListener;)V+]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/View;->addOnLayoutChangeListener(Landroid/view/View$OnLayoutChangeListener;)V
 HSPLandroid/view/View;->animate()Landroid/view/ViewPropertyAnimator;
 HSPLandroid/view/View;->announceForAccessibility(Ljava/lang/CharSequence;)V
 HSPLandroid/view/View;->appendId(Ljava/lang/StringBuilder;)V
 HSPLandroid/view/View;->applyBackgroundTint()V
 HSPLandroid/view/View;->applyForegroundTint()V
 HSPLandroid/view/View;->applyInsets(Landroid/graphics/Rect;)V
-HSPLandroid/view/View;->applyLegacyAnimation(Landroid/view/ViewGroup;JLandroid/view/animation/Animation;Z)Z+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/view/View;missing_types]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;
+HSPLandroid/view/View;->applyLegacyAnimation(Landroid/view/ViewGroup;JLandroid/view/animation/Animation;Z)Z
 HSPLandroid/view/View;->areDrawablesResolved()Z
 HSPLandroid/view/View;->assignParent(Landroid/view/ViewParent;)V
 HSPLandroid/view/View;->awakenScrollBars()Z
-HSPLandroid/view/View;->awakenScrollBars(IZ)Z+]Landroid/os/Handler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->awakenScrollBars(IZ)Z+]Landroid/os/Handler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/view/View;Landroid/widget/ImageView;,Landroid/widget/TextView;,Landroid/widget/LinearLayout;
 HSPLandroid/view/View;->bringToFront()V
 HSPLandroid/view/View;->buildDrawingCache(Z)V
 HSPLandroid/view/View;->buildDrawingCacheImpl(Z)V
@@ -17065,7 +17141,7 @@
 HSPLandroid/view/View;->calculateAccessibilityDataSensitive()V
 HSPLandroid/view/View;->calculateIsImportantForContentCapture()Z
 HSPLandroid/view/View;->canHaveDisplayList()Z
-HSPLandroid/view/View;->canNotifyAutofillEnterExitEvent()Z+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->canNotifyAutofillEnterExitEvent()Z
 HSPLandroid/view/View;->canReceivePointerEvents()Z
 HSPLandroid/view/View;->canResolveLayoutDirection()Z+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
 HSPLandroid/view/View;->canResolveTextDirection()Z+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
@@ -17077,8 +17153,8 @@
 HSPLandroid/view/View;->cancelPendingInputEvents()V
 HSPLandroid/view/View;->checkForLongClick(JFFI)V
 HSPLandroid/view/View;->checkInputConnectionProxy(Landroid/view/View;)Z
-HSPLandroid/view/View;->cleanupDraw()V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
-HSPLandroid/view/View;->clearAccessibilityFocus()V+]Landroid/view/View;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/View;->cleanupDraw()V
+HSPLandroid/view/View;->clearAccessibilityFocus()V
 HSPLandroid/view/View;->clearAccessibilityFocusNoCallbacks(I)V
 HSPLandroid/view/View;->clearAccessibilityThrottles()V
 HSPLandroid/view/View;->clearAnimation()V
@@ -17087,7 +17163,7 @@
 HSPLandroid/view/View;->clearParentsWantFocus()V
 HSPLandroid/view/View;->clearTranslationState()V
 HSPLandroid/view/View;->clearViewTranslationResponse()V
-HSPLandroid/view/View;->collectPreferKeepClearRects()Ljava/util/List;+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->collectPreferKeepClearRects()Ljava/util/List;
 HSPLandroid/view/View;->collectUnrestrictedPreferKeepClearRects()Ljava/util/List;
 HSPLandroid/view/View;->combineMeasuredStates(II)I
 HSPLandroid/view/View;->combineVisibility(II)I
@@ -17095,21 +17171,21 @@
 HSPLandroid/view/View;->computeHorizontalScrollExtent()I
 HSPLandroid/view/View;->computeHorizontalScrollOffset()I
 HSPLandroid/view/View;->computeHorizontalScrollRange()I
-HSPLandroid/view/View;->computeOpaqueFlags()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/view/View;->computeOpaqueFlags()V
 HSPLandroid/view/View;->computeScroll()V
 HSPLandroid/view/View;->computeSystemWindowInsets(Landroid/view/WindowInsets;Landroid/graphics/Rect;)Landroid/view/WindowInsets;
-HSPLandroid/view/View;->computeVerticalScrollExtent()I
+HSPLandroid/view/View;->computeVerticalScrollExtent()I+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->computeVerticalScrollOffset()I
-HSPLandroid/view/View;->computeVerticalScrollRange()I
-HSPLandroid/view/View;->damageInParent()V+]Landroid/view/ViewParent;missing_types
+HSPLandroid/view/View;->computeVerticalScrollRange()I+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->damageInParent()V
 HSPLandroid/view/View;->destroyDrawingCache()V
 HSPLandroid/view/View;->destroyHardwareResources()V
-HSPLandroid/view/View;->dispatchApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V+]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Landroid/view/View;missing_types]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/Iterator;Ljava/util/concurrent/CopyOnWriteArrayList$COWIterator;]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;
-HSPLandroid/view/View;->dispatchCancelPendingInputEvents()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->dispatchApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
+HSPLandroid/view/View;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V+]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/View;missing_types]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;]Ljava/util/Iterator;Ljava/util/concurrent/CopyOnWriteArrayList$COWIterator;
+HSPLandroid/view/View;->dispatchCancelPendingInputEvents()V
 HSPLandroid/view/View;->dispatchCollectViewAttributes(Landroid/view/View$AttachInfo;I)V+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->dispatchConfigurationChanged(Landroid/content/res/Configuration;)V
-HSPLandroid/view/View;->dispatchDetachedFromWindow()V+]Landroid/view/ImeFocusController;Landroid/view/ImeFocusController;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;Landroid/view/ViewOverlay$OverlayViewGroup;]Landroid/view/ViewOverlay;Landroid/view/ViewGroupOverlay;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/Iterator;Ljava/util/concurrent/CopyOnWriteArrayList$COWIterator;]Ljava/util/List;Ljava/util/Collections$EmptyList;]Ljava/util/concurrent/CopyOnWriteArrayList;Ljava/util/concurrent/CopyOnWriteArrayList;
+HSPLandroid/view/View;->dispatchDetachedFromWindow()V+]Landroid/view/View;missing_types]Ljava/util/List;Ljava/util/Collections$EmptyList;]Landroid/view/ImeFocusController;Landroid/view/ImeFocusController;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/View;->dispatchDraw(Landroid/graphics/Canvas;)V
 HSPLandroid/view/View;->dispatchDrawableHotspotChanged(FF)V
 HSPLandroid/view/View;->dispatchFinishTemporaryDetach()V
@@ -17125,7 +17201,7 @@
 HSPLandroid/view/View;->dispatchProvideContentCaptureStructure()V
 HSPLandroid/view/View;->dispatchProvideStructure(Landroid/view/ViewStructure;II)V
 HSPLandroid/view/View;->dispatchRestoreInstanceState(Landroid/util/SparseArray;)V
-HSPLandroid/view/View;->dispatchSaveInstanceState(Landroid/util/SparseArray;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/view/View;->dispatchSaveInstanceState(Landroid/util/SparseArray;)V
 HSPLandroid/view/View;->dispatchScreenStateChanged(I)V
 HSPLandroid/view/View;->dispatchSetActivated(Z)V
 HSPLandroid/view/View;->dispatchSetPressed(Z)V
@@ -17134,18 +17210,18 @@
 HSPLandroid/view/View;->dispatchSystemUiVisibilityChanged(I)V
 HSPLandroid/view/View;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z
 HSPLandroid/view/View;->dispatchVisibilityAggregated(Z)Z+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->dispatchVisibilityChanged(Landroid/view/View;I)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->dispatchVisibilityChanged(Landroid/view/View;I)V
 HSPLandroid/view/View;->dispatchWindowFocusChanged(Z)V
 HSPLandroid/view/View;->dispatchWindowInsetsAnimationEnd(Landroid/view/WindowInsetsAnimation;)V
 HSPLandroid/view/View;->dispatchWindowSystemUiVisiblityChanged(I)V
-HSPLandroid/view/View;->dispatchWindowVisibilityChanged(I)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->dispatchWindowVisibilityChanged(I)V
 HSPLandroid/view/View;->draw(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->draw(Landroid/graphics/Canvas;Landroid/view/ViewGroup;J)Z+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/AnimationSet;,Landroid/view/animation/RotateAnimation;]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;
-HSPLandroid/view/View;->drawAutofilledHighlight(Landroid/graphics/Canvas;)V
-HSPLandroid/view/View;->drawBackground(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->draw(Landroid/graphics/Canvas;Landroid/view/ViewGroup;J)Z+]Landroid/view/View;missing_types]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/view/ViewGroup;Landroid/widget/FrameLayout;]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;]Landroid/view/animation/Animation;Landroid/view/animation/TranslateAnimation;,Landroid/view/animation/AlphaAnimation;
+HSPLandroid/view/View;->drawAutofilledHighlight(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->drawBackground(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/view/View;->drawDefaultFocusHighlight(Landroid/graphics/Canvas;)V
 HSPLandroid/view/View;->drawableHotspotChanged(FF)V
-HSPLandroid/view/View;->drawableStateChanged()V+]Landroid/animation/StateListAnimator;Landroid/animation/StateListAnimator;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types
+HSPLandroid/view/View;->drawableStateChanged()V+]Landroid/animation/StateListAnimator;Landroid/animation/StateListAnimator;]Landroid/view/View;missing_types]Landroid/graphics/drawable/Drawable;Landroid/widget/ScrollBarDrawable;,Landroid/graphics/drawable/RippleDrawable;,Landroid/graphics/drawable/InsetDrawable;,Landroid/graphics/drawable/StateListDrawable;,Landroid/graphics/drawable/ColorDrawable;
 HSPLandroid/view/View;->drawsWithRenderNode(Landroid/graphics/Canvas;)Z+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/view/View;->ensureTransformationInfo()V
 HSPLandroid/view/View;->findAccessibilityFocusHost(Z)Landroid/view/View;
@@ -17155,7 +17231,7 @@
 HSPLandroid/view/View;->findOnBackInvokedDispatcher()Landroid/window/OnBackInvokedDispatcher;
 HSPLandroid/view/View;->findUserSetNextFocus(Landroid/view/View;I)Landroid/view/View;
 HSPLandroid/view/View;->findViewByAutofillIdTraversal(I)Landroid/view/View;
-HSPLandroid/view/View;->findViewById(I)Landroid/view/View;+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->findViewById(I)Landroid/view/View;
 HSPLandroid/view/View;->findViewTraversal(I)Landroid/view/View;
 HSPLandroid/view/View;->findViewWithTag(Ljava/lang/Object;)Landroid/view/View;
 HSPLandroid/view/View;->findViewWithTagTraversal(Ljava/lang/Object;)Landroid/view/View;
@@ -17190,7 +17266,7 @@
 HSPLandroid/view/View;->getContext()Landroid/content/Context;
 HSPLandroid/view/View;->getDefaultSize(II)I
 HSPLandroid/view/View;->getDisplay()Landroid/view/Display;
-HSPLandroid/view/View;->getDrawableRenderNode(Landroid/graphics/drawable/Drawable;Landroid/graphics/RenderNode;)Landroid/graphics/RenderNode;+]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/drawable/Drawable;missing_types]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;missing_types
+HSPLandroid/view/View;->getDrawableRenderNode(Landroid/graphics/drawable/Drawable;Landroid/graphics/RenderNode;)Landroid/graphics/RenderNode;+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/Drawable;missing_types]Ljava/lang/Object;missing_types]Ljava/lang/Class;Ljava/lang/Class;
 HSPLandroid/view/View;->getDrawableState()[I+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->getDrawingCache(Z)Landroid/graphics/Bitmap;
 HSPLandroid/view/View;->getDrawingRect(Landroid/graphics/Rect;)V
@@ -17220,16 +17296,16 @@
 HSPLandroid/view/View;->getInverseMatrix()Landroid/graphics/Matrix;
 HSPLandroid/view/View;->getKeyDispatcherState()Landroid/view/KeyEvent$DispatcherState;
 HSPLandroid/view/View;->getLayerType()I
-HSPLandroid/view/View;->getLayoutDirection()I+]Landroid/content/Context;missing_types]Landroid/view/View;missing_types
+HSPLandroid/view/View;->getLayoutDirection()I+]Landroid/view/View;missing_types]Landroid/content/Context;missing_types
 HSPLandroid/view/View;->getLayoutParams()Landroid/view/ViewGroup$LayoutParams;
 HSPLandroid/view/View;->getLeft()I
 HSPLandroid/view/View;->getListenerInfo()Landroid/view/View$ListenerInfo;
 HSPLandroid/view/View;->getLocalVisibleRect(Landroid/graphics/Rect;)Z
 HSPLandroid/view/View;->getLocationInSurface([I)V
-HSPLandroid/view/View;->getLocationInWindow([I)V
+HSPLandroid/view/View;->getLocationInWindow([I)V+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->getLocationOnScreen()[I
-HSPLandroid/view/View;->getLocationOnScreen([I)V
-HSPLandroid/view/View;->getMatrix()Landroid/graphics/Matrix;
+HSPLandroid/view/View;->getLocationOnScreen([I)V+]Landroid/view/View;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/View;->getMatrix()Landroid/graphics/Matrix;+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->getMeasuredHeight()I
 HSPLandroid/view/View;->getMeasuredState()I
 HSPLandroid/view/View;->getMeasuredWidth()I
@@ -17241,9 +17317,9 @@
 HSPLandroid/view/View;->getOverScrollMode()I
 HSPLandroid/view/View;->getPaddingBottom()I
 HSPLandroid/view/View;->getPaddingEnd()I
-HSPLandroid/view/View;->getPaddingLeft()I+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->getPaddingLeft()I
 HSPLandroid/view/View;->getPaddingRight()I
-HSPLandroid/view/View;->getPaddingStart()I+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->getPaddingStart()I
 HSPLandroid/view/View;->getPaddingTop()I
 HSPLandroid/view/View;->getParent()Landroid/view/ViewParent;
 HSPLandroid/view/View;->getPivotX()F
@@ -17261,8 +17337,8 @@
 HSPLandroid/view/View;->getRotationX()F
 HSPLandroid/view/View;->getRotationY()F
 HSPLandroid/view/View;->getRunQueue()Landroid/view/HandlerActionQueue;
-HSPLandroid/view/View;->getScaleX()F
-HSPLandroid/view/View;->getScaleY()F
+HSPLandroid/view/View;->getScaleX()F+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->getScaleY()F+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->getScrollX()I
 HSPLandroid/view/View;->getScrollY()I
 HSPLandroid/view/View;->getSolidColor()I
@@ -17281,7 +17357,7 @@
 HSPLandroid/view/View;->getTransitionAlpha()F
 HSPLandroid/view/View;->getTransitionName()Ljava/lang/String;
 HSPLandroid/view/View;->getTranslationX()F
-HSPLandroid/view/View;->getTranslationY()F
+HSPLandroid/view/View;->getTranslationY()F+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->getTranslationZ()F
 HSPLandroid/view/View;->getVerticalFadingEdgeLength()I
 HSPLandroid/view/View;->getVerticalScrollbarWidth()I+]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;
@@ -17292,11 +17368,11 @@
 HSPLandroid/view/View;->getWidth()I
 HSPLandroid/view/View;->getWindowAttachCount()I
 HSPLandroid/view/View;->getWindowId()Landroid/view/WindowId;
-HSPLandroid/view/View;->getWindowInsetsController()Landroid/view/WindowInsetsController;
+HSPLandroid/view/View;->getWindowInsetsController()Landroid/view/WindowInsetsController;+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
 HSPLandroid/view/View;->getWindowSystemUiVisibility()I
 HSPLandroid/view/View;->getWindowToken()Landroid/os/IBinder;
 HSPLandroid/view/View;->getWindowVisibility()I
-HSPLandroid/view/View;->getWindowVisibleDisplayFrame(Landroid/graphics/Rect;)V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/View;->getWindowVisibleDisplayFrame(Landroid/graphics/Rect;)V
 HSPLandroid/view/View;->getX()F
 HSPLandroid/view/View;->getY()F
 HSPLandroid/view/View;->getZ()F
@@ -17314,7 +17390,7 @@
 HSPLandroid/view/View;->hasNestedScrollingParent()Z
 HSPLandroid/view/View;->hasOnClickListeners()Z
 HSPLandroid/view/View;->hasOverlappingRendering()Z
-HSPLandroid/view/View;->hasRtlSupport()Z+]Landroid/content/Context;missing_types]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;
+HSPLandroid/view/View;->hasRtlSupport()Z
 HSPLandroid/view/View;->hasSize()Z
 HSPLandroid/view/View;->hasTransientState()Z
 HSPLandroid/view/View;->hasTranslationTransientState()Z
@@ -17327,22 +17403,22 @@
 HSPLandroid/view/View;->includeForAccessibility(Z)Z
 HSPLandroid/view/View;->inflate(Landroid/content/Context;ILandroid/view/ViewGroup;)Landroid/view/View;
 HSPLandroid/view/View;->initScrollCache()V
-HSPLandroid/view/View;->initialAwakenScrollBars()Z+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->initialAwakenScrollBars()Z+]Landroid/view/View;Landroid/widget/ScrollView;
 HSPLandroid/view/View;->initializeFadingEdgeInternal(Landroid/content/res/TypedArray;)V
 HSPLandroid/view/View;->initializeScrollIndicatorsInternal()V
 HSPLandroid/view/View;->initializeScrollbarsInternal(Landroid/content/res/TypedArray;)V
-HSPLandroid/view/View;->internalSetPadding(IIII)V+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->invalidate()V
+HSPLandroid/view/View;->internalSetPadding(IIII)V
+HSPLandroid/view/View;->invalidate()V+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->invalidate(IIII)V+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->invalidate(Landroid/graphics/Rect;)V
+HSPLandroid/view/View;->invalidate(Landroid/graphics/Rect;)V+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->invalidate(Z)V+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types
-HSPLandroid/view/View;->invalidateInternal(IIIIZZ)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
-HSPLandroid/view/View;->invalidateOutline()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/view/View;missing_types]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/view/View;->invalidateInternal(IIIIZZ)V+]Landroid/view/View;megamorphic_types]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewParent;missing_types]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/view/View;->invalidateOutline()V
 HSPLandroid/view/View;->invalidateParentCaches()V
 HSPLandroid/view/View;->invalidateParentIfNeeded()V
 HSPLandroid/view/View;->invalidateParentIfNeededAndWasQuickRejected()V
-HSPLandroid/view/View;->invalidateViewProperty(ZZ)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->invalidateViewProperty(ZZ)V
 HSPLandroid/view/View;->isAccessibilityFocused()Z
 HSPLandroid/view/View;->isAccessibilityFocusedViewOrHost()Z
 HSPLandroid/view/View;->isAccessibilityPane()Z
@@ -17377,7 +17453,7 @@
 HSPLandroid/view/View;->isInTouchMode()Z
 HSPLandroid/view/View;->isKeyboardNavigationCluster()Z
 HSPLandroid/view/View;->isLaidOut()Z
-HSPLandroid/view/View;->isLayoutDirectionInherited()Z+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->isLayoutDirectionInherited()Z
 HSPLandroid/view/View;->isLayoutDirectionResolved()Z
 HSPLandroid/view/View;->isLayoutModeOptical(Ljava/lang/Object;)Z+]Landroid/view/ViewGroup;missing_types
 HSPLandroid/view/View;->isLayoutRequested()Z
@@ -17390,7 +17466,7 @@
 HSPLandroid/view/View;->isPressed()Z
 HSPLandroid/view/View;->isProjectionReceiver()Z
 HSPLandroid/view/View;->isRootNamespace()Z
-HSPLandroid/view/View;->isRtlCompatibilityMode()Z+]Landroid/content/Context;missing_types]Landroid/view/View;missing_types
+HSPLandroid/view/View;->isRtlCompatibilityMode()Z
 HSPLandroid/view/View;->isSelected()Z
 HSPLandroid/view/View;->isShowingLayoutBounds()Z
 HSPLandroid/view/View;->isShown()Z
@@ -17406,44 +17482,44 @@
 HSPLandroid/view/View;->isViewIdGenerated(I)Z
 HSPLandroid/view/View;->isVisibleToUser()Z
 HSPLandroid/view/View;->isVisibleToUser(Landroid/graphics/Rect;)Z
-HSPLandroid/view/View;->jumpDrawablesToCurrentState()V+]Landroid/animation/StateListAnimator;Landroid/animation/StateListAnimator;]Landroid/graphics/drawable/Drawable;missing_types
-HSPLandroid/view/View;->layout(IIII)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->jumpDrawablesToCurrentState()V
+HSPLandroid/view/View;->layout(IIII)V+]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/View;->makeFrameworkOptionalFitsSystemWindows()V
 HSPLandroid/view/View;->makeOptionalFitsSystemWindows()V
 HSPLandroid/view/View;->mapRectFromViewToScreenCoords(Landroid/graphics/RectF;Z)V
 HSPLandroid/view/View;->mapRectFromViewToWindowCoords(Landroid/graphics/RectF;Z)V
-HSPLandroid/view/View;->measure(II)V+]Landroid/util/LongSparseLongArray;Landroid/util/LongSparseLongArray;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->measure(II)V+]Landroid/view/View;megamorphic_types]Landroid/util/LongSparseLongArray;Landroid/util/LongSparseLongArray;
 HSPLandroid/view/View;->mergeDrawableStates([I[I)[I
 HSPLandroid/view/View;->needGlobalAttributesUpdate(Z)V
 HSPLandroid/view/View;->needRtlPropertiesResolution()Z
 HSPLandroid/view/View;->notifyAppearedOrDisappearedForContentCaptureIfNeeded(Z)V
 HSPLandroid/view/View;->notifyAutofillManagerOnClick()V
-HSPLandroid/view/View;->notifyEnterOrExitForAutoFillIfNeeded(Z)V+]Landroid/view/View;missing_types]Landroid/view/autofill/AutofillManager;Landroid/view/autofill/AutofillManager;
+HSPLandroid/view/View;->notifyEnterOrExitForAutoFillIfNeeded(Z)V
 HSPLandroid/view/View;->notifyGlobalFocusCleared(Landroid/view/View;)V
 HSPLandroid/view/View;->notifySubtreeAccessibilityStateChangedByParentIfNeeded()V
-HSPLandroid/view/View;->notifySubtreeAccessibilityStateChangedIfNeeded()V+]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;
-HSPLandroid/view/View;->notifyViewAccessibilityStateChangedIfNeeded(I)V+]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;
+HSPLandroid/view/View;->notifySubtreeAccessibilityStateChangedIfNeeded()V
+HSPLandroid/view/View;->notifyViewAccessibilityStateChangedIfNeeded(I)V
 HSPLandroid/view/View;->offsetLeftAndRight(I)V
 HSPLandroid/view/View;->offsetTopAndBottom(I)V
 HSPLandroid/view/View;->onAnimationEnd()V
 HSPLandroid/view/View;->onAnimationStart()V
 HSPLandroid/view/View;->onApplyFrameworkOptionalFitSystemWindows(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
 HSPLandroid/view/View;->onApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
-HSPLandroid/view/View;->onAttachedToWindow()V+]Landroid/view/View;missing_types]Landroid/view/accessibility/AccessibilityNodeIdManager;Landroid/view/accessibility/AccessibilityNodeIdManager;
-HSPLandroid/view/View;->onCancelPendingInputEvents()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->onAttachedToWindow()V+]Landroid/view/accessibility/AccessibilityNodeIdManager;Landroid/view/accessibility/AccessibilityNodeIdManager;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->onCancelPendingInputEvents()V
 HSPLandroid/view/View;->onCheckIsTextEditor()Z
 HSPLandroid/view/View;->onCloseSystemDialogs(Ljava/lang/String;)V
 HSPLandroid/view/View;->onConfigurationChanged(Landroid/content/res/Configuration;)V
 HSPLandroid/view/View;->onCreateDrawableState(I)[I+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->onCreateInputConnection(Landroid/view/inputmethod/EditorInfo;)Landroid/view/inputmethod/InputConnection;
 HSPLandroid/view/View;->onDetachedFromWindow()V
-HSPLandroid/view/View;->onDetachedFromWindowInternal()V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types]Landroid/view/accessibility/AccessibilityNodeIdManager;Landroid/view/accessibility/AccessibilityNodeIdManager;
+HSPLandroid/view/View;->onDetachedFromWindowInternal()V+]Landroid/view/accessibility/AccessibilityNodeIdManager;Landroid/view/accessibility/AccessibilityNodeIdManager;]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->onDraw(Landroid/graphics/Canvas;)V
 HSPLandroid/view/View;->onDrawForeground(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->onDrawHorizontalScrollBar(Landroid/graphics/Canvas;Landroid/graphics/drawable/Drawable;IIII)V
-HSPLandroid/view/View;->onDrawScrollBars(Landroid/graphics/Canvas;)V
+HSPLandroid/view/View;->onDrawScrollBars(Landroid/graphics/Canvas;)V+]Landroid/graphics/Interpolator;Landroid/graphics/Interpolator;]Landroid/view/View;missing_types]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;
 HSPLandroid/view/View;->onDrawScrollIndicators(Landroid/graphics/Canvas;)V
-HSPLandroid/view/View;->onDrawVerticalScrollBar(Landroid/graphics/Canvas;Landroid/graphics/drawable/Drawable;IIII)V
+HSPLandroid/view/View;->onDrawVerticalScrollBar(Landroid/graphics/Canvas;Landroid/graphics/drawable/Drawable;IIII)V+]Landroid/graphics/drawable/Drawable;Landroid/widget/ScrollBarDrawable;
 HSPLandroid/view/View;->onFilterTouchEventForSecurity(Landroid/view/MotionEvent;)Z
 HSPLandroid/view/View;->onFinishInflate()V
 HSPLandroid/view/View;->onFinishTemporaryDetach()V
@@ -17453,7 +17529,7 @@
 HSPLandroid/view/View;->onKeyPreIme(ILandroid/view/KeyEvent;)Z
 HSPLandroid/view/View;->onKeyUp(ILandroid/view/KeyEvent;)Z
 HSPLandroid/view/View;->onLayout(ZIIII)V
-HSPLandroid/view/View;->onMeasure(II)V+]Landroid/view/View;Landroid/view/View;
+HSPLandroid/view/View;->onMeasure(II)V+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->onProvideAutofillStructure(Landroid/view/ViewStructure;I)V
 HSPLandroid/view/View;->onProvideAutofillVirtualStructure(Landroid/view/ViewStructure;I)V
 HSPLandroid/view/View;->onProvideContentCaptureStructure(Landroid/view/ViewStructure;I)V
@@ -17463,14 +17539,14 @@
 HSPLandroid/view/View;->onRtlPropertiesChanged(I)V
 HSPLandroid/view/View;->onSaveInstanceState()Landroid/os/Parcelable;
 HSPLandroid/view/View;->onScreenStateChanged(I)V
-HSPLandroid/view/View;->onScrollChanged(IIII)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->onScrollChanged(IIII)V
 HSPLandroid/view/View;->onSetAlpha(I)Z
 HSPLandroid/view/View;->onSizeChanged(IIII)V
 HSPLandroid/view/View;->onStartTemporaryDetach()V
 HSPLandroid/view/View;->onTouchEvent(Landroid/view/MotionEvent;)Z
-HSPLandroid/view/View;->onVisibilityAggregated(Z)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types]Ljava/util/List;Ljava/util/Collections$EmptyList;
+HSPLandroid/view/View;->onVisibilityAggregated(Z)V+]Landroid/view/View;megamorphic_types]Ljava/util/List;Ljava/util/Collections$EmptyList;,Ljava/util/ArrayList;]Landroid/graphics/drawable/Drawable;missing_types
 HSPLandroid/view/View;->onVisibilityChanged(Landroid/view/View;I)V
-HSPLandroid/view/View;->onWindowFocusChanged(Z)V+]Landroid/view/View;megamorphic_types
+HSPLandroid/view/View;->onWindowFocusChanged(Z)V
 HSPLandroid/view/View;->onWindowSystemUiVisibilityChanged(I)V
 HSPLandroid/view/View;->onWindowVisibilityChanged(I)V
 HSPLandroid/view/View;->overScrollBy(IIIIIIIIZ)Z
@@ -17494,9 +17570,9 @@
 HSPLandroid/view/View;->postOnAnimationDelayed(Ljava/lang/Runnable;J)V
 HSPLandroid/view/View;->postSendViewScrolledAccessibilityEventCallback(II)V
 HSPLandroid/view/View;->postUpdate(Ljava/lang/Runnable;)V
-HSPLandroid/view/View;->rebuildOutline()V+]Landroid/graphics/Outline;Landroid/graphics/Outline;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/ViewOutlineProvider;missing_types
+HSPLandroid/view/View;->rebuildOutline()V+]Landroid/view/ViewOutlineProvider;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/Outline;Landroid/graphics/Outline;
 HSPLandroid/view/View;->recomputePadding()V
-HSPLandroid/view/View;->refreshDrawableState()V+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
+HSPLandroid/view/View;->refreshDrawableState()V
 HSPLandroid/view/View;->registerPendingFrameMetricsObservers()V
 HSPLandroid/view/View;->removeCallbacks(Ljava/lang/Runnable;)Z
 HSPLandroid/view/View;->removeFrameMetricsListener(Landroid/view/Window$OnFrameMetricsAvailableListener;)V
@@ -17512,30 +17588,30 @@
 HSPLandroid/view/View;->requestFocus(I)Z
 HSPLandroid/view/View;->requestFocus(ILandroid/graphics/Rect;)Z
 HSPLandroid/view/View;->requestFocusNoSearch(ILandroid/graphics/Rect;)Z
-HSPLandroid/view/View;->requestLayout()V+]Landroid/util/LongSparseLongArray;Landroid/util/LongSparseLongArray;]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/View;->requestLayout()V+]Landroid/view/View;missing_types]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/util/LongSparseLongArray;Landroid/util/LongSparseLongArray;]Landroid/view/ViewParent;missing_types
 HSPLandroid/view/View;->requestRectangleOnScreen(Landroid/graphics/Rect;)Z
 HSPLandroid/view/View;->requestRectangleOnScreen(Landroid/graphics/Rect;Z)Z
 HSPLandroid/view/View;->requireViewById(I)Landroid/view/View;
-HSPLandroid/view/View;->resetDisplayList()V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->resetDisplayList()V
 HSPLandroid/view/View;->resetPressedState()V
-HSPLandroid/view/View;->resetResolvedDrawables()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->resetResolvedDrawables()V
 HSPLandroid/view/View;->resetResolvedDrawablesInternal()V
 HSPLandroid/view/View;->resetResolvedLayoutDirection()V
-HSPLandroid/view/View;->resetResolvedPadding()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->resetResolvedPadding()V
 HSPLandroid/view/View;->resetResolvedPaddingInternal()V
 HSPLandroid/view/View;->resetResolvedTextAlignment()V
 HSPLandroid/view/View;->resetResolvedTextDirection()V
-HSPLandroid/view/View;->resetRtlProperties()V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->resetRtlProperties()V
 HSPLandroid/view/View;->resetSubtreeAccessibilityStateChanged()V
-HSPLandroid/view/View;->resolveDrawables()V+]Landroid/graphics/drawable/Drawable;megamorphic_types]Landroid/view/View;missing_types
-HSPLandroid/view/View;->resolveLayoutDirection()Z+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
+HSPLandroid/view/View;->resolveDrawables()V
+HSPLandroid/view/View;->resolveLayoutDirection()Z
 HSPLandroid/view/View;->resolveLayoutParams()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup$LayoutParams;missing_types
-HSPLandroid/view/View;->resolvePadding()V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;
+HSPLandroid/view/View;->resolvePadding()V+]Landroid/view/View;missing_types]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/InsetDrawable;,Landroid/graphics/drawable/RippleDrawable;,Landroid/graphics/drawable/ColorDrawable;
 HSPLandroid/view/View;->resolveRtlPropertiesIfNeeded()Z+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->resolveSize(II)I
 HSPLandroid/view/View;->resolveSizeAndState(III)I
-HSPLandroid/view/View;->resolveTextAlignment()Z+]Landroid/view/View;missing_types
-HSPLandroid/view/View;->resolveTextDirection()Z+]Landroid/view/View;missing_types]Landroid/view/ViewParent;missing_types
+HSPLandroid/view/View;->resolveTextAlignment()Z
+HSPLandroid/view/View;->resolveTextDirection()Z
 HSPLandroid/view/View;->restoreHierarchyState(Landroid/util/SparseArray;)V
 HSPLandroid/view/View;->retrieveExplicitStyle(Landroid/content/res/Resources$Theme;Landroid/util/AttributeSet;)V
 HSPLandroid/view/View;->rootViewRequestFocus()Z
@@ -17557,53 +17633,53 @@
 HSPLandroid/view/View;->setActivated(Z)V
 HSPLandroid/view/View;->setAlpha(F)V
 HSPLandroid/view/View;->setAlphaInternal(F)V
-HSPLandroid/view/View;->setAlphaNoInvalidation(F)Z+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setAlphaNoInvalidation(F)Z
 HSPLandroid/view/View;->setAnimation(Landroid/view/animation/Animation;)V
 HSPLandroid/view/View;->setAutoHandwritingEnabled(Z)V
 HSPLandroid/view/View;->setAutofilled(ZZ)V
 HSPLandroid/view/View;->setBackground(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/view/View;->setBackgroundBounds()V+]Landroid/graphics/drawable/Drawable;missing_types
 HSPLandroid/view/View;->setBackgroundColor(I)V
-HSPLandroid/view/View;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/view/View;missing_types]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;
+HSPLandroid/view/View;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/view/View;missing_types]Ljava/lang/ThreadLocal;Ljava/lang/ThreadLocal$SuppliedThreadLocal;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;,Landroid/graphics/drawable/RippleDrawable;,Landroid/graphics/drawable/ColorDrawable;
 HSPLandroid/view/View;->setBackgroundRenderNodeProperties(Landroid/graphics/RenderNode;)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->setBackgroundResource(I)V
 HSPLandroid/view/View;->setBackgroundTintList(Landroid/content/res/ColorStateList;)V
-HSPLandroid/view/View;->setBottom(I)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types
+HSPLandroid/view/View;->setBottom(I)V
 HSPLandroid/view/View;->setClickable(Z)V
 HSPLandroid/view/View;->setClipBounds(Landroid/graphics/Rect;)V
 HSPLandroid/view/View;->setClipToOutline(Z)V
 HSPLandroid/view/View;->setContentDescription(Ljava/lang/CharSequence;)V
 HSPLandroid/view/View;->setDefaultFocusHighlightEnabled(Z)V
 HSPLandroid/view/View;->setDetached(Z)V
-HSPLandroid/view/View;->setDisplayListProperties(Landroid/graphics/RenderNode;)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setDisplayListProperties(Landroid/graphics/RenderNode;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->setDrawingCacheEnabled(Z)V
 HSPLandroid/view/View;->setElevation(F)V
 HSPLandroid/view/View;->setEnabled(Z)V
 HSPLandroid/view/View;->setFitsSystemWindows(Z)V
-HSPLandroid/view/View;->setFlags(II)V+]Landroid/view/View;megamorphic_types]Landroid/view/ViewGroup;missing_types]Landroid/view/ViewParent;missing_types]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;
+HSPLandroid/view/View;->setFlags(II)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/view/ViewParent;missing_types
 HSPLandroid/view/View;->setFocusable(I)V
 HSPLandroid/view/View;->setFocusable(Z)V
 HSPLandroid/view/View;->setFocusableInTouchMode(Z)V
 HSPLandroid/view/View;->setForeground(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/view/View;->setForegroundGravity(I)V
-HSPLandroid/view/View;->setFrame(IIII)Z+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setFrame(IIII)Z+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->setHandwritingArea(Landroid/graphics/Rect;)V
 HSPLandroid/view/View;->setHapticFeedbackEnabled(Z)V
 HSPLandroid/view/View;->setHasTransientState(Z)V
 HSPLandroid/view/View;->setHorizontalFadingEdgeEnabled(Z)V
 HSPLandroid/view/View;->setHorizontalScrollBarEnabled(Z)V
 HSPLandroid/view/View;->setId(I)V
-HSPLandroid/view/View;->setImportantForAccessibility(I)V+]Landroid/view/View;megamorphic_types
+HSPLandroid/view/View;->setImportantForAccessibility(I)V
 HSPLandroid/view/View;->setImportantForAutofill(I)V
 HSPLandroid/view/View;->setImportantForContentCapture(I)V
 HSPLandroid/view/View;->setIsRootNamespace(Z)V
 HSPLandroid/view/View;->setKeepScreenOn(Z)V
 HSPLandroid/view/View;->setKeyboardNavigationCluster(Z)V
-HSPLandroid/view/View;->setKeyedTag(ILjava/lang/Object;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/view/View;->setKeyedTag(ILjava/lang/Object;)V
 HSPLandroid/view/View;->setLayerPaint(Landroid/graphics/Paint;)V
 HSPLandroid/view/View;->setLayerType(ILandroid/graphics/Paint;)V
 HSPLandroid/view/View;->setLayoutDirection(I)V
-HSPLandroid/view/View;->setLayoutParams(Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/View;->setLayoutParams(Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;Lcom/android/internal/policy/DecorView;
 HSPLandroid/view/View;->setLeft(I)V
 HSPLandroid/view/View;->setLeftTopRightBottom(IIII)V
 HSPLandroid/view/View;->setLongClickable(Z)V
@@ -17628,21 +17704,21 @@
 HSPLandroid/view/View;->setOutlineProviderFromAttribute(I)V
 HSPLandroid/view/View;->setOutlineSpotShadowColor(I)V
 HSPLandroid/view/View;->setOverScrollMode(I)V
-HSPLandroid/view/View;->setPadding(IIII)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->setPadding(IIII)V
 HSPLandroid/view/View;->setPaddingRelative(IIII)V
 HSPLandroid/view/View;->setPivotX(F)V
 HSPLandroid/view/View;->setPivotY(F)V
 HSPLandroid/view/View;->setPointerIcon(Landroid/view/PointerIcon;)V
 HSPLandroid/view/View;->setPressed(Z)V
 HSPLandroid/view/View;->setRenderEffect(Landroid/graphics/RenderEffect;)V
-HSPLandroid/view/View;->setRight(I)V+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setRight(I)V
 HSPLandroid/view/View;->setRotation(F)V
 HSPLandroid/view/View;->setRotationX(F)V
 HSPLandroid/view/View;->setRotationY(F)V
 HSPLandroid/view/View;->setSaveEnabled(Z)V
 HSPLandroid/view/View;->setSaveFromParentEnabled(Z)V
-HSPLandroid/view/View;->setScaleX(F)V
-HSPLandroid/view/View;->setScaleY(F)V
+HSPLandroid/view/View;->setScaleX(F)V+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
+HSPLandroid/view/View;->setScaleY(F)V+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->setScrollContainer(Z)V
 HSPLandroid/view/View;->setScrollIndicators(II)V
 HSPLandroid/view/View;->setScrollX(I)V
@@ -17665,40 +17741,41 @@
 HSPLandroid/view/View;->setTransitionVisibility(I)V
 HSPLandroid/view/View;->setTranslationX(F)V
 HSPLandroid/view/View;->setTranslationY(F)V
-HSPLandroid/view/View;->setTranslationZ(F)V
+HSPLandroid/view/View;->setTranslationZ(F)V+]Landroid/view/View;missing_types]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->setVerticalScrollBarEnabled(Z)V
-HSPLandroid/view/View;->setVisibility(I)V+]Landroid/view/View;missing_types
+HSPLandroid/view/View;->setVisibility(I)V
 HSPLandroid/view/View;->setWillNotDraw(Z)V
 HSPLandroid/view/View;->setX(F)V
 HSPLandroid/view/View;->setY(F)V
-HSPLandroid/view/View;->shouldDrawRoundScrollbar()Z+]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/content/res/Resources;Landroid/content/res/Resources;
-HSPLandroid/view/View;->sizeChange(IIII)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/ViewOverlay;Landroid/view/ViewGroupOverlay;
+HSPLandroid/view/View;->shouldDrawRoundScrollbar()Z+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;
+HSPLandroid/view/View;->sizeChange(IIII)V
 HSPLandroid/view/View;->skipInvalidate()Z+]Landroid/view/ViewGroup;missing_types
 HSPLandroid/view/View;->startAnimation(Landroid/view/animation/Animation;)V
 HSPLandroid/view/View;->startNestedScroll(I)Z
 HSPLandroid/view/View;->stopNestedScroll()V
 HSPLandroid/view/View;->switchDefaultFocusHighlight()V
 HSPLandroid/view/View;->toString()Ljava/lang/String;
-HSPLandroid/view/View;->transformFromViewToWindowSpace([I)V
+HSPLandroid/view/View;->transformFromViewToWindowSpace([I)V+]Landroid/view/View;missing_types
 HSPLandroid/view/View;->unFocus(Landroid/view/View;)V
-HSPLandroid/view/View;->unscheduleDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
+HSPLandroid/view/View;->unscheduleDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/view/View;->unscheduleDrawable(Landroid/graphics/drawable/Drawable;Ljava/lang/Runnable;)V
-HSPLandroid/view/View;->updateDisplayListIfDirty()Landroid/graphics/RenderNode;+]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;Landroid/view/ViewOverlay$OverlayViewGroup;]Landroid/view/ViewOverlay;Landroid/view/ViewGroupOverlay;
+HSPLandroid/view/View;->updateDisplayListIfDirty()Landroid/graphics/RenderNode;+]Landroid/view/View;megamorphic_types]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/view/View;->updateFocusedInCluster(Landroid/view/View;I)V
 HSPLandroid/view/View;->updateHandwritingArea()V
 HSPLandroid/view/View;->updateKeepClearRects()V
 HSPLandroid/view/View;->updateLocalSystemUiVisibility(II)Z
 HSPLandroid/view/View;->updatePflags3AndNotifyA11yIfChanged(IZ)V
-HSPLandroid/view/View;->updatePositionUpdateListener()V+]Landroid/view/View;missing_types]Ljava/util/List;Ljava/util/Collections$EmptyList;
+HSPLandroid/view/View;->updatePositionUpdateListener()V
 HSPLandroid/view/View;->updatePreferKeepClearForFocus()V
 HSPLandroid/view/View;->updateSystemGestureExclusionRects()V
 HSPLandroid/view/View;->verifyDrawable(Landroid/graphics/drawable/Drawable;)Z
 HSPLandroid/view/View;->willNotDraw()Z
 HSPLandroid/view/ViewAnimationHostBridge;-><init>(Landroid/view/View;)V
 HSPLandroid/view/ViewAnimationHostBridge;->isAttached()Z
+HSPLandroid/view/ViewAnimationHostBridge;->registerAnimatingRenderNode(Landroid/graphics/RenderNode;)V
 HSPLandroid/view/ViewAnimationHostBridge;->registerVectorDrawableAnimator(Landroid/view/NativeVectorDrawableAnimator;)V
 HSPLandroid/view/ViewConfiguration;-><init>(Landroid/content/Context;)V
-HSPLandroid/view/ViewConfiguration;->get(Landroid/content/Context;)Landroid/view/ViewConfiguration;+]Landroid/util/SparseArray;Landroid/util/SparseArray;
+HSPLandroid/view/ViewConfiguration;->get(Landroid/content/Context;)Landroid/view/ViewConfiguration;
 HSPLandroid/view/ViewConfiguration;->getDoubleTapTimeout()I
 HSPLandroid/view/ViewConfiguration;->getLongPressTimeout()I
 HSPLandroid/view/ViewConfiguration;->getPressedStateDuration()I
@@ -17745,9 +17822,9 @@
 HSPLandroid/view/ViewGroup$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/view/ViewGroup$LayoutParams;-><init>(Landroid/view/ViewGroup$LayoutParams;)V
 HSPLandroid/view/ViewGroup$LayoutParams;->resolveLayoutDirection(I)V
-HSPLandroid/view/ViewGroup$LayoutParams;->setBaseAttributes(Landroid/content/res/TypedArray;II)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
+HSPLandroid/view/ViewGroup$LayoutParams;->setBaseAttributes(Landroid/content/res/TypedArray;II)V
 HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(II)V
-HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/Context;missing_types]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/view/ViewGroup$MarginLayoutParams;missing_types
+HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/view/ViewGroup$MarginLayoutParams;missing_types]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
 HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(Landroid/view/ViewGroup$LayoutParams;)V
 HSPLandroid/view/ViewGroup$MarginLayoutParams;-><init>(Landroid/view/ViewGroup$MarginLayoutParams;)V
 HSPLandroid/view/ViewGroup$MarginLayoutParams;->doResolveMargins()V
@@ -17773,12 +17850,12 @@
 HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;I)V
 HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;II)V
-HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V
 HSPLandroid/view/ViewGroup;->addView(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
 HSPLandroid/view/ViewGroup;->addViewInLayout(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)Z
 HSPLandroid/view/ViewGroup;->addViewInLayout(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;Z)Z
-HSPLandroid/view/ViewGroup;->addViewInner(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;Z)V+]Landroid/animation/LayoutTransition;Landroid/animation/LayoutTransition;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->attachViewToParent(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->addViewInner(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;Z)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->attachViewToParent(Landroid/view/View;ILandroid/view/ViewGroup$LayoutParams;)V
 HSPLandroid/view/ViewGroup;->bringChildToFront(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->buildOrderedChildList()Ljava/util/ArrayList;
 HSPLandroid/view/ViewGroup;->buildTouchDispatchChildList()Ljava/util/ArrayList;
@@ -17795,20 +17872,20 @@
 HSPLandroid/view/ViewGroup;->clearFocus()V
 HSPLandroid/view/ViewGroup;->clearFocusedInCluster()V
 HSPLandroid/view/ViewGroup;->clearTouchTargets()V
-HSPLandroid/view/ViewGroup;->destroyHardwareResources()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->destroyHardwareResources()V
 HSPLandroid/view/ViewGroup;->detachAllViewsFromParent()V
 HSPLandroid/view/ViewGroup;->detachViewFromParent(I)V
 HSPLandroid/view/ViewGroup;->dispatchApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
-HSPLandroid/view/ViewGroup;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->dispatchCancelPendingInputEvents()V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->dispatchAttachedToWindow(Landroid/view/View$AttachInfo;I)V
+HSPLandroid/view/ViewGroup;->dispatchCancelPendingInputEvents()V
 HSPLandroid/view/ViewGroup;->dispatchCollectViewAttributes(Landroid/view/View$AttachInfo;I)V+]Landroid/view/View;missing_types
 HSPLandroid/view/ViewGroup;->dispatchConfigurationChanged(Landroid/content/res/Configuration;)V
 HSPLandroid/view/ViewGroup;->dispatchDetachedFromWindow()V
-HSPLandroid/view/ViewGroup;->dispatchDraw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/animation/LayoutAnimationController;Landroid/view/animation/LayoutAnimationController;
+HSPLandroid/view/ViewGroup;->dispatchDraw(Landroid/graphics/Canvas;)V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/view/ViewGroup;->dispatchDrawableHotspotChanged(FF)V
 HSPLandroid/view/ViewGroup;->dispatchFinishTemporaryDetach()V
 HSPLandroid/view/ViewGroup;->dispatchFreezeSelfOnly(Landroid/util/SparseArray;)V
-HSPLandroid/view/ViewGroup;->dispatchGetDisplayList()V+]Landroid/view/View;missing_types]Landroid/view/ViewOverlay;Landroid/view/ViewGroupOverlay;
+HSPLandroid/view/ViewGroup;->dispatchGetDisplayList()V+]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/ViewGroup;->dispatchKeyEvent(Landroid/view/KeyEvent;)Z
 HSPLandroid/view/ViewGroup;->dispatchKeyEventPreIme(Landroid/view/KeyEvent;)Z
 HSPLandroid/view/ViewGroup;->dispatchProvideAutofillStructure(Landroid/view/ViewStructure;I)V
@@ -17822,17 +17899,17 @@
 HSPLandroid/view/ViewGroup;->dispatchStartTemporaryDetach()V
 HSPLandroid/view/ViewGroup;->dispatchSystemUiVisibilityChanged(I)V
 HSPLandroid/view/ViewGroup;->dispatchThawSelfOnly(Landroid/util/SparseArray;)V
-HSPLandroid/view/ViewGroup;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/view/ViewGroup;->dispatchTransformedTouchEvent(Landroid/view/MotionEvent;ZLandroid/view/View;I)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z+]Landroid/view/ViewGroup$TouchTarget;Landroid/view/ViewGroup$TouchTarget;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
+HSPLandroid/view/ViewGroup;->dispatchTransformedTouchEvent(Landroid/view/MotionEvent;ZLandroid/view/View;I)Z+]Landroid/view/View;missing_types]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
 HSPLandroid/view/ViewGroup;->dispatchUnhandledKeyEvent(Landroid/view/KeyEvent;)Landroid/view/View;
-HSPLandroid/view/ViewGroup;->dispatchViewAdded(Landroid/view/View;)V+]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->dispatchViewAdded(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->dispatchViewRemoved(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->dispatchVisibilityAggregated(Z)Z+]Landroid/view/View;missing_types
-HSPLandroid/view/ViewGroup;->dispatchVisibilityChanged(Landroid/view/View;I)V+]Landroid/view/View;missing_types
-HSPLandroid/view/ViewGroup;->dispatchWindowFocusChanged(Z)V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->dispatchVisibilityChanged(Landroid/view/View;I)V
+HSPLandroid/view/ViewGroup;->dispatchWindowFocusChanged(Z)V
 HSPLandroid/view/ViewGroup;->dispatchWindowInsetsAnimationEnd(Landroid/view/WindowInsetsAnimation;)V
 HSPLandroid/view/ViewGroup;->dispatchWindowSystemUiVisiblityChanged(I)V
-HSPLandroid/view/ViewGroup;->dispatchWindowVisibilityChanged(I)V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->dispatchWindowVisibilityChanged(I)V
 HSPLandroid/view/ViewGroup;->drawChild(Landroid/graphics/Canvas;Landroid/view/View;J)Z+]Landroid/view/View;missing_types
 HSPLandroid/view/ViewGroup;->drawableStateChanged()V
 HSPLandroid/view/ViewGroup;->endViewTransition(Landroid/view/View;)V
@@ -17842,7 +17919,7 @@
 HSPLandroid/view/ViewGroup;->findOnBackInvokedDispatcherForChild(Landroid/view/View;Landroid/view/View;)Landroid/window/OnBackInvokedDispatcher;
 HSPLandroid/view/ViewGroup;->findViewByAutofillIdTraversal(I)Landroid/view/View;
 HSPLandroid/view/ViewGroup;->findViewByPredicateTraversal(Ljava/util/function/Predicate;Landroid/view/View;)Landroid/view/View;
-HSPLandroid/view/ViewGroup;->findViewTraversal(I)Landroid/view/View;+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->findViewTraversal(I)Landroid/view/View;
 HSPLandroid/view/ViewGroup;->findViewWithTagTraversal(Ljava/lang/Object;)Landroid/view/View;
 HSPLandroid/view/ViewGroup;->finishAnimatingView(Landroid/view/View;Landroid/view/animation/Animation;)V
 HSPLandroid/view/ViewGroup;->focusSearch(Landroid/view/View;I)Landroid/view/View;
@@ -17858,7 +17935,7 @@
 HSPLandroid/view/ViewGroup;->getChildMeasureSpec(III)I
 HSPLandroid/view/ViewGroup;->getChildTransformation()Landroid/view/animation/Transformation;
 HSPLandroid/view/ViewGroup;->getChildVisibleRect(Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;)Z
-HSPLandroid/view/ViewGroup;->getChildVisibleRect(Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;Z)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/view/ViewParent;Landroid/view/ViewRootImpl;
+HSPLandroid/view/ViewGroup;->getChildVisibleRect(Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;Z)Z+]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewParent;Landroid/view/ViewRootImpl;
 HSPLandroid/view/ViewGroup;->getChildrenForAutofill(I)Landroid/view/ViewGroup$ChildListForAutoFillOrContentCapture;
 HSPLandroid/view/ViewGroup;->getChildrenForContentCapture()Landroid/view/ViewGroup$ChildListForAutoFillOrContentCapture;
 HSPLandroid/view/ViewGroup;->getClipChildren()Z
@@ -17884,8 +17961,8 @@
 HSPLandroid/view/ViewGroup;->hasUnhandledKeyListener()Z
 HSPLandroid/view/ViewGroup;->hasWindowInsetsAnimationCallback()Z
 HSPLandroid/view/ViewGroup;->indexOfChild(Landroid/view/View;)I
-HSPLandroid/view/ViewGroup;->initFromAttributes(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->initViewGroup()V+]Landroid/content/Context;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->initFromAttributes(Landroid/content/Context;Landroid/util/AttributeSet;II)V
+HSPLandroid/view/ViewGroup;->initViewGroup()V
 HSPLandroid/view/ViewGroup;->internalSetPadding(IIII)V
 HSPLandroid/view/ViewGroup;->invalidateChild(Landroid/view/View;Landroid/graphics/Rect;)V+]Landroid/view/ViewGroup;missing_types
 HSPLandroid/view/ViewGroup;->invalidateChildInParent([ILandroid/graphics/Rect;)Landroid/view/ViewParent;
@@ -17894,7 +17971,7 @@
 HSPLandroid/view/ViewGroup;->isLayoutSuppressed()Z
 HSPLandroid/view/ViewGroup;->isTransformedTouchPointInView(FFLandroid/view/View;Landroid/graphics/PointF;)Z
 HSPLandroid/view/ViewGroup;->isViewTransitioning(Landroid/view/View;)Z
-HSPLandroid/view/ViewGroup;->jumpDrawablesToCurrentState()V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->jumpDrawablesToCurrentState()V
 HSPLandroid/view/ViewGroup;->layout(IIII)V
 HSPLandroid/view/ViewGroup;->makeFrameworkOptionalFitsSystemWindows()V
 HSPLandroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V
@@ -17911,9 +17988,9 @@
 HSPLandroid/view/ViewGroup;->onDescendantInvalidated(Landroid/view/View;Landroid/view/View;)V+]Landroid/view/ViewParent;missing_types
 HSPLandroid/view/ViewGroup;->onDescendantUnbufferedRequested()V
 HSPLandroid/view/ViewGroup;->onDetachedFromWindow()V
-HSPLandroid/view/ViewGroup;->onInterceptTouchEvent(Landroid/view/MotionEvent;)Z
+HSPLandroid/view/ViewGroup;->onInterceptTouchEvent(Landroid/view/MotionEvent;)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
 HSPLandroid/view/ViewGroup;->onRequestFocusInDescendants(ILandroid/graphics/Rect;)Z
-HSPLandroid/view/ViewGroup;->onSetLayoutParams(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->onSetLayoutParams(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
 HSPLandroid/view/ViewGroup;->onStartNestedScroll(Landroid/view/View;Landroid/view/View;I)Z
 HSPLandroid/view/ViewGroup;->onViewAdded(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->onViewRemoved(Landroid/view/View;)V
@@ -17934,22 +18011,22 @@
 HSPLandroid/view/ViewGroup;->removeViewInternal(Landroid/view/View;)Z
 HSPLandroid/view/ViewGroup;->requestChildFocus(Landroid/view/View;Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->requestChildRectangleOnScreen(Landroid/view/View;Landroid/graphics/Rect;Z)Z
-HSPLandroid/view/ViewGroup;->requestDisallowInterceptTouchEvent(Z)V
+HSPLandroid/view/ViewGroup;->requestDisallowInterceptTouchEvent(Z)V+]Landroid/view/ViewParent;missing_types
 HSPLandroid/view/ViewGroup;->requestFocus(ILandroid/graphics/Rect;)Z
 HSPLandroid/view/ViewGroup;->requestTransitionStart(Landroid/animation/LayoutTransition;)V
 HSPLandroid/view/ViewGroup;->requestTransparentRegion(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->resetCancelNextUpFlag(Landroid/view/View;)Z
-HSPLandroid/view/ViewGroup;->resetResolvedDrawables()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetResolvedLayoutDirection()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetResolvedPadding()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetResolvedTextAlignment()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetResolvedTextDirection()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resetSubtreeAccessibilityStateChanged()V+]Landroid/view/View;missing_types
+HSPLandroid/view/ViewGroup;->resetResolvedDrawables()V
+HSPLandroid/view/ViewGroup;->resetResolvedLayoutDirection()V
+HSPLandroid/view/ViewGroup;->resetResolvedPadding()V
+HSPLandroid/view/ViewGroup;->resetResolvedTextAlignment()V
+HSPLandroid/view/ViewGroup;->resetResolvedTextDirection()V
+HSPLandroid/view/ViewGroup;->resetSubtreeAccessibilityStateChanged()V
 HSPLandroid/view/ViewGroup;->resetTouchState()V
 HSPLandroid/view/ViewGroup;->resolveDrawables()V
 HSPLandroid/view/ViewGroup;->resolveLayoutDirection()Z
 HSPLandroid/view/ViewGroup;->resolveLayoutParams()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
-HSPLandroid/view/ViewGroup;->resolvePadding()V+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
+HSPLandroid/view/ViewGroup;->resolvePadding()V
 HSPLandroid/view/ViewGroup;->resolveRtlPropertiesIfNeeded()Z+]Landroid/view/View;missing_types]Landroid/view/ViewGroup;missing_types
 HSPLandroid/view/ViewGroup;->resolveTextAlignment()Z
 HSPLandroid/view/ViewGroup;->resolveTextDirection()Z
@@ -17970,7 +18047,7 @@
 HSPLandroid/view/ViewGroup;->shouldDelayChildPressedState()Z
 HSPLandroid/view/ViewGroup;->startViewTransition(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->suppressLayout(Z)V
-HSPLandroid/view/ViewGroup;->touchAccessibilityNodeProviderIfNeeded(Landroid/view/View;)V+]Landroid/content/Context;missing_types
+HSPLandroid/view/ViewGroup;->touchAccessibilityNodeProviderIfNeeded(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->transformPointToViewLocal([FLandroid/view/View;)V
 HSPLandroid/view/ViewGroup;->unFocus(Landroid/view/View;)V
 HSPLandroid/view/ViewGroup;->updateLocalSystemUiVisibility(II)Z
@@ -18002,7 +18079,7 @@
 HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationCancel(Landroid/animation/Animator;)V
 HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationEnd(Landroid/animation/Animator;)V
 HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationStart(Landroid/animation/Animator;)V
-HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationUpdate(Landroid/animation/ValueAnimator;)V+]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLandroid/view/ViewPropertyAnimator$AnimatorEventListener;->onAnimationUpdate(Landroid/animation/ValueAnimator;)V+]Ljava/util/HashMap;Ljava/util/HashMap;]Landroid/view/View;Landroid/widget/LinearLayout;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/animation/ValueAnimator;Landroid/animation/ValueAnimator;
 HSPLandroid/view/ViewPropertyAnimator$NameValuesHolder;-><init>(IFF)V
 HSPLandroid/view/ViewPropertyAnimator$PropertyBundle;-><init>(ILjava/util/ArrayList;)V
 HSPLandroid/view/ViewPropertyAnimator$PropertyBundle;->cancel(I)Z
@@ -18026,6 +18103,7 @@
 HSPLandroid/view/ViewPropertyAnimator;->withEndAction(Ljava/lang/Runnable;)Landroid/view/ViewPropertyAnimator;
 HSPLandroid/view/ViewPropertyAnimator;->withLayer()Landroid/view/ViewPropertyAnimator;
 HSPLandroid/view/ViewPropertyAnimator;->withStartAction(Ljava/lang/Runnable;)Landroid/view/ViewPropertyAnimator;
+HSPLandroid/view/ViewRootImpl$$ExternalSyntheticLambda0;->run()V
 HSPLandroid/view/ViewRootImpl$$ExternalSyntheticLambda17;-><init>(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/ViewRootImpl$$ExternalSyntheticLambda3;->run()V
 HSPLandroid/view/ViewRootImpl$AccessibilityInteractionConnectionManager;-><init>(Landroid/view/ViewRootImpl;)V
@@ -18042,13 +18120,13 @@
 HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
 HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->processKeyEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
 HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->processMotionEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
-HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->processPointerEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/autofill/AutofillManager;Landroid/view/autofill/AutofillManager;
+HSPLandroid/view/ViewRootImpl$EarlyPostImeInputStage;->processPointerEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
 HSPLandroid/view/ViewRootImpl$HighContrastTextManager;-><init>(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/ViewRootImpl$ImeInputStage;-><init>(Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl$InputStage;Ljava/lang/String;)V
 HSPLandroid/view/ViewRootImpl$ImeInputStage;->onFinishedInputEvent(Ljava/lang/Object;Z)V
 HSPLandroid/view/ViewRootImpl$ImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
 HSPLandroid/view/ViewRootImpl$InputMetricsListener;-><init>(Landroid/view/ViewRootImpl;)V
-HSPLandroid/view/ViewRootImpl$InputMetricsListener;->onFrameMetricsAvailable(I)V
+HSPLandroid/view/ViewRootImpl$InputMetricsListener;->onFrameMetricsAvailable(I)V+]Landroid/view/ViewRootImpl$WindowInputEventReceiver;Landroid/view/ViewRootImpl$WindowInputEventReceiver;
 HSPLandroid/view/ViewRootImpl$InputStage;-><init>(Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl$InputStage;)V
 HSPLandroid/view/ViewRootImpl$InputStage;->apply(Landroid/view/ViewRootImpl$QueuedInputEvent;I)V
 HSPLandroid/view/ViewRootImpl$InputStage;->deliver(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
@@ -18057,12 +18135,12 @@
 HSPLandroid/view/ViewRootImpl$InputStage;->onDeliverToNext(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
 HSPLandroid/view/ViewRootImpl$InputStage;->onDetachedFromWindow()V
 HSPLandroid/view/ViewRootImpl$InputStage;->onWindowFocusChanged(Z)V
-HSPLandroid/view/ViewRootImpl$InputStage;->shouldDropInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)Z+]Landroid/view/InputEvent;Landroid/view/MotionEvent;
-HSPLandroid/view/ViewRootImpl$InputStage;->traceEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;J)V+]Landroid/view/InputEvent;Landroid/view/MotionEvent;]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;Landroid/view/ViewRootImpl$EarlyPostImeInputStage;,Landroid/view/ViewRootImpl$NativePostImeInputStage;,Landroid/view/ViewRootImpl$SyntheticInputStage;,Landroid/view/ViewRootImpl$ViewPostImeInputStage;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/ViewRootImpl$InputStage;->shouldDropInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)Z
+HSPLandroid/view/ViewRootImpl$InputStage;->traceEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;J)V
 HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;-><init>(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->addView(Landroid/view/View;)V+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->postIfNeededLocked()V+]Landroid/view/Choreographer;Landroid/view/Choreographer;
-HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->removeView(Landroid/view/View;)V+]Landroid/view/Choreographer;Landroid/view/Choreographer;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->removeView(Landroid/view/View;)V
 HSPLandroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;->run()V+]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/ViewRootImpl$NativePostImeInputStage;-><init>(Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl$InputStage;Ljava/lang/String;)V
 HSPLandroid/view/ViewRootImpl$NativePostImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
@@ -18081,6 +18159,7 @@
 HSPLandroid/view/ViewRootImpl$SyntheticJoystickHandler;-><init>(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/ViewRootImpl$SyntheticJoystickHandler;->cancel()V
 HSPLandroid/view/ViewRootImpl$SyntheticKeyboardHandler;-><init>(Landroid/view/ViewRootImpl;)V
+HSPLandroid/view/ViewRootImpl$SyntheticTouchNavigationHandler$1;-><init>(Landroid/view/ViewRootImpl$SyntheticTouchNavigationHandler;)V
 HSPLandroid/view/ViewRootImpl$SyntheticTouchNavigationHandler;-><init>(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/ViewRootImpl$SyntheticTrackballHandler;-><init>(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/ViewRootImpl$SystemUiVisibilityInfo;-><init>()V
@@ -18097,7 +18176,7 @@
 HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->onDeliverToNext(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
 HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
 HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->processKeyEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
-HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->processPointerEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I+]Landroid/view/HandwritingInitiator;Landroid/view/HandwritingInitiator;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl$ViewPostImeInputStage;->processPointerEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
 HSPLandroid/view/ViewRootImpl$ViewPreImeInputStage;-><init>(Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl$InputStage;)V
 HSPLandroid/view/ViewRootImpl$ViewPreImeInputStage;->onProcess(Landroid/view/ViewRootImpl$QueuedInputEvent;)I
 HSPLandroid/view/ViewRootImpl$ViewRootHandler;-><init>(Landroid/view/ViewRootImpl;)V
@@ -18109,6 +18188,7 @@
 HSPLandroid/view/ViewRootImpl$W;->closeSystemDialogs(Ljava/lang/String;)V
 HSPLandroid/view/ViewRootImpl$W;->dispatchAppVisibility(Z)V
 HSPLandroid/view/ViewRootImpl$W;->dispatchWindowShown()V
+HSPLandroid/view/ViewRootImpl$W;->insetsControlChanged(Landroid/view/InsetsState;[Landroid/view/InsetsSourceControl;)V
 HSPLandroid/view/ViewRootImpl$W;->moved(II)V
 HSPLandroid/view/ViewRootImpl$WindowInputEventReceiver;-><init>(Landroid/view/ViewRootImpl;Landroid/view/InputChannel;Landroid/os/Looper;)V
 HSPLandroid/view/ViewRootImpl$WindowInputEventReceiver;->dispose()V
@@ -18117,27 +18197,29 @@
 HSPLandroid/view/ViewRootImpl$WindowInputEventReceiver;->onInputEvent(Landroid/view/InputEvent;)V
 HSPLandroid/view/ViewRootImpl;->-$$Nest$fgetmBlastBufferQueue(Landroid/view/ViewRootImpl;)Landroid/graphics/BLASTBufferQueue;
 HSPLandroid/view/ViewRootImpl;->-$$Nest$fputmProfileRendering(Landroid/view/ViewRootImpl;Z)V
+HSPLandroid/view/ViewRootImpl;->-$$Nest$mdispatchInsetsControlChanged(Landroid/view/ViewRootImpl;Landroid/view/InsetsState;[Landroid/view/InsetsSourceControl;)V
 HSPLandroid/view/ViewRootImpl;->-$$Nest$mprofileRendering(Landroid/view/ViewRootImpl;Z)V
 HSPLandroid/view/ViewRootImpl;-><init>(Landroid/content/Context;Landroid/view/Display;)V
-HSPLandroid/view/ViewRootImpl;-><init>(Landroid/content/Context;Landroid/view/Display;Landroid/view/IWindowSession;Landroid/view/WindowLayout;)V+]Landroid/content/Context;missing_types]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/WindowLeaked;Landroid/view/WindowLeaked;]Ljava/lang/String;Ljava/lang/String;]Ljava/util/Optional;Ljava/util/Optional;
+HSPLandroid/view/ViewRootImpl;-><init>(Landroid/content/Context;Landroid/view/Display;Landroid/view/IWindowSession;Landroid/view/WindowLayout;)V
 HSPLandroid/view/ViewRootImpl;->addConfigCallback(Landroid/view/ViewRootImpl$ConfigChangedCallback;)V
-HSPLandroid/view/ViewRootImpl;->addFrameCommitCallbackIfNeeded()V
+HSPLandroid/view/ViewRootImpl;->addFrameCommitCallbackIfNeeded()V+]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
 HSPLandroid/view/ViewRootImpl;->addSurfaceChangedCallback(Landroid/view/ViewRootImpl$SurfaceChangedCallback;)V
 HSPLandroid/view/ViewRootImpl;->addWindowCallbacks(Landroid/view/WindowCallbacks;)V
+HSPLandroid/view/ViewRootImpl;->adjustLayoutParamsForCompatibility(Landroid/view/WindowManager$LayoutParams;)V
 HSPLandroid/view/ViewRootImpl;->applyKeepScreenOnFlag(Landroid/view/WindowManager$LayoutParams;)V
-HSPLandroid/view/ViewRootImpl;->applyTransactionOnDraw(Landroid/view/SurfaceControl$Transaction;)Z
+HSPLandroid/view/ViewRootImpl;->applyTransactionOnDraw(Landroid/view/SurfaceControl$Transaction;)Z+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
 HSPLandroid/view/ViewRootImpl;->canResolveTextDirection()Z
-HSPLandroid/view/ViewRootImpl;->cancelInvalidate(Landroid/view/View;)V+]Landroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;Landroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;
+HSPLandroid/view/ViewRootImpl;->cancelInvalidate(Landroid/view/View;)V
 HSPLandroid/view/ViewRootImpl;->checkForLeavingTouchModeAndConsume(Landroid/view/KeyEvent;)Z
 HSPLandroid/view/ViewRootImpl;->checkThread()V
 HSPLandroid/view/ViewRootImpl;->childDrawableStateChanged(Landroid/view/View;)V
 HSPLandroid/view/ViewRootImpl;->childHasTransientStateChanged(Landroid/view/View;Z)V
 HSPLandroid/view/ViewRootImpl;->clearChildFocus(Landroid/view/View;)V
 HSPLandroid/view/ViewRootImpl;->clearLowProfileModeIfNeeded(IZ)V
-HSPLandroid/view/ViewRootImpl;->collectViewAttributes()Z+]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl;->collectViewAttributes()Z+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
 HSPLandroid/view/ViewRootImpl;->controlInsetsForCompatibility(Landroid/view/WindowManager$LayoutParams;)V
-HSPLandroid/view/ViewRootImpl;->createSyncIfNeeded()V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/window/SurfaceSyncGroup;Landroid/window/SurfaceSyncGroup;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/view/ViewRootImpl;->deliverInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)V+]Landroid/view/InputEvent;Landroid/view/MotionEvent;]Landroid/view/ViewRootImpl$InputStage;Landroid/view/ViewRootImpl$EarlyPostImeInputStage;]Landroid/view/ViewRootImpl$QueuedInputEvent;Landroid/view/ViewRootImpl$QueuedInputEvent;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/ViewRootImpl;->createSyncIfNeeded()V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/window/SurfaceSyncGroup;Landroid/window/SurfaceSyncGroup;
+HSPLandroid/view/ViewRootImpl;->deliverInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
 HSPLandroid/view/ViewRootImpl;->destroyHardwareRenderer()V
 HSPLandroid/view/ViewRootImpl;->destroyHardwareResources()V
 HSPLandroid/view/ViewRootImpl;->destroySurface()V
@@ -18149,14 +18231,15 @@
 HSPLandroid/view/ViewRootImpl;->dispatchDetachedFromWindow()V
 HSPLandroid/view/ViewRootImpl;->dispatchDispatchSystemUiVisibilityChanged()V
 HSPLandroid/view/ViewRootImpl;->dispatchFocusEvent(ZZ)V
+HSPLandroid/view/ViewRootImpl;->dispatchInsetsControlChanged(Landroid/view/InsetsState;[Landroid/view/InsetsSourceControl;)V
 HSPLandroid/view/ViewRootImpl;->dispatchInvalidateDelayed(Landroid/view/View;J)V
-HSPLandroid/view/ViewRootImpl;->dispatchInvalidateOnAnimation(Landroid/view/View;)V
+HSPLandroid/view/ViewRootImpl;->dispatchInvalidateOnAnimation(Landroid/view/View;)V+]Landroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;Landroid/view/ViewRootImpl$InvalidateOnAnimationRunnable;
 HSPLandroid/view/ViewRootImpl;->dispatchMoved(II)V
 HSPLandroid/view/ViewRootImpl;->doConsumeBatchedInput(J)Z
 HSPLandroid/view/ViewRootImpl;->doDie()V
-HSPLandroid/view/ViewRootImpl;->doProcessInputEvents()V+]Landroid/view/InputEventAssigner;Landroid/view/InputEventAssigner;]Landroid/view/ViewFrameInfo;Landroid/view/ViewFrameInfo;
-HSPLandroid/view/ViewRootImpl;->doTraversal()V+]Landroid/os/Looper;Landroid/os/Looper;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;
-HSPLandroid/view/ViewRootImpl;->draw(ZLandroid/window/SurfaceSyncGroup;Z)Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/HdrRenderState;Landroid/view/HdrRenderState;]Landroid/view/Surface;Landroid/view/Surface;]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;
+HSPLandroid/view/ViewRootImpl;->doProcessInputEvents()V
+HSPLandroid/view/ViewRootImpl;->doTraversal()V+]Landroid/os/Looper;Landroid/os/Looper;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;
+HSPLandroid/view/ViewRootImpl;->draw(ZLandroid/window/SurfaceSyncGroup;Z)Z+]Landroid/view/Surface;Landroid/view/Surface;]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/HdrRenderState;Landroid/view/HdrRenderState;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;
 HSPLandroid/view/ViewRootImpl;->drawAccessibilityFocusedDrawableIfNeeded(Landroid/graphics/Canvas;)V
 HSPLandroid/view/ViewRootImpl;->drawSoftware(Landroid/view/Surface;Landroid/view/View$AttachInfo;IIZLandroid/graphics/Rect;Landroid/graphics/Rect;)Z
 HSPLandroid/view/ViewRootImpl;->enableHardwareAcceleration(Landroid/view/WindowManager$LayoutParams;)V
@@ -18178,10 +18261,10 @@
 HSPLandroid/view/ViewRootImpl;->getBufferTransformHint()I
 HSPLandroid/view/ViewRootImpl;->getChildVisibleRect(Landroid/view/View;Landroid/graphics/Rect;Landroid/graphics/Point;)Z
 HSPLandroid/view/ViewRootImpl;->getCompatWindowConfiguration()Landroid/app/WindowConfiguration;
-HSPLandroid/view/ViewRootImpl;->getConfiguration()Landroid/content/res/Configuration;+]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;]Landroid/content/res/Resources;Landroid/content/res/Resources;
+HSPLandroid/view/ViewRootImpl;->getConfiguration()Landroid/content/res/Configuration;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;
 HSPLandroid/view/ViewRootImpl;->getDisplayId()I
 HSPLandroid/view/ViewRootImpl;->getHandwritingInitiator()Landroid/view/HandwritingInitiator;
-HSPLandroid/view/ViewRootImpl;->getHostVisibility()I+]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl;->getHostVisibility()I+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
 HSPLandroid/view/ViewRootImpl;->getImeFocusController()Landroid/view/ImeFocusController;
 HSPLandroid/view/ViewRootImpl;->getImpliedSystemUiVisibility(Landroid/view/WindowManager$LayoutParams;)I
 HSPLandroid/view/ViewRootImpl;->getInsetsController()Landroid/view/InsetsController;
@@ -18195,14 +18278,14 @@
 HSPLandroid/view/ViewRootImpl;->getSurfaceSequenceId()I
 HSPLandroid/view/ViewRootImpl;->getTextDirection()I
 HSPLandroid/view/ViewRootImpl;->getTitle()Ljava/lang/CharSequence;
-HSPLandroid/view/ViewRootImpl;->getUpdatedFrameInfo()Landroid/graphics/FrameInfo;
+HSPLandroid/view/ViewRootImpl;->getUpdatedFrameInfo()Landroid/graphics/FrameInfo;+]Landroid/view/InputEventAssigner;Landroid/view/InputEventAssigner;]Landroid/view/ViewFrameInfo;Landroid/view/ViewFrameInfo;
 HSPLandroid/view/ViewRootImpl;->getValidLayoutRequesters(Ljava/util/ArrayList;Z)Ljava/util/ArrayList;
 HSPLandroid/view/ViewRootImpl;->getView()Landroid/view/View;
 HSPLandroid/view/ViewRootImpl;->getViewBoundsSandboxingEnabled()Z
 HSPLandroid/view/ViewRootImpl;->getWindowBoundsInsetSystemBars()Landroid/graphics/Rect;
 HSPLandroid/view/ViewRootImpl;->getWindowFlags()I
-HSPLandroid/view/ViewRootImpl;->getWindowInsets(Z)Landroid/view/WindowInsets;+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/graphics/Insets;Landroid/graphics/Insets;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/WindowInsets;Landroid/view/WindowInsets;
-HSPLandroid/view/ViewRootImpl;->getWindowVisibleDisplayFrame(Landroid/graphics/Rect;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/ViewRootImpl;->getWindowInsets(Z)Landroid/view/WindowInsets;
+HSPLandroid/view/ViewRootImpl;->getWindowVisibleDisplayFrame(Landroid/graphics/Rect;)V
 HSPLandroid/view/ViewRootImpl;->handleAppVisibility(Z)V
 HSPLandroid/view/ViewRootImpl;->handleContentCaptureFlush()V
 HSPLandroid/view/ViewRootImpl;->handleDispatchSystemUiVisibilityChanged()V
@@ -18211,6 +18294,7 @@
 HSPLandroid/view/ViewRootImpl;->invalidateChild(Landroid/view/View;Landroid/graphics/Rect;)V
 HSPLandroid/view/ViewRootImpl;->invalidateChildInParent([ILandroid/graphics/Rect;)Landroid/view/ViewParent;
 HSPLandroid/view/ViewRootImpl;->invalidateRectOnScreen(Landroid/graphics/Rect;)V
+HSPLandroid/view/ViewRootImpl;->isAccessibilityFocusDirty()Z+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
 HSPLandroid/view/ViewRootImpl;->isContentCaptureEnabled()Z
 HSPLandroid/view/ViewRootImpl;->isContentCaptureReallyEnabled()Z
 HSPLandroid/view/ViewRootImpl;->isHardwareEnabled()Z+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
@@ -18228,10 +18312,10 @@
 HSPLandroid/view/ViewRootImpl;->lambda$new$2(Landroid/view/View;)Ljava/util/List;
 HSPLandroid/view/ViewRootImpl;->loadSystemProperties()V
 HSPLandroid/view/ViewRootImpl;->maybeFireAccessibilityWindowStateChangedEvent()V
-HSPLandroid/view/ViewRootImpl;->maybeHandleWindowMove(Landroid/graphics/Rect;)V+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
+HSPLandroid/view/ViewRootImpl;->maybeHandleWindowMove(Landroid/graphics/Rect;)V
 HSPLandroid/view/ViewRootImpl;->maybeUpdateTooltip(Landroid/view/MotionEvent;)V
-HSPLandroid/view/ViewRootImpl;->measureHierarchy(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;Landroid/content/res/Resources;IIZ)Z+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/util/TypedValue;Landroid/util/TypedValue;]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
-HSPLandroid/view/ViewRootImpl;->mergeWithNextTransaction(Landroid/view/SurfaceControl$Transaction;J)V
+HSPLandroid/view/ViewRootImpl;->measureHierarchy(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;Landroid/content/res/Resources;IIZ)Z+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl;->mergeWithNextTransaction(Landroid/view/SurfaceControl$Transaction;J)V+]Landroid/graphics/BLASTBufferQueue;Landroid/graphics/BLASTBufferQueue;
 HSPLandroid/view/ViewRootImpl;->notifyContentCaptureEvents()V
 HSPLandroid/view/ViewRootImpl;->notifyDrawStarted(Z)V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/ViewRootImpl;->notifyInsetsChanged()V
@@ -18246,24 +18330,24 @@
 HSPLandroid/view/ViewRootImpl;->onPreDraw(Landroid/graphics/RecordingCanvas;)V
 HSPLandroid/view/ViewRootImpl;->onStartNestedScroll(Landroid/view/View;Landroid/view/View;I)Z
 HSPLandroid/view/ViewRootImpl;->performContentCaptureInitialReport()V
-HSPLandroid/view/ViewRootImpl;->performDraw(Landroid/window/SurfaceSyncGroup;)Z+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
-HSPLandroid/view/ViewRootImpl;->performLayout(Landroid/view/WindowManager$LayoutParams;II)V+]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/view/ViewRootImpl;->performMeasure(II)V+]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;
-HSPLandroid/view/ViewRootImpl;->performTraversals()V+]Landroid/content/Context;missing_types]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/graphics/Region;Landroid/graphics/Region;]Landroid/util/MergedConfiguration;Landroid/util/MergedConfiguration;]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Landroid/view/ImeFocusController;Landroid/view/ImeFocusController;]Landroid/view/Surface;Landroid/view/Surface;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/window/SurfaceSyncGroup;Landroid/window/SurfaceSyncGroup;]Landroid/window/WindowOnBackInvokedDispatcher;Landroid/window/WindowOnBackInvokedDispatcher;]Lcom/android/internal/view/RootViewSurfaceTaker;Lcom/android/internal/policy/DecorView;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ViewRootImpl;->performDraw(Landroid/window/SurfaceSyncGroup;)Z+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
+HSPLandroid/view/ViewRootImpl;->performLayout(Landroid/view/WindowManager$LayoutParams;II)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ViewRootImpl;->performMeasure(II)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;
+HSPLandroid/view/ViewRootImpl;->performTraversals()V+]Landroid/view/ViewTreeObserver;Landroid/view/ViewTreeObserver;]Landroid/view/View;missing_types]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/view/HandlerActionQueue;Landroid/view/HandlerActionQueue;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/Surface;Landroid/view/Surface;]Landroid/util/MergedConfiguration;Landroid/util/MergedConfiguration;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ImeFocusController;Landroid/view/ImeFocusController;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/content/Context;Landroid/view/ContextThemeWrapper;,Lcom/android/internal/policy/DecorContext;]Lcom/android/internal/view/RootViewSurfaceTaker;Lcom/android/internal/policy/DecorView;]Landroid/graphics/Region;Landroid/graphics/Region;]Landroid/content/res/Configuration;Landroid/content/res/Configuration;]Landroid/window/SurfaceSyncGroup;Landroid/window/SurfaceSyncGroup;]Landroid/window/WindowOnBackInvokedDispatcher;Landroid/window/WindowOnBackInvokedDispatcher;
 HSPLandroid/view/ViewRootImpl;->playSoundEffect(I)V
 HSPLandroid/view/ViewRootImpl;->pokeDrawLockIfNeeded()V
-HSPLandroid/view/ViewRootImpl;->prepareSurfaces()V
+HSPLandroid/view/ViewRootImpl;->prepareSurfaces()V+]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
 HSPLandroid/view/ViewRootImpl;->profileRendering(Z)V
 HSPLandroid/view/ViewRootImpl;->recomputeViewAttributes(Landroid/view/View;)V
 HSPLandroid/view/ViewRootImpl;->recycleQueuedInputEvent(Landroid/view/ViewRootImpl$QueuedInputEvent;)V
 HSPLandroid/view/ViewRootImpl;->registerAnimatingRenderNode(Landroid/graphics/RenderNode;)V
 HSPLandroid/view/ViewRootImpl;->registerBackCallbackOnWindow()V
-HSPLandroid/view/ViewRootImpl;->registerCallbackForPendingTransactions()V
+HSPLandroid/view/ViewRootImpl;->registerCallbackForPendingTransactions()V+]Landroid/view/SurfaceControl$Transaction;Landroid/view/SurfaceControl$Transaction;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
 HSPLandroid/view/ViewRootImpl;->registerCallbacksForSync(ZLandroid/window/SurfaceSyncGroup;)V
 HSPLandroid/view/ViewRootImpl;->registerCompatOnBackInvokedCallback()V
 HSPLandroid/view/ViewRootImpl;->registerListeners()V
-HSPLandroid/view/ViewRootImpl;->registerRtFrameCallback(Landroid/graphics/HardwareRenderer$FrameDrawingCallback;)V
-HSPLandroid/view/ViewRootImpl;->relayoutWindow(Landroid/view/WindowManager$LayoutParams;IZ)I+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/os/Bundle;Landroid/os/Bundle;]Landroid/util/MergedConfiguration;Landroid/util/MergedConfiguration;]Landroid/view/Display;Landroid/view/Display;]Landroid/view/HdrRenderState;Landroid/view/HdrRenderState;]Landroid/view/IWindowSession;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/InsetsSourceControl$Array;Landroid/view/InsetsSourceControl$Array;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/ViewRootImpl;->registerRtFrameCallback(Landroid/graphics/HardwareRenderer$FrameDrawingCallback;)V+]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
+HSPLandroid/view/ViewRootImpl;->relayoutWindow(Landroid/view/WindowManager$LayoutParams;IZ)I+]Landroid/view/IWindowSession;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/view/InsetsState;Landroid/view/InsetsState;]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;]Landroid/view/HdrRenderState;Landroid/view/HdrRenderState;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/WindowLayout;Landroid/view/WindowLayout;]Landroid/util/MergedConfiguration;Landroid/util/MergedConfiguration;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/view/Display;Landroid/view/Display;
 HSPLandroid/view/ViewRootImpl;->removeSendWindowContentChangedCallback()V
 HSPLandroid/view/ViewRootImpl;->removeSurfaceChangedCallback(Landroid/view/ViewRootImpl$SurfaceChangedCallback;)V
 HSPLandroid/view/ViewRootImpl;->removeWindowCallbacks(Landroid/view/WindowCallbacks;)V
@@ -18276,28 +18360,31 @@
 HSPLandroid/view/ViewRootImpl;->requestLayout()V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
 HSPLandroid/view/ViewRootImpl;->requestLayoutDuringLayout(Landroid/view/View;)Z
 HSPLandroid/view/ViewRootImpl;->requestTransparentRegion(Landroid/view/View;)V
-HSPLandroid/view/ViewRootImpl;->scheduleConsumeBatchedInput()V+]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;
-HSPLandroid/view/ViewRootImpl;->scheduleTraversals()V+]Landroid/os/Looper;Landroid/os/Looper;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;]Landroid/view/Choreographer;Landroid/view/Choreographer;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
+HSPLandroid/view/ViewRootImpl;->scheduleConsumeBatchedInput()V
+HSPLandroid/view/ViewRootImpl;->scheduleTraversals()V+]Landroid/os/Looper;Landroid/os/Looper;]Landroid/view/ViewRootImpl$ViewRootHandler;Landroid/view/ViewRootImpl$ViewRootHandler;]Landroid/os/MessageQueue;Landroid/os/MessageQueue;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/Choreographer;Landroid/view/Choreographer;
 HSPLandroid/view/ViewRootImpl;->scrollToRectOrFocus(Landroid/graphics/Rect;Z)Z
 HSPLandroid/view/ViewRootImpl;->sendBackKeyEvent(I)V
 HSPLandroid/view/ViewRootImpl;->setAccessibilityFocus(Landroid/view/View;Landroid/view/accessibility/AccessibilityNodeInfo;)V
 HSPLandroid/view/ViewRootImpl;->setAccessibilityWindowAttributesIfNeeded()V
 HSPLandroid/view/ViewRootImpl;->setActivityConfigCallback(Landroid/view/ViewRootImpl$ActivityConfigCallback;)V
 HSPLandroid/view/ViewRootImpl;->setBoundsLayerCrop(Landroid/view/SurfaceControl$Transaction;)V
-HSPLandroid/view/ViewRootImpl;->setFrame(Landroid/graphics/Rect;Z)V
-HSPLandroid/view/ViewRootImpl;->setLayoutParams(Landroid/view/WindowManager$LayoutParams;Z)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;
+HSPLandroid/view/ViewRootImpl;->setFrame(Landroid/graphics/Rect;Z)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/InsetsController;Landroid/view/InsetsController;
+HSPLandroid/view/ViewRootImpl;->setLayoutParams(Landroid/view/WindowManager$LayoutParams;Z)V+]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;
 HSPLandroid/view/ViewRootImpl;->setOnContentApplyWindowInsetsListener(Landroid/view/Window$OnContentApplyWindowInsetsListener;)V
 HSPLandroid/view/ViewRootImpl;->setTag()V
-HSPLandroid/view/ViewRootImpl;->setView(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;Landroid/view/View;I)V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/Display;Landroid/view/Display;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/view/FallbackEventHandler;Lcom/android/internal/policy/PhoneFallbackEventHandler;]Landroid/view/IWindowSession;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/InsetsSourceControl$Array;Landroid/view/InsetsSourceControl$Array;]Landroid/view/InsetsState;Landroid/view/InsetsState;]Landroid/view/PendingInsetsController;Landroid/view/PendingInsetsController;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/View;Landroid/widget/FrameLayout;,Lcom/android/internal/policy/DecorView;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/WindowLayout;Landroid/view/WindowLayout;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Lcom/android/internal/view/RootViewSurfaceTaker;Lcom/android/internal/policy/DecorView;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
+HSPLandroid/view/ViewRootImpl;->setView(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;Landroid/view/View;I)V+]Landroid/view/IWindowSession;Landroid/view/IWindowSession$Stub$Proxy;]Landroid/view/InsetsState;Landroid/view/InsetsState;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/content/res/CompatibilityInfo;Landroid/content/res/CompatibilityInfo$1;]Landroid/view/ThreadedRenderer;Landroid/view/ThreadedRenderer;]Landroid/view/InsetsSourceControl$Array;Landroid/view/InsetsSourceControl$Array;]Landroid/view/InsetsController;Landroid/view/InsetsController;]Landroid/view/PendingInsetsController;Landroid/view/PendingInsetsController;]Lcom/android/internal/view/RootViewSurfaceTaker;Lcom/android/internal/policy/DecorView;]Landroid/view/FallbackEventHandler;Lcom/android/internal/policy/PhoneFallbackEventHandler;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/WindowLayout;Landroid/view/WindowLayout;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/view/DisplayAdjustments;Landroid/view/DisplayAdjustments;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/view/Display;Landroid/view/Display;
 HSPLandroid/view/ViewRootImpl;->setWindowStopped(Z)V
 HSPLandroid/view/ViewRootImpl;->shouldDispatchCutout()Z
 HSPLandroid/view/ViewRootImpl;->shouldOptimizeMeasure(Landroid/view/WindowManager$LayoutParams;)Z
+HSPLandroid/view/ViewRootImpl;->shouldSetFrameRate()Z+]Landroid/view/Surface;Landroid/view/Surface;
+HSPLandroid/view/ViewRootImpl;->shouldSetFrameRateCategory()Z+]Landroid/view/Surface;Landroid/view/Surface;
 HSPLandroid/view/ViewRootImpl;->shouldUseDisplaySize(Landroid/view/WindowManager$LayoutParams;)Z
 HSPLandroid/view/ViewRootImpl;->systemGestureExclusionChanged()V
 HSPLandroid/view/ViewRootImpl;->unscheduleConsumeBatchedInput()V
 HSPLandroid/view/ViewRootImpl;->unscheduleTraversals()V
-HSPLandroid/view/ViewRootImpl;->updateBlastSurfaceIfNeeded()V
+HSPLandroid/view/ViewRootImpl;->updateBlastSurfaceIfNeeded()V+]Landroid/graphics/BLASTBufferQueue;Landroid/graphics/BLASTBufferQueue;]Landroid/view/SurfaceControl;Landroid/view/SurfaceControl;
 HSPLandroid/view/ViewRootImpl;->updateBoundsLayer(Landroid/view/SurfaceControl$Transaction;)Z
+HSPLandroid/view/ViewRootImpl;->updateCaptionInsets()Z
 HSPLandroid/view/ViewRootImpl;->updateCompatSysUiVisibility(III)V
 HSPLandroid/view/ViewRootImpl;->updateCompatSystemUiVisibilityInfo(IIII)V
 HSPLandroid/view/ViewRootImpl;->updateConfiguration(I)V
@@ -18320,6 +18407,7 @@
 HSPLandroid/view/ViewRootInsetsControllerHost;->getTranslator()Landroid/content/res/CompatibilityInfo$Translator;
 HSPLandroid/view/ViewRootInsetsControllerHost;->getWindowToken()Landroid/os/IBinder;
 HSPLandroid/view/ViewRootInsetsControllerHost;->hasAnimationCallbacks()Z
+HSPLandroid/view/ViewRootInsetsControllerHost;->isSystemBarsAppearanceControlled()Z
 HSPLandroid/view/ViewRootInsetsControllerHost;->notifyInsetsChanged()V
 HSPLandroid/view/ViewRootInsetsControllerHost;->updateCompatSysUiVisibility(III)V
 HSPLandroid/view/ViewRootRectTracker$ViewInfo;-><init>(Landroid/view/ViewRootRectTracker;Landroid/view/View;)V
@@ -18342,16 +18430,16 @@
 HSPLandroid/view/ViewStub;->setOnInflateListener(Landroid/view/ViewStub$OnInflateListener;)V
 HSPLandroid/view/ViewStub;->setVisibility(I)V
 HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray$Access;-><init>()V
-HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray$Access;->get(I)Ljava/lang/Object;
+HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray$Access;->get(I)Ljava/lang/Object;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray$Access;->size()I
 HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;-><init>()V
 HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->add(Ljava/lang/Object;)V
 HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->addAll(Landroid/view/ViewTreeObserver$CopyOnWriteArray;)V
-HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->end()V
+HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->end()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->getArray()Ljava/util/ArrayList;
 HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->remove(Ljava/lang/Object;)V
-HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->size()I
-HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->start()Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;
+HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->size()I+]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/ViewTreeObserver$CopyOnWriteArray;->start()Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;+]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/ViewTreeObserver$InternalInsetsInfo;-><init>()V
 HSPLandroid/view/ViewTreeObserver$InternalInsetsInfo;->equals(Ljava/lang/Object;)Z
 HSPLandroid/view/ViewTreeObserver$InternalInsetsInfo;->isEmpty()Z
@@ -18367,10 +18455,10 @@
 HSPLandroid/view/ViewTreeObserver;->captureFrameCommitCallbacks()Ljava/util/ArrayList;
 HSPLandroid/view/ViewTreeObserver;->checkIsAlive()V
 HSPLandroid/view/ViewTreeObserver;->dispatchOnComputeInternalInsets(Landroid/view/ViewTreeObserver$InternalInsetsInfo;)V
-HSPLandroid/view/ViewTreeObserver;->dispatchOnDraw()V
+HSPLandroid/view/ViewTreeObserver;->dispatchOnDraw()V+]Ljava/util/ArrayList;Ljava/util/ArrayList;]Landroid/view/ViewTreeObserver$OnDrawListener;Landroid/widget/Editor$2;
 HSPLandroid/view/ViewTreeObserver;->dispatchOnEnterAnimationComplete()V
-HSPLandroid/view/ViewTreeObserver;->dispatchOnGlobalLayout()V
-HSPLandroid/view/ViewTreeObserver;->dispatchOnPreDraw()Z
+HSPLandroid/view/ViewTreeObserver;->dispatchOnGlobalLayout()V+]Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;]Landroid/view/ViewTreeObserver$CopyOnWriteArray;Landroid/view/ViewTreeObserver$CopyOnWriteArray;
+HSPLandroid/view/ViewTreeObserver;->dispatchOnPreDraw()Z+]Landroid/view/ViewTreeObserver$OnPreDrawListener;missing_types]Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;Landroid/view/ViewTreeObserver$CopyOnWriteArray$Access;]Landroid/view/ViewTreeObserver$CopyOnWriteArray;Landroid/view/ViewTreeObserver$CopyOnWriteArray;
 HSPLandroid/view/ViewTreeObserver;->dispatchOnScrollChanged()V
 HSPLandroid/view/ViewTreeObserver;->dispatchOnSystemGestureExclusionRectsChanged(Ljava/util/List;)V
 HSPLandroid/view/ViewTreeObserver;->dispatchOnTouchModeChanged(Z)V
@@ -18418,7 +18506,7 @@
 HSPLandroid/view/Window;->onDrawLegacyNavigationBarBackgroundChanged(Z)Z
 HSPLandroid/view/Window;->removeOnFrameMetricsAvailableListener(Landroid/view/Window$OnFrameMetricsAvailableListener;)V
 HSPLandroid/view/Window;->requestFeature(I)Z
-HSPLandroid/view/Window;->setAttributes(Landroid/view/WindowManager$LayoutParams;)V
+HSPLandroid/view/Window;->setAttributes(Landroid/view/WindowManager$LayoutParams;)V+]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/Window;Lcom/android/internal/policy/PhoneWindow;
 HSPLandroid/view/Window;->setBackgroundBlurRadius(I)V
 HSPLandroid/view/Window;->setCallback(Landroid/view/Window$Callback;)V
 HSPLandroid/view/Window;->setCloseOnTouchOutside(Z)V
@@ -18453,6 +18541,7 @@
 HSPLandroid/view/WindowInsets$Type;->systemBars()I
 HSPLandroid/view/WindowInsets$Type;->systemGestures()I
 HSPLandroid/view/WindowInsets$Type;->toString(I)Ljava/lang/String;
+HSPLandroid/view/WindowInsets;-><init>([Landroid/graphics/Insets;[Landroid/graphics/Insets;[ZZIILandroid/view/DisplayCutout;Landroid/view/RoundedCorners;Landroid/view/PrivacyIndicatorBounds;Landroid/view/DisplayShape;IZ[[Landroid/graphics/Rect;[[Landroid/graphics/Rect;II)V+]Landroid/view/DisplayCutout;Landroid/view/DisplayCutout;][Landroid/graphics/Insets;[Landroid/graphics/Insets;][[Landroid/graphics/Rect;[[Landroid/graphics/Rect;
 HSPLandroid/view/WindowInsets;->assignCompatInsets([Landroid/graphics/Insets;Landroid/graphics/Rect;)V
 HSPLandroid/view/WindowInsets;->consumeDisplayCutout()Landroid/view/WindowInsets;
 HSPLandroid/view/WindowInsets;->consumeStableInsets()Landroid/view/WindowInsets;
@@ -18474,13 +18563,13 @@
 HSPLandroid/view/WindowInsets;->getSystemWindowInsetLeft()I
 HSPLandroid/view/WindowInsets;->getSystemWindowInsetRight()I
 HSPLandroid/view/WindowInsets;->getSystemWindowInsetTop()I
-HSPLandroid/view/WindowInsets;->getSystemWindowInsets()Landroid/graphics/Insets;+]Landroid/view/WindowInsets;Landroid/view/WindowInsets;
+HSPLandroid/view/WindowInsets;->getSystemWindowInsets()Landroid/graphics/Insets;
 HSPLandroid/view/WindowInsets;->getSystemWindowInsetsAsRect()Landroid/graphics/Rect;
 HSPLandroid/view/WindowInsets;->inset(IIII)Landroid/view/WindowInsets;
 HSPLandroid/view/WindowInsets;->inset(Landroid/graphics/Insets;)Landroid/view/WindowInsets;
 HSPLandroid/view/WindowInsets;->insetInsets(Landroid/graphics/Insets;IIII)Landroid/graphics/Insets;
 HSPLandroid/view/WindowInsets;->insetInsets([Landroid/graphics/Insets;IIII)[Landroid/graphics/Insets;
-HSPLandroid/view/WindowInsets;->insetUnchecked(IIII)Landroid/view/WindowInsets;+]Landroid/view/PrivacyIndicatorBounds;Landroid/view/PrivacyIndicatorBounds;]Landroid/view/RoundedCorners;Landroid/view/RoundedCorners;
+HSPLandroid/view/WindowInsets;->insetUnchecked(IIII)Landroid/view/WindowInsets;
 HSPLandroid/view/WindowInsets;->isConsumed()Z
 HSPLandroid/view/WindowInsets;->isRound()Z
 HSPLandroid/view/WindowInsets;->replaceSystemWindowInsets(IIII)Landroid/view/WindowInsets;
@@ -18491,8 +18580,8 @@
 HSPLandroid/view/WindowInsetsAnimation;->setAlpha(F)V
 HSPLandroid/view/WindowLayout;-><clinit>()V
 HSPLandroid/view/WindowLayout;-><init>()V
-HSPLandroid/view/WindowLayout;->computeFrames(Landroid/view/WindowManager$LayoutParams;Landroid/view/InsetsState;Landroid/graphics/Rect;Landroid/graphics/Rect;IIIIFLandroid/window/ClientWindowFrames;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/DisplayCutout;Landroid/view/DisplayCutout;]Landroid/view/InsetsSource;Landroid/view/InsetsSource;]Landroid/view/InsetsState;Landroid/view/InsetsState;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;
-HSPLandroid/view/WindowLayout;->computeSurfaceSize(Landroid/view/WindowManager$LayoutParams;Landroid/graphics/Rect;IILandroid/graphics/Rect;ZLandroid/graphics/Point;)V
+HSPLandroid/view/WindowLayout;->computeFrames(Landroid/view/WindowManager$LayoutParams;Landroid/view/InsetsState;Landroid/graphics/Rect;Landroid/graphics/Rect;IIIIFLandroid/window/ClientWindowFrames;)V+]Landroid/view/InsetsState;Landroid/view/InsetsState;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Landroid/view/DisplayCutout;Landroid/view/DisplayCutout;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/view/WindowLayout;->computeSurfaceSize(Landroid/view/WindowManager$LayoutParams;Landroid/graphics/Rect;IILandroid/graphics/Rect;ZLandroid/graphics/Point;)V+]Landroid/graphics/Point;Landroid/graphics/Point;]Landroid/graphics/Rect;Landroid/graphics/Rect;
 HSPLandroid/view/WindowLeaked;-><init>(Ljava/lang/String;)V
 HSPLandroid/view/WindowManager$LayoutParams$1;->createFromParcel(Landroid/os/Parcel;)Landroid/view/WindowManager$LayoutParams;
 HSPLandroid/view/WindowManager$LayoutParams$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -18527,7 +18616,7 @@
 HSPLandroid/view/WindowManagerGlobal;->closeAllExceptView(Landroid/os/IBinder;Landroid/view/View;Ljava/lang/String;Ljava/lang/String;)V
 HSPLandroid/view/WindowManagerGlobal;->doRemoveView(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/WindowManagerGlobal;->dumpGfxInfo(Ljava/io/FileDescriptor;[Ljava/lang/String;)V
-HSPLandroid/view/WindowManagerGlobal;->findViewLocked(Landroid/view/View;Z)I
+HSPLandroid/view/WindowManagerGlobal;->findViewLocked(Landroid/view/View;Z)I+]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/WindowManagerGlobal;->getInstance()Landroid/view/WindowManagerGlobal;
 HSPLandroid/view/WindowManagerGlobal;->getRootViews(Landroid/os/IBinder;)Ljava/util/ArrayList;
 HSPLandroid/view/WindowManagerGlobal;->getWindowManagerService()Landroid/view/IWindowManager;
@@ -18537,9 +18626,9 @@
 HSPLandroid/view/WindowManagerGlobal;->peekWindowSession()Landroid/view/IWindowSession;
 HSPLandroid/view/WindowManagerGlobal;->removeView(Landroid/view/View;Z)V
 HSPLandroid/view/WindowManagerGlobal;->removeViewLocked(IZ)V
-HSPLandroid/view/WindowManagerGlobal;->setStoppedState(Landroid/os/IBinder;Z)V+]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Landroid/view/WindowManagerGlobal;Landroid/view/WindowManagerGlobal;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/view/WindowManagerGlobal;->setStoppedState(Landroid/os/IBinder;Z)V
 HSPLandroid/view/WindowManagerGlobal;->trimMemory(I)V
-HSPLandroid/view/WindowManagerGlobal;->updateViewLayout(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
+HSPLandroid/view/WindowManagerGlobal;->updateViewLayout(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/view/ViewRootImpl;Landroid/view/ViewRootImpl;]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/view/WindowManagerImpl;-><init>(Landroid/content/Context;)V
 HSPLandroid/view/WindowManagerImpl;-><init>(Landroid/content/Context;Landroid/view/Window;Landroid/os/IBinder;)V
 HSPLandroid/view/WindowManagerImpl;->addView(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
@@ -18552,7 +18641,7 @@
 HSPLandroid/view/WindowManagerImpl;->getMaximumWindowMetrics()Landroid/view/WindowMetrics;
 HSPLandroid/view/WindowManagerImpl;->removeView(Landroid/view/View;)V
 HSPLandroid/view/WindowManagerImpl;->removeViewImmediate(Landroid/view/View;)V
-HSPLandroid/view/WindowManagerImpl;->updateViewLayout(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V
+HSPLandroid/view/WindowManagerImpl;->updateViewLayout(Landroid/view/View;Landroid/view/ViewGroup$LayoutParams;)V+]Landroid/view/WindowManagerGlobal;Landroid/view/WindowManagerGlobal;
 HSPLandroid/view/WindowMetrics;-><init>(Landroid/graphics/Rect;Landroid/view/WindowInsets;)V
 HSPLandroid/view/WindowMetrics;-><init>(Landroid/graphics/Rect;Ljava/util/function/Supplier;F)V
 HSPLandroid/view/WindowMetrics;->getBounds()Landroid/graphics/Rect;
@@ -18594,8 +18683,8 @@
 HSPLandroid/view/accessibility/AccessibilityManager;->updateUiTimeout(J)V
 HSPLandroid/view/accessibility/AccessibilityNodeIdManager;-><init>()V
 HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->getInstance()Landroid/view/accessibility/AccessibilityNodeIdManager;
-HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->registerViewWithId(Landroid/view/View;I)V+]Landroid/view/accessibility/WeakSparseArray;Landroid/view/accessibility/WeakSparseArray;
-HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->unregisterViewWithId(I)V+]Landroid/view/accessibility/WeakSparseArray;Landroid/view/accessibility/WeakSparseArray;
+HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->registerViewWithId(Landroid/view/View;I)V
+HSPLandroid/view/accessibility/AccessibilityNodeIdManager;->unregisterViewWithId(I)V
 HSPLandroid/view/accessibility/AccessibilityNodeInfo$AccessibilityAction;-><init>(ILjava/lang/CharSequence;)V
 HSPLandroid/view/accessibility/AccessibilityNodeInfo$AccessibilityAction;->equals(Ljava/lang/Object;)Z
 HSPLandroid/view/accessibility/AccessibilityNodeInfo$AccessibilityAction;->getId()I
@@ -18635,9 +18724,9 @@
 HSPLandroid/view/accessibility/IAccessibilityManagerClient$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/view/accessibility/WeakSparseArray$WeakReferenceWithId;-><init>(Ljava/lang/Object;Ljava/lang/ref/ReferenceQueue;I)V
 HSPLandroid/view/accessibility/WeakSparseArray;-><init>()V
-HSPLandroid/view/accessibility/WeakSparseArray;->append(ILjava/lang/Object;)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
-HSPLandroid/view/accessibility/WeakSparseArray;->remove(I)V+]Landroid/util/SparseArray;Landroid/util/SparseArray;
-HSPLandroid/view/accessibility/WeakSparseArray;->removeUnreachableValues()V+]Ljava/lang/ref/ReferenceQueue;Ljava/lang/ref/ReferenceQueue;
+HSPLandroid/view/accessibility/WeakSparseArray;->append(ILjava/lang/Object;)V
+HSPLandroid/view/accessibility/WeakSparseArray;->remove(I)V
+HSPLandroid/view/accessibility/WeakSparseArray;->removeUnreachableValues()V
 HSPLandroid/view/animation/AccelerateDecelerateInterpolator;-><init>()V
 HSPLandroid/view/animation/AccelerateDecelerateInterpolator;->createNativeInterpolator()J
 HSPLandroid/view/animation/AccelerateDecelerateInterpolator;->getInterpolation(F)F
@@ -18647,7 +18736,7 @@
 HSPLandroid/view/animation/AccelerateInterpolator;->getInterpolation(F)F
 HSPLandroid/view/animation/AlphaAnimation;-><init>(FF)V
 HSPLandroid/view/animation/AlphaAnimation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
-HSPLandroid/view/animation/AlphaAnimation;->applyTransformation(FLandroid/view/animation/Transformation;)V+]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;
+HSPLandroid/view/animation/AlphaAnimation;->applyTransformation(FLandroid/view/animation/Transformation;)V
 HSPLandroid/view/animation/AlphaAnimation;->hasAlpha()Z
 HSPLandroid/view/animation/AlphaAnimation;->willChangeBounds()Z
 HSPLandroid/view/animation/AlphaAnimation;->willChangeTransformationMatrix()Z
@@ -18656,7 +18745,7 @@
 HSPLandroid/view/animation/Animation$Description;-><init>()V
 HSPLandroid/view/animation/Animation$Description;->parseValue(Landroid/util/TypedValue;Landroid/content/Context;)Landroid/view/animation/Animation$Description;
 HSPLandroid/view/animation/Animation;-><init>()V
-HSPLandroid/view/animation/Animation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;
+HSPLandroid/view/animation/Animation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/view/animation/Animation;->cancel()V
 HSPLandroid/view/animation/Animation;->detach()V
 HSPLandroid/view/animation/Animation;->dispatchAnimationEnd()V
@@ -18665,12 +18754,12 @@
 HSPLandroid/view/animation/Animation;->finalize()V
 HSPLandroid/view/animation/Animation;->getDuration()J
 HSPLandroid/view/animation/Animation;->getFillAfter()Z
-HSPLandroid/view/animation/Animation;->getInvalidateRegion(IIIILandroid/graphics/RectF;Landroid/view/animation/Transformation;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;
+HSPLandroid/view/animation/Animation;->getInvalidateRegion(IIIILandroid/graphics/RectF;Landroid/view/animation/Transformation;)V
 HSPLandroid/view/animation/Animation;->getScaleFactor()F
 HSPLandroid/view/animation/Animation;->getStartOffset()J
-HSPLandroid/view/animation/Animation;->getTransformation(JLandroid/view/animation/Transformation;)Z+]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;]Ldalvik/system/CloseGuard;Ldalvik/system/CloseGuard;
-HSPLandroid/view/animation/Animation;->getTransformation(JLandroid/view/animation/Transformation;F)Z+]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;
-HSPLandroid/view/animation/Animation;->getTransformationAt(FLandroid/view/animation/Transformation;)V+]Landroid/view/animation/Animation;Landroid/view/animation/AlphaAnimation;,Landroid/view/animation/RotateAnimation;]Landroid/view/animation/Interpolator;Landroid/view/animation/AccelerateDecelerateInterpolator;,Landroid/view/animation/LinearInterpolator;
+HSPLandroid/view/animation/Animation;->getTransformation(JLandroid/view/animation/Transformation;)Z
+HSPLandroid/view/animation/Animation;->getTransformation(JLandroid/view/animation/Transformation;F)Z
+HSPLandroid/view/animation/Animation;->getTransformationAt(FLandroid/view/animation/Transformation;)V
 HSPLandroid/view/animation/Animation;->hasAlpha()Z
 HSPLandroid/view/animation/Animation;->hasEnded()Z
 HSPLandroid/view/animation/Animation;->hasStarted()Z
@@ -18727,7 +18816,7 @@
 HSPLandroid/view/animation/AnimationUtils$AnimationState;-><init>(Landroid/view/animation/AnimationUtils$AnimationState-IA;)V
 HSPLandroid/view/animation/AnimationUtils;->createAnimationFromXml(Landroid/content/Context;Lorg/xmlpull/v1/XmlPullParser;)Landroid/view/animation/Animation;
 HSPLandroid/view/animation/AnimationUtils;->createAnimationFromXml(Landroid/content/Context;Lorg/xmlpull/v1/XmlPullParser;Landroid/view/animation/AnimationSet;Landroid/util/AttributeSet;)Landroid/view/animation/Animation;
-HSPLandroid/view/animation/AnimationUtils;->createInterpolatorFromXml(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Lorg/xmlpull/v1/XmlPullParser;)Landroid/view/animation/Interpolator;+]Ljava/lang/Object;Ljava/lang/String;]Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/XmlBlock$Parser;
+HSPLandroid/view/animation/AnimationUtils;->createInterpolatorFromXml(Landroid/content/res/Resources;Landroid/content/res/Resources$Theme;Lorg/xmlpull/v1/XmlPullParser;)Landroid/view/animation/Interpolator;
 HSPLandroid/view/animation/AnimationUtils;->currentAnimationTimeMillis()J
 HSPLandroid/view/animation/AnimationUtils;->loadAnimation(Landroid/content/Context;I)Landroid/view/animation/Animation;
 HSPLandroid/view/animation/AnimationUtils;->loadInterpolator(Landroid/content/Context;I)Landroid/view/animation/Interpolator;
@@ -18753,7 +18842,7 @@
 HSPLandroid/view/animation/PathInterpolator;->createNativeInterpolator()J
 HSPLandroid/view/animation/PathInterpolator;->getInterpolation(F)F
 HSPLandroid/view/animation/PathInterpolator;->initCubic(FFFF)V
-HSPLandroid/view/animation/PathInterpolator;->initPath(Landroid/graphics/Path;)V
+HSPLandroid/view/animation/PathInterpolator;->initPath(Landroid/graphics/Path;)V+]Landroid/graphics/Path;Landroid/graphics/Path;
 HSPLandroid/view/animation/PathInterpolator;->parseInterpolatorFromTypeArray(Landroid/content/res/TypedArray;)V
 HSPLandroid/view/animation/ScaleAnimation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/view/animation/ScaleAnimation;->applyTransformation(FLandroid/view/animation/Transformation;)V
@@ -18761,13 +18850,13 @@
 HSPLandroid/view/animation/ScaleAnimation;->initializePivotPoint()V
 HSPLandroid/view/animation/ScaleAnimation;->resolveScale(FIIII)F
 HSPLandroid/view/animation/Transformation;-><init>()V
-HSPLandroid/view/animation/Transformation;->clear()V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/view/animation/Transformation;->clear()V
 HSPLandroid/view/animation/Transformation;->compose(Landroid/view/animation/Transformation;)V
 HSPLandroid/view/animation/Transformation;->getAlpha()F
 HSPLandroid/view/animation/Transformation;->getInsets()Landroid/graphics/Insets;
 HSPLandroid/view/animation/Transformation;->getMatrix()Landroid/graphics/Matrix;
 HSPLandroid/view/animation/Transformation;->getTransformationType()I
-HSPLandroid/view/animation/Transformation;->set(Landroid/view/animation/Transformation;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/view/animation/Transformation;Landroid/view/animation/Transformation;
+HSPLandroid/view/animation/Transformation;->set(Landroid/view/animation/Transformation;)V
 HSPLandroid/view/animation/Transformation;->setAlpha(F)V
 HSPLandroid/view/animation/Transformation;->setInsets(Landroid/graphics/Insets;)V
 HSPLandroid/view/animation/TranslateAnimation;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
@@ -18840,7 +18929,7 @@
 HSPLandroid/view/autofill/AutofillManager;->isActiveLocked()Z
 HSPLandroid/view/autofill/AutofillManager;->isDisabledByServiceLocked()Z
 HSPLandroid/view/autofill/AutofillManager;->isEnabled()Z
-HSPLandroid/view/autofill/AutofillManager;->notifyValueChanged(Landroid/view/View;)V+]Landroid/view/autofill/AutofillManager;Landroid/view/autofill/AutofillManager;
+HSPLandroid/view/autofill/AutofillManager;->notifyValueChanged(Landroid/view/View;)V
 HSPLandroid/view/autofill/AutofillManager;->notifyViewEntered(Landroid/view/View;I)V
 HSPLandroid/view/autofill/AutofillManager;->notifyViewEnteredForAugmentedAutofill(Landroid/view/View;)V
 HSPLandroid/view/autofill/AutofillManager;->notifyViewEnteredForFillDialog(Landroid/view/View;)V
@@ -18872,6 +18961,7 @@
 HSPLandroid/view/autofill/IAugmentedAutofillManagerClient$Stub;->asBinder()Landroid/os/IBinder;
 HSPLandroid/view/autofill/IAugmentedAutofillManagerClient$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;->addClient(Landroid/view/autofill/IAutoFillManagerClient;Landroid/content/ComponentName;ILcom/android/internal/os/IResultReceiver;)V
 HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;->cancelSession(II)V
 HSPLandroid/view/autofill/IAutoFillManager$Stub$Proxy;->getAutofillServiceComponentName(Lcom/android/internal/os/IResultReceiver;)V
@@ -19112,7 +19202,7 @@
 HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onPostWindowGainedFocus(Landroid/view/View;Landroid/view/WindowManager$LayoutParams;)V
 HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onPreWindowGainedFocus(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onScheduledCheckFocus(Landroid/view/ViewRootImpl;)V
-HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onViewDetachedFromWindow(Landroid/view/View;Landroid/view/ViewRootImpl;)V+]Landroid/view/View;missing_types
+HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onViewDetachedFromWindow(Landroid/view/View;Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->onWindowDismissed(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/inputmethod/InputMethodManager$DelegateImpl;->setCurrentRootViewLocked(Landroid/view/ViewRootImpl;)V
 HSPLandroid/view/inputmethod/InputMethodManager$H$$ExternalSyntheticLambda0;->run()V
@@ -19439,17 +19529,17 @@
 HSPLandroid/widget/AbsListView$DeviceConfigChangeListener;-><init>()V
 HSPLandroid/widget/AbsListView$DeviceConfigChangeListener;-><init>(Landroid/widget/AbsListView$DeviceConfigChangeListener-IA;)V
 HSPLandroid/widget/AbsListView$PerformClick;->run()V
-HSPLandroid/widget/AbsListView$RecycleBin;->addScrapView(Landroid/view/View;I)V+]Landroid/view/View;Landroid/widget/LinearLayout;]Landroid/widget/AbsListView$RecycleBin;Landroid/widget/AbsListView$RecycleBin;]Landroid/widget/AbsListView;Landroid/widget/ListView;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/AbsListView$RecycleBin;->addScrapView(Landroid/view/View;I)V
 HSPLandroid/widget/AbsListView$RecycleBin;->clear()V
 HSPLandroid/widget/AbsListView$RecycleBin;->clearTransientStateViews()V
 HSPLandroid/widget/AbsListView$RecycleBin;->fillActiveViews(II)V
 HSPLandroid/widget/AbsListView$RecycleBin;->getActiveView(I)Landroid/view/View;
-HSPLandroid/widget/AbsListView$RecycleBin;->getScrapView(I)Landroid/view/View;+]Landroid/widget/ListAdapter;missing_types
+HSPLandroid/widget/AbsListView$RecycleBin;->getScrapView(I)Landroid/view/View;
 HSPLandroid/widget/AbsListView$RecycleBin;->getTransientStateView(I)Landroid/view/View;
 HSPLandroid/widget/AbsListView$RecycleBin;->markChildrenDirty()V
 HSPLandroid/widget/AbsListView$RecycleBin;->pruneScrapViews()V
 HSPLandroid/widget/AbsListView$RecycleBin;->removeSkippedScrap()V
-HSPLandroid/widget/AbsListView$RecycleBin;->retrieveFromScrap(Ljava/util/ArrayList;I)Landroid/view/View;+]Landroid/view/View;Landroid/widget/LinearLayout;]Landroid/widget/ListAdapter;Landroid/preference/PreferenceGroupAdapter;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/AbsListView$RecycleBin;->retrieveFromScrap(Ljava/util/ArrayList;I)Landroid/view/View;
 HSPLandroid/widget/AbsListView$RecycleBin;->scrapActiveViews()V
 HSPLandroid/widget/AbsListView$RecycleBin;->setViewTypeCount(I)V
 HSPLandroid/widget/AbsListView$RecycleBin;->shouldRecycleViewType(I)Z
@@ -19459,12 +19549,12 @@
 HSPLandroid/widget/AbsListView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V
 HSPLandroid/widget/AbsListView;->checkLayoutParams(Landroid/view/ViewGroup$LayoutParams;)Z
 HSPLandroid/widget/AbsListView;->clearChoices()V
-HSPLandroid/widget/AbsListView;->computeVerticalScrollExtent()I+]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/widget/AbsListView;missing_types
-HSPLandroid/widget/AbsListView;->computeVerticalScrollOffset()I+]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/widget/AbsListView;missing_types
+HSPLandroid/widget/AbsListView;->computeVerticalScrollExtent()I
+HSPLandroid/widget/AbsListView;->computeVerticalScrollOffset()I
 HSPLandroid/widget/AbsListView;->computeVerticalScrollRange()I
 HSPLandroid/widget/AbsListView;->dispatchDraw(Landroid/graphics/Canvas;)V
 HSPLandroid/widget/AbsListView;->dispatchSetPressed(Z)V
-HSPLandroid/widget/AbsListView;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/widget/AbsListView;missing_types]Landroid/widget/EdgeEffect;Landroid/widget/EdgeEffect;
+HSPLandroid/widget/AbsListView;->draw(Landroid/graphics/Canvas;)V
 HSPLandroid/widget/AbsListView;->drawableStateChanged()V
 HSPLandroid/widget/AbsListView;->generateDefaultLayoutParams()Landroid/view/ViewGroup$LayoutParams;
 HSPLandroid/widget/AbsListView;->generateLayoutParams(Landroid/util/AttributeSet;)Landroid/view/ViewGroup$LayoutParams;
@@ -19482,7 +19572,7 @@
 HSPLandroid/widget/AbsListView;->isInFilterMode()Z
 HSPLandroid/widget/AbsListView;->isVerticalScrollBarHidden()Z
 HSPLandroid/widget/AbsListView;->jumpDrawablesToCurrentState()V
-HSPLandroid/widget/AbsListView;->obtainView(I[Z)Landroid/view/View;+]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/widget/AbsListView$RecycleBin;Landroid/widget/AbsListView$RecycleBin;]Landroid/widget/ListAdapter;missing_types
+HSPLandroid/widget/AbsListView;->obtainView(I[Z)Landroid/view/View;
 HSPLandroid/widget/AbsListView;->onAttachedToWindow()V
 HSPLandroid/widget/AbsListView;->onCancelPendingInputEvents()V
 HSPLandroid/widget/AbsListView;->onDetachedFromWindow()V
@@ -19492,9 +19582,9 @@
 HSPLandroid/widget/AbsListView;->onRtlPropertiesChanged(I)V
 HSPLandroid/widget/AbsListView;->onSaveInstanceState()Landroid/os/Parcelable;
 HSPLandroid/widget/AbsListView;->onTouchDown(Landroid/view/MotionEvent;)V
-HSPLandroid/widget/AbsListView;->onTouchEvent(Landroid/view/MotionEvent;)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/VelocityTracker;Landroid/view/VelocityTracker;]Landroid/widget/AbsListView;Landroid/widget/ListView;
+HSPLandroid/widget/AbsListView;->onTouchEvent(Landroid/view/MotionEvent;)Z
 HSPLandroid/widget/AbsListView;->onTouchModeChanged(Z)V
-HSPLandroid/widget/AbsListView;->onTouchMove(Landroid/view/MotionEvent;Landroid/view/MotionEvent;)V+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;]Landroid/view/View;Landroid/widget/LinearLayout;]Landroid/widget/AbsListView;Landroid/widget/ListView;
+HSPLandroid/widget/AbsListView;->onTouchMove(Landroid/view/MotionEvent;Landroid/view/MotionEvent;)V
 HSPLandroid/widget/AbsListView;->onTouchUp(Landroid/view/MotionEvent;)V
 HSPLandroid/widget/AbsListView;->onWindowFocusChanged(Z)V
 HSPLandroid/widget/AbsListView;->performItemClick(Landroid/view/View;IJ)Z
@@ -19509,7 +19599,7 @@
 HSPLandroid/widget/AbsListView;->setFastScrollEnabled(Z)V
 HSPLandroid/widget/AbsListView;->setFastScrollStyle(I)V
 HSPLandroid/widget/AbsListView;->setFrame(IIII)Z
-HSPLandroid/widget/AbsListView;->setItemViewLayoutParams(Landroid/view/View;I)V+]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/widget/AbsListView;missing_types]Landroid/widget/ListAdapter;missing_types
+HSPLandroid/widget/AbsListView;->setItemViewLayoutParams(Landroid/view/View;I)V
 HSPLandroid/widget/AbsListView;->setOnScrollListener(Landroid/widget/AbsListView$OnScrollListener;)V
 HSPLandroid/widget/AbsListView;->setScrollingCacheEnabled(Z)V
 HSPLandroid/widget/AbsListView;->setSelectionFromTop(II)V
@@ -19649,7 +19739,7 @@
 HSPLandroid/widget/EdgeEffect;->isFinished()Z
 HSPLandroid/widget/EdgeEffect;->onAbsorb(I)V
 HSPLandroid/widget/EdgeEffect;->onPull(FF)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;
-HSPLandroid/widget/EdgeEffect;->onPullDistance(FF)F+]Landroid/widget/EdgeEffect;Landroid/widget/EdgeEffect;
+HSPLandroid/widget/EdgeEffect;->onPullDistance(FF)F
 HSPLandroid/widget/EdgeEffect;->onRelease()V
 HSPLandroid/widget/EdgeEffect;->setSize(II)V
 HSPLandroid/widget/EdgeEffect;->update()V
@@ -19674,7 +19764,7 @@
 HSPLandroid/widget/Editor$Blink;->cancel()V
 HSPLandroid/widget/Editor$Blink;->run()V
 HSPLandroid/widget/Editor$Blink;->uncancel()V
-HSPLandroid/widget/Editor$CursorAnchorInfoNotifier;->updatePosition(IIZZ)V
+HSPLandroid/widget/Editor$CursorAnchorInfoNotifier;->updatePosition(IIZZ)V+]Landroid/view/inputmethod/InputMethodManager;Landroid/view/inputmethod/InputMethodManager;
 HSPLandroid/widget/Editor$EditOperation;-><init>(Landroid/widget/Editor;Ljava/lang/String;ILjava/lang/String;Z)V
 HSPLandroid/widget/Editor$EditOperation;->commit()V
 HSPLandroid/widget/Editor$EditOperation;->forceMergeWith(Landroid/widget/Editor$EditOperation;)V
@@ -19718,10 +19808,10 @@
 HSPLandroid/widget/Editor$InsertionPointCursorController;->onTouchEvent(Landroid/view/MotionEvent;)V
 HSPLandroid/widget/Editor$InsertionPointCursorController;->show()V
 HSPLandroid/widget/Editor$PositionListener;->addSubscriber(Landroid/widget/Editor$TextViewPositionListener;Z)V
-HSPLandroid/widget/Editor$PositionListener;->onPreDraw()Z
+HSPLandroid/widget/Editor$PositionListener;->onPreDraw()Z+]Landroid/widget/Editor$TextViewPositionListener;Landroid/widget/Editor$CursorAnchorInfoNotifier;,Landroid/widget/Editor$InsertionHandleView;
 HSPLandroid/widget/Editor$PositionListener;->onScrollChanged()V
 HSPLandroid/widget/Editor$PositionListener;->removeSubscriber(Landroid/widget/Editor$TextViewPositionListener;)V
-HSPLandroid/widget/Editor$PositionListener;->updatePosition()V
+HSPLandroid/widget/Editor$PositionListener;->updatePosition()V+]Landroid/widget/TextView;Landroid/widget/EditText;
 HSPLandroid/widget/Editor$ProcessTextIntentActionsHandler;-><init>(Landroid/widget/Editor;)V
 HSPLandroid/widget/Editor$SelectionModifierCursorController;->getMinTouchOffset()I
 HSPLandroid/widget/Editor$SelectionModifierCursorController;->hide()V
@@ -19730,7 +19820,7 @@
 HSPLandroid/widget/Editor$SelectionModifierCursorController;->isDragAcceleratorActive()Z
 HSPLandroid/widget/Editor$SelectionModifierCursorController;->isSelectionStartDragged()Z
 HSPLandroid/widget/Editor$SelectionModifierCursorController;->onDetached()V
-HSPLandroid/widget/Editor$SelectionModifierCursorController;->onTouchEvent(Landroid/view/MotionEvent;)V
+HSPLandroid/widget/Editor$SelectionModifierCursorController;->onTouchEvent(Landroid/view/MotionEvent;)V+]Landroid/widget/EditorTouchState;Landroid/widget/EditorTouchState;]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/widget/Editor$SelectionModifierCursorController;Landroid/widget/Editor$SelectionModifierCursorController;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
 HSPLandroid/widget/Editor$SelectionModifierCursorController;->resetDragAcceleratorState()V
 HSPLandroid/widget/Editor$SelectionModifierCursorController;->resetTouchOffsets()V
 HSPLandroid/widget/Editor$SelectionModifierCursorController;->updateSelection(Landroid/view/MotionEvent;)V
@@ -19738,7 +19828,7 @@
 HSPLandroid/widget/Editor$SpanController;->onSpanAdded(Landroid/text/Spannable;Ljava/lang/Object;II)V
 HSPLandroid/widget/Editor$SpanController;->onSpanChanged(Landroid/text/Spannable;Ljava/lang/Object;IIII)V
 HSPLandroid/widget/Editor$SpanController;->onSpanRemoved(Landroid/text/Spannable;Ljava/lang/Object;II)V
-HSPLandroid/widget/Editor$TextRenderNode;->needsRecord()Z
+HSPLandroid/widget/Editor$TextRenderNode;->needsRecord()Z+]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;
 HSPLandroid/widget/Editor$UndoInputFilter;->beginBatchEdit()V
 HSPLandroid/widget/Editor$UndoInputFilter;->canUndoEdit(Ljava/lang/CharSequence;IILandroid/text/Spanned;II)Z
 HSPLandroid/widget/Editor$UndoInputFilter;->endBatchEdit()V
@@ -19759,7 +19849,7 @@
 HSPLandroid/widget/Editor;->createInputMethodStateIfNeeded()V
 HSPLandroid/widget/Editor;->discardTextDisplayLists()V
 HSPLandroid/widget/Editor;->downgradeEasyCorrectionSpans()V
-HSPLandroid/widget/Editor;->drawHardwareAcceleratedInner(Landroid/graphics/Canvas;Landroid/text/Layout;Landroid/graphics/Path;Landroid/graphics/Paint;I[I[IIII)I
+HSPLandroid/widget/Editor;->drawHardwareAcceleratedInner(Landroid/graphics/Canvas;Landroid/text/Layout;Landroid/graphics/Path;Landroid/graphics/Paint;I[I[IIII)I+]Landroid/widget/Editor$TextRenderNode;Landroid/widget/Editor$TextRenderNode;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Landroid/text/Layout;Landroid/text/DynamicLayout;]Landroid/graphics/RenderNode;Landroid/graphics/RenderNode;]Landroid/graphics/RecordingCanvas;Landroid/graphics/RecordingCanvas;
 HSPLandroid/widget/Editor;->endBatchEdit()V
 HSPLandroid/widget/Editor;->ensureEndedBatchEdit()V
 HSPLandroid/widget/Editor;->ensureNoSelectionIfNonSelectable()V
@@ -19795,10 +19885,10 @@
 HSPLandroid/widget/Editor;->onLocaleChanged()V
 HSPLandroid/widget/Editor;->onScreenStateChanged(I)V
 HSPLandroid/widget/Editor;->onScrollChanged()V
-HSPLandroid/widget/Editor;->onTouchEvent(Landroid/view/MotionEvent;)V
+HSPLandroid/widget/Editor;->onTouchEvent(Landroid/view/MotionEvent;)V+]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/EditorTouchState;Landroid/widget/EditorTouchState;]Landroid/widget/Editor$SelectionModifierCursorController;Landroid/widget/Editor$SelectionModifierCursorController;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
 HSPLandroid/widget/Editor;->onTouchUpEvent(Landroid/view/MotionEvent;)V
 HSPLandroid/widget/Editor;->onWindowFocusChanged(Z)V
-HSPLandroid/widget/Editor;->prepareCursorControllers()V
+HSPLandroid/widget/Editor;->prepareCursorControllers()V+]Landroid/view/View;Lcom/android/internal/policy/DecorView;]Landroid/widget/Editor;Landroid/widget/Editor;
 HSPLandroid/widget/Editor;->refreshTextActionMode()V
 HSPLandroid/widget/Editor;->reportExtractedText()Z
 HSPLandroid/widget/Editor;->restoreInstanceState(Landroid/os/ParcelableParcel;)V
@@ -19823,19 +19913,19 @@
 HSPLandroid/widget/EditorTouchState;->isMovedEnoughForDrag()Z
 HSPLandroid/widget/EditorTouchState;->isMultiTap()Z
 HSPLandroid/widget/EditorTouchState;->isMultiTapInSameArea()Z
-HSPLandroid/widget/EditorTouchState;->update(Landroid/view/MotionEvent;Landroid/view/ViewConfiguration;)V
+HSPLandroid/widget/EditorTouchState;->update(Landroid/view/MotionEvent;Landroid/view/ViewConfiguration;)V+]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
 HSPLandroid/widget/Filter;-><init>()V
 HSPLandroid/widget/ForwardingListener;-><init>(Landroid/view/View;)V
 HSPLandroid/widget/ForwardingListener;->onViewAttachedToWindow(Landroid/view/View;)V
 HSPLandroid/widget/ForwardingListener;->onViewDetachedFromWindow(Landroid/view/View;)V
 HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(II)V
 HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(III)V
-HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
+HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/FrameLayout$LayoutParams;-><init>(Landroid/view/ViewGroup$LayoutParams;)V
 HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;)V
 HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/widget/FrameLayout;missing_types
+HSPLandroid/widget/FrameLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V
 HSPLandroid/widget/FrameLayout;->checkLayoutParams(Landroid/view/ViewGroup$LayoutParams;)Z
 HSPLandroid/widget/FrameLayout;->generateDefaultLayoutParams()Landroid/view/ViewGroup$LayoutParams;
 HSPLandroid/widget/FrameLayout;->generateDefaultLayoutParams()Landroid/widget/FrameLayout$LayoutParams;
@@ -19849,7 +19939,7 @@
 HSPLandroid/widget/FrameLayout;->getPaddingTopWithForeground()I+]Landroid/widget/FrameLayout;missing_types
 HSPLandroid/widget/FrameLayout;->layoutChildren(IIIIZ)V+]Landroid/view/View;missing_types]Landroid/widget/FrameLayout;missing_types
 HSPLandroid/widget/FrameLayout;->onLayout(ZIIII)V+]Landroid/widget/FrameLayout;missing_types
-HSPLandroid/widget/FrameLayout;->onMeasure(II)V+]Landroid/view/View;missing_types]Landroid/widget/FrameLayout;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/FrameLayout;->onMeasure(II)V+]Landroid/widget/FrameLayout;missing_types]Landroid/view/View;missing_types]Ljava/util/ArrayList;Ljava/util/ArrayList;
 HSPLandroid/widget/FrameLayout;->setForegroundGravity(I)V
 HSPLandroid/widget/FrameLayout;->setMeasureAllChildren(Z)V
 HSPLandroid/widget/FrameLayout;->shouldDelayChildPressedState()Z
@@ -19946,13 +20036,13 @@
 HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;)V
 HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
 HSPLandroid/widget/ImageView;->applyAlpha()V
 HSPLandroid/widget/ImageView;->applyColorFilter()V
-HSPLandroid/widget/ImageView;->applyImageTint()V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/VectorDrawable;
+HSPLandroid/widget/ImageView;->applyImageTint()V
 HSPLandroid/widget/ImageView;->applyXfermode()V
 HSPLandroid/widget/ImageView;->clearColorFilter()V
-HSPLandroid/widget/ImageView;->configureBounds()V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;]Landroid/graphics/RectF;Landroid/graphics/RectF;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->configureBounds()V
 HSPLandroid/widget/ImageView;->drawableHotspotChanged(FF)V
 HSPLandroid/widget/ImageView;->drawableStateChanged()V
 HSPLandroid/widget/ImageView;->getAccessibilityClassName()Ljava/lang/CharSequence;
@@ -19961,21 +20051,21 @@
 HSPLandroid/widget/ImageView;->getImageMatrix()Landroid/graphics/Matrix;
 HSPLandroid/widget/ImageView;->getScaleType()Landroid/widget/ImageView$ScaleType;
 HSPLandroid/widget/ImageView;->hasOverlappingRendering()Z
-HSPLandroid/widget/ImageView;->initImageView()V+]Landroid/widget/ImageView;missing_types
-HSPLandroid/widget/ImageView;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->initImageView()V
+HSPLandroid/widget/ImageView;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/ImageView;->isFilledByImage()Z
-HSPLandroid/widget/ImageView;->isOpaque()Z+]Landroid/graphics/drawable/Drawable;megamorphic_types
-HSPLandroid/widget/ImageView;->jumpDrawablesToCurrentState()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/widget/ImageView;->isOpaque()Z
+HSPLandroid/widget/ImageView;->jumpDrawablesToCurrentState()V
 HSPLandroid/widget/ImageView;->onAttachedToWindow()V
 HSPLandroid/widget/ImageView;->onCreateDrawableState(I)[I
 HSPLandroid/widget/ImageView;->onDetachedFromWindow()V
-HSPLandroid/widget/ImageView;->onDraw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/Drawable;missing_types
-HSPLandroid/widget/ImageView;->onMeasure(II)V+]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->onDraw(Landroid/graphics/Canvas;)V
+HSPLandroid/widget/ImageView;->onMeasure(II)V
 HSPLandroid/widget/ImageView;->onRtlPropertiesChanged(I)V
-HSPLandroid/widget/ImageView;->onVisibilityAggregated(Z)V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/widget/ImageView;->onVisibilityAggregated(Z)V
 HSPLandroid/widget/ImageView;->resizeFromDrawable()V
 HSPLandroid/widget/ImageView;->resolveAdjustedSize(III)I
-HSPLandroid/widget/ImageView;->resolveUri()V+]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->resolveUri()V
 HSPLandroid/widget/ImageView;->scaleTypeToScaleToFit(Landroid/widget/ImageView$ScaleType;)Landroid/graphics/Matrix$ScaleToFit;
 HSPLandroid/widget/ImageView;->setAdjustViewBounds(Z)V
 HSPLandroid/widget/ImageView;->setAlpha(I)V
@@ -19986,9 +20076,9 @@
 HSPLandroid/widget/ImageView;->setFrame(IIII)Z
 HSPLandroid/widget/ImageView;->setImageAlpha(I)V
 HSPLandroid/widget/ImageView;->setImageBitmap(Landroid/graphics/Bitmap;)V
-HSPLandroid/widget/ImageView;->setImageDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/widget/ImageView;missing_types
-HSPLandroid/widget/ImageView;->setImageMatrix(Landroid/graphics/Matrix;)V
-HSPLandroid/widget/ImageView;->setImageResource(I)V+]Landroid/widget/ImageView;Landroid/widget/ImageView;
+HSPLandroid/widget/ImageView;->setImageDrawable(Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/widget/ImageView;->setImageMatrix(Landroid/graphics/Matrix;)V+]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
+HSPLandroid/widget/ImageView;->setImageResource(I)V
 HSPLandroid/widget/ImageView;->setImageTintBlendMode(Landroid/graphics/BlendMode;)V
 HSPLandroid/widget/ImageView;->setImageTintList(Landroid/content/res/ColorStateList;)V
 HSPLandroid/widget/ImageView;->setMaxHeight(I)V
@@ -19996,16 +20086,16 @@
 HSPLandroid/widget/ImageView;->setScaleType(Landroid/widget/ImageView$ScaleType;)V
 HSPLandroid/widget/ImageView;->setSelected(Z)V
 HSPLandroid/widget/ImageView;->setVisibility(I)V
-HSPLandroid/widget/ImageView;->updateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;missing_types]Landroid/widget/ImageView;missing_types
+HSPLandroid/widget/ImageView;->updateDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/ImageView;->verifyDrawable(Landroid/graphics/drawable/Drawable;)Z
 HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(II)V
 HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(IIF)V
-HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
+HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/LinearLayout$LayoutParams;-><init>(Landroid/view/ViewGroup$LayoutParams;)V
 HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;)V
 HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/widget/LinearLayout;missing_types
+HSPLandroid/widget/LinearLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/widget/LinearLayout;Landroid/widget/LinearLayout;
 HSPLandroid/widget/LinearLayout;->allViewsAreGoneBefore(I)Z
 HSPLandroid/widget/LinearLayout;->checkLayoutParams(Landroid/view/ViewGroup$LayoutParams;)Z
 HSPLandroid/widget/LinearLayout;->forceUniformHeight(II)V
@@ -20027,8 +20117,8 @@
 HSPLandroid/widget/LinearLayout;->getVirtualChildAt(I)Landroid/view/View;+]Landroid/widget/LinearLayout;missing_types
 HSPLandroid/widget/LinearLayout;->getVirtualChildCount()I+]Landroid/widget/LinearLayout;missing_types
 HSPLandroid/widget/LinearLayout;->hasDividerBeforeChildAt(I)Z
-HSPLandroid/widget/LinearLayout;->layoutHorizontal(IIII)V+]Landroid/view/View;missing_types]Landroid/widget/LinearLayout;Landroid/widget/LinearLayout;
-HSPLandroid/widget/LinearLayout;->layoutVertical(IIII)V+]Landroid/view/View;megamorphic_types]Landroid/widget/LinearLayout;missing_types
+HSPLandroid/widget/LinearLayout;->layoutHorizontal(IIII)V
+HSPLandroid/widget/LinearLayout;->layoutVertical(IIII)V+]Landroid/view/View;missing_types]Landroid/widget/LinearLayout;missing_types
 HSPLandroid/widget/LinearLayout;->measureChildBeforeLayout(Landroid/view/View;IIIII)V+]Landroid/widget/LinearLayout;missing_types
 HSPLandroid/widget/LinearLayout;->measureHorizontal(II)V+]Landroid/view/View;missing_types]Landroid/widget/LinearLayout;Landroid/widget/LinearLayout;
 HSPLandroid/widget/LinearLayout;->measureVertical(II)V+]Landroid/view/View;megamorphic_types]Landroid/widget/LinearLayout;missing_types
@@ -20061,7 +20151,7 @@
 HSPLandroid/widget/ListView;->adjustViewsUpOrDown()V
 HSPLandroid/widget/ListView;->clearRecycledState(Ljava/util/ArrayList;)V
 HSPLandroid/widget/ListView;->correctTooHigh(I)V
-HSPLandroid/widget/ListView;->dispatchDraw(Landroid/graphics/Canvas;)V+]Landroid/view/View;Landroid/widget/LinearLayout;]Landroid/widget/ListAdapter;Landroid/preference/PreferenceGroupAdapter;]Landroid/widget/ListView;Landroid/widget/ListView;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/ListView;->dispatchDraw(Landroid/graphics/Canvas;)V
 HSPLandroid/widget/ListView;->drawChild(Landroid/graphics/Canvas;Landroid/view/View;J)Z
 HSPLandroid/widget/ListView;->fillDown(II)Landroid/view/View;
 HSPLandroid/widget/ListView;->fillFromTop(I)Landroid/view/View;
@@ -20077,8 +20167,8 @@
 HSPLandroid/widget/ListView;->layoutChildren()V
 HSPLandroid/widget/ListView;->lookForSelectablePosition(IZ)I
 HSPLandroid/widget/ListView;->makeAndAddView(IIZIZ)Landroid/view/View;
-HSPLandroid/widget/ListView;->measureHeightOfChildren(IIIII)I+]Landroid/view/View;Landroid/widget/CheckedTextView;]Landroid/widget/AbsListView$RecycleBin;Landroid/widget/AbsListView$RecycleBin;
-HSPLandroid/widget/ListView;->measureScrapChild(Landroid/view/View;III)V+]Landroid/view/View;Landroid/widget/CheckedTextView;
+HSPLandroid/widget/ListView;->measureHeightOfChildren(IIIII)I
+HSPLandroid/widget/ListView;->measureScrapChild(Landroid/view/View;III)V
 HSPLandroid/widget/ListView;->onDetachedFromWindow()V
 HSPLandroid/widget/ListView;->onFinishInflate()V
 HSPLandroid/widget/ListView;->onMeasure(II)V
@@ -20090,8 +20180,8 @@
 HSPLandroid/widget/ListView;->setCacheColorHint(I)V
 HSPLandroid/widget/ListView;->setDivider(Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/ListView;->setSelection(I)V
-HSPLandroid/widget/ListView;->setupChild(Landroid/view/View;IIZIZZ)V+]Landroid/util/SparseBooleanArray;Landroid/util/SparseBooleanArray;]Landroid/view/View;Landroid/widget/CheckedTextView;,Landroid/widget/LinearLayout;]Landroid/widget/Checkable;Landroid/widget/CheckedTextView;]Landroid/widget/ListAdapter;missing_types]Landroid/widget/ListView;missing_types
-HSPLandroid/widget/OverScroller$SplineOverScroller;-><init>(Landroid/content/Context;)V
+HSPLandroid/widget/ListView;->setupChild(Landroid/view/View;IIZIZZ)V
+HSPLandroid/widget/OverScroller$SplineOverScroller;-><init>(Landroid/content/Context;)V+]Landroid/content/res/Resources;Landroid/content/res/Resources;
 HSPLandroid/widget/OverScroller$SplineOverScroller;->adjustDuration(III)V
 HSPLandroid/widget/OverScroller$SplineOverScroller;->continueWhenFinished()Z
 HSPLandroid/widget/OverScroller$SplineOverScroller;->finish()V
@@ -20103,13 +20193,14 @@
 HSPLandroid/widget/OverScroller$SplineOverScroller;->startScroll(III)V
 HSPLandroid/widget/OverScroller$SplineOverScroller;->startSpringback(III)V
 HSPLandroid/widget/OverScroller$SplineOverScroller;->update()Z
+HSPLandroid/widget/OverScroller$SplineOverScroller;->updateScroll(F)V
 HSPLandroid/widget/OverScroller;-><init>(Landroid/content/Context;)V
 HSPLandroid/widget/OverScroller;-><init>(Landroid/content/Context;Landroid/view/animation/Interpolator;)V
 HSPLandroid/widget/OverScroller;-><init>(Landroid/content/Context;Landroid/view/animation/Interpolator;Z)V
 HSPLandroid/widget/OverScroller;->abortAnimation()V
 HSPLandroid/widget/OverScroller;->computeScrollOffset()Z
 HSPLandroid/widget/OverScroller;->fling(IIIIIIII)V
-HSPLandroid/widget/OverScroller;->fling(IIIIIIIIII)V
+HSPLandroid/widget/OverScroller;->fling(IIIIIIIIII)V+]Landroid/widget/OverScroller;Landroid/widget/OverScroller;]Landroid/widget/OverScroller$SplineOverScroller;Landroid/widget/OverScroller$SplineOverScroller;
 HSPLandroid/widget/OverScroller;->forceFinished(Z)V
 HSPLandroid/widget/OverScroller;->getCurrVelocity()F
 HSPLandroid/widget/OverScroller;->getCurrX()I
@@ -20197,7 +20288,7 @@
 HSPLandroid/widget/ProgressBar;->getProgress()I
 HSPLandroid/widget/ProgressBar;->getProgressDrawable()Landroid/graphics/drawable/Drawable;
 HSPLandroid/widget/ProgressBar;->initProgressBar()V
-HSPLandroid/widget/ProgressBar;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/widget/ProgressBar;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/GradientDrawable;,Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/RippleDrawable;
 HSPLandroid/widget/ProgressBar;->isIndeterminate()Z
 HSPLandroid/widget/ProgressBar;->jumpDrawablesToCurrentState()V
 HSPLandroid/widget/ProgressBar;->needsTileify(Landroid/graphics/drawable/Drawable;)Z
@@ -20237,8 +20328,8 @@
 HSPLandroid/widget/RelativeLayout$DependencyGraph;-><init>()V
 HSPLandroid/widget/RelativeLayout$DependencyGraph;->add(Landroid/view/View;)V
 HSPLandroid/widget/RelativeLayout$DependencyGraph;->clear()V
-HSPLandroid/widget/RelativeLayout$DependencyGraph;->findRoots([I)Ljava/util/ArrayDeque;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/View;Landroid/widget/TextView;]Ljava/util/ArrayDeque;Ljava/util/ArrayDeque;]Ljava/util/ArrayList;Ljava/util/ArrayList;
-HSPLandroid/widget/RelativeLayout$DependencyGraph;->getSortedViews([Landroid/view/View;[I)V+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/View;Landroid/widget/TextView;]Ljava/util/ArrayDeque;Ljava/util/ArrayDeque;
+HSPLandroid/widget/RelativeLayout$DependencyGraph;->findRoots([I)Ljava/util/ArrayDeque;+]Landroid/util/ArrayMap;Landroid/util/ArrayMap;]Ljava/util/ArrayDeque;Ljava/util/ArrayDeque;]Landroid/util/SparseArray;Landroid/util/SparseArray;]Ljava/util/ArrayList;Ljava/util/ArrayList;
+HSPLandroid/widget/RelativeLayout$DependencyGraph;->getSortedViews([Landroid/view/View;[I)V
 HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fgetmBottom(Landroid/widget/RelativeLayout$LayoutParams;)I
 HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fgetmLeft(Landroid/widget/RelativeLayout$LayoutParams;)I
 HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fgetmRight(Landroid/widget/RelativeLayout$LayoutParams;)I
@@ -20246,7 +20337,7 @@
 HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fputmBottom(Landroid/widget/RelativeLayout$LayoutParams;I)V
 HSPLandroid/widget/RelativeLayout$LayoutParams;->-$$Nest$fputmTop(Landroid/widget/RelativeLayout$LayoutParams;I)V
 HSPLandroid/widget/RelativeLayout$LayoutParams;-><init>(II)V
-HSPLandroid/widget/RelativeLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
+HSPLandroid/widget/RelativeLayout$LayoutParams;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V+]Landroid/content/pm/ApplicationInfo;Landroid/content/pm/ApplicationInfo;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;
 HSPLandroid/widget/RelativeLayout$LayoutParams;->addRule(I)V
 HSPLandroid/widget/RelativeLayout$LayoutParams;->addRule(II)V
 HSPLandroid/widget/RelativeLayout$LayoutParams;->getRules()[I
@@ -20273,21 +20364,21 @@
 HSPLandroid/widget/RelativeLayout;->getAccessibilityClassName()Ljava/lang/CharSequence;
 HSPLandroid/widget/RelativeLayout;->getBaseline()I
 HSPLandroid/widget/RelativeLayout;->getChildMeasureSpec(IIIIIIII)I
-HSPLandroid/widget/RelativeLayout;->getRelatedView([II)Landroid/view/View;+]Landroid/util/SparseArray;Landroid/util/SparseArray;]Landroid/view/View;Landroid/widget/TextView;
+HSPLandroid/widget/RelativeLayout;->getRelatedView([II)Landroid/view/View;
 HSPLandroid/widget/RelativeLayout;->getRelatedViewBaselineOffset([I)I
 HSPLandroid/widget/RelativeLayout;->getRelatedViewParams([II)Landroid/widget/RelativeLayout$LayoutParams;
 HSPLandroid/widget/RelativeLayout;->initFromAttributes(Landroid/content/Context;Landroid/util/AttributeSet;II)V
-HSPLandroid/widget/RelativeLayout;->measureChild(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;II)V+]Landroid/view/View;Landroid/widget/TextView;
-HSPLandroid/widget/RelativeLayout;->measureChildHorizontal(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;II)V+]Landroid/view/View;Landroid/widget/TextView;
+HSPLandroid/widget/RelativeLayout;->measureChild(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;II)V
+HSPLandroid/widget/RelativeLayout;->measureChildHorizontal(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;II)V
 HSPLandroid/widget/RelativeLayout;->onLayout(ZIIII)V
-HSPLandroid/widget/RelativeLayout;->onMeasure(II)V+]Landroid/view/View;Landroid/widget/TextView;]Landroid/widget/RelativeLayout$LayoutParams;Landroid/widget/RelativeLayout$LayoutParams;]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;
+HSPLandroid/widget/RelativeLayout;->onMeasure(II)V+]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;]Landroid/view/View;Landroid/widget/TextView;]Landroid/widget/RelativeLayout$LayoutParams;Landroid/widget/RelativeLayout$LayoutParams;
 HSPLandroid/widget/RelativeLayout;->positionAtEdge(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;I)V
-HSPLandroid/widget/RelativeLayout;->positionChildHorizontal(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;IZ)Z+]Landroid/view/View;Landroid/widget/TextView;]Landroid/widget/RelativeLayout$LayoutParams;Landroid/widget/RelativeLayout$LayoutParams;]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;
-HSPLandroid/widget/RelativeLayout;->positionChildVertical(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;IZ)Z+]Landroid/view/View;Landroid/widget/TextView;]Landroid/widget/RelativeLayout$LayoutParams;Landroid/widget/RelativeLayout$LayoutParams;
+HSPLandroid/widget/RelativeLayout;->positionChildHorizontal(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;IZ)Z
+HSPLandroid/widget/RelativeLayout;->positionChildVertical(Landroid/view/View;Landroid/widget/RelativeLayout$LayoutParams;IZ)Z
 HSPLandroid/widget/RelativeLayout;->queryCompatibilityModes(Landroid/content/Context;)V
 HSPLandroid/widget/RelativeLayout;->requestLayout()V
 HSPLandroid/widget/RelativeLayout;->shouldDelayChildPressedState()Z
-HSPLandroid/widget/RelativeLayout;->sortChildren()V+]Landroid/widget/RelativeLayout$DependencyGraph;Landroid/widget/RelativeLayout$DependencyGraph;]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;
+HSPLandroid/widget/RelativeLayout;->sortChildren()V+]Landroid/widget/RelativeLayout;Landroid/widget/RelativeLayout;]Landroid/widget/RelativeLayout$DependencyGraph;Landroid/widget/RelativeLayout$DependencyGraph;
 HSPLandroid/widget/RemoteViews$2;->createFromParcel(Landroid/os/Parcel;)Landroid/widget/RemoteViews;
 HSPLandroid/widget/RemoteViews$2;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLandroid/widget/RemoteViews$Action;-><init>()V
@@ -20363,15 +20454,15 @@
 HSPLandroid/widget/RtlSpacingHelper;->setDirection(Z)V
 HSPLandroid/widget/RtlSpacingHelper;->setRelative(II)V
 HSPLandroid/widget/ScrollBarDrawable;-><init>()V
-HSPLandroid/widget/ScrollBarDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;
-HSPLandroid/widget/ScrollBarDrawable;->drawThumb(Landroid/graphics/Canvas;Landroid/graphics/Rect;IIZ)V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
-HSPLandroid/widget/ScrollBarDrawable;->getSize(Z)I
-HSPLandroid/widget/ScrollBarDrawable;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V
-HSPLandroid/widget/ScrollBarDrawable;->isStateful()Z
-HSPLandroid/widget/ScrollBarDrawable;->mutate()Landroid/widget/ScrollBarDrawable;
+HSPLandroid/widget/ScrollBarDrawable;->draw(Landroid/graphics/Canvas;)V+]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/Rect;Landroid/graphics/Rect;
+HSPLandroid/widget/ScrollBarDrawable;->drawThumb(Landroid/graphics/Canvas;Landroid/graphics/Rect;IIZ)V
+HSPLandroid/widget/ScrollBarDrawable;->getSize(Z)I+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/widget/ScrollBarDrawable;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;
+HSPLandroid/widget/ScrollBarDrawable;->isStateful()Z+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
+HSPLandroid/widget/ScrollBarDrawable;->mutate()Landroid/widget/ScrollBarDrawable;+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
 HSPLandroid/widget/ScrollBarDrawable;->onBoundsChange(Landroid/graphics/Rect;)V
 HSPLandroid/widget/ScrollBarDrawable;->onStateChange([I)Z
-HSPLandroid/widget/ScrollBarDrawable;->propagateCurrentState(Landroid/graphics/drawable/Drawable;)V
+HSPLandroid/widget/ScrollBarDrawable;->propagateCurrentState(Landroid/graphics/drawable/Drawable;)V+]Landroid/widget/ScrollBarDrawable;Landroid/widget/ScrollBarDrawable;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
 HSPLandroid/widget/ScrollBarDrawable;->setAlpha(I)V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/GradientDrawable;
 HSPLandroid/widget/ScrollBarDrawable;->setAlwaysDrawVerticalTrack(Z)V
 HSPLandroid/widget/ScrollBarDrawable;->setHorizontalThumbDrawable(Landroid/graphics/drawable/Drawable;)V
@@ -20486,34 +20577,34 @@
 HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;)V
 HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
-HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/content/Context;missing_types]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/util/TypedValue;Landroid/util/TypedValue;]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V+]Landroid/graphics/Paint;Landroid/graphics/Paint;]Landroid/content/res/Resources$Theme;Landroid/content/res/Resources$Theme;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/view/ViewConfiguration;Landroid/view/ViewConfiguration;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/content/Context;missing_types]Landroid/widget/TextView;missing_types
 HSPLandroid/widget/TextView;->addSearchHighlightPaths()V
 HSPLandroid/widget/TextView;->addTextChangedListener(Landroid/text/TextWatcher;)V
 HSPLandroid/widget/TextView;->applyCompoundDrawableTint()V
 HSPLandroid/widget/TextView;->applySingleLine(ZZZZ)V
-HSPLandroid/widget/TextView;->applyTextAppearance(Landroid/widget/TextView$TextAppearanceAttributes;)V+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->applyTextAppearance(Landroid/widget/TextView$TextAppearanceAttributes;)V
 HSPLandroid/widget/TextView;->assumeLayout()V
 HSPLandroid/widget/TextView;->autoSizeText()V
 HSPLandroid/widget/TextView;->beginBatchEdit()V
 HSPLandroid/widget/TextView;->bringPointIntoView(I)Z
 HSPLandroid/widget/TextView;->bringPointIntoView(IZ)Z
-HSPLandroid/widget/TextView;->bringTextIntoView()Z+]Landroid/text/Layout;Landroid/text/BoringLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->bringTextIntoView()Z
 HSPLandroid/widget/TextView;->canMarquee()Z
 HSPLandroid/widget/TextView;->cancelLongPress()V
-HSPLandroid/widget/TextView;->checkForRelayout()V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->checkForRelayout()V
 HSPLandroid/widget/TextView;->checkForResize()V
 HSPLandroid/widget/TextView;->cleanupAutoSizePresetSizes([I)[I
-HSPLandroid/widget/TextView;->compressText(F)Z+]Landroid/text/Layout;Landroid/text/BoringLayout;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/widget/TextView;Landroid/widget/CheckedTextView;,Landroid/widget/TextView;
+HSPLandroid/widget/TextView;->compressText(F)Z
 HSPLandroid/widget/TextView;->computeHorizontalScrollRange()I
 HSPLandroid/widget/TextView;->computeScroll()V
-HSPLandroid/widget/TextView;->computeVerticalScrollExtent()I
-HSPLandroid/widget/TextView;->computeVerticalScrollRange()I
+HSPLandroid/widget/TextView;->computeVerticalScrollExtent()I+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->computeVerticalScrollRange()I+]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;
 HSPLandroid/widget/TextView;->convertToLocalHorizontalCoordinate(F)F
 HSPLandroid/widget/TextView;->createEditorIfNeeded()V
 HSPLandroid/widget/TextView;->didTouchFocusSelect()Z
 HSPLandroid/widget/TextView;->doKeyDown(ILandroid/view/KeyEvent;Landroid/view/KeyEvent;)I
 HSPLandroid/widget/TextView;->drawableHotspotChanged(FF)V
-HSPLandroid/widget/TextView;->drawableStateChanged()V+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->drawableStateChanged()V
 HSPLandroid/widget/TextView;->endBatchEdit()V
 HSPLandroid/widget/TextView;->findLargestTextSizeWhichFits(Landroid/graphics/RectF;)I
 HSPLandroid/widget/TextView;->fixFocusableAndClickableSettings()V
@@ -20522,10 +20613,10 @@
 HSPLandroid/widget/TextView;->getAutofillHints()[Ljava/lang/String;
 HSPLandroid/widget/TextView;->getAutofillType()I
 HSPLandroid/widget/TextView;->getAutofillValue()Landroid/view/autofill/AutofillValue;
-HSPLandroid/widget/TextView;->getBaseline()I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
-HSPLandroid/widget/TextView;->getBaselineOffset()I+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getBaseline()I
+HSPLandroid/widget/TextView;->getBaselineOffset()I
 HSPLandroid/widget/TextView;->getBottomVerticalOffset(Z)I
-HSPLandroid/widget/TextView;->getBoxHeight(Landroid/text/Layout;)I+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getBoxHeight(Landroid/text/Layout;)I+]Landroid/widget/TextView;Landroid/widget/EditText;,Landroid/widget/Button;
 HSPLandroid/widget/TextView;->getBreakStrategy()I
 HSPLandroid/widget/TextView;->getCompoundDrawablePadding()I
 HSPLandroid/widget/TextView;->getCompoundDrawables()[Landroid/graphics/drawable/Drawable;
@@ -20538,12 +20629,12 @@
 HSPLandroid/widget/TextView;->getDefaultEditable()Z
 HSPLandroid/widget/TextView;->getDefaultMovementMethod()Landroid/text/method/MovementMethod;
 HSPLandroid/widget/TextView;->getDesiredHeight()I
-HSPLandroid/widget/TextView;->getDesiredHeight(Landroid/text/Layout;Z)I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getDesiredHeight(Landroid/text/Layout;Z)I+]Landroid/text/Layout;Landroid/text/BoringLayout;]Landroid/widget/TextView;Landroid/widget/TextView;
 HSPLandroid/widget/TextView;->getEditableText()Landroid/text/Editable;
 HSPLandroid/widget/TextView;->getEllipsize()Landroid/text/TextUtils$TruncateAt;
 HSPLandroid/widget/TextView;->getError()Ljava/lang/CharSequence;
-HSPLandroid/widget/TextView;->getExtendedPaddingBottom()I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
-HSPLandroid/widget/TextView;->getExtendedPaddingTop()I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getExtendedPaddingBottom()I+]Landroid/text/Layout;Landroid/text/StaticLayout;]Landroid/widget/TextView;Landroid/widget/TextView;
+HSPLandroid/widget/TextView;->getExtendedPaddingTop()I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;,Landroid/text/DynamicLayout;]Landroid/widget/TextView;Landroid/widget/TextView;,Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/Button;
 HSPLandroid/widget/TextView;->getFilters()[Landroid/text/InputFilter;
 HSPLandroid/widget/TextView;->getFocusedRect(Landroid/graphics/Rect;)V
 HSPLandroid/widget/TextView;->getFreezesText()Z
@@ -20559,7 +20650,7 @@
 HSPLandroid/widget/TextView;->getJustificationMode()I
 HSPLandroid/widget/TextView;->getKeyListener()Landroid/text/method/KeyListener;
 HSPLandroid/widget/TextView;->getLayout()Landroid/text/Layout;
-HSPLandroid/widget/TextView;->getLayoutAlignment()Landroid/text/Layout$Alignment;+]Landroid/widget/TextView;Landroid/widget/TextView;
+HSPLandroid/widget/TextView;->getLayoutAlignment()Landroid/text/Layout$Alignment;
 HSPLandroid/widget/TextView;->getLineAtCoordinate(F)I
 HSPLandroid/widget/TextView;->getLineAtCoordinateUnclamped(F)I
 HSPLandroid/widget/TextView;->getLineCount()I
@@ -20575,14 +20666,14 @@
 HSPLandroid/widget/TextView;->getPaint()Landroid/text/TextPaint;
 HSPLandroid/widget/TextView;->getSelectionEnd()I
 HSPLandroid/widget/TextView;->getSelectionEndTransformed()I
-HSPLandroid/widget/TextView;->getSelectionStart()I
+HSPLandroid/widget/TextView;->getSelectionStart()I+]Landroid/widget/TextView;missing_types
 HSPLandroid/widget/TextView;->getSelectionStartTransformed()I
 HSPLandroid/widget/TextView;->getServiceManagerForUser(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
 HSPLandroid/widget/TextView;->getSpellCheckerLocale()Ljava/util/Locale;
 HSPLandroid/widget/TextView;->getText()Ljava/lang/CharSequence;
 HSPLandroid/widget/TextView;->getTextColors()Landroid/content/res/ColorStateList;
 HSPLandroid/widget/TextView;->getTextCursorDrawable()Landroid/graphics/drawable/Drawable;
-HSPLandroid/widget/TextView;->getTextDirectionHeuristic()Landroid/text/TextDirectionHeuristic;+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->getTextDirectionHeuristic()Landroid/text/TextDirectionHeuristic;
 HSPLandroid/widget/TextView;->getTextLocale()Ljava/util/Locale;
 HSPLandroid/widget/TextView;->getTextLocales()Landroid/os/LocaleList;
 HSPLandroid/widget/TextView;->getTextSelectHandle()Landroid/graphics/drawable/Drawable;
@@ -20596,53 +20687,53 @@
 HSPLandroid/widget/TextView;->getTransformationMethod()Landroid/text/method/TransformationMethod;
 HSPLandroid/widget/TextView;->getTypeface()Landroid/graphics/Typeface;
 HSPLandroid/widget/TextView;->getTypefaceStyle()I
-HSPLandroid/widget/TextView;->getUpdatedHighlightPath()Landroid/graphics/Path;+]Landroid/widget/TextView;missing_types
-HSPLandroid/widget/TextView;->getVerticalOffset(Z)I+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLandroid/widget/TextView;->getUpdatedHighlightPath()Landroid/graphics/Path;
+HSPLandroid/widget/TextView;->getVerticalOffset(Z)I
 HSPLandroid/widget/TextView;->handleBackInTextActionModeIfNeeded(Landroid/view/KeyEvent;)Z
 HSPLandroid/widget/TextView;->handleTextChanged(Ljava/lang/CharSequence;III)V
 HSPLandroid/widget/TextView;->hasGesturePreviewHighlight()Z
-HSPLandroid/widget/TextView;->hasOverlappingRendering()Z+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/RippleDrawable;
+HSPLandroid/widget/TextView;->hasOverlappingRendering()Z
 HSPLandroid/widget/TextView;->hasPasswordTransformationMethod()Z
 HSPLandroid/widget/TextView;->hasSelection()Z
 HSPLandroid/widget/TextView;->hideErrorIfUnchanged()V
 HSPLandroid/widget/TextView;->invalidateCursor()V
 HSPLandroid/widget/TextView;->invalidateCursorPath()V
-HSPLandroid/widget/TextView;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/ColorDrawable;,Landroid/graphics/drawable/GradientDrawable;,Landroid/graphics/drawable/RippleDrawable;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->invalidateDrawable(Landroid/graphics/drawable/Drawable;)V+]Landroid/widget/TextView;Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/Button;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/AnimatedStateListDrawable;,Landroid/graphics/drawable/InsetDrawable;,Landroid/graphics/drawable/RippleDrawable;,Landroid/graphics/drawable/LayerDrawable;,Landroid/graphics/drawable/VectorDrawable;
 HSPLandroid/widget/TextView;->invalidateRegion(IIZ)V
 HSPLandroid/widget/TextView;->isAnyPasswordInputType()Z
 HSPLandroid/widget/TextView;->isAutoSizeEnabled()Z
 HSPLandroid/widget/TextView;->isAutofillable()Z
 HSPLandroid/widget/TextView;->isFallbackLineSpacingForStaticLayout()Z
-HSPLandroid/widget/TextView;->isFromPrimePointer(Landroid/view/MotionEvent;Z)Z
+HSPLandroid/widget/TextView;->isFromPrimePointer(Landroid/view/MotionEvent;Z)Z+]Landroid/view/MotionEvent;Landroid/view/MotionEvent;
 HSPLandroid/widget/TextView;->isInBatchEditMode()Z
 HSPLandroid/widget/TextView;->isInExtractedMode()Z
 HSPLandroid/widget/TextView;->isInputMethodTarget()Z
 HSPLandroid/widget/TextView;->isMarqueeFadeEnabled()Z
 HSPLandroid/widget/TextView;->isMultilineInputType(I)Z
 HSPLandroid/widget/TextView;->isPasswordInputType(I)Z
-HSPLandroid/widget/TextView;->isPositionVisible(FF)Z
+HSPLandroid/widget/TextView;->isPositionVisible(FF)Z+]Landroid/view/View;missing_types]Landroid/graphics/Matrix;Landroid/graphics/Matrix;
 HSPLandroid/widget/TextView;->isShowingHint()Z
 HSPLandroid/widget/TextView;->isSuggestionsEnabled()Z
 HSPLandroid/widget/TextView;->isTextAutofillable()Z
 HSPLandroid/widget/TextView;->isTextEditable()Z
 HSPLandroid/widget/TextView;->isTextSelectable()Z
 HSPLandroid/widget/TextView;->isVisibleToAccessibility()Z
-HSPLandroid/widget/TextView;->jumpDrawablesToCurrentState()V+]Landroid/graphics/drawable/Drawable;missing_types
+HSPLandroid/widget/TextView;->jumpDrawablesToCurrentState()V
 HSPLandroid/widget/TextView;->length()I
-HSPLandroid/widget/TextView;->makeNewLayout(IILandroid/text/BoringLayout$Metrics;Landroid/text/BoringLayout$Metrics;IZ)V+]Landroid/text/Layout;Landroid/text/BoringLayout;]Landroid/widget/TextView;missing_types
-HSPLandroid/widget/TextView;->makeSingleLayout(ILandroid/text/BoringLayout$Metrics;ILandroid/text/Layout$Alignment;ZLandroid/text/TextUtils$TruncateAt;Z)Landroid/text/Layout;+]Landroid/text/BoringLayout;Landroid/text/BoringLayout;]Landroid/text/StaticLayout$Builder;Landroid/text/StaticLayout$Builder;]Landroid/widget/TextView;missing_types]Ljava/lang/CharSequence;Ljava/lang/String;
-HSPLandroid/widget/TextView;->maybeUpdateHighlightPaths()V+]Landroid/widget/TextView;missing_types]Ljava/util/List;Ljava/util/ArrayList;
+HSPLandroid/widget/TextView;->makeNewLayout(IILandroid/text/BoringLayout$Metrics;Landroid/text/BoringLayout$Metrics;IZ)V+]Landroid/text/BoringLayout;Landroid/text/BoringLayout;]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/TextView;Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/TextView;,Landroid/widget/Button;
+HSPLandroid/widget/TextView;->makeSingleLayout(ILandroid/text/BoringLayout$Metrics;ILandroid/text/Layout$Alignment;ZLandroid/text/TextUtils$TruncateAt;Z)Landroid/text/Layout;+]Landroid/text/DynamicLayout$Builder;Landroid/text/DynamicLayout$Builder;]Landroid/text/BoringLayout;Landroid/text/BoringLayout;]Landroid/widget/TextView;Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/TextView;]Ljava/lang/CharSequence;Ljava/lang/String;]Landroid/text/StaticLayout$Builder;Landroid/text/StaticLayout$Builder;
+HSPLandroid/widget/TextView;->maybeUpdateHighlightPaths()V
 HSPLandroid/widget/TextView;->notifyContentCaptureTextChanged()V
-HSPLandroid/widget/TextView;->notifyListeningManagersAfterTextChanged()V+]Landroid/view/autofill/AutofillManager;Landroid/view/autofill/AutofillManager;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->notifyListeningManagersAfterTextChanged()V
 HSPLandroid/widget/TextView;->nullLayouts()V
 HSPLandroid/widget/TextView;->onAttachedToWindow()V
 HSPLandroid/widget/TextView;->onBeginBatchEdit()V
 HSPLandroid/widget/TextView;->onCheckIsTextEditor()Z
 HSPLandroid/widget/TextView;->onConfigurationChanged(Landroid/content/res/Configuration;)V
-HSPLandroid/widget/TextView;->onCreateDrawableState(I)[I+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->onCreateDrawableState(I)[I
 HSPLandroid/widget/TextView;->onCreateInputConnection(Landroid/view/inputmethod/EditorInfo;)Landroid/view/inputmethod/InputConnection;
 HSPLandroid/widget/TextView;->onDetachedFromWindowInternal()V
-HSPLandroid/widget/TextView;->onDraw(Landroid/graphics/Canvas;)V+]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/graphics/drawable/Drawable;missing_types]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->onDraw(Landroid/graphics/Canvas;)V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/StaticLayout;,Landroid/text/DynamicLayout;]Landroid/widget/TextView;missing_types]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/graphics/Canvas;Landroid/graphics/RecordingCanvas;]Landroid/widget/Editor;Landroid/widget/Editor;]Ljava/lang/CharSequence;Landroid/text/SpannableStringBuilder;
 HSPLandroid/widget/TextView;->onEditorAction(I)V
 HSPLandroid/widget/TextView;->onEndBatchEdit()V
 HSPLandroid/widget/TextView;->onFocusChanged(ZILandroid/graphics/Rect;)V
@@ -20653,7 +20744,7 @@
 HSPLandroid/widget/TextView;->onKeyUp(ILandroid/view/KeyEvent;)Z
 HSPLandroid/widget/TextView;->onLayout(ZIIII)V
 HSPLandroid/widget/TextView;->onLocaleChanged()V
-HSPLandroid/widget/TextView;->onMeasure(II)V+]Landroid/text/Layout;Landroid/text/BoringLayout;,Landroid/text/DynamicLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->onMeasure(II)V+]Landroid/text/Layout;Landroid/text/DynamicLayout;,Landroid/text/BoringLayout;,Landroid/text/StaticLayout;]Landroid/widget/TextView;Landroid/widget/CheckBox;,Landroid/widget/EditText;,Landroid/widget/TextView;,Landroid/widget/Button;
 HSPLandroid/widget/TextView;->onPreDraw()Z
 HSPLandroid/widget/TextView;->onProvideStructure(Landroid/view/ViewStructure;II)V
 HSPLandroid/widget/TextView;->onResolveDrawables(I)V
@@ -20670,7 +20761,7 @@
 HSPLandroid/widget/TextView;->onWindowFocusChanged(Z)V
 HSPLandroid/widget/TextView;->originalToTransformed(II)I
 HSPLandroid/widget/TextView;->preloadFontCache()V
-HSPLandroid/widget/TextView;->readTextAppearance(Landroid/content/Context;Landroid/content/res/TypedArray;Landroid/widget/TextView$TextAppearanceAttributes;Z)V+]Landroid/content/Context;missing_types]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Landroid/util/TypedValue;Landroid/util/TypedValue;
+HSPLandroid/widget/TextView;->readTextAppearance(Landroid/content/Context;Landroid/content/res/TypedArray;Landroid/widget/TextView$TextAppearanceAttributes;Z)V+]Landroid/util/SparseIntArray;Landroid/util/SparseIntArray;]Landroid/util/TypedValue;Landroid/util/TypedValue;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Landroid/content/Context;missing_types
 HSPLandroid/widget/TextView;->registerForPreDraw()V
 HSPLandroid/widget/TextView;->removeAdjacentSuggestionSpans(I)V
 HSPLandroid/widget/TextView;->removeIntersectingNonAdjacentSpans(IILjava/lang/Class;)V
@@ -20690,7 +20781,7 @@
 HSPLandroid/widget/TextView;->setBreakStrategy(I)V
 HSPLandroid/widget/TextView;->setCompoundDrawablePadding(I)V
 HSPLandroid/widget/TextView;->setCompoundDrawableTintList(Landroid/content/res/ColorStateList;)V
-HSPLandroid/widget/TextView;->setCompoundDrawables(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V+]Landroid/graphics/Rect;Landroid/graphics/Rect;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->setCompoundDrawables(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/TextView;->setCompoundDrawablesRelative(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/TextView;->setCompoundDrawablesRelativeWithIntrinsicBounds(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/TextView;->setCompoundDrawablesWithIntrinsicBounds(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
@@ -20720,7 +20811,7 @@
 HSPLandroid/widget/TextView;->setInputTypeSingleLine(Z)V
 HSPLandroid/widget/TextView;->setKeyListener(Landroid/text/method/KeyListener;)V
 HSPLandroid/widget/TextView;->setKeyListenerOnly(Landroid/text/method/KeyListener;)V
-HSPLandroid/widget/TextView;->setLetterSpacing(F)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
+HSPLandroid/widget/TextView;->setLetterSpacing(F)V
 HSPLandroid/widget/TextView;->setLineHeight(I)V
 HSPLandroid/widget/TextView;->setLineSpacing(FF)V
 HSPLandroid/widget/TextView;->setLines(I)V
@@ -20737,7 +20828,7 @@
 HSPLandroid/widget/TextView;->setPaddingRelative(IIII)V
 HSPLandroid/widget/TextView;->setPrivateImeOptions(Ljava/lang/String;)V
 HSPLandroid/widget/TextView;->setRawInputType(I)V
-HSPLandroid/widget/TextView;->setRawTextSize(FZ)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
+HSPLandroid/widget/TextView;->setRawTextSize(FZ)V
 HSPLandroid/widget/TextView;->setRelativeDrawablesIfNeeded(Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/Drawable;)V
 HSPLandroid/widget/TextView;->setSelected(Z)V
 HSPLandroid/widget/TextView;->setShadowLayer(FFFI)V
@@ -20746,7 +20837,7 @@
 HSPLandroid/widget/TextView;->setText(I)V
 HSPLandroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
 HSPLandroid/widget/TextView;->setText(Ljava/lang/CharSequence;Landroid/widget/TextView$BufferType;)V
-HSPLandroid/widget/TextView;->setText(Ljava/lang/CharSequence;Landroid/widget/TextView$BufferType;ZI)V+]Landroid/text/Editable$Factory;Landroid/text/Editable$Factory;]Landroid/text/InputFilter;Landroid/text/InputFilter$LengthFilter;]Landroid/text/Spannable$Factory;Landroid/text/Spannable$Factory;]Landroid/text/Spannable;Landroid/text/SpannableString;,Landroid/text/SpannableStringBuilder;]Landroid/text/Spanned;Landroid/text/SpannableStringBuilder;,Landroid/text/SpannedString;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/text/method/MovementMethod;Landroid/text/method/ArrowKeyMovementMethod;,Landroid/text/method/LinkMovementMethod;]Landroid/text/method/TransformationMethod;Landroid/text/method/AllCapsTransformationMethod;,Landroid/text/method/SingleLineTransformationMethod;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/TextView;missing_types]Ljava/lang/CharSequence;Landroid/text/SpannableString;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannedString;,Ljava/lang/String;
+HSPLandroid/widget/TextView;->setText(Ljava/lang/CharSequence;Landroid/widget/TextView$BufferType;ZI)V+]Landroid/text/Editable$Factory;Landroid/text/Editable$Factory;]Landroid/text/method/MovementMethod;Landroid/text/method/ArrowKeyMovementMethod;,Landroid/text/method/ScrollingMovementMethod;]Landroid/text/method/TransformationMethod;Landroid/text/method/SingleLineTransformationMethod;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/text/InputFilter;Landroid/text/InputFilter$LengthFilter;]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/text/Spanned;Landroid/text/SpannableString;]Landroid/text/Spannable$Factory;Landroid/text/Spannable$Factory;]Ljava/lang/CharSequence;Ljava/lang/String;,Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;]Landroid/view/accessibility/AccessibilityManager;Landroid/view/accessibility/AccessibilityManager;]Landroid/text/Spannable;Landroid/text/SpannableStringBuilder;,Landroid/text/SpannableString;
 HSPLandroid/widget/TextView;->setTextAppearance(I)V
 HSPLandroid/widget/TextView;->setTextAppearance(Landroid/content/Context;I)V
 HSPLandroid/widget/TextView;->setTextColor(I)V
@@ -20758,14 +20849,14 @@
 HSPLandroid/widget/TextView;->setTextSizeInternal(IFZ)V
 HSPLandroid/widget/TextView;->setTransformationMethod(Landroid/text/method/TransformationMethod;)V
 HSPLandroid/widget/TextView;->setTransformationMethodInternal(Landroid/text/method/TransformationMethod;Z)V
-HSPLandroid/widget/TextView;->setTypeface(Landroid/graphics/Typeface;)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;
-HSPLandroid/widget/TextView;->setTypeface(Landroid/graphics/Typeface;I)V+]Landroid/text/TextPaint;Landroid/text/TextPaint;]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->setTypeface(Landroid/graphics/Typeface;)V
+HSPLandroid/widget/TextView;->setTypeface(Landroid/graphics/Typeface;I)V
 HSPLandroid/widget/TextView;->setTypefaceFromAttrs(Landroid/graphics/Typeface;Ljava/lang/String;III)V
 HSPLandroid/widget/TextView;->setupAutoSizeText()Z
 HSPLandroid/widget/TextView;->setupAutoSizeUniformPresetSizesConfiguration()Z
 HSPLandroid/widget/TextView;->shouldAdvanceFocusOnEnter()Z
 HSPLandroid/widget/TextView;->spanChange(Landroid/text/Spanned;Ljava/lang/Object;IIII)V
-HSPLandroid/widget/TextView;->startMarquee()V+]Landroid/widget/TextView;Landroid/widget/CheckedTextView;,Landroid/widget/TextView;
+HSPLandroid/widget/TextView;->startMarquee()V
 HSPLandroid/widget/TextView;->startStopMarquee(Z)V
 HSPLandroid/widget/TextView;->stopMarquee()V
 HSPLandroid/widget/TextView;->stopTextActionMode()V
@@ -20775,8 +20866,8 @@
 HSPLandroid/widget/TextView;->unregisterForPreDraw()V
 HSPLandroid/widget/TextView;->updateAfterEdit()V
 HSPLandroid/widget/TextView;->updateCursorVisibleInternal()V
-HSPLandroid/widget/TextView;->updateTextColors()V+]Landroid/content/res/ColorStateList;Landroid/content/res/ColorStateList;]Landroid/widget/Editor;Landroid/widget/Editor;]Landroid/widget/TextView;missing_types]Ljava/lang/CharSequence;Ljava/lang/String;
-HSPLandroid/widget/TextView;->useDynamicLayout()Z+]Landroid/widget/TextView;missing_types
+HSPLandroid/widget/TextView;->updateTextColors()V
+HSPLandroid/widget/TextView;->useDynamicLayout()Z
 HSPLandroid/widget/TextView;->validateAndSetAutoSizeTextTypeUniformConfiguration(FFF)V
 HSPLandroid/widget/TextView;->verifyDrawable(Landroid/graphics/drawable/Drawable;)Z
 HSPLandroid/widget/TextView;->viewClicked(Landroid/view/inputmethod/InputMethodManager;)V
@@ -20837,6 +20928,7 @@
 HSPLandroid/widget/inline/InlinePresentationSpec;-><clinit>()V
 HSPLandroid/widget/inline/InlinePresentationSpec;-><init>(Landroid/os/Parcel;)V
 HSPLandroid/widget/inline/InlinePresentationSpec;->writeToParcel(Landroid/os/Parcel;I)V
+HSPLandroid/window/BackProgressAnimator;-><init>()V+]Lcom/android/internal/dynamicanimation/animation/SpringAnimation;Lcom/android/internal/dynamicanimation/animation/SpringAnimation;]Lcom/android/internal/dynamicanimation/animation/SpringForce;Lcom/android/internal/dynamicanimation/animation/SpringForce;
 HSPLandroid/window/ClientWindowFrames$1;-><init>()V
 HSPLandroid/window/ClientWindowFrames$1;->createFromParcel(Landroid/os/Parcel;)Landroid/window/ClientWindowFrames;
 HSPLandroid/window/ClientWindowFrames$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
@@ -20954,6 +21046,8 @@
 HSPLandroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper;->onBackCancelled()V
 HSPLandroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper;->onBackInvoked()V
 HSPLandroid/window/WindowOnBackInvokedDispatcher;-><clinit>()V
+HSPLandroid/window/WindowOnBackInvokedDispatcher;-><init>(Landroid/content/Context;)V
+HSPLandroid/window/WindowOnBackInvokedDispatcher;->attachToWindow(Landroid/view/IWindowSession;Landroid/view/IWindow;)V
 HSPLandroid/window/WindowOnBackInvokedDispatcher;->clear()V
 HSPLandroid/window/WindowOnBackInvokedDispatcher;->detachFromWindow()V
 HSPLandroid/window/WindowOnBackInvokedDispatcher;->getTopCallback()Landroid/window/OnBackInvokedCallback;
@@ -20989,12 +21083,12 @@
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getMetadataForRegionOrCallingCode(ILjava/lang/String;)Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNationalSignificantNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Ljava/lang/String;
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNumberDescByType(Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;)Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;
-HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNumberTypeHelper(Ljava/lang/String;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;)Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
+HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNumberTypeHelper(Ljava/lang/String;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;)Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;+]Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;]Lcom/android/i18n/phonenumbers/PhoneNumberUtil;Lcom/android/i18n/phonenumbers/PhoneNumberUtil;
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForCountryCode(I)Ljava/lang/String;
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Ljava/lang/String;
-HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForNumberFromRegionList(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;Ljava/util/List;)Ljava/lang/String;
+HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForNumberFromRegionList(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;Ljava/util/List;)Ljava/lang/String;+]Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;]Ljava/util/List;Ljava/util/ArrayList;]Lcom/android/i18n/phonenumbers/PhoneNumberUtil;Lcom/android/i18n/phonenumbers/PhoneNumberUtil;]Ljava/util/Iterator;Ljava/util/ArrayList$Itr;
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->hasFormattingPatternForNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Z
-HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isNumberMatchingDesc(Ljava/lang/String;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;)Z
+HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isNumberMatchingDesc(Ljava/lang/String;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;)Z+]Ljava/lang/String;Ljava/lang/String;]Lcom/android/i18n/phonenumbers/internal/MatcherApi;Lcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;]Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;]Ljava/util/List;Ljava/util/ArrayList;
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isValidNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Z
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isValidNumberForRegion(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;Ljava/lang/String;)Z
 HSPLcom/android/i18n/phonenumbers/PhoneNumberUtil;->isValidRegionCode(Ljava/lang/String;)Z
@@ -21099,8 +21193,8 @@
 HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->setCountryCodeSource(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource;)Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;
 HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->setNationalNumber(J)Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;
 HSPLcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->setRawInput(Ljava/lang/String;)Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;
-HSPLcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;->match(Ljava/lang/CharSequence;Ljava/util/regex/Pattern;Z)Z
-HSPLcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;->matchNationalNumber(Ljava/lang/CharSequence;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;Z)Z
+HSPLcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;->match(Ljava/lang/CharSequence;Ljava/util/regex/Pattern;Z)Z+]Ljava/util/regex/Matcher;Ljava/util/regex/Matcher;]Ljava/util/regex/Pattern;Ljava/util/regex/Pattern;
+HSPLcom/android/i18n/phonenumbers/internal/RegexBasedMatcher;->matchNationalNumber(Ljava/lang/CharSequence;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;Z)Z+]Ljava/lang/String;Ljava/lang/String;]Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;]Lcom/android/i18n/phonenumbers/internal/RegexCache;Lcom/android/i18n/phonenumbers/internal/RegexCache;
 HSPLcom/android/i18n/phonenumbers/internal/RegexCache$LRUCache$1;->removeEldestEntry(Ljava/util/Map$Entry;)Z
 HSPLcom/android/i18n/phonenumbers/internal/RegexCache$LRUCache;->get(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLcom/android/i18n/phonenumbers/internal/RegexCache$LRUCache;->put(Ljava/lang/Object;Ljava/lang/Object;)V
@@ -21178,10 +21272,10 @@
 HSPLcom/android/i18n/timezone/internal/NioBufferIterator;->readLongArray([JII)V
 HSPLcom/android/i18n/timezone/internal/NioBufferIterator;->skip(I)V
 HSPLcom/android/icu/charset/CharsetDecoderICU;-><init>(Ljava/nio/charset/Charset;FJ)V
-HSPLcom/android/icu/charset/CharsetDecoderICU;->decodeLoop(Ljava/nio/ByteBuffer;Ljava/nio/CharBuffer;)Ljava/nio/charset/CoderResult;
-HSPLcom/android/icu/charset/CharsetDecoderICU;->getArray(Ljava/nio/ByteBuffer;)I
-HSPLcom/android/icu/charset/CharsetDecoderICU;->getArray(Ljava/nio/CharBuffer;)I
-HSPLcom/android/icu/charset/CharsetDecoderICU;->implFlush(Ljava/nio/CharBuffer;)Ljava/nio/charset/CoderResult;
+HSPLcom/android/icu/charset/CharsetDecoderICU;->decodeLoop(Ljava/nio/ByteBuffer;Ljava/nio/CharBuffer;)Ljava/nio/charset/CoderResult;+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
+HSPLcom/android/icu/charset/CharsetDecoderICU;->getArray(Ljava/nio/ByteBuffer;)I+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
+HSPLcom/android/icu/charset/CharsetDecoderICU;->getArray(Ljava/nio/CharBuffer;)I+]Ljava/nio/CharBuffer;Ljava/nio/HeapCharBuffer;
+HSPLcom/android/icu/charset/CharsetDecoderICU;->implFlush(Ljava/nio/CharBuffer;)Ljava/nio/charset/CoderResult;+]Lcom/android/icu/charset/CharsetDecoderICU;Lcom/android/icu/charset/CharsetDecoderICU;
 HSPLcom/android/icu/charset/CharsetDecoderICU;->implOnMalformedInput(Ljava/nio/charset/CodingErrorAction;)V
 HSPLcom/android/icu/charset/CharsetDecoderICU;->implOnUnmappableCharacter(Ljava/nio/charset/CodingErrorAction;)V
 HSPLcom/android/icu/charset/CharsetDecoderICU;->implReplaceWith(Ljava/lang/String;)V
@@ -21191,16 +21285,16 @@
 HSPLcom/android/icu/charset/CharsetDecoderICU;->setPosition(Ljava/nio/CharBuffer;)V
 HSPLcom/android/icu/charset/CharsetDecoderICU;->updateCallback()V
 HSPLcom/android/icu/charset/CharsetEncoderICU;-><init>(Ljava/nio/charset/Charset;FF[BJ)V
-HSPLcom/android/icu/charset/CharsetEncoderICU;->encodeLoop(Ljava/nio/CharBuffer;Ljava/nio/ByteBuffer;)Ljava/nio/charset/CoderResult;
-HSPLcom/android/icu/charset/CharsetEncoderICU;->getArray(Ljava/nio/ByteBuffer;)I
-HSPLcom/android/icu/charset/CharsetEncoderICU;->getArray(Ljava/nio/CharBuffer;)I
+HSPLcom/android/icu/charset/CharsetEncoderICU;->encodeLoop(Ljava/nio/CharBuffer;Ljava/nio/ByteBuffer;)Ljava/nio/charset/CoderResult;+]Ljava/nio/CharBuffer;Ljava/nio/HeapCharBuffer;
+HSPLcom/android/icu/charset/CharsetEncoderICU;->getArray(Ljava/nio/ByteBuffer;)I+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
+HSPLcom/android/icu/charset/CharsetEncoderICU;->getArray(Ljava/nio/CharBuffer;)I+]Ljava/nio/CharBuffer;Ljava/nio/HeapCharBuffer;
 HSPLcom/android/icu/charset/CharsetEncoderICU;->implFlush(Ljava/nio/ByteBuffer;)Ljava/nio/charset/CoderResult;
 HSPLcom/android/icu/charset/CharsetEncoderICU;->implOnMalformedInput(Ljava/nio/charset/CodingErrorAction;)V
 HSPLcom/android/icu/charset/CharsetEncoderICU;->implOnUnmappableCharacter(Ljava/nio/charset/CodingErrorAction;)V
 HSPLcom/android/icu/charset/CharsetEncoderICU;->implReset()V
 HSPLcom/android/icu/charset/CharsetEncoderICU;->makeReplacement(Ljava/lang/String;J)[B
 HSPLcom/android/icu/charset/CharsetEncoderICU;->newInstance(Ljava/nio/charset/Charset;Ljava/lang/String;)Lcom/android/icu/charset/CharsetEncoderICU;
-HSPLcom/android/icu/charset/CharsetEncoderICU;->setPosition(Ljava/nio/ByteBuffer;)V
+HSPLcom/android/icu/charset/CharsetEncoderICU;->setPosition(Ljava/nio/ByteBuffer;)V+]Ljava/nio/ByteBuffer;Ljava/nio/HeapByteBuffer;
 HSPLcom/android/icu/charset/CharsetEncoderICU;->setPosition(Ljava/nio/CharBuffer;)V
 HSPLcom/android/icu/charset/CharsetEncoderICU;->updateCallback()V
 HSPLcom/android/icu/charset/CharsetFactory;->create(Ljava/lang/String;)Ljava/nio/charset/Charset;
@@ -21240,7 +21334,7 @@
 HSPLcom/android/icu/util/LocaleNative;->getDisplayCountry(Ljava/util/Locale;Ljava/util/Locale;)Ljava/lang/String;
 HSPLcom/android/icu/util/LocaleNative;->getDisplayLanguage(Ljava/util/Locale;Ljava/util/Locale;)Ljava/lang/String;
 HSPLcom/android/icu/util/LocaleNative;->setDefault(Ljava/lang/String;)V
-HSPLcom/android/icu/util/regex/MatcherNative;-><init>(Lcom/android/icu/util/regex/PatternNative;)V
+HSPLcom/android/icu/util/regex/MatcherNative;-><init>(Lcom/android/icu/util/regex/PatternNative;)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;]Lcom/android/icu/util/regex/PatternNative;Lcom/android/icu/util/regex/PatternNative;
 HSPLcom/android/icu/util/regex/MatcherNative;->create(Lcom/android/icu/util/regex/PatternNative;)Lcom/android/icu/util/regex/MatcherNative;
 HSPLcom/android/icu/util/regex/MatcherNative;->find(I[I)Z
 HSPLcom/android/icu/util/regex/MatcherNative;->findNext([I)Z
@@ -21252,7 +21346,7 @@
 HSPLcom/android/icu/util/regex/MatcherNative;->setInput(Ljava/lang/String;II)V
 HSPLcom/android/icu/util/regex/MatcherNative;->useAnchoringBounds(Z)V
 HSPLcom/android/icu/util/regex/MatcherNative;->useTransparentBounds(Z)V
-HSPLcom/android/icu/util/regex/PatternNative;-><init>(Ljava/lang/String;I)V
+HSPLcom/android/icu/util/regex/PatternNative;-><init>(Ljava/lang/String;I)V+]Llibcore/util/NativeAllocationRegistry;Llibcore/util/NativeAllocationRegistry;
 HSPLcom/android/icu/util/regex/PatternNative;->create(Ljava/lang/String;I)Lcom/android/icu/util/regex/PatternNative;
 HSPLcom/android/icu/util/regex/PatternNative;->openMatcher()J
 HSPLcom/android/internal/app/AlertController;-><init>(Landroid/content/Context;Landroid/content/DialogInterface;Landroid/view/Window;)V
@@ -21336,6 +21430,8 @@
 HSPLcom/android/internal/content/ReferrerIntent$1;->createFromParcel(Landroid/os/Parcel;)Ljava/lang/Object;
 HSPLcom/android/internal/display/BrightnessSynchronizer;-><clinit>()V
 HSPLcom/android/internal/display/BrightnessSynchronizer;->floatEquals(FF)Z
+HSPLcom/android/internal/dynamicanimation/animation/DynamicAnimation;-><init>(Ljava/lang/Object;Landroid/util/FloatProperty;)V
+HSPLcom/android/internal/dynamicanimation/animation/SpringForce;-><init>()V
 HSPLcom/android/internal/graphics/ColorUtils;->HSLToColor([F)I
 HSPLcom/android/internal/graphics/ColorUtils;->RGBToHSL(III[F)V
 HSPLcom/android/internal/graphics/ColorUtils;->colorToHSL(I[F)V
@@ -21464,7 +21560,7 @@
 HSPLcom/android/internal/listeners/ListenerExecutor$ListenerOperation;->onPostExecute(Z)V
 HSPLcom/android/internal/listeners/ListenerExecutor$ListenerOperation;->onPreExecute()V
 HSPLcom/android/internal/listeners/ListenerExecutor;->executeSafely(Ljava/util/concurrent/Executor;Ljava/util/function/Supplier;Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;)V
-HSPLcom/android/internal/listeners/ListenerExecutor;->executeSafely(Ljava/util/concurrent/Executor;Ljava/util/function/Supplier;Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;Lcom/android/internal/listeners/ListenerExecutor$FailureCallback;)V+]Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;Landroid/telephony/TelephonyRegistryManager$CarrierPrivilegesCallbackWrapper$$ExternalSyntheticLambda2;,Landroid/telephony/TelephonyRegistryManager$CarrierPrivilegesCallbackWrapper$$ExternalSyntheticLambda3;]Ljava/util/concurrent/Executor;Landroid/net/connectivity/com/android/modules/utils/HandlerExecutor;,Landroid/os/HandlerExecutor;,Lcom/android/wifi/x/com/android/modules/utils/HandlerExecutor;]Ljava/util/function/Supplier;Landroid/telephony/TelephonyRegistryManager$CarrierPrivilegesCallbackWrapper$$ExternalSyntheticLambda1;
+HSPLcom/android/internal/listeners/ListenerExecutor;->executeSafely(Ljava/util/concurrent/Executor;Ljava/util/function/Supplier;Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;Lcom/android/internal/listeners/ListenerExecutor$FailureCallback;)V
 HSPLcom/android/internal/listeners/ListenerExecutor;->lambda$executeSafely$0(Ljava/lang/Object;Ljava/util/function/Supplier;Lcom/android/internal/listeners/ListenerExecutor$ListenerOperation;Lcom/android/internal/listeners/ListenerExecutor$FailureCallback;)V
 HSPLcom/android/internal/logging/AndroidConfig;-><init>()V
 HSPLcom/android/internal/logging/AndroidHandler$1;->format(Ljava/util/logging/LogRecord;)Ljava/lang/String;
@@ -21705,33 +21801,42 @@
 HSPLcom/android/internal/policy/DecorView$ColorViewAttributes;->isVisible(ZIIZ)Z
 HSPLcom/android/internal/policy/DecorView$ColorViewState;-><init>(Lcom/android/internal/policy/DecorView$ColorViewAttributes;)V
 HSPLcom/android/internal/policy/DecorView;-><init>(Landroid/content/Context;ILcom/android/internal/policy/PhoneWindow;Landroid/view/WindowManager$LayoutParams;)V
-HSPLcom/android/internal/policy/DecorView;->calculateNavigationBarColor(I)I
-HSPLcom/android/internal/policy/DecorView;->calculateStatusBarColor(I)I
+HSPLcom/android/internal/policy/DecorView;->calculateNavigationBarColor(I)I+]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
+HSPLcom/android/internal/policy/DecorView;->calculateStatusBarColor(I)I+]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
+HSPLcom/android/internal/policy/DecorView;->createDecorCaptionView(Landroid/view/LayoutInflater;)Lcom/android/internal/widget/DecorCaptionView;
 HSPLcom/android/internal/policy/DecorView;->dispatchKeyEvent(Landroid/view/KeyEvent;)Z
 HSPLcom/android/internal/policy/DecorView;->dispatchTouchEvent(Landroid/view/MotionEvent;)Z
 HSPLcom/android/internal/policy/DecorView;->draw(Landroid/graphics/Canvas;)V
 HSPLcom/android/internal/policy/DecorView;->drawLegacyNavigationBarBackground(Landroid/graphics/RecordingCanvas;)V
 HSPLcom/android/internal/policy/DecorView;->drawableChanged()V
+HSPLcom/android/internal/policy/DecorView;->enableCaption(Z)V
+HSPLcom/android/internal/policy/DecorView;->enforceNonTranslucentBackground(Landroid/graphics/drawable/Drawable;Z)Landroid/graphics/drawable/Drawable;
 HSPLcom/android/internal/policy/DecorView;->finishChanging()V
+HSPLcom/android/internal/policy/DecorView;->gatherTransparentRegion(Landroid/graphics/Region;)Z
+HSPLcom/android/internal/policy/DecorView;->gatherTransparentRegion(Lcom/android/internal/policy/DecorView$ColorViewState;Landroid/graphics/Region;)Z
 HSPLcom/android/internal/policy/DecorView;->getAccessibilityViewId()I
 HSPLcom/android/internal/policy/DecorView;->getBackground()Landroid/graphics/drawable/Drawable;
+HSPLcom/android/internal/policy/DecorView;->getCaptionHeight()I
+HSPLcom/android/internal/policy/DecorView;->getCaptionInsetsHeight()I
 HSPLcom/android/internal/policy/DecorView;->getNavBarSize(III)I
-HSPLcom/android/internal/policy/DecorView;->getResources()Landroid/content/res/Resources;+]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
-HSPLcom/android/internal/policy/DecorView;->getTitleSuffix(Landroid/view/WindowManager$LayoutParams;)Ljava/lang/String;
-HSPLcom/android/internal/policy/DecorView;->getWindowInsetsController()Landroid/view/WindowInsetsController;
+HSPLcom/android/internal/policy/DecorView;->getResources()Landroid/content/res/Resources;+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Landroid/content/Context;Landroid/view/ContextThemeWrapper;,Lcom/android/internal/policy/DecorContext;
+HSPLcom/android/internal/policy/DecorView;->getTitleSuffix(Landroid/view/WindowManager$LayoutParams;)Ljava/lang/String;+]Ljava/lang/String;Ljava/lang/String;]Landroid/view/WindowManager$LayoutParams;Landroid/view/WindowManager$LayoutParams;]Ljava/lang/CharSequence;Ljava/lang/String;
+HSPLcom/android/internal/policy/DecorView;->getWindowInsetsController()Landroid/view/WindowInsetsController;+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
 HSPLcom/android/internal/policy/DecorView;->initializeElevation()V
 HSPLcom/android/internal/policy/DecorView;->isNavBarToLeftEdge(II)Z
 HSPLcom/android/internal/policy/DecorView;->isNavBarToRightEdge(II)Z
+HSPLcom/android/internal/policy/DecorView;->isResizing()Z
+HSPLcom/android/internal/policy/DecorView;->isShowingCaption()Z
 HSPLcom/android/internal/policy/DecorView;->onApplyWindowInsets(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
 HSPLcom/android/internal/policy/DecorView;->onAttachedToWindow()V
 HSPLcom/android/internal/policy/DecorView;->onCloseSystemDialogs(Ljava/lang/String;)V
 HSPLcom/android/internal/policy/DecorView;->onConfigurationChanged(Landroid/content/res/Configuration;)V
 HSPLcom/android/internal/policy/DecorView;->onContentDrawn(IIII)Z
 HSPLcom/android/internal/policy/DecorView;->onDetachedFromWindow()V
-HSPLcom/android/internal/policy/DecorView;->onDraw(Landroid/graphics/Canvas;)V
+HSPLcom/android/internal/policy/DecorView;->onDraw(Landroid/graphics/Canvas;)V+]Lcom/android/internal/widget/BackgroundFallback;Lcom/android/internal/widget/BackgroundFallback;
 HSPLcom/android/internal/policy/DecorView;->onInterceptTouchEvent(Landroid/view/MotionEvent;)Z
-HSPLcom/android/internal/policy/DecorView;->onLayout(ZIIII)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
-HSPLcom/android/internal/policy/DecorView;->onMeasure(II)V+]Landroid/content/Context;Lcom/android/internal/policy/DecorContext;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/util/TypedValue;Landroid/util/TypedValue;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
+HSPLcom/android/internal/policy/DecorView;->onLayout(ZIIII)V
+HSPLcom/android/internal/policy/DecorView;->onMeasure(II)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Landroid/content/Context;Landroid/view/ContextThemeWrapper;,Lcom/android/internal/policy/DecorContext;]Landroid/content/res/Resources;Landroid/content/res/Resources;
 HSPLcom/android/internal/policy/DecorView;->onPostDraw(Landroid/graphics/RecordingCanvas;)V
 HSPLcom/android/internal/policy/DecorView;->onResourcesLoaded(Landroid/view/LayoutInflater;I)V
 HSPLcom/android/internal/policy/DecorView;->onRootViewScrollYChanged(I)V
@@ -21740,12 +21845,13 @@
 HSPLcom/android/internal/policy/DecorView;->onWindowFocusChanged(Z)V
 HSPLcom/android/internal/policy/DecorView;->onWindowSystemUiVisibilityChanged(I)V
 HSPLcom/android/internal/policy/DecorView;->providePendingInsetsController()Landroid/view/PendingInsetsController;
+HSPLcom/android/internal/policy/DecorView;->releaseThreadedRenderer()V
 HSPLcom/android/internal/policy/DecorView;->removeBackgroundBlurDrawable()V
 HSPLcom/android/internal/policy/DecorView;->sendAccessibilityEvent(I)V
 HSPLcom/android/internal/policy/DecorView;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLcom/android/internal/policy/DecorView;->setBackgroundFallback(Landroid/graphics/drawable/Drawable;)V
 HSPLcom/android/internal/policy/DecorView;->setColor(Landroid/view/View;IIZZ)V
-HSPLcom/android/internal/policy/DecorView;->setFrame(IIII)Z+]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/ColorDrawable;,Landroid/graphics/drawable/GradientDrawable;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
+HSPLcom/android/internal/policy/DecorView;->setFrame(IIII)Z+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Landroid/graphics/drawable/Drawable;Landroid/graphics/drawable/ColorDrawable;
 HSPLcom/android/internal/policy/DecorView;->setWindow(Lcom/android/internal/policy/PhoneWindow;)V
 HSPLcom/android/internal/policy/DecorView;->setWindowBackground(Landroid/graphics/drawable/Drawable;)V
 HSPLcom/android/internal/policy/DecorView;->setWindowFrame(Landroid/graphics/drawable/Drawable;)V
@@ -21753,12 +21859,13 @@
 HSPLcom/android/internal/policy/DecorView;->superDispatchKeyEvent(Landroid/view/KeyEvent;)Z
 HSPLcom/android/internal/policy/DecorView;->superDispatchTouchEvent(Landroid/view/MotionEvent;)Z
 HSPLcom/android/internal/policy/DecorView;->updateBackgroundBlurRadius()V
-HSPLcom/android/internal/policy/DecorView;->updateBackgroundDrawable()V
-HSPLcom/android/internal/policy/DecorView;->updateColorViewInt(Lcom/android/internal/policy/DecorView$ColorViewState;IIIZZIZZI)V+]Landroid/view/View;Landroid/view/View;]Landroid/view/ViewPropertyAnimator;Landroid/view/ViewPropertyAnimator;]Lcom/android/internal/policy/DecorView$ColorViewAttributes;Lcom/android/internal/policy/DecorView$ColorViewAttributes;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
+HSPLcom/android/internal/policy/DecorView;->updateBackgroundDrawable()V+]Landroid/graphics/Insets;Landroid/graphics/Insets;
+HSPLcom/android/internal/policy/DecorView;->updateColorViewInt(Lcom/android/internal/policy/DecorView$ColorViewState;IIIZZIZZI)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;]Landroid/view/View;Landroid/view/View;]Landroid/view/ViewPropertyAnimator;Landroid/view/ViewPropertyAnimator;]Lcom/android/internal/policy/DecorView$ColorViewAttributes;Lcom/android/internal/policy/DecorView$ColorViewAttributes;
 HSPLcom/android/internal/policy/DecorView;->updateColorViewTranslations()V
-HSPLcom/android/internal/policy/DecorView;->updateColorViews(Landroid/view/WindowInsets;Z)Landroid/view/WindowInsets;+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/view/ViewGroup;Landroid/widget/LinearLayout;]Landroid/view/WindowInsets;Landroid/view/WindowInsets;]Landroid/view/WindowInsetsController;Landroid/view/InsetsController;,Landroid/view/PendingInsetsController;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;
-HSPLcom/android/internal/policy/DecorView;->updateElevation()V+]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
-HSPLcom/android/internal/policy/DecorView;->updateLogTag(Landroid/view/WindowManager$LayoutParams;)V
+HSPLcom/android/internal/policy/DecorView;->updateColorViews(Landroid/view/WindowInsets;Z)Landroid/view/WindowInsets;+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;]Landroid/view/ViewGroup;Landroid/widget/LinearLayout;]Landroid/view/WindowInsetsController;Landroid/view/InsetsController;,Landroid/view/PendingInsetsController;]Landroid/view/WindowInsets;Landroid/view/WindowInsets;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
+HSPLcom/android/internal/policy/DecorView;->updateDecorCaptionStatus(Landroid/content/res/Configuration;)V
+HSPLcom/android/internal/policy/DecorView;->updateElevation()V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/app/WindowConfiguration;Landroid/app/WindowConfiguration;
+HSPLcom/android/internal/policy/DecorView;->updateLogTag(Landroid/view/WindowManager$LayoutParams;)V+]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;
 HSPLcom/android/internal/policy/DecorView;->updateStatusGuard(Landroid/view/WindowInsets;)Landroid/view/WindowInsets;
 HSPLcom/android/internal/policy/DecorView;->willYouTakeTheInputQueue()Landroid/view/InputQueue$Callback;
 HSPLcom/android/internal/policy/DecorView;->willYouTakeTheSurface()Landroid/view/SurfaceHolder$Callback2;
@@ -21792,10 +21899,10 @@
 HSPLcom/android/internal/policy/PhoneWindow;->closeAllPanels()V
 HSPLcom/android/internal/policy/PhoneWindow;->closeContextMenu()V
 HSPLcom/android/internal/policy/PhoneWindow;->closePanel(Lcom/android/internal/policy/PhoneWindow$PanelFeatureState;Z)V
-HSPLcom/android/internal/policy/PhoneWindow;->dispatchWindowAttributesChanged(Landroid/view/WindowManager$LayoutParams;)V
+HSPLcom/android/internal/policy/PhoneWindow;->dispatchWindowAttributesChanged(Landroid/view/WindowManager$LayoutParams;)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
 HSPLcom/android/internal/policy/PhoneWindow;->doInvalidatePanelMenu(I)V
 HSPLcom/android/internal/policy/PhoneWindow;->generateDecor(I)Lcom/android/internal/policy/DecorView;
-HSPLcom/android/internal/policy/PhoneWindow;->generateLayout(Lcom/android/internal/policy/DecorView;)Landroid/view/ViewGroup;+]Landroid/content/res/Resources;Landroid/content/res/Resources;]Landroid/content/res/TypedArray;Landroid/content/res/TypedArray;]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;]Lcom/android/internal/policy/PhoneWindow;Lcom/android/internal/policy/PhoneWindow;]Ljava/lang/Boolean;Ljava/lang/Boolean;
+HSPLcom/android/internal/policy/PhoneWindow;->generateLayout(Lcom/android/internal/policy/DecorView;)Landroid/view/ViewGroup;
 HSPLcom/android/internal/policy/PhoneWindow;->getCurrentFocus()Landroid/view/View;
 HSPLcom/android/internal/policy/PhoneWindow;->getDecorView()Landroid/view/View;
 HSPLcom/android/internal/policy/PhoneWindow;->getLayoutInflater()Landroid/view/LayoutInflater;
@@ -21823,7 +21930,7 @@
 HSPLcom/android/internal/policy/PhoneWindow;->requestFeature(I)Z
 HSPLcom/android/internal/policy/PhoneWindow;->restoreHierarchyState(Landroid/os/Bundle;)V
 HSPLcom/android/internal/policy/PhoneWindow;->saveHierarchyState()Landroid/os/Bundle;
-HSPLcom/android/internal/policy/PhoneWindow;->setAttributes(Landroid/view/WindowManager$LayoutParams;)V
+HSPLcom/android/internal/policy/PhoneWindow;->setAttributes(Landroid/view/WindowManager$LayoutParams;)V+]Lcom/android/internal/policy/DecorView;Lcom/android/internal/policy/DecorView;
 HSPLcom/android/internal/policy/PhoneWindow;->setBackgroundBlurRadius(I)V
 HSPLcom/android/internal/policy/PhoneWindow;->setBackgroundDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLcom/android/internal/policy/PhoneWindow;->setContentView(I)V
@@ -21896,6 +22003,7 @@
 HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultDataSubId()I
 HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultSmsSubId()I
 HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultSubId()I
+HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultSubIdAsUser(I)I
 HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getDefaultVoiceSubId()I
 HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getPhoneId(I)I
 HSPLcom/android/internal/telephony/ISub$Stub$Proxy;->getSlotIndex(I)I
@@ -21981,7 +22089,7 @@
 HSPLcom/android/internal/util/ArrayUtils;->deepToString(Ljava/lang/Object;)Ljava/lang/String;
 HSPLcom/android/internal/util/ArrayUtils;->defeatNullable([Ljava/io/File;)[Ljava/io/File;
 HSPLcom/android/internal/util/ArrayUtils;->defeatNullable([Ljava/lang/String;)[Ljava/lang/String;
-HSPLcom/android/internal/util/ArrayUtils;->emptyArray(Ljava/lang/Class;)[Ljava/lang/Object;
+HSPLcom/android/internal/util/ArrayUtils;->emptyArray(Ljava/lang/Class;)[Ljava/lang/Object;+]Ljava/lang/Object;Ljava/lang/Class;]Ljava/lang/Class;Ljava/lang/Class;
 HSPLcom/android/internal/util/ArrayUtils;->emptyIfNull([Ljava/lang/Object;Ljava/lang/Class;)[Ljava/lang/Object;
 HSPLcom/android/internal/util/ArrayUtils;->filter([Ljava/lang/Object;Ljava/util/function/IntFunction;Ljava/util/function/Predicate;)[Ljava/lang/Object;
 HSPLcom/android/internal/util/ArrayUtils;->getOrNull([Ljava/lang/Object;I)Ljava/lang/Object;
@@ -21989,14 +22097,14 @@
 HSPLcom/android/internal/util/ArrayUtils;->isEmpty(Ljava/util/Collection;)Z
 HSPLcom/android/internal/util/ArrayUtils;->isEmpty([I)Z
 HSPLcom/android/internal/util/ArrayUtils;->isEmpty([Ljava/lang/Object;)Z
-HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedArray(Ljava/lang/Class;I)[Ljava/lang/Object;
+HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedArray(Ljava/lang/Class;I)[Ljava/lang/Object;+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
 HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedBooleanArray(I)[Z
 HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedByteArray(I)[B
-HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedCharArray(I)[C
+HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedCharArray(I)[C+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
 HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedFloatArray(I)[F
-HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedIntArray(I)[I
+HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedIntArray(I)[I+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
 HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedLongArray(I)[J
-HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedObjectArray(I)[Ljava/lang/Object;
+HSPLcom/android/internal/util/ArrayUtils;->newUnpaddedObjectArray(I)[Ljava/lang/Object;+]Ldalvik/system/VMRuntime;Ldalvik/system/VMRuntime;
 HSPLcom/android/internal/util/ArrayUtils;->remove(Ljava/util/ArrayList;Ljava/lang/Object;)Ljava/util/ArrayList;
 HSPLcom/android/internal/util/ArrayUtils;->removeElement(Ljava/lang/Class;[Ljava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;
 HSPLcom/android/internal/util/ArrayUtils;->size([Ljava/lang/Object;)I
@@ -22037,13 +22145,13 @@
 HSPLcom/android/internal/util/FastPrintWriter;->print(Ljava/lang/String;)V
 HSPLcom/android/internal/util/FastPrintWriter;->println()V
 HSPLcom/android/internal/util/FastPrintWriter;->write(I)V
-HSPLcom/android/internal/util/FastPrintWriter;->write(Ljava/lang/String;)V
+HSPLcom/android/internal/util/FastPrintWriter;->write(Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;
 HSPLcom/android/internal/util/FastPrintWriter;->write([CII)V
 HSPLcom/android/internal/util/FastXmlSerializer;-><init>()V
 HSPLcom/android/internal/util/FastXmlSerializer;-><init>(I)V
 HSPLcom/android/internal/util/FastXmlSerializer;->append(C)V
 HSPLcom/android/internal/util/FastXmlSerializer;->append(Ljava/lang/String;)V+]Ljava/lang/String;Ljava/lang/String;
-HSPLcom/android/internal/util/FastXmlSerializer;->append(Ljava/lang/String;II)V+]Ljava/lang/String;Ljava/lang/String;
+HSPLcom/android/internal/util/FastXmlSerializer;->append(Ljava/lang/String;II)V+]Ljava/lang/String;Ljava/lang/String;]Lcom/android/internal/util/FastXmlSerializer;Lcom/android/internal/util/FastXmlSerializer;
 HSPLcom/android/internal/util/FastXmlSerializer;->appendIndent(I)V+]Ljava/lang/String;Ljava/lang/String;
 HSPLcom/android/internal/util/FastXmlSerializer;->attribute(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/xmlpull/v1/XmlSerializer;
 HSPLcom/android/internal/util/FastXmlSerializer;->endDocument()V
@@ -22065,12 +22173,12 @@
 HSPLcom/android/internal/util/FrameworkStatsLog;->write(ILjava/lang/String;IIF)V
 HSPLcom/android/internal/util/GrowingArrayUtils;->append([III)[I
 HSPLcom/android/internal/util/GrowingArrayUtils;->append([JIJ)[J
-HSPLcom/android/internal/util/GrowingArrayUtils;->append([Ljava/lang/Object;ILjava/lang/Object;)[Ljava/lang/Object;
+HSPLcom/android/internal/util/GrowingArrayUtils;->append([Ljava/lang/Object;ILjava/lang/Object;)[Ljava/lang/Object;+]Ljava/lang/Object;missing_types]Ljava/lang/Class;Ljava/lang/Class;
 HSPLcom/android/internal/util/GrowingArrayUtils;->append([ZIZ)[Z
 HSPLcom/android/internal/util/GrowingArrayUtils;->growSize(I)I
 HSPLcom/android/internal/util/GrowingArrayUtils;->insert([IIII)[I
 HSPLcom/android/internal/util/GrowingArrayUtils;->insert([JIIJ)[J
-HSPLcom/android/internal/util/GrowingArrayUtils;->insert([Ljava/lang/Object;IILjava/lang/Object;)[Ljava/lang/Object;+]Ljava/lang/Class;Ljava/lang/Class;]Ljava/lang/Object;[Ljava/lang/Object;
+HSPLcom/android/internal/util/GrowingArrayUtils;->insert([Ljava/lang/Object;IILjava/lang/Object;)[Ljava/lang/Object;+]Ljava/lang/Object;[Ljava/lang/Object;]Ljava/lang/Class;Ljava/lang/Class;
 HSPLcom/android/internal/util/GrowingArrayUtils;->insert([ZIIZ)[Z
 HSPLcom/android/internal/util/IndentingPrintWriter;->decreaseIndent()Lcom/android/internal/util/IndentingPrintWriter;
 HSPLcom/android/internal/util/IndentingPrintWriter;->increaseIndent()Lcom/android/internal/util/IndentingPrintWriter;
@@ -22140,7 +22248,7 @@
 HSPLcom/android/internal/util/ProcFileReader;->finishLine()V
 HSPLcom/android/internal/util/ScreenshotHelper;-><init>(Landroid/content/Context;)V
 HSPLcom/android/internal/util/StatLogger;->getTime()J
-HSPLcom/android/internal/util/StatLogger;->logDurationStat(IJ)J+]Lcom/android/internal/util/StatLogger;Lcom/android/internal/util/StatLogger;
+HSPLcom/android/internal/util/StatLogger;->logDurationStat(IJ)J
 HSPLcom/android/internal/util/State;-><init>()V
 HSPLcom/android/internal/util/State;->enter()V
 HSPLcom/android/internal/util/StateMachine$LogRecords;->add(Lcom/android/internal/util/StateMachine;Landroid/os/Message;Ljava/lang/String;Lcom/android/internal/util/IState;Lcom/android/internal/util/IState;Lcom/android/internal/util/IState;)V
@@ -22192,7 +22300,7 @@
 HSPLcom/android/internal/util/XmlSerializerWrapper;->setFeature(Ljava/lang/String;Z)V
 HSPLcom/android/internal/util/XmlSerializerWrapper;->setOutput(Ljava/io/OutputStream;Ljava/lang/String;)V
 HSPLcom/android/internal/util/XmlSerializerWrapper;->startDocument(Ljava/lang/String;Ljava/lang/Boolean;)V
-HSPLcom/android/internal/util/XmlSerializerWrapper;->startTag(Ljava/lang/String;Ljava/lang/String;)Lorg/xmlpull/v1/XmlSerializer;+]Lorg/xmlpull/v1/XmlSerializer;Lcom/android/internal/util/FastXmlSerializer;
+HSPLcom/android/internal/util/XmlSerializerWrapper;->startTag(Ljava/lang/String;Ljava/lang/String;)Lorg/xmlpull/v1/XmlSerializer;
 HSPLcom/android/internal/util/XmlSerializerWrapper;->text(Ljava/lang/String;)Lorg/xmlpull/v1/XmlSerializer;
 HSPLcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;-><init>(Lorg/xmlpull/v1/XmlPullParser;)V
 HSPLcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;->getAttributeBoolean(I)Z
@@ -22215,19 +22323,19 @@
 HSPLcom/android/internal/util/XmlUtils;->readLongAttribute(Lorg/xmlpull/v1/XmlPullParser;Ljava/lang/String;J)J
 HSPLcom/android/internal/util/XmlUtils;->readMapXml(Ljava/io/InputStream;)Ljava/util/HashMap;
 HSPLcom/android/internal/util/XmlUtils;->readStringAttribute(Lorg/xmlpull/v1/XmlPullParser;Ljava/lang/String;)Ljava/lang/String;
-HSPLcom/android/internal/util/XmlUtils;->readThisMapXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;)Ljava/util/HashMap;
-HSPLcom/android/internal/util/XmlUtils;->readThisPrimitiveValueXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;)Ljava/lang/Object;
+HSPLcom/android/internal/util/XmlUtils;->readThisMapXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;)Ljava/util/HashMap;+]Ljava/util/HashMap;Ljava/util/HashMap;]Ljava/lang/Object;Ljava/lang/String;]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
+HSPLcom/android/internal/util/XmlUtils;->readThisPrimitiveValueXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;)Ljava/lang/Object;+]Ljava/lang/Object;Ljava/lang/String;]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
 HSPLcom/android/internal/util/XmlUtils;->readThisSetXml(Lcom/android/modules/utils/TypedXmlPullParser;Ljava/lang/String;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;Z)Ljava/util/HashSet;
-HSPLcom/android/internal/util/XmlUtils;->readThisValueXml(Lcom/android/modules/utils/TypedXmlPullParser;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;Z)Ljava/lang/Object;
+HSPLcom/android/internal/util/XmlUtils;->readThisValueXml(Lcom/android/modules/utils/TypedXmlPullParser;[Ljava/lang/String;Lcom/android/internal/util/XmlUtils$ReadMapCallback;Z)Ljava/lang/Object;+]Ljava/lang/Object;Ljava/lang/String;]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;]Ljava/lang/StringBuilder;Ljava/lang/StringBuilder;]Lcom/android/internal/util/XmlUtils$ReadMapCallback;Landroid/os/PersistableBundle$MyReadMapCallback;
 HSPLcom/android/internal/util/XmlUtils;->readValueXml(Lcom/android/modules/utils/TypedXmlPullParser;[Ljava/lang/String;)Ljava/lang/Object;
 HSPLcom/android/internal/util/XmlUtils;->skipCurrentTag(Lorg/xmlpull/v1/XmlPullParser;)V
-HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V+]Ljava/util/Iterator;Ljava/util/HashMap$EntryIterator;]Ljava/util/Map$Entry;Ljava/util/HashMap$Node;]Ljava/util/Map;Ljava/util/HashMap;]Ljava/util/Set;Ljava/util/HashMap$EntrySet;
+HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V
 HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Ljava/io/OutputStream;)V
 HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;)V
 HSPLcom/android/internal/util/XmlUtils;->writeMapXml(Ljava/util/Map;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V
 HSPLcom/android/internal/util/XmlUtils;->writeSetXml(Ljava/util/Set;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;)V
 HSPLcom/android/internal/util/XmlUtils;->writeValueXml(Ljava/lang/Object;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;)V
-HSPLcom/android/internal/util/XmlUtils;->writeValueXml(Ljava/lang/Object;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V+]Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlSerializer;]Ljava/lang/Boolean;Ljava/lang/Boolean;]Ljava/lang/Integer;Ljava/lang/Integer;]Ljava/lang/Long;Ljava/lang/Long;]Ljava/lang/Object;Ljava/lang/String;
+HSPLcom/android/internal/util/XmlUtils;->writeValueXml(Ljava/lang/Object;Ljava/lang/String;Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$WriteMapCallback;)V+]Ljava/lang/Integer;Ljava/lang/Integer;]Lcom/android/modules/utils/TypedXmlSerializer;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlSerializer;]Ljava/lang/Object;Ljava/lang/String;]Ljava/lang/Boolean;Ljava/lang/Boolean;]Ljava/lang/Long;Ljava/lang/Long;]Ljava/lang/Float;Ljava/lang/Float;
 HSPLcom/android/internal/util/function/pooled/OmniFunction;->run()V
 HSPLcom/android/internal/util/function/pooled/PooledLambda;->obtainMessage(Lcom/android/internal/util/function/HexConsumer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Landroid/os/Message;
 HSPLcom/android/internal/util/function/pooled/PooledLambda;->obtainMessage(Lcom/android/internal/util/function/QuadConsumer;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Landroid/os/Message;
@@ -22263,6 +22371,7 @@
 HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->addClient(Lcom/android/internal/inputmethod/IInputMethodClient;Lcom/android/internal/inputmethod/IRemoteInputConnection;I)V
 HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->asBinder()Landroid/os/IBinder;
+HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->getEnabledInputMethodList(I)Ljava/util/List;
 HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->getImeTrackerService()Lcom/android/internal/inputmethod/IImeTracker;
 HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->isImeTraceEnabled()Z
 HSPLcom/android/internal/view/IInputMethodManager$Stub$Proxy;->removeImeSurfaceFromWindowAsync(Landroid/os/IBinder;)V
@@ -22307,7 +22416,7 @@
 HSPLcom/android/internal/widget/AlertDialogLayout;->setChildFrame(Landroid/view/View;IIII)V
 HSPLcom/android/internal/widget/AlertDialogLayout;->tryOnMeasure(II)Z
 HSPLcom/android/internal/widget/BackgroundFallback;-><init>()V
-HSPLcom/android/internal/widget/BackgroundFallback;->draw(Landroid/view/ViewGroup;Landroid/view/ViewGroup;Landroid/graphics/Canvas;Landroid/view/View;Landroid/view/View;Landroid/view/View;)V
+HSPLcom/android/internal/widget/BackgroundFallback;->draw(Landroid/view/ViewGroup;Landroid/view/ViewGroup;Landroid/graphics/Canvas;Landroid/view/View;Landroid/view/View;Landroid/view/View;)V+]Lcom/android/internal/widget/BackgroundFallback;Lcom/android/internal/widget/BackgroundFallback;
 HSPLcom/android/internal/widget/BackgroundFallback;->hasFallback()Z
 HSPLcom/android/internal/widget/BackgroundFallback;->setDrawable(Landroid/graphics/drawable/Drawable;)V
 HSPLcom/android/internal/widget/ButtonBarLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
@@ -22326,6 +22435,7 @@
 HSPLcom/android/internal/widget/LockPatternUtils$StrongAuthTracker;->isNonStrongBiometricAllowedAfterIdleTimeout(I)Z
 HSPLcom/android/internal/widget/LockPatternUtils$StrongAuthTracker;->onIsNonStrongBiometricAllowedChanged(I)V
 HSPLcom/android/internal/widget/LockPatternUtils;-><init>(Landroid/content/Context;)V
+HSPLcom/android/internal/widget/LockPatternUtils;-><init>(Landroid/content/Context;Lcom/android/internal/widget/ILockSettings;)V+]Landroid/content/Context;Landroid/app/ContextImpl;,Landroid/app/ReceiverRestrictedContext;
 HSPLcom/android/internal/widget/LockPatternUtils;->credentialTypeToPasswordQuality(I)I
 HSPLcom/android/internal/widget/LockPatternUtils;->getBoolean(Ljava/lang/String;ZI)Z
 HSPLcom/android/internal/widget/LockPatternUtils;->getCredentialTypeForUser(I)I
@@ -22341,8 +22451,8 @@
 HSPLcom/android/internal/widget/LockPatternUtils;->isSecure(I)Z
 HSPLcom/android/internal/widget/LockPatternUtils;->isSeparateProfileChallengeEnabled(I)Z
 HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeBoolean(Ljava/lang/String;Ljava/lang/String;)Z+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
-HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeFloat(Ljava/lang/String;Ljava/lang/String;)F+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
-HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeIndex(Ljava/lang/String;Ljava/lang/String;)I+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;]Ljava/lang/Object;Ljava/lang/String;
+HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeFloat(Ljava/lang/String;Ljava/lang/String;)F
+HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeIndex(Ljava/lang/String;Ljava/lang/String;)I+]Ljava/lang/Object;Ljava/lang/String;]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
 HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeIndexOrThrow(Ljava/lang/String;Ljava/lang/String;)I+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
 HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeInt(Ljava/lang/String;Ljava/lang/String;)I+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
 HSPLcom/android/modules/utils/TypedXmlPullParser;->getAttributeLong(Ljava/lang/String;Ljava/lang/String;)J+]Lcom/android/modules/utils/TypedXmlPullParser;Lcom/android/internal/util/XmlUtils$ForcedTypedXmlPullParser;
@@ -23291,6 +23401,12 @@
 HSPLcom/android/telephony/Rlog;->log(ILjava/lang/String;Ljava/lang/String;)I
 HSPLcom/android/telephony/Rlog;->pii(ZLjava/lang/Object;)Ljava/lang/String;
 HSPLcom/android/telephony/Rlog;->w(Ljava/lang/String;Ljava/lang/String;)I
+HSPLcom/android/text/flags/FeatureFlagsImpl;-><init>()V
+HSPLcom/android/text/flags/Flags;-><clinit>()V
+HSPLcom/android/window/flags/FeatureFlagsImpl;-><init>()V
+HSPLcom/android/window/flags/FeatureFlagsImpl;->bundleClientTransactionFlag()Z
+HSPLcom/android/window/flags/Flags;-><clinit>()V
+HSPLcom/android/window/flags/Flags;->bundleClientTransactionFlag()Z+]Lcom/android/window/flags/FeatureFlags;Lcom/android/window/flags/FeatureFlagsImpl;
 HSPLcom/google/android/collect/Lists;->newArrayList()Ljava/util/ArrayList;
 HSPLcom/google/android/collect/Lists;->newArrayList([Ljava/lang/Object;)Ljava/util/ArrayList;
 HSPLcom/google/android/collect/Maps;->newHashMap()Ljava/util/HashMap;
@@ -24968,7 +25084,7 @@
 HSPLjava/lang/UnsatisfiedLinkError;-><init>(Ljava/lang/String;)V
 HSPLjava/lang/UnsupportedOperationException;-><init>()V
 HSPLjava/lang/UnsupportedOperationException;-><init>(Ljava/lang/String;)V
-HSPLjava/lang/VMClassLoader;->createBootClassPathUrlHandlers()[Llibcore/io/ClassPathURLStreamHandler;
+HPLjava/lang/VMClassLoader;->createBootClassPathUrlHandlers()[Llibcore/io/ClassPathURLStreamHandler;
 HSPLjava/lang/VMClassLoader;->getResource(Ljava/lang/String;)Ljava/net/URL;
 HSPLjava/lang/VMClassLoader;->getResources(Ljava/lang/String;)Ljava/util/List;
 HSPLjava/lang/invoke/FieldVarHandle;-><init>(Ljava/lang/reflect/Field;Ljava/lang/Class;)V
@@ -25880,7 +25996,7 @@
 HSPLjava/nio/ByteBuffer;->position(I)Ljava/nio/Buffer;
 HSPLjava/nio/ByteBuffer;->put(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;
 HSPLjava/nio/ByteBuffer;->put([B)Ljava/nio/ByteBuffer;
-HSPLjava/nio/ByteBuffer;->putBuffer(ILjava/nio/ByteBuffer;II)V
+HSPLjava/nio/ByteBuffer;->putBuffer(ILjava/nio/ByteBuffer;II)V+]Ljava/nio/ByteBuffer;Ljava/nio/DirectByteBuffer;,Ljava/nio/HeapByteBuffer;
 HSPLjava/nio/ByteBuffer;->reset()Ljava/nio/Buffer;
 HSPLjava/nio/ByteBuffer;->rewind()Ljava/nio/Buffer;
 HSPLjava/nio/ByteBuffer;->wrap([B)Ljava/nio/ByteBuffer;
@@ -26888,12 +27004,12 @@
 HSPLjava/time/chrono/AbstractChronology;->equals(Ljava/lang/Object;)Z
 HSPLjava/time/chrono/AbstractChronology;->resolveDate(Ljava/util/Map;Ljava/time/format/ResolverStyle;)Ljava/time/chrono/ChronoLocalDate;
 HSPLjava/time/chrono/ChronoLocalDate;->isSupported(Ljava/time/temporal/TemporalField;)Z
-HSPLjava/time/chrono/ChronoLocalDateTime;->getChronology()Ljava/time/chrono/Chronology;+]Ljava/time/chrono/ChronoLocalDate;Ljava/time/LocalDate;]Ljava/time/chrono/ChronoLocalDateTime;Ljava/time/LocalDateTime;
+HSPLjava/time/chrono/ChronoLocalDateTime;->getChronology()Ljava/time/chrono/Chronology;
 HSPLjava/time/chrono/ChronoLocalDateTime;->query(Ljava/time/temporal/TemporalQuery;)Ljava/lang/Object;
-HSPLjava/time/chrono/ChronoLocalDateTime;->toEpochSecond(Ljava/time/ZoneOffset;)J+]Ljava/time/chrono/ChronoLocalDate;Ljava/time/LocalDate;]Ljava/time/chrono/ChronoLocalDateTime;Ljava/time/LocalDateTime;
-HSPLjava/time/chrono/ChronoZonedDateTime;->getChronology()Ljava/time/chrono/Chronology;+]Ljava/time/chrono/ChronoLocalDate;Ljava/time/LocalDate;]Ljava/time/chrono/ChronoZonedDateTime;Ljava/time/ZonedDateTime;
+HSPLjava/time/chrono/ChronoLocalDateTime;->toEpochSecond(Ljava/time/ZoneOffset;)J+]Ljava/time/chrono/ChronoLocalDateTime;Ljava/time/LocalDateTime;]Ljava/time/chrono/ChronoLocalDate;Ljava/time/LocalDate;
+HSPLjava/time/chrono/ChronoZonedDateTime;->getChronology()Ljava/time/chrono/Chronology;+]Ljava/time/chrono/ChronoZonedDateTime;Ljava/time/ZonedDateTime;]Ljava/time/chrono/ChronoLocalDate;Ljava/time/LocalDate;
 HSPLjava/time/chrono/ChronoZonedDateTime;->query(Ljava/time/temporal/TemporalQuery;)Ljava/lang/Object;
-HSPLjava/time/chrono/ChronoZonedDateTime;->toEpochSecond()J+]Ljava/time/chrono/ChronoLocalDate;Ljava/time/LocalDate;]Ljava/time/chrono/ChronoZonedDateTime;Ljava/time/ZonedDateTime;
+HSPLjava/time/chrono/ChronoZonedDateTime;->toEpochSecond()J+]Ljava/time/chrono/ChronoZonedDateTime;Ljava/time/ZonedDateTime;]Ljava/time/chrono/ChronoLocalDate;Ljava/time/LocalDate;
 HSPLjava/time/chrono/ChronoZonedDateTime;->toInstant()Ljava/time/Instant;+]Ljava/time/chrono/ChronoZonedDateTime;Ljava/time/ZonedDateTime;
 HSPLjava/time/chrono/IsoChronology;->isLeapYear(J)Z
 HSPLjava/time/chrono/IsoChronology;->resolveDate(Ljava/util/Map;Ljava/time/format/ResolverStyle;)Ljava/time/LocalDate;
@@ -27302,7 +27418,7 @@
 HSPLjava/util/Arrays$ArrayList;->spliterator()Ljava/util/Spliterator;
 HSPLjava/util/Arrays$ArrayList;->toArray()[Ljava/lang/Object;
 HSPLjava/util/Arrays$ArrayList;->toArray([Ljava/lang/Object;)[Ljava/lang/Object;
-HSPLjava/util/Arrays$ArrayList;->toArrayPreserveComponentType()[Ljava/lang/Object;
+HSPLjava/util/Arrays$ArrayList;->toArrayPreserveComponentType()[Ljava/lang/Object;+][Ljava/lang/Object;missing_types
 HSPLjava/util/Arrays;->asList([Ljava/lang/Object;)Ljava/util/List;
 HSPLjava/util/Arrays;->binarySearch([CC)I
 HSPLjava/util/Arrays;->binarySearch([II)I
@@ -27464,7 +27580,7 @@
 HSPLjava/util/Calendar;->setWeekCountData(Ljava/util/Locale;)V
 HSPLjava/util/Calendar;->setZoneShared(Z)V
 HSPLjava/util/Calendar;->updateTime()V
-HSPLjava/util/Collection;->removeIf(Ljava/util/function/Predicate;)Z+]Ljava/util/Collection;megamorphic_types]Ljava/util/Iterator;megamorphic_types]Ljava/util/function/Predicate;Lcom/android/internal/telephony/data/DataNetworkController$$ExternalSyntheticLambda32;,Lcom/android/internal/telephony/data/DataNetworkController$$ExternalSyntheticLambda43;
+HSPLjava/util/Collection;->removeIf(Ljava/util/function/Predicate;)Z+]Ljava/util/Collection;Landroid/util/MapCollections$ValuesCollection;,Landroid/util/MapCollections$EntrySet;,Ljava/util/LinkedHashMap$LinkedEntrySet;,Ljava/util/LinkedList;,Landroid/util/MapCollections$KeySet;,Ljava/util/HashSet;,Ljava/util/LinkedHashMap$LinkedValues;,Ljava/util/LinkedHashSet;,Ljava/util/HashMap$EntrySet;]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;,Landroid/util/MapCollections$MapIterator;,Ljava/util/LinkedList$ListItr;,Ljava/util/LinkedHashMap$LinkedEntryIterator;,Ljava/util/HashMap$KeyIterator;,Ljava/util/LinkedHashMap$LinkedValueIterator;,Ljava/util/LinkedHashMap$LinkedKeyIterator;,Ljava/util/HashMap$EntryIterator;
 HSPLjava/util/Collection;->spliterator()Ljava/util/Spliterator;
 HSPLjava/util/Collection;->stream()Ljava/util/stream/Stream;+]Ljava/util/Collection;megamorphic_types
 HSPLjava/util/Collections$1;-><init>(Ljava/lang/Object;)V
@@ -27652,7 +27768,7 @@
 HSPLjava/util/Collections;->rotate1(Ljava/util/List;I)V
 HSPLjava/util/Collections;->shuffle(Ljava/util/List;)V
 HSPLjava/util/Collections;->shuffle(Ljava/util/List;Ljava/util/Random;)V
-HSPLjava/util/Collections;->shuffle(Ljava/util/List;Ljava/util/random/RandomGenerator;)V
+HSPLjava/util/Collections;->shuffle(Ljava/util/List;Ljava/util/random/RandomGenerator;)V+]Ljava/util/random/RandomGenerator;Ljava/util/Random;]Ljava/util/List;missing_types
 HSPLjava/util/Collections;->singleton(Ljava/lang/Object;)Ljava/util/Set;
 HSPLjava/util/Collections;->singletonIterator(Ljava/lang/Object;)Ljava/util/Iterator;
 HSPLjava/util/Collections;->singletonList(Ljava/lang/Object;)Ljava/util/List;
@@ -27824,7 +27940,7 @@
 HSPLjava/util/Formatter$FormatSpecifier;-><init>(Ljava/util/Formatter;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
 HSPLjava/util/Formatter$FormatSpecifier;->addZeros(Ljava/lang/StringBuilder;I)V
 HSPLjava/util/Formatter$FormatSpecifier;->adjustWidth(ILjava/util/Formatter$Flags;Z)I
-HSPLjava/util/Formatter$FormatSpecifier;->appendJustified(Ljava/lang/Appendable;Ljava/lang/CharSequence;)V
+HSPLjava/util/Formatter$FormatSpecifier;->appendJustified(Ljava/lang/Appendable;Ljava/lang/CharSequence;)V+]Ljava/util/Formatter$Flags;Ljava/util/Formatter$Flags;]Ljava/lang/CharSequence;Ljava/lang/String;,Ljava/lang/StringBuilder;]Ljava/lang/Appendable;megamorphic_types
 HSPLjava/util/Formatter$FormatSpecifier;->checkBadFlags([Ljava/util/Formatter$Flags;)V
 HSPLjava/util/Formatter$FormatSpecifier;->checkCharacter()V
 HSPLjava/util/Formatter$FormatSpecifier;->checkDateTime()V
@@ -27887,7 +28003,7 @@
 HSPLjava/util/Formatter;->out()Ljava/lang/Appendable;
 HSPLjava/util/Formatter;->parse(Ljava/lang/String;)Ljava/util/List;
 HSPLjava/util/Formatter;->toString()Ljava/lang/String;
-HSPLjava/util/Formatter;->zero()C
+HSPLjava/util/Formatter;->zero()C+]Llibcore/icu/DecimalFormatData;Llibcore/icu/DecimalFormatData;
 HSPLjava/util/GregorianCalendar;-><init>()V
 HSPLjava/util/GregorianCalendar;-><init>(IIIIII)V
 HSPLjava/util/GregorianCalendar;-><init>(IIIIIII)V
@@ -28043,8 +28159,8 @@
 HSPLjava/util/HashSet;->remove(Ljava/lang/Object;)Z
 HSPLjava/util/HashSet;->size()I
 HSPLjava/util/HashSet;->spliterator()Ljava/util/Spliterator;
-HSPLjava/util/HashSet;->toArray()[Ljava/lang/Object;
-HSPLjava/util/HashSet;->toArray([Ljava/lang/Object;)[Ljava/lang/Object;
+HSPLjava/util/HashSet;->toArray()[Ljava/lang/Object;+]Ljava/util/HashMap;Ljava/util/HashMap;,Ljava/util/LinkedHashMap;
+HSPLjava/util/HashSet;->toArray([Ljava/lang/Object;)[Ljava/lang/Object;+]Ljava/util/HashMap;Ljava/util/HashMap;,Ljava/util/LinkedHashMap;
 HSPLjava/util/HashSet;->writeObject(Ljava/io/ObjectOutputStream;)V
 HSPLjava/util/Hashtable$EntrySet;-><init>(Ljava/util/Hashtable;)V
 HSPLjava/util/Hashtable$EntrySet;->iterator()Ljava/util/Iterator;
@@ -28068,7 +28184,6 @@
 HSPLjava/util/Hashtable;-><init>()V
 HSPLjava/util/Hashtable;-><init>(I)V
 HSPLjava/util/Hashtable;-><init>(IF)V
-HSPLjava/util/Hashtable;-><init>(Ljava/lang/Void;)V
 HSPLjava/util/Hashtable;->addEntry(ILjava/lang/Object;Ljava/lang/Object;I)V
 HSPLjava/util/Hashtable;->clear()V
 HSPLjava/util/Hashtable;->clone()Ljava/lang/Object;
@@ -28154,14 +28269,13 @@
 HSPLjava/util/ImmutableCollections$MapN;->containsKey(Ljava/lang/Object;)Z
 HSPLjava/util/ImmutableCollections$MapN;->get(Ljava/lang/Object;)Ljava/lang/Object;
 HSPLjava/util/ImmutableCollections$MapN;->probe(Ljava/lang/Object;)I
-HSPLjava/util/ImmutableCollections$Set12;-><init>(Ljava/lang/Object;Ljava/lang/Object;)V+]Ljava/lang/Object;missing_types
 HSPLjava/util/ImmutableCollections$SetN;-><init>([Ljava/lang/Object;)V
 HSPLjava/util/ImmutableCollections$SetN;->contains(Ljava/lang/Object;)Z
 HSPLjava/util/ImmutableCollections$SetN;->probe(Ljava/lang/Object;)I
 HSPLjava/util/ImmutableCollections;-><clinit>()V
 HSPLjava/util/ImmutableCollections;->listCopy(Ljava/util/Collection;)Ljava/util/List;
 HSPLjava/util/ImmutableCollections;->listFromTrustedArray([Ljava/lang/Object;)Ljava/util/List;
-HSPLjava/util/Iterator;->forEachRemaining(Ljava/util/function/Consumer;)V+]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;,Landroid/util/MapCollections$MapIterator;,Ljava/util/AbstractList$Itr;,Ljava/util/AbstractMap$2$1;]Ljava/util/function/Consumer;megamorphic_types
+HSPLjava/util/Iterator;->forEachRemaining(Ljava/util/function/Consumer;)V+]Ljava/util/function/Consumer;megamorphic_types]Ljava/util/Iterator;Landroid/util/MapCollections$ArrayIterator;,Ljava/util/AbstractMap$2$1;,Ljava/util/AbstractList$Itr;,Ljava/util/LinkedHashMap$LinkedValueIterator;
 HSPLjava/util/JumboEnumSet$EnumSetIterator;-><init>(Ljava/util/JumboEnumSet;)V
 HSPLjava/util/JumboEnumSet$EnumSetIterator;->hasNext()Z
 HSPLjava/util/JumboEnumSet$EnumSetIterator;->next()Ljava/lang/Enum;
@@ -28289,7 +28403,7 @@
 HSPLjava/util/List;->of(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/List;
 HSPLjava/util/List;->of(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/List;
 HSPLjava/util/List;->of([Ljava/lang/Object;)Ljava/util/List;
-HSPLjava/util/List;->sort(Ljava/util/Comparator;)V+]Ljava/util/List;Ljava/util/ArrayList$SubList;,Ljava/util/LinkedList;]Ljava/util/ListIterator;Ljava/util/ArrayList$SubList$1;,Ljava/util/LinkedList$ListItr;
+HSPLjava/util/List;->sort(Ljava/util/Comparator;)V+]Ljava/util/ListIterator;Ljava/util/ArrayList$SubList$1;,Ljava/util/LinkedList$ListItr;]Ljava/util/List;Ljava/util/ArrayList$SubList;,Ljava/util/LinkedList;
 HSPLjava/util/List;->spliterator()Ljava/util/Spliterator;
 HSPLjava/util/Locale$Builder;-><init>()V
 HSPLjava/util/Locale$Builder;->build()Ljava/util/Locale;
@@ -28350,7 +28464,7 @@
 HSPLjava/util/Locale;->writeObject(Ljava/io/ObjectOutputStream;)V
 HSPLjava/util/Map;->computeIfAbsent(Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object;+]Ljava/util/Map;Landroid/util/ArrayMap;]Ljava/util/function/Function;missing_types
 HSPLjava/util/Map;->entry(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/Map$Entry;
-HSPLjava/util/Map;->forEach(Ljava/util/function/BiConsumer;)V
+HSPLjava/util/Map;->forEach(Ljava/util/function/BiConsumer;)V+]Ljava/util/Map$Entry;Ljava/util/KeyValueHolder;]Ljava/util/Map;Ljava/util/ImmutableCollections$MapN;]Ljava/util/Iterator;Ljava/util/ImmutableCollections$MapN$MapNIterator;]Ljava/util/Set;Ljava/util/ImmutableCollections$MapN$1;
 HSPLjava/util/Map;->getOrDefault(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+]Ljava/util/Map;Landroid/util/ArrayMap;
 HSPLjava/util/Map;->of(Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/Map;
 HSPLjava/util/Map;->ofEntries([Ljava/util/Map$Entry;)Ljava/util/Map;
@@ -28548,7 +28662,7 @@
 HSPLjava/util/SimpleTimeZone;->getOffsets(J[I)I
 HSPLjava/util/SimpleTimeZone;->getRawOffset()I
 HSPLjava/util/SimpleTimeZone;->hasSameRules(Ljava/util/TimeZone;)Z
-HSPLjava/util/Spliterator$OfInt;->forEachRemaining(Ljava/util/function/Consumer;)V+]Ljava/util/Spliterator$OfInt;Ljava/lang/StringUTF16$CodePointsSpliteratorForString;,Ljava/util/Spliterators$EmptySpliterator$OfInt;,Ljava/util/Spliterators$IntArraySpliterator;,Ljava/util/stream/Streams$RangeIntSpliterator;
+HSPLjava/util/Spliterator$OfInt;->forEachRemaining(Ljava/util/function/Consumer;)V+]Ljava/util/Spliterator$OfInt;Ljava/util/Spliterators$IntArraySpliterator;,Ljava/util/Spliterators$EmptySpliterator$OfInt;,Ljava/util/stream/Streams$RangeIntSpliterator;,Ljava/lang/StringUTF16$CodePointsSpliteratorForString;
 HSPLjava/util/Spliterator;->getExactSizeIfKnown()J+]Ljava/util/Spliterator;megamorphic_types
 HSPLjava/util/Spliterators$ArraySpliterator;-><init>([Ljava/lang/Object;I)V
 HSPLjava/util/Spliterators$ArraySpliterator;-><init>([Ljava/lang/Object;III)V
@@ -29941,7 +30055,7 @@
 HSPLjava/util/stream/Collectors$$ExternalSyntheticLambda25;-><init>()V
 HSPLjava/util/stream/Collectors$$ExternalSyntheticLambda25;->get()Ljava/lang/Object;
 HSPLjava/util/stream/Collectors$$ExternalSyntheticLambda26;-><init>()V
-HSPLjava/util/stream/Collectors$$ExternalSyntheticLambda26;->accept(Ljava/lang/Object;Ljava/lang/Object;)V
+HSPLjava/util/stream/Collectors$$ExternalSyntheticLambda26;->accept(Ljava/lang/Object;Ljava/lang/Object;)V+]Ljava/util/List;Ljava/util/ArrayList;
 HSPLjava/util/stream/Collectors$$ExternalSyntheticLambda27;-><init>()V
 HSPLjava/util/stream/Collectors$$ExternalSyntheticLambda28;-><init>()V
 HSPLjava/util/stream/Collectors$$ExternalSyntheticLambda28;->apply(Ljava/lang/Object;)Ljava/lang/Object;
@@ -29968,7 +30082,7 @@
 HSPLjava/util/stream/Collectors;->joining(Ljava/lang/CharSequence;)Ljava/util/stream/Collector;
 HSPLjava/util/stream/Collectors;->joining(Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/util/stream/Collector;
 HSPLjava/util/stream/Collectors;->lambda$joining$11(Ljava/lang/CharSequence;Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/util/StringJoiner;
-HSPLjava/util/stream/Collectors;->lambda$toUnmodifiableList$6(Ljava/util/ArrayList;)Ljava/util/List;
+HSPLjava/util/stream/Collectors;->lambda$toUnmodifiableList$6(Ljava/util/ArrayList;)Ljava/util/List;+]Ljdk/internal/access/JavaUtilCollectionAccess;Ljava/util/ImmutableCollections$Access$1;
 HSPLjava/util/stream/Collectors;->lambda$uniqKeysMapAccumulator$1(Ljava/util/function/Function;Ljava/util/function/Function;Ljava/util/Map;Ljava/lang/Object;)V
 HSPLjava/util/stream/Collectors;->mapMerger(Ljava/util/function/BinaryOperator;)Ljava/util/function/BinaryOperator;
 HSPLjava/util/stream/Collectors;->toCollection(Ljava/util/function/Supplier;)Ljava/util/stream/Collector;
@@ -30012,7 +30126,7 @@
 HSPLjava/util/stream/IntPipeline$$ExternalSyntheticLambda7;-><init>()V
 HSPLjava/util/stream/IntPipeline$$ExternalSyntheticLambda8;-><init>()V
 HSPLjava/util/stream/IntPipeline$1$1;-><init>(Ljava/util/stream/IntPipeline$1;Ljava/util/stream/Sink;)V
-HSPLjava/util/stream/IntPipeline$1$1;->accept(I)V
+HSPLjava/util/stream/IntPipeline$1$1;->accept(I)V+]Ljava/util/function/IntFunction;megamorphic_types]Ljava/util/stream/Sink;megamorphic_types
 HSPLjava/util/stream/IntPipeline$1;-><init>(Ljava/util/stream/IntPipeline;Ljava/util/stream/AbstractPipeline;Ljava/util/stream/StreamShape;ILjava/util/function/IntFunction;)V
 HSPLjava/util/stream/IntPipeline$1;->opWrapSink(ILjava/util/stream/Sink;)Ljava/util/stream/Sink;
 HSPLjava/util/stream/IntPipeline$4$1;-><init>(Ljava/util/stream/IntPipeline$4;Ljava/util/stream/Sink;)V
@@ -30141,7 +30255,7 @@
 HSPLjava/util/stream/ReduceOps;->makeRef(Ljava/util/function/BinaryOperator;)Ljava/util/stream/TerminalOp;
 HSPLjava/util/stream/ReduceOps;->makeRef(Ljava/util/stream/Collector;)Ljava/util/stream/TerminalOp;
 HSPLjava/util/stream/ReferencePipeline$15$1;-><init>(Ljava/util/stream/ReferencePipeline$15;Ljava/util/stream/Sink;)V
-HSPLjava/util/stream/ReferencePipeline$15$1;->accept(Ljava/lang/Object;)V
+HSPLjava/util/stream/ReferencePipeline$15$1;->accept(Ljava/lang/Object;)V+]Ljava/util/stream/Sink;Ljava/util/stream/ReduceOps$3ReducingSink;]Ljava/util/function/Consumer;Landroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda2;
 HSPLjava/util/stream/ReferencePipeline$15;-><init>(Ljava/util/stream/ReferencePipeline;Ljava/util/stream/AbstractPipeline;Ljava/util/stream/StreamShape;ILjava/util/function/Consumer;)V
 HSPLjava/util/stream/ReferencePipeline$15;->opWrapSink(ILjava/util/stream/Sink;)Ljava/util/stream/Sink;
 HSPLjava/util/stream/ReferencePipeline$2$1;-><init>(Ljava/util/stream/ReferencePipeline$2;Ljava/util/stream/Sink;)V
@@ -30272,7 +30386,7 @@
 HSPLjava/util/zip/Deflater$DeflaterZStreamRef;-><init>(Ljava/util/zip/Deflater;J)V
 HSPLjava/util/zip/Deflater$DeflaterZStreamRef;-><init>(Ljava/util/zip/Deflater;JLjava/util/zip/Deflater$DeflaterZStreamRef-IA;)V
 HSPLjava/util/zip/Deflater$DeflaterZStreamRef;->address()J
-HSPLjava/util/zip/Deflater$DeflaterZStreamRef;->clean()V
+HSPLjava/util/zip/Deflater$DeflaterZStreamRef;->clean()V+]Ljava/lang/ref/Cleaner$Cleanable;Ljdk/internal/ref/CleanerImpl$PhantomCleanableRef;
 HSPLjava/util/zip/Deflater$DeflaterZStreamRef;->run()V
 HSPLjava/util/zip/Deflater;->-$$Nest$smend(J)V
 HSPLjava/util/zip/Deflater;-><init>()V
@@ -30319,7 +30433,7 @@
 HSPLjava/util/zip/GZIPOutputStream;->writeShort(I[BI)V
 HSPLjava/util/zip/GZIPOutputStream;->writeTrailer([BI)V
 HSPLjava/util/zip/Inflater$InflaterZStreamRef;->address()J
-HSPLjava/util/zip/Inflater$InflaterZStreamRef;->clean()V
+HSPLjava/util/zip/Inflater$InflaterZStreamRef;->clean()V+]Ljava/lang/ref/Cleaner$Cleanable;Ljdk/internal/ref/CleanerImpl$PhantomCleanableRef;
 HSPLjava/util/zip/Inflater$InflaterZStreamRef;->run()V
 HSPLjava/util/zip/Inflater;->-$$Nest$smend(J)V
 HSPLjava/util/zip/Inflater;-><init>()V
@@ -30367,15 +30481,15 @@
 HSPLjava/util/zip/ZipEntry;->isDirectory()Z
 HSPLjava/util/zip/ZipEntry;->setExtra0([BZZ)V
 HSPLjava/util/zip/ZipFile$CleanableResource;-><init>(Ljava/util/zip/ZipFile;Ljava/util/zip/ZipCoder;Ljava/io/File;IZ)V
-HSPLjava/util/zip/ZipFile$CleanableResource;->clean()V
-HSPLjava/util/zip/ZipFile$CleanableResource;->getInflater()Ljava/util/zip/Inflater;
-HSPLjava/util/zip/ZipFile$CleanableResource;->releaseInflater(Ljava/util/zip/Inflater;)V
-HSPLjava/util/zip/ZipFile$CleanableResource;->run()V
-HSPLjava/util/zip/ZipFile$InflaterCleanupAction;->run()V
+HSPLjava/util/zip/ZipFile$CleanableResource;->clean()V+]Ljava/lang/ref/Cleaner$Cleanable;Ljdk/internal/ref/CleanerImpl$PhantomCleanableRef;
+HSPLjava/util/zip/ZipFile$CleanableResource;->getInflater()Ljava/util/zip/Inflater;+]Ljava/util/Deque;Ljava/util/ArrayDeque;
+HSPLjava/util/zip/ZipFile$CleanableResource;->releaseInflater(Ljava/util/zip/Inflater;)V+]Ljava/util/Deque;Ljava/util/ArrayDeque;]Ljava/util/zip/Inflater;Ljava/util/zip/Inflater;
+HSPLjava/util/zip/ZipFile$CleanableResource;->run()V+]Ljava/util/Deque;Ljava/util/ArrayDeque;]Ljava/util/Set;Ljava/util/Collections$SetFromMap;]Ljava/util/zip/Inflater;Ljava/util/zip/Inflater;
+HSPLjava/util/zip/ZipFile$InflaterCleanupAction;->run()V+]Ljava/util/zip/ZipFile$CleanableResource;Ljava/util/zip/ZipFile$CleanableResource;
 HSPLjava/util/zip/ZipFile$Source$End;-><init>()V
 HSPLjava/util/zip/ZipFile$Source$End;-><init>(Ljava/util/zip/ZipFile$Source$End-IA;)V
 HSPLjava/util/zip/ZipFile$Source$Key;-><init>(Ljava/io/File;Ljava/nio/file/attribute/BasicFileAttributes;Ljava/util/zip/ZipCoder;Z)V
-HSPLjava/util/zip/ZipFile$Source$Key;->equals(Ljava/lang/Object;)Z
+HSPLjava/util/zip/ZipFile$Source$Key;->equals(Ljava/lang/Object;)Z+]Ljava/lang/Object;Lsun/nio/fs/UnixFileKey;]Ljava/nio/file/attribute/BasicFileAttributes;Lsun/nio/fs/UnixFileAttributes$UnixAsBasicFileAttributes;
 HSPLjava/util/zip/ZipFile$Source$Key;->hashCode()I
 HSPLjava/util/zip/ZipFile$Source;->-$$Nest$fgetlocpos(Ljava/util/zip/ZipFile$Source;)J
 HSPLjava/util/zip/ZipFile$Source;->-$$Nest$mgetEntryPos(Ljava/util/zip/ZipFile$Source;Ljava/lang/String;Z)I
@@ -30383,7 +30497,7 @@
 HSPLjava/util/zip/ZipFile$Source;->-$$Nest$mreadFullyAt(Ljava/util/zip/ZipFile$Source;[BIIJ)I
 HSPLjava/util/zip/ZipFile$Source;-><init>(Ljava/util/zip/ZipFile$Source$Key;ZLjava/util/zip/ZipCoder;)V
 HSPLjava/util/zip/ZipFile$Source;->checkAndAddEntry(II)I
-HSPLjava/util/zip/ZipFile$Source;->close()V
+HSPLjava/util/zip/ZipFile$Source;->close()V+]Ljava/io/RandomAccessFile;Ljava/io/RandomAccessFile;
 HSPLjava/util/zip/ZipFile$Source;->findEND()Ljava/util/zip/ZipFile$Source$End;
 HSPLjava/util/zip/ZipFile$Source;->get(Ljava/io/File;ZLjava/util/zip/ZipCoder;Z)Ljava/util/zip/ZipFile$Source;
 HSPLjava/util/zip/ZipFile$Source;->getEntryPos(Ljava/lang/String;Z)I
@@ -30393,9 +30507,9 @@
 HSPLjava/util/zip/ZipFile$Source;->isMetaName([BII)Z
 HSPLjava/util/zip/ZipFile$Source;->isSignatureRelated(II)Z
 HSPLjava/util/zip/ZipFile$Source;->nextEntryPos(III)I
-HSPLjava/util/zip/ZipFile$Source;->readAt([BIIJ)I
+HSPLjava/util/zip/ZipFile$Source;->readAt([BIIJ)I+]Ljava/io/RandomAccessFile;Ljava/io/RandomAccessFile;
 HSPLjava/util/zip/ZipFile$Source;->readFullyAt([BIIJ)I
-HSPLjava/util/zip/ZipFile$Source;->release(Ljava/util/zip/ZipFile$Source;)V
+HSPLjava/util/zip/ZipFile$Source;->release(Ljava/util/zip/ZipFile$Source;)V+]Ljava/util/HashMap;Ljava/util/HashMap;
 HSPLjava/util/zip/ZipFile$Source;->zipCoderForPos(I)Ljava/util/zip/ZipCoder;
 HSPLjava/util/zip/ZipFile$ZipEntryIterator;->hasMoreElements()Z
 HSPLjava/util/zip/ZipFile$ZipEntryIterator;->hasNext()Z
@@ -30770,10 +30884,10 @@
 HSPLjdk/internal/misc/VM;->getSavedProperty(Ljava/lang/String;)Ljava/lang/String;
 HSPLjdk/internal/ref/CleanerFactory;->cleaner()Ljava/lang/ref/Cleaner;
 HSPLjdk/internal/ref/CleanerImpl$PhantomCleanableRef;-><init>(Ljava/lang/Object;Ljava/lang/ref/Cleaner;Ljava/lang/Runnable;)V
-HSPLjdk/internal/ref/CleanerImpl$PhantomCleanableRef;->performCleanup()V
+HSPLjdk/internal/ref/CleanerImpl$PhantomCleanableRef;->performCleanup()V+]Ljava/lang/Runnable;megamorphic_types
 HSPLjdk/internal/ref/CleanerImpl;->getCleanerImpl(Ljava/lang/ref/Cleaner;)Ljdk/internal/ref/CleanerImpl;
 HSPLjdk/internal/ref/PhantomCleanable;-><init>(Ljava/lang/Object;Ljava/lang/ref/Cleaner;)V
-HSPLjdk/internal/ref/PhantomCleanable;->clean()V
+HSPLjdk/internal/ref/PhantomCleanable;->clean()V+]Ljdk/internal/ref/PhantomCleanable;Ljdk/internal/ref/CleanerImpl$PhantomCleanableRef;
 HSPLjdk/internal/ref/PhantomCleanable;->insert()V
 HSPLjdk/internal/ref/PhantomCleanable;->remove()Z
 HSPLjdk/internal/reflect/Reflection;->getCallerClass()Ljava/lang/Class;
@@ -30832,6 +30946,7 @@
 HSPLlibcore/icu/ICU;->localesFromStrings([Ljava/lang/String;)[Ljava/util/Locale;
 HSPLlibcore/icu/ICU;->parseLangScriptRegionAndVariants(Ljava/lang/String;[Ljava/lang/String;)V
 HSPLlibcore/icu/ICU;->setDefaultLocale(Ljava/lang/String;)V
+HSPLlibcore/icu/ICU;->transformIcuDateTimePattern(Ljava/lang/String;)Ljava/lang/String;
 HSPLlibcore/icu/ICU;->transformIcuDateTimePattern_forJavaText(Ljava/lang/String;)Ljava/lang/String;
 HSPLlibcore/icu/LocaleData;->get(Ljava/util/Locale;)Llibcore/icu/LocaleData;
 HSPLlibcore/icu/LocaleData;->getCompatibleLocaleForBug159514442(Ljava/util/Locale;)Ljava/util/Locale;
@@ -31122,7 +31237,6 @@
 HSPLlibcore/util/SneakyThrow;->sneakyThrow(Ljava/lang/Throwable;)V
 HSPLlibcore/util/SneakyThrow;->sneakyThrow_(Ljava/lang/Throwable;)V
 HSPLlibcore/util/XmlObjectFactory;->newXmlPullParser()Lorg/xmlpull/v1/XmlPullParser;
-HSPLlibcore/util/ZoneInfo;-><clinit>()V
 HSPLlibcore/util/ZoneInfo;-><init>(Lcom/android/i18n/timezone/ZoneInfoData;IZ)V
 HSPLlibcore/util/ZoneInfo;->clone()Ljava/lang/Object;
 HSPLlibcore/util/ZoneInfo;->createZoneInfo(Lcom/android/i18n/timezone/ZoneInfoData;)Llibcore/util/ZoneInfo;
@@ -31228,8 +31342,8 @@
 HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->getValue(I)Ljava/lang/String;
 HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->getValue(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->removeAttribute(I)V
-HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->setAttributes(Lorg/xml/sax/Attributes;)V+]Lorg/ccil/cowan/tagsoup/AttributesImpl;Lorg/ccil/cowan/tagsoup/AttributesImpl;]Lorg/xml/sax/Attributes;Lorg/ccil/cowan/tagsoup/AttributesImpl;
-HSPLorg/ccil/cowan/tagsoup/Element;-><init>(Lorg/ccil/cowan/tagsoup/ElementType;Z)V+]Lorg/ccil/cowan/tagsoup/ElementType;Lorg/ccil/cowan/tagsoup/ElementType;
+HSPLorg/ccil/cowan/tagsoup/AttributesImpl;->setAttributes(Lorg/xml/sax/Attributes;)V
+HSPLorg/ccil/cowan/tagsoup/Element;-><init>(Lorg/ccil/cowan/tagsoup/ElementType;Z)V
 HSPLorg/ccil/cowan/tagsoup/Element;->atts()Lorg/ccil/cowan/tagsoup/AttributesImpl;
 HSPLorg/ccil/cowan/tagsoup/Element;->canContain(Lorg/ccil/cowan/tagsoup/Element;)Z
 HSPLorg/ccil/cowan/tagsoup/Element;->clean()V
@@ -31258,10 +31372,10 @@
 HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->mark()V
 HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->resetDocumentLocator(Ljava/lang/String;Ljava/lang/String;)V
 HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->save(ILorg/ccil/cowan/tagsoup/ScanHandler;)V
-HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->scan(Ljava/io/Reader;Lorg/ccil/cowan/tagsoup/ScanHandler;)V+]Ljava/io/PushbackReader;Ljava/io/PushbackReader;]Lorg/ccil/cowan/tagsoup/ScanHandler;Lorg/ccil/cowan/tagsoup/Parser;
+HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->scan(Ljava/io/Reader;Lorg/ccil/cowan/tagsoup/ScanHandler;)V
 HSPLorg/ccil/cowan/tagsoup/HTMLScanner;->unread(Ljava/io/PushbackReader;I)V
 HSPLorg/ccil/cowan/tagsoup/Parser$1;-><init>(Lorg/ccil/cowan/tagsoup/Parser;)V
-HSPLorg/ccil/cowan/tagsoup/Parser;-><init>()V+]Ljava/util/HashMap;Ljava/util/HashMap;
+HSPLorg/ccil/cowan/tagsoup/Parser;-><init>()V
 HSPLorg/ccil/cowan/tagsoup/Parser;->aname([CII)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->aval([CII)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->entity([CII)V
@@ -31276,16 +31390,16 @@
 HSPLorg/ccil/cowan/tagsoup/Parser;->gi([CII)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->lookupEntity([CII)I
 HSPLorg/ccil/cowan/tagsoup/Parser;->makeName([CII)Ljava/lang/String;
-HSPLorg/ccil/cowan/tagsoup/Parser;->parse(Lorg/xml/sax/InputSource;)V+]Ljava/lang/Object;Ljava/lang/String;]Lorg/ccil/cowan/tagsoup/Scanner;Lorg/ccil/cowan/tagsoup/HTMLScanner;]Lorg/ccil/cowan/tagsoup/Schema;Lorg/ccil/cowan/tagsoup/HTMLSchema;]Lorg/xml/sax/ContentHandler;Landroid/text/HtmlToSpannedConverter;]Lorg/xml/sax/InputSource;Lorg/xml/sax/InputSource;
+HSPLorg/ccil/cowan/tagsoup/Parser;->parse(Lorg/xml/sax/InputSource;)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->pcdata([CII)V
-HSPLorg/ccil/cowan/tagsoup/Parser;->pop()V+]Lorg/ccil/cowan/tagsoup/Element;Lorg/ccil/cowan/tagsoup/Element;]Lorg/xml/sax/Attributes;Lorg/ccil/cowan/tagsoup/AttributesImpl;]Lorg/xml/sax/ContentHandler;Landroid/text/HtmlToSpannedConverter;
+HSPLorg/ccil/cowan/tagsoup/Parser;->pop()V
 HSPLorg/ccil/cowan/tagsoup/Parser;->prefixOf(Ljava/lang/String;)Ljava/lang/String;
-HSPLorg/ccil/cowan/tagsoup/Parser;->push(Lorg/ccil/cowan/tagsoup/Element;)V+]Ljava/lang/String;Ljava/lang/String;]Lorg/ccil/cowan/tagsoup/Element;Lorg/ccil/cowan/tagsoup/Element;]Lorg/xml/sax/Attributes;Lorg/ccil/cowan/tagsoup/AttributesImpl;]Lorg/xml/sax/ContentHandler;Landroid/text/HtmlToSpannedConverter;
-HSPLorg/ccil/cowan/tagsoup/Parser;->rectify(Lorg/ccil/cowan/tagsoup/Element;)V+]Ljava/lang/Object;Ljava/lang/String;]Lorg/ccil/cowan/tagsoup/Element;Lorg/ccil/cowan/tagsoup/Element;
+HSPLorg/ccil/cowan/tagsoup/Parser;->push(Lorg/ccil/cowan/tagsoup/Element;)V
+HSPLorg/ccil/cowan/tagsoup/Parser;->rectify(Lorg/ccil/cowan/tagsoup/Element;)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->restart(Lorg/ccil/cowan/tagsoup/Element;)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->setContentHandler(Lorg/xml/sax/ContentHandler;)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->setProperty(Ljava/lang/String;Ljava/lang/Object;)V
-HSPLorg/ccil/cowan/tagsoup/Parser;->setup()V+]Lorg/ccil/cowan/tagsoup/Schema;Lorg/ccil/cowan/tagsoup/HTMLSchema;
+HSPLorg/ccil/cowan/tagsoup/Parser;->setup()V
 HSPLorg/ccil/cowan/tagsoup/Parser;->stagc([CII)V
 HSPLorg/ccil/cowan/tagsoup/Parser;->truthValue(Z)Ljava/lang/Boolean;
 HSPLorg/ccil/cowan/tagsoup/Schema;->getElementType(Ljava/lang/String;)Lorg/ccil/cowan/tagsoup/ElementType;
@@ -31652,7 +31766,7 @@
 HSPLsun/nio/cs/StreamEncoder;->implClose()V
 HSPLsun/nio/cs/StreamEncoder;->implFlush()V
 HSPLsun/nio/cs/StreamEncoder;->implFlushBuffer()V
-HSPLsun/nio/cs/StreamEncoder;->implWrite(Ljava/nio/CharBuffer;)V
+HSPLsun/nio/cs/StreamEncoder;->implWrite(Ljava/nio/CharBuffer;)V+]Ljava/nio/charset/CoderResult;Ljava/nio/charset/CoderResult;
 HSPLsun/nio/cs/StreamEncoder;->implWrite([CII)V
 HSPLsun/nio/cs/StreamEncoder;->write(I)V
 HSPLsun/nio/cs/StreamEncoder;->write(Ljava/lang/String;II)V
@@ -31717,7 +31831,7 @@
 HSPLsun/nio/fs/UnixFileAttributeViews;->createBasicView(Lsun/nio/fs/UnixPath;Z)Lsun/nio/fs/UnixFileAttributeViews$Basic;
 HSPLsun/nio/fs/UnixFileAttributes$UnixAsBasicFileAttributes;-><init>(Lsun/nio/fs/UnixFileAttributes;)V
 HSPLsun/nio/fs/UnixFileAttributes$UnixAsBasicFileAttributes;->creationTime()Ljava/nio/file/attribute/FileTime;
-HSPLsun/nio/fs/UnixFileAttributes$UnixAsBasicFileAttributes;->fileKey()Ljava/lang/Object;
+HSPLsun/nio/fs/UnixFileAttributes$UnixAsBasicFileAttributes;->fileKey()Ljava/lang/Object;+]Lsun/nio/fs/UnixFileAttributes;Lsun/nio/fs/UnixFileAttributes;
 HSPLsun/nio/fs/UnixFileAttributes$UnixAsBasicFileAttributes;->isDirectory()Z
 HSPLsun/nio/fs/UnixFileAttributes$UnixAsBasicFileAttributes;->isRegularFile()Z
 HSPLsun/nio/fs/UnixFileAttributes$UnixAsBasicFileAttributes;->isSymbolicLink()Z
@@ -32108,7 +32222,7 @@
 HSPLsun/security/util/DerValue;->resetTag(B)V
 HSPLsun/security/util/DerValue;->toByteArray()[B
 HSPLsun/security/util/DerValue;->toDerInputStream()Lsun/security/util/DerInputStream;
-HSPLsun/security/util/DisabledAlgorithmConstraints$Constraints;-><init>([Ljava/lang/String;)V
+HPLsun/security/util/DisabledAlgorithmConstraints$Constraints;-><init>([Ljava/lang/String;)V
 HSPLsun/security/util/DisabledAlgorithmConstraints$Constraints;->getConstraints(Ljava/lang/String;)Ljava/util/Set;
 HSPLsun/security/util/DisabledAlgorithmConstraints$Constraints;->permits(Ljava/security/Key;)Z
 HSPLsun/security/util/DisabledAlgorithmConstraints$Constraints;->permits(Lsun/security/util/CertConstraintParameters;)V
@@ -32577,6 +32691,7 @@
 Landroid/accounts/AuthenticatorDescription-IA;
 Landroid/accounts/AuthenticatorDescription;
 Landroid/accounts/AuthenticatorException;
+Landroid/accounts/IAccountAuthenticator$Stub$Proxy;
 Landroid/accounts/IAccountAuthenticator$Stub;
 Landroid/accounts/IAccountAuthenticator;
 Landroid/accounts/IAccountAuthenticatorResponse$Stub$Proxy;
@@ -32585,6 +32700,7 @@
 Landroid/accounts/IAccountManager$Stub$Proxy;
 Landroid/accounts/IAccountManager$Stub;
 Landroid/accounts/IAccountManager;
+Landroid/accounts/IAccountManagerResponse$Stub$Proxy;
 Landroid/accounts/IAccountManagerResponse$Stub;
 Landroid/accounts/IAccountManagerResponse;
 Landroid/accounts/NetworkErrorException;
@@ -32713,6 +32829,7 @@
 Landroid/app/ActivityClient$ActivityClientControllerSingleton;
 Landroid/app/ActivityClient-IA;
 Landroid/app/ActivityClient;
+Landroid/app/ActivityManager$1;
 Landroid/app/ActivityManager$2;
 Landroid/app/ActivityManager$3;
 Landroid/app/ActivityManager$AppTask;
@@ -32745,7 +32862,6 @@
 Landroid/app/ActivityOptions$1;
 Landroid/app/ActivityOptions$2;
 Landroid/app/ActivityOptions$OnAnimationStartedListener;
-Landroid/app/ActivityOptions$SceneTransitionInfo$1;
 Landroid/app/ActivityOptions$SceneTransitionInfo;
 Landroid/app/ActivityOptions$SourceInfo$1;
 Landroid/app/ActivityOptions$SourceInfo;
@@ -32807,7 +32923,6 @@
 Landroid/app/AlertDialog$Builder;
 Landroid/app/AlertDialog;
 Landroid/app/AppCompatCallbacks;
-Landroid/app/AppCompatTaskInfo$1;
 Landroid/app/AppCompatTaskInfo;
 Landroid/app/AppComponentFactory;
 Landroid/app/AppDetailsActivity;
@@ -32820,6 +32935,7 @@
 Landroid/app/AppOpsManager$$ExternalSyntheticLambda5;
 Landroid/app/AppOpsManager$$ExternalSyntheticLambda6;
 Landroid/app/AppOpsManager$1;
+Landroid/app/AppOpsManager$2;
 Landroid/app/AppOpsManager$3;
 Landroid/app/AppOpsManager$4;
 Landroid/app/AppOpsManager$AppOpsCollector;
@@ -32896,11 +33012,9 @@
 Landroid/app/BackStackRecord;
 Landroid/app/BackStackState$1;
 Landroid/app/BackStackState;
-Landroid/app/BackgroundInstallControlManager;
 Landroid/app/BackgroundServiceStartNotAllowedException$1;
 Landroid/app/BackgroundServiceStartNotAllowedException;
 Landroid/app/BroadcastOptions;
-Landroid/app/CameraCompatTaskInfo;
 Landroid/app/ClientTransactionHandler;
 Landroid/app/ComponentCaller;
 Landroid/app/ComponentOptions;
@@ -33045,6 +33159,7 @@
 Landroid/app/IStopUserCallback$Stub$Proxy;
 Landroid/app/IStopUserCallback$Stub;
 Landroid/app/IStopUserCallback;
+Landroid/app/ITaskStackListener$Stub$Proxy;
 Landroid/app/ITaskStackListener$Stub;
 Landroid/app/ITaskStackListener;
 Landroid/app/ITransientNotification$Stub$Proxy;
@@ -33167,6 +33282,7 @@
 Landroid/app/PendingIntent$1;
 Landroid/app/PendingIntent$CancelListener;
 Landroid/app/PendingIntent$CanceledException;
+Landroid/app/PendingIntent$FinishedDispatcher;
 Landroid/app/PendingIntent$OnFinished;
 Landroid/app/PendingIntent$OnMarshaledListener;
 Landroid/app/PendingIntent;
@@ -33216,7 +33332,6 @@
 Landroid/app/ResourcesManager$ActivityResources;
 Landroid/app/ResourcesManager$ApkAssetsSupplier;
 Landroid/app/ResourcesManager$ApkKey;
-Landroid/app/ResourcesManager$SharedLibraryAssets;
 Landroid/app/ResourcesManager$UpdateHandler-IA;
 Landroid/app/ResourcesManager$UpdateHandler;
 Landroid/app/ResourcesManager;
@@ -33248,6 +33363,7 @@
 Landroid/app/SharedPreferencesImpl$MemoryCommitResult-IA;
 Landroid/app/SharedPreferencesImpl$MemoryCommitResult;
 Landroid/app/SharedPreferencesImpl$SharedPreferencesThreadFactory;
+Landroid/app/SharedPreferencesImpl;
 Landroid/app/StackTrace;
 Landroid/app/StatusBarManager;
 Landroid/app/SyncNotedAppOp$1;
@@ -33298,12 +33414,8 @@
 Landroid/app/SystemServiceRegistry$139;
 Landroid/app/SystemServiceRegistry$13;
 Landroid/app/SystemServiceRegistry$140;
-Landroid/app/SystemServiceRegistry$141;
-Landroid/app/SystemServiceRegistry$142;
 Landroid/app/SystemServiceRegistry$143;
 Landroid/app/SystemServiceRegistry$144;
-Landroid/app/SystemServiceRegistry$145;
-Landroid/app/SystemServiceRegistry$146;
 Landroid/app/SystemServiceRegistry$14;
 Landroid/app/SystemServiceRegistry$15;
 Landroid/app/SystemServiceRegistry$16;
@@ -33611,13 +33723,13 @@
 Landroid/app/contentsuggestions/SelectionsRequest$Builder;
 Landroid/app/contentsuggestions/SelectionsRequest-IA;
 Landroid/app/contentsuggestions/SelectionsRequest;
-Landroid/app/contextualsearch/ContextualSearchManager;
 Landroid/app/job/IJobCallback$Stub$Proxy;
 Landroid/app/job/IJobCallback$Stub;
 Landroid/app/job/IJobCallback;
 Landroid/app/job/IJobScheduler$Stub$Proxy;
 Landroid/app/job/IJobScheduler$Stub;
 Landroid/app/job/IJobScheduler;
+Landroid/app/job/IJobService$Stub$Proxy;
 Landroid/app/job/IJobService$Stub;
 Landroid/app/job/IJobService;
 Landroid/app/job/IUserVisibleJobObserver;
@@ -33636,14 +33748,15 @@
 Landroid/app/job/JobSchedulerFrameworkInitializer$$ExternalSyntheticLambda1;
 Landroid/app/job/JobSchedulerFrameworkInitializer$$ExternalSyntheticLambda2;
 Landroid/app/job/JobSchedulerFrameworkInitializer$$ExternalSyntheticLambda3;
+Landroid/app/job/JobSchedulerFrameworkInitializer$$ExternalSyntheticLambda4;
 Landroid/app/job/JobSchedulerFrameworkInitializer;
 Landroid/app/job/JobService$1;
 Landroid/app/job/JobService;
 Landroid/app/job/JobServiceEngine$JobHandler;
+Landroid/app/job/JobServiceEngine$JobInterface;
 Landroid/app/job/JobServiceEngine;
 Landroid/app/job/JobWorkItem$1;
 Landroid/app/job/JobWorkItem;
-Landroid/app/ondeviceintelligence/OnDeviceIntelligenceManager;
 Landroid/app/people/IPeopleManager$Stub$Proxy;
 Landroid/app/people/IPeopleManager$Stub;
 Landroid/app/people/IPeopleManager;
@@ -33723,6 +33836,7 @@
 Landroid/app/servertransaction/TopResumedActivityChangeItem;
 Landroid/app/servertransaction/TransactionExecutor;
 Landroid/app/servertransaction/TransactionExecutorHelper;
+Landroid/app/servertransaction/WindowStateResizeItem$ResizeListener;
 Landroid/app/slice/ISliceManager$Stub$Proxy;
 Landroid/app/slice/ISliceManager$Stub;
 Landroid/app/slice/ISliceManager;
@@ -33774,6 +33888,7 @@
 Landroid/app/smartspace/uitemplatedata/TapAction;
 Landroid/app/smartspace/uitemplatedata/Text$1;
 Landroid/app/smartspace/uitemplatedata/Text;
+Landroid/app/tare/EconomyManager;
 Landroid/app/time/ITimeZoneDetectorListener$Stub$Proxy;
 Landroid/app/time/ITimeZoneDetectorListener$Stub;
 Landroid/app/time/ITimeZoneDetectorListener;
@@ -33835,8 +33950,6 @@
 Landroid/app/usage/EventList;
 Landroid/app/usage/ExternalStorageStats$1;
 Landroid/app/usage/ExternalStorageStats;
-Landroid/app/usage/FeatureFlags;
-Landroid/app/usage/FeatureFlagsImpl;
 Landroid/app/usage/Flags;
 Landroid/app/usage/ICacheQuotaService$Stub$Proxy;
 Landroid/app/usage/ICacheQuotaService$Stub;
@@ -33876,8 +33989,6 @@
 Landroid/appwidget/AppWidgetProviderInfo;
 Landroid/appwidget/PendingHostUpdate$1;
 Landroid/appwidget/PendingHostUpdate;
-Landroid/appwidget/flags/FeatureFlags;
-Landroid/appwidget/flags/FeatureFlagsImpl;
 Landroid/appwidget/flags/Flags;
 Landroid/attention/AttentionManagerInternal$AttentionCallbackInternal;
 Landroid/attention/AttentionManagerInternal;
@@ -33896,7 +34007,6 @@
 Landroid/companion/virtual/IVirtualDeviceManager$Stub$Proxy;
 Landroid/companion/virtual/IVirtualDeviceManager$Stub;
 Landroid/companion/virtual/IVirtualDeviceManager;
-Landroid/companion/virtual/VirtualDevice;
 Landroid/companion/virtual/VirtualDeviceManager;
 Landroid/companion/virtual/flags/FeatureFlags;
 Landroid/companion/virtual/flags/FeatureFlagsImpl;
@@ -33948,8 +34058,8 @@
 Landroid/content/ComponentName$WithComponentName;
 Landroid/content/ComponentName;
 Landroid/content/ContentCaptureOptions$1;
+Landroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda0;
 Landroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda1;
-Landroid/content/ContentCaptureOptions$ContentProtectionOptions$$ExternalSyntheticLambda2;
 Landroid/content/ContentCaptureOptions$ContentProtectionOptions;
 Landroid/content/ContentCaptureOptions;
 Landroid/content/ContentInterface;
@@ -33970,10 +34080,12 @@
 Landroid/content/ContentProviderOperation$Builder;
 Landroid/content/ContentProviderOperation-IA;
 Landroid/content/ContentProviderOperation;
+Landroid/content/ContentProviderProxy;
 Landroid/content/ContentProviderResult$1;
 Landroid/content/ContentProviderResult;
 Landroid/content/ContentResolver$1;
 Landroid/content/ContentResolver$2;
+Landroid/content/ContentResolver$CursorWrapperInner;
 Landroid/content/ContentResolver$OpenResourceIdResult;
 Landroid/content/ContentResolver$ParcelFileDescriptorInner;
 Landroid/content/ContentResolver$ResultListener-IA;
@@ -34025,6 +34137,7 @@
 Landroid/content/ISyncContext$Stub$Proxy;
 Landroid/content/ISyncContext$Stub;
 Landroid/content/ISyncContext;
+Landroid/content/ISyncStatusObserver$Stub$Proxy;
 Landroid/content/ISyncStatusObserver$Stub;
 Landroid/content/ISyncStatusObserver;
 Landroid/content/Intent$1;
@@ -34127,7 +34240,6 @@
 Landroid/content/pm/ApplicationInfo$1;
 Landroid/content/pm/ApplicationInfo-IA;
 Landroid/content/pm/ApplicationInfo;
-Landroid/content/pm/ArchivedPackageParcel$1;
 Landroid/content/pm/ArchivedPackageParcel;
 Landroid/content/pm/Attribution$1;
 Landroid/content/pm/Attribution;
@@ -34151,6 +34263,8 @@
 Landroid/content/pm/DataLoaderParamsParcel$1;
 Landroid/content/pm/DataLoaderParamsParcel;
 Landroid/content/pm/FallbackCategoryProvider;
+Landroid/content/pm/FeatureFlags;
+Landroid/content/pm/FeatureFlagsImpl;
 Landroid/content/pm/FeatureGroupInfo$1;
 Landroid/content/pm/FeatureGroupInfo;
 Landroid/content/pm/FeatureInfo$1;
@@ -34158,6 +34272,7 @@
 Landroid/content/pm/FeatureInfo;
 Landroid/content/pm/FileSystemControlParcel$1;
 Landroid/content/pm/FileSystemControlParcel;
+Landroid/content/pm/Flags;
 Landroid/content/pm/ICrossProfileApps$Stub$Proxy;
 Landroid/content/pm/ICrossProfileApps$Stub;
 Landroid/content/pm/ICrossProfileApps;
@@ -34174,6 +34289,7 @@
 Landroid/content/pm/ILauncherApps$Stub$Proxy;
 Landroid/content/pm/ILauncherApps$Stub;
 Landroid/content/pm/ILauncherApps;
+Landroid/content/pm/IOnAppsChangedListener$Stub$Proxy;
 Landroid/content/pm/IOnAppsChangedListener$Stub;
 Landroid/content/pm/IOnAppsChangedListener;
 Landroid/content/pm/IOnChecksumsReadyListener$Stub$Proxy;
@@ -34541,7 +34657,6 @@
 Landroid/content/type/DefaultMimeMapFactory$$ExternalSyntheticLambda0;
 Landroid/content/type/DefaultMimeMapFactory;
 Landroid/credentials/CredentialManager;
-Landroid/credentials/GetCredentialResponse$1;
 Landroid/credentials/GetCredentialResponse;
 Landroid/database/AbstractCursor$SelfContentObserver;
 Landroid/database/AbstractCursor;
@@ -34606,6 +34721,7 @@
 Landroid/database/sqlite/SQLiteConnectionPool$IdleConnectionHandler;
 Landroid/database/sqlite/SQLiteConnectionPool;
 Landroid/database/sqlite/SQLiteConstraintException;
+Landroid/database/sqlite/SQLiteCursor;
 Landroid/database/sqlite/SQLiteCursorDriver;
 Landroid/database/sqlite/SQLiteCustomFunction;
 Landroid/database/sqlite/SQLiteDatabase$$ExternalSyntheticLambda0;
@@ -34778,7 +34894,6 @@
 Landroid/graphics/LinearGradient;
 Landroid/graphics/MaskFilter;
 Landroid/graphics/Matrix$1;
-Landroid/graphics/Matrix$ExtraNatives;
 Landroid/graphics/Matrix$NoImagePreloadHolder;
 Landroid/graphics/Matrix$ScaleToFit;
 Landroid/graphics/Matrix;
@@ -34802,7 +34917,6 @@
 Landroid/graphics/PaintFlagsDrawFilter;
 Landroid/graphics/Path$Direction;
 Landroid/graphics/Path$FillType;
-Landroid/graphics/Path$NoImagePreloadHolder;
 Landroid/graphics/Path$Op;
 Landroid/graphics/Path;
 Landroid/graphics/PathDashPathEffect;
@@ -35013,7 +35127,6 @@
 Landroid/graphics/drawable/shapes/RoundRectShape;
 Landroid/graphics/drawable/shapes/Shape;
 Landroid/graphics/fonts/Font$Builder;
-Landroid/graphics/fonts/Font$NoImagePreloadHolder;
 Landroid/graphics/fonts/Font;
 Landroid/graphics/fonts/FontCustomizationParser$Result;
 Landroid/graphics/fonts/FontCustomizationParser;
@@ -35058,7 +35171,6 @@
 Landroid/hardware/CameraStatus$1;
 Landroid/hardware/CameraStatus;
 Landroid/hardware/ConsumerIrManager;
-Landroid/hardware/DataSpace;
 Landroid/hardware/GeomagneticField$LegendreTable;
 Landroid/hardware/GeomagneticField;
 Landroid/hardware/HardwareBuffer$1;
@@ -35106,6 +35218,7 @@
 Landroid/hardware/SystemSensorManager$BaseEventQueue;
 Landroid/hardware/SystemSensorManager$SensorEventQueue;
 Landroid/hardware/SystemSensorManager$TriggerEventQueue;
+Landroid/hardware/SystemSensorManager;
 Landroid/hardware/TriggerEvent;
 Landroid/hardware/TriggerEventListener;
 Landroid/hardware/biometrics/BiometricAuthenticator$AuthenticationCallback;
@@ -35172,10 +35285,13 @@
 Landroid/hardware/camera2/CameraDevice$StateCallback;
 Landroid/hardware/camera2/CameraDevice;
 Landroid/hardware/camera2/CameraManager$AvailabilityCallback;
-Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$$ExternalSyntheticLambda0;
 Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$$ExternalSyntheticLambda2;
 Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$1;
-Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$DeviceCameraInfo;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$3;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$4;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$5;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$6;
+Landroid/hardware/camera2/CameraManager$CameraManagerGlobal$7;
 Landroid/hardware/camera2/CameraManager$CameraManagerGlobal;
 Landroid/hardware/camera2/CameraManager$DeviceStateListener;
 Landroid/hardware/camera2/CameraManager$FoldStateListener$$ExternalSyntheticLambda0;
@@ -35332,7 +35448,6 @@
 Landroid/hardware/contexthub/V1_0/NanoAppBinary;
 Landroid/hardware/contexthub/V1_0/PhysicalSensor;
 Landroid/hardware/contexthub/V1_1/Setting;
-Landroid/hardware/devicestate/DeviceState$Configuration;
 Landroid/hardware/devicestate/DeviceState;
 Landroid/hardware/devicestate/DeviceStateInfo$1;
 Landroid/hardware/devicestate/DeviceStateInfo;
@@ -35447,9 +35562,12 @@
 Landroid/hardware/fingerprint/Fingerprint;
 Landroid/hardware/fingerprint/FingerprintManager$1;
 Landroid/hardware/fingerprint/FingerprintManager$2;
+Landroid/hardware/fingerprint/FingerprintManager$3;
 Landroid/hardware/fingerprint/FingerprintManager$AuthenticationCallback;
 Landroid/hardware/fingerprint/FingerprintManager$AuthenticationResult;
 Landroid/hardware/fingerprint/FingerprintManager$LockoutResetCallback;
+Landroid/hardware/fingerprint/FingerprintManager$MyHandler-IA;
+Landroid/hardware/fingerprint/FingerprintManager$MyHandler;
 Landroid/hardware/fingerprint/FingerprintManager;
 Landroid/hardware/fingerprint/FingerprintSensorPropertiesInternal$1;
 Landroid/hardware/fingerprint/FingerprintSensorPropertiesInternal;
@@ -35935,9 +36053,13 @@
 Landroid/icu/impl/CalType;
 Landroid/icu/impl/CalendarAstronomer$1;
 Landroid/icu/impl/CalendarAstronomer$2;
+Landroid/icu/impl/CalendarAstronomer$3;
+Landroid/icu/impl/CalendarAstronomer$4;
 Landroid/icu/impl/CalendarAstronomer$AngleFunc;
+Landroid/icu/impl/CalendarAstronomer$CoordFunc;
 Landroid/icu/impl/CalendarAstronomer$Ecliptic;
 Landroid/icu/impl/CalendarAstronomer$Equatorial;
+Landroid/icu/impl/CalendarAstronomer$Horizon;
 Landroid/icu/impl/CalendarAstronomer$MoonAge;
 Landroid/icu/impl/CalendarAstronomer$SolarLongitude;
 Landroid/icu/impl/CalendarAstronomer;
@@ -35974,7 +36096,6 @@
 Landroid/icu/impl/DayPeriodRules-IA;
 Landroid/icu/impl/DayPeriodRules;
 Landroid/icu/impl/DontCareFieldPosition;
-Landroid/icu/impl/EmojiProps$IsAcceptable;
 Landroid/icu/impl/EmojiProps;
 Landroid/icu/impl/EraRules;
 Landroid/icu/impl/FormattedStringBuilder$FieldWrapper;
@@ -36250,8 +36371,6 @@
 Landroid/icu/impl/UCharacterProperty$25;
 Landroid/icu/impl/UCharacterProperty$26;
 Landroid/icu/impl/UCharacterProperty$27;
-Landroid/icu/impl/UCharacterProperty$28;
-Landroid/icu/impl/UCharacterProperty$29;
 Landroid/icu/impl/UCharacterProperty$2;
 Landroid/icu/impl/UCharacterProperty$3;
 Landroid/icu/impl/UCharacterProperty$4;
@@ -36269,7 +36388,6 @@
 Landroid/icu/impl/UCharacterProperty$IsAcceptable;
 Landroid/icu/impl/UCharacterProperty$LayoutProps$IsAcceptable;
 Landroid/icu/impl/UCharacterProperty$LayoutProps;
-Landroid/icu/impl/UCharacterProperty$MathCompatBinaryProperty;
 Landroid/icu/impl/UCharacterProperty$NormInertBinaryProperty;
 Landroid/icu/impl/UCharacterProperty$NormQuickCheckIntProperty;
 Landroid/icu/impl/UCharacterProperty;
@@ -36454,15 +36572,8 @@
 Landroid/icu/impl/locale/KeyTypeData$TypeInfoType;
 Landroid/icu/impl/locale/KeyTypeData$ValueType;
 Landroid/icu/impl/locale/KeyTypeData;
-Landroid/icu/impl/locale/LSR$CachedDecoder$$ExternalSyntheticLambda0;
-Landroid/icu/impl/locale/LSR$CachedDecoder$$ExternalSyntheticLambda1;
-Landroid/icu/impl/locale/LSR$CachedDecoder$$ExternalSyntheticLambda2;
-Landroid/icu/impl/locale/LSR$CachedDecoder;
 Landroid/icu/impl/locale/LSR;
 Landroid/icu/impl/locale/LanguageTag;
-Landroid/icu/impl/locale/LikelySubtags$1;
-Landroid/icu/impl/locale/LikelySubtags$Data;
-Landroid/icu/impl/locale/LikelySubtags;
 Landroid/icu/impl/locale/LocaleDistance$Data;
 Landroid/icu/impl/locale/LocaleDistance;
 Landroid/icu/impl/locale/LocaleExtensions;
@@ -36493,6 +36604,9 @@
 Landroid/icu/impl/locale/XCldrStub$Splitter;
 Landroid/icu/impl/locale/XCldrStub$TreeMultimap;
 Landroid/icu/impl/locale/XCldrStub;
+Landroid/icu/impl/locale/XLikelySubtags$1;
+Landroid/icu/impl/locale/XLikelySubtags$Data;
+Landroid/icu/impl/locale/XLikelySubtags;
 Landroid/icu/impl/number/AdoptingModifierStore$1;
 Landroid/icu/impl/number/AdoptingModifierStore;
 Landroid/icu/impl/number/AffixPatternProvider$Flags;
@@ -36623,7 +36737,6 @@
 Landroid/icu/lang/UCharacter$EastAsianWidth;
 Landroid/icu/lang/UCharacter$GraphemeClusterBreak;
 Landroid/icu/lang/UCharacter$HangulSyllableType;
-Landroid/icu/lang/UCharacter$IdentifierType;
 Landroid/icu/lang/UCharacter$IndicPositionalCategory;
 Landroid/icu/lang/UCharacter$IndicSyllabicCategory;
 Landroid/icu/lang/UCharacter$JoiningGroup;
@@ -37169,7 +37282,6 @@
 Landroid/icu/text/Transform;
 Landroid/icu/text/TransliterationRule;
 Landroid/icu/text/TransliterationRuleSet;
-Landroid/icu/text/Transliterator$$ExternalSyntheticLambda0;
 Landroid/icu/text/Transliterator$Factory;
 Landroid/icu/text/Transliterator$Position;
 Landroid/icu/text/Transliterator;
@@ -37216,7 +37328,6 @@
 Landroid/icu/text/UnicodeSet$EntryRangeIterator;
 Landroid/icu/text/UnicodeSet$Filter;
 Landroid/icu/text/UnicodeSet$GeneralCategoryMaskFilter;
-Landroid/icu/text/UnicodeSet$IdentifierTypeFilter;
 Landroid/icu/text/UnicodeSet$IntPropertyFilter;
 Landroid/icu/text/UnicodeSet$NumericValueFilter;
 Landroid/icu/text/UnicodeSet$ScriptExtensionsFilter;
@@ -37323,12 +37434,7 @@
 Landroid/icu/util/IllformedLocaleException;
 Landroid/icu/util/IndianCalendar;
 Landroid/icu/util/InitialTimeZoneRule;
-Landroid/icu/util/IslamicCalendar$Algorithm;
 Landroid/icu/util/IslamicCalendar$CalculationType;
-Landroid/icu/util/IslamicCalendar$CivilAlgorithm;
-Landroid/icu/util/IslamicCalendar$IslamicAlgorithm;
-Landroid/icu/util/IslamicCalendar$TBLAAlgorithm;
-Landroid/icu/util/IslamicCalendar$UmalquraAlgorithm;
 Landroid/icu/util/IslamicCalendar;
 Landroid/icu/util/JapaneseCalendar;
 Landroid/icu/util/LocaleData$MeasurementSystem;
@@ -37678,8 +37784,6 @@
 Landroid/media/ImageWriter$WriterSurfaceImage;
 Landroid/media/ImageWriter;
 Landroid/media/JetPlayer;
-Landroid/media/MediaCodec$$ExternalSyntheticLambda6;
-Landroid/media/MediaCodec$$ExternalSyntheticLambda7;
 Landroid/media/MediaCodec$BufferInfo;
 Landroid/media/MediaCodec$BufferMap$CodecBuffer-IA;
 Landroid/media/MediaCodec$BufferMap$CodecBuffer;
@@ -37904,8 +38008,6 @@
 Landroid/media/VolumeShaper$State$1;
 Landroid/media/VolumeShaper$State;
 Landroid/media/VolumeShaper;
-Landroid/media/audio/FeatureFlags;
-Landroid/media/audio/FeatureFlagsImpl;
 Landroid/media/audio/Flags;
 Landroid/media/audio/common/AidlConversion;
 Landroid/media/audio/common/HeadTracking$SensorData$Tag;
@@ -38354,7 +38456,6 @@
 Landroid/net/wifi/nl80211/WifiNl80211Manager$SignalPollResult;
 Landroid/net/wifi/nl80211/WifiNl80211Manager;
 Landroid/net/wifi/sharedconnectivity/app/SharedConnectivityManager;
-Landroid/nfc/NfcAdapter;
 Landroid/nfc/NfcFrameworkInitializer$$ExternalSyntheticLambda0;
 Landroid/nfc/NfcFrameworkInitializer;
 Landroid/nfc/NfcManager;
@@ -38605,6 +38706,7 @@
 Landroid/os/IIncidentManager$Stub$Proxy;
 Landroid/os/IIncidentManager$Stub;
 Landroid/os/IIncidentManager;
+Landroid/os/IInstalld$Stub$Proxy;
 Landroid/os/IInstalld$Stub;
 Landroid/os/IInstalld;
 Landroid/os/IInterface;
@@ -38827,6 +38929,7 @@
 Landroid/os/StrictMode$2;
 Landroid/os/StrictMode$3;
 Landroid/os/StrictMode$4;
+Landroid/os/StrictMode$5;
 Landroid/os/StrictMode$6;
 Landroid/os/StrictMode$7;
 Landroid/os/StrictMode$8;
@@ -38857,6 +38960,7 @@
 Landroid/os/SynchronousResultReceiver$Result;
 Landroid/os/SynchronousResultReceiver;
 Landroid/os/SystemClock$2;
+Landroid/os/SystemClock$3;
 Landroid/os/SystemClock;
 Landroid/os/SystemConfigManager;
 Landroid/os/SystemProperties$Handle-IA;
@@ -39015,8 +39119,6 @@
 Landroid/os/strictmode/UntaggedSocketViolation;
 Landroid/os/strictmode/Violation;
 Landroid/os/strictmode/WebViewMethodCalledOnWrongThreadViolation;
-Landroid/os/vibrator/FeatureFlags;
-Landroid/os/vibrator/FeatureFlagsImpl;
 Landroid/os/vibrator/Flags;
 Landroid/os/vibrator/PrebakedSegment$1;
 Landroid/os/vibrator/PrebakedSegment;
@@ -39050,13 +39152,15 @@
 Landroid/permission/PermissionControllerManager;
 Landroid/permission/PermissionManager$1;
 Landroid/permission/PermissionManager$2;
-Landroid/permission/PermissionManager$OnPermissionsChangeListenerDelegate;
 Landroid/permission/PermissionManager$PackageNamePermissionQuery;
 Landroid/permission/PermissionManager$PermissionQuery;
 Landroid/permission/PermissionManager$SplitPermissionInfo-IA;
 Landroid/permission/PermissionManager$SplitPermissionInfo;
 Landroid/permission/PermissionManager;
 Landroid/permission/PermissionManagerInternal;
+Landroid/permission/flags/FeatureFlags;
+Landroid/permission/flags/FeatureFlagsImpl;
+Landroid/permission/flags/Flags;
 Landroid/preference/DialogPreference;
 Landroid/preference/GenericInflater$Parent;
 Landroid/preference/GenericInflater;
@@ -39285,6 +39389,7 @@
 Landroid/security/KeyStore2$$ExternalSyntheticLambda8;
 Landroid/security/KeyStore2$CheckedRemoteRequest;
 Landroid/security/KeyStore2;
+Landroid/security/KeyStore;
 Landroid/security/KeyStoreException$PublicErrorInformation;
 Landroid/security/KeyStoreException;
 Landroid/security/KeyStoreOperation$$ExternalSyntheticLambda0;
@@ -39455,8 +39560,6 @@
 Landroid/service/autofill/AutofillServiceInfo;
 Landroid/service/autofill/Dataset$1;
 Landroid/service/autofill/Dataset;
-Landroid/service/autofill/FeatureFlags;
-Landroid/service/autofill/FeatureFlagsImpl;
 Landroid/service/autofill/FieldClassificationUserData;
 Landroid/service/autofill/FillContext$1;
 Landroid/service/autofill/FillContext;
@@ -39593,7 +39696,6 @@
 Landroid/service/media/MediaBrowserService$ServiceBinder$$ExternalSyntheticLambda1;
 Landroid/service/media/MediaBrowserService$ServiceBinder-IA;
 Landroid/service/media/MediaBrowserService$ServiceBinder;
-Landroid/service/media/MediaBrowserService$ServiceState-IA;
 Landroid/service/media/MediaBrowserService$ServiceState;
 Landroid/service/media/MediaBrowserService;
 Landroid/service/notification/Adjustment$1;
@@ -39632,7 +39734,6 @@
 Landroid/service/notification/SnoozeCriterion;
 Landroid/service/notification/StatusBarNotification$1;
 Landroid/service/notification/StatusBarNotification;
-Landroid/service/notification/ZenDeviceEffects$1;
 Landroid/service/notification/ZenDeviceEffects;
 Landroid/service/notification/ZenModeConfig$1;
 Landroid/service/notification/ZenModeConfig$EventInfo;
@@ -40046,6 +40147,7 @@
 Landroid/telephony/ICellInfoCallback$Stub$Proxy;
 Landroid/telephony/ICellInfoCallback$Stub;
 Landroid/telephony/ICellInfoCallback;
+Landroid/telephony/INetworkService$Stub$Proxy;
 Landroid/telephony/INetworkService$Stub;
 Landroid/telephony/INetworkService;
 Landroid/telephony/INetworkServiceCallback$Stub$Proxy;
@@ -40081,6 +40183,7 @@
 Landroid/telephony/NetworkScan;
 Landroid/telephony/NetworkScanRequest$1;
 Landroid/telephony/NetworkScanRequest;
+Landroid/telephony/NetworkService$INetworkServiceWrapper;
 Landroid/telephony/NetworkService$NetworkServiceHandler;
 Landroid/telephony/NetworkService$NetworkServiceProvider;
 Landroid/telephony/NetworkService;
@@ -40217,7 +40320,6 @@
 Landroid/telephony/TelephonyCallback$CallForwardingIndicatorListener;
 Landroid/telephony/TelephonyCallback$CallStateListener;
 Landroid/telephony/TelephonyCallback$CarrierNetworkListener;
-Landroid/telephony/TelephonyCallback$CarrierRoamingNtnModeListener;
 Landroid/telephony/TelephonyCallback$CellInfoListener;
 Landroid/telephony/TelephonyCallback$CellLocationListener;
 Landroid/telephony/TelephonyCallback$DataActivationStateListener;
@@ -40518,6 +40620,7 @@
 Landroid/telephony/ims/aidl/IImsConfigCallback$Stub$Proxy;
 Landroid/telephony/ims/aidl/IImsConfigCallback$Stub;
 Landroid/telephony/ims/aidl/IImsConfigCallback;
+Landroid/telephony/ims/aidl/IImsMmTelFeature$Stub$Proxy;
 Landroid/telephony/ims/aidl/IImsMmTelFeature$Stub;
 Landroid/telephony/ims/aidl/IImsMmTelFeature;
 Landroid/telephony/ims/aidl/IImsMmTelListener$Stub$Proxy;
@@ -40527,6 +40630,7 @@
 Landroid/telephony/ims/aidl/IImsRcsController;
 Landroid/telephony/ims/aidl/IImsRcsFeature$Stub;
 Landroid/telephony/ims/aidl/IImsRcsFeature;
+Landroid/telephony/ims/aidl/IImsRegistration$Stub$Proxy;
 Landroid/telephony/ims/aidl/IImsRegistration$Stub;
 Landroid/telephony/ims/aidl/IImsRegistration;
 Landroid/telephony/ims/aidl/IImsRegistrationCallback$Stub$Proxy;
@@ -40665,7 +40769,6 @@
 Landroid/text/Layout$TabStops;
 Landroid/text/Layout$TextInclusionStrategy;
 Landroid/text/Layout;
-Landroid/text/MeasuredParagraph$StyleRunCallback;
 Landroid/text/MeasuredParagraph;
 Landroid/text/NoCopySpan$Concrete;
 Landroid/text/NoCopySpan;
@@ -40706,7 +40809,6 @@
 Landroid/text/TextFlags;
 Landroid/text/TextLine$DecorationInfo-IA;
 Landroid/text/TextLine$DecorationInfo;
-Landroid/text/TextLine$LineInfo;
 Landroid/text/TextLine;
 Landroid/text/TextPaint;
 Landroid/text/TextShaper$GlyphsConsumer;
@@ -40791,7 +40893,6 @@
 Landroid/text/style/LeadingMarginSpan;
 Landroid/text/style/LineBackgroundSpan$Standard;
 Landroid/text/style/LineBackgroundSpan;
-Landroid/text/style/LineBreakConfigSpan$1;
 Landroid/text/style/LineBreakConfigSpan;
 Landroid/text/style/LineHeightSpan$Standard;
 Landroid/text/style/LineHeightSpan$WithDensity;
@@ -40845,7 +40946,6 @@
 Landroid/timezone/TelephonyNetwork;
 Landroid/timezone/TelephonyNetworkFinder;
 Landroid/timezone/TimeZoneFinder;
-Landroid/tracing/Flags;
 Landroid/tracing/perfetto/CreateIncrementalStateArgs;
 Landroid/tracing/perfetto/CreateTlsStateArgs;
 Landroid/tracing/perfetto/DataSource;
@@ -41045,6 +41145,7 @@
 Landroid/util/SparseLongArray;
 Landroid/util/SparseSetArray;
 Landroid/util/Spline$LinearSpline;
+Landroid/util/Spline$MonotoneCubicSpline;
 Landroid/util/Spline;
 Landroid/util/StateSet;
 Landroid/util/StringBuilderPrinter;
@@ -41271,7 +41372,6 @@
 Landroid/view/IScrollCaptureResponseListener$Stub$Proxy;
 Landroid/view/IScrollCaptureResponseListener$Stub;
 Landroid/view/IScrollCaptureResponseListener;
-Landroid/view/ISensitiveContentProtectionManager$Stub$Proxy;
 Landroid/view/ISensitiveContentProtectionManager$Stub;
 Landroid/view/ISensitiveContentProtectionManager;
 Landroid/view/ISurfaceControlViewHost;
@@ -41298,7 +41398,6 @@
 Landroid/view/IWindowSessionCallback$Stub$Proxy;
 Landroid/view/IWindowSessionCallback$Stub;
 Landroid/view/IWindowSessionCallback;
-Landroid/view/ImeBackAnimationController;
 Landroid/view/ImeFocusController$InputMethodManagerDelegate;
 Landroid/view/ImeFocusController;
 Landroid/view/ImeInsetsSourceConsumer;
@@ -41360,6 +41459,7 @@
 Landroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda3;
 Landroid/view/InsetsController$InternalAnimationControlListener$$ExternalSyntheticLambda4;
 Landroid/view/InsetsController$InternalAnimationControlListener$1;
+Landroid/view/InsetsController$InternalAnimationControlListener$2;
 Landroid/view/InsetsController$InternalAnimationControlListener;
 Landroid/view/InsetsController$PendingControlRequest;
 Landroid/view/InsetsController$RunningAnimation;
@@ -41448,7 +41548,6 @@
 Landroid/view/ScaleGestureDetector$OnScaleGestureListener;
 Landroid/view/ScaleGestureDetector$SimpleOnScaleGestureListener;
 Landroid/view/ScaleGestureDetector;
-Landroid/view/ScrollCaptureSearchResults$$ExternalSyntheticLambda0;
 Landroid/view/ScrollCaptureSearchResults;
 Landroid/view/ScrollFeedbackProvider;
 Landroid/view/SearchEvent;
@@ -41467,7 +41566,6 @@
 Landroid/view/SurfaceControl$DisplayMode;
 Landroid/view/SurfaceControl$DisplayPrimaries;
 Landroid/view/SurfaceControl$DynamicDisplayInfo;
-Landroid/view/SurfaceControl$IdleScreenRefreshRateConfig;
 Landroid/view/SurfaceControl$JankData;
 Landroid/view/SurfaceControl$OnJankDataListener;
 Landroid/view/SurfaceControl$OnReparentListener;
@@ -41776,14 +41874,12 @@
 Landroid/view/WindowManagerGlobal$$ExternalSyntheticLambda0;
 Landroid/view/WindowManagerGlobal$1;
 Landroid/view/WindowManagerGlobal$2;
-Landroid/view/WindowManagerGlobal$TrustedPresentationListener-IA;
 Landroid/view/WindowManagerGlobal$TrustedPresentationListener;
 Landroid/view/WindowManagerGlobal;
 Landroid/view/WindowManagerImpl;
 Landroid/view/WindowManagerPolicyConstants$PointerEventListener;
 Landroid/view/WindowManagerPolicyConstants;
 Landroid/view/WindowMetrics;
-Landroid/view/WindowRelayoutResult;
 Landroid/view/WindowlessWindowLayout;
 Landroid/view/WindowlessWindowManager;
 Landroid/view/accessibility/AccessibilityCache$AccessibilityNodeRefresher;
@@ -41827,8 +41923,6 @@
 Landroid/view/accessibility/CaptioningManager$MyContentObserver;
 Landroid/view/accessibility/CaptioningManager;
 Landroid/view/accessibility/DirectAccessibilityConnection;
-Landroid/view/accessibility/FeatureFlags;
-Landroid/view/accessibility/FeatureFlagsImpl;
 Landroid/view/accessibility/Flags;
 Landroid/view/accessibility/IAccessibilityEmbeddedConnection;
 Landroid/view/accessibility/IAccessibilityInteractionConnection$Stub$Proxy;
@@ -41954,6 +42048,7 @@
 Landroid/view/contentcapture/IContentCaptureManager;
 Landroid/view/contentcapture/IContentCaptureOptionsCallback$Stub;
 Landroid/view/contentcapture/IContentCaptureOptionsCallback;
+Landroid/view/contentcapture/IDataShareWriteAdapter$Stub$Proxy;
 Landroid/view/contentcapture/IDataShareWriteAdapter$Stub;
 Landroid/view/contentcapture/IDataShareWriteAdapter;
 Landroid/view/contentcapture/MainContentCaptureSession$$ExternalSyntheticLambda0;
@@ -42008,8 +42103,6 @@
 Landroid/view/inputmethod/ExtractedText;
 Landroid/view/inputmethod/ExtractedTextRequest$1;
 Landroid/view/inputmethod/ExtractedTextRequest;
-Landroid/view/inputmethod/FeatureFlags;
-Landroid/view/inputmethod/FeatureFlagsImpl;
 Landroid/view/inputmethod/Flags;
 Landroid/view/inputmethod/HandwritingGesture;
 Landroid/view/inputmethod/IAccessibilityInputMethodSessionInvoker$$ExternalSyntheticLambda0;
@@ -42610,7 +42703,6 @@
 Landroid/widget/RemoteViews$BitmapCache;
 Landroid/widget/RemoteViews$BitmapReflectionAction;
 Landroid/widget/RemoteViews$ComplexUnitDimensionReflectionAction;
-Landroid/widget/RemoteViews$DrawInstructions;
 Landroid/widget/RemoteViews$HierarchyRootData;
 Landroid/widget/RemoteViews$InteractionHandler;
 Landroid/widget/RemoteViews$LayoutParamAction;
@@ -42769,12 +42861,10 @@
 Landroid/widget/ViewFlipper;
 Landroid/widget/ViewSwitcher;
 Landroid/widget/WrapperListAdapter;
-Landroid/widget/flags/Flags;
 Landroid/widget/inline/InlinePresentationSpec$1;
 Landroid/widget/inline/InlinePresentationSpec$BaseBuilder;
 Landroid/widget/inline/InlinePresentationSpec$Builder;
 Landroid/widget/inline/InlinePresentationSpec;
-Landroid/window/ActivityWindowInfo$1;
 Landroid/window/ActivityWindowInfo;
 Landroid/window/BackAnimationAdapter$1;
 Landroid/window/BackAnimationAdapter;
@@ -42783,12 +42873,9 @@
 Landroid/window/BackMotionEvent;
 Landroid/window/BackNavigationInfo$1;
 Landroid/window/BackNavigationInfo;
-Landroid/window/BackProgressAnimator$$ExternalSyntheticLambda0;
 Landroid/window/BackProgressAnimator$1;
 Landroid/window/BackProgressAnimator$ProgressCallback;
 Landroid/window/BackProgressAnimator;
-Landroid/window/BackTouchTracker$TouchTrackerState;
-Landroid/window/BackTouchTracker;
 Landroid/window/ClientWindowFrames$1;
 Landroid/window/ClientWindowFrames-IA;
 Landroid/window/ClientWindowFrames;
@@ -42822,6 +42909,7 @@
 Landroid/window/ITaskFragmentOrganizer;
 Landroid/window/ITaskFragmentOrganizerController$Stub;
 Landroid/window/ITaskFragmentOrganizerController;
+Landroid/window/ITaskOrganizer$Stub$Proxy;
 Landroid/window/ITaskOrganizer$Stub;
 Landroid/window/ITaskOrganizer;
 Landroid/window/ITaskOrganizerController$Stub$Proxy;
@@ -42845,11 +42933,8 @@
 Landroid/window/ImeOnBackInvokedDispatcher$$ExternalSyntheticLambda0;
 Landroid/window/ImeOnBackInvokedDispatcher$1;
 Landroid/window/ImeOnBackInvokedDispatcher$2;
-Landroid/window/ImeOnBackInvokedDispatcher$DefaultImeOnBackAnimationCallback;
 Landroid/window/ImeOnBackInvokedDispatcher$ImeOnBackInvokedCallback;
 Landroid/window/ImeOnBackInvokedDispatcher;
-Landroid/window/InputTransferToken$1;
-Landroid/window/InputTransferToken;
 Landroid/window/OnBackAnimationCallback;
 Landroid/window/OnBackInvokedCallback;
 Landroid/window/OnBackInvokedCallbackInfo$1;
@@ -42873,7 +42958,6 @@
 Landroid/window/SizeConfigurationBuckets;
 Landroid/window/SplashScreen$SplashScreenManagerGlobal$1;
 Landroid/window/SplashScreen$SplashScreenManagerGlobal;
-Landroid/window/SplashScreen;
 Landroid/window/SplashScreenView$SplashScreenViewParcelable$1;
 Landroid/window/SplashScreenView$SplashScreenViewParcelable;
 Landroid/window/SplashScreenView;
@@ -42901,7 +42985,6 @@
 Landroid/window/TaskFragmentOrganizer;
 Landroid/window/TaskFragmentOrganizerToken$1;
 Landroid/window/TaskFragmentOrganizerToken;
-Landroid/window/TaskFragmentTransaction$1;
 Landroid/window/TaskFragmentTransaction;
 Landroid/window/TaskOrganizer$1;
 Landroid/window/TaskOrganizer;
@@ -42936,6 +43019,7 @@
 Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$$ExternalSyntheticLambda2;
 Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$$ExternalSyntheticLambda3;
 Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$$ExternalSyntheticLambda4;
+Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$$ExternalSyntheticLambda5;
 Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper$CallbackRef;
 Landroid/window/WindowOnBackInvokedDispatcher$OnBackInvokedCallbackWrapper;
 Landroid/window/WindowOnBackInvokedDispatcher;
@@ -43020,9 +43104,6 @@
 Lcom/android/framework/protobuf/nano/InvalidProtocolBufferNanoException;
 Lcom/android/framework/protobuf/nano/MessageNano;
 Lcom/android/framework/protobuf/nano/WireFormatNano;
-Lcom/android/graphics/flags/Flags;
-Lcom/android/graphics/hwui/flags/FeatureFlags;
-Lcom/android/graphics/hwui/flags/FeatureFlagsImpl;
 Lcom/android/graphics/hwui/flags/Flags;
 Lcom/android/i18n/phonenumbers/AlternateFormatsCountryCodeSet;
 Lcom/android/i18n/phonenumbers/AsYouTypeFormatter;
@@ -43142,7 +43223,6 @@
 Lcom/android/i18n/timezone/internal/MemoryMappedFile;
 Lcom/android/i18n/timezone/internal/NioBufferIterator;
 Lcom/android/i18n/util/Log;
-Lcom/android/icu/charset/CharsetDecoderICU;
 Lcom/android/icu/charset/CharsetEncoderICU;
 Lcom/android/icu/charset/CharsetFactory;
 Lcom/android/icu/charset/NativeConverter;
@@ -43212,6 +43292,7 @@
 Lcom/android/ims/ImsManager$$ExternalSyntheticLambda3;
 Lcom/android/ims/ImsManager$$ExternalSyntheticLambda4;
 Lcom/android/ims/ImsManager$$ExternalSyntheticLambda5;
+Lcom/android/ims/ImsManager$$ExternalSyntheticLambda6;
 Lcom/android/ims/ImsManager$$ExternalSyntheticLambda7;
 Lcom/android/ims/ImsManager$$ExternalSyntheticLambda8;
 Lcom/android/ims/ImsManager$$ExternalSyntheticLambda9;
@@ -43290,6 +43371,7 @@
 Lcom/android/ims/internal/IImsRegistrationListener;
 Lcom/android/ims/internal/IImsServiceController$Stub;
 Lcom/android/ims/internal/IImsServiceController;
+Lcom/android/ims/internal/IImsServiceFeatureCallback$Stub$Proxy;
 Lcom/android/ims/internal/IImsServiceFeatureCallback$Stub;
 Lcom/android/ims/internal/IImsServiceFeatureCallback;
 Lcom/android/ims/internal/IImsStreamMediaSession;
@@ -43544,8 +43626,6 @@
 Lcom/android/ims/rcs/uce/util/FeatureTags;
 Lcom/android/ims/rcs/uce/util/NetworkSipCode;
 Lcom/android/ims/rcs/uce/util/UceUtils;
-Lcom/android/input/flags/FeatureFlags;
-Lcom/android/input/flags/FeatureFlagsImpl;
 Lcom/android/input/flags/Flags;
 Lcom/android/internal/R$attr;
 Lcom/android/internal/R$dimen;
@@ -43573,6 +43653,7 @@
 Lcom/android/internal/app/IAppOpsActiveCallback;
 Lcom/android/internal/app/IAppOpsAsyncNotedCallback$Stub;
 Lcom/android/internal/app/IAppOpsAsyncNotedCallback;
+Lcom/android/internal/app/IAppOpsCallback$Stub$Proxy;
 Lcom/android/internal/app/IAppOpsCallback$Stub;
 Lcom/android/internal/app/IAppOpsCallback;
 Lcom/android/internal/app/IAppOpsNotedCallback$Stub;
@@ -43667,7 +43748,6 @@
 Lcom/android/internal/colorextraction/types/Tonal$TonalPalette;
 Lcom/android/internal/colorextraction/types/Tonal;
 Lcom/android/internal/compat/AndroidBuildClassifier;
-Lcom/android/internal/compat/ChangeReporter$$ExternalSyntheticLambda0;
 Lcom/android/internal/compat/ChangeReporter$ChangeReport;
 Lcom/android/internal/compat/ChangeReporter;
 Lcom/android/internal/compat/CompatibilityChangeConfig$1;
@@ -43681,9 +43761,6 @@
 Lcom/android/internal/compat/IPlatformCompat;
 Lcom/android/internal/compat/IPlatformCompatNative$Stub;
 Lcom/android/internal/compat/IPlatformCompatNative;
-Lcom/android/internal/compat/flags/FeatureFlags;
-Lcom/android/internal/compat/flags/FeatureFlagsImpl;
-Lcom/android/internal/compat/flags/Flags;
 Lcom/android/internal/config/appcloning/AppCloningDeviceConfigHelper$$ExternalSyntheticLambda0;
 Lcom/android/internal/config/appcloning/AppCloningDeviceConfigHelper;
 Lcom/android/internal/config/sysui/SystemUiSystemPropertiesFlags$DebugResolver;
@@ -43732,7 +43809,6 @@
 Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$8;
 Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$9;
 Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$MassState;
-Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$OnAnimationEndListener;
 Lcom/android/internal/dynamicanimation/animation/DynamicAnimation$ViewProperty;
 Lcom/android/internal/dynamicanimation/animation/DynamicAnimation;
 Lcom/android/internal/dynamicanimation/animation/Force;
@@ -43752,15 +43828,6 @@
 Lcom/android/internal/graphics/drawable/BackgroundBlurDrawable$BlurRegion;
 Lcom/android/internal/graphics/drawable/BackgroundBlurDrawable-IA;
 Lcom/android/internal/graphics/drawable/BackgroundBlurDrawable;
-Lcom/android/internal/hidden_from_bootclasspath/android/app/job/Flags;
-Lcom/android/internal/hidden_from_bootclasspath/android/content/pm/FeatureFlags;
-Lcom/android/internal/hidden_from_bootclasspath/android/content/pm/FeatureFlagsImpl;
-Lcom/android/internal/hidden_from_bootclasspath/android/content/pm/Flags;
-Lcom/android/internal/hidden_from_bootclasspath/android/os/FeatureFlags;
-Lcom/android/internal/hidden_from_bootclasspath/android/os/FeatureFlagsImpl;
-Lcom/android/internal/hidden_from_bootclasspath/android/os/Flags;
-Lcom/android/internal/hidden_from_bootclasspath/android/service/notification/FeatureFlags;
-Lcom/android/internal/hidden_from_bootclasspath/android/service/notification/FeatureFlagsImpl;
 Lcom/android/internal/hidden_from_bootclasspath/android/service/notification/Flags;
 Lcom/android/internal/infra/AbstractMultiplePendingRequestsRemoteService;
 Lcom/android/internal/infra/AbstractRemoteService$AsyncRequest;
@@ -43924,7 +43991,8 @@
 Lcom/android/internal/os/BinderDeathDispatcher$RecipientsInfo-IA;
 Lcom/android/internal/os/BinderDeathDispatcher$RecipientsInfo;
 Lcom/android/internal/os/BinderDeathDispatcher;
-Lcom/android/internal/os/BinderInternal$BinderProxyCountEventListenerDelegate;
+Lcom/android/internal/os/BinderInternal$BinderProxyLimitListener;
+Lcom/android/internal/os/BinderInternal$BinderProxyLimitListenerDelegate;
 Lcom/android/internal/os/BinderInternal$CallSession;
 Lcom/android/internal/os/BinderInternal$CallStatsObserver;
 Lcom/android/internal/os/BinderInternal$GcWatcher;
@@ -43943,9 +44011,6 @@
 Lcom/android/internal/os/CachedDeviceState;
 Lcom/android/internal/os/ClassLoaderFactory;
 Lcom/android/internal/os/Clock;
-Lcom/android/internal/os/FeatureFlags;
-Lcom/android/internal/os/FeatureFlagsImpl;
-Lcom/android/internal/os/Flags;
 Lcom/android/internal/os/FuseAppLoop$1;
 Lcom/android/internal/os/FuseAppLoop;
 Lcom/android/internal/os/FuseUnavailableMountException;
@@ -44052,11 +44117,10 @@
 Lcom/android/internal/os/logging/MetricsLoggerWrapper;
 Lcom/android/internal/pm/parsing/PackageParser2$Callback;
 Lcom/android/internal/pm/parsing/PackageParserException;
-Lcom/android/internal/pm/pkg/component/flags/FeatureFlags;
-Lcom/android/internal/pm/pkg/component/flags/FeatureFlagsImpl;
 Lcom/android/internal/pm/pkg/component/flags/Flags;
 Lcom/android/internal/pm/pkg/parsing/ParsingPackageUtils$Callback;
 Lcom/android/internal/policy/AttributeCache;
+Lcom/android/internal/policy/BackdropFrameRenderer;
 Lcom/android/internal/policy/DecorContext;
 Lcom/android/internal/policy/DecorView$$ExternalSyntheticLambda0;
 Lcom/android/internal/policy/DecorView$$ExternalSyntheticLambda1;
@@ -44123,6 +44187,7 @@
 Lcom/android/internal/protolog/common/LogDataType;
 Lcom/android/internal/security/VerityUtils;
 Lcom/android/internal/statusbar/IAddTileResultCallback;
+Lcom/android/internal/statusbar/IStatusBar$Stub$Proxy;
 Lcom/android/internal/statusbar/IStatusBar$Stub;
 Lcom/android/internal/statusbar/IStatusBar;
 Lcom/android/internal/statusbar/IStatusBarService$Stub$Proxy;
@@ -44205,8 +44270,6 @@
 Lcom/android/internal/telephony/CarrierInfoManager;
 Lcom/android/internal/telephony/CarrierKeyDownloadManager$1;
 Lcom/android/internal/telephony/CarrierKeyDownloadManager$2;
-Lcom/android/internal/telephony/CarrierKeyDownloadManager$3;
-Lcom/android/internal/telephony/CarrierKeyDownloadManager$DefaultNetworkCallback;
 Lcom/android/internal/telephony/CarrierKeyDownloadManager;
 Lcom/android/internal/telephony/CarrierPrivilegesTracker$1;
 Lcom/android/internal/telephony/CarrierPrivilegesTracker;
@@ -44361,6 +44424,7 @@
 Lcom/android/internal/telephony/ISub$Stub$Proxy;
 Lcom/android/internal/telephony/ISub$Stub;
 Lcom/android/internal/telephony/ISub;
+Lcom/android/internal/telephony/ITelephony$Stub$Proxy;
 Lcom/android/internal/telephony/ITelephony$Stub;
 Lcom/android/internal/telephony/ITelephony;
 Lcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy;
@@ -44535,6 +44599,7 @@
 Lcom/android/internal/telephony/RILConstants$$ExternalSyntheticLambda0;
 Lcom/android/internal/telephony/RILConstants$$ExternalSyntheticLambda1;
 Lcom/android/internal/telephony/RILConstants;
+Lcom/android/internal/telephony/RILRequest$$ExternalSyntheticLambda0;
 Lcom/android/internal/telephony/RILRequest;
 Lcom/android/internal/telephony/RadioBugDetector;
 Lcom/android/internal/telephony/RadioCapability;
@@ -45186,7 +45251,6 @@
 Lcom/android/internal/telephony/nano/PersistAtomsProto$CellularDataServiceSwitch;
 Lcom/android/internal/telephony/nano/PersistAtomsProto$CellularServiceState;
 Lcom/android/internal/telephony/nano/PersistAtomsProto$DataCallSession;
-Lcom/android/internal/telephony/nano/PersistAtomsProto$DataNetworkValidation;
 Lcom/android/internal/telephony/nano/PersistAtomsProto$EmergencyNumbersInfo;
 Lcom/android/internal/telephony/nano/PersistAtomsProto$GbaEvent;
 Lcom/android/internal/telephony/nano/PersistAtomsProto$ImsDedicatedBearerEvent;
@@ -45842,6 +45906,7 @@
 Lcom/android/internal/widget/ConversationLayout$1;
 Lcom/android/internal/widget/ConversationLayout$TouchDelegateComposite;
 Lcom/android/internal/widget/ConversationLayout;
+Lcom/android/internal/widget/DecorCaptionView;
 Lcom/android/internal/widget/DecorContentParent;
 Lcom/android/internal/widget/DecorToolbar;
 Lcom/android/internal/widget/DialogTitle;
@@ -45906,11 +45971,8 @@
 Lcom/android/internal/widget/floatingtoolbar/FloatingToolbar$$ExternalSyntheticLambda1;
 Lcom/android/internal/widget/floatingtoolbar/FloatingToolbar;
 Lcom/android/internal/widget/floatingtoolbar/FloatingToolbarPopup;
-Lcom/android/media/flags/FeatureFlags;
-Lcom/android/media/flags/FeatureFlagsImpl;
 Lcom/android/media/flags/Flags;
 Lcom/android/modules/expresslog/Counter;
-Lcom/android/modules/expresslog/MetricIds$MetricInfo;
 Lcom/android/modules/expresslog/MetricIds;
 Lcom/android/modules/expresslog/StatsExpressLog;
 Lcom/android/modules/utils/BasicShellCommandHandler;
@@ -45965,7 +46027,6 @@
 Lcom/android/okhttp/HttpUrl$Builder$ParseResult;
 Lcom/android/okhttp/HttpUrl$Builder;
 Lcom/android/okhttp/HttpUrl;
-Lcom/android/okhttp/HttpsHandler;
 Lcom/android/okhttp/Interceptor$Chain;
 Lcom/android/okhttp/MediaType;
 Lcom/android/okhttp/OkCacheContainer;
@@ -46046,7 +46107,6 @@
 Lcom/android/okhttp/internal/http/StreamAllocation;
 Lcom/android/okhttp/internal/huc/DelegatingHttpsURLConnection;
 Lcom/android/okhttp/internal/huc/HttpURLConnectionImpl;
-Lcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;
 Lcom/android/okhttp/internal/io/FileSystem$1;
 Lcom/android/okhttp/internal/io/FileSystem;
 Lcom/android/okhttp/internal/io/RealConnection;
@@ -46079,7 +46139,6 @@
 Lcom/android/okhttp/okio/Okio;
 Lcom/android/okhttp/okio/RealBufferedSink$1;
 Lcom/android/okhttp/okio/RealBufferedSink;
-Lcom/android/okhttp/okio/RealBufferedSource$1;
 Lcom/android/okhttp/okio/RealBufferedSource;
 Lcom/android/okhttp/okio/Segment;
 Lcom/android/okhttp/okio/SegmentPool;
@@ -46272,7 +46331,6 @@
 Lcom/android/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi$Std;
 Lcom/android/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi$StoreEntry;
 Lcom/android/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi;
-Lcom/android/org/bouncycastle/jcajce/provider/symmetric/AES$ECB;
 Lcom/android/org/bouncycastle/jcajce/provider/symmetric/AES$Mappings;
 Lcom/android/org/bouncycastle/jcajce/provider/symmetric/AES;
 Lcom/android/org/bouncycastle/jcajce/provider/symmetric/ARC4$Mappings;
@@ -46357,16 +46415,12 @@
 Lcom/android/phone/ecc/nano/ProtobufEccData$EccInfo;
 Lcom/android/phone/ecc/nano/UnknownFieldData;
 Lcom/android/phone/ecc/nano/WireFormatNano;
-Lcom/android/sdksandbox/flags/FeatureFlags;
-Lcom/android/sdksandbox/flags/FeatureFlagsImpl;
 Lcom/android/sdksandbox/flags/Flags;
 Lcom/android/server/AppWidgetBackupBridge;
 Lcom/android/server/LocalServices;
 Lcom/android/server/WidgetBackupProvider;
 Lcom/android/server/am/nano/Capabilities;
 Lcom/android/server/am/nano/Capability;
-Lcom/android/server/am/nano/FrameworkCapability;
-Lcom/android/server/am/nano/VMCapability;
 Lcom/android/server/backup/AccountManagerBackupHelper;
 Lcom/android/server/backup/AccountSyncSettingsBackupHelper;
 Lcom/android/server/backup/NotificationBackupHelper;
@@ -46395,7 +46449,6 @@
 Lcom/android/server/criticalevents/nano/CriticalEventLogProto;
 Lcom/android/server/criticalevents/nano/CriticalEventLogStorageProto;
 Lcom/android/server/criticalevents/nano/CriticalEventProto$AppNotResponding;
-Lcom/android/server/criticalevents/nano/CriticalEventProto$ExcessiveBinderCalls;
 Lcom/android/server/criticalevents/nano/CriticalEventProto$HalfWatchdog;
 Lcom/android/server/criticalevents/nano/CriticalEventProto$InstallPackages;
 Lcom/android/server/criticalevents/nano/CriticalEventProto$JavaCrash;
@@ -46446,9 +46499,6 @@
 Lcom/android/server/sip/SipWakeupTimer$MyEvent;
 Lcom/android/server/sip/SipWakeupTimer$MyEventComparator;
 Lcom/android/server/sip/SipWakeupTimer;
-Lcom/android/server/telecom/flags/FeatureFlags;
-Lcom/android/server/telecom/flags/FeatureFlagsImpl;
-Lcom/android/server/telecom/flags/Flags;
 Lcom/android/server/usage/AppStandbyInternal$AppIdleStateChangeListener;
 Lcom/android/server/usage/AppStandbyInternal;
 Lcom/android/server/wm/nano/WindowManagerProtos$TaskSnapshotProto;
@@ -46509,7 +46559,6 @@
 Ldalvik/system/BaseDexClassLoader$Reporter;
 Ldalvik/system/BaseDexClassLoader;
 Ldalvik/system/BlockGuard$2;
-Ldalvik/system/BlockGuard$3;
 Ldalvik/system/BlockGuard$BlockGuardPolicyException;
 Ldalvik/system/BlockGuard$Policy;
 Ldalvik/system/BlockGuard$VmPolicy;
@@ -46967,7 +47016,6 @@
 Ljava/awt/font/TextAttribute;
 Ljava/io/Bits;
 Ljava/io/BufferedInputStream;
-Ljava/io/BufferedOutputStream;
 Ljava/io/BufferedReader;
 Ljava/io/BufferedWriter;
 Ljava/io/ByteArrayInputStream;
@@ -47029,7 +47077,6 @@
 Ljava/io/ObjectInputStream;
 Ljava/io/ObjectOutput;
 Ljava/io/ObjectOutputStream$1;
-Ljava/io/ObjectOutputStream$BlockDataOutputStream;
 Ljava/io/ObjectOutputStream$Caches;
 Ljava/io/ObjectOutputStream$DebugTraceInfoStack;
 Ljava/io/ObjectOutputStream$HandleTable;
@@ -47083,7 +47130,6 @@
 Ljava/io/SyncFailedException;
 Ljava/io/UTFDataFormatException;
 Ljava/io/UncheckedIOException;
-Ljava/io/UnixFileSystem;
 Ljava/io/UnsupportedEncodingException;
 Ljava/io/WriteAbortedException;
 Ljava/io/Writer;
@@ -47220,7 +47266,6 @@
 Ljava/lang/String$$ExternalSyntheticLambda2;
 Ljava/lang/String$$ExternalSyntheticLambda3;
 Ljava/lang/String$CaseInsensitiveComparator-IA;
-Ljava/lang/String$CaseInsensitiveComparator;
 Ljava/lang/String;
 Ljava/lang/StringBuffer;
 Ljava/lang/StringBuilder;
@@ -47247,7 +47292,6 @@
 Ljava/lang/ThreadLocal$ThreadLocalMap$Entry;
 Ljava/lang/ThreadLocal$ThreadLocalMap-IA;
 Ljava/lang/ThreadLocal$ThreadLocalMap;
-Ljava/lang/ThreadLocal;
 Ljava/lang/Throwable$PrintStreamOrWriter-IA;
 Ljava/lang/Throwable$PrintStreamOrWriter;
 Ljava/lang/Throwable$SentinelHolder;
@@ -47482,9 +47526,7 @@
 Ljava/net/Inet6Address$Inet6AddressHolder-IA;
 Ljava/net/Inet6Address$Inet6AddressHolder;
 Ljava/net/Inet6Address;
-Ljava/net/Inet6AddressImpl;
 Ljava/net/InetAddress$1;
-Ljava/net/InetAddress$InetAddressHolder;
 Ljava/net/InetAddress;
 Ljava/net/InetAddressImpl;
 Ljava/net/InetSocketAddress$InetSocketAddressHolder-IA;
@@ -47547,6 +47589,7 @@
 Ljava/nio/ByteBuffer;
 Ljava/nio/ByteBufferAsCharBuffer;
 Ljava/nio/ByteBufferAsDoubleBuffer;
+Ljava/nio/ByteBufferAsLongBuffer;
 Ljava/nio/ByteBufferAsShortBuffer;
 Ljava/nio/ByteOrder;
 Ljava/nio/CharBuffer;
@@ -47733,7 +47776,6 @@
 Ljava/security/Security;
 Ljava/security/SecurityPermission;
 Ljava/security/Signature$CipherAdapter;
-Ljava/security/Signature$Delegate;
 Ljava/security/Signature;
 Ljava/security/SignatureException;
 Ljava/security/SignatureSpi;
@@ -48038,11 +48080,9 @@
 Ljava/util/Collections$ReverseComparator2;
 Ljava/util/Collections$ReverseComparator;
 Ljava/util/Collections$SequencedSetFromMap;
-Ljava/util/Collections$SetFromMap;
 Ljava/util/Collections$SynchronizedList;
 Ljava/util/Collections$SynchronizedNavigableMap;
 Ljava/util/Collections$SynchronizedNavigableSet;
-Ljava/util/Collections$SynchronizedRandomAccessList;
 Ljava/util/Collections$SynchronizedSet;
 Ljava/util/Collections$SynchronizedSortedMap;
 Ljava/util/Collections$SynchronizedSortedSet;
@@ -48058,7 +48098,6 @@
 Ljava/util/Collections$UnmodifiableSortedMap;
 Ljava/util/Collections;
 Ljava/util/ComparableTimSort;
-Ljava/util/Comparator$$ExternalSyntheticLambda0;
 Ljava/util/Comparator$$ExternalSyntheticLambda1;
 Ljava/util/Comparator$$ExternalSyntheticLambda2;
 Ljava/util/Comparator$$ExternalSyntheticLambda3;
@@ -48146,7 +48185,6 @@
 Ljava/util/IdentityHashMap$Values-IA;
 Ljava/util/IdentityHashMap$Values;
 Ljava/util/IdentityHashMap;
-Ljava/util/IllegalFormatArgumentIndexException;
 Ljava/util/IllegalFormatCodePointException;
 Ljava/util/IllegalFormatConversionException;
 Ljava/util/IllegalFormatException;
@@ -48170,9 +48208,6 @@
 Ljava/util/JumboEnumSet$EnumSetIterator;
 Ljava/util/JumboEnumSet;
 Ljava/util/KeyValueHolder;
-Ljava/util/LinkedHashMap$Entry;
-Ljava/util/LinkedHashMap$LinkedEntryIterator;
-Ljava/util/LinkedHashMap$LinkedEntrySet;
 Ljava/util/LinkedHashMap$LinkedHashIterator;
 Ljava/util/LinkedHashMap$ReversedLinkedHashMapView;
 Ljava/util/LinkedHashMap;
@@ -48286,7 +48321,6 @@
 Ljava/util/TreeMap$AscendingSubMap$AscendingEntrySetView;
 Ljava/util/TreeMap$AscendingSubMap;
 Ljava/util/TreeMap$DescendingSubMap;
-Ljava/util/TreeMap$KeySet;
 Ljava/util/TreeMap$NavigableSubMap$DescendingSubMapKeyIterator;
 Ljava/util/TreeMap$NavigableSubMap$EntrySetView;
 Ljava/util/TreeMap$NavigableSubMap$SubMapEntryIterator;
@@ -48460,7 +48494,6 @@
 Ljava/util/concurrent/ThreadLocalRandom;
 Ljava/util/concurrent/ThreadPoolExecutor$AbortPolicy;
 Ljava/util/concurrent/ThreadPoolExecutor$DiscardPolicy;
-Ljava/util/concurrent/ThreadPoolExecutor$Worker;
 Ljava/util/concurrent/TimeUnit$1;
 Ljava/util/concurrent/TimeUnit;
 Ljava/util/concurrent/TimeoutException;
@@ -48773,7 +48806,6 @@
 Ljava/util/stream/ReferencePipeline$$ExternalSyntheticLambda0;
 Ljava/util/stream/ReferencePipeline$$ExternalSyntheticLambda1;
 Ljava/util/stream/ReferencePipeline$15$1;
-Ljava/util/stream/ReferencePipeline$15;
 Ljava/util/stream/ReferencePipeline$2$1;
 Ljava/util/stream/ReferencePipeline$3$1;
 Ljava/util/stream/ReferencePipeline$4$1;
@@ -48833,12 +48865,10 @@
 Ljava/util/zip/Checksum$1;
 Ljava/util/zip/Checksum;
 Ljava/util/zip/DataFormatException;
-Ljava/util/zip/Deflater$DeflaterZStreamRef-IA;
 Ljava/util/zip/Deflater$DeflaterZStreamRef;
 Ljava/util/zip/Deflater;
 Ljava/util/zip/DeflaterOutputStream;
 Ljava/util/zip/GZIPInputStream$1;
-Ljava/util/zip/GZIPInputStream;
 Ljava/util/zip/GZIPOutputStream;
 Ljava/util/zip/Inflater$InflaterZStreamRef-IA;
 Ljava/util/zip/Inflater$InflaterZStreamRef;
@@ -49100,13 +49130,10 @@
 Ljdk/internal/access/SharedSecrets;
 Ljdk/internal/math/FDBigInteger;
 Ljdk/internal/math/FloatingDecimal$1;
-Ljdk/internal/math/FloatingDecimal$ASCIIToBinaryBuffer;
 Ljdk/internal/math/FloatingDecimal$ASCIIToBinaryConverter;
-Ljdk/internal/math/FloatingDecimal$BinaryToASCIIBuffer;
 Ljdk/internal/math/FloatingDecimal$BinaryToASCIIConverter;
 Ljdk/internal/math/FloatingDecimal$ExceptionalBinaryToASCIIBuffer;
 Ljdk/internal/math/FloatingDecimal$HexFloatPattern;
-Ljdk/internal/math/FloatingDecimal$PreparedASCIIToBinaryBuffer;
 Ljdk/internal/math/FloatingDecimal;
 Ljdk/internal/math/FormattedFloatingDecimal$1;
 Ljdk/internal/math/FormattedFloatingDecimal$Form;
@@ -49117,6 +49144,7 @@
 Ljdk/internal/misc/UnsafeConstants;
 Ljdk/internal/misc/VM;
 Ljdk/internal/ref/CleanerFactory;
+Ljdk/internal/ref/CleanerImpl$PhantomCleanableRef;
 Ljdk/internal/ref/CleanerImpl;
 Ljdk/internal/ref/PhantomCleanable;
 Ljdk/internal/reflect/Reflection;
@@ -49142,7 +49170,6 @@
 Llibcore/icu/TimeZoneNames;
 Llibcore/internal/StringPool;
 Llibcore/io/AsynchronousCloseMonitor;
-Llibcore/io/BlockGuardOs;
 Llibcore/io/BufferIterator;
 Llibcore/io/ClassPathURLStreamHandler$ClassPathURLConnection$1;
 Llibcore/io/ClassPathURLStreamHandler$ClassPathURLConnection;
@@ -49192,7 +49219,6 @@
 Llibcore/util/HexEncoding;
 Llibcore/util/NativeAllocationRegistry$CleanerRunner;
 Llibcore/util/NativeAllocationRegistry$CleanerThunk;
-Llibcore/util/NativeAllocationRegistry;
 Llibcore/util/Objects;
 Llibcore/util/SneakyThrow;
 Llibcore/util/XmlObjectFactory;
@@ -49214,9 +49240,7 @@
 Lorg/apache/harmony/xml/dom/CharacterDataImpl;
 Lorg/apache/harmony/xml/dom/CommentImpl;
 Lorg/apache/harmony/xml/dom/DOMImplementationImpl;
-Lorg/apache/harmony/xml/dom/DocumentImpl;
 Lorg/apache/harmony/xml/dom/DocumentTypeImpl;
-Lorg/apache/harmony/xml/dom/ElementImpl;
 Lorg/apache/harmony/xml/dom/EntityReferenceImpl;
 Lorg/apache/harmony/xml/dom/InnerNodeImpl;
 Lorg/apache/harmony/xml/dom/LeafNodeImpl;
@@ -49224,7 +49248,6 @@
 Lorg/apache/harmony/xml/dom/NodeImpl;
 Lorg/apache/harmony/xml/dom/NodeListImpl;
 Lorg/apache/harmony/xml/dom/ProcessingInstructionImpl;
-Lorg/apache/harmony/xml/dom/TextImpl;
 Lorg/apache/harmony/xml/parsers/DocumentBuilderFactoryImpl;
 Lorg/apache/harmony/xml/parsers/DocumentBuilderImpl;
 Lorg/apache/harmony/xml/parsers/SAXParserFactoryImpl;
@@ -49412,7 +49435,6 @@
 Lsun/nio/fs/DefaultFileSystemProvider;
 Lsun/nio/fs/DynamicFileAttributeView;
 Lsun/nio/fs/FileOwnerAttributeViewImpl;
-Lsun/nio/fs/LinuxFileSystem;
 Lsun/nio/fs/LinuxFileSystemProvider;
 Lsun/nio/fs/NativeBuffer$Deallocator;
 Lsun/nio/fs/NativeBuffer;
@@ -49518,7 +49540,6 @@
 Lsun/security/util/DerOutputStream;
 Lsun/security/util/DerValue;
 Lsun/security/util/DisabledAlgorithmConstraints$Constraint$Operator;
-Lsun/security/util/DisabledAlgorithmConstraints$Constraint-IA;
 Lsun/security/util/DisabledAlgorithmConstraints$Constraint;
 Lsun/security/util/DisabledAlgorithmConstraints$Constraints;
 Lsun/security/util/DisabledAlgorithmConstraints$KeySizeConstraint;
@@ -49759,8 +49780,6 @@
 [Landroid/graphics/fonts/FontVariationAxis;
 [Landroid/hardware/CameraStatus;
 [Landroid/hardware/biometrics/BiometricSourceType;
-[Landroid/hardware/camera2/CameraCharacteristics$Key;
-[Landroid/hardware/camera2/marshal/MarshalQueryable;
 [Landroid/hardware/camera2/params/Capability;
 [Landroid/hardware/camera2/params/Face;
 [Landroid/hardware/camera2/params/HighSpeedVideoConfiguration;
@@ -49822,7 +49841,6 @@
 [Landroid/icu/impl/units/MeasureUnitImpl$InitialCompoundPart;
 [Landroid/icu/impl/units/MeasureUnitImpl$PowerPart;
 [Landroid/icu/impl/units/MeasureUnitImpl$UnitsParser$Token$Type;
-[Landroid/icu/lang/UCharacter$IdentifierType;
 [Landroid/icu/lang/UCharacter$UnicodeBlock;
 [Landroid/icu/lang/UScript$ScriptUsage;
 [Landroid/icu/lang/UScriptRun$ParenStackEntry;
@@ -50080,7 +50098,6 @@
 [Landroid/widget/SpellChecker$SpellParser;
 [Landroid/widget/TextView$BufferType;
 [Landroid/widget/TextView$ChangeWatcher;
-[Landroid/window/BackTouchTracker$TouchTrackerState;
 [Landroid/window/TransitionFilter$Requirement;
 [Lcom/android/framework/protobuf/GeneratedMessageLite$MethodToInvoke;
 [Lcom/android/framework/protobuf/MessageInfoFactory;
@@ -50180,7 +50197,6 @@
 [Lgov/nist/javax/sip/DialogTimeoutEvent$Reason;
 [Ljava/io/File$PathStatus;
 [Ljava/io/File;
-[Ljava/io/InputStream;
 [Ljava/io/ObjectInputStream$HandleTable$HandleList;
 [Ljava/io/ObjectStreamClass$ClassDataSlot;
 [Ljava/io/ObjectStreamClass$MemberSignature;
diff --git a/core/api/current.txt b/core/api/current.txt
index 245d12d..46f426b 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -2456,7 +2456,7 @@
     field public static final int config_longAnimTime = 17694722; // 0x10e0002
     field public static final int config_mediumAnimTime = 17694721; // 0x10e0001
     field public static final int config_shortAnimTime = 17694720; // 0x10e0000
-    field public static final int status_bar_notification_info_maxnum = 17694723; // 0x10e0003
+    field @Deprecated public static final int status_bar_notification_info_maxnum = 17694723; // 0x10e0003
   }
 
   public static final class R.interpolator {
@@ -2550,7 +2550,7 @@
     field public static final int search_go = 17039372; // 0x104000c
     field public static final int selectAll = 17039373; // 0x104000d
     field public static final int selectTextMode = 17039382; // 0x1040016
-    field public static final int status_bar_notification_info_overflow = 17039383; // 0x1040017
+    field @Deprecated public static final int status_bar_notification_info_overflow = 17039383; // 0x1040017
     field public static final int unknownName = 17039374; // 0x104000e
     field public static final int untitled = 17039375; // 0x104000f
     field @Deprecated public static final int yes = 17039379; // 0x1040013
@@ -6701,7 +6701,7 @@
     method @NonNull public android.app.Notification.Builder setExtras(android.os.Bundle);
     method @NonNull public android.app.Notification.Builder setFlag(int, boolean);
     method @NonNull public android.app.Notification.Builder setForegroundServiceBehavior(int);
-    method @NonNull public android.app.Notification.Builder setFullScreenIntent(android.app.PendingIntent, boolean);
+    method @NonNull @RequiresPermission(android.Manifest.permission.USE_FULL_SCREEN_INTENT) public android.app.Notification.Builder setFullScreenIntent(android.app.PendingIntent, boolean);
     method @NonNull public android.app.Notification.Builder setGroup(String);
     method @NonNull public android.app.Notification.Builder setGroupAlertBehavior(int);
     method @NonNull public android.app.Notification.Builder setGroupSummary(boolean);
@@ -9826,6 +9826,7 @@
     method public void onAssociationPending(@NonNull android.content.IntentSender);
     method @Deprecated public void onDeviceFound(@NonNull android.content.IntentSender);
     method public abstract void onFailure(@Nullable CharSequence);
+    method @FlaggedApi("android.companion.association_failure_code") public void onFailure(int);
   }
 
   public abstract class CompanionDeviceService extends android.app.Service {
@@ -11335,7 +11336,7 @@
     field public static final String CATEGORY_UNIT_TEST = "android.intent.category.UNIT_TEST";
     field public static final String CATEGORY_VOICE = "android.intent.category.VOICE";
     field public static final String CATEGORY_VR_HOME = "android.intent.category.VR_HOME";
-    field @FlaggedApi("android.service.chooser.chooser_album_text") public static final int CHOOSER_CONTENT_TYPE_ALBUM = 1; // 0x1
+    field public static final int CHOOSER_CONTENT_TYPE_ALBUM = 1; // 0x1
     field @NonNull public static final android.os.Parcelable.Creator<android.content.Intent> CREATOR;
     field public static final String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT";
     field public static final String EXTRA_ALLOW_MULTIPLE = "android.intent.extra.ALLOW_MULTIPLE";
@@ -11358,7 +11359,7 @@
     field public static final String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list";
     field public static final String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list";
     field @FlaggedApi("android.service.chooser.chooser_payload_toggling") public static final String EXTRA_CHOOSER_ADDITIONAL_CONTENT_URI = "android.intent.extra.CHOOSER_ADDITIONAL_CONTENT_URI";
-    field @FlaggedApi("android.service.chooser.chooser_album_text") public static final String EXTRA_CHOOSER_CONTENT_TYPE_HINT = "android.intent.extra.CHOOSER_CONTENT_TYPE_HINT";
+    field public static final String EXTRA_CHOOSER_CONTENT_TYPE_HINT = "android.intent.extra.CHOOSER_CONTENT_TYPE_HINT";
     field public static final String EXTRA_CHOOSER_CUSTOM_ACTIONS = "android.intent.extra.CHOOSER_CUSTOM_ACTIONS";
     field @FlaggedApi("android.service.chooser.chooser_payload_toggling") public static final String EXTRA_CHOOSER_FOCUSED_ITEM_POSITION = "android.intent.extra.CHOOSER_FOCUSED_ITEM_POSITION";
     field public static final String EXTRA_CHOOSER_MODIFY_SHARE_ACTION = "android.intent.extra.CHOOSER_MODIFY_SHARE_ACTION";
@@ -12493,6 +12494,7 @@
     method @FlaggedApi("android.os.allow_private_profile") @Nullable @RequiresPermission(conditional=true, anyOf={"android.permission.ACCESS_HIDDEN_PROFILES_FULL", android.Manifest.permission.ACCESS_HIDDEN_PROFILES}) public final android.content.pm.LauncherUserInfo getLauncherUserInfo(@NonNull android.os.UserHandle);
     method public android.content.pm.LauncherApps.PinItemRequest getPinItemRequest(android.content.Intent);
     method @FlaggedApi("android.os.allow_private_profile") @NonNull @RequiresPermission(conditional=true, anyOf={"android.permission.ACCESS_HIDDEN_PROFILES_FULL", android.Manifest.permission.ACCESS_HIDDEN_PROFILES}) public java.util.List<java.lang.String> getPreInstalledSystemPackages(@NonNull android.os.UserHandle);
+    method @FlaggedApi("android.os.get_private_space_settings") @Nullable @RequiresPermission(conditional=true, anyOf={"android.permission.ACCESS_HIDDEN_PROFILES_FULL", android.Manifest.permission.ACCESS_HIDDEN_PROFILES}) public android.content.IntentSender getPrivateSpaceSettingsIntent();
     method @RequiresPermission(conditional=true, anyOf={"android.permission.ACCESS_HIDDEN_PROFILES_FULL", android.Manifest.permission.ACCESS_HIDDEN_PROFILES}) public java.util.List<android.os.UserHandle> getProfiles();
     method public android.graphics.drawable.Drawable getShortcutBadgedIconDrawable(android.content.pm.ShortcutInfo, int);
     method @Nullable public android.content.IntentSender getShortcutConfigActivityIntent(@NonNull android.content.pm.LauncherActivityInfo);
@@ -20354,6 +20356,7 @@
     method public android.view.Surface getSurface();
     method public void release();
     method public void resize(int, int, int);
+    method @FlaggedApi("android.companion.virtualdevice.flags.virtual_display_rotation_api") public void setRotation(int);
     method public void setSurface(android.view.Surface);
   }
 
@@ -43900,6 +43903,7 @@
     field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT = "satellite_connection_hysteresis_sec_int";
     field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_SATELLITE_ENTITLEMENT_STATUS_REFRESH_DAYS_INT = "satellite_entitlement_status_refresh_days_int";
     field @FlaggedApi("com.android.internal.telephony.flags.carrier_enabled_satellite_flag") public static final String KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL = "satellite_entitlement_supported_bool";
+    field @FlaggedApi("com.android.internal.telephony.flags.carrier_roaming_nb_iot_ntn") public static final String KEY_SATELLITE_ESOS_SUPPORTED_BOOL = "satellite_esos_supported_bool";
     field public static final String KEY_SHOW_4G_FOR_3G_DATA_ICON_BOOL = "show_4g_for_3g_data_icon_bool";
     field public static final String KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL = "show_4g_for_lte_data_icon_bool";
     field public static final String KEY_SHOW_APN_SETTING_CDMA_BOOL = "show_apn_setting_cdma_bool";
@@ -55311,7 +55315,7 @@
     field public static final int TYPE_MAGNIFICATION_OVERLAY = 6; // 0x6
     field public static final int TYPE_SPLIT_SCREEN_DIVIDER = 5; // 0x5
     field public static final int TYPE_SYSTEM = 3; // 0x3
-    field @FlaggedApi("android.view.accessibility.add_type_window_control") public static final int TYPE_WINDOW_CONTROL = 7; // 0x7
+    field @FlaggedApi("android.view.accessibility.enable_type_window_control") public static final int TYPE_WINDOW_CONTROL = 7; // 0x7
   }
 
   public class CaptioningManager {
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 0ab2588..7ae5d1b 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -318,6 +318,14 @@
 
 }
 
+package android.net.wifi {
+
+  public final class WifiMigration {
+    method @FlaggedApi("android.net.wifi.flags.legacy_keystore_to_wifi_blobstore_migration") public static void migrateLegacyKeystoreToWifiBlobstore();
+  }
+
+}
+
 package android.nfc {
 
   public class NfcServiceManager {
@@ -666,7 +674,7 @@
     method @Nullable public String getCurrentWebViewPackageName();
     method @FlaggedApi("android.webkit.update_service_v2") @NonNull public android.webkit.WebViewProviderInfo getDefaultWebViewPackage();
     method @Nullable public static android.webkit.WebViewUpdateManager getInstance();
-    method @NonNull public android.webkit.WebViewProviderInfo[] getValidWebViewPackages();
+    method @NonNull @RequiresPermission(allOf={android.Manifest.permission.INTERACT_ACROSS_USERS, android.Manifest.permission.QUERY_ALL_PACKAGES}) public android.webkit.WebViewProviderInfo[] getValidWebViewPackages();
     method @NonNull public android.webkit.WebViewProviderResponse waitForAndGetProvider();
   }
 
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 91dbd0e..36a335e 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -105,6 +105,7 @@
     field public static final String CAMERA_OPEN_CLOSE_LISTENER = "android.permission.CAMERA_OPEN_CLOSE_LISTENER";
     field @FlaggedApi("com.android.internal.camera.flags.camera_privacy_allowlist") public static final String CAMERA_PRIVACY_ALLOWLIST = "android.permission.CAMERA_PRIVACY_ALLOWLIST";
     field public static final String CAPTURE_AUDIO_HOTWORD = "android.permission.CAPTURE_AUDIO_HOTWORD";
+    field @FlaggedApi("android.os.allow_consentless_bugreport_delegated_consent") public static final String CAPTURE_CONSENTLESS_BUGREPORT_DELEGATED_CONSENT = "android.permission.CAPTURE_CONSENTLESS_BUGREPORT_DELEGATED_CONSENT";
     field public static final String CAPTURE_CONSENTLESS_BUGREPORT_ON_USERDEBUG_BUILD = "android.permission.CAPTURE_CONSENTLESS_BUGREPORT_ON_USERDEBUG_BUILD";
     field public static final String CAPTURE_MEDIA_OUTPUT = "android.permission.CAPTURE_MEDIA_OUTPUT";
     field public static final String CAPTURE_TUNER_AUDIO_INPUT = "android.permission.CAPTURE_TUNER_AUDIO_INPUT";
@@ -3446,6 +3447,7 @@
   }
 
   public static interface VirtualDeviceManager.ActivityListener {
+    method @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") public default void onActivityLaunchBlocked(int, @NonNull android.content.ComponentName, int);
     method public void onDisplayEmpty(int);
     method @Deprecated public void onTopActivityChanged(int, @NonNull android.content.ComponentName);
     method public default void onTopActivityChanged(int, @NonNull android.content.ComponentName, int);
@@ -3475,6 +3477,7 @@
     method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualMouse createVirtualMouse(@NonNull android.hardware.input.VirtualMouseConfig);
     method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualMouse createVirtualMouse(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
     method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualNavigationTouchpad createVirtualNavigationTouchpad(@NonNull android.hardware.input.VirtualNavigationTouchpadConfig);
+    method @FlaggedApi("android.companion.virtualdevice.flags.virtual_rotary") @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualRotaryEncoder createVirtualRotaryEncoder(@NonNull android.hardware.input.VirtualRotaryEncoderConfig);
     method @FlaggedApi("android.companion.virtual.flags.virtual_stylus") @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualStylus createVirtualStylus(@NonNull android.hardware.input.VirtualStylusConfig);
     method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualTouchscreen createVirtualTouchscreen(@NonNull android.hardware.input.VirtualTouchscreenConfig);
     method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualTouchscreen createVirtualTouchscreen(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
@@ -3521,6 +3524,7 @@
     field @Deprecated public static final int NAVIGATION_POLICY_DEFAULT_BLOCKED = 1; // 0x1
     field @FlaggedApi("android.companion.virtual.flags.dynamic_policy") public static final int POLICY_TYPE_ACTIVITY = 3; // 0x3
     field public static final int POLICY_TYPE_AUDIO = 1; // 0x1
+    field @FlaggedApi("android.companion.virtualdevice.flags.activity_control_api") public static final int POLICY_TYPE_BLOCKED_ACTIVITY_BEHAVIOR = 6; // 0x6
     field @FlaggedApi("android.companion.virtual.flags.virtual_camera") public static final int POLICY_TYPE_CAMERA = 5; // 0x5
     field @FlaggedApi("android.companion.virtual.flags.cross_device_clipboard") public static final int POLICY_TYPE_CLIPBOARD = 4; // 0x4
     field public static final int POLICY_TYPE_RECENTS = 2; // 0x2
@@ -5158,10 +5162,12 @@
   }
 
   public final class VirtualDisplayConfig implements android.os.Parcelable {
+    method @FlaggedApi("android.companion.virtualdevice.flags.virtual_display_insets") @Nullable public android.view.DisplayCutout getDisplayCutout();
     method @FlaggedApi("android.companion.virtual.flags.vdm_custom_home") public boolean isHomeSupported();
   }
 
   public static final class VirtualDisplayConfig.Builder {
+    method @FlaggedApi("android.companion.virtualdevice.flags.virtual_display_insets") @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setDisplayCutout(@Nullable android.view.DisplayCutout);
     method @FlaggedApi("android.companion.virtual.flags.vdm_custom_home") @NonNull public android.hardware.display.VirtualDisplayConfig.Builder setHomeSupported(boolean);
   }
 
@@ -5762,6 +5768,37 @@
     method @NonNull public android.hardware.input.VirtualNavigationTouchpadConfig build();
   }
 
+  @FlaggedApi("android.companion.virtualdevice.flags.virtual_rotary") public class VirtualRotaryEncoder implements java.io.Closeable {
+    method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void close();
+    method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void sendScrollEvent(@NonNull android.hardware.input.VirtualRotaryEncoderScrollEvent);
+  }
+
+  @FlaggedApi("android.companion.virtualdevice.flags.virtual_rotary") public final class VirtualRotaryEncoderConfig extends android.hardware.input.VirtualInputDeviceConfig implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.input.VirtualRotaryEncoderConfig> CREATOR;
+  }
+
+  public static final class VirtualRotaryEncoderConfig.Builder extends android.hardware.input.VirtualInputDeviceConfig.Builder<android.hardware.input.VirtualRotaryEncoderConfig.Builder> {
+    ctor public VirtualRotaryEncoderConfig.Builder();
+    method @NonNull public android.hardware.input.VirtualRotaryEncoderConfig build();
+  }
+
+  @FlaggedApi("android.companion.virtualdevice.flags.virtual_rotary") public final class VirtualRotaryEncoderScrollEvent implements android.os.Parcelable {
+    method public int describeContents();
+    method public long getEventTimeNanos();
+    method @FloatRange(from=-1.0F, to=1.0f) public float getScrollAmount();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.input.VirtualRotaryEncoderScrollEvent> CREATOR;
+  }
+
+  public static final class VirtualRotaryEncoderScrollEvent.Builder {
+    ctor public VirtualRotaryEncoderScrollEvent.Builder();
+    method @NonNull public android.hardware.input.VirtualRotaryEncoderScrollEvent build();
+    method @NonNull public android.hardware.input.VirtualRotaryEncoderScrollEvent.Builder setEventTimeNanos(long);
+    method @NonNull public android.hardware.input.VirtualRotaryEncoderScrollEvent.Builder setScrollAmount(@FloatRange(from=-1.0F, to=1.0f) float);
+  }
+
   @FlaggedApi("android.companion.virtual.flags.virtual_stylus") public class VirtualStylus implements java.io.Closeable {
     method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void close();
     method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void sendButtonEvent(@NonNull android.hardware.input.VirtualStylusButtonEvent);
@@ -11367,8 +11404,9 @@
     method public long getNumPacketsTx();
     method public long getRxTimeMillis();
     method public long getSleepTimeMillis();
-    method @NonNull public long getTimeInRatMicros(int);
-    method @NonNull public long getTimeInRxSignalStrengthLevelMicros(@IntRange(from=android.telephony.CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN, to=android.telephony.CellSignalStrength.SIGNAL_STRENGTH_GREAT) int);
+    method public long getTimeInRatMicros(int);
+    method public long getTimeInRxSignalStrengthLevelMicros(@IntRange(from=android.telephony.CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN, to=android.telephony.CellSignalStrength.SIGNAL_STRENGTH_GREAT) int);
+    method @FlaggedApi("com.android.server.power.optimization.streamlined_connectivity_battery_stats") public long getTxTimeMillis(@IntRange(from=android.telephony.ModemActivityInfo.TX_POWER_LEVEL_0, to=android.telephony.ModemActivityInfo.TX_POWER_LEVEL_4) int);
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.os.connectivity.CellularBatteryStats> CREATOR;
   }
@@ -11472,6 +11510,19 @@
 
 }
 
+package android.os.vibrator.persistence {
+
+  @FlaggedApi("android.os.vibrator.vibration_xml_apis") public final class ParsedVibration {
+    method @FlaggedApi("android.os.vibrator.vibration_xml_apis") @Nullable public android.os.VibrationEffect resolve(@NonNull android.os.Vibrator);
+  }
+
+  @FlaggedApi("android.os.vibrator.vibration_xml_apis") public final class VibrationXmlParser {
+    method @FlaggedApi("android.os.vibrator.vibration_xml_apis") @NonNull public static android.os.vibrator.persistence.ParsedVibration parse(@NonNull java.io.InputStream) throws java.io.IOException;
+    method @FlaggedApi("android.os.vibrator.vibration_xml_apis") @NonNull public static android.os.VibrationEffect parseVibrationEffect(@NonNull java.io.InputStream) throws java.io.IOException;
+  }
+
+}
+
 package android.permission {
 
   public final class AdminPermissionControlParams implements android.os.Parcelable {
@@ -12887,7 +12938,13 @@
     field public static final String KEY_SENSITIVE_CONTENT = "key_sensitive_content";
     field public static final String KEY_SNOOZE_CRITERIA = "key_snooze_criteria";
     field public static final String KEY_TEXT_REPLIES = "key_text_replies";
+    field @FlaggedApi("android.service.notification.notification_classification") public static final String KEY_TYPE = "key_type";
     field public static final String KEY_USER_SENTIMENT = "key_user_sentiment";
+    field @FlaggedApi("android.service.notification.notification_classification") public static final int TYPE_CONTENT_RECOMMENDATION = 4; // 0x4
+    field @FlaggedApi("android.service.notification.notification_classification") public static final int TYPE_NEWS = 3; // 0x3
+    field @FlaggedApi("android.service.notification.notification_classification") public static final int TYPE_OTHER = 0; // 0x0
+    field @FlaggedApi("android.service.notification.notification_classification") public static final int TYPE_PROMOTION = 1; // 0x1
+    field @FlaggedApi("android.service.notification.notification_classification") public static final int TYPE_SOCIAL_MEDIA = 2; // 0x2
   }
 
   public abstract class NotificationAssistantService extends android.service.notification.NotificationListenerService {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index c2f960f..2ca9f2e 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -379,6 +379,10 @@
     method public void setImportantConversation(boolean);
     method public void setOriginalImportance(int);
     method public void setUserVisibleTaskShown(boolean);
+    field @FlaggedApi("android.service.notification.notification_classification") public static final String NEWS_ID = "android.app.news";
+    field @FlaggedApi("android.service.notification.notification_classification") public static final String PROMOTIONS_ID = "android.app.promotions";
+    field @FlaggedApi("android.service.notification.notification_classification") public static final String RECS_ID = "android.app.recs";
+    field @FlaggedApi("android.service.notification.notification_classification") public static final String SOCIAL_MEDIA_ID = "android.app.social";
   }
 
   public final class NotificationChannelGroup implements android.os.Parcelable {
@@ -1978,6 +1982,7 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) public float getRs2Value();
     method public int getStreamMinVolumeInt(int);
     method @NonNull public java.util.Map<java.lang.Integer,java.lang.Boolean> getSurroundFormats();
+    method @NonNull public android.media.VolumePolicy getVolumePolicy();
     method public boolean hasRegisteredDynamicPolicy();
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) public boolean isCsdEnabled();
     method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.QUERY_AUDIO_STATE, android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public boolean isFullVolumeDevice();
@@ -2069,6 +2074,20 @@
     method public android.media.PlaybackParams setAudioStretchMode(int);
   }
 
+  public final class VolumePolicy implements android.os.Parcelable {
+    ctor public VolumePolicy(boolean, boolean, boolean, int);
+    method public int describeContents();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field public static final int A11Y_MODE_INDEPENDENT_A11Y_VOLUME = 1; // 0x1
+    field public static final int A11Y_MODE_MEDIA_A11Y_VOLUME = 0; // 0x0
+    field @NonNull public static final android.os.Parcelable.Creator<android.media.VolumePolicy> CREATOR;
+    field @NonNull public static final android.media.VolumePolicy DEFAULT;
+    field public final boolean doNotDisturbWhenSilent;
+    field public final int vibrateToSilentDebounce;
+    field public final boolean volumeDownToEnterSilent;
+    field public final boolean volumeUpToExitSilent;
+  }
+
   public static final class VolumeShaper.Configuration.Builder {
     method @NonNull public android.media.VolumeShaper.Configuration.Builder setOptionFlags(int);
   }
@@ -2604,6 +2623,18 @@
 
 }
 
+package android.os.connectivity {
+
+  public final class CellularBatteryStats implements android.os.Parcelable {
+    ctor @FlaggedApi("com.android.server.power.optimization.streamlined_connectivity_battery_stats") public CellularBatteryStats(long, long, long, long, long, long, long, long, long, long, @NonNull long[], @NonNull long[], @NonNull long[], long);
+  }
+
+  public final class WifiBatteryStats implements android.os.Parcelable {
+    ctor @FlaggedApi("com.android.server.power.optimization.streamlined_connectivity_battery_stats") public WifiBatteryStats(long, long, long, long, long, long, long, long, long, long, long, long, long, @NonNull long[], @NonNull long[], @NonNull long[], long);
+  }
+
+}
+
 package android.os.health {
 
   public class HealthKeys {
@@ -2757,21 +2788,18 @@
 
 package android.os.vibrator.persistence {
 
-  public class ParsedVibration {
-    method @NonNull public java.util.List<android.os.VibrationEffect> getVibrationEffects();
-    method @Nullable public android.os.VibrationEffect resolve(@NonNull android.os.Vibrator);
+  @FlaggedApi("android.os.vibrator.vibration_xml_apis") public final class ParsedVibration {
+    ctor public ParsedVibration(@NonNull java.util.List<android.os.VibrationEffect>);
   }
 
-  public final class VibrationXmlParser {
-    method @Nullable public static android.os.vibrator.persistence.ParsedVibration parseDocument(@NonNull java.io.Reader) throws java.io.IOException;
-    method @Nullable public static android.os.VibrationEffect parseVibrationEffect(@NonNull java.io.Reader) throws java.io.IOException;
+  public static final class VibrationXmlParser.ParseFailedException extends java.io.IOException {
   }
 
   public final class VibrationXmlSerializer {
-    method public static void serialize(@NonNull android.os.VibrationEffect, @NonNull java.io.Writer) throws java.io.IOException, android.os.vibrator.persistence.VibrationXmlSerializer.SerializationFailedException;
+    method public static void serialize(@NonNull android.os.VibrationEffect, @NonNull java.io.Writer) throws java.io.IOException;
   }
 
-  public static final class VibrationXmlSerializer.SerializationFailedException extends java.lang.RuntimeException {
+  public static final class VibrationXmlSerializer.SerializationFailedException extends java.io.IOException {
   }
 
 }
diff --git a/core/java/Android.bp b/core/java/Android.bp
index fae411d..128fb62 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -20,10 +20,43 @@
         "**/*.java",
         "**/*.aidl",
         ":framework-nfc-non-updatable-sources",
+        ":messagequeue-gen",
+    ],
+    // Exactly one of the below will be added to srcs by messagequeue-gen
+    exclude_srcs: [
+        "android/os/LegacyMessageQueue/MessageQueue.java",
+        "android/os/ConcurrentMessageQueue/MessageQueue.java",
+        "android/os/SemiConcurrentMessageQueue/MessageQueue.java",
     ],
     visibility: ["//frameworks/base"],
 }
 
+// Add selected MessageQueue.java implementation to srcs
+soong_config_module_type {
+    name: "release_package_messagequeue_implementation_srcs",
+    module_type: "genrule",
+    config_namespace: "messagequeue",
+    value_variables: ["release_package_messagequeue_implementation"],
+    properties: [
+        "srcs",
+    ],
+}
+
+// Output the selected android/os/MessageQueue.java implementation
+release_package_messagequeue_implementation_srcs {
+    name: "messagequeue-gen",
+    soong_config_variables: {
+        release_package_messagequeue_implementation: {
+            srcs: ["android/os/%s"],
+            conditions_default: {
+                srcs: ["android/os/LegacyMessageQueue/MessageQueue.java"],
+            },
+        },
+    },
+    cmd: "mkdir -p android/os/; cp $(in) $(out);",
+    out: ["android/os/MessageQueue.java"],
+}
+
 aidl_library {
     name: "IDropBoxManagerService_aidl",
     srcs: [
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 497d47a..87acbbf 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -385,7 +385,7 @@
     /**
      * @hide
      */
-    public static final int CACHE_USER_DATA_SIZE = 4;
+    public static final int CACHE_USER_DATA_SIZE = 32;
 
     private static final class AccountKeyData {
         final public Account account;
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 0947e33..5a3a8d5 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -21,6 +21,7 @@
 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
+import static android.app.Instrumentation.DEBUG_FINISH_ACTIVITY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.inMultiWindowMode;
 import static android.os.Process.myUid;
@@ -7297,6 +7298,9 @@
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private void finish(int finishTask) {
+        if (DEBUG_FINISH_ACTIVITY) {
+            Log.d("Instrumentation", "finishActivity: finishTask=" + finishTask, new Throwable());
+        }
         if (mParent == null) {
             int resultCode;
             Intent resultData;
diff --git a/core/java/android/app/AppCompatCallbacks.java b/core/java/android/app/AppCompatCallbacks.java
index f2debfc..4bfa3b3 100644
--- a/core/java/android/app/AppCompatCallbacks.java
+++ b/core/java/android/app/AppCompatCallbacks.java
@@ -82,7 +82,7 @@
 
     private void reportChange(long changeId, int state, boolean isLoggable) {
         int uid = Process.myUid();
-        mChangeReporter.reportChange(uid, changeId, state, isLoggable);
+        mChangeReporter.reportChange(uid, changeId, state, false, isLoggable);
     }
 
 }
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 2313fa2..5214d2c 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -2981,9 +2981,7 @@
         new AppOpInfo.Builder(OP_ESTABLISH_VPN_MANAGER, OPSTR_ESTABLISH_VPN_MANAGER,
                 "ESTABLISH_VPN_MANAGER").setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
         new AppOpInfo.Builder(OP_ACCESS_RESTRICTED_SETTINGS, OPSTR_ACCESS_RESTRICTED_SETTINGS,
-                "ACCESS_RESTRICTED_SETTINGS").setDefaultMode(
-                        android.permission.flags.Flags.enhancedConfirmationModeApisEnabled()
-                                ? MODE_DEFAULT : MODE_ALLOWED)
+                "ACCESS_RESTRICTED_SETTINGS").setDefaultMode(AppOpsManager.MODE_ALLOWED)
             .setDisableReset(true).setRestrictRead(true).build(),
         new AppOpInfo.Builder(OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO,
                 "RECEIVE_SOUNDTRIGGER_AUDIO").setDefaultMode(AppOpsManager.MODE_ALLOWED)
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 5956e2b..80764af 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1128,7 +1128,7 @@
     private static final PropertyInvalidatedCache<Integer, GetPackagesForUidResult>
             mGetPackagesForUidCache =
             new PropertyInvalidatedCache<Integer, GetPackagesForUidResult>(
-                32, CACHE_KEY_PACKAGES_FOR_UID_PROPERTY) {
+                1024, CACHE_KEY_PACKAGES_FOR_UID_PROPERTY) {
                 @Override
                 public GetPackagesForUidResult recompute(Integer uid) {
                     try {
diff --git a/core/java/android/app/AutomaticZenRule.java b/core/java/android/app/AutomaticZenRule.java
index 1925380..62b5412 100644
--- a/core/java/android/app/AutomaticZenRule.java
+++ b/core/java/android/app/AutomaticZenRule.java
@@ -397,6 +397,23 @@
     }
 
     /**
+     * Sets the component name of the
+     * {@link android.service.notification.ConditionProviderService} that manages this rule
+     * (but note that {@link android.service.notification.ConditionProviderService} is
+     * deprecated in favor of using {@link NotificationManager#setAutomaticZenRuleState} to
+     * notify the system about the state of your rule).
+     *
+     * <p>This is exclusive with {@link #setConfigurationActivity}; rules where a configuration
+     * activity is set will not use the component set here to determine whether the rule
+     * should be active.
+     *
+     * @hide
+     */
+    public void setOwner(@Nullable ComponentName owner) {
+        this.owner = owner;
+    }
+
+    /**
      * Sets the configuration activity - an activity that handles
      * {@link NotificationManager#ACTION_AUTOMATIC_ZEN_RULE} that shows the user more information
      * about this rule and/or allows them to configure it. This is required to be non-null for rules
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 3436da0..7e2a580 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2326,19 +2326,26 @@
                 && PermissionManager.DEVICE_AWARE_PERMISSIONS.contains(permission)) {
             VirtualDeviceManager virtualDeviceManager =
                     getSystemService(VirtualDeviceManager.class);
-            VirtualDevice virtualDevice = virtualDeviceManager.getVirtualDevice(deviceId);
-            if (virtualDevice != null) {
-                if ((Objects.equals(permission, Manifest.permission.RECORD_AUDIO)
-                                && !virtualDevice.hasCustomAudioInputSupport())
-                        || (Objects.equals(permission, Manifest.permission.CAMERA)
-                                && !virtualDevice.hasCustomCameraSupport())) {
-                    deviceId = Context.DEVICE_ID_DEFAULT;
-                }
-            } else {
+            if (virtualDeviceManager == null) {
                 Slog.e(
                         TAG,
-                        "virtualDevice is not found when device id is not default. deviceId = "
+                        "VDM is not enabled when device id is not default. deviceId = "
                                 + deviceId);
+            } else {
+                VirtualDevice virtualDevice = virtualDeviceManager.getVirtualDevice(deviceId);
+                if (virtualDevice != null) {
+                    if ((Objects.equals(permission, Manifest.permission.RECORD_AUDIO)
+                                    && !virtualDevice.hasCustomAudioInputSupport())
+                            || (Objects.equals(permission, Manifest.permission.CAMERA)
+                                    && !virtualDevice.hasCustomCameraSupport())) {
+                        deviceId = Context.DEVICE_ID_DEFAULT;
+                    }
+                } else {
+                    Slog.e(
+                            TAG,
+                            "virtualDevice is not found when device id is not default. deviceId = "
+                                    + deviceId);
+                }
             }
         }
 
@@ -3192,6 +3199,11 @@
     public void updateDeviceId(int updatedDeviceId) {
         if (updatedDeviceId != Context.DEVICE_ID_DEFAULT) {
             VirtualDeviceManager vdm = getSystemService(VirtualDeviceManager.class);
+            if (vdm == null) {
+                throw new IllegalArgumentException(
+                        "VDM is not enabled when updating to non-default device id: "
+                                + updatedDeviceId);
+            }
             if (!vdm.isValidVirtualDeviceId(updatedDeviceId)) {
                 throw new IllegalArgumentException(
                         "Not a valid ID of the default device or any virtual device: "
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index db216b1..be27046 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -107,6 +107,8 @@
     // If set, will print the stack trace for activity starts within the process
     static final boolean DEBUG_START_ACTIVITY = Build.IS_DEBUGGABLE &&
             SystemProperties.getBoolean("persist.wm.debug.start_activity", false);
+    static final boolean DEBUG_FINISH_ACTIVITY = Build.IS_DEBUGGABLE &&
+            SystemProperties.getBoolean("persist.wm.debug.finish_activity", false);
 
     /**
      * @hide
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index a1fa404..db979a5 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -762,6 +762,16 @@
     @FlaggedApi(Flags.FLAG_LIFETIME_EXTENSION_REFACTOR)
     public static final int FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY = 0x00010000;
 
+    /**
+     * Bit to be bitwise-ored into the {@link #flags} field that should be
+     * set by the system if this notification is silent.
+     *
+     * This flag is for internal use only; applications cannot set this flag directly.
+     * @hide
+     */
+    @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
+    public static final int FLAG_SILENT = 1 << 17;  //0x00020000
+
     private static final List<Class<? extends Style>> PLATFORM_STYLE_CLASSES = Arrays.asList(
             BigTextStyle.class, BigPictureStyle.class, InboxStyle.class, MediaStyle.class,
             DecoratedCustomViewStyle.class, DecoratedMediaCustomViewStyle.class,
@@ -784,7 +794,8 @@
             FLAG_BUBBLE,
             FLAG_NO_DISMISS,
             FLAG_FSI_REQUESTED_BUT_DENIED,
-            FLAG_USER_INITIATED_JOB
+            FLAG_USER_INITIATED_JOB,
+            FLAG_SILENT
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface NotificationFlags{};
@@ -1692,6 +1703,7 @@
      *
      * @hide
      */
+    @Deprecated
     public static final String GROUP_KEY_SILENT = "silent";
 
     private int mGroupAlertBehavior = GROUP_ALERT_ALL;
@@ -3984,6 +3996,13 @@
             }
         }
 
+        if (android.service.notification.Flags.notificationSilentFlag()) {
+            if ((flags & FLAG_SILENT) != 0) {
+                flagStrings.add("SILENT");
+                flags &= ~FLAG_SILENT;
+            }
+        }
+
         if (flagStrings.isEmpty()) {
             return "0";
         }
@@ -4123,6 +4142,17 @@
     }
 
     /**
+     * Sets which type of notifications in a group are responsible for audibly alerting the
+     * user. See {@link #GROUP_ALERT_ALL}, {@link #GROUP_ALERT_CHILDREN},
+     * {@link #GROUP_ALERT_SUMMARY}.
+     * @param groupAlertBehavior
+     * @hide
+     */
+    public void setGroupAlertBehavior(@GroupAlertBehavior int groupAlertBehavior) {
+        mGroupAlertBehavior = groupAlertBehavior;
+    }
+
+    /**
      * Returns the bubble metadata that will be used to display app content in a floating window
      * over the existing foreground activity.
      */
@@ -4309,6 +4339,31 @@
     }
 
     /**
+     * Sets the FLAG_SILENT flag to mark the notification as silent and clears the group key.
+     * @hide
+     */
+    public void fixSilentGroup() {
+        if (android.service.notification.Flags.notificationSilentFlag()) {
+            if (GROUP_KEY_SILENT.equals(mGroupKey)) {
+                mGroupKey = null;
+                flags |= FLAG_SILENT;
+            }
+        }
+    }
+
+    /**
+     * @return whether this notification is silent. See {@link Builder#setSilent()}
+     * @hide
+     */
+    public boolean isSilent() {
+        if (android.service.notification.Flags.notificationSilentFlag()) {
+            return (flags & Notification.FLAG_SILENT) != 0;
+        } else {
+            return GROUP_KEY_SILENT.equals(getGroup()) && suppressAlertingDueToGrouping();
+        }
+    }
+
+    /**
      * Builder class for {@link Notification} objects.
      *
      * Provides a convenient way to set the various fields of a {@link Notification} and generate
@@ -4759,8 +4814,12 @@
             mN.defaults &= ~DEFAULT_VIBRATE;
             setDefaults(mN.defaults);
 
-            if (TextUtils.isEmpty(mN.mGroupKey)) {
-                setGroup(GROUP_KEY_SILENT);
+            if (android.service.notification.Flags.notificationSilentFlag()) {
+                mN.flags |= FLAG_SILENT;
+            } else {
+                if (TextUtils.isEmpty(mN.mGroupKey)) {
+                    setGroup(GROUP_KEY_SILENT);
+                }
             }
             return this;
         }
@@ -5058,6 +5117,7 @@
          * @see Notification#fullScreenIntent
          */
         @NonNull
+        @RequiresPermission(android.Manifest.permission.USE_FULL_SCREEN_INTENT)
         public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) {
             mN.fullScreenIntent = intent;
             setFlag(FLAG_HIGH_PRIORITY, highPriority);
@@ -6050,6 +6110,7 @@
             bindProfileBadge(contentView, p);
             bindAlertedIcon(contentView, p);
             bindExpandButton(contentView, p);
+            bindCloseButton(contentView, p);
             mN.mUsesStandardHeader = true;
         }
 
@@ -6071,6 +6132,15 @@
             contentView.setInt(R.id.expand_button, "setHighlightPillColor", pillColor);
         }
 
+        private void bindCloseButton(RemoteViews contentView, StandardTemplateParams p) {
+            // set default colors
+            int bgColor = getBackgroundColor(p);
+            int backgroundColor = Colors.flattenAlpha(getColors(p).getProtectionColor(), bgColor);
+            int foregroundColor = Colors.flattenAlpha(getPrimaryTextColor(p), backgroundColor);
+            contentView.setInt(R.id.close_button, "setForegroundColor", foregroundColor);
+            contentView.setInt(R.id.close_button, "setBackgroundColor", backgroundColor);
+        }
+
         private void bindHeaderChronometerAndTime(RemoteViews contentView,
                 StandardTemplateParams p, boolean hasTextToLeft) {
             if (!p.mHideTime && showsTimeOrChronometer()) {
@@ -6222,6 +6292,7 @@
                 if (appIconRes != 0) {
                     mN.mAppIcon = Icon.createWithResource(mContext, appIconRes);
                     contentView.setImageViewIcon(R.id.icon, mN.mAppIcon);
+                    contentView.setBoolean(R.id.icon, "setShouldShowAppIcon", true);
                     usingAppIcon = true;
                 } else {
                     Log.w(TAG, "bindSmallIcon: could not get the app icon");
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 3f6c81b..326d7ce 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -72,6 +72,35 @@
     public static final String DEFAULT_CHANNEL_ID = "miscellaneous";
 
     /**
+     * A reserved id for a system channel reserved for promotional notifications.
+     *  @hide
+     */
+    @TestApi
+    @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+    public static final String PROMOTIONS_ID = "android.app.promotions";
+    /**
+     * A reserved id for a system channel reserved for non-conversation social media notifications.
+     *  @hide
+     */
+    @TestApi
+    @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+    public static final String SOCIAL_MEDIA_ID = "android.app.social";
+    /**
+     * A reserved id for a system channel reserved for news notifications.
+     *  @hide
+     */
+    @TestApi
+    @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+    public static final String NEWS_ID = "android.app.news";
+    /**
+     * A reserved id for a system channel reserved for content recommendation notifications.
+     *  @hide
+     */
+    @TestApi
+    @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+    public static final String RECS_ID = "android.app.recs";
+
+    /**
      * The formatter used by the system to create an id for notification
      * channels when it automatically creates conversation channels on behalf of an app. The format
      * string takes two arguments, in this order: the
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index bd80dc1..69b5222 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -499,32 +499,31 @@
 
     /**
      * Activity Action: Launch an Automatic Zen Rule configuration screen
-     * <p>
-     * Input: Optionally, {@link #EXTRA_AUTOMATIC_RULE_ID}, if the configuration screen for an
+     *
+     * <p> Input: Optionally, {@link #EXTRA_AUTOMATIC_RULE_ID}, if the configuration screen for an
      * existing rule should be displayed. If the rule id is missing or null, apps should display
      * a configuration screen where users can create a new instance of the rule.
-     * <p>
-     * Output: Nothing
-     * <p>
-     *     You can have multiple activities handling this intent, if you support multiple
-     *     {@link AutomaticZenRule rules}. In order for the system to properly display all of your
-     *     rule types so that users can create new instances or configure existing ones, you need
-     *     to add some extra metadata ({@link #META_DATA_AUTOMATIC_RULE_TYPE})
-     *     to your activity tag in your manifest. If you'd like to limit the number of rules a user
-     *     can create from this flow, you can additionally optionally include
-     *     {@link #META_DATA_RULE_INSTANCE_LIMIT}.
      *
-     *     For example,
-     *     &lt;meta-data
-     *         android:name="android.app.zen.automatic.ruleType"
-     *         android:value="@string/my_condition_rule">
-     *     &lt;/meta-data>
-     *     &lt;meta-data
-     *         android:name="android.app.zen.automatic.ruleInstanceLimit"
-     *         android:value="1">
-     *     &lt;/meta-data>
-     * </p>
-     * </p>
+     * <p> Output: Nothing
+     *
+     * <p> You can have multiple activities handling this intent, if you support multiple
+     * {@link AutomaticZenRule rules}. In order for the system to properly display all of your
+     * rule types so that users can create new instances or configure existing ones, you need
+     * to add some extra metadata ({@link #META_DATA_AUTOMATIC_RULE_TYPE})
+     * to your activity tag in your manifest. If you'd like to limit the number of rules a user
+     * can create from this flow, you can additionally optionally include
+     * {@link #META_DATA_RULE_INSTANCE_LIMIT}. For example,
+     *
+     * <pre>
+     *     {@code
+     *     <meta-data
+     *         android:name="android.service.zen.automatic.ruleType"
+     *         android:value="@string/my_condition_rule" />
+     *     <meta-data
+     *         android:name="android.service.zen.automatic.ruleInstanceLimit"
+     *         android:value="1" />
+     *     }
+     * </pre>
      *
      * @see #addAutomaticZenRule(AutomaticZenRule)
      */
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 370aff8..fd4d8e9 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -30,6 +30,7 @@
 import android.content.res.CompatResources;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
+import android.content.res.Flags;
 import android.content.res.Resources;
 import android.content.res.ResourcesImpl;
 import android.content.res.ResourcesKey;
@@ -73,7 +74,7 @@
     static final String TAG = "ResourcesManager";
     private static final boolean DEBUG = false;
 
-    private static ResourcesManager sResourcesManager;
+    private static volatile ResourcesManager sResourcesManager;
 
     /**
      * Internal lock object
@@ -138,16 +139,22 @@
     private final ArrayMap<String, SharedLibraryAssets> mSharedLibAssetsMap =
             new ArrayMap<>();
 
+    @VisibleForTesting
+    public ArrayMap<String, SharedLibraryAssets> getRegisteredResourcePaths() {
+        return mSharedLibAssetsMap;
+    }
+
     /**
      * The internal function to register the resources paths of a package (e.g. a shared library).
      * This will collect the package resources' paths from its ApplicationInfo and add them to all
      * existing and future contexts while the application is running.
      */
     public void registerResourcePaths(@NonNull String uniqueId, @NonNull ApplicationInfo appInfo) {
-        SharedLibraryAssets sharedLibAssets = new SharedLibraryAssets(appInfo.sourceDir,
-                appInfo.splitSourceDirs, appInfo.sharedLibraryFiles,
-                appInfo.resourceDirs, appInfo.overlayPaths);
+        if (!Flags.registerResourcePaths()) {
+            return;
+        }
 
+        final var sharedLibAssets = new SharedLibraryAssets(appInfo);
         synchronized (mLock) {
             if (mSharedLibAssetsMap.containsKey(uniqueId)) {
                 Slog.v(TAG, "Package resources' paths for uniqueId: " + uniqueId
@@ -155,18 +162,37 @@
                 return;
             }
             mSharedLibAssetsMap.put(uniqueId, sharedLibAssets);
-            appendLibAssetsLocked(sharedLibAssets.getAllAssetPaths());
-            Slog.v(TAG, "The following resources' paths have been added: "
-                    + Arrays.toString(sharedLibAssets.getAllAssetPaths()));
+            appendLibAssetsLocked(sharedLibAssets);
+            Slog.v(TAG, "The following library key has been added: "
+                    + sharedLibAssets.getResourcesKey());
         }
     }
 
-    private static class ApkKey {
+    /**
+     * Apply the registered library paths to the passed impl object
+     * @return the hash code for the current version of the registered paths
+     */
+    public int updateResourceImplWithRegisteredLibs(@NonNull ResourcesImpl impl) {
+        if (!Flags.registerResourcePaths()) {
+            return 0;
+        }
+
+        final var collector = new PathCollector(null);
+        final int size = mSharedLibAssetsMap.size();
+        for (int i = 0; i < size; i++) {
+            final var libraryKey = mSharedLibAssetsMap.valueAt(i).getResourcesKey();
+            collector.appendKey(libraryKey);
+        }
+        impl.getAssets().addPresetApkKeys(extractApkKeys(collector.collectedKey()));
+        return size;
+    }
+
+    public static class ApkKey {
         public final String path;
         public final boolean sharedLib;
         public final boolean overlay;
 
-        ApkKey(String path, boolean sharedLib, boolean overlay) {
+        public ApkKey(String path, boolean sharedLib, boolean overlay) {
             this.path = path;
             this.sharedLib = sharedLib;
             this.overlay = overlay;
@@ -190,6 +216,12 @@
             return this.path.equals(other.path) && this.sharedLib == other.sharedLib
                     && this.overlay == other.overlay;
         }
+
+        @Override
+        public String toString() {
+            return "ApkKey[" + (sharedLib ? "lib" : "app") + (overlay ? ", overlay" : "") + ": "
+                    + path + "]";
+        }
     }
 
     /**
@@ -327,17 +359,20 @@
             sResourcesManager = resourcesManager;
             return oldResourceManager;
         }
-
     }
 
     @UnsupportedAppUsage
     public static ResourcesManager getInstance() {
-        synchronized (ResourcesManager.class) {
-            if (sResourcesManager == null) {
-                sResourcesManager = new ResourcesManager();
+        var rm = sResourcesManager;
+        if (rm == null) {
+            synchronized (ResourcesManager.class) {
+                rm = sResourcesManager;
+                if (rm == null) {
+                    sResourcesManager = rm = new ResourcesManager();
+                }
             }
-            return sResourcesManager;
         }
+        return rm;
     }
 
     /**
@@ -505,7 +540,10 @@
         return "/data/resource-cache/" + path.substring(1).replace('/', '@') + "@idmap";
     }
 
-    private @NonNull ApkAssets loadApkAssets(@NonNull final ApkKey key) throws IOException {
+    /**
+     * Loads the ApkAssets object for the passed key, or picks the one from the cache if available.
+     */
+    public @NonNull ApkAssets loadApkAssets(@NonNull final ApkKey key) throws IOException {
         ApkAssets apkAssets;
 
         // Optimistically check if this ApkAssets exists somewhere else.
@@ -747,8 +785,8 @@
     private @Nullable ResourcesImpl findOrCreateResourcesImplForKeyLocked(
             @NonNull ResourcesKey key, @Nullable ApkAssetsSupplier apkSupplier) {
         ResourcesImpl impl = findResourcesImplForKeyLocked(key);
-        // ResourcesImpl also need to be recreated if its shared library count is not up-to-date.
-        if (impl == null || impl.getSharedLibCount() != mSharedLibAssetsMap.size()) {
+        // ResourcesImpl also need to be recreated if its shared library hash is not up-to-date.
+        if (impl == null || impl.getAppliedSharedLibsHash() != mSharedLibAssetsMap.size()) {
             impl = createResourcesImpl(key, apkSupplier);
             if (impl != null) {
                 mResourceImpls.put(key, new WeakReference<>(impl));
@@ -1533,54 +1571,107 @@
         }
     }
 
-    private void appendLibAssetsLocked(String[] libAssets) {
-        synchronized (mLock) {
-            // Record which ResourcesImpl need updating
-            // (and what ResourcesKey they should update to).
-            final ArrayMap<ResourcesImpl, ResourcesKey> updatedResourceKeys = new ArrayMap<>();
+    /**
+     * A utility class to collect resources paths into a ResourcesKey object:
+     *  - Separates the libraries and the overlays into different sets as those are loaded in
+     *    different ways.
+     *  - Allows to start with an existing original key object, and copies all non-path related
+     *    properties into the final one.
+     *  - Preserves the path order while dropping all duplicates in an efficient manner.
+     */
+    private static class PathCollector {
+        public final ResourcesKey originalKey;
+        public final ArrayList<String> orderedLibs = new ArrayList<>();
+        public final ArraySet<String> libsSet = new ArraySet<>();
+        public final ArrayList<String> orderedOverlays = new ArrayList<>();
+        public final ArraySet<String> overlaysSet = new ArraySet<>();
 
-            final int implCount = mResourceImpls.size();
-            for (int i = 0; i < implCount; i++) {
-                final ResourcesKey key = mResourceImpls.keyAt(i);
-                final WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.valueAt(i);
-                final ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null;
-                if (impl == null) {
-                    Slog.w(TAG, "Found a ResourcesImpl which is null, skip it and continue to "
-                            + "append shared library assets for next ResourcesImpl.");
-                    continue;
-                }
+        static void appendNewPath(@NonNull String path,
+                @NonNull ArraySet<String> uniquePaths, @NonNull ArrayList<String> orderedPaths) {
+            if (uniquePaths.add(path)) {
+                orderedPaths.add(path);
+            }
+        }
 
-                var newDirs = new ArrayList<String>();
-                var dirsSet = new ArraySet<String>();
-                if (key.mLibDirs != null) {
-                    final int dirsLength = key.mLibDirs.length;
-                    for (int k = 0; k < dirsLength; k++) {
-                        newDirs.add(key.mLibDirs[k]);
-                        dirsSet.add(key.mLibDirs[k]);
-                    }
-                }
-                final int assetsLength = libAssets.length;
-                for (int j = 0; j < assetsLength; j++) {
-                    if (dirsSet.add(libAssets[j])) {
-                        newDirs.add(libAssets[j]);
-                    }
-                }
-                String[] newLibAssets = newDirs.toArray(new String[0]);
-                if (!Arrays.equals(newLibAssets, key.mLibDirs)) {
-                    updatedResourceKeys.put(impl, new ResourcesKey(
-                            key.mResDir,
-                            key.mSplitResDirs,
-                            key.mOverlayPaths,
-                            newLibAssets,
-                            key.mDisplayId,
-                            key.mOverrideConfiguration,
-                            key.mCompatInfo,
-                            key.mLoaders));
-                }
+        static void appendAllNewPaths(@Nullable String[] paths,
+                @NonNull ArraySet<String> uniquePaths, @NonNull ArrayList<String> orderedPaths) {
+            if (paths == null) return;
+            for (int i = 0, size = paths.length; i < size; i++) {
+                appendNewPath(paths[i], uniquePaths, orderedPaths);
+            }
+        }
+
+        PathCollector(@Nullable ResourcesKey original) {
+            originalKey = original;
+            if (originalKey != null) {
+                appendKey(originalKey);
+            }
+        }
+
+        public void appendKey(@NonNull ResourcesKey key) {
+            appendAllNewPaths(key.mLibDirs, libsSet, orderedLibs);
+            appendAllNewPaths(key.mOverlayPaths, overlaysSet, orderedOverlays);
+        }
+
+        boolean isSameAsOriginal() {
+            if (originalKey == null) {
+                return orderedLibs.isEmpty() && orderedOverlays.isEmpty();
+            }
+            return ((originalKey.mLibDirs == null && orderedLibs.isEmpty())
+                        || (originalKey.mLibDirs != null
+                            && originalKey.mLibDirs.length == orderedLibs.size()))
+                    && ((originalKey.mOverlayPaths == null && orderedOverlays.isEmpty())
+                        || (originalKey.mOverlayPaths != null
+                                && originalKey.mOverlayPaths.length == orderedOverlays.size()));
+        }
+
+        @NonNull ResourcesKey collectedKey() {
+            return new ResourcesKey(
+                    originalKey == null ? null : originalKey.mResDir,
+                    originalKey == null ? null : originalKey.mSplitResDirs,
+                    orderedOverlays.toArray(new String[0]), orderedLibs.toArray(new String[0]),
+                    originalKey == null ? 0 : originalKey.mDisplayId,
+                    originalKey == null ? null : originalKey.mOverrideConfiguration,
+                    originalKey == null ? null : originalKey.mCompatInfo,
+                    originalKey == null ? null : originalKey.mLoaders);
+        }
+    }
+
+    /**
+     * Takes the original resources key and the one containing a set of library paths and overlays
+     * to append, and combines them together. In case when the original key already contains all
+     * those paths this function returns null, otherwise it makes a new ResourcesKey object.
+     */
+    private @Nullable ResourcesKey createNewResourceKeyIfNeeded(
+            @NonNull ResourcesKey original, @NonNull ResourcesKey library) {
+        final var collector = new PathCollector(original);
+        collector.appendKey(library);
+        return collector.isSameAsOriginal() ? null : collector.collectedKey();
+    }
+
+    /**
+     * Append the newly registered shared library asset paths to all existing resources objects.
+     */
+    private void appendLibAssetsLocked(@NonNull SharedLibraryAssets libAssets) {
+        // Record the ResourcesImpl's that need updating, and what ResourcesKey they should
+        // update to.
+        final ArrayMap<ResourcesImpl, ResourcesKey> updatedResourceKeys = new ArrayMap<>();
+        final int implCount = mResourceImpls.size();
+        for (int i = 0; i < implCount; i++) {
+            final ResourcesKey key = mResourceImpls.keyAt(i);
+            final WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.valueAt(i);
+            final ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null;
+            if (impl == null) {
+                Slog.w(TAG, "Found a null ResourcesImpl, skipped.");
+                continue;
             }
 
-            redirectAllResourcesToNewImplLocked(updatedResourceKeys);
+            final var newKey = createNewResourceKeyIfNeeded(key, libAssets.getResourcesKey());
+            if (newKey != null) {
+                updatedResourceKeys.put(impl, newKey);
+            }
         }
+        redirectAllResourcesToNewImplLocked(updatedResourceKeys);
     }
 
     private void applyNewResourceDirsLocked(@Nullable final String[] oldSourceDirs,
@@ -1718,8 +1809,9 @@
         }
     }
 
-    // Another redirect function which will loop through all Resources and reload ResourcesImpl
-    // if it needs a shared library asset paths update.
+    // Another redirect function which will loop through all Resources in the process, even the ones
+    // the app created outside of the regular Android Runtime, and reload their ResourcesImpl if it
+    // needs a shared library asset paths update.
     private void redirectAllResourcesToNewImplLocked(
             @NonNull final ArrayMap<ResourcesImpl, ResourcesKey> updatedResourceKeys) {
         cleanupReferences(mAllResourceReferences, mAllResourceReferencesQueue);
@@ -1745,10 +1837,15 @@
                     if (r.getImpl() != null) {
                         final ResourcesImpl oldImpl = r.getImpl();
                         // ResourcesImpl constructor will help to append shared library asset paths.
-                        final ResourcesImpl newImpl = new ResourcesImpl(oldImpl.getAssets(),
-                                oldImpl.getMetrics(), oldImpl.getConfiguration(),
-                                oldImpl.getDisplayAdjustments());
-                        r.setImpl(newImpl);
+                        if (oldImpl.getAssets().isUpToDate()) {
+                            final ResourcesImpl newImpl = new ResourcesImpl(oldImpl.getAssets(),
+                                    oldImpl.getMetrics(), oldImpl.getConfiguration(),
+                                    oldImpl.getDisplayAdjustments());
+                            r.setImpl(newImpl);
+                        } else {
+                            Slog.w(TAG, "Skip appending shared library asset paths for the "
+                                    + "Resource as its assets are not up to date.");
+                        }
                     }
                 }
             }
@@ -1830,52 +1927,35 @@
         }
     }
 
-    public static class SharedLibraryAssets{
-        private final String[] mAssetPaths;
+    @VisibleForTesting
+    public static class SharedLibraryAssets {
+        private final ResourcesKey mResourcesKey;
 
-        SharedLibraryAssets(String sourceDir, String[] splitSourceDirs, String[] sharedLibraryFiles,
-                String[] resourceDirs, String[] overlayPaths) {
-            mAssetPaths = collectAssetPaths(sourceDir, splitSourceDirs, sharedLibraryFiles,
-                    resourceDirs, overlayPaths);
-        }
-
-        private @NonNull String[] collectAssetPaths(String sourceDir, String[] splitSourceDirs,
-                String[] sharedLibraryFiles, String[] resourceDirs, String[] overlayPaths) {
-            final String[][] inputLists = {
-                    splitSourceDirs, sharedLibraryFiles, resourceDirs, overlayPaths
-            };
-
-            final ArraySet<String> assetPathSet = new ArraySet<>();
-            final List<String> assetPathList = new ArrayList<>();
-            if (sourceDir != null) {
-                assetPathSet.add(sourceDir);
-                assetPathList.add(sourceDir);
-            }
-
-            for (int i = 0; i < inputLists.length; i++) {
-                if (inputLists[i] != null) {
-                    for (int j = 0; j < inputLists[i].length; j++) {
-                        if (assetPathSet.add(inputLists[i][j])) {
-                            assetPathList.add(inputLists[i][j]);
-                        }
-                    }
-                }
-            }
-            return assetPathList.toArray(new String[0]);
+        private SharedLibraryAssets(ApplicationInfo appInfo) {
+            // We're loading all library's files as shared libs, regardless where they are in
+            // its own ApplicationInfo.
+            final var collector = new PathCollector(null);
+            PathCollector.appendNewPath(appInfo.sourceDir, collector.libsSet,
+                    collector.orderedLibs);
+            PathCollector.appendAllNewPaths(appInfo.splitSourceDirs, collector.libsSet,
+                    collector.orderedLibs);
+            PathCollector.appendAllNewPaths(appInfo.sharedLibraryFiles, collector.libsSet,
+                    collector.orderedLibs);
+            PathCollector.appendAllNewPaths(appInfo.resourceDirs, collector.overlaysSet,
+                    collector.orderedOverlays);
+            PathCollector.appendAllNewPaths(appInfo.overlayPaths, collector.overlaysSet,
+                    collector.orderedOverlays);
+            mResourcesKey = collector.collectedKey();
         }
 
         /**
-         * @return all the asset paths of this collected in this class.
+         * @return the resources key for this library assets.
          */
-        public @NonNull String[] getAllAssetPaths() {
-            return mAssetPaths;
+        public @NonNull ResourcesKey getResourcesKey() {
+            return mResourcesKey;
         }
     }
 
-    public @NonNull ArrayMap<String, SharedLibraryAssets> getSharedLibAssetsMap() {
-        return new ArrayMap<>(mSharedLibAssetsMap);
-    }
-
     /**
      * Add all resources references to the list which is designed to help to append shared library
      * asset paths. This is invoked in Resources constructor to include all Resources instances.
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index ef8501f..531537c 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -30,6 +30,7 @@
 import android.content.res.Configuration;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.net.Uri;
 import android.os.Build;
 import android.os.IBinder;
 import android.os.Parcel;
@@ -297,6 +298,25 @@
     public boolean isTopActivityTransparent;
 
     /**
+     * Whether the top activity has specified style floating.
+     * @hide
+     */
+    public boolean isTopActivityStyleFloating;
+
+    /**
+     * The URI of the intent that generated the top-most activity opened using a URL.
+     * @hide
+     */
+    @Nullable
+    public Uri capturedLink;
+
+    /**
+     * The time of the last launch of the activity opened using the {@link #capturedLink}.
+     * @hide
+     */
+    public long capturedLinkTimestamp;
+
+    /**
      * Encapsulate specific App Compat information.
      * @hide
      */
@@ -429,6 +449,9 @@
                 && parentTaskId == that.parentTaskId
                 && Objects.equals(topActivity, that.topActivity)
                 && isTopActivityTransparent == that.isTopActivityTransparent
+                && isTopActivityStyleFloating == that.isTopActivityStyleFloating
+                && Objects.equals(capturedLink, that.capturedLink)
+                && capturedLinkTimestamp == that.capturedLinkTimestamp
                 && appCompatTaskInfo.equalsForTaskOrganizer(that.appCompatTaskInfo);
     }
 
@@ -498,6 +521,9 @@
         mTopActivityLocusId = source.readTypedObject(LocusId.CREATOR);
         displayAreaFeatureId = source.readInt();
         isTopActivityTransparent = source.readBoolean();
+        isTopActivityStyleFloating = source.readBoolean();
+        capturedLink = source.readTypedObject(Uri.CREATOR);
+        capturedLinkTimestamp = source.readLong();
         appCompatTaskInfo = source.readTypedObject(AppCompatTaskInfo.CREATOR);
     }
 
@@ -545,6 +571,9 @@
         dest.writeTypedObject(mTopActivityLocusId, flags);
         dest.writeInt(displayAreaFeatureId);
         dest.writeBoolean(isTopActivityTransparent);
+        dest.writeBoolean(isTopActivityStyleFloating);
+        dest.writeTypedObject(capturedLink, flags);
+        dest.writeLong(capturedLinkTimestamp);
         dest.writeTypedObject(appCompatTaskInfo, flags);
     }
 
@@ -582,6 +611,9 @@
                 + " locusId=" + mTopActivityLocusId
                 + " displayAreaFeatureId=" + displayAreaFeatureId
                 + " isTopActivityTransparent=" + isTopActivityTransparent
+                + " isTopActivityStyleFloating=" + isTopActivityStyleFloating
+                + " capturedLink=" + capturedLink
+                + " capturedLinkTimestamp=" + capturedLinkTimestamp
                 + " appCompatTaskInfo=" + appCompatTaskInfo
                 + "}";
     }
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index 348d4d8f..a249c39 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -1647,10 +1647,13 @@
 
             // Calling out without a lock held.
             mUiAutomationConnection.executeShellCommand(command, sink, null);
-        } catch (IOException ioe) {
-            Log.e(LOG_TAG, "Error executing shell command!", ioe);
-        } catch (RemoteException re) {
-            Log.e(LOG_TAG, "Error executing shell command!", re);
+        } catch (IOException | RemoteException e) {
+            Log.e(LOG_TAG, "Error executing shell command!", e);
+        } catch (IllegalArgumentException | NullPointerException | SecurityException e) {
+            // An exception of these types is propagated from the server.
+            // Rethrow it to keep the old behavior. To avoid FD leak, close the source.
+            IoUtils.closeQuietly(source);
+            throw e;
         } finally {
             IoUtils.closeQuietly(sink);
         }
@@ -1734,10 +1737,15 @@
             // Calling out without a lock held.
             mUiAutomationConnection.executeShellCommandWithStderr(
                     command, sink_read, source_write, stderr_sink_read);
-        } catch (IOException ioe) {
-            Log.e(LOG_TAG, "Error executing shell command!", ioe);
-        } catch (RemoteException re) {
-            Log.e(LOG_TAG, "Error executing shell command!", re);
+        } catch (IOException | RemoteException e) {
+            Log.e(LOG_TAG, "Error executing shell command!", e);
+        } catch (IllegalArgumentException | SecurityException | NullPointerException e) {
+            // An exception of these types is propagated from the server.
+            // Rethrow it to keep the old behavior. To avoid FD leaks, close the sources.
+            IoUtils.closeQuietly(sink_write);
+            IoUtils.closeQuietly(source_read);
+            IoUtils.closeQuietly(stderr_source_read);
+            throw e;
         } finally {
             IoUtils.closeQuietly(sink_read);
             IoUtils.closeQuietly(source_write);
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index 3c4bd9e..5e21e05 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -550,8 +550,21 @@
 
         try {
             process = Runtime.getRuntime().exec(command);
-        } catch (IOException exc) {
-            throw new RuntimeException("Error running shell command '" + command + "'", exc);
+        } catch (IOException ex) {
+            // Make sure the passed FDs are closed.
+            IoUtils.closeQuietly(sink);
+            IoUtils.closeQuietly(source);
+            IoUtils.closeQuietly(stderrSink);
+            // No to need to wrap in RuntimeException. Only to keep the old behavior.
+            // This is just logged and not propagated to the remote caller anyway.
+            throw new RuntimeException("Error running shell command '" + command + "'", ex);
+        } catch (IllegalArgumentException | NullPointerException | SecurityException ex) {
+            // Make sure the passed FDs are closed.
+            IoUtils.closeQuietly(sink);
+            IoUtils.closeQuietly(source);
+            IoUtils.closeQuietly(stderrSink);
+            // Rethrow the exception. This will be propagated to the remote caller.
+            throw ex;
         }
 
         // Read from process and write to pipe
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 257aff0..1a72df1 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -262,13 +262,6 @@
     public static final String COMMAND_GOING_TO_SLEEP = "android.wallpaper.goingtosleep";
 
     /**
-     * Command for {@link #sendWallpaperCommand}: reported when a physical display switch event
-     * happens, e.g. fold and unfold.
-     * @hide
-     */
-    public static final String COMMAND_DISPLAY_SWITCH = "android.wallpaper.displayswitch";
-
-    /**
      * Command for {@link #sendWallpaperCommand}: reported when the wallpaper that was already
      * set is re-applied by the user.
      * @hide
diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig
index 7d5806a..8227112 100644
--- a/core/java/android/app/admin/flags/flags.aconfig
+++ b/core/java/android/app/admin/flags/flags.aconfig
@@ -383,3 +383,13 @@
     purpose: PURPOSE_BUGFIX
   }
 }
+
+flag {
+    name: "management_mode_policy_metrics"
+    namespace: "enterprise"
+    description: "Enabling management mode and password complexity policy metrics collection"
+    bug: "293091314"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/core/java/android/app/compat/ChangeIdStateCache.java b/core/java/android/app/compat/ChangeIdStateCache.java
index dea4e9c8..7948cec 100644
--- a/core/java/android/app/compat/ChangeIdStateCache.java
+++ b/core/java/android/app/compat/ChangeIdStateCache.java
@@ -32,7 +32,7 @@
 public final class ChangeIdStateCache
         extends PropertyInvalidatedCache<ChangeIdStateQuery, Boolean> {
     private static final String CACHE_KEY = "cache_key.is_compat_change_enabled";
-    private static final int MAX_ENTRIES = 64;
+    private static final int MAX_ENTRIES = 2048;
     private static boolean sDisabled = false;
     private volatile IPlatformCompat mPlatformCompat;
 
diff --git a/core/java/android/app/servertransaction/ClientTransaction.java b/core/java/android/app/servertransaction/ClientTransaction.java
index 9a04ded..6fb852f 100644
--- a/core/java/android/app/servertransaction/ClientTransaction.java
+++ b/core/java/android/app/servertransaction/ClientTransaction.java
@@ -52,8 +52,8 @@
      * List of transaction items that should be executed in order. Including both
      * {@link ActivityLifecycleItem} and other {@link ClientTransactionItem}.
      */
-    @Nullable
-    private List<ClientTransactionItem> mTransactionItems;
+    @NonNull
+    private final List<ClientTransactionItem> mTransactionItems = new ArrayList<>();
 
     /** @deprecated use {@link #getTransactionItems} instead. */
     @Nullable
@@ -89,12 +89,7 @@
      * @param item A single message that can contain a client activity/window request/callback.
      */
     public void addTransactionItem(@NonNull ClientTransactionItem item) {
-        if (Flags.bundleClientTransactionFlag()) {
-            if (mTransactionItems == null) {
-                mTransactionItems = new ArrayList<>();
-            }
-            mTransactionItems.add(item);
-        }
+        mTransactionItems.add(item);
 
         // TODO(b/324203798): cleanup after remove UnsupportedAppUsage
         // Populate even if mTransactionItems is set to support the UnsupportedAppUsage.
@@ -107,9 +102,8 @@
 
     /**
      * Gets the list of client window requests/callbacks.
-     * TODO(b/260873529): must be non null after remove the deprecated methods.
      */
-    @Nullable
+    @NonNull
     public List<ClientTransactionItem> getTransactionItems() {
         return mTransactionItems;
     }
@@ -197,22 +191,9 @@
      *                                 requested by transaction items.
      */
     public void preExecute(@NonNull ClientTransactionHandler clientTransactionHandler) {
-        if (mTransactionItems != null) {
-            final int size = mTransactionItems.size();
-            for (int i = 0; i < size; ++i) {
-                mTransactionItems.get(i).preExecute(clientTransactionHandler);
-            }
-            return;
-        }
-
-        if (mActivityCallbacks != null) {
-            final int size = mActivityCallbacks.size();
-            for (int i = 0; i < size; ++i) {
-                mActivityCallbacks.get(i).preExecute(clientTransactionHandler);
-            }
-        }
-        if (mLifecycleStateRequest != null) {
-            mLifecycleStateRequest.preExecute(clientTransactionHandler);
+        final int size = mTransactionItems.size();
+        for (int i = 0; i < size; ++i) {
+            mTransactionItems.get(i).preExecute(clientTransactionHandler);
         }
     }
 
@@ -252,29 +233,13 @@
         if (Flags.disableObjectPool()) {
             return;
         }
-        if (mTransactionItems != null) {
-            int size = mTransactionItems.size();
-            for (int i = 0; i < size; i++) {
-                mTransactionItems.get(i).recycle();
-            }
-            mTransactionItems = null;
-            mActivityCallbacks = null;
-            mLifecycleStateRequest = null;
-        } else {
-            // Only needed when mTransactionItems is null, otherwise these will have the same
-            // reference as mTransactionItems to support UnsupportedAppUsage.
-            if (mActivityCallbacks != null) {
-                int size = mActivityCallbacks.size();
-                for (int i = 0; i < size; i++) {
-                    mActivityCallbacks.get(i).recycle();
-                }
-                mActivityCallbacks = null;
-            }
-            if (mLifecycleStateRequest != null) {
-                mLifecycleStateRequest.recycle();
-                mLifecycleStateRequest = null;
-            }
+        int size = mTransactionItems.size();
+        for (int i = 0; i < size; i++) {
+            mTransactionItems.get(i).recycle();
         }
+        mTransactionItems.clear();
+        mActivityCallbacks = null;
+        mLifecycleStateRequest = null;
         mClient = null;
         mActivityToken = null;
         ObjectPool.recycle(this);
@@ -286,60 +251,24 @@
     @SuppressWarnings("AndroidFrameworkEfficientParcelable") // Item class is not final.
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        final boolean writeTransactionItems = mTransactionItems != null;
-        dest.writeBoolean(writeTransactionItems);
-        if (writeTransactionItems) {
-            dest.writeParcelableList(mTransactionItems, flags);
-        } else {
-            // TODO(b/324203798): cleanup after remove UnsupportedAppUsage
-            // Only write mLifecycleStateRequest and mActivityCallbacks when mTransactionItems is
-            // null
-            dest.writeParcelable(mLifecycleStateRequest, flags);
-            final boolean writeActivityCallbacks = mActivityCallbacks != null;
-            dest.writeBoolean(writeActivityCallbacks);
-            if (writeActivityCallbacks) {
-                dest.writeParcelableList(mActivityCallbacks, flags);
-            }
-        }
+        dest.writeParcelableList(mTransactionItems, flags);
     }
 
     /** Read from Parcel. */
     private ClientTransaction(@NonNull Parcel in) {
-        final boolean readTransactionItems = in.readBoolean();
-        if (readTransactionItems) {
-            mTransactionItems = new ArrayList<>();
-            in.readParcelableList(mTransactionItems, getClass().getClassLoader(),
-                    ClientTransactionItem.class);
+        in.readParcelableList(mTransactionItems, getClass().getClassLoader(),
+                ClientTransactionItem.class);
 
-            // TODO(b/324203798): cleanup after remove UnsupportedAppUsage
-            // Populate mLifecycleStateRequest and mActivityCallbacks from mTransactionItems so
-            // that they have the same reference when there is UnsupportedAppUsage to those fields.
-            final int size = mTransactionItems.size();
-            for (int i = 0; i < size; i++) {
-                final ClientTransactionItem item = mTransactionItems.get(i);
-                if (item.isActivityLifecycleItem()) {
-                    setLifecycleStateRequest((ActivityLifecycleItem) item);
-                } else {
-                    addCallback(item);
-                }
-            }
-        } else {
-            // TODO(b/324203798): cleanup after remove UnsupportedAppUsage
-            // Only read mLifecycleStateRequest and mActivityCallbacks when mTransactionItems is
-            // null
-            mLifecycleStateRequest = in.readParcelable(getClass().getClassLoader(),
-                    ActivityLifecycleItem.class);
-            setActivityTokenIfNotSet(mLifecycleStateRequest);
-            final boolean readActivityCallbacks = in.readBoolean();
-            if (readActivityCallbacks) {
-                mActivityCallbacks = new ArrayList<>();
-                in.readParcelableList(mActivityCallbacks, getClass().getClassLoader(),
-                        ClientTransactionItem.class);
-                final int size = mActivityCallbacks.size();
-                for (int i = 0; mActivityToken == null && i < size; i++) {
-                    final ClientTransactionItem item = mActivityCallbacks.get(i);
-                    setActivityTokenIfNotSet(item);
-                }
+        // TODO(b/324203798): cleanup after remove UnsupportedAppUsage
+        // Populate mLifecycleStateRequest and mActivityCallbacks from mTransactionItems so
+        // that they have the same reference when there is UnsupportedAppUsage to those fields.
+        final int size = mTransactionItems.size();
+        for (int i = 0; i < size; i++) {
+            final ClientTransactionItem item = mTransactionItems.get(i);
+            if (item.isActivityLifecycleItem()) {
+                setLifecycleStateRequest((ActivityLifecycleItem) item);
+            } else {
+                addCallback(item);
             }
         }
     }
@@ -390,25 +319,12 @@
     public String toString() {
         final StringBuilder sb = new StringBuilder();
         sb.append("ClientTransaction{");
-        if (mTransactionItems != null) {
-            // #addTransactionItem
-            sb.append("\n  transactionItems=[");
-            final int size = mTransactionItems.size();
-            for (int i = 0; i < size; i++) {
-                sb.append("\n    ").append(mTransactionItems.get(i));
-            }
-            sb.append("\n  ]");
-        } else {
-            // #addCallback
-            sb.append("\n  callbacks=[");
-            final int size = mActivityCallbacks != null ? mActivityCallbacks.size() : 0;
-            for (int i = 0; i < size; i++) {
-                sb.append("\n    ").append(mActivityCallbacks.get(i));
-            }
-            sb.append("\n  ]");
-            // #setLifecycleStateRequest
-            sb.append("\n  stateRequest=").append(mLifecycleStateRequest);
+        sb.append("\n  transactionItems=[");
+        final int size = mTransactionItems.size();
+        for (int i = 0; i < size; i++) {
+            sb.append("\n    ").append(mTransactionItems.get(i));
         }
+        sb.append("\n  ]");
         sb.append("\n}");
         return sb.toString();
     }
@@ -417,41 +333,18 @@
     void dump(@NonNull String prefix, @NonNull PrintWriter pw,
             @NonNull ClientTransactionHandler transactionHandler) {
         pw.append(prefix).println("ClientTransaction{");
-        if (mTransactionItems != null) {
-            pw.append(prefix).print("  transactionItems=[");
-            final String itemPrefix = prefix + "    ";
-            final int size = mTransactionItems.size();
-            if (size > 0) {
-                pw.println();
-                for (int i = 0; i < size; i++) {
-                    mTransactionItems.get(i).dump(itemPrefix, pw, transactionHandler);
-                }
-                pw.append(prefix).println("  ]");
-            } else {
-                pw.println("]");
-            }
-            pw.append(prefix).println("}");
-            return;
-        }
-        pw.append(prefix).print("  callbacks=[");
+        pw.append(prefix).print("  transactionItems=[");
         final String itemPrefix = prefix + "    ";
-        final int size = mActivityCallbacks != null ? mActivityCallbacks.size() : 0;
+        final int size = mTransactionItems.size();
         if (size > 0) {
             pw.println();
             for (int i = 0; i < size; i++) {
-                mActivityCallbacks.get(i).dump(itemPrefix, pw, transactionHandler);
+                mTransactionItems.get(i).dump(itemPrefix, pw, transactionHandler);
             }
             pw.append(prefix).println("  ]");
         } else {
             pw.println("]");
         }
-
-        pw.append(prefix).println("  stateRequest=");
-        if (mLifecycleStateRequest != null) {
-            mLifecycleStateRequest.dump(itemPrefix, pw, transactionHandler);
-        } else {
-            pw.append(itemPrefix).println("null");
-        }
         pw.append(prefix).println("}");
     }
 }
diff --git a/core/java/android/app/servertransaction/ClientTransactionListenerController.java b/core/java/android/app/servertransaction/ClientTransactionListenerController.java
index 9b53461..0c1e7a3 100644
--- a/core/java/android/app/servertransaction/ClientTransactionListenerController.java
+++ b/core/java/android/app/servertransaction/ClientTransactionListenerController.java
@@ -20,7 +20,6 @@
 import static android.view.Display.INVALID_DISPLAY;
 
 import static com.android.window.flags.Flags.activityWindowInfoFlag;
-import static com.android.window.flags.Flags.bundleClientTransactionFlag;
 
 import static java.util.Objects.requireNonNull;
 
@@ -196,7 +195,7 @@
 
     /** Called before updating the Configuration of the given {@code context}. */
     public void onContextConfigurationPreChanged(@NonNull Context context) {
-        if (!bundleClientTransactionFlag() || ActivityThread.isSystem()) {
+        if (ActivityThread.isSystem()) {
             // Not enable for system server.
             return;
         }
@@ -212,7 +211,7 @@
 
     /** Called after updating the Configuration of the given {@code context}. */
     public void onContextConfigurationPostChanged(@NonNull Context context) {
-        if (!bundleClientTransactionFlag() || ActivityThread.isSystem()) {
+        if (ActivityThread.isSystem()) {
             // Not enable for system server.
             return;
         }
diff --git a/core/java/android/app/servertransaction/RefreshCallbackItem.java b/core/java/android/app/servertransaction/RefreshCallbackItem.java
index 368ed76..a3f82e9 100644
--- a/core/java/android/app/servertransaction/RefreshCallbackItem.java
+++ b/core/java/android/app/servertransaction/RefreshCallbackItem.java
@@ -29,8 +29,8 @@
 
 /**
  * Callback that allows to {@link TransactionExecutor#cycleToPath} to {@link ON_PAUSE} or
- * {@link ON_STOP} in {@link TransactionExecutor#executeCallbacks} for activity "refresh" flow
- * that goes through "paused -> resumed" or "stopped -> resumed" cycle.
+ * {@link ON_STOP} in {@link TransactionExecutor#executeTransactionItems} for activity "refresh"
+ * flow that goes through "paused -> resumed" or "stopped -> resumed" cycle.
  *
  * <p>This is used in combination with {@link com.android.server.wm.DisplayRotationCompatPolicy}
  * for camera compatibility treatment that handles orientation mismatch between camera buffers and
diff --git a/core/java/android/app/servertransaction/TransactionExecutor.java b/core/java/android/app/servertransaction/TransactionExecutor.java
index 480205e..68012e2 100644
--- a/core/java/android/app/servertransaction/TransactionExecutor.java
+++ b/core/java/android/app/servertransaction/TransactionExecutor.java
@@ -26,7 +26,6 @@
 import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED;
 import static android.app.servertransaction.TransactionExecutorHelper.getShortActivityName;
 import static android.app.servertransaction.TransactionExecutorHelper.getStateName;
-import static android.app.servertransaction.TransactionExecutorHelper.lastCallbackRequestingState;
 import static android.app.servertransaction.TransactionExecutorHelper.shouldExcludeLastLifecycleState;
 import static android.app.servertransaction.TransactionExecutorHelper.tId;
 import static android.app.servertransaction.TransactionExecutorHelper.transactionToString;
@@ -77,13 +76,7 @@
 
         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "clientTransactionExecuted");
         try {
-            if (transaction.getTransactionItems() != null) {
-                executeTransactionItems(transaction);
-            } else {
-                // TODO(b/260873529): cleanup after launch.
-                executeCallbacks(transaction);
-                executeLifecycleState(transaction);
-            }
+            executeTransactionItems(transaction);
         } catch (Exception e) {
             Slog.e(TAG, "Failed to execute the transaction: "
                     + transactionToString(transaction, mTransactionHandler));
@@ -112,41 +105,6 @@
         }
     }
 
-    /**
-     * Cycle through all states requested by callbacks and execute them at proper times.
-     * @deprecated use {@link #executeTransactionItems} instead.
-     */
-    @VisibleForTesting
-    @Deprecated
-    public void executeCallbacks(@NonNull ClientTransaction transaction) {
-        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
-        if (callbacks == null || callbacks.isEmpty()) {
-            // No callbacks to execute, return early.
-            return;
-        }
-        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callbacks in transaction");
-
-        // In case when post-execution state of the last callback matches the final state requested
-        // for the activity in this transaction, we won't do the last transition here and do it when
-        // moving to final state instead (because it may contain additional parameters from server).
-        final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
-        final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
-                : UNDEFINED;
-        // Index of the last callback that requests some post-execution state.
-        final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);
-
-        final int size = callbacks.size();
-        for (int i = 0; i < size; ++i) {
-            final ClientTransactionItem item = callbacks.get(i);
-
-            // Skip the very last transition and perform it by explicit state request instead.
-            final int postExecutionState = item.getPostExecutionState();
-            final boolean shouldExcludeLastLifecycleState = postExecutionState != UNDEFINED
-                    && i == lastCallbackRequestingState && finalState == postExecutionState;
-            executeNonLifecycleItem(transaction, item, shouldExcludeLastLifecycleState);
-        }
-    }
-
     private void executeNonLifecycleItem(@NonNull ClientTransaction transaction,
             @NonNull ClientTransactionItem item, boolean shouldExcludeLastLifecycleState) {
         final IBinder token = item.getActivityToken();
@@ -184,21 +142,6 @@
         }
     }
 
-    /**
-     * Transition to the final state if requested by the transaction.
-     * @deprecated use {@link #executeTransactionItems} instead
-     */
-    @Deprecated
-    private void executeLifecycleState(@NonNull ClientTransaction transaction) {
-        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
-        if (lifecycleItem == null) {
-            // No lifecycle request, return early.
-            return;
-        }
-
-        executeLifecycleItem(transaction, lifecycleItem);
-    }
-
     private void executeLifecycleItem(@NonNull ClientTransaction transaction,
             @NonNull ActivityLifecycleItem lifecycleItem) {
         final IBinder token = lifecycleItem.getActivityToken();
diff --git a/core/java/android/app/servertransaction/TransactionExecutorHelper.java b/core/java/android/app/servertransaction/TransactionExecutorHelper.java
index 710261a..9f622e9 100644
--- a/core/java/android/app/servertransaction/TransactionExecutorHelper.java
+++ b/core/java/android/app/servertransaction/TransactionExecutorHelper.java
@@ -226,29 +226,6 @@
     }
 
     /**
-     * Return the index of the last callback that requests the state in which activity will be after
-     * execution. If there is a group of callbacks in the end that requests the same specific state
-     * or doesn't request any - we will find the first one from such group.
-     *
-     * E.g. ActivityResult requests RESUMED post-execution state, Configuration does not request any
-     * specific state. If there is a sequence
-     *   Configuration - ActivityResult - Configuration - ActivityResult
-     * index 1 will be returned, because ActivityResult request on position 1 will be the last
-     * request that moves activity to the RESUMED state where it will eventually end.
-     * @deprecated to be removed with {@link TransactionExecutor#executeCallbacks}.
-     */
-    @Deprecated
-    static int lastCallbackRequestingState(@NonNull ClientTransaction transaction) {
-        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
-        if (callbacks == null || callbacks.isEmpty()
-                || transaction.getLifecycleStateRequest() == null) {
-            return -1;
-        }
-        return lastCallbackRequestingStateIndex(callbacks, 0, callbacks.size() - 1,
-                transaction.getLifecycleStateRequest().getActivityToken());
-    }
-
-    /**
      * Returns the index of the last callback between the start index and last index that requests
      * the state for the given activity token in which that activity will be after execution.
      * If there is a group of callbacks in the end that requests the same specific state or doesn't
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 3213b40..abb562d 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -523,6 +523,8 @@
     private final IAppWidgetService mService;
     private final DisplayMetrics mDisplayMetrics;
 
+    private int mMaxBitmapMemory = 0;
+
     private boolean mHasPostedLegacyLists = false;
 
     /**
@@ -548,6 +550,12 @@
         if (mService == null) {
             return;
         }
+        // Allowing some buffer when estimating the maximum bitmap cache size
+        try {
+            mMaxBitmapMemory = (int) (mService.getMaxBitmapMemory() * 0.9);
+        } catch (Exception e) {
+            Log.e(TAG, "Error setting the maximum bitmap memory", e);
+        }
         BackgroundThread.getExecutor().execute(() -> {
             try {
                 mService.notifyProviderInheritance(getInstalledProvidersForPackage(mPackageName,
@@ -576,7 +584,7 @@
             final RemoteViews viewsCopy = new RemoteViews(original);
             Runnable updateWidgetWithTask = () -> {
                 try {
-                    viewsCopy.collectAllIntents().get();
+                    viewsCopy.collectAllIntents(mMaxBitmapMemory).get();
                     action.acceptOrThrow(viewsCopy);
                 } catch (Exception e) {
                     Log.e(TAG, failureMsg, e);
diff --git a/core/java/android/appwidget/flags.aconfig b/core/java/android/appwidget/flags.aconfig
index 18cfca6..4e0379e 100644
--- a/core/java/android/appwidget/flags.aconfig
+++ b/core/java/android/appwidget/flags.aconfig
@@ -50,3 +50,10 @@
       purpose: PURPOSE_BUGFIX
   }
 }
+
+flag {
+  name: "remote_views_proto"
+  namespace: "app_widgets"
+  description: "Enable support for persisting RemoteViews previews to Protobuf"
+  bug: "306546610"
+}
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index b4ad1c8..34cfa58 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -21,6 +21,8 @@
 import static android.Manifest.permission.REQUEST_COMPANION_PROFILE_COMPUTER;
 import static android.Manifest.permission.REQUEST_COMPANION_PROFILE_WATCH;
 
+import static java.util.Collections.unmodifiableMap;
+
 import android.annotation.CallbackExecutor;
 import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
@@ -56,6 +58,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.service.notification.NotificationListenerService;
+import android.util.ArrayMap;
 import android.util.ExceptionUtils;
 import android.util.Log;
 import android.util.SparseArray;
@@ -75,6 +78,7 @@
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.Executor;
 import java.util.function.BiConsumer;
@@ -119,29 +123,31 @@
      * is created successfully.
      */
     public static final int RESULT_OK = -1;
-
+    //TODO(b/331459560) Need to update the java doc after API cut for W.
     /**
      * The result code to propagate back to the user activity, indicates if the association dialog
      * is implicitly cancelled.
      * E.g. phone is locked, switch to another app or press outside the dialog.
      */
     public static final int RESULT_CANCELED = 0;
-
+    //TODO(b/331459560) Need to update the java doc after API cut for W.
     /**
      * The result code to propagate back to the user activity, indicates the association dialog
      * is explicitly declined by the users.
      */
     public static final int RESULT_USER_REJECTED = 1;
-
+    //TODO(b/331459560) Need to update the java doc after API cut for W.
     /**
      * The result code to propagate back to the user activity, indicates the association
      * dialog is dismissed if there's no device found after 20 seconds.
      */
     public static final int RESULT_DISCOVERY_TIMEOUT = 2;
-
+    //TODO(b/331459560) Need to update the java doc after API cut for W.
     /**
      * The result code to propagate back to the user activity, indicates the internal error
      * in CompanionDeviceManager.
+     * E.g. Missing necessary permissions or duplicate {@link AssociationRequest}s when create the
+     * {@link AssociationInfo}.
      */
     public static final int RESULT_INTERNAL_ERROR = 3;
 
@@ -368,12 +374,22 @@
          */
         public void onAssociationCreated(@NonNull AssociationInfo associationInfo) {}
 
+        //TODO(b/331459560): Add deprecated and remove abstract after API cut for W.
         /**
          * Invoked if the association could not be created.
          *
          * @param error error message.
          */
         public abstract void onFailure(@Nullable CharSequence error);
+
+        /**
+         * Invoked if the association could not be created.
+         *
+         * @param resultCode indicate the particular reason why the association
+         *                   could not be created.
+         */
+        @FlaggedApi(Flags.FLAG_ASSOCIATION_FAILURE_CODE)
+        public void onFailure(@ResultCode int resultCode) {}
     }
 
     private final ICompanionDeviceManager mService;
@@ -1803,8 +1819,12 @@
         }
 
         @Override
-        public void onFailure(CharSequence error) throws RemoteException {
-            execute(mCallback::onFailure, error);
+        public void onFailure(@ResultCode int resultCode) {
+            if (Flags.associationFailureCode()) {
+                execute(mCallback::onFailure, resultCode);
+            }
+
+            execute(mCallback::onFailure, RESULT_CODE_TO_REASON.get(resultCode));
         }
 
         private <T> void execute(Consumer<T> callback, T arg) {
@@ -1988,4 +2008,15 @@
             }
         }
     }
+
+    private static final Map<Integer, String> RESULT_CODE_TO_REASON;
+    static {
+        final Map<Integer, String> map = new ArrayMap<>();
+        map.put(RESULT_CANCELED, REASON_CANCELED);
+        map.put(RESULT_USER_REJECTED, REASON_USER_REJECTED);
+        map.put(RESULT_DISCOVERY_TIMEOUT, REASON_DISCOVERY_TIMEOUT);
+        map.put(RESULT_INTERNAL_ERROR, REASON_INTERNAL_ERROR);
+
+        RESULT_CODE_TO_REASON = unmodifiableMap(map);
+    }
 }
diff --git a/core/java/android/companion/IAssociationRequestCallback.aidl b/core/java/android/companion/IAssociationRequestCallback.aidl
index 8cc2a71..b1be30a 100644
--- a/core/java/android/companion/IAssociationRequestCallback.aidl
+++ b/core/java/android/companion/IAssociationRequestCallback.aidl
@@ -25,5 +25,5 @@
 
     oneway void onAssociationCreated(in AssociationInfo associationInfo);
 
-    oneway void onFailure(in CharSequence error);
+    oneway void onFailure(in int resultCode);
 }
\ No newline at end of file
diff --git a/core/java/android/companion/flags.aconfig b/core/java/android/companion/flags.aconfig
index fd4ba83..ee9114f 100644
--- a/core/java/android/companion/flags.aconfig
+++ b/core/java/android/companion/flags.aconfig
@@ -53,4 +53,12 @@
     namespace: "companion"
     description: "Unpair with an associated bluetooth device"
     bug: "322237619"
-}
\ No newline at end of file
+}
+
+flag {
+    name: "association_failure_code"
+    is_exported: true
+    namespace: "companion"
+    description: "Enable association failure code API"
+    bug: "331459560"
+}
diff --git a/core/java/android/companion/virtual/IVirtualDevice.aidl b/core/java/android/companion/virtual/IVirtualDevice.aidl
index 24f18cc..0653839 100644
--- a/core/java/android/companion/virtual/IVirtualDevice.aidl
+++ b/core/java/android/companion/virtual/IVirtualDevice.aidl
@@ -17,7 +17,9 @@
 package android.companion.virtual;
 
 import android.app.PendingIntent;
+import android.companion.virtual.IVirtualDeviceActivityListener;
 import android.companion.virtual.IVirtualDeviceIntentInterceptor;
+import android.companion.virtual.IVirtualDeviceSoundEffectListener;
 import android.companion.virtual.audio.IAudioConfigChangedCallback;
 import android.companion.virtual.audio.IAudioRoutingCallback;
 import android.companion.virtual.sensor.VirtualSensor;
@@ -35,6 +37,8 @@
 import android.hardware.input.VirtualMouseConfig;
 import android.hardware.input.VirtualMouseRelativeEvent;
 import android.hardware.input.VirtualMouseScrollEvent;
+import android.hardware.input.VirtualRotaryEncoderConfig;
+import android.hardware.input.VirtualRotaryEncoderScrollEvent;
 import android.hardware.input.VirtualStylusButtonEvent;
 import android.hardware.input.VirtualStylusConfig;
 import android.hardware.input.VirtualStylusMotionEvent;
@@ -158,6 +162,12 @@
     void createVirtualStylus(in VirtualStylusConfig config, IBinder token);
 
     /**
+     * Creates a new rotary encoder and registers it with the input framework with the given token.
+     */
+    @EnforcePermission("CREATE_VIRTUAL_DEVICE")
+    void createVirtualRotaryEncoder(in VirtualRotaryEncoderConfig config, IBinder token);
+
+    /**
      * Removes the input device corresponding to the given token from the framework.
      */
     @EnforcePermission("CREATE_VIRTUAL_DEVICE")
@@ -218,6 +228,12 @@
     boolean sendStylusButtonEvent(IBinder token, in VirtualStylusButtonEvent event);
 
     /**
+     * Injects a scroll event from the virtual rotary encoder corresponding to the given token.
+     */
+    @EnforcePermission("CREATE_VIRTUAL_DEVICE")
+    boolean sendRotaryEncoderScrollEvent(IBinder token, in VirtualRotaryEncoderScrollEvent event);
+
+    /**
      * Returns all virtual sensors created for this device.
      */
     @EnforcePermission("CREATE_VIRTUAL_DEVICE")
@@ -282,4 +298,15 @@
      */
     @EnforcePermission("CREATE_VIRTUAL_DEVICE")
     String getVirtualCameraId(in VirtualCameraConfig camera);
+
+    /**
+     * Setter for listeners that live in the client process, namely in
+     * {@link android.companion.virtual.VirtualDeviceInternal}.
+     *
+     * This is needed for virtual devices that are created by the system, as the VirtualDeviceImpl
+     * object is created before the returned VirtualDeviceInternal one.
+     */
+    @EnforcePermission("CREATE_VIRTUAL_DEVICE")
+    void setListeners(in IVirtualDeviceActivityListener activityListener,
+            in IVirtualDeviceSoundEffectListener soundEffectListener);
 }
diff --git a/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl b/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl
index fc7f85c..39371a3 100644
--- a/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl
+++ b/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl
@@ -32,7 +32,7 @@
      * @param topActivity The component name of the top activity.
      * @param userId The user ID associated with the top activity.
      */
-    void onTopActivityChanged(int displayId, in ComponentName topActivity, in int userId);
+    void onTopActivityChanged(int displayId, in ComponentName topActivity, int userId);
 
     /**
      * Called when the display becomes empty (e.g. if the user hits back on the last
@@ -41,4 +41,13 @@
      * @param displayId The display ID that became empty.
      */
     void onDisplayEmpty(int displayId);
+
+    /**
+     * Called when an activity launch was blocked due to a policy violation.
+     *
+     * @param displayId The display ID on which the activity tried to launch.
+     * @param componentName The component name of the blocked activity.
+     * @param userId The user ID associated with the blocked activity.
+     */
+    void onActivityLaunchBlocked(int displayId, in ComponentName componentName, int userId);
 }
diff --git a/core/java/android/companion/virtual/VirtualDeviceInternal.java b/core/java/android/companion/virtual/VirtualDeviceInternal.java
index 60448ba..d3fcfc6 100644
--- a/core/java/android/companion/virtual/VirtualDeviceInternal.java
+++ b/core/java/android/companion/virtual/VirtualDeviceInternal.java
@@ -46,6 +46,8 @@
 import android.hardware.input.VirtualMouseConfig;
 import android.hardware.input.VirtualNavigationTouchpad;
 import android.hardware.input.VirtualNavigationTouchpadConfig;
+import android.hardware.input.VirtualRotaryEncoder;
+import android.hardware.input.VirtualRotaryEncoderConfig;
 import android.hardware.input.VirtualStylus;
 import android.hardware.input.VirtualStylusConfig;
 import android.hardware.input.VirtualTouchscreen;
@@ -126,6 +128,22 @@
                         Binder.restoreCallingIdentity(token);
                     }
                 }
+
+                @Override
+                public void onActivityLaunchBlocked(int displayId, ComponentName componentName,
+                        @UserIdInt int userId) {
+                    final long token = Binder.clearCallingIdentity();
+                    try {
+                        synchronized (mActivityListenersLock) {
+                            for (int i = 0; i < mActivityListeners.size(); i++) {
+                                mActivityListeners.valueAt(i)
+                                        .onActivityLaunchBlocked(displayId, componentName, userId);
+                            }
+                        }
+                    } finally {
+                        Binder.restoreCallingIdentity(token);
+                    }
+                }
             };
     private final IVirtualDeviceSoundEffectListener mSoundEffectListener =
             new IVirtualDeviceSoundEffectListener.Stub() {
@@ -162,6 +180,20 @@
                 mSoundEffectListener);
     }
 
+    VirtualDeviceInternal(
+            IVirtualDeviceManager service,
+            Context context,
+            IVirtualDevice virtualDevice) {
+        mService = service;
+        mContext = context.getApplicationContext();
+        mVirtualDevice = virtualDevice;
+        try {
+            mVirtualDevice.setListeners(mActivityListenerBinder, mSoundEffectListener);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     int getDeviceId() {
         try {
             return mVirtualDevice.getDeviceId();
@@ -335,6 +367,19 @@
         }
     }
 
+    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    @NonNull
+    VirtualRotaryEncoder createVirtualRotaryEncoder(@NonNull VirtualRotaryEncoderConfig config) {
+        try {
+            final IBinder token = new Binder(
+                    "android.hardware.input.VirtualRotaryEncoder:" + config.getInputDeviceName());
+            mVirtualDevice.createVirtualRotaryEncoder(config, token);
+            return new VirtualRotaryEncoder(config, mVirtualDevice, token);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     @NonNull
     VirtualNavigationTouchpad createVirtualNavigationTouchpad(
             @NonNull VirtualNavigationTouchpadConfig config) {
@@ -496,6 +541,12 @@
         public void onDisplayEmpty(int displayId) {
             mExecutor.execute(() -> mActivityListener.onDisplayEmpty(displayId));
         }
+
+        public void onActivityLaunchBlocked(int displayId, ComponentName componentName,
+                @UserIdInt int userId) {
+            mExecutor.execute(() ->
+                    mActivityListener.onActivityLaunchBlocked(displayId, componentName, userId));
+        }
     }
 
     /**
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index ed55a3f..296ca33 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -56,6 +56,8 @@
 import android.hardware.input.VirtualMouseConfig;
 import android.hardware.input.VirtualNavigationTouchpad;
 import android.hardware.input.VirtualNavigationTouchpadConfig;
+import android.hardware.input.VirtualRotaryEncoder;
+import android.hardware.input.VirtualRotaryEncoderConfig;
 import android.hardware.input.VirtualStylus;
 import android.hardware.input.VirtualStylusConfig;
 import android.hardware.input.VirtualTouchscreen;
@@ -573,6 +575,12 @@
                     new VirtualDeviceInternal(service, context, associationId, params);
         }
 
+        /** @hide */
+        public VirtualDevice(IVirtualDeviceManager service, Context context,
+                IVirtualDevice virtualDevice) {
+            mVirtualDeviceInternal = new VirtualDeviceInternal(service, context, virtualDevice);
+        }
+
         /**
          * Returns the unique ID of this virtual device.
          */
@@ -947,6 +955,23 @@
         }
 
         /**
+         * Creates a virtual rotary encoder.
+         *
+         * @param config the configuration for the virtual rotary encoder.
+         * @see android.view.InputDevice#SOURCE_ROTARY_ENCODER
+         */
+        @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+        @NonNull
+        @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_VIRTUAL_ROTARY)
+        public VirtualRotaryEncoder createVirtualRotaryEncoder(
+                @NonNull VirtualRotaryEncoderConfig config) {
+            if (!android.companion.virtualdevice.flags.Flags.virtualRotary()) {
+                throw new UnsupportedOperationException("Virtual rotary support not enabled");
+            }
+            return mVirtualDeviceInternal.createVirtualRotaryEncoder(config);
+        }
+
+        /**
          * Creates a VirtualAudioDevice, capable of recording audio emanating from this device,
          * or injecting audio from another device.
          *
@@ -1101,7 +1126,7 @@
     }
 
     /**
-     * Listener for activity changes in this virtual device.
+     * Listener for activity changes and other activity events on a virtual device.
      *
      * @hide
      */
@@ -1142,6 +1167,20 @@
          * @param displayId The display ID that became empty.
          */
         void onDisplayEmpty(int displayId);
+
+        /**
+         * Called when an activity launch was blocked due to a policy violation.
+         *
+         * @param displayId The display ID on which the activity tried to launch.
+         * @param componentName The component name of the blocked activity.
+         * @param userId The user ID associated with the blocked activity.
+         *
+         * @see VirtualDeviceParams#POLICY_TYPE_ACTIVITY
+         * @see VirtualDevice#addActivityPolicyExemption(ComponentName)
+         */
+        @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
+        default void onActivityLaunchBlocked(int displayId, @NonNull ComponentName componentName,
+                @UserIdInt int userId) {}
     }
 
     /**
diff --git a/core/java/android/companion/virtual/VirtualDeviceParams.java b/core/java/android/companion/virtual/VirtualDeviceParams.java
index f9a9da1..f7f842f 100644
--- a/core/java/android/companion/virtual/VirtualDeviceParams.java
+++ b/core/java/android/companion/virtual/VirtualDeviceParams.java
@@ -171,7 +171,7 @@
      * @hide
      */
     @IntDef(prefix = "POLICY_TYPE_", value = {POLICY_TYPE_RECENTS, POLICY_TYPE_ACTIVITY,
-            POLICY_TYPE_CLIPBOARD})
+            POLICY_TYPE_CLIPBOARD, POLICY_TYPE_BLOCKED_ACTIVITY_BEHAVIOR})
     @Retention(RetentionPolicy.SOURCE)
     @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
     public @interface DynamicPolicyType {}
@@ -263,6 +263,22 @@
     @FlaggedApi(Flags.FLAG_VIRTUAL_CAMERA)
     public static final int POLICY_TYPE_CAMERA = 5;
 
+    /**
+     * Tells the virtual device framework how to handle activity launches that were blocked due to
+     * the current activity policy.
+     *
+     * <ul>
+     *     <li>{@link #DEVICE_POLICY_DEFAULT}: Show UI informing the user of the blocked activity
+     *     launch on the virtual display that the activity was originally launched on.
+     *     <li>{@link #DEVICE_POLICY_CUSTOM}: Does not inform the user of the blocked activity
+     *     launch. The virtual device owner can use this policy together with
+     *     {@link VirtualDeviceManager.ActivityListener#onActivityLaunchBlocked} to provide custom
+     *     experience on the virtual device.
+     * </ul>
+     */
+    @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_ACTIVITY_CONTROL_API)
+    public static final int POLICY_TYPE_BLOCKED_ACTIVITY_BEHAVIOR = 6;
+
     private final int mLockState;
     @NonNull private final ArraySet<UserHandle> mUsersWithMatchingAccounts;
     @NavigationPolicy
@@ -1174,6 +1190,10 @@
                 mDevicePolicies.delete(POLICY_TYPE_CAMERA);
             }
 
+            if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
+                mDevicePolicies.delete(POLICY_TYPE_BLOCKED_ACTIVITY_BEHAVIOR);
+            }
+
             if ((mAudioPlaybackSessionId != AUDIO_SESSION_ID_GENERATE
                     || mAudioRecordingSessionId != AUDIO_SESSION_ID_GENERATE)
                     && mDevicePolicies.get(POLICY_TYPE_AUDIO, DEVICE_POLICY_DEFAULT)
diff --git a/core/java/android/companion/virtual/flags/flags.aconfig b/core/java/android/companion/virtual/flags/flags.aconfig
index 1e781532..d05d23c 100644
--- a/core/java/android/companion/virtual/flags/flags.aconfig
+++ b/core/java/android/companion/virtual/flags/flags.aconfig
@@ -32,6 +32,13 @@
 }
 
 flag {
+    namespace: "virtual_devices"
+    name: "virtual_display_insets"
+    description: "APIs for specifying virtual display insets (via cutout)"
+    bug: "350007135"
+}
+
+flag {
      namespace: "virtual_devices"
      name: "metrics_collection"
      description: "Enable collection of VDM-related metrics"
@@ -41,12 +48,27 @@
 
 flag {
      namespace: "virtual_devices"
+     name: "activity_control_api"
+     description: "Enable APIs for fine grained activity policy, fallback and callbacks"
+     bug: "333443509"
+}
+
+flag {
+     namespace: "virtual_devices"
      name: "camera_device_awareness"
      description: "Enable device awareness in camera service"
      bug: "305170199"
 }
 
 flag {
+    name: "virtual_rotary"
+    is_exported: true
+    namespace: "virtual_devices"
+    description: "Enable virtual rotary input"
+    bug: "320328752"
+}
+
+flag {
     namespace: "virtual_devices"
     name: "device_aware_drm"
     description: "Makes MediaDrm APIs device-aware"
@@ -74,3 +96,17 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    namespace: "virtual_devices"
+    name: "virtual_display_rotation_api"
+    description: "API for on-demand rotation of virtual displays"
+    bug: "291748430"
+}
+
+flag {
+    namespace: "virtual_devices"
+    name: "high_resolution_scroll"
+    description: "Enable high resolution scroll"
+    bug: "335160780"
+}
diff --git a/core/java/android/content/ClipDescription.java b/core/java/android/content/ClipDescription.java
index 5953890..93724bb 100644
--- a/core/java/android/content/ClipDescription.java
+++ b/core/java/android/content/ClipDescription.java
@@ -136,6 +136,14 @@
             "android.intent.extra.LOGGING_INSTANCE_ID";
 
     /**
+     * The id of the task containing the window that initiated the drag that should be hidden.
+     * Only provided to internal drag handlers as a part of the DRAG_START event.
+     * @hide
+     */
+    public static final String EXTRA_HIDE_DRAG_SOURCE_TASK_ID =
+            "android.intent.extra.HIDE_DRAG_SOURCE_TASK_ID";
+
+    /**
      * Indicates that a ClipData contains potentially sensitive information, such as a
      * password or credit card number.
      * <p>
diff --git a/core/java/android/content/ComponentCallbacks.java b/core/java/android/content/ComponentCallbacks.java
index fb9536f..3acb373 100644
--- a/core/java/android/content/ComponentCallbacks.java
+++ b/core/java/android/content/ComponentCallbacks.java
@@ -58,7 +58,9 @@
      * @deprecated Since API level 14 this is superseded by
      *             {@link ComponentCallbacks2#onTrimMemory}.
      *             Since API level 34 this is never called.
-     *             Apps targeting API level 34 and above may provide an empty implementation.
+     *             If you're overriding ComponentCallbacks2#onTrimMemory and
+     *             your minSdkVersion is greater than API 14, you can provide
+     *             an empty implementation for this method.
      */
     @Deprecated
     void onLowMemory();
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index dfa29738..112507e 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -6068,7 +6068,6 @@
      * @see #CHOOSER_CONTENT_TYPE_ALBUM
      * @see #createChooser(Intent, CharSequence)
      */
-    @FlaggedApi(android.service.chooser.Flags.FLAG_CHOOSER_ALBUM_TEXT)
     public static final String EXTRA_CHOOSER_CONTENT_TYPE_HINT =
             "android.intent.extra.CHOOSER_CONTENT_TYPE_HINT";
 
@@ -6085,7 +6084,6 @@
      *
      * @see #EXTRA_CHOOSER_CONTENT_TYPE_HINT
      */
-    @FlaggedApi(android.service.chooser.Flags.FLAG_CHOOSER_ALBUM_TEXT)
     public static final int CHOOSER_CONTENT_TYPE_ALBUM = 1;
 
     /**
@@ -7630,6 +7628,13 @@
             | FLAG_GRANT_PREFIX_URI_PERMISSION;
 
     /**
+     * Flags that are not normally set by application code, but set for you by the system.
+     */
+    private static final int SYSTEM_ONLY_FLAGS = FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
+            | FLAG_ACTIVITY_BROUGHT_TO_FRONT
+            | FLAG_RECEIVER_FROM_SHELL;
+
+    /**
      * Local flag indicating this instance was created by copy constructor.
      */
     private static final int LOCAL_FLAG_FROM_COPY = 1 << 0;
@@ -7682,6 +7687,11 @@
     @TestApi
     public static final int EXTENDED_FLAG_FILTER_MISMATCH = 1 << 0;
 
+    /**
+     * Extended flags that are not normally set by application code, but set for you by the system.
+     */
+    private static final int SYSTEM_ONLY_EXTENDED_FLAGS = EXTENDED_FLAG_FILTER_MISMATCH;
+
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // toUri() and parseUri() options.
@@ -12625,6 +12635,28 @@
         }
     }
 
+    /**
+     * Prepare this {@link Intent} to enter system_server.
+     *
+     * @hide
+     */
+    public void prepareToEnterSystemServer() {
+        // Refuse possible leaked file descriptors
+        if (hasFileDescriptors()) {
+            throw new IllegalArgumentException("File descriptors passed in Intent");
+        }
+        // These flags are set only by the system, and should be stripped out as soon as the intent
+        // is received by system_server from the caller so it can be properly updated later.
+        removeFlags(SYSTEM_ONLY_FLAGS);
+        removeExtendedFlags(SYSTEM_ONLY_EXTENDED_FLAGS);
+        if (mOriginalIntent != null) {
+            mOriginalIntent.prepareToEnterSystemServer();
+        }
+        if (mSelector != null) {
+            mSelector.prepareToEnterSystemServer();
+        }
+    }
+
     /** @hide */
     public boolean hasWebURI() {
         if (getData() == null) {
diff --git a/core/java/android/content/OWNERS b/core/java/android/content/OWNERS
index a37408b..6d9dc45 100644
--- a/core/java/android/content/OWNERS
+++ b/core/java/android/content/OWNERS
@@ -14,3 +14,4 @@
 per-file ComponentCallbacksController = charlesccchen@google.com
 per-file AttributionSource* = file:/core/java/android/permission/OWNERS
 per-file Broadcast* = file:/BROADCASTS_OWNERS
+per-file ComponentCallbacks*.java = file:/PERFORMANCE_OWNERS
\ No newline at end of file
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 4f06209..57ffed4 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -1331,6 +1331,7 @@
      * This change id is the gatekeeper for all treatments that force a given min aspect ratio.
      * Enabling this change will allow the following min aspect ratio treatments to be applied:
      * <ul>
+     *  <li>OVERRIDE_MIN_ASPECT_RATIO_SMALL
      *  <li>OVERRIDE_MIN_ASPECT_RATIO_MEDIUM
      *  <li>OVERRIDE_MIN_ASPECT_RATIO_LARGE
      * </ul>
@@ -1372,6 +1373,22 @@
     public static final long OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY = 203647190L; // buganizer id
 
     /**
+     * This change id sets the activity's min aspect ratio to a small value as defined by
+     * OVERRIDE_MIN_ASPECT_RATIO_SMALL_VALUE.
+     *
+     * This treatment only takes effect if OVERRIDE_MIN_ASPECT_RATIO is also enabled.
+     * @hide
+     */
+    @ChangeId
+    @Overridable
+    @Disabled
+    // TODO(b/349060719): Add CTS tests.
+    public static final long OVERRIDE_MIN_ASPECT_RATIO_SMALL = 349045028L; // buganizer id
+
+    /** @hide Small override aspect ratio, currently 4:3.  */
+    public static final float OVERRIDE_MIN_ASPECT_RATIO_SMALL_VALUE = 4 / 3f;
+
+    /**
      * This change id sets the activity's min aspect ratio to a medium value as defined by
      * OVERRIDE_MIN_ASPECT_RATIO_MEDIUM_VALUE.
      *
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index df27f9d..52c84dc 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -935,12 +935,11 @@
      *
      * @return {@link IntentSender} object which launches the Private Space Settings Activity, if
      * successful, null otherwise.
-     * @hide
      */
     // Alternatively, a system app can access this api for private profile if they've been granted
     // with the {@code android.Manifest.permission#ACCESS_HIDDEN_PROFILES_FULL} permission.
     @Nullable
-    @FlaggedApi(Flags.FLAG_ALLOW_PRIVATE_PROFILE)
+    @FlaggedApi(Flags.FLAG_GET_PRIVATE_SPACE_SETTINGS)
     @RequiresPermission(conditional = true,
             anyOf = {ACCESS_HIDDEN_PROFILES_FULL, ACCESS_HIDDEN_PROFILES})
     public IntentSender getPrivateSpaceSettingsIntent() {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 282ede3..8c56a9d 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -11436,7 +11436,7 @@
     private static final PropertyInvalidatedCache<ApplicationInfoQuery, ApplicationInfo>
             sApplicationInfoCache =
             new PropertyInvalidatedCache<ApplicationInfoQuery, ApplicationInfo>(
-                    32, PermissionManager.CACHE_KEY_PACKAGE_INFO,
+                    2048, PermissionManager.CACHE_KEY_PACKAGE_INFO,
                     "getApplicationInfo") {
                 @Override
                 public ApplicationInfo recompute(ApplicationInfoQuery query) {
@@ -11537,7 +11537,7 @@
     private static final PropertyInvalidatedCache<PackageInfoQuery, PackageInfo>
             sPackageInfoCache =
             new PropertyInvalidatedCache<PackageInfoQuery, PackageInfo>(
-                    64, PermissionManager.CACHE_KEY_PACKAGE_INFO,
+                    2048, PermissionManager.CACHE_KEY_PACKAGE_INFO,
                     "getPackageInfo") {
                 @Override
                 public PackageInfo recompute(PackageInfoQuery query) {
diff --git a/core/java/android/content/pm/ShortcutServiceInternal.java b/core/java/android/content/pm/ShortcutServiceInternal.java
index 55d0bc1..c811a47 100644
--- a/core/java/android/content/pm/ShortcutServiceInternal.java
+++ b/core/java/android/content/pm/ShortcutServiceInternal.java
@@ -91,6 +91,9 @@
     public abstract void addShortcutChangeCallback(
             @NonNull LauncherApps.ShortcutChangeCallback callback);
 
+    public abstract void removeShortcutChangeCallback(
+            @NonNull LauncherApps.ShortcutChangeCallback callback);
+
     public abstract int getShortcutIconResId(int launcherUserId, @NonNull String callingPackage,
             @NonNull String packageName, @NonNull String shortcutId, int userId);
 
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index a9c07d1..c7d94c6 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -126,7 +126,7 @@
     description: "Talkback focus doesn't move to the 'If you change your Google Account picture…' after swiping next to move the focus from 'Choose a picture'"
     bug: "330835921"
     metadata {
-    	purpose: PURPOSE_BUGFIX
+        purpose: PURPOSE_BUGFIX
   }
 }
 
@@ -136,7 +136,7 @@
     description: "Talkback doesn't announce 'selected' after double tapping the button in the picture list in 'Choose a picture' page."
     bug: "330840549"
     metadata {
-    	purpose: PURPOSE_BUGFIX
+        purpose: PURPOSE_BUGFIX
   }
 }
 
@@ -146,7 +146,37 @@
     description: "Fix potential unexpected behavior due to concurrent file writing"
     bug: "339351031"
     metadata {
-    	purpose: PURPOSE_BUGFIX
+        purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
+    name: "fix_get_user_property_cache"
+    namespace: "multiuser"
+    description: "Cache is not optimised for getUserProperty for values below 0, eg. UserHandler.USER_NULL or UserHandle.USER_ALL"
+    bug: "350416200"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
+    name: "cache_quiet_mode_state"
+    namespace: "multiuser"
+    description: "Optimise quiet mode state retrieval"
+    bug: "350420769"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
+    name: "cache_user_serial_number"
+    namespace: "multiuser"
+    description: "Optimise user serial number retrieval"
+    bug: "340018451"
+    metadata {
+        purpose: PURPOSE_BUGFIX
   }
 }
 
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 273e40a..899c2d6 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -17,6 +17,7 @@
 package android.content.res;
 
 import static android.content.res.Resources.ID_NULL;
+import static android.app.ResourcesManager.ApkKey;
 
 import android.annotation.AnyRes;
 import android.annotation.ArrayRes;
@@ -26,12 +27,14 @@
 import android.annotation.StringRes;
 import android.annotation.StyleRes;
 import android.annotation.TestApi;
+import android.app.ResourcesManager;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration.NativeConfig;
 import android.content.res.loader.ResourcesLoader;
 import android.os.Build;
 import android.os.ParcelFileDescriptor;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
 import android.util.SparseArray;
@@ -264,7 +267,7 @@
             }
 
             sSystemApkAssetsSet = new ArraySet<>(apkAssets);
-            sSystemApkAssets = apkAssets.toArray(new ApkAssets[apkAssets.size()]);
+            sSystemApkAssets = apkAssets.toArray(new ApkAssets[0]);
             if (sSystem == null) {
                 sSystem = new AssetManager(true /*sentinel*/);
             }
@@ -448,7 +451,7 @@
     @Deprecated
     @UnsupportedAppUsage
     public int addAssetPath(String path) {
-        return addAssetPathInternal(path, false /*overlay*/, false /*appAsLib*/);
+        return addAssetPathInternal(List.of(new ApkKey(path, false, false)), false);
     }
 
     /**
@@ -458,7 +461,7 @@
     @Deprecated
     @UnsupportedAppUsage
     public int addAssetPathAsSharedLibrary(String path) {
-        return addAssetPathInternal(path, false /*overlay*/, true /*appAsLib*/);
+        return addAssetPathInternal(List.of(new ApkKey(path, true, false)), false);
     }
 
     /**
@@ -468,55 +471,109 @@
     @Deprecated
     @UnsupportedAppUsage
     public int addOverlayPath(String path) {
-        return addAssetPathInternal(path, true /*overlay*/, false /*appAsLib*/);
+        return addAssetPathInternal(List.of(new ApkKey(path, false, true)), false);
     }
 
     /**
      * @hide
      */
-    public void addSharedLibraryPaths(@NonNull String[] paths) {
-        final int length = paths.length;
-        for (int i = 0; i < length; i++) {
-            addAssetPathInternal(paths[i], false, true);
+    public void addPresetApkKeys(@NonNull List<ApkKey> keys) {
+        addAssetPathInternal(keys, true);
+    }
+
+    private int addAssetPathInternal(List<ApkKey> apkKeys, boolean presetAssets) {
+        Objects.requireNonNull(apkKeys, "apkKeys");
+        if (apkKeys.isEmpty()) {
+            return 0;
+        }
+
+        synchronized (this) {
+            ensureOpenLocked();
+
+            // See if we already have some of the apkKeys loaded.
+            final int originalAssetsCount = mApkAssets.length;
+
+            // Getting an assets' path is a relatively expensive operation, cache them.
+            final ArrayMap<String, Integer> assetPaths = new ArrayMap<>(originalAssetsCount);
+            for (int i = 0; i < originalAssetsCount; i++) {
+                assetPaths.put(mApkAssets[i].getAssetPath(), i);
+            }
+
+            final var newKeys = new ArrayList<ApkKey>(apkKeys.size());
+            int lastFoundIndex = -1;
+            for (int i = 0, pathsSize = apkKeys.size(); i < pathsSize; i++) {
+                final var key = apkKeys.get(i);
+                final var index = assetPaths.get(key.path);
+                if (index == null) {
+                    newKeys.add(key);
+                } else {
+                    lastFoundIndex = index;
+                }
+            }
+            if (newKeys.isEmpty()) {
+                return lastFoundIndex + 1;
+            }
+
+            final var newAssets = loadAssets(newKeys);
+            if (newAssets.isEmpty()) {
+                return 0;
+            }
+            mApkAssets = makeNewAssetsArrayLocked(newAssets);
+            nativeSetApkAssets(mObject, mApkAssets, true, presetAssets);
+            invalidateCachesLocked(-1);
+            return originalAssetsCount + 1;
         }
     }
 
-    private int addAssetPathInternal(String path, boolean overlay, boolean appAsLib) {
-        Objects.requireNonNull(path, "path");
-        synchronized (this) {
-            ensureOpenLocked();
-            final int count = mApkAssets.length;
-
-            // See if we already have it loaded.
-            for (int i = 0; i < count; i++) {
-                if (mApkAssets[i].getAssetPath().equals(path)) {
-                    return i + 1;
-                }
+    /**
+     * Insert the new assets preserving the correct order: all non-loader assets go before all
+     * of the loader assets.
+     */
+    @GuardedBy("this")
+    private @NonNull ApkAssets[] makeNewAssetsArrayLocked(
+            @NonNull ArrayList<ApkAssets> newNonLoaderAssets) {
+        final int originalAssetsCount = mApkAssets.length;
+        int firstLoaderIndex = originalAssetsCount;
+        for (int i = 0; i < originalAssetsCount; i++) {
+            if (mApkAssets[i].isForLoader()) {
+                firstLoaderIndex = i;
+                break;
             }
-
-            final ApkAssets assets;
-            try {
-                if (overlay) {
-                    // TODO(b/70343104): This hardcoded path will be removed once
-                    // addAssetPathInternal is deleted.
-                    final String idmapPath = "/data/resource-cache/"
-                            + path.substring(1).replace('/', '@')
-                            + "@idmap";
-                    assets = ApkAssets.loadOverlayFromPath(idmapPath, 0 /* flags */);
-                } else {
-                    assets = ApkAssets.loadFromPath(path,
-                            appAsLib ? ApkAssets.PROPERTY_DYNAMIC : 0);
-                }
-            } catch (IOException e) {
-                return 0;
-            }
-
-            mApkAssets = Arrays.copyOf(mApkAssets, count + 1);
-            mApkAssets[count] = assets;
-            nativeSetApkAssets(mObject, mApkAssets, true, false);
-            invalidateCachesLocked(-1);
-            return count + 1;
         }
+        final int newAssetsSize = newNonLoaderAssets.size();
+        final var newAssetsArray = new ApkAssets[originalAssetsCount + newAssetsSize];
+        if (firstLoaderIndex > 0) {
+            // This should always be true, but who knows...
+            System.arraycopy(mApkAssets, 0, newAssetsArray, 0, firstLoaderIndex);
+        }
+        for (int i = 0; i < newAssetsSize; i++) {
+            newAssetsArray[firstLoaderIndex + i] = newNonLoaderAssets.get(i);
+        }
+        if (originalAssetsCount > firstLoaderIndex) {
+            System.arraycopy(
+                    mApkAssets, firstLoaderIndex,
+                    newAssetsArray, firstLoaderIndex + newAssetsSize,
+                    originalAssetsCount - firstLoaderIndex);
+        }
+        return newAssetsArray;
+    }
+
+    private static @NonNull ArrayList<ApkAssets> loadAssets(@NonNull ArrayList<ApkKey> keys) {
+        final int pathsSize = keys.size();
+        final var loadedAssets = new ArrayList<ApkAssets>(pathsSize);
+        final var resourcesManager = ResourcesManager.getInstance();
+        for (int i = 0; i < pathsSize; i++) {
+            final var key = keys.get(i);
+            try {
+                // ResourcesManager has a cache of loaded assets, ensuring we don't open the same
+                // file repeatedly, which is useful for the common overlays and registered
+                // shared libraries.
+                loadedAssets.add(resourcesManager.loadApkAssets(key));
+            } catch (IOException e) {
+                Log.w(TAG, "Failed to load asset, key = " + key, e);
+            }
+        }
+        return loadedAssets;
     }
 
     /** @hide */
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
index 5031faa..7b18117 100644
--- a/core/java/android/content/res/ColorStateList.java
+++ b/core/java/android/content/res/ColorStateList.java
@@ -32,6 +32,9 @@
 import android.util.SparseArray;
 import android.util.StateSet;
 import android.util.Xml;
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoOutputStream;
+import android.util.proto.ProtoUtils;
 
 import com.android.internal.R;
 import com.android.internal.graphics.ColorUtils;
@@ -44,7 +47,9 @@
 
 import java.io.IOException;
 import java.lang.ref.WeakReference;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 
 /**
  *
@@ -793,4 +798,61 @@
             return new ColorStateList(stateSpecs, colors);
         }
     };
+
+    /** @hide */
+    public void writeToProto(ProtoOutputStream out) {
+        for (int[] states : mStateSpecs) {
+            long specToken = out.start(ColorStateListProto.STATE_SPECS);
+            for (int state : states) {
+                out.write(ColorStateListProto.StateSpec.STATE, state);
+            }
+            out.end(specToken);
+        }
+        for (int color : mColors) {
+            out.write(ColorStateListProto.COLORS, color);
+        }
+    }
+
+    /** @hide */
+    public static ColorStateList createFromProto(ProtoInputStream in)
+            throws Exception {
+        List<int[]> stateSpecs = new ArrayList<>();
+        List<Integer> colors = new ArrayList<>();
+
+
+        while (in.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+            switch (in.getFieldNumber()) {
+                case (int) ColorStateListProto.COLORS:
+                    colors.add(in.readInt(ColorStateListProto.COLORS));
+                    break;
+                case (int) ColorStateListProto.STATE_SPECS:
+                    final long stateToken = in.start(ColorStateListProto.STATE_SPECS);
+                    List<Integer> states = new ArrayList<>();
+                    while (in.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+                        switch (in.getFieldNumber()) {
+                            case (int) ColorStateListProto.StateSpec.STATE:
+                                states.add(in.readInt(ColorStateListProto.StateSpec.STATE));
+                                break;
+                            default:
+                                Log.w(TAG, "Unhandled field while reading Icon proto!\n"
+                                        + ProtoUtils.currentFieldToString(in));
+                        }
+                    }
+                    int[] statesArray = new int[states.size()];
+                    Arrays.setAll(statesArray, states::get);
+                    stateSpecs.add(statesArray);
+                    in.end(stateToken);
+                    break;
+                default:
+                    Log.w(TAG, "Unhandled field while reading Icon proto!\n"
+                            + ProtoUtils.currentFieldToString(in));
+            }
+        }
+
+        int[][] stateSpecsArray = new int[stateSpecs.size()][];
+        Arrays.setAll(stateSpecsArray, stateSpecs::get);
+        int[] colorsArray = new int[colors.size()];
+        Arrays.setAll(colorsArray, colors::get);
+        return new ColorStateList(stateSpecsArray, colorsArray);
+    }
 }
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index 31cacb7..d874270 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -29,7 +29,6 @@
 import android.annotation.StyleableRes;
 import android.app.LocaleConfig;
 import android.app.ResourcesManager;
-import android.app.ResourcesManager.SharedLibraryAssets;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ActivityInfo.Config;
@@ -48,7 +47,6 @@
 import android.os.LocaleList;
 import android.os.ParcelFileDescriptor;
 import android.os.Trace;
-import android.util.ArrayMap;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.Log;
@@ -147,10 +145,9 @@
     // Cyclical cache used for recently-accessed XML files.
     private int mLastCachedXmlBlockIndex = -1;
 
-    // The number of shared libraries registered within this ResourcesImpl, which is designed to
-    // help to determine whether this ResourcesImpl is outdated on shared library information and
-    // needs to be replaced.
-    private int mSharedLibCount;
+    // The hash that allows to detect when the shared libraries applied to this object have changed,
+    // and it is outdated and needs to be replaced.
+    private final int mAppliedSharedLibsHash;
     private final int[] mCachedXmlBlockCookies = new int[XML_BLOCK_CACHE_SIZE];
     private final String[] mCachedXmlBlockFiles = new String[XML_BLOCK_CACHE_SIZE];
     private final XmlBlock[] mCachedXmlBlocks = new XmlBlock[XML_BLOCK_CACHE_SIZE];
@@ -204,15 +201,8 @@
     public ResourcesImpl(@NonNull AssetManager assets, @Nullable DisplayMetrics metrics,
             @Nullable Configuration config, @NonNull DisplayAdjustments displayAdjustments) {
         mAssets = assets;
-        if (Flags.registerResourcePaths()) {
-            ArrayMap<String, SharedLibraryAssets> sharedLibMap =
-                    ResourcesManager.getInstance().getSharedLibAssetsMap();
-            final int size = sharedLibMap.size();
-            for (int i = 0; i < size; i++) {
-                assets.addSharedLibraryPaths(sharedLibMap.valueAt(i).getAllAssetPaths());
-            }
-            mSharedLibCount = sharedLibMap.size();
-        }
+        mAppliedSharedLibsHash =
+                ResourcesManager.getInstance().updateResourceImplWithRegisteredLibs(this);
         mMetrics.setToDefaults();
         mDisplayAdjustments = displayAdjustments;
         mConfiguration.setToDefaults();
@@ -1615,7 +1605,7 @@
         }
     }
 
-    public int getSharedLibCount() {
-        return mSharedLibCount;
+    public int getAppliedSharedLibsHash() {
+        return mAppliedSharedLibsHash;
     }
 }
diff --git a/core/java/android/credentials/selection/IntentFactory.java b/core/java/android/credentials/selection/IntentFactory.java
index b98a0d8..c521b96 100644
--- a/core/java/android/credentials/selection/IntentFactory.java
+++ b/core/java/android/credentials/selection/IntentFactory.java
@@ -232,7 +232,17 @@
                             oemComponentName,
                             PackageManager.ComponentInfoFlags.of(
                                     PackageManager.MATCH_SYSTEM_ONLY));
-                    if (info.enabled && info.exported) {
+                    boolean oemComponentEnabled = info.enabled;
+                    int runtimeComponentEnabledState = context.getPackageManager()
+                          .getComponentEnabledSetting(oemComponentName);
+                    if (runtimeComponentEnabledState == PackageManager
+                          .COMPONENT_ENABLED_STATE_ENABLED) {
+                          oemComponentEnabled = true;
+                    } else if (runtimeComponentEnabledState == PackageManager
+                          .COMPONENT_ENABLED_STATE_DISABLED) {
+                        oemComponentEnabled = false;
+                    }
+                    if (oemComponentEnabled && info.exported) {
                         intentResultBuilder.setOemUiUsageStatus(IntentCreationResult
                                 .OemUiUsageStatus.SUCCESS);
                         Slog.i(TAG,
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
index ba356bb..6514872 100644
--- a/core/java/android/database/CursorWindow.java
+++ b/core/java/android/database/CursorWindow.java
@@ -16,6 +16,8 @@
 
 package android.database;
 
+import static java.util.Objects.requireNonNull;
+
 import android.annotation.BytesLong;
 import android.annotation.IntRange;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -640,6 +642,7 @@
      */
     public boolean putBlob(byte[] value,
             @IntRange(from = 0) int row, @IntRange(from = 0) int column) {
+        requireNonNull(value);
         acquireReference();
         try {
             return nativePutBlob(mWindowPtr, value, row - mStartPos, column);
@@ -658,6 +661,7 @@
      */
     public boolean putString(String value,
             @IntRange(from = 0) int row, @IntRange(from = 0) int column) {
+        requireNonNull(value);
         acquireReference();
         try {
             return nativePutString(mWindowPtr, value, row - mStartPos, column);
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index faa2c70..e0dc568 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -239,8 +239,8 @@
                     NoPreloadHolder.DEBUG_SQL_STATEMENTS, NoPreloadHolder.DEBUG_SQL_TIME,
                     mConfiguration.lookasideSlotSize, mConfiguration.lookasideSlotCount);
         } catch (SQLiteCantOpenDatabaseException e) {
-            final StringBuilder message = new StringBuilder("Cannot open database '")
-                    .append(file).append('\'')
+            final StringBuilder message = new StringBuilder(e.getMessage())
+                    .append(" '").append(file).append("'")
                     .append(" with flags 0x")
                     .append(Integer.toHexString(mConfiguration.openFlags));
 
@@ -265,12 +265,10 @@
                     message.append(": File ").append(path).append(" is not readable");
                 } else if (Files.isDirectory(path)) {
                     message.append(": Path ").append(path).append(" is a directory");
-                } else {
-                    message.append(": Unable to deduct failure reason");
                 }
             } catch (Throwable th) {
-                message.append(": Unable to deduct failure reason"
-                        + " because filesystem couldn't be examined: ").append(th.getMessage());
+                // Ignore any exceptions generated whilst attempting to create extended diagnostic
+                // messages.
             }
             throw new SQLiteCantOpenDatabaseException(message.toString(), e);
         } finally {
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 32d2a6f..ca3e3d2 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -32,6 +32,7 @@
 import android.app.AppOpsManager;
 import android.companion.virtual.VirtualDeviceManager;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.content.AttributionSource.ScopedParcelState;
 import android.content.Context;
 import android.graphics.ImageFormat;
 import android.graphics.Point;
@@ -45,6 +46,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Parcel;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -293,10 +295,14 @@
     @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
     @TestApi
     public static int getNumberOfCameras(@NonNull Context context) {
-        return _getNumberOfCameras(context.getDeviceId(), getDevicePolicyFromContext(context));
+        try (ScopedParcelState clientAttribution =
+                context.getAttributionSource().asScopedParcelState()) {
+            return _getNumberOfCameras(
+                    clientAttribution.getParcel(), getDevicePolicyFromContext(context));
+        }
     }
 
-    private static native int _getNumberOfCameras(int deviceId, int devicePolicy);
+    private static native int _getNumberOfCameras(Parcel clientAttributionParcel, int devicePolicy);
 
     /**
      * Returns the information about a particular camera.
@@ -321,8 +327,16 @@
     @TestApi
     public static void getCameraInfo(int cameraId, @NonNull Context context,
             int rotationOverride, CameraInfo cameraInfo) {
-        _getCameraInfo(cameraId, rotationOverride, context.getDeviceId(),
-                getDevicePolicyFromContext(context), cameraInfo);
+        try (ScopedParcelState clientAttribution =
+                context.getAttributionSource().asScopedParcelState()) {
+            _getCameraInfo(
+                    cameraId,
+                    rotationOverride,
+                    clientAttribution.getParcel(),
+                    getDevicePolicyFromContext(context),
+                    cameraInfo);
+        }
+
         IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
         IAudioService audioService = IAudioService.Stub.asInterface(b);
         try {
@@ -336,8 +350,12 @@
         }
     }
 
-    private native static void _getCameraInfo(int cameraId, int rotationOverride,
-            int deviceId, int devicePolicy, CameraInfo cameraInfo);
+    private native static void _getCameraInfo(
+            int cameraId,
+            int rotationOverride,
+            Parcel clientAttributionParcel,
+            int devicePolicy,
+            CameraInfo cameraInfo);
 
     private static int getDevicePolicyFromContext(Context context) {
         if (context.getDeviceId() == DEVICE_ID_DEFAULT
@@ -347,7 +365,9 @@
 
         VirtualDeviceManager virtualDeviceManager =
                 context.getSystemService(VirtualDeviceManager.class);
-        return virtualDeviceManager.getDevicePolicy(context.getDeviceId(), POLICY_TYPE_CAMERA);
+        return virtualDeviceManager == null
+                ? DEVICE_POLICY_DEFAULT
+                : virtualDeviceManager.getDevicePolicy(context.getDeviceId(), POLICY_TYPE_CAMERA);
     }
 
     /**
@@ -543,9 +563,17 @@
         }
 
         boolean forceSlowJpegMode = shouldForceSlowJpegMode();
-        return native_setup(new WeakReference<>(this), cameraId,
-                ActivityThread.currentOpPackageName(), rotationOverride, forceSlowJpegMode,
-                context.getDeviceId(), getDevicePolicyFromContext(context));
+
+        try (ScopedParcelState clientAttribution =
+                context.getAttributionSource().asScopedParcelState()) {
+            return native_setup(
+                    new WeakReference<>(this),
+                    cameraId,
+                    rotationOverride,
+                    forceSlowJpegMode,
+                    clientAttribution.getParcel(),
+                    getDevicePolicyFromContext(context));
+        }
     }
 
     private boolean shouldForceSlowJpegMode() {
@@ -628,8 +656,13 @@
     }
 
     @UnsupportedAppUsage
-    private native int native_setup(Object cameraThis, int cameraId, String packageName,
-            int rotationOverride, boolean forceSlowJpegMode, int deviceId, int devicePolicy);
+    private native int native_setup(
+            Object cameraThis,
+            int cameraId,
+            int rotationOverride,
+            boolean forceSlowJpegMode,
+            Parcel clientAttributionParcel,
+            int devicePolicy);
 
     private native final void native_release();
 
@@ -2265,9 +2298,11 @@
         private static final String KEY_MIN_EXPOSURE_COMPENSATION = "min-exposure-compensation";
         private static final String KEY_EXPOSURE_COMPENSATION_STEP = "exposure-compensation-step";
         private static final String KEY_AUTO_EXPOSURE_LOCK = "auto-exposure-lock";
-        private static final String KEY_AUTO_EXPOSURE_LOCK_SUPPORTED = "auto-exposure-lock-supported";
+        private static final String KEY_AUTO_EXPOSURE_LOCK_SUPPORTED =
+                "auto-exposure-lock-supported";
         private static final String KEY_AUTO_WHITEBALANCE_LOCK = "auto-whitebalance-lock";
-        private static final String KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED = "auto-whitebalance-lock-supported";
+        private static final String KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED =
+                "auto-whitebalance-lock-supported";
         private static final String KEY_METERING_AREAS = "metering-areas";
         private static final String KEY_MAX_NUM_METERING_AREAS = "max-num-metering-areas";
         private static final String KEY_ZOOM = "zoom";
@@ -2284,7 +2319,8 @@
         private static final String KEY_RECORDING_HINT = "recording-hint";
         private static final String KEY_VIDEO_SNAPSHOT_SUPPORTED = "video-snapshot-supported";
         private static final String KEY_VIDEO_STABILIZATION = "video-stabilization";
-        private static final String KEY_VIDEO_STABILIZATION_SUPPORTED = "video-stabilization-supported";
+        private static final String KEY_VIDEO_STABILIZATION_SUPPORTED =
+                "video-stabilization-supported";
 
         // Parameter key suffix for supported values.
         private static final String SUPPORTED_VALUES_SUFFIX = "-values";
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index fdd8b04..678bd6b 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -137,6 +137,7 @@
                 BIOMETRIC_WEAK,
                 BIOMETRIC_CONVENIENCE,
                 DEVICE_CREDENTIAL,
+                MANDATORY_BIOMETRICS,
         })
         @Retention(RetentionPolicy.SOURCE)
         @interface Types {}
@@ -214,6 +215,21 @@
          */
         int DEVICE_CREDENTIAL = 1 << 15;
 
+        /**
+         * The bit is used to request for mandatory biometrics.
+         *
+         * <p> The requirements to trigger mandatory biometrics are as follows:
+         * 1. User must have enabled the toggle for mandatory biometrics is settings
+         * 2. User must have enrollments for all {@link #BIOMETRIC_STRONG} sensors available
+         * 3. The device must not be in a trusted location
+         * </p>
+         *
+         * <p> If all the above conditions are satisfied, only {@link #BIOMETRIC_STRONG} sensors
+         * will be eligible for authentication, and device credential fallback will be dropped.
+         * @hide
+         */
+        int MANDATORY_BIOMETRICS = 1 << 16;
+
     }
 
     /**
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index 37a2df8..42f5fc8 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -794,10 +794,15 @@
         public void onDialogDismissed(int reason) {
             // Check the reason and invoke OnClickListener(s) if necessary
             if (reason == DISMISSED_REASON_NEGATIVE) {
-                mNegativeButtonInfo.executor.execute(() -> {
-                    mNegativeButtonInfo.listener.onClick(null, DialogInterface.BUTTON_NEGATIVE);
-                    mIsPromptShowing = false;
-                });
+                if (mNegativeButtonInfo != null) {
+                    mNegativeButtonInfo.executor.execute(() -> {
+                        mNegativeButtonInfo.listener.onClick(null, DialogInterface.BUTTON_NEGATIVE);
+                        mIsPromptShowing = false;
+                    });
+                } else {
+                    mAuthenticationCallback.onAuthenticationError(BIOMETRIC_ERROR_USER_CANCELED,
+                            null /* errString */);
+                }
             } else if (reason == DISMISSED_REASON_CONTENT_VIEW_MORE_OPTIONS) {
                 if (mContentViewMoreOptionsButtonInfo != null) {
                     mContentViewMoreOptionsButtonInfo.executor.execute(() -> {
diff --git a/core/java/android/hardware/biometrics/PromptInfo.java b/core/java/android/hardware/biometrics/PromptInfo.java
index ba9f30d..901f6b7 100644
--- a/core/java/android/hardware/biometrics/PromptInfo.java
+++ b/core/java/android/hardware/biometrics/PromptInfo.java
@@ -195,6 +195,10 @@
             return true;
         } else if (mContentView != null && isContentViewMoreOptionsButtonUsed()) {
             return true;
+        } else if (Flags.mandatoryBiometrics()
+                && (mAuthenticators & BiometricManager.Authenticators.MANDATORY_BIOMETRICS)
+                != 0) {
+            return true;
         }
         return false;
     }
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 6fffb82..056ca93 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -564,7 +564,7 @@
      * {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, then this list will only contain
      * CONTROL_ZOOM_RATIO_RANGE and SCALER_AVAILABLE_MAX_DIGITAL_ZOOM
      *
-     * @see INFO_SESSION_CONFIGURATION_QUERY_VERSION
+     * @see #INFO_SESSION_CONFIGURATION_QUERY_VERSION
      */
     @NonNull
     @FlaggedApi(Flags.FLAG_FEATURE_COMBINATION_QUERY)
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 50d976f..4935389 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -1423,7 +1423,9 @@
      *         {@code false} otherwise.
      * @throws UnsupportedOperationException if the query operation is not supported by the camera
      *                                       device
-     * @throws IllegalArgumentException if the session configuration is invalid
+     * @throws IllegalArgumentException if the session configuration is invalid, including, if it
+     *                                  contains certain non-supported features queryable via
+     *                                  CameraCharacteristics.
      * @throws CameraAccessException if the camera device is no longer connected or has
      *                               encountered a fatal error
      * @throws IllegalStateException if the camera device has been closed
@@ -1691,12 +1693,11 @@
          *
          * <p><b>IMPORTANT:</b></p>
          * <ul>
-         * <li>If feature support can be queried via
-         * {@link CameraCharacteristics#SCALER_MANDATORY_STREAM_COMBINATIONS} or
-         * {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP}, applications should
-         * directly use that route rather than calling this function as: (1) using
-         * {@code CameraCharacteristics} is more efficient, and (2) calling this function with
-         * certain non-supported features will throw a {@link IllegalArgumentException}.</li>
+         * <li>If feature support can be queried via {@link CameraCharacteristics}, applications
+         * should directly use that route rather than calling this function as: (1) using
+         * {@code CameraCharacteristics} is more efficient, and (2) querying a feature explicitly
+         * deemed unsupported by CameraCharacteristics may throw a
+         * {@link IllegalArgumentException}.</li>
          *
          * <li>To minimize {@link SessionConfiguration} creation latency due to its dependency on
          * output surfaces, the application can call this method before acquiring valid
@@ -1724,7 +1725,8 @@
          *
          * @throws CameraAccessException if the camera device is no longer connected or has
          * encountered a fatal error
-         * @throws IllegalArgumentException if the session configuration is invalid
+         * @throws IllegalArgumentException if the session configuration is invalid, including,
+         * if it contains certain non-supported features queryable via CameraCharacteristics.
          *
          * @see CameraCharacteristics#INFO_SESSION_CONFIGURATION_QUERY_VERSION
          * @see SessionConfiguration
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 708f8a1..6201359 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -35,6 +35,7 @@
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.EnabledSince;
 import android.compat.annotation.Overridable;
+import android.content.AttributionSourceState;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.graphics.Point;
@@ -106,6 +107,7 @@
     private final boolean DEBUG = false;
 
     private static final int USE_CALLING_UID = -1;
+    private static final int USE_CALLING_PID = -1;
 
     @SuppressWarnings("unused")
     private static final int API_VERSION_1 = 1;
@@ -418,9 +420,12 @@
     public boolean isConcurrentSessionConfigurationSupported(
             @NonNull Map<String, SessionConfiguration> cameraIdAndSessionConfig)
             throws CameraAccessException {
-        return CameraManagerGlobal.get().isConcurrentSessionConfigurationSupported(
-                cameraIdAndSessionConfig, mContext.getApplicationInfo().targetSdkVersion,
-                mContext.getDeviceId(), getDevicePolicyFromContext(mContext));
+        return CameraManagerGlobal.get()
+                .isConcurrentSessionConfigurationSupported(
+                        cameraIdAndSessionConfig,
+                        mContext.getApplicationInfo().targetSdkVersion,
+                        getClientAttribution(),
+                        getDevicePolicyFromContext(mContext));
     }
 
     /**
@@ -581,7 +586,9 @@
         if (mVirtualDeviceManager == null) {
             mVirtualDeviceManager = context.getSystemService(VirtualDeviceManager.class);
         }
-        return mVirtualDeviceManager.getDevicePolicy(context.getDeviceId(), POLICY_TYPE_CAMERA);
+        return mVirtualDeviceManager == null
+                ? DEVICE_POLICY_DEFAULT
+                : mVirtualDeviceManager.getDevicePolicy(context.getDeviceId(), POLICY_TYPE_CAMERA);
     }
 
     // TODO(b/147726300): Investigate how to support foldables/multi-display devices.
@@ -658,11 +665,14 @@
         }
         try {
             for (String physicalCameraId : physicalCameraIds) {
+                AttributionSourceState clientAttribution = getClientAttribution();
+                clientAttribution.deviceId = DEVICE_ID_DEFAULT;
                 CameraMetadataNative physicalCameraInfo =
-                        cameraService.getCameraCharacteristics(physicalCameraId,
+                        cameraService.getCameraCharacteristics(
+                                physicalCameraId,
                                 mContext.getApplicationInfo().targetSdkVersion,
                                 /*rotationOverride*/ ICameraService.ROTATION_OVERRIDE_NONE,
-                                DEVICE_ID_DEFAULT,
+                                clientAttribution,
                                 DEVICE_POLICY_DEFAULT);
                 StreamConfiguration[] configs = physicalCameraInfo.get(
                         CameraCharacteristics.
@@ -754,9 +764,13 @@
                         "Camera service is currently unavailable");
             }
             try {
-                CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId,
-                        mContext.getApplicationInfo().targetSdkVersion, rotationOverride,
-                        mContext.getDeviceId(), getDevicePolicyFromContext(mContext));
+                CameraMetadataNative info =
+                        cameraService.getCameraCharacteristics(
+                                cameraId,
+                                mContext.getApplicationInfo().targetSdkVersion,
+                                rotationOverride,
+                                getClientAttribution(),
+                                getDevicePolicyFromContext(mContext));
                 characteristics = prepareCameraCharacteristics(cameraId, info, cameraService);
             } catch (ServiceSpecificException e) {
                 throw ExceptionUtils.throwAsPublicException(e);
@@ -949,15 +963,35 @@
     }
 
     /**
+     * Constructs an AttributionSourceState with only the uid, pid, and deviceId fields set
+     *
+     * <p>This method is a temporary stopgap in the transition to using AttributionSource. Currently
+     * AttributionSourceState is only used as a vehicle for passing deviceId, uid, and pid
+     * arguments.</p>
+     *
+     * @hide
+     */
+    public AttributionSourceState getClientAttribution() {
+        // TODO: Send the full contextAttribution over aidl, remove USE_CALLING_*
+        AttributionSourceState contextAttribution =
+                mContext.getAttributionSource().asState();
+        AttributionSourceState clientAttribution =
+                new AttributionSourceState();
+        clientAttribution.uid = USE_CALLING_UID;
+        clientAttribution.pid = USE_CALLING_PID;
+        clientAttribution.deviceId = contextAttribution.deviceId;
+        clientAttribution.packageName = mContext.getOpPackageName();
+        clientAttribution.attributionTag = mContext.getAttributionTag();
+        clientAttribution.next = new AttributionSourceState[0];
+        return clientAttribution;
+    }
+
+    /**
      * Helper for opening a connection to a camera with the given ID.
      *
      * @param cameraId The unique identifier of the camera device to open
      * @param callback The callback for the camera. Must not be null.
      * @param executor The executor to invoke the callback with. Must not be null.
-     * @param uid      The UID of the application actually opening the camera.
-     *                 Must be USE_CALLING_UID unless the caller is a service
-     *                 that is trusted to open the device on behalf of an
-     *                 application and to forward the real UID.
      *
      * @throws CameraAccessException if the camera is disabled by device policy,
      * too many camera devices are already open, or the cameraId does not match
@@ -972,7 +1006,7 @@
      * @see android.app.admin.DevicePolicyManager#setCameraDisabled
      */
     private CameraDevice openCameraDeviceUserAsync(String cameraId,
-            CameraDevice.StateCallback callback, Executor executor, final int uid,
+            CameraDevice.StateCallback callback, Executor executor,
             final int oomScoreOffset, int rotationOverride) throws CameraAccessException {
         CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
         CameraDevice device = null;
@@ -1003,11 +1037,17 @@
                         "Camera service is currently unavailable");
                 }
 
-                cameraUser = cameraService.connectDevice(callbacks, cameraId,
-                    mContext.getOpPackageName(), mContext.getAttributionTag(), uid,
-                    oomScoreOffset, mContext.getApplicationInfo().targetSdkVersion,
-                        rotationOverride, mContext.getDeviceId(),
-                        getDevicePolicyFromContext(mContext));
+                AttributionSourceState clientAttribution =
+                        getClientAttribution();
+                cameraUser =
+                        cameraService.connectDevice(
+                                callbacks,
+                                cameraId,
+                                oomScoreOffset,
+                                mContext.getApplicationInfo().targetSdkVersion,
+                                rotationOverride,
+                                clientAttribution,
+                                getDevicePolicyFromContext(mContext));
             } catch (ServiceSpecificException e) {
                 if (e.errorCode == ICameraService.ERROR_DEPRECATED_HAL) {
                     throw new AssertionError("Should've gone down the shim path");
@@ -1133,8 +1173,8 @@
     public void openCamera(@NonNull String cameraId,
             @NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)
             throws CameraAccessException {
-        openCameraForUid(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),
-                USE_CALLING_UID);
+
+        openCameraImpl(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler));
     }
 
     /**
@@ -1170,8 +1210,8 @@
     public void openCamera(@NonNull String cameraId, boolean overrideToPortrait,
             @Nullable Handler handler,
             @NonNull final CameraDevice.StateCallback callback) throws CameraAccessException {
-        openCameraForUid(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),
-                         USE_CALLING_UID, /*oomScoreOffset*/0,
+        openCameraImpl(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),
+                         /*oomScoreOffset*/0,
                          overrideToPortrait
                                  ? ICameraService.ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT
                                  : ICameraService.ROTATION_OVERRIDE_NONE);
@@ -1219,7 +1259,7 @@
         if (executor == null) {
             throw new IllegalArgumentException("executor was null");
         }
-        openCameraForUid(cameraId, callback, executor, USE_CALLING_UID);
+        openCameraImpl(cameraId, callback, executor);
     }
 
     /**
@@ -1287,13 +1327,13 @@
             throw new IllegalArgumentException(
                     "oomScoreOffset < 0, cannot increase priority of camera client");
         }
-        openCameraForUid(cameraId, callback, executor, USE_CALLING_UID, oomScoreOffset,
+        openCameraImpl(cameraId, callback, executor, oomScoreOffset,
                 getRotationOverride(mContext));
     }
 
     /**
-     * Open a connection to a camera with the given ID, on behalf of another application
-     * specified by clientUid. Also specify the minimum oom score and process state the application
+     * Open a connection to a camera with the given ID, on behalf of another application.
+     * Also specify the minimum oom score and process state the application
      * should have, as seen by the cameraserver.
      *
      * <p>The behavior of this method matches that of {@link #openCamera}, except that it allows
@@ -1301,9 +1341,6 @@
      * done by services trusted by the camera subsystem to act on behalf of applications and
      * to forward the real UID.</p>
      *
-     * @param clientUid
-     *             The UID of the application on whose behalf the camera is being opened.
-     *             Must be USE_CALLING_UID unless the caller is a trusted service.
      * @param oomScoreOffset
      *             The minimum oom score that cameraservice must see for this client.
      * @param rotationOverride
@@ -1311,9 +1348,9 @@
      *             that should be followed for this camera id connection
      * @hide
      */
-    public void openCameraForUid(@NonNull String cameraId,
+    public void openCameraImpl(@NonNull String cameraId,
             @NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor,
-            int clientUid, int oomScoreOffset, int rotationOverride)
+            int oomScoreOffset, int rotationOverride)
             throws CameraAccessException {
 
         if (cameraId == null) {
@@ -1325,29 +1362,24 @@
             throw new IllegalArgumentException("No cameras available on device");
         }
 
-        openCameraDeviceUserAsync(cameraId, callback, executor, clientUid, oomScoreOffset,
+        openCameraDeviceUserAsync(cameraId, callback, executor, oomScoreOffset,
                 rotationOverride);
     }
 
     /**
-     * Open a connection to a camera with the given ID, on behalf of another application
-     * specified by clientUid.
+     * Open a connection to a camera with the given ID, on behalf of another application.
      *
      * <p>The behavior of this method matches that of {@link #openCamera}, except that it allows
      * the caller to specify the UID to use for permission/etc verification. This can only be
      * done by services trusted by the camera subsystem to act on behalf of applications and
      * to forward the real UID.</p>
      *
-     * @param clientUid
-     *             The UID of the application on whose behalf the camera is being opened.
-     *             Must be USE_CALLING_UID unless the caller is a trusted service.
-     *
      * @hide
      */
-    public void openCameraForUid(@NonNull String cameraId,
-            @NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor,
-            int clientUid) throws CameraAccessException {
-        openCameraForUid(cameraId, callback, executor, clientUid, /*oomScoreOffset*/0,
+    public void openCameraImpl(@NonNull String cameraId,
+            @NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor)
+            throws CameraAccessException {
+        openCameraImpl(cameraId, callback, executor, /*oomScoreOffset*/0,
                 getRotationOverride(mContext));
     }
 
@@ -1395,8 +1427,12 @@
         if (CameraManagerGlobal.sCameraServiceDisabled) {
             throw new IllegalArgumentException("No cameras available on device");
         }
-        CameraManagerGlobal.get().setTorchMode(cameraId, enabled, mContext.getDeviceId(),
-                getDevicePolicyFromContext(mContext));
+        CameraManagerGlobal.get()
+                .setTorchMode(
+                        cameraId,
+                        enabled,
+                        getClientAttribution(),
+                        getDevicePolicyFromContext(mContext));
     }
 
     /**
@@ -1459,8 +1495,12 @@
         if (CameraManagerGlobal.sCameraServiceDisabled) {
             throw new IllegalArgumentException("No camera available on device");
         }
-        CameraManagerGlobal.get().turnOnTorchWithStrengthLevel(cameraId, torchStrength,
-                mContext.getDeviceId(), getDevicePolicyFromContext(mContext));
+        CameraManagerGlobal.get()
+                .turnOnTorchWithStrengthLevel(
+                        cameraId,
+                        torchStrength,
+                        getClientAttribution(),
+                        getDevicePolicyFromContext(mContext));
     }
 
     /**
@@ -1486,8 +1526,11 @@
         if (CameraManagerGlobal.sCameraServiceDisabled) {
             throw new IllegalArgumentException("No camera available on device.");
         }
-        return CameraManagerGlobal.get().getTorchStrengthLevel(cameraId, mContext.getDeviceId(),
-                getDevicePolicyFromContext(mContext));
+        return CameraManagerGlobal.get()
+                .getTorchStrengthLevel(
+                        cameraId,
+                        getClientAttribution(),
+                        getDevicePolicyFromContext(mContext));
     }
 
     /**
@@ -2497,7 +2540,9 @@
 
         public boolean isConcurrentSessionConfigurationSupported(
                 @NonNull Map<String, SessionConfiguration> cameraIdsAndSessionConfigurations,
-                int targetSdkVersion, int deviceId, int devicePolicy)
+                int targetSdkVersion,
+                AttributionSourceState clientAttribution,
+                int devicePolicy)
                 throws CameraAccessException {
             if (cameraIdsAndSessionConfigurations == null) {
                 throw new IllegalArgumentException("cameraIdsAndSessionConfigurations was null");
@@ -2515,9 +2560,12 @@
                 for (Set<DeviceCameraInfo> combination : mConcurrentCameraIdCombinations) {
                     Set<DeviceCameraInfo> infos = new ArraySet<>();
                     for (String cameraId : cameraIdsAndSessionConfigurations.keySet()) {
-                        infos.add(new DeviceCameraInfo(cameraId,
-                                devicePolicy == DEVICE_POLICY_DEFAULT
-                                        ? DEVICE_ID_DEFAULT : deviceId));
+                        infos.add(
+                                new DeviceCameraInfo(
+                                        cameraId,
+                                        devicePolicy == DEVICE_POLICY_DEFAULT
+                                                ? DEVICE_ID_DEFAULT
+                                                : clientAttribution.deviceId));
                     }
                     if (combination.containsAll(infos)) {
                         subsetFound = true;
@@ -2539,7 +2587,7 @@
                 }
                 try {
                     return mCameraService.isConcurrentSessionConfigurationSupported(
-                            cameraIdsAndConfigs, targetSdkVersion, deviceId, devicePolicy);
+                            cameraIdsAndConfigs, targetSdkVersion, clientAttribution, devicePolicy);
                 } catch (ServiceSpecificException e) {
                     throw ExceptionUtils.throwAsPublicException(e);
                 } catch (RemoteException e) {
@@ -2578,7 +2626,11 @@
             return false;
         }
 
-        public void setTorchMode(String cameraId, boolean enabled, int deviceId, int devicePolicy)
+        public void setTorchMode(
+                String cameraId,
+                boolean enabled,
+                AttributionSourceState clientAttribution,
+                int devicePolicy)
                 throws CameraAccessException {
             synchronized (mLock) {
                 if (cameraId == null) {
@@ -2592,8 +2644,8 @@
                 }
 
                 try {
-                    cameraService.setTorchMode(cameraId, enabled, mTorchClientBinder, deviceId,
-                            devicePolicy);
+                    cameraService.setTorchMode(
+                            cameraId, enabled, mTorchClientBinder, clientAttribution, devicePolicy);
                 } catch(ServiceSpecificException e) {
                     throw ExceptionUtils.throwAsPublicException(e);
                 } catch (RemoteException e) {
@@ -2603,7 +2655,10 @@
             }
         }
 
-        public void turnOnTorchWithStrengthLevel(String cameraId, int torchStrength, int deviceId,
+        public void turnOnTorchWithStrengthLevel(
+                String cameraId,
+                int torchStrength,
+                AttributionSourceState clientAttribution,
                 int devicePolicy)
                 throws CameraAccessException {
             synchronized (mLock) {
@@ -2618,8 +2673,12 @@
                 }
 
                 try {
-                    cameraService.turnOnTorchWithStrengthLevel(cameraId, torchStrength,
-                            mTorchClientBinder, deviceId, devicePolicy);
+                    cameraService.turnOnTorchWithStrengthLevel(
+                            cameraId,
+                            torchStrength,
+                            mTorchClientBinder,
+                            clientAttribution,
+                            devicePolicy);
                 } catch(ServiceSpecificException e) {
                     throw ExceptionUtils.throwAsPublicException(e);
                 } catch (RemoteException e) {
@@ -2629,7 +2688,8 @@
             }
         }
 
-        public int getTorchStrengthLevel(String cameraId, int deviceId, int devicePolicy)
+        public int getTorchStrengthLevel(
+                String cameraId, AttributionSourceState clientAttribution, int devicePolicy)
                 throws CameraAccessException {
             int torchStrength;
             synchronized (mLock) {
@@ -2644,8 +2704,9 @@
                 }
 
                 try {
-                    torchStrength = cameraService.getTorchStrengthLevel(cameraId, deviceId,
-                            devicePolicy);
+                    torchStrength =
+                            cameraService.getTorchStrengthLevel(
+                                    cameraId, clientAttribution, devicePolicy);
                 } catch(ServiceSpecificException e) {
                     throw ExceptionUtils.throwAsPublicException(e);
                 } catch (RemoteException e) {
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 6968f27..fbed50a 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -57,7 +57,7 @@
  *
  * <p>CaptureRequests can be created by using a {@link Builder} instance,
  * obtained by calling {@link CameraDevice#createCaptureRequest} or {@link
- * CameraManager#createCaptureRequest}</p>
+ * CameraDevice.CameraDeviceSetup#createCaptureRequest}</p>
  *
  * <p>CaptureRequests are given to {@link CameraCaptureSession#capture} or
  * {@link CameraCaptureSession#setRepeatingRequest} to capture images from a camera.</p>
@@ -84,7 +84,7 @@
  * @see CameraCaptureSession#setRepeatingBurst
  * @see CameraDevice#createCaptureRequest
  * @see CameraDevice#createReprocessCaptureRequest
- * @see CameraManager#createCaptureRequest
+ * @see CameraDevice.CameraDeviceSetup#createCaptureRequest
  */
 public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
         implements Parcelable {
@@ -812,8 +812,9 @@
      * A builder for capture requests.
      *
      * <p>To obtain a builder instance, use the
-     * {@link CameraDevice#createCaptureRequest} or {@link CameraManager#createCaptureRequest}
-     * method, which initializes the request fields to one of the templates defined in
+     * {@link CameraDevice#createCaptureRequest} or
+     * {@link CameraDevice.CameraDeviceSetup#createCaptureRequest} method, which
+     * initializes the request fields to one of the templates defined in
      * {@link CameraDevice}.
      *
      * @see CameraDevice#createCaptureRequest
@@ -822,7 +823,7 @@
      * @see CameraDevice#TEMPLATE_STILL_CAPTURE
      * @see CameraDevice#TEMPLATE_VIDEO_SNAPSHOT
      * @see CameraDevice#TEMPLATE_MANUAL
-     * @see CameraManager#createCaptureRequest
+     * @see CameraDevice.CameraDeviceSetup#createCaptureRequest
      */
     public final static class Builder {
 
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java
index df057a1..4ddf602 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java
@@ -71,9 +71,12 @@
             }
 
             try {
-                CameraMetadataNative defaultRequest = cameraService.createDefaultRequest(mCameraId,
-                        templateType, mContext.getDeviceId(),
-                        mCameraManager.getDevicePolicyFromContext(mContext));
+                CameraMetadataNative defaultRequest =
+                        cameraService.createDefaultRequest(
+                                mCameraId,
+                                templateType,
+                                mCameraManager.getClientAttribution(),
+                                mCameraManager.getDevicePolicyFromContext(mContext));
                 CameraDeviceImpl.disableZslIfNeeded(defaultRequest, mTargetSdkVersion,
                         templateType);
 
@@ -104,9 +107,11 @@
             }
 
             try {
-                return cameraService.isSessionConfigurationWithParametersSupported(mCameraId,
-                        mTargetSdkVersion, config,
-                        mContext.getDeviceId(),
+                return cameraService.isSessionConfigurationWithParametersSupported(
+                        mCameraId,
+                        mTargetSdkVersion,
+                        config,
+                        mCameraManager.getClientAttribution(),
                         mCameraManager.getDevicePolicyFromContext(mContext));
             } catch (ServiceSpecificException e) {
                 throw ExceptionUtils.throwAsPublicException(e);
@@ -133,12 +138,14 @@
             }
 
             try {
-                CameraMetadataNative metadata = cameraService.getSessionCharacteristics(
-                        mCameraId, mTargetSdkVersion,
-                        CameraManager.getRotationOverride(mContext),
-                        sessionConfig,
-                        mContext.getDeviceId(),
-                        mCameraManager.getDevicePolicyFromContext(mContext));
+                CameraMetadataNative metadata =
+                        cameraService.getSessionCharacteristics(
+                                mCameraId,
+                                mTargetSdkVersion,
+                                CameraManager.getRotationOverride(mContext),
+                                sessionConfig,
+                                mCameraManager.getClientAttribution(),
+                                mCameraManager.getDevicePolicyFromContext(mContext));
 
                 return mCameraManager.prepareCameraCharacteristics(mCameraId, metadata,
                         cameraService);
diff --git a/core/java/android/hardware/camera2/params/ExtensionSessionConfiguration.java b/core/java/android/hardware/camera2/params/ExtensionSessionConfiguration.java
index 69a6e9b..bf3f59f 100644
--- a/core/java/android/hardware/camera2/params/ExtensionSessionConfiguration.java
+++ b/core/java/android/hardware/camera2/params/ExtensionSessionConfiguration.java
@@ -23,12 +23,13 @@
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraExtensionCharacteristics.Extension;
 import android.hardware.camera2.CameraExtensionSession;
+import android.media.ImageReader;
+
+import com.android.internal.camera.flags.Flags;
 
 import java.util.List;
 import java.util.concurrent.Executor;
 
-import com.android.internal.camera.flags.Flags;
-
 /**
  * A class that aggregates all supported arguments for
  * {@link CameraExtensionSession} initialization.
diff --git a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
index f3b7b91..fb2c2f0 100644
--- a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
+++ b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
@@ -260,7 +260,7 @@
          * smaller sizes, then the resulting
          * {@link android.hardware.camera2.params.SessionConfiguration session configuration} can
          * be tested either by calling {@link CameraDevice#createCaptureSession} or
-         * {@link CameraDeviceSetup#isSessionConfigurationSupported}.
+         * {@link CameraDevice.CameraDeviceSetup#isSessionConfigurationSupported}.
          *
          * @return non-modifiable ascending list of available sizes.
          */
diff --git a/core/java/android/hardware/camera2/params/SessionConfiguration.java b/core/java/android/hardware/camera2/params/SessionConfiguration.java
index 3b2913c..0c55ed5 100644
--- a/core/java/android/hardware/camera2/params/SessionConfiguration.java
+++ b/core/java/android/hardware/camera2/params/SessionConfiguration.java
@@ -130,8 +130,8 @@
      * Create a new {@link SessionConfiguration} with sessionType and output configurations.
      *
      * <p>The SessionConfiguration objects created by this constructor can be used by
-     * {@link CameraDeviceSetup.isSessionConfigurationSupported} and {@link
-     * CameraDeviceSetup.getSessionCharacteristics} to query a camera device's feature
+     * {@link CameraDeviceSetup#isSessionConfigurationSupported} and {@link
+     * CameraDeviceSetup#getSessionCharacteristics} to query a camera device's feature
      * combination support and session specific characteristics. For the SessionConfiguration
      * object to be used to create a capture session, {@link #setStateCallback} must be called to
      * specify the state callback function, and any incomplete OutputConfigurations must be
diff --git a/core/java/android/hardware/devicestate/feature/flags.aconfig b/core/java/android/hardware/devicestate/feature/flags.aconfig
index 12d3f94..a09c84d 100644
--- a/core/java/android/hardware/devicestate/feature/flags.aconfig
+++ b/core/java/android/hardware/devicestate/feature/flags.aconfig
@@ -8,4 +8,13 @@
     description: "Updated DeviceState hasProperty API"
     bug: "293636629"
     is_fixed_read_only: true
+}
+
+flag {
+    name: "device_state_property_migration"
+    is_exported: true
+    namespace: "windowing_sdk"
+    description: "Client migration to updated DeviceStateManager API's"
+    bug: "336640888"
+    is_fixed_read_only: true
 }
\ No newline at end of file
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index 8519722..e9cd37a 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -549,15 +549,20 @@
     }
 
     /**
-     * Request to power a display ON or OFF.
+     * Request to power a display OFF or reset it to a power state it supposed to have.
+     * @param displayId the id of the display
+     * @param state one of {@link android.view.Display#STATE_UNKNOWN} (to reset the state to
+     *  the one the display should have had now), {@link android.view.Display#STATE_OFF}.
+     * @return true if successful, false otherwise
      * @hide
      */
     @RequiresPermission("android.permission.MANAGE_DISPLAYS")
-    public boolean requestDisplayPower(int displayId, boolean on) {
+    public boolean requestDisplayPower(int displayId, int state) {
         try {
-            return mDm.requestDisplayPower(displayId, on);
+            return mDm.requestDisplayPower(displayId, state);
         } catch (RemoteException ex) {
-            Log.e(TAG, "Error trying to request display power " + on, ex);
+            Log.e(TAG, "Error trying to request display power:"
+                    + " state=" + state, ex);
             return false;
         }
     }
@@ -812,6 +817,14 @@
         }
     }
 
+    void setVirtualDisplayRotation(IVirtualDisplayCallback token, @Surface.Rotation int rotation) {
+        try {
+            mDm.setVirtualDisplayRotation(token, rotation);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
     /**
      * Gets the stable device display size, in pixels.
      */
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index b2dcf90..91caedc 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -740,6 +740,12 @@
          */
         void onBlockingScreenOn(Runnable unblocker);
 
+        /**
+         * Called while display is turning to screen state other than state ON to notify that any
+         * pending work from the previous blockScreenOn call should have been cancelled.
+         */
+        void cancelBlockScreenOn();
+
         /** Whether auto brightness update in doze is allowed */
         boolean allowAutoBrightnessInDoze();
     }
@@ -774,6 +780,12 @@
         boolean blockScreenOn(Runnable unblocker);
 
         /**
+         * Called while display is turning to screen state other than state ON to notify that any
+         * pending work from the previous blockScreenOn call should have been cancelled.
+         */
+        void cancelBlockScreenOn();
+
+        /**
          * Get the brightness levels used to determine automatic brightness based on lux levels.
          * @param mode The auto-brightness mode
          *             (AutomaticBrightnessController.AutomaticBrightnessMode)
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index b7c02b0..77277ee 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -117,6 +117,9 @@
     // No permissions required but must be same Uid as the creator.
     void setVirtualDisplayState(in IVirtualDisplayCallback token, boolean isOn);
 
+    // No permissions required but must be same Uid as the creator.
+    void setVirtualDisplayRotation(in IVirtualDisplayCallback token, int rotation);
+
     // Get a stable metric for the device's display size. No permissions required.
     Point getStableDisplaySize();
 
@@ -236,9 +239,9 @@
     @EnforcePermission("MANAGE_DISPLAYS")
     void disableConnectedDisplay(int displayId);
 
-    // Request to power display ON or OFF.
+    // Request to power display OFF or reset it to a power state it supposed to have.
     @EnforcePermission("MANAGE_DISPLAYS")
-    boolean requestDisplayPower(int displayId, boolean on);
+    boolean requestDisplayPower(int displayId, int state);
 
     // Restricts display modes to specified modeIds.
     @EnforcePermission("RESTRICT_DISPLAY_MODES")
diff --git a/core/java/android/hardware/display/VirtualDisplay.java b/core/java/android/hardware/display/VirtualDisplay.java
index 051ce63..6cc938f 100644
--- a/core/java/android/hardware/display/VirtualDisplay.java
+++ b/core/java/android/hardware/display/VirtualDisplay.java
@@ -15,6 +15,7 @@
  */
 package android.hardware.display;
 
+import android.annotation.FlaggedApi;
 import android.view.Display;
 import android.view.Surface;
 
@@ -122,6 +123,28 @@
         }
     }
 
+    /**
+     * Sets the rotation of the virtual display.
+     *
+     * @param rotation the new rotation of the display. May be one of {@link Surface#ROTATION_0},
+     *     {@link Surface#ROTATION_90}, {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}.
+     *     Upon creation, the rotation of the virtual display is always {@link Surface#ROTATION_0}.
+     */
+    @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_VIRTUAL_DISPLAY_ROTATION_API)
+    public void setRotation(@Surface.Rotation int rotation) {
+        if (!android.companion.virtualdevice.flags.Flags.virtualDisplayRotationApi()) {
+            return;
+        }
+        if (rotation != Surface.ROTATION_0 && rotation != Surface.ROTATION_90
+                && rotation != Surface.ROTATION_180 && rotation != Surface.ROTATION_270) {
+            throw new IllegalArgumentException(
+                    "Invalid virtual display rotation value: " + rotation);
+        }
+        if (mToken != null && mDisplay.getRotation() != rotation) {
+            mGlobal.setVirtualDisplayRotation(mToken, rotation);
+        }
+    }
+
     @Override
     public String toString() {
         return "VirtualDisplay{display=" + mDisplay + ", token=" + mToken
diff --git a/core/java/android/hardware/display/VirtualDisplayConfig.java b/core/java/android/hardware/display/VirtualDisplayConfig.java
index 56f69a6..b0994e6 100644
--- a/core/java/android/hardware/display/VirtualDisplayConfig.java
+++ b/core/java/android/hardware/display/VirtualDisplayConfig.java
@@ -31,6 +31,7 @@
 import android.os.Parcelable;
 import android.util.ArraySet;
 import android.view.Display;
+import android.view.DisplayCutout;
 import android.view.Surface;
 
 import java.util.Collections;
@@ -55,9 +56,10 @@
     private final String mUniqueId;
     private final int mDisplayIdToMirror;
     private final boolean mWindowManagerMirroringEnabled;
-    private ArraySet<String> mDisplayCategories = null;
+    private final ArraySet<String> mDisplayCategories;
     private final float mRequestedRefreshRate;
     private final boolean mIsHomeSupported;
+    private final DisplayCutout mDisplayCutout;
 
     private VirtualDisplayConfig(
             @NonNull String name,
@@ -71,7 +73,8 @@
             boolean windowManagerMirroringEnabled,
             @NonNull ArraySet<String> displayCategories,
             float requestedRefreshRate,
-            boolean isHomeSupported) {
+            boolean isHomeSupported,
+            @Nullable DisplayCutout displayCutout) {
         mName = name;
         mWidth = width;
         mHeight = height;
@@ -84,6 +87,7 @@
         mDisplayCategories = displayCategories;
         mRequestedRefreshRate = requestedRefreshRate;
         mIsHomeSupported = isHomeSupported;
+        mDisplayCutout = displayCutout;
     }
 
     /**
@@ -135,6 +139,21 @@
     }
 
     /**
+     * Returns the cutout of this display.
+     *
+     * @return the cutout of the display or {@code null} if none is specified.
+     *
+     * @see Builder#setDisplayCutout
+     * @hide
+     */
+    @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_VIRTUAL_DISPLAY_INSETS)
+    @SystemApi
+    @Nullable
+    public DisplayCutout getDisplayCutout() {
+        return mDisplayCutout;
+    }
+
+    /**
      * Returns the unique identifier for the display. Shouldn't be displayed to the user.
      * @hide
      */
@@ -207,6 +226,7 @@
         dest.writeArraySet(mDisplayCategories);
         dest.writeFloat(mRequestedRefreshRate);
         dest.writeBoolean(mIsHomeSupported);
+        DisplayCutout.ParcelableWrapper.writeCutoutToParcel(mDisplayCutout, dest, flags);
     }
 
     @Override
@@ -232,7 +252,8 @@
                 && mWindowManagerMirroringEnabled == that.mWindowManagerMirroringEnabled
                 && Objects.equals(mDisplayCategories, that.mDisplayCategories)
                 && mRequestedRefreshRate == that.mRequestedRefreshRate
-                && mIsHomeSupported == that.mIsHomeSupported;
+                && mIsHomeSupported == that.mIsHomeSupported
+                && Objects.equals(mDisplayCutout, that.mDisplayCutout);
     }
 
     @Override
@@ -240,7 +261,7 @@
         int hashCode = Objects.hash(
                 mName, mWidth, mHeight, mDensityDpi, mFlags, mSurface, mUniqueId,
                 mDisplayIdToMirror, mWindowManagerMirroringEnabled, mDisplayCategories,
-                mRequestedRefreshRate, mIsHomeSupported);
+                mRequestedRefreshRate, mIsHomeSupported, mDisplayCutout);
         return hashCode;
     }
 
@@ -260,6 +281,7 @@
                 + " mDisplayCategories=" + mDisplayCategories
                 + " mRequestedRefreshRate=" + mRequestedRefreshRate
                 + " mIsHomeSupported=" + mIsHomeSupported
+                + " mDisplayCutout=" + mDisplayCutout
                 + ")";
     }
 
@@ -276,6 +298,7 @@
         mDisplayCategories = (ArraySet<String>) in.readArraySet(null);
         mRequestedRefreshRate = in.readFloat();
         mIsHomeSupported = in.readBoolean();
+        mDisplayCutout = DisplayCutout.ParcelableWrapper.readCutoutFromParcel(in);
     }
 
     @NonNull
@@ -308,6 +331,7 @@
         private ArraySet<String> mDisplayCategories = new ArraySet<>();
         private float mRequestedRefreshRate = 0.0f;
         private boolean mIsHomeSupported = false;
+        private DisplayCutout mDisplayCutout = null;
 
         /**
          * Creates a new Builder.
@@ -469,6 +493,19 @@
         }
 
         /**
+         * Sets the cutout of this display.
+         *
+         * @hide
+         */
+        @FlaggedApi(android.companion.virtualdevice.flags.Flags.FLAG_VIRTUAL_DISPLAY_INSETS)
+        @SystemApi
+        @NonNull
+        public Builder setDisplayCutout(@Nullable DisplayCutout displayCutout) {
+            mDisplayCutout = displayCutout;
+            return this;
+        }
+
+        /**
          * Builds the {@link VirtualDisplayConfig} instance.
          */
         @NonNull
@@ -485,7 +522,8 @@
                     mWindowManagerMirroringEnabled,
                     mDisplayCategories,
                     mRequestedRefreshRate,
-                    mIsHomeSupported);
+                    mIsHomeSupported,
+                    mDisplayCutout);
         }
     }
 }
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 2ded615..903e916 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -699,6 +699,25 @@
     }
 
     /**
+     * Set whether the HAL should ignore display touches.
+     * Only applies to sensors where the HAL is reponsible for handling touches.
+     * @hide
+     */
+    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
+    public void setIgnoreDisplayTouches(long requestId, int sensorId, boolean ignoreTouch) {
+        if (mService == null) {
+            Slog.w(TAG, "setIgnoreDisplayTouches: no fingerprint service");
+            return;
+        }
+
+        try {
+            mService.setIgnoreDisplayTouches(requestId, sensorId, ignoreTouch);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Request fingerprint enrollment. This call warms up the fingerprint hardware
      * and starts scanning for fingerprints. Progress will be indicated by callbacks to the
      * {@link EnrollmentCallback} object. It terminates when
diff --git a/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java b/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java
index f701ec3..d84d292 100644
--- a/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java
+++ b/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java
@@ -120,6 +120,14 @@
     }
 
     /**
+     * Returns if sensor type is ultrasonic Udfps
+     * @return true if sensor is ultrasonic Udfps, false otherwise
+     */
+    public boolean isUltrasonicUdfps() {
+        return sensorType == TYPE_UDFPS_ULTRASONIC;
+    }
+
+    /**
      * Returns if sensor type is side-FPS
      * @return true if sensor is side-fps, false otherwise
      */
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 742fa57..370f097 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -195,6 +195,9 @@
     @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void onUdfpsUiEvent(int event, long requestId, int sensorId);
 
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
+    void setIgnoreDisplayTouches(long requestId, int sensorId, boolean ignoreTouches);
+
     // Sets the controller for managing the UDFPS overlay.
     @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     void setUdfpsOverlayController(in IUdfpsOverlayController controller);
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 40d4fb6..1767d64 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -32,6 +32,7 @@
 import android.os.CombinedVibration;
 import android.hardware.input.IInputSensorEventListener;
 import android.hardware.input.InputSensorInfo;
+import android.hardware.input.KeyGlyphMap;
 import android.hardware.lights.Light;
 import android.hardware.lights.LightState;
 import android.os.IBinder;
@@ -236,4 +237,6 @@
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
             + "android.Manifest.permission.MONITOR_STICKY_MODIFIER_STATE)")
     void unregisterStickyModifierStateListener(IStickyModifierStateListener listener);
+
+    KeyGlyphMap getKeyGlyphMap(int deviceId);
 }
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 53771e3..23e262c 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -19,6 +19,7 @@
 import static com.android.input.flags.Flags.FLAG_INPUT_DEVICE_VIEW_BEHAVIOR_API;
 import static com.android.input.flags.Flags.FLAG_DEVICE_ASSOCIATIONS;
 import static com.android.hardware.input.Flags.keyboardLayoutPreviewFlag;
+import static com.android.hardware.input.Flags.keyboardGlyphMap;
 
 import android.Manifest;
 import android.annotation.FlaggedApi;
@@ -158,6 +159,34 @@
             "android.hardware.input.metadata.KEYBOARD_LAYOUTS";
 
     /**
+     * Broadcast Action: Query available keyboard glyph maps.
+     * <p>
+     * The input manager service locates available keyboard glyph maps
+     * by querying broadcast receivers that are registered for this action.
+     * An application can offer additional keyboard glyph maps to the user
+     * by declaring a suitable broadcast receiver in its manifest.
+     * </p>
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_QUERY_KEYBOARD_GLYPH_MAPS =
+            "android.hardware.input.action.QUERY_KEYBOARD_GLYPH_MAPS";
+
+    /**
+     * Metadata Key: Keyboard glyph map metadata associated with
+     * {@link #ACTION_QUERY_KEYBOARD_GLYPH_MAPS}.
+     * <p>
+     * Specifies the resource id of a XML resource that describes the keyboard
+     * glyph maps that are provided by the application.
+     * </p>
+     *
+     * @hide
+     */
+    public static final String META_DATA_KEYBOARD_GLYPH_MAPS =
+            "android.hardware.input.metadata.KEYBOARD_GLYPH_MAPS";
+
+    /**
      * Prevent touches from being consumed by apps if these touches passed through a non-trusted
      * window from a different UID and are considered unsafe.
      *
@@ -898,6 +927,23 @@
     }
 
     /**
+     * Provides associated glyph map for the keyboard device (if available)
+     *
+     * @hide
+     */
+    @Nullable
+    public KeyGlyphMap getKeyGlyphMap(int deviceId) {
+        if (!keyboardGlyphMap()) {
+            return null;
+        }
+        try {
+            return mIm.getKeyGlyphMap(deviceId);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Injects an input event into the event system, targeting windows owned by the provided uid.
      *
      * If a valid targetUid is provided, the system will only consider injecting the input event
@@ -1025,8 +1071,18 @@
     /**
      * Monitor input on the specified display for gestures.
      *
+     * NOTE: New usages of Gesture Monitors are strongly discouraged. Gesture Monitors are
+     * deprecated, in favor of spy windows (see {@link LayoutParams#INPUT_FEATURE_SPY}).
+     * The spy window should be configured specifically to receive the desired events,
+     * unlike the gesture monitor which receives all events on the display.
+     *
      * @hide
+     * @deprecated
+     * @see LayoutParams#INPUT_FEATURE_SPY
+     * @see android.os.InputConfig#SPY
+     * @see #pilferPointers(IBinder)
      */
+    @Deprecated
     public InputMonitor monitorGestureInput(String name, int displayId) {
         return mGlobal.monitorGestureInput(name, displayId);
     }
diff --git a/core/java/android/hardware/input/KeyGlyphMap.aidl b/core/java/android/hardware/input/KeyGlyphMap.aidl
new file mode 100644
index 0000000..104f1e4
--- /dev/null
+++ b/core/java/android/hardware/input/KeyGlyphMap.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.input;
+
+parcelable KeyGlyphMap;
\ No newline at end of file
diff --git a/core/java/android/hardware/input/KeyGlyphMap.java b/core/java/android/hardware/input/KeyGlyphMap.java
new file mode 100644
index 0000000..49c47a2
--- /dev/null
+++ b/core/java/android/hardware/input/KeyGlyphMap.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.input;
+
+import android.annotation.DrawableRes;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+import android.util.SparseIntArray;
+import android.view.KeyEvent;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This class provides access to device specific key glyphs, modifier glyphs and device specific
+ * shortcuts and keys
+ *
+ * @hide
+ */
+public final class KeyGlyphMap implements Parcelable {
+    private static final String TAG = "KeyGlyphMap";
+
+    @NonNull
+    private final ComponentName mComponentName;
+    @NonNull
+    private final SparseIntArray mKeyGlyphs;
+    @NonNull
+    private final SparseIntArray mModifierGlyphs;
+    @NonNull
+    private final int[] mFunctionRowKeys;
+    @NonNull
+    private final Map<KeyCombination, Integer> mHardwareShortcuts;
+
+    public static final @NonNull Parcelable.Creator<KeyGlyphMap> CREATOR =
+            new Parcelable.Creator<>() {
+                public KeyGlyphMap createFromParcel(Parcel in) {
+                    return new KeyGlyphMap(in);
+                }
+
+                public KeyGlyphMap[] newArray(int size) {
+                    return new KeyGlyphMap[size];
+                }
+            };
+
+    public KeyGlyphMap(@NonNull ComponentName componentName,
+            @NonNull SparseIntArray keyGlyphs, @NonNull SparseIntArray modifierGlyphs,
+            @NonNull int[] functionRowKeys,
+            @NonNull Map<KeyCombination, Integer> hardwareShortcuts) {
+        mComponentName = componentName;
+        mKeyGlyphs = keyGlyphs;
+        mModifierGlyphs = modifierGlyphs;
+        mFunctionRowKeys = functionRowKeys;
+        mHardwareShortcuts = hardwareShortcuts;
+    }
+
+    public KeyGlyphMap(Parcel in) {
+        mComponentName = in.readParcelable(getClass().getClassLoader(), ComponentName.class);
+        mKeyGlyphs = in.readSparseIntArray();
+        mModifierGlyphs = in.readSparseIntArray();
+        mFunctionRowKeys = new int[in.readInt()];
+        in.readIntArray(mFunctionRowKeys);
+        mHardwareShortcuts = new HashMap<>(in.readInt());
+        in.readMap(mHardwareShortcuts, getClass().getClassLoader(), KeyCombination.class,
+                Integer.class);
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeParcelable(mComponentName, 0);
+        dest.writeSparseIntArray(mKeyGlyphs);
+        dest.writeSparseIntArray(mModifierGlyphs);
+        dest.writeInt(mFunctionRowKeys.length);
+        dest.writeIntArray(mFunctionRowKeys);
+        dest.writeInt(mHardwareShortcuts.size());
+        dest.writeMap(mHardwareShortcuts);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Defines a key combination that includes a keycode and modifier state.
+     */
+    public record KeyCombination(int modifierState, int keycode) {}
+
+    /**
+     * Returns keycodes generated from the functional row defined for the keyboard.
+     */
+    public int[] getFunctionRowKeys() {
+        return mFunctionRowKeys;
+    }
+
+    /**
+     * Returns hardware defined shortcuts that are handled in the firmware of a particular
+     * keyboard (e.g. Fn+Backspace = Back, etc.)
+     *
+     * @return a map of (modifier + key) combinations to keycode mappings that are handled by the
+     * device hardware/firmware.
+     */
+    public Map<KeyCombination, Integer> getHardwareShortcuts() {
+        return mHardwareShortcuts;
+    }
+
+    /**
+     * Provides the drawable resource for the glyph for a keycode.
+     * Returns null if not available.
+     */
+    @Nullable
+    public Drawable getDrawableForKeycode(Context context, int keycode) {
+        return getDrawable(context, mKeyGlyphs.get(keycode, 0));
+    }
+
+    /**
+     * Provides the drawable resource for the glyph for a modifier key.
+     * Returns null if not available.
+     */
+    @Nullable
+    public Drawable getDrawableForModifier(Context context, int modifierKeycode) {
+        int modifier = switch (modifierKeycode) {
+            case KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_META_RIGHT -> KeyEvent.META_META_ON;
+            case KeyEvent.KEYCODE_CTRL_LEFT, KeyEvent.KEYCODE_CTRL_RIGHT -> KeyEvent.META_CTRL_ON;
+            case KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_ALT_RIGHT -> KeyEvent.META_ALT_ON;
+            case KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.KEYCODE_SHIFT_RIGHT ->
+                    KeyEvent.META_SHIFT_ON;
+            case KeyEvent.KEYCODE_FUNCTION -> KeyEvent.META_FUNCTION_ON;
+            case KeyEvent.KEYCODE_SYM -> KeyEvent.META_SYM_ON;
+            case KeyEvent.KEYCODE_CAPS_LOCK -> KeyEvent.META_CAPS_LOCK_ON;
+            case KeyEvent.KEYCODE_NUM_LOCK -> KeyEvent.META_NUM_LOCK_ON;
+            case KeyEvent.KEYCODE_SCROLL_LOCK -> KeyEvent.META_SCROLL_LOCK_ON;
+            default -> 0;
+        };
+        return getDrawable(context, mModifierGlyphs.get(modifier, 0));
+    }
+
+    @Nullable
+    private Drawable getDrawable(Context context, @DrawableRes int drawableRes) {
+        PackageManager pm = context.getPackageManager();
+        try {
+            ActivityInfo receiver = pm.getReceiverInfo(mComponentName,
+                    PackageManager.GET_META_DATA
+                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
+                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
+            Resources resources = pm.getResourcesForApplication(receiver.applicationInfo);
+            return resources.getDrawable(drawableRes, null);
+        } catch (PackageManager.NameNotFoundException ignored) {
+            Log.e(TAG, "Package name not found for " + mComponentName);
+        }
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return "KeyGlyphMap{"
+                + "mComponentName=" + mComponentName
+                + ", mKeyGlyphs=" + mKeyGlyphs
+                + ", mModifierGlyphs=" + mModifierGlyphs
+                + ", mFunctionRowKeys=" + Arrays.toString(mFunctionRowKeys)
+                + ", mHardwareShortcuts=" + mHardwareShortcuts
+                + '}';
+    }
+}
diff --git a/core/java/android/hardware/input/VirtualRotaryEncoder.java b/core/java/android/hardware/input/VirtualRotaryEncoder.java
new file mode 100644
index 0000000..bc131df
--- /dev/null
+++ b/core/java/android/hardware/input/VirtualRotaryEncoder.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.input;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.companion.virtual.IVirtualDevice;
+import android.companion.virtualdevice.flags.Flags;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * A virtual rotary encoder representing a scroll input mechanism on a remote device.
+ *
+ * <p>This registers an {@link android.view.InputDevice} that is interpreted like a
+ * physically-connected device and dispatches received events to it.</p>
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_VIRTUAL_ROTARY)
+@SystemApi
+public class VirtualRotaryEncoder extends VirtualInputDevice {
+    /** @hide */
+    public VirtualRotaryEncoder(VirtualRotaryEncoderConfig config, IVirtualDevice virtualDevice,
+            IBinder token) {
+        super(config, virtualDevice, token);
+    }
+
+    /**
+     * Sends a scroll event to the system.
+     *
+     * @param event the event to send
+     */
+    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    public void sendScrollEvent(@NonNull VirtualRotaryEncoderScrollEvent event) {
+        try {
+            if (!mVirtualDevice.sendRotaryEncoderScrollEvent(mToken, event)) {
+                Log.w(TAG, "Failed to send scroll event from virtual rotary "
+                        + mConfig.getInputDeviceName());
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+}
diff --git a/core/java/android/hardware/input/VirtualRotaryEncoderConfig.aidl b/core/java/android/hardware/input/VirtualRotaryEncoderConfig.aidl
new file mode 100644
index 0000000..2d9a899
--- /dev/null
+++ b/core/java/android/hardware/input/VirtualRotaryEncoderConfig.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.input;
+
+parcelable VirtualRotaryEncoderConfig;
diff --git a/core/java/android/hardware/input/VirtualRotaryEncoderConfig.java b/core/java/android/hardware/input/VirtualRotaryEncoderConfig.java
new file mode 100644
index 0000000..8d81fa9
--- /dev/null
+++ b/core/java/android/hardware/input/VirtualRotaryEncoderConfig.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.input;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.companion.virtualdevice.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Configuration for creating a virtual rotary encoder.
+ *
+ * @see android.companion.virtual.VirtualDeviceManager.VirtualDevice#createVirtualRotaryEncoder
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_VIRTUAL_ROTARY)
+@SystemApi
+public final class VirtualRotaryEncoderConfig extends VirtualInputDeviceConfig
+        implements Parcelable {
+    @NonNull
+    public static final Creator<VirtualRotaryEncoderConfig> CREATOR = new Creator<>() {
+        @Override
+        public VirtualRotaryEncoderConfig createFromParcel(Parcel in) {
+            return new VirtualRotaryEncoderConfig(in);
+        }
+
+        @Override
+        public VirtualRotaryEncoderConfig[] newArray(int size) {
+            return new VirtualRotaryEncoderConfig[size];
+        }
+    };
+
+    private VirtualRotaryEncoderConfig(@NonNull VirtualRotaryEncoderConfig.Builder builder) {
+        super(builder);
+    }
+
+    private VirtualRotaryEncoderConfig(@NonNull Parcel in) {
+        super(in);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        super.writeToParcel(dest, flags);
+    }
+
+    /**
+     * Builder for creating a {@link VirtualRotaryEncoderConfig}.
+     */
+    public static final class Builder extends VirtualInputDeviceConfig.Builder<Builder> {
+
+        /**
+         * Builds the {@link VirtualRotaryEncoderConfig} instance.
+         */
+        @NonNull
+        public VirtualRotaryEncoderConfig build() {
+            return new VirtualRotaryEncoderConfig(this);
+        }
+    }
+}
diff --git a/core/java/android/hardware/input/VirtualRotaryEncoderScrollEvent.aidl b/core/java/android/hardware/input/VirtualRotaryEncoderScrollEvent.aidl
new file mode 100644
index 0000000..0b238ee
--- /dev/null
+++ b/core/java/android/hardware/input/VirtualRotaryEncoderScrollEvent.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.input;
+
+parcelable VirtualRotaryEncoderScrollEvent;
diff --git a/core/java/android/hardware/input/VirtualRotaryEncoderScrollEvent.java b/core/java/android/hardware/input/VirtualRotaryEncoderScrollEvent.java
new file mode 100644
index 0000000..3be911abe7
--- /dev/null
+++ b/core/java/android/hardware/input/VirtualRotaryEncoderScrollEvent.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.input;
+
+import android.annotation.FlaggedApi;
+import android.annotation.FloatRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.companion.virtualdevice.flags.Flags;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.SystemClock;
+import android.view.InputEvent;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * An event describing a rotary encoder scroll interaction originating from a remote device.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_VIRTUAL_ROTARY)
+@SystemApi
+public final class VirtualRotaryEncoderScrollEvent implements Parcelable {
+
+    private final float mScrollAmount;
+    private final long mEventTimeNanos;
+
+    private VirtualRotaryEncoderScrollEvent(float scrollAmount, long eventTimeNanos) {
+        mScrollAmount = scrollAmount;
+        mEventTimeNanos = eventTimeNanos;
+    }
+
+    private VirtualRotaryEncoderScrollEvent(@NonNull Parcel parcel) {
+        mScrollAmount = parcel.readFloat();
+        mEventTimeNanos = parcel.readLong();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int parcelableFlags) {
+        parcel.writeFloat(mScrollAmount);
+        parcel.writeLong(mEventTimeNanos);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        return "VirtualRotaryScrollEvent("
+                + " scrollAmount=" + mScrollAmount
+                + " eventTime(ns)=" + mEventTimeNanos;
+    }
+
+    /**
+     * Returns the scroll amount, normalized from -1.0 to 1.0, inclusive.
+     * <p>
+     * Positive values indicate scrolling forward (e.g. down in a vertical list); negative values,
+     * backward.
+     * <p>
+     * Values of 1.0 or -1.0 represent the maximum supported scroll.
+     * </p>
+     */
+    public @FloatRange(from = -1.0f, to = 1.0f) float getScrollAmount() {
+        return mScrollAmount;
+    }
+
+    /**
+     * Returns the time this event occurred, in the {@link SystemClock#uptimeMillis()} time base but
+     * with nanosecond (instead of millisecond) precision.
+     *
+     * @see InputEvent#getEventTime()
+     */
+    public long getEventTimeNanos() {
+        return mEventTimeNanos;
+    }
+
+    /**
+     * Builder for {@link VirtualRotaryEncoderScrollEvent}.
+     */
+    public static final class Builder {
+
+        @FloatRange(from = -1.0f, to = 1.0f) private float mScrollAmount = 0.0f;
+        private long mEventTimeNanos = 0L;
+
+        /**
+         * Creates a {@link VirtualRotaryEncoderScrollEvent} object with the current configuration.
+         */
+        public @NonNull VirtualRotaryEncoderScrollEvent build() {
+            return new VirtualRotaryEncoderScrollEvent(mScrollAmount, mEventTimeNanos);
+        }
+
+        /**
+         * Sets the scroll amount, normalized from -1.0 to 1.0, inclusive.
+         * <p>
+         * Positive values indicate scrolling forward (e.g. down in a vertical list); negative
+         * values, backward.
+         * <p>
+         * Values of 1.0 or -1.0 represent the maximum supported scroll.
+         * </p>
+         * @return this builder, to allow for chaining of calls
+         */
+        public @NonNull Builder setScrollAmount(
+                @FloatRange(from = -1.0f, to = 1.0f) float scrollAmount) {
+            Preconditions.checkArgumentInRange(scrollAmount, -1f, 1f, "scrollAmount");
+            mScrollAmount = scrollAmount;
+            return this;
+        }
+
+        /**
+         * Sets the time (in nanoseconds) when this specific event was generated. This may be
+         * obtained from {@link SystemClock#uptimeMillis()} (with nanosecond precision instead of
+         * millisecond), but can be different depending on the use case.
+         * This field is optional and can be omitted.
+         *
+         * @return this builder, to allow for chaining of calls
+         * @see InputEvent#getEventTime()
+         */
+        public @NonNull Builder setEventTimeNanos(long eventTimeNanos) {
+            if (eventTimeNanos < 0L) {
+                throw new IllegalArgumentException("Event time cannot be negative");
+            }
+            mEventTimeNanos = eventTimeNanos;
+            return this;
+        }
+    }
+
+    public static final @NonNull Creator<VirtualRotaryEncoderScrollEvent> CREATOR =
+            new Creator<VirtualRotaryEncoderScrollEvent>() {
+                public VirtualRotaryEncoderScrollEvent createFromParcel(Parcel source) {
+                    return new VirtualRotaryEncoderScrollEvent(source);
+                }
+
+                public VirtualRotaryEncoderScrollEvent[] newArray(int size) {
+                    return new VirtualRotaryEncoderScrollEvent[size];
+                }
+            };
+}
diff --git a/core/java/android/hardware/input/input_framework.aconfig b/core/java/android/hardware/input/input_framework.aconfig
index ed536ce..16d9ef2 100644
--- a/core/java/android/hardware/input/input_framework.aconfig
+++ b/core/java/android/hardware/input/input_framework.aconfig
@@ -53,4 +53,18 @@
     name: "touchpad_tap_dragging"
     description: "Offers a setting to enable touchpad tap dragging"
     bug: "321978150"
-}
\ No newline at end of file
+}
+
+flag {
+    namespace: "input_native"
+    name: "keyboard_glyph_map"
+    description: "Allows system to provide keyboard specific key drawables and shortcuts via config files"
+    bug: "345440920"
+}
+
+flag {
+    namespace: "input_native"
+    name: "keyboard_a11y_mouse_keys"
+    description: "Controls if the mouse keys accessibility feature for physical keyboard is available to the user"
+    bug: "341799888"
+}
diff --git a/core/java/android/hardware/location/ContextHubInfo.java b/core/java/android/hardware/location/ContextHubInfo.java
index 5012a79..d934970 100644
--- a/core/java/android/hardware/location/ContextHubInfo.java
+++ b/core/java/android/hardware/location/ContextHubInfo.java
@@ -26,6 +26,7 @@
 import android.util.proto.ProtoOutputStream;
 
 import java.util.Arrays;
+import java.util.Objects;
 
 /**
  * @hide
@@ -294,24 +295,38 @@
     @NonNull
     @Override
     public String toString() {
-        String retVal = "";
-        retVal += "ID/handle : " + mId;
-        retVal += ", Name : " + mName;
-        retVal += "\n\tVendor : " + mVendor;
-        retVal += ", Toolchain : " + mToolchain;
-        retVal += ", Toolchain version: 0x" + Integer.toHexString(mToolchainVersion);
-        retVal += "\n\tPlatformVersion : 0x" + Integer.toHexString(mPlatformVersion);
-        retVal += ", SwVersion : "
-                + Byte.toUnsignedInt(mChreApiMajorVersion) + "." + Byte.toUnsignedInt(
-                mChreApiMinorVersion) + "." + Short.toUnsignedInt(mChrePatchVersion);
-        retVal += ", CHRE platform ID: 0x" + Long.toHexString(mChrePlatformId);
-        retVal += "\n\tPeakMips : " + mPeakMips;
-        retVal += ", StoppedPowerDraw : " + mStoppedPowerDrawMw + " mW";
-        retVal += ", PeakPowerDraw : " + mPeakPowerDrawMw + " mW";
-        retVal += ", MaxPacketLength : " + mMaxPacketLengthBytes + " Bytes";
-        retVal += ", SupportsReliableMessage : " + mSupportsReliableMessages;
-
-        return retVal;
+        StringBuilder out = new StringBuilder();
+        out.append("ID/handle : ");
+        out.append(mId);
+        out.append(", Name : ");
+        out.append(mName);
+        out.append("\n\tVendor : ");
+        out.append(mVendor);
+        out.append(", Toolchain : ");
+        out.append(mToolchain);
+        out.append(", Toolchain version: 0x");
+        out.append(Integer.toHexString(mToolchainVersion));
+        out.append("\n\tPlatformVersion : 0x");
+        out.append(Integer.toHexString(mPlatformVersion));
+        out.append(", SwVersion : ");
+        out.append(Byte.toUnsignedInt(mChreApiMajorVersion));
+        out.append(".");
+        out.append(Byte.toUnsignedInt(mChreApiMinorVersion));
+        out.append(".");
+        out.append(Short.toUnsignedInt(mChrePatchVersion));
+        out.append(", CHRE platform ID: 0x");
+        out.append(Long.toHexString(mChrePlatformId));
+        out.append("\n\tPeakMips : ");
+        out.append(mPeakMips);
+        out.append(", StoppedPowerDraw : ");
+        out.append(mStoppedPowerDrawMw);
+        out.append(" mW, PeakPowerDraw : ");
+        out.append(mPeakPowerDrawMw);
+        out.append(" mW, MaxPacketLength : ");
+        out.append(mMaxPacketLengthBytes);
+        out.append(" Bytes, SupportsReliableMessages : ");
+        out.append(mSupportsReliableMessages);
+        return out.toString();
     }
 
     /**
@@ -370,6 +385,20 @@
         return isEqual;
     }
 
+    @Override
+    public int hashCode() {
+        if (!Flags.fixApiCheck()) {
+            return super.hashCode();
+        }
+
+        return Objects.hash(mId, mName, mVendor, mToolchain, mToolchainVersion,
+                getStaticSwVersion(), mChrePlatformId, mPeakMips,
+                mStoppedPowerDrawMw, mSleepPowerDrawMw, mPeakPowerDrawMw,
+                mMaxPacketLengthBytes, mSupportsReliableMessages,
+                Arrays.hashCode(mSupportedSensors),
+                Arrays.hashCode(mMemoryRegions));
+    }
+
     private ContextHubInfo(Parcel in) {
         mId = in.readInt();
         mName = in.readString();
diff --git a/core/java/android/hardware/location/ContextHubIntentEvent.java b/core/java/android/hardware/location/ContextHubIntentEvent.java
index 06c5334..002c683 100644
--- a/core/java/android/hardware/location/ContextHubIntentEvent.java
+++ b/core/java/android/hardware/location/ContextHubIntentEvent.java
@@ -19,6 +19,7 @@
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.app.PendingIntent;
+import android.chre.flags.Flags;
 import android.content.Intent;
 
 import java.util.Objects;
@@ -275,6 +276,16 @@
         return isEqual;
     }
 
+    @Override
+    public int hashCode() {
+        if (!Flags.fixApiCheck()) {
+            return super.hashCode();
+        }
+
+        return Objects.hash(mEventType, mContextHubInfo, mNanoAppId,
+                mNanoAppMessage, mNanoAppAbortCode, mClientAuthorizationState);
+    }
+
     private static void hasExtraOrThrow(Intent intent, String extra) {
         if (!intent.hasExtra(extra)) {
             throw new IllegalArgumentException("Intent did not have extra: " + extra);
diff --git a/core/java/android/hardware/location/MemoryRegion.java b/core/java/android/hardware/location/MemoryRegion.java
index c033228..d95894f 100644
--- a/core/java/android/hardware/location/MemoryRegion.java
+++ b/core/java/android/hardware/location/MemoryRegion.java
@@ -19,9 +19,12 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.chre.flags.Flags;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.util.Objects;
+
 /**
  * @hide
  */
@@ -128,6 +131,16 @@
     }
 
     @Override
+    public int hashCode() {
+        if (!Flags.fixApiCheck()) {
+            return super.hashCode();
+        }
+
+        return Objects.hash(mSizeBytes, mSizeBytesFree, mIsReadable,
+                mIsWritable, mIsExecutable);
+    }
+
+    @Override
     public int describeContents() {
         return 0;
     }
diff --git a/core/java/android/hardware/location/NanoAppMessage.java b/core/java/android/hardware/location/NanoAppMessage.java
index 905caf0..ec0adda 100644
--- a/core/java/android/hardware/location/NanoAppMessage.java
+++ b/core/java/android/hardware/location/NanoAppMessage.java
@@ -26,6 +26,7 @@
 import libcore.util.HexEncoding;
 
 import java.util.Arrays;
+import java.util.Objects;
 
 /**
  * A class describing messages send to or from nanoapps through the Context Hub Service.
@@ -229,27 +230,38 @@
     public String toString() {
         int length = mMessageBody.length;
 
-        String ret = "NanoAppMessage[type = " + mMessageType + ", length = " + mMessageBody.length
-                + " bytes, " + (mIsBroadcasted ? "broadcast" : "unicast") + ", nanoapp = 0x"
-                + Long.toHexString(mNanoAppId) + ", isReliable = "
-                + (mIsReliable ? "true" : "false") + ", messageSequenceNumber = "
-                + mMessageSequenceNumber + "](";
+        StringBuilder out = new StringBuilder();
+        out.append( "NanoAppMessage[type = ");
+        out.append(mMessageType);
+        out.append(", length = ");
+        out.append(mMessageBody.length);
+        out.append(" bytes, ");
+        out.append(mIsBroadcasted ? "broadcast" : "unicast");
+        out.append(", nanoapp = 0x");
+        out.append(Long.toHexString(mNanoAppId));
+        out.append(", isReliable = ");
+        out.append(mIsReliable ? "true" : "false");
+        out.append(", messageSequenceNumber = ");
+        out.append(mMessageSequenceNumber);
+        out.append("](");
+
         if (length > 0) {
-            ret += "data = 0x";
+            out.append("data = 0x");
         }
         for (int i = 0; i < Math.min(length, DEBUG_LOG_NUM_BYTES); i++) {
-            ret += HexEncoding.encodeToString(mMessageBody[i], true /* upperCase */);
+            out.append(HexEncoding.encodeToString(mMessageBody[i],
+                                                  true /* upperCase */));
 
             if ((i + 1) % 4 == 0) {
-                ret += " ";
+                out.append(" ");
             }
         }
         if (length > DEBUG_LOG_NUM_BYTES) {
-            ret += "...";
+            out.append("...");
         }
-        ret += ")";
+        out.append(")");
 
-        return ret;
+        return out.toString();
     }
 
     @Override
@@ -273,4 +285,15 @@
 
         return isEqual;
     }
+
+    @Override
+    public int hashCode() {
+        if (!Flags.fixApiCheck()) {
+            return super.hashCode();
+        }
+
+        return Objects.hash(mNanoAppId, mMessageType, mIsBroadcasted,
+                Arrays.hashCode(mMessageBody), mIsReliable,
+                mMessageSequenceNumber);
+    }
 }
diff --git a/core/java/android/hardware/radio/TunerCallbackAdapter.java b/core/java/android/hardware/radio/TunerCallbackAdapter.java
index f9a2dbb..b1b4de3 100644
--- a/core/java/android/hardware/radio/TunerCallbackAdapter.java
+++ b/core/java/android/hardware/radio/TunerCallbackAdapter.java
@@ -63,48 +63,53 @@
     }
 
     void close() {
+        ProgramList programList;
         synchronized (mLock) {
-            if (mProgramList != null) {
-                mProgramList.close();
+            if (mProgramList == null) {
+                return;
             }
+            programList = mProgramList;
         }
+        programList.close();
     }
 
     void setProgramListObserver(@Nullable ProgramList programList,
             ProgramList.OnCloseListener closeListener) {
         Objects.requireNonNull(closeListener, "CloseListener cannot be null");
+        ProgramList prevProgramList;
         synchronized (mLock) {
-            if (mProgramList != null) {
-                Log.w(TAG, "Previous program list observer wasn't properly closed, closing it...");
-                mProgramList.close();
-            }
+            prevProgramList = mProgramList;
             mProgramList = programList;
-            if (programList == null) {
-                return;
-            }
-            programList.setOnCloseListener(() -> {
-                synchronized (mLock) {
-                    if (mProgramList != programList) {
-                        return;
-                    }
-                    mProgramList = null;
-                    mLastCompleteList = null;
-                }
-                closeListener.onClose();
-            });
-            programList.addOnCompleteListener(() -> {
-                synchronized (mLock) {
-                    if (mProgramList != programList) {
-                        return;
-                    }
-                    mLastCompleteList = programList.toList();
-                    if (mDelayedCompleteCallback) {
-                        Log.d(TAG, "Sending delayed onBackgroundScanComplete callback");
-                        sendBackgroundScanCompleteLocked();
-                    }
-                }
-            });
         }
+        if (prevProgramList != null) {
+            Log.w(TAG, "Previous program list observer wasn't properly closed, closing it...");
+            prevProgramList.close();
+        }
+        if (programList == null) {
+            return;
+        }
+        programList.setOnCloseListener(() -> {
+            synchronized (mLock) {
+                if (mProgramList != programList) {
+                    return;
+                }
+                mProgramList = null;
+                mLastCompleteList = null;
+            }
+            closeListener.onClose();
+        });
+        programList.addOnCompleteListener(() -> {
+            synchronized (mLock) {
+                if (mProgramList != programList) {
+                    return;
+                }
+                mLastCompleteList = programList.toList();
+                if (mDelayedCompleteCallback) {
+                    Log.d(TAG, "Sending delayed onBackgroundScanComplete callback");
+                    sendBackgroundScanCompleteLocked();
+                }
+            }
+        });
     }
 
     @Nullable List<RadioManager.ProgramInfo> getLastCompleteList() {
@@ -245,12 +250,14 @@
     @Override
     public void onProgramListUpdated(ProgramList.Chunk chunk) {
         mHandler.post(() -> {
+            ProgramList programList;
             synchronized (mLock) {
                 if (mProgramList == null) {
                     return;
                 }
-                mProgramList.apply(Objects.requireNonNull(chunk, "Chunk cannot be null"));
+                programList = mProgramList;
             }
+            programList.apply(Objects.requireNonNull(chunk, "Chunk cannot be null"));
         });
     }
 
diff --git a/core/java/android/inputmethodservice/navigationbar/NavigationBarConstants.java b/core/java/android/inputmethodservice/navigationbar/NavigationBarConstants.java
index 93c5439..4bb66ed 100644
--- a/core/java/android/inputmethodservice/navigationbar/NavigationBarConstants.java
+++ b/core/java/android/inputmethodservice/navigationbar/NavigationBarConstants.java
@@ -17,6 +17,7 @@
 package android.inputmethodservice.navigationbar;
 
 import android.annotation.ColorInt;
+import android.graphics.Color;
 
 final class NavigationBarConstants {
     private NavigationBarConstants() {
@@ -27,13 +28,13 @@
     // TODO(b/215443343): Handle this in the drawable then remove this constant.
     static final float NAVBAR_BACK_BUTTON_IME_OFFSET = 2.0f;
 
-    // Copied from "light_mode_icon_color_single_tone" at packages/SettingsLib/res/values/colors.xml
+    // Copied from "white" at packages/SettingsLib/res/values/colors.xml
     @ColorInt
-    static final int LIGHT_MODE_ICON_COLOR_SINGLE_TONE = 0xffffffff;
+    static final int WHITE = Color.WHITE;
 
-    // Copied from "dark_mode_icon_color_single_tone" at packages/SettingsLib/res/values/colors.xml
+    // Copied from "black" at packages/SettingsLib/res/values/colors.xml
     @ColorInt
-    static final int DARK_MODE_ICON_COLOR_SINGLE_TONE = 0x99000000;
+    static final int BLACK = Color.BLACK;
 
     // Copied from "navigation_bar_deadzone_hold"
     static final int NAVIGATION_BAR_DEADZONE_HOLD = 333;
diff --git a/core/java/android/inputmethodservice/navigationbar/NavigationBarView.java b/core/java/android/inputmethodservice/navigationbar/NavigationBarView.java
index e28f345..b522e9b 100644
--- a/core/java/android/inputmethodservice/navigationbar/NavigationBarView.java
+++ b/core/java/android/inputmethodservice/navigationbar/NavigationBarView.java
@@ -16,8 +16,8 @@
 
 package android.inputmethodservice.navigationbar;
 
-import static android.inputmethodservice.navigationbar.NavigationBarConstants.DARK_MODE_ICON_COLOR_SINGLE_TONE;
-import static android.inputmethodservice.navigationbar.NavigationBarConstants.LIGHT_MODE_ICON_COLOR_SINGLE_TONE;
+import static android.inputmethodservice.navigationbar.NavigationBarConstants.BLACK;
+import static android.inputmethodservice.navigationbar.NavigationBarConstants.WHITE;
 import static android.inputmethodservice.navigationbar.NavigationBarConstants.NAVBAR_BACK_BUTTON_IME_OFFSET;
 import static android.inputmethodservice.navigationbar.NavigationBarUtils.dpToPx;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
@@ -83,8 +83,8 @@
         super(context, attrs);
 
         mLightContext = context;
-        mLightIconColor = LIGHT_MODE_ICON_COLOR_SINGLE_TONE;
-        mDarkIconColor = DARK_MODE_ICON_COLOR_SINGLE_TONE;
+        mLightIconColor = WHITE;
+        mDarkIconColor = BLACK;
 
         mConfiguration = new Configuration();
         mTmpLastConfiguration = new Configuration();
diff --git a/core/java/android/os/BatteryConsumer.java b/core/java/android/os/BatteryConsumer.java
index 02f3a25..744f6a8 100644
--- a/core/java/android/os/BatteryConsumer.java
+++ b/core/java/android/os/BatteryConsumer.java
@@ -888,6 +888,13 @@
             return (T) this;
         }
 
+        @SuppressWarnings("unchecked")
+        @NonNull
+        public T addConsumedPowerForCustomComponent(int componentId, double componentPower) {
+            mPowerComponentsBuilder.addConsumedPowerForCustomComponent(componentId, componentPower);
+            return (T) this;
+        }
+
         /**
          * Sets the amount of time used by the specified component, e.g. CPU, WiFi etc.
          *
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 065b3d6..b2f333a 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -9025,6 +9025,10 @@
 
             final int uid = consumer.getUid();
             final Uid u = uidStats.get(uid);
+            if (u == null) {
+                continue;
+            }
+
             final long rxPackets = u.getNetworkActivityPackets(
                     BatteryStats.NETWORK_MOBILE_RX_DATA, STATS_SINCE_CHARGED);
             final long txPackets = u.getNetworkActivityPackets(
diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java
index 90d82e7..61cc23d 100644
--- a/core/java/android/os/BatteryUsageStats.java
+++ b/core/java/android/os/BatteryUsageStats.java
@@ -870,6 +870,16 @@
         }
 
         /**
+         * Returns true if this Builder is configured to hold data for the specified
+         * custom power component ID.
+         */
+        public boolean isSupportedCustomPowerComponent(int componentId) {
+            return componentId >= BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID
+                    && componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID
+                    + mBatteryConsumerDataLayout.customPowerComponentCount;
+        }
+
+        /**
          * Constructs a read-only object using the Builder values.
          */
         @NonNull
diff --git a/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java b/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
new file mode 100644
index 0000000..72b5cf7
--- /dev/null
+++ b/core/java/android/os/ConcurrentMessageQueue/MessageQueue.java
@@ -0,0 +1,1648 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.os;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.os.Handler;
+import android.os.Trace;
+import android.util.Log;
+import android.util.Printer;
+import android.util.SparseArray;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.io.FileDescriptor;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.concurrent.ConcurrentSkipListSet;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Low-level class holding the list of messages to be dispatched by a
+ * {@link Looper}.  Messages are not added directly to a MessageQueue,
+ * but rather through {@link Handler} objects associated with the Looper.
+ *
+ * <p>You can retrieve the MessageQueue for the current thread with
+ * {@link Looper#myQueue() Looper.myQueue()}.
+ */
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
+@android.ravenwood.annotation.RavenwoodNativeSubstitutionClass(
+        "com.android.platform.test.ravenwood.nativesubstitution.MessageQueue_host")
+public final class MessageQueue {
+    private static final String TAG = "ConcurrentMessageQueue";
+    private static final boolean DEBUG = false;
+    private static final boolean TRACE = false;
+
+    // True if the message queue can be quit.
+    private final boolean mQuitAllowed;
+
+    @SuppressWarnings("unused")
+    private long mPtr; // used by native code
+
+    @IntDef(value = {
+        STACK_NODE_MESSAGE,
+        STACK_NODE_ACTIVE,
+        STACK_NODE_PARKED,
+        STACK_NODE_TIMEDPARK})
+    @Retention(RetentionPolicy.SOURCE)
+    private @interface StackNodeType {}
+
+    /*
+     * Stack node types. STACK_NODE_MESSAGE indicates a node containing a message.
+     * The other types indicate what state our Looper thread is in. The bottom of
+     * the stack is always a single state node. Message nodes are added on top.
+     */
+    private static final int STACK_NODE_MESSAGE = 0;
+    /*
+     * Active state indicates that next() is processing messages
+     */
+    private static final int STACK_NODE_ACTIVE = 1;
+    /*
+     * Parked state indicates that the Looper thread is sleeping indefinitely (nothing to deliver)
+     */
+    private static final int STACK_NODE_PARKED = 2;
+    /*
+     * Timed Park state indicates that the Looper thread is sleeping, waiting for a message
+     * deadline
+     */
+    private static final int STACK_NODE_TIMEDPARK = 3;
+
+    /* Describes a node in the Treiber stack */
+    static class StackNode {
+        @StackNodeType
+        private final int mType;
+
+        StackNode(@StackNodeType int type) {
+            mType = type;
+        }
+
+        @StackNodeType
+        final int getNodeType() {
+            return mType;
+        }
+
+        final boolean isMessageNode() {
+            return mType == STACK_NODE_MESSAGE;
+        }
+    }
+
+    static final class MessageNode extends StackNode implements Comparable<MessageNode> {
+        private final Message mMessage;
+        volatile StackNode mNext;
+        StateNode mBottomOfStack;
+        boolean mWokeUp;
+        final long mInsertSeq;
+        private static final VarHandle sRemovedFromStack;
+        private volatile boolean mRemovedFromStackValue;
+        static {
+            try {
+                MethodHandles.Lookup l = MethodHandles.lookup();
+                sRemovedFromStack = l.findVarHandle(MessageQueue.MessageNode.class,
+                        "mRemovedFromStackValue", boolean.class);
+            } catch (Exception e) {
+                Log.wtf(TAG, "VarHandle lookup failed with exception: " + e);
+                throw new ExceptionInInitializerError(e);
+            }
+        }
+
+        MessageNode(@NonNull Message message, long insertSeq) {
+            super(STACK_NODE_MESSAGE);
+            mMessage = message;
+            mInsertSeq = insertSeq;
+        }
+
+        long getWhen() {
+            return mMessage.when;
+        }
+
+        boolean isRemovedFromStack() {
+            return mRemovedFromStackValue;
+        }
+
+        boolean removeFromStack() {
+            return sRemovedFromStack.compareAndSet(this, false, true);
+        }
+
+        boolean isAsync() {
+            return mMessage.isAsynchronous();
+        }
+
+        boolean isBarrier() {
+            return mMessage.target == null;
+        }
+
+        @Override
+        public int compareTo(@NonNull MessageNode messageNode) {
+            Message other = messageNode.mMessage;
+
+            int compared = Long.compare(mMessage.when, other.when);
+            if (compared == 0) {
+                compared = Long.compare(mInsertSeq, messageNode.mInsertSeq);
+            }
+            return compared;
+        }
+    }
+
+    static class StateNode extends StackNode {
+        StateNode(int type) {
+            super(type);
+        }
+    }
+
+    static final class TimedParkStateNode extends StateNode {
+        long mWhenToWake;
+
+        TimedParkStateNode() {
+            super(STACK_NODE_TIMEDPARK);
+        }
+    }
+
+    private static final StateNode sStackStateActive = new StateNode(STACK_NODE_ACTIVE);
+    private static final StateNode sStackStateParked = new StateNode(STACK_NODE_PARKED);
+    private final TimedParkStateNode mStackStateTimedPark = new TimedParkStateNode();
+
+    /* This is the top of our treiber stack. */
+    private static final VarHandle sState;
+    static {
+        try {
+            MethodHandles.Lookup l = MethodHandles.lookup();
+            sState = l.findVarHandle(MessageQueue.class, "mStateValue",
+                    MessageQueue.StackNode.class);
+        } catch (Exception e) {
+            Log.wtf(TAG, "VarHandle lookup failed with exception: " + e);
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
+    private volatile StackNode mStateValue = sStackStateParked;
+    private final ConcurrentSkipListSet<MessageNode> mPriorityQueue =
+            new ConcurrentSkipListSet<MessageNode>();
+    private final ConcurrentSkipListSet<MessageNode> mAsyncPriorityQueue =
+            new ConcurrentSkipListSet<MessageNode>();
+
+    /*
+     * This helps us ensure that messages with the same timestamp are inserted in FIFO order.
+     * Increments on each insert, starting at 0. MessageNode.compareTo() will compare sequences
+     * when delivery timestamps are identical.
+     */
+    private static final VarHandle sNextInsertSeq;
+    private volatile long mNextInsertSeqValue = 0;
+    /*
+     * The exception to the FIFO order rule is sendMessageAtFrontOfQueue().
+     * Those messages must be in LIFO order - SIGH.
+     * Decrements on each front of queue insert.
+     */
+    private static final VarHandle sNextFrontInsertSeq;
+    private volatile long mNextFrontInsertSeqValue = -1;
+    static {
+        try {
+            MethodHandles.Lookup l = MethodHandles.lookup();
+            sNextInsertSeq = l.findVarHandle(MessageQueue.class, "mNextInsertSeqValue",
+                    long.class);
+            sNextFrontInsertSeq = l.findVarHandle(MessageQueue.class, "mNextFrontInsertSeqValue",
+                    long.class);
+        } catch (Exception e) {
+            Log.wtf(TAG, "VarHandle lookup failed with exception: " + e);
+            throw new ExceptionInInitializerError(e);
+        }
+
+    }
+
+    /*
+     * Tracks the number of queued and cancelled messages in our stack.
+     *
+     * On item cancellation, determine whether to wake next() to flush tombstoned messages.
+     * We track queued and cancelled counts as two ints packed into a single long.
+     */
+    private static final class MessageCounts {
+        private static VarHandle sCounts;
+        private volatile long mCountsValue = 0;
+        static {
+            try {
+                MethodHandles.Lookup l = MethodHandles.lookup();
+                sCounts = l.findVarHandle(MessageQueue.MessageCounts.class, "mCountsValue",
+                        long.class);
+            } catch (Exception e) {
+                Log.wtf(TAG, "VarHandle lookup failed with exception: " + e);
+                throw new ExceptionInInitializerError(e);
+            }
+        }
+
+        /* We use a special value to indicate when next() has been woken for flush. */
+        private static final long AWAKE = Long.MAX_VALUE;
+        /*
+         * Minimum number of messages in the stack which we need before we consider flushing
+         * tombstoned items.
+         */
+        private static final int MESSAGE_FLUSH_THRESHOLD = 10;
+
+        private static int numQueued(long val) {
+            return (int) (val >>> Integer.SIZE);
+        }
+
+        private static int numCancelled(long val) {
+            return (int) val;
+        }
+
+        private static long combineCounts(int queued, int cancelled) {
+            return ((long) queued << Integer.SIZE) | (long) cancelled;
+        }
+
+        public void incrementQueued() {
+            while (true) {
+                long oldVal = mCountsValue;
+                int queued = numQueued(oldVal);
+                int cancelled = numCancelled(oldVal);
+                /* Use Math.max() to avoid overflow of queued count */
+                long newVal = combineCounts(Math.max(queued + 1, queued), cancelled);
+
+                /* Don't overwrite 'AWAKE' state */
+                if (oldVal == AWAKE || sCounts.compareAndSet(this, oldVal, newVal)) {
+                    break;
+                }
+            }
+        }
+
+        public boolean incrementCancelled() {
+            while (true) {
+                long oldVal = mCountsValue;
+                if (oldVal == AWAKE) {
+                    return false;
+                }
+                int queued = numQueued(oldVal);
+                int cancelled = numCancelled(oldVal);
+                boolean needsPurge = queued > MESSAGE_FLUSH_THRESHOLD
+                        && (queued >> 1) < cancelled;
+                long newVal;
+                if (needsPurge) {
+                    newVal = AWAKE;
+                } else {
+                    newVal = combineCounts(queued,
+                            Math.max(cancelled + 1, cancelled));
+                }
+
+                if (sCounts.compareAndSet(this, oldVal, newVal)) {
+                    return needsPurge;
+                }
+            }
+        }
+
+        public void clearCounts() {
+            mCountsValue = 0;
+        }
+    }
+
+    private final MessageCounts mMessageCounts = new MessageCounts();
+
+    private final Object mIdleHandlersLock = new Object();
+    @GuardedBy("mIdleHandlersLock")
+    private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();
+    private IdleHandler[] mPendingIdleHandlers;
+
+    private final Object mFileDescriptorRecordsLock = new Object();
+    @GuardedBy("mFileDescriptorRecordsLock")
+    private SparseArray<FileDescriptorRecord> mFileDescriptorRecords;
+
+    private static final VarHandle sQuitting;
+    private boolean mQuittingValue = false;
+    static {
+        try {
+            MethodHandles.Lookup l = MethodHandles.lookup();
+            sQuitting = l.findVarHandle(MessageQueue.class, "mQuittingValue", boolean.class);
+        } catch (Exception e) {
+            Log.wtf(TAG, "VarHandle lookup failed with exception: " + e);
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
+    // The next barrier token.
+    // Barriers are indicated by messages with a null target whose arg1 field carries the token.
+    private final AtomicInteger mNextBarrierToken = new AtomicInteger(1);
+
+    private static native long nativeInit();
+    private static native void nativeDestroy(long ptr);
+    private native void nativePollOnce(long ptr, int timeoutMillis); /*non-static for callbacks*/
+    private static native void nativeWake(long ptr);
+    private static native boolean nativeIsPolling(long ptr);
+    private static native void nativeSetFileDescriptorEvents(long ptr, int fd, int events);
+
+    MessageQueue(boolean quitAllowed) {
+        mQuitAllowed = quitAllowed;
+        mPtr = nativeInit();
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            dispose();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    // Disposes of the underlying message queue.
+    // Must only be called on the looper thread or the finalizer.
+    private void dispose() {
+        if (mPtr != 0) {
+            nativeDestroy(mPtr);
+            mPtr = 0;
+        }
+    }
+
+    /**
+     * Returns true if the looper has no pending messages which are due to be processed.
+     *
+     * <p>This method is safe to call from any thread.
+     *
+     * @return True if the looper is idle.
+     */
+    public boolean isIdle() {
+        MessageNode msgNode = null;
+        MessageNode asyncMsgNode = null;
+
+        if (!mPriorityQueue.isEmpty()) {
+            try {
+                msgNode = mPriorityQueue.first();
+            } catch (NoSuchElementException e) { }
+        }
+
+        if (!mAsyncPriorityQueue.isEmpty()) {
+            try {
+                asyncMsgNode = mAsyncPriorityQueue.first();
+            } catch (NoSuchElementException e) { }
+        }
+
+        final long now = SystemClock.uptimeMillis();
+        if ((msgNode != null && msgNode.getWhen() <= now)
+                || (asyncMsgNode != null && asyncMsgNode.getWhen() <= now)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /* Protects mNextIsDrainingStack */
+    private final ReentrantLock mDrainingLock = new ReentrantLock();
+    private boolean mNextIsDrainingStack = false;
+    private final Condition mDrainCompleted = mDrainingLock.newCondition();
+
+    /**
+     * Add a new {@link IdleHandler} to this message queue.  This may be
+     * removed automatically for you by returning false from
+     * {@link IdleHandler#queueIdle IdleHandler.queueIdle()} when it is
+     * invoked, or explicitly removing it with {@link #removeIdleHandler}.
+     *
+     * <p>This method is safe to call from any thread.
+     *
+     * @param handler The IdleHandler to be added.
+     */
+    public void addIdleHandler(@NonNull IdleHandler handler) {
+        if (handler == null) {
+            throw new NullPointerException("Can't add a null IdleHandler");
+        }
+        synchronized (mIdleHandlersLock) {
+            mIdleHandlers.add(handler);
+        }
+    }
+
+    /**
+     * Remove an {@link IdleHandler} from the queue that was previously added
+     * with {@link #addIdleHandler}.  If the given object is not currently
+     * in the idle list, nothing is done.
+     *
+     * <p>This method is safe to call from any thread.
+     *
+     * @param handler The IdleHandler to be removed.
+     */
+    public void removeIdleHandler(@NonNull IdleHandler handler) {
+        synchronized (mIdleHandlersLock) {
+            mIdleHandlers.remove(handler);
+        }
+    }
+
+    /**
+     * Returns whether this looper's thread is currently polling for more work to do.
+     * This is a good signal that the loop is still alive rather than being stuck
+     * handling a callback.  Note that this method is intrinsically racy, since the
+     * state of the loop can change before you get the result back.
+     *
+     * <p>This method is safe to call from any thread.
+     *
+     * @return True if the looper is currently polling for events.
+     * @hide
+     */
+    public boolean isPolling() {
+        // If the loop is quitting then it must not be idling.
+        // We can assume mPtr != 0 when sQuitting is false.
+        return !((boolean) sQuitting.getVolatile(this)) && nativeIsPolling(mPtr);
+    }
+
+    /* Helper to choose the correct queue to insert into. */
+    private void insertIntoPriorityQueue(MessageNode msgNode) {
+        if (msgNode.isAsync()) {
+            mAsyncPriorityQueue.add(msgNode);
+        } else {
+            mPriorityQueue.add(msgNode);
+        }
+    }
+
+    private boolean removeFromPriorityQueue(MessageNode msgNode) {
+        if (msgNode.isAsync()) {
+            return mAsyncPriorityQueue.remove(msgNode);
+        } else {
+            return mPriorityQueue.remove(msgNode);
+        }
+    }
+
+    private MessageNode pickEarliestNode(MessageNode nodeA, MessageNode nodeB) {
+        if (nodeA != null && nodeB != null) {
+            if (nodeA.compareTo(nodeB) < 0) {
+                return nodeA;
+            }
+            return nodeB;
+        }
+
+        return nodeA != null ? nodeA : nodeB;
+    }
+
+    private MessageNode iterateNext(Iterator<MessageNode> iter) {
+        if (iter.hasNext()) {
+            try {
+                return iter.next();
+            } catch (NoSuchElementException e) {
+                /* The queue is empty - this can happen if we race with remove */
+            }
+        }
+        return null;
+    }
+
+    /* Move any non-cancelled messages into the priority queue */
+    private void drainStack(StackNode oldTop) {
+        while (oldTop.isMessageNode()) {
+            MessageNode oldTopMessageNode = (MessageNode) oldTop;
+            if (oldTopMessageNode.removeFromStack()) {
+                insertIntoPriorityQueue(oldTopMessageNode);
+            }
+            MessageNode inserted = oldTopMessageNode;
+            oldTop = oldTopMessageNode.mNext;
+            /*
+             * removeMessages can walk this list while we are consuming it.
+             * Set our next pointer to null *after* we add the message to our
+             * priority queue. This way removeMessages() will always find the
+             * message, either in our list or in the priority queue.
+             */
+            inserted.mNext = null;
+        }
+    }
+
+    /* Set the stack state to Active, return a list of nodes to walk. */
+    private StackNode swapAndSetStackStateActive() {
+        while (true) {
+            /* Set stack state to Active, get node list to walk later */
+            StackNode current = (StackNode) sState.getVolatile(this);
+            if (current == sStackStateActive
+                    || sState.compareAndSet(this, current, sStackStateActive)) {
+                return current;
+            }
+        }
+    }
+
+    /* This is only read/written from the Looper thread */
+    private int mNextPollTimeoutMillis;
+    private static final AtomicLong mMessagesDelivered = new AtomicLong();
+
+    private Message nextMessage() {
+        int i = 0;
+
+        while (true) {
+            if (DEBUG) {
+                Log.d(TAG, "nextMessage loop #" + i);
+                i++;
+            }
+
+            mDrainingLock.lock();
+            mNextIsDrainingStack = true;
+            mDrainingLock.unlock();
+
+            /*
+             * Set our state to active, drain any items from the stack into our priority queues
+             */
+            StackNode oldTop;
+            oldTop = swapAndSetStackStateActive();
+            drainStack(oldTop);
+
+            mDrainingLock.lock();
+            mNextIsDrainingStack = false;
+            mDrainCompleted.signalAll();
+            mDrainingLock.unlock();
+
+            /*
+             * The objective of this next block of code is to:
+             *  - find a message to return (if any is ready)
+             *  - find a next message we would like to return, after scheduling.
+             *     - we make our scheduling decision based on this next message (if it exists).
+             *
+             * We have two queues to juggle and the presence of barriers throws an additional
+             * wrench into our plans.
+             *
+             * The last wrinkle is that remove() may delete items from underneath us. If we hit
+             * that case, we simply restart the loop.
+             */
+
+            /* Get the first node from each queue */
+            Iterator<MessageNode> queueIter = mPriorityQueue.iterator();
+            MessageNode msgNode = iterateNext(queueIter);
+            Iterator<MessageNode> asyncQueueIter = mAsyncPriorityQueue.iterator();
+            MessageNode asyncMsgNode = iterateNext(asyncQueueIter);
+
+            if (DEBUG) {
+                if (msgNode != null) {
+                    Message msg = msgNode.mMessage;
+                    Log.d(TAG, "Next found node what: " + msg.what + " when: " + msg.when
+                            + " seq: " + msgNode.mInsertSeq + "barrier: "
+                            + msgNode.isBarrier() + " now: " + SystemClock.uptimeMillis());
+                }
+                if (asyncMsgNode != null) {
+                    Message msg = asyncMsgNode.mMessage;
+                    Log.d(TAG, "Next found async node what: " + msg.what + " when: " + msg.when
+                            + " seq: " + asyncMsgNode.mInsertSeq + "barrier: "
+                            + asyncMsgNode.isBarrier() + " now: "
+                            + SystemClock.uptimeMillis());
+                }
+            }
+
+            /*
+             * the node which we will return, null if none are ready
+             */
+            MessageNode found = null;
+            /*
+             * The node from which we will determine our next wakeup time.
+             * Null indicates there is no next message ready. If we found a node,
+             * we can leave this null as Looper will call us again after delivering
+             * the message.
+             */
+            MessageNode next = null;
+
+            long now = SystemClock.uptimeMillis();
+            /*
+             * If we have a barrier we should return the async node (if it exists and is ready)
+             */
+            if (msgNode != null && msgNode.isBarrier()) {
+                if (asyncMsgNode != null && now >= asyncMsgNode.getWhen()) {
+                    found = asyncMsgNode;
+                } else {
+                    next = asyncMsgNode;
+                }
+            } else { /* No barrier. */
+                MessageNode earliest;
+                /*
+                 * If we have two messages, pick the earliest option from either queue.
+                 * Otherwise grab whichever node is non-null. If both are null we'll fall through.
+                 */
+                earliest = pickEarliestNode(msgNode, asyncMsgNode);
+
+                if (earliest != null) {
+                    if (now >= earliest.getWhen()) {
+                        found = earliest;
+                    } else {
+                        next = earliest;
+                    }
+                }
+            }
+
+            if (DEBUG) {
+                if (found != null) {
+                    Message msg = found.mMessage;
+                    Log.d(TAG, "Will deliver node what: " + msg.what + " when: " + msg.when
+                            + " seq: " + found.mInsertSeq + " barrier: " + found.isBarrier()
+                            + " async: " + found.isAsync() + " now: "
+                            + SystemClock.uptimeMillis());
+                } else {
+                    Log.d(TAG, "No node to deliver");
+                }
+                if (next != null) {
+                    Message msg = next.mMessage;
+                    Log.d(TAG, "Next node what: " + msg.what + " when: " + msg.when + " seq: "
+                            + next.mInsertSeq + " barrier: " + next.isBarrier() + " async: "
+                            + next.isAsync()
+                            + " now: " + SystemClock.uptimeMillis());
+                } else {
+                    Log.d(TAG, "No next node");
+                }
+            }
+
+            /*
+             * If we have a found message, we will get called again so there's no need to set state.
+             * In that case we can leave our state as ACTIVE.
+             *
+             * Otherwise we should determine how to park the thread.
+             */
+            StateNode nextOp = sStackStateActive;
+            if (found == null) {
+                if (next == null) {
+                    /* No message to deliver, sleep indefinitely */
+                    mNextPollTimeoutMillis = -1;
+                    nextOp = sStackStateParked;
+                    if (DEBUG) {
+                        Log.d(TAG, "nextMessage next state is StackStateParked");
+                    }
+                } else {
+                    /* Message not ready, or we found one to deliver already, set a timeout */
+                    long nextMessageWhen = next.getWhen();
+                    if (nextMessageWhen > now) {
+                        mNextPollTimeoutMillis = (int) Math.min(nextMessageWhen - now,
+                                Integer.MAX_VALUE);
+                    } else {
+                        mNextPollTimeoutMillis = 0;
+                    }
+
+                    mStackStateTimedPark.mWhenToWake = now + mNextPollTimeoutMillis;
+                    nextOp = mStackStateTimedPark;
+                    if (DEBUG) {
+                        Log.d(TAG, "nextMessage next state is StackStateTimedParked timeout ms "
+                                + mNextPollTimeoutMillis + " mWhenToWake: "
+                                + mStackStateTimedPark.mWhenToWake + " now " + now);
+                    }
+                }
+            }
+
+            /*
+             * Try to swap our state from Active back to Park or TimedPark. If we raced with
+             * enqueue, loop back around to pick up any new items.
+             */
+            if (sState.compareAndSet(this, sStackStateActive, nextOp)) {
+                mMessageCounts.clearCounts();
+                if (found != null) {
+                    if (!removeFromPriorityQueue(found)) {
+                        /*
+                         * RemoveMessages() might be able to pull messages out from under us
+                         * However we can detect that here and just loop around if it happens.
+                         */
+                        continue;
+                    }
+
+                    if (TRACE) {
+                        Trace.setCounter("MQ.Delivered", mMessagesDelivered.incrementAndGet());
+                    }
+                    return found.mMessage;
+                }
+                return null;
+            }
+        }
+    }
+
+    Message next() {
+        final long ptr = mPtr;
+        if (ptr == 0) {
+            return null;
+        }
+
+        mNextPollTimeoutMillis = 0;
+        int pendingIdleHandlerCount = -1; // -1 only during first iteration
+        while (true) {
+            if (mNextPollTimeoutMillis != 0) {
+                Binder.flushPendingCommands();
+            }
+
+            nativePollOnce(ptr, mNextPollTimeoutMillis);
+
+            Message msg = nextMessage();
+            if (msg != null) {
+                msg.markInUse();
+                return msg;
+            }
+
+            if ((boolean) sQuitting.getVolatile(this)) {
+                return null;
+            }
+
+            synchronized (mIdleHandlersLock) {
+                // If first time idle, then get the number of idlers to run.
+                // Idle handles only run if the queue is empty or if the first message
+                // in the queue (possibly a barrier) is due to be handled in the future.
+                if (pendingIdleHandlerCount < 0
+                        && mNextPollTimeoutMillis != 0) {
+                    pendingIdleHandlerCount = mIdleHandlers.size();
+                }
+                if (pendingIdleHandlerCount <= 0) {
+                    // No idle handlers to run.  Loop and wait some more.
+                    continue;
+                }
+
+                if (mPendingIdleHandlers == null) {
+                    mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
+                }
+                mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
+            }
+
+            // Run the idle handlers.
+            // We only ever reach this code block during the first iteration.
+            for (int i = 0; i < pendingIdleHandlerCount; i++) {
+                final IdleHandler idler = mPendingIdleHandlers[i];
+                mPendingIdleHandlers[i] = null; // release the reference to the handler
+
+                boolean keep = false;
+                try {
+                    keep = idler.queueIdle();
+                } catch (Throwable t) {
+                    Log.wtf(TAG, "IdleHandler threw exception", t);
+                }
+
+                if (!keep) {
+                    synchronized (mIdleHandlersLock) {
+                        mIdleHandlers.remove(idler);
+                    }
+                }
+            }
+
+            // Reset the idle handler count to 0 so we do not run them again.
+            pendingIdleHandlerCount = 0;
+
+            // While calling an idle handler, a new message could have been delivered
+            // so go back and look again for a pending message without waiting.
+            mNextPollTimeoutMillis = 0;
+        }
+    }
+
+    void quit(boolean safe) {
+        if (!mQuitAllowed) {
+            throw new IllegalStateException("Main thread not allowed to quit.");
+        }
+        synchronized (mIdleHandlersLock) {
+            if (sQuitting.compareAndSet(this, false, true)) {
+                if (safe) {
+                    removeAllFutureMessages();
+                } else {
+                    removeAllMessages();
+                }
+
+                // We can assume mPtr != 0 because sQuitting was previously false.
+                nativeWake(mPtr);
+            }
+        }
+    }
+
+    boolean enqueueMessage(@NonNull Message msg, long when) {
+        if (msg.target == null) {
+            throw new IllegalArgumentException("Message must have a target.");
+        }
+
+        if (msg.isInUse()) {
+            throw new IllegalStateException(msg + " This message is already in use.");
+        }
+
+        return enqueueMessageUnchecked(msg, when);
+    }
+
+    private boolean enqueueMessageUnchecked(@NonNull Message msg, long when) {
+        if ((boolean) sQuitting.getVolatile(this)) {
+            IllegalStateException e = new IllegalStateException(
+                    msg.target + " sending message to a Handler on a dead thread");
+            Log.w(TAG, e.getMessage(), e);
+            msg.recycleUnchecked();
+            return false;
+        }
+
+        long seq = when != 0 ? ((long)sNextInsertSeq.getAndAdd(this, 1L) + 1L)
+                : ((long)sNextFrontInsertSeq.getAndAdd(this, -1L) - 1L);
+        /* TODO: Add a MessageNode member to Message so we can avoid this allocation */
+        MessageNode node = new MessageNode(msg, seq);
+        msg.when = when;
+        msg.markInUse();
+
+        if (DEBUG) {
+            Log.d(TAG, "Insert message what: " + msg.what + " when: " + msg.when + " seq: "
+                    + node.mInsertSeq + " barrier: " + node.isBarrier() + " async: "
+                    + node.isAsync() + " now: " + SystemClock.uptimeMillis());
+        }
+
+        while (true) {
+            StackNode old = (StackNode) sState.getVolatile(this);
+            boolean wakeNeeded;
+            boolean inactive;
+
+            node.mNext = old;
+            switch (old.getNodeType()) {
+                case STACK_NODE_ACTIVE:
+                    /*
+                     * The worker thread is currently active and will process any elements added to
+                     * the stack before parking again.
+                     */
+                    node.mBottomOfStack = (StateNode) old;
+                    inactive = false;
+                    node.mWokeUp = true;
+                    wakeNeeded = false;
+                    break;
+
+                case STACK_NODE_PARKED:
+                    node.mBottomOfStack = (StateNode) old;
+                    inactive = true;
+                    node.mWokeUp = true;
+                    wakeNeeded = true;
+                    break;
+
+                case STACK_NODE_TIMEDPARK:
+                    node.mBottomOfStack = (StateNode) old;
+                    inactive = true;
+                    wakeNeeded = mStackStateTimedPark.mWhenToWake >= node.getWhen();
+                    node.mWokeUp = wakeNeeded;
+                    break;
+
+                default:
+                    MessageNode oldMessage = (MessageNode) old;
+
+                    node.mBottomOfStack = oldMessage.mBottomOfStack;
+                    int bottomType = node.mBottomOfStack.getNodeType();
+                    inactive = bottomType >= STACK_NODE_PARKED;
+                    wakeNeeded = (bottomType == STACK_NODE_TIMEDPARK
+                            && mStackStateTimedPark.mWhenToWake >= node.getWhen()
+                            && !oldMessage.mWokeUp);
+                    node.mWokeUp = oldMessage.mWokeUp || wakeNeeded;
+                    break;
+            }
+            if (sState.compareAndSet(this, old, node)) {
+                if (inactive) {
+                    if (wakeNeeded) {
+                        nativeWake(mPtr);
+                    } else {
+                        mMessageCounts.incrementQueued();
+                    }
+                }
+                return true;
+            }
+        }
+    }
+
+    /**
+     * Posts a synchronization barrier to the Looper's message queue.
+     *
+     * Message processing occurs as usual until the message queue encounters the
+     * synchronization barrier that has been posted.  When the barrier is encountered,
+     * later synchronous messages in the queue are stalled (prevented from being executed)
+     * until the barrier is released by calling {@link #removeSyncBarrier} and specifying
+     * the token that identifies the synchronization barrier.
+     *
+     * This method is used to immediately postpone execution of all subsequently posted
+     * synchronous messages until a condition is met that releases the barrier.
+     * Asynchronous messages (see {@link Message#isAsynchronous} are exempt from the barrier
+     * and continue to be processed as usual.
+     *
+     * This call must be always matched by a call to {@link #removeSyncBarrier} with
+     * the same token to ensure that the message queue resumes normal operation.
+     * Otherwise the application will probably hang!
+     *
+     * @return A token that uniquely identifies the barrier.  This token must be
+     * passed to {@link #removeSyncBarrier} to release the barrier.
+     *
+     * @hide
+     */
+    @TestApi
+    public int postSyncBarrier() {
+        return postSyncBarrier(SystemClock.uptimeMillis());
+    }
+
+    private int postSyncBarrier(long when) {
+        final int token = mNextBarrierToken.getAndIncrement();
+        final Message msg = Message.obtain();
+
+        msg.markInUse();
+        msg.arg1 = token;
+
+        if (!enqueueMessageUnchecked(msg, when)) {
+            Log.wtf(TAG, "Unexpected error while adding sync barrier!");
+            return -1;
+        }
+
+        return token;
+    }
+
+    private class MatchBarrierToken extends MessageCompare {
+        int mBarrierToken;
+
+        MatchBarrierToken(int token) {
+            super();
+            mBarrierToken = token;
+        }
+
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            if (m.target == null && m.arg1 == mBarrierToken) {
+                return true;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Removes a synchronization barrier.
+     *
+     * @param token The synchronization barrier token that was returned by
+     * {@link #postSyncBarrier}.
+     *
+     * @throws IllegalStateException if the barrier was not found.
+     *
+     * @hide
+     */
+    @TestApi
+    public void removeSyncBarrier(int token) {
+        boolean removed;
+        MessageNode first;
+        final MatchBarrierToken matchBarrierToken = new MatchBarrierToken(token);
+
+        try {
+            /* Retain the first element to see if we are currently stuck on a barrier. */
+            first = mPriorityQueue.first();
+        } catch (NoSuchElementException e) {
+            /* The queue is empty */
+            first = null;
+        }
+
+        removed = findOrRemoveMessages(null, 0, null, null, 0, matchBarrierToken, true);
+        if (removed && first != null) {
+            Message m = first.mMessage;
+            if (m.target == null && m.arg1 == token) {
+                /* Wake up next() in case it was sleeping on this barrier. */
+                nativeWake(mPtr);
+            }
+        } else if (!removed) {
+            throw new IllegalStateException("The specified message queue synchronization "
+                    + " barrier token has not been posted or has already been removed.");
+        }
+    }
+
+    private StateNode getStateNode(StackNode node) {
+        if (node.isMessageNode()) {
+            return ((MessageNode) node).mBottomOfStack;
+        }
+        return (StateNode) node;
+    }
+
+    private void waitForDrainCompleted() {
+        mDrainingLock.lock();
+        while (mNextIsDrainingStack) {
+            mDrainCompleted.awaitUninterruptibly();
+        }
+        mDrainingLock.unlock();
+    }
+
+    /*
+     * This class is used to find matches for hasMessages() and removeMessages()
+     */
+    private abstract static class MessageCompare {
+        public abstract boolean compareMessage(Message m, Handler h, int what, Object object,
+                Runnable r, long when);
+    }
+
+    private boolean stackHasMessages(Handler h, int what, Object object, Runnable r, long when,
+            MessageCompare compare, boolean removeMatches) {
+        boolean found = false;
+        StackNode top = (StackNode) sState.getVolatile(this);
+        StateNode bottom = getStateNode(top);
+
+        /*
+         * If the top node is a state node, there are no reachable messages.
+         * If it's anything other than Active, we can quit as we know that next() is not
+         * consuming items.
+         * If the top node is Active then we know that next() is currently consuming items.
+         * In that case we should wait next() has drained the stack.
+         */
+        if (top == bottom) {
+            if (bottom != sStackStateActive) {
+                return false;
+            }
+            waitForDrainCompleted();
+            return false;
+        }
+
+        /*
+         * We have messages that we may tombstone. Walk the stack until we hit the bottom or we
+         * hit a null pointer.
+         * If we hit the bottom, we are done.
+         * If we hit a null pointer, then the stack is being consumed by next() and we must cycle
+         * until the stack has been drained.
+         */
+        MessageNode p = (MessageNode) top;
+
+        while (true) {
+            if (compare.compareMessage(p.mMessage, h, what, object, r, when)) {
+                found = true;
+                if (DEBUG) {
+                    Log.w(TAG, "stackHasMessages node matches");
+                }
+                if (removeMatches) {
+                    if (p.removeFromStack()) {
+                        p.mMessage.recycleUnchecked();
+                        if (mMessageCounts.incrementCancelled()) {
+                            nativeWake(mPtr);
+                        }
+                    }
+                } else {
+                    return true;
+                }
+            }
+
+            StackNode n = p.mNext;
+            if (n == null) {
+                /* Next() is walking the stack, we must re-sample */
+                if (DEBUG) {
+                    Log.d(TAG, "stackHasMessages next() is walking the stack, we must re-sample");
+                }
+                waitForDrainCompleted();
+                break;
+            }
+            if (!n.isMessageNode()) {
+                /* We reached the end of the stack */
+                return found;
+            }
+            p = (MessageNode) n;
+        }
+
+        return found;
+    }
+
+    private boolean priorityQueueHasMessage(ConcurrentSkipListSet<MessageNode> queue, Handler h,
+            int what, Object object, Runnable r, long when, MessageCompare compare,
+            boolean removeMatches) {
+        Iterator<MessageNode> iterator = queue.iterator();
+        boolean found = false;
+
+        while (iterator.hasNext()) {
+            MessageNode msg = iterator.next();
+
+            if (compare.compareMessage(msg.mMessage, h, what, object, r, when)) {
+                if (removeMatches) {
+                    found = true;
+                    if (queue.remove(msg)) {
+                        msg.mMessage.recycleUnchecked();
+                    }
+                } else {
+                    return true;
+                }
+            }
+        }
+        return found;
+    }
+
+    private boolean findOrRemoveMessages(Handler h, int what, Object object, Runnable r, long when,
+            MessageCompare compare, boolean removeMatches) {
+        boolean foundInStack, foundInQueue;
+
+        foundInStack = stackHasMessages(h, what, object, r, when, compare, removeMatches);
+        foundInQueue = priorityQueueHasMessage(mPriorityQueue, h, what, object, r, when, compare,
+                removeMatches);
+        foundInQueue |= priorityQueueHasMessage(mAsyncPriorityQueue, h, what, object, r, when,
+                compare, removeMatches);
+
+        return foundInStack || foundInQueue;
+    }
+
+    private static class MatchHandlerWhatAndObject extends MessageCompare {
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            if (m.target == h && m.what == what && (object == null || m.obj == object)) {
+                return true;
+            }
+            return false;
+        }
+    }
+    private final MatchHandlerWhatAndObject mMatchHandlerWhatAndObject =
+            new MatchHandlerWhatAndObject();
+    boolean hasMessages(Handler h, int what, Object object) {
+        if (h == null) {
+            return false;
+        }
+
+        return findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObject, false);
+    }
+
+    private static class MatchHandlerWhatAndObjectEquals extends MessageCompare {
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            if (m.target == h && m.what == what && (object == null || object.equals(m.obj))) {
+                return true;
+            }
+            return false;
+        }
+    }
+    private final MatchHandlerWhatAndObjectEquals mMatchHandlerWhatAndObjectEquals =
+            new MatchHandlerWhatAndObjectEquals();
+    boolean hasEqualMessages(Handler h, int what, Object object) {
+        if (h == null) {
+            return false;
+        }
+
+        return findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObjectEquals,
+                false);
+    }
+
+    private static class MatchHandlerRunnableAndObject extends MessageCompare {
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            if (m.target == h && m.callback == r && (object == null || m.obj == object)) {
+                return true;
+            }
+            return false;
+        }
+    }
+    private final MatchHandlerRunnableAndObject mMatchHandlerRunnableAndObject =
+            new MatchHandlerRunnableAndObject();
+
+    boolean hasMessages(Handler h, Runnable r, Object object) {
+        if (h == null) {
+            return false;
+        }
+
+        return findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObject, false);
+    }
+
+    private static class MatchHandler extends MessageCompare {
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            if (m.target == h) {
+                return true;
+            }
+            return false;
+        }
+    }
+    private final MatchHandler mMatchHandler = new MatchHandler();
+    boolean hasMessages(Handler h) {
+        if (h == null) {
+            return false;
+        }
+        return findOrRemoveMessages(h, -1, null, null, 0, mMatchHandler, false);
+    }
+
+    void removeMessages(Handler h, int what, Object object) {
+        if (h == null) {
+            return;
+        }
+        findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObject, true);
+    }
+
+    void removeEqualMessages(Handler h, int what, Object object) {
+        if (h == null) {
+            return;
+        }
+        findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObjectEquals, true);
+    }
+
+    void removeMessages(Handler h, Runnable r, Object object) {
+        if (h == null || r == null) {
+            return;
+        }
+        findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObject, true);
+    }
+
+    private static class MatchHandlerRunnableAndObjectEquals extends MessageCompare {
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            if (m.target == h && m.callback == r && (object == null || object.equals(m.obj))) {
+                return true;
+            }
+            return false;
+        }
+    }
+    private final MatchHandlerRunnableAndObjectEquals mMatchHandlerRunnableAndObjectEquals =
+            new MatchHandlerRunnableAndObjectEquals();
+    void removeEqualMessages(Handler h, Runnable r, Object object) {
+        if (h == null || r == null) {
+            return;
+        }
+        findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObjectEquals, true);
+    }
+
+    private static class MatchHandlerAndObject extends MessageCompare {
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            if (m.target == h && (object == null || m.obj == object)) {
+                return true;
+            }
+            return false;
+        }
+    }
+    private final MatchHandlerAndObject mMatchHandlerAndObject = new MatchHandlerAndObject();
+    void removeCallbacksAndMessages(Handler h, Object object) {
+        if (h == null) {
+            return;
+        }
+        findOrRemoveMessages(h, -1, object, null, 0, mMatchHandlerAndObject, true);
+    }
+
+    private static class MatchHandlerAndObjectEquals extends MessageCompare {
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            if (m.target == h && (object == null || object.equals(m.obj))) {
+                return true;
+            }
+            return false;
+        }
+    }
+    private final MatchHandlerAndObjectEquals mMatchHandlerAndObjectEquals =
+            new MatchHandlerAndObjectEquals();
+    void removeCallbacksAndEqualMessages(Handler h, Object object) {
+        if (h == null) {
+            return;
+        }
+        findOrRemoveMessages(h, -1, object, null, 0, mMatchHandlerAndObjectEquals, true);
+    }
+
+    private static class MatchAllMessages extends MessageCompare {
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            return true;
+        }
+    }
+    private final MatchAllMessages mMatchAllMessages = new MatchAllMessages();
+    private void removeAllMessages() {
+        findOrRemoveMessages(null, -1, null, null, 0, mMatchAllMessages, true);
+    }
+
+    private static class MatchAllFutureMessages extends MessageCompare {
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            if (m.when > when) {
+                return true;
+            }
+            return false;
+        }
+    }
+    private final MatchAllFutureMessages mMatchAllFutureMessages = new MatchAllFutureMessages();
+    private void removeAllFutureMessages() {
+        findOrRemoveMessages(null, -1, null, null, SystemClock.uptimeMillis(),
+                mMatchAllFutureMessages, true);
+    }
+
+    private void printPriorityQueueNodes() {
+        Iterator<MessageNode> iterator = mPriorityQueue.iterator();
+
+        Log.d(TAG, "* Dump priority queue");
+        while (iterator.hasNext()) {
+            MessageNode msgNode = iterator.next();
+            Log.d(TAG, "** MessageNode what: " + msgNode.mMessage.what + " when "
+                    + msgNode.mMessage.when + " seq: " + msgNode.mInsertSeq);
+        }
+    }
+
+    private int dumpPriorityQueue(ConcurrentSkipListSet<MessageNode> queue, Printer pw,
+            String prefix, Handler h, int n) {
+        int count = 0;
+        long now = SystemClock.uptimeMillis();
+
+        for (MessageNode msgNode : queue) {
+            Message msg = msgNode.mMessage;
+            if (h == null || h == msg.target) {
+                pw.println(prefix + "Message " + (n + count) + ": " + msg.toString(now));
+            }
+            count++;
+        }
+        return count;
+    }
+
+    void dump(Printer pw, String prefix, Handler h) {
+        long now = SystemClock.uptimeMillis();
+        int n = 0;
+
+        pw.println(prefix + "(MessageQueue is using Concurrent implementation)");
+
+        StackNode node = (StackNode) sState.getVolatile(this);
+        while (node != null) {
+            if (node.isMessageNode()) {
+                Message msg = ((MessageNode) node).mMessage;
+                if (h == null || h == msg.target) {
+                    pw.println(prefix + "Message " + n + ": " + msg.toString(now));
+                }
+                node = ((MessageNode) node).mNext;
+            } else {
+                pw.println(prefix + "State: " + node);
+                node = null;
+            }
+            n++;
+        }
+
+        pw.println(prefix + "PriorityQueue Messages: ");
+        n += dumpPriorityQueue(mPriorityQueue, pw, prefix, h, n);
+        pw.println(prefix + "AsyncPriorityQueue Messages: ");
+        n += dumpPriorityQueue(mAsyncPriorityQueue, pw, prefix, h, n);
+
+        pw.println(prefix + "(Total messages: " + n + ", polling=" + isPolling()
+                + ", quitting=" + (boolean) sQuitting.getVolatile(this) + ")");
+    }
+
+    private int dumpPriorityQueue(ConcurrentSkipListSet<MessageNode> queue,
+            ProtoOutputStream proto) {
+        int count = 0;
+
+        for (MessageNode msgNode : queue) {
+            Message msg = msgNode.mMessage;
+            msg.dumpDebug(proto, MessageQueueProto.MESSAGES);
+            count++;
+        }
+        return count;
+    }
+
+    void dumpDebug(ProtoOutputStream proto, long fieldId) {
+        final long messageQueueToken = proto.start(fieldId);
+
+        StackNode node = (StackNode) sState.getVolatile(this);
+        while (node.isMessageNode()) {
+            Message msg = ((MessageNode) node).mMessage;
+            msg.dumpDebug(proto, MessageQueueProto.MESSAGES);
+            node = ((MessageNode) node).mNext;
+        }
+
+        dumpPriorityQueue(mPriorityQueue, proto);
+        dumpPriorityQueue(mAsyncPriorityQueue, proto);
+
+        proto.write(MessageQueueProto.IS_POLLING_LOCKED, isPolling());
+        proto.write(MessageQueueProto.IS_QUITTING, (boolean) sQuitting.getVolatile(this));
+        proto.end(messageQueueToken);
+    }
+
+    /**
+     * Adds a file descriptor listener to receive notification when file descriptor
+     * related events occur.
+     * <p>
+     * If the file descriptor has already been registered, the specified events
+     * and listener will replace any that were previously associated with it.
+     * It is not possible to set more than one listener per file descriptor.
+     * </p><p>
+     * It is important to always unregister the listener when the file descriptor
+     * is no longer of use.
+     * </p>
+     *
+     * @param fd The file descriptor for which a listener will be registered.
+     * @param events The set of events to receive: a combination of the
+     * {@link OnFileDescriptorEventListener#EVENT_INPUT},
+     * {@link OnFileDescriptorEventListener#EVENT_OUTPUT}, and
+     * {@link OnFileDescriptorEventListener#EVENT_ERROR} event masks.  If the requested
+     * set of events is zero, then the listener is unregistered.
+     * @param listener The listener to invoke when file descriptor events occur.
+     *
+     * @see OnFileDescriptorEventListener
+     * @see #removeOnFileDescriptorEventListener
+     */
+    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+    public void addOnFileDescriptorEventListener(@NonNull FileDescriptor fd,
+            @OnFileDescriptorEventListener.Events int events,
+            @NonNull OnFileDescriptorEventListener listener) {
+        if (fd == null) {
+            throw new IllegalArgumentException("fd must not be null");
+        }
+        if (listener == null) {
+            throw new IllegalArgumentException("listener must not be null");
+        }
+
+        synchronized (mFileDescriptorRecordsLock) {
+            updateOnFileDescriptorEventListenerLocked(fd, events, listener);
+        }
+    }
+
+    /**
+     * Removes a file descriptor listener.
+     * <p>
+     * This method does nothing if no listener has been registered for the
+     * specified file descriptor.
+     * </p>
+     *
+     * @param fd The file descriptor whose listener will be unregistered.
+     *
+     * @see OnFileDescriptorEventListener
+     * @see #addOnFileDescriptorEventListener
+     */
+    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+    public void removeOnFileDescriptorEventListener(@NonNull FileDescriptor fd) {
+        if (fd == null) {
+            throw new IllegalArgumentException("fd must not be null");
+        }
+
+        synchronized (mFileDescriptorRecordsLock) {
+            updateOnFileDescriptorEventListenerLocked(fd, 0, null);
+        }
+    }
+
+    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+    private void updateOnFileDescriptorEventListenerLocked(FileDescriptor fd, int events,
+            OnFileDescriptorEventListener listener) {
+        final int fdNum = fd.getInt$();
+
+        int index = -1;
+        FileDescriptorRecord record = null;
+        if (mFileDescriptorRecords != null) {
+            index = mFileDescriptorRecords.indexOfKey(fdNum);
+            if (index >= 0) {
+                record = mFileDescriptorRecords.valueAt(index);
+                if (record != null && record.mEvents == events) {
+                    return;
+                }
+            }
+        }
+
+        if (events != 0) {
+            events |= OnFileDescriptorEventListener.EVENT_ERROR;
+            if (record == null) {
+                if (mFileDescriptorRecords == null) {
+                    mFileDescriptorRecords = new SparseArray<FileDescriptorRecord>();
+                }
+                record = new FileDescriptorRecord(fd, events, listener);
+                mFileDescriptorRecords.put(fdNum, record);
+            } else {
+                record.mListener = listener;
+                record.mEvents = events;
+                record.mSeq += 1;
+            }
+            nativeSetFileDescriptorEvents(mPtr, fdNum, events);
+        } else if (record != null) {
+            record.mEvents = 0;
+            mFileDescriptorRecords.removeAt(index);
+            nativeSetFileDescriptorEvents(mPtr, fdNum, 0);
+        }
+    }
+
+    // Called from native code.
+    private int dispatchEvents(int fd, int events) {
+        // Get the file descriptor record and any state that might change.
+        final FileDescriptorRecord record;
+        final int oldWatchedEvents;
+        final OnFileDescriptorEventListener listener;
+        final int seq;
+        synchronized (mFileDescriptorRecordsLock) {
+            record = mFileDescriptorRecords.get(fd);
+            if (record == null) {
+                return 0; // spurious, no listener registered
+            }
+
+            oldWatchedEvents = record.mEvents;
+            events &= oldWatchedEvents; // filter events based on current watched set
+            if (events == 0) {
+                return oldWatchedEvents; // spurious, watched events changed
+            }
+
+            listener = record.mListener;
+            seq = record.mSeq;
+        }
+
+        // Invoke the listener outside of the lock.
+        int newWatchedEvents = listener.onFileDescriptorEvents(
+                record.mDescriptor, events);
+        if (newWatchedEvents != 0) {
+            newWatchedEvents |= OnFileDescriptorEventListener.EVENT_ERROR;
+        }
+
+        // Update the file descriptor record if the listener changed the set of
+        // events to watch and the listener itself hasn't been updated since.
+        if (newWatchedEvents != oldWatchedEvents) {
+            synchronized (mFileDescriptorRecordsLock) {
+                int index = mFileDescriptorRecords.indexOfKey(fd);
+                if (index >= 0 && mFileDescriptorRecords.valueAt(index) == record
+                        && record.mSeq == seq) {
+                    record.mEvents = newWatchedEvents;
+                    if (newWatchedEvents == 0) {
+                        mFileDescriptorRecords.removeAt(index);
+                    }
+                }
+            }
+        }
+
+        // Return the new set of events to watch for native code to take care of.
+        return newWatchedEvents;
+    }
+
+    /**
+     * Callback interface for discovering when a thread is going to block
+     * waiting for more messages.
+     */
+    public static interface IdleHandler {
+        /**
+         * Called when the message queue has run out of messages and will now
+         * wait for more.  Return true to keep your idle handler active, false
+         * to have it removed.  This may be called if there are still messages
+         * pending in the queue, but they are all scheduled to be dispatched
+         * after the current time.
+         */
+        boolean queueIdle();
+    }
+
+    /**
+     * A listener which is invoked when file descriptor related events occur.
+     */
+    public interface OnFileDescriptorEventListener {
+        /**
+         * File descriptor event: Indicates that the file descriptor is ready for input
+         * operations, such as reading.
+         * <p>
+         * The listener should read all available data from the file descriptor
+         * then return <code>true</code> to keep the listener active or <code>false</code>
+         * to remove the listener.
+         * </p><p>
+         * In the case of a socket, this event may be generated to indicate
+         * that there is at least one incoming connection that the listener
+         * should accept.
+         * </p><p>
+         * This event will only be generated if the {@link #EVENT_INPUT} event mask was
+         * specified when the listener was added.
+         * </p>
+         */
+        public static final int EVENT_INPUT = 1 << 0;
+
+        /**
+         * File descriptor event: Indicates that the file descriptor is ready for output
+         * operations, such as writing.
+         * <p>
+         * The listener should write as much data as it needs.  If it could not
+         * write everything at once, then it should return <code>true</code> to
+         * keep the listener active.  Otherwise, it should return <code>false</code>
+         * to remove the listener then re-register it later when it needs to write
+         * something else.
+         * </p><p>
+         * This event will only be generated if the {@link #EVENT_OUTPUT} event mask was
+         * specified when the listener was added.
+         * </p>
+         */
+        public static final int EVENT_OUTPUT = 1 << 1;
+
+        /**
+         * File descriptor event: Indicates that the file descriptor encountered a
+         * fatal error.
+         * <p>
+         * File descriptor errors can occur for various reasons.  One common error
+         * is when the remote peer of a socket or pipe closes its end of the connection.
+         * </p><p>
+         * This event may be generated at any time regardless of whether the
+         * {@link #EVENT_ERROR} event mask was specified when the listener was added.
+         * </p>
+         */
+        public static final int EVENT_ERROR = 1 << 2;
+
+        /** @hide */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(flag = true, prefix = { "EVENT_" }, value = {
+                EVENT_INPUT,
+                EVENT_OUTPUT,
+                EVENT_ERROR
+        })
+        public @interface Events {}
+
+        /**
+         * Called when a file descriptor receives events.
+         *
+         * @param fd The file descriptor.
+         * @param events The set of events that occurred: a combination of the
+         * {@link #EVENT_INPUT}, {@link #EVENT_OUTPUT}, and {@link #EVENT_ERROR} event masks.
+         * @return The new set of events to watch, or 0 to unregister the listener.
+         *
+         * @see #EVENT_INPUT
+         * @see #EVENT_OUTPUT
+         * @see #EVENT_ERROR
+         */
+        @Events int onFileDescriptorEvents(@NonNull FileDescriptor fd, @Events int events);
+    }
+
+    static final class FileDescriptorRecord {
+        public final FileDescriptor mDescriptor;
+        public int mEvents;
+        public OnFileDescriptorEventListener mListener;
+        public int mSeq;
+
+        public FileDescriptorRecord(FileDescriptor descriptor,
+                int events, OnFileDescriptorEventListener listener) {
+            mDescriptor = descriptor;
+            mEvents = events;
+            mListener = listener;
+        }
+    }
+}
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index a459aaa..2c7b9c0 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -159,6 +159,8 @@
     @UnsupportedAppUsage
     private static UserEnvironment sCurrentUser;
     private static boolean sUserRequired;
+    private static Boolean sLegacyStorageAppOp;
+    private static Boolean sNoIsolatedStorageAppOp;
 
     static {
         initForCurrentUser();
@@ -1459,15 +1461,23 @@
         final AppOpsManager appOps = context.getSystemService(AppOpsManager.class);
         final String opPackageName = context.getOpPackageName();
 
-        if (appOps.noteOpNoThrow(AppOpsManager.OP_LEGACY_STORAGE, uid,
-                opPackageName) == AppOpsManager.MODE_ALLOWED) {
-            return true;
+        if (sLegacyStorageAppOp == null) {
+            sLegacyStorageAppOp =
+              appOps.checkOpNoThrow(AppOpsManager.OP_LEGACY_STORAGE, uid, opPackageName) ==
+                              AppOpsManager.MODE_ALLOWED;
+        }
+        if (sLegacyStorageAppOp) {
+            return sLegacyStorageAppOp;
         }
 
         // Legacy external storage access is granted to instrumentations invoked with
         // "--no-isolated-storage" flag.
-        return appOps.noteOpNoThrow(AppOpsManager.OP_NO_ISOLATED_STORAGE, uid,
-                opPackageName) == AppOpsManager.MODE_ALLOWED;
+        if (sNoIsolatedStorageAppOp == null) {
+            sNoIsolatedStorageAppOp =
+              appOps.checkOpNoThrow(AppOpsManager.OP_NO_ISOLATED_STORAGE, uid,
+                                    opPackageName) == AppOpsManager.MODE_ALLOWED;
+        }
+        return sNoIsolatedStorageAppOp;
     }
 
     private static boolean isScopedStorageEnforced(boolean defaultScopedStorage,
diff --git a/core/java/android/os/LegacyMessageQueue/MessageQueue.java b/core/java/android/os/LegacyMessageQueue/MessageQueue.java
new file mode 100644
index 0000000..6b9b349
--- /dev/null
+++ b/core/java/android/os/LegacyMessageQueue/MessageQueue.java
@@ -0,0 +1,1235 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.os;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Handler;
+import android.os.Process;
+import android.os.Trace;
+import android.util.Log;
+import android.util.Printer;
+import android.util.SparseArray;
+import android.util.proto.ProtoOutputStream;
+
+import java.io.FileDescriptor;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Low-level class holding the list of messages to be dispatched by a
+ * {@link Looper}.  Messages are not added directly to a MessageQueue,
+ * but rather through {@link Handler} objects associated with the Looper.
+ *
+ * <p>You can retrieve the MessageQueue for the current thread with
+ * {@link Looper#myQueue() Looper.myQueue()}.
+ */
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
+@android.ravenwood.annotation.RavenwoodNativeSubstitutionClass(
+        "com.android.platform.test.ravenwood.nativesubstitution.MessageQueue_host")
+public final class MessageQueue {
+    private static final String TAG = "MessageQueue";
+    private static final boolean DEBUG = false;
+    private static final boolean TRACE = false;
+
+    // True if the message queue can be quit.
+    @UnsupportedAppUsage
+    private final boolean mQuitAllowed;
+
+    @UnsupportedAppUsage
+    @SuppressWarnings("unused")
+    private long mPtr; // used by native code
+
+    @UnsupportedAppUsage
+    Message mMessages;
+    private Message mLast;
+    @UnsupportedAppUsage
+    private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();
+    private SparseArray<FileDescriptorRecord> mFileDescriptorRecords;
+    private IdleHandler[] mPendingIdleHandlers;
+    private boolean mQuitting;
+
+    // Indicates whether next() is blocked waiting in pollOnce() with a non-zero timeout.
+    private boolean mBlocked;
+
+    // Tracks the number of async message. We use this in enqueueMessage() to avoid searching the
+    // queue for async messages when inserting a message at the tail.
+    private int mAsyncMessageCount;
+
+    // The next barrier token.
+    // Barriers are indicated by messages with a null target whose arg1 field carries the token.
+    @UnsupportedAppUsage
+    private int mNextBarrierToken;
+
+    private native static long nativeInit();
+    private native static void nativeDestroy(long ptr);
+    @UnsupportedAppUsage
+    private native void nativePollOnce(long ptr, int timeoutMillis); /*non-static for callbacks*/
+    private native static void nativeWake(long ptr);
+    private native static boolean nativeIsPolling(long ptr);
+    private native static void nativeSetFileDescriptorEvents(long ptr, int fd, int events);
+
+    MessageQueue(boolean quitAllowed) {
+        mQuitAllowed = quitAllowed;
+        mPtr = nativeInit();
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            dispose();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    // Disposes of the underlying message queue.
+    // Must only be called on the looper thread or the finalizer.
+    private void dispose() {
+        if (mPtr != 0) {
+            nativeDestroy(mPtr);
+            mPtr = 0;
+        }
+    }
+
+    /**
+     * Returns true if the looper has no pending messages which are due to be processed.
+     *
+     * <p>This method is safe to call from any thread.
+     *
+     * @return True if the looper is idle.
+     */
+    public boolean isIdle() {
+        synchronized (this) {
+            final long now = SystemClock.uptimeMillis();
+            return mMessages == null || now < mMessages.when;
+        }
+    }
+
+    /**
+     * Add a new {@link IdleHandler} to this message queue.  This may be
+     * removed automatically for you by returning false from
+     * {@link IdleHandler#queueIdle IdleHandler.queueIdle()} when it is
+     * invoked, or explicitly removing it with {@link #removeIdleHandler}.
+     *
+     * <p>This method is safe to call from any thread.
+     *
+     * @param handler The IdleHandler to be added.
+     */
+    public void addIdleHandler(@NonNull IdleHandler handler) {
+        if (handler == null) {
+            throw new NullPointerException("Can't add a null IdleHandler");
+        }
+        synchronized (this) {
+            mIdleHandlers.add(handler);
+        }
+    }
+
+    /**
+     * Remove an {@link IdleHandler} from the queue that was previously added
+     * with {@link #addIdleHandler}.  If the given object is not currently
+     * in the idle list, nothing is done.
+     *
+     * <p>This method is safe to call from any thread.
+     *
+     * @param handler The IdleHandler to be removed.
+     */
+    public void removeIdleHandler(@NonNull IdleHandler handler) {
+        synchronized (this) {
+            mIdleHandlers.remove(handler);
+        }
+    }
+
+    /**
+     * Returns whether this looper's thread is currently polling for more work to do.
+     * This is a good signal that the loop is still alive rather than being stuck
+     * handling a callback.  Note that this method is intrinsically racy, since the
+     * state of the loop can change before you get the result back.
+     *
+     * <p>This method is safe to call from any thread.
+     *
+     * @return True if the looper is currently polling for events.
+     * @hide
+     */
+    public boolean isPolling() {
+        synchronized (this) {
+            return isPollingLocked();
+        }
+    }
+
+    private boolean isPollingLocked() {
+        // If the loop is quitting then it must not be idling.
+        // We can assume mPtr != 0 when mQuitting is false.
+        return !mQuitting && nativeIsPolling(mPtr);
+    }
+
+    /**
+     * Adds a file descriptor listener to receive notification when file descriptor
+     * related events occur.
+     * <p>
+     * If the file descriptor has already been registered, the specified events
+     * and listener will replace any that were previously associated with it.
+     * It is not possible to set more than one listener per file descriptor.
+     * </p><p>
+     * It is important to always unregister the listener when the file descriptor
+     * is no longer of use.
+     * </p>
+     *
+     * @param fd The file descriptor for which a listener will be registered.
+     * @param events The set of events to receive: a combination of the
+     * {@link OnFileDescriptorEventListener#EVENT_INPUT},
+     * {@link OnFileDescriptorEventListener#EVENT_OUTPUT}, and
+     * {@link OnFileDescriptorEventListener#EVENT_ERROR} event masks.  If the requested
+     * set of events is zero, then the listener is unregistered.
+     * @param listener The listener to invoke when file descriptor events occur.
+     *
+     * @see OnFileDescriptorEventListener
+     * @see #removeOnFileDescriptorEventListener
+     */
+    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+    public void addOnFileDescriptorEventListener(@NonNull FileDescriptor fd,
+            @OnFileDescriptorEventListener.Events int events,
+            @NonNull OnFileDescriptorEventListener listener) {
+        if (fd == null) {
+            throw new IllegalArgumentException("fd must not be null");
+        }
+        if (listener == null) {
+            throw new IllegalArgumentException("listener must not be null");
+        }
+
+        synchronized (this) {
+            updateOnFileDescriptorEventListenerLocked(fd, events, listener);
+        }
+    }
+
+    /**
+     * Removes a file descriptor listener.
+     * <p>
+     * This method does nothing if no listener has been registered for the
+     * specified file descriptor.
+     * </p>
+     *
+     * @param fd The file descriptor whose listener will be unregistered.
+     *
+     * @see OnFileDescriptorEventListener
+     * @see #addOnFileDescriptorEventListener
+     */
+    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+    public void removeOnFileDescriptorEventListener(@NonNull FileDescriptor fd) {
+        if (fd == null) {
+            throw new IllegalArgumentException("fd must not be null");
+        }
+
+        synchronized (this) {
+            updateOnFileDescriptorEventListenerLocked(fd, 0, null);
+        }
+    }
+
+    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+    private void updateOnFileDescriptorEventListenerLocked(FileDescriptor fd, int events,
+            OnFileDescriptorEventListener listener) {
+        final int fdNum = fd.getInt$();
+
+        int index = -1;
+        FileDescriptorRecord record = null;
+        if (mFileDescriptorRecords != null) {
+            index = mFileDescriptorRecords.indexOfKey(fdNum);
+            if (index >= 0) {
+                record = mFileDescriptorRecords.valueAt(index);
+                if (record != null && record.mEvents == events) {
+                    return;
+                }
+            }
+        }
+
+        if (events != 0) {
+            events |= OnFileDescriptorEventListener.EVENT_ERROR;
+            if (record == null) {
+                if (mFileDescriptorRecords == null) {
+                    mFileDescriptorRecords = new SparseArray<FileDescriptorRecord>();
+                }
+                record = new FileDescriptorRecord(fd, events, listener);
+                mFileDescriptorRecords.put(fdNum, record);
+            } else {
+                record.mListener = listener;
+                record.mEvents = events;
+                record.mSeq += 1;
+            }
+            nativeSetFileDescriptorEvents(mPtr, fdNum, events);
+        } else if (record != null) {
+            record.mEvents = 0;
+            mFileDescriptorRecords.removeAt(index);
+            nativeSetFileDescriptorEvents(mPtr, fdNum, 0);
+        }
+    }
+
+    // Called from native code.
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private int dispatchEvents(int fd, int events) {
+        // Get the file descriptor record and any state that might change.
+        final FileDescriptorRecord record;
+        final int oldWatchedEvents;
+        final OnFileDescriptorEventListener listener;
+        final int seq;
+        synchronized (this) {
+            record = mFileDescriptorRecords.get(fd);
+            if (record == null) {
+                return 0; // spurious, no listener registered
+            }
+
+            oldWatchedEvents = record.mEvents;
+            events &= oldWatchedEvents; // filter events based on current watched set
+            if (events == 0) {
+                return oldWatchedEvents; // spurious, watched events changed
+            }
+
+            listener = record.mListener;
+            seq = record.mSeq;
+        }
+
+        // Invoke the listener outside of the lock.
+        int newWatchedEvents = listener.onFileDescriptorEvents(
+                record.mDescriptor, events);
+        if (newWatchedEvents != 0) {
+            newWatchedEvents |= OnFileDescriptorEventListener.EVENT_ERROR;
+        }
+
+        // Update the file descriptor record if the listener changed the set of
+        // events to watch and the listener itself hasn't been updated since.
+        if (newWatchedEvents != oldWatchedEvents) {
+            synchronized (this) {
+                int index = mFileDescriptorRecords.indexOfKey(fd);
+                if (index >= 0 && mFileDescriptorRecords.valueAt(index) == record
+                        && record.mSeq == seq) {
+                    record.mEvents = newWatchedEvents;
+                    if (newWatchedEvents == 0) {
+                        mFileDescriptorRecords.removeAt(index);
+                    }
+                }
+            }
+        }
+
+        // Return the new set of events to watch for native code to take care of.
+        return newWatchedEvents;
+    }
+
+    private static final AtomicLong mMessagesDelivered = new AtomicLong();
+
+    @UnsupportedAppUsage
+    Message next() {
+        // Return here if the message loop has already quit and been disposed.
+        // This can happen if the application tries to restart a looper after quit
+        // which is not supported.
+        final long ptr = mPtr;
+        if (ptr == 0) {
+            return null;
+        }
+
+        int pendingIdleHandlerCount = -1; // -1 only during first iteration
+        int nextPollTimeoutMillis = 0;
+        for (;;) {
+            if (nextPollTimeoutMillis != 0) {
+                Binder.flushPendingCommands();
+            }
+
+            nativePollOnce(ptr, nextPollTimeoutMillis);
+
+            synchronized (this) {
+                // Try to retrieve the next message.  Return if found.
+                final long now = SystemClock.uptimeMillis();
+                Message prevMsg = null;
+                Message msg = mMessages;
+                if (msg != null && msg.target == null) {
+                    // Stalled by a barrier.  Find the next asynchronous message in the queue.
+                    do {
+                        prevMsg = msg;
+                        msg = msg.next;
+                    } while (msg != null && !msg.isAsynchronous());
+                }
+                if (msg != null) {
+                    if (now < msg.when) {
+                        // Next message is not ready.  Set a timeout to wake up when it is ready.
+                        nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
+                    } else {
+                        // Got a message.
+                        mBlocked = false;
+                        if (prevMsg != null) {
+                            prevMsg.next = msg.next;
+                            if (prevMsg.next == null) {
+                                mLast = prevMsg;
+                            }
+                        } else {
+                            mMessages = msg.next;
+                            if (msg.next == null) {
+                                mLast = null;
+                            }
+                        }
+                        msg.next = null;
+                        if (DEBUG) Log.v(TAG, "Returning message: " + msg);
+                        msg.markInUse();
+                        if (msg.isAsynchronous()) {
+                            mAsyncMessageCount--;
+                        }
+                        if (TRACE) {
+                            Trace.setCounter("MQ.Delivered", mMessagesDelivered.incrementAndGet());
+                        }
+                        return msg;
+                    }
+                } else {
+                    // No more messages.
+                    nextPollTimeoutMillis = -1;
+                }
+
+                // Process the quit message now that all pending messages have been handled.
+                if (mQuitting) {
+                    dispose();
+                    return null;
+                }
+
+                // If first time idle, then get the number of idlers to run.
+                // Idle handles only run if the queue is empty or if the first message
+                // in the queue (possibly a barrier) is due to be handled in the future.
+                if (pendingIdleHandlerCount < 0
+                        && (mMessages == null || now < mMessages.when)) {
+                    pendingIdleHandlerCount = mIdleHandlers.size();
+                }
+                if (pendingIdleHandlerCount <= 0) {
+                    // No idle handlers to run.  Loop and wait some more.
+                    mBlocked = true;
+                    continue;
+                }
+
+                if (mPendingIdleHandlers == null) {
+                    mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
+                }
+                mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
+            }
+
+            // Run the idle handlers.
+            // We only ever reach this code block during the first iteration.
+            for (int i = 0; i < pendingIdleHandlerCount; i++) {
+                final IdleHandler idler = mPendingIdleHandlers[i];
+                mPendingIdleHandlers[i] = null; // release the reference to the handler
+
+                boolean keep = false;
+                try {
+                    keep = idler.queueIdle();
+                } catch (Throwable t) {
+                    Log.wtf(TAG, "IdleHandler threw exception", t);
+                }
+
+                if (!keep) {
+                    synchronized (this) {
+                        mIdleHandlers.remove(idler);
+                    }
+                }
+            }
+
+            // Reset the idle handler count to 0 so we do not run them again.
+            pendingIdleHandlerCount = 0;
+
+            // While calling an idle handler, a new message could have been delivered
+            // so go back and look again for a pending message without waiting.
+            nextPollTimeoutMillis = 0;
+        }
+    }
+
+    void quit(boolean safe) {
+        if (!mQuitAllowed) {
+            throw new IllegalStateException("Main thread not allowed to quit.");
+        }
+
+        synchronized (this) {
+            if (mQuitting) {
+                return;
+            }
+            mQuitting = true;
+
+            if (safe) {
+                removeAllFutureMessagesLocked();
+            } else {
+                removeAllMessagesLocked();
+            }
+
+            // We can assume mPtr != 0 because mQuitting was previously false.
+            nativeWake(mPtr);
+        }
+    }
+
+    /**
+     * Posts a synchronization barrier to the Looper's message queue.
+     *
+     * Message processing occurs as usual until the message queue encounters the
+     * synchronization barrier that has been posted.  When the barrier is encountered,
+     * later synchronous messages in the queue are stalled (prevented from being executed)
+     * until the barrier is released by calling {@link #removeSyncBarrier} and specifying
+     * the token that identifies the synchronization barrier.
+     *
+     * This method is used to immediately postpone execution of all subsequently posted
+     * synchronous messages until a condition is met that releases the barrier.
+     * Asynchronous messages (see {@link Message#isAsynchronous} are exempt from the barrier
+     * and continue to be processed as usual.
+     *
+     * This call must be always matched by a call to {@link #removeSyncBarrier} with
+     * the same token to ensure that the message queue resumes normal operation.
+     * Otherwise the application will probably hang!
+     *
+     * @return A token that uniquely identifies the barrier.  This token must be
+     * passed to {@link #removeSyncBarrier} to release the barrier.
+     *
+     * @hide
+     */
+    @UnsupportedAppUsage
+    @TestApi
+    public int postSyncBarrier() {
+        return postSyncBarrier(SystemClock.uptimeMillis());
+    }
+
+    private int postSyncBarrier(long when) {
+        // Enqueue a new sync barrier token.
+        // We don't need to wake the queue because the purpose of a barrier is to stall it.
+        synchronized (this) {
+            final int token = mNextBarrierToken++;
+            final Message msg = Message.obtain();
+            msg.markInUse();
+            msg.when = when;
+            msg.arg1 = token;
+
+            if (Flags.messageQueueTailTracking() && mLast != null && mLast.when <= when) {
+                /* Message goes to tail of list */
+                mLast.next = msg;
+                mLast = msg;
+                msg.next = null;
+                return token;
+            }
+
+            Message prev = null;
+            Message p = mMessages;
+            if (when != 0) {
+                while (p != null && p.when <= when) {
+                    prev = p;
+                    p = p.next;
+                }
+            }
+
+            if (p == null) {
+                /* We reached the tail of the list, or list is empty. */
+                mLast = msg;
+            }
+
+            if (prev != null) { // invariant: p == prev.next
+                msg.next = p;
+                prev.next = msg;
+            } else {
+                msg.next = p;
+                mMessages = msg;
+            }
+            return token;
+        }
+    }
+
+    /**
+     * Removes a synchronization barrier.
+     *
+     * @param token The synchronization barrier token that was returned by
+     * {@link #postSyncBarrier}.
+     *
+     * @throws IllegalStateException if the barrier was not found.
+     *
+     * @hide
+     */
+    @UnsupportedAppUsage
+    @TestApi
+    public void removeSyncBarrier(int token) {
+        // Remove a sync barrier token from the queue.
+        // If the queue is no longer stalled by a barrier then wake it.
+        synchronized (this) {
+            Message prev = null;
+            Message p = mMessages;
+            while (p != null && (p.target != null || p.arg1 != token)) {
+                prev = p;
+                p = p.next;
+            }
+            if (p == null) {
+                throw new IllegalStateException("The specified message queue synchronization "
+                        + " barrier token has not been posted or has already been removed.");
+            }
+            final boolean needWake;
+            if (prev != null) {
+                prev.next = p.next;
+                if (prev.next == null) {
+                    mLast = prev;
+                }
+                needWake = false;
+            } else {
+                mMessages = p.next;
+                if (mMessages == null) {
+                    mLast = null;
+                }
+                needWake = mMessages == null || mMessages.target != null;
+            }
+            p.recycleUnchecked();
+
+            // If the loop is quitting then it is already awake.
+            // We can assume mPtr != 0 when mQuitting is false.
+            if (needWake && !mQuitting) {
+                nativeWake(mPtr);
+            }
+        }
+    }
+
+    boolean enqueueMessage(Message msg, long when) {
+        if (msg.target == null) {
+            throw new IllegalArgumentException("Message must have a target.");
+        }
+
+        synchronized (this) {
+            if (msg.isInUse()) {
+                throw new IllegalStateException(msg + " This message is already in use.");
+            }
+
+            if (mQuitting) {
+                IllegalStateException e = new IllegalStateException(
+                        msg.target + " sending message to a Handler on a dead thread");
+                Log.w(TAG, e.getMessage(), e);
+                msg.recycle();
+                return false;
+            }
+
+            msg.markInUse();
+            msg.when = when;
+            Message p = mMessages;
+            boolean needWake;
+            if (p == null || when == 0 || when < p.when) {
+                // New head, wake up the event queue if blocked.
+                msg.next = p;
+                mMessages = msg;
+                needWake = mBlocked;
+                if (p == null) {
+                    mLast = mMessages;
+                }
+            } else {
+                // Message is to be inserted at tail or middle of queue. Usually we don't have to
+                // wake up the event queue unless there is a barrier at the head of the queue and
+                // the message is the earliest asynchronous message in the queue.
+                needWake = mBlocked && p.target == null && msg.isAsynchronous();
+
+                // For readability, we split this portion of the function into two blocks based on
+                // whether tail tracking is enabled. This has a minor implication for the case
+                // where tail tracking is disabled. See the comment below.
+                if (Flags.messageQueueTailTracking()) {
+                    if (when >= mLast.when) {
+                        needWake = needWake && mAsyncMessageCount == 0;
+                        msg.next = null;
+                        mLast.next = msg;
+                        mLast = msg;
+                    } else {
+                        // Inserted within the middle of the queue.
+                        Message prev;
+                        for (;;) {
+                            prev = p;
+                            p = p.next;
+                            if (p == null || when < p.when) {
+                                break;
+                            }
+                            if (needWake && p.isAsynchronous()) {
+                                needWake = false;
+                            }
+                        }
+                        if (p == null) {
+                            /* Inserting at tail of queue */
+                            mLast = msg;
+                        }
+                        msg.next = p; // invariant: p == prev.next
+                        prev.next = msg;
+                    }
+                } else {
+                    Message prev;
+                    for (;;) {
+                        prev = p;
+                        p = p.next;
+                        if (p == null || when < p.when) {
+                            break;
+                        }
+                        if (needWake && p.isAsynchronous()) {
+                            needWake = false;
+                        }
+                    }
+                    msg.next = p; // invariant: p == prev.next
+                    prev.next = msg;
+
+                    /*
+                     * If this block is executing then we have a build without tail tracking -
+                     * specifically: Flags.messageQueueTailTracking() == false. This is determined
+                     * at build time so the flag won't change on us during runtime.
+                     *
+                     * Since we don't want to pepper the code with extra checks, we only check
+                     * for tail tracking when we might use mLast. Otherwise, we continue to update
+                     * mLast as the tail of the list.
+                     *
+                     * In this case however we are not maintaining mLast correctly. Since we never
+                     * use it, this is fine. However, we run the risk of leaking a reference.
+                     * So set mLast to null in this case to avoid any Message leaks. The other
+                     * sites will never use the value so we are safe against null pointer derefs.
+                     */
+                    mLast = null;
+                }
+            }
+
+            if (msg.isAsynchronous()) {
+                mAsyncMessageCount++;
+            }
+
+            // We can assume mPtr != 0 because mQuitting is false.
+            if (needWake) {
+                nativeWake(mPtr);
+            }
+        }
+        return true;
+    }
+
+    boolean hasMessages(Handler h, int what, Object object) {
+        if (h == null) {
+            return false;
+        }
+
+        synchronized (this) {
+            Message p = mMessages;
+            while (p != null) {
+                if (p.target == h && p.what == what && (object == null || p.obj == object)) {
+                    return true;
+                }
+                p = p.next;
+            }
+            return false;
+        }
+    }
+
+    boolean hasEqualMessages(Handler h, int what, Object object) {
+        if (h == null) {
+            return false;
+        }
+
+        synchronized (this) {
+            Message p = mMessages;
+            while (p != null) {
+                if (p.target == h && p.what == what && (object == null || object.equals(p.obj))) {
+                    return true;
+                }
+                p = p.next;
+            }
+            return false;
+        }
+    }
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    boolean hasMessages(Handler h, Runnable r, Object object) {
+        if (h == null) {
+            return false;
+        }
+
+        synchronized (this) {
+            Message p = mMessages;
+            while (p != null) {
+                if (p.target == h && p.callback == r && (object == null || p.obj == object)) {
+                    return true;
+                }
+                p = p.next;
+            }
+            return false;
+        }
+    }
+
+    boolean hasMessages(Handler h) {
+        if (h == null) {
+            return false;
+        }
+
+        synchronized (this) {
+            Message p = mMessages;
+            while (p != null) {
+                if (p.target == h) {
+                    return true;
+                }
+                p = p.next;
+            }
+            return false;
+        }
+    }
+
+    void removeMessages(Handler h, int what, Object object) {
+        if (h == null) {
+            return;
+        }
+
+        synchronized (this) {
+            Message p = mMessages;
+
+            // Remove all messages at front.
+            while (p != null && p.target == h && p.what == what
+                   && (object == null || p.obj == object)) {
+                Message n = p.next;
+                mMessages = n;
+                if (p.isAsynchronous()) {
+                    mAsyncMessageCount--;
+                }
+                p.recycleUnchecked();
+                p = n;
+            }
+
+            if (p == null) {
+                mLast = mMessages;
+            }
+
+            // Remove all messages after front.
+            while (p != null) {
+                Message n = p.next;
+                if (n != null) {
+                    if (n.target == h && n.what == what
+                            && (object == null || n.obj == object)) {
+                        Message nn = n.next;
+                        if (n.isAsynchronous()) {
+                            mAsyncMessageCount--;
+                        }
+                        n.recycleUnchecked();
+                        p.next = nn;
+                        if (p.next == null) {
+                            mLast = p;
+                        }
+                        continue;
+                    }
+                }
+                p = n;
+            }
+        }
+    }
+
+    void removeEqualMessages(Handler h, int what, Object object) {
+        if (h == null) {
+            return;
+        }
+
+        synchronized (this) {
+            Message p = mMessages;
+
+            // Remove all messages at front.
+            while (p != null && p.target == h && p.what == what
+                   && (object == null || object.equals(p.obj))) {
+                Message n = p.next;
+                mMessages = n;
+                if (p.isAsynchronous()) {
+                    mAsyncMessageCount--;
+                }
+                p.recycleUnchecked();
+                p = n;
+            }
+
+            if (p == null) {
+                mLast = mMessages;
+            }
+
+            // Remove all messages after front.
+            while (p != null) {
+                Message n = p.next;
+                if (n != null) {
+                    if (n.target == h && n.what == what
+                            && (object == null || object.equals(n.obj))) {
+                        Message nn = n.next;
+                        if (n.isAsynchronous()) {
+                            mAsyncMessageCount--;
+                        }
+                        n.recycleUnchecked();
+                        p.next = nn;
+                        if (p.next == null) {
+                            mLast = p;
+                        }
+                        continue;
+                    }
+                }
+                p = n;
+            }
+        }
+    }
+
+    void removeMessages(Handler h, Runnable r, Object object) {
+        if (h == null || r == null) {
+            return;
+        }
+
+        synchronized (this) {
+            Message p = mMessages;
+
+            // Remove all messages at front.
+            while (p != null && p.target == h && p.callback == r
+                   && (object == null || p.obj == object)) {
+                Message n = p.next;
+                mMessages = n;
+                if (p.isAsynchronous()) {
+                    mAsyncMessageCount--;
+                }
+                p.recycleUnchecked();
+                p = n;
+            }
+
+            if (p == null) {
+                mLast = mMessages;
+            }
+
+            // Remove all messages after front.
+            while (p != null) {
+                Message n = p.next;
+                if (n != null) {
+                    if (n.target == h && n.callback == r
+                            && (object == null || n.obj == object)) {
+                        Message nn = n.next;
+                        if (n.isAsynchronous()) {
+                            mAsyncMessageCount--;
+                        }
+                        n.recycleUnchecked();
+                        p.next = nn;
+                        if (p.next == null) {
+                            mLast = p;
+                        }
+                        continue;
+                    }
+                }
+                p = n;
+            }
+        }
+    }
+
+    void removeEqualMessages(Handler h, Runnable r, Object object) {
+        if (h == null || r == null) {
+            return;
+        }
+
+        synchronized (this) {
+            Message p = mMessages;
+
+            // Remove all messages at front.
+            while (p != null && p.target == h && p.callback == r
+                   && (object == null || object.equals(p.obj))) {
+                Message n = p.next;
+                mMessages = n;
+                if (p.isAsynchronous()) {
+                    mAsyncMessageCount--;
+                }
+                p.recycleUnchecked();
+                p = n;
+            }
+
+            if (p == null) {
+                mLast = mMessages;
+            }
+
+            // Remove all messages after front.
+            while (p != null) {
+                Message n = p.next;
+                if (n != null) {
+                    if (n.target == h && n.callback == r
+                            && (object == null || object.equals(n.obj))) {
+                        Message nn = n.next;
+                        if (n.isAsynchronous()) {
+                            mAsyncMessageCount--;
+                        }
+                        n.recycleUnchecked();
+                        p.next = nn;
+                        if (p.next == null) {
+                            mLast = p;
+                        }
+                        continue;
+                    }
+                }
+                p = n;
+            }
+        }
+    }
+
+
+    void removeCallbacksAndMessages(Handler h, Object object) {
+        if (h == null) {
+            return;
+        }
+
+        synchronized (this) {
+            Message p = mMessages;
+
+            // Remove all messages at front.
+            while (p != null && p.target == h
+                    && (object == null || p.obj == object)) {
+                Message n = p.next;
+                mMessages = n;
+                if (p.isAsynchronous()) {
+                    mAsyncMessageCount--;
+                }
+                p.recycleUnchecked();
+                p = n;
+            }
+
+            if (p == null) {
+                mLast = mMessages;
+            }
+
+            // Remove all messages after front.
+            while (p != null) {
+                Message n = p.next;
+                if (n != null) {
+                    if (n.target == h && (object == null || n.obj == object)) {
+                        Message nn = n.next;
+                        if (n.isAsynchronous()) {
+                            mAsyncMessageCount--;
+                        }
+                        n.recycleUnchecked();
+                        p.next = nn;
+                        if (p.next == null) {
+                            mLast = p;
+                        }
+                        continue;
+                    }
+                }
+                p = n;
+            }
+        }
+    }
+
+    void removeCallbacksAndEqualMessages(Handler h, Object object) {
+        if (h == null) {
+            return;
+        }
+
+        synchronized (this) {
+            Message p = mMessages;
+
+            // Remove all messages at front.
+            while (p != null && p.target == h
+                    && (object == null || object.equals(p.obj))) {
+                Message n = p.next;
+                mMessages = n;
+                if (p.isAsynchronous()) {
+                    mAsyncMessageCount--;
+                }
+                p.recycleUnchecked();
+                p = n;
+            }
+
+            if (p == null) {
+                mLast = mMessages;
+            }
+
+            // Remove all messages after front.
+            while (p != null) {
+                Message n = p.next;
+                if (n != null) {
+                    if (n.target == h && (object == null || object.equals(n.obj))) {
+                        Message nn = n.next;
+                        if (n.isAsynchronous()) {
+                            mAsyncMessageCount--;
+                        }
+                        n.recycleUnchecked();
+                        p.next = nn;
+                        if (p.next == null) {
+                            mLast = p;
+                        }
+                        continue;
+                    }
+                }
+                p = n;
+            }
+        }
+    }
+
+    private void removeAllMessagesLocked() {
+        Message p = mMessages;
+        while (p != null) {
+            Message n = p.next;
+            p.recycleUnchecked();
+            p = n;
+        }
+        mMessages = null;
+        mLast = null;
+        mAsyncMessageCount = 0;
+    }
+
+    private void removeAllFutureMessagesLocked() {
+        final long now = SystemClock.uptimeMillis();
+        Message p = mMessages;
+        if (p != null) {
+            if (p.when > now) {
+                removeAllMessagesLocked();
+            } else {
+                Message n;
+                for (;;) {
+                    n = p.next;
+                    if (n == null) {
+                        return;
+                    }
+                    if (n.when > now) {
+                        break;
+                    }
+                    p = n;
+                }
+                p.next = null;
+                mLast = p;
+
+                do {
+                    p = n;
+                    n = p.next;
+                    if (p.isAsynchronous()) {
+                        mAsyncMessageCount--;
+                    }
+                    p.recycleUnchecked();
+                } while (n != null);
+            }
+        }
+    }
+
+    void dump(Printer pw, String prefix, Handler h) {
+        synchronized (this) {
+            pw.println(prefix + "(MessageQueue is using Legacy implementation)");
+            long now = SystemClock.uptimeMillis();
+            int n = 0;
+            for (Message msg = mMessages; msg != null; msg = msg.next) {
+                if (h == null || h == msg.target) {
+                    pw.println(prefix + "Message " + n + ": " + msg.toString(now));
+                }
+                n++;
+            }
+            pw.println(prefix + "(Total messages: " + n + ", polling=" + isPollingLocked()
+                    + ", quitting=" + mQuitting + ")");
+        }
+    }
+
+    void dumpDebug(ProtoOutputStream proto, long fieldId) {
+        final long messageQueueToken = proto.start(fieldId);
+        synchronized (this) {
+            for (Message msg = mMessages; msg != null; msg = msg.next) {
+                msg.dumpDebug(proto, MessageQueueProto.MESSAGES);
+            }
+            proto.write(MessageQueueProto.IS_POLLING_LOCKED, isPollingLocked());
+            proto.write(MessageQueueProto.IS_QUITTING, mQuitting);
+        }
+        proto.end(messageQueueToken);
+    }
+
+    /**
+     * Callback interface for discovering when a thread is going to block
+     * waiting for more messages.
+     */
+    public static interface IdleHandler {
+        /**
+         * Called when the message queue has run out of messages and will now
+         * wait for more.  Return true to keep your idle handler active, false
+         * to have it removed.  This may be called if there are still messages
+         * pending in the queue, but they are all scheduled to be dispatched
+         * after the current time.
+         */
+        boolean queueIdle();
+    }
+
+    /**
+     * A listener which is invoked when file descriptor related events occur.
+     */
+    public interface OnFileDescriptorEventListener {
+        /**
+         * File descriptor event: Indicates that the file descriptor is ready for input
+         * operations, such as reading.
+         * <p>
+         * The listener should read all available data from the file descriptor
+         * then return <code>true</code> to keep the listener active or <code>false</code>
+         * to remove the listener.
+         * </p><p>
+         * In the case of a socket, this event may be generated to indicate
+         * that there is at least one incoming connection that the listener
+         * should accept.
+         * </p><p>
+         * This event will only be generated if the {@link #EVENT_INPUT} event mask was
+         * specified when the listener was added.
+         * </p>
+         */
+        public static final int EVENT_INPUT = 1 << 0;
+
+        /**
+         * File descriptor event: Indicates that the file descriptor is ready for output
+         * operations, such as writing.
+         * <p>
+         * The listener should write as much data as it needs.  If it could not
+         * write everything at once, then it should return <code>true</code> to
+         * keep the listener active.  Otherwise, it should return <code>false</code>
+         * to remove the listener then re-register it later when it needs to write
+         * something else.
+         * </p><p>
+         * This event will only be generated if the {@link #EVENT_OUTPUT} event mask was
+         * specified when the listener was added.
+         * </p>
+         */
+        public static final int EVENT_OUTPUT = 1 << 1;
+
+        /**
+         * File descriptor event: Indicates that the file descriptor encountered a
+         * fatal error.
+         * <p>
+         * File descriptor errors can occur for various reasons.  One common error
+         * is when the remote peer of a socket or pipe closes its end of the connection.
+         * </p><p>
+         * This event may be generated at any time regardless of whether the
+         * {@link #EVENT_ERROR} event mask was specified when the listener was added.
+         * </p>
+         */
+        public static final int EVENT_ERROR = 1 << 2;
+
+        /** @hide */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(flag = true, prefix = { "EVENT_" }, value = {
+                EVENT_INPUT,
+                EVENT_OUTPUT,
+                EVENT_ERROR
+        })
+        public @interface Events {}
+
+        /**
+         * Called when a file descriptor receives events.
+         *
+         * @param fd The file descriptor.
+         * @param events The set of events that occurred: a combination of the
+         * {@link #EVENT_INPUT}, {@link #EVENT_OUTPUT}, and {@link #EVENT_ERROR} event masks.
+         * @return The new set of events to watch, or 0 to unregister the listener.
+         *
+         * @see #EVENT_INPUT
+         * @see #EVENT_OUTPUT
+         * @see #EVENT_ERROR
+         */
+        @Events int onFileDescriptorEvents(@NonNull FileDescriptor fd, @Events int events);
+    }
+
+    private static final class FileDescriptorRecord {
+        public final FileDescriptor mDescriptor;
+        public int mEvents;
+        public OnFileDescriptorEventListener mListener;
+        public int mSeq;
+
+        public FileDescriptorRecord(FileDescriptor descriptor,
+                int events, OnFileDescriptorEventListener listener) {
+            mDescriptor = descriptor;
+            mEvents = events;
+            mListener = listener;
+        }
+    }
+}
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java
deleted file mode 100644
index 5b711c9..0000000
--- a/core/java/android/os/MessageQueue.java
+++ /dev/null
@@ -1,1224 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.os;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.TestApi;
-import android.compat.annotation.UnsupportedAppUsage;
-import android.util.Log;
-import android.util.Printer;
-import android.util.SparseArray;
-import android.util.proto.ProtoOutputStream;
-
-import java.io.FileDescriptor;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-
-/**
- * Low-level class holding the list of messages to be dispatched by a
- * {@link Looper}.  Messages are not added directly to a MessageQueue,
- * but rather through {@link Handler} objects associated with the Looper.
- *
- * <p>You can retrieve the MessageQueue for the current thread with
- * {@link Looper#myQueue() Looper.myQueue()}.
- */
-@android.ravenwood.annotation.RavenwoodKeepWholeClass
-@android.ravenwood.annotation.RavenwoodNativeSubstitutionClass(
-        "com.android.platform.test.ravenwood.nativesubstitution.MessageQueue_host")
-public final class MessageQueue {
-    private static final String TAG = "MessageQueue";
-    private static final boolean DEBUG = false;
-
-    // True if the message queue can be quit.
-    @UnsupportedAppUsage
-    private final boolean mQuitAllowed;
-
-    @UnsupportedAppUsage
-    @SuppressWarnings("unused")
-    private long mPtr; // used by native code
-
-    @UnsupportedAppUsage
-    Message mMessages;
-    private Message mLast;
-    @UnsupportedAppUsage
-    private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();
-    private SparseArray<FileDescriptorRecord> mFileDescriptorRecords;
-    private IdleHandler[] mPendingIdleHandlers;
-    private boolean mQuitting;
-
-    // Indicates whether next() is blocked waiting in pollOnce() with a non-zero timeout.
-    private boolean mBlocked;
-
-    // Tracks the number of async message. We use this in enqueueMessage() to avoid searching the
-    // queue for async messages when inserting a message at the tail.
-    private int mAsyncMessageCount;
-
-    // The next barrier token.
-    // Barriers are indicated by messages with a null target whose arg1 field carries the token.
-    @UnsupportedAppUsage
-    private int mNextBarrierToken;
-
-    private native static long nativeInit();
-    private native static void nativeDestroy(long ptr);
-    @UnsupportedAppUsage
-    private native void nativePollOnce(long ptr, int timeoutMillis); /*non-static for callbacks*/
-    private native static void nativeWake(long ptr);
-    private native static boolean nativeIsPolling(long ptr);
-    private native static void nativeSetFileDescriptorEvents(long ptr, int fd, int events);
-
-    MessageQueue(boolean quitAllowed) {
-        mQuitAllowed = quitAllowed;
-        mPtr = nativeInit();
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            dispose();
-        } finally {
-            super.finalize();
-        }
-    }
-
-    // Disposes of the underlying message queue.
-    // Must only be called on the looper thread or the finalizer.
-    private void dispose() {
-        if (mPtr != 0) {
-            nativeDestroy(mPtr);
-            mPtr = 0;
-        }
-    }
-
-    /**
-     * Returns true if the looper has no pending messages which are due to be processed.
-     *
-     * <p>This method is safe to call from any thread.
-     *
-     * @return True if the looper is idle.
-     */
-    public boolean isIdle() {
-        synchronized (this) {
-            final long now = SystemClock.uptimeMillis();
-            return mMessages == null || now < mMessages.when;
-        }
-    }
-
-    /**
-     * Add a new {@link IdleHandler} to this message queue.  This may be
-     * removed automatically for you by returning false from
-     * {@link IdleHandler#queueIdle IdleHandler.queueIdle()} when it is
-     * invoked, or explicitly removing it with {@link #removeIdleHandler}.
-     *
-     * <p>This method is safe to call from any thread.
-     *
-     * @param handler The IdleHandler to be added.
-     */
-    public void addIdleHandler(@NonNull IdleHandler handler) {
-        if (handler == null) {
-            throw new NullPointerException("Can't add a null IdleHandler");
-        }
-        synchronized (this) {
-            mIdleHandlers.add(handler);
-        }
-    }
-
-    /**
-     * Remove an {@link IdleHandler} from the queue that was previously added
-     * with {@link #addIdleHandler}.  If the given object is not currently
-     * in the idle list, nothing is done.
-     *
-     * <p>This method is safe to call from any thread.
-     *
-     * @param handler The IdleHandler to be removed.
-     */
-    public void removeIdleHandler(@NonNull IdleHandler handler) {
-        synchronized (this) {
-            mIdleHandlers.remove(handler);
-        }
-    }
-
-    /**
-     * Returns whether this looper's thread is currently polling for more work to do.
-     * This is a good signal that the loop is still alive rather than being stuck
-     * handling a callback.  Note that this method is intrinsically racy, since the
-     * state of the loop can change before you get the result back.
-     *
-     * <p>This method is safe to call from any thread.
-     *
-     * @return True if the looper is currently polling for events.
-     * @hide
-     */
-    public boolean isPolling() {
-        synchronized (this) {
-            return isPollingLocked();
-        }
-    }
-
-    private boolean isPollingLocked() {
-        // If the loop is quitting then it must not be idling.
-        // We can assume mPtr != 0 when mQuitting is false.
-        return !mQuitting && nativeIsPolling(mPtr);
-    }
-
-    /**
-     * Adds a file descriptor listener to receive notification when file descriptor
-     * related events occur.
-     * <p>
-     * If the file descriptor has already been registered, the specified events
-     * and listener will replace any that were previously associated with it.
-     * It is not possible to set more than one listener per file descriptor.
-     * </p><p>
-     * It is important to always unregister the listener when the file descriptor
-     * is no longer of use.
-     * </p>
-     *
-     * @param fd The file descriptor for which a listener will be registered.
-     * @param events The set of events to receive: a combination of the
-     * {@link OnFileDescriptorEventListener#EVENT_INPUT},
-     * {@link OnFileDescriptorEventListener#EVENT_OUTPUT}, and
-     * {@link OnFileDescriptorEventListener#EVENT_ERROR} event masks.  If the requested
-     * set of events is zero, then the listener is unregistered.
-     * @param listener The listener to invoke when file descriptor events occur.
-     *
-     * @see OnFileDescriptorEventListener
-     * @see #removeOnFileDescriptorEventListener
-     */
-    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
-    public void addOnFileDescriptorEventListener(@NonNull FileDescriptor fd,
-            @OnFileDescriptorEventListener.Events int events,
-            @NonNull OnFileDescriptorEventListener listener) {
-        if (fd == null) {
-            throw new IllegalArgumentException("fd must not be null");
-        }
-        if (listener == null) {
-            throw new IllegalArgumentException("listener must not be null");
-        }
-
-        synchronized (this) {
-            updateOnFileDescriptorEventListenerLocked(fd, events, listener);
-        }
-    }
-
-    /**
-     * Removes a file descriptor listener.
-     * <p>
-     * This method does nothing if no listener has been registered for the
-     * specified file descriptor.
-     * </p>
-     *
-     * @param fd The file descriptor whose listener will be unregistered.
-     *
-     * @see OnFileDescriptorEventListener
-     * @see #addOnFileDescriptorEventListener
-     */
-    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
-    public void removeOnFileDescriptorEventListener(@NonNull FileDescriptor fd) {
-        if (fd == null) {
-            throw new IllegalArgumentException("fd must not be null");
-        }
-
-        synchronized (this) {
-            updateOnFileDescriptorEventListenerLocked(fd, 0, null);
-        }
-    }
-
-    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
-    private void updateOnFileDescriptorEventListenerLocked(FileDescriptor fd, int events,
-            OnFileDescriptorEventListener listener) {
-        final int fdNum = fd.getInt$();
-
-        int index = -1;
-        FileDescriptorRecord record = null;
-        if (mFileDescriptorRecords != null) {
-            index = mFileDescriptorRecords.indexOfKey(fdNum);
-            if (index >= 0) {
-                record = mFileDescriptorRecords.valueAt(index);
-                if (record != null && record.mEvents == events) {
-                    return;
-                }
-            }
-        }
-
-        if (events != 0) {
-            events |= OnFileDescriptorEventListener.EVENT_ERROR;
-            if (record == null) {
-                if (mFileDescriptorRecords == null) {
-                    mFileDescriptorRecords = new SparseArray<FileDescriptorRecord>();
-                }
-                record = new FileDescriptorRecord(fd, events, listener);
-                mFileDescriptorRecords.put(fdNum, record);
-            } else {
-                record.mListener = listener;
-                record.mEvents = events;
-                record.mSeq += 1;
-            }
-            nativeSetFileDescriptorEvents(mPtr, fdNum, events);
-        } else if (record != null) {
-            record.mEvents = 0;
-            mFileDescriptorRecords.removeAt(index);
-            nativeSetFileDescriptorEvents(mPtr, fdNum, 0);
-        }
-    }
-
-    // Called from native code.
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    private int dispatchEvents(int fd, int events) {
-        // Get the file descriptor record and any state that might change.
-        final FileDescriptorRecord record;
-        final int oldWatchedEvents;
-        final OnFileDescriptorEventListener listener;
-        final int seq;
-        synchronized (this) {
-            record = mFileDescriptorRecords.get(fd);
-            if (record == null) {
-                return 0; // spurious, no listener registered
-            }
-
-            oldWatchedEvents = record.mEvents;
-            events &= oldWatchedEvents; // filter events based on current watched set
-            if (events == 0) {
-                return oldWatchedEvents; // spurious, watched events changed
-            }
-
-            listener = record.mListener;
-            seq = record.mSeq;
-        }
-
-        // Invoke the listener outside of the lock.
-        int newWatchedEvents = listener.onFileDescriptorEvents(
-                record.mDescriptor, events);
-        if (newWatchedEvents != 0) {
-            newWatchedEvents |= OnFileDescriptorEventListener.EVENT_ERROR;
-        }
-
-        // Update the file descriptor record if the listener changed the set of
-        // events to watch and the listener itself hasn't been updated since.
-        if (newWatchedEvents != oldWatchedEvents) {
-            synchronized (this) {
-                int index = mFileDescriptorRecords.indexOfKey(fd);
-                if (index >= 0 && mFileDescriptorRecords.valueAt(index) == record
-                        && record.mSeq == seq) {
-                    record.mEvents = newWatchedEvents;
-                    if (newWatchedEvents == 0) {
-                        mFileDescriptorRecords.removeAt(index);
-                    }
-                }
-            }
-        }
-
-        // Return the new set of events to watch for native code to take care of.
-        return newWatchedEvents;
-    }
-
-    @UnsupportedAppUsage
-    Message next() {
-        // Return here if the message loop has already quit and been disposed.
-        // This can happen if the application tries to restart a looper after quit
-        // which is not supported.
-        final long ptr = mPtr;
-        if (ptr == 0) {
-            return null;
-        }
-
-        int pendingIdleHandlerCount = -1; // -1 only during first iteration
-        int nextPollTimeoutMillis = 0;
-        for (;;) {
-            if (nextPollTimeoutMillis != 0) {
-                Binder.flushPendingCommands();
-            }
-
-            nativePollOnce(ptr, nextPollTimeoutMillis);
-
-            synchronized (this) {
-                // Try to retrieve the next message.  Return if found.
-                final long now = SystemClock.uptimeMillis();
-                Message prevMsg = null;
-                Message msg = mMessages;
-                if (msg != null && msg.target == null) {
-                    // Stalled by a barrier.  Find the next asynchronous message in the queue.
-                    do {
-                        prevMsg = msg;
-                        msg = msg.next;
-                    } while (msg != null && !msg.isAsynchronous());
-                }
-                if (msg != null) {
-                    if (now < msg.when) {
-                        // Next message is not ready.  Set a timeout to wake up when it is ready.
-                        nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
-                    } else {
-                        // Got a message.
-                        mBlocked = false;
-                        if (prevMsg != null) {
-                            prevMsg.next = msg.next;
-                            if (prevMsg.next == null) {
-                                mLast = prevMsg;
-                            }
-                        } else {
-                            mMessages = msg.next;
-                            if (msg.next == null) {
-                                mLast = null;
-                            }
-                        }
-                        msg.next = null;
-                        if (DEBUG) Log.v(TAG, "Returning message: " + msg);
-                        msg.markInUse();
-                        if (msg.isAsynchronous()) {
-                            mAsyncMessageCount--;
-                        }
-                        return msg;
-                    }
-                } else {
-                    // No more messages.
-                    nextPollTimeoutMillis = -1;
-                }
-
-                // Process the quit message now that all pending messages have been handled.
-                if (mQuitting) {
-                    dispose();
-                    return null;
-                }
-
-                // If first time idle, then get the number of idlers to run.
-                // Idle handles only run if the queue is empty or if the first message
-                // in the queue (possibly a barrier) is due to be handled in the future.
-                if (pendingIdleHandlerCount < 0
-                        && (mMessages == null || now < mMessages.when)) {
-                    pendingIdleHandlerCount = mIdleHandlers.size();
-                }
-                if (pendingIdleHandlerCount <= 0) {
-                    // No idle handlers to run.  Loop and wait some more.
-                    mBlocked = true;
-                    continue;
-                }
-
-                if (mPendingIdleHandlers == null) {
-                    mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
-                }
-                mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
-            }
-
-            // Run the idle handlers.
-            // We only ever reach this code block during the first iteration.
-            for (int i = 0; i < pendingIdleHandlerCount; i++) {
-                final IdleHandler idler = mPendingIdleHandlers[i];
-                mPendingIdleHandlers[i] = null; // release the reference to the handler
-
-                boolean keep = false;
-                try {
-                    keep = idler.queueIdle();
-                } catch (Throwable t) {
-                    Log.wtf(TAG, "IdleHandler threw exception", t);
-                }
-
-                if (!keep) {
-                    synchronized (this) {
-                        mIdleHandlers.remove(idler);
-                    }
-                }
-            }
-
-            // Reset the idle handler count to 0 so we do not run them again.
-            pendingIdleHandlerCount = 0;
-
-            // While calling an idle handler, a new message could have been delivered
-            // so go back and look again for a pending message without waiting.
-            nextPollTimeoutMillis = 0;
-        }
-    }
-
-    void quit(boolean safe) {
-        if (!mQuitAllowed) {
-            throw new IllegalStateException("Main thread not allowed to quit.");
-        }
-
-        synchronized (this) {
-            if (mQuitting) {
-                return;
-            }
-            mQuitting = true;
-
-            if (safe) {
-                removeAllFutureMessagesLocked();
-            } else {
-                removeAllMessagesLocked();
-            }
-
-            // We can assume mPtr != 0 because mQuitting was previously false.
-            nativeWake(mPtr);
-        }
-    }
-
-    /**
-     * Posts a synchronization barrier to the Looper's message queue.
-     *
-     * Message processing occurs as usual until the message queue encounters the
-     * synchronization barrier that has been posted.  When the barrier is encountered,
-     * later synchronous messages in the queue are stalled (prevented from being executed)
-     * until the barrier is released by calling {@link #removeSyncBarrier} and specifying
-     * the token that identifies the synchronization barrier.
-     *
-     * This method is used to immediately postpone execution of all subsequently posted
-     * synchronous messages until a condition is met that releases the barrier.
-     * Asynchronous messages (see {@link Message#isAsynchronous} are exempt from the barrier
-     * and continue to be processed as usual.
-     *
-     * This call must be always matched by a call to {@link #removeSyncBarrier} with
-     * the same token to ensure that the message queue resumes normal operation.
-     * Otherwise the application will probably hang!
-     *
-     * @return A token that uniquely identifies the barrier.  This token must be
-     * passed to {@link #removeSyncBarrier} to release the barrier.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    @TestApi
-    public int postSyncBarrier() {
-        return postSyncBarrier(SystemClock.uptimeMillis());
-    }
-
-    private int postSyncBarrier(long when) {
-        // Enqueue a new sync barrier token.
-        // We don't need to wake the queue because the purpose of a barrier is to stall it.
-        synchronized (this) {
-            final int token = mNextBarrierToken++;
-            final Message msg = Message.obtain();
-            msg.markInUse();
-            msg.when = when;
-            msg.arg1 = token;
-
-            if (Flags.messageQueueTailTracking() && mLast != null && mLast.when <= when) {
-                /* Message goes to tail of list */
-                mLast.next = msg;
-                mLast = msg;
-                msg.next = null;
-                return token;
-            }
-
-            Message prev = null;
-            Message p = mMessages;
-            if (when != 0) {
-                while (p != null && p.when <= when) {
-                    prev = p;
-                    p = p.next;
-                }
-            }
-
-            if (p == null) {
-                /* We reached the tail of the list, or list is empty. */
-                mLast = msg;
-            }
-
-            if (prev != null) { // invariant: p == prev.next
-                msg.next = p;
-                prev.next = msg;
-            } else {
-                msg.next = p;
-                mMessages = msg;
-            }
-            return token;
-        }
-    }
-
-    /**
-     * Removes a synchronization barrier.
-     *
-     * @param token The synchronization barrier token that was returned by
-     * {@link #postSyncBarrier}.
-     *
-     * @throws IllegalStateException if the barrier was not found.
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    @TestApi
-    public void removeSyncBarrier(int token) {
-        // Remove a sync barrier token from the queue.
-        // If the queue is no longer stalled by a barrier then wake it.
-        synchronized (this) {
-            Message prev = null;
-            Message p = mMessages;
-            while (p != null && (p.target != null || p.arg1 != token)) {
-                prev = p;
-                p = p.next;
-            }
-            if (p == null) {
-                throw new IllegalStateException("The specified message queue synchronization "
-                        + " barrier token has not been posted or has already been removed.");
-            }
-            final boolean needWake;
-            if (prev != null) {
-                prev.next = p.next;
-                if (prev.next == null) {
-                    mLast = prev;
-                }
-                needWake = false;
-            } else {
-                mMessages = p.next;
-                if (mMessages == null) {
-                    mLast = null;
-                }
-                needWake = mMessages == null || mMessages.target != null;
-            }
-            p.recycleUnchecked();
-
-            // If the loop is quitting then it is already awake.
-            // We can assume mPtr != 0 when mQuitting is false.
-            if (needWake && !mQuitting) {
-                nativeWake(mPtr);
-            }
-        }
-    }
-
-    boolean enqueueMessage(Message msg, long when) {
-        if (msg.target == null) {
-            throw new IllegalArgumentException("Message must have a target.");
-        }
-
-        synchronized (this) {
-            if (msg.isInUse()) {
-                throw new IllegalStateException(msg + " This message is already in use.");
-            }
-
-            if (mQuitting) {
-                IllegalStateException e = new IllegalStateException(
-                        msg.target + " sending message to a Handler on a dead thread");
-                Log.w(TAG, e.getMessage(), e);
-                msg.recycle();
-                return false;
-            }
-
-            msg.markInUse();
-            msg.when = when;
-            Message p = mMessages;
-            boolean needWake;
-            if (p == null || when == 0 || when < p.when) {
-                // New head, wake up the event queue if blocked.
-                msg.next = p;
-                mMessages = msg;
-                needWake = mBlocked;
-                if (p == null) {
-                    mLast = mMessages;
-                }
-            } else {
-                // Message is to be inserted at tail or middle of queue. Usually we don't have to
-                // wake up the event queue unless there is a barrier at the head of the queue and
-                // the message is the earliest asynchronous message in the queue.
-                needWake = mBlocked && p.target == null && msg.isAsynchronous();
-
-                // For readability, we split this portion of the function into two blocks based on
-                // whether tail tracking is enabled. This has a minor implication for the case
-                // where tail tracking is disabled. See the comment below.
-                if (Flags.messageQueueTailTracking()) {
-                    if (when >= mLast.when) {
-                        needWake = needWake && mAsyncMessageCount == 0;
-                        msg.next = null;
-                        mLast.next = msg;
-                        mLast = msg;
-                    } else {
-                        // Inserted within the middle of the queue.
-                        Message prev;
-                        for (;;) {
-                            prev = p;
-                            p = p.next;
-                            if (p == null || when < p.when) {
-                                break;
-                            }
-                            if (needWake && p.isAsynchronous()) {
-                                needWake = false;
-                            }
-                        }
-                        if (p == null) {
-                            /* Inserting at tail of queue */
-                            mLast = msg;
-                        }
-                        msg.next = p; // invariant: p == prev.next
-                        prev.next = msg;
-                    }
-                } else {
-                    Message prev;
-                    for (;;) {
-                        prev = p;
-                        p = p.next;
-                        if (p == null || when < p.when) {
-                            break;
-                        }
-                        if (needWake && p.isAsynchronous()) {
-                            needWake = false;
-                        }
-                    }
-                    msg.next = p; // invariant: p == prev.next
-                    prev.next = msg;
-
-                    /*
-                     * If this block is executing then we have a build without tail tracking -
-                     * specifically: Flags.messageQueueTailTracking() == false. This is determined
-                     * at build time so the flag won't change on us during runtime.
-                     *
-                     * Since we don't want to pepper the code with extra checks, we only check
-                     * for tail tracking when we might use mLast. Otherwise, we continue to update
-                     * mLast as the tail of the list.
-                     *
-                     * In this case however we are not maintaining mLast correctly. Since we never
-                     * use it, this is fine. However, we run the risk of leaking a reference.
-                     * So set mLast to null in this case to avoid any Message leaks. The other
-                     * sites will never use the value so we are safe against null pointer derefs.
-                     */
-                    mLast = null;
-                }
-            }
-
-            if (msg.isAsynchronous()) {
-                mAsyncMessageCount++;
-            }
-
-            // We can assume mPtr != 0 because mQuitting is false.
-            if (needWake) {
-                nativeWake(mPtr);
-            }
-        }
-        return true;
-    }
-
-    boolean hasMessages(Handler h, int what, Object object) {
-        if (h == null) {
-            return false;
-        }
-
-        synchronized (this) {
-            Message p = mMessages;
-            while (p != null) {
-                if (p.target == h && p.what == what && (object == null || p.obj == object)) {
-                    return true;
-                }
-                p = p.next;
-            }
-            return false;
-        }
-    }
-
-    boolean hasEqualMessages(Handler h, int what, Object object) {
-        if (h == null) {
-            return false;
-        }
-
-        synchronized (this) {
-            Message p = mMessages;
-            while (p != null) {
-                if (p.target == h && p.what == what && (object == null || object.equals(p.obj))) {
-                    return true;
-                }
-                p = p.next;
-            }
-            return false;
-        }
-    }
-
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    boolean hasMessages(Handler h, Runnable r, Object object) {
-        if (h == null) {
-            return false;
-        }
-
-        synchronized (this) {
-            Message p = mMessages;
-            while (p != null) {
-                if (p.target == h && p.callback == r && (object == null || p.obj == object)) {
-                    return true;
-                }
-                p = p.next;
-            }
-            return false;
-        }
-    }
-
-    boolean hasMessages(Handler h) {
-        if (h == null) {
-            return false;
-        }
-
-        synchronized (this) {
-            Message p = mMessages;
-            while (p != null) {
-                if (p.target == h) {
-                    return true;
-                }
-                p = p.next;
-            }
-            return false;
-        }
-    }
-
-    void removeMessages(Handler h, int what, Object object) {
-        if (h == null) {
-            return;
-        }
-
-        synchronized (this) {
-            Message p = mMessages;
-
-            // Remove all messages at front.
-            while (p != null && p.target == h && p.what == what
-                   && (object == null || p.obj == object)) {
-                Message n = p.next;
-                mMessages = n;
-                if (p.isAsynchronous()) {
-                    mAsyncMessageCount--;
-                }
-                p.recycleUnchecked();
-                p = n;
-            }
-
-            if (p == null) {
-                mLast = mMessages;
-            }
-
-            // Remove all messages after front.
-            while (p != null) {
-                Message n = p.next;
-                if (n != null) {
-                    if (n.target == h && n.what == what
-                        && (object == null || n.obj == object)) {
-                        Message nn = n.next;
-                        if (n.isAsynchronous()) {
-                            mAsyncMessageCount--;
-                        }
-                        n.recycleUnchecked();
-                        p.next = nn;
-                        if (p.next == null) {
-                            mLast = p;
-                        }
-                        continue;
-                    }
-                }
-                p = n;
-            }
-        }
-    }
-
-    void removeEqualMessages(Handler h, int what, Object object) {
-        if (h == null) {
-            return;
-        }
-
-        synchronized (this) {
-            Message p = mMessages;
-
-            // Remove all messages at front.
-            while (p != null && p.target == h && p.what == what
-                   && (object == null || object.equals(p.obj))) {
-                Message n = p.next;
-                mMessages = n;
-                if (p.isAsynchronous()) {
-                    mAsyncMessageCount--;
-                }
-                p.recycleUnchecked();
-                p = n;
-            }
-
-            if (p == null) {
-                mLast = mMessages;
-            }
-
-            // Remove all messages after front.
-            while (p != null) {
-                Message n = p.next;
-                if (n != null) {
-                    if (n.target == h && n.what == what
-                        && (object == null || object.equals(n.obj))) {
-                        Message nn = n.next;
-                        if (n.isAsynchronous()) {
-                            mAsyncMessageCount--;
-                        }
-                        n.recycleUnchecked();
-                        p.next = nn;
-                        if (p.next == null) {
-                            mLast = p;
-                        }
-                        continue;
-                    }
-                }
-                p = n;
-            }
-        }
-    }
-
-    void removeMessages(Handler h, Runnable r, Object object) {
-        if (h == null || r == null) {
-            return;
-        }
-
-        synchronized (this) {
-            Message p = mMessages;
-
-            // Remove all messages at front.
-            while (p != null && p.target == h && p.callback == r
-                   && (object == null || p.obj == object)) {
-                Message n = p.next;
-                mMessages = n;
-                if (p.isAsynchronous()) {
-                    mAsyncMessageCount--;
-                }
-                p.recycleUnchecked();
-                p = n;
-            }
-
-            if (p == null) {
-                mLast = mMessages;
-            }
-
-            // Remove all messages after front.
-            while (p != null) {
-                Message n = p.next;
-                if (n != null) {
-                    if (n.target == h && n.callback == r
-                        && (object == null || n.obj == object)) {
-                        Message nn = n.next;
-                        if (n.isAsynchronous()) {
-                            mAsyncMessageCount--;
-                        }
-                        n.recycleUnchecked();
-                        p.next = nn;
-                        if (p.next == null) {
-                            mLast = p;
-                        }
-                        continue;
-                    }
-                }
-                p = n;
-            }
-        }
-    }
-
-    void removeEqualMessages(Handler h, Runnable r, Object object) {
-        if (h == null || r == null) {
-            return;
-        }
-
-        synchronized (this) {
-            Message p = mMessages;
-
-            // Remove all messages at front.
-            while (p != null && p.target == h && p.callback == r
-                   && (object == null || object.equals(p.obj))) {
-                Message n = p.next;
-                mMessages = n;
-                if (p.isAsynchronous()) {
-                    mAsyncMessageCount--;
-                }
-                p.recycleUnchecked();
-                p = n;
-            }
-
-            if (p == null) {
-                mLast = mMessages;
-            }
-
-            // Remove all messages after front.
-            while (p != null) {
-                Message n = p.next;
-                if (n != null) {
-                    if (n.target == h && n.callback == r
-                        && (object == null || object.equals(n.obj))) {
-                        Message nn = n.next;
-                        if (n.isAsynchronous()) {
-                            mAsyncMessageCount--;
-                        }
-                        n.recycleUnchecked();
-                        p.next = nn;
-                        if (p.next == null) {
-                            mLast = p;
-                        }
-                        continue;
-                    }
-                }
-                p = n;
-            }
-        }
-    }
-
-
-    void removeCallbacksAndMessages(Handler h, Object object) {
-        if (h == null) {
-            return;
-        }
-
-        synchronized (this) {
-            Message p = mMessages;
-
-            // Remove all messages at front.
-            while (p != null && p.target == h
-                    && (object == null || p.obj == object)) {
-                Message n = p.next;
-                mMessages = n;
-                if (p.isAsynchronous()) {
-                    mAsyncMessageCount--;
-                }
-                p.recycleUnchecked();
-                p = n;
-            }
-
-            if (p == null) {
-                mLast = mMessages;
-            }
-
-            // Remove all messages after front.
-            while (p != null) {
-                Message n = p.next;
-                if (n != null) {
-                    if (n.target == h && (object == null || n.obj == object)) {
-                        Message nn = n.next;
-                        if (n.isAsynchronous()) {
-                            mAsyncMessageCount--;
-                        }
-                        n.recycleUnchecked();
-                        p.next = nn;
-                        if (p.next == null) {
-                            mLast = p;
-                        }
-                        continue;
-                    }
-                }
-                p = n;
-            }
-        }
-    }
-
-    void removeCallbacksAndEqualMessages(Handler h, Object object) {
-        if (h == null) {
-            return;
-        }
-
-        synchronized (this) {
-            Message p = mMessages;
-
-            // Remove all messages at front.
-            while (p != null && p.target == h
-                    && (object == null || object.equals(p.obj))) {
-                Message n = p.next;
-                mMessages = n;
-                if (p.isAsynchronous()) {
-                    mAsyncMessageCount--;
-                }
-                p.recycleUnchecked();
-                p = n;
-            }
-
-            if (p == null) {
-                mLast = mMessages;
-            }
-
-            // Remove all messages after front.
-            while (p != null) {
-                Message n = p.next;
-                if (n != null) {
-                    if (n.target == h && (object == null || object.equals(n.obj))) {
-                        Message nn = n.next;
-                        if (n.isAsynchronous()) {
-                            mAsyncMessageCount--;
-                        }
-                        n.recycleUnchecked();
-                        p.next = nn;
-                        if (p.next == null) {
-                            mLast = p;
-                        }
-                        continue;
-                    }
-                }
-                p = n;
-            }
-        }
-    }
-
-    private void removeAllMessagesLocked() {
-        Message p = mMessages;
-        while (p != null) {
-            Message n = p.next;
-            p.recycleUnchecked();
-            p = n;
-        }
-        mMessages = null;
-        mLast = null;
-        mAsyncMessageCount = 0;
-    }
-
-    private void removeAllFutureMessagesLocked() {
-        final long now = SystemClock.uptimeMillis();
-        Message p = mMessages;
-        if (p != null) {
-            if (p.when > now) {
-                removeAllMessagesLocked();
-            } else {
-                Message n;
-                for (;;) {
-                    n = p.next;
-                    if (n == null) {
-                        return;
-                    }
-                    if (n.when > now) {
-                        break;
-                    }
-                    p = n;
-                }
-                p.next = null;
-                mLast = p;
-
-                do {
-                    p = n;
-                    n = p.next;
-                    if (p.isAsynchronous()) {
-                        mAsyncMessageCount--;
-                    }
-                    p.recycleUnchecked();
-                } while (n != null);
-            }
-        }
-    }
-
-    void dump(Printer pw, String prefix, Handler h) {
-        synchronized (this) {
-            long now = SystemClock.uptimeMillis();
-            int n = 0;
-            for (Message msg = mMessages; msg != null; msg = msg.next) {
-                if (h == null || h == msg.target) {
-                    pw.println(prefix + "Message " + n + ": " + msg.toString(now));
-                }
-                n++;
-            }
-            pw.println(prefix + "(Total messages: " + n + ", polling=" + isPollingLocked()
-                    + ", quitting=" + mQuitting + ")");
-        }
-    }
-
-    void dumpDebug(ProtoOutputStream proto, long fieldId) {
-        final long messageQueueToken = proto.start(fieldId);
-        synchronized (this) {
-            for (Message msg = mMessages; msg != null; msg = msg.next) {
-                msg.dumpDebug(proto, MessageQueueProto.MESSAGES);
-            }
-            proto.write(MessageQueueProto.IS_POLLING_LOCKED, isPollingLocked());
-            proto.write(MessageQueueProto.IS_QUITTING, mQuitting);
-        }
-        proto.end(messageQueueToken);
-    }
-
-    /**
-     * Callback interface for discovering when a thread is going to block
-     * waiting for more messages.
-     */
-    public static interface IdleHandler {
-        /**
-         * Called when the message queue has run out of messages and will now
-         * wait for more.  Return true to keep your idle handler active, false
-         * to have it removed.  This may be called if there are still messages
-         * pending in the queue, but they are all scheduled to be dispatched
-         * after the current time.
-         */
-        boolean queueIdle();
-    }
-
-    /**
-     * A listener which is invoked when file descriptor related events occur.
-     */
-    public interface OnFileDescriptorEventListener {
-        /**
-         * File descriptor event: Indicates that the file descriptor is ready for input
-         * operations, such as reading.
-         * <p>
-         * The listener should read all available data from the file descriptor
-         * then return <code>true</code> to keep the listener active or <code>false</code>
-         * to remove the listener.
-         * </p><p>
-         * In the case of a socket, this event may be generated to indicate
-         * that there is at least one incoming connection that the listener
-         * should accept.
-         * </p><p>
-         * This event will only be generated if the {@link #EVENT_INPUT} event mask was
-         * specified when the listener was added.
-         * </p>
-         */
-        public static final int EVENT_INPUT = 1 << 0;
-
-        /**
-         * File descriptor event: Indicates that the file descriptor is ready for output
-         * operations, such as writing.
-         * <p>
-         * The listener should write as much data as it needs.  If it could not
-         * write everything at once, then it should return <code>true</code> to
-         * keep the listener active.  Otherwise, it should return <code>false</code>
-         * to remove the listener then re-register it later when it needs to write
-         * something else.
-         * </p><p>
-         * This event will only be generated if the {@link #EVENT_OUTPUT} event mask was
-         * specified when the listener was added.
-         * </p>
-         */
-        public static final int EVENT_OUTPUT = 1 << 1;
-
-        /**
-         * File descriptor event: Indicates that the file descriptor encountered a
-         * fatal error.
-         * <p>
-         * File descriptor errors can occur for various reasons.  One common error
-         * is when the remote peer of a socket or pipe closes its end of the connection.
-         * </p><p>
-         * This event may be generated at any time regardless of whether the
-         * {@link #EVENT_ERROR} event mask was specified when the listener was added.
-         * </p>
-         */
-        public static final int EVENT_ERROR = 1 << 2;
-
-        /** @hide */
-        @Retention(RetentionPolicy.SOURCE)
-        @IntDef(flag = true, prefix = { "EVENT_" }, value = {
-                EVENT_INPUT,
-                EVENT_OUTPUT,
-                EVENT_ERROR
-        })
-        public @interface Events {}
-
-        /**
-         * Called when a file descriptor receives events.
-         *
-         * @param fd The file descriptor.
-         * @param events The set of events that occurred: a combination of the
-         * {@link #EVENT_INPUT}, {@link #EVENT_OUTPUT}, and {@link #EVENT_ERROR} event masks.
-         * @return The new set of events to watch, or 0 to unregister the listener.
-         *
-         * @see #EVENT_INPUT
-         * @see #EVENT_OUTPUT
-         * @see #EVENT_ERROR
-         */
-        @Events int onFileDescriptorEvents(@NonNull FileDescriptor fd, @Events int events);
-    }
-
-    private static final class FileDescriptorRecord {
-        public final FileDescriptor mDescriptor;
-        public int mEvents;
-        public OnFileDescriptorEventListener mListener;
-        public int mSeq;
-
-        public FileDescriptorRecord(FileDescriptor descriptor,
-                int events, OnFileDescriptorEventListener listener) {
-            mDescriptor = descriptor;
-            mEvents = events;
-            mListener = listener;
-        }
-    }
-}
diff --git a/core/java/android/os/PowerComponents.java b/core/java/android/os/PowerComponents.java
index 164e265..b035f12 100644
--- a/core/java/android/os/PowerComponents.java
+++ b/core/java/android/os/PowerComponents.java
@@ -516,6 +516,19 @@
         }
 
         @NonNull
+        public Builder addConsumedPowerForCustomComponent(int componentId, double componentPower) {
+            final int index = componentId - BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID;
+            if (index < 0 || index >= mData.layout.customPowerComponentCount) {
+                throw new IllegalArgumentException(
+                        "Unsupported custom power component ID: " + componentId);
+            }
+            mData.putDouble(mData.layout.firstCustomConsumedPowerColumn + index,
+                    mData.getDouble(mData.layout.firstCustomConsumedPowerColumn + index)
+                            + componentPower);
+            return this;
+        }
+
+        @NonNull
         public Builder setUsageDurationMillis(BatteryConsumer.Key key,
                 long componentUsageDurationMillis) {
             mData.putLong(key.mDurationColumnIndex, componentUsageDurationMillis);
diff --git a/core/java/android/os/SemiConcurrentMessageQueue/MessageQueue.java b/core/java/android/os/SemiConcurrentMessageQueue/MessageQueue.java
new file mode 100644
index 0000000..967332f
--- /dev/null
+++ b/core/java/android/os/SemiConcurrentMessageQueue/MessageQueue.java
@@ -0,0 +1,1589 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.os;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.os.Handler;
+import android.os.Trace;
+import android.util.Log;
+import android.util.Printer;
+import android.util.SparseArray;
+import android.util.proto.ProtoOutputStream;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.io.FileDescriptor;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.PriorityQueue;
+import java.util.PriorityQueue;
+import java.util.PriorityQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Low-level class holding the list of messages to be dispatched by a
+ * {@link Looper}.  Messages are not added directly to a MessageQueue,
+ * but rather through {@link Handler} objects associated with the Looper.
+ *
+ * <p>You can retrieve the MessageQueue for the current thread with
+ * {@link Looper#myQueue() Looper.myQueue()}.
+ */
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
+@android.ravenwood.annotation.RavenwoodNativeSubstitutionClass(
+        "com.android.platform.test.ravenwood.nativesubstitution.MessageQueue_host")
+public final class MessageQueue {
+    private static final String TAG = "SemiConcurrentMessageQueue";
+    private static final boolean DEBUG = false;
+    private static final boolean TRACE = false;
+
+    // True if the message queue can be quit.
+    private final boolean mQuitAllowed;
+
+    @SuppressWarnings("unused")
+    private long mPtr; // used by native code
+
+    @IntDef(value = {
+        STACK_NODE_MESSAGE,
+        STACK_NODE_ACTIVE,
+        STACK_NODE_PARKED,
+        STACK_NODE_TIMEDPARK})
+    @Retention(RetentionPolicy.SOURCE)
+    private @interface StackNodeType {}
+
+    /*
+     * Stack node types. STACK_NODE_MESSAGE indicates a node containing a message.
+     * The other types indicate what state our Looper thread is in. The bottom of
+     * the stack is always a single state node. Message nodes are added on top.
+     */
+    private static final int STACK_NODE_MESSAGE = 0;
+    /*
+     * Active state indicates that next() is processing messages
+     */
+    private static final int STACK_NODE_ACTIVE = 1;
+    /*
+     * Parked state indicates that the Looper thread is sleeping indefinitely (nothing to deliver)
+     */
+    private static final int STACK_NODE_PARKED = 2;
+    /*
+     * Timed Park state indicates that the Looper thread is sleeping, waiting for a message
+     * deadline
+     */
+    private static final int STACK_NODE_TIMEDPARK = 3;
+
+    /* Describes a node in the Treiber stack */
+    static class StackNode {
+        @StackNodeType
+        private final int mType;
+
+        StackNode(@StackNodeType int type) {
+            mType = type;
+        }
+
+        @StackNodeType
+        final int getNodeType() {
+            return mType;
+        }
+
+        final boolean isMessageNode() {
+            return mType == STACK_NODE_MESSAGE;
+        }
+    }
+
+    static final class MessageNode extends StackNode implements Comparable<MessageNode> {
+        private final Message mMessage;
+        volatile StackNode mNext;
+        StateNode mBottomOfStack;
+        boolean mWokeUp;
+        boolean mRemovedFromStack = false;
+        final long mInsertSeq;
+
+        MessageNode(@NonNull Message message, long insertSeq) {
+            super(STACK_NODE_MESSAGE);
+            mMessage = message;
+            mInsertSeq = insertSeq;
+        }
+
+        long getWhen() {
+            return mMessage.when;
+        }
+
+        boolean isRemovedFromStack() {
+            return mRemovedFromStack;
+        }
+
+        boolean removeFromStack() {
+            if (!mRemovedFromStack) {
+                mRemovedFromStack = true;
+                return true;
+            }
+            return false;
+        }
+
+        boolean isAsync() {
+            return mMessage.isAsynchronous();
+        }
+
+        boolean isBarrier() {
+            return mMessage.target == null;
+        }
+
+        @Override
+        public int compareTo(@NonNull MessageNode messageNode) {
+            Message other = messageNode.mMessage;
+
+            int compared = Long.compare(mMessage.when, other.when);
+            if (compared == 0) {
+                compared = Long.compare(mInsertSeq, messageNode.mInsertSeq);
+            }
+            return compared;
+        }
+    }
+
+    static class StateNode extends StackNode {
+        StateNode(int type) {
+            super(type);
+        }
+    }
+
+    static final class TimedParkStateNode extends StateNode {
+        long mWhenToWake;
+
+        TimedParkStateNode() {
+            super(STACK_NODE_TIMEDPARK);
+        }
+    }
+
+    private static final StateNode sStackStateActive = new StateNode(STACK_NODE_ACTIVE);
+    private static final StateNode sStackStateParked = new StateNode(STACK_NODE_PARKED);
+    private final TimedParkStateNode mStackStateTimedPark = new TimedParkStateNode();
+
+    /* This is the top of our treiber stack. */
+    private static final VarHandle sState;
+    static {
+        try {
+            MethodHandles.Lookup l = MethodHandles.lookup();
+            sState = l.findVarHandle(MessageQueue.class, "mStateValue",
+                    MessageQueue.StackNode.class);
+        } catch (Exception e) {
+            Log.wtf(TAG, "VarHandle lookup failed with exception: " + e);
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
+    private volatile StackNode mStateValue = sStackStateParked;
+    @GuardedBy("mPriorityQueue")
+    private final PriorityQueue<MessageNode> mPriorityQueue =
+            new PriorityQueue<MessageNode>();
+    @GuardedBy("mPriorityQueue")
+    private final PriorityQueue<MessageNode> mAsyncPriorityQueue =
+            new PriorityQueue<MessageNode>();
+
+    /*
+     * This helps us ensure that messages with the same timestamp are inserted in FIFO order.
+     * Increments on each insert, starting at 0. MessageNode.compareTo() will compare sequences
+     * when delivery timestamps are identical.
+     */
+    private static final VarHandle sNextInsertSeq;
+    private volatile long mNextInsertSeqValue = 0;
+    /*
+     * The exception to the FIFO order rule is sendMessageAtFrontOfQueue().
+     * Those messages must be in LIFO order - SIGH.
+     * Decrements on each front of queue insert.
+     */
+    private static final VarHandle sNextFrontInsertSeq;
+    private volatile long mNextFrontInsertSeqValue = -1;
+    static {
+        try {
+            MethodHandles.Lookup l = MethodHandles.lookup();
+            sNextInsertSeq = l.findVarHandle(MessageQueue.class, "mNextInsertSeqValue",
+                    long.class);
+            sNextFrontInsertSeq = l.findVarHandle(MessageQueue.class, "mNextFrontInsertSeqValue",
+                    long.class);
+        } catch (Exception e) {
+            Log.wtf(TAG, "VarHandle lookup failed with exception: " + e);
+            throw new ExceptionInInitializerError(e);
+        }
+
+    }
+
+    /*
+     * Tracks the number of queued and cancelled messages in our stack.
+     *
+     * On item cancellation, determine whether to wake next() to flush tombstoned messages.
+     * We track queued and cancelled counts as two ints packed into a single long.
+     */
+    private static final class MessageCounts {
+        private static VarHandle sCounts;
+        private volatile long mCountsValue = 0;
+        static {
+            try {
+                MethodHandles.Lookup l = MethodHandles.lookup();
+                sCounts = l.findVarHandle(MessageQueue.MessageCounts.class, "mCountsValue",
+                        long.class);
+            } catch (Exception e) {
+                Log.wtf(TAG, "VarHandle lookup failed with exception: " + e);
+                throw new ExceptionInInitializerError(e);
+            }
+        }
+        /* We use a special value to indicate when next() has been woken for flush. */
+        private static final long AWAKE = Long.MAX_VALUE;
+        /*
+         * Minimum number of messages in the stack which we need before we consider flushing
+         * tombstoned items.
+         */
+        private static final int MESSAGE_FLUSH_THRESHOLD = 10;
+
+        private static int numQueued(long val) {
+            return (int) (val >>> Integer.SIZE);
+        }
+
+        private static int numCancelled(long val) {
+            return (int) val;
+        }
+
+        private static long combineCounts(int queued, int cancelled) {
+            return ((long) queued << Integer.SIZE) | (long) cancelled;
+        }
+
+        public void incrementQueued() {
+            while (true) {
+                long oldVal = mCountsValue;
+                int queued = numQueued(oldVal);
+                int cancelled = numCancelled(oldVal);
+                /* Use Math.max() to avoid overflow of queued count */
+                long newVal = combineCounts(Math.max(queued + 1, queued), cancelled);
+
+                /* Don't overwrite 'AWAKE' state */
+                if (oldVal == AWAKE || sCounts.compareAndSet(this, oldVal, newVal)) {
+                    break;
+                }
+            }
+        }
+
+        public boolean incrementCancelled() {
+            while (true) {
+                long oldVal = mCountsValue;
+                if (oldVal == AWAKE) {
+                    return false;
+                }
+                int queued = numQueued(oldVal);
+                int cancelled = numCancelled(oldVal);
+                boolean needsPurge = queued > MESSAGE_FLUSH_THRESHOLD
+                        && (queued >> 1) < cancelled;
+                long newVal;
+                if (needsPurge) {
+                    newVal = AWAKE;
+                } else {
+                    newVal = combineCounts(queued,
+                            Math.max(cancelled + 1, cancelled));
+                }
+
+                if (sCounts.compareAndSet(this, oldVal, newVal)) {
+                    return needsPurge;
+                }
+            }
+        }
+
+        public void clearCounts() {
+            mCountsValue = 0;
+        }
+    }
+
+    private final MessageCounts mMessageCounts = new MessageCounts();
+
+    private final Object mIdleHandlersLock = new Object();
+    @GuardedBy("mIdleHandlersLock")
+    private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();
+    private IdleHandler[] mPendingIdleHandlers;
+
+    private final Object mFileDescriptorRecordsLock = new Object();
+    @GuardedBy("mFileDescriptorRecordsLock")
+    private SparseArray<FileDescriptorRecord> mFileDescriptorRecords;
+
+    private static final VarHandle sQuitting;
+    private boolean mQuittingValue = false;
+    static {
+        try {
+            MethodHandles.Lookup l = MethodHandles.lookup();
+            sQuitting = l.findVarHandle(MessageQueue.class, "mQuittingValue", boolean.class);
+        } catch (Exception e) {
+            Log.wtf(TAG, "VarHandle lookup failed with exception: " + e);
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
+    // The next barrier token.
+    // Barriers are indicated by messages with a null target whose arg1 field carries the token.
+    private final AtomicInteger mNextBarrierToken = new AtomicInteger(1);
+
+    private static native long nativeInit();
+    private static native void nativeDestroy(long ptr);
+    private native void nativePollOnce(long ptr, int timeoutMillis); /*non-static for callbacks*/
+    private static native void nativeWake(long ptr);
+    private static native boolean nativeIsPolling(long ptr);
+    private static native void nativeSetFileDescriptorEvents(long ptr, int fd, int events);
+
+    MessageQueue(boolean quitAllowed) {
+        mQuitAllowed = quitAllowed;
+        mPtr = nativeInit();
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            dispose();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    // Disposes of the underlying message queue.
+    // Must only be called on the looper thread or the finalizer.
+    private void dispose() {
+        if (mPtr != 0) {
+            nativeDestroy(mPtr);
+            mPtr = 0;
+        }
+    }
+
+    /**
+     * Returns true if the looper has no pending messages which are due to be processed.
+     *
+     * <p>This method is safe to call from any thread.
+     *
+     * @return True if the looper is idle.
+     */
+    public boolean isIdle() {
+        MessageNode msgNode = null;
+        MessageNode asyncMsgNode = null;
+
+        synchronized (mPriorityQueue) {
+            msgNode = mPriorityQueue.peek();
+            asyncMsgNode = mAsyncPriorityQueue.peek();
+
+            final long now = SystemClock.uptimeMillis();
+            if ((msgNode != null && msgNode.getWhen() <= now)
+                    || (asyncMsgNode != null && asyncMsgNode.getWhen() <= now)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Add a new {@link IdleHandler} to this message queue.  This may be
+     * removed automatically for you by returning false from
+     * {@link IdleHandler#queueIdle IdleHandler.queueIdle()} when it is
+     * invoked, or explicitly removing it with {@link #removeIdleHandler}.
+     *
+     * <p>This method is safe to call from any thread.
+     *
+     * @param handler The IdleHandler to be added.
+     */
+    public void addIdleHandler(@NonNull IdleHandler handler) {
+        if (handler == null) {
+            throw new NullPointerException("Can't add a null IdleHandler");
+        }
+        synchronized (mIdleHandlersLock) {
+            mIdleHandlers.add(handler);
+        }
+    }
+
+    /**
+     * Remove an {@link IdleHandler} from the queue that was previously added
+     * with {@link #addIdleHandler}.  If the given object is not currently
+     * in the idle list, nothing is done.
+     *
+     * <p>This method is safe to call from any thread.
+     *
+     * @param handler The IdleHandler to be removed.
+     */
+    public void removeIdleHandler(@NonNull IdleHandler handler) {
+        synchronized (mIdleHandlersLock) {
+            mIdleHandlers.remove(handler);
+        }
+    }
+
+    /**
+     * Returns whether this looper's thread is currently polling for more work to do.
+     * This is a good signal that the loop is still alive rather than being stuck
+     * handling a callback.  Note that this method is intrinsically racy, since the
+     * state of the loop can change before you get the result back.
+     *
+     * <p>This method is safe to call from any thread.
+     *
+     * @return True if the looper is currently polling for events.
+     * @hide
+     */
+    public boolean isPolling() {
+        // If the loop is quitting then it must not be idling.
+        // We can assume mPtr != 0 when sQuitting is false.
+        return !((boolean) sQuitting.getVolatile(this)) && nativeIsPolling(mPtr);
+    }
+
+    /* Helper to choose the correct queue to insert into. */
+    @GuardedBy("mPriorityQueue")
+    private void insertIntoPriorityQueue(MessageNode msgNode) {
+        if (msgNode.isAsync()) {
+            mAsyncPriorityQueue.offer(msgNode);
+        } else {
+            mPriorityQueue.offer(msgNode);
+        }
+    }
+
+    @GuardedBy("mPriorityQueue")
+    private boolean removeFromPriorityQueue(MessageNode msgNode) {
+        if (msgNode.isAsync()) {
+            return mAsyncPriorityQueue.remove(msgNode);
+        } else {
+            return mPriorityQueue.remove(msgNode);
+        }
+    }
+
+    private MessageNode pickEarliestNode(MessageNode nodeA, MessageNode nodeB) {
+        if (nodeA != null && nodeB != null) {
+            if (nodeA.compareTo(nodeB) < 0) {
+                return nodeA;
+            }
+            return nodeB;
+        }
+
+        return nodeA != null ? nodeA : nodeB;
+    }
+
+    /* Move any non-cancelled messages into the priority queue */
+    private void drainStack(StackNode oldTop) {
+        while (oldTop.isMessageNode()) {
+            MessageNode oldTopMessageNode = (MessageNode) oldTop;
+            if (oldTopMessageNode.removeFromStack()) {
+                insertIntoPriorityQueue(oldTopMessageNode);
+            }
+            MessageNode inserted = oldTopMessageNode;
+            oldTop = oldTopMessageNode.mNext;
+        }
+    }
+
+    /* Set the stack state to Active, return a list of nodes to walk. */
+    private StackNode swapAndSetStackStateActive() {
+        while (true) {
+            /* Set stack state to Active, get node list to walk later */
+            StackNode current = (StackNode) sState.getVolatile(this);
+            if (current == sStackStateActive
+                    || sState.compareAndSet(this, current, sStackStateActive)) {
+                return current;
+            }
+        }
+    }
+
+    /* This is only read/written from the Looper thread */
+    private int mNextPollTimeoutMillis;
+    private static final AtomicLong mMessagesDelivered = new AtomicLong();
+
+    private Message nextMessage() {
+        int i = 0;
+
+        while (true) {
+            if (DEBUG) {
+                Log.d(TAG, "nextMessage loop #" + i);
+                i++;
+            }
+
+            /* This protects us from racing with remove. Enqueue can still add items. */
+            synchronized (mPriorityQueue) {
+
+                /*
+                 * Set our state to active, drain any items from the stack into our priority queues
+                 */
+                StackNode oldTop;
+                oldTop = swapAndSetStackStateActive();
+                drainStack(oldTop);
+
+                /*
+                 * The objective of this next block of code is to:
+                 *  - find a message to return (if any is ready)
+                 *  - find a next message we would like to return, after scheduling.
+                 *     - we make our scheduling decision based on this next message (if it exists).
+                 *
+                 * We have two queues to juggle and the presence of barriers throws an additional
+                 * wrench into our plans.
+                */
+
+                /* Get the first node from each queue */
+                MessageNode msgNode = mPriorityQueue.peek();
+                MessageNode asyncMsgNode = mAsyncPriorityQueue.peek();
+
+                if (DEBUG) {
+                    if (msgNode != null) {
+                        Message msg = msgNode.mMessage;
+                        Log.d(TAG, "Next found node what: " + msg.what + " when: " + msg.when
+                                + " seq: " + msgNode.mInsertSeq + "barrier: "
+                                + msgNode.isBarrier() + " now: "
+                                + SystemClock.uptimeMillis());
+                    }
+                    if (asyncMsgNode != null) {
+                        Message msg = asyncMsgNode.mMessage;
+                        Log.d(TAG, "Next found async node what: " + msg.what + " when: " + msg.when
+                                + " seq: " + asyncMsgNode.mInsertSeq + "barrier: "
+                                + asyncMsgNode.isBarrier() + " now: "
+                                + SystemClock.uptimeMillis());
+                    }
+                }
+
+                /*
+                 * the node which we will return, null if none are ready
+                 */
+                MessageNode found = null;
+                /*
+                 * The node from which we will determine our next wakeup time.
+                 * Null indicates there is no next message ready. If we found a node,
+                 * we can leave this null as Looper will call us again after delivering
+                 * the message.
+                 */
+                MessageNode next = null;
+
+                long now = SystemClock.uptimeMillis();
+                /*
+                 * If we have a barrier we should return the async node if it exists and is
+                 * ready
+                 */
+                if (msgNode != null && msgNode.isBarrier()) {
+                    if (asyncMsgNode != null && now >= asyncMsgNode.getWhen()) {
+                        found = asyncMsgNode;
+                        removeFromPriorityQueue(found);
+                    } else {
+                        next = asyncMsgNode;
+                    }
+                } else { /* No barrier. */
+                    MessageNode earliest;
+                    /*
+                     * If we have two messages, pick the earliest option from either queue.
+                     * Otherwise grab whichever node is non-null. If both are null we'll fall
+                     * through.
+                     */
+                    earliest = pickEarliestNode(msgNode, asyncMsgNode);
+
+                    if (earliest != null) {
+                        if (now >= earliest.getWhen()) {
+                            found = earliest;
+                            removeFromPriorityQueue(found);
+                        } else {
+                            next = earliest;
+                        }
+                    }
+                }
+
+                if (DEBUG) {
+                    if (found != null) {
+                        Message msg = found.mMessage;
+                        Log.d(TAG, "Will deliver node what: " + msg.what + " when: " + msg.when
+                                + " seq: " + found.mInsertSeq + " barrier: "
+                                + found.isBarrier() + " async: " + found.isAsync()
+                                + " now: " + SystemClock.uptimeMillis());
+                    } else {
+                        Log.d(TAG, "No node to deliver");
+                    }
+                    if (next != null) {
+                        Message msg = next.mMessage;
+                        Log.d(TAG, "Next node what: " + msg.what + " when: " + msg.when + " seq: "
+                                + next.mInsertSeq + " barrier: " + next.isBarrier()
+                                + " async: " + next.isAsync()
+                                + " now: " + SystemClock.uptimeMillis());
+                    } else {
+                        Log.d(TAG, "No next node");
+                    }
+                }
+
+                /*
+                 * If we have a found message, we will get called again so there's no need to set
+                 * state.
+                 * In that case we can leave our state as ACTIVE.
+                 *
+                 * Otherwise we should determine how to park the thread.
+                 */
+                StateNode nextOp = sStackStateActive;
+                if (found == null) {
+                    if (next == null) {
+                        /* No message to deliver, sleep indefinitely */
+                        mNextPollTimeoutMillis = -1;
+                        nextOp = sStackStateParked;
+                        if (DEBUG) {
+                            Log.d(TAG, "nextMessage next state is StackStateParked");
+                        }
+                    } else {
+                        /* Message not ready, or we found one to deliver already, set a timeout */
+                        long nextMessageWhen = next.getWhen();
+                        if (nextMessageWhen > now) {
+                            mNextPollTimeoutMillis = (int) Math.min(nextMessageWhen - now,
+                                    Integer.MAX_VALUE);
+                        } else {
+                            mNextPollTimeoutMillis = 0;
+                        }
+
+                        mStackStateTimedPark.mWhenToWake = now + mNextPollTimeoutMillis;
+                        nextOp = mStackStateTimedPark;
+                        if (DEBUG) {
+                            Log.d(TAG, "nextMessage next state is StackStateTimedParked "
+                                    + " next timeout ms " + mNextPollTimeoutMillis
+                                    + " mWhenToWake: " + mStackStateTimedPark.mWhenToWake
+                                    + " now " + now);
+                        }
+                    }
+                }
+
+                /*
+                 * Try to swap our state from Active back to Park or TimedPark. If we raced with
+                 * enqueue, loop back around to pick up any new items.
+                 */
+                if (sState.compareAndSet(this, sStackStateActive, nextOp)) {
+                    mMessageCounts.clearCounts();
+                    if (found != null) {
+                        if (TRACE) {
+                            Trace.setCounter("MQ.Delivered", mMessagesDelivered.incrementAndGet());
+                        }
+                        return found.mMessage;
+                    }
+                    return null;
+                }
+                if (found != null) {
+                    /*
+                     * Add this node back - we will be adding new nodes into our priority queue, and
+                     * recalculating what to return.
+                     */
+                    insertIntoPriorityQueue(found);
+                }
+            }
+        }
+    }
+
+    Message next() {
+        final long ptr = mPtr;
+        if (ptr == 0) {
+            return null;
+        }
+
+        mNextPollTimeoutMillis = 0;
+        int pendingIdleHandlerCount = -1; // -1 only during first iteration
+        while (true) {
+            if (mNextPollTimeoutMillis != 0) {
+                Binder.flushPendingCommands();
+            }
+
+            nativePollOnce(ptr, mNextPollTimeoutMillis);
+
+            Message msg = nextMessage();
+            if (msg != null) {
+                msg.markInUse();
+                return msg;
+            }
+
+            if ((boolean) sQuitting.getVolatile(this)) {
+                return null;
+            }
+
+            synchronized (mIdleHandlersLock) {
+                // If first time idle, then get the number of idlers to run.
+                // Idle handles only run if the queue is empty or if the first message
+                // in the queue (possibly a barrier) is due to be handled in the future.
+                if (pendingIdleHandlerCount < 0
+                        && mNextPollTimeoutMillis != 0) {
+                    pendingIdleHandlerCount = mIdleHandlers.size();
+                }
+                if (pendingIdleHandlerCount <= 0) {
+                    // No idle handlers to run.  Loop and wait some more.
+                    continue;
+                }
+
+                if (mPendingIdleHandlers == null) {
+                    mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
+                }
+                mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
+            }
+
+            // Run the idle handlers.
+            // We only ever reach this code block during the first iteration.
+            for (int i = 0; i < pendingIdleHandlerCount; i++) {
+                final IdleHandler idler = mPendingIdleHandlers[i];
+                mPendingIdleHandlers[i] = null; // release the reference to the handler
+
+                boolean keep = false;
+                try {
+                    keep = idler.queueIdle();
+                } catch (Throwable t) {
+                    Log.wtf(TAG, "IdleHandler threw exception", t);
+                }
+
+                if (!keep) {
+                    synchronized (mIdleHandlersLock) {
+                        mIdleHandlers.remove(idler);
+                    }
+                }
+            }
+
+            // Reset the idle handler count to 0 so we do not run them again.
+            pendingIdleHandlerCount = 0;
+
+            // While calling an idle handler, a new message could have been delivered
+            // so go back and look again for a pending message without waiting.
+            mNextPollTimeoutMillis = 0;
+        }
+    }
+
+    void quit(boolean safe) {
+        if (!mQuitAllowed) {
+            throw new IllegalStateException("Main thread not allowed to quit.");
+        }
+        synchronized (mIdleHandlersLock) {
+            if (sQuitting.compareAndSet(this, false, true)) {
+                if (safe) {
+                    removeAllFutureMessages();
+                } else {
+                    removeAllMessages();
+                }
+
+                // We can assume mPtr != 0 because sQuitting was previously false.
+                nativeWake(mPtr);
+            }
+        }
+    }
+
+    boolean enqueueMessage(@NonNull Message msg, long when) {
+        if (msg.target == null) {
+            throw new IllegalArgumentException("Message must have a target.");
+        }
+
+        if (msg.isInUse()) {
+            throw new IllegalStateException(msg + " This message is already in use.");
+        }
+
+        return enqueueMessageUnchecked(msg, when);
+    }
+
+    private boolean enqueueMessageUnchecked(@NonNull Message msg, long when) {
+        if ((boolean) sQuitting.getVolatile(this)) {
+            IllegalStateException e = new IllegalStateException(
+                    msg.target + " sending message to a Handler on a dead thread");
+            Log.w(TAG, e.getMessage(), e);
+            msg.recycleUnchecked();
+            return false;
+        }
+
+        long seq = when != 0 ? ((long)sNextInsertSeq.getAndAdd(this, 1L) + 1L)
+                : ((long)sNextFrontInsertSeq.getAndAdd(this, -1L) - 1L);
+        /* TODO: Add a MessageNode member to Message so we can avoid this allocation */
+        MessageNode node = new MessageNode(msg, seq);
+        msg.when = when;
+        msg.markInUse();
+
+        if (DEBUG) {
+            Log.d(TAG, "Insert message what: " + msg.what + " when: " + msg.when + " seq: "
+                    + node.mInsertSeq + " barrier: " + node.isBarrier() + " async: "
+                    + node.isAsync() + " now: " + SystemClock.uptimeMillis());
+        }
+
+        while (true) {
+            StackNode old = (StackNode) sState.getVolatile(this);
+            boolean wakeNeeded;
+            boolean inactive;
+
+            node.mNext = old;
+            switch (old.getNodeType()) {
+                case STACK_NODE_ACTIVE:
+                    /*
+                     * The worker thread is currently active and will process any elements added to
+                     * the stack before parking again.
+                     */
+                    node.mBottomOfStack = (StateNode) old;
+                    inactive = false;
+                    node.mWokeUp = true;
+                    wakeNeeded = false;
+                    break;
+
+                case STACK_NODE_PARKED:
+                    node.mBottomOfStack = (StateNode) old;
+                    inactive = true;
+                    node.mWokeUp = true;
+                    wakeNeeded = true;
+                    break;
+
+                case STACK_NODE_TIMEDPARK:
+                    node.mBottomOfStack = (StateNode) old;
+                    inactive = true;
+                    wakeNeeded = mStackStateTimedPark.mWhenToWake >= node.getWhen();
+                    node.mWokeUp = wakeNeeded;
+                    break;
+
+                default:
+                    MessageNode oldMessage = (MessageNode) old;
+
+                    node.mBottomOfStack = oldMessage.mBottomOfStack;
+                    int bottomType = node.mBottomOfStack.getNodeType();
+                    inactive = bottomType >= STACK_NODE_PARKED;
+                    wakeNeeded = (bottomType == STACK_NODE_TIMEDPARK
+                            && mStackStateTimedPark.mWhenToWake >= node.getWhen()
+                            && !oldMessage.mWokeUp);
+                    node.mWokeUp = oldMessage.mWokeUp || wakeNeeded;
+                    break;
+            }
+            if (sState.compareAndSet(this, old, node)) {
+                if (inactive) {
+                    if (wakeNeeded) {
+                        nativeWake(mPtr);
+                    } else {
+                        mMessageCounts.incrementQueued();
+                    }
+                }
+                return true;
+            }
+        }
+    }
+
+    /**
+     * Posts a synchronization barrier to the Looper's message queue.
+     *
+     * Message processing occurs as usual until the message queue encounters the
+     * synchronization barrier that has been posted.  When the barrier is encountered,
+     * later synchronous messages in the queue are stalled (prevented from being executed)
+     * until the barrier is released by calling {@link #removeSyncBarrier} and specifying
+     * the token that identifies the synchronization barrier.
+     *
+     * This method is used to immediately postpone execution of all subsequently posted
+     * synchronous messages until a condition is met that releases the barrier.
+     * Asynchronous messages (see {@link Message#isAsynchronous} are exempt from the barrier
+     * and continue to be processed as usual.
+     *
+     * This call must be always matched by a call to {@link #removeSyncBarrier} with
+     * the same token to ensure that the message queue resumes normal operation.
+     * Otherwise the application will probably hang!
+     *
+     * @return A token that uniquely identifies the barrier.  This token must be
+     * passed to {@link #removeSyncBarrier} to release the barrier.
+     *
+     * @hide
+     */
+    @TestApi
+    public int postSyncBarrier() {
+        return postSyncBarrier(SystemClock.uptimeMillis());
+    }
+
+    private int postSyncBarrier(long when) {
+        final int token = mNextBarrierToken.getAndIncrement();
+        final Message msg = Message.obtain();
+
+        msg.markInUse();
+        msg.arg1 = token;
+
+        if (!enqueueMessageUnchecked(msg, when)) {
+            Log.wtf(TAG, "Unexpected error while adding sync barrier!");
+            return -1;
+        }
+
+        return token;
+    }
+
+    private class MatchBarrierToken extends MessageCompare {
+        int mBarrierToken;
+
+        MatchBarrierToken(int token) {
+            super();
+            mBarrierToken = token;
+        }
+
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            if (m.target == null && m.arg1 == mBarrierToken) {
+                return true;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Removes a synchronization barrier.
+     *
+     * @param token The synchronization barrier token that was returned by
+     * {@link #postSyncBarrier}.
+     *
+     * @throws IllegalStateException if the barrier was not found.
+     *
+     * @hide
+     */
+    @TestApi
+    public void removeSyncBarrier(int token) {
+        boolean removed;
+        MessageNode first;
+        final MatchBarrierToken matchBarrierToken = new MatchBarrierToken(token);
+
+        synchronized (mPriorityQueue) {
+            try {
+                /* Retain the first element to see if we are currently stuck on a barrier. */
+                first = mPriorityQueue.peek();
+            } catch (NoSuchElementException e) {
+                /* The queue is empty */
+                first = null;
+            }
+
+            removed = findOrRemoveMessages(null, 0, null, null, 0, matchBarrierToken, true);
+            if (removed && first != null) {
+                Message m = first.mMessage;
+                if (m.target == null && m.arg1 == token) {
+                    /* Wake up next() in case it was sleeping on this barrier. */
+                    nativeWake(mPtr);
+                }
+            } else if (!removed) {
+                throw new IllegalStateException("The specified message queue synchronization "
+                        + " barrier token has not been posted or has already been removed.");
+            }
+        }
+    }
+
+    private StateNode getStateNode(StackNode node) {
+        if (node.isMessageNode()) {
+            return ((MessageNode) node).mBottomOfStack;
+        }
+        return (StateNode) node;
+    }
+
+    /*
+     * This class is used to find matches for hasMessages() and removeMessages()
+     */
+    private abstract static class MessageCompare {
+        public abstract boolean compareMessage(Message m, Handler h, int what, Object object,
+                Runnable r, long when);
+    }
+    @GuardedBy("mPriorityQueue")
+    private boolean stackHasMessages(Handler h, int what, Object object, Runnable r, long when,
+            MessageCompare compare, boolean removeMatches) {
+        boolean found = false;
+        StackNode top = (StackNode) sState.getVolatile(this);
+        StateNode bottom = getStateNode(top);
+
+        /* No messages to search. */
+        if (!top.isMessageNode()) {
+            return false;
+        }
+
+        /*
+         * We have messages that we may tombstone. Walk the stack until we hit the bottom.
+         * next() will remove them on it's next pass.
+         */
+        if (!(top instanceof MessageNode)) {
+            Log.wtf(TAG, "Unknown node type found in Trieber stack");
+        }
+        MessageNode p = (MessageNode) top;
+
+        while (true) {
+            if (compare.compareMessage(p.mMessage, h, what, object, r, when)) {
+                found = true;
+                if (DEBUG) {
+                    Log.w(TAG, "stackHasMessages node matches");
+                }
+                if (removeMatches) {
+                    if (p.removeFromStack()) {
+                        p.mMessage.recycleUnchecked();
+                        if (mMessageCounts.incrementCancelled()) {
+                            nativeWake(mPtr);
+                        }
+                    }
+                } else {
+                    return true;
+                }
+            }
+
+            StackNode n = p.mNext;
+            if (!n.isMessageNode()) {
+                /* We reached the end of the stack */
+                return found;
+            }
+            p = (MessageNode) n;
+        }
+    }
+
+    @GuardedBy("mPriorityQueue")
+    private boolean priorityQueueHasMessage(PriorityQueue queue, Handler h,
+            int what, Object object, Runnable r, long when, MessageCompare compare,
+            boolean removeMatches) {
+        Iterator<MessageNode> iterator = queue.iterator();
+        boolean found = false;
+
+        while (iterator.hasNext()) {
+            MessageNode msg = iterator.next();
+
+            if (compare.compareMessage(msg.mMessage, h, what, object, r, when)) {
+                if (removeMatches) {
+                    found = true;
+                    iterator.remove();
+                    msg.mMessage.recycleUnchecked();
+                } else {
+                    return true;
+                }
+            }
+        }
+        return found;
+    }
+
+    private boolean findOrRemoveMessages(Handler h, int what, Object object, Runnable r, long when,
+            MessageCompare compare, boolean removeMatches) {
+        boolean foundInStack, foundInQueue;
+
+        synchronized (mPriorityQueue) {
+            foundInStack = stackHasMessages(h, what, object, r, when, compare, removeMatches);
+            foundInQueue = priorityQueueHasMessage(mPriorityQueue, h, what, object, r, when,
+                    compare, removeMatches);
+            foundInQueue |= priorityQueueHasMessage(mAsyncPriorityQueue, h, what, object, r, when,
+                    compare, removeMatches);
+
+            return foundInStack || foundInQueue;
+        }
+    }
+
+    private static class MatchHandlerWhatAndObject extends MessageCompare {
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            if (m.target == h && m.what == what && (object == null || m.obj == object)) {
+                return true;
+            }
+            return false;
+        }
+    }
+    private final MatchHandlerWhatAndObject mMatchHandlerWhatAndObject =
+            new MatchHandlerWhatAndObject();
+    boolean hasMessages(Handler h, int what, Object object) {
+        if (h == null) {
+            return false;
+        }
+
+        return findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObject, false);
+    }
+
+    private static class MatchHandlerWhatAndObjectEquals extends MessageCompare {
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            if (m.target == h && m.what == what && (object == null || object.equals(m.obj))) {
+                return true;
+            }
+            return false;
+        }
+    }
+    private final MatchHandlerWhatAndObjectEquals mMatchHandlerWhatAndObjectEquals =
+            new MatchHandlerWhatAndObjectEquals();
+    boolean hasEqualMessages(Handler h, int what, Object object) {
+        if (h == null) {
+            return false;
+        }
+
+        return findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObjectEquals,
+                false);
+    }
+
+    private static class MatchHandlerRunnableAndObject extends MessageCompare {
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            if (m.target == h && m.callback == r && (object == null || m.obj == object)) {
+                return true;
+            }
+            return false;
+        }
+    }
+    private final MatchHandlerRunnableAndObject mMatchHandlerRunnableAndObject =
+            new MatchHandlerRunnableAndObject();
+
+    boolean hasMessages(Handler h, Runnable r, Object object) {
+        if (h == null) {
+            return false;
+        }
+
+        return findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObject, false);
+    }
+
+    private static class MatchHandler extends MessageCompare {
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            if (m.target == h) {
+                return true;
+            }
+            return false;
+        }
+    }
+    private final MatchHandler mMatchHandler = new MatchHandler();
+    boolean hasMessages(Handler h) {
+        if (h == null) {
+            return false;
+        }
+        return findOrRemoveMessages(h, -1, null, null, 0, mMatchHandler, false);
+    }
+
+    void removeMessages(Handler h, int what, Object object) {
+        if (h == null) {
+            return;
+        }
+        findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObject, true);
+    }
+
+    void removeEqualMessages(Handler h, int what, Object object) {
+        if (h == null) {
+            return;
+        }
+        findOrRemoveMessages(h, what, object, null, 0, mMatchHandlerWhatAndObjectEquals, true);
+    }
+
+    void removeMessages(Handler h, Runnable r, Object object) {
+        if (h == null || r == null) {
+            return;
+        }
+        findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObject, true);
+    }
+
+    private static class MatchHandlerRunnableAndObjectEquals extends MessageCompare {
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            if (m.target == h && m.callback == r && (object == null || object.equals(m.obj))) {
+                return true;
+            }
+            return false;
+        }
+    }
+    private final MatchHandlerRunnableAndObjectEquals mMatchHandlerRunnableAndObjectEquals =
+            new MatchHandlerRunnableAndObjectEquals();
+    void removeEqualMessages(Handler h, Runnable r, Object object) {
+        if (h == null || r == null) {
+            return;
+        }
+        findOrRemoveMessages(h, -1, object, r, 0, mMatchHandlerRunnableAndObjectEquals, true);
+    }
+
+    private static class MatchHandlerAndObject extends MessageCompare {
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            if (m.target == h && (object == null || m.obj == object)) {
+                return true;
+            }
+            return false;
+        }
+    }
+    private final MatchHandlerAndObject mMatchHandlerAndObject = new MatchHandlerAndObject();
+    void removeCallbacksAndMessages(Handler h, Object object) {
+        if (h == null) {
+            return;
+        }
+        findOrRemoveMessages(h, -1, object, null, 0, mMatchHandlerAndObject, true);
+    }
+
+    private static class MatchHandlerAndObjectEquals extends MessageCompare {
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            if (m.target == h && (object == null || object.equals(m.obj))) {
+                return true;
+            }
+            return false;
+        }
+    }
+    private final MatchHandlerAndObjectEquals mMatchHandlerAndObjectEquals =
+            new MatchHandlerAndObjectEquals();
+    void removeCallbacksAndEqualMessages(Handler h, Object object) {
+        if (h == null) {
+            return;
+        }
+        findOrRemoveMessages(h, -1, object, null, 0, mMatchHandlerAndObjectEquals, true);
+    }
+
+    private static class MatchAllMessages extends MessageCompare {
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            return true;
+        }
+    }
+    private final MatchAllMessages mMatchAllMessages = new MatchAllMessages();
+    private void removeAllMessages() {
+        findOrRemoveMessages(null, -1, null, null, 0, mMatchAllMessages, true);
+    }
+
+    private static class MatchAllFutureMessages extends MessageCompare {
+        @Override
+        public boolean compareMessage(Message m, Handler h, int what, Object object, Runnable r,
+                long when) {
+            if (m.when > when) {
+                return true;
+            }
+            return false;
+        }
+    }
+    private final MatchAllFutureMessages mMatchAllFutureMessages = new MatchAllFutureMessages();
+    private void removeAllFutureMessages() {
+        findOrRemoveMessages(null, -1, null, null, SystemClock.uptimeMillis(),
+                mMatchAllFutureMessages, true);
+    }
+
+    private void printPriorityQueueNodes() {
+        Iterator<MessageNode> iterator = mPriorityQueue.iterator();
+
+        Log.d(TAG, "* Dump priority queue");
+        while (iterator.hasNext()) {
+            MessageNode msgNode = iterator.next();
+            Log.d(TAG, "** MessageNode what: " + msgNode.mMessage.what + " when "
+                    + msgNode.mMessage.when + " seq: " + msgNode.mInsertSeq);
+        }
+    }
+
+    private int dumpPriorityQueue(PriorityQueue<MessageNode> queue, Printer pw, String prefix,
+            Handler h, int n) {
+        int count = 0;
+        long now = SystemClock.uptimeMillis();
+
+        for (MessageNode msgNode : queue) {
+            Message msg = msgNode.mMessage;
+            if (h == null || h == msg.target) {
+                pw.println(prefix + "Message " + (n + count) + ": " + msg.toString(now));
+            }
+            count++;
+        }
+        return count;
+    }
+
+    void dump(Printer pw, String prefix, Handler h) {
+        long now = SystemClock.uptimeMillis();
+        int n = 0;
+
+        pw.println(prefix + "(MessageQueue is using SemiConcurrent implementation)");
+
+        StackNode node = (StackNode) sState.getVolatile(this);
+        while (node != null) {
+            if (node.isMessageNode()) {
+                Message msg = ((MessageNode) node).mMessage;
+                if (h == null || h == msg.target) {
+                    pw.println(prefix + "Message " + n + ": " + msg.toString(now));
+                }
+                node = ((MessageNode) node).mNext;
+            } else {
+                pw.println(prefix + "State: " + node);
+                node = null;
+            }
+            n++;
+        }
+
+        synchronized (mPriorityQueue) {
+            pw.println(prefix + "PriorityQueue Messages: ");
+            n += dumpPriorityQueue(mPriorityQueue, pw, prefix, h, n);
+            pw.println(prefix + "AsyncPriorityQueue Messages: ");
+            n += dumpPriorityQueue(mAsyncPriorityQueue, pw, prefix, h, n);
+        }
+
+        pw.println(prefix + "(Total messages: " + n + ", polling=" + isPolling()
+                + ", quitting=" + (boolean) sQuitting.getVolatile(this) + ")");
+    }
+
+    private int dumpPriorityQueue(PriorityQueue<MessageNode> queue, ProtoOutputStream proto) {
+        int count = 0;
+
+        for (MessageNode msgNode : queue) {
+            Message msg = msgNode.mMessage;
+            msg.dumpDebug(proto, MessageQueueProto.MESSAGES);
+            count++;
+        }
+        return count;
+    }
+
+    void dumpDebug(ProtoOutputStream proto, long fieldId) {
+        final long messageQueueToken = proto.start(fieldId);
+
+        StackNode node = (StackNode) sState.getVolatile(this);
+        while (node.isMessageNode()) {
+            Message msg = ((MessageNode) node).mMessage;
+            msg.dumpDebug(proto, MessageQueueProto.MESSAGES);
+            node = ((MessageNode) node).mNext;
+        }
+
+        synchronized (mPriorityQueue) {
+            dumpPriorityQueue(mPriorityQueue, proto);
+            dumpPriorityQueue(mAsyncPriorityQueue, proto);
+        }
+
+        proto.write(MessageQueueProto.IS_POLLING_LOCKED, isPolling());
+        proto.write(MessageQueueProto.IS_QUITTING, (boolean) sQuitting.getVolatile(this));
+        proto.end(messageQueueToken);
+    }
+
+    /**
+     * Adds a file descriptor listener to receive notification when file descriptor
+     * related events occur.
+     * <p>
+     * If the file descriptor has already been registered, the specified events
+     * and listener will replace any that were previously associated with it.
+     * It is not possible to set more than one listener per file descriptor.
+     * </p><p>
+     * It is important to always unregister the listener when the file descriptor
+     * is no longer of use.
+     * </p>
+     *
+     * @param fd The file descriptor for which a listener will be registered.
+     * @param events The set of events to receive: a combination of the
+     * {@link OnFileDescriptorEventListener#EVENT_INPUT},
+     * {@link OnFileDescriptorEventListener#EVENT_OUTPUT}, and
+     * {@link OnFileDescriptorEventListener#EVENT_ERROR} event masks.  If the requested
+     * set of events is zero, then the listener is unregistered.
+     * @param listener The listener to invoke when file descriptor events occur.
+     *
+     * @see OnFileDescriptorEventListener
+     * @see #removeOnFileDescriptorEventListener
+     */
+    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+    public void addOnFileDescriptorEventListener(@NonNull FileDescriptor fd,
+            @OnFileDescriptorEventListener.Events int events,
+            @NonNull OnFileDescriptorEventListener listener) {
+        if (fd == null) {
+            throw new IllegalArgumentException("fd must not be null");
+        }
+        if (listener == null) {
+            throw new IllegalArgumentException("listener must not be null");
+        }
+
+        synchronized (mFileDescriptorRecordsLock) {
+            updateOnFileDescriptorEventListenerLocked(fd, events, listener);
+        }
+    }
+
+    /**
+     * Removes a file descriptor listener.
+     * <p>
+     * This method does nothing if no listener has been registered for the
+     * specified file descriptor.
+     * </p>
+     *
+     * @param fd The file descriptor whose listener will be unregistered.
+     *
+     * @see OnFileDescriptorEventListener
+     * @see #addOnFileDescriptorEventListener
+     */
+    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+    public void removeOnFileDescriptorEventListener(@NonNull FileDescriptor fd) {
+        if (fd == null) {
+            throw new IllegalArgumentException("fd must not be null");
+        }
+
+        synchronized (mFileDescriptorRecordsLock) {
+            updateOnFileDescriptorEventListenerLocked(fd, 0, null);
+        }
+    }
+
+    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
+    private void updateOnFileDescriptorEventListenerLocked(FileDescriptor fd, int events,
+            OnFileDescriptorEventListener listener) {
+        final int fdNum = fd.getInt$();
+
+        int index = -1;
+        FileDescriptorRecord record = null;
+        if (mFileDescriptorRecords != null) {
+            index = mFileDescriptorRecords.indexOfKey(fdNum);
+            if (index >= 0) {
+                record = mFileDescriptorRecords.valueAt(index);
+                if (record != null && record.mEvents == events) {
+                    return;
+                }
+            }
+        }
+
+        if (events != 0) {
+            events |= OnFileDescriptorEventListener.EVENT_ERROR;
+            if (record == null) {
+                if (mFileDescriptorRecords == null) {
+                    mFileDescriptorRecords = new SparseArray<FileDescriptorRecord>();
+                }
+                record = new FileDescriptorRecord(fd, events, listener);
+                mFileDescriptorRecords.put(fdNum, record);
+            } else {
+                record.mListener = listener;
+                record.mEvents = events;
+                record.mSeq += 1;
+            }
+            nativeSetFileDescriptorEvents(mPtr, fdNum, events);
+        } else if (record != null) {
+            record.mEvents = 0;
+            mFileDescriptorRecords.removeAt(index);
+            nativeSetFileDescriptorEvents(mPtr, fdNum, 0);
+        }
+    }
+
+    // Called from native code.
+    private int dispatchEvents(int fd, int events) {
+        // Get the file descriptor record and any state that might change.
+        final FileDescriptorRecord record;
+        final int oldWatchedEvents;
+        final OnFileDescriptorEventListener listener;
+        final int seq;
+        synchronized (mFileDescriptorRecordsLock) {
+            record = mFileDescriptorRecords.get(fd);
+            if (record == null) {
+                return 0; // spurious, no listener registered
+            }
+
+            oldWatchedEvents = record.mEvents;
+            events &= oldWatchedEvents; // filter events based on current watched set
+            if (events == 0) {
+                return oldWatchedEvents; // spurious, watched events changed
+            }
+
+            listener = record.mListener;
+            seq = record.mSeq;
+        }
+
+        // Invoke the listener outside of the lock.
+        int newWatchedEvents = listener.onFileDescriptorEvents(
+                record.mDescriptor, events);
+        if (newWatchedEvents != 0) {
+            newWatchedEvents |= OnFileDescriptorEventListener.EVENT_ERROR;
+        }
+
+        // Update the file descriptor record if the listener changed the set of
+        // events to watch and the listener itself hasn't been updated since.
+        if (newWatchedEvents != oldWatchedEvents) {
+            synchronized (mFileDescriptorRecordsLock) {
+                int index = mFileDescriptorRecords.indexOfKey(fd);
+                if (index >= 0 && mFileDescriptorRecords.valueAt(index) == record
+                        && record.mSeq == seq) {
+                    record.mEvents = newWatchedEvents;
+                    if (newWatchedEvents == 0) {
+                        mFileDescriptorRecords.removeAt(index);
+                    }
+                }
+            }
+        }
+
+        // Return the new set of events to watch for native code to take care of.
+        return newWatchedEvents;
+    }
+
+    /**
+     * Callback interface for discovering when a thread is going to block
+     * waiting for more messages.
+     */
+    public static interface IdleHandler {
+        /**
+         * Called when the message queue has run out of messages and will now
+         * wait for more.  Return true to keep your idle handler active, false
+         * to have it removed.  This may be called if there are still messages
+         * pending in the queue, but they are all scheduled to be dispatched
+         * after the current time.
+         */
+        boolean queueIdle();
+    }
+
+    /**
+     * A listener which is invoked when file descriptor related events occur.
+     */
+    public interface OnFileDescriptorEventListener {
+        /**
+         * File descriptor event: Indicates that the file descriptor is ready for input
+         * operations, such as reading.
+         * <p>
+         * The listener should read all available data from the file descriptor
+         * then return <code>true</code> to keep the listener active or <code>false</code>
+         * to remove the listener.
+         * </p><p>
+         * In the case of a socket, this event may be generated to indicate
+         * that there is at least one incoming connection that the listener
+         * should accept.
+         * </p><p>
+         * This event will only be generated if the {@link #EVENT_INPUT} event mask was
+         * specified when the listener was added.
+         * </p>
+         */
+        public static final int EVENT_INPUT = 1 << 0;
+
+        /**
+         * File descriptor event: Indicates that the file descriptor is ready for output
+         * operations, such as writing.
+         * <p>
+         * The listener should write as much data as it needs.  If it could not
+         * write everything at once, then it should return <code>true</code> to
+         * keep the listener active.  Otherwise, it should return <code>false</code>
+         * to remove the listener then re-register it later when it needs to write
+         * something else.
+         * </p><p>
+         * This event will only be generated if the {@link #EVENT_OUTPUT} event mask was
+         * specified when the listener was added.
+         * </p>
+         */
+        public static final int EVENT_OUTPUT = 1 << 1;
+
+        /**
+         * File descriptor event: Indicates that the file descriptor encountered a
+         * fatal error.
+         * <p>
+         * File descriptor errors can occur for various reasons.  One common error
+         * is when the remote peer of a socket or pipe closes its end of the connection.
+         * </p><p>
+         * This event may be generated at any time regardless of whether the
+         * {@link #EVENT_ERROR} event mask was specified when the listener was added.
+         * </p>
+         */
+        public static final int EVENT_ERROR = 1 << 2;
+
+        /** @hide */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(flag = true, prefix = { "EVENT_" }, value = {
+                EVENT_INPUT,
+                EVENT_OUTPUT,
+                EVENT_ERROR
+        })
+        public @interface Events {}
+
+        /**
+         * Called when a file descriptor receives events.
+         *
+         * @param fd The file descriptor.
+         * @param events The set of events that occurred: a combination of the
+         * {@link #EVENT_INPUT}, {@link #EVENT_OUTPUT}, and {@link #EVENT_ERROR} event masks.
+         * @return The new set of events to watch, or 0 to unregister the listener.
+         *
+         * @see #EVENT_INPUT
+         * @see #EVENT_OUTPUT
+         * @see #EVENT_ERROR
+         */
+        @Events int onFileDescriptorEvents(@NonNull FileDescriptor fd, @Events int events);
+    }
+
+    static final class FileDescriptorRecord {
+        public final FileDescriptor mDescriptor;
+        public int mEvents;
+        public OnFileDescriptorEventListener mListener;
+        public int mSeq;
+
+        public FileDescriptorRecord(FileDescriptor descriptor,
+                int events, OnFileDescriptorEventListener listener) {
+            mDescriptor = descriptor;
+            mEvents = events;
+            mListener = listener;
+        }
+    }
+}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 7926afe..f30a9f5 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -6367,6 +6367,33 @@
                 Settings.Global.DEVICE_DEMO_MODE, 0) > 0;
     }
 
+    private static final String CACHE_KEY_USER_SERIAL_NUMBER_PROPERTY =
+        PropertyInvalidatedCache.createPropertyName(
+            PropertyInvalidatedCache.MODULE_SYSTEM, "user_serial_number");
+
+    private final PropertyInvalidatedCache<Integer, Integer> mUserSerialNumberCache =
+            new PropertyInvalidatedCache<Integer, Integer>(
+                32, CACHE_KEY_USER_SERIAL_NUMBER_PROPERTY) {
+                @Override
+                public Integer recompute(Integer query) {
+                    try {
+                        return mService.getUserSerialNumber(query);
+                    } catch (RemoteException re) {
+                        throw re.rethrowFromSystemServer();
+                    }
+                }
+                @Override
+                public boolean bypass(Integer query) {
+                    return query <= 0;
+                }
+            };
+
+
+    /** @hide */
+    public static final void invalidateUserSerialNumberCache() {
+        PropertyInvalidatedCache.invalidateCache(CACHE_KEY_USER_SERIAL_NUMBER_PROPERTY);
+    }
+
     /**
      * Returns a serial number on this device for a given userId. User handles can be recycled
      * when deleting and creating users, but serial numbers are not reused until the device is wiped.
@@ -6376,6 +6403,14 @@
      */
     @UnsupportedAppUsage
     public int getUserSerialNumber(@UserIdInt int userId) {
+        if (android.multiuser.Flags.cacheUserSerialNumber()) {
+            // System user serial number is always 0, and it always exists.
+            // There is no need to call binder for that.
+            if (userId == UserHandle.USER_SYSTEM) {
+               return UserHandle.USER_SERIAL_SYSTEM;
+            }
+            return mUserSerialNumberCache.query(userId);
+        }
         try {
             return mService.getUserSerialNumber(userId);
         } catch (RemoteException re) {
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index 4b2d4eb..8af371c 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -184,16 +184,6 @@
     }
 
     /**
-     * Whether the keyboard vibration is enabled by default.
-     *
-     * @return {@code true} if the keyboard vibration is default enabled, {@code false} otherwise.
-     * @hide
-     */
-    public boolean isDefaultKeyboardVibrationEnabled() {
-        return getConfig().isDefaultKeyboardVibrationEnabled();
-    }
-
-    /**
      * Return the ID of this vibrator.
      *
      * @return A non-negative integer representing the id of the vibrator controlled by this
diff --git a/core/java/android/os/connectivity/CellularBatteryStats.java b/core/java/android/os/connectivity/CellularBatteryStats.java
index fc17002..1649ed5 100644
--- a/core/java/android/os/connectivity/CellularBatteryStats.java
+++ b/core/java/android/os/connectivity/CellularBatteryStats.java
@@ -15,11 +15,13 @@
  */
 package android.os.connectivity;
 
+import android.annotation.FlaggedApi;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.BatteryStats;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -35,6 +37,7 @@
  *
  * @hide
  */
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
 @SystemApi
 public final class CellularBatteryStats implements Parcelable {
 
@@ -83,11 +86,17 @@
                 }
             };
 
-    /** @hide **/
+    /**
+     * This constructor should only be used in tests.
+     * @hide
+     */
+    @FlaggedApi(
+            com.android.server.power.optimization.Flags.FLAG_STREAMLINED_CONNECTIVITY_BATTERY_STATS)
+    @TestApi
     public CellularBatteryStats(long loggingDurationMs, long kernelActiveTimeMs, long numPacketsTx,
             long numBytesTx, long numPacketsRx, long numBytesRx, long sleepTimeMs, long idleTimeMs,
-            long rxTimeMs, Long energyConsumedMaMs, long[] timeInRatMs,
-            long[] timeInRxSignalStrengthLevelMs, long[] txTimeMs,
+            long rxTimeMs, long energyConsumedMaMs, @NonNull long[] timeInRatMs,
+            @NonNull long[] timeInRxSignalStrengthLevelMs, @NonNull long[] txTimeMs,
             long monitoredRailChargeConsumedMaMs) {
 
         mLoggingDurationMs = loggingDurationMs;
@@ -270,7 +279,6 @@
      * @return The amount of time the phone spends in the {@code networkType} network type. The
      * unit is in microseconds.
      */
-    @NonNull
     @SuppressLint("MethodNameUnits")
     public long getTimeInRatMicros(@NetworkType int networkType) {
         if (networkType >= mTimeInRatMs.length) {
@@ -289,7 +297,6 @@
      * @return Amount of time phone spends in specific cellular rx signal strength levels
      * in microseconds. The index is signal strength bin.
      */
-    @NonNull
     @SuppressLint("MethodNameUnits")
     public long getTimeInRxSignalStrengthLevelMicros(
             @IntRange(from = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN,
@@ -315,10 +322,9 @@
      * <li> index 3 = 15dBm < tx_power < 20dBm. </li>
      * <li> index 4 = tx_power > 20dBm. </li>
      * </ul>
-     *
-     * @hide
      */
-    @NonNull
+    @FlaggedApi(
+            com.android.server.power.optimization.Flags.FLAG_STREAMLINED_CONNECTIVITY_BATTERY_STATS)
     public long getTxTimeMillis(
             @IntRange(from = ModemActivityInfo.TX_POWER_LEVEL_0,
                     to = ModemActivityInfo.TX_POWER_LEVEL_4) int level) {
diff --git a/core/java/android/os/connectivity/WifiBatteryStats.java b/core/java/android/os/connectivity/WifiBatteryStats.java
index 7e6ebcf..79e0be8 100644
--- a/core/java/android/os/connectivity/WifiBatteryStats.java
+++ b/core/java/android/os/connectivity/WifiBatteryStats.java
@@ -19,9 +19,11 @@
 import static android.os.BatteryStatsManager.NUM_WIFI_STATES;
 import static android.os.BatteryStatsManager.NUM_WIFI_SUPPL_STATES;
 
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -34,6 +36,7 @@
  * @hide
  */
 @SystemApi
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
 public final class WifiBatteryStats implements Parcelable {
     private final long mLoggingDurationMillis;
     private final long mKernelActiveTimeMillis;
@@ -150,7 +153,13 @@
                 mMonitoredRailChargeConsumedMaMillis);
     }
 
-    /** @hide **/
+    /**
+     * This constructor should only be used in tests.
+     * @hide
+     */
+    @FlaggedApi(
+            com.android.server.power.optimization.Flags.FLAG_STREAMLINED_CONNECTIVITY_BATTERY_STATS)
+    @TestApi
     public WifiBatteryStats(long loggingDurationMillis, long kernelActiveTimeMillis,
             long numPacketsTx, long numBytesTx, long numPacketsRx, long numBytesRx,
             long sleepTimeMillis, long scanTimeMillis, long idleTimeMillis, long rxTimeMillis,
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index 11b1b08..f026997 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -209,3 +209,18 @@
      description: "Tracing using Perfetto SDK."
      bug: "303199244"
 }
+
+flag {
+    name: "allow_consentless_bugreport_delegated_consent"
+    namespace: "crumpet"
+    description: "Allow privileged apps to call bugreport generation without enforcing user consent and delegate it to the calling app instead"
+    bug: "324046728"
+}
+
+flag {
+    name: "get_private_space_settings"
+    namespace: "profile_experiences"
+    description: "Guards a new Private Profile API in LauncherApps"
+    bug: "346294653"
+    is_exported: true
+}
diff --git a/core/java/android/os/vibrator/VibrationConfig.java b/core/java/android/os/vibrator/VibrationConfig.java
index 555a120..f6e73b3 100644
--- a/core/java/android/os/vibrator/VibrationConfig.java
+++ b/core/java/android/os/vibrator/VibrationConfig.java
@@ -68,9 +68,7 @@
     @VibrationIntensity
     private final int mDefaultRingVibrationIntensity;
 
-    private final boolean mDefaultKeyboardVibrationEnabled;
-
-    private final boolean mHasFixedKeyboardAmplitude;
+    private final boolean mKeyboardVibrationSettingsSupported;
 
     /** @hide */
     public VibrationConfig(@Nullable Resources resources) {
@@ -87,10 +85,8 @@
 
         mIgnoreVibrationsOnWirelessCharger = loadBoolean(resources,
                 com.android.internal.R.bool.config_ignoreVibrationsOnWirelessCharger, false);
-        mDefaultKeyboardVibrationEnabled = loadBoolean(resources,
-                com.android.internal.R.bool.config_defaultKeyboardVibrationEnabled, true);
-        mHasFixedKeyboardAmplitude = loadFloat(resources,
-                com.android.internal.R.dimen.config_keyboardHapticFeedbackFixedAmplitude, -1) > 0;
+        mKeyboardVibrationSettingsSupported = loadBoolean(resources,
+                com.android.internal.R.bool.config_keyboardVibrationSettingsSupported, false);
 
         mDefaultAlarmVibrationIntensity = loadDefaultIntensity(resources,
                 com.android.internal.R.integer.config_defaultAlarmVibrationIntensity);
@@ -194,19 +190,11 @@
     }
 
     /**
-     * Whether keyboard vibration settings is enabled by default.
+     * Whether the device support keyboard vibration settings.
      * @hide
      */
-    public boolean isDefaultKeyboardVibrationEnabled() {
-        return mDefaultKeyboardVibrationEnabled;
-    }
-
-    /**
-     * Whether the device has a fixed amplitude for keyboard.
-     * @hide
-     */
-    public boolean hasFixedKeyboardAmplitude() {
-        return mHasFixedKeyboardAmplitude;
+    public boolean isKeyboardVibrationSettingsSupported() {
+        return mKeyboardVibrationSettingsSupported;
     }
 
     /** Get the default vibration intensity for given usage. */
@@ -248,7 +236,7 @@
                 + ", mDefaultMediaIntensity=" + mDefaultMediaVibrationIntensity
                 + ", mDefaultNotificationIntensity=" + mDefaultNotificationVibrationIntensity
                 + ", mDefaultRingIntensity=" + mDefaultRingVibrationIntensity
-                + ", mDefaultKeyboardVibrationEnabled=" + mDefaultKeyboardVibrationEnabled
+                + ", mKeyboardVibrationSettingsSupported=" + mKeyboardVibrationSettingsSupported
                 + "}";
     }
 
diff --git a/core/java/android/os/vibrator/flags.aconfig b/core/java/android/os/vibrator/flags.aconfig
index eda755c..c73a422 100644
--- a/core/java/android/os/vibrator/flags.aconfig
+++ b/core/java/android/os/vibrator/flags.aconfig
@@ -31,3 +31,24 @@
     description: "Enables the adaptive haptics feature"
     bug: "305961689"
 }
+
+flag {
+    namespace: "haptics"
+    name: "cancel_by_appops"
+    description: "Cancels ongoing vibrations when the appops mode changes to disallow them"
+    bug: "230745615"
+    is_fixed_read_only: true
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
+    namespace: "haptics"
+    name: "vibration_xml_apis"
+    description: "Enabled System APIs for vibration effect XML parser and serializer"
+    bug: "347273158"
+    metadata {
+        purpose: PURPOSE_FEATURE
+    }
+}
diff --git a/core/java/android/os/vibrator/persistence/ParsedVibration.java b/core/java/android/os/vibrator/persistence/ParsedVibration.java
index a16d21e..1916269 100644
--- a/core/java/android/os/vibrator/persistence/ParsedVibration.java
+++ b/core/java/android/os/vibrator/persistence/ParsedVibration.java
@@ -16,73 +16,65 @@
 
 package android.os.vibrator.persistence;
 
+import static android.os.vibrator.Flags.FLAG_VIBRATION_XML_APIS;
+
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.os.VibrationEffect;
 import android.os.Vibrator;
 import android.os.VibratorInfo;
 
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.Collections;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 /**
- * The result of parsing a serialized vibration, which can be define by one or more
- * {@link VibrationEffect} and a resolution method.
+ * The result of parsing a serialized vibration.
+ *
+ * @see VibrationXmlParser
  *
  * @hide
  */
-@TestApi
-@SuppressLint("UnflaggedApi") // @TestApi without associated feature.
-public class ParsedVibration {
-    private final List<VibrationEffect> mEffects;
+@SystemApi
+@FlaggedApi(FLAG_VIBRATION_XML_APIS)
+public final class ParsedVibration {
+    private final ArrayList<VibrationEffect> mEffects;
 
     /** @hide */
+    @TestApi
     public ParsedVibration(@NonNull List<VibrationEffect> effects) {
-        mEffects = effects;
+        mEffects = new ArrayList<>(effects);
     }
 
     /** @hide */
     public ParsedVibration(@NonNull VibrationEffect effect) {
-        mEffects = List.of(effect);
+        mEffects = new ArrayList<>(1);
+        mEffects.add(effect);
     }
+
     /**
      * Returns the first parsed vibration supported by {@code vibrator}, or {@code null} if none of
      * the parsed vibrations are supported.
      *
      * @hide
      */
-    @TestApi
+    @SystemApi
+    @FlaggedApi(FLAG_VIBRATION_XML_APIS)
     @Nullable
     public VibrationEffect resolve(@NonNull Vibrator vibrator) {
         return resolve(vibrator.getInfo());
     }
 
     /**
-     * Returns the parsed vibrations for testing purposes.
-     *
-     * <p>Real callers should not use this method. Instead, they should resolve to a
-     * {@link VibrationEffect} via {@link #resolve(Vibrator)}.
-     *
-     * @hide
-     */
-    @TestApi
-    @VisibleForTesting
-    @NonNull
-    public List<VibrationEffect> getVibrationEffects() {
-        return Collections.unmodifiableList(mEffects);
-    }
-
-    /**
      * Same as {@link #resolve(Vibrator)}, but uses {@link VibratorInfo} instead for resolving.
      *
      * @hide
      */
     @Nullable
-    public final VibrationEffect resolve(@NonNull VibratorInfo info) {
+    public VibrationEffect resolve(@NonNull VibratorInfo info) {
         for (int i = 0; i < mEffects.size(); i++) {
             VibrationEffect effect = mEffects.get(i);
             if (info.areVibrationFeaturesSupported(effect)) {
@@ -91,4 +83,28 @@
         }
         return null;
     }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof ParsedVibration)) {
+            return false;
+        }
+        ParsedVibration other = (ParsedVibration) o;
+        return mEffects.equals(other.mEffects);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(mEffects);
+    }
+
+    @Override
+    public String toString() {
+        return "ParsedVibration{"
+                + "effects=" + mEffects
+                + '}';
+    }
 }
diff --git a/core/java/android/os/vibrator/persistence/VibrationXmlParser.java b/core/java/android/os/vibrator/persistence/VibrationXmlParser.java
index 7202d9a..7d9624c 100644
--- a/core/java/android/os/vibrator/persistence/VibrationXmlParser.java
+++ b/core/java/android/os/vibrator/persistence/VibrationXmlParser.java
@@ -16,13 +16,15 @@
 
 package android.os.vibrator.persistence;
 
+import static android.os.vibrator.Flags.FLAG_VIBRATION_XML_APIS;
+
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.os.VibrationEffect;
-import android.util.Slog;
 import android.util.Xml;
 
 import com.android.internal.vibrator.persistence.VibrationEffectXmlParser;
@@ -36,9 +38,12 @@
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.Reader;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -116,10 +121,9 @@
  *
  * @hide
  */
-@TestApi
-@SuppressLint("UnflaggedApi") // @TestApi without associated feature.
+@SystemApi
+@FlaggedApi(FLAG_VIBRATION_XML_APIS)
 public final class VibrationXmlParser {
-    private static final String TAG = "VibrationXmlParser";
 
     /**
      * The MIME type for a xml holding a vibration.
@@ -168,55 +172,12 @@
     }
 
     /**
-     * Parses XML content from given input stream into a {@link VibrationEffect}.
-     *
-     * <p>This method parses an XML content that contains a single, complete {@link VibrationEffect}
-     * serialization. As such, the root tag must be a "vibration" tag.
-     *
-     * <p>This parser fails silently and returns {@code null} if the content of the input stream
-     * does not follow the schema or has unsupported values.
-     *
-     * @return the {@link VibrationEffect} if parsed successfully, {@code null} otherwise.
-     * @throws IOException error reading from given {@link Reader}
-     *
-     * @hide
-     */
-    @TestApi
-    @Nullable
-    public static VibrationEffect parseVibrationEffect(@NonNull Reader reader) throws IOException {
-        return parseVibrationEffect(reader, /* flags= */ 0);
-    }
-
-    /**
-     * Parses XML content from given input stream into a {@link VibrationEffect}.
-     *
-     * <p>This method parses an XML content that contains a single, complete {@link VibrationEffect}
-     * serialization. As such, the root tag must be a "vibration" tag.
-     *
-     * <p>Same as {@link #parseVibrationEffect(Reader)}, with extra flags to control the parsing
-     * behavior.
-     *
-     * @hide
-     */
-    @Nullable
-    public static VibrationEffect parseVibrationEffect(@NonNull Reader reader, @Flags int flags)
-            throws IOException {
-        try {
-            return parseDocumentInternal(
-                    reader, flags, VibrationXmlParser::parseVibrationEffectInternal);
-        } catch (XmlParserException | XmlPullParserException e) {
-            Slog.w(TAG, "Error parsing vibration XML", e);
-            return null;
-        }
-    }
-
-    /**
      * Parses XML content from given input stream into a {@link ParsedVibration}.
      *
-     * <p>It supports both the "vibration" and "vibration-select" root tags.
+     * <p>It supports both the "vibration-effect" and "vibration-select" root tags.
      * <ul>
-     *     <li>If "vibration" is the root tag, the serialization provided through {@code reader}
-     *         should contain a valid serialization for a single vibration.
+     *     <li>If "vibration-effect" is the root tag, the serialization provided should contain a
+     *         valid serialization for a single vibration.
      *     <li>If "vibration-select" is the root tag, the serialization may contain one or more
      *         valid vibration serializations.
      * </ul>
@@ -225,36 +186,93 @@
      * vibration(s), and the caller can get a concrete {@link VibrationEffect} by resolving this
      * result to a specific vibrator.
      *
-     * <p>This parser fails silently and returns {@code null} if the content of the input does not
-     * follow the schema or has unsupported values.
+     * <p>This parser fails with an exception if the content of the input stream does not follow the
+     * schema or has unsupported values.
      *
      * @return a {@link ParsedVibration}
-     * @throws IOException error reading from given {@link Reader}
+     * @throws IOException error reading from given {@link InputStream} or parsing the content.
      *
      * @hide
      */
-    @TestApi
-    @Nullable
+    @SystemApi
+    @FlaggedApi(FLAG_VIBRATION_XML_APIS)
+    @NonNull
+    public static ParsedVibration parse(@NonNull InputStream inputStream) throws IOException {
+        return parseDocument(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
+    }
+
+    /**
+     * Parses XML content from given input stream into a single {@link VibrationEffect}.
+     *
+     * <p>This method parses an XML content that contains a single, complete {@link VibrationEffect}
+     * serialization. As such, the root tag must be a "vibration-effect" tag.
+     *
+     * <p>This parser fails with an exception if the content of the input stream does not follow the
+     * schema or has unsupported values.
+     *
+     * @return the parsed {@link VibrationEffect}
+     * @throws IOException error reading from given {@link InputStream} or parsing the content.
+     *
+     * @hide
+     */
+    @SystemApi
+    @FlaggedApi(FLAG_VIBRATION_XML_APIS)
+    @NonNull
+    public static VibrationEffect parseVibrationEffect(@NonNull InputStream inputStream)
+            throws IOException {
+        return parseVibrationEffect(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
+    }
+
+    /**
+     * Parses XML content from given {@link Reader} into a {@link VibrationEffect}.
+     *
+     * <p>Same as {@link #parseVibrationEffect(InputStream)}, but with a {@link Reader}.
+     *
+     * @hide
+     */
+    @NonNull
+    public static VibrationEffect parseVibrationEffect(@NonNull Reader reader) throws IOException {
+        return parseVibrationEffect(reader, /* flags= */ 0);
+    }
+
+    /**
+     * Parses XML content from given {@link Reader} into a {@link VibrationEffect}.
+     *
+     * <p>Same as {@link #parseVibrationEffect(Reader)}, with extra flags to control the parsing
+     * behavior.
+     *
+     * @hide
+     */
+    @NonNull
+    public static VibrationEffect parseVibrationEffect(@NonNull Reader reader, @Flags int flags)
+            throws IOException {
+        return parseDocumentInternal(reader, flags,
+                VibrationXmlParser::parseVibrationEffectInternal);
+    }
+
+    /**
+     * Parses XML content from given {@link Reader} into a {@link ParsedVibration}.
+     *
+     * <p>Same as {@link #parse(InputStream)}, but with a {@link Reader}.
+     *
+     * @hide
+     */
+    @NonNull
     public static ParsedVibration parseDocument(@NonNull Reader reader) throws IOException {
         return parseDocument(reader, /* flags= */ 0);
     }
 
     /**
-     * Parses XML content from given input stream into a {@link ParsedVibration}.
+     * Parses XML content from given {@link Reader} into a {@link ParsedVibration}.
      *
      * <p>Same as {@link #parseDocument(Reader)}, with extra flags to control the parsing behavior.
      *
      * @hide
      */
-    @Nullable
+    @NonNull
     public static ParsedVibration parseDocument(@NonNull Reader reader, @Flags int flags)
             throws IOException {
-        try {
-            return parseDocumentInternal(reader, flags, VibrationXmlParser::parseElementInternal);
-        } catch (XmlParserException | XmlPullParserException e) {
-            Slog.w(TAG, "Error parsing vibration/vibration-select XML", e);
-            return null;
-        }
+        return parseDocumentInternal(reader, flags, VibrationXmlParser::parseElementInternal);
     }
 
     /**
@@ -262,7 +280,7 @@
      * {@link ParsedVibration}.
      *
      * <p>Same as {@link #parseDocument(Reader, int)}, but, instead of parsing the full XML content,
-     * it takes a parser that points to either a <vibration-effect> or a <vibration-select> start
+     * it takes a parser that points to either a "vibration-effect" or a "vibration-select" start
      * tag. No other parser position, including start of document, is considered valid.
      *
      * <p>This method parses until an end "vibration-effect" or "vibration-select" tag (depending
@@ -270,37 +288,22 @@
      * will point to the end tag.
      *
      * @throws IOException error parsing from given {@link TypedXmlPullParser}.
-     * @throws VibrationXmlParserException if the XML tag cannot be parsed into a
-     *      {@link ParsedVibration}. The given {@code parser} might be pointing to a child XML tag
-     *      that caused the parser failure.
+     *         The given {@code parser} might be pointing to a child XML tag that caused the parser
+     *         failure.
      *
      * @hide
      */
     @NonNull
     public static ParsedVibration parseElement(@NonNull TypedXmlPullParser parser, @Flags int flags)
-            throws IOException, VibrationXmlParserException {
+            throws IOException {
         try {
             return parseElementInternal(parser, flags);
         } catch (XmlParserException e) {
-            throw new VibrationXmlParserException("Error parsing vibration-select.", e);
+            throw new ParseFailedException(e);
         }
     }
 
-    /**
-     * Represents an error while parsing a vibration XML input.
-     *
-     * @hide
-     */
-    public static final class VibrationXmlParserException extends Exception {
-        private VibrationXmlParserException(String message, Throwable cause) {
-            super(message, cause);
-        }
-
-        private VibrationXmlParserException(String message) {
-            super(message);
-        }
-    }
-
+    @NonNull
     private static ParsedVibration parseElementInternal(
                 @NonNull TypedXmlPullParser parser, @Flags int flags)
                         throws IOException, XmlParserException {
@@ -313,11 +316,12 @@
             case XmlConstants.TAG_VIBRATION_SELECT:
                 return parseVibrationSelectInternal(parser, flags);
             default:
-                throw new XmlParserException(
-                        "Unexpected tag name when parsing element: " + tagName);
+                throw new ParseFailedException(
+                        "Unexpected tag " + tagName + " when parsing a vibration");
         }
     }
 
+    @NonNull
     private static ParsedVibration parseVibrationSelectInternal(
             @NonNull TypedXmlPullParser parser, @Flags int flags)
                     throws IOException, XmlParserException {
@@ -332,7 +336,7 @@
         return new ParsedVibration(effects);
     }
 
-    /** Parses a single XML element for "vibration" tag into a {@link VibrationEffect}. */
+    @NonNull
     private static VibrationEffect parseVibrationEffectInternal(
             @NonNull TypedXmlPullParser parser, @Flags int flags)
                     throws IOException, XmlParserException {
@@ -347,32 +351,60 @@
      * This method parses a whole XML document (provided through a {@link Reader}). The root tag is
      * parsed as per a provided {@link ElementParser}.
      */
+    @NonNull
     private static <T> T parseDocumentInternal(
             @NonNull Reader reader, @Flags int flags, ElementParser<T> parseLogic)
-                    throws IOException, XmlParserException, XmlPullParserException {
-        TypedXmlPullParser parser = Xml.newFastPullParser();
-        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-        parser.setInput(reader);
+            throws IOException {
+        try {
+            TypedXmlPullParser parser = Xml.newFastPullParser();
+            parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
+            parser.setInput(reader);
 
-        // Ensure XML starts with a document start tag.
-        XmlReader.readDocumentStart(parser);
+            // Ensure XML starts with a document start tag.
+            XmlReader.readDocumentStart(parser);
 
-        // Parse root tag.
-        T result = parseLogic.parse(parser, flags);
+            // Parse root tag.
+            T result = parseLogic.parse(parser, flags);
 
-        // Ensure XML ends after root tag is consumed.
-        XmlReader.readDocumentEndTag(parser);
+            // Ensure XML ends after root tag is consumed.
+            XmlReader.readDocumentEndTag(parser);
 
-        return result;
+            return result;
+        } catch (XmlPullParserException e) {
+            throw new ParseFailedException("Error initializing XMLPullParser", e);
+        } catch (XmlParserException e) {
+            throw new ParseFailedException(e);
+        }
     }
 
     /** Encapsulate a logic to parse an XML element from an open parser. */
     private interface ElementParser<T> {
         /** Parses a single XML element starting from the current position of the {@code parser}. */
+        @NonNull
         T parse(@NonNull TypedXmlPullParser parser, @Flags int flags)
                 throws IOException, XmlParserException;
     }
 
+    /**
+     * Represents an error while parsing a vibration XML input.
+     *
+     * @hide
+     */
+    @TestApi
+    public static final class ParseFailedException extends IOException {
+        private ParseFailedException(String message) {
+            super(message);
+        }
+
+        private ParseFailedException(XmlParserException parserException) {
+            this(parserException.getMessage(), parserException);
+        }
+
+        private ParseFailedException(String message, Throwable cause) {
+            super(message, cause);
+        }
+    }
+
     private VibrationXmlParser() {
     }
 }
diff --git a/core/java/android/os/vibrator/persistence/VibrationXmlSerializer.java b/core/java/android/os/vibrator/persistence/VibrationXmlSerializer.java
index 2065d5d..a26c6f4 100644
--- a/core/java/android/os/vibrator/persistence/VibrationXmlSerializer.java
+++ b/core/java/android/os/vibrator/persistence/VibrationXmlSerializer.java
@@ -18,9 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.SuppressLint;
 import android.annotation.TestApi;
-import android.os.CombinedVibration;
 import android.os.VibrationEffect;
 import android.util.Xml;
 
@@ -37,14 +35,13 @@
 import java.lang.annotation.RetentionPolicy;
 
 /**
- * Serializes {@link CombinedVibration} and {@link VibrationEffect} instances to XML.
+ * Serializes {@link VibrationEffect} instances to XML.
  *
  * <p>This uses the same schema expected by the {@link VibrationXmlParser}.
  *
  * @hide
  */
 @TestApi
-@SuppressLint("UnflaggedApi") // @TestApi without associated feature.
 public final class VibrationXmlSerializer {
 
     /**
@@ -80,20 +77,19 @@
             "http://xmlpull.org/v1/doc/features.html#indent-output";
 
     /**
-     * Serializes a {@link VibrationEffect} to XML and writes output to given {@link Writer}.
+     * Serializes a {@link VibrationEffect} to XML and writes output to given {@link Writer} using
+     * UTF-8 encoding.
      *
-     * <p>This method will only write into the {@link Writer} if the effect can successfully
-     * be represented by the XML serialization. It will throw an exception otherwise.
+     * <p>This method will only write to the stream if the effect can successfully be represented by
+     * the XML serialization. It will throw an exception otherwise.
      *
-     * @throws SerializationFailedException serialization of input effect failed, no data was
-     *                                      written into given {@link Writer}.
-     * @throws IOException error writing to given {@link Writer}.
+     * @throws IOException serialization of input effect failed or error writing to output stream.
      *
      * @hide
      */
     @TestApi
     public static void serialize(@NonNull VibrationEffect effect, @NonNull Writer writer)
-            throws SerializationFailedException, IOException {
+            throws IOException {
         serialize(effect, writer, /* flags= */ 0);
     }
 
@@ -106,7 +102,7 @@
      * @hide
      */
     public static void serialize(@NonNull VibrationEffect effect, @NonNull Writer writer,
-            @Flags int flags) throws SerializationFailedException, IOException {
+            @Flags int flags) throws IOException {
         // Serialize effect first to fail early.
         XmlSerializedVibration<VibrationEffect> serializedVibration =
                 toSerializedVibration(effect, flags);
@@ -138,17 +134,16 @@
     }
 
     /**
-     * Exception thrown when a {@link VibrationEffect} instance serialization fails.
+     * Exception thrown when a {@link VibrationEffect} serialization fails.
      *
      * <p>The serialization can fail if a given vibration cannot be represented using the public
-     * format, or if it uses hidden APIs that are not supported for serialization (e.g.
-     * {@link VibrationEffect.WaveformBuilder}).
+     * format, or if it uses a non-public representation that is not supported for serialization.
      *
      * @hide
      */
     @TestApi
-    public static final class SerializationFailedException extends RuntimeException {
-        SerializationFailedException(VibrationEffect effect, Throwable cause) {
+    public static final class SerializationFailedException extends IOException {
+        private SerializationFailedException(VibrationEffect effect, Throwable cause) {
             super("Serialization failed for vibration effect " + effect, cause);
         }
     }
diff --git a/core/java/android/permission/PermissionUsageHelper.java b/core/java/android/permission/PermissionUsageHelper.java
index 141ffc9..a698b18 100644
--- a/core/java/android/permission/PermissionUsageHelper.java
+++ b/core/java/android/permission/PermissionUsageHelper.java
@@ -374,20 +374,22 @@
     public @NonNull List<PermissionGroupUsage> getOpUsageDataForAllDevices(
             boolean includeMicrophoneUsage) {
         List<PermissionGroupUsage> allUsages = new ArrayList<>();
-        List<VirtualDevice> virtualDevices = mVirtualDeviceManager.getVirtualDevices();
-        ArraySet<String> persistentDeviceIds = new ArraySet<>();
 
-        for (int num = 0; num < virtualDevices.size(); num++) {
-            persistentDeviceIds.add(virtualDevices.get(num).getPersistentDeviceId());
+        if (mVirtualDeviceManager != null) {
+            List<VirtualDevice> virtualDevices = mVirtualDeviceManager.getVirtualDevices();
+            ArraySet<String> persistentDeviceIds = new ArraySet<>();
+
+            for (int num = 0; num < virtualDevices.size(); num++) {
+                persistentDeviceIds.add(virtualDevices.get(num).getPersistentDeviceId());
+            }
+            persistentDeviceIds.add(VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT);
+
+            for (int index = 0; index < persistentDeviceIds.size(); index++) {
+                allUsages.addAll(
+                        getOpUsageDataByDevice(includeMicrophoneUsage,
+                                persistentDeviceIds.valueAt(index)));
+            }
         }
-        persistentDeviceIds.add(VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT);
-
-        for (int index = 0; index < persistentDeviceIds.size(); index++) {
-            allUsages.addAll(
-                    getOpUsageDataByDevice(includeMicrophoneUsage,
-                            persistentDeviceIds.valueAt(index)));
-        }
-
         return allUsages;
     }
 
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index e029e52..5ef597d 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -213,3 +213,11 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    name: "location_bypass_privacy_dashboard_enabled"
+    is_exported: true
+    namespace: "permissions"
+    description: "Show access entry of location bypass permission in the Privacy Dashboard"
+    bug: "325536053"
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d91508f..2562c8e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1403,6 +1403,19 @@
             "android.settings.QUICK_LAUNCH_SETTINGS";
 
     /**
+     * Activity Action: Showing settings to manage adaptive notifications.
+     * <p>
+     * Input: Nothing.
+     * <p>
+     * Output: Nothing.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_MANAGE_ADAPTIVE_NOTIFICATIONS =
+            "android.settings.MANAGE_ADAPTIVE_NOTIFICATIONS";
+
+    /**
      * Activity Action: Show settings to manage installed applications.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you
@@ -6165,6 +6178,15 @@
         public static final String POINTER_FILL_STYLE = "pointer_fill_style";
 
         /**
+         * Pointer stroke style, specified by
+         * {@link android.view.PointerIcon.PointerIconVectorStyleStroke} constants.
+         *
+         * @hide
+         */
+        @Readable
+        public static final String POINTER_STROKE_STYLE = "pointer_stroke_style";
+
+        /**
          * Whether lock-to-app will be triggered by long-press on recents.
          * @hide
          */
@@ -6367,6 +6389,7 @@
             PRIVATE_SETTINGS.add(SIP_ASK_ME_EACH_TIME);
             PRIVATE_SETTINGS.add(POINTER_SPEED);
             PRIVATE_SETTINGS.add(POINTER_FILL_STYLE);
+            PRIVATE_SETTINGS.add(POINTER_STROKE_STYLE);
             PRIVATE_SETTINGS.add(POINTER_SCALE);
             PRIVATE_SETTINGS.add(LOCK_TO_APP_ENABLED);
             PRIVATE_SETTINGS.add(EGG_MODE);
@@ -11046,6 +11069,12 @@
         public static final String BIOMETRIC_APP_ENABLED = "biometric_app_enabled";
 
         /**
+         * Whether or not mandatory biometrics is enabled.
+         * @hide
+         */
+        public static final String MANDATORY_BIOMETRICS = "mandatory_biometrics";
+
+        /**
          * Whether or not active unlock triggers on wake.
          * @hide
          */
@@ -11066,6 +11095,13 @@
                 "active_unlock_on_biometric_fail";
 
         /**
+         * Whether or not active unlock triggers on legacy unlock intents.
+         * @hide
+         */
+        public static final String ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY =
+                "active_unlock_on_unlock_intent_legacy";
+
+        /**
          * If active unlock triggers on biometric failures, include the following error codes
          * as a biometric failure. See {@link android.hardware.biometrics.BiometricFaceConstants}.
          * Error codes should be separated by a pipe. For example: "1|4|5". If active unlock
@@ -12288,6 +12324,18 @@
                 "accessibility_force_invert_color_enabled";
 
         /**
+         * Whether to enable mouse keys for Physical Keyboard accessibility.
+         *
+         * If set to true, key presses (of the mouse keys) on
+         * physical keyboard will control mouse pointer on the display.
+         *
+         * @hide
+         */
+        @Readable
+        public static final String ACCESSIBILITY_MOUSE_KEYS_ENABLED =
+                "accessibility_mouse_keys_enabled";
+
+        /**
          * Whether the Adaptive connectivity option is enabled.
          *
          * @hide
@@ -13370,7 +13418,19 @@
                 = "enable_freeform_support";
 
         /**
-         * Whether to enable experimental desktop mode on secondary displays.
+         * Whether to override the availability of the desktop mode on the main display of the
+         * device. If on, users can make move an app to the desktop, allowing a freeform windowing
+         * experience.
+         * @hide
+         */
+        @Readable
+        public static final String DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES =
+                "override_desktop_mode_features";
+
+        /**
+         * Whether to enable the legacy freeform support on secondary displays. If enabled, the
+         * SECONDARY_HOME of the launcher is started on any secondary display, allowing for a
+         * desktop experience.
          * @hide
          */
         @Readable
@@ -20081,7 +20141,7 @@
              * (0 = false, 1 = true)
              * @hide
              */
-            @Readable(maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+            @Readable
             public static final String REDUCE_MOTION = "reduce_motion";
 
             /**
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 88bd87e..d019bad 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -4940,7 +4940,7 @@
          *
          * @hide
          */
-        public static final String COLUMN_IS_NTN = "is_ntn";
+        public static final String COLUMN_IS_ONLY_NTN = "is_only_ntn";
 
         /**
          * TelephonyProvider column name for transferred status
@@ -4976,6 +4976,15 @@
         public static final String COLUMN_SATELLITE_ENTITLEMENT_PLMNS =
                 "satellite_entitlement_plmns";
 
+        /**
+         * TelephonyProvider column name to indicate the satellite ESOS supported. The value of this
+         * column is set based on {@link CarrierConfigManager#KEY_SATELLITE_ESOS_SUPPORTED_BOOL}.
+         * By default, it's disabled.
+         *
+         * @hide
+         */
+        public static final String COLUMN_SATELLITE_ESOS_SUPPORTED = "satellite_esos_supported";
+
         /** All columns in {@link SimInfo} table. */
         private static final List<String> ALL_COLUMNS = List.of(
                 COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID,
@@ -5047,11 +5056,12 @@
                 COLUMN_USER_HANDLE,
                 COLUMN_SATELLITE_ENABLED,
                 COLUMN_SATELLITE_ATTACH_ENABLED_FOR_CARRIER,
-                COLUMN_IS_NTN,
+                COLUMN_IS_ONLY_NTN,
                 COLUMN_SERVICE_CAPABILITIES,
                 COLUMN_TRANSFER_STATUS,
                 COLUMN_SATELLITE_ENTITLEMENT_STATUS,
-                COLUMN_SATELLITE_ENTITLEMENT_PLMNS
+                COLUMN_SATELLITE_ENTITLEMENT_PLMNS,
+                COLUMN_SATELLITE_ESOS_SUPPORTED
         );
 
         /**
diff --git a/core/java/android/service/chooser/flags.aconfig b/core/java/android/service/chooser/flags.aconfig
index d6425c3..82c1613 100644
--- a/core/java/android/service/chooser/flags.aconfig
+++ b/core/java/android/service/chooser/flags.aconfig
@@ -2,14 +2,6 @@
 container: "system"
 
 flag {
-  name: "chooser_album_text"
-  is_exported: true
-  namespace: "intentresolver"
-  description: "Flag controlling the album text subtype hint for sharesheet"
-  bug: "323380224"
-}
-
-flag {
     name: "enable_sharesheet_metadata_extra"
     is_exported: true
     namespace: "intentresolver"
@@ -32,3 +24,14 @@
   description: "Provides additional callbacks with information about user actions in ChooserResult"
   bug: "263474465"
 }
+
+flag {
+  name: "fix_resolver_memory_leak"
+  is_exported: true
+  namespace: "intentresolver"
+  description: "ResolverActivity memory leak (through the AppPredictor callback) fix"
+  bug: "346671041"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
diff --git a/core/java/android/service/dreams/DreamOverlayConnectionHandler.java b/core/java/android/service/dreams/DreamOverlayConnectionHandler.java
index 85a13c7..bc03400 100644
--- a/core/java/android/service/dreams/DreamOverlayConnectionHandler.java
+++ b/core/java/android/service/dreams/DreamOverlayConnectionHandler.java
@@ -27,7 +27,6 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ObservableServiceConnection;
-import com.android.internal.util.PersistentServiceConnection;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -48,22 +47,20 @@
     private static final int MSG_OVERLAY_CLIENT_READY = 3;
 
     private final Handler mHandler;
-    private final PersistentServiceConnection<IDreamOverlay> mConnection;
+    private final ObservableServiceConnection<IDreamOverlay> mConnection;
     // Retrieved Client
     private IDreamOverlayClient mClient;
     // A list of pending requests to execute on the overlay.
     private final List<Consumer<IDreamOverlayClient>> mConsumers = new ArrayList<>();
     private final OverlayConnectionCallback mCallback;
+    private final Runnable mOnDisconnected;
 
     DreamOverlayConnectionHandler(
             Context context,
             Looper looper,
             Intent serviceIntent,
-            int minConnectionDurationMs,
-            int maxReconnectAttempts,
-            int baseReconnectDelayMs) {
-        this(context, looper, serviceIntent, minConnectionDurationMs, maxReconnectAttempts,
-                baseReconnectDelayMs, new Injector());
+            Runnable onDisconnected) {
+        this(context, looper, serviceIntent, onDisconnected, new Injector());
     }
 
     @VisibleForTesting
@@ -71,20 +68,15 @@
             Context context,
             Looper looper,
             Intent serviceIntent,
-            int minConnectionDurationMs,
-            int maxReconnectAttempts,
-            int baseReconnectDelayMs,
+            Runnable onDisconnected,
             Injector injector) {
         mCallback = new OverlayConnectionCallback();
         mHandler = new Handler(looper, new OverlayHandlerCallback());
+        mOnDisconnected = onDisconnected;
         mConnection = injector.buildConnection(
                 context,
                 mHandler,
-                serviceIntent,
-                minConnectionDurationMs,
-                maxReconnectAttempts,
-                baseReconnectDelayMs
-        );
+                serviceIntent);
     }
 
     /**
@@ -201,10 +193,14 @@
         @Override
         public void onDisconnected(ObservableServiceConnection<IDreamOverlay> connection,
                 int reason) {
+            Log.i(TAG, "Dream overlay disconnected, reason: " + reason);
             mClient = null;
             // Cancel any pending messages about the overlay being ready, since it is no
             // longer ready.
             mHandler.removeMessages(MSG_OVERLAY_CLIENT_READY);
+            if (mOnDisconnected != null) {
+                mOnDisconnected.run();
+            }
         }
     }
 
@@ -217,25 +213,18 @@
          * Returns milliseconds since boot, not counting time spent in deep sleep. Can be overridden
          * in tests with a fake clock.
          */
-        public PersistentServiceConnection<IDreamOverlay> buildConnection(
+        public ObservableServiceConnection<IDreamOverlay> buildConnection(
                 Context context,
                 Handler handler,
-                Intent serviceIntent,
-                int minConnectionDurationMs,
-                int maxReconnectAttempts,
-                int baseReconnectDelayMs) {
+                Intent serviceIntent) {
             final Executor executor = handler::post;
             final int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
-            return new PersistentServiceConnection<>(
+            return new ObservableServiceConnection<>(
                     context,
                     executor,
-                    handler,
                     IDreamOverlay.Stub::asInterface,
                     serviceIntent,
-                    flags,
-                    minConnectionDurationMs,
-                    maxReconnectAttempts,
-                    baseReconnectDelayMs
+                    flags
             );
         }
     }
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index a769643..6b0d301 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -19,6 +19,7 @@
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.service.dreams.Flags.dreamHandlesConfirmKeys;
 import static android.service.dreams.Flags.dreamHandlesBeingObscured;
+import static android.service.dreams.Flags.startAndStopDozingInBackground;
 
 import android.annotation.FlaggedApi;
 import android.annotation.IdRes;
@@ -182,6 +183,7 @@
 
     /**
      * The name of the dream manager service.
+     *
      * @hide
      */
     public static final String DREAM_SERVICE = "dreams";
@@ -222,12 +224,14 @@
 
     /**
      * Dream category for Low Light Dream
+     *
      * @hide
      */
     public static final int DREAM_CATEGORY_LOW_LIGHT = 1 << 0;
 
     /**
      * Dream category for Home Panel Dream
+     *
      * @hide
      */
     public static final int DREAM_CATEGORY_HOME_PANEL = 1 << 1;
@@ -295,7 +299,8 @@
         void init(Context context);
 
         /** Creates and returns the dream overlay connection */
-        DreamOverlayConnectionHandler createOverlayConnection(ComponentName overlayComponent);
+        DreamOverlayConnectionHandler createOverlayConnection(ComponentName overlayComponent,
+                Runnable onDisconnected);
 
         /** Returns the {@link DreamActivity} component */
         ComponentName getDreamActivityComponent();
@@ -333,16 +338,15 @@
 
         @Override
         public DreamOverlayConnectionHandler createOverlayConnection(
-                ComponentName overlayComponent) {
+                ComponentName overlayComponent,
+                Runnable onDisconnected) {
             final Resources resources = mContext.getResources();
 
             return new DreamOverlayConnectionHandler(
                     /* context= */ mContext,
                     Looper.getMainLooper(),
                     new Intent().setComponent(overlayComponent),
-                    resources.getInteger(R.integer.config_minDreamOverlayDurationMs),
-                    resources.getInteger(R.integer.config_dreamOverlayMaxReconnectAttempts),
-                    resources.getInteger(R.integer.config_dreamOverlayReconnectTimeoutMs));
+                    onDisconnected);
         }
 
         @Override
@@ -920,9 +924,16 @@
 
         if (mDozing) {
             try {
-                mDreamManager.startDozing(
+                if (startAndStopDozingInBackground()) {
+                    mDreamManager.startDozingOneway(
                         mDreamToken, mDozeScreenState, mDozeScreenStateReason,
                         mDozeScreenBrightness);
+                } else {
+                    mDreamManager.startDozing(
+                            mDreamToken, mDozeScreenState, mDozeScreenStateReason,
+                            mDozeScreenBrightness);
+                }
+
             } catch (RemoteException ex) {
                 // system server died
             }
@@ -1176,7 +1187,8 @@
 
         // Connect to the overlay service if present.
         if (!mWindowless && overlayComponent != null) {
-            mOverlayConnection = mInjector.createOverlayConnection(overlayComponent);
+            mOverlayConnection = mInjector.createOverlayConnection(overlayComponent,
+                    this::finish);
 
             if (!mOverlayConnection.bind()) {
                 // Binding failed.
@@ -1246,7 +1258,11 @@
         try {
             // finishSelf will unbind the dream controller from the dream service. This will
             // trigger DreamService.this.onDestroy and DreamService.this will die.
-            mDreamManager.finishSelf(mDreamToken, true /*immediate*/);
+            if (startAndStopDozingInBackground()) {
+                mDreamManager.finishSelfOneway(mDreamToken, true /*immediate*/);
+            } else {
+                mDreamManager.finishSelf(mDreamToken, true /*immediate*/);
+            }
         } catch (RemoteException ex) {
             // system server died
         }
@@ -1389,7 +1405,8 @@
                         convertToComponentName(
                                 rawMetadata.getString(
                                         com.android.internal.R.styleable.Dream_settingsActivity),
-                                serviceInfo),
+                                serviceInfo,
+                                packageManager),
                         rawMetadata.getDrawable(
                                 com.android.internal.R.styleable.Dream_previewImage),
                         rawMetadata.getBoolean(R.styleable.Dream_showClockAndComplications,
@@ -1404,26 +1421,38 @@
     }
 
     @Nullable
-    private static ComponentName convertToComponentName(@Nullable String flattenedString,
-            ServiceInfo serviceInfo) {
+    private static ComponentName convertToComponentName(
+            @Nullable String flattenedString,
+            ServiceInfo serviceInfo,
+            PackageManager packageManager) {
         if (flattenedString == null) {
             return null;
         }
 
-        if (!flattenedString.contains("/")) {
-            return new ComponentName(serviceInfo.packageName, flattenedString);
+        final ComponentName cn =
+                flattenedString.contains("/")
+                        ? ComponentName.unflattenFromString(flattenedString)
+                        : new ComponentName(serviceInfo.packageName, flattenedString);
+
+        if (cn == null) {
+            return null;
         }
 
         // Ensure that the component is from the same package as the dream service. If not,
         // treat the component as invalid and return null instead.
-        final ComponentName cn = ComponentName.unflattenFromString(flattenedString);
-        if (cn == null) return null;
         if (!cn.getPackageName().equals(serviceInfo.packageName)) {
             Log.w(TAG,
                     "Inconsistent package name in component: " + cn.getPackageName()
                             + ", should be: " + serviceInfo.packageName);
             return null;
         }
+
+        // Ensure that the activity exists. If not, treat the component as invalid and return null.
+        if (new Intent().setComponent(cn).resolveActivityInfo(packageManager, 0) == null) {
+            Log.w(TAG, "Dream settings activity not found: " + cn);
+            return null;
+        }
+
         return cn;
     }
 
diff --git a/core/java/android/service/dreams/IDreamManager.aidl b/core/java/android/service/dreams/IDreamManager.aidl
index cf98bfe0..620eef6 100644
--- a/core/java/android/service/dreams/IDreamManager.aidl
+++ b/core/java/android/service/dreams/IDreamManager.aidl
@@ -50,4 +50,6 @@
     void startDreamActivity(in Intent intent);
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.WRITE_DREAM_STATE)")
     oneway void setDreamIsObscured(in boolean isObscured);
+    oneway void startDozingOneway(in IBinder token, int screenState, int reason, int screenBrightness);
+    oneway void finishSelfOneway(in IBinder token, boolean immediate);
 }
diff --git a/core/java/android/service/dreams/flags.aconfig b/core/java/android/service/dreams/flags.aconfig
index 54d950c..83e0adf 100644
--- a/core/java/android/service/dreams/flags.aconfig
+++ b/core/java/android/service/dreams/flags.aconfig
@@ -47,3 +47,13 @@
     purpose: PURPOSE_BUGFIX
   }
 }
+
+flag {
+    name: "start_and_stop_dozing_in_background"
+    namespace: "systemui"
+    description: "Move the start-dozing and stop-dozing operation to the background"
+    bug: "330287187"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/core/java/android/service/notification/Adjustment.java b/core/java/android/service/notification/Adjustment.java
index 9c14946..073f512 100644
--- a/core/java/android/service/notification/Adjustment.java
+++ b/core/java/android/service/notification/Adjustment.java
@@ -15,6 +15,8 @@
  */
 package android.service.notification;
 
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.StringDef;
@@ -62,7 +64,8 @@
             KEY_IMPORTANCE_PROPOSAL,
             KEY_SENSITIVE_CONTENT,
             KEY_RANKING_SCORE,
-            KEY_NOT_CONVERSATION
+            KEY_NOT_CONVERSATION,
+            KEY_TYPE
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface Keys {}
@@ -172,6 +175,54 @@
     public static final String KEY_NOT_CONVERSATION = "key_not_conversation";
 
     /**
+     * Data type: int, the classification type of this notification. The OS may display
+     * notifications differently depending on the type, and may change the alerting level of the
+     * notification.
+     */
+    @FlaggedApi(Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+    public static final String KEY_TYPE = "key_type";
+
+    /** @hide */
+    @IntDef(prefix = { "TYPE_" }, value = {
+            TYPE_OTHER,
+            TYPE_PROMOTION,
+            TYPE_SOCIAL_MEDIA,
+            TYPE_NEWS,
+            TYPE_CONTENT_RECOMMENDATION
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Types {}
+
+    /**
+     * This notification can be categorized, but not into one of the other categories known to the
+     * OS at a given version.
+     */
+    @FlaggedApi(Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+    public static final int TYPE_OTHER = 0;
+    /**
+     * The type of this notification is a promotion/deal.
+     */
+    @FlaggedApi(Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+    public static final int TYPE_PROMOTION = 1;
+    /**
+     * The type of this notification is social media content that isn't a
+     * {@link Notification.Builder#setShortcutId(String) conversation}.
+     */
+    @FlaggedApi(Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+    public static final int TYPE_SOCIAL_MEDIA = 2;
+    /**
+     * The type of this notification is news.
+     */
+    @FlaggedApi(Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+    public static final int TYPE_NEWS = 3;
+    /**
+     * The type of this notification is content recommendation, for example new videos or books the
+     * user may be interested in.
+     */
+    @FlaggedApi(Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+    public static final int TYPE_CONTENT_RECOMMENDATION = 4;
+
+    /**
      * Create a notification adjustment.
      *
      * @param pkg The package of the notification.
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 264b53c..146c2b6 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -176,7 +176,11 @@
 
     private String groupKey() {
         if (overrideGroupKey != null) {
-            return user.getIdentifier() + "|" + pkg + "|" + "g:" + overrideGroupKey;
+            if (Flags.notificationForceGrouping()) {
+                return overrideGroupKey;
+            } else {
+                return user.getIdentifier() + "|" + pkg + "|" + "g:" + overrideGroupKey;
+            }
         }
         final String group = getNotification().getGroup();
         final String sortKey = getNotification().getSortKey();
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 7a0c016..e16a6a1 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -262,15 +262,12 @@
     private static final String CONDITION_ATT_SOURCE = "source";
     private static final String CONDITION_ATT_FLAGS = "flags";
 
-    private static final String ZEN_POLICY_TAG = "zen_policy";
-
     private static final String MANUAL_TAG = "manual";
     private static final String AUTOMATIC_TAG = "automatic";
     private static final String AUTOMATIC_DELETED_TAG = "deleted";
 
     private static final String RULE_ATT_ID = "ruleId";
     private static final String RULE_ATT_ENABLED = "enabled";
-    private static final String RULE_ATT_SNOOZING = "snoozing";
     private static final String RULE_ATT_NAME = "name";
     private static final String RULE_ATT_PKG = "pkg";
     private static final String RULE_ATT_COMPONENT = "component";
@@ -286,6 +283,7 @@
     private static final String RULE_ATT_ICON = "rule_icon";
     private static final String RULE_ATT_TRIGGER_DESC = "triggerDesc";
     private static final String RULE_ATT_DELETION_INSTANT = "deletionInstant";
+    private static final String RULE_ATT_DISABLED_ORIGIN = "disabledOrigin";
 
     private static final String DEVICE_EFFECT_DISPLAY_GRAYSCALE = "zdeDisplayGrayscale";
     private static final String DEVICE_EFFECT_SUPPRESS_AMBIENT_DISPLAY =
@@ -1170,6 +1168,10 @@
             if (deletionInstant != null) {
                 rt.deletionInstant = Instant.ofEpochMilli(deletionInstant);
             }
+            if (Flags.modesUi()) {
+                rt.disabledOrigin = safeInt(parser, RULE_ATT_DISABLED_ORIGIN,
+                        UPDATE_ORIGIN_UNKNOWN);
+            }
         }
         return rt;
     }
@@ -1224,6 +1226,9 @@
                 out.attributeLong(null, RULE_ATT_DELETION_INSTANT,
                         rule.deletionInstant.toEpochMilli());
             }
+            if (Flags.modesUi()) {
+                out.attributeInt(null, RULE_ATT_DISABLED_ORIGIN, rule.disabledOrigin);
+            }
         }
     }
 
@@ -2373,7 +2378,7 @@
 
         public int userId = UserHandle.USER_NULL;  // USER_NULL = unspecified - use current user
         public String calName;  // CalendarContract.Calendars.DISPLAY_NAME, or null for any
-        public Long calendarId; // Calendars._ID, or null if restored from < Q calendar
+        @Nullable public Long calendarId; // Calendars._ID, or null if restored from < Q calendar
         public int reply;
 
         @Override
@@ -2405,6 +2410,33 @@
         }
     }
 
+    // ==== Built-in system condition: custom manual ====
+
+    public static final String CUSTOM_MANUAL_PATH = "custom_manual";
+    private static final Uri CUSTOM_MANUAL_CONDITION_ID =
+            new Uri.Builder().scheme(Condition.SCHEME)
+                    .authority(SYSTEM_AUTHORITY)
+                    .appendPath(CUSTOM_MANUAL_PATH)
+                    .build();
+
+    /** Returns the condition id used for manual (not automatically triggered) custom rules. */
+    public static Uri toCustomManualConditionId() {
+        return CUSTOM_MANUAL_CONDITION_ID;
+    }
+
+    /**
+     * Returns whether the supplied {@link Uri} corresponds to the condition id used for manual (not
+     * automatically triggered) custom rules.
+     */
+    public static boolean isValidCustomManualConditionId(Uri conditionId) {
+        return CUSTOM_MANUAL_CONDITION_ID.equals(conditionId);
+    }
+
+    /** Returns the {@link ComponentName} of the custom manual condition provider. */
+    public static ComponentName getCustomManualConditionProvider() {
+        return new ComponentName(SYSTEM_AUTHORITY, "CustomManualConditionProvider");
+    }
+
     // ==== End built-in system conditions ====
 
     private static int[] tryParseHourAndMinute(String value) {
@@ -2487,6 +2519,8 @@
         @ZenPolicy.ModifiableField public int zenPolicyUserModifiedFields;
         @ZenDeviceEffects.ModifiableField public int zenDeviceEffectsUserModifiedFields;
         @Nullable public Instant deletionInstant; // Only set on deleted rules.
+        @FlaggedApi(Flags.FLAG_MODES_UI)
+        @ConfigChangeOrigin public int disabledOrigin = UPDATE_ORIGIN_UNKNOWN;
 
         public ZenRule() { }
 
@@ -2525,6 +2559,9 @@
                 if (source.readInt() == 1) {
                     deletionInstant = Instant.ofEpochMilli(source.readLong());
                 }
+                if (Flags.modesUi()) {
+                    disabledOrigin = source.readInt();
+                }
             }
         }
 
@@ -2599,6 +2636,9 @@
                 } else {
                     dest.writeInt(0);
                 }
+                if (Flags.modesUi()) {
+                    dest.writeInt(disabledOrigin);
+                }
             }
         }
 
@@ -2644,6 +2684,9 @@
                 if (deletionInstant != null) {
                     sb.append(",deletionInstant=").append(deletionInstant);
                 }
+                if (Flags.modesUi()) {
+                    sb.append(",disabledOrigin=").append(disabledOrigin);
+                }
             }
 
             return sb.append(']').toString();
@@ -2697,7 +2740,7 @@
                     && other.modified == modified;
 
             if (Flags.modesApi()) {
-                return finalEquals
+                finalEquals = finalEquals
                         && Objects.equals(other.zenDeviceEffects, zenDeviceEffects)
                         && other.allowManualInvocation == allowManualInvocation
                         && Objects.equals(other.iconResName, iconResName)
@@ -2708,6 +2751,11 @@
                         && other.zenDeviceEffectsUserModifiedFields
                             == zenDeviceEffectsUserModifiedFields
                         && Objects.equals(other.deletionInstant, deletionInstant);
+
+                if (Flags.modesUi()) {
+                    finalEquals = finalEquals
+                            && other.disabledOrigin == disabledOrigin;
+                }
             }
 
             return finalEquals;
@@ -2716,11 +2764,21 @@
         @Override
         public int hashCode() {
             if (Flags.modesApi()) {
-                return Objects.hash(enabled, snoozing, name, zenMode, conditionId, condition,
-                        component, configurationActivity, pkg, id, enabler, zenPolicy,
-                        zenDeviceEffects, modified, allowManualInvocation, iconResName,
-                        triggerDescription, type, userModifiedFields, zenPolicyUserModifiedFields,
-                        zenDeviceEffectsUserModifiedFields, deletionInstant);
+                if (Flags.modesUi()) {
+                    return Objects.hash(enabled, snoozing, name, zenMode, conditionId, condition,
+                            component, configurationActivity, pkg, id, enabler, zenPolicy,
+                            zenDeviceEffects, modified, allowManualInvocation, iconResName,
+                            triggerDescription, type, userModifiedFields,
+                            zenPolicyUserModifiedFields,
+                            zenDeviceEffectsUserModifiedFields, deletionInstant, disabledOrigin);
+                } else {
+                    return Objects.hash(enabled, snoozing, name, zenMode, conditionId, condition,
+                            component, configurationActivity, pkg, id, enabler, zenPolicy,
+                            zenDeviceEffects, modified, allowManualInvocation, iconResName,
+                            triggerDescription, type, userModifiedFields,
+                            zenPolicyUserModifiedFields,
+                            zenDeviceEffectsUserModifiedFields, deletionInstant);
+                }
             }
             return Objects.hash(enabled, snoozing, name, zenMode, conditionId, condition,
                     component, configurationActivity, pkg, id, enabler, zenPolicy, modified);
@@ -2883,7 +2941,7 @@
         long latestEndTime = -1;
 
         // DND turned on by manual rule
-        if (config.manualRule != null) {
+        if (config.isManualActive()) {
             final Uri id = config.manualRule.conditionId;
             if (config.manualRule.enabler != null) {
                 // app triggered manual rule
@@ -2892,7 +2950,7 @@
                     secondaryText = appName;
                 }
             } else {
-                if (id == null) {
+                if (id == null || Uri.EMPTY.equals(id)) {
                     // Do not disturb manually triggered to remain on forever until turned off
                     if (describeForeverCondition) {
                         return context.getString(R.string.zen_mode_forever);
diff --git a/core/java/android/service/notification/flags.aconfig b/core/java/android/service/notification/flags.aconfig
index c5b4b41..51961a8 100644
--- a/core/java/android/service/notification/flags.aconfig
+++ b/core/java/android/service/notification/flags.aconfig
@@ -35,4 +35,26 @@
   description: "Guards the new CallStyleNotificationEventsCallback"
   bug: "305095040"
   is_fixed_read_only: true
+}
+
+flag {
+    name: "notification_classification"
+    is_exported: true
+    namespace: "systemui"
+    description: "Allows the NAS to classify notifications"
+    bug: "343988084"
+}
+
+flag {
+  name: "notification_force_grouping"
+  namespace: "systemui"
+  description: "This flag controls the forced auto-grouping feature"
+  bug: "336488844"
+}
+
+flag {
+  name: "notification_silent_flag"
+  namespace: "systemui"
+  description: "Guards the new FLAG_SILENT Notification flag"
+  bug: "336488844"
 }
\ No newline at end of file
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 8271caf..46b222b 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -16,7 +16,6 @@
 
 package android.service.wallpaper;
 
-import static android.app.WallpaperManager.COMMAND_DISPLAY_SWITCH;
 import static android.app.WallpaperManager.COMMAND_FREEZE;
 import static android.app.WallpaperManager.COMMAND_UNFREEZE;
 import static android.app.WallpaperManager.SetWallpaperFlags;
@@ -31,7 +30,6 @@
 import static com.android.window.flags.Flags.noConsecutiveVisibilityEvents;
 import static com.android.window.flags.Flags.noVisibilityEventOnDisplayStateChange;
 import static com.android.window.flags.Flags.offloadColorExtraction;
-import static com.android.window.flags.Flags.windowSessionRelayoutInfo;
 
 import android.animation.AnimationHandler;
 import android.animation.Animator;
@@ -162,7 +160,6 @@
     static final boolean DEBUG = false;
     static final float MIN_PAGE_ALLOWED_MARGIN = .05f;
     private static final int MIN_BITMAP_SCREENSHOT_WIDTH = 64;
-    private static final long PRESERVE_VISIBLE_TIMEOUT_MS = 1000;
     private static final long DEFAULT_UPDATE_SCREENSHOT_DURATION = 60 * 1000; //Once per minute
     private static final @NonNull RectF LOCAL_COLOR_BOUNDS =
             new RectF(0, 0, 1, 1);
@@ -175,7 +172,6 @@
 
     private static final int MSG_UPDATE_SURFACE = 10000;
     private static final int MSG_VISIBILITY_CHANGED = 10010;
-    private static final int MSG_REFRESH_VISIBILITY = 10011;
     private static final int MSG_WALLPAPER_OFFSETS = 10020;
     private static final int MSG_WALLPAPER_COMMAND = 10025;
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -259,11 +255,6 @@
          */
         private boolean mIsScreenTurningOn;
         boolean mReportedVisible;
-        /**
-         * This is used with {@link #PRESERVE_VISIBLE_TIMEOUT_MS} to avoid intermediate visibility
-         * changes if the display may be toggled in a short time, e.g. display switch.
-         */
-        boolean mPreserveVisible;
         boolean mDestroyed;
         // Set to true after receiving WallpaperManager#COMMAND_FREEZE. It's reset back to false
         // after receiving WallpaperManager#COMMAND_UNFREEZE. COMMAND_FREEZE is fully applied once
@@ -302,13 +293,10 @@
         final InsetsState mInsetsState = new InsetsState();
         final InsetsSourceControl.Array mTempControls = new InsetsSourceControl.Array();
         final MergedConfiguration mMergedConfiguration = new MergedConfiguration();
-        final Bundle mSyncSeqIdBundle = windowSessionRelayoutInfo() ? null : new Bundle();
 
         SurfaceControl mSurfaceControl = new SurfaceControl();
-        WindowRelayoutResult mRelayoutResult = windowSessionRelayoutInfo()
-                ? new WindowRelayoutResult(mWinFrames, mMergedConfiguration, mSurfaceControl,
-                        mInsetsState, mTempControls)
-                : null;
+        WindowRelayoutResult mRelayoutResult = new WindowRelayoutResult(
+                mWinFrames, mMergedConfiguration, mSurfaceControl, mInsetsState, mTempControls);
 
         private final Point mSurfaceSize = new Point();
         private final Point mLastSurfaceSize = new Point();
@@ -1111,9 +1099,6 @@
             if (pendingCount != 0) {
                 out.print(prefix); out.print("mPendingResizeCount="); out.println(pendingCount);
             }
-            if (mPreserveVisible) {
-                out.print(prefix); out.print("mPreserveVisible=true");
-            }
             synchronized (mLock) {
                 out.print(prefix); out.print("mPendingXOffset="); out.print(mPendingXOffset);
                         out.print(" mPendingXOffset="); out.println(mPendingXOffset);
@@ -1277,15 +1262,8 @@
                     } else {
                         mLayout.surfaceInsets.set(0, 0, 0, 0);
                     }
-                    final int relayoutResult;
-                    if (windowSessionRelayoutInfo()) {
-                        relayoutResult = mSession.relayout(mWindow, mLayout, mWidth, mHeight,
-                                View.VISIBLE, 0, 0, 0, mRelayoutResult);
-                    } else {
-                        relayoutResult = mSession.relayoutLegacy(mWindow, mLayout, mWidth, mHeight,
-                                View.VISIBLE, 0, 0, 0, mWinFrames, mMergedConfiguration,
-                                mSurfaceControl, mInsetsState, mTempControls, mSyncSeqIdBundle);
-                    }
+                    final int relayoutResult = mSession.relayout(mWindow, mLayout, mWidth, mHeight,
+                            View.VISIBLE, 0, 0, 0, mRelayoutResult);
                     final Rect outMaxBounds = mMergedConfiguration.getMergedConfiguration()
                             .windowConfiguration.getMaxBounds();
                     if (!outMaxBounds.equals(maxBounds)) {
@@ -1683,8 +1661,7 @@
                                 ? false
                                 : mIWallpaperEngine.mInfo.supportsAmbientMode();
                 // Report visibility only if display is fully on or wallpaper supports ambient mode.
-                final boolean visible = (mVisible && (displayFullyOn || supportsAmbientMode))
-                        || mPreserveVisible;
+                final boolean visible = mVisible && (displayFullyOn || supportsAmbientMode);
                 if (DEBUG) {
                     Log.v(
                             TAG,
@@ -2121,9 +2098,6 @@
             if (!mDestroyed) {
                 if (COMMAND_FREEZE.equals(cmd.action) || COMMAND_UNFREEZE.equals(cmd.action)) {
                     updateFrozenState(/* frozenRequested= */ !COMMAND_UNFREEZE.equals(cmd.action));
-                } else if (COMMAND_DISPLAY_SWITCH.equals(cmd.action)) {
-                    handleDisplaySwitch(cmd.z == 1 /* startToSwitch */);
-                    return;
                 }
                 result = onCommand(cmd.action, cmd.x, cmd.y, cmd.z,
                         cmd.extras, cmd.sync);
@@ -2139,23 +2113,6 @@
             }
         }
 
-        private void handleDisplaySwitch(boolean startToSwitch) {
-            if (startToSwitch && mReportedVisible) {
-                // The display may be off/on in a short time when the display is switching.
-                // Keep the visible state until onScreenTurnedOn or !startToSwitch is received, so
-                // the rendering thread can be active to redraw in time when receiving size change.
-                mPreserveVisible = true;
-                mCaller.removeMessages(MSG_REFRESH_VISIBILITY);
-                mCaller.sendMessageDelayed(mCaller.obtainMessage(MSG_REFRESH_VISIBILITY),
-                        PRESERVE_VISIBLE_TIMEOUT_MS);
-            } else if (!startToSwitch && mPreserveVisible) {
-                // The switch is finished, so restore to actual visibility.
-                mPreserveVisible = false;
-                mCaller.removeMessages(MSG_REFRESH_VISIBILITY);
-                reportVisibility(false /* forceReport */);
-            }
-        }
-
         private void updateFrozenState(boolean frozenRequested) {
             if (mIWallpaperEngine.mInfo == null
                     // Procees the unfreeze command in case the wallaper became static while
@@ -2702,10 +2659,6 @@
                             + ": " + message.arg1);
                     mEngine.doVisibilityChanged(message.arg1 != 0);
                     break;
-                case MSG_REFRESH_VISIBILITY:
-                    mEngine.mPreserveVisible = false;
-                    mEngine.reportVisibility(false /* forceReport */);
-                    break;
                 case MSG_UPDATE_SCREEN_TURNING_ON:
                     if (DEBUG) {
                         Log.v(TAG,
diff --git a/core/java/android/tracing/flags.aconfig b/core/java/android/tracing/flags.aconfig
index d7389ba..be60c25 100644
--- a/core/java/android/tracing/flags.aconfig
+++ b/core/java/android/tracing/flags.aconfig
@@ -38,3 +38,11 @@
     is_fixed_read_only: true
     bug: "323166383"
 }
+
+flag {
+    name: "perfetto_wm_tracing"
+    namespace: "windowing_tools"
+    description: "Migrate WindowManager tracing to Perfetto"
+    is_fixed_read_only: true
+    bug: "323165543"
+}
diff --git a/core/java/android/util/SequenceUtils.java b/core/java/android/util/SequenceUtils.java
new file mode 100644
index 0000000..4f8db0f
--- /dev/null
+++ b/core/java/android/util/SequenceUtils.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+
+/**
+ * Utilities to manage an info change seq id to ensure the update is in sync between client and
+ * system server. This should be used for info that can be updated though multiple IPC channel.
+ *
+ * To use it:
+ * 1. The system server should store the current seq as the source of truth, with initializing to
+ * {@link #getInitSeq}.
+ * 2. Whenever a newer info needs to be sent to the client side, the system server should first
+ * update its seq with {@link #getNextSeq}, then send the new info with the new seq to the client.
+ * 3. On the client side, when receiving a new info, it should only consume it if it is not stale by
+ * checking {@link #isIncomingSeqStale}.
+ *
+ * @hide
+ */
+public final class SequenceUtils {
+
+    private SequenceUtils() {
+    }
+
+    /**
+     * Returns {@code true} if the incomingSeq is stale, which means the client should not consume
+     * it.
+     */
+    public static boolean isIncomingSeqStale(int curSeq, int incomingSeq) {
+        if (curSeq == getInitSeq()) {
+            // curSeq can be set to the initial seq in the following cases:
+            // 1. The client process/field is newly created/recreated.
+            // 2. The field is not managed by the system server, such as WindowlessWindowManager.
+            // The client should always consume the incoming in these cases.
+            return false;
+        }
+        // Convert to long for comparison.
+        final long diff = (long) incomingSeq - curSeq;
+        // When diff is 0, allow client to consume.
+        // When there has been a sufficiently large jump, assume the sequence has wrapped around.
+        return (diff < 0 && diff > Integer.MIN_VALUE) || diff > Integer.MAX_VALUE;
+    }
+
+    /** Returns the initial seq. */
+    public static int getInitSeq() {
+        return Integer.MIN_VALUE;
+    }
+
+    /** Returns the next seq. */
+    public static int getNextSeq(int seq) {
+        return seq == Integer.MAX_VALUE
+                // Skip the initial seq, so that when the app process is relaunched, the incoming
+                // seq from the server is always treated as newer.
+                ? getInitSeq() + 1
+                : ++seq;
+    }
+}
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 8b9d876..12dbc5a 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -24,6 +24,7 @@
 import static android.view.DisplayInfoProto.LOGICAL_HEIGHT;
 import static android.view.DisplayInfoProto.LOGICAL_WIDTH;
 import static android.view.DisplayInfoProto.NAME;
+import static android.view.DisplayInfoProto.TYPE;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -961,6 +962,7 @@
         protoOutputStream.write(APP_HEIGHT, appHeight);
         protoOutputStream.write(NAME, name);
         protoOutputStream.write(FLAGS, flags);
+        protoOutputStream.write(TYPE, type);
         if (displayCutout != null) {
             displayCutout.dumpDebug(protoOutputStream, CUTOUT);
         }
diff --git a/core/java/android/view/EventLogTags.logtags b/core/java/android/view/EventLogTags.logtags
index f1cd671..f379293 100644
--- a/core/java/android/view/EventLogTags.logtags
+++ b/core/java/android/view/EventLogTags.logtags
@@ -62,6 +62,9 @@
 # following other view events defined in system/logging/logcat/event.logtags
 # ViewRoot Draw Events
 60004 viewroot_draw_event (window|3),(event|3)
+# SurfaceView Events
+60005 surfaceview_layout (window|3),(format|1),(width|1),(height|1),(z|1),(sizeFrom|3),(attached|1),(lifecycleStrategy|1),(viewVisible|1)
+60006 surfaceview_callback (window|3),(callback|3)
 
 
 # NOTE - the range 1000000-2000000 is reserved for partners and others who
diff --git a/core/java/android/view/IPinnedTaskListener.aidl b/core/java/android/view/IPinnedTaskListener.aidl
index e4e2d6f..3bd1506 100644
--- a/core/java/android/view/IPinnedTaskListener.aidl
+++ b/core/java/android/view/IPinnedTaskListener.aidl
@@ -42,12 +42,4 @@
      * with fromImeAdjustement set to {@code true}.
      */
     void onImeVisibilityChanged(boolean imeVisible, int imeHeight);
-
-    /**
-     * Called by the window manager to notify the listener that Activity (was or is in pinned mode)
-     * is hidden (either stopped or removed). This is generally used as a signal to reset saved
-     * reentry fraction and size.
-     * {@param componentName} represents the application component of PiP window.
-     */
-    void onActivityHidden(in ComponentName componentName);
 }
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index e3e4fc0..070d33b 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -49,18 +49,6 @@
  */
 interface IWindowSession {
 
-    /**
-     * Bundle key to store the latest sync seq id for the relayout configuration.
-     * @see #relayout
-     */
-    const String KEY_RELAYOUT_BUNDLE_SEQID = "seqid";
-    /**
-     * Bundle key to store the latest ActivityWindowInfo associated with the relayout configuration.
-     * Will only be set if the relayout window is an activity window.
-     * @see #relayout
-     */
-    const String KEY_RELAYOUT_BUNDLE_ACTIVITY_WINDOW_INFO = "activity_window_info";
-
     int addToDisplay(IWindow window, in WindowManager.LayoutParams attrs,
             in int viewVisibility, in int layerStackId, int requestedVisibleTypes,
             out InputChannel outInputChannel, out InsetsState insetsState,
@@ -85,16 +73,6 @@
     void remove(IBinder clientToken);
 
     /**
-     * @deprecated
-     */
-    int relayoutLegacy(IWindow window, in WindowManager.LayoutParams attrs,
-            int requestedWidth, int requestedHeight, int viewVisibility,
-            int flags, int seq, int lastSyncSeqId, out ClientWindowFrames outFrames,
-            out MergedConfiguration outMergedConfiguration, out SurfaceControl outSurfaceControl,
-            out InsetsState insetsState, out InsetsSourceControl.Array activeControls,
-            out Bundle bundle);
-
-    /**
      * Change the parameters of a window.  You supply the
      * new parameters, it returns the new frame of the window on screen (the
      * position should be ignored) and surface of the window.  The surface
diff --git a/core/java/android/view/ImeBackAnimationController.java b/core/java/android/view/ImeBackAnimationController.java
index fc1852d..c7e93c1 100644
--- a/core/java/android/view/ImeBackAnimationController.java
+++ b/core/java/android/view/ImeBackAnimationController.java
@@ -27,6 +27,7 @@
 import android.animation.ValueAnimator;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.WindowConfiguration;
 import android.graphics.Insets;
 import android.util.Log;
 import android.view.animation.BackGestureInterpolator;
@@ -137,9 +138,10 @@
     @Override
     public void onBackInvoked() {
         if (!isBackAnimationAllowed() || !mIsPreCommitAnimationInProgress) {
-            // play regular hide animation if back-animation is not allowed or if insets control has
-            // been cancelled by the system (this can happen in split screen for example)
-            mInsetsController.hide(ime());
+            // play regular hide animation if predictive back-animation is not allowed or if insets
+            // control has been cancelled by the system. This can happen in multi-window mode for
+            // example (i.e. split-screen or activity-embedding)
+            notifyHideIme();
             return;
         }
         startPostCommitAnim(/*hideIme*/ true);
@@ -209,6 +211,11 @@
         if (triggerBack) {
             mInsetsController.setPredictiveBackImeHideAnimInProgress(true);
             notifyHideIme();
+            // requesting IME as invisible during post-commit
+            mInsetsController.setRequestedVisibleTypes(0, ime());
+            // Changes the animation state. This also notifies RootView of changed insets, which
+            // causes it to reset its scrollY to 0f (animated) if it was panned
+            mInsetsController.onAnimationStateChanged(ime(), /*running*/ true);
         }
         if (mStartRootScrollY != 0 && !triggerBack) {
             // This causes RootView to update its scroll back to the panned position
@@ -228,12 +235,6 @@
         // the IME away
         mInsetsController.getHost().getInputMethodManager()
                 .notifyImeHidden(mInsetsController.getHost().getWindowToken(), statsToken);
-
-        // requesting IME as invisible during post-commit
-        mInsetsController.setRequestedVisibleTypes(0, ime());
-        // Changes the animation state. This also notifies RootView of changed insets, which causes
-        // it to reset its scrollY to 0f (animated) if it was panned
-        mInsetsController.onAnimationStateChanged(ime(), /*running*/ true);
     }
 
     private void reset() {
@@ -254,8 +255,18 @@
     }
 
     private boolean isBackAnimationAllowed() {
-        // back animation is allowed in all cases except when softInputMode is adjust_resize AND
-        // there is no app-registered WindowInsetsAnimationCallback AND edge-to-edge is not enabled.
+
+        if (mViewRoot.mContext.getResources().getConfiguration().windowConfiguration
+                .getWindowingMode() == WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW) {
+            // TODO(b/346726115) enable predictive back animation in multi-window mode in
+            //  DisplayImeController
+            return false;
+        }
+
+        // otherwise, the predictive back animation is allowed in all cases except when
+        // 1. softInputMode is adjust_resize AND
+        // 2. there is no app-registered WindowInsetsAnimationCallback AND
+        // 3. edge-to-edge is not enabled.
         return (mViewRoot.mWindowAttributes.softInputMode & SOFT_INPUT_MASK_ADJUST)
                 != SOFT_INPUT_ADJUST_RESIZE
                 || (mViewRoot.mView != null && mViewRoot.mView.hasWindowInsetsAnimationCallback())
diff --git a/core/java/android/view/InputMonitor.java b/core/java/android/view/InputMonitor.java
index 4996f5a..2302dc7 100644
--- a/core/java/android/view/InputMonitor.java
+++ b/core/java/android/view/InputMonitor.java
@@ -32,8 +32,11 @@
  * registered to monitor that type of event on the targeted display.
  *
  * @hide
+ * @deprecated See {@link android.hardware.input.InputManager#monitorGestureInput(String, int)}
+ *             for more details.
  */
 @DataClass(genToString = true)
+@Deprecated
 public final class InputMonitor implements Parcelable {
     private static final String TAG = "InputMonitor";
 
diff --git a/core/java/android/view/InsetsAnimationThreadControlRunner.java b/core/java/android/view/InsetsAnimationThreadControlRunner.java
index 83ff88b..1b3b3eb 100644
--- a/core/java/android/view/InsetsAnimationThreadControlRunner.java
+++ b/core/java/android/view/InsetsAnimationThreadControlRunner.java
@@ -89,7 +89,7 @@
                 SyncRtSurfaceTransactionApplier.SurfaceParams surfaceParams = params[i];
                 applyParams(t, surfaceParams, mTmpFloat9);
             }
-            t.setFrameTimelineVsync(Choreographer.getSfInstance().getVsyncId());
+            t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId());
             t.apply();
             t.close();
         }
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 02ea6d4..df2af73 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -29,6 +29,7 @@
 import static android.view.WindowInsets.Type.ime;
 
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
+import static com.android.window.flags.Flags.insetsControlSeq;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -890,7 +891,9 @@
         @InsetsType int visibleTypes = 0;
         @InsetsType int[] cancelledUserAnimationTypes = {0};
         for (int i = 0, size = newState.sourceSize(); i < size; i++) {
-            final InsetsSource source = newState.sourceAt(i);
+            final InsetsSource source = insetsControlSeq()
+                    ? new InsetsSource(newState.sourceAt(i))
+                    : newState.sourceAt(i);
             @InsetsType int type = source.getType();
             @AnimationType int animationType = getAnimationType(type);
             final InsetsSourceConsumer consumer = mSourceConsumers.get(source.getId());
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index 6a92fd9..c73cbc6 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -28,6 +28,7 @@
 import static android.view.InsetsSourceConsumerProto.TYPE_NUMBER;
 
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
+import static com.android.window.flags.Flags.insetsControlSeq;
 
 import android.annotation.IntDef;
 import android.annotation.Nullable;
@@ -410,7 +411,9 @@
 
         // Frame is changing while animating. Keep note of the new frame but keep existing frame
         // until animation is finished.
-        newSource = new InsetsSource(newSource);
+        if (!insetsControlSeq()) {
+            newSource = new InsetsSource(newSource);
+        }
         mPendingFrame = new Rect(newSource.getFrame());
         mPendingVisibleFrame = newSource.getVisibleFrame() != null
                 ? new Rect(newSource.getVisibleFrame())
diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java
index 487214c..2efa647 100644
--- a/core/java/android/view/InsetsSourceControl.java
+++ b/core/java/android/view/InsetsSourceControl.java
@@ -18,6 +18,7 @@
 
 import static android.graphics.PointProto.X;
 import static android.graphics.PointProto.Y;
+import static android.util.SequenceUtils.getInitSeq;
 import static android.view.InsetsSourceControlProto.LEASH;
 import static android.view.InsetsSourceControlProto.POSITION;
 import static android.view.InsetsSourceControlProto.TYPE_NUMBER;
@@ -266,6 +267,9 @@
 
         private @Nullable InsetsSourceControl[] mControls;
 
+        /** To make sure the info update between client and system server is in order. */
+        private int mSeq = getInitSeq();
+
         public Array() {
         }
 
@@ -280,9 +284,18 @@
             readFromParcel(in);
         }
 
+        public int getSeq() {
+            return mSeq;
+        }
+
+        public void setSeq(int seq) {
+            mSeq = seq;
+        }
+
         /** Updates the current Array to the given Array. */
         public void setTo(@NonNull Array other, boolean copyControls) {
             set(other.mControls, copyControls);
+            mSeq = other.mSeq;
         }
 
         /** Updates the current controls to the given controls. */
@@ -336,11 +349,13 @@
 
         public void readFromParcel(Parcel in) {
             mControls = in.createTypedArray(InsetsSourceControl.CREATOR);
+            mSeq = in.readInt();
         }
 
         @Override
         public void writeToParcel(Parcel out, int flags) {
             out.writeTypedArray(mControls, flags);
+            out.writeInt(mSeq);
         }
 
         public static final @NonNull Creator<Array> CREATOR = new Creator<>() {
@@ -362,6 +377,7 @@
                 return false;
             }
             final InsetsSourceControl.Array other = (InsetsSourceControl.Array) o;
+            // mSeq is for internal bookkeeping only.
             return Arrays.equals(mControls, other.mControls);
         }
 
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index 21eec67..bbd9acf 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -17,6 +17,7 @@
 package android.view;
 
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.util.SequenceUtils.getInitSeq;
 import static android.view.InsetsSource.FLAG_FORCE_CONSUMING;
 import static android.view.InsetsSource.FLAG_INSETS_ROUNDED_CORNER;
 import static android.view.InsetsStateProto.DISPLAY_CUTOUT;
@@ -95,6 +96,9 @@
     /** The display shape */
     private DisplayShape mDisplayShape = DisplayShape.NONE;
 
+    /** To make sure the info update between client and system server is in order. */
+    private int mSeq = getInitSeq();
+
     public InsetsState() {
         mSources = new SparseArray<>();
     }
@@ -586,6 +590,14 @@
         }
     }
 
+    public int getSeq() {
+        return mSeq;
+    }
+
+    public void setSeq(int seq) {
+        mSeq = seq;
+    }
+
     public void set(InsetsState other) {
         set(other, false /* copySources */);
     }
@@ -597,6 +609,7 @@
         mRoundedCornerFrame.set(other.mRoundedCornerFrame);
         mPrivacyIndicatorBounds = other.getPrivacyIndicatorBounds();
         mDisplayShape = other.getDisplayShape();
+        mSeq = other.mSeq;
         mSources.clear();
         for (int i = 0, size = other.mSources.size(); i < size; i++) {
             final InsetsSource otherSource = other.mSources.valueAt(i);
@@ -620,6 +633,7 @@
         mRoundedCornerFrame.set(other.mRoundedCornerFrame);
         mPrivacyIndicatorBounds = other.getPrivacyIndicatorBounds();
         mDisplayShape = other.getDisplayShape();
+        mSeq = other.mSeq;
         if (types == 0) {
             return;
         }
@@ -705,6 +719,7 @@
                 || !mRoundedCornerFrame.equals(state.mRoundedCornerFrame)
                 || !mPrivacyIndicatorBounds.equals(state.mPrivacyIndicatorBounds)
                 || !mDisplayShape.equals(state.mDisplayShape)) {
+            // mSeq is for internal bookkeeping only.
             return false;
         }
 
@@ -778,6 +793,7 @@
         mRoundedCornerFrame.writeToParcel(dest, flags);
         dest.writeTypedObject(mPrivacyIndicatorBounds, flags);
         dest.writeTypedObject(mDisplayShape, flags);
+        dest.writeInt(mSeq);
         final int size = mSources.size();
         dest.writeInt(size);
         for (int i = 0; i < size; i++) {
@@ -803,6 +819,7 @@
         mRoundedCornerFrame.readFromParcel(in);
         mPrivacyIndicatorBounds = in.readTypedObject(PrivacyIndicatorBounds.CREATOR);
         mDisplayShape = in.readTypedObject(DisplayShape.CREATOR);
+        mSeq = in.readInt();
         final int size = in.readInt();
         final SparseArray<InsetsSource> sources;
         if (mSources == null) {
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 79a9f2d..72d2d3b 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -16,15 +16,6 @@
 
 package android.view;
 
-import static android.os.IInputConstants.INPUT_EVENT_FLAG_CANCELED;
-import static android.os.IInputConstants.MOTION_EVENT_FLAG_HOVER_EXIT_PENDING;
-import static android.os.IInputConstants.INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
-import static android.os.IInputConstants.MOTION_EVENT_FLAG_IS_GENERATED_GESTURE;
-import static android.os.IInputConstants.MOTION_EVENT_FLAG_NO_FOCUS_CHANGE;
-import static android.os.IInputConstants.INPUT_EVENT_FLAG_TAINTED;
-import static android.os.IInputConstants.MOTION_EVENT_FLAG_TARGET_ACCESSIBILITY_FOCUS;
-import static android.os.IInputConstants.MOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
-import static android.os.IInputConstants.MOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
 import static android.view.Display.DEFAULT_DISPLAY;
 
 import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -38,6 +29,7 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.graphics.Matrix;
 import android.os.Build;
+import android.os.MotionEventFlag;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemClock;
@@ -476,7 +468,7 @@
      * to drop the suspect touches or to take additional precautions to confirm the user's
      * actual intent.
      */
-    public static final int FLAG_WINDOW_IS_OBSCURED = MOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
+    public static final int FLAG_WINDOW_IS_OBSCURED = MotionEventFlag.WINDOW_IS_OBSCURED;
 
     /**
      * This flag indicates that the window that received this motion event is partly
@@ -493,7 +485,7 @@
      * obstructed in areas other than the touched location.
      */
     public static final int FLAG_WINDOW_IS_PARTIALLY_OBSCURED =
-            MOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
+            MotionEventFlag.WINDOW_IS_PARTIALLY_OBSCURED;
 
     /**
      * This private flag is only set on {@link #ACTION_HOVER_MOVE} events and indicates that
@@ -501,7 +493,7 @@
      * prevent generating redundant {@link #ACTION_HOVER_ENTER} events.
      * @hide
      */
-    public static final int FLAG_HOVER_EXIT_PENDING = MOTION_EVENT_FLAG_HOVER_EXIT_PENDING;
+    public static final int FLAG_HOVER_EXIT_PENDING = MotionEventFlag.HOVER_EXIT_PENDING;
 
     /**
      * This flag indicates that the event has been generated by a gesture generator. It
@@ -509,7 +501,7 @@
      *
      * @hide
      */
-    public static final int FLAG_IS_GENERATED_GESTURE = MOTION_EVENT_FLAG_IS_GENERATED_GESTURE;
+    public static final int FLAG_IS_GENERATED_GESTURE = MotionEventFlag.IS_GENERATED_GESTURE;
 
     /**
      * This flag is only set for events with {@link #ACTION_POINTER_UP} and {@link #ACTION_CANCEL}.
@@ -522,7 +514,7 @@
      * @see #ACTION_POINTER_UP
      * @see #ACTION_CANCEL
      */
-    public static final int FLAG_CANCELED = INPUT_EVENT_FLAG_CANCELED;
+    public static final int FLAG_CANCELED = MotionEventFlag.CANCELED;
 
     /**
      * This flag indicates that the event will not cause a focus change if it is directed to an
@@ -531,7 +523,7 @@
      * window into focus.
      * @hide
      */
-    public static final int FLAG_NO_FOCUS_CHANGE = MOTION_EVENT_FLAG_NO_FOCUS_CHANGE;
+    public static final int FLAG_NO_FOCUS_CHANGE = MotionEventFlag.NO_FOCUS_CHANGE;
 
     /**
      * This flag indicates that this event was modified by or generated from an accessibility
@@ -539,7 +531,7 @@
      * @hide
      */
     @TestApi
-    public static final int FLAG_IS_ACCESSIBILITY_EVENT = INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
+    public static final int FLAG_IS_ACCESSIBILITY_EVENT = MotionEventFlag.IS_ACCESSIBILITY_EVENT;
 
     /**
      * Private flag that indicates when the system has detected that this motion event
@@ -550,7 +542,7 @@
      * @see #isTainted
      * @see #setTainted
      */
-    public static final int FLAG_TAINTED = INPUT_EVENT_FLAG_TAINTED;
+    public static final int FLAG_TAINTED = MotionEventFlag.TAINTED;
 
     /**
      * Private flag indicating that this event was synthesized by the system and should be delivered
@@ -566,7 +558,7 @@
      * @see #setTargetAccessibilityFocus(boolean)
      */
     public static final int FLAG_TARGET_ACCESSIBILITY_FOCUS =
-            MOTION_EVENT_FLAG_TARGET_ACCESSIBILITY_FOCUS;
+            MotionEventFlag.TARGET_ACCESSIBILITY_FOCUS;
 
     /** @hide */
     @IntDef(flag = true, prefix = { "FLAG_" }, value = {
diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java
index c302126..1535145 100644
--- a/core/java/android/view/PointerIcon.java
+++ b/core/java/android/view/PointerIcon.java
@@ -193,6 +193,25 @@
     /** @hide */ public static final int POINTER_ICON_VECTOR_STYLE_FILL_END =
             POINTER_ICON_VECTOR_STYLE_FILL_BLUE;
 
+    /** @hide */
+    @IntDef(prefix = {"POINTER_ICON_VECTOR_STYLE_STROKE_"}, value = {
+            POINTER_ICON_VECTOR_STYLE_STROKE_WHITE,
+            POINTER_ICON_VECTOR_STYLE_STROKE_BLACK,
+            POINTER_ICON_VECTOR_STYLE_STROKE_NONE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PointerIconVectorStyleStroke {}
+
+    /** @hide */ public static final int POINTER_ICON_VECTOR_STYLE_STROKE_WHITE = 0;
+    /** @hide */ public static final int POINTER_ICON_VECTOR_STYLE_STROKE_BLACK = 1;
+    /** @hide */ public static final int POINTER_ICON_VECTOR_STYLE_STROKE_NONE = 2;
+
+    // If adding PointerIconVectorStyleStroke, update END value for {@link SystemSettingsValidators}
+    /** @hide */ public static final int POINTER_ICON_VECTOR_STYLE_STROKE_BEGIN =
+            POINTER_ICON_VECTOR_STYLE_STROKE_WHITE;
+    /** @hide */ public static final int POINTER_ICON_VECTOR_STYLE_STROKE_END =
+            POINTER_ICON_VECTOR_STYLE_STROKE_NONE;
+
     /** @hide */ public static final float DEFAULT_POINTER_SCALE = 1f;
     /** @hide */ public static final float LARGE_POINTER_SCALE = 2.5f;
 
@@ -712,6 +731,23 @@
     }
 
     /**
+     * Convert stroke style constant to resource ID.
+     *
+     * @hide
+     */
+    public static int vectorStrokeStyleToResource(@PointerIconVectorStyleStroke int strokeStyle) {
+        return switch (strokeStyle) {
+            case POINTER_ICON_VECTOR_STYLE_STROKE_BLACK ->
+                    com.android.internal.R.style.PointerIconVectorStyleStrokeBlack;
+            case POINTER_ICON_VECTOR_STYLE_STROKE_WHITE ->
+                    com.android.internal.R.style.PointerIconVectorStyleStrokeWhite;
+            case POINTER_ICON_VECTOR_STYLE_STROKE_NONE ->
+                    com.android.internal.R.style.PointerIconVectorStyleStrokeNone;
+            default -> com.android.internal.R.style.PointerIconVectorStyleStrokeWhite;
+        };
+    }
+
+    /**
      * Sets whether drop shadow will draw in the native code.
      *
      * @hide
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 0bdb4ad..634469d 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -72,7 +72,6 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.Preconditions;
-import com.android.internal.util.VirtualRefBasePtr;
 import com.android.window.flags.Flags;
 
 import dalvik.system.CloseGuard;
@@ -273,10 +272,12 @@
             String windowName, int displayId);
     private static native void nativeSetFrameTimelineVsync(long transactionObj,
             long frameTimelineVsyncId);
-    private static native void nativeAddJankDataListener(long nativeListener,
-            long nativeSurfaceControl);
-    private static native void nativeRemoveJankDataListener(long nativeListener);
-    private static native long nativeCreateJankDataListenerWrapper(OnJankDataListener listener);
+    private static native long nativeCreateJankDataListenerWrapper(
+            long surfaceControl, OnJankDataListener listener);
+    private static native long nativeGetJankDataListenerWrapperFinalizer();
+    private static native void nativeAddJankDataListener(long nativeListener);
+    private static native void nativeFlushJankData(long nativeListener);
+    private static native void nativeRemoveJankDataListener(long nativeListener, long afterVsync);
     private static native int nativeGetGPUContextPriority();
     private static native void nativeSetTransformHint(long nativeObject,
             @SurfaceControl.BufferTransform int transformHint);
@@ -461,17 +462,63 @@
      * @see #addJankDataListener
      * @hide
      */
-    public static abstract class OnJankDataListener {
-        private final VirtualRefBasePtr mNativePtr;
-
-        public OnJankDataListener() {
-            mNativePtr = new VirtualRefBasePtr(nativeCreateJankDataListenerWrapper(this));
-        }
-
+    public interface OnJankDataListener {
         /**
          * Called when new jank classifications are available.
          */
-        public abstract void onJankDataAvailable(JankData[] jankStats);
+        void onJankDataAvailable(JankData[] jankData);
+
+    }
+
+    /**
+     * Handle to a registered {@link OnJankDatalistener}.
+     * @hide
+     */
+    public static class OnJankDataListenerRegistration {
+        private final long mNativeObject;
+
+        private static final NativeAllocationRegistry sRegistry =
+                NativeAllocationRegistry.createMalloced(
+                       OnJankDataListenerRegistration.class.getClassLoader(),
+                       nativeGetJankDataListenerWrapperFinalizer());
+
+        private final Runnable mFreeNativeResources;
+        private boolean mRemoved = false;
+
+        OnJankDataListenerRegistration(SurfaceControl surface, OnJankDataListener listener) {
+            mNativeObject = nativeCreateJankDataListenerWrapper(surface.mNativeObject, listener);
+            mFreeNativeResources = (mNativeObject == 0) ? () -> {} :
+                    sRegistry.registerNativeAllocation(this, mNativeObject);
+        }
+
+        /**
+         * Request a flush of any pending jank classification data. May cause the registered
+         * listener to be invoked inband.
+         */
+        public void flush() {
+            nativeFlushJankData(mNativeObject);
+        }
+
+        /**
+         * Request the removal of the registered listener after the VSync with the provided ID. Use
+         * a value <= 0 for afterVsync to remove the listener immediately. The given listener will
+         * not be removed before the given VSync, but may still reveive data for frames past the
+         * provided VSync.
+         */
+        public void removeAfter(long afterVsync) {
+            mRemoved = true;
+            nativeRemoveJankDataListener(mNativeObject, afterVsync);
+        }
+
+        /**
+         * Free the native resources associated with the listener registration.
+         */
+        public void release() {
+            if (!mRemoved) {
+                removeAfter(0);
+            }
+            mFreeNativeResources.run();
+        }
     }
 
     private final CloseGuard mCloseGuard = CloseGuard.get();
@@ -2632,19 +2679,11 @@
     }
 
     /**
-     * Adds a callback to be informed about SF's jank classification for a specific surface.
+     * Adds a callback to be informed about SF's jank classification for this surface.
      * @hide
      */
-    public static void addJankDataListener(OnJankDataListener listener, SurfaceControl surface) {
-        nativeAddJankDataListener(listener.mNativePtr.get(), surface.mNativeObject);
-    }
-
-    /**
-     * Removes a jank callback previously added with {@link #addJankDataListener}
-     * @hide
-     */
-    public static void removeJankDataListener(OnJankDataListener listener) {
-        nativeRemoveJankDataListener(listener.mNativePtr.get());
+    public OnJankDataListenerRegistration addJankDataListener(OnJankDataListener listener) {
+        return new OnJankDataListenerRegistration(this, listener);
     }
 
     /**
@@ -2812,6 +2851,10 @@
         private final ArrayMap<SurfaceControl, Point> mResizedSurfaces = new ArrayMap<>();
         private final ArrayMap<SurfaceControl, SurfaceControl> mReparentedSurfaces =
                  new ArrayMap<>();
+        // Only non-null if the SurfaceControlRegistry is enabled. This list tracks the set of calls
+        // made through this transaction object, and is dumped (and cleared) when the transaction is
+        // later applied.
+        ArrayList<String> mCalls;
 
         Runnable mFreeNativeResources;
         private static final float[] INVALID_COLOR = {-1, -1, -1};
@@ -2837,13 +2880,28 @@
         private Transaction(long nativeObject) {
             mNativeObject = nativeObject;
             mFreeNativeResources = sRegistry.registerNativeAllocation(this, mNativeObject);
-            if (!SurfaceControlRegistry.sCallStackDebuggingInitialized) {
-                SurfaceControlRegistry.initializeCallStackDebugging();
-            }
+            setUpForSurfaceControlRegistry();
         }
 
         private Transaction(Parcel in) {
             readFromParcel(in);
+            setUpForSurfaceControlRegistry();
+        }
+
+        /**
+         * Sets up this transaction for the SurfaceControlRegistry.
+         */
+        private void setUpForSurfaceControlRegistry() {
+            if (!SurfaceControlRegistry.sCallStackDebuggingInitialized) {
+                SurfaceControlRegistry.initializeCallStackDebugging();
+            }
+            mCalls = SurfaceControlRegistry.sLogAllTxCallsOnApply
+                    ? new ArrayList<>()
+                    : null;
+            if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
+                SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
+                        "ctor", this, null, null);
+            }
         }
 
         /**
@@ -2893,6 +2951,9 @@
             if (mNativeObject != 0) {
                 nativeClearTransaction(mNativeObject);
             }
+            if (mCalls != null) {
+                mCalls.clear();
+            }
         }
 
         /**
@@ -2904,6 +2965,9 @@
             mReparentedSurfaces.clear();
             mFreeNativeResources.run();
             mNativeObject = 0;
+            if (mCalls != null) {
+                mCalls.clear();
+            }
         }
 
         /**
@@ -2921,7 +2985,10 @@
 
             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
-                        "apply", this, null, null);
+                        SurfaceControlRegistry.APPLY, this, null, null);
+            }
+            if (mCalls != null) {
+                mCalls.clear();
             }
         }
 
@@ -4421,6 +4488,14 @@
             if (this == other) {
                 return this;
             }
+            if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
+                SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
+                        "merge", this, null, "otherTx=" + other.getId());
+                if (mCalls != null) {
+                    mCalls.addAll(other.mCalls);
+                    other.mCalls.clear();
+                }
+            }
             mResizedSurfaces.putAll(other.mResizedSurfaces);
             other.mResizedSurfaces.clear();
             mReparentedSurfaces.putAll(other.mReparentedSurfaces);
@@ -4472,6 +4547,10 @@
                 Log.w(TAG, "addTransactionCompletedListener was called but flag is disabled");
                 return this;
             }
+            if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
+                SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
+                        "setFrameTimeline", this, null, "vsyncId=" + vsyncId);
+            }
             nativeSetFrameTimelineVsync(mNativeObject, vsyncId);
             return this;
         }
@@ -4479,6 +4558,11 @@
         /** @hide */
         @NonNull
         public Transaction setFrameTimelineVsync(long frameTimelineVsyncId) {
+            if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
+                SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
+                        "setFrameTimelineVsync", this, null, "frameTimelineVsyncId="
+                                + frameTimelineVsyncId);
+            }
             nativeSetFrameTimelineVsync(mNativeObject, frameTimelineVsyncId);
             return this;
         }
diff --git a/core/java/android/view/SurfaceControlRegistry.java b/core/java/android/view/SurfaceControlRegistry.java
index aa3654d..117b200 100644
--- a/core/java/android/view/SurfaceControlRegistry.java
+++ b/core/java/android/view/SurfaceControlRegistry.java
@@ -44,6 +44,8 @@
  */
 public class SurfaceControlRegistry {
     private static final String TAG = "SurfaceControlRegistry";
+    // Special constant for identifying the Transaction#apply() calls
+    static final String APPLY = "apply";
 
     /**
      * An interface for processing the registered SurfaceControls when the threshold is exceeded.
@@ -134,6 +136,10 @@
     // sCallStackDebuggingEnabled is true.  Can be combined with the match name.
     private static String sCallStackDebuggingMatchCall;
 
+    // When set, all calls on a SurfaceControl.Transaction will be stored and logged when the
+    // transaction is applied.
+    static boolean sLogAllTxCallsOnApply;
+
     // Mapping of the active SurfaceControls to the elapsed time when they were registered
     @GuardedBy("sLock")
     private final WeakHashMap<SurfaceControl, Long> mSurfaceControls;
@@ -185,6 +191,7 @@
     public void setCallStackDebuggingParams(String matchName, String matchCall) {
         sCallStackDebuggingMatchName = matchName.toLowerCase();
         sCallStackDebuggingMatchCall = matchCall.toLowerCase();
+        sLogAllTxCallsOnApply = sCallStackDebuggingMatchCall.contains("apply");
     }
 
     /**
@@ -294,13 +301,15 @@
         sCallStackDebuggingMatchName =
                 SystemProperties.get("persist.wm.debug.sc.tx.log_match_name", null)
                         .toLowerCase();
+        sLogAllTxCallsOnApply = sCallStackDebuggingMatchCall.contains("apply");
         // Only enable stack debugging if any of the match filters are set
-        sCallStackDebuggingEnabled = (!sCallStackDebuggingMatchCall.isEmpty()
-                || !sCallStackDebuggingMatchName.isEmpty());
+        sCallStackDebuggingEnabled = !sCallStackDebuggingMatchCall.isEmpty()
+                || !sCallStackDebuggingMatchName.isEmpty();
         if (sCallStackDebuggingEnabled) {
             Log.d(TAG, "Enabling transaction call stack debugging:"
                     + " matchCall=" + sCallStackDebuggingMatchCall
-                    + " matchName=" + sCallStackDebuggingMatchName);
+                    + " matchName=" + sCallStackDebuggingMatchName
+                    + " logCallsWithApply=" + sLogAllTxCallsOnApply);
         }
     }
 
@@ -319,15 +328,31 @@
         if (!sCallStackDebuggingEnabled) {
             return;
         }
-        if (!matchesForCallStackDebugging(sc != null ? sc.getName() : null, call)) {
-            return;
-        }
-        final String txMsg = tx != null ? "tx=" + tx.getId() + " ": "";
-        final String scMsg = sc != null ? " sc=" + sc.getName() + "": "";
+
+        final String txMsg = tx != null ? "tx=" + tx.getId() + " " : "";
+        final String scMsg = sc != null ? " sc=" + sc.getName() + "" : "";
         final String msg = details != null
                 ? call + " (" + txMsg + scMsg + ") " + details
                 : call + " (" + txMsg + scMsg + ")";
-        Log.e(TAG, msg, new Throwable());
+        if (sLogAllTxCallsOnApply && tx != null) {
+            if (call == APPLY) {
+                // Log the apply and dump the calls on that transaction
+                Log.e(TAG, msg, new Throwable());
+                for (int i = 0; i < tx.mCalls.size(); i++) {
+                    Log.d(TAG, "        " + tx.mCalls.get(i));
+                }
+            } else if (matchesForCallStackDebugging(sc != null ? sc.getName() : null, call)) {
+                // Otherwise log this call to the transaction if it matches the tracked calls
+                Log.e(TAG, msg, new Throwable());
+                tx.mCalls.add(msg);
+            }
+        } else {
+            // Log this call if it matches the tracked calls
+            if (!matchesForCallStackDebugging(sc != null ? sc.getName() : null, call)) {
+                return;
+            }
+            Log.e(TAG, msg, new Throwable());
+        }
     }
 
     /**
@@ -388,6 +413,7 @@
                 pw.println("sCallStackDebuggingEnabled=" + sCallStackDebuggingEnabled);
                 pw.println("sCallStackDebuggingMatchName=" + sCallStackDebuggingMatchName);
                 pw.println("sCallStackDebuggingMatchCall=" + sCallStackDebuggingMatchCall);
+                pw.println("sLogAllTxCallsOnApply=" + sLogAllTxCallsOnApply);
             }
         }
     }
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 1d70d18..fedbe4a 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -49,6 +49,7 @@
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.AttributeSet;
+import android.util.EventLog;
 import android.util.Log;
 import android.view.SurfaceControl.Transaction;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -163,6 +164,8 @@
     private static final boolean DEBUG_POSITION = false;
 
     private static final long FORWARD_BACK_KEY_TOLERANCE_MS = 100;
+    private static final int LOGTAG_SURFACEVIEW_LAYOUT = 60005;
+    private static final int LOGTAG_SURFACEVIEW_CALLBACK = 60006;
 
     @UnsupportedAppUsage(
             maxTargetSdk = Build.VERSION_CODES.TIRAMISU,
@@ -320,6 +323,8 @@
     private final ConcurrentLinkedQueue<WindowManager.LayoutParams> mEmbeddedWindowParams =
             new ConcurrentLinkedQueue<>();
 
+    private String mTag = TAG;
+
     private final ISurfaceControlViewHostParent mSurfaceControlViewHostParent =
             new ISurfaceControlViewHostParent.Stub() {
         @Override
@@ -418,13 +423,26 @@
         updateSurface();
     }
 
+    private void setTag() {
+        String windowName = "";
+        ViewRootImpl viewRoot = getViewRootImpl();
+        if (viewRoot != null) {
+            // strip package name
+            final String[] split = viewRoot.mWindowAttributes.getTitle().toString().split("\\.");
+            if (split.length > 0) {
+                windowName =  " " + split[split.length - 1];
+            }
+        }
+
+        mTag = "SV[" + System.identityHashCode(this) + windowName + "]";
+    }
+
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-
+        setTag();
         getViewRootImpl().addSurfaceChangedCallback(this);
         mWindowStopped = false;
-
         mViewVisibility = getVisibility() == VISIBLE;
         updateRequestedVisibility();
 
@@ -1146,13 +1164,22 @@
                     + " format=" + formatChanged + " size=" + sizeChanged
                     + " visible=" + visibleChanged + " alpha=" + alphaChanged
                     + " hint=" + hintChanged
-                    + " visible=" + visibleChanged
                     + " left=" + (mWindowSpaceLeft != mLocation[0])
                     + " top=" + (mWindowSpaceTop != mLocation[1])
                     + " z=" + relativeZChanged
                     + " attached=" + mAttachedToWindow
                     + " lifecycleStrategy=" + surfaceLifecycleStrategyChanged);
 
+            if (creating || formatChanged || sizeChanged  || visibleChanged
+                    || layoutSizeChanged ||  relativeZChanged || !mAttachedToWindow
+                    || surfaceLifecycleStrategyChanged ) {
+                EventLog.writeEvent(LOGTAG_SURFACEVIEW_LAYOUT,
+                        mTag, mRequestedFormat, myWidth, myHeight, mRequestedSubLayer,
+                        (mRequestedWidth > 0 ? "setFixedSize" : "layout"),
+                        (mAttachedToWindow ? 1 : 0),
+                        mRequestedSurfaceLifecycleStrategy, (mRequestedVisible ? 1 : 0));
+            }
+
             try {
                 mVisible = mRequestedVisible;
                 mWindowSpaceLeft = mLocation[0];
@@ -1235,6 +1262,8 @@
                             mIsCreating = true;
                             if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
                                     + "visibleChanged -- surfaceCreated");
+                            EventLog.writeEvent(LOGTAG_SURFACEVIEW_CALLBACK, mTag,
+                                "surfaceCreated");
                             callbacks = getSurfaceCallbacks();
                             for (SurfaceHolder.Callback c : callbacks) {
                                 c.surfaceCreated(mSurfaceHolder);
@@ -1245,6 +1274,9 @@
                             if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
                                     + "surfaceChanged -- format=" + mFormat
                                     + " w=" + myWidth + " h=" + myHeight);
+                            EventLog.writeEvent(LOGTAG_SURFACEVIEW_CALLBACK, mTag,
+                                    "surfaceChanged -- format=" + mFormat
+                                    + " w=" + myWidth + " h=" + myHeight);
                             if (callbacks == null) {
                                 callbacks = getSurfaceCallbacks();
                             }
@@ -1256,6 +1288,9 @@
                             if (DEBUG) {
                                 Log.i(TAG, System.identityHashCode(this) + " surfaceRedrawNeeded");
                             }
+                            EventLog.writeEvent(LOGTAG_SURFACEVIEW_CALLBACK, mTag,
+                                "surfaceRedrawNeeded");
+
                             if (callbacks == null) {
                                 callbacks = getSurfaceCallbacks();
                             }
@@ -1337,7 +1372,7 @@
 
     private void redrawNeededAsync(SurfaceHolder.Callback[] callbacks,
             Runnable callbacksCollected) {
-        SurfaceCallbackHelper sch = new SurfaceCallbackHelper(callbacksCollected);
+        SurfaceCallbackHelper sch = new SurfaceCallbackHelper(callbacksCollected, mTag);
         sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
     }
 
@@ -2100,6 +2135,7 @@
         if (mSurface.isValid()) {
             if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
                     + "surfaceDestroyed");
+            EventLog.writeEvent(LOGTAG_SURFACEVIEW_CALLBACK, mTag, "surfaceDestroyed");
             SurfaceHolder.Callback[] callbacks = getSurfaceCallbacks();
             for (SurfaceHolder.Callback c : callbacks) {
                 c.surfaceDestroyed(mSurfaceHolder);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 3df72e8..88d7a83 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -22,6 +22,7 @@
 import static android.service.autofill.Flags.FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION;
 import static android.view.ContentInfo.SOURCE_DRAG_AND_DROP;
 import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH;
+import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH_HINT;
 import static android.view.Surface.FRAME_RATE_CATEGORY_LOW;
 import static android.view.Surface.FRAME_RATE_CATEGORY_NORMAL;
 import static android.view.Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE;
@@ -5512,6 +5513,14 @@
     public static final int DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG = 1 << 13;
 
     /**
+     * Flag indicating that this drag will result in the caller activity's task to be hidden for the
+     * duration of the drag, this means that the source activity will not receive drag events for
+     * the current drag gesture. Only the current voice interaction service may use this flag.
+     * @hide
+     */
+    public static final int DRAG_FLAG_HIDE_CALLING_TASK_ON_DRAG_START = 1 << 14;
+
+    /**
      * Vertical scroll factor cached by {@link #getVerticalScrollFactor}.
      */
     private float mVerticalScrollFactor;
@@ -19630,7 +19639,6 @@
      */
     public final void setLeft(int left) {
         if (left != mLeft) {
-            mPrivateFlags4 |= PFLAG4_HAS_MOVED;
             final boolean matrixIsIdentity = hasIdentityMatrix();
             if (matrixIsIdentity) {
                 if (mAttachInfo != null) {
@@ -25584,6 +25592,7 @@
                         ? FRAME_RATE_CATEGORY_NORMAL : FRAME_RATE_CATEGORY_HIGH;
                 mSizeBasedFrameRateCategoryAndReason = category | FRAME_RATE_CATEGORY_REASON_LARGE;
             }
+            mPrivateFlags4 |= PFLAG4_HAS_MOVED;
         }
 
         onSizeChanged(newWidth, newHeight, oldWidth, oldHeight);
@@ -30607,7 +30616,8 @@
      * {@link #setPointerIcon(PointerIcon)} for mouse devices. Subclasses may override this to
      * customize the icon for the given pointer.
      *
-     * For example, the pointer icon for a stylus pointer can be resolved in the following way:
+     * For example, to always show the PointerIcon.TYPE_HANDWRITING icon for a stylus pointer,
+     * the event can be resolved in the following way:
      * <code><pre>
      * &#64;Override
      * public PointerIcon onResolvePointerIcon(MotionEvent event, int pointerIndex) {
@@ -30617,7 +30627,7 @@
      *             && (toolType == MotionEvent.TOOL_TYPE_STYLUS
      *                     || toolType == MotionEvent.TOOL_TYPE_ERASER)) {
      *         // Show this pointer icon only if this pointer is a stylus.
-     *         return PointerIcon.getSystemIcon(mContext, PointerIcon.TYPE_WAIT);
+     *         return PointerIcon.getSystemIcon(mContext, PointerIcon.TYPE_HANDWRITING);
      *     }
      *     // Use the default logic for determining the pointer icon for other non-stylus pointers,
      *     // like for the mouse cursor.
@@ -33896,10 +33906,37 @@
      * @hide
      */
     protected int calculateFrameRateCategory() {
+        ViewRootImpl viewRootImpl = getViewRootImpl();
+        ViewParent parent = mParent;
+        boolean isInputMethodWindowType =
+                viewRootImpl.mWindowAttributes.type == TYPE_INPUT_METHOD;
+
+        // boost frame rate when the position or the size changed.
+        if (((mPrivateFlags4 & (PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN)) == (
+                PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN) || mLastFrameLeft != mLeft
+                || mLastFrameTop != mTop)
+                && viewRootImpl.shouldCheckFrameRateCategory()
+                && parent instanceof View
+                && ((View) parent).mFrameContentVelocity <= 0
+                && !isInputMethodWindowType) {
+
+            return FRAME_RATE_CATEGORY_HIGH_HINT | FRAME_RATE_CATEGORY_REASON_BOOST;
+        }
         int category;
-        switch (getViewRootImpl().intermittentUpdateState()) {
-            case ViewRootImpl.INTERMITTENT_STATE_INTERMITTENT -> category =
-                    FRAME_RATE_CATEGORY_NORMAL | FRAME_RATE_CATEGORY_REASON_INTERMITTENT;
+        switch (viewRootImpl.intermittentUpdateState()) {
+            case ViewRootImpl.INTERMITTENT_STATE_INTERMITTENT -> {
+                if (!sToolkitFrameRateBySizeReadOnlyFlagValue) {
+                    category = FRAME_RATE_CATEGORY_NORMAL;
+                } else {
+                    // The size based frame rate category can only be LOW or NORMAL. If the size
+                    // based frame rate category is LOW, we shouldn't vote for NORMAL for
+                    // intermittent.
+                    category = Math.min(
+                            mSizeBasedFrameRateCategoryAndReason & ~FRAME_RATE_CATEGORY_REASON_MASK,
+                            FRAME_RATE_CATEGORY_NORMAL);
+                }
+                category |= FRAME_RATE_CATEGORY_REASON_INTERMITTENT;
+            }
             case ViewRootImpl.INTERMITTENT_STATE_NOT_INTERMITTENT ->
                     category = mSizeBasedFrameRateCategoryAndReason;
             default -> category = mLastFrameRateCategory;
@@ -33920,59 +33957,23 @@
         }
         float velocity = mFrameContentVelocity;
         final float frameRate = mPreferredFrameRate;
-        ViewParent parent = mParent;
-        if (velocity <= 0 && Float.isNaN(frameRate)) {
-            // The most common case is when nothing is set, so this special case is called
-            // often.
-            if (mAttachInfo.mViewVelocityApi
-                    && ((mPrivateFlags4 & (PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN)) == (
-                    PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN) || mLastFrameLeft != mLeft
-                    || mLastFrameTop != mTop)
-                    && viewRootImpl.shouldCheckFrameRate(false)
-                    && parent instanceof View
-                    && ((View) parent).mFrameContentVelocity <= 0) {
-                viewRootImpl.votePreferredFrameRate(MAX_FRAME_RATE, FRAME_RATE_COMPATIBILITY_GTE);
-            }
-            if (viewRootImpl.shouldCheckFrameRateCategory()) {
-                int frameRateCategory = calculateFrameRateCategory();
-                int category = frameRateCategory & ~FRAME_RATE_CATEGORY_REASON_MASK;
-                int reason = frameRateCategory & FRAME_RATE_CATEGORY_REASON_MASK;
-                viewRootImpl.votePreferredFrameRateCategory(category, reason, this);
-                mLastFrameRateCategory = frameRateCategory;
-            }
-            mLastFrameLeft = mLeft;
-            mLastFrameTop = mTop;
-            return;
-        }
-        if (viewRootImpl.shouldCheckFrameRate(frameRate > 0f)) {
+
+        if (viewRootImpl.shouldCheckFrameRate(frameRate > 0f)
+                && (frameRate > 0 || (mAttachInfo.mViewVelocityApi && velocity > 0f))) {
             float velocityFrameRate = 0f;
-            if (mAttachInfo.mViewVelocityApi) {
-                if (velocity < 0f
-                        && ((mPrivateFlags4 & (PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN)) == (
-                        PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN) || mLastFrameLeft != mLeft
-                        || mLastFrameTop != mTop)
-                        && mParent instanceof View
-                        && ((View) mParent).mFrameContentVelocity <= 0
-                ) {
-                    // This current calculation is very simple. If something on the screen
-                    // moved, then it votes for the highest velocity.
-                    velocityFrameRate = MAX_FRAME_RATE;
-                } else if (velocity > 0f) {
-                    velocityFrameRate = convertVelocityToFrameRate(velocity);
-                }
+            if (mAttachInfo.mViewVelocityApi && velocity > 0f) {
+                velocityFrameRate = convertVelocityToFrameRate(velocity);
             }
-            if (velocityFrameRate > 0f || frameRate > 0f) {
-                int compatibility;
-                float frameRateToSet;
-                if (frameRate >= velocityFrameRate) {
-                    compatibility = FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
-                    frameRateToSet = frameRate;
-                } else {
-                    compatibility = FRAME_RATE_COMPATIBILITY_GTE;
-                    frameRateToSet = velocityFrameRate;
-                }
-                viewRootImpl.votePreferredFrameRate(frameRateToSet, compatibility);
+            int compatibility;
+            float frameRateToSet;
+            if (frameRate >= velocityFrameRate) {
+                compatibility = FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
+                frameRateToSet = frameRate;
+            } else {
+                compatibility = FRAME_RATE_COMPATIBILITY_GTE;
+                frameRateToSet = velocityFrameRate;
             }
+            viewRootImpl.votePreferredFrameRate(frameRateToSet, compatibility);
         }
 
         if (viewRootImpl.shouldCheckFrameRateCategory()) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 2377b86..d224217 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -22,11 +22,11 @@
 import static android.graphics.HardwareRenderer.SYNC_LOST_SURFACE_REWARD_IF_FOUND;
 import static android.os.IInputConstants.INVALID_INPUT_EVENT_ID;
 import static android.os.Trace.TRACE_TAG_VIEW;
+import static android.util.SequenceUtils.getInitSeq;
+import static android.util.SequenceUtils.isIncomingSeqStale;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.DragEvent.ACTION_DRAG_LOCATION;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_APP_PROGRESS_GENERATION_ALLOWED;
-import static android.view.flags.Flags.sensitiveContentPrematureProtectionRemovedFix;
 import static android.view.InputDevice.SOURCE_CLASS_NONE;
 import static android.view.InsetsSource.ID_IME;
 import static android.view.Surface.FRAME_RATE_CATEGORY_DEFAULT;
@@ -90,6 +90,7 @@
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 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_APP_PROGRESS_GENERATION_ALLOWED;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FIT_INSETS_CONTROLLED;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
@@ -113,7 +114,9 @@
 import static android.view.accessibility.Flags.forceInvertColor;
 import static android.view.accessibility.Flags.reduceWindowContentChangedEventThrottle;
 import static android.view.flags.Flags.addSchandleToVriSurface;
+import static android.view.flags.Flags.disableDrawWakeLock;
 import static android.view.flags.Flags.sensitiveContentAppProtection;
+import static android.view.flags.Flags.sensitiveContentPrematureProtectionRemovedFix;
 import static android.view.flags.Flags.toolkitFrameRateFunctionEnablingReadOnly;
 import static android.view.flags.Flags.toolkitFrameRateTypingReadOnly;
 import static android.view.flags.Flags.toolkitFrameRateVelocityMappingReadOnly;
@@ -124,11 +127,12 @@
 import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.INSETS_CONTROLLER;
 
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
+import static com.android.text.flags.Flags.disableHandwritingInitiatorForIme;
 import static com.android.window.flags.Flags.activityWindowInfoFlag;
 import static com.android.window.flags.Flags.enableBufferTransformHintFromDisplay;
+import static com.android.window.flags.Flags.insetsControlChangedItem;
+import static com.android.window.flags.Flags.insetsControlSeq;
 import static com.android.window.flags.Flags.setScPropertiesInClient;
-import static com.android.window.flags.Flags.windowSessionRelayoutInfo;
-import static com.android.text.flags.Flags.disableHandwritingInitiatorForIme;
 
 import android.Manifest;
 import android.accessibilityservice.AccessibilityService;
@@ -146,6 +150,8 @@
 import android.app.WindowConfiguration;
 import android.app.compat.CompatChanges;
 import android.app.servertransaction.WindowStateTransactionItem;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ClipData;
 import android.content.ClipDescription;
@@ -334,6 +340,15 @@
     private static final int LOGTAG_VIEWROOT_DRAW_EVENT = 60004;
 
     /**
+     * This change disables the {@code DRAW_WAKE_LOCK}, an internal wakelock acquired per-frame
+     * duration display DOZE. It was added to allow animation during AOD. This wakelock consumes
+     * battery severely if the animation is too heavy, so, it will be removed.
+     */
+    @ChangeId
+    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
+    private static final long DISABLE_DRAW_WAKE_LOCK = 349153669L;
+
+    /**
      * Set to false if we do not want to use the multi threaded renderer even though
      * threaded renderer (aka hardware renderering) is used. Note that by disabling
      * this, WindowCallbacks will not fire.
@@ -892,6 +907,12 @@
     /** Non-{@code null} if {@link #mActivityConfigCallback} is not {@code null}. */
     @Nullable
     private ActivityWindowInfo mLastReportedActivityWindowInfo;
+    @Nullable
+    private final ClientWindowFrames mLastReportedFrames = insetsControlSeq()
+            ? new ClientWindowFrames()
+            : null;
+    private int mLastReportedInsetsStateSeq = getInitSeq();
+    private int mLastReportedActiveControlsSeq = getInitSeq();
 
     boolean mScrollMayChange;
     @SoftInputModeFlags
@@ -1107,6 +1128,8 @@
     private boolean mIsFrameRateBoosting = false;
     // Used to check if it is in touch boosting period.
     private boolean mIsTouchBoosting = false;
+    // Used to track if an ongoing press gesture is occurring.
+    private boolean mIsPressedGesture = false;
     private boolean mDrawnThisFrame = false;
     // Used to check if there is a conflict between different frame rate voting.
     // Take 24 and 30 as an example, 24 is not a divisor of 30.
@@ -1137,7 +1160,7 @@
      */
 
     /**
-     * A temporary object used so relayoutWindow can return the latest SyncSeqId
+     * Object for relayoutWindow to return the latest window info, including the SyncSeqId
      * system. The SyncSeqId system was designed to work without synchronous relayout
      * window, and actually synchronous relayout window presents a problem.  We could have
      * a sequence like this:
@@ -1151,14 +1174,8 @@
      * we get rid of synchronous relayout, until then, we use this bundle to channel the
      * integer back over relayout.
      */
-    private final Bundle mRelayoutBundle = windowSessionRelayoutInfo()
-            ? null
-            : new Bundle();
-
-    private final WindowRelayoutResult mRelayoutResult = windowSessionRelayoutInfo()
-            ? new WindowRelayoutResult(mTmpFrames, mPendingMergedConfiguration, mSurfaceControl,
-                    mTempInsets, mTempControls)
-            : null;
+    private final WindowRelayoutResult mRelayoutResult = new WindowRelayoutResult(
+            mTmpFrames, mPendingMergedConfiguration, mSurfaceControl, mTempInsets, mTempControls);
 
     private static volatile boolean sAnrReported = false;
     static BLASTBufferQueue.TransactionHangCallback sTransactionHangCallback =
@@ -1190,6 +1207,8 @@
     private final Rect mChildBoundingInsets = new Rect();
     private boolean mChildBoundingInsetsChanged = false;
 
+    private final boolean mDisableDrawWakeLock;
+
     private String mTag = TAG;
     private String mFpsTraceName;
     private String mLargestViewTraceName;
@@ -1266,7 +1285,6 @@
         mDensity = context.getResources().getDisplayMetrics().densityDpi;
         mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi;
         mFallbackEventHandler = new PhoneFallbackEventHandler(context);
-        // TODO(b/222696368): remove getSfInstance usage and use vsyncId for transactions
         mChoreographer = Choreographer.getInstance();
         mInsetsController = new InsetsController(new ViewRootInsetsControllerHost(this));
         mImeBackAnimationController = new ImeBackAnimationController(this, mInsetsController);
@@ -1320,6 +1338,10 @@
         }
 
         mAppStartInfoTimestampsFlagValue = android.app.Flags.appStartInfoTimestamps();
+
+        // Disable DRAW_WAKE_LOCK starting U.
+        mDisableDrawWakeLock =
+                CompatChanges.isChangeEnabled(DISABLE_DRAW_WAKE_LOCK) && disableDrawWakeLock();
     }
 
     public static void addFirstDrawHandler(Runnable callback) {
@@ -1601,8 +1623,6 @@
                         attachedFrame = null;
                     }
                     if (mTranslator != null) {
-                        mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
-                        mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls.get());
                         mTranslator.translateRectInScreenToAppWindow(attachedFrame);
                     }
                     mTmpFrames.attachedFrame = attachedFrame;
@@ -1625,8 +1645,7 @@
                 mAttachInfo.mAlwaysConsumeSystemBars =
                         (res & WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_SYSTEM_BARS) != 0;
                 mPendingAlwaysConsumeSystemBars = mAttachInfo.mAlwaysConsumeSystemBars;
-                mInsetsController.onStateChanged(mTempInsets);
-                mInsetsController.onControlsChanged(mTempControls.get());
+                handleInsetsControlChanged(mTempInsets, mTempControls);
                 final InsetsState state = mInsetsController.getState();
                 final Rect displayCutoutSafe = mTempRect;
                 state.getDisplayCutoutSafe(displayCutoutSafe);
@@ -2224,17 +2243,18 @@
             return;
         }
 
+        onClientWindowFramesChanged(frames);
+
         CompatibilityInfo.applyOverrideScaleIfNeeded(mergedConfiguration);
         final Rect frame = frames.frame;
         final Rect displayFrame = frames.displayFrame;
         final Rect attachedFrame = frames.attachedFrame;
         if (mTranslator != null) {
-            mTranslator.translateInsetsStateInScreenToAppWindow(insetsState);
             mTranslator.translateRectInScreenToAppWindow(frame);
             mTranslator.translateRectInScreenToAppWindow(displayFrame);
             mTranslator.translateRectInScreenToAppWindow(attachedFrame);
         }
-        mInsetsController.onStateChanged(insetsState);
+        onInsetsStateChanged(insetsState);
         final float compatScale = frames.compatScale;
         final boolean frameChanged = !mWinFrame.equals(frame);
         final boolean shouldReportActivityWindowInfoChanged =
@@ -2299,26 +2319,69 @@
     }
 
     /** Handles messages {@link #MSG_INSETS_CONTROL_CHANGED}. */
-    private void handleInsetsControlChanged(@NonNull InsetsState insetsState,
+    @VisibleForTesting
+    public void handleInsetsControlChanged(@NonNull InsetsState insetsState,
             @NonNull InsetsSourceControl.Array activeControls) {
-        final InsetsSourceControl[] controls = activeControls.get();
-
-        if (mTranslator != null) {
-            mTranslator.translateInsetsStateInScreenToAppWindow(insetsState);
-            mTranslator.translateSourceControlsInScreenToAppWindow(controls);
-        }
-
         // Deliver state change before control change, such that:
         // a) When gaining control, controller can compare with server state to evaluate
         // whether it needs to run animation.
         // b) When loosing control, controller can restore server state by taking last
         // dispatched state as truth.
-        mInsetsController.onStateChanged(insetsState);
-        if (mAdded) {
-            mInsetsController.onControlsChanged(controls);
-        } else {
-            activeControls.release();
+        onInsetsStateChanged(insetsState);
+        onActiveControlsChanged(activeControls);
+    }
+
+    private void onClientWindowFramesChanged(@NonNull ClientWindowFrames inOutFrames) {
+        if (mLastReportedFrames == null) {
+            return;
         }
+        if (isIncomingSeqStale(mLastReportedFrames.seq, inOutFrames.seq)) {
+            // If the incoming is stale, use the last reported instead.
+            inOutFrames.setTo(mLastReportedFrames);
+        } else {
+            // Keep track of the latest.
+            mLastReportedFrames.setTo(inOutFrames);
+        }
+    }
+
+    private void onInsetsStateChanged(@NonNull InsetsState insetsState) {
+        if (insetsControlSeq()) {
+            if (isIncomingSeqStale(mLastReportedInsetsStateSeq, insetsState.getSeq())) {
+                // The incoming is stale. Skip.
+                return;
+            }
+            // Keep track of the latest.
+            mLastReportedInsetsStateSeq = insetsState.getSeq();
+        }
+
+        if (mTranslator != null) {
+            mTranslator.translateInsetsStateInScreenToAppWindow(insetsState);
+        }
+        mInsetsController.onStateChanged(insetsState);
+    }
+
+    private void onActiveControlsChanged(@NonNull InsetsSourceControl.Array activeControls) {
+        if (!mAdded) {
+            // Do not update the last report if window is not added yet.
+            activeControls.release();
+            return;
+        }
+
+        if (insetsControlSeq()) {
+            if (isIncomingSeqStale(mLastReportedActiveControlsSeq, activeControls.getSeq())) {
+                // The incoming is stale. Skip.
+                activeControls.release();
+                return;
+            }
+            // Keep track of the latest.
+            mLastReportedActiveControlsSeq = activeControls.getSeq();
+        }
+
+        final InsetsSourceControl[] controls = activeControls.get();
+        if (mTranslator != null) {
+            mTranslator.translateSourceControlsInScreenToAppWindow(controls);
+        }
+        mInsetsController.onControlsChanged(controls);
     }
 
     private final DisplayListener mDisplayListener = new DisplayListener() {
@@ -2414,8 +2477,11 @@
     }
 
     void pokeDrawLockIfNeeded() {
-        if (!Display.isDozeState(mAttachInfo.mDisplayState)) {
-            // Only need to acquire wake lock for DOZE state.
+        // Disable DRAW_WAKE_LOCK starting U. Otherwise, only need to acquire it for DOZE state.
+        if (mDisableDrawWakeLock || mAttachInfo.mDisplayState != Display.STATE_DOZE) {
+            // In DOZE_SUSPEND, Android shouldn't control the display; therefore we only poke the
+            // draw wake lock when display state is DOZE. Noted that Display#isDozeState includes
+            // DOZE_SUSPEND as well, so, it's not feasible here.
             return;
         }
         if (mWindowAttributes.type != WindowManager.LayoutParams.TYPE_BASE_APPLICATION) {
@@ -4358,6 +4424,8 @@
             }
             mFrameRateCategoryHighCount = mFrameRateCategoryHighCount > 0
                     ? mFrameRateCategoryHighCount - 1 : mFrameRateCategoryHighCount;
+            mFrameRateCategoryHighHintCount = mFrameRateCategoryHighHintCount > 0
+                    ? mFrameRateCategoryHighHintCount - 1 : mFrameRateCategoryHighHintCount;
             mFrameRateCategoryNormalCount = mFrameRateCategoryNormalCount > 0
                     ? mFrameRateCategoryNormalCount - 1 : mFrameRateCategoryNormalCount;
             mFrameRateCategoryLowCount = mFrameRateCategoryLowCount > 0
@@ -4405,7 +4473,7 @@
         if (mAppStartInfoTimestampsFlagValue && !mAppStartTrackingStarted) {
             mAppStartTrackingStarted = true;
             Transaction transaction = new Transaction();
-            transaction.addTransactionCompletedListener(mExecutor,
+            transaction.addTransactionCompletedListener(mSimpleExecutor,
                     new Consumer<TransactionStats>() {
                         @Override
                         public void accept(TransactionStats transactionStats) {
@@ -6919,6 +6987,7 @@
                         setPreferredFrameRate(mPreferredFrameRate);
                         setPreferredFrameRateCategory(mPreferredFrameRateCategory);
                         mInvalidationIdleMessagePosted = false;
+                        mIsPressedGesture = false;
                     } else {
                         mInvalidationIdleMessagePosted = true;
                         mHandler.sendEmptyMessageDelayed(MSG_CHECK_INVALIDATION_IDLE,
@@ -7405,6 +7474,10 @@
 
         @Override
         protected int onProcess(QueuedInputEvent q) {
+            if (q.forPreImeOnly()) {
+                // this event is intended for the ViewPreImeInputStage only, let's forward
+                return FORWARD;
+            }
             if (q.mEvent instanceof KeyEvent) {
                 final KeyEvent keyEvent = (KeyEvent) q.mEvent;
 
@@ -7511,6 +7584,8 @@
             final KeyEvent event = (KeyEvent)q.mEvent;
             if (mView.dispatchKeyEventPreIme(event)) {
                 return FINISH_HANDLED;
+            } else if (q.forPreImeOnly()) {
+                return FINISH_NOT_HANDLED;
             }
             return FORWARD;
         }
@@ -7930,6 +8005,9 @@
         private int processPointerEvent(QueuedInputEvent q) {
             final MotionEvent event = (MotionEvent)q.mEvent;
             final int action = event.getAction();
+            if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+                mIsPressedGesture = false;
+            }
             boolean handled = false;
             if (!disableHandwritingInitiatorForIme()
                     || mWindowAttributes.type != TYPE_INPUT_METHOD) {
@@ -7960,6 +8038,9 @@
                     mWindowAttributes.type)) {
                 // set the frame rate to the maximum value.
                 mIsTouchBoosting = true;
+                if (action == MotionEvent.ACTION_DOWN) {
+                    mIsPressedGesture = true;
+                }
                 setPreferredFrameRateCategory(mLastPreferredFrameRateCategory);
             }
             /**
@@ -9258,42 +9339,21 @@
                     insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, mRelayoutSeq,
                     mLastSyncSeqId);
         } else {
-            if (windowSessionRelayoutInfo()) {
-                relayoutResult = mWindowSession.relayout(mWindow, params,
-                        requestedWidth, requestedHeight, viewVisibility,
-                        insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
-                        mRelayoutSeq, mLastSyncSeqId, mRelayoutResult);
-            } else {
-                relayoutResult = mWindowSession.relayoutLegacy(mWindow, params,
-                        requestedWidth, requestedHeight, viewVisibility,
-                        insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
-                        mRelayoutSeq, mLastSyncSeqId, mTmpFrames, mPendingMergedConfiguration,
-                        mSurfaceControl, mTempInsets, mTempControls, mRelayoutBundle);
-            }
+            relayoutResult = mWindowSession.relayout(mWindow, params,
+                    requestedWidth, requestedHeight, viewVisibility,
+                    insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
+                    mRelayoutSeq, mLastSyncSeqId, mRelayoutResult);
             mRelayoutRequested = true;
 
+            onClientWindowFramesChanged(mTmpFrames);
+
             if (activityWindowInfoFlag() && mPendingActivityWindowInfo != null) {
-                ActivityWindowInfo outInfo = null;
-                if (windowSessionRelayoutInfo()) {
-                    outInfo = mRelayoutResult != null ? mRelayoutResult.activityWindowInfo : null;
-                } else {
-                    try {
-                        outInfo = mRelayoutBundle.getParcelable(
-                                IWindowSession.KEY_RELAYOUT_BUNDLE_ACTIVITY_WINDOW_INFO,
-                                ActivityWindowInfo.class);
-                        mRelayoutBundle.remove(
-                                IWindowSession.KEY_RELAYOUT_BUNDLE_ACTIVITY_WINDOW_INFO);
-                    } catch (IllegalStateException e) {
-                        Log.e(TAG, "Failed to get ActivityWindowInfo from relayout Bundle", e);
-                    }
-                }
+                final ActivityWindowInfo outInfo = mRelayoutResult.activityWindowInfo;
                 if (outInfo != null) {
                     mPendingActivityWindowInfo.set(outInfo);
                 }
             }
-            final int maybeSyncSeqId = windowSessionRelayoutInfo()
-                    ? mRelayoutResult.syncSeqId
-                    : mRelayoutBundle.getInt(IWindowSession.KEY_RELAYOUT_BUNDLE_SEQID);
+            final int maybeSyncSeqId = mRelayoutResult.syncSeqId;
             if (maybeSyncSeqId > 0) {
                 mSyncSeqId = maybeSyncSeqId;
             }
@@ -9303,13 +9363,10 @@
                 mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame);
                 mTranslator.translateRectInScreenToAppWindow(mTmpFrames.displayFrame);
                 mTranslator.translateRectInScreenToAppWindow(mTmpFrames.attachedFrame);
-                mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
-                mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls.get());
             }
             mInvCompatScale = 1f / mTmpFrames.compatScale;
             CompatibilityInfo.applyOverrideScaleIfNeeded(mPendingMergedConfiguration);
-            mInsetsController.onStateChanged(mTempInsets);
-            mInsetsController.onControlsChanged(mTempControls.get());
+            handleInsetsControlChanged(mTempInsets, mTempControls);
 
             mPendingAlwaysConsumeSystemBars =
                     (relayoutResult & RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0;
@@ -10007,6 +10064,7 @@
         public static final int FLAG_RESYNTHESIZED = 1 << 4;
         public static final int FLAG_UNHANDLED = 1 << 5;
         public static final int FLAG_MODIFIED_FOR_COMPATIBILITY = 1 << 6;
+        public static final int FLAG_PRE_IME_ONLY = 1 << 7;
 
         public QueuedInputEvent mNext;
 
@@ -10014,6 +10072,13 @@
         public InputEventReceiver mReceiver;
         public int mFlags;
 
+        public boolean forPreImeOnly() {
+            if ((mFlags & FLAG_PRE_IME_ONLY) != 0) {
+                return true;
+            }
+            return false;
+        }
+
         public boolean shouldSkipIme() {
             if ((mFlags & FLAG_DELIVER_POST_IME) != 0) {
                 return true;
@@ -10040,6 +10105,7 @@
             hasPrevious = flagToString("FINISHED_HANDLED", FLAG_FINISHED_HANDLED, hasPrevious, sb);
             hasPrevious = flagToString("RESYNTHESIZED", FLAG_RESYNTHESIZED, hasPrevious, sb);
             hasPrevious = flagToString("UNHANDLED", FLAG_UNHANDLED, hasPrevious, sb);
+            hasPrevious = flagToString("FLAG_PRE_IME_ONLY", FLAG_PRE_IME_ONLY, hasPrevious, sb);
             if (!hasPrevious) {
                 sb.append("0");
             }
@@ -10096,7 +10162,7 @@
     }
 
     @UnsupportedAppUsage
-    void enqueueInputEvent(InputEvent event,
+    QueuedInputEvent enqueueInputEvent(InputEvent event,
             InputEventReceiver receiver, int flags, boolean processImmediately) {
         QueuedInputEvent q = obtainQueuedInputEvent(event, receiver, flags);
 
@@ -10135,6 +10201,7 @@
         } else {
             scheduleProcessInputEvents();
         }
+        return q;
     }
 
     private void scheduleProcessInputEvents() {
@@ -11417,8 +11484,13 @@
         @Override
         public void insetsControlChanged(InsetsState insetsState,
                 InsetsSourceControl.Array activeControls) {
-            final boolean isFromInsetsControlChangeItem = mIsFromTransactionItem;
-            mIsFromTransactionItem = false;
+            final boolean isFromInsetsControlChangeItem;
+            if (insetsControlChangedItem()) {
+                isFromInsetsControlChangeItem = mIsFromTransactionItem;
+                mIsFromTransactionItem = false;
+            } else {
+                isFromInsetsControlChangeItem = false;
+            }
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor == null) {
                 if (isFromInsetsControlChangeItem) {
@@ -12456,29 +12528,45 @@
                             + "IWindow:%s Session:%s",
                     mOnBackInvokedDispatcher, mBasePackageName, mWindow, mWindowSession));
         }
-        mOnBackInvokedDispatcher.attachToWindow(mWindowSession, mWindow,
+        mOnBackInvokedDispatcher.attachToWindow(mWindowSession, mWindow, this,
                 mImeBackAnimationController);
     }
 
-    private void sendBackKeyEvent(int action) {
+    /**
+     * Sends {@link KeyEvent#ACTION_DOWN ACTION_DOWN} and {@link KeyEvent#ACTION_UP ACTION_UP}
+     * back key events
+     *
+     * @param preImeOnly whether the back events should be sent to the pre-ime stage only
+     * @return whether the event was handled (i.e. onKeyPreIme consumed it if preImeOnly=true)
+     */
+    public boolean injectBackKeyEvents(boolean preImeOnly) {
+        boolean consumed;
+        try {
+            processingBackKey(true);
+            sendBackKeyEvent(KeyEvent.ACTION_DOWN, preImeOnly);
+            consumed = sendBackKeyEvent(KeyEvent.ACTION_UP, preImeOnly);
+        } finally {
+            processingBackKey(false);
+        }
+        return consumed;
+    }
+
+    private boolean sendBackKeyEvent(int action, boolean preImeOnly) {
         long when = SystemClock.uptimeMillis();
         final KeyEvent ev = new KeyEvent(when, when, action,
                 KeyEvent.KEYCODE_BACK, 0 /* repeat */, 0 /* metaState */,
                 KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */,
                 KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
                 InputDevice.SOURCE_KEYBOARD);
-        enqueueInputEvent(ev, null /* receiver */, 0 /* flags */, true /* processImmediately */);
+        int flags = preImeOnly ? QueuedInputEvent.FLAG_PRE_IME_ONLY : 0;
+        QueuedInputEvent q = enqueueInputEvent(ev, null /* receiver */, flags,
+                true /* processImmediately */);
+        return (q.mFlags & QueuedInputEvent.FLAG_FINISHED_HANDLED) != 0;
     }
 
     private void registerCompatOnBackInvokedCallback() {
         mCompatOnBackInvokedCallback = () -> {
-            try {
-                processingBackKey(true);
-                sendBackKeyEvent(KeyEvent.ACTION_DOWN);
-                sendBackKeyEvent(KeyEvent.ACTION_UP);
-            } finally {
-                processingBackKey(false);
-            }
+            injectBackKeyEvents(/* preImeOnly */ false);
         };
         if (mOnBackInvokedDispatcher.hasImeOnBackInvokedDispatcher()) {
             Log.d(TAG, "Skip registering CompatOnBackInvokedCallback on IME dispatcher");
@@ -13054,7 +13142,7 @@
         if (frameRate <= 0) {
             return;
         }
-        if (frameRateCompatibility == FRAME_RATE_COMPATIBILITY_GTE) {
+        if (frameRateCompatibility == FRAME_RATE_COMPATIBILITY_GTE && !mIsPressedGesture) {
             mIsTouchBoosting = false;
             mIsFrameRateBoosting = false;
             if (!sToolkitFrameRateVelocityMappingReadOnlyFlagValue) {
diff --git a/core/java/android/view/ViewTraversalTracingStrings.java b/core/java/android/view/ViewTraversalTracingStrings.java
index 7dde87b..e95205b 100644
--- a/core/java/android/view/ViewTraversalTracingStrings.java
+++ b/core/java/android/view/ViewTraversalTracingStrings.java
@@ -58,6 +58,6 @@
         out.append(" ");
         out.append(className);
         v.appendId(out);
-        return out.substring(0, Math.min(out.length() - 1, Trace.MAX_SECTION_NAME_LEN - 1));
+        return out.substring(0, Math.min(out.length(), Trace.MAX_SECTION_NAME_LEN));
     }
 }
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index ae051f9..18006bb 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -6387,10 +6387,6 @@
      * The host is likely to be an {@link AttachedSurfaceControl} so the host token can be
      * retrieved via {@link AttachedSurfaceControl#getInputTransferToken()}.
      * <p><br>
-     * Only the window currently receiving touch is allowed to transfer the gesture so if the caller
-     * attempts to transfer touch gesture from a token that doesn't have touch, it will fail the
-     * transfer.
-     * <p><br>
      * When the host wants to transfer touch gesture to the embedded, it can retrieve the embedded
      * token via {@link SurfaceControlViewHost.SurfacePackage#getInputTransferToken()} or use the
      * value returned from either
@@ -6414,6 +6410,23 @@
      * arrives, input dispatcher will do a new round of hit testing. So, if the host window is
      * still the first thing that's being touched, then it will receive the new gesture again. It
      * will again be up to the host to transfer this new gesture to the embedded.
+     * <p><br>
+     * The call can fail for the following reasons:
+     * <ul>
+     * <li>
+     * Caller attempts to transfer touch gesture from a token that doesn't have an active gesture.
+     * </li>
+     * <li>
+     * The gesture is transferred to a token that is not associated with the transferFromToken. For
+     * example, if the caller transfers to a {@link SurfaceControlViewHost} not attached to the
+     * host window via {@link SurfaceView#setChildSurfacePackage(SurfacePackage)}.
+     * </li>
+     * <li>
+     * The active gesture completes before the transfer is complete, such as in the case of a
+     * fling.
+     * </li>
+     * </ul>
+     * <p>
      *
      * @param transferFromToken the InputTransferToken for the currently active gesture
      * @param transferToToken   the InputTransferToken to transfer the gesture to.
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index d7d764b..55f22a6 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -23,7 +23,6 @@
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.Region;
-import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
@@ -349,18 +348,6 @@
     }
 
     @Override
-    public int relayoutLegacy(IWindow window, WindowManager.LayoutParams inAttrs,
-            int requestedWidth, int requestedHeight, int viewFlags, int flags, int seq,
-            int lastSyncSeqId, ClientWindowFrames outFrames,
-            MergedConfiguration outMergedConfiguration, SurfaceControl outSurfaceControl,
-            InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls,
-            Bundle outSyncSeqIdBundle) {
-        return relayoutInner(window, inAttrs, requestedWidth, requestedHeight, viewFlags, flags,
-                seq, lastSyncSeqId, outFrames, outMergedConfiguration, outSurfaceControl,
-                outInsetsState, outActiveControls);
-    }
-
-    @Override
     public int relayout(IWindow window, WindowManager.LayoutParams inAttrs,
             int requestedWidth, int requestedHeight, int viewFlags, int flags, int seq,
             int lastSyncSeqId, WindowRelayoutResult outRelayoutResult) {
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 3fc9ebc..a4cea33 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -19,6 +19,8 @@
 import static android.accessibilityservice.AccessibilityServiceInfo.FLAG_ENABLE_ACCESSIBILITY_VOLUME;
 import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
 
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
+
 import android.Manifest;
 import android.accessibilityservice.AccessibilityService;
 import android.accessibilityservice.AccessibilityServiceInfo;
@@ -62,6 +64,7 @@
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.SparseArray;
+import android.view.Display;
 import android.view.IWindow;
 import android.view.SurfaceControl;
 import android.view.View;
@@ -69,6 +72,7 @@
 
 import com.android.internal.R;
 import com.android.internal.accessibility.common.ShortcutConstants;
+import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.IntPair;
 
@@ -1565,7 +1569,7 @@
     @SystemApi
     @RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY)
     public void performAccessibilityShortcut() {
-        performAccessibilityShortcut(null);
+        performAccessibilityShortcut(Display.DEFAULT_DISPLAY, HARDWARE, null);
     }
 
     /**
@@ -1577,7 +1581,8 @@
      * @hide
      */
     @RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY)
-    public void performAccessibilityShortcut(@Nullable String targetName) {
+    public void performAccessibilityShortcut(
+            int displayId, @UserShortcutType int shortcutType, @Nullable String targetName) {
         final IAccessibilityManager service;
         synchronized (mLock) {
             service = getServiceLocked();
@@ -1586,7 +1591,7 @@
             }
         }
         try {
-            service.performAccessibilityShortcut(targetName);
+            service.performAccessibilityShortcut(displayId, shortcutType, targetName);
         } catch (RemoteException re) {
             Log.e(LOG_TAG, "Error performing accessibility shortcut. ", re);
         }
@@ -1602,7 +1607,7 @@
      */
     @RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY)
     public void enableShortcutsForTargets(boolean enable,
-            @ShortcutConstants.UserShortcutType int shortcutTypes, @NonNull Set<String> targets,
+            @UserShortcutType int shortcutTypes, @NonNull Set<String> targets,
             @UserIdInt int userId) {
         final IAccessibilityManager service;
         synchronized (mLock) {
@@ -1817,7 +1822,7 @@
     @RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY)
     @NonNull
     public List<String> getAccessibilityShortcutTargets(
-            @ShortcutConstants.UserShortcutType int shortcutType) {
+            @UserShortcutType int shortcutType) {
         final IAccessibilityManager service;
         synchronized (mLock) {
             service = getServiceLocked();
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
index 749f977..c92593f 100644
--- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
@@ -97,7 +97,7 @@
     /**
      * Window type: A system window that has the function to control an associated window.
      */
-    @FlaggedApi(Flags.FLAG_ADD_TYPE_WINDOW_CONTROL)
+    @FlaggedApi(Flags.FLAG_ENABLE_TYPE_WINDOW_CONTROL)
     public static final int TYPE_WINDOW_CONTROL = 7;
 
     /* Special values for window IDs */
@@ -880,7 +880,7 @@
      * @hide
      */
     public static String typeToString(int type) {
-        if (Flags.addTypeWindowControl() && type == TYPE_WINDOW_CONTROL) {
+        if (Flags.enableTypeWindowControl() && type == TYPE_WINDOW_CONTROL) {
             return "TYPE_WINDOW_CONTROL";
         }
 
diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl
index cd11314..72a1fe4 100644
--- a/core/java/android/view/accessibility/IAccessibilityManager.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl
@@ -92,7 +92,7 @@
     void notifyAccessibilityButtonVisibilityChanged(boolean available);
 
     @EnforcePermission("MANAGE_ACCESSIBILITY")
-    void performAccessibilityShortcut(String targetName);
+    void performAccessibilityShortcut(int displayId, int shortcutType, String targetName);
 
     @EnforcePermission("MANAGE_ACCESSIBILITY")
     List<String> getAccessibilityShortcutTargets(int shortcutType);
diff --git a/core/java/android/view/accessibility/a11ychecker/AccessibilityNodePathBuilder.java b/core/java/android/view/accessibility/a11ychecker/AccessibilityNodePathBuilder.java
new file mode 100644
index 0000000..2996dde
--- /dev/null
+++ b/core/java/android/view/accessibility/a11ychecker/AccessibilityNodePathBuilder.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.a11ychecker;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+/**
+ * Utility class to create developer-friendly {@link AccessibilityNodeInfo} path Strings for use
+ * in reporting AccessibilityCheck results.
+ *
+ * @hide
+ */
+public final class AccessibilityNodePathBuilder {
+
+    /**
+     * Returns the path of the node within its accessibility hierarchy starting from the root node
+     * down to the given node itself, and prefixed by the package name. This path is not guaranteed
+     * to be unique. This can return null in case the node's hierarchy changes while scanning.
+     *
+     * <p>Each element in the path is represented by its View ID resource name, when available, or
+     * the
+     * simple class name if not. The path also includes the index of each child node relative to
+     * its
+     * parent. See {@link AccessibilityNodeInfo#getViewIdResourceName()}.
+     *
+     * <p>For example,
+     * "com.example.app:RootElementClassName/parent_resource_name[1]/TargetElementClassName[3]"
+     * indicates the element has type {@code TargetElementClassName}, and is the third child of an
+     * element with the resource name {@code parent_resource_name}, which is the first child of an
+     * element of type {@code RootElementClassName}.
+     *
+     * <p>This format is consistent with elements paths in Pre-Launch Reports and the Accessibility
+     * Scanner, starting from the window's root node instead of the first resource name.
+     * TODO (b/344607035): link to ClusteringUtils when AATF is merged in main.
+     */
+    public static @Nullable String createNodePath(@NonNull AccessibilityNodeInfo nodeInfo) {
+        StringBuilder resourceIdBuilder = getNodePathBuilder(nodeInfo);
+        return resourceIdBuilder == null ? null : String.valueOf(nodeInfo.getPackageName()) + ':'
+                + resourceIdBuilder;
+    }
+
+    private static @Nullable StringBuilder getNodePathBuilder(AccessibilityNodeInfo nodeInfo) {
+        AccessibilityNodeInfo parent = nodeInfo.getParent();
+        if (parent == null) {
+            return new StringBuilder(getShortUiElementName(nodeInfo));
+        }
+        StringBuilder parentNodePath = getNodePathBuilder(parent);
+        if (parentNodePath == null) {
+            return null;
+        }
+        int childCount = parent.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            if (!nodeInfo.equals(parent.getChild(i))) {
+                continue;
+            }
+            CharSequence uiElementName = getShortUiElementName(nodeInfo);
+            if (uiElementName != null) {
+                parentNodePath.append('/').append(uiElementName).append('[').append(i + 1).append(
+                        ']');
+            } else {
+                parentNodePath.append(":nth-child(").append(i + 1).append(')');
+            }
+            return parentNodePath;
+        }
+        return null;
+    }
+
+    //Returns the part of the element's View ID resource name after the qualifier
+    // "package_name:id/"  or the last '/', when available. Otherwise, returns the element's
+    // simple class name.
+    private static CharSequence getShortUiElementName(AccessibilityNodeInfo nodeInfo) {
+        String viewIdResourceName = nodeInfo.getViewIdResourceName();
+        if (viewIdResourceName != null) {
+            String idQualifier = ":id/";
+            int idQualifierStartIndex = viewIdResourceName.indexOf(idQualifier);
+            int unqualifiedNameStartIndex = idQualifierStartIndex == -1 ? 0
+                    : (idQualifierStartIndex + idQualifier.length());
+            return viewIdResourceName.substring(unqualifiedNameStartIndex);
+        }
+        return getSimpleClassName(nodeInfo);
+    }
+
+    private static CharSequence getSimpleClassName(AccessibilityNodeInfo nodeInfo) {
+        CharSequence name = nodeInfo.getClassName();
+        for (int i = name.length() - 1; i > 0; i--) {
+            char ithChar = name.charAt(i);
+            if (ithChar == '.' || ithChar == '$') {
+                return name.subSequence(i + 1, name.length());
+            }
+        }
+        return name;
+    }
+
+    private AccessibilityNodePathBuilder() {
+    }
+}
diff --git a/core/java/android/view/accessibility/a11ychecker/Android.bp b/core/java/android/view/accessibility/a11ychecker/Android.bp
new file mode 100644
index 0000000..e5a577c
--- /dev/null
+++ b/core/java/android/view/accessibility/a11ychecker/Android.bp
@@ -0,0 +1,7 @@
+java_library_static {
+    name: "A11yChecker",
+    srcs: [
+        "*.java",
+    ],
+    visibility: ["//visibility:public"],
+}
diff --git a/core/java/android/view/accessibility/a11ychecker/OWNERS b/core/java/android/view/accessibility/a11ychecker/OWNERS
new file mode 100644
index 0000000..d1e7986
--- /dev/null
+++ b/core/java/android/view/accessibility/a11ychecker/OWNERS
@@ -0,0 +1,4 @@
+# Android Accessibility Framework owners
+include /services/accessibility/OWNERS
+
+yaraabdullatif@google.com
diff --git a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
index 64cf40b..d0bc57b 100644
--- a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
+++ b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
@@ -136,9 +136,8 @@
 
 flag {
     namespace: "accessibility"
-    name: "add_type_window_control"
+    name: "enable_type_window_control"
     is_exported: true
-    is_fixed_read_only: true
     description: "adds new TYPE_WINDOW_CONTROL to AccessibilityWindowInfo for detecting Window Decorations"
     bug: "320445550"
 }
diff --git a/core/java/android/view/autofill/AutofillFeatureFlags.java b/core/java/android/view/autofill/AutofillFeatureFlags.java
index 199a69a..5b1c7d5 100644
--- a/core/java/android/view/autofill/AutofillFeatureFlags.java
+++ b/core/java/android/view/autofill/AutofillFeatureFlags.java
@@ -256,6 +256,21 @@
             "ignore_relayout_auth_pending";
 
     /**
+     * Fixes to handle apps relaying out, and causing problems for autofill.
+     *
+     * @hide
+     */
+    public static final String DEVICE_CONFIG_ENABLE_RELAYOUT = "enable_relayout";
+
+    /**
+     * Enable relative location of views for fingerprinting for relayout.
+     *
+     * @hide
+     */
+    public static final String DEVICE_CONFIG_ENABLE_RELATIVE_LOCATION_FOR_RELAYOUT =
+            "enable_relative_location_for_relayout";
+
+    /**
      * Bugfix flag, Autofill should only fill in value from current session.
      *
      * See frameworks/base/services/autofill/bugfixes.aconfig#fill_fields_from_current_session_only
@@ -543,6 +558,22 @@
                 false);
     }
 
+    /** @hide */
+    public static boolean enableRelayoutFixes() {
+        return DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_AUTOFILL,
+                DEVICE_CONFIG_ENABLE_RELAYOUT,
+                true);
+    }
+
+    /** @hide */
+    public static boolean enableRelativeLocationForRelayout() {
+        return DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_AUTOFILL,
+                DEVICE_CONFIG_ENABLE_RELATIVE_LOCATION_FOR_RELAYOUT,
+                false);
+    }
+
     /** @hide **/
     public static boolean shouldFillFieldsFromCurrentSessionOnly() {
         return DeviceConfig.getBoolean(
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 0d4c556..515ed0e 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -748,7 +748,16 @@
 
     // Controls logic around apps changing some properties of their views when activity loses
     // focus due to autofill showing biometric activity, password manager, or password breach check.
-    private boolean mRelayoutFix;
+    // Deprecated. TODO: Remove it after ramp of new solution.
+    private boolean mRelayoutFixDeprecated;
+
+    // Controls logic around apps changing some properties of their views when activity loses
+    // focus due to autofill showing biometric activity, password manager, or password breach check.
+    private final boolean mRelayoutFix;
+
+    // Controls logic around apps changing some properties of their views when activity loses
+    // focus due to autofill showing biometric activity, password manager, or password breach check.
+    private final boolean mRelativePositionForRelayout;
 
     // Indicates whether the credman integration is enabled.
     private final boolean mIsCredmanIntegrationEnabled;
@@ -978,11 +987,31 @@
         mShouldIncludeInvisibleViewInAssistStructure =
                 AutofillFeatureFlags.shouldIncludeInvisibleViewInAssistStructure();
 
-        mRelayoutFix = AutofillFeatureFlags.shouldIgnoreRelayoutWhenAuthPending();
+        mRelayoutFixDeprecated = AutofillFeatureFlags.shouldIgnoreRelayoutWhenAuthPending();
+        mRelayoutFix = AutofillFeatureFlags.enableRelayoutFixes();
+        mRelativePositionForRelayout = AutofillFeatureFlags.enableRelativeLocationForRelayout();
         mIsCredmanIntegrationEnabled = Flags.autofillCredmanIntegration();
     }
 
     /**
+     * Whether to apply relayout fixes.
+     *
+     * @hide
+     */
+    public boolean isRelayoutFixEnabled() {
+        return mRelayoutFix;
+    }
+
+    /**
+     * Whether to use relative positions and locations of the views for disambiguation.
+     *
+     * @hide
+     */
+    public boolean isRelativePositionForRelayoutEnabled() {
+        return mRelativePositionForRelayout;
+    }
+
+    /**
      * Whether to apply heuristic check on important views before triggering fill request
      *
      * @hide
@@ -1779,7 +1808,7 @@
                 }
                 return;
             }
-            if (mRelayoutFix && mState == STATE_PENDING_AUTHENTICATION) {
+            if (mRelayoutFixDeprecated && mState == STATE_PENDING_AUTHENTICATION) {
                 if (sVerbose) {
                     Log.v(TAG, "notifyViewVisibilityChanged(): ignoring in auth pending mode");
                 }
@@ -2917,7 +2946,7 @@
             Intent fillInIntent, boolean authenticateInline) {
         synchronized (mLock) {
             if (sessionId == mSessionId) {
-                if (mRelayoutFix) {
+                if (mRelayoutFixDeprecated) {
                     mState = STATE_PENDING_AUTHENTICATION;
                 }
                 final AutofillClient client = getClient();
@@ -3778,7 +3807,7 @@
 
     @GuardedBy("mLock")
     private boolean isPendingAuthenticationLocked() {
-        return mRelayoutFix && mState == STATE_PENDING_AUTHENTICATION;
+        return mRelayoutFixDeprecated && mState == STATE_PENDING_AUTHENTICATION;
     }
 
     @GuardedBy("mLock")
@@ -4322,6 +4351,13 @@
                         addToSet(mInvisibleDialogTrackedIds, id);
                     }
                 }
+            } else {
+                if (sDebug) {
+                    // isClientVisibleForAutofillLocked() is checking whether
+                    // activity has stopped under the hood
+                    Log.d(TAG, "notifyViewVisibilityChangedLocked(): ignoring "
+                            + "view visibility change since activity has stopped");
+                }
             }
 
             if (mIsTrackedSaveView && mVisibleTrackedIds.isEmpty()) {
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index d74867c..724e8fa 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -18,7 +18,6 @@
 import static android.view.contentcapture.ContentCaptureHelper.sDebug;
 import static android.view.contentcapture.ContentCaptureHelper.sVerbose;
 import static android.view.contentcapture.ContentCaptureHelper.toSet;
-import static android.view.contentcapture.flags.Flags.runOnBackgroundThreadEnabled;
 
 import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
@@ -602,26 +601,16 @@
     public ContentCaptureSession getMainContentCaptureSession() {
         synchronized (mLock) {
             if (mMainSession == null) {
-                mMainSession = prepareMainSession();
-                if (sVerbose) Log.v(TAG, "getMainContentCaptureSession(): created " + mMainSession);
-            }
-            return mMainSession;
-        }
-    }
-
-    @NonNull
-    @GuardedBy("mLock")
-    private ContentCaptureSession prepareMainSession() {
-        if (runOnBackgroundThreadEnabled()) {
-            return new MainContentCaptureSessionV2(
+                mMainSession = new MainContentCaptureSession(
                     mContext,
                     this,
                     prepareUiHandler(),
                     prepareContentCaptureHandler(),
                     mService
-            );
-        } else {
-            return new MainContentCaptureSession(mContext, this, prepareUiHandler(), mService);
+                );
+                if (sVerbose) Log.v(TAG, "getMainContentCaptureSession(): created " + mMainSession);
+            }
+            return mMainSession;
         }
     }
 
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index a90c94e..eb827dd 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -69,16 +69,13 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.NoSuchElementException;
+import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
-// TODO(b/309411951): Replace V2 as the only main session once the experiment is done.
 /**
  * Main session associated with a context.
  *
- * <p>This session is created when the activity starts and finished when it stops; clients can use
- * it to create children activities.
- *
  * @hide
  */
 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
@@ -107,7 +104,10 @@
     private final ContentCaptureManager mManager;
 
     @NonNull
-    private final Handler mHandler;
+    private final Handler mUiHandler;
+
+    @NonNull
+    private final Handler mContentCaptureHandler;
 
     /**
      * Interface to the system_server binder object - it's only used to start the session (and
@@ -142,6 +142,18 @@
     public ComponentName mComponentName;
 
     /**
+     * Thread-safe queue of events held to be processed as a batch.
+     *
+     * Because it is not guaranteed that the events will be enqueued from a single thread, the
+     * implementation must be thread-safe to prevent unexpected behaviour.
+     *
+     * @hide
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    @NonNull
+    public final ConcurrentLinkedQueue<ContentCaptureEvent> mEventProcessQueue;
+
+    /**
      * List of events held to be sent to the {@link ContentCaptureService} as a batch.
      *
      * @hide
@@ -200,14 +212,14 @@
                 binder = resultData.getBinder(EXTRA_BINDER);
                 if (binder == null) {
                     Log.wtf(TAG, "No " + EXTRA_BINDER + " extra result");
-                    mainSession.mHandler.post(() -> mainSession.resetSession(
+                    mainSession.runOnContentCaptureThread(() -> mainSession.resetSession(
                             STATE_DISABLED | STATE_INTERNAL_ERROR));
                     return;
                 }
             } else {
                 binder = null;
             }
-            mainSession.mHandler.post(() ->
+            mainSession.runOnContentCaptureThread(() ->
                     mainSession.onSessionStarted(resultCode, binder));
         }
     }
@@ -217,17 +229,21 @@
     public MainContentCaptureSession(
             @NonNull ContentCaptureManager.StrippedContext context,
             @NonNull ContentCaptureManager manager,
-            @NonNull Handler handler,
+            @NonNull Handler uiHandler,
+            @NonNull Handler contentCaptureHandler,
             @NonNull IContentCaptureManager systemServerInterface) {
         mContext = context;
         mManager = manager;
-        mHandler = handler;
+        mUiHandler = uiHandler;
+        mContentCaptureHandler = contentCaptureHandler;
         mSystemServerInterface = systemServerInterface;
 
         final int logHistorySize = mManager.mOptions.logHistorySize;
         mFlushHistory = logHistorySize > 0 ? new LocalLog(logHistorySize) : null;
 
         mSessionStateReceiver = new SessionStateReceiver(this);
+
+        mEventProcessQueue = new ConcurrentLinkedQueue<>();
     }
 
     @Override
@@ -248,7 +264,13 @@
     @Override
     void start(@NonNull IBinder token, @NonNull IBinder shareableActivityToken,
             @NonNull ComponentName component, int flags) {
-        checkOnUiThread();
+        runOnContentCaptureThread(
+                () -> startImpl(token, shareableActivityToken, component, flags));
+    }
+
+    private void startImpl(@NonNull IBinder token, @NonNull IBinder shareableActivityToken,
+               @NonNull ComponentName component, int flags) {
+        checkOnContentCaptureThread();
         if (!isContentCaptureEnabled()) return;
 
         if (sVerbose) {
@@ -282,17 +304,15 @@
             Log.w(TAG, "Error starting session for " + component.flattenToShortString() + ": " + e);
         }
     }
-
     @Override
     void onDestroy() {
-        mHandler.removeMessages(MSG_FLUSH);
-        mHandler.post(() -> {
+        clearAndRunOnContentCaptureThread(() -> {
             try {
                 flush(FLUSH_REASON_SESSION_FINISHED);
             } finally {
                 destroySession();
             }
-        });
+        }, MSG_FLUSH);
     }
 
     /**
@@ -305,7 +325,7 @@
      */
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
     public void onSessionStarted(int resultCode, @Nullable IBinder binder) {
-        checkOnUiThread();
+        checkOnContentCaptureThread();
         if (binder != null) {
             mDirectServiceInterface = IContentCaptureDirectManager.Stub.asInterface(binder);
             mDirectServiceVulture = () -> {
@@ -324,7 +344,7 @@
             mContentProtectionEventProcessor =
                     new ContentProtectionEventProcessor(
                             mManager.getContentProtectionEventBuffer(),
-                            mHandler,
+                            mContentCaptureHandler,
                             mSystemServerInterface,
                             mComponentName.getPackageName(),
                             mManager.mOptions.contentProtectionOptions);
@@ -354,7 +374,7 @@
     }
 
     private void sendEvent(@NonNull ContentCaptureEvent event, boolean forceFlush) {
-        checkOnUiThread();
+        checkOnContentCaptureThread();
         final int eventType = event.getType();
         if (sVerbose) Log.v(TAG, "handleSendEvent(" + getDebugState() + "): " + event);
         if (!hasStarted() && eventType != ContentCaptureEvent.TYPE_SESSION_STARTED
@@ -398,14 +418,14 @@
     }
 
     private void sendContentProtectionEvent(@NonNull ContentCaptureEvent event) {
-        checkOnUiThread();
+        checkOnContentCaptureThread();
         if (mContentProtectionEventProcessor != null) {
             mContentProtectionEventProcessor.processEvent(event);
         }
     }
 
     private void sendContentCaptureEvent(@NonNull ContentCaptureEvent event, boolean forceFlush) {
-        checkOnUiThread();
+        checkOnContentCaptureThread();
         final int eventType = event.getType();
         final int maxBufferSize = mManager.mOptions.maxBufferSize;
         if (mEvents == null) {
@@ -540,12 +560,12 @@
     }
 
     private boolean hasStarted() {
-        checkOnUiThread();
+        checkOnContentCaptureThread();
         return mState != UNKNOWN_STATE;
     }
 
     private void scheduleFlush(@FlushReason int reason, boolean checkExisting) {
-        checkOnUiThread();
+        checkOnContentCaptureThread();
         if (sVerbose) {
             Log.v(TAG, "handleScheduleFlush(" + getDebugState(reason)
                     + ", checkExisting=" + checkExisting);
@@ -562,9 +582,9 @@
                     + "when disabled. events=" + (mEvents == null ? null : mEvents.size()));
             return;
         }
-        if (checkExisting && mHandler.hasMessages(MSG_FLUSH)) {
+        if (checkExisting && mContentCaptureHandler.hasMessages(MSG_FLUSH)) {
             // "Renew" the flush message by removing the previous one
-            mHandler.removeMessages(MSG_FLUSH);
+            mContentCaptureHandler.removeMessages(MSG_FLUSH);
         }
 
         final int flushFrequencyMs;
@@ -586,12 +606,12 @@
                     + flushFrequencyMs + "ms: " + TimeUtils.logTimeOfDay(mNextFlush));
         }
         // Post using a Runnable directly to trim a few μs from PooledLambda.obtainMessage()
-        mHandler.postDelayed(() ->
+        mContentCaptureHandler.postDelayed(() ->
                 flushIfNeeded(reason), MSG_FLUSH, flushFrequencyMs);
     }
 
     private void flushIfNeeded(@FlushReason int reason) {
-        checkOnUiThread();
+        checkOnContentCaptureThread();
         if (mEvents == null || mEvents.isEmpty()) {
             if (sVerbose) Log.v(TAG, "Nothing to flush");
             return;
@@ -603,7 +623,11 @@
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
     @Override
     public void flush(@FlushReason int reason) {
-        checkOnUiThread();
+        runOnContentCaptureThread(() -> flushImpl(reason));
+    }
+
+    private void flushImpl(@FlushReason int reason) {
+        checkOnContentCaptureThread();
         if (mEvents == null || mEvents.size() == 0) {
             if (sVerbose) {
                 Log.v(TAG, "Don't flush for empty event buffer.");
@@ -626,7 +650,7 @@
                 Log.v(TAG, "handleForceFlush(" + getDebugState(reason) + "): hold your horses, "
                         + "client not ready: " + mEvents);
             }
-            if (!mHandler.hasMessages(MSG_FLUSH)) {
+            if (!mContentCaptureHandler.hasMessages(MSG_FLUSH)) {
                 scheduleFlush(reason, /* checkExisting= */ false);
             }
             return;
@@ -652,7 +676,7 @@
             mFlushHistory.log(logRecord);
         }
         try {
-            mHandler.removeMessages(MSG_FLUSH);
+            mContentCaptureHandler.removeMessages(MSG_FLUSH);
 
             final ParceledListSlice<ContentCaptureEvent> events = clearEvents();
             mDirectServiceInterface.sendEvents(events, reason, mManager.mOptions);
@@ -672,7 +696,7 @@
      */
     @NonNull
     private ParceledListSlice<ContentCaptureEvent> clearEvents() {
-        checkOnUiThread();
+        checkOnContentCaptureThread();
         // NOTE: we must save a reference to the current mEvents and then set it to to null,
         // otherwise clearing it would clear it in the receiving side if the service is also local.
         if (mEvents == null) {
@@ -687,7 +711,7 @@
     /** hide */
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
     public void destroySession() {
-        checkOnUiThread();
+        checkOnContentCaptureThread();
         if (sDebug) {
             Log.d(TAG, "Destroying session (ctx=" + mContext + ", id=" + mId + ") with "
                     + (mEvents == null ? 0 : mEvents.size()) + " event(s) for "
@@ -707,6 +731,7 @@
         }
         mDirectServiceInterface = null;
         mContentProtectionEventProcessor = null;
+        mEventProcessQueue.clear();
     }
 
     // TODO(b/122454205): once we support multiple sessions, we might need to move some of these
@@ -714,7 +739,7 @@
     /** @hide */
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
     public void resetSession(int newState) {
-        checkOnUiThread();
+        checkOnContentCaptureThread();
         if (sVerbose) {
             Log.v(TAG, "handleResetSession(" + getActivityName() + "): from "
                     + getStateAsString(mState) + " to " + getStateAsString(newState));
@@ -735,21 +760,21 @@
         }
         mDirectServiceInterface = null;
         mContentProtectionEventProcessor = null;
-        mHandler.removeMessages(MSG_FLUSH);
+        mContentCaptureHandler.removeMessages(MSG_FLUSH);
     }
 
     @Override
     void internalNotifyViewAppeared(int sessionId, @NonNull ViewStructureImpl node) {
         final ContentCaptureEvent event = new ContentCaptureEvent(sessionId, TYPE_VIEW_APPEARED)
                 .setViewNode(node.mNode);
-        mHandler.post(() -> sendEvent(event));
+        enqueueEvent(event);
     }
 
     @Override
     void internalNotifyViewDisappeared(int sessionId, @NonNull AutofillId id) {
         final ContentCaptureEvent event = new ContentCaptureEvent(sessionId, TYPE_VIEW_DISAPPEARED)
                 .setAutofillId(id);
-        mHandler.post(() -> sendEvent(event));
+        enqueueEvent(event);
     }
 
     @Override
@@ -780,7 +805,7 @@
                 .setAutofillId(id).setText(eventText)
                 .setComposingIndex(composingStart, composingEnd)
                 .setSelectionIndex(startIndex, endIndex);
-        mHandler.post(() -> sendEvent(event));
+        enqueueEvent(event);
     }
 
     @Override
@@ -788,7 +813,7 @@
         final ContentCaptureEvent event =
                 new ContentCaptureEvent(sessionId, TYPE_VIEW_INSETS_CHANGED)
                         .setInsets(viewInsets);
-        mHandler.post(() -> sendEvent(event));
+        enqueueEvent(event);
     }
 
     @Override
@@ -798,19 +823,19 @@
         final boolean forceFlush = disableFlush ? !started : FORCE_FLUSH;
 
         final ContentCaptureEvent event = new ContentCaptureEvent(sessionId, type);
-        mHandler.post(() -> sendEvent(event, FORCE_FLUSH));
+        enqueueEvent(event, forceFlush);
     }
 
     @Override
     public void internalNotifySessionResumed() {
         final ContentCaptureEvent event = new ContentCaptureEvent(mId, TYPE_SESSION_RESUMED);
-        mHandler.post(() -> sendEvent(event, FORCE_FLUSH));
+        enqueueEvent(event, FORCE_FLUSH);
     }
 
     @Override
     public void internalNotifySessionPaused() {
         final ContentCaptureEvent event = new ContentCaptureEvent(mId, TYPE_SESSION_PAUSED);
-        mHandler.post(() -> sendEvent(event, FORCE_FLUSH));
+        enqueueEvent(event, FORCE_FLUSH);
     }
 
     @Override
@@ -818,12 +843,16 @@
         return super.isContentCaptureEnabled() && mManager.isContentCaptureEnabled();
     }
 
-    @Override
+    // Called by ContentCaptureManager.isContentCaptureEnabled
     boolean isDisabled() {
         return mDisabled.get();
     }
 
-    @Override
+    /**
+     * Sets the disabled state of content capture.
+     *
+     * @return whether disabled state was changed.
+     */
     boolean setDisabled(boolean disabled) {
         return mDisabled.compareAndSet(!disabled, disabled);
     }
@@ -835,7 +864,7 @@
                 new ContentCaptureEvent(childSessionId, TYPE_SESSION_STARTED)
                         .setParentSessionId(parentSessionId)
                         .setClientContext(clientContext);
-        mHandler.post(() -> sendEvent(event, FORCE_FLUSH));
+        enqueueEvent(event, FORCE_FLUSH);
     }
 
     @Override
@@ -843,14 +872,14 @@
         final ContentCaptureEvent event =
                 new ContentCaptureEvent(childSessionId, TYPE_SESSION_FINISHED)
                         .setParentSessionId(parentSessionId);
-        mHandler.post(() -> sendEvent(event, FORCE_FLUSH));
+        enqueueEvent(event, FORCE_FLUSH);
     }
 
     @Override
     void internalNotifyContextUpdated(int sessionId, @Nullable ContentCaptureContext context) {
         final ContentCaptureEvent event = new ContentCaptureEvent(sessionId, TYPE_CONTEXT_UPDATED)
                 .setClientContext(context);
-        mHandler.post(() -> sendEvent(event, FORCE_FLUSH));
+        enqueueEvent(event, FORCE_FLUSH);
     }
 
     @Override
@@ -858,18 +887,97 @@
         final ContentCaptureEvent event =
                 new ContentCaptureEvent(sessionId, TYPE_WINDOW_BOUNDS_CHANGED)
                         .setBounds(bounds);
-        mHandler.post(() -> sendEvent(event));
+        enqueueEvent(event);
+    }
+
+    private List<ContentCaptureEvent> clearBufferEvents() {
+        final ArrayList<ContentCaptureEvent> bufferEvents = new ArrayList<>();
+        ContentCaptureEvent event;
+        while ((event = mEventProcessQueue.poll()) != null) {
+            bufferEvents.add(event);
+        }
+        return bufferEvents;
+    }
+
+    private void enqueueEvent(@NonNull final ContentCaptureEvent event) {
+        enqueueEvent(event, /* forceFlush */ false);
+    }
+
+    /**
+     * Enqueue the event into {@code mEventProcessBuffer} if it is not an urgent request. Otherwise,
+     * clear the buffer events then starting sending out current event.
+     */
+    private void enqueueEvent(@NonNull final ContentCaptureEvent event, boolean forceFlush) {
+        if (forceFlush || mEventProcessQueue.size() >= mManager.mOptions.maxBufferSize - 1) {
+            // The buffer events are cleared in the same thread first to prevent new events
+            // being added during the time of context switch. This would disrupt the sequence
+            // of events.
+            final List<ContentCaptureEvent> batchEvents = clearBufferEvents();
+            runOnContentCaptureThread(() -> {
+                for (int i = 0; i < batchEvents.size(); i++) {
+                    sendEvent(batchEvents.get(i));
+                }
+                sendEvent(event, /* forceFlush= */ true);
+            });
+        } else {
+            mEventProcessQueue.offer(event);
+        }
     }
 
     @Override
     public void notifyContentCaptureEvents(
             @NonNull SparseArray<ArrayList<Object>> contentCaptureEvents) {
-        notifyContentCaptureEventsImpl(contentCaptureEvents);
+        runOnUiThread(() -> {
+            prepareViewStructures(contentCaptureEvents);
+            runOnContentCaptureThread(() ->
+                    notifyContentCaptureEventsImpl(contentCaptureEvents));
+        });
+    }
+
+    /**
+     * Traverse events and pre-process {@link View} events to {@link ViewStructureSession} events.
+     * If a {@link View} event is invalid, an empty {@link ViewStructureSession} will still be
+     * provided.
+     */
+    private void prepareViewStructures(
+            @NonNull SparseArray<ArrayList<Object>> contentCaptureEvents) {
+        for (int i = 0; i < contentCaptureEvents.size(); i++) {
+            int sessionId = contentCaptureEvents.keyAt(i);
+            ArrayList<Object> events = contentCaptureEvents.valueAt(i);
+            for_each_event: for (int j = 0; j < events.size(); j++) {
+                Object event = events.get(j);
+                if (event instanceof View) {
+                    View view = (View) event;
+                    ContentCaptureSession session = view.getContentCaptureSession();
+                    ViewStructureSession structureSession = new ViewStructureSession();
+
+                    // Replace the View event with ViewStructureSession no matter the data is
+                    // available or not. This is to ensure the sequence of the events are still
+                    // the same. Calls to notifyViewAppeared will check the availability later.
+                    events.set(j, structureSession);
+                    if (session == null) {
+                        Log.w(TAG, "no content capture session on view: " + view);
+                        continue for_each_event;
+                    }
+                    int actualId = session.getId();
+                    if (actualId != sessionId) {
+                        Log.w(TAG, "content capture session mismatch for view (" + view
+                                + "): was " + sessionId + " before, it's " + actualId + " now");
+                        continue for_each_event;
+                    }
+                    ViewStructure structure = session.newViewStructure(view);
+                    view.onProvideContentCaptureStructure(structure, /* flags= */ 0);
+
+                    structureSession.setSession(session);
+                    structureSession.setStructure(structure);
+                }
+            }
+        }
     }
 
     private void notifyContentCaptureEventsImpl(
             @NonNull SparseArray<ArrayList<Object>> contentCaptureEvents) {
-        checkOnUiThread();
+        checkOnContentCaptureThread();
         try {
             if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
                 Trace.traceBegin(Trace.TRACE_TAG_VIEW, "notifyContentCaptureEvents");
@@ -882,22 +990,8 @@
                     Object event = events.get(j);
                     if (event instanceof AutofillId) {
                         internalNotifyViewDisappeared(sessionId, (AutofillId) event);
-                    } else if (event instanceof View) {
-                        View view = (View) event;
-                        ContentCaptureSession session = view.getContentCaptureSession();
-                        if (session == null) {
-                            Log.w(TAG, "no content capture session on view: " + view);
-                            continue for_each_event;
-                        }
-                        int actualId = session.getId();
-                        if (actualId != sessionId) {
-                            Log.w(TAG, "content capture session mismatch for view (" + view
-                                    + "): was " + sessionId + " before, it's " + actualId + " now");
-                            continue for_each_event;
-                        }
-                        ViewStructure structure = session.newViewStructure(view);
-                        view.onProvideContentCaptureStructure(structure, /* flags= */ 0);
-                        session.notifyViewAppeared(structure);
+                    } else if (event instanceof ViewStructureSession viewStructureSession) {
+                        viewStructureSession.notifyViewAppeared();
                     } else if (event instanceof Insets) {
                         internalNotifyViewInsetsChanged(sessionId, (Insets) event);
                     } else {
@@ -1015,9 +1109,9 @@
      * Therefore, accessing internal properties in {@link MainContentCaptureSession} should
      * always delegate to the assigned thread from {@code mHandler} for synchronization.</p>
      */
-    private void checkOnUiThread() {
-        final boolean onUiThread = mHandler.getLooper().isCurrentThread();
-        if (!onUiThread) {
+    private void checkOnContentCaptureThread() {
+        final boolean onContentCaptureThread = mContentCaptureHandler.getLooper().isCurrentThread();
+        if (!onContentCaptureThread) {
             mWrongThreadCount.incrementAndGet();
             Log.e(TAG, "MainContentCaptureSession running on " + Thread.currentThread());
         }
@@ -1028,4 +1122,63 @@
         Counter.logIncrement(
                 CONTENT_CAPTURE_WRONG_THREAD_METRIC_ID, mWrongThreadCount.getAndSet(0));
     }
+
+    /**
+     * Ensures that {@code r} will be running on the assigned thread.
+     *
+     * <p>This is to prevent unnecessary delegation to Handler that results in fragmented runnable.
+     * </p>
+     */
+    private void runOnContentCaptureThread(@NonNull Runnable r) {
+        if (!mContentCaptureHandler.getLooper().isCurrentThread()) {
+            mContentCaptureHandler.post(r);
+        } else {
+            r.run();
+        }
+    }
+
+    private void clearAndRunOnContentCaptureThread(@NonNull Runnable r, int what) {
+        if (!mContentCaptureHandler.getLooper().isCurrentThread()) {
+            mContentCaptureHandler.removeMessages(what);
+            mContentCaptureHandler.post(r);
+        } else {
+            r.run();
+        }
+    }
+
+    private void runOnUiThread(@NonNull Runnable r) {
+        if (mUiHandler.getLooper().isCurrentThread()) {
+            r.run();
+        } else {
+            mUiHandler.post(r);
+        }
+    }
+
+    /**
+     * Holds {@link ContentCaptureSession} and related {@link ViewStructure} for processing.
+     */
+    private static final class ViewStructureSession {
+        @Nullable private ContentCaptureSession mSession;
+        @Nullable private ViewStructure mStructure;
+
+        ViewStructureSession() {}
+
+        void setSession(@Nullable ContentCaptureSession session) {
+            this.mSession = session;
+        }
+
+        void setStructure(@Nullable ViewStructure struct) {
+            this.mStructure = struct;
+        }
+
+        /**
+         * Calls {@link ContentCaptureSession#notifyViewAppeared(ViewStructure)} if the session and
+         * the view structure are available.
+         */
+        void notifyViewAppeared() {
+            if (mSession != null && mStructure != null) {
+                mSession.notifyViewAppeared(mStructure);
+            }
+        }
+    }
 }
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSessionV2.java b/core/java/android/view/contentcapture/MainContentCaptureSessionV2.java
deleted file mode 100644
index fbb66d1..0000000
--- a/core/java/android/view/contentcapture/MainContentCaptureSessionV2.java
+++ /dev/null
@@ -1,1187 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.contentcapture;
-
-import static android.view.contentcapture.ContentCaptureEvent.TYPE_CONTEXT_UPDATED;
-import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_FINISHED;
-import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_PAUSED;
-import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_RESUMED;
-import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_STARTED;
-import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_APPEARED;
-import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_DISAPPEARED;
-import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_INSETS_CHANGED;
-import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_TEXT_CHANGED;
-import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_TREE_APPEARED;
-import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_TREE_APPEARING;
-import static android.view.contentcapture.ContentCaptureEvent.TYPE_WINDOW_BOUNDS_CHANGED;
-import static android.view.contentcapture.ContentCaptureHelper.getSanitizedString;
-import static android.view.contentcapture.ContentCaptureHelper.sDebug;
-import static android.view.contentcapture.ContentCaptureHelper.sVerbose;
-import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_FALSE;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ComponentName;
-import android.content.pm.ParceledListSlice;
-import android.graphics.Insets;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IBinder.DeathRecipient;
-import android.os.RemoteException;
-import android.os.Trace;
-import android.service.contentcapture.ContentCaptureService;
-import android.text.Selection;
-import android.text.Spannable;
-import android.text.TextUtils;
-import android.util.LocalLog;
-import android.util.Log;
-import android.util.SparseArray;
-import android.util.TimeUtils;
-import android.view.View;
-import android.view.ViewStructure;
-import android.view.autofill.AutofillId;
-import android.view.contentcapture.ViewNode.ViewStructureImpl;
-import android.view.contentprotection.ContentProtectionEventProcessor;
-import android.view.inputmethod.BaseInputConnection;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.os.IResultReceiver;
-import com.android.modules.expresslog.Counter;
-
-import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Main session associated with a context.
- *
- * <p>This is forked from {@link MainContentCaptureSession} to hold the logic of running operations
- * in the background thread.</p>
- *
- * @hide
- */
-@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-public final class MainContentCaptureSessionV2 extends ContentCaptureSession {
-
-    private static final String TAG = MainContentCaptureSession.class.getSimpleName();
-
-    private static final String CONTENT_CAPTURE_WRONG_THREAD_METRIC_ID =
-            "content_capture.value_content_capture_wrong_thread_count";
-
-    // For readability purposes...
-    private static final boolean FORCE_FLUSH = true;
-
-    /**
-     * Handler message used to flush the buffer.
-     */
-    private static final int MSG_FLUSH = 1;
-
-    @NonNull
-    private final AtomicBoolean mDisabled = new AtomicBoolean(false);
-
-    @NonNull
-    private final ContentCaptureManager.StrippedContext mContext;
-
-    @NonNull
-    private final ContentCaptureManager mManager;
-
-    @NonNull
-    private final Handler mUiHandler;
-
-    @NonNull
-    private final Handler mContentCaptureHandler;
-
-    /**
-     * Interface to the system_server binder object - it's only used to start the session (and
-     * notify when the session is finished).
-     */
-    @NonNull
-    private final IContentCaptureManager mSystemServerInterface;
-
-    /**
-     * Direct interface to the service binder object - it's used to send the events, including the
-     * last ones (when the session is finished)
-     *
-     * @hide
-     */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    @Nullable
-    public IContentCaptureDirectManager mDirectServiceInterface;
-
-    @Nullable
-    private DeathRecipient mDirectServiceVulture;
-
-    private int mState = UNKNOWN_STATE;
-
-    @Nullable
-    private IBinder mApplicationToken;
-    @Nullable
-    private IBinder mShareableActivityToken;
-
-    /** @hide */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    @Nullable
-    public ComponentName mComponentName;
-
-    /**
-     * Thread-safe queue of events held to be processed as a batch.
-     *
-     * Because it is not guaranteed that the events will be enqueued from a single thread, the
-     * implementation must be thread-safe to prevent unexpected behaviour.
-     *
-     * @hide
-     */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    @NonNull
-    public final ConcurrentLinkedQueue<ContentCaptureEvent> mEventProcessQueue;
-
-    /**
-     * List of events held to be sent to the {@link ContentCaptureService} as a batch.
-     *
-     * @hide
-     */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    @Nullable
-    public ArrayList<ContentCaptureEvent> mEvents;
-
-    // Used just for debugging purposes (on dump)
-    private long mNextFlush;
-
-    /**
-     * Whether the next buffer flush is queued by a text changed event.
-     */
-    private boolean mNextFlushForTextChanged = false;
-
-    @Nullable
-    private final LocalLog mFlushHistory;
-
-    private final AtomicInteger mWrongThreadCount = new AtomicInteger(0);
-
-    /**
-     * Binder object used to update the session state.
-     */
-    @NonNull
-    private final SessionStateReceiver mSessionStateReceiver;
-
-    /** @hide */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    @Nullable
-    public ContentProtectionEventProcessor mContentProtectionEventProcessor;
-
-    private static class SessionStateReceiver extends IResultReceiver.Stub {
-        private final WeakReference<MainContentCaptureSessionV2> mMainSession;
-
-        SessionStateReceiver(MainContentCaptureSessionV2 session) {
-            mMainSession = new WeakReference<>(session);
-        }
-
-        @Override
-        public void send(int resultCode, Bundle resultData) {
-            final MainContentCaptureSessionV2 mainSession = mMainSession.get();
-            if (mainSession == null) {
-                Log.w(TAG, "received result after mina session released");
-                return;
-            }
-            final IBinder binder;
-            if (resultData != null) {
-                // Change in content capture enabled.
-                final boolean hasEnabled = resultData.getBoolean(EXTRA_ENABLED_STATE);
-                if (hasEnabled) {
-                    final boolean disabled = (resultCode == RESULT_CODE_FALSE);
-                    mainSession.mDisabled.set(disabled);
-                    return;
-                }
-                binder = resultData.getBinder(EXTRA_BINDER);
-                if (binder == null) {
-                    Log.wtf(TAG, "No " + EXTRA_BINDER + " extra result");
-                    mainSession.runOnContentCaptureThread(() -> mainSession.resetSession(
-                            STATE_DISABLED | STATE_INTERNAL_ERROR));
-                    return;
-                }
-            } else {
-                binder = null;
-            }
-            mainSession.runOnContentCaptureThread(() ->
-                    mainSession.onSessionStarted(resultCode, binder));
-        }
-    }
-
-    /** @hide */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED)
-    public MainContentCaptureSessionV2(
-            @NonNull ContentCaptureManager.StrippedContext context,
-            @NonNull ContentCaptureManager manager,
-            @NonNull Handler uiHandler,
-            @NonNull Handler contentCaptureHandler,
-            @NonNull IContentCaptureManager systemServerInterface) {
-        mContext = context;
-        mManager = manager;
-        mUiHandler = uiHandler;
-        mContentCaptureHandler = contentCaptureHandler;
-        mSystemServerInterface = systemServerInterface;
-
-        final int logHistorySize = mManager.mOptions.logHistorySize;
-        mFlushHistory = logHistorySize > 0 ? new LocalLog(logHistorySize) : null;
-
-        mSessionStateReceiver = new SessionStateReceiver(this);
-
-        mEventProcessQueue = new ConcurrentLinkedQueue<>();
-    }
-
-    @Override
-    ContentCaptureSession getMainCaptureSession() {
-        return this;
-    }
-
-    @Override
-    ContentCaptureSession newChild(@NonNull ContentCaptureContext clientContext) {
-        final ContentCaptureSession child = new ChildContentCaptureSession(this, clientContext);
-        internalNotifyChildSessionStarted(mId, child.mId, clientContext);
-        return child;
-    }
-
-    /**
-     * Starts this session.
-     */
-    @Override
-    void start(@NonNull IBinder token, @NonNull IBinder shareableActivityToken,
-            @NonNull ComponentName component, int flags) {
-        runOnContentCaptureThread(
-                () -> startImpl(token, shareableActivityToken, component, flags));
-    }
-
-    private void startImpl(@NonNull IBinder token, @NonNull IBinder shareableActivityToken,
-               @NonNull ComponentName component, int flags) {
-        checkOnContentCaptureThread();
-        if (!isContentCaptureEnabled()) return;
-
-        if (sVerbose) {
-            Log.v(TAG, "start(): token=" + token + ", comp="
-                    + ComponentName.flattenToShortString(component));
-        }
-
-        if (hasStarted()) {
-            // TODO(b/122959591): make sure this is expected (and when), or use Log.w
-            if (sDebug) {
-                Log.d(TAG, "ignoring handleStartSession(" + token + "/"
-                        + ComponentName.flattenToShortString(component) + " while on state "
-                        + getStateAsString(mState));
-            }
-            return;
-        }
-        mState = STATE_WAITING_FOR_SERVER;
-        mApplicationToken = token;
-        mShareableActivityToken = shareableActivityToken;
-        mComponentName = component;
-
-        if (sVerbose) {
-            Log.v(TAG, "handleStartSession(): token=" + token + ", act="
-                    + getDebugState() + ", id=" + mId);
-        }
-
-        try {
-            mSystemServerInterface.startSession(mApplicationToken, mShareableActivityToken,
-                    component, mId, flags, mSessionStateReceiver);
-        } catch (RemoteException e) {
-            Log.w(TAG, "Error starting session for " + component.flattenToShortString() + ": " + e);
-        }
-    }
-    @Override
-    void onDestroy() {
-        clearAndRunOnContentCaptureThread(() -> {
-            try {
-                flush(FLUSH_REASON_SESSION_FINISHED);
-            } finally {
-                destroySession();
-            }
-        }, MSG_FLUSH);
-    }
-
-    /**
-     * Callback from {@code system_server} after call to {@link
-     * IContentCaptureManager#startSession(IBinder, ComponentName, String, int, IResultReceiver)}.
-     *
-     * @param resultCode session state
-     * @param binder handle to {@code IContentCaptureDirectManager}
-     * @hide
-     */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    public void onSessionStarted(int resultCode, @Nullable IBinder binder) {
-        checkOnContentCaptureThread();
-        if (binder != null) {
-            mDirectServiceInterface = IContentCaptureDirectManager.Stub.asInterface(binder);
-            mDirectServiceVulture = () -> {
-                Log.w(TAG, "Keeping session " + mId + " when service died");
-                mState = STATE_SERVICE_DIED;
-                mDisabled.set(true);
-            };
-            try {
-                binder.linkToDeath(mDirectServiceVulture, 0);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed to link to death on " + binder + ": " + e);
-            }
-        }
-
-        if (isContentProtectionEnabled()) {
-            mContentProtectionEventProcessor =
-                    new ContentProtectionEventProcessor(
-                            mManager.getContentProtectionEventBuffer(),
-                            mContentCaptureHandler,
-                            mSystemServerInterface,
-                            mComponentName.getPackageName(),
-                            mManager.mOptions.contentProtectionOptions);
-        } else {
-            mContentProtectionEventProcessor = null;
-        }
-
-        if ((resultCode & STATE_DISABLED) != 0) {
-            resetSession(resultCode);
-        } else {
-            mState = resultCode;
-            mDisabled.set(false);
-            // Flush any pending data immediately as buffering forced until now.
-            flushIfNeeded(FLUSH_REASON_SESSION_CONNECTED);
-        }
-        if (sVerbose) {
-            Log.v(TAG, "handleSessionStarted() result: id=" + mId + " resultCode=" + resultCode
-                    + ", state=" + getStateAsString(mState) + ", disabled=" + mDisabled.get()
-                    + ", binder=" + binder + ", events=" + (mEvents == null ? 0 : mEvents.size()));
-        }
-    }
-
-    /** @hide */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    public void sendEvent(@NonNull ContentCaptureEvent event) {
-        sendEvent(event, /* forceFlush= */ false);
-    }
-
-    private void sendEvent(@NonNull ContentCaptureEvent event, boolean forceFlush) {
-        checkOnContentCaptureThread();
-        final int eventType = event.getType();
-        if (sVerbose) Log.v(TAG, "handleSendEvent(" + getDebugState() + "): " + event);
-        if (!hasStarted() && eventType != ContentCaptureEvent.TYPE_SESSION_STARTED
-                && eventType != ContentCaptureEvent.TYPE_CONTEXT_UPDATED) {
-            // TODO(b/120494182): comment when this could happen (dialogs?)
-            if (sVerbose) {
-                Log.v(TAG, "handleSendEvent(" + getDebugState() + ", "
-                        + ContentCaptureEvent.getTypeAsString(eventType)
-                        + "): dropping because session not started yet");
-            }
-            return;
-        }
-        if (mDisabled.get()) {
-            // This happens when the event was queued in the handler before the sesison was ready,
-            // then handleSessionStarted() returned and set it as disabled - we need to drop it,
-            // otherwise it will keep triggering handleScheduleFlush()
-            if (sVerbose) Log.v(TAG, "handleSendEvent(): ignoring when disabled");
-            return;
-        }
-
-        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
-            if (eventType == TYPE_VIEW_TREE_APPEARING) {
-                Trace.asyncTraceBegin(
-                        Trace.TRACE_TAG_VIEW, /* methodName= */ "sendEventAsync", /* cookie= */ 0);
-            }
-        }
-
-        if (isContentProtectionReceiverEnabled()) {
-            sendContentProtectionEvent(event);
-        }
-        if (isContentCaptureReceiverEnabled()) {
-            sendContentCaptureEvent(event, forceFlush);
-        }
-
-        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
-            if (eventType == TYPE_VIEW_TREE_APPEARED) {
-                Trace.asyncTraceEnd(
-                        Trace.TRACE_TAG_VIEW, /* methodName= */ "sendEventAsync", /* cookie= */ 0);
-            }
-        }
-    }
-
-    private void sendContentProtectionEvent(@NonNull ContentCaptureEvent event) {
-        checkOnContentCaptureThread();
-        if (mContentProtectionEventProcessor != null) {
-            mContentProtectionEventProcessor.processEvent(event);
-        }
-    }
-
-    private void sendContentCaptureEvent(@NonNull ContentCaptureEvent event, boolean forceFlush) {
-        checkOnContentCaptureThread();
-        final int eventType = event.getType();
-        final int maxBufferSize = mManager.mOptions.maxBufferSize;
-        if (mEvents == null) {
-            if (sVerbose) {
-                Log.v(TAG, "handleSendEvent(): creating buffer for " + maxBufferSize + " events");
-            }
-            mEvents = new ArrayList<>(maxBufferSize);
-        }
-
-        // Some type of events can be merged together
-        boolean addEvent = true;
-
-        if (eventType == TYPE_VIEW_TEXT_CHANGED) {
-            // We determine whether to add or merge the current event by following criteria:
-            // 1. Don't have composing span: always add.
-            // 2. Have composing span:
-            //    2.1 either last or current text is empty: add.
-            //    2.2 last event doesn't have composing span: add.
-            // Otherwise, merge.
-            final CharSequence text = event.getText();
-            final boolean hasComposingSpan = event.hasComposingSpan();
-            if (hasComposingSpan) {
-                ContentCaptureEvent lastEvent = null;
-                for (int index = mEvents.size() - 1; index >= 0; index--) {
-                    final ContentCaptureEvent tmpEvent = mEvents.get(index);
-                    if (event.getId().equals(tmpEvent.getId())) {
-                        lastEvent = tmpEvent;
-                        break;
-                    }
-                }
-                if (lastEvent != null && lastEvent.hasComposingSpan()) {
-                    final CharSequence lastText = lastEvent.getText();
-                    final boolean bothNonEmpty = !TextUtils.isEmpty(lastText)
-                            && !TextUtils.isEmpty(text);
-                    boolean equalContent =
-                            TextUtils.equals(lastText, text)
-                            && lastEvent.hasSameComposingSpan(event)
-                            && lastEvent.hasSameSelectionSpan(event);
-                    if (equalContent) {
-                        addEvent = false;
-                    } else if (bothNonEmpty) {
-                        lastEvent.mergeEvent(event);
-                        addEvent = false;
-                    }
-                    if (!addEvent && sVerbose) {
-                        Log.v(TAG, "Buffering VIEW_TEXT_CHANGED event, updated text="
-                                + getSanitizedString(text));
-                    }
-                }
-            }
-        }
-
-        if (!mEvents.isEmpty() && eventType == TYPE_VIEW_DISAPPEARED) {
-            final ContentCaptureEvent lastEvent = mEvents.get(mEvents.size() - 1);
-            if (lastEvent.getType() == TYPE_VIEW_DISAPPEARED
-                    && event.getSessionId() == lastEvent.getSessionId()) {
-                if (sVerbose) {
-                    Log.v(TAG, "Buffering TYPE_VIEW_DISAPPEARED events for session "
-                            + lastEvent.getSessionId());
-                }
-                lastEvent.mergeEvent(event);
-                addEvent = false;
-            }
-        }
-
-        if (addEvent) {
-            mEvents.add(event);
-        }
-
-        // TODO: we need to change when the flush happens so that we don't flush while the
-        //  composing span hasn't changed. But we might need to keep flushing the events for the
-        //  non-editable views and views that don't have the composing state; otherwise some other
-        //  Content Capture features may be delayed.
-
-        final int numberEvents = mEvents.size();
-
-        final boolean bufferEvent = numberEvents < maxBufferSize;
-
-        if (bufferEvent && !forceFlush) {
-            final int flushReason;
-            if (eventType == TYPE_VIEW_TEXT_CHANGED) {
-                mNextFlushForTextChanged = true;
-                flushReason = FLUSH_REASON_TEXT_CHANGE_TIMEOUT;
-            } else {
-                if (mNextFlushForTextChanged) {
-                    if (sVerbose) {
-                        Log.i(TAG, "Not scheduling flush because next flush is for text changed");
-                    }
-                    return;
-                }
-
-                flushReason = FLUSH_REASON_IDLE_TIMEOUT;
-            }
-            scheduleFlush(flushReason, /* checkExisting= */ true);
-            return;
-        }
-
-        if (mState != STATE_ACTIVE && numberEvents >= maxBufferSize) {
-            // Callback from startSession hasn't been called yet - typically happens on system
-            // apps that are started before the system service
-            // TODO(b/122959591): try to ignore session while system is not ready / boot
-            // not complete instead. Similarly, the manager service should return right away
-            // when the user does not have a service set
-            if (sDebug) {
-                Log.d(TAG, "Closing session for " + getDebugState()
-                        + " after " + numberEvents + " delayed events");
-            }
-            resetSession(STATE_DISABLED | STATE_NO_RESPONSE);
-            // TODO(b/111276913): denylist activity / use special flag to indicate that
-            // when it's launched again
-            return;
-        }
-        final int flushReason;
-        switch (eventType) {
-            case ContentCaptureEvent.TYPE_SESSION_STARTED:
-                flushReason = FLUSH_REASON_SESSION_STARTED;
-                break;
-            case ContentCaptureEvent.TYPE_SESSION_FINISHED:
-                flushReason = FLUSH_REASON_SESSION_FINISHED;
-                break;
-            case ContentCaptureEvent.TYPE_VIEW_TREE_APPEARING:
-                flushReason = FLUSH_REASON_VIEW_TREE_APPEARING;
-                break;
-            case ContentCaptureEvent.TYPE_VIEW_TREE_APPEARED:
-                flushReason = FLUSH_REASON_VIEW_TREE_APPEARED;
-                break;
-            default:
-                flushReason = forceFlush ? FLUSH_REASON_FORCE_FLUSH : FLUSH_REASON_FULL;
-        }
-
-        flush(flushReason);
-    }
-
-    private boolean hasStarted() {
-        checkOnContentCaptureThread();
-        return mState != UNKNOWN_STATE;
-    }
-
-    private void scheduleFlush(@FlushReason int reason, boolean checkExisting) {
-        checkOnContentCaptureThread();
-        if (sVerbose) {
-            Log.v(TAG, "handleScheduleFlush(" + getDebugState(reason)
-                    + ", checkExisting=" + checkExisting);
-        }
-        if (!hasStarted()) {
-            if (sVerbose) Log.v(TAG, "handleScheduleFlush(): session not started yet");
-            return;
-        }
-
-        if (mDisabled.get()) {
-            // Should not be called on this state, as handleSendEvent checks.
-            // But we rather add one if check and log than re-schedule and keep the session alive...
-            Log.e(TAG, "handleScheduleFlush(" + getDebugState(reason) + "): should not be called "
-                    + "when disabled. events=" + (mEvents == null ? null : mEvents.size()));
-            return;
-        }
-        if (checkExisting && mContentCaptureHandler.hasMessages(MSG_FLUSH)) {
-            // "Renew" the flush message by removing the previous one
-            mContentCaptureHandler.removeMessages(MSG_FLUSH);
-        }
-
-        final int flushFrequencyMs;
-        if (reason == FLUSH_REASON_TEXT_CHANGE_TIMEOUT) {
-            flushFrequencyMs = mManager.mOptions.textChangeFlushingFrequencyMs;
-        } else {
-            if (reason != FLUSH_REASON_IDLE_TIMEOUT) {
-                if (sDebug) {
-                    Log.d(TAG, "handleScheduleFlush(" + getDebugState(reason) + "): not a timeout "
-                            + "reason because mDirectServiceInterface is not ready yet");
-                }
-            }
-            flushFrequencyMs = mManager.mOptions.idleFlushingFrequencyMs;
-        }
-
-        mNextFlush = System.currentTimeMillis() + flushFrequencyMs;
-        if (sVerbose) {
-            Log.v(TAG, "handleScheduleFlush(): scheduled to flush in "
-                    + flushFrequencyMs + "ms: " + TimeUtils.logTimeOfDay(mNextFlush));
-        }
-        // Post using a Runnable directly to trim a few μs from PooledLambda.obtainMessage()
-        mContentCaptureHandler.postDelayed(() ->
-                flushIfNeeded(reason), MSG_FLUSH, flushFrequencyMs);
-    }
-
-    private void flushIfNeeded(@FlushReason int reason) {
-        checkOnContentCaptureThread();
-        if (mEvents == null || mEvents.isEmpty()) {
-            if (sVerbose) Log.v(TAG, "Nothing to flush");
-            return;
-        }
-        flush(reason);
-    }
-
-    /** @hide */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-    @Override
-    public void flush(@FlushReason int reason) {
-        runOnContentCaptureThread(() -> flushImpl(reason));
-    }
-
-    private void flushImpl(@FlushReason int reason) {
-        checkOnContentCaptureThread();
-        if (mEvents == null || mEvents.size() == 0) {
-            if (sVerbose) {
-                Log.v(TAG, "Don't flush for empty event buffer.");
-            }
-            return;
-        }
-
-        if (mDisabled.get()) {
-            Log.e(TAG, "handleForceFlush(" + getDebugState(reason) + "): should not be when "
-                    + "disabled");
-            return;
-        }
-
-        if (!isContentCaptureReceiverEnabled()) {
-            return;
-        }
-
-        if (mDirectServiceInterface == null) {
-            if (sVerbose) {
-                Log.v(TAG, "handleForceFlush(" + getDebugState(reason) + "): hold your horses, "
-                        + "client not ready: " + mEvents);
-            }
-            if (!mContentCaptureHandler.hasMessages(MSG_FLUSH)) {
-                scheduleFlush(reason, /* checkExisting= */ false);
-            }
-            return;
-        }
-
-        mNextFlushForTextChanged = false;
-
-        final int numberEvents = mEvents.size();
-        final String reasonString = getFlushReasonAsString(reason);
-
-        if (sVerbose) {
-            ContentCaptureEvent event = mEvents.get(numberEvents - 1);
-            String forceString = (reason == FLUSH_REASON_FORCE_FLUSH) ? ". The force flush event "
-                    + ContentCaptureEvent.getTypeAsString(event.getType()) : "";
-            Log.v(TAG, "Flushing " + numberEvents + " event(s) for " + getDebugState(reason)
-                    + forceString);
-        }
-        if (mFlushHistory != null) {
-            // Logs reason, size, max size, idle timeout
-            final String logRecord = "r=" + reasonString + " s=" + numberEvents
-                    + " m=" + mManager.mOptions.maxBufferSize
-                    + " i=" + mManager.mOptions.idleFlushingFrequencyMs;
-            mFlushHistory.log(logRecord);
-        }
-        try {
-            mContentCaptureHandler.removeMessages(MSG_FLUSH);
-
-            final ParceledListSlice<ContentCaptureEvent> events = clearEvents();
-            mDirectServiceInterface.sendEvents(events, reason, mManager.mOptions);
-        } catch (RemoteException e) {
-            Log.w(TAG, "Error sending " + numberEvents + " for " + getDebugState()
-                    + ": " + e);
-        }
-    }
-
-    @Override
-    public void updateContentCaptureContext(@Nullable ContentCaptureContext context) {
-        internalNotifyContextUpdated(mId, context);
-    }
-
-    /**
-     * Resets the buffer and return a {@link ParceledListSlice} with the previous events.
-     */
-    @NonNull
-    private ParceledListSlice<ContentCaptureEvent> clearEvents() {
-        checkOnContentCaptureThread();
-        // NOTE: we must save a reference to the current mEvents and then set it to to null,
-        // otherwise clearing it would clear it in the receiving side if the service is also local.
-        if (mEvents == null) {
-            return new ParceledListSlice<>(Collections.EMPTY_LIST);
-        }
-
-        final List<ContentCaptureEvent> events = new ArrayList<>(mEvents);
-        mEvents.clear();
-        return new ParceledListSlice<>(events);
-    }
-
-    /** hide */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    public void destroySession() {
-        checkOnContentCaptureThread();
-        if (sDebug) {
-            Log.d(TAG, "Destroying session (ctx=" + mContext + ", id=" + mId + ") with "
-                    + (mEvents == null ? 0 : mEvents.size()) + " event(s) for "
-                    + getDebugState());
-        }
-
-        reportWrongThreadMetric();
-        try {
-            mSystemServerInterface.finishSession(mId);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error destroying system-service session " + mId + " for "
-                    + getDebugState() + ": " + e);
-        }
-
-        if (mDirectServiceInterface != null) {
-            mDirectServiceInterface.asBinder().unlinkToDeath(mDirectServiceVulture, 0);
-        }
-        mDirectServiceInterface = null;
-        mContentProtectionEventProcessor = null;
-        mEventProcessQueue.clear();
-    }
-
-    // TODO(b/122454205): once we support multiple sessions, we might need to move some of these
-    // clearings out.
-    /** @hide */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    public void resetSession(int newState) {
-        checkOnContentCaptureThread();
-        if (sVerbose) {
-            Log.v(TAG, "handleResetSession(" + getActivityName() + "): from "
-                    + getStateAsString(mState) + " to " + getStateAsString(newState));
-        }
-        mState = newState;
-        mDisabled.set((newState & STATE_DISABLED) != 0);
-        // TODO(b/122454205): must reset children (which currently is owned by superclass)
-        mApplicationToken = null;
-        mShareableActivityToken = null;
-        mComponentName = null;
-        mEvents = null;
-        if (mDirectServiceInterface != null) {
-            try {
-                mDirectServiceInterface.asBinder().unlinkToDeath(mDirectServiceVulture, 0);
-            } catch (NoSuchElementException e) {
-                Log.w(TAG, "IContentCaptureDirectManager does not exist");
-            }
-        }
-        mDirectServiceInterface = null;
-        mContentProtectionEventProcessor = null;
-        mContentCaptureHandler.removeMessages(MSG_FLUSH);
-    }
-
-    @Override
-    void internalNotifyViewAppeared(int sessionId, @NonNull ViewStructureImpl node) {
-        final ContentCaptureEvent event = new ContentCaptureEvent(sessionId, TYPE_VIEW_APPEARED)
-                .setViewNode(node.mNode);
-        enqueueEvent(event);
-    }
-
-    @Override
-    void internalNotifyViewDisappeared(int sessionId, @NonNull AutofillId id) {
-        final ContentCaptureEvent event = new ContentCaptureEvent(sessionId, TYPE_VIEW_DISAPPEARED)
-                .setAutofillId(id);
-        enqueueEvent(event);
-    }
-
-    @Override
-    void internalNotifyViewTextChanged(
-            int sessionId, @NonNull AutofillId id, @Nullable CharSequence text) {
-        // Since the same CharSequence instance may be reused in the TextView, we need to make
-        // a copy of its content so that its value will not be changed by subsequent updates
-        // in the TextView.
-        CharSequence trimmed = TextUtils.trimToParcelableSize(text);
-        final CharSequence eventText = trimmed != null && trimmed == text
-                ? trimmed.toString()
-                : trimmed;
-
-        final int composingStart;
-        final int composingEnd;
-        if (text instanceof Spannable) {
-            composingStart = BaseInputConnection.getComposingSpanStart((Spannable) text);
-            composingEnd = BaseInputConnection.getComposingSpanEnd((Spannable) text);
-        } else {
-            composingStart = ContentCaptureEvent.MAX_INVALID_VALUE;
-            composingEnd = ContentCaptureEvent.MAX_INVALID_VALUE;
-        }
-
-        final int startIndex = Selection.getSelectionStart(text);
-        final int endIndex = Selection.getSelectionEnd(text);
-
-        final ContentCaptureEvent event = new ContentCaptureEvent(sessionId, TYPE_VIEW_TEXT_CHANGED)
-                .setAutofillId(id).setText(eventText)
-                .setComposingIndex(composingStart, composingEnd)
-                .setSelectionIndex(startIndex, endIndex);
-        enqueueEvent(event);
-    }
-
-    @Override
-    void internalNotifyViewInsetsChanged(int sessionId, @NonNull Insets viewInsets) {
-        final ContentCaptureEvent event =
-                new ContentCaptureEvent(sessionId, TYPE_VIEW_INSETS_CHANGED)
-                        .setInsets(viewInsets);
-        enqueueEvent(event);
-    }
-
-    @Override
-    public void internalNotifyViewTreeEvent(int sessionId, boolean started) {
-        final int type = started ? TYPE_VIEW_TREE_APPEARING : TYPE_VIEW_TREE_APPEARED;
-        final boolean disableFlush = mManager.getFlushViewTreeAppearingEventDisabled();
-        final boolean forceFlush = disableFlush ? !started : FORCE_FLUSH;
-
-        final ContentCaptureEvent event = new ContentCaptureEvent(sessionId, type);
-        enqueueEvent(event, forceFlush);
-    }
-
-    @Override
-    public void internalNotifySessionResumed() {
-        final ContentCaptureEvent event = new ContentCaptureEvent(mId, TYPE_SESSION_RESUMED);
-        enqueueEvent(event, FORCE_FLUSH);
-    }
-
-    @Override
-    public void internalNotifySessionPaused() {
-        final ContentCaptureEvent event = new ContentCaptureEvent(mId, TYPE_SESSION_PAUSED);
-        enqueueEvent(event, FORCE_FLUSH);
-    }
-
-    @Override
-    boolean isContentCaptureEnabled() {
-        return super.isContentCaptureEnabled() && mManager.isContentCaptureEnabled();
-    }
-
-    // Called by ContentCaptureManager.isContentCaptureEnabled
-    boolean isDisabled() {
-        return mDisabled.get();
-    }
-
-    /**
-     * Sets the disabled state of content capture.
-     *
-     * @return whether disabled state was changed.
-     */
-    boolean setDisabled(boolean disabled) {
-        return mDisabled.compareAndSet(!disabled, disabled);
-    }
-
-    @Override
-    void internalNotifyChildSessionStarted(int parentSessionId, int childSessionId,
-            @NonNull ContentCaptureContext clientContext) {
-        final ContentCaptureEvent event =
-                new ContentCaptureEvent(childSessionId, TYPE_SESSION_STARTED)
-                        .setParentSessionId(parentSessionId)
-                        .setClientContext(clientContext);
-        enqueueEvent(event, FORCE_FLUSH);
-    }
-
-    @Override
-    void internalNotifyChildSessionFinished(int parentSessionId, int childSessionId) {
-        final ContentCaptureEvent event =
-                new ContentCaptureEvent(childSessionId, TYPE_SESSION_FINISHED)
-                        .setParentSessionId(parentSessionId);
-        enqueueEvent(event, FORCE_FLUSH);
-    }
-
-    @Override
-    void internalNotifyContextUpdated(int sessionId, @Nullable ContentCaptureContext context) {
-        final ContentCaptureEvent event = new ContentCaptureEvent(sessionId, TYPE_CONTEXT_UPDATED)
-                .setClientContext(context);
-        enqueueEvent(event, FORCE_FLUSH);
-    }
-
-    @Override
-    public void notifyWindowBoundsChanged(int sessionId, @NonNull Rect bounds) {
-        final ContentCaptureEvent event =
-                new ContentCaptureEvent(sessionId, TYPE_WINDOW_BOUNDS_CHANGED)
-                        .setBounds(bounds);
-        enqueueEvent(event);
-    }
-
-    private List<ContentCaptureEvent> clearBufferEvents() {
-        final ArrayList<ContentCaptureEvent> bufferEvents = new ArrayList<>();
-        ContentCaptureEvent event;
-        while ((event = mEventProcessQueue.poll()) != null) {
-            bufferEvents.add(event);
-        }
-        return bufferEvents;
-    }
-
-    private void enqueueEvent(@NonNull final ContentCaptureEvent event) {
-        enqueueEvent(event, /* forceFlush */ false);
-    }
-
-    /**
-     * Enqueue the event into {@code mEventProcessBuffer} if it is not an urgent request. Otherwise,
-     * clear the buffer events then starting sending out current event.
-     */
-    private void enqueueEvent(@NonNull final ContentCaptureEvent event, boolean forceFlush) {
-        if (forceFlush || mEventProcessQueue.size() >= mManager.mOptions.maxBufferSize - 1) {
-            // The buffer events are cleared in the same thread first to prevent new events
-            // being added during the time of context switch. This would disrupt the sequence
-            // of events.
-            final List<ContentCaptureEvent> batchEvents = clearBufferEvents();
-            runOnContentCaptureThread(() -> {
-                for (int i = 0; i < batchEvents.size(); i++) {
-                    sendEvent(batchEvents.get(i));
-                }
-                sendEvent(event, /* forceFlush= */ true);
-            });
-        } else {
-            mEventProcessQueue.offer(event);
-        }
-    }
-
-    @Override
-    public void notifyContentCaptureEvents(
-            @NonNull SparseArray<ArrayList<Object>> contentCaptureEvents) {
-        runOnUiThread(() -> {
-            prepareViewStructures(contentCaptureEvents);
-            runOnContentCaptureThread(() ->
-                    notifyContentCaptureEventsImpl(contentCaptureEvents));
-        });
-    }
-
-    /**
-     * Traverse events and pre-process {@link View} events to {@link ViewStructureSession} events.
-     * If a {@link View} event is invalid, an empty {@link ViewStructureSession} will still be
-     * provided.
-     */
-    private void prepareViewStructures(
-            @NonNull SparseArray<ArrayList<Object>> contentCaptureEvents) {
-        for (int i = 0; i < contentCaptureEvents.size(); i++) {
-            int sessionId = contentCaptureEvents.keyAt(i);
-            ArrayList<Object> events = contentCaptureEvents.valueAt(i);
-            for_each_event: for (int j = 0; j < events.size(); j++) {
-                Object event = events.get(j);
-                if (event instanceof View) {
-                    View view = (View) event;
-                    ContentCaptureSession session = view.getContentCaptureSession();
-                    ViewStructureSession structureSession = new ViewStructureSession();
-
-                    // Replace the View event with ViewStructureSession no matter the data is
-                    // available or not. This is to ensure the sequence of the events are still
-                    // the same. Calls to notifyViewAppeared will check the availability later.
-                    events.set(j, structureSession);
-                    if (session == null) {
-                        Log.w(TAG, "no content capture session on view: " + view);
-                        continue for_each_event;
-                    }
-                    int actualId = session.getId();
-                    if (actualId != sessionId) {
-                        Log.w(TAG, "content capture session mismatch for view (" + view
-                                + "): was " + sessionId + " before, it's " + actualId + " now");
-                        continue for_each_event;
-                    }
-                    ViewStructure structure = session.newViewStructure(view);
-                    view.onProvideContentCaptureStructure(structure, /* flags= */ 0);
-
-                    structureSession.setSession(session);
-                    structureSession.setStructure(structure);
-                }
-            }
-        }
-    }
-
-    private void notifyContentCaptureEventsImpl(
-            @NonNull SparseArray<ArrayList<Object>> contentCaptureEvents) {
-        checkOnContentCaptureThread();
-        try {
-            if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
-                Trace.traceBegin(Trace.TRACE_TAG_VIEW, "notifyContentCaptureEvents");
-            }
-            for (int i = 0; i < contentCaptureEvents.size(); i++) {
-                int sessionId = contentCaptureEvents.keyAt(i);
-                internalNotifyViewTreeEvent(sessionId, /* started= */ true);
-                ArrayList<Object> events = contentCaptureEvents.valueAt(i);
-                for_each_event: for (int j = 0; j < events.size(); j++) {
-                    Object event = events.get(j);
-                    if (event instanceof AutofillId) {
-                        internalNotifyViewDisappeared(sessionId, (AutofillId) event);
-                    } else if (event instanceof ViewStructureSession viewStructureSession) {
-                        viewStructureSession.notifyViewAppeared();
-                    } else if (event instanceof Insets) {
-                        internalNotifyViewInsetsChanged(sessionId, (Insets) event);
-                    } else {
-                        Log.w(TAG, "invalid content capture event: " + event);
-                    }
-                }
-                internalNotifyViewTreeEvent(sessionId, /* started= */ false);
-            }
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
-        }
-    }
-
-    @Override
-    void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
-        super.dump(prefix, pw);
-
-        pw.print(prefix); pw.print("mContext: "); pw.println(mContext);
-        pw.print(prefix); pw.print("user: "); pw.println(mContext.getUserId());
-        if (mDirectServiceInterface != null) {
-            pw.print(prefix); pw.print("mDirectServiceInterface: ");
-            pw.println(mDirectServiceInterface);
-        }
-        pw.print(prefix); pw.print("mDisabled: "); pw.println(mDisabled.get());
-        pw.print(prefix); pw.print("isEnabled(): "); pw.println(isContentCaptureEnabled());
-        pw.print(prefix); pw.print("state: "); pw.println(getStateAsString(mState));
-        if (mApplicationToken != null) {
-            pw.print(prefix); pw.print("app token: "); pw.println(mApplicationToken);
-        }
-        if (mShareableActivityToken != null) {
-            pw.print(prefix); pw.print("sharable activity token: ");
-            pw.println(mShareableActivityToken);
-        }
-        if (mComponentName != null) {
-            pw.print(prefix); pw.print("component name: ");
-            pw.println(mComponentName.flattenToShortString());
-        }
-        if (mEvents != null && !mEvents.isEmpty()) {
-            final int numberEvents = mEvents.size();
-            pw.print(prefix); pw.print("buffered events: "); pw.print(numberEvents);
-            pw.print('/'); pw.println(mManager.mOptions.maxBufferSize);
-            if (sVerbose && numberEvents > 0) {
-                final String prefix3 = prefix + "  ";
-                for (int i = 0; i < numberEvents; i++) {
-                    final ContentCaptureEvent event = mEvents.get(i);
-                    pw.print(prefix3); pw.print(i); pw.print(": "); event.dump(pw);
-                    pw.println();
-                }
-            }
-            pw.print(prefix); pw.print("mNextFlushForTextChanged: ");
-            pw.println(mNextFlushForTextChanged);
-            pw.print(prefix); pw.print("flush frequency: ");
-            if (mNextFlushForTextChanged) {
-                pw.println(mManager.mOptions.textChangeFlushingFrequencyMs);
-            } else {
-                pw.println(mManager.mOptions.idleFlushingFrequencyMs);
-            }
-            pw.print(prefix); pw.print("next flush: ");
-            TimeUtils.formatDuration(mNextFlush - System.currentTimeMillis(), pw);
-            pw.print(" ("); pw.print(TimeUtils.logTimeOfDay(mNextFlush)); pw.println(")");
-        }
-        if (mFlushHistory != null) {
-            pw.print(prefix); pw.println("flush history:");
-            mFlushHistory.reverseDump(/* fd= */ null, pw, /* args= */ null); pw.println();
-        } else {
-            pw.print(prefix); pw.println("not logging flush history");
-        }
-
-        super.dump(prefix, pw);
-    }
-
-    /**
-     * Gets a string that can be used to identify the activity on logging statements.
-     */
-    private String getActivityName() {
-        return mComponentName == null
-                ? "pkg:" + mContext.getPackageName()
-                : "act:" + mComponentName.flattenToShortString();
-    }
-
-    @NonNull
-    private String getDebugState() {
-        return getActivityName() + " [state=" + getStateAsString(mState) + ", disabled="
-                + mDisabled.get() + "]";
-    }
-
-    @NonNull
-    private String getDebugState(@FlushReason int reason) {
-        return getDebugState() + ", reason=" + getFlushReasonAsString(reason);
-    }
-
-    private boolean isContentProtectionReceiverEnabled() {
-        return mManager.mOptions.contentProtectionOptions.enableReceiver;
-    }
-
-    private boolean isContentCaptureReceiverEnabled() {
-        return mManager.mOptions.enableReceiver;
-    }
-
-    private boolean isContentProtectionEnabled() {
-        // Should not be possible for mComponentName to be null here but check anyway
-        // Should not be possible for groups to be empty if receiver is enabled but check anyway
-        return mManager.mOptions.contentProtectionOptions.enableReceiver
-                && mManager.getContentProtectionEventBuffer() != null
-                && mComponentName != null
-                && (!mManager.mOptions.contentProtectionOptions.requiredGroups.isEmpty()
-                        || !mManager.mOptions.contentProtectionOptions.optionalGroups.isEmpty());
-    }
-
-    /**
-     * Checks that the current work is running on the assigned thread from {@code mHandler} and
-     * count the number of times running on the wrong thread.
-     *
-     * <p>It is not guaranteed that the callers always invoke function from a single thread.
-     * Therefore, accessing internal properties in {@link MainContentCaptureSession} should
-     * always delegate to the assigned thread from {@code mHandler} for synchronization.</p>
-     */
-    private void checkOnContentCaptureThread() {
-        final boolean onContentCaptureThread = mContentCaptureHandler.getLooper().isCurrentThread();
-        if (!onContentCaptureThread) {
-            mWrongThreadCount.incrementAndGet();
-            Log.e(TAG, "MainContentCaptureSession running on " + Thread.currentThread());
-        }
-    }
-
-    /** Reports number of times running on the wrong thread. */
-    private void reportWrongThreadMetric() {
-        Counter.logIncrement(
-                CONTENT_CAPTURE_WRONG_THREAD_METRIC_ID, mWrongThreadCount.getAndSet(0));
-    }
-
-    /**
-     * Ensures that {@code r} will be running on the assigned thread.
-     *
-     * <p>This is to prevent unnecessary delegation to Handler that results in fragmented runnable.
-     * </p>
-     */
-    private void runOnContentCaptureThread(@NonNull Runnable r) {
-        if (!mContentCaptureHandler.getLooper().isCurrentThread()) {
-            mContentCaptureHandler.post(r);
-        } else {
-            r.run();
-        }
-    }
-
-    private void clearAndRunOnContentCaptureThread(@NonNull Runnable r, int what) {
-        if (!mContentCaptureHandler.getLooper().isCurrentThread()) {
-            mContentCaptureHandler.removeMessages(what);
-            mContentCaptureHandler.post(r);
-        } else {
-            r.run();
-        }
-    }
-
-    private void runOnUiThread(@NonNull Runnable r) {
-        if (mUiHandler.getLooper().isCurrentThread()) {
-            r.run();
-        } else {
-            mUiHandler.post(r);
-        }
-    }
-
-    /**
-     * Holds {@link ContentCaptureSession} and related {@link ViewStructure} for processing.
-     */
-    private static final class ViewStructureSession {
-        @Nullable private ContentCaptureSession mSession;
-        @Nullable private ViewStructure mStructure;
-
-        ViewStructureSession() {}
-
-        void setSession(@Nullable ContentCaptureSession session) {
-            this.mSession = session;
-        }
-
-        void setStructure(@Nullable ViewStructure struct) {
-            this.mStructure = struct;
-        }
-
-        /**
-         * Calls {@link ContentCaptureSession#notifyViewAppeared(ViewStructure)} if the session and
-         * the view structure are available.
-         */
-        void notifyViewAppeared() {
-            if (mSession != null && mStructure != null) {
-                mSession.notifyViewAppeared(mStructure);
-            }
-        }
-    }
-}
diff --git a/core/java/android/view/flags/view_flags.aconfig b/core/java/android/view/flags/view_flags.aconfig
index 4d4e4af..f570a9a 100644
--- a/core/java/android/view/flags/view_flags.aconfig
+++ b/core/java/android/view/flags/view_flags.aconfig
@@ -89,4 +89,12 @@
     metadata {
         purpose: PURPOSE_BUGFIX
     }
+}
+
+flag {
+    name: "disable_draw_wake_lock"
+    namespace: "wear_frameworks"
+    description: "Disable Draw Wakelock starting U."
+    bug: "331698645"
+    is_fixed_read_only: true
 }
\ No newline at end of file
diff --git a/core/java/android/webkit/WebViewUpdateManager.java b/core/java/android/webkit/WebViewUpdateManager.java
index 07576a2..dd48df9 100644
--- a/core/java/android/webkit/WebViewUpdateManager.java
+++ b/core/java/android/webkit/WebViewUpdateManager.java
@@ -101,6 +101,8 @@
      * enabled for all users.
      */
     @SuppressLint({"ParcelableList", "ArrayReturn"})
+    @RequiresPermission(allOf = {android.Manifest.permission.INTERACT_ACROSS_USERS,
+            android.Manifest.permission.QUERY_ALL_PACKAGES})
     public @NonNull WebViewProviderInfo[] getValidWebViewPackages() {
         try {
             return mService.getValidWebViewPackages();
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 3c5623f..9512347 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -17,8 +17,10 @@
 package android.widget;
 
 import static android.appwidget.flags.Flags.FLAG_DRAW_DATA_PARCEL;
+import static android.appwidget.flags.Flags.FLAG_REMOTE_VIEWS_PROTO;
 import static android.appwidget.flags.Flags.drawDataParcel;
 import static android.appwidget.flags.Flags.remoteAdapterConversion;
+import static android.util.proto.ProtoInputStream.NO_MORE_FIELDS;
 import static android.view.inputmethod.Flags.FLAG_HOME_SCREEN_HANDWRITING_DELEGATOR;
 
 import android.annotation.AttrRes;
@@ -60,6 +62,7 @@
 import android.content.res.loader.ResourcesLoader;
 import android.content.res.loader.ResourcesProvider;
 import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.graphics.BlendMode;
 import android.graphics.Outline;
 import android.graphics.PorterDuff;
@@ -88,12 +91,17 @@
 import android.util.IntArray;
 import android.util.Log;
 import android.util.LongArray;
+import android.util.LongSparseArray;
 import android.util.Pair;
 import android.util.SizeF;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.util.TypedValue;
 import android.util.TypedValue.ComplexDimensionUnit;
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoOutputStream;
+import android.util.proto.ProtoStream;
+import android.util.proto.ProtoUtils;
 import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.LayoutInflater.Filter;
@@ -135,10 +143,12 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
@@ -1231,8 +1241,8 @@
     /**
      * @hide
      */
-    public CompletableFuture<Void> collectAllIntents() {
-        return mCollectionCache.collectAllIntentsNoComplete(this);
+    public CompletableFuture<Void> collectAllIntents(int bitmapSizeLimit) {
+        return mCollectionCache.collectAllIntentsNoComplete(this, bitmapSizeLimit);
     }
 
     private class RemoteCollectionCache {
@@ -1259,11 +1269,16 @@
                 int intentId = in.readInt();
                 String intentUri = in.readString8();
                 RemoteCollectionItems items = new RemoteCollectionItems(in, currentRootData);
-                mIdToUriMapping.put(intentId, intentUri);
-                mUriToCollectionMapping.put(intentUri, items);
+                addMapping(intentId, intentUri, items);
             }
         }
 
+        void addMapping(int intentId, String intentUri, RemoteCollectionItems items) {
+            mIdToUriMapping.put(intentId, intentUri);
+            mUriToCollectionMapping.put(intentUri, items);
+        }
+
+
         void setHierarchyDataForId(int intentId, HierarchyRootData data) {
             String uri = mIdToUriMapping.get(intentId);
             if (mUriToCollectionMapping.get(uri) == null) {
@@ -1281,7 +1296,7 @@
         }
 
         public @NonNull CompletableFuture<Void> collectAllIntentsNoComplete(
-                @NonNull RemoteViews inViews) {
+                @NonNull RemoteViews inViews, int bitmapSizeLimit) {
             SparseArray<Intent> idToIntentMapping = new SparseArray<>();
             // Collect the number of uinque Intent (which is equal to the number of new connections
             // to make) for size allocation and exclude certain collections from being written to
@@ -1309,7 +1324,11 @@
                     ? 0
                     : remainingSize / numOfIntents;
 
-            return connectAllUniqueIntents(individualSize, idToIntentMapping);
+            int individualBitmapSizeLimit = (bitmapSizeLimit - getBitmapMemoryUsedByActions())
+                    / numOfIntents;
+
+            return connectAllUniqueIntents(individualSize, individualBitmapSizeLimit,
+                    idToIntentMapping);
         }
 
         private void collectAllIntentsInternal(@NonNull RemoteViews inViews,
@@ -1375,13 +1394,13 @@
         }
 
         private @NonNull CompletableFuture<Void> connectAllUniqueIntents(int individualSize,
-                @NonNull SparseArray<Intent> idToIntentMapping) {
+                int individualBitmapSize, @NonNull SparseArray<Intent> idToIntentMapping) {
             List<CompletableFuture<Void>> intentFutureList = new ArrayList<>();
             for (int i = 0; i < idToIntentMapping.size(); i++) {
                 String currentIntentUri = mIdToUriMapping.get(idToIntentMapping.keyAt(i));
                 Intent currentIntent = idToIntentMapping.valueAt(i);
                 intentFutureList.add(getItemsFutureFromIntentWithTimeout(currentIntent,
-                        individualSize)
+                        individualSize, individualBitmapSize)
                         .thenAccept(items -> {
                             items.setHierarchyRootData(getHierarchyRootData());
                             mUriToCollectionMapping.put(currentIntentUri, items);
@@ -1392,7 +1411,7 @@
         }
 
         private static CompletableFuture<RemoteCollectionItems> getItemsFutureFromIntentWithTimeout(
-                Intent intent, int individualSize) {
+                Intent intent, int individualSize, int individualBitmapSize) {
             if (intent == null) {
                 Log.e(LOG_TAG, "Null intent received when generating adapter future");
                 return CompletableFuture.completedFuture(new RemoteCollectionItems
@@ -1410,7 +1429,8 @@
                             RemoteCollectionItems items;
                             try {
                                 items = IRemoteViewsFactory.Stub.asInterface(iBinder)
-                                        .getRemoteCollectionItems(individualSize);
+                                        .getRemoteCollectionItems(individualSize,
+                                                individualBitmapSize);
                             } catch (RemoteException re) {
                                 items = new RemoteCollectionItems.Builder().build();
                                 Log.e(LOG_TAG, "Error getting collection items from the"
@@ -1453,6 +1473,87 @@
                 mUriToCollectionMapping.get(intentUri).writeToParcel(out, flags, true);
             }
         }
+
+        public void writeToProto(Context context, ProtoOutputStream out) {
+            final long token = out.start(RemoteViewsProto.REMOTE_COLLECTION_CACHE);
+            for (int i = 0; i < mIdToUriMapping.size(); i++) {
+                final long entryToken = out.start(RemoteViewsProto.RemoteCollectionCache.ENTRIES);
+                out.write(RemoteViewsProto.RemoteCollectionCache.Entry.ID,
+                        mIdToUriMapping.keyAt(i));
+                String intentUri = mIdToUriMapping.valueAt(i);
+                out.write(RemoteViewsProto.RemoteCollectionCache.Entry.URI, intentUri);
+                final long itemsToken = out.start(
+                        RemoteViewsProto.RemoteCollectionCache.Entry.ITEMS);
+                mUriToCollectionMapping.get(intentUri).writeToProto(context, out, /* attached= */
+                        true);
+                out.end(itemsToken);
+                out.end(entryToken);
+            }
+            out.end(token);
+        }
+    }
+
+    private PendingResources<RemoteCollectionCache> populateRemoteCollectionCacheFromProto(
+            ProtoInputStream in) throws Exception {
+        final ArrayList<LongSparseArray<Object>> entries = new ArrayList<>();
+        final long token = in.start(RemoteViewsProto.REMOTE_COLLECTION_CACHE);
+        while (in.nextField() != NO_MORE_FIELDS) {
+            switch (in.getFieldNumber()) {
+                case (int) RemoteViewsProto.RemoteCollectionCache.ENTRIES:
+                    final LongSparseArray<Object> entry = new LongSparseArray<>();
+                    final long entryToken = in.start(
+                            RemoteViewsProto.RemoteCollectionCache.ENTRIES);
+                    while (in.nextField() != NO_MORE_FIELDS) {
+                        switch (in.getFieldNumber()) {
+                            case (int) RemoteViewsProto.RemoteCollectionCache.Entry.ID:
+                                entry.put(RemoteViewsProto.RemoteCollectionCache.Entry.ID,
+                                        in.readInt(
+                                                RemoteViewsProto.RemoteCollectionCache.Entry.ID));
+                                break;
+                            case (int) RemoteViewsProto.RemoteCollectionCache.Entry.URI:
+                                entry.put(RemoteViewsProto.RemoteCollectionCache.Entry.URI,
+                                        in.readString(
+                                                RemoteViewsProto.RemoteCollectionCache.Entry.URI));
+                                break;
+                            case (int) RemoteViewsProto.RemoteCollectionCache.Entry.ITEMS:
+                                final long itemsToken = in.start(
+                                        RemoteViewsProto.RemoteCollectionCache.Entry.ITEMS);
+                                entry.put(RemoteViewsProto.RemoteCollectionCache.Entry.ITEMS,
+                                        RemoteCollectionItems.createFromProto(in));
+                                in.end(itemsToken);
+                                break;
+                            default:
+                                Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n"
+                                        + ProtoUtils.currentFieldToString(in));
+                        }
+                    }
+                    in.end(entryToken);
+                    checkContainsKeys(entry,
+                            new long[]{RemoteViewsProto.RemoteCollectionCache.Entry.ID,
+                                    RemoteViewsProto.RemoteCollectionCache.Entry.URI,
+                                    RemoteViewsProto.RemoteCollectionCache.Entry.ITEMS});
+                    entries.add(entry);
+                    break;
+                default:
+                    Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n"
+                            + ProtoUtils.currentFieldToString(in));
+            }
+        }
+        in.end(token);
+
+        return (context, resources, rootData, depth) -> {
+            for (LongSparseArray<Object> entry : entries) {
+                int id = (int) entry.get(RemoteViewsProto.RemoteCollectionCache.Entry.ID);
+                String uri = (String) entry.get(RemoteViewsProto.RemoteCollectionCache.Entry.URI);
+                // Depth resets to 0 for RemoteCollectionItems
+                RemoteCollectionItems items = ((PendingResources<RemoteCollectionItems>) entry.get(
+                        RemoteViewsProto.RemoteCollectionCache.Entry.ITEMS)).create(context,
+                        resources, rootData, depth);
+                rootData.mRemoteCollectionCache.addMapping(id, uri, items);
+            }
+            // Redundant return, but type signature requires we return something.
+            return rootData.mRemoteCollectionCache;
+        };
     }
 
     private class SetRemoteViewsAdapterIntent extends Action {
@@ -2002,7 +2103,14 @@
         }
     }
 
-    private static class BitmapCache {
+    /**
+     * @hide
+     */
+    @NonNull BitmapCache getBitmapCache() {
+        return mBitmapCache;
+    }
+
+    static class BitmapCache {
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         ArrayList<Bitmap> mBitmaps;
         SparseIntArray mBitmapHashes;
@@ -2024,6 +2132,11 @@
             }
         }
 
+        BitmapCache(BitmapCache other) {
+            mBitmaps = new ArrayList<>(other.mBitmaps);
+            mBitmapHashes = other.mBitmapHashes.clone();
+        }
+
         public int getBitmapId(Bitmap b) {
             if (b == null) {
                 return -1;
@@ -2056,6 +2169,15 @@
             dest.writeTypedList(mBitmaps, flags);
         }
 
+        public void writeBitmapsToProto(ProtoOutputStream out) {
+            for (int i = 0; i < mBitmaps.size(); i++) {
+                final Bitmap bitmap = mBitmaps.get(i);
+                final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+                bitmap.compress(Bitmap.CompressFormat.WEBP_LOSSLESS, 100, bytes);
+                out.write(RemoteViewsProto.BITMAP_CACHE, bytes.toByteArray());
+            }
+        }
+
         public int getBitmapMemory() {
             if (mBitmapMemory < 0) {
                 mBitmapMemory = 0;
@@ -2066,6 +2188,12 @@
             }
             return mBitmapMemory;
         }
+
+        public void mergeWithCache(BitmapCache other) {
+            for (int i = 0; i < other.mBitmaps.size(); i++) {
+                getBitmapId(other.mBitmaps.get(i));
+            }
+        }
     }
 
     private class BitmapReflectionAction extends Action {
@@ -7338,6 +7466,38 @@
         return true;
     }
 
+    private int getBitmapMemoryUsedByActions() {
+        Set<Integer> bitmapIdSet = getBitmapIdsUsedByActions(new HashSet<>());
+        int result = 0;
+        for (int bitmapId: bitmapIdSet) {
+            result += mBitmapCache.getBitmapForId(bitmapId).getAllocationByteCount();
+        }
+
+        return result;
+    }
+
+    private Set<Integer> getBitmapIdsUsedByActions(@NonNull Set<Integer> intSet) {
+        if (hasSizedRemoteViews()) {
+            for (RemoteViews views: mSizedRemoteViews) {
+                views.getBitmapIdsUsedByActions(intSet);
+            }
+        } else if (hasLandscapeAndPortraitLayouts()) {
+            mLandscape.getBitmapIdsUsedByActions(intSet);
+            mPortrait.getBitmapIdsUsedByActions(intSet);
+        } else if (mActions != null) {
+            for (Action action: mActions) {
+                if (action instanceof ViewGroupActionAdd vgaa
+                        && vgaa.mNestedViews != null) {
+                    vgaa.mNestedViews.getBitmapIdsUsedByActions(intSet);
+                } else if (action instanceof BitmapReflectionAction bitmapAction) {
+                    intSet.add(bitmapAction.mBitmapId);
+                }
+            }
+        }
+
+        return intSet;
+    }
+
     /** Representation of a fixed list of items to be displayed in a RemoteViews collection. */
     public static final class RemoteCollectionItems implements Parcelable {
         private final long[] mIds;
@@ -7460,6 +7620,127 @@
             dest.restoreAllowSquashing(prevAllowSquashing);
         }
 
+        /** @hide */
+        public void writeToProto(Context context, ProtoOutputStream out) {
+            writeToProto(context, out, /* attached= */ false);
+        }
+
+        private void writeToProto(Context context, ProtoOutputStream out, boolean attached) {
+            for (long id : mIds) {
+                out.write(RemoteViewsProto.RemoteCollectionItems.IDS, id);
+            }
+
+            boolean restoreRoot = false;
+            out.write(RemoteViewsProto.RemoteCollectionItems.ATTACHED, attached);
+            if (!attached && mViews.length > 0 && !mViews[0].mIsRoot) {
+                restoreRoot = true;
+                mViews[0].mIsRoot = true;
+            }
+            for (RemoteViews view : mViews) {
+                final long viewsToken = out.start(RemoteViewsProto.RemoteCollectionItems.VIEWS);
+                view.writePreviewToProto(context, out);
+                out.end(viewsToken);
+            }
+            if (restoreRoot) mViews[0].mIsRoot = false;
+            out.write(RemoteViewsProto.RemoteCollectionItems.HAS_STABLE_IDS, mHasStableIds);
+            out.write(RemoteViewsProto.RemoteCollectionItems.VIEW_TYPE_COUNT, mViewTypeCount);
+        }
+
+        /**
+         * Overload used for testing unattached RemoteCollectionItems serialization.
+         *
+         * @hide
+         */
+        public static RemoteCollectionItems createFromProto(Context context, ProtoInputStream in)
+                throws Exception {
+            return createFromProto(in).create(context, context.getResources(), /* rootData= */
+                    null, 0);
+        }
+
+        /** @hide */
+        public static PendingResources<RemoteCollectionItems> createFromProto(ProtoInputStream in)
+                throws Exception {
+            final LongSparseArray<Object> values = new LongSparseArray<>();
+            values.put(RemoteViewsProto.RemoteCollectionItems.IDS, new ArrayList<Long>());
+            values.put(RemoteViewsProto.RemoteCollectionItems.VIEWS,
+                    new ArrayList<PendingResources<RemoteViews>>());
+            while (in.nextField() != NO_MORE_FIELDS) {
+                switch (in.getFieldNumber()) {
+                    case (int) RemoteViewsProto.RemoteCollectionItems.IDS:
+                        ((ArrayList<Long>) values.get(
+                                RemoteViewsProto.RemoteCollectionItems.IDS)).add(
+                                in.readLong(RemoteViewsProto.RemoteCollectionItems.IDS));
+                        break;
+                    case (int) RemoteViewsProto.RemoteCollectionItems.VIEWS:
+                        final long viewsToken = in.start(
+                                RemoteViewsProto.RemoteCollectionItems.VIEWS);
+                        ((ArrayList<PendingResources<RemoteViews>>) values.get(
+                                RemoteViewsProto.RemoteCollectionItems.VIEWS)).add(
+                                RemoteViews.createFromProto(in));
+                        in.end(viewsToken);
+                        break;
+                    case (int) RemoteViewsProto.RemoteCollectionItems.HAS_STABLE_IDS:
+                        values.put(RemoteViewsProto.RemoteCollectionItems.HAS_STABLE_IDS,
+                                in.readBoolean(
+                                        RemoteViewsProto.RemoteCollectionItems.HAS_STABLE_IDS));
+                        break;
+                    case (int) RemoteViewsProto.RemoteCollectionItems.VIEW_TYPE_COUNT:
+                        values.put(RemoteViewsProto.RemoteCollectionItems.VIEW_TYPE_COUNT,
+                                in.readInt(RemoteViewsProto.RemoteCollectionItems.VIEW_TYPE_COUNT));
+                        break;
+                    case (int) RemoteViewsProto.RemoteCollectionItems.ATTACHED:
+                        values.put(RemoteViewsProto.RemoteCollectionItems.ATTACHED,
+                                in.readBoolean(RemoteViewsProto.RemoteCollectionItems.ATTACHED));
+                        break;
+                    default:
+                        Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n"
+                                + ProtoUtils.currentFieldToString(in));
+                }
+            }
+
+            checkContainsKeys(values,
+                    new long[]{RemoteViewsProto.RemoteCollectionItems.VIEW_TYPE_COUNT});
+            return (context, resources, rootData, depth) -> {
+                List<Long> idList = (List<Long>) values.get(
+                        RemoteViewsProto.RemoteCollectionItems.IDS);
+                long[] ids = new long[idList.size()];
+                for (int i = 0; i < idList.size(); i++) {
+                    ids[i] = idList.get(i);
+                }
+                boolean attached = (boolean) values.get(
+                        RemoteViewsProto.RemoteCollectionItems.ATTACHED, false);
+                List<PendingResources<RemoteViews>> pendingViews =
+                        (List<PendingResources<RemoteViews>>) values.get(
+                                RemoteViewsProto.RemoteCollectionItems.VIEWS);
+                RemoteViews[] views = new RemoteViews[pendingViews.size()];
+
+                if (attached && rootData == null) {
+                    throw new IllegalStateException("Cannot create a RemoteCollectionItems from "
+                            + "proto that was attached without providing HierarchyRootData");
+                }
+
+                int firstChildIndex = 0;
+                if (!attached && pendingViews.size() > 0) {
+                    // If written as unattached, get HierarchyRootData from first view
+                    views[0] = pendingViews.get(0).create(context, resources, /* rootData= */ null,
+                            /* depth= */ 0);
+                    rootData = views[0].getHierarchyRootData();
+                    firstChildIndex = 1;
+                }
+                for (int i = firstChildIndex; i < views.length; i++) {
+                    // Depth is reset to 0 for RemoteCollectionItems item views, see Parcel
+                    // constructor.
+                    views[i] = pendingViews.get(i).create(context, resources, rootData,
+                            /* depth= */ 0);
+                }
+                return new RemoteCollectionItems(ids, views,
+                        (boolean) values.get(RemoteViewsProto.RemoteCollectionItems.HAS_STABLE_IDS,
+                                false),
+                        (int) values.get(RemoteViewsProto.RemoteCollectionItems.VIEW_TYPE_COUNT,
+                                0));
+            };
+        }
+
         /**
          * Returns the id for {@code position}. See {@link #hasStableIds()} for whether this id
          * should be considered meaningful across collection updates.
@@ -7822,4 +8103,308 @@
             mClassCookies = classCookies;
         }
     }
+
+    /**
+     * Write this RemoteViews to proto.
+     * @hide
+     */
+    @FlaggedApi(FLAG_REMOTE_VIEWS_PROTO)
+    public void writePreviewToProto(@NonNull Context context, @NonNull ProtoOutputStream out) {
+        if (mApplication != null) {
+            // mApplication may be null if this was created with DrawInstructions constructor.
+            out.write(RemoteViewsProto.PACKAGE_NAME, mApplication.packageName);
+        }
+        Resources appResources = getContextForResourcesEnsuringCorrectCachedApkPaths(
+                context).getResources();
+        if (mLayoutId != 0) {
+            out.write(RemoteViewsProto.LAYOUT_ID, appResources.getResourceName(mLayoutId));
+        }
+        if (mLightBackgroundLayoutId != 0) {
+            out.write(RemoteViewsProto.LIGHT_BACKGROUND_LAYOUT_ID,
+                    appResources.getResourceName(mLightBackgroundLayoutId));
+        }
+        if (mViewId != 0 && mViewId != -1) {
+            out.write(RemoteViewsProto.VIEW_ID, appResources.getResourceName(mViewId));
+        }
+        if (mIsRoot) {
+            mBitmapCache.writeBitmapsToProto(out);
+            mCollectionCache.writeToProto(context, out);
+        }
+        out.write(RemoteViewsProto.IS_ROOT, mIsRoot);
+        out.write(RemoteViewsProto.APPLY_FLAGS, mApplyFlags);
+        out.write(RemoteViewsProto.HAS_DRAW_INSTRUCTIONS, mHasDrawInstructions);
+        if (mProviderInstanceId != -1) {
+            out.write(RemoteViewsProto.PROVIDER_INSTANCE_ID, mProviderInstanceId);
+        }
+
+        if (!hasMultipleLayouts()) {
+            out.write(RemoteViewsProto.MODE, MODE_NORMAL);
+            if (mIdealSize != null) {
+                final long token = out.start(RemoteViewsProto.IDEAL_SIZE);
+                out.write(SizeFProto.WIDTH, mIdealSize.getWidth());
+                out.write(SizeFProto.HEIGHT, mIdealSize.getHeight());
+                out.end(token);
+            }
+        } else if (hasSizedRemoteViews()) {
+            out.write(RemoteViewsProto.MODE, MODE_HAS_SIZED_REMOTEVIEWS);
+            for (RemoteViews view : mSizedRemoteViews) {
+                final long sizedViewToken = out.start(RemoteViewsProto.SIZED_REMOTEVIEWS);
+                view.writePreviewToProto(context, out);
+                out.end(sizedViewToken);
+            }
+        } else {
+            out.write(RemoteViewsProto.MODE, MODE_HAS_LANDSCAPE_AND_PORTRAIT);
+            final long landscapeViewToken = out.start(RemoteViewsProto.LANDSCAPE_REMOTEVIEWS);
+            mLandscape.writePreviewToProto(context, out);
+            out.end(landscapeViewToken);
+            final long portraitViewToken = out.start(RemoteViewsProto.PORTRAIT_REMOTEVIEWS);
+            mPortrait.writePreviewToProto(context, out);
+            out.end(portraitViewToken);
+        }
+    }
+
+    /**
+     * Create a RemoteViews from proto input.
+     * @hide
+     */
+    @FlaggedApi(FLAG_REMOTE_VIEWS_PROTO)
+    public static RemoteViews createPreviewFromProto(Context context, ProtoInputStream in)
+            throws Exception {
+        return createFromProto(in).create(context, context.getResources(), /* rootData= */ null,
+                /* depth= */ 0);
+    }
+
+    private static PendingResources<RemoteViews> createFromProto(ProtoInputStream in)
+            throws Exception {
+        // Grouping these variables into an anonymous object allows us to access them through `ref`
+        // (which is final) later in the lambda.
+        final var ref = new Object() {
+            final RemoteViews mRv = new RemoteViews();
+            int mMode = 0;
+            int mApplyFlags = 0;
+            long mProviderInstanceId = -1;
+            String mPackageName = null;
+            SizeF mIdealSize = null;
+            String mLayoutResName = null;
+            String mLightBackgroundResName = null;
+            String mViewResName = null;
+            final List<PendingResources<RemoteViews>> mSizedRemoteViews = new ArrayList<>();
+            PendingResources<RemoteViews> mLandscapeViews = null;
+            PendingResources<RemoteViews> mPortraitViews = null;
+            PendingResources<RemoteCollectionCache> mPopulateRemoteCollectionCache = null;
+            boolean mIsRoot = false;
+            boolean mHasDrawInstructions = false;
+        };
+
+        try {
+            while (in.nextField() != NO_MORE_FIELDS) {
+                switch (in.getFieldNumber()) {
+                    case (int) RemoteViewsProto.MODE:
+                        ref.mMode = in.readInt(RemoteViewsProto.MODE);
+                        break;
+                    case (int) RemoteViewsProto.PACKAGE_NAME:
+                        ref.mPackageName = in.readString(RemoteViewsProto.PACKAGE_NAME);
+                        break;
+                    case (int) RemoteViewsProto.IDEAL_SIZE:
+                        final long idealSizeToken = in.start(RemoteViewsProto.IDEAL_SIZE);
+                        ref.mIdealSize = createSizeFFromProto(in);
+                        in.end(idealSizeToken);
+                        break;
+                    case (int) RemoteViewsProto.LAYOUT_ID:
+                        ref.mLayoutResName = in.readString(RemoteViewsProto.LAYOUT_ID);
+                        break;
+                    case (int) RemoteViewsProto.LIGHT_BACKGROUND_LAYOUT_ID:
+                        ref.mLightBackgroundResName = in.readString(
+                                RemoteViewsProto.LIGHT_BACKGROUND_LAYOUT_ID);
+                        break;
+                    case (int) RemoteViewsProto.VIEW_ID:
+                        ref.mViewResName = in.readString(RemoteViewsProto.VIEW_ID);
+                        break;
+                    case (int) RemoteViewsProto.APPLY_FLAGS:
+                        ref.mApplyFlags = in.readInt(RemoteViewsProto.APPLY_FLAGS);
+                        break;
+                    case (int) RemoteViewsProto.PROVIDER_INSTANCE_ID:
+                        ref.mProviderInstanceId = in.readInt(RemoteViewsProto.PROVIDER_INSTANCE_ID);
+                        break;
+                    case (int) RemoteViewsProto.SIZED_REMOTEVIEWS:
+                        final long sizedToken = in.start(RemoteViewsProto.SIZED_REMOTEVIEWS);
+                        ref.mSizedRemoteViews.add(createFromProto(in));
+                        in.end(sizedToken);
+                        break;
+                    case (int) RemoteViewsProto.LANDSCAPE_REMOTEVIEWS:
+                        final long landscapeToken = in.start(
+                                RemoteViewsProto.LANDSCAPE_REMOTEVIEWS);
+                        ref.mLandscapeViews = createFromProto(in);
+                        in.end(landscapeToken);
+                        break;
+                    case (int) RemoteViewsProto.PORTRAIT_REMOTEVIEWS:
+                        final long portraitToken = in.start(RemoteViewsProto.PORTRAIT_REMOTEVIEWS);
+                        ref.mPortraitViews = createFromProto(in);
+                        in.end(portraitToken);
+                        break;
+                    case (int) RemoteViewsProto.BITMAP_CACHE:
+                        byte[] src = in.readBytes(RemoteViewsProto.BITMAP_CACHE);
+                        Bitmap bitmap = BitmapFactory.decodeByteArray(src, 0, src.length);
+                        ref.mRv.mBitmapCache.getBitmapId(bitmap);
+                        break;
+                    case (int) RemoteViewsProto.REMOTE_COLLECTION_CACHE:
+                        final long collectionToken = in.start(
+                                RemoteViewsProto.REMOTE_COLLECTION_CACHE);
+                        ref.mPopulateRemoteCollectionCache =
+                                ref.mRv.populateRemoteCollectionCacheFromProto(in);
+                        in.end(collectionToken);
+                        break;
+                    case (int) RemoteViewsProto.IS_ROOT:
+                        ref.mIsRoot = in.readBoolean(RemoteViewsProto.IS_ROOT);
+                        break;
+                    case (int) RemoteViewsProto.HAS_DRAW_INSTRUCTIONS:
+                        ref.mHasDrawInstructions = in.readBoolean(
+                                RemoteViewsProto.HAS_DRAW_INSTRUCTIONS);
+                        break;
+                    default:
+                        Log.w(LOG_TAG, "Unhandled field while reading RemoteViews proto!\n"
+                                + ProtoUtils.currentFieldToString(in));
+                }
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+
+        return (context, resources, rootData, depth) -> {
+            if (depth > MAX_NESTED_VIEWS && (UserHandle.getAppId(Binder.getCallingUid())
+                    != Process.SYSTEM_UID)) {
+                throw new IllegalArgumentException("Too many nested views.");
+            }
+            depth++;
+
+            RemoteViews rv = ref.mRv;
+            rv.mApplyFlags = ref.mApplyFlags;
+            rv.mIsRoot = ref.mIsRoot;
+            rv.mHasDrawInstructions = ref.mHasDrawInstructions;
+
+            // The root view will read its HierarchyRootData (bitmap cache, collection cache) from
+            // proto; all nested views will instead get it through the rootData parameter.
+            if (rootData == null) {
+                if (!rv.mIsRoot || depth != 1) {
+                    throw new IllegalStateException(
+                            "A nested view did not receive HierarchyRootData");
+                }
+                rootData = rv.getHierarchyRootData();
+            } else {
+                rv.configureAsChild(rootData);
+            }
+
+            Context appContext = null;
+            Resources appResources = null;
+            if (!ref.mHasDrawInstructions) {
+                checkProtoResultNotNull(ref.mPackageName, "No application info");
+                rv.mApplication = context.getPackageManager().getApplicationInfo(ref.mPackageName,
+                        /* flags= */ 0);
+                appContext = rv.getContextForResourcesEnsuringCorrectCachedApkPaths(context);
+                appResources = appContext.getResources();
+
+                checkProtoResultNotNull(ref.mLayoutResName, "No layout id");
+                rv.mLayoutId = appResources.getIdentifier(ref.mLayoutResName, /* defType= */ null,
+                        /* defPackage= */ null);
+                checkValidResource(rv.mLayoutId, "Invalid layout id", ref.mLayoutResName);
+
+                if (ref.mViewResName != null) {
+                    rv.mViewId = appResources.getIdentifier(ref.mViewResName, /* defType= */ null,
+                            /* defPackage= */ null);
+                    checkValidResource(rv.mViewId, "Invalid view id", ref.mViewResName);
+                }
+
+                if (ref.mLightBackgroundResName != null) {
+                    int lightBackgroundLayoutId = appResources.getIdentifier(
+                            ref.mLightBackgroundResName,
+                            /* defType= */ null, /* defPackage= */ null);
+                    checkValidResource(lightBackgroundLayoutId,
+                            "Invalid light background layout id", ref.mLightBackgroundResName);
+                    rv.setLightBackgroundLayoutId(lightBackgroundLayoutId);
+                }
+            }
+            if (ref.mPopulateRemoteCollectionCache != null) {
+                ref.mPopulateRemoteCollectionCache.create(context, resources, rootData, depth);
+            }
+            if (ref.mProviderInstanceId != -1) {
+                rv.mProviderInstanceId = ref.mProviderInstanceId;
+            }
+            if (ref.mMode == MODE_NORMAL) {
+                rv.setIdealSize(ref.mIdealSize);
+                return rv;
+            } else if (ref.mMode == MODE_HAS_SIZED_REMOTEVIEWS) {
+                List<RemoteViews> sizedViews = new ArrayList<>();
+                for (RemoteViews.PendingResources<RemoteViews> pendingViews :
+                        ref.mSizedRemoteViews) {
+                    RemoteViews views = pendingViews.create(context, resources, rootData, depth);
+                    sizedViews.add(views);
+                }
+                rv.initializeSizedRemoteViews(sizedViews.iterator());
+                return rv;
+            } else if (ref.mMode == MODE_HAS_LANDSCAPE_AND_PORTRAIT) {
+                checkProtoResultNotNull(ref.mLandscapeViews, "Missing landscape views");
+                checkProtoResultNotNull(ref.mPortraitViews, "Missing portrait views");
+                RemoteViews parentRv = new RemoteViews(
+                        ref.mLandscapeViews.create(context, resources, rootData, depth),
+                        ref.mPortraitViews.create(context, resources, rootData, depth));
+                parentRv.initializeFrom(/* src= */ rv, /* hierarchyRoot= */ rv);
+                return parentRv;
+            } else {
+                throw new InvalidProtoException(ref.mMode + " is not a valid mode.");
+            }
+        };
+    }
+
+    private static class InvalidProtoException extends Exception {
+        InvalidProtoException(String message) {
+            super(message);
+        }
+    }
+
+    private interface PendingResources<T> {
+        T create(Context context, Resources appResources, HierarchyRootData rootData, int depth)
+                throws Exception;
+    }
+
+    private static void checkValidResource(int id, String message, String resName)
+            throws Exception {
+        if (id == 0) throw new Exception(message + ": " + resName);
+    }
+
+    private static void checkProtoResultNotNull(Object o, String message)
+            throws InvalidProtoException {
+        if (o == null) {
+            throw new InvalidProtoException(message);
+        }
+    }
+
+    private static void checkContainsKeys(LongSparseArray<?> array, long[] requiredFields) {
+        for (long requiredField : requiredFields) {
+            if (array.indexOfKey(requiredField) < 0) {
+                throw new IllegalArgumentException(
+                        "RemoteViews proto missing field: " + ProtoStream.getFieldIdString(
+                                requiredField));
+            }
+        }
+    }
+
+    private static SizeF createSizeFFromProto(ProtoInputStream in) throws Exception {
+        float width = 0;
+        float height = 0;
+        while (in.nextField() != NO_MORE_FIELDS) {
+            switch (in.getFieldNumber()) {
+                case (int) SizeFProto.WIDTH:
+                    width = in.readFloat(SizeFProto.WIDTH);
+                    break;
+                case (int) SizeFProto.HEIGHT:
+                    height = in.readFloat(SizeFProto.HEIGHT);
+                    break;
+                default:
+                    Log.w(LOG_TAG, "Unhandled field while reading SizeF proto!\n"
+                            + ProtoUtils.currentFieldToString(in));
+            }
+        }
+
+        return new SizeF(width, height);
+    }
 }
diff --git a/core/java/android/widget/RemoteViewsService.java b/core/java/android/widget/RemoteViewsService.java
index c79eac6..4045d42 100644
--- a/core/java/android/widget/RemoteViewsService.java
+++ b/core/java/android/widget/RemoteViewsService.java
@@ -128,7 +128,8 @@
         /**
          * @hide
          */
-        default RemoteViews.RemoteCollectionItems getRemoteCollectionItems(int capSize) {
+        default RemoteViews.RemoteCollectionItems getRemoteCollectionItems(int capSize,
+                int capBitmapSize) {
             RemoteViews.RemoteCollectionItems items = new RemoteViews.RemoteCollectionItems
                     .Builder().build();
             Parcel capSizeTestParcel = Parcel.obtain();
@@ -138,6 +139,7 @@
             try {
                 RemoteViews.RemoteCollectionItems.Builder itemsBuilder =
                         new RemoteViews.RemoteCollectionItems.Builder();
+                RemoteViews.BitmapCache testBitmapCache = null;
                 onDataSetChanged();
 
                 itemsBuilder.setHasStableIds(hasStableIds());
@@ -150,6 +152,15 @@
                     if (capSizeTestParcel.dataSize() > capSize) {
                         break;
                     }
+                    if (testBitmapCache == null) {
+                        testBitmapCache = new RemoteViews.BitmapCache(currentView.getBitmapCache());
+                    } else {
+                        testBitmapCache.mergeWithCache(currentView.getBitmapCache());
+                    }
+                    if (testBitmapCache.getBitmapMemory() >= capBitmapSize) {
+                        break;
+                    }
+
                     itemsBuilder.addItem(currentItemId, currentView);
                 }
 
@@ -266,11 +277,12 @@
         }
 
         @Override
-        public RemoteViews.RemoteCollectionItems getRemoteCollectionItems(int capSize) {
+        public RemoteViews.RemoteCollectionItems getRemoteCollectionItems(int capSize,
+                int capBitmapSize) {
             RemoteViews.RemoteCollectionItems items = new RemoteViews.RemoteCollectionItems
                     .Builder().build();
             try {
-                items = mFactory.getRemoteCollectionItems(capSize);
+                items = mFactory.getRemoteCollectionItems(capSize, capBitmapSize);
             } catch (Exception ex) {
                 Thread t = Thread.currentThread();
                 Thread.getDefaultUncaughtExceptionHandler().uncaughtException(t, ex);
diff --git a/core/java/android/widget/flags/notification_widget_flags.aconfig b/core/java/android/widget/flags/notification_widget_flags.aconfig
index 503e542..56a2cf7 100644
--- a/core/java/android/widget/flags/notification_widget_flags.aconfig
+++ b/core/java/android/widget/flags/notification_widget_flags.aconfig
@@ -57,3 +57,13 @@
     purpose: PURPOSE_BUGFIX
   }
 }
+
+flag {
+  name: "conversation_layout_use_maximum_child_height"
+  namespace: "systemui"
+  description: "MessagingChild always needs to be measured during MessagingLinearLayout onMeasure."
+  bug: "324537506"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
\ No newline at end of file
diff --git a/core/java/android/window/ClientWindowFrames.java b/core/java/android/window/ClientWindowFrames.java
index d5398e6..781a901 100644
--- a/core/java/android/window/ClientWindowFrames.java
+++ b/core/java/android/window/ClientWindowFrames.java
@@ -16,6 +16,8 @@
 
 package android.window;
 
+import static android.util.SequenceUtils.getInitSeq;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.graphics.Rect;
@@ -53,6 +55,9 @@
 
     public float compatScale = 1f;
 
+    /** To make sure the info update between client and system server is in order. */
+    public int seq = getInitSeq();
+
     public ClientWindowFrames() {
     }
 
@@ -74,6 +79,7 @@
         }
         isParentFrameClippedByDisplayCutout = other.isParentFrameClippedByDisplayCutout;
         compatScale = other.compatScale;
+        seq = other.seq;
     }
 
     /** Needed for AIDL out parameters. */
@@ -84,6 +90,7 @@
         attachedFrame = in.readTypedObject(Rect.CREATOR);
         isParentFrameClippedByDisplayCutout = in.readBoolean();
         compatScale = in.readFloat();
+        seq = in.readInt();
     }
 
     @Override
@@ -94,6 +101,7 @@
         dest.writeTypedObject(attachedFrame, flags);
         dest.writeBoolean(isParentFrameClippedByDisplayCutout);
         dest.writeFloat(compatScale);
+        dest.writeInt(seq);
     }
 
     @Override
@@ -116,6 +124,7 @@
             return false;
         }
         final ClientWindowFrames other = (ClientWindowFrames) o;
+        // seq is for internal bookkeeping only.
         return frame.equals(other.frame)
                 && displayFrame.equals(other.displayFrame)
                 && parentFrame.equals(other.parentFrame)
diff --git a/core/java/android/window/TaskFragmentAnimationParams.java b/core/java/android/window/TaskFragmentAnimationParams.java
index 85e96c9..67b22f9 100644
--- a/core/java/android/window/TaskFragmentAnimationParams.java
+++ b/core/java/android/window/TaskFragmentAnimationParams.java
@@ -171,7 +171,7 @@
      */
     public boolean hasOverrideAnimation() {
         return mOpenAnimationResId != DEFAULT_ANIMATION_RESOURCES_ID
-                || mChangeAnimationResId != DEFAULT_ANIMATION_BACKGROUND_COLOR
+                || mChangeAnimationResId != DEFAULT_ANIMATION_RESOURCES_ID
                 || mCloseAnimationResId != DEFAULT_ANIMATION_RESOURCES_ID;
     }
 
diff --git a/core/java/android/window/TransitionInfo.java b/core/java/android/window/TransitionInfo.java
index 8bd39fb..8ded608 100644
--- a/core/java/android/window/TransitionInfo.java
+++ b/core/java/android/window/TransitionInfo.java
@@ -663,6 +663,7 @@
         private final Rect mStartAbsBounds = new Rect();
         private final Rect mEndAbsBounds = new Rect();
         private final Point mEndRelOffset = new Point();
+        private final Point mEndParentSize = new Point();
         private ActivityManager.RunningTaskInfo mTaskInfo = null;
         private boolean mAllowEnterPip;
         private int mStartDisplayId = INVALID_DISPLAY;
@@ -697,6 +698,7 @@
             mStartAbsBounds.readFromParcel(in);
             mEndAbsBounds.readFromParcel(in);
             mEndRelOffset.readFromParcel(in);
+            mEndParentSize.readFromParcel(in);
             mTaskInfo = in.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR);
             mAllowEnterPip = in.readBoolean();
             mStartDisplayId = in.readInt();
@@ -721,6 +723,7 @@
             out.mStartAbsBounds.set(mStartAbsBounds);
             out.mEndAbsBounds.set(mEndAbsBounds);
             out.mEndRelOffset.set(mEndRelOffset);
+            out.mEndParentSize.set(mEndParentSize);
             out.mTaskInfo = mTaskInfo;
             out.mAllowEnterPip = mAllowEnterPip;
             out.mStartDisplayId = mStartDisplayId;
@@ -781,6 +784,13 @@
         }
 
         /**
+         * Sets the size of its parent container after the change.
+         */
+        public void setEndParentSize(int width, int height) {
+            mEndParentSize.set(width, height);
+        }
+
+        /**
          * Sets the taskinfo of this container if this is a task. WARNING: this takes the
          * reference, so don't modify it afterwards.
          */
@@ -916,6 +926,14 @@
             return mEndRelOffset;
         }
 
+        /**
+         * Returns the size of parent container after the change.
+         */
+        @NonNull
+        public Point getEndParentSize() {
+            return mEndParentSize;
+        }
+
         /** @return the leash or surface to animate for this container */
         @NonNull
         public SurfaceControl getLeash() {
@@ -1003,6 +1021,7 @@
             mStartAbsBounds.writeToParcel(dest, flags);
             mEndAbsBounds.writeToParcel(dest, flags);
             mEndRelOffset.writeToParcel(dest, flags);
+            mEndParentSize.writeToParcel(dest, flags);
             dest.writeTypedObject(mTaskInfo, flags);
             dest.writeBoolean(mAllowEnterPip);
             dest.writeInt(mStartDisplayId);
@@ -1055,6 +1074,9 @@
             if (mEndRelOffset.x != 0 || mEndRelOffset.y != 0) {
                 sb.append(" eo="); sb.append(mEndRelOffset);
             }
+            if (!mEndParentSize.equals(0, 0)) {
+                sb.append(" epz=").append(mEndParentSize);
+            }
             sb.append(" d=");
             if (mStartDisplayId != mEndDisplayId) {
                 sb.append(mStartDisplayId).append("->");
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index f4f6c8a..cd033ca 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -25,6 +25,7 @@
 import static android.window.TaskFragmentOperation.OP_TYPE_SET_COMPANION_TASK_FRAGMENT;
 import static android.window.TaskFragmentOperation.OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT;
 
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
@@ -44,6 +45,8 @@
 import android.view.SurfaceControl;
 import android.view.WindowInsets.Type.InsetsType;
 
+import com.android.window.flags.Flags;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -962,6 +965,23 @@
     }
 
     /**
+     * Sets the task as trimmable or not. This can be used to prevent the task from being trimmed by
+     * recents. This attribute is set to true on task creation by default.
+     *
+     * @param isTrimmableFromRecents When {@code true}, task is set as trimmable from recents.
+     * @hide
+     */
+    @NonNull
+    public WindowContainerTransaction setTaskTrimmableFromRecents(
+            @NonNull WindowContainerToken container,
+            boolean isTrimmableFromRecents) {
+        mHierarchyOps.add(
+                HierarchyOp.createForSetTaskTrimmableFromRecents(container.asBinder(),
+                        isTrimmableFromRecents));
+        return this;
+    }
+
+    /**
      * Merges another WCT into this one.
      * @param transfer When true, this will transfer everything from other potentially leaving
      *                 other in an unusable state. When false, other is left alone, but
@@ -1412,6 +1432,7 @@
         public static final int HIERARCHY_OP_TYPE_SET_REPARENT_LEAF_TASK_IF_RELAUNCH = 16;
         public static final int HIERARCHY_OP_TYPE_ADD_TASK_FRAGMENT_OPERATION = 17;
         public static final int HIERARCHY_OP_TYPE_MOVE_PIP_ACTIVITY_TO_PINNED_TASK = 18;
+        public static final int HIERARCHY_OP_TYPE_SET_IS_TRIMMABLE = 19;
 
         // The following key(s) are for use with mLaunchOptions:
         // When launching a task (eg. from recents), this is the taskId to be launched.
@@ -1473,6 +1494,8 @@
 
         private boolean mReparentLeafTaskIfRelaunch;
 
+        private boolean mIsTrimmableFromRecents;
+
         public static HierarchyOp createForReparent(
                 @NonNull IBinder container, @Nullable IBinder reparent, boolean toTop) {
             return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_REPARENT)
@@ -1575,6 +1598,16 @@
                     .build();
         }
 
+        /** Create a hierarchy op for setting a task non-trimmable by recents. */
+        @FlaggedApi(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+        public static HierarchyOp createForSetTaskTrimmableFromRecents(@NonNull IBinder container,
+                boolean isTrimmableFromRecents) {
+            return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_SET_IS_TRIMMABLE)
+                    .setContainer(container)
+                    .setIsTrimmableFromRecents(isTrimmableFromRecents)
+                    .build();
+        }
+
         /** Only creates through {@link Builder}. */
         private HierarchyOp(int type) {
             mType = type;
@@ -1599,6 +1632,7 @@
             mShortcutInfo = copy.mShortcutInfo;
             mAlwaysOnTop = copy.mAlwaysOnTop;
             mReparentLeafTaskIfRelaunch = copy.mReparentLeafTaskIfRelaunch;
+            mIsTrimmableFromRecents = copy.mIsTrimmableFromRecents;
         }
 
         protected HierarchyOp(Parcel in) {
@@ -1620,6 +1654,7 @@
             mShortcutInfo = in.readTypedObject(ShortcutInfo.CREATOR);
             mAlwaysOnTop = in.readBoolean();
             mReparentLeafTaskIfRelaunch = in.readBoolean();
+            mIsTrimmableFromRecents = in.readBoolean();
         }
 
         public int getType() {
@@ -1715,6 +1750,12 @@
             return mIncludingParents;
         }
 
+        /** Set the task to be trimmable */
+        @NonNull
+        public boolean isTrimmableFromRecents() {
+            return mIsTrimmableFromRecents;
+        }
+
         /** Gets a string representation of a hierarchy-op type. */
         public static String hopToString(int type) {
             switch (type) {
@@ -1811,6 +1852,10 @@
                     sb.append("fragmentToken= ").append(mContainer)
                             .append(" operation= ").append(mTaskFragmentOperation);
                     break;
+                case HIERARCHY_OP_TYPE_SET_IS_TRIMMABLE:
+                    sb.append("container= ").append(mContainer)
+                            .append(" isTrimmable= ")
+                            .append(mIsTrimmableFromRecents);
                 default:
                     sb.append("container=").append(mContainer)
                             .append(" reparent=").append(mReparent)
@@ -1841,6 +1886,7 @@
             dest.writeTypedObject(mShortcutInfo, flags);
             dest.writeBoolean(mAlwaysOnTop);
             dest.writeBoolean(mReparentLeafTaskIfRelaunch);
+            dest.writeBoolean(mIsTrimmableFromRecents);
         }
 
         @Override
@@ -1910,6 +1956,8 @@
 
             private boolean mReparentLeafTaskIfRelaunch;
 
+            private boolean mIsTrimmableFromRecents;
+
             Builder(int type) {
                 mType = type;
             }
@@ -2000,6 +2048,11 @@
                 return this;
             }
 
+            Builder setIsTrimmableFromRecents(boolean isTrimmableFromRecents) {
+                mIsTrimmableFromRecents = isTrimmableFromRecents;
+                return this;
+            }
+
             HierarchyOp build() {
                 final HierarchyOp hierarchyOp = new HierarchyOp(mType);
                 hierarchyOp.mContainer = mContainer;
@@ -2023,6 +2076,7 @@
                 hierarchyOp.mBounds = mBounds;
                 hierarchyOp.mIncludingParents = mIncludingParents;
                 hierarchyOp.mReparentLeafTaskIfRelaunch = mReparentLeafTaskIfRelaunch;
+                hierarchyOp.mIsTrimmableFromRecents = mIsTrimmableFromRecents;
 
                 return hierarchyOp;
             }
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index 4ca64e7..9b87e23 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -37,6 +37,7 @@
 import android.view.IWindowSession;
 import android.view.ImeBackAnimationController;
 import android.view.MotionEvent;
+import android.view.ViewRootImpl;
 
 import androidx.annotation.VisibleForTesting;
 
@@ -49,6 +50,7 @@
 import java.util.HashMap;
 import java.util.Objects;
 import java.util.TreeMap;
+import java.util.function.BooleanSupplier;
 import java.util.function.Supplier;
 
 /**
@@ -68,6 +70,7 @@
 public class WindowOnBackInvokedDispatcher implements OnBackInvokedDispatcher {
     private IWindowSession mWindowSession;
     private IWindow mWindow;
+    private ViewRootImpl mViewRoot;
     @VisibleForTesting
     public final BackTouchTracker mTouchTracker = new BackTouchTracker();
     @VisibleForTesting
@@ -134,10 +137,12 @@
      * is attached a window.
      */
     public void attachToWindow(@NonNull IWindowSession windowSession, @NonNull IWindow window,
+            @Nullable ViewRootImpl viewRoot,
             @Nullable ImeBackAnimationController imeBackAnimationController) {
         synchronized (mLock) {
             mWindowSession = windowSession;
             mWindow = window;
+            mViewRoot = viewRoot;
             mImeBackAnimationController = imeBackAnimationController;
             if (!mAllCallbacks.isEmpty()) {
                 setTopOnBackInvokedCallback(getTopCallback());
@@ -151,6 +156,7 @@
             clear();
             mWindow = null;
             mWindowSession = null;
+            mViewRoot = null;
             mImeBackAnimationController = null;
         }
     }
@@ -176,8 +182,6 @@
                 return;
             }
             if (callback instanceof ImeOnBackInvokedDispatcher.ImeOnBackInvokedCallback) {
-                // Fall back to compat back key injection if legacy back behaviour should be used.
-                if (!isOnBackInvokedCallbackEnabled()) return;
                 if (callback instanceof ImeOnBackInvokedDispatcher.DefaultImeOnBackAnimationCallback
                         && mImeBackAnimationController != null) {
                     // register ImeBackAnimationController instead to play predictive back animation
@@ -300,6 +304,14 @@
         }
     }
 
+    private boolean callOnKeyPreIme() {
+        if (mViewRoot != null && !isOnBackInvokedCallbackEnabled(mViewRoot.mContext)) {
+            return mViewRoot.injectBackKeyEvents(/*preImeOnly*/ true);
+        } else {
+            return false;
+        }
+    }
+
     private void setTopOnBackInvokedCallback(@Nullable OnBackInvokedCallback callback) {
         if (mWindowSession == null || mWindow == null) {
             return;
@@ -308,8 +320,8 @@
             OnBackInvokedCallbackInfo callbackInfo = null;
             if (callback != null) {
                 int priority = mAllCallbacks.get(callback);
-                final IOnBackInvokedCallback iCallback = new OnBackInvokedCallbackWrapper(
-                        callback, mTouchTracker, mProgressAnimator, mHandler);
+                final IOnBackInvokedCallback iCallback = new OnBackInvokedCallbackWrapper(callback,
+                        mTouchTracker, mProgressAnimator, mHandler, this::callOnKeyPreIme);
                 callbackInfo = new OnBackInvokedCallbackInfo(
                         iCallback,
                         priority,
@@ -399,16 +411,20 @@
         private final BackTouchTracker mTouchTracker;
         @NonNull
         private final Handler mHandler;
+        @NonNull
+        private final BooleanSupplier mOnKeyPreIme;
 
         OnBackInvokedCallbackWrapper(
                 @NonNull OnBackInvokedCallback callback,
                 @NonNull BackTouchTracker touchTracker,
                 @NonNull BackProgressAnimator progressAnimator,
-                @NonNull Handler handler) {
+                @NonNull Handler handler,
+                @NonNull BooleanSupplier onKeyPreIme) {
             mCallback = new WeakReference<>(callback);
             mTouchTracker = touchTracker;
             mProgressAnimator = progressAnimator;
             mHandler = handler;
+            mOnKeyPreIme = onKeyPreIme;
         }
 
         @Override
@@ -460,6 +476,7 @@
         public void onBackInvoked() throws RemoteException {
             mHandler.post(() -> {
                 mTouchTracker.reset();
+                if (consumedByOnKeyPreIme()) return;
                 boolean isInProgress = mProgressAnimator.isBackAnimationInProgress();
                 final OnBackInvokedCallback callback = mCallback.get();
                 if (callback == null) {
@@ -472,7 +489,8 @@
                     return;
                 }
                 OnBackAnimationCallback animationCallback = getBackAnimationCallback();
-                if (animationCallback != null) {
+                if (animationCallback != null
+                        && !(callback instanceof ImeBackAnimationController)) {
                     mProgressAnimator.onBackInvoked(callback::onBackInvoked);
                 } else {
                     mProgressAnimator.reset();
@@ -481,6 +499,30 @@
             });
         }
 
+        private boolean consumedByOnKeyPreIme() {
+            final OnBackInvokedCallback callback = mCallback.get();
+            if (callback instanceof ImeBackAnimationController
+                    || callback instanceof ImeOnBackInvokedDispatcher.ImeOnBackInvokedCallback) {
+                // call onKeyPreIme API if the current callback is an IME callback and the app has
+                // not set enableOnBackInvokedCallback="false"
+                try {
+                    boolean consumed = mOnKeyPreIme.getAsBoolean();
+                    if (consumed) {
+                        // back event intercepted by app in onKeyPreIme -> cancel the IME animation.
+                        final OnBackAnimationCallback animationCallback =
+                                getBackAnimationCallback();
+                        if (animationCallback != null) {
+                            mProgressAnimator.onBackCancelled(animationCallback::onBackCancelled);
+                        }
+                        return true;
+                    }
+                } catch (Exception e) {
+                    Log.d(TAG, "Failed to call onKeyPreIme", e);
+                }
+            }
+            return false;
+        }
+
         @Override
         public void setTriggerBack(boolean triggerBack) throws RemoteException {
             mTouchTracker.setTriggerBack(triggerBack);
diff --git a/core/java/android/window/WindowTokenClient.java b/core/java/android/window/WindowTokenClient.java
index cc54a93..15adc80 100644
--- a/core/java/android/window/WindowTokenClient.java
+++ b/core/java/android/window/WindowTokenClient.java
@@ -19,8 +19,6 @@
 import static android.window.ConfigurationHelper.isDifferentDisplay;
 import static android.window.ConfigurationHelper.shouldUpdateResources;
 
-import static com.android.window.flags.Flags.windowTokenConfigThreadSafe;
-
 import android.annotation.AnyThread;
 import android.annotation.MainThread;
 import android.annotation.NonNull;
@@ -146,7 +144,7 @@
         if (context == null) {
             return;
         }
-        if (shouldReportConfigChange && windowTokenConfigThreadSafe()) {
+        if (shouldReportConfigChange) {
             // Only report to ClientTransactionListenerController when shouldReportConfigChange.
             final ClientTransactionListenerController controller =
                     getClientTransactionListenerController();
diff --git a/core/java/android/window/flags/large_screen_experiences_app_compat.aconfig b/core/java/android/window/flags/large_screen_experiences_app_compat.aconfig
index 5b99ff9..cc880e1 100644
--- a/core/java/android/window/flags/large_screen_experiences_app_compat.aconfig
+++ b/core/java/android/window/flags/large_screen_experiences_app_compat.aconfig
@@ -113,4 +113,12 @@
     namespace: "large_screen_experiences_app_compat"
     description: "Enables sysui animation for user aspect ratio button"
     bug: "300357441"
+}
+
+flag {
+  name: "app_compat_ui_framework"
+  namespace: "large_screen_experiences_app_compat"
+  description: "Whether the declarative compat UI framework is enabled"
+  bug: "270361630"
+  is_fixed_read_only: true
 }
\ No newline at end of file
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index ca125da..61fdcdd 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -120,3 +120,45 @@
     description: "Whether to enable min/max window size constraints when resizing a window in desktop windowing mode"
     bug: "327589741"
 }
+
+flag {
+    name: "enable_caption_compat_inset_force_consumption"
+    namespace: "lse_desktop_experience"
+    description: "Enables force-consumption of caption bar insets for immersive apps in freeform"
+    bug: "316231589"
+}
+
+flag {
+    name: "show_desktop_windowing_dev_option"
+    namespace: "lse_desktop_experience"
+    description: "Whether to show developer option for enabling desktop windowing mode"
+    bug: "348193756"
+}
+
+flag {
+    name: "enable_desktop_windowing_app_to_web"
+    namespace: "lse_desktop_experience"
+    description: "Whether to enable the app-to-web feature and show the open in browser button in the header menu"
+    bug: "349695493"
+}
+
+flag {
+    name: "enable_windowing_transition_handlers_observers"
+    namespace: "lse_desktop_experience"
+    description: "Whether to enable desktop windowing transition handler and observer instead of task listeners."
+    bug: "332682201"
+}
+
+flag {
+    name: "enable_caption_compat_inset_conversion"
+    namespace: "lse_desktop_experience"
+    description: "Enables compatibility mitigation for apps that don't support caption insets well"
+    bug: "316231589"
+}
+
+flag {
+    name: "enable_desktop_windowing_multi_instance_features"
+    namespace: "lse_desktop_experience"
+    description: "Whether to enable multi-instance support in desktop windowing."
+    bug: "336289597"
+}
diff --git a/core/java/android/window/flags/responsible_apis.aconfig b/core/java/android/window/flags/responsible_apis.aconfig
index 69cac6f..94f6503 100644
--- a/core/java/android/window/flags/responsible_apis.aconfig
+++ b/core/java/android/window/flags/responsible_apis.aconfig
@@ -56,3 +56,11 @@
     description: "Improved metrics."
     bug: "339245692"
 }
+
+flag {
+    name: "bal_send_intent_with_options"
+    namespace: "responsible_apis"
+    description: "Add options parameter to IntentSender.sendIntent."
+    bug: "339720406"
+}
+
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index b714682..92db37e 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -19,6 +19,16 @@
 }
 
 flag {
+    name: "apply_lifecycle_on_pip_change"
+    namespace: "windowing_frontend"
+    description: "Make pip activity lifecyle change with windowing mode"
+    bug: "333452456"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
     name: "blast_sync_notification_shade_on_display_switch"
     namespace: "windowing_frontend"
     description: "Make the buffer content of notification shade synchronize with display switch"
@@ -53,17 +63,6 @@
 }
 
 flag {
-  name: "remove_prepare_surface_in_placement"
-  namespace: "windowing_frontend"
-  description: "Reduce unnecessary invocation to improve performance"
-  bug: "330721336"
-  is_fixed_read_only: true
-  metadata {
-    purpose: PURPOSE_BUGFIX
-  }
-}
-
-flag {
   name: "close_to_square_config_includes_status_bar"
   namespace: "windowing_frontend"
   description: "On close to square display, when necessary, configuration includes status bar"
@@ -71,17 +70,6 @@
 }
 
 flag {
-  name: "skip_sleeping_when_switching_display"
-  namespace: "windowing_frontend"
-  description: "Reduce unnecessary visibility or lifecycle changes when changing fold state"
-  bug: "303241079"
-  is_fixed_read_only: true
-  metadata {
-    purpose: PURPOSE_BUGFIX
-  }
-}
-
-flag {
   name: "introduce_smoother_dimmer"
   namespace: "windowing_frontend"
   description: "Refactor dim to fix flickers"
@@ -146,6 +134,20 @@
 }
 
 flag {
+  name: "process_priority_policy_for_multi_window_mode"
+  namespace: "windowing_frontend"
+  description: "Use higher priority for top-like processes"
+  bug: "200769420"
+}
+
+flag {
+  name: "respect_non_top_visible_fixed_orientation"
+  namespace: "windowing_frontend"
+  description: "If top activity is not opaque, respect the fixed orientation of activity behind it"
+  bug: "283514860"
+}
+
+flag {
   name: "insets_decoupled_configuration"
   namespace: "windowing_frontend"
   description: "Configuration decoupled from insets"
@@ -192,4 +194,15 @@
   metadata {
     purpose: PURPOSE_BUGFIX
   }
-}
\ No newline at end of file
+}
+
+flag {
+  name: "ensure_wallpaper_in_transitions"
+  namespace: "windowing_frontend"
+  description: "Ensure that wallpaper window tokens are always present/available for collection in transitions"
+  bug: "347593088"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
+
diff --git a/core/java/android/window/flags/windowing_sdk.aconfig b/core/java/android/window/flags/windowing_sdk.aconfig
index 0a4762d..ae9d757 100644
--- a/core/java/android/window/flags/windowing_sdk.aconfig
+++ b/core/java/android/window/flags/windowing_sdk.aconfig
@@ -93,37 +93,6 @@
 
 flag {
     namespace: "windowing_sdk"
-    name: "window_token_config_thread_safe"
-    description: "Ensure the Configuration pre/post changed is thread safe"
-    bug: "334285008"
-    metadata {
-        purpose: PURPOSE_BUGFIX
-    }
-}
-
-flag {
-    namespace: "windowing_sdk"
-    name: "always_defer_transition_when_apply_wct"
-    description: "Report error when defer transition fails when it should not"
-    bug: "335562144"
-    metadata {
-        purpose: PURPOSE_BUGFIX
-    }
-}
-
-flag {
-    namespace: "windowing_sdk"
-    name: "window_session_relayout_info"
-    description: "Pass an out RelayoutInfo instead of Bundle to fix the Parcel recycle bug"
-    bug: "335601427"
-    is_fixed_read_only: true
-    metadata {
-        purpose: PURPOSE_BUGFIX
-    }
-}
-
-flag {
-    namespace: "windowing_sdk"
     name: "fix_pip_restore_to_overlay"
     description: "Restore exit-pip activity back to ActivityEmbedding overlay"
     bug: "297887697"
@@ -191,3 +160,25 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    namespace: "windowing_sdk"
+    name: "fix_no_container_update_without_resize"
+    description: "Fix the containers not being updated when the Task is brought to front and has the same configuration"
+    bug: "344721335"
+    is_fixed_read_only: true
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
+    namespace: "windowing_sdk"
+    name: "per_user_display_window_settings"
+    description: "Whether to store display window settings per user to avoid conflicts"
+    bug: "346668297"
+    is_fixed_read_only: true
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/core/java/com/android/internal/accessibility/common/ShortcutConstants.java b/core/java/com/android/internal/accessibility/common/ShortcutConstants.java
index 6420620..a3fcfad 100644
--- a/core/java/com/android/internal/accessibility/common/ShortcutConstants.java
+++ b/core/java/com/android/internal/accessibility/common/ShortcutConstants.java
@@ -72,6 +72,7 @@
             UserShortcutType.TRIPLETAP,
             UserShortcutType.TWOFINGER_DOUBLETAP,
             UserShortcutType.QUICK_SETTINGS,
+            UserShortcutType.GESTURE
     })
     public @interface UserShortcutType {
         int DEFAULT = 0;
@@ -81,6 +82,7 @@
         int TRIPLETAP = 1 << 2;
         int TWOFINGER_DOUBLETAP = 1 << 3;
         int QUICK_SETTINGS = 1 << 4;
+        int GESTURE = 1 << 5;
         // LINT.ThenChange(:shortcut_type_array)
     }
 
@@ -95,6 +97,7 @@
             UserShortcutType.TRIPLETAP,
             UserShortcutType.TWOFINGER_DOUBLETAP,
             UserShortcutType.QUICK_SETTINGS,
+            UserShortcutType.GESTURE
             // LINT.ThenChange(:shortcut_type_intdef)
     };
 
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityButtonChooserActivity.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityButtonChooserActivity.java
index fc3cd45..01cbb55 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityButtonChooserActivity.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityButtonChooserActivity.java
@@ -20,6 +20,7 @@
 
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
 import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getTargets;
 import static com.android.internal.accessibility.util.AccessibilityStatsLogUtils.logAccessibilityButtonLongPressStatus;
@@ -29,8 +30,6 @@
 import android.content.ComponentName;
 import android.os.Bundle;
 import android.provider.Settings;
-import android.text.TextUtils;
-import android.view.View;
 import android.view.accessibility.AccessibilityManager;
 import android.widget.GridView;
 import android.widget.TextView;
@@ -68,24 +67,22 @@
                 NAV_BAR_MODE_GESTURAL == getResources().getInteger(
                         com.android.internal.R.integer.config_navBarInteractionMode);
 
+        final int targetType = (isGestureNavigateEnabled
+                && android.provider.Flags.a11yStandaloneGestureEnabled()) ? GESTURE : SOFTWARE;
+
         if (isGestureNavigateEnabled) {
             final TextView promptPrologue = findViewById(R.id.accessibility_button_prompt_prologue);
             promptPrologue.setText(isTouchExploreOn
                     ? R.string.accessibility_gesture_3finger_prompt_text
                     : R.string.accessibility_gesture_prompt_text);
-        }
 
-        if (TextUtils.isEmpty(component)) {
             final TextView prompt = findViewById(R.id.accessibility_button_prompt);
-            if (isGestureNavigateEnabled) {
-                prompt.setText(isTouchExploreOn
-                        ? R.string.accessibility_gesture_3finger_instructional_text
-                        : R.string.accessibility_gesture_instructional_text);
-            }
-            prompt.setVisibility(View.VISIBLE);
+            prompt.setText(isTouchExploreOn
+                    ? R.string.accessibility_gesture_3finger_instructional_text
+                    : R.string.accessibility_gesture_instructional_text);
         }
 
-        mTargets.addAll(getTargets(this, SOFTWARE));
+        mTargets.addAll(getTargets(this, targetType));
 
         final GridView gridview = findViewById(R.id.accessibility_button_chooser_grid);
         gridview.setAdapter(new ButtonTargetAdapter(mTargets));
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityShortcutChooserActivity.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityShortcutChooserActivity.java
index 6256dbc..44c7543 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityShortcutChooserActivity.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityShortcutChooserActivity.java
@@ -18,7 +18,6 @@
 import static com.android.internal.accessibility.common.ShortcutConstants.ShortcutMenuMode;
 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
-import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
 import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getInstalledTargets;
 import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getTargets;
 import static com.android.internal.accessibility.util.AccessibilityUtils.isUserSetupCompleted;
@@ -213,10 +212,7 @@
         final boolean isEditMenuMode =
                 mTargetAdapter.getShortcutMenuMode() == ShortcutMenuMode.EDIT;
         final int selectDialogTitleId = R.string.accessibility_select_shortcut_menu_title;
-        final int editDialogTitleId =
-                mShortcutType == SOFTWARE
-                        ? R.string.accessibility_edit_shortcut_menu_button_title
-                        : R.string.accessibility_edit_shortcut_menu_volume_title;
+        final int editDialogTitleId = R.string.accessibility_edit_shortcut_menu_volume_title;
 
         mMenuDialog.setTitle(getString(isEditMenuMode ? editDialogTitleId : selectDialogTitleId));
         mMenuDialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java
index 66faa31..a753110 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.accessibility.dialog;
 
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
 import static com.android.internal.accessibility.util.ShortcutUtils.optInValueToSettings;
@@ -36,6 +37,7 @@
 import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType;
 import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 import com.android.internal.accessibility.dialog.TargetAdapter.ViewHolder;
+import com.android.internal.accessibility.util.ShortcutUtils;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.Set;
@@ -67,6 +69,10 @@
     public AccessibilityTarget(Context context, @UserShortcutType int shortcutType,
             @AccessibilityFragmentType int fragmentType, boolean isShortcutSwitched, String id,
             int uid, CharSequence label, Drawable icon, String key) {
+        if (!isRecognizedShortcutType(shortcutType)) {
+            throw new IllegalArgumentException(
+                    "Unexpected shortcut type " + ShortcutUtils.convertToKey(shortcutType));
+        }
         mContext = context;
         mShortcutType = shortcutType;
         mFragmentType = fragmentType;
@@ -97,20 +103,15 @@
         holder.mStatusView.setVisibility(View.GONE);
     }
 
+    @SuppressLint("MissingPermission")
     @Override
     public void onSelected() {
         final AccessibilityManager am =
                 getContext().getSystemService(AccessibilityManager.class);
-        switch (getShortcutType()) {
-            case SOFTWARE:
-                am.notifyAccessibilityButtonClicked(getContext().getDisplayId(), getId());
-                return;
-            case HARDWARE:
-                am.performAccessibilityShortcut(getId());
-                return;
-            default:
-                throw new IllegalStateException("Unexpected shortcut type");
+        if (am == null) {
+            return;
         }
+        am.performAccessibilityShortcut(getContext().getDisplayId(), mShortcutType, getId());
     }
 
     @SuppressLint("MissingPermission")
@@ -188,4 +189,18 @@
     public String getKey() {
         return mKey;
     }
+
+    /**
+     * Determines if the provided shortcut type is valid for use with AccessibilityTargets.
+     * @param shortcutType shortcut type to check.
+     * @return {@code true} if the shortcut type can be used, {@code false} otherwise.
+     */
+    @VisibleForTesting
+    public static boolean isRecognizedShortcutType(@UserShortcutType int shortcutType) {
+        int mask = SOFTWARE | HARDWARE;
+        if (android.provider.Flags.a11yStandaloneGestureEnabled()) {
+            mask = mask | GESTURE;
+        }
+        return (shortcutType != 0 && (shortcutType & mask) == shortcutType);
+    }
 }
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java
index e523ab0..4ccdf79 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java
@@ -41,6 +41,7 @@
 import com.android.internal.R;
 import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType;
 import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
+import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -159,21 +160,32 @@
 
         final List<AccessibilityTarget> targets = new ArrayList<>(installedServices.size());
         for (AccessibilityServiceInfo info : installedServices) {
-            final int targetSdk =
-                    info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion;
-            final boolean hasRequestAccessibilityButtonFlag =
-                    (info.flags & AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0;
-            if ((targetSdk <= Build.VERSION_CODES.Q) && !hasRequestAccessibilityButtonFlag
-                    && (shortcutType == SOFTWARE)) {
-                continue;
+            if (isValidServiceTarget(info, shortcutType)) {
+                targets.add(createAccessibilityServiceTarget(context, shortcutType, info));
             }
-
-            targets.add(createAccessibilityServiceTarget(context, shortcutType, info));
         }
 
         return targets;
     }
 
+    /**
+     * Check for maintaining compatibility on prior versions.
+     * Determines if a given service should be accumulated in a list of installed services.
+     * @param info service info to check.
+     * @param shortcutType type of shortcut to accumulate a list for.
+     * @return {@code true} if the service should be added (always true past version Q),
+     * otherwise {@code false}.
+     */
+    @VisibleForTesting
+    public static boolean isValidServiceTarget(
+            AccessibilityServiceInfo info, @UserShortcutType int shortcutType) {
+        final boolean hasRequestAccessibilityButtonFlag =
+                (info.flags & AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0;
+        return (info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion
+                > Build.VERSION_CODES.Q) || hasRequestAccessibilityButtonFlag
+                || shortcutType != SOFTWARE;
+    }
+
     private static List<AccessibilityTarget> getAccessibilityActivityTargets(Context context,
             @UserShortcutType int shortcutType) {
         final AccessibilityManager am = (AccessibilityManager) context.getSystemService(
diff --git a/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java b/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
index 8e18f84..9d66461 100644
--- a/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
+++ b/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
@@ -23,6 +23,7 @@
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
 
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.QUICK_SETTINGS;
 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
@@ -247,6 +248,8 @@
                 } else {
                     return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_BUTTON;
                 }
+            case GESTURE:
+                return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_GESTURE;
             case HARDWARE:
                 return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__VOLUME_KEY;
             case QUICK_SETTINGS:
diff --git a/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java b/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java
index e8472d4..0b1ecf7 100644
--- a/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java
+++ b/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java
@@ -126,7 +126,7 @@
     }
 
     /**
-     * Changes an accessibility component's state.
+     * Changes an accessibility component's state for the calling process userId
      */
     public static void setAccessibilityServiceState(Context context, ComponentName componentName,
             boolean enabled) {
diff --git a/core/java/com/android/internal/accessibility/util/ShortcutUtils.java b/core/java/com/android/internal/accessibility/util/ShortcutUtils.java
index 5b09a8b..48f86ff 100644
--- a/core/java/com/android/internal/accessibility/util/ShortcutUtils.java
+++ b/core/java/com/android/internal/accessibility/util/ShortcutUtils.java
@@ -166,6 +166,8 @@
         switch (type) {
             case UserShortcutType.SOFTWARE:
                 return Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
+            case UserShortcutType.GESTURE:
+                return Settings.Secure.ACCESSIBILITY_GESTURE_TARGETS;
             case UserShortcutType.HARDWARE:
                 return Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
             case UserShortcutType.TRIPLETAP:
@@ -181,6 +183,28 @@
     }
 
     /**
+     * Converts {@link Settings.Secure} key to {@link UserShortcutType}.
+     *
+     * @param key The shortcut key in Settings.
+     * @return The mapped type
+     */
+    @UserShortcutType
+    public static int convertToType(String key) {
+        return switch (key) {
+            case Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS -> UserShortcutType.SOFTWARE;
+            case Settings.Secure.ACCESSIBILITY_GESTURE_TARGETS -> UserShortcutType.GESTURE;
+            case Settings.Secure.ACCESSIBILITY_QS_TARGETS -> UserShortcutType.QUICK_SETTINGS;
+            case Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE -> UserShortcutType.HARDWARE;
+            case Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED ->
+                    UserShortcutType.TRIPLETAP;
+            case Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED ->
+                    UserShortcutType.TWOFINGER_DOUBLETAP;
+            default -> throw new IllegalArgumentException(
+                    "Unsupported user shortcut key: " + key);
+        };
+    }
+
+    /**
      * Updates an accessibility state if the accessibility service is a Always-On a11y service,
      * a.k.a. AccessibilityServices that has FLAG_REQUEST_ACCESSIBILITY_BUTTON
      * <p>
@@ -224,7 +248,9 @@
                 boolean enableA11yService = servicesWithShortcuts.contains(componentName);
                 AccessibilityUtils.setAccessibilityServiceState(
                         context,
-                        ComponentName.unflattenFromString(componentName), enableA11yService);
+                        ComponentName.unflattenFromString(componentName),
+                        enableA11yService,
+                        userId);
             }
         }
     }
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 920981e..a194535 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -1209,9 +1209,19 @@
         if (!isChangingConfigurations() && mPickOptionRequest != null) {
             mPickOptionRequest.cancel();
         }
-        if (mMultiProfilePagerAdapter != null
-                && mMultiProfilePagerAdapter.getActiveListAdapter() != null) {
-            mMultiProfilePagerAdapter.getActiveListAdapter().onDestroy();
+        if (mMultiProfilePagerAdapter != null) {
+            ResolverListAdapter activeAdapter =
+                    mMultiProfilePagerAdapter.getActiveListAdapter();
+            if (activeAdapter != null) {
+                activeAdapter.onDestroy();
+            }
+            if (android.service.chooser.Flags.fixResolverMemoryLeak()) {
+                ResolverListAdapter inactiveAdapter =
+                        mMultiProfilePagerAdapter.getInactiveListAdapter();
+                if (inactiveAdapter != null) {
+                    inactiveAdapter.onDestroy();
+                }
+            }
         }
     }
 
diff --git a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
index e55cdef..b5930e1 100644
--- a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
+++ b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
@@ -72,6 +72,7 @@
     boolean bindRemoteViewsService(String callingPackage, int appWidgetId, in Intent intent,
             IApplicationThread caller, IBinder token, IServiceConnection connection, long flags);
     void notifyProviderInheritance(in ComponentName[] componentNames);
+    int getMaxBitmapMemory();
 
     @UnsupportedAppUsage
     int[] getAppWidgetIds(in ComponentName providerComponent);
diff --git a/core/java/com/android/internal/compat/ChangeReporter.java b/core/java/com/android/internal/compat/ChangeReporter.java
index ded142c..f611571 100644
--- a/core/java/com/android/internal/compat/ChangeReporter.java
+++ b/core/java/com/android/internal/compat/ChangeReporter.java
@@ -42,7 +42,7 @@
  *
  * @hide
  */
-public final class ChangeReporter {
+public class ChangeReporter {
     private static final String TAG = "CompatChangeReporter";
     private static final Function<Integer, Set<ChangeReport>> NEW_CHANGE_REPORT_SET =
             uid -> Collections.synchronizedSet(new HashSet<>());
@@ -88,17 +88,20 @@
      * Report the change to stats log and to the debug log if the change was not previously
      * logged already.
      *
-     * @param uid             affected by the change
-     * @param changeId        the reported change id
-     * @param state           of the reported change - enabled/disabled/only logged
-     * @param isLoggableBySdk whether debug logging is allowed for this change based on target
-     *                        SDK version. This is combined with other logic to determine whether to
-     *                        actually log. If the sdk version does not matter, should be true.
+     * @param uid              affected by the change
+     * @param changeId         the reported change id
+     * @param state            of the reported change - enabled/disabled/only logged
+     * @param isKnownSystemApp do we know that the affected app is a system app? (if true is
+     *                         definitely a system app, if false it may or may not be a system app)
+     * @param isLoggableBySdk  whether debug logging is allowed for this change based on target
+     *                         SDK version. This is combined with other logic to determine whether
+     *                         to actually log. If the sdk version does not matter, should be true.
      */
-    public void reportChange(int uid, long changeId, int state, boolean isLoggableBySdk) {
+    public void reportChange(int uid, long changeId, int state, boolean isKnownSystemApp,
+            boolean isLoggableBySdk) {
         boolean isAlreadyReported =
                 checkAndSetIsAlreadyReported(uid, new ChangeReport(changeId, state));
-        if (!isAlreadyReported) {
+        if (shouldWriteToStatsLog(isKnownSystemApp, isAlreadyReported)) {
             FrameworkStatsLog.write(FrameworkStatsLog.APP_COMPATIBILITY_CHANGE_REPORTED, uid,
                     changeId, state, mSource);
         }
@@ -116,7 +119,7 @@
      * @param state    of the reported change - enabled/disabled/only logged
      */
     public void reportChange(int uid, long changeId, int state) {
-        reportChange(uid, changeId, state, true);
+        reportChange(uid, changeId, state, false, true);
     }
 
     /**
@@ -136,14 +139,15 @@
     /**
      * Returns whether the next report should be logged to FrameworkStatsLog.
      *
-     * @param uid      affected by the change
-     * @param changeId the reported change id
-     * @param state    of the reported change - enabled/disabled/only logged
+     * @param isKnownSystemApp do we know that the affected app is a system app? (if true is
+     *                         definitely a system app, if false it may or may not be a system app)
+     * @param isAlreadyReported is the change already reported
      * @return true if the report should be logged
      */
     @VisibleForTesting
-    boolean shouldWriteToStatsLog(int uid, long changeId, int state) {
-        return !isAlreadyReported(uid, new ChangeReport(changeId, state));
+    boolean shouldWriteToStatsLog(boolean isKnownSystemApp, boolean isAlreadyReported) {
+        // We don't log where we know the source is a system app or is already reported
+        return !isKnownSystemApp && !isAlreadyReported;
     }
 
     /**
@@ -224,6 +228,19 @@
         return mReportedChanges.getOrDefault(uid, EMPTY_SET).contains(report);
     }
 
+    /**
+     * Returns whether the next report should be logged.
+     *
+     * @param uid      affected by the change
+     * @param changeId the reported change id
+     * @param state    of the reported change - enabled/disabled/only logged
+     * @return true if the report should be logged
+     */
+    @VisibleForTesting
+    boolean isAlreadyReported(int uid, long changeId, int state) {
+        return isAlreadyReported(uid, new ChangeReport(changeId, state));
+    }
+
     private void markAsReported(int uid, ChangeReport report) {
         mReportedChanges.computeIfAbsent(uid, NEW_CHANGE_REPORT_SET).add(report);
     }
diff --git a/core/java/com/android/internal/display/BrightnessSynchronizer.java b/core/java/com/android/internal/display/BrightnessSynchronizer.java
index 0068490..9f5ed65 100644
--- a/core/java/com/android/internal/display/BrightnessSynchronizer.java
+++ b/core/java/com/android/internal/display/BrightnessSynchronizer.java
@@ -78,9 +78,9 @@
     // Feature flag that will eventually be removed
     private final boolean mIntRangeUserPerceptionEnabled;
 
-    public BrightnessSynchronizer(Context context, boolean intRangeUserPerceptionEnabled) {
-        this(context, Looper.getMainLooper(), SystemClock::uptimeMillis,
-                intRangeUserPerceptionEnabled);
+    public BrightnessSynchronizer(Context context, Looper looper,
+            boolean intRangeUserPerceptionEnabled) {
+        this(context, looper, SystemClock::uptimeMillis, intRangeUserPerceptionEnabled);
     }
 
     @VisibleForTesting
diff --git a/core/java/com/android/internal/jank/Cuj.java b/core/java/com/android/internal/jank/Cuj.java
index 6ffa826..2b096ea 100644
--- a/core/java/com/android/internal/jank/Cuj.java
+++ b/core/java/com/android/internal/jank/Cuj.java
@@ -137,9 +137,60 @@
     public static final int CUJ_LAUNCHER_PRIVATE_SPACE_LOCK = 102;
     public static final int CUJ_LAUNCHER_PRIVATE_SPACE_UNLOCK = 103;
 
+    /**
+     * Track maximize window interaction in desktop mode.
+     *
+     * <p>Tracking starts onClick of the maximize window button or option {@link
+     * com.android.wm.shell.windowdecor.DesktopModeWindowDecorViewModel#onClick}
+     * and finishes when the window animation is ended {@link
+     * com.android.wm.shell.windowdecor.ToggleResizeDesktopTaskTransitionHandler#startAnimation}
+     */
+    public static final int CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW = 104;
+
+    /**
+     * Track fade-in animation when in SystemUI process fold
+     *
+     * <p>Tracking starts after the screen turns on and finish when the animation is over {@link
+     * com.android.systemui.unfold.FoldLightRevealOverlayAnimation#playFoldLightRevealOverlayAnimation} for the span
+     */
+    public static final int CUJ_FOLD_ANIM = 105;
+
+    /**
+     * Track window re-sizing interaction in desktop mode.
+     */
+    public static final int CUJ_DESKTOP_MODE_RESIZE_WINDOW = 106;
+
+    /**
+     * Track entering desktop mode interaction via app handle drag.
+     *
+     * <p>Tracking starts when the app handle is dragged and
+     * finishes when the window animation to desktop ends after app handle release.
+     */
+    public static final int CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_DRAG = 107;
+
+    /** Track exiting desktop mode interaction. */
+    public static final int CUJ_DESKTOP_MODE_EXIT_MODE = 108;
+
+    /** Track minimize window interaction in desktop mode. */
+    public static final int CUJ_DESKTOP_MODE_MINIMIZE_WINDOW = 109;
+
+    /** Track window drag interaction in desktop mode. */
+    public static final int CUJ_DESKTOP_MODE_DRAG_WINDOW = 110;
+
+    /** Track launching a dialog from a status bar chip. */
+    public static final int CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP = 111;
+
+    /**
+     * Track entering desktop mode interaction via app handle menu.
+     *
+     * <p>Tracking starts after windowing mode option in the app handle menu is clicked and
+     * finishes when the window animation to desktop ends.
+     */
+    public static final int CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU = 112;
+
+
     // When adding a CUJ, update this and make sure to also update CUJ_TO_STATSD_INTERACTION_TYPE.
-    @VisibleForTesting
-    static final int LAST_CUJ = CUJ_LAUNCHER_PRIVATE_SPACE_UNLOCK;
+    @VisibleForTesting static final int LAST_CUJ = CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU;
 
     /** @hide */
     @IntDef({
@@ -234,11 +285,19 @@
             CUJ_LAUNCHER_WIDGET_PICKER_SEARCH_BACK,
             CUJ_LAUNCHER_WIDGET_BOTTOM_SHEET_CLOSE_BACK,
             CUJ_LAUNCHER_PRIVATE_SPACE_LOCK,
-            CUJ_LAUNCHER_PRIVATE_SPACE_UNLOCK
+            CUJ_LAUNCHER_PRIVATE_SPACE_UNLOCK,
+            CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW,
+            CUJ_FOLD_ANIM,
+            CUJ_DESKTOP_MODE_RESIZE_WINDOW,
+            CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_DRAG,
+            CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU,
+            CUJ_DESKTOP_MODE_EXIT_MODE,
+            CUJ_DESKTOP_MODE_MINIMIZE_WINDOW,
+            CUJ_DESKTOP_MODE_DRAG_WINDOW,
+            CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP
     })
     @Retention(RetentionPolicy.SOURCE)
-    public @interface CujType {
-    }
+    public @interface CujType {}
 
     private static final int NO_STATSD_LOGGING = -1;
 
@@ -341,6 +400,15 @@
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_WIDGET_EDU_SHEET_CLOSE_BACK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_WIDGET_EDU_SHEET_CLOSE_BACK;
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_PRIVATE_SPACE_LOCK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_PRIVATE_SPACE_LOCK;
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_PRIVATE_SPACE_UNLOCK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_PRIVATE_SPACE_UNLOCK;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_MAXIMIZE_WINDOW;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_FOLD_ANIM] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__FOLD_ANIM;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_RESIZE_WINDOW] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_RESIZE_WINDOW;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_DRAG] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_ENTER_MODE_APP_HANDLE_DRAG;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_EXIT_MODE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_EXIT_MODE;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_MINIMIZE_WINDOW] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_MINIMIZE_WINDOW;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_DRAG_WINDOW] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_DRAG_WINDOW;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP;
     }
 
     private Cuj() {
@@ -543,6 +611,24 @@
                 return "LAUNCHER_PRIVATE_SPACE_LOCK";
             case CUJ_LAUNCHER_PRIVATE_SPACE_UNLOCK:
                 return "LAUNCHER_PRIVATE_SPACE_UNLOCK";
+            case CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW:
+                return "DESKTOP_MODE_MAXIMIZE_WINDOW";
+            case CUJ_FOLD_ANIM:
+                return "FOLD_ANIM";
+            case CUJ_DESKTOP_MODE_RESIZE_WINDOW:
+                return "DESKTOP_MODE_RESIZE_WINDOW";
+            case CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_DRAG:
+                return "DESKTOP_MODE_ENTER_MODE_APP_HANDLE_DRAG";
+            case CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU:
+                return "DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU";
+            case CUJ_DESKTOP_MODE_EXIT_MODE:
+                return "DESKTOP_MODE_EXIT_MODE";
+            case CUJ_DESKTOP_MODE_MINIMIZE_WINDOW:
+                return "DESKTOP_MODE_MINIMIZE_WINDOW";
+            case CUJ_DESKTOP_MODE_DRAG_WINDOW:
+                return "DESKTOP_MODE_DRAG_WINDOW";
+            case CUJ_STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP:
+                return "STATUS_BAR_LAUNCH_DIALOG_FROM_CHIP";
         }
         return "UNKNOWN";
     }
diff --git a/core/java/com/android/internal/jank/FrameTracker.java b/core/java/com/android/internal/jank/FrameTracker.java
index 86729f7..bf5df03 100644
--- a/core/java/com/android/internal/jank/FrameTracker.java
+++ b/core/java/com/android/internal/jank/FrameTracker.java
@@ -63,8 +63,8 @@
  * A class that allows the app to get the frame metrics from HardwareRendererObserver.
  * @hide
  */
-public class FrameTracker extends SurfaceControl.OnJankDataListener
-        implements HardwareRendererObserver.OnFrameMetricsAvailableListener {
+public class FrameTracker implements HardwareRendererObserver.OnFrameMetricsAvailableListener,
+         SurfaceControl.OnJankDataListener {
     private static final String TAG = "FrameTracker";
 
     private static final long INVALID_ID = -1;
@@ -118,6 +118,7 @@
     public final boolean mSurfaceOnly;
 
     private SurfaceControl mSurfaceControl;
+    private SurfaceControl.OnJankDataListenerRegistration mJankDataListenerRegistration;
     private long mBeginVsyncId = INVALID_ID;
     private long mEndVsyncId = INVALID_ID;
     private boolean mMetricsFinalized;
@@ -316,7 +317,8 @@
         Trace.asyncTraceForTrackBegin(Trace.TRACE_TAG_APP, name, name, (int) mBeginVsyncId);
         markEvent("FT#beginVsync", mBeginVsyncId);
         markEvent("FT#layerId", mSurfaceControl.getLayerId());
-        mSurfaceControlWrapper.addJankStatsListener(this, mSurfaceControl);
+        mJankDataListenerRegistration =
+                mSurfaceControlWrapper.addJankStatsListener(this, mSurfaceControl);
         if (!mSurfaceOnly) {
             mRendererWrapper.addObserver(mObserver);
         }
@@ -342,6 +344,10 @@
             markEvent("FT#endVsync", mEndVsyncId);
             Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_APP, name, (int) mBeginVsyncId);
 
+            if (mJankDataListenerRegistration != null) {
+                mJankDataListenerRegistration.removeAfter(mEndVsyncId);
+            }
+
             // 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.
@@ -358,6 +364,9 @@
                     // Send a flush jank data transaction.
                     if (mSurfaceControl != null && mSurfaceControl.isValid()) {
                         SurfaceControl.Transaction.sendSurfaceFlushJankData(mSurfaceControl);
+                        if (mJankDataListenerRegistration != null) {
+                            mJankDataListenerRegistration.flush();
+                        }
                     }
 
                     long delay;
@@ -680,7 +689,10 @@
     @VisibleForTesting
     @UiThread
     public void removeObservers() {
-        mSurfaceControlWrapper.removeJankStatsListener(this);
+        if (mJankDataListenerRegistration != null) {
+            mJankDataListenerRegistration.release();
+            mJankDataListenerRegistration = null;
+        }
         if (!mSurfaceOnly) {
             // HWUI part.
             mRendererWrapper.removeObserver(mObserver);
@@ -796,14 +808,10 @@
     }
 
     public static class SurfaceControlWrapper {
-
-        public void addJankStatsListener(SurfaceControl.OnJankDataListener listener,
-                SurfaceControl surfaceControl) {
-            SurfaceControl.addJankDataListener(listener, surfaceControl);
-        }
-
-        public void removeJankStatsListener(SurfaceControl.OnJankDataListener listener) {
-            SurfaceControl.removeJankDataListener(listener);
+        /** adds the jank listener to the given surface */
+        public SurfaceControl.OnJankDataListenerRegistration addJankStatsListener(
+                SurfaceControl.OnJankDataListener listener, SurfaceControl surfaceControl) {
+            return surfaceControl.addJankDataListener(listener);
         }
     }
 
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index b86cbfb..33610a0 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -325,6 +325,48 @@
     /**
      * Begins a trace session.
      *
+     * @param surface a handle for the surface to begin tracing for.
+     * @param context context to provide display and handler information.
+     * @param cujType the specific {@link Cuj.CujType}.
+     * @return boolean true if the tracker is started successfully, false otherwise.
+     */
+    public boolean begin(SurfaceControl surface, Context context, @Cuj.CujType int cujType) {
+        try {
+            return begin(Configuration.Builder.withSurface(cujType, context, surface));
+        } catch (IllegalArgumentException ex) {
+            Log.d(TAG, "Build configuration failed!", ex);
+            return false;
+        }
+    }
+
+    /**
+     * Begins a trace session.
+     *
+     * @param surface a handle for the surface to begin tracing for.
+     * @param context context to provide display and handler information.
+     * @param cujType the specific {@link Cuj.CujType}.
+     * @param tag a tag containing extra information about the interaction.
+     * @return boolean true if the tracker is started successfully, false otherwise.
+     */
+    public boolean begin(SurfaceControl surface, Context context, @Cuj.CujType int cujType,
+            String tag) {
+        try {
+            final Configuration.Builder builder =
+                    Configuration.Builder.withSurface(cujType, context, surface);
+            if (!TextUtils.isEmpty(tag)) {
+                builder.setTag(tag);
+            }
+            return begin(builder);
+        } catch (IllegalArgumentException ex) {
+            Log.d(TAG, "Build configuration failed!", ex);
+            return false;
+        }
+    }
+
+
+    /**
+     * Begins a trace session.
+     *
      * @param builder the builder of the configurations for instrumenting the CUJ.
      * @return boolean true if the tracker is begun successfully, false otherwise.
      */
diff --git a/core/java/com/android/internal/jank/OWNERS b/core/java/com/android/internal/jank/OWNERS
index 2f3bbee..5463883 100644
--- a/core/java/com/android/internal/jank/OWNERS
+++ b/core/java/com/android/internal/jank/OWNERS
@@ -4,4 +4,5 @@
 ahanwu@google.com
 vadimt@google.com
 marcinoc@google.com
-pmuetschard@google.com
\ No newline at end of file
+pmuetschard@google.com
+nicomazz@google.com
diff --git a/core/java/com/android/internal/os/BinderTransactionNameResolver.java b/core/java/com/android/internal/os/BinderTransactionNameResolver.java
index 5f6f427..f1dc1f2 100644
--- a/core/java/com/android/internal/os/BinderTransactionNameResolver.java
+++ b/core/java/com/android/internal/os/BinderTransactionNameResolver.java
@@ -17,6 +17,7 @@
 package com.android.internal.os;
 
 import android.os.Binder;
+import android.text.TextUtils;
 
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -37,6 +38,8 @@
 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
 public class BinderTransactionNameResolver {
     private static final Method NO_GET_DEFAULT_TRANSACTION_NAME_METHOD;
+    private static final boolean USE_TRANSACTION_CODES_FOR_UNKNOWN_METHODS =
+            Flags.useTransactionCodesForUnknownMethods();
 
     /**
      * Generates the default transaction method name, which is just the transaction code.
@@ -81,7 +84,14 @@
         }
 
         try {
-            return (String) method.invoke(null, transactionCode);
+            String methodName = (String) method.invoke(null, transactionCode);
+            if (USE_TRANSACTION_CODES_FOR_UNKNOWN_METHODS) {
+                return TextUtils.isEmpty(methodName)
+                        ? String.valueOf(transactionCode)
+                        : methodName;
+            } else {
+                return methodName;
+            }
         } catch (IllegalAccessException | InvocationTargetException e) {
             throw new RuntimeException(e);
         }
diff --git a/core/java/com/android/internal/os/flags.aconfig b/core/java/com/android/internal/os/flags.aconfig
index c8d6810..30fa4f1 100644
--- a/core/java/com/android/internal/os/flags.aconfig
+++ b/core/java/com/android/internal/os/flags.aconfig
@@ -9,3 +9,14 @@
     is_fixed_read_only: true
     bug: "241474956"
 }
+
+flag {
+    name: "use_transaction_codes_for_unknown_methods"
+    namespace: "dropbox"
+    description: "Use transaction codes when the method names is unknown"
+    bug: "350041302"
+    is_fixed_read_only: true
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
\ No newline at end of file
diff --git a/core/java/com/android/internal/policy/TransitionAnimation.java b/core/java/com/android/internal/policy/TransitionAnimation.java
index 66b2a9c..238e6f5 100644
--- a/core/java/com/android/internal/policy/TransitionAnimation.java
+++ b/core/java/com/android/internal/policy/TransitionAnimation.java
@@ -75,10 +75,11 @@
 /** @hide */
 public class TransitionAnimation {
     public static final int WALLPAPER_TRANSITION_NONE = 0;
-    public static final int WALLPAPER_TRANSITION_OPEN = 1;
-    public static final int WALLPAPER_TRANSITION_CLOSE = 2;
-    public static final int WALLPAPER_TRANSITION_INTRA_OPEN = 3;
-    public static final int WALLPAPER_TRANSITION_INTRA_CLOSE = 4;
+    public static final int WALLPAPER_TRANSITION_CHANGE = 1;
+    public static final int WALLPAPER_TRANSITION_OPEN = 2;
+    public static final int WALLPAPER_TRANSITION_CLOSE = 3;
+    public static final int WALLPAPER_TRANSITION_INTRA_OPEN = 4;
+    public static final int WALLPAPER_TRANSITION_INTRA_CLOSE = 5;
 
     // These are the possible states for the enter/exit activities during a thumbnail transition
     private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_UP = 0;
diff --git a/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java b/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
index d244874..572a599 100644
--- a/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
@@ -48,6 +48,7 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Map;
 import java.util.TreeMap;
 import java.util.stream.Collectors;
 
@@ -65,7 +66,7 @@
     private final String mLegacyViewerConfigFilename;
     private final TraceBuffer mBuffer;
     private final LegacyProtoLogViewerConfigReader mViewerConfig;
-    private final TreeMap<String, IProtoLogGroup> mLogGroups;
+    private final Map<String, IProtoLogGroup> mLogGroups = new TreeMap<>();
     private final Runnable mCacheUpdater;
     private final int mPerChunkSize;
 
@@ -74,20 +75,19 @@
     private final Object mProtoLogEnabledLock = new Object();
 
     public LegacyProtoLogImpl(String outputFile, String viewerConfigFilename,
-            TreeMap<String, IProtoLogGroup> logGroups, Runnable cacheUpdater) {
+            Runnable cacheUpdater) {
         this(new File(outputFile), viewerConfigFilename, BUFFER_CAPACITY,
-                new LegacyProtoLogViewerConfigReader(), PER_CHUNK_SIZE, logGroups, cacheUpdater);
+                new LegacyProtoLogViewerConfigReader(), PER_CHUNK_SIZE, cacheUpdater);
     }
 
     public LegacyProtoLogImpl(File file, String viewerConfigFilename, int bufferCapacity,
             LegacyProtoLogViewerConfigReader viewerConfig, int perChunkSize,
-            TreeMap<String, IProtoLogGroup> logGroups, Runnable cacheUpdater) {
+            Runnable cacheUpdater) {
         mLogFile = file;
         mBuffer = new TraceBuffer(bufferCapacity);
         mLegacyViewerConfigFilename = viewerConfigFilename;
         mViewerConfig = viewerConfig;
         mPerChunkSize = perChunkSize;
-        mLogGroups = logGroups;
         mCacheUpdater = cacheUpdater;
     }
 
@@ -97,21 +97,26 @@
     @VisibleForTesting
     @Override
     public void log(LogLevel level, IProtoLogGroup group, long messageHash, int paramsMask,
-            @Nullable String messageString, Object[] args) {
+            @Nullable Object[] args) {
         if (group.isLogToProto()) {
             logToProto(messageHash, paramsMask, args);
         }
         if (group.isLogToLogcat()) {
-            logToLogcat(group.getTag(), level, messageHash, messageString, args);
+            logToLogcat(group.getTag(), level, messageHash, args);
         }
     }
 
+    @Override
+    public void log(LogLevel logLevel, IProtoLogGroup group, String messageString, Object... args) {
+        // This will be removed very soon so no point implementing it here.
+        throw new IllegalStateException(
+                "Not implemented. Only implemented for PerfettoProtoLogImpl.");
+    }
+
     private void logToLogcat(String tag, LogLevel level, long messageHash,
-            @Nullable String messageString, Object[] args) {
+            @Nullable Object[] args) {
         String message = null;
-        if (messageString == null) {
-            messageString = mViewerConfig.getViewerString(messageHash);
-        }
+        final String messageString = mViewerConfig.getViewerString(messageHash);
         if (messageString != null) {
             if (args != null) {
                 try {
@@ -125,8 +130,10 @@
         }
         if (message == null) {
             StringBuilder builder = new StringBuilder("UNKNOWN MESSAGE (" + messageHash + ")");
-            for (Object o : args) {
-                builder.append(" ").append(o);
+            if (args != null) {
+                for (Object o : args) {
+                    builder.append(" ").append(o);
+                }
             }
             message = builder.toString();
         }
@@ -410,5 +417,12 @@
         // so we ignore the level argument to this function.
         return group.isLogToLogcat() || (group.isLogToProto() && isProtoEnabled());
     }
+
+    @Override
+    public void registerGroups(IProtoLogGroup... protoLogGroups) {
+        for (IProtoLogGroup group : protoLogGroups) {
+            mLogGroups.put(group.name(), group);
+        }
+    }
 }
 
diff --git a/core/java/com/android/internal/protolog/LogcatOnlyProtoLogImpl.java b/core/java/com/android/internal/protolog/LogcatOnlyProtoLogImpl.java
new file mode 100644
index 0000000..ebdad6d
--- /dev/null
+++ b/core/java/com/android/internal/protolog/LogcatOnlyProtoLogImpl.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.protolog;
+
+import static com.android.internal.protolog.ProtoLog.REQUIRE_PROTOLOGTOOL;
+
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.protolog.common.ILogger;
+import com.android.internal.protolog.common.IProtoLog;
+import com.android.internal.protolog.common.IProtoLogGroup;
+import com.android.internal.protolog.common.LogLevel;
+
+/**
+ * Class only create and used to server temporarily for when there is source code pre-processing by
+ * the ProtoLog tool, when the tracing to Perfetto flag is off, and the static REQUIRE_PROTOLOGTOOL
+ * boolean is false. In which case we simply want to log protolog message to logcat. Note, that this
+ * means that in such cases there is no real advantage of using protolog over logcat.
+ *
+ * @deprecated Should not be used. This is just a temporary class to support a legacy behavior.
+ */
+@Deprecated
+public class LogcatOnlyProtoLogImpl implements IProtoLog {
+    @Override
+    public void log(LogLevel logLevel, IProtoLogGroup group, long messageHash, int paramsMask,
+            Object[] args) {
+        throw new RuntimeException("Not supported when using LogcatOnlyProtoLogImpl");
+    }
+
+    @Override
+    public void log(LogLevel logLevel, IProtoLogGroup group, String messageString, Object[] args) {
+        if (REQUIRE_PROTOLOGTOOL) {
+            throw new RuntimeException(
+                    "REQUIRE_PROTOLOGTOOL not set to false before the first log call.");
+        }
+
+        String formattedString = TextUtils.formatSimple(messageString, args);
+        switch (logLevel) {
+            case VERBOSE -> Log.v(group.getTag(), formattedString);
+            case INFO -> Log.i(group.getTag(), formattedString);
+            case DEBUG -> Log.d(group.getTag(), formattedString);
+            case WARN -> Log.w(group.getTag(), formattedString);
+            case ERROR -> Log.e(group.getTag(), formattedString);
+            case WTF -> Log.wtf(group.getTag(), formattedString);
+        }
+    }
+
+    @Override
+    public boolean isProtoEnabled() {
+        return false;
+    }
+
+    @Override
+    public int startLoggingToLogcat(String[] groups, ILogger logger) {
+        return 0;
+    }
+
+    @Override
+    public int stopLoggingToLogcat(String[] groups, ILogger logger) {
+        return 0;
+    }
+
+    @Override
+    public boolean isEnabled(IProtoLogGroup group, LogLevel level) {
+        return true;
+    }
+
+    @Override
+    public void registerGroups(IProtoLogGroup... protoLogGroups) {
+        // Does nothing
+    }
+}
diff --git a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
index 42fa6ac..6abba8b 100644
--- a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
@@ -42,11 +42,11 @@
 import static android.internal.perfetto.protos.TracePacketOuterClass.TracePacket.SEQ_NEEDS_INCREMENTAL_STATE;
 import static android.internal.perfetto.protos.TracePacketOuterClass.TracePacket.TIMESTAMP;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.internal.perfetto.protos.Protolog.ProtoLogViewerConfig.MessageData;
 import android.os.ShellCommand;
 import android.os.SystemClock;
-import android.os.Trace;
 import android.text.TextUtils;
 import android.tracing.perfetto.DataSourceParams;
 import android.tracing.perfetto.InitArguments;
@@ -72,37 +72,45 @@
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
+import java.util.UUID;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 
 /**
  * A service for the ProtoLog logging system.
  */
 public class PerfettoProtoLogImpl implements IProtoLog {
     private static final String LOG_TAG = "ProtoLog";
+    public static final String NULL_STRING = "null";
     private final AtomicInteger mTracingInstances = new AtomicInteger();
 
     private final ProtoLogDataSource mDataSource = new ProtoLogDataSource(
             this::onTracingInstanceStart,
-            this::dumpTransitionTraceConfig,
+            this::onTracingFlush,
             this::onTracingInstanceStop
     );
     private final ProtoLogViewerConfigReader mViewerConfigReader;
     private final ViewerConfigInputStreamProvider mViewerConfigInputStreamProvider;
-    private final TreeMap<String, IProtoLogGroup> mLogGroups;
+    private final TreeMap<String, IProtoLogGroup> mLogGroups = new TreeMap<>();
     private final Runnable mCacheUpdater;
 
-    private final Map<LogLevel, Integer> mDefaultLogLevelCounts = new ArrayMap<>();
-    private final Map<IProtoLogGroup, Map<LogLevel, Integer>> mLogLevelCounts = new ArrayMap<>();
+    private final int[] mDefaultLogLevelCounts = new int[LogLevel.values().length];
+    private final Map<IProtoLogGroup, int[]> mLogLevelCounts = new ArrayMap<>();
+    private final Map<IProtoLogGroup, Integer> mCollectStackTraceGroupCounts = new ArrayMap<>();
 
-    private final ExecutorService mBackgroundLoggingService = Executors.newSingleThreadExecutor();
+    private final Lock mBackgroundServiceLock = new ReentrantLock();
+    private ExecutorService mBackgroundLoggingService = Executors.newSingleThreadExecutor();
 
-    public PerfettoProtoLogImpl(String viewerConfigFilePath,
-            TreeMap<String, IProtoLogGroup> logGroups, Runnable cacheUpdater) {
+    public PerfettoProtoLogImpl(String viewerConfigFilePath, Runnable cacheUpdater) {
         this(() -> {
             try {
                 return new ProtoInputStream(new FileInputStream(viewerConfigFilePath));
@@ -110,16 +118,19 @@
                 Slog.w(LOG_TAG, "Failed to load viewer config file " + viewerConfigFilePath, e);
                 return null;
             }
-        }, logGroups, cacheUpdater);
+        }, cacheUpdater);
+    }
+
+    public PerfettoProtoLogImpl() {
+        this(null, null, () -> {});
     }
 
     public PerfettoProtoLogImpl(
             ViewerConfigInputStreamProvider viewerConfigInputStreamProvider,
-            TreeMap<String, IProtoLogGroup> logGroups,
             Runnable cacheUpdater
     ) {
         this(viewerConfigInputStreamProvider,
-                new ProtoLogViewerConfigReader(viewerConfigInputStreamProvider), logGroups,
+                new ProtoLogViewerConfigReader(viewerConfigInputStreamProvider),
                 cacheUpdater);
     }
 
@@ -127,7 +138,6 @@
     public PerfettoProtoLogImpl(
             ViewerConfigInputStreamProvider viewerConfigInputStreamProvider,
             ProtoLogViewerConfigReader viewerConfigReader,
-            TreeMap<String, IProtoLogGroup> logGroups,
             Runnable cacheUpdater
     ) {
         Producer.init(InitArguments.DEFAULTS);
@@ -140,7 +150,6 @@
         mDataSource.register(params);
         this.mViewerConfigInputStreamProvider = viewerConfigInputStreamProvider;
         this.mViewerConfigReader = viewerConfigReader;
-        this.mLogGroups = logGroups;
         this.mCacheUpdater = cacheUpdater;
     }
 
@@ -149,23 +158,176 @@
      */
     @VisibleForTesting
     @Override
-    public void log(LogLevel level, IProtoLogGroup group, long messageHash, int paramsMask,
-            @Nullable String messageString, Object[] args) {
-        Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "log");
+    public void log(LogLevel logLevel, IProtoLogGroup group, long messageHash, int paramsMask,
+            @Nullable Object[] args) {
+        log(logLevel, group, new Message(messageHash, paramsMask), args);
+    }
 
-        long tsNanos = SystemClock.elapsedRealtimeNanos();
-        try {
-            mBackgroundLoggingService.submit(() ->
-                    logToProto(level, group.name(), messageHash, paramsMask, args, tsNanos));
-            if (group.isLogToLogcat()) {
-                logToLogcat(group.getTag(), level, messageHash, messageString, args);
-            }
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+    @Override
+    public void log(LogLevel logLevel, IProtoLogGroup group, String messageString, Object... args) {
+        log(logLevel, group, new Message(messageString), args);
+    }
+
+    /**
+     * SLog wrapper.
+     */
+    @VisibleForTesting
+    public void passToLogcat(String tag, LogLevel level, String message) {
+        switch (level) {
+            case DEBUG:
+                Slog.d(tag, message);
+                break;
+            case VERBOSE:
+                Slog.v(tag, message);
+                break;
+            case INFO:
+                Slog.i(tag, message);
+                break;
+            case WARN:
+                Slog.w(tag, message);
+                break;
+            case ERROR:
+                Slog.e(tag, message);
+                break;
+            case WTF:
+                Slog.wtf(tag, message);
+                break;
         }
     }
 
+    /**
+     * Returns {@code true} iff logging to proto is enabled.
+     */
+    public boolean isProtoEnabled() {
+        return mTracingInstances.get() > 0;
+    }
+
+    /**
+     * Start text logging
+     * @param groups Groups to start text logging for
+     * @param logger A logger to write status updates to
+     * @return status code
+     */
+    public int startLoggingToLogcat(String[] groups, ILogger logger) {
+        mViewerConfigReader.loadViewerConfig(logger);
+        return setTextLogging(true, logger, groups);
+    }
+
+    /**
+     * Stop text logging
+     * @param groups Groups to start text logging for
+     * @param logger A logger to write status updates to
+     * @return status code
+     */
+    public int stopLoggingToLogcat(String[] groups, ILogger logger) {
+        mViewerConfigReader.unloadViewerConfig();
+        return setTextLogging(false, logger, groups);
+    }
+
+    @Override
+    public boolean isEnabled(IProtoLogGroup group, LogLevel level) {
+        final int[] groupLevelCount = mLogLevelCounts.get(group);
+        return (groupLevelCount == null && mDefaultLogLevelCounts[level.ordinal()] > 0)
+                || (groupLevelCount != null && groupLevelCount[level.ordinal()] > 0)
+                || group.isLogToLogcat();
+    }
+
+    @Override
+    public void registerGroups(IProtoLogGroup... protoLogGroups) {
+        for (IProtoLogGroup protoLogGroup : protoLogGroups) {
+            mLogGroups.put(protoLogGroup.name(), protoLogGroup);
+        }
+    }
+
+    /**
+     * Responds to a shell command.
+     */
+    public int onShellCommand(ShellCommand shell) {
+        PrintWriter pw = shell.getOutPrintWriter();
+        String cmd = shell.getNextArg();
+        if (cmd == null) {
+            return unknownCommand(pw);
+        }
+        ArrayList<String> args = new ArrayList<>();
+        String arg;
+        while ((arg = shell.getNextArg()) != null) {
+            args.add(arg);
+        }
+        final ILogger logger = (msg) -> logAndPrintln(pw, msg);
+        String[] groups = args.toArray(new String[0]);
+        switch (cmd) {
+            case "start", "stop" -> {
+                pw.println("Command not supported. "
+                        + "Please start and stop ProtoLog tracing with Perfetto.");
+                return -1;
+            }
+            case "enable-text" -> {
+                mViewerConfigReader.loadViewerConfig(logger);
+                return setTextLogging(true, logger, groups);
+            }
+            case "disable-text" -> {
+                return setTextLogging(false, logger, groups);
+            }
+            default -> {
+                return unknownCommand(pw);
+            }
+        }
+    }
+
+    private void log(LogLevel logLevel, IProtoLogGroup group, Message message,
+            @Nullable Object[] args) {
+        if (isProtoEnabled()) {
+            long tsNanos = SystemClock.elapsedRealtimeNanos();
+            final String stacktrace;
+            if (mCollectStackTraceGroupCounts.getOrDefault(group, 0) > 0) {
+                stacktrace = collectStackTrace();
+            } else {
+                stacktrace = null;
+            }
+            try {
+                mBackgroundServiceLock.lock();
+                mBackgroundLoggingService.execute(() ->
+                        logToProto(logLevel, group, message, args, tsNanos,
+                                stacktrace));
+            } finally {
+                mBackgroundServiceLock.unlock();
+            }
+        }
+        if (group.isLogToLogcat()) {
+            logToLogcat(group.getTag(), logLevel, message, args);
+        }
+    }
+
+    private void onTracingFlush() {
+        final ExecutorService loggingService;
+        try {
+            mBackgroundServiceLock.lock();
+            loggingService = mBackgroundLoggingService;
+            mBackgroundLoggingService = Executors.newSingleThreadExecutor();
+        } finally {
+            mBackgroundServiceLock.unlock();
+        }
+
+        try {
+            loggingService.shutdown();
+            boolean finished = loggingService.awaitTermination(10, TimeUnit.SECONDS);
+
+            if (!finished) {
+                Log.e(LOG_TAG, "ProtoLog background tracing service didn't finish gracefully.");
+            }
+        } catch (InterruptedException e) {
+            Log.e(LOG_TAG, "Failed to wait for tracing to finish", e);
+        }
+
+        dumpTransitionTraceConfig();
+    }
+
     private void dumpTransitionTraceConfig() {
+        if (mViewerConfigInputStreamProvider == null) {
+            // No viewer config available
+            return;
+        }
+
         ProtoInputStream pis = mViewerConfigInputStreamProvider.getInputStream();
 
         if (pis == null) {
@@ -256,89 +418,53 @@
         os.end(outMessagesToken);
     }
 
-    private void logToLogcat(String tag, LogLevel level, long messageHash,
-            @Nullable String messageString, Object[] args) {
-        Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "logToLogcat");
-        try {
-            doLogToLogcat(tag, level, messageHash, messageString, args);
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
+    private void logToLogcat(String tag, LogLevel level, Message message,
+            @Nullable Object[] args) {
+        String messageString = message.getMessage(mViewerConfigReader);
+
+        if (messageString == null) {
+            StringBuilder builder = new StringBuilder("UNKNOWN MESSAGE");
+            if (args != null) {
+                builder.append(" args = (");
+                builder.append(String.join(", ", Arrays.stream(args)
+                        .map(it -> {
+                            if (it == null) {
+                                return "null";
+                            } else {
+                                return it.toString();
+                            }
+                        }).toList()));
+                builder.append(")");
+            }
+            messageString = builder.toString();
+            args = new Object[0];
         }
+
+        logToLogcat(tag, level, messageString, args);
     }
 
-    private void doLogToLogcat(String tag, LogLevel level, long messageHash,
-            @androidx.annotation.Nullable String messageString, Object[] args) {
-        String message = null;
-        if (messageString == null) {
-            messageString = mViewerConfigReader.getViewerString(messageHash);
-        }
-        if (messageString != null) {
-            if (args != null) {
-                try {
-                    message = TextUtils.formatSimple(messageString, args);
-                } catch (Exception ex) {
-                    Slog.w(LOG_TAG, "Invalid ProtoLog format string.", ex);
-                }
-            } else {
-                message = messageString;
+    private void logToLogcat(String tag, LogLevel level, String messageString,
+            @Nullable Object[] args) {
+        String message;
+        if (args != null) {
+            try {
+                message = TextUtils.formatSimple(messageString, args);
+            } catch (IllegalArgumentException e) {
+                message = "FORMAT_ERROR \"" + messageString + "\", args=("
+                        + String.join(
+                        ", ", Arrays.stream(args).map(Object::toString).toList()) + ")";
             }
-        }
-        if (message == null) {
-            StringBuilder builder = new StringBuilder("UNKNOWN MESSAGE (" + messageHash + ")");
-            for (Object o : args) {
-                builder.append(" ").append(o);
-            }
-            message = builder.toString();
+        } else {
+            message = messageString;
         }
         passToLogcat(tag, level, message);
     }
 
-    /**
-     * SLog wrapper.
-     */
-    @VisibleForTesting
-    public void passToLogcat(String tag, LogLevel level, String message) {
-        switch (level) {
-            case DEBUG:
-                Slog.d(tag, message);
-                break;
-            case VERBOSE:
-                Slog.v(tag, message);
-                break;
-            case INFO:
-                Slog.i(tag, message);
-                break;
-            case WARN:
-                Slog.w(tag, message);
-                break;
-            case ERROR:
-                Slog.e(tag, message);
-                break;
-            case WTF:
-                Slog.wtf(tag, message);
-                break;
-        }
-    }
-
-    private void logToProto(LogLevel level, String groupName, long messageHash, int paramsMask,
-            Object[] args, long tsNanos) {
-        if (!isProtoEnabled()) {
-            return;
-        }
-
-        Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "logToProto");
-        try {
-            doLogToProto(level, groupName, messageHash, paramsMask, args, tsNanos);
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
-        }
-    }
-
-    private void doLogToProto(LogLevel level, String groupName, long messageHash, int paramsMask,
-            Object[] args, long tsNanos) {
+    private void logToProto(LogLevel level, IProtoLogGroup logGroup, Message message, Object[] args,
+            long tsNanos, @Nullable String stacktrace) {
         mDataSource.trace(ctx -> {
             final ProtoLogDataSource.TlsState tlsState = ctx.getCustomTlsState();
-            final LogLevel logFrom = tlsState.getLogFromLevel(groupName);
+            final LogLevel logFrom = tlsState.getLogFromLevel(logGroup.name());
 
             if (level.ordinal() < logFrom.ordinal()) {
                 return;
@@ -350,29 +476,43 @@
                 // trace processing easier.
                 int argIndex = 0;
                 for (Object o : args) {
-                    int type = LogDataType.bitmaskToLogDataType(paramsMask, argIndex);
+                    int type = LogDataType.bitmaskToLogDataType(message.getMessageMask(), argIndex);
                     if (type == LogDataType.STRING) {
-                        internStringArg(ctx, o.toString());
+                        if (o == null) {
+                            internStringArg(ctx, NULL_STRING);
+                        } else {
+                            internStringArg(ctx, o.toString());
+                        }
                     }
                     argIndex++;
                 }
             }
 
             int internedStacktrace = 0;
-            if (tlsState.getShouldCollectStacktrace(groupName)) {
+            if (tlsState.getShouldCollectStacktrace(logGroup.name())) {
                 // Intern stackstraces before creating the trace packet for the proto message so
                 // that the interned stacktrace strings appear before in the trace to make the
                 // trace processing easier.
-                String stacktrace = collectStackTrace();
                 internedStacktrace = internStacktraceString(ctx, stacktrace);
             }
 
+            boolean needsIncrementalState = false;
+
+            long messageHash = 0;
+            if (message.mMessageHash != null) {
+                messageHash = message.mMessageHash;
+            }
+            if (message.mMessageString != null) {
+                needsIncrementalState = true;
+                messageHash =
+                        internProtoMessage(ctx, level, logGroup, message.mMessageString);
+            }
+
             final ProtoOutputStream os = ctx.newTracePacket();
             os.write(TIMESTAMP, tsNanos);
             long token = os.start(PROTOLOG_MESSAGE);
-            os.write(MESSAGE_ID, messageHash);
 
-            boolean needsIncrementalState = false;
+            os.write(MESSAGE_ID, messageHash);
 
             if (args != null) {
 
@@ -381,22 +521,39 @@
                 ArrayList<Double> doubleParams = new ArrayList<>();
                 ArrayList<Boolean> booleanParams = new ArrayList<>();
                 for (Object o : args) {
-                    int type = LogDataType.bitmaskToLogDataType(paramsMask, argIndex);
+                    int type = LogDataType.bitmaskToLogDataType(message.getMessageMask(), argIndex);
                     try {
                         switch (type) {
                             case LogDataType.STRING:
-                                final int internedStringId = internStringArg(ctx, o.toString());
+                                final int internedStringId;
+                                if (o == null) {
+                                    internedStringId = internStringArg(ctx, NULL_STRING);
+                                } else {
+                                    internedStringId = internStringArg(ctx, o.toString());
+                                }
                                 os.write(STR_PARAM_IIDS, internedStringId);
                                 needsIncrementalState = true;
                                 break;
                             case LogDataType.LONG:
-                                longParams.add(((Number) o).longValue());
+                                if (o == null) {
+                                    longParams.add(0);
+                                } else {
+                                    longParams.add(((Number) o).longValue());
+                                }
                                 break;
                             case LogDataType.DOUBLE:
-                                doubleParams.add(((Number) o).doubleValue());
+                                if (o == null) {
+                                    doubleParams.add(0d);
+                                } else {
+                                    doubleParams.add(((Number) o).doubleValue());
+                                }
                                 break;
                             case LogDataType.BOOLEAN:
-                                booleanParams.add((boolean) o);
+                                if (o == null) {
+                                    booleanParams.add(false);
+                                } else {
+                                    booleanParams.add((boolean) o);
+                                }
                                 break;
                         }
                     } catch (ClassCastException ex) {
@@ -414,7 +571,7 @@
                 booleanParams.forEach(it -> os.write(BOOLEAN_PARAMS, it ? 1 : 0));
             }
 
-            if (tlsState.getShouldCollectStacktrace(groupName)) {
+            if (tlsState.getShouldCollectStacktrace(logGroup.name())) {
                 os.write(STACKTRACE_IID, internedStacktrace);
             }
 
@@ -427,6 +584,63 @@
         });
     }
 
+    private long internProtoMessage(
+            TracingContext<ProtoLogDataSource.Instance, ProtoLogDataSource.TlsState,
+                    ProtoLogDataSource.IncrementalState> ctx, LogLevel level,
+            IProtoLogGroup logGroup, String message) {
+        final ProtoLogDataSource.IncrementalState incrementalState = ctx.getIncrementalState();
+
+        if (!incrementalState.clearReported) {
+            final ProtoOutputStream os = ctx.newTracePacket();
+            os.write(SEQUENCE_FLAGS, SEQ_INCREMENTAL_STATE_CLEARED);
+            incrementalState.clearReported = true;
+        }
+
+
+        if (!incrementalState.protologGroupInterningSet.contains(logGroup.getId())) {
+            incrementalState.protologGroupInterningSet.add(logGroup.getId());
+
+            final ProtoOutputStream os = ctx.newTracePacket();
+            final long protologViewerConfigToken = os.start(PROTOLOG_VIEWER_CONFIG);
+            final long groupConfigToken = os.start(GROUPS);
+
+            os.write(ID, logGroup.getId());
+            os.write(NAME, logGroup.name());
+            os.write(TAG, logGroup.getTag());
+
+            os.end(groupConfigToken);
+            os.end(protologViewerConfigToken);
+        }
+
+        final Long messageHash = hash(level, logGroup.name(), message);
+        if (!incrementalState.protologMessageInterningSet.contains(messageHash)) {
+            incrementalState.protologMessageInterningSet.add(messageHash);
+
+            final ProtoOutputStream os = ctx.newTracePacket();
+            final long protologViewerConfigToken = os.start(PROTOLOG_VIEWER_CONFIG);
+            final long messageConfigToken = os.start(MESSAGES);
+
+            os.write(MessageData.MESSAGE_ID, messageHash);
+            os.write(MESSAGE, message);
+            os.write(LEVEL, level.ordinal());
+            os.write(GROUP_ID, logGroup.getId());
+
+            os.end(messageConfigToken);
+            os.end(protologViewerConfigToken);
+        }
+
+        return messageHash;
+    }
+
+    private Long hash(
+            LogLevel logLevel,
+            String logGroup,
+            String messageString
+    ) {
+        final String fullStringIdentifier =  messageString + logLevel + logGroup;
+        return UUID.nameUUIDFromBytes(fullStringIdentifier.getBytes()).getMostSignificantBits();
+    }
+
     private static final int STACK_SIZE_TO_PROTO_LOG_ENTRY_CALL = 12;
 
     private String collectStackTrace() {
@@ -466,7 +680,7 @@
                     ProtoLogDataSource.IncrementalState> ctx,
             Map<String, Integer> internMap,
             long fieldId,
-            String string
+            @NonNull String string
     ) {
         final ProtoLogDataSource.IncrementalState incrementalState = ctx.getIncrementalState();
 
@@ -492,74 +706,6 @@
         return internMap.get(string);
     }
 
-    /**
-     * Returns {@code true} iff logging to proto is enabled.
-     */
-    public boolean isProtoEnabled() {
-        return mTracingInstances.get() > 0;
-    }
-
-    /**
-     * Start text logging
-     * @param groups Groups to start text logging for
-     * @param logger A logger to write status updates to
-     * @return status code
-     */
-    public int startLoggingToLogcat(String[] groups, ILogger logger) {
-        mViewerConfigReader.loadViewerConfig(logger);
-        return setTextLogging(true, logger, groups);
-    }
-
-    /**
-     * Stop text logging
-     * @param groups Groups to start text logging for
-     * @param logger A logger to write status updates to
-     * @return status code
-     */
-    public int stopLoggingToLogcat(String[] groups, ILogger logger) {
-        mViewerConfigReader.unloadViewerConfig();
-        return setTextLogging(false, logger, groups);
-    }
-
-    @Override
-    public boolean isEnabled(IProtoLogGroup group, LogLevel level) {
-        return group.isLogToLogcat() || getLogFromLevel(group).ordinal() <= level.ordinal();
-    }
-
-    private LogLevel getLogFromLevel(IProtoLogGroup group) {
-        if (mLogLevelCounts.containsKey(group)) {
-            for (LogLevel logLevel : LogLevel.values()) {
-                if (mLogLevelCounts.get(group).getOrDefault(logLevel, 0) > 0) {
-                    return logLevel;
-                }
-            }
-        } else {
-            for (LogLevel logLevel : LogLevel.values()) {
-                if (mDefaultLogLevelCounts.getOrDefault(logLevel, 0) > 0) {
-                    return logLevel;
-                }
-            }
-        }
-
-        return LogLevel.WTF;
-    }
-
-    /**
-     * Start logging the stack trace of the when the log message happened for target groups
-     * @return status code
-     */
-    public int startLoggingStackTrace(String[] groups, ILogger logger) {
-        return -1;
-    }
-
-    /**
-     * Stop logging the stack trace of the when the log message happened for target groups
-     * @return status code
-     */
-    public int stopLoggingStackTrace() {
-        return -1;
-    }
-
     private int setTextLogging(boolean value, ILogger logger, String... groups) {
         for (int i = 0; i < groups.length; i++) {
             String group = groups[i];
@@ -576,41 +722,6 @@
         return 0;
     }
 
-    /**
-     * Responds to a shell command.
-     */
-    public int onShellCommand(ShellCommand shell) {
-        PrintWriter pw = shell.getOutPrintWriter();
-        String cmd = shell.getNextArg();
-        if (cmd == null) {
-            return unknownCommand(pw);
-        }
-        ArrayList<String> args = new ArrayList<>();
-        String arg;
-        while ((arg = shell.getNextArg()) != null) {
-            args.add(arg);
-        }
-        final ILogger logger = (msg) -> logAndPrintln(pw, msg);
-        String[] groups = args.toArray(new String[0]);
-        switch (cmd) {
-            case "start", "stop" -> {
-                pw.println("Command not supported. "
-                        + "Please start and stop ProtoLog tracing with Perfetto.");
-                return -1;
-            }
-            case "enable-text" -> {
-                mViewerConfigReader.loadViewerConfig(logger);
-                return setTextLogging(true, logger, groups);
-            }
-            case "disable-text" -> {
-                return setTextLogging(false, logger, groups);
-            }
-            default -> {
-                return unknownCommand(pw);
-            }
-        }
-    }
-
     private int unknownCommand(PrintWriter pw) {
         pw.println("Unknown command");
         pw.println("Window manager logging options:");
@@ -620,36 +731,51 @@
     }
 
     private synchronized void onTracingInstanceStart(ProtoLogDataSource.ProtoLogConfig config) {
-        this.mTracingInstances.incrementAndGet();
-
         final LogLevel defaultLogFrom = config.getDefaultGroupConfig().logFrom;
-        mDefaultLogLevelCounts.put(defaultLogFrom,
-                mDefaultLogLevelCounts.getOrDefault(defaultLogFrom, 0) + 1);
+        for (int i = defaultLogFrom.ordinal(); i < LogLevel.values().length; i++) {
+            mDefaultLogLevelCounts[i]++;
+        }
 
         final Set<String> overriddenGroupTags = config.getGroupTagsWithOverriddenConfigs();
 
         for (String overriddenGroupTag : overriddenGroupTags) {
             IProtoLogGroup group = mLogGroups.get(overriddenGroupTag);
 
-            mLogLevelCounts.putIfAbsent(group, new ArrayMap<>());
-            final Map<LogLevel, Integer> logLevelsCountsForGroup = mLogLevelCounts.get(group);
+            if (group == null) {
+                throw new IllegalArgumentException("Trying to set config for \""
+                        + overriddenGroupTag + "\" that isn't registered");
+            }
+
+            mLogLevelCounts.putIfAbsent(group, new int[LogLevel.values().length]);
+            final int[] logLevelsCountsForGroup = mLogLevelCounts.get(group);
 
             final LogLevel logFromLevel = config.getConfigFor(overriddenGroupTag).logFrom;
-            logLevelsCountsForGroup.put(logFromLevel,
-                    logLevelsCountsForGroup.getOrDefault(logFromLevel, 0) + 1);
+            for (int i = logFromLevel.ordinal(); i < LogLevel.values().length; i++) {
+                logLevelsCountsForGroup[i]++;
+            }
+
+            if (config.getConfigFor(overriddenGroupTag).collectStackTrace) {
+                mCollectStackTraceGroupCounts.put(group,
+                        mCollectStackTraceGroupCounts.getOrDefault(group, 0) + 1);
+            }
+
+            if (config.getConfigFor(overriddenGroupTag).collectStackTrace) {
+                mCollectStackTraceGroupCounts.put(group,
+                        mCollectStackTraceGroupCounts.getOrDefault(group, 0) + 1);
+            }
         }
 
         mCacheUpdater.run();
+
+        this.mTracingInstances.incrementAndGet();
     }
 
     private synchronized void onTracingInstanceStop(ProtoLogDataSource.ProtoLogConfig config) {
         this.mTracingInstances.decrementAndGet();
 
         final LogLevel defaultLogFrom = config.getDefaultGroupConfig().logFrom;
-        mDefaultLogLevelCounts.put(defaultLogFrom,
-                mDefaultLogLevelCounts.get(defaultLogFrom) - 1);
-        if (mDefaultLogLevelCounts.get(defaultLogFrom) <= 0) {
-            mDefaultLogLevelCounts.remove(defaultLogFrom);
+        for (int i = defaultLogFrom.ordinal(); i < LogLevel.values().length; i++) {
+            mDefaultLogLevelCounts[i]--;
         }
 
         final Set<String> overriddenGroupTags = config.getGroupTagsWithOverriddenConfigs();
@@ -657,29 +783,66 @@
         for (String overriddenGroupTag : overriddenGroupTags) {
             IProtoLogGroup group = mLogGroups.get(overriddenGroupTag);
 
-            mLogLevelCounts.putIfAbsent(group, new ArrayMap<>());
-            final Map<LogLevel, Integer> logLevelsCountsForGroup = mLogLevelCounts.get(group);
+            final int[] logLevelsCountsForGroup = mLogLevelCounts.get(group);
 
             final LogLevel logFromLevel = config.getConfigFor(overriddenGroupTag).logFrom;
-            logLevelsCountsForGroup.put(logFromLevel,
-                    logLevelsCountsForGroup.get(logFromLevel) - 1);
-            if (logLevelsCountsForGroup.get(logFromLevel) <= 0) {
-                logLevelsCountsForGroup.remove(logFromLevel);
+            for (int i = defaultLogFrom.ordinal(); i < LogLevel.values().length; i++) {
+                logLevelsCountsForGroup[i]--;
             }
-            if (logLevelsCountsForGroup.isEmpty()) {
+            if (Arrays.stream(logLevelsCountsForGroup).allMatch(it -> it == 0)) {
                 mLogLevelCounts.remove(group);
             }
+
+            if (config.getConfigFor(overriddenGroupTag).collectStackTrace) {
+                mCollectStackTraceGroupCounts.put(group,
+                        mCollectStackTraceGroupCounts.get(group) - 1);
+
+                if (mCollectStackTraceGroupCounts.get(group) == 0) {
+                    mCollectStackTraceGroupCounts.remove(group);
+                }
+            }
         }
 
         mCacheUpdater.run();
     }
 
-    static void logAndPrintln(@Nullable PrintWriter pw, String msg) {
+    private static void logAndPrintln(@Nullable PrintWriter pw, String msg) {
         Slog.i(LOG_TAG, msg);
         if (pw != null) {
             pw.println(msg);
             pw.flush();
         }
     }
+
+    private static class Message {
+        private final Long mMessageHash;
+        private final Integer mMessageMask;
+        private final String mMessageString;
+
+        private Message(Long messageHash, int messageMask) {
+            this.mMessageHash = messageHash;
+            this.mMessageMask = messageMask;
+            this.mMessageString = null;
+        }
+
+        private Message(String messageString) {
+            this.mMessageHash = null;
+            final List<Integer> argTypes = LogDataType.parseFormatString(messageString);
+            this.mMessageMask = LogDataType.logDataTypesToBitMask(argTypes);
+            this.mMessageString = messageString;
+        }
+
+        private int getMessageMask() {
+            return mMessageMask;
+        }
+
+        private String getMessage(ProtoLogViewerConfigReader viewerConfigReader) {
+            if (mMessageString != null) {
+                return mMessageString;
+            }
+
+            return viewerConfigReader.getViewerString(mMessageHash);
+        }
+    }
 }
 
diff --git a/core/java/com/android/internal/protolog/ProtoLog.java b/core/java/com/android/internal/protolog/ProtoLog.java
new file mode 100644
index 0000000..87678e5
--- /dev/null
+++ b/core/java/com/android/internal/protolog/ProtoLog.java
@@ -0,0 +1,182 @@
+/*
+ * 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.internal.protolog;
+
+import com.android.internal.protolog.common.IProtoLog;
+import com.android.internal.protolog.common.IProtoLogGroup;
+import com.android.internal.protolog.common.LogLevel;
+
+/**
+ * ProtoLog API - exposes static logging methods. Usage of this API is similar
+ * to {@code android.utils.Log} class. Instead of plain text log messages each call consists of
+ * a messageString, which is a format string for the log message (has to be a string literal or
+ * a concatenation of string literals) and a vararg array of parameters for the formatter.
+ *
+ * The syntax for the message string depends on
+ * {@link android.text.TextUtils#formatSimple(String, Object...)}}.
+ * Supported conversions:
+ * %b - boolean
+ * %d %x - integral type (Short, Integer or Long)
+ * %f - floating point type (Float or Double)
+ * %s - string
+ * %% - a literal percent character
+ * The width and precision modifiers are supported, argument_index and flags are not.
+ *
+ * Methods in this class are stubs, that are replaced by optimised versions by the ProtoLogTool
+ * during build.
+ */
+// LINT.IfChange
+public class ProtoLog {
+// LINT.ThenChange(frameworks/base/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt)
+
+    // Needs to be set directly otherwise the protologtool tries to transform the method call
+    @Deprecated
+    public static boolean REQUIRE_PROTOLOGTOOL = true;
+
+    private static IProtoLog sProtoLogInstance;
+
+    /**
+     * DEBUG level log.
+     *
+     * @param group         {@code IProtoLogGroup} controlling this log call.
+     * @param messageString constant format string for the logged message.
+     * @param args          parameters to be used with the format string.
+     *
+     * NOTE: If source code is pre-processed by ProtoLogTool this is not the function call that is
+     *       executed. Check generated code for actual call.
+     */
+    public static void d(IProtoLogGroup group, String messageString, Object... args) {
+        logStringMessage(LogLevel.DEBUG, group, messageString, args);
+    }
+
+    /**
+     * VERBOSE level log.
+     *
+     * @param group         {@code IProtoLogGroup} controlling this log call.
+     * @param messageString constant format string for the logged message.
+     * @param args          parameters to be used with the format string.
+     *
+     * NOTE: If source code is pre-processed by ProtoLogTool this is not the function call that is
+     *       executed. Check generated code for actual call.
+     */
+    public static void v(IProtoLogGroup group, String messageString, Object... args) {
+        logStringMessage(LogLevel.VERBOSE, group, messageString, args);
+    }
+
+    /**
+     * INFO level log.
+     *
+     * @param group         {@code IProtoLogGroup} controlling this log call.
+     * @param messageString constant format string for the logged message.
+     * @param args          parameters to be used with the format string.
+     *
+     * NOTE: If source code is pre-processed by ProtoLogTool this is not the function call that is
+     *       executed. Check generated code for actual call.
+     */
+    public static void i(IProtoLogGroup group, String messageString, Object... args) {
+        logStringMessage(LogLevel.INFO, group, messageString, args);
+    }
+
+    /**
+     * WARNING level log.
+     *
+     * @param group         {@code IProtoLogGroup} controlling this log call.
+     * @param messageString constant format string for the logged message.
+     * @param args          parameters to be used with the format string.
+     *
+     * NOTE: If source code is pre-processed by ProtoLogTool this is not the function call that is
+     *       executed. Check generated code for actual call.
+     */
+    public static void w(IProtoLogGroup group, String messageString, Object... args) {
+        logStringMessage(LogLevel.WARN, group, messageString, args);
+    }
+
+    /**
+     * ERROR level log.
+     *
+     * @param group         {@code IProtoLogGroup} controlling this log call.
+     * @param messageString constant format string for the logged message.
+     * @param args          parameters to be used with the format string.
+     *
+     * NOTE: If source code is pre-processed by ProtoLogTool this is not the function call that is
+     *       executed. Check generated code for actual call.
+     */
+    public static void e(IProtoLogGroup group, String messageString, Object... args) {
+        logStringMessage(LogLevel.ERROR, group, messageString, args);
+    }
+
+    /**
+     * WHAT A TERRIBLE FAILURE level log.
+     *
+     * @param group         {@code IProtoLogGroup} controlling this log call.
+     * @param messageString constant format string for the logged message.
+     * @param args          parameters to be used with the format string.
+     *
+     * NOTE: If source code is pre-processed by ProtoLogTool this is not the function call that is
+     *       executed. Check generated code for actual call.
+     */
+    public static void wtf(IProtoLogGroup group, String messageString, Object... args) {
+        logStringMessage(LogLevel.WTF, group, messageString, args);
+    }
+
+    /**
+     * Check if ProtoLog isEnabled for a target group.
+     * @param group Group to check enable status of.
+     * @return true iff this is being logged.
+     */
+    public static boolean isEnabled(IProtoLogGroup group, LogLevel level) {
+        return sProtoLogInstance.isEnabled(group, level);
+    }
+
+    /**
+     * Get the single ProtoLog instance.
+     * @return A singleton instance of ProtoLog.
+     */
+    public static IProtoLog getSingleInstance() {
+        return sProtoLogInstance;
+    }
+
+    /**
+     * Registers available protolog groups. A group must be registered before it can be used.
+     * @param protoLogGroups The groups to register for use in protolog.
+     */
+    public static void registerGroups(IProtoLogGroup... protoLogGroups) {
+        sProtoLogInstance.registerGroups(protoLogGroups);
+    }
+
+    private static void logStringMessage(LogLevel logLevel, IProtoLogGroup group,
+            String stringMessage, Object... args) {
+        if (sProtoLogInstance == null) {
+            throw new IllegalStateException(
+                    "Trying to use ProtoLog before it is initialized in this process.");
+        }
+
+        if (sProtoLogInstance.isEnabled(group, logLevel)) {
+            sProtoLogInstance.log(logLevel, group, stringMessage, args);
+        }
+    }
+
+    static {
+        if (android.tracing.Flags.perfettoProtologTracing()) {
+            sProtoLogInstance = new PerfettoProtoLogImpl();
+        } else {
+            // The first call to ProtoLog is likely to flip REQUIRE_PROTOLOGTOOL, which is when this
+            // static block will be executed before REQUIRE_PROTOLOGTOOL is actually set.
+            sProtoLogInstance = new LogcatOnlyProtoLogImpl();
+        }
+    }
+}
diff --git a/core/java/com/android/internal/protolog/ProtoLogDataSource.java b/core/java/com/android/internal/protolog/ProtoLogDataSource.java
index 6ab79b9..84f3237 100644
--- a/core/java/com/android/internal/protolog/ProtoLogDataSource.java
+++ b/core/java/com/android/internal/protolog/ProtoLogDataSource.java
@@ -40,6 +40,7 @@
 
 import java.io.IOException;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.function.Consumer;
@@ -138,6 +139,8 @@
     }
 
     public static class IncrementalState {
+        public final Set<Integer> protologGroupInterningSet = new HashSet<>();
+        public final Set<Long> protologMessageInterningSet = new HashSet<>();
         public final Map<String, Integer> argumentInterningMap = new HashMap<>();
         public final Map<String, Integer> stacktraceInterningMap = new HashMap<>();
         public boolean clearReported = false;
diff --git a/core/java/com/android/internal/protolog/ProtoLogImpl.java b/core/java/com/android/internal/protolog/ProtoLogImpl.java
index 6d142af..3082295 100644
--- a/core/java/com/android/internal/protolog/ProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/ProtoLogImpl.java
@@ -54,48 +54,33 @@
     private static Runnable sCacheUpdater;
 
     /** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
-    public static void d(IProtoLogGroup group, long messageHash, int paramsMask,
-            @Nullable String messageString,
-            Object... args) {
-        getSingleInstance()
-                .log(LogLevel.DEBUG, group, messageHash, paramsMask, messageString, args);
+    public static void d(IProtoLogGroup group, long messageHash, int paramsMask, Object... args) {
+        getSingleInstance().log(LogLevel.DEBUG, group, messageHash, paramsMask, args);
     }
 
     /** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
-    public static void v(IProtoLogGroup group, long messageHash, int paramsMask,
-            @Nullable String messageString,
-            Object... args) {
-        getSingleInstance().log(LogLevel.VERBOSE, group, messageHash, paramsMask, messageString,
-                args);
+    public static void v(IProtoLogGroup group, long messageHash, int paramsMask, Object... args) {
+        getSingleInstance().log(LogLevel.VERBOSE, group, messageHash, paramsMask, args);
     }
 
     /** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
-    public static void i(IProtoLogGroup group, long messageHash, int paramsMask,
-            @Nullable String messageString,
-            Object... args) {
-        getSingleInstance().log(LogLevel.INFO, group, messageHash, paramsMask, messageString, args);
+    public static void i(IProtoLogGroup group, long messageHash, int paramsMask, Object... args) {
+        getSingleInstance().log(LogLevel.INFO, group, messageHash, paramsMask, args);
     }
 
     /** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
-    public static void w(IProtoLogGroup group, long messageHash, int paramsMask,
-            @Nullable String messageString,
-            Object... args) {
-        getSingleInstance().log(LogLevel.WARN, group, messageHash, paramsMask, messageString, args);
+    public static void w(IProtoLogGroup group, long messageHash, int paramsMask, Object... args) {
+        getSingleInstance().log(LogLevel.WARN, group, messageHash, paramsMask, args);
     }
 
     /** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
-    public static void e(IProtoLogGroup group, long messageHash, int paramsMask,
-            @Nullable String messageString,
-            Object... args) {
-        getSingleInstance()
-                .log(LogLevel.ERROR, group, messageHash, paramsMask, messageString, args);
+    public static void e(IProtoLogGroup group, long messageHash, int paramsMask, Object... args) {
+        getSingleInstance().log(LogLevel.ERROR, group, messageHash, paramsMask, args);
     }
 
     /** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
-    public static void wtf(IProtoLogGroup group, long messageHash, int paramsMask,
-            @Nullable String messageString,
-            Object... args) {
-        getSingleInstance().log(LogLevel.WTF, group, messageHash, paramsMask, messageString, args);
+    public static void wtf(IProtoLogGroup group, long messageHash, int paramsMask, Object... args) {
+        getSingleInstance().log(LogLevel.WTF, group, messageHash, paramsMask, args);
     }
 
     /**
@@ -107,18 +92,27 @@
     }
 
     /**
+     * Registers available protolog groups. A group must be registered before it can be used.
+     * @param protoLogGroups The groups to register for use in protolog.
+     */
+    public static void registerGroups(IProtoLogGroup... protoLogGroups) {
+        getSingleInstance().registerGroups(protoLogGroups);
+    }
+
+    /**
      * Returns the single instance of the ProtoLogImpl singleton class.
      */
     public static synchronized IProtoLog getSingleInstance() {
         if (sServiceInstance == null) {
             if (android.tracing.Flags.perfettoProtologTracing()) {
-                sServiceInstance = new PerfettoProtoLogImpl(
-                        sViewerConfigPath, sLogGroups, sCacheUpdater);
+                sServiceInstance = new PerfettoProtoLogImpl(sViewerConfigPath, sCacheUpdater);
             } else {
                 sServiceInstance = new LegacyProtoLogImpl(
-                        sLegacyOutputFilePath, sLegacyViewerConfigPath, sLogGroups, sCacheUpdater);
+                        sLegacyOutputFilePath, sLegacyViewerConfigPath, sCacheUpdater);
             }
 
+            IProtoLogGroup[] groups = sLogGroups.values().toArray(new IProtoLogGroup[0]);
+            sServiceInstance.registerGroups(groups);
             sCacheUpdater.run();
         }
         return sServiceInstance;
diff --git a/core/java/com/android/internal/protolog/common/IProtoLog.java b/core/java/com/android/internal/protolog/common/IProtoLog.java
index f72d9f7..f5695ac 100644
--- a/core/java/com/android/internal/protolog/common/IProtoLog.java
+++ b/core/java/com/android/internal/protolog/common/IProtoLog.java
@@ -27,11 +27,19 @@
      * @param group The group this message belongs to.
      * @param messageHash The hash of the message.
      * @param paramsMask The parameters mask of the message.
-     * @param messageString The message string.
      * @param args The arguments of the message.
      */
     void log(LogLevel logLevel, IProtoLogGroup group, long messageHash, int paramsMask,
-             String messageString, Object[] args);
+            Object[] args);
+
+    /**
+     * Log a ProtoLog message
+     * @param logLevel Log level of the proto message.
+     * @param group The group this message belongs to.
+     * @param messageString The message string.
+     * @param args The arguments of the message.
+     */
+    void log(LogLevel logLevel, IProtoLogGroup group, String messageString, Object... args);
 
     /**
      * Check if ProtoLog is tracing.
@@ -60,4 +68,10 @@
      * @return If we need to log this group and level to either ProtoLog or Logcat.
      */
     boolean isEnabled(IProtoLogGroup group, LogLevel level);
+
+    /**
+     * Registers available protolog groups. A group must be registered before it can be used.
+     * @param protoLogGroups The groups to register for use in protolog.
+     */
+    void registerGroups(IProtoLogGroup... protoLogGroups);
 }
diff --git a/core/java/com/android/internal/protolog/common/ProtoLog.java b/core/java/com/android/internal/protolog/common/ProtoLog.java
deleted file mode 100644
index 8149cd5..0000000
--- a/core/java/com/android/internal/protolog/common/ProtoLog.java
+++ /dev/null
@@ -1,157 +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.internal.protolog.common;
-
-/**
- * ProtoLog API - exposes static logging methods. Usage of this API is similar
- * to {@code android.utils.Log} class. Instead of plain text log messages each call consists of
- * a messageString, which is a format string for the log message (has to be a string literal or
- * a concatenation of string literals) and a vararg array of parameters for the formatter.
- *
- * The syntax for the message string depends on
- * {@link android.text.TextUtils#formatSimple(String, Object...)}}.
- * Supported conversions:
- * %b - boolean
- * %d %x - integral type (Short, Integer or Long)
- * %f - floating point type (Float or Double)
- * %s - string
- * %% - a literal percent character
- * The width and precision modifiers are supported, argument_index and flags are not.
- *
- * Methods in this class are stubs, that are replaced by optimised versions by the ProtoLogTool
- * during build.
- */
-public class ProtoLog {
-
-    // Needs to be set directly otherwise the protologtool tries to transform the method call
-    public static boolean REQUIRE_PROTOLOGTOOL = true;
-
-    /**
-     * DEBUG level log.
-     *
-     * @param group         {@code IProtoLogGroup} controlling this log call.
-     * @param messageString constant format string for the logged message.
-     * @param args          parameters to be used with the format string.
-     */
-    public static void d(IProtoLogGroup group, String messageString, Object... args) {
-        // Stub, replaced by the ProtoLogTool.
-        if (REQUIRE_PROTOLOGTOOL) {
-            throw new UnsupportedOperationException(
-                    "ProtoLog calls MUST be processed with ProtoLogTool");
-        }
-    }
-
-    /**
-     * VERBOSE level log.
-     *
-     * @param group         {@code IProtoLogGroup} controlling this log call.
-     * @param messageString constant format string for the logged message.
-     * @param args          parameters to be used with the format string.
-     */
-    public static void v(IProtoLogGroup group, String messageString, Object... args) {
-        // Stub, replaced by the ProtoLogTool.
-        if (REQUIRE_PROTOLOGTOOL) {
-            throw new UnsupportedOperationException(
-                    "ProtoLog calls MUST be processed with ProtoLogTool");
-        }
-    }
-
-    /**
-     * INFO level log.
-     *
-     * @param group         {@code IProtoLogGroup} controlling this log call.
-     * @param messageString constant format string for the logged message.
-     * @param args          parameters to be used with the format string.
-     */
-    public static void i(IProtoLogGroup group, String messageString, Object... args) {
-        // Stub, replaced by the ProtoLogTool.
-        if (REQUIRE_PROTOLOGTOOL) {
-            throw new UnsupportedOperationException(
-                    "ProtoLog calls MUST be processed with ProtoLogTool");
-        }
-    }
-
-    /**
-     * WARNING level log.
-     *
-     * @param group         {@code IProtoLogGroup} controlling this log call.
-     * @param messageString constant format string for the logged message.
-     * @param args          parameters to be used with the format string.
-     */
-    public static void w(IProtoLogGroup group, String messageString, Object... args) {
-        // Stub, replaced by the ProtoLogTool.
-        if (REQUIRE_PROTOLOGTOOL) {
-            throw new UnsupportedOperationException(
-                    "ProtoLog calls MUST be processed with ProtoLogTool");
-        }
-    }
-
-    /**
-     * ERROR level log.
-     *
-     * @param group         {@code IProtoLogGroup} controlling this log call.
-     * @param messageString constant format string for the logged message.
-     * @param args          parameters to be used with the format string.
-     */
-    public static void e(IProtoLogGroup group, String messageString, Object... args) {
-        // Stub, replaced by the ProtoLogTool.
-        if (REQUIRE_PROTOLOGTOOL) {
-            throw new UnsupportedOperationException(
-                    "ProtoLog calls MUST be processed with ProtoLogTool");
-        }
-    }
-
-    /**
-     * WHAT A TERRIBLE FAILURE level log.
-     *
-     * @param group         {@code IProtoLogGroup} controlling this log call.
-     * @param messageString constant format string for the logged message.
-     * @param args          parameters to be used with the format string.
-     */
-    public static void wtf(IProtoLogGroup group, String messageString, Object... args) {
-        // Stub, replaced by the ProtoLogTool.
-        if (REQUIRE_PROTOLOGTOOL) {
-            throw new UnsupportedOperationException(
-                    "ProtoLog calls MUST be processed with ProtoLogTool");
-        }
-    }
-
-    /**
-     * Check if ProtoLog isEnabled for a target group.
-     * @param group Group to check enable status of.
-     * @return true iff this is being logged.
-     */
-    public static boolean isEnabled(IProtoLogGroup group, LogLevel level) {
-        if (REQUIRE_PROTOLOGTOOL) {
-            throw new UnsupportedOperationException(
-                    "ProtoLog calls MUST be processed with ProtoLogTool");
-        }
-        return false;
-    }
-
-    /**
-     * Get the single ProtoLog instance.
-     * @return A singleton instance of ProtoLog.
-     */
-    public static IProtoLog getSingleInstance() {
-        if (REQUIRE_PROTOLOGTOOL) {
-            throw new UnsupportedOperationException(
-                    "ProtoLog calls MUST be processed with ProtoLogTool");
-        }
-        return null;
-    }
-}
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index 13efaf0..754f77e7 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -28,6 +28,7 @@
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FOLD_TO_AOD;
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE;
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE_WITH_SHADE_OPEN;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_KEYGUARD_FACE_UNLOCK_TO_HOME;
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME;
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOAD_SHARE_SHEET;
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_LOCKSCREEN_UNLOCK;
@@ -227,7 +228,8 @@
     public static final int ACTION_NOTIFICATION_BIG_PICTURE_LOADED = 23;
 
     /**
-     * Time it takes to unlock the device via udfps, until the whole launcher appears.
+     * Time it takes to unlock the device via fps,
+     * until either the launcher or the foreground app appears.
      */
     public static final int ACTION_KEYGUARD_FPS_UNLOCK_TO_HOME = 24;
 
@@ -249,6 +251,12 @@
      */
     public static final int ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE_WITH_SHADE_OPEN = 27;
 
+    /**
+     * Time it takes to unlock the device via face,
+     * until either the launcher or the foreground app appears.
+     */
+    public static final int ACTION_KEYGUARD_FACE_UNLOCK_TO_HOME = 28;
+
     private static final int[] ACTIONS_ALL = {
         ACTION_EXPAND_PANEL,
         ACTION_TOGGLE_RECENTS,
@@ -278,6 +286,7 @@
         ACTION_BACK_SYSTEM_ANIMATION,
         ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE,
         ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE_WITH_SHADE_OPEN,
+        ACTION_KEYGUARD_FACE_UNLOCK_TO_HOME,
     };
 
     /** @hide */
@@ -310,6 +319,7 @@
         ACTION_BACK_SYSTEM_ANIMATION,
         ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE,
         ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE_WITH_SHADE_OPEN,
+        ACTION_KEYGUARD_FACE_UNLOCK_TO_HOME,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface Action {
@@ -345,6 +355,7 @@
             UIACTION_LATENCY_REPORTED__ACTION__ACTION_BACK_SYSTEM_ANIMATION,
             UIACTION_LATENCY_REPORTED__ACTION__ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE,
             UIACTION_LATENCY_REPORTED__ACTION__ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE_WITH_SHADE_OPEN,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_KEYGUARD_FACE_UNLOCK_TO_HOME,
     };
 
     private final Object mLock = new Object();
@@ -539,6 +550,8 @@
                 return "ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE";
             case UIACTION_LATENCY_REPORTED__ACTION__ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE_WITH_SHADE_OPEN:
                 return "ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE_WITH_SHADE_OPEN";
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_KEYGUARD_FACE_UNLOCK_TO_HOME:
+                return "ACTION_KEYGUARD_FACE_UNLOCK_TO_HOME";
             default:
                 throw new IllegalArgumentException("Invalid action");
         }
diff --git a/core/java/com/android/internal/view/SurfaceCallbackHelper.java b/core/java/com/android/internal/view/SurfaceCallbackHelper.java
index 507b673..3fd5120 100644
--- a/core/java/com/android/internal/view/SurfaceCallbackHelper.java
+++ b/core/java/com/android/internal/view/SurfaceCallbackHelper.java
@@ -16,11 +16,13 @@
 
 package com.android.internal.view;
 
-import android.os.RemoteException;
-import android.view.Surface;
+import android.util.EventLog;
 import android.view.SurfaceHolder;
 
 public class SurfaceCallbackHelper {
+    private static final int LOGTAG_SURFACEVIEW_CALLBACK = 60006;
+    private final String mTag;
+    private boolean mSurfaceRedrawImplemented;
     Runnable mRunnable;
 
     int mFinishDrawingCollected = 0;
@@ -35,12 +37,23 @@
                         return;
                     }
                     mRunnable.run();
+                    if (mSurfaceRedrawImplemented && mTag != null) {
+                        EventLog.writeEvent(LOGTAG_SURFACEVIEW_CALLBACK, mTag,
+                                "surfaceRedrawNeeded implemented");
+                    }
                 }
             }
     };
 
     public SurfaceCallbackHelper(Runnable callbacksCollected) {
+        // skip logging surfaceRedrawNeeded calls
+        this(callbacksCollected, null);
+    }
+
+    public SurfaceCallbackHelper(Runnable callbacksCollected, String tag) {
         mRunnable = callbacksCollected;
+        mTag = tag;
+        mSurfaceRedrawImplemented = false;
     }
 
     public void dispatchSurfaceRedrawNeededAsync(SurfaceHolder holder, SurfaceHolder.Callback callbacks[]) {
@@ -58,6 +71,7 @@
             if (c instanceof SurfaceHolder.Callback2) {
                 ((SurfaceHolder.Callback2) c).surfaceRedrawNeededAsync(
                         holder, mFinishDrawingRunnable);
+                mSurfaceRedrawImplemented = true;
             } else {
                 mFinishDrawingRunnable.run();
             }
diff --git a/core/java/com/android/internal/widget/ConversationLayout.java b/core/java/com/android/internal/widget/ConversationLayout.java
index bd654fa..2bfbf84 100644
--- a/core/java/com/android/internal/widget/ConversationLayout.java
+++ b/core/java/com/android/internal/widget/ConversationLayout.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.widget;
 
+import static android.widget.flags.Flags.conversationLayoutUseMaximumChildHeight;
+
 import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_EXTERNAL;
 import static com.android.internal.widget.MessagingGroup.IMAGE_DISPLAY_LOCATION_INLINE;
 
@@ -1407,6 +1409,38 @@
         }
     }
 
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        // ConversationLayout needs to set its height to its biggest child to show the content
+        // properly.
+        // FrameLayout measures its match_parent children twice when any of FLs dimension is not
+        // specified. However, its sets its own dimensions before the second measurement pass.
+        // Content CutOff happens when children have bigger height on its second measurement.
+        if (conversationLayoutUseMaximumChildHeight()) {
+            int maxHeight = getMeasuredHeight();
+            final int count = getChildCount();
+
+            for (int i = 0; i < count; i++) {
+                final View child = getChildAt(i);
+                if (child == null || child.getVisibility() == GONE) {
+                    continue;
+                }
+
+                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+                maxHeight = Math.max(maxHeight,
+                        child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
+            }
+
+            maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
+            if (maxHeight != getMeasuredHeight()) {
+                setMeasuredDimension(getMeasuredWidth(), maxHeight);
+            }
+        }
+    }
+
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
diff --git a/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl b/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl
index 1d0e972..7e8724d 100644
--- a/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl
+++ b/core/java/com/android/internal/widget/IRemoteViewsFactory.aidl
@@ -39,6 +39,6 @@
     boolean hasStableIds();
     @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     boolean isCreated();
-    RemoteViews.RemoteCollectionItems getRemoteCollectionItems(int capSize);
+    RemoteViews.RemoteCollectionItems getRemoteCollectionItems(int capSize, int capBitmapSize);
 }
 
diff --git a/core/java/com/android/internal/widget/NotificationCloseButton.java b/core/java/com/android/internal/widget/NotificationCloseButton.java
new file mode 100644
index 0000000..bce266d
--- /dev/null
+++ b/core/java/com/android/internal/widget/NotificationCloseButton.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.widget;
+
+import android.annotation.ColorInt;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.util.AttributeSet;
+import android.view.RemotableViewMethod;
+import android.view.View;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.RemoteViews;
+
+import com.android.internal.R;
+
+/**
+ * A close button in a notification
+ */
+@RemoteViews.RemoteView
+public class NotificationCloseButton extends ImageView {
+
+    @ColorInt private int mBackgroundColor;
+    @ColorInt private int mForegroundColor;
+
+    public NotificationCloseButton(Context context) {
+        this(context, null, 0, 0);
+    }
+
+    public NotificationCloseButton(Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, 0, 0);
+    }
+
+    public NotificationCloseButton(Context context, @Nullable AttributeSet attrs,
+            int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public NotificationCloseButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        setContentDescription(mContext.getText(R.string.close_button_text));
+        boolean notificationCloseButtonSupported = Resources.getSystem().getBoolean(
+                com.android.internal.R.bool.config_notificationCloseButtonSupported);
+        this.setVisibility(notificationCloseButtonSupported ? View.VISIBLE : View.GONE);
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        info.setClassName(Button.class.getName());
+    }
+
+
+    private void updateColors() {
+        if (mBackgroundColor != 0) {
+            this.setBackgroundTintList(ColorStateList.valueOf(mBackgroundColor));
+        }
+        if (mForegroundColor != 0) {
+            this.setImageTintList(ColorStateList.valueOf(mForegroundColor));
+        }
+    }
+
+    /**
+     * Set the color used for the foreground.
+     */
+    @RemotableViewMethod
+    public void setForegroundColor(@ColorInt int color) {
+        mForegroundColor = color;
+        updateColors();
+    }
+
+    /**
+     * Sets the color used for the background.
+     */
+    @RemotableViewMethod
+    public void setBackgroundColor(@ColorInt int color) {
+        mBackgroundColor = color;
+        updateColors();
+    }
+}
diff --git a/core/java/com/android/internal/widget/NotificationRowIconView.java b/core/java/com/android/internal/widget/NotificationRowIconView.java
index 58bddae..98e6e85 100644
--- a/core/java/com/android/internal/widget/NotificationRowIconView.java
+++ b/core/java/com/android/internal/widget/NotificationRowIconView.java
@@ -22,7 +22,12 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapShader;
 import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
 import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
@@ -30,12 +35,21 @@
 import android.view.RemotableViewMethod;
 import android.widget.RemoteViews;
 
+import com.android.internal.R;
+
 /**
- * An image view that holds the icon displayed on the left side of a notification row.
+ * An image view that holds the icon displayed at the start of a notification row.
  */
 @RemoteViews.RemoteView
 public class NotificationRowIconView extends CachingIconView {
     private boolean mApplyCircularCrop = false;
+    private boolean mShouldShowAppIcon = false;
+
+    // Padding and background set on the view prior to being changed by setShouldShowAppIcon(true),
+    // to be restored if shouldShowAppIcon becomes false again.
+    private Rect mOriginalPadding = null;
+    private Drawable mOriginalBackground = null;
+
 
     public NotificationRowIconView(Context context) {
         super(context);
@@ -59,7 +73,7 @@
     @Override
     protected void onFinishInflate() {
         // If showing the app icon, we don't need background or padding.
-        if (Flags.notificationsUseAppIcon() || Flags.notificationsUseAppIconInRow()) {
+        if (Flags.notificationsUseAppIcon()) {
             setPadding(0, 0, 0, 0);
             setBackground(null);
         }
@@ -67,6 +81,45 @@
         super.onFinishInflate();
     }
 
+    /** Whether the icon represents the app icon (instead of the small icon). */
+    @RemotableViewMethod
+    public void setShouldShowAppIcon(boolean shouldShowAppIcon) {
+        if (Flags.notificationsUseAppIconInRow()) {
+            if (mShouldShowAppIcon == shouldShowAppIcon) {
+                return; // no change
+            }
+
+            mShouldShowAppIcon = shouldShowAppIcon;
+            if (mShouldShowAppIcon) {
+                if (mOriginalPadding == null && mOriginalBackground == null) {
+                    mOriginalPadding = new Rect(getPaddingLeft(), getPaddingTop(),
+                            getPaddingRight(), getPaddingBottom());
+                    mOriginalBackground = getBackground();
+                }
+
+                setPadding(0, 0, 0, 0);
+
+                // Make the background white in case the icon itself doesn't have one.
+                ColorFilter colorFilter = new PorterDuffColorFilter(Color.WHITE,
+                        PorterDuff.Mode.SRC_ATOP);
+
+                if (mOriginalBackground == null) {
+                    setBackground(getContext().getDrawable(R.drawable.notification_icon_circle));
+                }
+                getBackground().mutate().setColorFilter(colorFilter);
+            } else {
+                // Restore original padding and background if needed
+                if (mOriginalPadding != null) {
+                    setPadding(mOriginalPadding.left, mOriginalPadding.top, mOriginalPadding.right,
+                            mOriginalPadding.bottom);
+                    mOriginalPadding = null;
+                }
+                setBackground(mOriginalBackground);
+                mOriginalBackground = null;
+            }
+        }
+    }
+
     @Nullable
     @Override
     Drawable loadSizeRestrictedIcon(@Nullable Icon icon) {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
index 00262be..5c2a167 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
@@ -15,6 +15,7 @@
  */
 package com.android.internal.widget.remotecompose.core;
 
+import com.android.internal.widget.remotecompose.core.operations.NamedVariable;
 import com.android.internal.widget.remotecompose.core.operations.RootContentBehavior;
 import com.android.internal.widget.remotecompose.core.operations.Theme;
 
@@ -308,9 +309,10 @@
 
         /**
          * Returns true if x,y coordinate is within bounds
+         *
          * @param x x-coordinate
          * @param y y-coordinate
-         * @return x,y coordinate is within bounds
+         * @return x, y coordinate is within bounds
          */
         public boolean contains(float x, float y) {
             return x >= mLeft && x < mRight
@@ -483,6 +485,37 @@
         return builder.toString();
     }
 
+    /**
+     * Gets the names of all named colors.
+     *
+     * @return array of named colors or null
+     */
+    public String[] getNamedColors() {
+        int count = 0;
+        for (Operation op : mOperations) {
+            if (op instanceof NamedVariable) {
+                NamedVariable n = (NamedVariable) op;
+                if (n.mVarType == NamedVariable.COLOR_TYPE) {
+                    count++;
+                }
+            }
+        }
+        if (count == 0) {
+            return null;
+        }
+        String[] ret = new String[count];
+        int i = 0;
+        for (Operation op : mOperations) {
+            if (op instanceof NamedVariable) {
+                NamedVariable n = (NamedVariable) op;
+                if (n.mVarType == NamedVariable.COLOR_TYPE) {
+                    ret[i++] = n.mVarName;
+                }
+            }
+        }
+        return ret;
+    }
+
     //////////////////////////////////////////////////////////////////////////
     // Painting
     //////////////////////////////////////////////////////////////////////////
@@ -493,6 +526,7 @@
 
     /**
      * Returns > 0 if it needs to repaint
+     *
      * @return
      */
     public int needsRepaint() {
@@ -525,7 +559,6 @@
         context.loadFloat(RemoteContext.ID_WINDOW_WIDTH, getWidth());
         context.loadFloat(RemoteContext.ID_WINDOW_HEIGHT, getHeight());
         mRepaintNext = context.updateOps();
-
         for (Operation op : mOperations) {
             // operations will only be executed if no theme is set (ie UNSPECIFIED)
             // or the theme is equal as the one passed in argument to paint.
diff --git a/core/java/com/android/internal/widget/remotecompose/core/Operations.java b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
index 4b45ab6..fc8668e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/Operations.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
@@ -19,6 +19,7 @@
 import com.android.internal.widget.remotecompose.core.operations.ClickArea;
 import com.android.internal.widget.remotecompose.core.operations.ClipPath;
 import com.android.internal.widget.remotecompose.core.operations.ClipRect;
+import com.android.internal.widget.remotecompose.core.operations.ColorConstant;
 import com.android.internal.widget.remotecompose.core.operations.ColorExpression;
 import com.android.internal.widget.remotecompose.core.operations.DrawArc;
 import com.android.internal.widget.remotecompose.core.operations.DrawBitmap;
@@ -42,6 +43,7 @@
 import com.android.internal.widget.remotecompose.core.operations.MatrixScale;
 import com.android.internal.widget.remotecompose.core.operations.MatrixSkew;
 import com.android.internal.widget.remotecompose.core.operations.MatrixTranslate;
+import com.android.internal.widget.remotecompose.core.operations.NamedVariable;
 import com.android.internal.widget.remotecompose.core.operations.PaintData;
 import com.android.internal.widget.remotecompose.core.operations.PathData;
 import com.android.internal.widget.remotecompose.core.operations.RootContentBehavior;
@@ -105,6 +107,8 @@
     public static final int COLOR_EXPRESSIONS = 134;
     public static final int TEXT_FROM_FLOAT = 135;
     public static final int TEXT_MERGE = 136;
+    public static final int NAMED_VARIABLE = 137;
+    public static final int COLOR_CONSTANT = 138;
 
     /////////////////////////////////////////======================
     public static IntMap<CompanionOperation> map = new IntMap<>();
@@ -147,7 +151,8 @@
         map.put(COLOR_EXPRESSIONS, ColorExpression.COMPANION);
         map.put(TEXT_FROM_FLOAT, TextFromFloat.COMPANION);
         map.put(TEXT_MERGE, TextMerge.COMPANION);
-
+        map.put(NAMED_VARIABLE, NamedVariable.COMPANION);
+        map.put(COLOR_CONSTANT, ColorConstant.COMPANION);
     }
 
 }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
index 52fc314..d462c7d 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
@@ -19,6 +19,7 @@
 import com.android.internal.widget.remotecompose.core.operations.ClickArea;
 import com.android.internal.widget.remotecompose.core.operations.ClipPath;
 import com.android.internal.widget.remotecompose.core.operations.ClipRect;
+import com.android.internal.widget.remotecompose.core.operations.ColorConstant;
 import com.android.internal.widget.remotecompose.core.operations.ColorExpression;
 import com.android.internal.widget.remotecompose.core.operations.DrawArc;
 import com.android.internal.widget.remotecompose.core.operations.DrawBitmap;
@@ -42,6 +43,7 @@
 import com.android.internal.widget.remotecompose.core.operations.MatrixScale;
 import com.android.internal.widget.remotecompose.core.operations.MatrixSkew;
 import com.android.internal.widget.remotecompose.core.operations.MatrixTranslate;
+import com.android.internal.widget.remotecompose.core.operations.NamedVariable;
 import com.android.internal.widget.remotecompose.core.operations.PaintData;
 import com.android.internal.widget.remotecompose.core.operations.PathData;
 import com.android.internal.widget.remotecompose.core.operations.RootContentBehavior;
@@ -899,6 +901,20 @@
     }
 
     /**
+     * Add a simple color
+     * @param color
+     * @return id that represents that color
+     */
+    public int addColor(int color) {
+        ColorConstant c = new ColorConstant(0, color);
+        short id = (short) mRemoteComposeState.cache(c);
+        c.mColorId = id;
+        c.write(mBuffer);
+        return id;
+    }
+
+
+    /**
      * Add a color that represents the tween between two colors
      * @param color1
      * @param color2
@@ -1013,5 +1029,14 @@
         return FloatAnimation.packToFloatArray(duration, type, spec, initialValue, wrap);
     }
 
+    /**
+     * This defines the name of the color given the id.
+     * @param id of the color
+     * @param name Name of the color
+     */
+    public void setColorName(int id, String name) {
+        NamedVariable.COMPANION.apply(mBuffer, id,
+                NamedVariable.COLOR_TYPE, name);
+    }
 }
 
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
index 66a37e67..bfe67c8 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeState.java
@@ -33,11 +33,13 @@
 public class RemoteComposeState {
     public static final int START_ID = 42;
     private static final int MAX_FLOATS = 500;
+    private static final int MAX_COLORS = 200;
     private final IntMap<Object> mIntDataMap = new IntMap<>();
     private final IntMap<Boolean> mIntWrittenMap = new IntMap<>();
     private final HashMap<Object, Integer> mDataIntMap = new HashMap();
     private final float[] mFloatMap = new float[MAX_FLOATS]; // efficient cache
-    private final int[] mColorMap = new int[MAX_FLOATS]; // efficient cache
+    private final int[] mColorMap = new int[MAX_COLORS]; // efficient cache
+    private final boolean[] mColorOverride = new boolean[MAX_COLORS];
     private int mNextId = START_ID;
 
     {
@@ -49,6 +51,7 @@
     /**
      * Get Object based on id. The system will cache things like bitmaps
      * Paths etc. They can be accessed with this command
+     *
      * @param id
      * @return
      */
@@ -58,6 +61,7 @@
 
     /**
      * true if the cache contain this id
+     *
      * @param id
      * @return
      */
@@ -150,9 +154,32 @@
      * @param color
      */
     public void updateColor(int id, int color) {
+        if (mColorOverride[id]) {
+            return;
+        }
         mColorMap[id] = color;
     }
 
+    /**
+     * Adds a colorOverride.
+     * This is a list of ids and there colors optimized for playback;
+     *
+     * @param id
+     * @param color
+     */
+    public void overrideColor(int id, int color) {
+        mColorOverride[id] = true;
+        mColorMap[id] = color;
+    }
+
+    /**
+     * Clear the color Overrides
+     */
+    public void clearColorOverride() {
+        for (int i = 0; i < mColorOverride.length; i++) {
+            mColorOverride[i] = false;
+        }
+    }
 
     /**
      * Method to determine if a cached value has been written to the documents WireBuffer based on
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
index 7e72168..32027d8 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
@@ -72,6 +72,14 @@
         return (System.nanoTime() - mStart) * 1E-9f;
     }
 
+    /**
+     * Set the value of a named Color.
+     * This overrides the color in the document
+     * @param colorName
+     * @param color
+     */
+    public abstract void setNamedColorOverride(String colorName, int color);
+
 
     /**
      * The context can be used in a few different mode, allowing operations to skip being executed:
@@ -262,16 +270,45 @@
     public static final int ID_COMPONENT_WIDTH = 7;
     public static final int ID_COMPONENT_HEIGHT = 8;
     public static final int ID_CALENDAR_MONTH = 9;
+    public static final int ID_OFFSET_TO_UTC = 10;
+    public static final int ID_WEEK_DAY = 11;
+    public static final int ID_DAY_OF_MONTH = 12;
 
+    /**
+     * CONTINUOUS_SEC is seconds from midnight looping every hour 0-3600
+     */
     public static final float FLOAT_CONTINUOUS_SEC = Utils.asNan(ID_CONTINUOUS_SEC);
+    /**
+     * seconds run from Midnight=0 quantized to seconds hour 0..3599
+     */
     public static final float FLOAT_TIME_IN_SEC = Utils.asNan(ID_TIME_IN_SEC);
+    /**
+     * minutes run from Midnight=0 quantized to minutes 0..1439
+     */
     public static final float FLOAT_TIME_IN_MIN = Utils.asNan(ID_TIME_IN_MIN);
+    /**
+     * hours run from Midnight=0 quantized to Hours 0-23
+     */
     public static final float FLOAT_TIME_IN_HR = Utils.asNan(ID_TIME_IN_HR);
+    /**
+     * Moth of Year quantized to MONTHS 1-12. 1 = January
+     */
     public static final float FLOAT_CALENDAR_MONTH = Utils.asNan(ID_CALENDAR_MONTH);
+    /**
+     * DAY OF THE WEEK 1-7. 1 = Monday
+     */
+    public static final float FLOAT_WEEK_DAY = Utils.asNan(ID_WEEK_DAY);
+    /**
+     * DAY OF THE MONTH 1-31
+     */
+    public static final float FLOAT_DAY_OF_MONTH = Utils.asNan(ID_DAY_OF_MONTH);
+
     public static final float FLOAT_WINDOW_WIDTH = Utils.asNan(ID_WINDOW_WIDTH);
     public static final float FLOAT_WINDOW_HEIGHT = Utils.asNan(ID_WINDOW_HEIGHT);
     public static final float FLOAT_COMPONENT_WIDTH = Utils.asNan(ID_COMPONENT_WIDTH);
     public static final float FLOAT_COMPONENT_HEIGHT = Utils.asNan(ID_COMPONENT_HEIGHT);
+    // ID_OFFSET_TO_UTC is the offset from UTC in sec (typically / 3600f)
+    public static final float FLOAT_OFFSET_TO_UTC = Utils.asNan(ID_OFFSET_TO_UTC);
     ///////////////////////////////////////////////////////////////////////////////////////////////
     // Click handling
     ///////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java b/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java
index e9708b7..04e04bbb 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/TimeVariables.java
@@ -16,6 +16,9 @@
 package com.android.internal.widget.remotecompose.core;
 
 import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
 
 /**
  * This generates the standard system variables for time.
@@ -23,6 +26,7 @@
 public class TimeVariables {
     /**
      * This class populates all time variables in the system
+     *
      * @param context
      */
     public void updateTime(RemoteContext context) {
@@ -33,19 +37,29 @@
         // hours run from Midnight=0 quantized to Hours 0-23
         // CONTINUOUS_SEC is seconds from midnight looping every hour 0-3600
         // CONTINUOUS_SEC is accurate to milliseconds due to float precession
-        int month = dateTime.getDayOfMonth();
+        // ID_OFFSET_TO_UTC is the offset from UTC in sec (typically / 3600f)
+        int month = dateTime.getMonth().getValue();
         int hour = dateTime.getHour();
         int minute = dateTime.getMinute();
         int seconds = dateTime.getSecond();
         int currentMinute = hour * 60 + minute;
         int currentSeconds = minute * 60 + seconds;
         float sec = currentSeconds + dateTime.getNano() * 1E-9f;
+        int day_week = dateTime.getDayOfWeek().getValue();
 
+
+        ZoneId zone = ZoneId.systemDefault();
+        OffsetDateTime offsetDateTime = dateTime.atZone(zone).toOffsetDateTime();
+        ZoneOffset offset = offsetDateTime.getOffset();
+
+        context.loadFloat(RemoteContext.ID_OFFSET_TO_UTC, offset.getTotalSeconds());
         context.loadFloat(RemoteContext.ID_CONTINUOUS_SEC, sec);
         context.loadFloat(RemoteContext.ID_TIME_IN_SEC, currentSeconds);
         context.loadFloat(RemoteContext.ID_TIME_IN_MIN, currentMinute);
         context.loadFloat(RemoteContext.ID_TIME_IN_HR, hour);
         context.loadFloat(RemoteContext.ID_CALENDAR_MONTH, month);
+        context.loadFloat(RemoteContext.ID_DAY_OF_MONTH, month);
+        context.loadFloat(RemoteContext.ID_WEEK_DAY, day_week);
 
     }
 }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java
new file mode 100644
index 0000000..15c208f
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ColorConstant.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.widget.remotecompose.core.operations;
+
+import com.android.internal.widget.remotecompose.core.CompanionOperation;
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+
+import java.util.List;
+
+/**
+ * Operation that defines a simple Color based on ID
+ * Mainly for colors in theming.
+ */
+public class ColorConstant implements Operation {
+    public int mColorId;
+    public int mColor;
+    public static final Companion COMPANION = new Companion();
+
+    public ColorConstant(int colorId, int color) {
+        this.mColorId = colorId;
+        this.mColor = color;
+    }
+
+    @Override
+    public void write(WireBuffer buffer) {
+        COMPANION.apply(buffer, mColorId, mColor);
+    }
+
+    @Override
+    public String toString() {
+        return "ColorConstant[" + mColorId + "] = " + Utils.colorInt(mColor) + "";
+    }
+
+    public static class Companion implements CompanionOperation {
+        private Companion() {
+        }
+
+        @Override
+        public String name() {
+            return "ColorConstant";
+        }
+
+        @Override
+        public int id() {
+            return Operations.COLOR_CONSTANT;
+        }
+
+        /**
+         * Writes out the operation to the buffer
+         *
+         * @param buffer
+         * @param colorId
+         * @param color
+         */
+        public void apply(WireBuffer buffer, int colorId, int color) {
+            buffer.start(Operations.COLOR_CONSTANT);
+            buffer.writeInt(colorId);
+            buffer.writeInt(color);
+        }
+
+        @Override
+        public void read(WireBuffer buffer, List<Operation> operations) {
+            int colorId = buffer.readInt();
+            int color = buffer.readInt();
+            operations.add(new ColorConstant(colorId, color));
+        }
+    }
+
+    @Override
+    public void apply(RemoteContext context) {
+        context.loadColor(mColorId, mColor);
+    }
+
+    @Override
+    public String deepToString(String indent) {
+        return indent + toString();
+    }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java b/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java
index 0c5b286..ae27f5f 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/NamedVariable.java
@@ -32,7 +32,9 @@
     public int mVarType;
     public static final Companion COMPANION = new Companion();
     public static final int MAX_STRING_SIZE = 4000;
-
+    public static final int COLOR_TYPE = 2;
+    public static final int FLOAT_TYPE = 1;
+    public static final int STRING_TYPE = 0;
     public NamedVariable(int varId, int varType, String name) {
         this.mVarId = varId;
         this.mVarType = varType;
@@ -72,7 +74,7 @@
          * @param text
          */
         public void apply(WireBuffer buffer, int varId, int varType, String text) {
-            buffer.start(Operations.DATA_TEXT);
+            buffer.start(Operations.NAMED_VARIABLE);
             buffer.writeInt(varId);
             buffer.writeInt(varType);
             buffer.writeUTF8(text);
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java b/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java
index fdc6860..fcb3bfa 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/Utils.java
@@ -78,7 +78,9 @@
      */
     public static void log(String str) {
         StackTraceElement s = new Throwable().getStackTrace()[1];
-        System.out.println("(" + s.getFileName() + ":" + s.getLineNumber() + ")." + str);
+        System.out.println("(" + s.getFileName()
+                + ":" + s.getLineNumber() + "). "
+                + s.getMethodName() + "() " + str);
     }
 
     /**
diff --git a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java
index d1c4d46..a42c584 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposeDocument.java
@@ -103,5 +103,15 @@
         return "Document{\n"
                 + mDocument + '}';
     }
+
+    /**
+     * Gets a array of Names of the named colors defined in the loaded doc.
+     *
+     * @return
+     */
+    public String[] getNamedColors() {
+        return mDocument.getNamedColors();
+    }
+
 }
 
diff --git a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
index 7423a16..73e94fa 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
@@ -16,9 +16,11 @@
 package com.android.internal.widget.remotecompose.player;
 
 import android.content.Context;
+import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.TypedValue;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 import android.widget.HorizontalScrollView;
@@ -53,6 +55,7 @@
 
     /**
      * Turn on debug information
+     *
      * @param debugFlags 1 to set debug on
      */
     public void setDebug(int debugFlags) {
@@ -79,6 +82,7 @@
         } else {
             mInner.setDocument(null);
         }
+        mapColors();
     }
 
     /**
@@ -106,7 +110,8 @@
                             LayoutParams.MATCH_PARENT);
                     addView(horizontalScrollView, layoutParams);
                 }
-            } break;
+            }
+            break;
             case RootContentBehavior.SCROLL_VERTICAL: {
                 if (!(mInner.getParent() instanceof ScrollView)) {
                     ((ViewGroup) mInner.getParent()).removeView(mInner);
@@ -123,9 +128,10 @@
                             LayoutParams.MATCH_PARENT);
                     addView(scrollView, layoutParams);
                 }
-            } break;
+            }
+            break;
             default:
-                if (mInner.getParent() != this)  {
+                if (mInner.getParent() != this) {
                     ((ViewGroup) mInner.getParent()).removeView(mInner);
                     removeAllViews();
                     LayoutParams layoutParams = new LayoutParams(
@@ -178,5 +184,230 @@
             mInner.invalidate();
         }
     }
+
+    /**
+     * This returns a list of colors that have names in the Document.
+     *
+     * @return
+     */
+    public String[] getNamedColors() {
+        return mInner.getNamedColors();
+    }
+
+    /**
+     * This sets a color based on its name. Overriding the color set in
+     * the document.
+     *
+     * @param colorName Name of the color
+     * @param colorValue The new color value
+     */
+    public void setColor(String colorName, int colorValue) {
+        mInner.setColor(colorName, colorValue);
+    }
+
+    private void mapColors() {
+        String[] name = getNamedColors();
+
+        // make every effort to terminate early
+        if (name == null) {
+            return;
+        }
+        boolean found = false;
+        for (int i = 0; i < name.length; i++) {
+            if (name[i].startsWith("android.")) {
+                found = true;
+                break;
+            }
+        }
+        if (!found) {
+            return;
+        }
+
+        for (int i = 0; i < name.length; i++) {
+            String s = name[i];
+            if (!s.startsWith("android.")) {
+                continue;
+            }
+            String sub = s.substring("android.".length());
+            switch (sub) {
+                case "actionBarItemBackground":
+                    setRColor(s, android.R.attr.actionBarItemBackground);
+                    break;
+                case "actionModeBackground":
+                    setRColor(s, android.R.attr.actionModeBackground);
+                    break;
+                case "actionModeSplitBackground":
+                    setRColor(s, android.R.attr.actionModeSplitBackground);
+                    break;
+                case "activatedBackgroundIndicator":
+                    setRColor(s, android.R.attr.activatedBackgroundIndicator);
+                    break;
+                case "colorAccent": // Highlight color for interactive elements
+                    setRColor(s, android.R.attr.colorAccent);
+                    break;
+                case "colorActivatedHighlight":
+                    setRColor(s, android.R.attr.colorActivatedHighlight);
+                    break;
+                case "colorBackground": // background color for the app’s window
+                    setRColor(s, android.R.attr.colorBackground);
+                    break;
+                case "colorBackgroundCacheHint":
+                    setRColor(s, android.R.attr.colorBackgroundCacheHint);
+                    break;
+                //  Background color for floating elements
+                case "colorBackgroundFloating":
+                    setRColor(s, android.R.attr.colorBackgroundFloating);
+                    break;
+                case "colorButtonNormal": // The default color for buttons
+                    setRColor(s, android.R.attr.colorButtonNormal);
+                    break;
+                // Color for activated (checked) state of controls.
+                case "colorControlActivated":
+                    setRColor(s, android.R.attr.colorControlActivated);
+                    break;
+                case "colorControlHighlight": // Color for highlights on controls
+                    setRColor(s, android.R.attr.colorControlHighlight);
+                    break;
+                // Default color for controls in their normal state.
+                case "colorControlNormal":
+                    setRColor(s, android.R.attr.colorControlNormal);
+                    break;
+                // Color for edge effects (e.g., overscroll glow)
+                case "colorEdgeEffect":
+                    setRColor(s, android.R.attr.colorEdgeEffect);
+                    break;
+                case "colorError":
+                    setRColor(s, android.R.attr.colorError);
+                    break;
+                case "colorFocusedHighlight":
+                    setRColor(s, android.R.attr.colorFocusedHighlight);
+                    break;
+                case "colorForeground":   // General foreground color for views.
+                    setRColor(s, android.R.attr.colorForeground);
+                    break;
+                // Foreground color for inverse backgrounds.
+                case "colorForegroundInverse":
+                    setRColor(s, android.R.attr.colorForegroundInverse);
+                    break;
+                case "colorLongPressedHighlight":
+                    setRColor(s, android.R.attr.colorLongPressedHighlight);
+                    break;
+                case "colorMultiSelectHighlight":
+                    setRColor(s, android.R.attr.colorMultiSelectHighlight);
+                    break;
+                case "colorPressedHighlight":
+                    setRColor(s, android.R.attr.colorPressedHighlight);
+                    break;
+                case "colorPrimary": // The primary branding color for the app.
+                    setRColor(s, android.R.attr.colorPrimary);
+                    break;
+                case "colorPrimaryDark": // darker variant of the primary color
+                    setRColor(s, android.R.attr.colorPrimaryDark);
+                    break;
+                case "colorSecondary":
+                    setRColor(s, android.R.attr.colorSecondary);
+                    break;
+                case "detailsElementBackground":
+                    setRColor(s, android.R.attr.detailsElementBackground);
+                    break;
+                case "editTextBackground":
+                    setRColor(s, android.R.attr.editTextBackground);
+                    break;
+                case "galleryItemBackground":
+                    setRColor(s, android.R.attr.galleryItemBackground);
+                    break;
+                case "headerBackground":
+                    setRColor(s, android.R.attr.headerBackground);
+                    break;
+                case "itemBackground":
+                    setRColor(s, android.R.attr.itemBackground);
+                    break;
+                case "numbersBackgroundColor":
+                    setRColor(s, android.R.attr.numbersBackgroundColor);
+                    break;
+                case "panelBackground":
+                    setRColor(s, android.R.attr.panelBackground);
+                    break;
+                case "panelColorBackground":
+                    setRColor(s, android.R.attr.panelColorBackground);
+                    break;
+                case "panelFullBackground":
+                    setRColor(s, android.R.attr.panelFullBackground);
+                    break;
+                case "popupBackground":
+                    setRColor(s, android.R.attr.popupBackground);
+                    break;
+                case "queryBackground":
+                    setRColor(s, android.R.attr.queryBackground);
+                    break;
+                case "selectableItemBackground":
+                    setRColor(s, android.R.attr.selectableItemBackground);
+                    break;
+                case "submitBackground":
+                    setRColor(s, android.R.attr.submitBackground);
+                    break;
+                case "textColor":
+                    setRColor(s, android.R.attr.textColor);
+                    break;
+                case "windowBackground":
+                    setRColor(s, android.R.attr.windowBackground);
+                    break;
+                case "windowBackgroundFallback":
+                    setRColor(s, android.R.attr.windowBackgroundFallback);
+                    break;
+                // Primary text color for inverse backgrounds
+                case "textColorPrimaryInverse":
+                    setRColor(s, android.R.attr.textColorPrimaryInverse);
+                    break;
+                // Secondary text color for inverse backgrounds
+                case "textColorSecondaryInverse":
+                    setRColor(s, android.R.attr.textColorSecondaryInverse);
+                    break;
+                // Tertiary text color for less important text.
+                case "textColorTertiary":
+                    setRColor(s, android.R.attr.textColorTertiary);
+                    break;
+                // Tertiary text color for inverse backgrounds
+                case "textColorTertiaryInverse":
+                    setRColor(s, android.R.attr.textColorTertiaryInverse);
+                    break;
+                // Text highlight color (e.g., selected text background).
+                case "textColorHighlight":
+                    setRColor(s, android.R.attr.textColorHighlight);
+                    break;
+                // Color for hyperlinks.
+                case "textColorLink":
+                    setRColor(s, android.R.attr.textColorLink);
+                    break;
+                //  Color for hint text.
+                case "textColorHint":
+                    setRColor(s, android.R.attr.textColorHint);
+                    break;
+                // text color for inverse backgrounds..
+                case "textColorHintInverse":
+                    setRColor(s, android.R.attr.textColorHintInverse);
+                    break;
+                // Default color for the thumb of switches.
+                case "colorSwitchThumbNormal":
+                    setRColor(s, android.R.attr.colorControlNormal);
+                    break;
+            }
+        }
+    }
+
+    private void setRColor(String name, int id) {
+        int color = getColorFromResource(id);
+        setColor(name, color);
+    }
+
+    private int getColorFromResource(int id) {
+        TypedValue typedValue = new TypedValue();
+        try (TypedArray arr = getContext()
+                .getApplicationContext()
+                .obtainStyledAttributes(typedValue.data, new int[]{id})) {
+            int color = arr.getColor(0, -1);
+            return color;
+        }
+    }
 }
 
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java
index 6e4893b..dd43bd5 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java
@@ -76,6 +76,16 @@
     }
 
     /**
+     * Override a color to force it to be the color provided
+     *
+     * @param colorName name of color
+     * @param color
+     */
+    public void setNamedColorOverride(String colorName, int color) {
+        int id = mVarNameHashMap.get(colorName).mId;
+        mRemoteComposeState.overrideColor(id, color);
+    }
+    /**
      * Decode a byte array into an image and cache it using the given imageId
      *
      * @param width  with of image to be loaded
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
index 97d23c8..a2f79cc 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
@@ -42,6 +42,7 @@
     boolean mInActionDown = false;
     boolean mDebug = false;
     Point mActionDownPoint = new Point(0, 0);
+    AndroidRemoteContext mARContext = new AndroidRemoteContext();
 
     public RemoteComposeCanvas(Context context) {
         super(context);
@@ -88,8 +89,6 @@
         invalidate();
     }
 
-    AndroidRemoteContext mARContext = new AndroidRemoteContext();
-
     @Override
     public void onViewAttachedToWindow(View view) {
         if (mDocument == null) {
@@ -120,6 +119,20 @@
         removeAllViews();
     }
 
+    public String[] getNamedColors() {
+        return mDocument.getNamedColors();
+    }
+
+    /**
+     * set the color associated with this name.
+     *
+     * @param colorName Name of color typically "android.xxx"
+     * @param colorValue "the argb value"
+     */
+    public void setColor(String colorName, int colorValue) {
+        mARContext.setNamedColorOverride(colorName, colorValue);
+    }
+
     public interface ClickCallbacks {
         void click(int id, String metadata);
     }
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 17c4ee9..011ef30 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -111,6 +111,7 @@
         "libminikin",
         "libz",
         "server_configurable_flags",
+        "libaconfig_storage_read_api_cc",
         "android.database.sqlite-aconfig-cc",
         "android.media.audiopolicy-aconfig-cc",
     ],
diff --git a/core/jni/android_database_SQLiteConnection.cpp b/core/jni/android_database_SQLiteConnection.cpp
index 8f70268..7410468 100644
--- a/core/jni/android_database_SQLiteConnection.cpp
+++ b/core/jni/android_database_SQLiteConnection.cpp
@@ -134,10 +134,15 @@
     String8 label(labelChars);
     env->ReleaseStringUTFChars(labelStr, labelChars);
 
+    errno = 0;
     sqlite3* db;
     int err = sqlite3_open_v2(path.c_str(), &db, sqliteFlags, NULL);
     if (err != SQLITE_OK) {
-        throw_sqlite3_exception_errcode(env, err, "Could not open database");
+        if (errno == 0) {
+            throw_sqlite3_exception(env, db, "could not open database");
+        } else {
+            throw_sqlite3_exception(env, db, strerror(errno));
+        }
         return 0;
     }
 
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 2316f4c..3f74fac 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -17,9 +17,12 @@
 
 //#define LOG_NDEBUG 0
 #define LOG_TAG "Camera-JNI"
+#include <android/content/AttributionSourceState.h>
+#include <android_os_Parcel.h>
 #include <android_runtime/android_graphics_SurfaceTexture.h>
 #include <android_runtime/android_view_Surface.h>
 #include <binder/IMemory.h>
+#include <binder/Parcel.h>
 #include <camera/Camera.h>
 #include <camera/StringUtils.h>
 #include <cutils/properties.h>
@@ -523,22 +526,45 @@
     }
 }
 
-static jint android_hardware_Camera_getNumberOfCameras(JNIEnv *env, jobject thiz, jint deviceId,
+static bool attributionSourceStateForJavaParcel(JNIEnv *env, jobject jClientAttributionParcel,
+                                                AttributionSourceState &clientAttribution) {
+    const Parcel *clientAttributionParcel = parcelForJavaObject(env, jClientAttributionParcel);
+    if (clientAttribution.readFromParcel(clientAttributionParcel) != ::android::OK) {
+        jniThrowRuntimeException(env, "Fail to unparcel AttributionSourceState");
+        return false;
+    }
+    clientAttribution.uid = Camera::USE_CALLING_UID;
+    clientAttribution.pid = Camera::USE_CALLING_PID;
+    return true;
+}
+
+static jint android_hardware_Camera_getNumberOfCameras(JNIEnv *env, jobject thiz,
+                                                       jobject jClientAttributionParcel,
                                                        jint devicePolicy) {
-    return Camera::getNumberOfCameras(deviceId, devicePolicy);
+    AttributionSourceState clientAttribution;
+    if (!attributionSourceStateForJavaParcel(env, jClientAttributionParcel, clientAttribution)) {
+        return 0;
+    }
+    return Camera::getNumberOfCameras(clientAttribution, devicePolicy);
 }
 
 static void android_hardware_Camera_getCameraInfo(JNIEnv *env, jobject thiz, jint cameraId,
-                                                  jint rotationOverride, jint deviceId,
+                                                  jint rotationOverride,
+                                                  jobject jClientAttributionParcel,
                                                   jint devicePolicy, jobject info_obj) {
+    AttributionSourceState clientAttribution;
+    if (!attributionSourceStateForJavaParcel(env, jClientAttributionParcel, clientAttribution)) {
+        return;
+    }
+
     CameraInfo cameraInfo;
-    if (cameraId >= Camera::getNumberOfCameras(deviceId, devicePolicy) || cameraId < 0) {
+    if (cameraId >= Camera::getNumberOfCameras(clientAttribution, devicePolicy) || cameraId < 0) {
         ALOGE("%s: Unknown camera ID %d", __FUNCTION__, cameraId);
         jniThrowRuntimeException(env, "Unknown camera ID");
         return;
     }
 
-    status_t rc = Camera::getCameraInfo(cameraId, rotationOverride, deviceId, devicePolicy,
+    status_t rc = Camera::getCameraInfo(cameraId, rotationOverride, clientAttribution, devicePolicy,
                                         &cameraInfo);
     if (rc != NO_ERROR) {
         jniThrowRuntimeException(env, "Fail to get camera info");
@@ -556,23 +582,18 @@
 
 // connect to camera service
 static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
-                                                 jint cameraId, jstring clientPackageName,
-                                                 jint rotationOverride,
-                                                 jboolean forceSlowJpegMode, jint deviceId,
+                                                 jint cameraId, jint rotationOverride,
+                                                 jboolean forceSlowJpegMode,
+                                                 jobject jClientAttributionParcel,
                                                  jint devicePolicy) {
-    // Convert jstring to String16
-    const char16_t *rawClientName = reinterpret_cast<const char16_t*>(
-        env->GetStringChars(clientPackageName, NULL));
-    jsize rawClientNameLen = env->GetStringLength(clientPackageName);
-    std::string clientName = toStdString(rawClientName, rawClientNameLen);
-    env->ReleaseStringChars(clientPackageName,
-                            reinterpret_cast<const jchar*>(rawClientName));
+    AttributionSourceState clientAttribution;
+    if (!attributionSourceStateForJavaParcel(env, jClientAttributionParcel, clientAttribution)) {
+        return -EACCES;
+    }
 
     int targetSdkVersion = android_get_application_target_sdk_version();
-    sp<Camera> camera =
-            Camera::connect(cameraId, clientName, Camera::USE_CALLING_UID, Camera::USE_CALLING_PID,
-                            targetSdkVersion, rotationOverride, forceSlowJpegMode, deviceId,
-                            devicePolicy);
+    sp<Camera> camera = Camera::connect(cameraId, targetSdkVersion, rotationOverride,
+                                        forceSlowJpegMode, clientAttribution, devicePolicy);
     if (camera == NULL) {
         return -EACCES;
     }
@@ -600,7 +621,7 @@
 
     // Update default display orientation in case the sensor is reverse-landscape
     CameraInfo cameraInfo;
-    status_t rc = Camera::getCameraInfo(cameraId, rotationOverride, deviceId, devicePolicy,
+    status_t rc = Camera::getCameraInfo(cameraId, rotationOverride, clientAttribution, devicePolicy,
                                         &cameraInfo);
     if (rc != NO_ERROR) {
         ALOGE("%s: getCameraInfo error: %d", __FUNCTION__, rc);
@@ -1056,10 +1077,11 @@
 //-------------------------------------------------
 
 static const JNINativeMethod camMethods[] = {
-        {"_getNumberOfCameras", "(II)I", (void *)android_hardware_Camera_getNumberOfCameras},
-        {"_getCameraInfo", "(IIIILandroid/hardware/Camera$CameraInfo;)V",
+        {"_getNumberOfCameras", "(Landroid/os/Parcel;I)I",
+         (void *)android_hardware_Camera_getNumberOfCameras},
+        {"_getCameraInfo", "(IILandroid/os/Parcel;ILandroid/hardware/Camera$CameraInfo;)V",
          (void *)android_hardware_Camera_getCameraInfo},
-        {"native_setup", "(Ljava/lang/Object;ILjava/lang/String;IZII)I",
+        {"native_setup", "(Ljava/lang/Object;IIZLandroid/os/Parcel;I)I",
          (void *)android_hardware_Camera_native_setup},
         {"native_release", "()V", (void *)android_hardware_Camera_release},
         {"setPreviewSurface", "(Landroid/view/Surface;)V",
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 5365838..9ce7658 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -22,6 +22,7 @@
 #include <android/graphics/properties.h>
 #include <android/graphics/region.h>
 #include <android/gui/BnWindowInfosReportedListener.h>
+#include <android/gui/JankData.h>
 #include <android/hardware/display/IDeviceProductInfoConstants.h>
 #include <android/os/IInputConstants.h>
 #include <android_runtime/AndroidRuntime.h>
@@ -2062,11 +2063,13 @@
         env->DeleteWeakGlobalRef(mOnJankDataListenerWeak);
     }
 
-    void onJankDataAvailable(const std::vector<JankData>& jankData) {
+    bool onJankDataAvailable(const std::vector<gui::JankData>& jankData) override {
         JNIEnv* env = getEnv();
 
         jobject target = env->NewLocalRef(mOnJankDataListenerWeak);
-        if (target == nullptr) return;
+        if (target == nullptr) {
+            return false;
+        }
 
         jobjectArray jJankDataArray = env->NewObjectArray(jankData.size(),
                 gJankDataClassInfo.clazz, nullptr);
@@ -2082,6 +2085,8 @@
                 jJankDataArray);
         env->DeleteLocalRef(jJankDataArray);
         env->DeleteLocalRef(target);
+
+        return true;
     }
 
 private:
@@ -2096,29 +2101,49 @@
     jobject mOnJankDataListenerWeak;
 };
 
-static void nativeAddJankDataListener(JNIEnv* env, jclass clazz,
-                                       jlong jankDataCallbackListenerPtr,
-                                       jlong nativeSurfaceControl) {
+static jlong nativeCreateJankDataListenerWrapper(JNIEnv* env, jclass clazz,
+                                                 jlong nativeSurfaceControl, jobject listener) {
     sp<SurfaceControl> surface(reinterpret_cast<SurfaceControl *>(nativeSurfaceControl));
     if (surface == nullptr) {
+        return 0;
+    }
+
+    sp<JankDataListenerWrapper> wrapper = sp<JankDataListenerWrapper>::make(env, listener);
+    if (wrapper->addListener(std::move(surface)) != OK) {
+        return 0;
+    }
+
+    wrapper->incStrong((void*)nativeCreateJankDataListenerWrapper);
+    return reinterpret_cast<jlong>(wrapper.get());
+}
+
+static void destroyJankDatalistenerWrapper(void* ptr) {
+    JankDataListenerWrapper* wrapper = reinterpret_cast<JankDataListenerWrapper*>(ptr);
+    if (wrapper == nullptr) {
         return;
     }
-    sp<JankDataListenerWrapper> wrapper =
-            reinterpret_cast<JankDataListenerWrapper*>(jankDataCallbackListenerPtr);
-    TransactionCompletedListener::getInstance()->addJankListener(wrapper, surface);
+    wrapper->decStrong((void*)nativeCreateJankDataListenerWrapper);
 }
 
-static void nativeRemoveJankDataListener(JNIEnv* env, jclass clazz,
-                                          jlong jankDataCallbackListenerPtr) {
-    sp<JankDataListenerWrapper> wrapper =
-            reinterpret_cast<JankDataListenerWrapper*>(jankDataCallbackListenerPtr);
-    TransactionCompletedListener::getInstance()->removeJankListener(wrapper);
+static jlong nativeGetJankDataListenerWrapperFinalizer() {
+    return reinterpret_cast<jlong>(&destroyJankDatalistenerWrapper);
 }
 
-static jlong nativeCreateJankDataListenerWrapper(JNIEnv* env, jclass clazz,
-                                                 jobject jankDataListenerObject) {
-    return reinterpret_cast<jlong>(
-            new JankDataListenerWrapper(env, jankDataListenerObject));
+static void nativeFlushJankData(JNIEnv* env, jclass clazz, jlong listener) {
+    sp<JankDataListenerWrapper> wrapper = reinterpret_cast<JankDataListenerWrapper*>(listener);
+    if (wrapper == nullptr) {
+        return;
+    }
+    wrapper->flushJankData();
+}
+
+static void nativeRemoveJankDataListener(JNIEnv* env, jclass clazz, jlong listener,
+                                         jlong afterVsync) {
+    sp<JankDataListenerWrapper> wrapper = reinterpret_cast<JankDataListenerWrapper*>(listener);
+    if (wrapper == nullptr) {
+        return;
+    }
+    wrapper->removeListener(afterVsync);
 }
 
 static jint nativeGetGPUContextPriority(JNIEnv* env, jclass clazz) {
@@ -2436,12 +2461,14 @@
             (void*)nativeRemoveCurrentInputFocus},
     {"nativeSetFrameTimelineVsync", "(JJ)V",
             (void*)nativeSetFrameTimelineVsync },
-    {"nativeAddJankDataListener", "(JJ)V",
-            (void*)nativeAddJankDataListener },
-    {"nativeRemoveJankDataListener", "(J)V",
+    {"nativeFlushJankData", "(J)V",
+            (void*)nativeFlushJankData },
+    {"nativeRemoveJankDataListener", "(JJ)V",
             (void*)nativeRemoveJankDataListener },
-    {"nativeCreateJankDataListenerWrapper", "(Landroid/view/SurfaceControl$OnJankDataListener;)J",
+    {"nativeCreateJankDataListenerWrapper", "(JLandroid/view/SurfaceControl$OnJankDataListener;)J",
             (void*)nativeCreateJankDataListenerWrapper },
+    {"nativeGetJankDataListenerWrapperFinalizer", "()J",
+            (void*)nativeGetJankDataListenerWrapperFinalizer },
     {"nativeGetGPUContextPriority", "()I",
             (void*)nativeGetGPUContextPriority },
     {"nativeSetTransformHint", "(JI)V",
diff --git a/core/proto/android/content/res/color_state_list.proto b/core/proto/android/content/res/color_state_list.proto
new file mode 100644
index 0000000..3d0d8a8
--- /dev/null
+++ b/core/proto/android/content/res/color_state_list.proto
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless optional by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+option java_multiple_files = true;
+
+package android.content.res;
+
+import "frameworks/base/core/proto/android/privacy.proto";
+
+/**
+ * An android.content.res.ColorStateList object.
+ */
+message ColorStateListProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+    repeated StateSpec state_specs = 1;
+    repeated int32 colors = 2 [packed = true];
+
+    message StateSpec {
+        repeated int32 state = 1 [packed = true];
+    }
+}
diff --git a/core/proto/android/providers/settings/system.proto b/core/proto/android/providers/settings/system.proto
index 6a0ec1d..e5ced25 100644
--- a/core/proto/android/providers/settings/system.proto
+++ b/core/proto/android/providers/settings/system.proto
@@ -126,6 +126,7 @@
         option (android.msg_privacy).dest = DEST_EXPLICIT;
 
         optional SettingProto pointer_fill_style = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        optional SettingProto pointer_stroke_style = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto pointer_scale = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
     }
     optional Pointer pointer = 37;
diff --git a/core/proto/android/server/vibrator/vibratormanagerservice.proto b/core/proto/android/server/vibrator/vibratormanagerservice.proto
index 1d9b0db..5a4d6db 100644
--- a/core/proto/android/server/vibrator/vibratormanagerservice.proto
+++ b/core/proto/android/server/vibrator/vibratormanagerservice.proto
@@ -146,6 +146,7 @@
         IGNORED_FROM_VIRTUAL_DEVICE = 26;
         IGNORED_ON_WIRELESS_CHARGER = 27;
         IGNORED_MISSING_PERMISSION = 28;
+        CANCELLED_BY_APP_OPS = 29;
         reserved 17; // prev IGNORED_UNKNOWN_VIBRATION
     }
 }
diff --git a/core/proto/android/view/displayinfo.proto b/core/proto/android/view/displayinfo.proto
index f936ed1..32f4cb3 100644
--- a/core/proto/android/view/displayinfo.proto
+++ b/core/proto/android/view/displayinfo.proto
@@ -36,4 +36,5 @@
     optional string name = 5;
     optional int32 flags = 6;
     optional DisplayCutoutProto cutout = 7;
+    optional int32 type = 8;
 }
diff --git a/core/proto/android/widget/remoteviews.proto b/core/proto/android/widget/remoteviews.proto
new file mode 100644
index 0000000..f08ea1b
--- /dev/null
+++ b/core/proto/android/widget/remoteviews.proto
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless optional by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+option java_multiple_files = true;
+
+package android.widget;
+
+import "frameworks/base/core/proto/android/privacy.proto";
+
+/**
+ * An android.widget.RemoteViews object. This is used by RemoteViews.createPreviewFromProto
+ * and RemoteViews.writePreviewToProto.
+ *
+ * Any addition of fields here will require an update to the parsing code in RemoteViews.java.
+ * Otherwise the field will be ignored when parsing (with a logged warning).
+ *
+ * Do not change the tag number or type of any fields in order to maintain compatibility with
+ * previous versions. If a field is deleted, use `reserved` to mark its tag number.
+ */
+message RemoteViewsProto {
+    option (android.msg_privacy).dest = DEST_AUTOMATIC;
+    optional int32 mode = 1;
+    optional string package_name = 2;
+    optional string layout_id = 3;
+    optional string light_background_layout_id = 4;
+    optional string view_id = 5;
+    optional SizeFProto ideal_size = 6;
+    optional int32 apply_flags = 7;
+    optional int64 provider_instance_id = 8;
+    // RemoteViews for different sizes (created with RemoteViews(Map<SizeF, RemoteViews)
+    // constructor).
+    repeated RemoteViewsProto sized_remoteviews = 9;
+    // RemoteViews for portrait/landscape (created with RemoteViews(RemoteViews, RemoteViews)i
+    // constructor).
+    optional RemoteViewsProto portrait_remoteviews = 10;
+    optional RemoteViewsProto landscape_remoteviews = 11;
+    optional bool is_root = 12;
+    optional bool has_draw_instructions = 13;
+    repeated bytes bitmap_cache = 14;
+    optional RemoteCollectionCache remote_collection_cache = 15;
+
+    message RemoteCollectionCache {
+        message Entry {
+            optional int64 id = 1;
+            optional string uri = 2;
+            optional RemoteCollectionItems items = 3;
+        }
+
+        repeated Entry entries = 1;
+    }
+
+    message RemoteCollectionItems {
+        repeated int64 ids = 1 [packed = true];
+        repeated RemoteViewsProto views = 2;
+        optional bool has_stable_ids = 3;
+        optional int32 view_type_count = 4;
+        optional bool attached = 5;
+    }
+}
+
+
+message SizeFProto {
+    optional float width = 1;
+    optional float height = 2;
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index c71f9bd..9f00d5e 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -843,6 +843,7 @@
     <protected-broadcast android:name="android.intent.action.PROFILE_UNAVAILABLE" />
     <protected-broadcast android:name="android.app.action.CONSOLIDATED_NOTIFICATION_POLICY_CHANGED" />
     <protected-broadcast android:name="android.intent.action.MAIN_USER_LOCKSCREEN_KNOWLEDGE_FACTOR_CHANGED" />
+    <protected-broadcast android:name="com.android.uwb.uwbcountrycode.GEOCODE_RETRY" />
 
     <!-- ====================================================================== -->
     <!--                          RUNTIME PERMISSIONS                           -->
@@ -5593,6 +5594,15 @@
     <permission android:name="android.permission.BIND_TV_INPUT"
         android:protectionLevel="signature|privileged" />
 
+    <!-- This permission is required among systems services to always keep the
+         binding with TvInputManagerService.
+         <p>This should only be used by the OEM TvInputService.
+         <p>Protection level: signature|privileged|vendorPrivileged
+         @hide
+    -->
+    <permission android:name="android.permission.ALWAYS_BOUND_TV_INPUT"
+        android:protectionLevel="signature|privileged|vendorPrivileged" />
+
     <!-- Must be required by a {@link android.media.tv.interactive.TvInteractiveAppService}
          to ensure that only the system can bind to it.
          <p>Protection level: signature|privileged
@@ -8222,6 +8232,19 @@
     <permission android:name="android.permission.CAPTURE_CONSENTLESS_BUGREPORT_ON_USERDEBUG_BUILD"
                 android:protectionLevel="internal|appop" />
 
+    <!-- @hide @SystemApi
+         @FlaggedApi(android.os.Flags.FLAG_ALLOW_CONSENTLESS_BUGREPORT_DELEGATED_CONSENT)
+         Allows system applications to capture bugreport directly without consent dialog when using
+         the bugreporting API, and instead use the applications-owned consent page.
+         <p>The application still needs to hold {@link android.permission.DUMP} permission and be
+         bugreport-whitelisted to be able to capture a bugreport using the bugreporting API in the
+         first place.
+         <p>Protection level: signature|privileged
+         <p>Not for use by third-party applications. -->
+    <permission
+        android:name="android.permission.CAPTURE_CONSENTLESS_BUGREPORT_DELEGATED_CONSENT"
+        android:protectionLevel="signature|privileged" />
+
     <!-- @SystemApi Allows to call APIs that log process lifecycle events
          @hide -->
     <permission android:name="android.permission.LOG_FOREGROUND_RESOURCE_USE"
diff --git a/core/res/res/anim/overlay_task_fragment_change.xml b/core/res/res/anim/overlay_task_fragment_change.xml
new file mode 100644
index 0000000..eb02ba8
--- /dev/null
+++ b/core/res/res/anim/overlay_task_fragment_change.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:showBackdrop="false">
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/overlay_task_fragment_close_to_bottom.xml b/core/res/res/anim/overlay_task_fragment_close_to_bottom.xml
new file mode 100644
index 0000000..d9487cb
--- /dev/null
+++ b/core/res/res/anim/overlay_task_fragment_close_to_bottom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <translate
+        android:fromYDelta="0"
+        android:toYDelta="100%"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:duration="517" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/overlay_task_fragment_close_to_left.xml b/core/res/res/anim/overlay_task_fragment_close_to_left.xml
new file mode 100644
index 0000000..3cdb77a
--- /dev/null
+++ b/core/res/res/anim/overlay_task_fragment_close_to_left.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <translate
+        android:fromXDelta="0"
+        android:toXDelta="-100%"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:duration="517" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/overlay_task_fragment_close_to_right.xml b/core/res/res/anim/overlay_task_fragment_close_to_right.xml
new file mode 100644
index 0000000..3764561
--- /dev/null
+++ b/core/res/res/anim/overlay_task_fragment_close_to_right.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <translate
+        android:fromXDelta="0"
+        android:toXDelta="100%"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:duration="517" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/overlay_task_fragment_close_to_top.xml b/core/res/res/anim/overlay_task_fragment_close_to_top.xml
new file mode 100644
index 0000000..a8bfbbd
--- /dev/null
+++ b/core/res/res/anim/overlay_task_fragment_close_to_top.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <translate
+        android:fromYDelta="0"
+        android:toYDelta="-100%"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:duration="517" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/overlay_task_fragment_open_from_bottom.xml b/core/res/res/anim/overlay_task_fragment_open_from_bottom.xml
new file mode 100644
index 0000000..1d1223f
--- /dev/null
+++ b/core/res/res/anim/overlay_task_fragment_open_from_bottom.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <translate
+        android:fromYDelta="100%"
+        android:toYDelta="0"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:duration="517" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/overlay_task_fragment_open_from_left.xml b/core/res/res/anim/overlay_task_fragment_open_from_left.xml
new file mode 100644
index 0000000..5e5e080
--- /dev/null
+++ b/core/res/res/anim/overlay_task_fragment_open_from_left.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <translate
+        android:fromXDelta="-100%"
+        android:toXDelta="0"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:duration="517" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/overlay_task_fragment_open_from_right.xml b/core/res/res/anim/overlay_task_fragment_open_from_right.xml
new file mode 100644
index 0000000..5674ff3
--- /dev/null
+++ b/core/res/res/anim/overlay_task_fragment_open_from_right.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <translate
+        android:fromXDelta="100%"
+        android:toXDelta="0"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:duration="517" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/overlay_task_fragment_open_from_top.xml b/core/res/res/anim/overlay_task_fragment_open_from_top.xml
new file mode 100644
index 0000000..2e3dd0a
--- /dev/null
+++ b/core/res/res/anim/overlay_task_fragment_open_from_top.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2024 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <translate
+        android:fromYDelta="-100%"
+        android:toYDelta="0"
+        android:interpolator="@interpolator/fast_out_extra_slow_in"
+        android:duration="517" />
+</set>
\ No newline at end of file
diff --git a/core/res/res/drawable/notification_close_button_icon.xml b/core/res/res/drawable/notification_close_button_icon.xml
new file mode 100644
index 0000000..947cd5a
--- /dev/null
+++ b/core/res/res/drawable/notification_close_button_icon.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT 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="@dimen/notification_close_button_size"
+        android:height="@dimen/notification_close_button_size"
+        android:viewportWidth="16.0"
+        android:viewportHeight="16.0">
+<path
+    android:fillColor="#FF000000"
+    android:pathData="M 12.6667 4.2733 L 11.7267 3.3333 L 8 7.06 L 4.2734 3.3333 L 3.3334
+4.2733 L 7.06 8 L 3.3334 11.7267 L 4.2734 12.6667 L 8 8.94 L 11.7267 12.6667 L 12.6667
+11.7267 L 8.94 8 L 12.6667 4.2733 Z"/>
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/pointer_alias_vector.xml b/core/res/res/drawable/pointer_alias_vector.xml
index 035a099..60149f1 100644
--- a/core/res/res/drawable/pointer_alias_vector.xml
+++ b/core/res/res/drawable/pointer_alias_vector.xml
@@ -22,10 +22,10 @@
         android:fillColor="#00FFFFFF"
         android:pathData="M14.494 12.779a5.2 5.2 0 0 1-1.771 1.414 5.2 5.2 0 0 1-1.68.489l.81 1.658a1.968 1.968 0 0 0 3.536-1.728zM12.03 8.291l-.81-1.658a1.968 1.968 0 0 0-3.536 1.728l.896 1.833a5.2 5.2 0 0 1 1.77-1.414 5.2 5.2 0 0 1 1.68-.489" />
     <path
-        android:fillColor="#FFFFFF"
+        android:fillColor="?attr/pointerIconVectorStroke"
         android:pathData="m18.323 13.178-.975-1.995a5.2 5.2 0 0 0-1.704-1.978 5.2 5.2 0 0 0-.517-2.01L14.152 5.2a5.232 5.232 0 0 0-9.401 4.594l.975 1.995a5.2 5.2 0 0 0 1.704 1.978 5.2 5.2 0 0 0 .517 2.01l.975 1.995a5.233 5.233 0 0 0 9.401-4.594m-2.843 6.1a4.23 4.23 0 0 1-5.66-1.944l-.975-1.995a4.2 4.2 0 0 1-.431-1.838l-.001-.276-.234-.146a4.2 4.2 0 0 1-1.555-1.729L5.65 9.355a4.232 4.232 0 1 1 7.604-3.716l.975 1.995c.29.594.428 1.22.431 1.838l.001.276.234.146c.648.405 1.194.99 1.555 1.728l.975 1.995a4.234 4.234 0 0 1-1.945 5.661" />
     <path
-        android:fillColor="#FFFFFF"
+        android:fillColor="?attr/pointerIconVectorStroke"
         android:pathData="M15.313 12.177a3 3 0 0 0-.416-.633l-.459-.534-.353.609a4.2 4.2 0 0 1-1.801 1.675 4.2 4.2 0 0 1-1.977.429l-.704-.02.213.671q.066.208.164.409l.975 1.995a2.967 2.967 0 1 0 5.332-2.606zm-.827 5.066a1.97 1.97 0 0 1-2.632-.904l-.81-1.658a5.2 5.2 0 0 0 1.68-.489 5.2 5.2 0 0 0 1.771-1.414l.896 1.833a1.97 1.97 0 0 1-.905 2.632m-3.697-7.565a4.2 4.2 0 0 1 1.977-.429l.704.02-.213-.671a3 3 0 0 0-.164-.409l-.975-1.995A2.967 2.967 0 1 0 6.785 8.8l.975 1.995q.172.35.416.633l.459.534.353-.609a4.2 4.2 0 0 1 1.801-1.675m-2.21.516-.895-1.833a1.968 1.968 0 1 1 3.536-1.728l.81 1.658a5.2 5.2 0 0 0-1.68.489 5.2 5.2 0 0 0-1.771 1.414m3.151 1.965a3 3 0 0 0 1.02-.818l.755-.95-1.205.142a2.97 2.97 0 0 0-1.975 1.1l-.755.95 1.205-.142c.324-.039.646-.132.955-.282" />
     <path
         android:fillColor="?attr/pointerIconVectorFill"
diff --git a/core/res/res/drawable/pointer_all_scroll_vector.xml b/core/res/res/drawable/pointer_all_scroll_vector.xml
index 45ad98c..41314ed 100644
--- a/core/res/res/drawable/pointer_all_scroll_vector.xml
+++ b/core/res/res/drawable/pointer_all_scroll_vector.xml
@@ -24,5 +24,5 @@
         android:fillColor="?attr/pointerIconVectorFill"/>
     <path
         android:pathData="M12 4c.36 0 .72.18.93.54l1.75 3.06c.41.71-.1 1.6-.92 1.6h-.82v1.86h1.86v-.84a1.07 1.07 0 0 1 1.6-.92l3.06 1.75c.72.41.72 1.44 0 1.85l-3.06 1.76a1.07 1.07 0 0 1-1.6-.92v-.8h-1.86v1.87h.82c.82 0 1.33.88.92 1.6l-1.75 3.06a1.07 1.07 0 0 1-1.85 0L9.32 16.4c-.4-.7.1-1.6.93-1.6h.81v-1.86H9.2v.8a1.07 1.07 0 0 1-1.6.92L4.54 12.9a1.06 1.06 0 0 1 0-1.85L7.6 9.3a1.07 1.07 0 0 1 1.6.92v.85h1.86V9.2h-.82c-.81 0-1.33-.89-.92-1.6l1.76-3.06c.2-.36.56-.54.92-.54m0-1c-.74 0-1.41.39-1.79 1.04L8.45 7.1c-.18.33-.28.7-.27 1.05h-.05c-.36 0-.71.1-1.03.28l-3.06 1.76a2.05 2.05 0 0 0 0 3.58l3.06 1.75c.32.18.67.28 1.03.28h.05c-.01.38.08.76.28 1.1l1.75 3.07c.38.65 1.05 1.03 1.8 1.03s1.41-.38 1.78-1.03l1.76-3.07c.2-.34.3-.72.28-1.1h.04c.36 0 .71-.1 1.03-.28l3.06-1.75a2.07 2.07 0 0 0 0-3.58L16.9 8.43a2.07 2.07 0 0 0-1.03-.28h-.04c0-.36-.09-.72-.28-1.05L13.8 4.04A2.04 2.04 0 0 0 12 3z"
-        android:fillColor="#FFFFFF"/>
+        android:fillColor="?attr/pointerIconVectorStroke"/>
 </vector>
diff --git a/core/res/res/drawable/pointer_arrow_vector.xml b/core/res/res/drawable/pointer_arrow_vector.xml
index 2614170..a0bd5b6 100644
--- a/core/res/res/drawable/pointer_arrow_vector.xml
+++ b/core/res/res/drawable/pointer_arrow_vector.xml
@@ -24,5 +24,5 @@
         android:fillColor="?attr/pointerIconVectorFill"/>
     <path
         android:pathData="M16.94 10.38 7.37 3.22a2.77 2.77 0 0 0-2.93-.27 2.75 2.75 0 0 0-1.55 2.51l.01 11.95a2.78 2.78 0 0 0 2.82 2.8c.77 0 1.5-.32 2.03-.9l2.97-3.19a.8.8 0 0 1 .5-.25l4.34-.46a2.76 2.76 0 0 0 2.4-2.05 2.8 2.8 0 0 0-1.02-2.98zM17 13.1a1.77 1.77 0 0 1-1.55 1.31l-4.33.47a1.8 1.8 0 0 0-1.13.56l-2.97 3.2c-.4.42-.86.57-1.3.57-.24 0-.48-.05-.68-.13a1.77 1.77 0 0 1-1.14-1.67V5.46a1.81 1.81 0 0 1 1.8-1.8c.38 0 .75.11 1.07.36l9.57 7.16c.72.54.81 1.35.66 1.92z"
-        android:fillColor="#FFFFFF"/>
+        android:fillColor="?attr/pointerIconVectorStroke"/>
 </vector>
diff --git a/core/res/res/drawable/pointer_cell_vector.xml b/core/res/res/drawable/pointer_cell_vector.xml
index cead1c4..9ad64e27 100644
--- a/core/res/res/drawable/pointer_cell_vector.xml
+++ b/core/res/res/drawable/pointer_cell_vector.xml
@@ -19,7 +19,7 @@
     android:viewportHeight="24"
     android:viewportWidth="24">
     <path
-        android:fillColor="#FFFFFF"
+        android:fillColor="?attr/pointerIconVectorStroke"
         android:pathData="M19 9.667h-4.668V5a2 2 0 0 0-2-2h-.667a2 2 0 0 0-2 2v4.667H5a2 2 0 0 0-2 2v.667a2 2 0 0 0 2 2h4.665V19a2 2 0 0 0 2 2h.667a2 2 0 0 0 2-2v-4.666H19a2 2 0 0 0 2-2v-.667a2 2 0 0 0-2-2m1 2.667a1 1 0 0 1-1 1h-5.668V19a1 1 0 0 1-1 1h-.667a1 1 0 0 1-1-1v-5.666H5a1 1 0 0 1-1-1v-.667a1 1 0 0 1 1-1h5.665V5a1 1 0 0 1 1-1h.667a1 1 0 0 1 1 1v5.667H19a1 1 0 0 1 1 1z" />
     <path
         android:fillColor="?attr/pointerIconVectorFill"
diff --git a/core/res/res/drawable/pointer_context_menu_vector.xml b/core/res/res/drawable/pointer_context_menu_vector.xml
index fb2af43..33b1ace 100644
--- a/core/res/res/drawable/pointer_context_menu_vector.xml
+++ b/core/res/res/drawable/pointer_context_menu_vector.xml
@@ -19,11 +19,11 @@
     android:viewportHeight="24"
     android:viewportWidth="24">
     <group>
-        <path android:fillColor="#FFFFFF" android:pathData="M19.475 2.604h-2.66c-.842 0-1.527.685-1.527 1.527v2.66c0 .842.685 1.527 1.527 1.527h2.66c.842 0 1.527-.685 1.527-1.527v-2.66c0-.842-.685-1.527-1.527-1.527m.67 4.187c0 .37-.3.67-.67.67h-2.66a.67.67 0 0 1-.67-.67v-2.66c0-.37.3-.67.67-.67h2.66c.37 0 .67.3.67.67z" />
-        <path android:fillColor="#FFFFFF" android:pathData="M19.175 4.17h-2.067a.3.3 0 1 0 0 .6h2.067a.3.3 0 1 0 0-.6m0 .886h-2.067a.3.3 0 1 0 0 .6h2.067a.3.3 0 1 0 0-.6m0 .868h-2.067a.3.3 0 1 0 0 .6h2.067a.3.3 0 1 0 0-.6" />
+        <path android:fillColor="?attr/pointerIconVectorStroke" android:pathData="M19.475 2.604h-2.66c-.842 0-1.527.685-1.527 1.527v2.66c0 .842.685 1.527 1.527 1.527h2.66c.842 0 1.527-.685 1.527-1.527v-2.66c0-.842-.685-1.527-1.527-1.527m.67 4.187c0 .37-.3.67-.67.67h-2.66a.67.67 0 0 1-.67-.67v-2.66c0-.37.3-.67.67-.67h2.66c.37 0 .67.3.67.67z" />
+        <path android:fillColor="?attr/pointerIconVectorStroke" android:pathData="M19.175 4.17h-2.067a.3.3 0 1 0 0 .6h2.067a.3.3 0 1 0 0-.6m0 .886h-2.067a.3.3 0 1 0 0 .6h2.067a.3.3 0 1 0 0-.6m0 .868h-2.067a.3.3 0 1 0 0 .6h2.067a.3.3 0 1 0 0-.6" />
     </group>
     <path
-        android:fillColor="#FFFFFF"
+        android:fillColor="?attr/pointerIconVectorStroke"
         android:pathData="M16.938 10.38 7.372 3.216a2.77 2.77 0 0 0-2.931-.262A2.75 2.75 0 0 0 2.894 5.46l.009 11.951a2.785 2.785 0 0 0 1.776 2.604c.33.129.691.197 1.044.197a2.75 2.75 0 0 0 2.031-.897l2.969-3.193a.8.8 0 0 1 .5-.25l4.336-.467c1.397-.15 2.157-1.153 2.401-2.041a2.785 2.785 0 0 0-1.022-2.984m.058 2.718c-.157.571-.645 1.216-1.544 1.312l-4.335.467a1.8 1.8 0 0 0-1.126.563l-2.97 3.193a1.74 1.74 0 0 1-1.298.578 1.9 1.9 0 0 1-.678-.128c-.551-.217-1.141-.771-1.142-1.674l-.009-11.95c0-.697.371-1.299.994-1.611.262-.131.538-.196.813-.196.377 0 .75.123 1.072.365l9.566 7.163c.723.542.814 1.346.657 1.918" />
     <path
         android:fillColor="?attr/pointerIconVectorFill"
diff --git a/core/res/res/drawable/pointer_copy_vector.xml b/core/res/res/drawable/pointer_copy_vector.xml
index 3f13868..8ac8c21 100644
--- a/core/res/res/drawable/pointer_copy_vector.xml
+++ b/core/res/res/drawable/pointer_copy_vector.xml
@@ -23,7 +23,7 @@
         <path android:fillColor="?attr/pointerIconVectorFillInverse" android:pathData="M19.299 6H18V4.7a.5.5 0 0 0-1 0V6h-1.301a.5.5 0 0 0 0 1H17v1.3a.5.5 0 0 0 1 0V7h1.299a.5.5 0 0 0 0-1" />
     </group>
     <path
-        android:fillColor="#000000"
+        android:fillColor="?attr/pointerIconVectorStrokeInverse"
         android:pathData="M18.485 10.884v1.739q.013.189.013.38c0 3.045-2.518 5.514-5.563 5.514a5.58 5.58 0 0 1-3.922-1.613 1 1 0 0 1-.117-.106l-3.847-3.936c-.482-.494-.482-1.294 0-1.787s1.265-.494 1.747 0l.697.713V7.583a1 1 0 0 1 2 0v1.096q.463-.364.997-.625v-1.57a1 1 0 0 1 2 0v1.022q.22-.018.446-.018c.062 0 .123.007.185.009A4.4 4.4 0 0 1 13 6.5c0-.378.061-.739.149-1.09a1.97 1.97 0 0 0-1.659-.926c-.903 0-1.658.603-1.906 1.425a1.997 1.997 0 0 0-3.091 1.674v2.206a2.2 2.2 0 0 0-2.159.586 2.285 2.285 0 0 0 0 3.185l3.847 3.936q.063.061.13.118l-.001.001a6.58 6.58 0 0 0 4.624 1.902c3.586 0 6.563-2.905 6.563-6.514q-.001-.192-.013-.381v-2.108c-.316.156-.645.29-.999.37" />
     <path
         android:fillColor="#1FA54A"
diff --git a/core/res/res/drawable/pointer_crosshair_vector.xml b/core/res/res/drawable/pointer_crosshair_vector.xml
index 8a50d1b..4fba080 100644
--- a/core/res/res/drawable/pointer_crosshair_vector.xml
+++ b/core/res/res/drawable/pointer_crosshair_vector.xml
@@ -19,7 +19,7 @@
     android:viewportHeight="24"
     android:viewportWidth="24">
     <path
-        android:fillColor="#FFFFFF"
+        android:fillColor="?attr/pointerIconVectorStroke"
         android:pathData="M19.25 10.25h-5.5v-5.5a1.75 1.75 0 0 0-3.5 0v5.5h-5.5a1.75 1.75 0 0 0 0 3.5h5.5v5.5a1.75 1.75 0 0 0 3.5 0v-5.5h5.5a1.75 1.75 0 0 0 0-3.5m0 2.5h-6.5v6.5a.75.75 0 0 1-1.5 0v-6.5h-6.5a.75.75 0 0 1 0-1.5h6.5v-6.5a.75.75 0 0 1 1.5 0v6.5h6.5a.75.75 0 0 1 0 1.5" />
     <path
         android:fillType="evenOdd"
diff --git a/core/res/res/drawable/pointer_grab_vector.xml b/core/res/res/drawable/pointer_grab_vector.xml
index 48c01ce..d9e1f18 100644
--- a/core/res/res/drawable/pointer_grab_vector.xml
+++ b/core/res/res/drawable/pointer_grab_vector.xml
@@ -19,7 +19,7 @@
     android:viewportHeight="24"
     android:viewportWidth="24">
     <path
-        android:fillColor="#000000"
+        android:fillColor="?attr/pointerIconVectorStrokeInverse"
         android:pathData="M20.442 7.562a2 2 0 0 0-2-2c-.366 0-.705.106-1 .277V4.686a2 2 0 0 0-2-2 2 2 0 0 0-1.004.279 1.995 1.995 0 0 0-3.986-.06 2 2 0 0 0-1.006-.28 2 2 0 0 0-2 2v6.501l-.247-.253a2.216 2.216 0 0 0-3.178 0 2.286 2.286 0 0 0 0 3.186l5.106 5.224q.063.061.131.118l-.001.001a6.58 6.58 0 0 0 4.624 1.901c3.587 0 6.565-2.906 6.565-6.516q0-.105-.004-.21m-6.561 5.727a5.58 5.58 0 0 1-3.922-1.613 1 1 0 0 1-.117-.106l-5.106-5.224a1.286 1.286 0 0 1 0-1.788 1.215 1.215 0 0 1 1.747 0l1.962 2.008V4.625a1 1 0 0 1 2 0v5.833q.463-.362.996-.623V3a1 1 0 0 1 2 0v6.29a6 6 0 0 1 1 .011V4.686a1 1 0 0 1 2 0v5.21c.357.185.693.408 1 .663V7.562a1 1 0 0 1 2 0v7.019h.001-.001q.004.104.004.207c.001 3.046-2.518 5.516-5.564 5.516" />
     <path
         android:fillColor="?attr/pointerIconVectorFillInverse"
diff --git a/core/res/res/drawable/pointer_grabbing_vector.xml b/core/res/res/drawable/pointer_grabbing_vector.xml
index ad9f86c..7f52fc5 100644
--- a/core/res/res/drawable/pointer_grabbing_vector.xml
+++ b/core/res/res/drawable/pointer_grabbing_vector.xml
@@ -19,7 +19,7 @@
     android:viewportHeight="24"
     android:viewportWidth="24">
     <path
-        android:fillColor="#000000"
+        android:fillColor="?attr/pointerIconVectorStrokeInverse"
         android:pathData="M19.485 12.622V8.508a2 2 0 0 0-3.12-1.657 1.993 1.993 0 0 0-2.99-1.006 1.99 1.99 0 0 0-1.886-1.361c-.903 0-1.658.603-1.906 1.425a2 2 0 0 0-3.09 1.674v2.206a2.2 2.2 0 0 0-2.159.586 2.285 2.285 0 0 0 0 3.185l3.847 3.936q.063.061.13.118l-.001.001a6.58 6.58 0 0 0 4.624 1.902c3.586 0 6.563-2.905 6.563-6.514a5 5 0 0 0-.012-.381m-6.55 5.895a5.58 5.58 0 0 1-3.922-1.613 1 1 0 0 1-.117-.106l-3.847-3.936c-.482-.494-.482-1.294 0-1.787s1.265-.494 1.747 0l.697.713V7.583a1 1 0 0 1 2 0v1.096q.463-.364.997-.625v-1.57a1 1 0 0 1 2 0v1.022a5.5 5.5 0 0 1 .996.009v-.007a1 1 0 0 1 2 0v.599q.537.277 1 .66v-.259a1 1 0 0 1 2 0v4.115q.013.189.013.38c-.001 3.045-2.518 5.514-5.564 5.514" />
     <path
         android:fillColor="?attr/pointerIconVectorFillInverse"
diff --git a/core/res/res/drawable/pointer_hand_vector.xml b/core/res/res/drawable/pointer_hand_vector.xml
index a06dc08..115b53b 100644
--- a/core/res/res/drawable/pointer_hand_vector.xml
+++ b/core/res/res/drawable/pointer_hand_vector.xml
@@ -19,7 +19,7 @@
     android:viewportHeight="24"
     android:viewportWidth="24">
     <path
-        android:fillColor="#000000"
+        android:fillColor="?attr/pointerIconVectorStrokeInverse"
         android:pathData="M20.492 15.197v-4.198A1.995 1.995 0 0 0 18.5 9.001c-.413 0-.797.126-1.115.342a1.99 1.99 0 0 0-1.873-1.341c-.411 0-.792.125-1.109.339a1.99 1.99 0 0 0-1.879-1.361c-.363 0-.699.105-.992.275V3.998A1.99 1.99 0 0 0 9.542 2c-1.1 0-1.992.895-1.992 1.998v7.831l-.242-.249a2.2 2.2 0 0 0-3.164 0 2.29 2.29 0 0 0 0 3.183l5.084 5.219q.063.061.13.118l-.001.001A6.54 6.54 0 0 0 13.963 22c3.572 0 6.537-2.903 6.537-6.509q0-.148-.008-.294m-6.529 5.804a5.55 5.55 0 0 1-3.906-1.611 1 1 0 0 1-.117-.106l-5.084-5.219a1.286 1.286 0 0 1 0-1.786 1.21 1.21 0 0 1 1.74 0l1.95 2.002V3.998c0-.552.446-.999.996-.999s.996.447.996.999v7.17l.011-.007a.495.495 0 0 0 .989-.037V8.939a.992.992 0 0 1 1.984.039v.796l-.007 1.386a.5.5 0 0 0 .495.502h.003a.5.5 0 0 0 .498-.497l.006-1.157h.001V10a.997.997 0 1 1 1.991 0v.601l.004.003v1.02q.001.107.042.199a.5.5 0 0 0 .153.187l.031.021a.5.5 0 0 0 .231.083c.014.001.026.008.04.008a.5.5 0 0 0 .498-.5v-.642a.996.996 0 0 1 .993-.98c.55 0 .996.447.996.999v4.199a6 6 0 0 1 .008.293c-.001 3.043-2.509 5.51-5.542 5.51" />
     <path
         android:fillColor="?attr/pointerIconVectorFillInverse"
diff --git a/core/res/res/drawable/pointer_handwriting_vector.xml b/core/res/res/drawable/pointer_handwriting_vector.xml
index 8497592..6f62aba 100644
--- a/core/res/res/drawable/pointer_handwriting_vector.xml
+++ b/core/res/res/drawable/pointer_handwriting_vector.xml
@@ -19,8 +19,8 @@
     android:viewportHeight="24"
     android:viewportWidth="24">
     <group>
-        <path android:fillColor="#FFFFFF" android:pathData="M20.12 6.8 18.7 5.38c-.57-.57-1.32-.88-2.12-.88s-1.56.31-2.13.88l-7.16 7.16-.29.29V5c0-1.1-.9-2-2-2s-2 .9-2 2v14c0 1.1.9 2 2 2s2-.9 2-2v-.5h5.67l.29-.29 7.16-7.16c.57-.57.88-1.32.88-2.12s-.31-1.57-.88-2.13M6 19c0 .55-.45 1-1 1s-1-.45-1-1V5c0-.55.45-1 1-1s1 .45 1 1zm13.41-8.66-7.16 7.16H8v-4.25l7.16-7.16c.39-.39.9-.59 1.41-.59h.01c.51 0 1.02.2 1.41.59l1.42 1.42c.78.78.78 2.05 0 2.83" />
-        <path android:fillColor="#FFFFFF" android:pathData="m16.431 7.64-6.29 6.29 1.43 1.43 6.29-6.29-1.42-1.43z" />
+        <path android:fillColor="?attr/pointerIconVectorStroke" android:pathData="M20.12 6.8 18.7 5.38c-.57-.57-1.32-.88-2.12-.88s-1.56.31-2.13.88l-7.16 7.16-.29.29V5c0-1.1-.9-2-2-2s-2 .9-2 2v14c0 1.1.9 2 2 2s2-.9 2-2v-.5h5.67l.29-.29 7.16-7.16c.57-.57.88-1.32.88-2.12s-.31-1.57-.88-2.13M6 19c0 .55-.45 1-1 1s-1-.45-1-1V5c0-.55.45-1 1-1s1 .45 1 1zm13.41-8.66-7.16 7.16H8v-4.25l7.16-7.16c.39-.39.9-.59 1.41-.59h.01c.51 0 1.02.2 1.41.59l1.42 1.42c.78.78.78 2.05 0 2.83" />
+        <path android:fillColor="?attr/pointerIconVectorStroke" android:pathData="m16.431 7.64-6.29 6.29 1.43 1.43 6.29-6.29-1.42-1.43z" />
     </group>
     <path
         android:fillColor="?attr/pointerIconVectorFill"
diff --git a/core/res/res/drawable/pointer_help_vector.xml b/core/res/res/drawable/pointer_help_vector.xml
index 07970fb..63cf287 100644
--- a/core/res/res/drawable/pointer_help_vector.xml
+++ b/core/res/res/drawable/pointer_help_vector.xml
@@ -22,7 +22,7 @@
         android:fillColor="?attr/pointerIconVectorFill"
         android:pathData="M16.339 11.18 6.773 4.017a1.78 1.78 0 0 0-1.072-.365c-.274 0-.551.065-.813.196a1.77 1.77 0 0 0-.994 1.611l.009 11.951c0 .903.59 1.457 1.142 1.674.2.078.433.128.678.128.434 0 .906-.155 1.298-.578l2.97-3.193a1.8 1.8 0 0 1 1.126-.563l4.335-.467c.899-.097 1.387-.741 1.544-1.312.157-.573.066-1.377-.657-1.919" />
     <path
-        android:fillColor="#FFFFFF"
+        android:fillColor="?attr/pointerIconVectorStroke"
         android:pathData="M16.94 10.38 7.37 3.22a2.77 2.77 0 0 0-2.93-.27A2.75 2.75 0 0 0 2.9 5.46l.01 11.95a2.79 2.79 0 0 0 2.82 2.8c.78 0 1.5-.32 2.03-.9l2.97-3.19a.8.8 0 0 1 .5-.25l4.34-.46a2.76 2.76 0 0 0 2.4-2.05 2.8 2.8 0 0 0-1.02-2.98zM17 13.1a1.77 1.77 0 0 1-1.55 1.31l-4.33.47a1.8 1.8 0 0 0-1.13.56l-2.97 3.2c-.4.42-.86.57-1.3.57-.24 0-.48-.05-.68-.13a1.77 1.77 0 0 1-1.14-1.67V5.46a1.81 1.81 0 0 1 1.8-1.8c.38 0 .75.11 1.07.36l9.57 7.16c.72.54.81 1.35.66 1.92zm2.64-10.83a2.5 2.5 0 0 0-1.84-.72 3 3 0 0 0-2.83 1.93l-.39.94.96.37.86.32.12.05-.02.03c-.22.4-.3.82-.3 1.33v.94a1.56 1.56 0 0 0 .4 1.47 1.54 1.54 0 0 0 2.24.01 1.55 1.55 0 0 0 .28-1.84v-.52c0-.1.02-.17.03-.25l.16-.15c.32-.25.6-.56.78-.93.18-.37.26-.76.26-1.16 0-.68-.21-1.32-.7-1.82zm-1.5 5.96a.55.55 0 0 1-.82 0 .56.56 0 0 1-.17-.4c0-.16.06-.3.17-.4a.55.55 0 0 1 .41-.18c.15 0 .28.06.4.17a.55.55 0 0 1 0 .81zm1.05-3.42c-.1.22-.28.42-.52.6-.26.22-.42.42-.47.6-.05.18-.08.37-.08.57l-.93-.06c0-.38.07-.62.19-.86.13-.24.3-.46.54-.66.17-.13.3-.28.4-.43s.14-.3.14-.46c0-.2-.08-.37-.22-.5s-.31-.17-.52-.17c-.2 0-.39.06-.56.18-.17.13-.3.31-.4.56l-.87-.33a2.03 2.03 0 0 1 1.91-1.3c.48 0 .86.14 1.13.42.28.28.41.65.41 1.12 0 .26-.05.5-.15.72z" />
     <path
         android:fillColor="?attr/pointerIconVectorFill"
diff --git a/core/res/res/drawable/pointer_horizontal_double_arrow_vector.xml b/core/res/res/drawable/pointer_horizontal_double_arrow_vector.xml
index 32c56b6..7aa6571 100644
--- a/core/res/res/drawable/pointer_horizontal_double_arrow_vector.xml
+++ b/core/res/res/drawable/pointer_horizontal_double_arrow_vector.xml
@@ -19,7 +19,7 @@
     android:viewportHeight="24"
     android:viewportWidth="24">
     <path
-        android:fillColor="#FFFFFF"
+        android:fillColor="?attr/pointerIconVectorStroke"
         android:pathData="m19.963 10.185-3.065-1.758c-1.327-.761-2.96.14-3.072 1.633h-3.651c-.113-1.492-1.746-2.394-3.072-1.633l-3.065 1.758c-1.383.793-1.383 2.786 0 3.579l3.065 1.758c1.311.752 2.918-.12 3.065-1.581h3.666c.147 1.46 1.754 2.333 3.065 1.581l3.065-1.758c1.382-.793 1.382-2.786-.001-3.579m-.498 2.712L16.4 14.655a1.065 1.065 0 0 1-1.596-.922v-.791H9.195v.791c0 .818-.886 1.33-1.596.922l-3.065-1.758a1.063 1.063 0 0 1 0-1.845l3.065-1.758a1.065 1.065 0 0 1 1.596.922v.843h5.609v-.843c0-.818.886-1.33 1.596-.922l3.065 1.758a1.063 1.063 0 0 1 0 1.845" />
     <path
         android:fillColor="?attr/pointerIconVectorFill"
diff --git a/core/res/res/drawable/pointer_nodrop_vector.xml b/core/res/res/drawable/pointer_nodrop_vector.xml
index 6108e96..7cef01a 100644
--- a/core/res/res/drawable/pointer_nodrop_vector.xml
+++ b/core/res/res/drawable/pointer_nodrop_vector.xml
@@ -23,7 +23,7 @@
         <path android:fillColor="?attr/pointerIconVectorFillInverse" android:pathData="M17.5 4c-.493 0-.95.148-1.337.395l3.442 3.442C19.852 7.45 20 6.993 20 6.5 20 5.121 18.879 4 17.5 4M15 6.5C15 7.879 16.121 9 17.5 9c.525 0 1.011-.164 1.413-.441l-3.472-3.472A2.5 2.5 0 0 0 15 6.5" />
     </group>
     <path
-        android:fillColor="#000000"
+        android:fillColor="?attr/pointerIconVectorStrokeInverse"
         android:pathData="M18.485 10.932v1.69q.013.188.013.38c0 3.045-2.518 5.514-5.563 5.514a5.58 5.58 0 0 1-3.922-1.613 1 1 0 0 1-.117-.106l-3.847-3.936c-.482-.494-.482-1.294 0-1.787s1.265-.494 1.747 0l.697.713V7.583a1 1 0 0 1 2 0v1.096q.463-.364.997-.625v-1.57a1 1 0 0 1 2 0v1.022q.22-.018.446-.018c.046 0 .09.006.135.007a4.5 4.5 0 0 1-.117-.995c0-.399.068-.779.165-1.148a1.97 1.97 0 0 0-1.629-.867c-.903 0-1.658.603-1.906 1.425a2 2 0 0 0-1.091-.327 2 2 0 0 0-2 2v2.206a2.2 2.2 0 0 0-2.159.586 2.285 2.285 0 0 0 0 3.185l3.847 3.936q.063.061.13.118l-.001.001a6.58 6.58 0 0 0 4.624 1.902c3.586 0 6.563-2.905 6.563-6.514q-.001-.192-.013-.381v-2.056a4.5 4.5 0 0 1-.999.366" />
     <path
         android:fillColor="#B22A25"
diff --git a/core/res/res/drawable/pointer_text_vector.xml b/core/res/res/drawable/pointer_text_vector.xml
index a147273..2fa1332 100644
--- a/core/res/res/drawable/pointer_text_vector.xml
+++ b/core/res/res/drawable/pointer_text_vector.xml
@@ -22,6 +22,6 @@
         android:fillColor="?attr/pointerIconVectorFill"
         android:pathData="M12 3c-.551 0-1 .448-1 1v14a1.001 1.001 0 0 0 2 0V4c0-.552-.449-1-1-1" />
     <path
-        android:fillColor="#FFFFFF"
+        android:fillColor="?attr/pointerIconVectorStroke"
         android:pathData="M12 2c-1.103 0-2 .897-2 2v14c0 1.103.897 2 2 2s2-.897 2-2V4c0-1.103-.897-2-2-2m1 16a1.001 1.001 0 0 1-2 0V4a1.001 1.001 0 0 1 2 0z" />
 </vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/pointer_top_left_diagonal_double_arrow_vector.xml b/core/res/res/drawable/pointer_top_left_diagonal_double_arrow_vector.xml
index 7f95207..cd4e5e7 100644
--- a/core/res/res/drawable/pointer_top_left_diagonal_double_arrow_vector.xml
+++ b/core/res/res/drawable/pointer_top_left_diagonal_double_arrow_vector.xml
@@ -19,7 +19,7 @@
     android:viewportHeight="24"
     android:viewportWidth="24">
     <path
-        android:fillColor="#FFFFFF"
+        android:fillColor="?attr/pointerIconVectorStroke"
         android:pathData="m18.896 16.365-.924-3.41c-.398-1.467-2.169-1.985-3.305-1.035L12.08 9.333c.952-1.136.434-2.908-1.034-3.306l-3.41-.924c-1.539-.416-2.948.993-2.532 2.532l.924 3.41c.398 1.468 2.17 1.986 3.306 1.034l2.586 2.586c-.953 1.136-.435 2.91 1.033 3.307l3.41.924c1.54.417 2.949-.992 2.533-2.531m-2.27 1.566-3.41-.924a1.065 1.065 0 0 1-.476-1.781l.579-.579-3.966-3.966-.579.579a1.066 1.066 0 0 1-1.781-.476L6.07 7.373a1.063 1.063 0 0 1 1.304-1.304l3.41.924a1.065 1.065 0 0 1 .476 1.781l-.578.578 3.966 3.966.577-.577a1.066 1.066 0 0 1 1.781.477l.924 3.41a1.062 1.062 0 0 1-1.304 1.303" />
     <path
         android:fillType="evenOdd"
diff --git a/core/res/res/drawable/pointer_top_right_diagonal_double_arrow_vector.xml b/core/res/res/drawable/pointer_top_right_diagonal_double_arrow_vector.xml
index 8a33715..3736290 100644
--- a/core/res/res/drawable/pointer_top_right_diagonal_double_arrow_vector.xml
+++ b/core/res/res/drawable/pointer_top_right_diagonal_double_arrow_vector.xml
@@ -19,7 +19,7 @@
     android:viewportHeight="24"
     android:viewportWidth="24">
     <path
-        android:fillColor="#FFFFFF"
+        android:fillColor="?attr/pointerIconVectorStroke"
         android:pathData="m16.365 5.104-3.41.924c-1.468.398-1.986 2.171-1.033 3.307l-2.586 2.586c-1.136-.952-2.909-.434-3.306 1.034l-.924 3.41c-.417 1.539.992 2.948 2.531 2.531l3.41-.924c1.468-.398 1.986-2.17 1.034-3.306l2.587-2.587c1.136.951 2.908.432 3.305-1.035l.924-3.41c.415-1.538-.994-2.947-2.532-2.53m1.565 2.269-.924 3.41a1.065 1.065 0 0 1-1.781.476l-.577-.577-3.966 3.966.578.578a1.066 1.066 0 0 1-.476 1.781l-3.41.924a1.063 1.063 0 0 1-1.304-1.304l.924-3.41a1.066 1.066 0 0 1 1.781-.477l.578.578 3.966-3.966-.579-.579a1.066 1.066 0 0 1 .476-1.781l3.41-.924a1.063 1.063 0 0 1 1.304 1.305" />
     <path
         android:fillColor="?attr/pointerIconVectorFill"
diff --git a/core/res/res/drawable/pointer_vertical_double_arrow_vector.xml b/core/res/res/drawable/pointer_vertical_double_arrow_vector.xml
index 889372c..ff99f41 100644
--- a/core/res/res/drawable/pointer_vertical_double_arrow_vector.xml
+++ b/core/res/res/drawable/pointer_vertical_double_arrow_vector.xml
@@ -19,7 +19,7 @@
     android:viewportHeight="24"
     android:viewportWidth="24">
     <path
-        android:fillColor="#FFFFFF"
+        android:fillColor="?attr/pointerIconVectorStroke"
         android:pathData="M13.945 13.829V10.17c1.476-.131 2.363-1.75 1.606-3.069l-1.758-3.065c-.793-1.383-2.786-1.383-3.579 0L8.455 7.102c-.757 1.319.131 2.939 1.607 3.069v3.658c-1.477.13-2.364 1.75-1.607 3.069l1.758 3.065c.793 1.383 2.786 1.383 3.579 0l1.758-3.065c.758-1.319-.129-2.938-1.605-3.069m.739 2.572-1.758 3.065a1.063 1.063 0 0 1-1.845 0l-1.758-3.065a1.065 1.065 0 0 1 .922-1.596h.818v-5.61h-.818c-.818 0-1.33-.886-.922-1.596l1.758-3.065a1.063 1.063 0 0 1 1.845 0l1.758 3.065a1.065 1.065 0 0 1-.922 1.596h-.817v5.609h.817c.817.001 1.329.886.922 1.597" />
     <path
         android:fillColor="?attr/pointerIconVectorFill"
diff --git a/core/res/res/drawable/pointer_vertical_text_vector.xml b/core/res/res/drawable/pointer_vertical_text_vector.xml
index 9238f94..d610d04 100644
--- a/core/res/res/drawable/pointer_vertical_text_vector.xml
+++ b/core/res/res/drawable/pointer_vertical_text_vector.xml
@@ -22,6 +22,6 @@
         android:fillColor="?attr/pointerIconVectorFill"
         android:pathData="M19 11H5a1 1 0 0 0 0 2h14a1 1 0 0 0 0-2" />
     <path
-        android:fillColor="#FFFFFF"
+        android:fillColor="?attr/pointerIconVectorStroke"
         android:pathData="M19 10H5c-1.103 0-2 .897-2 2s.897 2 2 2h14c1.103 0 2-.897 2-2s-.897-2-2-2m0 3H5a1 1 0 0 1 0-2h14a1 1 0 0 1 0 2" />
 </vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/pointer_zoom_in_vector.xml b/core/res/res/drawable/pointer_zoom_in_vector.xml
index a7f56c2..c4aa95b 100644
--- a/core/res/res/drawable/pointer_zoom_in_vector.xml
+++ b/core/res/res/drawable/pointer_zoom_in_vector.xml
@@ -19,8 +19,8 @@
     android:viewportHeight="24"
     android:viewportWidth="24">
     <group>
-        <path android:fillColor="#FFFFFF" android:pathData="m20.445 17.298-3.591-3.613a7.5 7.5 0 0 0 1.243-4.138 7.547 7.547 0 1 0-7.546 7.546c1.239 0 2.402-.31 3.435-.84l3.733 3.756a1.922 1.922 0 1 0 2.726-2.711m-.713 2.009a.923.923 0 0 1-1.305-.004l-4.268-4.294a6.547 6.547 0 1 1 2.938-5.462 6.52 6.52 0 0 1-1.555 4.236l4.194 4.22a.92.92 0 0 1-.004 1.304" />
-        <path android:fillColor="#FFFFFF" android:pathData="M10.55 5a4.546 4.546 0 1 0 0 9.093 4.546 4.546 0 0 0 0-9.093m2.462 5h-2v2a.5.5 0 0 1-1 0v-2h-2a.5.5 0 0 1 0-1h2V7a.5.5 0 0 1 1 0v2h2a.5.5 0 0 1 0 1" />
+        <path android:fillColor="?attr/pointerIconVectorStroke" android:pathData="m20.445 17.298-3.591-3.613a7.5 7.5 0 0 0 1.243-4.138 7.547 7.547 0 1 0-7.546 7.546c1.239 0 2.402-.31 3.435-.84l3.733 3.756a1.922 1.922 0 1 0 2.726-2.711m-.713 2.009a.923.923 0 0 1-1.305-.004l-4.268-4.294a6.547 6.547 0 1 1 2.938-5.462 6.52 6.52 0 0 1-1.555 4.236l4.194 4.22a.92.92 0 0 1-.004 1.304" />
+        <path android:fillColor="?attr/pointerIconVectorStroke" android:pathData="M10.55 5a4.546 4.546 0 1 0 0 9.093 4.546 4.546 0 0 0 0-9.093m2.462 5h-2v2a.5.5 0 0 1-1 0v-2h-2a.5.5 0 0 1 0-1h2V7a.5.5 0 0 1 1 0v2h2a.5.5 0 0 1 0 1" />
     </group>
     <group>
         <path android:fillColor="?attr/pointerIconVectorFill" android:pathData="m19.736 18.003-4.194-4.22a6.547 6.547 0 1 0-1.382 1.226l4.268 4.294a.923.923 0 0 0 1.308-1.3m-9.186-3.91A4.546 4.546 0 1 1 10.549 5a4.546 4.546 0 0 1 .001 9.093" />
diff --git a/core/res/res/drawable/pointer_zoom_out_vector.xml b/core/res/res/drawable/pointer_zoom_out_vector.xml
index e46b978..16c4520 100644
--- a/core/res/res/drawable/pointer_zoom_out_vector.xml
+++ b/core/res/res/drawable/pointer_zoom_out_vector.xml
@@ -19,8 +19,8 @@
     android:viewportHeight="24"
     android:viewportWidth="24">
     <group>
-        <path android:fillColor="#FFFFFF" android:pathData="m20.445 17.298-3.591-3.613a7.5 7.5 0 0 0 1.243-4.138 7.547 7.547 0 1 0-7.546 7.546c1.239 0 2.402-.31 3.435-.84l3.733 3.756a1.922 1.922 0 1 0 2.726-2.711m-.713 2.009a.923.923 0 0 1-1.305-.004l-4.268-4.294a6.547 6.547 0 1 1 2.938-5.462 6.52 6.52 0 0 1-1.555 4.236l4.194 4.22a.92.92 0 0 1-.004 1.304" />
-        <path android:fillColor="#FFFFFF" android:pathData="M10.55 5a4.546 4.546 0 1 0 0 9.093 4.546 4.546 0 0 0 0-9.093m2.462 5h-5a.5.5 0 0 1 0-1h5a.5.5 0 0 1 0 1" />
+        <path android:fillColor="?attr/pointerIconVectorStroke" android:pathData="m20.445 17.298-3.591-3.613a7.5 7.5 0 0 0 1.243-4.138 7.547 7.547 0 1 0-7.546 7.546c1.239 0 2.402-.31 3.435-.84l3.733 3.756a1.922 1.922 0 1 0 2.726-2.711m-.713 2.009a.923.923 0 0 1-1.305-.004l-4.268-4.294a6.547 6.547 0 1 1 2.938-5.462 6.52 6.52 0 0 1-1.555 4.236l4.194 4.22a.92.92 0 0 1-.004 1.304" />
+        <path android:fillColor="?attr/pointerIconVectorStroke" android:pathData="M10.55 5a4.546 4.546 0 1 0 0 9.093 4.546 4.546 0 0 0 0-9.093m2.462 5h-5a.5.5 0 0 1 0-1h5a.5.5 0 0 1 0 1" />
     </group>
     <group>
         <path android:fillColor="?attr/pointerIconVectorFill" android:pathData="m19.736 18.003-4.194-4.22a6.547 6.547 0 1 0-1.382 1.226l4.268 4.294a.923.923 0 0 0 1.308-1.3m-9.186-3.91A4.546 4.546 0 1 1 10.549 5a4.546 4.546 0 0 1 .001 9.093" />
diff --git a/core/res/res/layout/accessibility_button_chooser.xml b/core/res/res/layout/accessibility_button_chooser.xml
index 2f97bae..f50af15 100644
--- a/core/res/res/layout/accessibility_button_chooser.xml
+++ b/core/res/res/layout/accessibility_button_chooser.xml
@@ -47,6 +47,16 @@
             android:paddingTop="8dp"
             android:paddingBottom="8dp"/>
 
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:id="@+id/accessibility_button_prompt"
+            android:textAppearance="?attr/textAppearanceMedium"
+            android:text="@string/accessibility_button_instructional_text"
+            android:gravity="start|center_vertical"
+            android:paddingTop="8dp"
+            android:paddingBottom="8dp"/>
+
         <GridView
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
@@ -57,16 +67,5 @@
             android:horizontalSpacing="10dp"
             android:stretchMode="columnWidth"
             android:gravity="center"/>
-
-        <TextView
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:id="@+id/accessibility_button_prompt"
-            android:textAppearance="?attr/textAppearanceMedium"
-            android:text="@string/accessibility_button_instructional_text"
-            android:gravity="start|center_vertical"
-            android:paddingTop="8dp"
-            android:paddingBottom="8dp"
-            android:visibility="gone"/>
     </LinearLayout>
 </com.android.internal.widget.ResolverDrawerLayout>
diff --git a/core/res/res/layout/notification_close_button.xml b/core/res/res/layout/notification_close_button.xml
new file mode 100644
index 0000000..5eff84e
--- /dev/null
+++ b/core/res/res/layout/notification_close_button.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<com.android.internal.widget.NotificationCloseButton
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/close_button"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="top|end"
+    android:contentDescription="@string/close_button_text"
+    android:visibility="gone"
+    android:src="@drawable/notification_close_button_icon"
+    android:padding="2dp"
+    android:scaleType="fitCenter"
+    android:importantForAccessibility="no"
+    >
+</com.android.internal.widget.NotificationCloseButton>
diff --git a/core/res/res/layout/notification_template_conversation_icon_container.xml b/core/res/res/layout/notification_template_conversation_icon_container.xml
index 0438dc5..b45483b 100644
--- a/core/res/res/layout/notification_template_conversation_icon_container.xml
+++ b/core/res/res/layout/notification_template_conversation_icon_container.xml
@@ -77,7 +77,7 @@
                 android:scaleType="center"
                 />
 
-            <com.android.internal.widget.CachingIconView
+            <com.android.internal.widget.NotificationRowIconView
                 android:id="@+id/icon"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index d80b765..565d584 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -62,7 +62,7 @@
         android:layout_height="match_parent"
         android:layout_alignParentStart="true"
         android:layout_centerVertical="true"
-        android:layout_toStartOf="@id/expand_button"
+        android:layout_toStartOf="@id/notification_buttons_column"
         android:layout_alignWithParentIfMissing="true"
         android:clipChildren="false"
         android:gravity="center_vertical"
@@ -83,11 +83,28 @@
         android:focusable="false"
         />
 
-    <include layout="@layout/notification_expand_button"
+    <LinearLayout
+        android:id="@+id/notification_buttons_column"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentEnd="true"
-        android:layout_centerVertical="true"
-        />
+        android:orientation="vertical"
+        >
+
+        <include layout="@layout/notification_close_button"
+            android:layout_width="@dimen/notification_close_button_size"
+            android:layout_height="@dimen/notification_close_button_size"
+            android:layout_gravity="end"
+            android:layout_marginEnd="20dp"
+            />
+
+        <include layout="@layout/notification_expand_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentEnd="true"
+            android:layout_centerVertical="true"
+            />
+
+    </LinearLayout>
 
 </NotificationHeaderView>
diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml
index 452df50..29f14a4 100644
--- a/core/res/res/layout/notification_template_material_base.xml
+++ b/core/res/res/layout/notification_template_material_base.xml
@@ -157,20 +157,38 @@
             android:maxDrawableHeight="@dimen/notification_right_icon_size"
             />
 
-        <FrameLayout
-            android:id="@+id/expand_button_touch_container"
+        <LinearLayout
+            android:id="@+id/notification_buttons_column"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
-            android:minWidth="@dimen/notification_content_margin_end"
+            android:layout_alignParentEnd="true"
+            android:orientation="vertical"
             >
 
-            <include layout="@layout/notification_expand_button"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical|end"
+            <include layout="@layout/notification_close_button"
+                android:layout_width="@dimen/notification_close_button_size"
+                android:layout_height="@dimen/notification_close_button_size"
+                android:layout_gravity="end"
+                android:layout_marginEnd="20dp"
                 />
 
-        </FrameLayout>
+            <FrameLayout
+                android:id="@+id/expand_button_touch_container"
+                android:layout_width="wrap_content"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:minWidth="@dimen/notification_content_margin_end"
+                >
+
+                <include layout="@layout/notification_expand_button"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_vertical|end"
+                    />
+
+            </FrameLayout>
+
+        </LinearLayout>
 
     </LinearLayout>
 
diff --git a/core/res/res/layout/notification_template_material_conversation.xml b/core/res/res/layout/notification_template_material_conversation.xml
index ce8a904..13f2c37 100644
--- a/core/res/res/layout/notification_template_material_conversation.xml
+++ b/core/res/res/layout/notification_template_material_conversation.xml
@@ -107,13 +107,20 @@
         >
         <!--expand_button_container is dynamically placed between here and at the end of the
         layout. It starts here since only FrameLayout layout params have gravity-->
-        <FrameLayout
+        <LinearLayout
             android:id="@+id/expand_button_container"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
             android:layout_gravity="end|top"
             android:clipChildren="false"
-            android:clipToPadding="false">
+            android:clipToPadding="false"
+            android:orientation="vertical">
+            <include layout="@layout/notification_close_button"
+                android:layout_width="@dimen/notification_close_button_size"
+                android:layout_height="@dimen/notification_close_button_size"
+                android:layout_gravity="end"
+                android:layout_marginEnd="20dp"
+                />
             <!--expand_button_touch_container makes sure that we can nicely center the expand
             content in the collapsed layout while the parent makes sure that we're never laid out
             bigger than the messaging content.-->
@@ -145,6 +152,6 @@
                     android:layout_gravity="center"
                     />
             </LinearLayout>
-        </FrameLayout>
+        </LinearLayout>
     </FrameLayout>
 </com.android.internal.widget.ConversationLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 0c6d49e..8aeffbe 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -484,7 +484,7 @@
     <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Laat die program toe om jou Android TV-toestel se oproeprekord te wysig, insluitend data oor inkomende en uitgaande oproepe. Kwaadwillige programme kan dit gebruik om jou oproeprekord uit te vee of te wysig."</string>
     <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Laat die program toe om jou foon se oproeprekord, insluitende data oor inkomende en uitgaande oproepe, te verander. Kwaadwillige programme kan dit gebruik om jou oproeprekord uit te vee of te verander."</string>
     <string name="permlab_bodySensors" msgid="662918578601619569">"Kry toegang tot liggaamsensordata, soos polsslag, terwyl program gebruik word"</string>
-    <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Gee die program toegang tot liggaamsensordata, soos polsslag, temperatuur en bloedsuurstofpersentasie, terwyl die program gebruik word."</string>
+    <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Gee die app toegang tot liggaamsensordata, soos polsslag, temperatuur en bloedsuurstofpersentasie, terwyl die app  gebruik word."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Kry toegang tot liggaamsensordata, soos polsslag, terwyl program op agtergrond is"</string>
     <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Gee die program toegang tot liggaamsensordata, soos polsslag, temperatuur en bloedsuurstofpersentasie, terwyl dit op die agtergrond is."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Lees kalendergebeurtenisse en -besonderhede"</string>
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Kies om draadlose ontfouting te deaktiveer."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Toetsraamwerkmodus is geaktiveer"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Voer \'n fabriekterugstelling uit om Toetsraamwerkmodus te deaktiveer."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Reekskonsole is geaktiveer"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Werkverrigting word beïnvloed. Gaan selflaaiprogram na om te deaktiveer."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimentele MTE is geaktiveer"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Het volumesleutels ingehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aangeskakel."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Het volumesleutels ingehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> is afgeskakel"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Los die volumesleutels. Druk en hou albei volumesleutels weer 3 sekondes lank in om <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aan te skakel."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Kies \'n kenmerk om te gebruik wanneer jy op die toeganklikheidknoppie tik:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Kies \'n kenmerk om te gebruik saam met die toeganklikheidgebaar (swiep met twee vingers op van die onderkant van die skerm af):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Kies \'n kenmerk om te gebruik saam met die toeganklikheidgebaar (swiep met drie vingers op van die onderkant van die skerm af):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Raak en hou die toeganklikheidknoppie om tussen kenmerke te wissel."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Swiep op met twee vingers en hou om tussen kenmerke te wissel."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Swiep op met drie vingers en hou om tussen kenmerke te wissel."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Die kenmerk sal oopmaak wanneer jy weer op die toeganklikheidknoppie tik"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Die kenmerk sal oopmaak wanneer jy weer hierdie kortpad gebruik. Swiep vanaf die onderkant van jou skerm met 2 vingers op en los vinnig."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Die kenmerk sal oopmaak wanneer jy weer hierdie kortpad gebruik. Swiep vanaf die onderkant van jou skerm met 3 vingers op en los vinnig."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Vergroting"</string>
     <string name="user_switched" msgid="7249833311585228097">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g> ."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Skakel tans oor na <xliff:g id="NAME">%1$s</xliff:g> …"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Oproep aan die gang"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Keur tans \'n inkomende oproep"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Ongekategoriseer"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promosies"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Sosiaal"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Nuus"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Aanbevelings"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Jy stel die belangrikheid van hierdie kennisgewings."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Dit is belangrik as gevolg van die mense wat betrokke is."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Gepasmaakte appkennisgewing"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Toeganklikheidkortpadkieser op skerm"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Toeganklikheidkortpad"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Maak kennisgewingskerm toe"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Kieslys"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media speel/onderbreek"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"D-paneel op"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"D-paneel af"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"D-paneel links"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Hoe dit werk"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Hangend …"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Stel Vingerafdrukslot weer op"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> het nie goed gewerk nie en is uitgevee"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> het nie goed gewerk nie en is uitgevee"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> het nie goed gewerk nie en is uitgevee. Stel dit weer op om jou foon met vingerafdruk te ontsluit."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> het nie goed gewerk nie en is uitgevee. Stel dit weer op om jou foon met jou vingerafdruk te ontsluit."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> kan nie meer herken word nie."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> kan nie meer herken word nie."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> kan nie meer herken word nie. Stel Vingerafdrukslot weer op."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> kan nie meer herken word nie. Stel Vingerafdrukslot weer op."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Stel Gesigslot weer op"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Jou gesigmodel het nie goed gewerk nie en is uitgevee. Stel dit weer op om jou foon met gesig te ontsluit."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Jou gesigmodel kan nie meer herken word nie. Stel Gesigslot weer op."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Stel op"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Nie nou nie"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm vir <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Wissel gebruiker"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Demp"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tik om klank te demp"</string>
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 39152fe..5edfe13 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ገመድ-አልባ debuggingን ለማሰናከል ይምረጡ።"</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"የሙከራ ጥቅል ሁነታ ነቅቷል"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"የመሞከሪያ ጥቅል ሁነታን ለማሰናከል የፋብሪካ ዳግም ቅንብርን ይሞክሩ።"</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"ተከታታይ ኮንሶል ነቅቷል"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"አፈጻጸም ተጽዕኖ አርፎበታል። ለማሰናከል፣ bootloader ን ይፈትሹ።"</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"የሙከራ MTE ነቅቷል።"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"የድምፅ ቁልፎችን ይዟል። <xliff:g id="SERVICE_NAME">%1$s</xliff:g> በርቷል።"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"የድምፅ ቁልፎችን ይዟል። <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ጠፍተዋል።"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"የድምጽ መጠን ቁልፎቹን ይልቀቁ። <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ን ለማብራት ሁለቱንም የድምጽ መጠን ቁልፎች በድጋሚ ለ3 ሰከንዶች ተጭነው ይያዙ።"</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"የተደራሽነት አዝራርን መታ በሚያደርጉበት ጊዜ ጥቅም ላይ የሚውለውን ባሕሪ ይምረጡ፦"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ከተደራሽነት ጣት ምልክት ጋር የሚጠቀሙበት ባሕሪ ይምረጡ (በሁለት ጣቶች ከማያ ገጹ ግርጌ ወደ ላይ ይጥረጉ)፦"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ከተደራሽነት ጣት ምልክት ጋር አብረው የሚጠቀሙበት ባሕሪ ይምረጡ (በሦስት ጣቶች ከማያ ገጹ ግርጌ ወደ ላይ ይጥረጉ)፦"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"በባሕሪያት መካከል ለመቀያየር የተደራሽነት አዝራሩን ነክተው ይያዙ።"</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"በባሕሪያት መካከል ለመቀያየር በሁለት ጣቶች ወደ ላይ ጠርገው ይያዙ።"</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"በባሕሪያት መካከል ለመቀያየር በሶስት ጣቶች ወደ ላይ ጠርገው ይያዙ።"</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"በቀጣይ ጊዜ የተደራሽነት አዝራሩን መታ ሲያደርጉ ባህሪው ይከፈታል"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"በቀጣይ ጊዜ ይህን አቋራጭ ሲመለከቱ ባህሪው ይከፈታል። ከማያ ገፅዎ ታች በ2 ጣቶች ወደላይ ያንሸራትቱ እና በፍጥነት ይልቀቁ።"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"በቀጣይ ጊዜ ይህን አቋራጭ ሲመለከቱ ባህሪው ይከፈታል። ከማያ ገፅዎ ታች ወደላይ በ3 ጣቶች ያንሸራትቱ እና ወዲያው ይልቀቁ።"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ማጉላት"</string>
     <string name="user_switched" msgid="7249833311585228097">"የአሁኑ ተጠቃሚ <xliff:g id="NAME">%1$s</xliff:g>።"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"ወደ <xliff:g id="NAME">%1$s</xliff:g> በመቀየር ላይ…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"እየተካሄደ ያለ ጥሪ"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"ገቢ ጥሪ ማጣራት"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"ያልተመደቡ"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ማስተዋወቂያዎች"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"ማህበራዊ"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"ዜና"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"ምክሮች"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"የእነዚህን ማሳወቂያዎች አስፈላጊነት አዘጋጅተዋል።"</string>
     <string name="importance_from_person" msgid="4235804979664465383">"ይሄ በሚሳተፉ ሰዎች ምክንያት አስፈላጊ ነው።"</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"ብጁ የመተግበሪያ ማሳወቂያ"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"የማያ ገፅ ላይ ተደራሽነት አቋራጭ መራጭ"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"የተደራሽነት አቋራጭ"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"የማሳወቂያ ጥላን አሰናብት"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"ምናሌ"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"ሚዲያ አጫውት/ለአፍታ አቁም"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"ከDpad በላይ"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"ከDpad በታች"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"ከDpad በስተግራ"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"እንዴት እንደሚሠራ"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"በመጠባበቅ ላይ..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"በጣት አሻራ መክፈቻን እንደገና ያዋቅሩ"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> በደንብ እየሠራ አልነበረም እና ተሰርዟል"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> እና <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> በደንብ እየሠሩ አልነበረም እና ተሰርዘዋል"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> በደንብ እየሠራ አልነበረም እና ተሰርዟል። ስልክዎን በጣት አሻራ ለመክፈት እንደገና ያዋቅሩት።"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> እና <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> በደንብ እየሠሩ አልነበረም እና ተሰርዘዋል። ስልክዎን በጣት አሻራ ለመክፈት እንደገና ያዋቅሯቸው።"</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ከእንግዲህ መለየት አይችልም።"</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> እና <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ከእንግዲህ መለየት አይችሉም።"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ከእንግዲህ መለየት አይችልም። በጣት አሻራ መክፈቻን እንደገና ያዋቅሩ።"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> እና <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ከእንግዲህ መለየት አይችሉም። በጣት አሻራ መክፈቻን እንደገና ያዋቅሩ።"</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"በመልክ መክፈትን እንደገና ያዋቅሩ"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"የእርስዎ የመልክ ሞዴል በደንብ እየሠራ አልነበረም እና ተሰርዟል። ስልክዎን በመልክ ለመክፈት እንደገና ያዋቅሩት።"</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"የመልክ ሞዴልዎ ከእንግዲህ መለየት አይችልም። በመልክ መክፈትን እንደገና ያዋቅሩ።"</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ያዋቅሩ"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"አሁን አይደለም"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"ለ<xliff:g id="USER_NAME">%s</xliff:g> ማንቂያ"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ተጠቃሚ ቀይር"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ድምፀ-ከል አድርግ"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ድምፀ-ከል አድርግ ለማድረግ መታ ያድርጉ"</string>
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 3d066d9..e0d1949 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1415,6 +1415,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"انقر لإيقاف ميزة \"تصحيح الأخطاء اللاسلكي\""</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"تم تفعيل وضع \"مفعّل الاختبار\""</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"يمكنك إجراء إعادة ضبط على الإعدادات الأصلية لإيقاف وضع \"مفعِّل اختبار\"."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"وحدة التحكّم التسلسلية مفعّلة"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"الأداء متأثر. لإيقاف وحدة التحكّم، تحقّق من برنامج الإقلاع."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"‏الميزة التجريبية إضافة وضع علامات الذاكرة (MTE) مفعّلة"</string>
@@ -1759,18 +1763,21 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"تم الضغط مع الاستمرار على مفتاحَي التحكّم في مستوى الصوت. تم تفعيل <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"تم الضغط مع الاستمرار على مفتاحَي التحكّم في مستوى الصوت. تم إيقاف <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ارفع إصبعَيك عن مفتاحَي مستوى الصوت. لتفعيل خدمة \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"، اضغط مع الاستمرار على كلا مفتاحَي مستوى الصوت مجددًا لمدة 3 ثوانٍ."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"يمكنك اختيار إحدى الميزات لاستخدامها عند النقر على زر أدوات تمكين الوصول:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"يمكنك اختيار إحدى الميزات لاستخدامها مع إيماءة أدوات تمكين الوصول (مرّر سريعًا إلى الأعلى من أسفل الشاشة باستخدام إصبعين):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"يمكنك اختيار إحدى الميزات التالية لاستخدامها مع إيماءة أدوات تمكين الوصول (مرّر سريعًا إلى الأعلى من أسفل الشاشة باستخدام ثلاثة أصابع):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"للتبديل بين الخدمات، يمكنك النقر مع الاستمرار على زر أدوات تمكين الوصول."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"للتبديل بين الخدمات، مرّر سريعًا من أسفل الشاشة إلى أعلاها باستخدام إصبعين مع تثبيتهما."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"للتبديل بين الميزات، مرّر سريعًا من أسفل الشاشة لأعلاها بثلاثة أصابع مع تثبيتها."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"سيتم فتح الميزة عند النقر على زر أدوات تسهيل الاستخدام في المرة القادمة"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"سيتم فتح الميزة عند استخدام هذا الاختصار في المرة القادمة. مرِّر سريعًا من أسفل الشاشة إلى أعلاها باستخدام إصبعَين وارفعما بعدها بسرعة."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"سيتم فتح الميزة عند استخدام هذا الاختصار في المرة القادمة. مرِّر سريعًا من أسفل الشاشة إلى أعلاها باستخدام 3 أصابع وارفع أصابعك بعدها بسرعة."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"التكبير"</string>
     <string name="user_switched" msgid="7249833311585228097">"المستخدم الحالي <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"جارٍ التبديل إلى <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"جارٍ الخروج <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="owner_name" msgid="8713560351570795743">"المالك"</string>
-    <string name="guest_name" msgid="8502103277839834324">"ضيف"</string>
+    <string name="guest_name" msgid="8502103277839834324">"وضع الضيف"</string>
     <string name="error_message_title" msgid="4082495589294631966">"خطأ"</string>
     <string name="error_message_change_not_allowed" msgid="843159705042381454">"لا يسمح المشرف بإجراء هذا التغيير"</string>
     <string name="app_not_found" msgid="3429506115332341800">"لم يتم العثور على تطبيق يمكنه التعامل مع هذا الإجراء."</string>
@@ -1980,6 +1987,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"مكالمة جارية"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"يتم فحص المكالمة الواردة"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"غير مصنفة"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"العروض الترويجية"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"التواصل الاجتماعي"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"الأخبار"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"الاقتراحات"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"لقد عيَّنت أهمية هذه الإشعارات."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"هذه الرسالة مهمة نظرًا لأهمية الأشخاص المعنيين."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"إشعار تطبيق مخصّص"</string>
@@ -2196,6 +2207,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"أداة اختيار اختصارات أدوات تمكين الوصول على الشاشة"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"اختصارات أدوات تمكين الوصول"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"إغلاق مركز الإشعارات"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"القائمة"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"تشغيل الوسائط أو إيقافها مؤقتًا"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"زرّ الاتجاه للأعلى"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"زرّ الاتجاه للأسفل"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"زرّ الاتجاه لليسار"</string>
@@ -2422,12 +2435,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"طريقة العمل"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"بانتظار الإزالة من الأرشيف…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"إعادة إعداد ميزة \"فتح الجهاز ببصمة الإصبع\""</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"هناك مشكلة في <xliff:g id="FINGERPRINT">%s</xliff:g> وتم حذفها"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"هناك مشكلة في <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> و<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> وتم حذفهما"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"هناك مشكلة في <xliff:g id="FINGERPRINT">%s</xliff:g> وتم حذفها. يُرجى إعدادها مرة أخرى لفتح قفل هاتفك باستخدام بصمة الإصبع."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"هناك مشكلة في <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> و<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> وتم حذفهما. يُرجى إعادة إعدادهما لفتح قفل هاتفك باستخدام بصمة الإصبع."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"لا يمكن بعد الآن التعرّف على \"<xliff:g id="FINGERPRINT">%s</xliff:g>\"."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"لا يمكن بعد الآن التعرّف على \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" و\"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\"."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"لا يمكن بعد الآن التعرّف على \"<xliff:g id="FINGERPRINT">%s</xliff:g>\". يجب ضبط ميزة \"فتح الجهاز ببصمة الإصبع\" مجددًا."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"لا يمكن بعد الآن التعرّف على \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" و\"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\". يجب ضبط ميزة \"فتح الجهاز ببصمة الإصبع\" مجددًا."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"إعادة إعداد ميزة \"فتح الجهاز بالتعرّف على الوجه\""</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"هناك مشكلة في نموذج الوجه الخاص بك وتم حذفه. يُرجى إعداده مرة أخرى لفتح قفل هاتفك باستخدام وجهك."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"لا يمكن بعد الآن التعرّف على نموذج الوجه الخاص بك. يجب ضبط ميزة \"فتح الجهاز بالتعرّف على الوجه\" مجددًا."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"إعداد"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"لاحقًا"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"تنبيه لـ \"<xliff:g id="USER_NAME">%s</xliff:g>\""</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"تبديل المستخدم"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"كتم الصوت"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"انقر لكتم الصوت"</string>
 </resources>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index b9c072b..b9a71b3 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -606,12 +606,12 @@
     <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"এপ্‌টোক নিকটৱৰ্তী ব্লুটুথ ডিভাইচ বিচাৰি উলিয়াবলৈ আৰু সেইসমূহৰ সৈতে পেয়াৰ কৰিবলৈ অনুমতি দিয়ে"</string>
     <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"পেয়াৰ কৰা ব্লুটুথ ডিভাইচৰ সৈতে সংযোগ কৰক"</string>
     <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"এপ্‌টোক পেয়াৰ কৰা ব্লুটুথ ডিভাইচৰ সৈতে সংযোগ কৰিবলৈ অনুমতি দিয়ে"</string>
-    <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"নিকটৱৰ্তী ব্লুটুথ ডিভাইচত বিজ্ঞাপন প্ৰচাৰ কৰা"</string>
-    <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"এপ্‌টোক নিকটৱৰ্তী ব্লুটুথ ডিভাইচত বিজ্ঞাপন প্ৰচাৰ কৰিবলৈ দিয়ে"</string>
+    <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"নিকটৱৰ্তী ব্লুটুথ ডিভাইচত বিজ্ঞাপন প্ৰচাৰাভিযান কৰা"</string>
+    <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"এপ্‌টোক নিকটৱৰ্তী ব্লুটুথ ডিভাইচত বিজ্ঞাপন প্ৰচাৰাভিযান কৰিবলৈ দিয়ে"</string>
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"নিকটৱৰ্তী আল্ট্ৰা-ৱাইডবেণ্ড ডিভাইচৰ মাজৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰক"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"এপ্‌টোক নিকটৱৰ্তী আল্ট্ৰা-ৱাইডবেণ্ড ডিভাইচসমূহৰ মাজৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰিবলৈ অনুমতি দিয়ক"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"নিকটৱৰ্তী ৱাই-ফাই ডিভাইচসমূহৰ সৈতে ভাব বিনিময় কৰক"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"এপ্‌টোক বিজ্ঞাপন প্ৰচাৰ কৰিবলৈ, সংযোগ কৰিবলৈ আৰু নিকটৱৰ্তী ৱাই-ফাই ডিভাইচৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰিবলৈ অনুমতি দিয়ে"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"এপ্‌টোক বিজ্ঞাপন প্ৰচাৰাভিযান কৰিবলৈ, সংযোগ কৰিবলৈ আৰু নিকটৱৰ্তী ৱাই-ফাই ডিভাইচৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰিবলৈ অনুমতি দিয়ে"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"অগ্ৰাধিকাৰ দিয়া NFC পৰিশোধ সেৱাৰ তথ্য"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"এপ্‌টোক অগ্ৰাধিকাৰ দিয়া nfc পৰিশোধ সেৱাৰ পঞ্জীকৃত সহায়কসমূহ আৰু পৰিশোধ কৰিব লগা লক্ষ্যস্থান দৰে তথ্য পাবলৈ অনুমতি দিয়ে।"</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"নিয়েৰ ফিল্ড কমিউনিকেশ্বন নিয়ন্ত্ৰণ কৰক"</string>
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ৱায়াৰলেচ ডি\'বাগিং অক্ষম কৰিবলৈ বাছনি কৰক।"</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"টেষ্ট হাৰনেছ ম’ড সক্ষম কৰা আছে"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"টেষ্ট হাৰনেছ ম’ড অক্ষম কৰিবলৈ ফেক্টৰী ৰিছেট কৰক।"</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"ক্ৰমিক কনছ’ল সক্ষম কৰা আছে"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"কাৰ্যক্ষমতা প্ৰভাৱিত হৈছে। অক্ষম কৰিবলৈ বুটল’ডাৰ পৰীক্ষা কৰক।"</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"পৰীক্ষামূলক MTE সক্ষম কৰা হ\'ল"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ভলিউম কীসমূহ ধৰি ৰাখক। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অন কৰা হ\'ল।"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ভলিউম কী ধৰি ৰাখিছিল। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অফ কৰা হ\'ল।"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ভলিউম কী এৰি দিয়ক। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অন কৰিবলৈ, দুয়োটা ভলিউম কী পুনৰ ৩ ছেকেণ্ডৰ বাবে টিপি হেঁচি ৰাখক।"</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"আপুনি সাধ্য-সুবিধাৰ বুটামটো টিপিলে ব্যৱহাৰ কৰিবলৈ এটা সুবিধা বাছনি কৰক:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"সাধ্য-সুবিধাৰ নির্দেশৰ জৰিয়তে ব্যৱহাৰ কৰিবলৈ এটা সুবিধা বাছনি কৰক (দুটা আঙুলিৰে স্ক্রীনখনৰ একেবাৰে তলিৰ পৰা ওপৰলৈ ছোৱাইপ কৰক):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"সাধ্য-সুবিধাৰ নির্দেশৰ জৰিয়তে ব্যৱহাৰ কৰিবলৈ এটা সুবিধা বাছনি কৰক (তিনিটা আঙুলিৰে স্ক্রীনখনৰ একেবাৰে তলিৰ পৰা ওপৰলৈ ছোৱাইপ কৰক):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"সুবিধাসমূহ সালসলনিকৈ ব্যৱহাৰ কৰিবলৈ সাধ্য-সুবিধাৰ বুটামটো স্পৰ্শ কৰি ধৰি ৰাখক।"</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"সুবিধাসমূহ সালসলনিকৈ ব্যৱহাৰ কৰিবলৈ দুটা আঙুলিৰে ওপৰলৈ ছোৱাইপ কৰি ধৰি ৰাখক।"</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"সুবিধাসমূহ সালসলনিকৈ ব্যৱহাৰ কৰিবলৈ তিনিটা আঙুলিৰে ওপৰলৈ ছোৱাইপ কৰি ধৰি ৰাখক।"</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"আপুনি ইয়াৰ পাছত সাধ্য-সুবিধা বুটামটোত টিপিলে সুবিধাটো খোল খাব"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ইয়াৰ পাছত আপুনি এই শ্বৰ্টকাটটো ব্যৱহাৰ কৰিলে সুবিধাটো খোল খাব। আপোনাৰ স্ক্ৰীনখনৰ একেবাৰে তলৰ পৰা ওপৰলৈ ২ টা আঙুলিৰে ছোৱাইপ কৰি আঙুলিকেইটা দ্ৰুতভাৱে উঠাই দিয়ক।"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ইয়াৰ পাছত আপুনি এই শ্বৰ্টকাটটো ব্যৱহাৰ কৰিলে সুবিধাটো খোল খাব। আপোনাৰ স্ক্ৰীনখনৰ একেবাৰে তলৰ পৰা ওপৰলৈ ৩ টা আঙুলিৰে ছোৱাইপ কৰি আঙুলিকেইটা দ্ৰুতভাৱে উঠাই দিয়ক।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"বিবৰ্ধন"</string>
     <string name="user_switched" msgid="7249833311585228097">"বৰ্তমানৰ ব্যৱহাৰকাৰী <xliff:g id="NAME">%1$s</xliff:g>।"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>লৈ সলনি কৰি থকা হৈছে…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"চলি থকা কল"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"এটা অন্তৰ্গামী কলৰ পৰীক্ষা কৰি থকা হৈছে"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"শ্ৰেণীবদ্ধ নকৰা"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"প্ৰমোশ্বন"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"সামাজিক"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"বাতৰি"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"চুপাৰিছ"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"এই জাননীবোৰৰ গুৰুত্ব আপুনি ছেট কৰব লাগিব।"</string>
     <string name="importance_from_person" msgid="4235804979664465383">"এই কার্যৰ সৈতে জড়িত থকা লোকসকলক ভিত্তি কৰি এইয়া গুৰুত্বপূর্ণ বুলি বিবেচনা কৰা হৈছ।"</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"কাষ্টম এপৰ জাননী"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"স্ক্ৰীনত সাধ্য সুবিধাসমূহৰ শ্বৰ্টকাট বাছনি কৰাৰ সুবিধা"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"সাধ্য সুবিধাৰ শ্বৰ্টকাট"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"জাননী পেনেল অগ্ৰাহ্য কৰক"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"মেনু"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"মিডিয়া প্লে’/পজ কৰক"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"ডিপেডৰ ওপৰফালৰ বুটাম"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"ডিপেডৰ তলফালৰ বুটাম"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"ডিপেডৰ বাওঁফালৰ বুটাম"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ই কেনেকৈ কাম কৰে"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"বিবেচনাধীন হৈ আছে..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ফিংগাৰপ্ৰিণ্ট আনলক পুনৰ ছেট আপ কৰক"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g>এ ভালদৰে কাম কৰা নাছিল আৰু সেইটো মচি পেলোৱা হৈছে"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> আৰু <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>এ ভালদৰে কাম কৰা নাছিল আৰু সেয়া মচি পেলোৱা হৈছে"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g>এ ভালদৰে কাম কৰা নাছিল আৰু সেইটো মচি পেলোৱা হৈছে। ফিংগাৰপ্ৰিণ্টৰ জৰিয়তে আপোনাৰ ফ’নটো আনলক কৰিবলৈ এইটো পুনৰ ছেট আপ কৰক।"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> আৰু <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>এ ভালদৰে কাম কৰা নাছিল আৰু সেয়া মচি পেলোৱা হৈছে। ফিংগাৰপ্ৰিণ্টৰ জৰিয়তে আপোনাৰ ফ’নটো আনলক কৰিবলৈ সেয়া পুনৰ ছেট আপ কৰক।"</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> আৰু চিনাক্ত কৰিব নোৱাৰি।"</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> আৰু <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> আৰু চিনাক্ত কৰিব নোৱাৰি।"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> আৰু চিনাক্ত কৰিব নোৱাৰি। ফিংগাৰপ্ৰিণ্ট আনলক পুনৰ ছেট আপ কৰক।"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> আৰু <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> আৰু চিনাক্ত কৰিব নোৱাৰি। ফিংগাৰপ্ৰিণ্ট আনলক পুনৰ ছেট আপ কৰক।"</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"ফে’চ আনলক পুনৰ ছেট আপ কৰক"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"আপোনাৰ মুখাৱয়বৰ মডেলটোৱে ভালদৰে কাম কৰা নাছিল আৰু সেইটো মচি পেলোৱা হৈছে। মুখাৱয়বৰ জৰিয়তে আপোনাৰ ফ’নটো আনলক কৰিবলৈ এইটো পুনৰ ছেট আপ কৰক।"</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"আপোনাৰ মুখাৱয়বৰ মডেলটো আৰু চিনাক্ত কৰিব নোৱাৰি। ফে’চ আনলক পুনৰ ছেট আপ কৰক।"</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ছেট আপ কৰক"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"এতিয়া নহয়"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>ৰ বাবে এলাৰ্ম"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ব্যৱহাৰকাৰী সলনি কৰক"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"মিউট কৰক"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ধ্বনি মিউট কৰিবলৈ টিপক"</string>
 </resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 32210f7..764780f 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"WiFi sazlamasını deaktiv etmək üçün seçin."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test Rejimi aktivdir"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Test Rejimini deaktiv etmək üçün fabrika ayarlarına sıfırlayın."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Ardıcıl konsol aktiv edildi"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Performans təsirlənir. Söndürməkçün yükləyicini yoxlayın."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimental MTE aktiv edilib"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Səs səviyyəsi düymələrinə basıb saxlayın. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktiv edildi."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Səs səviyyəsi düymələrinə basılaraq saxlanıb. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> deaktiv edilib."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Səs düymələrini buraxın. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> xidmətini aktiv etmək üçün hər iki səs düyməsinə yenidən 3 saniyə basıb saxlayın."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Xüsusi imkanlar düyməsinə toxunanda istədiyiniz funksiyanı seçin:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Əlçatımlılıq jesti (iki barmağınızla ekranın aşağısından yuxarı doğru sürüşdürün) ilə istifadə edəcəyiniz funksiyanı seçin:"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Əlçatımlılıq jesti (üç barmağınızla ekranın aşağısından yuxarı doğru sürüşdürün) ilə istifadə edəcəyiniz funksiyanı seçin:"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Funksiyalar arasında keçid etmək üçün xüsusi imkanlar düyməsini basıb saxlayın."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Funksiyalar arasında keçid etmək üçün iki barmağınızla yuxarı sürüşdürüb saxlayın."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Funksiyalar arasında keçid etmək üçün üç barmağınızla yuxarı doğru sürüşdürüb saxlayın."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Növbəti dəfə xüsusi imkanlar düyməsinə toxunduğunuz zaman funksiya açılacaq"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Növbəti dəfə bu qısayoldan istifadə etdiyiniz zaman funksiya açılacaq. Ekranın aşağısından 2 barmaq ilə yuxarı çəkin və tez buraxın."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Növbəti dəfə bu qısayoldan istifadə etdiyiniz zaman funksiya açılacaq. Ekranın aşağısından 3 barmaq ilə yuxarı çəkin və tez buraxın."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Böyütmə"</string>
     <string name="user_switched" msgid="7249833311585228097">"Cari istifadəçi <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> adına keçirilir…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Davam edən zəng"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Gələn zəng göstərilir"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Kateqoriyasız"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Tanıtımlar"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Sosial"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Xəbərlər"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Tövsiyələr"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Bildirişlərin əhəmiyyətini Siz ayarlaryırsınız."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"İnsanlar cəlb olunduğu üçün bu vacibdir."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Fərdi tətbiq bildirişi"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekranda Əlçatımlılıq Qısayolu Seçicisi"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Əlçatımlılıq Qısayolu"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Bildiriş Göstərişini qapadın"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menyu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Medianı oxudun/durdurun"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad Yuxarı"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad Aşağı"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad Sola"</string>
@@ -2411,19 +2424,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Şəxsi sahə"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"Həssas bildiriş kontenti gizlədildi"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Güvənlik üçün tətbiq kontenti ekran paylaşımından gizlədildi"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Tətbiq kontenti güvənlik məsələlərinə görə ekran paylaşımından gizlədildi"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"Peykə avtomatik qoşulub"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Mobil və ya Wi-Fi şəbəkəsi olmadan mesaj göndərə və qəbul edə bilərsiniz"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Mesajı açın"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Haqqında"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Gözləmədə..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Barmaqla Kilidaçmanı yenidən ayarlayın"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> yaxşı işləmirdi və silindi"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> və <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> yaxşı işləmirdi və silindi"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> yaxşı işləmirdi və silindi. Telefonu barmaq izi ilə kiliddən çıxarmaq üçün onu yenidən ayarlayın."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> və <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> yaxşı işləmirdi və silindi. Telefonu barmaq izi ilə kiliddən çıxarmaq üçün onları yenidən ayarlayın."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> artıq tanınmır."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> və <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> artıq tanınmır."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> artıq tanınmır. Barmaqla Kilidaçmanı yenidən ayarlayın."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> və <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> artıq tanınmır. Barmaqla Kilidaçmanı yenidən ayarlayın."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Üzlə Kilidaçmanı yenidən ayarlayın"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Üz modeliniz yaxşı işləmirdi və silindi. Telefonu üzlə kiliddən çıxarmaq üçün onu yenidən ayarlayın."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Üz modeliniz artıq tanınmır. Üzlə Kilidaçmanı yenidən ayarlayın."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Ayarlayın"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"İndi yox"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> üçün alarm"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"İstifadəçini dəyişin"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Susdurun"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Susdurmaq üçün toxunun"</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 ac01883..aad68d3 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -517,11 +517,11 @@
     <string name="permlab_activityRecognition" msgid="1782303296053990884">"prepoznavanje fizičkih aktivnosti"</string>
     <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Ova aplikacija može da prepozna fizičke aktivnosti."</string>
     <string name="permlab_camera" msgid="6320282492904119413">"snimanje fotografija i videa"</string>
-    <string name="permdesc_camera" msgid="5240801376168647151">"Ova aplikacija može da snima slike i video snimke pomoću kamere dok se aplikacija koristi."</string>
-    <string name="permlab_backgroundCamera" msgid="7549917926079731681">"da snima slike i video snimke u pozadini"</string>
+    <string name="permdesc_camera" msgid="5240801376168647151">"Ova aplikacija može da snima slike i video pomoću kamere dok se aplikacija koristi."</string>
+    <string name="permlab_backgroundCamera" msgid="7549917926079731681">"da snima slike i video u pozadini"</string>
     <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Ova aplikacija može da snima fotografije i video snimke pomoću kamere u bilo kom trenutku."</string>
     <string name="permlab_systemCamera" msgid="3642917457796210580">"Dozvolite nekoj aplikaciji ili usluzi da pristupa kamerama sistema da bi snimala slike i video snimke"</string>
-    <string name="permdesc_systemCamera" msgid="5938360914419175986">"Ova privilegovana sistemska aplikacija može da snima slike i video snimke pomoću kamere sistema u bilo kom trenutku. Aplikacija treba da ima i dozvolu android.permission.CAMERA"</string>
+    <string name="permdesc_systemCamera" msgid="5938360914419175986">"Ova privilegovana sistemska aplikacija može da snima slike i video pomoću kamere sistema u bilo kom trenutku. Aplikacija treba da ima i dozvolu android.permission.CAMERA"</string>
     <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Dozvolite aplikaciji ili usluzi da dobija povratne pozive o otvaranju ili zatvaranju uređaja sa kamerom."</string>
     <string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"Ova aplikacija može da dobija povratne pozive kada se bilo koji uređaj sa kamerom otvara ili zatvara (pomoću neke aplikacije)."</string>
     <string name="permlab_cameraHeadlessSystemUser" msgid="680194666834500050">"Dozvolite aplikaciji ili usluzi da pristupa kameri kao korisnik sistema bez grafičkog korisničkog interfejsa."</string>
@@ -1412,6 +1412,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Izaberite da biste onemogućili bežično otklanjanje grešaka."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Omogućen je režim probnog korišćenja"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Obavite resetovanje na fabrička podešavanja da biste onemogućili režim probnog korišćenja."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Serijska konzola je omogućena"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Performanse su smanjene. Da biste onemogući konzolu, proverite pokretački program."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimentalni MTE je omogućen"</string>
@@ -1756,12 +1760,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Pustite tastere za jačinu zvuka. Da biste uključili <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ponovo pritisnite i zadržite oba tastera za jačinu zvuka 3 sekunde."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Izaberite funkciju koja će se koristiti kada dodirnete dugme Pristupačnost:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Odaberite funkciju koja će se koristiti pomoću pokreta za pristupačnost (pomoću dva prsta prevucite nagore od dna ekrana):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Odaberite funkciju koja će se koristiti pomoću pokreta za pristupačnost (pomoću tri prsta prevucite nagore od dna ekrana):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Da biste prelazili sa jedne funkcije na drugu, dodirnite i zadržite dugme Pristupačnost."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Da biste prelazili sa jedne funkcije na drugu, prevucite nagore pomoću dva prsta i zadržite."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Da biste prelazili sa jedne funkcije na drugu, prevucite nagore pomoću tri prsta i zadržite."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funkcija će se otvoriti kada sledeći put dodirnete dugme Pristupačnost"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkcija će se otvoriti kada sledeći put budete koristili ovu prečicu. Prevucite nagore od dna ekrana sa 2 prsta i brzo pustite."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcija će se otvoriti kada sledeći put budete koristili ovu prečicu. Prevucite nagore od dna ekrana sa 3 prsta i brzo pustite."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Uvećanje"</string>
     <string name="user_switched" msgid="7249833311585228097">"Aktuelni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1984,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Poziv je u toku"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Proverava se dolazni poziv"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Nekategorizovano"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promocije"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Društvene mreže"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Vesti"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Preporuke"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Vi podešavate važnost ovih obaveštenja."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Ovo je važno zbog ljudi koji učestvuju."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Prilagođeno obaveštenje o aplikaciji"</string>
@@ -2193,6 +2204,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Alatka za biranje prečica za pristupačnost na ekranu"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Prečica za pristupačnost"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Odbaci traku sa obaveštenjima"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Meni"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Pusti/pauziraj medije"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"nagore na D-pad-u"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"nadole na D-pad-u"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"nalevo na D-pad-u"</string>
@@ -2419,12 +2432,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Princip rada"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Na čekanju..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ponovo podesite otključavanje otiskom prsta"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> nije funkcionisao i izbrisali smo ga"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nisu funkcionisali i izbrisali smo ih"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> nije funkcionisao i izbrisali smo ga. Ponovo ga podesite da biste telefon otključavali otiskom prsta."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nisu funkcionisali i izbrisali smo ih. Ponovo ih podesite da biste telefon otključavali otiskom prsta."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> više ne može da se prepozna."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> više ne mogu da se prepoznaju."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> više ne može da se prepozna. Ponovo podesite otključavanje otiskom prsta."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> više ne mogu da se prepoznaju. Ponovo podesite otključavanje otiskom prsta."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Ponovo podesite otključavanje licem"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Vaš model lica nije funkcionisao i izbrisali smo ga. Ponovo ga podesite da biste telefon otključavali licem."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Vaš model lica više ne može da se prepozna. Ponovo podesite otključavanje licem."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Podesi"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne sada"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm za: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Promeni korisnika"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Isključi zvuk"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Dodirnite da biste isključili zvuk"</string>
 </resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index cbcc90a..993457f 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1413,6 +1413,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Выберыце, каб выключыць адладку па Wi-Fi."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Тэставы рэжым уключаны"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Каб выключыць тэставы рэжым, скіньце налады да заводскіх значэнняў."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Паслядоўная кансоль уключана"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Паказчык прадукцыйнасці змяніўся. Каб выключыць кансоль, праверце загрузчык."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Эксперыментальнае пашырэнне тэгаў памяці (MTE) уключана"</string>
@@ -1757,12 +1761,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Клавішы гучнасці ўтрымліваліся націснутымі. Уключана служба \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Клавішы гучнасці ўтрымліваліся націснутымі. Служба \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" выключана."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Адпусціце клавішы гучнасці. Каб уключыць сэрвіс \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\", націсніце абедзве клавішы гучнасці яшчэ раз і ўтрымлівайце іх на працягу 3 секунд."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Выберыце функцыю, якую будзеце выкарыстоўваць пры націску кнопкі спецыяльных магчымасцей:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Выберыце функцыю, якую будзеце выкарыстоўваць з жэстам спецыяльных магчымасцей (правесці двума пальцамі па экране знізу ўверх):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Выберыце функцыю, якую будзеце выкарыстоўваць з жэстам спецыяльных магчымасцей (правесці трыма пальцамі па экране знізу ўверх):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Каб пераключыцца на іншыя функцыі, націсніце і ўтрымлівайце кнопку спецыяльных магчымасцей."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Каб пераключыцца на іншую функцыю, правядзіце ўверх двума пальцамі і ўтрымлівайце іх на экране."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Каб пераключыцца на іншую функцыю, правядзіце ўверх трыма пальцамі і ўтрымлівайце іх на экране."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Функцыя адкрыецца, калі вы наступным разам націснеце на кнопку спецыяльных магчымасцей"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Функцыя адкрыецца, калі вы наступным разам выкарыстаеце гэты хуткі доступ. Правядзіце двума пальцамі ад нізу экрана ўверх і хутка адпусціце."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Функцыя адкрыецца, калі вы наступным разам выкарыстаеце гэты хуткі доступ. Правядзіце трыма пальцамі ад нізу экрана ўверх і хутка адпусціце."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Павелічэнне"</string>
     <string name="user_switched" msgid="7249833311585228097">"Бягучы карыстальнік <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Пераход у рэжым \"<xliff:g id="NAME">%1$s</xliff:g>\"..."</string>
@@ -1978,6 +1985,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Бягучы выклік"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Фільтраванне ўваходнага выкліку"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Некатэгарызаванае"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Прома-акцыі"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Сацыяльныя сеткі"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Навіны"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Рэкамендацыі"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Вы задалі важнасць гэтых апавяшчэнняў."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Гэта важна, бо з гэтым звязаны пэўныя людзі."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Апавяшчэнне пра карыстальніцкую праграму"</string>
@@ -2194,6 +2205,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Налада хуткага доступу да спецыяльных магчымасцей на экране"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Хуткі доступ"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Закрыць шчыток апавяшчэнняў"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Меню"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Прайграць або прыпыніць медыяфайл"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Уверх на панэлі кіравання"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Уніз на панэлі кіравання"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Улева на панэлі кіравання"</string>
@@ -2420,12 +2433,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Як гэта працуе"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"У чаканні..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Наладзіць разблакіроўку адбіткам пальца паўторна"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Адбітак пальца \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" не працаваў належным чынам і быў выдалены"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Адбіткі пальцаў \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" і \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" не працавалі належным чынам і былі выдалены"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Адбітак пальца \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" не працаваў належным чынам і быў выдалены. Каб мець магчымасць разблакіраваць тэлефон з дапамогай адбітка пальца, наладзьце яго яшчэ раз."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Адбіткі пальцаў \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" і \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" не працавалі належным чынам і былі выдалены. Каб мець магчымасць разблакіраваць тэлефон з дапамогай адбітка пальца, наладзьце іх яшчэ раз."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Адбітак пальца \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" больш не можа быць распазнаны."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Адбіткі пальцаў \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" і \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" больш не могуць быць распазнаны."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Адбітак пальца \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" больш не можа быць распазнаны. Паўторна наладзьце разблакіроўку адбіткам пальца."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Адбіткі пальцаў \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" і \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" больш не могуць быць распазнаны. Паўторна наладзьце разблакіроўку адбіткам пальца."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Паўторна наладзьце распазнаванне твару"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Мадэль твару не працавала належным чынам і была выдалена. Каб мець магчымасць разблакіраваць тэлефон з дапамогай распазнавання твару, наладзьце яго яшчэ раз."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Мадэль твару больш не можа быць распазнана. Паўторна наладзьце распазнаванне твару."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Наладзіць"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не зараз"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Будзільнік карыстальніка <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Змяніць карыстальніка"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Выключыць гук"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Націсніце, каб выключыць гук"</string>
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index affa311..3360025 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Изберете, за да деактивирате безжичното отстраняване на грешки."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Режимът за тестова среда е активиран"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Възстановете фабричните настройки, за да деактивирате режима за тестова среда."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Серийната конзола е активирана"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Ефективността е засегната. За да деактивирате, проверете програмата за първоначално зареждане."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Експерименталното разширение MTE е активирано"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Задържахте бутоните за силата на звука. Услугата <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е включена."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Задържахте бутоните за силата на звука. Услугата <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е изключена."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Освободете бутоните за силата на звука. За да включите <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, отново натиснете двата бутона за силата на звука и задръжте за 3 секунди."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Изберете функция, която да използвате, когато докоснете бутона за достъпност:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Изберете коя функция да се използва с жеста за достъпност (прекарване на два пръста нагоре от долната част на екрана):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Изберете коя функция да се използва с жеста за достъпност (прекарване на три пръста нагоре от долната част на екрана):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"За превключване между функциите докоснете и задръжте бутона за достъпност."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"За превключване между функциите прекарайте два пръста нагоре и задръжте."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"За превключване между функциите прекарайте три пръста нагоре и задръжте."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Функцията ще се отвори при следващото докосване бутона за достъпност"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Функцията ще се отвори при следващото използване на този пряк път. Прекарайте 2 пръста нагоре от долната част на екрана и бързо освободете."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Функцията ще се отвори при следващото използване на този пряк път. Прекарайте 3 пръста нагоре от долната част на екрана и бързо освободете."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Увеличение"</string>
     <string name="user_switched" msgid="7249833311585228097">"Текущ потребител <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Превключва се към: <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Текущо обаждане"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Преглежда се входящо обаждане"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Некатегоризирани"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Промоции"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Социални мрежи"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Новини"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Препоръки"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Зададохте важността на тези известия."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Това е важно заради участващите хора."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Персонализирано известие за приложение"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Инструмент за избор на пряк път към достъпността на екрана"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Пряк път за достъпност"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Отхвърляне на падащия панел с известия"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Меню"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Пускане/пауза на мултимедията"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Контролен пад – горе"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Контролен пад – долу"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Контролен пад – ляво"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Начин на работа"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Изчаква..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Повторно настройване на „Отключване с отпечатък“"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Отпечатъкът „<xliff:g id="FINGERPRINT">%s</xliff:g>“ бе изтрит, защото не работеше добре"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Отпечатъците „<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>“ и „<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>“ бяха изтрити, защото не работеха добре"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Отпечатъкът „<xliff:g id="FINGERPRINT">%s</xliff:g>“ бе изтрит, защото не работеше добре. Настройте го отново, за да отключвате телефона си с отпечатък."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Отпечатъците „<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>“ и „<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>“ бяха изтрити, защото не работеха добре. Настройте ги отново, за да отключвате телефона си с отпечатък."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> вече не може да се разпознае."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> вече не могат да бъдат разпознати."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> вече не може да се разпознае. Настройте отново „Отключване с отпечатък“."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> вече не могат да бъдат разпознати. Настройте отново „Отключване с отпечатък“."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Повторно настройване на „Отключване с лице“"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Моделът на лицето ви бе изтрит, защото не работеше добре. Настройте го отново, за да отключвате телефона си с лице."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Моделът на лицето ви вече не може да бъде разпознат. Настройте отново „Отключване с лице“."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Настройване"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не сега"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Будилник за <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Смяна на потребителя"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Спиране на звука"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Докоснете, за да спрете звука"</string>
 </resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 889de67..1a7fc6b 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ওয়্যারলেস ডিবাগিং বন্ধ করতে বেছে নিন।"</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"টেস্ট হারনেস মোড চালু আছে"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"টেস্ট হারনেস মোড বন্ধ করতে ফ্যাক্টরি রিসেট করুন।"</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"সিরিয়াল কনসোল চালু করা হয়েছে"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"পারফর্ম্যান্সে এর প্রভাব পড়বে। চালানো বন্ধ করতে \'বুটলোডার\' প্রোগ্রামে এটিকে চেক করে দেখুন।"</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"পরীক্ষামূলক MTE চালু আছে"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ভলিউম কী ধরে ছিলেন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> চালু করা হয়েছে।"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ভলিউম কী ধরে ছিলেন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> বন্ধ করা হয়েছে।"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ভলিউম \'কী\' রিলিজ করুন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> চালু করুন, দু\'টি ভলিউম \'কী\' আবার প্রেস করে ৩ সেকেন্ড ধরে রাখুন।"</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"অ্যাক্সেসিবিলিটি বোতামে ট্যাপ করে আপনি যে ফিচার ব্যবহার করতে চান সেটি বেছে নিন:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"অ্যাক্সেসিবিলিটি জেসচারের (দুটি আঙ্গুল দিয়ে স্ক্রিনের নিচে থেকে উপরের দিকে সোয়াইপ করুন) সাহায্যে আপনি যে ফিচার ব্যবহার করতে চান সেটি বেছে নিন:"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"অ্যাক্সেসিবিলিটি জেসচারের (তিনটি আঙ্গুল দিয়ে স্ক্রিনের নিচে থেকে উপরের দিকে সোয়াইপ করুন) সাহায্যে আপনি যে ফিচার ব্যবহার করতে চান সেটি বেছে নিন:"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"একটি ফিচার থেকে অন্যটিতে যেতে অ্যাক্সেসিবিলিটি বোতাম টাচ করে ধরে থাকুন।"</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"একটি ফিচার থেকে অন্যটিতে যেতে, দুটি আঙ্গুল দিয়ে নিচে থেকে উপরের দিকে সোয়াইপ করে ধরে থাকুন।"</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"একটি ফিচার থেকে অন্যটিতে যেতে, তিনটি আঙ্গুল দিয়ে উপরের দিকে সোয়াইপ করে ধরে থাকুন।"</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"পরের বার অ্যাক্সেসিবিলিটি বোতামে ট্যাপ করলে, ফিচারটি চালু হয়ে যাবে"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"পরের বার এই শর্টকাট ব্যবহার করলে, ফিচারটি চালু হয়ে যাবে। ২টি আঙ্গুল দিয়ে স্ক্রিনের নিচ থেকে উপরের দিকে সোয়াইপ করে দ্রুত ছেড়ে দিন।"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"পরের বার এই শর্টকাট ব্যবহার করলে, ফিচারটি চালু হয়ে যাবে। ৩টি আঙ্গুল দিয়ে স্ক্রিনের নিচ থেকে উপরের দিকে সোয়াইপ করে দ্রুত ছেড়ে দিন।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"বড় করে দেখা"</string>
     <string name="user_switched" msgid="7249833311585228097">"বর্তমান ব্যবহারকারী <xliff:g id="NAME">%1$s</xliff:g>৷"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> প্রোফাইলে পাল্টানো হচ্ছে…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"চালু থাকা কল"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"ইনকামিং কল স্ক্রিনিং করা হচ্ছে"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"বিভাগ নির্ধারিত নয়"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"প্রোমোশন"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"সোশ্যাল"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"খবর"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"সাজেশন"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"আপনি এই বিজ্ঞপ্তিগুলির গুরুত্ব সেট করেছেন।"</string>
     <string name="importance_from_person" msgid="4235804979664465383">"লোকজন জড়িত থাকার কারণে এটি গুরুত্বপূর্ণ।"</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"কাস্টম অ্যাপ বিজ্ঞপ্তি"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"অন-স্ক্রিন অ্যাক্সেসিবিলিটি শর্টকাট বেছে নেওয়ার বিকল্প"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"অ্যাক্সেসিবিলিটি শর্টকাট"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"বিজ্ঞপ্তি শেড বাতিল করুন"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"মেনু"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"মিডিয়া প্লে/পজ করুন"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"ডিপ্যাড (Dpad)-এর উপরে"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"ডিপ্যাড (Dpad)-এর নিচে"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"ডিপ্যাড (Dpad)-এর বাঁদিকে"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"এটি কীভাবে কাজ করে"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"বাকি আছে…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"\'ফিঙ্গারপ্রিন্ট আনলক\' আবার সেট-আপ করুন"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ভালোভাবে কাজ করছিল না এবং সেটি মুছে ফেলা হয়েছে"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ও <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ভালোভাবে কাজ করছিল না এবং মুছে ফেলা হয়েছে"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ভালোভাবে কাজ করছিল না বলে সেটি মুছে ফেলা হয়েছে। ফিঙ্গারপ্রিন্ট ব্যবহার করে আপনার ফোন আনলক করতে হলে এটি আবার সেট-আপ করুন।"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ও <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ভালোভাবে কাজ করছিল না বলে মুছে ফেলা হয়েছে। ফিঙ্গারপ্রিন্ট ব্যবহার করে আপনার ফোন আনলক করতে হলে সেগুলি আবার সেট-আপ করুন।"</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> আর শনাক্ত করা যাবে না।"</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ও <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> আর শনাক্ত করা যাবে না।"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> আর শনাক্ত করা যাবে না। ফিঙ্গারপ্রিন্ট আনলক আবার সেট-আপ করুন।"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ও <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> আর শনাক্ত করা যাবে না। ফিঙ্গারপ্রিন্ট আনলক আবার সেট-আপ করুন।"</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"\'ফেস আনলক\' আবার সেট-আপ করুন"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"আপনার ফেস মডেল ভালোভাবে কাজ করছিল না বলে সেটি মুছে ফেলা হয়েছে। ফেস ব্যবহার করে আপনার ফোন আনলক করতে হলে এটি আবার সেট-আপ করুন।"</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"আপনার ফেস মডেল আর শনাক্ত করা যাবে না। ফেস আনলক আবার সেট-আপ করুন।"</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"সেট-আপ করুন"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"এখন নয়"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>-এর জন্য অ্যালার্ম"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ব্যবহারকারী পাল্টান"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"মিউট করুন"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"সাউন্ড মিউট করতে ট্যাপ করুন"</string>
 </resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index af9ac56..37bb750 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -1412,6 +1412,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Odaberite da onemogućite bežično otklanjanje grešaka."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Omogućen način rada okvira za testiranje"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Izvršite vraćanje na fabričke postavke da onemogućite način rada okvira za testiranje."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Serijska konzola omogućena"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Performanse su smanjene. Da onemogućite, provjerite program za učitavanje operativnog sistema."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimentalni MTE je omogućen"</string>
@@ -1756,12 +1760,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Pustite tipke za jačinu zvuka. Da uključite uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ponovo pritisnite i zadržite obje tipke za jačinu zvuka 3 sekunde."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Odaberite funkciju koja će se koristiti kada dodirnete dugme Pristupačnost:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Odaberite funkciju koju ćete koristiti kada izvedete pokret za pristupačnost (s dva prsta prevucite prema gore s dna ekrana):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Odaberite funkciju koju ćete koristiti kada izvedete pokret za pristupačnost (s tri prsta prevucite prema gore s dna ekrana):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Za prebacivanje između funkcija, dodirnite i zadržite dugme Pristupačnost."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Da prebacujete između funkcija, s dva prsta prevucite prema gore i zadržite."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Da prebacujete između funkcija, s tri prsta prevucite prema gore i zadržite."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funkcija će se otvoriti sljedeći put kada dodirnete dugme za pristupačnost"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkcija će se otvoriti sljedeći put kada upotrijebite ovu prečicu. Prevucite s 2 prsta s dna ekrana i brzo pustite."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcija će se otvoriti sljedeći put kada upotrijebite ovu prečicu. Prevucite s 3 prsta s dna ekrana i brzo pustite."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Uvećavanje"</string>
     <string name="user_switched" msgid="7249833311585228097">"Trenutni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>..."</string>
@@ -1977,6 +1984,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Poziv u toku"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtriranje dolaznog poziva"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Nije kategorizirano"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promocije"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Društveni mediji"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Vijesti"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Preporuke"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Vi određujete značaj ovih obavještenja."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Ovo je značajno zbog osoba koje su uključene."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Prilagođeno obavještenje aplikacije"</string>
@@ -2193,6 +2204,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Okvir za odabir prečice za pristupačnost na ekranu"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Prečica za pristupačnost"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Odbacite lokaciju za obavještenja"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Meni"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Reprodukcija/pauziranje medijskog sadržaja"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Upravljač gore"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Upravljač dolje"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Upravljač lijevo"</string>
@@ -2419,12 +2432,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako ovo funkcionira"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Na čekanju…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ponovo postavite otključavanje otiskom prsta"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Otisak prsta <xliff:g id="FINGERPRINT">%s</xliff:g> nije dobro funkcionirao, pa je izbrisan"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Otisci prstiju <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nisu dobro funkcionirali, pa su izbrisani"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Otisak prsta <xliff:g id="FINGERPRINT">%s</xliff:g> nije dobro funkcionirao, pa je izbrisan. Postavite ga ponovo da otključavate telefon otiskom prsta."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Otisci prstiju <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nisu dobro funkcionirali, pa su izbrisani. Postavite ih ponovo da otključavate telefon otiskom prsta."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> se više ne može prepoznati."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> se više ne mogu prepoznati."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> se više ne može prepoznati. Ponovo postavite otključavanje otiskom prsta."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> se više ne mogu prepoznati. Ponovo postavite otključavanje otiskom prsta."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Ponovo postavite otključavanje licem"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Model lica nije dobro funkcionirao, pa je izbrisan. Postavite ga ponovo da otključavate telefon licem."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Vaš model lica se više ne može prepoznati. Ponovo postavite otključavanje licem."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Postavite"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne sada"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm za: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Prebaci na drugog korisnika"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Isključi zvuk"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Dodirnite da isključite zvuk"</string>
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 66c81e6..fa10e45 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -157,7 +157,7 @@
     <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"Seguretat de xarxes mòbils"</string>
     <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"Encriptació, notificacions de xarxes sense encriptació"</string>
     <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"S\'ha accedit a l\'identificador de dispositiu"</string>
-    <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"A les <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, una xarxa propera ha registrat l\'identificador únic del teu dispositiu (IMSI or IMEI) mentre s\'utilitzava la SIM de <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>"</string>
+    <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"A les <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, una xarxa propera ha registrat l\'ID únic del dispositiu (IMSI or IMEI) amb la SIM de <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>"</string>
     <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"A les <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, una xarxa propera ha registrat l\'identificador únic del teu dispositiu (IMSI or IMEI) mentre s\'utilitzava la SIM de <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>.\n\nAixò vol dir que s\'han registrat la teva ubicació, activitat o identitat. Tot i ser una pràctica habitual, pot suposar un problema per a aquelles persones preocupades per la privadesa."</string>
     <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"T\'has connectat a la xarxa encriptada <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string>
     <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"La connexió SIM de <xliff:g id="NETWORK_NAME">%1$s</xliff:g> ara és més segura"</string>
@@ -1412,6 +1412,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecciona per desactivar la depuració sense fil."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"S\'ha activat el mode Agent de prova"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Si vols desactivar el mode Agent de prova, restableix les dades de fàbrica."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"S\'ha activat la consola de sèrie"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Afecta el rendiment. Per desactivar-la, comprova el bootloader."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"L\'MTE experimental s\'ha activat"</string>
@@ -1756,12 +1760,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"S\'han mantingut premudes les tecles de volum. S\'ha activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"S\'han mantingut premudes les tecles de volum. S\'ha desactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Deixa anar les tecles de volum. Per activar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, torna a mantenir premudes totes dues tecles de volum durant 3 segons."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Tria la funció que vols utilitzar quan toquis el botó d\'accessibilitat:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Tria la funció que vols utilitzar amb el gest d\'accessibilitat (llisca cap amunt amb dos dits des de la part inferior de la pantalla):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Tria la funció que vols utilitzar amb el gest d\'accessibilitat (fes lliscar tres dits cap amunt des de la part inferior de la pantalla):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Per canviar entre funcions, mantén premut el botó d\'accessibilitat."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Per canviar entre funcions, llisca cap amunt amb dos dits i mantén premut."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Per canviar entre funcions, llisca cap amunt amb tres dits i mantén premut."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"La funció s\'obrirà la pròxima vegada que toquis el botó d\'accessibilitat"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"La funció s\'obrirà la pròxima vegada que utilitzis aquesta drecera. Llisca cap amunt amb 2 dits des de la part inferior de la pantalla i aixeca\'ls ràpidament."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La funció s\'obrirà la pròxima vegada que utilitzis aquesta drecera. Llisca cap amunt amb 3 dits des de la part inferior de la pantalla i aixeca\'ls ràpidament."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliació"</string>
     <string name="user_switched" msgid="7249833311585228097">"Usuari actual: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"S\'està canviant a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1984,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Trucada en curs"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"S\'està filtrant una trucada entrant"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Sense classificar"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promocions"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Notícies"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recomanacions"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Has definit la importància d\'aquestes notificacions."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Aquest missatge és important per les persones implicades."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificació d\'aplicació personalitzada"</string>
@@ -2193,6 +2204,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selector de dreceres d\'accessibilitat en pantalla"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Drecera d\'accessibilitat"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ignora l\'àrea de notificacions"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menú"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Reprodueix o posa en pausa el contingut multimèdia"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Creu direccional: amunt"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Creu direccional: avall"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Creu direccional: esquerra"</string>
@@ -2412,19 +2425,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espai privat"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"S\'ha amagat contingut sensible de les notificacions"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Contingut de l\'aplicació amagat de la compartició de pantalla per motius de seguretat"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Contingut de l\'aplicació amagat de la compartició de pantalla per seguretat"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"S\'ha connectat automàticament a un satèl·lit"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Pots enviar i rebre missatges sense una xarxa mòbil o Wi‑Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Obre Missatges"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Com funciona"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendent..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Torna a configurar Desbloqueig amb empremta digital"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> no funcionava correctament i s\'ha suprimit"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> no funcionaven correctament i s\'han suprimit"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> no funcionava correctament i s\'ha suprimit. Torna a configurar-la per desbloquejar el telèfon amb l\'empremta digital."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> no funcionaven correctament i s\'han suprimit. Torna a configurar-les per desbloquejar el telèfon amb l\'empremta digital."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ja no es pot reconèixer."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ja no es poden reconèixer."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ja no es pot reconèixer. Torna a configurar Desbloqueig amb empremta digital."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ja no es poden reconèixer. Torna a configurar Desbloqueig amb empremta digital."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Torna a configurar Desbloqueig facial"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"El teu model facial no funcionava correctament i s\'ha suprimit. Torna a configurar-lo per desbloquejar el telèfon amb la cara."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"El teu model facial ja no es pot reconèixer. Torna a configurar Desbloqueig facial."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configura"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ara no"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarma per a <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Canvia d\'usuari"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Silencia"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Toca per silenciar el so"</string>
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index ad43a95..a4e5b28 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1413,6 +1413,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Vyberte, chcete-li zakázat bezdrátové ladění."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Režim správce testů je aktivní"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Chcete-li deaktivovat režim správce testů, restartujte zařízení do továrního nastavení."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Je zapnutá sériová konzole"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Toto má dopad na výkon. Chcete-li ji vypnout, zkontrolujte bootloader."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Je zapnuto experimentální MTE"</string>
@@ -1437,7 +1441,7 @@
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Zobrazení přes ostatní aplikace"</string>
     <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"Aplikace <xliff:g id="NAME">%s</xliff:g> se zobrazuje přes ostatní aplikace"</string>
-    <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> se zobrazuje přes ostatní aplikace"</string>
+    <string name="alert_windows_notification_title" msgid="6331662751095228536">"Aplikace <xliff:g id="NAME">%s</xliff:g> se zobrazuje přes ostatní aplikace"</string>
     <string name="alert_windows_notification_message" msgid="6538171456970725333">"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="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Vypnout"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Kontroluje se <xliff:g id="NAME">%s</xliff:g>…"</string>
@@ -1757,12 +1761,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> byla vypnuta."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Uvolněte tlačítka hlasitosti. Pokud chcete zapnout službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, znovu tři sekundy podržte obě tlačítka hlasitosti."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Určete, jakou funkci aktivujete klepnutím na tlačítko přístupnosti:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Určete, jakou funkci aktivujete pomocí gesta přístupnosti (přejetí dvěma prsty ze spodní části obrazovky nahoru):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Určete, jakou funkci aktivujete pomocí gesta přístupnosti (přejetí třemi prsty ze spodní části obrazovky nahoru):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Chcete-li přepnout mezi funkcemi, podržte tlačítko přístupnosti."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Chcete-li přepnout mezi funkcemi, přejeďte nahoru dvěma prsty a podržte je."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Chcete-li přepnout mezi funkcemi, přejeďte nahoru třemi prsty a podržte je."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funkce se otevře, až příště klepnete na tlačítko přístupnosti"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkce se otevře při příštím použití této zkratky. Přejeďte dvěma prsty nahoru ze spodní části obrazovky a rychle je zvedněte."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkce se otevře při příštím použití této zkratky. Přejeďte třemi prsty nahoru ze spodní části obrazovky a rychle je zvedněte."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Zvětšení"</string>
     <string name="user_switched" msgid="7249833311585228097">"Aktuální uživatel je <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Přepínání na uživatele <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1978,6 +1985,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Probíhající hovor"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Prověřování příchozího hovoru"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Neklasifikováno"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoakce"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Sociální sítě"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Zprávy"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Doporučení"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Důležitost oznámení určujete vy."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Tato zpráva je důležitá kvůli lidem zapojeným do konverzace."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Vlastní oznámení aplikace"</string>
@@ -2194,6 +2205,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Výběr zkratky přístupnosti na obrazovce"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Zkratka přístupnosti"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Zavřít panel oznámení"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Nabídka"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Přehrát/pozastavit média"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad nahoru"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad dolů"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad doleva"</string>
@@ -2420,12 +2433,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Jak to funguje"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Čeká na vyřízení…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Opětovné nastavení odemknutí otiskem prstu"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> nefungoval správně a byl vymazán"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nefungovaly správně a byly vymazány"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> nefungoval správně a byl vymazán. Pokud chcete telefon odemykat otiskem prstu, nastavte jej znovu."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nefungovaly správně a byly vymazány. Pokud chcete telefon odemykat otiskem prstu, nastavte je znovu."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> se nedaří rozpoznat."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> se nedaří rozpoznat."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> se nedaří rozpoznat. Nastavte odemknutí otiskem prstu znovu."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> se nedaří rozpoznat. Nastavte odemknutí otiskem prstu znovu."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Nastavte odemknutí obličejem znovu"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Váš model obličeje nefungoval správně a byl vymazán. Pokud chcete telefon odemykat obličejem, nastavte jej znovu."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Váš model obličeje se nedaří rozpoznat. Nastavte odemknutí obličejem znovu."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Nastavit"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Teď ne"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Budík pro uživatele <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Přepnout uživatele"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Ztlumit"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Klepnutím ztlumíte zvuk"</string>
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index e32b0b6..4d10a6d 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Vælg for at deaktivere trådløs fejlretning."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Tilstanden Testsele er aktiveret"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Gendan fabriksindstillingerne for at deaktivere tilstanden Testsele."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Seriekonsollen er aktiveret"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Effektiviteten er påvirket. Deaktiver via bootloaderen."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimentel MTE er aktiveret"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Lydstyrkeknapperne blev holdt nede. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er aktiveret."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Lydstyrkeknapperne blev holdt nede. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er deaktiveret."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Slip lydstyrkeknapperne. Du kan aktivere <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ved at holde begge lydstyrkeknapper nede igen i 3 sekunder."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Vælg, hvilken funktion du vil bruge, når du trykker på knappen til hjælpefunktioner:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Vælg, hvilken funktion du vil bruge, når du laver bevægelsen for hjælpefunktioner (stryger opad fra bunden af skærmen med to fingre):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Vælg, hvilken funktion du vil bruge, når du laver bevægelsen for hjælpefunktioner (stryger opad fra bunden af skærmen med tre fingre):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Du kan skifte mellem funktioner ved at holde knappen til hjælpefunktioner nede."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Du kan skifte mellem funktioner ved at stryge opad med to fingre og holde dem nede."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Du kan skifte mellem funktioner ved at stryge opad med tre fingre og holde dem nede."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funktionen åbnes næste gang, du trykker på knappen til hjælpefunktioner"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funktionen åbnes næste gang, du bruger denne genvej. Stryg opad fra bunden af skærmen med 2 fingre, og slip derefter hurtigt."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funktionen åbnes næste gang, du bruger denne genvej. Stryg opad fra bunden af skærmen med 3 fingre, og slip derefter hurtigt."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Forstørrelse"</string>
     <string name="user_switched" msgid="7249833311585228097">"Nuværende bruger <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Skifter til <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Igangværende opkald"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Et indgående opkald screenes"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Uden kategori"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoveringer"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Socialt"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Nyheder"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Anbefalinger"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Du angiver, hvor vigtige disse notifikationer er."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Dette er vigtigt på grund af de personer, det handler om."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Tilpasset appnotifikation"</string>
@@ -2140,7 +2151,7 @@
     <string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"Denne notifikation blev placeret højere. Tryk for at give feedback."</string>
     <string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"Denne notifikation blev placeret lavere. Tryk for at give feedback."</string>
     <string name="nas_upgrade_notification_title" msgid="8436359459300146555">"Forbedrede notifikationer"</string>
-    <string name="nas_upgrade_notification_content" msgid="5157550369837103337">"Foreslåede handlinger og svar leveres nu via forbedrede notifikationer. Tilpassede Android-notifikationer understøttes ikke længere."</string>
+    <string name="nas_upgrade_notification_content" msgid="5157550369837103337">"Foreslåede handlinger og svar leveres nu via forbedrede notifikationer. Adaptive Android-notifikationer understøttes ikke længere."</string>
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Deaktiver"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Få flere oplysninger"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Valg af genvej til hjælpefunktioner på skærmen"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Genvej til hjælpefunktioner"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Luk notifikationspanel"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Afspil medie/sæt medie på pause"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"D-pad, op"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"D-pad, ned"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"D-pad, venstre"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Sådan fungerer det"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Afventer…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfigurer fingeroplåsning igen"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> virkede ikke optimalt og er derfor slettet"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> virkede ikke optimalt og er derfor slettet"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> virkede ikke optimalt og er derfor slettet. Konfigurer den igen for at bruge fingeroplåsning på din telefon."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> virkede ikke optimalt og er derfor slettet. Konfigurer dem igen for at bruge dit fingeraftryk til at låse din telefon op."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> kan ikke længere genkendes."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> kan ikke længere genkendes."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> kan ikke længere genkendes. Konfigurer fingeroplåsning igen."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> kan ikke længere genkendes. Konfigurer fingeroplåsning igen."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Konfigurer ansigtsoplåsning igen"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Din ansigtsmodel virkede ikke optimalt og er derfor slettet. Konfigurer den igen for at bruge ansigtsoplåsning på din telefon."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Din ansigtsmodel kan ikke længere genkendes. Konfigurer ansigtsoplåsning igen."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Konfigurer"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ikke nu"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm til <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Skift bruger"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Slå lyden fra"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tryk for at slå lyden fra"</string>
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index ca858790..d22aec8 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -345,7 +345,7 @@
     <string name="permgroupdesc_phone" msgid="270048070781478204">"Telefonanrufe tätigen und verwalten"</string>
     <string name="permgrouplab_sensors" msgid="9134046949784064495">"Körpersensoren"</string>
     <string name="permgroupdesc_sensors" msgid="2610631290633747752">"auf Sensordaten zu deinen Vitaldaten zugreifen"</string>
-    <string name="permgrouplab_notifications" msgid="5472972361980668884">"Benachrichtigungen"</string>
+    <string name="permgrouplab_notifications" msgid="5472972361980668884">"Benachrichtigun­gen"</string>
     <string name="permgroupdesc_notifications" msgid="4608679556801506580">"Benachrichtigungen anzeigen"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"Fensterinhalte abrufen"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"Die Inhalte eines Fensters, mit dem du interagierst, werden abgerufen."</string>
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Auswählen, um \"Debugging über WLAN\" zu deaktivieren."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test-Harnischmodus aktiviert"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Setz das Gerät auf die Werkseinstellungen zurück, um den Test-Harnischmodus zu deaktivieren."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Serielle Konsole aktiviert"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Leistung wird beeinflusst. Überprüfe Bootloader zum Deaktivieren."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Experimentelle MTE aktiviert"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist aktiviert."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist deaktiviert."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lass die Lautstärketasten los. Halte zum Aktivieren von <xliff:g id="SERVICE_NAME">%1$s</xliff:g> beide Lautstärketasten noch einmal 3 Sekunden lang gedrückt."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Wähle eine Funktion aus, die verwendet wird, wenn du auf die Schaltfläche \"Bedienungshilfen\" tippst:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Wähle die Funktion aus, die mit der Touch-Geste für die Bedienungshilfen verwendet werden soll (mit zwei Fingern vom unteren Bildschirmrand nach oben wischen):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Wähle eine Funktion aus, die mit der Touch-Geste für die Bedienungshilfen verwendet werden soll (mit drei Fingern vom unteren Bildschirmrand nach oben wischen):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Wenn du zwischen den Funktionen wechseln möchtest, halte die Schaltfläche „Bedienungshilfen“ gedrückt."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Wenn du zwischen den Funktionen wechseln möchtest, wische mit zwei Fingern nach oben und halte."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Wenn du zwischen den Funktionen wechseln möchtest, wische mit drei Fingern nach oben und halte."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Die Funktion wird geöffnet, wenn du das nächste Mal auf die Schaltfläche „Bedienungshilfen“ tippst"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Die Funktion wird geöffnet, wenn du diese Touch-Geste für Bedienungshilfen das nächste Mal verwendest. Wische mit 2 Fingern vom unteren Displayrand nach oben und lass dann schnell los."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Die Funktion wird geöffnet, wenn du diese Touch-Geste für Bedienungshilfen das nächste Mal verwendest. Wische mit 3 Fingern vom unteren Displayrand nach oben und lass dann schnell los."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Vergrößerung"</string>
     <string name="user_switched" msgid="7249833311585228097">"Aktueller Nutzer <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Wechseln zu <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Aktueller Anruf"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Filter für eingehenden Anruf"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Unkategorisiert"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Werbeaktionen"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Soziale Netzwerke"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Neuigkeiten"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Empfehlungen"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Du hast die Wichtigkeit dieser Benachrichtigungen festgelegt."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Diese Benachrichtigung ist aufgrund der beteiligten Personen wichtig."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Benutzerdefinierte App-Benachrichtigung"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Auswahl für Kurzbefehle für Bildschirmbedienungshilfen"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Kurzbefehl für Bedienungshilfen"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Benachrichtigungsleiste schließen"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menü"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Medien wiedergeben/pausieren"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Steuerkreuz nach oben"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Steuerkreuz nach unten"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Steuerkreuz nach links"</string>
@@ -2411,19 +2424,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Vertrauliches Profil"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"Vertrauliche Benachrichtigungsinhalte ausgeblendet"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"App-Inhalte werden aus Sicherheitsgründen bei der Bildschirmfreigabe ausgeblendet"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Aus Sicherheitsgründen werden bei der Bildschirmfreigabe App-Inhalte ausgeblendet"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"Automatisch mit Satellit verbunden"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Du kannst Nachrichten ohne Mobilfunknetz oder WLAN senden und empfangen"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages öffnen"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"So funktionierts"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Ausstehend…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Entsperrung per Fingerabdruck neu einrichten"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> hat nicht einwandfrei funktioniert und wurde gelöscht"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> und <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> haben nicht einwandfrei funktioniert und wurden gelöscht"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> hat nicht einwandfrei funktioniert und wurde gelöscht. Richte ihn noch einmal ein, um dein Smartphone per Fingerabdruck zu entsperren."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> und <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> haben nicht einwandfrei funktioniert und wurden gelöscht. Richte sie noch einmal ein, um dein Smartphone per Fingerabdruck zu entsperren."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> wird nicht mehr erkannt."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> und <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> werden nicht mehr erkannt."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> wird nicht mehr erkannt. Richte die Entsperrung per Fingerabdruck neu ein."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> und <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> werden nicht mehr erkannt. Richte die Entsperrung per Fingerabdruck neu ein."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Entsperrung per Gesichtserkennung neu einrichten"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Dein Gesichtsmodell hat nicht einwandfrei funktioniert und wurde gelöscht. Richte es noch einmal ein, um dein Smartphone per Gesichtserkennung zu entsperren."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Dein Gesichtsmodell wird nicht mehr erkannt. Richte die Entsperrung per Gesichtserkennung neu ein."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Einrichten"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Nicht jetzt"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Wecker für <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Nutzer wechseln"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Stummschalten"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Zum Stummschalten tippen"</string>
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index cb1d3b1..8321d60 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Επιλέξτε, για να απενεργοποιήσετε τον ασύρματο εντοπισμό σφαλμάτων."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Η λειτουργία περιβάλλοντος δοκιμών ενεργοποιήθηκε"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Εκτελέστε επαναφορά εργοστασιακών ρυθμίσεων για να απενεργοποιήσετε τη λειτουργία περιβάλλοντος δοκιμών."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Η σειριακή κονσόλα ενεργοποιήθηκε"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Η απόδοση επηρεάζεται. Για απενεργοποίηση, επιλέξτε το πρόγραμμα φόρτωσης εκκίνησης."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Ενεργοποιήθηκε το πειραματικό MTE"</string>
@@ -1435,7 +1439,7 @@
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Εμφάνιση πάνω σε άλλες εφαρμογές"</string>
     <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"Η εφαρμογή <xliff:g id="NAME">%s</xliff:g> προβάλλεται πάνω από άλλες εφαρμογές"</string>
-    <string name="alert_windows_notification_title" msgid="6331662751095228536">"Η εφαρμογή <xliff:g id="NAME">%s</xliff:g> επικαλύπτει άλλες"</string>
+    <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>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Τα πλήκτρα έντασης είναι πατημένα. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ενεργοποιήθηκε."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Τα πλήκτρα έντασης είναι πατημένα. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>: απενεργοποιημένο"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Αφήστε τα κουμπιά έντασης ήχου. Για να ενεργοποιήσετε την υπηρεσία <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, πατήστε ξανά παρατεταμένα και τα δύο κουμπιά έντασης ήχου για τρία δευτερόλεπτα."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Επιλέξτε μια λειτουργία που θα χρησιμοποιείται κατά το πάτημα του κουμπιού προσβασιμότητας:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Επιλέξτε μια λειτουργία που θα χρησιμοποιείται με την κίνηση προσβασιμότητας (σύρετε με δύο δάχτυλα προς τα επάνω από το κάτω μέρος της οθόνης):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Επιλέξτε μια λειτουργία που θα χρησιμοποιείται με την κίνηση προσβασιμότητας (σύρετε με τρία δάχτυλα προς τα επάνω από το κάτω μέρος της οθόνης):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Για εναλλαγή μεταξύ λειτουργιών, αγγίξτε παρατεταμένα το κουμπί προσβασιμότητας."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Για εναλλαγή μεταξύ λειτουργιών, σύρετε παρατεταμένα με δύο δάχτυλα προς τα επάνω."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Για εναλλαγή μεταξύ λειτουργιών, σύρετε παρατεταμένα με τρία δάχτυλα προς τα επάνω."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Η λειτουργία θα ανοίξει την επόμενη φορά που θα πατήσετε το κουμπί προσβασιμότητας"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Η λειτουργία θα ανοίξει την επόμενη φορά που θα χρησιμοποιήσετε αυτή τη συντόμευση. Σαρώστε προς τα πάνω με 2 δάχτυλα από το κάτω μέρος της οθόνης και απομακρύνετε γρήγορα τα δάχτυλά σας."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Η λειτουργία θα ανοίξει την επόμενη φορά που θα χρησιμοποιήσετε αυτή τη συντόμευση. Σαρώστε προς τα πάνω με 3 δάχτυλα από το κάτω μέρος της οθόνης και απομακρύνετε γρήγορα τα δάχτυλά σας."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Μεγιστοποίηση"</string>
     <string name="user_switched" msgid="7249833311585228097">"Τρέχων χρήστης <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Εναλλαγή σε <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Κλήση σε εξέλιξη"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Διαλογή εισερχόμενης κλήσης"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Μη κατηγοριοποιημένο"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Προωθήσεις"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Κοινωνικά δίκτυα"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Ειδήσεις"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Προτάσεις"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Μπορείτε να ρυθμίσετε τη βαρύτητα αυτών των ειδοποιήσεων."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Αυτό είναι σημαντικό λόγω των ατόμων που συμμετέχουν."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Προσαρμοσμένη ειδοποίηση εφαρμογής"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Επιλογέας συντόμευσης οθόνης για την προσβασιμότητα"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Συντόμευση προσβασιμότητας"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Παράβλεψη πλαισίου σκίασης ειδοποιήσεων"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Μενού"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Αναπαραγωγή/παύση μέσων"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad επάνω"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad κάτω"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad αριστερά"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Πώς λειτουργεί"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Σε εκκρεμότητα…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Επαναρρύθμιση λειτουργίας Ξεκλείδωμα με δακτυλικό αποτύπωμα"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Το δακτυλικό αποτύπωμα <xliff:g id="FINGERPRINT">%s</xliff:g> δεν λειτουργούσε καλά και διαγράφηκε"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Τα δακτυλικά αποτυπώματα <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> και <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> δεν λειτουργούσαν καλά και διαγράφηκαν"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Το δακτυλικό αποτύπωμα <xliff:g id="FINGERPRINT">%s</xliff:g> δεν λειτουργούσε καλά και διαγράφηκε. Ρυθμίστε το ξανά για να ξεκλειδώνετε το τηλέφωνο με το δακτυλικό αποτύπωμά σας."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Τα δακτυλικά αποτυπώματα <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> και <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> δεν λειτουργούσαν καλά και διαγράφηκαν. Ρυθμίστε τα ξανά για να ξεκλειδώνετε το τηλέφωνο με το δακτυλικό αποτύπωμά σας."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Δεν είναι πλέον δυνατή η αναγνώριση του <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Δεν είναι πλέον δυνατή η αναγνώριση του <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> και του <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Δεν είναι πλέον δυνατή η αναγνώριση του <xliff:g id="FINGERPRINT">%s</xliff:g>. Ρυθμίστε ξανά τη λειτουργία Ξεκλείδωμα με δακτυλικό αποτύπωμα."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Δεν είναι πλέον δυνατή η αναγνώριση του <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> και του <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>. Ρυθμίστε ξανά τη λειτουργία Ξεκλείδωμα με δακτυλικό αποτύπωμα."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Επαναρρύθμιση λειτουργίας Ξεκλείδωμα με το πρόσωπο"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Το μοντέλο προσώπου δεν λειτουργούσε καλά και διαγράφηκε. Ρυθμίστε το ξανά για να ξεκλειδώνετε το τηλέφωνο με το πρόσωπό σας."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Δεν είναι πλέον δυνατή η αναγνώριση του μοντέλου προσώπου σας. Ρυθμίστε ξανά τη λειτουργία Ξεκλείδωμα με το πρόσωπο."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Ρύθμιση"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Όχι τώρα"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Ξυπνητήρι για τον χρήστη <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Εναλλαγή χρήστη"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Σίγαση"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Πατήστε για σίγαση του ήχου"</string>
 </resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index e748648..39f55dd 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Select to disable wireless debugging."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test Harness Mode enabled"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Perform a factory reset to disable Test Harness Mode."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Serial console enabled"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Performance is impacted. To disable, check bootloader."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Experimental MTE enabled"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Release the volume keys. To turn on <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, press and hold both volume keys again for three seconds."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Choose a feature to use when you tap the Accessibility button:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"To switch between features, touch and hold the Accessibility button."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"To switch between features, swipe up with two fingers and hold."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"To switch between features, swipe up with three fingers and hold."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"The feature will open the next time that you tap the accessibility button"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"The feature will open the next time that you use this shortcut. Swipe up with 2 fingers from the bottom of your screen and release quickly."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"The feature will open the next time that you use this shortcut. Swipe up with 3 fingers from the bottom of your screen and release quickly."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string>
     <string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"On-going call"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Screening an incoming call"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Uncategorised"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promotions"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"News"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recommendations"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"You set the importance of these notifications."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"This is important because of the people involved."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Custom app notification"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"On-screen accessibility shortcut chooser"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Accessibility shortcut"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Dismiss notification shade"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media play/pause"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad up"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad down"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad left"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted. Set it up again to unlock your phone with your fingerprint."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted. Set them up again to unlock your phone with your fingerprint."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognised."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognised."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognised. Set up Fingerprint Unlock again."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognised. Set up Fingerprint Unlock again."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Your face model wasn\'t working well and was deleted. Set it up again to unlock your phone with your face."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Your face model can no longer be recognised. Set up Face Unlock again."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Set up"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Not now"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm for <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Switch user"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Mute"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tap to mute sound"</string>
 </resources>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 3c1ae77..bd5976b 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1411,6 +1411,8 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Select to disable wireless debugging."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test Harness Mode enabled"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Perform a factory reset to disable Test Harness Mode."</string>
+    <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"Wrong HSUM build configuration"</string>
+    <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"The Headless System User Mode state of this device differs from its build configuration. Please factory reset the device."</string>
     <string name="console_running_notification_title" msgid="6087888939261635904">"Serial console enabled"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Performance is impacted. To disable, check bootloader."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Experimental MTE enabled"</string>
@@ -1755,12 +1757,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Release the volume keys. To turn on <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, press and hold both volume keys again for 3 seconds."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Choose a feature to use when you tap the accessibility button:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"To switch between features, touch and hold the accessibility button."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"To switch between features, swipe up with two fingers and hold."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"To switch between features, swipe up with three fingers and hold."</string>
+    <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"Choose a feature"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"Choose a feature"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"Choose a feature"</string>
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"The feature will open next time you tap the accessibility button"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"The feature will open next time you use this shortcut. Swipe up with 2 fingers from the bottom of your screen and release quickly."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"The feature will open next time you use this shortcut. Swipe up with 3 fingers from the bottom of your screen and release quickly."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string>
     <string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1883,8 +1885,7 @@
     <string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN is too short. Must be at least 4 digits."</string>
     <string name="restr_pin_try_later" msgid="5897719962541636727">"Try again later"</string>
     <string name="immersive_cling_title" msgid="2307034298721541791">"Viewing full screen"</string>
-    <!-- no translation found for immersive_cling_description (2896205051090870978) -->
-    <skip />
+    <string name="immersive_cling_description" msgid="2896205051090870978">"To exit, swipe down from the top of your screen"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Got it"</string>
     <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Rotate for a better view"</string>
     <string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Open <xliff:g id="NAME">%s</xliff:g> in full screen for a better view"</string>
@@ -1976,6 +1977,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Ongoing call"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Screening an incoming call"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Uncategorized"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promotions"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"News"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recommendations"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"You set the importance of these notifications."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"This is important because of the people involved."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Custom app notification"</string>
@@ -2192,6 +2197,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"On-screen Accessibility Shortcut Chooser"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Accessibility Shortcut"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Dismiss Notification Shade"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media Play/Pause"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad Up"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad Down"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad Left"</string>
@@ -2418,12 +2425,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted. Set it up again to unlock your phone with fingerprint."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted. Set them up again to unlock your phone with your fingerprint."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognized."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognized."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognized. Set up Fingerprint Unlock again."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognized. Set up Fingerprint Unlock again."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Your face model wasn\'t working well and was deleted. Set it up again to unlock your phone with face."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Your face model can no longer be recognized. Set up Face Unlock again."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Set up"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Not now"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm for <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Switch user"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Mute"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tap to mute sound"</string>
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 818614a..ad909ef 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Select to disable wireless debugging."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test Harness Mode enabled"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Perform a factory reset to disable Test Harness Mode."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Serial console enabled"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Performance is impacted. To disable, check bootloader."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Experimental MTE enabled"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Release the volume keys. To turn on <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, press and hold both volume keys again for three seconds."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Choose a feature to use when you tap the Accessibility button:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"To switch between features, touch and hold the Accessibility button."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"To switch between features, swipe up with two fingers and hold."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"To switch between features, swipe up with three fingers and hold."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"The feature will open the next time that you tap the accessibility button"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"The feature will open the next time that you use this shortcut. Swipe up with 2 fingers from the bottom of your screen and release quickly."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"The feature will open the next time that you use this shortcut. Swipe up with 3 fingers from the bottom of your screen and release quickly."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string>
     <string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"On-going call"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Screening an incoming call"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Uncategorised"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promotions"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"News"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recommendations"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"You set the importance of these notifications."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"This is important because of the people involved."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Custom app notification"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"On-screen accessibility shortcut chooser"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Accessibility shortcut"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Dismiss notification shade"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media play/pause"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad up"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad down"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad left"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted. Set it up again to unlock your phone with your fingerprint."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted. Set them up again to unlock your phone with your fingerprint."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognised."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognised."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognised. Set up Fingerprint Unlock again."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognised. Set up Fingerprint Unlock again."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Your face model wasn\'t working well and was deleted. Set it up again to unlock your phone with your face."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Your face model can no longer be recognised. Set up Face Unlock again."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Set up"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Not now"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm for <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Switch user"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Mute"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tap to mute sound"</string>
 </resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index a58f731..5fe0d32 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Select to disable wireless debugging."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test Harness Mode enabled"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Perform a factory reset to disable Test Harness Mode."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Serial console enabled"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Performance is impacted. To disable, check bootloader."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Experimental MTE enabled"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Release the volume keys. To turn on <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, press and hold both volume keys again for three seconds."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Choose a feature to use when you tap the Accessibility button:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"To switch between features, touch and hold the Accessibility button."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"To switch between features, swipe up with two fingers and hold."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"To switch between features, swipe up with three fingers and hold."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"The feature will open the next time that you tap the accessibility button"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"The feature will open the next time that you use this shortcut. Swipe up with 2 fingers from the bottom of your screen and release quickly."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"The feature will open the next time that you use this shortcut. Swipe up with 3 fingers from the bottom of your screen and release quickly."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string>
     <string name="user_switched" msgid="7249833311585228097">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"On-going call"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Screening an incoming call"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Uncategorised"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promotions"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"News"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recommendations"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"You set the importance of these notifications."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"This is important because of the people involved."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Custom app notification"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"On-screen accessibility shortcut chooser"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Accessibility shortcut"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Dismiss notification shade"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media play/pause"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad up"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad down"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad left"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"How it works"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pending…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Set up Fingerprint Unlock again"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> wasn\'t working well and was deleted. Set it up again to unlock your phone with your fingerprint."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> weren\'t working well and were deleted. Set them up again to unlock your phone with your fingerprint."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognised."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognised."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> can no longer be recognised. Set up Fingerprint Unlock again."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> and <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> can no longer be recognised. Set up Fingerprint Unlock again."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Set up Face Unlock again"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Your face model wasn\'t working well and was deleted. Set it up again to unlock your phone with your face."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Your face model can no longer be recognised. Set up Face Unlock again."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Set up"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Not now"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm for <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Switch user"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Mute"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tap to mute sound"</string>
 </resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 5572714..1c0ea4b 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -1411,6 +1411,8 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‏‏‎‏‏‎‏‏‎‏‏‏‏‎‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‏‏‏‏‏‏‎‎‏‎‏‏‎‎Select to disable wireless debugging.‎‏‎‎‏‎"</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‏‏‎‏‎‎‏‎‏‎‎‎‏‏‏‎‎‎‏‏‎‏‏‎‏‎‏‏‏‎‏‎‎‎‎‏‎‏‏‏‏‎Test Harness Mode enabled‎‏‎‎‏‎"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‏‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‏‎‎‏‏‎‎‎‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‎‎Perform a factory reset to disable Test Harness Mode.‎‏‎‎‏‎"</string>
+    <string name="wrong_hsum_configuration_notification_title" msgid="7212758829332714385">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‎‎‎‏‏‎‏‏‏‎‏‏‏‏‏‎‎‎‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎Wrong HSUM build configuration‎‏‎‎‏‎"</string>
+    <string name="wrong_hsum_configuration_notification_message" msgid="5353475441480684381">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‏‎‏‎‏‏‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‎‎‏‏‎‎‏‏‏‎‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‎‏‎The Headless System User Mode state of this device differs from its build configuration. Please factory reset the device.‎‏‎‎‏‎"</string>
     <string name="console_running_notification_title" msgid="6087888939261635904">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‏‏‎‏‎‏‏‏‏‎‎‎‎‏‏‏‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‏‎‎‎‎‎‎‎Serial console enabled‎‏‎‎‏‎"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‏‎‏‏‎‎‎‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‎‏‎‏‏‏‎Performance is impacted. To disable, check bootloader.‎‏‎‎‏‎"</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‏‎‏‎‎‎‎‏‎‎‏‏‎‎‎‏‎‏‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‎‎‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎Experimental MTE enabled‎‏‎‎‏‎"</string>
@@ -1755,12 +1757,12 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‏‏‏‎‏‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‏‎Held volume keys. ‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ turned on.‎‏‎‎‏‎"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‏‎‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎Held volume keys. ‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ turned off.‎‏‎‎‏‎"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‏‎‎‎‏‏‎‎‏‏‎‎‎‏‎‎‏‏‎‎‏‏‎‏‎‎Release the volume keys. To turn on ‎‏‎‎‏‏‎<xliff:g id="SERVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎, press and hold both volume keys again for 3 seconds.‎‏‎‎‏‎"</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‏‎‎‎‎‏‏‎‎‏‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎‎‏‎‎‏‏‎‎‎‎‎‏‏‎‏‎‏‏‏‏‏‎‎‏‎Choose a feature to use when you tap the accessibility button:‎‏‎‎‏‎"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‏‏‏‎‏‏‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‎‏‏‏‎‏‏‏‎‏‎‏‎‏‎‏‎‎‏‏‏‎‏‏‏‎‎‎‎‎Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):‎‏‎‎‏‎"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‏‎‏‎‎‎‎‏‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‎‎‎‎‎‏‏‎‏‎‎‏‏‎‏‎‏‏‎Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):‎‏‎‎‏‎"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‏‎‏‎‏‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‎‎‏‎‎‎To switch between features, touch &amp; hold the accessibility button.‎‏‎‎‏‎"</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‏‏‎‎‎‎‎‏‎To switch between features, swipe up with two fingers and hold.‎‏‎‎‏‎"</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‏‏‏‎‎‏‏‏‏‎‎‎‎‏‎‎‎‎‎‏‏‎‎‏‎‏‎To switch between features, swipe up with three fingers and hold.‎‏‎‎‏‎"</string>
+    <string name="accessibility_button_prompt_text" msgid="6105393217162198616">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‏‎‏‎‏‎‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‎‎‎‎‎‏‏‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎Choose a feature‎‏‎‎‏‎"</string>
+    <string name="accessibility_gesture_prompt_text" msgid="6452246951969541792">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‏‏‎‏‎‏‏‏‎‎‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎‎‎‎Choose a feature‎‏‎‎‏‎"</string>
+    <string name="accessibility_gesture_3finger_prompt_text" msgid="77745752309056152">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎‎‎‎‏‎‏‎‎‏‏‎‎‎‎Choose a feature‎‏‎‎‏‎"</string>
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‏‏‎‎‏‎‏‎‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‎‎‎‏‏‎‎‎The feature will open next time you tap the accessibility button‎‏‎‎‏‎"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‏‏‎‎‏‏‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‎The feature will open next time you use this shortcut. Swipe up with 2 fingers from the bottom of your screen and release quickly.‎‏‎‎‏‎"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‎‎‎‎‏‏‎‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‏‎‏‎‏‎‎‏‎‎‎‎‏‏‎‏‎‏‏‎‏‎‎The feature will open next time you use this shortcut. Swipe up with 3 fingers from the bottom of your screen and release quickly.‎‏‎‎‏‎"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎‎‏‏‏‎‎‎‏‏‏‎‎‏‎‎‎‏‎‎‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎‎‏‏‎‎‎Magnification‎‏‎‎‏‎"</string>
     <string name="user_switched" msgid="7249833311585228097">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‎‏‎‏‎‎‎‎‎‏‎Current user ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‎"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‎‏‎‏‎‏‎‎‏‎‎‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‎‎‎‎‎Switching to ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎…‎‏‎‎‏‎"</string>
@@ -1883,8 +1885,7 @@
     <string name="restr_pin_error_too_short" msgid="1547007808237941065">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‏‏‎‎‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‏‏‏‎‎‏‏‎‎‎‏‎‏‎‎‏‎‎‏‎PIN is too short. Must be at least 4 digits.‎‏‎‎‏‎"</string>
     <string name="restr_pin_try_later" msgid="5897719962541636727">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‎‎‎‎‎‎‎‏‏‎‎‎‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎Try again later‎‏‎‎‏‎"</string>
     <string name="immersive_cling_title" msgid="2307034298721541791">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‎‏‎‎‎‎‏‏‏‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‎‎‏‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‏‎‏‎‎‏‏‏‏‏‎Viewing full screen‎‏‎‎‏‎"</string>
-    <!-- no translation found for immersive_cling_description (2896205051090870978) -->
-    <skip />
+    <string name="immersive_cling_description" msgid="2896205051090870978">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‏‎‎‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‏‏‎‎‎‏‏‎‎‏‎‏‏‏‏‎‏‏‎‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‎‎To exit, swipe down from the top of your screen‎‏‎‎‏‎"</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‏‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‎‏‏‎‏‏‎Got it‎‏‎‎‏‎"</string>
     <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‏‎‏‏‏‏‎‎Rotate for a better view‎‏‎‎‏‎"</string>
     <string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‎‎‏‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‎‏‎‎‎‎‎‏‏‎‏‏‏‎Open ‎‏‎‎‏‏‎<xliff:g id="NAME">%s</xliff:g>‎‏‎‎‏‏‏‎ in full screen for a better view‎‏‎‎‏‎"</string>
@@ -1976,6 +1977,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‎‏‏‎Ongoing call‎‏‎‎‏‎"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‎‏‎‎‏‎‏‎‎‎‎‎‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‏‏‎‎‎‎‎Screening an incoming call‎‏‎‎‏‎"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‎‎‎‏‏‎‏‎‏‏‏‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎‏‎‎‎‎‏‏‎‎‏‎‏‎‎‏‏‏‎‏‎‏‏‎‎‏‎‎Uncategorized‎‏‎‎‏‎"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‏‎‏‏‎‏‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‏‎‏‎‎‎‎‏‏‎‏‏‏‎‏‎‎‏‎‎‏‎Promotions‎‏‎‎‏‎"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎‏‏‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‎‎‏‎Social‎‏‎‎‏‎"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‏‏‏‎‎‏‎‎‏‎‏‎‏‎‏‎‏‏‎‎‎‎‎‎‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‎‏‎‏‏‏‏‎News‎‏‎‎‏‎"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎‏‏‎‏‎‎‎‎‏‏‎‏‎‏‎‎‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‎Recommendations‎‏‎‎‏‎"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‏‏‏‏‏‎You set the importance of these notifications.‎‏‎‎‏‎"</string>
     <string name="importance_from_person" msgid="4235804979664465383">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‏‎‎‎‏‎‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‏‏‏‏‎‎‏‏‏‎This is important because of the people involved.‎‏‎‎‏‎"</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‏‎‎‎‏‎‏‎‏‎‏‎‏‏‎‏‎‎‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‎‏‏‏‏‏‏‏‎Custom app notification‎‏‎‎‏‎"</string>
@@ -2192,6 +2197,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‎‏‎‏‎‎‎‏‏‏‏‎‎On-screen Accessibility Shortcut Chooser‎‏‎‎‏‎"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‎‎‎‎‎‏‎‎‎‎‏‎‏‎‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎Accessibility Shortcut‎‏‎‎‏‎"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‎‎‏‏‏‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‎‏‏‎‎‏‏‏‎‎‎‎‎Dismiss Notification Shade‎‏‎‎‏‎"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‏‎‏‎‎‎‎‎‏‏‎‏‏‎‏‎‏‎‏‏‎‎‏‎‎‎‎‎‎‎Menu‎‏‎‎‏‎"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎Media Play/Pause‎‏‎‎‏‎"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‏‎‎‎‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎‏‏‏‎‎‎‏‎‏‏‎‎Dpad Up‎‏‎‎‏‎"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‎‏‎‎‎‎‏‎‎‏‏‎‏‎‎‏‎‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‎‏‏‎‏‏‏‎‏‎‏‏‎‏‏‏‎‏‎‏‎Dpad Down‎‏‎‎‏‎"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎‎‏‎‏‎‎‏‎‎‎‎‎‏‎‏‎‏‏‎‎‎‎‎Dpad Left‎‏‎‎‏‎"</string>
@@ -2418,12 +2425,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‎‏‎‎‎‎‏‏‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‎‎‎‎‏‏‎‎‎‎‏‏‏‎How it works‎‏‎‎‏‎"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‎‏‎‎‏‏‏‏‎‏‎‏‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‏‎‏‏‏‎‏‎‏‎‏‏‎‏‎Pending...‎‏‎‎‏‎"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‎‎‏‏‎‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎Set up Fingerprint Unlock again‎‏‎‎‏‎"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‎‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎‏‎‏‎‎‏‏‎‏‎‏‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT">%s</xliff:g>‎‏‎‎‏‏‏‎ wasn\'t working well and was deleted‎‏‎‎‏‎"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‏‎‏‎‏‏‎‏‎‎‏‎‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎ and ‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>‎‏‎‎‏‏‏‎ weren\'t working well and were deleted‎‏‎‎‏‎"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‏‏‏‎‎‎‎‏‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT">%s</xliff:g>‎‏‎‎‏‏‏‎ wasn\'t working well and was deleted. Set it up again to unlock your phone with fingerprint.‎‏‎‎‏‎"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‎‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎ and ‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>‎‏‎‎‏‏‏‎ weren\'t working well and were deleted. Set them up again to unlock your phone with your fingerprint.‎‏‎‎‏‎"</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‏‎‎‎‎‎‎‎‏‎‎‏‏‎‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT">%s</xliff:g>‎‏‎‎‏‏‏‎ can no longer be recognized.‎‏‎‎‏‎"</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‎‎‎‎‏‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎ and ‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>‎‏‎‎‏‏‏‎ can no longer be recognized.‎‏‎‎‏‎"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‎‏‏‏‎‏‏‎‎‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‎‏‏‏‎‏‎‏‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT">%s</xliff:g>‎‏‎‎‏‏‏‎ can no longer be recognized. Set up Fingerprint Unlock again.‎‏‎‎‏‎"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‎‏‎‎‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‎‎‎‎‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎ and ‎‏‎‎‏‏‎<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>‎‏‎‎‏‏‏‎ can no longer be recognized. Set up Fingerprint Unlock again.‎‏‎‎‏‎"</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‏‏‎‏‏‏‎‎‏‎‏‏‎‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‏‎‎‏‎‎‎‎‎‎‏‎‏‏‎‏‏‏‎‎‎‏‎Set up Face Unlock again‎‏‎‎‏‎"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‎‎‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‏‏‎‎‏‏‏‎‏‎‎‏‎‏‏‏‎Your face model wasn\'t working well and was deleted. Set it up again to unlock your phone with face.‎‏‎‎‏‎"</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‏‎‏‏‎‎‏‎‏‎‎‏‎‎‎‎‎‏‎‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‎‎‎‏‎‏‎‏‎‎‎‎Your face model can no longer be recognized. Set up Face Unlock again.‎‏‎‎‏‎"</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‏‏‎‏‎‎‏‎‎‎‏‏‏‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎‏‏‏‏‎‎‏‏‏‎‏‎‎‏‎Set up‎‏‎‎‏‎"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‎‎‎‎‏‏‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‎‏‏‎‏‏‏‎‏‏‎‏‏‎‏‏‏‎‎‎‏‏‎‎‎‏‏‎Not now‎‏‎‎‏‎"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‎‎‏‏‎‏‏‎‏‎‏‏‏‎‎‎‎‎‏‏‎‎‎‏‏‎‏‎‎‏‏‎‏‎‏‏‏‏‎‎‎‏‎‏‏‏‎‎‏‏‏‎Alarm for ‎‏‎‎‏‏‎<xliff:g id="USER_NAME">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‎‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‏‎‎‎‎‏‏‎‏‎‎‏‎‎Switch user‎‏‎‎‏‎"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‎‏‏‎‎‎‎‏‎‎‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‏‏‎Mute‎‏‎‎‏‎"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‏‎‎‏‎‏‎‏‎‏‏‏‏‏‎‏‎‎‎‏‎‎‏‎‏‎‎‎‎‏‎‎‎‎‏‎Tap to mute sound‎‏‎‎‏‎"</string>
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 94591ea8..6f49b54 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1412,6 +1412,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecciona para inhabilitar la depuración inalámbrica."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Se habilitó el modo de agente de prueba"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Restablece la configuración de fábrica para inhabilitar el modo de agente de prueba."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Se habilitó la consola en serie"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Afecta el rendimiento. Para inhabilitarla, verifica el bootloader."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"MTE experimental habilitada"</string>
@@ -1756,12 +1760,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Como mantuviste presionadas las teclas de volumen, se activó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Se presionaron las teclas de volumen. Se desactivó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Suelta las teclas de volumen. Para activar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, vuelve a mantener presionadas las teclas de volumen durante 3 segundos."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Elige una función para usar cuando pulses el botón accesibilidad:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Elige la función que se usará cuando realices el gesto de accesibilidad (deslizar dos dedos hacia arriba desde la parte inferior de la pantalla):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Elige la función que se usará cuando realices el gesto de accesibilidad (deslizar tres dedos hacia arriba desde la parte inferior de la pantalla):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Para cambiar entre funciones, mantén presionado el botón de accesibilidad."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Para cambiar de función, desliza dos dedos hacia arriba y mantén presionada la pantalla."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Para cambiar de función, desliza tres dedos hacia arriba y mantén presionada la pantalla."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"La función se abrirá la próxima vez que presiones el botón de accesibilidad"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"La función se abrirá la próxima vez que uses este atajo. Desliza hacia arriba con 2 dedos desde la parte inferior de la pantalla y levanta los dedos rápidamente."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La función se abrirá la próxima vez que uses este atajo. Desliza hacia arriba con 3 dedos desde la parte inferior de la pantalla y levanta los dedos rápidamente."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliación"</string>
     <string name="user_switched" msgid="7249833311585228097">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1984,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Llamada en curso"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando una llamada entrante"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Sin categoría"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promociones"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Redes sociales"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Noticias"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recomendaciones"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Estableciste la importancia de estas notificaciones."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Es importante debido a las personas involucradas."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificación de app personalizada"</string>
@@ -2193,6 +2204,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selector del acceso directo de accesibilidad en pantalla"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Acceso directo de accesibilidad"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Descartar panel de notificaciones"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menú"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Reproducir o pausar contenido multimedia"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Pad direccional: arriba"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Pad direccional: abajo"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Pad direccional: izquierda"</string>
@@ -2419,12 +2432,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cómo funciona"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendiente…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Vuelve a configurar el Desbloqueo con huellas dactilares"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Se borró <xliff:g id="FINGERPRINT">%s</xliff:g> porque no funcionaba correctamente"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Se borraron <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> porque no funcionaban correctamente"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Se borró <xliff:g id="FINGERPRINT">%s</xliff:g> porque no funcionaba correctamente. Vuelve a configurarla para desbloquear el teléfono con la huella dactilar."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Se borraron <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> porque no funcionaban correctamente. Vuelve a configurarlas para desbloquear el teléfono con la huella dactilar."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Ya no se puede reconocer <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Ya no se pueden reconocer <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Ya no se puede reconocer <xliff:g id="FINGERPRINT">%s</xliff:g>. Vuelve a configurar el Desbloqueo con huellas dactilares."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Ya no se pueden reconocer <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>. Vuelve a configurar el Desbloqueo con huellas dactilares."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Vuelve a configurar el Desbloqueo facial"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Se borró tu modelo de rostro porque no funcionaba correctamente. Vuelve a configurarlo para desbloquear el teléfono con el rostro."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Ya no se puede reconocer tu modelo de rostro. Vuelve a configurar el Desbloqueo facial."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurar"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ahora no"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarma para <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Cambiar de usuario"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Silenciar"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Presiona para silenciar el sonido"</string>
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 2634494..bd2a616 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1412,6 +1412,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Toca para desactivar la depuración inalámbrica."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modo de agente de prueba habilitado"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Restablece los ajustes de fábrica para inhabilitar el modo de agente de prueba."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Se ha habilitado la consola en serie"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Afecta al rendimiento. Para inhabilitarlo, comprueba el bootloader."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"MTE experimental habilitado"</string>
@@ -1436,7 +1440,7 @@
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Mostrar sobre otras aplicaciones"</string>
     <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> se muestra sobre otras aplicaciones"</string>
-    <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> se muestra sobre otras apps"</string>
+    <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> se muestra sobre otras aplicaciones"</string>
     <string name="alert_windows_notification_message" msgid="6538171456970725333">"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="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Desactivar"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Comprobando <xliff:g id="NAME">%s</xliff:g>…"</string>
@@ -1748,7 +1752,7 @@
     <string name="done_accessibility_shortcut_menu_button" msgid="3668407723770815708">"Hecho"</string>
     <string name="disable_accessibility_shortcut" msgid="5806091378745232383">"Desactivar acceso directo"</string>
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Utilizar acceso directo"</string>
-    <string name="color_inversion_feature_name" msgid="2672824491933264951">"Invertir colores"</string>
+    <string name="color_inversion_feature_name" msgid="2672824491933264951">"Inversión de colores"</string>
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Corrección de color"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo Una mano"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Atenuación extra"</string>
@@ -1756,12 +1760,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Al mantener pulsadas las teclas de volumen, se ha activado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Se han mantenido pulsadas las teclas de volumen. Se ha desactivado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Suelta las teclas de volumen. Para activar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, mantén pulsadas las dos teclas de volumen de nuevo durante 3 segundos."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Selecciona la función que se utilizará cuando toques el botón de accesibilidad:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Elige la función que se utilizará con el gesto de accesibilidad (deslizar dos dedos hacia arriba desde la parte inferior de la pantalla):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Elige la función que se utilizará con el gesto de accesibilidad (deslizar tres dedos hacia arriba desde la parte inferior de la pantalla):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Para cambiar de una función a otra, mantén pulsado el botón de accesibilidad."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Para cambiar de una función a otra, desliza hacia arriba con dos dedos y mantén pulsada la pantalla."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Para cambiar de una función a otra, desliza tres dedos hacia arriba y mantén pulsada la pantalla."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"La función se abrirá la próxima vez que toques el botón de accesibilidad"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"La función se abrirá la próxima vez que uses este acceso directo. Desliza hacia arriba con 2 dedos desde la parte inferior de la pantalla y suelta rápidamente."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La función se abrirá la próxima vez que uses este acceso directo. Desliza hacia arriba con 3 dedos desde la parte inferior de la pantalla y suelta rápidamente."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliación"</string>
     <string name="user_switched" msgid="7249833311585228097">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1984,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Llamada en curso"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando una llamada entrante"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Sin clasificar"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promociones"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Noticias"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recomendaciones"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Tú determinas la importancia de estas notificaciones."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Esto es importante por los usuarios implicados."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificación de aplicación personalizada"</string>
@@ -2193,6 +2204,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Menú de acceso directo de accesibilidad en pantalla"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Acceso directo de accesibilidad"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Cerrar pantalla de notificaciones"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menú"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Pausar/Reproducir contenido multimedia"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Cruceta: arriba"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Cruceta: abajo"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Cruceta: izquierda"</string>
@@ -2412,19 +2425,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espacio privado"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"Contenido sensible de la notificación oculto"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Contenido de la aplicación oculto en pantalla compartida por motivos de seguridad"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Contenido de la aplicación oculto en pantalla compartida por seguridad"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"Conectado automáticamente al satélite"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Puedes enviar y recibir mensajes sin una red móvil o Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abre Mensajes"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cómo funciona"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendiente..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configura Desbloqueo con huella digital de nuevo"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> no funcionaba correctamente y se ha eliminado"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> no funcionaban correctamente y se han eliminado"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> no funcionaba correctamente y se ha eliminado. Configúrala de nuevo para desbloquear el teléfono con la huella digital."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> no funcionaban correctamente y se han eliminado. Configúralas de nuevo para desbloquear el teléfono con la huella digital."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ya no puede reconocerse."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ya no pueden reconocerse."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ya no puede reconocerse. Vuelve a configurar Desbloqueo con huella digital."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> y <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ya no pueden reconocerse. Vuelve a configurar Desbloqueo con huella digital."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Configura Desbloqueo facial de nuevo"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Tu modelo facial no funcionaba correctamente y se ha eliminado. Configúralo de nuevo para desbloquear el teléfono con la cara."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Tu modelo facial ya no puede reconocerse. Vuelve a configurar Desbloqueo facial."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurar"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ahora no"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarma para <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Cambiar de usuario"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Silenciar"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Toca para silenciar el sonido"</string>
 </resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 9c9ff1b..36bca22 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Valige juhtmevaba silumise keelamiseks."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Testrakendirežiim on lubatud"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Testrakendirežiimi keelamiseks taastage tehaseseaded."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Seeriakonsool on lubatud"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"See mõjutab toimivust. Keelamiseks kontrollige käivituslaadurit."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Katseline MTE on lubatud"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati sisse."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati välja."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Vabastage helitugevuse klahvid. Teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> sisselülitamiseks vajutage uuesti mõlemat helitugevuse klahvi ja hoidke neid 3 sekundit all."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Valige, millist funktsiooni kasutada, kui vajutate juurdepääsetavuse nuppu:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Valige, millist funktsiooni juurdepääsetavuse liigutusega (kahe sõrmega ekraanikuval alt üles pühkimine) kasutada:"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Valige, millist funktsiooni juurdepääsetavuse liigutusega (kolme sõrmega ekraanikuval alt üles pühkimine) kasutada:"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Funktsioonide vahel vahetamiseks vajutage juurdepääsetavuse nuppu pikalt."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Funktsioonide vahel vahetamiseks pühkige kahe sõrmega üles ja hoidke."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Funktsioonide vahel vahetamiseks pühkige kolme sõrmega üles ja hoidke."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funktsioon avaneb järgmine kord, kui puudutate juurdepääsetavuse nuppu"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funktsioon avaneb järgmine kord, kui kasutate seda otseteed. Tõmmake kahe sõrmega ekraani allservast üles ja vabastage kiiresti."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funktsioon avaneb järgmine kord, kui kasutate seda otseteed. Tõmmake kolme sõrmega ekraani allservast üles ja vabastage kiiresti."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Suurendus"</string>
     <string name="user_switched" msgid="7249833311585228097">"Praegune kasutaja <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Üleminek kasutajale <xliff:g id="NAME">%1$s</xliff:g> ..."</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Käimasolev kõne"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Sissetuleva kõne filtreerimine"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Kategoriseerimata"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Kampaaniad"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Suhtlus"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Uudised"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Soovitused"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Teie määrasite nende märguannete tähtsuse."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"See on tähtis osalevate inimeste tõttu."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Rakenduse kohandatud märguanne"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekraanil kuvatav juurdepääsetavuse otsetee valija"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Juurdepääsetavuse otsetee"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Loobu märguandealast"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menüü"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Meedia esitamine/peatamine"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Suunaklahvistiku ülesnool"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Suunaklahvistiku allanool"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Suunaklahvistiku vasaknool"</string>
@@ -2411,19 +2424,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Privaatne ruum"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"Märguande delikaatne sisu peideti"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Rakenduse sisu on ekraani jagamises turvalisuse huvides peidetud"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Rakenduse sisu on ekraani jagamisel turvalisuse huvides peidetud"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"Satelliidiga loodi automaatselt ühendus"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Teil on võimalik sõnumeid saata ja vastu võtta ilma mobiilside- ja WiFi-võrguta"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ava rakendus Messages"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Tööpõhimõtted"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Ootel …"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Seadistage sõrmejäljega avamine uuesti"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ei töötanud hästi ja kustutati"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ei töötanud hästi ning kustutati"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ei töötanud hästi ja kustutati. Telefoni sõrmejäljega avamiseks seadistage see uuesti."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ei töötanud hästi ning kustutati. Telefoni sõrmejäljega avamiseks seadistage need uuesti."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Sõrmejälge <xliff:g id="FINGERPRINT">%s</xliff:g> ei saa enam tuvastada."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Sõrmejälgi <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ei saa enam tuvastada."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Sõrmejälge <xliff:g id="FINGERPRINT">%s</xliff:g> ei saa enam tuvastada. Seadistage sõrmejäljega avamine uuesti."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Sõrmejälgi <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ei saa enam tuvastada. Seadistage sõrmejäljega avamine uuesti."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Seadistage näoga avamine uuesti"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Teie näomudel ei töötanud hästi ja kustutati. Telefoni näoga avamiseks seadistage see uuesti."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Teie näomudelit ei saa enam tuvastada. Seadistage näoga avamine uuesti."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Seadista"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Mitte praegu"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Äratus kasutajale <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Vaheta kasutajat"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Vaigista"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Puudutage heli vaigistamiseks"</string>
 </resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index d2f77eb..a16c56b 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -270,7 +270,7 @@
     <string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Txosten dinamikoa"</string>
     <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Aukera hau erabili beharko zenuke ia beti. Txostenaren jarraipena egin ahal izango duzu eta arazoari buruzko xehetasunak eman ahal izango dituzu. Baliteke gutxitan erabili behar izaten diren atalak ez agertzea, denbora aurrezteko."</string>
     <string name="bugreport_option_full_title" msgid="7681035745950045690">"Txosten osoa"</string>
-    <string name="bugreport_option_full_summary" msgid="1975130009258435885">"Erabili aukera hau sisteman ahalik eta traba gutxien eragiteko gailuak erantzuten ez duenean, mantsoegi dabilenean edo txosteneko atal guztiak behar dituzunean. Ez dizu uzten xehetasun gehiago idazten, ezta beste pantaila-argazkirik ateratzen ere."</string>
+    <string name="bugreport_option_full_summary" msgid="1975130009258435885">"Erabili aukera hau sistemaren interferentzia ahalik eta txikiena izateko gailuak erantzuten ez duenean, mantsoegi dabilenean edo txosteneko atal guztiak behar dituzunean. Ez dizu uzten xehetasun gehiago idazten, ezta beste pantaila-argazkirik ateratzen ere."</string>
     <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{Akatsen txostenerako argazkia aterako da # segundo barru.}other{Akatsen txostenerako argazkia aterako da # segundo barru.}}"</string>
     <string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"Pantaila-argazkia egin da akatsen txostenarekin"</string>
     <string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"Ezin izan da egin pantaila-argazkia akatsen txostenarekin"</string>
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Hautatu hau hari gabeko arazketa desgaitzeko."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Proba-materialeko modua gaitu da"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Proba-materialaren modua desgaitzeko, berrezarri jatorrizko datuak."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Serie-kontsola gaituta"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Errendimenduari eragiten dio. Desgaitzeko, joan abiarazlera."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"MTE esperimentala gaituta dago"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktibatu egin da."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desaktibatu egin da."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Askatu bolumen-botoiak. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktibatzeko, eduki sakatuta berriro bi bolumen-botoiak hiru segundoz."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Aukeratu zein eginbide erabili nahi duzun Erabilerraztasuna botoia sakatzean:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Aukeratu zein eginbide erabili nahi duzun erabilerraztasun-keinuarekin (hau da, bi hatz pantailaren behealdetik gora pasatzean):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Aukeratu zein eginbide erabili nahi duzun erabilerraztasun-keinuarekin (hau da, hiru hatz pantailaren behealdetik gora pasatzean):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Eginbide batetik bestera aldatzeko, eduki sakatuta Erabilerraztasuna botoia."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Eginbide batetik bestera aldatzeko, pasatu bi hatz pantailaren behealdetik gora eta eduki sakatuta une batez."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Eginbide batetik bestera aldatzeko, pasatu hiru hatz pantailaren behealdetik gora eta eduki sakatuta une batez."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Erabilerraztasuna botoia sakatzen duzun hurrengoan irekiko da eginbidea"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Lasterbidea erabiltzen duzun hurrengoan irekiko da eginbidea. Pasatu 2 hatz pantailaren behealdetik gorantz eta askatu bizkor."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Lasterbidea erabiltzen duzun hurrengoan irekiko da eginbidea. Pasatu 3 hatz pantailaren behealdetik gorantz eta askatu bizkor."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Lupa"</string>
     <string name="user_switched" msgid="7249833311585228097">"Erabiltzailea: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"\"<xliff:g id="NAME">%1$s</xliff:g>\" erabiltzailera aldatzen…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Deia abian da"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Sarrerako dei bat bistaratzen"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Kategoriarik gabea"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promozioak"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Sare sozialak"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Albisteak"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Gomendioak"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Zuk ezarri duzu jakinarazpen hauen garrantzia."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Garrantzitsua da eragiten dien pertsonengatik."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Aplikazio-jakinarazpen pertsonalizatua"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Pantailako erabilerraztasun-lasterbideen hautatzailea"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Erabilerraztasun-lasterbidea"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Baztertu jakinarazpenen panela"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menua"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Erreproduzitu/Pausatu multimedia-elementua"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Norabide-kontrolagailuko goiko botoia"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Norabide-kontrolagailuko beheko botoia"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Norabide-kontrolagailuko ezkerreko botoia"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Nola funtzionatzen du?"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Zain…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfiguratu berriro hatz-marka bidez desblokeatzeko eginbidea"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ezabatu egin da, ez zuelako ondo funtzionatzen"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> eta <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ezabatu egin dira, ez zutelako ondo funtzionatzen"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ezabatu egin da, ez zuelako ondo funtzionatzen. Telefonoa hatz-markarekin desblokeatzeko, konfigura ezazu berriro."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> eta <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ezabatu egin dira, ez zutelako ondo funtzionatzen. Telefonoa hatz-markarekin desblokeatzeko, konfigura itzazu berriro."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ez da ezagutzen jada."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> eta <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ez dira ezagutzen jada."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ez da ezagutzen jada. Konfiguratu berriro hatz-marka bidez desblokeatzeko eginbidea."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> eta <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ez dira ezagutzen jada. Konfiguratu berriro hatz-marka bidez desblokeatzeko eginbidea."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Konfiguratu berriro aurpegi bidez desblokeatzeko eginbidea"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Aurpegi-eredua ezabatu egin da, ez zuelako ondo funtzionatzen. Telefonoa aurpegiarekin desblokeatzeko, konfigura ezazu berriro."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Zure aurpegi-eredua ez da ezagutzen jada. Konfiguratu berriro aurpegi bidez desblokeatzeko eginbidea."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Konfiguratu"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Orain ez"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> erabiltzailearentzako alarma"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Aldatu erabiltzailea"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Desaktibatu audioa"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Sakatu audioa desaktibatzeko"</string>
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index d761c8a..3eeb781 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -82,7 +82,7 @@
     <string name="RestrictedStateContent" msgid="7693575344608618926">"شرکت مخابراتی شما موقتاً آن را خاموش کرده است"</string>
     <string name="RestrictedStateContentMsimTemplate" msgid="5228235722511044687">"شرکت مخابراتی‌تان موقتاً آن را برای سیم‌کارت <xliff:g id="SIMNUMBER">%d</xliff:g> خاموش کرده است"</string>
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"شبکه تلفن همراه دردسترس نیست"</string>
-    <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"تغییر شبکه ترجیحی را امتحان کنید. برای تغییر، ضربه بزنید."</string>
+    <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"تغییر شبکه ترجیحی را امتحان کنید. برای تغییر، تک‌ضرب بزنید."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"تماس اضطراری امکان‌پذیر نیست"</string>
     <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"برای برقراری تماس اضطراری به شبکه تلفن همراه نیاز دارید"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"هشدارها"</string>
@@ -204,7 +204,7 @@
     <string name="private_space_deleted_by_admin" msgid="1484365588862066939">"فضای خصوصی حذف شد"</string>
     <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"سازمان شما اجازه نمی‌دهد در این دستگاه مدیریت‌شده فضای خصوصی وجود داشته باشد."</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"دستگاه مدیریت می‌شود"</string>
-    <string name="network_logging_notification_text" msgid="1327373071132562512">"سازمانتان این دستگاه را مدیریت می‌کند و ممکن است ترافیک شبکه را پایش کند. برای اطلاع از جزئیات، ضربه بزنید."</string>
+    <string name="network_logging_notification_text" msgid="1327373071132562512">"سازمانتان این دستگاه را مدیریت می‌کند و ممکن است ترافیک شبکه را پایش کند. برای اطلاع از جزئیات، تک‌ضرب بزنید."</string>
     <string name="location_changed_notification_title" msgid="3620158742816699316">"برنامه‌ها می‌توانند به مکانتان دسترسی پیدا کنند"</string>
     <string name="location_changed_notification_text" msgid="7158423339982706912">"برای کسب اطلاعات بیشتر با سرپرست فناوری اطلاعات تماس بگیرید"</string>
     <string name="geofencing_service" msgid="3826902410740315456">"سرویس حصارکشی جغرافیایی"</string>
@@ -309,7 +309,7 @@
     <string name="notification_channel_display" msgid="6905032605735615090">"نمایشگر"</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_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">"‏سیستم Android"</string>
@@ -356,7 +356,7 @@
     <string name="capability_title_canControlMagnification" msgid="7701572187333415795">"کنترل درشت‌نمایی نمایشگر"</string>
     <string name="capability_desc_canControlMagnification" msgid="2206586716709254805">"موقعیت و سطح بزرگ‌نمایی نمایشگر را کنترل کنید."</string>
     <string name="capability_title_canPerformGestures" msgid="9106545062106728987">"اجرای اشاره‌ها"</string>
-    <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"می‌توانید ضربه بزنید، انگشتتان را تند بکشید، انگشتانتان را به هم نزدیک یا از هم دور کنید و اشاره‌های دیگری اجرا کنید."</string>
+    <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"می‌توانید تک‌ضرب بزنید، انگشتتان را تند بکشید، انگشتانتان را به هم نزدیک یا از هم دور کنید و اشاره‌های دیگری اجرا کنید."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"اشاره‌های اثر انگشت"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"می‌تواند اشاره‌های اجرا‌شده روی حسگر اثرانگشت دستگاه را ثبت کند."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"گرفتن نماگرفت"</string>
@@ -701,7 +701,7 @@
     <string name="alternative_fp_setup_notification_content" msgid="7454096947415721639">"وقتی چهره‌تان تشخیص داده نمی‌شود، مثل زمانی که نور کافی نیست، از «قفل‌گشایی با اثر انگشت» استفاده کنید"</string>
     <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_recalibrate_notification_content" msgid="3064513770251355594">"برای حذف مدل چهره‌تان تک‌ضرب بزنید، سپس چهره‌تان را دوباره اضافه کنید"</string>
     <string name="face_sensor_privacy_enabled" msgid="7407126963510598508">"‏برای استفاده از «قفل‌گشایی با چهره»، "<b>"دسترسی به دوربین"</b>" را در «تنظیمات &gt; حریم خصوصی» روشن کنید"</string>
     <string name="fingerprint_recalibrate_notification_name" msgid="1414578431898579354">"قفل‌گشایی با اثر انگشت"</string>
     <string name="fingerprint_recalibrate_notification_title" msgid="2406561052064558497">"امکان استفاده از حسگر اثر انگشت وجود ندارد"</string>
@@ -847,7 +847,7 @@
     <string name="policydesc_resetPassword" msgid="4626419138439341851">"قفل صفحه را تغییر می‌دهد."</string>
     <string name="policylab_forceLock" msgid="7360335502968476434">"قفل کردن صفحه"</string>
     <string name="policydesc_forceLock" msgid="1008844760853899693">"نحوه و زمان قفل شدن صفحه را کنترل می‌کند."</string>
-    <string name="policylab_wipeData" msgid="1359485247727537311">"پاک کردن تمام داده‌ها"</string>
+    <string name="policylab_wipeData" msgid="1359485247727537311">"پاک کردن همه داده‌ها"</string>
     <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"با انجام بازنشانی داده‌های کارخانه، داده‌های رایانهٔ لوحی بدون هشدار پاک می‌شود."</string>
     <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"‏داده‌های دستگاه Android TV شما، بدون نشان داده شدن هشدار و با انجام بازنشانی داده‌های کارخانه، پاک می‌شود."</string>
     <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"داده‌های سیستم اطلاعات-سرگرمی بدون هشدار و با انجام بازنشانی داده‌های کارخانه پاک می‌شود."</string>
@@ -986,7 +986,7 @@
     <string name="keyguard_password_enter_puk_code" msgid="3112256684547584093">"‏PUK و پین کد جدید را تایپ کنید"</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="2825313071899938305">"‏کد PUK"</string>
     <string name="keyguard_password_enter_pin_prompt" msgid="5505434724229581207">"پین کد جدید"</string>
-    <string name="keyguard_password_entry_touch_hint" msgid="4032288032993261520"><font size="17">"برای تایپ گذرواژه ضربه بزنید"</font></string>
+    <string name="keyguard_password_entry_touch_hint" msgid="4032288032993261520"><font size="17">"برای تایپ گذرواژه تک‌ضرب بزنید"</font></string>
     <string name="keyguard_password_enter_password_code" msgid="2751130557661643482">"برای بازکردن قفل، گذرواژه را وارد کنید"</string>
     <string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"برای بازکردن قفل، پین را تایپ کنید"</string>
     <string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"پین کد اشتباه است."</string>
@@ -1198,7 +1198,7 @@
     <string name="low_internal_storage_view_text" msgid="8172166728369697835">"برخی از عملکردهای سیستم ممکن است کار نکنند"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"فضای ذخیره‌سازی سیستم کافی نیست. اطمینان حاصل کنید که دارای ۲۵۰ مگابایت فضای خالی هستید و سیستم را راه‌اندازی مجدد کنید."</string>
     <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="app_running_notification_text" msgid="5120815883400228566">"برای کسب اطلاعات بیشتر یا توقف برنامه تک‌ضرب بزنید."</string>
     <string name="ok" msgid="2646370155170753815">"تأیید"</string>
     <string name="cancel" msgid="6908697720451760115">"لغو"</string>
     <string name="yes" msgid="9069828999585032361">"تأیید"</string>
@@ -1289,15 +1289,15 @@
     <string name="android_preparing_apk" msgid="589736917792300956">"آماده‌سازی <xliff:g id="APPNAME">%1$s</xliff:g>."</string>
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"درحال آغاز کردن برنامه‌ها."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"درحال اتمام راه‌اندازی."</string>
-    <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"دکمه روشن/خاموش را فشار دادید — این کار معمولاً صفحه‌نمایش را خاموش می‌کند.\n\nهنگام راه‌اندازی اثر انگشت، آرام ضربه بزنید."</string>
+    <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"دکمه روشن/خاموش را فشار دادید — این کار معمولاً صفحه‌نمایش را خاموش می‌کند.\n\nهنگام راه‌اندازی اثر انگشت، آرام تک‌ضرب بزنید."</string>
     <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"برای اتمام راه‌اندازی، صفحه را خاموش کنید"</string>
     <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"خاموش کردن"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"تأیید اثر انگشت را ادامه می‌دهید؟"</string>
-    <string name="fp_power_button_bp_message" msgid="2983163038168903393">"دکمه روشن/خاموش را فشار دادید — این کار معمولاً صفحه‌نمایش را خاموش می‌کند.\n\nبرای تأیید اثر انگشتتان، آرام ضربه بزنید."</string>
+    <string name="fp_power_button_bp_message" msgid="2983163038168903393">"دکمه روشن/خاموش را فشار دادید — این کار معمولاً صفحه‌نمایش را خاموش می‌کند.\n\nبرای تأیید اثر انگشتتان، آرام تک‌ضرب بزنید."</string>
     <string name="fp_power_button_bp_positive_button" msgid="728945472408552251">"خاموش کردن صفحه"</string>
     <string name="fp_power_button_bp_negative_button" msgid="3971364246496775178">"ادامه"</string>
     <string name="heavy_weight_notification" msgid="8382784283600329576">"<xliff:g id="APP">%1$s</xliff:g> در حال اجرا"</string>
-    <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"برای برگشتن به بازی، ضربه بزنید"</string>
+    <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"برای برگشتن به بازی، تک‌ضرب بزنید"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"انتخاب بازی"</string>
     <string name="heavy_weight_switcher_text" msgid="6814316627367160126">"برای عملکرد بهتر، هربار فقط یکی از این بازی‌ها را می‌توان باز کرد."</string>
     <string name="old_app_action" msgid="725331621042848590">"به <xliff:g id="OLD_APP">%1$s</xliff:g> برگردید"</string>
@@ -1305,19 +1305,19 @@
     <string name="new_app_description" msgid="1958903080400806644">"<xliff:g id="OLD_APP">%1$s</xliff:g> بدون ذخیره شدن بسته می‌شود"</string>
     <string name="dump_heap_notification" msgid="5316644945404825032">"<xliff:g id="PROC">%1$s</xliff:g> از حد مجاز حافظه فراتر رفت"</string>
     <string name="dump_heap_ready_notification" msgid="2302452262927390268">"رونوشت حافظه آزاد<xliff:g id="PROC">%1$s</xliff:g> آماده است"</string>
-    <string name="dump_heap_notification_detail" msgid="8431586843001054050">"رونوشت حافظه جمع‌آوری شد. برای هم‌رسانی ضربه بزنید."</string>
+    <string name="dump_heap_notification_detail" msgid="8431586843001054050">"رونوشت حافظه جمع‌آوری شد. برای هم‌رسانی تک‌ضرب بزنید."</string>
     <string name="dump_heap_title" msgid="4367128917229233901">"رونوشت حافظه آزاد به اشتراک گذاشته شود؟"</string>
     <string name="dump_heap_text" msgid="1692649033835719336">"فرآیند <xliff:g id="PROC">%1$s</xliff:g> از حد مجاز حافظه پردازش خود،<xliff:g id="SIZE">%2$s</xliff:g>، فراتر رفته است. رونوشت حافظه آزادی دردسترستان است که با برنامه‌نویس آن به اشتراک بگذارید. مراقب باشید: این رونوشت حافظه آزاد می‌تواند حاوی هرنوع اطلاعات شخصی‌ شما باشد که برنامه به آن دسترسی دارد."</string>
     <string name="dump_heap_system_text" msgid="6805155514925350849">"فرآیند <xliff:g id="PROC">%1$s</xliff:g> از حد مجاز حافظه پردازش خود <xliff:g id="SIZE">%2$s</xliff:g> فراتر رفته است. یک رونوشت حافظه آزاد برای شما برای هم‌رسانی دردسترس است. مواظب باشید: این رونوشت حافظه آزاد می‌تواند حاوی هر نوع اطلاعات شخصی شما باشد که فرآیند به آن دسترسی دارد که ممکن است شامل چیزهایی باشد که تایپ کرده‌اید."</string>
     <string name="dump_heap_ready_text" msgid="5849618132123045516">"رونوشت حافظه آزاد فرآیند<xliff:g id="PROC">%1$s</xliff:g> برای هم‌رسانی دردسترس شما قرار دارد. مراقب باشید: ممکن است این رونوشت حافظه آزاد حاوی اطلاعات شخصی حساس باشد که فرآیند به آن دسترسی دارد و ممکن است شامل چیزهایی باشد که تایپ کرده‌اید."</string>
     <string name="sendText" msgid="493003724401350724">"انتخاب یک عملکرد برای نوشتار"</string>
-    <string name="volume_ringtone" msgid="134784084629229029">"میزان صدای زنگ"</string>
+    <string name="volume_ringtone" msgid="134784084629229029">"صدای زنگ"</string>
     <string name="volume_music" msgid="7727274216734955095">"میزان صدای رسانه"</string>
     <string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"پخش از طریق بلوتوث"</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>
+    <string name="volume_alarm" msgid="4486241060751798448">"صدای زنگ هشدار"</string>
     <string name="volume_notification" msgid="6864412249031660057">"میزان صدای اعلان"</string>
     <string name="volume_unknown" msgid="4041914008166576293">"میزان صدا"</string>
     <string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"میزان صدای بلوتوث"</string>
@@ -1337,12 +1337,12 @@
     <!-- no translation found for network_available_sign_in_detailed (7520423801613396556) -->
     <skip />
     <string name="wifi_no_internet" msgid="1386911698276448061">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> به اینترنت دسترسی ندارد"</string>
-    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"برای گزینه‌ها ضربه بزنید"</string>
+    <string name="wifi_no_internet_detailed" msgid="634938444133558942">"برای گزینه‌ها تک‌ضرب بزنید"</string>
     <string name="mobile_no_internet" msgid="4014455157529909781">"شبکه تلفن همراه به اینترنت دسترسی ندارد"</string>
     <string name="other_networks_no_internet" msgid="6698711684200067033">"شبکه به اینترنت دسترسی ندارد"</string>
     <string name="private_dns_broken_detailed" msgid="3709388271074611847">"‏سرور DNS خصوصی قابل دسترسی نیست"</string>
     <string name="network_partial_connectivity" msgid="4791024923851432291">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> اتصال محدودی دارد"</string>
-    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"به‌هرصورت، برای اتصال ضربه بزنید"</string>
+    <string name="network_partial_connectivity_detailed" msgid="5741329444564575840">"به‌هرصورت، برای اتصال تک‌ضرب بزنید"</string>
     <string name="network_switch_metered" msgid="1531869544142283384">"به <xliff:g id="NETWORK_TYPE">%1$s</xliff:g> تغییر کرد"</string>
     <string name="network_switch_metered_detail" msgid="1358296010128405906">"وقتی <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> به اینترنت دسترسی نداشته باشد، دستگاه از <xliff:g id="NEW_NETWORK">%1$s</xliff:g> استفاده می‌کند. ممکن است هزینه‌هایی اعمال شود."</string>
     <string name="network_switch_metered_toast" msgid="501662047275723743">"از <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> به <xliff:g id="NEW_NETWORK">%2$s</xliff:g> تغییر کرد"</string>
@@ -1381,7 +1381,7 @@
     <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"برای فعال کردن سیم‌کارت جدیدتان، برنامه <xliff:g id="APP_NAME">%1$s</xliff:g> را بارگیری کنید"</string>
     <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"بارگیری برنامه"</string>
     <string name="carrier_app_notification_title" msgid="5815477368072060250">"سیم‌کارت جدید جاگذاری شد"</string>
-    <string name="carrier_app_notification_text" msgid="6567057546341958637">"برای تنظیم آن ضربه بزنید"</string>
+    <string name="carrier_app_notification_text" msgid="6567057546341958637">"برای تنظیم آن تک‌ضرب بزنید"</string>
     <string name="time_picker_dialog_title" msgid="9053376764985220821">"تنظیم زمان"</string>
     <string name="date_picker_dialog_title" msgid="5030520449243071926">"تاریخ تنظیم"</string>
     <string name="date_time_set" msgid="4603445265164486816">"تنظیم"</string>
@@ -1399,24 +1399,28 @@
     <string name="usb_midi_notification_title" msgid="7404506788950595557">"‏MIDI ازطریق USB روشن شد"</string>
     <string name="usb_uvc_notification_title" msgid="2030032862673400008">"دستگاه به‌عنوان «وب‌بین» متصل شده است"</string>
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"‏وسیله جانبی USB متصل است"</string>
-    <string name="usb_notification_message" msgid="4715163067192110676">"برای گزینه‌های بیشتر ضربه بزنید."</string>
-    <string name="usb_power_notification_message" msgid="7284765627437897702">"درحال شارژ کردن دستگاه متصل‌‌شده. برای گزینه‌های بیشتر، ضربه بزنید."</string>
+    <string name="usb_notification_message" msgid="4715163067192110676">"برای گزینه‌های بیشتر تک‌ضرب بزنید."</string>
+    <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="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_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>
+    <string name="adbwifi_active_notification_message" msgid="930987922852867972">"برای خاموش کردن اشکال‌زدایی بی‌سیم تک‌ضرب بزنید"</string>
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"برای غیرفعال کردن اشکال‌زدایی بی‌سیم انتخاب کنید."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"«حالت مجموعه داده‌های تست» فعال شد"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"برای غیرفعال کردن «حالت مجموعه داده‌های تست»، بازنشانی کارخانه‌ای کنید."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"کنسول سریال فعال است"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"‏عملکرد تحت‌تأثیر قرار گرفته است. برای غیرفعال کردن، bootloader را بررسی کنید."</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>
-    <string name="usb_contaminant_detected_message" msgid="7346100585390795743">"‏درگاه USB به‌طور خودکار غیرفعال شده است. برای اطلاعات بیشتر، ضربه بزنید."</string>
+    <string name="usb_contaminant_detected_message" msgid="7346100585390795743">"‏درگاه USB به‌طور خودکار غیرفعال شده است. برای اطلاعات بیشتر، تک‌ضرب بزنید."</string>
     <string name="usb_contaminant_not_detected_title" msgid="2651167729563264053">"‏می‌توان از درگاه USB استفاده کرد"</string>
     <string name="usb_contaminant_not_detected_message" msgid="892863190942660462">"تلفن دیگر وجود مایعات یا خاکروبه را تشخیص نمی‌دهد."</string>
     <string name="taking_remote_bugreport_notification_title" msgid="1582531382166919850">"درحال گرفتن گزارش اشکال…"</string>
@@ -1430,7 +1434,7 @@
     <string name="hardware" msgid="3611039921284836033">"استفاده از صفحه‌کلید مجازی"</string>
     <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"پیکربندی <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
     <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"پیکربندی صفحه‌کلیدهای فیزیکی"</string>
-    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"برای انتخاب زبان و چیدمان ضربه بزنید"</string>
+    <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"برای انتخاب زبان و چیدمان تک‌ضرب بزنید"</string>
     <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"نمایش روی سایر برنامه‌ها"</string>
@@ -1443,19 +1447,19 @@
     <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>
     <string name="ext_media_new_notification_title" product="automotive" msgid="9085349544984742727">"<xliff:g id="NAME">%s</xliff:g> کار نمی‌کند"</string>
-    <string name="ext_media_new_notification_message" msgid="6095403121990786986">"برای راه‌اندازی ضربه بزنید"</string>
+    <string name="ext_media_new_notification_message" msgid="6095403121990786986">"برای راه‌اندازی تک‌ضرب بزنید"</string>
     <string name="ext_media_new_notification_message" product="tv" msgid="216863352100263668">"برای راه‌اندازی، انتخاب کنید"</string>
-    <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"شاید لازم باشد دستگاه را دوباره قالب‌بندی کنید. برای خارج کردن، ضربه بزنید."</string>
+    <string name="ext_media_new_notification_message" product="automotive" msgid="5140127881613227162">"شاید لازم باشد دستگاه را دوباره قالب‌بندی کنید. برای خارج کردن، تک‌ضرب بزنید."</string>
     <string name="ext_media_ready_notification_message" msgid="7509496364380197369">"برای ذخیره کردن عکس، ویدیو، موسیقی و غیره"</string>
     <string name="ext_media_ready_notification_message" product="tv" msgid="8847134811163165935">"فایل‌های رسانه‌ای را مرور کنید"</string>
     <string name="ext_media_unmountable_notification_title" msgid="4895444667278979910">"مشکل مرتبط با <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_unmountable_notification_title" product="automotive" msgid="3142723758949023280">"<xliff:g id="NAME">%s</xliff:g> کار نمی‌کند"</string>
-    <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"برای برطرف کردن مشکل، ضربه بزنید"</string>
+    <string name="ext_media_unmountable_notification_message" msgid="3256290114063126205">"برای برطرف کردن مشکل، تک‌ضرب بزنید"</string>
     <string name="ext_media_unmountable_notification_message" product="tv" msgid="3003611129979934633">"<xliff:g id="NAME">%s</xliff:g> خراب است. رفع خطا را انتخاب کنید."</string>
-    <string name="ext_media_unmountable_notification_message" product="automotive" msgid="2274596120715020680">"شاید لازم باشد دستگاه را دوباره قالب‌بندی کنید. برای خارج کردن، ضربه بزنید."</string>
+    <string name="ext_media_unmountable_notification_message" product="automotive" msgid="2274596120715020680">"شاید لازم باشد دستگاه را دوباره قالب‌بندی کنید. برای خارج کردن، تک‌ضرب بزنید."</string>
     <string name="ext_media_unsupported_notification_title" msgid="3487534182861251401">"<xliff:g id="NAME">%s</xliff:g> تشخیص داده شد"</string>
     <string name="ext_media_unsupported_notification_title" product="automotive" msgid="6004193172658722381">"<xliff:g id="NAME">%s</xliff:g> کار نمی‌کند"</string>
-    <string name="ext_media_unsupported_notification_message" msgid="8463636521459807981">"برای راه‌اندازی ضربه بزنید."</string>
+    <string name="ext_media_unsupported_notification_message" msgid="8463636521459807981">"برای راه‌اندازی تک‌ضرب بزنید."</string>
     <string name="ext_media_unsupported_notification_message" product="tv" msgid="1595482802187036532">"برای راه‌اندازی <xliff:g id="NAME">%s</xliff:g> در قالب پشتیبانی‌شده، انتخاب کنید."</string>
     <string name="ext_media_unsupported_notification_message" product="automotive" msgid="3412494732736336330">"شاید لازم باشد دستگاه را دوباره قالب‌بندی کنید"</string>
     <string name="ext_media_badremoval_notification_title" msgid="4114625551266196872">"<xliff:g id="NAME">%s</xliff:g> به‌طور غیرمنتظره جدا شد"</string>
@@ -1500,7 +1504,7 @@
     <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"به یک برنامه اجازه می‌دهد جهت نادیده گرفتن بهینه‌سازی باتری برای خود مجوز درخواست کند."</string>
     <string name="permlab_queryAllPackages" msgid="2928450604653281650">"پُرسمان همه بسته‌ها"</string>
     <string name="permdesc_queryAllPackages" msgid="5339069855520996010">"به برنامه اجازه می‌دهد همه بسته‌های نصب‌شده را ببیند."</string>
-    <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"برای کنترل بزرگ‌نمایی، دو بار ضربه بزنید"</string>
+    <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"برای کنترل بزرگ‌نمایی، دو بار تک‌ضرب بزنید"</string>
     <string name="gadget_host_error_inflating" msgid="2449961590495198720">"افزودن ابزارک انجام نشد."</string>
     <string name="ime_action_go" msgid="5536744546326495436">"برو"</string>
     <string name="ime_action_search" msgid="4501435960587287668">"جستجو"</string>
@@ -1532,8 +1536,8 @@
     <string name="notification_ranker_binding_label" msgid="432708245635563763">"سرویس رده‌بندی اعلان"</string>
     <string name="vpn_title" msgid="5906991595291514182">"‏VPN فعال شد"</string>
     <string name="vpn_title_long" msgid="6834144390504619998">"‏VPN را <xliff:g id="APP">%s</xliff:g> فعال کرده است"</string>
-    <string name="vpn_text" msgid="2275388920267251078">"برای مدیریت شبکه ضربه بزنید."</string>
-    <string name="vpn_text_long" msgid="278540576806169831">"به <xliff:g id="SESSION">%s</xliff:g> متصل شد. برای مدیریت شبکه ضربه بزنید."</string>
+    <string name="vpn_text" msgid="2275388920267251078">"برای مدیریت شبکه تک‌ضرب بزنید."</string>
+    <string name="vpn_text_long" msgid="278540576806169831">"به <xliff:g id="SESSION">%s</xliff:g> متصل شد. برای مدیریت شبکه تک‌ضرب بزنید."</string>
     <string name="vpn_lockdown_connecting" msgid="6096725311950342607">"‏درحال اتصال به VPN همیشه روشن…"</string>
     <string name="vpn_lockdown_connected" msgid="2853127976590658469">"‏VPN همیشه روشن متصل شد"</string>
     <string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"‏از «VPN همیشه روشن» قطع شد"</string>
@@ -1544,7 +1548,7 @@
     <string name="reset" msgid="3865826612628171429">"بازنشانی"</string>
     <string name="submit" msgid="862795280643405865">"ارسال"</string>
     <string name="car_mode_disable_notification_title" msgid="8450693275833142896">"برنامه رانندگی درحال اجرا است"</string>
-    <string name="car_mode_disable_notification_message" msgid="8954550232288567515">"برای خروج از برنامه رانندگی ضربه بزنید."</string>
+    <string name="car_mode_disable_notification_message" msgid="8954550232288567515">"برای خروج از برنامه رانندگی تک‌ضرب بزنید."</string>
     <string name="back_button_label" msgid="4078224038025043387">"برگشت"</string>
     <string name="next_button_label" msgid="6040209156399907780">"بعدی"</string>
     <string name="skip_button_label" msgid="3566599811326688389">"رد شدن"</string>
@@ -1623,7 +1627,7 @@
     <string name="data_usage_wifi_limit_snoozed_title" msgid="1622359254521960508">"‏بیش‌از حدمجاز داده Wi-Fi"</string>
     <string name="data_usage_limit_snoozed_body" msgid="545146591766765678">"مصرف داده شما <xliff:g id="SIZE">%s</xliff:g> از حداکثر مجاز بیشتر شده است"</string>
     <string name="data_usage_restricted_title" msgid="126711424380051268">"داده پس‌زمینه محدود شد"</string>
-    <string name="data_usage_restricted_body" msgid="5338694433686077733">"برای برداشتن محدودیت ضربه بزنید."</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>
@@ -1739,7 +1743,7 @@
     <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"مجاز نبودن"</string>
     <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"حذف نصب"</string>
     <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"پاسخ شما تأیید نشد زیرا یک برنامه درخواست اجازه را مسدود کرده است."</string>
-    <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"برای استفاده از ویژگی، روی آن ضربه بزنید:"</string>
+    <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"برای استفاده از ویژگی، روی آن تک‌ضرب بزنید:"</string>
     <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>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"کلیدهای میزان صدا پایین نگه داشته شد. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> روشن شد."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"کلیدهای میزان صدا پایین نگه داشته شد. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> خاموش شد."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"کلیدهای میزان صدا را رها کنید. برای روشن کردن <xliff:g id="SERVICE_NAME">%1$s</xliff:g>، هر دو کلید میزان صدا را مجدداً به‌مدت ۳ ثانیه فشار دهید و نگه دارید."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ویژگی را انتخاب کنید که هنگام ضربه زدن روی دکمه دسترس‌پذیری استفاده می‌شود:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ویژگی را برای استفاده با اشاره دسترس‌پذیری انتخاب کنید (با دو انگشت صفحه را از پایین تند به‌بالا بکشید):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ویزگی را برای استفاده با اشاره دسترس‌پذیری انتخاب کنید (با سه انگشت صفحه را از پایین تند به‌بالا بکشید):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"برای جابه‌جایی بین ویژگی‌ها، دکمه دسترس‌پذیری را لمس کنید و نگه دارید."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"برای جابه‌جایی بین ویژگی‌ها، با دو انگشت صفحه را تند به‌بالا بکشید و نگه دارید."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"برای جابه‌جایی بین ویژگی‌ها، با سه انگشت صفحه را تند به‌بالا بکشید و نگه دارید."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"دفعه بعد که روی دکمه دسترس‌پذیری تک‌ضرب بزنید، این ویژگی باز می‌شود"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"دفعه بعد که از این میان‌بر استفاده کنید، این ویژگی باز می‌شود. با ۲ انگشت از پایین صفحه تند به بالا بکشید و سریع رها کنید."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"دفعه بعد که از این میان‌بر استفاده کنید، این ویژگی باز می‌شود. با ۳ انگشت از پایین صفحه تند به بالا بکشید و سریع رها کنید."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"درشت‌نمایی"</string>
     <string name="user_switched" msgid="7249833311585228097">"کاربر کنونی <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"در حالت تغییر به <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1871,7 +1878,7 @@
     <string name="reason_unknown" msgid="5599739807581133337">"نامعلوم"</string>
     <string name="reason_service_unavailable" msgid="5288405248063804713">"سرویس چاپ فعال نشده است"</string>
     <string name="print_service_installed_title" msgid="6134880817336942482">"سرویس <xliff:g id="NAME">%s</xliff:g> نصب شد"</string>
-    <string name="print_service_installed_message" msgid="7005672469916968131">"برای فعال کردن ضربه بزنید"</string>
+    <string name="print_service_installed_message" msgid="7005672469916968131">"برای فعال کردن تک‌ضرب بزنید"</string>
     <string name="restr_pin_enter_admin_pin" msgid="1199419462726962697">"پین سرپرست سیستم را وارد کنید"</string>
     <string name="restr_pin_enter_pin" msgid="373139384161304555">"پین را وارد کنید"</string>
     <string name="restr_pin_incorrect" msgid="3861383632940852496">"نادرست"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"تماس درحال انجام"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"درحال غربال کردن تماس ورودی"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"دسته‌بندی‌نشده"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"تبلیغات ویژه"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"اجتماعی"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"اخبار"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"توصیه‌ها"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"شما اهمیت این اعلان‌ها را تنظیم می‌کنید."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"به دلیل افراد درگیر مهم است."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"اعلان برنامه سفارشی"</string>
@@ -2032,9 +2043,9 @@
     <string name="new_sms_notification_content" msgid="3197949934153460639">"برای مشاهده، برنامه پیامک را باز کنید"</string>
     <string name="profile_encrypted_title" msgid="9001208667521266472">"برخی از عملکردها ممکن است محدود باشند"</string>
     <string name="profile_encrypted_detail" msgid="5279730442756849055">"نمایه کاری قفل است"</string>
-    <string name="profile_encrypted_message" msgid="1128512616293157802">"برای باز کردن قفل ضربه بزنید"</string>
+    <string name="profile_encrypted_message" msgid="1128512616293157802">"برای باز کردن قفل تک‌ضرب بزنید"</string>
     <string name="usb_mtp_launch_notification_title" msgid="774319638256707227">"به <xliff:g id="PRODUCT_NAME">%1$s</xliff:g> متصل شد"</string>
-    <string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"برای دیدن فایل‌ها، ضربه بزنید"</string>
+    <string name="usb_mtp_launch_notification_description" msgid="6942535713629852684">"برای دیدن فایل‌ها، تک‌ضرب بزنید"</string>
     <string name="pin_target" msgid="8036028973110156895">"سنجاق کردن"</string>
     <string name="pin_specific_target" msgid="7824671240625957415">"سنجاق کردن <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="unpin_target" msgid="3963318576590204447">"برداشتن سنجاق"</string>
@@ -2122,11 +2133,11 @@
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"تغییرات سیستم"</string>
     <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"مزاحم نشوید"</string>
     <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_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 نسخه ۱۳ به بعد، برنامه‌هایی که نصب می‌کنید برای ارسال اعلان به اجازه شما نیاز دارند. برای تغییر دادن این اجازه در برنامه‌های موجود، ضربه بزنید."</string>
+    <string name="review_notification_settings_text" msgid="5916244866751849279">"‏از Android نسخه ۱۳ به بعد، برنامه‌هایی که نصب می‌کنید برای ارسال اعلان به اجازه شما نیاز دارند. برای تغییر دادن این اجازه در برنامه‌های موجود، تک‌ضرب بزنید."</string>
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"بعداً یادآوری شود"</string>
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"رد شدن"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"سیستم"</string>
@@ -2135,10 +2146,10 @@
     <string name="notification_appops_microphone_active" msgid="581333393214739332">"میکروفون"</string>
     <string name="notification_appops_overlay_active" msgid="5571732753262836481">"نمایش روی برنامه‌های دیگر در صفحه‌نمایش"</string>
     <string name="notification_feedback_indicator" msgid="663476517711323016">"ارائه بازخورد"</string>
-    <string name="notification_feedback_indicator_alerted" msgid="6552871804121942099">"این اعلان به «پیش‌فرض» ارتقا داده شد. برای ارائه بازخورد، ضربه بزنید."</string>
-    <string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"این اعلان به «بی‌صدا» تنزل داده شد. برای ارائه بازخورد، ضربه بزنید."</string>
-    <string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"این اعلان در رتبه بالاتری قرار گرفت. برای ارائه بازخورد، ضربه بزنید."</string>
-    <string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"این اعلان در رتبه پایین‌تری قرار گرفت. برای ارائه بازخورد، ضربه بزنید."</string>
+    <string name="notification_feedback_indicator_alerted" msgid="6552871804121942099">"این اعلان به «پیش‌فرض» ارتقا داده شد. برای ارائه بازخورد، تک‌ضرب بزنید."</string>
+    <string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"این اعلان به «بی‌صدا» تنزل داده شد. برای ارائه بازخورد، تک‌ضرب بزنید."</string>
+    <string name="notification_feedback_indicator_promoted" msgid="9030204303764698640">"این اعلان در رتبه بالاتری قرار گرفت. برای ارائه بازخورد، تک‌ضرب بزنید."</string>
+    <string name="notification_feedback_indicator_demoted" msgid="8880309924296450875">"این اعلان در رتبه پایین‌تری قرار گرفت. برای ارائه بازخورد، تک‌ضرب بزنید."</string>
     <string name="nas_upgrade_notification_title" msgid="8436359459300146555">"اعلان‌های بهبودیافته"</string>
     <string name="nas_upgrade_notification_content" msgid="5157550369837103337">"‏اکنون پاسخ‌ها و کنش‌های پیشنهادی ازطریق اعلان‌های بهبودیافته ارائه می‌شوند. «اعلان‌های تطبیقی Android» دیگر پشتیبانی نمی‌شوند."</string>
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"تأیید"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"انتخاب‌گر میان‌بر دسترس‌پذیری روی صفحه"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"میان‌بر دسترسی‌پذیری"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"رد کردن کشوی اعلانات"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"منو"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"پخش/موقتاً متوقف کردن رسانه"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"پد کنترل بالا"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"پد کنترل پایین"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"پد کنترل چپ"</string>
@@ -2353,14 +2366,14 @@
     <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>
-    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> می‌تواند صفحه‌نمایش شما را مشاهده و کنترل کند. برای مرور، ضربه بزنید."</string>
+    <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> می‌تواند صفحه‌نمایش شما را مشاهده و کنترل کند. برای مرور، تک‌ضرب بزنید."</string>
     <string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> ترجمه شد."</string>
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"پیام از <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> به <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> ترجمه شد."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"فعالیت در پس‌زمینه"</string>
     <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"برنامه‌ای شارژ باتری را خالی می‌کند"</string>
     <string name="notification_title_long_running_fgs" msgid="8170284286477131587">"یکی از برنامه‌ها همچنان فعال است"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"<xliff:g id="APP">%1$s</xliff:g> در پس‌زمینه درحال اجرا است. برای مدیریت مصرف باتری ضربه بزنید."</string>
-    <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> ممکن است بر عمر باتری تأثیر بگذارد. برای مرور برنامه‌های فعال، ضربه بزنید."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"<xliff:g id="APP">%1$s</xliff:g> در پس‌زمینه درحال اجرا است. برای مدیریت مصرف باتری تک‌ضرب بزنید."</string>
+    <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> ممکن است بر عمر باتری تأثیر بگذارد. برای مرور برنامه‌های فعال، تک‌ضرب بزنید."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"بررسی برنامه‌های فعال"</string>
     <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>
@@ -2391,12 +2404,12 @@
     <string name="device_state_notification_settings_button" msgid="691937505741872749">"رفتن به تنظیمات"</string>
     <string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"خاموش کردن"</string>
     <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"‫<xliff:g id="DEVICE_NAME">%s</xliff:g> پیکربندی شد"</string>
-    <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"جانمایی صفحه‌کلید روی <xliff:g id="LAYOUT_1">%s</xliff:g> تنظیم شد. برای تغییر دادن، ضربه بزنید."</string>
-    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"جانمایی صفحه‌کلید روی <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g> تنظیم شد. برای تغییر دادن، ضربه بزنید."</string>
-    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"جانمایی صفحه‌کلید روی <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g>، <xliff:g id="LAYOUT_3">%3$s</xliff:g> تنظیم شد. برای تغییر دادن، ضربه بزنید."</string>
-    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"جانمایی صفحه‌کلید چنین تنظیم شد: <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g>، <xliff:g id="LAYOUT_3">%3$s</xliff:g>… برای تغییر ضربه بزنید"</string>
+    <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"جانمایی صفحه‌کلید روی <xliff:g id="LAYOUT_1">%s</xliff:g> تنظیم شد. برای تغییر دادن، تک‌ضرب بزنید."</string>
+    <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"جانمایی صفحه‌کلید روی <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g> تنظیم شد. برای تغییر دادن، تک‌ضرب بزنید."</string>
+    <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"جانمایی صفحه‌کلید روی <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g>، <xliff:g id="LAYOUT_3">%3$s</xliff:g> تنظیم شد. برای تغییر دادن، تک‌ضرب بزنید."</string>
+    <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"جانمایی صفحه‌کلید چنین تنظیم شد: <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g>، <xliff:g id="LAYOUT_3">%3$s</xliff:g>… برای تغییر تک‌ضرب بزنید"</string>
     <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"صفحه‌کلیدهای فیزیکی پیکربندی شدند"</string>
-    <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"برای مشاهده صفحه‌کلیدها ضربه بزنید"</string>
+    <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"برای مشاهده صفحه‌کلیدها تک‌ضرب بزنید"</string>
     <string name="profile_label_private" msgid="6463418670715290696">"خصوصی"</string>
     <string name="profile_label_clone" msgid="769106052210954285">"همسانه‌سازی"</string>
     <string name="profile_label_work" msgid="3495359133038584618">"کار"</string>
@@ -2411,19 +2424,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"فضای خصوصی"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"محتوای اعلان حساس پنهان شده است"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"به‌دلایل امنیتی، محتوای برنامه از دید هم‌رسانی صفحه‌نمایش پنهان شد"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"به‌دلایل امنیتی، محتوای برنامه پس‌از هم‌رسانی صفحه‌نمایش پنهان می‌شود"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"به‌طور خودکار به ماهواره متصل شد"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"‏می‌توانید بدون شبکه تلفن همراه یا Wi-Fi پیام ارسال و دریافت کنید"</string>
-    <string name="satellite_notification_open_message" msgid="4149234979688273729">"باز کردن «پیام‌ها»"</string>
+    <string name="satellite_notification_open_message" msgid="4149234979688273729">"باز کردن «پیام‌نگار»"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"روش کار"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"درحال تعلیق…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"راه‌اندازی مجدد «قفل‌گشایی با اثر انگشت»"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"‫<xliff:g id="FINGERPRINT">%s</xliff:g> خوب کار نمی‌کرد و حذف شد"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"‫<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> و <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> خوب کار نمی‌کردند و حذف شدند"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> خوب کار نمی‌کرد و حذف شد. برای باز کردن قفل تلفن با اثر انگشت، آن را دوباره راه‌اندازی کنید."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"‫<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> و <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> خوب کار نمی‌کرد و حذف شد. برای باز کردن قفل تلفن با اثر انگشت، آن‌ها را دوباره راه‌اندازی کنید."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"‫<xliff:g id="FINGERPRINT">%s</xliff:g> دیگر قابل‌شناسایی نیست."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"‫<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> و <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> دیگر قابل‌شناسایی نیستند."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"‫<xliff:g id="FINGERPRINT">%s</xliff:g> دیگر قابل‌شناسایی نیست. «قفل‌گشایی با اثر انگشت» را دوباره راه‌اندازی کنید."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"‫<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> و <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> دیگر قابل‌شناسایی نیستند. «قفل‌گشایی با اثر انگشت» را دوباره راه‌اندازی کنید."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"راه‌اندازی مجدد «قفل‌گشایی با چهره»"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"مدل چهره شما خوب کار نمی‌کرد و حذف شد. برای باز کردن قفل تلفن با چهره، دوباره آن را راه‌اندازی کنید."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"مدل چهره‌تان دیگر قابل‌شناسایی نیست. «قفل‌گشایی با چهره» را دوباره راه‌اندازی کنید."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"راه‌اندازی"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"حالا نه"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"زنگ ساعت <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"تغییر کاربر"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"بی‌صدا کردن"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"برای بی‌صدا کردن تک‌ضرب بزنید"</string>
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 9a7bfff..0cb8ce0 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Poista langaton virheenkorjaus käytöstä valitsemalla tämä."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Testikehystila käytössä"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Palauta tehdasasetukset, niin voit poistaa testikehystilan käytöstä."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Sarjakonsoli käytössä"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Tämä vaikuttaa suorituskykyyn. Jos haluat poistaa toiminnon käytöstä, tarkista käynnistysohjelma."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Kokeellinen MTE käytössä"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Äänenvoimakkuuspainikkeita painettiin pitkään. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> laitettiin päälle."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Äänenvoimakkuuspainikkeita painettiin pitkään. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> laitettiin pois päältä."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Vapauta äänenvoimakkuuspainikkeet. Laita <xliff:g id="SERVICE_NAME">%1$s</xliff:g> päälle painamalla äänenvoimakkuuspainikkeita uudelleen kolmen sekunnin ajan."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Valitse ominaisuus, jonka esteettömyyspainike aktivoi:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Valitse ominaisuus, jota käytetään esteettömyyseleellä (pyyhkäise näytön alalaidasta ylös kahdella sormella):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Valitse ominaisuus, jota käytetään esteettömyyseleellä (pyyhkäise näytön alalaidasta ylös kolmella sormella):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Vaihda ominaisuuksien välillä painamalla esteettömyyspainiketta pitkään."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Vaihda ominaisuuksien välillä pyyhkäisemällä ylös kahdella sormella ja koskettamalla pitkään."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Vaihda ominaisuuksien välillä pyyhkäisemällä ylös kolmella sormella ja koskettamalla pitkään."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Ominaisuus avautuu, kun seuraavan kerran napautat saavutettavuuspainiketta"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Ominaisuus avautuu, kun seuraavan kerran käytät tätä pikakomentoa. Pyyhkäise näytön alareunasta ylös kahdella sormella ja nosta sormet näytöltä nopeasti."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Ominaisuus avautuu, kun seuraavan kerran käytät tätä pikakomentoa. Pyyhkäise näytön alareunasta ylös kolmella sormella ja nosta sormet näytöltä nopeasti."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Suurennus"</string>
     <string name="user_switched" msgid="7249833311585228097">"Nykyinen käyttäjä: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Vaihdetaan käyttäjään <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Käynnissä oleva puhelu"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Seulotaan saapuvaa puhelua"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Luokittelematon"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Tarjoukset"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Some"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Uutiset"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Suositukset"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Voit valita näiden ilmoitusten tärkeyden."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Tämä on tärkeää siihen liittyvien ihmisten perusteella."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Oma sovellusilmoitus"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Näytöllä näkyvän esteettömyyspainikkeen valitsin"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Saavutettavuuspainike"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Sulje ilmoitusalue"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Valikko"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media: toista/keskeytä"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Suuntanäppäimistö: ylös-painike"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Suuntanäppäimisto: alas-painike"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Suuntanäppäimistö: vasen painike"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Näin se toimii"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Odottaa…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ota sormenjälkiavaus uudelleen käyttöön"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ei toiminut kunnolla, ja se poistettiin"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> eivät toimineet kunnolla, ja ne poistettiin"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ei toiminut kunnolla, ja se poistettiin. Ota se uudelleen käyttöön, jotta voit avata puhelimen lukituksen sormenjäljellä."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> eivät toimineet kunnolla, ja ne poistettiin. Ota ne uudelleen käyttöön, jotta voit avata puhelimen lukituksen sormenjäljellä."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ei enää ole tunnistettavissa."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> eivät enää ole tunnistettavissa."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ei enää ole tunnistettavissa. Ota sormenjälkiavaus uudelleen käyttöön."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ja <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> eivät enää ole tunnistettavissa. Ota sormenjälkiavaus uudelleen käyttöön."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Ota kasvojentunnistusavaus uudelleen käyttöön"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Kasvomallisi ei toiminut kunnolla, ja se poistettiin. Ota se uudelleen käyttöön, jotta voit avata puhelimen lukituksen kasvoilla."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Kasvomallia ei enää tunnisteta. Ota kasvojentunnistusavaus uudelleen käyttöön."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Ota käyttöön"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ei nyt"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Hälytys: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Vaihda käyttäjää"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Mykistä"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Mykistä äänet napauttamalla"</string>
 </resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index cc56526..07cbbf1 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -198,7 +198,7 @@
     <string name="ssl_ca_cert_noti_by_administrator" msgid="4564941950768783879">"Par l\'administrateur de votre profil professionnel"</string>
     <string name="ssl_ca_cert_noti_managed" msgid="217337232273211674">"Par <xliff:g id="MANAGING_DOMAIN">%s</xliff:g>"</string>
     <string name="work_profile_deleted" msgid="5891181538182009328">"Profil professionnel supprimé"</string>
-    <string name="work_profile_deleted_details" msgid="3773706828364418016">"Le profil professionnel de l\'application d\'administration est manquant ou corrompu. Votre profil professionnel et ses données connexes ont donc été supprimés. Communiquez avec votre administrateur pour obtenir de l\'assistance."</string>
+    <string name="work_profile_deleted_details" msgid="3773706828364418016">"Le profil professionnel de l\'appli d\'administration est manquant ou corrompu. Votre profil professionnel et ses données connexes ont donc été supprimés. Communiquez avec votre administrateur pour obtenir de l\'assistance."</string>
     <string name="work_profile_deleted_description_dpm_wipe" msgid="2477244968924647232">"Votre profil professionnel n\'est plus accessible sur cet appareil"</string>
     <string name="work_profile_deleted_reason_maximum_password_failure" msgid="1080323158315663167">"Trop de tentatives d\'entrée du mot de passe"</string>
     <string name="device_ownership_relinquished" msgid="4080886992183195724">"L\'administrateur a libéré l\'appareil pour un usage personnel"</string>
@@ -206,7 +206,7 @@
     <string name="private_space_deleted_by_admin_details" msgid="7007781735201818689">"Votre organisation n\'autorise pas les espaces privés sur cet appareil géré."</string>
     <string name="network_logging_notification_title" msgid="554983187553845004">"L\'appareil est géré"</string>
     <string name="network_logging_notification_text" msgid="1327373071132562512">"Votre organisation gère cet appareil et peut surveiller le trafic réseau. Touchez ici pour obtenir plus d\'information."</string>
-    <string name="location_changed_notification_title" msgid="3620158742816699316">"Les applications peuvent accéder à votre position"</string>
+    <string name="location_changed_notification_title" msgid="3620158742816699316">"Les applis peuvent accéder à votre position"</string>
     <string name="location_changed_notification_text" msgid="7158423339982706912">"Communiquez avec votre administrateur informatique pour en savoir plus"</string>
     <string name="geofencing_service" msgid="3826902410740315456">"Service de définition de limites géographiques"</string>
     <string name="country_detector" msgid="7023275114706088854">"Détecteur de pays"</string>
@@ -218,14 +218,14 @@
     <string name="device_policy_manager_service" msgid="5085762851388850332">"Service de gestionnaire Device Policy"</string>
     <string name="music_recognition_manager_service" msgid="7481956037950276359">"Service de gestion de la reconnaissance musicale"</string>
     <string name="factory_reset_warning" msgid="6858705527798047809">"Le contenu de votre appareil sera effacé"</string>
-    <string name="factory_reset_message" msgid="2657049595153992213">"Impossible d\'utiliser l\'application d\'administration. Les données de votre appareil vont maintenant être effacées.\n\nSi vous avez des questions, communiquez avec l\'administrateur de votre organisation."</string>
+    <string name="factory_reset_message" msgid="2657049595153992213">"Impossible d\'utiliser l\'appli d\'administration. Les données de votre appareil vont maintenant être effacées.\n\nSi vous avez des questions, communiquez avec l\'administrateur de votre organisation."</string>
     <string name="printing_disabled_by" msgid="3517499806528864633">"Impression désactivée par <xliff:g id="OWNER_APP">%s</xliff:g>."</string>
     <string name="personal_apps_suspension_title" msgid="7561416677884286600">"Activer profil professionnel"</string>
-    <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Vos applications personnelles sont bloquées jusqu\'à ce que vous activiez votre profil professionnel"</string>
-    <string name="personal_apps_suspension_soon_text" msgid="8123898693479590">"Les applications personnelles seront bloquées le <xliff:g id="DATE">%1$s</xliff:g> à <xliff:g id="TIME">%2$s</xliff:g>. Votre administrateur informatique ne vous autorise pas à laisser votre profil professionnel désactivé pendant plus de <xliff:g id="NUMBER">%3$d</xliff:g> jours."</string>
+    <string name="personal_apps_suspension_text" msgid="6115455688932935597">"Vos applis personnelles sont bloquées jusqu\'à ce que vous activiez votre profil professionnel"</string>
+    <string name="personal_apps_suspension_soon_text" msgid="8123898693479590">"Les applis personnelles seront bloquées le <xliff:g id="DATE">%1$s</xliff:g> à <xliff:g id="TIME">%2$s</xliff:g>. Votre administrateur informatique ne vous autorise pas à laisser votre profil professionnel désactivé pendant plus de <xliff:g id="NUMBER">%3$d</xliff:g> jours."</string>
     <string name="personal_apps_suspended_turn_profile_on" msgid="2758012869627513689">"Activer"</string>
     <string name="work_profile_telephony_paused_title" msgid="7690804479291839519">"Les appels et messages sont désactivés"</string>
-    <string name="work_profile_telephony_paused_text" msgid="8065762301100978221">"Vous avez mis en pause les applications professionnelles. Vous ne recevrez aucun appel téléphonique ni message texte."</string>
+    <string name="work_profile_telephony_paused_text" msgid="8065762301100978221">"Vous avez mis en pause les applis professionnelles. Vous ne recevrez aucun appel téléphonique ni message texte."</string>
     <string name="work_profile_telephony_paused_turn_on_button" msgid="7542632318337068821">"Réact. applis pros"</string>
     <string name="me" msgid="6207584824693813140">"Moi"</string>
     <string name="power_dialog" product="tablet" msgid="8333207765671417261">"Options de la tablette"</string>
@@ -252,7 +252,7 @@
     <string name="shutdown_confirm" product="default" msgid="136816458966692315">"Votre téléphone va s\'éteindre."</string>
     <string name="shutdown_confirm_question" msgid="796151167261608447">"Voulez-vous éteindre l\'appareil?"</string>
     <string name="reboot_safemode_title" msgid="5853949122655346734">"Redémarrer en mode sans échec"</string>
-    <string name="reboot_safemode_confirm" msgid="1658357874737219624">"Voulez-vous redémarrer en mode sans échec? Cette opération aura pour effet de désactiver toutes les applications tierces que vous avez installées. Elles seront réactivées au prochain redémarrage."</string>
+    <string name="reboot_safemode_confirm" msgid="1658357874737219624">"Voulez-vous redémarrer en mode sans échec? Cette opération aura pour effet de désactiver toutes les applis tierces que vous avez installées. Elles seront réactivées au prochain redémarrage."</string>
     <string name="recent_tasks_title" msgid="8183172372995396653">"Récents"</string>
     <string name="no_recent_tasks" msgid="9063946524312275906">"Aucune appli récente"</string>
     <string name="global_actions" product="tablet" msgid="4412132498517933867">"Options de la tablette"</string>
@@ -303,13 +303,13 @@
     <string name="notification_channel_alerts" msgid="5070241039583668427">"Alertes"</string>
     <string name="notification_channel_retail_mode" msgid="3732239154256431213">"Démo en magasin"</string>
     <string name="notification_channel_usb" msgid="1528280969406244896">"Connexion USB"</string>
-    <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Application en cours d\'exécution"</string>
-    <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Applications qui sollicitent la pile"</string>
+    <string name="notification_channel_heavy_weight_app" msgid="17455756500828043">"Appli en cours d\'exécution"</string>
+    <string name="notification_channel_foreground_service" msgid="7102189948158885178">"Applis qui sollicitent la pile"</string>
     <string name="notification_channel_accessibility_magnification" msgid="1707913872219798098">"Agrandissement"</string>
     <string name="notification_channel_accessibility_security_policy" msgid="1727787021725251912">"Usage des fonctionnalités d\'accessibilité"</string>
     <string name="notification_channel_display" msgid="6905032605735615090">"Écran"</string>
     <string name="foreground_service_app_in_background" msgid="1439289699671273555">"<xliff:g id="APP_NAME">%1$s</xliff:g> sollicite la pile"</string>
-    <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> applications sollicitent la pile"</string>
+    <string name="foreground_service_apps_in_background" msgid="7340037176412387863">"<xliff:g id="NUMBER">%1$d</xliff:g> applis sollicitent la pile"</string>
     <string name="foreground_service_tap_for_details" msgid="9078123626015586751">"Touchez pour afficher des détails sur l\'utilisation de la pile et des données"</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">"Mode sans échec"</string>
@@ -365,282 +365,282 @@
     <string name="dream_preview_title" msgid="5570751491996100804">"Aperçu, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="dream_accessibility_action_click" msgid="7392398629967797805">"Ignorer"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"désactiver ou modifier la barre d\'état"</string>
-    <string name="permdesc_statusBar" msgid="5809162768651019642">"Permet à l\'application de désactiver la barre d\'état, ou d\'ajouter et de supprimer des icônes système."</string>
+    <string name="permdesc_statusBar" msgid="5809162768651019642">"Permet à l\'appli de désactiver la barre d\'état, ou d\'ajouter et de supprimer des icônes système."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"servir de barre d\'état"</string>
-    <string name="permdesc_statusBarService" msgid="6652917399085712557">"Permet à l\'application de faire office de barre d\'état."</string>
+    <string name="permdesc_statusBarService" msgid="6652917399085712557">"Permet à l\'appli de faire office de barre d\'état."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"agrandir ou réduire la barre d\'état"</string>
-    <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permet à l\'application de réduire ou de développer la barre d\'état."</string>
+    <string name="permdesc_expandStatusBar" msgid="7180756900448498536">"Permet à l\'appli de réduire ou de développer la barre d\'état."</string>
     <string name="permlab_fullScreenIntent" msgid="4310888199502509104">"afficher les notifications en mode plein écran sur un appareil verrouillé"</string>
-    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permet à l\'application d\'afficher les notifications en mode plein écran sur un appareil verrouillé."</string>
+    <string name="permdesc_fullScreenIntent" msgid="1100721419406643997">"Permet à l\'appli d\'afficher les notifications en mode plein écran sur un appareil verrouillé."</string>
     <string name="permlab_install_shortcut" msgid="7451554307502256221">"Installer des raccourcis"</string>
-    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permet à une application d\'ajouter des raccourcis sans l\'intervention de l\'utilisateur."</string>
+    <string name="permdesc_install_shortcut" msgid="4476328467240212503">"Permet à une appli d\'ajouter des raccourcis sans l\'intervention de l\'utilisateur."</string>
     <string name="permlab_uninstall_shortcut" msgid="295263654781900390">"désinstaller des raccourcis"</string>
-    <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Permet à l\'application de supprimer des raccourcis de la page d\'accueil sans intervention de l\'utilisateur."</string>
+    <string name="permdesc_uninstall_shortcut" msgid="1924735350988629188">"Permet à l\'appli de supprimer des raccourcis de la page d\'accueil sans intervention de l\'utilisateur."</string>
     <string name="permlab_processOutgoingCalls" msgid="4075056020714266558">"transférer les appels sortants"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"Permet à l\'application de lire le numéro composé lors d\'un appel sortant et lui donne la possibilité de rediriger l\'appel vers un autre numéro ou d\'abandonner l\'appel."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="7833149750590606334">"Permet à l\'appli de lire le numéro composé lors d\'un appel sortant et lui donne la possibilité de rediriger l\'appel vers un autre numéro ou d\'abandonner l\'appel."</string>
     <string name="permlab_answerPhoneCalls" msgid="4131324833663725855">"répondre aux appels téléphoniques"</string>
-    <string name="permdesc_answerPhoneCalls" msgid="894386681983116838">"Permet à l\'application de répondre aux appels entrants."</string>
+    <string name="permdesc_answerPhoneCalls" msgid="894386681983116838">"Permet à l\'appli de répondre aux appels entrants."</string>
     <string name="permlab_receiveSms" msgid="505961632050451881">"recevoir des messages texte"</string>
-    <string name="permdesc_receiveSms" msgid="1797345626687832285">"Permet à l\'application de recevoir et de traiter les messages texte. Cette autorisation lui donne la possibilité de surveiller ou de supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
+    <string name="permdesc_receiveSms" msgid="1797345626687832285">"Permet à l\'appli de recevoir et de traiter les messages texte. Cette autorisation lui donne la possibilité de surveiller ou de supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
     <string name="permlab_receiveMms" msgid="4000650116674380275">"recevoir des messages multimédias"</string>
-    <string name="permdesc_receiveMms" msgid="958102423732219710">"Permet à l\'application de recevoir et de traiter les messages multimédias. Cette autorisation lui donne la possibilité de surveiller ou de supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
+    <string name="permdesc_receiveMms" msgid="958102423732219710">"Permet à l\'appli de recevoir et de traiter les messages multimédias. Cette autorisation lui donne la possibilité de surveiller ou de supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
     <string name="permlab_bindCellBroadcastService" msgid="586746677002040651">"Transférer les messages de diffusion cellulaire"</string>
-    <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"Permet à l\'application d\'établir un lien avec le module de diffusion cellulaire afin de transférer les messages de diffusion cellulaire à mesure de leur réception. Dans certaines régions, des alertes de diffusion cellulaire sont envoyées afin de vous avertir de situations d\'urgence. Des applications malveillantes peuvent interférer avec les performances ou le fonctionnement de votre appareil lors de la réception d\'une alerte d\'urgence par diffusion cellulaire."</string>
+    <string name="permdesc_bindCellBroadcastService" msgid="6540910200973641606">"Permet à l\'appli d\'établir un lien avec le module de diffusion cellulaire afin de transférer les messages de diffusion cellulaire à mesure de leur réception. Dans certaines régions, des alertes de diffusion cellulaire sont envoyées afin de vous avertir de situations d\'urgence. Des applis malveillantes peuvent interférer avec les performances ou le fonctionnement de votre appareil lors de la réception d\'une alerte d\'urgence par diffusion cellulaire."</string>
     <string name="permlab_manageOngoingCalls" msgid="281244770664231782">"Gérer les appels en cours"</string>
-    <string name="permdesc_manageOngoingCalls" msgid="7003138133829915265">"Autorise une application à afficher les renseignements concernant les appels en cours sur votre appareil et à les gérer."</string>
+    <string name="permdesc_manageOngoingCalls" msgid="7003138133829915265">"Autorise une appli à afficher les renseignements concernant les appels en cours sur votre appareil et à les gérer."</string>
     <string name="permlab_accessLastKnownCellId" msgid="7638226620825665130">"Accéder à la dernière identité cellulaire connue."</string>
-    <string name="permdesc_accessLastKnownCellId" msgid="6664621339249308857">"Autorise une application à accéder à la dernière identité cellulaire connue fournie par la téléphonie."</string>
+    <string name="permdesc_accessLastKnownCellId" msgid="6664621339249308857">"Autorise une appli à accéder à la dernière identité cellulaire connue fournie par la téléphonie."</string>
     <string name="permlab_readCellBroadcasts" msgid="5869884450872137693">"lire les messages de diffusion cellulaire"</string>
-    <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"Permet à l\'application de lire les messages de diffusion cellulaire que votre appareil reçoit. Dans certaines zones géographiques, des alertes vous sont envoyées afin de vous prévenir en cas de situation d\'urgence. Des applications malveillantes peuvent venir perturber les performances ou le fonctionnement de votre appareil lors de la réception d\'un message de diffusion cellulaire."</string>
+    <string name="permdesc_readCellBroadcasts" msgid="672513437331980168">"Permet à l\'appli de lire les messages de diffusion cellulaire que votre appareil reçoit. Dans certaines zones géographiques, des alertes vous sont envoyées afin de vous prévenir en cas de situation d\'urgence. Des applis malveillantes peuvent venir perturber les performances ou le fonctionnement de votre appareil lors de la réception d\'un message de diffusion cellulaire."</string>
     <string name="permlab_subscribedFeedsRead" msgid="217624769238425461">"lire les flux auxquels vous êtes abonné"</string>
-    <string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"Permet à l\'application d\'obtenir des données sur les flux en cours de synchronisation."</string>
+    <string name="permdesc_subscribedFeedsRead" msgid="6911349196661811865">"Permet à l\'appli d\'obtenir des données sur les flux en cours de synchronisation."</string>
     <string name="permlab_sendSms" msgid="7757368721742014252">"envoyer et afficher des messages texte"</string>
-    <string name="permdesc_sendSms" msgid="6757089798435130769">"Permet à l\'application d\'envoyer des messages texte. Cette autorisation peut entraîner des frais inattendus. Des applications malveillantes peuvent générer des frais en envoyant des messages sans votre consentement."</string>
+    <string name="permdesc_sendSms" msgid="6757089798435130769">"Permet à l\'appli d\'envoyer des messages texte. Cette autorisation peut entraîner des frais inattendus. Des applis malveillantes peuvent générer des frais en envoyant des messages sans votre consentement."</string>
     <string name="permlab_readSms" msgid="5164176626258800297">"voir les messages texte ou multimédias"</string>
-    <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"Cette application peut lire tous les messages texte stockés sur votre tablette."</string>
-    <string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"Cette application peut lire tous les messages texte stockés sur votre appareil Android TV."</string>
-    <string name="permdesc_readSms" product="default" msgid="774753371111699782">"Cette application peut lire tous les messages texte stockés sur votre téléphone."</string>
+    <string name="permdesc_readSms" product="tablet" msgid="7912990447198112829">"Cette appli peut lire tous les messages texte stockés sur votre tablette."</string>
+    <string name="permdesc_readSms" product="tv" msgid="3054753345758011986">"Cette appli peut lire tous les messages texte stockés sur votre appareil Android TV."</string>
+    <string name="permdesc_readSms" product="default" msgid="774753371111699782">"Cette appli peut lire tous les messages texte stockés sur votre téléphone."</string>
     <string name="permlab_receiveWapPush" msgid="4223747702856929056">"recevoir des messages WAP"</string>
-    <string name="permdesc_receiveWapPush" msgid="1638677888301778457">"Permet à l\'application de recevoir et de traiter les messages WAP. Cette autorisation lui donne la possibilité de surveiller ou de supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
-    <string name="permlab_getTasks" msgid="7460048811831750262">"récupérer les données des applications en cours d\'exécution"</string>
-    <string name="permdesc_getTasks" msgid="7388138607018233726">"Permet à l\'application de récupérer des données sur des tâches en cours d\'exécution et récemment exécutées. L\'application est ainsi susceptible d\'obtenir des données concernant les applications utilisées sur l\'appareil."</string>
+    <string name="permdesc_receiveWapPush" msgid="1638677888301778457">"Permet à l\'appli de recevoir et de traiter les messages WAP. Cette autorisation lui donne la possibilité de surveiller ou de supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
+    <string name="permlab_getTasks" msgid="7460048811831750262">"récupérer les données des applis en cours d\'exécution"</string>
+    <string name="permdesc_getTasks" msgid="7388138607018233726">"Permet à l\'appli de récupérer des données sur des tâches en cours d\'exécution et récemment exécutées. L\'appli est ainsi susceptible d\'obtenir des données concernant les applis utilisées sur l\'appareil."</string>
     <string name="permlab_manageProfileAndDeviceOwners" msgid="639849495253987493">"gérer les propriétaires des profils et de l\'appareil"</string>
-    <string name="permdesc_manageProfileAndDeviceOwners" msgid="7304240671781989283">"Autoriser les applications à définir les propriétaires des profils et celui de l\'appareil"</string>
-    <string name="permlab_reorderTasks" msgid="7598562301992923804">"réorganiser les applications en cours d\'exécution"</string>
-    <string name="permdesc_reorderTasks" msgid="8796089937352344183">"Permet à l\'application de déplacer les tâches au premier plan et en arrière-plan. L\'application peut procéder à ces opérations sans votre intervention."</string>
+    <string name="permdesc_manageProfileAndDeviceOwners" msgid="7304240671781989283">"Autoriser les applis à définir les propriétaires des profils et celui de l\'appareil"</string>
+    <string name="permlab_reorderTasks" msgid="7598562301992923804">"réorganiser les applis en cours d\'exécution"</string>
+    <string name="permdesc_reorderTasks" msgid="8796089937352344183">"Permet à l\'appli de déplacer les tâches au premier plan et en arrière-plan. L\'appli peut procéder à ces opérations sans votre intervention."</string>
     <string name="permlab_enableCarMode" msgid="893019409519325311">"activer le mode voiture"</string>
-    <string name="permdesc_enableCarMode" msgid="56419168820473508">"Permet à l\'application d\'activer le mode Voiture."</string>
-    <string name="permlab_killBackgroundProcesses" msgid="6559320515561928348">"fermer les autres applications"</string>
-    <string name="permdesc_killBackgroundProcesses" msgid="2357013583055434685">"Permet à l\'application de mettre fin aux processus d\'autres applications exécutés en arrière-plan. Cette autorisation peut interrompre l\'exécution d\'autres applications."</string>
-    <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"Cette application peut s\'afficher par-dessus d\'autres applications"</string>
-    <string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"Cette application peut s\'afficher par-dessus d\'autres applications ou parties de l\'écran. Cela pourrait interférer avec l\'utilisation normale des applications et modifier la manière dont les autres applications s\'affichent à l\'écran."</string>
-    <string name="permlab_hideOverlayWindows" msgid="6382697828482271802">"Masquer les superpositions d\'autres applications"</string>
-    <string name="permdesc_hideOverlayWindows" msgid="5660242821651958225">"Cette application peut demander au système de masquer les superpositions provenant d\'applications, afin qu\'elles ne s\'affichent pas au-dessus de celle-ci."</string>
+    <string name="permdesc_enableCarMode" msgid="56419168820473508">"Permet à l\'appli d\'activer le mode Voiture."</string>
+    <string name="permlab_killBackgroundProcesses" msgid="6559320515561928348">"fermer les autres applis"</string>
+    <string name="permdesc_killBackgroundProcesses" msgid="2357013583055434685">"Permet à l\'appli de mettre fin aux processus d\'autres applis exécutés en arrière-plan. Cette autorisation peut interrompre l\'exécution d\'autres applis."</string>
+    <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"Cette appli peut s\'afficher par-dessus d\'autres applis"</string>
+    <string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"Cette appli peut s\'afficher par-dessus d\'autres applis ou parties de l\'écran. Cela pourrait interférer avec l\'utilisation normale des applis et modifier la manière dont les autres applis s\'affichent à l\'écran."</string>
+    <string name="permlab_hideOverlayWindows" msgid="6382697828482271802">"Masquer les superpositions d\'autres applis"</string>
+    <string name="permdesc_hideOverlayWindows" msgid="5660242821651958225">"Cette appli peut demander au système de masquer les superpositions provenant d\'applis, afin qu\'elles ne s\'affichent pas au-dessus de celle-ci."</string>
     <string name="permlab_runInBackground" msgid="541863968571682785">"fonctionner en arrière-plan"</string>
-    <string name="permdesc_runInBackground" msgid="4344539472115495141">"Cette application peut fonctionner en arrière-plan. Cela risque d\'épuiser la pile plus rapidement."</string>
+    <string name="permdesc_runInBackground" msgid="4344539472115495141">"Cette appli peut fonctionner en arrière-plan. Cela risque d\'épuiser la pile plus rapidement."</string>
     <string name="permlab_useDataInBackground" msgid="783415807623038947">"utiliser des données en arrière-plan"</string>
-    <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Cette application peut utiliser des données en arrière-plan. Cela risque d\'augmenter l\'utilisation des données."</string>
+    <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Cette appli peut utiliser des données en arrière-plan. Cela risque d\'augmenter l\'utilisation des données."</string>
     <string name="permlab_schedule_exact_alarm" msgid="6683283918033029730">"Programmer des actions à échéance précise"</string>
-    <string name="permdesc_schedule_exact_alarm" msgid="8198009212013211497">"Cette application peut programmer des tâches à effectuer ultérieurement à un moment voulu. Cela implique que l\'application peut également s\'exécuter quand vous n\'utilisez pas activement l\'appareil."</string>
+    <string name="permdesc_schedule_exact_alarm" msgid="8198009212013211497">"Cette appli peut programmer des tâches à effectuer ultérieurement à un moment voulu. Cela implique que l\'appli peut également s\'exécuter quand vous n\'utilisez pas activement l\'appareil."</string>
     <string name="permlab_use_exact_alarm" msgid="348045139777131552">"Programmer des alarmes ou des rappels d\'événements"</string>
-    <string name="permdesc_use_exact_alarm" msgid="7033761461886938912">"Cette application peut programmer des actions, comme des alarmes et des rappels, pour vous avertir ultérieurement à un moment voulu."</string>
-    <string name="permlab_persistentActivity" msgid="464970041740567970">"exécuter l\'application en continu"</string>
-    <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"Permet à l\'application de rendre certains de ces composants persistants dans la mémoire. Cette autorisation peut limiter la mémoire disponible pour d\'autres applications et ralentir la tablette."</string>
-    <string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"Permet à l\'application de rendre certains de ses composants persistants dans la mémoire. Cette autorisation peut limiter la mémoire disponible pour d\'autres applications et ralentir l\'appareil Android TV."</string>
-    <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Permet à l\'application de rendre certains de ces composants persistants dans la mémoire. Cette autorisation peut limiter la mémoire disponible pour d\'autres applications et ralentir le téléphone."</string>
+    <string name="permdesc_use_exact_alarm" msgid="7033761461886938912">"Cette appli peut programmer des actions, comme des alarmes et des rappels, pour vous avertir ultérieurement à un moment voulu."</string>
+    <string name="permlab_persistentActivity" msgid="464970041740567970">"exécuter l\'appli en continu"</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"Permet à l\'appli de rendre certains de ces composants persistants dans la mémoire. Cette autorisation peut limiter la mémoire disponible pour d\'autres applis et ralentir la tablette."</string>
+    <string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"Permet à l\'appli de rendre certains de ses composants persistants dans la mémoire. Cette autorisation peut limiter la mémoire disponible pour d\'autres applis et ralentir l\'appareil Android TV."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"Permet à l\'appli de rendre certains de ces composants persistants dans la mémoire. Cette autorisation peut limiter la mémoire disponible pour d\'autres applis et ralentir le téléphone."</string>
     <string name="permlab_foregroundService" msgid="1768855976818467491">"exécuter le service en premier plan"</string>
-    <string name="permdesc_foregroundService" msgid="8720071450020922795">"Permet à l\'application d\'utiliser les services en premier plan."</string>
+    <string name="permdesc_foregroundService" msgid="8720071450020922795">"Permet à l\'appli d\'utiliser les services en premier plan."</string>
     <string name="permlab_foregroundServiceCamera" msgid="7814751737955715297">"exécuter le service d\'avant-plan avec le type « appareil photo »"</string>
-    <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « appareil photo »"</string>
+    <string name="permdesc_foregroundServiceCamera" msgid="6973701931250595727">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « appareil photo »"</string>
     <string name="permlab_foregroundServiceConnectedDevice" msgid="3019650546176872501">"exécuter le service d\'avant-plan avec le type « appareil connecté »"</string>
-    <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « appareil connecté »"</string>
+    <string name="permdesc_foregroundServiceConnectedDevice" msgid="1067457315741352963">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « appareil connecté »"</string>
     <string name="permlab_foregroundServiceDataSync" msgid="5847463514326881076">"exécuter le service d\'avant-plan avec le type « synchronisation des données »"</string>
-    <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « synchronisation des données »"</string>
+    <string name="permdesc_foregroundServiceDataSync" msgid="2267140263423973050">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « synchronisation des données »"</string>
     <string name="permlab_foregroundServiceLocation" msgid="3745428302378535690">"exécuter le service d\'avant-plan avec le type « emplacement »"</string>
-    <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « emplacement »"</string>
+    <string name="permdesc_foregroundServiceLocation" msgid="118894034365177183">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « emplacement »"</string>
     <string name="permlab_foregroundServiceMediaPlayback" msgid="4002687983891935514">"exécuter le service d\'avant-plan avec le type « lecture multimédia »"</string>
-    <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « lecture multimédia »"</string>
+    <string name="permdesc_foregroundServiceMediaPlayback" msgid="3638032446063968043">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « lecture multimédia »"</string>
     <string name="permlab_foregroundServiceMediaProjection" msgid="2630868915733312527">"exécuter le service d\'avant-plan avec le type « projection de contenus multimédias »"</string>
-    <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « projection de contenus multimédias »"</string>
+    <string name="permdesc_foregroundServiceMediaProjection" msgid="4805677128082002298">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « projection de contenus multimédias »"</string>
     <string name="permlab_foregroundServiceMicrophone" msgid="7390033424890545399">"exécuter le service d\'avant-plan avec le type « microphone »"</string>
-    <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « microphone »"</string>
+    <string name="permdesc_foregroundServiceMicrophone" msgid="1206041516173483201">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « microphone »"</string>
     <string name="permlab_foregroundServicePhoneCall" msgid="627937743867697892">"exécuter le service d\'avant-plan avec le type « appel téléphonique »"</string>
-    <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « appel téléphonique »"</string>
+    <string name="permdesc_foregroundServicePhoneCall" msgid="5941660252587015147">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « appel téléphonique »"</string>
     <string name="permlab_foregroundServiceHealth" msgid="3675776442080928184">"exécuter le service d\'avant-plan avec le type « santé »"</string>
-    <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « santé »"</string>
+    <string name="permdesc_foregroundServiceHealth" msgid="2024586220562667185">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « santé »"</string>
     <string name="permlab_foregroundServiceRemoteMessaging" msgid="105670277002780950">"exécuter le service d\'avant-plan avec le type « messagerie à distance »"</string>
-    <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « messagerie à distance »"</string>
+    <string name="permdesc_foregroundServiceRemoteMessaging" msgid="8767598075877576277">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « messagerie à distance »"</string>
     <string name="permlab_foregroundServiceSystemExempted" msgid="1597663713590612685">"exécuter le service d\'avant-plan avec le type « système exempté »"</string>
-    <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « système exempté »"</string>
+    <string name="permdesc_foregroundServiceSystemExempted" msgid="947381760834649622">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « système exempté »"</string>
     <string name="permlab_foregroundServiceFileManagement" msgid="2585000987966045030">"exécuter le service d\'avant-plan avec le type « fileManagement »"</string>
-    <string name="permdesc_foregroundServiceFileManagement" msgid="417103601269698508">"Autorise l\'application à utiliser les services d\'avant-plan avec le type « fileManagement »"</string>
+    <string name="permdesc_foregroundServiceFileManagement" msgid="417103601269698508">"Autorise l\'appli à utiliser les services d\'avant-plan avec le type « fileManagement »"</string>
     <string name="permlab_foregroundServiceMediaProcessing" msgid="3045295152245381864">"exécuter le service de premier plan avec le type « mediaProcessing »"</string>
-    <string name="permdesc_foregroundServiceMediaProcessing" msgid="8303086172106677312">"Autorise l\'application à utiliser les services de premier plan avec le type « mediaProcessing »"</string>
+    <string name="permdesc_foregroundServiceMediaProcessing" msgid="8303086172106677312">"Autorise l\'appli à utiliser les services de premier plan avec le type « mediaProcessing »"</string>
     <string name="permlab_foregroundServiceSpecialUse" msgid="7973536745876645082">"exécuter le service d\'avant-plan avec le type « usage spécial »"</string>
-    <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Autoriser l\'application à utiliser les services d\'avant-plan avec le type « usage spécial »"</string>
-    <string name="permlab_getPackageSize" msgid="375391550792886641">"évaluer l\'espace de stockage de l\'application"</string>
-    <string name="permdesc_getPackageSize" msgid="742743530909966782">"Permet à l\'application de récupérer la taille de son code, de ses données et de sa mémoire cache."</string>
+    <string name="permdesc_foregroundServiceSpecialUse" msgid="646713654541885919">"Autoriser l\'appli à utiliser les services d\'avant-plan avec le type « usage spécial »"</string>
+    <string name="permlab_getPackageSize" msgid="375391550792886641">"évaluer l\'espace de stockage de l\'appli"</string>
+    <string name="permdesc_getPackageSize" msgid="742743530909966782">"Permet à l\'appli de récupérer la taille de son code, de ses données et de sa mémoire cache."</string>
     <string name="permlab_writeSettings" msgid="8057285063719277394">"modifier les paramètres du système"</string>
-    <string name="permdesc_writeSettings" msgid="8293047411196067188">"Permet à l\'application de modifier les paramètres du système. Des applications malveillantes peuvent utiliser cette fonctionnalité pour corrompre la configuration de votre système."</string>
+    <string name="permdesc_writeSettings" msgid="8293047411196067188">"Permet à l\'appli de modifier les paramètres du système. Des applis malveillantes peuvent utiliser cette fonctionnalité pour corrompre la configuration de votre système."</string>
     <string name="permlab_receiveBootCompleted" msgid="6643339400247325379">"s\'exécuter au démarrage"</string>
-    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"Permet à l\'application de se lancer une fois le démarrage du système terminé. Elle peut rallonger le temps de démarrage de la tablette et ralentir son fonctionnement global en raison de son exécution continue."</string>
-    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"Permet à l\'application de se lancer une fois le démarrage du système terminé. Cela peut rallonger le temps de démarrage de votre appareil Android TV et permettre à l\'application d\'en ralentir le fonctionnement global en raison de son exécution continue."</string>
-    <string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"Permet à l\'application de se lancer une fois le démarrage du système terminé. Elle peut rallonger le temps de démarrage du téléphone et ralentir son fonctionnement global en raison de son exécution continue."</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"Permet à l\'appli de se lancer une fois le démarrage du système terminé. Elle peut rallonger le temps de démarrage de la tablette et ralentir son fonctionnement global en raison de son exécution continue."</string>
+    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"Permet à l\'appli de se lancer une fois le démarrage du système terminé. Cela peut rallonger le temps de démarrage de votre appareil Android TV et permettre à l\'appli d\'en ralentir le fonctionnement global en raison de son exécution continue."</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"Permet à l\'appli de se lancer une fois le démarrage du système terminé. Elle peut rallonger le temps de démarrage du téléphone et ralentir son fonctionnement global en raison de son exécution continue."</string>
     <string name="permlab_broadcastSticky" msgid="4552241916400572230">"envoyer une diffusion persistante"</string>
-    <string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"Permet à l\'application d\'envoyer des intentions de diffusion \"persistantes\", qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir la tablette ou la rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
-    <string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Permet à l\'application d\'envoyer des intentions de diffusion persistantes, qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir votre appareil Android TV ou le rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
-    <string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Permet à l\'application d\'envoyer des intentions de diffusion \"persistantes\", qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir le téléphone ou le rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"Permet à l\'appli d\'envoyer des intentions de diffusion \"persistantes\", qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir la tablette ou la rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
+    <string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"Permet à l\'appli d\'envoyer des intentions de diffusion persistantes, qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir votre appareil Android TV ou le rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
+    <string name="permdesc_broadcastSticky" product="default" msgid="134529339678913453">"Permet à l\'appli d\'envoyer des intentions de diffusion \"persistantes\", qui perdurent une fois la diffusion terminée. Une utilisation excessive peut ralentir le téléphone ou le rendre instable en l\'obligeant à utiliser trop de mémoire."</string>
     <string name="permlab_readContacts" msgid="8776395111787429099">"lire vos contacts"</string>
-    <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre tablette. Les applications auront aussi accès aux comptes sur votre tablette qui ont créé des contacts. Cela peut comprendre des comptes créés par des applications que vous avez installées. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
-    <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre appareil Android TV. Les applications auront aussi accès aux comptes sur votre appareil Android TV qui ont créé des contacts. Cela peut comprendre des comptes créés par des applications que vous avez installées. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
-    <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Permet à l\'application de lire les données relatives aux contacts stockés sur votre téléphone. Les applications auront aussi accès aux comptes sur votre téléphone qui ont créé des contacts. Cela peut comprendre des comptes créés par des applications que vous avez installées. Cette autorisation permet aux applications d\'enregistrer ces données. Les applications malveillantes peuvent les partager à votre insu."</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="6430093481659992692">"Permet à l\'appli de lire les données relatives aux contacts stockés sur votre tablette. Les applis auront aussi accès aux comptes sur votre tablette qui ont créé des contacts. Cela peut comprendre des comptes créés par des applis que vous avez installées. Cette autorisation permet aux applis d\'enregistrer ces données. Les applis malveillantes peuvent les partager à votre insu."</string>
+    <string name="permdesc_readContacts" product="tv" msgid="8400138591135554789">"Permet à l\'appli de lire les données relatives aux contacts stockés sur votre appareil Android TV. Les applis auront aussi accès aux comptes sur votre appareil Android TV qui ont créé des contacts. Cela peut comprendre des comptes créés par des applis que vous avez installées. Cette autorisation permet aux applis d\'enregistrer ces données. Les applis malveillantes peuvent les partager à votre insu."</string>
+    <string name="permdesc_readContacts" product="default" msgid="4911989776203207644">"Permet à l\'appli de lire les données relatives aux contacts stockés sur votre téléphone. Les applis auront aussi accès aux comptes sur votre téléphone qui ont créé des contacts. Cela peut comprendre des comptes créés par des applis que vous avez installées. Cette autorisation permet aux applis d\'enregistrer ces données. Les applis malveillantes peuvent les partager à votre insu."</string>
     <string name="permlab_writeContacts" msgid="8919430536404830430">"modifier vos contacts"</string>
-    <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Permet à l\'application de modifier les données relatives aux contacts stockés sur votre tablette. Cette autorisation permet aux applications de supprimer des données relatives aux contacts."</string>
-    <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Permet à l\'application de modifier les données relatives aux contacts stockés sur votre appareil Android TV. Cette autorisation permet aux applications de supprimer des données relatives aux contacts."</string>
-    <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Permet à l\'application de modifier les données relatives aux contacts stockés sur votre téléphone. Cette autorisation permet aux applications de supprimer des données relatives aux contacts."</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="6422419281427826181">"Permet à l\'appli de modifier les données relatives aux contacts stockés sur votre tablette. Cette autorisation permet aux applis de supprimer des données relatives aux contacts."</string>
+    <string name="permdesc_writeContacts" product="tv" msgid="6488872735379978935">"Permet à l\'appli de modifier les données relatives aux contacts stockés sur votre appareil Android TV. Cette autorisation permet aux applis de supprimer des données relatives aux contacts."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="8304795696237065281">"Permet à l\'appli de modifier les données relatives aux contacts stockés sur votre téléphone. Cette autorisation permet aux applis de supprimer des données relatives aux contacts."</string>
     <string name="permlab_readCallLog" msgid="1739990210293505948">"lire le journal d\'appels"</string>
-    <string name="permdesc_readCallLog" msgid="8964770895425873433">"Cette application peut lire votre historique d\'appel."</string>
+    <string name="permdesc_readCallLog" msgid="8964770895425873433">"Cette appli peut lire votre historique d\'appel."</string>
     <string name="permlab_writeCallLog" msgid="670292975137658895">"modifier le journal d\'appels"</string>
-    <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Permet à l\'application de lire le journal d\'appels de votre tablette, y compris les données relatives aux appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
-    <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Permet à l\'application de modifier le journal d\'appels de votre appareil Android TV, y compris les données sur les appels entrants et sortants. Des applications malveillantes pourraient utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
-    <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Permet à l\'application de lire le journal d\'appels de votre téléphone, y compris les données relatives aux appels entrants et sortants. Des applications malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
+    <string name="permdesc_writeCallLog" product="tablet" msgid="2657525794731690397">"Permet à l\'appli de lire le journal d\'appels de votre tablette, y compris les données relatives aux appels entrants et sortants. Des applis malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
+    <string name="permdesc_writeCallLog" product="tv" msgid="3934939195095317432">"Permet à l\'appli de modifier le journal d\'appels de votre appareil Android TV, y compris les données sur les appels entrants et sortants. Des applis malveillantes pourraient utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
+    <string name="permdesc_writeCallLog" product="default" msgid="5903033505665134802">"Permet à l\'appli de lire le journal d\'appels de votre téléphone, y compris les données relatives aux appels entrants et sortants. Des applis malveillantes peuvent utiliser cette fonctionnalité pour effacer ou modifier votre journal d\'appels."</string>
     <string name="permlab_bodySensors" msgid="662918578601619569">"Accéder aux données des capteurs corporels si en utilisation (fréq. card., etc.)"</string>
-    <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permet à l\'application d\'accéder aux données des capteurs corporels telles que la fréquence cardiaque, la température et le pourcentage d\'oxygène dans le sang pendant l\'utilisation de l\'application."</string>
+    <string name="permdesc_bodySensors" product="default" msgid="7652650410295512140">"Permet à l\'appli d\'accéder aux données des capteurs corporels telles que la fréquence cardiaque, la température et le pourcentage d\'oxygène dans le sang pendant l\'utilisation de l\'appli."</string>
     <string name="permlab_bodySensors_background" msgid="4912560779957760446">"Accéder aux données des capteurs corporels (comme la fréq. card.) en arrière-plan"</string>
-    <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permet à l\'application d\'accéder aux données des capteurs corporels telles que la fréquence cardiaque, la température et le pourcentage d\'oxygène dans le sang pendant que l\'application s\'exécute en arrière-plan."</string>
+    <string name="permdesc_bodySensors_background" product="default" msgid="8870726027557749417">"Permet à l\'appli d\'accéder aux données des capteurs corporels telles que la fréquence cardiaque, la température et le pourcentage d\'oxygène dans le sang pendant que l\'appli s\'exécute en arrière-plan."</string>
     <string name="permlab_readCalendar" msgid="6408654259475396200">"Lire les événements d\'agenda et leurs détails"</string>
-    <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Cette application peut lire tous les événements d\'agenda stockés sur votre tablette et partager ou enregistrer les données de votre agenda."</string>
-    <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Cette application peut lire tous les événements d\'agenda stockés sur votre appareil Android TV et partager ou enregistrer les données de votre agenda."</string>
-    <string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"Cette application peut lire tous les événements d\'agenda stockés sur votre téléphone et partager ou enregistrer les données de votre agenda."</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="515452384059803326">"Cette appli peut lire tous les événements d\'agenda stockés sur votre tablette et partager ou enregistrer les données de votre agenda."</string>
+    <string name="permdesc_readCalendar" product="tv" msgid="5811726712981647628">"Cette appli peut lire tous les événements d\'agenda stockés sur votre appareil Android TV et partager ou enregistrer les données de votre agenda."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="9118823807655829957">"Cette appli peut lire tous les événements d\'agenda stockés sur votre téléphone et partager ou enregistrer les données de votre agenda."</string>
     <string name="permlab_writeCalendar" msgid="6422137308329578076">"ajouter ou modifier des événements d\'agenda et envoyer des courriels aux invités à l\'insu du propriétaire"</string>
-    <string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"Cette application peut ajouter, supprimer et modifier des événements d\'agenda sur votre tablette. Elle peut aussi envoyer des messages qui pourraient sembler venir des propriétaires d\'agenda en question ou modifier des événements sans avertir leur propriétaire."</string>
-    <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"Cette application peut ajouter, supprimer et modifier des événements d\'agenda sur votre appareil Android TV. Elle peut aussi envoyer des messages qui pourraient sembler venir des propriétaires d\'agenda en question ou modifier des événements sans avertir leur propriétaire."</string>
-    <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Cette application peut ajouter, supprimer et modifier des événements d\'agenda sur votre téléphone. Elle peut aussi envoyer des messages qui pourraient sembler venir des propriétaires d\'agenda en question ou modifier des événements sans avertir leur propriétaire."</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="8722230940717092850">"Cette appli peut ajouter, supprimer et modifier des événements d\'agenda sur votre tablette. Elle peut aussi envoyer des messages qui pourraient sembler venir des propriétaires d\'agenda en question ou modifier des événements sans avertir leur propriétaire."</string>
+    <string name="permdesc_writeCalendar" product="tv" msgid="951246749004952706">"Cette appli peut ajouter, supprimer et modifier des événements d\'agenda sur votre appareil Android TV. Elle peut aussi envoyer des messages qui pourraient sembler venir des propriétaires d\'agenda en question ou modifier des événements sans avertir leur propriétaire."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="5416380074475634233">"Cette appli peut ajouter, supprimer et modifier des événements d\'agenda sur votre téléphone. Elle peut aussi envoyer des messages qui pourraient sembler venir des propriétaires d\'agenda en question ou modifier des événements sans avertir leur propriétaire."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"accéder aux commandes de fournisseur de position géographique supplémentaires"</string>
-    <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permet à l\'application d\'accéder à des commandes de localisation supplémentaires offertes par le fournisseur. Elle est ainsi susceptible d\'interférer avec le bon fonctionnement du GPS ou de toute autre source de localisation."</string>
+    <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Permet à l\'appli d\'accéder à des commandes de localisation supplémentaires offertes par le fournisseur. Elle est ainsi susceptible d\'interférer avec le bon fonctionnement du GPS ou de toute autre source de localisation."</string>
     <string name="permlab_accessFineLocation" msgid="6426318438195622966">"accéder à votre position précise seulement en avant-plan"</string>
-    <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Cette application peut obtenir votre position précise des services de localisation lorsque vous utilisez l\'application. Les services de localisation doivent être activés sur votre appareil pour que l\'application puisse obtenir votre position. Cela pourrait accroître l\'utilisation de la pile."</string>
+    <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Cette appli peut obtenir votre position précise des services de localisation lorsque vous utilisez l\'appli. Les services de localisation doivent être activés sur votre appareil pour que l\'appli puisse obtenir votre position. Cela pourrait accroître l\'utilisation de la pile."</string>
     <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"accéder à votre position approximative seulement en avant-plan"</string>
-    <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Cette application peut obtenir votre position approximative des services de localisation lorsque vous utilisez l\'application. Les services de localisation doivent être activés sur votre appareil pour que l\'application puisse obtenir votre position."</string>
+    <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Cette appli peut obtenir votre position approximative des services de localisation lorsque vous utilisez l\'appli. Les services de localisation doivent être activés sur votre appareil pour que l\'appli puisse obtenir votre position."</string>
     <string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"accès à la localisation en arrière-plan"</string>
-    <string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"Cette application peut accéder à votre position en tout temps, même lorsque vous n\'utilisez pas l\'application."</string>
+    <string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"Cette appli peut accéder à votre position en tout temps, même lorsque vous n\'utilisez pas l\'appli."</string>
     <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"modifier vos paramètres audio"</string>
-    <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Permet à l\'application de modifier les paramètres audio généraux, tels que le volume et la sortie audio utilisée."</string>
+    <string name="permdesc_modifyAudioSettings" msgid="8687227609663124921">"Permet à l\'appli de modifier les paramètres audio généraux, tels que le volume et la sortie audio utilisée."</string>
     <string name="permlab_recordAudio" msgid="1208457423054219147">"enregistrer des fichiers audio"</string>
-    <string name="permdesc_recordAudio" msgid="5857246765327514062">"Cette application peut enregistrer de l\'audio à l\'aide du microphone lorsque vous utilisez l\'application."</string>
+    <string name="permdesc_recordAudio" msgid="5857246765327514062">"Cette appli peut enregistrer de l\'audio à l\'aide du microphone lorsque vous utilisez l\'appli."</string>
     <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"enregistrer de l\'audio en arrière-plan"</string>
-    <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Cette application peut enregistrer de l\'audio à l\'aide du microphone en tout temps."</string>
-    <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"détecter les captures d\'écran des fenêtres d\'application"</string>
-    <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Cette application recevra une notification lorsqu\'une capture d\'écran sera prise pendant que l\'application est en cours d\'utilisation."</string>
+    <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Cette appli peut enregistrer de l\'audio à l\'aide du microphone en tout temps."</string>
+    <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"détecter les captures d\'écran des fenêtres d\'appli"</string>
+    <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Cette appli recevra une notification lorsqu\'une capture d\'écran sera prise pendant que l\'appli est en cours d\'utilisation."</string>
     <string name="permlab_sim_communication" msgid="176788115994050692">"envoyer des commandes à la carte SIM"</string>
-    <string name="permdesc_sim_communication" msgid="4179799296415957960">"Permet à l\'application d\'envoyer des commandes à la carte SIM. Cette fonctionnalité est très dangereuse."</string>
+    <string name="permdesc_sim_communication" msgid="4179799296415957960">"Permet à l\'appli d\'envoyer des commandes à la carte SIM. Cette fonctionnalité est très dangereuse."</string>
     <string name="permlab_activityRecognition" msgid="1782303296053990884">"reconnaître les activités physiques"</string>
-    <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Cette application peut reconnaître vos activités physiques."</string>
+    <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Cette appli peut reconnaître vos activités physiques."</string>
     <string name="permlab_camera" msgid="6320282492904119413">"prendre des photos et filmer des vidéos"</string>
-    <string name="permdesc_camera" msgid="5240801376168647151">"Cette application peut prendre des photos et enregistrer des vidéos à l\'aide de l\'appareil photo lorsque vous utilisez l\'application."</string>
+    <string name="permdesc_camera" msgid="5240801376168647151">"Cette appli peut prendre des photos et enregistrer des vidéos à l\'aide de l\'appareil photo lorsque vous utilisez l\'appli."</string>
     <string name="permlab_backgroundCamera" msgid="7549917926079731681">"prendre des photos et enregistrer des vidéos en arrière-plan"</string>
-    <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Cette application peut prendre des photos et enregistrer des vidéos à l\'aide de l\'appareil photo en tout temps."</string>
-    <string name="permlab_systemCamera" msgid="3642917457796210580">"Autoriser une application ou un service à accéder aux appareils photo système pour prendre des photos et filmer des vidéos"</string>
-    <string name="permdesc_systemCamera" msgid="5938360914419175986">"Cette application privilégiée ou système peut prendre des photos ou filmer des vidéos à l\'aide d\'un appareil photo système en tout temps. L\'application doit également posséder l\'autorisation android.permission.CAMERA"</string>
-    <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Autoriser une application ou un service de recevoir des rappels relatifs à l\'ouverture ou à la fermeture des appareils photos."</string>
-    <string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"Cette application peut recevoir des rappels lorsque l\'appareil photo est ouvert ou fermé (par l\'application en question)."</string>
-    <string name="permlab_cameraHeadlessSystemUser" msgid="680194666834500050">"Autoriser une application ou un service à accéder à la caméra en tant qu\'utilisateur de système sans interface."</string>
-    <string name="permdesc_cameraHeadlessSystemUser" msgid="6963163319710996412">"Cette application peut accéder à la caméra en tant qu\'utilisateur de système sans interface."</string>
+    <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Cette appli peut prendre des photos et enregistrer des vidéos à l\'aide de l\'appareil photo en tout temps."</string>
+    <string name="permlab_systemCamera" msgid="3642917457796210580">"Autoriser une appli ou un service à accéder aux appareils photo système pour prendre des photos et filmer des vidéos"</string>
+    <string name="permdesc_systemCamera" msgid="5938360914419175986">"Cette appli privilégiée ou système peut prendre des photos ou filmer des vidéos à l\'aide d\'un appareil photo système en tout temps. L\'appli doit également posséder l\'autorisation android.permission.CAMERA"</string>
+    <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Autoriser une appli ou un service de recevoir des rappels relatifs à l\'ouverture ou à la fermeture des appareils photos."</string>
+    <string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"Cette appli peut recevoir des rappels lorsque l\'appareil photo est ouvert ou fermé (par l\'appli en question)."</string>
+    <string name="permlab_cameraHeadlessSystemUser" msgid="680194666834500050">"Autoriser une appli ou un service à accéder à la caméra en tant qu\'utilisateur de système sans interface."</string>
+    <string name="permdesc_cameraHeadlessSystemUser" msgid="6963163319710996412">"Cette appli peut accéder à la caméra en tant qu\'utilisateur de système sans interface."</string>
     <string name="permlab_vibrate" msgid="8596800035791962017">"gérer le vibreur"</string>
-    <string name="permdesc_vibrate" msgid="8733343234582083721">"Permet à l\'application de gérer le vibreur de l\'appareil."</string>
-    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permet à l\'application d\'accéder au mode vibration."</string>
+    <string name="permdesc_vibrate" msgid="8733343234582083721">"Permet à l\'appli de gérer le vibreur de l\'appareil."</string>
+    <string name="permdesc_vibrator_state" msgid="7050024956594170724">"Permet à l\'appli d\'accéder au mode vibration."</string>
     <string name="permlab_callPhone" msgid="1798582257194643320">"appeler directement des numéros de téléphone"</string>
-    <string name="permdesc_callPhone" msgid="7892422187827695656">"Autorisez l\'application à appeler des numéros de téléphone sans votre intervention. Cela peut entraîner des frais ou des appels imprévus. Notez aussi que cela ne permet pas à l\'application d\'appeler des numéros d\'urgence. Des applications malveillantes peuvent engendrer des frais en passant des appels sans votre confirmation ou en composant des codes de fournisseurs de service qui transfèrent automatiquement des appels entrants vers un autre numéro."</string>
+    <string name="permdesc_callPhone" msgid="7892422187827695656">"Autorisez l\'appli à appeler des numéros de téléphone sans votre intervention. Cela peut entraîner des frais ou des appels imprévus. Notez aussi que cela ne permet pas à l\'appli d\'appeler des numéros d\'urgence. Des applis malveillantes peuvent engendrer des frais en passant des appels sans votre confirmation ou en composant des codes de fournisseurs de service qui transfèrent automatiquement des appels entrants vers un autre numéro."</string>
     <string name="permlab_accessImsCallService" msgid="442192920714863782">"accéder au service d\'appel IMS"</string>
-    <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Permet à l\'application d\'utiliser le service IMS pour faire des appels sans votre intervention."</string>
+    <string name="permdesc_accessImsCallService" msgid="6328551241649687162">"Permet à l\'appli d\'utiliser le service IMS pour faire des appels sans votre intervention."</string>
     <string name="permlab_readPhoneState" msgid="8138526903259297969">"voir l\'état et l\'identité du téléphone"</string>
-    <string name="permdesc_readPhoneState" msgid="7229063553502788058">"Permet à l\'application d\'accéder aux fonctionnalités téléphoniques de l\'appareil. Cette autorisation permet à l\'application de déterminer le numéro de téléphone et les identifiants de l\'appareil, si un appel est actif et le numéro distant connecté par un appel."</string>
+    <string name="permdesc_readPhoneState" msgid="7229063553502788058">"Permet à l\'appli d\'accéder aux fonctionnalités téléphoniques de l\'appareil. Cette autorisation permet à l\'appli de déterminer le numéro de téléphone et les identifiants de l\'appareil, si un appel est actif et le numéro distant connecté par un appel."</string>
     <string name="permlab_readBasicPhoneState" msgid="3214853233263871347">"Lire l\'état et l\'identité de la téléphonie de base"</string>
-    <string name="permdesc_readBasicPhoneState" msgid="828185691675460520">"Permet à l\'application d\'accéder aux fonctionnalités de téléphonie de base de l\'appareil."</string>
+    <string name="permdesc_readBasicPhoneState" msgid="828185691675460520">"Permet à l\'appli d\'accéder aux fonctionnalités de téléphonie de base de l\'appareil."</string>
     <string name="permlab_manageOwnCalls" msgid="9033349060307561370">"acheminer les appels dans le système"</string>
-    <string name="permdesc_manageOwnCalls" msgid="4431178362202142574">"Permet à l\'application d\'acheminer ses appels dans le système afin d\'améliorer l\'expérience d\'appel."</string>
+    <string name="permdesc_manageOwnCalls" msgid="4431178362202142574">"Permet à l\'appli d\'acheminer ses appels dans le système afin d\'améliorer l\'expérience d\'appel."</string>
     <string name="permlab_callCompanionApp" msgid="3654373653014126884">"afficher et gérer les appels à l\'aide du système."</string>
-    <string name="permdesc_callCompanionApp" msgid="8474168926184156261">"Autorise l\'application à afficher et à gérer les appels sortants sur l\'appareil. Cela comprend de l\'information comme les numéros pour les appels et l\'état des appels."</string>
+    <string name="permdesc_callCompanionApp" msgid="8474168926184156261">"Autorise l\'appli à afficher et à gérer les appels sortants sur l\'appareil. Cela comprend de l\'information comme les numéros pour les appels et l\'état des appels."</string>
     <string name="permlab_exemptFromAudioRecordRestrictions" msgid="1164725468350759486">"est exemptée des restrictions relatives à l\'enregistrement de fichiers audio"</string>
-    <string name="permdesc_exemptFromAudioRecordRestrictions" msgid="2425117015896871976">"Exempter l\'application des restrictions relatives à l\'enregistrement de fichiers audio."</string>
-    <string name="permlab_acceptHandover" msgid="2925523073573116523">"continuer un appel d\'une autre application"</string>
-    <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"Permet à l\'application de continuer un appel commencé dans une autre application."</string>
+    <string name="permdesc_exemptFromAudioRecordRestrictions" msgid="2425117015896871976">"Exempter l\'appli des restrictions relatives à l\'enregistrement de fichiers audio."</string>
+    <string name="permlab_acceptHandover" msgid="2925523073573116523">"continuer un appel d\'une autre appli"</string>
+    <string name="permdesc_acceptHandovers" msgid="7129026180128626870">"Permet à l\'appli de continuer un appel commencé dans une autre appli."</string>
     <string name="permlab_readPhoneNumbers" msgid="5668704794723365628">"lire les numéros de téléphone"</string>
-    <string name="permdesc_readPhoneNumbers" msgid="7368652482818338871">"Permet à l\'application d\'accéder aux numéros de téléphone de l\'appareil."</string>
+    <string name="permdesc_readPhoneNumbers" msgid="7368652482818338871">"Permet à l\'appli d\'accéder aux numéros de téléphone de l\'appareil."</string>
     <string name="permlab_wakeLock" product="automotive" msgid="1904736682319375676">"garder l\'écran de la voiture allumé"</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1527660973931694000">"empêcher la tablette de passer en mode veille"</string>
     <string name="permlab_wakeLock" product="tv" msgid="2856941418123343518">"Empêcher votre appareil Android TV de passer en mode Veille"</string>
     <string name="permlab_wakeLock" product="default" msgid="569409726861695115">"empêcher le téléphone de passer en mode veille"</string>
-    <string name="permdesc_wakeLock" product="automotive" msgid="5995045369683254571">"Permet à l\'application de garder l\'écran de la voiture allumé."</string>
-    <string name="permdesc_wakeLock" product="tablet" msgid="2441742939101526277">"Permet à l\'application d\'empêcher la tablette de passer en mode veille."</string>
-    <string name="permdesc_wakeLock" product="tv" msgid="2329298966735118796">"Permet à l\'application d\'empêcher votre appareil Android TV de passer en mode Veille."</string>
-    <string name="permdesc_wakeLock" product="default" msgid="3689523792074007163">"Permet à l\'application d\'empêcher le téléphone de passer en mode veille."</string>
+    <string name="permdesc_wakeLock" product="automotive" msgid="5995045369683254571">"Permet à l\'appli de garder l\'écran de la voiture allumé."</string>
+    <string name="permdesc_wakeLock" product="tablet" msgid="2441742939101526277">"Permet à l\'appli d\'empêcher la tablette de passer en mode veille."</string>
+    <string name="permdesc_wakeLock" product="tv" msgid="2329298966735118796">"Permet à l\'appli d\'empêcher votre appareil Android TV de passer en mode Veille."</string>
+    <string name="permdesc_wakeLock" product="default" msgid="3689523792074007163">"Permet à l\'appli d\'empêcher le téléphone de passer en mode veille."</string>
     <string name="permlab_transmitIr" msgid="8077196086358004010">"transmettre des signaux infrarouges"</string>
-    <string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"Permet à l\'application d\'utiliser l\'émetteur infrarouge de la tablette."</string>
-    <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"Permet à l\'application d\'utiliser le transmetteur infrarouge de votre appareil Android TV."</string>
-    <string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"Permet à l\'application d\'utiliser l\'émetteur infrarouge du téléphone."</string>
+    <string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"Permet à l\'appli d\'utiliser l\'émetteur infrarouge de la tablette."</string>
+    <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"Permet à l\'appli d\'utiliser le transmetteur infrarouge de votre appareil Android TV."</string>
+    <string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"Permet à l\'appli d\'utiliser l\'émetteur infrarouge du téléphone."</string>
     <string name="permlab_setWallpaper" msgid="6959514622698794511">"définir le fond d\'écran"</string>
-    <string name="permdesc_setWallpaper" msgid="2973996714129021397">"Permet à l\'application de définir le fond d\'écran du système."</string>
+    <string name="permdesc_setWallpaper" msgid="2973996714129021397">"Permet à l\'appli de définir le fond d\'écran du système."</string>
     <string name="permlab_accessHiddenProfile" msgid="8607094418491556823">"Accéder aux profils masqués"</string>
-    <string name="permdesc_accessHiddenProfile" msgid="1543153202481009676">"Autorise l\'application à accéder aux profils masqués"</string>
+    <string name="permdesc_accessHiddenProfile" msgid="1543153202481009676">"Autorise l\'appli à accéder aux profils masqués"</string>
     <string name="permlab_setWallpaperHints" msgid="1153485176642032714">"modifier la taille du fond d\'écran"</string>
-    <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"Permet à l\'application de définir les bulles d\'aide concernant la taille du fond d\'écran du système."</string>
+    <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"Permet à l\'appli de définir les bulles d\'aide concernant la taille du fond d\'écran du système."</string>
     <string name="permlab_setTimeZone" msgid="7922618798611542432">"définir le fuseau horaire"</string>
-    <string name="permdesc_setTimeZone" product="tablet" msgid="1788868809638682503">"Permet à l\'application de modifier le fuseau horaire de la tablette."</string>
-    <string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"Permet à l\'application de modifier le fuseau horaire de votre appareil Android TV."</string>
-    <string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"Permet à l\'application de modifier le fuseau horaire du téléphone."</string>
+    <string name="permdesc_setTimeZone" product="tablet" msgid="1788868809638682503">"Permet à l\'appli de modifier le fuseau horaire de la tablette."</string>
+    <string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"Permet à l\'appli de modifier le fuseau horaire de votre appareil Android TV."</string>
+    <string name="permdesc_setTimeZone" product="default" msgid="4611828585759488256">"Permet à l\'appli de modifier le fuseau horaire du téléphone."</string>
     <string name="permlab_getAccounts" msgid="5304317160463582791">"rechercher des comptes sur l\'appareil"</string>
-    <string name="permdesc_getAccounts" product="tablet" msgid="1784452755887604512">"Permet à l\'application d\'obtenir la liste des comptes connus par la tablette. Il peut s\'agir de n\'importe quel compte créé par les applications que vous avez installées."</string>
-    <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"Permet à l\'application d\'obtenir la liste des comptes connus de votre appareil Android TV. Cela peut comprendre n\'importe quel compte créé par les applications que vous avez installées."</string>
-    <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"Permet à l\'application d\'obtenir la liste des comptes connus par le téléphone. Il peut s\'agir de n\'importe quel compte créé par les applications que vous avez installées."</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="1784452755887604512">"Permet à l\'appli d\'obtenir la liste des comptes connus par la tablette. Il peut s\'agir de n\'importe quel compte créé par les applis que vous avez installées."</string>
+    <string name="permdesc_getAccounts" product="tv" msgid="437604680436540822">"Permet à l\'appli d\'obtenir la liste des comptes connus de votre appareil Android TV. Cela peut comprendre n\'importe quel compte créé par les applis que vous avez installées."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="2491273043569751867">"Permet à l\'appli d\'obtenir la liste des comptes connus par le téléphone. Il peut s\'agir de n\'importe quel compte créé par les applis que vous avez installées."</string>
     <string name="permlab_accessNetworkState" msgid="2349126720783633918">"afficher les connexions réseau"</string>
-    <string name="permdesc_accessNetworkState" msgid="4394564702881662849">"Permet à l\'application d\'accéder à des détails concernant les connexions réseau, comme les réseaux existants et connectés."</string>
+    <string name="permdesc_accessNetworkState" msgid="4394564702881662849">"Permet à l\'appli d\'accéder à des détails concernant les connexions réseau, comme les réseaux existants et connectés."</string>
     <string name="permlab_createNetworkSockets" msgid="3224420491603590541">"bénéficier d\'un accès complet au réseau"</string>
-    <string name="permdesc_createNetworkSockets" msgid="7722020828749535988">"Permet à l\'application de créer des interfaces de connexion réseau et d\'utiliser des protocoles réseau personnalisés. Le navigateur et d\'autres applications permettent d\'envoyer des données sur Internet. Cette autorisation n\'est donc pas nécessaire pour envoyer des données sur Internet."</string>
+    <string name="permdesc_createNetworkSockets" msgid="7722020828749535988">"Permet à l\'appli de créer des interfaces de connexion réseau et d\'utiliser des protocoles réseau personnalisés. Le navigateur et d\'autres applis permettent d\'envoyer des données sur Internet. Cette autorisation n\'est donc pas nécessaire pour envoyer des données sur Internet."</string>
     <string name="permlab_changeNetworkState" msgid="8945711637530425586">"modifier la connectivité réseau"</string>
-    <string name="permdesc_changeNetworkState" msgid="649341947816898736">"Permet à l\'application de modifier l\'état de la connectivité réseau."</string>
+    <string name="permdesc_changeNetworkState" msgid="649341947816898736">"Permet à l\'appli de modifier l\'état de la connectivité réseau."</string>
     <string name="permlab_changeTetherState" msgid="9079611809931863861">"changer la connectivité du partage de connexion"</string>
-    <string name="permdesc_changeTetherState" msgid="3025129606422533085">"Permet à l\'application de modifier l\'état de la connectivité du partage de connexion."</string>
+    <string name="permdesc_changeTetherState" msgid="3025129606422533085">"Permet à l\'appli de modifier l\'état de la connectivité du partage de connexion."</string>
     <string name="permlab_accessWifiState" msgid="5552488500317911052">"afficher les connexions Wi-Fi"</string>
-    <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Permet à l\'application d\'accéder à des détails sur les réseaux Wi-Fi afin de savoir si une connexion Wi-Fi est activée et pour connaître le nom des appareils connectés au Wi-Fi, par exemple."</string>
+    <string name="permdesc_accessWifiState" msgid="6913641669259483363">"Permet à l\'appli d\'accéder à des détails sur les réseaux Wi-Fi afin de savoir si une connexion Wi-Fi est activée et pour connaître le nom des appareils connectés au Wi-Fi, par exemple."</string>
     <string name="permlab_changeWifiState" msgid="7947824109713181554">"activer/désactiver la connexion Wi-Fi"</string>
-    <string name="permdesc_changeWifiState" msgid="7170350070554505384">"Permet à l\'application de se connecter à des points d\'accès Wi-Fi, de s\'en déconnecter et de modifier la configuration de l\'appareil pour les réseaux Wi-Fi."</string>
+    <string name="permdesc_changeWifiState" msgid="7170350070554505384">"Permet à l\'appli de se connecter à des points d\'accès Wi-Fi, de s\'en déconnecter et de modifier la configuration de l\'appareil pour les réseaux Wi-Fi."</string>
     <string name="permlab_changeWifiMulticastState" msgid="285626875870754696">"autoriser la réception de données en mode Wi-Fi multidiffusion"</string>
-    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"Permet à l\'application de recevoir des paquets envoyés à tous les appareils (et pas seulement à votre tablette) d\'un réseau Wi-Fi qui utilise des adresses de multidiffusion. Cette autorisation entraîne une consommation d\'énergie supérieure au mode de diffusion simple."</string>
-    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"Permet à l\'application de recevoir des paquets envoyés à tous les appareils d\'un réseau Wi-Fi qui utilise des adresses de multidiffusion, et pas seulement à votre appareil Android TV. Cette autorisation entraîne une consommation d\'énergie supérieure au mode de diffusion simple."</string>
-    <string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"Permet à l\'application de recevoir des paquets envoyés à tous les appareils (et pas seulement à votre téléphone) d\'un réseau Wi-Fi qui utilise des adresses de multidiffusion. Cette autorisation entraîne une consommation d\'énergie supérieure au mode de diffusion simple."</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="191079868596433554">"Permet à l\'appli de recevoir des paquets envoyés à tous les appareils (et pas seulement à votre tablette) d\'un réseau Wi-Fi qui utilise des adresses de multidiffusion. Cette autorisation entraîne une consommation d\'énergie supérieure au mode de diffusion simple."</string>
+    <string name="permdesc_changeWifiMulticastState" product="tv" msgid="1336952358450652595">"Permet à l\'appli de recevoir des paquets envoyés à tous les appareils d\'un réseau Wi-Fi qui utilise des adresses de multidiffusion, et pas seulement à votre appareil Android TV. Cette autorisation entraîne une consommation d\'énergie supérieure au mode de diffusion simple."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="8296627590220222740">"Permet à l\'appli de recevoir des paquets envoyés à tous les appareils (et pas seulement à votre téléphone) d\'un réseau Wi-Fi qui utilise des adresses de multidiffusion. Cette autorisation entraîne une consommation d\'énergie supérieure au mode de diffusion simple."</string>
     <string name="permlab_bluetoothAdmin" msgid="6490373569441946064">"accéder aux paramètres Bluetooth"</string>
-    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Permet à l\'application de configurer la tablette Bluetooth locale, d\'identifier des appareils distants et de les associer à la tablette."</string>
-    <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Permet à l\'application de configurer le Bluetooth sur votre appareil Android TV, de repérer des appareils distants et de les associer à l\'appareil."</string>
-    <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"Permet à l\'application de configurer le téléphone Bluetooth local, d\'identifier des appareils distants et de les associer au téléphone."</string>
+    <string name="permdesc_bluetoothAdmin" product="tablet" msgid="5370837055438574863">"Permet à l\'appli de configurer la tablette Bluetooth locale, d\'identifier des appareils distants et de les associer à la tablette."</string>
+    <string name="permdesc_bluetoothAdmin" product="tv" msgid="1623992984547014588">"Permet à l\'appli de configurer le Bluetooth sur votre appareil Android TV, de repérer des appareils distants et de les associer à l\'appareil."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="7381341743021234863">"Permet à l\'appli de configurer le téléphone Bluetooth local, d\'identifier des appareils distants et de les associer au téléphone."</string>
     <string name="permlab_accessWimaxState" msgid="7029563339012437434">"se connecter au réseau WiMAX et s\'en déconnecter"</string>
-    <string name="permdesc_accessWimaxState" msgid="5372734776802067708">"Permet à l\'application de déterminer si le WiMAX est activé et d\'obtenir des détails sur tous les réseaux WiMAX connectés."</string>
+    <string name="permdesc_accessWimaxState" msgid="5372734776802067708">"Permet à l\'appli de déterminer si le WiMAX est activé et d\'obtenir des détails sur tous les réseaux WiMAX connectés."</string>
     <string name="permlab_changeWimaxState" msgid="6223305780806267462">"modifier l\'état du WiMAX"</string>
-    <string name="permdesc_changeWimaxState" product="tablet" msgid="4011097664859480108">"Permet à l\'application de connecter la tablette aux réseaux WiMAX et de l\'en déconnecter."</string>
-    <string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"Permet à l\'application de connecter votre appareil Android TV aux réseaux WiMAX et de les en déconnecter."</string>
-    <string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"Permet à l\'application de connecter le téléphone aux réseaux WiMAX et de l\'en déconnecter."</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="4011097664859480108">"Permet à l\'appli de connecter la tablette aux réseaux WiMAX et de l\'en déconnecter."</string>
+    <string name="permdesc_changeWimaxState" product="tv" msgid="5373274458799425276">"Permet à l\'appli de connecter votre appareil Android TV aux réseaux WiMAX et de les en déconnecter."</string>
+    <string name="permdesc_changeWimaxState" product="default" msgid="1551666203780202101">"Permet à l\'appli de connecter le téléphone aux réseaux WiMAX et de l\'en déconnecter."</string>
     <string name="permlab_bluetooth" msgid="586333280736937209">"s\'associer à des appareils Bluetooth"</string>
-    <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Permet à l\'application d\'accéder à la configuration du Bluetooth sur la tablette, et d\'établir et accepter des connexions avec les appareils associés."</string>
-    <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Permet à l\'application d\'afficher la configuration du Bluetooth sur votre appareil Android TV, de se connecter à des appareils associés et d\'accepter leur connexion."</string>
-    <string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Permet à l\'application d\'accéder à la configuration du Bluetooth sur le téléphone, et d\'établir et accepter des connexions avec les appareils associés."</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Permet à l\'appli d\'accéder à la configuration du Bluetooth sur la tablette, et d\'établir et accepter des connexions avec les appareils associés."</string>
+    <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Permet à l\'appli d\'afficher la configuration du Bluetooth sur votre appareil Android TV, de se connecter à des appareils associés et d\'accepter leur connexion."</string>
+    <string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Permet à l\'appli d\'accéder à la configuration du Bluetooth sur le téléphone, et d\'établir et accepter des connexions avec les appareils associés."</string>
     <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"découvrir des appareils Bluetooth et s\'y connecter"</string>
-    <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permet à l\'application de découvrir les appareils Bluetooth à proximité et de s\'y connecter"</string>
+    <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permet à l\'appli de découvrir les appareils Bluetooth à proximité et de s\'y connecter"</string>
     <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"se connecter aux appareils Bluetooth associés"</string>
-    <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permet à l\'application de se connecter aux appareils Bluetooth associés"</string>
+    <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permet à l\'appli de se connecter aux appareils Bluetooth associés"</string>
     <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"envoyer annonces aux appareils Bluetooth à proxim."</string>
-    <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permet à l\'application d\'envoyer des annonces aux appareils Bluetooth à proximité"</string>
+    <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permet à l\'appli d\'envoyer des annonces aux appareils Bluetooth à proximité"</string>
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"déterminer la position relative entre des appareils à bande ultralarge à proximité"</string>
-    <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Autorisez l\'application à déterminer la position relative entre des appareils à bande ultralarge à proximité"</string>
+    <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Autorisez l\'appli à déterminer la position relative entre des appareils à bande ultralarge à proximité"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir avec les appareils Wi-Fi à proximité"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permet à l\'application de diffuser des annonces, de se connecter et de déterminer la position relative des appareils Wi-Fi à proximité"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permet à l\'appli de diffuser des annonces, de se connecter et de déterminer la position relative des appareils Wi-Fi à proximité"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Information sur le service préféré de paiement CCP"</string>
-    <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet à l\'application d\'obtenir de l\'information sur le service préféré de paiement CCP comme les aides enregistrées et la route de destination."</string>
+    <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet à l\'appli d\'obtenir de l\'information sur le service préféré de paiement CCP comme les aides enregistrées et la route de destination."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"gérer la communication en champ proche"</string>
-    <string name="permdesc_nfc" msgid="8352737680695296741">"Permet à l\'application de communiquer avec des bornes, des cartes et des lecteurs compatibles avec la technologie CCP (communication en champ proche)."</string>
+    <string name="permdesc_nfc" msgid="8352737680695296741">"Permet à l\'appli de communiquer avec des bornes, des cartes et des lecteurs compatibles avec la technologie CCP (communication en champ proche)."</string>
     <string name="permlab_nfcTransactionEvent" msgid="5868209446710407679">"Événement de transaction relatif à un élément sécurisé"</string>
-    <string name="permdesc_nfcTransactionEvent" msgid="1904286701876487397">"Autorise l\'application à recevoir des informations relatives aux transactions effectuées sur un élément sécurisé."</string>
+    <string name="permdesc_nfcTransactionEvent" msgid="1904286701876487397">"Autorise l\'appli à recevoir des informations relatives aux transactions effectuées sur un élément sécurisé."</string>
     <string name="permlab_disableKeyguard" msgid="3605253559020928505">"désactiver le verrouillage de l\'écran"</string>
-    <string name="permdesc_disableKeyguard" msgid="3223710003098573038">"Permet à l\'application de désactiver le verrouillage des touches et toute mesure de sécurité par mot de passe associée. Par exemple, votre téléphone désactive le verrouillage des touches lorsque vous recevez un appel, puis le réactive lorsque vous raccrochez."</string>
+    <string name="permdesc_disableKeyguard" msgid="3223710003098573038">"Permet à l\'appli de désactiver le verrouillage des touches et toute mesure de sécurité par mot de passe associée. Par exemple, votre téléphone désactive le verrouillage des touches lorsque vous recevez un appel, puis le réactive lorsque vous raccrochez."</string>
     <string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"demander la complexité du verrouillage d\'écran"</string>
-    <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="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Autorise l\'appli à 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\'appli 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\'appli 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="permdesc_postNotification" msgid="5974977162462877075">"Permet à l\'appli 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="permdesc_turnScreenOn" msgid="4394606875897601559">"Permet à l\'appli 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="permdesc_useBiometric" msgid="7502858732677143410">"Permet à l\'appli 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>
-    <string name="permdesc_manageFingerprint" msgid="2025616816437339865">"Permet à l\'application de faire appel à des méthodes d\'ajout et de suppression de modèles d\'empreinte digitale que vous pouvez utiliser."</string>
+    <string name="permdesc_manageFingerprint" msgid="2025616816437339865">"Permet à l\'appli de faire appel à des méthodes d\'ajout et de suppression de modèles d\'empreinte digitale que vous pouvez utiliser."</string>
     <string name="permlab_useFingerprint" msgid="1001421069766751922">"utiliser le lecteur d\'empreintes digitales"</string>
-    <string name="permdesc_useFingerprint" msgid="412463055059323742">"Permet à l\'application d\'utiliser le lecteur d\'empreintes digitales pour l\'authentification"</string>
+    <string name="permdesc_useFingerprint" msgid="412463055059323742">"Permet à l\'appli d\'utiliser le lecteur d\'empreintes digitales pour l\'authentification"</string>
     <string name="permlab_audioWrite" msgid="8501705294265669405">"modifier votre collection de musique"</string>
-    <string name="permdesc_audioWrite" msgid="8057399517013412431">"Autorise l\'application à modifier votre collection de musique."</string>
+    <string name="permdesc_audioWrite" msgid="8057399517013412431">"Autorise l\'appli à modifier votre collection de musique."</string>
     <string name="permlab_videoWrite" msgid="5940738769586451318">"modifier votre collection de vidéos"</string>
-    <string name="permdesc_videoWrite" msgid="6124731210613317051">"Autorise l\'application à modifier votre collection de vidéos."</string>
+    <string name="permdesc_videoWrite" msgid="6124731210613317051">"Autorise l\'appli à modifier votre collection de vidéos."</string>
     <string name="permlab_imagesWrite" msgid="1774555086984985578">"modifier votre collection de photos"</string>
-    <string name="permdesc_imagesWrite" msgid="5195054463269193317">"Autorise l\'application à modifier votre collection de photos."</string>
+    <string name="permdesc_imagesWrite" msgid="5195054463269193317">"Autorise l\'appli à modifier votre collection de photos."</string>
     <string name="permlab_mediaLocation" msgid="7368098373378598066">"lire les positions issues de votre collection multimédia"</string>
-    <string name="permdesc_mediaLocation" msgid="597912899423578138">"Autorise l\'application à lire les positions indiquées dans votre collection multimédia."</string>
+    <string name="permdesc_mediaLocation" msgid="597912899423578138">"Autorise l\'appli à lire les positions indiquées dans votre collection multimédia."</string>
     <string name="biometric_app_setting_name" msgid="3339209978734534457">"Utiliser les données biométriques"</string>
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Utiliser les données biométriques ou le verrouillage de l\'écran"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Confirmez que c\'est vous"</string>
@@ -758,81 +758,81 @@
     <string name="face_error_vendor_unknown" msgid="7387005932083302070">"Un problème est survenu. Réessayez."</string>
     <string name="face_icon_content_description" msgid="465030547475916280">"Icône visage"</string>
     <string name="permlab_readSyncSettings" msgid="6250532864893156277">"lire les paramètres de synchronisation"</string>
-    <string name="permdesc_readSyncSettings" msgid="1325658466358779298">"Permet à l\'application d\'accéder aux paramètres de synchronisation d\'un compte. Par exemple, cette autorisation peut permettre de déterminer si l\'application Contacts est synchronisée avec un compte ou non."</string>
+    <string name="permdesc_readSyncSettings" msgid="1325658466358779298">"Permet à l\'appli d\'accéder aux paramètres de synchronisation d\'un compte. Par exemple, cette autorisation peut permettre de déterminer si l\'appli Contacts est synchronisée avec un compte ou non."</string>
     <string name="permlab_writeSyncSettings" msgid="6583154300780427399">"activer ou désactiver la synchronisation"</string>
-    <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"Permet à une application de modifier les paramètres de synchronisation d\'un compte. Cette autorisation peut, par exemple, être utilisée pour activer la synchronisation de l\'application Contacts avec un compte."</string>
+    <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"Permet à une appli de modifier les paramètres de synchronisation d\'un compte. Cette autorisation peut, par exemple, être utilisée pour activer la synchronisation de l\'appli Contacts avec un compte."</string>
     <string name="permlab_readSyncStats" msgid="3747407238320105332">"lire les statistiques de synchronisation"</string>
-    <string name="permdesc_readSyncStats" msgid="3867809926567379434">"Permet à une application d\'accéder aux statistiques de synchronisation d\'un compte, y compris l\'historique des événements de synchronisation et le volume de données synchronisées."</string>
+    <string name="permdesc_readSyncStats" msgid="3867809926567379434">"Permet à une appli d\'accéder aux statistiques de synchronisation d\'un compte, y compris l\'historique des événements de synchronisation et le volume de données synchronisées."</string>
     <string name="permlab_sdcardRead" msgid="5791467020950064920">"lire le contenu de votre espace de stockage partagé"</string>
-    <string name="permdesc_sdcardRead" msgid="6872973242228240382">"Permet à l\'application de lire le contenu de votre espace de stockage partagé."</string>
+    <string name="permdesc_sdcardRead" msgid="6872973242228240382">"Permet à l\'appli de lire le contenu de votre espace de stockage partagé."</string>
     <string name="permlab_readMediaAudio" msgid="8723513075731763810">"lire des fichiers audio à partir de l\'espace de stockage partagé"</string>
-    <string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Permet à l\'application de lire les fichiers audio de votre espace de stockage partagé."</string>
+    <string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Permet à l\'appli de lire les fichiers audio de votre espace de stockage partagé."</string>
     <string name="permlab_readMediaVideo" msgid="7768003311260655007">"lire des fichiers vidéo à partir de l\'espace de stockage partagé"</string>
-    <string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Permet à l\'application de lire les fichiers vidéo de votre espace de stockage partagé."</string>
+    <string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Permet à l\'appli de lire les fichiers vidéo de votre espace de stockage partagé."</string>
     <string name="permlab_readMediaImages" msgid="4057590631020986789">"lire des fichiers d\'image à partir de l\'espace de stockage partagé"</string>
-    <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Permet à l\'application de lire les fichiers d\'image de votre espace de stockage partagé."</string>
+    <string name="permdesc_readMediaImages" msgid="5836219373138469259">"Permet à l\'appli de lire les fichiers d\'image de votre espace de stockage partagé."</string>
     <string name="permlab_readVisualUserSelect" msgid="5516204215354667586">"lire les fichiers d\'images et de vidéos sélectionnés par l\'utilisateur dans l\'espace de stockage partagé"</string>
-    <string name="permdesc_readVisualUserSelect" msgid="8027174717714968217">"Permet à l\'application de lire les fichiers d\'images et de vidéos que vous sélectionnez dans votre espace de stockage partagé."</string>
+    <string name="permdesc_readVisualUserSelect" msgid="8027174717714968217">"Permet à l\'appli de lire les fichiers d\'images et de vidéos que vous sélectionnez dans votre espace de stockage partagé."</string>
     <string name="permlab_sdcardWrite" msgid="4863021819671416668">"modifier ou supprimer le contenu de votre espace de stockage partagé"</string>
-    <string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Autorise l\'application à écrire le contenu de votre espace de stockage partagé."</string>
+    <string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Autorise l\'appli à écrire le contenu de votre espace de stockage partagé."</string>
     <string name="permlab_use_sip" msgid="8250774565189337477">"faire et recevoir des appels SIP"</string>
-    <string name="permdesc_use_sip" msgid="3590270893253204451">"Autorise l\'application à effectuer et à recevoir des appels SIP."</string>
+    <string name="permdesc_use_sip" msgid="3590270893253204451">"Autorise l\'appli à effectuer et à recevoir des appels SIP."</string>
     <string name="permlab_register_sim_subscription" msgid="1653054249287576161">"enregistrer de nouvelles connexions de télécommunication à l\'aide de la carte SIM"</string>
-    <string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"Permettre à l\'application d\'enregistrer de nouvelles connexions de télécommunication à l\'aide de la carte SIM"</string>
+    <string name="permdesc_register_sim_subscription" msgid="4183858662792232464">"Permettre à l\'appli d\'enregistrer de nouvelles connexions de télécommunication à l\'aide de la carte SIM"</string>
     <string name="permlab_register_call_provider" msgid="6135073566140050702">"enregistrer de nouvelles connexions de télécommunication"</string>
-    <string name="permdesc_register_call_provider" msgid="4201429251459068613">"Permettre à l\'application d\'enregistrer de nouvelles connexions de télécommunication"</string>
+    <string name="permdesc_register_call_provider" msgid="4201429251459068613">"Permettre à l\'appli d\'enregistrer de nouvelles connexions de télécommunication"</string>
     <string name="permlab_connection_manager" msgid="3179365584691166915">"gérer les connexions de télécommunication"</string>
-    <string name="permdesc_connection_manager" msgid="1426093604238937733">"Permettre à l\'application de gérer les connexions de télécommunication"</string>
+    <string name="permdesc_connection_manager" msgid="1426093604238937733">"Permettre à l\'appli de gérer les connexions de télécommunication"</string>
     <string name="permlab_bind_incall_service" msgid="5990625112603493016">"interagir avec l\'écran d\'appel"</string>
-    <string name="permdesc_bind_incall_service" msgid="4124917526967765162">"Permet à l\'application de contrôler quand et comment l\'écran d\'appel s\'affiche."</string>
+    <string name="permdesc_bind_incall_service" msgid="4124917526967765162">"Permet à l\'appli de contrôler quand et comment l\'écran d\'appel s\'affiche."</string>
     <string name="permlab_bind_connection_service" msgid="5409268245525024736">"interagir avec les services de téléphonie"</string>
-    <string name="permdesc_bind_connection_service" msgid="6261796725253264518">"Permet à l\'application d\'interagir avec les services de téléphonie afin de faire et de recevoir des appels."</string>
+    <string name="permdesc_bind_connection_service" msgid="6261796725253264518">"Permet à l\'appli d\'interagir avec les services de téléphonie afin de faire et de recevoir des appels."</string>
     <string name="permlab_control_incall_experience" msgid="6436863486094352987">"fournir une expérience utilisateur pendant l\'appel"</string>
-    <string name="permdesc_control_incall_experience" msgid="5896723643771737534">"Permet à l\'application de fournir une expérience utilisateur pendant l\'appel."</string>
+    <string name="permdesc_control_incall_experience" msgid="5896723643771737534">"Permet à l\'appli de fournir une expérience utilisateur pendant l\'appel."</string>
     <string name="permlab_readNetworkUsageHistory" msgid="8470402862501573795">"lire l\'historique d\'utilisation de réseaux"</string>
-    <string name="permdesc_readNetworkUsageHistory" msgid="1112962304941637102">"Permet à l\'application de lire l\'historique d\'utilisation de réseaux et d\'applications particuliers."</string>
+    <string name="permdesc_readNetworkUsageHistory" msgid="1112962304941637102">"Permet à l\'appli de lire l\'historique d\'utilisation de réseaux et d\'applis particuliers."</string>
     <string name="permlab_manageNetworkPolicy" msgid="6872549423152175378">"gérer les politiques du réseau"</string>
-    <string name="permdesc_manageNetworkPolicy" msgid="1865663268764673296">"Permet à l\'application de gérer les politiques du réseau et de définir celles propres à l\'application"</string>
+    <string name="permdesc_manageNetworkPolicy" msgid="1865663268764673296">"Permet à l\'appli de gérer les politiques du réseau et de définir celles propres à l\'appli"</string>
     <string name="permlab_modifyNetworkAccounting" msgid="7448790834938749041">"modifier le système d\'analyse de l\'utilisation du réseau"</string>
-    <string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"Permet à l\'application de modifier le système d\'analyse de l\'utilisation du réseau par les autres applications. Les applications standards ne doivent pas utiliser cette fonctionnalité."</string>
+    <string name="permdesc_modifyNetworkAccounting" msgid="5076042642247205390">"Permet à l\'appli de modifier le système d\'analyse de l\'utilisation du réseau par les autres applis. Les applis standards ne doivent pas utiliser cette fonctionnalité."</string>
     <string name="permlab_accessNotifications" msgid="7130360248191984741">"accéder aux notifications"</string>
-    <string name="permdesc_accessNotifications" msgid="761730149268789668">"Permet aux applications de récupérer, d\'examiner et d\'autoriser les notifications, y compris celles envoyées par d\'autres applications."</string>
+    <string name="permdesc_accessNotifications" msgid="761730149268789668">"Permet aux applis de récupérer, d\'examiner et d\'autoriser les notifications, y compris celles envoyées par d\'autres applis."</string>
     <string name="permlab_bindNotificationListenerService" msgid="5848096702733262458">"s\'associer à l\'interface de niveau supérieur d\'un service d\'écoute des notifications"</string>
-    <string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"Permet à l\'application de s\'associer à l\'interface de niveau supérieur d\'un service d\'écoute des notifications. Ne devrait jamais être nécessaire pour les applications normales."</string>
+    <string name="permdesc_bindNotificationListenerService" msgid="4970553694467137126">"Permet à l\'appli de s\'associer à l\'interface de niveau supérieur d\'un service d\'écoute des notifications. Ne devrait jamais être nécessaire pour les applis normales."</string>
     <string name="permlab_bindConditionProviderService" msgid="5245421224814878483">"s\'associer à un service de fournisseur de conditions"</string>
-    <string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"Permet à l\'application de s\'associer à l\'interface de niveau supérieur d\'un service de fournisseur de conditions. Ne devrait pas être nécessaire pour les applications standards."</string>
+    <string name="permdesc_bindConditionProviderService" msgid="6106018791256120258">"Permet à l\'appli de s\'associer à l\'interface de niveau supérieur d\'un service de fournisseur de conditions. Ne devrait pas être nécessaire pour les applis standards."</string>
     <string name="permlab_bindDreamService" msgid="4776175992848982706">"associer à un service de rêve"</string>
-    <string name="permdesc_bindDreamService" msgid="9129615743300572973">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service de rêve. Les applications standard ne devraient pas avoir recours à cette fonctionnalité."</string>
-    <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"faire appel à l\'application de configuration du fournisseur de services"</string>
-    <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"Permet à l\'application autorisée de faire appel à l\'application de configuration fournie par le fournisseur de services. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
+    <string name="permdesc_bindDreamService" msgid="9129615743300572973">"Permet à l\'appli autorisée de s\'associer à l\'interface de plus haut niveau d\'un service de rêve. Les applis standard ne devraient pas avoir recours à cette fonctionnalité."</string>
+    <string name="permlab_invokeCarrierSetup" msgid="5098810760209818140">"faire appel à l\'appli de configuration du fournisseur de services"</string>
+    <string name="permdesc_invokeCarrierSetup" msgid="4790845896063237887">"Permet à l\'appli autorisée de faire appel à l\'appli de configuration fournie par le fournisseur de services. Cette fonctionnalité ne devrait pas être nécessaire pour les applis standards."</string>
     <string name="permlab_accessNetworkConditions" msgid="1270732533356286514">"détecter des observations sur les conditions du réseau"</string>
-    <string name="permdesc_accessNetworkConditions" msgid="2959269186741956109">"Permet à une application de détecter les observations sur les conditions du réseau. Ne devrait jamais être nécessaire pour les applications standards."</string>
+    <string name="permdesc_accessNetworkConditions" msgid="2959269186741956109">"Permet à une appli de détecter les observations sur les conditions du réseau. Ne devrait jamais être nécessaire pour les applis standards."</string>
     <string name="permlab_setInputCalibration" msgid="932069700285223434">"modifier le calibrage du périphérique d\'entrée"</string>
-    <string name="permdesc_setInputCalibration" msgid="2937872391426631726">"Permet à l\'application de modifier les paramètres de calibrage de l\'écran tactile. Ne devrait jamais être nécessaire pour les applications standards."</string>
+    <string name="permdesc_setInputCalibration" msgid="2937872391426631726">"Permet à l\'appli de modifier les paramètres de calibrage de l\'écran tactile. Ne devrait jamais être nécessaire pour les applis standards."</string>
     <string name="permlab_accessDrmCertificates" msgid="6473765454472436597">"accéder aux certificats GDN"</string>
-    <string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"Permet à une application de fournir et d\'utiliser les certificats de GDN. Cela ne devrait jamais être nécessaire pour les applications normales."</string>
+    <string name="permdesc_accessDrmCertificates" msgid="6983139753493781941">"Permet à une appli de fournir et d\'utiliser les certificats de GDN. Cela ne devrait jamais être nécessaire pour les applis normales."</string>
     <string name="permlab_handoverStatus" msgid="7620438488137057281">"recevoir des données sur l\'état du transfert Android Beam"</string>
-    <string name="permdesc_handoverStatus" msgid="3842269451732571070">"Autoriser cette application à recevoir des données sur les transferts Android Beam en cours"</string>
+    <string name="permdesc_handoverStatus" msgid="3842269451732571070">"Autoriser cette appli à recevoir des données sur les transferts Android Beam en cours"</string>
     <string name="permlab_removeDrmCertificates" msgid="710576248717404416">"supprimer des certificats GDN"</string>
-    <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Permet à une application de supprimer les certificats GDN. Cela ne devrait jamais être nécessaire pour des applications normales."</string>
+    <string name="permdesc_removeDrmCertificates" msgid="4068445390318355716">"Permet à une appli de supprimer les certificats GDN. Cela ne devrait jamais être nécessaire pour des applis normales."</string>
     <string name="permlab_bindCarrierMessagingService" msgid="3363450860593096967">"s\'associer à un service de messagerie d\'un fournisseur"</string>
-    <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service de messagerie d\'un fournisseur. Les applications standards ne devraient jamais avoir recours à cette fonctionnalité."</string>
+    <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Permet à l\'appli autorisée de s\'associer à l\'interface de plus haut niveau d\'un service de messagerie d\'un fournisseur. Les applis standards ne devraient jamais avoir recours à cette fonctionnalité."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"s\'associer aux services d\'un fournisseur"</string>
-    <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Permet à l\'application autorisée de s\'associer aux services d\'un fournisseur. Ne devrait pas être nécessaire pour les applications standards."</string>
+    <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Permet à l\'appli autorisée de s\'associer aux services d\'un fournisseur. Ne devrait pas être nécessaire pour les applis standards."</string>
     <string name="permlab_access_notification_policy" msgid="5524112842876975537">"accéder au mode Ne pas déranger"</string>
-    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permet à l\'application de consulter et de modifier la configuration du mode Ne pas déranger."</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permet à l\'appli de consulter et de modifier la configuration du mode Ne pas déranger."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"démarrer l\'affichage de l\'usage des autorisations"</string>
-    <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permet au détenteur de démarrer l\'usage des autorisations pour une application. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
+    <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permet au détenteur de démarrer l\'usage des autorisations pour une appli. Cette fonctionnalité ne devrait pas être nécessaire pour les applis standards."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"démarrer les décisions d\'autorisation de lecture"</string>
-    <string name="permdesc_startReviewPermissionDecisions" msgid="2775556853503004236">"Permet au détenteur de démarrer l\'écran pour revoir les décisions d\'autorisation. Ne devrait pas être requis pour les applications standards."</string>
-    <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"démarrer l\'affichage des fonctionnalités de l\'application"</string>
-    <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Permet au détenteur de commencer à afficher les renseignements sur les fonctionnalités d\'une application."</string>
+    <string name="permdesc_startReviewPermissionDecisions" msgid="2775556853503004236">"Permet au détenteur de démarrer l\'écran pour revoir les décisions d\'autorisation. Ne devrait pas être requis pour les applis standards."</string>
+    <string name="permlab_startViewAppFeatures" msgid="7955084203185903001">"démarrer l\'affichage des fonctionnalités de l\'appli"</string>
+    <string name="permdesc_startViewAppFeatures" msgid="7207240860165206107">"Permet au détenteur de commencer à afficher les renseignements sur les fonctionnalités d\'une appli."</string>
     <string name="permlab_highSamplingRateSensors" msgid="3941068435726317070">"accéder aux données des capteurs à un taux d’échantillonnage élevé"</string>
-    <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Permet à l’application d’échantillonner les données des capteurs à une fréquence supérieure à 200 Hz"</string>
-    <string name="permlab_updatePackagesWithoutUserAction" msgid="3363272609642618551">"Mettre à jour l\'application sans intervention de l\'utilisateur"</string>
-    <string name="permdesc_updatePackagesWithoutUserAction" msgid="4567739631260526366">"Permet à une application précédemment installée de se mettre à jour sans intervention de l\'utilisateur"</string>
-    <string name="permlab_writeVerificationStateE2eeContactKeys" msgid="3990742344778360457">"mettre à jour les états des vérifications des clés de contact chiffrées de bout en bout qui appartiennent à d\'autres applications"</string>
-    <string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"Autorise l\'application à mettre à jour les états des vérifications des clés de contact chiffrées de bout en bout qui appartiennent à d\'autres applications"</string>
+    <string name="permdesc_highSamplingRateSensors" msgid="8430061978931155995">"Permet à l’appli d’échantillonner les données des capteurs à une fréquence supérieure à 200 Hz"</string>
+    <string name="permlab_updatePackagesWithoutUserAction" msgid="3363272609642618551">"Mettre à jour l\'appli sans intervention de l\'utilisateur"</string>
+    <string name="permdesc_updatePackagesWithoutUserAction" msgid="4567739631260526366">"Permet à une appli précédemment installée de se mettre à jour sans intervention de l\'utilisateur"</string>
+    <string name="permlab_writeVerificationStateE2eeContactKeys" msgid="3990742344778360457">"mettre à jour les états des vérifications des clés de contact chiffrées de bout en bout qui appartiennent à d\'autres applis"</string>
+    <string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"Autorise l\'appli à mettre à jour les états des vérifications des clés de contact chiffrées de bout en bout qui appartiennent à d\'autres applis"</string>
     <string name="policylab_limitPassword" msgid="4851829918814422199">"Définir les règles du mot de passe"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"Gérer le nombre et le type de caractères autorisés dans les mots de passe et les NIP de verrouillage de l\'écran."</string>
     <string name="policylab_watchLogin" msgid="7599669460083719504">"Gérer les tentatives de déverrouillage de l\'écran"</string>
@@ -864,7 +864,7 @@
     <string name="policylab_expirePassword" msgid="6015404400532459169">"Déf. expir. m. passe verr. écr."</string>
     <string name="policydesc_expirePassword" msgid="9136524319325960675">"Modifier la fréquence de modification du mot de passe, du NIP ou du schéma de verrouillage de l\'écran."</string>
     <string name="policylab_encryptedStorage" msgid="9012936958126670110">"Définir cryptage du stockage"</string>
-    <string name="policydesc_encryptedStorage" msgid="1102516950740375617">"Exiger le chiffrement des données d\'application stockées"</string>
+    <string name="policydesc_encryptedStorage" msgid="1102516950740375617">"Exiger le chiffrement des données d\'appli stockées"</string>
     <string name="policylab_disableCamera" msgid="5749486347810162018">"Désactiver les appareils photo"</string>
     <string name="policydesc_disableCamera" msgid="3204405908799676104">"Empêcher l\'utilisation de tous les appareils photos"</string>
     <string name="policylab_disableKeyguardFeatures" msgid="5071855750149949741">"Désact. fonctions verr. écran"</string>
@@ -982,7 +982,7 @@
     <string name="sipAddressTypeHome" msgid="5918441930656878367">"Domicile"</string>
     <string name="sipAddressTypeWork" msgid="7873967986701216770">"Travail"</string>
     <string name="sipAddressTypeOther" msgid="6317012577345187275">"Autre"</string>
-    <string name="quick_contacts_not_available" msgid="1262709196045052223">"Aucune application permettant d\'afficher ce contact n\'a été trouvée."</string>
+    <string name="quick_contacts_not_available" msgid="1262709196045052223">"Aucune appli permettant d\'afficher ce contact n\'a été trouvée."</string>
     <string name="keyguard_password_enter_pin_code" msgid="6401406801060956153">"Saisissez le NIP."</string>
     <string name="keyguard_password_enter_puk_code" msgid="3112256684547584093">"Saisissez la clé PUK et le nouveau NIP."</string>
     <string name="keyguard_password_enter_puk_prompt" msgid="2825313071899938305">"Clé PUK"</string>
@@ -1100,9 +1100,9 @@
     <string name="js_dialog_before_unload" msgid="7213364985774778744">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nVoulez-vous vraiment quitter cette page?"</string>
     <string name="autofill_window_title" msgid="4379134104008111961">"Remplissage automatique avec <xliff:g id="SERVICENAME">%1$s</xliff:g>"</string>
     <string name="permlab_setAlarm" msgid="1158001610254173567">"définir une alarme"</string>
-    <string name="permdesc_setAlarm" msgid="2185033720060109640">"Permet à l\'application de régler la sonnerie d\'une fonction de réveil installée sur votre appareil. Cette fonctionnalité n\'est pas compatible avec toutes les applications de réveils."</string>
+    <string name="permdesc_setAlarm" msgid="2185033720060109640">"Permet à l\'appli de régler la sonnerie d\'une fonction de réveil installée sur votre appareil. Cette fonctionnalité n\'est pas compatible avec toutes les applis de réveils."</string>
     <string name="permlab_addVoicemail" msgid="4770245808840814471">"ajouter des messages vocaux"</string>
-    <string name="permdesc_addVoicemail" msgid="5470312139820074324">"Permet à l\'application d\'ajouter des messages à votre messagerie vocale."</string>
+    <string name="permdesc_addVoicemail" msgid="5470312139820074324">"Permet à l\'appli d\'ajouter des messages à votre messagerie vocale."</string>
     <string name="pasted_from_clipboard" msgid="7355790625710831847">"<xliff:g id="PASTING_APP_NAME">%1$s</xliff:g> a collé du contenu de votre presse-papiers"</string>
     <string name="more_item_label" msgid="7419249600215749115">"Plus"</string>
     <string name="prepend_shortcut_label" msgid="1743716737502867951">"Menu+"</string>
@@ -1199,7 +1199,7 @@
     <string name="low_internal_storage_view_text" msgid="8172166728369697835">"Il est possible que certaines fonctionnalités du système ne soient pas opérationnelles."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"Espace de stockage insuffisant pour le système. Assurez-vous de disposer de 250 Mo d\'espace libre, puis redémarrez."</string>
     <string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> en cours d\'exécution"</string>
-    <string name="app_running_notification_text" msgid="5120815883400228566">"Touchez pour en savoir plus ou pour arrêter l\'application."</string>
+    <string name="app_running_notification_text" msgid="5120815883400228566">"Touchez pour en savoir plus ou pour arrêter l\'appli."</string>
     <string name="ok" msgid="2646370155170753815">"OK"</string>
     <string name="cancel" msgid="6908697720451760115">"Annuler"</string>
     <string name="yes" msgid="9069828999585032361">"OK"</string>
@@ -1234,28 +1234,28 @@
     <string name="whichSendToApplication" msgid="77101541959464018">"Envoyer avec"</string>
     <string name="whichSendToApplicationNamed" msgid="3385686512014670003">"Envoyer avec %1$s"</string>
     <string name="whichSendToApplicationLabel" msgid="3543240188816513303">"Envoyer"</string>
-    <string name="whichHomeApplication" msgid="8276350727038396616">"Sélectionner une application pour l\'écran d\'accueil"</string>
+    <string name="whichHomeApplication" msgid="8276350727038396616">"Sélectionner une appli pour l\'écran d\'accueil"</string>
     <string name="whichHomeApplicationNamed" msgid="5855990024847433794">"Utiliser %1$s comme écran d\'accueil"</string>
     <string name="whichHomeApplicationLabel" msgid="8907334282202933959">"Enregistrer l\'image"</string>
     <string name="whichImageCaptureApplication" msgid="2737413019463215284">"Enregistrer l\'image avec"</string>
     <string name="whichImageCaptureApplicationNamed" msgid="8820702441847612202">"Enregistrer l\'image avec %1$s"</string>
     <string name="whichImageCaptureApplicationLabel" msgid="6505433734824988277">"Enregistrer l\'image"</string>
-    <string name="alwaysUse" msgid="3153558199076112903">"Utiliser cette application par défaut pour cette action"</string>
+    <string name="alwaysUse" msgid="3153558199076112903">"Utiliser cette appli par défaut pour cette action"</string>
     <string name="use_a_different_app" msgid="4987790276170972776">"Utiliser une appli différente"</string>
-    <string name="clearDefaultHintMsg" msgid="1325866337702524936">"Pour supprimer les valeurs par défaut, accédez à Paramètres système &gt; Applications &gt; Téléchargements."</string>
+    <string name="clearDefaultHintMsg" msgid="1325866337702524936">"Pour supprimer les valeurs par défaut, accédez à Paramètres système &gt; Applis &gt; Téléchargements."</string>
     <string name="chooseActivity" msgid="8563390197659779956">"Sélectionnez une action"</string>
-    <string name="chooseUsbActivity" msgid="2096269989990986612">"Sélectionnez une application pour le périphérique de stockage USB"</string>
-    <string name="noApplications" msgid="1186909265235544019">"Aucune application ne peut effectuer cette action."</string>
+    <string name="chooseUsbActivity" msgid="2096269989990986612">"Sélectionnez une appli pour le périphérique de stockage USB"</string>
+    <string name="noApplications" msgid="1186909265235544019">"Aucune appli ne peut effectuer cette action."</string>
     <string name="aerr_application" msgid="4090916809370389109">"<xliff:g id="APPLICATION">%1$s</xliff:g> a cessé de fonctionner"</string>
     <string name="aerr_process" msgid="4268018696970966407">"<xliff:g id="PROCESS">%1$s</xliff:g> a cessé de fonctionner"</string>
     <string name="aerr_application_repeated" msgid="7804378743218496566">"<xliff:g id="APPLICATION">%1$s</xliff:g> plante continuellement"</string>
     <string name="aerr_process_repeated" msgid="1153152413537954974">"<xliff:g id="PROCESS">%1$s</xliff:g> plante continuellement"</string>
-    <string name="aerr_restart" msgid="2789618625210505419">"Rouvrir l\'application"</string>
+    <string name="aerr_restart" msgid="2789618625210505419">"Rouvrir l\'appli"</string>
     <string name="aerr_report" msgid="3095644466849299308">"Envoyer des commentaires"</string>
     <string name="aerr_close" msgid="3398336821267021852">"Fermer"</string>
     <string name="aerr_mute" msgid="2304972923480211376">"Désactiver jusqu\'au redémarrage de l\'appareil"</string>
     <string name="aerr_wait" msgid="3198677780474548217">"Attendre"</string>
-    <string name="aerr_close_app" msgid="8318883106083050970">"Fermer l\'application"</string>
+    <string name="aerr_close_app" msgid="8318883106083050970">"Fermer l\'appli"</string>
     <string name="anr_title" msgid="7290329487067300120"></string>
     <string name="anr_activity_application" msgid="8121716632960340680">"<xliff:g id="APPLICATION">%2$s</xliff:g> ne répond pas"</string>
     <string name="anr_activity_process" msgid="3477362583767128667">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ne répond pas"</string>
@@ -1265,18 +1265,18 @@
     <string name="report" msgid="2149194372340349521">"Signaler"</string>
     <string name="wait" msgid="7765985809494033348">"Attendre"</string>
     <string name="webpage_unresponsive" msgid="7850879412195273433">"La page ne répond pas.\n \nVoulez-vous la fermer?"</string>
-    <string name="launch_warning_title" msgid="6725456009564953595">"Application redirigée"</string>
+    <string name="launch_warning_title" msgid="6725456009564953595">"Appli redirigée"</string>
     <string name="launch_warning_replace" msgid="3073392976283203402">"<xliff:g id="APP_NAME">%1$s</xliff:g> est maintenant lancée."</string>
-    <string name="launch_warning_original" msgid="3332206576800169626">"L\'application <xliff:g id="APP_NAME">%1$s</xliff:g> a été lancée initialement."</string>
+    <string name="launch_warning_original" msgid="3332206576800169626">"L\'appli <xliff:g id="APP_NAME">%1$s</xliff:g> a été lancée initialement."</string>
     <string name="screen_compat_mode_scale" msgid="8627359598437527726">"Redimensionner"</string>
     <string name="screen_compat_mode_show" msgid="5080361367584709857">"Toujours afficher"</string>
-    <string name="screen_compat_mode_hint" msgid="4032272159093750908">"Réactivez ce mode en accédant à Paramètres système &gt; Applications &gt; Téléchargements"</string>
+    <string name="screen_compat_mode_hint" msgid="4032272159093750908">"Réactivez ce mode en accédant à Paramètres système &gt; Applis &gt; Téléchargements"</string>
     <string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas compatible avec le paramètre de taille d\'affichage actuel et peut se comporter de manière inattendue."</string>
     <string name="unsupported_display_size_show" msgid="980129850974919375">"Toujours afficher"</string>
-    <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"<xliff:g id="APP_NAME">%1$s</xliff:g> a été conçue pour une version incompatible du système d\'exploitation Android et peut se comporter de manière inattendue. Il se peut qu\'une version mise à jour de l\'application soit proposée."</string>
+    <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"<xliff:g id="APP_NAME">%1$s</xliff:g> a été conçue pour une version incompatible du système d\'exploitation Android et peut se comporter de manière inattendue. Il se peut qu\'une version mise à jour de l\'appli soit proposée."</string>
     <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"Toujours afficher"</string>
     <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"Vérifier la présence de mises à jour"</string>
-    <string name="smv_application" msgid="3775183542777792638">"L\'application <xliff:g id="APPLICATION">%1$s</xliff:g> (du processus <xliff:g id="PROCESS">%2$s</xliff:g>) a enfreint ses propres règles du mode strict."</string>
+    <string name="smv_application" msgid="3775183542777792638">"L\'appli <xliff:g id="APPLICATION">%1$s</xliff:g> (du processus <xliff:g id="PROCESS">%2$s</xliff:g>) a enfreint ses propres règles du mode strict."</string>
     <string name="smv_process" msgid="1398801497130695446">"Le processus <xliff:g id="PROCESS">%1$s</xliff:g> a enfreint ses propres règles du mode strict."</string>
     <string name="android_upgrading_title" product="default" msgid="7279077384220829683">"Mise à jour du téléphone en cours…"</string>
     <string name="android_upgrading_title" product="tablet" msgid="4268417249079938805">"Mise à jour de la tablette en cours…"</string>
@@ -1288,7 +1288,7 @@
     <string name="android_upgrading_notification_title" product="default" msgid="3509927005342279257">"Finalisation de la m. à j. syst. en cours…"</string>
     <string name="app_upgrading_toast" msgid="1016267296049455585">"Mise à niveau de <xliff:g id="APPLICATION">%1$s</xliff:g> en cours…"</string>
     <string name="android_preparing_apk" msgid="589736917792300956">"Préparation de <xliff:g id="APPNAME">%1$s</xliff:g> en cours…"</string>
-    <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Lancement des applications…"</string>
+    <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Lancement des applis…"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Finalisation de la mise à jour."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Vous avez appuyé sur le l\'interrupteur – cette action éteint habituellement l\'écran.\n\nEssayez de toucher légèrement pendant la configuration de votre empreinte digitale."</string>
     <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Pour terminer, éteignez l\'écran"</string>
@@ -1308,9 +1308,9 @@
     <string name="dump_heap_ready_notification" msgid="2302452262927390268">"L\'empreinte de mémoire <xliff:g id="PROC">%1$s</xliff:g> est prête"</string>
     <string name="dump_heap_notification_detail" msgid="8431586843001054050">"L\'empreinte de mémoire a été recueillie. Touchez ici pour la partager."</string>
     <string name="dump_heap_title" msgid="4367128917229233901">"Partager l\'empreinte de mémoire?"</string>
-    <string name="dump_heap_text" msgid="1692649033835719336">"Le processus <xliff:g id="PROC">%1$s</xliff:g> a dépassé sa limite de mémoire de <xliff:g id="SIZE">%2$s</xliff:g>. Vous pouvez partager son empreinte de mémoire avec son développeur. Attention : Cette empreinte peut contenir certains de vos renseignements personnels auxquels l\'application a accès."</string>
+    <string name="dump_heap_text" msgid="1692649033835719336">"Le processus <xliff:g id="PROC">%1$s</xliff:g> a dépassé sa limite de mémoire de <xliff:g id="SIZE">%2$s</xliff:g>. Vous pouvez partager son empreinte de mémoire avec son développeur. Attention : Cette empreinte peut contenir certains de vos renseignements personnels auxquels l\'appli a accès."</string>
     <string name="dump_heap_system_text" msgid="6805155514925350849">"Le processus <xliff:g id="PROC">%1$s</xliff:g> a dépassé sa limite de mémoire de <xliff:g id="SIZE">%2$s</xliff:g>. Vous pouvez partager son empreinte de mémoire. Attention : Cette empreinte peut contenir des renseignements personnels auxquels le processus a accès, y compris du texte que vous avez entré."</string>
-    <string name="dump_heap_ready_text" msgid="5849618132123045516">"Une empreinte de mémoire du processus lié à l\'application <xliff:g id="PROC">%1$s</xliff:g> peut être partagée. Attention : Cette empreinte peut contenir des renseignements personnels auxquels le processus a accès, y compris du texte que vous avez entré."</string>
+    <string name="dump_heap_ready_text" msgid="5849618132123045516">"Une empreinte de mémoire du processus lié à l\'appli <xliff:g id="PROC">%1$s</xliff:g> peut être partagée. Attention : Cette empreinte peut contenir des renseignements personnels auxquels le processus a accès, y compris du texte que vous avez entré."</string>
     <string name="sendText" msgid="493003724401350724">"Sélectionner une action pour le texte"</string>
     <string name="volume_ringtone" msgid="134784084629229029">"Volume de la sonnerie"</string>
     <string name="volume_music" msgid="7727274216734955095">"Volume du contenu multimédia"</string>
@@ -1359,7 +1359,7 @@
     <string name="decline" msgid="6490507610282145874">"Refuser"</string>
     <string name="select_character" msgid="3352797107930786979">"Insérer un caractère"</string>
     <string name="sms_control_title" msgid="4748684259903148341">"Envoi de messages SMS"</string>
-    <string name="sms_control_message" msgid="6574313876316388239">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; envoie un grand nombre de SMS. Autorisez-vous cette application à poursuivre l\'envoi des messages?"</string>
+    <string name="sms_control_message" msgid="6574313876316388239">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; envoie un grand nombre de SMS. Autorisez-vous cette appli à poursuivre l\'envoi des messages?"</string>
     <string name="sms_control_yes" msgid="4858845109269524622">"Autoriser"</string>
     <string name="sms_control_no" msgid="4845717880040355570">"Refuser"</string>
     <string name="sms_short_code_confirm_message" msgid="1385416688897538724">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; souhaite envoyer un message à &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;."</string>
@@ -1368,7 +1368,7 @@
     <string name="sms_short_code_confirm_allow" msgid="920477594325526691">"Envoyer"</string>
     <string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"Annuler"</string>
     <string name="sms_short_code_remember_choice" msgid="1374526438647744862">"Mémoriser mon choix"</string>
-    <string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"Pour modifier : Paramètres &gt; Applications"</string>
+    <string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"Pour modifier : Paramètres &gt; Applis"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"Toujours autoriser"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"Ne jamais autoriser"</string>
     <string name="sim_removed_title" msgid="1349026474932481037">"Carte SIM retirée"</string>
@@ -1378,9 +1378,9 @@
     <string name="sim_added_message" msgid="6602906609509958680">"Redémarrez votre appareil pour accéder au réseau mobile."</string>
     <string name="sim_restart_button" msgid="8481803851341190038">"Redémarrer"</string>
     <string name="install_carrier_app_notification_title" msgid="5712723402213090102">"Activer le service cellulaire"</string>
-    <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"Téléchargez l\'application du fournisseur de services pour activer votre nouvelle carte SIM"</string>
-    <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Téléchargez l\'application de <xliff:g id="APP_NAME">%1$s</xliff:g> pour activer votre nouvelle carte SIM"</string>
-    <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Télécharger l\'application"</string>
+    <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"Téléchargez l\'appli du fournisseur de services pour activer votre nouvelle carte SIM"</string>
+    <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Téléchargez l\'appli de <xliff:g id="APP_NAME">%1$s</xliff:g> pour activer votre nouvelle carte SIM"</string>
+    <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Télécharger l\'appli"</string>
     <string name="carrier_app_notification_title" msgid="5815477368072060250">"Nouvelle carte SIM insérée"</string>
     <string name="carrier_app_notification_text" msgid="6567057546341958637">"Touchez ici pour effectuer la configuration"</string>
     <string name="time_picker_dialog_title" msgid="9053376764985220821">"Définir l\'heure"</string>
@@ -1412,6 +1412,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Sélectionnez cette option pour désactiver le débogage sans fil."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Mode Logiciel de test activé"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Effectuez une réinitialisation pour désactiver le mode Logiciel de test."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"La console série est activée"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"La performance est réduite. Pour désactiver cette fonction, vérifier le programme d\'amorçage."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Extension MTE expérimentale activée"</string>
@@ -1423,7 +1427,7 @@
     <string name="taking_remote_bugreport_notification_title" msgid="1582531382166919850">"Création d\'un rapport de bogue en cours..."</string>
     <string name="share_remote_bugreport_notification_title" msgid="6708897723753334999">"Partager le rapport de bogue?"</string>
     <string name="sharing_remote_bugreport_notification_title" msgid="3077385149217638550">"Partage du rapport de bogue en cours..."</string>
-    <string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"Votre administrateur a demandé un rapport de bogue pour l\'aider à dépanner cet appareil. Les applications et les données peuvent être partagées."</string>
+    <string name="share_remote_bugreport_notification_message_finished" msgid="7325635795739260135">"Votre administrateur a demandé un rapport de bogue pour l\'aider à dépanner cet appareil. Les applis et les données peuvent être partagées."</string>
     <string name="share_remote_bugreport_action" msgid="7630880678785123682">"PARTAGER"</string>
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"REFUSER"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Sélectionnez le mode de saisie"</string>
@@ -1435,7 +1439,7 @@
     <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Afficher par-dessus les autres applis"</string>
-    <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> affiche du contenu par-dessus d\'autres applications"</string>
+    <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> affiche du contenu par-dessus d\'autres applis"</string>
     <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> aff. contenu par-dessus applis"</string>
     <string name="alert_windows_notification_message" msgid="6538171456970725333">"Si vous ne voulez pas que <xliff:g id="NAME">%s</xliff:g> utilise cette fonctionnalités, touchez l\'écran pour ouvrir les paramètres, puis désactivez-la."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Désactiver"</string>
@@ -1490,17 +1494,17 @@
     <string name="ext_media_status_missing" msgid="6520746443048867314">"Non insérée"</string>
     <string name="activity_list_empty" msgid="4219430010716034252">"Aucune activité correspondante trouvée."</string>
     <string name="permlab_route_media_output" msgid="8048124531439513118">"diriger la sortie multimédia"</string>
-    <string name="permdesc_route_media_output" msgid="1759683269387729675">"Permet à une application de diriger la sortie multimédia vers d\'autres appareils externes."</string>
+    <string name="permdesc_route_media_output" msgid="1759683269387729675">"Permet à une appli de diriger la sortie multimédia vers d\'autres appareils externes."</string>
     <string name="permlab_readInstallSessions" msgid="7279049337895583621">"accéder aux sessions d\'installation"</string>
-    <string name="permdesc_readInstallSessions" msgid="4012608316610763473">"Permet à une application d\'accéder aux sessions d\'installation. Cela lui permet de consulter les détails relatifs à l\'installation des paquets actifs."</string>
+    <string name="permdesc_readInstallSessions" msgid="4012608316610763473">"Permet à une appli d\'accéder aux sessions d\'installation. Cela lui permet de consulter les détails relatifs à l\'installation des paquets actifs."</string>
     <string name="permlab_requestInstallPackages" msgid="7600020863445351154">"demander l\'installation de paquets"</string>
-    <string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"Permet à une application de demander l\'installation de paquets."</string>
+    <string name="permdesc_requestInstallPackages" msgid="3969369278325313067">"Permet à une appli de demander l\'installation de paquets."</string>
     <string name="permlab_requestDeletePackages" msgid="2541172829260106795">"demander la suppression de paquets"</string>
-    <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Permet à une application de demander la suppression de paquets."</string>
+    <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"Permet à une appli de demander la suppression de paquets."</string>
     <string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"demander d\'ignorer les optimisations de la pile"</string>
-    <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permet à une application de demander la permission d\'ignorer les optimisations de la pile."</string>
+    <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"Permet à une appli de demander la permission d\'ignorer les optimisations de la pile."</string>
     <string name="permlab_queryAllPackages" msgid="2928450604653281650">"envoyer une requête à propos de tous les paquets"</string>
-    <string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Permet à une application de voir tous les paquets installés."</string>
+    <string name="permdesc_queryAllPackages" msgid="5339069855520996010">"Permet à une appli de voir tous les paquets installés."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="1842872462124648678">"Appuyer deux fois pour régler le zoom"</string>
     <string name="gadget_host_error_inflating" msgid="2449961590495198720">"Impossible d\'ajouter le widget."</string>
     <string name="ime_action_go" msgid="5536744546326495436">"Aller"</string>
@@ -1512,7 +1516,7 @@
     <string name="ime_action_default" msgid="8265027027659800121">"Exécuter"</string>
     <string name="dial_number_using" msgid="6060769078933953531">"Composer le numéro\nen utilisant <xliff:g id="NUMBER">%s</xliff:g>"</string>
     <string name="create_contact_using" msgid="6200708808003692594">"Ajouter un contact\nen utilisant <xliff:g id="NUMBER">%s</xliff:g>"</string>
-    <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Les applications suivantes demandent l\'autorisation d\'accéder à votre compte à partir de maintenant."</string>
+    <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"Les applis suivantes demandent l\'autorisation d\'accéder à votre compte à partir de maintenant."</string>
     <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"Voulez-vous autoriser cette demande?"</string>
     <string name="grant_permissions_header_text" msgid="3420736827804657201">"Demande d\'accès"</string>
     <string name="allow" msgid="6195617008611933762">"Autoriser"</string>
@@ -1520,8 +1524,8 @@
     <string name="permission_request_notification_title" msgid="1810025922441048273">"Autorisation demandée"</string>
     <string name="permission_request_notification_with_subtitle" msgid="3743417870360129298">"Autorisation demandée\npour le compte \"<xliff:g id="ACCOUNT">%s</xliff:g>\""</string>
     <string name="permission_request_notification_for_app_with_subtitle" msgid="1298704005732851350">"Autorisation demandée par <xliff:g id="APP">%1$s</xliff:g>\npour le compte <xliff:g id="ACCOUNT">%2$s</xliff:g>."</string>
-    <string name="forward_intent_to_owner" msgid="4620359037192871015">"Vous utilisez cette application en dehors de votre profil professionnel"</string>
-    <string name="forward_intent_to_work" msgid="3620262405636021151">"Vous utilisez cette application dans votre profil professionnel"</string>
+    <string name="forward_intent_to_owner" msgid="4620359037192871015">"Vous utilisez cette appli en dehors de votre profil professionnel"</string>
+    <string name="forward_intent_to_work" msgid="3620262405636021151">"Vous utilisez cette appli dans votre profil professionnel"</string>
     <string name="input_method_binding_label" msgid="1166731601721983656">"Mode de saisie"</string>
     <string name="sync_binding_label" msgid="469249309424662147">"Synchroniser"</string>
     <string name="accessibility_binding_label" msgid="1974602776545801715">"Accessibilité"</string>
@@ -1544,8 +1548,8 @@
     <string name="no_file_chosen" msgid="4146295695162318057">"Aucun fichier sélectionné"</string>
     <string name="reset" msgid="3865826612628171429">"Réinitialiser"</string>
     <string name="submit" msgid="862795280643405865">"Envoyer"</string>
-    <string name="car_mode_disable_notification_title" msgid="8450693275833142896">"L\'application de conduite est en cours d\'exécution"</string>
-    <string name="car_mode_disable_notification_message" msgid="8954550232288567515">"Touchez pour quitter l\'application de conduite."</string>
+    <string name="car_mode_disable_notification_title" msgid="8450693275833142896">"L\'appli de conduite est en cours d\'exécution"</string>
+    <string name="car_mode_disable_notification_message" msgid="8954550232288567515">"Touchez pour quitter l\'appli de conduite."</string>
     <string name="back_button_label" msgid="4078224038025043387">"Précédent"</string>
     <string name="next_button_label" msgid="6040209156399907780">"Suivante"</string>
     <string name="skip_button_label" msgid="3566599811326688389">"Ignorer"</string>
@@ -1597,8 +1601,8 @@
     <string name="keyboardview_keycode_mode_change" msgid="2743735349997999020">"Changement de mode"</string>
     <string name="keyboardview_keycode_shift" msgid="3026509237043975573">"Maj"</string>
     <string name="keyboardview_keycode_enter" msgid="168054869339091055">"Entrée"</string>
-    <string name="activitychooserview_choose_application" msgid="3500574466367891463">"Sélectionnez une application"</string>
-    <string name="activitychooserview_choose_application_error" msgid="6937782107559241734">"Impossible de lancer l\'application <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+    <string name="activitychooserview_choose_application" msgid="3500574466367891463">"Sélectionnez une appli"</string>
+    <string name="activitychooserview_choose_application_error" msgid="6937782107559241734">"Impossible de lancer l\'appli <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="2753089758467748982">"Partagez avec"</string>
     <string name="shareactionprovider_share_with_application" msgid="4902832247173666973">"Partager avec <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="982510275422590757">"Poignée coulissante. Appuyez de manière prolongée."</string>
@@ -1626,7 +1630,7 @@
     <string name="data_usage_restricted_title" msgid="126711424380051268">"Données en arrière-plan limitées"</string>
     <string name="data_usage_restricted_body" msgid="5338694433686077733">"Touchez pour suppr. restriction."</string>
     <string name="data_usage_rapid_title" msgid="2950192123248740375">"Utilis. élevée des données cell."</string>
-    <string name="data_usage_rapid_body" msgid="3886676853263693432">"Vos applications ont utilisé plus de données que d\'habitude"</string>
+    <string name="data_usage_rapid_body" msgid="3886676853263693432">"Vos applis ont utilisé plus de données que d\'habitude"</string>
     <string name="data_usage_rapid_app_body" msgid="5425779218506513861">"<xliff:g id="APP">%s</xliff:g> a utilisé plus de données que d\'habitude"</string>
     <string name="ssl_certificate" msgid="5690020361307261997">"Certificat de sécurité"</string>
     <string name="ssl_certificate_is_valid" msgid="7293675884598527081">"Ce certificat est valide."</string>
@@ -1731,15 +1735,15 @@
     <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ACTIVÉ"</string>
     <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"DÉSACTIVÉ"</string>
     <string name="accessibility_enable_service_title" msgid="3931558336268541484">"Permettre à <xliff:g id="SERVICE">%1$s</xliff:g> de contrôler complètement votre appareil?"</string>
-    <string name="accessibility_service_warning_description" msgid="291674995220940133">"Le contrôle total convient aux applications qui répondent à vos besoins d\'accessibilité. Il ne convient pas à la plupart des applications."</string>
+    <string name="accessibility_service_warning_description" msgid="291674995220940133">"Le contrôle total convient aux applis qui répondent à vos besoins d\'accessibilité. Il ne convient pas à la plupart des applis."</string>
     <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"Afficher et contrôler l\'écran"</string>
-    <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Cette fonctionnalité peut lire tout le contenu à l\'écran et afficher du contenu par-dessus d\'autres applications."</string>
+    <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"Cette fonctionnalité peut lire tout le contenu à l\'écran et afficher du contenu par-dessus d\'autres applis."</string>
     <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"Afficher et effectuer des actions"</string>
-    <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Cette fonctionnalité peut faire le suivi de vos interactions avec une application ou un capteur matériel et interagir avec des applications en votre nom."</string>
+    <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"Cette fonctionnalité peut faire le suivi de vos interactions avec une appli ou un capteur matériel et interagir avec des applis en votre nom."</string>
     <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"Autoriser"</string>
     <string name="accessibility_dialog_button_deny" msgid="4129575637812472671">"Refuser"</string>
     <string name="accessibility_dialog_button_uninstall" msgid="2952465517671708108">"Désinstaller"</string>
-    <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"Une application masque la demande d\'autorisation de sorte que votre réponse ne peut pas être vérifiée."</string>
+    <string name="accessibility_dialog_touch_filtered_warning" msgid="3741940116597822451">"Une appli masque la demande d\'autorisation de sorte que votre réponse ne peut pas être vérifiée."</string>
     <string name="accessibility_select_shortcut_menu_title" msgid="6002726538854613272">"Toucher une fonctionnalité pour commencer à l\'utiliser :"</string>
     <string name="accessibility_edit_shortcut_menu_button_title" msgid="239446795930436325">"Choisir les fonctionnalités à utiliser à l\'aide du bouton d\'accessibilité"</string>
     <string name="accessibility_edit_shortcut_menu_volume_title" msgid="1077294237378645981">"Choisir les fonctionnalités à utiliser avec le raccourci des touches de volume"</string>
@@ -1756,12 +1760,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume maintenues enfoncées. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume maintenues enfoncées. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Relâchez les touches de volume. Pour activer <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, maintenez les deux touches de volume enfoncées pendant 3 secondes."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Choisissez une fonctionnalité à utiliser lorsque vous touchez le bouton d\'accessibilité :"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Choisissez une fonctionnalité à utiliser lorsque vous utilisez le geste d\'accessibilité (balayer l\'écran de bas en haut avec deux doigts) :"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Choisissez une fonctionnalité à utiliser lorsque vous utilisez le geste d\'accessibilité (balayer l\'écran de bas en haut avec trois doigts) :"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Pour basculer entre les fonctionnalités, maintenez le doigt sur le bouton d\'accessibilité."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Pour basculer entre les fonctionnalités, balayez l\'écran vers le haut avec deux doigts et maintenez-les-y."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Pour basculer entre les fonctionnalités, balayez l\'écran vers le haut avec trois doigts et maintenez-les-y."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"La fonctionnalité s\'ouvrira la prochaine fois que vous toucherez le bouton d\'accessibilité"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"La fonctionnalité s\'ouvrira la prochaine fois que vous utiliserez ce raccourci. Balayez l\'écran du bas vers le haut avec deux doigts et relâchez rapidement."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La fonctionnalité s\'ouvrira la prochaine fois que vous utiliserez ce raccourci. Balayez l\'écran du bas vers le haut avec trois doigts et relâchez rapidement."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Agrandissement"</string>
     <string name="user_switched" msgid="7249833311585228097">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Passage au profil : <xliff:g id="NAME">%1$s</xliff:g> en cours…"</string>
@@ -1770,7 +1777,7 @@
     <string name="guest_name" msgid="8502103277839834324">"Invité"</string>
     <string name="error_message_title" msgid="4082495589294631966">"Erreur"</string>
     <string name="error_message_change_not_allowed" msgid="843159705042381454">"Cette modification n\'est pas autorisée par votre administrateur"</string>
-    <string name="app_not_found" msgid="3429506115332341800">"Aucune application trouvée pour gérer cette action."</string>
+    <string name="app_not_found" msgid="3429506115332341800">"Aucune appli trouvée pour gérer cette action."</string>
     <string name="revoke" msgid="5526857743819590458">"Révoquer"</string>
     <string name="mediasize_iso_a0" msgid="7039061159929977973">"ISO A0"</string>
     <string name="mediasize_iso_a1" msgid="4063589931031977223">"ISO A1"</string>
@@ -1977,9 +1984,13 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Appel en cours"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrer un appel entrant"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Sans catégorie"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promotions"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Médias sociaux"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Actualités"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recommandations"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Vous définissez l\'importance de ces notifications."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Ces notifications sont importantes en raison des participants."</string>
-    <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notification d\'application personnalisée"</string>
+    <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notification d\'appli personnalisée"</string>
     <string name="user_creation_account_exists" msgid="2239146360099708035">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un utilisateur <xliff:g id="ACCOUNT">%2$s</xliff:g>? (Un utilisateur est déjà associé à ce compte)"</string>
     <string name="user_creation_adding" msgid="7305185499667958364">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à créer un profil d\'utilisateur avec le compte <xliff:g id="ACCOUNT">%2$s</xliff:g>?"</string>
     <string name="supervised_user_creation_label" msgid="6884904353827427515">"Ajouter un utilisateur supervisé"</string>
@@ -1993,17 +2004,17 @@
     <string name="language_picker_section_all" msgid="1985809075777564284">"Toutes les langues"</string>
     <string name="region_picker_section_all" msgid="756441309928774155">"Toutes les régions"</string>
     <string name="locale_search_menu" msgid="6258090710176422934">"Rechercher"</string>
-    <string name="app_suspended_title" msgid="888873445010322650">"L\'application n\'est pas accessible"</string>
-    <string name="app_suspended_default_message" msgid="6451215678552004172">"L\'application <xliff:g id="APP_NAME_0">%1$s</xliff:g> n\'est pas accessible pour le moment. Ceci est géré par <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
+    <string name="app_suspended_title" msgid="888873445010322650">"L\'appli n\'est pas accessible"</string>
+    <string name="app_suspended_default_message" msgid="6451215678552004172">"L\'appli <xliff:g id="APP_NAME_0">%1$s</xliff:g> n\'est pas accessible pour le moment. Ceci est géré par <xliff:g id="APP_NAME_1">%2$s</xliff:g>."</string>
     <string name="app_suspended_more_details" msgid="211260942831587014">"En savoir plus"</string>
-    <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Réactiver l\'application"</string>
+    <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"Réactiver l\'appli"</string>
     <string name="work_mode_off_title" msgid="6367463960165135829">"Réactiver les applis pros?"</string>
     <string name="work_mode_turn_on" msgid="5316648862401307800">"Réactiver"</string>
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Urgence"</string>
     <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Config. Verrouillage d\'écran"</string>
     <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Config. Verrouillage d\'écran"</string>
     <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Configurez verrouillage de l\'écran pour utiliser Espace privé"</string>
-    <string name="app_blocked_title" msgid="7353262160455028160">"L\'application n\'est pas accessible"</string>
+    <string name="app_blocked_title" msgid="7353262160455028160">"L\'appli n\'est pas accessible"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas accessible pour le moment."</string>
     <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> non accessible"</string>
     <string name="app_streaming_blocked_title_for_permission_dialog" msgid="3805704317624448487">"La demande d\'autorisation a été supprimée."</string>
@@ -2017,20 +2028,20 @@
     <string name="app_streaming_blocked_message" product="tv" msgid="4003011766528814377">"Impossible d\'accéder à ce contenu sur votre <xliff:g id="DEVICE">%1$s</xliff:g> pour le moment. Essayez sur votre appareil Android TV à la place."</string>
     <string name="app_streaming_blocked_message" product="tablet" msgid="4242053045964946062">"Impossible d\'accéder à ce contenu sur votre <xliff:g id="DEVICE">%1$s</xliff:g> pour le moment. Essayez sur votre tablette à la place."</string>
     <string name="app_streaming_blocked_message" product="default" msgid="6159168735030739398">"Impossible d\'accéder à ce contenu sur votre <xliff:g id="DEVICE">%1$s</xliff:g> pour le moment. Essayez sur votre téléphone à la place."</string>
-    <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"Cette application demande des autorisations supplémentaires, mais les autorisations ne peuvent pas être accordées lors d\'une session de diffusion en continu. Accordez l\'autorisation sur votre appareil Android TV d\'abord."</string>
-    <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"Cette application demande des autorisations supplémentaires, mais les autorisations ne peuvent pas être accordées lors d\'une session de diffusion en continu. Accordez l\'autorisation sur votre tablette d\'abord."</string>
-    <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"Cette application demande des autorisations supplémentaires, mais les autorisations ne peuvent pas être accordées lors d\'une session de diffusion en continu. Accordez l\'autorisation sur votre téléphone d\'abord."</string>
-    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Cette application demande une sécurité supplémentaire. Essayez sur votre appareil Android TV à la place."</string>
-    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Cette application demande une sécurité supplémentaire. Essayez sur votre tablette à la place."</string>
-    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Cette application demande une sécurité supplémentaire. Essayez sur votre téléphone à la place."</string>
+    <string name="app_streaming_blocked_message_for_permission_request" product="tv" msgid="4706276040125072077">"Cette appli demande des autorisations supplémentaires, mais les autorisations ne peuvent pas être accordées lors d\'une session de diffusion en continu. Accordez l\'autorisation sur votre appareil Android TV d\'abord."</string>
+    <string name="app_streaming_blocked_message_for_permission_request" product="tablet" msgid="1824604581465771629">"Cette appli demande des autorisations supplémentaires, mais les autorisations ne peuvent pas être accordées lors d\'une session de diffusion en continu. Accordez l\'autorisation sur votre tablette d\'abord."</string>
+    <string name="app_streaming_blocked_message_for_permission_request" product="default" msgid="7755223160363292105">"Cette appli demande des autorisations supplémentaires, mais les autorisations ne peuvent pas être accordées lors d\'une session de diffusion en continu. Accordez l\'autorisation sur votre téléphone d\'abord."</string>
+    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tv" msgid="3470977315395784567">"Cette appli demande une sécurité supplémentaire. Essayez sur votre appareil Android TV à la place."</string>
+    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="tablet" msgid="698460091901465092">"Cette appli demande une sécurité supplémentaire. Essayez sur votre tablette à la place."</string>
+    <string name="app_streaming_blocked_message_for_fingerprint_dialog" product="default" msgid="8552691971910603907">"Cette appli demande une sécurité supplémentaire. Essayez sur votre téléphone à la place."</string>
     <string name="app_streaming_blocked_message_for_settings_dialog" product="tv" msgid="820334666354451145">"Impossible d\'accéder à ce contenu sur votre <xliff:g id="DEVICE">%1$s</xliff:g>. Essayez sur votre appareil Android TV à la place."</string>
     <string name="app_streaming_blocked_message_for_settings_dialog" product="tablet" msgid="3286849551133045896">"Impossible d\'accéder à ce contenu sur votre <xliff:g id="DEVICE">%1$s</xliff:g>. Essayez sur votre tablette à la place."</string>
     <string name="app_streaming_blocked_message_for_settings_dialog" product="default" msgid="6264287556598916295">"Impossible d\'accéder à ce contenu sur votre <xliff:g id="DEVICE">%1$s</xliff:g>. Essayez sur votre téléphone à la place."</string>
-    <string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Cette application a été conçue pour une ancienne version d\'Android. Elle pourrait ne pas fonctionner correctement, et ne comprend pas les dernières protections des données confidentielles et de sécurité. Vérifiez s\'il existe une mise à jour ou contactez le développeur de l\'application."</string>
+    <string name="deprecated_target_sdk_message" msgid="5246906284426844596">"Cette appli a été conçue pour une ancienne version d\'Android. Elle pourrait ne pas fonctionner correctement, et ne comprend pas les dernières protections des données confidentielles et de sécurité. Vérifiez s\'il existe une mise à jour ou contactez le développeur de l\'appli."</string>
     <string name="deprecated_target_sdk_app_store" msgid="8456784048558808909">"Vérifier la présence de mises à jour"</string>
-    <string name="deprecated_abi_message" msgid="6820548011196218091">"Cette application n\'est pas compatible avec la dernière version d\'Android. Vérifiez s\'il existe une mise à jour ou communiquez avec le développeur de l\'application."</string>
+    <string name="deprecated_abi_message" msgid="6820548011196218091">"Cette appli n\'est pas compatible avec la dernière version d\'Android. Vérifiez s\'il existe une mise à jour ou communiquez avec le développeur de l\'appli."</string>
     <string name="new_sms_notification_title" msgid="6528758221319927107">"Vous avez de nouveaux messages"</string>
-    <string name="new_sms_notification_content" msgid="3197949934153460639">"Ouvrez l\'application de messagerie texte pour l\'afficher"</string>
+    <string name="new_sms_notification_content" msgid="3197949934153460639">"Ouvrez l\'appli de messagerie texte pour l\'afficher"</string>
     <string name="profile_encrypted_title" msgid="9001208667521266472">"Des fonctionnalités sont limitées"</string>
     <string name="profile_encrypted_detail" msgid="5279730442756849055">"Profil professionnel verrouillé"</string>
     <string name="profile_encrypted_message" msgid="1128512616293157802">"Touch. pr déver. profil profess."</string>
@@ -2040,7 +2051,7 @@
     <string name="pin_specific_target" msgid="7824671240625957415">"Épingler <xliff:g id="LABEL">%1$s</xliff:g>"</string>
     <string name="unpin_target" msgid="3963318576590204447">"Annuler l\'épinglage"</string>
     <string name="unpin_specific_target" msgid="3859828252160908146">"Annuler l\'épinglage de <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="app_info" msgid="6113278084877079851">"Détails de l\'application"</string>
+    <string name="app_info" msgid="6113278084877079851">"Détails de l\'appli"</string>
     <string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="6577581216125805905">"Démarrage de la démonstration en cours…"</string>
     <string name="demo_restarting_message" msgid="1160053183701746766">"Réinitialisation de l\'appareil en cours…"</string>
@@ -2108,14 +2119,14 @@
     <string name="mmcc_illegal_me_msim_template" msgid="4802735138861422802">"La carte SIM <xliff:g id="SIMNUMBER">%d</xliff:g> n\'est pas autorisée"</string>
     <string name="popup_window_default_title" msgid="6907717596694826919">"Fenêtre contextuelle"</string>
     <string name="slice_more_content" msgid="3377367737876888459">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
-    <string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"La version de l\'application a été rétrogradée ou n\'est pas compatible avec ce raccourci"</string>
-    <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"Impossible de restaurer le raccourci, car l\'application ne prend pas en charge la sauvegarde et la restauration"</string>
-    <string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"Impossible de restaurer le raccourci en raison d\'une erreur de correspondance des signature d\'applications"</string>
+    <string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"La version de l\'appli a été rétrogradée ou n\'est pas compatible avec ce raccourci"</string>
+    <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"Impossible de restaurer le raccourci, car l\'appli ne prend pas en charge la sauvegarde et la restauration"</string>
+    <string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"Impossible de restaurer le raccourci en raison d\'une erreur de correspondance des signature d\'applis"</string>
     <string name="shortcut_restore_unknown_issue" msgid="2478146134395982154">"Impossible de restaurer le raccourci"</string>
     <string name="shortcut_disabled_reason_unknown" msgid="753074793553599166">"Le raccourci est désactivé"</string>
     <string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DÉSINSTALLER"</string>
     <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"OUVRIR QUAND MÊME"</string>
-    <string name="harmful_app_warning_title" msgid="8794823880881113856">"Une application nuisible a été détectée"</string>
+    <string name="harmful_app_warning_title" msgid="8794823880881113856">"Une appli nuisible a été détectée"</string>
     <string name="slices_permission_request" msgid="3677129866636153406">"<xliff:g id="APP_0">%1$s</xliff:g> souhaite afficher <xliff:g id="APP_2">%2$s</xliff:g> tranches"</string>
     <string name="screenshot_edit" msgid="7408934887203689207">"Modifier"</string>
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Les appels et les notifications vibreront"</string>
@@ -2127,14 +2138,14 @@
     <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Les paramètres du mode Ne pas déranger ont changé"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Touchez l\'écran pour vérifier ce qui est bloqué."</string>
     <string name="review_notification_settings_title" msgid="5102557424459810820">"Examiner les paramètres de notification"</string>
-    <string name="review_notification_settings_text" msgid="5916244866751849279">"À partir d\'Android 13, les applications que vous installez ont besoin de votre autorisation pour envoyer des notifications. Touchez pour modifier cette autorisation pour les applications existantes."</string>
+    <string name="review_notification_settings_text" msgid="5916244866751849279">"À partir d\'Android 13, les applis que vous installez ont besoin de votre autorisation pour envoyer des notifications. Touchez pour modifier cette autorisation pour les applis existantes."</string>
     <string name="review_notification_settings_remind_me_action" msgid="1081081018678480907">"Me rappeler plus tard"</string>
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Fermer"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Système"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Paramètres"</string>
     <string name="notification_appops_camera_active" msgid="8177643089272352083">"Appareil photo"</string>
     <string name="notification_appops_microphone_active" msgid="581333393214739332">"Microphone"</string>
-    <string name="notification_appops_overlay_active" msgid="5571732753262836481">"superpose du contenu par-dessus d\'autres applications à l\'écran"</string>
+    <string name="notification_appops_overlay_active" msgid="5571732753262836481">"superpose du contenu par-dessus d\'autres applis à l\'écran"</string>
     <string name="notification_feedback_indicator" msgid="663476517711323016">"Envoyer des commentaires"</string>
     <string name="notification_feedback_indicator_alerted" msgid="6552871804121942099">"La notification a été automatiquement élevée à la catégorie Par défaut. Touchez pour envoyer des commentaires."</string>
     <string name="notification_feedback_indicator_silenced" msgid="3799442124723177262">"Cette notification a été rétrogradée à Silencieuse. Touchez pour envoyer des commentaires."</string>
@@ -2157,7 +2168,7 @@
     <string name="battery_saver_charged_notification_summary" product="tablet" msgid="4426317048139996888">"La tablette est suffisamment chargée. Ces fonctionnalités ne sont plus restreintes."</string>
     <string name="battery_saver_charged_notification_summary" product="device" msgid="1031562417867646649">"L\'appareil est suffisamment chargé. Ces fonctionnalités ne sont plus restreintes."</string>
     <string name="mime_type_folder" msgid="2203536499348787650">"Dossier"</string>
-    <string name="mime_type_apk" msgid="3168784749499623902">"Application Android"</string>
+    <string name="mime_type_apk" msgid="3168784749499623902">"Appli Android"</string>
     <string name="mime_type_generic" msgid="4606589110116560228">"Fichier"</string>
     <string name="mime_type_generic_ext" msgid="9220220924380909486">"Fichier <xliff:g id="EXTENSION">%1$s</xliff:g>"</string>
     <string name="mime_type_audio" msgid="4933450584432509875">"Son"</string>
@@ -2178,11 +2189,11 @@
     <string name="car_loading_profile" msgid="8219978381196748070">"Chargement en cours…"</string>
     <string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # fichier}one{{file_name} + # fichier}many{{file_name} + # fichiers}other{{file_name} + # fichiers}}"</string>
     <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Aucune recommandation de personnes avec lesquelles effectuer un partage"</string>
-    <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Liste des applications"</string>
-    <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Cette application n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait capturer du contenu audio par l\'intermédiaire de cet appareil USB."</string>
+    <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Liste des applis"</string>
+    <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Cette appli n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait capturer du contenu audio par l\'intermédiaire de cet appareil USB."</string>
     <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Accueil"</string>
     <string name="accessibility_system_action_back_label" msgid="4205361367345537608">"Retour"</string>
-    <string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Applications récentes"</string>
+    <string name="accessibility_system_action_recents_label" msgid="4782875610281649728">"Applis récentes"</string>
     <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Notifications"</string>
     <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Paramètres rapides"</string>
     <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Boîte de dialogue sur l\'alimentation"</string>
@@ -2193,6 +2204,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Sélecteur de raccourci d\'accessibilité à l\'écran"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Raccourci d\'accessibilité"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ignorer le volet de notification"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Lecture/pause du contenu multimédia"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Pavé directionnel – haut"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Pavé directionnel – bas"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Pavé directionnel – gauche"</string>
@@ -2209,22 +2222,22 @@
     <string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Affichage personnel"</string>
     <string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Affichage professionnel"</string>
     <string name="resolver_cross_profile_blocked" msgid="3014597376026044840">"Bloqué par votre administrateur informatique"</string>
-    <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Impossible de partager ce contenu avec des applications professionnelles"</string>
-    <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Impossible d\'ouvrir ce contenu avec des applications professionnelles"</string>
-    <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Impossible de partager ce contenu avec des applications personnelles"</string>
-    <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Impossible d\'ouvrir ce contenu avec des applications personnelles"</string>
-    <string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"Les applications professionnelles sont interrompues"</string>
+    <string name="resolver_cant_share_with_work_apps_explanation" msgid="9071442683080586643">"Impossible de partager ce contenu avec des applis professionnelles"</string>
+    <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Impossible d\'ouvrir ce contenu avec des applis professionnelles"</string>
+    <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Impossible de partager ce contenu avec des applis personnelles"</string>
+    <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Impossible d\'ouvrir ce contenu avec des applis personnelles"</string>
+    <string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"Les applis professionnelles sont interrompues"</string>
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Réactiver"</string>
-    <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Aucune application professionnelle"</string>
-    <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Aucune application personnelle"</string>
+    <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Aucune appli professionnelle"</string>
+    <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Aucune appli personnelle"</string>
     <string name="miniresolver_open_work" msgid="6286176185835401931">"Ouvrir le profil professionnel de <xliff:g id="APP">%s</xliff:g>?"</string>
     <string name="miniresolver_open_in_personal" msgid="807427577794490375">"Ouvrir <xliff:g id="APP">%s</xliff:g> dans le profil personnel?"</string>
     <string name="miniresolver_open_in_work" msgid="941341494673509916">"Ouvrir <xliff:g id="APP">%s</xliff:g> dans le profil professionnel?"</string>
-    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Appeler à partir de l\'application professionnelle?"</string>
-    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Passer à l\'application professionnelle?"</string>
-    <string name="miniresolver_call_information" msgid="6739417525304184083">"Votre organisation vous autorise à passer des appels uniquement à partir d\'applications professionnelles"</string>
-    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Votre organisation vous autorise à envoyer des messages uniquement à partir d\'applications professionnelles"</string>
-    <string name="miniresolver_private_space_phone_information" msgid="4469511223312488570">"Vous ne pouvez passer des appels téléphoniques qu\'à partir de votre application Téléphone personnelle. Les appels passés à l\'aide de cette dernière seront ajoutés à votre historique personnel des appels."</string>
+    <string name="miniresolver_call_in_work" msgid="528779988307529039">"Appeler à partir de l\'appli professionnelle?"</string>
+    <string name="miniresolver_switch_to_work" msgid="1042640606122638596">"Passer à l\'appli professionnelle?"</string>
+    <string name="miniresolver_call_information" msgid="6739417525304184083">"Votre organisation vous autorise à passer des appels uniquement à partir d\'applis professionnelles"</string>
+    <string name="miniresolver_sms_information" msgid="4311292661329483088">"Votre organisation vous autorise à envoyer des messages uniquement à partir d\'applis professionnelles"</string>
+    <string name="miniresolver_private_space_phone_information" msgid="4469511223312488570">"Vous ne pouvez passer des appels téléphoniques qu\'à partir de votre appli Téléphone personnelle. Les appels passés à l\'aide de cette dernière seront ajoutés à votre historique personnel des appels."</string>
     <string name="miniresolver_private_space_messages_information" msgid="111285656327622118">"Vous ne pouvez envoyer des messages texte qu\'à partir de votre appli Messages personnelle."</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Utiliser le navigateur du profil personnel"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Utiliser le navigateur du profil professionnel"</string>
@@ -2348,35 +2361,35 @@
     <string name="dismiss_action" msgid="1728820550388704784">"Fermer"</string>
     <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Débloquer le microphone de l\'appareil"</string>
     <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Débloquer l\'appareil photo de l\'appareil"</string>
-    <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Pour &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ainsi que toutes les applications et tous les services"</string>
+    <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Pour &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; ainsi que toutes les applis et tous les services"</string>
     <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Débloquer"</string>
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Confidentialité des capteurs"</string>
-    <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icône de l\'application"</string>
-    <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Image de marque de l\'application"</string>
+    <string name="splash_screen_view_icon_description" msgid="180638751260598187">"Icône de l\'appli"</string>
+    <string name="splash_screen_view_branding_description" msgid="7911129347402728216">"Image de marque de l\'appli"</string>
     <string name="view_and_control_notification_title" msgid="4300765399209912240">"Vérifiez les paramètres d\'accès"</string>
     <string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> peut voir et contrôler votre écran. Touchez pour examiner."</string>
     <string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"Message <xliff:g id="MESSAGE">%1$s</xliff:g> traduit."</string>
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Message traduit : <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> vers <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Activité en arrière-plan"</string>
-    <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"Une application décharge votre pile"</string>
-    <string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Une application est toujours active"</string>
+    <string name="notification_title_abusive_bg_apps" msgid="994230770856147656">"Une appli décharge votre pile"</string>
+    <string name="notification_title_long_running_fgs" msgid="8170284286477131587">"Une appli est toujours active"</string>
     <string name="notification_content_abusive_bg_apps" msgid="5296898075922695259">"<xliff:g id="APP">%1$s</xliff:g> s\'exécute en arrière-plan. Touchez pour gérer l\'utilisation de la pile."</string>
-    <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> peut avoir une incidence sur l\'autonomie de la pile. Touchez pour examiner les applications actives."</string>
-    <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Vérifier les applications actives"</string>
+    <string name="notification_content_long_running_fgs" msgid="8258193410039977101">"<xliff:g id="APP">%1$s</xliff:g> peut avoir une incidence sur l\'autonomie de la pile. Touchez pour examiner les applis actives."</string>
+    <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Vérifier les applis actives"</string>
     <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="vdm_secure_window" msgid="161700398158812314">"Vous ne pouvez pas y accéder lorsque vous utilisez la diffusion en continu. Essayez sur votre téléphone à la place."</string>
     <string name="vdm_pip_blocked" msgid="4036107522497281397">"Impossible d\'afficher des incrustations d\'image pendant une diffusion en continu"</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>
-    <string name="permlab_companionProfileWatch" msgid="2457738382085872542">"Autorisation du profil de la montre de l\'application compagnon pour gérer les montres"</string>
-    <string name="permdesc_companionProfileWatch" msgid="5655698581110449397">"Autorise une application compagnon à gérer les montres."</string>
+    <string name="permlab_companionProfileWatch" msgid="2457738382085872542">"Autorisation du profil de la montre de l\'appli compagnon pour gérer les montres"</string>
+    <string name="permdesc_companionProfileWatch" msgid="5655698581110449397">"Autorise une appli compagnon à gérer les montres."</string>
     <string name="permlab_observeCompanionDevicePresence" msgid="9008994909653990465">"Surveiller la présence d\'un appareil compagnon"</string>
-    <string name="permdesc_observeCompanionDevicePresence" msgid="3011699826788697852">"Autorise une application compagnon à surveiller la présence d\'un appareil compagnon lorsque les appareils sont à proximité ou éloignés."</string>
-    <string name="permlab_deliverCompanionMessages" msgid="3931552294842980887">"Transmettre les messages des applications compagnons"</string>
-    <string name="permdesc_deliverCompanionMessages" msgid="2170847384281412850">"Autorise une application compagnon à transmettre des messages à d\'autres appareils."</string>
+    <string name="permdesc_observeCompanionDevicePresence" msgid="3011699826788697852">"Autorise une appli compagnon à surveiller la présence d\'un appareil compagnon lorsque les appareils sont à proximité ou éloignés."</string>
+    <string name="permlab_deliverCompanionMessages" msgid="3931552294842980887">"Transmettre les messages des applis compagnons"</string>
+    <string name="permdesc_deliverCompanionMessages" msgid="2170847384281412850">"Autorise une appli compagnon à transmettre des messages à d\'autres appareils."</string>
     <string name="permlab_startForegroundServicesFromBackground" msgid="6363004936218638382">"Lancer les services d\'avant-plan à partir de l\'arrière-plan"</string>
-    <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Permet à une application compagnon en arrière-plan de lancer des services d\'avant-plan."</string>
+    <string name="permdesc_startForegroundServicesFromBackground" msgid="4071826571656001537">"Permet à une appli compagnon en arrière-plan de lancer des services d\'avant-plan."</string>
     <string name="mic_access_on_toast" msgid="2666925317663845156">"Le microphone est accessible"</string>
     <string name="mic_access_off_toast" msgid="8111040892954242437">"Le microphone est bloqué"</string>
     <string name="connected_display_unavailable_notification_title" msgid="5265409360902073556">"Impossible de dupliquer l\'écran"</string>
@@ -2412,19 +2425,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espace privé"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"Le contenu confidentiel de la notification est masqué"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Le contenu de l\'application est masqué du Partage d\'écran par mesure de sécurité"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Le contenu de l\'appli est masqué du Partage d\'écran par mesure de sécurité"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"Connecté au satellite automatiquement"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Vous pouvez envoyer et recevoir des messages sans avoir recours à un appareil mobile ou à un réseau Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ouvrir Messages"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Fonctionnement"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"En attente…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurer le Déverrouillage par empreinte digitale à nouveau"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ne fonctionnait pas bien et a été supprimée"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne fonctionnaient pas bien et ont été supprimées"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ne fonctionnait pas bien et a été supprimée. Configurez-le à nouveau pour déverrouiller votre téléphone avec l\'empreinte digitale."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne fonctionnaient pas bien et ont été supprimées. Configurez-les à nouveau pour déverrouiller votre téléphone avec votre empreinte digitale."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"L\'empreinte digitale <xliff:g id="FINGERPRINT">%s</xliff:g> ne peut plus être reconnue."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Les empreintes digitales <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne peuvent plus être reconnues."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"L\'empreinte digitale <xliff:g id="FINGERPRINT">%s</xliff:g> ne peut plus être reconnue. Reconfigurez le Déverrouillage par empreinte digitale."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Les empreintes digitales <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne peuvent plus être reconnues. Reconfigurez le Déverrouillage par empreinte digitale."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Configurer le Déverrouillage par reconnaissance faciale à nouveau"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Votre modèle facial ne fonctionnait pas bien et a été supprimé. Configurez-le à nouveau pour déverrouiller votre téléphone avec votre visage."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Votre modèle facial ne peut plus être reconnu. Reconfigurez le Déverrouillage par reconnaissance faciale."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurer"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Plus tard"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarme pour <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Changer d\'utilisateur"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Désactiver le son"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Toucher pour désactiver le son"</string>
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index f1a81a3..e4b87ed 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1412,6 +1412,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Sélectionnez cette option pour désactiver le débogage sans fil."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Mode Atelier de test activé"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Rétablissez la configuration d\'usine pour désactiver le mode Atelier de test."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Console série activée"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Les performances sont affectées. Pour désactiver la console série, vérifiez le bootloader."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"MTE expérimentale activée"</string>
@@ -1756,12 +1760,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Relâchez les boutons de volume. Pour activer <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, appuyez de nouveau sur les deux boutons de volume pendant trois secondes."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Choisissez une fonctionnalité à utiliser lorsque vous appuyez sur le bouton Accessibilité :"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Choisissez une fonctionnalité à utiliser avec le geste d\'accessibilité (balayez l\'écran de bas en haut avec deux doigts) :"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Choisissez une fonctionnalité à utiliser avec le geste d\'accessibilité (balayer l\'écran de bas en haut avec trois doigts) :"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Pour changer de fonctionnalité, appuyez de manière prolongée sur le bouton Accessibilité."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Pour changer de fonctionnement, balayez l\'écran vers le haut avec deux doigts et appuyez de manière prolongée."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Pour changer de fonctionnalité, balayez l\'écran vers le haut avec trois doigts et appuyez de manière prolongée."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"La fonctionnalité s\'ouvrira la prochaine fois que vous appuierez sur le bouton Accessibilité"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"La fonctionnalité s\'ouvrira la prochaine fois que vous utiliserez ce raccourci. Balayez du bas de l\'écran vers le haut avec deux doigts et relâchez rapidement."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La fonctionnalité s\'ouvrira la prochaine fois que vous utiliserez ce raccourci. Balayez du bas de l\'écran vers le haut avec trois doigts et relâchez rapidement."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Agrandissement"</string>
     <string name="user_switched" msgid="7249833311585228097">"Utilisateur actuel : <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Passage à <xliff:g id="NAME">%1$s</xliff:g>..."</string>
@@ -1977,6 +1984,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Appel en cours"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrage d\'un appel entrant"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Sans catégorie"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promotions"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Réseaux sociaux"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Actualités"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recommandations"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Vous définissez l\'importance de ces notifications."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Ces notifications sont importantes en raison des participants."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notification d\'application personnalisée"</string>
@@ -2193,6 +2204,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Outil de sélection des raccourcis d\'accessibilité à l\'écran"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Raccourci d\'accessibilité"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Fermer le volet des notifications"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Contenu multimédia : lecture/pause"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Pavé directionnel - Haut"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Pavé directionnel - Bas"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Pavé directionnel - Gauche"</string>
@@ -2412,19 +2425,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espace privé"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"Le contenu sensible de la notification a été masqué"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Le contenu de l\'appli est masqué lors du partage d\'écran pour des raisons de sécurité"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Le contenu de l\'appli est masqué lors du partage d\'écran par mesure de sécurité"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"Connecté automatiquement au réseau satellite"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Vous pouvez envoyer et recevoir des messages sans connexion au réseau mobile ou Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ouvrir Messages"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Fonctionnement"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"En attente…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Reconfigurer le déverrouillage par empreinte digitale"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ne fonctionnait pas correctement et a été supprimée"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne fonctionnaient pas correctement et ont été supprimées"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ne fonctionnait pas correctement et a été supprimée. Configurez-la à nouveau pour déverrouiller votre téléphone à l\'aide de votre empreinte digitale."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne fonctionnaient pas correctement et ont été supprimées. Configurez-les à nouveau pour déverrouiller votre téléphone à l\'aide de votre empreinte digitale."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ne peut plus être reconnue."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne peuvent plus être reconnues."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ne peut plus être reconnue. Reconfigurez le déverrouillage par empreinte digitale."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> et <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ne peuvent plus être reconnues. Reconfigurez le déverrouillage par empreinte digitale."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Reconfigurer le déverrouillage par reconnaissance faciale"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Votre empreinte faciale ne fonctionnait pas correctement et a été supprimée. Configurez-la à nouveau pour déverrouiller votre téléphone à l\'aide de votre visage."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Votre empreinte faciale ne peut plus être reconnue. Reconfigurez le déverrouillage par reconnaissance faciale."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configuration"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Pas maintenant"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarme pour <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Changer d\'utilisateur"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Couper le son"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Appuyer pour couper le son"</string>
 </resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index c29d888..2adedd5 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -642,7 +642,7 @@
     <string name="permdesc_mediaLocation" msgid="597912899423578138">"Permite que a aplicación lea as localizacións da túa colección multimedia."</string>
     <string name="biometric_app_setting_name" msgid="3339209978734534457">"Utilizar desbloqueo biométrico"</string>
     <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Utilizar desbloqueo biométrico ou credencial do dispositivo"</string>
-    <string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica que es ti"</string>
+    <string name="biometric_dialog_default_title" msgid="55026799173208210">"Verifica a túa identidade"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Para continuar, utiliza o desbloqueo biométrico"</string>
     <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Para continuar, utiliza o desbloqueo biométrico ou o bloqueo de pantalla"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"O hardware biométrico non está dispoñible"</string>
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecciona para desactivar a depuración sen fíos."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Activouse o modo de axente de proba"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Restablece a configuración de fábrica para desactivar o modo de axente de proba."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"A consola de serie está activada"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"O rendemento vese afectado. Para desactivar a consola, comproba o cargador de arranque."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"A MTE experimental está activada"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume premidas. Activouse o servizo <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume premidas. Desactivouse <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Solta as teclas de volume. Para activar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, mantenas premidas de novo durante 3 segundos."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Escolle a función que queres utilizar cando toques o botón Accesibilidade:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Escolle a función que queres usar co xesto de accesibilidade (pasa dous dedos cara arriba desde a parte inferior da pantalla):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Escolle a función que queres usar co xesto de accesibilidade (pasa tres dedos cara arriba desde a parte inferior da pantalla):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Para cambiar de función, mantén premido o botón Accesibilidade."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Para cambiar de función, pasa dous dedos cara arriba pola pantalla e mantén premido."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Para cambiar de función, pasa tres dedos cara arriba pola pantalla e mantén premido."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"A función abrirase cando volvas tocar o botón Accesibilidade"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"A función abrirase cando volvas usar este atallo. Pasa dous dedos desde a parte inferior da pantalla e solta rapidamente."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"A función abrirase cando volvas usar este atallo. Pasa tres dedos desde a parte inferior da pantalla e solta rapidamente."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliación"</string>
     <string name="user_switched" msgid="7249833311585228097">"Usuario actual <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chamada en curso"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando chamada entrante"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Sen clasificar"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promocións"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Novidades"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recomendacións"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Ti defines a importancia destas notificacións."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"É importante polas persoas involucradas."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificación de aplicación personalizada"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selector de atallos de accesibilidade en pantalla"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Atallo de accesibilidade"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ignorar panel despregable"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menú"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Reproducir/pór en pausa contido multimedia"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Cruceta: arriba"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Cruceta: abaixo"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Cruceta: esquerda"</string>
@@ -2411,19 +2424,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espazo privado"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"Contido confidencial da notificación oculto"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Por motivos de seguranza, ocultouse o contido da aplicación para que no se mostre na pantalla compartida"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Por seguranza, ocultouse o contido da aplicación na pantalla compartida"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"Conexión automática ao satélite"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Podes enviar e recibir mensaxes sen unha rede de telefonía móbil ou wifi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir Mensaxes"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona?"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configura de novo o desbloqueo dactilar"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"A <xliff:g id="FINGERPRINT">%s</xliff:g> non funcionaba correctamente, polo que se eliminou"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"As impresións dixitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> non funcionaban correctamente, polo que se eliminaron"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"A <xliff:g id="FINGERPRINT">%s</xliff:g> non funcionaba correctamente, polo que se eliminou. Configúraa de novo para desbloquear o teléfono usando a impresión dixital."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"As impresións dixitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> non funcionaban correctamente, polo que se eliminaron. Configúraas de novo para desbloquear o teléfono usando a impresión dixital."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> xa non se recoñece."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> xa non se recoñecen."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> xa non se recoñece. Configura de novo o desbloqueo dactilar."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> xa non se recoñecen. Configura de novo o desbloqueo dactilar."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Configura de novo o desbloqueo facial"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"O teu modelo facial non funcionaba correctamente, polo que se eliminou. Configúrao de novo para desbloquear o teléfono usando a cara."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Xa non se recoñece o teu modelo facial. Configura de novo o desbloqueo facial."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurar"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Agora non"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarma para <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Cambiar de usuario"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Silenciar"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tocar para silenciar o son"</string>
 </resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 4d350a0..6a01682 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"વાયરલેસ ડિબગીંગ બંધ કરવા માટે પસંદ કરો."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ટેસ્ટ હાર્નેસ મોડ ચાલુ કર્યો"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ટેસ્ટ હાર્નેસ મોડ બંધ કરવા માટે ફૅક્ટરી રીસેટ કરો."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"સિરીયલ કન્સોલ ચાલુ થયો"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"કાર્યપ્રદર્શનને અસર થાય છે. બંધ કરવા માટે, બૂટલોડર ચેક કરો."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"પ્રયોગાત્મક MTE ચાલુ કર્યું"</string>
@@ -1433,7 +1437,7 @@
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ભાષા અને લેઆઉટ પસંદ કરવા માટે ટૅપ કરો"</string>
     <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"અન્ય ઍપથી ઉપર બતાવો"</string>
+    <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"અન્ય ઍપની ઉપર ડિસ્પ્લે કરો"</string>
     <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> અન્ય ઍપ્લિકેશનોની ઉપર પ્રદર્શિત થઈ રહ્યું છે"</string>
     <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>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"વૉલ્યૂમ કી દબાવી રાખો. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ચાલુ કરી."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"વૉલ્યૂમ કી દબાવી રાખો. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> બંધ કરી."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"વૉલ્યૂમ કી છોડી દો. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ને ચાલુ કરવા માટે, 3 સેકન્ડ માટે બન્ને વૉલ્યૂમ કીને ફરીથી દબાવી રાખો."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"જ્યારે તમે ઍક્સેસિબિલિટી બટન પર ટૅપ કરો, ત્યારે ઉપયોગ કરવાની સુવિધા પસંદ કરો:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ઍક્સેસિબિલિટી સંકેત સાથે ઉપયોગ કરવાની સુવિધા પસંદ કરો (બે આંગળીઓ વડે સ્ક્રીનના નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરવા માટે):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ઍક્સેસિબિલિટી સંકેત સાથે ઉપયોગ કરવાની સુવિધા પસંદ કરો (ત્રણ આંગળીઓ વડે સ્ક્રીનના નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરવા માટે):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"કોઈ એક સુવિધાથી બીજી સુવિધા પર સ્વિચ કરવા માટે, ઍક્સેસિબિલિટી બટનને ટચ કરીને થોડીવાર દબાવી રાખો."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"કોઈ એક સુવિધાથી બીજી સુવિધા પર સ્વિચ કરવા માટે, બે આંગળીઓ વડે સ્ક્રીનની ઉપરની તરફ સ્વાઇપ કરીને દબાવી રાખો."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"કોઈ એક સુવિધાથી બીજી સુવિધા પર સ્વિચ કરવા માટે, ત્રણ આંગળીઓ વડે સ્ક્રીનની ઉપરની તરફ સ્વાઇપ કરીને દબાવી રાખો."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"તમે આગલી વાર જ્યારે ઍક્સેસિબિલિટી બટન પર ટૅપ કરશો, ત્યારે આ સુવિધા ચાલુ થશે"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"તમે આગલી વાર જ્યારે આ શૉર્ટકટનો ઉપયોગ કરશો, ત્યારે આ સુવિધા ચાલુ થશે. તમારી સ્ક્રીનની સૌથી નીચેથી 2 આંગળી વડે ઉપરની દિશાએ સ્વાઇપ કરો અને ઝડપથી છોડી દો."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"તમે આગલી વાર જ્યારે આ શૉર્ટકટનો ઉપયોગ કરશો, ત્યારે આ સુવિધા ચાલુ થશે. તમારી સ્ક્રીનની સૌથી નીચેથી 3 આંગળી વડે ઉપરની દિશાએ સ્વાઇપ કરો અને ઝડપથી છોડી દો."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"મોટું કરવું"</string>
     <string name="user_switched" msgid="7249833311585228097">"વર્તમાન વપરાશકર્તા <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> પર સ્વિચ કરી રહ્યાં છે…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"ચાલુ કૉલ"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"ઇનકમિંગ કૉલનું સ્ક્રીનિંગ થાય છે"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"અવર્ગીકૃત"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"પ્રમોશન"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"સામાજિક"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"ન્યૂઝ"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"સુઝાવો"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"તમે આ સૂચનાઓનું મહત્વ સેટ કર્યું છે."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"શામેલ થયેલ લોકોને કારણે આ મહત્વપૂર્ણ છે."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"ઍપનું કસ્ટમ નોટિફિકેશન"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"સ્ક્રીન પરના ઍક્સેસિબિલિટી શૉર્ટકટના પસંદકર્તા"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ઍક્સેસિબિલિટી શૉર્ટકટ"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"નોટિફિકેશન શેડ છોડી દો"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"મેનૂ"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"મીડિયા ચલાવો/થોભાવો"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"ડી-પૅડ ઉપર"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"ડી-પૅડ નીચે"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"ડી-પૅડ ડાબે"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"તેની કામ કરવાની રીત"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"બાકી..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ફિંગરપ્રિન્ટ અનલૉક સુવિધાનું ફરી સેટઅપ કરો"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> યોગ્ય રીતે કામ કરતી ન હતી અને તેને ડિલીટ કરવામાં આવી હતી"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> અને <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> યોગ્ય રીતે કામ કરતી ન હતી અને તેને ડિલીટ કરવામાં આવી હતી"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> બરાબર કામ કરતી ન હતી અને તેને ડિલીટ કરવામાં આવી હતી. તમારા ફોનને ફિંગરપ્રિન્ટ વડે અનલૉક કરવા માટે, તેનું ફરીથી સેટઅપ કરો."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> અને <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> બરાબર કામ કરતી ન હતી અને તેને ડિલીટ કરવામાં આવી હતી. તમારા ફોનને તમારી ફિંગરપ્રિન્ટ વડે અનલૉક કરવા માટે, તેનું ફરીથી સેટઅપ કરો."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"હવે <xliff:g id="FINGERPRINT">%s</xliff:g> ઓળખી શકાતી નથી."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"હવે <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> અને <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ઓળખી શકાતી નથી."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"હવે <xliff:g id="FINGERPRINT">%s</xliff:g> ઓળખી શકાતી નથી. ફિંગરપ્રિન્ટ અનલૉક સુવિધાનું ફરી સેટઅપ કરો."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"હવે <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> અને <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ઓળખી શકાતી નથી. ફિંગરપ્રિન્ટ અનલૉક સુવિધાનું ફરી સેટઅપ કરો."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"ફેસ અનલૉક સુવિધાનું ફરી સેટઅપ કરો"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"તમારા ચહેરાનું મૉડલ બરાબર કામ કરતું ન હતું અને તેને ડિલીટ કરવામાં આવ્યું હતું. તમારા ફોનને ચહેરા વડે અનલૉક કરવા માટે, તેનું ફરીથી સેટઅપ કરો."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"હવે તમારા ચહેરાનું મૉડલ ઓળખી શકાતું નથી. ફેસ અનલૉક સુવિધાનું ફરી સેટઅપ કરો."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"સેટઅપ કરો"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"હમણાં નહીં"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> માટે અલાર્મ"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"વપરાશકર્તા સ્વિચ કરો"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"મ્યૂટ કરો"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"સાઉન્ડ મ્યૂટ કરવા માટે ટૅપ કરો"</string>
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 39e6625..04ee203c 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1198,7 +1198,7 @@
     <string name="low_internal_storage_view_text" msgid="8172166728369697835">"हो सकता है कुछ सिस्टम फ़ंक्शन काम नहीं करें"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"सिस्टम के लिए ज़रूरी मेमोरी नहीं है. पक्का करें कि आपके पास 250एमबी की खाली जगह है और फिर से शुरू करें."</string>
     <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="app_running_notification_text" msgid="5120815883400228566">"ऐप्लिकेशन को रोकने या ज़्यादा जानकारी के लिए टैप करें."</string>
     <string name="ok" msgid="2646370155170753815">"ठीक है"</string>
     <string name="cancel" msgid="6908697720451760115">"रद्द करें"</string>
     <string name="yes" msgid="9069828999585032361">"ठीक है"</string>
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"वॉयरलेस डीबगिंग की सुविधा बंद करने के लिए चुनें."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"टेस्ट हार्नेस मोड चालू किया गया"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"टेस्ट हार्नेस मोड बंद करने के लिए फ़ैक्ट्री रीसेट करें."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"सीरियल कंसोल को चालू करें"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"परफ़ॉर्मेंस पर असर पड़ा है. बंद करने के लिए बूटलोडर चुनें."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"आज़माने के लिए एमटीई चालू है"</string>
@@ -1435,8 +1439,8 @@
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"दूसरे ऐप्लिकेशन के ऊपर दिखाए जाने का ऐक्सेस"</string>
     <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> अन्य ऐप्लिकेशन के ऊपर दिखाई दे रहा है"</string>
-    <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_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_message" msgid="2231566971425375542">"मौजूदा सामग्री की जाँच की जा रही है"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"आवाज़ कम-ज़्यादा करने वाले दोनों बटन दबाकर रखें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को चालू कर दिया गया."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"आवाज़ कम-ज़्यादा करने वाले दोनों बटन दबाकर रखें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को बंद कर दिया गया."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"आवाज़ बटन को छोड़ें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> की सुविधा चालू करने के लिए, आवाज़ वाले दोनों बटन तीन सेकंड तक दबाकर रखें."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"सुलभता बटन पर टैप करके, इस्तेमाल करने के लिए सुविधा चुनें:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"सुलभता वाले हाथ के जेस्चर (हाव-भाव) के साथ इस्तेमाल करने के लिए सुविधा चुनें (दो उंगलियों से स्क्रीन पर सबसे नीचे से ऊपर की ओर स्वाइप करें):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"सुलभता वाले हाथ के जेस्चर (हाव-भाव) के साथ इस्तेमाल करने के लिए सुविधा चुनें (तीन उंगलियों से स्क्रीन पर सबसे नीचे से ऊपर की ओर स्वाइप करें):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"एक सुविधा से दूसरी सुविधा पर जाने के लिए, सुलभता बटन दबाकर रखें."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"एक सुविधा से दूसरी सुविधा पर जाने के लिए, स्क्रीन पर दो उंगलियों से ऊपर की ओर स्वाइप करें और थोड़ी देर तक उंगलियां स्क्रीन पर रखे रहें."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"एक सुविधा से दूसरी सुविधा पर जाने के लिए, स्क्रीन पर तीन उंगलियों से ऊपर की ओर स्वाइप करें और थोड़ी देर तक उंगलियां स्क्रीन पर रखे रहें."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"अगली बार सुलभता बटन पर टैप करने से, यह सुविधा चालू हो जाएगी"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"इस शॉर्टकट का अगली बार इस्तेमाल करने पर, यह सुविधा चालू हो जाएगी. स्क्रीन पर दो उंगलियों से, नीचे से ऊपर की ओर स्वाइप करें और फिर स्क्रीन से तुरंत उंगलियां हटा दें."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"इस शॉर्टकट का अगली बार इस्तेमाल करने पर, यह सुविधा चालू हो जाएगी. स्क्रीन पर तीन उंगलियों से, नीचे से ऊपर की ओर स्वाइप करें और फिर स्क्रीन से तुरंत उंगलियां हटा दें."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ज़ूम करने की सुविधा"</string>
     <string name="user_switched" msgid="7249833311585228097">"मौजूदा उपयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> पर स्विच किया जा रहा है…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"पहले से जारी कॉल"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"इनकमिंग कॉल को स्क्रीन किया जा रहा है"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"बिना किसी श्रेणी के"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"प्रमोशन"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"सोशल"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"खबरें"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"सुझाव"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"आपने इन सूचनाओं की अहमियत सेट की है."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"यह मौजूद व्यक्तियों के कारण महत्वपूर्ण है."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"ऐप्लिकेशन की सूचना पसंद के मुताबिक बनाएं"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"स्क्रीन पर दिखने वाले सुलभता के शॉर्टकट को चुनने का मेन्यू"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"सुलभता का शॉर्टकट"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"नोटिफ़िकेशन शेड खारिज करें"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"मेन्यू"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"मीडिया चलाएं/रोकें"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"डी-पैड का ऊपर वाला बटन"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"डी-पैड का नीचे वाला बटन"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"डी-पैड का बाईं ओर वाला बटन"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"यह सेटिंग कैसे काम करती है"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"प्रोसेस जारी है..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"फ़िंगरप्रिंट अनलॉक की सुविधा दोबारा सेट अप करें"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"अच्छे से काम न करने की वजह से <xliff:g id="FINGERPRINT">%s</xliff:g> को मिटा दिया गया"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"अच्छे से काम न करने की वजह से, <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> और <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> को मिटा दिया गया"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"अच्छे से काम न करने की वजह से <xliff:g id="FINGERPRINT">%s</xliff:g> को मिटा दिया गया. फ़िंगरप्रिंट की मदद से फ़ोन अनलॉक करने के लिए, फ़िंगरप्रिंट अनलॉक की सुविधा को दोबारा सेट अप करें."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"अच्छे से काम न करने की वजह से, <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> और <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> को मिटा दिया गया. फ़िंगरप्रिंट की मदद से फ़ोन अनलॉक करने के लिए, फ़िंगरप्रिंट अनलॉक की सुविधा दोबारा सेट अप करें."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"अब <xliff:g id="FINGERPRINT">%s</xliff:g> की पहचान नहीं की जा सकती."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"अब <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> और <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> की पहचान नहीं की जा सकती."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"अब <xliff:g id="FINGERPRINT">%s</xliff:g> की पहचान नहीं की जा सकती. फ़िंगरप्रिंट अनलॉक की सुविधा दोबारा सेट अप करें."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"अब <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> और <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> की पहचान नहीं की जा सकती. फ़िंगरप्रिंट अनलॉक की सुविधा दोबारा सेट अप करें."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"फ़ेस अनलॉक की सुविधा को दोबारा सेट अप करें"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"अच्छे से काम न करने की वजह से, चेहरे का मॉडल मिटा दिया गया. फ़ेस अनलॉक की सुविधा की मदद से फ़ोन अनलॉक करने के लिए, इस सुविधा को दोबारा सेट अप करें."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"अब आपके चेहरे के मॉडल की पहचान नहीं की जा सकती. फ़ेस अनलॉक की सुविधा को दोबारा सेट अप करें."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"सेट अप करें"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"अभी नहीं"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> के लिए अलार्म"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"दूसरे खाते पर स्विच करें"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"म्यूट करें"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"आवाज़ म्यूट करने के लिए टैप करें"</string>
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 08ea4a2..acb6d04 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1412,6 +1412,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Odaberite da biste onemogućili bežično otklanjanje pogrešaka."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Omogućen je način testnog okvira"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Vratite na tvorničke postavke da biste onemogućili način testnog okvira."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Serijska konzola omogućena"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Izvedba je otežana. Provjerite pokretač operativnog sustava da biste onemogućili konzolu."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Omogućen je eksperimentalni MTE"</string>
@@ -1756,12 +1760,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za glasnoću. Uključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za glasnoću. Isključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Pustite tipke za glasnoću. Da biste uključili uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ponovo pritisnite i zadržite obje tipke za glasnoću tri sekunde."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Odaberite značajku koju ćete upotrebljavati kada dodirnete gumb za Pristupačnost:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Odaberite za koju će se značajku upotrebljavati pokret pristupačnosti (prelazak s dva prsta prema gore od dna zaslona):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Odaberite za koju će se značajku upotrebljavati pokret pristupačnosti (prelazak s tri prsta prema gore od dna zaslona):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Da biste prešli na neku drugu značajku, dodirnite i zadržite gumb za Pristupačnost."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Da biste prešli na neku drugu značajku, prijeđite s dva prsta prema gore i zadržite."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Da biste prešli na neku drugu značajku, prijeđite s tri prsta prema gore i zadržite."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Značajka će se otvoriti sljedeći put kad dodirnete gumb za pristupačnost"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Značajka će se otvoriti sljedeći put kad upotrijebite ovaj prečac. Nakratko prijeđite dvama prstima s dna zaslona."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Značajka će se otvoriti sljedeći put kad upotrijebite ovaj prečac. Nakratko prijeđite s dna zaslona trima prstima."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Povećavanje"</string>
     <string name="user_switched" msgid="7249833311585228097">"Trenutačni korisnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1984,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Poziv u tijeku"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtriranje dolaznog poziva"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Nema kategorije"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promocije"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Društvene mreže"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Vijesti"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Preporuke"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Postavili ste važnost tih obavijesti."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Važno je zbog uključenih osoba."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Prilagođena obavijest aplikacije"</string>
@@ -2193,6 +2204,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Alat za odabir prečaca pristupačnosti na zaslonu"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Prečac pristupačnosti"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Odbacivanje zaslona obavijesti"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Izbornik"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Reproduciraj/pauziraj medijske sadržaje"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Gore na plohi za smjerove"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dolje na plohi za smjerove"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Lijevo na plohi za smjerove"</string>
@@ -2419,12 +2432,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako to funkcionira"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Na čekanju..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ponovno postavite otključavanje otiskom prsta"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Otisak prsta <xliff:g id="FINGERPRINT">%s</xliff:g> nije dobro funkcionirao i izbrisan je"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Otisci prstiju <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nisu dobro funkcionirali i izbrisani su"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Otisak prsta <xliff:g id="FINGERPRINT">%s</xliff:g> nije dobro funkcionirao i izbrisan je. Ponovno ga postavite da biste otključali telefon otiskom prsta."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Otisci prstiju <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nisu dobro funkcionirali i izbrisani su. Ponovno ih postavite da biste otključali telefon otiskom prsta."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> više se ne prepoznaje."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> više se ne prepoznaju."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> više se ne prepoznaje. Ponovo postavite otključavanje otiskom prsta."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> više se ne prepoznaju. Ponovo postavite otključavanje otiskom prsta."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Ponovno postavite otključavanje licem"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Model vašeg lica nije dobro funkcionirao i izbrisan je. Ponovno ga postavite da biste otključali telefon licem."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Vaš model lica više se ne prepoznaje. Ponovo postavite otključavanje licem."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Postavi"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne sad"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm za korisnika <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Promijeni korisnika"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Isključi zvuk"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Dodirnite za isključivanje zvuka"</string>
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 729fad9..5002b09 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Válassza ezt a vezeték nélküli hibakeresés letiltásához."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Tesztelési alapkörnyezet mód engedélyezve"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"A Tesztelési alapkörnyezet mód kikapcsolásához állítsa vissza a gyári beállításokat."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Soros konzol engedélyezve"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Ez hatással van a teljesítményre. A letiltáshoz ellenőrizze a rendszerindítót."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Kísérleti MTE engedélyezve"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Nyomva tartotta a hangerőgombokat. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> bekapcsolva."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Nyomva tartotta a hangerőgombokat. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kikapcsolva."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Engedje fel a hangerőszabályzó gombokat. A(z) <xliff:g id="SERVICE_NAME">%1$s</xliff:g> bekapcsolásához tartsa újra lenyomva a hangerőszabályzó gombokat három másodpercig."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Válassza ki a Kisegítő lehetőségek gombra koppintáskor használni kívánt funkciót:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Válassza ki a kisegítő kézmozdulattal (felfelé csúsztatás két ujjal a képernyő aljáról) használni kívánt funkciót:"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Válassza ki a kisegítő kézmozdulattal (felfelé csúsztatás három ujjal a képernyő aljáról) használni kívánt funkciót:"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"A funkciók közötti váltáshoz tartsa lenyomva a Kisegítő lehetőségek gombot."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"A funkciók közötti váltáshoz csúsztassa felfelé két ujját, és ne emelje fel őket a képernyőről."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"A funkciók közötti váltáshoz csúsztassa felfelé három ujját, és ne emelje fel őket a képernyőről."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"A funkció a Kisegítő lehetőségek gombra való következő koppintáskor lesz megnyitva"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"A funkció a gyorsparancs következő használatakor lesz megnyitva. Csúsztasson felfelé két ujjal a képernyő aljáról, majd emelje fel gyorsan az ujjait."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"A funkció a gyorsparancs következő használatakor lesz megnyitva. Csúsztasson felfelé három ujjal a képernyő aljáról, majd emelje fel gyorsan az ujjait."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Nagyítás"</string>
     <string name="user_switched" msgid="7249833311585228097">"<xliff:g id="NAME">%1$s</xliff:g> az aktuális felhasználó."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Átváltás erre: <xliff:g id="NAME">%1$s</xliff:g>..."</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Hívás folyamatban"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Bejövő hívás szűrése"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Nincs kategóriába sorolva"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promóciók"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Közösségi"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Hírek"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Javaslatok"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Ön állította be ezen értesítések fontossági szintjét."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Ez az üzenet a résztvevők miatt fontos."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Egyéni alkalmazásértesítés"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Képernyőn megjelenő kisegítő lehetőségekre vonatkozó parancsválasztó"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Kisegítő lehetőségek gyorsparancsa"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Értesítési felület bezárása"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menü"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Médialejátszás/szüneteltetés"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"D-pad – fel"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"D-pad – le"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"D-pad – balra"</string>
@@ -2411,19 +2424,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Privát terület"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"Bizalmas értesítéstartalom elrejtve"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"A biztonság érdekében a képernyőmegosztástól elrejtett alkalmazástartalom"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Apptartalom elrejtve a megosztástól a biztonság érdekében"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"Automatikusan csatlakozva a műholdhoz"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Küldhet és fogadhat üzeneteket mobil- és Wi-Fi-hálózat nélkül is"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"A Messages megnyitása"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Hogyan működik?"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Függőben…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"A Feloldás ujjlenyomattal funkció újbóli beállítása"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"A(z) <xliff:g id="FINGERPRINT">%s</xliff:g> nem működött megfelelően, ezért törölve lett"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"A(z) <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> és a(z) <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nem működtek megfelelően, ezért törölve lettek"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"A(z) <xliff:g id="FINGERPRINT">%s</xliff:g> nem működött megfelelően, ezért törölve lett. Állítsa be újra, hogy feloldhassa a telefonját az ujjlenyomata segítségével."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"A(z) <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> és a(z) <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nem működtek megfelelően, ezért törölve lettek. Állítsa be őket újra, hogy feloldhassa a telefonját az ujjlenyomata segítségével."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"A következő már nem felismerhető: <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"A következők már nem felismerhetők: <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> és <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"A következő már nem felismerhető: <xliff:g id="FINGERPRINT">%s</xliff:g>. Állítsa be újra a Feloldás ujjlenyomattal funkciót."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"A következők már nem felismerhetők: <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> és <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>. Állítsa be újra a Feloldás ujjlenyomattal funkciót."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Állítsa be újra az Arcalapú feloldást"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Az arcmodellje nem működött megfelelően, ezért törölve lett. Állítsa be újra, hogy feloldhassa a telefonját az arca segítségével."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Az arcmodellje már nem felismerhető. Állítsa be újra az Arcalapú feloldást."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Beállítás"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Most nem"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Riasztás <xliff:g id="USER_NAME">%s</xliff:g> részére"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Felhasználóváltás"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Némítás"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Koppintson a hang elnémításához"</string>
 </resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index c3eec0f..2a5bdfc 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Սեղմեք՝ անլար վրիպազերծումն անջատելու համար:"</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Թեստային ռեժիմը միացված է"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Թեստային ռեժիմն անջատելու համար զրոյացրեք կարգավորումները։"</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Սերիական վահանակը միացված է"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Աշխատանքի արդյունավետությունը նվազում է։ Վահանակն անջատելու համար ստուգեք օպերացիոն համակարգի բեռնիչը։"</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Միացված է փորձնական MTE գործառույթը"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ձայնի կարգավորման կոճակները սեղմվեցին։ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունը միացավ։"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ձայնի կարգավորման կոճակները սեղմվեցին։ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունն անջատվեց։"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Բաց թողեք ձայնի ուժգնության կոճակները։ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունը միացնելու համար սեղմեք և 3 վայրկյան պահեք ձայնի ուժգնության երկու կոճակը։"</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Ընտրեք գործառույթը, որը կգործարկվի «Հատուկ գործառույթներ» կոճակին հպելու դեպքում՝"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Ընտրեք գործառույթը, որը կգործարկվի հատուկ գործառույթների ժեստը (երկու մատը էկրանի ներքևից սահեցրեք վերև) անելու դեպքում՝"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Ընտրեք գործառույթը, որը կգործարկվի հատուկ գործառույթների ժեստը (երեք մատը էկրանի ներքևից սահեցրեք վերև) անելու դեպքում՝"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Մի գործառույթից մյուսին անցնելու համար հպեք «Հատուկ գործառույթներ» կոճակին և պահեք։"</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Մի գործառույթից մյուսին անցնելու համար երկու մատը սահեցրեք վերև և պահեք։"</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Մի գործառույթից մյուսին անցնելու համար երեք մատը սահեցրեք վերև և պահեք։"</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Գործառույթը կբացվի հաջորդ անգամ, երբ սեղմեք «Հատուկ գործառույթներ» կոճակը"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Գործառույթը կբացվի հաջորդ անգամ, երբ օգտագործեք այս դյուրանցումը։ Երկու մատը էկրանի ներքևից սահեցրեք վերև և արագ բաց թողեք։"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Գործառույթը կբացվի հաջորդ անգամ, երբ օգտագործեք այս դյուրանցումը։ Երեք մատը էկրանի ներքևից սահեցրեք վերև և արագ բաց թողեք։"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Խոշորացում"</string>
     <string name="user_switched" msgid="7249833311585228097">"Ներկայիս օգտատերը <xliff:g id="NAME">%1$s</xliff:g>:"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Անցում <xliff:g id="NAME">%1$s</xliff:g> պրոֆիլին..."</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Ընթացիկ զանգ"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Մուտքային զանգի զտում"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Չդասակարգված"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Պրոմոակցիաներ"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Սոցցանցեր"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Նորություններ"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Առաջարկներ"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Դուք սահմանել եք այս ծանուցումների կարևորությունը:"</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Կարևոր է, քանի որ որոշակի մարդիկ են ներգրավված:"</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Հատուկ հավելվածի ծանուցում"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Հատուկ գործառույթների դյուրանցման ընտրիչ"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Հատուկ գործառույթների դյուրանցում"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Փակել ծանուցումների վահանակը"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Ընտրացանկ"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Նվագարկում/դադար"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad-ի «Վերև» կոճակ"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad-ի «Ներքև» կոճակ"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad-ի «Ձախ» կոճակ"</string>
@@ -2411,19 +2424,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Մասնավոր տարածք"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"Ծանուցման զգայուն բովանդակությունը թաքցված է"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Անվտանգության նկատառումներից ելնելով՝ հավելվածի բովանդակությունը թաքցվել է էկրանի ցուցադրումից"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Անվտանգության նկատառումներով՝ բովանդակությունը թաքցվել է ցուցադրումից"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"Ավտոմատ միացել է արբանյակին"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Դուք կարող եք ուղարկել և ստանալ հաղորդագրություններ՝ առանց բջջային կամ Wi-Fi կապի"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Բացել Messages-ը"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ինչպես է դա աշխատում"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Առկախ է…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Նորից կարգավորեք մատնահետքով ապակողպումը"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"«<xliff:g id="FINGERPRINT">%s</xliff:g>» մատնահետքը հեռացվել է, քանի որ լավ չէր աշխատում"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"«<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>» և «<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>» մատնահետքերը հեռացվել են, քանի որ լավ չէին աշխատում"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"«<xliff:g id="FINGERPRINT">%s</xliff:g>» մատնահետքը հեռացվել է, քանի որ լավ չէր աշխատում։ Նորից կարգավորեք այն՝ ձեր հեռախոսը մատնահետքով ապակողպելու համար։"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"«<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>» և «<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>» մատնահետքերը հեռացվել են, քանի որ լավ չէին աշխատում։ Նորից կարգավորեք դրանք՝ ձեր հեռախոսը մատնահետքով ապակողպելու համար։"</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> մատնահետքն այլևս չի կարող ճանաչվել։"</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> և <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> մատնահետքերն այլևս չեն կարող ճանաչվել։"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> մատնահետքն այլևս չի կարող ճանաչվել։ Նորից կարգավորեք մատնահետքով ապակողպումը։"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> և <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> մատնահետքերն այլևս չեն կարող ճանաչվել։ Նորից կարգավորեք մատնահետքով ապակողպումը։"</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Նորից կարգավորեք դեմքով ապակողպումը"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Ձեր դեմքի նմուշը հեռացվել է, քանի որ լավ չէր աշխատում։ Նորից կարգավորեք այն՝ ձեր հեռախոսը դեմքով ապակողպելու համար։"</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Ձեր դեմքի նմուշն այլևս չի կարող ճանաչվել։ Նորից կարգավորեք դեմքով ապակողպումը։"</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Կարգավորել"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ոչ հիմա"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>-ի զարթուցիչ"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Անցնել մյուս հաշիվ"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Անտեսել"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Հպեք՝ ձայնն անջատելու համար"</string>
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 34a52e4..f861728 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Pilih untuk menonaktifkan proses debug nirkabel."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Mode Tes Otomatis diaktifkan"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Lakukan reset ke setelan pabrik untuk menonaktifkan Mode Tes Otomatis."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Konsol serial diaktifkan"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Performa terpengaruh. Untuk menonaktifkan, periksa bootloader."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"MTE eksperimental diaktifkan"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> diaktifkan."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dinonaktifkan."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lepaskan tombol volume. Untuk mengaktifkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tekan dan tahan kedua tombol volume lagi selama 3 detik."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Pilih fitur yang akan digunakan saat mengetuk tombol aksesibilitas:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Pilih fitur yang akan digunakan dengan gestur aksesibilitas (geser ke atas dari bawah layar dengan dua jari):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Pilih fitur yang akan digunakan dengan gestur aksesibilitas (geser ke atas dari bawah layar dengan tiga jari):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Sentuh lama tombol aksesibilitas untuk beralih ke fitur lain."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Geser ke atas dengan dua jari dan tahan untuk beralih ke fitur lain."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Geser ke atas dengan tiga jari dan tahan untuk beralih ke fitur lain."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Fitur akan terbuka setelah Anda mengetuk tombol aksesibilitas"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Fitur akan terbuka setelah Anda menggunakan pintasan ini. Geser ke atas dengan 2 jari dari bawah layar, lalu lepaskan dengan cepat."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Fitur akan terbuka setelah Anda menggunakan pintasan ini. Geser ke atas dengan 3 jari dari bawah layar, lalu lepaskan dengan cepat."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Pembesaran"</string>
     <string name="user_switched" msgid="7249833311585228097">"Pengguna saat ini <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Beralih ke <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Panggilan sedang berlangsung"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Menyaring panggilan masuk"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Tidak dikategorikan"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promosi"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Sosial"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Berita"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Rekomendasi"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Anda menyetel nilai penting notifikasi ini."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Ini penting karena orang-orang yang terlibat."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notifikasi aplikasi kustom"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Pemilih Pintasan Aksesibilitas di layar"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Pintasan Aksesibilitas"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Tutup Menu Notifikasi"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Putar/Jeda Media"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad Atas"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad Bawah"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad Kiri"</string>
@@ -2411,19 +2424,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Ruang privasi"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"Konten notifikasi sensitif disembunyikan"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Konten aplikasi disembunyikan dari berbagi layar untuk alasan keamanan"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Konten aplikasi disembunyikan dari berbagi layar karena alasan keamanan"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"Menghubungkan otomatis ke satelit"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Anda dapat mengirim dan menerima pesan tanpa jaringan seluler atau Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Buka Message"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cara kerjanya"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Tertunda..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Siapkan Buka dengan Sidik Jari lagi"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak berfungsi dengan baik dan telah dihapus"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak berfungsi dengan baik dan telah dihapus"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak berfungsi dengan baik dan telah dihapus. Siapkan lagi untuk membuka kunci ponsel Anda dengan sidik jari."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak berfungsi dengan baik dan telah dihapus. Siapkan lagi untuk membuka kunci ponsel Anda dengan sidik jari."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak dapat dikenali lagi."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak dapat dikenali lagi."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak dapat dikenali lagi. Siapkan Buka dengan Sidik Jari lagi."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak dapat dikenali lagi. Siapkan Buka dengan Sidik Jari lagi."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Siapkan Buka dengan Wajah lagi"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Model wajah Anda tidak berfungsi dengan baik dan telah dihapus. Siapkan lagi untuk membuka kunci ponsel Anda dengan wajah."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Model wajah Anda tidak dapat dikenali lagi. Siapkan Buka dengan Wajah lagi."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Penyiapan"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Lain kali"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm untuk <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Ganti pengguna"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Bisukan"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Ketuk untuk membisukan suara"</string>
 </resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 9495626..21d57ea 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Veldu til að slökkva á þráðlausri villuleit."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Kveikt á stillingu prófunarvangs"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Núllstilltu til að slökkva á stillingu prófunarvangs."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Raðstjórnborð virkjað"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Þetta hefur áhrif á afköst. Athugaðu ræsiforritið ef þú vilt gera þetta óvirkt."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Kveikt á MTE á tilraunarstigi"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Hljóðstyrkstökkum haldið inni. Kveikt á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Hljóðstyrkstökkum haldið inni. Slökkt á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Slepptu hljóðstyrkstökkunum. Til að kveikja á <xliff:g id="SERVICE_NAME">%1$s</xliff:g> skaltu halda báðum hljóðstyrkstökkunum aftur inni í 3 sekúndur."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Veldu eiginleika sem á að nota þegar ýtt er á aðgengishnappinn:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Veldu eiginleika sem á að nota með aðgengisbendingunni (strjúka upp frá neðri hluta skjásins með tveimur fingrum):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Veldu eiginleika sem á að nota með aðgengisbendingunni (strjúka upp frá neðri hluta skjásins með þremur fingrum):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Til að skipta á milli eiginleika skaltu halda aðgengishnappinum inni."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Til að skipta á milli eiginleika skaltu strjúka upp með tveimur fingrum og halda inni."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Til að skipta á milli eiginleika skaltu strjúka upp með þremur fingrum og halda inni."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Eiginleikinn opnast næst þegar þú ýtir á aðgengishnappinn"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Eiginleikinn opnast næst þegar þú notar þessa flýtileið Strjúktu upp með 2 fingrum frá neðsta hluta skjásins og slepptu hratt."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Eiginleikinn opnast næst þegar þú notar þessa flýtileið Strjúktu upp með 3 fingrum frá neðsta hluta skjásins og slepptu hratt."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Stækkun"</string>
     <string name="user_switched" msgid="7249833311585228097">"Núverandi notandi <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Skiptir yfir á <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Símtal í gangi"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Síar símtal sem berst"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Óflokkað"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Kynningar"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Samfélag"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Fréttir"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Tillögur"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Þú stilltir mikilvægi þessara tilkynninga."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Þetta er mikilvægt vegna fólksins sem tekur þátt í þessu."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Sérsniðin forritatilkynning"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Val um flýtileið í aðgengiseiginleika á skjánum"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Flýtileið aðgengisstillingar"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Loka tilkynningaglugga"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Valmynd"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Spila/gera hlé á margmiðlunarefni"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Upphnappur stýriflatar"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Niðurhnappur stýriflatar"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Vinstrihnappur stýriflatar"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Svona virkar þetta"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Í bið…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Setja upp fingrafarskenni aftur"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> virkaði illa og var eytt."</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> virkuðu illa og var eytt."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> virkaði illa og var eytt. Settu það upp aftur til að taka símann úr lás með fingrafari."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> virkuðu illa og var eytt. Settu þau upp aftur til að taka símann úr lás með fingrafarinu þínu."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Ekki er hægt að bera kennsl á <xliff:g id="FINGERPRINT">%s</xliff:g> lengur."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Ekki er hægt að bera kennsl á <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> lengur."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Ekki er hægt að bera kennsl á <xliff:g id="FINGERPRINT">%s</xliff:g> lengur. Settu upp fingrafarskenni aftur."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Ekki er hægt að bera kennsl á <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> lengur. Settu upp fingrafarskenni aftur."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Setja upp andlitskenni aftur"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Andlitslíkanið þitt virkaði illa og var eytt. Settu það upp aftur til að taka símann úr lás með andlitinu."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Ekki er hægt að bera kennsl á andlitslíkanið þitt lengur. Settu upp andlitskenni aftur."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Setja upp"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ekki núna"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Viðvörun fyrir <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Skipta um notanda"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Þagga"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Ýttu til að þagga hljóð"</string>
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 3952837..e99e948 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -420,9 +420,9 @@
     <string name="permdesc_runInBackground" msgid="4344539472115495141">"Questa app può essere eseguita in background, velocizzando il consumo della batteria."</string>
     <string name="permlab_useDataInBackground" msgid="783415807623038947">"utilizzo dei dati in background"</string>
     <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Questa app può usare dati in background, aumentando l\'utilizzo dei dati."</string>
-    <string name="permlab_schedule_exact_alarm" msgid="6683283918033029730">"Pianificare la precisione delle azioni temporizzate"</string>
+    <string name="permlab_schedule_exact_alarm" msgid="6683283918033029730">"Programma azioni temporizzate con precisione"</string>
     <string name="permdesc_schedule_exact_alarm" msgid="8198009212013211497">"Questa app può pianificare il lavoro al momento desiderato nel futuro. Significa anche che l\'app può essere eseguita quando non stai attivamente utilizzando il dispositivo."</string>
-    <string name="permlab_use_exact_alarm" msgid="348045139777131552">"Pianifica sveglie o promemoria eventi"</string>
+    <string name="permlab_use_exact_alarm" msgid="348045139777131552">"Programma sveglie o promemoria eventi"</string>
     <string name="permdesc_use_exact_alarm" msgid="7033761461886938912">"Quest\'app può pianificare azioni come sveglie e promemoria per notificarti al momento desiderato nel futuro."</string>
     <string name="permlab_persistentActivity" msgid="464970041740567970">"esecuzione permanente delle applicazioni"</string>
     <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"Consente all\'applicazione di rendere persistenti in memoria alcune sue parti. Ciò può limitare la memoria disponibile per altre applicazioni, rallentando il tablet."</string>
@@ -1412,6 +1412,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Seleziona per disattivare il debug wireless."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modalità test harness attivata"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Ripristina le impostazioni di fabbrica per disattivare la modalità test harness."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Console seriale attivata"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Ci sono conseguenze sulle prestazioni. Per disattivare, seleziona il bootloader."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Funzionalità MTE sperimentale attivata"</string>
@@ -1756,12 +1760,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> attivato."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> disattivato."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Rilascia i tasti del volume. Per attivare <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tieni di nuovo premuti entrambi i tasti del volume per 3 secondi."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Scegli una funzionalità da usare quando tocchi il pulsante Accessibilità:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Scegli una funzionalità da usare con il gesto di accessibilità (scorrimento verso l\'alto dalla parte inferiore dello schermo con due dita):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Scegli una funzionalità da usare con il gesto di accessibilità (scorrimento verso l\'alto dalla parte inferiore dello schermo con tre dita):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Per spostarti tra le funzionalità, tocca e tieni premuto il pulsante Accessibilità."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Per spostarti tra le funzionalità, scorri verso l\'alto con due dita e tieni premuto."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Per spostarti tra le funzionalità, scorri verso l\'alto con tre dita e tieni premuto."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"La funzionalità si aprirà la prossima volta che toccherai il pulsante Accessibilità"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"La funzionalità si aprirà la prossima volta che utilizzerai questa scorciatoia. Scorri verso l\'alto con 2 dita dalla parte inferiore dello schermo e rilascia rapidamente."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La funzionalità si aprirà la prossima volta che utilizzerai questa scorciatoia. Scorri verso l\'alto con 3 dita dalla parte inferiore dello schermo e rilascia rapidamente."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ingrandimento"</string>
     <string name="user_switched" msgid="7249833311585228097">"Utente corrente <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Passaggio a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1984,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chiamata in corso"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Applicazione filtro a chiamata in arrivo"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Senza categoria"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promozioni"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Novità"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Contenuti consigliati"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Stabilisci tu l\'importanza di queste notifiche."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Importante a causa delle persone coinvolte."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notifica app personalizzata"</string>
@@ -2193,6 +2204,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selettore scorciatoia Accessibilità sullo schermo"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Scorciatoia Accessibilità"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ignora area notifiche"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Play/Pausa contenuti multimediali"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"D-pad - Su"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"D-pad - Giù"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"D-pad - Sinistra"</string>
@@ -2419,12 +2432,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Come funziona"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"In attesa…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Riconfigura lo Sblocco con l\'Impronta"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> non funzionava bene ed è stata eliminata"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> non funzionavano bene e sono state eliminate"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> non funzionava bene ed è stata eliminata. Riconfigurala per sbloccare lo smartphone con l\'impronta."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> non funzionavano bene e sono state eliminate. Riconfigurale per sbloccare lo smartphone con l\'impronta."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> non può più essere riconosciuto."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> non possono più essere riconosciuti."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> non può più essere riconosciuto. Riconfigura lo Sblocco con l\'Impronta."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> non possono più essere riconosciuti. Riconfigura lo Sblocco con l\'Impronta."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Riconfigura lo Sblocco con il Volto"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Il tuo modello del volto non funzionava bene ed è stato eliminato. Riconfiguralo per sbloccare lo smartphone con il volto."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Il tuo modello del volto non può più essere riconosciuto. Riconfigura lo Sblocco con il Volto."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configura"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Non ora"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Sveglia per: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Cambia utente"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Disattiva audio"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tocca per disattivare l\'audio"</string>
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 9c143c7..6a4cea6 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1412,6 +1412,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"יש לבחור כדי להשבית ניפוי באגים אלחוטי."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"מצב מסגרת בדיקה הופעל"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"כדי להשבית את מצב \'מסגרת בדיקה\' צריך לאפס להגדרות היצרן."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"קונסולה סדרתית מופעלת"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"קיימת השפעה על הביצועים. כדי להשבית, יש לבדוק את תוכנת האתחול."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"‏ה-MTE הניסיוני הופעל"</string>
@@ -1756,12 +1760,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"לחצני עוצמת הקול נלחצו בלחיצה ארוכה. שירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g> הופעל."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"לחצני עוצמת הקול נלחצו בלחיצה ארוכה. שירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g> הושבת."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"אפשר לשחרר את מקש עוצמת הקול. כדי להפעיל את השירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, צריך ללחוץ לחיצה ארוכה על שני המקשים של עוצמת הקול שוב במשך 3 שניות."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"צריך לבחור תכונה שתופעל כשלוחצים על לחצן הנגישות:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"יש לבחור תכונה שתופעל באמצעות תנועת הנגישות (החלקה למעלה מתחתית המסך בעזרת שתי אצבעות):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"יש לבחור תכונה שתופעל באמצעות תנועת הנגישות (החלקה למעלה מתחתית המסך בעזרת שלוש אצבעות):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"כדי לעבור בין תכונות, יש ללחוץ לחיצה ארוכה על לחצן הנגישות."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"כדי לעבור בין תכונות, יש להחליק כלפי מעלה בעזרת שתי אצבעות ולהחזיק."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"כדי לעבור בין תכונות, יש להחליק כלפי מעלה בעזרת שלוש אצבעות ולהחזיק."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"התכונה תיפתח בפעם הבאה שתזוהה הקשה על לחצן הנגישות"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"התכונה תיפתח בפעם הבאה שייעשה שימוש במקש הקיצור הזה. צריך להחליק למעלה עם 2 אצבעות מהחלק התחתון של המסך ולשחרר במהירות."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"התכונה תיפתח בפעם הבאה שייעשה שימוש במקש הקיצור הזה. צריך להחליק למעלה עם 3 אצבעות מהחלק התחתון של המסך ולשחרר במהירות."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"הגדלה"</string>
     <string name="user_switched" msgid="7249833311585228097">"המשתמש הנוכחי <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"מעבר אל <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1984,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"שיחה פעילה"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"סינון שיחה נכנסת"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"ללא שיוך לקטגוריה"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"קידומי מכירות"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"רשתות חברתיות"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"חדשות"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"המלצות"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"עליך להגדיר את החשיבות של ההתראות האלה."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"ההודעה חשובה בשל האנשים המעורבים."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"התראות אפליקציה בהתאמה אישית"</string>
@@ -2193,6 +2204,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"בורר קיצורי דרך לנגישות במסך"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"קיצור דרך לנגישות"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"סגירת לוח ההתראות"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"תפריט"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"הפעלה/השהיה של המדיה"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"‏לחצן עליון ב-Dpad"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"‏לחצן תחתון ב-Dpad"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"‏לחצן שמאלי ב-Dpad"</string>
@@ -2419,12 +2432,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"איך זה עובד"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"בהמתנה..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"הגדרה חוזרת של \'ביטול הנעילה בטביעת אצבע\'"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"‫<xliff:g id="FINGERPRINT">%s</xliff:g> לא פעלה טוב ולכן היא נמחקה"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"‫<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ו<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> לא פעלו טוב ולכן הן נמחקו"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"‫<xliff:g id="FINGERPRINT">%s</xliff:g> לא פעלה היטב ולכן היא נמחקה. עליך להגדיר אותה שוב כדי שתהיה לך אפשרות לבטל את הנעילה של הטלפון באמצעות טביעת אצבע."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"‫<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ו<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> לא פעלו היטב ולכן הן נמחקו. עליך להגדיר אותן שוב כדי שתהיה לך אפשרות לבטל את הנעילה של הטלפון באמצעות טביעת אצבע."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"כבר לא ניתן לזהות את <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"כבר לא ניתן לזהות את <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ואת <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"כבר לא ניתן לזהות את <xliff:g id="FINGERPRINT">%s</xliff:g>. הגדרה חוזרת של \'פתיחה בטביעת אצבע\'."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"כבר לא ניתן לזהות את <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ואת <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>. הגדרה חוזרת של \'פתיחה בטביעת אצבע\'."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"הגדרה חוזרת של \'פתיחה ע\"י זיהוי הפנים\'"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"התבנית לזיהוי הפנים לא פעלה היטב ולכן היא נמחקה. עליך להגדיר אותה שוב כדי שתהיה לך אפשרות לבטל את הנעילה של הטלפון באמצעות זיהוי הפנים."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"כבר לא ניתן לזהות את התבנית לזיהוי הפנים. הגדרה חוזרת של \'פתיחה בזיהוי פנים\'."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"הגדרה"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"לא עכשיו"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"שעון מעורר של <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"החלפת משתמש"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"השתקה"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"צריך להקיש כדי להשתיק את הצליל"</string>
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 934967f..743d58e 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -156,8 +156,8 @@
     <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"モバイル ネットワーク セキュリティ"</string>
     <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"暗号化、暗号化されていないネットワークに関する通知"</string>
     <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"デバイス ID へのアクセスが発生しました"</string>
-    <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>、<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> の SIM の使用中に付近のネットワークでお使いのデバイスの一意の ID(IMSI または IMEI)が記録されました"</string>
-    <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>、<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> の SIM の使用中に付近のネットワークでお使いのデバイスの一意の ID(IMSI または IMEI)が記録されました。\n\nつまり、あなたの位置情報、アクティビティ、身元などが記録されことになります。これはよくある事象ですが、プライバシーに不安を持たれている人にとっては問題になる可能性があります。"</string>
+    <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>、<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> の SIM の使用中に、お使いのデバイスの一意の ID(IMSI または IMEI)が付近のネットワークで記録されました。"</string>
+    <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"<xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>、<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g> の SIM の使用中に、お使いのデバイスの一意の ID(IMSI または IMEI)が付近のネットワークで記録されました。\n\nつまり、あなたの位置情報、アクティビティ、身元などが記録されたことになります。これはよくある事象ですが、プライバシーを保護したいユーザーにとっては問題となる可能性があります。"</string>
     <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"暗号化されたネットワーク(<xliff:g id="NETWORK_NAME">%1$s</xliff:g>)に接続しました"</string>
     <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"<xliff:g id="NETWORK_NAME">%1$s</xliff:g> の SIM 接続のセキュリティが強化されました"</string>
     <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"接続先のネットワークが暗号化されていません"</string>
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ワイヤレス デバッグを無効にするには選択します。"</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"テストハーネス モード有効"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"出荷時設定にリセットしてテストハーネス モードを無効にしてください。"</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"シリアル コンソールは有効です"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"シリアル コンソールを有効にすると、パフォーマンスに影響します。無効にするには、ブートローダーをチェックしてください。"</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"試験運用版 MTE を有効にしました"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"音量ボタンを長押ししました。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> が ON になりました。"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"音量ボタンを長押ししました。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> が OFF になりました。"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"音量ボタンを離してください。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> を有効にするには音量大と音量小の両方のボタンを 3 秒ほど長押ししてください。"</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ユーザー補助機能ボタンをタップした場合に使用する機能を選択してください。"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ユーザー補助操作(2 本の指で画面の下から上にスワイプ)で使用する機能を選択してください。"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ユーザー補助操作(3 本の指で画面の下から上にスワイプ)で使用する機能を選択してください。"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"機能を切り替えるには、ユーザー補助機能ボタンを長押しします。"</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"機能を切り替えるには、2 本の指で上にスワイプしたまま長押しします。"</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"機能を切り替えるには、3 本の指で上にスワイプしたまま長押しします。"</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"この機能は、ユーザー補助機能ボタンを次回タップした時に利用できるようになります"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"この機能は、このショートカットを次回使用した時に利用できるようになります。2 本の指で画面の下部から上にスワイプし、素早く離してください。"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"この機能は、このショートカットを次回使用した時に利用できるようになります。3 本の指で画面の下部から上にスワイプし、素早く離してください。"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"拡大"</string>
     <string name="user_switched" msgid="7249833311585228097">"現在のユーザーは<xliff:g id="NAME">%1$s</xliff:g>です。"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>に切り替えています…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"通話中"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"着信をスクリーニング中"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"カテゴリなし"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"プロモーション"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"ソーシャル"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"ニュース"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"推奨事項"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"このような通知の重要度を設定します。"</string>
     <string name="importance_from_person" msgid="4235804979664465383">"関係するユーザーのため、この設定は重要です。"</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"カスタムアプリ通知"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"画面上のユーザー補助機能のショートカットの選択メニュー"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ユーザー補助のショートカット"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"通知シェードを閉じる"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"メニュー"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"メディアの再生 / 一時停止"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"D-pad: 上"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"D-pad: 下"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"D-pad: 左"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"仕組み"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"保留中..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"指紋認証をもう一度設定してください"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> は正常に機能せず、削除されました"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> と <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> は正常に機能せず、削除されました"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> が正常に機能せず、削除されました。指紋認証でスマートフォンのロックを解除するには、設定し直してください。"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> と <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> が正常に機能せず、削除されました。指紋認証でスマートフォンのロックを解除するには、設定し直してください。"</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>を認識できなくなりました。"</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>と<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>を認識できなくなりました。"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g>を認識できなくなりました。指紋認証をもう一度設定してください。"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>と<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>を認識できなくなりました。指紋認証をもう一度設定してください。"</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"顔認証をもう一度設定してください"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"顔モデルが正常に機能せず、削除されました。顔認証でスマートフォンのロックを解除するには、設定し直してください。"</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"顔モデルを認識できなくなりました。顔認証をもう一度設定してください。"</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"設定"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"後で"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> さんのアラーム"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ユーザーを切り替え"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ミュート"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"音声をミュートするにはタップします"</string>
 </resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 013125e..45d8264 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"აირჩიეთ შეცდომების უსადენო გამართვის გასათიშად."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"რეჟიმი „გარემო ტესტირებისთვის“ ჩართულია"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"დააბრუნეთ ქარხნული პარამეტრები „გარემო ტესტირებისთვის“ რეჟიმის გასათიშად."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"სერიული კონსოლი ჩართულია"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"მუშაობა შეფერხებულია. გასათიშად მონიშნეთ ჩამტვირთავი."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"ექსპერიმენტული MTE ჩართულია"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ხანგრძლივად დააჭირეთ ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ჩართულია."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ხანგრძლივად დააჭირეთ ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> გამორთულია."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ხელი აუშვით ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-ის ჩასართველად, ხელმეორედ ხანგრძლივად დააჭირეთ ორივე ხმის ღილაკს 3 წამის განმავლობაში."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"აირჩიეთ მარტივი წვდომის ღილაკზე შეხებისას გამოსაყენებელი ფუნქცია:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"აირჩიეთ მარტივი წვდომის ჟესტთან (ორი თითით გადაფურცვლა ეკრანის ქვედა კიდიდან ზემოთ) გამოსაყენებელი ფუნქცია:"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"აირჩიეთ მარტივი წვდომის ჟესტთან (სამი თითით გადაფურცვლა ეკრანის ქვედა კიდიდან ზემოთ) გამოსაყენებელი ფუნქცია:"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"სერვისების გადასართავად, ხანგრძლივად შეეხეთ მარტივი წვდომის ღილაკს."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"ფუნქციების გადასართავად, ორი თითით გადაფურცლეთ ზემოთ და დააყოვნეთ."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ფუნქციების გადასართავად, სამი თითით გადაფურცლეთ ზემოთ და დააყოვნეთ."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"ეს ფუნქცია გაიხსნება, როცა შემდეგ ჯერზე შეეხებით მარტივი წვდომის ღილაკს"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ეს ფუნქცია გაიხსნება, როცა შემდეგ ჯერზე გამოიყენებთ ამ მალსახმობს. გადაფურცლეთ 2 თითით თქვენი ეკრანის ქვედა ნაწილიდან და სწრაფად აუშვით."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ეს ფუნქცია გაიხსნება, როცა შემდეგ ჯერზე გამოიყენებთ ამ მალსახმობს. გადაფურცლეთ 3 თითით თქვენი ეკრანის ქვედა ნაწილიდან და სწრაფად აუშვით."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"გადიდება"</string>
     <string name="user_switched" msgid="7249833311585228097">"ამჟამინდელი მომხმარებელი <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>-ზე გადართვა…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"მიმდინარე ზარი"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"შემომავალი ზარების გაცხრილვა"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"კატეგორიის გარეშე"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"სარეკლამო აქციები"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"სოციალური ქსელები"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"ახალი ამბები"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"რეკომენდაციები"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"ამ შეტყობინებების მნიშვნელობის დონე განისაზღვრა თქვენ მიერ."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"მნიშვნელოვანია ჩართული მომხმარებლების გამო."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"აპის მორგებული შეტყობინება"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"მისაწვდომობის ეკრანული მალსახმობის ამომრჩევი"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"მისაწვდომობის მალსახმობი"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"შეტყობინებების ფარდის დახურვა"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"მენიუ"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"მედიის დაკვრა/დაპაუზება"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad ზევით"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad ქვევით"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad მარცხნივ"</string>
@@ -2411,19 +2424,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"კერძო სივრცე"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"სენსიტიური შეტყობინების კონტენტი დამალულია"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ეკრანის გაზიარებიდან აპის კონტენტი დამალულია უსაფრთხოების მიზნით"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ეკრანის გაზიარებისას აპის კონტენტი დამალულია უსაფრთხოების მიზნით"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"სატელიტთან ავტომატურად დაკავშირებულია"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"შეგიძლიათ გაგზავნოთ და მიიღოთ შეტყობინებები მობილური ან Wi-Fi ქსელის გარეშე"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages-ის გახსნა"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"მუშაობის პრინციპი"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"მომლოდინე..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ანაბეჭდით განბლოკვის ხელახლა დაყენება"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> კარგად არ მუშაობდა და წაიშალა"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> და <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> კარგად არ მუშაობდნენ და წაიშალა"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> კარგად არ მუშაობდა და წაიშალა. თავიდან დააყენეთ, რათა თქვენი ტელეფონი თითის ანაბეჭდის საშუალებით განბლოკოთ."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> და <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> კარგად არ მუშაობდნენ და წაიშალა. თავიდან დააყენეთ, რათა თქვენი ტელეფონი თითის ანაბეჭდის საშუალებით განბლოკოთ."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>-ის ამოცნობა ვეღარ ხერხდება."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>-ისა და <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>-ის ამოცნობა ვეღარ ხერხდება."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g>-ის ამოცნობა ვეღარ ხერხდება. დააყენეთ ანაბეჭდით განბლოკვა ხელახლა."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>-ისა და <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>-ის ამოცნობა ვეღარ ხერხდება. დააყენეთ ანაბეჭდით განბლოკვა ხელახლა."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"დააყენეთ სახით განბლოკვა ხელახლა"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"თქვენი სახის მოდელი კარგად არ მუშაობდა და წაიშალა. თავიდან დააყენეთ, რათა თქვენი ტელეფონი სახის საშუალებით განბლოკოთ."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"თქვენი სახის მოდელის ამოცნობა ვეღარ ხერხდება. დააყენეთ სახით განბლოკვა ხელახლა."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"დაყენება"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ახლა არა"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"მაღვიძარა <xliff:g id="USER_NAME">%s</xliff:g>-ისთვის"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"მომხმარებლის გადართვა"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"დადუმება"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"შეეხეთ ხმის დასადუმებლად"</string>
 </resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 791644d..0393067 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Сымсыз түзетуді өшіру үшін басыңыз."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Сынақ бағдарламасы режимі қосылды"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Сынақ бағдарламасы режимін өшіру үшін зауыттық күйіне қайтарыңыз."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Сериялық консоль қосылды"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Өнімділікке әсер етеді. Өшіру үшін жүктегішті тексеріңіз."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Эксперименттік MTE қосылды"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Пайдаланушы дыбыс деңгейі пернелерін басып ұстап тұрды. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қосулы."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Дыбыс деңгейі пернелерін басып тұрған соң, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өшірілді."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Дыбыс деңгейі пернелерін жіберіңіз. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қызметін қосу үшін дыбыс деңгейі пернесінің екеуін де қайтадан 3 секундқа басып тұрыңыз."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"\"Арнайы мүмкіндіктер\" түймесін түрткенде пайдаланатын функцияны таңдаңыз:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Арнайы мүмкіндіктер қимылымен (екі саусақпен экранның төменгі жағынан жоғары қарай сырғытыңыз) пайдаланатын функцияны таңдаңыз:"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Арнайы мүмкіндіктер қимылымен (үш саусақпен экранның төменгі жағынан жоғары қарай сырғытыңыз) пайдаланатын функцияны таңдаңыз:"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Бір функциядан екінші функцияға ауысу үшін \"Арнайы мүмкіндіктер\" түймесін түртіп, оны ұстап тұрыңыз."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Бір функциядан екінші функцияға ауысу үшін екі саусақпен жоғары қарай сырғытып, ұстап тұрыңыз."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Бір функциядан екінші функцияға ауысу үшін үш саусақпен жоғары қарай сырғытып, ұстап тұрыңыз."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Келесіде арнайы мүмкіндіктер түймесін түрткенде, функция ашылады."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Келесіде осы жылдам пәрменді қолданғанда, функция ашылады. 2 саусақпен экранның төменгі жағынан жоғары қарай сырғытып, жылдам жіберіп қалыңыз."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Келесіде осы жылдам пәрменді қолданғанда, функция ашылады. 3 саусақпен экранның төменгі жағынан жоғары қарай сырғытып, жылдам жіберіп қалыңыз."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ұлғайту"</string>
     <string name="user_switched" msgid="7249833311585228097">"Ағымдағы пайдаланушы <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> профиліне ауысу…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Қоңырау"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Келген қоңырауды сүзу"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Санатқа жатқызылмаған"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Промонауқандар"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Әлеуметтік желі"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Жаңалықтар"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Ұсыныстар"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Сіз осы хабарландырулардың маңыздылығын орнатасыз."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Қатысты адамдарға байланысты бұл маңызды."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Арнаулы қолданба хабарландыруы"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Экрандағы арнайы мүмкіндіктерді жылдам қосу әрекетін таңдау"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Арнайы мүмкіндіктерді жылдам қосу"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Хабарландыру тақтасын жабу"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Mәзір"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Медиафайл ойнату/кідірту"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Жоғарғы Dpad түймесі"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Төменгі Dpad түймесі"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Сол жақ Dpad түймесі"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Бұл қалай орындалады?"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Дайын емес…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Саусақ ізімен ашу функциясын қайта реттеу"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> саусақ ізі дұрыс істемегендіктен жойылды."</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Саусақ іздері (<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> және <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>) дұрыс істемегендіктен жойылды."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> саусақ ізі дұрыс істемегендіктен жойылды. Телефонды саусақ ізімен ашу үшін оны қайта реттеңіз."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Саусақ іздері (<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> және <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>) дұрыс істемегендіктен жойылды. Телефонды саусақ ізімен ашу үшін оларды қайта реттеңіз."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> бұдан былай танылмайды."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> және <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> бұдан былай танылмайды."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> бұдан былай танылмайды. Саусақ ізімен ашу функциясын қайта реттеңіз."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> және <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> бұдан былай танылмайды. Саусақ ізімен ашу функциясын қайта реттеңіз."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Бет тану функциясын қайта реттеу"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Бет үлгісі дұрыс істемегендіктен жойылды. Телефонды бетпен ашу үшін оны қайта реттеңіз."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Бет үлгіңіз бұдан былай танылмайды. Бет тану функциясын қайта реттеңіз."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Реттеу"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Қазір емес"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> атына қойылған дабыл"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Пайдаланушыны ауыстыру"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Дыбысын өшіру"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Дыбысын өшіру үшін түртіңіз."</string>
 </resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 12e1a36..8fa4c58 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ជ្រើសរើស ដើម្បី​បិទ​ការជួសជុល​ដោយឥតខ្សែ។"</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"បាន​បើក​មុខងារប្រមូលធ្វើតេស្ត"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ធ្វើការកំណត់ដូចដើមឡើងវិញ ដើម្បី​បិទ​មុខងារប្រមូលធ្វើតេស្ត។"</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"កុងសូល​ស៊េរី​ត្រូវបានបើក"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"ប្រតិបត្តិការ​ទទួលរង​ការប៉ះពាល់។ សូម​ពិនិត្យមើល​កម្មវិធី​ដំណើរការ​ប្រព័ន្ធ ដើម្បី​បិទ។"</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"បានបើក MTE ពិសោធន៍"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"បានសង្កត់​គ្រាប់ចុច​កម្រិតសំឡេង​ជាប់។ បាន​បើក <xliff:g id="SERVICE_NAME">%1$s</xliff:g>។"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"បានសង្កត់​គ្រាប់ចុច​កម្រិតសំឡេង​ជាប់។ បាន​បិទ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>។"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"លែង​គ្រាប់ចុចកម្រិតសំឡេង។ ដើម្បីបើក <xliff:g id="SERVICE_NAME">%1$s</xliff:g> សូមចុច​គ្រាប់ចុចកម្រិតសំឡេងទាំងពីរឱ្យជាប់ម្ដងទៀត​រយៈពេល 3 វិនាទី។"</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ជ្រើសរើស​មុខងារ​ដែលត្រូវប្រើ នៅពេល​ដែល​អ្នកចុច​ប៊ូតុង​ភាពងាយស្រួល៖"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ជ្រើសរើស​មុខងារ ដើម្បី​ប្រើជាមួយចលនា​ភាពងាយស្រួល (អូស​ឡើងលើ​ពី​ផ្នែកខាងក្រោម​នៃ​អេក្រង់​ដោយប្រើ​ម្រាមដៃ​ពីរ)៖"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ជ្រើសរើស​មុខងារ ដើម្បី​ប្រើជាមួយ​ចលនា​ភាពងាយស្រួល (អូស​ឡើងលើ​ពី​ផ្នែកខាងក្រោម​នៃ​អេក្រង់​ដោយប្រើ​ម្រាមដៃ​បី)៖"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"ដើម្បី​ប្ដូររវាង​មុខងារផ្សេងៗ សូមចុច​ប៊ូតុង​ភាពងាយស្រួល​ឱ្យជាប់។"</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"ដើម្បី​ប្ដូររវាង​មុខងារផ្សេងៗ សូមអូស​ឡើងលើ​ដោយប្រើ​ម្រាមដៃ​ពីរ ហើយ​សង្កត់ឱ្យជាប់។"</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ដើម្បី​ប្ដូររវាង​មុខងារផ្សេងៗ សូមអូស​ឡើងលើ​ដោយប្រើ​ម្រាមដៃ​បី ហើយ​សង្កត់ឱ្យជាប់។"</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"មុខងារនេះនឹងបើក ពេលអ្នកចុចប៊ូតុង​ភាពងាយស្រួលនៅលើកក្រោយ"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"មុខងារនេះនឹងបើក ពេលអ្នកប្រើផ្លូវកាត់នេះនៅលើកក្រោយ។ អូសពីផ្នែកខាងក្រោមនៃអេក្រង់របស់អ្នកឡើងលើដោយប្រើម្រាមដៃ 2 ហើយលែងឱ្យរហ័ស។"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"មុខងារនេះនឹងបើក ពេលអ្នកប្រើផ្លូវកាត់នេះនៅលើកក្រោយ។ អូសពីផ្នែកខាងក្រោមនៃអេក្រង់របស់អ្នកឡើងលើដោយប្រើម្រាមដៃ 3 ហើយលែងឱ្យរហ័ស។"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ការ​ពង្រីក"</string>
     <string name="user_switched" msgid="7249833311585228097">"អ្នក​ប្រើ​បច្ចុប្បន្ន <xliff:g id="NAME">%1$s</xliff:g> ។"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"កំពុង​ប្ដូរ​ទៅ <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"ការ​ហៅដែលកំពុងដំណើរការ"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"កំពុងពិនិត្យការ​ហៅ​ចូល"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"មិន​​បែងចែក​ប្រភេទ"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ប្រូម៉ូសិន"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"សង្គម"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"ព័ត៌មាន"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"ការណែនាំ"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"អ្នកបានកំណត់សារៈសំខាន់នៃការជូនដំណឹងទាំងនេះ"</string>
     <string name="importance_from_person" msgid="4235804979664465383">"វាមានសារៈសំខាន់ដោយសារតែមនុស្សដែលពាក់ព័ន្ធ"</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"ការជូន​ដំណឹងកម្មវិធី​ផ្ទាល់ខ្លួន"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ម៉ឺនុយជ្រើសរើស​ផ្លូវកាត់ភាពងាយស្រួល​នៅលើអេក្រង់"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ផ្លូវកាត់​ភាពងាយស្រួល"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"ច្រានចោល​ផ្ទាំងជូនដំណឹង"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"ម៉ឺនុយ"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"ចាក់/ផ្អាកមេឌៀ"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad ឡើងលើ"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad ចុះក្រោម"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ឆ្វេង"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"របៀបដែលវាដំណើរការ"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"កំពុងរង់ចាំ..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"រៀបចំការដោះសោ​ដោយស្កេន​ស្នាមម្រាមដៃម្ដងទៀត"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> មិនដំណើរការល្អទេ ហើយត្រូវបានលុបចេញហើយ"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> និង <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> មិនដំណើរការល្អទេ ហើយត្រូវបានលុបចេញហើយ"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> មិនដំណើរការល្អទេ ហើយត្រូវបានលុបចេញហើយ។ រៀបចំវាម្ដងទៀត ដើម្បីដោះសោទូរសព្ទរបស់អ្នកដោយប្រើស្នាមម្រាមដៃ។"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> និង <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> មិនដំណើរការល្អទេ ហើយត្រូវបានលុបចេញហើយ។ រៀបចំវាម្ដងទៀត ដើម្បីដោះសោទូរសព្ទរបស់អ្នកដោយប្រើស្នាមម្រាមដៃ។"</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"លែងអាចសម្គាល់ <xliff:g id="FINGERPRINT">%s</xliff:g> បានទៀតហើយ។"</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"លែងអាចសម្គាល់ <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> និង <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> បានទៀតហើយ។"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"លែងអាចសម្គាល់ <xliff:g id="FINGERPRINT">%s</xliff:g> បានទៀតហើយ។ សូមរៀបចំការដោះសោ​ដោយស្កេន​ស្នាមម្រាមដៃម្ដងទៀត។"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"លែងអាចសម្គាល់ <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> និង <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> បានទៀតហើយ។ សូមរៀបចំការដោះសោ​ដោយស្កេន​ស្នាមម្រាមដៃម្ដងទៀត។"</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"រៀបចំ​ការដោះ​សោ​ដោយស្កេន​មុខម្ដងទៀត"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"គំរូមុខរបស់អ្នកមិនដំណើរការល្អទេ ហើយត្រូវបានលុបចេញហើយ។ រៀបចំវាម្ដងទៀត ដើម្បីដោះសោទូរសព្ទរបស់អ្នកដោយប្រើមុខ។"</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"លែងអាចសម្គាល់គំរូមុខរបស់អ្នកបានទៀតហើយ។ សូមរៀបចំ​ការដោះ​សោ​ដោយស្កេន​មុខម្ដងទៀត។"</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"រៀបចំ"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"កុំទាន់"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"ម៉ោងរោទ៍សម្រាប់ <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ប្ដូរអ្នកប្រើប្រាស់"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"បិទសំឡេង"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ចុចដើម្បីបិទសំឡេង"</string>
 </resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index c134b74..dee9b4a 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ವೈರ್‌ಲೆಸ್ ಡೀಬಗ್‌ ಮಾಡುವಿಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಆಯ್ಕೆ ಮಾಡಿ."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ಸ್ವಯಂ ಪರೀಕ್ಷೆಯಾಗುವಿಕೆ ಮೋಡ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ಸ್ವಯಂ ಪರೀಕ್ಷೆಯಾಗುವಿಕೆ ಮೋಡ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಫ್ಯಾಕ್ಟರಿ ರಿಸೆಟ್ ಮಾಡಬೇಕು."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"ಸರಣಿ ಕನ್ಸೋಲ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"ಕಾರ್ಯಕ್ಷಮತೆಯ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರುತ್ತದೆ. ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು, ಬೂಟ್‌ಲೋಡರ್ ಅನ್ನು ಪರಿಶೀಲಿಸಿ."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"ಪ್ರಾಯೋಗಿಕ MTE ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಹಿಡಿದುಕೊಳ್ಳಿ. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಆನ್ ಮಾಡಲಾಗಿದೆ."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಹಿಡಿದಿಟ್ಟುಕೊಳ್ಳಲಾಗಿದೆ. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ಆಫ್ ಮಾಡಲಾಗಿದೆ."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಬಿಡುಗಡೆ ಮಾಡಿ. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಆನ್ ಮಾಡಲು, ಎರಡೂ ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಮತ್ತೊಮ್ಮೆ 3 ಸೆಕೆಂಡ್‌ಗಳ ಕಾಲ ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ನೀವು ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಬಟನ್ ಟ್ಯಾಪ್ ಮಾಡಿದಾಗ ಬಳಸುವುದಕ್ಕಾಗಿ ವೈಶಿಷ್ಟ್ಯವೊಂದನ್ನು ಆರಿಸಿ:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಗೆಸ್ಚರ್‌ನೊಂದಿಗೆ ಬಳಸಲು ವೈಶಿಷ್ಟ್ಯವೊಂದನ್ನು ಆಯ್ಕೆಮಾಡಿ (ಎರಡು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಪರದೆಯ ಕೆಳಭಾಗದಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಗೆಸ್ಚರ್‌ನೊಂದಿಗೆ ಬಳಸಲು ವೈಶಿಷ್ಟ್ಯವೊಂದನ್ನು ಆಯ್ಕೆಮಾಡಿ (ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಪರದೆಯ ಕೆಳಭಾಗದಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"ವೈಶಿಷ್ಟ್ಯಗಳ ನಡುವೆ ಬದಲಿಸಲು, ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಬಟನ್ ಅನ್ನು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹೋಲ್ಡ್‌ ಮಾಡಿ."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"ವೈಶಿಷ್ಟ್ಯಗಳ ನಡುವೆ ಬದಲಿಸಲು, ಎರಡು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿಯಿರಿ."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ವೈಶಿಷ್ಟ್ಯಗಳ ನಡುವೆ ಬದಲಿಸಲು, ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿಯಿರಿ."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"ಮುಂದಿನ ಬಾರಿ ನೀವು ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಬಟನ್ ಅನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿದಾಗ ಈ ಫೀಚರ್ ಆನ್‌ ಆಗುತ್ತದೆ"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ಮುಂದಿನ ಬಾರಿ ನೀವು ಈ ಶಾರ್ಟ್‌ಕಟ್ ಅನ್ನು ಬಳಸುವಾಗ ಈ ಫೀಚರ್ ಆನ್ ಆಗುತ್ತದೆ. ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ನ ಕೆಳಗಿನಿಂದ 2 ಬೆರಳುಗಳಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಹಾಗೂ ತ್ವರಿತವಾಗಿ ಬಿಡುಗಡೆ ಮಾಡಿ."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ಮುಂದಿನ ಬಾರಿ ನೀವು ಈ ಶಾರ್ಟ್‌ಕಟ್ ಅನ್ನು ಬಳಸುವಾಗ ಈ ಫೀಚರ್ ಆನ್ ಆಗುತ್ತದೆ. ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ನ ಕೆಳಗಿನಿಂದ 3 ಬೆರಳುಗಳಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ ಹಾಗೂ ತ್ವರಿತವಾಗಿ ಬಿಡುಗಡೆ ಮಾಡಿ."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ಹಿಗ್ಗಿಸುವಿಕೆ"</string>
     <string name="user_switched" msgid="7249833311585228097">"ಪ್ರಸ್ತುತ ಬಳಕೆದಾರರು <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>ಗೆ ಬದಲಾಯಿಸಲಾಗುತ್ತಿದೆ…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಕರೆ"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"ಒಳಬರುವ ಕರೆಯನ್ನು ಸ್ಕ್ರೀನ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"ವರ್ಗೀಕರಿಸದಿರುವುದು"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ಪ್ರೊಮೋಷನ್‍ಗಳು"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"ಸಾಮಾಜಿಕ"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"ಸುದ್ದಿ"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"ಶಿಫಾರಸುಗಳು"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"ನೀವು ಈ ಅಧಿಸೂಚನೆಗಳ ಪ್ರಾಮುಖ್ಯತೆಯನ್ನು ಹೊಂದಿಸಿರುವಿರಿ."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"ಜನರು ತೊಡಗಿಕೊಂಡಿರುವ ಕಾರಣ ಇದು ಅತ್ಯಂತ ಪ್ರಮುಖವಾಗಿದೆ."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"ಕಸ್ಟಮ್ ಆ್ಯಪ್ ನೋಟಿಫಿಕೇಶನ್"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿನ ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಶಾರ್ಟ್‌ಕಟ್ ಆಯ್ಕೆ"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಶಾರ್ಟ್‌ಕಟ್"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"ಅಧಿಸೂಚನೆಯ ಪರದೆಯನ್ನು ವಜಾಗೊಳಿಸಿ"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"ಮೆನು"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"ಮೀಡಿಯಾವನ್ನು ಪ್ಲೇ ಮಾಡಿ/ವಿರಾಮಗೊಳಿಸಿ"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad ನ ಮೇಲಿನ ಬಟನ್"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad ನ ಕೆಳಗಿನ ಬಟನ್"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ನ ಎಡಭಾಗದ ಬಟನ್"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ಇದು ಹೇಗೆ ಕೆಲಸ ಮಾಡುತ್ತದೆ"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"ಬಾಕಿ ಉಳಿದಿದೆ..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್‌ಲಾಕ್ ಅನ್ನು ಮತ್ತೊಮ್ಮೆ ಸೆಟಪ್ ಮಾಡಿ"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿರಲಿಲ್ಲ, ಹಾಗಾಗಿ ಅದನ್ನು ಅಳಿಸಲಾಗಿದೆ"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ಮತ್ತು <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿರಲಿಲ್ಲ, ಹಾಗಾಗಿ ಅವುಗಳನ್ನು ಅಳಿಸಲಾಗಿದೆ"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿಲ್ಲ ಹಾಗೂ ಅದನ್ನು ಅಳಿಸಲಾಗಿದೆ. ಫಿಂಗರ್‌ ಪ್ರಿಂಟ್ ಮೂಲಕ ನಿಮ್ಮ ಫೋನ್ ಅನ್ನು ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಅದನ್ನು ಪುನಃ ಸೆಟಪ್‌ ಮಾಡಿ."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ಮತ್ತು <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿಲ್ಲ ಹಾಗೂ ಅವುಗಳನ್ನು ಅಳಿಸಲಾಗಿದೆ. ನಿಮ್ಮ ಫಿಂಗರ್‌ ಪ್ರಿಂಟ್ ಮೂಲಕ ನಿಮ್ಮ ಫೋನ್ ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಅವುಗಳನ್ನು ಪುನಃ ಸೆಟಪ್‌ ಮಾಡಿ."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ಅನ್ನು ಇನ್ನು ಮುಂದೆ ಗುರುತಿಸಲಾಗುವುದಿಲ್ಲ."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ಮತ್ತು <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ಅನ್ನು ಇನ್ನು ಮುಂದೆ ಗುರುತಿಸಲಾಗುವುದಿಲ್ಲ."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ಅನ್ನು ಇನ್ನು ಮುಂದೆ ಗುರುತಿಸಲಾಗುವುದಿಲ್ಲ. ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್‌ಲಾಕ್ ಅನ್ನು ಮತ್ತೊಮ್ಮೆ ಸೆಟಪ್ ಮಾಡಿ."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ಮತ್ತು <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ಅನ್ನು ಇನ್ನು ಮುಂದೆ ಗುರುತಿಸಲಾಗುವುದಿಲ್ಲ. ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಅನ್‌ಲಾಕ್ ಅನ್ನು ಮತ್ತೊಮ್ಮೆ ಸೆಟಪ್ ಮಾಡಿ."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"ಫೇಸ್ ಅನ್‌ಲಾಕ್ ಅನ್ನು ಮತ್ತೊಮ್ಮೆ ಸೆಟಪ್ ಮಾಡಿ"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ನಿಮ್ಮ ಫೇಸ್ ಮಾಡೆಲ್ ಸರಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿಲ್ಲ ಹಾಗೂ ಅದನ್ನು ಅಳಿಸಲಾಗಿದೆ. ಫೇಸ್ ಮೂಲಕ ನಿಮ್ಮ ಫೋನ್ ಅನ್ನು ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಅದನ್ನು ಪುನಃ ಸೆಟಪ್‌ ಮಾಡಿ."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"ನಿಮ್ಮ ಫೇಸ್ ಮಾಡೆಲ್ ಅನ್ನು ಇನ್ನು ಮುಂದೆ ಗುರುತಿಸಲಾಗುವುದಿಲ್ಲ. ಫೇಸ್ ಅನ್‌ಲಾಕ್ ಅನ್ನು ಮತ್ತೊಮ್ಮೆ ಸೆಟಪ್ ಮಾಡಿ."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ಸೆಟಪ್ ಮಾಡಿ"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ಈಗ ಬೇಡ"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> ಗಾಗಿ ಅಲಾರಾಂ"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ಬಳಕೆದಾರರನ್ನು ಬದಲಿಸಿ"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ಮ್ಯೂಟ್ ಮಾಡಿ"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ಧ್ವನಿಯನ್ನು ಮ್ಯೂಟ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 62ec778..7a4774b 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1197,7 +1197,7 @@
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"저장 공간이 부족함"</string>
     <string name="low_internal_storage_view_text" msgid="8172166728369697835">"일부 시스템 기능이 작동하지 않을 수 있습니다."</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"시스템의 저장 공간이 부족합니다. 250MB의 여유 공간이 확보한 후 다시 시작하세요."</string>
-    <string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g>이(가) 실행 중입니다."</string>
+    <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>
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"무선 디버깅을 사용 중지하려면 선택하세요."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"테스트 하네스 모드 사용 설정됨"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"테스트 하네스 모드를 사용 중지하려면 초기화하세요."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"시리얼 콘솔 사용 설정됨"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"성능에 영향을 미쳤습니다. 사용 중지하려면 부트로더를 확인하세요."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"실험용 MTE 사용 설정됨"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"볼륨 키를 길게 눌렀습니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 설정되었습니다."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"볼륨 키를 길게 눌렀습니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 중지되었습니다."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"볼륨 키에서 손을 뗍니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>을 켜려면 볼륨 키 2개를 3초 동안 길게 누르세요."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"접근성 버튼을 탭할 때 사용할 기능을 선택하세요."</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"접근성 동작(두 손가락을 사용하여 화면 하단에서 위로 스와이프)으로 실행할 기능을 선택하세요."</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"접근성 동작(세 손가락을 사용하여 화면 하단에서 위로 스와이프)으로 실행할 기능을 선택하세요."</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"기능 간에 전환하려면 접근성 버튼을 길게 터치합니다."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"기능 간에 전환하려면 두 손가락을 사용하여 위로 스와이프한 다음 잠시 기다립니다."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"기능 간에 전환하려면 세 손가락을 사용하여 위로 스와이프한 다음 잠시 기다립니다."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"다음번에 접근성 버튼을 탭할 때 이 기능이 열립니다."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"다음번에 이 단축키를 사용할 때 이 기능이 열립니다. 화면 하단에서 손가락 두 개를 사용해 위로 스와이프했다가 빠르게 놓습니다."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"다음번에 이 단축키를 사용할 때 이 기능이 열립니다. 화면 하단에서 손가락 세 개를 사용해 위로 스와이프했다가 빠르게 놓습니다."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"확대"</string>
     <string name="user_switched" msgid="7249833311585228097">"현재 사용자는 <xliff:g id="NAME">%1$s</xliff:g>님입니다."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>로 전환하는 중…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"진행 중인 통화"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"수신 전화 검사 중"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"지정된 카테고리 없음"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"프로모션"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"소셜"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"뉴스"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"권장사항"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"이러한 알림의 중요도를 설정했습니다."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"관련된 사용자가 있으므로 중요합니다."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"맞춤 앱 알림"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"화면상의 접근성 바로가기 선택 도구"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"접근성 단축키"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"알림 창 닫기"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"메뉴"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"미디어 재생/일시중지"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"방향 패드 위쪽"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"방향 패드 아래"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"방향 패드 왼쪽"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"작동 방식"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"대기 중…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"지문 잠금 해제 다시 설정"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> 지문이 제대로 작동하지 않아 삭제되었습니다."</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> 및 <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> 지문이 제대로 작동하지 않아 삭제되었습니다."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g>이(가) 제대로 작동하지 않아 삭제되었습니다. 지문으로 휴대전화를 잠금 해제하려면 다시 설정하세요."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> 및 <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>이(가) 제대로 작동하지 않아 삭제되었습니다. 지문으로 휴대전화를 잠금 해제하려면 다시 설정하세요."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> 지문을 더 이상 인식할 수 없습니다."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> 및 <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> 지문을 더 이상 인식할 수 없습니다."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> 지문을 더 이상 인식할 수 없습니다. 지문 잠금 해제를 다시 설정하세요."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> 및 <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> 지문을 더 이상 인식할 수 없습니다. 지문 잠금 해제를 다시 설정하세요."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"얼굴 인식 잠금 해제 다시 설정"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"얼굴 모델이 제대로 작동하지 않아 삭제되었습니다. 얼굴로 휴대전화를 잠금 해제하려면 다시 설정하세요."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"얼굴 모델을 더 이상 인식할 수 없습니다. 얼굴 인식 잠금 해제를 다시 설정하세요."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"설정"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"나중에"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>님의 알람"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"사용자 전환"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"음소거"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"탭하여 소리 음소거"</string>
 </resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 4df1e7e..cf1d2d3 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Мүчүлүштүктөрдү Wi-Fi аркылуу оңдоону өчүрүңүз."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Сыноо программасынын режими иштетилди"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Сыноо программасынын режимин өчүрүү үчүн баштапкы параметрлерге кайтарыңыз."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Сериялык консоль иштетилди"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Майнаптуулугуна таасири тиет. Өчүрүү үчүн операциялык тутумду жүктөгүчтү текшериңиз."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Cынамык MTE иштетилди"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Үндү катуулатуу/акырындатуу баскычтары басылып, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> күйгүзүлдү."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Үндү катуулатуу/акырындатуу баскычтары басылып, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өчүрүлдү."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Үн баскычтарын коё бериңиз. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> кызматын күйгүзүү үчүн үн баскычтарын кайра 3 секунд коё бербей басып туруңуз."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Атайын мүмкүнчүлүктөр баскычын таптаганыңызда иштей турган функцияны тандаңыз:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Атайын мүмкүнчүлүктөр жаңсоосу үчүн функцияны тандаңыз (эки манжаңыз менен экранды ылдыйдан өйдө сүрүңүз):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Атайын мүмкүнчүлүктөр жаңсоосу аркылуу иштетиле турган функцияны тандаңыз (үч манжаңыз менен экранды ылдыйдан өйдө сүрүңүз):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Функцияларды которуштуруу үчүн, Атайын мүмкүнчүлүктөр баскычын басып, кармап туруңуз."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Функцияларды которуштуруу үчүн, эки манжаңыз менен өйдө сүрүп, кармап туруңуз."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Башка функцияга которулуу үчүн үч манжаңыз менен экранды өйдө сүрүп, кармап туруңуз."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Эми функция атайын мүмкүнчүлүктөр баскычын басканыңызда ачылат"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Эми функция ушул ыкчам баскыч менен ачылат. Экранды 2 манжаңыз менен ылдыйдан өйдө карай сүрүп, тез коё бериңиз."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Эми функция ушул ыкчам баскыч менен ачылат. Экранды 3 манжаңыз менен ылдыйдан өйдө карай сүрүп, тез коё бериңиз."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Чоңойтуу"</string>
     <string name="user_switched" msgid="7249833311585228097">"Учурдагы колдонуучу <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> дегенге которулууда…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Учурдагы чалуу"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Кирүүчү чалууну иргөө"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Категорияларга бөлүнгөн эмес"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Промоакциялар"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Коомдук тармактар"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Жаңылыктар"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Cунуштар"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Бул эскертмелердин маанилүүлүгүн белгиледиңиз."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Булар сиз үчүн маанилүү адамдар."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Колдонмонун ыңгайлаштырылган билдирмеси"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ыкчам иштетүү менюсу"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Ыкчам иштетүү"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Билдирмелер тактасын жабуу"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Меню"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Медиа файлды ойнотуу/тындыруу"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad\'дын жогорку баскычы"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad\'дын ылдыйкы баскычы"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad\'дын сол баскычы"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ал кантип иштейт"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Кезекте турат..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Манжа изи менен ачуу функциясын кайра тууралаңыз"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ойдогудай иштебегендиктен өчүрүлдү"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> жана <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ойдогудай иштебегендиктен өчүрүлдү"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ойдогудай иштебегендиктен, жок кылынды. Телефондо Манжа изи менен ачуу функциясын колдонуу үчүн аны кайра тууралаңыз."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> жана <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ойдогудай иштебегендиктен, жок кылынды. Телефонду манжа изи менен ачуу үчүн аларды кайра тууралаңыз."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> мындан ары таанылбайт."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> жана <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> мындан ары таанылбайт."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> мындан ары таанылбайт. Манжа изи менен ачуу функциясын кайрадан тууралаңыз."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> жана <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> мындан ары таанылбайт. Манжа изи менен ачуу функциясын кайрадан тууралаңыз."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Жүзүнөн таанып ачуу функциясын кайрадан тууралаңыз"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Жүзүңүздүн үлгүсү ойдогудай иштебегендиктен, жок кылынды. Телефондо Жүзүнөн таанып ачуу функциясын колдонуу үчүн аны кайра тууралаңыз."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Жүзүңүздүн үлгүсү мындан ары таанылбайт. Жүзүнөн таанып ачуу функциясын кайрадан тууралаңыз."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Тууралоо"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Азыр эмес"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> үчүн ойготкуч"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Колдонуучуну которуштуруу"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Үнүн басуу"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Үнүн басуу үчүн таптап коюңуз"</string>
 </resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 3b77acb..dde778b 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ເລືອກເພື່ອປິດການນຳໃຊ້ການດີບັກໄຮ້ສາຍ."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ເປີດໃຊ້ໂໝດ Test Harness ແລ້ວ"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ດຳເນີນການຣີເຊັດເປັນຄ່າຈາກໂຮງງານເພື່ອປິດການນຳໃຊ້ໂໝດ Test Harness."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"ເປີດນຳໃຊ້ຊີຣຽວຄອນໂຊແລ້ວ"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"ມີຜົນກະທົບກັບປະສິດທິພາບ. ເພື່ອປິດການນຳໃຊ້, ໃຫ້ກວດສອບ bootloader ເບິ່ງ."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"ເປີດການນຳໃຊ້ MTE ແບບທົດລອງແລ້ວ"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ກົດປຸ່ມລະດັບສຽງຄ້າງໄວ້. ເປີດໃຊ້ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ແລ້ວ."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ກົດປຸ່ມລະດັບສຽງຄ້າງໄວ້. ປິດ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ໄວ້ແລ້ວ."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ປ່ອຍປຸ່ມລະດັບສຽງ. ເພື່ອເປີດ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ໃຫ້ກົດປຸ່ມລະດັບສຽງທັງສອງຄ້າງໄວ້ 3 ວິນາທີ."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ເລືອກຄຸນສົມບັດທີ່ຈະໃຊ້ເມື່ອທ່ານແຕະປຸ່ມການຊ່ວຍເຂົ້າເຖິງ:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ເລືອກຄຸນສົມບັດເພື່ອໃຊ້ກັບທ່າທາງການຊ່ວຍເຂົ້າເຖິງ (ປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍດ້ວຍສອງນິ້ວ):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ເລືອກຄຸນສົມບັດເພື່ອໃຊ້ກັບທ່າທາງການຊ່ວຍເຂົ້າເຖິງ (ປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍດ້ວຍສາມນິ້ວ):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"ເພື່ອສະຫຼັບລະຫວ່າງຄຸນສົມບັດຕ່າງໆ, ໃຫ້ແຕະໃສ່ປຸ່ມການຊ່ວຍເຂົ້າເຖິງຄ້າງໄວ້."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"ເພື່ອສະຫຼັບລະຫວ່າງບໍລິຄຸນສົມບັດຕ່າງໆ, ໃຫ້ປັດຂຶ້ນດ້ວຍສອງນິ້ວຄ້າງໄວ້."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ເພື່ອສະຫຼັບລະຫວ່າງຄຸນສົມບັດຕ່າງໆ, ໃຫ້ປັດຂຶ້ນດ້ວຍສາມນິ້ວຄ້າງໄວ້."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"ຄຸນສົມບັດນີ້ຈະເປີດຂຶ້ນໃນເທື່ອຕໍ່ໄປທີ່ທ່ານແຕະປຸ່ມການຊ່ວຍເຂົ້າເຖິງ"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ຄຸນສົມບັດນີ້ຈະເປີດຂຶ້ນໃນເທື່ອຕໍ່ໄປທີ່ທ່ານໃຊ້ທາງລັດນີ້. ໃຊ້ 2 ນິ້ວປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍຂອງທ່ານແລ້ວປ່ອຍແບບໄວໆ."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ຄຸນສົມບັດນີ້ຈະເປີດຂຶ້ນໃນເທື່ອຕໍ່ໄປທີ່ທ່ານໃຊ້ທາງລັດນີ້. ໃຊ້ 3 ນິ້ວປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍຂອງທ່ານແລ້ວປ່ອຍແບບໄວໆ."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ການຂະຫຍາຍ"</string>
     <string name="user_switched" msgid="7249833311585228097">"ຜູ່ໃຊ້ປັດຈຸບັນ <xliff:g id="NAME">%1$s</xliff:g> ."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"ກຳລັງສະຫຼັບໄປຫາ<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"ສາຍໂທອອກ"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"ກຳລັງກວດສອບສາຍໂທເຂົ້າ"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"ບໍ່​ມີ​ໝວດ​ໝູ່"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ໂປຣໂມຊັນ"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"ສັງຄົມ"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"ຂ່າວ"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"ການແນະນຳ"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"ທ່ານຕັ້ງຄວາມສຳຄັນຂອງການແຈ້ງເຕືອນເຫຼົ່ານີ້."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"ຂໍ້ຄວາມນີ້ສຳຄັນເນື່ອງຈາກບຸກຄົນທີ່ກ່ຽວຂ້ອງ."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"ການແຈ້ງເຕືອນແອັບແບບກຳນົດເອງ"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ຕົວເລືອກທາງລັດການຊ່ວຍເຂົ້າເຖິງຢູ່ໜ້າຈໍ"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ທາງລັດການຊ່ວຍເຂົ້າເຖິງ"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"ປິດເງົາການແຈ້ງເຕືອນໄວ້"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"ເມນູ"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"ຫຼິ້ນ/ຢຸດສື່ຊົ່ວຄາວ"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad ຂຶ້ນ"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad ລົງ"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ຊ້າຍ"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ມັນເຮັດວຽກແນວໃດ"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"ລໍຖ້າດຳເນີນການ..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ຕັ້ງຄ່າການປົດລັອກດ້ວຍລາຍນິ້ວມືຄືນໃໝ່"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ເຮັດວຽກໄດ້ບໍ່ດີ ແລະ ຖືກລຶບອອກແລ້ວ"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ແລະ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ເຮັດວຽກໄດ້ບໍ່ດີ ແລະ ຖືກລຶບອອກແລ້ວ"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ເຮັດວຽກໄດ້ບໍ່ດີ ແລະ ຖືກລຶບອອກແລ້ວ. ໃຫ້ຕັ້ງຄ່າມັນຄືນໃໝ່ເພື່ອປົດລັອກໂທລະສັບຂອງທ່ານດ້ວຍລາຍນິ້ວມື."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ແລະ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ເຮັດວຽກໄດ້ບໍ່ດີ ແລະ ຖືກລຶບອອກແລ້ວ. ໃຫ້ຕັ້ງຄ່າພວກມັນຄືນໃໝ່ເພື່ອປົດລັອກໂທລະສັບຂອງທ່ານດ້ວຍລາຍນິ້ວມື."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"ບໍ່ສາມາດຈຳແນກ <xliff:g id="FINGERPRINT">%s</xliff:g> ໄດ້ອີກຕໍ່ໄປ."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"ບໍ່ສາມາດຈຳແນກ <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ແລະ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ໄດ້ອີກຕໍ່ໄປ."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"ບໍ່ສາມາດຈຳແນກ <xliff:g id="FINGERPRINT">%s</xliff:g> ໄດ້ອີກຕໍ່ໄປ. ກະລຸນາຕັ້ງຄ່າການປົດລັອກດ້ວຍລາຍນິ້ວມືອີກຄັ້ງ."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"ບໍ່ສາມາດຈຳແນກ <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ແລະ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ໄດ້ອີກຕໍ່ໄປ. ກະລຸນາຕັ້ງຄ່າການປົດລັອກດ້ວຍລາຍນິ້ວມືອີກຄັ້ງ."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"ຕັ້ງຄ່າການປົດລັອກດ້ວຍໜ້າຄືນໃໝ່"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ຮູບແບບໃບໜ້າຂອງທ່ານເຮັດວຽກໄດ້ບໍ່ດີ ແລະ ຖືກລຶບອອກແລ້ວ. ໃຫ້ຕັ້ງຄ່າມັນຄືນໃໝ່ເພື່ອປົດລັອກໂທລະສັບຂອງທ່ານດ້ວຍໃບໜ້າ."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"ບໍ່ສາມາດຈຳແນກຮູບແບບໃບໜ້າຂອງທ່ານໄດ້ອີກຕໍ່ໄປ. ກະລຸນາຕັ້ງຄ່າການປົດລັອກດ້ວຍໜ້າອີກຄັ້ງ."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ຕັ້ງຄ່າ"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ບໍ່ຟ້າວເທື່ອ"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"ໂມງປຸກສຳລັບ <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ສະຫຼັບຜູ້ໃຊ້"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ປິດສຽງ"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ແຕະເພື່ອປິດສຽງ"</string>
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index b864773..f7ee53a 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1413,6 +1413,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Pasirinkite, kad išjungtumėte belaidžio ryšio derinimą."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Testavimo sistemos režimas įgalintas"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Atkurkite gamyklinius duomenis, kad išjungtumėte testavimo sistemos režimą."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Serijos pultas įgalintas"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Našumas paveiktas. Norėdami išjungti, patikrinkite paleidyklę."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimentiniai atminties žymėjimo plėtiniai (angl. „Memory Tagging Extensions“, MTE) įgalinti"</string>
@@ -1757,12 +1761,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Laikomi garsumo klavišai. „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“ įjungta."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Laikomi garsumo klavišai. „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“ išjungta."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Atleiskite garsumo klavišus. Kad įjungtumėte „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“, paspauskite ir 3 sekundes palaikykite garsumo klavišus."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Pasirinkite funkciją, kuri bus naudojama, kai paliesite pritaikomumo mygtuką:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Pasirinkite funkciją, kuri bus naudojama su pritaikomumo gestu (perbraukimas aukštyn dviem pirštais iš ekrano apačios):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Pasirinkite funkciją, kuri bus naudojama su pritaikomumo gestu (perbraukimas aukštyn trimis pirštais iš ekrano apačios):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Norėdami perjungti funkcijas, palieskite ir palaikykite pritaikomumo mygtuką."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Norėdami perjungti funkcijas, perbraukite aukštyn dviem pirštais ir palaikykite."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Norėdami perjungti funkcijas, perbraukite aukštyn trimis pirštais ir palaikykite."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funkcija bus atidaryta kitą kartą, kai paliesite pritaikomumo mygtuką"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkcija bus atidaryta kitą kartą, kai naudosite šį spartųjį klavišą. Perbraukite dviem pirštais aukštyn nuo ekrano apačios ir greitai atleiskite."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcija bus atidaryta kitą kartą, kai naudosite šį spartųjį klavišą. Perbraukite trimis pirštais aukštyn nuo ekrano apačios ir greitai atleiskite."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Didinimas"</string>
     <string name="user_switched" msgid="7249833311585228097">"Dabartinis naudotojas: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Perjungiama į <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1978,6 +1985,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Vykstantis skambutis"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Gaunamojo skambučio tikrinimas"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Be kategorijos"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Akcijos"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Socialiniai tinklai"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Naujienos"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Rekomendacijos"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Galite nustatyti šių pranešimų svarbą."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Tai svarbu dėl susijusių žmonių."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Tinkintas programos pranešimas"</string>
@@ -2194,6 +2205,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekrano pritaikomumo šaukinių parinkiklis"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Pritaikomumo šaukinys"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Atsisakyti pranešimų skydelio"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Meniu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Leisti / pristabdyti mediją"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Valdymo pultas – aukštyn"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Valdymo pultas – žemyn"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Valdymo pultas – kairėn"</string>
@@ -2420,12 +2433,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kaip tai veikia"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Laukiama..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Atrakinimo piršto atspaudu nustatymas dar kartą"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> neveikė tinkamai ir buvo ištrintas"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ir <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> neveikė tinkamai ir buvo ištrinti"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> neveikė tinkamai ir buvo ištrintas. Nustatykite jį dar kartą, kad atrakintumėte telefoną piršto atspaudu."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ir <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> neveikė tinkamai ir buvo ištrinti. Nustatykite juos dar kartą, kad atrakintumėte telefoną piršto atspaudu."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> nebegalima atpažinti."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ir <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nebegalima atpažinti."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> nebegalima atpažinti. Dar kartą nustatykite atrakinimą piršto atspaudu."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ir <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nebegalima atpažinti. Dar kartą nustatykite atrakinimą piršto atspaudu."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Atrakinimo pagal veidą nustatymas iš naujo"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Jūsų veido modelis neveikė tinkamai ir buvo ištrintas. Nustatykite jį dar kartą, kad atrakintumėte telefoną pagal veidą."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Jūsų veido modelio nebegalima atpažinti. Iš naujo nustatykite atrakinimą pagal veidą."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Nustatyti"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne dabar"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Signalas: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Perjungti naudotoją"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Nutildyti"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Palieskite, kad nutildytumėte garsą"</string>
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 9147e9b..6cc99a4 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1412,6 +1412,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Atlasiet, lai atspējotu bezvadu atkļūdošanu."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Drošības pārbaudes režīms ir iespējots"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Lai atspējotu drošības pārbaudes režīmu, veiciet rūpnīcas datu atiestatīšanu."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Seriālā konsole ir iespējota"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Tiek ietekmēta veiktspēja. Lai atspējotu, pārbaudiet operētājsistēmu ielādes rīku."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Eksperimentālais paplašinājums MTE iespējots"</string>
@@ -1756,12 +1760,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika ieslēgts."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika izslēgts."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Atlaidiet skaļuma pogas. Lai ieslēgtu pakalpojumu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, vēlreiz nospiediet un trīs sekundes turiet nospiestas abas skaļuma pogas."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Izvēlieties funkciju, ko izmantot, kad pieskaraties pieejamības pogai."</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Izvēlieties funkciju, ko izmantot ar pieejamības žestu (vilkšana ar diviem pirkstiem augšup no ekrāna apakšdaļas)."</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Izvēlieties funkciju, ko izmantot ar pieejamības žestu (vilkšana ar trīs pirkstiem augšup no ekrāna apakšdaļas)."</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Lai pārslēgtu funkcijas, pieskarieties pieejamības pogai un turiet to."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Lai pārslēgtu funkcijas, velciet ar diviem pirkstiem augšup un turiet."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Lai pārslēgtu funkcijas, velciet ar trīs pirkstiem augšup un turiet."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funkcija tiks atvērta, kad nākamreiz pieskarsieties pieejamības pogai."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkcija tiks atvērta, kad nākamreiz izmantosiet šo saīsni. Velciet augšup ar diviem pirkstiem no ekrāna apakšdaļas un ātri atlaidiet."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcija tiks atvērta, kad nākamreiz izmantosiet šo saīsni. Velciet augšup ar trim pirkstiem no ekrāna apakšdaļas un ātri atlaidiet."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Palielinājums"</string>
     <string name="user_switched" msgid="7249833311585228097">"Pašreizējais lietotājs: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Notiek pāriešana uz: <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -1977,6 +1984,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Pašreizējais zvans"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Ienākošā zvana filtrēšana"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Nav kategorijas"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Akcijas"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Sociālie tīkli"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Ziņas"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Ieteikumi"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Jūs iestatījāt šo paziņojumu svarīguma līmeni."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Tas ir svarīgi iesaistīto personu dēļ."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Pielāgots lietotnes paziņojums"</string>
@@ -2193,6 +2204,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekrāna pieejamības saīsnes atlasītājs"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Pieejamības saīsne"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Nerādīt paziņojumu paneli"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Izvēlne"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Sākt/apturēt multivides atskaņošanu"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Virzienu slēdzis — augšup"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Virzienu slēdzis — lejup"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Virzienu slēdzis — pa kreisi"</string>
@@ -2419,12 +2432,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Darbības principi"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Gaida…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Vēlreiz iestatiet autorizāciju ar pirksta nospiedumu"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> nedarbojās pareizi un tika izdzēsts"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> un <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nedarbojās pareizi un tika izdzēsti"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> nedarbojās pareizi un tika izdzēsts. Iestatiet to atkal, lai varētu atbloķēt tālruni ar pirksta nospiedumu."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> un <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nedarbojās pareizi un tika izdzēsti. Iestatiet tos atkal, lai varētu atbloķētu tālruni ar pirksta nospiedumu."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Pirksta nospiedumu (<xliff:g id="FINGERPRINT">%s</xliff:g>) vairs nevar atpazīt."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Pirkstu nospiedumus (<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> un <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>) vairs nevar atpazīt."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Pirksta nospiedumu (<xliff:g id="FINGERPRINT">%s</xliff:g>) vairs nevar atpazīt. Vēlreiz iestatiet autorizāciju ar pirksta nospiedumu."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Pirkstu nospiedumus (<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> un <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>) vairs nevar atpazīt. Vēlreiz iestatiet autorizāciju ar pirksta nospiedumu."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Vēlreiz iestatiet autorizāciju pēc sejas"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Jūsu sejas modelis nedarbojās pareizi un tika izdzēsts. Iestatiet to atkal, lai varētu atbloķēt tālruni ar seju."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Jūsu sejas modeli vairs nevar atpazīt. Vēlreiz iestatiet autorizāciju pēc sejas."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Iestatīt"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne tagad"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Signāls lietotājam <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Mainīt lietotāju"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Izslēgt skaņu"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Pieskarieties, lai izslēgtu skaņu"</string>
 </resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index f4ed853..cf70e96 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -209,7 +209,7 @@
     <string name="location_changed_notification_text" msgid="7158423339982706912">"Контактирајте со IT-администраторот за да дознаете повеќе"</string>
     <string name="geofencing_service" msgid="3826902410740315456">"Услуга за виртуелна географска граница"</string>
     <string name="country_detector" msgid="7023275114706088854">"Детектор на земја"</string>
-    <string name="location_service" msgid="2439187616018455546">"Услуга за локација"</string>
+    <string name="location_service" msgid="2439187616018455546">"Локациска услуга"</string>
     <string name="gnss_service" msgid="8907781262179951385">"Услуга GNSS"</string>
     <string name="sensor_notification_service" msgid="7474531979178682676">"Услуга за известување од сензорот"</string>
     <string name="twilight_service" msgid="8964898045693187224">"Услуга за самрак"</string>
@@ -498,9 +498,9 @@
     <string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"пристапи кон наредби на давателот на дополнителна локација"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Овозможува апликацијата да пристапи кон дополнителни наредби на давател на локација. Ова може да овозможи апликацијата да го попечи функционирањето на GPS или други извори на локација."</string>
     <string name="permlab_accessFineLocation" msgid="6426318438195622966">"пристап до прецизната локација само во преден план"</string>
-    <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Апликацијава може да ја добие вашата прецизна локација од „Услугите според локација“ кога се користи. „Услугите според локација“ за уредот мора да се вклучени ако сакате апликацијата да ја добие локацијата. Ова може да го зголеми користењето на батеријата."</string>
+    <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Апликацијава може да ја добие вашата прецизна локација од „Локациските услуги“ кога се користи. „Локациските услуги“ за уредот мора да се вклучени ако сакате апликацијата да ја добие локацијата. Ова може да го зголеми користењето на батеријата."</string>
     <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"пристап до приближната локација само во преден план"</string>
-    <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Апликацијава може да ја добие вашата приближна локација од „Услугите според локација“ кога се користи. „Услугите според локација“ за уредот мора да се вклучени ако сакате апликацијата да ја добие локацијата."</string>
+    <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Апликацијава може да ја добие вашата приближна локација од „Локациските услуги“ кога се користи. „Локациските услуги“ за уредот мора да се вклучени ако сакате апликацијата да ја добие локацијата."</string>
     <string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"пристап до локацијата во заднина"</string>
     <string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"Апликацијава може да пристапува до локацијата во секое време, дури и кога не се користи."</string>
     <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"менува аудио поставки"</string>
@@ -1242,7 +1242,7 @@
     <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="chooseActivity" msgid="8563390197659779956">"Избери дејство"</string>
+    <string name="chooseActivity" msgid="8563390197659779956">"Изберете дејство"</string>
     <string name="chooseUsbActivity" msgid="2096269989990986612">"Изберете апликација за USB-уредот"</string>
     <string name="noApplications" msgid="1186909265235544019">"Нема апликации што можат да го извршат ова дејство."</string>
     <string name="aerr_application" msgid="4090916809370389109">"<xliff:g id="APPLICATION">%1$s</xliff:g> запре"</string>
@@ -1310,7 +1310,7 @@
     <string name="dump_heap_text" msgid="1692649033835719336">"Процесот <xliff:g id="PROC">%1$s</xliff:g> го надмина ограничувањето за меморија од <xliff:g id="SIZE">%2$s</xliff:g>. Слика од меморијата ви е достапна за споделување со програмерот. Бидете внимателни: оваа слика од меморијата може да ги содржи сите лични информации до коишто апликацијата има пристап."</string>
     <string name="dump_heap_system_text" msgid="6805155514925350849">"Процесот <xliff:g id="PROC">%1$s</xliff:g> го надмина ограничувањето за меморија од <xliff:g id="SIZE">%2$s</xliff:g>. Слика од меморијата ви е достапна за споделување. Бидете внимателни: оваа слика од меморијата може да содржи чувствителни лични информации до коишто процесот има пристап, што може да вклучуваат работи што сте ги напишале."</string>
     <string name="dump_heap_ready_text" msgid="5849618132123045516">"Слика од меморијата на <xliff:g id="PROC">%1$s</xliff:g> ви е достапна за споделување. Бидете внимателни: оваа слика од меморијата можеби ги содржи сите чувствителни лични информации до коишто процесот има пристап, што може да вклучуваат работи што сте ги напишале."</string>
-    <string name="sendText" msgid="493003724401350724">"Избери дејство за текст"</string>
+    <string name="sendText" msgid="493003724401350724">"Изберете дејство за текст"</string>
     <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>
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Изберете за да се оневозможи безжично отстранување грешки."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Овозможен е режимот на рамка за тестирање"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Извршете фабричко ресетирање за да го оневозможите режимот на рамка за тестирање."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Сериската конзола е овозможена"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Перформансите се засегнати. За да оневозможите, проверете го подигнувачот."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Овозможена е експериментална MTE"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ги задржавте копчињата за јачина на звук. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е вклучена."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ги задржавте копчињата за јачина на звук. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е исклучена."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Ослободете ги копчињата за јачина на звукот. Притиснете ги и задржете ги двете копчиња за јачина на звукот во траење од 3 секунди за да вклучите <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Изберете функција за користење кога ќе го допрете копчето за пристапност:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Изберете ја функцијата што ќе ја користите со движењето за пристапност (повлекување нагоре од дното на екранот со два прста):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Изберете ја функцијата што ќе ја користите со движењето за пристапност (повлекување нагоре од дното на екранот со три прста):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"За префрлање помеѓу функциите, допрете и задржете го копчето за пристапност."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"За да се префрлите на друга функција, повлечете нагоре со два прста и задржете."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"За префрлање помеѓу функциите, повлечете нагоре со три прста и задржете."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Функцијата ќе се отвори следниот пат кога ќе го допрете копчето за пристапност"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Функцијата ќе се отвори следниот пат кога ќе ја користите кратенкава. Повлечете нагоре со 2 прста од долниот дел на екранот и брзо отпуштете."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Функцијата ќе се отвори следниот пат кога ќе ја користите кратенкава. Повлечете нагоре со 3 прста од долниот дел на екранот и брзо отпуштете."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Зголемување"</string>
     <string name="user_switched" msgid="7249833311585228097">"Тековен корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Се префрла на <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Тековен повик"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Проверка на дојдовен повик"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Некатегоризирано"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Промоции"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Друштвени"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Вести"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Препораки"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Ја поставивте важноста на известувањава."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Ова е важно заради луѓето кои се вклучени."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Приспособено известување за апликација"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Избирач на кратенка за пристапност на екранот"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Кратенка за пристапност"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Отфрлете го панелот за известување"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Мени"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Пушти/паузирај аудиовизуелни содржини"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Навигациско копче за нагоре"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Навигациско копче за надолу"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Навигациско копче за налево"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Дознајте како функционира"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Во фаза на чекање…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Поставете „Отклучување со отпечаток“ повторно"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> не функционираше добро, па се избриша"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> не функционираа добро, па се избришаа"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> не функционираше добро, па се избриша. Поставете го повторно за да го отклучувате телефонот со отпечаток."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> не функционираа добро, па се избришаа. Поставете ги повторно за да го отклучувате телефонот со отпечаток."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> веќе не може да се препознае."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> веќе не може да се препознаат."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> веќе не може да се препознае. Поставете „Отклучување со отпечаток“ повторно."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> веќе не може да се препознаат. Поставете „Отклучување со отпечаток“ повторно."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Поставете „Отклучување со лик“ повторно"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Вашиот модел на лик не функционираше добро, па се избриша. Поставете го повторно за да го отклучите телефонот со лик."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Вашиот модел на лик веќе не може да се препознае. Поставете „Отклучување со лик“ повторно."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Поставете"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не сега"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Аларм за <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Сменете го корисникот"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Исклучи звук"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Допрете за да го исклучите звукот"</string>
 </resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index ede15a1..f13f1bb 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"വയർലെസ് ഡീബഗ്ഗിംഗ് പ്രവർത്തനരഹിതമാക്കാൻ തിരഞ്ഞെടുക്കുക."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"പരിശോധനാ സംവിധാനങ്ങൾ മോഡ് പ്രവർത്തനക്ഷമമാക്കി"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"പരിശോധനാ സംവിധാന മോഡ് പ്രവർത്തനരഹിതമാക്കാൻ ഫാക്‌ടറി പുനഃക്രമീകരണം നിർവഹിക്കുക."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"സീരിയൽ കൺസോൾ പ്രവർത്തനക്ഷമമാക്കി"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"പ്രകടനത്തെ ബാധിച്ചു. പ്രവർത്തനരഹിതമാക്കാൻ, ബൂട്ട് ലോഡർ പരിശോധിക്കുക."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"പരീക്ഷണാത്മക MTE പ്രവർത്തനക്ഷമമാക്കി"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"വോളിയം കീകൾ പിടിച്ചു. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓണാക്കി."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"വോളിയം കീകൾ അമർത്തിപ്പിടിച്ചു. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓഫാക്കി."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"വോളിയം കീകൾ വിടുക. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓണാക്കാൻ, രണ്ട് വോളിയം കീകളും വീണ്ടും മൂന്ന് സെക്കൻഡ് അമർത്തിപ്പിടിക്കുക."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"നിങ്ങൾ ഉപയോഗസഹായി ബട്ടൺ ടാപ്പ് ചെയ്യുമ്പോൾ ഉപയോഗിക്കുന്നതിന് ഒരു ഫീച്ചർ തിരഞ്ഞെടുക്കുക:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ഉപയോഗസഹായി വിരൽചലനത്തോടൊപ്പം ഉപയോഗിക്കാൻ ഒരു ഫീച്ചർ തിരഞ്ഞെടുക്കുക (രണ്ട് വിരലുകളുപയോഗിച്ച് സ്‌ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ഉപയോഗസഹായി വിരൽചലനത്തോടൊപ്പം ഉപയോഗിക്കാൻ ഒരു ഫീച്ചർ തിരഞ്ഞെടുക്കുക (മൂന്ന് വിരലുകളുപയോഗിച്ച് സ്‌ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"ഫീച്ചറുകൾക്കിടയിൽ മാറാൻ, ഉപയോഗസഹായി ബട്ടൺ സ്‌പർശിച്ച് പിടിക്കുക."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"ഫീച്ചറുകൾക്കിടയിൽ മാറാൻ, രണ്ട് വിരലുകളുപയോഗിച്ച് മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്‌ത് പിടിക്കുക."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ഫീച്ചറുകൾക്കിടയിൽ മാറാൻ, മൂന്ന് വിരലുകളുപയോഗിച്ച് മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്‌ത് പിടിക്കുക."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"അടുത്ത തവണ നിങ്ങൾ ഉപയോഗസഹായി ബട്ടൺ ടാപ്പ് ചെയ്യുമ്പോൾ ഫീച്ചർ തുറക്കും"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"അടുത്ത തവണ നിങ്ങൾ ഈ കുറുക്കുവഴി ഉപയോഗിക്കുമ്പോൾ ഫീച്ചർ തുറക്കും. നിങ്ങളുടെ സ്ക്രീനിന്റെ താഴെ നിന്ന് 2 വിരലുകൾ ഉപയോഗിച്ച് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്‌ത് പെട്ടെന്ന് വിടുക."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"അടുത്ത തവണ നിങ്ങൾ ഈ കുറുക്കുവഴി ഉപയോഗിക്കുമ്പോൾ ഫീച്ചർ തുറക്കും. നിങ്ങളുടെ സ്ക്രീനിന്റെ താഴെ നിന്ന് 3 വിരലുകൾ ഉപയോഗിച്ച് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്‌ത് പെട്ടെന്ന് വിടുക."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"മാഗ്നിഫിക്കേഷൻ"</string>
     <string name="user_switched" msgid="7249833311585228097">"നിലവിലെ ഉപയോക്താവ് <xliff:g id="NAME">%1$s</xliff:g> ആണ്."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> എന്ന ഉപയോക്താവിലേക്ക് മാറുന്നു…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"സജീവമായ കോൾ"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"ഇൻകമിംഗ് കോൾ സ്‌ക്രീൻ ചെയ്യുന്നു"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"വർഗ്ഗീകരിച്ചിട്ടില്ലാത്ത"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"പ്രമോഷനുകൾ"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"സാമൂഹികം"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"വാർത്തകൾ"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"നിർദ്ദേശങ്ങൾ"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"ഈ അറിയിപ്പുകളുടെ പ്രാധാന്യം നിങ്ങൾ സജ്ജീകരിച്ചു."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"ഉൾപ്പെട്ടിട്ടുള്ള ആളുകളെ കണക്കിലെടുക്കുമ്പോള്‍ ഇത് പ്രധാനപ്പെട്ടതാണ്‌."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"ഇഷ്ടാനുസൃത ആപ്പ് അറിയിപ്പുകൾ"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"സ്ക്രീനിലെ ഉപയോഗസഹായി കുറുക്കുവഴി ചൂസർ"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ഉപയോഗസഹായി കുറുക്കുവഴി"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"അറിയിപ്പ് ഷെയ്‌ഡ് ഡിസ്‌മിസ് ചെയ്യുക"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"മെനു"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"മീഡിയ പ്ലേ ചെയ്യുക/താൽക്കാലികമായി നിർത്തുക"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad അപ്പ്"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad ഡൗൺ"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ലെഫ്റ്റ്"</string>
@@ -2411,19 +2424,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"സ്വകാര്യ സ്പേസ്"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"സൂക്ഷ്‌മമായി കൈകാര്യം ചെയ്യേണ്ട അറിയിപ്പ് ഉള്ളടക്കം മറച്ചിരിക്കുന്നു"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ആപ്പ് ഉള്ളടക്കം, അതിന്റെ സുരക്ഷയ്ക്കായി സ്ക്രീൻ പങ്കിടലിൽ നിന്ന് മറച്ചിരിക്കുന്നു"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"സുരക്ഷയ്ക്കായി സ്ക്രീൻ പങ്കിടലിൽ നിന്ന് ആപ്പ് ഉള്ളടക്കം മറച്ചിരിക്കുന്നു"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"സാറ്റലൈറ്റിലേക്ക് സ്വയമേവ കണക്റ്റ് ചെയ്തു"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"മൊബൈലോ വൈഫൈ നെറ്റ്‌വർക്കോ ഇല്ലാതെ തന്നെ സന്ദേശങ്ങൾ അയയ്‌ക്കാനും സ്വീകരിക്കാനും നിങ്ങൾക്ക് കഴിയും"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages തുറക്കുക"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ഇത് പ്രവർത്തിക്കുന്നത് എങ്ങനെയാണ്"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"തീർപ്പാക്കിയിട്ടില്ല..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ഫിംഗർപ്രിന്റ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കുക"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ശരിയായി പ്രവർത്തിക്കാത്തതിനാൽ അത് ഇല്ലാതാക്കി"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> എന്നിവ ശരിയായി പ്രവർത്തിക്കാത്തതിനാൽ അവ ഇല്ലാതാക്കി"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ശരിയായി പ്രവർത്തിക്കാത്തതിനാൽ അത് ഇല്ലാതാക്കി. നിങ്ങളുടെ ഫിംഗർപ്രിന്റ് ഉപയോഗിച്ച് ഫോൺ അൺലോക്ക് ചെയ്യുന്നതിനായി വീണ്ടും സജ്ജീകരിക്കുക."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> എന്നിവ ശരിയായി പ്രവർത്തിക്കാത്തതിനാൽ അവ ഇല്ലാതാക്കി. നിങ്ങളുടെ ഫിംഗർപ്രിന്റ് ഉപയോഗിച്ച് ഫോൺ അൺലോക്ക് ചെയ്യുന്നതിനായി അവ വീണ്ടും സജ്ജീകരിക്കുക."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ഇനി തിരിച്ചറിയാനാകില്ല."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> എന്നിവ ഇനി തിരിച്ചറിയാനാകില്ല."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ഇനി തിരിച്ചറിയാനാകില്ല. ഫിംഗർപ്രിന്റ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കുക."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> എന്നിവ ഇനി തിരിച്ചറിയാനാകില്ല. ഫിംഗർപ്രിന്റ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കുക."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"ഫെയ്‌സ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കുക"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"നിങ്ങളുടെ മുഖ മോഡൽ ശരിയായി പ്രവർത്തിക്കാത്തതിനാൽ അത് ഇല്ലാതാക്കി. നിങ്ങളുടെ മുഖം ഉപയോഗിച്ച് ഫോൺ അൺലോക്ക് ചെയ്യുന്നതിനായി വീണ്ടും സജ്ജീകരിക്കുക."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"നിങ്ങളുടെ മുഖ മോഡൽ ഇനി തിരിച്ചറിയാനാകില്ല. ഫെയ്‌സ് അൺലോക്ക് വീണ്ടും സജ്ജീകരിക്കുക."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"സജ്ജീകരിക്കുക"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ഇപ്പോൾ വേണ്ട"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> എന്നയാൾക്കുള്ള അലാറം"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ഉപയോക്താവിനെ മാറുക"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"മ്യൂട്ടുചെയ്യുക"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ശബ്ദം മ്യൂട്ട് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക"</string>
 </resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 955b025..109cce8 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Wireless debugging-г идэвхгүй болгохын тулд сонгоно уу."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Туршилтын цогц горимыг идэвхжүүлсэн"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Туршилтын цогц горимыг идэвхгүй болгохын тулд үйлдвэрийн төлөвт шинэчилнэ үү."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Цуваа консолыг идэвхжүүлсэн"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Гүйцэтгэлд нөлөөлнө. Идэвхгүй болгохын тулд эхэлж ачаалагчийг шалгана уу."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Туршилтын MTE-г идэвхжүүлсэн"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Дууны түвшний түлхүүрийг удаан дарсан. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г асаалаа."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Дууны түвшний түлхүүрийг удаан дарсан. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г унтраалаа."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Дууны түвшний товчнуудыг суллана уу. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г асаахын тулд дууны түвшний 2 товчийг зэрэг 3 секундийн турш удаан дарна уу."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Хандалтын товчлуурыг товшихдоо ашиглах онцлогийг сонгоно уу:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Хандалтын зангаагаар ашиглах үйлчилгээг сонгоно уу (хоёр хуруугаараа дэлгэцийн доороос дээш хоёр хуруугаар шударна уу):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Хандалтын зангаагаар ашиглах онцлогийг сонгоно уу (гурван хуруугаар дэлгэцийн доороос дээш шударна уу):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Онцлогуудын хооронд сэлгэхийн тулд хандалтын товчлуурыг удаан дарна уу."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Онцлогуудын хооронд сэлгэхийн тулд хоёр хуруугаар дээш шудраад удаан дарна уу."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Онцлогуудын хооронд сэлгэхийн тулд гурван хуруугаар дээш шудраад удаан дарна уу."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Таныг дараагийн удаа хандалтын товчийг товших үед тус онцлог нээгдэнэ"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Таныг дараагийн удаа энэ товчлолыг ашиглах үед тус онцлог нээгдэнэ. Дэлгэцийнхээ доод талаас 2 хуруугаараа дээш шудраад, түргэн суллана уу."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Таныг дараагийн удаа энэ товчлолыг ашиглах үед тус онцлог нээгдэнэ. Дэлгэцийнхээ доод талаас 3 хуруугаараа дээш шудраад, түргэн суллана уу."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Томруулах"</string>
     <string name="user_switched" msgid="7249833311585228097">"Одоогийн хэрэглэгч <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> руу сэлгэж байна…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Дуудлага хийгдэж байна"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Ирсэн дуудлагыг харуулж байна"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Ангилаагүй"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Урамшуулал"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Сошиал"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Мэдээ"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Зөвлөмж"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Та эдгээр мэдэгдлийн ач холбогдлыг тогтоосон."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Оролцсон хүмүүсээс шалтгаалан энэ нь өндөр ач холбогдолтой."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Аппын захиалгат мэдэгдэл"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Дэлгэц дээрх хандалтын товчлол сонгогч"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Хандалтын товчлол"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Мэдэгдлийн хураангуй самбарыг хаах"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Цэс"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Медиаг тоглуулах/түр зогсоох"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad дээш"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad доош"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad зүүн"</string>
@@ -2411,19 +2424,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Хаалттай орон зай"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"Эмзэг мэдэгдлийн контентыг нуусан"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Аюулгүй байдлын улмаас аппын контентыг дэлгэц хуваалцахаас нуусан"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Аюулгүй байдлын үүднээс аппын контентыг дэлгэц хуваалцахаас нуусан"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"Хиймэл дагуулд автоматаар холбогдсон"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Та мобайл эсвэл Wi-Fi сүлжээгүйгээр мессеж илгээх болон хүлээн авах боломжтой"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Мессежийг нээх"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Энэ хэрхэн ажилладаг вэ?"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Хүлээгдэж буй..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Хурууны хээгээр түгжээ тайлахыг дахин тохируулна уу"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> сайн ажиллахгүй байсан тул хурууны хээг устгасан"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> болон <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> сайн ажиллахгүй байсан тул эдгээр хурууны хээг устгасан"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> сайн ажиллахгүй байсан тул үүнийг устгасан. Утасныхаа түгжээг хурууны хээгээр тайлахын тулд хурууны хээг дахин тохируулна уу."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> сайн ажиллахгүй байсан тул эдгээрийг устгасан. Утасныхаа түгжээг хурууныхаа хээгээр тайлахын тулд хоёр хурууны хээг дахин тохируулна уу."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>-г цаашид таних боломжгүй."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> болон <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>-г цаашид таних боломжгүй."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g>-г цаашид таних боломжгүй. Хурууны хээгээр түгжээ тайлахыг дахин тохируулна уу."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> болон <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>-г цаашид таних боломжгүй. Хурууны хээгээр түгжээ тайлахыг дахин тохируулна уу."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Царайгаар түгжээ тайлахыг дахин тохируулна уу"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Таны нүүрний загвар сайн ажиллахгүй байсан бөгөөд үүнийг устгасан. Утасныхаа түгжээг царайгаар тайлахын тулд нүүрний загварыг дахин тохируулна уу."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Таны нүүрний загварыг цаашид таних боломжгүй. Царайгаар түгжээ тайлахыг дахин тохируулна уу."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Тохируулах"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Одоо биш"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>-н сэрүүлэг"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Хэрэглэгч сэлгэх"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Дууг хаах"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Дууг хаахын тулд товшино уу"</string>
 </resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 2df1bc9..3817d27 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"वायरलेस डीबगिंग बंद करण्यासाठी निवडा."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"टेस्ट हार्नेस मोड सुरू केला आहे"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"टेस्ट हार्नेस मोड बंद करण्यासाठी फॅक्टरी रीसेट करा."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"सिरीअल कन्सोल सुरू केला आहे"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"परफॉर्मन्सवर परिणाम होतो. बंद करण्यासाठी, बूटलोडर तपासा."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"प्रायोगिक MTE सुरू केले आहे"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"धरून ठेवलेल्या व्हॉल्यूम की. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> सुरू केला आहे."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"धरून ठेवलेल्या व्हॉल्यूम की. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> बंद केले आहे."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"व्हॉल्यूम की रिलीझ करा. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> सुरू करण्यासाठी, दोन्ही व्हॉल्यूम की पुन्हा प्रेस करा आणि तीन सेकंदांसाठी धरून ठेवा."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"तुम्ही अ‍ॅक्सेसिबिलिटी बटणावर टॅप केल्यास वापरण्यासाठी एक वैशिष्ट्य निवडा:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"अ‍ॅक्सेसिबिलिटी जेश्चरसोबत वापराचे असलेले वैशिष्‍ट्य निवडा (दोन बोटांनी स्क्रीनच्या तळापासून वर स्वाइप करा):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"अ‍ॅक्सेसिबिलिटी जेश्चरसोबत वापराचे असलेले वैशिष्‍ट्य निवडा (तीनन बोटांनी स्क्रीनच्या तळापासून वर स्वाइप करा):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"वैशिष्टयांदरम्यान स्विच करण्यासाठी अ‍ॅक्सेसिबिलिटी बटणाला स्पर्श करा आणि धरून ठेवा."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"वैशिष्टयांदरम्यान स्विच करण्यासाठी दोन बोटांनी वर स्वाइप करा आणि धरून ठेवा."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"वैशिष्टयांदरम्यान स्विच करण्यासाठी तीन बोटांनी वर स्वाइप करा आणि धरून ठेवा."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"तुम्ही पुढील वेळी अ‍ॅक्सेसिबिलिटी बटणावर टॅप कराल, तेव्हा वैशिष्ट्य उघडेल"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"तुम्ही पुढील वेळी हा शॉर्टकट वापराल, तेव्हा वैशिष्ट्य उघडेल. २ बोटांनी तुमच्या स्क्रीनच्या तळापासून वर स्वाइप करा आणि पटकन रिलीझ करा."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"तुम्ही पुढील वेळी हा शॉर्टकट वापराल, तेव्हा वैशिष्ट्य उघडेल. ३ बोटांनी तुमच्या स्क्रीनच्या तळापासून वर स्वाइप करा आणि पटकन रिलीझ करा."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"मॅग्निफिकेशन"</string>
     <string name="user_switched" msgid="7249833311585228097">"वर्तमान वापरकर्ता <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> वर स्विच करत आहे…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"सुरू असलेला कॉल"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"इनकमिंग कॉल स्क्रीन करत आहे"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"वर्गीकरण न केलेले"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"प्रमोशन"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"सोशल"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"बातम्या"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"शिफारशी"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"तुम्ही या सूचनांचे महत्त्व सेट केले."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"सामील असलेल्या लोकांमुळे हे महत्वाचे आहे."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"कस्टम ॲप सूचना"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ऑन-स्क्रीन ॲक्सेसिबिलिटी शॉर्टकट निवडकर्ता"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"अ‍ॅक्सेसिबिलिटी शॉर्टकट"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"सूचना शेड डिसमिस करा"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"मेनू"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"मीडिया प्ले करा/थांबवा"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad चे वरील"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad चे खालचे"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad डावीकडील"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ते कसे काम करते"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"प्रलंबित आहे..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"फिंगरप्रिंट अनलॉक पुन्हा सेट करा"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> योग्यरीत्या काम करत नव्हती, त्यामुळे ती हटवली आहे"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> आणि <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> योग्यरीत्या काम करत नव्हत्या, त्यामुळे त्या हटवल्या आहेत"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"योग्यरीत्या काम करत नसल्यामुळे <xliff:g id="FINGERPRINT">%s</xliff:g> हटवले गेले आहे. तुमचे फिंगरप्रिंट वापरून फोन अनलॉक करण्यासाठी ते पुन्हा सेट करा."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"परफॉर्मन्समध्ये सुधारणा करण्यासाठी आणि योग्यरीत्या काम करत नसल्यामुळे <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> व <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> हटवली गेली आहेत. तुमचे फिंगरप्रिंट वापरून फोन अनलॉक करण्यासाठी ते पुन्हा सेट करा."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> यापुढे ओळखता येणार नाही."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> आणि <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> यापुढे ओळखता येणार नाहीत."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> यापुढे ओळखता येणार नाही. फिंगरप्रिंट अनलॉक पुन्हा सेट करा."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> आणि <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> यापुढे ओळखता येणार नाहीत. फिंगरप्रिंट अनलॉक पुन्हा सेट करा."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"फेस अनलॉक पुन्हा सेट करा"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"तुमचे फेस मॉडेल योग्यरीत्या काम करत नसल्यामुळे ते हटवले गेले आहे. तुमचा चेहरा वापरून फोन अनलॉक करण्यासाठी ते पुन्हा सेट करा."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"तुमचे फेस मॉडेल यापुढे ओळखता येणार नाही. फेस अनलॉक पुन्हा सेट करा."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"सेट करा"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"आताच नको"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> साठी अलार्म"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"वापरकर्ता स्विच करा"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"म्यूट करा"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"आवाज म्यूट करण्यासाठी टॅप करा"</string>
 </resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 31180be..d1bd23d 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Pilih untuk melumpuhkan penyahpepijatan wayarles."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Mod Abah-abah Ujian didayakan"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Laksanakan tetapan semula kilang untuk melumpuhkan Mod Abah-abah Ujian."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Konsol bersiri didayakan"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Prestasi terjejas. Untuk melumpuhkan, semak pemuat but."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Percubaan MTE didayakan"</string>
@@ -1436,7 +1440,7 @@
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Paparkan di atas apl lain"</string>
     <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> dipaparkan di atas apl lain"</string>
     <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> dipaparkan di atas apl lain"</string>
-    <string name="alert_windows_notification_message" msgid="6538171456970725333">"Jika anda tidak mahu <xliff:g id="NAME">%s</xliff:g> menggunakan ciri ini, ketik untuk membuka tetapan dan matikannya."</string>
+    <string name="alert_windows_notification_message" msgid="6538171456970725333">"Jika anda tidak mahu <xliff:g id="NAME">%s</xliff:g> menggunakan ciri ini, ketik untuk membuka tetapan dan matikan ciri tersebut."</string>
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Matikan"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Menyemak <xliff:g id="NAME">%s</xliff:g>…"</string>
     <string name="ext_media_checking_notification_message" msgid="2231566971425375542">"Menyemak kandungan semasa"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dihidupkan."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dimatikan."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lepaskan kekunci kelantangan. Untuk menghidupkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, sila tekan dan tahan kedua-dua kekunci kelantangan sekali lagi selama 3 saat."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Pilih ciri yang hendak digunakan apabila anda mengetik butang kebolehaksesan:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Pilih ciri untuk digunakan dengan gerak isyarat kebolehaksesan (leret ke atas dari bahagian bawah skrin menggunakan dua jari):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Pilih ciri untuk digunakan dengan gerak isyarat kebolehaksesan (leret ke atas dari bahagian bawah skrin menggunakan tiga jari):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Untuk beralih antara ciri, sentuh &amp; tahan butang kebolehaksesan."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Untuk beralih antara ciri, leret ke atas menggunakan dua jari dan tahan."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Untuk beralih antara ciri, leret ke atas menggunakan tiga jari dan tahan."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Ciri ini akan dibuka pada kali seterusnya anda mengetik butang kebolehaksesan"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Ciri ini akan dibuka pada kali seterusnya anda menggunakan pintasan ini. Leret ke atas menggunakan 2 jari dari bahagian bawah skrin anda dan lepaskan dengan cepat."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Ciri ini akan dibuka pada kali seterusnya anda menggunakan pintasan ini. Leret ke atas menggunakan 3 jari dari bahagian bawah skrin anda dan lepaskan dengan cepat."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Pembesaran"</string>
     <string name="user_switched" msgid="7249833311585228097">"Pengguna semasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Beralih kepada <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Panggilan sedang berlangsung"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Menyaring panggilan masuk"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Tidak dikategorikan"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promosi"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Sosial"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Berita"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Syor"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Anda menetapkan kepentingan pemberitahuan ini."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Mesej ini penting disebabkan orang yang terlibat."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Pemberitahuan apl tersuai"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Pemilih Pintasan Kebolehaksesan Pada Skrin"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Pintasan Kebolehaksesan"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ketepikan Bidai Pemberitahuan"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Mainkan/Jeda Media"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad Atas"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad Bawah"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad Kiri"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cara ciri ini berfungsi"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Belum selesai..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Sediakan Buka Kunci Cap Jari sekali lagi"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak berfungsi dengan baik dan telah dipadamkan"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak berfungsi dengan baik dan telah dipadamkan"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak berfungsi dengan baik dan telah dipadamkan. Sediakan cap jari sekali lagi untuk membuka kunci telefon anda menggunakan cap jari."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak berfungsi dengan baik dan telah dipadamkan. Sediakan kedua-dua cap jari tersebut sekali lagi untuk membuka kunci telefon anda menggunakan cap jari anda."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak dapat dicam lagi."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak dapat dicam lagi."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> tidak dapat dicam lagi. Sediakan semula Buka Kunci Cap Jari."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dan <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> tidak dapat dicam lagi. Sediakan semula Buka Kunci Cap Jari."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Sediakan semula Buka Kunci Wajah"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Model wajah anda tidak berfungsi dengan baik dan telah dipadamkan. Sediakan model wajah sekali lagi untuk membuka kunci telefon anda menggunakan wajah."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Model wajah anda tidak dapat dicam lagi. Sediakan semula Buka Kunci Wajah."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Sediakan"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Bukan sekarang"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Penggera untuk <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Tukar pengguna"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Redam"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Ketik untuk meredamkan bunyi"</string>
 </resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index f1ab9e0..535b854 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ကြိုးမဲ့ အမှားရှာပြင်ခြင်းကို ပိတ်ရန် ရွေးပါ။"</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"\'စမ်းသပ်ခြင်းစနစ်မုဒ်\' ဖွင့်ထားသည်"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"\'စမ်းသပ်ခြင်းစနစ် မုဒ်\' ကိုပိတ်ရန် စက်ရုံထုတ်အတိုင်း ပြင်ဆင်သတ်မှတ်ပါ။"</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"အမှတ်စဉ် ကွန်ဆိုးလ်ကို ဖွင့်ထားသည်"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"စွမ်းဆောင်ရည်အပေါ် သက်ရောက်မှုရှိနိုင်ပါသည်။ ပိတ်ရန် bootloader ကို စစ်ဆေးပါ။"</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"အစမ်းသုံး MTE ကို ဖွင့်ထားသည်"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"အသံခလုတ်များကို ဖိထားသည်။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ဖွင့်လိုက်သည်။"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"အသံခလုတ်များကို ဖိထားသည်။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ပိတ်လိုက်သည်။"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"အသံထိန်းခလုတ်များကို လွှတ်လိုက်ပါ။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ဖွင့်ရန် အသံထိန်းခလုတ်နှစ်ခုစလုံးကို ၃ စက္ကန့်ကြာအောင် ထပ်နှိပ်ပါ။"</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"သုံးနိုင်မှုခလုတ်ကို တို့ပြီးလျှင် ဝန်ဆောင်မှုတစ်ခု ရွေးပါ−"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"သုံးနိုင်မှုလက်ဟန်ဖြင့် အသုံးပြုရန် ဝန်ဆောင်မှုတစ်ခုကို ရွေးပါ (ဖန်သားပြင်အောက်ခြေမှနေ၍ လက်နှစ်ချောင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပါ)-"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"သုံးနိုင်မှုလက်ဟန်ဖြင့် အသုံးပြုရန် ဝန်ဆောင်မှုတစ်ခုကို ရွေးပါ (ဖန်သားပြင်အောက်ခြေမှနေ၍ လက်သုံးချောင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပါ)-"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"ဝန်ဆောင်မှုများအကြား ပြောင်းရန် အများသုံးစွဲနိုင်မှုခလုတ်ကို ဖိထားပါ။"</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"ဝန်ဆောင်မှုများအကြား ပြောင်းရန် လက်နှစ်ချောင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပြီး ဖိထားပါ။"</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ဝန်ဆောင်မှုများအကြား ပြောင်းရန် လက်သုံးချောင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပြီး ဖိထားပါ။"</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"နောက်တစ်ကြိမ်တွင် သုံးနိုင်မှုခလုတ်ကို တို့သည့်အခါ ဤဝန်ဆောင်မှု ပွင့်လာမည်"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"နောက်တစ်ကြိမ်တွင် ဤဖြတ်လမ်းကို သုံးသည့်အခါ ဤဝန်ဆောင်မှု ပွင့်လာမည်။ သင့်ဖန်သားပြင်အောက်ခြေမှ အပေါ်သို့ လက် ၂ ချောင်းဖြင့် ပွတ်ဆွဲ၍ အမြန်လွှတ်လိုက်ပါ။"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"နောက်တစ်ကြိမ်တွင် ဤဖြတ်လမ်းကို သုံးသည့်အခါ ဤဝန်ဆောင်မှု ပွင့်လာမည်။ သင့်ဖန်သားပြင်အောက်ခြေမှ အပေါ်သို့ လက် ၃ ချောင်းဖြင့် ပွတ်ဆွဲ၍ အမြန်လွှတ်လိုက်ပါ။"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ချဲ့ခြင်း"</string>
     <string name="user_switched" msgid="7249833311585228097">"လက်ရှိအသုံးပြုနေသူ <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>သို့ ပြောင်းနေသည်…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"လက်ရှိခေါ်ဆိုမှု"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"အဝင်ခေါ်ဆိုမှုကို စစ်ဆေးနေသည်"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"အမျိုးအစားမခွဲရသေးပါ"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ပရိုမိုးရှင်းများ"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"လူမှုရေး"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"သတင်း"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"အကြံပြုချက်များ"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"ဤသတိပေးချက်များ၏ အရေးပါမှုကိုသတ်မှတ်ပြီးပါပြီ။"</string>
     <string name="importance_from_person" msgid="4235804979664465383">"ပါဝင်သည့်လူများကြောင့် အရေးပါပါသည်။"</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"စိတ်ကြိုက်အက်ပ် အကြောင်းကြားချက်"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ဖန်သားပြင်အတွက် အများသုံးစွဲနိုင်မှုဖြတ်လမ်းလင့်ခ် ရွေးချယ်စနစ်"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"အများသုံးနိုင်မှု ဖြတ်လမ်းလင့်ခ်"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"အကြောင်းကြားစာအကွက်ကို ပယ်ရန်"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"မီနူး"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"မီဒီယာ ဖွင့်ရန်/ခဏရပ်ရန်"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad အပေါ်"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad အောက်"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ဘယ်"</string>
@@ -2411,19 +2424,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"သီးသန့်နေရာ"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"သတိထားရမည့် အကြောင်းကြားချက်ပါ အချက်အလက်ကို ဖျောက်ထားသည်"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"အက်ပ်အကြောင်းအရာသည် လုံခြုံရေးအတွက် မျက်နှာပြင် မျှဝေခြင်းမှ ဖျောက်ထားသည်"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"လုံခြုံရေးအတွက် အက်ပ်အကြောင်းအရာကို ဖန်သားပြင် မျှဝေခြင်းတွင် ဖျောက်ထားသည်"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"ဂြိုဟ်တုနှင့် အလိုအလျောက် ချိတ်ဆက်ထားသည်"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"မိုဘိုင်း (သို့) Wi-Fi ကွန်ရက်မရှိဘဲ မက်ဆေ့ဂျ်များကို ပို့နိုင်၊ လက်ခံနိုင်သည်"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ဖွင့်ရန်"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"အလုပ်လုပ်ပုံ"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"ဆိုင်းငံ့ထားသည်…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"‘လက်ဗွေသုံး လော့ခ်ဖွင့်ခြင်း’ ကို စနစ်ထပ်မံထည့်သွင်းပါ"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> သိပ်အဆင်မပြေသဖြင့် ဖျက်ထားသည်"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> နှင့် <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> တို့ သိပ်အဆင်မပြေသဖြင့် ဖျက်ထားသည်"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> သိပ်အဆင်မပြေသဖြင့် ဖျက်ထားသည်။ သင့်ဖုန်းကို လက်ဗွေဖြင့်လော့ခ်ဖွင့်ရန် ၎င်းကို စနစ်ထပ်မံထည့်သွင်းပါ။"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> နှင့် <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> တို့ သိပ်အဆင်မပြေသဖြင့် ဖျက်ထားသည်။ သင့်ဖုန်းကို လက်ဗွေဖြင့်လော့ခ်ဖွင့်ရန် ၎င်းတို့ကို စနစ်ထပ်မံထည့်သွင်းပါ။"</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ကို မသိရှိနိုင်တော့ပါ။"</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> နှင့် <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ကို မသိရှိနိုင်တော့ပါ။"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ကို မသိရှိနိုင်တော့ပါ။ ‘လက်ဗွေသုံး လော့ခ်ဖွင့်ခြင်း’ ထပ်မံစနစ်ထည့်သွင်းပါ။"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> နှင့် <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ကို မသိရှိနိုင်တော့ပါ။ ‘လက်ဗွေသုံး လော့ခ်ဖွင့်ခြင်း’ ထပ်မံစနစ်ထည့်သွင်းပါ။"</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"‘မျက်နှာပြ လော့ခ်ဖွင့်ခြင်း’ ကို စနစ်ထပ်မံထည့်သွင်းပါ"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"သင့်မျက်နှာနမူနာ သိပ်အဆင်မပြေသဖြင့် ဖျက်ထားသည်။ သင့်ဖုန်းကို မျက်နှာဖြင့်လော့ခ်ဖွင့်ရန် ၎င်းကို စနစ်ထပ်မံထည့်သွင်းပါ။"</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"သင်၏မျက်နှာနမူနာကို မသိရှိနိုင်တော့ပါ။ ‘မျက်နှာပြ လော့ခ်ဖွင့်ခြင်း’ ထပ်မံစနစ်ထည့်သွင်းပါ။"</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"စနစ်ထည့်သွင်းရန်"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ယခုမလုပ်ပါ"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> အတွက် နှိုးစက်"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"အသုံးပြုသူ ပြောင်းရန်"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"အသံပိတ်ရန်"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"အသံပိတ်ရန် တို့ပါ"</string>
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 456366f..fe45ab7 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -264,16 +264,16 @@
     <string name="global_action_emergency" msgid="1387617624177105088">"Nødssituasjon"</string>
     <string name="global_action_bug_report" msgid="5127867163044170003">"Feilrapport"</string>
     <string name="global_action_logout" msgid="6093581310002476511">"Avslutt økten"</string>
-    <string name="global_action_screenshot" msgid="2610053466156478564">"Skjermdump"</string>
+    <string name="global_action_screenshot" msgid="2610053466156478564">"Skjermbilde"</string>
     <string name="bugreport_title" msgid="8549990811777373050">"Feilrapport"</string>
     <string name="bugreport_message" msgid="5212529146119624326">"Informasjon om tilstanden til enheten din samles inn og sendes som en e-post. Det tar litt tid fra du starter feilrapporten til e-posten er klar, så vær tålmodig."</string>
     <string name="bugreport_option_interactive_title" msgid="7968287837902871289">"Interaktiv rapport"</string>
-    <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Bruk dette alternativet i de fleste tilfeller. Da kan du spore fremgangen for rapporten, skrive inn flere detaljer om problemet samt ta skjermdumper. Noen deler som tar lang tid å behandle, blir kanskje utelatt."</string>
+    <string name="bugreport_option_interactive_summary" msgid="8493795476325339542">"Bruk dette alternativet i de fleste tilfeller. Da kan du spore fremgangen for rapporten, skrive inn flere detaljer om problemet samt ta skjermbilder. Noen deler som tar lang tid å behandle, blir kanskje utelatt."</string>
     <string name="bugreport_option_full_title" msgid="7681035745950045690">"Fullstendig rapport"</string>
-    <string name="bugreport_option_full_summary" msgid="1975130009258435885">"Bruk dette alternativet for minst mulig forstyrrelse på systemet når enheten din er treg eller ikke svarer, eller når du trenger alle rapportdelene. Det tas ikke noen skjermdump, og du kan ikke legge til flere detaljer."</string>
-    <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{Tar skjermdump for feilrapporten om # sekund.}other{Tar skjermdump for feilrapporten om # sekunder.}}"</string>
-    <string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"En skjermdump er tatt med feilrapporten"</string>
-    <string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"Kunne ikke ta skjermdump med feilrapporten"</string>
+    <string name="bugreport_option_full_summary" msgid="1975130009258435885">"Bruk dette alternativet for minst mulig forstyrrelse på systemet når enheten din er treg eller ikke svarer, eller når du trenger alle rapportdelene. Det tas ikke noen skjermbilde, og du kan ikke legge til flere detaljer."</string>
+    <string name="bugreport_countdown" msgid="6418620521782120755">"{count,plural, =1{Tar skjermbilde for feilrapporten om # sekund.}other{Tar skjermbilde for feilrapporten om # sekunder.}}"</string>
+    <string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"En skjermbilde er tatt med feilrapporten"</string>
+    <string name="bugreport_screenshot_failure_toast" msgid="6736320861311294294">"Kunne ikke ta skjermbilde med feilrapporten"</string>
     <string name="global_action_toggle_silent_mode" msgid="8464352592860372188">"Stillemodus"</string>
     <string name="global_action_silent_mode_on_status" msgid="2371892537738632013">"Lyden er av"</string>
     <string name="global_action_silent_mode_off_status" msgid="6608006545950920042">"Lyden er på"</string>
@@ -359,8 +359,8 @@
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"Kan trykke, sveipe, klype og gjøre andre bevegelser."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Bevegelser på fingeravtrykkssensor"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Kan fange inn bevegelser som utføres på enhetens fingeravtrykkssensor."</string>
-    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ta skjermdump"</string>
-    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Kan ikke ta en skjermdump av skjermen."</string>
+    <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Ta skjermbilde"</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Kan ikke ta et skjermbilde av skjermen."</string>
     <string name="dream_preview_title" msgid="5570751491996100804">"Forhåndsvisning, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="dream_accessibility_action_click" msgid="7392398629967797805">"lukk"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"deaktivere eller endre statusfeltet"</string>
@@ -509,8 +509,8 @@
     <string name="permdesc_recordAudio" msgid="5857246765327514062">"Denne appen kan ta opp lyd med mikrofonen mens den er i bruk."</string>
     <string name="permlab_recordBackgroundAudio" msgid="5891032812308878254">"ta opp lyd i bakgrunnen"</string>
     <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Denne appen kan når som helst ta opp lyd med mikrofonen."</string>
-    <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"registrere skjermdumper av appvinduer"</string>
-    <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Denne appen varsles hvis det tas skjermdumper mens appen er i bruk."</string>
+    <string name="permlab_detectScreenCapture" msgid="4447042362828799433">"registrere skjermbilder av appvinduer"</string>
+    <string name="permdesc_detectScreenCapture" msgid="3485784917960342284">"Denne appen varsles hvis det tas skjermbilder mens appen er i bruk."</string>
     <string name="permlab_sim_communication" msgid="176788115994050692">"sende kommandoer til SIM-kortet"</string>
     <string name="permdesc_sim_communication" msgid="4179799296415957960">"Lar appen sende kommandoer til SIM-kortet. Dette er veldig farlig."</string>
     <string name="permlab_activityRecognition" msgid="1782303296053990884">"gjenkjenn fysisk aktivitet"</string>
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Velg for å slå av trådløs feilsøking."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Testrammeverk-modus er slått på"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Tilbakestill enheten til fabrikkstandard for å slå av Testrammeverk-modus."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Seriekonsollen er aktivert"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Ytelsen er påvirket. Sjekk oppstartsinnlasteren for å deaktivere."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"MTE på forsøksstadiet er aktivert"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått på."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått av."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Slipp opp volumtastene. For å slå på <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, trykk og hold på begge volumtastene igjen i 3 sekunder."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Velg en funksjon du vil bruke når du trykker på Tilgjengelighet-knappen:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Velg en funksjon du vil bruke med tilgjengelighetsbevegelsen (sveip opp fra bunnen av skjermen med to fingre):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Velg en funksjon du vil bruke med tilgjengelighetsbevegelsen (sveip opp fra bunnen av skjermen med tre fingre):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"For å bytte mellom funksjoner, trykk og hold på Tilgjengelighet-knappen."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"For å bytte mellom funksjoner, sveip opp med to fingre og hold."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"For å bytte mellom funksjoner, sveip opp med tre fingre og hold."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funksjonen åpnes neste gang du trykker på Tilgjengelighet-knappen"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funksjonen åpnes neste gang du bruker denne snarveien. Sveip opp med 2 fingre fra nederst på skjermen, og slipp raskt opp."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funksjonen åpnes neste gang du bruker denne snarveien. Sveip opp med 3 fingre fra nederst på skjermen, og slipp raskt opp."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Forstørring"</string>
     <string name="user_switched" msgid="7249833311585228097">"Gjeldende bruker: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Bytter til <xliff:g id="NAME">%1$s</xliff:g> …"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Pågående samtale"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrerer et innkommende anrop"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Uten kategori"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoteringer"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Sosialt"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Nyheter"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Anbefalinger"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Du angir viktigheten for disse varslene."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Dette er viktig på grunn av folkene som er involvert."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Tilpasset appvarsel"</string>
@@ -2186,12 +2197,14 @@
     <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Hurtiginnstillinger"</string>
     <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dialogboks for å slå av/på"</string>
     <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Låseskjerm"</string>
-    <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Skjermdump"</string>
+    <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Skjermbilde"</string>
     <string name="accessibility_system_action_headset_hook_label" msgid="8524691721287425468">"Hook for hodetelefoner"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Tilgjengelighetssnarvei på skjermen"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Velger for tilgjengelighetssnarvei på skjermen"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Tilgjengelighetssnarvei"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Lukk varselpanelet"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Meny"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media – spill av og sett på pause"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Opp på styrepilene"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Ned på styrepilene"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Venstre på styrepilene"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Slik fungerer det"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Venter …"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfigurer opplåsingen med fingeravtrykk på nytt"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> fungerte ikke skikkelig og ble slettet"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> fungerte ikke skikkelig og ble slettet"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> fungerte ikke skikkelig og ble slettet. Du kan konfigurere det på nytt for å låse opp telefonen med fingeravtrykket."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> fungerte ikke skikkelig og ble slettet. Du kan konfigurere dem på nytt for å låse opp telefonen med fingeravtrykket."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> gjenkjennes ikke lenger."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> gjenkjennes ikke lenger."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> gjenkjennes ikke lenger. Konfigurer opplåsing med fingeravtrykk på nytt."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> og <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> gjenkjennes ikke lenger. Konfigurer opplåsing med fingeravtrykk på nytt."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Konfigurer ansiktslåsen på nytt"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Ansiktsmodellen din fungerte ikke skikkelig og ble slettet. Du kan konfigurere den på nytt for å låse opp telefonen med ansiktet."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Ansiktsmodellen din gjenkjennes ikke lenger. Konfigurer ansiktslåsen på nytt."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Konfigurer"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ikke nå"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm for <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Bytt bruker"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Kutt lyden"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Trykk for å kutte lyden"</string>
 </resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 55c2ef4..8519e23 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"वायरलेस डिबगिङ असक्षम पार्न यो विकल्प चयन गर्नुहोस्।"</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"परीक्षण प्याकेज मोड सक्षम पारियो"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"परीक्षण प्याकेज मोड असक्षम पार्न फ्याक्ट्री रिसेट गर्नुहोस्।"</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"क्रमसम्बन्धी कन्सोल सक्षम पारियो"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"पर्फर्मेन्समा प्रभाव परेको छ। यसलाई असक्षम पार्न बुटलोडरको जाँच गर्नुहोस्।"</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"परीक्षणका क्रममा रहेको MTE अन गरियो"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अन भयो।"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अफ भयो।"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"भोल्युम बटनहरू थिच्न छाड्नुहोस्। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अन गर्न दुवै भोल्युम बटन फेरि ३ सेकेन्डसम्म थिचिराख्नुहोस्।"</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"तपाईंले एक्सेसिबिलिटी बटन ट्याप गर्दा प्रयोग गर्न चाहनुभएको सुविधा छनौट गर्नुहोस्:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"तपाईंले पहुँचको इसारामार्फत प्रयोग गर्न चाहनुभएको सुविधा छनौट गर्नुहोस् (दुईवटा औँलाले स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"तपाईंले पहुँचको इसारामार्फत प्रयोग गर्न चाहनुभएको सुविधा छनौट गर्नुहोस् (तीनवटा औँलाले स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"एउटा सुविधाबाट अर्को सुविधामा जान पहुँच बटन टच एण्ड होल्ड गर्नुहोस्।"</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"एउटा सुविधाबाट अर्को सुविधामा जान दुईवटा औँलाले माथितिर स्वाइप गरी स्क्रिनमा टच एण्ड होल्ड गर्नुहोस्।"</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"एउटा सुविधाबाट अर्को सुविधामा जान तीनवटा औँलाले माथितिर स्वाइप गरी स्क्रिनमा टच एण्ड होल्ड गर्नुहोस्।"</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"तपाईंले अर्को पटक एक्सेसिबिलिटी बटनमा ट्याप गर्दा यो सुविधा खुल्ने छ"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"तपाईंले अर्को पटक यो सर्टकट प्रयोग गर्दा यो सुविधा खुल्ने छ। २ वटा औँलाले स्क्रिनको पुछारबाट माथितिर स्वाइप गर्नुहोस् र तुरुन्तै औँला उठाउनुहोस्।"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"तपाईंले अर्को पटक यो सर्टकट प्रयोग गर्दा यो सुविधा खुल्ने छ। ३ वटा औँलाले स्क्रिनको पुछारबाट माथितिर स्वाइप गर्नुहोस् र तुरुन्तै औँला उठाउनुहोस्।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"म्याग्निफिकेसन"</string>
     <string name="user_switched" msgid="7249833311585228097">"अहिलेको प्रयोगकर्ता <xliff:g id="NAME">%1$s</xliff:g>।"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"स्विच गरेर <xliff:g id="NAME">%1$s</xliff:g> बनाइँदै..."</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"भइरहेको कल"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"आगमन कल जाँचिँदै छ"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"वर्गीकरण नगरिएको"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"प्रवर्धनहरू"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"सोसल मिडिया"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"समाचार"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"सिफारिसहरू"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"तपाईंले यी सूचनाहरूको महत्त्व सेट गर्नुहोस् ।"</string>
     <string name="importance_from_person" msgid="4235804979664465383">"यसमा सङ्लग्न भएका मानिसहरूको कारणले गर्दा यो महत्वपूर्ण छ।"</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"एपसम्बन्धी आफ्नो रोजाइअनुसारको सूचना"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"सहज पहुँचका लागि स्क्रिनमा राखिने सर्टकट छान्ने मेनु"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"पहुँचको सर्टकट"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"सूचना कक्ष खारेज गर्नुहोस्"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"मेनु"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"मिडिया प्ले/पज"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad को माथिको बटन"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad को तलको बटन"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad को बायाँको बटन"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"यसले काम गर्ने तरिका"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"विचाराधीन..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"फिंगरप्रिन्ट अनलक फेरि सेटअप गर्नुहोस्"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"राम्ररी काम नगरिरहेको हुनाले <xliff:g id="FINGERPRINT">%s</xliff:g> मेटाइएको छ"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"राम्ररी काम नगरिरहेका हुनाले <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> र <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> मेटाइएका छन्"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ले काम गरिरहेको थिएन र त्यसलाई मेटाइयो। फिंगरप्रिन्ट प्रयोग गरी आफ्नो फोन अनलक गर्न त्यसलाई फेरि सेट अप गर्नुहोस्।"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> र <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ले राम्ररी काम गरिरहेका थिएनन् र तिनलाई मेटाइयो। फिंगरप्रिन्ट प्रयोग गरी आफ्नो फोन अनलक गर्न तिनलाई फेरि सेट अप गर्नुहोस्।"</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> अब पहिचान गर्न सकिँदैन।"</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> र <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> अब पहिचान गर्न सकिँदैन।"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> अब पहिचान गर्न सकिँदैन। फिंगरप्रिन्ट अनलक फेरि सेटअप गर्नुहोस्।"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> र <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> अब पहिचान गर्न सकिँदैन। फिंगरप्रिन्ट अनलक फेरि सेटअप गर्नुहोस्।"</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"फेस अनलक फेरि सेटअप गर्नुहोस्"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"तपाईंको फेस मोडेलले राम्ररी काम गरिरहेको थिएन र त्यसलाई मेटाइयो। अनुहार प्रयोग गरी आफ्नो फोन अनलक गर्न फेस मोडेल फेरि सेट अप गर्नुहोस्।"</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"तपाईंको फेस मोडेल अब पहिचान गर्न सकिँदैन। फेस अनलक फेरि सेटअप गर्नुहोस्।"</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"सेटअप गर्नुहोस्"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"अहिले होइन"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> का निम्ति अलार्म"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"प्रयोगकर्ता बदल्नुहोस्"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"म्युट गर्नुहोस्"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"साउन्ड म्युट गर्न ट्याप गर्नुहोस्"</string>
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index b1b3060..e557d59 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecteer deze optie om draadloze foutopsporing uit te zetten."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test harness-modus staat aan"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Reset de fabrieksinstellingen om de test harness-modus uit te zetten."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Seriële console staat aan"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Dit is van invloed op de prestaties. Controleer de bootloader om dit uit te zetten."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Experimentele MTE aangezet"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> staat aan."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> staat uit."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Laat de volumeknoppen los. Als je <xliff:g id="SERVICE_NAME">%1$s</xliff:g> wilt aanzetten, houd je beide volumeknoppen weer 3 seconden ingedrukt."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Kies een functie om te gebruiken als je op de knop Toegankelijkheid tikt:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Kies een functie om te gebruiken met het toegankelijkheidsgebaar (met twee vingers omhoog swipen vanaf de onderkant van het scherm):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Kies een functie om te gebruiken met het toegankelijkheidsgebaar (met drie vingers omhoog swipen vanaf de onderkant van het scherm):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Tik op de knop Toegankelijkheid en houd deze vast om tussen functies te schakelen."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Swipe met twee vingers omhoog en houd vast om tussen functies te schakelen."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Swipe met drie vingers omhoog en houd vast om tussen functies te schakelen."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"De functie opent de volgende keer dat je op de knop Toegankelijkheid tikt"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"De functie opent de volgende keer dat je deze snelkoppeling gebruikt. Swipe met 2 vingers omhoog vanaf de onderkant van je scherm en laat snel los."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"De functie opent de volgende keer dat je deze snelkoppeling gebruikt. Swipe met 3 vingers omhoog vanaf de onderkant van je scherm en laat snel los."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Vergroting"</string>
     <string name="user_switched" msgid="7249833311585228097">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Overschakelen naar <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Actief gesprek"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Een inkomend gesprek screenen"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Geen categorie"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoties"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Sociaal"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Nieuws"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Aanbevelingen"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Je stelt het belang van deze meldingen in."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Dit is belangrijk vanwege de betrokken mensen."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Aangepaste app-melding"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Kiezer voor snelkoppeling voor toegankelijkheid op scherm"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Snelkoppeling voor toegankelijkheid"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Meldingenpaneel sluiten"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media afspelen/onderbreken"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"D-pad omhoog"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"D-pad omlaag"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"D-pad links"</string>
@@ -2411,19 +2424,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Privégedeelte"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"Content van gevoelige meldingen verborgen"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"App-content verborgen voor scherm delen vanwege beveiligingsrisico\'s"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Vanwege beveiligingsrisico\'s is app-content verborgen voor scherm delen"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"Automatisch verbonden met satelliet"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Je kunt berichten sturen en krijgen zonder een mobiel of wifi-netwerk"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Berichten openen"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Hoe het werkt"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"In behandeling…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Ontgrendelen met vingerafdruk weer instellen"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> werkte niet goed en is verwijderd"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> werkten niet goed en zijn verwijderd"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> werkte niet goed en is verwijderd. Stel deze opnieuw in om de telefoon met je vingerafdruk te ontgrendelen."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> werkten niet goed en zijn verwijderd. Stel ze opnieuw in om de telefoon met je vingerafdruk te ontgrendelen."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> wordt niet meer herkend."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> worden niet meer herkend."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> wordt niet meer herkend. Stel Ontgrendelen met vingerafdruk opnieuw in."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> en <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> worden niet meer herkend. Stel Ontgrendelen met vingerafdruk opnieuw in."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Ontgrendelen via gezichtsherkenning weer instellen"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Je gezichtsmodel werkte niet goed en is verwijderd. Stel het opnieuw in om de telefoon met je gezicht te ontgrendelen."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Je gezichtsmodel wordt niet meer herkend. Stel Ontgrendelen via gezichtsherkenning opnieuw in."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Instellen"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Niet nu"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Wekker voor <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Gebruiker wijzigen"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Geluid uitzetten"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tik om het geluid uit te zetten"</string>
 </resources>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index b56c114..211d0ae 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ୱାୟାରଲେସ୍ ଡିବଗିଂକୁ ଅକ୍ଷମ କରିବା ପାଇଁ ଚୟନ କରନ୍ତୁ।"</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ଟେଷ୍ଟ ହାର୍ନେସ୍ ମୋଡ୍ ସକ୍ଷମ ଅଛି"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ଟେଷ୍ଟ ହାର୍‌ନେସ୍ ମୋଡ୍ ଅକ୍ଷମ କରିବାକୁ ଏକ ଫ୍ୟାକ୍ଟରୀ ରିସେଟ୍ କରନ୍ତୁ।"</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"କ୍ରମିକ କନ୍‍‍ସୋଲ୍‍କୁ ସକ୍ଷମ କରାଯାଇଛି"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"କାର୍ଯ୍ୟଦକ୍ଷତା ପ୍ରଭାବିତ ହୋଇଛି। ଅକ୍ଷମ କରିବା ପାଇଁ, ବୁଟ୍‌ଲୋଡର୍‍ର ଯାଞ୍ଚ କରନ୍ତୁ।"</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"ପରୀକ୍ଷାମୂଳକ MTEକୁ ସକ୍ଷମ କରାଯାଇଛି"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ଭଲ୍ୟୁମ୍ କୀ\'ଗୁଡ଼ିକୁ ଧରି ରଖାଯାଇଛି। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ଚାଲୁ ହୋଇଛି।"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ଭଲ୍ୟୁମ୍ କୀ\'ଗୁଡ଼ିକୁ ଧରି ରଖାଯାଇଛି। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ବନ୍ଦ ହୋଇଛି।"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ଭଲ୍ୟୁମ କୀ\'ଗୁଡ଼ିକୁ ରିଲିଜ କରନ୍ତୁ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g>କୁ ଚାଲୁ କରିବା ପାଇଁ ଉଭୟ ଭଲ୍ୟୁମ କୀ\'କୁ ପୁଣି 3 ସେକେଣ୍ଡ ପାଇଁ ଦବାଇ ଧରି ରଖନ୍ତୁ।"</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ଆପଣ ଆକ୍ସେସିବିଲିଟୀ ବଟନ୍ ଟାପ୍ କରିବା ବେଳେ ଏକ ଫିଚର୍ ବ୍ୟବହାର କରିବାକୁ ବାଛନ୍ତୁ:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ଆକ୍ସେସିବିଲିଟୀ ଜେଶ୍ଚର୍ ସହିତ ବ୍ୟବହାର କରିବାକୁ ଏକ ଫିଚର୍ ବାଛନ୍ତୁ (ଦୁଇଟି ଆଙ୍ଗୁଠିରେ ସ୍କ୍ରିନର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ଆକ୍ସେସିବିଲିଟୀ ଜେଶ୍ଚର୍ ସହିତ ବ୍ୟବହାର କରିବାକୁ ଏକ ଫିଚର୍ ବାଛନ୍ତୁ (ତିନୋଟି ଆଙ୍ଗୁଠିରେ ସ୍କ୍ରିନର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"ଫିଚରଗୁଡ଼ିକ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିବାକୁ ଆକ୍ସେସିବିଲିଟୀ ବଟନ୍ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ।"</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"ଫିଚରଗୁଡ଼ିକ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିବାକୁ ଦୁଇଟି ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ୍ କରି ଧରି ରଖନ୍ତୁ।"</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ଫିଚରଗୁଡ଼ିକ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିବାକୁ, ତିନୋଟି ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ୍ କରି ଧରି ରଖନ୍ତୁ।"</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"ଆପଣ ଆଗାମୀ ଥର ଆକ୍ସେସିବିଲିଟୀ ବଟନରେ ଟାପ କଲେ ଏହି ଫିଚରଟି ଖୋଲିବ"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ଆପଣ ଆଗାମୀ ଥର ଏହି ସର୍ଟକଟକୁ ବ୍ୟବହାର କଲେ ଏହି ଫିଚରଟି ଖୋଲିବ। ଆପଣଙ୍କ ସ୍କ୍ରିନର ନିମ୍ନଭାଗରୁ 2 ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ କରି ଶୀଘ୍ର ରିଲିଜ କରନ୍ତୁ।"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ଆପଣ ଆଗାମୀ ଥର ଏହି ସର୍ଟକଟକୁ ବ୍ୟବହାର କଲେ ଏହି ଫିଚରଟି ଖୋଲିବ। ଆପଣଙ୍କ ସ୍କ୍ରିନର ନିମ୍ନଭାଗରୁ 3 ଆଙ୍ଗୁଠିରେ ଉପରକୁ ସ୍ୱାଇପ କରି ଶୀଘ୍ର ରିଲିଜ କରନ୍ତୁ।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ମେଗ୍ନିଫିକେସନ"</string>
     <string name="user_switched" msgid="7249833311585228097">"ବର୍ତ୍ତମାନର ୟୁଜର୍‌ ହେଉଛନ୍ତି <xliff:g id="NAME">%1$s</xliff:g>।"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>ରେ ସ୍ୱିଚ କରନ୍ତୁ…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"ଚାଲିଥିବା କଲ୍"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"ଏକ ଇନକମିଂ କଲକୁ ସ୍କ୍ରିନ୍ କରୁଛି"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"ଅବର୍ଗୀକୃତ"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ପ୍ରଚାରଗୁଡ଼ିକ"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"ସୋସିଆଲ"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"ନ୍ୟୁଜ"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"ସୁପାରିଶଗୁଡ଼ିକ"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକର ପ୍ରମୁଖତା ଆପଣ ସେଟ୍‍ କରନ୍ତି।"</string>
     <string name="importance_from_person" msgid="4235804979664465383">"ସମ୍ପୃକ୍ତ ଲୋକଙ୍କ କାରଣରୁ ଏହା ଗୁରୁତ୍ୱପୂର୍ଣ୍ଣ ଅଟେ।"</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"କଷ୍ଟମ୍ ଆପ୍ ବିଜ୍ଞପ୍ତି"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ଅନ୍-ସ୍କ୍ରିନ୍ ଆକ୍ସେସିବିଲିଟୀ ସର୍ଟକଟ୍ ବାଛିବା ସୁବିଧା"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ଆକ୍ସେସିବିଲିଟୀ ସର୍ଟକଟ୍"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"ବିଜ୍ଞପ୍ତି ସେଡକୁ ଖାରଜ କରନ୍ତୁ"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"ମେନୁ"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"ମିଡିଆ ପ୍ଲେ କରନ୍ତୁ/ବିରତ କରନ୍ତୁ"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad ଉପର"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad ତଳ"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ବାମ"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ଏହା କିପରି କାମ କରେ"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"ବାକି ଅଛି…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ଫିଙ୍ଗରପ୍ରିଣ୍ଟ ଅନଲକ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ସଠିକ ଭାବେ କାମ କରୁନାହିଁ ଏବଂ ଏହାକୁ ଡିଲିଟ କରାଯାଇଛି"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ଏବଂ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ସଠିକ ଭାବେ କାମ କରୁନାହିଁ ଏବଂ ଏଗୁଡ଼ିକୁ ଡିଲିଟ କରାଯାଇଛି"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ସଠିକ ଭାବେ କାମ କରୁନାହିଁ ଏବଂ ଏହାକୁ ଡିଲିଟ କରାଯାଇଛି। ଟିପଚିହ୍ନ ମାଧ୍ୟମରେ ଆପଣଙ୍କ ଫୋନକୁ ଅନଲକ କରିବାକୁ ଏହାକୁ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ।"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ଏବଂ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ସଠିକ ଭାବେ କାମ କରୁନାହିଁ ଏବଂ ଏଗୁଡ଼ିକୁ ଡିଲିଟ କରାଯାଇଛି। ଆପଣଙ୍କ ଟିପଚିହ୍ନ ମାଧ୍ୟମରେ ଆପଣଙ୍କ ଫୋନକୁ ଅନଲକ କରିବାକୁ ଏଗୁଡ଼ିକୁ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ।"</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>କୁ ଆଉ ଚିହ୍ନଟ କରାଯାଇପାରିବ ନାହିଁ।"</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ଏବଂ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>କୁ ଆଉ ଚିହ୍ନଟ କରାଯାଇପାରିବ ନାହିଁ।"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g>କୁ ଆଉ ଚିହ୍ନଟ କରାଯାଇପାରିବ ନାହିଁ। ଫିଙ୍ଗରପ୍ରିଣ୍ଟ ଅନଲକ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ।"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ଏବଂ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>କୁ ଆଉ ଚିହ୍ନଟ କରାଯାଇପାରିବ ନାହିଁ। ଫିଙ୍ଗରପ୍ରିଣ୍ଟ ଅନଲକ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ।"</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"ଫେସ୍ ଅନଲକ୍ ପୁଣି ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ଆପଣଙ୍କ ଫେସ ମଡେଲ ସଠିକ ଭାବେ କାମ କରୁନାହିଁ ଏବଂ ଏହାକୁ ଡିଲିଟ କରାଯାଇଛି। ଫେସ ମାଧ୍ୟମରେ ଆପଣଙ୍କ ଫୋନକୁ ଅନଲକ କରିବାକୁ ଏହାକୁ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ।"</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"ଆପଣଙ୍କ ଫେସ ମଡେଲକୁ ଆଉ ଚିହ୍ନଟ କରାଯାଇପାରିବ ନାହିଁ। ଫେସ ଅନଲକ ପୁଣି ସେଟ ଅପ କରନ୍ତୁ।"</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ସେଟ ଅପ କରନ୍ତୁ"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ବର୍ତ୍ତମାନ ନୁହେଁ"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>ଙ୍କ ପାଇଁ ଆଲାରାମ"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ୟୁଜରଙ୍କୁ ସ୍ୱିଚ କରନ୍ତୁ"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ମ୍ୟୁଟ କରନ୍ତୁ"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ସାଉଣ୍ଡ ମ୍ୟୁଟ କରିବାକୁ ଟାପ କରନ୍ତୁ"</string>
 </resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 72598d1..76ddb42 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"ਵਾਇਰਲੈੱਸ ਡੀਬੱਗਿੰਗ ਨੂੰ ਬੰਦ ਕਰਨ ਲਈ ਚੁਣੋ।"</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ਟੈਸਟ ਹਾਰਨੈੱਸ ਮੋਡ ਚਾਲੂ ਹੈ"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ਟੈਸਟ ਹਾਰਨੈੱਸ ਮੋਡ ਬੰਦ ਕਰਨ ਲਈ ਫੈਕਟਰੀ ਰੀਸੈੱਟ ਕਰੋ।"</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"ਸੀਰੀਅਲ ਕੰਸੋਲ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"ਕਾਰਗੁਜ਼ਾਰੀ ਪ੍ਰਭਾਵਿਤ ਹੋਈ ਹੈ। ਬੰਦ ਕਰਨ ਲਈ, ਬੂਟਲੋਡਰ ਦੇਖੋ।"</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"ਪ੍ਰਯੋਗਮਈ MTE ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ਅਵਾਜ਼ੀ ਕੁੰਜੀਆਂ ਦਬਾ ਕੇ ਰੱਖੀਆਂ ਗਈਆਂ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ।"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ਅਵਾਜ਼ੀ ਕੁੰਜੀਆਂ ਦਬਾ ਕੇ ਰੱਖੀਆਂ ਗਈਆਂ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ਅਵਾਜ਼ ਕੁੰਜੀਆਂ ਨੂੰ ਛੱਡੋ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਚਾਲੂ ਕਰਨ ਲਈ, ਦੋਵੇਂ ਅਵਾਜ਼ ਕੁੰਜੀਆਂ ਨੂੰ 3 ਸਕਿੰਟਾਂ ਲਈ ਦੁਬਾਰਾ ਦਬਾਈ ਰੱਖੋ।"</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ ਨੂੰ ਟੈਪ ਕੀਤੇ ਜਾਣ \'ਤੇ ਵਰਤਣ ਲਈ ਕੋਈ ਵਿਸ਼ੇਸ਼ਤਾ ਚੁਣੋ:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ਪਹੁੰਚਯੋਗਤਾ ਸੰਕੇਤ ਨਾਲ ਵਰਤਣ ਲਈ ਕੋਈ ਵਿਸ਼ੇਸ਼ਤਾ ਚੁਣੋ (ਦੋ ਉਂਗਲਾਂ ਨਾਲ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ਪਹੁੰਚਯੋਗਤਾ ਸੰਕੇਤ ਨਾਲ ਵਰਤਣ ਲਈ ਕੋਈ ਵਿਸ਼ੇਸ਼ਤਾ ਚੁਣੋ (ਤਿੰਨ ਉਂਗਲਾਂ ਨਾਲ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ, ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ \'ਤੇ ਸਪਰਸ਼ ਕਰਕੇ ਰੱਖੋ।"</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ, ਦੋ ਉਂਗਲਾਂ ਨਾਲ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ।"</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ, ਤਿੰਨ ਉਂਗਲਾਂ ਨਾਲ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ।"</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"ਅਗਲੀ ਵਾਰ ਜਦੋਂ ਤੁਸੀਂ ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ ਨੂੰ ਟੈਪ ਕਰੋਗੇ, ਤਾਂ ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਖੁੱਲ੍ਹ ਜਾਵੇਗੀ"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ਅਗਲੀ ਵਾਰ ਜਦੋਂ ਤੁਸੀਂ ਇਸ ਸ਼ਾਰਟਕੱਟ ਦੀ ਵਰਤੋਂ ਕਰੋਗੇ, ਤਾਂ ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਖੁੱਲ੍ਹ ਜਾਵੇਗੀ। 2 ਉਂਗਲਾਂ ਨਾਲ ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰ ਕੇ ਤੁਰੰਤ ਛੱਡੋ।"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ਅਗਲੀ ਵਾਰ ਜਦੋਂ ਤੁਸੀਂ ਇਸ ਸ਼ਾਰਟਕੱਟ ਦੀ ਵਰਤੋਂ ਕਰੋਗੇ, ਤਾਂ ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਖੁੱਲ੍ਹ ਜਾਵੇਗੀ। 3 ਉਂਗਲਾਂ ਨਾਲ ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰ ਕੇ ਤੁਰੰਤ ਛੱਡੋ।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ਵੱਡਦਰਸ਼ੀਕਰਨ"</string>
     <string name="user_switched" msgid="7249833311585228097">"ਮੌਜੂਦਾ ਉਪਭੋਗਤਾ <xliff:g id="NAME">%1$s</xliff:g>।"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> \'ਤੇ ਸਵਿੱਚ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"ਜਾਰੀ ਕਾਲ"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"ਇਨਕਮਿੰਗ ਕਾਲ ਦੀ ਸਕ੍ਰੀਨਿੰਗ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"ਗੈਰ-ਸ਼੍ਰੇਣੀਕਿਰਤ"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ਪ੍ਰਮੋਸ਼ਨ"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"ਸੋਸ਼ਲ ਐਪਾਂ"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"ਖਬਰਾਂ"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"ਸਿਫ਼ਾਰਸ਼ਾਂ"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"ਤੁਸੀਂ ਇਹਨਾਂ ਸੂਚਨਾਵਾਂ ਦੀ ਮਹੱਤਤਾ ਸੈੱਟ ਕੀਤੀ।"</string>
     <string name="importance_from_person" msgid="4235804979664465383">"ਇਹ ਸ਼ਾਮਲ ਲੋਕਾਂ ਦੇ ਕਾਰਨ ਮਹੱਤਵਪੂਰਨ ਹੈ।"</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"ਵਿਉਂਤੀ ਐਪ ਸੂਚਨਾ"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਸਣ ਵਾਲੇ ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ ਦਾ ਚੋਣਕਾਰ"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ਪਹੁੰਚਯੋਗਤਾ ਸ਼ਾਰਟਕੱਟ"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"ਸੂਚਨਾ ਸ਼ੇਡ ਖਾਰਜ ਕਰੋ"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"ਮੀਨੂ"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"ਮੀਡੀਆ ਚਲਾਓ/ਰੋਕੋ"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad ਦਾ ਉੱਪਰਲਾ ਬਟਨ"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad ਦਾ ਹੇਠਲਾ ਬਟਨ"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ਦਾ ਖੱਬੇ ਪਾਸੇ ਵਾਲਾ ਬਟਨ"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ਇਹ ਕਿਵੇਂ ਕੰਮ ਕਰਦਾ ਹੈ"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"ਵਿਚਾਰ-ਅਧੀਨ..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਅਣਲਾਕ ਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ਚੰਗੀ ਤਰ੍ਹਾਂ ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ ਸੀ ਅਤੇ ਉਸਨੂੰ ਮਿਟਾਇਆ ਗਿਆ ਸੀ"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ਅਤੇ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ਚੰਗੀ ਤਰ੍ਹਾਂ ਕੰਮ ਨਹੀਂ ਕਰ ਰਹੇ ਸਨ ਅਤੇ ਉਨ੍ਹਾਂ ਨੂੰ ਮਿਟਾਇਆ ਗਿਆ ਸੀ"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ਚੰਗੀ ਤਰ੍ਹਾਂ ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ ਸੀ ਅਤੇ ਉਸਨੂੰ ਮਿਟਾਇਆ ਗਿਆ ਸੀ। ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਫਿੰਗਰਪ੍ਰਿੰਟ ਨਾਲ ਅਣਲਾਕ ਕਰਨ ਲਈ ਇਸਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ।"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ਅਤੇ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ਚੰਗੀ ਤਰ੍ਹਾਂ ਕੰਮ ਨਹੀਂ ਕਰ ਰਹੇ ਸੀ ਅਤੇ ਉਨ੍ਹਾਂ ਨੂੰ ਮਿਟਾਇਆ ਗਿਆ ਸੀ। ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਆਪਣੇ ਫਿੰਗਰਪ੍ਰਿੰਟ ਨਾਲ ਅਣਲਾਕ ਕਰਨ ਲਈ ਇਨ੍ਹਾਂ ਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ।"</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> ਦੀ ਹੁਣ ਪਛਾਣ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ਅਤੇ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ਦੀ ਹੁਣ ਪਛਾਣ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> ਦੀ ਹੁਣ ਪਛਾਣ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਫਿੰਗਰਪ੍ਰਿੰਟ ਅਣਲਾਕ ਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ।"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ਅਤੇ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ਦੀ ਹੁਣ ਪਛਾਣ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਫਿੰਗਰਪ੍ਰਿੰਟ ਅਣਲਾਕ ਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ।"</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"ਫ਼ੇਸ ਅਣਲਾਕ ਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ਤੁਹਾਡਾ ਚਿਹਰੇ ਦਾ ਮਾਡਲ ਚੰਗੀ ਤਰ੍ਹਾਂ ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ ਸੀ ਅਤੇ ਉਸਨੂੰ ਮਿਟਾਇਆ ਗਿਆ ਸੀ। ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਚਿਹਰੇ ਨਾਲ ਅਣਲਾਕ ਕਰਨ ਲਈ ਇਸਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ।"</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"ਤੁਹਾਡੇ ਚਿਹਰੇ ਦੇ ਮਾਡਲ ਦੀ ਹੁਣ ਪਛਾਣ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ। ਫ਼ੇਸ ਅਣਲਾਕ ਦਾ ਦੁਬਾਰਾ ਸੈੱਟਅੱਪ ਕਰੋ।"</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ਸੈੱਟਅੱਪ ਕਰੋ"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ਹੁਣੇ ਨਹੀਂ"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> ਲਈ ਅਲਾਰਮ"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"ਵਰਤੋਂਕਾਰ ਬਦਲੋ"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ਮਿਊਟ ਕਰੋ"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ਧੁਨੀ ਮਿਊਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index f19b0d0..81e5bf2 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -163,7 +163,7 @@
     <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Połączono z szyfrowaną siecią <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string>
     <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Połączenie przy użyciu karty SIM w sieci <xliff:g id="NETWORK_NAME">%1$s</xliff:g> jest teraz bezpieczniejsze"</string>
     <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"Połączono z niezaszyfrowaną siecią"</string>
-    <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Gdy korzystasz z karty SIM w sieci <xliff:g id="NETWORK_NAME">%1$s</xliff:g>, połączenia, wiadomości i dane są bardziej narażone na ataki"</string>
+    <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"Gdy korzystasz z karty SIM w sieci <xliff:g id="NETWORK_NAME">%1$s</xliff:g>, połączenia, SMS-y i dane są bardziej narażone na ataki"</string>
     <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"Połączenia, wiadomości i dane są obecnie bardziej podatne na ataki podczas korzystania z karty SIM <xliff:g id="NETWORK_NAME">%1$s</xliff:g>.\n\nGdy połączenie zostanie ponownie zaszyfrowane, otrzymasz kolejne powiadomienie."</string>
     <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"Ustawienia bezpieczeństwa sieci komórkowej"</string>
     <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"Więcej informacji"</string>
@@ -1413,6 +1413,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Wybierz, by wyłączyć debugowanie bezprzewodowe."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Tryb jarzma testowego został włączony"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Przywróć ustawienia fabryczne, by wyłączyć tryb jarzma testowego."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Konsola szeregowa włączona"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Wpływa na wydajność. Aby wyłączyć, sprawdź program rozruchowy."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Włączono eksperymentalne rozszerzenie MTE"</string>
@@ -1757,12 +1761,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została włączona."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została wyłączona."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Zwolnij przyciski głośności. Aby włączyć usługę <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, naciśnij i przytrzymaj oba przyciski głośności przez 3 sekundy."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Wybierz funkcję używaną po kliknięciu przycisku ułatwień dostępu:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Wybierz funkcję, której chcesz używać w przypadku gestu ułatwień dostępu (przesunięcie dwoma palcami w górę od dołu ekranu):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Wybierz funkcję, której chcesz używać w przypadku gestu ułatwień dostępu (przesunięcie trzema palcami w górę od dołu ekranu):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Aby przełączać funkcje, naciśnij i przytrzymaj przycisk ułatwień dostępu."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Aby przełączać funkcje, przesuń dwoma palcami w górę i przytrzymaj."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Aby przełączyć funkcje, przesuń trzema palcami w górę i przytrzymaj."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funkcja otworzy się, gdy następnym razem klikniesz przycisk ułatwień dostępu"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkcja otworzy się, gdy następnym razem użyjesz tego skrótu. Przesuń 2 palcami z dołu ekranu i szybko je unieś."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcja otworzy się, gdy następnym razem użyjesz tego skrótu. Przesuń 3 palcami z dołu ekranu i szybko je unieś."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Powiększenie"</string>
     <string name="user_switched" msgid="7249833311585228097">"Bieżący użytkownik: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Przełączam na użytkownika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1978,6 +1985,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Trwa połączenie"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtruję połączenie przychodzące"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Bez kategorii"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promocje"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Społecznościowe"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Wiadomości"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Rekomendacje"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Ustawiłeś ważność tych powiadomień."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Ta wiadomość jest ważna ze względu na osoby uczestniczące w wątku."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Niestandardowe powiadomienie z aplikacji"</string>
@@ -2194,6 +2205,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Wybierz ekranowy skrót ułatwień dostępu"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Skrót ułatwień dostępu"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Zamknij obszar powiadomień"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Odtwórz/wstrzymaj multimedia"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad – w górę"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad – w dół"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad – w lewo"</string>
@@ -2420,12 +2433,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Jak to działa"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Oczekiwanie…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Skonfiguruj ponownie odblokowywanie odciskiem palca"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Odcisk palca <xliff:g id="FINGERPRINT">%s</xliff:g> nie sprawdzał się dobrze i został usunięty"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Odciski palców <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nie sprawdzały się dobrze i zostały usunięte"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Odcisk palca <xliff:g id="FINGERPRINT">%s</xliff:g> nie sprawdzał się dobrze i został usunięty. Skonfiguruj go ponownie, aby odblokowywać telefon odciskiem palca."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Odciski palca <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nie sprawdzały się dobrze i zostały usunięte. Skonfiguruj je ponownie, aby odblokowywać telefon odciskiem palca."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Ten odcisk palca (<xliff:g id="FINGERPRINT">%s</xliff:g>) nie jest już rozpoznawany."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Te odciski palców (<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>) nie są już rozpoznawane."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Ten odcisk palca (<xliff:g id="FINGERPRINT">%s</xliff:g>) nie jest już rozpoznawany. Skonfiguruj ponownie odblokowywanie odciskiem palca."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Te odciski palców (<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> i <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>) nie są już rozpoznawane. Skonfiguruj ponownie odblokowywanie odciskiem palca."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Skonfiguruj ponownie rozpoznawanie twarzy"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Twój model twarzy nie sprawdzał się dobrze i został usunięty. Skonfiguruj go ponownie, aby odblokowywać telefon za pomocą skanu twarzy."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Model Twojej twarzy nie jest już rozpoznawany. Skonfiguruj ponownie rozpoznawanie twarzy."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Skonfiguruj"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Nie teraz"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm dla: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Przełącz konto"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Wycisz"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Kliknij, aby wyciszyć dźwięk"</string>
 </resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index bc6c99c..c270c1c 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1380,7 +1380,7 @@
     <string name="install_carrier_app_notification_title" msgid="5712723402213090102">"Ativar serviço móvel"</string>
     <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"Baixe o app da operadora para ativar seu novo chip"</string>
     <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Baixe o app <xliff:g id="APP_NAME">%1$s</xliff:g> para ativar seu novo chip"</string>
-    <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Fazer download do app"</string>
+    <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Baixar o app"</string>
     <string name="carrier_app_notification_title" msgid="5815477368072060250">"Novo chip inserido"</string>
     <string name="carrier_app_notification_text" msgid="6567057546341958637">"Toque para configurar"</string>
     <string name="time_picker_dialog_title" msgid="9053376764985220821">"Definir hora"</string>
@@ -1412,6 +1412,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecione para desativar a depuração por Wi-Fi."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modo Arcabouço de testes ativado"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Realize uma redefinição para configuração original para desativar o modo Arcabouço de testes."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Console serial ativado"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"O desempenho foi impactado. Para desativar, verifique o carregador de inicialização."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"MTE experimental ativada"</string>
@@ -1756,12 +1760,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Solte as teclas de volume. Para ativar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, toque e pressione as duas teclas de volume por três segundos."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Escolha um recurso a ser usado quando você toca no botão de acessibilidade:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Escolha um recurso para usar com o gesto de acessibilidade (deslizar de baixo para cima na tela com dois dedos):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Escolha um recurso para usar com o gesto de acessibilidade (deslizar de baixo para cima na tela com três dedos):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Para alternar entre recursos, toque no botão de acessibilidade e mantenha-o pressionado."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Para alternar entre recursos, deslize de baixo para cima na tela com dois dedos, sem soltar."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Para alternar entre recursos, deslize de baixo para cima na tela com três dedos, sem soltar."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"O recurso será aberto na próxima vez que você tocar no botão de acessibilidade"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"O recurso será aberto na próxima vez que você usar este atalho. Deslize com 2 dedos de baixo para cima na tela e solte rapidamente."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"O recurso será aberto na próxima vez que você usar este atalho. Deslize com 3 dedos de baixo para cima na tela e solte rapidamente."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliação"</string>
     <string name="user_switched" msgid="7249833311585228097">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Mudando para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1984,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chamada em andamento"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando uma ligação recebida"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Sem classificação"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoções"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Notícias"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recomendações"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Você definiu a importância dessas notificações."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Isso é importante por causa das pessoas envolvidas."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificação personalizada do app"</string>
@@ -2193,6 +2204,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Seletor de atalho de acessibilidade na tela"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Atalho de acessibilidade"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Dispensar aba de notificações"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Tocar/pausar mídia"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Botão direcional: para cima"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Botão direcional: para baixo"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Botão direcional: para a esquerda"</string>
@@ -2412,19 +2425,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espaço privado"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"Conteúdo de notificação sensível oculto"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conteúdo do app oculto no compartilhamento de tela por motivos de segurança"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conteúdo oculto no compartilhamento de tela por segurança"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"Conectado automaticamente ao satélite"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Você pode enviar e receber mensagens sem um dispositivo móvel ou uma rede Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir o app Mensagens"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurar o Desbloqueio por impressão digital de novo"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não estava funcionando bem e foi excluída"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não estavam funcionando bem e foram excluídas"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não estava funcionando bem e foi excluída. Configure de novo para desbloquear o smartphone com a impressão digital."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não estavam funcionando bem e foram excluídas. Configure de novo para desbloquear o smartphone com a impressão digital."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não é mais reconhecida."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não são mais reconhecidas."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não é mais reconhecida. Configure o \"Desbloqueio por impressão digital\" de novo."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não são mais reconhecidas. Configure o \"Desbloqueio por impressão digital\" de novo."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Configure o Desbloqueio facial de novo"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Seu modelo de rosto não estava funcionando bem e foi excluído. Configure de novo para desbloquear o smartphone com o rosto."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Seu modelo de rosto não é mais reconhecido. Configure o \"Desbloqueio facial\" de novo."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configuração"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Agora não"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarme para <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Trocar usuário"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Desativar som"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Toque para silenciar"</string>
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 5cf49fbd..cf07ea8 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -663,7 +663,7 @@
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Moveu o dedo demasiado lentamente. Tente novamente."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Experimente outra impressão digital"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Está demasiado claro"</string>
-    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Detetou-se que o botão ligar/desligar foi premido"</string>
+    <string name="fingerprint_acquired_power_press" msgid="3107864151278434961">"Detetou-se que o botão ligar/desligar foi pressionado"</string>
     <string name="fingerprint_acquired_try_adjusting" msgid="3667006071003809364">"Experimente ajustar"</string>
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Altere a posição do seu dedo ligeiramente de cada vez"</string>
   <string-array name="fingerprint_acquired_vendor">
@@ -686,7 +686,7 @@
     <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Este dispositivo não tem sensor de impressões digitais."</string>
     <string name="fingerprint_error_security_update_required" msgid="8440349108169661934">"Sensor temporariamente desativado"</string>
     <string name="fingerprint_error_bad_calibration" msgid="6770614925736183528">"Não é possível usar o sensor de impressões digitais. Visite um fornecedor de serviços de reparação."</string>
-    <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Botão ligar/desligar premido"</string>
+    <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Botão ligar/desligar pressionado"</string>
     <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 a impressão digital"</string>
     <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Usar o bloqueio de ecrã ou a impressão digital"</string>
@@ -1412,6 +1412,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecione para desativar a depuração sem fios."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modo de estrutura de teste ativado"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Efetue uma reposição de dados de fábrica para desativar o Modo de estrutura de teste."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Consola de série ativada"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"O desempenho é afetado. Para desativar, selecione o carregador de arranque."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"MTE experimental ativada"</string>
@@ -1436,7 +1440,7 @@
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Sobreposição a outras apps"</string>
     <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"A app <xliff:g id="NAME">%s</xliff:g> sobrepõe-se a outras aplicações"</string>
-    <string name="alert_windows_notification_title" msgid="6331662751095228536">"O <xliff:g id="NAME">%s</xliff:g> sobrepõe-se a outras app"</string>
+    <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> sobrepõe-se a outras app"</string>
     <string name="alert_windows_notification_message" msgid="6538171456970725333">"Se não quer 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="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Desativar"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"A verificar o <xliff:g id="NAME">%s</xliff:g>…"</string>
@@ -1756,12 +1760,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas do volume premidas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume premidas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Solte as teclas de volume. Para ativar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, prima sem soltar ambas as teclas de volume novamente durante 3 segundos."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Escolha uma funcionalidade para utilizar quando tocar no botão Acessibilidade:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Escolha a funcionalidade a utilizar com o gesto de acessibilidade (deslize rapidamente com dois dedos para cima a partir da parte inferior do ecrã):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Escolha a funcionalidade a utilizar com o gesto de acessibilidade (deslize rapidamente com três dedos para cima a partir da parte inferior do ecrã):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Para alternar entre funcionalidades, toque sem soltar no botão Acessibilidade."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Para alternar entre funcionalidades, deslize rapidamente com dois dedos para cima sem soltar."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Para alternar entre funcionalidades, deslize rapidamente com três dedos para cima sem soltar."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"A funcionalidade vai ser aberta da próxima vez que tocar no botão Acessibilidade"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"A funcionalidade vai ser aberta da próxima vez que usar este atalho. Deslize com 2 dedos a partir da parte inferior do ecrã e solte rapidamente."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"A funcionalidade vai ser aberta da próxima vez que usar este atalho. Deslize para cima com 3 dedos a partir da parte inferior do ecrã e solte rapidamente."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliação"</string>
     <string name="user_switched" msgid="7249833311585228097">"<xliff:g id="NAME">%1$s</xliff:g> do utilizador atual."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"A mudar para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1984,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chamada em curso"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"A filtrar uma chamada recebida…"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Sem categoria"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoções"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Redes sociais"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Notícias"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recomendações"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Definiu a importância destas notificações."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"É importante devido às pessoas envolvidas."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificação de app personalizada"</string>
@@ -2177,7 +2188,7 @@
     <string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"O Bluetooth continuará ativado durante o modo de avião."</string>
     <string name="car_loading_profile" msgid="8219978381196748070">"A carregar…"</string>
     <string name="file_count" msgid="3220018595056126969">"{count,plural, =1{{file_name} + # ficheiro}many{{file_name} + # ficheiros}other{{file_name} + # ficheiros}}"</string>
-    <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Não existem pessoas recomendadas com quem partilhar"</string>
+    <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Sem pessoas recomendadas com quem partilhar"</string>
     <string name="chooser_all_apps_button_label" msgid="3230427756238666328">"Lista de aplicações"</string>
     <string name="usb_device_resolve_prompt_warn" msgid="325871329788064199">"Esta app não recebeu autorização de gravação, mas pode capturar áudio através deste dispositivo USB."</string>
     <string name="accessibility_system_action_home_label" msgid="3234748160850301870">"Página inicial"</string>
@@ -2193,6 +2204,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selecionador de atalhos de acessibilidade no ecrã"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Atalho de acessibilidade"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ignorar o painel de notificações"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Reproduzir/pausar multimédia"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Teclado direcional: para cima"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Teclado direcional: para baixo"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Teclado direcional: para a esquerda"</string>
@@ -2419,12 +2432,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configure o Desbloqueio por impressão digital novamente"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"A <xliff:g id="FINGERPRINT">%s</xliff:g> não estava a funcionar bem e foi eliminada"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"A <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não estavam a funcionar bem e foram eliminadas"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"A <xliff:g id="FINGERPRINT">%s</xliff:g> não estava a funcionar bem e foi eliminada. Configure-a novamente para desbloquear o telemóvel com a impressão digital."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"A <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não estavam a funcionar bem e foram eliminadas. Configure-as novamente para desbloquear o telemóvel com a sua impressão digital."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Já não é possível reconhecer <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Já não é possível reconhecer <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Já não é possível reconhecer <xliff:g id="FINGERPRINT">%s</xliff:g>. Configure o Desbloqueio por impressão digital novamente."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Já não é possível reconhecer <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>. Configure o Desbloqueio por impressão digital novamente."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Configure o Desbloqueio facial novamente"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"O seu modelo de rosto não estava a funcionar bem e foi eliminado. Configure-o novamente para desbloquear o telemóvel com o rosto."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Já não é possível reconhecer o seu modelo de rosto. Configure o Desbloqueio facial novamente."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurar"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Agora não"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarme de <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Mudar de utilizador"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Desativar som"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Toque para desativar o som"</string>
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index bc6c99c..c270c1c 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1380,7 +1380,7 @@
     <string name="install_carrier_app_notification_title" msgid="5712723402213090102">"Ativar serviço móvel"</string>
     <string name="install_carrier_app_notification_text" msgid="2781317581274192728">"Baixe o app da operadora para ativar seu novo chip"</string>
     <string name="install_carrier_app_notification_text_app_name" msgid="4086877327264106484">"Baixe o app <xliff:g id="APP_NAME">%1$s</xliff:g> para ativar seu novo chip"</string>
-    <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Fazer download do app"</string>
+    <string name="install_carrier_app_notification_button" msgid="6257740533102594290">"Baixar o app"</string>
     <string name="carrier_app_notification_title" msgid="5815477368072060250">"Novo chip inserido"</string>
     <string name="carrier_app_notification_text" msgid="6567057546341958637">"Toque para configurar"</string>
     <string name="time_picker_dialog_title" msgid="9053376764985220821">"Definir hora"</string>
@@ -1412,6 +1412,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selecione para desativar a depuração por Wi-Fi."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modo Arcabouço de testes ativado"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Realize uma redefinição para configuração original para desativar o modo Arcabouço de testes."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Console serial ativado"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"O desempenho foi impactado. Para desativar, verifique o carregador de inicialização."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"MTE experimental ativada"</string>
@@ -1756,12 +1760,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Solte as teclas de volume. Para ativar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, toque e pressione as duas teclas de volume por três segundos."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Escolha um recurso a ser usado quando você toca no botão de acessibilidade:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Escolha um recurso para usar com o gesto de acessibilidade (deslizar de baixo para cima na tela com dois dedos):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Escolha um recurso para usar com o gesto de acessibilidade (deslizar de baixo para cima na tela com três dedos):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Para alternar entre recursos, toque no botão de acessibilidade e mantenha-o pressionado."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Para alternar entre recursos, deslize de baixo para cima na tela com dois dedos, sem soltar."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Para alternar entre recursos, deslize de baixo para cima na tela com três dedos, sem soltar."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"O recurso será aberto na próxima vez que você tocar no botão de acessibilidade"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"O recurso será aberto na próxima vez que você usar este atalho. Deslize com 2 dedos de baixo para cima na tela e solte rapidamente."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"O recurso será aberto na próxima vez que você usar este atalho. Deslize com 3 dedos de baixo para cima na tela e solte rapidamente."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliação"</string>
     <string name="user_switched" msgid="7249833311585228097">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Mudando para <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1984,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Chamada em andamento"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Filtrando uma ligação recebida"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Sem classificação"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoções"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Notícias"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recomendações"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Você definiu a importância dessas notificações."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Isso é importante por causa das pessoas envolvidas."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificação personalizada do app"</string>
@@ -2193,6 +2204,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Seletor de atalho de acessibilidade na tela"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Atalho de acessibilidade"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Dispensar aba de notificações"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Tocar/pausar mídia"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Botão direcional: para cima"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Botão direcional: para baixo"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Botão direcional: para a esquerda"</string>
@@ -2412,19 +2425,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Espaço privado"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"Conteúdo de notificação sensível oculto"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conteúdo do app oculto no compartilhamento de tela por motivos de segurança"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Conteúdo oculto no compartilhamento de tela por segurança"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"Conectado automaticamente ao satélite"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Você pode enviar e receber mensagens sem um dispositivo móvel ou uma rede Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir o app Mensagens"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Como funciona"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Pendente…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurar o Desbloqueio por impressão digital de novo"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não estava funcionando bem e foi excluída"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não estavam funcionando bem e foram excluídas"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não estava funcionando bem e foi excluída. Configure de novo para desbloquear o smartphone com a impressão digital."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não estavam funcionando bem e foram excluídas. Configure de novo para desbloquear o smartphone com a impressão digital."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não é mais reconhecida."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não são mais reconhecidas."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"A impressão digital <xliff:g id="FINGERPRINT">%s</xliff:g> não é mais reconhecida. Configure o \"Desbloqueio por impressão digital\" de novo."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"As impressões digitais <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> e <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> não são mais reconhecidas. Configure o \"Desbloqueio por impressão digital\" de novo."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Configure o Desbloqueio facial de novo"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Seu modelo de rosto não estava funcionando bem e foi excluído. Configure de novo para desbloquear o smartphone com o rosto."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Seu modelo de rosto não é mais reconhecido. Configure o \"Desbloqueio facial\" de novo."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configuração"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Agora não"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarme para <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Trocar usuário"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Desativar som"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Toque para silenciar"</string>
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index e4a6a07..e490ac5e 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1412,6 +1412,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Selectează pentru a dezactiva remedierea erorilor wireless."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modul Set de testare este activat"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Revino la setările din fabrică pentru a dezactiva modul Set de testare."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Consola din serie este activată"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Performanța este afectată. Pentru a dezactiva, verifică programul bootloader."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"MTE experimentală activată"</string>
@@ -1756,12 +1760,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"S-au apăsat lung tastele de volum. S-a activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"S-au apăsat lung tastele de volum. S-a dezactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Eliberează butoanele de volum. Pentru a activa <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, apasă lung pe ambele butoane de volum timp de trei secunde încă o dată."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Alege o funcție pe care să o folosești când atingi butonul de accesibilitate:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Alege o funcție pe care să o folosești cu gestul de accesibilitate (glisează în sus cu două degete din partea de jos a ecranului):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Alege o funcție pe care să o folosești cu gestul de accesibilitate (glisează în sus cu trei degete din partea de jos a ecranului):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Pentru a comuta între funcții, atinge lung butonul de accesibilitate."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Pentru a comuta între funcții, glisează în sus cu două degete și ține apăsat."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Pentru a comuta între funcții, glisează în sus cu trei degete și ține apăsat."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funcția se va deschide data viitoare când atingi butonul de accesibilitate"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funcția se va deschide data viitoare când folosești această comandă rapidă. Glisează în sus cu două degete din partea de jos a ecranului și ridică-le rapid."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funcția se va deschide data viitoare când folosești această comandă rapidă. Glisează în sus cu trei degete din partea de jos a ecranului și ridică-le rapid."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Mărire"</string>
     <string name="user_switched" msgid="7249833311585228097">"Utilizator curent: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Se comută la <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1984,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Apel în desfășurare"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Se filtrează un apel primit"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Neclasificate"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoțiii"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Rețele sociale"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Știri"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Recomandări"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Tu setezi importanța acestor notificări."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Notificarea este importantă având în vedere persoanele implicate."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Notificare de aplicație personalizată"</string>
@@ -2193,6 +2204,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selector de comenzi rapide de accesibilitate de pe ecran"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Comandă rapidă de accesibilitate"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Închide fereastra de notificări"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Meniu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Redă / întrerupe conținutul media"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad sus"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad jos"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad stânga"</string>
@@ -2419,12 +2432,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cum funcționează"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"În așteptare..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Configurează din nou Deblocarea cu amprenta"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> nu funcționa bine și a fost ștearsă"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> și <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nu funcționau bine și au fost șterse"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> nu funcționa bine și s-a șters. Configureaz-o din nou pentru a-ți debloca telefonul cu amprenta."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> și <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nu funcționau bine și s-au șters. Configurează-le din nou pentru a-ți debloca telefonul cu amprenta."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> nu mai poate fi recunoscută."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> și <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nu mai pot fi recunoscute."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> nu mai poate fi recunoscută. Configurează din nou Deblocarea cu amprenta."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> și <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nu mai pot fi recunoscute. Configurează din nou Deblocarea cu amprenta."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Reconfigurează Deblocarea facială"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Modelul tău facial nu funcționa bine și s-a șters. Configurează-l din nou pentru a-ți debloca telefonul folosindu-ți chipul."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Modelul tău facial nu mai poate fi recunoscut. Configurează din nou Deblocarea facială."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Configurează"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Nu acum"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarmă pentru <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Schimbă utilizatorul"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Dezactivează sunetul"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Atinge pentru a dezactiva sunetul"</string>
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 0e98b3f..923d2b4 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1413,6 +1413,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Нажмите, чтобы отключить отладку по Wi-Fi."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Тестовый режим включен"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Чтобы отключить тестовый режим, сбросьте настройки до заводских."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Консоль последовательного порта включена"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Производительность устройства снижена. Чтобы отключить консоль, перейдите в загрузчик операционной системы."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Включена экспериментальная функция MTE"</string>
@@ -1757,12 +1761,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Использован жест с кнопками регулировки громкости. Функция \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" включена."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Использован жест с кнопками регулировки громкости. Функция \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" отключена."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Отпустите кнопки громкости. Чтобы включить <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, нажмите и удерживайте обе кнопки регулировки громкости в течение трех секунд."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Выберите функцию, которая будет запускаться при нажатии кнопки специальных возможностей:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Выберите функцию, которая будет запускаться с помощью жеста (провести по экрану снизу вверх двумя пальцами):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Выберите функцию, которая будет запускаться с помощью жеста (провести по экрану снизу вверх тремя пальцами):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Для переключения между функциями нажмите и удерживайте кнопку специальных возможностей."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Для переключения между функциями проведите по экрану снизу вверх двумя пальцами и задержите их."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Для переключения между функциями проведите по экрану снизу вверх тремя пальцами и задержите их."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Функция теперь будет включаться при нажатии кнопки специальных возможностей."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Функция теперь будет включаться при выполнении действия быстрого запуска. Проведите двумя пальцами по экрану снизу вверх."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Функция теперь будет включаться при выполнении действия быстрого запуска. Проведите тремя пальцами по экрану снизу вверх."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Увеличение"</string>
     <string name="user_switched" msgid="7249833311585228097">"Выбран аккаунт пользователя <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Смена профиля на \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
@@ -1978,6 +1985,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Текущий вызов"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Фильтрация входящего вызова"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Без категории"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Промоакции"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Общение"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Новости"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Рекомендации"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Вы определяете важность этих уведомлений."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Важное (люди)"</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Уведомление пользовательского приложения"</string>
@@ -2194,6 +2205,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Выбор действия для быстрого включения"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Быстрое включение"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Скрыть панель уведомлений"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Меню"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Воспроизведение и пауза"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"D-pad – вверх"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"D-pad – вниз"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"D-pad – влево"</string>
@@ -2413,19 +2426,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Частное пространство"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"Конфиденциальная информация в уведомлении скрыта"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Содержимое приложения исключено из демонстрации экрана в целях безопасности."</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Для безопасности содержимое приложения при демонстрации экрана скрыто."</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"Автоматически подключено к системам спутниковой связи"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Вы можете отправлять и получать сообщения без доступа к мобильной сети или Wi-Fi."</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Открыть Сообщения"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Узнать принцип работы"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Обработка…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Настройте разблокировку по отпечатку пальца заново"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Отпечаток пальца \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" оказался неудачным и был удален."</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Отпечатки пальцев \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" и \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" оказались неудачными и были удалены."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Отпечаток пальца \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" оказался неудачным и был удален. Чтобы использовать разблокировку с помощью отпечатка пальца, настройте ее заново."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Отпечатки пальцев \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" и \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" оказались неудачными и были удалены. Чтобы использовать разблокировку с помощью отпечатка пальца, настройте ее заново."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Отпечаток \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" больше нельзя распознать."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Отпечатки \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" и \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" больше нельзя распознать."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Отпечаток \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" больше нельзя распознать. Настройте разблокировку по отпечатку пальца снова."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Отпечатки \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" и \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" больше нельзя распознать. Настройте разблокировку по отпечатку пальца снова."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Настройте фейсконтроль заново"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Модель лица оказалась неудачной и была удалена. Чтобы пользоваться фейсконтролем, настройте его заново."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Вашу модель лица больше нельзя распознать. Настройте фейсконтроль снова."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Настроить"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не сейчас"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Будильник пользователя <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Сменить пользователя"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Отключить звук"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Нажмите, чтобы отключить звук."</string>
 </resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 03068fe..992f8aa0 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"නොරැහැන් නිදොස්කරණය අබල කිරීමට තෝරන්න."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"පුරක පරීක්‍ෂා ප්‍රකාරය සබලයි"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"පුරක පරීක්‍ෂා ප්‍රකාරය අබල කිරීමට කර්මාන්තශාලා යළි සැකසීමක් ඉටු කරන්න."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"අනුක්‍රමික කොන්සෝලය සබලයි"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"කාර්ය සාධනය බලපෑමට ලක් වී ඇත. අබල කිරීමට, ආරම්භකය පරීක්ෂා කරන්න."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"අත්හදා බැලීමේ MTE සබලයි"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"හඬ පරිමා යතුරු අල්ලා ගන්න <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්‍රියාත්මකයි."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"හඬ පරිමා යතුරු අල්ලා ගන්න <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්‍රියාවිරහිතයි."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"හඬ පරිමා යතුරු මුදා හරින්න. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> සක්‍රීය කිරීමට, හඬ පරිමා යතුරු දෙකම නැවත තත්පර 3ක් ඔබා අල්ලා සිටින්න."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ඔබ ප්‍රවේශ්‍යතා බොත්තම තට්ටු කරන විට භාවිත කිරීමට විශේෂාංගයක් තෝරා ගන්න:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ප්‍රවේශ්‍යතා ඉංගිතය සමඟ භාවිතයට විශේෂාංගයක් තෝරා ගන්න (ඇඟිලි දෙකකින් තිරයේ පහළ සිට ඉහළට ස්වයිප් කරන්න):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ප්‍රවේශ්‍යතා ඉංගිතය සමඟ භාවිතයට විශේෂාංගයක් තෝරා ගන්න (ඇඟිලි තුනකින් තිරයේ පහළ සිට ඉහළට ස්වයිප් කරන්න):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"විශේෂාංග අතර මාරු වීමට, ප්‍රවේශ්‍යතා බොත්තම ස්පර්ශ කර අල්ලාගෙන සිටින්න."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"විශේෂාංග අතර මාරු වීමට, ඇඟිලි දෙකකින් ඉහළට ස්වයිප් කර අල්ලාගෙන සිටින්න."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"විශේෂාංග අතර මාරු වීමට, ඇඟිලි තුනකින් ඉහළට ස්වයිප් කර අල්ලාගෙන සිටින්න."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"මීළඟ වතාවේ ඔබ ප්‍රවේශ්‍යතා බොත්තම තට්ටු කිරීමෙන් විශේෂාංගය විවෘත වේ"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ඔබ මෙම කෙටිමඟ භාවිතා කරන මීළඟ වතාවේ විශේෂාංගය විවෘත වනු ඇත. ඔබේ තිරයෙහි පහළ සිට ඇඟිලි 2කින් ඉහළට ස්වයිප් කර ඉක්මනින් නිදහස් කරන්න."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ඔබ මෙම කෙටිමඟ භාවිතා කරන මීළඟ වතාවේ විශේෂාංගය විවෘත වනු ඇත. ඔබේ තිරයෙහි පහළ සිට ඇඟිලි 3කින් ඉහළට ස්වයිප් කර ඉක්මනින් නිදහස් කරන්න."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"විශාලනය"</string>
     <string name="user_switched" msgid="7249833311585228097">"දැනට සිටින පරිශීලකයා <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> වෙත මාරු කරමින්…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"කරගෙන යන ඇමතුම"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"එන ඇමතුමක් පරීක්ෂා කරන්න"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"වර්ගීකරණය නොකළ"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ප්‍රවර්ධන"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"සමාජයීය"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"පුවත්"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"නිර්දේශ"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"ඔබ මෙම දැනුම්දීම්වල වැදගත්කම සකසා ඇත."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"සම්බන්ධ වූ පුද්ගලයන් නිසා මෙය වැදගත් වේ."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"අභිරුචි යෙදුම් දැනුම් දීම"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"තිරය මත ප්‍රවේශ්‍යතා කෙටිමං තෝරනය"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ප්‍රවේශ්‍යතා කෙටිමඟ"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"දැනුම්දීම් සෙවන ඉවත ලන්න"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"මෙනුව"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"මාධ්‍ය වාදනය/විරාමය"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad ඉහළ"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad පහළ"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad වම"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"එය ක්‍රියා කරන ආකාරය"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"පොරොත්තුයි..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ඇඟිලි සලකුණු අගුලු හැරීම නැවත සකසන්න"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> හොඳින් ක්‍රියා නොකළ අතර එය මකන ලදි"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> සහ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> හොඳින් ක්‍රියා නොකළ අතර ඒවා මකන ලදි"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> හොඳින් ක්‍රියා නොකළේය, එය මකන ලදි ඇඟිලි සලකුණ මගින් ඔබේ දුරකථනය අගුලු හැරීමට එය නැවත සකසන්න."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> සහ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> හොඳින් ක්‍රියා නොකළේය, කාර්යසාධනය දියුණූ කිරීමට ඒවා මකන ලදි. ඔබේ ඇඟිලි සලකුණ මගින් ඔබේ දුරකථනය අගුලු හැරීමට ඒවා නැවත සකසන්න."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> තවදුරටත් හඳුනා ගත නොහැක."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> සහ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> තවදුරටත් හඳුනා ගත නොහැක."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> තවදුරටත් හඳුනා ගත නොහැක. ඇඟිලි සලකුණු අගුළු හැරීම නැවත පිහිටුවන්න."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> සහ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> තවදුරටත් හඳුනා ගත නොහැක. ඇඟිලි සලකුණු අගුළු හැරීම නැවත පිහිටුවන්න."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"මුහුණෙන් අගුලු හැරීම නැවත සකසන්න"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"ඔබේ මුහුණු මාදිලිය හොඳින් ක්‍රියා නොකරයි, එය මකන ලදි. මුහුණ මගින් ඔබේ දුරකථනය අගුලු හැරීමට එය නැවත සකසන්න."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"ඔබේ මුහුණු ආකෘතිය තවදුරටත් හඳුනා ගත නොහැක. මුහුණෙන් අගුළු හැරීම නැවත පිහිටුවන්න."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"සකසන්න"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"දැන් නොවේ"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> සඳහා එලාමය"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"පරිශීලක මාරු කරන්න"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"නිහඬ කරන්න"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ශබ්දය නිශ්ශබ්ද කිරීමට තට්ටු කරන්න"</string>
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 694c55bb..f3154c9 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1200,7 +1200,7 @@
     <string name="low_internal_storage_view_text" msgid="8172166728369697835">"Niektoré systémové funkcie nemusia fungovať"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"V úložisku nie je dostatok voľného miesta pre systém. Zaistite, aby ste mali 250 MB voľného miesta a zariadenie reštartujte."</string>
     <string name="app_running_notification_title" msgid="8985999749231486569">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> je spustená"</string>
-    <string name="app_running_notification_text" msgid="5120815883400228566">"Klepnutím zobrazíte ďalšie informácie alebo zastavíte aplikáciu."</string>
+    <string name="app_running_notification_text" msgid="5120815883400228566">"Klepnutím zobrazíte ďalšie informácie alebo aplikáciu zastavíte."</string>
     <string name="ok" msgid="2646370155170753815">"OK"</string>
     <string name="cancel" msgid="6908697720451760115">"Zrušiť"</string>
     <string name="yes" msgid="9069828999585032361">"OK"</string>
@@ -1413,6 +1413,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Výberom zakážete bezdrôtové ladenie."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Režim správcu testov je aktivovaný"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Ak chcete zakázať režim správcu testov, obnovte výrobné nastavenia."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Sériová konzola je povolená"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Ovplyvňuje výkon. Ak ju chcete zakázať, skontrolujte zavádzací program systému."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Je zapnuté experimentálne rozšírenie MTE"</string>
@@ -1437,7 +1441,7 @@
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Zobrazenie cez iné aplikácie"</string>
     <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> sa zobrazuje cez iné aplikácie"</string>
-    <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> sa zobrazuje cez iné aplikácie"</string>
+    <string name="alert_windows_notification_title" msgid="6331662751095228536">"Aplikácia <xliff:g id="NAME">%s</xliff:g> sa zobrazuje nad inými aplikáciami"</string>
     <string name="alert_windows_notification_message" msgid="6538171456970725333">"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="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Vypnúť"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Kontroluje sa <xliff:g id="NAME">%s</xliff:g>…"</string>
@@ -1757,12 +1761,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vypnutá."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Uvoľnite tlačidlá hlasitosti. Ak chcete zapnúť službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, znova pridržte tri sekundy obe tlačidlá hlasitosti."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Klepnutím na tlačidlo dostupnosti vyberte požadovanú funkciu:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Vyberte funkciu, ktorú chcete používať s daným gestom dostupnosti (potiahnutím dvoma prstami z dolnej časti obrazovky nahor):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Vyberte funkciu aktivovanú daným gestom dostupnosti (potiahnutím troma prstami z dolnej časti obrazovky nahor):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Funkcie prepnete pridržaním tlačidla dostupnosti."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Funkcie prepnete potiahnutím dvoma prstami nahor a pridržaním."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Funkcie prepnete potiahnutím troma prstami nahor a pridržaním."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Táto funkcia sa otvorí, keď nabudúce klepnete na tlačidlo dostupnosti"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Táto funkcia sa otvorí, keď nabudúce použijete túto skratku. Potiahnite zdola obrazovky dvoma prstami nahor a rýchlo uvoľnite."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Táto funkcia sa otvorí, keď nabudúce použijete túto skratku. Potiahnite zdola obrazovky troma prstami nahor a rýchlo uvoľnite."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Zväčšenie"</string>
     <string name="user_switched" msgid="7249833311585228097">"Aktuálny používateľ je <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Prepína sa na účet <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1978,6 +1985,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Prebiehajúci hovor"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Preveruje sa prichádzajúci hovor"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Nekategorizované"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promá"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Sociálne siete"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Správy"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Odporúčania"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Nastavili ste dôležitosť týchto upozornení."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Táto správa je dôležitá vzhľadom na osoby, ktorých sa to týka."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Vlastné upozornenie na aplikáciu"</string>
@@ -2194,6 +2205,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Výber skratky dostupnosti na obrazovke"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Skratka dostupnosti"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Zavrieť panel upozornení"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Ponuka"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Prehrať / pozastaviť médium"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Stlačiť tlačidlo nahor krížového ovládača"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Stlačiť tlačidlo nadol krížového ovládača"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Stlačiť tlačidlo doľava krížového ovládača"</string>
@@ -2413,19 +2426,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"Súkromný priestor"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"Obsah citlivého upozornenia je skrytý"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Obsah aplikácie bol na účely zabezpečenia skrytý v zdieľaní obrazovky"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"Obsah aplikácie je z bezpečnostných dôvodov pri zdieľaní obrazovky skrytý"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"Automaticky pripojené k satelitu"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Správy môžete odosielať a prijímať bez mobilnej siete či siete Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvoriť Správy"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ako to funguje"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Nespracovaná…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Znova nastavte odomknutie odtlačkom prsta"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Odtlačok <xliff:g id="FINGERPRINT">%s</xliff:g> nefungoval správne a bol odstránený"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Odtlačky <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nefungovali správne a boli odstránené"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Odtlačok <xliff:g id="FINGERPRINT">%s</xliff:g> nefungoval správne a bol odstránený. Ak chcete odomykať telefón odtlačkom prsta, nastavte ho znova."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Odtlačky <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nefungovali správne a boli odstránené. Ak chcete odomykať telefón odtlačkom prsta, nastavte ich znova."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> sa už nedari rozpoznať."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> sa už nedari rozpoznať."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> sa už nedari rozpoznať. Znova nastavte odomknutie odtlačkom prsta."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> a <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> sa už nedari rozpoznať. Znova nastavte odomknutie odtlačkom prsta."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Znova nastavte odomknutie tvárou"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Váš model tváre nefungoval správne a bol odstránený. Ak chcete odomykať telefón tvárou, nastavte ho znova."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Váš model tváre sa už nedari rozpoznať. Znova nastavte odomknutie tvárou."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Nastaviť"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Teraz nie"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Budík pre používateľa <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Prepnúť používateľa"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Ignorovať"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Klepnutím vypnite zvuk"</string>
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index edf80c5..8a29452 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1413,6 +1413,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Izberite, če želite onemogočiti brezžično odpravljanje napak."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Način preizkusnega ogrodja je omogočen"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Če želite onemogočiti način preizkusnega ogrodja, ponastavite napravo na tovarniške nastavitve."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Serijska konzola je omogočena"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Učinkovitost delovanja je slabša. Uporabo konzole lahko onemogočite v zagonskem nalagalniku."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Preizkusne razširitve MTE so omogočene"</string>
@@ -1757,12 +1761,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vklopljena."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je izklopljena."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Spustite gumba za glasnost. Če želite vklopiti storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, znova pritisnite in 3 sekunde pridržite oba gumba za glasnost."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Izberite funkcijo, ki jo želite uporabljati, ko se dotaknete gumba za dostopnost:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Izberite funkcijo, ki jo želite zagnati s potezo za dostopnost (vlečenje z dvema prstoma z dna zaslona navzgor):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Izberite funkcijo, ki jo želite zagnati s potezo za dostopnost (vlečenje s tremi prsti z dna zaslona navzgor):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Če želite preklopiti med funkcijami, pridržite gumb za dostopnost."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Če želite preklopiti med funkcijami, z dvema prstoma povlecite navzgor in pridržite."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Če želite preklopiti med funkcijami, s tremi prsti povlecite navzgor in pridržite."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funkcija se bo odprla, ko se boste naslednjič dotaknili gumba za dostopnost"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funkcija se bo odprla, ko boste naslednjič uporabili to bližnjico. Z dvema prstoma povlecite navzgor z dna zaslona in hitro spustite."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcija se bo odprla, ko boste naslednjič uporabili to bližnjico. S tremi prsti povlecite navzgor z dna zaslona in hitro spustite."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Povečava"</string>
     <string name="user_switched" msgid="7249833311585228097">"Trenutni uporabnik <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Preklapljanje na uporabnika <xliff:g id="NAME">%1$s</xliff:g> …"</string>
@@ -1978,6 +1985,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Aktivni klic"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Preverjanje dohodnega klica"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Nekategorizirano"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promocije"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Družbeno"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Novice"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Priporočila"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Vi določite raven pomembnosti teh obvestil."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Pomembno zaradi udeleženih ljudi."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Obvestilo po meri iz aplikacije"</string>
@@ -2194,6 +2205,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Izbirnik zaslonske bližnjice za dostopnost"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Bližnjica za dostopnost"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Opusti zaslon z obvestili"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Meni"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Predvajaj/začasno zaustavi predstavnost"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Smerni gumb gor"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Smerni gumb dol"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Smerni gumb levo"</string>
@@ -2420,12 +2433,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Kako deluje"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"V teku …"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Vnovična nastavitev odklepanja s prstnim odtisom"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ni deloval pravilno in je bil izbrisan"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> in <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nista delovala pravilno in sta bila izbrisana"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> ni deloval pravilno in je bil izbrisan. Znova ga nastavite, če želite telefon odklepati s prstnim odtisom."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> in <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nista delovala pravilno in sta bila izbrisana. Znova ju nastavite, če želite telefon odklepati s prstnim odtisom."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Odtisa »<xliff:g id="FINGERPRINT">%s</xliff:g>« ni več mogoče prepoznati."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Odtisov »<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>« in »<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>« ni več mogoče prepoznati."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Odtisa »<xliff:g id="FINGERPRINT">%s</xliff:g>« ni več mogoče prepoznati. Znova nastavite odklepanje s prstnim odtisom."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Odtisov »<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>« in »<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>« ni več mogoče prepoznati. Znova nastavite odklepanje s prstnim odtisom."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Vnovična nastavitev odklepanja z obrazom"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Model obraza ni deloval pravilno in je bil izbrisan. Znova ga nastavite, če želite telefon odklepati z obrazom."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Vašega modela obraza ni več mogoče prepoznati. Znova nastavite odklepanje z obrazom."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Nastavi"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Ne zdaj"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm za uporabnika <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Preklop uporabnika"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Izklop zvoka"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Dotaknite se za izklop zvoka"</string>
 </resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 88c4987..cba1f08 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Zgjidh për të çaktivizuar korrigjimin përmes Wi-Fi."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Modaliteti i lidhjes së testimit është aktivizuar"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Kryej një rivendosje në cilësimet e fabrikës për të çaktivizuar \"Modalitetin e lidhjes së testimit\"."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Paneli komandues i serisë është aktivizuar"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Ndikohet cilësia e funksionimit. Për ta çaktivizuar, kontrollo ngarkuesin e sistemit."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"MTE eksperimentale u aktivizua"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tastet e volumit të mbajtura shtypur. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> i aktivizuar."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tastet e volumit të mbajtura shtypur. U çaktivizua \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lësho tastet e volumit. Për të aktivizuar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, shtyp dhe mbaj shtypur të dy tastet e volumit sërish për 3 sekonda."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Zgjidh një funksion për ta përdorur kur troket butonin e qasshmërisë:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Zgjidh një veçori për ta përdorur me gjestin e qasshmërisë (rrëshqit shpejt lart nga fundi i ekranit me dy gishta):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Zgjidh një veçori për ta përdorur me gjestin e qasshmërisë (rrëshqit shpejt lart nga fundi i ekranit me tre gishta):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Për të kaluar mes veçorive, prek dhe mbaj prekur butonin e qasshmërisë."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Për të kaluar mes veçorive, rrëshqit shpejt lart me dy gishta dhe mbaje prekur."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Për të kaluar mes veçorive, rrëshqit shpejt lart me tre gishta dhe mbaje prekur."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Veçoria do të hapet herën tjetër kur të trokasësh te butoni i qasshmërisë"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Veçoria do të hapet herën tjetër kur të përdorësh këtë shkurtore. Rrëshqit shpejt lart me 2 gishta nga fundi i ekranit dhe lëshoje me shpejtësi."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Veçoria do të hapet herën tjetër kur të përdorësh këtë shkurtore. Rrëshqit shpejt lart me 3 gishta nga fundi i ekranit dhe lëshoje me shpejtësi."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Zmadhimi"</string>
     <string name="user_switched" msgid="7249833311585228097">"Emri i përdoruesit aktual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Po kalon në \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Telefonatë në vazhdim"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Po filtron një telefonatë hyrëse"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"E pakategorizuara"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promovime"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Sociale"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Lajme"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Rekomandime"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Ke caktuar rëndësinë e këtyre njoftimeve."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Është i rëndësishëm për shkak të personave të përfshirë."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Njoftim i personalizuar për aplikacionin"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Zgjedhësi i shkurtores së qasshmërisë në ekran"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Shkurtorja e qasshmërisë"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Hiq \"Strehën e njoftimeve\""</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menyja"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Luaj/vendos në pauzë median"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Lart në bllokun e drejtimit"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Poshtë në bllokun e drejtimit"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Majtas në bllokun e drejtimit"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Si funksionon"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Në pritje..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfiguro përsëri \"Shkyçjen me gjurmën e gishtit\""</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> nuk po funksiononte mirë dhe u fshi"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dhe <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nuk po funksiononin mirë dhe u fshinë"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> nuk po funksiononte mirë dhe u fshi. Konfiguroje përsëri për ta shkyçur telefonin tënd me gjurmën e gishtit."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dhe <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nuk po funksiononin mirë dhe u fshinë. Konfiguroji përsëri për ta shkyçur telefonin tënd me gjurmën e gishtit."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> nuk mund të njihet më."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dhe <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nuk mund të njihen më."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> nuk mund të njihet më. Konfiguro përsëri \"Shkyçjen me gjurmën e gishtit\"."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> dhe <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nuk mund të njihen më. Konfiguro përsëri \"Shkyçjen me gjurmën e gishtit\"."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Konfiguro \"Shkyçjen me fytyrë\" përsëri"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Modeli yt i fytyrës nuk po funksiononte mirë dhe u fshi. Konfiguroje përsëri për ta shkyçur telefonin tënd me fytyrën."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Modeli yt i fytyrës nuk mund të njihet më. Konfiguro \"Shkyçjen me fytyrë\" përsëri."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Konfiguro"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Jo tani"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarmi për <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Ndërro përdoruesin"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Hiqi zërin"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Trokit për t\'i hequr zërin"</string>
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index f620246..afb8e6b 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -517,11 +517,11 @@
     <string name="permlab_activityRecognition" msgid="1782303296053990884">"препознавање физичких активности"</string>
     <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Ова апликација може да препозна физичке активности."</string>
     <string name="permlab_camera" msgid="6320282492904119413">"снимање фотографија и видеа"</string>
-    <string name="permdesc_camera" msgid="5240801376168647151">"Ова апликација може да снима слике и видео снимке помоћу камере док се апликација користи."</string>
-    <string name="permlab_backgroundCamera" msgid="7549917926079731681">"да снима слике и видео снимке у позадини"</string>
+    <string name="permdesc_camera" msgid="5240801376168647151">"Ова апликација може да снима слике и видео помоћу камере док се апликација користи."</string>
+    <string name="permlab_backgroundCamera" msgid="7549917926079731681">"да снима слике и видео у позадини"</string>
     <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Ова апликација може да снима фотографије и видео снимке помоћу камере у било ком тренутку."</string>
     <string name="permlab_systemCamera" msgid="3642917457796210580">"Дозволите некој апликацији или услузи да приступа камерама система да би снимала слике и видео снимке"</string>
-    <string name="permdesc_systemCamera" msgid="5938360914419175986">"Ова привилегована системска апликација може да снима слике и видео снимке помоћу камере система у било ком тренутку. Апликација треба да има и дозволу android.permission.CAMERA"</string>
+    <string name="permdesc_systemCamera" msgid="5938360914419175986">"Ова привилегована системска апликација може да снима слике и видео помоћу камере система у било ком тренутку. Апликација треба да има и дозволу android.permission.CAMERA"</string>
     <string name="permlab_cameraOpenCloseListener" msgid="5548732769068109315">"Дозволите апликацији или услузи да добија повратне позиве о отварању или затварању уређаја са камером."</string>
     <string name="permdesc_cameraOpenCloseListener" msgid="2002636131008772908">"Ова апликација може да добија повратне позиве када се било који уређај са камером отвара или затвара (помоћу неке апликације)."</string>
     <string name="permlab_cameraHeadlessSystemUser" msgid="680194666834500050">"Дозволите апликацији или услузи да приступа камери као корисник система без графичког корисничког интерфејса."</string>
@@ -1412,6 +1412,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Изаберите да бисте онемогућили бежично отклањање грешака."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Омогућен је режим пробног коришћења"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Обавите ресетовање на фабричка подешавања да бисте онемогућили режим пробног коришћења."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Серијска конзола је омогућена"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Перформансе су смањене. Да бисте онемогући конзолу, проверите покретачки програм."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Експериментални MTE је омогућен"</string>
@@ -1756,12 +1760,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је укључена."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је искључена."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Пустите тастере за јачину звука. Да бисте укључили <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, поново притисните и задржите оба тастера за јачину звука 3 секунде."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Изаберите функцију која ће се користити када додирнете дугме Приступачност:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Одаберите функцију која ће се користити помоћу покрета за приступачност (помоћу два прста превуците нагоре од дна екрана):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Одаберите функцију која ће се користити помоћу покрета за приступачност (помоћу три прста превуците нагоре од дна екрана):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Да бисте прелазили са једне функције на другу, додирните и задржите дугме Приступачност."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Да бисте прелазили са једне функције на другу, превуците нагоре помоћу два прста и задржите."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Да бисте прелазили са једне функције на другу, превуците нагоре помоћу три прста и задржите."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Функција ће се отворити када следећи пут додирнете дугме Приступачност"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Функција ће се отворити када следећи пут будете користили ову пречицу. Превуците нагоре од дна екрана са 2 прста и брзо пустите."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Функција ће се отворити када следећи пут будете користили ову пречицу. Превуците нагоре од дна екрана са 3 прста и брзо пустите."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Увећање"</string>
     <string name="user_switched" msgid="7249833311585228097">"Актуелни корисник <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Пребацивање на <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1977,6 +1984,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Позив је у току"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Проверава се долазни позив"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Некатегоризовано"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Промоције"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Друштвене мреже"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Вести"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Препоруке"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Ви подешавате важност ових обавештења."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Ово је важно због људи који учествују."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Прилагођено обавештење о апликацији"</string>
@@ -2193,6 +2204,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Алатка за бирање пречица за приступачност на екрану"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Пречица за приступачност"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Одбаци траку са обавештењима"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Мени"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Пусти/паузирај медије"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"нагоре на D-pad-у"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"надоле на D-pad-у"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"налево на D-pad-у"</string>
@@ -2419,12 +2432,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Принцип рада"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"На чекању..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Поново подесите откључавање отиском прста"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> није функционисао и избрисали смо га"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> нису функционисали и избрисали смо их"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> није функционисао и избрисали смо га. Поново га подесите да бисте телефон откључавали отиском прста."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> нису функционисали и избрисали смо их. Поново их подесите да бисте телефон откључавали отиском прста."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> више не може да се препозна."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> више не могу да се препознају."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> више не може да се препозна. Поново подесите откључавање отиском прста."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> и <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> више не могу да се препознају. Поново подесите откључавање отиском прста."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Поново подесите откључавање лицем"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Ваш модел лица није функционисао и избрисали смо га. Поново га подесите да бисте телефон откључавали лицем."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Ваш модел лица више не може да се препозна. Поново подесите откључавање лицем."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Подеси"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не сада"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Аларм за: <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Промени корисника"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Искључи звук"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Додирните да бисте искључили звук"</string>
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 35c4c71..6dee8ea 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Välj för att inaktivera trådlös felsökning."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Läget för testverktyg har aktiverats"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Inaktivera testverktygsläget genom att göra en återställning till standardinställningarna."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Seriekonsolen är aktiverad"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Prestandan påverkas. Inaktivera via starthanteraren."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Experimentell MTE har aktiverats"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volymknapparna har tryckts ned. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> har aktiverats."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volymknapparna har tryckts ned. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> har inaktiverats."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Släpp volymknapparna. Du kan aktivera <xliff:g id="SERVICE_NAME">%1$s</xliff:g> genom att hålla båda volymknapparna nedtryckta i tre sekunder igen."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Välj en funktion som ska användas när du trycker på tillgänglighetsknappen:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Välj en funktion som ska användas med tillgänglighetsrörelsen (svepa uppåt med två fingrar från skärmens nederkant):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Välj en funktion som ska användas med tillgänglighetsrörelsen (svepa uppåt med tre fingrar från skärmens nederkant):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Byt mellan funktionerna genom att trycka länge på tillgänglighetsknappen."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Byt funktion genom att svepa uppåt med två fingrar och hålla kvar dem."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Byt funktion genom att svepa uppåt med tre fingrar och hålla kvar dem."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Funktionen öppnas nästa gång du trycker på tillgänglighetsknappen"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Funktionen öppnas nästa gång du använder kortkommandot. Svep uppåt med två fingrar från skärmens nederkant och släpp snabbt."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funktionen öppnas nästa gång du använder kortkommandot. Svep uppåt med tre fingrar från skärmens nederkant och släpp snabbt."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Förstoring"</string>
     <string name="user_switched" msgid="7249833311585228097">"Nuvarande användare: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Byter till <xliff:g id="NAME">%1$s</xliff:g> …"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Pågående samtal"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Ett inkommande samtal filtreras"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Okategoriserad"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Kampanjer"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Socialt"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Nyheter"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Rekommendationer"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Du anger hur viktiga aviseringarna är."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Detta är viktigt på grund av personerna som deltar."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Anpassad appavisering"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Valfunktion för tillgänglighetsgenväg på skärmen"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Aktivera tillgänglighet snabbt"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Stäng meddelandepanelen"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Meny"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Spela upp/pausa"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Styrkors, upp"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Styrkors, ned"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Styrkors, vänster"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Så fungerar det"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Väntar …"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Konfigurera fingeravtryckslås igen"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> fungerade inte bra och har raderats"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> och <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> fungerade inte bra och har raderats"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> fungerade inte bra och har raderats. Konfigurera det igen för att låsa upp telefonen med fingeravtryck."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> och <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> fungerade inte bra och har raderats. Konfigurera dem igen för att låsa upp telefonen med fingeravtryck."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Det går inte längre att känna igen <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Det går inte längre att känna igen <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> och <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Det går inte längre att känna igen <xliff:g id="FINGERPRINT">%s</xliff:g>. Konfigurera fingeravtryckslås igen."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Det går inte längre att känna igen <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> och <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>. Konfigurera fingeravtryckslås igen."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Konfigurera ansiktslås igen"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Ansiktsmodellen fungerade inte bra och har raderats. Konfigurera den igen för att låsa upp telefonen med ansiktet."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Det går inte längre att känna igen din ansiktsmodell. Konfigurera ansiktslåset på nytt."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Ställ in"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Inte nu"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm för <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Byt användare"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Ljud av"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tryck för att stänga av ljudet"</string>
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index dc19026..05cc4bb 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1318,7 +1318,7 @@
     <string name="volume_call" msgid="7625321655265747433">"Sauti ya simu inayoendelea"</string>
     <string name="volume_bluetooth_call" msgid="2930204618610115061">"Sauti ya simu inayoendelea ya Bluetooth"</string>
     <string name="volume_alarm" msgid="4486241060751798448">"Sauti ya kengele"</string>
-    <string name="volume_notification" msgid="6864412249031660057">"Sauti ya notisi"</string>
+    <string name="volume_notification" msgid="6864412249031660057">"Sauti ya arifa"</string>
     <string name="volume_unknown" msgid="4041914008166576293">"Kiwango"</string>
     <string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Sauti ya Bluetooth"</string>
     <string name="volume_icon_description_ringer" msgid="2187800636867423459">"Sauti ya toni mlio"</string>
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Chagua ili uzime utatuzi usiotumia waya."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Hali ya Muunganisho wa Majaribio imewashwa"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Rejesha mipangilio iliyotoka nayo kiwandani ili uzime hali ya Muunganisho wa Majaribio."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Muunganisho kupitia mlango umewashwa"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Utendaji unaathirika. lli uzime, teua programu ya kuwasha mfumo wa uendeshaji."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Kipengele cha majaribio cha MTE kimeruhusiwa"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Vitufe vya sauti vilivyoshikiliwa. Umewasha <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Vitufe vya sauti vimeshikiliwa. Umezima <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Achilia vitufe vya sauti. Ili uwashe <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, bonyeza na ushikilie tena vitufe vyote vya sauti kwa sekunde 3."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Chagua kipengele utakachotumia ukigusa kitufe cha ufikivu:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Chagua kipengele cha kutumia pamoja na ishara ya ufikivu (telezesha vidole viwili kutoka chini kwenda juu kwenye skrini):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Chagua kipengele cha kutumia pamoja na ishara ya ufikivu (telezesha vidole vitatu kutoka chini kwenda juu kwenye skrini):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Ili ubadilishe kati ya vipengele, gusa na ushikilie kitufe cha zana za ufikivu."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Ili ubadilishe kati ya vipengele, telezesha vidole viwili juu na ushikilie."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Ili ubadilishe kati ya vipengele, telezesha vidole vitatu juu na ushikilie."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Kipengele kitafunguka utakapogusa tena kitufe cha zana za ufikivu"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Kipengele kitafunguka utakapotumia tena njia hii ya mkato. Telezesha vidole 2 kuanzia sehemu ya chini ya skrini yako kwenda juu kisha uachilie haraka."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Kipengele kitafunguka utakapotumia tena njia hii ya mkato. Telezesha vidole 3 kuanzia sehemu ya chini ya skrini yako kwenda juu kisha uachilie haraka."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ukuzaji"</string>
     <string name="user_switched" msgid="7249833311585228097">"Mtumiaji wa sasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Inaenda kwa <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Simu inayoendelea"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Inachuja simu unayopigiwa"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Ambazo aina haijabainishwa"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Matoleo"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Mitandao Jamii"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Habari"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Mapendekezo"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Uliweka mipangilio ya umuhimu wa arifa hizi."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Hii ni muhimu kwa sababu ya watu waliohusika."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Arifa ya programu maalum"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Kichagua Njia ya Mkato ya Ufikivu kwenye Skrini"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Njia ya Mkato ya Ufikivu"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ondoa Sehemu ya Arifa"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menyu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Cheza/Sitisha Maudhui"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Kitufe cha juu cha Dpad"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Kitufe cha chini cha Dpad"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Kitufe cha kushoto cha Dpad"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Utaratibu wake"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Inashughulikiwa..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Weka tena mipangilio ya Kufungua kwa Alama ya Kidole"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Alama ya <xliff:g id="FINGERPRINT">%s</xliff:g> ilikuwa na hitilafu na imefutwa"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Alama za <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> na <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> zilikuwa na hitilafu na zimefutwa"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Alama ya <xliff:g id="FINGERPRINT">%s</xliff:g> ilikuwa na hitilafu na imefutwa. Iweke tena ili ufungue simu yako kwa alama ya kidole."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Alama za <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> na <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> zilikuwa na hitilafu na zimefutwa. Ziweke tena ili ufungue simu yako kwa alama ya kidole."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> haitambuliki tena."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> na <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> havitambuliki tena."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> haitambuliki tena. Weka tena mipangilio ya Kufungua kwa Alama ya Kidole."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> na <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> havitambuliki tena. Weka tena mipangilio ya Kufungua kwa Alama ya Kidole."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Weka tena mipangilio ya Kufungua kwa Uso"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Muundo wako wa uso ulikuwa na hitilafu na umefutwa. Uweke tena ili ufungue simu yako kwa uso."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Muundo wa uso wako hautambuliki tena. Weka tena mipangilio ya Kufungua kwa Uso."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Weka mipangilio"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Si sasa"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"King\'ora cha <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Badilisha mtumiaji"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Zima sauti"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Gusa ili uzime sauti"</string>
 </resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 91ae904..78513d6 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"வைஃபை பிழைதிருத்தத்தை முடக்க தேர்ந்தெடுக்கவும்."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"\'தன்னியக்க சோதனைப்\' பயன்முறை இயக்கப்பட்டது"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"’தன்னியக்க சோதனைப்\' பயன்முறையை முடக்க ஆரம்பநிலைக்கு மீட்டமைக்கவும்."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"சீரியல் கன்சோல் இயக்கப்பட்டது"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"செயல்திறன் பாதிக்கப்பட்டுள்ளது. முடக்குவதற்கு பூட்லோடரைத் தேர்வுசெய்யவும்."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"பரிசோதனை MTE இயக்கப்பட்டது"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ஒலியளவுக்கான விசைகளைப் பிடித்திருந்தீர்கள். <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ஆன் செய்யப்பட்டது."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ஒலியளவுக்கான விசைகளைப் பிடித்திருந்தீர்கள். <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ஆஃப் செய்யப்பட்டது."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ஒலியளவு பட்டன்களை அழுத்துவதை நிறுத்துங்கள். <xliff:g id="SERVICE_NAME">%1$s</xliff:g> சேவையை இயக்க, ஒலியளவு பட்டன்கள் இரண்டையும் 3 வினாடிகளுக்கு மீண்டும் அழுத்திப் பிடிக்கவும்."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"அணுகல்தன்மை பட்டனைத் தட்டுவதன் மூலம் பயன்படுத்த விரும்பும் அம்சத்தைத் தேர்ந்தெடுக்கவும்:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"அணுகல்தன்மை சைகைக்கான அம்சத்தைத் தேர்வுசெய்யவும் (இரண்டு விரல்களால் திரையின் கீழிருந்து மேல் நோக்கி ஸ்வைப் செய்யவும்):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"அணுகல்தன்மை சைகைக்கான அம்சத்தைத் தேர்வுசெய்யவும் (மூன்று விரல்களால் திரையின் கீழிருந்து மேல் நோக்கி ஸ்வைப் செய்யவும்):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"அம்சங்களுக்கு இடையே மாற அணுகல்தன்மை பட்டனைத் தொட்டுப் பிடித்திருக்கவும்."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"அம்சங்களுக்கு இடையே மாற இரண்டு விரல்களால் மேல்நோக்கி ஸ்வைப் செய்து பிடித்திருக்கவும்."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"அம்சங்களுக்கு இடையே மாற மூன்று விரல்களால் மேல்நோக்கி ஸ்வைப் செய்து பிடித்திருக்கவும்."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"அடுத்த முறை மாற்றுத்திறன் பட்டனை நீங்கள் தட்டும்போது அம்சம் திறக்கும்"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"அடுத்த முறை இந்த ஷார்ட்கட்டை நீங்கள் பயன்படுத்தும்போது அம்சம் திறக்கும். 2 விரல்களால் திரையின் கீழிருந்து மேல்நோக்கி ஸ்வைப் செய்து விரைவாக விரல்களை எடுக்கவும்."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"அடுத்த முறை இந்த ஷார்ட்கட்டை நீங்கள் பயன்படுத்தும்போது அம்சம் திறக்கும். 3 விரல்களால் திரையின் கீழிருந்து மேல்நோக்கி ஸ்வைப் செய்து விரைவாக விரல்களை எடுக்கவும்."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"பெரிதாக்கல்"</string>
     <string name="user_switched" msgid="7249833311585228097">"நடப்பு பயனர் <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g>க்கு மாறுகிறது…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"செயலில் இருக்கும் அழைப்பு"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"உள்வரும் அழைப்பை மதிப்பாய்வு செய்கிறது"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"வகைப்படுத்தப்படாதவை"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"சலுகைகள்"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"சமூகம்"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"செய்திகள்"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"பரிந்துரைகள்"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"இந்த அறிவிப்புகளின் முக்கியத்துவத்தை அமைத்துள்ளீர்கள்."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"ஈடுபட்டுள்ளவர்களின் காரணமாக, இது முக்கியமானது."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"பிரத்தியேக ஆப்ஸ் அறிவிப்பு"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"திரையிலுள்ள அணுகல்தன்மை ஷார்ட்கட்டிற்கான தேர்வி"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"அணுகல்தன்மை ஷார்ட்கட்"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"அறிவிப்பு விவரத்தை நிராகரி"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"மெனு"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"மீடியாவை இயக்குதல்/இடைநிறுத்துதல்"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"மேல் திசை காட்டும் பட்டன்"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"கீழ் திசை காட்டும் பட்டன்"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"இடது திசை காட்டும் பட்டன்"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"இது செயல்படும் விதம்"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"நிலுவையிலுள்ளது..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"கைரேகை அன்லாக் அம்சத்தை மீண்டும் அமையுங்கள்"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> சரியாகச் செயல்படவில்லை என்பதால் அது நீக்கப்பட்டது"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> மற்றும் <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> சரியாகச் செயல்படவில்லை என்பதால் அவை நீக்கப்பட்டன"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> சரியாகச் செயல்படவில்லை என்பதால் அது நீக்கபட்டது. கைரேகை மூலம் உங்கள் மொபைலை அன்லாக் செய்ய அதை மீண்டும் அமையுங்கள்."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> மற்றும் <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> சரியாகச் செயல்படவில்லை என்பதால் அவை நீக்கப்பட்டன. கைரேகை மூலம் உங்கள் மொபைலை அன்லாக் செய்ய அவற்றை மீண்டும் அமையுங்கள்."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>ஐ இனி அடையாளம் காண முடியாது."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ஆகியவற்றை இனி அடையாளம் காண முடியாது."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g>ஐ இனி அடையாளம் காண முடியாது. கைரேகை அன்லாக் அம்சத்தை மீண்டும் அமையுங்கள்."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ஆகியவற்றை இனி அடையாளம் காண முடியாது. கைரேகை அன்லாக் அம்சத்தை மீண்டும் அமையுங்கள்."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"\'முகம் காட்டித் திறத்தல்\' அம்சத்தை மீண்டும் அமையுங்கள்"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"உங்கள் முகத் தோற்றப் பதிவு சரியாகச் செயல்படவில்லை என்பதால் அது நீக்கப்பட்டது. உங்கள் முகத்தைப் பயன்படுத்தி மொபைலை அன்லாக் செய்ய அதை மீண்டும் அமையுங்கள்."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"உங்கள் முகத் தோற்றப் பதிவை இனி அடையாளம் காண முடியாது. முகம் காட்டித் திறத்தல் அம்சத்தை மீண்டும் அமையுங்கள்."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"அமை"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"இப்போது வேண்டாம்"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>க்கான அலாரம்"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"பயனரை மாற்றுங்கள்"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ஒலியடக்கு"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"ஒலியடக்க தட்டவும்"</string>
 </resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 759c6e6..5f55515 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"వైర్‌లెస్ డీబగ్గింగ్‌ను డిజేబుల్ చేయడానికి ఎంచుకోండి."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"పరీక్ష నియంత్రణ మోడ్ ప్రారంభించబడింది"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"పరీక్ష నియంత్రణ మోడ్‌ను నిలిపివేయడానికి ఫ్యాక్టరీ రీసెట్‍‌ను అమలు చేయండి."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"సీరియల్ కన్సోల్ ప్రారంభించబడింది"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"పని తీరు ప్రభావితమైంది. నిలిపివేయడానికి, బూట్‌లోడర్‌ను చెక్ చేయండి."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"ప్రయోగాత్మక MTE ఎనేబుల్ చేయబడింది"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆన్ చేయబడింది"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆఫ్ చేయబడింది"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"వాల్యూమ్ కీలను రిలీజ్ చేయండి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>‌ను ఆన్ చేయడానికి, రెండు వాల్యూమ్ కీలను మళ్లీ 3 సెకన్ల పాటు నొక్కి పట్టుకోండి."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"యాక్సెస్ సామర్థ్య బటన్‌ను మీరు నొక్కినప్పుడు ఉపయోగించాల్సిన ఒక ఫీచర్‌ను ఎంచుకోండి:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"యాక్సెసిబిలిటీ సంజ్ఞతో ఉపయోగించడానికి ఒక ఫీచర్‌ని ఎంచుకోండి (రెండు వేళ్లతో స్క్రీన్‌ను కింద నుండి పైకి స్వైప్ చేయండి):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"యాక్సెసిబిలిటీ సంజ్ఞతో ఉపయోగించడానికి ఒక ఫీచర్‌ను ఎంచుకోండి (మూడు చేతి వేళ్లతో స్క్రీన్‌ను కింద నుండి పైకి స్వైప్ చేయండి):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"ఫీచర్ల మధ్య మారడానికి, యాక్సెసిబిలిటీ బటన్‌ను నొక్కి &amp; పట్టుకోండి."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"ఫీచర్ల మధ్య మారడానికి, రెండు చేతి వేళ్ళతో పైకి స్వైప్ చేసి పట్టుకోండి."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"ఫీచర్ల మధ్య మారడానికి, మూడు చేతి వేళ్ళతో పైకి స్వైప్ చేసి పట్టుకోండి."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"తర్వాతిసారి మీరు యాక్సెసిబిలిటీ బటన్‌ను ట్యాప్ చేసినప్పుడు ఈ ఫీచర్ తెరుచుకుంటుంది"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"తర్వాతిసారి మీరు ఈ షార్ట్‌కట్‌ను ఉపయోగించినప్పుడు ఈ ఫీచర్ తెరుచుకుంటుంది. మీ స్క్రీన్ దిగువ నుండి 2 వేళ్లతో పైకి స్వైప్ చేసి, వెంటనే వదలండి."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"తర్వాతిసారి మీరు ఈ షార్ట్‌కట్‌ను ఉపయోగించినప్పుడు ఈ ఫీచర్ తెరుచుకుంటుంది. మీ స్క్రీన్ దిగువ నుండి 3 వేళ్లతో పైకి స్వైప్ చేసి, వెంటనే వదలండి."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"మ్యాగ్నిఫికేషన్"</string>
     <string name="user_switched" msgid="7249833311585228097">"ప్రస్తుత వినియోగదారు <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> యూజర్‌కు స్విచ్ అవుతోంది…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"కాల్ కొనసాగుతోంది"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"ఇన్‌కమింగ్ కాల్‌ను స్క్రీన్ చేయండి"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"వర్గీకరించబడలేదు"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"ప్రమోషన్లు"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"సామాజికం"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"వార్తలు"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"సిఫార్సులు"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"మీరు ఈ నోటిఫికేషన్‌ల ప్రాముఖ్యతను సెట్ చేశారు."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"ఇందులో పేర్కొనబడిన వ్యక్తులను బట్టి ఇది చాలా ముఖ్యమైనది."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"అనుకూల యాప్ నోటిఫికేషన్"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"స్క్రీన్‌పై ఉండే యాక్సెసిబిలిటీ షార్ట్‌కట్‌ల ఎంపిక సాధనం"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"యాక్సెసిబిలిటీ షార్ట్‌కట్"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"నోటిఫికేషన్ తెరను తీసివేయండి"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"మెనూ"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"మీడియాను ప్లే/పాజ్ చేయండి"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad పైకి"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad కింద"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ఎడమవైపున"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"ఇది ఎలా పని చేస్తుంది"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"పెండింగ్‌లో ఉంది..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"వేలిముద్ర అన్‌లాక్‌ను మళ్లీ సెటప్ చేయండి"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> సరిగ్గా పని చేయడం లేదు, తొలగించబడింది"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> బాగా పని చేయడం లేదు, తొలగించబడ్డాయి"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> సరిగ్గా పని చేయడం లేదు, తొలగించబడింది. వేలిముద్రతో మీ ఫోన్‌ను అన్‌లాక్ చేయడానికి దాన్ని మళ్లీ సెటప్ చేయండి."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> బాగా పని చేయడం లేదు, తొలగించబడ్డాయి. మీ వేలిముద్రతో మీ ఫోన్‌ను అన్‌లాక్ చేయడానికి వాటిని మళ్లీ సెటప్ చేయండి."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g>‌ను ఇకపై గుర్తించడం సాధ్యం కాదు."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>‌లను ఇకపై గుర్తించడం సాధ్యం కాదు."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g>‌ను ఇకపై గుర్తించడం సాధ్యం కాదు. వేలిముద్ర అన్‌లాక్‌ను మళ్లీ సెటప్ చేయండి."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>, <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>‌లను ఇకపై గుర్తించడం సాధ్యం కాదు. వేలిముద్ర అన్‌లాక్‌ను మళ్లీ సెటప్ చేయండి."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"ఫేస్ అన్‌లాక్‌ను మళ్లీ సెటప్ చేయండి"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"మీ ఫేస్ మోడల్ సరిగ్గా పని చేయడం లేదు, తొలగించబడింది. ఫేస్‌తో మీ ఫోన్‌ను అన్‌లాక్ చేయడానికి దాన్ని మళ్లీ సెటప్ చేయండి."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"మీ ఫేస్ మోడల్‌ను ఇకపై గుర్తించడం సాధ్యం కాదు. ఫేస్ అన్‌లాక్‌ను మళ్లీ సెటప్ చేయండి."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"సెటప్ చేయండి"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ఇప్పుడు కాదు"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> కోసం అలారం"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"యూజర్‌ను మార్చండి"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"మ్యూట్ చేయండి"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"సౌండ్‌ను మ్యూట్ చేయడానికి ట్యాప్ చేయండి"</string>
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 282f66e..358b38a 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"เลือกเพื่อปิดใช้การแก้ไขข้อบกพร่องผ่าน Wi-Fi"</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"โหมดโปรแกรมทดสอบอัตโนมัติเปิดใช้อยู่"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"รีเซ็ตเป็นค่าเริ่มต้นเพื่อปิดใช้โหมดโปรแกรมทดสอบอัตโนมัติ"</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"เปิดใช้คอนโซลการเรียงอันดับแล้ว"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"ประสิทธิภาพได้รับผลกระทบ ตรวจสอบ Bootloader เพื่อปิดใช้งาน"</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"เปิดใช้ MTE เชิงทดสอบอยู่"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"กดปุ่มปรับระดับเสียงค้างไว้แล้ว เปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"กดปุ่มปรับระดับเสียงค้างไว้แล้ว ปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ปล่อยปุ่มปรับระดับเสียง หากต้องการเปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ให้กดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มค้างไว้อีกครั้งเป็นเวลา 3 วินาที"</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"เลือกฟีเจอร์ที่จะใช้เมื่อคุณแตะปุ่มการช่วยเหลือพิเศษดังต่อไปนี้"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"เลือกฟีเจอร์ที่จะใช้กับท่าทางสัมผัสการช่วยเหลือพิเศษ (ใช้ 2 นิ้วเลื่อนขึ้นจากด้านล่างของหน้าจอ) ดังต่อไปนี้"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"เลือกฟีเจอร์ที่จะใช้กับท่าทางสัมผัสการช่วยเหลือพิเศษ (ใช้ 3 นิ้วเลื่อนขึ้นจากด้านล่างของหน้าจอ) ดังต่อไปนี้"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"หากต้องการสลับระหว่างฟีเจอร์ต่างๆ ให้แตะปุ่มการช่วยเหลือพิเศษค้างไว้"</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"หากต้องการสลับระหว่างฟีเจอร์ต่างๆ ให้ใช้ 2 นิ้วเลื่อนขึ้นแล้วค้างไว้"</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"หากต้องการสลับระหว่างฟีเจอร์ต่างๆ ให้ใช้ 3 นิ้วเลื่อนขึ้นแล้วค้างไว้"</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"ฟีเจอร์นี้จะเปิดขึ้นในครั้งถัดไปที่คุณแตะปุ่มการช่วยเหลือพิเศษ"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"ฟีเจอร์นี้จะเปิดขึ้นในครั้งถัดไปที่คุณใช้ทางลัดนี้ ใช้ 2 นิ้วปัดขึ้นจากด้านล่างของหน้าจอและปล่อยอย่างรวดเร็ว"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"ฟีเจอร์นี้จะเปิดขึ้นในครั้งถัดไปที่คุณใช้ทางลัดนี้ ใช้ 3 นิ้วปัดขึ้นจากด้านล่างของหน้าจอและปล่อยอย่างรวดเร็ว"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"การขยาย"</string>
     <string name="user_switched" msgid="7249833311585228097">"ผู้ใช้ปัจจุบัน <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"กำลังเปลี่ยนเป็น<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"สายที่สนทนาอยู่"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"กำลังสกรีนสายเรียกเข้า"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"ไม่จัดอยู่ในหมวดหมู่ใดๆ"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"โปรโมชัน"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"โซเชียล"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"ข่าว"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"การแนะนำ"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"คุณตั้งค่าความสำคัญของการแจ้งเตือนเหล่านี้"</string>
     <string name="importance_from_person" msgid="4235804979664465383">"ข้อความนี้สำคัญเนื่องจากบุคคลที่เกี่ยวข้อง"</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"การแจ้งเตือนที่กำหนดเองของแอป"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"ตัวเลือกทางลัดการช่วยเหลือพิเศษบนหน้าจอ"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ทางลัดการช่วยเหลือพิเศษ"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"ปิดหน้าต่างแจ้งเตือน"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"เมนู"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"เล่น/หยุดสื่อชั่วคราว"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad ขึ้น"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad ลง"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad ซ้าย"</string>
@@ -2411,19 +2424,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"พื้นที่ส่วนตัว"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"เนื้อหาการแจ้งเตือนที่ละเอียดอ่อนซ่อนอยู่"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ซ่อนเนื้อหาแอปจากการแชร์หน้าจอเพื่อความปลอดภัย"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"ซ่อนเนื้อหาแอปจากการแชร์หน้าจอแล้วเพื่อความปลอดภัย"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"เชื่อมต่อกับดาวเทียมโดยอัตโนมัติ"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"คุณรับส่งข้อความผ่านดาวเทียมได้โดยไม่ต้องใช้เครือข่ายมือถือหรือ Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"เปิด Messages"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"วิธีการทำงาน"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"รอดำเนินการ..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"ตั้งค่าการปลดล็อกด้วยลายนิ้วมืออีกครั้ง"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> ทำงานได้ไม่ดีและถูกลบออกไปแล้ว"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> และ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ทำงานได้ไม่ดีและถูกลบออกไปแล้ว"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g>ทำงานได้ไม่ดีและถูกลบออกไปแล้ว ตั้งค่าอีกครั้งเพื่อปลดล็อกโทรศัพท์ด้วยลายนิ้วมือ"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> และ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ทำงานได้ไม่ดีและถูกลบออกไปแล้ว ตั้งค่าอีกครั้งเพื่อปลดล็อกโทรศัพท์ด้วยลายนิ้วมือ"</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"ระบบไม่จดจำ <xliff:g id="FINGERPRINT">%s</xliff:g> อีกต่อไป"</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"ระบบไม่จดจำ <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> และ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> อีกต่อไป"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"ระบบไม่จดจำ <xliff:g id="FINGERPRINT">%s</xliff:g> อีกต่อไป ตั้งค่าการปลดล็อกด้วยลายนิ้วมืออีกครั้ง"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"ระบบไม่จดจำ <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> และ <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> อีกต่อไป ตั้งค่าการปลดล็อกด้วยลายนิ้วมืออีกครั้ง"</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"ตั้งค่าการปลดล็อกด้วยใบหน้าอีกครั้ง"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"รูปแบบใบหน้าของคุณทำงานได้ไม่ดีและถูกลบออกไปแล้ว ตั้งค่าอีกครั้งเพื่อปลดล็อกโทรศัพท์ด้วยใบหน้า"</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"ระบบไม่จดจำรูปแบบใบหน้าของคุณอีกต่อไป ตั้งค่าการปลดล็อกด้วยใบหน้าอีกครั้ง"</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"ตั้งค่า"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ไว้ทีหลัง"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"นาฬิกาปลุกสำหรับ <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"สลับผู้ใช้"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"ปิดเสียง"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"แตะเพื่อปิดเสียง"</string>
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 31b81aa..2d88801 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Piliin para i-disable ang wireless na pag-debug."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Naka-enable ang Test Harness Mode"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Mag-factory reset para i-disable ang Test Harness Mode."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Naka-enable ang serial console"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Naaapektuhan ang performance. Para i-disable, lagyan ng check ang bootloader."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Na-enable ang Pang-eksperimentong MTE"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pinindot nang matagal ang volume keys. Na-on ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pinindot nang matagal ang volume keys. Na-off ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Bitawan ang mga volume key. Para i-on ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, muling pindutin nang matagal ang dalawang volume key sa loob ng 3 segundo."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Pumili ng feature na gagana sa pamamagitan ng pag-tap mo sa button ng accessibility:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Pumili ng feature na gagana sa pamamagitan ng galaw ng accessibility (pag-swipe pataas mula sa ibaba ng screen gamit ang dalawang daliri):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Pumili ng feature na gagana sa pamamagitan ng galaw ng accessibility (pag-swipe pataas mula sa ibaba ng screen gamit ang tatlong daliri):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Para magpalipat-lipat sa mga feature, pindutin nang matagal ang button ng accessibility."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Para magpalipat-lipat sa mga feature, mag-swipe pataas gamit ang dalawang daliri at i-hold ito."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Para magpalipat-lipat sa mga feature, mag-swipe pataas gamit ang tatlong daliri at i-hold ito."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Magbubukas ang feature sa susunod na i-tap mo ang button ng accessibility"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Magbubukas ang feature sa susunod na gamitin mo ang shortcut na ito. Mag-swipe pataas gamit ang 2 daliri mula sa ibaba ng iyong screen at mabilis na i-release."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Magbubukas ang feature sa susunod na gamitin mo ang shortcut na ito. Mag-swipe pataas gamit ang 3 daliri mula sa ibaba ng iyong screen at mabilis na i-release."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Pag-magnify"</string>
     <string name="user_switched" msgid="7249833311585228097">"Kasalukuyang user <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Lumilipat kay <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Kasalukuyang tawag"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Nagsi-screen ng papasok na tawag"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Di-nakategorya"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Mga Promosyon"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Social"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Balita"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Mga Rekomendasyon"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Ikaw ang magtatakda sa kahalagahan ng mga notification na ito."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Mahalaga ito dahil sa mga taong kasangkot."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Custom na notification ng app"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Tagapili ng Shortcut ng Accessibility sa Screen"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Shortcut ng Accessibility"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"I-dismiss ang Notification Shade"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"I-Play/I-Pause ang Media"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad Up"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad Down"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad Left"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Paano ito gumagana"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Nakabinbin..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"I-set up ulit ang Pag-unlock Gamit ang Fingerprint"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Hindi gumagana nang maayos ang <xliff:g id="FINGERPRINT">%s</xliff:g> at na-delete ito"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Hindi gumagana nang maayos ang <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> at <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> at na-delete ang mga ito"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Hindi gumagana nang maayos ang <xliff:g id="FINGERPRINT">%s</xliff:g> at na-delete na ito. I-set up ulit ito para ma-unlock ang iyong telepono sa pamamagitan ng fingerprint."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Hindi gumagana nang maayos ang <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> at <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> at na-delete na ang mga ito. I-set up ulit ang mga ito para ma-unlock ang iyong telepono gamit ang fingerprint mo."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Hindi na makilala ang <xliff:g id="FINGERPRINT">%s</xliff:g>."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Hindi na makilala ang <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> at <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Hindi na makilala ang <xliff:g id="FINGERPRINT">%s</xliff:g>. I-set up ulit ang Pag-unlock Gamit ang Fingerprint."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Hindi na makilala ang <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> at <xliff:g id="FINGERPRINT_1">%2$s</xliff:g>. I-set up ulit ang Pag-unlock Gamit ang Fingerprint."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"I-set up ulit ang Pag-unlock Gamit ang Mukha"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Hindi gumagana nang maayos ang iyong face model at na-delete na ito. I-set up ulit ito para ma-unlock ang iyong telepono sa pamamagitan ng mukha."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Hindi na makilala ang iyong face model. I-set up ulit ang Pag-unlock Gamit ang Mukha."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"I-set up"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Huwag muna"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Alarm para kay <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Magpalit ng user"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"I-mute"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"I-tap para i-mute ang tunog"</string>
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 13f7c2f..d3e61dc 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Kablosuz hata ayıklamayı devre dışı bırakmak için seçin."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Test Bandı Modu etkin"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Test Bandı Modu\'nu devre dışı bırakmak için cihazı fabrika ayarlarına sıfırlayın."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Seri konsol etkinleştirildi"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Performans etkilendi. Devre dışı bırakmak için bootloader\'ı kontrol edin."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Deneysel MTE etkinleştirildi"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> açıldı."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kapatıldı."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Ses seviyesi tuşlarını bırakın. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> hizmetini etkinleştirmek için her iki ses seviyesi tuşuna yeniden basıp 3 saniye boyunca basılı tutun."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Erişilebilirlik düğmesine dokunduğunuzda kullanmak için bir özellik seçin:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Erişilebilirlik hareketiyle (iki parmakla ekranın altından yukarı kaydırma) kullanılacak bir özellik seçin:"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Erişilebilirlik hareketiyle (üç parmakla ekranın altından yukarı kaydırma) kullanılacak bir özellik seçin:"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Özellikler arasında geçiş yapmak için erişilebilirlik düğmesine dokunup basılı tutun."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Özellikler arasında geçiş yapmak için iki parmakla yukarı kaydırıp basılı tutun."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Özellikler arasında geçiş yapmak için üç parmakla yukarı kaydırıp basılı tutun."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Özellik, erişilebilirlik düğmesine bir sonraki dokunuşunuzda açılır."</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Özellik, bu kısayolu bir sonraki kullanışınızda açılır. Ekranın alt kısmından 2 parmağınızla yukarı doğru kaydırın ve hızlıca bırakın."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Özellik, bu kısayolu bir sonraki kullanışınızda açılır. Ekranın alt kısmından 3 parmağınızla yukarı doğru kaydırın ve hızlıca bırakın."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Büyütme"</string>
     <string name="user_switched" msgid="7249833311585228097">"Geçerli kullanıcı: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> adlı kullanıcıya geçiliyor…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Devam eden arama"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Gelen arama süzülüyor"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Kategorize edilmemiş"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promosyonlar"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Sosyal"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Haberler"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Öneriler"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Bu bildirimlerin önem derecesini ayarladınız."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Bu, dahil olan kişiler nedeniyle önemlidir."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Özel uygulama bildirimi"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekran Erişilebilirlik Kısayol Seçici"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Erişilebilirlik Kısayolu"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Bildirim Gölgesini Kapat"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menü"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Medyayı Oynat/Duraklat"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad Yukarı"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad Aşağı"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad Sol"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"İşleyiş şekli"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Bekliyor..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Parmak İzi Kilidi\'ni tekrar kurun"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> iyi çalışmadığı için silindi"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ve <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> iyi çalışmadığı için silindi"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> iyi çalışmadığı için silindi. Telefonunuzun kilidini parmak iziyle açmak için tekrar kurun."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ve <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> iyi çalışmadığı için silindi. Telefonunuzun kilidini parmak izinizle açmak için tekrar kurun."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> artık tanınamayacak."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ve <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> artık tanınamayacak."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> artık tanınamayacak. Parmak İzi Kilidi\'ni tekrar kurun."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> ve <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> artık tanınamayacak. Parmak İzi Kilidi\'ni tekrar kurun."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Yüz Tanıma Kilidi\'ni tekrar kurun"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Yüz modeliniz iyi çalışmadığı için silindi. Telefonunuzun kilidini yüzünüzle açmak için tekrar kurun."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Yüz modeliniz artık tanınamayacak. Yüz Tanıma Kilidi\'ni tekrar kurun."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Ayarla"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Şimdi değil"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> için alarm"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Kullanıcı değiştir"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Sesi kapat"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Sesi kapat düğmesine dokunun"</string>
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index b8764e7..81434c2 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -158,7 +158,7 @@
     <string name="scCellularNetworkSecurityTitle" msgid="7752521808690294384">"Безпека мобільної мережі"</string>
     <string name="scCellularNetworkSecuritySummary" msgid="7042036754550545005">"Шифрування, сповіщення для незашифрованих мереж"</string>
     <string name="scIdentifierDisclosureIssueTitle" msgid="2898888825129970328">"Отримано доступ до ідентифікатора пристрою"</string>
-    <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"О <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> у мережі поблизу зафіксовано унікальний ідентифікатор вашого пристрою (IMSI або IMEI) під час використання вашої SIM-карти <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>"</string>
+    <string name="scIdentifierDisclosureIssueSummaryNotification" msgid="3699930821270580416">"О <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>, коли ви використали SIM-карту <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>, мережа поблизу зафіксувала унікальний ідентифікатор вашого пристрою (IMSI або IMEI)"</string>
     <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"О <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g> у мережі поблизу зафіксовано унікальний ідентифікатор вашого пристрою (IMSI або IMEI) під час використання вашої SIM-карти <xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>.\n\nЦе означає, що було зареєстровано ваше місцезнаходження, дії чи особу. Це звичайна практика, але може виявитися проблемою для людей, для яких важлива конфіденційність."</string>
     <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"Підключено до зашифрованої мережі <xliff:g id="NETWORK_NAME">%1$s</xliff:g>"</string>
     <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"Тепер з’єднання SIM-карти <xliff:g id="NETWORK_NAME">%1$s</xliff:g> краще захищене"</string>
@@ -1413,6 +1413,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Натисніть, щоб вимкнути налагодження."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Увімкнено режим автоматизованого тестування"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Щоб вимкнути режим автоматизованого тестування, відновіть заводські налаштування."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Послідовну консоль увімкнено"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Продуктивність зазнала впливу. Щоб вимкнути, перевірте завантажувач операційної системи."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Експериментальний запуск з MTE ввімкнено"</string>
@@ -1757,12 +1761,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Утримано клавіші гучності. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> увімкнено."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Утримано клавіші гучності. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> вимкнено."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Відпустіть клавіші гучності. Щоб увімкнути сервіс <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, натисніть і втримуйте обидві клавіші гучності протягом 3 секунд."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Виберіть функцію для кнопки спеціальних можливостей:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Виберіть функцію для жесту спеціальних можливостей (проведення двома пальцями знизу вгору):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Виберіть функцію для жесту спеціальних можливостей (проведення трьома пальцями знизу вгору):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Щоб переключитися між функціями, натисніть і утримуйте кнопку спеціальних можливостей."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Щоб переключитися між функціями, проведіть по екрану знизу вгору двома пальцями й утримуйте їх."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Щоб переключитися між функціями, проведіть по екрану знизу вгору трьома пальцями й утримуйте їх."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Функція відкриється, коли ви наступного разу натиснете кнопку функцій доступності"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Функція відкриється, коли ви наступного разу скористаєтеся цією швидкою командою. Проведіть двома пальцями вгору від низу екрана й швидко відпустіть."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Функція відкриється, коли ви наступного разу скористаєтеся цією швидкою командою. Проведіть трьома пальцями вгору від низу екрана й швидко відпустіть."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Збільшення"</string>
     <string name="user_switched" msgid="7249833311585228097">"Поточний користувач: <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Перехід у режим \"<xliff:g id="NAME">%1$s</xliff:g>\"…"</string>
@@ -1978,6 +1985,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Активний виклик"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Вхідний виклик (Фільтр)"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Без категорії"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Промоакції"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Соцмережі"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Новини"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Рекомендації"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Ви вказуєте пріоритет цих сповіщень."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Важливе з огляду на учасників."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Користувацьке сповіщення додатка"</string>
@@ -2194,6 +2205,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Вибір екранного засобу спеціальних можливостей"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Засіб спеціальних можливостей"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Закрити панель сповіщень"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Меню"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Відтворити/призупинити медіаконтент"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Кнопка \"вгору\" панелі керування"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Кнопка \"вниз\" панелі керування"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Кнопка \"вліво\" панелі керування"</string>
@@ -2420,12 +2433,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Як це працює"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Обробка…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Налаштуйте розблокування відбитком пальця повторно"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"Відбиток \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" працював неналежним чином, і його видалено"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"Відбитки \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" і \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" працювали неналежним чином, і їх видалено"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"Відбиток \"<xliff:g id="FINGERPRINT">%s</xliff:g>\" працював неналежним чином, і його видалено. Налаштуйте його ще раз, щоб розблоковувати телефон за допомогою відбитка пальця."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"Відбитки \"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>\" і \"<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>\" працювали неналежним чином, і їх видалено. Налаштуйте їх ще раз, щоб розблоковувати телефон за допомогою відбитка пальця."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Відбиток пальця <xliff:g id="FINGERPRINT">%s</xliff:g> більше не розпізнається."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Відбитки пальців <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> і <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> більше не розпізнаються."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Відбиток пальця <xliff:g id="FINGERPRINT">%s</xliff:g> більше не розпізнається. Налаштуйте розблокування відбитком пальця повторно."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Відбитки пальців <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> і <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> більше не розпізнаються. Налаштуйте розблокування відбитком пальця повторно."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Налаштуйте фейс-контроль повторно"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Модель обличчя працювала неналежним чином, і її видалено. Налаштуйте її ще раз, щоб розблоковувати телефон за допомогою фейс-контролю."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Модель вашого обличчя більше не розпізнається. Налаштуйте фейс-контроль повторно."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Налаштувати"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Не зараз"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Будильник користувача <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Змінити користувача"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Вимкнути звук"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Натисніть, щоб вимкнути звук"</string>
 </resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 1ae5e20..8363933 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"وائرلیس ڈیبگنگ کو غیر فعال کرنے کے ليے منتخب کریں۔"</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"ٹیسٹ ہارنیس موڈ فعال ہے"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"ٹیسٹ ہارنیس موڈ غیر فعال کرنے کے لیے فیکٹری ری سیٹ کریں۔"</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"شمار کونسول فعال ہے"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"کارکردگی پر اثر پڑا ہے۔ غیر فعال کرنے کے ليے، بوٹ لوڈر چیک کریں۔"</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"‏تجرباتی MTE کو فعال کیا گیا"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"والیوم کی کلیدوں کو دبائے رکھا گیا۔ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> آن ہے۔"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"والیوم کی کلیدوں کو دبائے رکھا گیا۔ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> آف ہے۔"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"والیوم کی کلیدوں کو ریلیز کریں <xliff:g id="SERVICE_NAME">%1$s</xliff:g> کو آن کرنے کے لیے، والیوم کی دونوں کلیدوں کو دوبارہ 3 سیکنڈ تک چھوئیں اور دبائے رکھیں۔"</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ایکسیسبیلٹی بٹن پر تھپتھپانے وقت استعمال کرنے کیلئے ایک خصوصیت منتخب کریں:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ایکسیسبیلٹی اشارہ کے ساتھ استعمال کرنے کے لیے ایک خصوصیت چنیں (دو انگلیوں سے اسکرین کے نیچے سے اوپر کی طرف سوائپ کریں):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ایکسیسبیلٹی اشارہ کے ساتھ استعمال کرنے کے لیے ایک خصوصیت چنیں (تین انگلیوں سے اسکرین کے نیچے سے اوپر کی طرف سوائپ کریں):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"خصوصیات کے مابین سوئچ کرنے کے لیے، ایکسیسبیلٹی بٹن کو ٹچ کریں اور دبائے رکھیں۔"</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"خصوصیات کے مابین سوئچ کرنے کے لیے، دو انگلیوں سے اوپر سوائپ کریں اور دبائیں رکھیں۔"</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"خصوصیات کے مابین سوئچ کرنے کے لیے، تین انگلیوں سے اوپر سوائپ کریں اور دبائیں رکھیں۔"</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"اگلی بار جب آپ ایکسیسبیلٹی بٹن پر تھپتھپائیں گے تو خصوصیت کھل جائے گی"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"اگلی بار جب آپ یہ شارٹ کٹ استعمال کریں گے تو خصوصیت کھل جائے گی۔ اپنی اسکرین کے نیچے سے 2 انگلیوں سے اوپر کی طرف سوائپ کریں اور تیزی سے ریلیز کریں۔"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"اگلی بار جب آپ یہ شارٹ کٹ استعمال کریں گے تو خصوصیت کھل جائے گی۔ اپنی اسکرین کے نیچے سے 3 انگلیوں سے اوپر کی طرف سوائپ کریں اور تیزی سے ریلیز کریں۔"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"میگنیفکیشن"</string>
     <string name="user_switched" msgid="7249833311585228097">"موجودہ صارف <xliff:g id="NAME">%1$s</xliff:g>۔"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> پر سوئچ کیا جا رہا ہے…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"جاری کال"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"اِن کمنگ کال کی اسکریننگ"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"غیر زمرہ بند"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"پروموشنز"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"سوشل"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"خبریں"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"تجاویز"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"ان اطلاعات کی اہمیت آپ مقرر کرتے ہیں۔"</string>
     <string name="importance_from_person" msgid="4235804979664465383">"اس میں موجود لوگوں کی وجہ سے یہ اہم ہے۔"</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"حسب ضرورت ایپ کی اطلاع"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"آن اسکرین ایکسیسبیلٹی شارٹ کٹ منتخب کنندہ"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"ایکسیسبیلٹی کا شارٹ کٹ"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"اطلاعاتی شیڈ برخاست کریں"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"مینیو"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"میڈیا چلائیں/موقوف کریں"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"‏Dpad اوپر کریں"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"‏Dpad نیچے کریں"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"‏Dpad بائیں کریں"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"اس کے کام کرنے کا طریقہ"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"زیر التواء..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"فنگر پرنٹ اَن لاک کو دوبارہ سیٹ اپ کریں"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"‫<xliff:g id="FINGERPRINT">%s</xliff:g> اچھی طرح کام نہیں کر رہا تھا اور حذف کر دیا گیا تھا"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"‫<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> اور <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> اچھی طرح کام نہیں کر رہے تھے اور انہیں حذف کر دیا گیا تھا"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> اچھی طرح کام نہیں کر رہا تھا اور حذف کر دیا گیا تھا۔ اپنے فون کو فنگر پرنٹ سے غیر مقفل کرنے کے لیے، اسے دوبارہ سیٹ اپ کریں۔"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> اور <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> اچھی طرح کام نہیں کر رہے تھے اور انہیں حذف کر دیا گیا تھا۔ اپنے فون کو اپنے فنگر پرنٹ سے غیر مقفل کرنے کے لیے انہیں دوبارہ سیٹ اپ کریں۔"</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> مزید پہچانا نہیں جا سکتا۔"</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> اور <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> کو مزید پہچانا نہیں جا سکتا۔"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> مزید پہچانا نہیں جا سکتا۔ فنگر پرنٹ اَن لاک کو دوبارہ سیٹ اپ کریں۔"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> اور <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> کو مزید پہچانا نہیں جا سکتا۔ فنگر پرنٹ اَن لاک کو دوبارہ سیٹ اپ کریں۔"</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"فیس اَن لاک کو دوبارہ سیٹ اپ کریں"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"آپ کے چہرے کا ماڈل اچھی طرح کام نہیں کر رہا تھا اور حذف کر دیا گیا تھا۔ اپنے فون کو چہرے سے غیر مقفل کرنے کے لیے، اسے دوبارہ سیٹ اپ کریں۔"</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"آپ کے چہرے کا ماڈل مزید پہچانا نہیں جا سکتا۔ فیس اَن لاک کو دوبارہ سیٹ اپ کریں۔"</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"سیٹ اپ کریں"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"ابھی نہیں"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> کیلئے الارم"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"صارف سوئچ کریں"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"خاموش کریں"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"آواز کو خاموش کرنے کے لیے تھپتھپائیں"</string>
 </resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 8d6e169..21abada 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Uni faolsizlantirish uchun bosing."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Xavfsizlik sinovi rejimi yoqildi"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Xavfsizlik sinovi rejimini faolsizlantirish uchun zavod sozlamalariga qaytaring."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Ketma-ket port konsoli yoqildi"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Qurilma samaradorligi pasaydi. Konsolni faolsizlantirish uchun operatsion tizim yuklagichini oching."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Tajribaviy MTE yoqildi"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tovush tugmalari bosib turildi. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> yoqildi."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tovush tugmalari bosib turildi. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> faolsizlantirildi."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Tovush tugmalarini qoʻyib yuboring. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> xizmatini yoqish uchun ikkala tovush tugmasini 3 soniya bosib turing."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Qulayliklar tugmasi bosilganda ishga tushadigan funksiyani tanlang:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Qulayliklar ishorasi bilan ishga tushadigan funksiyani tanlang (ikkita barmoq bilan ekranning pastidan tepaga surib tortilganda):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Qulayliklar ishorasi bilan ishga tushadigan funksiyani tanlang (uchta barmoq bilan ekranning pastidan tepaga surib tortilganda):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Funksiyalarni almashtirish uchun maxsus imkoniyatlar tugmasini bosib turing."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Funksiyalarni almashtirish uchun ikkita barmoq bilan tepaga suring va ushlab turing."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Funksiyalarni almashtirish uchun uchta barmoq bilan tepaga suring va ushlab turing."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Keyingi safar qulayliklar tugmasini bosganingizda funksiya ochiladi"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Keyingi safar shu buyruqdan foydalanganingizda funksiya ochiladi. Ekranning pastidan 2 barmoq bilan tepaga suring va darhol qoʻyib yuboring."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Keyingi safar shu buyruqdan foydalanganingizda funksiya ochiladi. Ekranning pastidan 3 barmoq bilan tepaga suring va darhol qoʻyib yuboring."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Kattalashtirish"</string>
     <string name="user_switched" msgid="7249833311585228097">"Joriy foydalanuvchi <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Bunga almashilmoqda: <xliff:g id="NAME">%1$s</xliff:g>"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Joriy chaqiruv"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Kiruvchi chaqiruvni filtrlash"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Turkumlanmagan"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Promoaksiyalar"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Ijtimoiy"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Yangiliklar"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Tavsiyalar"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Siz ushbu bildirishnomalarning muhimligini belgilagansiz."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Bu odamlar siz uchun muhim."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Maxsus ilova bildirishnomasi"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Ekranda tezkor ishga tushirishni tanlagich"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Tezkor ishga tushirish"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Eslatma soyasini yopish"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Menyu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Media ijro/pauza"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad – tepaga"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad – pastga"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad – chapga"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Ishlash tartibi"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Kutilmoqda..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Barmoq izi bilan ochish funksiyasini qayta sozlang"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> yaxshi ishlamadi va oʻchirib tashlandi."</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> va <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> yaxshi ishlamadi va oʻchirib tashlandi."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> yaxshi ishlamadi va oʻchirib tashlandi. Telefonni barmoq izi bilan ochish uchun uni qayta sozlang."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> va <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> yaxshi ishlamadi va oʻchirib tashlandi. Telefonni barmoq izi bilan ochish uchun ularni qayta sozlang."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"<xliff:g id="FINGERPRINT">%s</xliff:g> endi tanilmaydi."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> va <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> endi tanilmaydi."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"<xliff:g id="FINGERPRINT">%s</xliff:g> endi tanilmaydi. Barmoq izi bilan ochishni qayta sozlang."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> va <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> endi tanilmaydi. Barmoq izi bilan ochishni qayta sozlang."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Yuz bilan ochishni qayta sozlash"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Yuzingiz mobeli yaxshi ishlamadi va oʻchirib tashlandi. Telefonni yuz bilan ochish uchun uni qayta sozlang."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Yuzingiz modeli endi tanilmaydi. Yuz bilan ochishni qayta sozlang."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Sozlash"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Hozir emas"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g> uchun signal"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Foydalanuvchini almashtirish"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Ovozsiz qilish"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Tovushsiz qilish uchun bosing"</string>
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 857a095..0141d9d 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Chọn để tắt tính năng gỡ lỗi qua Wi-Fi."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Đã bật Chế độ khai thác kiểm thử"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Khôi phục cài đặt gốc để tắt Chế độ khai thác kiểm thử."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"Đã bật bảng điều khiển cổng nối tiếp"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Hiệu suất sẽ bị ảnh hưởng. Để tắt, hãy chọn trình tải khởi động."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"Đã bật MTE thử nghiệm"</string>
@@ -1435,7 +1439,7 @@
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"Hiển thị trên các ứng dụng khác"</string>
     <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> hiển thị trên các ứng dụng khác"</string>
-    <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> hiển thị trên ứng dụng khác"</string>
+    <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> đang hiện trên các ứng dụng khác"</string>
     <string name="alert_windows_notification_message" msgid="6538171456970725333">"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="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"Tắt"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"Đang kiểm tra <xliff:g id="NAME">%s</xliff:g>…"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bạn đã giữ các phím âm lượng. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> đã bật."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bạn đã giữ các phím âm lượng. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> đã tắt."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Thả phím âm lượng. Để bật <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, hãy nhấn và giữ cả 2 phím âm lượng trong 3 giây một lần nữa."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Chọn một tính năng để dùng khi bạn nhấn nút hỗ trợ tiếp cận:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Chọn một tính năng để dùng với cử chỉ hỗ trợ tiếp cận (dùng 2 ngón tay vuốt lên từ cuối màn hình):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Chọn một tính năng để dùng với cử chỉ hỗ trợ tiếp cận (dùng 3 ngón tay vuốt lên từ cuối màn hình):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Để chuyển đổi giữa các tính năng, hãy chạm và giữ nút hỗ trợ tiếp cận."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Để chuyển đổi giữa các tính năng, hãy dùng 2 ngón tay vuốt lên và giữ."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Để chuyển đổi giữa các tính năng, hãy dùng 3 ngón tay vuốt lên và giữ."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Tính năng này sẽ được mở vào lần tới bạn nhấn nút hỗ trợ tiếp cận"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Tính năng này sẽ được mở vào lần tới bạn dùng lối tắt này. Hãy dùng 2 ngón tay vuốt từ cuối màn hình lên rồi thả tay nhanh."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Tính năng này sẽ được mở vào lần tới bạn dùng lối tắt này. Hãy dùng 3 ngón tay vuốt từ cuối màn hình lên rồi thả tay nhanh."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Phóng to"</string>
     <string name="user_switched" msgid="7249833311585228097">"Người dùng hiện tại <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Đang chuyển sang <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Cuộc gọi đang thực hiện"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Đang sàng lọc cuộc gọi đến"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Chưa được phân loại"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Khuyến mãi"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Mạng xã hội"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Tin tức"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Đề xuất"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Bạn đặt tầm quan trọng của các thông báo này."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Thông báo này quan trọng vì những người có liên quan."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Thông báo tùy chỉnh cho ứng dụng"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Bộ chọn lối tắt hỗ trợ tiếp cận trên màn hình"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Lối tắt hỗ trợ tiếp cận"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Đóng Ngăn thông báo"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Trình đơn"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Phát/Tạm dừng nội dung nghe nhìn"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Chuyển lên trên bằng bàn phím di chuyển"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Chuyển xuống dưới bằng bàn phím di chuyển"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Chuyển sang trái bằng bàn phím di chuyển"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Cách hoạt động"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Đang chờ xử lý..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Thiết lập lại tính năng Mở khoá bằng vân tay"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"<xliff:g id="FINGERPRINT">%s</xliff:g> không dùng được và đã bị xoá"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> và <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> không dùng được và đã bị xoá"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"<xliff:g id="FINGERPRINT">%s</xliff:g> không dùng được và đã bị xoá. Hãy thiết lập lại để mở khoá điện thoại bằng vân tay."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> và <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> không dùng được và đã bị xoá. Hãy thiết lập lại để mở khoá điện thoại bằng vân tay."</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"Không nhận dạng được <xliff:g id="FINGERPRINT">%s</xliff:g> nữa."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"Không nhận dạng được <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> và <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nữa."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"Không nhận dạng được <xliff:g id="FINGERPRINT">%s</xliff:g> nữa. Hãy thiết lập lại tính năng Mở khoá bằng vân tay."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"Không nhận dạng được <xliff:g id="FINGERPRINT_0">%1$s</xliff:g> và <xliff:g id="FINGERPRINT_1">%2$s</xliff:g> nữa. Hãy thiết lập lại tính năng Mở khoá bằng vân tay."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Thiết lập lại tính năng Mở khoá bằng khuôn mặt"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Mẫu khuôn mặt của bạn không dùng được và đã bị xoá. Hãy thiết lập lại để mở khoá điện thoại bằng khuôn mặt."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Không nhận dạng được mẫu khuôn mặt của bạn nữa. Hãy thiết lập lại tính năng Mở khoá bằng khuôn mặt."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Thiết lập"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Để sau"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"Chuông báo cho <xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Chuyển đổi người dùng"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Tắt tiếng"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Nhấn để tắt tiếng"</string>
 </resources>
diff --git a/core/res/res/values-watch/colors.xml b/core/res/res/values-watch/colors.xml
deleted file mode 100644
index e2b7505..0000000
--- a/core/res/res/values-watch/colors.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<!-- Watch specific system colors. -->
-<resources>
-  <color name="system_error_light">#B3261E</color>
-  <color name="system_on_error_light">#FFFFFF</color>
-  <color name="system_error_container_light">#F7DCDA</color>
-  <color name="system_on_error_container_light">#410E0B</color>
-
-  <color name="system_error_dark">#F2B8B5</color>
-  <color name="system_on_error_dark">#601410</color>
-  <color name="system_error_container_dark">#FF8986</color>
-  <color name="system_on_error_container_dark">#410E0B</color>
-
-  <!-- With material deprecation of 'background' in favor of 'surface' we flatten these
-       on watches to match the black background requirements -->
-  <color name="system_surface_dark">#000000</color>
-  <color name="system_surface_dim_dark">#000000</color>
-  <color name="system_surface_bright_dark">#000000</color>
-
-  <!-- Wear flattens the typical 5 container layers to 3; container + high & low -->
-  <color name="system_surface_container_dark">#303030</color>
-  <color name="system_surface_variant_dark">#303030</color>
-  <color name="system_surface_container_high_dark">#474747</color>
-  <color name="system_surface_container_highest_dark">#474747</color>
-  <color name="system_surface_container_low_dark">#252626</color>
-  <color name="system_surface_container_lowest_dark">#252626</color>
-
-</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 6cd89cf..3a7c906 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"选择即可停用无线调试功能。"</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"自动化测试框架模式已启用"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"恢复出厂设置以停用自动化测试框架模式。"</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"已启用序列控制台"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"性能受到影响。要停用,请查看引导加载程序。"</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"已启用实验性 MTE"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已开启。"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已关闭。"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"松开音量键。如要启用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>,请再次同时按住两个音量键 3 秒。"</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"选择点按“无障碍”按钮后要使用的功能:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"选择要搭配无障碍手势(用两根手指从屏幕底部向上滑动)使用的功能:"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"选择要搭配无障碍手势(用三根手指从屏幕底部向上滑动)使用的功能:"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"轻触并按住“无障碍”按钮,即可在多项功能之间切换。"</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"用两根手指向上滑动并按住,即可在多项功能之间切换。"</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"用三根手指向上滑动并按住,即可在多项功能之间切换。"</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"下次点按“无障碍”按钮时,将打开此功能"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"下次使用此快捷手势时,将打开此功能。用 2 根手指从画面底部向上滑动,然后快速松开。"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"下次使用此快捷手势时,将打开此功能。用 3 根手指从画面底部向上滑动,然后快速松开。"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"放大功能"</string>
     <string name="user_switched" msgid="7249833311585228097">"当前用户是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"正在切换为<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"正在通话"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"正在过滤来电"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"未分类"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"促销"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"社交"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"资讯"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"建议"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"这些通知的重要程度由您来设置。"</string>
     <string name="importance_from_person" msgid="4235804979664465383">"这条通知涉及特定的人,因此被归为重要通知。"</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"自定义应用通知"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"屏幕上的无障碍功能快捷方式选择器"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"无障碍功能快捷方式"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"关闭通知栏"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"菜单"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"媒体播放/暂停"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"向上方向键"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"向下方向键"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"向左方向键"</string>
@@ -2411,19 +2424,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"私密空间"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"已隐藏敏感通知内容"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"为安全起见而在屏幕共享画面中处于隐藏状态的应用内容"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"为安全起见,屏幕共享画面已隐藏此应用的内容"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"自动连接到卫星"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"您无需使用移动网络或 WLAN 网络便能收发消息"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"打开“信息”应用"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"运作方式"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"待归档…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"重新设置指纹解锁功能"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"“<xliff:g id="FINGERPRINT">%s</xliff:g>”无法正常使用,已被删除"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"“<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>”和“<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>”无法正常使用,已被删除"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"“<xliff:g id="FINGERPRINT">%s</xliff:g>”无法正常使用,系统已将其删除。如要通过指纹解锁功能来解锁手机,请重新设置。"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"“<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>”和“<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>”无法正常使用,系统已将它们删除。如要通过指纹解锁功能来解锁手机,请重新设置。"</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"系统无法再识别<xliff:g id="FINGERPRINT">%s</xliff:g>。"</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"系统无法再识别<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>和<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>。"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"系统无法再识别<xliff:g id="FINGERPRINT">%s</xliff:g>。请重新设置指纹解锁功能。"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"系统无法再识别<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>和<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>。请重新设置指纹解锁功能。"</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"重新设置“人脸解锁”功能"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"您的脸部模型无法正常使用,系统已将其删除。如要通过人脸解锁功能来解锁手机,请重新设置。"</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"系统无法再识别您的脸部模型。请重新设置人脸解锁功能。"</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"设置"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"以后再说"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>的闹钟"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"切换用户"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"静音"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"点按即可设为静音"</string>
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 5224753..a28efbe 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"選取即可停用無線偵錯功能。"</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"已啟用測試工具模式"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"請將裝置回復原廠設定,以停用測試工具模式。"</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"已啟用序列控制器"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"效能受到影響,勾選啟動程式即可停用。"</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"實驗版 MTE 已啟用"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量鍵。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> 已開啟。"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量鍵。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> 已關閉。"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"鬆開音量鍵。如果要開 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>,請同時㩒住兩個音量鍵 3 秒。"</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"請選擇輕按「無障礙功能」按鈕時使用的功能:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"請選擇要配搭無障礙手勢 (使用兩隻手指從螢幕底部向上滑動) 使用的功能:"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"請選擇要配搭無障礙手勢 (使用三隻手指從螢幕底部向上滑動) 使用的功能:"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"如要在功能之間切換,請按住無障礙功能按鈕。"</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"如要在功能之間切換,請使用兩隻手指向上滑動並按住。"</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"如要在功能之間切換,請使用三隻手指向上滑動並按住。"</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"下次輕按無障礙功能按鈕時,就會開啟此功能"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"下次使用此快速鍵時,就會開啟此功能。請用 2 隻手指從螢幕底部向上滑動並快速放開。"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"下次使用此快速鍵時,就會開啟此功能。請用 3 隻手指從螢幕底部向上滑動並快速放開。"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"放大"</string>
     <string name="user_switched" msgid="7249833311585228097">"目前的使用者是<xliff:g id="NAME">%1$s</xliff:g>。"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"正在切換至<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"通話中"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"正在過濾來電"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"未分類"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"宣傳"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"社交"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"新聞"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"建議"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"你可以設定這些通知的重要性。"</string>
     <string name="importance_from_person" msgid="4235804979664465383">"列為重要的原因:涉及的人。"</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"自訂應用程式通知"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"螢幕無障礙功能捷徑選擇器"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"無障礙功能捷徑"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"關閉通知欄"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"選單"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"媒體播放/暫停"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"十字鍵向上鍵"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"十字鍵向下鍵"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"十字鍵向左鍵"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"運作方式"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"待處理…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"重新設定「指紋解鎖」功能"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"由於「<xliff:g id="FINGERPRINT">%s</xliff:g>」無法正常運作,因此系統已將其刪除"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"由於「<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>」和「<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>」無法正常運作,因此系統已將其刪除。"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"由於「<xliff:g id="FINGERPRINT">%s</xliff:g>」無法正常運作,因此系統已將其刪除。請重新設定,才能使用指紋解鎖手機。"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"由於「<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>」和「<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>」無法正常運作,因此系統已將其刪除。請重新設定,才能使用指紋解鎖手機。"</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"無法再辨識<xliff:g id="FINGERPRINT">%s</xliff:g>。"</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"無法再辨識<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>和<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>。"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"無法再辨識<xliff:g id="FINGERPRINT">%s</xliff:g>。請重新設定「指紋解鎖」功能。"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"無法再辨識<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>和<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>。請重新設定「指紋解鎖」功能。"</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"重新設定「面孔解鎖」功能"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"由於面部模型無法正常運作,因此系統已將其刪除。請重新設定,才能使用面孔解鎖手機。"</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"無法再辨識你的面部模型。請重新設定「面孔解鎖」功能。"</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"設定"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"暫時不要"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>的鬧鐘"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"切換使用者"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"靜音"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"輕按即可靜音"</string>
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index fe66eb9..ed49988 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -160,9 +160,9 @@
     <string name="scIdentifierDisclosureIssueSummary" msgid="7283387338827749276">"在 <xliff:g id="DISCLOSURE_TIME">%1$s</xliff:g>,鄰近網路使用你的「<xliff:g id="DISCLOSURE_NETWORK">%2$s</xliff:g>」SIM 卡時,記錄了你的裝置專屬 ID (IMSI 或 IMEI)。\n\n這代表鄰近網路記錄了你的位置、活動或身分資訊。儘管這種情況很常見,但注重隱私的人可能會認為這是個問題。"</string>
     <string name="scNullCipherIssueEncryptedTitle" msgid="234717016411824969">"已連上加密網路「<xliff:g id="NETWORK_NAME">%1$s</xliff:g>」"</string>
     <string name="scNullCipherIssueEncryptedSummary" msgid="8577510708842150475">"現在連上「<xliff:g id="NETWORK_NAME">%1$s</xliff:g>」SIM 卡更加安全"</string>
-    <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"已連上未加密網路"</string>
-    <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"目前使用「<xliff:g id="NETWORK_NAME">%1$s</xliff:g>」SIM 卡時,通話、訊息和資料較容易受到攻擊"</string>
-    <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"目前使用「<xliff:g id="NETWORK_NAME">%1$s</xliff:g>」SIM 卡時,通話、訊息和資料較容易受到攻擊。\n\n連線再次加密時,你會收到另一則通知。"</string>
+    <string name="scNullCipherIssueNonEncryptedTitle" msgid="3978071464929453915">"連接上未加密網路"</string>
+    <string name="scNullCipherIssueNonEncryptedSummaryNotification" msgid="7386936934128110388">"使用目前的「<xliff:g id="NETWORK_NAME">%1$s</xliff:g>」SIM 卡,通話、訊息和資料較易受到攻擊"</string>
+    <string name="scNullCipherIssueNonEncryptedSummary" msgid="5093428974513703253">"使用目前的「<xliff:g id="NETWORK_NAME">%1$s</xliff:g>」SIM 卡,通話、訊息和資料較易受到攻擊。\n\n連線再次加密時,你會收到另一則通知。"</string>
     <string name="scNullCipherIssueActionSettings" msgid="5888857706424639946">"行動網路安全性設定"</string>
     <string name="scNullCipherIssueActionLearnMore" msgid="7896642417214757769">"瞭解詳情"</string>
     <string name="scNullCipherIssueActionGotIt" msgid="8747796640866585787">"我知道了"</string>
@@ -1197,7 +1197,7 @@
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"儲存空間即將用盡"</string>
     <string name="low_internal_storage_view_text" msgid="8172166728369697835">"部分系統功能可能無法運作"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"系統儲存空間不足。請確定你已釋出 250MB 的可用空間,然後重新啟動。"</string>
-    <string name="app_running_notification_title" msgid="8985999749231486569">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」目前正在執行"</string>
+    <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>
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"選取即可停用無線偵錯功能。"</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"測試控管工具模式已啟用"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"恢復原廠設定以停用測試控管工具模式。"</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"已啟用序列主控台"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"效能已受到影響。如要停用,請檢查系統啟動載入程式。"</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"已啟用實驗 MTE"</string>
@@ -1433,9 +1437,9 @@
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"輕觸即可選取語言和版面配置"</string>
     <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"顯示在其他應用程式上層"</string>
+    <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"在其他應用程式上面顯示"</string>
     <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"「<xliff:g id="NAME">%s</xliff:g>」在其他應用程式上顯示內容"</string>
-    <string name="alert_windows_notification_title" msgid="6331662751095228536">"「<xliff:g id="NAME">%s</xliff:g>」正在其他應用程式上顯示內容"</string>
+    <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>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量鍵。「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」已開啟。"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量鍵。「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」已關閉。"</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"放開音量鍵。如要開啟 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>,請同時按住音量調高鍵和調低鍵 3 秒。"</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"輕觸無障礙工具按鈕後,選擇你想使用的功能:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"選擇要搭配無障礙手勢 (用兩指從螢幕底部向上滑動) 使用的功能:"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"選擇要搭配無障礙手勢 (用三指從螢幕底部向上滑動) 使用的功能:"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"如要切換不同的功能,請按住無障礙工具按鈕。"</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"如要切換不同的功能,請用兩指向上滑動並按住。"</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"如要切換不同的功能,請用三指向上滑動並按住。"</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"下次輕觸無障礙工具按鈕時,就會開啟這項功能"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"下次使用這個捷徑時,就會開啟這項功能。請用 2 指從螢幕底部向上滑動並快速放開。"</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"下次使用這個捷徑時,就會開啟這項功能。請用 3 指從螢幕底部向上滑動並快速放開。"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"放大"</string>
     <string name="user_switched" msgid="7249833311585228097">"目前的使用者是 <xliff:g id="NAME">%1$s</xliff:g>。"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"正在切換至<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"通話中"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"正在過濾來電"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"未分類"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"促銷"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"社群"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"新聞"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"建議"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"這些通知的重要性由你決定。"</string>
     <string name="importance_from_person" msgid="4235804979664465383">"這則通知涉及特定人士,因此被歸為重要通知。"</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"自訂應用程式通知"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"螢幕上的無障礙捷徑選擇器"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"無障礙捷徑"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"關閉通知欄"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"選單"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"媒體播放/暫停"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Dpad 向上移"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Dpad 向下移"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Dpad 向左移"</string>
@@ -2411,19 +2424,23 @@
     <string name="private_space_biometric_prompt_title" msgid="5777592909271728154">"私人空間"</string>
     <string name="redacted_notification_message" msgid="1520587845842228816">"系統已隱藏含有私密資訊的通知內容"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
-    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"為安全起見,分享螢幕畫面未顯示應用程式內容"</string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"為安全起見,分享螢幕畫面隱藏了這個應用程式的內容"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"已自動連上衛星"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"你可以收發訊息,沒有行動/Wi-Fi 網路也無妨"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"開啟「訊息」應用程式"</string>
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"運作方式"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"待處理…"</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"重新設定指紋解鎖"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"「<xliff:g id="FINGERPRINT">%s</xliff:g>」無法正常運作,系統已將其刪除"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"「<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>」和「<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>」無法正常運作,系統已將其刪除"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"「<xliff:g id="FINGERPRINT">%s</xliff:g>」無法正常運作,因此系統已將其刪除。請重新設定,才能用指紋解鎖手機。"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"「<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>」和「<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>」無法正常運作,因此系統已將其刪除。請重新設定,才能用指紋解鎖手機。"</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"系統無法再辨識「<xliff:g id="FINGERPRINT">%s</xliff:g>」。"</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"系統無法再辨識「<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>」和「<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>」。"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"系統無法再辨識「<xliff:g id="FINGERPRINT">%s</xliff:g>」,請重新設定指紋解鎖。"</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"系統無法再辨識「<xliff:g id="FINGERPRINT_0">%1$s</xliff:g>」和「<xliff:g id="FINGERPRINT_1">%2$s</xliff:g>」,請重新設定指紋解鎖。"</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"重新設定人臉解鎖"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"臉部模型無法正常運作,因此系統已將其刪除。請重新設定,才能用臉解鎖手機。"</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"系統無法再辨識你的臉部模型,請重新設定人臉解鎖。"</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"設定"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"暫時不要"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"<xliff:g id="USER_NAME">%s</xliff:g>的鬧鐘"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"切換使用者"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"靜音"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"輕觸即可設為靜音"</string>
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 8285d3e..d378b7c5d 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1411,6 +1411,10 @@
     <string name="adbwifi_active_notification_message" product="tv" msgid="8633421848366915478">"Khetha ukukhubaza ukulungisa amaphutha okungenantambo."</string>
     <string name="test_harness_mode_notification_title" msgid="2282785860014142511">"Imodi yokuhlola i-harness inikwe amandla"</string>
     <string name="test_harness_mode_notification_message" msgid="3039123743127958420">"Yenza ukusetha kabusha kwasekuqaleni ukuze ukhubaze imodi yokuqina yokuhlola."</string>
+    <!-- no translation found for wrong_hsum_configuration_notification_title (7212758829332714385) -->
+    <skip />
+    <!-- no translation found for wrong_hsum_configuration_notification_message (5353475441480684381) -->
+    <skip />
     <string name="console_running_notification_title" msgid="6087888939261635904">"I-serial console inikwe amandla"</string>
     <string name="console_running_notification_message" msgid="7892751888125174039">"Ukusebenza kuyathinteka. Ukuze ukhubaze, hlola i-bootloader."</string>
     <string name="mte_override_notification_title" msgid="4731115381962792944">"I-Experimental MTE inikwe amandla"</string>
@@ -1755,12 +1759,15 @@
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ubambe okhiye bevolumu. I-<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ivuliwe."</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ubambe okhiye bevolumu. I-<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ivaliwe."</string>
     <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Khipha okhiye bevolumu. Ukuze uvule i-<xliff:g id="SERVICE_NAME">%1$s</xliff:g>, cindezela bese ubamba bobabili okhiye bevolumu futhi imizuzwana emi-3."</string>
-    <string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Khetha isici ozosisebenzisa uma uthepha inkinobho yokufinyelela:"</string>
-    <string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Khetha isici ozosisebenzisa ngokuthinta kokufinyeleleka (swayiphela phezulu kusukela ngaphansi kwesikrini ngeminwe emibili):"</string>
-    <string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Khetha isici ozosisebenzisa ngokuthinta kokufinyeleleka (swayiphela phezulu kusukela phansi esikrinini ngeminwe emithathu):"</string>
-    <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Ukuze ushintshe phakathi kwezici, thinta uphinde ubambe inkinobho yokufinyeleleka."</string>
-    <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Ukuze ushintshe phakathi kwezici, swayiphela phezulu ngeminwe emibili uphinde ubambe."</string>
-    <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Ukuze ushintshe phakathi kwezici, swayiphela phezulu ngeminwe emithathu uphinde ubambe."</string>
+    <!-- no translation found for accessibility_button_prompt_text (6105393217162198616) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_prompt_text (6452246951969541792) -->
+    <skip />
+    <!-- no translation found for accessibility_gesture_3finger_prompt_text (77745752309056152) -->
+    <skip />
+    <string name="accessibility_button_instructional_text" msgid="6831154884557881996">"Isakhi sizovuleka ngokulandelayo uma uthepha inkinobho yokufinyeleleka"</string>
+    <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Lesi sakhi sizovuleka ngokulandelayo uma usebenzisa lesi sinqamuleli. Swayiphela phezulu ngeminwe engu-2 kusukela ngaphansi kwesikrini sakho uphinde udedele ngokushesha."</string>
+    <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Lesi sakhi sizovuleka ngokulandelayo uma usebenzisa lesi sinqamuleli. Swayiphela phezulu ngeminwe engu-3 kusukela ngaphansi kwesikrini sakho uphinde udedele ngokushesha."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ukukhuliswa"</string>
     <string name="user_switched" msgid="7249833311585228097">"Umsebenzisi wamanje <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Ishintshela ku-<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1976,6 +1983,10 @@
     <string name="call_notification_ongoing_text" msgid="3880832933933020875">"Ikholi eqhubekayo"</string>
     <string name="call_notification_screening_text" msgid="8396931408268940208">"Ukuveza ikholi engenayo"</string>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Akufakwanga esigabeni"</string>
+    <string name="promotional_notification_channel_label" msgid="7414844730492860233">"Izindali"</string>
+    <string name="social_notification_channel_label" msgid="106520267132019945">"Imithombo yezokuxhumana"</string>
+    <string name="news_notification_channel_label" msgid="4299937455247883311">"Izindaba"</string>
+    <string name="recs_notification_channel_label" msgid="4945985121418684297">"Izincomo"</string>
     <string name="importance_from_user" msgid="2782756722448800447">"Usethe ukubaluleka kwalezi zaziso."</string>
     <string name="importance_from_person" msgid="4235804979664465383">"Lokhu kubalulekile ngenxa yabantu ababandakanyekayo."</string>
     <string name="notification_history_title_placeholder" msgid="7748630986182249599">"Isaziso sohlelo lokusebenza olungokwezifiso"</string>
@@ -2192,6 +2203,8 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Isikhethi sesinqamuleli sokufinyeleleka kusikrini"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Isinqamuleli sokufinyeleleka"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Cashisa Umthunzi Wesaziso"</string>
+    <string name="accessibility_system_action_menu_label" msgid="3385283204496447040">"Imenyu"</string>
+    <string name="accessibility_system_action_media_play_pause_label" msgid="1905647491347119748">"Ukudlala/Ukumisa Imidiya"</string>
     <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Phezulu kwe-Dpad"</string>
     <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Phansi kwe-Dpad"</string>
     <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Ngakwesokunxele se-Dpad"</string>
@@ -2418,12 +2431,16 @@
     <string name="satellite_notification_how_it_works" msgid="3132069321977520519">"Indlela esebenza ngayo"</string>
     <string name="unarchival_session_app_label" msgid="6811856981546348205">"Ilindile..."</string>
     <string name="fingerprint_dangling_notification_title" msgid="7362075195588639989">"Setha Ukuvula ngesigxivizo somunwe futhi"</string>
-    <string name="fingerprint_dangling_notification_msg_1" msgid="8517140433796229725">"I-<xliff:g id="FINGERPRINT">%s</xliff:g> ibingasebenzi kahle futhi isuliwe"</string>
-    <string name="fingerprint_dangling_notification_msg_2" msgid="7578829498452127613">"I-<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> kanye ne-<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ibingasebenzi kahle futhi isuliwe"</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="2927018569542316055">"I-<xliff:g id="FINGERPRINT">%s</xliff:g> ibingasebenzi kahle futhi isuliwe. Phinde uyisethe ukuze uvule ifoni yakho ngesigxivizo somunwe."</string>
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="6897989352716156176">"I-<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> kanye ne-<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> ibingasebenzi kahle futhi isuliwe. Phinde uyisethe ukuze uvule ifoni yakho ngesigxivizo somunwe wakho"</string>
+    <string name="fingerprint_dangling_notification_msg_1" msgid="5851784577768803510">"I-<xliff:g id="FINGERPRINT">%s</xliff:g> angeke isaziwa."</string>
+    <string name="fingerprint_dangling_notification_msg_2" msgid="7925203589860744456">"I-<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> kanye ne-<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> angeke isaziwa."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1" msgid="1824812666549916586">"I-<xliff:g id="FINGERPRINT">%s</xliff:g> angeke isaziwa. Setha Ukuvula Ngesigxivizo Somunwe futhi."</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2" msgid="5974657382960155099">"I-<xliff:g id="FINGERPRINT_0">%1$s</xliff:g> kanye ne-<xliff:g id="FINGERPRINT_1">%2$s</xliff:g> angeke isaziwa. Setha Ukuvula Ngesigxivizo Somunwe futhi."</string>
     <string name="face_dangling_notification_title" msgid="947852541060975473">"Setha Ukuvula Ngobuso futhi"</string>
-    <string name="face_dangling_notification_msg" msgid="8806849376915541655">"Imodeli yobuso yakho ibingasebenzi kahle futhi isuliwe. Phinde uyisethe ukuze uvule ifoni yakho ngobuso."</string>
+    <string name="face_dangling_notification_msg" msgid="746235263598985384">"Imodeli yobuso yakho angeke isabonwa. Setha Ukuvula Ngobuso futhi."</string>
     <string name="biometric_dangling_notification_action_set_up" msgid="8246885009807817961">"Setha"</string>
     <string name="biometric_dangling_notification_action_not_now" msgid="8095249216864443491">"Hhayi manje"</string>
+    <string name="bg_user_sound_notification_title_alarm" msgid="5251678483393143527">"I-alamu ka-<xliff:g id="USER_NAME">%s</xliff:g>"</string>
+    <string name="bg_user_sound_notification_button_switch_user" msgid="3091969648572788946">"Shintsha umsebenzisi"</string>
+    <string name="bg_user_sound_notification_button_mute" msgid="4942158515665615243">"Thulisa"</string>
+    <string name="bg_user_sound_notification_message" msgid="8613881975316976673">"Thepha ukuze uthulise umsindo"</string>
 </resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 9846b71..4892f59 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1361,7 +1361,7 @@
         <!-- @hide -->
         <attr name="customColorThemeAppRing" format="color"/>
         <!-- @hide -->
-        <attr name="customColorOnThemeAppRing" format="color"/>
+        <attr name="customColorThemeNotif" format="color"/>
         <!-- @hide -->
         <attr name="customColorBrandA" format="color"/>
         <!-- @hide -->
@@ -2184,6 +2184,344 @@
         <enum name="KEYCODE_DEMO_APP_2" value="302" />
         <enum name="KEYCODE_DEMO_APP_3" value="303" />
         <enum name="KEYCODE_DEMO_APP_4" value="304" />
+        <enum name="KEYCODE_KEYBOARD_BACKLIGHT_DOWN" value="305" />
+        <enum name="KEYCODE_KEYBOARD_BACKLIGHT_UP" value="306" />
+        <enum name="KEYCODE_KEYBOARD_BACKLIGHT_TOGGLE" value="307" />
+        <enum name="KEYCODE_STYLUS_BUTTON_PRIMARY" value="308" />
+        <enum name="KEYCODE_STYLUS_BUTTON_SECONDARY" value="309" />
+        <enum name="KEYCODE_STYLUS_BUTTON_TERTIARY" value="310" />
+        <enum name="KEYCODE_STYLUS_BUTTON_TAIL" value="311" />
+        <enum name="KEYCODE_RECENT_APPS" value="312" />
+        <enum name="KEYCODE_MACRO_1" value="313" />
+        <enum name="KEYCODE_MACRO_2" value="314" />
+        <enum name="KEYCODE_MACRO_3" value="315" />
+        <enum name="KEYCODE_MACRO_4" value="316" />
+        <enum name="KEYCODE_EMOJI_PICKER" value="317" />
+        <enum name="KEYCODE_SCREENSHOT" value="318" />
+    </attr>
+
+    <!-- @hide same as keycode enum defined above, but to be used to define keycode output.
+         (redefining it to allow keycode and outKeycode to be part of same styleable attribute) -->
+    <attr name="outKeycode">
+        <enum name="KEYCODE_UNKNOWN" value="0" />
+        <enum name="KEYCODE_SOFT_LEFT" value="1" />
+        <enum name="KEYCODE_SOFT_RIGHT" value="2" />
+        <enum name="KEYCODE_HOME" value="3" />
+        <enum name="KEYCODE_BACK" value="4" />
+        <enum name="KEYCODE_CALL" value="5" />
+        <enum name="KEYCODE_ENDCALL" value="6" />
+        <enum name="KEYCODE_0" value="7" />
+        <enum name="KEYCODE_1" value="8" />
+        <enum name="KEYCODE_2" value="9" />
+        <enum name="KEYCODE_3" value="10" />
+        <enum name="KEYCODE_4" value="11" />
+        <enum name="KEYCODE_5" value="12" />
+        <enum name="KEYCODE_6" value="13" />
+        <enum name="KEYCODE_7" value="14" />
+        <enum name="KEYCODE_8" value="15" />
+        <enum name="KEYCODE_9" value="16" />
+        <enum name="KEYCODE_STAR" value="17" />
+        <enum name="KEYCODE_POUND" value="18" />
+        <enum name="KEYCODE_DPAD_UP" value="19" />
+        <enum name="KEYCODE_DPAD_DOWN" value="20" />
+        <enum name="KEYCODE_DPAD_LEFT" value="21" />
+        <enum name="KEYCODE_DPAD_RIGHT" value="22" />
+        <enum name="KEYCODE_DPAD_CENTER" value="23" />
+        <enum name="KEYCODE_VOLUME_UP" value="24" />
+        <enum name="KEYCODE_VOLUME_DOWN" value="25" />
+        <enum name="KEYCODE_POWER" value="26" />
+        <enum name="KEYCODE_CAMERA" value="27" />
+        <enum name="KEYCODE_CLEAR" value="28" />
+        <enum name="KEYCODE_A" value="29" />
+        <enum name="KEYCODE_B" value="30" />
+        <enum name="KEYCODE_C" value="31" />
+        <enum name="KEYCODE_D" value="32" />
+        <enum name="KEYCODE_E" value="33" />
+        <enum name="KEYCODE_F" value="34" />
+        <enum name="KEYCODE_G" value="35" />
+        <enum name="KEYCODE_H" value="36" />
+        <enum name="KEYCODE_I" value="37" />
+        <enum name="KEYCODE_J" value="38" />
+        <enum name="KEYCODE_K" value="39" />
+        <enum name="KEYCODE_L" value="40" />
+        <enum name="KEYCODE_M" value="41" />
+        <enum name="KEYCODE_N" value="42" />
+        <enum name="KEYCODE_O" value="43" />
+        <enum name="KEYCODE_P" value="44" />
+        <enum name="KEYCODE_Q" value="45" />
+        <enum name="KEYCODE_R" value="46" />
+        <enum name="KEYCODE_S" value="47" />
+        <enum name="KEYCODE_T" value="48" />
+        <enum name="KEYCODE_U" value="49" />
+        <enum name="KEYCODE_V" value="50" />
+        <enum name="KEYCODE_W" value="51" />
+        <enum name="KEYCODE_X" value="52" />
+        <enum name="KEYCODE_Y" value="53" />
+        <enum name="KEYCODE_Z" value="54" />
+        <enum name="KEYCODE_COMMA" value="55" />
+        <enum name="KEYCODE_PERIOD" value="56" />
+        <enum name="KEYCODE_ALT_LEFT" value="57" />
+        <enum name="KEYCODE_ALT_RIGHT" value="58" />
+        <enum name="KEYCODE_SHIFT_LEFT" value="59" />
+        <enum name="KEYCODE_SHIFT_RIGHT" value="60" />
+        <enum name="KEYCODE_TAB" value="61" />
+        <enum name="KEYCODE_SPACE" value="62" />
+        <enum name="KEYCODE_SYM" value="63" />
+        <enum name="KEYCODE_EXPLORER" value="64" />
+        <enum name="KEYCODE_ENVELOPE" value="65" />
+        <enum name="KEYCODE_ENTER" value="66" />
+        <enum name="KEYCODE_DEL" value="67" />
+        <enum name="KEYCODE_GRAVE" value="68" />
+        <enum name="KEYCODE_MINUS" value="69" />
+        <enum name="KEYCODE_EQUALS" value="70" />
+        <enum name="KEYCODE_LEFT_BRACKET" value="71" />
+        <enum name="KEYCODE_RIGHT_BRACKET" value="72" />
+        <enum name="KEYCODE_BACKSLASH" value="73" />
+        <enum name="KEYCODE_SEMICOLON" value="74" />
+        <enum name="KEYCODE_APOSTROPHE" value="75" />
+        <enum name="KEYCODE_SLASH" value="76" />
+        <enum name="KEYCODE_AT" value="77" />
+        <enum name="KEYCODE_NUM" value="78" />
+        <enum name="KEYCODE_HEADSETHOOK" value="79" />
+        <enum name="KEYCODE_FOCUS" value="80" />
+        <enum name="KEYCODE_PLUS" value="81" />
+        <enum name="KEYCODE_MENU" value="82" />
+        <enum name="KEYCODE_NOTIFICATION" value="83" />
+        <enum name="KEYCODE_SEARCH" value="84" />
+        <enum name="KEYCODE_MEDIA_PLAY_PAUSE" value="85" />
+        <enum name="KEYCODE_MEDIA_STOP" value="86" />
+        <enum name="KEYCODE_MEDIA_NEXT" value="87" />
+        <enum name="KEYCODE_MEDIA_PREVIOUS" value="88" />
+        <enum name="KEYCODE_MEDIA_REWIND" value="89" />
+        <enum name="KEYCODE_MEDIA_FAST_FORWARD" value="90" />
+        <enum name="KEYCODE_MUTE" value="91" />
+        <enum name="KEYCODE_PAGE_UP" value="92" />
+        <enum name="KEYCODE_PAGE_DOWN" value="93" />
+        <enum name="KEYCODE_PICTSYMBOLS" value="94" />
+        <enum name="KEYCODE_SWITCH_CHARSET" value="95" />
+        <enum name="KEYCODE_BUTTON_A" value="96" />
+        <enum name="KEYCODE_BUTTON_B" value="97" />
+        <enum name="KEYCODE_BUTTON_C" value="98" />
+        <enum name="KEYCODE_BUTTON_X" value="99" />
+        <enum name="KEYCODE_BUTTON_Y" value="100" />
+        <enum name="KEYCODE_BUTTON_Z" value="101" />
+        <enum name="KEYCODE_BUTTON_L1" value="102" />
+        <enum name="KEYCODE_BUTTON_R1" value="103" />
+        <enum name="KEYCODE_BUTTON_L2" value="104" />
+        <enum name="KEYCODE_BUTTON_R2" value="105" />
+        <enum name="KEYCODE_BUTTON_THUMBL" value="106" />
+        <enum name="KEYCODE_BUTTON_THUMBR" value="107" />
+        <enum name="KEYCODE_BUTTON_START" value="108" />
+        <enum name="KEYCODE_BUTTON_SELECT" value="109" />
+        <enum name="KEYCODE_BUTTON_MODE" value="110" />
+        <enum name="KEYCODE_ESCAPE" value="111" />
+        <enum name="KEYCODE_FORWARD_DEL" value="112" />
+        <enum name="KEYCODE_CTRL_LEFT" value="113" />
+        <enum name="KEYCODE_CTRL_RIGHT" value="114" />
+        <enum name="KEYCODE_CAPS_LOCK" value="115" />
+        <enum name="KEYCODE_SCROLL_LOCK" value="116" />
+        <enum name="KEYCODE_META_LEFT" value="117" />
+        <enum name="KEYCODE_META_RIGHT" value="118" />
+        <enum name="KEYCODE_FUNCTION" value="119" />
+        <enum name="KEYCODE_SYSRQ" value="120" />
+        <enum name="KEYCODE_BREAK" value="121" />
+        <enum name="KEYCODE_MOVE_HOME" value="122" />
+        <enum name="KEYCODE_MOVE_END" value="123" />
+        <enum name="KEYCODE_INSERT" value="124" />
+        <enum name="KEYCODE_FORWARD" value="125" />
+        <enum name="KEYCODE_MEDIA_PLAY" value="126" />
+        <enum name="KEYCODE_MEDIA_PAUSE" value="127" />
+        <enum name="KEYCODE_MEDIA_CLOSE" value="128" />
+        <enum name="KEYCODE_MEDIA_EJECT" value="129" />
+        <enum name="KEYCODE_MEDIA_RECORD" value="130" />
+        <enum name="KEYCODE_F1" value="131" />
+        <enum name="KEYCODE_F2" value="132" />
+        <enum name="KEYCODE_F3" value="133" />
+        <enum name="KEYCODE_F4" value="134" />
+        <enum name="KEYCODE_F5" value="135" />
+        <enum name="KEYCODE_F6" value="136" />
+        <enum name="KEYCODE_F7" value="137" />
+        <enum name="KEYCODE_F8" value="138" />
+        <enum name="KEYCODE_F9" value="139" />
+        <enum name="KEYCODE_F10" value="140" />
+        <enum name="KEYCODE_F11" value="141" />
+        <enum name="KEYCODE_F12" value="142" />
+        <enum name="KEYCODE_NUM_LOCK" value="143" />
+        <enum name="KEYCODE_NUMPAD_0" value="144" />
+        <enum name="KEYCODE_NUMPAD_1" value="145" />
+        <enum name="KEYCODE_NUMPAD_2" value="146" />
+        <enum name="KEYCODE_NUMPAD_3" value="147" />
+        <enum name="KEYCODE_NUMPAD_4" value="148" />
+        <enum name="KEYCODE_NUMPAD_5" value="149" />
+        <enum name="KEYCODE_NUMPAD_6" value="150" />
+        <enum name="KEYCODE_NUMPAD_7" value="151" />
+        <enum name="KEYCODE_NUMPAD_8" value="152" />
+        <enum name="KEYCODE_NUMPAD_9" value="153" />
+        <enum name="KEYCODE_NUMPAD_DIVIDE" value="154" />
+        <enum name="KEYCODE_NUMPAD_MULTIPLY" value="155" />
+        <enum name="KEYCODE_NUMPAD_SUBTRACT" value="156" />
+        <enum name="KEYCODE_NUMPAD_ADD" value="157" />
+        <enum name="KEYCODE_NUMPAD_DOT" value="158" />
+        <enum name="KEYCODE_NUMPAD_COMMA" value="159" />
+        <enum name="KEYCODE_NUMPAD_ENTER" value="160" />
+        <enum name="KEYCODE_NUMPAD_EQUALS" value="161" />
+        <enum name="KEYCODE_NUMPAD_LEFT_PAREN" value="162" />
+        <enum name="KEYCODE_NUMPAD_RIGHT_PAREN" value="163" />
+        <enum name="KEYCODE_VOLUME_MUTE" value="164" />
+        <enum name="KEYCODE_INFO" value="165" />
+        <enum name="KEYCODE_CHANNEL_UP" value="166" />
+        <enum name="KEYCODE_CHANNEL_DOWN" value="167" />
+        <enum name="KEYCODE_ZOOM_IN" value="168" />
+        <enum name="KEYCODE_ZOOM_OUT" value="169" />
+        <enum name="KEYCODE_TV" value="170" />
+        <enum name="KEYCODE_WINDOW" value="171" />
+        <enum name="KEYCODE_GUIDE" value="172" />
+        <enum name="KEYCODE_DVR" value="173" />
+        <enum name="KEYCODE_BOOKMARK" value="174" />
+        <enum name="KEYCODE_CAPTIONS" value="175" />
+        <enum name="KEYCODE_SETTINGS" value="176" />
+        <enum name="KEYCODE_TV_POWER" value="177" />
+        <enum name="KEYCODE_TV_INPUT" value="178" />
+        <enum name="KEYCODE_STB_POWER" value="179" />
+        <enum name="KEYCODE_STB_INPUT" value="180" />
+        <enum name="KEYCODE_AVR_POWER" value="181" />
+        <enum name="KEYCODE_AVR_INPUT" value="182" />
+        <enum name="KEYCODE_PROG_GRED" value="183" />
+        <enum name="KEYCODE_PROG_GREEN" value="184" />
+        <enum name="KEYCODE_PROG_YELLOW" value="185" />
+        <enum name="KEYCODE_PROG_BLUE" value="186" />
+        <enum name="KEYCODE_APP_SWITCH" value="187" />
+        <enum name="KEYCODE_BUTTON_1" value="188" />
+        <enum name="KEYCODE_BUTTON_2" value="189" />
+        <enum name="KEYCODE_BUTTON_3" value="190" />
+        <enum name="KEYCODE_BUTTON_4" value="191" />
+        <enum name="KEYCODE_BUTTON_5" value="192" />
+        <enum name="KEYCODE_BUTTON_6" value="193" />
+        <enum name="KEYCODE_BUTTON_7" value="194" />
+        <enum name="KEYCODE_BUTTON_8" value="195" />
+        <enum name="KEYCODE_BUTTON_9" value="196" />
+        <enum name="KEYCODE_BUTTON_10" value="197" />
+        <enum name="KEYCODE_BUTTON_11" value="198" />
+        <enum name="KEYCODE_BUTTON_12" value="199" />
+        <enum name="KEYCODE_BUTTON_13" value="200" />
+        <enum name="KEYCODE_BUTTON_14" value="201" />
+        <enum name="KEYCODE_BUTTON_15" value="202" />
+        <enum name="KEYCODE_BUTTON_16" value="203" />
+        <enum name="KEYCODE_LANGUAGE_SWITCH" value="204" />
+        <enum name="KEYCODE_MANNER_MODE" value="205" />
+        <enum name="KEYCODE_3D_MODE" value="206" />
+        <enum name="KEYCODE_CONTACTS" value="207" />
+        <enum name="KEYCODE_CALENDAR" value="208" />
+        <enum name="KEYCODE_MUSIC" value="209" />
+        <enum name="KEYCODE_CALCULATOR" value="210" />
+        <enum name="KEYCODE_ZENKAKU_HANKAKU" value="211" />
+        <enum name="KEYCODE_EISU" value="212" />
+        <enum name="KEYCODE_MUHENKAN" value="213" />
+        <enum name="KEYCODE_HENKAN" value="214" />
+        <enum name="KEYCODE_KATAKANA_HIRAGANA" value="215" />
+        <enum name="KEYCODE_YEN" value="216" />
+        <enum name="KEYCODE_RO" value="217" />
+        <enum name="KEYCODE_KANA" value="218" />
+        <enum name="KEYCODE_ASSIST" value="219" />
+        <enum name="KEYCODE_BRIGHTNESS_DOWN" value="220" />
+        <enum name="KEYCODE_BRIGHTNESS_UP" value="221" />
+        <enum name="KEYCODE_MEDIA_AUDIO_TRACK" value="222" />
+        <enum name="KEYCODE_MEDIA_SLEEP" value="223" />
+        <enum name="KEYCODE_MEDIA_WAKEUP" value="224" />
+        <enum name="KEYCODE_PAIRING" value="225" />
+        <enum name="KEYCODE_MEDIA_TOP_MENU" value="226" />
+        <enum name="KEYCODE_11" value="227" />
+        <enum name="KEYCODE_12" value="228" />
+        <enum name="KEYCODE_LAST_CHANNEL" value="229" />
+        <enum name="KEYCODE_TV_DATA_SERVICE" value="230" />
+        <enum name="KEYCODE_VOICE_ASSIST" value="231" />
+        <enum name="KEYCODE_TV_RADIO_SERVICE" value="232" />
+        <enum name="KEYCODE_TV_TELETEXT" value="233" />
+        <enum name="KEYCODE_TV_NUMBER_ENTRY" value="234" />
+        <enum name="KEYCODE_TV_TERRESTRIAL_ANALOG" value="235" />
+        <enum name="KEYCODE_TV_TERRESTRIAL_DIGITAL" value="236" />
+        <enum name="KEYCODE_TV_SATELLITE" value="237" />
+        <enum name="KEYCODE_TV_SATELLITE_BS" value="238" />
+        <enum name="KEYCODE_TV_SATELLITE_CS" value="239" />
+        <enum name="KEYCODE_TV_SATELLITE_SERVICE" value="240" />
+        <enum name="KEYCODE_TV_NETWORK" value="241" />
+        <enum name="KEYCODE_TV_ANTENNA_CABLE" value="242" />
+        <enum name="KEYCODE_TV_INPUT_HDMI_1" value="243" />
+        <enum name="KEYCODE_TV_INPUT_HDMI_2" value="244" />
+        <enum name="KEYCODE_TV_INPUT_HDMI_3" value="245" />
+        <enum name="KEYCODE_TV_INPUT_HDMI_4" value="246" />
+        <enum name="KEYCODE_TV_INPUT_COMPOSITE_1" value="247" />
+        <enum name="KEYCODE_TV_INPUT_COMPOSITE_2" value="248" />
+        <enum name="KEYCODE_TV_INPUT_COMPONENT_1" value="249" />
+        <enum name="KEYCODE_TV_INPUT_COMPONENT_2" value="250" />
+        <enum name="KEYCODE_TV_INPUT_VGA_1" value="251" />
+        <enum name="KEYCODE_TV_AUDIO_DESCRIPTION" value="252" />
+        <enum name="KEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP" value="253" />
+        <enum name="KEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN" value="254" />
+        <enum name="KEYCODE_TV_ZOOM_MODE" value="255" />
+        <enum name="KEYCODE_TV_CONTENTS_MENU" value="256" />
+        <enum name="KEYCODE_TV_MEDIA_CONTEXT_MENU" value="257" />
+        <enum name="KEYCODE_TV_TIMER_PROGRAMMING" value="258" />
+        <enum name="KEYCODE_HELP" value="259" />
+        <enum name="KEYCODE_NAVIGATE_PREVIOUS" value="260" />
+        <enum name="KEYCODE_NAVIGATE_NEXT" value="261" />
+        <enum name="KEYCODE_NAVIGATE_IN" value="262" />
+        <enum name="KEYCODE_NAVIGATE_OUT" value="263" />
+        <enum name="KEYCODE_STEM_PRIMARY" value="264" />
+        <enum name="KEYCODE_STEM_1" value="265" />
+        <enum name="KEYCODE_STEM_2" value="266" />
+        <enum name="KEYCODE_STEM_3" value="267" />
+        <enum name="KEYCODE_DPAD_UP_LEFT" value="268" />
+        <enum name="KEYCODE_DPAD_DOWN_LEFT" value="269" />
+        <enum name="KEYCODE_DPAD_UP_RIGHT" value="270" />
+        <enum name="KEYCODE_DPAD_DOWN_RIGHT" value="271" />
+        <enum name="KEYCODE_MEDIA_SKIP_FORWARD" value="272" />
+        <enum name="KEYCODE_MEDIA_SKIP_BACKWARD" value="273" />
+        <enum name="KEYCODE_MEDIA_STEP_FORWARD" value="274" />
+        <enum name="KEYCODE_MEDIA_STEP_BACKWARD" value="275" />
+        <enum name="KEYCODE_SOFT_SLEEP" value="276" />
+        <enum name="KEYCODE_CUT" value="277" />
+        <enum name="KEYCODE_COPY" value="278" />
+        <enum name="KEYCODE_PASTE" value="279" />
+        <enum name="KEYCODE_SYSTEM_NAVIGATION_UP" value="280" />
+        <enum name="KEYCODE_SYSTEM_NAVIGATION_DOWN" value="281" />
+        <enum name="KEYCODE_SYSTEM_NAVIGATION_LEFT" value="282" />
+        <enum name="KEYCODE_SYSTEM_NAVIGATION_RIGHT" value="283" />
+        <enum name="KEYCODE_ALL_APPS" value="284" />
+        <enum name="KEYCODE_REFRESH" value="285" />
+        <enum name="KEYCODE_THUMBS_UP" value="286" />
+        <enum name="KEYCODE_THUMBS_DOWN" value="287" />
+        <enum name="KEYCODE_PROFILE_SWITCH" value="288" />
+        <enum name="KEYCODE_VIDEO_APP_1" value="289" />
+        <enum name="KEYCODE_VIDEO_APP_2" value="290" />
+        <enum name="KEYCODE_VIDEO_APP_3" value="291" />
+        <enum name="KEYCODE_VIDEO_APP_4" value="292" />
+        <enum name="KEYCODE_VIDEO_APP_5" value="293" />
+        <enum name="KEYCODE_VIDEO_APP_6" value="294" />
+        <enum name="KEYCODE_VIDEO_APP_7" value="295" />
+        <enum name="KEYCODE_VIDEO_APP_8" value="296" />
+        <enum name="KEYCODE_FEATURED_APP_1" value="297" />
+        <enum name="KEYCODE_FEATURED_APP_2" value="298" />
+        <enum name="KEYCODE_FEATURED_APP_3" value="299" />
+        <enum name="KEYCODE_FEATURED_APP_4" value="300" />
+        <enum name="KEYCODE_DEMO_APP_1" value="301" />
+        <enum name="KEYCODE_DEMO_APP_2" value="302" />
+        <enum name="KEYCODE_DEMO_APP_3" value="303" />
+        <enum name="KEYCODE_DEMO_APP_4" value="304" />
+        <enum name="KEYCODE_KEYBOARD_BACKLIGHT_DOWN" value="305" />
+        <enum name="KEYCODE_KEYBOARD_BACKLIGHT_UP" value="306" />
+        <enum name="KEYCODE_KEYBOARD_BACKLIGHT_TOGGLE" value="307" />
+        <enum name="KEYCODE_STYLUS_BUTTON_PRIMARY" value="308" />
+        <enum name="KEYCODE_STYLUS_BUTTON_SECONDARY" value="309" />
+        <enum name="KEYCODE_STYLUS_BUTTON_TERTIARY" value="310" />
+        <enum name="KEYCODE_STYLUS_BUTTON_TAIL" value="311" />
+        <enum name="KEYCODE_RECENT_APPS" value="312" />
+        <enum name="KEYCODE_MACRO_1" value="313" />
+        <enum name="KEYCODE_MACRO_2" value="314" />
+        <enum name="KEYCODE_MACRO_3" value="315" />
+        <enum name="KEYCODE_MACRO_4" value="316" />
+        <enum name="KEYCODE_EMOJI_PICKER" value="317" />
+        <enum name="KEYCODE_SCREENSHOT" value="318" />
     </attr>
 
     <!-- ***************************************************************** -->
@@ -9704,6 +10042,8 @@
     <declare-styleable name="PointerIconVectorTheme">
         <attr name="pointerIconVectorFill" format="color" />
         <attr name="pointerIconVectorFillInverse" format="color" />
+        <attr name="pointerIconVectorStroke" format="color" />
+        <attr name="pointerIconVectorStrokeInverse" format="color" />
     </declare-styleable>
 
     <declare-styleable name="Storage">
@@ -9844,6 +10184,63 @@
         <attr name="productId" format="integer" />
     </declare-styleable>
 
+    <!-- @hide -->
+    <declare-styleable name="KeyboardGlyphMap">
+        <attr name="glyphMap" format="reference" />
+        <attr name="vendorId" format="integer" />
+        <attr name="productId" format="integer" />
+    </declare-styleable>
+
+    <!-- @hide -->
+    <declare-styleable name="KeyGlyph">
+        <attr name="keycode" />
+        <attr name="glyphDrawable" format="reference" />
+    </declare-styleable>
+
+    <!-- @hide -->
+    <declare-styleable name="ModifierGlyph">
+        <!-- The values are taken from public constants for modifier state defined in
+             {@see KeyEvent.java}. Here we explicitly allow only one modifier bit as value, since
+             this represents the modifier key -->
+        <attr name="modifier">
+            <enum name="META" value="0x10000" />
+            <enum name="CTRL" value="0x1000" />
+            <enum name="ALT" value="0x02" />
+            <enum name="SHIFT" value="0x1" />
+            <enum name="SYM" value="0x4" />
+            <enum name="FUNCTION" value="0x8" />
+            <enum name="CAPS_LOCK" value="0x100000" />
+            <enum name="NUM_LOCK" value="0x200000" />
+            <enum name="SCROLL_LOCK" value="0x400000" />
+        </attr>
+        <attr name="glyphDrawable" format="reference" />
+    </declare-styleable>
+
+    <!-- @hide -->
+    <declare-styleable name="HardwareDefinedShortcut">
+        <attr name="keycode" />
+        <!-- The values are taken from public constants for modifier state defined in
+             {@see KeyEvent.java}. Here we allow multiple modifier flags as value, since this
+             represents the modifier state -->
+        <attr name="modifierState">
+            <flag name="META" value="0x10000" />
+            <flag name="CTRL" value="0x1000" />
+            <flag name="ALT" value="0x02" />
+            <flag name="SHIFT" value="0x1" />
+            <flag name="SYM" value="0x4" />
+            <flag name="FUNCTION" value="0x8" />
+            <flag name="CAPS_LOCK" value="0x100000" />
+            <flag name="NUM_LOCK" value="0x200000" />
+            <flag name="SCROLL_LOCK" value="0x400000" />
+        </attr>
+        <attr name="outKeycode" />
+    </declare-styleable>
+
+    <!-- @hide -->
+    <declare-styleable name="FunctionRowKey">
+        <attr name="keycode" />
+    </declare-styleable>
+
     <declare-styleable name="MediaRouteButton">
         <!-- This drawable is a state list where the "activated" state
              indicates active media routing. Non-activated indicates
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 5e039b5..f5bb554 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -480,17 +480,17 @@
 
     <!-- Colors used in Android system, from design system.
      These values can be overlaid at runtime by OverlayManager RROs. -->
-    <color name="system_primary_container_light">#5E73A9</color>
-    <color name="system_on_primary_container_light">#FFFFFF</color>
-    <color name="system_primary_light">#2A4174</color>
+    <color name="system_primary_container_light">#D9E2FF</color>
+    <color name="system_on_primary_container_light">#001945</color>
+    <color name="system_primary_light">#475D92</color>
     <color name="system_on_primary_light">#FFFFFF</color>
-    <color name="system_secondary_container_light">#6E7488</color>
-    <color name="system_on_secondary_container_light">#FFFFFF</color>
-    <color name="system_secondary_light">#3C4255</color>
+    <color name="system_secondary_container_light">#DCE2F9</color>
+    <color name="system_on_secondary_container_light">#151B2C</color>
+    <color name="system_secondary_light">#575E71</color>
     <color name="system_on_secondary_light">#FFFFFF</color>
-    <color name="system_tertiary_container_light">#8A6A89</color>
-    <color name="system_on_tertiary_container_light">#FFFFFF</color>
-    <color name="system_tertiary_light">#553A55</color>
+    <color name="system_tertiary_container_light">#FDD7FA</color>
+    <color name="system_on_tertiary_container_light">#2A122C</color>
+    <color name="system_tertiary_light">#725572</color>
     <color name="system_on_tertiary_light">#FFFFFF</color>
     <color name="system_background_light">#FAF8FF</color>
     <color name="system_on_background_light">#1A1B20</color>
@@ -504,17 +504,17 @@
     <color name="system_surface_bright_light">#FAF8FF</color>
     <color name="system_surface_dim_light">#DAD9E0</color>
     <color name="system_surface_variant_light">#E1E2EC</color>
-    <color name="system_on_surface_variant_light">#40434B</color>
-    <color name="system_outline_light">#5D5F67</color>
-    <color name="system_outline_variant_light">#797A83</color>
-    <color name="system_error_light">#8C0009</color>
+    <color name="system_on_surface_variant_light">#44464F</color>
+    <color name="system_outline_light">#757780</color>
+    <color name="system_outline_variant_light">#C5C6D0</color>
+    <color name="system_error_light">#BA1A1A</color>
     <color name="system_on_error_light">#FFFFFF</color>
-    <color name="system_error_container_light">#DA342E</color>
-    <color name="system_on_error_container_light">#FFFFFF</color>
+    <color name="system_error_container_light">#FFDAD6</color>
+    <color name="system_on_error_container_light">#410002</color>
     <color name="system_control_activated_light">#D9E2FF</color>
     <color name="system_control_normal_light">#44464F</color>
     <color name="system_control_highlight_light">#000000</color>
-    <color name="system_text_primary_inverse_light">#E2E2E9</color>
+<color name="system_text_primary_inverse_light">#E2E2E9</color>
     <color name="system_text_secondary_and_tertiary_inverse_light">#C5C6D0</color>
     <color name="system_text_primary_inverse_disable_only_light">#E2E2E9</color>
     <color name="system_text_secondary_and_tertiary_inverse_disabled_light">#E2E2E9</color>
@@ -524,22 +524,22 @@
     <color name="system_palette_key_color_tertiary_light">#8C6D8C</color>
     <color name="system_palette_key_color_neutral_light">#76777D</color>
     <color name="system_palette_key_color_neutral_variant_light">#757780</color>
-    <color name="system_primary_container_dark">#7A90C8</color>
-    <color name="system_on_primary_container_dark">#000000</color>
-    <color name="system_primary_dark">#B7CAFF</color>
-    <color name="system_on_primary_dark">#00143B</color>
-    <color name="system_secondary_container_dark">#8A90A5</color>
-    <color name="system_on_secondary_container_dark">#000000</color>
-    <color name="system_secondary_dark">#C4CAE1</color>
-    <color name="system_on_secondary_dark">#0F1626</color>
-    <color name="system_tertiary_container_dark">#A886A6</color>
-    <color name="system_on_tertiary_container_dark">#000000</color>
-    <color name="system_tertiary_dark">#E4BFE2</color>
-    <color name="system_on_tertiary_dark">#240D26</color>
+    <color name="system_primary_container_dark">#2F4578</color>
+    <color name="system_on_primary_container_dark">#D9E2FF</color>
+    <color name="system_primary_dark">#B0C6FF</color>
+    <color name="system_on_primary_dark">#152E60</color>
+    <color name="system_secondary_container_dark">#404659</color>
+    <color name="system_on_secondary_container_dark">#DCE2F9</color>
+    <color name="system_secondary_dark">#C0C6DC</color>
+    <color name="system_on_secondary_dark">#2A3042</color>
+    <color name="system_tertiary_container_dark">#593D59</color>
+    <color name="system_on_tertiary_container_dark">#FDD7FA</color>
+    <color name="system_tertiary_dark">#E0BBDD</color>
+    <color name="system_on_tertiary_dark">#412742</color>
     <color name="system_background_dark">#121318</color>
     <color name="system_on_background_dark">#E2E2E9</color>
     <color name="system_surface_dark">#121318</color>
-    <color name="system_on_surface_dark">#FCFAFF</color>
+    <color name="system_on_surface_dark">#E2E2E9</color>
     <color name="system_surface_container_low_dark">#1A1B20</color>
     <color name="system_surface_container_lowest_dark">#0C0E13</color>
     <color name="system_surface_container_dark">#1E1F25</color>
@@ -548,13 +548,13 @@
     <color name="system_surface_bright_dark">#38393F</color>
     <color name="system_surface_dim_dark">#121318</color>
     <color name="system_surface_variant_dark">#44464F</color>
-    <color name="system_on_surface_variant_dark">#C9CAD4</color>
-    <color name="system_outline_dark">#A1A2AC</color>
-    <color name="system_outline_variant_dark">#81838C</color>
-    <color name="system_error_dark">#FFBAB1</color>
-    <color name="system_on_error_dark">#370001</color>
-    <color name="system_error_container_dark">#FF5449</color>
-    <color name="system_on_error_container_dark">#000000</color>
+    <color name="system_on_surface_variant_dark">#C5C6D0</color>
+    <color name="system_outline_dark">#8F9099</color>
+    <color name="system_outline_variant_dark">#44464F</color>
+    <color name="system_error_dark">#FFB4AB</color>
+    <color name="system_on_error_dark">#690005</color>
+    <color name="system_error_container_dark">#93000A</color>
+    <color name="system_on_error_container_dark">#FFDAD6</color>
     <color name="system_control_activated_dark">#2F4578</color>
     <color name="system_control_normal_dark">#C5C6D0</color>
     <color name="system_control_highlight_dark">#FFFFFF</color>
@@ -568,63 +568,63 @@
     <color name="system_palette_key_color_tertiary_dark">#8C6D8C</color>
     <color name="system_palette_key_color_neutral_dark">#76777D</color>
     <color name="system_palette_key_color_neutral_variant_dark">#757780</color>
-    <color name="system_primary_fixed">#5E73A9</color>
-    <color name="system_primary_fixed_dim">#455B8F</color>
-    <color name="system_on_primary_fixed">#FFFFFF</color>
-    <color name="system_on_primary_fixed_variant">#FFFFFF</color>
-    <color name="system_secondary_fixed">#6E7488</color>
-    <color name="system_secondary_fixed_dim">#555C6F</color>
-    <color name="system_on_secondary_fixed">#FFFFFF</color>
-    <color name="system_on_secondary_fixed_variant">#FFFFFF</color>
-    <color name="system_tertiary_fixed">#8A6A89</color>
-    <color name="system_tertiary_fixed_dim">#705270</color>
-    <color name="system_on_tertiary_fixed">#FFFFFF</color>
-    <color name="system_on_tertiary_fixed_variant">#FFFFFF</color>
+    <color name="system_primary_fixed">#D9E2FF</color>
+    <color name="system_primary_fixed_dim">#B0C6FF</color>
+    <color name="system_on_primary_fixed">#001945</color>
+    <color name="system_on_primary_fixed_variant">#2F4578</color>
+    <color name="system_secondary_fixed">#DCE2F9</color>
+    <color name="system_secondary_fixed_dim">#C0C6DC</color>
+    <color name="system_on_secondary_fixed">#151B2C</color>
+    <color name="system_on_secondary_fixed_variant">#404659</color>
+    <color name="system_tertiary_fixed">#FDD7FA</color>
+    <color name="system_tertiary_fixed_dim">#E0BBDD</color>
+    <color name="system_on_tertiary_fixed">#2A122C</color>
+    <color name="system_on_tertiary_fixed_variant">#593D59</color>
 
     <!--Colors used in Android system, from design system. These values can be overlaid at runtime
      by OverlayManager RROs.-->
     <color name="system_widget_background_light">#EEF0FF</color>
-    <color name="system_clock_hour_light">#1D2435</color>
-    <color name="system_clock_minute_light">#20386A</color>
-    <color name="system_clock_second_light">#000000</color>
-    <color name="system_theme_app_light">#2F4578</color>
-    <color name="system_on_theme_app_light">#D6DFFF</color>
+    <color name="system_clock_hour_light">#373D50</color>
+    <color name="system_clock_minute_light">#3D5487</color>
+    <color name="system_clock_second_light">#4F659A</color>
+    <color name="system_theme_app_light">#D9E2FF</color>
+    <color name="system_on_theme_app_light">#475D92</color>
     <color name="system_theme_app_ring_light">#94AAE4</color>
-    <color name="system_on_theme_app_ring_light">#FDD7FA</color>
-    <color name="system_brand_a_light">#3A5084</color>
+    <color name="system_theme_notif_light">#E0BBDD</color>
+    <color name="system_brand_a_light">#475D92</color>
     <color name="system_brand_b_light">#6E7488</color>
-    <color name="system_brand_c_light">#6076AC</color>
-    <color name="system_brand_d_light">#8C6D8C</color>
+    <color name="system_brand_c_light">#5E73A9</color>
+    <color name="system_brand_d_light">#8A6A89</color>
     <color name="system_under_surface_light">#000000</color>
-    <color name="system_shade_active_light">#D9E2FF</color>
+<color name="system_shade_active_light">#D9E2FF</color>
     <color name="system_on_shade_active_light">#152E60</color>
     <color name="system_on_shade_active_variant_light">#2F4578</color>
     <color name="system_shade_inactive_light">#2F3036</color>
     <color name="system_on_shade_inactive_light">#E1E2EC</color>
     <color name="system_on_shade_inactive_variant_light">#C5C6D0</color>
     <color name="system_shade_disabled_light">#0C0E13</color>
-    <color name="system_overview_background_light">#50525A</color>
+    <color name="system_overview_background_light">#C5C6D0</color>
     <color name="system_widget_background_dark">#152E60</color>
-    <color name="system_clock_hour_dark">#9AA0B6</color>
-    <color name="system_clock_minute_dark">#D8E1FF</color>
-    <color name="system_clock_second_dark">#FFFFFF</color>
-    <color name="system_theme_app_dark">#D9E2FF</color>
-    <color name="system_on_theme_app_dark">#304679</color>
+    <color name="system_clock_hour_dark">#8A90A5</color>
+    <color name="system_clock_minute_dark">#D9E2FF</color>
+    <color name="system_clock_second_dark">#B0C6FF</color>
+    <color name="system_theme_app_dark">#2F4578</color>
+    <color name="system_on_theme_app_dark">#B0C6FF</color>
     <color name="system_theme_app_ring_dark">#94AAE4</color>
-    <color name="system_on_theme_app_ring_dark">#E0BBDD</color>
-    <color name="system_brand_a_dark">#90A6DF</color>
-    <color name="system_brand_b_dark">#A4ABC1</color>
+    <color name="system_theme_notif_dark">#FDD7FA</color>
+    <color name="system_brand_a_dark">#B0C6FF</color>
+    <color name="system_brand_b_dark">#DCE2F9</color>
     <color name="system_brand_c_dark">#7A90C8</color>
-    <color name="system_brand_d_dark">#A886A6</color>
+    <color name="system_brand_d_dark">#FDD7FA</color>
     <color name="system_under_surface_dark">#000000</color>
-    <color name="system_shade_active_dark">#D9E2FF</color>
+<color name="system_shade_active_dark">#D9E2FF</color>
     <color name="system_on_shade_active_dark">#001945</color>
     <color name="system_on_shade_active_variant_dark">#2F4578</color>
     <color name="system_shade_inactive_dark">#2F3036</color>
     <color name="system_on_shade_inactive_dark">#E1E2EC</color>
     <color name="system_on_shade_inactive_variant_dark">#C5C6D0</color>
     <color name="system_shade_disabled_dark">#0C0E13</color>
-    <color name="system_overview_background_dark">#C5C6D0</color>
+    <color name="system_overview_background_dark">#50525A</color>
 
     <!-- Accessibility shortcut icon background color -->
     <color name="accessibility_feature_background">#5F6368</color> <!-- Google grey 700 -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 17666cf..dc3d935 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -533,6 +533,9 @@
     <!-- If this is true, key chords can be used to take a screenshot on the device. -->
     <bool name="config_enableScreenshotChord">true</bool>
 
+    <!-- If this is true, accessibility events on notifications are sent. -->
+    <bool name="config_enableNotificationAccessibilityEvents">true</bool>
+
     <!-- If this is true, allow wake from theater mode when plugged in or unplugged. -->
     <bool name="config_allowTheaterModeWakeFromUnplug">false</bool>
     <!-- If this is true, allow wake from theater mode from gesture. -->
@@ -567,14 +570,6 @@
          It has been updated to affect other plug types. -->
     <bool name="config_keepDreamingWhenUnplugging">false</bool>
 
-    <!-- The timeout (in ms) to wait before attempting to reconnect to the dream overlay service if
-         it becomes disconnected -->
-    <integer name="config_dreamOverlayReconnectTimeoutMs">1000</integer> <!-- 1 second -->
-    <!-- The maximum number of times to attempt reconnecting to the dream overlay service -->
-    <integer name="config_dreamOverlayMaxReconnectAttempts">3</integer>
-    <!-- The duration after which the dream overlay connection should be considered stable -->
-    <integer name="config_minDreamOverlayDurationMs">10000</integer> <!-- 10 seconds -->
-
     <!-- Auto-rotation behavior -->
 
     <!-- If true, enables auto-rotation features using the accelerometer.
@@ -2633,10 +2628,7 @@
          If false, not supported. -->
     <bool name="config_duplicate_port_omadm_wappush">false</bool>
 
-    <!-- Maximum numerical value that will be shown in a status bar
-         notification icon or in the notification itself. Will be replaced
-         with @string/status_bar_notification_info_overflow when shown in the
-         UI. -->
+    <!-- @deprecated No longer used. -->
     <integer name="status_bar_notification_info_maxnum">999</integer>
 
     <!-- Path to an ISO image to be shared with via USB mass storage.
@@ -3917,6 +3909,7 @@
         <item>countdown</item>
         <item>schedule</item>
         <item>event</item>
+        <item>custom_manual</item>
     </string-array>
 
     <!-- Priority repeat caller threshold, in minutes -->
@@ -4143,8 +4136,8 @@
          and should depend on the touch feedback intensity user setting -->
     <item name="config_keyboardHapticFeedbackFixedAmplitude" format="float" type="dimen">-1</item>
 
-    <!-- The default value for keyboard vibration toggle in settings. -->
-    <bool name="config_defaultKeyboardVibrationEnabled">true</bool>
+    <!-- Indicating if keyboard vibration settings supported or not. -->
+    <bool name="config_keyboardVibrationSettingsSupported">false</bool>
 
     <!-- If the device should still vibrate even in low power mode, for certain priority vibrations
      (e.g. accessibility, alarms). This is mainly for Wear devices that don't have speakers. -->
@@ -6972,6 +6965,9 @@
          Note that, indefinitely repeating vibrations are not allowed as shutdown vibrations. -->
     <string name="config_defaultShutdownVibrationFile" />
 
+    <!-- Whether or not vibration is disabled during shutdown -->
+    <bool name="config_disableShutdownVibrationInZen">false</bool>
+
     <!-- Whether single finger panning is enabled by default when magnification is on -->
     <bool name="config_enable_a11y_magnification_single_panning">false</bool>
 
@@ -7088,6 +7084,9 @@
     <!-- Whether the system uses auto-suspend mode. -->
     <bool name="config_useAutoSuspend">true</bool>
 
+    <!-- Whether close/dismiss buttons are supported on notifications. -->
+    <bool name="config_notificationCloseButtonSupported">false</bool>
+
     <!-- Whether to show GAIA education screen during account login of private space setup.
          OEM/Partner can explicitly opt to disable the screen. -->
     <bool name="config_enableGaiaEducationInPrivateSpace">true</bool>
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index e983427..cdd8557 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -393,6 +393,12 @@
     <bool name="config_wait_for_device_alignment_in_demo_datagram">false</bool>
     <java-symbol type="bool" name="config_wait_for_device_alignment_in_demo_datagram" />
 
+    <!-- Boolean indicating whether to enable MMS to be attempted on IWLAN if possible, even if
+     existing cellular networks already supports IWLAN.
+     -->
+    <bool name="force_iwlan_mms_feature_enabled">false</bool>
+    <java-symbol type="bool" name="force_iwlan_mms_feature_enabled" />
+
     <!-- The time duration in millis after which Telephony will abort the last message datagram
      sending requests. Telephony starts a timer when receiving a last message datagram sending
      request in either OFF, IDLE, or NOT_CONNECTED state. In NOT_CONNECTED, the duration of the
@@ -424,4 +430,11 @@
     <bool name="config_dropboxmanager_persistent_logging_enabled">false</bool>
     <java-symbol type="bool" name="config_dropboxmanager_persistent_logging_enabled" />
 
+    <!-- Telephony satellite gateway class name for handling carrier roaming to satellite is using ESOS messaging. -->
+    <string name="config_satellite_carrier_roaming_esos_provisioned_class" translatable="false"></string>
+    <java-symbol type="string" name="config_satellite_carrier_roaming_esos_provisioned_class" />
+
+    <!-- Telephony satellite gateway intent for handling carrier roaming to satellite is using ESOS messaging. -->
+    <string name="config_satellite_carrier_roaming_esos_provisioned_intent_action" translatable="false"></string>
+    <java-symbol type="string" name="config_satellite_carrier_roaming_esos_provisioned_intent_action" />
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 5fea515..6cba84b 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -355,6 +355,9 @@
     <!-- the padding of the expand icon in the notification header -->
     <dimen name="notification_expand_button_icon_padding">2dp</dimen>
 
+    <!-- the size of the notification close button -->
+    <dimen name="notification_close_button_size">16dp</dimen>
+
     <!-- Vertical margin for the headerless notification content, when content has 1 line -->
     <!-- 16 * 2 (margins) + 24 (1 line) = 56 (notification) -->
     <dimen name="notification_headerless_margin_oneline">16dp</dimen>
diff --git a/core/res/res/values/locale_config.xml b/core/res/res/values/locale_config.xml
index bd93aa9..77d2e87 100644
--- a/core/res/res/values/locale_config.xml
+++ b/core/res/res/values/locale_config.xml
@@ -14,6 +14,11 @@
      limitations under the License.
 -->
 
+<!--
+     ICU Version: 75.1
+     CLDR Data Version: 45
+-->
+
 <resources>
 
     <string-array translatable="false" name="supported_locales">
@@ -88,6 +93,11 @@
         <item>bem-ZM</item> <!-- Bemba (Zambia) -->
         <item>bez-TZ</item> <!-- Bena (Tanzania) -->
         <item>bg-BG</item> <!-- Bulgarian (Bulgaria) -->
+        <item>bgc-IN</item> <!-- Haryanvi (India) -->
+        <item>bgc-IN-u-nu-latn</item> <!-- Haryanvi (India, Western Digits) -->
+        <item>bho-IN</item> <!-- Bhojpuri (India) -->
+        <item>bho-IN-u-nu-latn</item> <!-- Bhojpuri (India, Western Digits) -->
+        <item>blo-BJ</item> <!-- Anii (Benin) -->
         <item>bm-ML</item> <!-- Bambara (Mali) -->
         <item>bn-BD</item> <!-- Bangla (Bangladesh) -->
         <item>bn-BD-u-nu-latn</item> <!-- Bangla (Bangladesh, Western Digits) -->
@@ -108,6 +118,7 @@
         <item>cgg-UG</item> <!-- Chiga (Uganda) -->
         <item>chr-US</item> <!-- Cherokee (United States) -->
         <item>cs-CZ</item> <!-- Czech (Czechia) -->
+        <item>csw-CA</item> <!-- Swampy Cree (Canada) -->
         <item>cv-RU</item> <!-- Chuvash (Russia) -->
         <item>cy-GB</item> <!-- Welsh (United Kingdom) -->
         <item>da-DK</item> <!-- Danish (Denmark) -->
@@ -170,6 +181,7 @@
         <item>en-GU</item> <!-- English (Guam) -->
         <item>en-GY</item> <!-- English (Guyana) -->
         <item>en-HK</item> <!-- English (Hong Kong) -->
+        <item>en-ID</item> <!-- English (Indonesia) -->
         <item>en-IE</item> <!-- English (Ireland) -->
         <item>en-IL</item> <!-- English (Israel) -->
         <item>en-IM</item> <!-- English (Isle of Man) -->
@@ -237,6 +249,7 @@
         <item>en-ZA</item> <!-- English (South Africa) -->
         <item>en-ZM</item> <!-- English (Zambia) -->
         <item>en-ZW</item> <!-- English (Zimbabwe) -->
+        <item>eo-001</item> <!-- Esperanto (world) -->
         <item>es-AR</item> <!-- Spanish (Argentina) -->
         <item>es-BO</item> <!-- Spanish (Bolivia) -->
         <item>es-BR</item> <!-- Spanish (Brazil) -->
@@ -381,6 +394,7 @@
         <item>hu-HU</item> <!-- Hungarian (Hungary) -->
         <item>hy-AM</item> <!-- Armenian (Armenia) -->
         <item>ia-001</item> <!-- Interlingua (world) -->
+        <item>ie-EE</item> <!-- Interlingue (Estonia) -->
         <item>ig-NG</item> <!-- Igbo (Nigeria) -->
         <item>ii-CN</item> <!-- Sichuan Yi (China) -->
         <item>in-ID</item> <!-- Indonesian (Indonesia) -->
@@ -408,6 +422,7 @@
         <item>kln-KE</item> <!-- Kalenjin (Kenya) -->
         <item>km-KH</item> <!-- Khmer (Cambodia) -->
         <item>kn-IN</item> <!-- Kannada (India) -->
+        <item>ko-CN</item> <!-- Korean (China) -->
         <item>ko-KP</item> <!-- Korean (North Korea) -->
         <item>ko-KR</item> <!-- Korean (South Korea) -->
         <item>kok-IN</item> <!-- Konkani (India) -->
@@ -417,12 +432,19 @@
         <item>ksb-TZ</item> <!-- Shambala (Tanzania) -->
         <item>ksf-CM</item> <!-- Bafia (Cameroon) -->
         <item>ksh-DE</item> <!-- Colognian (Germany) -->
+        <item>ku-TR</item> <!-- Kurdish (Türkiye) -->
         <item>kw-GB</item> <!-- Cornish (United Kingdom) -->
+        <item>kxv-Deva-IN</item> <!-- Kuvi (Devanagari, India) -->
+        <item>kxv-Latn-IN</item> <!-- Kuvi (Latin, India) -->
+        <item>kxv-Orya-IN</item> <!-- Kuvi (Odia, India) -->
+        <item>kxv-Telu-IN</item> <!-- Kuvi (Telugu, India) -->
         <item>ky-KG</item> <!-- Kyrgyz (Kyrgyzstan) -->
         <item>lag-TZ</item> <!-- Langi (Tanzania) -->
         <item>lb-LU</item> <!-- Luxembourgish (Luxembourg) -->
         <item>lg-UG</item> <!-- Ganda (Uganda) -->
+        <item>lij-IT</item> <!-- Ligurian (Italy) -->
         <item>lkt-US</item> <!-- Lakota (United States) -->
+        <item>lmo-IT</item> <!-- Lombard (Italy) -->
         <item>ln-AO</item> <!-- Lingala (Angola) -->
         <item>ln-CD</item> <!-- Lingala (Congo - Kinshasa) -->
         <item>ln-CF</item> <!-- Lingala (Central African Republic) -->
@@ -462,6 +484,8 @@
         <item>nb-NO</item> <!-- Norwegian Bokmål (Norway) -->
         <item>nb-SJ</item> <!-- Norwegian Bokmål (Svalbard & Jan Mayen) -->
         <item>nd-ZW</item> <!-- North Ndebele (Zimbabwe) -->
+        <item>nds-DE</item> <!-- Low German (Germany) -->
+        <item>nds-NL</item> <!-- Low German (Netherlands) -->
         <item>ne-IN</item> <!-- Nepali (India) -->
         <item>ne-IN-u-nu-latn</item> <!-- Nepali (India, Western Digits) -->
         <item>ne-NP</item> <!-- Nepali (Nepal) -->
@@ -475,8 +499,12 @@
         <item>nl-SX</item> <!-- Dutch (Sint Maarten) -->
         <item>nn-NO</item> <!-- Norwegian Nynorsk (Norway) -->
         <item>nnh-CM</item> <!-- Ngiemboon (Cameroon) -->
+        <item>nqo-GN</item> <!-- N’Ko (Guinea) -->
+        <item>nqo-GN-u-nu-latn</item> <!-- N’Ko (Guinea, Western Digits) -->
         <item>nus-SS</item> <!-- Nuer (South Sudan) -->
         <item>nyn-UG</item> <!-- Nyankole (Uganda) -->
+        <item>oc-ES</item> <!-- Occitan (Spain) -->
+        <item>oc-FR</item> <!-- Occitan (France) -->
         <item>om-ET</item> <!-- Oromo (Ethiopia) -->
         <item>om-KE</item> <!-- Oromo (Kenya) -->
         <item>or-IN</item> <!-- Odia (India) -->
@@ -487,6 +515,7 @@
         <item>pa-Guru-IN</item> <!-- Punjabi (Gurmukhi, India) -->
         <item>pcm-NG</item> <!-- Nigerian Pidgin (Nigeria) -->
         <item>pl-PL</item> <!-- Polish (Poland) -->
+        <item>prg-PL</item> <!-- Prussian (Poland) -->
         <item>ps-AF</item> <!-- Pashto (Afghanistan) -->
         <item>ps-AF-u-nu-latn</item> <!-- Pashto (Afghanistan, Western Digits) -->
         <item>ps-PK</item> <!-- Pashto (Pakistan) -->
@@ -566,6 +595,9 @@
         <item>sw-KE</item> <!-- Swahili (Kenya) -->
         <item>sw-TZ</item> <!-- Swahili (Tanzania) -->
         <item>sw-UG</item> <!-- Swahili (Uganda) -->
+        <item>syr-IQ</item> <!-- Syriac (Iraq) -->
+        <item>syr-SY</item> <!-- Syriac (Syria) -->
+        <item>szl-PL</item> <!-- Silesian (Poland) -->
         <item>ta-IN</item> <!-- Tamil (India) -->
         <item>ta-LK</item> <!-- Tamil (Sri Lanka) -->
         <item>ta-MY</item> <!-- Tamil (Malaysia) -->
@@ -580,7 +612,7 @@
         <item>tk-TM</item> <!-- Turkmen (Turkmenistan) -->
         <item>to-TO</item> <!-- Tongan (Tonga) -->
         <item>tr-CY</item> <!-- Turkish (Cyprus) -->
-        <item>tr-TR</item> <!-- Turkish (Turkey) -->
+        <item>tr-TR</item> <!-- Turkish (Türkiye) -->
         <item>tt-RU</item> <!-- Tatar (Russia) -->
         <item>twq-NE</item> <!-- Tasawaq (Niger) -->
         <item>tzm-MA</item> <!-- Central Atlas Tamazight (Morocco) -->
@@ -594,11 +626,14 @@
         <item>uz-Arab-AF-u-nu-latn</item> <!-- Uzbek (Arabic, Afghanistan, Western Digits) -->
         <item>uz-Cyrl-UZ</item> <!-- Uzbek (Cyrillic, Uzbekistan) -->
         <item>uz-Latn-UZ</item> <!-- Uzbek (Latin, Uzbekistan) -->
+        <item>vec-IT</item> <!-- Venetian (Italy) -->
         <item>vi-VN</item> <!-- Vietnamese (Vietnam) -->
+        <item>vmw-MZ</item> <!-- Makhuwa (Mozambique) -->
         <item>vun-TZ</item> <!-- Vunjo (Tanzania) -->
         <item>wae-CH</item> <!-- Walser (Switzerland) -->
         <item>wo-SN</item> <!-- Wolof (Senegal) -->
         <item>xh-ZA</item> <!-- Xhosa (South Africa) -->
+        <item>xnr-IN</item> <!-- Kangri (India) -->
         <item>xog-UG</item> <!-- Soga (Uganda) -->
         <item>yav-CM</item> <!-- Yangben (Cameroon) -->
         <item>yo-BJ</item> <!-- Yoruba (Benin) -->
@@ -608,6 +643,7 @@
         <item>yrl-VE</item> <!-- Nheengatu (Venezuela) -->
         <item>yue-Hans-CN</item> <!-- Cantonese (Simplified, China) -->
         <item>yue-Hant-HK</item> <!-- Cantonese (Traditional, Hong Kong) -->
+        <item>za-CN</item> <!-- Zhuang (China) -->
         <item>zgh-MA</item> <!-- Standard Moroccan Tamazight (Morocco) -->
         <item>zh-Hans-CN</item> <!-- Chinese (Simplified, China) -->
         <item>zh-Hans-HK</item> <!-- Chinese (Simplified, Hong Kong) -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 10373a5..6b71f97 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -788,11 +788,7 @@
     <!-- label for item that locks the phone and enforces that it can't be unlocked without strong authentication. [CHAR LIMIT=24] -->
     <string name="global_action_lockdown">Lockdown</string>
 
-    <!-- Text to use when the number in a notification info is too large
-         (greater than status_bar_notification_info_maxnum, defined in
-         values/config.xml) and must be truncated. May need to be localized
-         for most appropriate textual indicator of "more than X".
-         [CHAR LIMIT=4] -->
+    <!-- @deprecated No longer used. -->
     <string name="status_bar_notification_info_overflow">999+</string>
 
     <!-- The divider symbol between different parts of the notification header. not translatable [CHAR LIMIT=1] -->
@@ -3837,6 +3833,11 @@
     <!-- Message of notification shown when Test Harness Mode is enabled. [CHAR LIMIT=NONE] -->
     <string name="test_harness_mode_notification_message">Perform a factory reset to disable Test Harness Mode.</string>
 
+    <!-- Title of notification shown when device is in the wrong Headless System User Mode configuration. [CHAR LIMIT=NONE] -->
+    <string name="wrong_hsum_configuration_notification_title">Wrong HSUM build configuration</string>
+    <!-- Message of notification shown when device is in the wrong Headless System User Mode configuration. [CHAR LIMIT=NONE] -->
+    <string name="wrong_hsum_configuration_notification_message">The Headless System User Mode state of this device differs from its build configuration. Please factory reset the device.</string>
+
     <!-- Title of notification shown when serial console is enabled. [CHAR LIMIT=NONE] -->
     <string name="console_running_notification_title">Serial console enabled</string>
     <!-- Message of notification shown when serial console is enabled. [CHAR LIMIT=NONE] -->
@@ -4844,19 +4845,19 @@
     <!-- Text spoken when accessibility shortcut warning dialog is shown. [CHAR LIMIT=none] -->
     <string name="accessibility_shortcut_spoken_feedback">Release the volume keys. To turn on <xliff:g id="service_name" example="TalkBack">%1$s</xliff:g>, press and hold both volume keys again for 3 seconds.</string>
 
-    <!-- Text appearing in a prompt at the top of UI allowing the user to select a target service or feature to be assigned to the Accessibility button in the navigation bar. [CHAR LIMIT=none]-->
-    <string name="accessibility_button_prompt_text">Choose a feature to use when you tap the accessibility button:</string>
+    <!-- Text appearing in a prompt at the top of UI allowing the user to select a target service or feature to be assigned to the Accessibility button in the navigation bar or in gesture navigation. [CHAR LIMIT=none]-->
+    <string name="accessibility_button_prompt_text">Choose a feature</string>
     <!-- Text appearing in a prompt at the top of UI allowing the user to select a target service or feature to be assigned to the Accessibility button when gesture navigation is enabled [CHAR LIMIT=none] -->
-    <string name="accessibility_gesture_prompt_text">Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):</string>
+    <string name="accessibility_gesture_prompt_text">Choose a feature</string>
     <!-- Text appearing in a prompt at the top of UI allowing the user to select a target service or feature to be assigned to the Accessibility button when gesture navigation and TalkBack is enabled [CHAR LIMIT=none] -->
-    <string name="accessibility_gesture_3finger_prompt_text">Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):</string>
+    <string name="accessibility_gesture_3finger_prompt_text">Choose a feature</string>
 
     <!-- Text describing how to display UI allowing a user to select a target service or feature to be assigned to the Accessibility button in the navigation bar. [CHAR LIMIT=none]-->
-    <string name="accessibility_button_instructional_text">To switch between features, touch &amp; hold the accessibility button.</string>
+    <string name="accessibility_button_instructional_text">The feature will open next time you tap the accessibility button</string>
     <!-- Text describing how to display UI allowing a user to select a target service or feature to be assigned to the Accessibility button when gesture navigation is enabled. [CHAR LIMIT=none] -->
-    <string name="accessibility_gesture_instructional_text">To switch between features, swipe up with two fingers and hold.</string>
+    <string name="accessibility_gesture_instructional_text">The feature will open next time you use this shortcut. Swipe up with 2 fingers from the bottom of your screen and release quickly.</string>
     <!-- Text describing how to display UI allowing a user to select a target service or feature to be assigned to the Accessibility button when gesture navigation and TalkBack is enabled. [CHAR LIMIT=none] -->
-    <string name="accessibility_gesture_3finger_instructional_text">To switch between features, swipe up with three fingers and hold.</string>
+    <string name="accessibility_gesture_3finger_instructional_text">The feature will open next time you use this shortcut. Swipe up with 3 fingers from the bottom of your screen and release quickly.</string>
 
     <!-- Text used to describe system navigation features, shown within a UI allowing a user to assign system magnification features to the Accessibility button in the navigation bar. -->
     <string name="accessibility_magnification_chooser_text">Magnification</string>
@@ -5430,6 +5431,10 @@
     <string name="call_notification_screening_text">Screening an incoming call</string>
 
     <string name="default_notification_channel_label">Uncategorized</string>
+    <string name="promotional_notification_channel_label">Promotions</string>
+    <string name="social_notification_channel_label">Social</string>
+    <string name="news_notification_channel_label">News</string>
+    <string name="recs_notification_channel_label">Recommendations</string>
 
     <string name="importance_from_user">You set the importance of these notifications.</string>
     <string name="importance_from_person">This is important because of the people involved.</string>
@@ -6503,19 +6508,30 @@
     <!-- Fingerprint dangling notification title -->
     <string name="fingerprint_dangling_notification_title">Set up Fingerprint Unlock again</string>
     <!-- Fingerprint dangling notification content for only 1 fingerprint deleted -->
-    <string name="fingerprint_dangling_notification_msg_1"><xliff:g id="fingerprint">%s</xliff:g> wasn\'t working well and was deleted</string>
+    <string name="fingerprint_dangling_notification_msg_1"><xliff:g id="fingerprint">%s</xliff:g> can no longer be recognized.</string>
     <!-- Fingerprint dangling notification content for more than 1 fingerprints deleted -->
-    <string name="fingerprint_dangling_notification_msg_2"><xliff:g id="fingerprint">%1$s</xliff:g> and <xliff:g id="fingerprint">%2$s</xliff:g> weren\'t working well and were deleted</string>
+    <string name="fingerprint_dangling_notification_msg_2"><xliff:g id="fingerprint">%1$s</xliff:g> and <xliff:g id="fingerprint">%2$s</xliff:g> can no longer be recognized.</string>
     <!-- Fingerprint dangling notification content for only 1 fingerprint deleted and no fingerprint left-->
-    <string name="fingerprint_dangling_notification_msg_all_deleted_1"><xliff:g id="fingerprint">%s</xliff:g> wasn\'t working well and was deleted. Set it up again to unlock your phone with fingerprint.</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_1"><xliff:g id="fingerprint">%s</xliff:g> can no longer be recognized. Set up Fingerprint Unlock again.</string>
     <!-- Fingerprint dangling notification content for more than 1 fingerprints deleted and no fingerprint left  -->
-    <string name="fingerprint_dangling_notification_msg_all_deleted_2"><xliff:g id="fingerprint">%1$s</xliff:g> and <xliff:g id="fingerprint">%2$s</xliff:g> weren\'t working well and were deleted. Set them up again to unlock your phone with your fingerprint.</string>
+    <string name="fingerprint_dangling_notification_msg_all_deleted_2"><xliff:g id="fingerprint">%1$s</xliff:g> and <xliff:g id="fingerprint">%2$s</xliff:g> can no longer be recognized. Set up Fingerprint Unlock again.</string>
     <!-- Face dangling notification title -->
     <string name="face_dangling_notification_title">Set up Face Unlock again</string>
     <!-- Face dangling notification content -->
-    <string name="face_dangling_notification_msg">Your face model wasn\'t working well and was deleted. Set it up again to unlock your phone with face.</string>
+    <string name="face_dangling_notification_msg">Your face model can no longer be recognized. Set up Face Unlock again.</string>
     <!-- Biometric dangling notification "set up" action button -->
     <string name="biometric_dangling_notification_action_set_up">Set up</string>
     <!-- Biometric dangling notification "Not now" action button -->
     <string name="biometric_dangling_notification_action_not_now">Not now</string>
+
+
+    <!-- Background user sound notification related messages -->
+    <!-- Notification title when sound comes from an alarm or timer on background user [CHAR LIMIT=NOTIF_TITLE]-->
+    <string name="bg_user_sound_notification_title_alarm">Alarm for <xliff:g id="user_name" example="John Doe">%s</xliff:g></string>
+    <!-- Notification action button to prompt user switch to the background user [CHAR LIMIT=NONE] -->
+    <string name="bg_user_sound_notification_button_switch_user">Switch user</string>
+    <!-- Notification action button to mute the sound from the background user [CHAR LIMIT=NONE] -->
+    <string name="bg_user_sound_notification_button_mute">Mute</string>
+    <!-- Notification text to mute the sound from the background user [CHAR LIMIT=NOTIF_BODY]-->
+    <string name="bg_user_sound_notification_message">Tap to mute sound</string>
 </resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 50c3b1a..aabc8ca 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1527,6 +1527,24 @@
     </style>
 
     <!-- @hide -->
+    <style name="PointerIconVectorStyleStrokeWhite">
+        <item name="pointerIconVectorStroke">@color/white</item>
+        <item name="pointerIconVectorStrokeInverse">@color/black</item>
+    </style>
+
+    <!-- @hide -->
+    <style name="PointerIconVectorStyleStrokeBlack">
+        <item name="pointerIconVectorStroke">@color/black</item>
+        <item name="pointerIconVectorStrokeInverse">@color/white</item>
+    </style>
+
+    <!-- @hide -->
+    <style name="PointerIconVectorStyleStrokeNone">
+        <item name="pointerIconVectorStroke">@color/transparent</item>
+        <item name="pointerIconVectorStrokeInverse">@color/transparent</item>
+    </style>
+
+    <!-- @hide -->
     <style name="aerr_list_item" parent="Widget.Material.Light.Button.Borderless">
         <item name="minHeight">?attr/listPreferredItemHeightSmall</item>
         <item name="textAppearance">?attr/textAppearanceListItemSmall</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 06a4d55..d25f59d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -521,6 +521,7 @@
   <java-symbol type="bool" name="config_preferKeepClearForFocus" />
   <java-symbol type="bool" name="config_hibernationDeletesOatArtifactsEnabled"/>
   <java-symbol type="integer" name="config_defaultAnalogClockSecondsHandFps"/>
+  <java-symbol type="bool" name="config_notificationCloseButtonSupported"/>
   <java-symbol type="bool" name="config_enableGaiaEducationInPrivateSpace"/>
 
   <java-symbol type="color" name="tab_indicator_text_v4" />
@@ -1703,6 +1704,10 @@
   <java-symbol type="style" name="PointerIconVectorStyleFillPink" />
   <java-symbol type="style" name="PointerIconVectorStyleFillBlue" />
   <java-symbol type="attr" name="pointerIconVectorFill" />
+  <java-symbol type="style" name="PointerIconVectorStyleStrokeWhite" />
+  <java-symbol type="style" name="PointerIconVectorStyleStrokeBlack" />
+  <java-symbol type="style" name="PointerIconVectorStyleStrokeNone" />
+  <java-symbol type="attr" name="pointerIconVectorStroke" />
   <java-symbol type="style" name="TextAppearance.DeviceDefault.Notification.Title" />
   <java-symbol type="style" name="TextAppearance.DeviceDefault.Notification.Info" />
 
@@ -1752,6 +1757,15 @@
   <java-symbol type="anim" name="task_fragment_clear_top_close_exit" />
   <java-symbol type="anim" name="task_fragment_clear_top_open_enter" />
   <java-symbol type="anim" name="task_fragment_clear_top_open_exit" />
+  <java-symbol type="anim" name="overlay_task_fragment_open_from_left" />
+  <java-symbol type="anim" name="overlay_task_fragment_open_from_top" />
+  <java-symbol type="anim" name="overlay_task_fragment_open_from_right" />
+  <java-symbol type="anim" name="overlay_task_fragment_open_from_bottom" />
+  <java-symbol type="anim" name="overlay_task_fragment_change" />
+  <java-symbol type="anim" name="overlay_task_fragment_close_to_left" />
+  <java-symbol type="anim" name="overlay_task_fragment_close_to_top" />
+  <java-symbol type="anim" name="overlay_task_fragment_close_to_right" />
+  <java-symbol type="anim" name="overlay_task_fragment_close_to_bottom" />
 
   <java-symbol type="array" name="config_autoRotationTiltTolerance" />
   <java-symbol type="array" name="config_longPressVibePattern" />
@@ -1992,6 +2006,7 @@
   <java-symbol type="array" name="config_notificationFallbackVibeWaveform" />
   <java-symbol type="bool" name="config_enableServerNotificationEffectsForAutomotive" />
   <java-symbol type="bool" name="config_useAttentionLight" />
+  <java-symbol type="bool" name="config_enableNotificationAccessibilityEvents" />
   <java-symbol type="bool" name="config_adaptive_sleep_available" />
   <java-symbol type="bool" name="config_camera_autorotate"/>
   <java-symbol type="bool" name="config_animateScreenLights" />
@@ -2111,7 +2126,7 @@
   <java-symbol type="integer" name="config_defaultVibrationAmplitude" />
   <java-symbol type="dimen" name="config_hapticChannelMaxVibrationAmplitude" />
   <java-symbol type="dimen" name="config_keyboardHapticFeedbackFixedAmplitude" />
-  <java-symbol type="bool" name="config_defaultKeyboardVibrationEnabled" />
+  <java-symbol type="bool" name="config_keyboardVibrationSettingsSupported" />
   <java-symbol type="integer" name="config_vibrationWaveformRampStepDuration" />
   <java-symbol type="bool" name="config_ignoreVibrationsOnWirelessCharger" />
   <java-symbol type="integer" name="config_vibrationWaveformRampDownDuration" />
@@ -2152,6 +2167,8 @@
   <java-symbol type="string" name="adbwifi_active_notification_title" />
   <java-symbol type="string" name="test_harness_mode_notification_title" />
   <java-symbol type="string" name="test_harness_mode_notification_message" />
+  <java-symbol type="string" name="wrong_hsum_configuration_notification_title" />
+  <java-symbol type="string" name="wrong_hsum_configuration_notification_message" />
   <java-symbol type="string" name="console_running_notification_title" />
   <java-symbol type="string" name="console_running_notification_message" />
   <java-symbol type="string" name="mte_override_notification_title" />
@@ -2298,9 +2315,6 @@
   <java-symbol type="array" name="config_disabledDreamComponents" />
   <java-symbol type="bool" name="config_dismissDreamOnActivityStart" />
   <java-symbol type="bool" name="config_resetScreenTimeoutOnUnexpectedDreamExit" />
-  <java-symbol type="integer" name="config_dreamOverlayReconnectTimeoutMs" />
-  <java-symbol type="integer" name="config_dreamOverlayMaxReconnectAttempts" />
-  <java-symbol type="integer" name="config_minDreamOverlayDurationMs" />
   <java-symbol type="array" name="config_loggable_dream_prefixes" />
   <java-symbol type="string" name="config_dozeComponent" />
   <java-symbol type="string" name="enable_explore_by_touch_warning_title" />
@@ -3171,6 +3185,7 @@
   <java-symbol type="id" name="header_text_secondary_divider" />
   <java-symbol type="drawable" name="ic_expand_notification" />
   <java-symbol type="drawable" name="ic_collapse_notification" />
+  <java-symbol type="drawable" name="notification_close_button_icon" />
   <java-symbol type="drawable" name="ic_expand_bundle" />
   <java-symbol type="drawable" name="ic_collapse_bundle" />
   <java-symbol type="drawable" name="ic_notification_summary_auto" />
@@ -3877,6 +3892,7 @@
 
   <java-symbol type="string" name="expand_button_content_description_collapsed" />
   <java-symbol type="string" name="expand_button_content_description_expanded" />
+  <java-symbol type="string" name="close_button_text" />
 
   <java-symbol type="string" name="content_description_collapsed" />
   <java-symbol type="string" name="content_description_expanded" />
@@ -4044,6 +4060,7 @@
   <java-symbol type="id" name="snooze_button" />
   <java-symbol type="dimen" name="text_size_body_2_material" />
   <java-symbol type="dimen" name="notification_icon_circle_size" />
+  <java-symbol type="drawable" name="notification_icon_circle" />
   <java-symbol type="dimen" name="messaging_avatar_size" />
   <java-symbol type="dimen" name="messaging_group_sending_progress_size" />
   <java-symbol type="dimen" name="messaging_image_rounding" />
@@ -5044,6 +5061,9 @@
   <java-symbol type="string" name="ui_translation_accessibility_translation_finished" />
 
   <java-symbol type="layout" name="notification_expand_button"/>
+  <java-symbol type="id" name="close_button" />
+  <java-symbol type="layout" name="notification_close_button"/>
+  <java-symbol type="id" name="notification_buttons_column" />
 
   <java-symbol type="bool" name="config_supportsMicToggle" />
   <java-symbol type="bool" name="config_supportsCamToggle" />
@@ -5302,7 +5322,7 @@
   <java-symbol name="customColorThemeApp" type="attr"/>
   <java-symbol name="customColorOnThemeApp" type="attr"/>
   <java-symbol name="customColorThemeAppRing" type="attr"/>
-  <java-symbol name="customColorOnThemeAppRing" type="attr"/>
+  <java-symbol name="customColorThemeNotif" type="attr"/>
   <java-symbol name="customColorBrandA" type="attr"/>
   <java-symbol name="customColorBrandB" type="attr"/>
   <java-symbol name="customColorBrandC" type="attr"/>
@@ -5324,7 +5344,7 @@
   <java-symbol name="system_theme_app_light" type="color"/>
   <java-symbol name="system_on_theme_app_light" type="color"/>
   <java-symbol name="system_theme_app_ring_light" type="color"/>
-  <java-symbol name="system_on_theme_app_ring_light" type="color"/>
+  <java-symbol name="system_theme_notif_light" type="color"/>
   <java-symbol name="system_brand_a_light" type="color"/>
   <java-symbol name="system_brand_b_light" type="color"/>
   <java-symbol name="system_brand_c_light" type="color"/>
@@ -5345,7 +5365,7 @@
   <java-symbol name="system_theme_app_dark" type="color"/>
   <java-symbol name="system_on_theme_app_dark" type="color"/>
   <java-symbol name="system_theme_app_ring_dark" type="color"/>
-  <java-symbol name="system_on_theme_app_ring_dark" type="color"/>
+  <java-symbol name="system_theme_notif_dark" type="color"/>
   <java-symbol name="system_brand_a_dark" type="color"/>
   <java-symbol name="system_brand_b_dark" type="color"/>
   <java-symbol name="system_brand_c_dark" type="color"/>
@@ -5427,6 +5447,7 @@
   <java-symbol type="drawable" name="focus_event_pressed_key_background" />
   <java-symbol type="drawable" name="focus_event_rotary_input_background" />
   <java-symbol type="string" name="config_defaultShutdownVibrationFile" />
+  <java-symbol type="bool" name="config_disableShutdownVibrationInZen" />
   <java-symbol type="string" name="lockscreen_too_many_failed_attempts_countdown" />
 
   <java-symbol type="bool" name="config_enable_a11y_magnification_single_panning" />
@@ -5518,6 +5539,12 @@
   <java-symbol type="string" name="biometric_dangling_notification_action_set_up" />
   <java-symbol type="string" name="biometric_dangling_notification_action_not_now" />
 
+  <!-- Notification bundles -->
+  <java-symbol type="string"  name="promotional_notification_channel_label"/>
+  <java-symbol type="string"  name="social_notification_channel_label"/>
+  <java-symbol type="string"  name="news_notification_channel_label"/>
+  <java-symbol type="string"  name="recs_notification_channel_label"/>
+
   <!-- Priority Modes icons -->
   <java-symbol type="drawable" name="ic_zen_mode_type_bedtime" />
   <java-symbol type="drawable" name="ic_zen_mode_type_driving" />
@@ -5529,4 +5556,9 @@
   <java-symbol type="drawable" name="ic_zen_mode_type_theater" />
   <java-symbol type="drawable" name="ic_zen_mode_type_unknown" />
 
+  <!-- System notification for background user sound -->
+  <java-symbol type="string" name="bg_user_sound_notification_title_alarm" />
+  <java-symbol type="string" name="bg_user_sound_notification_button_switch_user" />
+  <java-symbol type="string" name="bg_user_sound_notification_button_mute" />
+  <java-symbol type="string" name="bg_user_sound_notification_message" />
 </resources>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 24d4938..382ff04 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -292,7 +292,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -410,7 +410,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -527,7 +527,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -646,7 +646,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -764,7 +764,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -890,7 +890,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -1007,7 +1007,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -1123,7 +1123,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -1240,7 +1240,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -1373,7 +1373,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -1491,7 +1491,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -1607,7 +1607,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -1725,7 +1725,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -1842,7 +1842,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -1959,7 +1959,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -2076,7 +2076,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -2193,7 +2193,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -2310,7 +2310,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -2432,7 +2432,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -2547,7 +2547,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -2800,7 +2800,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -2917,7 +2917,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -3033,7 +3033,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -3150,7 +3150,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -3269,7 +3269,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -3387,7 +3387,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -3511,7 +3511,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -3631,7 +3631,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -3750,7 +3750,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -3870,7 +3870,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -3971,7 +3971,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -4072,7 +4072,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -4192,7 +4192,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -4313,7 +4313,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -4432,7 +4432,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -4550,7 +4550,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -4667,7 +4667,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -4784,7 +4784,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -4899,7 +4899,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -5022,7 +5022,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -5126,7 +5126,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -5222,7 +5222,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -5339,7 +5339,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -5440,7 +5440,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -5581,7 +5581,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -5700,7 +5700,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -5845,7 +5845,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -5920,7 +5920,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -5999,7 +5999,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
@@ -6074,7 +6074,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_light</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_light</item>
         <item name="customColorBrandA">@color/system_brand_a_light</item>
         <item name="customColorBrandB">@color/system_brand_b_light</item>
         <item name="customColorBrandC">@color/system_brand_c_light</item>
@@ -6160,7 +6160,7 @@
         <item name="customColorThemeApp">@color/system_theme_app_dark</item>
         <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
         <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
+        <item name="customColorThemeNotif">@color/system_theme_notif_dark</item>
         <item name="customColorBrandA">@color/system_brand_a_dark</item>
         <item name="customColorBrandB">@color/system_brand_b_dark</item>
         <item name="customColorBrandC">@color/system_brand_c_dark</item>
diff --git a/core/res/res/xml/power_profile.xml b/core/res/res/xml/power_profile.xml
index fc63657..f67ad3f 100644
--- a/core/res/res/xml/power_profile.xml
+++ b/core/res/res/xml/power_profile.xml
@@ -33,14 +33,14 @@
        There must be one of these for each display, labeled:
        ambient.on.display0, ambient.on.display1, etc...
 
-       Each display suffix number should match it's ordinal in its display device config.
+       Each display suffix number should match its ordinal in its display device config.
   -->
   <item name="ambient.on.display0">0.1</item>  <!-- ~100mA -->
   <!-- Average battery current draw of display0 while on without backlight.
        There must be one of these for each display, labeled:
        screen.on.display0, screen.on.display1, etc...
 
-       Each display suffix number should match it's ordinal in its display device config.
+       Each display suffix number should match its ordinal in its display device config.
   -->
   <item name="screen.on.display0">0.1</item>  <!-- ~100mA -->
   <!-- Average battery current draw of the backlight at full brightness.
@@ -50,7 +50,7 @@
        There must be one of these for each display, labeled:
        screen.full.display0, screen.full.display1, etc...
 
-       Each display suffix number should match it's ordinal in its display device config.
+       Each display suffix number should match its ordinal in its display device config.
   -->
   <item name="screen.full.display0">0.1</item>  <!-- ~100mA -->
 
diff --git a/core/tests/BroadcastRadioTests/src/android/hardware/radio/RadioMetadataTest.java b/core/tests/BroadcastRadioTests/src/android/hardware/radio/RadioMetadataTest.java
index b3a0aba..db3a2da 100644
--- a/core/tests/BroadcastRadioTests/src/android/hardware/radio/RadioMetadataTest.java
+++ b/core/tests/BroadcastRadioTests/src/android/hardware/radio/RadioMetadataTest.java
@@ -470,6 +470,20 @@
     }
 
     @Test
+    public void equals_forMetadataWithDifferentContents_returnsFalse() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_HD_RADIO_IMPROVED);
+        RadioMetadata metadata1 = mBuilder
+                .putStringArray(RadioMetadata.METADATA_KEY_UFIDS, UFIDS_VALUE)
+                .build();
+        RadioMetadata metadata2 = mBuilder
+                .putStringArray(RadioMetadata.METADATA_KEY_UFIDS, new String[]{"ufid3", "ufid2"})
+                .build();
+
+        mExpect.withMessage("Metadata with the same contents")
+                .that(metadata1).isNotEqualTo(metadata2);
+    }
+
+    @Test
     public void describeContents_forMetadata() {
         RadioMetadata metadata = mBuilder.build();
 
@@ -553,4 +567,25 @@
                 .that(metadata.getBitmap(RadioMetadata.METADATA_KEY_ICON))
                 .isEqualTo(bitmapResized);
     }
+
+    @Test
+    public void toString_containsMetadataValues() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_HD_RADIO_IMPROVED);
+        RadioMetadata metadataExpected = mBuilder
+                .putInt(RadioMetadata.METADATA_KEY_RDS_PI, INT_KEY_VALUE)
+                .putString(RadioMetadata.METADATA_KEY_ARTIST, ARTIST_KEY_VALUE)
+                .putStringArray(RadioMetadata.METADATA_KEY_UFIDS, UFIDS_VALUE)
+                .build();
+
+        String metadateString = metadataExpected.toString();
+
+        mExpect.withMessage("RDS PI value in converted sting for metadata")
+                .that(metadateString).contains(Integer.toString(INT_KEY_VALUE));
+        mExpect.withMessage("Artist value in converted sting for metadata")
+                .that(metadateString).contains(ARTIST_KEY_VALUE);
+        for (int i = 0; i < UFIDS_VALUE.length; i++) {
+            mExpect.withMessage("UFIDs[%s] value in converted sting for metadata", i)
+                    .that(metadateString).contains(UFIDS_VALUE[i]);
+        }
+    }
 }
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java
index f3d4ccf..3fb1554 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AidlTestUtils.java
@@ -15,6 +15,7 @@
  */
 package com.android.server.broadcastradio.aidl;
 
+import android.annotation.Nullable;
 import android.hardware.broadcastradio.IdentifierType;
 import android.hardware.broadcastradio.Metadata;
 import android.hardware.broadcastradio.ProgramIdentifier;
@@ -110,20 +111,25 @@
 
     static ProgramInfo makeHalProgramInfo(
             android.hardware.broadcastradio.ProgramSelector hwSel,
-            ProgramIdentifier logicallyTunedTo, ProgramIdentifier physicallyTunedTo,
-            int hwSignalQuality) {
+            @Nullable ProgramIdentifier logicallyTunedTo,
+            @Nullable ProgramIdentifier physicallyTunedTo, int hwSignalQuality) {
         return makeHalProgramInfo(hwSel, logicallyTunedTo, physicallyTunedTo, hwSignalQuality,
                 new ProgramIdentifier[]{}, new Metadata[]{});
     }
 
     static ProgramInfo makeHalProgramInfo(
             android.hardware.broadcastradio.ProgramSelector hwSel,
-            ProgramIdentifier logicallyTunedTo, ProgramIdentifier physicallyTunedTo,
-            int hwSignalQuality, ProgramIdentifier[] relatedContent, Metadata[] metadata) {
+            @Nullable ProgramIdentifier logicallyTunedTo,
+            @Nullable ProgramIdentifier physicallyTunedTo, int hwSignalQuality,
+            ProgramIdentifier[] relatedContent, Metadata[] metadata) {
         ProgramInfo hwInfo = new ProgramInfo();
         hwInfo.selector = hwSel;
-        hwInfo.logicallyTunedTo = logicallyTunedTo;
-        hwInfo.physicallyTunedTo = physicallyTunedTo;
+        if (logicallyTunedTo != null) {
+            hwInfo.logicallyTunedTo = logicallyTunedTo;
+        }
+        if (physicallyTunedTo != null) {
+            hwInfo.physicallyTunedTo = physicallyTunedTo;
+        }
         hwInfo.signalQuality = hwSignalQuality;
         hwInfo.relatedContent = relatedContent;
         hwInfo.metadata = metadata;
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
index 86a6744..bdc4d25 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
@@ -255,6 +255,17 @@
     }
 
     @Test
+    public void throwOnError_withUnknownErrorCode() {
+        int invalidErrorCode = 100;
+        ServiceSpecificException halException = new ServiceSpecificException(invalidErrorCode);
+
+        RuntimeException thrown = ConversionUtils.throwOnError(halException, "seek");
+
+        expect.withMessage("Exception thrown for unknown error code")
+                .that(thrown).hasMessageThat().contains("seek: unknown error");
+    }
+
+    @Test
     public void propertiesFromHalProperties_idsMatch() {
         expect.withMessage("Properties id")
                 .that(MODULE_PROPERTIES.getId()).isEqualTo(TEST_ID);
@@ -296,7 +307,7 @@
         Map<String, Integer> dabTableExpected = Map.of(DAB_ENTRY_LABEL_1, DAB_ENTRY_FREQUENCY_1,
                 DAB_ENTRY_LABEL_2, DAB_ENTRY_FREQUENCY_2);
 
-        expect.withMessage("Supported program types")
+        expect.withMessage("DAB frequency table")
                 .that(MODULE_PROPERTIES.getDabFrequencyTable())
                 .containsExactlyEntriesIn(dabTableExpected);
     }
@@ -551,13 +562,29 @@
     @Test
     public void programInfoFromHalProgramInfo_withInvalidDabProgramInfo() {
         android.hardware.broadcastradio.ProgramSelector invalidHalDabSelector =
-                AidlTestUtils.makeHalSelector(TEST_HAL_DAB_SID_EXT_ID,
-                new ProgramIdentifier[]{TEST_HAL_DAB_ENSEMBLE_ID, TEST_HAL_DAB_FREQUENCY_ID});
+                AidlTestUtils.makeHalSelector(TEST_HAL_DAB_ENSEMBLE_ID,
+                        new ProgramIdentifier[]{TEST_HAL_DAB_FREQUENCY_ID});
+        ProgramInfo halProgramInfo = AidlTestUtils.makeHalProgramInfo(invalidHalDabSelector,
+                /* logicallyTunedTo= */ null, /* physicallyTunedTo= */ null,
+                TEST_SIGNAL_QUALITY);
+
+        RadioManager.ProgramInfo programInfo =
+                ConversionUtils.programInfoFromHalProgramInfo(halProgramInfo);
+
+        expect.withMessage("Invalid DAB program info with incorrect type of physically tuned to id")
+                .that(programInfo).isNull();
+    }
+
+    @Test
+    public void tunedProgramInfoFromHalProgramInfo_withInvalidDabProgramInfo() {
+        android.hardware.broadcastradio.ProgramSelector invalidHalDabSelector =
+                AidlTestUtils.makeHalSelector(TEST_HAL_DAB_SID_EXT_ID, new ProgramIdentifier[]{
+                        TEST_HAL_DAB_ENSEMBLE_ID, TEST_HAL_DAB_FREQUENCY_ID});
         ProgramInfo halProgramInfo = AidlTestUtils.makeHalProgramInfo(invalidHalDabSelector,
                 TEST_HAL_DAB_SID_EXT_ID, TEST_HAL_DAB_ENSEMBLE_ID, TEST_SIGNAL_QUALITY);
 
         RadioManager.ProgramInfo programInfo =
-                ConversionUtils.programInfoFromHalProgramInfo(halProgramInfo);
+                ConversionUtils.tunedProgramInfoFromHalProgramInfo(halProgramInfo);
 
         expect.withMessage("Invalid DAB program info with incorrect type of physically tuned to id")
                 .that(programInfo).isNull();
@@ -621,7 +648,7 @@
     @Test
     public void programInfoMeetsSdkVersionRequirement_withLowerVersionIdForRelatedContent() {
         RadioManager.ProgramInfo dabProgramInfo = new RadioManager.ProgramInfo(
-                TEST_DAB_SELECTOR_LEGACY, TEST_DAB_SID_EXT_ID, TEST_DAB_FREQUENCY_ID,
+                TEST_DAB_SELECTOR_LEGACY, TEST_DAB_SID_EXT_LEGACY_ID, TEST_DAB_FREQUENCY_ID,
                 List.of(TEST_DAB_SID_EXT_ID), /* infoFlags= */ 0, TEST_SIGNAL_QUALITY,
                 new RadioMetadata.Builder().build(), new ArrayMap<>());
 
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ProgramInfoCacheTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ProgramInfoCacheTest.java
index d64fcaf..b1856719 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ProgramInfoCacheTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ProgramInfoCacheTest.java
@@ -189,13 +189,16 @@
 
     @Test
     public void updateFromHalProgramListChunk_withInvalidChunk() {
-        RadioManager.ProgramInfo invalidDabInfo = AidlTestUtils.makeProgramInfo(TEST_DAB_SELECTOR,
-                TEST_DAB_DMB_SID_EXT_ID, TEST_DAB_ENSEMBLE_ID, TEST_SIGNAL_QUALITY);
+        ProgramInfo invalidHalDabInfo = AidlTestUtils.makeHalProgramInfo(
+                AidlTestUtils.makeHalSelector(
+                        ConversionUtils.identifierToHalProgramIdentifier(TEST_DAB_ENSEMBLE_ID),
+                        new ProgramIdentifier[]{}), /* logicallyTunedTo= */ null,
+                /* physicallyTunedTo= */ null, TEST_SIGNAL_QUALITY);
         ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null,
                 /* complete= */ false);
         ProgramListChunk chunk = AidlTestUtils.makeHalChunk(/* purge= */ false,
-                /* complete= */ true, new ProgramInfo[]{AidlTestUtils.programInfoToHalProgramInfo(
-                        invalidDabInfo)}, new ProgramIdentifier[]{});
+                /* complete= */ true, new ProgramInfo[]{invalidHalDabInfo},
+                new ProgramIdentifier[]{});
 
         cache.updateFromHalProgramListChunk(chunk);
 
@@ -447,10 +450,10 @@
                 /* complete= */ false, TEST_FM_INFO, TEST_RDS_INFO, TEST_DAB_INFO);
         ProgramInfo[] halModified = new android.hardware.broadcastradio.ProgramInfo[1];
         halModified[0] = AidlTestUtils.makeHalProgramInfo(
-                ConversionUtils.programSelectorToHalProgramSelector(TEST_DAB_SELECTOR_ALTERNATIVE),
-                ConversionUtils.identifierToHalProgramIdentifier(TEST_DAB_FREQUENCY_ID_ALTERNATIVE),
-                ConversionUtils.identifierToHalProgramIdentifier(TEST_DAB_FREQUENCY_ID_ALTERNATIVE),
-                TEST_SIGNAL_QUALITY);
+                AidlTestUtils.makeHalSelector(
+                        ConversionUtils.identifierToHalProgramIdentifier(TEST_DAB_ENSEMBLE_ID),
+                        new ProgramIdentifier[]{}), /* logicallyTunedTo= */ null,
+                /* physicallyTunedTo= */ null, TEST_SIGNAL_QUALITY);
         ProgramIdentifier[] halRemoved = new android.hardware.broadcastradio.ProgramIdentifier[1];
         halRemoved[0] = new android.hardware.broadcastradio.ProgramIdentifier();
         ProgramListChunk halChunk = AidlTestUtils.makeHalChunk(/* purge= */ false,
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ConvertTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ConvertTest.java
index 98641ef..c5c3a61 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ConvertTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ConvertTest.java
@@ -32,6 +32,7 @@
 import android.hardware.radio.ProgramSelector;
 import android.hardware.radio.RadioManager;
 import android.hardware.radio.RadioMetadata;
+import android.os.ParcelableException;
 import android.util.ArrayMap;
 
 import com.google.common.truth.Expect;
@@ -89,6 +90,15 @@
     }
 
     @Test
+    public void throwOnError_withUnknownErrorCode() {
+        ParcelableException thrown = assertThrows(ParcelableException.class, () ->
+                Convert.throwOnError("tune", /* result= */ 1000));
+
+        expect.withMessage("Exception for unknown error code").that(thrown)
+                .hasMessageThat().contains("unknown error");
+    }
+
+    @Test
     public void propertiesFromHalProperties_idsMatch() {
         expect.withMessage("Properties id")
                 .that(MODULE_PROPERTIES.getId()).isEqualTo(TEST_ID);
@@ -232,6 +242,12 @@
     }
 
     @Test
+    public void vendorInfoFromHalVendorKeyValues_withNull() {
+        expect.withMessage("Null vendor info converted from HAL")
+                .that(Convert.vendorInfoFromHal(/* info= */ null)).isEmpty();
+    }
+
+    @Test
     public void vendorInfoFromHalVendorKeyValues_withNullElements() {
         VendorKeyValue halVendorInfo = new VendorKeyValue();
         halVendorInfo.key = null;
diff --git a/core/tests/PlatformCompatFramework/src/com/android/internal/compat/ChangeReporterTest.java b/core/tests/PlatformCompatFramework/src/com/android/internal/compat/ChangeReporterTest.java
index 12a42f9..ed5e4af 100644
--- a/core/tests/PlatformCompatFramework/src/com/android/internal/compat/ChangeReporterTest.java
+++ b/core/tests/PlatformCompatFramework/src/com/android/internal/compat/ChangeReporterTest.java
@@ -37,15 +37,20 @@
         long myChangeId = 500L, otherChangeId = 600L;
         int myState = ChangeReporter.STATE_ENABLED, otherState = ChangeReporter.STATE_DISABLED;
 
-        assertTrue(reporter.shouldWriteToStatsLog(myUid, myChangeId, myState));
+        assertTrue(reporter.shouldWriteToStatsLog(false,
+                reporter.isAlreadyReported(myUid, myChangeId, myState)));
         reporter.reportChange(myUid, myChangeId, myState);
 
         // Same report will not be logged again.
-        assertFalse(reporter.shouldWriteToStatsLog(myUid, myChangeId, myState));
+        assertFalse(reporter.shouldWriteToStatsLog(false,
+                reporter.isAlreadyReported(myUid, myChangeId, myState)));
         // Other reports will be logged.
-        assertTrue(reporter.shouldWriteToStatsLog(otherUid, myChangeId, myState));
-        assertTrue(reporter.shouldWriteToStatsLog(myUid, otherChangeId, myState));
-        assertTrue(reporter.shouldWriteToStatsLog(myUid, myChangeId, otherState));
+        assertTrue(reporter.shouldWriteToStatsLog(false,
+                reporter.isAlreadyReported(otherUid, myChangeId, myState)));
+        assertTrue(reporter.shouldWriteToStatsLog(false,
+                reporter.isAlreadyReported(myUid, otherChangeId, myState)));
+        assertTrue(reporter.shouldWriteToStatsLog(false,
+                reporter.isAlreadyReported(myUid, myChangeId, otherState)));
     }
 
     @Test
@@ -55,15 +60,18 @@
         long myChangeId = 500L;
         int myState = ChangeReporter.STATE_ENABLED;
 
-        assertTrue(reporter.shouldWriteToStatsLog(myUid, myChangeId, myState));
+        assertTrue(reporter.shouldWriteToStatsLog(false,
+                reporter.isAlreadyReported(myUid, myChangeId, myState)));
         reporter.reportChange(myUid, myChangeId, myState);
 
         // Same report will not be logged again.
-        assertFalse(reporter.shouldWriteToStatsLog(myUid, myChangeId, myState));
+        assertFalse(reporter.shouldWriteToStatsLog(false,
+                reporter.isAlreadyReported(myUid, myChangeId, myState)));
         reporter.resetReportedChanges(myUid);
 
         // Same report will be logged again after reset.
-        assertTrue(reporter.shouldWriteToStatsLog(myUid, myChangeId, myState));
+        assertTrue(reporter.shouldWriteToStatsLog(false,
+                reporter.isAlreadyReported(myUid, myChangeId, myState)));
     }
 
     @Test
@@ -196,4 +204,21 @@
         // off.
         assertTrue(reporter.shouldWriteToDebug(myUid, myChangeId, myDisabledState, false));
     }
+
+    @Test
+    public void testDontLogSystemApps() {
+        // Verify we don't log an app if we know it's a system app when source is system server.
+        ChangeReporter systemServerReporter =
+                new ChangeReporter(ChangeReporter.SOURCE_SYSTEM_SERVER);
+
+        assertFalse(systemServerReporter.shouldWriteToStatsLog(true, false));
+        assertFalse(systemServerReporter.shouldWriteToStatsLog(true, true));
+
+        // Verify we don't log an app if we know it's a system app when source is unknown.
+        ChangeReporter unknownReporter =
+                new ChangeReporter(ChangeReporter.SOURCE_UNKNOWN_SOURCE);
+
+        assertFalse(unknownReporter.shouldWriteToStatsLog(true, false));
+        assertFalse(unknownReporter.shouldWriteToStatsLog(true, true));
+    }
 }
diff --git a/core/tests/bugreports/Android.bp b/core/tests/bugreports/Android.bp
index 7c1ac48..15e07e5 100644
--- a/core/tests/bugreports/Android.bp
+++ b/core/tests/bugreports/Android.bp
@@ -30,6 +30,7 @@
         "android.test.base",
     ],
     static_libs: [
+        "android.tracing.flags-aconfig-java",
         "androidx.test.rules",
         "androidx.test.uiautomator_uiautomator",
         "truth",
diff --git a/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java b/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java
index 8072d69..7294d4c 100644
--- a/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java
+++ b/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java
@@ -71,6 +71,7 @@
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
@@ -102,17 +103,11 @@
     // associated with the bugreport).
     private static final String INTENT_BUGREPORT_FINISHED =
             "com.android.internal.intent.action.BUGREPORT_FINISHED";
-    private static final String EXTRA_BUGREPORT = "android.intent.extra.BUGREPORT";
-    private static final String EXTRA_SCREENSHOT = "android.intent.extra.SCREENSHOT";
 
-    private static final Path[] UI_TRACES_PREDUMPED = {
+    private ArrayList<Path> mUiTracesPreDumped = new ArrayList<>(Arrays.asList(
             Paths.get("/data/misc/perfetto-traces/bugreport/systrace.pftrace"),
-            Paths.get("/data/misc/wmtrace/ime_trace_clients.winscope"),
-            Paths.get("/data/misc/wmtrace/ime_trace_managerservice.winscope"),
-            Paths.get("/data/misc/wmtrace/ime_trace_service.winscope"),
-            Paths.get("/data/misc/wmtrace/wm_trace.winscope"),
-            Paths.get("/data/misc/wmtrace/wm_log.winscope"),
-    };
+            Paths.get("/data/misc/wmtrace/wm_trace.winscope")
+    ));
 
     private Handler mHandler;
     private Executor mExecutor;
@@ -124,6 +119,17 @@
 
     @Before
     public void setup() throws Exception {
+        if (!android.tracing.Flags.perfettoIme()) {
+            mUiTracesPreDumped.add(Paths.get("/data/misc/wmtrace/ime_trace_clients.winscope"));
+            mUiTracesPreDumped.add(
+                    Paths.get("/data/misc/wmtrace/ime_trace_managerservice.winscope"));
+            mUiTracesPreDumped.add(Paths.get("/data/misc/wmtrace/ime_trace_service.winscope"));
+        }
+
+        if (!android.tracing.Flags.perfettoProtologTracing()) {
+            mUiTracesPreDumped.add(Paths.get("/data/misc/wmtrace/wm_log.winscope"));
+        }
+
         mHandler = createHandler();
         mExecutor = (runnable) -> {
             if (mHandler != null) {
@@ -206,7 +212,7 @@
 
         mBrm.preDumpUiData();
         waitTillDumpstateExitedOrTimeout();
-        List<File> expectedPreDumpedTraceFiles = copyFiles(UI_TRACES_PREDUMPED);
+        List<File> expectedPreDumpedTraceFiles = copyFiles(mUiTracesPreDumped);
 
         BugreportCallbackImpl callback = new BugreportCallbackImpl();
         mBrm.startBugreport(mBugreportFd, null, fullWithUsePreDumpFlag(), mExecutor,
@@ -220,9 +226,9 @@
         assertThat(mBugreportFile.length()).isGreaterThan(0L);
         assertFdsAreClosed(mBugreportFd);
 
-        assertThatBugreportContainsFiles(UI_TRACES_PREDUMPED);
+        assertThatBugreportContainsFiles(mUiTracesPreDumped);
 
-        List<File> actualPreDumpedTraceFiles = extractFilesFromBugreport(UI_TRACES_PREDUMPED);
+        List<File> actualPreDumpedTraceFiles = extractFilesFromBugreport(mUiTracesPreDumped);
         assertThatAllFileContentsAreEqual(actualPreDumpedTraceFiles, expectedPreDumpedTraceFiles);
     }
 
@@ -235,9 +241,9 @@
         // In some corner cases, data dumped as part of the full bugreport could be the same as the
         // pre-dumped data and this test would fail. Hence, here we create fake/artificial
         // pre-dumped data that we know it won't match with the full bugreport data.
-        createFakeTraceFiles(UI_TRACES_PREDUMPED);
+        createFakeTraceFiles(mUiTracesPreDumped);
 
-        List<File> preDumpedTraceFiles = copyFiles(UI_TRACES_PREDUMPED);
+        List<File> preDumpedTraceFiles = copyFiles(mUiTracesPreDumped);
 
         BugreportCallbackImpl callback = new BugreportCallbackImpl();
         mBrm.startBugreport(mBugreportFd, null, full(), mExecutor,
@@ -251,9 +257,9 @@
         assertThat(mBugreportFile.length()).isGreaterThan(0L);
         assertFdsAreClosed(mBugreportFd);
 
-        assertThatBugreportContainsFiles(UI_TRACES_PREDUMPED);
+        assertThatBugreportContainsFiles(mUiTracesPreDumped);
 
-        List<File> actualTraceFiles = extractFilesFromBugreport(UI_TRACES_PREDUMPED);
+        List<File> actualTraceFiles = extractFilesFromBugreport(mUiTracesPreDumped);
         assertThatAllFileContentsAreDifferent(preDumpedTraceFiles, actualTraceFiles);
     }
 
@@ -270,7 +276,7 @@
         // 1. Pre-dump data
         // 2. Start bugreport + "use pre-dump" flag (USE AND REMOVE THE PRE-DUMP FROM DISK)
         // 3. Start bugreport + "use pre-dump" flag (NO PRE-DUMP AVAILABLE ON DISK)
-        removeFilesIfNeeded(UI_TRACES_PREDUMPED);
+        removeFilesIfNeeded(mUiTracesPreDumped);
 
         // Start bugreport with "use predump" flag. Because the pre-dumped data is not available
         // the flag will be ignored and data will be dumped as in normal flow.
@@ -286,7 +292,7 @@
         assertThat(mBugreportFile.length()).isGreaterThan(0L);
         assertFdsAreClosed(mBugreportFd);
 
-        assertThatBugreportContainsFiles(UI_TRACES_PREDUMPED);
+        assertThatBugreportContainsFiles(mUiTracesPreDumped);
     }
 
     @Test
@@ -555,7 +561,7 @@
         );
     }
 
-    private void assertThatBugreportContainsFiles(Path[] paths)
+    private void assertThatBugreportContainsFiles(List<Path> paths)
             throws IOException {
         List<Path> entries = listZipArchiveEntries(mBugreportFile);
         for (Path pathInDevice : paths) {
@@ -564,7 +570,7 @@
         }
     }
 
-    private List<File> extractFilesFromBugreport(Path[] paths) throws Exception {
+    private List<File> extractFilesFromBugreport(List<Path> paths) throws Exception {
         List<File> files = new ArrayList<File>();
         for (Path pathInDevice : paths) {
             Path pathInArchive = Paths.get("FS" + pathInDevice.toString());
@@ -614,7 +620,7 @@
         return extractedFile;
     }
 
-    private static void createFakeTraceFiles(Path[] paths) throws Exception {
+    private static void createFakeTraceFiles(List<Path> paths) throws Exception {
         File src = createTempFile("fake", ".data");
         Files.write("fake data".getBytes(StandardCharsets.UTF_8), src);
 
@@ -631,7 +637,7 @@
         );
     }
 
-    private static List<File> copyFiles(Path[] paths) throws Exception {
+    private static List<File> copyFiles(List<Path> paths) throws Exception {
         ArrayList<File> files = new ArrayList<File>();
         for (Path src : paths) {
             File dst = createTempFile(src.getFileName().toString(), ".copy");
@@ -643,7 +649,7 @@
         return files;
     }
 
-    private static void removeFilesIfNeeded(Path[] paths) throws Exception {
+    private static void removeFilesIfNeeded(List<Path> paths) throws Exception {
         for (Path path : paths) {
             InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand(
                     "rm -f " + path.toString()
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 41696df..d277169 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -63,6 +63,7 @@
         "-c fa",
     ],
     static_libs: [
+        "A11yChecker",
         "collector-device-lib-platform",
         "frameworks-base-testutils",
         "core-test-rules", // for libcore.dalvik.system.CloseGuardSupport
diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java
index b64eeca..ef6ff05 100644
--- a/core/tests/coretests/src/android/app/NotificationTest.java
+++ b/core/tests/coretests/src/android/app/NotificationTest.java
@@ -84,6 +84,8 @@
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.Presubmit;
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.text.Spannable;
@@ -545,12 +547,26 @@
     }
 
     @Test
+    @DisableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
     public void testBuilder_setSilent_emptyGroupKey_groupKeySilent() {
         Notification emptyGroupKeyNotif = new Notification.Builder(mContext, "channelId")
                 .setGroup("")
                 .setSilent(true)
                 .build();
-        assertEquals(GROUP_KEY_SILENT, emptyGroupKeyNotif.getGroup());
+        assertThat(emptyGroupKeyNotif.getGroup()).isEqualTo(GROUP_KEY_SILENT);
+        assertThat(emptyGroupKeyNotif.isSilent()).isTrue();
+    }
+
+    @Test
+    @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
+    public void testBuilder_setSilent_flagSilent() {
+        final String groupKey = "groupKey";
+        Notification emptyGroupKeyNotif = new Notification.Builder(mContext, "channelId")
+            .setGroup(groupKey)
+            .setSilent(true)
+            .build();
+        assertThat(emptyGroupKeyNotif.getGroup()).isEqualTo(groupKey);
+        assertThat(emptyGroupKeyNotif.isSilent()).isTrue();
     }
 
     @Test
@@ -804,6 +820,7 @@
     }
 
     @Test
+    @Ignore // b/347089000 - Restore or delete
     public void testColors_ensureColors_colorized_producesValidPalette_white() {
         validateColorizedPaletteForColor(Color.WHITE);
     }
diff --git a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java
index ee1d1e1..0b270d4 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionListenerControllerTest.java
@@ -20,9 +20,6 @@
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
-import static com.android.window.flags.Flags.FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG;
-import static com.android.window.flags.Flags.FLAG_WINDOW_TOKEN_CONFIG_THREAD_SAFE;
-
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -105,8 +102,6 @@
 
     @Before
     public void setup() {
-        mSetFlagsRule.enableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
         MockitoAnnotations.initMocks(this);
         mDisplayManager = new DisplayManagerGlobal(mIDisplayManager);
         mHandler = getInstrumentation().getContext().getMainThreadHandler();
@@ -192,8 +187,6 @@
 
     @Test
     public void testWindowTokenClient_onConfigurationChanged() {
-        mSetFlagsRule.enableFlags(FLAG_WINDOW_TOKEN_CONFIG_THREAD_SAFE);
-
         doNothing().when(mController).onContextConfigurationPreChanged(any());
         doNothing().when(mController).onContextConfigurationPostChanged(any());
 
diff --git a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java
index 5272416..79659ca 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java
@@ -16,22 +16,16 @@
 
 package android.app.servertransaction;
 
-import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
-
-import static com.android.window.flags.Flags.FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG;
-
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
 import android.app.ClientTransactionHandler;
 import android.platform.test.annotations.Presubmit;
-import android.platform.test.flag.junit.SetFlagsRule;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -49,24 +43,8 @@
 @Presubmit
 public class ClientTransactionTests {
 
-    @Rule
-    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
-
     @Test
     public void testPreExecute() {
-        mSetFlagsRule.disableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
-        testPreExecuteInner();
-    }
-
-    @Test
-    public void testPreExecute_bundleClientTransaction() {
-        mSetFlagsRule.enableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
-        testPreExecuteInner();
-    }
-
-    private void testPreExecuteInner() {
         final ClientTransactionItem callback1 = mock(ClientTransactionItem.class);
         final ClientTransactionItem callback2 = mock(ClientTransactionItem.class);
         final ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class);
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
index 935bc75..73b7447 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
@@ -25,9 +25,6 @@
 import static android.app.servertransaction.ActivityLifecycleItem.ON_STOP;
 import static android.app.servertransaction.ActivityLifecycleItem.PRE_ON_CREATE;
 import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED;
-import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
-
-import static com.android.window.flags.Flags.FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
@@ -54,14 +51,12 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.platform.test.annotations.Presubmit;
-import android.platform.test.flag.junit.SetFlagsRule;
 import android.util.ArrayMap;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.InOrder;
@@ -88,9 +83,6 @@
 @Presubmit
 public class TransactionExecutorTests {
 
-    @Rule
-    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
-
     @Mock
     private ClientTransactionHandler mTransactionHandler;
     @Mock
@@ -248,19 +240,6 @@
 
     @Test
     public void testTransactionResolution() {
-        mSetFlagsRule.disableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
-        testTransactionResolutionInner();
-    }
-
-    @Test
-    public void testTransactionResolution_bundleClientTransaction() {
-        mSetFlagsRule.enableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
-        testTransactionResolutionInner();
-    }
-
-    private void testTransactionResolutionInner() {
         ClientTransactionItem callback1 = mock(ClientTransactionItem.class);
         when(callback1.getPostExecutionState()).thenReturn(UNDEFINED);
         ClientTransactionItem callback2 = mock(ClientTransactionItem.class);
@@ -284,19 +263,6 @@
 
     @Test
     public void testDoNotLaunchDestroyedActivity() {
-        mSetFlagsRule.disableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
-        testDoNotLaunchDestroyedActivityInner();
-    }
-
-    @Test
-    public void testDoNotLaunchDestroyedActivity_bundleClientTransaction() {
-        mSetFlagsRule.enableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
-        testDoNotLaunchDestroyedActivityInner();
-    }
-
-    private void testDoNotLaunchDestroyedActivityInner() {
         final Map<IBinder, DestroyActivityItem> activitiesToBeDestroyed = new ArrayMap<>();
         when(mTransactionHandler.getActivitiesToBeDestroyed()).thenReturn(activitiesToBeDestroyed);
         // Assume launch transaction is still in queue, so there is no client record.
@@ -329,19 +295,6 @@
 
     @Test
     public void testActivityResultRequiredStateResolution() {
-        mSetFlagsRule.disableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
-        testActivityResultRequiredStateResolutionInner();
-    }
-
-    @Test
-    public void testActivityResultRequiredStateResolution_bundleClientTransaction() {
-        mSetFlagsRule.enableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
-        testActivityResultRequiredStateResolutionInner();
-    }
-
-    private void testActivityResultRequiredStateResolutionInner() {
         when(mTransactionHandler.getActivity(any())).thenReturn(mock(Activity.class));
 
         PostExecItem postExecItem = new PostExecItem(ON_RESUME);
@@ -495,19 +448,6 @@
 
     @Test(expected = IllegalArgumentException.class)
     public void testActivityItemNullRecordThrowsException() {
-        mSetFlagsRule.disableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
-        testActivityItemNullRecordThrowsExceptionInner();
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testActivityItemNullRecordThrowsException_bundleClientTransaction() {
-        mSetFlagsRule.enableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
-        testActivityItemNullRecordThrowsExceptionInner();
-    }
-
-    private void testActivityItemNullRecordThrowsExceptionInner() {
         final ActivityTransactionItem activityItem = mock(ActivityTransactionItem.class);
         when(activityItem.getPostExecutionState()).thenReturn(UNDEFINED);
         final IBinder token = mock(IBinder.class);
@@ -520,19 +460,6 @@
 
     @Test
     public void testActivityItemExecute() {
-        mSetFlagsRule.disableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
-        testActivityItemExecuteInner();
-    }
-
-    @Test
-    public void testActivityItemExecute_bundleClientTransaction() {
-        mSetFlagsRule.enableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
-        testActivityItemExecuteInner();
-    }
-
-    private void testActivityItemExecuteInner() {
         final ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
         final ActivityTransactionItem activityItem = mock(ActivityTransactionItem.class);
         when(activityItem.getPostExecutionState()).thenReturn(UNDEFINED);
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index d451fe5..a4d7661 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -20,9 +20,6 @@
 import static android.app.servertransaction.TestUtils.mergedConfig;
 import static android.app.servertransaction.TestUtils.referrerIntentList;
 import static android.app.servertransaction.TestUtils.resultInfoList;
-import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
-
-import static com.android.window.flags.Flags.FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG;
 
 import static org.junit.Assert.assertEquals;
 
@@ -40,14 +37,12 @@
 import android.os.Parcelable;
 import android.os.PersistableBundle;
 import android.platform.test.annotations.Presubmit;
-import android.platform.test.flag.junit.SetFlagsRule;
 import android.window.ActivityWindowInfo;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -67,9 +62,6 @@
 @Presubmit
 public class TransactionParcelTests {
 
-    @Rule
-    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
-
     private Parcel mParcel;
     private IBinder mActivityToken;
 
@@ -296,8 +288,6 @@
 
     @Test
     public void testClientTransaction() {
-        mSetFlagsRule.enableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
         // Write to parcel
         NewIntentItem callback1 = NewIntentItem.obtain(mActivityToken, new ArrayList<>(), true);
         ActivityConfigurationChangeItem callback2 = ActivityConfigurationChangeItem.obtain(
@@ -320,49 +310,6 @@
         assertEquals(mActivityToken, result.getActivityToken());
     }
 
-    @Test
-    public void testClientTransactionCallbacksOnly() {
-        mSetFlagsRule.disableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
-        // Write to parcel
-        NewIntentItem callback1 = NewIntentItem.obtain(mActivityToken, new ArrayList<>(), true);
-        ActivityConfigurationChangeItem callback2 = ActivityConfigurationChangeItem.obtain(
-                mActivityToken, config(), new ActivityWindowInfo());
-
-        ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
-        transaction.addTransactionItem(callback1);
-        transaction.addTransactionItem(callback2);
-
-        writeAndPrepareForReading(transaction);
-
-        // Read from parcel and assert
-        ClientTransaction result = ClientTransaction.CREATOR.createFromParcel(mParcel);
-
-        assertEquals(transaction.hashCode(), result.hashCode());
-        assertEquals(transaction, result);
-        assertEquals(mActivityToken, result.getActivityToken());
-    }
-
-    @Test
-    public void testClientTransactionLifecycleOnly() {
-        mSetFlagsRule.disableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
-        // Write to parcel
-        StopActivityItem lifecycleRequest = StopActivityItem.obtain(mActivityToken);
-
-        ClientTransaction transaction = ClientTransaction.obtain(null /* client */);
-        transaction.addTransactionItem(lifecycleRequest);
-
-        writeAndPrepareForReading(transaction);
-
-        // Read from parcel and assert
-        ClientTransaction result = ClientTransaction.CREATOR.createFromParcel(mParcel);
-
-        assertEquals(transaction.hashCode(), result.hashCode());
-        assertEquals(transaction, result);
-        assertEquals(mActivityToken, result.getActivityToken());
-    }
-
     /** Write to {@link #mParcel} and reset its position to prepare for reading from the start. */
     private void writeAndPrepareForReading(Parcelable parcelable) {
         parcelable.writeToParcel(mParcel, 0 /* flags */);
diff --git a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
index 6b3cf7b..ee1b658 100644
--- a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
+++ b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java
@@ -44,7 +44,6 @@
 import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -382,8 +381,7 @@
         assertTrue(allResourcePathsLoaded(resourcePaths, loadedAssets));
 
         // Package resources' paths should be cached in ResourcesManager.
-        assertEquals(Arrays.toString(resourcePaths), Arrays.toString(ResourcesManager.getInstance()
-                .getSharedLibAssetsMap().get(TEST_LIB).getAllAssetPaths()));
+        assertNotNull(ResourcesManager.getInstance().getRegisteredResourcePaths().get(TEST_LIB));
 
         // Revert the ResourcesManager instance back.
         ResourcesManager.setInstance(oriResourcesManager);
@@ -414,9 +412,7 @@
         assertTrue(allResourcePathsLoaded(resourcePaths, loadedAssets));
 
         // Package resources' paths should be cached in ResourcesManager.
-        assertEquals(Arrays.toString(resourcePaths), Arrays.toString(ResourcesManager.getInstance()
-                .getSharedLibAssetsMap().get(TEST_LIB).getAllAssetPaths()));
-
+        assertNotNull(ResourcesManager.getInstance().getRegisteredResourcePaths().get(TEST_LIB));
         // Revert the ResourcesManager instance back.
         ResourcesManager.setInstance(oriResourcesManager);
     }
@@ -452,9 +448,7 @@
         assertTrue(allResourcePathsLoaded(resourcePaths, loadedAssets));
 
         // Package resources' paths should be cached in ResourcesManager.
-        assertEquals(Arrays.toString(resourcePaths), Arrays.toString(ResourcesManager.getInstance()
-                .getSharedLibAssetsMap().get(TEST_LIB).getAllAssetPaths()));
-
+        assertNotNull(ResourcesManager.getInstance().getRegisteredResourcePaths().get(TEST_LIB));
         // Revert the ResourcesManager instance back.
         ResourcesManager.setInstance(oriResourcesManager);
     }
@@ -493,9 +487,7 @@
         assertTrue(allResourcePathsLoaded(resourcePaths, loadedAssets));
 
         // Package resources' paths should be cached in ResourcesManager.
-        assertEquals(Arrays.toString(resourcePaths), Arrays.toString(ResourcesManager.getInstance()
-                .getSharedLibAssetsMap().get(TEST_LIB).getAllAssetPaths()));
-
+        assertNotNull(ResourcesManager.getInstance().getRegisteredResourcePaths().get(TEST_LIB));
         // Revert the ResourcesManager instance back.
         ResourcesManager.setInstance(oriResourcesManager);
     }
diff --git a/core/tests/coretests/src/android/database/sqlite/SQLiteCantOpenDatabaseExceptionTest.java b/core/tests/coretests/src/android/database/sqlite/SQLiteCantOpenDatabaseExceptionTest.java
new file mode 100644
index 0000000..09c380a
--- /dev/null
+++ b/core/tests/coretests/src/android/database/sqlite/SQLiteCantOpenDatabaseExceptionTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.database.sqlite;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteCantOpenDatabaseException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDatabase.OpenParams;
+import android.util.Log;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class SQLiteCantOpenDatabaseExceptionTest {
+    private static final String TAG = "SQLiteCantOpenDatabaseExceptionTest";
+
+    private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
+
+    private File getDatabaseFile(String name) {
+        mContext.deleteDatabase(name);
+
+        // getDatabasePath() doesn't like a filename with a / in it, so we can't use it directly.
+        return new File(mContext.getDatabasePath("a").getParentFile(), name);
+    }
+
+    private void callWithExpectedMessage(File file, String expectedMessagePattern) {
+        try {
+            SQLiteDatabase.openDatabase(file, new OpenParams.Builder().build());
+            fail("SQLiteCantOpenDatabaseException was not thrown");
+        } catch (SQLiteCantOpenDatabaseException e) {
+            Log.i(TAG, "Caught expected exception: " + e.getMessage());
+            assertTrue(e.getMessage().matches(expectedMessagePattern));
+        }
+    }
+
+    /** DB's directory doesn't exist. */
+    @Test
+    public void testDirectoryDoesNotExist() {
+        final File file = getDatabaseFile("nonexisitentdir/mydb.db");
+
+        callWithExpectedMessage(file, ".*: Directory .* doesn't exist");
+    }
+
+    /** File doesn't exist */
+    @Test
+    public void testFileDoesNotExist() {
+        final File file = getDatabaseFile("mydb.db");
+
+        callWithExpectedMessage(file, ".*: File .* doesn't exist");
+    }
+
+    /** File exists, but not readable. */
+    @Test
+    public void testFileNotReadable() {
+        final File file = getDatabaseFile("mydb.db");
+
+        SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(file, null);
+        db.close();
+
+        file.setReadable(false);
+
+        callWithExpectedMessage(file, ".*: File .* not readable");
+    }
+
+    /** Directory with the given name exists already. */
+    @Test
+    public void testPathIsADirectory() {
+        final File file = getDatabaseFile("mydb.db");
+
+        file.mkdirs();
+
+        callWithExpectedMessage(file, ".*: Path .* is a directory");
+    }
+}
diff --git a/core/tests/coretests/src/android/database/sqlite/SQLiteRawStatementTest.java b/core/tests/coretests/src/android/database/sqlite/SQLiteRawStatementTest.java
index 8071d3d..24d27c4 100644
--- a/core/tests/coretests/src/android/database/sqlite/SQLiteRawStatementTest.java
+++ b/core/tests/coretests/src/android/database/sqlite/SQLiteRawStatementTest.java
@@ -27,7 +27,6 @@
 import android.database.Cursor;
 import android.database.DatabaseUtils;
 import android.os.SystemClock;
-import android.test.AndroidTestCase;
 import android.util.Log;
 
 import androidx.test.filters.SmallTest;
diff --git a/core/tests/coretests/src/android/graphics/ColorStateListTest.java b/core/tests/coretests/src/android/graphics/ColorStateListTest.java
index a3d52ea..ab41bd0 100644
--- a/core/tests/coretests/src/android/graphics/ColorStateListTest.java
+++ b/core/tests/coretests/src/android/graphics/ColorStateListTest.java
@@ -19,6 +19,8 @@
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.test.AndroidTestCase;
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoOutputStream;
 
 import androidx.test.filters.SmallTest;
 
@@ -49,6 +51,15 @@
     }
 
     @SmallTest
+    public void testStateIsInList_proto() throws Exception {
+        ColorStateList colorStateList = recreateFromProto(
+                mResources.getColorStateList(R.color.color1));
+        int[] focusedState = {android.R.attr.state_focused};
+        int focusColor = colorStateList.getColorForState(focusedState, R.color.failColor);
+        assertEquals(mResources.getColor(R.color.testcolor1), focusColor);
+    }
+
+    @SmallTest
     public void testEmptyState() throws Exception {
         ColorStateList colorStateList = mResources.getColorStateList(R.color.color1);
         int[] emptyState = {};
@@ -57,6 +68,15 @@
     }
 
     @SmallTest
+    public void testEmptyState_proto() throws Exception {
+        ColorStateList colorStateList = recreateFromProto(
+                mResources.getColorStateList(R.color.color1));
+        int[] emptyState = {};
+        int defaultColor = colorStateList.getColorForState(emptyState, mFailureColor);
+        assertEquals(mResources.getColor(R.color.testcolor2), defaultColor);
+    }
+
+    @SmallTest
     public void testGetColor() throws Exception {
         int defaultColor = mResources.getColor(R.color.color1);
         assertEquals(mResources.getColor(R.color.testcolor2), defaultColor);
@@ -73,4 +93,11 @@
         int defaultColor = mResources.getColor(R.color.color_with_lstar);
         assertEquals(mResources.getColor(R.color.testcolor3), defaultColor);
     }
+
+    private ColorStateList recreateFromProto(ColorStateList colorStateList) throws Exception {
+        ProtoOutputStream out = new ProtoOutputStream();
+        colorStateList.writeToProto(out);
+        ProtoInputStream in = new ProtoInputStream(out.getBytes());
+        return ColorStateList.createFromProto(in);
+    }
 }
diff --git a/core/tests/coretests/src/android/hardware/biometrics/BiometricPromptTest.java b/core/tests/coretests/src/android/hardware/biometrics/BiometricPromptTest.java
index ca91542..5464ea3 100644
--- a/core/tests/coretests/src/android/hardware/biometrics/BiometricPromptTest.java
+++ b/core/tests/coretests/src/android/hardware/biometrics/BiometricPromptTest.java
@@ -28,6 +28,7 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -209,6 +210,25 @@
                 "The number of list items exceeds ");
     }
 
+    @Test
+    public void testOnDialogDismissed_dialogDismissedNegative() throws RemoteException {
+        final ArgumentCaptor<IBiometricServiceReceiver> biometricServiceReceiverCaptor =
+                ArgumentCaptor.forClass(IBiometricServiceReceiver.class);
+        final BiometricPrompt.AuthenticationCallback callback =
+                mock(BiometricPrompt.AuthenticationCallback.class);
+        mBiometricPrompt.authenticate(mCancellationSignal, mExecutor, callback);
+        mLooper.dispatchAll();
+
+        verify(mService).authenticate(any(), anyLong(), anyInt(),
+                biometricServiceReceiverCaptor.capture(), anyString(), any());
+
+        biometricServiceReceiverCaptor.getValue().onDialogDismissed(
+                BiometricPrompt.DISMISSED_REASON_NEGATIVE);
+
+        verify(callback).onAuthenticationError(BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED,
+                null /* errString */);
+    }
+
     private String generateRandomString(int charNum) {
         final Random random = new Random();
         final StringBuilder longString = new StringBuilder(charNum);
diff --git a/core/tests/coretests/src/android/os/MessageQueueTest.java b/core/tests/coretests/src/android/os/MessageQueueTest.java
index 851e612..8cd6773 100644
--- a/core/tests/coretests/src/android/os/MessageQueueTest.java
+++ b/core/tests/coretests/src/android/os/MessageQueueTest.java
@@ -16,7 +16,6 @@
 
 package android.os;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.MediumTest;
@@ -154,7 +153,6 @@
 
     @Test
     @MediumTest
-    @IgnoreUnderRavenwood(reason = "Flaky test, b/315872700")
     public void testFieldIntegrity() throws Exception {
 
         TestHandlerThread tester = new TestFieldIntegrityHandler() {
diff --git a/core/tests/coretests/src/android/util/SequenceUtilsTest.java b/core/tests/coretests/src/android/util/SequenceUtilsTest.java
new file mode 100644
index 0000000..6ca1751
--- /dev/null
+++ b/core/tests/coretests/src/android/util/SequenceUtilsTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 android.util.SequenceUtils.getInitSeq;
+import static android.util.SequenceUtils.getNextSeq;
+import static android.util.SequenceUtils.isIncomingSeqStale;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.platform.test.annotations.DisabledOnRavenwood;
+import android.platform.test.annotations.Presubmit;
+import android.platform.test.ravenwood.RavenwoodRule;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for subtypes of {@link SequenceUtils}.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksCoreTests:SequenceUtilsTest
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+@DisabledOnRavenwood(blockedBy = SequenceUtils.class)
+public class SequenceUtilsTest {
+
+    // This is needed to disable the test in Ravenwood test, because SequenceUtils hasn't opted in
+    // for Ravenwood, which is still in experiment.
+    @Rule
+    public final RavenwoodRule mRavenwood = new RavenwoodRule();
+
+    @Test
+    public void testNextSeq() {
+        assertEquals(getInitSeq() + 1, getNextSeq(getInitSeq()));
+        assertEquals(getInitSeq() + 1, getNextSeq(Integer.MAX_VALUE));
+    }
+
+    @Test
+    public void testIsIncomingSeqStale() {
+        assertFalse(isIncomingSeqStale(getInitSeq() + 1, getInitSeq() + 10));
+        assertTrue(isIncomingSeqStale(getInitSeq() + 10, getInitSeq() + 1));
+        assertFalse(isIncomingSeqStale(-100, 100));
+        assertTrue(isIncomingSeqStale(100, -100));
+        assertFalse(isIncomingSeqStale(1, 2));
+        assertTrue(isIncomingSeqStale(2, 1));
+
+        // Possible incoming seq are all newer than the initial seq.
+        assertFalse(isIncomingSeqStale(getInitSeq(), getInitSeq()));
+        assertFalse(isIncomingSeqStale(getInitSeq(), getInitSeq() + 1));
+        assertFalse(isIncomingSeqStale(getInitSeq(), -100));
+        assertFalse(isIncomingSeqStale(getInitSeq(), 0));
+        assertFalse(isIncomingSeqStale(getInitSeq(), 100));
+        assertFalse(isIncomingSeqStale(getInitSeq(), Integer.MAX_VALUE));
+        assertFalse(isIncomingSeqStale(getInitSeq(), getNextSeq(Integer.MAX_VALUE)));
+
+        // False for the same seq.
+        assertFalse(isIncomingSeqStale(100, 100));
+        assertFalse(isIncomingSeqStale(Integer.MAX_VALUE, Integer.MAX_VALUE));
+
+        // False when there is a large jump (overflow).
+        assertFalse(isIncomingSeqStale(Integer.MAX_VALUE, getInitSeq() + 1));
+        assertFalse(isIncomingSeqStale(Integer.MAX_VALUE, getInitSeq() + 100));
+        assertFalse(isIncomingSeqStale(Integer.MAX_VALUE, getNextSeq(Integer.MAX_VALUE)));
+
+        // True when the large jump is opposite (curSeq is newer).
+        assertTrue(isIncomingSeqStale(getInitSeq() + 1, Integer.MAX_VALUE));
+        assertTrue(isIncomingSeqStale(getInitSeq() + 100, Integer.MAX_VALUE));
+        assertTrue(isIncomingSeqStale(getNextSeq(Integer.MAX_VALUE), Integer.MAX_VALUE));
+    }
+}
diff --git a/core/tests/coretests/src/android/util/SparseSetArrayTest.java b/core/tests/coretests/src/android/util/SparseSetArrayTest.java
index 1c72185..a8dce70 100644
--- a/core/tests/coretests/src/android/util/SparseSetArrayTest.java
+++ b/core/tests/coretests/src/android/util/SparseSetArrayTest.java
@@ -17,7 +17,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
@@ -37,7 +36,6 @@
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
 
     @Test
-    @IgnoreUnderRavenwood(reason = "Flaky test, b/315872700")
     public void testAddAll() {
         final SparseSetArray<Integer> sparseSetArray = new SparseSetArray<>();
 
@@ -59,7 +57,6 @@
     }
 
     @Test
-    @IgnoreUnderRavenwood(reason = "b/315036461")
     public void testCopyConstructor() {
         final SparseSetArray<Integer> sparseSetArray = new SparseSetArray<>();
 
diff --git a/core/tests/coretests/src/android/view/ImeBackAnimationControllerTest.java b/core/tests/coretests/src/android/view/ImeBackAnimationControllerTest.java
index 58e5be2..4d9b591c 100644
--- a/core/tests/coretests/src/android/view/ImeBackAnimationControllerTest.java
+++ b/core/tests/coretests/src/android/view/ImeBackAnimationControllerTest.java
@@ -34,6 +34,7 @@
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertEquals;
 
+import android.app.WindowConfiguration;
 import android.content.Context;
 import android.graphics.Insets;
 import android.platform.test.annotations.Presubmit;
@@ -102,6 +103,8 @@
             mViewRoot.setOnContentApplyWindowInsetsListener(
                     mock(Window.OnContentApplyWindowInsetsListener.class));
             mBackAnimationController = new ImeBackAnimationController(mViewRoot, mInsetsController);
+            mViewRoot.mContext.getResources().getConfiguration().windowConfiguration
+                    .setWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
 
             when(mWindowInsetsAnimationController.getHiddenStateInsets()).thenReturn(Insets.NONE);
             when(mWindowInsetsAnimationController.getShownStateInsets()).thenReturn(IME_INSETS);
@@ -156,8 +159,28 @@
         mBackAnimationController.onBackProgressed(new BackEvent(100f, 0f, 0.5f, EDGE_LEFT));
         // commit back gesture
         mBackAnimationController.onBackInvoked();
-        // verify that InsetsController#hide is called
-        verify(mInsetsController, times(1)).hide(ime());
+        // verify that InputMethodManager#notifyImeHidden is called (which is the case whenever
+        // getInputMethodManager is called from ImeBackAnimationController)
+        verify(mViewRootInsetsControllerHost, times(1)).getInputMethodManager();
+        // verify that ImeBackAnimationController does not take control over IME insets
+        verify(mInsetsController, never()).controlWindowInsetsAnimation(anyInt(), any(), any(),
+                anyBoolean(), anyLong(), any(), anyInt(), anyBoolean());
+    }
+
+    @Test
+    public void testMultiWindowModeNotPlayingAnim() {
+        // setup ViewRoot with WINDOWING_MODE_MULTI_WINDOW
+        mViewRoot.mContext.getResources().getConfiguration().windowConfiguration.setWindowingMode(
+                WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW);
+        // start back gesture
+        mBackAnimationController.onBackStarted(new BackEvent(0f, 0f, 0f, EDGE_LEFT));
+        // progress back gesture
+        mBackAnimationController.onBackProgressed(new BackEvent(100f, 0f, 0.5f, EDGE_LEFT));
+        // commit back gesture
+        mBackAnimationController.onBackInvoked();
+        // verify that InputMethodManager#notifyImeHidden is called (which is the case whenever
+        // getInputMethodManager is called from ImeBackAnimationController)
+        verify(mViewRootInsetsControllerHost, times(1)).getInputMethodManager();
         // verify that ImeBackAnimationController does not take control over IME insets
         verify(mInsetsController, never()).controlWindowInsetsAnimation(anyInt(), any(), any(),
                 anyBoolean(), anyLong(), any(), anyInt(), anyBoolean());
@@ -277,9 +300,9 @@
 
             // commit back gesture
             mBackAnimationController.onBackInvoked();
-
-            // verify that InsetsController#hide is called
-            verify(mInsetsController, times(1)).hide(ime());
+            // verify that InputMethodManager#notifyImeHidden is called (which is the case whenever
+            // getInputMethodManager is called from ImeBackAnimationController)
+            verify(mViewRootInsetsControllerHost, times(1)).getInputMethodManager();
         });
     }
 
diff --git a/core/tests/coretests/src/android/view/ViewFrameRateTest.java b/core/tests/coretests/src/android/view/ViewFrameRateTest.java
index 169300a..b68ff78 100644
--- a/core/tests/coretests/src/android/view/ViewFrameRateTest.java
+++ b/core/tests/coretests/src/android/view/ViewFrameRateTest.java
@@ -21,6 +21,7 @@
 import static android.view.Surface.FRAME_RATE_CATEGORY_LOW;
 import static android.view.Surface.FRAME_RATE_CATEGORY_NORMAL;
 import static android.view.Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VELOCITY_MAPPING_READ_ONLY;
 import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY;
 import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY;
@@ -28,11 +29,9 @@
 import static android.view.flags.Flags.toolkitFrameRateBySizeReadOnly;
 import static android.view.flags.Flags.toolkitFrameRateDefaultNormalReadOnly;
 import static android.view.flags.Flags.toolkitFrameRateSmallUsesPercentReadOnly;
-import static android.view.flags.Flags.toolkitFrameRateVelocityMappingReadOnly;
 
 import static junit.framework.Assert.assertEquals;
 
-import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import android.annotation.NonNull;
@@ -99,9 +98,8 @@
     }
 
     @Test
-    @RequiresFlagsEnabled({FLAG_VIEW_VELOCITY_API,
-            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
-    public void frameRateChangesWhenContentMoves() throws Throwable {
+    @RequiresFlagsEnabled(FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY)
+    public void highHintWhenContentMoves() throws Throwable {
         if (!ViewProperties.vrr_enabled().orElse(true)) {
             return;
         }
@@ -109,18 +107,59 @@
         mActivityRule.runOnUiThread(() -> {
             mMovingView.offsetLeftAndRight(100);
             runAfterDraw(() -> {
-                if (toolkitFrameRateVelocityMappingReadOnly()) {
-                    float frameRate = mViewRoot.getLastPreferredFrameRate();
-                    assertTrue(frameRate > 0);
-                } else {
-                    assertEquals(FRAME_RATE_CATEGORY_HIGH,
-                            mViewRoot.getLastPreferredFrameRateCategory());
-                }
+                assertEquals(FRAME_RATE_CATEGORY_HIGH_HINT,
+                        mViewRoot.getLastPreferredFrameRateCategory());
             });
         });
         waitForAfterDraw();
     }
 
+    @Test
+    @RequiresFlagsEnabled(FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY)
+    public void inputMethodWithContentMoves() throws Throwable {
+        if (!ViewProperties.vrr_enabled().orElse(true)) {
+            return;
+        }
+        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+
+        // update the window type to TYPE_INPUT_METHOD
+        int windowType = mViewRoot.mWindowAttributes.type;
+        final WindowManager.LayoutParams attrs = mViewRoot.mWindowAttributes;
+        attrs.type = TYPE_INPUT_METHOD;
+        instrumentation.runOnMainSync(() -> {
+            attrs.width = 1;
+            attrs.height = 1;
+            mViewRoot.setLayoutParams(attrs, false);
+        });
+        instrumentation.waitForIdleSync();
+
+        final WindowManager.LayoutParams newAttrs = mViewRoot.mWindowAttributes;
+        assertTrue(newAttrs.type == TYPE_INPUT_METHOD);
+
+        waitForFrameRateCategoryToSettle();
+        mActivityRule.runOnUiThread(() -> {
+            mMovingView.offsetLeftAndRight(100);
+            runAfterDraw(() -> {
+                int expected = toolkitFrameRateBySizeReadOnly()
+                        ? FRAME_RATE_CATEGORY_LOW : FRAME_RATE_CATEGORY_NORMAL;
+                float frameRate = mViewRoot.getLastPreferredFrameRate();
+                // frame rate shouldn't be boost with TYPE_INPUT_METHOD window type
+                assertTrue(frameRate == 0);
+                assertEquals(expected,
+                        mViewRoot.getLastPreferredFrameRateCategory());
+            });
+        });
+        waitForAfterDraw();
+
+        // Reset the window type back to the original one.
+        newAttrs.type = windowType;
+        instrumentation.runOnMainSync(() -> {
+            mViewRoot.setLayoutParams(newAttrs, false);
+        });
+        instrumentation.waitForIdleSync();
+        assertTrue(mViewRoot.mWindowAttributes.type == windowType);
+    }
+
     @UiThreadTest
     @Test
     @RequiresFlagsEnabled(FLAG_VIEW_VELOCITY_API)
@@ -128,40 +167,118 @@
         assertEquals(0f, mViewRoot.getLastPreferredFrameRate(), 0f);
     }
 
+
     @Test
-    @RequiresFlagsEnabled(FLAG_VIEW_VELOCITY_API)
-    public void frameBoostDisable() throws Throwable {
+    @RequiresFlagsEnabled(FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY)
+    public void highHintWhenActionMove() throws Throwable {
         if (!ViewProperties.vrr_enabled().orElse(true)) {
             return;
         }
-        mActivityRule.runOnUiThread(() -> {
-            long now = SystemClock.uptimeMillis();
-            MotionEvent down = MotionEvent.obtain(
-                    /* downTime */ now,
-                    /* eventTime */ now,
-                    /* action */ MotionEvent.ACTION_DOWN,
-                    /* x */ 0f,
-                    /* y */ 0f,
-                    /* metaState */ 0
-            );
-            mActivity.dispatchTouchEvent(down);
-            mMovingView.offsetLeftAndRight(10);
-        });
-        mActivityRule.runOnUiThread(() -> {
-            mMovingView.invalidate();
-        });
 
         mActivityRule.runOnUiThread(() -> {
-            assertFalse(mViewRoot.getIsTouchBoosting());
-            assertFalse(mViewRoot.getIsFrameRateBoosting());
+            mMovingView.setRequestedFrameRate(View.REQUESTED_FRAME_RATE_CATEGORY_LOW);
+            ViewGroup.LayoutParams layoutParams = mMovingView.getLayoutParams();
+            layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
+            layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
+            mMovingView.setLayoutParams(layoutParams);
+            mMovingView.setOnClickListener((v) -> {});
         });
+        waitForFrameRateCategoryToSettle();
+        mActivityRule.runOnUiThread(() -> assertEquals(FRAME_RATE_CATEGORY_LOW,
+                mViewRoot.getLastPreferredFrameRateCategory()));
+
+        int[] position = new int[2];
+        mActivityRule.runOnUiThread(() -> {
+            mMovingView.getLocationOnScreen(position);
+            position[0] += mMovingView.getWidth() / 2;
+            position[1] += mMovingView.getHeight() / 2;
+        });
+        final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+
+        long now = SystemClock.uptimeMillis();
+        MotionEvent down = MotionEvent.obtain(
+                now, // downTime
+                now, // eventTime
+                MotionEvent.ACTION_DOWN, // action
+                position[0], // x
+                position[1], // y
+                0 // metaState
+        );
+        down.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+        instrumentation.sendPointerSync(down);
+
+        now = SystemClock.uptimeMillis();
+        MotionEvent move = MotionEvent.obtain(
+                now, // downTime
+                now, // eventTime
+                MotionEvent.ACTION_MOVE, // action
+                position[0], // x
+                position[1], // y
+                0 // metaState
+        );
+        move.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+        instrumentation.sendPointerSync(move);
+
+        // Should continue to enable touch boost.
+        mActivityRule.runOnUiThread(() -> {
+            mMovingView.offsetLeftAndRight(10);
+            assertTrue(mViewRoot.getIsTouchBoosting());
+        });
+
+        down.recycle();
+        move.recycle();
+    }
+
+    // When the size of a View is changed, we should boost the frame rate.
+    @Test
+    @RequiresFlagsEnabled(FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY)
+    public void highHintWhenSizeChanged() throws Throwable {
+        if (!ViewProperties.vrr_enabled().orElse(true)) {
+            return;
+        }
+        waitForFrameRateCategoryToSettle();
+        assertEquals(FRAME_RATE_CATEGORY_LOW,
+                        mViewRoot.getLastPreferredFrameRateCategory());
+
+        int width = mMovingView.getWidth();
+        int height = mMovingView.getHeight();
+
+        ViewGroup.LayoutParams params = mMovingView.getLayoutParams();
+        params.width = width * 2;
+        params.height = height * 2;
+
+        // frame rate category should be HIGH_HINT when the size is changed
+        mActivityRule.runOnUiThread(() -> {
+            mMovingView.setLayoutParams(params);
+            runAfterDraw(() -> {
+                assertTrue(mMovingView.getWidth() > width);
+                assertTrue(mMovingView.getHeight() > height);
+                assertEquals(FRAME_RATE_CATEGORY_HIGH_HINT,
+                        mViewRoot.getLastPreferredFrameRateCategory());
+            });
+        });
+        waitForAfterDraw();
+
+        // set it back to the original size
+        params.width = width;
+        params.height = height;
+        mActivityRule.runOnUiThread(() -> {
+            mMovingView.setLayoutParams(params);
+            runAfterDraw(() -> {
+                assertEquals(width, mMovingView.getWidth());
+                assertEquals(height, mMovingView.getHeight());
+                assertEquals(FRAME_RATE_CATEGORY_HIGH_HINT,
+                        mViewRoot.getLastPreferredFrameRateCategory());
+            });
+        });
+        waitForAfterDraw();
     }
 
     @Test
     @RequiresFlagsEnabled({FLAG_VIEW_VELOCITY_API,
             FLAG_TOOLKIT_FRAME_RATE_VELOCITY_MAPPING_READ_ONLY,
             FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
-    public void lowVelocity60() throws Throwable {
+    public void lowVelocity80() throws Throwable {
         if (!ViewProperties.vrr_enabled().orElse(true)) {
             return;
         }
@@ -676,6 +793,12 @@
         down.setSource(InputDevice.SOURCE_TOUCHSCREEN);
         instrumentation.sendPointerSync(down);
         assertEquals(FRAME_RATE_CATEGORY_HIGH_HINT, mViewRoot.getLastPreferredFrameRateCategory());
+
+        // Should still be boost with position changed
+        mActivityRule.runOnUiThread(() -> {
+            mMovingView.offsetLeftAndRight(10);
+            assertTrue(mViewRoot.getIsTouchBoosting());
+        });
     }
 
     @LargeTest
diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java
index 06cb0ee..033ac7c 100644
--- a/core/tests/coretests/src/android/view/ViewRootImplTest.java
+++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java
@@ -16,13 +16,7 @@
 
 package android.view;
 
-import static android.view.accessibility.Flags.FLAG_FORCE_INVERT_COLOR;
-import static android.view.flags.Flags.FLAG_ADD_SCHANDLE_TO_VRI_SURFACE;
-import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY;
-import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_BY_SIZE_READ_ONLY;
-import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY;
-import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY;
-import static android.view.flags.Flags.FLAG_VIEW_VELOCITY_API;
+import static android.util.SequenceUtils.getInitSeq;
 import static android.view.Surface.FRAME_RATE_CATEGORY_DEFAULT;
 import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH;
 import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH_HINT;
@@ -44,6 +38,13 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
+import static android.view.accessibility.Flags.FLAG_FORCE_INVERT_COLOR;
+import static android.view.flags.Flags.FLAG_ADD_SCHANDLE_TO_VRI_SURFACE;
+import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_BY_SIZE_READ_ONLY;
+import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY;
+import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY;
+import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY;
+import static android.view.flags.Flags.FLAG_VIEW_VELOCITY_API;
 import static android.view.flags.Flags.toolkitFrameRateBySizeReadOnly;
 import static android.view.flags.Flags.toolkitFrameRateDefaultNormalReadOnly;
 import static android.view.flags.Flags.toolkitFrameRateVelocityMappingReadOnly;
@@ -53,6 +54,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -63,9 +65,11 @@
 import android.app.UiModeManager;
 import android.content.Context;
 import android.graphics.ForceDarkType;
+import android.graphics.Rect;
 import android.hardware.display.DisplayManagerGlobal;
 import android.os.Binder;
 import android.os.SystemProperties;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.Presubmit;
 import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
@@ -1250,6 +1254,81 @@
         });
     }
 
+    @Test
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_BY_SIZE_READ_ONLY})
+    public void votePreferredFrameRate_infrequentLayer_smallView_voteForLow() throws Throwable {
+        if (!ViewProperties.vrr_enabled().orElse(true)) {
+            return;
+        }
+        final long delay = 200L;
+
+        mView = new View(sContext);
+        WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY);
+        wmlp.token = new Binder(); // Set a fake token to bypass 'is your activity running' check
+        wmlp.width = 1;
+        wmlp.height = 1;
+
+        // The view is a small view, and it should vote for category low only.
+        int expected = FRAME_RATE_CATEGORY_LOW;
+
+        sInstrumentation.runOnMainSync(() -> {
+            WindowManager wm = sContext.getSystemService(WindowManager.class);
+            wm.addView(mView, wmlp);
+        });
+        sInstrumentation.waitForIdleSync();
+
+        mViewRootImpl = mView.getViewRootImpl();
+        waitForFrameRateCategoryToSettle(mView);
+
+        // In transition from frequent update to infrequent update
+        Thread.sleep(delay);
+        sInstrumentation.runOnMainSync(() -> {
+            mView.invalidate();
+            runAfterDraw(() -> assertEquals(expected,
+                    mViewRootImpl.getLastPreferredFrameRateCategory()));
+        });
+        waitForAfterDraw();
+
+        // In transition from frequent update to infrequent update
+        Thread.sleep(delay);
+        sInstrumentation.runOnMainSync(() -> {
+            mView.invalidate();
+            runAfterDraw(() -> assertEquals(expected,
+                    mViewRootImpl.getLastPreferredFrameRateCategory()));
+        });
+
+        // Infrequent update
+        Thread.sleep(delay);
+
+        // The view is small, the expected category is still low for intermittent.
+        int intermittentExpected = FRAME_RATE_CATEGORY_LOW;
+
+        sInstrumentation.runOnMainSync(() -> {
+            mView.invalidate();
+            runAfterDraw(() -> assertEquals(intermittentExpected,
+                    mViewRootImpl.getLastPreferredFrameRateCategory()));
+        });
+        waitForAfterDraw();
+
+        // When the View vote, it's still considered as intermittent update state
+        sInstrumentation.runOnMainSync(() -> {
+            mView.invalidate();
+            runAfterDraw(() -> assertEquals(intermittentExpected,
+                    mViewRootImpl.getLastPreferredFrameRateCategory()));
+        });
+        waitForAfterDraw();
+
+        // Becomes frequent update state
+        sInstrumentation.runOnMainSync(() -> {
+            mView.invalidate();
+            runAfterDraw(() -> assertEquals(expected,
+                    mViewRootImpl.getLastPreferredFrameRateCategory()));
+        });
+    }
+
     /**
      * Test the IsFrameRatePowerSavingsBalanced values are properly set
      */
@@ -1465,6 +1544,37 @@
                 nativeCreateASurfaceControlFromSurface(mViewRootImpl.mSurface));
     }
 
+    @EnableFlags(Flags.FLAG_INSETS_CONTROL_SEQ)
+    @Test
+    public void testHandleInsetsControlChanged() {
+        mView = new View(sContext);
+        attachViewToWindow(mView);
+
+        mViewRootImpl = mView.getViewRootImpl();
+        final InsetsController controller = mViewRootImpl.getInsetsController();
+
+        final InsetsState state0 = new InsetsState();
+        final InsetsState state1 = new InsetsState();
+        state0.setDisplayFrame(new Rect(0, 0, 500, 1000));
+        state0.setSeq(getInitSeq() + 10000);
+        state1.setDisplayFrame(new Rect(0, 0, 1500, 2000));
+        state1.setSeq(getInitSeq() + 10001);
+        final InsetsSourceControl.Array array = new InsetsSourceControl.Array();
+
+        sInstrumentation.runOnMainSync(() -> {
+            mViewRootImpl.handleInsetsControlChanged(state0, array);
+            assertEquals(state0, controller.getLastDispatchedState());
+
+            mViewRootImpl.handleInsetsControlChanged(state1, array);
+            assertEquals(state1, controller.getLastDispatchedState());
+
+            // Skip the stale value.
+            mViewRootImpl.handleInsetsControlChanged(state0, array);
+            assertEquals(state1, controller.getLastDispatchedState());
+            assertNotEquals(state0, controller.getLastDispatchedState());
+        });
+    }
+
     private boolean setForceDarkSysProp(boolean isForceDarkEnabled) {
         try {
             SystemProperties.set(
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityManagerTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityManagerTest.java
index 1013bf5..ce36ee0 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityManagerTest.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityManagerTest.java
@@ -20,6 +20,7 @@
 import static com.android.internal.accessibility.AccessibilityShortcutController.COLOR_INVERSION_TILE_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_TILE_COMPONENT_NAME;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -31,6 +32,8 @@
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.doThrow;
@@ -48,12 +51,14 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.view.Display;
 
 import androidx.annotation.NonNull;
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.R;
+import com.android.internal.accessibility.common.ShortcutConstants;
 import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 import com.android.internal.util.IntPair;
 import com.android.server.accessibility.test.MessageCapturingHandler;
@@ -321,7 +326,7 @@
         Throwable rethrownException = assertThrows(RuntimeException.class,
                 () -> manager.enableShortcutsForTargets(
                         /* enable= */ false,
-                        UserShortcutType.HARDWARE,
+                        HARDWARE,
                         Set.of(DALTONIZER_COMPONENT_NAME.flattenToString()),
                         UserHandle.USER_CURRENT
                 ));
@@ -331,7 +336,7 @@
     @Test
     public void enableShortcutsForTargets_verifyServiceMethodCalled() throws Exception {
         AccessibilityManager manager = createManager(WITH_A11Y_ENABLED);
-        int shortcutTypes = UserShortcutType.HARDWARE | UserShortcutType.TRIPLETAP;
+        int shortcutTypes = HARDWARE | UserShortcutType.TRIPLETAP;
 
         manager.enableShortcutsForTargets(
                 /* enable= */ false,
@@ -348,6 +353,30 @@
         );
     }
 
+    @Test
+    public void performAccessibilityShortcut_callToService_defaultTypeIsHardware()
+            throws Exception {
+        AccessibilityManager manager = createManager(WITH_A11Y_ENABLED);
+
+        manager.performAccessibilityShortcut();
+
+        verify(mMockService).performAccessibilityShortcut(
+                eq(Display.DEFAULT_DISPLAY), eq(HARDWARE), isNull());
+    }
+
+    @Test
+    public void performAccessibilityShortcut_callToService_typeParameterMatches() throws Exception {
+        AccessibilityManager manager = createManager(WITH_A11Y_ENABLED);
+        int display = Display.DEFAULT_DISPLAY;
+        String name = LABEL;
+
+        for (int type: ShortcutConstants.USER_SHORTCUT_TYPES) {
+            manager.performAccessibilityShortcut(display, type, name);
+
+            verify(mMockService).performAccessibilityShortcut(display, type, name);
+        }
+    }
+
     private class MyAccessibilityProxy extends AccessibilityDisplayProxy {
         MyAccessibilityProxy(int displayId,
                 @NonNull List<AccessibilityServiceInfo> serviceInfos) {
diff --git a/core/tests/coretests/src/android/view/accessibility/a11ychecker/AccessibilityNodePathBuilderTest.java b/core/tests/coretests/src/android/view/accessibility/a11ychecker/AccessibilityNodePathBuilderTest.java
new file mode 100644
index 0000000..438277b
--- /dev/null
+++ b/core/tests/coretests/src/android/view/accessibility/a11ychecker/AccessibilityNodePathBuilderTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.a11ychecker;
+
+import static android.view.accessibility.a11ychecker.MockAccessibilityNodeInfoBuilder.PACKAGE_NAME;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.FrameLayout;
+import android.widget.TextView;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.widget.RecyclerView;
+
+import com.google.common.collect.ImmutableList;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityNodePathBuilderTest {
+
+    public static final String RESOURCE_ID_PREFIX = PACKAGE_NAME + ":id/";
+
+    @Test
+    public void createNodePath_pathWithResourceNames() {
+        AccessibilityNodeInfo child = new MockAccessibilityNodeInfoBuilder()
+                .setViewIdResourceName(RESOURCE_ID_PREFIX + "child_node")
+                .build();
+        AccessibilityNodeInfo parent =
+                new MockAccessibilityNodeInfoBuilder()
+                        .setViewIdResourceName(RESOURCE_ID_PREFIX + "parent_node")
+                        .addChildren(ImmutableList.of(child))
+                        .build();
+        AccessibilityNodeInfo root =
+                new MockAccessibilityNodeInfoBuilder()
+                        .setViewIdResourceName(RESOURCE_ID_PREFIX + "root_node")
+                        .addChildren(ImmutableList.of(parent))
+                        .build();
+
+        assertThat(AccessibilityNodePathBuilder.createNodePath(child))
+                .isEqualTo(PACKAGE_NAME + ":root_node/parent_node[1]/child_node[1]");
+        assertThat(AccessibilityNodePathBuilder.createNodePath(parent))
+                .isEqualTo(PACKAGE_NAME + ":root_node/parent_node[1]");
+        assertThat(AccessibilityNodePathBuilder.createNodePath(root))
+                .isEqualTo(PACKAGE_NAME + ":root_node");
+    }
+
+    @Test
+    public void createNodePath_pathWithoutResourceNames() {
+        AccessibilityNodeInfo child =
+                new MockAccessibilityNodeInfoBuilder()
+                        .setClassName(TextView.class.getName())
+                        .build();
+        AccessibilityNodeInfo parent =
+
+                new MockAccessibilityNodeInfoBuilder()
+                        .setClassName(RecyclerView.class.getName())
+                        .addChildren(ImmutableList.of(child))
+                        .build();
+        AccessibilityNodeInfo root =
+                new MockAccessibilityNodeInfoBuilder()
+                        .setClassName(FrameLayout.class.getName())
+                        .addChildren(ImmutableList.of(parent))
+                        .build();
+
+        assertThat(AccessibilityNodePathBuilder.createNodePath(child))
+                .isEqualTo(PACKAGE_NAME + ":FrameLayout/RecyclerView[1]/TextView[1]");
+        assertThat(AccessibilityNodePathBuilder.createNodePath(parent))
+                .isEqualTo(PACKAGE_NAME + ":FrameLayout/RecyclerView[1]");
+        assertThat(AccessibilityNodePathBuilder.createNodePath(root))
+                .isEqualTo(PACKAGE_NAME + ":FrameLayout");
+    }
+
+    @Test
+    public void createNodePath_parentWithMultipleChildren() {
+        AccessibilityNodeInfo child1 =
+                new MockAccessibilityNodeInfoBuilder()
+                        .setViewIdResourceName(RESOURCE_ID_PREFIX + "child1")
+                        .build();
+        AccessibilityNodeInfo child2 =
+                new MockAccessibilityNodeInfoBuilder()
+                        .setClassName(TextView.class.getName())
+                        .build();
+        AccessibilityNodeInfo parent =
+                new MockAccessibilityNodeInfoBuilder()
+                        .setClassName(FrameLayout.class.getName())
+                        .addChildren(ImmutableList.of(child1, child2))
+                        .build();
+
+        assertThat(AccessibilityNodePathBuilder.createNodePath(child1))
+                .isEqualTo(PACKAGE_NAME + ":FrameLayout/child1[1]");
+        assertThat(AccessibilityNodePathBuilder.createNodePath(child2))
+                .isEqualTo(PACKAGE_NAME + ":FrameLayout/TextView[2]");
+        assertThat(AccessibilityNodePathBuilder.createNodePath(parent))
+                .isEqualTo(PACKAGE_NAME + ":FrameLayout");
+    }
+
+    @Test
+    public void createNodePath_handlesDifferentIdFormats() {
+        AccessibilityNodeInfo child1 =
+                new MockAccessibilityNodeInfoBuilder()
+                        .setViewIdResourceName(RESOURCE_ID_PREFIX + "childId")
+                        .build();
+        AccessibilityNodeInfo child2 =
+                new MockAccessibilityNodeInfoBuilder()
+                        .setViewIdResourceName(RESOURCE_ID_PREFIX + "child/Id/With/Slash")
+                        .build();
+        AccessibilityNodeInfo child3 =
+                new MockAccessibilityNodeInfoBuilder()
+                        .setViewIdResourceName("childIdWithoutPrefix")
+                        .build();
+        AccessibilityNodeInfo parent =
+                new MockAccessibilityNodeInfoBuilder()
+                        .addChildren(ImmutableList.of(child1, child2, child3))
+                        .setViewIdResourceName(RESOURCE_ID_PREFIX + "parentId")
+                        .build();
+
+        assertThat(AccessibilityNodePathBuilder.createNodePath(child1))
+                .isEqualTo(PACKAGE_NAME + ":parentId/childId[1]");
+        assertThat(AccessibilityNodePathBuilder.createNodePath(child2))
+                .isEqualTo(PACKAGE_NAME + ":parentId/child/Id/With/Slash[2]");
+        assertThat(AccessibilityNodePathBuilder.createNodePath(child3))
+                .isEqualTo(PACKAGE_NAME + ":parentId/childIdWithoutPrefix[3]");
+        assertThat(AccessibilityNodePathBuilder.createNodePath(parent))
+                .isEqualTo(PACKAGE_NAME + ":parentId");
+    }
+
+}
diff --git a/core/tests/coretests/src/android/view/accessibility/a11ychecker/MockAccessibilityNodeInfoBuilder.java b/core/tests/coretests/src/android/view/accessibility/a11ychecker/MockAccessibilityNodeInfoBuilder.java
new file mode 100644
index 0000000..e363f0c
--- /dev/null
+++ b/core/tests/coretests/src/android/view/accessibility/a11ychecker/MockAccessibilityNodeInfoBuilder.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.a11ychecker;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import java.util.List;
+
+final class MockAccessibilityNodeInfoBuilder {
+    static final String PACKAGE_NAME = "com.example.app";
+    private final AccessibilityNodeInfo mMockNodeInfo = mock(AccessibilityNodeInfo.class);
+
+    MockAccessibilityNodeInfoBuilder() {
+        when(mMockNodeInfo.getPackageName()).thenReturn(PACKAGE_NAME);
+    }
+
+    MockAccessibilityNodeInfoBuilder setClassName(String className) {
+        when(mMockNodeInfo.getClassName()).thenReturn(className);
+        return this;
+    }
+
+    MockAccessibilityNodeInfoBuilder setViewIdResourceName(String
+            viewIdResourceName) {
+        when(mMockNodeInfo.getViewIdResourceName()).thenReturn(viewIdResourceName);
+        return this;
+    }
+
+    MockAccessibilityNodeInfoBuilder addChildren(List<AccessibilityNodeInfo>
+            children) {
+        when(mMockNodeInfo.getChildCount()).thenReturn(children.size());
+        for (int i = 0; i < children.size(); i++) {
+            when(mMockNodeInfo.getChild(i)).thenReturn(children.get(i));
+            when(children.get(i).getParent()).thenReturn(mMockNodeInfo);
+        }
+        return this;
+    }
+
+    AccessibilityNodeInfo build() {
+        return mMockNodeInfo;
+    }
+}
diff --git a/core/tests/coretests/src/android/view/accessibility/a11ychecker/OWNERS b/core/tests/coretests/src/android/view/accessibility/a11ychecker/OWNERS
new file mode 100644
index 0000000..872a180
--- /dev/null
+++ b/core/tests/coretests/src/android/view/accessibility/a11ychecker/OWNERS
@@ -0,0 +1,5 @@
+# Android Accessibility Framework owners
+include /core/java/android/view/accessibility/a11ychecker/OWNERS
+include /services/accessibility/OWNERS
+
+yaraabdullatif@google.com
diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java
index 4a4c693..5a4561d 100644
--- a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java
+++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureSessionTest.java
@@ -198,7 +198,7 @@
         }
 
         @Override
-        MainContentCaptureSession getMainCaptureSession() {
+        ContentCaptureSession getMainCaptureSession() {
             throw new UnsupportedOperationException("should not have been called");
         }
 
diff --git a/core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionTest.java b/core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionTest.java
index 1cdcb37..b42bcee 100644
--- a/core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionTest.java
+++ b/core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionTest.java
@@ -433,6 +433,72 @@
         assertThat(session.mEvents).isEmpty();
     }
 
+    @Test
+    public void notifyViewAppearedBelowMaximumBufferSize() throws RemoteException {
+        ContentCaptureOptions options =
+                createOptions(
+                        /* enableContentCaptureReceiver= */ true,
+                        /* enableContentProtectionReceiver= */ true);
+        MainContentCaptureSession session = createSession(options);
+        session.mDirectServiceInterface = mMockContentCaptureDirectManager;
+
+        session.onSessionStarted(0x2, null);
+        for (int i = 0; i < BUFFER_SIZE - 1; i++) {
+            View view = prepareView(session);
+            session.notifyViewAppeared(session.newViewStructure(view));
+        }
+        mTestableLooper.processAllMessages();
+
+        verify(mMockContentCaptureDirectManager, times(0))
+                .sendEvents(any(), anyInt(), any());
+        assertThat(session.mEvents).isNull();
+        assertThat(session.mEventProcessQueue).hasSize(BUFFER_SIZE - 1);
+    }
+
+    @Test
+    public void notifyViewAppearedExactAsMaximumBufferSize() throws RemoteException {
+        ContentCaptureOptions options =
+                createOptions(
+                        /* enableContentCaptureReceiver= */ true,
+                        /* enableContentProtectionReceiver= */ true);
+        MainContentCaptureSession session = createSession(options);
+        session.mDirectServiceInterface = mMockContentCaptureDirectManager;
+
+        session.onSessionStarted(0x2, null);
+        for (int i = 0; i < BUFFER_SIZE; i++) {
+            View view = prepareView(session);
+            session.notifyViewAppeared(session.newViewStructure(view));
+        }
+        mTestableLooper.processAllMessages();
+
+        verify(mMockContentCaptureDirectManager, times(1))
+                .sendEvents(any(), anyInt(), any());
+        assertThat(session.mEvents).isEmpty();
+        assertThat(session.mEventProcessQueue).isEmpty();
+    }
+
+    @Test
+    public void notifyViewAppearedAboveMaximumBufferSize() throws RemoteException {
+        ContentCaptureOptions options =
+                createOptions(
+                        /* enableContentCaptureReceiver= */ true,
+                        /* enableContentProtectionReceiver= */ true);
+        MainContentCaptureSession session = createSession(options);
+        session.mDirectServiceInterface = mMockContentCaptureDirectManager;
+
+        session.onSessionStarted(0x2, null);
+        for (int i = 0; i < BUFFER_SIZE * 2 + 1; i++) {
+            View view = prepareView(session);
+            session.notifyViewAppeared(session.newViewStructure(view));
+        }
+        mTestableLooper.processAllMessages();
+
+        verify(mMockContentCaptureDirectManager, times(2))
+                .sendEvents(any(), anyInt(), any());
+        assertThat(session.mEvents).isEmpty();
+        assertThat(session.mEventProcessQueue).hasSize(1);
+    }
+
     /** Simulates the regular content capture events sequence. */
     private void notifyContentCaptureEvents(final MainContentCaptureSession session) {
         final ArrayList<Object> events = new ArrayList<>(
@@ -489,11 +555,13 @@
     }
 
     private MainContentCaptureSession createSession(ContentCaptureManager manager) {
+        final Handler testHandler = Handler.createAsync(mTestableLooper.getLooper());
         MainContentCaptureSession session =
                 new MainContentCaptureSession(
                         sStrippedContext,
                         manager,
-                        Handler.createAsync(mTestableLooper.getLooper()),
+                        testHandler,
+                        testHandler,
                         mMockSystemServerInterface);
         session.mComponentName = COMPONENT_NAME;
         return session;
diff --git a/core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionV2Test.java b/core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionV2Test.java
deleted file mode 100644
index 0075128..0000000
--- a/core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionV2Test.java
+++ /dev/null
@@ -1,596 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.contentcapture;
-
-import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_STARTED;
-import static android.view.contentcapture.ContentCaptureSession.FLUSH_REASON_VIEW_TREE_APPEARED;
-import static android.view.contentcapture.ContentCaptureSession.FLUSH_REASON_VIEW_TREE_APPEARING;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-
-import android.content.ComponentName;
-import android.content.ContentCaptureOptions;
-import android.content.Context;
-import android.content.pm.ParceledListSlice;
-import android.graphics.Insets;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.util.SparseArray;
-import android.view.View;
-import android.view.autofill.AutofillId;
-import android.view.contentprotection.ContentProtectionEventProcessor;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Test for {@link MainContentCaptureSessionV2}.
- *
- * <p>Run with: {@code atest
- * FrameworksCoreTests:android.view.contentcapture.MainContentCaptureSessionV2Test}
- */
-@RunWith(AndroidTestingRunner.class)
-@SmallTest
-@TestableLooper.RunWithLooper
-public class MainContentCaptureSessionV2Test {
-
-    private static final int BUFFER_SIZE = 100;
-
-    private static final int REASON = 123;
-
-    private static final ContentCaptureEvent EVENT =
-            new ContentCaptureEvent(/* sessionId= */ 0, TYPE_SESSION_STARTED);
-
-    private static final ComponentName COMPONENT_NAME =
-            new ComponentName("com.test.package", "TestClass");
-
-    private static final Context sContext = ApplicationProvider.getApplicationContext();
-
-    private static final ContentCaptureManager.StrippedContext sStrippedContext =
-            new ContentCaptureManager.StrippedContext(sContext);
-
-    private TestableLooper mTestableLooper;
-
-    @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
-
-    @Mock private IContentCaptureManager mMockSystemServerInterface;
-
-    @Mock private ContentProtectionEventProcessor mMockContentProtectionEventProcessor;
-
-    @Mock private IContentCaptureDirectManager mMockContentCaptureDirectManager;
-
-    @Before
-    public void setup() {
-        mTestableLooper = TestableLooper.get(this);
-    }
-
-    @Test
-    public void onSessionStarted_contentProtectionEnabled_processorCreated() {
-        MainContentCaptureSessionV2 session = createSession();
-        assertThat(session.mContentProtectionEventProcessor).isNull();
-
-        session.onSessionStarted(/* resultCode= */ 0, /* binder= */ null);
-        mTestableLooper.processAllMessages();
-
-        assertThat(session.mContentProtectionEventProcessor).isNotNull();
-    }
-
-    @Test
-    public void onSessionStarted_contentProtectionDisabled_processorNotCreated() {
-        MainContentCaptureSessionV2 session =
-                createSession(
-                        /* enableContentCaptureReceiver= */ true,
-                        /* enableContentProtectionReceiver= */ false);
-        session.mContentProtectionEventProcessor = mMockContentProtectionEventProcessor;
-
-        session.onSessionStarted(/* resultCode= */ 0, /* binder= */ null);
-        mTestableLooper.processAllMessages();
-
-        assertThat(session.mContentProtectionEventProcessor).isNull();
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
-    }
-
-    @Test
-    public void onSessionStarted_contentProtectionNoBuffer_processorNotCreated() {
-        ContentCaptureOptions options =
-                createOptions(
-                        /* enableContentCaptureReceiver= */ true,
-                        new ContentCaptureOptions.ContentProtectionOptions(
-                                /* enableReceiver= */ true,
-                                -BUFFER_SIZE,
-                                /* requiredGroups= */ List.of(List.of("a")),
-                                /* optionalGroups= */ Collections.emptyList(),
-                                /* optionalGroupsThreshold= */ 0));
-        MainContentCaptureSessionV2 session = createSession(options);
-        session.mContentProtectionEventProcessor = mMockContentProtectionEventProcessor;
-
-        session.onSessionStarted(/* resultCode= */ 0, /* binder= */ null);
-        mTestableLooper.processAllMessages();
-
-        assertThat(session.mContentProtectionEventProcessor).isNull();
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
-    }
-
-    @Test
-    public void onSessionStarted_contentProtectionNoGroups_processorNotCreated() {
-        ContentCaptureOptions options =
-                createOptions(
-                        /* enableContentCaptureReceiver= */ true,
-                        new ContentCaptureOptions.ContentProtectionOptions(
-                                /* enableReceiver= */ true,
-                                BUFFER_SIZE,
-                                /* requiredGroups= */ Collections.emptyList(),
-                                /* optionalGroups= */ Collections.emptyList(),
-                                /* optionalGroupsThreshold= */ 0));
-        MainContentCaptureSessionV2 session = createSession(options);
-        session.mContentProtectionEventProcessor = mMockContentProtectionEventProcessor;
-
-        session.onSessionStarted(/* resultCode= */ 0, /* binder= */ null);
-        mTestableLooper.processAllMessages();
-
-        assertThat(session.mContentProtectionEventProcessor).isNull();
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
-    }
-
-    @Test
-    public void onSessionStarted_noComponentName_processorNotCreated() {
-        MainContentCaptureSessionV2 session = createSession();
-        session.mComponentName = null;
-
-        session.onSessionStarted(/* resultCode= */ 0, /* binder= */ null);
-        mTestableLooper.processAllMessages();
-
-        assertThat(session.mContentProtectionEventProcessor).isNull();
-    }
-
-    @Test
-    public void sendEvent_contentCaptureDisabled_contentProtectionDisabled() {
-        MainContentCaptureSessionV2 session =
-                createSession(
-                        /* enableContentCaptureReceiver= */ false,
-                        /* enableContentProtectionReceiver= */ false);
-        session.mContentProtectionEventProcessor = mMockContentProtectionEventProcessor;
-
-        session.sendEvent(EVENT);
-        mTestableLooper.processAllMessages();
-
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
-        assertThat(session.mEvents).isNull();
-    }
-
-    @Test
-    public void sendEvent_contentCaptureDisabled_contentProtectionEnabled() {
-        MainContentCaptureSessionV2 session =
-                createSession(
-                        /* enableContentCaptureReceiver= */ false,
-                        /* enableContentProtectionReceiver= */ true);
-        session.mContentProtectionEventProcessor = mMockContentProtectionEventProcessor;
-
-        session.sendEvent(EVENT);
-        mTestableLooper.processAllMessages();
-
-        verify(mMockContentProtectionEventProcessor).processEvent(EVENT);
-        assertThat(session.mEvents).isNull();
-    }
-
-    @Test
-    public void sendEvent_contentCaptureEnabled_contentProtectionDisabled() {
-        MainContentCaptureSessionV2 session =
-                createSession(
-                        /* enableContentCaptureReceiver= */ true,
-                        /* enableContentProtectionReceiver= */ false);
-        session.mContentProtectionEventProcessor = mMockContentProtectionEventProcessor;
-
-        session.sendEvent(EVENT);
-        mTestableLooper.processAllMessages();
-
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
-        assertThat(session.mEvents).isNotNull();
-        assertThat(session.mEvents).containsExactly(EVENT);
-    }
-
-    @Test
-    public void sendEvent_contentCaptureEnabled_contentProtectionEnabled() {
-        MainContentCaptureSessionV2 session = createSession();
-        session.mContentProtectionEventProcessor = mMockContentProtectionEventProcessor;
-
-        session.sendEvent(EVENT);
-        mTestableLooper.processAllMessages();
-
-        verify(mMockContentProtectionEventProcessor).processEvent(EVENT);
-        assertThat(session.mEvents).isNotNull();
-        assertThat(session.mEvents).containsExactly(EVENT);
-    }
-
-    @Test
-    public void sendEvent_contentProtectionEnabled_processorNotCreated() {
-        MainContentCaptureSessionV2 session =
-                createSession(
-                        /* enableContentCaptureReceiver= */ false,
-                        /* enableContentProtectionReceiver= */ true);
-
-        session.sendEvent(EVENT);
-        mTestableLooper.processAllMessages();
-
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
-        assertThat(session.mEvents).isNull();
-    }
-
-    @Test
-    public void flush_contentCaptureDisabled_contentProtectionDisabled() throws Exception {
-        ContentCaptureOptions options =
-                createOptions(
-                        /* enableContentCaptureReceiver= */ false,
-                        /* enableContentProtectionReceiver= */ false);
-        MainContentCaptureSessionV2 session = createSession(options);
-        session.mEvents = new ArrayList<>(Arrays.asList(EVENT));
-        session.mDirectServiceInterface = mMockContentCaptureDirectManager;
-
-        session.flush(REASON);
-        mTestableLooper.processAllMessages();
-
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
-        verifyZeroInteractions(mMockContentCaptureDirectManager);
-        assertThat(session.mEvents).containsExactly(EVENT);
-    }
-
-    @Test
-    public void flush_contentCaptureDisabled_contentProtectionEnabled() {
-        MainContentCaptureSessionV2 session =
-                createSession(
-                        /* enableContentCaptureReceiver= */ false,
-                        /* enableContentProtectionReceiver= */ true);
-        session.mEvents = new ArrayList<>(Arrays.asList(EVENT));
-        session.mDirectServiceInterface = mMockContentCaptureDirectManager;
-
-        session.flush(REASON);
-        mTestableLooper.processAllMessages();
-
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
-        verifyZeroInteractions(mMockContentCaptureDirectManager);
-        assertThat(session.mEvents).containsExactly(EVENT);
-    }
-
-    @Test
-    public void flush_contentCaptureEnabled_contentProtectionDisabled() throws Exception {
-        ContentCaptureOptions options =
-                createOptions(
-                        /* enableContentCaptureReceiver= */ true,
-                        /* enableContentProtectionReceiver= */ false);
-        MainContentCaptureSessionV2 session = createSession(options);
-        session.mEvents = new ArrayList<>(Arrays.asList(EVENT));
-        session.mDirectServiceInterface = mMockContentCaptureDirectManager;
-
-        session.flush(REASON);
-        mTestableLooper.processAllMessages();
-
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
-        assertThat(session.mEvents).isEmpty();
-        assertEventFlushedContentCapture(options);
-    }
-
-    @Test
-    public void flush_contentCaptureEnabled_contentProtectionEnabled() throws Exception {
-        ContentCaptureOptions options =
-                createOptions(
-                        /* enableContentCaptureReceiver= */ true,
-                        /* enableContentProtectionReceiver= */ true);
-        MainContentCaptureSessionV2 session = createSession(options);
-        session.mEvents = new ArrayList<>(Arrays.asList(EVENT));
-        session.mDirectServiceInterface = mMockContentCaptureDirectManager;
-
-        session.flush(REASON);
-        mTestableLooper.processAllMessages();
-
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
-        assertThat(session.mEvents).isEmpty();
-        assertEventFlushedContentCapture(options);
-    }
-
-    @Test
-    public void destroySession() throws Exception {
-        MainContentCaptureSessionV2 session = createSession();
-        session.mContentProtectionEventProcessor = mMockContentProtectionEventProcessor;
-
-        session.destroySession();
-        mTestableLooper.processAllMessages();
-
-        verify(mMockSystemServerInterface).finishSession(anyInt());
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
-        assertThat(session.mDirectServiceInterface).isNull();
-        assertThat(session.mContentProtectionEventProcessor).isNull();
-    }
-
-    @Test
-    public void resetSession() {
-        MainContentCaptureSessionV2 session = createSession();
-        session.mContentProtectionEventProcessor = mMockContentProtectionEventProcessor;
-
-        session.resetSession(/* newState= */ 0);
-        mTestableLooper.processAllMessages();
-
-        verifyZeroInteractions(mMockSystemServerInterface);
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
-        assertThat(session.mDirectServiceInterface).isNull();
-        assertThat(session.mContentProtectionEventProcessor).isNull();
-    }
-
-    @Test
-    @SuppressWarnings("GuardedBy")
-    public void notifyContentCaptureEvents_notStarted_ContentCaptureDisabled_ProtectionDisabled() {
-        ContentCaptureOptions options =
-                createOptions(
-                        /* enableContentCaptureReceiver= */ false,
-                        /* enableContentProtectionReceiver= */ false);
-        MainContentCaptureSessionV2 session = createSession(options);
-
-        notifyContentCaptureEvents(session);
-        mTestableLooper.processAllMessages();
-
-        verifyZeroInteractions(mMockContentCaptureDirectManager);
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
-        assertThat(session.mEvents).isNull();
-    }
-
-    @Test
-    @SuppressWarnings("GuardedBy")
-    public void notifyContentCaptureEvents_started_ContentCaptureDisabled_ProtectionDisabled() {
-        ContentCaptureOptions options =
-                createOptions(
-                        /* enableContentCaptureReceiver= */ false,
-                        /* enableContentProtectionReceiver= */ false);
-        MainContentCaptureSessionV2 session = createSession(options);
-
-        session.onSessionStarted(0x2, null);
-        notifyContentCaptureEvents(session);
-        mTestableLooper.processAllMessages();
-
-        verifyZeroInteractions(mMockContentCaptureDirectManager);
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
-        assertThat(session.mEvents).isNull();
-    }
-
-    @Test
-    @SuppressWarnings("GuardedBy")
-    public void notifyContentCaptureEvents_notStarted_ContentCaptureEnabled_ProtectionEnabled() {
-        ContentCaptureOptions options =
-                createOptions(
-                        /* enableContentCaptureReceiver= */ true,
-                        /* enableContentProtectionReceiver= */ true);
-        MainContentCaptureSessionV2 session = createSession(options);
-        session.mDirectServiceInterface = mMockContentCaptureDirectManager;
-        session.mContentProtectionEventProcessor = mMockContentProtectionEventProcessor;
-
-        notifyContentCaptureEvents(session);
-        mTestableLooper.processAllMessages();
-
-        verifyZeroInteractions(mMockContentCaptureDirectManager);
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
-        assertThat(session.mEvents).isNull();
-    }
-
-    @Test
-    @SuppressWarnings("GuardedBy")
-    public void notifyContentCaptureEvents_started_ContentCaptureEnabled_ProtectionEnabled()
-            throws RemoteException {
-        ContentCaptureOptions options =
-                createOptions(
-                        /* enableContentCaptureReceiver= */ true,
-                        /* enableContentProtectionReceiver= */ true);
-        MainContentCaptureSessionV2 session = createSession(options);
-        session.mDirectServiceInterface = mMockContentCaptureDirectManager;
-
-        session.onSessionStarted(0x2, null);
-        // Override the processor for interaction verification.
-        session.mContentProtectionEventProcessor = mMockContentProtectionEventProcessor;
-        notifyContentCaptureEvents(session);
-        mTestableLooper.processAllMessages();
-
-        // Force flush will happen twice.
-        verify(mMockContentCaptureDirectManager, times(1))
-                .sendEvents(any(), eq(FLUSH_REASON_VIEW_TREE_APPEARING), any());
-        verify(mMockContentCaptureDirectManager, times(1))
-                .sendEvents(any(), eq(FLUSH_REASON_VIEW_TREE_APPEARED), any());
-        // Other than the five view events, there will be two additional tree appearing events.
-        verify(mMockContentProtectionEventProcessor, times(7)).processEvent(any());
-        assertThat(session.mEvents).isEmpty();
-    }
-
-    @Test
-    public void notifyViewAppearedBelowMaximumBufferSize() throws RemoteException {
-        ContentCaptureOptions options =
-                createOptions(
-                        /* enableContentCaptureReceiver= */ true,
-                        /* enableContentProtectionReceiver= */ true);
-        MainContentCaptureSessionV2 session = createSession(options);
-        session.mDirectServiceInterface = mMockContentCaptureDirectManager;
-
-        session.onSessionStarted(0x2, null);
-        for (int i = 0; i < BUFFER_SIZE - 1; i++) {
-            View view = prepareView(session);
-            session.notifyViewAppeared(session.newViewStructure(view));
-        }
-        mTestableLooper.processAllMessages();
-
-        verify(mMockContentCaptureDirectManager, times(0))
-                .sendEvents(any(), anyInt(), any());
-        assertThat(session.mEvents).isNull();
-        assertThat(session.mEventProcessQueue).hasSize(BUFFER_SIZE - 1);
-    }
-
-    @Test
-    public void notifyViewAppearedExactAsMaximumBufferSize() throws RemoteException {
-        ContentCaptureOptions options =
-                createOptions(
-                        /* enableContentCaptureReceiver= */ true,
-                        /* enableContentProtectionReceiver= */ true);
-        MainContentCaptureSessionV2 session = createSession(options);
-        session.mDirectServiceInterface = mMockContentCaptureDirectManager;
-
-        session.onSessionStarted(0x2, null);
-        for (int i = 0; i < BUFFER_SIZE; i++) {
-            View view = prepareView(session);
-            session.notifyViewAppeared(session.newViewStructure(view));
-        }
-        mTestableLooper.processAllMessages();
-
-        verify(mMockContentCaptureDirectManager, times(1))
-                .sendEvents(any(), anyInt(), any());
-        assertThat(session.mEvents).isEmpty();
-        assertThat(session.mEventProcessQueue).isEmpty();
-    }
-
-    @Test
-    public void notifyViewAppearedAboveMaximumBufferSize() throws RemoteException {
-        ContentCaptureOptions options =
-                createOptions(
-                        /* enableContentCaptureReceiver= */ true,
-                        /* enableContentProtectionReceiver= */ true);
-        MainContentCaptureSessionV2 session = createSession(options);
-        session.mDirectServiceInterface = mMockContentCaptureDirectManager;
-
-        session.onSessionStarted(0x2, null);
-        for (int i = 0; i < BUFFER_SIZE * 2 + 1; i++) {
-            View view = prepareView(session);
-            session.notifyViewAppeared(session.newViewStructure(view));
-        }
-        mTestableLooper.processAllMessages();
-
-        verify(mMockContentCaptureDirectManager, times(2))
-                .sendEvents(any(), anyInt(), any());
-        assertThat(session.mEvents).isEmpty();
-        assertThat(session.mEventProcessQueue).hasSize(1);
-    }
-
-    /** Simulates the regular content capture events sequence. */
-    private void notifyContentCaptureEvents(final MainContentCaptureSessionV2 session) {
-        final ArrayList<Object> events = new ArrayList<>(
-                List.of(
-                        prepareView(session),
-                        prepareView(session),
-                        new AutofillId(0),
-                        prepareView(session),
-                        Insets.of(0, 0, 0, 0)
-                )
-        );
-
-        final SparseArray<ArrayList<Object>> contentCaptureEvents = new SparseArray<>();
-        contentCaptureEvents.set(session.getId(), events);
-
-        session.notifyContentCaptureEvents(contentCaptureEvents);
-    }
-
-    private View prepareView(final MainContentCaptureSessionV2 session) {
-        final View view = new View(sContext);
-        view.setContentCaptureSession(session);
-        return view;
-    }
-
-    private static ContentCaptureOptions createOptions(
-            boolean enableContentCaptureReceiver,
-            ContentCaptureOptions.ContentProtectionOptions contentProtectionOptions) {
-        return new ContentCaptureOptions(
-                /* loggingLevel= */ 0,
-                BUFFER_SIZE,
-                /* idleFlushingFrequencyMs= */ 0,
-                /* textChangeFlushingFrequencyMs= */ 0,
-                /* logHistorySize= */ 0,
-                /* disableFlushForViewTreeAppearing= */ false,
-                enableContentCaptureReceiver,
-                contentProtectionOptions,
-                /* whitelistedComponents= */ null);
-    }
-
-    private static ContentCaptureOptions createOptions(
-            boolean enableContentCaptureReceiver, boolean enableContentProtectionReceiver) {
-        return createOptions(
-                enableContentCaptureReceiver,
-                new ContentCaptureOptions.ContentProtectionOptions(
-                        enableContentProtectionReceiver,
-                        BUFFER_SIZE,
-                        /* requiredGroups= */ List.of(List.of("a")),
-                        /* optionalGroups= */ Collections.emptyList(),
-                        /* optionalGroupsThreshold= */ 0));
-    }
-
-    private ContentCaptureManager createManager(ContentCaptureOptions options) {
-        return new ContentCaptureManager(sContext, mMockSystemServerInterface, options);
-    }
-
-    private MainContentCaptureSessionV2 createSession(ContentCaptureManager manager) {
-        final Handler testHandler = Handler.createAsync(mTestableLooper.getLooper());
-        MainContentCaptureSessionV2 session =
-                new MainContentCaptureSessionV2(
-                        sStrippedContext,
-                        manager,
-                        testHandler,
-                        testHandler,
-                        mMockSystemServerInterface);
-        session.mComponentName = COMPONENT_NAME;
-        return session;
-    }
-
-    private MainContentCaptureSessionV2 createSession(ContentCaptureOptions options) {
-        return createSession(createManager(options));
-    }
-
-    private MainContentCaptureSessionV2 createSession(
-            boolean enableContentCaptureReceiver, boolean enableContentProtectionReceiver) {
-        return createSession(
-                createOptions(enableContentCaptureReceiver, enableContentProtectionReceiver));
-    }
-
-    private MainContentCaptureSessionV2 createSession() {
-        return createSession(
-                /* enableContentCaptureReceiver= */ true,
-                /* enableContentProtectionReceiver= */ true);
-    }
-
-    private void assertEventFlushedContentCapture(ContentCaptureOptions options) throws Exception {
-        ArgumentCaptor<ParceledListSlice> captor = ArgumentCaptor.forClass(ParceledListSlice.class);
-        verify(mMockContentCaptureDirectManager)
-                .sendEvents(captor.capture(), eq(REASON), eq(options));
-
-        assertThat(captor.getValue()).isNotNull();
-        List<ContentCaptureEvent> actual = captor.getValue().getList();
-        assertThat(actual).isNotNull();
-        assertThat(actual).containsExactly(EVENT);
-    }
-}
diff --git a/core/tests/coretests/src/android/widget/RemoteViewsAdapterTest.java b/core/tests/coretests/src/android/widget/RemoteViewsAdapterTest.java
index 6ab77dc..534420e 100644
--- a/core/tests/coretests/src/android/widget/RemoteViewsAdapterTest.java
+++ b/core/tests/coretests/src/android/widget/RemoteViewsAdapterTest.java
@@ -355,7 +355,8 @@
         }
 
         @Override
-        public RemoteViews.RemoteCollectionItems getRemoteCollectionItems(int capSize) {
+        public RemoteViews.RemoteCollectionItems getRemoteCollectionItems(int capSize,
+                int capBitmapSize) {
             RemoteViews.RemoteCollectionItems.Builder itemsBuilder =
                     new RemoteViews.RemoteCollectionItems.Builder();
             itemsBuilder.setHasStableIds(hasStableIds())
diff --git a/core/tests/coretests/src/android/widget/RemoteViewsProtoTest.java b/core/tests/coretests/src/android/widget/RemoteViewsProtoTest.java
new file mode 100644
index 0000000..8e9ba7b
--- /dev/null
+++ b/core/tests/coretests/src/android/widget/RemoteViewsProtoTest.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.widget;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import android.content.Context;
+import android.util.SizeF;
+import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoOutputStream;
+import android.view.View;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.frameworks.coretests.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+
+import java.util.Map;
+
+/**
+ * Tests for RemoteViews.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class RemoteViewsProtoTest {
+
+    // This can point to any other package which exists on the device.
+    private static final String OTHER_PACKAGE = "com.android.systemui";
+
+    @Rule
+    public final ExpectedException exception = ExpectedException.none();
+
+    private Context mContext;
+    private String mPackage;
+    private LinearLayout mContainer;
+
+    @Before
+    public void setup() {
+        mContext = InstrumentationRegistry.getContext();
+        mPackage = mContext.getPackageName();
+        mContainer = new LinearLayout(mContext);
+    }
+
+    @Test
+    public void copy_canStillBeApplied() {
+        RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test);
+
+        RemoteViews clone = recreateFromProto(original);
+
+        clone.apply(mContext, mContainer);
+    }
+
+    @SuppressWarnings("ReturnValueIgnored")
+    @Test
+    public void clone_repeatedly() {
+        RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test);
+
+        recreateFromProto(original);
+        recreateFromProto(original);
+
+        original.apply(mContext, mContainer);
+    }
+
+    @Test
+    public void clone_chained() {
+        RemoteViews original = new RemoteViews(mPackage, R.layout.remote_views_test);
+
+        RemoteViews clone = recreateFromProto(recreateFromProto(original));
+
+
+        clone.apply(mContext, mContainer);
+    }
+
+    @Test
+    public void landscapePortraitViews_lightBackgroundLayoutFlag() {
+        RemoteViews inner = new RemoteViews(mPackage, R.layout.remote_views_text);
+        inner.setLightBackgroundLayoutId(R.layout.remote_views_light_background_text);
+
+        RemoteViews parent = new RemoteViews(inner, inner);
+        parent.addFlags(RemoteViews.FLAG_USE_LIGHT_BACKGROUND_LAYOUT);
+
+        View view = recreateFromProto(parent).apply(mContext, mContainer);
+        assertNull(view.findViewById(R.id.text));
+        assertNotNull(view.findViewById(R.id.light_background_text));
+    }
+
+    @Test
+    public void sizedViews_lightBackgroundLayoutFlag() {
+        RemoteViews inner = new RemoteViews(mPackage, R.layout.remote_views_text);
+        inner.setLightBackgroundLayoutId(R.layout.remote_views_light_background_text);
+
+        RemoteViews parent = new RemoteViews(
+                Map.of(new SizeF(0, 0), inner, new SizeF(100, 100), inner));
+        parent.addFlags(RemoteViews.FLAG_USE_LIGHT_BACKGROUND_LAYOUT);
+
+        View view = recreateFromProto(parent).apply(mContext, mContainer);
+        assertNull(view.findViewById(R.id.text));
+        assertNotNull(view.findViewById(R.id.light_background_text));
+    }
+
+    @Test
+    public void nestedLandscapeViews() throws Exception {
+        RemoteViews views = new RemoteViews(mPackage, R.layout.remote_views_test);
+        for (int i = 0; i < 10; i++) {
+            views = new RemoteViews(views, new RemoteViews(mPackage, R.layout.remote_views_test));
+        }
+        // writeTo/createFromProto works
+        recreateFromProto(views);
+
+        views = new RemoteViews(mPackage, R.layout.remote_views_test);
+        for (int i = 0; i < 11; i++) {
+            views = new RemoteViews(views, new RemoteViews(mPackage, R.layout.remote_views_test));
+        }
+        // writeTo/createFromProto fails
+        exception.expect(IllegalArgumentException.class);
+        recreateFromProtoNoRethrow(views);
+    }
+
+    private RemoteViews recreateFromProto(RemoteViews views) {
+        try {
+            return recreateFromProtoNoRethrow(views);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private RemoteViews recreateFromProtoNoRethrow(RemoteViews views) throws Exception {
+        ProtoOutputStream out = new ProtoOutputStream();
+        views.writePreviewToProto(mContext, out);
+        ProtoInputStream in = new ProtoInputStream(out.getBytes());
+        return RemoteViews.createPreviewFromProto(mContext, in);
+    }
+}
diff --git a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
index b0190a5..d4482f2 100644
--- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
+++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
@@ -112,7 +112,7 @@
         doReturn(mApplicationInfo).when(mContext).getApplicationInfo();
 
         mDispatcher = new WindowOnBackInvokedDispatcher(mContext, Looper.getMainLooper());
-        mDispatcher.attachToWindow(mWindowSession, mWindow, mImeBackAnimationController);
+        mDispatcher.attachToWindow(mWindowSession, mWindow, null, mImeBackAnimationController);
     }
 
     private void waitForIdle() {
@@ -455,25 +455,26 @@
 
     @Test
     public void registerImeCallbacks_onBackInvokedCallbackEnabled() throws RemoteException {
-        mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mDefaultImeCallback);
+        verifyImeCallackRegistrations();
+    }
+
+    @Test
+    public void registerImeCallbacks_onBackInvokedCallbackDisabled() throws RemoteException {
+        doReturn(false).when(mApplicationInfo).isOnBackInvokedCallbackEnabled();
+        verifyImeCallackRegistrations();
+    }
+
+    private void verifyImeCallackRegistrations() throws RemoteException {
+        // verify default callback is replaced with ImeBackAnimationController
+        mDispatcher.registerOnBackInvokedCallbackUnchecked(mDefaultImeCallback, PRIORITY_DEFAULT);
         assertCallbacksSize(/* default */ 1, /* overlay */ 0);
         assertSetCallbackInfo();
         assertTopCallback(mImeBackAnimationController);
 
-        mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mImeCallback);
+        // verify regular ime callback is successfully registered
+        mDispatcher.registerOnBackInvokedCallbackUnchecked(mImeCallback, PRIORITY_DEFAULT);
         assertCallbacksSize(/* default */ 2, /* overlay */ 0);
         assertSetCallbackInfo();
         assertTopCallback(mImeCallback);
     }
-
-    @Test
-    public void registerImeCallbacks_legacyBack() throws RemoteException {
-        doReturn(false).when(mApplicationInfo).isOnBackInvokedCallbackEnabled();
-
-        mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mDefaultImeCallback);
-        assertNoSetCallbackInfo();
-
-        mDispatcher.registerOnBackInvokedCallback(PRIORITY_DEFAULT, mImeCallback);
-        assertNoSetCallbackInfo();
-    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
index 6b9dbba..f78bc92 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
@@ -71,6 +71,7 @@
 import android.speech.tts.TextToSpeech;
 import android.speech.tts.Voice;
 import android.test.mock.MockContentResolver;
+import android.view.Display;
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityManager;
@@ -378,7 +379,8 @@
         verify(mAlertDialog).show();
         verify(mAccessibilityManagerService, atLeastOnce()).getInstalledAccessibilityServiceList(
                 anyInt());
-        verify(mAccessibilityManagerService, times(0)).performAccessibilityShortcut(null);
+        verify(mAccessibilityManagerService, times(0)).performAccessibilityShortcut(
+                Display.DEFAULT_DISPLAY, HARDWARE, null);
         verify(mFrameworkObjectProvider, times(0)).getTextToSpeech(any(), any());
     }
 
@@ -397,7 +399,8 @@
         // assertEquals(WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS,
         //        mLayoutParams.privateFlags
         //                & WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS);
-        verify(mAccessibilityManagerService, times(1)).performAccessibilityShortcut(null);
+        verify(mAccessibilityManagerService, times(1)).performAccessibilityShortcut(
+                Display.DEFAULT_DISPLAY, HARDWARE, null);
     }
 
     @Test
@@ -630,7 +633,8 @@
 
         verifyZeroInteractions(mAlertDialogBuilder, mAlertDialog);
         verify(mToast).show();
-        verify(mAccessibilityManagerService).performAccessibilityShortcut(null);
+        verify(mAccessibilityManagerService).performAccessibilityShortcut(
+                Display.DEFAULT_DISPLAY, HARDWARE, null);
     }
 
     @Test
@@ -649,7 +653,8 @@
         verify(mAccessibilityManagerService).enableShortcutsForTargets(
                 eq(true), eq(HARDWARE), mListCaptor.capture(), anyInt());
         assertThat(mListCaptor.getValue()).containsExactly(SERVICE_NAME_STRING);
-        verify(mAccessibilityManagerService).performAccessibilityShortcut(null);
+        verify(mAccessibilityManagerService).performAccessibilityShortcut(
+                Display.DEFAULT_DISPLAY, HARDWARE, null);
     }
 
     @Test
@@ -666,7 +671,8 @@
 
         assertThat(Settings.Secure.getString(mContentResolver,
                 ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)).isEqualTo(SERVICE_NAME_STRING);
-        verify(mAccessibilityManagerService).performAccessibilityShortcut(null);
+        verify(mAccessibilityManagerService).performAccessibilityShortcut(
+                Display.DEFAULT_DISPLAY, HARDWARE, null);
     }
 
     @Test
@@ -726,7 +732,8 @@
         Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
                 AccessibilityShortcutController.DialogStatus.SHOWN);
         getController().performAccessibilityShortcut();
-        verify(mAccessibilityManagerService).performAccessibilityShortcut(null);
+        verify(mAccessibilityManagerService).performAccessibilityShortcut(
+                Display.DEFAULT_DISPLAY, HARDWARE, null);
     }
 
     @Test
@@ -739,7 +746,8 @@
         getController().performAccessibilityShortcut();
 
         verifyZeroInteractions(mToast);
-        verify(mAccessibilityManagerService).performAccessibilityShortcut(null);
+        verify(mAccessibilityManagerService).performAccessibilityShortcut(
+                Display.DEFAULT_DISPLAY, HARDWARE, null);
     }
 
     @Test
@@ -755,7 +763,8 @@
         getController().performAccessibilityShortcut();
 
         verifyZeroInteractions(mToast);
-        verify(mAccessibilityManagerService).performAccessibilityShortcut(null);
+        verify(mAccessibilityManagerService).performAccessibilityShortcut(
+                Display.DEFAULT_DISPLAY, HARDWARE, null);
     }
 
     @Test
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/dialog/AccessibilityTargetHelperTest.java b/core/tests/coretests/src/com/android/internal/accessibility/dialog/AccessibilityTargetHelperTest.java
new file mode 100644
index 0000000..64be97d
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/accessibility/dialog/AccessibilityTargetHelperTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.accessibility.dialog;
+
+import static android.accessibilityservice.AccessibilityServiceInfo.DEFAULT;
+import static android.accessibilityservice.AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON;
+
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.os.Build;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityTargetHelperTest {
+    @Test
+    public void isValidServiceTarget_legacyService_hardware_isTrue() {
+        assertThat(AccessibilityTargetHelper.isValidServiceTarget(generateServiceInfo(
+                /* flags = */ 0, /* targetSdk = */ 0), HARDWARE)).isTrue();
+    }
+
+    @Test
+    public void isValidServiceTarget_legacyService_software_requestsButton_isTrue() {
+        assertThat(AccessibilityTargetHelper.isValidServiceTarget(generateServiceInfo(
+                FLAG_REQUEST_ACCESSIBILITY_BUTTON, /* targetSdk = */ 0), SOFTWARE)).isTrue();
+    }
+
+    @Test
+    public void isValidServiceTarget_legacyService_software_isFalse() {
+        assertThat(AccessibilityTargetHelper.isValidServiceTarget(generateServiceInfo(
+                /* flags = */ 0, /* targetSdk = */ 0), SOFTWARE)).isFalse();
+    }
+
+    @Test
+    public void isValidServiceTarget_modernService_isTrue() {
+        assertThat(AccessibilityTargetHelper.isValidServiceTarget(generateServiceInfo(
+                /* flags = */ 0, Build.VERSION_CODES.Q + 1), DEFAULT)).isTrue();
+    }
+
+    private AccessibilityServiceInfo generateServiceInfo(int flags, int targetSdk) {
+        AccessibilityServiceInfo info = new AccessibilityServiceInfo();
+        info.flags = flags;
+        info.setResolveInfo(new ResolveInfo());
+        info.getResolveInfo().serviceInfo = new ServiceInfo();
+        info.getResolveInfo().serviceInfo.applicationInfo = new ApplicationInfo();
+        info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = targetSdk;
+        return info;
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/dialog/AccessibilityTargetTest.java b/core/tests/coretests/src/com/android/internal/accessibility/dialog/AccessibilityTargetTest.java
new file mode 100644
index 0000000..f01ac6f
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/accessibility/dialog/AccessibilityTargetTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.accessibility.dialog;
+
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
+import android.provider.Flags;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.accessibility.common.ShortcutConstants;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.stream.IntStream;
+
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityTargetTest {
+    @Rule
+    public SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+    private static final int[] EXPECTED_TYPES = { HARDWARE, SOFTWARE };
+    private static final int[] EXPECTED_TYPES_GESTURE = { HARDWARE, SOFTWARE, GESTURE };
+
+    @Test
+    @DisableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
+    public void isRecognizedShortcutType_expectedType_isTrue() {
+        for (int type : EXPECTED_TYPES) {
+            assertThat(AccessibilityTarget.isRecognizedShortcutType(type)).isTrue();
+        }
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
+    public void isRecognizedShortcutType_notExpectedType_isFalse() {
+        for (int type: ShortcutConstants.USER_SHORTCUT_TYPES) {
+            if (IntStream.of(EXPECTED_TYPES).noneMatch(x -> x == type)) {
+                assertThat(AccessibilityTarget.isRecognizedShortcutType(type)).isFalse();
+            }
+        }
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
+    public void isRecognizedShortcutType_expectedType_gestureIncluded_isTrue() {
+        for (int type : EXPECTED_TYPES_GESTURE) {
+            if (!AccessibilityTarget.isRecognizedShortcutType(type)) {
+                throw new AssertionError(
+                        "Shortcut type " + type + " should be recognized");
+            }
+        }
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED)
+    public void isRecognizedShortcutType_notExpectedType_gestureIncluded_isFalse() {
+        for (int type: ShortcutConstants.USER_SHORTCUT_TYPES) {
+            if (IntStream.of(EXPECTED_TYPES_GESTURE).noneMatch(x -> x == type)) {
+                if (AccessibilityTarget.isRecognizedShortcutType(type)) {
+                    throw new AssertionError(
+                            "Shortcut type " + type + " should not be recognized");
+                }
+            }
+        }
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/util/ShortcutUtilsTest.java b/core/tests/coretests/src/com/android/internal/accessibility/util/ShortcutUtilsTest.java
index 708f246..8bebc62 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/util/ShortcutUtilsTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/util/ShortcutUtilsTest.java
@@ -20,38 +20,35 @@
 import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER;
 
 import static com.android.internal.accessibility.common.ShortcutConstants.SERVICES_SEPARATOR;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
+import android.annotation.UserIdInt;
 import android.content.ComponentName;
-import android.content.ContentResolver;
 import android.content.Context;
-import android.content.ContextWrapper;
 import android.content.pm.ParceledListSlice;
 import android.os.Handler;
 import android.os.RemoteException;
-import android.os.UserHandle;
 import android.provider.Settings;
+import android.testing.TestableContext;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.IAccessibilityManager;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.accessibility.AccessibilityShortcutController;
 import com.android.internal.accessibility.TestUtils;
 import com.android.internal.accessibility.common.ShortcutConstants;
-import com.android.internal.util.test.FakeSettingsProvider;
-import com.android.internal.util.test.FakeSettingsProviderRule;
 
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -79,39 +76,32 @@
     private static final String STANDARD_SERVICE_COMPONENT_NAME =
             "fake.package/fake.standard.service.name";
     private static final String SERVICE_NAME_SUMMARY = "Summary";
-
-    @Rule
-    public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
     @Mock
     private IAccessibilityManager mAccessibilityManagerService;
-    private ContextWrapper mContextSpy;
+    private TestableContext mContext;
+    @UserIdInt
+    private int mDefaultUserId;
 
     @Before
     public void setUp() throws RemoteException {
         MockitoAnnotations.initMocks(this);
-        mContextSpy = spy(
-                new ContextWrapper(InstrumentationRegistry.getInstrumentation().getContext()));
-
-        ContentResolver contentResolver = mSettingsProviderRule.mockContentResolver(mContextSpy);
-        when(mContextSpy.getContentResolver()).thenReturn(contentResolver);
+        mContext = new TestableContext(InstrumentationRegistry.getInstrumentation().getContext());
+        mDefaultUserId = mContext.getContentResolver().getUserId();
 
         AccessibilityManager accessibilityManager =
                 new AccessibilityManager(
-                        mContextSpy, mock(Handler.class),
-                        mAccessibilityManagerService, UserHandle.myUserId(),
+                        mContext, mock(Handler.class),
+                        mAccessibilityManagerService, mDefaultUserId,
                         /* serviceConnect= */ true);
-        when(mContextSpy.getSystemService(Context.ACCESSIBILITY_SERVICE))
-                .thenReturn(accessibilityManager);
-
-        setupFakeA11yServiceInfos();
+        mContext.addMockSystemService(Context.ACCESSIBILITY_SERVICE, accessibilityManager);
+        setupFakeInstalledA11yServiceInfos();
     }
 
     @Test
     public void getShortcutTargets_softwareShortcutNoService_emptyResult() {
         assertThat(
                 ShortcutUtils.getShortcutTargetsFromSettings(
-                        mContextSpy,
-                        ShortcutConstants.UserShortcutType.SOFTWARE, UserHandle.myUserId())
+                        mContext, SOFTWARE, mDefaultUserId)
         ).isEmpty();
     }
 
@@ -119,8 +109,16 @@
     public void getShortcutTargets_volumeKeyShortcutNoService_emptyResult() {
         assertThat(
                 ShortcutUtils.getShortcutTargetsFromSettings(
-                        mContextSpy, ShortcutConstants.UserShortcutType.HARDWARE,
-                        UserHandle.myUserId())
+                        mContext, ShortcutConstants.UserShortcutType.HARDWARE,
+                        mDefaultUserId)
+        ).isEmpty();
+    }
+
+    @Test
+    public void getShortcutTargets_gestureShortcutNoService_emptyResult() {
+        assertThat(
+                ShortcutUtils.getShortcutTargetsFromSettings(
+                        mContext, GESTURE, mDefaultUserId)
         ).isEmpty();
     }
 
@@ -131,8 +129,8 @@
 
         assertThat(
                 ShortcutUtils.getShortcutTargetsFromSettings(
-                        mContextSpy, ShortcutConstants.UserShortcutType.SOFTWARE,
-                        UserHandle.myUserId())
+                        mContext, SOFTWARE,
+                        mDefaultUserId)
         ).containsExactlyElementsIn(ONE_COMPONENT);
     }
 
@@ -143,8 +141,8 @@
 
         assertThat(
                 ShortcutUtils.getShortcutTargetsFromSettings(
-                        mContextSpy, ShortcutConstants.UserShortcutType.HARDWARE,
-                        UserHandle.myUserId())
+                        mContext, ShortcutConstants.UserShortcutType.HARDWARE,
+                        mDefaultUserId)
         ).containsExactlyElementsIn(TWO_COMPONENTS);
     }
 
@@ -156,8 +154,8 @@
 
         assertThat(
                 ShortcutUtils.getShortcutTargetsFromSettings(
-                        mContextSpy, ShortcutConstants.UserShortcutType.TRIPLETAP,
-                        UserHandle.myUserId())
+                        mContext, ShortcutConstants.UserShortcutType.TRIPLETAP,
+                        mDefaultUserId)
         ).isEmpty();
     }
 
@@ -169,8 +167,8 @@
 
         assertThat(
                 ShortcutUtils.getShortcutTargetsFromSettings(
-                        mContextSpy, ShortcutConstants.UserShortcutType.TRIPLETAP,
-                        UserHandle.myUserId())
+                        mContext, ShortcutConstants.UserShortcutType.TRIPLETAP,
+                        mDefaultUserId)
         ).containsExactly(ACCESSIBILITY_SHORTCUT_TARGET_MAGNIFICATION_CONTROLLER);
     }
 
@@ -180,23 +178,46 @@
                 ALWAYS_ON_SERVICE_COMPONENT_NAME, /* serviceOn= */ true, /* shortcutOn= */ false);
 
         ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
-                mContextSpy,
+                mContext,
                 Set.of(ALWAYS_ON_SERVICE_COMPONENT_NAME),
-                UserHandle.myUserId()
+                mDefaultUserId
         );
 
         assertA11yServiceState(ALWAYS_ON_SERVICE_COMPONENT_NAME, /* enabled= */ false);
     }
 
     @Test
+    public void updateAccessibilityServiceStateIfNeeded_alwaysOnServiceOnForBothUsers_noShortcutsForGuestUser_serviceTurnedOffForGuestUserOnly() {
+        // setup arbitrary userId by add 10 to the default user id
+        final int guestUserId = mDefaultUserId + 10;
+        setupA11yServiceAndShortcutStateForUser(
+                ALWAYS_ON_SERVICE_COMPONENT_NAME, /* serviceOn= */ true,
+                /* shortcutOn= */ true, mDefaultUserId);
+        setupA11yServiceAndShortcutStateForUser(
+                ALWAYS_ON_SERVICE_COMPONENT_NAME, /* serviceOn= */ true,
+                /* shortcutOn= */ false, guestUserId);
+
+        ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
+                mContext,
+                Set.of(ALWAYS_ON_SERVICE_COMPONENT_NAME),
+                guestUserId
+        );
+
+        assertA11yServiceStateForUser(
+                ALWAYS_ON_SERVICE_COMPONENT_NAME, /* enabled= */ false, guestUserId);
+        assertA11yServiceStateForUser(
+                ALWAYS_ON_SERVICE_COMPONENT_NAME, /* enabled= */ true, mDefaultUserId);
+    }
+
+    @Test
     public void updateAccessibilityServiceStateIfNeeded_alwaysOnServiceOn_hasShortcut_serviceKeepsOn() {
         setupA11yServiceAndShortcutState(
                 ALWAYS_ON_SERVICE_COMPONENT_NAME, /* serviceOn= */ true, /* shortcutOn= */ true);
 
         ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
-                mContextSpy,
+                mContext,
                 Set.of(ALWAYS_ON_SERVICE_COMPONENT_NAME),
-                UserHandle.myUserId()
+                mDefaultUserId
         );
 
         assertA11yServiceState(ALWAYS_ON_SERVICE_COMPONENT_NAME, /* enabled= */ true);
@@ -208,9 +229,9 @@
                 ALWAYS_ON_SERVICE_COMPONENT_NAME, /* serviceOn= */ false, /* shortcutOn= */ false);
 
         ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
-                mContextSpy,
+                mContext,
                 Set.of(ALWAYS_ON_SERVICE_COMPONENT_NAME),
-                UserHandle.myUserId()
+                mDefaultUserId
         );
 
         assertA11yServiceState(ALWAYS_ON_SERVICE_COMPONENT_NAME, /* enabled= */ false);
@@ -222,9 +243,9 @@
                 ALWAYS_ON_SERVICE_COMPONENT_NAME, /* serviceOn= */ false, /* shortcutOn= */ true);
 
         ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
-                mContextSpy,
+                mContext,
                 Set.of(ALWAYS_ON_SERVICE_COMPONENT_NAME),
-                UserHandle.myUserId()
+                mDefaultUserId
         );
 
         assertA11yServiceState(ALWAYS_ON_SERVICE_COMPONENT_NAME, /* enabled= */ true);
@@ -236,9 +257,9 @@
                 STANDARD_SERVICE_COMPONENT_NAME, /* serviceOn= */ true, /* shortcutOn= */ false);
 
         ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
-                mContextSpy,
+                mContext,
                 Set.of(STANDARD_SERVICE_COMPONENT_NAME),
-                UserHandle.myUserId()
+                mDefaultUserId
         );
 
         assertA11yServiceState(STANDARD_SERVICE_COMPONENT_NAME, /* enabled= */ true);
@@ -250,9 +271,9 @@
                 STANDARD_SERVICE_COMPONENT_NAME, /* serviceOn= */ true, /* shortcutOn= */ true);
 
         ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
-                mContextSpy,
+                mContext,
                 Set.of(STANDARD_SERVICE_COMPONENT_NAME),
-                UserHandle.myUserId()
+                mDefaultUserId
         );
 
         assertA11yServiceState(STANDARD_SERVICE_COMPONENT_NAME, /* enabled= */ true);
@@ -264,9 +285,9 @@
                 STANDARD_SERVICE_COMPONENT_NAME, /* serviceOn= */ false, /* shortcutOn= */ false);
 
         ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
-                mContextSpy,
+                mContext,
                 Set.of(STANDARD_SERVICE_COMPONENT_NAME),
-                UserHandle.myUserId()
+                mDefaultUserId
         );
 
         assertA11yServiceState(STANDARD_SERVICE_COMPONENT_NAME, /* enabled= */ false);
@@ -278,9 +299,9 @@
                 STANDARD_SERVICE_COMPONENT_NAME, /* serviceOn= */ false, /* shortcutOn= */ true);
 
         ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
-                mContextSpy,
+                mContext,
                 Set.of(STANDARD_SERVICE_COMPONENT_NAME),
-                UserHandle.myUserId()
+                mDefaultUserId
         );
 
         assertA11yServiceState(STANDARD_SERVICE_COMPONENT_NAME, /* enabled= */ false);
@@ -292,18 +313,18 @@
             stringJoiner.add(target);
         }
         Settings.Secure.putStringForUser(
-                mContextSpy.getContentResolver(), shortcutSettingsKey,
+                mContext.getContentResolver(), shortcutSettingsKey,
                 stringJoiner.toString(),
-                UserHandle.myUserId());
+                mDefaultUserId);
     }
 
     private void enableTripleTapShortcutForMagnification(boolean enable) {
         Settings.Secure.putInt(
-                mContextSpy.getContentResolver(),
+                mContext.getContentResolver(),
                 ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, enable ? 1 : 0);
     }
 
-    private void setupFakeA11yServiceInfos() throws RemoteException {
+    private void setupFakeInstalledA11yServiceInfos() throws RemoteException {
         List<AccessibilityServiceInfo> serviceInfos = List.of(
                 TestUtils.createFakeServiceInfo(
                         ALWAYS_ON_SERVICE_PACKAGE_LABEL,
@@ -322,37 +343,55 @@
 
     private void setupA11yServiceAndShortcutState(
             String a11yServiceComponentName, boolean serviceOn, boolean shortcutOn) {
-        enableA11yService(a11yServiceComponentName, serviceOn);
-        addShortcutForA11yService(a11yServiceComponentName, shortcutOn);
+        setupA11yServiceAndShortcutStateForUser(
+                a11yServiceComponentName, serviceOn, shortcutOn, mDefaultUserId);
+    }
+
+    private void setupA11yServiceAndShortcutStateForUser(
+            String a11yServiceComponentName, boolean serviceOn,
+            boolean shortcutOn, @UserIdInt int userId) {
+        enableA11yServiceForUser(a11yServiceComponentName, serviceOn, userId);
+        addShortcutForA11yServiceForUser(a11yServiceComponentName, shortcutOn, userId);
     }
 
     private void assertA11yServiceState(String a11yServiceComponentName, boolean enabled) {
+        assertA11yServiceStateForUser(a11yServiceComponentName, enabled, mDefaultUserId);
+    }
+
+    private void assertA11yServiceStateForUser(
+            String a11yServiceComponentName, boolean enabled, @UserIdInt int userId) {
         if (enabled) {
             assertThat(
-                    Settings.Secure.getString(
-                            mContextSpy.getContentResolver(),
-                            Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES)
+                    Settings.Secure.getStringForUser(
+                            mContext.getContentResolver(),
+                            Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+                            userId)
             ).contains(a11yServiceComponentName);
         } else {
             assertThat(
-                    Settings.Secure.getString(
-                            mContextSpy.getContentResolver(),
-                            Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES)
+                    Settings.Secure.getStringForUser(
+                            mContext.getContentResolver(),
+                            Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+                            userId)
             ).doesNotContain(a11yServiceComponentName);
         }
     }
 
-    private void enableA11yService(String a11yServiceComponentName, boolean enable) {
-        Settings.Secure.putString(
-                mContextSpy.getContentResolver(),
+    private void enableA11yServiceForUser(
+            String a11yServiceComponentName, boolean enable, @UserIdInt int userId) {
+        Settings.Secure.putStringForUser(
+                mContext.getContentResolver(),
                 Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
-                enable ? a11yServiceComponentName : "");
+                enable ? a11yServiceComponentName : "",
+                userId);
     }
 
-    private void addShortcutForA11yService(String a11yServiceComponentName, boolean add) {
-        Settings.Secure.putString(
-                mContextSpy.getContentResolver(),
+    private void addShortcutForA11yServiceForUser(
+            String a11yServiceComponentName, boolean add, @UserIdInt int userId) {
+        Settings.Secure.putStringForUser(
+                mContext.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
-                add ? a11yServiceComponentName : "");
+                add ? a11yServiceComponentName : "",
+                userId);
     }
 }
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 1a7117e..499caf5 100644
--- a/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/FrameTrackerTest.java
@@ -29,6 +29,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
@@ -83,6 +84,7 @@
     private ChoreographerWrapper mChoreographer;
     private StatsLogWrapper mStatsLog;
     private ArgumentCaptor<OnJankDataListener> mListenerCapture;
+    private SurfaceControl.OnJankDataListenerRegistration mJankStatsRegistration;
     private SurfaceControl mSurfaceControl;
     private FrameTracker.FrameTrackerListener mTrackerListener;
     private ArgumentCaptor<Runnable> mRunnableArgumentCaptor;
@@ -107,10 +109,11 @@
         mSurfaceControlWrapper = mock(SurfaceControlWrapper.class);
 
         mListenerCapture = ArgumentCaptor.forClass(OnJankDataListener.class);
-        doNothing().when(mSurfaceControlWrapper).addJankStatsListener(
+        mJankStatsRegistration = mock(SurfaceControl.OnJankDataListenerRegistration.class);
+        doReturn(mJankStatsRegistration).when(mSurfaceControlWrapper).addJankStatsListener(
                 mListenerCapture.capture(), any());
-        doNothing().when(mSurfaceControlWrapper).removeJankStatsListener(
-                mListenerCapture.capture());
+        doNothing().when(mJankStatsRegistration).flush();
+        doNothing().when(mJankStatsRegistration).removeAfter(anyLong());
 
         mChoreographer = mock(ChoreographerWrapper.class);
         mStatsLog = mock(StatsLogWrapper.class);
@@ -483,7 +486,7 @@
         // an extra frame to trigger finish
         sendFrame(tracker, JANK_NONE, 103L);
 
-        verify(mSurfaceControlWrapper).removeJankStatsListener(any());
+        verify(mJankStatsRegistration).removeAfter(anyLong());
         verify(mTrackerListener).triggerPerfetto(any());
 
         verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
@@ -520,7 +523,7 @@
         // an extra frame to trigger finish
         sendFrame(tracker, JANK_NONE, 103L);
 
-        verify(mSurfaceControlWrapper).removeJankStatsListener(any());
+        verify(mJankStatsRegistration).removeAfter(anyLong());
         verify(mTrackerListener, never()).triggerPerfetto(any());
 
         verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
@@ -557,7 +560,7 @@
         // janky frame, should be ignored, trigger finish
         sendFrame(tracker, JANK_APP_DEADLINE_MISSED, 103L);
 
-        verify(mSurfaceControlWrapper).removeJankStatsListener(any());
+        verify(mJankStatsRegistration).removeAfter(anyLong());
         verify(mTrackerListener, never()).triggerPerfetto(any());
 
         verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
@@ -589,7 +592,7 @@
         tracker.end(FrameTracker.REASON_END_NORMAL);
         sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 106L);
         sendFrame(tracker, JANK_SURFACEFLINGER_DEADLINE_MISSED, 107L);
-        verify(mSurfaceControlWrapper).removeJankStatsListener(any());
+        verify(mJankStatsRegistration).removeAfter(anyLong());
         verify(mTrackerListener).triggerPerfetto(any());
         verify(mStatsLog).write(eq(UI_INTERACTION_FRAME_INFO_REPORTED),
                 eq(42), /* displayId */
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 68095e5..5af272c 100644
--- a/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
+++ b/core/tests/coretests/src/com/android/internal/jank/InteractionJankMonitorTest.java
@@ -38,6 +38,7 @@
 import android.os.HandlerThread;
 import android.os.SystemClock;
 import android.provider.DeviceConfig;
+import android.view.SurfaceControl;
 import android.view.View;
 import android.view.ViewAttachTestActivity;
 
@@ -67,6 +68,7 @@
     private View mView;
     private Handler mHandler;
     private HandlerThread mWorker;
+    private SurfaceControl mSurfaceControl;
 
     @Rule
     public ActivityScenarioRule<ViewAttachTestActivity> mRule =
@@ -79,6 +81,9 @@
     public void setup() {
         mRule.getScenario().onActivity(activity -> mActivity = activity);
         mView = mActivity.getWindow().getDecorView();
+        mSurfaceControl = mView.getViewRootImpl().getSurfaceControl();
+        // Set mNativeObject to a non-zero value to make it a valid SurfaceControl.
+        mSurfaceControl.mNativeObject = 1;
         assertThat(mView.isAttachedToWindow()).isTrue();
 
         mHandler = spy(new Handler(mActivity.getMainLooper()));
@@ -88,7 +93,7 @@
     }
 
     @Test
-    public void testBeginEnd() {
+    public void testBeginEnd_inputView() {
         InteractionJankMonitor monitor = createMockedInteractionJankMonitor();
         FrameTracker tracker = createMockedFrameTracker();
         doReturn(tracker).when(monitor).createFrameTracker(any());
@@ -103,6 +108,22 @@
     }
 
     @Test
+    public void testBeginEnd_inputSurfaceControl() {
+        InteractionJankMonitor monitor = createMockedInteractionJankMonitor();
+        FrameTracker tracker = createMockedFrameTracker();
+        doReturn(tracker).when(monitor).createFrameTracker(any());
+        doNothing().when(tracker).begin();
+        doReturn(true).when(tracker).end(anyInt());
+
+        // Simulate a trace session and see if begin / end are invoked.
+        assertThat(monitor.begin(mSurfaceControl, mActivity.getApplicationContext(),
+                Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isTrue();
+        verify(tracker).begin();
+        assertThat(monitor.end(Cuj.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE)).isTrue();
+        verify(tracker).end(REASON_END_NORMAL);
+    }
+
+    @Test
     public void testDisabledThroughDeviceConfig() {
         InteractionJankMonitor monitor = new InteractionJankMonitor(mWorker);
 
@@ -183,8 +204,6 @@
         doNothing().when(viewRoot).removeSurfaceChangedCallback(any());
 
         SurfaceControlWrapper surfaceControl = mock(SurfaceControlWrapper.class);
-        doNothing().when(surfaceControl).addJankStatsListener(any(), any());
-        doNothing().when(surfaceControl).removeJankStatsListener(any());
 
         final ChoreographerWrapper choreographer = mock(ChoreographerWrapper.class);
         doReturn(SystemClock.elapsedRealtime()).when(choreographer).getVsyncId();
diff --git a/core/tests/coretests/src/com/android/internal/os/MonotonicClockTest.java b/core/tests/coretests/src/com/android/internal/os/MonotonicClockTest.java
index 06d888b..7ffc7b2 100644
--- a/core/tests/coretests/src/com/android/internal/os/MonotonicClockTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/MonotonicClockTest.java
@@ -18,7 +18,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
@@ -77,7 +76,6 @@
     }
 
     @Test
-    @IgnoreUnderRavenwood(reason = "b/321832617")
     public void corruptedFile() throws IOException {
         // Create an invalid binary XML file to cause IOException: "Unexpected magic number"
         try (FileWriter w = new FileWriter(mFile)) {
diff --git a/core/tests/utiltests/src/android/util/TimeUtilsTest.java b/core/tests/utiltests/src/android/util/TimeUtilsTest.java
index ac659e1..6c6feaf 100644
--- a/core/tests/utiltests/src/android/util/TimeUtilsTest.java
+++ b/core/tests/utiltests/src/android/util/TimeUtilsTest.java
@@ -18,17 +18,19 @@
 
 import static org.junit.Assert.assertEquals;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.runner.AndroidJUnit4;
 
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.util.TimeZone;
 import java.util.function.Consumer;
 
 @RunWith(AndroidJUnit4.class)
@@ -42,6 +44,22 @@
     public static final long DAY_IN_MILLIS = HOUR_IN_MILLIS * 24;
     public static final long WEEK_IN_MILLIS = DAY_IN_MILLIS * 7;
 
+    private TimeZone mOrigTimezone;
+
+    @Before
+    public void setUp() {
+        mOrigTimezone = TimeZone.getDefault();
+
+        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+    }
+
+    @After
+    public void tearDown() {
+        if (mOrigTimezone != null) {
+            TimeZone.setDefault(mOrigTimezone);
+        }
+    }
+
     @Test
     public void testFormatTime() {
         assertEquals("1672556400000 (now)",
@@ -85,32 +103,29 @@
     }
 
     @Test
-    @IgnoreUnderRavenwood(reason = "Flaky test, b/315872700")
     public void testDumpTime() {
-        assertEquals("2023-01-01 00:00:00.000", runWithPrintWriter((pw) -> {
+        assertEquals("2023-01-01 07:00:00.000", runWithPrintWriter((pw) -> {
             TimeUtils.dumpTime(pw, 1672556400000L);
         }));
-        assertEquals("2023-01-01 00:00:00.000 (now)", runWithPrintWriter((pw) -> {
+        assertEquals("2023-01-01 07:00:00.000 (now)", runWithPrintWriter((pw) -> {
             TimeUtils.dumpTimeWithDelta(pw, 1672556400000L, 1672556400000L);
         }));
-        assertEquals("2023-01-01 00:00:00.000 (-10ms)", runWithPrintWriter((pw) -> {
+        assertEquals("2023-01-01 07:00:00.000 (-10ms)", runWithPrintWriter((pw) -> {
             TimeUtils.dumpTimeWithDelta(pw, 1672556400000L, 1672556400000L + 10);
         }));
     }
 
     @Test
-    @IgnoreUnderRavenwood(reason = "Flaky test, b/315872700")
     public void testFormatForLogging() {
         assertEquals("unknown", TimeUtils.formatForLogging(0));
         assertEquals("unknown", TimeUtils.formatForLogging(-1));
         assertEquals("unknown", TimeUtils.formatForLogging(Long.MIN_VALUE));
-        assertEquals("2023-01-01 00:00:00", TimeUtils.formatForLogging(1672556400000L));
+        assertEquals("2023-01-01 07:00:00", TimeUtils.formatForLogging(1672556400000L));
     }
 
     @Test
-    @IgnoreUnderRavenwood(reason = "Flaky test, b/315872700")
     public void testLogTimeOfDay() {
-        assertEquals("01-01 00:00:00.000", TimeUtils.logTimeOfDay(1672556400000L));
+        assertEquals("01-01 07:00:00.000", TimeUtils.logTimeOfDay(1672556400000L));
     }
 
     public static String runWithPrintWriter(Consumer<PrintWriter> consumer) {
diff --git a/core/tests/vibrator/src/android/os/vibrator/persistence/ParsedVibrationTest.java b/core/tests/vibrator/src/android/os/vibrator/persistence/ParsedVibrationTest.java
index 94298dc..83a8f8f 100644
--- a/core/tests/vibrator/src/android/os/vibrator/persistence/ParsedVibrationTest.java
+++ b/core/tests/vibrator/src/android/os/vibrator/persistence/ParsedVibrationTest.java
@@ -63,6 +63,34 @@
     }
 
     @Test
+    public void testEquals() {
+        assertThat(new ParsedVibration(List.of())).isEqualTo(new ParsedVibration(List.of()));
+        assertThat(new ParsedVibration(List.of())).isNotEqualTo(new ParsedVibration(mEffect1));
+        assertThat(new ParsedVibration(mEffect1)).isEqualTo(new ParsedVibration(mEffect1));
+        assertThat(new ParsedVibration(mEffect1)).isNotEqualTo(new ParsedVibration(mEffect2));
+        assertThat(new ParsedVibration(List.of(mEffect1, mEffect2, mEffect3)))
+                .isEqualTo(new ParsedVibration(List.of(mEffect1, mEffect2, mEffect3)));
+        assertThat(new ParsedVibration(List.of(mEffect1, mEffect2)))
+                .isNotEqualTo(new ParsedVibration(List.of(mEffect2, mEffect1)));
+    }
+
+    @Test
+    public void testHashCode() {
+        assertThat(new ParsedVibration(mEffect1).hashCode())
+                .isEqualTo(new ParsedVibration(mEffect1).hashCode());
+        assertThat(new ParsedVibration(mEffect1).hashCode())
+                .isNotEqualTo(new ParsedVibration(mEffect2).hashCode());
+        assertThat(new ParsedVibration(List.of()).hashCode())
+                .isEqualTo(new ParsedVibration(List.of()).hashCode());
+        assertThat(new ParsedVibration(List.of()).hashCode())
+                .isNotEqualTo(new ParsedVibration(mEffect1).hashCode());
+        assertThat(new ParsedVibration(List.of(mEffect1, mEffect2, mEffect3)).hashCode())
+                .isEqualTo(new ParsedVibration(List.of(mEffect1, mEffect2, mEffect3)).hashCode());
+        assertThat(new ParsedVibration(List.of(mEffect1, mEffect2)).hashCode())
+                .isNotEqualTo(new ParsedVibration(List.of(mEffect2, mEffect1)).hashCode());
+    }
+
+    @Test
     public void testResolve_allUnsupportedVibrations() {
         when(mVibratorInfoMock.areVibrationFeaturesSupported(any())).thenReturn(false);
 
@@ -91,21 +119,6 @@
                 .isEqualTo(mEffect1);
     }
 
-    @Test
-    public void testGetVibrationEffects() {
-        ParsedVibration parsedVibration =
-                new ParsedVibration(List.of(mEffect1, mEffect2, mEffect3));
-        assertThat(parsedVibration.getVibrationEffects())
-                .containsExactly(mEffect1, mEffect2, mEffect3)
-                .inOrder();
-
-        parsedVibration = new ParsedVibration(List.of(mEffect1));
-        assertThat(parsedVibration.getVibrationEffects()).containsExactly(mEffect1);
-
-        parsedVibration = new ParsedVibration(List.of());
-        assertThat(parsedVibration.getVibrationEffects()).isEmpty();
-    }
-
     private Subject assertThatResolution(
             Vibrator vibrator, List<VibrationEffect> componentVibrations) {
         return assertThat(new ParsedVibration(componentVibrations).resolve(vibrator));
diff --git a/core/tests/vibrator/src/android/os/vibrator/persistence/VibrationEffectXmlSerializationTest.java b/core/tests/vibrator/src/android/os/vibrator/persistence/VibrationEffectXmlSerializationTest.java
index 7d8c53f..bf9a820 100644
--- a/core/tests/vibrator/src/android/os/vibrator/persistence/VibrationEffectXmlSerializationTest.java
+++ b/core/tests/vibrator/src/android/os/vibrator/persistence/VibrationEffectXmlSerializationTest.java
@@ -37,9 +37,9 @@
 import org.junit.runners.JUnit4;
 import org.xmlpull.v1.XmlPullParser;
 
-import java.io.IOException;
 import java.io.StringReader;
 import java.io.StringWriter;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
@@ -74,18 +74,22 @@
                 .addPrimitive(PRIMITIVE_CLICK)
                 .addPrimitive(PRIMITIVE_TICK, 0.2497f)
                 .compose();
-        String xml = "<vibration-effect>"
-                + "<primitive-effect name=\"click\"/>"
-                + "<primitive-effect name=\"tick\" scale=\"0.2497\"/>"
-                + "</vibration-effect>";
+        String xml = """
+                <vibration-effect>
+                    <primitive-effect name="click"/>
+                    <primitive-effect name="tick" scale="0.2497"/>
+                </vibration-effect>
+                """.trim();
         VibrationEffect effect2 = VibrationEffect.startComposition()
                 .addPrimitive(PRIMITIVE_LOW_TICK, 1f, 356)
                 .addPrimitive(PRIMITIVE_SPIN, 0.6364f, 7)
                 .compose();
-        String xml2 = "<vibration-effect>"
-                + "<primitive-effect name=\"low_tick\" delayMs=\"356\"/>"
-                + "<primitive-effect name=\"spin\" scale=\"0.6364\" delayMs=\"7\"/>"
-                + "</vibration-effect>";
+        String xml2 = """
+                <vibration-effect>
+                    <primitive-effect name="low_tick" delayMs="356"/>
+                    <primitive-effect name="spin" scale="0.6364" delayMs="7"/>
+                </vibration-effect>
+                """.trim();
 
         TypedXmlPullParser parser = createXmlPullParser(xml);
         assertParseElementSucceeds(parser, effect);
@@ -114,7 +118,12 @@
         assertEndOfDocument(parser);
 
         // Check when there is comment before the end tag.
-        xml = "<vibration-effect><primitive-effect name=\"tick\"/><!-- hi --></vibration-effect>";
+        xml = """
+            <vibration-effect>
+                <primitive-effect name="tick"/>
+                <!-- hi -->
+            </vibration-effect>
+            """.trim();
         parser = createXmlPullParser(xml);
         assertParseElementSucceeds(
                 parser, VibrationEffect.startComposition().addPrimitive(PRIMITIVE_TICK).compose());
@@ -128,18 +137,22 @@
                 .addPrimitive(PRIMITIVE_CLICK)
                 .addPrimitive(PRIMITIVE_TICK, 0.2497f)
                 .compose();
-        String vibrationXml1 = "<vibration-effect>"
-                + "<primitive-effect name=\"click\"/>"
-                + "<primitive-effect name=\"tick\" scale=\"0.2497\"/>"
-                + "</vibration-effect>";
+        String vibrationXml1 = """
+                <vibration-effect>
+                    <primitive-effect name="click"/>
+                    <primitive-effect name="tick" scale="0.2497"/>
+                </vibration-effect>
+                """.trim();
         VibrationEffect effect2 = VibrationEffect.startComposition()
                 .addPrimitive(PRIMITIVE_LOW_TICK, 1f, 356)
                 .addPrimitive(PRIMITIVE_SPIN, 0.6364f, 7)
                 .compose();
-        String vibrationXml2 = "<vibration-effect>"
-                + "<primitive-effect name=\"low_tick\" delayMs=\"356\"/>"
-                + "<primitive-effect name=\"spin\" scale=\"0.6364\" delayMs=\"7\"/>"
-                + "</vibration-effect>";
+        String vibrationXml2 = """
+                <vibration-effect>
+                    <primitive-effect name="low_tick" delayMs="356"/>
+                    <primitive-effect name="spin" scale="0.6364" delayMs="7"/>
+                </vibration-effect>
+                """.trim();
 
         String xml = "<vibration-select>" + vibrationXml1 + vibrationXml2 + "</vibration-select>";
         TypedXmlPullParser parser = createXmlPullParser(xml);
@@ -183,8 +196,11 @@
     @Test
     public void testParseElement_withHiddenApis_onlySucceedsWithFlag() throws Exception {
         // Check when the root tag is "vibration".
-        String xml =
-                "<vibration-effect><predefined-effect name=\"texture_tick\"/></vibration-effect>";
+        String xml = """
+                <vibration-effect>
+                    <predefined-effect name="texture_tick"/>
+                </vibration-effect>
+                """.trim();
         assertParseElementSucceeds(createXmlPullParser(xml),
                 VibrationXmlSerializer.FLAG_ALLOW_HIDDEN_APIS,
                 VibrationEffect.get(VibrationEffect.EFFECT_TEXTURE_TICK));
@@ -199,131 +215,186 @@
     }
 
     @Test
-    public void testParseElement_badXml_throwsException() throws Exception {
+    public void testParseElement_badXml_throwsException() {
         // No "vibration-select" tag.
-        assertParseElementFails(
-                "<vibration-effect>rand text<primitive-effect name=\"click\"/></vibration-effect>");
-        assertParseElementFails("<bad-tag><primitive-effect name=\"click\"/></vibration-effect>");
-        assertParseElementFails("<primitive-effect name=\"click\"/></vibration-effect>");
-        assertParseElementFails("<vibration-effect><primitive-effect name=\"click\"/>");
+        assertParseElementFails("""
+                <vibration-effect>
+                    rand text
+                    <primitive-effect name="click"/>
+                </vibration-effect>
+                """);
+        assertParseElementFails("""
+                <bad-tag>
+                    <primitive-effect name="click"/>
+                </vibration-effect>
+                """);
+        assertParseElementFails("""
+                <primitive-effect name="click"/>
+                </vibration-effect>
+                """);
+        assertParseElementFails("""
+                <vibration-effect>
+                    <primitive-effect name="click"/>
+                """);
 
         // Incomplete XML.
-        assertParseElementFails("<vibration-select><primitive-effect name=\"click\"/>");
-        assertParseElementFails("<vibration-select>"
-                + "<vibration-effect>"
-                + "<primitive-effect name=\"low_tick\" delayMs=\"356\"/>"
-                + "</vibration-effect>");
+        assertParseElementFails("""
+                <vibration-select>
+                    <primitive-effect name="click"/>
+                """);
+        assertParseElementFails("""
+                <vibration-select>
+                    <vibration-effect>
+                        <primitive-effect name="low_tick" delayMs="356"/>
+                    </vibration-effect>
+                """);
 
         // Bad vibration XML.
-        assertParseElementFails("<vibration-select>"
-                + "<primitive-effect name=\"low_tick\" delayMs=\"356\"/>"
-                + "</vibration-effect>"
-                + "</vibration-select>");
+        assertParseElementFails("""
+                <vibration-select>
+                    <primitive-effect name="low_tick" delayMs="356"/>
+                    </vibration-effect>
+                </vibration-select>
+                """);
 
         // "vibration-select" tag should have no attributes.
-        assertParseElementFails("<vibration-select bad_attr=\"123\">"
-                + "<vibration-effect>"
-                + "<predefined-effect name=\"tick\"/>"
-                + "</vibration-effect>"
-                + "</vibration-select>");
+        assertParseElementFails("""
+                <vibration-select bad_attr="123">
+                    <vibration-effect>
+                        <predefined-effect name="tick"/>
+                    </vibration-effect>
+                </vibration-select>
+                """);
     }
 
     @Test
-    public void testPrimitives_allSucceed() throws IOException {
+    public void testInvalidEffects_allFail() {
+        // Invalid root tag.
+        String xml = """
+                <vibration>
+                    <predefined-effect name="click"/>
+                </vibration>
+                """;
+
+        assertPublicApisParserFails(xml);
+        assertHiddenApisParserFails(xml);
+
+        // Invalid effect name.
+        xml = """
+                <vibration-effect>
+                    <predefined-effect name="invalid"/>
+                </vibration-effect>
+                """;
+
+        assertPublicApisParserFails(xml);
+        assertHiddenApisParserFails(xml);
+    }
+
+    @Test
+    public void testVibrationSelectTag_onlyParseDocumentSucceeds() throws Exception {
+        VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
+        String xml = """
+                <vibration-select>
+                    <vibration-effect><predefined-effect name="click"/></vibration-effect>
+                </vibration-select>
+                """;
+
+        assertPublicApisParseDocumentSucceeds(xml, effect);
+        assertHiddenApisParseDocumentSucceeds(xml, effect);
+
+        assertPublicApisParseVibrationEffectFails(xml);
+        assertHiddenApisParseVibrationEffectFails(xml);
+    }
+
+    @Test
+    public void testPrimitives_allSucceed() throws Exception {
         VibrationEffect effect = VibrationEffect.startComposition()
                 .addPrimitive(PRIMITIVE_CLICK)
                 .addPrimitive(PRIMITIVE_TICK, 0.2497f)
                 .addPrimitive(PRIMITIVE_LOW_TICK, 1f, 356)
                 .addPrimitive(PRIMITIVE_SPIN, 0.6364f, 7)
                 .compose();
-        String xml = "<vibration-effect>"
-                + "<primitive-effect name=\"click\"/>"
-                + "<primitive-effect name=\"tick\" scale=\"0.2497\"/>"
-                + "<primitive-effect name=\"low_tick\" delayMs=\"356\"/>"
-                + "<primitive-effect name=\"spin\" scale=\"0.6364\" delayMs=\"7\"/>"
-                + "</vibration-effect>";
+        String xml = """
+                <vibration-effect>
+                    <primitive-effect name="click"/>
+                    <primitive-effect name="tick" scale="0.2497"/>
+                    <primitive-effect name="low_tick" delayMs="356"/>
+                    <primitive-effect name="spin" scale="0.6364" delayMs="7"/>
+                </vibration-effect>
+                """;
 
         assertPublicApisParserSucceeds(xml, effect);
         assertPublicApisSerializerSucceeds(effect, "click", "tick", "low_tick", "spin");
         assertPublicApisRoundTrip(effect);
 
-        assertHiddenApisParseVibrationEffectSucceeds(xml, effect);
+        assertHiddenApisParserSucceeds(xml, effect);
         assertHiddenApisSerializerSucceeds(effect, "click", "tick", "low_tick", "spin");
         assertHiddenApisRoundTrip(effect);
     }
 
     @Test
-    public void testParseDocument_withVibrationSelectTag_withHiddenApis_onlySucceedsWithFlag()
-            throws Exception {
-        // Check when the root tag is "vibration-effect".
-        String xml =
-                "<vibration-effect><predefined-effect name=\"texture_tick\"/></vibration-effect>";
-        assertParseDocumentSucceeds(xml,
-                VibrationXmlSerializer.FLAG_ALLOW_HIDDEN_APIS,
-                VibrationEffect.get(VibrationEffect.EFFECT_TEXTURE_TICK));
-        assertThat(parseDocument(xml, /* flags= */ 0)).isNull();
-
-        // Check when the root tag is "vibration-select".
-        xml = "<vibration-select>" + xml + "</vibration-select>";
-        assertParseDocumentSucceeds(xml,
-                VibrationXmlSerializer.FLAG_ALLOW_HIDDEN_APIS,
-                VibrationEffect.get(VibrationEffect.EFFECT_TEXTURE_TICK));
-        assertThat(parseDocument(xml, /* flags= */ 0)).isNull();
-    }
-
-    @Test
-    public void testWaveforms_allSucceed() throws IOException {
+    public void testWaveforms_allSucceed() throws Exception {
         VibrationEffect effect = VibrationEffect.createWaveform(new long[]{123, 456, 789, 0},
                 new int[]{254, 1, 255, 0}, /* repeat= */ 0);
-        String xml = "<vibration-effect>"
-                + "<waveform-effect><repeating>"
-                + "<waveform-entry durationMs=\"123\" amplitude=\"254\"/>"
-                + "<waveform-entry durationMs=\"456\" amplitude=\"1\"/>"
-                + "<waveform-entry durationMs=\"789\" amplitude=\"255\"/>"
-                + "<waveform-entry durationMs=\"0\" amplitude=\"0\"/>"
-                + "</repeating></waveform-effect>"
-                + "</vibration-effect>";
+        String xml = """
+                <vibration-effect>
+                    <waveform-effect>
+                        <repeating>
+                            <waveform-entry durationMs="123" amplitude="254"/>
+                            <waveform-entry durationMs="456" amplitude="1"/>
+                            <waveform-entry durationMs="789" amplitude="255"/>
+                            <waveform-entry durationMs="0" amplitude="0"/>
+                        </repeating>
+                    </waveform-effect>
+                </vibration-effect>
+                """;
 
         assertPublicApisParserSucceeds(xml, effect);
         assertPublicApisSerializerSucceeds(effect, "123", "456", "789", "254", "1", "255", "0");
         assertPublicApisRoundTrip(effect);
 
-        assertHiddenApisParseVibrationEffectSucceeds(xml, effect);
+        assertHiddenApisParserSucceeds(xml, effect);
         assertHiddenApisSerializerSucceeds(effect, "123", "456", "789", "254", "1", "255", "0");
         assertHiddenApisRoundTrip(effect);
     }
 
     @Test
     public void testPredefinedEffects_publicEffectsWithDefaultFallback_allSucceed()
-            throws IOException {
+            throws Exception {
         for (Map.Entry<String, Integer> entry : createPublicPredefinedEffectsMap().entrySet()) {
             VibrationEffect effect = VibrationEffect.get(entry.getValue());
-            String xml = String.format(
-                    "<vibration-effect><predefined-effect name=\"%s\"/></vibration-effect>",
+            String xml = String.format("""
+                    <vibration-effect>
+                        <predefined-effect name="%s"/>
+                    </vibration-effect>
+                    """,
                     entry.getKey());
 
             assertPublicApisParserSucceeds(xml, effect);
             assertPublicApisSerializerSucceeds(effect, entry.getKey());
             assertPublicApisRoundTrip(effect);
 
-            assertHiddenApisParseVibrationEffectSucceeds(xml, effect);
+            assertHiddenApisParserSucceeds(xml, effect);
             assertHiddenApisSerializerSucceeds(effect, entry.getKey());
             assertHiddenApisRoundTrip(effect);
         }
     }
 
     @Test
-    public void testPredefinedEffects_hiddenEffects_onlySucceedsWithFlag() throws IOException {
+    public void testPredefinedEffects_hiddenEffects_onlySucceedsWithFlag() throws Exception {
         for (Map.Entry<String, Integer> entry : createHiddenPredefinedEffectsMap().entrySet()) {
             VibrationEffect effect = VibrationEffect.get(entry.getValue());
-            String xml = String.format(
-                    "<vibration-effect><predefined-effect name=\"%s\"/></vibration-effect>",
+            String xml = String.format("""
+                    <vibration-effect>
+                        <predefined-effect name="%s"/>
+                    </vibration-effect>
+                    """,
                     entry.getKey());
 
             assertPublicApisParserFails(xml);
             assertPublicApisSerializerFails(effect);
 
-            assertHiddenApisParseVibrationEffectSucceeds(xml, effect);
+            assertHiddenApisParserSucceeds(xml, effect);
             assertHiddenApisSerializerSucceeds(effect, entry.getKey());
             assertHiddenApisRoundTrip(effect);
         }
@@ -331,33 +402,119 @@
 
     @Test
     public void testPredefinedEffects_allEffectsWithNonDefaultFallback_onlySucceedsWithFlag()
-            throws IOException {
+            throws Exception {
         for (Map.Entry<String, Integer> entry : createAllPredefinedEffectsMap().entrySet()) {
             boolean nonDefaultFallback = !PrebakedSegment.DEFAULT_SHOULD_FALLBACK;
             VibrationEffect effect = VibrationEffect.get(entry.getValue(), nonDefaultFallback);
-            String xml = String.format(
-                    "<vibration-effect><predefined-effect name=\"%s\" fallback=\"%s\"/>"
-                            + "</vibration-effect>",
+            String xml = String.format("""
+                    <vibration-effect>
+                        <predefined-effect name="%s" fallback="%s"/>
+                    </vibration-effect>
+                    """,
                     entry.getKey(), nonDefaultFallback);
 
             assertPublicApisParserFails(xml);
             assertPublicApisSerializerFails(effect);
 
-            assertHiddenApisParseVibrationEffectSucceeds(xml, effect);
+            assertHiddenApisParserSucceeds(xml, effect);
             assertHiddenApisSerializerSucceeds(effect, entry.getKey());
             assertHiddenApisRoundTrip(effect);
         }
     }
 
-    private void assertPublicApisParserFails(String xml) throws IOException {
-        assertThat(parseVibrationEffect(xml, /* flags= */ 0)).isNull();
+    private void assertPublicApisParserFails(String xml) {
+        assertThrows("Expected parseVibrationEffect to fail for " + xml,
+                VibrationXmlParser.ParseFailedException.class,
+                () -> parseVibrationEffect(xml, /* flags= */ 0));
+        assertThrows("Expected parseDocument to fail for " + xml,
+                VibrationXmlParser.ParseFailedException.class,
+                () -> parseDocument(xml, /* flags= */ 0));
+    }
+
+    private void assertPublicApisParseVibrationEffectFails(String xml) {
+        assertThrows("Expected parseVibrationEffect to fail for " + xml,
+                VibrationXmlParser.ParseFailedException.class,
+                () -> parseVibrationEffect(xml, /* flags= */ 0));
     }
 
     private void assertPublicApisParserSucceeds(String xml, VibrationEffect effect)
-            throws IOException {
+            throws Exception {
+        assertPublicApisParseDocumentSucceeds(xml, effect);
+        assertPublicApisParseVibrationEffectSucceeds(xml, effect);
+    }
+
+    private void assertPublicApisParseDocumentSucceeds(String xml, VibrationEffect... effects)
+            throws Exception {
+        assertThat(parseDocument(xml, /* flags= */ 0))
+                .isEqualTo(new ParsedVibration(Arrays.asList(effects)));
+    }
+
+    private void assertPublicApisParseVibrationEffectSucceeds(String xml, VibrationEffect effect)
+            throws Exception {
         assertThat(parseVibrationEffect(xml, /* flags= */ 0)).isEqualTo(effect);
     }
 
+    private void assertHiddenApisParserFails(String xml) {
+        assertThrows("Expected parseVibrationEffect to fail for " + xml,
+                VibrationXmlParser.ParseFailedException.class,
+                () -> parseVibrationEffect(xml, VibrationXmlParser.FLAG_ALLOW_HIDDEN_APIS));
+        assertThrows("Expected parseDocument to fail for " + xml,
+                VibrationXmlParser.ParseFailedException.class,
+                () -> parseDocument(xml, VibrationXmlParser.FLAG_ALLOW_HIDDEN_APIS));
+    }
+
+    private void assertHiddenApisParseVibrationEffectFails(String xml) {
+        assertThrows("Expected parseVibrationEffect to fail for " + xml,
+                VibrationXmlParser.ParseFailedException.class,
+                () -> parseVibrationEffect(xml, VibrationXmlParser.FLAG_ALLOW_HIDDEN_APIS));
+    }
+
+    private void assertHiddenApisParserSucceeds(String xml, VibrationEffect effect)
+            throws Exception {
+        assertHiddenApisParseDocumentSucceeds(xml, effect);
+        assertHiddenApisParseVibrationEffectSucceeds(xml, effect);
+    }
+
+    private void assertHiddenApisParseDocumentSucceeds(String xml, VibrationEffect... effect)
+            throws Exception {
+        assertThat(parseDocument(xml, VibrationXmlParser.FLAG_ALLOW_HIDDEN_APIS))
+                .isEqualTo(new ParsedVibration(Arrays.asList(effect)));
+    }
+
+    private void assertHiddenApisParseVibrationEffectSucceeds(String xml, VibrationEffect effect)
+            throws Exception {
+        assertThat(parseVibrationEffect(xml, VibrationXmlParser.FLAG_ALLOW_HIDDEN_APIS))
+                .isEqualTo(effect);
+    }
+
+    private void assertPublicApisSerializerFails(VibrationEffect effect) {
+        assertThrows("Expected serialization to fail for " + effect,
+                VibrationXmlSerializer.SerializationFailedException.class,
+                () -> serialize(effect));
+    }
+
+    private void assertPublicApisSerializerSucceeds(VibrationEffect effect,
+            String... expectedSegments) throws Exception {
+        assertSerializationContainsSegments(serialize(effect), expectedSegments);
+    }
+
+    private void assertHiddenApisSerializerSucceeds(VibrationEffect effect,
+            String... expectedSegments) throws Exception {
+        assertSerializationContainsSegments(
+                serialize(effect, VibrationXmlSerializer.FLAG_ALLOW_HIDDEN_APIS), expectedSegments);
+    }
+
+    private void assertPublicApisRoundTrip(VibrationEffect effect) throws Exception {
+        assertThat(parseVibrationEffect(serialize(effect, /* flags= */ 0), /* flags= */ 0))
+                .isEqualTo(effect);
+    }
+
+    private void assertHiddenApisRoundTrip(VibrationEffect effect) throws Exception {
+        String xml = serialize(effect, VibrationXmlSerializer.FLAG_ALLOW_HIDDEN_APIS);
+        assertThat(parseVibrationEffect(xml, VibrationXmlParser.FLAG_ALLOW_HIDDEN_APIS))
+                .isEqualTo(effect);
+    }
+
     private TypedXmlPullParser createXmlPullParser(String xml) throws Exception {
         TypedXmlPullParser parser = Xml.newFastPullParser();
         parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
@@ -366,11 +523,6 @@
         return parser;
     }
 
-    private void assertParseDocumentSucceeds(String xml, int flags, VibrationEffect... effects)
-            throws Exception {
-        assertThat(parseDocument(xml, flags).getVibrationEffects()).containsExactly(effects);
-    }
-
     /**
      * Asserts parsing vibration from an open TypedXmlPullParser succeeds, and that the parser
      * points to the end "vibration" or "vibration-select" tag.
@@ -385,7 +537,8 @@
         String tagName = parser.getName();
         assertThat(Set.of("vibration-effect", "vibration-select")).contains(tagName);
 
-        assertThat(parseElement(parser, flags).getVibrationEffects()).containsExactly(effects);
+        assertThat(parseElement(parser, flags))
+                .isEqualTo(new ParsedVibration(Arrays.asList(effects)));
         assertThat(parser.getEventType()).isEqualTo(XmlPullParser.END_TAG);
         assertThat(parser.getName()).isEqualTo(tagName);
     }
@@ -405,69 +558,40 @@
         assertThat(parser.getEventType()).isEqualTo(parser.END_DOCUMENT);
     }
 
-    private void assertHiddenApisParseVibrationEffectSucceeds(String xml, VibrationEffect effect)
-            throws IOException {
-        assertThat(parseVibrationEffect(xml, VibrationXmlParser.FLAG_ALLOW_HIDDEN_APIS))
-                .isEqualTo(effect);
-    }
-
-    private void assertPublicApisSerializerFails(VibrationEffect effect) {
-        assertThrows("Expected serialization to fail for " + effect,
-                VibrationXmlSerializer.SerializationFailedException.class,
-                () -> serialize(effect, /* flags= */ 0));
-    }
-
     private void assertParseElementFails(String xml) {
         assertThrows("Expected parsing to fail for " + xml,
-                VibrationXmlParser.VibrationXmlParserException.class,
+                VibrationXmlParser.ParseFailedException.class,
                 () -> parseElement(createXmlPullParser(xml), /* flags= */ 0));
     }
 
-    private void assertPublicApisSerializerSucceeds(VibrationEffect effect,
-            String... expectedSegments) throws IOException {
-        assertSerializationContainsSegments(serialize(effect, /* flags= */ 0), expectedSegments);
-    }
-
-    private void assertHiddenApisSerializerSucceeds(VibrationEffect effect,
-            String... expectedSegments) throws IOException {
-        assertSerializationContainsSegments(
-                serialize(effect, VibrationXmlSerializer.FLAG_ALLOW_HIDDEN_APIS), expectedSegments);
-    }
-
     private void assertSerializationContainsSegments(String xml, String[] expectedSegments) {
         for (String expectedSegment : expectedSegments) {
             assertThat(xml).contains(expectedSegment);
         }
     }
 
-    private void assertPublicApisRoundTrip(VibrationEffect effect) throws IOException {
-        assertThat(parseVibrationEffect(serialize(effect, /* flags= */ 0), /* flags= */ 0))
-                .isEqualTo(effect);
-    }
-
-    private void assertHiddenApisRoundTrip(VibrationEffect effect) throws IOException {
-        String xml = serialize(effect, VibrationXmlSerializer.FLAG_ALLOW_HIDDEN_APIS);
-        assertThat(parseVibrationEffect(xml, VibrationXmlParser.FLAG_ALLOW_HIDDEN_APIS))
-                .isEqualTo(effect);
-    }
-
     private static VibrationEffect parseVibrationEffect(
-            String xml, @VibrationXmlParser.Flags int flags) throws IOException {
+            String xml, @VibrationXmlParser.Flags int flags) throws Exception {
         return VibrationXmlParser.parseVibrationEffect(new StringReader(xml), flags);
     }
 
-    private static ParsedVibration parseDocument(String xml, int flags)
-            throws IOException {
+    private static ParsedVibration parseDocument(String xml, int flags) throws Exception {
         return VibrationXmlParser.parseDocument(new StringReader(xml), flags);
     }
 
     private static ParsedVibration parseElement(TypedXmlPullParser parser, int flags)
-            throws IOException, VibrationXmlParser.VibrationXmlParserException {
+            throws Exception {
         return VibrationXmlParser.parseElement(parser, flags);
     }
 
+    private static String serialize(VibrationEffect effect) throws Exception {
+        StringWriter writer = new StringWriter();
+        VibrationXmlSerializer.serialize(effect, writer);
+        return writer.toString();
+    }
+
     private static String serialize(VibrationEffect effect, @VibrationXmlSerializer.Flags int flags)
-            throws IOException {
+            throws Exception {
         StringWriter writer = new StringWriter();
         VibrationXmlSerializer.serialize(effect, writer, flags);
         return writer.toString();
diff --git a/data/etc/com.android.settings.xml b/data/etc/com.android.settings.xml
index 7a4b6bc..99911de 100644
--- a/data/etc/com.android.settings.xml
+++ b/data/etc/com.android.settings.xml
@@ -69,5 +69,6 @@
         <permission name="android.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS" />
         <permission name="android.permission.SATELLITE_COMMUNICATION" />
         <permission name="android.permission.READ_SYSTEM_GRAMMATICAL_GENDER" />
+        <permission name="android.permission.SET_BIOMETRIC_DIALOG_ADVANCED" />
     </privapp-permissions>
 </permissions>
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index 66b47da..a115c65 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -40,6 +40,7 @@
         <permission name="android.permission.MASTER_CLEAR"/>
         <permission name="android.permission.MEDIA_CONTENT_CONTROL"/>
         <permission name="android.permission.MODIFY_AUDIO_ROUTING" />
+        <permission name="android.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED" />
         <permission name="android.permission.MODIFY_DAY_NIGHT_MODE"/>
         <permission name="android.permission.MODIFY_PHONE_STATE"/>
         <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
diff --git a/data/etc/package-shareduid-allowlist.xml b/data/etc/package-shareduid-allowlist.xml
index 2401d4a..3b35f44 100644
--- a/data/etc/package-shareduid-allowlist.xml
+++ b/data/etc/package-shareduid-allowlist.xml
@@ -32,4 +32,5 @@
 
 <config>
     <allow-package-shareduid package="android.test.settings" shareduid="android.uid.system" />
+    <allow-package-shareduid package="com.android.performanceLaunch" shareduid="com.android.performanceapp.tests" />
 </config>
diff --git a/data/keyboards/Vendor_18d1_Product_4f60.idc b/data/keyboards/Vendor_18d1_Product_4f60.idc
new file mode 100644
index 0000000..b9fd406
--- /dev/null
+++ b/data/keyboards/Vendor_18d1_Product_4f60.idc
@@ -0,0 +1,18 @@
+# Copyright 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Increase palm thresholds, since this touchpad has a tendency to overstate
+# touch sizes.
+gestureProp.Palm_Width = 40.0
+gestureProp.Multiple_Palm_Width = 40.0
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index 3256f31..5caedba 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -416,7 +416,8 @@
     }
 
     /**
-     * Retrieve the dataspace associated with the texture image.
+     * Retrieve the dataspace associated with the texture image
+     * set by the most recent call to {@link #updateTexImage}.
      */
     @SuppressLint("MethodNameUnits")
     public @NamedDataSpace int getDataSpace() {
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index c3aaf98..f8cb050 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -494,30 +494,37 @@
                         BitmapFactory.decodeByteArray(getDataBytes(), getDataOffset(),
                                 getDataLength())));
             case TYPE_URI:
-                InputStream is = getUriInputStream(context);
-                if (is != null) {
-                    final Bitmap bitmap = BitmapFactory.decodeStream(is);
-                    if (bitmap == null) {
-                        Log.w(TAG, "Unable to decode image from URI: " + getUriString());
-                        if (iconLoadDrawableReturnNullWhenUriDecodeFails()) {
-                            return null;
+                try (InputStream is = getUriInputStream(context)) {
+                    if (is != null) {
+                        final Bitmap bitmap = BitmapFactory.decodeStream(is);
+                        if (bitmap == null) {
+                            Log.w(TAG, "Unable to decode image from URI: " + getUriString());
+                            if (iconLoadDrawableReturnNullWhenUriDecodeFails()) {
+                                return null;
+                            }
                         }
+                        return new BitmapDrawable(context.getResources(), fixMaxBitmapSize(bitmap));
                     }
-                    return new BitmapDrawable(context.getResources(), fixMaxBitmapSize(bitmap));
+                } catch (IOException e) {
+                    throw new IllegalStateException(e);
                 }
                 break;
             case TYPE_URI_ADAPTIVE_BITMAP:
-                is = getUriInputStream(context);
-                if (is != null) {
-                    final Bitmap bitmap = BitmapFactory.decodeStream(is);
-                    if (bitmap == null) {
-                        Log.w(TAG, "Unable to decode image from URI: " + getUriString());
-                        if (iconLoadDrawableReturnNullWhenUriDecodeFails()) {
-                            return null;
+                try (InputStream is = getUriInputStream(context)) {
+                    if (is != null) {
+                        final Bitmap bitmap = BitmapFactory.decodeStream(is);
+                        if (bitmap == null) {
+                            Log.w(TAG, "Unable to decode image from URI: " + getUriString());
+                            if (iconLoadDrawableReturnNullWhenUriDecodeFails()) {
+                                return null;
+                            }
                         }
+                        return new AdaptiveIconDrawable(
+                                        null, new BitmapDrawable(context.getResources(),
+                                fixMaxBitmapSize(bitmap)));
                     }
-                    return new AdaptiveIconDrawable(null, new BitmapDrawable(context.getResources(),
-                            fixMaxBitmapSize(bitmap)));
+                } catch (IOException e) {
+                    throw new IllegalStateException(e);
                 }
                 break;
         }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
index 290fefa..544f0f3 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/DividerPresenter.java
@@ -169,6 +169,11 @@
     @GuardedBy("mLock")
     private int mDividerPosition;
 
+    /** Indicates if there are containers to be finished since the divider has appeared. */
+    @GuardedBy("mLock")
+    @VisibleForTesting
+    private boolean mHasContainersToFinish = false;
+
     DividerPresenter(int taskId, @NonNull DragEventCallback dragEventCallback,
             @NonNull Executor callbackExecutor) {
         mTaskId = taskId;
@@ -180,7 +185,8 @@
     void updateDivider(
             @NonNull WindowContainerTransaction wct,
             @NonNull TaskFragmentParentInfo parentInfo,
-            @Nullable SplitContainer topSplitContainer) {
+            @Nullable SplitContainer topSplitContainer,
+            boolean isTaskFragmentVanished) {
         if (!Flags.activityEmbeddingInteractiveDividerFlag()) {
             return;
         }
@@ -188,6 +194,18 @@
         synchronized (mLock) {
             // Clean up the decor surface if top SplitContainer is null.
             if (topSplitContainer == null) {
+                // Check if there are containers to finish but the TaskFragment hasn't vanished yet.
+                // Don't remove the decor surface and divider if so as the removal should happen in
+                // a following step when the TaskFragment has vanished. This ensures that the decor
+                // surface is removed only after the resulting Activity is ready to be shown,
+                // otherwise there may be flicker.
+                if (mHasContainersToFinish) {
+                    if (isTaskFragmentVanished) {
+                        setHasContainersToFinish(false);
+                    } else {
+                        return;
+                    }
+                }
                 removeDecorSurfaceAndDivider(wct);
                 return;
             }
@@ -868,11 +886,15 @@
         }
     }
 
+    void setHasContainersToFinish(boolean hasContainersToFinish) {
+        synchronized (mLock) {
+            mHasContainersToFinish = hasContainersToFinish;
+        }
+    }
+
     private static boolean isDraggingToFullscreenAllowed(
             @NonNull DividerAttributes dividerAttributes) {
-        // TODO(b/293654166) Use DividerAttributes.isDraggingToFullscreenAllowed when extension is
-        // updated to v7.
-        return false;
+        return dividerAttributes.isDraggingToFullscreenAllowed();
     }
 
     /**
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 f9a6caf..9ea2943 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/JetpackTaskFragmentOrganizer.java
@@ -17,6 +17,7 @@
 package androidx.window.extensions.embedding;
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.window.TaskFragmentAnimationParams.DEFAULT_ANIMATION_BACKGROUND_COLOR;
 import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_FRONT;
 import static android.window.TaskFragmentOperation.OP_TYPE_SET_ANIMATION_PARAMS;
 import static android.window.TaskFragmentOperation.OP_TYPE_SET_DIM_ON_TASK;
@@ -29,6 +30,7 @@
 import static androidx.window.extensions.embedding.SplitContainer.shouldFinishPrimaryWithSecondary;
 import static androidx.window.extensions.embedding.SplitContainer.shouldFinishSecondaryWithPrimary;
 
+import android.annotation.ColorInt;
 import android.app.Activity;
 import android.app.WindowConfiguration.WindowingMode;
 import android.content.Intent;
@@ -48,6 +50,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.window.flags.Flags;
 
 import java.util.Map;
 import java.util.concurrent.Executor;
@@ -391,13 +394,34 @@
         if (splitAttributes == null) {
             return TaskFragmentAnimationParams.DEFAULT;
         }
-        final AnimationBackground animationBackground = splitAttributes.getAnimationBackground();
-        if (animationBackground instanceof AnimationBackground.ColorBackground colorBackground) {
-            return new TaskFragmentAnimationParams.Builder()
-                    .setAnimationBackgroundColor(colorBackground.getColor())
-                    .build();
-        } else {
-            return TaskFragmentAnimationParams.DEFAULT;
+        final TaskFragmentAnimationParams.Builder builder =
+                new TaskFragmentAnimationParams.Builder();
+        final int animationBackgroundColor = getAnimationBackgroundColor(splitAttributes);
+        builder.setAnimationBackgroundColor(animationBackgroundColor);
+        if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+            final int openAnimationResId =
+                    splitAttributes.getAnimationParams().getOpenAnimationResId();
+            builder.setOpenAnimationResId(openAnimationResId);
+            final int closeAnimationResId =
+                    splitAttributes.getAnimationParams().getCloseAnimationResId();
+            builder.setCloseAnimationResId(closeAnimationResId);
+            final int changeAnimationResId =
+                    splitAttributes.getAnimationParams().getChangeAnimationResId();
+            builder.setChangeAnimationResId(changeAnimationResId);
         }
+        return builder.build();
+    }
+
+    @ColorInt
+    private static int getAnimationBackgroundColor(@NonNull SplitAttributes splitAttributes) {
+        int animationBackgroundColor = DEFAULT_ANIMATION_BACKGROUND_COLOR;
+        AnimationBackground animationBackground = splitAttributes.getAnimationBackground();
+        if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+            animationBackground = splitAttributes.getAnimationParams().getAnimationBackground();
+        }
+        if (animationBackground instanceof AnimationBackground.ColorBackground colorBackground) {
+            animationBackgroundColor = colorBackground.getColor();
+        }
+        return animationBackgroundColor;
     }
 }
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 f78e2b5..7ddda1f 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -673,7 +673,7 @@
                         break;
                     case TYPE_TASK_FRAGMENT_VANISHED:
                         mPresenter.removeTaskFragmentInfo(info);
-                        onTaskFragmentVanished(wct, info);
+                        onTaskFragmentVanished(wct, info, taskId);
                         break;
                     case TYPE_TASK_FRAGMENT_PARENT_INFO_CHANGED:
                         onTaskFragmentParentInfoChanged(wct, taskId,
@@ -834,7 +834,7 @@
     @VisibleForTesting
     @GuardedBy("mLock")
     void onTaskFragmentVanished(@NonNull WindowContainerTransaction wct,
-            @NonNull TaskFragmentInfo taskFragmentInfo) {
+            @NonNull TaskFragmentInfo taskFragmentInfo, int taskId) {
         final TaskFragmentContainer container = getContainer(taskFragmentInfo.getFragmentToken());
         if (container != null) {
             // Cleanup if the TaskFragment vanished is not requested by the organizer.
@@ -843,6 +843,11 @@
             updateContainersInTaskIfVisible(wct, container.getTaskId());
         }
         cleanupTaskFragment(taskFragmentInfo.getFragmentToken());
+        final TaskContainer taskContainer = getTaskContainer(taskId);
+        if (taskContainer != null) {
+            // Update the divider to clean up any decor surfaces.
+            updateDivider(wct, taskContainer, true /* isTaskFragmentVanished */);
+        }
     }
 
     /**
@@ -884,7 +889,7 @@
         // The divider need to be updated even if shouldUpdateContainer is false, because the decor
         // surface may change in TaskFragmentParentInfo, which requires divider update but not
         // container update.
-        updateDivider(wct, taskContainer);
+        updateDivider(wct, taskContainer, false /* isTaskFragmentVanished */);
 
         // If the last direct activity of the host task is dismissed and there's an always-on-top
         // overlay container in the task, the overlay container should also be dismissed.
@@ -899,14 +904,23 @@
     @GuardedBy("mLock")
     void updateContainersInTaskIfVisible(@NonNull WindowContainerTransaction wct, int taskId) {
         final TaskContainer taskContainer = getTaskContainer(taskId);
-        if (taskContainer != null && taskContainer.isVisible()) {
+        if (taskContainer == null) {
+            return;
+        }
+
+        if (taskContainer.isVisible()) {
             updateContainersInTask(wct, taskContainer);
+        } else if (Flags.fixNoContainerUpdateWithoutResize()) {
+            // the TaskFragmentContainers need to be updated when the task becomes visible
+            taskContainer.mTaskFragmentContainersNeedsUpdate = true;
         }
     }
 
     @GuardedBy("mLock")
     private void updateContainersInTask(@NonNull WindowContainerTransaction wct,
             @NonNull TaskContainer taskContainer) {
+        taskContainer.mTaskFragmentContainersNeedsUpdate = false;
+
         // Update all TaskFragments in the Task. Make a copy of the list since some may be
         // removed on updating.
         final List<TaskFragmentContainer> containers = taskContainer.getTaskFragmentContainers();
@@ -3257,12 +3271,15 @@
     }
 
     @GuardedBy("mLock")
-    void updateDivider(
-            @NonNull WindowContainerTransaction wct, @NonNull TaskContainer taskContainer) {
+    void updateDivider(@NonNull WindowContainerTransaction wct,
+            @NonNull TaskContainer taskContainer, boolean isTaskFragmentVanished) {
         final DividerPresenter dividerPresenter = mDividerPresenters.get(taskContainer.getTaskId());
         final TaskFragmentParentInfo parentInfo = taskContainer.getTaskFragmentParentInfo();
-        dividerPresenter.updateDivider(
-                wct, parentInfo, taskContainer.getTopNonFinishingSplitContainer());
+        final SplitContainer topSplitContainer = taskContainer.getTopNonFinishingSplitContainer();
+        if (dividerPresenter != null) {
+            dividerPresenter.updateDivider(
+                    wct, parentInfo, topSplitContainer, isTaskFragmentVanished);
+        }
     }
 
     @Override
@@ -3292,6 +3309,9 @@
                 final List<TaskFragmentContainer> containersToFinish = new ArrayList<>();
                 taskContainer.updateTopSplitContainerForDivider(
                         dividerPresenter, containersToFinish);
+                if (!containersToFinish.isEmpty()) {
+                    dividerPresenter.setHasContainersToFinish(true);
+                }
                 for (final TaskFragmentContainer container : containersToFinish) {
                     mPresenter.cleanupContainer(wct, container, false /* shouldFinishDependent */);
                 }
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index d888fa9..eb1fc23 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -20,8 +20,10 @@
 
 import static androidx.window.extensions.embedding.DividerPresenter.getBoundsOffsetForDivider;
 import static androidx.window.extensions.embedding.SplitAttributesHelper.isReversedLayout;
+import static androidx.window.extensions.embedding.SplitController.TAG;
 import static androidx.window.extensions.embedding.WindowAttributes.DIM_AREA_ON_TASK;
 
+import android.annotation.AnimRes;
 import android.app.Activity;
 import android.app.ActivityThread;
 import android.app.WindowConfiguration;
@@ -31,9 +33,11 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.IBinder;
+import android.util.Log;
 import android.util.Pair;
 import android.util.Size;
 import android.view.View;
@@ -56,6 +60,7 @@
 import androidx.window.extensions.layout.WindowLayoutComponentImpl;
 import androidx.window.extensions.layout.WindowLayoutInfo;
 
+import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.window.flags.Flags;
 
@@ -125,6 +130,16 @@
     static final int RESULT_EXPAND_FAILED_NO_TF_INFO = 2;
 
     /**
+     * The key of {@link ActivityStack} alignment relative to its parent container.
+     * <p>
+     * See {@link ContainerPosition} for possible values.
+     * <p>
+     * Note that this constants must align with the definition in WM Jetpack library.
+     */
+    private static final String KEY_ACTIVITY_STACK_ALIGNMENT =
+            "androidx.window.embedding.ActivityStackAlignment";
+
+    /**
      * Result of {@link #expandSplitContainerIfNeeded(WindowContainerTransaction, SplitContainer,
      * Activity, Activity, Intent)}
      */
@@ -374,7 +389,7 @@
         updateTaskFragmentWindowingModeIfRegistered(wct, secondaryContainer, windowingMode);
         updateAnimationParams(wct, primaryContainer.getTaskFragmentToken(), splitAttributes);
         updateAnimationParams(wct, secondaryContainer.getTaskFragmentToken(), splitAttributes);
-        mController.updateDivider(wct, taskContainer);
+        mController.updateDivider(wct, taskContainer, false /* isTaskFragmentVanished */);
     }
 
     private void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct,
@@ -649,14 +664,114 @@
         // TODO(b/243518738): Update to resizeTaskFragment after we migrate WCT#setRelativeBounds
         //  and WCT#setWindowingMode to take fragmentToken.
         resizeTaskFragmentIfRegistered(wct, container, relativeBounds);
-        int windowingMode = container.getTaskContainer().getWindowingModeForTaskFragment(
-                relativeBounds);
+        final TaskContainer taskContainer = container.getTaskContainer();
+        final int windowingMode = taskContainer.getWindowingModeForTaskFragment(relativeBounds);
         updateTaskFragmentWindowingModeIfRegistered(wct, container, windowingMode);
-        // Always use default animation for standalone ActivityStack.
-        updateAnimationParams(wct, fragmentToken, TaskFragmentAnimationParams.DEFAULT);
+        if (container.isOverlay() && isOverlayTransitionSupported()) {
+            // Use the overlay transition for the overlay container if it's supported.
+            final TaskFragmentAnimationParams params = createOverlayAnimationParams(relativeBounds,
+                    taskContainer.getBounds(), container);
+            updateAnimationParams(wct, fragmentToken, params);
+        } else {
+            // Otherwise, fallabck to use the default animation params.
+            updateAnimationParams(wct, fragmentToken, TaskFragmentAnimationParams.DEFAULT);
+        }
         setTaskFragmentDimOnTask(wct, fragmentToken, dimOnTask);
     }
 
+    private static boolean isOverlayTransitionSupported() {
+        return Flags.moveAnimationOptionsToChange()
+                && Flags.activityEmbeddingOverlayPresentationFlag();
+    }
+
+    @NonNull
+    private static TaskFragmentAnimationParams createOverlayAnimationParams(
+            @NonNull Rect relativeBounds, @NonNull Rect parentContainerBounds,
+            @NonNull TaskFragmentContainer container) {
+        if (relativeBounds.isEmpty()) {
+            return TaskFragmentAnimationParams.DEFAULT;
+        }
+
+        final int positionFromOptions = container.getLaunchOptions()
+                .getInt(KEY_ACTIVITY_STACK_ALIGNMENT , -1);
+        final int position = positionFromOptions != -1 ? positionFromOptions
+                // Fallback to calculate from bounds if the info can't be retrieved from options.
+                : getOverlayPosition(relativeBounds, parentContainerBounds);
+
+        return new TaskFragmentAnimationParams.Builder()
+                .setOpenAnimationResId(getOpenAnimationResourcesId(position))
+                .setChangeAnimationResId(R.anim.overlay_task_fragment_change)
+                .setCloseAnimationResId(getCloseAnimationResourcesId(position))
+                .build();
+    }
+
+    @VisibleForTesting
+    @ContainerPosition
+    static int getOverlayPosition(
+            @NonNull Rect relativeBounds, @NonNull Rect parentContainerBounds) {
+        final Rect relativeParentBounds = new Rect(parentContainerBounds);
+        relativeParentBounds.offsetTo(0, 0);
+        final int leftMatch = (relativeParentBounds.left == relativeBounds.left) ? 1 : 0;
+        final int topMatch = (relativeParentBounds.top == relativeBounds.top) ? 1 : 0;
+        final int rightMatch = (relativeParentBounds.right == relativeBounds.right) ? 1 : 0;
+        final int bottomMatch = (relativeParentBounds.bottom == relativeBounds.bottom) ? 1 : 0;
+
+        // Flag format: {left|top|right|bottom}. Note that overlay container could be shrunk and
+        // centered, which makes only one of overlay container edge matches the parent container.
+        final int directionFlag = (leftMatch << 3) + (topMatch << 2) + (rightMatch << 1)
+                + bottomMatch;
+
+        final int position = switch (directionFlag) {
+            // Only the left edge match or only the right edge not match: should be on the left of
+            // the parent container.
+            case 0b1000, 0b1101 -> CONTAINER_POSITION_LEFT;
+            // Only the top edge match or only the bottom edge not match: should be on the top of
+            // the parent container.
+            case 0b0100, 0b1110 -> CONTAINER_POSITION_TOP;
+            // Only the right edge match or only the left edge not match: should be on the right of
+            // the parent container.
+            case 0b0010, 0b0111 -> CONTAINER_POSITION_RIGHT;
+            // Only the bottom edge match or only the top edge not match: should be on the bottom of
+            // the parent container.
+            case 0b0001, 0b1011 -> CONTAINER_POSITION_BOTTOM;
+            default -> {
+                Log.w(TAG, "Unsupported position:" + Integer.toBinaryString(directionFlag)
+                        + " fallback to treat it as right. Relative parent bounds: "
+                        + relativeParentBounds + ", relative overlay bounds:" + relativeBounds);
+                yield CONTAINER_POSITION_RIGHT;
+            }
+        };
+        return position;
+    }
+
+    @AnimRes
+    private static int getOpenAnimationResourcesId(@ContainerPosition int position) {
+        return switch (position) {
+            case CONTAINER_POSITION_LEFT -> R.anim.overlay_task_fragment_open_from_left;
+            case CONTAINER_POSITION_TOP -> R.anim.overlay_task_fragment_open_from_top;
+            case CONTAINER_POSITION_RIGHT -> R.anim.overlay_task_fragment_open_from_right;
+            case CONTAINER_POSITION_BOTTOM -> R.anim.overlay_task_fragment_open_from_bottom;
+            default -> {
+                Log.w(TAG, "Unknown position:" + position);
+                yield Resources.ID_NULL;
+            }
+        };
+    }
+
+    @AnimRes
+    private static int getCloseAnimationResourcesId(@ContainerPosition int position) {
+        return switch (position) {
+            case CONTAINER_POSITION_LEFT -> R.anim.overlay_task_fragment_close_to_left;
+            case CONTAINER_POSITION_TOP -> R.anim.overlay_task_fragment_close_to_top;
+            case CONTAINER_POSITION_RIGHT -> R.anim.overlay_task_fragment_close_to_right;
+            case CONTAINER_POSITION_BOTTOM -> R.anim.overlay_task_fragment_close_to_bottom;
+            default -> {
+                Log.w(TAG, "Unknown position:" + position);
+                yield Resources.ID_NULL;
+            }
+        };
+    }
+
     /**
      * Returns the expanded bounds if the {@code relBounds} violate minimum dimension or are not
      * fully covered by the task bounds. Otherwise, returns {@code relBounds}.
@@ -757,7 +872,8 @@
     void expandTaskFragment(@NonNull WindowContainerTransaction wct,
             @NonNull TaskFragmentContainer container) {
         super.expandTaskFragment(wct, container);
-        mController.updateDivider(wct, container.getTaskContainer());
+        mController.updateDivider(
+                wct, container.getTaskContainer(), false /* isTaskFragmentVanished */);
     }
 
     static boolean shouldShowSplit(@NonNull SplitContainer splitContainer) {
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
index ee00c4c..20ad53e 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
@@ -108,6 +108,12 @@
     private boolean mPlaceholderRuleSuppressed;
 
     /**
+     * {@code true} if the TaskFragments in this Task needs to be updated next time the Task
+     * becomes visible. See {@link #shouldUpdateContainer(TaskFragmentParentInfo)}
+     */
+    boolean mTaskFragmentContainersNeedsUpdate;
+
+    /**
      * The {@link TaskContainer} constructor
      *
      * @param taskId         The ID of the Task, which must match {@link Activity#getTaskId()} with
@@ -185,7 +191,8 @@
 
         // If the task properties equals regardless of starting position, don't
         // need to update the container.
-        return mInfo.getConfiguration().diffPublicOnly(configuration) != 0
+        return mTaskFragmentContainersNeedsUpdate
+                || mInfo.getConfiguration().diffPublicOnly(configuration) != 0
                 || mInfo.getDisplayId() != info.getDisplayId();
     }
 
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 070fa5b..859bc2c 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
@@ -17,6 +17,7 @@
 package androidx.window.extensions.layout;
 
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
 
 import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_FLAT;
 import static androidx.window.common.CommonFoldingFeature.COMMON_STATE_HALF_OPENED;
@@ -41,6 +42,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.UiContext;
+import androidx.annotation.VisibleForTesting;
 import androidx.window.common.CommonFoldingFeature;
 import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
 import androidx.window.common.EmptyLifecycleCallbacksAdapter;
@@ -138,6 +140,10 @@
                 throw new IllegalArgumentException("Context must be a UI Context, which should be"
                         + " an Activity, WindowContext or InputMethodService");
             }
+            if (context.getAssociatedDisplayId() == INVALID_DISPLAY) {
+                Log.w(TAG, "The registered Context is a UI Context but not associated with any"
+                        + " display. This Context may not receive any WindowLayoutInfo update");
+            }
             mFoldingFeatureProducer.getData((features) -> {
                 WindowLayoutInfo newWindowLayout = getWindowLayoutInfo(context, features);
                 consumer.accept(newWindowLayout);
@@ -257,7 +263,8 @@
         }
     }
 
-    private void onDisplayFeaturesChanged(List<CommonFoldingFeature> storedFeatures) {
+    @VisibleForTesting
+    void onDisplayFeaturesChanged(List<CommonFoldingFeature> storedFeatures) {
         synchronized (mLock) {
             mLastReportedFoldingFeatures.clear();
             mLastReportedFoldingFeatures.addAll(storedFeatures);
@@ -409,9 +416,10 @@
      * @return true if the display features should be reported for the UI Context, false otherwise.
      */
     private boolean shouldReportDisplayFeatures(@NonNull @UiContext Context context) {
-        int displayId = context.getDisplay().getDisplayId();
+        int displayId = context.getAssociatedDisplayId();
         if (displayId != DEFAULT_DISPLAY) {
-            // Display features are not supported on secondary displays.
+            // Display features are not supported on secondary displays or the context is not
+            // associated with any display.
             return false;
         }
 
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
index 4267749..c5aaddc 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
@@ -29,6 +29,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 import androidx.window.extensions.embedding.AnimationBackground;
+import androidx.window.extensions.embedding.AnimationParams;
 import androidx.window.extensions.embedding.SplitAttributes;
 
 import org.junit.Before;
@@ -112,5 +113,13 @@
                 .isEqualTo(new SplitAttributes.SplitType.RatioSplitType(0.5f));
         assertThat(splitAttributes.getAnimationBackground())
                 .isEqualTo(AnimationBackground.ANIMATION_BACKGROUND_DEFAULT);
+        assertThat(splitAttributes.getAnimationParams().getAnimationBackground())
+                .isEqualTo(AnimationBackground.ANIMATION_BACKGROUND_DEFAULT);
+        assertThat(splitAttributes.getAnimationParams().getOpenAnimationResId())
+                .isEqualTo(AnimationParams.DEFAULT_ANIMATION_RESOURCES_ID);
+        assertThat(splitAttributes.getAnimationParams().getCloseAnimationResId())
+                .isEqualTo(AnimationParams.DEFAULT_ANIMATION_RESOURCES_ID);
+        assertThat(splitAttributes.getAnimationParams().getChangeAnimationResId())
+                .isEqualTo(AnimationParams.DEFAULT_ANIMATION_RESOURCES_ID);
     }
 }
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java
index 4f51815..bc18cd2 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/DividerPresenterTest.java
@@ -82,6 +82,7 @@
  */
 @Presubmit
 @SmallTest
+@SuppressWarnings("GuardedBy")
 @RunWith(AndroidJUnit4.class)
 public class DividerPresenterTest {
     @Rule
@@ -186,7 +187,8 @@
         mDividerPresenter.updateDivider(
                 mTransaction,
                 mParentInfo,
-                mSplitContainer);
+                mSplitContainer,
+                false /* isTaskFragmentVanished */);
 
         assertNotEquals(mProperties, mDividerPresenter.mProperties);
         verify(mRenderer).update();
@@ -206,7 +208,8 @@
         mDividerPresenter.updateDivider(
                 mTransaction,
                 mParentInfo,
-                mSplitContainer);
+                mSplitContainer,
+                false /* isTaskFragmentVanished */);
 
         assertNotEquals(mProperties, mDividerPresenter.mProperties);
         verify(mRenderer).update();
@@ -222,7 +225,8 @@
         mDividerPresenter.updateDivider(
                 mTransaction,
                 mParentInfo,
-                mSplitContainer);
+                mSplitContainer,
+                false /* isTaskFragmentVanished */);
 
         assertEquals(mProperties, mDividerPresenter.mProperties);
         verify(mRenderer, never()).update();
@@ -234,7 +238,42 @@
         mDividerPresenter.updateDivider(
                 mTransaction,
                 mParentInfo,
-                null /* splitContainer */);
+                null /* splitContainer */,
+                false /* isTaskFragmentVanished */);
+        final TaskFragmentOperation taskFragmentOperation = new TaskFragmentOperation.Builder(
+                OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE)
+                .build();
+
+        verify(mTransaction).addTaskFragmentOperation(
+                mPrimaryContainerToken, taskFragmentOperation);
+        verify(mRenderer).release();
+        assertNull(mDividerPresenter.mRenderer);
+        assertNull(mDividerPresenter.mProperties);
+        assertNull(mDividerPresenter.mDecorSurfaceOwner);
+    }
+
+    @Test
+    public void testUpdateDivider_noChangeWhenHasContainersToFinishButTaskFragmentNotVanished() {
+        mDividerPresenter.setHasContainersToFinish(true);
+        mDividerPresenter.updateDivider(
+                mTransaction,
+                mParentInfo,
+                null /* splitContainer */,
+                false /* isTaskFragmentVanished */);
+
+        assertEquals(mProperties, mDividerPresenter.mProperties);
+        verify(mRenderer, never()).update();
+        verify(mTransaction, never()).addTaskFragmentOperation(any(), any());
+    }
+
+    @Test
+    public void testUpdateDivider_dividerRemovedWhenHasContainersToFinishAndTaskFragmentVanished() {
+        mDividerPresenter.setHasContainersToFinish(true);
+        mDividerPresenter.updateDivider(
+                mTransaction,
+                mParentInfo,
+                null /* splitContainer */,
+                true /* isTaskFragmentVanished */);
         final TaskFragmentOperation taskFragmentOperation = new TaskFragmentOperation.Builder(
                 OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE)
                 .build();
@@ -254,7 +293,8 @@
         mDividerPresenter.updateDivider(
                 mTransaction,
                 mParentInfo,
-                mSplitContainer);
+                mSplitContainer,
+                false /* isTaskFragmentVanished */);
         final TaskFragmentOperation taskFragmentOperation = new TaskFragmentOperation.Builder(
                 OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE)
                 .build();
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
index 7a0b9a0..3257502 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/OverlayPresentationTest.java
@@ -30,6 +30,11 @@
 import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSplitPlaceholderRuleBuilder;
 import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSplitRule;
 import static androidx.window.extensions.embedding.EmbeddingTestUtils.createTfContainer;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_BOTTOM;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_LEFT;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_RIGHT;
+import static androidx.window.extensions.embedding.SplitPresenter.CONTAINER_POSITION_TOP;
+import static androidx.window.extensions.embedding.SplitPresenter.getOverlayPosition;
 import static androidx.window.extensions.embedding.SplitPresenter.sanitizeBounds;
 import static androidx.window.extensions.embedding.WindowAttributes.DIM_AREA_ON_TASK;
 
@@ -666,8 +671,8 @@
                 attributes.getRelativeBounds());
         verify(mSplitPresenter).updateTaskFragmentWindowingModeIfRegistered(mTransaction, container,
                 WINDOWING_MODE_MULTI_WINDOW);
-        verify(mSplitPresenter).updateAnimationParams(mTransaction, token,
-                TaskFragmentAnimationParams.DEFAULT);
+        verify(mSplitPresenter).updateAnimationParams(eq(mTransaction), eq(token),
+                any(TaskFragmentAnimationParams.class));
         verify(mSplitPresenter).setTaskFragmentIsolatedNavigation(mTransaction, container, true);
         verify(mSplitPresenter, never()).setTaskFragmentPinned(any(),
                 any(TaskFragmentContainer.class), anyBoolean());
@@ -691,8 +696,8 @@
                 attributes.getRelativeBounds());
         verify(mSplitPresenter).updateTaskFragmentWindowingModeIfRegistered(mTransaction,
                 container, WINDOWING_MODE_MULTI_WINDOW);
-        verify(mSplitPresenter).updateAnimationParams(mTransaction, token,
-                TaskFragmentAnimationParams.DEFAULT);
+        verify(mSplitPresenter).updateAnimationParams(eq(mTransaction), eq(token),
+                any(TaskFragmentAnimationParams.class));
         verify(mSplitPresenter, never()).setTaskFragmentIsolatedNavigation(any(),
                 any(TaskFragmentContainer.class), anyBoolean());
         verify(mSplitPresenter).setTaskFragmentPinned(mTransaction, container, true);
@@ -870,6 +875,59 @@
                 eq(overlayContainer.getTaskFragmentToken()), eq(activityToken));
     }
 
+    // TODO(b/243518738): Rewrite with TestParameter.
+    @Test
+    public void testGetOverlayPosition() {
+        assertWithMessage("It must be position left for left overlay.")
+                .that(getOverlayPosition(new Rect(
+                        TASK_BOUNDS.left,
+                        TASK_BOUNDS.top,
+                        TASK_BOUNDS.right / 2,
+                        TASK_BOUNDS.bottom), TASK_BOUNDS)).isEqualTo(CONTAINER_POSITION_LEFT);
+        assertWithMessage("It must be position left for shrunk left overlay.")
+                .that(getOverlayPosition(new Rect(
+                        TASK_BOUNDS.left,
+                        TASK_BOUNDS.top + 20,
+                        TASK_BOUNDS.right / 2,
+                        TASK_BOUNDS.bottom - 20), TASK_BOUNDS)).isEqualTo(CONTAINER_POSITION_LEFT);
+        assertWithMessage("It must be position left for top overlay.")
+                .that(getOverlayPosition(new Rect(
+                        TASK_BOUNDS.left,
+                        TASK_BOUNDS.top,
+                        TASK_BOUNDS.right,
+                        TASK_BOUNDS.bottom / 2), TASK_BOUNDS)).isEqualTo(CONTAINER_POSITION_TOP);
+        assertWithMessage("It must be position left for shrunk top overlay.")
+                .that(getOverlayPosition(new Rect(
+                        TASK_BOUNDS.left + 20,
+                        TASK_BOUNDS.top,
+                        TASK_BOUNDS.right - 20,
+                        TASK_BOUNDS.bottom / 2), TASK_BOUNDS)).isEqualTo(CONTAINER_POSITION_TOP);
+        assertWithMessage("It must be position left for right overlay.")
+                .that(getOverlayPosition(new Rect(
+                        TASK_BOUNDS.right / 2,
+                        TASK_BOUNDS.top,
+                        TASK_BOUNDS.right,
+                        TASK_BOUNDS.bottom), TASK_BOUNDS)).isEqualTo(CONTAINER_POSITION_RIGHT);
+        assertWithMessage("It must be position left for shrunk right overlay.")
+                .that(getOverlayPosition(new Rect(
+                        TASK_BOUNDS.right / 2,
+                        TASK_BOUNDS.top + 20,
+                        TASK_BOUNDS.right,
+                        TASK_BOUNDS.bottom - 20), TASK_BOUNDS)).isEqualTo(CONTAINER_POSITION_RIGHT);
+        assertWithMessage("It must be position left for bottom overlay.")
+                .that(getOverlayPosition(new Rect(
+                        TASK_BOUNDS.left,
+                        TASK_BOUNDS.bottom / 2,
+                        TASK_BOUNDS.right,
+                        TASK_BOUNDS.bottom), TASK_BOUNDS)).isEqualTo(CONTAINER_POSITION_BOTTOM);
+        assertWithMessage("It must be position left for shrunk bottom overlay.")
+                .that(getOverlayPosition(new Rect(
+                        TASK_BOUNDS.left + 20,
+                        TASK_BOUNDS.bottom / 20,
+                        TASK_BOUNDS.right - 20,
+                        TASK_BOUNDS.bottom), TASK_BOUNDS)).isEqualTo(CONTAINER_POSITION_BOTTOM);
+    }
+
     /**
      * A simplified version of {@link SplitController#createOrUpdateOverlayTaskFragmentIfNeeded}
      */
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 640b1fc..efeec82 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
@@ -200,12 +200,14 @@
     public void testOnTaskFragmentVanished() {
         final TaskFragmentContainer tf = createTfContainer(mSplitController, mActivity);
         doReturn(tf.getTaskFragmentToken()).when(mInfo).getFragmentToken();
+        doReturn(createTestTaskContainer()).when(mSplitController).getTaskContainer(TASK_ID);
 
         // The TaskFragment has been removed in the server, we only need to cleanup the reference.
-        mSplitController.onTaskFragmentVanished(mTransaction, mInfo);
+        mSplitController.onTaskFragmentVanished(mTransaction, mInfo, TASK_ID);
 
         verify(mSplitPresenter, never()).deleteTaskFragment(any(), any());
         verify(mSplitController).removeContainer(tf);
+        verify(mSplitController).updateDivider(any(), any(), anyBoolean());
         verify(mTransaction, never()).finishActivity(any());
     }
 
@@ -1152,7 +1154,7 @@
                 .setTaskFragmentInfo(info));
         mSplitController.onTransactionReady(transaction);
 
-        verify(mSplitController).onTaskFragmentVanished(any(), eq(info));
+        verify(mSplitController).onTaskFragmentVanished(any(), eq(info), anyInt());
         verify(mSplitPresenter).onTransactionHandled(eq(transaction.getTransactionToken()), any(),
                 anyInt(), anyBoolean());
     }
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/layout/WindowLayoutComponentImplTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/layout/WindowLayoutComponentImplTest.java
new file mode 100644
index 0000000..ff0a82f
--- /dev/null
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/layout/WindowLayoutComponentImplTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.window.extensions.layout;
+
+import static org.mockito.Mockito.mock;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collections;
+
+/**
+ * Test class for {@link WindowLayoutComponentImpl}.
+ *
+ * Build/Install/Run:
+ *  atest WMJetpackUnitTests:WindowLayoutComponentImplTest
+ */
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class WindowLayoutComponentImplTest {
+
+    private WindowLayoutComponentImpl mWindowLayoutComponent;
+
+    @Before
+    public void setUp() {
+        mWindowLayoutComponent = new WindowLayoutComponentImpl(
+                ApplicationProvider.getApplicationContext(),
+                mock(DeviceStateManagerFoldingFeatureProducer.class));
+    }
+
+    @Test
+    public void testAddWindowLayoutListenerOnFakeUiContext_noCrash() {
+        final Context fakeUiContext = createTestContext();
+
+        mWindowLayoutComponent.addWindowLayoutInfoListener(fakeUiContext, info -> {});
+
+        mWindowLayoutComponent.onDisplayFeaturesChanged(Collections.emptyList());
+    }
+
+    private static Context createTestContext() {
+        return new FakeUiContext(ApplicationProvider.getApplicationContext());
+    }
+
+    /**
+     * A {@link android.content.Context} overrides {@link android.content.Context#isUiContext} to
+     * {@code true}.
+     */
+    private static class FakeUiContext extends ContextWrapper {
+
+        FakeUiContext(Context base) {
+            super(base);
+        }
+
+        @Override
+        public boolean isUiContext() {
+            return true;
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index 25d3067..dbcad8a 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -88,7 +88,7 @@
     ],
     tools: ["protologtool"],
     cmd: "$(location protologtool) transform-protolog-calls " +
-        "--protolog-class com.android.internal.protolog.common.ProtoLog " +
+        "--protolog-class com.android.internal.protolog.ProtoLog " +
         "--loggroups-class com.android.wm.shell.protolog.ShellProtoLogGroup " +
         "--loggroups-jar $(location :wm_shell_protolog-groups) " +
         "--viewer-config-file-path /system_ext/etc/wmshell.protolog.pb " +
@@ -107,7 +107,7 @@
     ],
     tools: ["protologtool"],
     cmd: "$(location protologtool) generate-viewer-config " +
-        "--protolog-class com.android.internal.protolog.common.ProtoLog " +
+        "--protolog-class com.android.internal.protolog.ProtoLog " +
         "--loggroups-class com.android.wm.shell.protolog.ShellProtoLogGroup " +
         "--loggroups-jar $(location :wm_shell_protolog-groups) " +
         "--viewer-config-type json " +
@@ -124,7 +124,7 @@
     ],
     tools: ["protologtool"],
     cmd: "$(location protologtool) generate-viewer-config " +
-        "--protolog-class com.android.internal.protolog.common.ProtoLog " +
+        "--protolog-class com.android.internal.protolog.ProtoLog " +
         "--loggroups-class com.android.wm.shell.protolog.ShellProtoLogGroup " +
         "--loggroups-jar $(location :wm_shell_protolog-groups) " +
         "--viewer-config-type proto " +
@@ -190,6 +190,15 @@
     ],
 }
 
+java_library {
+    name: "WindowManager-Shell-shared-desktopMode",
+
+    srcs: [
+        "shared/**/desktopmode/*.java",
+        "shared/**/desktopmode/*.kt",
+    ],
+}
+
 android_library {
     name: "WindowManager-Shell",
     srcs: [
diff --git a/libs/WindowManager/Shell/AndroidManifest.xml b/libs/WindowManager/Shell/AndroidManifest.xml
index bcb1d29..52ae93f 100644
--- a/libs/WindowManager/Shell/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/AndroidManifest.xml
@@ -29,6 +29,7 @@
             android:name=".desktopmode.DesktopWallpaperActivity"
             android:excludeFromRecents="true"
             android:launchMode="singleInstance"
+            android:showForAllUsers="true"
             android:theme="@style/DesktopWallpaperTheme" />
 
         <activity
diff --git a/libs/WindowManager/Shell/aconfig/multitasking.aconfig b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
index 112eb61..3ff40e0 100644
--- a/libs/WindowManager/Shell/aconfig/multitasking.aconfig
+++ b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
@@ -121,3 +121,20 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    name: "enable_taskbar_on_phones"
+    namespace: "multitasking"
+    description: "Enables taskbar on phones"
+    bug: "348007377"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
+    name: "enable_bubble_bar_in_persistent_task_bar"
+    namespace: "multitasking"
+    description: "Enable bubble bar to be shown in the persistent task bar"
+    bug: "346391377"
+}
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/Android.bp b/libs/WindowManager/Shell/multivalentScreenshotTests/Android.bp
new file mode 100644
index 0000000..1871203
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/Android.bp
@@ -0,0 +1,95 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES 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"],
+    default_team: "trendy_team_multitasking_windowing",
+}
+
+android_app {
+    name: "WMShellRobolectricScreenshotTestApp",
+    platform_apis: true,
+    certificate: "platform",
+    static_libs: [
+        "WindowManager-Shell",
+        "platform-screenshot-diff-core",
+    ],
+    asset_dirs: ["goldens/robolectric"],
+    manifest: "AndroidManifestRobolectric.xml",
+    use_resource_processor: true,
+}
+
+android_robolectric_test {
+    name: "WMShellRobolectricScreenshotTests",
+    instrumentation_for: "WMShellRobolectricScreenshotTestApp",
+    upstream: true,
+    java_resource_dirs: [
+        "robolectric/config",
+    ],
+    srcs: [
+        "src/**/*.kt",
+    ],
+    static_libs: [
+        "junit",
+        "androidx.test.runner",
+        "androidx.test.rules",
+        "androidx.test.ext.junit",
+        "truth",
+        "platform-parametric-runner-lib",
+    ],
+    auto_gen_config: true,
+}
+
+android_test {
+    name: "WMShellMultivalentScreenshotTestsOnDevice",
+    srcs: [
+        "src/**/*.kt",
+    ],
+    static_libs: [
+        "WindowManager-Shell",
+        "junit",
+        "androidx.test.runner",
+        "androidx.test.rules",
+        "androidx.test.ext.junit",
+        "truth",
+        "platform-parametric-runner-lib",
+        "platform-screenshot-diff-core",
+    ],
+    libs: [
+        "android.test.base",
+        "android.test.runner",
+    ],
+    jni_libs: [
+        "libdexmakerjvmtiagent",
+        "libstaticjvmtiagent",
+    ],
+    kotlincflags: ["-Xjvm-default=all"],
+    optimize: {
+        enabled: false,
+    },
+    test_suites: ["device-tests"],
+    platform_apis: true,
+    certificate: "platform",
+    aaptflags: [
+        "--extra-packages",
+        "com.android.wm.shell",
+    ],
+    manifest: "AndroidManifest.xml",
+    asset_dirs: ["goldens/onDevice"],
+}
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/AndroidManifest.xml b/libs/WindowManager/Shell/multivalentScreenshotTests/AndroidManifest.xml
new file mode 100644
index 0000000..467dc6a
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="com.android.wm.shell.multivalentscreenshot">
+
+    <application android:debuggable="true" android:supportsRtl="true" >
+        <uses-library android:name="android.test.runner" />
+        <activity
+            android:name="platform.test.screenshot.ScreenshotActivity"
+            android:exported="true">
+        </activity>
+    </application>
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:label="Multivalent screenshot tests for WindowManager-Shell"
+        android:targetPackage="com.android.wm.shell.multivalentscreenshot">
+    </instrumentation>
+
+    <!-- this permission is required by Tuner Service in screenshot tests -->
+    <uses-permission android:name="android.permission.MANAGE_USERS" />
+</manifest>
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/AndroidManifestRobolectric.xml b/libs/WindowManager/Shell/multivalentScreenshotTests/AndroidManifestRobolectric.xml
new file mode 100644
index 0000000..b4bdaea
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/AndroidManifestRobolectric.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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="com.android.wm.shell.multivalentscreenshot">
+    <application android:debuggable="true" android:supportsRtl="true">
+        <activity
+            android:name="platform.test.screenshot.ScreenshotActivity"
+            android:exported="true">
+        </activity>
+    </application>
+</manifest>
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/AndroidTest.xml b/libs/WindowManager/Shell/multivalentScreenshotTests/AndroidTest.xml
new file mode 100644
index 0000000..75793ae
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/AndroidTest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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 Tests for WindowManagerShellLib">
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+    <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="WMShellMultivalentScreenshotTestsOnDevice.apk" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-tag" value="WMShellMultivalentScreenshotTestsOnDevice" />
+    <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
+        <option name="directory-keys" value="/data/user/0/com.android.wm.shell.multivalentscreenshot/files/wmshell_screenshots" />
+        <option name="collect-on-run-ended-only" value="true" />
+    </metrics_collector>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.wm.shell.multivalentscreenshot" />
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/OWNERS b/libs/WindowManager/Shell/multivalentScreenshotTests/OWNERS
new file mode 100644
index 0000000..dc11241
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/OWNERS
@@ -0,0 +1,4 @@
+atsjenk@google.com
+liranb@google.com
+madym@google.com
+mpodolian@google.com
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/phone/dark_portrait_bubbles_education.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/phone/dark_portrait_bubbles_education.png
new file mode 100644
index 0000000..027b28e
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/phone/dark_portrait_bubbles_education.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/phone/light_portrait_bubbles_education.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/phone/light_portrait_bubbles_education.png
new file mode 100644
index 0000000..027b28e
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice/phone/light_portrait_bubbles_education.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/dark_portrait_bubbles_education.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/dark_portrait_bubbles_education.png
new file mode 100644
index 0000000..e02c89a
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/dark_portrait_bubbles_education.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/light_portrait_bubbles_education.png b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/light_portrait_bubbles_education.png
new file mode 100644
index 0000000..e02c89a
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/robolectric/phone/light_portrait_bubbles_education.png
Binary files differ
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/robolectric/config/robolectric.properties b/libs/WindowManager/Shell/multivalentScreenshotTests/robolectric/config/robolectric.properties
new file mode 100644
index 0000000..d50d976
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/robolectric/config/robolectric.properties
@@ -0,0 +1,3 @@
+sdk=NEWEST_SDK
+graphicsMode=NATIVE
+
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/src/com/android/wm/shell/bubbles/BubbleEducationViewScreenshotTest.kt b/libs/WindowManager/Shell/multivalentScreenshotTests/src/com/android/wm/shell/bubbles/BubbleEducationViewScreenshotTest.kt
new file mode 100644
index 0000000..d35f493
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/src/com/android/wm/shell/bubbles/BubbleEducationViewScreenshotTest.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.bubbles
+
+import android.view.LayoutInflater
+import com.android.wm.shell.common.bubbles.BubblePopupView
+import com.android.wm.shell.testing.goldenpathmanager.WMShellGoldenPathManager
+import com.android.wm.shell.R
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+import platform.test.screenshot.DeviceEmulationSpec
+import platform.test.screenshot.Displays
+import platform.test.screenshot.ViewScreenshotTestRule
+import platform.test.screenshot.getEmulatedDevicePathConfig
+
+@RunWith(ParameterizedAndroidJunit4::class)
+class BubbleEducationViewScreenshotTest(emulationSpec: DeviceEmulationSpec) {
+    companion object {
+        @Parameters(name = "{0}")
+        @JvmStatic
+        fun getTestSpecs() = DeviceEmulationSpec.forDisplays(Displays.Phone, isLandscape = false)
+    }
+
+    @get:Rule
+    val screenshotRule =
+        ViewScreenshotTestRule(
+            emulationSpec,
+            WMShellGoldenPathManager(getEmulatedDevicePathConfig(emulationSpec))
+        )
+
+    @Test
+    fun bubblesEducation() {
+        screenshotRule.screenshotTest("bubbles_education") { activity ->
+            activity.actionBar?.hide()
+            val view =
+                LayoutInflater.from(activity)
+                    .inflate(R.layout.bubble_bar_stack_education, null) as BubblePopupView
+            view.setup()
+            view
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTests/src/com/android/wm/shell/testing/goldenpathmanager/WMShellGoldenPathManager.kt b/libs/WindowManager/Shell/multivalentScreenshotTests/src/com/android/wm/shell/testing/goldenpathmanager/WMShellGoldenPathManager.kt
new file mode 100644
index 0000000..901b79b
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTests/src/com/android/wm/shell/testing/goldenpathmanager/WMShellGoldenPathManager.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.testing.goldenpathmanager
+
+import android.os.Build
+import androidx.test.platform.app.InstrumentationRegistry
+import platform.test.screenshot.GoldenPathManager
+import platform.test.screenshot.PathConfig
+
+/** A WM Shell specific implementation of [GoldenPathManager]. */
+class WMShellGoldenPathManager(pathConfig: PathConfig) :
+    GoldenPathManager(
+        appContext = InstrumentationRegistry.getInstrumentation().context,
+        assetsPathRelativeToBuildRoot = assetPath,
+        deviceLocalPath = deviceLocalPath,
+        pathConfig = pathConfig,
+    ) {
+
+    private companion object {
+        private const val ASSETS_PATH =
+            "frameworks/base/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/onDevice"
+        private const val ASSETS_PATH_ROBO =
+            "frameworks/base/libs/WindowManager/Shell/multivalentScreenshotTests/goldens/" +
+                    "robolectric"
+        private val assetPath: String
+            get() = if (Build.FINGERPRINT.contains("robolectric")) ASSETS_PATH_ROBO else ASSETS_PATH
+        private val deviceLocalPath: String
+            get() =
+                InstrumentationRegistry.getInstrumentation()
+                    .targetContext
+                    .filesDir
+                    .absolutePath
+                    .toString() + "/wmshell_screenshots"
+    }
+    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 "WMShellGoldenPathManager"
+    }
+}
diff --git a/libs/WindowManager/Shell/multivalentScreenshotTestsForDevice b/libs/WindowManager/Shell/multivalentScreenshotTestsForDevice
new file mode 120000
index 0000000..e879efc
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentScreenshotTestsForDevice
@@ -0,0 +1 @@
+multivalentScreenshotTests
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
index 9e1440d..ae60d8b 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubblePositionerTest.kt
@@ -27,7 +27,7 @@
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.internal.protolog.common.ProtoLog
+import com.android.internal.protolog.ProtoLog
 import com.android.wm.shell.R
 import com.android.wm.shell.bubbles.BubblePositioner.MAX_HEIGHT
 import com.android.wm.shell.common.bubbles.BubbleBarLocation
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt
index 327e205..5e67333 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/BubbleStackViewTest.kt
@@ -32,7 +32,7 @@
 import androidx.test.filters.SmallTest
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.internal.logging.testing.UiEventLoggerFake
-import com.android.internal.protolog.common.ProtoLog
+import com.android.internal.protolog.ProtoLog
 import com.android.launcher3.icons.BubbleIconFactory
 import com.android.wm.shell.Flags
 import com.android.wm.shell.R
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt
index ace2c13..935d129 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt
@@ -27,7 +27,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
-import com.android.internal.protolog.common.ProtoLog
+import com.android.internal.protolog.ProtoLog
 import com.android.wm.shell.R
 import com.android.wm.shell.bubbles.BubblePositioner
 import com.android.wm.shell.bubbles.DeviceConfig
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_open_in_browser.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_open_in_browser.xml
new file mode 100644
index 0000000..7d912a2
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_ic_handle_menu_open_in_browser.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT 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="24dp" android:height="24dp" android:viewportWidth="960" android:viewportHeight="960" android:tint="?attr/colorControlNormal">
+    <path android:fillColor="@android:color/black" android:pathData="M160,880Q127,880 103.5,856.5Q80,833 80,800L80,440Q80,407 103.5,383.5Q127,360 160,360L240,360L240,160Q240,127 263.5,103.5Q287,80 320,80L800,80Q833,80 856.5,103.5Q880,127 880,160L880,520Q880,553 856.5,576.5Q833,600 800,600L720,600L720,800Q720,833 696.5,856.5Q673,880 640,880L160,880ZM160,800L640,800Q640,800 640,800Q640,800 640,800L640,520L160,520L160,800Q160,800 160,800Q160,800 160,800ZM720,520L800,520Q800,520 800,520Q800,520 800,520L800,240L320,240L320,360L640,360Q673,360 696.5,383.5Q720,407 720,440L720,520Z"/>
+</vector>
diff --git a/libs/WindowManager/Shell/res/layout/bubble_bar_expanded_view.xml b/libs/WindowManager/Shell/res/layout/bubble_bar_expanded_view.xml
index 34f03c2..501bedd 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_bar_expanded_view.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_bar_expanded_view.xml
@@ -19,7 +19,7 @@
     android:layout_height="wrap_content"
     android:layout_width="wrap_content"
     android:orientation="vertical"
-    android:id="@+id/bubble_bar_expanded_view">
+    android:id="@+id/bubble_expanded_view">
 
     <com.android.wm.shell.bubbles.bar.BubbleBarHandleView
         android:id="@+id/bubble_bar_handle_view"
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
index d5724cc..419d5c0 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
@@ -135,5 +135,24 @@
             android:drawableTint="?androidprv:attr/materialColorOnSurface"
             style="@style/DesktopModeHandleMenuActionButton"/>
     </LinearLayout>
+
+    <LinearLayout
+        android:id="@+id/open_in_browser_pill"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/desktop_mode_handle_menu_open_in_browser_pill_height"
+        android:layout_marginTop="@dimen/desktop_mode_handle_menu_pill_spacing_margin"
+        android:layout_marginStart="1dp"
+        android:orientation="vertical"
+        android:elevation="1dp"
+        android:background="@drawable/desktop_mode_decor_handle_menu_background">
+
+        <Button
+            android:id="@+id/open_in_browser_button"
+            android:contentDescription="@string/open_in_browser_text"
+            android:text="@string/open_in_browser_text"
+            android:drawableStart="@drawable/desktop_mode_ic_handle_menu_open_in_browser"
+            android:drawableTint="?androidprv:attr/materialColorOnSurface"
+            style="@style/DesktopModeHandleMenuActionButton"/>
+    </LinearLayout>
 </LinearLayout>
 
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml
index 7d5f9cd..5fe3f2a 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml
@@ -14,88 +14,100 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:id="@+id/maximize_menu"
-    style="?android:attr/buttonBarStyle"
     android:layout_width="@dimen/desktop_mode_maximize_menu_width"
     android:layout_height="@dimen/desktop_mode_maximize_menu_height"
-    android:orientation="horizontal"
-    android:gravity="center"
-    android:padding="16dp"
     android:background="@drawable/desktop_mode_maximize_menu_background"
     android:elevation="1dp">
 
     <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical">
+        android:id="@+id/container"
+        android:layout_width="@dimen/desktop_mode_maximize_menu_width"
+        android:layout_height="@dimen/desktop_mode_maximize_menu_height"
+        android:orientation="horizontal"
+        android:padding="16dp"
+        android:gravity="center">
 
-        <Button
-            android:layout_width="94dp"
-            android:layout_height="60dp"
-            android:id="@+id/maximize_menu_maximize_button"
-            style="?android:attr/buttonBarButtonStyle"
-            android:stateListAnimator="@null"
-            android:layout_marginRight="8dp"
-            android:layout_marginBottom="4dp"
-            android:alpha="0"/>
-
-        <TextView
-            android:id="@+id/maximize_menu_maximize_window_text"
-            android:layout_width="94dp"
-            android:layout_height="18dp"
-            android:textSize="11sp"
-            android:layout_marginBottom="76dp"
-            android:gravity="center"
-            android:fontFamily="google-sans-text"
-            android:text="@string/desktop_mode_maximize_menu_maximize_text"
-            android:textColor="?androidprv:attr/materialColorOnSurface"
-            android:alpha="0"/>
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical">
         <LinearLayout
-            android:id="@+id/maximize_menu_snap_menu_layout"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            android:padding="4dp"
-            android:background="@drawable/desktop_mode_maximize_menu_layout_background"
-            android:layout_marginBottom="4dp"
-            android:alpha="0">
-            <Button
-                android:id="@+id/maximize_menu_snap_left_button"
-                style="?android:attr/buttonBarButtonStyle"
-                android:layout_width="41dp"
-                android:layout_height="@dimen/desktop_mode_maximize_menu_button_height"
-                android:layout_marginRight="4dp"
-                android:background="@drawable/desktop_mode_maximize_menu_button_background"
-                android:stateListAnimator="@null"/>
+            android:orientation="vertical">
 
             <Button
-                android:id="@+id/maximize_menu_snap_right_button"
+                android:layout_width="94dp"
+                android:layout_height="60dp"
+                android:id="@+id/maximize_menu_maximize_button"
                 style="?android:attr/buttonBarButtonStyle"
-                android:layout_width="41dp"
-                android:layout_height="@dimen/desktop_mode_maximize_menu_button_height"
-                android:background="@drawable/desktop_mode_maximize_menu_button_background"
-                android:stateListAnimator="@null"/>
+                android:stateListAnimator="@null"
+                android:layout_marginRight="8dp"
+                android:layout_marginBottom="4dp"
+                android:alpha="0"/>
+
+            <TextView
+                android:id="@+id/maximize_menu_maximize_window_text"
+                android:layout_width="94dp"
+                android:layout_height="18dp"
+                android:textSize="11sp"
+                android:layout_marginBottom="76dp"
+                android:gravity="center"
+                android:fontFamily="google-sans-text"
+                android:text="@string/desktop_mode_maximize_menu_maximize_text"
+                android:textColor="?androidprv:attr/materialColorOnSurface"
+                android:alpha="0"/>
         </LinearLayout>
-        <TextView
-            android:id="@+id/maximize_menu_snap_window_text"
-            android:layout_width="94dp"
-            android:layout_height="18dp"
-            android:textSize="11sp"
-            android:layout_marginBottom="76dp"
-            android:layout_gravity="center"
-            android:gravity="center"
-            android:fontFamily="google-sans-text"
-            android:text="@string/desktop_mode_maximize_menu_snap_text"
-            android:textColor="?androidprv:attr/materialColorOnSurface"
-            android:alpha="0"/>
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+            <LinearLayout
+                android:id="@+id/maximize_menu_snap_menu_layout"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                android:padding="4dp"
+                android:background="@drawable/desktop_mode_maximize_menu_layout_background"
+                android:layout_marginBottom="4dp"
+                android:alpha="0">
+                <Button
+                    android:id="@+id/maximize_menu_snap_left_button"
+                    style="?android:attr/buttonBarButtonStyle"
+                    android:layout_width="41dp"
+                    android:layout_height="@dimen/desktop_mode_maximize_menu_button_height"
+                    android:layout_marginRight="4dp"
+                    android:background="@drawable/desktop_mode_maximize_menu_button_background"
+                    android:stateListAnimator="@null"/>
+
+                <Button
+                    android:id="@+id/maximize_menu_snap_right_button"
+                    style="?android:attr/buttonBarButtonStyle"
+                    android:layout_width="41dp"
+                    android:layout_height="@dimen/desktop_mode_maximize_menu_button_height"
+                    android:background="@drawable/desktop_mode_maximize_menu_button_background"
+                    android:stateListAnimator="@null"/>
+            </LinearLayout>
+            <TextView
+                android:id="@+id/maximize_menu_snap_window_text"
+                android:layout_width="94dp"
+                android:layout_height="18dp"
+                android:textSize="11sp"
+                android:layout_marginBottom="76dp"
+                android:layout_gravity="center"
+                android:gravity="center"
+                android:fontFamily="google-sans-text"
+                android:text="@string/desktop_mode_maximize_menu_snap_text"
+                android:textColor="?androidprv:attr/materialColorOnSurface"
+                android:alpha="0"/>
+        </LinearLayout>
     </LinearLayout>
-</LinearLayout>
+
+    <!-- Empty view intentionally placed in front of everything else and matching the menu size
+     used to monitor input events over the entire menu. -->
+    <View
+        android:id="@+id/maximize_menu_overlay"
+        android:layout_width="@dimen/desktop_mode_maximize_menu_width"
+        android:layout_height="@dimen/desktop_mode_maximize_menu_height"/>
+</FrameLayout>
 
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index 1c8f5e6..8b328e2 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Tik om hierdie app te herbegin vir ’n beter aansig"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Verander hierdie app se aspekverhouding in Instellings"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Verander aspekverhouding"</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index 81ab3ab..b005a01 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"አረፋ"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"ያቀናብሩ"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"አረፋ ተሰናብቷል።"</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"ለተሻለ ዕይታ ይህን መተግበሪያ እንደገና ለመጀመር መታ ያድርጉ"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"የዚህን መተግበሪያ ምጥጥነ ገፅታ በቅንብሮች ውስጥ ይለውጡ"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"የምጥጥነ ገፅታ ለውጥ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index 3974c39..8c283d3 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"فقاعة"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"إدارة"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"تم إغلاق الفقاعة."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"انقر لإعادة تشغيل هذا التطبيق للحصول على تجربة عرض أفضل."</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"يمكنك تغيير نسبة العرض إلى الارتفاع لهذا التطبيق من خلال \"الإعدادات\"."</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"تغيير نسبة العرض إلى الارتفاع"</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index a1ce1b3..ef92587 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"বাবল"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"পৰিচালনা কৰক"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"বাবল অগ্ৰাহ্য কৰা হৈছে"</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"উন্নত ভিউ পোৱাৰ বাবে এপ্‌টো ৰিষ্টাৰ্ট কৰিবলৈ টিপক"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"ছেটিঙলৈ গৈ এই এপ্‌টোৰ আকাৰৰ অনুপাত সলনি কৰক"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"আকাৰৰ অনুপাত সলনি কৰক"</string>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index 71dfe5a..04b2f1c 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Yaxşı görünüş üçün toxunaraq bu tətbiqi yenidən başladın"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Ayarlarda bu tətbiqin tərəflər nisbətini dəyişin"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Tərəflər nisbətini dəyişin"</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 f483609..47bc105 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Dodirnite da biste restartovali ovu aplikaciju radi boljeg prikaza"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Promenite razmeru ove aplikacije u Podešavanjima"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Promeni razmeru"</string>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index 532ecc6..6ad7553 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Усплывальнае апавяшчэнне"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Кіраваць"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Усплывальнае апавяшчэнне адхілена."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Націсніце, каб перазапусціць гэту праграму для зручнейшага прагляду"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Змяніць суадносіны бакоў для гэтай праграмы ў наладах"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Змяніць суадносіны бакоў"</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index 8f828ba..a9e0bce 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Балонче"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Управление"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Балончето е отхвърлено."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Докоснете, за да рестартирате това приложение с цел по-добър изглед"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Променете съотношението на това приложение в „Настройки“"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Промяна на съотношението"</string>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index e0a2ea8..29de100 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"বাবল"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"ম্যানেজ করুন"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"বাবল বাতিল করা হয়েছে।"</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"আরও ভাল ভিউয়ের জন্য এই অ্যাপ রিস্টার্ট করতে ট্যাপ করুন"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"সেটিংস থেকে এই অ্যাপের অ্যাস্পেক্ট রেশিও পরিবর্তন করুন"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"অ্যাস্পেক্ট রেশিও পরিবর্তন করুন"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 41c72c1..5f1da75 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Dodirnite da ponovo pokrenete ovu aplikaciju radi boljeg prikaza"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Promijenite format slike aplikacije u Postavkama"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Promijenite format slike"</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index 6792272..d70de79 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Toca per reiniciar aquesta aplicació i obtenir una millor visualització"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Canvia la relació d\'aspecte d\'aquesta aplicació a Configuració"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Canvia la relació d\'aspecte"</string>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index 150a6e6..ca00fec 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Klepnutím tuto aplikaci restartujete kvůli lepšímu zobrazení"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Změnit v Nastavení poměr stran této aplikace"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Změnit poměr stran"</string>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index 8878910..d50d2f0 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Tryk for at genstarte denne app, så visningen forbedres"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Skift denne apps billedformat i Indstillinger"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Skift billedformat"</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index 7b91559..7f44f83 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Tippen, um diese App neu zu starten und die Ansicht zu verbessern"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Seitenverhältnis der App in den Einstellungen ändern"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Seitenverhältnis ändern"</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index 14e5e2f..a3a5ccd 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Συννεφάκι"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Διαχείριση"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Το συννεφάκι παραβλέφθηκε."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Πατήστε για να επανεκκινήσετε αυτή την εφαρμογή για καλύτερη προβολή"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Αλλάξτε τον λόγο διαστάσεων αυτής της εφαρμογής στις Ρυθμίσεις"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Αλλαγή λόγου διαστάσεων"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index 7427b62..edc4f4e 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Tap to restart this app for a better view"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Change this app\'s aspect ratio in Settings"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Change aspect ratio"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index cb9ee4f..d7e23fd 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -84,6 +84,8 @@
     <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="bubble_shortcut_label" msgid="666269077944378311">"Bubbles"</string>
+    <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"Show Bubbles"</string>
     <string name="restart_button_description" msgid="4564728020654658478">"Tap to restart this app for a better view"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Change this app\'s aspect ratio in Settings"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Change aspect ratio"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index 7427b62..edc4f4e 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Tap to restart this app for a better view"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Change this app\'s aspect ratio in Settings"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Change aspect ratio"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index 7427b62..edc4f4e 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Tap to restart this app for a better view"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Change this app\'s aspect ratio in Settings"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Change aspect ratio"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
index 8498807..1da8c27 100644
--- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
@@ -84,6 +84,8 @@
     <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="bubble_shortcut_label" msgid="666269077944378311">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‏‏‏‏‎‎‎‏‎‎‎‎‎‎‏‏‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‏‎‎‎‏‏‏‏‎‎‎‏‏‏‎Bubbles‎‏‎‎‏‎"</string>
+    <string name="bubble_shortcut_long_label" msgid="6088437544312894043">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‏‏‎Show Bubbles‎‏‎‎‏‎"</string>
     <string name="restart_button_description" msgid="4564728020654658478">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‏‎‏‎‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‎‎‏‏‏‎‏‎‏‏‏‎‎Tap to restart this app for a better view‎‏‎‎‏‎"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‎‎‏‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‏‏‎‎‎‏‎‎‎‎‎‏‎‎‏‏‏‎‎‎‎Change this app\'s aspect ratio in Settings‎‏‎‎‏‎"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‎‎‎‏‎‏‎‏‏‏‎‏‎‎‏‎‎‏‎‎‏‎‎‏‎‎‏‏‎‎‏‎‎‎Change aspect ratio‎‏‎‎‏‎"</string>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index 406c1f3..8653e59 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Presiona para reiniciar esta app y tener una mejor vista"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Cambiar la relación de aspecto de esta app en Configuración"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Cambiar relación de aspecto"</string>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index 0583d79..8f59c9c 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Toca para reiniciar esta aplicación y obtener una mejor vista"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Cambiar la relación de aspecto de esta aplicación en Ajustes"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Cambiar relación de aspecto"</string>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index 70547f5..3d86eb4 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Puudutage, et see rakendus parema vaate jaoks taaskäivitada"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Muutke selle rakenduse kuvasuhet jaotises Seaded"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Muutke kuvasuhet"</string>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index 4be35ea..4e7bdd2 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Hobeto ikusteko, sakatu hau, eta aplikazioa berrabiarazi egingo da"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Aldatu aplikazioaren aspektu-erlazioa ezarpenetan"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Aldatu aspektu-erlazioa"</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index 32d5f5f..a4711d4 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -53,7 +53,7 @@
     <string name="accessibility_split_top" msgid="2789329702027147146">"تقسیم از بالا"</string>
     <string name="accessibility_split_bottom" msgid="8694551025220868191">"تقسیم از پایین"</string>
     <string name="one_handed_tutorial_title" msgid="4583241688067426350">"استفاده از حالت یک‌دستی"</string>
-    <string name="one_handed_tutorial_description" msgid="3486582858591353067">"برای خارج شدن، از پایین صفحه‌نمایش تند به‌طرف بالا بکشید یا در هر جایی از بالای برنامه که می‌خواهید ضربه بزنید"</string>
+    <string name="one_handed_tutorial_description" msgid="3486582858591353067">"برای خارج شدن، از پایین صفحه‌نمایش تند به‌طرف بالا بکشید یا در هر جایی از بالای برنامه که می‌خواهید تک‌ضرب بزنید"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"آغاز «حالت یک‌دستی»"</string>
     <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"خروج از «حالت یک‌دستی»"</string>
     <string name="bubbles_settings_button_description" msgid="1301286017420516912">"تنظیمات برای حبابک‌های <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -71,28 +71,32 @@
     <string name="bubble_dismiss_text" msgid="8816558050659478158">"رد کردن حبابک"</string>
     <string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"مکالمه در حباب نشان داده نشود"</string>
     <string name="bubbles_user_education_title" msgid="2112319053732691899">"گپ بااستفاده از حبابک‌ها"</string>
-    <string name="bubbles_user_education_description" msgid="4215862563054175407">"مکالمه‌های جدید به‌صورت نمادهای شناور یا حبابک‌ها نشان داده می‌شوند. برای باز کردن حبابک‌ها ضربه بزنید. برای جابه‌جایی، آن را بکشید."</string>
+    <string name="bubbles_user_education_description" msgid="4215862563054175407">"مکالمه‌های جدید به‌صورت نمادهای شناور یا حبابک‌ها نشان داده می‌شوند. برای باز کردن حبابک‌ها تک‌ضرب بزنید. برای جابه‌جایی، آن را بکشید."</string>
     <string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"کنترل حبابک‌ها در هرزمانی"</string>
-    <string name="bubbles_user_education_manage" msgid="3460756219946517198">"برای خاموش کردن حبابک‌ها از این برنامه، روی «مدیریت» ضربه بزنید"</string>
+    <string name="bubbles_user_education_manage" msgid="3460756219946517198">"برای خاموش کردن حبابک‌ها از این برنامه، روی «مدیریت» تک‌ضرب بزنید"</string>
     <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"متوجه‌ام"</string>
     <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"هیچ حبابک جدیدی وجود ندارد"</string>
     <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"حبابک‌های اخیر و حبابک‌های ردشده اینجا ظاهر خواهند شد"</string>
     <string name="bubble_bar_education_stack_title" msgid="2486903590422497245">"گپ زدن بااستفاده از حبابک"</string>
-    <string name="bubble_bar_education_stack_text" msgid="2446934610817409820">"مکالمه‌های جدید به‌صورت نماد در گوشه پایین صفحه‌نمایش نشان داده می‌شود. برای ازهم بازکردن آن‌ها ضربه بزنید یا برای بستن، آن‌ها را بکشید."</string>
+    <string name="bubble_bar_education_stack_text" msgid="2446934610817409820">"مکالمه‌های جدید به‌صورت نماد در گوشه پایین صفحه‌نمایش نشان داده می‌شود. برای ازهم بازکردن آن‌ها تک‌ضرب بزنید یا برای بستن، آن‌ها را بکشید."</string>
     <string name="bubble_bar_education_manage_title" msgid="6148404487810835924">"کنترل حبابک‌ها در هرزمانی"</string>
-    <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"برای مدیریت اینکه کدام برنامه‌ها و مکالمه‌ها حباب داشته باشند، ضربه بزنید"</string>
+    <string name="bubble_bar_education_manage_text" msgid="3199732148641842038">"برای مدیریت اینکه کدام برنامه‌ها و مکالمه‌ها حباب داشته باشند، تک‌ضرب بزنید"</string>
     <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="4564728020654658478">"برای داشتن نمایی بهتر، ضربه بزنید تا این برنامه بازراه‌اندازی شود"</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
+    <string name="restart_button_description" msgid="4564728020654658478">"برای داشتن نمایی بهتر، تک‌ضرب بزنید تا این برنامه بازراه‌اندازی شود"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"نسبت ابعادی این برنامه را در «تنظیمات» تغییر دهید"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"تغییر نسبت ابعادی"</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>
+    <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>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"از چندین برنامه به‌طور هم‌زمان استفاده کنید"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"برای حالت صفحهٔ دونیمه، در برنامه‌ای دیگر بکشید"</string>
-    <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"برای جابه‌جا کردن برنامه، بیرون از آن دوضربه بزنید"</string>
+    <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"برای جابه‌جا کردن برنامه، بیرون از آن دو تک‌ضرب بزنید"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"متوجه‌ام"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"برای اطلاعات بیشتر، گسترده کنید."</string>
     <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"برای نمایش بهتر بازراه‌اندازی شود؟"</string>
@@ -100,7 +104,7 @@
     <string name="letterbox_restart_cancel" msgid="1342209132692537805">"لغو کردن"</string>
     <string name="letterbox_restart_restart" msgid="8529976234412442973">"بازراه‌اندازی"</string>
     <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"دوباره نشان داده نشود"</string>
-    <string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"برای جابه‌جا کردن این برنامه\nدوضربه بزنید"</string>
+    <string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"برای جابه‌جا کردن این برنامه\nدو تک‌ضرب بزنید"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"بزرگ کردن"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"کوچک کردن"</string>
     <string name="close_button_text" msgid="2913281996024033299">"بستن"</string>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index 6f03545..577d625 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Napauta, niin sovellus käynnistyy uudelleen paremmin näytölle sopivana"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Muuta tämän sovelluksen kuvasuhdetta Asetuksissa"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Vaihda kuvasuhdetta"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index 3492f13..7feb772 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -31,11 +31,11 @@
     <string name="accessibility_action_pip_resize" msgid="4623966104749543182">"Redimensionner"</string>
     <string name="accessibility_action_pip_stash" msgid="4060775037619702641">"Ajouter à la réserve"</string>
     <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Retirer de la réserve"</string>
-    <string name="dock_forced_resizable" msgid="7429086980048964687">"L\'application peut ne pas fonctionner avec l\'écran partagé"</string>
-    <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"L\'application ne prend pas en charge l\'écran partagé"</string>
-    <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Cette application ne peut être ouverte que dans une seule fenêtre."</string>
-    <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="dock_forced_resizable" msgid="7429086980048964687">"L\'appli peut ne pas fonctionner avec l\'écran partagé"</string>
+    <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"L\'appli ne prend pas en charge l\'écran partagé"</string>
+    <string name="dock_multi_instances_not_supported_text" msgid="5011042177901502928">"Cette appli ne peut être ouverte que dans une seule fenêtre."</string>
+    <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Il est possible que l\'appli ne fonctionne pas sur un écran secondaire."</string>
+    <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"L\'appli ne peut pas être lancée sur des écrans secondaires."</string>
     <string name="accessibility_divider" msgid="6407584574218956849">"Séparateur d\'écran partagé"</string>
     <string name="divider_title" msgid="1963391955593749442">"Séparateur d\'écran partagé"</string>
     <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"Plein écran à la gauche"</string>
@@ -56,7 +56,7 @@
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Pour quitter, balayez l\'écran du bas vers le haut, ou touchez n\'importe où sur l\'écran en haut de l\'appli"</string>
     <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Démarrer le mode Une main"</string>
     <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Quitter le mode Une main"</string>
-    <string name="bubbles_settings_button_description" msgid="1301286017420516912">"Paramètres pour les bulles de l\'application <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="bubbles_settings_button_description" msgid="1301286017420516912">"Paramètres pour les bulles de l\'appli <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"Menu déroulant"</string>
     <string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"Replacer sur la pile"</string>
     <string name="bubble_content_description_single" msgid="8495748092720065813">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
@@ -73,7 +73,7 @@
     <string name="bubbles_user_education_title" msgid="2112319053732691899">"Clavarder en utilisant des bulles"</string>
     <string name="bubbles_user_education_description" msgid="4215862563054175407">"Les nouvelles conversations s\'affichent sous forme d\'icônes flottantes (de bulles). Touchez une bulle pour l\'ouvrir. Faites-la glisser pour la déplacer."</string>
     <string name="bubbles_user_education_manage_title" msgid="7042699946735628035">"Paramètres des bulles"</string>
-    <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Toucher Gérer pour désactiver les bulles de cette application"</string>
+    <string name="bubbles_user_education_manage" msgid="3460756219946517198">"Toucher Gérer pour désactiver les bulles de cette appli"</string>
     <string name="bubbles_user_education_got_it" msgid="3382046149225428296">"OK"</string>
     <string name="bubble_overflow_empty_title" msgid="2397251267073294968">"Aucune bulle récente"</string>
     <string name="bubble_overflow_empty_subtitle" msgid="2627417924958633713">"Les bulles récentes et les bulles ignorées s\'afficheront ici"</string>
@@ -84,29 +84,33 @@
     <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="4564728020654658478">"Touchez pour redémarrer cette application afin d\'obtenir un meilleur affichage"</string>
-    <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Changer les proportions de cette application dans les paramètres"</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
+    <string name="restart_button_description" msgid="4564728020654658478">"Touchez pour redémarrer cette appli afin d\'obtenir un meilleur affichage"</string>
+    <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Changer les proportions de cette appli dans les paramètres"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Modifier les proportions"</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>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Voir et en faire plus"</string>
-    <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Faites glisser une autre application pour utiliser l\'écran partagé"</string>
-    <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Touchez deux fois à côté d\'une application pour la repositionner"</string>
+    <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Faites glisser une autre appli pour utiliser l\'écran partagé"</string>
+    <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Touchez deux fois à côté d\'une appli pour la repositionner"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
     <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Développer pour en savoir plus."</string>
     <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Redémarrer pour un meilleur affichage?"</string>
-    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Vous pouvez redémarrer l\'application pour qu\'elle s\'affiche mieux sur votre écran, mais il se peut que vous perdiez votre progression ou toute modification non enregistrée"</string>
+    <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Vous pouvez redémarrer l\'appli pour qu\'elle s\'affiche mieux sur votre écran, mais il se peut que vous perdiez votre progression ou toute modification non enregistrée"</string>
     <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Annuler"</string>
     <string name="letterbox_restart_restart" msgid="8529976234412442973">"Redémarrer"</string>
     <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne plus afficher"</string>
-    <string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Toucher deux fois pour\ndéplacer cette application"</string>
+    <string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"Toucher deux fois pour\ndéplacer cette appli"</string>
     <string name="maximize_button_text" msgid="1650859196290301963">"Agrandir"</string>
     <string name="minimize_button_text" msgid="271592547935841753">"Réduire"</string>
     <string name="close_button_text" msgid="2913281996024033299">"Fermer"</string>
     <string name="back_button_text" msgid="1469718707134137085">"Retour"</string>
     <string name="handle_text" msgid="1766582106752184456">"Identifiant"</string>
-    <string name="app_icon_text" msgid="2823268023931811747">"Icône de l\'application"</string>
+    <string name="app_icon_text" msgid="2823268023931811747">"Icône de l\'appli"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Plein écran"</string>
     <string name="desktop_text" msgid="1077633567027630454">"Mode Bureau"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Écran divisé"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index 4002e4d..4d14d0b 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Appuyez pour redémarrer cette appli et obtenir une meilleure vue."</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Modifiez le format de cette appli dans les Paramètres."</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Modifier le format"</string>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index c371f7f..e5b67c2 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Toca o botón para reiniciar esta aplicación e gozar dunha mellor visualización"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Cambia a proporción desta aplicación en Configuración"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Cambiar a proporción"</string>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index 7e3d7a3..e2a52dc 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"બબલ"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"મેનેજ કરો"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"બબલ છોડી દેવાયો."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"વધુ સારા વ્યૂ માટે, આ ઍપને ફરી શરૂ કરવા ટૅપ કરો"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"સેટિંગમાં આ ઍપનો સાપેક્ષ ગુણોત્તર બદલો"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"સાપેક્ષ ગુણોત્તર બદલો"</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index cd0f4e3..f75e0e0 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"मैनेज करें"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल खारिज किया गया."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"बेहतर व्यू पाने के लिए, टैप करके ऐप्लिकेशन को रीस्टार्ट करें"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"सेटिंग में जाकर इस ऐप्लिकेशन का आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) बदलें"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) बदलें"</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index 27d4cfc..ed80c50 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Dodirnite da biste ponovo pokrenuli tu aplikaciju kako biste bolje vidjeli"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Promijeni omjer slike ove aplikacije u postavkama"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Promijeni omjer slike"</string>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index a8cc5c1..32a3106 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"A jobb nézet érdekében koppintson az alkalmazás újraindításához."</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Az app méretarányát a Beállításokban módosíthatja"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Méretarány módosítása"</string>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 7f37277..65ca704 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Պղպջակ"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Կառավարել"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Ամպիկը փակվեց։"</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Հպեք՝ հավելվածը վերագործարկելու և ավելի հարմար տեսք ընտրելու համար"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Փոխել հավելվածի կողմերի հարաբերակցությունը Կարգավորումներում"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Փոխել չափերի հարաբերակցությունը"</string>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index 3cf55fa..975dd72 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Ketuk untuk memulai ulang aplikasi ini agar mendapatkan tampilan yang lebih baik"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Ubah rasio aspek aplikasi ini di Setelan"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Ubah rasio aspek"</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index 6aa56f9..11c4718 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Ýttu til að endurræsa forritið og fá betri sýn"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Breyta myndhlutfalli þessa forrits í stillingunum"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Breyta myndhlutfalli"</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index 3c1d5e4..168c8cc 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Tocca per riavviare l\'app e migliorare la visualizzazione"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Cambia le proporzioni dell\'app nelle Impostazioni"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Cambia proporzioni"</string>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index a0c3b3a..fd4cd1a 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"בועה"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"ניהול"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"הבועה נסגרה."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"כדי לראות טוב יותר יש להקיש ולהפעיל את האפליקציה הזו מחדש"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"אפשר לשנות את יחס הגובה-רוחב של האפליקציה הזו ב\'הגדרות\'"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"שינוי יחס גובה-רוחב"</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index fb726c1..64ddec9 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"バブル"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ふきだしが非表示になっています。"</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"タップしてこのアプリを再起動すると、表示が適切になります"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"このアプリのアスペクト比を [設定] で変更します"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"アスペクト比を変更"</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index e9f620a..cab8807 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"ბუშტი"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"მართვა"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ბუშტი დაიხურა."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"შეხებით გადატვირთეთ ეს აპი უკეთესი ხედის მისაღებად"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"შეცვალეთ ამ აპის თანაფარდობა პარამეტრებიდან"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"თანაფარდობის შეცვლა"</string>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index 34e4103..4ff5b85 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Көпіршік"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Басқару"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Қалқыма хабар жабылды."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Көріністі жақсарту үшін осы қолданбаны түртіп, қайта ашыңыз."</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Осы қолданбаның арақатынасын параметрлерден өзгертуге болады."</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Арақатынасты өзгерту"</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index 362bbad..ba7a324 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"ពពុះ"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"គ្រប់គ្រង"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"បានច្រានចោល​សារលេចឡើង។"</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"ចុចដើម្បី​ចាប់ផ្ដើម​កម្មវិធី​នេះឡើងវិញសម្រាប់ទិដ្ឋភាពកាន់តែប្រសើរ"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"ផ្លាស់ប្ដូរសមាមាត្រ​របស់កម្មវិធីនេះនៅក្នុងការកំណត់"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"ប្ដូរ​​សមាមាត្រ"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index 77cc4a4..423e8d5 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"ಬಬಲ್"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"ನಿರ್ವಹಿಸಿ"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ಬಬಲ್ ವಜಾಗೊಳಿಸಲಾಗಿದೆ."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"ಉತ್ತಮ ವೀಕ್ಷಣೆಗಾಗಿ ಈ ಆ್ಯಪ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಈ ಆ್ಯಪ್‌ನ ದೃಶ್ಯಾನುಪಾತವನ್ನು ಬದಲಾಯಿಸಿ"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"ದೃಶ್ಯಾನುಪಾತವನ್ನು ಬದಲಾಯಿಸಿ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index caa114f..0d1c621 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"버블"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"관리"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"대화창을 닫았습니다."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"탭하면 앱을 다시 시작하여 보기를 개선합니다."</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"설정에서 앱의 가로세로 비율을 변경합니다."</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"가로세로 비율 변경"</string>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index 302c007..f17e9ca 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Көбүк"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Башкаруу"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Калкып чыкма билдирме жабылды."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Жакшыраак көрүү үчүн бул колдонмону өчүрүп күйгүзүңүз. Ал үчүн таптап коюңуз"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Бул колдонмонун тараптарынын катнашын параметрлерден өзгөртүү"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Тараптардын катнашын өзгөртүү"</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index a351963..195e4d5 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"ແຕະເພື່ອຣີສະຕາດແອັບນີ້ເພື່ອມຸມມອງທີ່ດີຂຶ້ນ"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"ປ່ຽນອັດຕາສ່ວນຂອງແອັບນີ້ໃນການຕັ້ງຄ່າ"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"ປ່ຽນອັດຕາສ່ວນ"</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index e4dd739..63ad580 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Palieskite, kad iš naujo paleistumėte šią programą ir matytumėte aiškiau"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Pakeiskite šios programos kraštinių santykį"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Keisti kraštinių santykį"</string>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index 99aebf6..268d893 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Pieskarieties, lai restartētu šo lietotni un uzlabotu attēlojumu."</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Iestatījumos mainiet šīs lietotnes malu attiecību."</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Mainīt malu attiecību"</string>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index c152c60..0a0027f 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Балонче"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Управувајте"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Балончето е отфрлено."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Допрете за да ја рестартирате апликацијава за подобар приказ"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Промени го соодносот на апликацијава во „Поставки“"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Променување на соодносот"</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index 90275cd..07809e1 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"ബബിൾ"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"മാനേജ് ചെയ്യുക"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ബബിൾ ഡിസ്മിസ് ചെയ്തു."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"മികച്ച കാഴ്‌ചയ്‌ക്കായി ഈ ആപ്പ് റീസ്‌റ്റാർട്ട് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"ഈ ആപ്പിന്റെ വീക്ഷണ അനുപാതം, ക്രമീകരണത്തിൽ മാറ്റുക"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"വീക്ഷണ അനുപാതം മാറ്റുക"</string>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index 5e43506..99bd2df 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Бөмбөлөг"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Удирдах"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Бөмбөлгийг үл хэрэгссэн."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Харагдах байдлыг сайжруулахын тулд энэ аппыг товшиж, дахин эхлүүлнэ үү"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Энэ аппын харьцааг Тохиргоонд өөрчилнө үү"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Харьцааг өөрчлөх"</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index 5874bff..ac57e0a5 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"व्यवस्थापित करा"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल डिसमिस केला."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"अधिक चांगल्या दृश्यासाठी हे अ‍ॅप रीस्टार्ट करण्याकरिता टॅप करा"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"सेटिंग्ज मध्ये या ॲपचा आस्पेक्ट रेशो बदला"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"आस्पेक्ट रेशो बदला"</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index 4de8a7b..6bc2fbb 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Ketik untuk memulakan semula apl ini untuk mendapatkan paparan yang lebih baik"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Tukar nisbah bidang apl ini dalam Tetapan"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Tukar nisbah bidang"</string>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 5b9e9cb..12c19ed 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"ပူဖောင်းဖောက်သံ"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"စီမံရန်"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ပူဖောင်းကွက် ဖယ်လိုက်သည်။"</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"ပိုကောင်းသောမြင်ကွင်းအတွက် ဤအက်ပ်ပြန်စရန် တို့ပါ"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"ဆက်တင်များတွင် ဤအက်ပ်၏အချိုးအစားကို ပြောင်းရန်"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"အချိုးစား ပြောင်းရန်"</string>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index 6005be4..27b7901 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Trykk for å starte denne appen på nytt og få en bedre visning"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Endre høyde/bredde-forholdet for denne appen i Innstillinger"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Endre høyde/bredde-forholdet"</string>
@@ -113,7 +117,7 @@
     <string name="more_button_text" msgid="3655388105592893530">"Mer"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Svevende"</string>
     <string name="select_text" msgid="5139083974039906583">"Velg"</string>
-    <string name="screenshot_text" msgid="1477704010087786671">"Skjermdump"</string>
+    <string name="screenshot_text" msgid="1477704010087786671">"Skjermbilde"</string>
     <string name="close_text" msgid="4986518933445178928">"Lukk"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Lukk menyen"</string>
     <string name="expand_menu_text" msgid="3847736164494181168">"Åpne menyen"</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index a5bd2ab..25d0337 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"बबल"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"व्यवस्थापन गर्नुहोस्"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"बबल हटाइयो।"</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"अझ राम्रो भ्यू प्राप्त गर्नका लागि यो एप रिस्टार्ट गर्न ट्याप गर्नुहोस्"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"सेटिङमा गई यो एपको एस्पेक्ट रेसियो परिवर्तन गर्नुहोस्"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"एस्पेक्ट रेसियो परिवर्तन गर्नुहोस्"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 0cd27c5..4ad343c 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Tik om deze app opnieuw op te starten voor een betere weergave"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Wijzig de beeldverhouding van deze app in Instellingen"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Beeldverhouding wijzigen"</string>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index bf75185..966d404 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"ବବଲ୍"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"ପରିଚାଳନା କରନ୍ତୁ"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ବବଲ୍ ଖାରଜ କରାଯାଇଛି।"</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"ଏକ ଆହୁରି ଭଲ ଭ୍ୟୁ ପାଇଁ ଏହି ଆପ ରିଷ୍ଟାର୍ଟ କରିବାକୁ ଟାପ କରନ୍ତୁ"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"ସେଟିଂସରେ ଏହି ଆପର ଚଉଡ଼ା ଓ ଉଚ୍ଚତାର ଅନୁପାତ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"ଚଉଡ଼ା ଓ ଉଚ୍ଚତାର ଅନୁପାତ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index 325c1e8..9feaf41 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"ਬੁਲਬੁਲਾ"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ਬਬਲ ਨੂੰ ਖਾਰਜ ਕੀਤਾ ਗਿਆ।"</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"ਬਿਹਤਰ ਦ੍ਰਿਸ਼ ਵਾਸਤੇ ਇਸ ਐਪ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਜਾ ਕੇ ਇਸ ਐਪ ਦੇ ਆਕਾਰ ਅਨੁਪਾਤ ਨੂੰ ਬਦਲੋ"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"ਆਕਾਰ ਅਨੁਪਾਤ ਬਦਲੋ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index a7648c8..1c7fbf8 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Kliknij w celu zrestartowania aplikacji, aby lepiej się wyświetlała."</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Zmień proporcje obrazu aplikacji w Ustawieniach"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Zmień proporcje obrazu"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index e47d151..5c2de2a 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Toque para reiniciar o app e atualizar a visualização"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Mude o tamanho da janela deste app nas Configurações"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Mudar a proporção"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index 1210fe8..6f76525 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Toque para reiniciar esta app e ficar com uma melhor visão"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Altere o formato desta app nas Definições"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Altere o formato"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index e47d151..5c2de2a 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Toque para reiniciar o app e atualizar a visualização"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Mude o tamanho da janela deste app nas Configurações"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Mudar a proporção"</string>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index ae871f3..6e85e78 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Balon"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestionează"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balonul a fost respins."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Atinge ca să repornești aplicația pentru o vizualizare mai bună"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Schimbă raportul de dimensiuni al aplicației din Setări"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Schimbă raportul de dimensiuni"</string>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index 971e146..1b41983 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Всплывающая подсказка"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Настроить"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Всплывающий чат закрыт."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Нажмите, чтобы перезапустить приложение и оптимизировать размер"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Изменить соотношение сторон приложения в настройках"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Изменить соотношение сторон"</string>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index ef1381c..6fd37e9 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"බුබුළු"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"කළමනා කරන්න"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"බුබුල ඉවත දමා ඇත."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"වඩා හොඳ දසුනක් සඳහා මෙම යෙදුම යළි ඇරඹීමට තට්ටු කරන්න"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"සැකසීම් තුළ මෙම යෙදුමේ දර්ශන අනුපාතය වෙනස් කරන්න"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"දර්ශන අනුපාතය වෙනස් කරන්න"</string>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index 55a0312..dabbf39 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Ak chcete zlepšiť zobrazenie, klepnutím túto aplikáciu reštartujte"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Zmeniť pomer strán tejto aplikácie v Nastaveniach"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Zmeniť pomer strán"</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index bb123dc..3ade338 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Če želite boljši prikaz, se dotaknite za vnovični zagon te aplikacije."</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Razmerje stranic te aplikacije spremenite v nastavitvah."</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Sprememba razmerja stranic"</string>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index c74a8cd..ee1aa00 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Trokit për ta rinisur këtë aplikacion për një pamje më të mirë"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Ndrysho raportin e pamjes së këtij aplikacioni te \"Cilësimet\""</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Ndrysho raportin e pamjes"</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index 0694a97..b2868ca 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Облачић"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Управљајте"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Облачић је одбачен."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Додирните да бисте рестартовали ову апликацију ради бољег приказа"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Промените размеру ове апликације у Подешавањима"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Промени размеру"</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index 8e0bcfe..66118ef 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Tryck för att starta om appen och få en bättre vy"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Ändra appens bildformat i inställningarna"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Ändra bildformat"</string>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index 41180ab..863b49b 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Gusa ili uzime kisha uwashe programu hii, ili upate mwonekano bora"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Badilisha uwiano wa programu hii katika Mipangilio"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Badilisha uwiano wa kipengele"</string>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index 01ac78d..74e0207 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"பபிள்"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"நிர்வகி"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"குமிழ் நிராகரிக்கப்பட்டது."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"இங்கு தட்டுவதன் மூலம் இந்த ஆப்ஸை மீண்டும் தொடங்கி, ஆப்ஸ் காட்டப்படும் விதத்தை இன்னும் சிறப்பாக்கலாம்"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"அமைப்புகளில் இந்த ஆப்ஸின் தோற்ற விகிதத்தை மாற்றும்"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"தோற்ற விகிதத்தை மாற்றும்"</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index 6224e72..3571156 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"బబుల్"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"మేనేజ్ చేయండి"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"బబుల్ విస్మరించబడింది."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"మెరుగైన వీక్షణ కోసం ఈ యాప్‌ను రీస్టార్ట్ చేయడానికి ట్యాప్ చేయండి"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"సెట్టింగ్‌లలో ఈ యాప్ ఆకార నిష్పత్తిని మార్చండి"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"ఆకార నిష్పత్తిని మార్చండి"</string>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index fe0b74c..4769416 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"บับเบิล"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"จัดการ"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ปิดบับเบิลแล้ว"</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"แตะเพื่อรีสตาร์ทแอปนี้และรับมุมมองที่ดียิ่งขึ้น"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"เปลี่ยนสัดส่วนภาพของแอปนี้ในการตั้งค่า"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"เปลี่ยนอัตราส่วนกว้างยาว"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index 786e99c..be18d88 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"I-tap para i-restart ang app na ito para sa mas magandang view"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Baguhin ang aspect ratio ng app na ito sa Mga Setting"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Baguhin ang aspect ratio"</string>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index e953f58..4c8c536 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Bu uygulamayı yeniden başlatarak daha iyi bir görünüm elde etmek için dokunun"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Bu uygulamanın en boy oranını Ayarlar\'dan değiştirin"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"En boy oranını değiştir"</string>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index fbdf42e..7cc1a04 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"Спливаюче сповіщення"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"Налаштувати"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Спливаюче сповіщення закрито."</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Натисніть, щоб перезапустити цей додаток для зручнішого перегляду"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Змінити формат для цього додатка в налаштуваннях"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Змінити формат"</string>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index 5562fa7..8b9f299 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"بلبلہ"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"نظم کریں"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"بلبلہ برخاست کر دیا گیا۔"</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"بہتر منظر کے لیے اس ایپ کو ری اسٹارٹ کرنے کی خاطر تھپتھپائیں"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"ترتیبات میں اس ایپ کی تناسبی شرح کو تبدیل کریں"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"تناسبی شرح کو تبدیل کریں"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 50e4232..55c6b32 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Yaxshiroq koʻrish maqsadida bu ilovani qayta ishga tushirish uchun bosing"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Sozlamalar orqali bu ilovaning tomonlar nisbatini oʻzgartiring"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Tomonlar nisbatini oʻzgartirish"</string>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index 6da8588..07a6b6f 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Nhấn nút khởi động lại ứng dụng này để xem dễ hơn"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Thay đổi tỷ lệ khung hình của ứng dụng này thông qua phần Cài đặt"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Thay đổi tỷ lệ khung hình"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index 4318caf..908095a 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"气泡"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"已关闭消息气泡。"</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"点按即可重启此应用,获得更好的视觉体验"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"在“设置”中更改此应用的宽高比"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"更改高宽比"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index 72cd39d..c8550b4 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"氣泡"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"對話氣泡已關閉。"</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"輕按並重新啟動此應用程式,以取得更佳的觀看體驗"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"前往「設定」變更此應用程式的長寬比"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"變更長寬比"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index c06d7b1..6704833 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -84,6 +84,10 @@
     <string name="notification_bubble_title" msgid="6082910224488253378">"泡泡"</string>
     <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string>
     <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"已關閉泡泡。"</string>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"輕觸此按鈕重新啟動這個應用程式,即可獲得更良好的觀看體驗"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"前往「設定」變更這個應用程式的顯示比例"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"變更顯示比例"</string>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index 755414e..96b4faec 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -84,6 +84,10 @@
     <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>
+    <!-- no translation found for bubble_shortcut_label (666269077944378311) -->
+    <skip />
+    <!-- no translation found for bubble_shortcut_long_label (6088437544312894043) -->
+    <skip />
     <string name="restart_button_description" msgid="4564728020654658478">"Thepha ukuze uqale kabusha le app ukuze ibonakale kangcono"</string>
     <string name="user_aspect_ratio_settings_button_hint" msgid="734835849600713016">"Shintsha ukubukeka kwesilinganiselo kwe-app kuMasethingi"</string>
     <string name="user_aspect_ratio_settings_button_description" msgid="4315566801697411684">"Shintsha ukubukeka kwesilinganiselo"</string>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 595d346..d143263 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -507,8 +507,11 @@
     <!-- The height of the handle menu's "More Actions" pill in desktop mode. -->
     <dimen name="desktop_mode_handle_menu_more_actions_pill_height">52dp</dimen>
 
+    <!-- The height of the handle menu's "Open in browser" pill in desktop mode. -->
+    <dimen name="desktop_mode_handle_menu_open_in_browser_pill_height">52dp</dimen>
+
     <!-- The height of the handle menu in desktop mode. -->
-    <dimen name="desktop_mode_handle_menu_height">328dp</dimen>
+    <dimen name="desktop_mode_handle_menu_height">380dp</dimen>
 
     <!-- The top margin of the handle menu in desktop mode. -->
     <dimen name="desktop_mode_handle_menu_margin_top">4dp</dimen>
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index 4784674..4e7cfb6 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -280,6 +280,8 @@
     <string name="select_text">Select</string>
     <!-- Accessibility text for the handle menu screenshot button [CHAR LIMIT=NONE] -->
     <string name="screenshot_text">Screenshot</string>
+    <!-- Accessibility text for the handle menu open in browser button [CHAR LIMIT=NONE] -->
+    <string name="open_in_browser_text">Open in browser</string>
     <!-- Accessibility text for the handle menu close button [CHAR LIMIT=NONE] -->
     <string name="close_text">Close</string>
     <!-- Accessibility text for the handle menu close menu button [CHAR LIMIT=NONE] -->
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/DesktopModeStatus.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/DesktopModeStatus.java
deleted file mode 100644
index 4876f32..0000000
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/DesktopModeStatus.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.shared;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.os.SystemProperties;
-
-import com.android.internal.R;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.window.flags.Flags;
-
-/**
- * Constants for desktop mode feature
- */
-public class DesktopModeStatus {
-
-    /**
-     * Flag to indicate whether task resizing is veiled.
-     */
-    private static final boolean IS_VEILED_RESIZE_ENABLED = SystemProperties.getBoolean(
-            "persist.wm.debug.desktop_veiled_resizing", true);
-
-    /**
-     * Flag to indicate is moving task to another display is enabled.
-     */
-    public static final boolean IS_DISPLAY_CHANGE_ENABLED = SystemProperties.getBoolean(
-            "persist.wm.debug.desktop_change_display", false);
-
-    /**
-     * Flag to indicate whether to apply shadows to windows in desktop mode.
-     */
-    private static final boolean USE_WINDOW_SHADOWS = SystemProperties.getBoolean(
-            "persist.wm.debug.desktop_use_window_shadows", true);
-
-    /**
-     * Flag to indicate whether to apply shadows to the focused window in desktop mode.
-     *
-     * Note: this flag is only relevant if USE_WINDOW_SHADOWS is false.
-     */
-    private static final boolean USE_WINDOW_SHADOWS_FOCUSED_WINDOW = SystemProperties.getBoolean(
-            "persist.wm.debug.desktop_use_window_shadows_focused_window", false);
-
-    /**
-     * Flag to indicate whether to use rounded corners for windows in desktop mode.
-     */
-    private static final boolean USE_ROUNDED_CORNERS = SystemProperties.getBoolean(
-            "persist.wm.debug.desktop_use_rounded_corners", true);
-
-    /**
-     * Flag to indicate whether to restrict desktop mode to supported devices.
-     */
-    private static final boolean ENFORCE_DEVICE_RESTRICTIONS = SystemProperties.getBoolean(
-            "persist.wm.debug.desktop_mode_enforce_device_restrictions", true);
-
-    /** Whether the desktop density override is enabled. */
-    public static final boolean DESKTOP_DENSITY_OVERRIDE_ENABLED =
-            SystemProperties.getBoolean("persist.wm.debug.desktop_mode_density_enabled", false);
-
-    /** Override density for tasks when they're inside the desktop. */
-    public static final int DESKTOP_DENSITY_OVERRIDE =
-            SystemProperties.getInt("persist.wm.debug.desktop_mode_density", 284);
-
-    /** The minimum override density allowed for tasks inside the desktop. */
-    private static final int DESKTOP_DENSITY_MIN = 100;
-
-    /** The maximum override density allowed for tasks inside the desktop. */
-    private static final int DESKTOP_DENSITY_MAX = 1000;
-
-    /**
-     * Default value for {@code MAX_TASK_LIMIT}.
-     */
-    @VisibleForTesting
-    public static final int DEFAULT_MAX_TASK_LIMIT = 4;
-
-    // TODO(b/335131008): add a config-overlay field for the max number of tasks in Desktop Mode
-    /**
-     * Flag declaring the maximum number of Tasks to show in Desktop Mode at any one time.
-     *
-     * <p> The limit does NOT affect Picture-in-Picture, Bubbles, or System Modals (like a screen
-     * recording window, or Bluetooth pairing window).
-     */
-    private static final int MAX_TASK_LIMIT = SystemProperties.getInt(
-            "persist.wm.debug.desktop_max_task_limit", DEFAULT_MAX_TASK_LIMIT);
-
-    /**
-     * Return {@code true} if desktop windowing is enabled. Only to be used for testing. Callers
-     * should use {@link #canEnterDesktopMode(Context)} to query the state of desktop windowing.
-     */
-    @VisibleForTesting
-    public static boolean isEnabled() {
-        return Flags.enableDesktopWindowingMode();
-    }
-
-    /**
-     * Return {@code true} if veiled resizing is active. If false, fluid resizing is used.
-     */
-    public static boolean isVeiledResizeEnabled() {
-        return IS_VEILED_RESIZE_ENABLED;
-    }
-
-    /**
-     * Return whether to use window shadows.
-     *
-     * @param isFocusedWindow whether the window to apply shadows to is focused
-     */
-    public static boolean useWindowShadow(boolean isFocusedWindow) {
-        return USE_WINDOW_SHADOWS
-            || (USE_WINDOW_SHADOWS_FOCUSED_WINDOW && isFocusedWindow);
-    }
-
-    /**
-     * Return whether to use rounded corners for windows.
-     */
-    public static boolean useRoundedCorners() {
-        return USE_ROUNDED_CORNERS;
-    }
-
-    /**
-     * Return {@code true} if desktop mode should be restricted to supported devices.
-     */
-    @VisibleForTesting
-    public static boolean enforceDeviceRestrictions() {
-        return ENFORCE_DEVICE_RESTRICTIONS;
-    }
-
-    /**
-     * Return the maximum limit on the number of Tasks to show in Desktop Mode at any one time.
-     */
-    public static int getMaxTaskLimit() {
-        return MAX_TASK_LIMIT;
-    }
-
-    /**
-     * Return {@code true} if the current device supports desktop mode.
-     */
-    @VisibleForTesting
-    public static boolean isDesktopModeSupported(@NonNull Context context) {
-        return context.getResources().getBoolean(R.bool.config_isDesktopModeSupported);
-    }
-
-    /**
-     * Return {@code true} if desktop mode is enabled and can be entered on the current device.
-     */
-    public static boolean canEnterDesktopMode(@NonNull Context context) {
-        return (!enforceDeviceRestrictions() || isDesktopModeSupported(context)) && isEnabled();
-    }
-
-    /**
-     * Return {@code true} if the override desktop density is enabled and valid.
-     */
-    public static boolean useDesktopOverrideDensity() {
-        return isDesktopDensityOverrideEnabled() && isValidDesktopDensityOverrideSet();
-    }
-
-    /**
-     * Return {@code true} if the override desktop density is enabled.
-     */
-    private static boolean isDesktopDensityOverrideEnabled() {
-        return DESKTOP_DENSITY_OVERRIDE_ENABLED;
-    }
-
-    /**
-     * Return {@code true} if the override desktop density is set and within a valid range.
-     */
-    private static boolean isValidDesktopDensityOverrideSet() {
-        return DESKTOP_DENSITY_OVERRIDE >= DESKTOP_DENSITY_MIN
-                && DESKTOP_DENSITY_OVERRIDE <= DESKTOP_DENSITY_MAX;
-    }
-}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt
new file mode 100644
index 0000000..f0d80a0
--- /dev/null
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlags.kt
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.shared.desktopmode
+
+import android.content.Context
+import android.provider.Settings
+import android.util.Log
+import com.android.window.flags.Flags
+
+/*
+ * A shared class to check desktop mode flags state.
+ *
+ * The class computes whether a Desktop Windowing flag should be enabled by using the aconfig flag
+ * value and the developer option override state (if applicable).
+ **/
+enum class DesktopModeFlags(
+    // Function called to obtain aconfig flag value.
+    private val flagFunction: () -> Boolean,
+    // Whether the flag state should be affected by developer option.
+    private val shouldOverrideByDevOption: Boolean
+) {
+  // All desktop mode related flags will be added here
+  DESKTOP_WINDOWING_MODE(Flags::enableDesktopWindowingMode, true),
+  WALLPAPER_ACTIVITY(Flags::enableDesktopWindowingWallpaperActivity, true);
+
+  /**
+   * Determines state of flag based on the actual flag and desktop mode developer option overrides.
+   *
+   * Note, this method makes sure that a constant developer toggle overrides is read until reboot.
+   */
+  fun isEnabled(context: Context): Boolean =
+      if (!Flags.showDesktopWindowingDevOption() ||
+          !shouldOverrideByDevOption ||
+          context.contentResolver == null) {
+        flagFunction()
+      } else {
+        val shouldToggleBeEnabledByDefault = DesktopModeStatus.shouldDevOptionBeEnabledByDefault()
+        when (getToggleOverride(context)) {
+          ToggleOverride.OVERRIDE_UNSET -> flagFunction()
+          // When toggle override matches its default state, don't override flags. This helps users
+          // reset their feature overrides.
+          ToggleOverride.OVERRIDE_OFF ->
+              if (shouldToggleBeEnabledByDefault) false else flagFunction()
+          ToggleOverride.OVERRIDE_ON -> if (shouldToggleBeEnabledByDefault) flagFunction() else true
+        }
+      }
+
+  private fun getToggleOverride(context: Context): ToggleOverride {
+    val override =
+        cachedToggleOverride
+            ?: run {
+              val override = getToggleOverrideFromSystem(context)
+              // Cache toggle override the first time we encounter context. Override does not change
+              // with context, as context is just used to fetch System Property and Settings.Global
+              cachedToggleOverride = override
+              Log.d(TAG, "Toggle override initialized to: $override")
+              override
+            }
+
+    return override
+  }
+
+  private fun getToggleOverrideFromSystem(context: Context): ToggleOverride {
+    // A non-persistent System Property is used to store override to ensure it remains
+    // constant till reboot.
+    val overrideFromSystemProperties: ToggleOverride? =
+        System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, null).convertToToggleOverride()
+    return overrideFromSystemProperties
+        ?: run {
+          // Read Setting Global if System Property is not present (just after reboot)
+          // or not valid (user manually changed the value)
+          val overrideFromSettingsGlobal =
+              convertToToggleOverrideWithFallback(
+                  Settings.Global.getInt(
+                      context.contentResolver,
+                      Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES,
+                      ToggleOverride.OVERRIDE_UNSET.setting),
+                  ToggleOverride.OVERRIDE_UNSET)
+          // Initialize System Property
+          System.setProperty(
+              SYSTEM_PROPERTY_OVERRIDE_KEY, overrideFromSettingsGlobal.setting.toString())
+
+          overrideFromSettingsGlobal
+        }
+  }
+
+  /**
+   * Override state of desktop mode developer option toggle.
+   *
+   * @property setting The integer value that is associated with the developer option toggle
+   *   override
+   */
+  enum class ToggleOverride(val setting: Int) {
+    /** No override is set. */
+    OVERRIDE_UNSET(-1),
+    /** Override to off. */
+    OVERRIDE_OFF(0),
+    /** Override to on. */
+    OVERRIDE_ON(1)
+  }
+
+  private fun String?.convertToToggleOverride(): ToggleOverride? {
+    val intValue = this?.toIntOrNull() ?: return null
+    return settingToToggleOverrideMap[intValue]
+        ?: run {
+          Log.w(TAG, "Unknown toggleOverride int $intValue")
+          null
+        }
+  }
+
+  companion object {
+    private const val TAG = "DesktopModeFlags"
+
+    /**
+     * Key for non-persistent System Property which is used to store desktop windowing developer
+     * option overrides.
+     */
+    private const val SYSTEM_PROPERTY_OVERRIDE_KEY = "sys.wmshell.desktopmode.dev_toggle_override"
+
+    /**
+     * Local cache for toggle override, which is initialized once on its first access. It needs to
+     * be refreshed only on reboots as overridden state takes effect on reboots.
+     */
+    private var cachedToggleOverride: ToggleOverride? = null
+
+    private val settingToToggleOverrideMap = ToggleOverride.entries.associateBy { it.setting }
+
+    @JvmStatic
+    fun convertToToggleOverrideWithFallback(
+        overrideInt: Int,
+        fallbackOverride: ToggleOverride
+    ): ToggleOverride {
+      return settingToToggleOverrideMap[overrideInt]
+          ?: run {
+            Log.w(TAG, "Unknown toggleOverride int $overrideInt")
+            fallbackOverride
+          }
+    }
+  }
+}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java
new file mode 100644
index 0000000..fc4710f
--- /dev/null
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeStatus.java
@@ -0,0 +1,199 @@
+/*
+ * 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.shared.desktopmode;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.SystemProperties;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.window.flags.Flags;
+
+/**
+ * Constants for desktop mode feature
+ */
+// TODO(b/237575897): Move this file to the `com.android.wm.shell.shared.desktopmode` package
+public class DesktopModeStatus {
+
+    private static final String TAG = "DesktopModeStatus";
+
+    /**
+     * Flag to indicate whether task resizing is veiled.
+     */
+    private static final boolean IS_VEILED_RESIZE_ENABLED = SystemProperties.getBoolean(
+            "persist.wm.debug.desktop_veiled_resizing", true);
+
+    /**
+     * Flag to indicate is moving task to another display is enabled.
+     */
+    public static final boolean IS_DISPLAY_CHANGE_ENABLED = SystemProperties.getBoolean(
+            "persist.wm.debug.desktop_change_display", false);
+
+    /**
+     * Flag to indicate whether to apply shadows to windows in desktop mode.
+     */
+    private static final boolean USE_WINDOW_SHADOWS = SystemProperties.getBoolean(
+            "persist.wm.debug.desktop_use_window_shadows", true);
+
+    /**
+     * Flag to indicate whether to apply shadows to the focused window in desktop mode.
+     *
+     * Note: this flag is only relevant if USE_WINDOW_SHADOWS is false.
+     */
+    private static final boolean USE_WINDOW_SHADOWS_FOCUSED_WINDOW = SystemProperties.getBoolean(
+            "persist.wm.debug.desktop_use_window_shadows_focused_window", false);
+
+    /**
+     * Flag to indicate whether to use rounded corners for windows in desktop mode.
+     */
+    private static final boolean USE_ROUNDED_CORNERS = SystemProperties.getBoolean(
+            "persist.wm.debug.desktop_use_rounded_corners", true);
+
+    /**
+     * Flag to indicate whether to restrict desktop mode to supported devices.
+     */
+    private static final boolean ENFORCE_DEVICE_RESTRICTIONS = SystemProperties.getBoolean(
+            "persist.wm.debug.desktop_mode_enforce_device_restrictions", true);
+
+    /** Whether the desktop density override is enabled. */
+    public static final boolean DESKTOP_DENSITY_OVERRIDE_ENABLED =
+            SystemProperties.getBoolean("persist.wm.debug.desktop_mode_density_enabled", false);
+
+    /** Override density for tasks when they're inside the desktop. */
+    public static final int DESKTOP_DENSITY_OVERRIDE =
+            SystemProperties.getInt("persist.wm.debug.desktop_mode_density", 284);
+
+    /** The minimum override density allowed for tasks inside the desktop. */
+    private static final int DESKTOP_DENSITY_MIN = 100;
+
+    /** The maximum override density allowed for tasks inside the desktop. */
+    private static final int DESKTOP_DENSITY_MAX = 1000;
+
+    /**
+     * Default value for {@code MAX_TASK_LIMIT}.
+     */
+    @VisibleForTesting
+    public static final int DEFAULT_MAX_TASK_LIMIT = 4;
+
+    // TODO(b/335131008): add a config-overlay field for the max number of tasks in Desktop Mode
+    /**
+     * Flag declaring the maximum number of Tasks to show in Desktop Mode at any one time.
+     *
+     * <p> The limit does NOT affect Picture-in-Picture, Bubbles, or System Modals (like a screen
+     * recording window, or Bluetooth pairing window).
+     */
+    private static final int MAX_TASK_LIMIT = SystemProperties.getInt(
+            "persist.wm.debug.desktop_max_task_limit", DEFAULT_MAX_TASK_LIMIT);
+
+    /**
+     * Return {@code true} if veiled resizing is active. If false, fluid resizing is used.
+     */
+    public static boolean isVeiledResizeEnabled() {
+        return IS_VEILED_RESIZE_ENABLED;
+    }
+
+    /**
+     * Return whether to use window shadows.
+     *
+     * @param isFocusedWindow whether the window to apply shadows to is focused
+     */
+    public static boolean useWindowShadow(boolean isFocusedWindow) {
+        return USE_WINDOW_SHADOWS
+                || (USE_WINDOW_SHADOWS_FOCUSED_WINDOW && isFocusedWindow);
+    }
+
+    /**
+     * Return whether to use rounded corners for windows.
+     */
+    public static boolean useRoundedCorners() {
+        return USE_ROUNDED_CORNERS;
+    }
+
+    /**
+     * Return {@code true} if desktop mode should be restricted to supported devices.
+     */
+    @VisibleForTesting
+    public static boolean enforceDeviceRestrictions() {
+        return ENFORCE_DEVICE_RESTRICTIONS;
+    }
+
+    /**
+     * Return the maximum limit on the number of Tasks to show in Desktop Mode at any one time.
+     */
+    public static int getMaxTaskLimit() {
+        return MAX_TASK_LIMIT;
+    }
+
+    /**
+     * Return {@code true} if the current device supports desktop mode.
+     */
+    @VisibleForTesting
+    public static boolean isDesktopModeSupported(@NonNull Context context) {
+        return context.getResources().getBoolean(R.bool.config_isDesktopModeSupported);
+    }
+
+    /**
+     * Return {@code true} if desktop mode dev option should be shown on current device
+     */
+    public static boolean canShowDesktopModeDevOption(@NonNull Context context) {
+        return isDeviceEligibleForDesktopMode(context) && Flags.showDesktopWindowingDevOption();
+    }
+
+    /** Returns if desktop mode dev option should be enabled if there is no user override. */
+    public static boolean shouldDevOptionBeEnabledByDefault() {
+        return Flags.enableDesktopWindowingMode();
+    }
+
+    /**
+     * Return {@code true} if desktop mode is enabled and can be entered on the current device.
+     */
+    public static boolean canEnterDesktopMode(@NonNull Context context) {
+        if (!isDeviceEligibleForDesktopMode(context)) return false;
+
+        return DesktopModeFlags.DESKTOP_WINDOWING_MODE.isEnabled(context);
+    }
+
+    /**
+     * Return {@code true} if the override desktop density is enabled and valid.
+     */
+    public static boolean useDesktopOverrideDensity() {
+        return isDesktopDensityOverrideEnabled() && isValidDesktopDensityOverrideSet();
+    }
+
+    /**
+     * Return {@code true} if the override desktop density is enabled.
+     */
+    private static boolean isDesktopDensityOverrideEnabled() {
+        return DESKTOP_DENSITY_OVERRIDE_ENABLED;
+    }
+
+    /**
+     * Return {@code true} if the override desktop density is set and within a valid range.
+     */
+    private static boolean isValidDesktopDensityOverrideSet() {
+        return DESKTOP_DENSITY_OVERRIDE >= DESKTOP_DENSITY_MIN
+                && DESKTOP_DENSITY_OVERRIDE <= DESKTOP_DENSITY_MAX;
+    }
+
+    /**
+     * Return {@code true} if desktop mode is unrestricted and is supported in the device.
+     */
+    private static boolean isDeviceEligibleForDesktopMode(@NonNull Context context) {
+        return !enforceDeviceRestrictions() || isDesktopModeSupported(context);
+    }
+}
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/OWNERS b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/OWNERS
new file mode 100644
index 0000000..2fabd4a
--- /dev/null
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/OWNERS
@@ -0,0 +1 @@
+file:/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java
index ef9bf00..514307f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ProtoLogController.java
@@ -19,7 +19,7 @@
 import com.android.internal.protolog.LegacyProtoLogImpl;
 import com.android.internal.protolog.common.ILogger;
 import com.android.internal.protolog.common.IProtoLog;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.sysui.ShellCommandHandler;
 import com.android.wm.shell.sysui.ShellInit;
 
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 2e5448a..b9bf136 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/RootDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/RootDisplayAreaOrganizer.java
@@ -29,7 +29,7 @@
 
 import androidx.annotation.NonNull;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.sysui.ShellInit;
 
 import java.io.PrintWriter;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
index 5143d41..9f01316 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java
@@ -38,7 +38,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.sysui.ShellInit;
 
 import java.io.PrintWriter;
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 3ded7d2..f014e55 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -24,6 +24,9 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 
+import static com.android.wm.shell.compatui.impl.CompatUIEventsKt.CAMERA_CONTROL_STATE_UPDATE;
+import static com.android.wm.shell.compatui.impl.CompatUIEventsKt.SIZE_COMPAT_RESTART_BUTTON_APPEARED;
+import static com.android.wm.shell.compatui.impl.CompatUIEventsKt.SIZE_COMPAT_RESTART_BUTTON_CLICKED;
 import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG;
 import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
 
@@ -31,7 +34,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager.RunningTaskInfo;
-import android.app.CameraCompatTaskInfo.CameraCompatControlState;
 import android.app.TaskInfo;
 import android.app.WindowConfiguration;
 import android.content.LocusId;
@@ -52,11 +54,16 @@
 import android.window.TaskOrganizer;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.wm.shell.common.ScreenshotUtils;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.compatui.CompatUIController;
+import com.android.wm.shell.compatui.api.CompatUIHandler;
+import com.android.wm.shell.compatui.api.CompatUIInfo;
+import com.android.wm.shell.compatui.impl.CompatUIEvents.CameraControlStateUpdated;
+import com.android.wm.shell.compatui.impl.CompatUIEvents.SizeCompatRestartButtonAppeared;
+import com.android.wm.shell.compatui.impl.CompatUIEvents.SizeCompatRestartButtonClicked;
 import com.android.wm.shell.recents.RecentTasksController;
 import com.android.wm.shell.startingsurface.StartingWindowController;
 import com.android.wm.shell.sysui.ShellCommandHandler;
@@ -75,8 +82,7 @@
  * Unified task organizer for all components in the shell.
  * TODO(b/167582004): may consider consolidating this class and TaskOrganizer
  */
-public class ShellTaskOrganizer extends TaskOrganizer implements
-        CompatUIController.CompatUICallback {
+public class ShellTaskOrganizer extends TaskOrganizer {
     private static final String TAG = "ShellTaskOrganizer";
 
     // Intentionally using negative numbers here so the positive numbers can be used
@@ -124,6 +130,15 @@
     }
 
     /**
+     * Limited scope callback to notify when a task is removed from the system.  This signal is
+     * not synchronized with anything (or any transition), and should not be used in cases where
+     * that is necessary.
+     */
+    public interface TaskVanishedListener {
+        default void onTaskVanished(RunningTaskInfo taskInfo) {}
+    }
+
+    /**
      * Callbacks for events on a task with a locus id.
      */
     public interface LocusIdListener {
@@ -167,6 +182,9 @@
 
     private final ArraySet<FocusListener> mFocusListeners = new ArraySet<>();
 
+    // Listeners that should be notified when a task is removed
+    private final ArraySet<TaskVanishedListener> mTaskVanishedListeners = new ArraySet<>();
+
     private final Object mLock = new Object();
     private StartingWindowController mStartingWindow;
 
@@ -182,12 +200,11 @@
      * In charge of showing compat UI. Can be {@code null} if the device doesn't support size
      * compat or if this isn't the main {@link ShellTaskOrganizer}.
      *
-     * <p>NOTE: only the main {@link ShellTaskOrganizer} should have a {@link CompatUIController},
-     * and register itself as a {@link CompatUIController.CompatUICallback}. Subclasses should be
-     * initialized with a {@code null} {@link CompatUIController}.
+     * <p>NOTE: only the main {@link ShellTaskOrganizer} should have a {@link CompatUIHandler},
+     * Subclasses should be initialized with a {@code null} {@link CompatUIHandler}.
      */
     @Nullable
-    private final CompatUIController mCompatUI;
+    private final CompatUIHandler mCompatUI;
 
     @NonNull
     private final ShellCommandHandler mShellCommandHandler;
@@ -211,7 +228,7 @@
 
     public ShellTaskOrganizer(ShellInit shellInit,
             ShellCommandHandler shellCommandHandler,
-            @Nullable CompatUIController compatUI,
+            @Nullable CompatUIHandler compatUI,
             Optional<UnfoldAnimationController> unfoldAnimationController,
             Optional<RecentTasksController> recentTasks,
             ShellExecutor mainExecutor) {
@@ -223,7 +240,7 @@
     protected ShellTaskOrganizer(ShellInit shellInit,
             ShellCommandHandler shellCommandHandler,
             ITaskOrganizerController taskOrganizerController,
-            @Nullable CompatUIController compatUI,
+            @Nullable CompatUIHandler compatUI,
             Optional<UnfoldAnimationController> unfoldAnimationController,
             Optional<RecentTasksController> recentTasks,
             ShellExecutor mainExecutor) {
@@ -240,7 +257,21 @@
     private void onInit() {
         mShellCommandHandler.addDumpCallback(this::dump, this);
         if (mCompatUI != null) {
-            mCompatUI.setCompatUICallback(this);
+            mCompatUI.setCallback(compatUIEvent -> {
+                switch(compatUIEvent.getEventId()) {
+                    case SIZE_COMPAT_RESTART_BUTTON_APPEARED:
+                        onSizeCompatRestartButtonAppeared(compatUIEvent.asType());
+                        break;
+                    case SIZE_COMPAT_RESTART_BUTTON_CLICKED:
+                        onSizeCompatRestartButtonClicked(compatUIEvent.asType());
+                        break;
+                    case CAMERA_CONTROL_STATE_UPDATE:
+                        onCameraControlStateUpdated(compatUIEvent.asType());
+                        break;
+                    default:
+
+                }
+            });
         }
         registerOrganizer();
     }
@@ -409,7 +440,7 @@
     }
 
     /**
-     * Removes listener.
+     * Removes a locus id listener.
      */
     public void removeLocusIdListener(LocusIdListener listener) {
         synchronized (mLock) {
@@ -430,7 +461,7 @@
     }
 
     /**
-     * Removes listener.
+     * Removes a focus listener.
      */
     public void removeFocusListener(FocusListener listener) {
         synchronized (mLock) {
@@ -439,6 +470,24 @@
     }
 
     /**
+     * Adds a listener to be notified when a task vanishes.
+     */
+    public void addTaskVanishedListener(TaskVanishedListener listener) {
+        synchronized (mLock) {
+            mTaskVanishedListeners.add(listener);
+        }
+    }
+
+    /**
+     * Removes a task-vanished listener.
+     */
+    public void removeTaskVanishedListener(TaskVanishedListener listener) {
+        synchronized (mLock) {
+            mTaskVanishedListeners.remove(listener);
+        }
+    }
+
+    /**
      * Returns a surface which can be used to attach overlays to the home root task
      */
     @NonNull
@@ -614,6 +663,9 @@
                 t.apply();
                 ProtoLog.v(WM_SHELL_TASK_ORG, "Removing overlay surface");
             }
+            for (TaskVanishedListener l : mTaskVanishedListeners) {
+                l.onTaskVanished(taskInfo);
+            }
 
             if (!ENABLE_SHELL_TRANSITIONS && (appearedInfo.getLeash() != null)) {
                 // Preemptively clean up the leash only if shell transitions are not enabled
@@ -647,6 +699,22 @@
         }
     }
 
+    /**
+     * Shows/hides the given task surface.  Not for general use as changing the task visibility may
+     * conflict with other Transitions.  This is currently ONLY used to temporarily hide a task
+     * while a drag is in session.
+     */
+    public void setTaskSurfaceVisibility(int taskId, boolean visible) {
+        synchronized (mLock) {
+            final TaskAppearedInfo info = mTasks.get(taskId);
+            if (info != null) {
+                SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+                t.setVisibility(info.getLeash(), visible);
+                t.apply();
+            }
+        }
+    }
+
     private boolean updateTaskListenerIfNeeded(RunningTaskInfo taskInfo, SurfaceControl leash,
             TaskListener oldListener, TaskListener newListener) {
         if (oldListener == newListener) return false;
@@ -694,45 +762,6 @@
         }
     }
 
-    @Override
-    public void onSizeCompatRestartButtonAppeared(int taskId) {
-        final TaskAppearedInfo info;
-        synchronized (mLock) {
-            info = mTasks.get(taskId);
-        }
-        if (info == null) {
-            return;
-        }
-        logSizeCompatRestartButtonEventReported(info,
-                FrameworkStatsLog.SIZE_COMPAT_RESTART_BUTTON_EVENT_REPORTED__EVENT__APPEARED);
-    }
-
-    @Override
-    public void onSizeCompatRestartButtonClicked(int taskId) {
-        final TaskAppearedInfo info;
-        synchronized (mLock) {
-            info = mTasks.get(taskId);
-        }
-        if (info == null) {
-            return;
-        }
-        logSizeCompatRestartButtonEventReported(info,
-                FrameworkStatsLog.SIZE_COMPAT_RESTART_BUTTON_EVENT_REPORTED__EVENT__CLICKED);
-        restartTaskTopActivityProcessIfVisible(info.getTaskInfo().token);
-    }
-
-    @Override
-    public void onCameraControlStateUpdated(int taskId, @CameraCompatControlState int state) {
-        final TaskAppearedInfo info;
-        synchronized (mLock) {
-            info = mTasks.get(taskId);
-        }
-        if (info == null) {
-            return;
-        }
-        updateCameraCompatControlState(info.getTaskInfo().token, state);
-    }
-
     /** Reparents a child window surface to the task surface. */
     public void reparentChildSurfaceToTask(int taskId, SurfaceControl sc,
             SurfaceControl.Transaction t) {
@@ -750,6 +779,50 @@
         taskListener.reparentChildSurfaceToTask(taskId, sc, t);
     }
 
+    @VisibleForTesting
+    void onSizeCompatRestartButtonAppeared(@NonNull SizeCompatRestartButtonAppeared compatUIEvent) {
+        final int taskId = compatUIEvent.getTaskId();
+        final TaskAppearedInfo info;
+        synchronized (mLock) {
+            info = mTasks.get(taskId);
+        }
+        if (info == null) {
+            return;
+        }
+        logSizeCompatRestartButtonEventReported(info,
+                FrameworkStatsLog.SIZE_COMPAT_RESTART_BUTTON_EVENT_REPORTED__EVENT__APPEARED);
+    }
+
+    @VisibleForTesting
+    void onSizeCompatRestartButtonClicked(@NonNull SizeCompatRestartButtonClicked compatUIEvent) {
+        final int taskId = compatUIEvent.getTaskId();
+        final TaskAppearedInfo info;
+        synchronized (mLock) {
+            info = mTasks.get(taskId);
+        }
+        if (info == null) {
+            return;
+        }
+        logSizeCompatRestartButtonEventReported(info,
+                FrameworkStatsLog.SIZE_COMPAT_RESTART_BUTTON_EVENT_REPORTED__EVENT__CLICKED);
+        restartTaskTopActivityProcessIfVisible(info.getTaskInfo().token);
+    }
+
+    @VisibleForTesting
+    void onCameraControlStateUpdated(@NonNull CameraControlStateUpdated compatUIEvent) {
+        final int taskId = compatUIEvent.getTaskId();
+        final int state = compatUIEvent.getState();
+        final TaskAppearedInfo info;
+        synchronized (mLock) {
+            info = mTasks.get(taskId);
+        }
+        if (info == null) {
+            return;
+        }
+        updateCameraCompatControlState(info.getTaskInfo().token, state);
+    }
+
+
     private void logSizeCompatRestartButtonEventReported(@NonNull TaskAppearedInfo info,
             int event) {
         ActivityInfo topActivityInfo = info.getTaskInfo().topActivityInfo;
@@ -777,10 +850,10 @@
         // on this Task if there is any.
         if (taskListener == null || !taskListener.supportCompatUI()
                 || !taskInfo.appCompatTaskInfo.hasCompatUI() || !taskInfo.isVisible) {
-            mCompatUI.onCompatInfoChanged(taskInfo, null /* taskListener */);
+            mCompatUI.onCompatInfoChanged(new CompatUIInfo(taskInfo, null /* taskListener */));
             return;
         }
-        mCompatUI.onCompatInfoChanged(taskInfo, taskListener);
+        mCompatUI.onCompatInfoChanged(new CompatUIInfo(taskInfo, taskListener));
     }
 
     private TaskListener getTaskListener(RunningTaskInfo runningTaskInfo) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
index a426b20..5696a54 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunner.java
@@ -31,6 +31,7 @@
 import android.animation.Animator;
 import android.animation.ValueAnimator;
 import android.content.Context;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.IBinder;
 import android.util.ArraySet;
@@ -45,6 +46,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.window.flags.Flags;
 import com.android.wm.shell.activityembedding.ActivityEmbeddingAnimationAdapter.SnapshotAdapter;
 import com.android.wm.shell.common.ScreenshotUtils;
 import com.android.wm.shell.shared.TransitionUtil;
@@ -263,7 +265,10 @@
         for (TransitionInfo.Change change : openingChanges) {
             final Animation animation =
                     animationProvider.get(info, change, openingWholeScreenBounds);
-            if (animation.getDuration() == 0) {
+            if (shouldUseJumpCutForAnimation(animation)) {
+                if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+                    return new ArrayList<>();
+                }
                 continue;
             }
             final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter(
@@ -288,7 +293,10 @@
             }
             final Animation animation =
                     animationProvider.get(info, change, closingWholeScreenBounds);
-            if (animation.getDuration() == 0) {
+            if (shouldUseJumpCutForAnimation(animation)) {
+                if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+                    return new ArrayList<>();
+                }
                 continue;
             }
             final ActivityEmbeddingAnimationAdapter adapter = createOpenCloseAnimationAdapter(
@@ -398,7 +406,15 @@
         // This is because the TaskFragment surface/change won't contain the Activity's before its
         // reparent.
         Animation changeAnimation = null;
-        Rect parentBounds = new Rect();
+        final Rect parentBounds = new Rect();
+        // We use a single boolean value to record the backdrop override because the override used
+        // for overlay and we restrict to single overlay animation. We should fix the assumption
+        // if we allow multiple overlay transitions.
+        // The backdrop logic is mainly for animations of split animations. The backdrop should be
+        // disabled if there is any open/close target in the same transition as the change target.
+        // However, the overlay change animation usually contains one change target, and shows
+        // backdrop unexpectedly.
+        Boolean overrideShowBackdrop = null;
         for (TransitionInfo.Change change : info.getChanges()) {
             if (change.getMode() != TRANSIT_CHANGE
                     || change.getStartAbsBounds().equals(change.getEndAbsBounds())) {
@@ -421,21 +437,29 @@
                 }
             }
 
-            // The TaskFragment may be enter/exit split, so we take the union of both as the parent
-            // size.
-            parentBounds.union(boundsAnimationChange.getStartAbsBounds());
-            parentBounds.union(boundsAnimationChange.getEndAbsBounds());
-            if (boundsAnimationChange != change) {
-                // Union the change starting bounds in case the activity is resized and reparented
-                // to a TaskFragment. In that case, the TaskFragment may not cover the activity's
-                // starting bounds.
-                parentBounds.union(change.getStartAbsBounds());
+            final TransitionInfo.AnimationOptions options = boundsAnimationChange
+                    .getAnimationOptions();
+            if (options != null) {
+                final Animation overrideAnimation = mAnimationSpec.loadCustomAnimationFromOptions(
+                        options, TRANSIT_CHANGE);
+                if (overrideAnimation != null) {
+                    overrideShowBackdrop = overrideAnimation.getShowBackdrop();
+                }
             }
 
+            calculateParentBounds(change, boundsAnimationChange, parentBounds);
             // There are two animations in the array. The first one is for the start leash
             // (snapshot), and the second one is for the end leash (TaskFragment).
-            final Animation[] animations = mAnimationSpec.createChangeBoundsChangeAnimations(change,
-                    parentBounds);
+            final Animation[] animations =
+                    mAnimationSpec.createChangeBoundsChangeAnimations(info, change, parentBounds);
+            // Jump cut if either animation has zero for duration.
+            if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+                for (Animation animation : animations) {
+                    if (shouldUseJumpCutForAnimation(animation)) {
+                        return new ArrayList<>();
+                    }
+                }
+            }
             // Keep track as we might need to add background color for the animation.
             // Although there may be multiple change animation, record one of them is sufficient
             // because the background color will be added to the root leash for the whole animation.
@@ -466,7 +490,7 @@
 
         // If there is no corresponding open/close window with the change, we should show background
         // color to cover the empty part of the screen.
-        boolean shouldShouldBackgroundColor = true;
+        boolean shouldShowBackgroundColor = true;
         // Handle the other windows that don't have bounds change in the same transition.
         for (TransitionInfo.Change change : info.getChanges()) {
             if (handledChanges.contains(change)) {
@@ -482,17 +506,26 @@
                 // window without bounds change.
                 animation = ActivityEmbeddingAnimationSpec.createNoopAnimation(change);
             } else if (TransitionUtil.isClosingType(change.getMode())) {
-                animation = mAnimationSpec.createChangeBoundsCloseAnimation(change, parentBounds);
-                shouldShouldBackgroundColor = false;
+                animation =
+                        mAnimationSpec.createChangeBoundsCloseAnimation(info, change, parentBounds);
+                shouldShowBackgroundColor = false;
             } else {
-                animation = mAnimationSpec.createChangeBoundsOpenAnimation(change, parentBounds);
-                shouldShouldBackgroundColor = false;
+                animation =
+                        mAnimationSpec.createChangeBoundsOpenAnimation(info, change, parentBounds);
+                shouldShowBackgroundColor = false;
+            }
+            if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+                if (shouldUseJumpCutForAnimation(animation)) {
+                    return new ArrayList<>();
+                }
             }
             adapters.add(new ActivityEmbeddingAnimationAdapter(animation, change,
                     TransitionUtil.getRootFor(change, info)));
         }
 
-        if (shouldShouldBackgroundColor && changeAnimation != null) {
+        shouldShowBackgroundColor = overrideShowBackdrop != null
+                ? overrideShowBackdrop : shouldShowBackgroundColor;
+        if (shouldShowBackgroundColor && changeAnimation != null) {
             // Change animation may leave part of the screen empty. Show background color to cover
             // that.
             changeAnimation.setShowBackdrop(true);
@@ -502,6 +535,39 @@
     }
 
     /**
+     * Calculates parent bounds of the animation target by {@code change}.
+     */
+    @VisibleForTesting
+    static void calculateParentBounds(@NonNull TransitionInfo.Change change,
+              @NonNull TransitionInfo.Change boundsAnimationChange, @NonNull Rect outParentBounds) {
+        if (Flags.activityEmbeddingOverlayPresentationFlag()) {
+            final Point endParentSize = change.getEndParentSize();
+            if (endParentSize.equals(0, 0)) {
+                return;
+            }
+            final Point endRelPosition = change.getEndRelOffset();
+            final Point endAbsPosition = new Point(change.getEndAbsBounds().left,
+                    change.getEndAbsBounds().top);
+            final Point parentEndAbsPosition = new Point(endAbsPosition.x - endRelPosition.x,
+                    endAbsPosition.y - endRelPosition.y);
+            outParentBounds.set(parentEndAbsPosition.x, parentEndAbsPosition.y,
+                    parentEndAbsPosition.x + endParentSize.x,
+                    parentEndAbsPosition.y + endParentSize.y);
+        } else {
+            // The TaskFragment may be enter/exit split, so we take the union of both as
+            // the parent size.
+            outParentBounds.union(boundsAnimationChange.getStartAbsBounds());
+            outParentBounds.union(boundsAnimationChange.getEndAbsBounds());
+            if (boundsAnimationChange != change) {
+                // Union the change starting bounds in case the activity is resized and
+                // reparented to a TaskFragment. In that case, the TaskFragment may not cover
+                // the activity's starting bounds.
+                outParentBounds.union(change.getStartAbsBounds());
+            }
+        }
+    }
+
+    /**
      * Takes a screenshot of the given {@code screenshotChange} surface if WM Core hasn't taken one.
      * The screenshot leash should be attached to the {@code animationChange} surface which we will
      * animate later.
@@ -595,6 +661,12 @@
         return true;
     }
 
+    /** Whether or not to use jump cut based on the animation. */
+    @VisibleForTesting
+    static boolean shouldUseJumpCutForAnimation(@NonNull Animation animation) {
+        return animation.getDuration() == 0;
+    }
+
     /** Updates the changes to end states in {@code startTransaction} for jump cut animation. */
     private void prepareForJumpCut(@NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction startTransaction) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
index b986862..3046307 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationSpec.java
@@ -18,6 +18,8 @@
 
 
 import static android.app.ActivityOptions.ANIM_CUSTOM;
+import static android.view.WindowManager.TRANSIT_CHANGE;
+import static android.window.TransitionInfo.AnimationOptions.DEFAULT_ANIMATION_RESOURCES_ID;
 
 import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_NONE;
 import static com.android.wm.shell.transition.TransitionAnimationHelper.loadAttributeAnimation;
@@ -27,6 +29,8 @@
 import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.Rect;
+import android.util.Log;
+import android.view.WindowManager;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
 import android.view.animation.AnimationSet;
@@ -42,7 +46,6 @@
 import com.android.wm.shell.shared.TransitionUtil;
 
 /** Animation spec for ActivityEmbedding transition. */
-// TODO(b/206557124): provide an easier way to customize animation
 class ActivityEmbeddingAnimationSpec {
 
     private static final String TAG = "ActivityEmbeddingAnimSpec";
@@ -91,8 +94,14 @@
 
     /** Animation for window that is opening in a change transition. */
     @NonNull
-    Animation createChangeBoundsOpenAnimation(@NonNull TransitionInfo.Change change,
-            @NonNull Rect parentBounds) {
+    Animation createChangeBoundsOpenAnimation(@NonNull TransitionInfo info,
+            @NonNull TransitionInfo.Change change, @NonNull Rect parentBounds) {
+        if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+            final Animation customAnimation = loadCustomAnimation(info, change, TRANSIT_CHANGE);
+            if (customAnimation != null) {
+                return customAnimation;
+            }
+        }
         // Use end bounds for opening.
         final Rect bounds = change.getEndAbsBounds();
         final int startLeft;
@@ -119,8 +128,14 @@
 
     /** Animation for window that is closing in a change transition. */
     @NonNull
-    Animation createChangeBoundsCloseAnimation(@NonNull TransitionInfo.Change change,
-            @NonNull Rect parentBounds) {
+    Animation createChangeBoundsCloseAnimation(@NonNull TransitionInfo info,
+            @NonNull TransitionInfo.Change change, @NonNull Rect parentBounds) {
+        if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+            final Animation customAnimation = loadCustomAnimation(info, change, TRANSIT_CHANGE);
+            if (customAnimation != null) {
+                return customAnimation;
+            }
+        }
         // Use start bounds for closing.
         final Rect bounds = change.getStartAbsBounds();
         final int endTop;
@@ -151,8 +166,17 @@
      *         the second one is for the end leash.
      */
     @NonNull
-    Animation[] createChangeBoundsChangeAnimations(@NonNull TransitionInfo.Change change,
-            @NonNull Rect parentBounds) {
+    Animation[] createChangeBoundsChangeAnimations(@NonNull TransitionInfo info,
+            @NonNull TransitionInfo.Change change, @NonNull Rect parentBounds) {
+        if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+            // TODO(b/293658614): Support more complicated animations that may need more than a noop
+            // animation as the start leash.
+            final Animation noopAnimation = createNoopAnimation(change);
+            final Animation customAnimation = loadCustomAnimation(info, change, TRANSIT_CHANGE);
+            if (customAnimation != null) {
+                return new Animation[]{noopAnimation, customAnimation};
+            }
+        }
         // Both start bounds and end bounds are in screen coordinates. We will post translate
         // to the local coordinates in ActivityEmbeddingAnimationAdapter#onAnimationUpdate
         final Rect startBounds = change.getStartAbsBounds();
@@ -203,7 +227,7 @@
     Animation loadOpenAnimation(@NonNull TransitionInfo info,
             @NonNull TransitionInfo.Change change, @NonNull Rect wholeAnimationBounds) {
         final boolean isEnter = TransitionUtil.isOpeningType(change.getMode());
-        final Animation customAnimation = loadCustomAnimation(info, change, isEnter);
+        final Animation customAnimation = loadCustomAnimation(info, change, change.getMode());
         final Animation animation;
         if (customAnimation != null) {
             animation = customAnimation;
@@ -230,7 +254,7 @@
     Animation loadCloseAnimation(@NonNull TransitionInfo info,
             @NonNull TransitionInfo.Change change, @NonNull Rect wholeAnimationBounds) {
         final boolean isEnter = TransitionUtil.isOpeningType(change.getMode());
-        final Animation customAnimation = loadCustomAnimation(info, change, isEnter);
+        final Animation customAnimation = loadCustomAnimation(info, change, change.getMode());
         final Animation animation;
         if (customAnimation != null) {
             animation = customAnimation;
@@ -263,18 +287,46 @@
 
     @Nullable
     private Animation loadCustomAnimation(@NonNull TransitionInfo info,
-            @NonNull TransitionInfo.Change change, boolean isEnter) {
+            @NonNull TransitionInfo.Change change, @WindowManager.TransitionType int mode) {
         final TransitionInfo.AnimationOptions options;
         if (Flags.moveAnimationOptionsToChange()) {
             options = change.getAnimationOptions();
         } else {
             options = info.getAnimationOptions();
         }
+        return loadCustomAnimationFromOptions(options, mode);
+    }
+
+    @Nullable
+    Animation loadCustomAnimationFromOptions(@Nullable TransitionInfo.AnimationOptions options,
+             @WindowManager.TransitionType int mode) {
         if (options == null || options.getType() != ANIM_CUSTOM) {
             return null;
         }
-        final Animation anim = mTransitionAnimation.loadAnimationRes(options.getPackageName(),
-                isEnter ? options.getEnterResId() : options.getExitResId());
+        final int resId;
+        if (TransitionUtil.isOpeningType(mode)) {
+            resId = options.getEnterResId();
+        } else if (TransitionUtil.isClosingType(mode)) {
+            resId = options.getExitResId();
+        } else if (mode == TRANSIT_CHANGE) {
+            resId = options.getChangeResId();
+        } else {
+            Log.w(TAG, "Unknown transit type:" + mode);
+            resId = DEFAULT_ANIMATION_RESOURCES_ID;
+        }
+        // Use the default animation if the resources ID is not specified.
+        if (resId == DEFAULT_ANIMATION_RESOURCES_ID) {
+            return null;
+        }
+
+        final Animation anim;
+        if (Flags.activityEmbeddingAnimationCustomizationFlag()) {
+            // TODO(b/293658614): Consider allowing custom animations from non-default packages.
+            // Enforce limiting to animations from the default "android" package for now.
+            anim = mTransitionAnimation.loadDefaultAnimationRes(resId);
+        } else {
+            anim = mTransitionAnimation.loadAnimationRes(options.getPackageName(), resId);
+        }
         if (anim != null) {
             return anim;
         }
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 7041ea3..ece0271 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
@@ -59,7 +59,7 @@
 import android.window.IOnBackInvokedCallback;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.LatencyTracker;
 import com.android.internal.view.AppearanceRegion;
 import com.android.wm.shell.R;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
index 4988a94..e24df0b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
@@ -30,7 +30,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.jank.Cuj.CujType;
-import com.android.wm.shell.common.InteractionJankMonitorUtils;
+import com.android.internal.jank.InteractionJankMonitor;
 
 /**
  * Used to register the animation callback and runner, it will trigger result if gesture was finish
@@ -86,20 +86,21 @@
      */
     void startAnimation(RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers,
             RemoteAnimationTarget[] nonApps, Runnable finishedCallback) {
+        InteractionJankMonitor interactionJankMonitor = InteractionJankMonitor.getInstance();
         final IRemoteAnimationFinishedCallback callback =
                 new IRemoteAnimationFinishedCallback.Stub() {
                     @Override
                     public void onAnimationFinished() {
                         if (shouldMonitorCUJ(apps)) {
-                            InteractionJankMonitorUtils.endTracing(mCujType);
+                            interactionJankMonitor.end(mCujType);
                         }
                         finishedCallback.run();
                     }
                 };
         mWaitingAnimation = false;
         if (shouldMonitorCUJ(apps)) {
-            InteractionJankMonitorUtils.beginTracing(
-                    mCujType, mContext, apps[0].leash, /* tag */ null);
+            interactionJankMonitor.begin(
+                    apps[0].leash, mContext, mCujType);
         }
         try {
             getRunner().onAnimationStart(TRANSIT_OLD_UNSET, apps, wallpapers,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
index a3111b3..4f04c5c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
@@ -48,7 +48,7 @@
 import com.android.internal.jank.Cuj
 import com.android.internal.policy.ScreenDecorationsUtils
 import com.android.internal.policy.SystemBarUtils
-import com.android.internal.protolog.common.ProtoLog
+import com.android.internal.protolog.ProtoLog
 import com.android.wm.shell.R
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer
 import com.android.wm.shell.animation.Interpolators
@@ -324,6 +324,7 @@
         enteringHasSameLetterbox = false
         lastPostCommitFlingScale = SPRING_SCALE
         gestureProgress = 0f
+        triggerBack = false
     }
 
     protected fun applyTransform(
@@ -499,10 +500,12 @@
         }
 
         override fun onBackCancelled() {
+            triggerBack = false
             progressAnimator.onBackCancelled { finishAnimation() }
         }
 
         override fun onBackInvoked() {
+            triggerBack = true
             progressAnimator.reset()
             onGestureCommitted(progressAnimator.velocity)
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
index 381914a5..103a654 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
@@ -49,7 +49,7 @@
 
 import com.android.internal.policy.ScreenDecorationsUtils;
 import com.android.internal.policy.SystemBarUtils;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.animation.Interpolators;
 import com.android.wm.shell.shared.annotations.ShellMainThread;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomCrossActivityBackAnimation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomCrossActivityBackAnimation.kt
index c738ce5..e266e2c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomCrossActivityBackAnimation.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomCrossActivityBackAnimation.kt
@@ -28,7 +28,7 @@
 import android.window.BackNavigationInfo
 import com.android.internal.R
 import com.android.internal.policy.TransitionAnimation
-import com.android.internal.protolog.common.ProtoLog
+import com.android.internal.protolog.ProtoLog
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer
 import com.android.wm.shell.protolog.ShellProtoLogGroup
 import com.android.wm.shell.shared.annotations.ShellMainThread
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
index 1279fc4..7dbbb04 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
@@ -48,7 +48,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.InstanceId;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.launcher3.icons.BubbleIconFactory;
 import com.android.wm.shell.bubbles.bar.BubbleBarExpandedView;
 import com.android.wm.shell.bubbles.bar.BubbleBarLayerView;
@@ -894,11 +894,22 @@
     }
 
     @Nullable
-    Intent getAppBubbleIntent() {
+    @VisibleForTesting
+    public Intent getAppBubbleIntent() {
         return mAppIntent;
     }
 
     /**
+     * Sets the intent for a bubble that is an app bubble (one for which {@link #mIsAppBubble} is
+     * true).
+     *
+     * @param appIntent The intent to set for the app bubble.
+     */
+    void setAppBubbleIntent(Intent appIntent) {
+        mAppIntent = appIntent;
+    }
+
+    /**
      * Returns whether this bubble is from an app versus a notification.
      */
     public boolean isAppBubble() {
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 d2c36e6..e36f6e6 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
@@ -84,7 +84,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.util.CollectionUtils;
 import com.android.launcher3.icons.BubbleIconFactory;
@@ -1450,6 +1450,8 @@
             if (b != null) {
                 // It's in the overflow, so remove it & reinflate
                 mBubbleData.dismissBubbleWithKey(appBubbleKey, Bubbles.DISMISS_NOTIF_CANCEL);
+                // Update the bubble entry in the overflow with the latest intent.
+                b.setAppBubbleIntent(intent);
             } else {
                 // App bubble does not exist, lets add and expand it
                 b = Bubble.createAppBubble(intent, user, icon, mMainExecutor);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index 761e025..4e6c517 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -35,7 +35,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.bubbles.Bubbles.DismissReason;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index c7ccd50..f7a5c27 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -67,7 +67,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.policy.ScreenDecorationsUtils;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.Flags;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.AlphaOptimizedButton;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
index 18e04d1..bf98ef8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
@@ -42,7 +42,7 @@
 import androidx.recyclerview.widget.GridLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.ContrastColorUtil;
 import com.android.wm.shell.Flags;
 import com.android.wm.shell.R;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index 2382545..0cf187b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -29,7 +29,7 @@
 
 import androidx.annotation.VisibleForTesting;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.launcher3.icons.IconNormalizer;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.bubbles.BubbleBarLocation;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 09bec8c..f93f19d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -78,7 +78,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.policy.ScreenDecorationsUtils;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.wm.shell.Flags;
 import com.android.wm.shell.R;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java
index 0b66bcb..c79d9c4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTaskViewHelper.java
@@ -35,7 +35,7 @@
 
 import androidx.annotation.Nullable;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.taskview.TaskView;
 
 /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarGestureTracker.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarGestureTracker.java
index 1375684..9429c9e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarGestureTracker.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarGestureTracker.java
@@ -29,7 +29,7 @@
 
 import androidx.annotation.Nullable;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.bubbles.BubblesNavBarMotionEventHandler.MotionEventListener;
 
 /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarMotionEventHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarMotionEventHandler.java
index b7107f0..d4f53ab 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarMotionEventHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblesNavBarMotionEventHandler.java
@@ -28,7 +28,7 @@
 
 import androidx.annotation.Nullable;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 /**
  * Handles {@link MotionEvent}s for bubbles that begin in the nav bar area
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerImpl.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerImpl.java
index aa4129a..fbef6b5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerImpl.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedViewAnimationControllerImpl.java
@@ -38,7 +38,7 @@
 import androidx.dynamicanimation.animation.SpringAnimation;
 import androidx.dynamicanimation.animation.SpringForce;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.animation.FlingAnimationUtils;
 import com.android.wm.shell.animation.Interpolators;
 import com.android.wm.shell.bubbles.BubbleExpandedView;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/CreateBubbleShortcutActivity.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/CreateBubbleShortcutActivity.kt
index a124f95..c93c11e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/CreateBubbleShortcutActivity.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/CreateBubbleShortcutActivity.kt
@@ -20,10 +20,10 @@
 import android.content.pm.ShortcutManager
 import android.graphics.drawable.Icon
 import android.os.Bundle
+import com.android.internal.protolog.ProtoLog
 import com.android.wm.shell.Flags
 import com.android.wm.shell.R
 import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES
-import com.android.wm.shell.util.KtProtoLog
 
 /** Activity to create a shortcut to open bubbles */
 class CreateBubbleShortcutActivity : Activity() {
@@ -31,7 +31,7 @@
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         if (Flags.enableRetrievableBubbles()) {
-            KtProtoLog.d(WM_SHELL_BUBBLES, "Creating a shortcut for bubbles")
+            ProtoLog.d(WM_SHELL_BUBBLES, "Creating a shortcut for bubbles")
             createShortcut()
         }
         finish()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/ShowBubblesActivity.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/ShowBubblesActivity.kt
index ae7940c..e578e9e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/ShowBubblesActivity.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/ShowBubblesActivity.kt
@@ -21,9 +21,9 @@
 import android.content.Context
 import android.content.Intent
 import android.os.Bundle
+import com.android.internal.protolog.ProtoLog
 import com.android.wm.shell.Flags
 import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES
-import com.android.wm.shell.util.KtProtoLog
 
 /** Activity that sends a broadcast to open bubbles */
 class ShowBubblesActivity : Activity() {
@@ -37,7 +37,7 @@
                     // Set the package as the receiver is not exported
                     `package` = packageName
                 }
-            KtProtoLog.v(WM_SHELL_BUBBLES, "Sending broadcast to show bubbles")
+            ProtoLog.v(WM_SHELL_BUBBLES, "Sending broadcast to show bubbles")
             sendBroadcast(intent)
         }
         finish()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/InteractionJankMonitorUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/InteractionJankMonitorUtils.java
deleted file mode 100644
index 86f00b8..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/InteractionJankMonitorUtils.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.common;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.text.TextUtils;
-import android.view.SurfaceControl;
-import android.view.View;
-
-import com.android.internal.jank.Cuj.CujType;
-import com.android.internal.jank.InteractionJankMonitor;
-
-/** Utils class for simplfy InteractionJank trancing call */
-public class InteractionJankMonitorUtils {
-
-    /**
-     * Begin a trace session.
-     *
-     * @param cujType the specific {@link CujType}.
-     * @param view the view to trace
-     * @param tag the tag to distinguish different flow of same type CUJ.
-     */
-    public static void beginTracing(@CujType int cujType,
-            @NonNull View view, @Nullable String tag) {
-        final InteractionJankMonitor.Configuration.Builder builder =
-                InteractionJankMonitor.Configuration.Builder.withView(cujType, view);
-        if (!TextUtils.isEmpty(tag)) {
-            builder.setTag(tag);
-        }
-        InteractionJankMonitor.getInstance().begin(builder);
-    }
-
-    /**
-     * Begin a trace session.
-     *
-     * @param cujType the specific {@link CujType}.
-     * @param context the context
-     * @param surface the surface to trace
-     * @param tag the tag to distinguish different flow of same type CUJ.
-     */
-    public static void beginTracing(@CujType int cujType,
-            @NonNull Context context, @NonNull SurfaceControl surface, @Nullable String tag) {
-        final InteractionJankMonitor.Configuration.Builder builder =
-                InteractionJankMonitor.Configuration.Builder.withSurface(cujType, context, surface);
-        if (!TextUtils.isEmpty(tag)) {
-            builder.setTag(tag);
-        }
-        InteractionJankMonitor.getInstance().begin(builder);
-    }
-
-    /**
-     * End a trace session.
-     *
-     * @param cujType the specific {@link CujType}.
-     */
-    public static void endTracing(@CujType int cujType) {
-        InteractionJankMonitor.getInstance().end(cujType);
-    }
-
-    /**
-     * Cancel the trace session.
-     *
-     * @param cujType the specific {@link CujType}.
-     */
-    public static void cancelTracing(@CujType int cujType) {
-        InteractionJankMonitor.getInstance().cancel(cujType);
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/LaunchAdjacentController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/LaunchAdjacentController.kt
index 81592c3..e92b0b5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/LaunchAdjacentController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/LaunchAdjacentController.kt
@@ -17,8 +17,8 @@
 
 import android.window.WindowContainerToken
 import android.window.WindowContainerTransaction
+import com.android.internal.protolog.ProtoLog
 import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG
-import com.android.wm.shell.util.KtProtoLog
 
 /**
  * Controller to manage behavior of activities launched with
@@ -30,7 +30,7 @@
     var launchAdjacentEnabled: Boolean = true
         set(value) {
             if (field != value) {
-                KtProtoLog.d(WM_SHELL_TASK_ORG, "set launch adjacent flag root enabled=%b", value)
+                ProtoLog.d(WM_SHELL_TASK_ORG, "set launch adjacent flag root enabled=%b", value)
                 field = value
                 container?.let { c ->
                     if (value) {
@@ -52,7 +52,7 @@
      * @see WindowContainerTransaction.setLaunchAdjacentFlagRoot
      */
     fun setLaunchAdjacentRoot(container: WindowContainerToken) {
-        KtProtoLog.d(WM_SHELL_TASK_ORG, "set new launch adjacent flag root container")
+        ProtoLog.d(WM_SHELL_TASK_ORG, "set new launch adjacent flag root container")
         this.container = container
         if (launchAdjacentEnabled) {
             enableContainer(container)
@@ -67,7 +67,7 @@
      * @see WindowContainerTransaction.clearLaunchAdjacentFlagRoot
      */
     fun clearLaunchAdjacentRoot() {
-        KtProtoLog.d(WM_SHELL_TASK_ORG, "clear launch adjacent flag root container")
+        ProtoLog.d(WM_SHELL_TASK_ORG, "clear launch adjacent flag root container")
         container?.let {
             disableContainer(it)
             container = null
@@ -75,14 +75,14 @@
     }
 
     private fun enableContainer(container: WindowContainerToken) {
-        KtProtoLog.v(WM_SHELL_TASK_ORG, "enable launch adjacent flag root container")
+        ProtoLog.v(WM_SHELL_TASK_ORG, "enable launch adjacent flag root container")
         val wct = WindowContainerTransaction()
         wct.setLaunchAdjacentFlagRoot(container)
         syncQueue.queue(wct)
     }
 
     private fun disableContainer(container: WindowContainerToken) {
-        KtProtoLog.v(WM_SHELL_TASK_ORG, "disable launch adjacent flag root container")
+        ProtoLog.v(WM_SHELL_TASK_ORG, "disable launch adjacent flag root container")
         val wct = WindowContainerTransaction()
         wct.clearLaunchAdjacentFlagRoot(container)
         syncQueue.queue(wct)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiInstanceHelper.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiInstanceHelper.kt
index 9e8dfb5..a6be640 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiInstanceHelper.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/MultiInstanceHelper.kt
@@ -23,9 +23,9 @@
 import android.os.UserHandle
 import android.view.WindowManager.PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI
 import com.android.internal.annotations.VisibleForTesting
+import com.android.internal.protolog.ProtoLog
 import com.android.wm.shell.R
 import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL
-import com.android.wm.shell.util.KtProtoLog
 import java.util.Arrays
 
 /**
@@ -52,7 +52,7 @@
         val packageName = componentName.packageName
         for (pkg in staticAppsSupportingMultiInstance) {
             if (pkg == packageName) {
-                KtProtoLog.v(WM_SHELL, "application=%s in allowlist supports multi-instance",
+                ProtoLog.v(WM_SHELL, "application=%s in allowlist supports multi-instance",
                     packageName)
                 return true
             }
@@ -70,10 +70,10 @@
             // If the above call doesn't throw a NameNotFoundException, then the activity property
             // should override the application property value
             if (activityProp.isBoolean) {
-                KtProtoLog.v(WM_SHELL, "activity=%s supports multi-instance", componentName)
+                ProtoLog.v(WM_SHELL, "activity=%s supports multi-instance", componentName)
                 return activityProp.boolean
             } else {
-                KtProtoLog.w(WM_SHELL, "Warning: property=%s for activity=%s has non-bool type=%d",
+                ProtoLog.w(WM_SHELL, "Warning: property=%s for activity=%s has non-bool type=%d",
                     PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI, packageName, activityProp.type)
             }
         } catch (nnfe: PackageManager.NameNotFoundException) {
@@ -85,10 +85,10 @@
             val appProp = packageManager.getProperty(
                 PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI, packageName)
             if (appProp.isBoolean) {
-                KtProtoLog.v(WM_SHELL, "application=%s supports multi-instance", packageName)
+                ProtoLog.v(WM_SHELL, "application=%s supports multi-instance", packageName)
                 return appProp.boolean
             } else {
-                KtProtoLog.w(WM_SHELL,
+                ProtoLog.w(WM_SHELL,
                     "Warning: property=%s for application=%s has non-bool type=%d",
                     PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI, packageName, appProp.type)
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java
index e261d92..f792392 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java
@@ -28,7 +28,7 @@
 import android.window.WindowContainerTransactionCallback;
 import android.window.WindowOrganizer;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.transition.LegacyTransitions;
 
 import java.util.ArrayList;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java
index 43c92ca..43f9cb98 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/TabletopModeController.java
@@ -32,7 +32,7 @@
 import android.view.Surface;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.shared.annotations.ShellMainThread;
 import com.android.wm.shell.sysui.ShellInit;
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsAlgorithm.java
index 6ffeb97..8e026f0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsAlgorithm.java
@@ -27,7 +27,9 @@
 import android.util.Size;
 import android.view.Gravity;
 
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
 import java.io.PrintWriter;
 
@@ -39,6 +41,9 @@
     private static final String TAG = PipBoundsAlgorithm.class.getSimpleName();
     private static final float INVALID_SNAP_FRACTION = -1f;
 
+    // The same value (with the same name) is used in Launcher.
+    private static final float PIP_ASPECT_RATIO_MISMATCH_THRESHOLD = 0.01f;
+
     @NonNull private final PipBoundsState mPipBoundsState;
     @NonNull protected final PipDisplayLayoutState mPipDisplayLayoutState;
     @NonNull protected final SizeSpecSource mSizeSpecSource;
@@ -206,9 +211,27 @@
      */
     public static boolean isSourceRectHintValidForEnterPip(Rect sourceRectHint,
             Rect destinationBounds) {
-        return sourceRectHint != null
-                && sourceRectHint.width() > destinationBounds.width()
-                && sourceRectHint.height() > destinationBounds.height();
+        if (sourceRectHint == null || sourceRectHint.isEmpty()) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "isSourceRectHintValidForEnterPip=false, empty hint");
+            return false;
+        }
+        if (sourceRectHint.width() <= destinationBounds.width()
+                || sourceRectHint.height() <= destinationBounds.height()) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "isSourceRectHintValidForEnterPip=false, hint(%s) is smaller"
+                            + " than destination(%s)", sourceRectHint, destinationBounds);
+            return false;
+        }
+        final float reportedRatio = destinationBounds.width() / (float) destinationBounds.height();
+        final float inferredRatio = sourceRectHint.width() / (float) sourceRectHint.height();
+        if (Math.abs(reportedRatio - inferredRatio) > PIP_ASPECT_RATIO_MISMATCH_THRESHOLD) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "isSourceRectHintValidForEnterPip=false, hint(%s) does not match"
+                            + " destination(%s) aspect ratio", sourceRectHint, destinationBounds);
+            return false;
+        }
+        return true;
     }
 
     public float getDefaultAspectRatio() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsState.java
index 7ceaaea..64a1b0c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsState.java
@@ -32,7 +32,7 @@
 import android.util.Size;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.function.TriConsumer;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.DisplayLayout;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipPerfHintController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipPerfHintController.java
index c421dec..b9c698e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipPerfHintController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipPerfHintController.java
@@ -26,7 +26,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.shared.annotations.ShellMainThread;
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
index a09720d..dcf84d9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
@@ -30,10 +30,11 @@
 import android.util.Pair
 import android.util.TypedValue
 import android.window.TaskSnapshot
-import com.android.internal.protolog.common.ProtoLog
+import com.android.internal.protolog.ProtoLog
 import com.android.wm.shell.Flags
 import com.android.wm.shell.protolog.ShellProtoLogGroup
 import kotlin.math.abs
+import kotlin.math.roundToInt
 
 /** A class that includes convenience methods.  */
 object PipUtils {
@@ -149,16 +150,16 @@
         val appBoundsAspRatio = appBounds.width().toFloat() / appBounds.height()
         val width: Int
         val height: Int
-        var left = 0
-        var top = 0
+        var left = appBounds.left
+        var top = appBounds.top
         if (appBoundsAspRatio < aspectRatio) {
             width = appBounds.width()
-            height = Math.round(width / aspectRatio)
-            top = (appBounds.height() - height) / 2
+            height = (width / aspectRatio).roundToInt()
+            top = appBounds.top + (appBounds.height() - height) / 2
         } else {
             height = appBounds.height()
-            width = Math.round(height * aspectRatio)
-            left = (appBounds.width() - width) / 2
+            width = (height * aspectRatio).roundToInt()
+            left = appBounds.left + (appBounds.width() - width) / 2
         }
         return Rect(left, top, left + width, top + height)
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
index c2242a8..1bc1795 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java
@@ -54,7 +54,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.animation.Interpolators;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
@@ -336,11 +336,6 @@
                 setTouching();
                 mStartPos = touchPos;
                 mMoving = false;
-                // This triggers initialization of things like the resize veil in preparation for
-                // showing it when the user moves the divider past the slop, and has to be done
-                // before onStartDragging() which starts the jank interaction tracing
-                mSplitLayout.updateDividerBounds(mSplitLayout.getDividerPosition(),
-                        false /* shouldUseParallaxEffect */);
                 mSplitLayout.onStartDragging();
                 break;
             case MotionEvent.ACTION_MOVE:
@@ -497,6 +492,11 @@
         return mHideHandle;
     }
 
+    /** Returns true if the divider is currently being physically controlled by the user. */
+    boolean isMoving() {
+        return mMoving;
+    }
+
     private class DoubleTapListener extends GestureDetector.SimpleOnGestureListener {
         @Override
         public boolean onDoubleTap(MotionEvent e) {
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 de016d3..5097ed8 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
@@ -269,7 +269,9 @@
 
         if (update) {
             if (immediately) {
+                t.setAlpha(mBackgroundLeash, showVeil ? 1f : 0f);
                 t.setVisibility(mBackgroundLeash, showVeil);
+                t.setAlpha(mIconLeash, showVeil ? 1f : 0f);
                 t.setVisibility(mIconLeash, showVeil);
             } else {
                 startFadeAnimation(showVeil, false, null);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index 8ced76f..51f9de8 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
@@ -59,7 +59,8 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.jank.InteractionJankMonitor;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.animation.Interpolators;
@@ -67,7 +68,6 @@
 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.InteractionJankMonitorUtils;
 import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition;
 import com.android.wm.shell.common.split.SplitScreenConstants.SnapPosition;
 import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
@@ -131,6 +131,7 @@
 
     private final boolean mDimNonImeSide;
     private final boolean mAllowLeftRightSplitInPortrait;
+    private final InteractionJankMonitor mInteractionJankMonitor;
     private boolean mIsLeftRightSplit;
     private ValueAnimator mDividerFlingAnimator;
 
@@ -163,6 +164,7 @@
 
         mRootBounds.set(configuration.windowConfiguration.getBounds());
         mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
+        mInteractionJankMonitor = InteractionJankMonitor.getInstance();
         resetDividerPosition();
         updateInvisibleRect();
     }
@@ -569,12 +571,11 @@
     }
 
     void onStartDragging() {
-        InteractionJankMonitorUtils.beginTracing(CUJ_SPLIT_SCREEN_RESIZE, mContext,
-                getDividerLeash(), null /* tag */);
+        mInteractionJankMonitor.begin(getDividerLeash(), mContext, CUJ_SPLIT_SCREEN_RESIZE);
     }
 
     void onDraggingCancelled() {
-        InteractionJankMonitorUtils.cancelTracing(CUJ_SPLIT_SCREEN_RESIZE);
+        mInteractionJankMonitor.cancel(CUJ_SPLIT_SCREEN_RESIZE);
     }
 
     void onDoubleTappedDivider() {
@@ -638,7 +639,7 @@
             if (flingFinishedCallback != null) {
                 flingFinishedCallback.run();
             }
-            InteractionJankMonitorUtils.endTracing(
+            mInteractionJankMonitor.end(
                     CUJ_SPLIT_SCREEN_RESIZE);
             return;
         }
@@ -651,9 +652,18 @@
                 .ofInt(from, to)
                 .setDuration(duration);
         mDividerFlingAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+
+        // If the divider is being physically controlled by the user, we use a cool parallax effect
+        // on the task windows. So if this "snap" animation is an extension of a user-controlled
+        // movement, we pass in true here to continue the parallax effect smoothly.
+        boolean isBeingMovedByUser = mSplitWindowManager.getDividerView() != null
+                && mSplitWindowManager.getDividerView().isMoving();
+
         mDividerFlingAnimator.addUpdateListener(
                 animation -> updateDividerBounds(
-                        (int) animation.getAnimatedValue(), false /* shouldUseParallaxEffect */)
+                        (int) animation.getAnimatedValue(),
+                        isBeingMovedByUser /* shouldUseParallaxEffect */
+                )
         );
         mDividerFlingAnimator.addListener(new AnimatorListenerAdapter() {
             @Override
@@ -661,7 +671,7 @@
                 if (flingFinishedCallback != null) {
                     flingFinishedCallback.run();
                 }
-                InteractionJankMonitorUtils.endTracing(
+                mInteractionJankMonitor.end(
                         CUJ_SPLIT_SCREEN_RESIZE);
                 mDividerFlingAnimator = null;
             }
@@ -707,8 +717,8 @@
         set.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationStart(Animator animation) {
-                InteractionJankMonitorUtils.beginTracing(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER,
-                        mContext, getDividerLeash(), null /*tag*/);
+                mInteractionJankMonitor.begin(getDividerLeash(),
+                        mContext, CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
             }
 
             @Override
@@ -716,12 +726,12 @@
                 mDividerPosition = dividerPos;
                 updateBounds(mDividerPosition);
                 finishCallback.accept(insets);
-                InteractionJankMonitorUtils.endTracing(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
+                mInteractionJankMonitor.end(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
             }
 
             @Override
             public void onAnimationCancel(Animator animation) {
-                InteractionJankMonitorUtils.cancelTracing(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
+                mInteractionJankMonitor.cancel(CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER);
             }
         });
         set.start();
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 5d121c2..46c1a43 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
@@ -37,7 +37,6 @@
 import android.view.SurfaceControl;
 import android.view.SurfaceControlViewHost;
 import android.view.SurfaceSession;
-import android.view.View;
 import android.view.WindowManager;
 import android.view.WindowlessWindowManager;
 
@@ -192,7 +191,7 @@
         mDividerView.setInteractive(interactive, hideHandle, from);
     }
 
-    View getDividerView() {
+    DividerView getDividerView() {
         return mDividerView;
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/AppCompatUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/AppCompatUtils.kt
index 6781d08..d1b2347 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/AppCompatUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/AppCompatUtils.kt
@@ -19,6 +19,16 @@
 package com.android.wm.shell.compatui
 
 import android.app.TaskInfo
-fun isSingleTopActivityTranslucent(task: TaskInfo) =
-    task.isTopActivityTransparent && task.numActivities == 1
+import android.content.Context
+import com.android.internal.R
 
+// TODO(b/347289970): Consider replacing with API
+fun isTopActivityExemptFromDesktopWindowing(context: Context, task: TaskInfo) =
+    isSystemUiTask(context, task) || (task.isTopActivityTransparent && task.numActivities == 1
+            && !task.isTopActivityStyleFloating)
+
+private fun isSystemUiTask(context: Context, task: TaskInfo): Boolean {
+    val sysUiPackageName: String =
+        context.resources.getString(R.string.config_systemUi)
+    return task.baseActivity?.packageName == sysUiPackageName
+}
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 bfac24b..c02c9cf 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
@@ -20,7 +20,6 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.CameraCompatTaskInfo.CameraCompatControlState;
 import android.app.TaskInfo;
 import android.content.ComponentName;
 import android.content.Context;
@@ -50,6 +49,10 @@
 import com.android.wm.shell.common.DockStateReader;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.compatui.api.CompatUIEvent;
+import com.android.wm.shell.compatui.api.CompatUIHandler;
+import com.android.wm.shell.compatui.api.CompatUIInfo;
+import com.android.wm.shell.compatui.impl.CompatUIEvents.SizeCompatRestartButtonClicked;
 import com.android.wm.shell.sysui.KeyguardChangeListener;
 import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.sysui.ShellInit;
@@ -71,17 +74,7 @@
  * activities are in compatibility mode.
  */
 public class CompatUIController implements OnDisplaysChangedListener,
-        DisplayImeController.ImePositionProcessor, KeyguardChangeListener {
-
-    /** Callback for compat UI interaction. */
-    public interface CompatUICallback {
-        /** Called when the size compat restart button appears. */
-        void onSizeCompatRestartButtonAppeared(int taskId);
-        /** Called when the size compat restart button is clicked. */
-        void onSizeCompatRestartButtonClicked(int taskId);
-        /** Called when the camera compat control state is updated. */
-        void onCameraControlStateUpdated(int taskId, @CameraCompatControlState int state);
-    }
+        DisplayImeController.ImePositionProcessor, KeyguardChangeListener, CompatUIHandler {
 
     private static final String TAG = "CompatUIController";
 
@@ -170,7 +163,7 @@
     private final Function<Integer, Integer> mDisappearTimeSupplier;
 
     @Nullable
-    private CompatUICallback mCompatUICallback;
+    private Consumer<CompatUIEvent> mCallback;
 
     // Indicates if the keyguard is currently showing, in which case compat UIs shouldn't
     // be shown.
@@ -230,20 +223,21 @@
         mCompatUIShellCommandHandler.onInit();
     }
 
-    /** Sets the callback for Compat UI interactions. */
-    public void setCompatUICallback(@NonNull CompatUICallback compatUiCallback) {
-        mCompatUICallback = compatUiCallback;
+    /** Sets the callback for UI interactions. */
+    @Override
+    public void setCallback(@Nullable Consumer<CompatUIEvent> callback) {
+        mCallback = callback;
     }
 
     /**
      * Called when the Task info changed. Creates and updates the compat UI if there is an
      * activity in size compat, or removes the UI if there is no size compat activity.
      *
-     * @param taskInfo {@link TaskInfo} task the activity is in.
-     * @param taskListener listener to handle the Task Surface placement.
+     * @param compatUIInfo {@link CompatUIInfo} encapsulates information about the task and listener
      */
-    public void onCompatInfoChanged(@NonNull TaskInfo taskInfo,
-            @Nullable ShellTaskOrganizer.TaskListener taskListener) {
+    public void onCompatInfoChanged(@NonNull CompatUIInfo compatUIInfo) {
+        final TaskInfo taskInfo = compatUIInfo.getTaskInfo();
+        final ShellTaskOrganizer.TaskListener taskListener = compatUIInfo.getListener();
         if (taskInfo != null && !taskInfo.appCompatTaskInfo.topActivityInSizeCompat) {
             mSetOfTaskIdsShowingRestartDialog.remove(taskInfo.taskId);
         }
@@ -258,9 +252,15 @@
             return;
         }
         // We're showing the first reachability education so we ignore incoming TaskInfo
-        // until the education flow has completed or we double tap.
+        // until the education flow has completed or we double tap. The double-tap
+        // basically cancel all the onboarding flow. We don't have to ignore events in case
+        // the app is in size compat mode.
         if (mIsFirstReachabilityEducationRunning) {
-            return;
+            if (!taskInfo.appCompatTaskInfo.isFromLetterboxDoubleTap
+                    && !taskInfo.appCompatTaskInfo.topActivityInSizeCompat) {
+                return;
+            }
+            mIsFirstReachabilityEducationRunning = false;
         }
         if (taskInfo.appCompatTaskInfo.topActivityBoundsLetterboxed) {
             if (taskInfo.appCompatTaskInfo.isLetterboxEducationEnabled) {
@@ -278,17 +278,24 @@
                 final boolean isFirstTimeVerticalReachabilityEdu = !topActivityPillarboxed
                         && !mCompatUIConfiguration.hasSeenVerticalReachabilityEducation(taskInfo);
                 if (isFirstTimeHorizontalReachabilityEdu || isFirstTimeVerticalReachabilityEdu) {
-                    mIsFirstReachabilityEducationRunning = true;
                     mCompatUIConfiguration.setSeenLetterboxEducation(taskInfo.userId);
-                    createOrUpdateReachabilityEduLayout(taskInfo, taskListener);
-                    return;
+                    // We activate the first reachability education if the double-tap is enabled.
+                    // If the double tap is not enabled (e.g. thin letterbox) we just set the value
+                    // of the education being seen.
+                    if (taskInfo.appCompatTaskInfo.isLetterboxDoubleTapEnabled) {
+                        mIsFirstReachabilityEducationRunning = true;
+                        createOrUpdateReachabilityEduLayout(taskInfo, taskListener);
+                        return;
+                    }
                 }
             }
         }
         createOrUpdateCompatLayout(taskInfo, taskListener);
         createOrUpdateRestartDialogLayout(taskInfo, taskListener);
         if (mCompatUIConfiguration.getHasSeenLetterboxEducation(taskInfo.userId)) {
-            createOrUpdateReachabilityEduLayout(taskInfo, taskListener);
+            if (taskInfo.appCompatTaskInfo.isLetterboxDoubleTapEnabled) {
+                createOrUpdateReachabilityEduLayout(taskInfo, taskListener);
+            }
             // The user aspect ratio button should not be handled when a new TaskInfo is
             // sent because of a double tap or when in multi-window mode.
             if (taskInfo.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
@@ -453,7 +460,7 @@
     CompatUIWindowManager createCompatUiWindowManager(Context context, TaskInfo taskInfo,
             ShellTaskOrganizer.TaskListener taskListener) {
         return new CompatUIWindowManager(context,
-                taskInfo, mSyncQueue, mCompatUICallback, taskListener,
+                taskInfo, mSyncQueue, mCallback, taskListener,
                 mDisplayController.getDisplayLayout(taskInfo.displayId), mCompatUIHintsState,
                 mCompatUIConfiguration, this::onRestartButtonClicked);
     }
@@ -465,9 +472,9 @@
                 taskInfoState.first)) {
             // We need to show the dialog
             mSetOfTaskIdsShowingRestartDialog.add(taskInfoState.first.taskId);
-            onCompatInfoChanged(taskInfoState.first, taskInfoState.second);
+            onCompatInfoChanged(new CompatUIInfo(taskInfoState.first, taskInfoState.second));
         } else {
-            mCompatUICallback.onSizeCompatRestartButtonClicked(taskInfoState.first.taskId);
+            mCallback.accept(new SizeCompatRestartButtonClicked(taskInfoState.first.taskId));
         }
     }
 
@@ -562,13 +569,13 @@
     private void onRestartDialogCallback(
             Pair<TaskInfo, ShellTaskOrganizer.TaskListener> stateInfo) {
         mTaskIdToRestartDialogWindowManagerMap.remove(stateInfo.first.taskId);
-        mCompatUICallback.onSizeCompatRestartButtonClicked(stateInfo.first.taskId);
+        mCallback.accept(new SizeCompatRestartButtonClicked(stateInfo.first.taskId));
     }
 
     private void onRestartDialogDismissCallback(
             Pair<TaskInfo, ShellTaskOrganizer.TaskListener> stateInfo) {
         mSetOfTaskIdsShowingRestartDialog.remove(stateInfo.first.taskId);
-        onCompatInfoChanged(stateInfo.first, stateInfo.second);
+        onCompatInfoChanged(new CompatUIInfo(stateInfo.first, stateInfo.second));
     }
 
     private void createOrUpdateReachabilityEduLayout(@NonNull TaskInfo taskInfo,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java
index 3ab1fad..1931212 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java
@@ -40,8 +40,10 @@
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.compatui.CompatUIController.CompatUICallback;
 import com.android.wm.shell.compatui.CompatUIController.CompatUIHintsState;
+import com.android.wm.shell.compatui.api.CompatUIEvent;
+import com.android.wm.shell.compatui.impl.CompatUIEvents.CameraControlStateUpdated;
+import com.android.wm.shell.compatui.impl.CompatUIEvents.SizeCompatRestartButtonAppeared;
 
 import java.util.function.Consumer;
 
@@ -50,10 +52,13 @@
  */
 class CompatUIWindowManager extends CompatUIWindowManagerAbstract {
 
-    private final CompatUICallback mCallback;
+    @NonNull
+    private final Consumer<CompatUIEvent> mCallback;
 
+    @NonNull
     private final CompatUIConfiguration mCompatUIConfiguration;
 
+    @NonNull
     private final Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>> mOnRestartButtonClicked;
 
     // Remember the last reported states in case visibility changes due to keyguard or IME updates.
@@ -65,6 +70,7 @@
     int mCameraCompatControlState = CAMERA_COMPAT_CONTROL_HIDDEN;
 
     @VisibleForTesting
+    @NonNull
     CompatUIHintsState mCompatUIHintsState;
 
     @Nullable
@@ -73,11 +79,15 @@
 
     private final float mHideScmTolerance;
 
-    CompatUIWindowManager(Context context, TaskInfo taskInfo,
-            SyncTransactionQueue syncQueue, CompatUICallback callback,
-            ShellTaskOrganizer.TaskListener taskListener, DisplayLayout displayLayout,
-            CompatUIHintsState compatUIHintsState, CompatUIConfiguration compatUIConfiguration,
-            Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>> onRestartButtonClicked) {
+    CompatUIWindowManager(@NonNull Context context, @NonNull TaskInfo taskInfo,
+                          @NonNull SyncTransactionQueue syncQueue,
+                          @NonNull Consumer<CompatUIEvent> callback,
+                          @Nullable ShellTaskOrganizer.TaskListener taskListener,
+                          @Nullable DisplayLayout displayLayout,
+                          @NonNull CompatUIHintsState compatUIHintsState,
+                          @NonNull CompatUIConfiguration compatUIConfiguration,
+                          @NonNull Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>>
+                                  onRestartButtonClicked) {
         super(context, taskInfo, syncQueue, taskListener, displayLayout);
         mCallback = callback;
         mHasSizeCompat = taskInfo.appCompatTaskInfo.topActivityInSizeCompat;
@@ -122,7 +132,7 @@
         updateVisibilityOfViews();
 
         if (mHasSizeCompat) {
-            mCallback.onSizeCompatRestartButtonAppeared(mTaskId);
+            mCallback.accept(new SizeCompatRestartButtonAppeared(mTaskId));
         }
 
         return mLayout;
@@ -177,7 +187,7 @@
                 mCameraCompatControlState == CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED
                         ? CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED
                         : CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
-        mCallback.onCameraControlStateUpdated(mTaskId, mCameraCompatControlState);
+        mCallback.accept(new CameraControlStateUpdated(mTaskId, mCameraCompatControlState));
         mLayout.updateCameraTreatmentButton(mCameraCompatControlState);
     }
 
@@ -188,7 +198,7 @@
             return;
         }
         mCameraCompatControlState = CAMERA_COMPAT_CONTROL_DISMISSED;
-        mCallback.onCameraControlStateUpdated(mTaskId, CAMERA_COMPAT_CONTROL_DISMISSED);
+        mCallback.accept(new CameraControlStateUpdated(mTaskId, CAMERA_COMPAT_CONTROL_DISMISSED));
         mLayout.setCameraControlVisibility(/* show= */ false);
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIEvent.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIEvent.kt
new file mode 100644
index 0000000..4a0cf98
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIEvent.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.api
+
+/**
+ * Abstraction for all the possible Compat UI Component events.
+ */
+interface CompatUIEvent {
+    /**
+     * Unique event identifier
+     */
+    val eventId: Int
+
+    @Suppress("UNCHECKED_CAST")
+    fun <T : CompatUIEvent> asType(): T? = this as? T
+
+    fun <T : CompatUIEvent> asType(clazz: Class<T>): T? {
+        return if (clazz.isInstance(this)) clazz.cast(this) else null
+    }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIHandler.kt
new file mode 100644
index 0000000..817e554
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIHandler.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.api
+
+import java.util.function.Consumer
+
+/**
+ * Abstraction for the objects responsible to handle all the CompatUI components and the
+ * communication with the server.
+ */
+interface CompatUIHandler {
+    /**
+     * Invoked when a new model is coming from the server.
+     */
+    fun onCompatInfoChanged(compatUIInfo: CompatUIInfo)
+
+    /**
+     * Optional reference to the object responsible to send {@link CompatUIEvent}
+     */
+    fun setCallback(compatUIEventSender: Consumer<CompatUIEvent>?)
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIInfo.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIInfo.kt
new file mode 100644
index 0000000..dbbf049
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/api/CompatUIInfo.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.api
+
+import android.app.TaskInfo
+import com.android.wm.shell.ShellTaskOrganizer
+
+/**
+ * Encapsulate the info of the message from core.
+ */
+data class CompatUIInfo(val taskInfo: TaskInfo, val listener: ShellTaskOrganizer.TaskListener?)
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/CompatUIEvents.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/CompatUIEvents.kt
new file mode 100644
index 0000000..58ce8ed
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/CompatUIEvents.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.impl
+
+import android.app.AppCompatTaskInfo
+import android.app.CameraCompatTaskInfo
+import com.android.wm.shell.compatui.api.CompatUIEvent
+
+internal const val SIZE_COMPAT_RESTART_BUTTON_APPEARED = 0
+internal const val SIZE_COMPAT_RESTART_BUTTON_CLICKED = 1
+internal const val CAMERA_CONTROL_STATE_UPDATE = 2
+
+/**
+ * All the {@link CompatUIEvent} the Compat UI Framework can handle
+ */
+sealed class CompatUIEvents(override val eventId: Int) : CompatUIEvent {
+    /** Sent when the size compat restart button appears. */
+    data class SizeCompatRestartButtonAppeared(val taskId: Int) :
+            CompatUIEvents(SIZE_COMPAT_RESTART_BUTTON_APPEARED)
+
+    /** Sent when the size compat restart button is clicked. */
+    data class SizeCompatRestartButtonClicked(val taskId: Int) :
+            CompatUIEvents(SIZE_COMPAT_RESTART_BUTTON_CLICKED)
+
+    /** Sent when the camera compat control state is updated. */
+    data class CameraControlStateUpdated(
+            val taskId: Int,
+            @CameraCompatTaskInfo.CameraCompatControlState val state: Int
+    ) : CompatUIEvents(CAMERA_CONTROL_STATE_UPDATE)
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandler.kt
new file mode 100644
index 0000000..a181eaf
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/impl/DefaultCompatUIHandler.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.impl
+
+import com.android.wm.shell.compatui.api.CompatUIEvent
+import com.android.wm.shell.compatui.api.CompatUIHandler
+import com.android.wm.shell.compatui.api.CompatUIInfo
+import java.util.function.Consumer
+
+/**
+ * Default implementation of {@link CompatUIHandler} to handle CompatUI components
+ */
+class DefaultCompatUIHandler : CompatUIHandler {
+
+    private var compatUIEventSender: Consumer<CompatUIEvent>? = null
+    override fun onCompatInfoChanged(compatUIInfo: CompatUIInfo) {
+        // Empty at the moment
+    }
+
+    override fun setCallback(compatUIEventSender: Consumer<CompatUIEvent>?) {
+        this.compatUIEventSender = compatUIEventSender
+    }
+}
\ No newline at end of file
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 609e5af..9bdc0b2 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
@@ -71,6 +71,8 @@
 import com.android.wm.shell.compatui.CompatUIConfiguration;
 import com.android.wm.shell.compatui.CompatUIController;
 import com.android.wm.shell.compatui.CompatUIShellCommandHandler;
+import com.android.wm.shell.compatui.api.CompatUIHandler;
+import com.android.wm.shell.compatui.impl.DefaultCompatUIHandler;
 import com.android.wm.shell.desktopmode.DesktopMode;
 import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
 import com.android.wm.shell.desktopmode.DesktopTasksController;
@@ -88,12 +90,12 @@
 import com.android.wm.shell.recents.RecentTasksController;
 import com.android.wm.shell.recents.RecentsTransitionHandler;
 import com.android.wm.shell.recents.TaskStackTransitionObserver;
-import com.android.wm.shell.shared.DesktopModeStatus;
 import com.android.wm.shell.shared.ShellTransitions;
 import com.android.wm.shell.shared.annotations.ShellAnimationThread;
 import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
 import com.android.wm.shell.shared.annotations.ShellMainThread;
 import com.android.wm.shell.shared.annotations.ShellSplashscreenThread;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.splitscreen.SplitScreen;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 import com.android.wm.shell.startingsurface.StartingSurface;
@@ -211,7 +213,7 @@
             Context context,
             ShellInit shellInit,
             ShellCommandHandler shellCommandHandler,
-            Optional<CompatUIController> compatUI,
+            Optional<CompatUIHandler> compatUI,
             Optional<UnfoldAnimationController> unfoldAnimationController,
             Optional<RecentTasksController> recentTasksOptional,
             @ShellMainThread ShellExecutor mainExecutor) {
@@ -230,7 +232,7 @@
 
     @WMSingleton
     @Provides
-    static Optional<CompatUIController> provideCompatUIController(
+    static Optional<CompatUIHandler> provideCompatUIController(
             Context context,
             ShellInit shellInit,
             ShellController shellController,
@@ -247,6 +249,9 @@
         if (!context.getResources().getBoolean(R.bool.config_enableCompatUIController)) {
             return Optional.empty();
         }
+        if (Flags.appCompatUiFramework()) {
+            return Optional.of(new DefaultCompatUIHandler());
+        }
         return Optional.of(
                 new CompatUIController(
                         context,
@@ -898,7 +903,7 @@
         // Use optional-of-lazy for the dependency that this provider relies on.
         // Lazy ensures that this provider will not be the cause the dependency is created
         // when it will not be returned due to the condition below.
-        return desktopTasksController.flatMap((lazy)-> {
+        return desktopTasksController.flatMap((lazy) -> {
             if (DesktopModeStatus.canEnterDesktopMode(context)) {
                 return Optional.of(lazy.get());
             }
@@ -917,7 +922,7 @@
         // Use optional-of-lazy for the dependency that this provider relies on.
         // Lazy ensures that this provider will not be the cause the dependency is created
         // when it will not be returned due to the condition below.
-        return desktopModeTaskRepository.flatMap((lazy)-> {
+        return desktopModeTaskRepository.flatMap((lazy) -> {
             if (DesktopModeStatus.canEnterDesktopMode(context)) {
                 return Optional.of(lazy.get());
             }
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 87bd840..eeceaa9 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
@@ -17,6 +17,7 @@
 package com.android.wm.shell.dagger;
 
 import android.annotation.Nullable;
+import android.app.KeyguardManager;
 import android.content.Context;
 import android.content.pm.LauncherApps;
 import android.os.Handler;
@@ -76,10 +77,10 @@
 import com.android.wm.shell.pip.PipTransitionController;
 import com.android.wm.shell.recents.RecentTasksController;
 import com.android.wm.shell.recents.RecentsTransitionHandler;
-import com.android.wm.shell.shared.DesktopModeStatus;
 import com.android.wm.shell.shared.annotations.ShellAnimationThread;
 import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
 import com.android.wm.shell.shared.annotations.ShellMainThread;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 import com.android.wm.shell.sysui.ShellCommandHandler;
 import com.android.wm.shell.sysui.ShellController;
@@ -220,7 +221,8 @@
             SyncTransactionQueue syncQueue,
             Transitions transitions,
             Optional<DesktopTasksController> desktopTasksController,
-            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
+            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+            InteractionJankMonitor interactionJankMonitor) {
         if (DesktopModeStatus.canEnterDesktopMode(context)) {
             return new DesktopModeWindowDecorViewModel(
                     context,
@@ -237,7 +239,8 @@
                     syncQueue,
                     transitions,
                     desktopTasksController,
-                    rootTaskDisplayAreaOrganizer);
+                    rootTaskDisplayAreaOrganizer,
+                    interactionJankMonitor);
         }
         return new CaptionWindowDecorViewModel(
                 context,
@@ -512,6 +515,7 @@
             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
             DragAndDropController dragAndDropController,
             Transitions transitions,
+            KeyguardManager keyguardManager,
             EnterDesktopTaskTransitionHandler enterDesktopTransitionHandler,
             ExitDesktopTaskTransitionHandler exitDesktopTransitionHandler,
             ToggleResizeDesktopTaskTransitionHandler toggleResizeDesktopTaskTransitionHandler,
@@ -526,7 +530,7 @@
             Optional<RecentTasksController> recentTasksController) {
         return new DesktopTasksController(context, shellInit, shellCommandHandler, shellController,
                 displayController, shellTaskOrganizer, syncQueue, rootTaskDisplayAreaOrganizer,
-                dragAndDropController, transitions, enterDesktopTransitionHandler,
+                dragAndDropController, transitions, keyguardManager, enterDesktopTransitionHandler,
                 exitDesktopTransitionHandler, toggleResizeDesktopTaskTransitionHandler,
                 dragToDesktopTransitionHandler, desktopModeTaskRepository,
                 desktopModeLoggerTransitionObserver, launchAdjacentController,
@@ -573,17 +577,18 @@
     @WMSingleton
     @Provides
     static ToggleResizeDesktopTaskTransitionHandler provideToggleResizeDesktopTaskTransitionHandler(
-            Transitions transitions) {
-        return new ToggleResizeDesktopTaskTransitionHandler(transitions);
+            Transitions transitions, InteractionJankMonitor interactionJankMonitor) {
+        return new ToggleResizeDesktopTaskTransitionHandler(transitions, interactionJankMonitor);
     }
 
     @WMSingleton
     @Provides
     static ExitDesktopTaskTransitionHandler provideExitDesktopTaskTransitionHandler(
             Transitions transitions,
-            Context context
-    ) {
-        return new ExitDesktopTaskTransitionHandler(transitions, context);
+            Context context,
+            InteractionJankMonitor interactionJankMonitor) {
+        return new ExitDesktopTaskTransitionHandler(
+            transitions, context, interactionJankMonitor);
     }
 
     @WMSingleton
@@ -599,11 +604,12 @@
             Context context,
             Optional<DesktopModeTaskRepository> desktopModeTaskRepository,
             Transitions transitions,
+            ShellTaskOrganizer shellTaskOrganizer,
             ShellInit shellInit
     ) {
         return desktopModeTaskRepository.flatMap(repository ->
                 Optional.of(new DesktopTasksTransitionObserver(
-                        context, repository, transitions, shellInit))
+                        context, repository, transitions, shellTaskOrganizer, shellInit))
         );
     }
 
@@ -642,6 +648,7 @@
             ShellInit shellInit,
             ShellController shellController,
             ShellCommandHandler shellCommandHandler,
+            ShellTaskOrganizer shellTaskOrganizer,
             DisplayController displayController,
             UiEventLogger uiEventLogger,
             IconProvider iconProvider,
@@ -649,8 +656,8 @@
             Transitions transitions,
             @ShellMainThread ShellExecutor mainExecutor) {
         return new DragAndDropController(context, shellInit, shellController, shellCommandHandler,
-                displayController, uiEventLogger, iconProvider, globalDragListener, transitions,
-                mainExecutor);
+                shellTaskOrganizer, displayController, uiEventLogger, iconProvider,
+                globalDragListener, transitions, mainExecutor);
     }
 
     //
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java
index 677fd5d..240cf3b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip1Module.java
@@ -212,12 +212,13 @@
     @WMSingleton
     @Provides
     static PipMotionHelper providePipMotionHelper(Context context,
+            @ShellMainThread ShellExecutor mainExecutor,
             PipBoundsState pipBoundsState, PipTaskOrganizer pipTaskOrganizer,
             PhonePipMenuController menuController, PipSnapAlgorithm pipSnapAlgorithm,
             PipTransitionController pipTransitionController,
             FloatingContentCoordinator floatingContentCoordinator,
             Optional<PipPerfHintController> pipPerfHintControllerOptional) {
-        return new PipMotionHelper(context, pipBoundsState, pipTaskOrganizer,
+        return new PipMotionHelper(context, mainExecutor, pipBoundsState, pipTaskOrganizer,
                 menuController, pipSnapAlgorithm, pipTransitionController,
                 floatingContentCoordinator, pipPerfHintControllerOptional);
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
index 9192e6e..400882a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeEventLogger.kt
@@ -16,9 +16,9 @@
 
 package com.android.wm.shell.desktopmode
 
+import com.android.internal.protolog.ProtoLog
 import com.android.internal.util.FrameworkStatsLog
 import com.android.wm.shell.protolog.ShellProtoLogGroup
-import com.android.wm.shell.util.KtProtoLog
 
 /** Event logger for logging desktop mode session events */
 class DesktopModeEventLogger {
@@ -27,7 +27,7 @@
      * entering desktop mode
      */
     fun logSessionEnter(sessionId: Int, enterReason: EnterReason) {
-        KtProtoLog.v(
+        ProtoLog.v(
             ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
             "DesktopModeLogger: Logging session enter, session: %s reason: %s",
             sessionId,
@@ -47,7 +47,7 @@
      * exiting desktop mode
      */
     fun logSessionExit(sessionId: Int, exitReason: ExitReason) {
-        KtProtoLog.v(
+        ProtoLog.v(
             ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
             "DesktopModeLogger: Logging session exit, session: %s reason: %s",
             sessionId,
@@ -67,7 +67,7 @@
      * session id [sessionId]
      */
     fun logTaskAdded(sessionId: Int, taskUpdate: TaskUpdate) {
-        KtProtoLog.v(
+        ProtoLog.v(
             ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
             "DesktopModeLogger: Logging task added, session: %s taskId: %s",
             sessionId,
@@ -99,7 +99,7 @@
      * session id [sessionId]
      */
     fun logTaskRemoved(sessionId: Int, taskUpdate: TaskUpdate) {
-        KtProtoLog.v(
+        ProtoLog.v(
             ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
             "DesktopModeLogger: Logging task remove, session: %s taskId: %s",
             sessionId,
@@ -131,7 +131,7 @@
      * having session id [sessionId]
      */
     fun logTaskInfoChanged(sessionId: Int, taskUpdate: TaskUpdate) {
-        KtProtoLog.v(
+        ProtoLog.v(
             ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
             "DesktopModeLogger: Logging task info changed, session: %s taskId: %s",
             sessionId,
@@ -159,13 +159,24 @@
     }
 
     companion object {
+        /**
+         * Describes a task position and dimensions.
+         *
+         * @property instanceId instance id of the task
+         * @property uid uid of the app associated with the task
+         * @property taskHeight height of the task in px
+         * @property taskWidth width of the task in px
+         * @property taskX x-coordinate of the top-left corner
+         * @property taskY y-coordinate of the top-left corner
+         *
+         */
         data class TaskUpdate(
             val instanceId: Int,
             val uid: Int,
-            val taskHeight: Int = Int.MIN_VALUE,
-            val taskWidth: Int = Int.MIN_VALUE,
-            val taskX: Int = Int.MIN_VALUE,
-            val taskY: Int = Int.MIN_VALUE,
+            val taskHeight: Int,
+            val taskWidth: Int,
+            val taskX: Int,
+            val taskY: Int,
         )
 
         /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
index 641952b..066b5ad 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
@@ -35,7 +35,7 @@
 import androidx.core.util.putAll
 import com.android.internal.logging.InstanceId
 import com.android.internal.logging.InstanceIdSequence
-import com.android.internal.protolog.common.ProtoLog
+import com.android.internal.protolog.ProtoLog
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.EnterReason
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ExitReason
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.TaskUpdate
@@ -46,11 +46,10 @@
 import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_DESKTOP_MODE_KEYBOARD_SHORTCUT
 import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_DESKTOP_MODE_TASK_DRAG
 import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
-import com.android.wm.shell.shared.DesktopModeStatus
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
 import com.android.wm.shell.shared.TransitionUtil
 import com.android.wm.shell.sysui.ShellInit
 import com.android.wm.shell.transition.Transitions
-import com.android.wm.shell.util.KtProtoLog
 
 /**
  * A [Transitions.TransitionObserver] that observes transitions and the proposed changes to log
@@ -106,7 +105,7 @@
     ) {
         // this was a new recents animation
         if (info.isExitToRecentsTransition() && tasksSavedForRecents.isEmpty()) {
-            KtProtoLog.v(
+            ProtoLog.v(
                 WM_SHELL_DESKTOP_MODE,
                 "DesktopModeLogger: Recents animation running, saving tasks for later"
             )
@@ -132,7 +131,7 @@
                 info.flags == 0 &&
                 tasksSavedForRecents.isNotEmpty()
         ) {
-            KtProtoLog.v(
+            ProtoLog.v(
                 WM_SHELL_DESKTOP_MODE,
                 "DesktopModeLogger: Canceled recents animation, restoring tasks"
             )
@@ -202,7 +201,7 @@
             }
         }
 
-        KtProtoLog.v(
+        ProtoLog.v(
             WM_SHELL_DESKTOP_MODE,
             "DesktopModeLogger: taskInfo map after processing changes %s",
             postTransitionFreeformTasks.size()
@@ -282,17 +281,23 @@
         visibleFreeformTaskInfos.putAll(postTransitionVisibleFreeformTasks)
     }
 
-    // TODO(b/326231724) - Add logging around taskInfoChanges Updates
     /** Compare the old and new state of taskInfos and identify and log the changes */
     private fun identifyAndLogTaskUpdates(
         sessionId: Int,
         preTransitionVisibleFreeformTasks: SparseArray<TaskInfo>,
         postTransitionVisibleFreeformTasks: SparseArray<TaskInfo>
     ) {
-        // find new tasks that were added
         postTransitionVisibleFreeformTasks.forEach { taskId, taskInfo ->
-            if (!preTransitionVisibleFreeformTasks.containsKey(taskId)) {
-                desktopModeEventLogger.logTaskAdded(sessionId, buildTaskUpdateForTask(taskInfo))
+            val currentTaskUpdate = buildTaskUpdateForTask(taskInfo)
+            val previousTaskInfo = preTransitionVisibleFreeformTasks[taskId]
+            when {
+                // new tasks added
+                previousTaskInfo == null ->
+                    desktopModeEventLogger.logTaskAdded(sessionId, currentTaskUpdate)
+                // old tasks that were resized or repositioned
+                // TODO(b/347935387): Log changes only once they are stable.
+                buildTaskUpdateForTask(previousTaskInfo) != currentTaskUpdate ->
+                    desktopModeEventLogger.logTaskInfoChanged(sessionId, currentTaskUpdate)
             }
         }
 
@@ -304,13 +309,17 @@
         }
     }
 
-    // TODO(b/326231724: figure out how to get taskWidth and taskHeight from TaskInfo
     private fun buildTaskUpdateForTask(taskInfo: TaskInfo): TaskUpdate {
-        val taskUpdate = TaskUpdate(taskInfo.taskId, taskInfo.userId)
-        // add task x, y if available
-        taskInfo.positionInParent?.let { taskUpdate.copy(taskX = it.x, taskY = it.y) }
-
-        return taskUpdate
+        val screenBounds = taskInfo.configuration.windowConfiguration.bounds
+        val positionInParent = taskInfo.positionInParent
+        return TaskUpdate(
+            instanceId = taskInfo.taskId,
+            uid = taskInfo.userId,
+            taskHeight = screenBounds.height(),
+            taskWidth = screenBounds.width(),
+            taskX = positionInParent.x,
+            taskY = positionInParent.y,
+        )
     }
 
     /** Get [EnterReason] for this session enter */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
index 7d01580..ca05864 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
@@ -26,8 +26,8 @@
 import androidx.core.util.forEach
 import androidx.core.util.keyIterator
 import androidx.core.util.valueIterator
+import com.android.internal.protolog.ProtoLog
 import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
-import com.android.wm.shell.util.KtProtoLog
 import java.io.PrintWriter
 import java.util.concurrent.Executor
 import java.util.function.Consumer
@@ -46,6 +46,9 @@
         val activeTasks: ArraySet<Int> = ArraySet(),
         val visibleTasks: ArraySet<Int> = ArraySet(),
         val minimizedTasks: ArraySet<Int> = ArraySet(),
+        // Tasks that are closing, but are still visible
+        // TODO(b/332682201): Remove when the repository state is updated via TransitionObserver
+        val closingTasks: ArraySet<Int> = ArraySet(),
         // Tasks currently in freeform mode, ordered from top to bottom (top is at index 0).
         val freeformTasksInZOrder: ArrayList<Int> = ArrayList(),
     )
@@ -139,7 +142,7 @@
 
         val added = displayData.getOrCreate(displayId).activeTasks.add(taskId)
         if (added) {
-            KtProtoLog.d(
+            ProtoLog.d(
                 WM_SHELL_DESKTOP_MODE,
                 "DesktopTaskRepo: add active task=%d displayId=%d",
                 taskId,
@@ -164,11 +167,47 @@
             }
         }
         if (result) {
-            KtProtoLog.d(WM_SHELL_DESKTOP_MODE, "DesktopTaskRepo: remove active task=%d", taskId)
+            ProtoLog.d(WM_SHELL_DESKTOP_MODE, "DesktopTaskRepo: remove active task=%d", taskId)
         }
         return result
     }
 
+    /**
+     * Mark a task with given [taskId] as closing on given [displayId]
+     *
+     * @return `true` if the task was not closing on given [displayId]
+     */
+    fun addClosingTask(displayId: Int, taskId: Int): Boolean {
+        val added = displayData.getOrCreate(displayId).closingTasks.add(taskId)
+        if (added) {
+            ProtoLog.d(
+                WM_SHELL_DESKTOP_MODE,
+                "DesktopTaskRepo: added closing task=%d displayId=%d",
+                taskId,
+                displayId
+            )
+        }
+        return added
+    }
+
+    /**
+     * Remove task with given [taskId] from closing tasks.
+     *
+     * @return `true` if the task was closing
+     */
+    fun removeClosingTask(taskId: Int): Boolean {
+        var removed = false
+        displayData.forEach { _, data ->
+            if (data.closingTasks.remove(taskId)) {
+                removed = true
+            }
+        }
+        if (removed) {
+            ProtoLog.d(WM_SHELL_DESKTOP_MODE, "DesktopTaskRepo: remove closing task=%d", taskId)
+        }
+        return removed
+    }
+
     /** Check if a task with the given [taskId] was marked as an active task */
     fun isActiveTask(taskId: Int): Boolean {
         return displayData.valueIterator().asSequence().any { data ->
@@ -176,6 +215,10 @@
         }
     }
 
+    /** Check if a task with the given [taskId] was marked as a closing task */
+    fun isClosingTask(taskId: Int): Boolean =
+        displayData.valueIterator().asSequence().any { data -> taskId in data.closingTasks }
+
     /** Whether a task is visible. */
     fun isVisibleTask(taskId: Int): Boolean {
         return displayData.valueIterator().asSequence().any { data ->
@@ -190,18 +233,27 @@
         }
     }
 
-    /** Check if a task with the given [taskId] is the only active task on its display */
-    fun isOnlyActiveTask(taskId: Int): Boolean {
-        return displayData.valueIterator().asSequence().any { data ->
-            data.activeTasks.singleOrNull() == taskId
+    /**
+     * Check if a task with the given [taskId] is the only visible, non-closing, not-minimized task
+     * on its display
+     */
+    fun isOnlyVisibleNonClosingTask(taskId: Int): Boolean =
+        displayData.valueIterator().asSequence().any { data ->
+            data.visibleTasks
+                .subtract(data.closingTasks)
+                .subtract(data.minimizedTasks)
+                .singleOrNull() == taskId
         }
-    }
 
     /** Get a set of the active tasks for given [displayId] */
     fun getActiveTasks(displayId: Int): ArraySet<Int> {
         return ArraySet(displayData[displayId]?.activeTasks)
     }
 
+    /** Returns the minimized tasks for the given [displayId]. */
+    fun getMinimizedTasks(displayId: Int): ArraySet<Int> =
+        ArraySet(displayData[displayId]?.minimizedTasks)
+
     /**
      * Returns whether Desktop Mode is currently showing any tasks, i.e. whether any Desktop Tasks
      * are visible.
@@ -264,14 +316,14 @@
 
         // Check if count changed
         if (prevCount != newCount) {
-            KtProtoLog.d(
+            ProtoLog.d(
                 WM_SHELL_DESKTOP_MODE,
                 "DesktopTaskRepo: update task visibility taskId=%d visible=%b displayId=%d",
                 taskId,
                 visible,
                 displayId
             )
-            KtProtoLog.d(
+            ProtoLog.d(
                 WM_SHELL_DESKTOP_MODE,
                 "DesktopTaskRepo: visibleTaskCount has changed from %d to %d",
                 prevCount,
@@ -289,7 +341,7 @@
 
     /** Get number of tasks that are marked as visible on given [displayId] */
     fun getVisibleTaskCount(displayId: Int): Int {
-        KtProtoLog.d(
+        ProtoLog.d(
             WM_SHELL_DESKTOP_MODE,
             "DesktopTaskRepo: visibleTaskCount= %d",
             displayData[displayId]?.visibleTasks?.size ?: 0
@@ -301,7 +353,7 @@
     // TODO(b/342417921): Identify if there is additional checks needed to move tasks for
     // multi-display scenarios.
     fun addOrMoveFreeformTaskToTop(displayId: Int, taskId: Int) {
-        KtProtoLog.d(
+        ProtoLog.d(
             WM_SHELL_DESKTOP_MODE,
             "DesktopTaskRepo: add or move task to top: display=%d, taskId=%d",
             displayId,
@@ -313,7 +365,7 @@
 
     /** Mark a Task as minimized. */
     fun minimizeTask(displayId: Int, taskId: Int) {
-        KtProtoLog.v(
+        ProtoLog.v(
             WM_SHELL_DESKTOP_MODE,
             "DesktopModeTaskRepository: minimize Task: display=%d, task=%d",
             displayId,
@@ -324,7 +376,7 @@
 
     /** Mark a Task as non-minimized. */
     fun unminimizeTask(displayId: Int, taskId: Int) {
-        KtProtoLog.v(
+        ProtoLog.v(
             WM_SHELL_DESKTOP_MODE,
             "DesktopModeTaskRepository: unminimize Task: display=%d, task=%d",
             displayId,
@@ -335,7 +387,7 @@
 
     /** Remove the task from the ordered list. */
     fun removeFreeformTask(displayId: Int, taskId: Int) {
-        KtProtoLog.d(
+        ProtoLog.d(
             WM_SHELL_DESKTOP_MODE,
             "DesktopTaskRepo: remove freeform task from ordered list: display=%d, taskId=%d",
             displayId,
@@ -343,7 +395,7 @@
         )
         displayData[displayId]?.freeformTasksInZOrder?.remove(taskId)
         boundsBeforeMaximizeByTaskId.remove(taskId)
-        KtProtoLog.d(
+        ProtoLog.d(
             WM_SHELL_DESKTOP_MODE,
             "DesktopTaskRepo: remaining freeform tasks: %s",
             displayData[displayId]?.freeformTasksInZOrder?.toDumpString() ?: ""
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
index 217b1d3..1bf1259 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeUtils.kt
@@ -19,6 +19,8 @@
 package com.android.wm.shell.desktopmode
 
 import android.app.ActivityManager.RunningTaskInfo
+import android.app.TaskInfo
+import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
 import android.content.pm.ActivityInfo.isFixedOrientationLandscape
 import android.content.pm.ActivityInfo.isFixedOrientationPortrait
 import android.content.res.Configuration.ORIENTATION_LANDSCAPE
@@ -105,7 +107,7 @@
  * Calculates the largest size that can fit in a given area while maintaining a specific aspect
  * ratio.
  */
-private fun maximumSizeMaintainingAspectRatio(
+fun maximumSizeMaintainingAspectRatio(
     taskInfo: RunningTaskInfo,
     targetArea: Size,
     aspectRatio: Float
@@ -114,7 +116,8 @@
     val targetWidth = targetArea.width
     val finalHeight: Int
     val finalWidth: Int
-    if (isFixedOrientationPortrait(taskInfo.topActivityInfo!!.screenOrientation)) {
+    // Get orientation either through top activity or task's orientation
+    if (taskInfo.hasPortraitTopActivity()) {
         val tempWidth = (targetHeight / aspectRatio).toInt()
         if (tempWidth <= targetWidth) {
             finalHeight = targetHeight
@@ -137,7 +140,7 @@
 }
 
 /** Calculates the aspect ratio of an activity from its fullscreen bounds. */
-private fun calculateAspectRatio(taskInfo: RunningTaskInfo): Float {
+fun calculateAspectRatio(taskInfo: RunningTaskInfo): Float {
     if (taskInfo.appCompatTaskInfo.topActivityBoundsLetterboxed) {
         val appLetterboxWidth = taskInfo.appCompatTaskInfo.topActivityLetterboxWidth
         val appLetterboxHeight = taskInfo.appCompatTaskInfo.topActivityLetterboxHeight
@@ -171,3 +174,41 @@
         desiredSize.height + heightOffset
     )
 }
+
+/**
+ * Adjusts bounds to be positioned in the middle of the area provided, not necessarily the
+ * entire screen, as area can be offset by left and top start.
+ */
+fun centerInArea(desiredSize: Size, areaBounds: Rect, leftStart: Int, topStart: Int): Rect {
+    val heightOffset = (areaBounds.height() - desiredSize.height) / 2
+    val widthOffset = (areaBounds.width() - desiredSize.width) / 2
+
+    val newLeft = leftStart + widthOffset
+    val newTop = topStart + heightOffset
+    val newRight = newLeft + desiredSize.width
+    val newBottom = newTop + desiredSize.height
+
+    return Rect(newLeft, newTop, newRight, newBottom)
+}
+
+fun TaskInfo.hasPortraitTopActivity(): Boolean {
+    val topActivityScreenOrientation =
+        topActivityInfo?.screenOrientation ?: SCREEN_ORIENTATION_UNSPECIFIED
+    val appBounds = configuration.windowConfiguration.appBounds
+
+    return when {
+        // First check if activity has portrait screen orientation
+        topActivityScreenOrientation != SCREEN_ORIENTATION_UNSPECIFIED -> {
+            isFixedOrientationPortrait(topActivityScreenOrientation)
+        }
+
+        // Then check if the activity is portrait when letterboxed
+        appCompatTaskInfo.topActivityBoundsLetterboxed -> appCompatTaskInfo.isTopActivityPillarboxed
+
+        // Then check if the activity is portrait
+        appBounds != null -> appBounds.height() > appBounds.width()
+
+        // Otherwise just take the orientation of the task
+        else -> isFixedOrientationPortrait(configuration.orientation)
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index c5111d6..18157d6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -18,6 +18,7 @@
 
 import android.app.ActivityManager.RunningTaskInfo
 import android.app.ActivityOptions
+import android.app.KeyguardManager
 import android.app.PendingIntent
 import android.app.TaskInfo
 import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
@@ -35,12 +36,12 @@
 import android.graphics.Region
 import android.os.IBinder
 import android.os.SystemProperties
+import android.util.Size
 import android.view.Display.DEFAULT_DISPLAY
 import android.view.SurfaceControl
 import android.view.WindowManager.TRANSIT_CHANGE
 import android.view.WindowManager.TRANSIT_NONE
 import android.view.WindowManager.TRANSIT_OPEN
-import android.view.WindowManager.TRANSIT_TO_BACK
 import android.view.WindowManager.TRANSIT_TO_FRONT
 import android.window.RemoteTransition
 import android.window.TransitionInfo
@@ -49,6 +50,7 @@
 import androidx.annotation.BinderThread
 import com.android.internal.annotations.VisibleForTesting
 import com.android.internal.policy.ScreenDecorationsUtils
+import com.android.internal.protolog.ProtoLog
 import com.android.window.flags.Flags
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer
 import com.android.wm.shell.ShellTaskOrganizer
@@ -65,7 +67,7 @@
 import com.android.wm.shell.common.desktopmode.DesktopModeTransitionSource
 import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
 import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
-import com.android.wm.shell.compatui.isSingleTopActivityTranslucent
+import com.android.wm.shell.compatui.isTopActivityExemptFromDesktopWindowing
 import com.android.wm.shell.desktopmode.DesktopModeTaskRepository.VisibleTasksListener
 import com.android.wm.shell.desktopmode.DragToDesktopTransitionHandler.DragToDesktopStateListener
 import com.android.wm.shell.draganddrop.DragAndDropController
@@ -73,9 +75,10 @@
 import com.android.wm.shell.recents.RecentTasksController
 import com.android.wm.shell.recents.RecentsTransitionHandler
 import com.android.wm.shell.recents.RecentsTransitionStateListener
-import com.android.wm.shell.shared.DesktopModeStatus
-import com.android.wm.shell.shared.DesktopModeStatus.DESKTOP_DENSITY_OVERRIDE
-import com.android.wm.shell.shared.DesktopModeStatus.useDesktopOverrideDensity
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus.DESKTOP_DENSITY_OVERRIDE
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus.useDesktopOverrideDensity
+import com.android.wm.shell.shared.TransitionUtil
 import com.android.wm.shell.shared.annotations.ExternalThread
 import com.android.wm.shell.shared.annotations.ShellMainThread
 import com.android.wm.shell.splitscreen.SplitScreenController
@@ -86,7 +89,6 @@
 import com.android.wm.shell.sysui.ShellSharedConstants
 import com.android.wm.shell.transition.OneShotRemoteHandler
 import com.android.wm.shell.transition.Transitions
-import com.android.wm.shell.util.KtProtoLog
 import com.android.wm.shell.windowdecor.DragPositioningCallbackUtility
 import com.android.wm.shell.windowdecor.MoveToDesktopAnimator
 import com.android.wm.shell.windowdecor.OnTaskResizeAnimationListener
@@ -108,6 +110,7 @@
     private val rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer,
     private val dragAndDropController: DragAndDropController,
     private val transitions: Transitions,
+    private val keyguardManager: KeyguardManager,
     private val enterDesktopTaskTransitionHandler: EnterDesktopTaskTransitionHandler,
     private val exitDesktopTaskTransitionHandler: ExitDesktopTaskTransitionHandler,
     private val toggleResizeDesktopTaskTransitionHandler: ToggleResizeDesktopTaskTransitionHandler,
@@ -155,8 +158,6 @@
                 visualIndicator = null
             }
         }
-    private val sysUIPackageName = context.resources.getString(
-        com.android.internal.R.string.config_systemUi)
 
     private val transitionAreaHeight
         get() =
@@ -185,7 +186,7 @@
     }
 
     private fun onInit() {
-        KtProtoLog.d(WM_SHELL_DESKTOP_MODE, "Initialize DesktopTasksController")
+        ProtoLog.d(WM_SHELL_DESKTOP_MODE, "Initialize DesktopTasksController")
         shellCommandHandler.addDumpCallback(this::dump, this)
         shellCommandHandler.addCommandCallback("desktopmode", desktopModeShellCommandHandler, this)
         shellController.addExternalInterface(
@@ -199,7 +200,7 @@
         recentsTransitionHandler.addTransitionStateListener(
             object : RecentsTransitionStateListener {
                 override fun onAnimationStateChanged(running: Boolean) {
-                    KtProtoLog.v(
+                    ProtoLog.v(
                         WM_SHELL_DESKTOP_MODE,
                         "DesktopTasksController: recents animation state changed running=%b",
                         running
@@ -216,11 +217,6 @@
         return visualIndicator
     }
 
-    // TODO(b/347289970): Consider replacing with API
-    private fun isSystemUIApplication(taskInfo: RunningTaskInfo): Boolean {
-        return taskInfo.baseActivity?.packageName == sysUIPackageName
-    }
-
     fun setOnTaskResizeAnimationListener(listener: OnTaskResizeAnimationListener) {
         toggleResizeDesktopTaskTransitionHandler.setOnTaskResizeAnimationListener(listener)
         enterDesktopTaskTransitionHandler.setOnTaskResizeAnimationListener(listener)
@@ -235,7 +231,7 @@
 
     /** Show all tasks, that are part of the desktop, on top of launcher */
     fun showDesktopApps(displayId: Int, remoteTransition: RemoteTransition? = null) {
-        KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: showDesktopApps")
+        ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: showDesktopApps")
         val wct = WindowContainerTransaction()
         bringDesktopAppsToFront(displayId, wct)
 
@@ -286,7 +282,7 @@
                     moveToDesktop(allFocusedTasks[0].taskId, transitionSource = transitionSource)
                 }
                 else -> {
-                    KtProtoLog.w(
+                    ProtoLog.w(
                         WM_SHELL_DESKTOP_MODE,
                         "DesktopTasksController: Cannot enter desktop, expected less " +
                             "than 3 focused tasks but found %d",
@@ -316,7 +312,7 @@
         transitionSource: DesktopModeTransitionSource,
     ): Boolean {
         recentTasksController?.findTaskInBackground(taskId)?.let {
-            KtProtoLog.v(
+            ProtoLog.v(
                 WM_SHELL_DESKTOP_MODE,
                 "DesktopTasksController: moveToDesktopFromNonRunningTask taskId=%d",
                 taskId
@@ -348,23 +344,16 @@
         wct: WindowContainerTransaction = WindowContainerTransaction(),
         transitionSource: DesktopModeTransitionSource,
     ) {
-        if (Flags.enableDesktopWindowingModalsPolicy() && isSingleTopActivityTranslucent(task)) {
-            KtProtoLog.w(
+        if (Flags.enableDesktopWindowingModalsPolicy()
+            && isTopActivityExemptFromDesktopWindowing(context, task)) {
+            ProtoLog.w(
                 WM_SHELL_DESKTOP_MODE,
                 "DesktopTasksController: Cannot enter desktop, " +
-                    "translucent top activity found. This is likely a modal dialog."
+                        "ineligible top activity found."
             )
             return
         }
-        if (isSystemUIApplication(task)) {
-            KtProtoLog.w(
-                WM_SHELL_DESKTOP_MODE,
-                "DesktopTasksController: Cannot enter desktop, " +
-                        "systemUI top activity found."
-            )
-            return
-        }
-        KtProtoLog.v(
+        ProtoLog.v(
             WM_SHELL_DESKTOP_MODE,
             "DesktopTasksController: moveToDesktop taskId=%d",
             task.taskId
@@ -391,7 +380,7 @@
         taskInfo: RunningTaskInfo,
         dragToDesktopValueAnimator: MoveToDesktopAnimator,
     ) {
-        KtProtoLog.v(
+        ProtoLog.v(
             WM_SHELL_DESKTOP_MODE,
             "DesktopTasksController: startDragToDesktop taskId=%d",
             taskInfo.taskId
@@ -407,14 +396,14 @@
      * [startDragToDesktop].
      */
     private fun finalizeDragToDesktop(taskInfo: RunningTaskInfo, freeformBounds: Rect) {
-        KtProtoLog.v(
+        ProtoLog.v(
             WM_SHELL_DESKTOP_MODE,
             "DesktopTasksController: finalizeDragToDesktop taskId=%d",
             taskInfo.taskId
         )
         val wct = WindowContainerTransaction()
         exitSplitIfApplicable(wct, taskInfo)
-        moveHomeTaskToFront(wct)
+        moveHomeTask(wct, toTop = true)
         val taskToMinimize =
             bringDesktopAppsToFrontBeforeShowingNewTask(taskInfo.displayId, wct, taskInfo.taskId)
         addMoveToDesktopChanges(wct, taskInfo)
@@ -442,12 +431,21 @@
      * active task.
      *
      * @param wct transaction to modify if the last active task is closed
+     * @param displayId display id of the window that's being closed
      * @param taskId task id of the window that's being closed
      */
-    fun onDesktopWindowClose(wct: WindowContainerTransaction, taskId: Int) {
-        if (desktopModeTaskRepository.isOnlyActiveTask(taskId)) {
+    fun onDesktopWindowClose(wct: WindowContainerTransaction, displayId: Int, taskId: Int) {
+        if (desktopModeTaskRepository.isOnlyVisibleNonClosingTask(taskId)) {
             removeWallpaperActivity(wct)
         }
+        if (!desktopModeTaskRepository.addClosingTask(displayId, taskId)) {
+            // Could happen if the task hasn't been removed from closing list after it disappeared
+            ProtoLog.w(
+                WM_SHELL_DESKTOP_MODE,
+                "DesktopTasksController: the task with taskId=%d is already closing!",
+                taskId
+            )
+        }
     }
 
     /** Move a task with given `taskId` to fullscreen */
@@ -466,7 +464,7 @@
 
     /** Move a desktop app to split screen. */
     fun moveToSplit(task: RunningTaskInfo) {
-        KtProtoLog.v(
+        ProtoLog.v(
             WM_SHELL_DESKTOP_MODE,
             "DesktopTasksController: moveToSplit taskId=%d",
             task.taskId
@@ -499,7 +497,7 @@
      * [startDragToDesktop].
      */
     fun cancelDragToDesktop(task: RunningTaskInfo) {
-        KtProtoLog.v(
+        ProtoLog.v(
             WM_SHELL_DESKTOP_MODE,
             "DesktopTasksController: cancelDragToDesktop taskId=%d",
             task.taskId
@@ -514,7 +512,7 @@
         position: Point,
         transitionSource: DesktopModeTransitionSource
     ) {
-        KtProtoLog.v(
+        ProtoLog.v(
             WM_SHELL_DESKTOP_MODE,
             "DesktopTasksController: moveToFullscreen with animation taskId=%d",
             task.taskId
@@ -542,7 +540,7 @@
 
     /** Move a task to the front */
     fun moveTaskToFront(taskInfo: RunningTaskInfo) {
-        KtProtoLog.v(
+        ProtoLog.v(
             WM_SHELL_DESKTOP_MODE,
             "DesktopTasksController: moveTaskToFront taskId=%d",
             taskInfo.taskId
@@ -573,10 +571,10 @@
     fun moveToNextDisplay(taskId: Int) {
         val task = shellTaskOrganizer.getRunningTaskInfo(taskId)
         if (task == null) {
-            KtProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToNextDisplay: taskId=%d not found", taskId)
+            ProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToNextDisplay: taskId=%d not found", taskId)
             return
         }
-        KtProtoLog.v(
+        ProtoLog.v(
             WM_SHELL_DESKTOP_MODE,
             "moveToNextDisplay: taskId=%d taskDisplayId=%d",
             taskId,
@@ -591,7 +589,7 @@
             newDisplayId = displayIds.firstOrNull { displayId -> displayId < task.displayId }
         }
         if (newDisplayId == null) {
-            KtProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToNextDisplay: next display not found")
+            ProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToNextDisplay: next display not found")
             return
         }
         moveToDisplay(task, newDisplayId)
@@ -603,7 +601,7 @@
      * No-op if task is already on that display per [RunningTaskInfo.displayId].
      */
     private fun moveToDisplay(task: RunningTaskInfo, displayId: Int) {
-        KtProtoLog.v(
+        ProtoLog.v(
             WM_SHELL_DESKTOP_MODE,
             "moveToDisplay: taskId=%d displayId=%d",
             task.taskId,
@@ -611,13 +609,13 @@
         )
 
         if (task.displayId == displayId) {
-            KtProtoLog.d(WM_SHELL_DESKTOP_MODE, "moveToDisplay: task already on display")
+            ProtoLog.d(WM_SHELL_DESKTOP_MODE, "moveToDisplay: task already on display")
             return
         }
 
         val displayAreaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(displayId)
         if (displayAreaInfo == null) {
-            KtProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToDisplay: display not found")
+            ProtoLog.w(WM_SHELL_DESKTOP_MODE, "moveToDisplay: display not found")
             return
         }
 
@@ -638,13 +636,21 @@
     fun toggleDesktopTaskSize(taskInfo: RunningTaskInfo) {
         val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return
 
-        val stableBounds = Rect()
-        displayLayout.getStableBounds(stableBounds)
+        val stableBounds = Rect().apply { displayLayout.getStableBounds(this) }
+        val currentTaskBounds = taskInfo.configuration.windowConfiguration.bounds
         val destinationBounds = Rect()
-        if (taskInfo.configuration.windowConfiguration.bounds == stableBounds) {
-            // The desktop task is currently occupying the whole stable bounds. If the bounds
-            // before the task was toggled to stable bounds were saved, toggle the task to those
-            // bounds. Otherwise, toggle to the default bounds.
+
+        val isMaximized = if (taskInfo.isResizeable) {
+            currentTaskBounds == stableBounds
+        } else {
+            currentTaskBounds.width() == stableBounds.width()
+                    || currentTaskBounds.height() == stableBounds.height()
+        }
+
+        if (isMaximized) {
+            // The desktop task is at the maximized width and/or height of the stable bounds.
+            // If the task's pre-maximize stable bounds were saved, toggle the task to those bounds.
+            // Otherwise, toggle to the default bounds.
             val taskBoundsBeforeMaximize =
                 desktopModeTaskRepository.removeBoundsBeforeMaximize(taskInfo.taskId)
             if (taskBoundsBeforeMaximize != null) {
@@ -659,9 +665,20 @@
         } else {
             // Save current bounds so that task can be restored back to original bounds if necessary
             // and toggle to the stable bounds.
-            val taskBounds = taskInfo.configuration.windowConfiguration.bounds
-            desktopModeTaskRepository.saveBoundsBeforeMaximize(taskInfo.taskId, taskBounds)
-            destinationBounds.set(stableBounds)
+            desktopModeTaskRepository.saveBoundsBeforeMaximize(taskInfo.taskId, currentTaskBounds)
+
+            if (taskInfo.isResizeable) {
+                // if resizable then expand to entire stable bounds (full display minus insets)
+                destinationBounds.set(stableBounds)
+            } else {
+                // if non-resizable then calculate max bounds according to aspect ratio
+                val activityAspectRatio = calculateAspectRatio(taskInfo)
+                val newSize = maximumSizeMaintainingAspectRatio(taskInfo,
+                    Size(stableBounds.width(), stableBounds.height()), activityAspectRatio)
+                val newBounds = centerInArea(
+                    newSize, stableBounds, stableBounds.left, stableBounds.top)
+                destinationBounds.set(newBounds)
+            }
         }
 
         val wct = WindowContainerTransaction().setBounds(taskInfo.token, destinationBounds)
@@ -753,7 +770,7 @@
         wct: WindowContainerTransaction,
         newTaskIdInFront: Int? = null
     ): RunningTaskInfo? {
-        KtProtoLog.v(
+        ProtoLog.v(
             WM_SHELL_DESKTOP_MODE,
             "DesktopTasksController: bringDesktopAppsToFront, newTaskIdInFront=%s",
             newTaskIdInFront ?: "null"
@@ -764,7 +781,7 @@
             addWallpaperActivity(wct)
         } else {
             // Move home to front
-            moveHomeTaskToFront(wct)
+            moveHomeTask(wct, toTop = true)
         }
 
         val nonMinimizedTasksOrderedFrontToBack =
@@ -790,15 +807,15 @@
         return taskToMinimize
     }
 
-    private fun moveHomeTaskToFront(wct: WindowContainerTransaction) {
+    private fun moveHomeTask(wct: WindowContainerTransaction, toTop: Boolean) {
         shellTaskOrganizer
             .getRunningTasks(context.displayId)
             .firstOrNull { task -> task.activityType == ACTIVITY_TYPE_HOME }
-            ?.let { homeTask -> wct.reorder(homeTask.getToken(), true /* onTop */) }
+            ?.let { homeTask -> wct.reorder(homeTask.getToken(), toTop /* onTop */) }
     }
 
     private fun addWallpaperActivity(wct: WindowContainerTransaction) {
-        KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: addWallpaper")
+        ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: addWallpaper")
         val intent = Intent(context, DesktopWallpaperActivity::class.java)
         val options =
             ActivityOptions.makeBasic().apply {
@@ -818,7 +835,7 @@
 
     private fun removeWallpaperActivity(wct: WindowContainerTransaction) {
         desktopModeTaskRepository.wallpaperActivityToken?.let { token ->
-            KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: removeWallpaper")
+            ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: removeWallpaper")
             wct.removeTask(token)
         }
     }
@@ -856,7 +873,7 @@
         transition: IBinder,
         request: TransitionRequestInfo
     ): WindowContainerTransaction? {
-        KtProtoLog.v(
+        ProtoLog.v(
             WM_SHELL_DESKTOP_MODE,
             "DesktopTasksController: handleRequest request=%s",
             request
@@ -870,8 +887,8 @@
                     reason = "recents animation is running"
                     false
                 }
-                // Handle back navigation for the last window if wallpaper available
-                shouldRemoveWallpaper(request) -> true
+                // Handle task closing for the last window if wallpaper is available
+                shouldHandleTaskClosing(request) -> true
                 // Only handle open or to front transitions
                 request.type != TRANSIT_OPEN && request.type != TRANSIT_TO_FRONT -> {
                     reason = "transition type not handled (${request.type})"
@@ -898,7 +915,7 @@
             }
 
         if (!shouldHandleRequest) {
-            KtProtoLog.v(
+            ProtoLog.v(
                 WM_SHELL_DESKTOP_MODE,
                 "DesktopTasksController: skipping handleRequest reason=%s",
                 reason
@@ -909,11 +926,10 @@
         val result =
             triggerTask?.let { task ->
                 when {
-                    request.type == TRANSIT_TO_BACK -> handleBackNavigation(task)
-                    // Check if the task has a top transparent activity
-                    shouldLaunchAsModal(task) -> handleIncompatibleTaskLaunch(task)
-                    // Check if the task has a top systemUI activity
-                    isSystemUIApplication(task) -> handleIncompatibleTaskLaunch(task)
+                    // Check if the closing task needs to be handled
+                    TransitionUtil.isClosingType(request.type) -> handleTaskClosing(task)
+                    // Check if the top task shouldn't be allowed to enter desktop mode
+                    isIncompatibleTask(task) -> handleIncompatibleTaskLaunch(task)
                     // Check if fullscreen task should be updated
                     task.isFullscreen -> handleFullscreenTaskLaunch(task, transition)
                     // Check if freeform task should be updated
@@ -923,7 +939,7 @@
                     }
                 }
             }
-        KtProtoLog.v(
+        ProtoLog.v(
             WM_SHELL_DESKTOP_MODE,
             "DesktopTasksController: handleRequest result=%s",
             result ?: "null"
@@ -947,28 +963,31 @@
             .forEach { finishTransaction.setCornerRadius(it.leash, cornerRadius) }
     }
 
-    // TODO(b/347289970): Consider replacing with API
-    private fun shouldLaunchAsModal(task: TaskInfo) =
-        Flags.enableDesktopWindowingModalsPolicy() && isSingleTopActivityTranslucent(task)
+    private fun isIncompatibleTask(task: TaskInfo) =
+        Flags.enableDesktopWindowingModalsPolicy()
+                && isTopActivityExemptFromDesktopWindowing(context, task)
 
-    private fun shouldRemoveWallpaper(request: TransitionRequestInfo): Boolean {
+    private fun shouldHandleTaskClosing(request: TransitionRequestInfo): Boolean {
         return Flags.enableDesktopWindowingWallpaperActivity() &&
-            request.type == TRANSIT_TO_BACK &&
-            request.triggerTask?.let { task ->
-                desktopModeTaskRepository.isOnlyActiveTask(task.taskId)
-            }
-                ?: false
+            TransitionUtil.isClosingType(request.type) &&
+            request.triggerTask != null
     }
 
     private fun handleFreeformTaskLaunch(
         task: RunningTaskInfo,
         transition: IBinder
     ): WindowContainerTransaction? {
-        KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: handleFreeformTaskLaunch")
+        ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: handleFreeformTaskLaunch")
+        if (keyguardManager.isKeyguardLocked) {
+            // Do NOT handle freeform task launch when locked.
+            // It will be launched in fullscreen windowing mode (Details: b/160925539)
+            ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: skip keyguard is locked")
+            return null
+        }
         if (!desktopModeTaskRepository.isDesktopModeShowing(task.displayId)) {
-            KtProtoLog.d(
+            ProtoLog.d(
                 WM_SHELL_DESKTOP_MODE,
-                "DesktopTasksController: switch freeform task to fullscreen oon transition" +
+                "DesktopTasksController: bring desktop tasks to front on transition" +
                     " taskId=%d",
                 task.taskId
             )
@@ -995,9 +1014,9 @@
         task: RunningTaskInfo,
         transition: IBinder
     ): WindowContainerTransaction? {
-        KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: handleFullscreenTaskLaunch")
+        ProtoLog.v(WM_SHELL_DESKTOP_MODE, "DesktopTasksController: handleFullscreenTaskLaunch")
         if (desktopModeTaskRepository.isDesktopModeShowing(task.displayId)) {
-            KtProtoLog.d(
+            ProtoLog.d(
                 WM_SHELL_DESKTOP_MODE,
                 "DesktopTasksController: switch fullscreen task to freeform on transition" +
                     " taskId=%d",
@@ -1005,6 +1024,9 @@
             )
             return WindowContainerTransaction().also { wct ->
                 addMoveToDesktopChanges(wct, task)
+                // In some launches home task is moved behind new task being launched. Make sure
+                // that's not the case for launches in desktop.
+                moveHomeTask(wct, toTop = false)
                 // Desktop Mode is already showing and we're launching a new Task - we might need to
                 // minimize another Task.
                 val taskToMinimize = addAndGetMinimizeChangesIfNeeded(task.displayId, wct, task)
@@ -1024,17 +1046,26 @@
         return WindowContainerTransaction().also { wct -> addMoveToFullscreenChanges(wct, task) }
     }
 
-    /** Handle back navigation by removing wallpaper activity if it's the last active task */
-    private fun handleBackNavigation(task: RunningTaskInfo): WindowContainerTransaction? {
-        if (
-            desktopModeTaskRepository.isOnlyActiveTask(task.taskId) &&
+    /** Handle task closing by removing wallpaper activity if it's the last active task */
+    private fun handleTaskClosing(task: RunningTaskInfo): WindowContainerTransaction? {
+        val wct = if (
+            desktopModeTaskRepository.isOnlyVisibleNonClosingTask(task.taskId) &&
                 desktopModeTaskRepository.wallpaperActivityToken != null
         ) {
             // Remove wallpaper activity when the last active task is removed
-            return WindowContainerTransaction().also { wct -> removeWallpaperActivity(wct) }
+            WindowContainerTransaction().also { wct -> removeWallpaperActivity(wct) }
         } else {
-            return null
+            null
         }
+        if (!desktopModeTaskRepository.addClosingTask(task.displayId, task.taskId)) {
+            // Could happen if the task hasn't been removed from closing list after it disappeared
+            ProtoLog.w(
+                WM_SHELL_DESKTOP_MODE,
+                "DesktopTasksController: the task with taskId=%d is already closing!",
+                task.taskId
+            )
+        }
+        return wct
     }
 
     private fun addMoveToDesktopChanges(
@@ -1367,7 +1398,7 @@
         if (!multiInstanceHelper.supportsMultiInstanceSplit(launchComponent)) {
             // TODO(b/320797628): Should only return early if there is an existing running task, and
             //                    notify the user as well. But for now, just ignore the drop.
-            KtProtoLog.v(WM_SHELL_DESKTOP_MODE, "Dropped intent does not support multi-instance")
+            ProtoLog.v(WM_SHELL_DESKTOP_MODE, "Dropped intent does not support multi-instance")
             return false
         }
 
@@ -1458,7 +1489,7 @@
         private val listener: VisibleTasksListener =
             object : VisibleTasksListener {
                 override fun onTasksVisibilityChanged(displayId: Int, visibleTasksCount: Int) {
-                    KtProtoLog.v(
+                    ProtoLog.v(
                         WM_SHELL_DESKTOP_MODE,
                         "IDesktopModeImpl: onVisibilityChanged display=%d visible=%d",
                         displayId,
@@ -1503,11 +1534,11 @@
         }
 
         override fun stashDesktopApps(displayId: Int) {
-            KtProtoLog.w(WM_SHELL_DESKTOP_MODE, "IDesktopModeImpl: stashDesktopApps is deprecated")
+            ProtoLog.w(WM_SHELL_DESKTOP_MODE, "IDesktopModeImpl: stashDesktopApps is deprecated")
         }
 
         override fun hideStashedDesktopApps(displayId: Int) {
-            KtProtoLog.w(
+            ProtoLog.w(
                 WM_SHELL_DESKTOP_MODE,
                 "IDesktopModeImpl: hideStashedDesktopApps is deprecated"
             )
@@ -1534,7 +1565,7 @@
         }
 
         override fun setTaskListener(listener: IDesktopTaskListener?) {
-            KtProtoLog.v(
+            ProtoLog.v(
                 WM_SHELL_DESKTOP_MODE,
                 "IDesktopModeImpl: set task listener=%s",
                 listener ?: "null"
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt
index 0f88384..534cc22 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksLimiter.kt
@@ -23,12 +23,12 @@
 import android.window.TransitionInfo
 import android.window.WindowContainerTransaction
 import androidx.annotation.VisibleForTesting
+import com.android.internal.protolog.ProtoLog
 import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.protolog.ShellProtoLogGroup
-import com.android.wm.shell.shared.DesktopModeStatus
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
 import com.android.wm.shell.transition.Transitions
 import com.android.wm.shell.transition.Transitions.TransitionObserver
-import com.android.wm.shell.util.KtProtoLog
 
 /**
  * Limits the number of tasks shown in Desktop Mode.
@@ -42,9 +42,12 @@
         private val shellTaskOrganizer: ShellTaskOrganizer,
 ) {
     private val minimizeTransitionObserver = MinimizeTransitionObserver()
+    @VisibleForTesting
+    val leftoverMinimizedTasksRemover = LeftoverMinimizedTasksRemover()
 
     init {
         transitions.registerObserver(minimizeTransitionObserver)
+        taskRepository.addActiveTaskListener(leftoverMinimizedTasksRemover)
     }
 
     private data class TaskDetails (val displayId: Int, val taskId: Int)
@@ -68,7 +71,7 @@
             if (!taskRepository.isActiveTask(taskToMinimize.taskId)) return
 
             if (!isTaskReorderedToBackOrInvisible(info, taskToMinimize)) {
-                KtProtoLog.v(
+                ProtoLog.v(
                         ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
                         "DesktopTasksLimiter: task %d is not reordered to back nor invis",
                         taskToMinimize.taskId)
@@ -106,19 +109,48 @@
         }
 
         override fun onTransitionFinished(transition: IBinder, aborted: Boolean) {
-            KtProtoLog.v(
+            ProtoLog.v(
                     ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
                     "DesktopTasksLimiter: transition %s finished", transition)
             mPendingTransitionTokensAndTasks.remove(transition)
         }
     }
 
+    @VisibleForTesting
+    inner class LeftoverMinimizedTasksRemover : DesktopModeTaskRepository.ActiveTasksListener {
+        override fun onActiveTasksChanged(displayId: Int) {
+            val wct = WindowContainerTransaction()
+            removeLeftoverMinimizedTasks(displayId, wct)
+            shellTaskOrganizer.applyTransaction(wct)
+        }
+
+        fun removeLeftoverMinimizedTasks(displayId: Int, wct: WindowContainerTransaction) {
+            if (taskRepository
+                .getActiveNonMinimizedTasksOrderedFrontToBack(displayId).isNotEmpty()) {
+                return
+            }
+            val remainingMinimizedTasks = taskRepository.getMinimizedTasks(displayId)
+            if (remainingMinimizedTasks.isEmpty()) {
+                return
+            }
+            ProtoLog.v(
+                ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
+                "DesktopTasksLimiter: removing leftover minimized tasks: $remainingMinimizedTasks")
+            remainingMinimizedTasks.forEach { taskIdToRemove ->
+                val taskToRemove = shellTaskOrganizer.getRunningTaskInfo(taskIdToRemove)
+                if (taskToRemove != null) {
+                    wct.removeTask(taskToRemove.token)
+                }
+            }
+        }
+    }
+
     /**
      * Mark a task as minimized, this should only be done after the corresponding transition has
      * finished so we don't minimize the task if the transition fails.
      */
     private fun markTaskMinimized(displayId: Int, taskId: Int) {
-        KtProtoLog.v(
+        ProtoLog.v(
                 ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
                 "DesktopTasksLimiter: marking %d as minimized", taskId)
         taskRepository.minimizeTask(displayId, taskId)
@@ -137,7 +169,7 @@
             wct: WindowContainerTransaction,
             newFrontTaskInfo: RunningTaskInfo,
     ): RunningTaskInfo? {
-        KtProtoLog.v(
+        ProtoLog.v(
                 ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
                 "DesktopTasksLimiter: addMinimizeBackTaskChangesIfNeeded, newFrontTask=%d",
                 newFrontTaskInfo.taskId)
@@ -185,7 +217,7 @@
             visibleFreeformTaskIdsOrderedFrontToBack: List<Int>
     ): RunningTaskInfo? {
         if (visibleFreeformTaskIdsOrderedFrontToBack.size <= getMaxTaskLimit()) {
-            KtProtoLog.v(
+            ProtoLog.v(
                     ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
                     "DesktopTasksLimiter: no need to minimize; tasks below limit")
             // No need to minimize anything
@@ -195,7 +227,7 @@
                 shellTaskOrganizer.getRunningTaskInfo(
                         visibleFreeformTaskIdsOrderedFrontToBack.last())
         if (taskToMinimize == null) {
-            KtProtoLog.e(
+            ProtoLog.e(
                     ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
                     "DesktopTasksLimiter: taskToMinimize == null")
             return null
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt
index dae75f9..246fd92 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt
@@ -21,35 +21,38 @@
 import android.view.SurfaceControl
 import android.view.WindowManager
 import android.window.TransitionInfo
+import android.window.WindowContainerTransaction
+import com.android.internal.protolog.ProtoLog
 import com.android.window.flags.Flags.enableDesktopWindowingWallpaperActivity
+import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
-import com.android.wm.shell.shared.DesktopModeStatus
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
 import com.android.wm.shell.sysui.ShellInit
 import com.android.wm.shell.transition.Transitions
-import com.android.wm.shell.util.KtProtoLog
 
 /**
- * A [Transitions.TransitionObserver] that observes shell transitions and updates
- * the [DesktopModeTaskRepository] state TODO: b/332682201
- * This observes transitions related to desktop mode
- * and other transitions that originate both within and outside shell.
+ * A [Transitions.TransitionObserver] that observes shell transitions and updates the
+ * [DesktopModeTaskRepository] state TODO: b/332682201 This observes transitions related to desktop
+ * mode and other transitions that originate both within and outside shell.
  */
 class DesktopTasksTransitionObserver(
     context: Context,
     private val desktopModeTaskRepository: DesktopModeTaskRepository,
     private val transitions: Transitions,
+    private val shellTaskOrganizer: ShellTaskOrganizer,
     shellInit: ShellInit
 ) : Transitions.TransitionObserver {
 
     init {
-        if (Transitions.ENABLE_SHELL_TRANSITIONS &&
-            DesktopModeStatus.canEnterDesktopMode(context)) {
+        if (
+            Transitions.ENABLE_SHELL_TRANSITIONS && DesktopModeStatus.canEnterDesktopMode(context)
+        ) {
             shellInit.addInitCallback(::onInit, this)
         }
     }
 
     fun onInit() {
-        KtProtoLog.d(WM_SHELL_DESKTOP_MODE, "DesktopTasksTransitionObserver: onInit")
+        ProtoLog.d(WM_SHELL_DESKTOP_MODE, "DesktopTasksTransitionObserver: onInit")
         transitions.registerObserver(this)
     }
 
@@ -83,8 +86,16 @@
             change.taskInfo?.let { taskInfo ->
                 if (DesktopWallpaperActivity.isWallpaperTask(taskInfo)) {
                     when (change.mode) {
-                        WindowManager.TRANSIT_OPEN ->
+                        WindowManager.TRANSIT_OPEN -> {
                             desktopModeTaskRepository.wallpaperActivityToken = taskInfo.token
+                            // After the task for the wallpaper is created, set it non-trimmable.
+                            // This is important to prevent recents from trimming and removing the
+                            // task.
+                            shellTaskOrganizer.applyTransaction(
+                                WindowContainerTransaction()
+                                    .setTaskTrimmableFromRecents(taskInfo.token, false)
+                            )
+                        }
                         WindowManager.TRANSIT_CLOSE ->
                             desktopModeTaskRepository.wallpaperActivityToken = null
                         else -> {}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopWallpaperActivity.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopWallpaperActivity.kt
index c4a4474..1c2415c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopWallpaperActivity.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopWallpaperActivity.kt
@@ -21,8 +21,8 @@
 import android.content.ComponentName
 import android.os.Bundle
 import android.view.WindowManager
+import com.android.internal.protolog.ProtoLog
 import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
-import com.android.wm.shell.util.KtProtoLog
 
 /**
  * A transparent activity used in the desktop mode to show the wallpaper under the freeform windows.
@@ -36,7 +36,7 @@
 class DesktopWallpaperActivity : Activity() {
 
     override fun onCreate(savedInstanceState: Bundle?) {
-        KtProtoLog.d(WM_SHELL_DESKTOP_MODE, "DesktopWallpaperActivity: onCreate")
+        ProtoLog.d(WM_SHELL_DESKTOP_MODE, "DesktopWallpaperActivity: onCreate")
         super.onCreate(savedInstanceState)
         window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
index d99b724..ddee8fa 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
@@ -29,6 +29,7 @@
 import android.window.TransitionRequestInfo
 import android.window.WindowContainerToken
 import android.window.WindowContainerTransaction
+import com.android.internal.protolog.ProtoLog
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer
 import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
 import com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT
@@ -42,7 +43,6 @@
 import com.android.wm.shell.transition.Transitions.TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP
 import com.android.wm.shell.transition.Transitions.TRANSIT_DESKTOP_MODE_START_DRAG_TO_DESKTOP
 import com.android.wm.shell.transition.Transitions.TransitionHandler
-import com.android.wm.shell.util.KtProtoLog
 import com.android.wm.shell.windowdecor.MoveToDesktopAnimator
 import com.android.wm.shell.windowdecor.MoveToDesktopAnimator.Companion.DRAG_FREEFORM_SCALE
 import com.android.wm.shell.windowdecor.OnTaskResizeAnimationListener
@@ -114,7 +114,7 @@
         dragToDesktopAnimator: MoveToDesktopAnimator,
     ) {
         if (inProgress) {
-            KtProtoLog.v(
+            ProtoLog.v(
                 ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
                 "DragToDesktop: Drag to desktop transition already in progress."
             )
@@ -599,7 +599,7 @@
     ) {
         val state = transitionState ?: return
         if (aborted && state.startTransitionToken == transition) {
-            KtProtoLog.v(
+            ProtoLog.v(
                 ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
                 "DragToDesktop: onTransitionConsumed() start transition aborted"
             )
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
index 891f75c..171378f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
@@ -42,6 +42,8 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.jank.Cuj;
+import com.android.internal.jank.InteractionJankMonitor;
 import com.android.wm.shell.common.desktopmode.DesktopModeTransitionSource;
 import com.android.wm.shell.transition.Transitions;
 
@@ -60,6 +62,7 @@
 
     private final Context mContext;
     private final Transitions mTransitions;
+    private final InteractionJankMonitor mInteractionJankMonitor;
     private final List<IBinder> mPendingTransitionTokens = new ArrayList<>();
     private Consumer<SurfaceControl.Transaction> mOnAnimationFinishedCallback;
     private final Supplier<SurfaceControl.Transaction> mTransactionSupplier;
@@ -67,17 +70,21 @@
 
     public ExitDesktopTaskTransitionHandler(
             Transitions transitions,
-            Context context) {
-        this(transitions, SurfaceControl.Transaction::new, context);
+            Context context,
+            InteractionJankMonitor interactionJankMonitor
+            ) {
+        this(transitions, SurfaceControl.Transaction::new, context, interactionJankMonitor);
     }
 
     private ExitDesktopTaskTransitionHandler(
             Transitions transitions,
             Supplier<SurfaceControl.Transaction> supplier,
-            Context context) {
+            Context context,
+            InteractionJankMonitor interactionJankMonitor) {
         mTransitions = transitions;
         mTransactionSupplier = supplier;
         mContext = context;
+        mInteractionJankMonitor = interactionJankMonitor;
     }
 
     /**
@@ -146,6 +153,8 @@
             final int screenHeight = metrics.heightPixels;
             final SurfaceControl sc = change.getLeash();
             final Rect endBounds = change.getEndAbsBounds();
+            mInteractionJankMonitor
+                .begin(sc, mContext, Cuj.CUJ_DESKTOP_MODE_EXIT_MODE);
             // Hide the first (fullscreen) frame because the animation will start from the freeform
             // size.
             startT.hide(sc)
@@ -175,6 +184,7 @@
                     if (mOnAnimationFinishedCallback != null) {
                         mOnAnimationFinishedCallback.accept(finishT);
                     }
+                    mInteractionJankMonitor.end(Cuj.CUJ_DESKTOP_MODE_EXIT_MODE);
                     mTransitions.getMainExecutor().execute(
                             () -> finishCallback.onTransitionFinished(null));
                 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
index 88d0554..c35d77a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ToggleResizeDesktopTaskTransitionHandler.kt
@@ -27,6 +27,8 @@
 import android.window.TransitionRequestInfo
 import android.window.WindowContainerTransaction
 import androidx.core.animation.addListener
+import com.android.internal.jank.Cuj
+import com.android.internal.jank.InteractionJankMonitor
 import com.android.wm.shell.transition.Transitions
 import com.android.wm.shell.transition.Transitions.TRANSIT_DESKTOP_MODE_TOGGLE_RESIZE
 import com.android.wm.shell.windowdecor.OnTaskResizeAnimationListener
@@ -35,7 +37,8 @@
 /** Handles the animation of quick resizing of desktop tasks. */
 class ToggleResizeDesktopTaskTransitionHandler(
     private val transitions: Transitions,
-    private val transactionSupplier: Supplier<SurfaceControl.Transaction>
+    private val transactionSupplier: Supplier<SurfaceControl.Transaction>,
+    private val interactionJankMonitor: InteractionJankMonitor
 ) : Transitions.TransitionHandler {
 
     private val rectEvaluator = RectEvaluator(Rect())
@@ -44,8 +47,9 @@
     private var boundsAnimator: Animator? = null
 
     constructor(
-        transitions: Transitions
-    ) : this(transitions, Supplier { SurfaceControl.Transaction() })
+        transitions: Transitions,
+        interactionJankMonitor: InteractionJankMonitor
+    ) : this(transitions, Supplier { SurfaceControl.Transaction() }, interactionJankMonitor)
 
     /** Starts a quick resize transition. */
     fun startTransition(wct: WindowContainerTransaction) {
@@ -103,6 +107,8 @@
                             onTaskResizeAnimationListener.onAnimationEnd(taskId)
                             finishCallback.onTransitionFinished(null)
                             boundsAnimator = null
+                            interactionJankMonitor.end(
+                                Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW)
                         }
                     )
                     addUpdateListener { anim ->
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
index 438aa76..3572d16 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md
@@ -73,7 +73,7 @@
 following system properties for example:
 ```shell
 # Enabling
-adb shell setprop persist.wm.debug.sc.tx.log_match_call setAlpha  # matches the name of the SurfaceControlTransaction method
+adb shell setprop persist.wm.debug.sc.tx.log_match_call setAlpha,setPosition  # matches the name of the SurfaceControlTransaction methods
 adb shell setprop persist.wm.debug.sc.tx.log_match_name com.android.systemui # matches the name of the surface
 adb reboot
 adb logcat -s "SurfaceControlRegistry"
@@ -87,7 +87,17 @@
 It is not necessary to set both `log_match_call` and `log_match_name`, but note logs can be quite
 noisy if unfiltered.
 
-## Tracing activity starts in the app process
+It can sometimes be useful to trace specific logs and when they are applied (sometimes we build
+transactions that can be applied later).  You can do this by adding the "merge" and "apply" calls to
+the set of requested calls:
+```shell
+# Enabling
+adb shell setprop persist.wm.debug.sc.tx.log_match_call setAlpha,merge,apply  # apply will dump logs of each setAlpha or merge call on that tx
+adb reboot
+adb logcat -s "SurfaceControlRegistry"
+```
+
+## Tracing activity starts & finishes in the app process
 
 It's sometimes useful to know when to see a stack trace of when an activity starts in the app code
 (ie. if you are repro'ing a bug related to activity starts). You can enable this system property to
@@ -103,6 +113,19 @@
 adb reboot
 ```
 
+Likewise, to trace where a finish() call may be made in the app process, you can enable this system
+property:
+```shell
+# Enabling
+adb shell setprop persist.wm.debug.finish_activity true
+adb reboot
+adb logcat -s "Instrumentation"
+
+# Disabling
+adb shell setprop persist.wm.debug.finish_activity \"\"
+adb reboot
+```
+
 ## Dumps
 
 Because the Shell library is built as a part of SystemUI, dumping the state is currently done as a
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 c374eb8..e00353d 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
@@ -52,6 +52,7 @@
 import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.widget.FrameLayout;
+import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
 import androidx.annotation.BinderThread;
@@ -59,9 +60,10 @@
 import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.logging.UiEventLogger;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 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.ExternalInterfaceBinder;
 import com.android.wm.shell.common.RemoteCallable;
@@ -85,6 +87,7 @@
 public class DragAndDropController implements RemoteCallable<DragAndDropController>,
         GlobalDragListener.GlobalDragListenerCallback,
         DisplayController.OnDisplaysChangedListener,
+        ShellTaskOrganizer.TaskVanishedListener,
         View.OnDragListener, ComponentCallbacks2 {
 
     private static final String TAG = DragAndDropController.class.getSimpleName();
@@ -92,6 +95,7 @@
     private final Context mContext;
     private final ShellController mShellController;
     private final ShellCommandHandler mShellCommandHandler;
+    private final ShellTaskOrganizer mShellTaskOrganizer;
     private final DisplayController mDisplayController;
     private final DragAndDropEventLogger mLogger;
     private final IconProvider mIconProvider;
@@ -133,6 +137,7 @@
             ShellInit shellInit,
             ShellController shellController,
             ShellCommandHandler shellCommandHandler,
+            ShellTaskOrganizer shellTaskOrganizer,
             DisplayController displayController,
             UiEventLogger uiEventLogger,
             IconProvider iconProvider,
@@ -142,6 +147,7 @@
         mContext = context;
         mShellController = shellController;
         mShellCommandHandler = shellCommandHandler;
+        mShellTaskOrganizer = shellTaskOrganizer;
         mDisplayController = displayController;
         mLogger = new DragAndDropEventLogger(uiEventLogger);
         mIconProvider = iconProvider;
@@ -163,6 +169,7 @@
         }, 0);
         mShellController.addExternalInterface(KEY_EXTRA_SHELL_DRAG_AND_DROP,
                 this::createExternalInterface, this);
+        mShellTaskOrganizer.addTaskVanishedListener(this);
         mShellCommandHandler.addDumpCallback(this::dump, this);
         mGlobalDragListener.setListener(this);
     }
@@ -281,6 +288,34 @@
     }
 
     @Override
+    public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
+        if (taskInfo.baseIntent == null) {
+            // Invalid info
+            return;
+        }
+        // Find the active drag
+        PerDisplay pd = null;
+        for (int i = 0; i < mDisplayDropTargets.size(); i++) {
+            final PerDisplay iPd = mDisplayDropTargets.valueAt(i);
+            if (iPd.isHandlingDrag) {
+                pd = iPd;
+                break;
+            }
+        }
+        if (pd == null || pd.activeDragCount <= 0 || !pd.isHandlingDrag) {
+            // Not currently dragging
+            return;
+        }
+
+        // Update the drag session
+        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+                "Handling vanished task: id=%d component=%s", taskInfo.taskId,
+                taskInfo.baseIntent.getComponent());
+        pd.dragSession.updateRunningTask();
+        pd.dragLayout.updateSession(pd.dragSession);
+    }
+
+    @Override
     public boolean onDrag(View target, DragEvent event) {
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
                 "Drag event: action=%s x=%f y=%f xOffset=%f yOffset=%f",
@@ -298,9 +333,10 @@
             mActiveDragDisplay = displayId;
             pd.isHandlingDrag = DragUtils.canHandleDrag(event);
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
-                    "Clip description: handlingDrag=%b itemCount=%d mimeTypes=%s",
+                    "Clip description: handlingDrag=%b itemCount=%d mimeTypes=%s flags=%s",
                     pd.isHandlingDrag, event.getClipData().getItemCount(),
-                    DragUtils.getMimeTypesConcatenated(description));
+                    DragUtils.getMimeTypesConcatenated(description),
+                    DragUtils.dragFlagsToString(event.getDragFlags()));
         }
 
         if (!pd.isHandlingDrag) {
@@ -313,13 +349,18 @@
                     Slog.w(TAG, "Unexpected drag start during an active drag");
                     return false;
                 }
-                // TODO(b/290391688): Also update the session data with task stack changes
                 pd.dragSession = new DragSession(ActivityTaskManager.getInstance(),
                         mDisplayController.getDisplayLayout(displayId), event.getClipData(),
                         event.getDragFlags());
-                pd.dragSession.update();
+                pd.dragSession.initialize();
                 pd.activeDragCount++;
                 pd.dragLayout.prepare(pd.dragSession, mLogger.logStart(pd.dragSession));
+                if (pd.dragSession.hideDragSourceTaskId != -1) {
+                    ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+                            "Hiding task surface: taskId=%d", pd.dragSession.hideDragSourceTaskId);
+                    mShellTaskOrganizer.setTaskSurfaceVisibility(
+                            pd.dragSession.hideDragSourceTaskId, false /* visible */);
+                }
                 setDropTargetWindowVisibility(pd, View.VISIBLE);
                 notifyListeners(l -> {
                     l.onDragStarted();
@@ -349,6 +390,13 @@
                 if (pd.dragLayout.hasDropped()) {
                     mLogger.logDrop();
                 } else {
+                    if (pd.dragSession.hideDragSourceTaskId != -1) {
+                        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+                                "Re-showing task surface: taskId=%d",
+                                pd.dragSession.hideDragSourceTaskId);
+                        mShellTaskOrganizer.setTaskSurfaceVisibility(
+                                pd.dragSession.hideDragSourceTaskId, true /* visible */);
+                    }
                     pd.activeDragCount--;
                     pd.dragLayout.hide(event, () -> {
                         if (pd.activeDragCount == 0) {
@@ -402,7 +450,16 @@
     private boolean handleDrop(DragEvent event, PerDisplay pd) {
         final SurfaceControl dragSurface = event.getDragSurface();
         pd.activeDragCount--;
-        return pd.dragLayout.drop(event, dragSurface, () -> {
+        // Find the token of the task to hide as a part of entering split
+        WindowContainerToken hideTaskToken = null;
+        if (pd.dragSession.hideDragSourceTaskId != -1) {
+            ActivityManager.RunningTaskInfo info = mShellTaskOrganizer.getRunningTaskInfo(
+                    pd.dragSession.hideDragSourceTaskId);
+            if (info != null) {
+                hideTaskToken = info.token;
+            }
+        }
+        return pd.dragLayout.drop(event, dragSurface, hideTaskToken, () -> {
             if (pd.activeDragCount == 0) {
                 // Hide the window if another drag hasn't been started while animating the drop
                 setDropTargetWindowVisibility(pd, View.INVISIBLE);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
index a42ca19..95fe8b6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
@@ -59,6 +59,7 @@
 import android.os.UserHandle;
 import android.util.Log;
 import android.util.Slog;
+import android.window.WindowContainerToken;
 
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
@@ -66,7 +67,7 @@
 import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.logging.InstanceId;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
@@ -84,7 +85,10 @@
     private static final String TAG = DragAndDropPolicy.class.getSimpleName();
 
     private final Context mContext;
-    private final Starter mStarter;
+    // Used only for launching a fullscreen task (or as a fallback if there is no split starter)
+    private final Starter mFullscreenStarter;
+    // Used for launching tasks into splitscreen
+    private final Starter mSplitscreenStarter;
     private final SplitScreenController mSplitScreen;
     private final ArrayList<DragAndDropPolicy.Target> mTargets = new ArrayList<>();
     private final RectF mDisallowHitRegion = new RectF();
@@ -97,10 +101,12 @@
     }
 
     @VisibleForTesting
-    DragAndDropPolicy(Context context, SplitScreenController splitScreen, Starter starter) {
+    DragAndDropPolicy(Context context, SplitScreenController splitScreen,
+            Starter fullscreenStarter) {
         mContext = context;
         mSplitScreen = splitScreen;
-        mStarter = mSplitScreen != null ? mSplitScreen : starter;
+        mFullscreenStarter = fullscreenStarter;
+        mSplitscreenStarter = splitScreen;
     }
 
     /**
@@ -229,8 +235,13 @@
         return null;
     }
 
+    /**
+     * Handles the drop on a given {@param target}.  If a {@param hideTaskToken} is set, then the
+     * handling of the drop will attempt to hide the given task as a part of the same window
+     * container transaction if possible.
+     */
     @VisibleForTesting
-    void handleDrop(Target target) {
+    void handleDrop(Target target, @Nullable WindowContainerToken hideTaskToken) {
         if (target == null || !mTargets.contains(target)) {
             return;
         }
@@ -245,17 +256,21 @@
             mSplitScreen.onDroppedToSplit(position, mLoggerSessionId);
         }
 
+        final Starter starter = target.type == TYPE_FULLSCREEN
+                ? mFullscreenStarter
+                : mSplitscreenStarter;
         if (mSession.appData != null) {
-            launchApp(mSession, position);
+            launchApp(mSession, starter, position, hideTaskToken);
         } else {
-            launchIntent(mSession, position);
+            launchIntent(mSession, starter, position, hideTaskToken);
         }
     }
 
     /**
      * Launches an app provided by SysUI.
      */
-    private void launchApp(DragSession session, @SplitPosition int position) {
+    private void launchApp(DragSession session, Starter starter, @SplitPosition int position,
+            @Nullable WindowContainerToken hideTaskToken) {
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Launching app data at position=%d",
                 position);
         final ClipDescription description = session.getClipDescription();
@@ -275,11 +290,15 @@
 
         if (isTask) {
             final int taskId = session.appData.getIntExtra(EXTRA_TASK_ID, INVALID_TASK_ID);
-            mStarter.startTask(taskId, position, opts);
+            starter.startTask(taskId, position, opts, hideTaskToken);
         } else if (isShortcut) {
+            if (hideTaskToken != null) {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+                        "Can not hide task token with starting shortcut");
+            }
             final String packageName = session.appData.getStringExtra(EXTRA_PACKAGE_NAME);
             final String id = session.appData.getStringExtra(EXTRA_SHORTCUT_ID);
-            mStarter.startShortcut(packageName, id, position, opts, user);
+            starter.startShortcut(packageName, id, position, opts, user);
         } else {
             final PendingIntent launchIntent =
                     session.appData.getParcelableExtra(EXTRA_PENDING_INTENT);
@@ -288,15 +307,16 @@
                     Log.e(TAG, "Expected app intent's EXTRA_USER to match pending intent user");
                 }
             }
-            mStarter.startIntent(launchIntent, user.getIdentifier(), null /* fillIntent */,
-                    position, opts);
+            starter.startIntent(launchIntent, user.getIdentifier(), null /* fillIntent */,
+                    position, opts, hideTaskToken);
         }
     }
 
     /**
      * Launches an intent sender provided by an application.
      */
-    private void launchIntent(DragSession session, @SplitPosition int position) {
+    private void launchIntent(DragSession session, Starter starter, @SplitPosition int position,
+            @Nullable WindowContainerToken hideTaskToken) {
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Launching intent at position=%d",
                 position);
         final ActivityOptions baseActivityOpts = ActivityOptions.makeBasic();
@@ -309,20 +329,22 @@
                 | FLAG_ACTIVITY_MULTIPLE_TASK);
 
         final Bundle opts = baseActivityOpts.toBundle();
-        mStarter.startIntent(session.launchableIntent,
+        starter.startIntent(session.launchableIntent,
                 session.launchableIntent.getCreatorUserHandle().getIdentifier(),
-                null /* fillIntent */, position, opts);
+                null /* fillIntent */, position, opts, hideTaskToken);
     }
 
     /**
      * Interface for actually committing the task launches.
      */
     public interface Starter {
-        void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options);
+        void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options,
+                @Nullable WindowContainerToken hideTaskToken);
         void startShortcut(String packageName, String shortcutId, @SplitPosition int position,
                 @Nullable Bundle options, UserHandle user);
         void startIntent(PendingIntent intent, int userId, Intent fillInIntent,
-                @SplitPosition int position, @Nullable Bundle options);
+                @SplitPosition int position, @Nullable Bundle options,
+                @Nullable WindowContainerToken hideTaskToken);
         void enterSplitScreen(int taskId, boolean leftOrTop);
 
         /**
@@ -344,7 +366,12 @@
         }
 
         @Override
-        public void startTask(int taskId, int position, @Nullable Bundle options) {
+        public void startTask(int taskId, int position, @Nullable Bundle options,
+                @Nullable WindowContainerToken hideTaskToken) {
+            if (hideTaskToken != null) {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+                        "Default starter does not support hide task token");
+            }
             try {
                 ActivityTaskManager.getService().startActivityFromRecents(taskId, options);
             } catch (RemoteException e) {
@@ -367,7 +394,12 @@
 
         @Override
         public void startIntent(PendingIntent intent, int userId, @Nullable Intent fillInIntent,
-                int position, @Nullable Bundle options) {
+                int position, @Nullable Bundle options,
+                @Nullable WindowContainerToken hideTaskToken) {
+            if (hideTaskToken != null) {
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+                        "Default starter does not support hide task token");
+            }
             try {
                 intent.send(mContext, 0, fillInIntent, null, null, null, options);
             } catch (PendingIntent.CanceledException e) {
@@ -420,7 +452,7 @@
 
         @Override
         public String toString() {
-            return "Target {hit=" + hitRegion + " draw=" + drawRegion + "}";
+            return "Target {type=" + type + " hit=" + hitRegion + " draw=" + drawRegion + "}";
         }
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
index 4bb10df..e4aa115 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
@@ -20,7 +20,6 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.content.pm.ActivityInfo.CONFIG_ASSETS_PATHS;
 import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
 
@@ -42,6 +41,7 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Insets;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.graphics.drawable.Drawable;
@@ -51,11 +51,13 @@
 import android.view.WindowInsets;
 import android.view.WindowInsets.Type;
 import android.widget.LinearLayout;
+import android.window.WindowContainerToken;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
 import com.android.internal.logging.InstanceId;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.R;
 import com.android.wm.shell.animation.Interpolators;
@@ -102,6 +104,8 @@
     private boolean mIsShowing;
     private boolean mHasDropped;
     private DragSession mSession;
+    // The last position that was handled by the drag layout
+    private final Point mLastPosition = new Point();
 
     @SuppressLint("WrongConstant")
     public DragLayout(Context context, SplitScreenController splitScreenController,
@@ -265,6 +269,15 @@
      */
     public void prepare(DragSession session, InstanceId loggerSessionId) {
         mPolicy.start(session, loggerSessionId);
+        updateSession(session);
+    }
+
+    /**
+     * Updates the drag layout based on the diven drag session.
+     */
+    public void updateSession(DragSession session) {
+        // Note: The policy currently just keeps a reference to the session
+        boolean updatingExistingSession = mSession != null;
         mSession = session;
         mHasDropped = false;
         mCurrentTarget = null;
@@ -280,6 +293,8 @@
                     int bgColor1 = getResizingBackgroundColor(taskInfo1).toArgb();
                     mDropZoneView1.setAppInfo(bgColor1, icon1);
                     mDropZoneView2.setAppInfo(bgColor1, icon1);
+                    mDropZoneView1.setForceIgnoreBottomMargin(false);
+                    mDropZoneView2.setForceIgnoreBottomMargin(false);
                     updateDropZoneSizes(null, null); // passing null splits the views evenly
                 } else {
                     // We use the first drop zone to show the fullscreen highlight, and don't need
@@ -312,6 +327,11 @@
             updateDropZoneSizes(topOrLeftBounds, bottomOrRightBounds);
         }
         requestLayout();
+        if (updatingExistingSession) {
+            // Update targets if we are already currently dragging
+            recomputeDropTargets();
+            update(mLastPosition.x, mLastPosition.y);
+        }
     }
 
     private void updateDropZoneSizesForSingleTask() {
@@ -359,6 +379,9 @@
         mDropZoneView2.setLayoutParams(dropZoneView2);
     }
 
+    /**
+     * Shows the drag layout.
+     */
     public void show() {
         mIsShowing = true;
         recomputeDropTargets();
@@ -384,13 +407,19 @@
      * Updates the visible drop target as the user drags.
      */
     public void update(DragEvent event) {
+        update((int) event.getX(), (int) event.getY());
+    }
+
+    /**
+     * Updates the visible drop target as the user drags to the given coordinates.
+     */
+    private void update(int x, int y) {
         if (mHasDropped) {
             return;
         }
         // Find containing region, if the same as mCurrentRegion, then skip, otherwise, animate the
         // visibility of the current region
-        DragAndDropPolicy.Target target = mPolicy.getTargetAtLocation(
-                (int) event.getX(), (int) event.getY());
+        DragAndDropPolicy.Target target = mPolicy.getTargetAtLocation(x, y);
         if (mCurrentTarget != target) {
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Current target: %s", target);
             if (target == null) {
@@ -429,6 +458,7 @@
             }
             mCurrentTarget = target;
         }
+        mLastPosition.set(x, y);
     }
 
     /**
@@ -436,6 +466,7 @@
      */
     public void hide(DragEvent event, Runnable hideCompleteCallback) {
         mIsShowing = false;
+        mLastPosition.set(-1, -1);
         animateSplitContainers(false, () -> {
             if (hideCompleteCallback != null) {
                 hideCompleteCallback.run();
@@ -456,13 +487,13 @@
     /**
      * Handles the drop onto a target and animates out the visible drop targets.
      */
-    public boolean drop(DragEvent event, SurfaceControl dragSurface,
-            Runnable dropCompleteCallback) {
+    public boolean drop(DragEvent event, @NonNull SurfaceControl dragSurface,
+            @Nullable WindowContainerToken hideTaskToken, Runnable dropCompleteCallback) {
         final boolean handledDrop = mCurrentTarget != null;
         mHasDropped = true;
 
         // Process the drop
-        mPolicy.handleDrop(mCurrentTarget);
+        mPolicy.handleDrop(mCurrentTarget, hideTaskToken);
 
         // Start animating the drop UI out with the drag surface
         hide(event, dropCompleteCallback);
@@ -472,7 +503,7 @@
         return handledDrop;
     }
 
-    private void hideDragSurface(SurfaceControl dragSurface) {
+    private void hideDragSurface(@NonNull SurfaceControl dragSurface) {
         final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
         final ValueAnimator dragSurfaceAnimator = ValueAnimator.ofFloat(0f, 1f);
         // Currently the splash icon animation runs with the default ValueAnimator duration of
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java
index 0addd43..dcbdfa3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragSession.java
@@ -18,6 +18,7 @@
 
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.ClipDescription.EXTRA_HIDE_DRAG_SOURCE_TASK_ID;
 
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
@@ -27,10 +28,13 @@
 import android.content.ClipDescription;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
+import android.os.PersistableBundle;
 
 import androidx.annotation.Nullable;
 
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.DisplayLayout;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
 import java.util.List;
 
@@ -61,6 +65,7 @@
     @WindowConfiguration.ActivityType
     int runningTaskActType = ACTIVITY_TYPE_STANDARD;
     boolean dragItemSupportsSplitscreen;
+    int hideDragSourceTaskId = -1;
 
     DragSession(ActivityTaskManager activityTaskManager,
             DisplayLayout dispLayout, ClipData data, int dragFlags) {
@@ -68,6 +73,11 @@
         mInitialDragData = data;
         mInitialDragFlags = dragFlags;
         displayLayout = dispLayout;
+        hideDragSourceTaskId = data.getDescription().getExtras() != null
+                ? data.getDescription().getExtras().getInt(EXTRA_HIDE_DRAG_SOURCE_TASK_ID, -1)
+                : -1;
+        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+                "Extracting drag source taskId: taskId=%d", hideDragSourceTaskId);
     }
 
     /**
@@ -79,17 +89,38 @@
     }
 
     /**
-     * Updates the session data based on the current state of the system.
+     * Updates the running task for this drag session.
      */
-    void update() {
-        List<ActivityManager.RunningTaskInfo> tasks =
-                mActivityTaskManager.getTasks(1, false /* filterOnlyVisibleRecents */);
+    void updateRunningTask() {
+        final boolean hideDragSourceTask = hideDragSourceTaskId != -1;
+        final List<ActivityManager.RunningTaskInfo> tasks =
+                mActivityTaskManager.getTasks(hideDragSourceTask ? 2 : 1,
+                        false /* filterOnlyVisibleRecents */);
         if (!tasks.isEmpty()) {
-            final ActivityManager.RunningTaskInfo task = tasks.get(0);
-            runningTaskInfo = task;
-            runningTaskWinMode = task.getWindowingMode();
-            runningTaskActType = task.getActivityType();
+            for (int i = tasks.size() - 1; i >= 0; i--) {
+                final ActivityManager.RunningTaskInfo task = tasks.get(i);
+                if (hideDragSourceTask && hideDragSourceTaskId == task.taskId) {
+                    ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+                            "Skipping running task: id=%d component=%s", task.taskId,
+                            task.baseIntent != null ? task.baseIntent.getComponent() : "null");
+                    continue;
+                }
+                runningTaskInfo = task;
+                runningTaskWinMode = task.getWindowingMode();
+                runningTaskActType = task.getActivityType();
+                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+                        "Running task: id=%d component=%s", task.taskId,
+                        task.baseIntent != null ? task.baseIntent.getComponent() : "null");
+                break;
+            }
         }
+    }
+
+    /**
+     * Updates the session data based on the current state of the system at the start of the drag.
+     */
+    void initialize() {
+        updateRunningTask();
 
         activityInfo = mInitialDragData.getItemAt(0).getActivityInfo();
         // TODO: This should technically check & respect config_supportsNonResizableMultiWindow
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragUtils.java
index e215870..22cfa32 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragUtils.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragUtils.java
@@ -19,16 +19,28 @@
 import static android.content.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY;
 import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
 import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
+import static android.view.View.DRAG_FLAG_ACCESSIBILITY_ACTION;
+import static android.view.View.DRAG_FLAG_GLOBAL;
+import static android.view.View.DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION;
+import static android.view.View.DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION;
+import static android.view.View.DRAG_FLAG_GLOBAL_SAME_APPLICATION;
+import static android.view.View.DRAG_FLAG_GLOBAL_URI_READ;
+import static android.view.View.DRAG_FLAG_GLOBAL_URI_WRITE;
+import static android.view.View.DRAG_FLAG_HIDE_CALLING_TASK_ON_DRAG_START;
+import static android.view.View.DRAG_FLAG_OPAQUE;
+import static android.view.View.DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION;
+import static android.view.View.DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG;
 
 import android.app.PendingIntent;
 import android.content.ClipData;
 import android.content.ClipDescription;
 import android.view.DragEvent;
-import android.view.View;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import java.util.StringJoiner;
+
 /** Collection of utility classes for handling drag and drop. */
 public class DragUtils {
     private static final String TAG = "DragUtils";
@@ -76,7 +88,7 @@
      */
     @Nullable
     public static PendingIntent getLaunchIntent(@NonNull ClipData data, int dragFlags) {
-        if ((dragFlags & View.DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG) == 0) {
+        if ((dragFlags & DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG) == 0) {
             // Disallow launching the intent if the app does not want to delegate it to the system
             return null;
         }
@@ -105,4 +117,35 @@
         }
         return mimeTypes;
     }
+
+    /**
+     * Returns the string description of the given {@param dragFlags}.
+     */
+    public static String dragFlagsToString(int dragFlags) {
+        StringJoiner str = new StringJoiner("|");
+        if ((dragFlags & DRAG_FLAG_GLOBAL) != 0) {
+            str.add("GLOBAL");
+        } else if ((dragFlags & DRAG_FLAG_GLOBAL_URI_READ) != 0) {
+            str.add("GLOBAL_URI_READ");
+        } else if ((dragFlags & DRAG_FLAG_GLOBAL_URI_WRITE) != 0) {
+            str.add("GLOBAL_URI_WRITE");
+        } else if ((dragFlags & DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION) != 0) {
+            str.add("GLOBAL_PERSISTABLE_URI_PERMISSION");
+        } else if ((dragFlags & DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION) != 0) {
+            str.add("GLOBAL_PREFIX_URI_PERMISSION");
+        } else if ((dragFlags & DRAG_FLAG_OPAQUE) != 0) {
+            str.add("OPAQUE");
+        } else if ((dragFlags & DRAG_FLAG_ACCESSIBILITY_ACTION) != 0) {
+            str.add("ACCESSIBILITY_ACTION");
+        } else if ((dragFlags & DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION) != 0) {
+            str.add("REQUEST_SURFACE_FOR_RETURN_ANIMATION");
+        } else if ((dragFlags & DRAG_FLAG_GLOBAL_SAME_APPLICATION) != 0) {
+            str.add("GLOBAL_SAME_APPLICATION");
+        } else if ((dragFlags & DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG) != 0) {
+            str.add("START_INTENT_SENDER_ON_UNHANDLED_DRAG");
+        } else if ((dragFlags & DRAG_FLAG_HIDE_CALLING_TASK_ON_DRAG_START) != 0) {
+            str.add("HIDE_CALLING_TASK_ON_DRAG_START");
+        }
+        return str.toString();
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropZoneView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropZoneView.java
index 724a130..18cd2d8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropZoneView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropZoneView.java
@@ -19,6 +19,7 @@
 import static com.android.wm.shell.animation.Interpolators.FAST_OUT_SLOW_IN;
 
 import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.graphics.Canvas;
@@ -37,13 +38,16 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.policy.ScreenDecorationsUtils;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
 /**
  * Renders a drop zone area for items being dragged.
  */
 public class DropZoneView extends FrameLayout {
 
+    private static final boolean DEBUG_LAYOUT = false;
     private static final float SPLASHSCREEN_ALPHA = 0.90f;
     private static final float HIGHLIGHT_ALPHA = 1f;
     private static final int MARGIN_ANIMATION_ENTER_DURATION = 400;
@@ -77,6 +81,7 @@
     private int mHighlightColor;
 
     private ObjectAnimator mBackgroundAnimator;
+    private int mTargetBackgroundColor;
     private ObjectAnimator mMarginAnimator;
     private float mMarginPercent;
 
@@ -146,6 +151,10 @@
 
     /** Ignores the bottom margin provided by the insets. */
     public void setForceIgnoreBottomMargin(boolean ignoreBottomMargin) {
+        if (DEBUG_LAYOUT) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+                    "setForceIgnoreBottomMargin: ignore=%b", ignoreBottomMargin);
+        }
         mIgnoreBottomMargin = ignoreBottomMargin;
         if (mMarginPercent > 0) {
             mMarginView.invalidate();
@@ -154,8 +163,14 @@
 
     /** Sets the bottom inset so the drop zones are above bottom navigation. */
     public void setBottomInset(float bottom) {
+        if (DEBUG_LAYOUT) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "setBottomInset: inset=%f",
+                    bottom);
+        }
         mBottomInset = bottom;
-        ((LayoutParams) mSplashScreenView.getLayoutParams()).bottomMargin = (int) bottom;
+        final LayoutParams lp = (LayoutParams) mSplashScreenView.getLayoutParams();
+        lp.bottomMargin = (int) bottom;
+        mSplashScreenView.setLayoutParams(lp);
         if (mMarginPercent > 0) {
             mMarginView.invalidate();
         }
@@ -181,6 +196,9 @@
 
     /** Animates between highlight and splashscreen depending on current state. */
     public void animateSwitch() {
+        if (DEBUG_LAYOUT) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "animateSwitch");
+        }
         mShowingHighlight = !mShowingHighlight;
         mShowingSplash = !mShowingHighlight;
         final int newColor = mShowingHighlight ? mHighlightColor : mSplashScreenColor;
@@ -190,6 +208,10 @@
 
     /** Animates the highlight indicating the zone is hovered on or not. */
     public void setShowingHighlight(boolean showingHighlight) {
+        if (DEBUG_LAYOUT) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "setShowingHighlight: showing=%b",
+                    showingHighlight);
+        }
         mShowingHighlight = showingHighlight;
         mShowingSplash = !mShowingHighlight;
         final int newColor = mShowingHighlight ? mHighlightColor : mSplashScreenColor;
@@ -199,6 +221,10 @@
 
     /** Animates the margins around the drop zone to show or hide. */
     public void setShowingMargin(boolean visible) {
+        if (DEBUG_LAYOUT) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "setShowingMargin: visible=%b",
+                    visible);
+        }
         if (mShowingMargin != visible) {
             mShowingMargin = visible;
             animateMarginToState();
@@ -212,6 +238,15 @@
     }
 
     private void animateBackground(int startColor, int endColor) {
+        if (DEBUG_LAYOUT) {
+            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+                    "animateBackground: start=%s end=%s",
+                    Integer.toHexString(startColor), Integer.toHexString(endColor));
+        }
+        if (endColor == mTargetBackgroundColor) {
+            // Already at, or animating to, that background color
+            return;
+        }
         if (mBackgroundAnimator != null) {
             mBackgroundAnimator.cancel();
         }
@@ -223,6 +258,7 @@
             mBackgroundAnimator.setInterpolator(FAST_OUT_SLOW_IN);
         }
         mBackgroundAnimator.start();
+        mTargetBackgroundColor = endColor;
     }
 
     private void animateSplashScreenIcon() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/GlobalDragListener.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/GlobalDragListener.kt
index 31214eb..ffcfe644 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/GlobalDragListener.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/GlobalDragListener.kt
@@ -25,7 +25,7 @@
 import android.window.IGlobalDragListener
 import android.window.IUnhandledDragCallback
 import androidx.annotation.VisibleForTesting
-import com.android.internal.protolog.common.ProtoLog
+import com.android.internal.protolog.ProtoLog
 import com.android.wm.shell.common.ShellExecutor
 import com.android.wm.shell.protolog.ShellProtoLogGroup
 import java.util.function.Consumer
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
index 7d2aa27..4531967 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
@@ -25,11 +25,11 @@
 import android.util.SparseArray;
 import android.view.SurfaceControl;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
-import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.transition.Transitions;
 import com.android.wm.shell.windowdecor.WindowDecorViewModel;
@@ -150,6 +150,10 @@
                         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
                                 "Adding active freeform task: #%d", taskInfo.taskId);
                     }
+                } else if (repository.isClosingTask(taskInfo.taskId)
+                        && repository.removeClosingTask(taskInfo.taskId)) {
+                    ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE,
+                            "Removing closing freeform task: #%d", taskInfo.taskId);
                 }
                 repository.updateVisibleFreeformTasks(taskInfo.displayId, taskInfo.taskId,
                         taskInfo.isVisible);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
index 2626e73..d2ceb67 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
@@ -27,7 +27,7 @@
 
 import androidx.annotation.NonNull;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
index cd478e5..333c75f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java
@@ -49,7 +49,7 @@
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.TaskStackListenerCallback;
 import com.android.wm.shell.common.TaskStackListenerImpl;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java
index ce98458..93ede7a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java
@@ -16,7 +16,6 @@
 
 package com.android.wm.shell.pip;
 
-import android.content.ComponentName;
 import android.os.RemoteException;
 import android.view.IPinnedTaskListener;
 import android.view.WindowManagerGlobal;
@@ -70,12 +69,6 @@
         }
     }
 
-    private void onActivityHidden(ComponentName componentName) {
-        for (PinnedTaskListener listener : mListeners) {
-            listener.onActivityHidden(componentName);
-        }
-    }
-
     @BinderThread
     private class PinnedTaskListenerImpl extends IPinnedTaskListener.Stub {
         @Override
@@ -91,13 +84,6 @@
                 PinnedStackListenerForwarder.this.onImeVisibilityChanged(imeVisible, imeHeight);
             });
         }
-
-        @Override
-        public void onActivityHidden(ComponentName componentName) {
-            mMainExecutor.execute(() -> {
-                PinnedStackListenerForwarder.this.onActivityHidden(componentName);
-            });
-        }
     }
 
     /**
@@ -108,7 +94,5 @@
         public void onMovementBoundsChanged(boolean fromImeAdjustment) {}
 
         public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {}
-
-        public void onActivityHidden(ComponentName componentName) {}
     }
 }
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 a749019..b27c428 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,10 +16,12 @@
 
 package com.android.wm.shell.pip;
 
+import android.annotation.NonNull;
 import android.graphics.Rect;
 
 import com.android.wm.shell.shared.annotations.ExternalThread;
 
+import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 
 /**
@@ -69,9 +71,10 @@
     default void removePipExclusionBoundsChangeListener(Consumer<Rect> listener) { }
 
     /**
-     * @return {@link PipTransitionController} instance.
+     * Register {@link PipTransitionController.PipTransitionCallback} to listen on PiP transition
+     * started / finished callbacks.
      */
-    default PipTransitionController getPipTransitionController() {
-        return null;
-    }
+    default void registerPipTransitionCallback(
+            @NonNull PipTransitionController.PipTransitionCallback callback,
+            @NonNull Executor executor) { }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
index 0a3c15b..a8346a9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
@@ -17,6 +17,7 @@
 package com.android.wm.shell.pip;
 
 import static android.util.RotationUtils.rotateBounds;
+import static android.view.Surface.ROTATION_0;
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
 
@@ -37,7 +38,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.animation.Interpolators;
 import com.android.wm.shell.common.pip.PipUtils;
@@ -625,6 +626,14 @@
                 }
             } else {
                 adjustedSourceRectHint.set(sourceRectHint);
+                if (isInPipDirection(direction)
+                        && rotationDelta == ROTATION_0
+                        && taskInfo.displayCutoutInsets != null) {
+                    // TODO: this is to special case the issues on Foldable device
+                    // with display cutout. This aligns with what's in SwipePipToHomeAnimator.
+                    adjustedSourceRectHint.offset(taskInfo.displayCutoutInsets.left,
+                            taskInfo.displayCutoutInsets.top);
+                }
             }
             final Rect sourceHintRectInsets = new Rect();
             if (!adjustedSourceRectHint.isEmpty()) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
index 202f60d..3d1994c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
@@ -137,7 +137,7 @@
         mTmpDestinationRect.inset(insets);
         // Scale to the bounds no smaller than the destination and offset such that the top/left
         // of the scaled inset source rect aligns with the top/left of the destination bounds
-        final float scale, left, top;
+        final float scale;
         if (isInPipDirection
                 && sourceRectHint != null && sourceRectHint.width() < sourceBounds.width()) {
             // scale by sourceRectHint if it's not edge-to-edge, for entering PiP transition only.
@@ -148,14 +148,17 @@
                     ? (float) destinationBounds.width() / sourceBounds.width()
                     : (float) destinationBounds.height() / sourceBounds.height();
             scale = (1 - fraction) * startScale + fraction * endScale;
-            left = destinationBounds.left - insets.left * scale;
-            top = destinationBounds.top - insets.top * scale;
         } else {
             scale = Math.max((float) destinationBounds.width() / sourceBounds.width(),
                     (float) destinationBounds.height() / sourceBounds.height());
-            // Work around the rounding error by fix the position at very beginning.
-            left = scale == 1 ? 0 : destinationBounds.left - insets.left * scale;
-            top = scale == 1 ? 0 : destinationBounds.top - insets.top * scale;
+        }
+        float left = destinationBounds.left - insets.left * scale;
+        float top = destinationBounds.top - insets.top * scale;
+        if (scale == 1) {
+            // Work around the 1 pixel off error by rounding the position down at very beginning.
+            // We noticed such error from flicker tests, not visually.
+            left = sourceBounds.left;
+            top = sourceBounds.top;
         }
         mTmpTransform.setScale(scale, scale);
         tx.setMatrix(leash, mTmpTransform, mTmpFloat9)
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 e4420d7..6e1e44b 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
@@ -63,7 +63,6 @@
 import android.graphics.Rect;
 import android.os.RemoteException;
 import android.os.SystemProperties;
-import android.util.Rational;
 import android.view.Choreographer;
 import android.view.Display;
 import android.view.Surface;
@@ -74,7 +73,7 @@
 import android.window.WindowContainerTransaction;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.animation.Interpolators;
@@ -128,8 +127,6 @@
             SystemProperties.getInt(
                     "persist.wm.debug.extra_content_overlay_fade_out_delay_ms", 400);
 
-    private static final float PIP_ASPECT_RATIO_MISMATCH_THRESHOLD = 0.005f;
-
     private final Context mContext;
     private final SyncTransactionQueue mSyncTransactionQueue;
     private final PipBoundsState mPipBoundsState;
@@ -426,7 +423,8 @@
             });
             mPipTransitionController.setPipOrganizer(this);
             displayController.addDisplayWindowListener(this);
-            pipTransitionController.registerPipTransitionCallback(mPipTransitionCallback);
+            pipTransitionController.registerPipTransitionCallback(
+                    mPipTransitionCallback, mMainExecutor);
         }
     }
 
@@ -498,7 +496,9 @@
         ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                 "startSwipePipToHome: %s, state=%s", componentName, mPipTransitionState);
         mPipTransitionState.setInSwipePipToHomeTransition(true);
-        sendOnPipTransitionStarted(TRANSITION_DIRECTION_TO_PIP);
+        if (!ENABLE_SHELL_TRANSITIONS) {
+            sendOnPipTransitionStarted(TRANSITION_DIRECTION_TO_PIP);
+        }
         setBoundsStateForEntry(componentName, pictureInPictureParams, activityInfo);
         return mPipBoundsAlgorithm.getEntryDestinationBounds();
     }
@@ -608,6 +608,7 @@
     public void exitPip(int animationDurationMs, boolean requestEnterSplit) {
         if (!mPipTransitionState.isInPip()
                 || mPipTransitionState.getTransitionState() == PipTransitionState.EXITING_PIP
+                || mPipTransitionState.getInSwipePipToHomeTransition()
                 || mToken == null) {
             ProtoLog.wtf(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                     "%s: Not allowed to exitPip in current state"
@@ -637,6 +638,13 @@
             return;
         }
 
+        // bail early if leash is null
+        if (mLeash == null) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "exitPip: leash is null");
+            return;
+        }
+
         final Rect destinationBounds = new Rect(getExitDestinationBounds());
         final int direction = syncWithSplitScreenBounds(destinationBounds, requestEnterSplit)
                 ? TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN
@@ -821,37 +829,6 @@
                     mPictureInPictureParams.getTitle());
             mPipParamsChangedForwarder.notifySubtitleChanged(
                     mPictureInPictureParams.getSubtitle());
-
-            if (mPictureInPictureParams.hasSourceBoundsHint()
-                    && mPictureInPictureParams.hasSetAspectRatio()) {
-                Rational sourceRectHintAspectRatio = new Rational(
-                        mPictureInPictureParams.getSourceRectHint().width(),
-                        mPictureInPictureParams.getSourceRectHint().height());
-                if (sourceRectHintAspectRatio.compareTo(
-                        mPictureInPictureParams.getAspectRatio()) != 0) {
-                    ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
-                            "Aspect ratio of source rect hint (%d/%d) does not match the provided "
-                                    + "aspect ratio value (%d/%d). Consider matching them for "
-                                    + "improved animation. Future releases might override the "
-                                    + "value to match.",
-                            mPictureInPictureParams.getSourceRectHint().width(),
-                            mPictureInPictureParams.getSourceRectHint().height(),
-                            mPictureInPictureParams.getAspectRatio().getNumerator(),
-                            mPictureInPictureParams.getAspectRatio().getDenominator());
-                }
-                if (Math.abs(sourceRectHintAspectRatio.floatValue()
-                        - mPictureInPictureParams.getAspectRatioFloat())
-                        > PIP_ASPECT_RATIO_MISMATCH_THRESHOLD) {
-                    ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
-                            "Aspect ratio of source rect hint (%f) does not match the provided "
-                                    + "aspect ratio value (%f) and is above threshold of %f. "
-                                    + "Consider matching them for improved animation. Future "
-                                    + "releases might override the value to match.",
-                            sourceRectHintAspectRatio.floatValue(),
-                            mPictureInPictureParams.getAspectRatioFloat(),
-                            PIP_ASPECT_RATIO_MISMATCH_THRESHOLD);
-                }
-            }
         }
 
         mPipUiEventLoggerLogger.setTaskInfo(mTaskInfo);
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 3cae72d..87692ac 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
@@ -24,6 +24,7 @@
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
 import static android.view.WindowManager.TRANSIT_CHANGE;
+import static android.view.WindowManager.TRANSIT_CLOSE;
 import static android.view.WindowManager.TRANSIT_OPEN;
 import static android.view.WindowManager.TRANSIT_PIP;
 import static android.view.WindowManager.TRANSIT_TO_BACK;
@@ -62,7 +63,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
@@ -300,6 +301,10 @@
                     finishTransaction);
         }
 
+        if (isCurrentPipActivityClosed(info)) {
+            mPipBoundsState.setLastPipComponentName(null /* componentName */);
+        }
+
         return false;
     }
 
@@ -322,6 +327,21 @@
         return true;
     }
 
+    private boolean isCurrentPipActivityClosed(TransitionInfo info) {
+        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+            TransitionInfo.Change change = info.getChanges().get(i);
+            boolean isTaskChange = change.getTaskInfo() != null;
+            boolean hasComponentNameOfPip = change.getActivityComponent() != null
+                    && change.getActivityComponent().equals(
+                            mPipBoundsState.getLastPipComponentName());
+            if (!isTaskChange && change.getMode() == TRANSIT_CLOSE && hasComponentNameOfPip) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
     @Override
     public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
@@ -1154,6 +1174,7 @@
         }
 
         final Rect sourceBounds = pipTaskInfo.configuration.windowConfiguration.getBounds();
+        sendOnPipTransitionStarted(TRANSITION_DIRECTION_TO_PIP);
         final PipAnimationController.PipTransitionAnimator animator =
                 mPipAnimationController.getAnimator(pipTaskInfo, leash, sourceBounds, sourceBounds,
                         destinationBounds, sourceHintRect, TRANSITION_DIRECTION_TO_PIP,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
index 6eefdcf..8d36db9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
@@ -41,7 +41,7 @@
 
 import androidx.annotation.NonNull;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
 import com.android.wm.shell.common.pip.PipBoundsState;
@@ -53,8 +53,9 @@
 import com.android.wm.shell.transition.Transitions;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Executor;
 
 /**
  * Responsible supplying PiP Transitions.
@@ -66,7 +67,7 @@
     protected final ShellTaskOrganizer mShellTaskOrganizer;
     protected final PipMenuController mPipMenuController;
     protected final Transitions mTransitions;
-    private final List<PipTransitionCallback> mPipTransitionCallbacks = new ArrayList<>();
+    private final Map<PipTransitionCallback, Executor> mPipTransitionCallbacks = new HashMap<>();
     protected PipTaskOrganizer mPipOrganizer;
     protected DefaultMixedHandler mMixedHandler;
 
@@ -126,8 +127,10 @@
 
     /**
      * Called when the Shell wants to start resizing Pip transition/animation.
+     *
+     * @param duration the suggested duration for resize animation.
      */
-    public void startResizeTransition(WindowContainerTransaction wct) {
+    public void startResizeTransition(WindowContainerTransaction wct, int duration) {
         // Default implementation does nothing.
     }
 
@@ -181,16 +184,18 @@
     /**
      * Registers {@link PipTransitionCallback} to receive transition callbacks.
      */
-    public void registerPipTransitionCallback(PipTransitionCallback callback) {
-        mPipTransitionCallbacks.add(callback);
+    public void registerPipTransitionCallback(
+            @NonNull PipTransitionCallback callback, @NonNull Executor executor) {
+        mPipTransitionCallbacks.put(callback, executor);
     }
 
     protected void sendOnPipTransitionStarted(
             @PipAnimationController.TransitionDirection int direction) {
         final Rect pipBounds = mPipBoundsState.getBounds();
-        for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) {
-            final PipTransitionCallback callback = mPipTransitionCallbacks.get(i);
-            callback.onPipTransitionStarted(direction, pipBounds);
+        for (Map.Entry<PipTransitionCallback, Executor> entry
+                : mPipTransitionCallbacks.entrySet()) {
+            entry.getValue().execute(
+                    () -> entry.getKey().onPipTransitionStarted(direction, pipBounds));
         }
         if (isInPipDirection(direction) && Flags.enablePipUiStateCallbackOnEntering()) {
             try {
@@ -207,9 +212,10 @@
 
     protected void sendOnPipTransitionFinished(
             @PipAnimationController.TransitionDirection int direction) {
-        for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) {
-            final PipTransitionCallback callback = mPipTransitionCallbacks.get(i);
-            callback.onPipTransitionFinished(direction);
+        for (Map.Entry<PipTransitionCallback, Executor> entry
+                : mPipTransitionCallbacks.entrySet()) {
+            entry.getValue().execute(
+                    () -> entry.getKey().onPipTransitionFinished(direction));
         }
         if (isInPipDirection(direction) && Flags.enablePipUiStateCallbackOnEntering()) {
             try {
@@ -226,9 +232,10 @@
 
     protected void sendOnPipTransitionCancelled(
             @PipAnimationController.TransitionDirection int direction) {
-        for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) {
-            final PipTransitionCallback callback = mPipTransitionCallbacks.get(i);
-            callback.onPipTransitionCanceled(direction);
+        for (Map.Entry<PipTransitionCallback, Executor> entry
+                : mPipTransitionCallbacks.entrySet()) {
+            entry.getValue().execute(
+                    () -> entry.getKey().onPipTransitionCanceled(direction));
         }
     }
 
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 0169e8c..c7369a3 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
@@ -32,7 +32,7 @@
 import android.view.ViewRootImpl;
 import android.view.WindowManagerGlobal;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SystemWindows;
 import com.android.wm.shell.common.pip.PipBoundsState;
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 8c4bf76..d1d8275 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
@@ -59,7 +59,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.jank.InteractionJankMonitor;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.WindowManagerShellWrapper;
 import com.android.wm.shell.common.DisplayChangeController;
@@ -106,6 +106,7 @@
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
+import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 
 /**
@@ -367,15 +368,6 @@
                     false /* fromRotation */, fromImeAdjustment, false /* fromShelfAdjustment */,
                     null /* windowContainerTransaction */);
         }
-
-        @Override
-        public void onActivityHidden(ComponentName componentName) {
-            if (componentName.equals(mPipBoundsState.getLastPipComponentName())) {
-                // The activity was removed, we don't want to restore to the reentry state
-                // saved for this component anymore.
-                mPipBoundsState.setLastPipComponentName(null);
-            }
-        }
     }
 
     /**
@@ -487,7 +479,7 @@
         mShellCommandHandler.addDumpCallback(this::dump, this);
         mPipInputConsumer = new PipInputConsumer(WindowManagerGlobal.getWindowManagerService(),
                 INPUT_CONSUMER_PIP, mMainExecutor);
-        mPipTransitionController.registerPipTransitionCallback(this);
+        mPipTransitionController.registerPipTransitionCallback(this, mMainExecutor);
         mPipTaskOrganizer.registerOnDisplayIdChangeCallback((int displayId) -> {
             mPipDisplayLayoutState.setDisplayId(displayId);
             onDisplayChanged(mDisplayController.getDisplayLayout(displayId),
@@ -1229,8 +1221,11 @@
         }
 
         @Override
-        public PipTransitionController getPipTransitionController() {
-            return mPipTransitionController;
+        public void registerPipTransitionCallback(
+                PipTransitionController.PipTransitionCallback callback,
+                Executor executor) {
+            mMainExecutor.execute(() -> mPipTransitionController.registerPipTransitionCallback(
+                    callback, executor));
         }
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java
index f6cab48..d1978c3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipInputConsumer.java
@@ -28,7 +28,7 @@
 import android.view.InputChannel;
 import android.view.InputEvent;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
index 15342be..c189642 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
@@ -59,7 +59,7 @@
 import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.animation.Interpolators;
 import com.android.wm.shell.common.ShellExecutor;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
index ef46843..df3803d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
@@ -34,10 +34,11 @@
 import android.graphics.Rect;
 import android.os.Debug;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.animation.FloatProperties;
 import com.android.wm.shell.common.FloatingContentCoordinator;
+import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.magnetictarget.MagnetizedObject;
 import com.android.wm.shell.common.pip.PipAppOpsListener;
 import com.android.wm.shell.common.pip.PipBoundsState;
@@ -47,6 +48,7 @@
 import com.android.wm.shell.pip.PipTransitionController;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.shared.animation.PhysicsAnimator;
+import com.android.wm.shell.shared.annotations.ShellMainThread;
 
 import kotlin.Unit;
 import kotlin.jvm.functions.Function0;
@@ -171,7 +173,9 @@
         public void onPipTransitionCanceled(int direction) {}
     };
 
-    public PipMotionHelper(Context context, @NonNull PipBoundsState pipBoundsState,
+    public PipMotionHelper(Context context,
+            @ShellMainThread ShellExecutor mainExecutor,
+            @NonNull PipBoundsState pipBoundsState,
             PipTaskOrganizer pipTaskOrganizer, PhonePipMenuController menuController,
             PipSnapAlgorithm snapAlgorithm, PipTransitionController pipTransitionController,
             FloatingContentCoordinator floatingContentCoordinator,
@@ -183,7 +187,7 @@
         mSnapAlgorithm = snapAlgorithm;
         mFloatingContentCoordinator = floatingContentCoordinator;
         mPipPerfHintController = pipPerfHintControllerOptional.orElse(null);
-        pipTransitionController.registerPipTransitionCallback(mPipTransitionCallback);
+        pipTransitionController.registerPipTransitionCallback(mPipTransitionCallback, mainExecutor);
         mResizePipUpdateListener = (target, values) -> {
             if (mPipBoundsState.getMotionBoundsState().isInMotion()) {
                 mPipTaskOrganizer.scheduleUserResizePip(getBounds(),
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
index d8ac8e9..9c4e723 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
@@ -48,7 +48,7 @@
 import android.view.accessibility.AccessibilityWindowInfo;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.FloatingContentCoordinator;
 import com.android.wm.shell.common.ShellExecutor;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java
index 5d858fa..cb82db6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java
@@ -23,7 +23,7 @@
 import android.view.ViewConfiguration;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipActionsProvider.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipActionsProvider.java
index 6b890c4..50d22ad 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipActionsProvider.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipActionsProvider.java
@@ -33,7 +33,7 @@
 import android.content.Context;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.pip.PipMediaController;
 import com.android.wm.shell.common.pip.PipUtils;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBackgroundView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBackgroundView.java
index 0221db8..eb7a10c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBackgroundView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBackgroundView.java
@@ -28,7 +28,7 @@
 
 import androidx.annotation.NonNull;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
index 72c0cd7..188c35f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsAlgorithm.java
@@ -33,7 +33,7 @@
 
 import androidx.annotation.NonNull;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsController.java
index 8a215b4..1afb470 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsController.java
@@ -26,7 +26,7 @@
 import android.os.Handler;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.pip.tv.TvPipKeepClearAlgorithm.Placement;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
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 3d28646..0ed5079 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
@@ -39,7 +39,7 @@
 
 import androidx.annotation.NonNull;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.WindowManagerShellWrapper;
 import com.android.wm.shell.common.DisplayController;
@@ -257,7 +257,7 @@
     }
 
     private void onInit() {
-        mPipTransitionController.registerPipTransitionCallback(this);
+        mPipTransitionController.registerPipTransitionCallback(this, mMainExecutor);
 
         reloadResources();
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipCustomAction.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipCustomAction.java
index 977aad4..327ceef 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipCustomAction.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipCustomAction.java
@@ -27,7 +27,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.TvWindowMenuActionButton;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
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 6b5bdd2..e74870d 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
@@ -37,7 +37,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.SystemWindows;
 import com.android.wm.shell.common.pip.PipMenuController;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuEduTextDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuEduTextDrawer.java
index adc03cf..eabf1b0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuEduTextDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuEduTextDrawer.java
@@ -39,7 +39,7 @@
 
 import androidx.annotation.NonNull;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 
 import java.util.Arrays;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
index 4a767ef..c7704f0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java
@@ -50,7 +50,7 @@
 
 import androidx.annotation.NonNull;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.widget.LinearLayoutManager;
 import com.android.internal.widget.RecyclerView;
 import com.android.wm.shell.R;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
index 54e162b..ce50792 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipNotificationController.java
@@ -33,7 +33,7 @@
 import android.text.TextUtils;
 
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.ImageUtils;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.pip.PipMediaController;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTransition.java
index ca0d61f..7a0e669 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipTransition.java
@@ -62,7 +62,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.pip.PipDisplayLayoutState;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java
index 5c561fe..88f9e4c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipResizeAnimator.java
@@ -47,9 +47,17 @@
     @Nullable
     private Runnable mAnimationEndCallback;
     private RectEvaluator mRectEvaluator;
+
+    // Bounds relative to which scaling/cropping must be done.
     private final Rect mBaseBounds = new Rect();
+
+    // Bounds to animate from.
     private final Rect mStartBounds = new Rect();
+
+    // Target bounds.
     private final Rect mEndBounds = new Rect();
+
+    // Bounds updated by the evaluator as animator is running.
     private final Rect mAnimatedRect = new Rect();
     private final float mDelta;
 
@@ -84,7 +92,6 @@
         addListener(this);
         addUpdateListener(this);
         setEvaluator(mRectEvaluator);
-        // TODO: change this
         setDuration(duration);
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java
index 6e36a32..9cfe162 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PhonePipMenuController.java
@@ -32,7 +32,7 @@
 import android.view.ViewRootImpl;
 import android.view.WindowManagerGlobal;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SystemWindows;
 import com.android.wm.shell.common.pip.PipBoundsState;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
index fc0d36d..06adad6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
@@ -36,7 +36,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.Preconditions;
 import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTaskOrganizer;
@@ -352,6 +352,7 @@
         mPipBoundsAlgorithm.dump(pw, innerPrefix);
         mPipBoundsState.dump(pw, innerPrefix);
         mPipDisplayLayoutState.dump(pw, innerPrefix);
+        mPipTransitionState.dump(pw, innerPrefix);
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipInputConsumer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipInputConsumer.java
index b757b00..ffda56d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipInputConsumer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipInputConsumer.java
@@ -28,7 +28,7 @@
 import android.view.InputChannel;
 import android.view.InputEvent;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMenuView.java
index 42b8e9f..c54e4cd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMenuView.java
@@ -59,7 +59,7 @@
 import android.widget.FrameLayout;
 import android.widget.LinearLayout;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.animation.Interpolators;
 import com.android.wm.shell.common.ShellExecutor;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
index 495cd00..e277a8d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
@@ -16,6 +16,7 @@
 
 package com.android.wm.shell.pip2.phone;
 
+import static androidx.dynamicanimation.animation.SpringForce.DAMPING_RATIO_LOW_BOUNCY;
 import static androidx.dynamicanimation.animation.SpringForce.DAMPING_RATIO_NO_BOUNCY;
 import static androidx.dynamicanimation.animation.SpringForce.STIFFNESS_LOW;
 import static androidx.dynamicanimation.animation.SpringForce.STIFFNESS_MEDIUM;
@@ -25,6 +26,7 @@
 import static com.android.wm.shell.common.pip.PipBoundsState.STASH_TYPE_RIGHT;
 import static com.android.wm.shell.pip2.phone.PipMenuView.ANIM_TYPE_DISMISS;
 import static com.android.wm.shell.pip2.phone.PipMenuView.ANIM_TYPE_NONE;
+import static com.android.wm.shell.pip2.phone.PipTransition.ANIMATING_BOUNDS_CHANGE_DURATION;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -35,7 +37,8 @@
 import android.os.Debug;
 import android.view.SurfaceControl;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
+import com.android.internal.util.Preconditions;
 import com.android.wm.shell.R;
 import com.android.wm.shell.animation.FloatProperties;
 import com.android.wm.shell.common.FloatingContentCoordinator;
@@ -45,6 +48,7 @@
 import com.android.wm.shell.common.pip.PipBoundsState;
 import com.android.wm.shell.common.pip.PipPerfHintController;
 import com.android.wm.shell.common.pip.PipSnapAlgorithm;
+import com.android.wm.shell.pip2.animation.PipResizeAnimator;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.shared.animation.PhysicsAnimator;
 
@@ -62,6 +66,7 @@
         PipTransitionState.PipTransitionStateChangedListener {
     private static final String TAG = "PipMotionHelper";
     private static final String FLING_BOUNDS_CHANGE = "fling_bounds_change";
+    private static final String ANIMATING_BOUNDS_CHANGE = "animating_bounds_change";
     private static final boolean DEBUG = false;
 
     private static final int SHRINK_STACK_FROM_MENU_DURATION = 250;
@@ -113,7 +118,7 @@
 
     /** SpringConfig to use for fling-then-spring animations. */
     private final PhysicsAnimator.SpringConfig mSpringConfig =
-            new PhysicsAnimator.SpringConfig(700f, DAMPING_RATIO_NO_BOUNCY);
+            new PhysicsAnimator.SpringConfig(300f, DAMPING_RATIO_LOW_BOUNCY);
 
     /** SpringConfig used for animating into the dismiss region, matches the one in
      * {@link MagnetizedObject}. */
@@ -152,9 +157,16 @@
     private boolean mDismissalPending = false;
 
     /**
-     * Set to true if bounds change transition has been scheduled from PipMotionHelper.
+     * Set to true if bounds change transition has been scheduled from PipMotionHelper
+     * after animating is over.
      */
-    private boolean mWaitingForBoundsChangeTransition = false;
+    private boolean mWaitingForFlingTransition = false;
+
+    /**
+     * Set to true if bounds change transition has been scheduled from PipMotionHelper,
+     * and if the animation is supposed to run while transition is playing.
+     */
+    private boolean mWaitingToPlayBoundsChangeTransition = false;
 
     /**
      * Gets set in {@link #animateToExpandedState(Rect, Rect, Rect, Runnable)}, this callback is
@@ -634,6 +646,9 @@
         // The physics animation ended, though we may not necessarily be done animating, such as
         // when we're still dragging after moving out of the magnetic target.
         if (!mDismissalPending && !mSpringingToTouch && !mMagnetizedPip.getObjectStuckToTarget()) {
+            // Update the earlier estimate on bounds we are animating towards, since physics
+            // animator is non-deterministic.
+            setAnimatingToBounds(mPipBoundsState.getMotionBoundsState().getBoundsInMotion());
             // do not schedule resize if PiP is dismissing, which may cause app re-open to
             // mBounds instead of its normal bounds.
             Bundle extra = new Bundle();
@@ -673,6 +688,11 @@
      * Directly resizes the PiP to the given {@param bounds}.
      */
     private void resizeAndAnimatePipUnchecked(Rect toBounds, int duration) {
+        if (mPipBoundsState.getMotionBoundsState().isInMotion()) {
+            // Do not carry out any resizing if we are dragging or physics animator is running.
+            return;
+        }
+
         if (DEBUG) {
             ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                     "%s: resizeAndAnimatePipUnchecked: toBounds=%s"
@@ -682,10 +702,11 @@
 
         // Intentionally resize here even if the current bounds match the destination bounds.
         // This is so all the proper callbacks are performed.
-
-        // mPipTaskOrganizer.scheduleAnimateResizePip(toBounds, duration,
-        //         TRANSITION_DIRECTION_EXPAND_OR_UNEXPAND, null /* updateBoundsCallback */);
-        // setAnimatingToBounds(toBounds);
+        setAnimatingToBounds(toBounds);
+        Bundle extra = new Bundle();
+        extra.putBoolean(ANIMATING_BOUNDS_CHANGE, true);
+        extra.putInt(ANIMATING_BOUNDS_CHANGE_DURATION, duration);
+        mPipTransitionState.setState(PipTransitionState.SCHEDULED_BOUNDS_CHANGE, extra);
     }
 
     @Override
@@ -694,7 +715,11 @@
             @Nullable Bundle extra) {
         switch (newState) {
             case PipTransitionState.SCHEDULED_BOUNDS_CHANGE:
-                if (!extra.getBoolean(FLING_BOUNDS_CHANGE)) break;
+                mWaitingForFlingTransition = extra.getBoolean(FLING_BOUNDS_CHANGE);
+                mWaitingToPlayBoundsChangeTransition = extra.getBoolean(ANIMATING_BOUNDS_CHANGE);
+                if (!mWaitingForFlingTransition && !mWaitingToPlayBoundsChangeTransition) {
+                    break;
+                }
 
                 if (mPipBoundsState.getBounds().equals(
                         mPipBoundsState.getMotionBoundsState().getBoundsInMotion())) {
@@ -709,30 +734,30 @@
                     break;
                 }
 
-                // If touch is turned off and we are in a fling animation, schedule a transition.
-                mWaitingForBoundsChangeTransition = true;
+                // Delay config until the end, if we are animating after scheduling the transition.
                 mPipScheduler.scheduleAnimateResizePip(
-                        mPipBoundsState.getMotionBoundsState().getBoundsInMotion());
+                        mPipBoundsState.getMotionBoundsState().getAnimatingToBounds(),
+                        mWaitingToPlayBoundsChangeTransition,
+                        extra.getInt(ANIMATING_BOUNDS_CHANGE_DURATION,
+                                PipTransition.BOUNDS_CHANGE_JUMPCUT_DURATION));
                 break;
             case PipTransitionState.CHANGING_PIP_BOUNDS:
-                if (!mWaitingForBoundsChangeTransition) break;
-
-                // If bounds change transition was scheduled from this class, handle leash updates.
-                mWaitingForBoundsChangeTransition = false;
                 SurfaceControl.Transaction startTx = extra.getParcelable(
                         PipTransition.PIP_START_TX, SurfaceControl.Transaction.class);
+                SurfaceControl.Transaction finishTx = extra.getParcelable(
+                        PipTransition.PIP_FINISH_TX, SurfaceControl.Transaction.class);
                 Rect destinationBounds = extra.getParcelable(
                         PipTransition.PIP_DESTINATION_BOUNDS, Rect.class);
-                startTx.setPosition(mPipTransitionState.mPinnedTaskLeash,
-                        destinationBounds.left, destinationBounds.top);
-                startTx.apply();
+                final int duration = extra.getInt(ANIMATING_BOUNDS_CHANGE_DURATION,
+                        PipTransition.BOUNDS_CHANGE_JUMPCUT_DURATION);
 
-                // All motion operations have actually finished, so make bounds cache updates.
-                settlePipBoundsAfterPhysicsAnimation(false /* animatingAfter */);
-                cleanUpHighPerfSessionMaybe();
-
-                // Signal that the transition is done - should update transition state by default.
-                mPipScheduler.scheduleFinishResizePip(false /* configAtEnd */);
+                if (mWaitingForFlingTransition) {
+                    mWaitingForFlingTransition = false;
+                    handleFlingTransition(startTx, finishTx, destinationBounds);
+                } else if (mWaitingToPlayBoundsChangeTransition) {
+                    mWaitingToPlayBoundsChangeTransition = false;
+                    startResizeAnimation(startTx, finishTx, destinationBounds, duration);
+                }
                 break;
             case PipTransitionState.EXITING_PIP:
                 // We need to force finish any local animators if about to leave PiP, to avoid
@@ -740,9 +765,46 @@
                 if (!mPipBoundsState.getMotionBoundsState().isInMotion()) break;
                 cancelPhysicsAnimation();
                 settlePipBoundsAfterPhysicsAnimation(false /* animatingAfter */);
+                break;
         }
     }
 
+    private void handleFlingTransition(SurfaceControl.Transaction startTx,
+            SurfaceControl.Transaction finishTx, Rect destinationBounds) {
+        startTx.setPosition(mPipTransitionState.mPinnedTaskLeash,
+                destinationBounds.left, destinationBounds.top);
+        startTx.apply();
+
+        // All motion operations have actually finished, so make bounds cache updates.
+        settlePipBoundsAfterPhysicsAnimation(false /* animatingAfter */);
+        cleanUpHighPerfSessionMaybe();
+
+        // Signal that the transition is done - should update transition state by default.
+        mPipScheduler.scheduleFinishResizePip(false /* configAtEnd */);
+    }
+
+    private void startResizeAnimation(SurfaceControl.Transaction startTx,
+            SurfaceControl.Transaction finishTx, Rect destinationBounds, int duration) {
+        SurfaceControl pipLeash = mPipTransitionState.mPinnedTaskLeash;
+        Preconditions.checkState(pipLeash != null,
+                "No leash cached by mPipTransitionState=" + mPipTransitionState);
+
+        startTx.setWindowCrop(pipLeash, mPipBoundsState.getBounds().width(),
+                mPipBoundsState.getBounds().height());
+
+        PipResizeAnimator animator = new PipResizeAnimator(mContext, pipLeash,
+                startTx, finishTx, mPipBoundsState.getBounds(), mPipBoundsState.getBounds(),
+                destinationBounds, duration, 0f /* angle */);
+        animator.setAnimationEndCallback(() -> {
+            mPipBoundsState.setBounds(destinationBounds);
+            // All motion operations have actually finished, so make bounds cache updates.
+            cleanUpHighPerfSessionMaybe();
+            // Signal that we are done with resize transition
+            mPipScheduler.scheduleFinishResizePip(true /* configAtEnd */);
+        });
+        animator.start();
+    }
+
     private void settlePipBoundsAfterPhysicsAnimation(boolean animatingAfter) {
         if (!animatingAfter) {
             // The physics animation ended, though we may not necessarily be done animating, such as
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java
index 33e80bd..5b0ca18 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java
@@ -16,6 +16,7 @@
 package com.android.wm.shell.pip2.phone;
 
 import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_NONE;
+import static com.android.wm.shell.pip2.phone.PipTransition.ANIMATING_BOUNDS_CHANGE_DURATION;
 
 import android.annotation.Nullable;
 import android.content.Context;
@@ -535,7 +536,8 @@
                 mWaitingForBoundsChangeTransition = true;
 
                 // Schedule PiP resize transition, but delay any config updates until very end.
-                mPipScheduler.scheduleAnimateResizePip(mLastResizeBounds, true /* configAtEnd */);
+                mPipScheduler.scheduleAnimateResizePip(mLastResizeBounds,
+                        true /* configAtEnd */, PINCH_RESIZE_SNAP_DURATION);
                 break;
             case PipTransitionState.CHANGING_PIP_BOUNDS:
                 if (!mWaitingForBoundsChangeTransition) break;
@@ -550,12 +552,15 @@
                         PipTransition.PIP_START_TX, SurfaceControl.Transaction.class);
                 SurfaceControl.Transaction finishTx = extra.getParcelable(
                         PipTransition.PIP_FINISH_TX, SurfaceControl.Transaction.class);
+                final int duration = extra.getInt(ANIMATING_BOUNDS_CHANGE_DURATION,
+                        PipTransition.BOUNDS_CHANGE_JUMPCUT_DURATION);
+
                 startTx.setWindowCrop(pipLeash, mPipBoundsState.getBounds().width(),
                         mPipBoundsState.getBounds().height());
 
                 PipResizeAnimator animator = new PipResizeAnimator(mContext, pipLeash,
                         startTx, finishTx, mPipBoundsState.getBounds(), mStartBoundsAfterRelease,
-                        mLastResizeBounds, PINCH_RESIZE_SNAP_DURATION, mAngle);
+                        mLastResizeBounds, duration, mAngle);
                 animator.setAnimationEndCallback(() -> {
                     // All motion operations have actually finished, so make bounds cache updates.
                     mUpdateResizeBoundsCallback.accept(mLastResizeBounds);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
index 9c1e321..ac670cf 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
@@ -33,7 +33,7 @@
 import androidx.annotation.Nullable;
 import androidx.core.content.ContextCompat;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.pip.PipBoundsState;
 import com.android.wm.shell.common.pip.PipUtils;
@@ -162,6 +162,18 @@
      * @param configAtEnd true if we are delaying config updates until the transition ends.
      */
     public void scheduleAnimateResizePip(Rect toBounds, boolean configAtEnd) {
+        scheduleAnimateResizePip(toBounds, configAtEnd,
+                PipTransition.BOUNDS_CHANGE_JUMPCUT_DURATION);
+    }
+
+    /**
+     * Animates resizing of the pinned stack given the duration.
+     *
+     * @param configAtEnd true if we are delaying config updates until the transition ends.
+     * @param duration    the suggested duration to run the animation; the component responsible
+     *                    for running the animator will get this as an extra.
+     */
+    public void scheduleAnimateResizePip(Rect toBounds, boolean configAtEnd, int duration) {
         if (mPipTransitionState.mPipTaskToken == null || !mPipTransitionState.isInPip()) {
             return;
         }
@@ -170,7 +182,7 @@
         if (configAtEnd) {
             wct.deferConfigToTransitionEnd(mPipTransitionState.mPipTaskToken);
         }
-        mPipTransitionController.startResizeTransition(wct);
+        mPipTransitionController.startResizeTransition(wct, duration);
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
index 56a465a..0c4ed26 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
@@ -51,7 +51,7 @@
 import android.view.accessibility.AccessibilityWindowInfo;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.FloatingContentCoordinator;
 import com.android.wm.shell.common.ShellExecutor;
@@ -713,15 +713,13 @@
         }
     }
 
-    private void animateToMaximizedState(Runnable callback) {
-        Rect maxMovementBounds = new Rect();
+    private void animateToMaximizedState() {
         Rect maxBounds = new Rect(0, 0, mPipBoundsState.getMaxSize().x,
                 mPipBoundsState.getMaxSize().y);
-        mPipBoundsAlgorithm.getMovementBounds(maxBounds, mInsetBounds, maxMovementBounds,
-                mIsImeShowing ? mImeHeight : 0);
+
         mSavedSnapFraction = mMotionHelper.animateToExpandedState(maxBounds,
-                mPipBoundsState.getMovementBounds(), maxMovementBounds,
-                callback);
+                getMovementBounds(mPipBoundsState.getBounds()),
+                getMovementBounds(maxBounds), null /* callback */);
     }
 
     private void animateToNormalSize(Runnable callback) {
@@ -729,22 +727,20 @@
         mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds());
 
         final Size minMenuSize = mMenuController.getEstimatedMinMenuSize();
-        final Rect normalBounds = mPipBoundsState.getNormalBounds();
-        final Rect destBounds = mPipBoundsAlgorithm.adjustNormalBoundsToFitMenu(normalBounds,
-                minMenuSize);
-        Rect restoredMovementBounds = new Rect();
-        mPipBoundsAlgorithm.getMovementBounds(destBounds,
-                mInsetBounds, restoredMovementBounds, mIsImeShowing ? mImeHeight : 0);
-        mSavedSnapFraction = mMotionHelper.animateToExpandedState(destBounds,
-                mPipBoundsState.getMovementBounds(), restoredMovementBounds, callback);
+        final Size defaultSize = mSizeSpecSource.getDefaultSize(mPipBoundsState.getAspectRatio());
+        final Rect normalBounds = new Rect(0, 0, defaultSize.getWidth(), defaultSize.getHeight());
+        final Rect adjustedNormalBounds = mPipBoundsAlgorithm.adjustNormalBoundsToFitMenu(
+                normalBounds, minMenuSize);
+
+        mSavedSnapFraction = mMotionHelper.animateToExpandedState(adjustedNormalBounds,
+                getMovementBounds(mPipBoundsState.getBounds()),
+                getMovementBounds(adjustedNormalBounds), callback /* callback */);
     }
 
     private void animateToUnexpandedState(Rect restoreBounds) {
-        Rect restoredMovementBounds = new Rect();
-        mPipBoundsAlgorithm.getMovementBounds(restoreBounds,
-                mInsetBounds, restoredMovementBounds, mIsImeShowing ? mImeHeight : 0);
         mMotionHelper.animateToUnexpandedState(restoreBounds, mSavedSnapFraction,
-                restoredMovementBounds, mPipBoundsState.getMovementBounds(), false /* immediate */);
+                getMovementBounds(restoreBounds),
+                getMovementBounds(mPipBoundsState.getBounds()), false /* immediate */);
         mSavedSnapFraction = -1f;
     }
 
@@ -919,10 +915,6 @@
                     && mMenuState != MENU_STATE_FULL) {
                 // If using pinch to zoom, double-tap functions as resizing between max/min size
                 if (mPipResizeGestureHandler.isUsingPinchToZoom()) {
-                    final boolean toExpand = mPipBoundsState.getBounds().width()
-                            < mPipBoundsState.getMaxSize().x
-                            && mPipBoundsState.getBounds().height()
-                            < mPipBoundsState.getMaxSize().y;
                     if (mMenuController.isMenuVisible()) {
                         mMenuController.hideMenu(ANIM_TYPE_NONE, false /* resize */);
                     }
@@ -934,7 +926,7 @@
                     // actually toggle to the size chosen
                     if (nextSize == PipDoubleTapHelper.SIZE_SPEC_MAX) {
                         mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds());
-                        animateToMaximizedState(null);
+                        animateToMaximizedState();
                     } else if (nextSize == PipDoubleTapHelper.SIZE_SPEC_DEFAULT) {
                         mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds());
                         animateToNormalSize(null);
@@ -1045,7 +1037,9 @@
 
     private Rect getMovementBounds(Rect curBounds) {
         Rect movementBounds = new Rect();
-        mPipBoundsAlgorithm.getMovementBounds(curBounds, mInsetBounds,
+        Rect insetBounds = new Rect();
+        mPipBoundsAlgorithm.getInsetBounds(insetBounds);
+        mPipBoundsAlgorithm.getMovementBounds(curBounds, insetBounds,
                 movementBounds, mIsImeShowing ? mImeHeight : 0);
         return movementBounds;
     }
@@ -1091,6 +1085,7 @@
             case PipTransitionState.ENTERED_PIP:
                 onActivityPinned();
                 mTouchState.setAllowInputEvents(true);
+                mTouchState.reset();
                 break;
             case PipTransitionState.EXITED_PIP:
                 mTouchState.setAllowInputEvents(false);
@@ -1101,6 +1096,7 @@
                 break;
             case PipTransitionState.CHANGED_PIP_BOUNDS:
                 mTouchState.setAllowInputEvents(true);
+                mTouchState.reset();
                 break;
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchState.java
index d093f1e..bb8d4ee 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchState.java
@@ -23,7 +23,7 @@
 import android.view.ViewConfiguration;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
index 57dc5f9..683d30d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
@@ -71,6 +71,9 @@
     static final String PIP_START_TX = "pip_start_tx";
     static final String PIP_FINISH_TX = "pip_finish_tx";
     static final String PIP_DESTINATION_BOUNDS = "pip_dest_bounds";
+    static final String ANIMATING_BOUNDS_CHANGE_DURATION =
+            "animating_bounds_change_duration";
+    static final int BOUNDS_CHANGE_JUMPCUT_DURATION = 0;
 
     /**
      * The fixed start delay in ms when fading out the content overlay from bounds animation.
@@ -87,7 +90,7 @@
     private final PipTransitionState mPipTransitionState;
 
     //
-    // Transition tokens
+    // Transition caches
     //
 
     @Nullable
@@ -96,6 +99,8 @@
     private IBinder mExitViaExpandTransition;
     @Nullable
     private IBinder mResizeTransition;
+    private int mBoundsChangeDuration = BOUNDS_CHANGE_JUMPCUT_DURATION;
+
 
     //
     // Internal state and relevant cached info
@@ -152,11 +157,12 @@
     }
 
     @Override
-    public void startResizeTransition(WindowContainerTransaction wct) {
+    public void startResizeTransition(WindowContainerTransaction wct, int duration) {
         if (wct == null) {
             return;
         }
         mResizeTransition = mTransitions.startTransition(TRANSIT_RESIZE_PIP, wct, this);
+        mBoundsChangeDuration = duration;
     }
 
     @Nullable
@@ -272,6 +278,10 @@
         extra.putParcelable(PIP_START_TX, startTransaction);
         extra.putParcelable(PIP_FINISH_TX, finishTransaction);
         extra.putParcelable(PIP_DESTINATION_BOUNDS, pipChange.getEndAbsBounds());
+        if (mBoundsChangeDuration > BOUNDS_CHANGE_JUMPCUT_DURATION) {
+            extra.putInt(ANIMATING_BOUNDS_CHANGE_DURATION, mBoundsChangeDuration);
+            mBoundsChangeDuration = BOUNDS_CHANGE_JUMPCUT_DURATION;
+        }
 
         mFinishCallback = finishCallback;
         mPipTransitionState.setState(PipTransitionState.CHANGING_PIP_BOUNDS, extra);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
index 9d599ca..29272be 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransitionState.java
@@ -29,6 +29,7 @@
 import com.android.internal.util.Preconditions;
 import com.android.wm.shell.shared.annotations.ShellMainThread;
 
+import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
@@ -62,6 +63,8 @@
  * and throw an <code>IllegalStateException</code> otherwise.</p>
  */
 public class PipTransitionState {
+    private static final String TAG = PipTransitionState.class.getSimpleName();
+
     public static final int UNDEFINED = 0;
 
     // State for Launcher animating the swipe PiP to home animation.
@@ -190,8 +193,9 @@
                     "No extra bundle for " + stateToString(state) + " state.");
         }
         if (mState != state) {
-            dispatchPipTransitionStateChanged(mState, state, extra);
+            final int prevState = mState;
             mState = state;
+            dispatchPipTransitionStateChanged(prevState, mState, extra);
         }
     }
 
@@ -319,4 +323,11 @@
         return String.format("PipTransitionState(mState=%s, mInSwipePipToHomeTransition=%b)",
                 stateToString(mState), mInSwipePipToHomeTransition);
     }
+
+    /** Dumps internal state. */
+    public void dump(PrintWriter pw, String prefix) {
+        final String innerPrefix = prefix + "  ";
+        pw.println(prefix + TAG);
+        pw.println(innerPrefix + "mState=" + stateToString(mState));
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index 03c8cf8..9539a45 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -37,13 +37,14 @@
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.view.IRecentsAnimationRunner;
+import android.window.WindowContainerToken;
 
 import androidx.annotation.BinderThread;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.ExternalInterfaceBinder;
 import com.android.wm.shell.common.RemoteCallable;
 import com.android.wm.shell.common.ShellExecutor;
@@ -52,9 +53,9 @@
 import com.android.wm.shell.common.TaskStackListenerImpl;
 import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
-import com.android.wm.shell.shared.DesktopModeStatus;
 import com.android.wm.shell.shared.annotations.ExternalThread;
 import com.android.wm.shell.shared.annotations.ShellMainThread;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.sysui.ShellCommandHandler;
 import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.sysui.ShellInit;
@@ -65,9 +66,11 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.Set;
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 
@@ -394,6 +397,7 @@
         }
 
         ArrayList<ActivityManager.RecentTaskInfo> freeformTasks = new ArrayList<>();
+        Set<Integer> minimizedFreeformTasks = new HashSet<>();
 
         int mostRecentFreeformTaskIndex = Integer.MAX_VALUE;
 
@@ -409,15 +413,14 @@
             if (DesktopModeStatus.canEnterDesktopMode(mContext)
                     && mDesktopModeTaskRepository.isPresent()
                     && mDesktopModeTaskRepository.get().isActiveTask(taskInfo.taskId)) {
-                if (mDesktopModeTaskRepository.get().isMinimizedTask(taskInfo.taskId)) {
-                    // Minimized freeform tasks should not be shown at all.
-                    continue;
-                }
                 // Freeform tasks will be added as a separate entry
                 if (mostRecentFreeformTaskIndex == Integer.MAX_VALUE) {
                     mostRecentFreeformTaskIndex = recentTasks.size();
                 }
                 freeformTasks.add(taskInfo);
+                if (mDesktopModeTaskRepository.get().isMinimizedTask(taskInfo.taskId)) {
+                    minimizedFreeformTasks.add(taskInfo.taskId);
+                }
                 continue;
             }
 
@@ -435,8 +438,10 @@
 
         // Add a special entry for freeform tasks
         if (!freeformTasks.isEmpty()) {
-            recentTasks.add(mostRecentFreeformTaskIndex, GroupedRecentTaskInfo.forFreeformTasks(
-                    freeformTasks.toArray(new ActivityManager.RecentTaskInfo[0])));
+            recentTasks.add(mostRecentFreeformTaskIndex,
+                    GroupedRecentTaskInfo.forFreeformTasks(
+                            freeformTasks.toArray(new ActivityManager.RecentTaskInfo[0]),
+                            minimizedFreeformTasks));
         }
 
         return recentTasks;
@@ -453,11 +458,31 @@
     }
 
     /**
-     * Find the background task that match the given component.
+     * Returns the top running leaf task ignoring {@param ignoreTaskToken} if it is specified.
+     * NOTE: This path currently makes assumptions that ignoreTaskToken is for the top task.
+     */
+    @Nullable
+    public ActivityManager.RunningTaskInfo getTopRunningTask(
+            @Nullable WindowContainerToken ignoreTaskToken) {
+        List<ActivityManager.RunningTaskInfo> tasks = mActivityTaskManager.getTasks(2,
+                false /* filterOnlyVisibleRecents */);
+        for (int i = tasks.size() - 1; i >= 0; i--) {
+            final ActivityManager.RunningTaskInfo task = tasks.get(i);
+            if (task.token.equals(ignoreTaskToken)) {
+                continue;
+            }
+            return task;
+        }
+        return null;
+    }
+
+    /**
+     * Find the background task that match the given component.  Ignores tasks match
+     * {@param ignoreTaskToken} if it is non-null.
      */
     @Nullable
     public ActivityManager.RecentTaskInfo findTaskInBackground(ComponentName componentName,
-            int userId) {
+            int userId, @Nullable WindowContainerToken ignoreTaskToken) {
         if (componentName == null) {
             return null;
         }
@@ -469,6 +494,9 @@
             if (task.isVisible) {
                 continue;
             }
+            if (task.token.equals(ignoreTaskToken)) {
+                continue;
+            }
             if (componentName.equals(task.baseIntent.getComponent()) && userId == task.userId) {
                 return task;
             }
@@ -636,7 +664,7 @@
         @Override
         public ActivityManager.RunningTaskInfo[] getRunningTasks(int maxNum) {
             final ActivityManager.RunningTaskInfo[][] tasks =
-                    new ActivityManager.RunningTaskInfo[][] {null};
+                    new ActivityManager.RunningTaskInfo[][]{null};
             executeRemoteCallWithTaskPermission(mController, "getRunningTasks",
                     (controller) -> tasks[0] = ActivityTaskManager.getInstance().getTasks(maxNum)
                             .toArray(new ActivityManager.RunningTaskInfo[0]),
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index 3a266d9..234b4d0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -63,7 +63,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.IResultReceiver;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.pip.PipUtils;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/TaskStackTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/TaskStackTransitionObserver.kt
index 7c5f10a..8ee72b4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/TaskStackTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/TaskStackTransitionObserver.kt
@@ -76,21 +76,40 @@
                     continue
                 }
 
+                // Filter out changes that we care about
                 if (change.mode == WindowManager.TRANSIT_OPEN) {
                     change.taskInfo?.let { taskInfoList.add(it) }
                     transitionTypeList.add(change.mode)
                 }
             }
-            transitionToTransitionChanges.put(
-                transition,
-                TransitionChanges(taskInfoList, transitionTypeList)
-            )
+            // Only add the transition to map if it has a change we care about
+            if (taskInfoList.isNotEmpty()) {
+                transitionToTransitionChanges.put(
+                    transition,
+                    TransitionChanges(taskInfoList, transitionTypeList)
+                )
+            }
         }
     }
 
     override fun onTransitionStarting(transition: IBinder) {}
 
-    override fun onTransitionMerged(merged: IBinder, playing: IBinder) {}
+    override fun onTransitionMerged(merged: IBinder, playing: IBinder) {
+        val mergedTransitionChanges =
+            transitionToTransitionChanges.get(merged)
+                ?:
+                // We are adding changes of the merged transition to changes of the playing
+                // transition so if there is no changes nothing to do.
+                return
+
+        transitionToTransitionChanges.remove(merged)
+        val playingTransitionChanges = transitionToTransitionChanges.get(playing)
+        if (playingTransitionChanges != null) {
+            playingTransitionChanges.merge(mergedTransitionChanges)
+        } else {
+            transitionToTransitionChanges.put(playing, mergedTransitionChanges)
+        }
+    }
 
     override fun onTransitionFinished(transition: IBinder, aborted: Boolean) {
         val taskInfoList =
@@ -138,6 +157,11 @@
 
     private data class TransitionChanges(
         val taskInfoList: MutableList<RunningTaskInfo> = ArrayList(),
-        val transitionTypeList: MutableList<Int> = ArrayList()
-    )
+        val transitionTypeList: MutableList<Int> = ArrayList(),
+    ) {
+        fun merge(transitionChanges: TransitionChanges) {
+            taskInfoList.addAll(transitionChanges.taskInfoList)
+            transitionTypeList.addAll(transitionChanges.transitionTypeList)
+        }
+    }
 }
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 64e26db..1cbb8bb 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
@@ -23,7 +23,7 @@
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.SyncTransactionQueue;
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 f5fbae5..27fd309 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
@@ -24,7 +24,7 @@
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.SyncTransactionQueue;
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 dd219d3..e659151 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
@@ -64,6 +64,7 @@
 import android.view.WindowManager;
 import android.widget.Toast;
 import android.window.RemoteTransition;
+import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
 import androidx.annotation.BinderThread;
@@ -73,7 +74,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.InstanceId;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.R;
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
@@ -526,7 +527,15 @@
         mStageCoordinator.requestEnterSplitSelect(taskInfo, wct, splitPosition, taskBounds);
     }
 
-    public void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options) {
+    /**
+     * Starts an existing task into split.
+     * TODO(b/351900580): We should remove this path and use StageCoordinator#startTask() instead
+     * @param hideTaskToken is not supported.
+     */
+    public void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options,
+            @Nullable WindowContainerToken hideTaskToken) {
+        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP,
+                "Legacy startTask does not support hide task token");
         final int[] result = new int[1];
         IRemoteAnimationRunner wrapper = new IRemoteAnimationRunner.Stub() {
             @Override
@@ -584,8 +593,8 @@
         if (options == null) options = new Bundle();
         final ActivityOptions activityOptions = ActivityOptions.fromBundle(options);
 
-        if (samePackage(packageName, getPackageName(reverseSplitPosition(position)),
-                user.getIdentifier(), getUserId(reverseSplitPosition(position)))) {
+        if (samePackage(packageName, getPackageName(reverseSplitPosition(position), null),
+                user.getIdentifier(), getUserId(reverseSplitPosition(position), null))) {
             if (mMultiInstanceHelpher.supportsMultiInstanceSplit(
                     getShortcutComponent(packageName, shortcutId, user, mLauncherApps))) {
                 activityOptions.setApplyMultipleTaskFlagForShortcut(true);
@@ -676,10 +685,11 @@
      * See {@link #startIntent(PendingIntent, int, Intent, int, Bundle)}
      * @param instanceId to be used by {@link SplitscreenEventLogger}
      */
-    public void startIntent(PendingIntent intent, int userId, @Nullable Intent fillInIntent,
-            @SplitPosition int position, @Nullable Bundle options, @NonNull InstanceId instanceId) {
+    public void startIntentWithInstanceId(PendingIntent intent, int userId,
+            @Nullable Intent fillInIntent, @SplitPosition int position, @Nullable Bundle options,
+            @NonNull InstanceId instanceId) {
         mStageCoordinator.onRequestToSplit(instanceId, ENTER_REASON_LAUNCHER);
-        startIntent(intent, userId, fillInIntent, position, options);
+        startIntent(intent, userId, fillInIntent, position, options, null /* hideTaskToken */);
     }
 
     private void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, int userId1,
@@ -825,9 +835,15 @@
                 instanceId);
     }
 
+    /**
+     * Starts the given intent into split.
+     * @param hideTaskToken If non-null, a task matching this token will be moved to back in the
+     *                      same window container transaction as the starting of the intent.
+     */
     @Override
     public void startIntent(PendingIntent intent, int userId1, @Nullable Intent fillInIntent,
-            @SplitPosition int position, @Nullable Bundle options) {
+            @SplitPosition int position, @Nullable Bundle options,
+            @Nullable WindowContainerToken hideTaskToken) {
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
                 "startIntent(): intent=%s user=%d fillInIntent=%s position=%d", intent, userId1,
                 fillInIntent, position);
@@ -838,23 +854,24 @@
         fillInIntent.addFlags(FLAG_ACTIVITY_NO_USER_ACTION);
 
         final String packageName1 = SplitScreenUtils.getPackageName(intent);
-        final String packageName2 = getPackageName(reverseSplitPosition(position));
-        final int userId2 = getUserId(reverseSplitPosition(position));
+        final String packageName2 = getPackageName(reverseSplitPosition(position), hideTaskToken);
+        final int userId2 = getUserId(reverseSplitPosition(position), hideTaskToken);
         final ComponentName component = intent.getIntent().getComponent();
 
         // To prevent accumulating large number of instances in the background, reuse task
         // in the background. If we don't explicitly reuse, new may be created even if the app
         // isn't multi-instance because WM won't automatically remove/reuse the previous instance
         final ActivityManager.RecentTaskInfo taskInfo = mRecentTasksOptional
-                .map(recentTasks -> recentTasks.findTaskInBackground(component, userId1))
+                .map(recentTasks -> recentTasks.findTaskInBackground(component, userId1,
+                        hideTaskToken))
                 .orElse(null);
         if (taskInfo != null) {
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
                     "Found suitable background task=%s", taskInfo);
             if (ENABLE_SHELL_TRANSITIONS) {
-                mStageCoordinator.startTask(taskInfo.taskId, position, options);
+                mStageCoordinator.startTask(taskInfo.taskId, position, options, hideTaskToken);
             } else {
-                startTask(taskInfo.taskId, position, options);
+                startTask(taskInfo.taskId, position, options, hideTaskToken);
             }
             ProtoLog.v(ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN, "Start task in background");
             return;
@@ -879,19 +896,23 @@
             }
         }
 
-        mStageCoordinator.startIntent(intent, fillInIntent, position, options);
+        mStageCoordinator.startIntent(intent, fillInIntent, position, options, hideTaskToken);
     }
 
-    /** Retrieve package name of a specific split position if split screen is activated, otherwise
-     *  returns the package name of the top running task. */
+    /**
+     * Retrieve package name of a specific split position if split screen is activated, otherwise
+     * returns the package name of the top running task.
+     * TODO(b/351900580): Merge this with getUserId() so we don't make multiple binder calls
+     */
     @Nullable
-    private String getPackageName(@SplitPosition int position) {
+    private String getPackageName(@SplitPosition int position,
+            @Nullable WindowContainerToken ignoreTaskToken) {
         ActivityManager.RunningTaskInfo taskInfo;
         if (isSplitScreenVisible()) {
             taskInfo = getTaskInfo(position);
         } else {
             taskInfo = mRecentTasksOptional
-                    .map(recentTasks -> recentTasks.getTopRunningTask())
+                    .map(recentTasks -> recentTasks.getTopRunningTask(ignoreTaskToken))
                     .orElse(null);
             if (!isValidToSplit(taskInfo)) {
                 return null;
@@ -901,15 +922,19 @@
         return taskInfo != null ? SplitScreenUtils.getPackageName(taskInfo.baseIntent) : null;
     }
 
-    /** Retrieve user id of a specific split position if split screen is activated, otherwise
-     *  returns the user id of the top running task. */
-    private int getUserId(@SplitPosition int position) {
+    /**
+     * Retrieve user id of a specific split position if split screen is activated, otherwise
+     * returns the user id of the top running task.
+     * TODO: Merge this with getPackageName() so we don't make multiple binder calls
+     */
+    private int getUserId(@SplitPosition int position,
+            @Nullable WindowContainerToken ignoreTaskToken) {
         ActivityManager.RunningTaskInfo taskInfo;
         if (isSplitScreenVisible()) {
             taskInfo = getTaskInfo(position);
         } else {
             taskInfo = mRecentTasksOptional
-                    .map(recentTasks -> recentTasks.getTopRunningTask())
+                    .map(recentTasks -> recentTasks.getTopRunningTask(ignoreTaskToken))
                     .orElse(null);
             if (!isValidToSplit(taskInfo)) {
                 return -1;
@@ -1290,7 +1315,8 @@
         @Override
         public void startTask(int taskId, int position, @Nullable Bundle options) {
             executeRemoteCallWithTaskPermission(mController, "startTask",
-                    (controller) -> controller.startTask(taskId, position, options));
+                    (controller) -> controller.startTask(taskId, position, options,
+                            null /* hideTaskToken */));
         }
 
         @Override
@@ -1402,8 +1428,8 @@
         public void startIntent(PendingIntent intent, int userId, Intent fillInIntent, int position,
                 @Nullable Bundle options, InstanceId instanceId) {
             executeRemoteCallWithTaskPermission(mController, "startIntent",
-                    (controller) -> controller.startIntent(intent, userId, fillInIntent, position,
-                            options, instanceId));
+                    (controller) -> controller.startIntentWithInstanceId(intent, userId,
+                            fillInIntent, position, options, instanceId));
         }
 
         @Override
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 0541a02..b3dab85 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
@@ -46,7 +46,7 @@
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.TransactionPool;
 import com.android.wm.shell.common.split.SplitDecorManager;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
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 b6a18e5..4104234 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
@@ -119,7 +119,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.InstanceId;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.ArrayUtils;
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.R;
@@ -592,12 +592,21 @@
         }
     }
 
-    /** Use this method to launch an existing Task via a taskId */
-    void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options) {
+    /**
+     * Use this method to launch an existing Task via a taskId.
+     * @param hideTaskToken If non-null, a task matching this token will be moved to back in the
+     *                      same window container transaction as the starting of the intent.
+     */
+    void startTask(int taskId, @SplitPosition int position, @Nullable Bundle options,
+            @Nullable WindowContainerToken hideTaskToken) {
         ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "startTask: task=%d position=%d", taskId, position);
         mSplitRequest = new SplitRequest(taskId, position);
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, null /* wct */);
+        if (hideTaskToken != null) {
+            ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "Reordering hide-task to bottom");
+            wct.reorder(hideTaskToken, false /* onTop */);
+        }
         wct.startTask(taskId, options);
         // If this should be mixed, send the task to avoid split handle transition directly.
         if (mMixedHandler != null && mMixedHandler.isTaskInPip(taskId, mTaskOrganizer)) {
@@ -623,9 +632,13 @@
                 extraTransitType, !mIsDropEntering);
     }
 
-    /** Launches an activity into split. */
+    /**
+     * Launches an activity into split.
+     * @param hideTaskToken If non-null, a task matching this token will be moved to back in the
+     *                      same window container transaction as the starting of the intent.
+     */
     void startIntent(PendingIntent intent, Intent fillInIntent, @SplitPosition int position,
-            @Nullable Bundle options) {
+            @Nullable Bundle options, @Nullable WindowContainerToken hideTaskToken) {
         ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "startIntent: intent=%s position=%d", intent.getIntent(),
                 position);
         mSplitRequest = new SplitRequest(intent.getIntent(), position);
@@ -636,6 +649,10 @@
 
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, null /* wct */);
+        if (hideTaskToken != null) {
+            ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "Reordering hide-task to bottom");
+            wct.reorder(hideTaskToken, false /* onTop */);
+        }
         wct.sendPendingIntent(intent, fillInIntent, options);
 
         // If this should be mixed, just send the intent to avoid split handle transition directly.
@@ -2649,7 +2666,7 @@
             @Nullable TransitionRequestInfo request) {
         final ActivityManager.RunningTaskInfo triggerTask = request.getTriggerTask();
         if (triggerTask == null) {
-            if (isSplitActive()) {
+            if (isSplitScreenVisible()) {
                 ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "handleRequest: transition=%d display rotation",
                         request.getDebugId());
                 // Check if the display is rotating.
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 0f3d6ca..1076eca 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
@@ -45,7 +45,7 @@
 
 import androidx.annotation.NonNull;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.ArrayUtils;
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.ShellTaskOrganizer;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitMenuController.java
index 1d8a8d5..e0f6394 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitMenuController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/tv/TvSplitMenuController.java
@@ -36,7 +36,7 @@
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.SystemWindows;
 import com.android.wm.shell.common.split.SplitScreenConstants;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimationUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimationUtils.java
index 6325c68..ea8c0eb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimationUtils.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimationUtils.java
@@ -390,7 +390,8 @@
                                 SurfaceControl firstWindowSurface, ViewGroup splashScreenView,
                                 TransactionPool transactionPool, Rect firstWindowFrame,
                                 int mainWindowShiftLength, float roundedCornerRadius) {
-            mFromYDelta = fromYDelta - Math.max(firstWindowFrame.top, roundedCornerRadius);
+            mFromYDelta = firstWindowFrame.top
+                    - Math.max(firstWindowFrame.top, roundedCornerRadius);
             mToYDelta = toYDelta;
             mOccludeHoleView = occludeHoleView;
             mApplier = new SyncRtSurfaceTransactionApplier(occludeHoleView);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
index 2b12a22..90eb22f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
@@ -74,7 +74,7 @@
 import com.android.internal.graphics.palette.Quantizer;
 import com.android.internal.graphics.palette.VariationalKMeansQuantizer;
 import com.android.internal.policy.PhoneWindow;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.launcher3.icons.BaseIconFactory;
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.common.TransactionPool;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
index e552e6c..08211ab 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenWindowCreator.java
@@ -53,7 +53,7 @@
 import android.window.StartingWindowInfo;
 import android.window.StartingWindowRemovalInfo;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.ContrastColorUtil;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index 3353c7b..97a695f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -43,7 +43,7 @@
 import android.window.TaskSnapshot;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.launcher3.icons.IconProvider;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.TransactionPool;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
index 66b3553..6e084d6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java
@@ -21,8 +21,6 @@
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 
-import static com.android.window.flags.Flags.windowSessionRelayoutInfo;
-
 import android.annotation.BinderThread;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -30,7 +28,6 @@
 import android.app.ActivityManager.TaskDescription;
 import android.graphics.Paint;
 import android.graphics.Rect;
-import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.Trace;
@@ -51,7 +48,7 @@
 import android.window.StartingWindowInfo;
 import android.window.TaskSnapshot;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.view.BaseIWindow;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
@@ -139,16 +136,10 @@
         }
         try {
             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "TaskSnapshot#relayout");
-            if (windowSessionRelayoutInfo()) {
-                final WindowRelayoutResult outRelayoutResult = new WindowRelayoutResult(tmpFrames,
-                        tmpMergedConfiguration, surfaceControl, tmpInsetsState, tmpControls);
-                session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0, 0, 0,
-                        outRelayoutResult);
-            } else {
-                session.relayoutLegacy(window, layoutParams, -1, -1, View.VISIBLE, 0, 0, 0,
-                        tmpFrames, tmpMergedConfiguration, surfaceControl, tmpInsetsState,
-                        tmpControls, new Bundle());
-            }
+            final WindowRelayoutResult outRelayoutResult = new WindowRelayoutResult(tmpFrames,
+                    tmpMergedConfiguration, surfaceControl, tmpInsetsState, tmpControls);
+            session.relayout(window, layoutParams, -1, -1, View.VISIBLE, 0, 0, 0,
+                    outRelayoutResult);
             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         } catch (RemoteException e) {
             snapshotSurface.clearWindowSynced();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java
index 72fc8686..2036d9c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java
@@ -35,7 +35,7 @@
 
 import android.window.StartingWindowInfo;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.startingsurface.StartingWindowTypeAlgorithm;
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellCommandHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellCommandHandler.java
index 2e6ddc3..aa9f15c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellCommandHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellCommandHandler.java
@@ -18,7 +18,7 @@
 
 import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_INIT;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 import java.io.PrintWriter;
 import java.util.Arrays;
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
index 5ced1fb..0202b6c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellController.java
@@ -40,7 +40,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.DisplayInsetsController;
 import com.android.wm.shell.common.DisplayInsetsController.OnInsetsChangedListener;
 import com.android.wm.shell.common.ExternalInterfaceBinder;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java
index 2e2f569..dd4595a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sysui/ShellInit.java
@@ -25,8 +25,9 @@
 
 import androidx.annotation.VisibleForTesting;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
 import java.util.ArrayList;
 
@@ -75,6 +76,7 @@
      */
     @VisibleForTesting
     public void init() {
+        ProtoLog.registerGroups(ShellProtoLogGroup.values());
         ProtoLog.v(WM_SHELL_INIT, "Initializing Shell Components: %d", mInitCallbacks.size());
         SurfaceControl.setDebugUsageAfterRelease(true);
         // Init in order of registration
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/CounterRotatorHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/CounterRotatorHelper.java
index b03daaa..35427b9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/CounterRotatorHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/CounterRotatorHelper.java
@@ -94,6 +94,11 @@
         return rotatedBounds;
     }
 
+    /** Returns true if the change is put on a surface in previous rotation. */
+    public boolean isRotated(@NonNull TransitionInfo.Change change) {
+        return mLastRotationDelta != 0 && mRotatorMap.containsKey(change.getParent());
+    }
+
     /**
      * Removes the counter rotation surface in the finish transaction. No need to reparent the
      * children as the finish transaction should have already taken care of that.
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 8ee1efa..4f4b809 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
@@ -39,7 +39,7 @@
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.activityembedding.ActivityEmbeddingController;
 import com.android.wm.shell.common.split.SplitScreenUtils;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java
index c33fb80..c8921d2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java
@@ -28,7 +28,7 @@
 import android.view.SurfaceControl;
 import android.window.TransitionInfo;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.activityembedding.ActivityEmbeddingController;
 import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
 import com.android.wm.shell.pip.PipTransitionController;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index 018c904..73b32a2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -53,6 +53,7 @@
 import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
 import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
 
+import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_CHANGE;
 import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_CLOSE;
 import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_INTRA_CLOSE;
 import static com.android.internal.policy.TransitionAnimation.WALLPAPER_TRANSITION_INTRA_OPEN;
@@ -102,7 +103,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.policy.ScreenDecorationsUtils;
 import com.android.internal.policy.TransitionAnimation;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.window.flags.Flags;
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
 import com.android.wm.shell.common.DisplayController;
@@ -517,7 +518,8 @@
                     animRelOffset.y = Math.max(animRelOffset.y, change.getEndRelOffset().y);
                 }
 
-                if (change.getActivityComponent() != null && !isActivityLevel) {
+                if (change.getActivityComponent() != null && !isActivityLevel
+                        && !mRotator.isRotated(change)) {
                     // At this point, this is an independent activity change in a non-activity
                     // transition. This means that an activity transition got erroneously combined
                     // with another ongoing transition. This then means that the animation root may
@@ -943,12 +945,15 @@
     }
 
     private static int getWallpaperTransitType(TransitionInfo info) {
+        boolean hasWallpaper = false;
         boolean hasOpenWallpaper = false;
         boolean hasCloseWallpaper = false;
 
         for (int i = info.getChanges().size() - 1; i >= 0; --i) {
             final TransitionInfo.Change change = info.getChanges().get(i);
-            if ((change.getFlags() & FLAG_SHOW_WALLPAPER) != 0) {
+            if ((change.getFlags() & FLAG_SHOW_WALLPAPER) != 0
+                    || (change.getFlags() & FLAG_IS_WALLPAPER) != 0) {
+                hasWallpaper = true;
                 if (TransitionUtil.isOpeningType(change.getMode())) {
                     hasOpenWallpaper = true;
                 } else if (TransitionUtil.isClosingType(change.getMode())) {
@@ -964,6 +969,8 @@
             return WALLPAPER_TRANSITION_OPEN;
         } else if (hasCloseWallpaper) {
             return WALLPAPER_TRANSITION_CLOSE;
+        } else if (hasWallpaper) {
+            return WALLPAPER_TRANSITION_CHANGE;
         } else {
             return WALLPAPER_TRANSITION_NONE;
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java
index 89b0e25..978b8da 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java
@@ -28,7 +28,7 @@
 import android.view.WindowManager;
 import android.window.IWindowContainerTransactionCallback;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 /**
  * Utilities and interfaces for transition-like usage on top of the legacy app-transition and
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/MixedTransitionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/MixedTransitionHelper.java
index e8b01b5..8cc7f21 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/MixedTransitionHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/MixedTransitionHelper.java
@@ -35,7 +35,7 @@
 import android.view.SurfaceControl;
 import android.window.TransitionInfo;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
 import com.android.wm.shell.pip.PipTransitionController;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
@@ -184,7 +184,8 @@
 
         for (int i = info.getChanges().size() - 1; i >= 0; --i) {
             TransitionInfo.Change change = info.getChanges().get(i);
-            if (change == pipChange || !isOpeningMode(change.getMode())) {
+            if (change == pipChange || !isOpeningMode(change.getMode()) ||
+                    change.getTaskInfo() == null) {
                 // Ignore the change/task that's going into Pip or not opening
                 continue;
             }
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 69c4167..c5dc668 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
@@ -30,7 +30,7 @@
 import android.window.WindowAnimationState;
 import android.window.WindowContainerTransaction;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RecentsMixedTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RecentsMixedTransition.java
index 9fc6702..391c5fe 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RecentsMixedTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RecentsMixedTransition.java
@@ -30,7 +30,7 @@
 import android.window.TransitionInfo;
 import android.window.WindowContainerTransaction;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.desktopmode.DesktopTasksController;
 import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
 import com.android.wm.shell.pip.PipTransitionController;
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 d686046..6013a1e 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
@@ -39,7 +39,7 @@
 
 import androidx.annotation.BinderThread;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.shared.TransitionUtil;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
index 2047b5a..a5f071a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/TransitionAnimationHelper.java
@@ -54,7 +54,7 @@
 
 import com.android.internal.R;
 import com.android.internal.policy.TransitionAnimation;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.window.flags.Flags;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.shared.TransitionUtil;
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 f257e20..21307a2 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
@@ -28,12 +28,16 @@
 import static android.view.WindowManager.TRANSIT_TO_BACK;
 import static android.view.WindowManager.TRANSIT_TO_FRONT;
 import static android.view.WindowManager.fixScale;
+import static android.view.WindowManager.transitTypeToString;
+import static android.window.TransitionInfo.FLAGS_IS_NON_APP_WINDOW;
 import static android.window.TransitionInfo.FLAG_BACK_GESTURE_ANIMATED;
 import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW;
 import static android.window.TransitionInfo.FLAG_IS_OCCLUDED;
+import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
 import static android.window.TransitionInfo.FLAG_NO_ANIMATION;
 import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
 
+import static com.android.window.flags.Flags.ensureWallpaperInTransitions;
 import static com.android.systemui.shared.Flags.returnAnimationFrameworkLibrary;
 import static com.android.wm.shell.shared.TransitionUtil.isClosingType;
 import static com.android.wm.shell.shared.TransitionUtil.isOpeningType;
@@ -72,7 +76,8 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
+import com.android.window.flags.Flags;
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.DisplayController;
@@ -512,12 +517,17 @@
         boolean isOpening = isOpeningType(info.getType());
         for (int i = info.getChanges().size() - 1; i >= 0; --i) {
             final TransitionInfo.Change change = info.getChanges().get(i);
-            if (change.hasFlags(TransitionInfo.FLAGS_IS_NON_APP_WINDOW)) {
+            if (change.hasFlags(FLAGS_IS_NON_APP_WINDOW & ~FLAG_IS_WALLPAPER)) {
                 // Currently system windows are controlled by WindowState, so don't change their
                 // surfaces. Otherwise their surfaces could be hidden or cropped unexpectedly.
-                // This includes Wallpaper (always z-ordered at bottom) and IME (associated with
-                // app), because there may not be a transition associated with their visibility
-                // changes, and currently they don't need transition animation.
+                // This includes IME (associated with app), because there may not be a transition
+                // associated with their visibility changes, and currently they don't need a
+                // transition animation.
+                continue;
+            }
+            if (change.hasFlags(FLAG_IS_WALLPAPER) && !ensureWallpaperInTransitions()) {
+                // Wallpaper is always z-ordered at bottom, and historically is not animated by
+                // transition handlers.
                 continue;
             }
             final SurfaceControl leash = change.getLeash();
@@ -570,6 +580,14 @@
         final boolean isOpening = isOpeningType(transitType);
         final boolean isClosing = isClosingType(transitType);
         final int mode = change.getMode();
+        // Ensure wallpapers stay in the back
+        if (change.hasFlags(FLAG_IS_WALLPAPER) && Flags.ensureWallpaperInTransitions()) {
+            if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT) {
+                return -zSplitLine + numChanges - i;
+            } else {
+                return -zSplitLine - i;
+            }
+        }
         // Put all the OPEN/SHOW on top
         if (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT) {
             if (isOpening) {
@@ -1186,7 +1204,7 @@
     public IBinder startTransition(@WindowManager.TransitionType int type,
             @NonNull WindowContainerTransaction wct, @Nullable TransitionHandler handler) {
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Directly starting a new transition "
-                + "type=%d wct=%s handler=%s", type, wct, handler);
+                + "type=%s wct=%s handler=%s", transitTypeToString(type), wct, handler);
         final ActiveTransition active =
                 new ActiveTransition(mOrganizer.startNewTransition(type, wct));
         active.mHandler = handler;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
index 7c2ba45..88bfebf 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldTransitionHandler.java
@@ -33,7 +33,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.TransactionPool;
 import com.android.wm.shell.shared.TransitionUtil;
 import com.android.wm.shell.sysui.ShellInit;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/util/GroupedRecentTaskInfo.java b/libs/WindowManager/Shell/src/com/android/wm/shell/util/GroupedRecentTaskInfo.java
index c045ceb..a2d2b9a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/util/GroupedRecentTaskInfo.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/util/GroupedRecentTaskInfo.java
@@ -27,6 +27,7 @@
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Simple container for recent tasks.  May contain either a single or pair of tasks.
@@ -50,6 +51,9 @@
     private final SplitBounds mSplitBounds;
     @GroupType
     private final int mType;
+    // TODO(b/348332802): move isMinimized inside each Task object instead once we have a
+    //  replacement for RecentTaskInfo
+    private final int[] mMinimizedTaskIds;
 
     /**
      * Create new for a single task
@@ -57,7 +61,7 @@
     public static GroupedRecentTaskInfo forSingleTask(
             @NonNull ActivityManager.RecentTaskInfo task) {
         return new GroupedRecentTaskInfo(new ActivityManager.RecentTaskInfo[]{task}, null,
-                TYPE_SINGLE);
+                TYPE_SINGLE, null /* minimizedFreeformTasks */);
     }
 
     /**
@@ -66,28 +70,51 @@
     public static GroupedRecentTaskInfo forSplitTasks(@NonNull ActivityManager.RecentTaskInfo task1,
             @NonNull ActivityManager.RecentTaskInfo task2, @Nullable SplitBounds splitBounds) {
         return new GroupedRecentTaskInfo(new ActivityManager.RecentTaskInfo[]{task1, task2},
-                splitBounds, TYPE_SPLIT);
+                splitBounds, TYPE_SPLIT, null /* minimizedFreeformTasks */);
     }
 
     /**
      * Create new for a group of freeform tasks
      */
     public static GroupedRecentTaskInfo forFreeformTasks(
-            @NonNull ActivityManager.RecentTaskInfo... tasks) {
-        return new GroupedRecentTaskInfo(tasks, null, TYPE_FREEFORM);
+            @NonNull ActivityManager.RecentTaskInfo[] tasks,
+            @NonNull Set<Integer> minimizedFreeformTasks) {
+        return new GroupedRecentTaskInfo(
+                tasks,
+                null /* splitBounds */,
+                TYPE_FREEFORM,
+                minimizedFreeformTasks.stream().mapToInt(i -> i).toArray());
     }
 
-    private GroupedRecentTaskInfo(@NonNull ActivityManager.RecentTaskInfo[] tasks,
-            @Nullable SplitBounds splitBounds, @GroupType int type) {
+    private GroupedRecentTaskInfo(
+            @NonNull ActivityManager.RecentTaskInfo[] tasks,
+            @Nullable SplitBounds splitBounds,
+            @GroupType int type,
+            @Nullable int[] minimizedFreeformTaskIds) {
         mTasks = tasks;
         mSplitBounds = splitBounds;
         mType = type;
+        mMinimizedTaskIds = minimizedFreeformTaskIds;
+        ensureAllMinimizedIdsPresent(tasks, minimizedFreeformTaskIds);
+    }
+
+    private static void ensureAllMinimizedIdsPresent(
+            @NonNull ActivityManager.RecentTaskInfo[] tasks,
+            @Nullable int[] minimizedFreeformTaskIds) {
+        if (minimizedFreeformTaskIds == null) {
+            return;
+        }
+        if (!Arrays.stream(minimizedFreeformTaskIds).allMatch(
+                taskId -> Arrays.stream(tasks).anyMatch(task -> task.taskId == taskId))) {
+            throw new IllegalArgumentException("Minimized task IDs contain non-existent Task ID.");
+        }
     }
 
     GroupedRecentTaskInfo(Parcel parcel) {
         mTasks = parcel.createTypedArray(ActivityManager.RecentTaskInfo.CREATOR);
         mSplitBounds = parcel.readTypedObject(SplitBounds.CREATOR);
         mType = parcel.readInt();
+        mMinimizedTaskIds = parcel.createIntArray();
     }
 
     /**
@@ -135,6 +162,10 @@
         return mType;
     }
 
+    public int[] getMinimizedTaskIds() {
+        return mMinimizedTaskIds;
+    }
+
     @Override
     public String toString() {
         StringBuilder taskString = new StringBuilder();
@@ -161,6 +192,8 @@
                 taskString.append("TYPE_FREEFORM");
                 break;
         }
+        taskString.append(", Minimized Task IDs: ");
+        taskString.append(Arrays.toString(mMinimizedTaskIds));
         return taskString.toString();
     }
 
@@ -181,6 +214,7 @@
         parcel.writeTypedArray(mTasks, flags);
         parcel.writeTypedObject(mSplitBounds, flags);
         parcel.writeInt(mType);
+        parcel.writeIntArray(mMinimizedTaskIds);
     }
 
     @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/util/KtProtoLog.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/util/KtProtoLog.kt
deleted file mode 100644
index 564e716..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/util/KtProtoLog.kt
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.util
-
-import android.util.Log
-import com.android.internal.protolog.common.IProtoLogGroup
-import com.android.internal.protolog.common.ProtoLog
-
-/**
- * Log messages using an API similar to [com.android.internal.protolog.common.ProtoLog]. Useful for
- * logging from Kotlin classes as ProtoLog does not have support for Kotlin.
- *
- * All messages are logged to logcat if logging is enabled for that [IProtoLogGroup].
- */
-// TODO(b/168581922): remove once ProtoLog adds support for Kotlin
-class KtProtoLog {
-    companion object {
-        /** @see [com.android.internal.protolog.common.ProtoLog.d] */
-        fun d(group: IProtoLogGroup, messageString: String, vararg args: Any) {
-            if (group.isLogToLogcat) {
-                Log.d(group.tag, String.format(messageString, *args))
-            }
-        }
-
-        /** @see [com.android.internal.protolog.common.ProtoLog.v] */
-        fun v(group: IProtoLogGroup, messageString: String, vararg args: Any) {
-            if (group.isLogToLogcat) {
-                Log.v(group.tag, String.format(messageString, *args))
-            }
-        }
-
-        /** @see [com.android.internal.protolog.common.ProtoLog.i] */
-        fun i(group: IProtoLogGroup, messageString: String, vararg args: Any) {
-            if (group.isLogToLogcat) {
-                Log.i(group.tag, String.format(messageString, *args))
-            }
-        }
-
-        /** @see [com.android.internal.protolog.common.ProtoLog.w] */
-        fun w(group: IProtoLogGroup, messageString: String, vararg args: Any) {
-            if (group.isLogToLogcat) {
-                Log.w(group.tag, String.format(messageString, *args))
-            }
-        }
-
-        /** @see [com.android.internal.protolog.common.ProtoLog.e] */
-        fun e(group: IProtoLogGroup, messageString: String, vararg args: Any) {
-            if (group.isLogToLogcat) {
-                Log.e(group.tag, String.format(messageString, *args))
-            }
-        }
-
-        /** @see [com.android.internal.protolog.common.ProtoLog.wtf] */
-        fun wtf(group: IProtoLogGroup, messageString: String, vararg args: Any) {
-            if (group.isLogToLogcat) {
-                Log.wtf(group.tag, String.format(messageString, *args))
-            }
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index 21b6db2..faf6a62 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -22,18 +22,18 @@
 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.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.view.InputDevice.SOURCE_TOUCHSCREEN;
 import static android.view.MotionEvent.ACTION_CANCEL;
 import static android.view.MotionEvent.ACTION_HOVER_ENTER;
 import static android.view.MotionEvent.ACTION_HOVER_EXIT;
-import static android.view.MotionEvent.ACTION_HOVER_MOVE;
 import static android.view.MotionEvent.ACTION_MOVE;
 import static android.view.MotionEvent.ACTION_UP;
 import static android.view.WindowInsets.Type.statusBars;
 
 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.compatui.AppCompatUtils.isSingleTopActivityTranslucent;
+import static com.android.wm.shell.compatui.AppCompatUtils.isTopActivityExemptFromDesktopWindowing;
 import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR;
 import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE;
 import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
@@ -42,12 +42,17 @@
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityTaskManager;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.hardware.input.InputManager;
+import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
@@ -73,7 +78,9 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.jank.Cuj;
+import com.android.internal.jank.InteractionJankMonitor;
+import com.android.internal.protolog.ProtoLog;
 import com.android.window.flags.Flags;
 import com.android.wm.shell.R;
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
@@ -90,7 +97,7 @@
 import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition;
 import com.android.wm.shell.desktopmode.DesktopWallpaperActivity;
 import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
-import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.splitscreen.SplitScreen;
 import com.android.wm.shell.splitscreen.SplitScreen.StageType;
 import com.android.wm.shell.splitscreen.SplitScreenController;
@@ -101,9 +108,9 @@
 import com.android.wm.shell.transition.Transitions;
 import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration.ExclusionRegionListener;
 import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
+import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder;
 
 import java.io.PrintWriter;
-import java.util.Objects;
 import java.util.Optional;
 import java.util.function.Supplier;
 
@@ -129,6 +136,7 @@
     private final SyncTransactionQueue mSyncQueue;
     private final DesktopTasksController mDesktopTasksController;
     private final InputManager mInputManager;
+    private final InteractionJankMonitor mInteractionJankMonitor;
     private boolean mTransitionDragActive;
 
     private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>();
@@ -184,7 +192,8 @@
             SyncTransactionQueue syncQueue,
             Transitions transitions,
             Optional<DesktopTasksController> desktopTasksController,
-            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer
+            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
+            InteractionJankMonitor interactionJankMonitor
     ) {
         this(
                 context,
@@ -205,7 +214,8 @@
                 new InputMonitorFactory(),
                 SurfaceControl.Transaction::new,
                 rootTaskDisplayAreaOrganizer,
-                new SparseArray<>());
+                new SparseArray<>(),
+                interactionJankMonitor);
     }
 
     @VisibleForTesting
@@ -228,7 +238,8 @@
             InputMonitorFactory inputMonitorFactory,
             Supplier<SurfaceControl.Transaction> transactionFactory,
             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
-            SparseArray<DesktopModeWindowDecoration> windowDecorByTaskId) {
+            SparseArray<DesktopModeWindowDecoration> windowDecorByTaskId,
+            InteractionJankMonitor interactionJankMonitor) {
         mContext = context;
         mMainExecutor = shellExecutor;
         mMainHandler = mainHandler;
@@ -251,6 +262,7 @@
         mWindowDecorByTaskId = windowDecorByTaskId;
         mSysUIPackageName = mContext.getResources().getString(
                 com.android.internal.R.string.config_systemUi);
+        mInteractionJankMonitor = interactionJankMonitor;
 
         shellInit.addInitCallback(this::onInit, this);
     }
@@ -381,10 +393,52 @@
         mWindowDecorByTaskId.remove(taskInfo.taskId);
     }
 
+    private void onMaximizeOrRestore(int taskId, String tag) {
+        final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId);
+        if (decoration == null) {
+            return;
+        }
+        mInteractionJankMonitor.begin(
+                decoration.mTaskSurface, mContext, Cuj.CUJ_DESKTOP_MODE_MAXIMIZE_WINDOW, tag);
+        mDesktopTasksController.toggleDesktopTaskSize(decoration.mTaskInfo);
+        decoration.closeHandleMenu();
+        decoration.closeMaximizeMenu();
+    }
+
+    private void onSnapResize(int taskId, boolean left) {
+        final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskId);
+        if (decoration == null) {
+            return;
+        }
+        mDesktopTasksController.snapToHalfScreen(decoration.mTaskInfo,
+                left ? SnapPosition.LEFT : SnapPosition.RIGHT);
+        decoration.closeHandleMenu();
+        decoration.closeMaximizeMenu();
+    }
+
+    private void onOpenInBrowser(@NonNull DesktopModeWindowDecoration decor, @NonNull Uri uri) {
+        openInBrowser(uri);
+        decor.closeHandleMenu();
+        decor.closeMaximizeMenu();
+    }
+
+    private void openInBrowser(Uri uri) {
+        final Intent intent = new Intent(Intent.ACTION_VIEW, uri)
+                .setComponent(getDefaultBrowser())
+                .addFlags(FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(intent);
+    }
+
+    private ComponentName getDefaultBrowser() {
+        final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://"));
+        final ResolveInfo info = mContext.getPackageManager()
+                .resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
+        return info.getComponentInfo().getComponentName();
+    }
+
     private class DesktopModeTouchEventListener extends GestureDetector.SimpleOnGestureListener
             implements View.OnClickListener, View.OnTouchListener, View.OnLongClickListener,
             View.OnGenericMotionListener, DragDetector.MotionEventHandler {
-        private static final int CLOSE_MAXIMIZE_MENU_DELAY_MS = 150;
 
         private final int mTaskId;
         private final WindowContainerToken mTaskToken;
@@ -403,7 +457,6 @@
         private boolean mTouchscreenInUse;
         private boolean mHasLongClicked;
         private int mDragPointerId = -1;
-        private final Runnable mCloseMaximizeWindowRunnable;
 
         private DesktopModeTouchEventListener(
                 RunningTaskInfo taskInfo,
@@ -414,11 +467,6 @@
             mDragDetector = new DragDetector(this);
             mGestureDetector = new GestureDetector(mContext, this);
             mDisplayId = taskInfo.displayId;
-            mCloseMaximizeWindowRunnable = () -> {
-                final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
-                if (decoration == null) return;
-                decoration.closeMaximizeMenu();
-            };
         }
 
         @Override
@@ -435,7 +483,7 @@
                             SplitScreenController.EXIT_REASON_DESKTOP_MODE);
                 } else {
                     WindowContainerTransaction wct = new WindowContainerTransaction();
-                    mDesktopTasksController.onDesktopWindowClose(wct, mTaskId);
+                    mDesktopTasksController.onDesktopWindowClose(wct, mDisplayId, mTaskId);
                     mTaskOperations.closeTask(mTaskToken, wct);
                 }
             } else if (id == R.id.back_button) {
@@ -467,28 +515,19 @@
             } else if (id == R.id.split_screen_button) {
                 decoration.closeHandleMenu();
                 mDesktopTasksController.requestSplit(decoration.mTaskInfo);
+            } else if (id == R.id.open_in_browser_button) {
+                // TODO(b/346441962): let the decoration handle the click gesture and only call back
+                //  to the ViewModel via #setOpenInBrowserClickListener
+                decoration.onOpenInBrowserClick();
             } else if (id == R.id.collapse_menu_button) {
                 decoration.closeHandleMenu();
             } else if (id == R.id.maximize_window) {
-                final RunningTaskInfo taskInfo = decoration.mTaskInfo;
-                decoration.closeHandleMenu();
-                decoration.closeMaximizeMenu();
-                mDesktopTasksController.toggleDesktopTaskSize(taskInfo);
-            } else if (id == R.id.maximize_menu_maximize_button) {
-                final RunningTaskInfo taskInfo = decoration.mTaskInfo;
-                mDesktopTasksController.toggleDesktopTaskSize(taskInfo);
-                decoration.closeHandleMenu();
-                decoration.closeMaximizeMenu();
-            } else if (id == R.id.maximize_menu_snap_left_button) {
-                final RunningTaskInfo taskInfo = decoration.mTaskInfo;
-                mDesktopTasksController.snapToHalfScreen(taskInfo, SnapPosition.LEFT);
-                decoration.closeHandleMenu();
-                decoration.closeMaximizeMenu();
-            } else if (id == R.id.maximize_menu_snap_right_button) {
-                final RunningTaskInfo taskInfo = decoration.mTaskInfo;
-                mDesktopTasksController.snapToHalfScreen(taskInfo, SnapPosition.RIGHT);
-                decoration.closeHandleMenu();
-                decoration.closeMaximizeMenu();
+                // TODO(b/346441962): move click detection logic into the decor's
+                //  {@link AppHeaderViewHolder}. Let it encapsulate the that and have it report
+                //  back to the decoration using
+                //  {@link DesktopModeWindowDecoration#setOnMaximizeOrRestoreClickListener}, which
+                //  should shared with the maximize menu's maximize/restore actions.
+                onMaximizeOrRestore(decoration.mTaskInfo.taskId, "caption_bar_button");
             }
         }
 
@@ -570,40 +609,26 @@
             return false;
         }
 
+        /**
+         * TODO(b/346441962): move this hover detection logic into the decor's
+         * {@link AppHeaderViewHolder}.
+         */
         @Override
         public boolean onGenericMotion(View v, MotionEvent ev) {
             final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
             final int id = v.getId();
-            if (ev.getAction() == ACTION_HOVER_ENTER) {
-                if (!decoration.isMaximizeMenuActive() && id == R.id.maximize_window) {
-                    decoration.onMaximizeWindowHoverEnter();
-                } else if (id == R.id.maximize_window
-                        || MaximizeMenu.Companion.isMaximizeMenuView(id)) {
-                    // Re-hovering over any of the maximize menu views should keep the menu open by
-                    // cancelling any attempts to close the menu.
-                    mMainHandler.removeCallbacks(mCloseMaximizeWindowRunnable);
-                    if (id != R.id.maximize_window) {
-                        decoration.onMaximizeMenuHoverEnter(id, ev);
-                    }
+            if (ev.getAction() == ACTION_HOVER_ENTER && id == R.id.maximize_window) {
+                decoration.setAppHeaderMaximizeButtonHovered(true);
+                if (!decoration.isMaximizeMenuActive()) {
+                    decoration.onMaximizeButtonHoverEnter();
                 }
                 return true;
-            } else if (ev.getAction() == ACTION_HOVER_MOVE
-                    && MaximizeMenu.Companion.isMaximizeMenuView(id)) {
-                decoration.onMaximizeMenuHoverMove(id, ev);
-                mMainHandler.removeCallbacks(mCloseMaximizeWindowRunnable);
-            } else if (ev.getAction() == ACTION_HOVER_EXIT) {
-                if (!decoration.isMaximizeMenuActive() && id == R.id.maximize_window) {
-                    decoration.onMaximizeWindowHoverExit();
-                } else if (id == R.id.maximize_window
-                        || MaximizeMenu.Companion.isMaximizeMenuView(id)) {
-                    // Close menu if not hovering over maximize menu or maximize button after a
-                    // delay to give user a chance to re-enter view or to move from one maximize
-                    // menu view to another.
-                    mMainHandler.postDelayed(mCloseMaximizeWindowRunnable,
-                            CLOSE_MAXIMIZE_MENU_DELAY_MS);
-                    if (id != R.id.maximize_window) {
-                        decoration.onMaximizeMenuHoverExit(id, ev);
-                    }
+            }
+            if (ev.getAction() == ACTION_HOVER_EXIT && id == R.id.maximize_window) {
+                decoration.setAppHeaderMaximizeButtonHovered(false);
+                decoration.onMaximizeHoverStateChanged();
+                if (!decoration.isMaximizeMenuActive()) {
+                    decoration.onMaximizeButtonHoverExit();
                 }
                 return true;
             }
@@ -711,8 +736,7 @@
                     && action != MotionEvent.ACTION_CANCEL)) {
                 return false;
             }
-            final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
-            mDesktopTasksController.toggleDesktopTaskSize(decoration.mTaskInfo);
+            onMaximizeOrRestore(mTaskId, "double_tap");
             return true;
         }
     }
@@ -1039,12 +1063,8 @@
                 && taskInfo.isFocused) {
             return false;
         }
-        // TODO(b/347289970): Consider replacing with API
         if (Flags.enableDesktopWindowingModalsPolicy()
-                && isSingleTopActivityTranslucent(taskInfo)) {
-            return false;
-        }
-        if (isSystemUIApplication(taskInfo)) {
+                && isTopActivityExemptFromDesktopWindowing(mContext, taskInfo)) {
             return false;
         }
         return DesktopModeStatus.canEnterDesktopMode(mContext)
@@ -1087,14 +1107,21 @@
         } else {
             dragPositioningCallback =  new VeiledResizeTaskPositioner(
                     mTaskOrganizer, windowDecoration, mDisplayController,
-                    mDragStartListener, mTransitions);
+                    mDragStartListener, mTransitions, mInteractionJankMonitor);
             windowDecoration.setTaskDragResizer(
                     (VeiledResizeTaskPositioner) dragPositioningCallback);
         }
 
         final DesktopModeTouchEventListener touchEventListener =
                 new DesktopModeTouchEventListener(taskInfo, dragPositioningCallback);
-
+        windowDecoration.setOnMaximizeOrRestoreClickListener(this::onMaximizeOrRestore);
+        windowDecoration.setOnLeftSnapClickListener((taskId, tag) -> {
+            onSnapResize(taskId, true /* isLeft */);
+        });
+        windowDecoration.setOnRightSnapClickListener((taskId, tag) -> {
+            onSnapResize(taskId, false /* isLeft */);
+        });
+        windowDecoration.setOpenInBrowserClickListener(this::onOpenInBrowser);
         windowDecoration.setCaptionListeners(
                 touchEventListener, touchEventListener, touchEventListener, touchEventListener);
         windowDecoration.setExclusionRegionListener(mExclusionRegionListener);
@@ -1117,14 +1144,6 @@
                 && mSplitScreenController.isTaskInSplitScreen(taskId);
     }
 
-    // TODO(b/347289970): Consider replacing with API
-    private boolean isSystemUIApplication(RunningTaskInfo taskInfo) {
-        if (taskInfo.baseActivity != null) {
-            return (Objects.equals(taskInfo.baseActivity.getPackageName(), mSysUIPackageName));
-        }
-        return false;
-    }
-
     private void dump(PrintWriter pw, String prefix) {
         final String innerPrefix = prefix + "  ";
         pw.println(prefix + "DesktopModeWindowDecorViewModel");
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 4d597ca..5ffd883 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -31,6 +31,7 @@
 import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.WindowConfiguration.WindowingMode;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
@@ -43,6 +44,7 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.graphics.drawable.Drawable;
+import android.net.Uri;
 import android.os.Handler;
 import android.os.Trace;
 import android.util.Log;
@@ -67,8 +69,9 @@
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.splitscreen.SplitScreenController;
+import com.android.wm.shell.windowdecor.common.OnTaskActionClickListener;
 import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
 import com.android.wm.shell.windowdecor.viewholder.AppHandleViewHolder;
 import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder;
@@ -86,6 +89,10 @@
  */
 public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLinearLayout> {
     private static final String TAG = "DesktopModeWindowDecoration";
+    private static final int CAPTURED_LINK_TIMEOUT_MS = 7000;
+
+    @VisibleForTesting
+    static final long CLOSE_MAXIMIZE_MENU_DELAY_MS = 150L;
 
     private final Handler mHandler;
     private final Choreographer mChoreographer;
@@ -96,6 +103,9 @@
     private View.OnTouchListener mOnCaptionTouchListener;
     private View.OnLongClickListener mOnCaptionLongClickListener;
     private View.OnGenericMotionListener mOnCaptionGenericMotionListener;
+    private OnTaskActionClickListener mOnMaximizeOrRestoreClickListener;
+    private OnTaskActionClickListener mOnLeftSnapClickListener;
+    private OnTaskActionClickListener mOnRightSnapClickListener;
     private DragPositioningCallback mDragPositioningCallback;
     private DragResizeInputListener mDragResizeListener;
     private DragDetector mDragDetector;
@@ -116,10 +126,23 @@
     private Bitmap mResizeVeilBitmap;
 
     private CharSequence mAppName;
+    private CapturedLink mCapturedLink;
+    private OpenInBrowserClickListener mOpenInBrowserClickListener;
 
     private ExclusionRegionListener mExclusionRegionListener;
 
     private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
+    private final MaximizeMenuFactory mMaximizeMenuFactory;
+
+    // Hover state for the maximize menu and button. The menu will remain open as long as either of
+    // these is true. See {@link #onMaximizeHoverStateChanged()}.
+    private boolean mIsAppHeaderMaximizeButtonHovered = false;
+    private boolean mIsMaximizeMenuHovered = false;
+    // Used to schedule the closing of the maximize menu when neither of the button or menu are
+    // being hovered. There's a small delay after stopping the hover, to allow a quick reentry
+    // to cancel the close.
+    private final Runnable mCloseMaximizeWindowRunnable = this::closeMaximizeMenu;
+    private final Runnable mCapturedLinkExpiredRunnable = this::onCapturedLinkExpired;
 
     DesktopModeWindowDecoration(
             Context context,
@@ -135,7 +158,7 @@
                 handler, choreographer, syncQueue, rootTaskDisplayAreaOrganizer,
                 SurfaceControl.Builder::new, SurfaceControl.Transaction::new,
                 WindowContainerTransaction::new, SurfaceControl::new,
-                new SurfaceControlViewHostFactory() {});
+                new SurfaceControlViewHostFactory() {}, DefaultMaximizeMenuFactory.INSTANCE);
     }
 
     DesktopModeWindowDecoration(
@@ -152,7 +175,8 @@
             Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier,
             Supplier<WindowContainerTransaction> windowContainerTransactionSupplier,
             Supplier<SurfaceControl> surfaceControlSupplier,
-            SurfaceControlViewHostFactory surfaceControlViewHostFactory) {
+            SurfaceControlViewHostFactory surfaceControlViewHostFactory,
+            MaximizeMenuFactory maximizeMenuFactory) {
         super(context, displayController, taskOrganizer, taskInfo, taskSurface,
                 surfaceControlBuilderSupplier, surfaceControlTransactionSupplier,
                 windowContainerTransactionSupplier, surfaceControlSupplier,
@@ -161,6 +185,31 @@
         mChoreographer = choreographer;
         mSyncQueue = syncQueue;
         mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
+        mMaximizeMenuFactory = maximizeMenuFactory;
+    }
+
+    /**
+     * Register a listener to be called back when one of the tasks' maximize/restore action is
+     * triggered.
+     * TODO(b/346441962): hook this up to double-tap and the header's maximize button, instead of
+     *  having the ViewModel deal with parsing motion events.
+     */
+    void setOnMaximizeOrRestoreClickListener(OnTaskActionClickListener listener) {
+        mOnMaximizeOrRestoreClickListener = listener;
+    }
+
+    /**
+     * Register a listener to be called back when one of the tasks snap-left action is triggered.
+     */
+    void setOnLeftSnapClickListener(OnTaskActionClickListener listener) {
+        mOnLeftSnapClickListener = listener;
+    }
+
+    /**
+     * Register a listener to be called back when one of the tasks' snap-right action is triggered.
+     */
+    void setOnRightSnapClickListener(OnTaskActionClickListener listener) {
+        mOnRightSnapClickListener = listener;
     }
 
     void setCaptionListeners(
@@ -187,6 +236,10 @@
         mDragDetector.setTouchSlop(ViewConfiguration.get(mContext).getScaledTouchSlop());
     }
 
+    void setOpenInBrowserClickListener(OpenInBrowserClickListener listener) {
+        mOpenInBrowserClickListener = listener;
+    }
+
     @Override
     void relayout(ActivityManager.RunningTaskInfo taskInfo) {
         final SurfaceControl.Transaction t = mSurfaceControlTransactionSupplier.get();
@@ -278,6 +331,11 @@
             SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
             boolean applyStartTransactionOnDraw, boolean shouldSetTaskPositionAndCrop) {
         Trace.beginSection("DesktopModeWindowDecoration#updateRelayoutParamsAndSurfaces");
+
+        if (Flags.enableDesktopWindowingAppToWeb()) {
+            setCapturedLink(taskInfo.capturedLink, taskInfo.capturedLinkTimestamp);
+        }
+
         if (isHandleMenuActive()) {
             mHandleMenu.relayout(startT);
         }
@@ -322,6 +380,28 @@
         Trace.endSection(); // DesktopModeWindowDecoration#updateRelayoutParamsAndSurfaces
     }
 
+    private void setCapturedLink(Uri capturedLink, long timeStamp) {
+        if (capturedLink == null
+                || (mCapturedLink != null && mCapturedLink.mTimeStamp == timeStamp)) {
+            return;
+        }
+        mCapturedLink = new CapturedLink(capturedLink, timeStamp);
+        mHandler.postDelayed(mCapturedLinkExpiredRunnable, CAPTURED_LINK_TIMEOUT_MS);
+    }
+
+    private void onCapturedLinkExpired() {
+        mHandler.removeCallbacks(mCapturedLinkExpiredRunnable);
+        if (mCapturedLink != null) {
+            mCapturedLink.setExpired();
+        }
+    }
+
+    void onOpenInBrowserClick() {
+        if (mOpenInBrowserClickListener == null || mCapturedLink == null) return;
+        mOpenInBrowserClickListener.onClick(this, mCapturedLink.mUri);
+        onCapturedLinkExpired();
+    }
+
     private void updateDragResizeListener(SurfaceControl oldDecorationSurface) {
         if (!isDragResizable(mTaskInfo)) {
             if (!mTaskInfo.positionInParent.equals(mPositionInParent)) {
@@ -556,12 +636,13 @@
             if (mAppIconBitmap != null && mAppName != null) {
                 return;
             }
-            final ActivityInfo activityInfo = mTaskInfo.topActivityInfo;
-            if (activityInfo == null) {
-                Log.e(TAG, "Top activity info not found in task");
+            final ComponentName baseActivity = mTaskInfo.baseActivity;
+            if (baseActivity == null) {
+                Log.e(TAG, "Base activity component not found in task");
                 return;
             }
-            PackageManager pm = mContext.getApplicationContext().getPackageManager();
+            final PackageManager pm = mContext.getApplicationContext().getPackageManager();
+            final ActivityInfo activityInfo = pm.getActivityInfo(baseActivity, 0 /* flags */);
             final IconProvider provider = new IconProvider(mContext);
             final Drawable appIconDrawable = provider.getIcon(activityInfo);
             final BaseIconFactory headerIconFactory = createIconFactory(mContext,
@@ -575,6 +656,8 @@
 
             final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
             mAppName = pm.getApplicationLabel(applicationInfo);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.e(TAG, "Base activity's component name cannot be found on the system");
         } finally {
             Trace.endSection();
         }
@@ -714,11 +797,41 @@
      * Create and display maximize menu window
      */
     void createMaximizeMenu() {
-        mMaximizeMenu = new MaximizeMenu(mSyncQueue, mRootTaskDisplayAreaOrganizer,
-                mDisplayController, mTaskInfo, mOnCaptionButtonClickListener,
-                mOnCaptionGenericMotionListener, mOnCaptionTouchListener, mContext,
+        mMaximizeMenu = mMaximizeMenuFactory.create(mSyncQueue, mRootTaskDisplayAreaOrganizer,
+                mDisplayController, mTaskInfo, mContext,
                 calculateMaximizeMenuPosition(), mSurfaceControlTransactionSupplier);
-        mMaximizeMenu.show();
+        mMaximizeMenu.show(
+                mOnMaximizeOrRestoreClickListener,
+                mOnLeftSnapClickListener,
+                mOnRightSnapClickListener,
+                hovered -> {
+                    mIsMaximizeMenuHovered = hovered;
+                    onMaximizeHoverStateChanged();
+                    return null;
+                }
+        );
+    }
+
+    /** Set whether the app header's maximize button is hovered. */
+    void setAppHeaderMaximizeButtonHovered(boolean hovered) {
+        mIsAppHeaderMaximizeButtonHovered = hovered;
+        onMaximizeHoverStateChanged();
+    }
+
+    /**
+     * Called when either one of the maximize button in the app header or the maximize menu has
+     * changed its hover state.
+     */
+    void onMaximizeHoverStateChanged() {
+        if (!mIsMaximizeMenuHovered && !mIsAppHeaderMaximizeButtonHovered) {
+            // Neither is hovered, close the menu.
+            if (isMaximizeMenuActive()) {
+                mHandler.postDelayed(mCloseMaximizeWindowRunnable, CLOSE_MAXIMIZE_MENU_DELAY_MS);
+            }
+            return;
+        }
+        // At least one of the two is hovered, cancel the close if needed.
+        mHandler.removeCallbacks(mCloseMaximizeWindowRunnable);
     }
 
     /**
@@ -749,11 +862,17 @@
                 .setCaptionHeight(mResult.mCaptionHeight)
                 .setDisplayController(mDisplayController)
                 .setSplitScreenController(splitScreenController)
+                .setBrowserLinkAvailable(browserLinkAvailable())
                 .build();
         mWindowDecorViewHolder.onHandleMenuOpened();
         mHandleMenu.show();
     }
 
+    @VisibleForTesting
+    boolean browserLinkAvailable() {
+        return mCapturedLink != null && !mCapturedLink.mExpired;
+    }
+
     /**
      * Close the handle menu window.
      */
@@ -992,34 +1111,22 @@
                 .setAnimatingTaskResize(animatingTaskResize);
     }
 
-    /** Called when there is a {@Link ACTION_HOVER_EXIT} on the maximize window button. */
-    void onMaximizeWindowHoverExit() {
+    /**
+     * Called when there is a {@link MotionEvent#ACTION_HOVER_EXIT} on the maximize window button.
+     */
+    void onMaximizeButtonHoverExit() {
         ((AppHeaderViewHolder) mWindowDecorViewHolder)
                 .onMaximizeWindowHoverExit();
     }
 
-    /** Called when there is a {@Link ACTION_HOVER_ENTER} on the maximize window button. */
-    void onMaximizeWindowHoverEnter() {
+    /**
+     * Called when there is a {@link MotionEvent#ACTION_HOVER_ENTER} on the maximize window button.
+     */
+    void onMaximizeButtonHoverEnter() {
         ((AppHeaderViewHolder) mWindowDecorViewHolder)
                 .onMaximizeWindowHoverEnter();
     }
 
-    /** Called when there is a {@Link ACTION_HOVER_ENTER} on a view in the maximize menu. */
-    void onMaximizeMenuHoverEnter(int id, MotionEvent ev) {
-        mMaximizeMenu.onMaximizeMenuHoverEnter(id, ev);
-    }
-
-    /** Called when there is a {@Link ACTION_HOVER_MOVE} on a view in the maximize menu. */
-    void onMaximizeMenuHoverMove(int id, MotionEvent ev) {
-        mMaximizeMenu.onMaximizeMenuHoverMove(id, ev);
-    }
-
-    /** Called when there is a {@Link ACTION_HOVER_EXIT} on a view in the maximize menu. */
-    void onMaximizeMenuHoverExit(int id, MotionEvent ev) {
-        mMaximizeMenu.onMaximizeMenuHoverExit(id, ev);
-    }
-
-
     @Override
     public String toString() {
         return "{"
@@ -1055,6 +1162,31 @@
         }
     }
 
+    @VisibleForTesting
+    static class CapturedLink {
+        private final long mTimeStamp;
+        private final Uri mUri;
+        private boolean mExpired;
+
+        CapturedLink(@NonNull Uri uri, long timeStamp) {
+            mUri = uri;
+            mTimeStamp = timeStamp;
+            mExpired = false;
+        }
+
+        void setExpired() {
+            mExpired = true;
+        }
+    }
+
+
+    /** Listener for the handle menu's "Open in browser" button */
+    interface OpenInBrowserClickListener {
+
+        /** Inform the implementing class that the "Open in browser" button has been clicked */
+        void onClick(DesktopModeWindowDecoration decoration, Uri uri);
+    }
+
     interface ExclusionRegionListener {
         /** Inform the implementing class of this task's change in region resize handles */
         void onExclusionRegionChanged(int taskId, Region region);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java
index fe1c9c3..2fd3eaa 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtility.java
@@ -28,10 +28,12 @@
 import android.util.DisplayMetrics;
 import android.view.SurfaceControl;
 
+import androidx.annotation.NonNull;
+
 import com.android.window.flags.Flags;
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 
 /**
  * Utility class that contains logic common to classes implementing {@link DragPositioningCallback}
@@ -106,13 +108,15 @@
             repositionTaskBounds.bottom = (candidateBottom < stableBounds.bottom)
                     ? candidateBottom : oldBottom;
         }
-        // If width or height are negative or less than the minimum width or height, revert the
+        // If width or height are negative or exceeding the width or height constraints, revert the
         // respective bounds to use previous bound dimensions.
-        if (repositionTaskBounds.width() < getMinWidth(displayController, windowDecoration)) {
+        if (isExceedingWidthConstraint(repositionTaskBounds, stableBounds, displayController,
+                windowDecoration)) {
             repositionTaskBounds.right = oldRight;
             repositionTaskBounds.left = oldLeft;
         }
-        if (repositionTaskBounds.height() < getMinHeight(displayController, windowDecoration)) {
+        if (isExceedingHeightConstraint(repositionTaskBounds, stableBounds, displayController,
+                windowDecoration)) {
             repositionTaskBounds.top = oldTop;
             repositionTaskBounds.bottom = oldBottom;
         }
@@ -174,6 +178,30 @@
         return result;
     }
 
+    private static boolean isExceedingWidthConstraint(@NonNull Rect repositionTaskBounds,
+            Rect maxResizeBounds, DisplayController displayController,
+            WindowDecoration windowDecoration) {
+        // Check if width is less than the minimum width constraint.
+        if (repositionTaskBounds.width() < getMinWidth(displayController, windowDecoration)) {
+            return true;
+        }
+        // Check if width is more than the maximum resize bounds on desktop windowing mode.
+        return isSizeConstraintForDesktopModeEnabled(windowDecoration.mDecorWindowContext)
+                && repositionTaskBounds.width() > maxResizeBounds.width();
+    }
+
+    private static boolean isExceedingHeightConstraint(@NonNull Rect repositionTaskBounds,
+            Rect maxResizeBounds, DisplayController displayController,
+            WindowDecoration windowDecoration) {
+        // Check if height is less than the minimum height constraint.
+        if (repositionTaskBounds.height() < getMinHeight(displayController, windowDecoration)) {
+            return true;
+        }
+        // Check if height is more than the maximum resize bounds on desktop windowing mode.
+        return isSizeConstraintForDesktopModeEnabled(windowDecoration.mDecorWindowContext)
+                && repositionTaskBounds.height() > maxResizeBounds.height();
+    }
+
     private static float getMinWidth(DisplayController displayController,
             WindowDecoration windowDecoration) {
         return windowDecoration.mTaskInfo.minWidth < 0 ? getDefaultMinWidth(displayController,
@@ -210,7 +238,7 @@
 
     private static float getDefaultMinSize(DisplayController displayController,
             WindowDecoration windowDecoration) {
-        float density =  displayController.getDisplayLayout(windowDecoration.mTaskInfo.displayId)
+        float density = displayController.getDisplayLayout(windowDecoration.mTaskInfo.displayId)
                 .densityDpi() * DisplayMetrics.DENSITY_DEFAULT_SCALE;
         return windowDecoration.mTaskInfo.defaultMinSize * density;
     }
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 d902444..a3616f6 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
@@ -55,7 +55,7 @@
 import android.view.WindowManagerGlobal;
 import android.window.InputTransferToken;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayLayout;
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java
index df0836c..7e44f32 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java
@@ -42,6 +42,7 @@
 import android.view.MotionEvent;
 import android.view.SurfaceControl;
 import android.view.View;
+import android.widget.Button;
 import android.widget.ImageButton;
 import android.widget.ImageView;
 import android.widget.TextView;
@@ -81,6 +82,7 @@
     // those as well.
     final Point mGlobalMenuPosition = new Point();
     private final boolean mShouldShowWindowingPill;
+    private final boolean mShouldShowBrowserPill;
     private final Bitmap mAppIconBitmap;
     private final CharSequence mAppName;
     private final View.OnClickListener mOnClickListener;
@@ -101,7 +103,7 @@
             View.OnClickListener onClickListener, View.OnTouchListener onTouchListener,
             Bitmap appIcon, CharSequence appName, DisplayController displayController,
             SplitScreenController splitScreenController, boolean shouldShowWindowingPill,
-            int captionHeight) {
+            boolean shouldShowBrowserPill, int captionHeight) {
         mParentDecor = parentDecor;
         mContext = mParentDecor.mDecorWindowContext;
         mTaskInfo = mParentDecor.mTaskInfo;
@@ -113,6 +115,7 @@
         mAppIconBitmap = appIcon;
         mAppName = appName;
         mShouldShowWindowingPill = shouldShowWindowingPill;
+        mShouldShowBrowserPill = shouldShowBrowserPill;
         mCaptionHeight = captionHeight;
         loadHandleMenuDimensions();
         updateHandleMenuPillPositions();
@@ -170,6 +173,7 @@
             setupWindowingPill(handleMenu);
         }
         setupMoreActionsPill(handleMenu);
+        setupOpenInBrowserPill(handleMenu);
     }
 
     /**
@@ -228,6 +232,15 @@
         }
     }
 
+    private void setupOpenInBrowserPill(View handleMenu) {
+        if (!mShouldShowBrowserPill) {
+            handleMenu.findViewById(R.id.open_in_browser_pill).setVisibility(View.GONE);
+            return;
+        }
+        final Button browserButton = handleMenu.findViewById(R.id.open_in_browser_button);
+        browserButton.setOnClickListener(mOnClickListener);
+    }
+
     /**
      * Returns array of windowing icon color based on current UI theme. First element of the
      * array is for inactive icons and the second is for active icons.
@@ -423,6 +436,10 @@
             menuHeight -= loadDimensionPixelSize(resources,
                     R.dimen.desktop_mode_handle_menu_more_actions_pill_height);
         }
+        if (!mShouldShowBrowserPill) {
+            menuHeight -= loadDimensionPixelSize(resources,
+                    R.dimen.desktop_mode_handle_menu_open_in_browser_pill_height);
+        }
         return menuHeight;
     }
 
@@ -457,6 +474,7 @@
         private int mCaptionHeight;
         private DisplayController mDisplayController;
         private SplitScreenController mSplitScreenController;
+        private boolean mShowBrowserPill;
 
         Builder(@NonNull DesktopModeWindowDecoration parent) {
             mParent = parent;
@@ -507,10 +525,15 @@
             return this;
         }
 
+        Builder setBrowserLinkAvailable(Boolean showBrowserPill) {
+            mShowBrowserPill = showBrowserPill;
+            return this;
+        }
+
         HandleMenu build() {
             return new HandleMenu(mParent, mLayoutId, mOnClickListener,
                     mOnTouchListener, mAppIcon, mName, mDisplayController, mSplitScreenController,
-                    mShowWindowingPill, mCaptionHeight);
+                    mShowWindowingPill, mShowBrowserPill, mCaptionHeight);
         }
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuAnimator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuAnimator.kt
index 8c5d4a2..25a829b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuAnimator.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuAnimator.kt
@@ -26,6 +26,7 @@
 import android.view.View.TRANSLATION_Y
 import android.view.View.TRANSLATION_Z
 import android.view.ViewGroup
+import android.widget.Button
 import androidx.core.animation.doOnEnd
 import androidx.core.view.children
 import com.android.wm.shell.R
@@ -72,6 +73,7 @@
     private val appInfoPill: ViewGroup = handleMenu.requireViewById(R.id.app_info_pill)
     private val windowingPill: ViewGroup = handleMenu.requireViewById(R.id.windowing_pill)
     private val moreActionsPill: ViewGroup = handleMenu.requireViewById(R.id.more_actions_pill)
+    private val openInBrowserPill: ViewGroup = handleMenu.requireViewById(R.id.open_in_browser_pill)
 
     /** Animates the opening of the handle menu. */
     fun animateOpen() {
@@ -80,6 +82,7 @@
         animateAppInfoPillOpen()
         animateWindowingPillOpen()
         animateMoreActionsPillOpen()
+        animateOpenInBrowserPill()
         runAnimations()
     }
 
@@ -94,6 +97,7 @@
         animateAppInfoPillOpen()
         animateWindowingPillOpen()
         animateMoreActionsPillOpen()
+        animateOpenInBrowserPill()
         runAnimations()
     }
 
@@ -109,6 +113,7 @@
         animateAppInfoPillFadeOut()
         windowingPillClose()
         moreActionsPillClose()
+        openInBrowserPillClose()
         runAnimations(after)
     }
 
@@ -125,6 +130,7 @@
         animateAppInfoPillFadeOut()
         windowingPillClose()
         moreActionsPillClose()
+        openInBrowserPillClose()
         runAnimations(after)
     }
 
@@ -137,6 +143,7 @@
         appInfoPill.children.forEach { it.alpha = 0f }
         windowingPill.alpha = 0f
         moreActionsPill.alpha = 0f
+        openInBrowserPill.alpha = 0f
 
         // Setup pivots.
         handleMenu.pivotX = menuWidth / 2f
@@ -147,6 +154,9 @@
 
         moreActionsPill.pivotX = menuWidth / 2f
         moreActionsPill.pivotY = appInfoPill.measuredHeight.toFloat()
+
+        openInBrowserPill.pivotX = menuWidth / 2f
+        openInBrowserPill.pivotY = appInfoPill.measuredHeight.toFloat()
     }
 
     private fun animateAppInfoPillOpen() {
@@ -268,12 +278,50 @@
         // More Actions Content Opacity Animation
         moreActionsPill.children.forEach {
             animators +=
-                ObjectAnimator.ofFloat(it, ALPHA, 1f).apply {
+                    ObjectAnimator.ofFloat(it, ALPHA, 1f).apply {
+                        startDelay = BODY_ALPHA_OPEN_DELAY
+                        duration = BODY_CONTENT_ALPHA_OPEN_DURATION
+                        interpolator = Interpolators.FAST_OUT_SLOW_IN
+                    }
+        }
+    }
+
+    private fun animateOpenInBrowserPill() {
+        // Open in Browser X & Y Scaling Animation
+        animators +=
+                ObjectAnimator.ofFloat(openInBrowserPill, SCALE_X, HALF_INITIAL_SCALE, 1f).apply {
+                    startDelay = BODY_SCALE_OPEN_DELAY
+                    duration = BODY_SCALE_OPEN_DURATION
+                }
+
+        animators +=
+                ObjectAnimator.ofFloat(openInBrowserPill, SCALE_Y, HALF_INITIAL_SCALE, 1f).apply {
+                    startDelay = BODY_SCALE_OPEN_DELAY
+                    duration = BODY_SCALE_OPEN_DURATION
+                }
+
+        // Open in Browser Opacity Animation
+        animators +=
+                ObjectAnimator.ofFloat(openInBrowserPill, ALPHA, 1f).apply {
+                    startDelay = BODY_ALPHA_OPEN_DELAY
+                    duration = BODY_ALPHA_OPEN_DURATION
+                }
+
+        // Open in Browser Elevation Animation
+        animators +=
+                ObjectAnimator.ofFloat(openInBrowserPill, TRANSLATION_Z, 1f).apply {
+                    startDelay = ELEVATION_OPEN_DELAY
+                    duration = BODY_ELEVATION_OPEN_DURATION
+                }
+
+        // Open in Browser Button Opacity Animation
+        val button = openInBrowserPill.requireViewById<Button>(R.id.open_in_browser_button)
+        animators +=
+                ObjectAnimator.ofFloat(button, ALPHA, 1f).apply {
                     startDelay = BODY_ALPHA_OPEN_DELAY
                     duration = BODY_CONTENT_ALPHA_OPEN_DURATION
                     interpolator = Interpolators.FAST_OUT_SLOW_IN
                 }
-        }
     }
 
     private fun appInfoPillCollapse() {
@@ -379,6 +427,37 @@
             }
     }
 
+    private fun openInBrowserPillClose() {
+        // Open in Browser X & Y Scaling Animation
+        animators +=
+                ObjectAnimator.ofFloat(openInBrowserPill, SCALE_X, HALF_INITIAL_SCALE).apply {
+                    duration = BODY_CLOSE_DURATION
+                }
+
+        animators +=
+                ObjectAnimator.ofFloat(openInBrowserPill, SCALE_Y, HALF_INITIAL_SCALE).apply {
+                    duration = BODY_CLOSE_DURATION
+                }
+
+        // Open in Browser Opacity Animation
+        animators +=
+                ObjectAnimator.ofFloat(openInBrowserPill, ALPHA, 0f).apply {
+                    duration = BODY_CLOSE_DURATION
+                }
+
+        animators +=
+                ObjectAnimator.ofFloat(openInBrowserPill, ALPHA, 0f).apply {
+                    duration = BODY_CLOSE_DURATION
+                }
+
+        // Upward Open in Browser y-translation Animation
+        val yStart: Float = -captionHeight / 2
+        animators +=
+                ObjectAnimator.ofFloat(openInBrowserPill, TRANSLATION_Y, yStart).apply {
+                    duration = BODY_CLOSE_DURATION
+                }
+    }
+
     /**
      * Runs the list of hide animators concurrently.
      *
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
index 0470367..5f9f8d6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
@@ -20,7 +20,6 @@
 import android.animation.ObjectAnimator
 import android.animation.ValueAnimator
 import android.annotation.ColorInt
-import android.annotation.IdRes
 import android.app.ActivityManager.RunningTaskInfo
 import android.content.Context
 import android.content.res.ColorStateList
@@ -28,6 +27,7 @@
 import android.graphics.Paint
 import android.graphics.PixelFormat
 import android.graphics.PointF
+import android.graphics.Rect
 import android.graphics.drawable.Drawable
 import android.graphics.drawable.GradientDrawable
 import android.graphics.drawable.LayerDrawable
@@ -37,16 +37,17 @@
 import android.util.StateSet
 import android.view.LayoutInflater
 import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_HOVER_ENTER
+import android.view.MotionEvent.ACTION_HOVER_EXIT
+import android.view.MotionEvent.ACTION_HOVER_MOVE
 import android.view.SurfaceControl
 import android.view.SurfaceControl.Transaction
 import android.view.SurfaceControlViewHost
 import android.view.View
-import android.view.View.OnClickListener
-import android.view.View.OnGenericMotionListener
-import android.view.View.OnTouchListener
 import android.view.View.SCALE_Y
 import android.view.View.TRANSLATION_Y
 import android.view.View.TRANSLATION_Z
+import android.view.ViewGroup
 import android.view.WindowManager
 import android.view.WindowlessWindowManager
 import android.widget.Button
@@ -64,10 +65,10 @@
 import com.android.wm.shell.windowdecor.common.DecorThemeUtil
 import com.android.wm.shell.windowdecor.common.OPACITY_12
 import com.android.wm.shell.windowdecor.common.OPACITY_40
+import com.android.wm.shell.windowdecor.common.OnTaskActionClickListener
 import com.android.wm.shell.windowdecor.common.withAlpha
 import java.util.function.Supplier
 
-
 /**
  *  Menu that appears when user long clicks the maximize button. Gives the user the option to
  *  maximize the task or snap the task to the right or left half of the screen.
@@ -77,9 +78,6 @@
         private val rootTdaOrganizer: RootTaskDisplayAreaOrganizer,
         private val displayController: DisplayController,
         private val taskInfo: RunningTaskInfo,
-        private val onClickListener: OnClickListener,
-        private val onGenericMotionListener: OnGenericMotionListener,
-        private val onTouchListener: OnTouchListener,
         private val decorWindowContext: Context,
         private val menuPosition: PointF,
         private val transactionSupplier: Supplier<Transaction> = Supplier { Transaction() }
@@ -102,9 +100,19 @@
     }
 
     /** Creates and shows the maximize window. */
-    fun show() {
+    fun show(
+        onMaximizeClickListener: OnTaskActionClickListener,
+        onLeftSnapClickListener: OnTaskActionClickListener,
+        onRightSnapClickListener: OnTaskActionClickListener,
+        onHoverListener: (Boolean) -> Unit
+    ) {
         if (maximizeMenu != null) return
-        createMaximizeMenu()
+        createMaximizeMenu(
+            onMaximizeClickListener = onMaximizeClickListener,
+            onLeftSnapClickListener = onLeftSnapClickListener,
+            onRightSnapClickListener = onRightSnapClickListener,
+            onHoverListener = onHoverListener
+        )
         maximizeMenuView?.animateOpenMenu()
     }
 
@@ -117,7 +125,12 @@
     }
 
     /** Create a maximize menu that is attached to the display area. */
-    private fun createMaximizeMenu() {
+    private fun createMaximizeMenu(
+        onMaximizeClickListener: OnTaskActionClickListener,
+        onLeftSnapClickListener: OnTaskActionClickListener,
+        onRightSnapClickListener: OnTaskActionClickListener,
+        onHoverListener: (Boolean) -> Unit
+    ) {
         val t = transactionSupplier.get()
         val builder = SurfaceControl.Builder()
         rootTdaOrganizer.attachToDisplayArea(taskInfo.displayId, builder)
@@ -146,11 +159,19 @@
             context = decorWindowContext,
             menuHeight = menuHeight,
             menuPadding = menuPadding,
-            onClickListener = onClickListener,
-            onTouchListener = onTouchListener,
-            onGenericMotionListener = onGenericMotionListener,
         ).also { menuView ->
+            val taskId = taskInfo.taskId
             menuView.bind(taskInfo)
+            menuView.onMaximizeClickListener = {
+                onMaximizeClickListener.onClick(taskId, "maximize_menu_option")
+            }
+            menuView.onLeftSnapClickListener = {
+                onLeftSnapClickListener.onClick(taskId, "left_snap_option")
+            }
+            menuView.onRightSnapClickListener = {
+                onRightSnapClickListener.onClick(taskId, "right_snap_option")
+            }
+            menuView.onMenuHoverListener = onHoverListener
             viewHost.setView(menuView.rootView, lp)
         }
 
@@ -198,56 +219,6 @@
     }
 
     /**
-     * Called when a [MotionEvent.ACTION_HOVER_ENTER] is triggered on any of the menu's views.
-     *
-     * TODO(b/346440693): this is only needed for the left/right snap options that don't support
-     *  selector states to manage its hover state. Look into whether that can be added to avoid
-     *  manually tracking hover enter/exit motion events. Also because those button colors/states
-     *  aren't updating correctly for pressed, focused and selected states.
-     *  See also [onMaximizeMenuHoverMove] and [onMaximizeMenuHoverExit].
-     */
-    fun onMaximizeMenuHoverEnter(viewId: Int, ev: MotionEvent) {
-        setSnapButtonsColorOnHover(viewId, ev)
-    }
-
-    /** Called when a [MotionEvent.ACTION_HOVER_MOVE] is triggered on any of the menu's views. */
-    fun onMaximizeMenuHoverMove(viewId: Int, ev: MotionEvent) {
-        setSnapButtonsColorOnHover(viewId, ev)
-    }
-
-    /** Called when a [MotionEvent.ACTION_HOVER_EXIT] is triggered on any of the menu's views. */
-    fun onMaximizeMenuHoverExit(id: Int, ev: MotionEvent) {
-        val snapOptionsWidth = maximizeMenuView?.snapOptionsWidth ?: return
-        val snapOptionsHeight = maximizeMenuView?.snapOptionsHeight ?: return
-        val inSnapMenuBounds = ev.x >= 0 && ev.x <= snapOptionsWidth &&
-                ev.y >= 0 && ev.y <= snapOptionsHeight
-
-        if (id == R.id.maximize_menu_snap_menu_layout && !inSnapMenuBounds) {
-            // After exiting the snap menu layout area, checks to see that user is not still
-            // hovering within the snap menu layout bounds which would indicate that the user is
-            // hovering over a snap button within the snap menu layout rather than having exited.
-            maximizeMenuView?.updateSplitSnapSelection(MaximizeMenuView.SnapToHalfSelection.NONE)
-        }
-    }
-
-    private fun setSnapButtonsColorOnHover(viewId: Int, ev: MotionEvent) {
-        val snapOptionsWidth = maximizeMenuView?.snapOptionsWidth ?: return
-        val snapMenuCenter = snapOptionsWidth / 2
-        when {
-            viewId == R.id.maximize_menu_snap_left_button ||
-                    (viewId == R.id.maximize_menu_snap_menu_layout && ev.x <= snapMenuCenter) -> {
-                        maximizeMenuView
-                            ?.updateSplitSnapSelection(MaximizeMenuView.SnapToHalfSelection.LEFT)
-            }
-            viewId == R.id.maximize_menu_snap_right_button ||
-                    (viewId == R.id.maximize_menu_snap_menu_layout && ev.x > snapMenuCenter) -> {
-                        maximizeMenuView
-                            ?.updateSplitSnapSelection(MaximizeMenuView.SnapToHalfSelection.RIGHT)
-                    }
-        }
-    }
-
-    /**
      * The view within the Maximize Menu, presents maximize, restore and snap-to-side options for
      * resizing a Task.
      */
@@ -255,12 +226,11 @@
         context: Context,
         private val menuHeight: Int,
         private val menuPadding: Int,
-        onClickListener: OnClickListener,
-        onTouchListener: OnTouchListener,
-        onGenericMotionListener: OnGenericMotionListener,
     ) {
-        val rootView: View = LayoutInflater.from(context)
-            .inflate(R.layout.desktop_mode_window_decor_maximize_menu, null /* root */)
+        val rootView = LayoutInflater.from(context)
+            .inflate(R.layout.desktop_mode_window_decor_maximize_menu, null /* root */) as ViewGroup
+        private val container = requireViewById(R.id.container)
+        private val overlay = requireViewById(R.id.maximize_menu_overlay)
         private val maximizeText =
             requireViewById(R.id.maximize_menu_maximize_window_text) as TextView
         private val maximizeButton =
@@ -285,30 +255,63 @@
         private val fillRadius = context.resources
             .getDimensionPixelSize(R.dimen.desktop_mode_maximize_menu_buttons_fill_radius)
 
+        private val hoverTempRect = Rect()
         private val openMenuAnimatorSet = AnimatorSet()
         private lateinit var taskInfo: RunningTaskInfo
         private lateinit var style: MenuStyle
 
-        /** The width of the snap menu option view, including both left and right snaps. */
-        val snapOptionsWidth: Int
-            get() = snapButtonsLayout.width
-        /** The height of the snap menu option view, including both left and right snaps .*/
-        val snapOptionsHeight: Int
-            get() = snapButtonsLayout.height
+        /** Invoked when the maximize or restore option is clicked. */
+        var onMaximizeClickListener: (() -> Unit)? = null
+        /** Invoked when the left snap option is clicked. */
+        var onLeftSnapClickListener: (() -> Unit)? = null
+        /** Invoked when the right snap option is clicked. */
+        var onRightSnapClickListener: (() -> Unit)? = null
+        /** Invoked whenever the hover state of the menu changes. */
+        var onMenuHoverListener: ((Boolean) -> Unit)? = null
 
         init {
-            // TODO(b/346441962): encapsulate menu hover enter/exit logic inside this class and
-            //  expose only what  is actually relevant to outside classes so that specific checks
-            //  against resource IDs aren't needed outside this class.
-            rootView.setOnGenericMotionListener(onGenericMotionListener)
-            rootView.setOnTouchListener(onTouchListener)
-            maximizeButton.setOnClickListener(onClickListener)
-            maximizeButton.setOnGenericMotionListener(onGenericMotionListener)
-            snapRightButton.setOnClickListener(onClickListener)
-            snapRightButton.setOnGenericMotionListener(onGenericMotionListener)
-            snapLeftButton.setOnClickListener(onClickListener)
-            snapLeftButton.setOnGenericMotionListener(onGenericMotionListener)
-            snapButtonsLayout.setOnGenericMotionListener(onGenericMotionListener)
+            overlay.setOnHoverListener { _, event ->
+                // The overlay covers the entire menu, so it's a convenient way to monitor whether
+                // the menu is hovered as a whole or not.
+                when (event.action) {
+                    ACTION_HOVER_ENTER -> onMenuHoverListener?.invoke(true)
+                    ACTION_HOVER_EXIT -> onMenuHoverListener?.invoke(false)
+                }
+
+                // Also check if the hover falls within the snap options layout, to manually
+                // set the left/right state based on the event's position.
+                // TODO(b/346440693): this manual hover tracking is needed for left/right snap
+                //  because its view/background(s) don't support selector states. Look into whether
+                //  that can be added to avoid manual tracking. Also because these button
+                //  colors/state logic is only being applied on hover events, but there's pressed,
+                //  focused and selected states that should be responsive too.
+                val snapLayoutBoundsRelToOverlay = hoverTempRect.also { rect ->
+                    snapButtonsLayout.getDrawingRect(rect)
+                    rootView.offsetDescendantRectToMyCoords(snapButtonsLayout, rect)
+                }
+                if (event.action == ACTION_HOVER_ENTER || event.action == ACTION_HOVER_MOVE) {
+                    if (snapLayoutBoundsRelToOverlay.contains(event.x.toInt(), event.y.toInt())) {
+                        // Hover is inside the snap layout, anything left of center is the left
+                        // snap, and anything right of center is right snap.
+                        val layoutCenter = snapLayoutBoundsRelToOverlay.centerX()
+                        if (event.x < layoutCenter) {
+                            updateSplitSnapSelection(SnapToHalfSelection.LEFT)
+                        } else {
+                            updateSplitSnapSelection(SnapToHalfSelection.RIGHT)
+                        }
+                    } else {
+                        // Any other hover is outside the snap layout, so neither is selected.
+                        updateSplitSnapSelection(SnapToHalfSelection.NONE)
+                    }
+                }
+
+                // Don't consume the event to allow child views to receive the event too.
+                return@setOnHoverListener false
+            }
+
+            maximizeButton.setOnClickListener { onMaximizeClickListener?.invoke() }
+            snapRightButton.setOnClickListener { onRightSnapClickListener?.invoke() }
+            snapLeftButton.setOnClickListener { onLeftSnapClickListener?.invoke() }
 
             // To prevent aliasing.
             maximizeButton.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
@@ -351,7 +354,7 @@
                             val value = animatedValue as Float
                             val topPadding = menuPadding -
                                     ((1 - value) * menuHeight).toInt()
-                            rootView.setPadding(menuPadding, topPadding,
+                            container.setPadding(menuPadding, topPadding,
                                 menuPadding, menuPadding)
                         }
                     },
@@ -410,7 +413,7 @@
         }
 
         /** Update the view state to a new snap to half selection. */
-        fun updateSplitSnapSelection(selection: SnapToHalfSelection) {
+        private fun updateSplitSnapSelection(selection: SnapToHalfSelection) {
             when (selection) {
                 SnapToHalfSelection.NONE -> deactivateSnapOptions()
                 SnapToHalfSelection.LEFT -> activateSnapOption(activateLeft = true)
@@ -638,13 +641,41 @@
         private const val ELEVATION_ANIMATION_DURATION_MS = 50L
         private const val CONTROLS_ALPHA_ANIMATION_DELAY_MS = 33L
         private const val MENU_Z_TRANSLATION = 1f
-        fun isMaximizeMenuView(@IdRes viewId: Int): Boolean {
-            return viewId == R.id.maximize_menu ||
-                    viewId == R.id.maximize_menu_maximize_button ||
-                    viewId == R.id.maximize_menu_snap_left_button ||
-                    viewId == R.id.maximize_menu_snap_right_button ||
-                    viewId == R.id.maximize_menu_snap_menu_layout ||
-                    viewId == R.id.maximize_menu_snap_menu_layout
-        }
+    }
+}
+
+/** A factory interface to create a [MaximizeMenu]. */
+interface MaximizeMenuFactory {
+    fun create(
+        syncQueue: SyncTransactionQueue,
+        rootTdaOrganizer: RootTaskDisplayAreaOrganizer,
+        displayController: DisplayController,
+        taskInfo: RunningTaskInfo,
+        decorWindowContext: Context,
+        menuPosition: PointF,
+        transactionSupplier: Supplier<Transaction>
+    ): MaximizeMenu
+}
+
+/** A [MaximizeMenuFactory] implementation that creates a [MaximizeMenu].  */
+object DefaultMaximizeMenuFactory : MaximizeMenuFactory {
+    override fun create(
+        syncQueue: SyncTransactionQueue,
+        rootTdaOrganizer: RootTaskDisplayAreaOrganizer,
+        displayController: DisplayController,
+        taskInfo: RunningTaskInfo,
+        decorWindowContext: Context,
+        menuPosition: PointF,
+        transactionSupplier: Supplier<Transaction>
+    ): MaximizeMenu {
+        return MaximizeMenu(
+            syncQueue,
+            rootTdaOrganizer,
+            displayController,
+            taskInfo,
+            decorWindowContext,
+            menuPosition,
+            transactionSupplier
+        )
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
index 5fce5d2..1532211 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
@@ -18,6 +18,8 @@
 
 import static android.view.WindowManager.TRANSIT_CHANGE;
 
+import static com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_RESIZE_WINDOW;
+
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
@@ -31,6 +33,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.internal.jank.InteractionJankMonitor;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.transition.Transitions;
@@ -56,6 +59,7 @@
     private final PointF mRepositionStartPoint = new PointF();
     private final Rect mRepositionTaskBounds = new Rect();
     private final Supplier<SurfaceControl.Transaction> mTransactionSupplier;
+    private final InteractionJankMonitor mInteractionJankMonitor;
     private int mCtrlType;
     private boolean mIsResizingOrAnimatingResize;
     @Surface.Rotation private int mRotation;
@@ -64,22 +68,24 @@
             DesktopModeWindowDecoration windowDecoration,
             DisplayController displayController,
             DragPositioningCallbackUtility.DragStartListener dragStartListener,
-            Transitions transitions) {
+            Transitions transitions, InteractionJankMonitor interactionJankMonitor) {
         this(taskOrganizer, windowDecoration, displayController, dragStartListener,
-                SurfaceControl.Transaction::new, transitions);
+                SurfaceControl.Transaction::new, transitions, interactionJankMonitor);
     }
 
     public VeiledResizeTaskPositioner(ShellTaskOrganizer taskOrganizer,
             DesktopModeWindowDecoration windowDecoration,
             DisplayController displayController,
             DragPositioningCallbackUtility.DragStartListener dragStartListener,
-            Supplier<SurfaceControl.Transaction> supplier, Transitions transitions) {
+            Supplier<SurfaceControl.Transaction> supplier, Transitions transitions,
+            InteractionJankMonitor interactionJankMonitor) {
         mDesktopWindowDecoration = windowDecoration;
         mTaskOrganizer = taskOrganizer;
         mDisplayController = displayController;
         mDragStartListener = dragStartListener;
         mTransactionSupplier = supplier;
         mTransitions = transitions;
+        mInteractionJankMonitor = interactionJankMonitor;
     }
 
     @Override
@@ -89,6 +95,9 @@
                 mDesktopWindowDecoration.mTaskInfo.configuration.windowConfiguration.getBounds());
         mRepositionStartPoint.set(x, y);
         if (isResizing()) {
+            // Capture CUJ for re-sizing window in DW mode.
+            mInteractionJankMonitor.begin(mDesktopWindowDecoration.mTaskSurface,
+                    mDesktopWindowDecoration.mContext, CUJ_DESKTOP_MODE_RESIZE_WINDOW);
             if (!mDesktopWindowDecoration.mTaskInfo.isFocused) {
                 WindowContainerTransaction wct = new WindowContainerTransaction();
                 wct.reorder(mDesktopWindowDecoration.mTaskInfo.token, true);
@@ -146,6 +155,7 @@
                 // won't be called.
                 resetVeilIfVisible();
             }
+            mInteractionJankMonitor.end(CUJ_DESKTOP_MODE_RESIZE_WINDOW);
         } else {
             final WindowContainerTransaction wct = new WindowContainerTransaction();
             DragPositioningCallbackUtility.updateTaskBounds(mRepositionTaskBounds,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index 216990c..03dbbb3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -55,7 +55,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.windowdecor.WindowDecoration.RelayoutParams.OccludingCaptionElement;
 import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewHostViewContainer;
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/OnTaskActionClickListener.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/OnTaskActionClickListener.kt
new file mode 100644
index 0000000..14b9e7f
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/common/OnTaskActionClickListener.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.windowdecor.common
+
+/** A callback to be invoked when a Task's window decor element is clicked. */
+fun interface OnTaskActionClickListener {
+    /**
+     * Called when a task's decor element has been clicked.
+     *
+     * @param taskId the id of the task.
+     * @param tag a readable identifier for the element.
+     */
+    fun onClick(taskId: Int, tag: String)
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
index a0a61fe2..d0e8215 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt
@@ -117,12 +117,10 @@
 
     /**
      * Checks that all parts of the screen are covered at the start and end of the transition
-     *
-     * TODO b/197726599 Prevents all states from being checked
      */
     @Presubmit
     @Test
-    fun entireScreenCoveredAtStartAndEnd() = flicker.entireScreenCovered(allStates = false)
+    fun entireScreenCoveredAtStartAndEnd() = flicker.entireScreenCovered()
 
     /** Checks [pipApp] window remains visible and on top throughout the transition */
     @Presubmit
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt
index 35ed8de..7873a85 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipTest.kt
@@ -65,7 +65,7 @@
         setup {
             standardAppHelper.launchViaIntent(
                 wmHelper,
-                YouTubeAppHelper.getYoutubeVideoIntent("HPcEAtoXXLA"),
+                YouTubeAppHelper.getYoutubeVideoIntent("3KtWfp0UopM"),
                 ComponentNameMatcher(YouTubeAppHelper.PACKAGE_NAME, "")
             )
             standardAppHelper.waitForVideoPlaying()
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt
index 879034f..5c539a5 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt
@@ -73,7 +73,7 @@
         setup {
             standardAppHelper.launchViaIntent(
                 wmHelper,
-                YouTubeAppHelper.getYoutubeVideoIntent("HPcEAtoXXLA"),
+                YouTubeAppHelper.getYoutubeVideoIntent("3KtWfp0UopM"),
                 ComponentNameMatcher(YouTubeAppHelper.PACKAGE_NAME, "")
             )
             standardAppHelper.enterFullscreen()
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/DesktopModeFlickerScenarios.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/DesktopModeFlickerScenarios.kt
index d485b82..430f80b 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/DesktopModeFlickerScenarios.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/DesktopModeFlickerScenarios.kt
@@ -20,18 +20,23 @@
 import android.tools.flicker.assertors.assertions.AppLayerIsInvisibleAtEnd
 import android.tools.flicker.assertors.assertions.AppLayerIsVisibleAlways
 import android.tools.flicker.assertors.assertions.AppLayerIsVisibleAtStart
+import android.tools.flicker.assertors.assertions.AppWindowBecomesVisible
 import android.tools.flicker.assertors.assertions.AppWindowHasDesktopModeInitialBoundsAtTheEnd
-import android.tools.flicker.assertors.assertions.AppWindowIsVisibleAlways
+import android.tools.flicker.assertors.assertions.AppWindowHasSizeOfAtLeast
+import android.tools.flicker.assertors.assertions.AppWindowIsInvisibleAtEnd
 import android.tools.flicker.assertors.assertions.AppWindowOnTopAtEnd
 import android.tools.flicker.assertors.assertions.AppWindowOnTopAtStart
-import android.tools.flicker.assertors.assertions.AppWindowRemainInsideDisplayBounds
-import android.tools.flicker.assertors.assertions.LauncherWindowMovesToTop
+import android.tools.flicker.assertors.assertions.LauncherWindowReplacesAppAsTopWindow
 import android.tools.flicker.config.AssertionTemplates
 import android.tools.flicker.config.FlickerConfigEntry
 import android.tools.flicker.config.ScenarioId
 import android.tools.flicker.config.desktopmode.Components
+import android.tools.flicker.config.desktopmode.Components.DESKTOP_WALLPAPER
 import android.tools.flicker.extractors.ITransitionMatcher
 import android.tools.flicker.extractors.ShellTransitionScenarioExtractor
+import android.tools.flicker.extractors.TaggedCujTransitionMatcher
+import android.tools.flicker.extractors.TaggedScenarioExtractorBuilder
+import android.tools.traces.events.CujType
 import android.tools.traces.wm.Transition
 import android.tools.traces.wm.TransitionType
 
@@ -48,6 +53,7 @@
                                     transitions: Collection<Transition>
                                 ): Collection<Transition> {
                                     return transitions.filter {
+                                        // TODO(351168217) Use jank CUJ to extract a longer trace
                                         it.type == TransitionType.DESKTOP_MODE_END_DRAG_TO_DESKTOP
                                     }
                                 }
@@ -60,11 +66,14 @@
                                 AppWindowOnTopAtEnd(Components.DESKTOP_MODE_APP),
                                 AppWindowHasDesktopModeInitialBoundsAtTheEnd(
                                     Components.DESKTOP_MODE_APP
-                                )
+                                ),
+                                AppWindowBecomesVisible(DESKTOP_WALLPAPER)
                             )
                             .associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
             )
 
+        // Use this scenario for closing an app in desktop windowing, except the last app. For the
+        // last app use CLOSE_LAST_APP scenario
         val CLOSE_APP =
             FlickerConfigEntry(
                 scenarioId = ScenarioId("CLOSE_APP"),
@@ -75,7 +84,13 @@
                                 override fun findAll(
                                     transitions: Collection<Transition>
                                 ): Collection<Transition> {
-                                    return transitions.filter { it.type == TransitionType.CLOSE }
+                                    // In case there are multiple windows closing, filter out the
+                                    // last window closing. It should use the CLOSE_LAST_APP
+                                    // scenario below.
+                                    return transitions
+                                        .filter { it.type == TransitionType.CLOSE }
+                                        .sortedByDescending { it.id }
+                                        .drop(1)
                                 }
                             }
                     ),
@@ -100,19 +115,19 @@
                                     transitions: Collection<Transition>
                                 ): Collection<Transition> {
                                     val lastTransition =
-                                        transitions.findLast { it.type == TransitionType.CLOSE }
-                                    return if (lastTransition != null) listOf(lastTransition)
-                                    else emptyList()
+                                        transitions
+                                            .filter { it.type == TransitionType.CLOSE }
+                                            .maxByOrNull { it.id }!!
+                                    return listOf(lastTransition)
                                 }
                             }
                     ),
                 assertions =
                     AssertionTemplates.COMMON_ASSERTIONS +
                         listOf(
-                                AppWindowOnTopAtStart(Components.DESKTOP_MODE_APP),
-                                AppLayerIsVisibleAtStart(Components.DESKTOP_MODE_APP),
-                                AppLayerIsInvisibleAtEnd(Components.DESKTOP_MODE_APP),
-                                LauncherWindowMovesToTop()
+                                AppWindowIsInvisibleAtEnd(Components.DESKTOP_MODE_APP),
+                                LauncherWindowReplacesAppAsTopWindow(Components.DESKTOP_MODE_APP),
+                                AppWindowIsInvisibleAtEnd(DESKTOP_WALLPAPER)
                             )
                             .associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
             )
@@ -121,24 +136,29 @@
             FlickerConfigEntry(
                 scenarioId = ScenarioId("CORNER_RESIZE"),
                 extractor =
-                ShellTransitionScenarioExtractor(
-                    transitionMatcher =
-                    object : ITransitionMatcher {
-                        override fun findAll(
-                            transitions: Collection<Transition>
-                        ): Collection<Transition> {
-                            return transitions.filter {
-                                it.type == TransitionType.CHANGE
-                            }
-                        }
-                    }
-                ),
+                    TaggedScenarioExtractorBuilder()
+                        .setTargetTag(CujType.CUJ_DESKTOP_MODE_RESIZE_WINDOW)
+                        .setTransitionMatcher(
+                            TaggedCujTransitionMatcher(associatedTransitionRequired = false)
+                        )
+                        .build(),
+                assertions = AssertionTemplates.DESKTOP_MODE_APP_VISIBILITY_ASSERTIONS
+            )
+
+        val CORNER_RESIZE_TO_MINIMUM_SIZE =
+            FlickerConfigEntry(
+                scenarioId = ScenarioId("CORNER_RESIZE_TO_MINIMUM_SIZE"),
+                extractor =
+                    TaggedScenarioExtractorBuilder()
+                        .setTargetTag(CujType.CUJ_DESKTOP_MODE_RESIZE_WINDOW)
+                        .setTransitionMatcher(
+                            TaggedCujTransitionMatcher(associatedTransitionRequired = false)
+                        )
+                        .build(),
                 assertions =
-                        listOf(
-                            AppWindowIsVisibleAlways(Components.DESKTOP_MODE_APP),
-                            AppWindowOnTopAtEnd(Components.DESKTOP_MODE_APP),
-                            AppWindowRemainInsideDisplayBounds(Components.DESKTOP_MODE_APP),
-                        ).associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
+                    AssertionTemplates.DESKTOP_MODE_APP_VISIBILITY_ASSERTIONS +
+                        listOf(AppWindowHasSizeOfAtLeast(Components.DESKTOP_MODE_APP, 770, 700))
+                            .associateBy({ it }, { AssertionInvocationGroup.BLOCKING }),
             )
     }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizeLandscape.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizeLandscape.kt
new file mode 100644
index 0000000..6319cf7
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizeLandscape.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.service.desktopmode.flicker
+
+import android.tools.Rotation
+import android.tools.flicker.FlickerConfig
+import android.tools.flicker.annotation.ExpectedScenarios
+import android.tools.flicker.annotation.FlickerConfigProvider
+import android.tools.flicker.config.FlickerConfig
+import android.tools.flicker.config.FlickerServiceConfig
+import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE_TO_MINIMUM_SIZE
+import com.android.wm.shell.flicker.service.desktopmode.scenarios.ResizeAppWithCornerResize
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Resize app window using corner resize to the smallest possible height and width in
+ * landscape mode.
+ *
+ * Assert that the minimum window size constraint is maintained.
+ */
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class ResizeAppToMinimumWindowSizeLandscape : ResizeAppWithCornerResize(
+    rotation = Rotation.ROTATION_90,
+    horizontalChange = -1500,
+    verticalChange = 1500) {
+    @ExpectedScenarios(["CORNER_RESIZE_TO_MINIMUM_SIZE"])
+    @Test
+    override fun resizeAppWithCornerResize() = super.resizeAppWithCornerResize()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT).use(CORNER_RESIZE_TO_MINIMUM_SIZE)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizePortrait.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizePortrait.kt
new file mode 100644
index 0000000..431f6e3
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/flicker/ResizeAppToMinimumWindowSizePortrait.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.service.desktopmode.flicker
+
+import android.tools.flicker.FlickerConfig
+import android.tools.flicker.annotation.ExpectedScenarios
+import android.tools.flicker.annotation.FlickerConfigProvider
+import android.tools.flicker.config.FlickerConfig
+import android.tools.flicker.config.FlickerServiceConfig
+import android.tools.flicker.junit.FlickerServiceJUnit4ClassRunner
+import com.android.wm.shell.flicker.service.desktopmode.flicker.DesktopModeFlickerScenarios.Companion.CORNER_RESIZE_TO_MINIMUM_SIZE
+import com.android.wm.shell.flicker.service.desktopmode.scenarios.ResizeAppWithCornerResize
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Resize app window using corner resize to the smallest possible height and width in portrait mode.
+ *
+ * Assert that the minimum window size constraint is maintained.
+ */
+@RunWith(FlickerServiceJUnit4ClassRunner::class)
+class ResizeAppToMinimumWindowSizePortrait : ResizeAppWithCornerResize(horizontalChange = -1500,
+    verticalChange = 1500) {
+    @ExpectedScenarios(["CORNER_RESIZE_TO_MINIMUM_SIZE"])
+    @Test
+    override fun resizeAppWithCornerResize() = super.resizeAppWithCornerResize()
+
+    companion object {
+        @JvmStatic
+        @FlickerConfigProvider
+        fun flickerConfigProvider(): FlickerConfig =
+            FlickerConfig().use(FlickerServiceConfig.DEFAULT).use(CORNER_RESIZE_TO_MINIMUM_SIZE)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/MaximizeAppWindow.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/MaximizeAppWindow.kt
new file mode 100644
index 0000000..20e2167c
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/MaximizeAppWindow.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.service.desktopmode.scenarios
+
+import android.app.Instrumentation
+import android.tools.NavBar
+import android.tools.Rotation
+import android.tools.traces.parsers.WindowManagerStateHelper
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.launcher3.tapl.LauncherInstrumentation
+import com.android.server.wm.flicker.helpers.DesktopModeAppHelper
+import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.window.flags.Flags
+import com.android.wm.shell.flicker.service.common.Utils
+import org.junit.After
+import org.junit.Assume
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+
+/** Base scenario test for maximize app window CUJ in desktop mode. */
+@Ignore("Base Test Class")
+abstract class MaximizeAppWindow
+{
+    private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val tapl = LauncherInstrumentation()
+    private val wmHelper = WindowManagerStateHelper(instrumentation)
+    private val device = UiDevice.getInstance(instrumentation)
+    private val testApp = DesktopModeAppHelper(SimpleAppHelper(instrumentation))
+
+    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL,
+        Rotation.ROTATION_0)
+
+    @Before
+    fun setup() {
+        Assume.assumeTrue(Flags.enableDesktopWindowingMode() && tapl.isTablet)
+        testApp.enterDesktopWithDrag(wmHelper, device)
+    }
+
+    @Test
+    open fun maximizeAppWindow() {
+        testApp.maximiseDesktopApp(wmHelper, device)
+    }
+
+    @After
+    fun teardown() {
+        testApp.exit(wmHelper)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ResizeAppWithCornerResize.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ResizeAppWithCornerResize.kt
index ac9089a..136cf37 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ResizeAppWithCornerResize.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/desktopmode/scenarios/ResizeAppWithCornerResize.kt
@@ -38,7 +38,9 @@
 @Ignore("Base Test Class")
 abstract class ResizeAppWithCornerResize
 @JvmOverloads
-constructor(val rotation: Rotation = Rotation.ROTATION_0) {
+constructor(val rotation: Rotation = Rotation.ROTATION_0,
+    val horizontalChange: Int = 50,
+    val verticalChange: Int = -50) {
 
     private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
     private val tapl = LauncherInstrumentation()
@@ -46,7 +48,9 @@
     private val device = UiDevice.getInstance(instrumentation)
     private val testApp = DesktopModeAppHelper(SimpleAppHelper(instrumentation))
 
-    @Rule @JvmField val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
+    @Rule
+    @JvmField
+    val testSetupRule = Utils.testSetupRule(NavBar.MODE_GESTURAL, rotation)
 
     @Before
     fun setup() {
@@ -58,7 +62,11 @@
 
     @Test
     open fun resizeAppWithCornerResize() {
-        testApp.cornerResize(wmHelper, device, DesktopModeAppHelper.Corners.RIGHT_TOP, 50, -50)
+        testApp.cornerResize(wmHelper,
+            device,
+            DesktopModeAppHelper.Corners.RIGHT_TOP,
+            horizontalChange,
+            verticalChange)
     }
 
     @After
diff --git a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt
index c671fbe..b5a6d83 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt
+++ b/libs/WindowManager/Shell/tests/flicker/service/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt
@@ -48,6 +48,8 @@
     fun setup() {
         tapl.setEnableRotation(true)
         tapl.setExpectedRotation(rotation.value)
+        // TODO: b/349075982 - Remove once launcher rotation and checks are stable.
+        tapl.setExpectedRotationCheckEnabled(false)
 
         SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp, rotation)
     }
diff --git a/libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp b/libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp
index 0fe7a16b..35b2f56 100644
--- a/libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp
+++ b/libs/WindowManager/Shell/tests/flicker/splitscreen/Android.bp
@@ -37,17 +37,51 @@
         "src/**/B*.kt",
         "src/**/C*.kt",
         "src/**/D*.kt",
-        "src/**/E*.kt",
     ],
 }
 
 filegroup {
     name: "WMShellFlickerTestsSplitScreenGroup2-src",
     srcs: [
+        "src/**/E*.kt",
+    ],
+}
+
+filegroup {
+    name: "WMShellFlickerTestsSplitScreenGroup3-src",
+    srcs: [
+        "src/**/S*.kt",
+    ],
+}
+
+filegroup {
+    name: "WMShellFlickerTestsSplitScreenGroupOther-src",
+    srcs: [
         "src/**/*.kt",
     ],
 }
 
+java_library {
+    name: "WMShellFlickerTestsSplitScreenBase",
+    srcs: [
+        ":WMShellFlickerTestsSplitScreenBase-src",
+    ],
+    static_libs: [
+        "WMShellFlickerTestsBase",
+        "wm-shell-flicker-utils",
+        "androidx.test.ext.junit",
+        "flickertestapplib",
+        "flickerlib",
+        "flickerlib-helpers",
+        "flickerlib-trace_processor_shell",
+        "platform-test-annotations",
+        "wm-flicker-common-app-helpers",
+        "wm-flicker-common-assertions",
+        "launcher-helper-lib",
+        "launcher-aosp-tapl",
+    ],
+}
+
 android_test {
     name: "WMShellFlickerTestsSplitScreenGroup1",
     defaults: ["WMShellFlickerTestsDefault"],
@@ -56,10 +90,12 @@
     instrumentation_target_package: "com.android.wm.shell.flicker.splitscreen",
     test_config_template: "AndroidTestTemplate.xml",
     srcs: [
-        ":WMShellFlickerTestsSplitScreenBase-src",
         ":WMShellFlickerTestsSplitScreenGroup1-src",
     ],
-    static_libs: ["WMShellFlickerTestsBase"],
+    static_libs: [
+        "WMShellFlickerTestsBase",
+        "WMShellFlickerTestsSplitScreenBase",
+    ],
     data: ["trace_config/*"],
 }
 
@@ -71,12 +107,50 @@
     instrumentation_target_package: "com.android.wm.shell.flicker.splitscreen",
     test_config_template: "AndroidTestTemplate.xml",
     srcs: [
-        ":WMShellFlickerTestsSplitScreenBase-src",
         ":WMShellFlickerTestsSplitScreenGroup2-src",
     ],
+    static_libs: [
+        "WMShellFlickerTestsBase",
+        "WMShellFlickerTestsSplitScreenBase",
+    ],
+    data: ["trace_config/*"],
+}
+
+android_test {
+    name: "WMShellFlickerTestsSplitScreenGroup3",
+    defaults: ["WMShellFlickerTestsDefault"],
+    manifest: "AndroidManifest.xml",
+    package_name: "com.android.wm.shell.flicker.splitscreen",
+    instrumentation_target_package: "com.android.wm.shell.flicker.splitscreen",
+    test_config_template: "AndroidTestTemplate.xml",
+    srcs: [
+        ":WMShellFlickerTestsSplitScreenGroup3-src",
+    ],
+    static_libs: [
+        "WMShellFlickerTestsBase",
+        "WMShellFlickerTestsSplitScreenBase",
+    ],
+    data: ["trace_config/*"],
+}
+
+android_test {
+    name: "WMShellFlickerTestsSplitScreenGroupOther",
+    defaults: ["WMShellFlickerTestsDefault"],
+    manifest: "AndroidManifest.xml",
+    package_name: "com.android.wm.shell.flicker.splitscreen",
+    instrumentation_target_package: "com.android.wm.shell.flicker.splitscreen",
+    test_config_template: "AndroidTestTemplate.xml",
+    srcs: [
+        ":WMShellFlickerTestsSplitScreenGroupOther-src",
+    ],
     exclude_srcs: [
         ":WMShellFlickerTestsSplitScreenGroup1-src",
+        ":WMShellFlickerTestsSplitScreenGroup2-src",
+        ":WMShellFlickerTestsSplitScreenGroup3-src",
     ],
-    static_libs: ["WMShellFlickerTestsBase"],
+    static_libs: [
+        "WMShellFlickerTestsBase",
+        "WMShellFlickerTestsSplitScreenBase",
+    ],
     data: ["trace_config/*"],
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/Android.bp b/libs/WindowManager/Shell/tests/unittest/Android.bp
index 13f95cc..6b69542 100644
--- a/libs/WindowManager/Shell/tests/unittest/Android.bp
+++ b/libs/WindowManager/Shell/tests/unittest/Android.bp
@@ -46,6 +46,7 @@
         "androidx.dynamicanimation_dynamicanimation",
         "dagger2",
         "frameworks-base-testutils",
+        "kotlin-test",
         "kotlinx-coroutines-android",
         "kotlinx-coroutines-core",
         "mockito-kotlin2",
@@ -58,6 +59,7 @@
         "guava-android-testlib",
         "com.android.window.flags.window-aconfig-java",
         "platform-test-annotations",
+        "flag-junit",
     ],
 
     libs: [
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 f9b4108..e91828b 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
@@ -45,6 +45,7 @@
 import static org.mockito.Mockito.verify;
 
 import android.app.ActivityManager.RunningTaskInfo;
+import android.app.TaskInfo;
 import android.content.LocusId;
 import android.content.pm.ParceledListSlice;
 import android.os.Binder;
@@ -63,6 +64,8 @@
 
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.compatui.CompatUIController;
+import com.android.wm.shell.compatui.api.CompatUIInfo;
+import com.android.wm.shell.compatui.impl.CompatUIEvents;
 import com.android.wm.shell.recents.RecentTasksController;
 import com.android.wm.shell.sysui.ShellCommandHandler;
 import com.android.wm.shell.sysui.ShellInit;
@@ -70,6 +73,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
@@ -371,7 +375,7 @@
         mOrganizer.onTaskAppeared(taskInfo1, /* leash= */ null);
 
         // sizeCompatActivity is null if top activity is not in size compat.
-        verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
+        verifyOnCompatInfoChangedInvokedWith(taskInfo1, null /* taskListener */);
 
         // sizeCompatActivity is non-null if top activity is in size compat.
         clearInvocations(mCompatUI);
@@ -381,7 +385,7 @@
         taskInfo2.appCompatTaskInfo.topActivityInSizeCompat = true;
         taskInfo2.isVisible = true;
         mOrganizer.onTaskInfoChanged(taskInfo2);
-        verify(mCompatUI).onCompatInfoChanged(taskInfo2, taskListener);
+        verifyOnCompatInfoChangedInvokedWith(taskInfo2, taskListener);
 
         // Not show size compat UI if task is not visible.
         clearInvocations(mCompatUI);
@@ -391,11 +395,11 @@
         taskInfo3.appCompatTaskInfo.topActivityInSizeCompat = true;
         taskInfo3.isVisible = false;
         mOrganizer.onTaskInfoChanged(taskInfo3);
-        verify(mCompatUI).onCompatInfoChanged(taskInfo3, null /* taskListener */);
+        verifyOnCompatInfoChangedInvokedWith(taskInfo3, null /* taskListener */);
 
         clearInvocations(mCompatUI);
         mOrganizer.onTaskVanished(taskInfo1);
-        verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
+        verifyOnCompatInfoChangedInvokedWith(taskInfo1, null /* taskListener */);
     }
 
     @Test
@@ -410,7 +414,7 @@
 
         // Task listener sent to compat UI is null if top activity isn't eligible for letterbox
         // education.
-        verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
+        verifyOnCompatInfoChangedInvokedWith(taskInfo1, null /* taskListener */);
 
         // Task listener is non-null if top activity is eligible for letterbox education and task
         // is visible.
@@ -421,7 +425,7 @@
         taskInfo2.appCompatTaskInfo.topActivityEligibleForLetterboxEducation = true;
         taskInfo2.isVisible = true;
         mOrganizer.onTaskInfoChanged(taskInfo2);
-        verify(mCompatUI).onCompatInfoChanged(taskInfo2, taskListener);
+        verifyOnCompatInfoChangedInvokedWith(taskInfo2, taskListener);
 
         // Task listener is null if task is invisible.
         clearInvocations(mCompatUI);
@@ -431,11 +435,11 @@
         taskInfo3.appCompatTaskInfo.topActivityEligibleForLetterboxEducation = true;
         taskInfo3.isVisible = false;
         mOrganizer.onTaskInfoChanged(taskInfo3);
-        verify(mCompatUI).onCompatInfoChanged(taskInfo3, null /* taskListener */);
+        verifyOnCompatInfoChangedInvokedWith(taskInfo3, null /* taskListener */);
 
         clearInvocations(mCompatUI);
         mOrganizer.onTaskVanished(taskInfo1);
-        verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
+        verifyOnCompatInfoChangedInvokedWith(taskInfo1, null /* taskListener */);
     }
 
     @Test
@@ -451,7 +455,7 @@
 
         // Task listener sent to compat UI is null if top activity doesn't request a camera
         // compat control.
-        verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
+        verifyOnCompatInfoChangedInvokedWith(taskInfo1, null /* taskListener */);
 
         // Task listener is non-null when request a camera compat control for a visible task.
         clearInvocations(mCompatUI);
@@ -462,7 +466,7 @@
                 CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
         taskInfo2.isVisible = true;
         mOrganizer.onTaskInfoChanged(taskInfo2);
-        verify(mCompatUI).onCompatInfoChanged(taskInfo2, taskListener);
+        verifyOnCompatInfoChangedInvokedWith(taskInfo2, taskListener);
 
         // CompatUIController#onCompatInfoChanged is called when requested state for a camera
         // compat control changes for a visible task.
@@ -474,7 +478,7 @@
                 CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED;
         taskInfo3.isVisible = true;
         mOrganizer.onTaskInfoChanged(taskInfo3);
-        verify(mCompatUI).onCompatInfoChanged(taskInfo3, taskListener);
+        verifyOnCompatInfoChangedInvokedWith(taskInfo3, taskListener);
 
         // CompatUIController#onCompatInfoChanged is called when a top activity goes in size compat
         // mode for a visible task that has a compat control.
@@ -487,7 +491,7 @@
                 CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED;
         taskInfo4.isVisible = true;
         mOrganizer.onTaskInfoChanged(taskInfo4);
-        verify(mCompatUI).onCompatInfoChanged(taskInfo4, taskListener);
+        verifyOnCompatInfoChangedInvokedWith(taskInfo4, taskListener);
 
         // Task linster is null when a camera compat control is dimissed for a visible task.
         clearInvocations(mCompatUI);
@@ -498,7 +502,7 @@
                 CAMERA_COMPAT_CONTROL_DISMISSED;
         taskInfo5.isVisible = true;
         mOrganizer.onTaskInfoChanged(taskInfo5);
-        verify(mCompatUI).onCompatInfoChanged(taskInfo5, null /* taskListener */);
+        verifyOnCompatInfoChangedInvokedWith(taskInfo5, null /* taskListener */);
 
         // Task linster is null when request a camera compat control for a invisible task.
         clearInvocations(mCompatUI);
@@ -509,11 +513,11 @@
                 CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
         taskInfo6.isVisible = false;
         mOrganizer.onTaskInfoChanged(taskInfo6);
-        verify(mCompatUI).onCompatInfoChanged(taskInfo6, null /* taskListener */);
+        verifyOnCompatInfoChangedInvokedWith(taskInfo6, null /* taskListener */);
 
         clearInvocations(mCompatUI);
         mOrganizer.onTaskVanished(taskInfo1);
-        verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
+        verifyOnCompatInfoChangedInvokedWith(taskInfo1, null /* taskListener */);
     }
 
     @Test
@@ -640,7 +644,8 @@
 
         mOrganizer.onTaskAppeared(task1, /* leash= */ null);
 
-        mOrganizer.onSizeCompatRestartButtonClicked(task1.taskId);
+        mOrganizer.onSizeCompatRestartButtonClicked(
+                new CompatUIEvents.SizeCompatRestartButtonClicked(task1.taskId));
 
         verify(mTaskOrganizerController).restartTaskTopActivityProcessIfVisible(task1.token);
     }
@@ -687,6 +692,25 @@
         verify(mRecentTasksController).onTaskRunningInfoChanged(task2);
     }
 
+    @Test
+    public void testTaskVanishedCallback() {
+        RunningTaskInfo task1 = createTaskInfo(/* taskId= */ 1, WINDOWING_MODE_FULLSCREEN);
+        mOrganizer.onTaskAppeared(task1, /* leash= */ null);
+
+        RunningTaskInfo[] vanishedTasks = new RunningTaskInfo[1];
+        ShellTaskOrganizer.TaskVanishedListener listener =
+                new ShellTaskOrganizer.TaskVanishedListener() {
+                    @Override
+                    public void onTaskVanished(RunningTaskInfo taskInfo) {
+                        vanishedTasks[0] = taskInfo;
+                    }
+                };
+        mOrganizer.addTaskVanishedListener(listener);
+        mOrganizer.onTaskVanished(task1);
+
+        assertEquals(vanishedTasks[0], task1);
+    }
+
     private static RunningTaskInfo createTaskInfo(int taskId, int windowingMode) {
         RunningTaskInfo taskInfo = new RunningTaskInfo();
         taskInfo.taskId = taskId;
@@ -694,4 +718,13 @@
         taskInfo.isVisible = true;
         return taskInfo;
     }
+
+    private void verifyOnCompatInfoChangedInvokedWith(TaskInfo taskInfo,
+                                                      ShellTaskOrganizer.TaskListener listener) {
+        final ArgumentCaptor<CompatUIInfo> capture = ArgumentCaptor.forClass(CompatUIInfo.class);
+        verify(mCompatUI).onCompatInfoChanged(capture.capture());
+        final CompatUIInfo captureValue = capture.getValue();
+        assertEquals(captureValue.getTaskInfo(), taskInfo);
+        assertEquals(captureValue.getListener(), listener);
+    }
 }
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 51a20ee..a2df22c 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
@@ -26,7 +26,7 @@
 
 import androidx.test.platform.app.InstrumentationRegistry;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 import org.junit.After;
 import org.junit.Before;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
index bd20c11..55b6bd2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationRunnerTests.java
@@ -20,9 +20,13 @@
 import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
 import static android.window.TransitionInfo.FLAG_IS_BEHIND_STARTING_WINDOW;
 
+import static com.android.wm.shell.activityembedding.ActivityEmbeddingAnimationRunner.calculateParentBounds;
+import static com.android.wm.shell.activityembedding.ActivityEmbeddingAnimationRunner.shouldUseJumpCutForAnimation;
 import static com.android.wm.shell.transition.Transitions.TRANSIT_TASK_FRAGMENT_DRAG_RESIZE;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doNothing;
@@ -32,9 +36,14 @@
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import android.animation.Animator;
+import android.annotation.NonNull;
+import android.graphics.Point;
+import android.graphics.Rect;
 import android.platform.test.annotations.DisableFlags;
 import android.platform.test.annotations.EnableFlags;
 import android.platform.test.flag.junit.SetFlagsRule;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
 import android.window.TransitionInfo;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -130,7 +139,7 @@
     @Test
     public void testInvalidCustomAnimation_disableAnimationOptionsPerChange() {
         final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN, 0)
-                .addChange(createChange(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY))
+                .addChange(createChange(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY, TRANSIT_OPEN))
                 .build();
         info.setAnimationOptions(TransitionInfo.AnimationOptions
                 .makeCustomAnimOptions("packageName", 0 /* enterResId */, 0 /* exitResId */,
@@ -148,7 +157,7 @@
     @Test
     public void testInvalidCustomAnimation_enableAnimationOptionsPerChange() {
         final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN, 0)
-                .addChange(createChange(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY))
+                .addChange(createChange(FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY, TRANSIT_OPEN))
                 .build();
         info.getChanges().getFirst().setAnimationOptions(TransitionInfo.AnimationOptions
                 .makeCustomAnimOptions("packageName", 0 /* enterResId */, 0 /* exitResId */,
@@ -161,4 +170,140 @@
         // An invalid custom animation is equivalent to jump-cut.
         assertEquals(0, animator.getDuration());
     }
+
+    @DisableFlags(Flags.FLAG_ACTIVITY_EMBEDDING_OVERLAY_PRESENTATION_FLAG)
+    @Test
+    public void testCalculateParentBounds_flagDisabled() {
+        final Rect parentBounds = new Rect(0, 0, 2000, 2000);
+        final Rect primaryBounds = new Rect();
+        final Rect secondaryBounds = new Rect();
+        parentBounds.splitVertically(primaryBounds, secondaryBounds);
+
+        final TransitionInfo.Change change = createChange(0 /* flags */);
+        change.setStartAbsBounds(secondaryBounds);
+
+        final TransitionInfo.Change boundsAnimationChange = createChange(0 /* flags */);
+        boundsAnimationChange.setStartAbsBounds(primaryBounds);
+        boundsAnimationChange.setEndAbsBounds(primaryBounds);
+        final Rect actualParentBounds = new Rect();
+
+        calculateParentBounds(change, boundsAnimationChange, actualParentBounds);
+
+        assertEquals(parentBounds, actualParentBounds);
+
+        actualParentBounds.setEmpty();
+
+        boundsAnimationChange.setStartAbsBounds(secondaryBounds);
+        boundsAnimationChange.setEndAbsBounds(primaryBounds);
+
+        calculateParentBounds(boundsAnimationChange, boundsAnimationChange, actualParentBounds);
+
+        assertEquals(parentBounds, actualParentBounds);
+    }
+
+    // TODO(b/243518738): Rewrite with TestParameter
+    @EnableFlags(Flags.FLAG_ACTIVITY_EMBEDDING_OVERLAY_PRESENTATION_FLAG)
+    @Test
+    public void testCalculateParentBounds_flagEnabled() {
+        TransitionInfo.Change change;
+        final TransitionInfo.Change stubChange = createChange(0 /* flags */);
+        final Rect actualParentBounds = new Rect();
+        Rect parentBounds = new Rect(0, 0, 2000, 2000);
+        Rect endAbsBounds = new Rect(0, 0, 2000, 2000);
+        change = prepareChangeForParentBoundsCalculationTest(
+                new Point(0, 0) /* endRelOffset */,
+                endAbsBounds,
+                new Point() /* endParentSize */
+        );
+
+        calculateParentBounds(change, stubChange, actualParentBounds);
+
+        assertTrue("Parent bounds must be empty because end parent size is not set.",
+                actualParentBounds.isEmpty());
+
+        String testString = "Parent start with (0, 0)";
+        change = prepareChangeForParentBoundsCalculationTest(
+                new Point(endAbsBounds.left - parentBounds.left,
+                        endAbsBounds.top - parentBounds.top),
+                endAbsBounds, new Point(parentBounds.width(), parentBounds.height()));
+
+        calculateParentBounds(change, stubChange, actualParentBounds);
+
+        assertEquals(testString + ": Parent bounds must be " + parentBounds, parentBounds,
+                actualParentBounds);
+
+        testString = "Container not start with (0, 0)";
+        parentBounds = new Rect(0, 0, 2000, 2000);
+        endAbsBounds = new Rect(1000, 500, 2000, 1500);
+        change = prepareChangeForParentBoundsCalculationTest(
+                new Point(endAbsBounds.left - parentBounds.left,
+                        endAbsBounds.top - parentBounds.top),
+                endAbsBounds, new Point(parentBounds.width(), parentBounds.height()));
+
+        calculateParentBounds(change, stubChange, actualParentBounds);
+
+        assertEquals(testString + ": Parent bounds must be " + parentBounds, parentBounds,
+                actualParentBounds);
+
+        testString = "Parent container on the right";
+        parentBounds = new Rect(1000, 0, 2000, 2000);
+        endAbsBounds = new Rect(1000, 500, 1500, 1500);
+        change = prepareChangeForParentBoundsCalculationTest(
+                new Point(endAbsBounds.left - parentBounds.left,
+                        endAbsBounds.top - parentBounds.top),
+                endAbsBounds, new Point(parentBounds.width(), parentBounds.height()));
+
+        calculateParentBounds(change, stubChange, actualParentBounds);
+
+        assertEquals(testString + ": Parent bounds must be " + parentBounds, parentBounds,
+                actualParentBounds);
+
+        testString = "Parent container on the bottom";
+        parentBounds = new Rect(0, 1000, 2000, 2000);
+        endAbsBounds = new Rect(500, 1500, 1500, 2000);
+        change = prepareChangeForParentBoundsCalculationTest(
+                new Point(endAbsBounds.left - parentBounds.left,
+                        endAbsBounds.top - parentBounds.top),
+                endAbsBounds, new Point(parentBounds.width(), parentBounds.height()));
+
+        calculateParentBounds(change, stubChange, actualParentBounds);
+
+        assertEquals(testString + ": Parent bounds must be " + parentBounds, parentBounds,
+                actualParentBounds);
+
+        testString = "Parent container in the middle";
+        parentBounds = new Rect(500, 500, 1500, 1500);
+        endAbsBounds = new Rect(1000, 500, 1500, 1000);
+        change = prepareChangeForParentBoundsCalculationTest(
+                new Point(endAbsBounds.left - parentBounds.left,
+                        endAbsBounds.top - parentBounds.top),
+                endAbsBounds, new Point(parentBounds.width(), parentBounds.height()));
+
+        calculateParentBounds(change, stubChange, actualParentBounds);
+
+        assertEquals(testString + ": Parent bounds must be " + parentBounds, parentBounds,
+                actualParentBounds);
+    }
+
+    @Test
+    public void testShouldUseJumpCutForAnimation() {
+        final Animation noopAnimation = new AlphaAnimation(0f, 1f);
+        assertTrue("Animation without duration should use jump cut.",
+                shouldUseJumpCutForAnimation(noopAnimation));
+
+        final Animation alphaAnimation = new AlphaAnimation(0f, 1f);
+        alphaAnimation.setDuration(100);
+        assertFalse("Animation with duration should not use jump cut.",
+                shouldUseJumpCutForAnimation(alphaAnimation));
+    }
+
+    @NonNull
+    private static TransitionInfo.Change prepareChangeForParentBoundsCalculationTest(
+            @NonNull Point endRelOffset, @NonNull Rect endAbsBounds, @NonNull Point endParentSize) {
+        final TransitionInfo.Change change = createChange(0 /* flags */);
+        change.setEndRelOffset(endRelOffset.x, endRelOffset.y);
+        change.setEndAbsBounds(endAbsBounds);
+        change.setEndParentSize(endParentSize.x, endParentSize.y);
+        return change;
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java
index 0b2265d..c18d7ec 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/activityembedding/ActivityEmbeddingAnimationTestBase.java
@@ -16,6 +16,7 @@
 
 package com.android.wm.shell.activityembedding;
 
+import static android.view.WindowManager.TRANSIT_NONE;
 import static android.window.TransitionInfo.FLAG_FILLS_TASK;
 import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
 
@@ -31,6 +32,7 @@
 import android.graphics.Rect;
 import android.os.IBinder;
 import android.view.SurfaceControl;
+import android.view.WindowManager;
 import android.window.TransitionInfo;
 import android.window.WindowContainerToken;
 
@@ -82,11 +84,27 @@
         spyOn(mFinishCallback);
     }
 
-    /** Creates a mock {@link TransitionInfo.Change}. */
+    /**
+     * Creates a mock {@link TransitionInfo.Change}.
+     *
+     * @param flags the {@link TransitionInfo.ChangeFlags} of the change
+     */
     static TransitionInfo.Change createChange(@TransitionInfo.ChangeFlags int flags) {
+        return createChange(flags, TRANSIT_NONE);
+    }
+
+    /**
+     * Creates a mock {@link TransitionInfo.Change}.
+     *
+     * @param flags the {@link TransitionInfo.ChangeFlags} of the change
+     * @param mode the transition mode of the change
+     */
+    static TransitionInfo.Change createChange(@TransitionInfo.ChangeFlags int flags,
+            @WindowManager.TransitionType int mode) {
         TransitionInfo.Change c = new TransitionInfo.Change(mock(WindowContainerToken.class),
                 mock(SurfaceControl.class));
         c.setFlags(flags);
+        c.setMode(mode);
         return c;
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/DividerViewTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/DividerViewTest.java
index 636c632..f5847cc 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/DividerViewTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/DividerViewTest.java
@@ -70,7 +70,7 @@
                 mContext,
                 configuration, mCallbacks);
         splitWindowManager.init(mSplitLayout, new InsetsState(), false /* isRestoring */);
-        mDividerView = spy((DividerView) splitWindowManager.getDividerView());
+        mDividerView = spy(splitWindowManager.getDividerView());
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt
index 4cd2a36..ecaf970 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/AppCompatUtilsTest.kt
@@ -16,8 +16,10 @@
 
 package com.android.wm.shell.compatui
 
+import android.content.ComponentName
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
+import com.android.internal.R
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
 import org.junit.Assert.assertFalse
@@ -34,26 +36,55 @@
 @RunWith(AndroidTestingRunner::class)
 @SmallTest
 class AppCompatUtilsTest : ShellTestCase() {
-
     @Test
-    fun testIsSingleTopActivityTranslucent() {
-        assertTrue(isSingleTopActivityTranslucent(
+    fun testIsTopActivityExemptFromDesktopWindowing_topActivityTransparent() {
+        assertTrue(isTopActivityExemptFromDesktopWindowing(mContext,
             createFreeformTask(/* displayId */ 0)
                     .apply {
                         isTopActivityTransparent = true
                         numActivities = 1
                     }))
-        assertFalse(isSingleTopActivityTranslucent(
+        assertFalse(isTopActivityExemptFromDesktopWindowing(mContext,
             createFreeformTask(/* displayId */ 0)
                     .apply {
                         isTopActivityTransparent = true
                         numActivities = 0
                     }))
-        assertFalse(isSingleTopActivityTranslucent(
+    }
+
+    @Test
+    fun testIsTopActivityExemptFromDesktopWindowing_singleTopActivity() {
+        assertTrue(isTopActivityExemptFromDesktopWindowing(mContext,
+            createFreeformTask(/* displayId */ 0)
+                    .apply {
+                        isTopActivityTransparent = true
+                        numActivities = 1
+                    }))
+        assertFalse(isTopActivityExemptFromDesktopWindowing(mContext,
             createFreeformTask(/* displayId */ 0)
                     .apply {
                         isTopActivityTransparent = false
                         numActivities = 1
                     }))
     }
-}
\ No newline at end of file
+
+    @Test
+    fun testIsTopActivityExemptFromDesktopWindowing__topActivityStyleFloating() {
+        assertFalse(isTopActivityExemptFromDesktopWindowing(mContext,
+            createFreeformTask(/* displayId */ 0)
+                    .apply {
+                        isTopActivityStyleFloating = true
+                    }))
+    }
+
+    @Test
+    fun testIsTopActivityExemptFromDesktopWindowing_systemUiTask() {
+        val systemUIPackageName = context.resources.getString(R.string.config_systemUi)
+        val baseComponent = ComponentName(systemUIPackageName, /* class */ "")
+        assertTrue(isTopActivityExemptFromDesktopWindowing(mContext,
+            createFreeformTask(/* displayId */ 0)
+                    .apply {
+                        baseActivity = baseComponent
+                    }))
+    }
+}
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 9c00864..fc7a777 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
@@ -38,6 +38,9 @@
 import android.app.TaskInfo;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.testing.AndroidTestingRunner;
 import android.view.InsetsSource;
 import android.view.InsetsState;
@@ -45,6 +48,7 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.window.flags.Flags;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.DisplayController;
@@ -55,6 +59,7 @@
 import com.android.wm.shell.common.DockStateReader;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.compatui.api.CompatUIInfo;
 import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.transition.Transitions;
@@ -63,6 +68,7 @@
 
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -82,6 +88,10 @@
     private static final int DISPLAY_ID = 0;
     private static final int TASK_ID = 12;
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule =
+            DeviceFlagsValueProvider.createCheckFlagsRule();
+
     private CompatUIController mController;
     private ShellInit mShellInit;
     @Mock
@@ -168,28 +178,32 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void instantiateController_addInitCallback() {
         verify(mShellInit, times(1)).addInitCallback(any(), any());
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void instantiateController_registerKeyguardChangeListener() {
         verify(mMockShellController, times(1)).addKeyguardChangeListener(any());
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testListenerRegistered() {
         verify(mMockDisplayController).addDisplayWindowListener(mController);
         verify(mMockImeController).addPositionProcessor(mController);
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnCompatInfoChanged() {
         TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
                 CAMERA_COMPAT_CONTROL_HIDDEN);
 
         // Verify that the compat controls are added with non-null task listener.
-        mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
 
         verify(mController).createCompatUiWindowManager(any(), eq(taskInfo), eq(mMockTaskListener));
         verify(mController).createLetterboxEduWindowManager(any(), eq(taskInfo),
@@ -202,7 +216,7 @@
         clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mController);
         taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
                 CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
-        mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
 
         verify(mMockCompatLayout).updateCompatInfo(taskInfo, mMockTaskListener,
                 /* canShow= */ true);
@@ -213,9 +227,9 @@
 
         // Verify that compat controls and letterbox education are removed with null task listener.
         clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mController);
-        mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
+        mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
                 /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN),
-                /* taskListener= */ null);
+                /* taskListener= */ null));
 
         verify(mMockCompatLayout).release();
         verify(mMockLetterboxEduLayout).release();
@@ -223,6 +237,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnCompatInfoChanged_createLayoutReturnsFalse() {
         doReturn(false).when(mMockCompatLayout).createLayout(anyBoolean());
         doReturn(false).when(mMockLetterboxEduLayout).createLayout(anyBoolean());
@@ -230,7 +245,7 @@
 
         TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
                 CAMERA_COMPAT_CONTROL_HIDDEN);
-        mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
 
         verify(mController).createCompatUiWindowManager(any(), eq(taskInfo), eq(mMockTaskListener));
         verify(mController).createLetterboxEduWindowManager(any(), eq(taskInfo),
@@ -240,7 +255,7 @@
 
         // Verify that the layout is created again.
         clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mController);
-        mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
 
         verify(mMockCompatLayout, never()).updateCompatInfo(any(), any(), anyBoolean());
         verify(mMockLetterboxEduLayout, never()).updateCompatInfo(any(), any(), anyBoolean());
@@ -253,6 +268,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnCompatInfoChanged_updateCompatInfoReturnsFalse() {
         doReturn(false).when(mMockCompatLayout).updateCompatInfo(any(), any(), anyBoolean());
         doReturn(false).when(mMockLetterboxEduLayout).updateCompatInfo(any(), any(), anyBoolean());
@@ -260,7 +276,7 @@
 
         TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
                 CAMERA_COMPAT_CONTROL_HIDDEN);
-        mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
 
         verify(mController).createCompatUiWindowManager(any(), eq(taskInfo), eq(mMockTaskListener));
         verify(mController).createLetterboxEduWindowManager(any(), eq(taskInfo),
@@ -270,7 +286,7 @@
 
         clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mMockRestartDialogLayout,
                 mController);
-        mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
 
         verify(mMockCompatLayout).updateCompatInfo(taskInfo, mMockTaskListener,
                 /* canShow= */ true);
@@ -282,7 +298,7 @@
         // Verify that the layout is created again.
         clearInvocations(mMockCompatLayout, mMockLetterboxEduLayout, mMockRestartDialogLayout,
                 mController);
-        mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
 
         verify(mMockCompatLayout, never()).updateCompatInfo(any(), any(), anyBoolean());
         verify(mMockLetterboxEduLayout, never()).updateCompatInfo(any(), any(), anyBoolean());
@@ -296,6 +312,7 @@
 
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnDisplayAdded() {
         mController.onDisplayAdded(DISPLAY_ID);
         mController.onDisplayAdded(DISPLAY_ID + 1);
@@ -305,11 +322,11 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnDisplayRemoved() {
         mController.onDisplayAdded(DISPLAY_ID);
-        mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
-                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN),
-                mMockTaskListener);
+        mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
+                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
 
         mController.onDisplayRemoved(DISPLAY_ID + 1);
 
@@ -328,9 +345,10 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnDisplayConfigurationChanged() {
-        mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
-                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
+        mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
+                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
 
         mController.onDisplayConfigurationChanged(DISPLAY_ID + 1, new Configuration());
 
@@ -346,10 +364,11 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testInsetsChanged() {
         mController.onDisplayAdded(DISPLAY_ID);
-        mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
-                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
+        mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
+                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
         InsetsState insetsState = new InsetsState();
         InsetsSource insetsSource = new InsetsSource(
                 InsetsSource.createId(null, 0, navigationBars()), navigationBars());
@@ -373,9 +392,10 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testChangeLayoutsVisibilityOnImeShowHide() {
-        mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
-                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
+        mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
+                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
 
         // Verify that the restart button is hidden after IME is showing.
         mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ true);
@@ -387,7 +407,7 @@
         // Verify button remains hidden while IME is showing.
         TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
                 CAMERA_COMPAT_CONTROL_HIDDEN);
-        mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
 
         verify(mMockCompatLayout).updateCompatInfo(taskInfo, mMockTaskListener,
                 /* canShow= */ false);
@@ -405,9 +425,10 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testChangeLayoutsVisibilityOnKeyguardShowingChanged() {
-        mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
-                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
+        mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
+                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
 
         // Verify that the restart button is hidden after keyguard becomes showing.
         mController.onKeyguardVisibilityChanged(true, false, false);
@@ -419,7 +440,7 @@
         // Verify button remains hidden while keyguard is showing.
         TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID, /* hasSizeCompat= */ true,
                 CAMERA_COMPAT_CONTROL_HIDDEN);
-        mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
 
         verify(mMockCompatLayout).updateCompatInfo(taskInfo, mMockTaskListener,
                 /* canShow= */ false);
@@ -437,9 +458,10 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testLayoutsRemainHiddenOnKeyguardShowingFalseWhenImeIsShowing() {
-        mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
-                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
+        mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
+                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
 
         mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ true);
         mController.onKeyguardVisibilityChanged(true, false, false);
@@ -466,9 +488,10 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testLayoutsRemainHiddenOnImeHideWhenKeyguardIsShowing() {
-        mController.onCompatInfoChanged(createTaskInfo(DISPLAY_ID, TASK_ID,
-                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener);
+        mController.onCompatInfoChanged(new CompatUIInfo(createTaskInfo(DISPLAY_ID, TASK_ID,
+                /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN), mMockTaskListener));
 
         mController.onImeVisibilityChanged(DISPLAY_ID, /* isShowing= */ true);
         mController.onKeyguardVisibilityChanged(true, false, false);
@@ -495,6 +518,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testRestartLayoutRecreatedIfNeeded() {
         final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
                 /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN);
@@ -502,14 +526,15 @@
                 .needsToBeRecreated(any(TaskInfo.class),
                         any(ShellTaskOrganizer.TaskListener.class));
 
-        mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
-        mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
+        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
 
         verify(mMockRestartDialogLayout, times(2))
                 .createLayout(anyBoolean());
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testRestartLayoutNotRecreatedIfNotNeeded() {
         final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
                 /* hasSizeCompat= */ true, CAMERA_COMPAT_CONTROL_HIDDEN);
@@ -517,14 +542,15 @@
                 .needsToBeRecreated(any(TaskInfo.class),
                         any(ShellTaskOrganizer.TaskListener.class));
 
-        mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
-        mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
+        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
 
         verify(mMockRestartDialogLayout, times(1))
                 .createLayout(anyBoolean());
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateActiveTaskInfo_newTask_visibleAndFocused_updated() {
         // Simulate user aspect ratio button being shown for previous task
         mController.setHasShownUserAspectRatioSettingsButton(true);
@@ -545,6 +571,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateActiveTaskInfo_newTask_notVisibleOrFocused_notUpdated() {
         // Create new task
         final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
@@ -606,6 +633,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateActiveTaskInfo_sameTask_notUpdated() {
         // Create new task
         final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
@@ -634,6 +662,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateActiveTaskInfo_transparentTask_notUpdated() {
         // Create new task
         final TaskInfo taskInfo = createTaskInfo(DISPLAY_ID, TASK_ID,
@@ -674,7 +703,7 @@
                 CAMERA_COMPAT_CONTROL_HIDDEN);
         taskInfo.appCompatTaskInfo.isLetterboxEducationEnabled = false;
 
-        mController.onCompatInfoChanged(taskInfo, mMockTaskListener);
+        mController.onCompatInfoChanged(new CompatUIInfo(taskInfo, mMockTaskListener));
 
         verify(mController, never()).createLetterboxEduWindowManager(any(), eq(taskInfo),
                 eq(mMockTaskListener));
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUILayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUILayoutTest.java
index cd3e8cb..33d69f5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUILayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUILayoutTest.java
@@ -23,6 +23,7 @@
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
@@ -31,6 +32,9 @@
 import android.app.CameraCompatTaskInfo.CameraCompatControlState;
 import android.app.TaskInfo;
 import android.graphics.Rect;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.testing.AndroidTestingRunner;
 import android.util.Pair;
 import android.view.LayoutInflater;
@@ -40,16 +44,20 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.window.flags.Flags;
 import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.compatui.CompatUIController.CompatUIHintsState;
+import com.android.wm.shell.compatui.api.CompatUIEvent;
+import com.android.wm.shell.compatui.impl.CompatUIEvents;
 
 import junit.framework.Assert;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -70,8 +78,12 @@
 
     private static final int TASK_ID = 1;
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule =
+            DeviceFlagsValueProvider.createCheckFlagsRule();
+
     @Mock private SyncTransactionQueue mSyncTransactionQueue;
-    @Mock private CompatUIController.CompatUICallback mCallback;
+    @Mock private Consumer<CompatUIEvent> mCallback;
     @Mock private Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>> mOnRestartButtonClicked;
     @Mock private ShellTaskOrganizer.TaskListener mTaskListener;
     @Mock private SurfaceControlViewHost mViewHost;
@@ -101,6 +113,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnClickForRestartButton() {
         final ImageButton button = mLayout.findViewById(R.id.size_compat_restart_button);
         button.performClick();
@@ -117,6 +130,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnLongClickForRestartButton() {
         doNothing().when(mWindowManager).onRestartButtonLongClicked();
 
@@ -127,6 +141,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnClickForSizeCompatHint() {
         mWindowManager.mHasSizeCompat = true;
         mWindowManager.createLayout(/* canShow= */ true);
@@ -137,6 +152,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateCameraTreatmentButton_treatmentAppliedByDefault() {
         mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED;
         mWindowManager.createLayout(/* canShow= */ true);
@@ -145,16 +161,17 @@
         button.performClick();
 
         verify(mWindowManager).onCameraTreatmentButtonClicked();
-        verify(mCallback).onCameraControlStateUpdated(
-                TASK_ID, CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
+        verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID,
+                CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
 
         button.performClick();
 
-        verify(mCallback).onCameraControlStateUpdated(
-                TASK_ID, CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
+        verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID,
+                CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateCameraTreatmentButton_treatmentSuggestedByDefault() {
         mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
         mWindowManager.createLayout(/* canShow= */ true);
@@ -163,16 +180,17 @@
         button.performClick();
 
         verify(mWindowManager).onCameraTreatmentButtonClicked();
-        verify(mCallback).onCameraControlStateUpdated(
-                TASK_ID, CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
+        verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID,
+                CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
 
         button.performClick();
 
-        verify(mCallback).onCameraControlStateUpdated(
-                TASK_ID, CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
+        verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID,
+                CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnCameraDismissButtonClicked() {
         mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
         mWindowManager.createLayout(/* canShow= */ true);
@@ -181,12 +199,12 @@
         button.performClick();
 
         verify(mWindowManager).onCameraDismissButtonClicked();
-        verify(mCallback).onCameraControlStateUpdated(
-                TASK_ID, CAMERA_COMPAT_CONTROL_DISMISSED);
+        verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID, CAMERA_COMPAT_CONTROL_DISMISSED);
         verify(mLayout).setCameraControlVisibility(/* show */ false);
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnLongClickForCameraTreatmentButton() {
         doNothing().when(mWindowManager).onCameraButtonLongClicked();
 
@@ -198,6 +216,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnLongClickForCameraDismissButton() {
         doNothing().when(mWindowManager).onCameraButtonLongClicked();
 
@@ -208,6 +227,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(Flags.FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnClickForCameraCompatHint() {
         mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
         mWindowManager.createLayout(/* canShow= */ true);
@@ -229,4 +249,15 @@
         taskInfo.configuration.windowConfiguration.setBounds(new Rect(0, 0, 2000, 2000));
         return taskInfo;
     }
+
+    private void verifyOnCameraControlStateUpdatedInvokedWith(int taskId, int state) {
+        final ArgumentCaptor<CompatUIEvent> captureValue = ArgumentCaptor.forClass(
+                CompatUIEvent.class);
+        verify(mCallback).accept(captureValue.capture());
+        final CompatUIEvents.CameraControlStateUpdated compatUIEvent =
+                (CompatUIEvents.CameraControlStateUpdated) captureValue.getValue();
+        Assert.assertEquals((compatUIEvent).getTaskId(), taskId);
+        Assert.assertEquals((compatUIEvent).getState(), state);
+        clearInvocations(mCallback);
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java
index 41a81c1..eb3da8f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIWindowManagerTest.java
@@ -25,6 +25,7 @@
 import static android.view.WindowManager.LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -42,6 +43,9 @@
 import android.app.TaskInfo;
 import android.content.res.Configuration;
 import android.graphics.Rect;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.testing.AndroidTestingRunner;
 import android.util.Pair;
@@ -60,6 +64,8 @@
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.SyncTransactionQueue;
 import com.android.wm.shell.compatui.CompatUIController.CompatUIHintsState;
+import com.android.wm.shell.compatui.api.CompatUIEvent;
+import com.android.wm.shell.compatui.impl.CompatUIEvents;
 
 import junit.framework.Assert;
 
@@ -85,12 +91,16 @@
     @Rule
     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule =
+            DeviceFlagsValueProvider.createCheckFlagsRule();
+
     private static final int TASK_ID = 1;
     private static final int TASK_WIDTH = 2000;
     private static final int TASK_HEIGHT = 2000;
 
     @Mock private SyncTransactionQueue mSyncTransactionQueue;
-    @Mock private CompatUIController.CompatUICallback mCallback;
+    @Mock private Consumer<CompatUIEvent> mCallback;
     @Mock private Consumer<Pair<TaskInfo, ShellTaskOrganizer.TaskListener>> mOnRestartButtonClicked;
     @Mock private ShellTaskOrganizer.TaskListener mTaskListener;
     @Mock private CompatUILayout mLayout;
@@ -129,6 +139,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testCreateSizeCompatButton() {
         // Doesn't create layout if show is false.
         mWindowManager.mHasSizeCompat = true;
@@ -174,6 +185,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testCreateCameraCompatControl() {
         // Doesn't create layout if show is false.
         mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
@@ -212,6 +224,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testRelease() {
         mWindowManager.mHasSizeCompat = true;
         mWindowManager.createLayout(/* canShow= */ true);
@@ -224,6 +237,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateCompatInfo() {
         mWindowManager.mHasSizeCompat = true;
         mWindowManager.createLayout(/* canShow= */ true);
@@ -315,6 +329,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateCompatInfoLayoutNotInflatedYet() {
         mWindowManager.createLayout(/* canShow= */ false);
 
@@ -347,6 +362,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateDisplayLayout() {
         final DisplayInfo displayInfo = new DisplayInfo();
         displayInfo.logicalWidth = 1000;
@@ -366,6 +382,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateDisplayLayoutInsets() {
         final DisplayInfo displayInfo = new DisplayInfo();
         displayInfo.logicalWidth = 1000;
@@ -390,6 +407,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateVisibility() {
         // Create button if it is not created.
         mWindowManager.mLayout = null;
@@ -415,6 +433,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testAttachToParentSurface() {
         final SurfaceControl.Builder b = new SurfaceControl.Builder();
         mWindowManager.attachToParentSurface(b);
@@ -423,37 +442,38 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnCameraDismissButtonClicked() {
         mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
         mWindowManager.createLayout(/* canShow= */ true);
         clearInvocations(mLayout);
         mWindowManager.onCameraDismissButtonClicked();
 
-        verify(mCallback).onCameraControlStateUpdated(TASK_ID, CAMERA_COMPAT_CONTROL_DISMISSED);
+        verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID, CAMERA_COMPAT_CONTROL_DISMISSED);
         verify(mLayout).setCameraControlVisibility(/* show= */ false);
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnCameraTreatmentButtonClicked() {
         mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
         mWindowManager.createLayout(/* canShow= */ true);
         clearInvocations(mLayout);
         mWindowManager.onCameraTreatmentButtonClicked();
 
-        verify(mCallback).onCameraControlStateUpdated(
-                TASK_ID, CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
-        verify(mLayout).updateCameraTreatmentButton(
+        verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID,
                 CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
+        verify(mLayout).updateCameraTreatmentButton(CAMERA_COMPAT_CONTROL_TREATMENT_APPLIED);
 
         mWindowManager.onCameraTreatmentButtonClicked();
 
-        verify(mCallback).onCameraControlStateUpdated(
-                TASK_ID, CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
-        verify(mLayout).updateCameraTreatmentButton(
+        verifyOnCameraControlStateUpdatedInvokedWith(TASK_ID,
                 CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
+        verify(mLayout).updateCameraTreatmentButton(CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED);
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnRestartButtonClicked() {
         mWindowManager.onRestartButtonClicked();
 
@@ -468,8 +488,9 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnRestartButtonLongClicked_showHint() {
-       // Not create hint popup.
+        // Not create hint popup.
         mWindowManager.mHasSizeCompat = true;
         mWindowManager.mCompatUIHintsState.mHasShownSizeCompatHint = true;
         mWindowManager.createLayout(/* canShow= */ true);
@@ -483,6 +504,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnCameraControlLongClicked_showHint() {
        // Not create hint popup.
         mWindowManager.mCameraCompatControlState = CAMERA_COMPAT_CONTROL_TREATMENT_SUGGESTED;
@@ -498,6 +520,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testWhenDockedStateHasChanged_needsToBeRecreated() {
         ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
         newTaskInfo.configuration.uiMode |= Configuration.UI_MODE_TYPE_DESK;
@@ -506,6 +529,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testShouldShowSizeCompatRestartButton() {
         mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_HIDE_SCM_BUTTON);
         doReturn(85).when(mCompatUIConfiguration).getHideSizeCompatRestartButtonTolerance();
@@ -558,4 +582,15 @@
         taskInfo.configuration.smallestScreenWidthDp = LARGE_SCREEN_SMALLEST_SCREEN_WIDTH_DP;
         return taskInfo;
     }
+
+    private void verifyOnCameraControlStateUpdatedInvokedWith(int taskId, int state) {
+        final ArgumentCaptor<CompatUIEvent> captureValue = ArgumentCaptor.forClass(
+                CompatUIEvent.class);
+        verify(mCallback).accept(captureValue.capture());
+        final CompatUIEvents.CameraControlStateUpdated compatUIEvent =
+                (CompatUIEvents.CameraControlStateUpdated) captureValue.getValue();
+        Assert.assertEquals((compatUIEvent).getTaskId(), taskId);
+        Assert.assertEquals((compatUIEvent).getState(), state);
+        clearInvocations(mCallback);
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduDialogLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduDialogLayoutTest.java
index 172c263..e8191db 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduDialogLayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduDialogLayoutTest.java
@@ -16,12 +16,17 @@
 
 package com.android.wm.shell.compatui;
 
+import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.testing.AndroidTestingRunner;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -32,6 +37,7 @@
 import com.android.wm.shell.ShellTestCase;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -54,6 +60,10 @@
     private View mDismissButton;
     private View mDialogContainer;
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule =
+            DeviceFlagsValueProvider.createCheckFlagsRule();
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -66,6 +76,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnFinishInflate() {
         assertEquals(mLayout.getDialogContainerView(),
                 mLayout.findViewById(R.id.letterbox_education_dialog_container));
@@ -76,6 +87,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnDismissButtonClicked() {
         assertTrue(mDismissButton.performClick());
 
@@ -83,6 +95,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnBackgroundClicked() {
         assertTrue(mLayout.performClick());
 
@@ -90,6 +103,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnDialogContainerClicked() {
         assertTrue(mDialogContainer.performClick());
 
@@ -97,6 +111,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testSetDismissOnClickListenerNull() {
         mLayout.setDismissOnClickListener(null);
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java
index a60a1cb..b5664ac 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java
@@ -19,6 +19,7 @@
 import static android.content.res.Configuration.UI_MODE_NIGHT_YES;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -37,6 +38,9 @@
 import android.app.TaskInfo;
 import android.graphics.Insets;
 import android.graphics.Rect;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.testing.AndroidTestingRunner;
 import android.util.Pair;
 import android.view.DisplayCutout;
@@ -61,6 +65,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -116,6 +121,10 @@
     private CompatUIConfiguration mCompatUIConfiguration;
     private TestShellExecutor mExecutor;
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule =
+            DeviceFlagsValueProvider.createCheckFlagsRule();
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -153,6 +162,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testCreateLayout_notEligible_doesNotCreateLayout() {
         LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ false);
 
@@ -162,6 +172,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testCreateLayout_eligibleAndDocked_doesNotCreateLayout() {
         LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */
                 true, /* isDocked */ true);
@@ -172,6 +183,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testCreateLayout_taskBarEducationIsShowing_doesNotCreateLayout() {
         LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true,
                 USER_ID_1, /* isTaskbarEduShowing= */ true);
@@ -182,6 +194,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testCreateLayout_canShowFalse_returnsTrueButDoesNotCreateLayout() {
         LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
 
@@ -192,6 +205,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testCreateLayout_canShowTrue_createsLayoutCorrectly() {
         LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
 
@@ -238,6 +252,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testCreateLayout_alreadyShownToUser_createsLayoutForOtherUserOnly() {
         LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true,
                 USER_ID_1, /* isTaskbarEduShowing= */ false);
@@ -271,6 +286,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testCreateLayout_windowManagerReleasedBeforeTransitionsIsIdle_doesNotStartAnim() {
         LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
 
@@ -288,6 +304,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateCompatInfo_updatesLayoutCorrectly() {
         LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
 
@@ -316,6 +333,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateCompatInfo_notEligibleUntilUpdate_createsLayoutAfterUpdate() {
         LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ false);
 
@@ -329,6 +347,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateCompatInfo_canShowFalse_doesNothing() {
         LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
 
@@ -343,6 +362,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateDisplayLayout_updatesLayoutCorrectly() {
         LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
 
@@ -364,6 +384,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testRelease_animationIsCancelled() {
         LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
 
@@ -374,6 +395,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testDeviceThemeChange_educationDialogUnseen_recreated() {
         LetterboxEduWindowManager windowManager = createWindowManager(/* eligible= */ true);
         ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduLayoutTest.java
index 4f71b83..0da14d6 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduLayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduLayoutTest.java
@@ -16,6 +16,8 @@
 
 package com.android.wm.shell.compatui;
 
+import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
 
@@ -23,6 +25,9 @@
 import static org.mockito.Mockito.verify;
 
 import android.app.TaskInfo;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.LayoutInflater;
@@ -34,6 +39,7 @@
 import com.android.wm.shell.ShellTestCase;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -62,6 +68,10 @@
     @Mock
     private TaskInfo mTaskInfo;
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule =
+            DeviceFlagsValueProvider.createCheckFlagsRule();
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -74,6 +84,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnFinishInflate() {
         assertNotNull(mMoveUpButton);
         assertNotNull(mMoveDownButton);
@@ -82,6 +93,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void handleVisibility_educationNotEnabled_buttonsAreHidden() {
         mLayout.handleVisibility(/* horizontalEnabled */ false, /* verticalEnabled */
                 false, /* letterboxVerticalPosition */
@@ -94,6 +106,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void handleVisibility_horizontalEducationEnableduiConfigurationIsUpdated() {
         mLayout.handleVisibility(/* horizontalEnabled */ true, /* verticalEnabled */
                 false, /* letterboxVerticalPosition */ -1, /* letterboxHorizontalPosition */
@@ -106,6 +119,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void handleVisibility_verticalEducationEnabled_uiConfigurationIsUpdated() {
         mLayout.handleVisibility(/* horizontalEnabled */ false, /* verticalEnabled */
                 true, /* letterboxVerticalPosition */ 0, /* letterboxHorizontalPosition */
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduWindowManagerTest.java
index 5867a85..eafb414 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/ReachabilityEduWindowManagerTest.java
@@ -16,12 +16,17 @@
 
 package com.android.wm.shell.compatui;
 
+import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 
 import android.app.ActivityManager;
 import android.app.TaskInfo;
 import android.content.res.Configuration;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.testing.AndroidTestingRunner;
 
 import androidx.test.filters.SmallTest;
@@ -35,6 +40,7 @@
 import junit.framework.Assert;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -65,6 +71,10 @@
     private TaskInfo mTaskInfo;
     private ReachabilityEduWindowManager mWindowManager;
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule =
+            DeviceFlagsValueProvider.createCheckFlagsRule();
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -80,6 +90,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testCreateLayout_notEligible_doesNotCreateLayout() {
         assertFalse(mWindowManager.createLayout(/* canShow= */ true));
 
@@ -87,6 +98,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testWhenDockedStateHasChanged_needsToBeRecreated() {
         ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
         newTaskInfo.configuration.uiMode =
@@ -97,6 +109,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testWhenDarkLightThemeHasChanged_needsToBeRecreated() {
         ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
         mTaskInfo.configuration.uiMode =
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogLayoutTest.java
index e2dcdb0..6b0c5dd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogLayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogLayoutTest.java
@@ -16,6 +16,8 @@
 
 package com.android.wm.shell.compatui;
 
+import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -23,6 +25,9 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.testing.AndroidTestingRunner;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -34,6 +39,7 @@
 import com.android.wm.shell.ShellTestCase;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -60,6 +66,10 @@
     private View mDialogContainer;
     private CheckBox mDontRepeatCheckBox;
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule =
+            DeviceFlagsValueProvider.createCheckFlagsRule();
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -76,6 +86,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnFinishInflate() {
         assertEquals(mLayout.getDialogContainerView(),
                 mLayout.findViewById(R.id.letterbox_restart_dialog_container));
@@ -86,6 +97,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnDismissButtonClicked() {
         assertTrue(mDismissButton.performClick());
 
@@ -93,6 +105,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnRestartButtonClickedWithoutCheckbox() {
         mDontRepeatCheckBox.setChecked(false);
         assertTrue(mRestartButton.performClick());
@@ -101,6 +114,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnRestartButtonClickedWithCheckbox() {
         mDontRepeatCheckBox.setChecked(true);
         assertTrue(mRestartButton.performClick());
@@ -109,6 +123,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnBackgroundClickedDoesntDismiss() {
         assertFalse(mLayout.performClick());
 
@@ -116,6 +131,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnDialogContainerClicked() {
         assertTrue(mDialogContainer.performClick());
 
@@ -124,6 +140,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testSetDismissOnClickListenerNull() {
         mLayout.setDismissOnClickListener(null);
 
@@ -135,6 +152,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testSetRestartOnClickListenerNull() {
         mLayout.setRestartOnClickListener(null);
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogWindowManagerTest.java
index 9f109a1..cfeef90 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/RestartDialogWindowManagerTest.java
@@ -16,9 +16,14 @@
 
 package com.android.wm.shell.compatui;
 
+import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
+
 import android.app.ActivityManager;
 import android.app.TaskInfo;
 import android.content.res.Configuration;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.testing.AndroidTestingRunner;
 import android.util.Pair;
 
@@ -33,6 +38,7 @@
 import junit.framework.Assert;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -60,6 +66,10 @@
     private RestartDialogWindowManager mWindowManager;
     private TaskInfo mTaskInfo;
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule =
+            DeviceFlagsValueProvider.createCheckFlagsRule();
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -76,6 +86,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testWhenDockedStateHasChanged_needsToBeRecreated() {
         ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
         newTaskInfo.configuration.uiMode =
@@ -86,6 +97,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testWhenDarkLightThemeHasChanged_needsToBeRecreated() {
         ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
         mTaskInfo.configuration.uiMode =
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java
index 0231612..3fa21ce 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsLayoutTest.java
@@ -19,6 +19,7 @@
 import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_CONTROL_HIDDEN;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
 
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
@@ -28,6 +29,9 @@
 import android.app.CameraCompatTaskInfo.CameraCompatControlState;
 import android.app.TaskInfo;
 import android.content.ComponentName;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.testing.AndroidTestingRunner;
 import android.util.Pair;
 import android.view.LayoutInflater;
@@ -47,6 +51,7 @@
 import junit.framework.Assert;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -86,6 +91,10 @@
     private UserAspectRatioSettingsLayout mLayout;
     private TaskInfo mTaskInfo;
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule =
+            DeviceFlagsValueProvider.createCheckFlagsRule();
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -107,6 +116,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnClickForUserAspectRatioSettingsButton() {
         final ImageButton button = mLayout.findViewById(R.id.user_aspect_ratio_settings_button);
         button.performClick();
@@ -123,6 +133,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnLongClickForUserAspectRatioButton() {
         doNothing().when(mWindowManager).onUserAspectRatioSettingsButtonLongClicked();
 
@@ -133,6 +144,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnClickForUserAspectRatioSettingsHint() {
         mWindowManager.mHasUserAspectRatioSettingsButton = true;
         mWindowManager.createLayout(/* canShow= */ true);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java
index 94e168e..9f288cc 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/UserAspectRatioSettingsWindowManagerTest.java
@@ -22,6 +22,7 @@
 import static android.view.WindowInsets.Type.navigationBars;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.window.flags.Flags.FLAG_APP_COMPAT_UI_FRAMEWORK;
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -39,6 +40,9 @@
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.graphics.Rect;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
 import android.util.Pair;
@@ -61,6 +65,7 @@
 import junit.framework.Assert;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -107,6 +112,10 @@
 
     private TestShellExecutor mExecutor;
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule =
+            DeviceFlagsValueProvider.createCheckFlagsRule();
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -138,6 +147,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testCreateUserAspectRatioButton() {
         // Doesn't create layout if show is false.
         mWindowManager.mHasUserAspectRatioSettingsButton = true;
@@ -178,6 +188,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testRelease() {
         mWindowManager.mHasUserAspectRatioSettingsButton = true;
         mWindowManager.createLayout(/* canShow= */ true);
@@ -190,6 +201,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateCompatInfo() {
         mWindowManager.mHasUserAspectRatioSettingsButton = true;
         mWindowManager.createLayout(/* canShow= */ true);
@@ -242,6 +254,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateCompatInfoLayoutNotInflatedYet() {
         mWindowManager.mHasUserAspectRatioSettingsButton = true;
         mWindowManager.createLayout(/* canShow= */ false);
@@ -267,6 +280,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testEligibleButtonHiddenIfLetterboxBoundsEqualToStableBounds() {
         TaskInfo taskInfo = createTaskInfo(/* eligibleForUserAspectRatioButton= */
                 true, /* topActivityBoundsLetterboxed */ true, ACTION_MAIN, CATEGORY_LAUNCHER);
@@ -292,6 +306,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUserFullscreenOverrideEnabled_buttonAlwaysShown() {
         TaskInfo taskInfo = createTaskInfo(/* eligibleForUserAspectRatioButton= */
                 true, /* topActivityBoundsLetterboxed */ true, ACTION_MAIN, CATEGORY_LAUNCHER);
@@ -310,6 +325,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateDisplayLayout() {
         final DisplayInfo displayInfo = new DisplayInfo();
         displayInfo.logicalWidth = 1000;
@@ -329,6 +345,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateDisplayLayoutInsets() {
         final DisplayInfo displayInfo = new DisplayInfo();
         displayInfo.logicalWidth = 1000;
@@ -353,6 +370,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testUpdateVisibility() {
         // Create button if it is not created.
         mWindowManager.removeLayout();
@@ -378,6 +396,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testLayoutHasUserAspectRatioSettingsButton() {
         clearInvocations(mWindowManager);
         spyOn(mWindowManager);
@@ -411,6 +430,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testAttachToParentSurface() {
         final SurfaceControl.Builder b = new SurfaceControl.Builder();
         mWindowManager.attachToParentSurface(b);
@@ -419,6 +439,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnUserAspectRatioButtonClicked() {
         mWindowManager.onUserAspectRatioSettingsButtonClicked();
 
@@ -433,6 +454,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testOnUserAspectRatioButtonLongClicked_showHint() {
        // Not create hint popup.
         mWindowManager.mHasUserAspectRatioSettingsButton = true;
@@ -448,6 +470,7 @@
     }
 
     @Test
+    @RequiresFlagsDisabled(FLAG_APP_COMPAT_UI_FRAMEWORK)
     public void testWhenDockedStateHasChanged_needsToBeRecreated() {
         ActivityManager.RunningTaskInfo newTaskInfo = new ActivityManager.RunningTaskInfo();
         newTaskInfo.configuration.uiMode |= Configuration.UI_MODE_TYPE_DESK;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt
index fb03f20..d459639 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt
@@ -19,6 +19,8 @@
 import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
 import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
 import android.content.Context
+import android.graphics.Point
+import android.graphics.Rect
 import android.os.IBinder
 import android.testing.AndroidTestingRunner
 import android.view.SurfaceControl
@@ -36,11 +38,12 @@
 import android.window.TransitionInfo.Change
 import android.window.WindowContainerToken
 import androidx.test.filters.SmallTest
-import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
 import com.android.modules.utils.testing.ExtendedMockitoRule
+import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.common.ShellExecutor
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.EnterReason
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ExitReason
+import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.TaskUpdate
 import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_ENTER_DESKTOP_FROM_APP_FROM_OVERVIEW
 import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_ENTER_DESKTOP_FROM_APP_HANDLE_MENU_BUTTON
 import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_ENTER_DESKTOP_FROM_KEYBOARD_SHORTCUT
@@ -49,26 +52,27 @@
 import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_DESKTOP_MODE_KEYBOARD_SHORTCUT
 import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_DESKTOP_MODE_TASK_DRAG
 import com.android.wm.shell.desktopmode.DesktopModeTransitionTypes.TRANSIT_EXIT_DESKTOP_MODE_UNKNOWN
-import com.android.wm.shell.shared.DesktopModeStatus
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
 import com.android.wm.shell.sysui.ShellInit
 import com.android.wm.shell.transition.TransitionInfoBuilder
 import com.android.wm.shell.transition.Transitions
-import com.google.common.truth.Truth.assertThat
+import junit.framework.Assert.assertNotNull
+import junit.framework.Assert.assertNull
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
-import org.mockito.Mock
-import org.mockito.Mockito
-import org.mockito.Mockito.mock
-import org.mockito.Mockito.verify
 import org.mockito.kotlin.any
 import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
 import org.mockito.kotlin.never
 import org.mockito.kotlin.same
+import org.mockito.kotlin.spy
 import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
 import org.mockito.kotlin.verifyZeroInteractions
+import org.mockito.kotlin.whenever
 
 /**
  * Test class for {@link DesktopModeLoggerTransitionObserver}
@@ -77,20 +81,17 @@
  */
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
-class DesktopModeLoggerTransitionObserverTest {
+class DesktopModeLoggerTransitionObserverTest : ShellTestCase() {
 
   @JvmField
   @Rule
   val extendedMockitoRule =
-      ExtendedMockitoRule.Builder(this)
-          .mockStatic(DesktopModeEventLogger::class.java)
-          .mockStatic(DesktopModeStatus::class.java)
-          .build()!!
+      ExtendedMockitoRule.Builder(this).mockStatic(DesktopModeStatus::class.java).build()!!
 
-  @Mock lateinit var testExecutor: ShellExecutor
-  @Mock private lateinit var mockShellInit: ShellInit
-  @Mock private lateinit var transitions: Transitions
-  @Mock private lateinit var context: Context
+  private val testExecutor = mock<ShellExecutor>()
+  private val mockShellInit = mock<ShellInit>()
+  private val transitions = mock<Transitions>()
+  private val context = mock<Context>()
 
   private lateinit var transitionObserver: DesktopModeLoggerTransitionObserver
   private lateinit var shellInit: ShellInit
@@ -98,9 +99,9 @@
 
   @Before
   fun setup() {
-    doReturn(true).`when` { DesktopModeStatus.canEnterDesktopMode(any()) }
-    shellInit = Mockito.spy(ShellInit(testExecutor))
-    desktopModeEventLogger = mock(DesktopModeEventLogger::class.java)
+    whenever(DesktopModeStatus.canEnterDesktopMode(any())).thenReturn(true)
+    shellInit = spy(ShellInit(testExecutor))
+    desktopModeEventLogger = mock<DesktopModeEventLogger>()
 
     transitionObserver =
         DesktopModeLoggerTransitionObserver(
@@ -121,7 +122,7 @@
 
   @Test
   fun transitOpen_notFreeformWindow_doesNotLogTaskAddedOrSessionEnter() {
-    val change = createChange(TRANSIT_OPEN, createTaskInfo(1, WINDOWING_MODE_FULLSCREEN))
+    val change = createChange(TRANSIT_OPEN, createTaskInfo(WINDOWING_MODE_FULLSCREEN))
     val transitionInfo = TransitionInfoBuilder(TRANSIT_OPEN, 0).addChange(change).build()
 
     callOnTransitionReady(transitionInfo)
@@ -132,22 +133,17 @@
 
   @Test
   fun transitOpen_logTaskAddedAndEnterReasonAppFreeformIntent() {
-    val change = createChange(TRANSIT_OPEN, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    val change = createChange(TRANSIT_OPEN, createTaskInfo(WINDOWING_MODE_FREEFORM))
     val transitionInfo = TransitionInfoBuilder(TRANSIT_OPEN, 0).addChange(change).build()
 
     callOnTransitionReady(transitionInfo)
-    val sessionId = transitionObserver.getLoggerSessionId()
 
-    assertThat(sessionId).isNotNull()
-    verify(desktopModeEventLogger, times(1))
-        .logSessionEnter(eq(sessionId!!), eq(EnterReason.APP_FREEFORM_INTENT))
-    verify(desktopModeEventLogger, times(1)).logTaskAdded(eq(sessionId), any())
-    verifyZeroInteractions(desktopModeEventLogger)
+    verifyTaskAddedAndEnterLogging(EnterReason.APP_FREEFORM_INTENT, DEFAULT_TASK_UPDATE)
   }
 
   @Test
   fun transitEndDragToDesktop_logTaskAddedAndEnterReasonAppHandleDrag() {
-    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(WINDOWING_MODE_FREEFORM))
     // task change is finalised when drag ends
     val transitionInfo =
         TransitionInfoBuilder(Transitions.TRANSIT_DESKTOP_MODE_END_DRAG_TO_DESKTOP, 0)
@@ -155,82 +151,57 @@
             .build()
 
     callOnTransitionReady(transitionInfo)
-    val sessionId = transitionObserver.getLoggerSessionId()
 
-    assertThat(sessionId).isNotNull()
-    verify(desktopModeEventLogger, times(1))
-        .logSessionEnter(eq(sessionId!!), eq(EnterReason.APP_HANDLE_DRAG))
-    verify(desktopModeEventLogger, times(1)).logTaskAdded(eq(sessionId), any())
-    verifyZeroInteractions(desktopModeEventLogger)
+    verifyTaskAddedAndEnterLogging(EnterReason.APP_HANDLE_DRAG, DEFAULT_TASK_UPDATE)
   }
 
   @Test
   fun transitEnterDesktopByButtonTap_logTaskAddedAndEnterReasonButtonTap() {
-    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(WINDOWING_MODE_FREEFORM))
     val transitionInfo =
         TransitionInfoBuilder(TRANSIT_ENTER_DESKTOP_FROM_APP_HANDLE_MENU_BUTTON, 0)
             .addChange(change)
             .build()
 
     callOnTransitionReady(transitionInfo)
-    val sessionId = transitionObserver.getLoggerSessionId()
 
-    assertThat(sessionId).isNotNull()
-    verify(desktopModeEventLogger, times(1))
-        .logSessionEnter(eq(sessionId!!), eq(EnterReason.APP_HANDLE_MENU_BUTTON))
-    verify(desktopModeEventLogger, times(1)).logTaskAdded(eq(sessionId), any())
-    verifyZeroInteractions(desktopModeEventLogger)
+    verifyTaskAddedAndEnterLogging(EnterReason.APP_HANDLE_MENU_BUTTON, DEFAULT_TASK_UPDATE)
   }
 
   @Test
   fun transitEnterDesktopFromAppFromOverview_logTaskAddedAndEnterReasonAppFromOverview() {
-    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(WINDOWING_MODE_FREEFORM))
     val transitionInfo =
         TransitionInfoBuilder(TRANSIT_ENTER_DESKTOP_FROM_APP_FROM_OVERVIEW, 0)
             .addChange(change)
             .build()
 
     callOnTransitionReady(transitionInfo)
-    val sessionId = transitionObserver.getLoggerSessionId()
 
-    assertThat(sessionId).isNotNull()
-    verify(desktopModeEventLogger, times(1))
-        .logSessionEnter(eq(sessionId!!), eq(EnterReason.APP_FROM_OVERVIEW))
-    verify(desktopModeEventLogger, times(1)).logTaskAdded(eq(sessionId), any())
-    verifyZeroInteractions(desktopModeEventLogger)
+    verifyTaskAddedAndEnterLogging(EnterReason.APP_FROM_OVERVIEW, DEFAULT_TASK_UPDATE)
   }
 
   @Test
   fun transitEnterDesktopFromKeyboardShortcut_logTaskAddedAndEnterReasonKeyboardShortcut() {
-    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(WINDOWING_MODE_FREEFORM))
     val transitionInfo =
         TransitionInfoBuilder(TRANSIT_ENTER_DESKTOP_FROM_KEYBOARD_SHORTCUT, 0)
             .addChange(change)
             .build()
 
     callOnTransitionReady(transitionInfo)
-    val sessionId = transitionObserver.getLoggerSessionId()
 
-    assertThat(sessionId).isNotNull()
-    verify(desktopModeEventLogger, times(1))
-        .logSessionEnter(eq(sessionId!!), eq(EnterReason.KEYBOARD_SHORTCUT_ENTER))
-    verify(desktopModeEventLogger, times(1)).logTaskAdded(eq(sessionId), any())
-    verifyZeroInteractions(desktopModeEventLogger)
+    verifyTaskAddedAndEnterLogging(EnterReason.KEYBOARD_SHORTCUT_ENTER, DEFAULT_TASK_UPDATE)
   }
 
   @Test
   fun transitToFront_logTaskAddedAndEnterReasonOverview() {
-    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(WINDOWING_MODE_FREEFORM))
     val transitionInfo = TransitionInfoBuilder(TRANSIT_TO_FRONT, 0).addChange(change).build()
 
     callOnTransitionReady(transitionInfo)
-    val sessionId = transitionObserver.getLoggerSessionId()
 
-    assertThat(sessionId).isNotNull()
-    verify(desktopModeEventLogger, times(1))
-        .logSessionEnter(eq(sessionId!!), eq(EnterReason.OVERVIEW))
-    verify(desktopModeEventLogger, times(1)).logTaskAdded(eq(sessionId), any())
-    verifyZeroInteractions(desktopModeEventLogger)
+    verifyTaskAddedAndEnterLogging(EnterReason.OVERVIEW, DEFAULT_TASK_UPDATE)
   }
 
   @Test
@@ -238,35 +209,29 @@
     // previous exit to overview transition
     val previousSessionId = 1
     // add a freeform task
-    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    val previousTaskInfo = createTaskInfo(WINDOWING_MODE_FREEFORM)
+    transitionObserver.addTaskInfosToCachedMap(previousTaskInfo)
     transitionObserver.setLoggerSessionId(previousSessionId)
-    val previousChange = createChange(TRANSIT_TO_BACK, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
     val previousTransitionInfo =
         TransitionInfoBuilder(TRANSIT_TO_FRONT, TRANSIT_FLAG_IS_RECENTS)
-            .addChange(previousChange)
+            .addChange(createChange(TRANSIT_TO_BACK, previousTaskInfo))
             .build()
 
     callOnTransitionReady(previousTransitionInfo)
 
-    verify(desktopModeEventLogger, times(1)).logTaskRemoved(eq(previousSessionId), any())
-    verify(desktopModeEventLogger, times(1))
-        .logSessionExit(eq(previousSessionId), eq(ExitReason.RETURN_HOME_OR_OVERVIEW))
+    verifyTaskRemovedAndExitLogging(
+        previousSessionId, ExitReason.RETURN_HOME_OR_OVERVIEW, DEFAULT_TASK_UPDATE)
 
     // Enter desktop mode from cancelled recents has no transition. Enter is detected on the
     // next transition involving freeform windows
 
     // TRANSIT_TO_FRONT
-    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(WINDOWING_MODE_FREEFORM))
     val transitionInfo = TransitionInfoBuilder(TRANSIT_TO_FRONT, 0).addChange(change).build()
 
     callOnTransitionReady(transitionInfo)
-    val sessionId = transitionObserver.getLoggerSessionId()
 
-    assertThat(sessionId).isNotNull()
-    verify(desktopModeEventLogger, times(1))
-        .logSessionEnter(eq(sessionId!!), eq(EnterReason.OVERVIEW))
-    verify(desktopModeEventLogger, times(1)).logTaskAdded(eq(sessionId), any())
-    verifyZeroInteractions(desktopModeEventLogger)
+    verifyTaskAddedAndEnterLogging(EnterReason.OVERVIEW, DEFAULT_TASK_UPDATE)
   }
 
   @Test
@@ -274,35 +239,29 @@
     // previous exit to overview transition
     val previousSessionId = 1
     // add a freeform task
-    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    val previousTaskInfo = createTaskInfo(WINDOWING_MODE_FREEFORM)
+    transitionObserver.addTaskInfosToCachedMap(previousTaskInfo)
     transitionObserver.setLoggerSessionId(previousSessionId)
-    val previousChange = createChange(TRANSIT_TO_BACK, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
     val previousTransitionInfo =
         TransitionInfoBuilder(TRANSIT_TO_FRONT, TRANSIT_FLAG_IS_RECENTS)
-            .addChange(previousChange)
+            .addChange(createChange(TRANSIT_TO_BACK, previousTaskInfo))
             .build()
 
     callOnTransitionReady(previousTransitionInfo)
 
-    verify(desktopModeEventLogger, times(1)).logTaskRemoved(eq(previousSessionId), any())
-    verify(desktopModeEventLogger, times(1))
-        .logSessionExit(eq(previousSessionId), eq(ExitReason.RETURN_HOME_OR_OVERVIEW))
+    verifyTaskRemovedAndExitLogging(
+        previousSessionId, ExitReason.RETURN_HOME_OR_OVERVIEW, DEFAULT_TASK_UPDATE)
 
     // Enter desktop mode from cancelled recents has no transition. Enter is detected on the
     // next transition involving freeform windows
 
     // TRANSIT_CHANGE
-    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(WINDOWING_MODE_FREEFORM))
     val transitionInfo = TransitionInfoBuilder(TRANSIT_CHANGE, 0).addChange(change).build()
 
     callOnTransitionReady(transitionInfo)
-    val sessionId = transitionObserver.getLoggerSessionId()
 
-    assertThat(sessionId).isNotNull()
-    verify(desktopModeEventLogger, times(1))
-        .logSessionEnter(eq(sessionId!!), eq(EnterReason.OVERVIEW))
-    verify(desktopModeEventLogger, times(1)).logTaskAdded(eq(sessionId), any())
-    verifyZeroInteractions(desktopModeEventLogger)
+    verifyTaskAddedAndEnterLogging(EnterReason.OVERVIEW, DEFAULT_TASK_UPDATE)
   }
 
   @Test
@@ -310,35 +269,29 @@
     // previous exit to overview transition
     val previousSessionId = 1
     // add a freeform task
-    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    val previousTaskInfo = createTaskInfo(WINDOWING_MODE_FREEFORM)
+    transitionObserver.addTaskInfosToCachedMap(previousTaskInfo)
     transitionObserver.setLoggerSessionId(previousSessionId)
-    val previousChange = createChange(TRANSIT_TO_BACK, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
     val previousTransitionInfo =
         TransitionInfoBuilder(TRANSIT_TO_FRONT, TRANSIT_FLAG_IS_RECENTS)
-            .addChange(previousChange)
+            .addChange(createChange(TRANSIT_TO_BACK, previousTaskInfo))
             .build()
 
     callOnTransitionReady(previousTransitionInfo)
 
-    verify(desktopModeEventLogger, times(1)).logTaskRemoved(eq(previousSessionId), any())
-    verify(desktopModeEventLogger, times(1))
-        .logSessionExit(eq(previousSessionId), eq(ExitReason.RETURN_HOME_OR_OVERVIEW))
+    verifyTaskRemovedAndExitLogging(
+        previousSessionId, ExitReason.RETURN_HOME_OR_OVERVIEW, DEFAULT_TASK_UPDATE)
 
     // Enter desktop mode from cancelled recents has no transition. Enter is detected on the
     // next transition involving freeform windows
 
     // TRANSIT_OPEN
-    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(WINDOWING_MODE_FREEFORM))
     val transitionInfo = TransitionInfoBuilder(TRANSIT_OPEN, 0).addChange(change).build()
 
     callOnTransitionReady(transitionInfo)
-    val sessionId = transitionObserver.getLoggerSessionId()
 
-    assertThat(sessionId).isNotNull()
-    verify(desktopModeEventLogger, times(1))
-        .logSessionEnter(eq(sessionId!!), eq(EnterReason.OVERVIEW))
-    verify(desktopModeEventLogger, times(1)).logTaskAdded(eq(sessionId), any())
-    verifyZeroInteractions(desktopModeEventLogger)
+    verifyTaskAddedAndEnterLogging(EnterReason.OVERVIEW, DEFAULT_TASK_UPDATE)
   }
 
   @Test
@@ -349,286 +302,389 @@
     // previous exit to overview transition
     val previousSessionId = 1
     // add a freeform task
-    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    val previousTaskInfo = createTaskInfo(WINDOWING_MODE_FREEFORM)
+    transitionObserver.addTaskInfosToCachedMap(previousTaskInfo)
     transitionObserver.setLoggerSessionId(previousSessionId)
-    val previousChange = createChange(TRANSIT_TO_BACK, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
     val previousTransitionInfo =
-      TransitionInfoBuilder(TRANSIT_TO_FRONT, TRANSIT_FLAG_IS_RECENTS)
-              .addChange(previousChange)
-              .build()
+        TransitionInfoBuilder(TRANSIT_TO_FRONT, TRANSIT_FLAG_IS_RECENTS)
+            .addChange(createChange(TRANSIT_TO_BACK, previousTaskInfo))
+            .build()
 
     callOnTransitionReady(previousTransitionInfo)
 
-    verify(desktopModeEventLogger, times(1)).logTaskRemoved(eq(previousSessionId), any())
-    verify(desktopModeEventLogger, times(1))
-            .logSessionExit(eq(previousSessionId), eq(ExitReason.RETURN_HOME_OR_OVERVIEW))
+    verifyTaskRemovedAndExitLogging(
+        previousSessionId, ExitReason.RETURN_HOME_OR_OVERVIEW, DEFAULT_TASK_UPDATE)
 
     // TRANSIT_ENTER_DESKTOP_FROM_APP_FROM_OVERVIEW
-    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(WINDOWING_MODE_FREEFORM))
     val transitionInfo =
-      TransitionInfoBuilder(TRANSIT_ENTER_DESKTOP_FROM_APP_FROM_OVERVIEW, 0)
-              .addChange(change)
-              .build()
+        TransitionInfoBuilder(TRANSIT_ENTER_DESKTOP_FROM_APP_FROM_OVERVIEW, 0)
+            .addChange(change)
+            .build()
 
     callOnTransitionReady(transitionInfo)
-    val sessionId = transitionObserver.getLoggerSessionId()
 
-    assertThat(sessionId).isNotNull()
-    verify(desktopModeEventLogger, times(1))
-            .logSessionEnter(eq(sessionId!!), eq(EnterReason.APP_FROM_OVERVIEW))
-    verify(desktopModeEventLogger, times(1)).logTaskAdded(eq(sessionId), any())
-    verifyZeroInteractions(desktopModeEventLogger)
+    verifyTaskAddedAndEnterLogging(EnterReason.APP_FROM_OVERVIEW, DEFAULT_TASK_UPDATE)
   }
 
   @Test
   fun transitEnterDesktopFromUnknown_logTaskAddedAndEnterReasonUnknown() {
-    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(WINDOWING_MODE_FREEFORM))
     val transitionInfo =
         TransitionInfoBuilder(TRANSIT_ENTER_DESKTOP_FROM_UNKNOWN, 0).addChange(change).build()
 
     callOnTransitionReady(transitionInfo)
-    val sessionId = transitionObserver.getLoggerSessionId()
 
-    assertThat(sessionId).isNotNull()
-    verify(desktopModeEventLogger, times(1))
-        .logSessionEnter(eq(sessionId!!), eq(EnterReason.UNKNOWN_ENTER))
-    verify(desktopModeEventLogger, times(1)).logTaskAdded(eq(sessionId), any())
-    verifyZeroInteractions(desktopModeEventLogger)
+    verifyTaskAddedAndEnterLogging(EnterReason.UNKNOWN_ENTER, DEFAULT_TASK_UPDATE)
   }
 
   @Test
   fun transitWake_logTaskAddedAndEnterReasonScreenOn() {
-    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(WINDOWING_MODE_FREEFORM))
     val transitionInfo = TransitionInfoBuilder(TRANSIT_WAKE, 0).addChange(change).build()
 
     callOnTransitionReady(transitionInfo)
-    val sessionId = transitionObserver.getLoggerSessionId()
 
-    assertThat(sessionId).isNotNull()
-    verify(desktopModeEventLogger, times(1))
-        .logSessionEnter(eq(sessionId!!), eq(EnterReason.SCREEN_ON))
-    verify(desktopModeEventLogger, times(1)).logTaskAdded(eq(sessionId), any())
-    verifyZeroInteractions(desktopModeEventLogger)
+    verifyTaskAddedAndEnterLogging(EnterReason.SCREEN_ON, DEFAULT_TASK_UPDATE)
   }
 
   @Test
-  fun transitSleep_logTaskAddedAndExitReasonScreenOff_sessionIdNull() {
+  fun transitSleep_logTaskRemovedAndExitReasonScreenOff_sessionIdNull() {
     val sessionId = 1
     // add a freeform task
-    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(WINDOWING_MODE_FREEFORM))
     transitionObserver.setLoggerSessionId(sessionId)
 
     val transitionInfo = TransitionInfoBuilder(TRANSIT_SLEEP).build()
     callOnTransitionReady(transitionInfo)
 
-    verify(desktopModeEventLogger, times(1)).logTaskRemoved(eq(sessionId), any())
-    verify(desktopModeEventLogger, times(1))
-        .logSessionExit(eq(sessionId), eq(ExitReason.SCREEN_OFF))
-    verifyZeroInteractions(desktopModeEventLogger)
-    assertThat(transitionObserver.getLoggerSessionId()).isNull()
+    verifyTaskRemovedAndExitLogging(sessionId, ExitReason.SCREEN_OFF, DEFAULT_TASK_UPDATE)
   }
 
   @Test
   fun transitExitDesktopTaskDrag_logTaskRemovedAndExitReasonDragToExit_sessionIdNull() {
     val sessionId = 1
     // add a freeform task
-    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(WINDOWING_MODE_FREEFORM))
     transitionObserver.setLoggerSessionId(sessionId)
 
     // window mode changing from FREEFORM to FULLSCREEN
-    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FULLSCREEN))
+    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(WINDOWING_MODE_FULLSCREEN))
     val transitionInfo =
         TransitionInfoBuilder(TRANSIT_EXIT_DESKTOP_MODE_TASK_DRAG).addChange(change).build()
     callOnTransitionReady(transitionInfo)
 
-    verify(desktopModeEventLogger, times(1)).logTaskRemoved(eq(sessionId), any())
-    verify(desktopModeEventLogger, times(1))
-        .logSessionExit(eq(sessionId), eq(ExitReason.DRAG_TO_EXIT))
-    verifyZeroInteractions(desktopModeEventLogger)
-    assertThat(transitionObserver.getLoggerSessionId()).isNull()
+    verifyTaskRemovedAndExitLogging(sessionId, ExitReason.DRAG_TO_EXIT, DEFAULT_TASK_UPDATE)
   }
 
   @Test
   fun transitExitDesktopAppHandleButton_logTaskRemovedAndExitReasonButton_sessionIdNull() {
     val sessionId = 1
     // add a freeform task
-    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(WINDOWING_MODE_FREEFORM))
     transitionObserver.setLoggerSessionId(sessionId)
 
     // window mode changing from FREEFORM to FULLSCREEN
-    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FULLSCREEN))
+    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(WINDOWING_MODE_FULLSCREEN))
     val transitionInfo =
         TransitionInfoBuilder(TRANSIT_EXIT_DESKTOP_MODE_HANDLE_MENU_BUTTON)
             .addChange(change)
             .build()
     callOnTransitionReady(transitionInfo)
 
-    verify(desktopModeEventLogger, times(1)).logTaskRemoved(eq(sessionId), any())
-    verify(desktopModeEventLogger, times(1))
-        .logSessionExit(eq(sessionId), eq(ExitReason.APP_HANDLE_MENU_BUTTON_EXIT))
-    verifyZeroInteractions(desktopModeEventLogger)
-    assertThat(transitionObserver.getLoggerSessionId()).isNull()
+    verifyTaskRemovedAndExitLogging(
+        sessionId, ExitReason.APP_HANDLE_MENU_BUTTON_EXIT, DEFAULT_TASK_UPDATE)
   }
 
   @Test
   fun transitExitDesktopUsingKeyboard_logTaskRemovedAndExitReasonKeyboard_sessionIdNull() {
     val sessionId = 1
     // add a freeform task
-    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(WINDOWING_MODE_FREEFORM))
     transitionObserver.setLoggerSessionId(sessionId)
 
     // window mode changing from FREEFORM to FULLSCREEN
-    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FULLSCREEN))
+    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(WINDOWING_MODE_FULLSCREEN))
     val transitionInfo =
         TransitionInfoBuilder(TRANSIT_EXIT_DESKTOP_MODE_KEYBOARD_SHORTCUT).addChange(change).build()
     callOnTransitionReady(transitionInfo)
 
-    verify(desktopModeEventLogger, times(1)).logTaskRemoved(eq(sessionId), any())
-    verify(desktopModeEventLogger, times(1))
-        .logSessionExit(eq(sessionId), eq(ExitReason.KEYBOARD_SHORTCUT_EXIT))
-    verifyZeroInteractions(desktopModeEventLogger)
-    assertThat(transitionObserver.getLoggerSessionId()).isNull()
+    verifyTaskRemovedAndExitLogging(
+        sessionId, ExitReason.KEYBOARD_SHORTCUT_EXIT, DEFAULT_TASK_UPDATE)
   }
 
   @Test
   fun transitExitDesktopUnknown_logTaskRemovedAndExitReasonUnknown_sessionIdNull() {
     val sessionId = 1
     // add a freeform task
-    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(WINDOWING_MODE_FREEFORM))
     transitionObserver.setLoggerSessionId(sessionId)
 
     // window mode changing from FREEFORM to FULLSCREEN
-    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(1, WINDOWING_MODE_FULLSCREEN))
+    val change = createChange(TRANSIT_TO_FRONT, createTaskInfo(WINDOWING_MODE_FULLSCREEN))
     val transitionInfo =
         TransitionInfoBuilder(TRANSIT_EXIT_DESKTOP_MODE_UNKNOWN).addChange(change).build()
     callOnTransitionReady(transitionInfo)
 
-    verify(desktopModeEventLogger, times(1)).logTaskRemoved(eq(sessionId), any())
-    verify(desktopModeEventLogger, times(1))
-        .logSessionExit(eq(sessionId), eq(ExitReason.UNKNOWN_EXIT))
-    verifyZeroInteractions(desktopModeEventLogger)
-    assertThat(transitionObserver.getLoggerSessionId()).isNull()
+    verifyTaskRemovedAndExitLogging(sessionId, ExitReason.UNKNOWN_EXIT, DEFAULT_TASK_UPDATE)
   }
 
   @Test
   fun transitToFrontWithFlagRecents_logTaskRemovedAndExitReasonOverview_sessionIdNull() {
     val sessionId = 1
     // add a freeform task
-    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(WINDOWING_MODE_FREEFORM))
     transitionObserver.setLoggerSessionId(sessionId)
 
     // recents transition
-    val change = createChange(TRANSIT_TO_BACK, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    val change = createChange(TRANSIT_TO_BACK, createTaskInfo(WINDOWING_MODE_FREEFORM))
     val transitionInfo =
         TransitionInfoBuilder(TRANSIT_TO_FRONT, TRANSIT_FLAG_IS_RECENTS).addChange(change).build()
     callOnTransitionReady(transitionInfo)
 
-    verify(desktopModeEventLogger, times(1)).logTaskRemoved(eq(sessionId), any())
-    verify(desktopModeEventLogger, times(1))
-        .logSessionExit(eq(sessionId), eq(ExitReason.RETURN_HOME_OR_OVERVIEW))
-    verifyZeroInteractions(desktopModeEventLogger)
-    assertThat(transitionObserver.getLoggerSessionId()).isNull()
+    verifyTaskRemovedAndExitLogging(
+        sessionId, ExitReason.RETURN_HOME_OR_OVERVIEW, DEFAULT_TASK_UPDATE)
   }
 
   @Test
   fun transitClose_logTaskRemovedAndExitReasonTaskFinished_sessionIdNull() {
     val sessionId = 1
     // add a freeform task
-    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(WINDOWING_MODE_FREEFORM))
     transitionObserver.setLoggerSessionId(sessionId)
 
     // task closing
-    val change = createChange(TRANSIT_CLOSE, createTaskInfo(1, WINDOWING_MODE_FULLSCREEN))
+    val change = createChange(TRANSIT_CLOSE, createTaskInfo(WINDOWING_MODE_FULLSCREEN))
     val transitionInfo = TransitionInfoBuilder(TRANSIT_CLOSE).addChange(change).build()
     callOnTransitionReady(transitionInfo)
 
-    verify(desktopModeEventLogger, times(1)).logTaskRemoved(eq(sessionId), any())
-    verify(desktopModeEventLogger, times(1))
-        .logSessionExit(eq(sessionId), eq(ExitReason.TASK_FINISHED))
-    verifyZeroInteractions(desktopModeEventLogger)
-    assertThat(transitionObserver.getLoggerSessionId()).isNull()
+    verifyTaskRemovedAndExitLogging(sessionId, ExitReason.TASK_FINISHED, DEFAULT_TASK_UPDATE)
   }
 
   @Test
   fun sessionExitByRecents_cancelledAnimation_sessionRestored() {
     val sessionId = 1
     // add a freeform task to an existing session
-    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    val taskInfo = createTaskInfo(WINDOWING_MODE_FREEFORM)
+    transitionObserver.addTaskInfosToCachedMap(taskInfo)
     transitionObserver.setLoggerSessionId(sessionId)
 
     // recents transition sent freeform window to back
-    val change = createChange(TRANSIT_TO_BACK, createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    val change = createChange(TRANSIT_TO_BACK, taskInfo)
     val transitionInfo1 =
         TransitionInfoBuilder(TRANSIT_TO_FRONT, TRANSIT_FLAG_IS_RECENTS).addChange(change).build()
     callOnTransitionReady(transitionInfo1)
-    verify(desktopModeEventLogger, times(1)).logTaskRemoved(eq(sessionId), any())
-    verify(desktopModeEventLogger, times(1))
-        .logSessionExit(eq(sessionId), eq(ExitReason.RETURN_HOME_OR_OVERVIEW))
-    assertThat(transitionObserver.getLoggerSessionId()).isNull()
+
+    verifyTaskRemovedAndExitLogging(
+        sessionId, ExitReason.RETURN_HOME_OR_OVERVIEW, DEFAULT_TASK_UPDATE)
 
     val transitionInfo2 = TransitionInfoBuilder(TRANSIT_NONE).build()
     callOnTransitionReady(transitionInfo2)
 
-    verify(desktopModeEventLogger, times(1)).logSessionEnter(any(), any())
-    verify(desktopModeEventLogger, times(1)).logTaskAdded(any(), any())
+    verifyTaskAddedAndEnterLogging(EnterReason.OVERVIEW, DEFAULT_TASK_UPDATE)
   }
 
   @Test
   fun sessionAlreadyStarted_newFreeformTaskAdded_logsTaskAdded() {
     val sessionId = 1
     // add an existing freeform task
-    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(1, WINDOWING_MODE_FREEFORM))
+    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(WINDOWING_MODE_FREEFORM))
     transitionObserver.setLoggerSessionId(sessionId)
 
     // new freeform task added
-    val change = createChange(TRANSIT_OPEN, createTaskInfo(2, WINDOWING_MODE_FREEFORM))
+    val change = createChange(TRANSIT_OPEN, createTaskInfo(WINDOWING_MODE_FREEFORM, id = 2))
     val transitionInfo = TransitionInfoBuilder(TRANSIT_OPEN, 0).addChange(change).build()
     callOnTransitionReady(transitionInfo)
 
-    verify(desktopModeEventLogger, times(1)).logTaskAdded(eq(sessionId), any())
+    verify(desktopModeEventLogger, times(1))
+        .logTaskAdded(eq(sessionId), eq(DEFAULT_TASK_UPDATE.copy(instanceId = 2)))
     verify(desktopModeEventLogger, never()).logSessionEnter(any(), any())
   }
 
   @Test
+  fun sessionAlreadyStarted_taskPositionChanged_logsTaskUpdate() {
+    val sessionId = 1
+    // add an existing freeform task
+    val taskInfo = createTaskInfo(WINDOWING_MODE_FREEFORM)
+    transitionObserver.addTaskInfosToCachedMap(taskInfo)
+    transitionObserver.setLoggerSessionId(sessionId)
+
+    // task position changed
+    val newTaskInfo = createTaskInfo(WINDOWING_MODE_FREEFORM, taskX = DEFAULT_TASK_X + 100)
+    val transitionInfo =
+        TransitionInfoBuilder(TRANSIT_CHANGE, 0)
+            .addChange(createChange(TRANSIT_CHANGE, newTaskInfo))
+            .build()
+    callOnTransitionReady(transitionInfo)
+
+    verify(desktopModeEventLogger, times(1))
+        .logTaskInfoChanged(
+            eq(sessionId), eq(DEFAULT_TASK_UPDATE.copy(taskX = DEFAULT_TASK_X + 100)))
+    verifyZeroInteractions(desktopModeEventLogger)
+  }
+
+  @Test
+  fun sessionAlreadyStarted_taskResized_logsTaskUpdate() {
+    val sessionId = 1
+    // add an existing freeform task
+    val taskInfo = createTaskInfo(WINDOWING_MODE_FREEFORM)
+    transitionObserver.addTaskInfosToCachedMap(taskInfo)
+    transitionObserver.setLoggerSessionId(sessionId)
+
+    // task resized
+    val newTaskInfo =
+        createTaskInfo(
+            WINDOWING_MODE_FREEFORM,
+            taskWidth = DEFAULT_TASK_WIDTH + 100,
+            taskHeight = DEFAULT_TASK_HEIGHT - 100)
+    val transitionInfo =
+        TransitionInfoBuilder(TRANSIT_CHANGE, 0)
+            .addChange(createChange(TRANSIT_CHANGE, newTaskInfo))
+            .build()
+    callOnTransitionReady(transitionInfo)
+
+    verify(desktopModeEventLogger, times(1))
+        .logTaskInfoChanged(
+            eq(sessionId),
+            eq(
+                DEFAULT_TASK_UPDATE.copy(
+                    taskWidth = DEFAULT_TASK_WIDTH + 100, taskHeight = DEFAULT_TASK_HEIGHT - 100)))
+    verifyZeroInteractions(desktopModeEventLogger)
+  }
+
+  @Test
+  fun sessionAlreadyStarted_multipleTasksUpdated_logsTaskUpdateForCorrectTask() {
+    val sessionId = 1
+    // add 2 existing freeform task
+    val taskInfo1 = createTaskInfo(WINDOWING_MODE_FREEFORM)
+    val taskInfo2 = createTaskInfo(WINDOWING_MODE_FREEFORM, id = 2)
+    transitionObserver.addTaskInfosToCachedMap(taskInfo1)
+    transitionObserver.addTaskInfosToCachedMap(taskInfo2)
+    transitionObserver.setLoggerSessionId(sessionId)
+
+    // task 1 position update
+    val newTaskInfo1 = createTaskInfo(WINDOWING_MODE_FREEFORM, taskX = DEFAULT_TASK_X + 100)
+    val transitionInfo1 =
+        TransitionInfoBuilder(TRANSIT_CHANGE, 0)
+            .addChange(createChange(TRANSIT_CHANGE, newTaskInfo1))
+            .build()
+    callOnTransitionReady(transitionInfo1)
+
+    verify(desktopModeEventLogger, times(1))
+        .logTaskInfoChanged(
+            eq(sessionId), eq(DEFAULT_TASK_UPDATE.copy(taskX = DEFAULT_TASK_X + 100)))
+    verifyZeroInteractions(desktopModeEventLogger)
+
+    // task 2 resize
+    val newTaskInfo2 =
+        createTaskInfo(
+            WINDOWING_MODE_FREEFORM,
+            id = 2,
+            taskWidth = DEFAULT_TASK_WIDTH + 100,
+            taskHeight = DEFAULT_TASK_HEIGHT - 100)
+    val transitionInfo2 =
+        TransitionInfoBuilder(TRANSIT_CHANGE, 0)
+            .addChange(createChange(TRANSIT_CHANGE, newTaskInfo2))
+            .build()
+
+    callOnTransitionReady(transitionInfo2)
+
+    verify(desktopModeEventLogger, times(1))
+        .logTaskInfoChanged(
+            eq(sessionId),
+            eq(
+                DEFAULT_TASK_UPDATE.copy(
+                    instanceId = 2,
+                    taskWidth = DEFAULT_TASK_WIDTH + 100,
+                    taskHeight = DEFAULT_TASK_HEIGHT - 100)))
+    verifyZeroInteractions(desktopModeEventLogger)
+  }
+
+  @Test
   fun sessionAlreadyStarted_freeformTaskRemoved_logsTaskRemoved() {
     val sessionId = 1
     // add two existing freeform tasks
-    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(1, WINDOWING_MODE_FREEFORM))
-    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(2, WINDOWING_MODE_FREEFORM))
+    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(WINDOWING_MODE_FREEFORM))
+    transitionObserver.addTaskInfosToCachedMap(createTaskInfo(WINDOWING_MODE_FREEFORM, id = 2))
     transitionObserver.setLoggerSessionId(sessionId)
 
-    // new freeform task added
-    val change = createChange(TRANSIT_CLOSE, createTaskInfo(2, WINDOWING_MODE_FREEFORM))
+    // new freeform task closed
+    val change = createChange(TRANSIT_CLOSE, createTaskInfo(WINDOWING_MODE_FREEFORM, id = 2))
     val transitionInfo = TransitionInfoBuilder(TRANSIT_CLOSE, 0).addChange(change).build()
     callOnTransitionReady(transitionInfo)
 
-    verify(desktopModeEventLogger, times(1)).logTaskRemoved(eq(sessionId), any())
+    verify(desktopModeEventLogger, times(1))
+        .logTaskRemoved(eq(sessionId), eq(DEFAULT_TASK_UPDATE.copy(instanceId = 2)))
     verify(desktopModeEventLogger, never()).logSessionExit(any(), any())
   }
 
   /** Simulate calling the onTransitionReady() method */
   private fun callOnTransitionReady(transitionInfo: TransitionInfo) {
-    val transition = mock(IBinder::class.java)
-    val startT = mock(SurfaceControl.Transaction::class.java)
-    val finishT = mock(SurfaceControl.Transaction::class.java)
+    val transition = mock<IBinder>()
+    val startT = mock<SurfaceControl.Transaction>()
+    val finishT = mock<SurfaceControl.Transaction>()
 
     transitionObserver.onTransitionReady(transition, transitionInfo, startT, finishT)
   }
 
-  companion object {
-    fun createTaskInfo(taskId: Int, windowMode: Int): ActivityManager.RunningTaskInfo {
-      val taskInfo = ActivityManager.RunningTaskInfo()
-      taskInfo.taskId = taskId
-      taskInfo.configuration.windowConfiguration.windowingMode = windowMode
+  private fun verifyTaskAddedAndEnterLogging(enterReason: EnterReason, taskUpdate: TaskUpdate) {
+    val sessionId = transitionObserver.getLoggerSessionId()
+    assertNotNull(sessionId)
+    verify(desktopModeEventLogger, times(1)).logSessionEnter(eq(sessionId!!), eq(enterReason))
+    verify(desktopModeEventLogger, times(1)).logTaskAdded(eq(sessionId), eq(taskUpdate))
+    verifyZeroInteractions(desktopModeEventLogger)
+  }
 
-      return taskInfo
-    }
+  private fun verifyTaskRemovedAndExitLogging(
+      sessionId: Int,
+      exitReason: ExitReason,
+      taskUpdate: TaskUpdate
+  ) {
+    verify(desktopModeEventLogger, times(1)).logTaskRemoved(eq(sessionId), eq(taskUpdate))
+    verify(desktopModeEventLogger, times(1)).logSessionExit(eq(sessionId), eq(exitReason))
+    verifyZeroInteractions(desktopModeEventLogger)
+    assertNull(transitionObserver.getLoggerSessionId())
+  }
+
+  private companion object {
+    const val DEFAULT_TASK_ID = 1
+    const val DEFAULT_TASK_UID = 2
+    const val DEFAULT_TASK_HEIGHT = 100
+    const val DEFAULT_TASK_WIDTH = 200
+    const val DEFAULT_TASK_X = 30
+    const val DEFAULT_TASK_Y = 70
+    val DEFAULT_TASK_UPDATE =
+        TaskUpdate(
+            DEFAULT_TASK_ID,
+            DEFAULT_TASK_UID,
+            DEFAULT_TASK_HEIGHT,
+            DEFAULT_TASK_WIDTH,
+            DEFAULT_TASK_X,
+            DEFAULT_TASK_Y,
+        )
+
+    fun createTaskInfo(
+        windowMode: Int,
+        id: Int = DEFAULT_TASK_ID,
+        uid: Int = DEFAULT_TASK_UID,
+        taskHeight: Int = DEFAULT_TASK_HEIGHT,
+        taskWidth: Int = DEFAULT_TASK_WIDTH,
+        taskX: Int = DEFAULT_TASK_X,
+        taskY: Int = DEFAULT_TASK_Y,
+    ) =
+        ActivityManager.RunningTaskInfo().apply {
+          taskId = id
+          userId = uid
+          configuration.windowConfiguration.apply {
+            windowingMode = windowMode
+            positionInParent = Point(taskX, taskY)
+            bounds.set(Rect(taskX, taskY, taskX + taskWidth, taskY + taskHeight))
+          }
+        }
 
     fun createChange(mode: Int, taskInfo: ActivityManager.RunningTaskInfo): Change {
       val change =
-          Change(
-              WindowContainerToken(mock(IWindowContainerToken::class.java)),
-              mock(SurfaceControl::class.java))
+          Change(WindowContainerToken(mock<IWindowContainerToken>()), mock<SurfaceControl>())
       change.mode = mode
       change.taskInfo = taskInfo
       return change
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
index 310ccc2..6612aee 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
@@ -119,54 +119,91 @@
     }
 
     @Test
-    fun isOnlyActiveTask_noActiveTasks() {
-        // Not an active task
-        assertThat(repo.isOnlyActiveTask(1)).isFalse()
+    fun isOnlyVisibleNonClosingTask_noTasks() {
+        // No visible tasks
+        assertThat(repo.isOnlyVisibleNonClosingTask(1)).isFalse()
+        assertThat(repo.isClosingTask(1)).isFalse()
     }
 
     @Test
-    fun isOnlyActiveTask_singleActiveTask() {
-        repo.addActiveTask(DEFAULT_DISPLAY, 1)
-        // The only active task
-        assertThat(repo.isActiveTask(1)).isTrue()
-        assertThat(repo.isOnlyActiveTask(1)).isTrue()
-        // Not an active task
-        assertThat(repo.isActiveTask(99)).isFalse()
-        assertThat(repo.isOnlyActiveTask(99)).isFalse()
+    fun isOnlyVisibleNonClosingTask_singleVisibleNonClosingTask() {
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
+
+        // The only visible task
+        assertThat(repo.isVisibleTask(1)).isTrue()
+        assertThat(repo.isClosingTask(1)).isFalse()
+        assertThat(repo.isOnlyVisibleNonClosingTask(1)).isTrue()
+        // Not a visible task
+        assertThat(repo.isVisibleTask(99)).isFalse()
+        assertThat(repo.isClosingTask(99)).isFalse()
+        assertThat(repo.isOnlyVisibleNonClosingTask(99)).isFalse()
     }
 
     @Test
-    fun isOnlyActiveTask_multipleActiveTasks() {
-        repo.addActiveTask(DEFAULT_DISPLAY, 1)
-        repo.addActiveTask(DEFAULT_DISPLAY, 2)
+    fun isOnlyVisibleNonClosingTask_singleVisibleClosingTask() {
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
+        repo.addClosingTask(DEFAULT_DISPLAY, 1)
+
+        // A visible task that's closing
+        assertThat(repo.isVisibleTask(1)).isTrue()
+        assertThat(repo.isClosingTask(1)).isTrue()
+        assertThat(repo.isOnlyVisibleNonClosingTask(1)).isFalse()
+        // Not a visible task
+        assertThat(repo.isVisibleTask(99)).isFalse()
+        assertThat(repo.isOnlyVisibleNonClosingTask(99)).isFalse()
+    }
+
+    @Test
+    fun isOnlyVisibleNonClosingTask_singleVisibleMinimizedTask() {
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
+        repo.minimizeTask(DEFAULT_DISPLAY, 1)
+
+        // The visible task that's closing
+        assertThat(repo.isVisibleTask(1)).isTrue()
+        assertThat(repo.isMinimizedTask(1)).isTrue()
+        assertThat(repo.isOnlyVisibleNonClosingTask(1)).isFalse()
+        // Not a visible task
+        assertThat(repo.isVisibleTask(99)).isFalse()
+        assertThat(repo.isOnlyVisibleNonClosingTask(99)).isFalse()
+    }
+
+    @Test
+    fun isOnlyVisibleNonClosingTask_multipleVisibleNonClosingTasks() {
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = true)
+
         // Not the only task
-        assertThat(repo.isActiveTask(1)).isTrue()
-        assertThat(repo.isOnlyActiveTask(1)).isFalse()
+        assertThat(repo.isVisibleTask(1)).isTrue()
+        assertThat(repo.isClosingTask(1)).isFalse()
+        assertThat(repo.isOnlyVisibleNonClosingTask(1)).isFalse()
         // Not the only task
-        assertThat(repo.isActiveTask(2)).isTrue()
-        assertThat(repo.isOnlyActiveTask(2)).isFalse()
-        // Not an active task
-        assertThat(repo.isActiveTask(99)).isFalse()
-        assertThat(repo.isOnlyActiveTask(99)).isFalse()
+        assertThat(repo.isVisibleTask(2)).isTrue()
+        assertThat(repo.isClosingTask(2)).isFalse()
+        assertThat(repo.isOnlyVisibleNonClosingTask(2)).isFalse()
+        // Not a visible task
+        assertThat(repo.isVisibleTask(99)).isFalse()
+        assertThat(repo.isClosingTask(99)).isFalse()
+        assertThat(repo.isOnlyVisibleNonClosingTask(99)).isFalse()
     }
 
     @Test
-    fun isOnlyActiveTask_multipleDisplays() {
-        repo.addActiveTask(DEFAULT_DISPLAY, 1)
-        repo.addActiveTask(DEFAULT_DISPLAY, 2)
-        repo.addActiveTask(SECOND_DISPLAY, 3)
+    fun isOnlyVisibleNonClosingTask_multipleDisplays() {
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = true)
+        repo.updateVisibleFreeformTasks(SECOND_DISPLAY, taskId = 3, visible = true)
+
         // Not the only task on DEFAULT_DISPLAY
-        assertThat(repo.isActiveTask(1)).isTrue()
-        assertThat(repo.isOnlyActiveTask(1)).isFalse()
+        assertThat(repo.isVisibleTask(1)).isTrue()
+        assertThat(repo.isOnlyVisibleNonClosingTask(1)).isFalse()
         // Not the only task on DEFAULT_DISPLAY
-        assertThat(repo.isActiveTask(2)).isTrue()
-        assertThat(repo.isOnlyActiveTask(2)).isFalse()
-        // The only active task on SECOND_DISPLAY
-        assertThat(repo.isActiveTask(3)).isTrue()
-        assertThat(repo.isOnlyActiveTask(3)).isTrue()
-        // Not an active task
-        assertThat(repo.isActiveTask(99)).isFalse()
-        assertThat(repo.isOnlyActiveTask(99)).isFalse()
+        assertThat(repo.isVisibleTask(2)).isTrue()
+        assertThat(repo.isOnlyVisibleNonClosingTask(2)).isFalse()
+        // The only visible task on SECOND_DISPLAY
+        assertThat(repo.isVisibleTask(3)).isTrue()
+        assertThat(repo.isOnlyVisibleNonClosingTask(3)).isTrue()
+        // Not a visible task
+        assertThat(repo.isVisibleTask(99)).isFalse()
+        assertThat(repo.isOnlyVisibleNonClosingTask(99)).isFalse()
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index e17f7f2..6cabbf9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -18,7 +18,9 @@
 
 import android.app.ActivityManager.RecentTaskInfo
 import android.app.ActivityManager.RunningTaskInfo
+import android.app.KeyguardManager
 import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
+import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE
 import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
 import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
 import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
@@ -45,6 +47,7 @@
 import android.view.SurfaceControl
 import android.view.WindowManager
 import android.view.WindowManager.TRANSIT_CHANGE
+import android.view.WindowManager.TRANSIT_CLOSE
 import android.view.WindowManager.TRANSIT_OPEN
 import android.view.WindowManager.TRANSIT_TO_BACK
 import android.view.WindowManager.TRANSIT_TO_FRONT
@@ -87,7 +90,7 @@
 import com.android.wm.shell.recents.RecentTasksController
 import com.android.wm.shell.recents.RecentsTransitionHandler
 import com.android.wm.shell.recents.RecentsTransitionStateListener
-import com.android.wm.shell.shared.DesktopModeStatus
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
 import com.android.wm.shell.splitscreen.SplitScreenController
 import com.android.wm.shell.sysui.ShellCommandHandler
 import com.android.wm.shell.sysui.ShellController
@@ -102,6 +105,8 @@
 import java.util.Optional
 import junit.framework.Assert.assertFalse
 import junit.framework.Assert.assertTrue
+import kotlin.test.assertNotNull
+import kotlin.test.assertNull
 import org.junit.After
 import org.junit.Assume.assumeTrue
 import org.junit.Before
@@ -133,6 +138,7 @@
  */
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
+@EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
 class DesktopTasksControllerTest : ShellTestCase() {
 
   @JvmField @Rule val setFlagsRule = SetFlagsRule()
@@ -146,6 +152,7 @@
   @Mock lateinit var syncQueue: SyncTransactionQueue
   @Mock lateinit var rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
   @Mock lateinit var transitions: Transitions
+  @Mock lateinit var keyguardManager: KeyguardManager
   @Mock lateinit var exitDesktopTransitionHandler: ExitDesktopTaskTransitionHandler
   @Mock lateinit var enterDesktopTransitionHandler: EnterDesktopTaskTransitionHandler
   @Mock
@@ -188,7 +195,6 @@
             .strictness(Strictness.LENIENT)
             .spyStatic(DesktopModeStatus::class.java)
             .startMocking()
-    whenever(DesktopModeStatus.isEnabled()).thenReturn(true)
     doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
 
     shellInit = spy(ShellInit(testExecutor))
@@ -230,6 +236,7 @@
         rootTaskDisplayAreaOrganizer,
         dragAndDropController,
         transitions,
+        keyguardManager,
         enterDesktopTransitionHandler,
         exitDesktopTransitionHandler,
         toggleResizeDesktopTaskTransitionHandler,
@@ -257,8 +264,8 @@
   }
 
   @Test
-  fun instantiate_flagOff_doNotAddInitCallback() {
-    whenever(DesktopModeStatus.isEnabled()).thenReturn(false)
+  fun instantiate_canNotEnterDesktopMode_doNotAddInitCallback() {
+    whenever(DesktopModeStatus.canEnterDesktopMode(context)).thenReturn(false)
     clearInvocations(shellInit)
 
     createController()
@@ -436,14 +443,15 @@
   }
 
   @Test
-  fun showDesktopApps_dontReorderMinimizedTask() {
+  @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun showDesktopApps_desktopWallpaperDisabled_dontReorderMinimizedTask() {
     val homeTask = setUpHomeTask()
     val freeformTask = setUpFreeformTask()
     val minimizedTask = setUpFreeformTask()
+
     markTaskHidden(freeformTask)
     markTaskHidden(minimizedTask)
     desktopModeTaskRepository.minimizeTask(DEFAULT_DISPLAY, minimizedTask.taskId)
-
     controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition()))
 
     val wct = getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java)
@@ -454,6 +462,26 @@
   }
 
   @Test
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun showDesktopApps_desktopWallpaperEnabled_dontReorderMinimizedTask() {
+    setUpHomeTask()
+    val freeformTask = setUpFreeformTask()
+    val minimizedTask = setUpFreeformTask()
+
+    markTaskHidden(freeformTask)
+    markTaskHidden(minimizedTask)
+    desktopModeTaskRepository.minimizeTask(DEFAULT_DISPLAY, minimizedTask.taskId)
+    controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition()))
+
+    val wct = getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java)
+    assertThat(wct.hierarchyOps).hasSize(2)
+    // Add desktop wallpaper activity
+    wct.assertPendingIntentAt(index = 0, desktopWallpaperIntent)
+    // Reorder freeform task to top, don't reorder the minimized task
+    wct.assertReorderAt(index = 1, freeformTask, toTop = true)
+  }
+
+  @Test
   fun getVisibleTaskCount_noTasks_returnsZero() {
     assertThat(controller.getVisibleTaskCount(DEFAULT_DISPLAY)).isEqualTo(0)
   }
@@ -642,33 +670,68 @@
   }
 
   @Test
-  fun moveToDesktop_nonRunningTask_launchesInFreeform() {
-    whenever(shellTaskOrganizer.getRunningTaskInfo(anyInt())).thenReturn(null)
-
+  @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun moveToDesktop_desktopWallpaperDisabled_nonRunningTask_launchesInFreeform() {
     val task = createTaskInfo(1)
-
+    whenever(shellTaskOrganizer.getRunningTaskInfo(anyInt())).thenReturn(null)
     whenever(recentTasksController.findTaskInBackground(anyInt())).thenReturn(task)
 
     controller.moveToDesktop(task.taskId, transitionSource = UNKNOWN)
+
     with(getLatestEnterDesktopWct()) {
       assertLaunchTaskAt(0, task.taskId, WINDOWING_MODE_FREEFORM)
     }
   }
 
   @Test
-  fun moveToDesktop_topActivityTranslucent_doesNothing() {
-    setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun moveToDesktop_desktopWallpaperEnabled_nonRunningTask_launchesInFreeform() {
+    val task = createTaskInfo(1)
+    whenever(shellTaskOrganizer.getRunningTaskInfo(anyInt())).thenReturn(null)
+    whenever(recentTasksController.findTaskInBackground(anyInt())).thenReturn(task)
+
+    controller.moveToDesktop(task.taskId, transitionSource = UNKNOWN)
+
+    with(getLatestEnterDesktopWct()) {
+      // Add desktop wallpaper activity
+      assertPendingIntentAt(index = 0, desktopWallpaperIntent)
+      // Launch task
+      assertLaunchTaskAt(index = 1, task.taskId, WINDOWING_MODE_FREEFORM)
+    }
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+  fun moveToDesktop_topActivityTranslucentWithStyleFloating_taskIsMovedToDesktop() {
     val task =
-        setUpFullscreenTask().apply {
-          isTopActivityTransparent = true
-          numActivities = 1
-        }
+      setUpFullscreenTask().apply {
+        isTopActivityTransparent = true
+        isTopActivityStyleFloating = true
+        numActivities = 1
+      }
+
+    controller.moveToDesktop(task, transitionSource = UNKNOWN)
+
+    val wct = getLatestEnterDesktopWct()
+    assertThat(wct.changes[task.token.asBinder()]?.windowingMode).isEqualTo(WINDOWING_MODE_FREEFORM)
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+  fun moveToDesktop_topActivityTranslucentWithoutStyleFloating_doesNothing() {
+    val task =
+      setUpFullscreenTask().apply {
+        isTopActivityTransparent = true
+        isTopActivityStyleFloating = false
+        numActivities = 1
+      }
 
     controller.moveToDesktop(task, transitionSource = UNKNOWN)
     verifyEnterDesktopWCTNotExecuted()
   }
 
   @Test
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
   fun moveToDesktop_systemUIActivity_doesNothing() {
     val task = setUpFullscreenTask()
 
@@ -773,21 +836,44 @@
   }
 
   @Test
-  fun moveToDesktop_bringsTasksOverLimit_dontShowBackTask() {
+  @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun moveToDesktop_desktopWallpaperDisabled_bringsTasksOver_dontShowBackTask() {
     val taskLimit = desktopTasksLimiter.getMaxTaskLimit()
-    val homeTask = setUpHomeTask()
     val freeformTasks = (1..taskLimit).map { _ -> setUpFreeformTask() }
     val newTask = setUpFullscreenTask()
+    val homeTask = setUpHomeTask()
 
     controller.moveToDesktop(newTask, transitionSource = UNKNOWN)
 
     val wct = getLatestEnterDesktopWct()
     assertThat(wct.hierarchyOps.size).isEqualTo(taskLimit + 1) // visible tasks + home
     wct.assertReorderAt(0, homeTask)
-    for (i in 1..<taskLimit) { // Skipping freeformTasks[0]
-      wct.assertReorderAt(index = i, task = freeformTasks[i])
-    }
-    wct.assertReorderAt(taskLimit, newTask)
+    wct.assertReorderSequenceInRange(
+      range = 1..<(taskLimit + 1),
+      *freeformTasks.drop(1).toTypedArray(), // Skipping freeformTasks[0]
+      newTask
+    )
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun moveToDesktop_desktopWallpaperEnabled_bringsTasksOverLimit_dontShowBackTask() {
+    val taskLimit = desktopTasksLimiter.getMaxTaskLimit()
+    val freeformTasks = (1..taskLimit).map { _ -> setUpFreeformTask() }
+    val newTask = setUpFullscreenTask()
+    setUpHomeTask()
+
+    controller.moveToDesktop(newTask, transitionSource = UNKNOWN)
+
+    val wct = getLatestEnterDesktopWct()
+    assertThat(wct.hierarchyOps.size).isEqualTo(taskLimit + 1) // visible tasks + wallpaper
+    // Add desktop wallpaper activity
+    wct.assertPendingIntentAt(0, desktopWallpaperIntent)
+    wct.assertReorderSequenceInRange(
+      range = 1..<(taskLimit + 1),
+      *freeformTasks.drop(1).toTypedArray(), // Skipping freeformTasks[0]
+      newTask
+    )
   }
 
   @Test
@@ -923,7 +1009,7 @@
   @Test
   fun onDesktopWindowClose_noActiveTasks() {
     val wct = WindowContainerTransaction()
-    controller.onDesktopWindowClose(wct, 1 /* taskId */)
+    controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, taskId = 1)
     // Doesn't modify transaction
     assertThat(wct.hierarchyOps).isEmpty()
   }
@@ -932,7 +1018,7 @@
   fun onDesktopWindowClose_singleActiveTask_noWallpaperActivityToken() {
     val task = setUpFreeformTask()
     val wct = WindowContainerTransaction()
-    controller.onDesktopWindowClose(wct, task.taskId)
+    controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, taskId = task.taskId)
     // Doesn't modify transaction
     assertThat(wct.hierarchyOps).isEmpty()
   }
@@ -944,12 +1030,38 @@
     desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
 
     val wct = WindowContainerTransaction()
-    controller.onDesktopWindowClose(wct, task.taskId)
+    controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, taskId = task.taskId)
     // Adds remove wallpaper operation
     wct.assertRemoveAt(index = 0, wallpaperToken)
   }
 
   @Test
+  fun onDesktopWindowClose_singleActiveTask_isClosing() {
+    val task = setUpFreeformTask()
+    val wallpaperToken = MockToken().token()
+    desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+    desktopModeTaskRepository.addClosingTask(DEFAULT_DISPLAY, task.taskId)
+
+    val wct = WindowContainerTransaction()
+    controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, taskId = task.taskId)
+    // Doesn't modify transaction
+    assertThat(wct.hierarchyOps).isEmpty()
+  }
+
+  @Test
+  fun onDesktopWindowClose_singleActiveTask_isMinimized() {
+    val task = setUpFreeformTask()
+    val wallpaperToken = MockToken().token()
+    desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+    desktopModeTaskRepository.minimizeTask(DEFAULT_DISPLAY, task.taskId)
+
+    val wct = WindowContainerTransaction()
+    controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, taskId = task.taskId)
+    // Doesn't modify transaction
+    assertThat(wct.hierarchyOps).isEmpty()
+  }
+
+  @Test
   fun onDesktopWindowClose_multipleActiveTasks() {
     val task1 = setUpFreeformTask()
     setUpFreeformTask()
@@ -957,22 +1069,56 @@
     desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
 
     val wct = WindowContainerTransaction()
-    controller.onDesktopWindowClose(wct, task1.taskId)
+    controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, taskId = task1.taskId)
     // Doesn't modify transaction
     assertThat(wct.hierarchyOps).isEmpty()
   }
 
   @Test
+  fun onDesktopWindowClose_multipleActiveTasks_isOnlyNonClosingTask() {
+    val task1 = setUpFreeformTask()
+    val task2 = setUpFreeformTask()
+    val wallpaperToken = MockToken().token()
+    desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+    desktopModeTaskRepository.addClosingTask(DEFAULT_DISPLAY, task2.taskId)
+
+    val wct = WindowContainerTransaction()
+    controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, taskId = task1.taskId)
+    // Adds remove wallpaper operation
+    wct.assertRemoveAt(index = 0, wallpaperToken)
+  }
+
+  @Test
+  fun onDesktopWindowClose_multipleActiveTasks_hasMinimized() {
+    val task1 = setUpFreeformTask()
+    val task2 = setUpFreeformTask()
+    val wallpaperToken = MockToken().token()
+    desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+    desktopModeTaskRepository.minimizeTask(DEFAULT_DISPLAY, task2.taskId)
+
+    val wct = WindowContainerTransaction()
+    controller.onDesktopWindowClose(wct, displayId = DEFAULT_DISPLAY, taskId = task1.taskId)
+    // Adds remove wallpaper operation
+    wct.assertRemoveAt(index = 0, wallpaperToken)
+  }
+
+  @Test
   fun handleRequest_fullscreenTask_freeformVisible_returnSwitchToFreeformWCT() {
     assumeTrue(ENABLE_SHELL_TRANSITIONS)
 
+    val homeTask = setUpHomeTask()
     val freeformTask = setUpFreeformTask()
     markTaskVisible(freeformTask)
     val fullscreenTask = createFullscreenTask()
 
-    val result = controller.handleRequest(Binder(), createTransition(fullscreenTask))
-    assertThat(result?.changes?.get(fullscreenTask.token.asBinder())?.windowingMode)
+    val wct = controller.handleRequest(Binder(), createTransition(fullscreenTask))
+
+    assertNotNull(wct, "should handle request")
+    assertThat(wct.changes[fullscreenTask.token.asBinder()]?.windowingMode)
         .isEqualTo(WINDOWING_MODE_FREEFORM)
+
+    assertThat(wct.hierarchyOps).hasSize(2)
+    wct.assertReorderAt(1, homeTask, toTop = false)
   }
 
   @Test
@@ -1052,41 +1198,106 @@
   }
 
   @Test
-  fun handleRequest_freeformTask_freeformNotVisible_reorderedToTop() {
+  @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_freeformTask_desktopWallpaperDisabled_freeformNotVisible_reorderedToTop() {
     assumeTrue(ENABLE_SHELL_TRANSITIONS)
 
     val freeformTask1 = setUpFreeformTask()
-    markTaskHidden(freeformTask1)
-
     val freeformTask2 = createFreeformTask()
+
+    markTaskHidden(freeformTask1)
     val result =
         controller.handleRequest(Binder(), createTransition(freeformTask2, type = TRANSIT_TO_FRONT))
 
-    assertThat(result?.hierarchyOps?.size).isEqualTo(2)
-    result!!.assertReorderAt(1, freeformTask2, toTop = true)
+    assertNotNull(result, "Should handle request")
+    assertThat(result.hierarchyOps?.size).isEqualTo(2)
+    result.assertReorderAt(1, freeformTask2, toTop = true)
   }
 
   @Test
-  fun handleRequest_freeformTask_noOtherTasks_reorderedToTop() {
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_freeformTask_desktopWallpaperEnabled_freeformNotVisible_reorderedToTop() {
+    assumeTrue(ENABLE_SHELL_TRANSITIONS)
+
+    val freeformTask1 = setUpFreeformTask()
+    val freeformTask2 = createFreeformTask()
+
+    markTaskHidden(freeformTask1)
+    val result =
+      controller.handleRequest(Binder(), createTransition(freeformTask2, type = TRANSIT_TO_FRONT))
+
+    assertNotNull(result, "Should handle request")
+    assertThat(result.hierarchyOps?.size).isEqualTo(3)
+    // Add desktop wallpaper activity
+    result.assertPendingIntentAt(0, desktopWallpaperIntent)
+    // Bring active desktop tasks to front
+    result.assertReorderAt(1, freeformTask1, toTop = true)
+    // Bring new task to front
+    result.assertReorderAt(2, freeformTask2, toTop = true)
+  }
+
+  @Test
+  @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_freeformTask_desktopWallpaperDisabled_noOtherTasks_reorderedToTop() {
     assumeTrue(ENABLE_SHELL_TRANSITIONS)
 
     val task = createFreeformTask()
     val result = controller.handleRequest(Binder(), createTransition(task))
 
-    assertThat(result?.hierarchyOps?.size).isEqualTo(1)
-    result!!.assertReorderAt(0, task, toTop = true)
+    assertNotNull(result, "Should handle request")
+    assertThat(result.hierarchyOps?.size).isEqualTo(1)
+    result.assertReorderAt(0, task, toTop = true)
   }
 
   @Test
-  fun handleRequest_freeformTask_freeformOnOtherDisplayOnly_reorderedToTop() {
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_freeformTask_desktopWallpaperEnabled_noOtherTasks_reorderedToTop() {
+    assumeTrue(ENABLE_SHELL_TRANSITIONS)
+
+    val task = createFreeformTask()
+    val result = controller.handleRequest(Binder(), createTransition(task))
+
+    assertNotNull(result, "Should handle request")
+    assertThat(result.hierarchyOps?.size).isEqualTo(2)
+    // Add desktop wallpaper activity
+    result.assertPendingIntentAt(0, desktopWallpaperIntent)
+    // Bring new task to front
+    result.assertReorderAt(1, task, toTop = true)
+  }
+
+  @Test
+  @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_freeformTask_dskWallpaperDisabled_freeformOnOtherDisplayOnly_reorderedToTop() {
     assumeTrue(ENABLE_SHELL_TRANSITIONS)
 
     val taskDefaultDisplay = createFreeformTask(displayId = DEFAULT_DISPLAY)
-    val taskSecondDisplay = createFreeformTask(displayId = SECOND_DISPLAY)
+    // Second display task
+    createFreeformTask(displayId = SECOND_DISPLAY)
 
     val result = controller.handleRequest(Binder(), createTransition(taskDefaultDisplay))
-    assertThat(result?.hierarchyOps?.size).isEqualTo(1)
-    result!!.assertReorderAt(0, taskDefaultDisplay, toTop = true)
+
+    assertNotNull(result, "Should handle request")
+    assertThat(result.hierarchyOps?.size).isEqualTo(1)
+    result.assertReorderAt(0, taskDefaultDisplay, toTop = true)
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_freeformTask_dskWallpaperEnabled_freeformOnOtherDisplayOnly_reorderedToTop() {
+    assumeTrue(ENABLE_SHELL_TRANSITIONS)
+
+    val taskDefaultDisplay = createFreeformTask(displayId = DEFAULT_DISPLAY)
+    // Second display task
+    createFreeformTask(displayId = SECOND_DISPLAY)
+
+    val result = controller.handleRequest(Binder(), createTransition(taskDefaultDisplay))
+
+    assertNotNull(result, "Should handle request")
+    assertThat(result.hierarchyOps?.size).isEqualTo(2)
+    // Add desktop wallpaper activity
+    result.assertPendingIntentAt(0, desktopWallpaperIntent)
+    // Bring new task to front
+    result.assertReorderAt(1, taskDefaultDisplay, toTop = true)
   }
 
   @Test
@@ -1118,6 +1329,17 @@
   }
 
   @Test
+  fun handleRequest_freeformTask_keyguardLocked_returnNull() {
+    assumeTrue(ENABLE_SHELL_TRANSITIONS)
+    whenever(keyguardManager.isKeyguardLocked).thenReturn(true)
+    val freeformTask = createFreeformTask(displayId = DEFAULT_DISPLAY)
+
+    val result = controller.handleRequest(Binder(), createTransition(freeformTask))
+
+    assertNull(result, "Should NOT handle request")
+  }
+
+  @Test
   fun handleRequest_notOpenOrToFrontTransition_returnNull() {
     assumeTrue(ENABLE_SHELL_TRANSITIONS)
 
@@ -1171,20 +1393,40 @@
   }
 
   @Test
-  fun handleRequest_shouldLaunchAsModal_returnSwitchToFullscreenWCT() {
-    setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+  fun handleRequest_topActivityTransparentWithStyleFloating_returnSwitchToFreeformWCT() {
+    val freeformTask = setUpFreeformTask()
+    markTaskVisible(freeformTask)
+
     val task =
-        setUpFreeformTask().apply {
-          isTopActivityTransparent = true
-          numActivities = 1
-        }
+      setUpFullscreenTask().apply {
+        isTopActivityTransparent = true
+        isTopActivityStyleFloating = true
+        numActivities = 1
+      }
 
     val result = controller.handleRequest(Binder(), createTransition(task))
     assertThat(result?.changes?.get(task.token.asBinder())?.windowingMode)
-        .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
+            .isEqualTo(WINDOWING_MODE_FREEFORM)
   }
 
   @Test
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+  fun handleRequest_topActivityTransparentWithoutStyleFloating_returnSwitchToFullscreenWCT() {
+    val task =
+      setUpFreeformTask().apply {
+        isTopActivityTransparent = true
+        isTopActivityStyleFloating = false
+        numActivities = 1
+      }
+
+    val result = controller.handleRequest(Binder(), createTransition(task))
+    assertThat(result?.changes?.get(task.token.asBinder())?.windowingMode)
+            .isEqualTo(WINDOWING_MODE_UNDEFINED) // inherited FULLSCREEN
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
   fun handleRequest_systemUIActivity_returnSwitchToFullscreenWCT() {
     val task = setUpFreeformTask()
 
@@ -1200,48 +1442,205 @@
   }
 
   @Test
-  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
-  fun handleRequest_backTransition_singleActiveTask_noToken() {
+  @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_backTransition_singleActiveTaskNoTokenFlagDisabled_doesNotHandle() {
     val task = setUpFreeformTask()
+
     val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_TO_BACK))
-    // Doesn't handle request
-    assertThat(result).isNull()
+
+    assertNull(result, "Should not handle request")
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_backTransition_singleActiveTaskNoTokenFlagEnabled_doesNotHandle() {
+    val task = setUpFreeformTask()
+
+    val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_TO_BACK))
+
+    assertNull(result, "Should not handle request")
   }
 
   @Test
   @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
-  fun handleRequest_backTransition_singleActiveTask_hasToken_desktopWallpaperDisabled() {
-    desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
-
+  fun handleRequest_backTransition_singleActiveTaskWithTokenFlagDisabled_doesNotHandle() {
     val task = setUpFreeformTask()
+
+    desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
     val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_TO_BACK))
-    // Doesn't handle request
-    assertThat(result).isNull()
+
+    assertNull(result, "Should not handle request")
   }
 
   @Test
   @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
-  fun handleRequest_backTransition_singleActiveTask_hasToken_desktopWallpaperEnabled() {
+  fun handleRequest_backTransition_singleActiveTaskWithTokenFlagEnabled_handlesRequest() {
+    val task = setUpFreeformTask()
     val wallpaperToken = MockToken().token()
-    desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
 
-    val task = setUpFreeformTask()
+    desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
     val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_TO_BACK))
-    assertThat(result).isNotNull()
-    // Creates remove wallpaper transaction
-    result!!.assertRemoveAt(index = 0, wallpaperToken)
+
+    assertNotNull(result, "Should handle request")
+      // Should create remove wallpaper transaction
+      .assertRemoveAt(index = 0, wallpaperToken)
   }
 
   @Test
-  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
-  fun handleRequest_backTransition_multipleActiveTasks() {
-    desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
-
+  @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_backTransition_multipleActiveTasksFlagDisabled_doesNotHandle() {
     val task1 = setUpFreeformTask()
     setUpFreeformTask()
+
+    desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
     val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_TO_BACK))
-    // Doesn't handle request
-    assertThat(result).isNull()
+
+    assertNull(result, "Should not handle request")
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_backTransition_multipleActiveTasksFlagEnabled_doesNotHandle() {
+    val task1 = setUpFreeformTask()
+    setUpFreeformTask()
+
+    desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
+    val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_TO_BACK))
+
+    assertNull(result, "Should not handle request")
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_backTransition_multipleActiveTasksSingleNonClosing_handlesRequest() {
+    val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+    val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+    val wallpaperToken = MockToken().token()
+
+    desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+    desktopModeTaskRepository.addClosingTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+    val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_TO_BACK))
+
+    assertNotNull(result, "Should handle request")
+      // Should create remove wallpaper transaction
+      .assertRemoveAt(index = 0, wallpaperToken)
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_backTransition_multipleActiveTasksSingleNonMinimized_handlesRequest() {
+    val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+    val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+    val wallpaperToken = MockToken().token()
+
+    desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+    desktopModeTaskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+    val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_TO_BACK))
+
+    assertNotNull(result, "Should handle request")
+      // Should create remove wallpaper transaction
+      .assertRemoveAt(index = 0, wallpaperToken)
+  }
+
+  @Test
+  @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_closeTransition_singleActiveTaskNoTokenFlagDisabled_doesNotHandle() {
+    val task = setUpFreeformTask()
+
+    val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_CLOSE))
+
+    assertNull(result, "Should not handle request")
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_closeTransition_singleActiveTaskNoTokenFlagEnabled_doesNotHandle() {
+    val task = setUpFreeformTask()
+
+    val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_CLOSE))
+
+    assertNull(result, "Should not handle request")
+  }
+
+  @Test
+  @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_closeTransition_singleActiveTaskWithTokenFlagDisabled_doesNotHandle() {
+    val task = setUpFreeformTask()
+
+    desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
+    val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_CLOSE))
+
+    assertNull(result, "Should not handle request")
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_closeTransition_singleActiveTaskWithTokenFlagEnabled_handlesRequest() {
+    val task = setUpFreeformTask()
+    val wallpaperToken = MockToken().token()
+
+    desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+    val result = controller.handleRequest(Binder(), createTransition(task, type = TRANSIT_CLOSE))
+
+    assertNotNull(result, "Should handle request")
+      // Should create remove wallpaper transaction
+      .assertRemoveAt(index = 0, wallpaperToken)
+  }
+
+  @Test
+  @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_closeTransition_multipleActiveTasksFlagDisabled_doesNotHandle() {
+    val task1 = setUpFreeformTask()
+    setUpFreeformTask()
+
+    desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
+    val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_CLOSE))
+
+    assertNull(result, "Should not handle request")
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_closeTransition_multipleActiveTasksFlagEnabled_doesNotHandle() {
+    val task1 = setUpFreeformTask()
+    setUpFreeformTask()
+
+    desktopModeTaskRepository.wallpaperActivityToken = MockToken().token()
+    val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_CLOSE))
+
+    assertNull(result, "Should not handle request")
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_closeTransition_multipleActiveTasksSingleNonClosing_handlesRequest() {
+    val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+    val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+    val wallpaperToken = MockToken().token()
+
+    desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+    desktopModeTaskRepository.addClosingTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+    val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_CLOSE))
+
+    assertNotNull(result, "Should handle request")
+      // Should create remove wallpaper transaction
+      .assertRemoveAt(index = 0, wallpaperToken)
+  }
+
+  @Test
+  @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun handleRequest_closeTransition_multipleActiveTasksSingleNonMinimized_handlesRequest() {
+    val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+    val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+    val wallpaperToken = MockToken().token()
+
+    desktopModeTaskRepository.wallpaperActivityToken = wallpaperToken
+    desktopModeTaskRepository.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+    val result = controller.handleRequest(Binder(), createTransition(task1, type = TRANSIT_CLOSE))
+
+    assertNotNull(result, "Should handle request")
+      // Should create remove wallpaper transaction
+      .assertRemoveAt(index = 0, wallpaperToken)
   }
 
   @Test
@@ -1562,6 +1961,26 @@
   }
 
   @Test
+  fun toggleBounds_togglesToCalculatedBoundsForNonResizable() {
+    val bounds = Rect(0, 0, 200, 100)
+    val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds).apply {
+      topActivityInfo = ActivityInfo().apply {
+        screenOrientation = SCREEN_ORIENTATION_LANDSCAPE
+        configuration.windowConfiguration.appBounds = bounds
+      }
+      isResizeable = false
+    }
+
+    // Bounds should be 1000 x 500, vertically centered in the 1000 x 1000 stable bounds
+    val expectedBounds = Rect(STABLE_BOUNDS.left, 250, STABLE_BOUNDS.right, 750)
+
+    controller.toggleDesktopTaskSize(task)
+    // Assert bounds set to stable bounds
+    val wct = getLatestToggleResizeDesktopTaskWct()
+    assertThat(findBoundsChange(wct, task)).isEqualTo(expectedBounds)
+  }
+
+  @Test
   fun toggleBounds_lastBoundsBeforeMaximizeSaved() {
     val bounds = Rect(0, 0, 100, 100)
     val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds)
@@ -1588,6 +2007,46 @@
   }
 
   @Test
+  fun toggleBounds_togglesFromStableBoundsToLastBoundsBeforeMaximize_nonResizeableEqualWidth() {
+    val boundsBeforeMaximize = Rect(0, 0, 100, 100)
+    val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize).apply {
+      isResizeable = false
+    }
+
+    // Maximize
+    controller.toggleDesktopTaskSize(task)
+    task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS.left,
+      boundsBeforeMaximize.top, STABLE_BOUNDS.right, boundsBeforeMaximize.bottom)
+
+    // Restore
+    controller.toggleDesktopTaskSize(task)
+
+    // Assert bounds set to last bounds before maximize
+    val wct = getLatestToggleResizeDesktopTaskWct()
+    assertThat(findBoundsChange(wct, task)).isEqualTo(boundsBeforeMaximize)
+  }
+
+  @Test
+  fun toggleBounds_togglesFromStableBoundsToLastBoundsBeforeMaximize_nonResizeableEqualHeight() {
+    val boundsBeforeMaximize = Rect(0, 0, 100, 100)
+    val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize).apply {
+      isResizeable = false
+    }
+
+    // Maximize
+    controller.toggleDesktopTaskSize(task)
+    task.configuration.windowConfiguration.bounds.set(boundsBeforeMaximize.left,
+      STABLE_BOUNDS.top, boundsBeforeMaximize.right, STABLE_BOUNDS.bottom)
+
+    // Restore
+    controller.toggleDesktopTaskSize(task)
+
+    // Assert bounds set to last bounds before maximize
+    val wct = getLatestToggleResizeDesktopTaskWct()
+    assertThat(findBoundsChange(wct, task)).isEqualTo(boundsBeforeMaximize)
+  }
+
+  @Test
   fun toggleBounds_removesLastBoundsBeforeMaximizeAfterRestoringBounds() {
     val boundsBeforeMaximize = Rect(0, 0, 100, 100)
     val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize)
@@ -1615,6 +2074,7 @@
     task.topActivityInfo = activityInfo
     whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
     desktopModeTaskRepository.addActiveTask(displayId, task.taskId)
+    desktopModeTaskRepository.updateVisibleFreeformTasks(displayId, task.taskId, visible = true)
     desktopModeTaskRepository.addOrMoveFreeformTaskToTop(displayId, task.taskId)
     runningTasks.add(task)
     return task
@@ -1826,6 +2286,16 @@
   }
 }
 
+/** Checks if the reorder hierarchy operations in [range] correspond to [tasks] list */
+private fun WindowContainerTransaction.assertReorderSequenceInRange(
+  range: IntRange,
+  vararg tasks: RunningTaskInfo
+) {
+  assertThat(hierarchyOps.slice(range).map { it.type to it.container })
+    .containsExactlyElementsIn(tasks.map { HIERARCHY_OP_TYPE_REORDER to it.token.asBinder() })
+    .inOrder()
+}
+
 private fun WindowContainerTransaction.assertRemoveAt(index: Int, token: WindowContainerToken) {
   assertIndexInBounds(index)
   val op = hierarchyOps[index]
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
index 77f917c..8d9fd91 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
@@ -24,6 +24,7 @@
 import android.view.WindowManager.TRANSIT_OPEN
 import android.view.WindowManager.TRANSIT_TO_BACK
 import android.window.WindowContainerTransaction
+import android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REMOVE_TASK
 import android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER
 import androidx.test.filters.SmallTest
 import com.android.dx.mockito.inline.extended.ExtendedMockito
@@ -32,7 +33,7 @@
 import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFreeformTask
-import com.android.wm.shell.shared.DesktopModeStatus
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
 import com.android.wm.shell.transition.TransitionInfoBuilder
 import com.android.wm.shell.transition.Transitions
 import com.android.wm.shell.util.StubTransaction
@@ -205,6 +206,46 @@
     }
 
     @Test
+    fun removeLeftoverMinimizedTasks_activeNonMinimizedTasksStillAround_doesNothing() {
+        desktopTaskRepo.addActiveTask(displayId = DEFAULT_DISPLAY, taskId = 1)
+        desktopTaskRepo.addActiveTask(displayId = DEFAULT_DISPLAY, taskId = 2)
+        desktopTaskRepo.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = 2)
+
+        val wct = WindowContainerTransaction()
+        desktopTasksLimiter.leftoverMinimizedTasksRemover.removeLeftoverMinimizedTasks(
+            DEFAULT_DISPLAY, wct)
+
+        assertThat(wct.isEmpty).isTrue()
+    }
+
+    @Test
+    fun removeLeftoverMinimizedTasks_noMinimizedTasks_doesNothing() {
+        val wct = WindowContainerTransaction()
+        desktopTasksLimiter.leftoverMinimizedTasksRemover.removeLeftoverMinimizedTasks(
+            DEFAULT_DISPLAY, wct)
+
+        assertThat(wct.isEmpty).isTrue()
+    }
+
+    @Test
+    fun removeLeftoverMinimizedTasks_onlyMinimizedTasksLeft_removesAllMinimizedTasks() {
+        val task1 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+        val task2 = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+        desktopTaskRepo.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task1.taskId)
+        desktopTaskRepo.minimizeTask(displayId = DEFAULT_DISPLAY, taskId = task2.taskId)
+
+        val wct = WindowContainerTransaction()
+        desktopTasksLimiter.leftoverMinimizedTasksRemover.removeLeftoverMinimizedTasks(
+            DEFAULT_DISPLAY, wct)
+
+        assertThat(wct.hierarchyOps).hasSize(2)
+        assertThat(wct.hierarchyOps[0].type).isEqualTo(HIERARCHY_OP_TYPE_REMOVE_TASK)
+        assertThat(wct.hierarchyOps[0].container).isEqualTo(task1.token.asBinder())
+        assertThat(wct.hierarchyOps[1].type).isEqualTo(HIERARCHY_OP_TYPE_REMOVE_TASK)
+        assertThat(wct.hierarchyOps[1].container).isEqualTo(task2.token.asBinder())
+    }
+
+    @Test
     fun addAndGetMinimizeTaskChangesIfNeeded_tasksWithinLimit_noTaskMinimized() {
         val taskLimit = desktopTasksLimiter.getMaxTaskLimit()
         (1..<taskLimit).forEach { _ -> setUpFreeformTask() }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java
index b2467e9..e5157c9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandlerTest.java
@@ -45,6 +45,7 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.internal.jank.InteractionJankMonitor;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.desktopmode.DesktopModeTransitionSource;
@@ -65,6 +66,8 @@
     @Mock
     private Transitions mTransitions;
     @Mock
+    private InteractionJankMonitor mInteractionJankMonitor;
+    @Mock
     IBinder mToken;
     @Mock
     Supplier<SurfaceControl.Transaction> mTransactionFactory;
@@ -94,7 +97,7 @@
                 .thenReturn(getContext().getResources().getDisplayMetrics());
 
         mExitDesktopTaskTransitionHandler = new ExitDesktopTaskTransitionHandler(mTransitions,
-                mContext);
+                mContext, mInteractionJankMonitor);
         mPoint = new Point(0, 0);
     }
 
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 a64ebd3..8401264 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
@@ -76,6 +76,8 @@
     @Mock
     private ShellCommandHandler mShellCommandHandler;
     @Mock
+    private ShellTaskOrganizer mShellTaskOrganizer;
+    @Mock
     private DisplayController mDisplayController;
     @Mock
     private UiEventLogger mUiEventLogger;
@@ -96,8 +98,8 @@
     public void setUp() throws RemoteException {
         MockitoAnnotations.initMocks(this);
         mController = new DragAndDropController(mContext, mShellInit, mShellController,
-                mShellCommandHandler, mDisplayController, mUiEventLogger, mIconProvider,
-                mGlobalDragListener, mTransitions, mMainExecutor);
+                mShellCommandHandler, mShellTaskOrganizer, mDisplayController, mUiEventLogger,
+                mIconProvider, mGlobalDragListener, mTransitions, mMainExecutor);
         mController.onInit();
     }
 
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 6e72e8d..97fa8d6 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
@@ -65,8 +65,6 @@
 import android.graphics.Insets;
 import android.os.RemoteException;
 import android.view.DisplayInfo;
-import android.view.DragEvent;
-import android.view.View;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
@@ -76,7 +74,6 @@
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.draganddrop.DragAndDropPolicy.Target;
 import com.android.wm.shell.splitscreen.SplitScreenController;
-import com.android.wm.shell.startingsurface.TaskSnapshotWindow;
 
 import org.junit.After;
 import org.junit.Before;
@@ -106,6 +103,8 @@
     // Both the split-screen and start interface.
     @Mock
     private SplitScreenController mSplitScreenStarter;
+    @Mock
+    private DragAndDropPolicy.Starter mFullscreenStarter;
 
     @Mock
     private InstanceId mLoggerSessionId;
@@ -151,7 +150,7 @@
         mPortraitDisplayLayout = new DisplayLayout(info2, res, false, false);
         mInsets = Insets.of(0, 0, 0, 0);
 
-        mPolicy = spy(new DragAndDropPolicy(mContext, mSplitScreenStarter, mSplitScreenStarter));
+        mPolicy = spy(new DragAndDropPolicy(mContext, mSplitScreenStarter, mFullscreenStarter));
         mActivityClipData = createAppClipData(MIMETYPE_APPLICATION_ACTIVITY);
         mLaunchableIntentPendingIntent = mock(PendingIntent.class);
         when(mLaunchableIntentPendingIntent.getCreatorUserHandle())
@@ -285,14 +284,14 @@
         setRunningTask(mHomeTask);
         DragSession dragSession = new DragSession(mActivityTaskManager,
                 mLandscapeDisplayLayout, data, 0 /* dragFlags */);
-        dragSession.update();
+        dragSession.initialize();
         mPolicy.start(dragSession, mLoggerSessionId);
         ArrayList<Target> targets = assertExactTargetTypes(
                 mPolicy.getTargets(mInsets), TYPE_FULLSCREEN);
 
-        mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN));
-        verify(mSplitScreenStarter).startIntent(any(), anyInt(), any(),
-                eq(SPLIT_POSITION_UNDEFINED), any());
+        mPolicy.handleDrop(filterTargetByType(targets, TYPE_FULLSCREEN), null /* hideTaskToken */);
+        verify(mFullscreenStarter).startIntent(any(), anyInt(), any(),
+                eq(SPLIT_POSITION_UNDEFINED), any(), any());
     }
 
     private void dragOverFullscreenApp_expectSplitScreenTargets(ClipData data) {
@@ -300,19 +299,19 @@
         setRunningTask(mFullscreenAppTask);
         DragSession dragSession = new DragSession(mActivityTaskManager,
                 mLandscapeDisplayLayout, data, 0 /* dragFlags */);
-        dragSession.update();
+        dragSession.initialize();
         mPolicy.start(dragSession, mLoggerSessionId);
         ArrayList<Target> targets = assertExactTargetTypes(
                 mPolicy.getTargets(mInsets), TYPE_SPLIT_LEFT, TYPE_SPLIT_RIGHT);
 
-        mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_LEFT));
+        mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_LEFT), null /* hideTaskToken */);
         verify(mSplitScreenStarter).startIntent(any(), anyInt(), any(),
-                eq(SPLIT_POSITION_TOP_OR_LEFT), any());
+                eq(SPLIT_POSITION_TOP_OR_LEFT), any(), any());
         reset(mSplitScreenStarter);
 
-        mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_RIGHT));
+        mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_RIGHT), null /* hideTaskToken */);
         verify(mSplitScreenStarter).startIntent(any(), anyInt(), any(),
-                eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), any());
+                eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), any(), any());
     }
 
     private void dragOverFullscreenAppPhone_expectVerticalSplitScreenTargets(ClipData data) {
@@ -320,19 +319,20 @@
         setRunningTask(mFullscreenAppTask);
         DragSession dragSession = new DragSession(mActivityTaskManager,
                 mPortraitDisplayLayout, data, 0 /* dragFlags */);
-        dragSession.update();
+        dragSession.initialize();
         mPolicy.start(dragSession, mLoggerSessionId);
         ArrayList<Target> targets = assertExactTargetTypes(
                 mPolicy.getTargets(mInsets), TYPE_SPLIT_TOP, TYPE_SPLIT_BOTTOM);
 
-        mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_TOP));
+        mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_TOP), null /* hideTaskToken */);
         verify(mSplitScreenStarter).startIntent(any(), anyInt(), any(),
-                eq(SPLIT_POSITION_TOP_OR_LEFT), any());
+                eq(SPLIT_POSITION_TOP_OR_LEFT), any(), any());
         reset(mSplitScreenStarter);
 
-        mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_BOTTOM));
+        mPolicy.handleDrop(filterTargetByType(targets, TYPE_SPLIT_BOTTOM),
+                null /* hideTaskToken */);
         verify(mSplitScreenStarter).startIntent(any(), anyInt(), any(),
-                eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), any());
+                eq(SPLIT_POSITION_BOTTOM_OR_RIGHT), any(), any());
     }
 
     @Test
@@ -340,7 +340,7 @@
         setRunningTask(mFullscreenAppTask);
         DragSession dragSession = new DragSession(mActivityTaskManager,
                 mLandscapeDisplayLayout, mActivityClipData, 0 /* dragFlags */);
-        dragSession.update();
+        dragSession.initialize();
         mPolicy.start(dragSession, mLoggerSessionId);
         ArrayList<Target> targets = mPolicy.getTargets(mInsets);
         for (Target t : targets) {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java
index 3f3cafc..6ec6bed 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java
@@ -36,7 +36,7 @@
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.TestRunningTaskInfoBuilder;
 import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
-import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.windowdecor.WindowDecorViewModel;
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
index 5880ffb..72950a8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
@@ -88,8 +88,11 @@
 
     @Test
     public void getAnimator_withBounds_returnBoundsAnimator() {
+        final Rect baseValue = new Rect(0, 0, 100, 100);
+        final Rect startValue = new Rect(0, 0, 100, 100);
+        final Rect endValue1 = new Rect(100, 100, 200, 200);
         final PipAnimationController.PipTransitionAnimator animator = mPipAnimationController
-                .getAnimator(mTaskInfo, mLeash, new Rect(), new Rect(), new Rect(), null,
+                .getAnimator(mTaskInfo, mLeash, baseValue, startValue, endValue1, null,
                         TRANSITION_DIRECTION_TO_PIP, 0, ROTATION_0);
 
         assertEquals("Expect ANIM_TYPE_BOUNDS animation",
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 d38fc6c..75d2145 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
@@ -34,7 +34,6 @@
 
 import static java.lang.Integer.MAX_VALUE;
 
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
@@ -183,7 +182,7 @@
 
     @Test
     public void instantiatePipController_registersPipTransitionCallback() {
-        verify(mMockPipTransitionController).registerPipTransitionCallback(any());
+        verify(mMockPipTransitionController).registerPipTransitionCallback(any(), any());
     }
 
     @Test
@@ -235,27 +234,6 @@
     }
 
     @Test
-    public void onActivityHidden_isLastPipComponentName_clearLastPipComponent() {
-        final ComponentName component1 = new ComponentName(mContext, "component1");
-        when(mMockPipBoundsState.getLastPipComponentName()).thenReturn(component1);
-
-        mPipController.mPinnedTaskListener.onActivityHidden(component1);
-
-        verify(mMockPipBoundsState).setLastPipComponentName(null);
-    }
-
-    @Test
-    public void onActivityHidden_isNotLastPipComponentName_lastPipComponentNotCleared() {
-        final ComponentName component1 = new ComponentName(mContext, "component1");
-        final ComponentName component2 = new ComponentName(mContext, "component2");
-        when(mMockPipBoundsState.getLastPipComponentName()).thenReturn(component1);
-
-        mPipController.mPinnedTaskListener.onActivityHidden(component2);
-
-        verify(mMockPipBoundsState, never()).setLastPipComponentName(null);
-    }
-
-    @Test
     public void saveReentryState_savesPipBoundsState() {
         final Rect bounds = new Rect(0, 0, 10, 10);
         when(mMockPipBoundsAlgorithm.getSnapFraction(bounds)).thenReturn(1.0f);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java
index ace09a8..66f8c0b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java
@@ -114,8 +114,8 @@
         final PipBoundsAlgorithm pipBoundsAlgorithm = new PipBoundsAlgorithm(mContext,
                 mPipBoundsState, pipSnapAlgorithm, pipKeepClearAlgorithm, mPipDisplayLayoutState,
                 mSizeSpecSource);
-        final PipMotionHelper motionHelper = new PipMotionHelper(mContext, mPipBoundsState,
-                mPipTaskOrganizer, mPhonePipMenuController, pipSnapAlgorithm,
+        final PipMotionHelper motionHelper = new PipMotionHelper(mContext, mMainExecutor,
+                mPipBoundsState, mPipTaskOrganizer, mPhonePipMenuController, pipSnapAlgorithm,
                 mMockPipTransitionController, mFloatingContentCoordinator,
                 Optional.empty() /* pipPerfHintControllerOptional */);
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
index 92762fa..6d18e36 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
@@ -116,8 +116,8 @@
         mPipSnapAlgorithm = new PipSnapAlgorithm();
         mPipBoundsAlgorithm = new PipBoundsAlgorithm(mContext, mPipBoundsState, mPipSnapAlgorithm,
                 new PipKeepClearAlgorithmInterface() {}, mPipDisplayLayoutState, mSizeSpecSource);
-        PipMotionHelper pipMotionHelper = new PipMotionHelper(mContext, mPipBoundsState,
-                mPipTaskOrganizer, mPhonePipMenuController, mPipSnapAlgorithm,
+        PipMotionHelper pipMotionHelper = new PipMotionHelper(mContext, mMainExecutor,
+                mPipBoundsState, mPipTaskOrganizer, mPhonePipMenuController, mPipSnapAlgorithm,
                 mMockPipTransitionController, mFloatingContentCoordinator,
                 Optional.empty() /* pipPerfHintControllerOptional */);
         mPipTouchHandler = new PipTouchHandler(mContext, mShellInit, mPhonePipMenuController,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipGravityTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipGravityTest.java
index 974539f..aa2d6f0 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipGravityTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipGravityTest.java
@@ -241,16 +241,16 @@
 
     @Test
     public void updateGravity_move_expanded_valid() {
-        mTvPipBoundsState.setTvPipExpanded(true);
-
         // Vertical expanded PiP.
         mTvPipBoundsState.setDesiredTvExpandedAspectRatio(VERTICAL_EXPANDED_ASPECT_RATIO, true);
+        mTvPipBoundsState.setTvPipExpanded(true);
         mTvPipBoundsState.setTvPipGravity(Gravity.CENTER_VERTICAL | Gravity.RIGHT);
         moveAndCheckGravity(KEYCODE_DPAD_LEFT, Gravity.CENTER_VERTICAL | Gravity.LEFT, true);
         moveAndCheckGravity(KEYCODE_DPAD_RIGHT, Gravity.CENTER_VERTICAL | Gravity.RIGHT, true);
 
         // Horizontal expanded PiP.
         mTvPipBoundsState.setDesiredTvExpandedAspectRatio(HORIZONTAL_EXPANDED_ASPECT_RATIO, true);
+        mTvPipBoundsState.setTvPipExpanded(true);
         mTvPipBoundsState.setTvPipGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);
         moveAndCheckGravity(KEYCODE_DPAD_UP, Gravity.TOP | Gravity.CENTER_HORIZONTAL, true);
         moveAndCheckGravity(KEYCODE_DPAD_DOWN, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, true);
@@ -281,10 +281,9 @@
 
     @Test
     public void updateGravity_move_expanded_invalid() {
-        mTvPipBoundsState.setTvPipExpanded(true);
-
         // Vertical expanded PiP.
         mTvPipBoundsState.setDesiredTvExpandedAspectRatio(VERTICAL_EXPANDED_ASPECT_RATIO, true);
+        mTvPipBoundsState.setTvPipExpanded(true);
         mTvPipBoundsState.setTvPipGravity(Gravity.CENTER_VERTICAL | Gravity.RIGHT);
         moveAndCheckGravity(KEYCODE_DPAD_RIGHT, Gravity.CENTER_VERTICAL | Gravity.RIGHT, false);
         moveAndCheckGravity(KEYCODE_DPAD_UP, Gravity.CENTER_VERTICAL | Gravity.RIGHT, false);
@@ -297,6 +296,7 @@
 
         // Horizontal expanded PiP.
         mTvPipBoundsState.setDesiredTvExpandedAspectRatio(HORIZONTAL_EXPANDED_ASPECT_RATIO, true);
+        mTvPipBoundsState.setTvPipExpanded(true);
         mTvPipBoundsState.setTvPipGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);
         moveAndCheckGravity(KEYCODE_DPAD_DOWN, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, false);
         moveAndCheckGravity(KEYCODE_DPAD_LEFT, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, false);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedRecentTaskInfoTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedRecentTaskInfoTest.kt
index bbd65be..15b73c5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedRecentTaskInfoTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedRecentTaskInfoTest.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.recents
 
 import android.app.ActivityManager
+import android.app.ActivityManager.RecentTaskInfo
 import android.graphics.Rect
 import android.os.Parcel
 import android.testing.AndroidTestingRunner
@@ -33,6 +34,7 @@
 import com.android.wm.shell.util.SplitBounds
 import com.google.common.truth.Correspondence
 import com.google.common.truth.Truth.assertThat
+import org.junit.Assert.assertThrows
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mockito.mock
@@ -86,12 +88,13 @@
 
     @Test
     fun testFreeformTasks_hasCorrectType() {
-        assertThat(freeformTasksGroupInfo().type).isEqualTo(TYPE_FREEFORM)
+        assertThat(freeformTasksGroupInfo(freeformTaskIds = arrayOf(1)).type)
+            .isEqualTo(TYPE_FREEFORM)
     }
 
     @Test
-    fun testSplitTasks_taskInfoList_hasThreeTasks() {
-        val list = freeformTasksGroupInfo().taskInfoList
+    fun testCreateFreeformTasks_hasCorrectNumberOfTasks() {
+        val list = freeformTasksGroupInfo(freeformTaskIds = arrayOf(1, 2, 3)).taskInfoList
         assertThat(list).hasSize(3)
         assertThat(list[0].taskId).isEqualTo(1)
         assertThat(list[1].taskId).isEqualTo(2)
@@ -99,6 +102,16 @@
     }
 
     @Test
+    fun testCreateFreeformTasks_nonExistentMinimizedTaskId_throwsException() {
+        assertThrows(IllegalArgumentException::class.java) {
+            freeformTasksGroupInfo(
+                freeformTaskIds = arrayOf(1, 2, 3),
+                minimizedTaskIds = arrayOf(1, 4)
+            )
+        }
+    }
+
+    @Test
     fun testParcelling_singleTask() {
         val recentTaskInfo = singleTaskGroupInfo()
         val parcel = Parcel.obtain()
@@ -129,7 +142,7 @@
 
     @Test
     fun testParcelling_freeformTasks() {
-        val recentTaskInfo = freeformTasksGroupInfo()
+        val recentTaskInfo = freeformTasksGroupInfo(freeformTaskIds = arrayOf(1, 2, 3))
         val parcel = Parcel.obtain()
         recentTaskInfo.writeToParcel(parcel, 0)
         parcel.setDataPosition(0)
@@ -145,6 +158,21 @@
             .containsExactly(1, 2, 3)
     }
 
+    @Test
+    fun testParcelling_freeformTasks_minimizedTasks() {
+        val recentTaskInfo = freeformTasksGroupInfo(
+            freeformTaskIds = arrayOf(1, 2, 3), minimizedTaskIds = arrayOf(2))
+
+        val parcel = Parcel.obtain()
+        recentTaskInfo.writeToParcel(parcel, 0)
+        parcel.setDataPosition(0)
+
+        // Read the object back from the parcel
+        val recentTaskInfoParcel = CREATOR.createFromParcel(parcel)
+        assertThat(recentTaskInfoParcel.type).isEqualTo(TYPE_FREEFORM)
+        assertThat(recentTaskInfoParcel.minimizedTaskIds).isEqualTo(arrayOf(2).toIntArray())
+    }
+
     private fun createTaskInfo(id: Int) = ActivityManager.RecentTaskInfo().apply {
         taskId = id
         token = WindowContainerToken(mock(IWindowContainerToken::class.java))
@@ -162,10 +190,12 @@
         return GroupedRecentTaskInfo.forSplitTasks(task1, task2, splitBounds)
     }
 
-    private fun freeformTasksGroupInfo(): GroupedRecentTaskInfo {
-        val task1 = createTaskInfo(id = 1)
-        val task2 = createTaskInfo(id = 2)
-        val task3 = createTaskInfo(id = 3)
-        return GroupedRecentTaskInfo.forFreeformTasks(task1, task2, task3)
+    private fun freeformTasksGroupInfo(
+        freeformTaskIds: Array<Int>,
+        minimizedTaskIds: Array<Int> = emptyArray()
+    ): GroupedRecentTaskInfo {
+        return GroupedRecentTaskInfo.forFreeformTasks(
+            freeformTaskIds.map { createTaskInfo(it) }.toTypedArray(),
+            minimizedTaskIds.toSet())
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
index e291c0e..a0aab2e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
@@ -68,7 +68,7 @@
 import com.android.wm.shell.common.DisplayInsetsController;
 import com.android.wm.shell.common.TaskStackListenerImpl;
 import com.android.wm.shell.desktopmode.DesktopModeTaskRepository;
-import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.sysui.ShellCommandHandler;
 import com.android.wm.shell.sysui.ShellController;
 import com.android.wm.shell.sysui.ShellInit;
@@ -399,7 +399,7 @@
     }
 
     @Test
-    public void testGetRecentTasks_proto2Enabled_ignoresMinimizedFreeformTasks() {
+    public void testGetRecentTasks_proto2Enabled_includesMinimizedFreeformTasks() {
         ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
         ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
         ActivityManager.RecentTaskInfo t3 = makeTaskInfo(3);
@@ -415,8 +415,7 @@
         ArrayList<GroupedRecentTaskInfo> recentTasks = mRecentTasksController.getRecentTasks(
                 MAX_VALUE, RECENT_IGNORE_UNAVAILABLE, 0);
 
-        // 2 freeform tasks should be grouped into one, 1 task should be skipped, 3 total recents
-        // entries
+        // 3 freeform tasks should be grouped into one, 2 single tasks, 3 total recents entries
         assertEquals(3, recentTasks.size());
         GroupedRecentTaskInfo freeformGroup = recentTasks.get(0);
         GroupedRecentTaskInfo singleGroup1 = recentTasks.get(1);
@@ -428,9 +427,10 @@
         assertEquals(GroupedRecentTaskInfo.TYPE_SINGLE, singleGroup2.getType());
 
         // Check freeform group entries
-        assertEquals(2, freeformGroup.getTaskInfoList().size());
+        assertEquals(3, freeformGroup.getTaskInfoList().size());
         assertEquals(t1, freeformGroup.getTaskInfoList().get(0));
-        assertEquals(t5, freeformGroup.getTaskInfoList().get(1));
+        assertEquals(t3, freeformGroup.getTaskInfoList().get(1));
+        assertEquals(t5, freeformGroup.getTaskInfoList().get(2));
 
         // Check single entries
         assertEquals(t2, singleGroup1.getTaskInfo1());
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/TaskStackTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/TaskStackTransitionObserverTest.kt
index f959970..0e5efa6 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/TaskStackTransitionObserverTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/TaskStackTransitionObserverTest.kt
@@ -48,7 +48,6 @@
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
 
-
 /**
  * Test class for {@link TaskStackTransitionObserver}
  *
@@ -168,6 +167,80 @@
             .isEqualTo(freeformOpenChange.taskInfo?.windowingMode)
     }
 
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_TASK_STACK_OBSERVER_IN_SHELL)
+    fun transitionMerged_withChange_onlyOpenChangeIsNotified() {
+        val listener = TestListener()
+        val executor = TestShellExecutor()
+        transitionObserver.addTaskStackTransitionObserverListener(listener, executor)
+
+        // Create open transition
+        val change =
+            createChange(
+                WindowManager.TRANSIT_OPEN,
+                createTaskInfo(1, WindowConfiguration.WINDOWING_MODE_FREEFORM)
+            )
+        val transitionInfo =
+            TransitionInfoBuilder(WindowManager.TRANSIT_OPEN, 0).addChange(change).build()
+
+        // create change transition to be merged to above transition
+        val mergedChange =
+            createChange(
+                WindowManager.TRANSIT_CHANGE,
+                createTaskInfo(2, WindowConfiguration.WINDOWING_MODE_FREEFORM)
+            )
+        val mergedTransitionInfo =
+            TransitionInfoBuilder(WindowManager.TRANSIT_CHANGE, 0).addChange(mergedChange).build()
+        val mergedTransition = Mockito.mock(IBinder::class.java)
+
+        callOnTransitionReady(transitionInfo)
+        callOnTransitionReady(mergedTransitionInfo, mergedTransition)
+        callOnTransitionMerged(mergedTransition)
+        callOnTransitionFinished()
+        executor.flushAll()
+
+        assertThat(listener.taskInfoToBeNotified.taskId).isEqualTo(change.taskInfo?.taskId)
+        assertThat(listener.taskInfoToBeNotified.windowingMode)
+            .isEqualTo(change.taskInfo?.windowingMode)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_TASK_STACK_OBSERVER_IN_SHELL)
+    fun transitionMerged_withOpen_lastOpenChangeIsNotified() {
+        val listener = TestListener()
+        val executor = TestShellExecutor()
+        transitionObserver.addTaskStackTransitionObserverListener(listener, executor)
+
+        // Create open transition
+        val change =
+            createChange(
+                WindowManager.TRANSIT_OPEN,
+                createTaskInfo(1, WindowConfiguration.WINDOWING_MODE_FREEFORM)
+            )
+        val transitionInfo =
+            TransitionInfoBuilder(WindowManager.TRANSIT_OPEN, 0).addChange(change).build()
+
+        // create change transition to be merged to above transition
+        val mergedChange =
+            createChange(
+                WindowManager.TRANSIT_OPEN,
+                createTaskInfo(2, WindowConfiguration.WINDOWING_MODE_FREEFORM)
+            )
+        val mergedTransitionInfo =
+            TransitionInfoBuilder(WindowManager.TRANSIT_OPEN, 0).addChange(mergedChange).build()
+        val mergedTransition = Mockito.mock(IBinder::class.java)
+
+        callOnTransitionReady(transitionInfo)
+        callOnTransitionReady(mergedTransitionInfo, mergedTransition)
+        callOnTransitionMerged(mergedTransition)
+        callOnTransitionFinished()
+        executor.flushAll()
+
+        assertThat(listener.taskInfoToBeNotified.taskId).isEqualTo(mergedChange.taskInfo?.taskId)
+        assertThat(listener.taskInfoToBeNotified.windowingMode)
+                .isEqualTo(mergedChange.taskInfo?.windowingMode)
+    }
+
     class TestListener : TaskStackTransitionObserver.TaskStackTransitionObserverListener {
         var taskInfoToBeNotified = ActivityManager.RunningTaskInfo()
 
@@ -179,11 +252,14 @@
     }
 
     /** Simulate calling the onTransitionReady() method */
-    private fun callOnTransitionReady(transitionInfo: TransitionInfo) {
+    private fun callOnTransitionReady(
+        transitionInfo: TransitionInfo,
+        transition: IBinder = mockTransitionBinder
+    ) {
         val startT = Mockito.mock(SurfaceControl.Transaction::class.java)
         val finishT = Mockito.mock(SurfaceControl.Transaction::class.java)
 
-        transitionObserver.onTransitionReady(mockTransitionBinder, transitionInfo, startT, finishT)
+        transitionObserver.onTransitionReady(transition, transitionInfo, startT, finishT)
     }
 
     /** Simulate calling the onTransitionFinished() method */
@@ -191,6 +267,11 @@
         transitionObserver.onTransitionFinished(mockTransitionBinder, false)
     }
 
+    /** Simulate calling the onTransitionMerged() method */
+    private fun callOnTransitionMerged(merged: IBinder, playing: IBinder = mockTransitionBinder) {
+        transitionObserver.onTransitionMerged(merged, playing)
+    }
+
     companion object {
         fun createTaskInfo(taskId: Int, windowingMode: Int): ActivityManager.RunningTaskInfo {
             val taskInfo = ActivityManager.RunningTaskInfo()
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlagsTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlagsTest.kt
new file mode 100644
index 0000000..b1d62f4
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeFlagsTest.kt
@@ -0,0 +1,456 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.shared.desktopmode
+
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
+import android.provider.Settings
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE
+import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY
+import com.android.window.flags.Flags.FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.shared.desktopmode.DesktopModeFlags.Companion.convertToToggleOverrideWithFallback
+import com.android.wm.shell.shared.desktopmode.DesktopModeFlags.DESKTOP_WINDOWING_MODE
+import com.android.wm.shell.shared.desktopmode.DesktopModeFlags.ToggleOverride.OVERRIDE_OFF
+import com.android.wm.shell.shared.desktopmode.DesktopModeFlags.ToggleOverride.OVERRIDE_ON
+import com.android.wm.shell.shared.desktopmode.DesktopModeFlags.ToggleOverride.OVERRIDE_UNSET
+import com.android.wm.shell.shared.desktopmode.DesktopModeFlags.WALLPAPER_ACTIVITY
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * Test class for [DesktopModeFlags]
+ *
+ * Usage: atest WMShellUnitTests:DesktopModeFlagsTest
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class DesktopModeFlagsTest : ShellTestCase() {
+
+  @JvmField @Rule val setFlagsRule = SetFlagsRule()
+
+  @Before
+  fun setUp() {
+    resetCache()
+  }
+
+  // TODO(b/348193756): Add tests
+  // isEnabled_flagNotOverridable_overrideOff_featureFlagOn_returnsTrue and
+  // isEnabled_flagNotOverridable_overrideOn_featureFlagOff_returnsFalse after adding non
+  // overridable flags to DesktopModeFlags.
+
+  @Test
+  @DisableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+  @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_devOptionFlagDisabled_overrideOff_featureFlagOn_returnsTrue() {
+    setOverride(OVERRIDE_OFF.setting)
+
+    // In absence of dev options, follow flag
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+  }
+
+  @Test
+  @DisableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_devOptionFlagDisabled_overrideOn_featureFlagOff_returnsFalse() {
+    setOverride(OVERRIDE_ON.setting)
+
+    // In absence of dev options, follow flag
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_overrideUnset_featureFlagOn_returnsTrue() {
+    setOverride(OVERRIDE_UNSET.setting)
+
+    // For overridableFlag, for unset overrides, follow flag
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+  @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_overrideUnset_featureFlagOff_returnsFalse() {
+    setOverride(OVERRIDE_UNSET.setting)
+
+    // For overridableFlag, for unset overrides, follow flag
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_noOverride_featureFlagOn_returnsTrue() {
+    setOverride(null)
+
+    // For overridableFlag, in absence of overrides, follow flag
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+  @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_noOverride_featureFlagOff_returnsFalse() {
+    setOverride(null)
+
+    // For overridableFlag, in absence of overrides, follow flag
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_unrecognizableOverride_featureFlagOn_returnsTrue() {
+    setOverride(-2)
+
+    // For overridableFlag, for recognizable overrides, follow flag
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+  @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_unrecognizableOverride_featureFlagOff_returnsFalse() {
+    setOverride(-2)
+
+    // For overridableFlag, for recognizable overrides, follow flag
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_overrideOff_featureFlagOn_returnsFalse() {
+    setOverride(OVERRIDE_OFF.setting)
+
+    // For overridableFlag, follow override if they exist
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+  @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_overrideOn_featureFlagOff_returnsTrue() {
+    setOverride(OVERRIDE_ON.setting)
+
+    // For overridableFlag, follow override if they exist
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_overrideOffThenOn_featureFlagOn_returnsFalseAndFalse() {
+    setOverride(OVERRIDE_OFF.setting)
+
+    // For overridableFlag, follow override if they exist
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+
+    setOverride(OVERRIDE_ON.setting)
+
+    // Keep overrides constant through the process
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+  @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_overrideOnThenOff_featureFlagOff_returnsTrueAndTrue() {
+    setOverride(OVERRIDE_ON.setting)
+
+    // For overridableFlag, follow override if they exist
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+
+    setOverride(OVERRIDE_OFF.setting)
+
+    // Keep overrides constant through the process
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+  @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_noSystemProperty_overrideOn_featureFlagOff_returnsTrueAndStoresPropertyOn() {
+    System.clearProperty(SYSTEM_PROPERTY_OVERRIDE_KEY)
+    setOverride(OVERRIDE_ON.setting)
+
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+    // Store System Property if not present
+    assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+        .isEqualTo(OVERRIDE_ON.setting.toString())
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_noSystemProperty_overrideUnset_featureFlagOn_returnsTrueAndStoresPropertyUnset() {
+    System.clearProperty(SYSTEM_PROPERTY_OVERRIDE_KEY)
+    setOverride(OVERRIDE_UNSET.setting)
+
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+    // Store System Property if not present
+    assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+        .isEqualTo(OVERRIDE_UNSET.setting.toString())
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+  @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_noSystemProperty_overrideUnset_featureFlagOff_returnsFalseAndStoresPropertyUnset() {
+    System.clearProperty(SYSTEM_PROPERTY_OVERRIDE_KEY)
+    setOverride(OVERRIDE_UNSET.setting)
+
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+    // Store System Property if not present
+    assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+        .isEqualTo(OVERRIDE_UNSET.setting.toString())
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  @Suppress("ktlint:standard:max-line-length")
+  fun isEnabled_systemPropertyNotInteger_overrideOff_featureFlagOn_returnsFalseAndStoresPropertyOff() {
+    System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, "abc")
+    setOverride(OVERRIDE_OFF.setting)
+
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+    // Store System Property if currently invalid
+    assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+        .isEqualTo(OVERRIDE_OFF.setting.toString())
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  @Suppress("ktlint:standard:max-line-length")
+  fun isEnabled_systemPropertyInvalidInteger_overrideOff_featureFlagOn_returnsFalseAndStoresPropertyOff() {
+    System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, "-2")
+    setOverride(OVERRIDE_OFF.setting)
+
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+    // Store System Property if currently invalid
+    assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+        .isEqualTo(OVERRIDE_OFF.setting.toString())
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_systemPropertyOff_overrideOn_featureFlagOn_returnsFalseAndDoesNotUpdateProperty() {
+    System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, OVERRIDE_OFF.setting.toString())
+    setOverride(OVERRIDE_ON.setting)
+
+    // Have a consistent override until reboot
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isFalse()
+    assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+        .isEqualTo(OVERRIDE_OFF.setting.toString())
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+  @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_systemPropertyOn_overrideOff_featureFlagOff_returnsTrueAndDoesNotUpdateProperty() {
+    System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, OVERRIDE_ON.setting.toString())
+    setOverride(OVERRIDE_OFF.setting)
+
+    // Have a consistent override until reboot
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+    assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+        .isEqualTo(OVERRIDE_ON.setting.toString())
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  @Suppress("ktlint:standard:max-line-length")
+  fun isEnabled_systemPropertyUnset_overrideOff_featureFlagOn_returnsTrueAndDoesNotUpdateProperty() {
+    System.setProperty(SYSTEM_PROPERTY_OVERRIDE_KEY, OVERRIDE_UNSET.setting.toString())
+    setOverride(OVERRIDE_OFF.setting)
+
+    // Have a consistent override until reboot
+    assertThat(DESKTOP_WINDOWING_MODE.isEnabled(mContext)).isTrue()
+    assertThat(System.getProperty(SYSTEM_PROPERTY_OVERRIDE_KEY))
+        .isEqualTo(OVERRIDE_UNSET.setting.toString())
+  }
+
+  @Test
+  @EnableFlags(
+      FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION,
+      FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+      FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun isEnabled_dwFlagEnabled_overrideUnset_featureFlagOn_returnsTrue() {
+    setOverride(OVERRIDE_UNSET.setting)
+
+    // For unset overrides, follow flag
+    assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isTrue()
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun isEnabled_dwFlagEnabled_overrideUnset_featureFlagOff_returnsFalse() {
+    setOverride(OVERRIDE_UNSET.setting)
+
+    // For unset overrides, follow flag
+    assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isFalse()
+  }
+
+  @Test
+  @EnableFlags(
+      FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION,
+      FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+      FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun isEnabled_dwFlagEnabled_overrideOn_featureFlagOn_returnsTrue() {
+    setOverride(OVERRIDE_ON.setting)
+
+    // When toggle override matches its default state (dw flag), don't override flags
+    assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isTrue()
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun isEnabled_dwFlagEnabled_overrideOn_featureFlagOff_returnFalse() {
+    setOverride(OVERRIDE_ON.setting)
+
+    // When toggle override matches its default state (dw flag), don't override flags
+    assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isFalse()
+  }
+
+  @Test
+  @EnableFlags(
+      FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION,
+      FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+      FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun isEnabled_dwFlagEnabled_overrideOff_featureFlagOn_returnsFalse() {
+    setOverride(OVERRIDE_OFF.setting)
+
+    // Follow override if they exist, and is not equal to default toggle state (dw flag)
+    assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isFalse()
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun isEnabled_dwFlagEnabled_overrideOff_featureFlagOff_returnsFalse() {
+    setOverride(OVERRIDE_OFF.setting)
+
+    // Follow override if they exist, and is not equal to default toggle state (dw flag)
+    assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isFalse()
+  }
+
+  @Test
+  @EnableFlags(
+      FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_dwFlagDisabled_overrideUnset_featureFlagOn_returnsTrue() {
+    setOverride(OVERRIDE_UNSET.setting)
+
+    // For unset overrides, follow flag
+    assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isTrue()
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+  @DisableFlags(
+      FLAG_ENABLE_DESKTOP_WINDOWING_MODE, FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun isEnabled_dwFlagDisabled_overrideUnset_featureFlagOff_returnsFalse() {
+    setOverride(OVERRIDE_UNSET.setting)
+
+    // For unset overrides, follow flag
+    assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isFalse()
+  }
+
+  @Test
+  @EnableFlags(
+      FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_dwFlagDisabled_overrideOn_featureFlagOn_returnsTrue() {
+    setOverride(OVERRIDE_ON.setting)
+
+    // Follow override if they exist, and is not equal to default toggle state (dw flag)
+    assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isTrue()
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+  @DisableFlags(
+      FLAG_ENABLE_DESKTOP_WINDOWING_MODE, FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun isEnabled_dwFlagDisabled_overrideOn_featureFlagOff_returnTrue() {
+    setOverride(OVERRIDE_ON.setting)
+
+    // Follow override if they exist, and is not equal to default toggle state (dw flag)
+    assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isTrue()
+  }
+
+  @Test
+  @EnableFlags(
+      FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION, FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+  fun isEnabled_dwFlagDisabled_overrideOff_featureFlagOn_returnsTrue() {
+    setOverride(OVERRIDE_OFF.setting)
+
+    // When toggle override matches its default state (dw flag), don't override flags
+    assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isTrue()
+  }
+
+  @Test
+  @EnableFlags(FLAG_SHOW_DESKTOP_WINDOWING_DEV_OPTION)
+  @DisableFlags(
+      FLAG_ENABLE_DESKTOP_WINDOWING_MODE, FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+  fun isEnabled_dwFlagDisabled_overrideOff_featureFlagOff_returnsFalse() {
+    setOverride(OVERRIDE_OFF.setting)
+
+    // When toggle override matches its default state (dw flag), don't override flags
+    assertThat(WALLPAPER_ACTIVITY.isEnabled(mContext)).isFalse()
+  }
+
+  @Test
+  fun convertToToggleOverrideWithFallback_validInt_returnsToggleOverride() {
+    assertThat(convertToToggleOverrideWithFallback(0, OVERRIDE_UNSET)).isEqualTo(OVERRIDE_OFF)
+    assertThat(convertToToggleOverrideWithFallback(1, OVERRIDE_UNSET)).isEqualTo(OVERRIDE_ON)
+    assertThat(convertToToggleOverrideWithFallback(-1, OVERRIDE_ON)).isEqualTo(OVERRIDE_UNSET)
+  }
+
+  @Test
+  fun convertToToggleOverrideWithFallback_invalidInt_returnsFallback() {
+    assertThat(convertToToggleOverrideWithFallback(2, OVERRIDE_ON)).isEqualTo(OVERRIDE_ON)
+    assertThat(convertToToggleOverrideWithFallback(-2, OVERRIDE_UNSET)).isEqualTo(OVERRIDE_UNSET)
+  }
+
+  private fun setOverride(setting: Int?) {
+    val contentResolver = mContext.contentResolver
+    val key = Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES
+    if (setting == null) {
+      Settings.Global.putString(contentResolver, key, null)
+    } else {
+      Settings.Global.putInt(contentResolver, key, setting)
+    }
+  }
+
+  private fun resetCache() {
+    val cachedToggleOverride =
+      DesktopModeFlags::class.java.getDeclaredField("cachedToggleOverride")
+    cachedToggleOverride.isAccessible = true
+    cachedToggleOverride.set(null, null)
+
+    // Clear override cache stored in System property
+    System.clearProperty(SYSTEM_PROPERTY_OVERRIDE_KEY)
+  }
+
+  private companion object {
+    const val SYSTEM_PROPERTY_OVERRIDE_KEY = "sys.wmshell.desktopmode.dev_toggle_override"
+  }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/OWNERS b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/OWNERS
new file mode 100644
index 0000000..2fabd4a
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/OWNERS
@@ -0,0 +1 @@
+file:/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS
\ No newline at end of file
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 3c387f0..5b95b15 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
@@ -36,6 +36,7 @@
 import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
@@ -49,6 +50,9 @@
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.os.Bundle;
+import android.os.IBinder;
+import android.window.IWindowContainerToken;
+import android.window.WindowContainerToken;
 
 import androidx.test.annotation.UiThreadTest;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -195,10 +199,10 @@
                 PendingIntent.getActivity(mContext, 0, startIntent, FLAG_IMMUTABLE);
 
         mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
-                SPLIT_POSITION_TOP_OR_LEFT, null);
+                SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */);
 
         verify(mStageCoordinator).startIntent(eq(pendingIntent), mIntentCaptor.capture(),
-                eq(SPLIT_POSITION_TOP_OR_LEFT), isNull());
+                eq(SPLIT_POSITION_TOP_OR_LEFT), isNull(), isNull());
         assertEquals(FLAG_ACTIVITY_NO_USER_ACTION,
                 mIntentCaptor.getValue().getFlags() & FLAG_ACTIVITY_NO_USER_ACTION);
     }
@@ -213,19 +217,20 @@
         ActivityManager.RunningTaskInfo topRunningTask =
                 createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, startIntent);
         doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask();
+        doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask(any());
 
         mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
-                SPLIT_POSITION_TOP_OR_LEFT, null);
+                SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */);
 
         verify(mStageCoordinator).startIntent(eq(pendingIntent), mIntentCaptor.capture(),
-                eq(SPLIT_POSITION_TOP_OR_LEFT), isNull());
+                eq(SPLIT_POSITION_TOP_OR_LEFT), isNull(), isNull());
         assertEquals(FLAG_ACTIVITY_MULTIPLE_TASK,
                 mIntentCaptor.getValue().getFlags() & FLAG_ACTIVITY_MULTIPLE_TASK);
     }
 
     @Test
     public void startIntent_multiInstancesNotSupported_startTaskInBackgroundBeforeSplitActivated() {
-        doNothing().when(mSplitScreenController).startTask(anyInt(), anyInt(), any());
+        doNothing().when(mSplitScreenController).startTask(anyInt(), anyInt(), any(), any());
         Intent startIntent = createStartIntent("startActivity");
         PendingIntent pendingIntent =
                 PendingIntent.getActivity(mContext, 0, startIntent, FLAG_IMMUTABLE);
@@ -233,15 +238,16 @@
         ActivityManager.RunningTaskInfo topRunningTask =
                 createTaskInfo(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, startIntent);
         doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask();
+        doReturn(topRunningTask).when(mRecentTasks).getTopRunningTask(any());
         // Put the same component into a task in the background
         ActivityManager.RecentTaskInfo sameTaskInfo = new ActivityManager.RecentTaskInfo();
-        doReturn(sameTaskInfo).when(mRecentTasks).findTaskInBackground(any(), anyInt());
+        doReturn(sameTaskInfo).when(mRecentTasks).findTaskInBackground(any(), anyInt(), any());
 
         mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
-                SPLIT_POSITION_TOP_OR_LEFT, null);
+                SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */);
 
         verify(mStageCoordinator).startTask(anyInt(), eq(SPLIT_POSITION_TOP_OR_LEFT),
-                isNull());
+                isNull(), isNull());
         verify(mMultiInstanceHelper, never()).supportsMultiInstanceSplit(any());
         verify(mStageCoordinator, never()).switchSplitPosition(any());
     }
@@ -249,7 +255,7 @@
     @Test
     public void startIntent_multiInstancesSupported_startTaskInBackgroundAfterSplitActivated() {
         doReturn(true).when(mMultiInstanceHelper).supportsMultiInstanceSplit(any());
-        doNothing().when(mSplitScreenController).startTask(anyInt(), anyInt(), any());
+        doNothing().when(mSplitScreenController).startTask(anyInt(), anyInt(), any(), any());
         Intent startIntent = createStartIntent("startActivity");
         PendingIntent pendingIntent =
                 PendingIntent.getActivity(mContext, 0, startIntent, FLAG_IMMUTABLE);
@@ -261,13 +267,13 @@
                 SPLIT_POSITION_BOTTOM_OR_RIGHT);
         // Put the same component into a task in the background
         doReturn(new ActivityManager.RecentTaskInfo()).when(mRecentTasks)
-                .findTaskInBackground(any(), anyInt());
+                .findTaskInBackground(any(), anyInt(), any());
 
         mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
-                SPLIT_POSITION_TOP_OR_LEFT, null);
+                SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */);
         verify(mMultiInstanceHelper, never()).supportsMultiInstanceSplit(any());
         verify(mStageCoordinator).startTask(anyInt(), eq(SPLIT_POSITION_TOP_OR_LEFT),
-                isNull());
+                isNull(), isNull());
     }
 
     @Test
@@ -284,7 +290,7 @@
                 SPLIT_POSITION_BOTTOM_OR_RIGHT);
 
         mSplitScreenController.startIntent(pendingIntent, mContext.getUserId(), null,
-                SPLIT_POSITION_TOP_OR_LEFT, null);
+                SPLIT_POSITION_TOP_OR_LEFT, null /* options */, null /* hideTaskToken */);
 
         verify(mStageCoordinator).switchSplitPosition(anyString());
     }
@@ -312,6 +318,7 @@
         info.supportsMultiWindow = true;
         info.baseIntent = strIntent;
         info.baseActivity = strIntent.getComponent();
+        info.token = new WindowContainerToken(mock(IWindowContainerToken.class));
         ActivityInfo activityInfo = new ActivityInfo();
         activityInfo.packageName = info.baseActivity.getPackageName();
         activityInfo.name = info.baseActivity.getClassName();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ChangeBuilder.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ChangeBuilder.java
new file mode 100644
index 0000000..b54c3bf
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ChangeBuilder.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transition;
+
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+
+import static org.mockito.Mockito.mock;
+
+import android.app.ActivityManager.RunningTaskInfo;
+import android.view.Surface;
+import android.view.SurfaceControl;
+import android.view.WindowManager;
+import android.window.TransitionInfo;
+
+public class ChangeBuilder {
+    final TransitionInfo.Change mChange;
+
+    ChangeBuilder(@WindowManager.TransitionType int mode) {
+        mChange = new TransitionInfo.Change(null /* token */, createMockSurface(true));
+        mChange.setMode(mode);
+    }
+
+    ChangeBuilder setFlags(@TransitionInfo.ChangeFlags int flags) {
+        mChange.setFlags(flags);
+        return this;
+    }
+
+    ChangeBuilder setTask(RunningTaskInfo taskInfo) {
+        mChange.setTaskInfo(taskInfo);
+        return this;
+    }
+
+    ChangeBuilder setRotate(int anim) {
+        return setRotate(Surface.ROTATION_90, anim);
+    }
+
+    ChangeBuilder setRotate() {
+        return setRotate(ROTATION_ANIMATION_UNSPECIFIED);
+    }
+
+    ChangeBuilder setRotate(@Surface.Rotation int target, int anim) {
+        mChange.setRotation(Surface.ROTATION_0, target);
+        mChange.setRotationAnimation(anim);
+        return this;
+    }
+
+    TransitionInfo.Change build() {
+        return mChange;
+    }
+
+    private static SurfaceControl createMockSurface(boolean valid) {
+        SurfaceControl sc = mock(SurfaceControl.class);
+        doReturn(valid).when(sc).isValid();
+        return sc;
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/DefaultTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/DefaultTransitionHandlerTest.java
new file mode 100644
index 0000000..754a173
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/DefaultTransitionHandlerTest.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transition;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.WindowManager.TRANSIT_OPEN;
+import static android.view.WindowManager.TRANSIT_SLEEP;
+import static android.view.WindowManager.TRANSIT_TO_BACK;
+import static android.window.TransitionInfo.FLAG_SYNC;
+import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.app.ActivityManager.RunningTaskInfo;
+import android.content.Context;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.view.SurfaceControl;
+import android.window.TransitionInfo;
+import android.window.WindowContainerToken;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
+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.TransactionPool;
+import com.android.wm.shell.sysui.ShellInit;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for the default animation handler that is used if no other special-purpose handler picks
+ * up an animation request.
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:DefaultTransitionHandlerTest
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class DefaultTransitionHandlerTest extends ShellTestCase {
+
+    private final Context mContext =
+            InstrumentationRegistry.getInstrumentation().getTargetContext();
+
+    private final DisplayController mDisplayController = mock(DisplayController.class);
+    private final TransactionPool mTransactionPool = new MockTransactionPool();
+    private final TestShellExecutor mMainExecutor = new TestShellExecutor();
+    private final TestShellExecutor mAnimExecutor = new TestShellExecutor();
+    private final Handler mMainHandler = new Handler(Looper.getMainLooper());
+
+    private ShellInit mShellInit;
+    private RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
+    private DefaultTransitionHandler mTransitionHandler;
+
+    @Before
+    public void setUp() {
+        mShellInit = new ShellInit(mMainExecutor);
+        mRootTaskDisplayAreaOrganizer = new RootTaskDisplayAreaOrganizer(
+                mMainExecutor,
+                mContext,
+                mShellInit);
+        mTransitionHandler = new DefaultTransitionHandler(
+                mContext, mShellInit, mDisplayController,
+                mTransactionPool, mMainExecutor, mMainHandler, mAnimExecutor,
+                mRootTaskDisplayAreaOrganizer);
+        mShellInit.init();
+    }
+
+    @After
+    public void tearDown() {
+        flushHandlers();
+    }
+
+    private void flushHandlers() {
+        mMainHandler.runWithScissors(() -> {
+            mAnimExecutor.flushAll();
+            mMainExecutor.flushAll();
+        }, 1000L);
+    }
+
+    @Test
+    public void testAnimationBackgroundCreatedForTaskTransition() {
+        final TransitionInfo.Change openTask = new ChangeBuilder(TRANSIT_OPEN)
+                .setTask(createTaskInfo(1))
+                .build();
+        final TransitionInfo.Change closeTask = new ChangeBuilder(TRANSIT_TO_BACK)
+                .setTask(createTaskInfo(2))
+                .build();
+
+        final IBinder token = new Binder();
+        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN)
+                .addChange(openTask)
+                .addChange(closeTask)
+                .build();
+        final SurfaceControl.Transaction startT = MockTransactionPool.create();
+        final SurfaceControl.Transaction finishT = MockTransactionPool.create();
+
+        mTransitionHandler.startAnimation(token, info, startT, finishT,
+                mock(Transitions.TransitionFinishCallback.class));
+
+        mergeSync(mTransitionHandler, token);
+        flushHandlers();
+
+        verify(startT).setColor(any(), any());
+    }
+
+    @Test
+    public void testNoAnimationBackgroundForTranslucentTasks() {
+        final TransitionInfo.Change openTask = new ChangeBuilder(TRANSIT_OPEN)
+                .setTask(createTaskInfo(1))
+                .setFlags(FLAG_TRANSLUCENT)
+                .build();
+        final TransitionInfo.Change closeTask = new ChangeBuilder(TRANSIT_TO_BACK)
+                .setTask(createTaskInfo(2))
+                .setFlags(FLAG_TRANSLUCENT)
+                .build();
+
+        final IBinder token = new Binder();
+        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN)
+                .addChange(openTask)
+                .addChange(closeTask)
+                .build();
+        final SurfaceControl.Transaction startT = MockTransactionPool.create();
+        final SurfaceControl.Transaction finishT = MockTransactionPool.create();
+
+        mTransitionHandler.startAnimation(token, info, startT, finishT,
+                mock(Transitions.TransitionFinishCallback.class));
+
+        mergeSync(mTransitionHandler, token);
+        flushHandlers();
+
+        verify(startT, never()).setColor(any(), any());
+    }
+
+    @Test
+    public void testNoAnimationBackgroundForWallpapers() {
+        final TransitionInfo.Change openWallpaper = new ChangeBuilder(TRANSIT_OPEN)
+                .setFlags(TransitionInfo.FLAG_IS_WALLPAPER)
+                .build();
+        final TransitionInfo.Change closeWallpaper = new ChangeBuilder(TRANSIT_TO_BACK)
+                .setFlags(TransitionInfo.FLAG_IS_WALLPAPER)
+                .build();
+
+        final IBinder token = new Binder();
+        final TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN)
+                .addChange(openWallpaper)
+                .addChange(closeWallpaper)
+                .build();
+        final SurfaceControl.Transaction startT = MockTransactionPool.create();
+        final SurfaceControl.Transaction finishT = MockTransactionPool.create();
+
+        mTransitionHandler.startAnimation(token, info, startT, finishT,
+                mock(Transitions.TransitionFinishCallback.class));
+
+        mergeSync(mTransitionHandler, token);
+        flushHandlers();
+
+        verify(startT, never()).setColor(any(), any());
+    }
+
+    private static void mergeSync(Transitions.TransitionHandler handler, IBinder token) {
+        handler.mergeAnimation(
+                new Binder(),
+                new TransitionInfoBuilder(TRANSIT_SLEEP, FLAG_SYNC).build(),
+                MockTransactionPool.create(),
+                token,
+                mock(Transitions.TransitionFinishCallback.class));
+    }
+
+    private static RunningTaskInfo createTaskInfo(int taskId) {
+        RunningTaskInfo taskInfo = new RunningTaskInfo();
+        taskInfo.taskId = taskId;
+        taskInfo.topActivityType = ACTIVITY_TYPE_STANDARD;
+        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        taskInfo.configuration.windowConfiguration.setActivityType(taskInfo.topActivityType);
+        taskInfo.token = mock(WindowContainerToken.class);
+        return taskInfo;
+    }
+}
+
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/MockTransactionPool.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/MockTransactionPool.java
new file mode 100644
index 0000000..574a87a
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/MockTransactionPool.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.transition;
+
+import static org.mockito.Mockito.RETURNS_SELF;
+import static org.mockito.Mockito.mock;
+
+import android.view.SurfaceControl;
+
+import com.android.wm.shell.common.TransactionPool;
+import com.android.wm.shell.util.StubTransaction;
+
+public class MockTransactionPool extends TransactionPool {
+
+    public static SurfaceControl.Transaction create() {
+        return mock(StubTransaction.class, RETURNS_SELF);
+    }
+
+    @Override
+    public SurfaceControl.Transaction acquire() {
+        return create();
+    }
+
+    @Override
+    public void release(SurfaceControl.Transaction t) {
+    }
+}
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 964d86e..409b877 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,7 +79,6 @@
 import android.view.IRecentsAnimationRunner;
 import android.view.Surface;
 import android.view.SurfaceControl;
-import android.view.WindowManager;
 import android.window.IRemoteTransition;
 import android.window.IRemoteTransitionFinishedCallback;
 import android.window.IWindowContainerToken;
@@ -1614,43 +1613,6 @@
                 eq(R.styleable.WindowAnimation_activityCloseEnterAnimation), anyBoolean());
     }
 
-    class ChangeBuilder {
-        final TransitionInfo.Change mChange;
-
-        ChangeBuilder(@WindowManager.TransitionType int mode) {
-            mChange = new TransitionInfo.Change(null /* token */, createMockSurface(true));
-            mChange.setMode(mode);
-        }
-
-        ChangeBuilder setFlags(@TransitionInfo.ChangeFlags int flags) {
-            mChange.setFlags(flags);
-            return this;
-        }
-
-        ChangeBuilder setTask(RunningTaskInfo taskInfo) {
-            mChange.setTaskInfo(taskInfo);
-            return this;
-        }
-
-        ChangeBuilder setRotate(int anim) {
-            return setRotate(Surface.ROTATION_90, anim);
-        }
-
-        ChangeBuilder setRotate() {
-            return setRotate(ROTATION_ANIMATION_UNSPECIFIED);
-        }
-
-        ChangeBuilder setRotate(@Surface.Rotation int target, int anim) {
-            mChange.setRotation(Surface.ROTATION_0, target);
-            mChange.setRotationAnimation(anim);
-            return this;
-        }
-
-        TransitionInfo.Change build() {
-            return mChange;
-        }
-    }
-
     class TestTransitionHandler implements Transitions.TransitionHandler {
         ArrayList<Pair<IBinder, Transitions.TransitionFinishCallback>> mFinishes =
                 new ArrayList<>();
@@ -1739,12 +1701,6 @@
                 .addChange(TRANSIT_OPEN).addChange(TRANSIT_CLOSE).build();
     }
 
-    private static SurfaceControl createMockSurface(boolean valid) {
-        SurfaceControl sc = mock(SurfaceControl.class);
-        doReturn(valid).when(sc).isValid();
-        return sc;
-    }
-
     private static RunningTaskInfo createTaskInfo(int taskId, int windowingMode, int activityType) {
         RunningTaskInfo taskInfo = new RunningTaskInfo();
         taskInfo.taskId = taskId;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index ca1e3f1..b1803e9 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -55,6 +55,7 @@
 import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
 import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
 import com.android.dx.mockito.inline.extended.StaticMockitoSession
+import com.android.internal.jank.InteractionJankMonitor
 import com.android.window.flags.Flags
 import com.android.wm.shell.R
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer
@@ -67,14 +68,16 @@
 import com.android.wm.shell.common.ShellExecutor
 import com.android.wm.shell.common.SyncTransactionQueue
 import com.android.wm.shell.desktopmode.DesktopTasksController
+import com.android.wm.shell.desktopmode.DesktopTasksController.SnapPosition
 import com.android.wm.shell.freeform.FreeformTaskTransitionStarter
-import com.android.wm.shell.shared.DesktopModeStatus
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
 import com.android.wm.shell.sysui.KeyguardChangeListener
 import com.android.wm.shell.sysui.ShellCommandHandler
 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.windowdecor.DesktopModeWindowDecorViewModel.DesktopModeOnInsetsChangedListener
+import com.android.wm.shell.windowdecor.common.OnTaskActionClickListener
 import java.util.Optional
 import java.util.function.Supplier
 import org.junit.Assert.assertEquals
@@ -82,6 +85,7 @@
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
 import org.mockito.Mock
 import org.mockito.Mockito
 import org.mockito.Mockito.anyInt
@@ -131,6 +135,7 @@
     @Mock private lateinit var mockRootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
     @Mock private lateinit var mockShellCommandHandler: ShellCommandHandler
     @Mock private lateinit var mockWindowManager: IWindowManager
+    @Mock private lateinit var mockInteractionJankMonitor: InteractionJankMonitor
 
     private val transactionFactory = Supplier<SurfaceControl.Transaction> {
         SurfaceControl.Transaction()
@@ -164,7 +169,7 @@
                 mockInputMonitorFactory,
                 transactionFactory,
                 mockRootTaskDisplayAreaOrganizer,
-            windowDecorByTaskIdSpy
+            windowDecorByTaskIdSpy, mockInteractionJankMonitor
         )
 
         whenever(mockDisplayController.getDisplayLayout(any())).thenReturn(mockDisplayLayout)
@@ -343,10 +348,35 @@
     }
 
     @Test
-    fun testDecorationIsNotCreatedForTopTranslucentActivities() {
-        setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+    fun testDecorationIsCreatedForTopTranslucentActivitiesWithStyleFloating() {
+        val mockitoSession: StaticMockitoSession = mockitoSession()
+                .strictness(Strictness.LENIENT)
+                .spyStatic(DesktopModeStatus::class.java)
+                .startMocking()
+        try {
+            val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true).apply {
+                isTopActivityTransparent = true
+                isTopActivityStyleFloating = true
+                numActivities = 1
+            }
+            doReturn(true).`when` { DesktopModeStatus.canEnterDesktopMode(any()) }
+            setUpMockDecorationsForTasks(task)
+
+            onTaskOpening(task)
+            verify(mockDesktopModeWindowDecorFactory)
+                    .create(any(), any(), any(), eq(task), any(), any(), any(), any(), any())
+        } finally {
+            mockitoSession.finishMocking()
+        }
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
+    fun testDecorationIsNotCreatedForTopTranslucentActivitiesWithoutStyleFloating() {
         val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true).apply {
             isTopActivityTransparent = true
+            isTopActivityStyleFloating = false
             numActivities = 1
         }
         onTaskOpening(task)
@@ -356,6 +386,7 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY)
     fun testDecorationIsNotCreatedForSystemUIActivities() {
         val task = createTask(windowingMode = WINDOWING_MODE_FULLSCREEN, focused = true)
 
@@ -518,6 +549,99 @@
         }
     }
 
+    @Test
+    fun testOnDecorMaximizedOrRestored_togglesTaskSize() {
+        val decor = setUpMockDecorationForTask(createTask(windowingMode = WINDOWING_MODE_FREEFORM))
+        onTaskOpening(decor.mTaskInfo)
+        val maxOrRestoreListener = ArgumentCaptor.forClass(OnTaskActionClickListener::class.java)
+            .let { captor ->
+                verify(decor).setOnMaximizeOrRestoreClickListener(captor.capture())
+                return@let captor.value
+            }
+
+        maxOrRestoreListener.onClick(decor.mTaskInfo.taskId, "test")
+
+        verify(mockDesktopTasksController).toggleDesktopTaskSize(decor.mTaskInfo)
+    }
+
+    @Test
+    fun testOnDecorMaximizedOrRestored_closesMenus() {
+        val decor = setUpMockDecorationForTask(createTask(windowingMode = WINDOWING_MODE_FREEFORM))
+        onTaskOpening(decor.mTaskInfo)
+        val maxOrRestoreListener = ArgumentCaptor.forClass(OnTaskActionClickListener::class.java)
+            .let { captor ->
+                verify(decor).setOnMaximizeOrRestoreClickListener(captor.capture())
+                return@let captor.value
+            }
+
+        maxOrRestoreListener.onClick(decor.mTaskInfo.taskId, "test")
+
+        verify(decor).closeHandleMenu()
+        verify(decor).closeMaximizeMenu()
+    }
+
+    @Test
+    fun testOnDecorSnappedLeft_snapResizes() {
+        val decor = setUpMockDecorationForTask(createTask(windowingMode = WINDOWING_MODE_FREEFORM))
+        onTaskOpening(decor.mTaskInfo)
+        val snapLeftListener = ArgumentCaptor.forClass(OnTaskActionClickListener::class.java)
+            .let { captor ->
+                verify(decor).setOnLeftSnapClickListener(captor.capture())
+                return@let captor.value
+            }
+
+        snapLeftListener.onClick(decor.mTaskInfo.taskId, "test")
+
+        verify(mockDesktopTasksController).snapToHalfScreen(decor.mTaskInfo, SnapPosition.LEFT)
+    }
+
+    @Test
+    fun testOnDecorSnappedLeft_closeMenus() {
+        val decor = setUpMockDecorationForTask(createTask(windowingMode = WINDOWING_MODE_FREEFORM))
+        onTaskOpening(decor.mTaskInfo)
+        val snapLeftListener = ArgumentCaptor.forClass(OnTaskActionClickListener::class.java)
+            .let { captor ->
+                verify(decor).setOnLeftSnapClickListener(captor.capture())
+                return@let captor.value
+            }
+
+        snapLeftListener.onClick(decor.mTaskInfo.taskId, "test")
+
+        verify(decor).closeHandleMenu()
+        verify(decor).closeMaximizeMenu()
+    }
+
+    @Test
+    fun testOnDecorSnappedRight_snapResizes() {
+        val decor = setUpMockDecorationForTask(createTask(windowingMode = WINDOWING_MODE_FREEFORM))
+        onTaskOpening(decor.mTaskInfo)
+        val snapLeftListener = ArgumentCaptor.forClass(OnTaskActionClickListener::class.java)
+            .let { captor ->
+                verify(decor).setOnRightSnapClickListener(captor.capture())
+                return@let captor.value
+            }
+
+        snapLeftListener.onClick(decor.mTaskInfo.taskId, "test")
+
+        verify(mockDesktopTasksController).snapToHalfScreen(decor.mTaskInfo, SnapPosition.RIGHT)
+    }
+
+    @Test
+    fun testOnDecorSnappedRight_closeMenus() {
+        val decor = setUpMockDecorationForTask(createTask(windowingMode = WINDOWING_MODE_FREEFORM))
+        onTaskOpening(decor.mTaskInfo)
+        val snapLeftListener = ArgumentCaptor.forClass(OnTaskActionClickListener::class.java)
+            .let { captor ->
+                verify(decor).setOnRightSnapClickListener(captor.capture())
+                return@let captor.value
+            }
+
+        snapLeftListener.onClick(decor.mTaskInfo.taskId, "test")
+
+        verify(decor).closeHandleMenu()
+        verify(decor).closeMaximizeMenu()
+    }
+
     private fun onTaskOpening(task: RunningTaskInfo, leash: SurfaceControl = SurfaceControl()) {
         desktopModeWindowDecorViewModel.onTaskOpening(
                 task,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
index 46c1589..d860609 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorationTests.java
@@ -24,9 +24,15 @@
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
 import static com.android.wm.shell.MockSurfaceControlHelper.createMockSurfaceControlTransaction;
+import static com.android.wm.shell.windowdecor.DesktopModeWindowDecoration.CLOSE_MAXIMIZE_MENU_DELAY_MS;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doReturn;
@@ -38,11 +44,14 @@
 
 import android.app.ActivityManager;
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
+import android.graphics.PointF;
+import android.net.Uri;
 import android.os.Handler;
 import android.os.SystemProperties;
 import android.platform.test.annotations.DisableFlags;
@@ -62,6 +71,7 @@
 import android.view.WindowManager;
 import android.window.WindowContainerTransaction;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.test.filters.SmallTest;
 
@@ -74,8 +84,12 @@
 import com.android.wm.shell.TestRunningTaskInfoBuilder;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.windowdecor.WindowDecoration.RelayoutParams;
+import com.android.wm.shell.windowdecor.common.OnTaskActionClickListener;
+
+import kotlin.Unit;
+import kotlin.jvm.functions.Function1;
 
 import org.junit.After;
 import org.junit.Before;
@@ -84,6 +98,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.quality.Strictness;
 
@@ -105,6 +120,8 @@
     private static final String USE_ROUNDED_CORNERS_SYSPROP_KEY =
             "persist.wm.debug.desktop_use_rounded_corners";
 
+    private static final Uri TEST_URI = Uri.parse("www.google.com");
+
     @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
 
     @Mock
@@ -112,8 +129,6 @@
     @Mock
     private ShellTaskOrganizer mMockShellTaskOrganizer;
     @Mock
-    private Handler mMockHandler;
-    @Mock
     private Choreographer mMockChoreographer;
     @Mock
     private SyncTransactionQueue mMockSyncQueue;
@@ -131,13 +146,20 @@
     private WindowDecoration.SurfaceControlViewHostFactory mMockSurfaceControlViewHostFactory;
     @Mock
     private TypedArray mMockRoundedCornersRadiusArray;
-
     @Mock
     private TestTouchEventListener mMockTouchEventListener;
     @Mock
     private DesktopModeWindowDecoration.ExclusionRegionListener mMockExclusionRegionListener;
     @Mock
     private PackageManager mMockPackageManager;
+    @Mock
+    private Handler mMockHandler;
+    @Mock
+    private DesktopModeWindowDecoration.OpenInBrowserClickListener mMockOpenInBrowserClickListener;
+    @Captor
+    private ArgumentCaptor<Function1<Boolean, Unit>> mOnMaxMenuHoverChangeListener;
+    @Captor
+    private ArgumentCaptor<Runnable> mCloseMaxMenuRunnable;
 
     private final InsetsState mInsetsState = new InsetsState();
     private SurfaceControl.Transaction mMockTransaction;
@@ -154,7 +176,7 @@
     }
 
     @Before
-    public void setUp() {
+    public void setUp() throws PackageManager.NameNotFoundException {
         mMockitoSession = mockitoSession()
                 .strictness(Strictness.LENIENT)
                 .spyStatic(DesktopModeStatus.class)
@@ -170,6 +192,9 @@
         mTestableContext.ensureTestableResources();
         mContext.setMockPackageManager(mMockPackageManager);
         when(mMockPackageManager.getApplicationLabel(any())).thenReturn("applicationLabel");
+        final ActivityInfo activityInfo = new ActivityInfo();
+        activityInfo.applicationInfo = new ApplicationInfo();
+        when(mMockPackageManager.getActivityInfo(any(), anyInt())).thenReturn(activityInfo);
         final Display defaultDisplay = mock(Display.class);
         doReturn(defaultDisplay).when(mMockDisplayController).getDisplay(Display.DEFAULT_DISPLAY);
         doReturn(mInsetsState).when(mMockDisplayController).getInsetsState(anyInt());
@@ -459,6 +484,151 @@
         verify(mMockHandler).removeCallbacks(runnableArgument.getValue());
     }
 
+    @Test
+    public void createMaximizeMenu_showsMenu() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+        final MaximizeMenu menu = mock(MaximizeMenu.class);
+        final DesktopModeWindowDecoration decoration = createWindowDecoration(taskInfo,
+                new FakeMaximizeMenuFactory(menu));
+        assertFalse(decoration.isMaximizeMenuActive());
+
+        createMaximizeMenu(decoration, menu);
+
+        assertTrue(decoration.isMaximizeMenuActive());
+    }
+
+    @Test
+    public void maximizeMenu_unHoversMenu_schedulesCloseMenu() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+        final MaximizeMenu menu = mock(MaximizeMenu.class);
+        final DesktopModeWindowDecoration decoration = createWindowDecoration(taskInfo,
+                new FakeMaximizeMenuFactory(menu));
+        decoration.setAppHeaderMaximizeButtonHovered(false);
+        createMaximizeMenu(decoration, menu);
+
+        mOnMaxMenuHoverChangeListener.getValue().invoke(false);
+
+        verify(mMockHandler)
+                .postDelayed(mCloseMaxMenuRunnable.capture(), eq(CLOSE_MAXIMIZE_MENU_DELAY_MS));
+
+        mCloseMaxMenuRunnable.getValue().run();
+        verify(menu).close();
+        assertFalse(decoration.isMaximizeMenuActive());
+    }
+
+    @Test
+    public void maximizeMenu_unHoversButton_schedulesCloseMenu() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+        final MaximizeMenu menu = mock(MaximizeMenu.class);
+        final DesktopModeWindowDecoration decoration = createWindowDecoration(taskInfo,
+                new FakeMaximizeMenuFactory(menu));
+        decoration.setAppHeaderMaximizeButtonHovered(true);
+        createMaximizeMenu(decoration, menu);
+
+        decoration.setAppHeaderMaximizeButtonHovered(false);
+
+        verify(mMockHandler)
+                .postDelayed(mCloseMaxMenuRunnable.capture(), eq(CLOSE_MAXIMIZE_MENU_DELAY_MS));
+
+        mCloseMaxMenuRunnable.getValue().run();
+        verify(menu).close();
+        assertFalse(decoration.isMaximizeMenuActive());
+    }
+
+    @Test
+    public void maximizeMenu_hoversMenu_cancelsCloseMenu() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+        final MaximizeMenu menu = mock(MaximizeMenu.class);
+        final DesktopModeWindowDecoration decoration = createWindowDecoration(taskInfo,
+                new FakeMaximizeMenuFactory(menu));
+        createMaximizeMenu(decoration, menu);
+
+        mOnMaxMenuHoverChangeListener.getValue().invoke(true);
+
+        verify(mMockHandler).removeCallbacks(any());
+    }
+
+    @Test
+    public void maximizeMenu_hoversButton_cancelsCloseMenu() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+        final MaximizeMenu menu = mock(MaximizeMenu.class);
+        final DesktopModeWindowDecoration decoration = createWindowDecoration(taskInfo,
+                new FakeMaximizeMenuFactory(menu));
+        createMaximizeMenu(decoration, menu);
+
+        decoration.setAppHeaderMaximizeButtonHovered(true);
+
+        verify(mMockHandler).removeCallbacks(any());
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB)
+    public void capturedLink_postsOnCapturedLinkExpiredRunnable() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+        final ArgumentCaptor<Runnable> runnableArgument = ArgumentCaptor.forClass(Runnable.class);
+        final DesktopModeWindowDecoration decor = createWindowDecoration(taskInfo);
+
+        decor.relayout(taskInfo);
+        // Assert captured link is set
+        assertTrue(decor.browserLinkAvailable());
+        // Asset runnable posted to set captured link to expired
+        verify(mMockHandler).postDelayed(runnableArgument.capture(), anyLong());
+        runnableArgument.getValue().run();
+        assertFalse(decor.browserLinkAvailable());
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB)
+    public void capturedLink_capturedLinkNotResetToSameLink() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+        final DesktopModeWindowDecoration decor = createWindowDecoration(taskInfo);
+        final ArgumentCaptor<Runnable> runnableArgument = ArgumentCaptor.forClass(Runnable.class);
+
+        // Set captured link and run on captured link expired runnable
+        decor.relayout(taskInfo);
+        verify(mMockHandler).postDelayed(runnableArgument.capture(), anyLong());
+        runnableArgument.getValue().run();
+
+        decor.relayout(taskInfo);
+        // Assert captured link not set to same value twice
+        assertFalse(decor.browserLinkAvailable());
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB)
+    public void capturedLink_capturedLinkExpiresAfterClick() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+        final DesktopModeWindowDecoration decor = createWindowDecoration(taskInfo);
+
+        decor.relayout(taskInfo);
+        // Assert captured link is set
+        assertTrue(decor.browserLinkAvailable());
+        decor.onOpenInBrowserClick();
+        //Assert Captured link expires after button is clicked
+        assertFalse(decor.browserLinkAvailable());
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_APP_TO_WEB)
+    public void capturedLink_openInBrowserListenerCalledOnClick() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(true /* visible */);
+        final DesktopModeWindowDecoration decor = createWindowDecoration(taskInfo);
+
+        decor.relayout(taskInfo);
+        decor.onOpenInBrowserClick();
+
+        verify(mMockOpenInBrowserClickListener).onClick(any(), any());
+    }
+
+    private void createMaximizeMenu(DesktopModeWindowDecoration decoration, MaximizeMenu menu) {
+        final OnTaskActionClickListener l = (taskId, tag) -> {};
+        decoration.setOnMaximizeOrRestoreClickListener(l);
+        decoration.setOnLeftSnapClickListener(l);
+        decoration.setOnRightSnapClickListener(l);
+        decoration.createMaximizeMenu();
+        verify(menu).show(any(), any(), any(), mOnMaxMenuHoverChangeListener.capture());
+    }
+
     private void fillRoundedCornersResources(int fillValue) {
         when(mMockRoundedCornersRadiusArray.getDimensionPixelSize(anyInt(), anyInt()))
                 .thenReturn(fillValue);
@@ -479,15 +649,22 @@
 
     private DesktopModeWindowDecoration createWindowDecoration(
             ActivityManager.RunningTaskInfo taskInfo) {
-        DesktopModeWindowDecoration windowDecor = new DesktopModeWindowDecoration(mContext,
+        return createWindowDecoration(taskInfo, new FakeMaximizeMenuFactory());
+    }
+
+    private DesktopModeWindowDecoration createWindowDecoration(
+            ActivityManager.RunningTaskInfo taskInfo,
+            MaximizeMenuFactory maximizeMenuFactory) {
+        final DesktopModeWindowDecoration windowDecor = new DesktopModeWindowDecoration(mContext,
                 mMockDisplayController, mMockShellTaskOrganizer, taskInfo, mMockSurfaceControl,
                 mMockHandler, mMockChoreographer, mMockSyncQueue, mMockRootTaskDisplayAreaOrganizer,
                 SurfaceControl.Builder::new, mMockTransactionSupplier,
                 WindowContainerTransaction::new, SurfaceControl::new,
-                mMockSurfaceControlViewHostFactory);
+                mMockSurfaceControlViewHostFactory, maximizeMenuFactory);
         windowDecor.setCaptionListeners(mMockTouchEventListener, mMockTouchEventListener,
                 mMockTouchEventListener, mMockTouchEventListener);
         windowDecor.setExclusionRegionListener(mMockExclusionRegionListener);
+        windowDecor.setOpenInBrowserClickListener(mMockOpenInBrowserClickListener);
         return windowDecor;
     }
 
@@ -499,12 +676,12 @@
                 .setTaskDescriptionBuilder(taskDescriptionBuilder)
                 .setVisible(visible)
                 .build();
-        taskInfo.topActivityInfo = new ActivityInfo();
-        taskInfo.topActivityInfo.applicationInfo = new ApplicationInfo();
         taskInfo.realActivity = new ComponentName("com.android.wm.shell.windowdecor",
                 "DesktopModeWindowDecorationTests");
         taskInfo.baseActivity = new ComponentName("com.android.wm.shell.windowdecor",
                 "DesktopModeWindowDecorationTests");
+        taskInfo.capturedLink = TEST_URI;
+        taskInfo.capturedLinkTimestamp = System.currentTimeMillis();
         return taskInfo;
 
     }
@@ -541,4 +718,27 @@
             return false;
         }
     }
+
+    private static final class FakeMaximizeMenuFactory implements MaximizeMenuFactory {
+        private final MaximizeMenu mMaximizeMenu;
+
+        FakeMaximizeMenuFactory() {
+            this(mock(MaximizeMenu.class));
+        }
+
+        FakeMaximizeMenuFactory(MaximizeMenu menu) {
+            mMaximizeMenu = menu;
+        }
+
+        @NonNull
+        @Override
+        public MaximizeMenu create(@NonNull SyncTransactionQueue syncQueue,
+                @NonNull RootTaskDisplayAreaOrganizer rootTdaOrganizer,
+                @NonNull DisplayController displayController,
+                @NonNull ActivityManager.RunningTaskInfo taskInfo,
+                @NonNull Context decorWindowContext, @NonNull PointF menuPosition,
+                @NonNull Supplier<SurfaceControl.Transaction> transactionSupplier) {
+            return mMaximizeMenu;
+        }
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
index f750e6b..e529711 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragPositioningCallbackUtilityTest.kt
@@ -21,27 +21,35 @@
 import android.graphics.PointF
 import android.graphics.Rect
 import android.os.IBinder
+import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
 import android.testing.AndroidTestingRunner
 import android.view.Display
 import android.window.WindowContainerToken
+import com.android.dx.mockito.inline.extended.ExtendedMockito
+import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
+import com.android.dx.mockito.inline.extended.StaticMockitoSession
 import com.android.window.flags.Flags
 import com.android.wm.shell.R
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.common.DisplayLayout
-import com.android.wm.shell.shared.DesktopModeStatus
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
 import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM
 import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT
 import com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP
 import com.google.common.truth.Truth.assertThat
 import junit.framework.Assert.assertTrue
+import org.junit.After
 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.any
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
+import org.mockito.quality.Strictness
 
 /**
  * Tests for [DragPositioningCallbackUtility].
@@ -53,24 +61,39 @@
 class DragPositioningCallbackUtilityTest {
     @Mock
     private lateinit var mockWindowDecoration: WindowDecoration<*>
+
     @Mock
     private lateinit var taskToken: WindowContainerToken
+
     @Mock
     private lateinit var taskBinder: IBinder
+
     @Mock
     private lateinit var mockDisplayController: DisplayController
+
     @Mock
     private lateinit var mockDisplayLayout: DisplayLayout
+
     @Mock
     private lateinit var mockDisplay: Display
+
     @Mock
     private lateinit var mockContext: Context
+
     @Mock
     private lateinit var mockResources: Resources
 
+    @JvmField
+    @Rule
+    val setFlagsRule = SetFlagsRule()
+
+    private lateinit var mockitoSession: StaticMockitoSession
+
     @Before
     fun setup() {
         MockitoAnnotations.initMocks(this)
+        mockitoSession = ExtendedMockito.mockitoSession().strictness(Strictness.LENIENT)
+                .spyStatic(DesktopModeStatus::class.java).startMocking()
 
         whenever(taskToken.asBinder()).thenReturn(taskBinder)
         whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout)
@@ -91,6 +114,11 @@
         whenever(mockDisplay.displayId).thenAnswer { DISPLAY_ID }
     }
 
+    @After
+    fun tearDown() {
+        mockitoSession.finishMocking()
+    }
+
     @Test
     fun testChangeBoundsDoesNotChangeHeightWhenLessThanMin() {
         val startingPoint = PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.top.toFloat())
@@ -238,7 +266,7 @@
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS)
     fun taskMinWidthHeightUndefined_changeBoundsInDesktopModeLessThanMin_shouldNotChangeBounds() {
-        whenever(DesktopModeStatus.canEnterDesktopMode(mockContext)).thenReturn(true)
+        doReturn(true).`when`{ DesktopModeStatus.canEnterDesktopMode(mockContext) }
         initializeTaskInfo(taskMinWidth = -1, taskMinHeight = -1)
         val startingPoint =
             PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.bottom.toFloat())
@@ -261,7 +289,7 @@
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS)
     fun taskMinWidthHeightUndefined_changeBoundsInDesktopModeAllowedSize_shouldChangeBounds() {
-        whenever(DesktopModeStatus.canEnterDesktopMode(mockContext)).thenReturn(true)
+        doReturn(true).`when`{ DesktopModeStatus.canEnterDesktopMode(mockContext) }
         initializeTaskInfo(taskMinWidth = -1, taskMinHeight = -1)
         val startingPoint =
             PointF(STARTING_BOUNDS.right.toFloat(), STARTING_BOUNDS.bottom.toFloat())
@@ -323,6 +351,49 @@
         assertThat(repositionTaskBounds.bottom).isEqualTo(STARTING_BOUNDS.bottom - 50)
     }
 
+    @Test
+    @DisableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS)
+    fun testChangeBounds_windowSizeExceedsStableBounds_shouldBeAllowedToChangeBounds() {
+        val startingPoint =
+            PointF(OFF_CENTER_STARTING_BOUNDS.right.toFloat(),
+                OFF_CENTER_STARTING_BOUNDS.bottom.toFloat())
+        val repositionTaskBounds = Rect(OFF_CENTER_STARTING_BOUNDS)
+        // Increase height and width by STABLE_BOUNDS. Subtract by 5px so that it doesn't reach
+        // the disallowed drag area.
+        val offset = 5
+        val newX = STABLE_BOUNDS.right.toFloat() - offset
+        val newY = STABLE_BOUNDS.bottom.toFloat() - offset
+        val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+
+        DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
+            repositionTaskBounds, OFF_CENTER_STARTING_BOUNDS, STABLE_BOUNDS, delta,
+            mockDisplayController, mockWindowDecoration)
+        assertThat(repositionTaskBounds.width()).isGreaterThan(STABLE_BOUNDS.right)
+        assertThat(repositionTaskBounds.height()).isGreaterThan(STABLE_BOUNDS.bottom)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_SIZE_CONSTRAINTS)
+    fun testChangeBoundsInDesktopMode_windowSizeExceedsStableBounds_shouldBeLimitedToDisplaySize() {
+        doReturn(true).`when`{ DesktopModeStatus.canEnterDesktopMode(mockContext) }
+        val startingPoint =
+            PointF(OFF_CENTER_STARTING_BOUNDS.right.toFloat(),
+                OFF_CENTER_STARTING_BOUNDS.bottom.toFloat())
+        val repositionTaskBounds = Rect(OFF_CENTER_STARTING_BOUNDS)
+        // Increase height and width by STABLE_BOUNDS. Subtract by 5px so that it doesn't reach
+        // the disallowed drag area.
+        val offset = 5
+        val newX = STABLE_BOUNDS.right.toFloat() - offset
+        val newY = STABLE_BOUNDS.bottom.toFloat() - offset
+        val delta = DragPositioningCallbackUtility.calculateDelta(newX, newY, startingPoint)
+
+        DragPositioningCallbackUtility.changeBounds(CTRL_TYPE_RIGHT or CTRL_TYPE_BOTTOM,
+            repositionTaskBounds, OFF_CENTER_STARTING_BOUNDS, STABLE_BOUNDS, delta,
+            mockDisplayController, mockWindowDecoration)
+        assertThat(repositionTaskBounds.width()).isLessThan(STABLE_BOUNDS.right)
+        assertThat(repositionTaskBounds.height()).isLessThan(STABLE_BOUNDS.bottom)
+    }
+
     private fun initializeTaskInfo(taskMinWidth: Int = MIN_WIDTH, taskMinHeight: Int = MIN_HEIGHT) {
         mockWindowDecoration.mTaskInfo = ActivityManager.RunningTaskInfo().apply {
             taskId = TASK_ID
@@ -347,6 +418,7 @@
         private const val NAVBAR_HEIGHT = 50
         private val DISPLAY_BOUNDS = Rect(0, 0, 2400, 1600)
         private val STARTING_BOUNDS = Rect(0, 0, 100, 100)
+        private val OFF_CENTER_STARTING_BOUNDS = Rect(-100, -100, 10, 10)
         private val DISALLOWED_RESIZE_AREA = Rect(
             DISPLAY_BOUNDS.left,
             DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
index 5582e0f..0c50ab6 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/HandleMenuTest.kt
@@ -196,9 +196,9 @@
             R.layout.desktop_mode_app_header
         }
         val handleMenu = HandleMenu(mockDesktopWindowDecoration, layoutId,
-            onClickListener, onTouchListener, appIcon, appName, displayController,
-            splitScreenController, true /* shouldShowWindowingPill */,
-            50 /* captionHeight */ )
+                onClickListener, onTouchListener, appIcon, appName, displayController,
+                splitScreenController, true /* shouldShowWindowingPill */,
+                true /* shouldShowBrowserPill */, 50 /* captionHeight */)
         handleMenu.show()
         return handleMenu
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
index 48ac1e5..943c313 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositionerTest.kt
@@ -17,6 +17,8 @@
 
 import android.app.ActivityManager
 import android.app.WindowConfiguration
+import android.content.Context
+import android.content.res.Resources
 import android.graphics.Point
 import android.graphics.Rect
 import android.os.IBinder
@@ -31,6 +33,7 @@
 import android.window.TransitionInfo
 import android.window.WindowContainerToken
 import androidx.test.filters.SmallTest
+import com.android.internal.jank.InteractionJankMonitor
 import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.common.DisplayController
@@ -98,6 +101,12 @@
     private lateinit var mockFinishCallback: TransitionFinishCallback
     @Mock
     private lateinit var mockTransitions: Transitions
+    @Mock
+    private lateinit var mockContext: Context
+    @Mock
+    private lateinit var mockResources: Resources
+    @Mock
+    private lateinit var mockInteractionJankMonitor: InteractionJankMonitor
 
     private lateinit var taskPositioner: VeiledResizeTaskPositioner
 
@@ -105,6 +114,9 @@
     fun setUp() {
         MockitoAnnotations.initMocks(this)
 
+        mockDesktopWindowDecoration.mDisplay = mockDisplay
+        mockDesktopWindowDecoration.mDecorWindowContext = mockContext
+        whenever(mockContext.getResources()).thenReturn(mockResources)
         whenever(taskToken.asBinder()).thenReturn(taskBinder)
         whenever(mockDisplayController.getDisplayLayout(DISPLAY_ID)).thenReturn(mockDisplayLayout)
         whenever(mockDisplayLayout.densityDpi()).thenReturn(DENSITY_DPI)
@@ -141,7 +153,8 @@
                         mockDisplayController,
                         mockDragStartListener,
                         mockTransactionFactory,
-                        mockTransitions
+                        mockTransitions,
+                        mockInteractionJankMonitor
                 )
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
index f3603e1..31c6479 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
@@ -75,7 +75,7 @@
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.TestRunningTaskInfoBuilder;
 import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.tests.R;
 import com.android.wm.shell.windowdecor.additionalviewcontainer.AdditionalViewContainer;
 
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index 77800a3..2fff4f5 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -212,6 +212,7 @@
         "tests/AttributeResolution_test.cpp",
         "tests/BigBuffer_test.cpp",
         "tests/ByteBucketArray_test.cpp",
+        "tests/CombinedIterator_test.cpp",
         "tests/Config_test.cpp",
         "tests/ConfigDescription_test.cpp",
         "tests/ConfigLocale_test.cpp",
@@ -267,6 +268,7 @@
 cc_benchmark {
     name: "libandroidfw_benchmarks",
     defaults: ["libandroidfw_defaults"],
+    test_config: "tests/AndroidTest_Benchmarks.xml",
     srcs: [
         // Helpers/infra for benchmarking.
         "tests/BenchMain.cpp",
@@ -282,7 +284,11 @@
         "tests/Theme_bench.cpp",
     ],
     shared_libs: common_test_libs,
-    data: ["tests/data/**/*.apk"],
+    data: [
+        "tests/data/**/*.apk",
+        ":FrameworkResourcesSparseTestApp",
+        ":FrameworkResourcesNotSparseTestApp",
+    ],
 }
 
 cc_library {
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index 46f636e..822a387 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -23,9 +23,11 @@
 #include <map>
 #include <set>
 #include <span>
+#include <utility>
 
 #include "android-base/logging.h"
 #include "android-base/stringprintf.h"
+#include "androidfw/CombinedIterator.h"
 #include "androidfw/ResourceTypes.h"
 #include "androidfw/ResourceUtils.h"
 #include "androidfw/Util.h"
@@ -1622,6 +1624,12 @@
 
 Theme::~Theme() = default;
 
+static bool IsUndefined(const Res_value& value) {
+  // DATA_NULL_EMPTY (@empty) is a valid resource value and DATA_NULL_UNDEFINED represents
+  // an absence of a valid value.
+  return value.dataType == Res_value::TYPE_NULL && value.data != Res_value::DATA_NULL_EMPTY;
+}
+
 base::expected<std::monostate, NullOrIOError> Theme::ApplyStyle(uint32_t resid, bool force) {
   ATRACE_NAME("Theme::ApplyStyle");
 
@@ -1633,39 +1641,76 @@
   // Merge the flags from this style.
   type_spec_flags_ |= (*bag)->type_spec_flags;
 
+  //
+  // This function is the most expensive part of applying an frro to the existing app resources,
+  // and needs to be as efficient as possible.
+  // The data structure we're working with is two parallel sorted arrays of keys (resource IDs)
+  // and entries (resource value + some attributes).
+  // The styles get applied in sequence, starting with an empty set of attributes. Each style
+  // contains its values for the theme attributes, and gets applied in either normal or forced way:
+  //  - normal way never overrides the existing attribute, so only unique style attributes are added
+  //  - forced way overrides anything for that attribute, and if it's undefined it removes the
+  //    previous value completely
+  //
+  // Style attributes come in a Bag data type - a sorted array of attributes with their values. This
+  // means we don't need to re-sort the attributes ever, and instead:
+  //  - for an already existing attribute just skip it or apply the forced value
+  //    - if the forced value is undefined, mark it undefined as well to get rid of it later
+  //  - for a new attribute append it to the array, forming a new sorted section of new attributes
+  //    past the end of the original ones (ignore undefined ones here)
+  //  - inplace merge two sorted sections to form a single sorted array again.
+  //  - run the last pass to remove all undefined elements
+  //
+  // Using this algorithm performs better than a repeated binary search + insert in the middle,
+  // as that keeps shifting the tail end of the arrays and wasting CPU cycles in memcpy().
+  //
+  const auto starting_size = keys_.size();
+  if (starting_size == 0) {
+    keys_.reserve((*bag)->entry_count);
+    entries_.reserve((*bag)->entry_count);
+  }
+  bool wrote_undefined = false;
   for (auto it = begin(*bag); it != end(*bag); ++it) {
     const uint32_t attr_res_id = it->key;
-
     // If the resource ID passed in is not a style, the key can be some other identifier that is not
     // a resource ID. We should fail fast instead of operating with strange resource IDs.
     if (!is_valid_resid(attr_res_id)) {
       return base::unexpected(std::nullopt);
     }
-
-    // DATA_NULL_EMPTY (@empty) is a valid resource value and DATA_NULL_UNDEFINED represents
-    // an absence of a valid value.
-    bool is_undefined = it->value.dataType == Res_value::TYPE_NULL &&
-        it->value.data != Res_value::DATA_NULL_EMPTY;
+    const bool is_undefined = IsUndefined(it->value);
     if (!force && is_undefined) {
       continue;
     }
-
-    const auto key_it = std::lower_bound(keys_.begin(), keys_.end(), attr_res_id);
-    const auto entry_it = entries_.begin() + (key_it - keys_.begin());
-    if (key_it != keys_.end() && *key_it == attr_res_id) {
-      if (is_undefined) {
-        // DATA_NULL_UNDEFINED clears the value of the attribute in the theme only when `force` is
-        // true.
-        keys_.erase(key_it);
-        entries_.erase(entry_it);
-      } else if (force) {
+    const auto key_it = std::lower_bound(keys_.begin(), keys_.begin() + starting_size, attr_res_id);
+    if (key_it != keys_.begin() + starting_size && *key_it == attr_res_id) {
+      const auto entry_it = entries_.begin() + (key_it - keys_.begin());
+      if (force || IsUndefined(entry_it->value)) {
         *entry_it = Entry{it->cookie, (*bag)->type_spec_flags, it->value};
+        wrote_undefined |= is_undefined;
       }
-    } else {
-      keys_.insert(key_it, attr_res_id);
-      entries_.insert(entry_it, Entry{it->cookie, (*bag)->type_spec_flags, it->value});
+    } else if (!is_undefined) {
+      keys_.emplace_back(attr_res_id);
+      entries_.emplace_back(it->cookie, (*bag)->type_spec_flags, it->value);
     }
   }
+
+  if (starting_size && keys_.size() != starting_size) {
+    std::inplace_merge(
+        CombinedIterator(keys_.begin(), entries_.begin()),
+        CombinedIterator(keys_.begin() + starting_size, entries_.begin() + starting_size),
+        CombinedIterator(keys_.end(), entries_.end()));
+  }
+  if (wrote_undefined) {
+    auto new_end = std::remove_if(CombinedIterator(keys_.begin(), entries_.begin()),
+                                  CombinedIterator(keys_.end(), entries_.end()),
+                                  [](const auto& pair) { return IsUndefined(pair.second.value); });
+    keys_.erase(new_end.it1, keys_.end());
+    entries_.erase(new_end.it2, entries_.end());
+  }
+  if (android::base::kEnableDChecks && !std::is_sorted(keys_.begin(), keys_.end())) {
+    ALOGW("Bag %u was unsorted in the apk?", unsigned(resid));
+    return base::unexpected(std::nullopt);
+  }
   return {};
 }
 
@@ -1691,6 +1736,9 @@
       return std::nullopt;
     }
     const auto entry_it = entries_.begin() + (key_it - keys_.begin());
+    if (IsUndefined(entry_it->value)) {
+      return std::nullopt;
+    }
     type_spec_flags |= entry_it->type_spec_flags;
     if (entry_it->value.dataType == Res_value::TYPE_ATTRIBUTE) {
       resid = entry_it->value.data;
diff --git a/libs/androidfw/StringPool.cpp b/libs/androidfw/StringPool.cpp
index 1cb8df3..629f146 100644
--- a/libs/androidfw/StringPool.cpp
+++ b/libs/androidfw/StringPool.cpp
@@ -132,7 +132,7 @@
 
   auto rhs_iter = rhs.entry_->spans.begin();
   for (const Span& span : entry_->spans) {
-    const Span& rhs_span = *rhs_iter;
+    const Span& rhs_span = *rhs_iter++;
     if (span.first_char != rhs_span.first_char || span.last_char != rhs_span.last_char ||
         span.name != rhs_span.name) {
       return false;
@@ -297,24 +297,22 @@
 template <typename E>
 static void SortEntries(
     std::vector<std::unique_ptr<E>>& entries,
-    const std::function<int(const StringPool::Context&, const StringPool::Context&)>& cmp) {
+    base::function_ref<int(const StringPool::Context&, const StringPool::Context&)> cmp) {
   using UEntry = std::unique_ptr<E>;
-
-  if (cmp != nullptr) {
-    std::sort(entries.begin(), entries.end(), [&cmp](const UEntry& a, const UEntry& b) -> bool {
-      int r = cmp(a->context, b->context);
-      if (r == 0) {
-        r = a->value.compare(b->value);
-      }
-      return r < 0;
-    });
-  } else {
-    std::sort(entries.begin(), entries.end(),
-              [](const UEntry& a, const UEntry& b) -> bool { return a->value < b->value; });
-  }
+  std::sort(entries.begin(), entries.end(), [cmp](const UEntry& a, const UEntry& b) -> bool {
+    int r = cmp(a->context, b->context);
+    if (r == 0) {
+      r = a->value.compare(b->value);
+    }
+    return r < 0;
+  });
 }
 
-void StringPool::Sort(const std::function<int(const Context&, const Context&)>& cmp) {
+void StringPool::Sort() {
+  Sort([](auto&&, auto&&) { return 0; });
+}
+
+void StringPool::Sort(base::function_ref<int(const Context&, const Context&)> cmp) {
   SortEntries(styles_, cmp);
   SortEntries(strings_, cmp);
   ReAssignIndices();
diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h
index 17a8ba6..ac46bc5 100644
--- a/libs/androidfw/include/androidfw/AssetManager2.h
+++ b/libs/androidfw/include/androidfw/AssetManager2.h
@@ -280,9 +280,9 @@
 
    private:
     SelectedValue(uint8_t value_type, Res_value::data_type value_data, ApkAssetsCookie cookie,
-                  uint32_t type_flags, uint32_t resid, const ResTable_config& config) :
+                  uint32_t type_flags, uint32_t resid, ResTable_config config) :
                   cookie(cookie), data(value_data), type(value_type), flags(type_flags),
-                  resid(resid), config(config) {};
+                  resid(resid), config(std::move(config)) {}
   };
 
   // Retrieves the best matching resource value with ID `resid`.
diff --git a/libs/androidfw/include/androidfw/CombinedIterator.h b/libs/androidfw/include/androidfw/CombinedIterator.h
new file mode 100644
index 0000000..4ff6a7d
--- /dev/null
+++ b/libs/androidfw/include/androidfw/CombinedIterator.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <compare>
+#include <iterator>
+#include <utility>
+
+namespace android {
+
+namespace detail {
+// A few useful aliases to not repeat them everywhere
+template <class It1, class It2>
+using Value = std::pair<typename std::iterator_traits<It1>::value_type,
+                        typename std::iterator_traits<It2>::value_type>;
+
+template <class It1, class It2>
+using BaseRefPair = std::pair<typename std::iterator_traits<It1>::reference,
+                              typename std::iterator_traits<It2>::reference>;
+
+template <class It1, class It2>
+struct RefPair : BaseRefPair<It1, It2> {
+  using Base = BaseRefPair<It1, It2>;
+  using Value = detail::Value<It1, It2>;
+
+  RefPair(It1 it1, It2 it2) : Base(*it1, *it2) {
+  }
+
+  RefPair& operator=(const Value& v) {
+    this->first = v.first;
+    this->second = v.second;
+    return *this;
+  }
+  operator Value() const {
+    return Value(this->first, this->second);
+  }
+  bool operator==(const RefPair& other) {
+    return this->first == other.first;
+  }
+  bool operator==(const Value& other) {
+    return this->first == other.first;
+  }
+  std::strong_ordering operator<=>(const RefPair& other) const {
+    return this->first <=> other.first;
+  }
+  std::strong_ordering operator<=>(const Value& other) const {
+    return this->first <=> other.first;
+  }
+  friend void swap(RefPair& l, RefPair& r) {
+    using std::swap;
+    swap(l.first, r.first);
+    swap(l.second, r.second);
+  }
+};
+
+template <class It1, class It2>
+struct RefPairPtr {
+  RefPair<It1, It2> value;
+
+  RefPair<It1, It2>* operator->() const {
+    return &value;
+  }
+};
+}  // namespace detail
+
+//
+//   CombinedIterator - a class to combine two iterators to process them as a single iterator to a
+// pair of values. Useful for processing a data structure of "struct of arrays", replacing
+// array of structs for cache locality.
+//
+// The value type is a pair of copies of the values of each iterator, and the reference is a
+// pair of references to the corresponding values. Comparison only compares the first element,
+// making it most useful for using on data like (vector<Key>, vector<Value>) for binary searching,
+// sorting both together and so on.
+//
+// The class is designed for handling arrays, so it requires random access iterators as an input.
+//
+
+template <class It1, class It2>
+requires std::random_access_iterator<It1> && std::random_access_iterator<It2>
+struct CombinedIterator {
+  typedef detail::Value<It1, It2> value_type;
+  typedef detail::RefPair<It1, It2> reference;
+  typedef std::ptrdiff_t difference_type;
+  typedef detail::RefPairPtr<It1, It2> pointer;
+  typedef std::random_access_iterator_tag iterator_category;
+
+  CombinedIterator(It1 it1 = {}, It2 it2 = {}) : it1(it1), it2(it2) {
+  }
+
+  bool operator<(const CombinedIterator& other) const {
+    return it1 < other.it1;
+  }
+  bool operator<=(const CombinedIterator& other) const {
+    return it1 <= other.it1;
+  }
+  bool operator>(const CombinedIterator& other) const {
+    return it1 > other.it1;
+  }
+  bool operator>=(const CombinedIterator& other) const {
+    return it1 >= other.it1;
+  }
+  bool operator==(const CombinedIterator& other) const {
+    return it1 == other.it1;
+  }
+  pointer operator->() const {
+    return pointer{{it1, it2}};
+  }
+  reference operator*() const {
+    return {it1, it2};
+  }
+  reference operator[](difference_type n) const {
+    return {it1 + n, it2 + n};
+  }
+
+  CombinedIterator& operator++() {
+    ++it1;
+    ++it2;
+    return *this;
+  }
+  CombinedIterator operator++(int) {
+    const auto res = *this;
+    ++*this;
+    return res;
+  }
+  CombinedIterator& operator--() {
+    --it1;
+    --it2;
+    return *this;
+  }
+  CombinedIterator operator--(int) {
+    const auto res = *this;
+    --*this;
+    return res;
+  }
+  CombinedIterator& operator+=(difference_type n) {
+    it1 += n;
+    it2 += n;
+    return *this;
+  }
+  CombinedIterator operator+(difference_type n) const {
+    CombinedIterator res = *this;
+    return res += n;
+  }
+
+  CombinedIterator& operator-=(difference_type n) {
+    it1 -= n;
+    it2 -= n;
+    return *this;
+  }
+  CombinedIterator operator-(difference_type n) const {
+    CombinedIterator res = *this;
+    return res -= n;
+  }
+  difference_type operator-(const CombinedIterator& other) {
+    return it1 - other.it1;
+  }
+
+  It1 it1;
+  It2 it2;
+};
+
+}  // namespace android
diff --git a/libs/androidfw/include/androidfw/StringPool.h b/libs/androidfw/include/androidfw/StringPool.h
index 0190ab5..9b2c72a 100644
--- a/libs/androidfw/include/androidfw/StringPool.h
+++ b/libs/androidfw/include/androidfw/StringPool.h
@@ -17,7 +17,6 @@
 #ifndef _ANDROID_STRING_POOL_H
 #define _ANDROID_STRING_POOL_H
 
-#include <functional>
 #include <memory>
 #include <string>
 #include <unordered_map>
@@ -25,6 +24,7 @@
 
 #include "BigBuffer.h"
 #include "IDiagnostics.h"
+#include "android-base/function_ref.h"
 #include "android-base/macros.h"
 #include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
@@ -205,7 +205,8 @@
   // Sorts the strings according to their Context using some comparison function.
   // Equal Contexts are further sorted by string value, lexicographically.
   // If no comparison function is provided, values are only sorted lexicographically.
-  void Sort(const std::function<int(const Context&, const Context&)>& cmp = nullptr);
+  void Sort();
+  void Sort(base::function_ref<int(const Context&, const Context&)> cmp);
 
   // Removes any strings that have no references.
   void Prune();
diff --git a/libs/androidfw/tests/AndroidTest_Benchmarks.xml b/libs/androidfw/tests/AndroidTest_Benchmarks.xml
new file mode 100644
index 0000000..e61e46f
--- /dev/null
+++ b/libs/androidfw/tests/AndroidTest_Benchmarks.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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 libandroidfw_benchmarks and libandroidfw_tests.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native-metric" />
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="libandroidfw_benchmarks->/data/local/tmp/libandroidfw_benchmarks" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.GoogleBenchmarkTest" >
+        <option name="native-benchmark-device-path" value="/data/local/tmp" />
+        <option name="benchmark-module-name" value="libandroidfw_benchmarks" />
+        <!-- The GoogleBenchmarkTest class ordinarily expects every file in the benchmark's
+             directory (recursively) to be a google-benchmark binary, so we need this setting to
+             avoid failing on the test data files. -->
+        <option name="file-exclusion-filter-regex" value=".*\.(apk|config)$"  />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/libs/androidfw/tests/AssetManager2_bench.cpp b/libs/androidfw/tests/AssetManager2_bench.cpp
index 2caa98c..136f5ea 100644
--- a/libs/androidfw/tests/AssetManager2_bench.cpp
+++ b/libs/androidfw/tests/AssetManager2_bench.cpp
@@ -37,7 +37,7 @@
 
 static void BM_AssetManagerLoadAssets(benchmark::State& state) {
   std::string path = GetTestDataPath() + "/basic/basic.apk";
-  while (state.KeepRunning()) {
+  for (auto&& _ : state) {
     auto apk = ApkAssets::Load(path);
     AssetManager2 assets;
     assets.SetApkAssets({apk});
@@ -47,7 +47,7 @@
 
 static void BM_AssetManagerLoadAssetsOld(benchmark::State& state) {
   String8 path((GetTestDataPath() + "/basic/basic.apk").data());
-  while (state.KeepRunning()) {
+  for (auto&& _ : state) {
     AssetManager assets;
     assets.addAssetPath(path, nullptr /* cookie */, false /* appAsLib */,
                         false /* isSystemAsset */);
@@ -60,7 +60,7 @@
 
 static void BM_AssetManagerLoadFrameworkAssets(benchmark::State& state) {
   std::string path = kFrameworkPath;
-  while (state.KeepRunning()) {
+  for (auto&& _ : state) {
     auto apk = ApkAssets::Load(path);
     AssetManager2 assets;
     assets.SetApkAssets({apk});
@@ -70,7 +70,7 @@
 
 static void BM_AssetManagerLoadFrameworkAssetsOld(benchmark::State& state) {
   String8 path(kFrameworkPath);
-  while (state.KeepRunning()) {
+  for (auto&& _ : state) {
     AssetManager assets;
     assets.addAssetPath(path, nullptr /* cookie */, false /* appAsLib */,
                         false /* isSystemAsset */);
@@ -138,7 +138,7 @@
   AssetManager2 assets;
   assets.SetApkAssets({apk});
 
-  while (state.KeepRunning()) {
+  for (auto&& _ : state) {
     auto bag = assets.GetBag(app::R::style::StyleTwo);
     if (!bag.has_value()) {
       state.SkipWithError("Failed to load get bag");
@@ -165,7 +165,7 @@
 
   const ResTable& table = assets.getResources(true);
 
-  while (state.KeepRunning()) {
+  for (auto&& _ : state) {
     const ResTable::bag_entry* bag_begin;
     const ssize_t N = table.lockBag(app::R::style::StyleTwo, &bag_begin);
     const ResTable::bag_entry* const bag_end = bag_begin + N;
@@ -190,7 +190,7 @@
   AssetManager2 assets;
   assets.SetApkAssets({apk});
 
-  while (state.KeepRunning()) {
+  for (auto&& _ : state) {
     std::set<std::string> locales =
         assets.GetResourceLocales(false /*exclude_system*/, true /*merge_equivalent_languages*/);
     benchmark::DoNotOptimize(locales);
@@ -208,7 +208,7 @@
 
   const ResTable& table = assets.getResources(true);
 
-  while (state.KeepRunning()) {
+  for (auto&& _ : state) {
     Vector<String8> locales;
     table.getLocales(&locales, true /*includeSystemLocales*/, true /*mergeEquivalentLangs*/);
     benchmark::DoNotOptimize(locales);
@@ -231,7 +231,7 @@
   std::vector<ResTable_config> configs;
   configs.push_back(config);
 
-  while (state.KeepRunning()) {
+  for (auto&& _ : state) {
     configs[0].sdkVersion = ~configs[0].sdkVersion;
     assets.SetConfigurations(configs);
   }
@@ -251,7 +251,7 @@
   ResTable_config config;
   memset(&config, 0, sizeof(config));
 
-  while (state.KeepRunning()) {
+  for (auto&& _ : state) {
     config.sdkVersion = ~config.sdkVersion;
     assets.setConfiguration(config);
   }
diff --git a/libs/androidfw/tests/BenchmarkHelpers.cpp b/libs/androidfw/tests/BenchmarkHelpers.cpp
index 8b883f4..e3fc0a0 100644
--- a/libs/androidfw/tests/BenchmarkHelpers.cpp
+++ b/libs/androidfw/tests/BenchmarkHelpers.cpp
@@ -28,7 +28,7 @@
   for (const std::string& path : paths) {
     if (!assetmanager.addAssetPath(String8(path.c_str()), nullptr /* cookie */,
                                    false /* appAsLib */, false /* isSystemAssets */)) {
-      state.SkipWithError(base::StringPrintf("Failed to load assets %s", path.c_str()).c_str());
+      state.SkipWithError(base::StringPrintf("Failed to old-load assets %s", path.c_str()).c_str());
       return;
     }
   }
@@ -57,7 +57,7 @@
   for (const std::string& path : paths) {
     auto apk = ApkAssets::Load(path);
     if (apk == nullptr) {
-      state.SkipWithError(base::StringPrintf("Failed to load assets %s", path.c_str()).c_str());
+      state.SkipWithError(base::StringPrintf("Failed to new-load assets %s", path.c_str()).c_str());
       return;
     }
     apk_assets.push_back(std::move(apk));
diff --git a/libs/androidfw/tests/CombinedIterator_test.cpp b/libs/androidfw/tests/CombinedIterator_test.cpp
new file mode 100644
index 0000000..c1228f3
--- /dev/null
+++ b/libs/androidfw/tests/CombinedIterator_test.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "androidfw/CombinedIterator.h"
+
+#include <algorithm>
+#include <string>
+#include <strstream>
+#include <utility>
+#include <vector>
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace android {
+
+template <class Coll>
+std::string toString(const Coll& coll) {
+  std::stringstream res;
+  res << "(" << std::size(coll) << ")";
+  if (std::size(coll)) {
+    res << "{" << coll[0];
+    for (int i = 1; i != std::size(coll); ++i) {
+      res << "," << coll[i];
+    }
+    res << "}";
+  }
+  return res.str();
+}
+
+template <class Coll>
+void AssertCollectionEq(const Coll& first, const Coll& second) {
+  ASSERT_EQ(std::size(first), std::size(second))
+      << "first: " << toString(first) << ", second: " << toString(second);
+  for (int i = 0; i != std::size(first); ++i) {
+    ASSERT_EQ(first[i], second[i])
+        << "index: " << i << " first: " << toString(first) << ", second: " << toString(second);
+  }
+}
+
+TEST(CombinedIteratorTest, Sorting) {
+  std::vector<int> v1 = {2, 1, 3, 4, 0};
+  std::vector<int> v2 = {20, 10, 30, 40, 0};
+
+  std::sort(CombinedIterator(v1.begin(), v2.begin()), CombinedIterator(v1.end(), v2.end()));
+
+  ASSERT_EQ(v1.size(), v2.size());
+  ASSERT_TRUE(std::is_sorted(v1.begin(), v1.end()));
+  ASSERT_TRUE(std::is_sorted(v2.begin(), v2.end()));
+  AssertCollectionEq(v1, {0, 1, 2, 3, 4});
+  AssertCollectionEq(v2, {0, 10, 20, 30, 40});
+}
+
+TEST(CombinedIteratorTest, Removing) {
+  std::vector<int> v1 = {1, 2, 3, 4, 5, 5, 5, 6};
+  std::vector<int> v2 = {10, 20, 30, 40, 50, 50, 50, 60};
+
+  auto newEnd =
+      std::remove_if(CombinedIterator(v1.begin(), v2.begin()), CombinedIterator(v1.end(), v2.end()),
+                     [](auto&& pair) { return pair.first >= 3 && pair.first <= 5; });
+
+  ASSERT_EQ(newEnd.it1, v1.begin() + 3);
+  ASSERT_EQ(newEnd.it2, v2.begin() + 3);
+
+  v1.erase(newEnd.it1, v1.end());
+  AssertCollectionEq(v1, {1, 2, 6});
+  v2.erase(newEnd.it2, v2.end());
+  AssertCollectionEq(v2, {10, 20, 60});
+}
+
+TEST(CombinedIteratorTest, InplaceMerge) {
+  std::vector<int> v1 = {1, 3, 4, 7, 2, 5, 6};
+  std::vector<int> v2 = {10, 30, 40, 70, 20, 50, 60};
+
+  std::inplace_merge(CombinedIterator(v1.begin(), v2.begin()),
+                     CombinedIterator(v1.begin() + 4, v2.begin() + 4),
+                     CombinedIterator(v1.end(), v2.end()));
+  ASSERT_TRUE(std::is_sorted(v1.begin(), v1.end()));
+  ASSERT_TRUE(std::is_sorted(v2.begin(), v2.end()));
+
+  AssertCollectionEq(v1, {1, 2, 3, 4, 5, 6, 7});
+  AssertCollectionEq(v2, {10, 20, 30, 40, 50, 60, 70});
+}
+
+}  // namespace android
diff --git a/libs/androidfw/tests/Theme_bench.cpp b/libs/androidfw/tests/Theme_bench.cpp
index dfbb5a7..bf89617 100644
--- a/libs/androidfw/tests/Theme_bench.cpp
+++ b/libs/androidfw/tests/Theme_bench.cpp
@@ -27,6 +27,10 @@
 constexpr const static uint32_t kStyleId = 0x01030237u;  // android:style/Theme.Material.Light
 constexpr const static uint32_t kAttrId = 0x01010030u;   // android:attr/colorForeground
 
+constexpr const static uint32_t kStyle2Id = 0x01030224u;  // android:style/Theme.Material
+constexpr const static uint32_t kStyle3Id = 0x0103024du;  // android:style/Widget.Material
+constexpr const static uint32_t kStyle4Id = 0x0103028eu;  // android:style/Widget.Material.Light
+
 static void BM_ThemeApplyStyleFramework(benchmark::State& state) {
   auto apk = ApkAssets::Load(kFrameworkPath);
   if (apk == nullptr) {
@@ -61,6 +65,32 @@
 }
 BENCHMARK(BM_ThemeApplyStyleFrameworkOld);
 
+static void BM_ThemeRebaseFramework(benchmark::State& state) {
+  auto apk = ApkAssets::Load(kFrameworkPath);
+  if (apk == nullptr) {
+    state.SkipWithError("Failed to load assets");
+    return;
+  }
+
+  AssetManager2 assets;
+  assets.SetApkAssets({apk});
+
+  // Create two arrays of styles to switch between back and forth.
+  const uint32_t styles1[] = {kStyle2Id, kStyleId, kStyle3Id};
+  const uint8_t force1[std::size(styles1)] = {false, true, false};
+  const uint32_t styles2[] = {kStyleId, kStyle2Id, kStyle4Id, kStyle3Id};
+  const uint8_t force2[std::size(styles2)] = {false, true, true, false};
+  const auto theme = assets.NewTheme();
+  // Initialize the theme to make the first iteration the same as the rest.
+  theme->Rebase(&assets, styles1, force1, std::size(force1));
+
+  while (state.KeepRunning()) {
+    theme->Rebase(&assets, styles2, force2, std::size(force2));
+    theme->Rebase(&assets, styles1, force1, std::size(force1));
+  }
+}
+BENCHMARK(BM_ThemeRebaseFramework);
+
 static void BM_ThemeGetAttribute(benchmark::State& state) {
   auto apk = ApkAssets::Load(kFrameworkPath);
 
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 0d0af11..4d185c6 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -28,8 +28,8 @@
 #include <include/gpu/ganesh/vk/GrVkBackendSemaphore.h>
 #include <include/gpu/ganesh/vk/GrVkBackendSurface.h>
 #include <include/gpu/ganesh/vk/GrVkDirectContext.h>
+#include <include/gpu/vk/VulkanBackendContext.h>
 #include <ui/FatVector.h>
-#include <vk/GrVkExtensions.h>
 #include <vk/GrVkTypes.h>
 
 #include <sstream>
@@ -141,7 +141,8 @@
     mPhysicalDeviceFeatures2 = {};
 }
 
-void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFeatures2& features) {
+void VulkanManager::setupDevice(skgpu::VulkanExtensions& grExtensions,
+                                VkPhysicalDeviceFeatures2& features) {
     VkResult err;
 
     constexpr VkApplicationInfo app_info = {
@@ -506,7 +507,7 @@
         return vkGetInstanceProcAddr(instance, proc_name);
     };
 
-    GrVkBackendContext backendContext;
+    skgpu::VulkanBackendContext backendContext;
     backendContext.fInstance = mInstance;
     backendContext.fPhysicalDevice = mPhysicalDevice;
     backendContext.fDevice = mDevice;
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index b92ebb3..08f9d42 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -24,8 +24,7 @@
 #include <SkSurface.h>
 #include <android-base/unique_fd.h>
 #include <utils/StrongPointer.h>
-#include <vk/GrVkBackendContext.h>
-#include <vk/GrVkExtensions.h>
+#include <vk/VulkanExtensions.h>
 #include <vulkan/vulkan.h>
 
 // VK_ANDROID_frame_boundary is a bespoke extension defined by AGI
@@ -127,7 +126,7 @@
 
     // Sets up the VkInstance and VkDevice objects. Also fills out the passed in
     // VkPhysicalDeviceFeatures struct.
-    void setupDevice(GrVkExtensions&, VkPhysicalDeviceFeatures2&);
+    void setupDevice(skgpu::VulkanExtensions&, VkPhysicalDeviceFeatures2&);
 
     // simple wrapper class that exists only to initialize a pointer to NULL
     template <typename FNPTR_TYPE>
@@ -206,7 +205,7 @@
         BufferAge,
     };
     SwapBehavior mSwapBehavior = SwapBehavior::Discard;
-    GrVkExtensions mExtensions;
+    skgpu::VulkanExtensions mExtensions;
     uint32_t mDriverVersion = 0;
 
     std::once_flag mInitFlag;
diff --git a/lint-baseline.xml b/lint-baseline.xml
index 660884a..0320aab 100644
--- a/lint-baseline.xml
+++ b/lint-baseline.xml
@@ -562,4 +562,10707 @@
             column="74"/>
     </issue>
 
+    <issue
+        id="FlaggedApi"
+        message="Method `getItemCount()` is a flagged API and should be inside an `if (Flags.collectionInfoItemCounts())` check (or annotate the surrounding method `writeToParcelNoRecycle` with `@FlaggedApi(Flags.FLAG_COLLECTION_INFO_ITEM_COUNTS) to transfer requirement to caller`)"
+        errorLine1="            parcel.writeInt(mCollectionInfo.getItemCount());"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/accessibility/AccessibilityNodeInfo.java"
+            line="4498"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getImportantForAccessibilityItemCount()` is a flagged API and should be inside an `if (Flags.collectionInfoItemCounts())` check (or annotate the surrounding method `writeToParcelNoRecycle` with `@FlaggedApi(Flags.FLAG_COLLECTION_INFO_ITEM_COUNTS) to transfer requirement to caller`)"
+        errorLine1="            parcel.writeInt(mCollectionInfo.getImportantForAccessibilityItemCount());"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/accessibility/AccessibilityNodeInfo.java"
+            line="4499"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isGranularScrollingSupported()` is a flagged API and should be inside an `if (Flags.granularScrolling())` check (or annotate the surrounding method `toString` with `@FlaggedApi(Flags.FLAG_GRANULAR_SCROLLING) to transfer requirement to caller`)"
+        errorLine1="        builder.append(&quot;; granularScrollingSupported: &quot;).append(isGranularScrollingSupported());"
+        errorLine2="                                                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/accessibility/AccessibilityNodeInfo.java"
+            line="5079"
+            column="65"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `UNDEFINED` is a flagged API and should be inside an `if (Flags.collectionInfoItemCounts())` check (or annotate the surrounding method `CollectionInfo` with `@FlaggedApi(Flags.FLAG_COLLECTION_INFO_ITEM_COUNTS) to transfer requirement to caller`)"
+        errorLine1="            mItemCount = UNDEFINED;"
+        errorLine2="                         ~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/accessibility/AccessibilityNodeInfo.java"
+            line="6211"
+            column="26"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `UNDEFINED` is a flagged API and should be inside an `if (Flags.collectionInfoItemCounts())` check (or annotate the surrounding method `CollectionInfo` with `@FlaggedApi(Flags.FLAG_COLLECTION_INFO_ITEM_COUNTS) to transfer requirement to caller`)"
+        errorLine1="            mImportantForAccessibilityItemCount = UNDEFINED;"
+        errorLine2="                                                  ~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/accessibility/AccessibilityNodeInfo.java"
+            line="6212"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `UNDEFINED` is a flagged API and should be inside an `if (Flags.collectionInfoItemCounts())` check (or annotate the surrounding method `clear` with `@FlaggedApi(Flags.FLAG_COLLECTION_INFO_ITEM_COUNTS) to transfer requirement to caller`)"
+        errorLine1="            mItemCount = UNDEFINED;"
+        errorLine2="                         ~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/accessibility/AccessibilityNodeInfo.java"
+            line="6319"
+            column="26"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `UNDEFINED` is a flagged API and should be inside an `if (Flags.collectionInfoItemCounts())` check (or annotate the surrounding method `clear` with `@FlaggedApi(Flags.FLAG_COLLECTION_INFO_ITEM_COUNTS) to transfer requirement to caller`)"
+        errorLine1="            mImportantForAccessibilityItemCount = UNDEFINED;"
+        errorLine2="                                                  ~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/accessibility/AccessibilityNodeInfo.java"
+            line="6320"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;android.view.accessibility.a11y_overlay_callbacks&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/accessibilityservice/AccessibilityService.java"
+            line="800"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;android.view.accessibility.a11y_overlay_callbacks&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/accessibilityservice/AccessibilityService.java"
+            line="811"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;android.view.accessibility.a11y_overlay_callbacks&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/accessibilityservice/AccessibilityService.java"
+            line="811"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;android.view.accessibility.a11y_overlay_callbacks&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/accessibilityservice/AccessibilityService.java"
+            line="811"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;android.view.accessibility.a11y_overlay_callbacks&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/accessibilityservice/AccessibilityService.java"
+            line="819"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;android.view.accessibility.a11y_overlay_callbacks&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/accessibilityservice/AccessibilityService.java"
+            line="819"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;android.view.accessibility.a11y_overlay_callbacks&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/accessibilityservice/AccessibilityService.java"
+            line="819"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;android.view.accessibility.a11y_overlay_callbacks&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/accessibilityservice/AccessibilityService.java"
+            line="819"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;android.view.accessibility.a11y_overlay_callbacks&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/accessibilityservice/AccessibilityService.java"
+            line="819"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;android.view.accessibility.a11y_overlay_callbacks&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/accessibilityservice/AccessibilityService.java"
+            line="819"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;android.view.accessibility.a11y_overlay_callbacks&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/accessibilityservice/AccessibilityService.java"
+            line="819"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;android.view.accessibility.a11y_overlay_callbacks&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/accessibilityservice/AccessibilityService.java"
+            line="827"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;android.view.accessibility.a11y_overlay_callbacks&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/accessibilityservice/AccessibilityService.java"
+            line="827"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setObservedMotionEventSources()` is a flagged API and should be inside an `if (Flags.motionEventObserving())` check (or annotate the surrounding method `initFromParcel` with `@FlaggedApi(Flags.FLAG_MOTION_EVENT_OBSERVING) to transfer requirement to caller`)"
+        errorLine1="        setObservedMotionEventSources(parcel.readInt());"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/accessibilityservice/AccessibilityServiceInfo.java"
+            line="1420"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TYPE_WINDOW_CONTROL` is a flagged API and should be inside an `if (Flags.addTypeWindowControl())` check (or annotate the surrounding method `typeToString` with `@FlaggedApi(Flags.FLAG_ADD_TYPE_WINDOW_CONTROL) to transfer requirement to caller`)"
+        errorLine1="        if (Flags.addTypeWindowControl() &amp;&amp; type == TYPE_WINDOW_CONTROL) {"
+        errorLine2="                                                    ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/accessibility/AccessibilityWindowInfo.java"
+            line="883"
+            column="53"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `requestPermissions()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `requestPermissions` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="        requestPermissions(permissions, requestCode, getDeviceId());"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/Activity.java"
+            line="5636"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `EXTRA_REQUEST_PERMISSIONS_DEVICE_ID` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `dispatchRequestPermissionsResult` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="                PackageManager.EXTRA_REQUEST_PERMISSIONS_DEVICE_ID, Context.DEVICE_ID_DEFAULT"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/Activity.java"
+            line="9530"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onRequestPermissionsResult()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `dispatchRequestPermissionsResult` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="        onRequestPermissionsResult(requestCode, permissions, grantResults, deviceId);"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/Activity.java"
+            line="9532"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `uptimeNanos()` is a flagged API and should be inside an `if (Flags.adpfGpuReportActualWorkDuration())` check (or annotate the surrounding method `handleBindApplication` with `@FlaggedApi(Flags.FLAG_ADPF_GPU_REPORT_ACTUAL_WORK_DURATION) to transfer requirement to caller`)"
+        errorLine1="                timestampApplicationOnCreateNs = SystemClock.uptimeNanos();"
+        errorLine2="                                                 ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/ActivityThread.java"
+            line="7503"
+            column="50"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `SeServiceManager()` is a flagged API and should be inside an `if (Flags.enableNfcMainline())` check (or annotate the surrounding method `initializeMainlineModules` with `@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) to transfer requirement to caller`)"
+        errorLine1="        SeFrameworkInitializer.setSeServiceManager(new SeServiceManager());"
+        errorLine2="                                                   ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/ActivityThread.java"
+            line="8725"
+            column="52"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setSeServiceManager()` is a flagged API and should be inside an `if (Flags.enableNfcMainline())` check (or annotate the surrounding method `initializeMainlineModules` with `@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) to transfer requirement to caller`)"
+        errorLine1="        SeFrameworkInitializer.setSeServiceManager(new SeServiceManager());"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/ActivityThread.java"
+            line="8725"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `ProfilingServiceManager()` is a flagged API and should be inside an `if (Flags.telemetryApisFrameworkInitialization())` check (or annotate the surrounding method `initializeMainlineModules` with `@FlaggedApi(Flags.FLAG_TELEMETRY_APIS_FRAMEWORK_INITIALIZATION) to transfer requirement to caller`)"
+        errorLine1="            ProfilingFrameworkInitializer.setProfilingServiceManager(new ProfilingServiceManager());"
+        errorLine2="                                                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/ActivityThread.java"
+            line="8727"
+            column="70"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `TvExtender()` is a flagged API and should be inside an `if (Flags.apiTvextender())` check (or annotate the surrounding method `createNotification` with `@FlaggedApi(Flags.FLAG_API_TVEXTENDER) to transfer requirement to caller`)"
+        errorLine1="                .extend(new Notification.TvExtender()"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/debug/AdbNotifications.java"
+            line="95"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setChannelId()` is a flagged API and should be inside an `if (Flags.apiTvextender())` check (or annotate the surrounding method `createNotification` with `@FlaggedApi(Flags.FLAG_API_TVEXTENDER) to transfer requirement to caller`)"
+        errorLine1="                .extend(new Notification.TvExtender()"
+        errorLine2="                        ^">
+        <location
+            file="frameworks/base/core/java/android/debug/AdbNotifications.java"
+            line="95"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isMgf1DigestsSpecified()` is a flagged API and should be inside an `if (Flags.mgf1DigestSetterV2())` check (or annotate the surrounding method `initialize` with `@FlaggedApi(Flags.FLAG_MGF1_DIGEST_SETTER_V2) to transfer requirement to caller`)"
+        errorLine1="                if (spec.isMgf1DigestsSpecified()) {"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java"
+            line="346"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getMgf1Digests()` is a flagged API and should be inside an `if (Flags.mgf1DigestSetterV2())` check (or annotate the surrounding method `initialize` with `@FlaggedApi(Flags.FLAG_MGF1_DIGEST_SETTER_V2) to transfer requirement to caller`)"
+        errorLine1="                    Set&lt;String> mgfDigests = spec.getMgf1Digests();"
+        errorLine2="                                             ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java"
+            line="349"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isMgf1DigestsSpecified()` is a flagged API and should be inside an `if (Flags.mgf1DigestSetterV2())` check (or annotate the surrounding method `setPrivateKeyEntry` with `@FlaggedApi(Flags.FLAG_MGF1_DIGEST_SETTER_V2) to transfer requirement to caller`)"
+        errorLine1="                    if (spec.isMgf1DigestsSpecified()) {"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java"
+            line="539"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getMgf1Digests()` is a flagged API and should be inside an `if (Flags.mgf1DigestSetterV2())` check (or annotate the surrounding method `setPrivateKeyEntry` with `@FlaggedApi(Flags.FLAG_MGF1_DIGEST_SETTER_V2) to transfer requirement to caller`)"
+        errorLine1="                        for (String mgf1Digest : spec.getMgf1Digests()) {"
+        errorLine2="                                                 ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java"
+            line="540"
+            column="50"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TYPE_RCS_STRING` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="        APN_TYPE_STRING_MAP.put(TYPE_RCS_STRING, TYPE_RCS);"
+        errorLine2="                                ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/data/ApnSetting.java"
+            line="491"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TYPE_RCS` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="        APN_TYPE_STRING_MAP.put(TYPE_RCS_STRING, TYPE_RCS);"
+        errorLine2="                                                 ~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/data/ApnSetting.java"
+            line="491"
+            column="50"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TYPE_RCS_STRING` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="        APN_TYPE_INT_MAP.put(TYPE_RCS, TYPE_RCS_STRING);"
+        errorLine2="                                       ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/data/ApnSetting.java"
+            line="509"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TYPE_RCS` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="        APN_TYPE_INT_MAP.put(TYPE_RCS, TYPE_RCS_STRING);"
+        errorLine2="                             ~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/data/ApnSetting.java"
+            line="509"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `MTU_V4` is a flagged API and should be inside an `if (Flags.apnSettingFieldSupportFlag())` check (or annotate the surrounding method `makeApnSetting` with `@FlaggedApi(Flags.FLAG_APN_SETTING_FIELD_SUPPORT_FLAG) to transfer requirement to caller`)"
+        errorLine1="        int mtuV4 = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MTU_V4));"
+        errorLine2="                                                                                  ~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/data/ApnSetting.java"
+            line="1075"
+            column="83"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setAlwaysOn()` is a flagged API and should be inside an `if (Flags.apnSettingFieldSupportFlag())` check (or annotate the surrounding method `makeApnSetting` with `@FlaggedApi(Flags.FLAG_APN_SETTING_FIELD_SUPPORT_FLAG) to transfer requirement to caller`)"
+        errorLine1="        return new Builder()"
+        errorLine2="               ^">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/data/ApnSetting.java"
+            line="1080"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `MTU_V6` is a flagged API and should be inside an `if (Flags.apnSettingFieldSupportFlag())` check (or annotate the surrounding method `makeApnSetting` with `@FlaggedApi(Flags.FLAG_APN_SETTING_FIELD_SUPPORT_FLAG) to transfer requirement to caller`)"
+        errorLine1="                .setMtuV6(cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.MTU_V6)))"
+        errorLine2="                                                                                        ~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/data/ApnSetting.java"
+            line="1126"
+            column="89"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `ALWAYS_ON` is a flagged API and should be inside an `if (Flags.apnSettingFieldSupportFlag())` check (or annotate the surrounding method `makeApnSetting` with `@FlaggedApi(Flags.FLAG_APN_SETTING_FIELD_SUPPORT_FLAG) to transfer requirement to caller`)"
+        errorLine1="                .setAlwaysOn(cursor.getInt(cursor.getColumnIndexOrThrow(Carriers.ALWAYS_ON)) == 1)"
+        errorLine2="                                                                                 ~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/data/ApnSetting.java"
+            line="1137"
+            column="82"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setAlwaysOn()` is a flagged API and should be inside an `if (Flags.apnSettingFieldSupportFlag())` check (or annotate the surrounding method `makeApnSetting` with `@FlaggedApi(Flags.FLAG_APN_SETTING_FIELD_SUPPORT_FLAG) to transfer requirement to caller`)"
+        errorLine1="        return new Builder()"
+        errorLine2="               ^">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/data/ApnSetting.java"
+            line="1151"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `MTU_V4` is a flagged API and should be inside an `if (Flags.apnSettingFieldSupportFlag())` check (or annotate the surrounding method `toContentValues` with `@FlaggedApi(Flags.FLAG_APN_SETTING_FIELD_SUPPORT_FLAG) to transfer requirement to caller`)"
+        errorLine1="        apnValue.put(Telephony.Carriers.MTU_V4, mMtuV4);"
+        errorLine2="                                        ~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/data/ApnSetting.java"
+            line="1500"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `MTU_V6` is a flagged API and should be inside an `if (Flags.apnSettingFieldSupportFlag())` check (or annotate the surrounding method `toContentValues` with `@FlaggedApi(Flags.FLAG_APN_SETTING_FIELD_SUPPORT_FLAG) to transfer requirement to caller`)"
+        errorLine1="        apnValue.put(Telephony.Carriers.MTU_V6, mMtuV6);"
+        errorLine2="                                        ~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/data/ApnSetting.java"
+            line="1501"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `ALWAYS_ON` is a flagged API and should be inside an `if (Flags.apnSettingFieldSupportFlag())` check (or annotate the surrounding method `toContentValues` with `@FlaggedApi(Flags.FLAG_APN_SETTING_FIELD_SUPPORT_FLAG) to transfer requirement to caller`)"
+        errorLine1="        apnValue.put(Telephony.Carriers.ALWAYS_ON, mAlwaysOn);"
+        errorLine2="                                        ~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/data/ApnSetting.java"
+            line="1504"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setAlwaysOn()` is a flagged API and should be inside an `if (Flags.apnSettingFieldSupportFlag())` check (or annotate the surrounding method `readFromParcel` with `@FlaggedApi(Flags.FLAG_APN_SETTING_FIELD_SUPPORT_FLAG) to transfer requirement to caller`)"
+        errorLine1="        return new Builder()"
+        errorLine2="               ^">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/data/ApnSetting.java"
+            line="1785"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TYPE_RCS` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `build` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="                    | TYPE_XCAP | TYPE_VSIM | TYPE_BIP | TYPE_ENTERPRISE | TYPE_RCS)) == 0"
+        errorLine2="                                                                           ~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/data/ApnSetting.java"
+            line="2386"
+            column="76"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `OPSTR_ACCESS_RESTRICTED_SETTINGS` is a flagged API and should be inside an `if (Flags.enhancedConfirmationModeApisEnabled())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_ENHANCED_CONFIRMATION_MODE_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="        new AppOpInfo.Builder(OP_ACCESS_RESTRICTED_SETTINGS, OPSTR_ACCESS_RESTRICTED_SETTINGS,"
+        errorLine2="                                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/AppOpsManager.java"
+            line="2983"
+            column="62"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `OPSTR_CREATE_ACCESSIBILITY_OVERLAY` is a flagged API and should be inside an `if (Flags.createAccessibilityOverlayAppOpEnabled())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CREATE_ACCESSIBILITY_OVERLAY_APP_OP_ENABLED) to transfer requirement to caller`)"
+        errorLine1="                OPSTR_CREATE_ACCESSIBILITY_OVERLAY,"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/AppOpsManager.java"
+            line="3050"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `OPSTR_MEDIA_ROUTING_CONTROL` is a flagged API and should be inside an `if (Flags.enablePrivilegedRoutingForMediaRoutingControl())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_ENABLE_PRIVILEGED_ROUTING_FOR_MEDIA_ROUTING_CONTROL) to transfer requirement to caller`)"
+        errorLine1="        new AppOpInfo.Builder(OP_MEDIA_ROUTING_CONTROL, OPSTR_MEDIA_ROUTING_CONTROL,"
+        errorLine2="                                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/AppOpsManager.java"
+            line="3053"
+            column="57"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `OPSTR_ENABLE_MOBILE_DATA_BY_USER` is a flagged API and should be inside an `if (Flags.opEnableMobileDataByUser())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_OP_ENABLE_MOBILE_DATA_BY_USER) to transfer requirement to caller`)"
+        errorLine1="        new AppOpInfo.Builder(OP_ENABLE_MOBILE_DATA_BY_USER, OPSTR_ENABLE_MOBILE_DATA_BY_USER,"
+        errorLine2="                                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/AppOpsManager.java"
+            line="3056"
+            column="62"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `OPSTR_RAPID_CLEAR_NOTIFICATIONS_BY_LISTENER` is a flagged API and should be inside an `if (Flags.rapidClearNotificationsByListenerAppOpEnabled())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_RAPID_CLEAR_NOTIFICATIONS_BY_LISTENER_APP_OP_ENABLED) to transfer requirement to caller`)"
+        errorLine1="                OPSTR_RAPID_CLEAR_NOTIFICATIONS_BY_LISTENER,"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/AppOpsManager.java"
+            line="3061"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `OPSTR_EMERGENCY_LOCATION` is a flagged API and should be inside an `if (Flags.locationBypass())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_LOCATION_BYPASS) to transfer requirement to caller`)"
+        errorLine1="        new AppOpInfo.Builder(OP_EMERGENCY_LOCATION, OPSTR_EMERGENCY_LOCATION, &quot;EMERGENCY_LOCATION&quot;)"
+        errorLine2="                                                     ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/AppOpsManager.java"
+            line="3077"
+            column="54"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `OPSTR_RECEIVE_SENSITIVE_NOTIFICATIONS` is a flagged API and should be inside an `if (Flags.redactSensitiveNotificationsFromUntrustedListeners())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS) to transfer requirement to caller`)"
+        errorLine1="                OPSTR_RECEIVE_SENSITIVE_NOTIFICATIONS, &quot;RECEIVE_SENSITIVE_NOTIFICATIONS&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/AppOpsManager.java"
+            line="3083"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `PERSISTENT_DEVICE_ID_DEFAULT` is a flagged API and should be inside an `if (Flags.persistentDeviceIdApi())` check (or annotate the surrounding method `OpEventProxyInfo` with `@FlaggedApi(Flags.FLAG_PERSISTENT_DEVICE_ID_API) to transfer requirement to caller`)"
+        errorLine1="                    VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT);"
+        errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/AppOpsManager.java"
+            line="3550"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `PERSISTENT_DEVICE_ID_DEFAULT` is a flagged API and should be inside an `if (Flags.persistentDeviceIdApi())` check (or annotate the surrounding method `onOpChanged` with `@FlaggedApi(Flags.FLAG_PERSISTENT_DEVICE_ID_API) to transfer requirement to caller`)"
+        errorLine1="                    VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT)) {"
+        errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/AppOpsManager.java"
+            line="7483"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `PERSISTENT_DEVICE_ID_DEFAULT` is a flagged API and should be inside an `if (Flags.persistentDeviceIdApi())` check (or annotate the surrounding method `getPackagesForOps` with `@FlaggedApi(Flags.FLAG_PERSISTENT_DEVICE_ID_API) to transfer requirement to caller`)"
+        errorLine1="                    VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT);"
+        errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/AppOpsManager.java"
+            line="7891"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getDeviceId()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `unsafeCheckOpRawNoThrow` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="                attributionSource.getPackageName(), attributionSource.getDeviceId());"
+        errorLine2="                                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/AppOpsManager.java"
+            line="8848"
+            column="53"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getDeviceId()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `noteOpNoThrow` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="                attributionSource.getAttributionTag(), attributionSource.getDeviceId(), message);"
+        errorLine2="                                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/AppOpsManager.java"
+            line="9034"
+            column="56"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getDeviceId()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `checkOpNoThrow` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="                attributionSource.getDeviceId());"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/AppOpsManager.java"
+            line="9329"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getDeviceId()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `startOpNoThrow` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="                attributionSource.getAttributionTag(), attributionSource.getDeviceId(),"
+        errorLine2="                                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/AppOpsManager.java"
+            line="9589"
+            column="56"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getDeviceId()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `finishOp` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="                attributionSource.getDeviceId());"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/AppOpsManager.java"
+            line="9842"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `EXTRA_REQUEST_PERMISSIONS_DEVICE_ID` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `buildRequestPermissionsIntent` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="        intent.putExtra(EXTRA_REQUEST_PERMISSIONS_DEVICE_ID, mContext.getDeviceId());"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/ApplicationPackageManager.java"
+            line="965"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `APP_METADATA_SOURCE_UNKNOWN` is a flagged API and should be inside an `if (Flags.aslInApkAppMetadataSource())` check (or annotate the surrounding method `getAppMetadataSource` with `@FlaggedApi(Flags.FLAG_ASL_IN_APK_APP_METADATA_SOURCE) to transfer requirement to caller`)"
+        errorLine1="        int source = PackageManager.APP_METADATA_SOURCE_UNKNOWN;"
+        errorLine2="                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/ApplicationPackageManager.java"
+            line="1283"
+            column="37"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `isArchived` is a flagged API and should be inside an `if (Flags.archiving())` check (or annotate the surrounding method `loadUnbadgedItemIcon` with `@FlaggedApi(Flags.FLAG_ARCHIVING) to transfer requirement to caller`)"
+        errorLine1="            if (itemInfo.isArchived) {"
+        errorLine2="                         ~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/ApplicationPackageManager.java"
+            line="3430"
+            column="26"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `ArchivedPackageInfo()` is a flagged API and should be inside an `if (Flags.archiving())` check (or annotate the surrounding method `getArchivedPackage` with `@FlaggedApi(Flags.FLAG_ARCHIVING) to transfer requirement to caller`)"
+        errorLine1="            return new ArchivedPackageInfo(parcel);"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/ApplicationPackageManager.java"
+            line="3995"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getPendingCredentialRequest()` is a flagged API and should be inside an `if (Flags.autofillCredmanDevIntegration())` check (or annotate the surrounding method `dump` with `@FlaggedApi(Flags.FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION) to transfer requirement to caller`)"
+        errorLine1="        GetCredentialRequest getCredentialRequest = node.getPendingCredentialRequest();"
+        errorLine2="                                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/assist/AssistStructure.java"
+            line="2657"
+            column="53"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `AttributionSource()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `AttributionSource` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="        this(uid, Process.INVALID_PID, packageName, attributionTag, sDefaultToken, null,"
+        errorLine2="        ^">
+        <location
+            file="frameworks/base/core/java/android/content/AttributionSource.java"
+            line="112"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `AttributionSource()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `AttributionSource` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="        this(uid, Process.INVALID_PID, packageName, attributionTag, token,"
+        errorLine2="        ^">
+        <location
+            file="frameworks/base/core/java/android/content/AttributionSource.java"
+            line="126"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `AttributionSource()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `AttributionSource` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="        this(uid, pid, packageName, attributionTag, token, /*renouncedPermissions*/ null,"
+        errorLine2="        ^">
+        <location
+            file="frameworks/base/core/java/android/content/AttributionSource.java"
+            line="133"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `AttributionSource()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `AttributionSource` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="        this(uid, Process.INVALID_PID, packageName, attributionTag, sDefaultToken,"
+        errorLine2="        ^">
+        <location
+            file="frameworks/base/core/java/android/content/AttributionSource.java"
+            line="142"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `AttributionSource()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `AttributionSource` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="        this(current.getUid(), current.getPid(), current.getPackageName(),"
+        errorLine2="        ^">
+        <location
+            file="frameworks/base/core/java/android/content/AttributionSource.java"
+            line="150"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getDeviceId()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `AttributionSource` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="                current.mAttributionSourceState.renouncedPermissions, current.getDeviceId(), next);"
+        errorLine2="                                                                      ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/AttributionSource.java"
+            line="152"
+            column="71"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `AttributionSource()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `AttributionSource` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="        this(uid, pid, packageName, attributionTag, sDefaultToken, renouncedPermissions, deviceId,"
+        errorLine2="        ^">
+        <location
+            file="frameworks/base/core/java/android/content/AttributionSource.java"
+            line="159"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `AttributionSource()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `withNextAttributionSource` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="        return new AttributionSource(getUid(), getPid(), getPackageName(), getAttributionTag(),"
+        errorLine2="               ^">
+        <location
+            file="frameworks/base/core/java/android/content/AttributionSource.java"
+            line="212"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getDeviceId()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `withNextAttributionSource` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="                getToken(), mAttributionSourceState.renouncedPermissions, getDeviceId(), next);"
+        errorLine2="                                                                          ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/AttributionSource.java"
+            line="213"
+            column="75"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `AttributionSource()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `withPackageName` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="        return new AttributionSource(getUid(), getPid(), packageName, getAttributionTag(),"
+        errorLine2="               ^">
+        <location
+            file="frameworks/base/core/java/android/content/AttributionSource.java"
+            line="218"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getDeviceId()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `withPackageName` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="               getToken(), mAttributionSourceState.renouncedPermissions, getDeviceId(), getNext());"
+        errorLine2="                                                                         ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/AttributionSource.java"
+            line="219"
+            column="74"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `AttributionSource()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `withToken` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="        return new AttributionSource(getUid(), getPid(), getPackageName(), getAttributionTag(),"
+        errorLine2="               ^">
+        <location
+            file="frameworks/base/core/java/android/content/AttributionSource.java"
+            line="224"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getDeviceId()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `withToken` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="                token, mAttributionSourceState.renouncedPermissions, getDeviceId(), getNext());"
+        errorLine2="                                                                     ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/AttributionSource.java"
+            line="225"
+            column="70"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `AttributionSource()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `withPid` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="        return new AttributionSource(getUid(), pid, getPackageName(), getAttributionTag(),"
+        errorLine2="               ^">
+        <location
+            file="frameworks/base/core/java/android/content/AttributionSource.java"
+            line="235"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getDeviceId()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `withPid` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="                getToken(), mAttributionSourceState.renouncedPermissions, getDeviceId(), getNext());"
+        errorLine2="                                                                          ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/AttributionSource.java"
+            line="236"
+            column="75"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `AttributionSource()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `withDeviceId` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="        return new AttributionSource(getUid(), getPid(), getPackageName(), getAttributionTag(),"
+        errorLine2="               ^">
+        <location
+            file="frameworks/base/core/java/android/content/AttributionSource.java"
+            line="241"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setDeviceId()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `myAttributionSource` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="            return new AttributionSource.Builder(uid)"
+        errorLine2="                   ^">
+        <location
+            file="frameworks/base/core/java/android/content/AttributionSource.java"
+            line="284"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isRegisteredAttributionSource()` is a flagged API and should be inside an `if (Flags.shouldRegisterAttributionSource())` check (or annotate the surrounding method `isTrusted` with `@FlaggedApi(Flags.FLAG_SHOULD_REGISTER_ATTRIBUTION_SOURCE) to transfer requirement to caller`)"
+        errorLine1="                &amp;&amp; context.getSystemService(PermissionManager.class)"
+        errorLine2="                   ^">
+        <location
+            file="frameworks/base/core/java/android/content/AttributionSource.java"
+            line="487"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isResumed()` is a flagged API and should be inside an `if (Flags.enableNfcMainline())` check (or annotate the surrounding method `isDisablingEnterExitEventForAutofill` with `@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) to transfer requirement to caller`)"
+        errorLine1="        return mAutoFillIgnoreFirstResumePause || !mActivity.isResumed();"
+        errorLine2="                                                   ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/autofill/AutofillClientController.java"
+            line="473"
+            column="52"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_NAME` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_NAME) != 0) {"
+        errorLine2="                       ~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/AutomaticZenRule.java"
+            line="582"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_INTERRUPTION_FILTER` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_INTERRUPTION_FILTER) != 0) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/AutomaticZenRule.java"
+            line="585"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_ICON` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_ICON) != 0) {"
+        errorLine2="                       ~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/AutomaticZenRule.java"
+            line="588"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getFrameTimeNanos()` is a flagged API and should be inside an `if (Flags.expectedPresentationTimeApi())` check (or annotate the surrounding method `run` with `@FlaggedApi(Flags.FLAG_EXPECTED_PRESENTATION_TIME_API) to transfer requirement to caller`)"
+        errorLine1="                doConsumeBatchedInput(mChoreographer.getFrameTimeNanos());"
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/BatchedInputEventReceiver.java"
+            line="130"
+            column="39"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `Gainmap()` is a flagged API and should be inside an `if (Flags.gainmapConstructorWithMetadata())` check (or annotate the surrounding method `createBitmap` with `@FlaggedApi(Flags.FLAG_GAINMAP_CONSTRUCTOR_WITH_METADATA) to transfer requirement to caller`)"
+        errorLine1="                bitmap.setGainmap(new Gainmap(source.getGainmap(), newMapContents));"
+        errorLine2="                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/Bitmap.java"
+            line="1030"
+            column="35"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `Gainmap()` is a flagged API and should be inside an `if (Flags.gainmapConstructorWithMetadata())` check (or annotate the surrounding method `setOverrideGainmap` with `@FlaggedApi(Flags.FLAG_GAINMAP_CONSTRUCTOR_WITH_METADATA) to transfer requirement to caller`)"
+        errorLine1="            mOverrideGainmap = new Gainmap(overrideGainmap, overrideGainmap.getGainmapContents());"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/BitmapShader.java"
+            line="193"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `set()` is a flagged API and should be inside an `if (Flags.fixLineHeightForLocale())` check (or annotate the surrounding method `isBoring` with `@FlaggedApi(Flags.FLAG_FIX_LINE_HEIGHT_FOR_LOCALE) to transfer requirement to caller`)"
+        errorLine1="                fm.set(minimumFontMetrics);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/BoringLayout.java"
+            line="594"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getUseBoundsForWidth()` is a flagged API and should be inside an `if (Flags.useBoundsForWidth())` check (or annotate the surrounding method `getLineMax` with `@FlaggedApi(Flags.FLAG_USE_BOUNDS_FOR_WIDTH) to transfer requirement to caller`)"
+        errorLine1="        if (getUseBoundsForWidth()) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/BoringLayout.java"
+            line="658"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getUseBoundsForWidth()` is a flagged API and should be inside an `if (Flags.useBoundsForWidth())` check (or annotate the surrounding method `getLineWidth` with `@FlaggedApi(Flags.FLAG_USE_BOUNDS_FOR_WIDTH) to transfer requirement to caller`)"
+        errorLine1="        if (getUseBoundsForWidth()) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/BoringLayout.java"
+            line="667"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getShiftDrawingOffsetForStartOverhang()` is a flagged API and should be inside an `if (Flags.useBoundsForWidth())` check (or annotate the surrounding method `draw` with `@FlaggedApi(Flags.FLAG_USE_BOUNDS_FOR_WIDTH) to transfer requirement to caller`)"
+        errorLine1="            if (getUseBoundsForWidth() &amp;&amp; getShiftDrawingOffsetForStartOverhang()) {"
+        errorLine2="                                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/BoringLayout.java"
+            line="720"
+            column="43"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getUseBoundsForWidth()` is a flagged API and should be inside an `if (Flags.useBoundsForWidth())` check (or annotate the surrounding method `draw` with `@FlaggedApi(Flags.FLAG_USE_BOUNDS_FOR_WIDTH) to transfer requirement to caller`)"
+        errorLine1="            if (getUseBoundsForWidth() &amp;&amp; getShiftDrawingOffsetForStartOverhang()) {"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/BoringLayout.java"
+            line="720"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `createFromParcelBody()` is a flagged API and should be inside an `if (Flags.tiafVApis())` check (or annotate the surrounding method `createFromParcel` with `@FlaggedApi(Flags.FLAG_TIAF_V_APIS) to transfer requirement to caller`)"
+        errorLine1="                            return SignalingDataRequest.createFromParcelBody(source);"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/BroadcastInfoRequest.java"
+            line="89"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `createFromParcelBody()` is a flagged API and should be inside an `if (Flags.tiafVApis())` check (or annotate the surrounding method `createFromParcel` with `@FlaggedApi(Flags.FLAG_TIAF_V_APIS) to transfer requirement to caller`)"
+        errorLine1="                            return SignalingDataResponse.createFromParcelBody(source);"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/BroadcastInfoResponse.java"
+            line="75"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `BUGREPORT_MODE_ONBOARDING` is a flagged API and should be inside an `if (Flags.onboardingBugreportV2Enabled())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_ONBOARDING_BUGREPORT_V2_ENABLED) to transfer requirement to caller`)"
+        errorLine1="    public static final int BUGREPORT_MODE_MAX_VALUE = BUGREPORT_MODE_ONBOARDING;"
+        errorLine2="                                                       ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/BugreportParams.java"
+            line="139"
+            column="56"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `PROPERTY_IS_TRANSACTIONAL` is a flagged API and should be inside an `if (Flags.voipAppActionsSupport())` check (or annotate the surrounding method `propertiesToString` with `@FlaggedApi(Flags.FLAG_VOIP_APP_ACTIONS_SUPPORT) to transfer requirement to caller`)"
+        errorLine1="            if (hasProperty(properties, PROPERTY_IS_TRANSACTIONAL)) {"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telecomm/java/android/telecom/Call.java"
+            line="854"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getImsReasonInfo()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `handleCallDisconnected` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="        if (disconnectCause.getImsReasonInfo() != null) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telecomm/java/android/telecom/CallDiagnosticService.java"
+            line="365"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getImsReasonInfo()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `handleCallDisconnected` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="            message = callDiagnostics.onCallDisconnected(disconnectCause.getImsReasonInfo());"
+        errorLine2="                                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telecomm/java/android/telecom/CallDiagnosticService.java"
+            line="366"
+            column="58"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getTelephonyDisconnectCause()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `handleCallDisconnected` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="                    disconnectCause.getTelephonyDisconnectCause(),"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telecomm/java/android/telecom/CallDiagnosticService.java"
+            line="369"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getTelephonyPreciseDisconnectCause()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `handleCallDisconnected` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="                    disconnectCause.getTelephonyPreciseDisconnectCause());"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telecomm/java/android/telecom/CallDiagnosticService.java"
+            line="370"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `POLICY_TYPE_CAMERA` is a flagged API and should be inside an `if (Flags.virtualCamera())` check (or annotate the surrounding method `getDevicePolicyFromContext` with `@FlaggedApi(Flags.FLAG_VIRTUAL_CAMERA) to transfer requirement to caller`)"
+        errorLine1="        return virtualDeviceManager.getDevicePolicy(context.getDeviceId(), POLICY_TYPE_CAMERA);"
+        errorLine2="                                                                           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/Camera.java"
+            line="350"
+            column="76"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FALLBACK_PACKAGE_NAME` is a flagged API and should be inside an `if (Flags.concertMode())` check (or annotate the surrounding method `onSuccess` with `@FlaggedApi(Flags.FLAG_CONCERT_MODE) to transfer requirement to caller`)"
+        errorLine1="                        .getString(FALLBACK_PACKAGE_NAME);"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java"
+            line="591"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `POLICY_TYPE_CAMERA` is a flagged API and should be inside an `if (Flags.virtualCamera())` check (or annotate the surrounding method `getDevicePolicyFromContext` with `@FlaggedApi(Flags.FLAG_VIRTUAL_CAMERA) to transfer requirement to caller`)"
+        errorLine1="        return mVirtualDeviceManager.getDevicePolicy(context.getDeviceId(), POLICY_TYPE_CAMERA);"
+        errorLine2="                                                                            ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/camera2/CameraManager.java"
+            line="584"
+            column="77"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `CameraDeviceSetupImpl()` is a flagged API and should be inside an `if (Flags.cameraDeviceSetup())` check (or annotate the surrounding method `getCameraDeviceSetupUnsafe` with `@FlaggedApi(Flags.FLAG_CAMERA_DEVICE_SETUP) to transfer requirement to caller`)"
+        errorLine1="        return new CameraDeviceSetupImpl(cameraId, /*cameraManager=*/ this, mContext);"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/camera2/CameraManager.java"
+            line="903"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isCameraDeviceSetupSupported()` is a flagged API and should be inside an `if (Flags.cameraDeviceSetup())` check (or annotate the surrounding method `openCameraDeviceUserAsync` with `@FlaggedApi(Flags.FLAG_CAMERA_DEVICE_SETUP) to transfer requirement to caller`)"
+        errorLine1="                    &amp;&amp; CameraDeviceSetupImpl.isCameraDeviceSetupSupported(characteristics)) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/camera2/CameraManager.java"
+            line="983"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `DeviceStateManager` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `registerDeviceStateListener` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="                        ctx.getSystemService(DeviceStateManager.class).registerCallback("
+        errorLine2="                                             ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/camera2/CameraManager.java"
+            line="2141"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `registerCallback()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `registerDeviceStateListener` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="                        ctx.getSystemService(DeviceStateManager.class).registerCallback("
+        errorLine2="                        ^">
+        <location
+            file="frameworks/base/core/java/android/hardware/camera2/CameraManager.java"
+            line="2141"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `STATISTICS_LENS_INTRINSICS_SAMPLES` is a flagged API and should be inside an `if (Flags.concertMode())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CONCERT_MODE) to transfer requirement to caller`)"
+        errorLine1="                CaptureResult.STATISTICS_LENS_INTRINSICS_SAMPLES.getNativeKey(),"
+        errorLine2="                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/camera2/impl/CameraMetadataNative.java"
+            line="856"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `STATISTICS_LENS_INTRINSICS_SAMPLES` is a flagged API and should be inside an `if (Flags.concertMode())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CONCERT_MODE) to transfer requirement to caller`)"
+        errorLine1="                CaptureResult.STATISTICS_LENS_INTRINSICS_SAMPLES.getNativeKey(),"
+        errorLine2="                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/camera2/impl/CameraMetadataNative.java"
+            line="2021"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="                    KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY,"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8054"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_EMERGENCY_OVER_IMS_ROAMING_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="                    KEY_EMERGENCY_OVER_IMS_ROAMING_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY,"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8060"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_EMERGENCY_OVER_CS_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="                    KEY_EMERGENCY_OVER_CS_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY,"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8066"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_EMERGENCY_OVER_CS_ROAMING_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="                    KEY_EMERGENCY_OVER_CS_ROAMING_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY,"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8073"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY,"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8079"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `DOMAIN_PS_3GPP` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="                        DOMAIN_PS_3GPP,"
+        errorLine2="                        ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8081"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `DOMAIN_CS` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="                        DOMAIN_CS,"
+        errorLine2="                        ~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8082"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `DOMAIN_PS_NON_3GPP` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="                        DOMAIN_PS_NON_3GPP"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8083"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_EMERGENCY_DOMAIN_PREFERENCE_ROAMING_INT_ARRAY` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_ROAMING_INT_ARRAY,"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8085"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `DOMAIN_PS_3GPP` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="                        DOMAIN_PS_3GPP,"
+        errorLine2="                        ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8087"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `DOMAIN_CS` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="                        DOMAIN_CS,"
+        errorLine2="                        ~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8088"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `DOMAIN_PS_NON_3GPP` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="                        DOMAIN_PS_NON_3GPP"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8089"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_PREFER_IMS_EMERGENCY_WHEN_VOICE_CALLS_ON_CS_BOOL` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putBoolean(KEY_PREFER_IMS_EMERGENCY_WHEN_VOICE_CALLS_ON_CS_BOOL, false);"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8092"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_EMERGENCY_VOWIFI_REQUIRES_CONDITION_INT` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putInt(KEY_EMERGENCY_VOWIFI_REQUIRES_CONDITION_INT, VOWIFI_REQUIRES_NONE);"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8093"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `VOWIFI_REQUIRES_NONE` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putInt(KEY_EMERGENCY_VOWIFI_REQUIRES_CONDITION_INT, VOWIFI_REQUIRES_NONE);"
+        errorLine2="                                                                         ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8093"
+            column="74"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_MAXIMUM_NUMBER_OF_EMERGENCY_TRIES_OVER_VOWIFI_INT` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putInt(KEY_MAXIMUM_NUMBER_OF_EMERGENCY_TRIES_OVER_VOWIFI_INT, 1);"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8094"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_EMERGENCY_SCAN_TIMER_SEC_INT` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putInt(KEY_EMERGENCY_SCAN_TIMER_SEC_INT, 10);"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8095"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_MAXIMUM_CELLULAR_SEARCH_TIMER_SEC_INT` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putInt(KEY_MAXIMUM_CELLULAR_SEARCH_TIMER_SEC_INT, REDIAL_TIMER_DISABLED);"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8096"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `REDIAL_TIMER_DISABLED` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putInt(KEY_MAXIMUM_CELLULAR_SEARCH_TIMER_SEC_INT, REDIAL_TIMER_DISABLED);"
+        errorLine2="                                                                       ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8096"
+            column="72"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_EMERGENCY_NETWORK_SCAN_TYPE_INT` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putInt(KEY_EMERGENCY_NETWORK_SCAN_TYPE_INT, SCAN_TYPE_NO_PREFERENCE);"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8097"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SCAN_TYPE_NO_PREFERENCE` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putInt(KEY_EMERGENCY_NETWORK_SCAN_TYPE_INT, SCAN_TYPE_NO_PREFERENCE);"
+        errorLine2="                                                                 ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8097"
+            column="66"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_EMERGENCY_CALL_SETUP_TIMER_ON_CURRENT_NETWORK_SEC_INT` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putInt(KEY_EMERGENCY_CALL_SETUP_TIMER_ON_CURRENT_NETWORK_SEC_INT, 0);"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8098"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_EMERGENCY_REQUIRES_IMS_REGISTRATION_BOOL` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putBoolean(KEY_EMERGENCY_REQUIRES_IMS_REGISTRATION_BOOL, false);"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8099"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_EMERGENCY_LTE_PREFERRED_AFTER_NR_FAILED_BOOL` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putBoolean(KEY_EMERGENCY_LTE_PREFERRED_AFTER_NR_FAILED_BOOL, false);"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8100"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_EMERGENCY_REQUIRES_VOLTE_ENABLED_BOOL` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putBoolean(KEY_EMERGENCY_REQUIRES_VOLTE_ENABLED_BOOL, false);"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8101"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_EMERGENCY_CDMA_PREFERRED_NUMBERS_STRING_ARRAY` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putStringArray(KEY_EMERGENCY_CDMA_PREFERRED_NUMBERS_STRING_ARRAY,"
+        errorLine2="                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8102"
+            column="37"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putInt(KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT, 120);"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8104"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT, REDIAL_TIMER_DISABLED);"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8105"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `REDIAL_TIMER_DISABLED` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT, REDIAL_TIMER_DISABLED);"
+        errorLine2="                                                                        ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8105"
+            column="73"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_START_QUICK_CROSS_STACK_REDIAL_TIMER_WHEN_REGISTERED_BOOL` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putBoolean(KEY_START_QUICK_CROSS_STACK_REDIAL_TIMER_WHEN_REGISTERED_BOOL,"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8106"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_SCAN_LIMITED_SERVICE_AFTER_VOLTE_FAILURE_BOOL` is a flagged API and should be inside an `if (Flags.useOemDomainSelectionService())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_USE_OEM_DOMAIN_SELECTION_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            defaults.putBoolean(KEY_SCAN_LIMITED_SERVICE_AFTER_VOLTE_FAILURE_BOOL, false);"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="8108"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_SUPPORTS_IKE_SESSION_MULTIPLE_SA_PROPOSALS_BOOL` is a flagged API and should be inside an `if (Flags.enableMultipleSaProposals())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_ENABLE_MULTIPLE_SA_PROPOSALS) to transfer requirement to caller`)"
+        errorLine1="            defaults.putBoolean(KEY_SUPPORTS_IKE_SESSION_MULTIPLE_SA_PROPOSALS_BOOL, false);"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="9405"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_SUPPORTS_CHILD_SESSION_MULTIPLE_SA_PROPOSALS_BOOL` is a flagged API and should be inside an `if (Flags.enableMultipleSaProposals())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_ENABLE_MULTIPLE_SA_PROPOSALS) to transfer requirement to caller`)"
+        errorLine1="            defaults.putBoolean(KEY_SUPPORTS_CHILD_SESSION_MULTIPLE_SA_PROPOSALS_BOOL, false);"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="9406"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_SUPPORTED_IKE_SESSION_AEAD_ALGORITHMS_INT_ARRAY` is a flagged API and should be inside an `if (Flags.enableAeadAlgorithms())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_ENABLE_AEAD_ALGORITHMS) to transfer requirement to caller`)"
+        errorLine1="                    KEY_SUPPORTED_IKE_SESSION_AEAD_ALGORITHMS_INT_ARRAY, new int[] {});"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="9422"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_SUPPORTED_CHILD_SESSION_AEAD_ALGORITHMS_INT_ARRAY` is a flagged API and should be inside an `if (Flags.enableAeadAlgorithms())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_ENABLE_AEAD_ALGORITHMS) to transfer requirement to caller`)"
+        errorLine1="                    KEY_SUPPORTED_CHILD_SESSION_AEAD_ALGORITHMS_INT_ARRAY, new int[] {});"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="9427"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_IKE_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY` is a flagged API and should be inside an `if (Flags.enableAeadAlgorithms())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_ENABLE_AEAD_ALGORITHMS) to transfer requirement to caller`)"
+        errorLine1="                    KEY_IKE_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY, new int[] {});"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="9477"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_CHILD_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY` is a flagged API and should be inside an `if (Flags.enableAeadAlgorithms())` check (or annotate the surrounding method `getDefaults` with `@FlaggedApi(Flags.FLAG_ENABLE_AEAD_ALGORITHMS) to transfer requirement to caller`)"
+        errorLine1="                    KEY_CHILD_SESSION_AES_GCM_KEY_SIZE_INT_ARRAY, new int[] {});"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="9479"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_ADDITIONAL_SETTINGS_CALLER_ID_VISIBILITY_BOOL` is a flagged API and should be inside an `if (Flags.showCallIdAndCallWaitingInAdditionalSettingsMenu())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_SHOW_CALL_ID_AND_CALL_WAITING_IN_ADDITIONAL_SETTINGS_MENU) to transfer requirement to caller`)"
+        errorLine1="        sDefaults.putBoolean(KEY_ADDITIONAL_SETTINGS_CALLER_ID_VISIBILITY_BOOL, true);"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="10519"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_ADDITIONAL_SETTINGS_CALL_WAITING_VISIBILITY_BOOL` is a flagged API and should be inside an `if (Flags.showCallIdAndCallWaitingInAdditionalSettingsMenu())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_SHOW_CALL_ID_AND_CALL_WAITING_IN_ADDITIONAL_SETTINGS_MENU) to transfer requirement to caller`)"
+        errorLine1="        sDefaults.putBoolean(KEY_ADDITIONAL_SETTINGS_CALL_WAITING_VISIBILITY_BOOL, true);"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="10520"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_PREFER_3G_VISIBILITY_BOOL` is a flagged API and should be inside an `if (Flags.hidePrefer3gItem())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_HIDE_PREFER_3G_ITEM) to transfer requirement to caller`)"
+        errorLine1="        sDefaults.putBoolean(KEY_PREFER_3G_VISIBILITY_BOOL, true);"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="10526"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_SHOW_ROAMING_INDICATOR_BOOL` is a flagged API and should be inside an `if (Flags.hideRoamingIcon())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_HIDE_ROAMING_ICON) to transfer requirement to caller`)"
+        errorLine1="        sDefaults.putBoolean(KEY_SHOW_ROAMING_INDICATOR_BOOL, true);"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="10794"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="                KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE,"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="11093"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_SATELLITE_ATTACH_SUPPORTED_BOOL` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="        sDefaults.putBoolean(KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, false);"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="11095"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="        sDefaults.putInt(KEY_SATELLITE_CONNECTION_HYSTERESIS_SEC_INT, 300);"
+        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="11096"
+            column="26"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_NTN_LTE_RSRP_THRESHOLDS_INT_ARRAY` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="        sDefaults.putIntArray(KEY_NTN_LTE_RSRP_THRESHOLDS_INT_ARRAY,"
+        errorLine2="                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="11097"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_NTN_LTE_RSRQ_THRESHOLDS_INT_ARRAY` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="        sDefaults.putIntArray(KEY_NTN_LTE_RSRQ_THRESHOLDS_INT_ARRAY,"
+        errorLine2="                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="11105"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_NTN_LTE_RSSNR_THRESHOLDS_INT_ARRAY` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="        sDefaults.putIntArray(KEY_NTN_LTE_RSSNR_THRESHOLDS_INT_ARRAY,"
+        errorLine2="                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="11113"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_PARAMETERS_USED_FOR_NTN_LTE_SIGNAL_BAR_INT` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="        sDefaults.putInt(KEY_PARAMETERS_USED_FOR_NTN_LTE_SIGNAL_BAR_INT,"
+        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="11121"
+            column="26"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_SATELLITE_ENTITLEMENT_STATUS_REFRESH_DAYS_INT` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="        sDefaults.putInt(KEY_SATELLITE_ENTITLEMENT_STATUS_REFRESH_DAYS_INT, 7);"
+        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="11127"
+            column="26"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="        sDefaults.putBoolean(KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, false);"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="11128"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SERVICE_TYPE_MMS` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="                        NetworkRegistrationInfo.SERVICE_TYPE_MMS"
+        errorLine2="                                                ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="11134"
+            column="49"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_SUPPORTS_BUSINESS_CALL_COMPOSER_BOOL` is a flagged API and should be inside an `if (Flags.businessCallComposer())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_BUSINESS_CALL_COMPOSER) to transfer requirement to caller`)"
+        errorLine1="        sDefaults.putBoolean(KEY_SUPPORTS_BUSINESS_CALL_COMPOSER_BOOL, false);"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="11142"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_CELLULAR_SERVICE_CAPABILITIES_INT_ARRAY` is a flagged API and should be inside an `if (Flags.dataOnlyCellularService())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_DATA_ONLY_CELLULAR_SERVICE) to transfer requirement to caller`)"
+        errorLine1="        sDefaults.putIntArray(KEY_CELLULAR_SERVICE_CAPABILITIES_INT_ARRAY, new int[]{1, 2, 3});"
+        errorLine2="                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="11233"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `TelephonyRegistryManager` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `registerCarrierConfigChangeListener` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="        TelephonyRegistryManager trm = mContext.getSystemService(TelephonyRegistryManager.class);"
+        errorLine2="                                                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="11771"
+            column="66"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `addCarrierConfigChangedListener()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `registerCarrierConfigChangeListener` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="        trm.addCarrierConfigChangedListener(executor, listener);"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="11775"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `TelephonyRegistryManager` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `unregisterCarrierConfigChangeListener` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="        TelephonyRegistryManager trm = mContext.getSystemService(TelephonyRegistryManager.class);"
+        errorLine2="                                                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="11789"
+            column="66"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `removeCarrierConfigChangedListener()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `unregisterCarrierConfigChangeListener` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="        trm.removeCarrierConfigChangedListener(listener);"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java"
+            line="11793"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="This is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `notifyCarrierNetworkChange` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="            (TelephonyRegistryManager) this.getSystemService("
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/service/carrier/CarrierService.java"
+            line="180"
+            column="14"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `notifyCarrierNetworkChange()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `notifyCarrierNetworkChange` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="            telephonyRegistryMgr.notifyCarrierNetworkChange(active);"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/service/carrier/CarrierService.java"
+            line="183"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `TelephonyRegistryManager` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `notifyCarrierNetworkChange` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="                TelephonyRegistryManager.class);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/service/carrier/CarrierService.java"
+            line="206"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `notifyCarrierNetworkChange()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `notifyCarrierNetworkChange` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="            telephonyRegistryMgr.notifyCarrierNetworkChange(subscriptionId, active);"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/service/carrier/CarrierService.java"
+            line="208"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isUsingNonTerrestrialNetwork()` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `updateLevel` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="            if (ss != null &amp;&amp; ss.isUsingNonTerrestrialNetwork()) {"
+        errorLine2="                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CellSignalStrengthLte.java"
+            line="266"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_PARAMETERS_USED_FOR_NTN_LTE_SIGNAL_BAR_INT` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `updateLevel` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="                        CarrierConfigManager.KEY_PARAMETERS_USED_FOR_NTN_LTE_SIGNAL_BAR_INT);"
+        errorLine2="                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CellSignalStrengthLte.java"
+            line="269"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_NTN_LTE_RSRP_THRESHOLDS_INT_ARRAY` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `updateLevel` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="                        CarrierConfigManager.KEY_NTN_LTE_RSRP_THRESHOLDS_INT_ARRAY);"
+        errorLine2="                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CellSignalStrengthLte.java"
+            line="271"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_NTN_LTE_RSRQ_THRESHOLDS_INT_ARRAY` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `updateLevel` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="                        CarrierConfigManager.KEY_NTN_LTE_RSRQ_THRESHOLDS_INT_ARRAY);"
+        errorLine2="                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CellSignalStrengthLte.java"
+            line="273"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEY_NTN_LTE_RSSNR_THRESHOLDS_INT_ARRAY` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `updateLevel` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="                        CarrierConfigManager.KEY_NTN_LTE_RSSNR_THRESHOLDS_INT_ARRAY);"
+        errorLine2="                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/CellSignalStrengthLte.java"
+            line="275"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getFrameTimeNanos()` is a flagged API and should be inside an `if (Flags.expectedPresentationTimeApi())` check (or annotate the surrounding method `getFrameTime` with `@FlaggedApi(Flags.FLAG_EXPECTED_PRESENTATION_TIME_API) to transfer requirement to caller`)"
+        errorLine1="        return getFrameTimeNanos() / TimeUtils.NANOS_PER_MS;"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/Choreographer.java"
+            line="694"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `lockAnimationClock()` is a flagged API and should be inside an `if (Flags.expectedPresentationTimeReadOnly())` check (or annotate the surrounding method `doFrame` with `@FlaggedApi(Flags.FLAG_EXPECTED_PRESENTATION_TIME_READ_ONLY) to transfer requirement to caller`)"
+        errorLine1="            AnimationUtils.lockAnimationClock(frameTimeNanos / TimeUtils.NANOS_PER_MS,"
+        errorLine2="            ^">
+        <location
+            file="frameworks/base/core/java/android/view/Choreographer.java"
+            line="934"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SOURCE_UNKNOWN` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `Condition` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        this(id, summary, &quot;&quot;, &quot;&quot;, -1, state, SOURCE_UNKNOWN, FLAG_RELEVANT_ALWAYS);"
+        errorLine2="                                             ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/Condition.java"
+            line="138"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `Condition()` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `Condition` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        this(id, summary, &quot;&quot;, &quot;&quot;, -1, state, SOURCE_UNKNOWN, FLAG_RELEVANT_ALWAYS);"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/Condition.java"
+            line="138"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SOURCE_UNKNOWN` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `Condition` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        this(id, summary, line1, line2, icon, state, SOURCE_UNKNOWN, flags);"
+        errorLine2="                                                     ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/Condition.java"
+            line="157"
+            column="54"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `Condition()` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `Condition` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        this(id, summary, line1, line2, icon, state, SOURCE_UNKNOWN, flags);"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/Condition.java"
+            line="157"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `Condition()` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `Condition` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        this((Uri)source.readParcelable(Condition.class.getClassLoader(), android.net.Uri.class),"
+        errorLine2="        ^">
+        <location
+            file="frameworks/base/core/java/android/service/notification/Condition.java"
+            line="192"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SOURCE_UNKNOWN` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `Condition` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="                Flags.modesApi() ? source.readInt() : SOURCE_UNKNOWN,"
+        errorLine2="                                                      ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/Condition.java"
+            line="198"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onCreateConnectionComplete()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `notifyCreateConnectionComplete` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="        onCreateConnectionComplete(findConnectionForAction(callId,"
+        errorLine2="        ^">
+        <location
+            file="frameworks/base/telecomm/java/android/telecom/ConnectionService.java"
+            line="2531"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onCreateConferenceComplete()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `notifyCreateConferenceComplete` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="        onCreateConferenceComplete(findConferenceForAction(callId,"
+        errorLine2="        ^">
+        <location
+            file="frameworks/base/telecomm/java/android/telecom/ConnectionService.java"
+            line="2548"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getCallDirection()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `addExistingConnection` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="                    connection.getCallDirection(),"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telecomm/java/android/telecom/ConnectionService.java"
+            line="3179"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `supportsReliableMessages()` is a flagged API and should be inside an `if (Flags.reliableMessage())` check (or annotate the surrounding method `equals` with `@FlaggedApi(Flags.FLAG_RELIABLE_MESSAGE) to transfer requirement to caller`)"
+        errorLine1="                            || (other.supportsReliableMessages() == mSupportsReliableMessages))"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/location/ContextHubInfo.java"
+            line="365"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isReliable()` is a flagged API and should be inside an `if (Flags.reliableMessage())` check (or annotate the surrounding method `onMessageFromNanoApp` with `@FlaggedApi(Flags.FLAG_RELIABLE_MESSAGE) to transfer requirement to caller`)"
+        errorLine1="                                        &amp;&amp; message.isReliable()) {"
+        errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/location/ContextHubManager.java"
+            line="715"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TYPE_RELIABLE_MESSAGE` is a flagged API and should be inside an `if (Flags.reliableMessage())` check (or annotate the surrounding method `typeToString` with `@FlaggedApi(Flags.FLAG_RELIABLE_MESSAGE) to transfer requirement to caller`)"
+        errorLine1="            case ContextHubTransaction.TYPE_RELIABLE_MESSAGE: {"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/location/ContextHubTransaction.java"
+            line="235"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `shouldRegisterAttributionSource()` is a flagged API and should be inside an `if (Flags.shouldRegisterAttributionSource())` check (or annotate the surrounding method `ContextImpl` with `@FlaggedApi(Flags.FLAG_SHOULD_REGISTER_ATTRIBUTION_SOURCE) to transfer requirement to caller`)"
+        errorLine1="                params.getRenouncedPermissions(), params.shouldRegisterAttributionSource(), mDeviceId);"
+        errorLine2="                                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/ContextImpl.java"
+            line="3540"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `NETWORK_VALIDATION_UNSUPPORTED` is a flagged API and should be inside an `if (Flags.networkValidation())` check (or annotate the surrounding method `DataCallResponse` with `@FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) to transfer requirement to caller`)"
+        errorLine1="                PreciseDataConnectionState.NETWORK_VALIDATION_UNSUPPORTED);"
+        errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/data/DataCallResponse.java"
+            line="192"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `NETWORK_VALIDATION_UNSUPPORTED` is a flagged API and should be inside an `if (Flags.networkValidation())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) to transfer requirement to caller`)"
+        errorLine1="                PreciseDataConnectionState.NETWORK_VALIDATION_UNSUPPORTED;"
+        errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/data/DataCallResponse.java"
+            line="655"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TYPE_RCS` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `networkCapabilityToApnType` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="                return ApnSetting.TYPE_RCS;"
+        errorLine2="                                  ~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/data/DataProfile.java"
+            line="435"
+            column="35"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `requestNetworkValidation()` is a flagged API and should be inside an `if (Flags.networkValidation())` check (or annotate the surrounding method `handleMessage` with `@FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) to transfer requirement to caller`)"
+        errorLine1="                    serviceProvider.requestNetworkValidation("
+        errorLine2="                    ^">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/data/DataService.java"
+            line="744"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `HEADLESS_DEVICE_OWNER_MODE_SINGLE_USER` is a flagged API and should be inside an `if (Flags.headlessDeviceOwnerSingleUserEnabled())` check (or annotate the surrounding method `DeviceAdminInfo` with `@FlaggedApi(Flags.FLAG_HEADLESS_DEVICE_OWNER_SINGLE_USER_ENABLED) to transfer requirement to caller`)"
+        errorLine1="                        mHeadlessDeviceOwnerMode = HEADLESS_DEVICE_OWNER_MODE_SINGLE_USER;"
+        errorLine2="                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/admin/DeviceAdminInfo.java"
+            line="410"
+            column="52"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CONTENT_PROTECTION_DISABLED` is a flagged API and should be inside an `if (Flags.manageDevicePolicyEnabled())` check (or annotate the surrounding method `getContentProtectionPolicy` with `@FlaggedApi(Flags.FLAG_MANAGE_DEVICE_POLICY_ENABLED) to transfer requirement to caller`)"
+        errorLine1="            return CONTENT_PROTECTION_DISABLED;"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/admin/DevicePolicyCache.java"
+            line="105"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `equals()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `equals` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="        return baseState.equals(that.baseState)"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateInfo.java"
+            line="101"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `equals()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `equals` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="                &amp;&amp;  currentState.equals(that.currentState)"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateInfo.java"
+            line="102"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `equals()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `diff` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="        if (!baseState.equals(other.baseState)) {"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateInfo.java"
+            line="120"
+            column="14"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `equals()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `diff` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="        if (!currentState.equals(other.currentState)) {"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateInfo.java"
+            line="123"
+            column="14"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getConfiguration()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `writeToParcel` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="            dest.writeTypedObject(supportedStates.get(i).getConfiguration(), flags);"
+        errorLine2="                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateInfo.java"
+            line="133"
+            column="35"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getConfiguration()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `writeToParcel` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="        dest.writeTypedObject(baseState.getConfiguration(), flags);"
+        errorLine2="                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateInfo.java"
+            line="136"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getConfiguration()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `writeToParcel` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="        dest.writeTypedObject(currentState.getConfiguration(), flags);"
+        errorLine2="                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateInfo.java"
+            line="137"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CREATOR` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `createFromParcel` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="                        DeviceState.Configuration.CREATOR);"
+        errorLine2="                                                  ~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateInfo.java"
+            line="152"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `DeviceState()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `createFromParcel` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="                supportedStates.add(i, new DeviceState(configuration));"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateInfo.java"
+            line="153"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `DeviceState()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `createFromParcel` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="            final DeviceState baseState = new DeviceState("
+        errorLine2="                                          ^">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateInfo.java"
+            line="156"
+            column="43"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CREATOR` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `createFromParcel` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="                    source.readTypedObject(DeviceState.Configuration.CREATOR));"
+        errorLine2="                                                                     ~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateInfo.java"
+            line="157"
+            column="70"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `DeviceState()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `createFromParcel` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="            final DeviceState currentState = new DeviceState("
+        errorLine2="                                             ^">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateInfo.java"
+            line="158"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CREATOR` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `createFromParcel` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="                    source.readTypedObject(DeviceState.Configuration.CREATOR));"
+        errorLine2="                                                                     ~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateInfo.java"
+            line="159"
+            column="70"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onSupportedStatesChanged()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `notifySupportedDeviceStatesChanged` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="                    mDeviceStateCallback.onSupportedStatesChanged(newSupportedDeviceStates));"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java"
+            line="393"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onDeviceStateChanged()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `notifyDeviceStateChanged` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="                    () -> mDeviceStateCallback.onDeviceStateChanged(newDeviceState));"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java"
+            line="398"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getConfiguration()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `calculateBaseStateIdentifier` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="        DeviceState.Configuration stateConfiguration = currentState.getConfiguration();"
+        errorLine2="                                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateUtil.java"
+            line="45"
+            column="56"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getConfiguration()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `calculateBaseStateIdentifier` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="            if (stateToCompare.getConfiguration().getPhysicalProperties().isEmpty()) {"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateUtil.java"
+            line="48"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getPhysicalProperties()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `calculateBaseStateIdentifier` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="            if (stateToCompare.getConfiguration().getPhysicalProperties().isEmpty()) {"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateUtil.java"
+            line="48"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getPhysicalProperties()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `calculateBaseStateIdentifier` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="            if (isDeviceStateMatchingPhysicalProperties(stateConfiguration.getPhysicalProperties(),"
+        errorLine2="                                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateUtil.java"
+            line="51"
+            column="57"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getIdentifier()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `calculateBaseStateIdentifier` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="                return supportedStates.get(i).getIdentifier();"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateUtil.java"
+            line="53"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `INVALID_DEVICE_STATE_IDENTIFIER` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `calculateBaseStateIdentifier` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="        return INVALID_DEVICE_STATE_IDENTIFIER;"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateUtil.java"
+            line="56"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `hasProperty()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `isDeviceStateMatchingPhysicalProperties` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="            if (!state.hasProperty(iterator.next())) {"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/devicestate/DeviceStateUtil.java"
+            line="69"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getTelephonyDisconnectCause()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `equals` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="                    &amp;&amp; Objects.equals(mTelephonyDisconnectCause, d.getTelephonyDisconnectCause())"
+        errorLine2="                                                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telecomm/java/android/telecom/DisconnectCause.java"
+            line="498"
+            column="66"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getTelephonyPreciseDisconnectCause()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `equals` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="                    d.getTelephonyPreciseDisconnectCause())"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telecomm/java/android/telecom/DisconnectCause.java"
+            line="500"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getImsReasonInfo()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `equals` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="                    &amp;&amp; Objects.equals(mImsReasonInfo, d.getImsReasonInfo());"
+        errorLine2="                                                      ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telecomm/java/android/telecom/DisconnectCause.java"
+            line="501"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SATELLITE_ENABLED` is a flagged API and should be inside an `if (Flags.oemEnabledSatelliteFlag())` check (or annotate the surrounding method `toString` with `@FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="            case SATELLITE_ENABLED:"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/DisconnectCause.java"
+            line="550"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `dreamCategory` is a flagged API and should be inside an `if (Flags.homePanelDream())` check (or annotate the surrounding method `DreamMetadata` with `@FlaggedApi(Flags.FLAG_HOME_PANEL_DREAM) to transfer requirement to caller`)"
+        errorLine1="                this.dreamCategory = DREAM_CATEGORY_DEFAULT;"
+        errorLine2="                     ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/dreams/DreamService.java"
+            line="1825"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setMinimumFontMetrics()` is a flagged API and should be inside an `if (Flags.fixLineHeightForLocale())` check (or annotate the surrounding method `reflow` with `@FlaggedApi(Flags.FLAG_FIX_LINE_HEIGHT_FOR_LOCALE) to transfer requirement to caller`)"
+        errorLine1="        b.setText(text, where, where + after)"
+        errorLine2="        ^">
+        <location
+            file="frameworks/base/core/java/android/text/DynamicLayout.java"
+            line="736"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setShiftDrawingOffsetForStartOverhang()` is a flagged API and should be inside an `if (Flags.useBoundsForWidth())` check (or annotate the surrounding method `reflow` with `@FlaggedApi(Flags.FLAG_USE_BOUNDS_FOR_WIDTH) to transfer requirement to caller`)"
+        errorLine1="        b.setText(text, where, where + after)"
+        errorLine2="        ^">
+        <location
+            file="frameworks/base/core/java/android/text/DynamicLayout.java"
+            line="736"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setUseBoundsForWidth()` is a flagged API and should be inside an `if (Flags.useBoundsForWidth())` check (or annotate the surrounding method `reflow` with `@FlaggedApi(Flags.FLAG_USE_BOUNDS_FOR_WIDTH) to transfer requirement to caller`)"
+        errorLine1="        b.setText(text, where, where + after)"
+        errorLine2="        ^">
+        <location
+            file="frameworks/base/core/java/android/text/DynamicLayout.java"
+            line="736"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getTextDirectionHeuristic()` is a flagged API and should be inside an `if (Flags.useBoundsForWidth())` check (or annotate the surrounding method `reflow` with `@FlaggedApi(Flags.FLAG_USE_BOUNDS_FOR_WIDTH) to transfer requirement to caller`)"
+        errorLine1="                .setTextDirection(getTextDirectionHeuristic())"
+        errorLine2="                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/DynamicLayout.java"
+            line="739"
+            column="35"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setLocalePreferredLineHeightForMinimumUsed()` is a flagged API and should be inside an `if (Flags.fixLineHeightForLocale())` check (or annotate the surrounding method `EditText` with `@FlaggedApi(Flags.FLAG_FIX_LINE_HEIGHT_FOR_LOCALE) to transfer requirement to caller`)"
+        errorLine1="        setLocalePreferredLineHeightForMinimumUsed(useLocalePreferredLineHeightForMinimumInt);"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/widget/EditText.java"
+            line="150"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `convertSpToDp()` is a flagged API and should be inside an `if (Flags.fontScaleConverterPublic())` check (or annotate the surrounding method `createInterpolatedTableBetween` with `@FlaggedApi(Flags.FLAG_FONT_SCALE_CONVERTER_PUBLIC) to transfer requirement to caller`)"
+        errorLine1="            float startDp = start.convertSpToDp(sp);"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/res/FontScaleConverterFactory.java"
+            line="242"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `convertSpToDp()` is a flagged API and should be inside an `if (Flags.fontScaleConverterPublic())` check (or annotate the surrounding method `createInterpolatedTableBetween` with `@FlaggedApi(Flags.FLAG_FONT_SCALE_CONVERTER_PUBLIC) to transfer requirement to caller`)"
+        errorLine1="            float endDp = end.convertSpToDp(sp);"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/res/FontScaleConverterFactory.java"
+            line="243"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="This is a flagged API and should be inside an `if (Flags.fontScaleConverterPublic())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_FONT_SCALE_CONVERTER_PUBLIC) to transfer requirement to caller`)"
+        errorLine1="public class FontScaleConverterImpl implements FontScaleConverter {"
+        errorLine2="                                               ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/res/FontScaleConverterImpl.java"
+            line="36"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FOREGROUND_SERVICE_TYPE_MEDIA_PROCESSING` is a flagged API and should be inside an `if (Flags.introduceMediaProcessingType())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_INTRODUCE_MEDIA_PROCESSING_TYPE) to transfer requirement to caller`)"
+        errorLine1="                    FOREGROUND_SERVICE_TYPE_MEDIA_PROCESSING,"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/ForegroundServiceTypePolicy.java"
+            line="587"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FOREGROUND_SERVICE_TYPE_MEDIA_PROCESSING` is a flagged API and should be inside an `if (Flags.introduceMediaProcessingType())` check (or annotate the surrounding method `DefaultForegroundServiceTypePolicy` with `@FlaggedApi(Flags.FLAG_INTRODUCE_MEDIA_PROCESSING_TYPE) to transfer requirement to caller`)"
+        errorLine1="            mForegroundServiceTypePolicies.put(FOREGROUND_SERVICE_TYPE_MEDIA_PROCESSING,"
+        errorLine2="                                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/ForegroundServiceTypePolicy.java"
+            line="1355"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `InputTransferToken()` is a flagged API and should be inside an `if (Flags.surfaceControlInputReceiver())` check (or annotate the surrounding method `doCreate` with `@FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) to transfer requirement to caller`)"
+        errorLine1="                        new InputTransferToken(), &quot;GameSessionService&quot;);"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/games/GameSessionService.java"
+            line="127"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CREATOR` is a flagged API and should be inside an `if (Flags.configurableSelectorUiEnabled())` check (or annotate the surrounding method `GetCandidateCredentialsResponse` with `@FlaggedApi(Flags.FLAG_CONFIGURABLE_SELECTOR_UI_ENABLED) to transfer requirement to caller`)"
+        errorLine1="        in.readTypedList(candidateProviderDataList, GetCredentialProviderData.CREATOR);"
+        errorLine2="                                                                              ~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/credentials/GetCandidateCredentialsResponse.java"
+            line="98"
+            column="79"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isConnectionlessStylusHandwritingAvailable()` is a flagged API and should be inside an `if (Flags.connectionlessHandwriting())` check (or annotate the surrounding method `prepareDelegation` with `@FlaggedApi(Flags.FLAG_CONNECTIONLESS_HANDWRITING) to transfer requirement to caller`)"
+        errorLine1="        if (mImm.isConnectionlessStylusHandwritingAvailable()) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/HandwritingInitiator.java"
+            line="450"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `startConnectionlessStylusHandwritingForDelegation()` is a flagged API and should be inside an `if (Flags.connectionlessHandwriting())` check (or annotate the surrounding method `prepareDelegation` with `@FlaggedApi(Flags.FLAG_CONNECTIONLESS_HANDWRITING) to transfer requirement to caller`)"
+        errorLine1="            mImm.startConnectionlessStylusHandwritingForDelegation("
+        errorLine2="            ^">
+        <location
+            file="frameworks/base/core/java/android/view/HandwritingInitiator.java"
+            line="454"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="This is a flagged API and should be inside an `if (Flags.connectionlessHandwriting())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CONNECTIONLESS_HANDWRITING) to transfer requirement to caller`)"
+        errorLine1="    private class DelegationCallback implements ConnectionlessHandwritingCallback {"
+        errorLine2="                                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/HandwritingInitiator.java"
+            line="1116"
+            column="49"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CONNECTIONLESS_HANDWRITING_ERROR_NO_TEXT_RECOGNIZED` is a flagged API and should be inside an `if (Flags.connectionlessHandwriting())` check (or annotate the surrounding method `onError` with `@FlaggedApi(Flags.FLAG_CONNECTIONLESS_HANDWRITING) to transfer requirement to caller`)"
+        errorLine1="                case CONNECTIONLESS_HANDWRITING_ERROR_NO_TEXT_RECOGNIZED:"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/HandwritingInitiator.java"
+            line="1133"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CONNECTIONLESS_HANDWRITING_ERROR_UNSUPPORTED` is a flagged API and should be inside an `if (Flags.connectionlessHandwriting())` check (or annotate the surrounding method `onError` with `@FlaggedApi(Flags.FLAG_CONNECTIONLESS_HANDWRITING) to transfer requirement to caller`)"
+        errorLine1="                case CONNECTIONLESS_HANDWRITING_ERROR_UNSUPPORTED:"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/HandwritingInitiator.java"
+            line="1136"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="This is a flagged API and should be inside an `if (Flags.scrollFeedbackApi())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_SCROLL_FEEDBACK_API) to transfer requirement to caller`)"
+        errorLine1="public class HapticScrollFeedbackProvider implements ScrollFeedbackProvider {"
+        errorLine2="                                                     ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/HapticScrollFeedbackProvider.java"
+            line="36"
+            column="54"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getOverlaySupport()` is a flagged API and should be inside an `if (Flags.overlaypropertiesClassApi())` check (or annotate the surrounding method `initDisplayInfo` with `@FlaggedApi(Flags.FLAG_OVERLAYPROPERTIES_CLASS_API) to transfer requirement to caller`)"
+        errorLine1="            final OverlayProperties overlayProperties = defaultDisplay.getOverlaySupport();"
+        errorLine2="                                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/HardwareRenderer.java"
+            line="1394"
+            column="57"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isCombinationSupported()` is a flagged API and should be inside an `if (Flags.overlaypropertiesClassApi())` check (or annotate the surrounding method `initDisplayInfo` with `@FlaggedApi(Flags.FLAG_OVERLAYPROPERTIES_CLASS_API) to transfer requirement to caller`)"
+        errorLine1="                    overlayProperties.isCombinationSupported("
+        errorLine2="                    ^">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/HardwareRenderer.java"
+            line="1422"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isCombinationSupported()` is a flagged API and should be inside an `if (Flags.overlaypropertiesClassApi())` check (or annotate the surrounding method `initDisplayInfo` with `@FlaggedApi(Flags.FLAG_OVERLAYPROPERTIES_CLASS_API) to transfer requirement to caller`)"
+        errorLine1="                    overlayProperties.isCombinationSupported("
+        errorLine2="                    ^">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/HardwareRenderer.java"
+            line="1424"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `RGBA_10101010` is a flagged API and should be inside an `if (Flags.requestedFormatsV())` check (or annotate the surrounding method `initDisplayInfo` with `@FlaggedApi(Flags.FLAG_REQUESTED_FORMATS_V) to transfer requirement to caller`)"
+        errorLine1="                            HardwareBuffer.RGBA_10101010),"
+        errorLine2="                                           ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/HardwareRenderer.java"
+            line="1429"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isMixedColorSpacesSupported()` is a flagged API and should be inside an `if (Flags.overlaypropertiesClassApi())` check (or annotate the surrounding method `initDisplayInfo` with `@FlaggedApi(Flags.FLAG_OVERLAYPROPERTIES_CLASS_API) to transfer requirement to caller`)"
+        errorLine1="                    overlayProperties.isMixedColorSpacesSupported());"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/HardwareRenderer.java"
+            line="1430"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CONFIDENCE_LEVEL_VERY_HIGH` is a flagged API and should be inside an `if (Flags.allowHotwordBumpEgress())` check (or annotate the surrounding method `confidenceLevelToString` with `@FlaggedApi(Flags.FLAG_ALLOW_HOTWORD_BUMP_EGRESS) to transfer requirement to caller`)"
+        errorLine1="            case CONFIDENCE_LEVEL_VERY_HIGH:"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/voice/HotwordRejectedResult.java"
+            line="120"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `scheduleMediaViewCleanup()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `release` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="        mSessionImpl.scheduleMediaViewCleanup();"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="87"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `release()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `executeMessage` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                mSessionImpl.release();"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="101"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setSurface()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `executeMessage` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                mSessionImpl.setSurface((Surface) msg.obj);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="114"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `dispatchSurfaceChanged()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `executeMessage` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                mSessionImpl.dispatchSurfaceChanged("
+        errorLine2="                ^">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="119"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `createMediaView()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `executeMessage` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                mSessionImpl.createMediaView((IBinder) args.arg1, (Rect) args.arg2);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="126"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `relayoutMediaView()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `executeMessage` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                mSessionImpl.relayoutMediaView((Rect) msg.obj);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="131"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `removeMediaView()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `executeMessage` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                mSessionImpl.removeMediaView(true);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="135"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `startAdService()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `executeMessage` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                mSessionImpl.startAdService();"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="139"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `stopAdService()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `executeMessage` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                mSessionImpl.stopAdService();"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="143"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `resetAdService()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `executeMessage` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                mSessionImpl.resetAdService();"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="147"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `sendCurrentVideoBounds()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `executeMessage` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                mSessionImpl.sendCurrentVideoBounds((Rect) msg.obj);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="151"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `sendCurrentChannelUri()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `executeMessage` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                mSessionImpl.sendCurrentChannelUri((Uri) msg.obj);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="155"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `sendTrackInfoList()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `executeMessage` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                mSessionImpl.sendTrackInfoList((List&lt;TvTrackInfo>) msg.obj);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="159"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `sendCurrentTvInputId()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `executeMessage` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                mSessionImpl.sendCurrentTvInputId((String) msg.obj);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="163"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `sendSigningResult()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `executeMessage` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                mSessionImpl.sendSigningResult((String) args.arg1, (byte[]) args.arg2);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="168"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `notifyError()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `executeMessage` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                mSessionImpl.notifyError((String) args.arg1, (Bundle) args.arg2);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="174"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `notifyTvMessage()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `executeMessage` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                mSessionImpl.notifyTvMessage((Integer) args.arg1, (Bundle) args.arg2);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="180"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `notifyTvInputSessionData()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `executeMessage` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                mSessionImpl.notifyTvInputSessionData((String) args.arg1, (Bundle) args.arg2);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="186"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `dispatchInputEvent()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `onInputEvent` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="            int handled = mSessionImpl.dispatchInputEvent(event, this);"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="309"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `DISPATCH_IN_PROGRESS` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `onInputEvent` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="            if (handled != TvAdManager.Session.DISPATCH_IN_PROGRESS) {"
+        errorLine2="                                               ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="310"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `DISPATCH_HANDLED` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `onInputEvent` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                        event, handled == TvAdManager.Session.DISPATCH_HANDLED);"
+        errorLine2="                                                              ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/ad/ITvAdSessionWrapper.java"
+            line="312"
+            column="63"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onDeregistered()` is a flagged API and should be inside an `if (Flags.emergencyRegistrationState())` check (or annotate the surrounding method `onDeregistered` with `@FlaggedApi(Flags.FLAG_EMERGENCY_REGISTRATION_STATE) to transfer requirement to caller`)"
+        errorLine1="        onDeregistered(info, suggestedAction, attributes);"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java"
+            line="576"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onTechnologyChangeFailed()` is a flagged API and should be inside an `if (Flags.emergencyRegistrationState())` check (or annotate the surrounding method `onTechnologyChangeFailed` with `@FlaggedApi(Flags.FLAG_EMERGENCY_REGISTRATION_STATE) to transfer requirement to caller`)"
+        errorLine1="        onTechnologyChangeFailed(info, attributes);"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java"
+            line="703"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `ATTR_REGISTRATION_TYPE_EMERGENCY` is a flagged API and should be inside an `if (Flags.emergencyRegistrationState())` check (or annotate the surrounding method `isEmergency` with `@FlaggedApi(Flags.FLAG_EMERGENCY_REGISTRATION_STATE) to transfer requirement to caller`)"
+        errorLine1="                    &amp; ImsRegistrationAttributes.ATTR_REGISTRATION_TYPE_EMERGENCY) != 0;"
+        errorLine2="                                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java"
+            line="753"
+            column="49"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CAPABILITY_SUPPORTS_SIMULTANEOUS_CALLING` is a flagged API and should be inside an `if (Flags.simultaneousCallingIndications())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_SIMULTANEOUS_CALLING_INDICATIONS) to transfer requirement to caller`)"
+        errorLine1="            Long.numberOfTrailingZeros(CAPABILITY_SUPPORTS_SIMULTANEOUS_CALLING);"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/ims/ImsService.java"
+            line="186"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CAPABILITY_SUPPORTS_SIMULTANEOUS_CALLING` is a flagged API and should be inside an `if (Flags.simultaneousCallingIndications())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_SIMULTANEOUS_CALLING_INDICATIONS) to transfer requirement to caller`)"
+        errorLine1="            CAPABILITY_SUPPORTS_SIMULTANEOUS_CALLING, &quot;SIMULTANEOUS_CALLING&quot;);"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/ims/ImsService.java"
+            line="212"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `InputTransferToken()` is a flagged API and should be inside an `if (Flags.surfaceControlInputReceiver())` check (or annotate the surrounding method `handleRenderSuggestion` with `@FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) to transfer requirement to caller`)"
+        errorLine1="                    new InputTransferToken(hostInputToken), &quot;InlineSuggestionRenderService&quot;);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/autofill/InlineSuggestionRenderService.java"
+            line="170"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `ViewBehavior()` is a flagged API and should be inside an `if (Flags.inputDeviceViewBehaviorApi())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_INPUT_DEVICE_VIEW_BEHAVIOR_API) to transfer requirement to caller`)"
+        errorLine1="    private final ViewBehavior mViewBehavior = new ViewBehavior(this);"
+        errorLine2="                                               ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/InputDevice.java"
+            line="99"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `mShouldSmoothScroll` is a flagged API and should be inside an `if (Flags.inputDeviceViewBehaviorApi())` check (or annotate the surrounding method `InputDevice` with `@FlaggedApi(Flags.FLAG_INPUT_DEVICE_VIEW_BEHAVIOR_API) to transfer requirement to caller`)"
+        errorLine1="        mViewBehavior.mShouldSmoothScroll = in.readBoolean();"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/InputDevice.java"
+            line="575"
+            column="23"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `mShouldSmoothScroll` is a flagged API and should be inside an `if (Flags.inputDeviceViewBehaviorApi())` check (or annotate the surrounding method `setShouldSmoothScroll` with `@FlaggedApi(Flags.FLAG_INPUT_DEVICE_VIEW_BEHAVIOR_API) to transfer requirement to caller`)"
+        errorLine1="        mViewBehavior.mShouldSmoothScroll = shouldSmoothScroll;"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/InputDevice.java"
+            line="1207"
+            column="23"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `mShouldSmoothScroll` is a flagged API and should be inside an `if (Flags.inputDeviceViewBehaviorApi())` check (or annotate the surrounding method `writeToParcel` with `@FlaggedApi(Flags.FLAG_INPUT_DEVICE_VIEW_BEHAVIOR_API) to transfer requirement to caller`)"
+        errorLine1="        out.writeBoolean(mViewBehavior.mShouldSmoothScroll);"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/InputDevice.java"
+            line="1642"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getHandwritingDelegateFlags()` is a flagged API and should be inside an `if (Flags.homeScreenHandwritingDelegator())` check (or annotate the surrounding method `acceptStylusHandwritingDelegation` with `@FlaggedApi(Flags.FLAG_HOME_SCREEN_HANDWRITING_DELEGATOR) to transfer requirement to caller`)"
+        errorLine1="                delegateView.getHandwritingDelegateFlags());"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/inputmethod/InputMethodManager.java"
+            line="2880"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getHandwritingDelegateFlags()` is a flagged API and should be inside an `if (Flags.homeScreenHandwritingDelegator())` check (or annotate the surrounding method `acceptStylusHandwritingDelegation` with `@FlaggedApi(Flags.FLAG_HOME_SCREEN_HANDWRITING_DELEGATOR) to transfer requirement to caller`)"
+        errorLine1="                delegateView, delegatorPackageName, delegateView.getHandwritingDelegateFlags());"
+        errorLine2="                                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/inputmethod/InputMethodManager.java"
+            line="2911"
+            column="53"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `acceptStylusHandwritingDelegation()` is a flagged API and should be inside an `if (Flags.homeScreenHandwritingDelegator())` check (or annotate the surrounding method `acceptStylusHandwritingDelegation` with `@FlaggedApi(Flags.FLAG_HOME_SCREEN_HANDWRITING_DELEGATOR) to transfer requirement to caller`)"
+        errorLine1="        acceptStylusHandwritingDelegation("
+        errorLine2="        ^">
+        <location
+            file="frameworks/base/core/java/android/view/inputmethod/InputMethodManager.java"
+            line="2940"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onError()` is a flagged API and should be inside an `if (Flags.connectionlessHandwriting())` check (or annotate the surrounding method `onResult` with `@FlaggedApi(Flags.FLAG_CONNECTIONLESS_HANDWRITING) to transfer requirement to caller`)"
+        errorLine1="                    executor.execute(() -> callback.onError("
+        errorLine2="                                           ^">
+        <location
+            file="frameworks/base/core/java/android/view/inputmethod/InputMethodManager.java"
+            line="4808"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CONNECTIONLESS_HANDWRITING_ERROR_NO_TEXT_RECOGNIZED` is a flagged API and should be inside an `if (Flags.connectionlessHandwriting())` check (or annotate the surrounding method `onResult` with `@FlaggedApi(Flags.FLAG_CONNECTIONLESS_HANDWRITING) to transfer requirement to caller`)"
+        errorLine1="                                    .CONNECTIONLESS_HANDWRITING_ERROR_NO_TEXT_RECOGNIZED));"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/inputmethod/InputMethodManager.java"
+            line="4810"
+            column="38"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onResult()` is a flagged API and should be inside an `if (Flags.connectionlessHandwriting())` check (or annotate the surrounding method `onResult` with `@FlaggedApi(Flags.FLAG_CONNECTIONLESS_HANDWRITING) to transfer requirement to caller`)"
+        errorLine1="                    executor.execute(() -> callback.onResult(text));"
+        errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/inputmethod/InputMethodManager.java"
+            line="4812"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onError()` is a flagged API and should be inside an `if (Flags.connectionlessHandwriting())` check (or annotate the surrounding method `onError` with `@FlaggedApi(Flags.FLAG_CONNECTIONLESS_HANDWRITING) to transfer requirement to caller`)"
+        errorLine1="                executor.execute(() -> callback.onError(errorCode));"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/inputmethod/InputMethodManager.java"
+            line="4834"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onStartConnectionlessStylusHandwriting()` is a flagged API and should be inside an `if (Flags.connectionlessHandwriting())` check (or annotate the surrounding method `canStartStylusHandwriting` with `@FlaggedApi(Flags.FLAG_CONNECTIONLESS_HANDWRITING) to transfer requirement to caller`)"
+        errorLine1="                if (onStartConnectionlessStylusHandwriting("
+        errorLine2="                    ^">
+        <location
+            file="frameworks/base/core/java/android/inputmethodservice/InputMethodService.java"
+            line="1085"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CONNECTIONLESS_HANDWRITING_ERROR_UNSUPPORTED` is a flagged API and should be inside an `if (Flags.connectionlessHandwriting())` check (or annotate the surrounding method `canStartStylusHandwriting` with `@FlaggedApi(Flags.FLAG_CONNECTIONLESS_HANDWRITING) to transfer requirement to caller`)"
+        errorLine1="                                CONNECTIONLESS_HANDWRITING_ERROR_UNSUPPORTED);"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/inputmethodservice/InputMethodService.java"
+            line="1096"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CONNECTIONLESS_HANDWRITING_ERROR_OTHER` is a flagged API and should be inside an `if (Flags.connectionlessHandwriting())` check (or annotate the surrounding method `finishStylusHandwriting` with `@FlaggedApi(Flags.FLAG_CONNECTIONLESS_HANDWRITING) to transfer requirement to caller`)"
+        errorLine1="                mConnectionlessHandwritingCallback.onError(CONNECTIONLESS_HANDWRITING_ERROR_OTHER);"
+        errorLine2="                                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/inputmethodservice/InputMethodService.java"
+            line="2825"
+            column="60"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getAccessibilityBounceKeysThreshold()` is a flagged API and should be inside an `if (Flags.keyboardA11yBounceKeysFlag())` check (or annotate the surrounding method `isAccessibilityBounceKeysEnabled` with `@FlaggedApi(Flags.FLAG_KEYBOARD_A11Y_BOUNCE_KEYS_FLAG) to transfer requirement to caller`)"
+        errorLine1="        return getAccessibilityBounceKeysThreshold(context) != 0;"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/input/InputSettings.java"
+            line="458"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getAccessibilitySlowKeysThreshold()` is a flagged API and should be inside an `if (Flags.keyboardA11ySlowKeysFlag())` check (or annotate the surrounding method `isAccessibilitySlowKeysEnabled` with `@FlaggedApi(Flags.FLAG_KEYBOARD_A11Y_SLOW_KEYS_FLAG) to transfer requirement to caller`)"
+        errorLine1="        return getAccessibilitySlowKeysThreshold(context) != 0;"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/input/InputSettings.java"
+            line="542"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND` is a flagged API and should be inside an `if (Flags.customizableWindowHeaders())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CUSTOMIZABLE_WINDOW_HEADERS) to transfer requirement to caller`)"
+        errorLine1="                    mask = APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND,"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/InsetsFlags.java"
+            line="76"
+            column="28"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND` is a flagged API and should be inside an `if (Flags.customizableWindowHeaders())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CUSTOMIZABLE_WINDOW_HEADERS) to transfer requirement to caller`)"
+        errorLine1="                    equals = APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND,"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/InsetsFlags.java"
+            line="77"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `APPEARANCE_LIGHT_CAPTION_BARS` is a flagged API and should be inside an `if (Flags.customizableWindowHeaders())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CUSTOMIZABLE_WINDOW_HEADERS) to transfer requirement to caller`)"
+        errorLine1="                    mask = APPEARANCE_LIGHT_CAPTION_BARS,"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/InsetsFlags.java"
+            line="80"
+            column="28"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `APPEARANCE_LIGHT_CAPTION_BARS` is a flagged API and should be inside an `if (Flags.customizableWindowHeaders())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CUSTOMIZABLE_WINDOW_HEADERS) to transfer requirement to caller`)"
+        errorLine1="                    equals = APPEARANCE_LIGHT_CAPTION_BARS,"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/InsetsFlags.java"
+            line="81"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `countUriRelativeFilterGroups()` is a flagged API and should be inside an `if (Flags.relativeReferenceIntentFilters())` check (or annotate the surrounding method `toLongString` with `@FlaggedApi(Flags.FLAG_RELATIVE_REFERENCE_INTENT_FILTERS) to transfer requirement to caller`)"
+        errorLine1="        if (Flags.relativeReferenceIntentFilters() &amp;&amp; countUriRelativeFilterGroups() > 0) {"
+        errorLine2="                                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/IntentFilter.java"
+            line="577"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `matchGroupsToUri()` is a flagged API and should be inside an `if (Flags.relativeReferenceIntentFilters())` check (or annotate the surrounding method `matchRelRefGroups` with `@FlaggedApi(Flags.FLAG_RELATIVE_REFERENCE_INTENT_FILTERS) to transfer requirement to caller`)"
+        errorLine1="        return UriRelativeFilterGroup.matchGroupsToUri(mUriRelativeFilterGroups, data);"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/IntentFilter.java"
+            line="1839"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isPrivateProfile()` is a flagged API and should be inside an `if (Flags.allowPrivateProfile())` check (or annotate the surrounding method `getPrivateProfile` with `@FlaggedApi(Flags.FLAG_ALLOW_PRIVATE_PROFILE) to transfer requirement to caller`)"
+        errorLine1="            if (userInfo.isPrivateProfile()) return userInfo;"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/com/android/internal/app/IntentForwarderActivity.java"
+            line="631"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `uptimeNanos()` is a flagged API and should be inside an `if (Flags.adpfGpuReportActualWorkDuration())` check (or annotate the surrounding method `postEventLogToWorkerThread` with `@FlaggedApi(Flags.FLAG_ADPF_GPU_REPORT_ACTUAL_WORK_DURATION) to transfer requirement to caller`)"
+        errorLine1="        final long realtimeNanos = SystemClock.uptimeNanos();"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/com/android/internal/jank/InteractionJankMonitor.java"
+            line="606"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `KEYCODE_SCREENSHOT` is a flagged API and should be inside an `if (Flags.emojiAndScreenshotKeycodesAvailable())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_EMOJI_AND_SCREENSHOT_KEYCODES_AVAILABLE) to transfer requirement to caller`)"
+        errorLine1="    public static final int LAST_KEYCODE = KEYCODE_SCREENSHOT;"
+        errorLine2="                                           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/KeyEvent.java"
+            line="955"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isMgf1DigestsSpecified()` is a flagged API and should be inside an `if (Flags.mgf1DigestSetterV2())` check (or annotate the surrounding method `Builder` with `@FlaggedApi(Flags.FLAG_MGF1_DIGEST_SETTER_V2) to transfer requirement to caller`)"
+        errorLine1="            if (sourceSpec.isMgf1DigestsSpecified()) {"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/keystore/java/android/security/keystore/KeyGenParameterSpec.java"
+            line="1025"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getMgf1Digests()` is a flagged API and should be inside an `if (Flags.mgf1DigestSetterV2())` check (or annotate the surrounding method `Builder` with `@FlaggedApi(Flags.FLAG_MGF1_DIGEST_SETTER_V2) to transfer requirement to caller`)"
+        errorLine1="                mMgf1Digests = sourceSpec.getMgf1Digests();"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/keystore/java/android/security/keystore/KeyGenParameterSpec.java"
+            line="1026"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `BIOMETRIC_NO_AUTHENTICATION` is a flagged API and should be inside an `if (Flags.lastAuthenticationTime())` check (or annotate the surrounding method `getLastAuthTime` with `@FlaggedApi(Flags.FLAG_LAST_AUTHENTICATION_TIME) to transfer requirement to caller`)"
+        errorLine1="            return BiometricConstants.BIOMETRIC_NO_AUTHENTICATION;"
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/keystore/java/android/security/KeyStoreAuthorization.java"
+            line="139"
+            column="39"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `BIOMETRIC_NO_AUTHENTICATION` is a flagged API and should be inside an `if (Flags.lastAuthenticationTime())` check (or annotate the surrounding method `getLastAuthTime` with `@FlaggedApi(Flags.FLAG_LAST_AUTHENTICATION_TIME) to transfer requirement to caller`)"
+        errorLine1="            return BiometricConstants.BIOMETRIC_NO_AUTHENTICATION;"
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/keystore/java/android/security/KeyStoreAuthorization.java"
+            line="145"
+            column="39"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `PERSISTENT_DATA_BLOCK_SERVICE` is a flagged API and should be inside an `if (Flags.frpEnforcement())` check (or annotate the surrounding method `createConfirmFactoryResetCredentialIntent` with `@FlaggedApi(Flags.FLAG_FRP_ENFORCEMENT) to transfer requirement to caller`)"
+        errorLine1="                    ServiceManager.getService(Context.PERSISTENT_DATA_BLOCK_SERVICE));"
+        errorLine2="                                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/KeyguardManager.java"
+            line="365"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isPrivateProfile()` is a flagged API and should be inside an `if (Flags.allowPrivateProfile())` check (or annotate the surrounding method `getProfiles` with `@FlaggedApi(Flags.FLAG_ALLOW_PRIVATE_PROFILE) to transfer requirement to caller`)"
+        errorLine1="                    &amp;&amp; mUserManager.isPrivateProfile())) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/pm/LauncherApps.java"
+            line="712"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `computeDrawingBoundingBox()` is a flagged API and should be inside an `if (Flags.useBoundsForWidth())` check (or annotate the surrounding method `draw` with `@FlaggedApi(Flags.FLAG_USE_BOUNDS_FOR_WIDTH) to transfer requirement to caller`)"
+        errorLine1="            RectF drawingRect = computeDrawingBoundingBox();"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/Layout.java"
+            line="498"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getLineSpacingMultiplier()` is a flagged API and should be inside an `if (Flags.useBoundsForWidth())` check (or annotate the surrounding method `getSpacingMultiplier` with `@FlaggedApi(Flags.FLAG_USE_BOUNDS_FOR_WIDTH) to transfer requirement to caller`)"
+        errorLine1="        return getLineSpacingMultiplier();"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/Layout.java"
+            line="4341"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getLineSpacingAmount()` is a flagged API and should be inside an `if (Flags.useBoundsForWidth())` check (or annotate the surrounding method `getSpacingAdd` with `@FlaggedApi(Flags.FLAG_USE_BOUNDS_FOR_WIDTH) to transfer requirement to caller`)"
+        errorLine1="        return getLineSpacingAmount();"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/Layout.java"
+            line="4368"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `LINE_BREAK_STYLE_UNSPECIFIED` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="        private @LineBreakStyle int mLineBreakStyle = LineBreakConfig.LINE_BREAK_STYLE_UNSPECIFIED;"
+        errorLine2="                                                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/text/LineBreakConfig.java"
+            line="276"
+            column="71"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `LINE_BREAK_WORD_STYLE_UNSPECIFIED` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                LineBreakConfig.LINE_BREAK_WORD_STYLE_UNSPECIFIED;"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/text/LineBreakConfig.java"
+            line="280"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `HYPHENATION_UNSPECIFIED` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="        private @Hyphenation int mHyphenation = LineBreakConfig.HYPHENATION_UNSPECIFIED;"
+        errorLine2="                                                                ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/text/LineBreakConfig.java"
+            line="282"
+            column="65"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `LINE_BREAK_STYLE_UNSPECIFIED` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `reset` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                mLineBreakStyle = LINE_BREAK_STYLE_UNSPECIFIED;"
+        errorLine2="                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/text/LineBreakConfig.java"
+            line="343"
+            column="35"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `LINE_BREAK_WORD_STYLE_UNSPECIFIED` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `reset` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                mLineBreakWordStyle = LINE_BREAK_WORD_STYLE_UNSPECIFIED;"
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/text/LineBreakConfig.java"
+            line="344"
+            column="39"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `HYPHENATION_UNSPECIFIED` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `reset` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                mHyphenation = HYPHENATION_UNSPECIFIED;"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/text/LineBreakConfig.java"
+            line="345"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `LINE_BREAK_STYLE_AUTO` is a flagged API and should be inside an `if (Flags.wordStyleAuto())` check (or annotate the surrounding method `getResolvedLineBreakStyle` with `@FlaggedApi(Flags.FLAG_WORD_STYLE_AUTO) to transfer requirement to caller`)"
+        errorLine1="            defaultStyle = LINE_BREAK_STYLE_AUTO;"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/text/LineBreakConfig.java"
+            line="492"
+            column="28"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `LINE_BREAK_STYLE_UNSPECIFIED` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `getResolvedLineBreakStyle` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="        return config.mLineBreakStyle == LINE_BREAK_STYLE_UNSPECIFIED"
+        errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/text/LineBreakConfig.java"
+            line="499"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `LINE_BREAK_WORD_STYLE_AUTO` is a flagged API and should be inside an `if (Flags.wordStyleAuto())` check (or annotate the surrounding method `getResolvedLineBreakWordStyle` with `@FlaggedApi(Flags.FLAG_WORD_STYLE_AUTO) to transfer requirement to caller`)"
+        errorLine1="            defaultWordStyle = LINE_BREAK_WORD_STYLE_AUTO;"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/text/LineBreakConfig.java"
+            line="527"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `LINE_BREAK_WORD_STYLE_UNSPECIFIED` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `getResolvedLineBreakWordStyle` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="        return config.mLineBreakWordStyle == LINE_BREAK_WORD_STYLE_UNSPECIFIED"
+        errorLine2="                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/text/LineBreakConfig.java"
+            line="534"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `HYPHENATION_ENABLED` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `getResolvedHyphenation` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="            return HYPHENATION_ENABLED;"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/text/LineBreakConfig.java"
+            line="559"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `HYPHENATION_UNSPECIFIED` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `getResolvedHyphenation` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="        return config.mHyphenation == HYPHENATION_UNSPECIFIED"
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/text/LineBreakConfig.java"
+            line="561"
+            column="39"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `HYPHENATION_ENABLED` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `getResolvedHyphenation` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                ? HYPHENATION_ENABLED : config.mHyphenation;"
+        errorLine2="                  ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/text/LineBreakConfig.java"
+            line="562"
+            column="19"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getSessionId()` is a flagged API and should be inside an `if (Flags.loudnessConfiguratorApi())` check (or annotate the surrounding method `dispatchLoudnessCodecParameterChange` with `@FlaggedApi(Flags.FLAG_LOUDNESS_CONFIGURATOR_API) to transfer requirement to caller`)"
+        errorLine1="                        if (lcConfig.getSessionId() == sessionId) {"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/LoudnessCodecDispatcher.java"
+            line="85"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `mediaCodecsConsume()` is a flagged API and should be inside an `if (Flags.loudnessConfiguratorApi())` check (or annotate the surrounding method `dispatchLoudnessCodecParameterChange` with `@FlaggedApi(Flags.FLAG_LOUDNESS_CONFIGURATOR_API) to transfer requirement to caller`)"
+        errorLine1="                            lcConfig.mediaCodecsConsume(mcEntry -> {"
+        errorLine2="                            ^">
+        <location
+            file="frameworks/base/media/java/android/media/LoudnessCodecDispatcher.java"
+            line="86"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onLoudnessCodecUpdate()` is a flagged API and should be inside an `if (Flags.loudnessConfiguratorApi())` check (or annotate the surrounding method `dispatchLoudnessCodecParameterChange` with `@FlaggedApi(Flags.FLAG_LOUDNESS_CONFIGURATOR_API) to transfer requirement to caller`)"
+        errorLine1="                                                    l.onLoudnessCodecUpdate(mediaCodec,"
+        errorLine2="                                                    ^">
+        <location
+            file="frameworks/base/media/java/android/media/LoudnessCodecDispatcher.java"
+            line="110"
+            column="53"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.provider.user_keys&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="29"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.provider.user_keys&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="29"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.provider.user_keys&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="29"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.provider.user_keys&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="29"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.internal.camera.flags.camera_hsum_permission&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="552"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.internal.camera.flags.camera_privacy_allowlist&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="561"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.net.thread.platform.flags.thread_enabled_platform&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="992"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.net.platform.flags.register_nsd_offload_engine&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1055"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.quarantined_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1101"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.quarantined_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1101"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.window.flags.screen_recording_callbacks&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1310"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.window.flags.screen_recording_callbacks&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1310"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.window.flags.screen_recording_callbacks&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1310"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.window.flags.screen_recording_callbacks&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1310"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.window.flags.screen_recording_callbacks&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1310"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.security.frp_enforcement&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1434"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.security.frp_enforcement&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1434"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.internal.telephony.flags.use_oem_domain_selection_service&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1639"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1726"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1726"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1726"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1726"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1839"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1839"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1839"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1839"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1839"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1839"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1839"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1839"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1839"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1839"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1839"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1839"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1839"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1839"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1839"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1839"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1839"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1839"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1848"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1848"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1848"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1848"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1848"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1848"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1848"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1848"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1848"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1848"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1848"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1848"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1848"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1848"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1848"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1848"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1848"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_permission_to_access_hidden_profiles&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="1848"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.net.thread.platform.flags.thread_user_restriction_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2292"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.admin.flags.assist_content_user_restriction_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2300"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.admin.flags.security_log_v2_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2363"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.admin.flags.security_log_v2_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2363"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.admin.flags.security_log_v2_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2363"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.admin.flags.security_log_v2_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2363"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.admin.flags.security_log_v2_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2363"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.admin.flags.device_theft_api_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2489"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.admin.flags.device_theft_api_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2489"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.view.contentprotection.flags.manage_device_policy_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2523"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.view.contentprotection.flags.manage_device_policy_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2523"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.view.contentprotection.flags.manage_device_policy_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2523"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.admin.flags.esim_management_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2532"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.admin.flags.esim_management_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2532"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.admin.flags.esim_management_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2532"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.admin.flags.esim_management_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2532"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.admin.flags.dedicated_device_control_api_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2539"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.admin.flags.dedicated_device_control_api_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2546"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.admin.flags.dedicated_device_control_api_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2553"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.permission.flags.enhanced_confirmation_mode_apis_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2596"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.permission.flags.enhanced_confirmation_mode_apis_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2596"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.permission.flags.enhanced_confirmation_mode_apis_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2596"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.window.flags.untrusted_embedding_any_app_permission&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2661"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.window.flags.always_update_wallpaper_permission&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2904"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.window.flags.always_update_wallpaper_permission&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="2904"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.feature.flags.enable_read_dropbox_permission&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="3364"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.feature.flags.enable_read_dropbox_permission&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="3364"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.feature.flags.enable_read_dropbox_permission&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="3364"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.accessibility.motion_event_observing&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="3584"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.media.tv.flags.enable_ad_service_fw&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="3971"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.get_resolved_apk_path&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4252"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.get_resolved_apk_path&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4252"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.companion.device_presence&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4465"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.companion.device_presence&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4465"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.companion.flags.companion_transport_apis&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4475"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.companion.flags.companion_transport_apis&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4475"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.companion.flags.companion_transport_apis&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4475"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.companion.flags.companion_transport_apis&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4475"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.companion.flags.companion_transport_apis&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4475"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.companion.flags.companion_transport_apis&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4475"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.media.flags.enable_privileged_routing_for_media_routing_control&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4780"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.media.flags.enable_privileged_routing_for_media_routing_control&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4780"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.media.flags.enable_privileged_routing_for_media_routing_control&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4780"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.media.flags.enable_privileged_routing_for_media_routing_control&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4780"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.media.flags.enable_privileged_routing_for_media_routing_control&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4780"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.media.flags.enable_privileged_routing_for_media_routing_control&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4780"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.media.flags.enable_privileged_routing_for_media_routing_control&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4780"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.usage.report_usage_stats_permission&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4938"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.usage.report_usage_stats_permission&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4938"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.usage.report_usage_stats_permission&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4938"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.usage.report_usage_stats_permission&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="4938"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.hardware.biometrics.custom_biometric_prompt&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5392"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.hardware.biometrics.custom_biometric_prompt&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5392"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.hardware.biometrics.custom_biometric_prompt&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5392"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.hardware.biometrics.custom_biometric_prompt&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5392"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.hardware.biometrics.custom_biometric_prompt&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5392"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.hardware.biometrics.custom_biometric_prompt&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5392"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.hardware.biometrics.custom_biometric_prompt&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5392"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.hardware.biometrics.custom_biometric_prompt&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5392"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.hardware.biometrics.custom_biometric_prompt&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5392"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.hardware.biometrics.custom_biometric_prompt&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5392"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.hardware.biometrics.custom_biometric_prompt&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5392"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.hardware.biometrics.custom_biometric_prompt&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5392"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.permission.flags.sensitive_notification_app_protection&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5535"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5706"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5706"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5706"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5706"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5706"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5706"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5706"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5706"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5706"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5714"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5714"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5714"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5714"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5714"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5714"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5714"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5714"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.telecom.flags.telecom_resolve_hidden_dependencies&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5714"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.contextualsearch.flags.enable_service&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5829"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.contextualsearch.flags.enable_service&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5829"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.introduce_media_processing_type&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5935"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.introduce_media_processing_type&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5935"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.introduce_media_processing_type&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="5935"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.permission.flags.voice_activation_permission_apis&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6084"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.permission.flags.voice_activation_permission_apis&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6084"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.nfc.enable_nfc_mainline&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6304"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.ondeviceintelligence.flags.enable_on_device_intelligence&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6544"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.ondeviceintelligence.flags.enable_on_device_intelligence&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6544"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.ondeviceintelligence.flags.enable_on_device_intelligence&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6544"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.ondeviceintelligence.flags.enable_on_device_intelligence&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6544"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.ondeviceintelligence.flags.enable_on_device_intelligence&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6544"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.ondeviceintelligence.flags.enable_on_device_intelligence&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6544"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.ondeviceintelligence.flags.enable_on_device_intelligence&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6544"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.ondeviceintelligence.flags.enable_on_device_intelligence&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6544"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.ondeviceintelligence.flags.enable_on_device_intelligence&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6544"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.ondeviceintelligence.flags.enable_on_device_intelligence&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6544"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.ondeviceintelligence.flags.enable_on_device_intelligence&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6552"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.ondeviceintelligence.flags.enable_on_device_intelligence&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6560"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.get_binding_uid_importance&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6660"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.get_binding_uid_importance&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6660"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.permission.flags.factory_reset_prep_permission_apis&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6676"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.input.flags.override_key_behavior_permission_apis&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6693"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.view.flags.sensitive_content_app_protection_api&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6704"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.bic_client&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6715"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.bic_client&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6715"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.system_terms_of_address_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6723"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.system_terms_of_address_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6723"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.app.system_terms_of_address_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6723"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.emergency_install_permission&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6732"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.server.power.feature.flags.enable_early_screen_timeout_detector&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6747"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.security.fsverity_api&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/Manifest.java"
+            line="6755"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `LineBreakConfigSpan` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `buildForMeasurement` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                        LineBreakConfigSpan.class);"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/MeasuredParagraph.java"
+            line="471"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `LineBreakConfigSpan` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `buildForMeasurement` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                        LineBreakConfigSpan.class);"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/MeasuredParagraph.java"
+            line="476"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `LineBreakConfigSpan` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `buildForMeasurement` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                        LineBreakConfigSpan.class);"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/MeasuredParagraph.java"
+            line="479"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `LineBreakConfigSpan` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `buildForStaticLayoutInternal` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                            LineBreakConfigSpan.class);"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/MeasuredParagraph.java"
+            line="625"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `LineBreakConfigSpan` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `buildForStaticLayoutInternal` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                            LineBreakConfigSpan.class);"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/MeasuredParagraph.java"
+            line="630"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `LineBreakConfigSpan` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `buildForStaticLayoutInternal` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                                                       LineBreakConfigSpan.class);"
+        errorLine2="                                                       ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/MeasuredParagraph.java"
+            line="634"
+            column="56"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onAppendReplacementRun()` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `applyReplacementRun` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="            testCallback.onAppendReplacementRun(paint, end - start, width);"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/MeasuredParagraph.java"
+            line="784"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_LEFT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `applyStyleRun` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="                        | (Paint.TEXT_RUN_FLAG_LEFT_EDGE | Paint.TEXT_RUN_FLAG_RIGHT_EDGE));"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/MeasuredParagraph.java"
+            line="802"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_RIGHT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `applyStyleRun` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="                        | (Paint.TEXT_RUN_FLAG_LEFT_EDGE | Paint.TEXT_RUN_FLAG_RIGHT_EDGE));"
+        errorLine2="                                                                 ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/MeasuredParagraph.java"
+            line="802"
+            column="66"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onAppendStyleRun()` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `applyStyleRun` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                testCallback.onAppendStyleRun(paint, config, end - start, false);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/MeasuredParagraph.java"
+            line="814"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_LEFT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `applyStyleRun` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="                                | (Paint.TEXT_RUN_FLAG_LEFT_EDGE | Paint.TEXT_RUN_FLAG_RIGHT_EDGE));"
+        errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/MeasuredParagraph.java"
+            line="828"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_RIGHT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `applyStyleRun` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="                                | (Paint.TEXT_RUN_FLAG_LEFT_EDGE | Paint.TEXT_RUN_FLAG_RIGHT_EDGE));"
+        errorLine2="                                                                         ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/MeasuredParagraph.java"
+            line="828"
+            column="74"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onAppendStyleRun()` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `applyStyleRun` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                        testCallback.onAppendStyleRun(paint, config, levelEnd - levelStart, isRtl);"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/MeasuredParagraph.java"
+            line="840"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getLineBreakConfig()` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `applyMetricsAffectingSpan` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                mLineBreakConfigBuilder.merge(lbcSpan.getLineBreakConfig());"
+        errorLine2="                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/MeasuredParagraph.java"
+            line="888"
+            column="47"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `merge()` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `applyMetricsAffectingSpan` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                mLineBreakConfigBuilder.merge(lbcSpan.getLineBreakConfig());"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/MeasuredParagraph.java"
+            line="888"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `HYPHENATION_ENABLED` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `appendStyleRun` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                    == LineBreakConfig.HYPHENATION_ENABLED;"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/text/MeasuredText.java"
+            line="319"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onOutputBuffersAvailable()` is a flagged API and should be inside an `if (Flags.largeAudioFrame())` check (or annotate the surrounding method `handleCallback` with `@FlaggedApi(Flags.FLAG_LARGE_AUDIO_FRAME) to transfer requirement to caller`)"
+        errorLine1="                    mCallback.onOutputBuffersAvailable("
+        errorLine2="                    ^">
+        <location
+            file="frameworks/base/media/java/android/media/MediaCodec.java"
+            line="1985"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CONFIGURE_FLAG_DETACHED_SURFACE` is a flagged API and should be inside an `if (Flags.nullOutputSurface())` check (or annotate the surrounding method `configure` with `@FlaggedApi(Flags.FLAG_NULL_OUTPUT_SURFACE) to transfer requirement to caller`)"
+        errorLine1="            if (surface == null &amp;&amp; (flags &amp; CONFIGURE_FLAG_DETACHED_SURFACE) != 0 &amp;&amp; !canDetach) {"
+        errorLine2="                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/MediaCodec.java"
+            line="2371"
+            column="45"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CONFIGURE_FLAG_DETACHED_SURFACE` is a flagged API and should be inside an `if (Flags.nullOutputSurface())` check (or annotate the surrounding method `configure` with `@FlaggedApi(Flags.FLAG_NULL_OUTPUT_SURFACE) to transfer requirement to caller`)"
+        errorLine1="            if (surface == null &amp;&amp; (flags &amp; CONFIGURE_FLAG_DETACHED_SURFACE) != 0) {"
+        errorLine2="                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/MediaCodec.java"
+            line="2422"
+            column="45"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FEATURE_DynamicColorAspects` is a flagged API and should be inside an `if (Flags.dynamicColorAspects())` check (or annotate the surrounding method `getDecoderFeatures` with `@FlaggedApi(Flags.FLAG_DYNAMIC_COLOR_ASPECTS) to transfer requirement to caller`)"
+        errorLine1="                    features.add(new Feature(FEATURE_DynamicColorAspects, (1 &lt;&lt; 8), true));"
+        errorLine2="                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/MediaCodecInfo.java"
+            line="832"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FEATURE_DetachedSurface` is a flagged API and should be inside an `if (Flags.nullOutputSurface())` check (or annotate the surrounding method `getDecoderFeatures` with `@FlaggedApi(Flags.FLAG_NULL_OUTPUT_SURFACE) to transfer requirement to caller`)"
+        errorLine1="                    features.add(new Feature(FEATURE_DetachedSurface,     (1 &lt;&lt; 9), true));"
+        errorLine2="                                             ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/MediaCodecInfo.java"
+            line="835"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FEATURE_HlgEditing` is a flagged API and should be inside an `if (Flags.hlgEditing())` check (or annotate the surrounding method `getEncoderFeatures` with `@FlaggedApi(Flags.FLAG_HLG_EDITING) to transfer requirement to caller`)"
+        errorLine1="                    features.add(new Feature(FEATURE_HlgEditing, (1 &lt;&lt; 6), true));"
+        errorLine2="                                             ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/MediaCodecInfo.java"
+            line="856"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FEATURE_Roi` is a flagged API and should be inside an `if (Flags.regionOfInterest())` check (or annotate the surrounding method `getEncoderFeatures` with `@FlaggedApi(Flags.FLAG_REGION_OF_INTEREST) to transfer requirement to caller`)"
+        errorLine1="                    features.add(new Feature(FEATURE_Roi, (1 &lt;&lt; 7), true));"
+        errorLine2="                                             ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/MediaCodecInfo.java"
+            line="859"
+            column="46"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TYPE_HDMI_ARC` is a flagged API and should be inside an `if (Flags.enableAudioPoliciesDeviceAndBluetoothController())` check (or annotate the surrounding method `getDeviceTypeString` with `@FlaggedApi(Flags.FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER) to transfer requirement to caller`)"
+        errorLine1="            case TYPE_HDMI_ARC:"
+        errorLine2="                 ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/MediaRoute2Info.java"
+            line="1030"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TYPE_HDMI_EARC` is a flagged API and should be inside an `if (Flags.enableAudioPoliciesDeviceAndBluetoothController())` check (or annotate the surrounding method `getDeviceTypeString` with `@FlaggedApi(Flags.FLAG_ENABLE_AUDIO_POLICIES_DEVICE_AND_BLUETOOTH_CONTROLLER) to transfer requirement to caller`)"
+        errorLine1="            case TYPE_HDMI_EARC:"
+        errorLine2="                 ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/MediaRoute2Info.java"
+            line="1032"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TYPE_REMOTE_TABLET` is a flagged API and should be inside an `if (Flags.enableNewMediaRoute2InfoTypes())` check (or annotate the surrounding method `getDeviceTypeString` with `@FlaggedApi(Flags.FLAG_ENABLE_NEW_MEDIA_ROUTE_2_INFO_TYPES) to transfer requirement to caller`)"
+        errorLine1="            case TYPE_REMOTE_TABLET:"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/MediaRoute2Info.java"
+            line="1050"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TYPE_REMOTE_TABLET_DOCKED` is a flagged API and should be inside an `if (Flags.enableNewMediaRoute2InfoTypes())` check (or annotate the surrounding method `getDeviceTypeString` with `@FlaggedApi(Flags.FLAG_ENABLE_NEW_MEDIA_ROUTE_2_INFO_TYPES) to transfer requirement to caller`)"
+        errorLine1="            case TYPE_REMOTE_TABLET_DOCKED:"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/MediaRoute2Info.java"
+            line="1052"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TYPE_REMOTE_COMPUTER` is a flagged API and should be inside an `if (Flags.enableNewMediaRoute2InfoTypes())` check (or annotate the surrounding method `getDeviceTypeString` with `@FlaggedApi(Flags.FLAG_ENABLE_NEW_MEDIA_ROUTE_2_INFO_TYPES) to transfer requirement to caller`)"
+        errorLine1="            case TYPE_REMOTE_COMPUTER:"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/MediaRoute2Info.java"
+            line="1054"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TYPE_REMOTE_GAME_CONSOLE` is a flagged API and should be inside an `if (Flags.enableNewMediaRoute2InfoTypes())` check (or annotate the surrounding method `getDeviceTypeString` with `@FlaggedApi(Flags.FLAG_ENABLE_NEW_MEDIA_ROUTE_2_INFO_TYPES) to transfer requirement to caller`)"
+        errorLine1="            case TYPE_REMOTE_GAME_CONSOLE:"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/MediaRoute2Info.java"
+            line="1056"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TYPE_REMOTE_CAR` is a flagged API and should be inside an `if (Flags.enableNewMediaRoute2InfoTypes())` check (or annotate the surrounding method `getDeviceTypeString` with `@FlaggedApi(Flags.FLAG_ENABLE_NEW_MEDIA_ROUTE_2_INFO_TYPES) to transfer requirement to caller`)"
+        errorLine1="            case TYPE_REMOTE_CAR:"
+        errorLine2="                 ~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/MediaRoute2Info.java"
+            line="1058"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TYPE_REMOTE_SMARTWATCH` is a flagged API and should be inside an `if (Flags.enableNewMediaRoute2InfoTypes())` check (or annotate the surrounding method `getDeviceTypeString` with `@FlaggedApi(Flags.FLAG_ENABLE_NEW_MEDIA_ROUTE_2_INFO_TYPES) to transfer requirement to caller`)"
+        errorLine1="            case TYPE_REMOTE_SMARTWATCH:"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/MediaRoute2Info.java"
+            line="1060"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TYPE_REMOTE_SMARTPHONE` is a flagged API and should be inside an `if (Flags.enableNewMediaRoute2InfoTypes())` check (or annotate the surrounding method `getDeviceTypeString` with `@FlaggedApi(Flags.FLAG_ENABLE_NEW_MEDIA_ROUTE_2_INFO_TYPES) to transfer requirement to caller`)"
+        errorLine1="            case TYPE_REMOTE_SMARTPHONE:"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/MediaRoute2Info.java"
+            line="1062"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SUITABILITY_STATUS_SUITABLE_FOR_DEFAULT_TRANSFER` is a flagged API and should be inside an `if (Flags.enableBuiltInSpeakerRouteSuitabilityStatuses())` check (or annotate the surrounding method `Builder` with `@FlaggedApi(Flags.FLAG_ENABLE_BUILT_IN_SPEAKER_ROUTE_SUITABILITY_STATUSES) to transfer requirement to caller`)"
+        errorLine1="            mSuitabilityStatus = SUITABILITY_STATUS_SUITABLE_FOR_DEFAULT_TRANSFER;"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/MediaRoute2Info.java"
+            line="1122"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `OPSTR_MEDIA_ROUTING_CONTROL` is a flagged API and should be inside an `if (Flags.enablePrivilegedRoutingForMediaRoutingControl())` check (or annotate the surrounding method `checkCallerHasOnlyRevocablePermissions` with `@FlaggedApi(Flags.FLAG_ENABLE_PRIVILEGED_ROUTING_FOR_MEDIA_ROUTING_CONTROL) to transfer requirement to caller`)"
+        errorLine1="                                AppOpsManager.OPSTR_MEDIA_ROUTING_CONTROL,"
+        errorLine2="                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/MediaRouter2.java"
+            line="457"
+            column="47"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CAPABILITY_TYPE_CALL_COMPOSER_BUSINESS_ONLY` is a flagged API and should be inside an `if (Flags.businessCallComposer())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_BUSINESS_CALL_COMPOSER) to transfer requirement to caller`)"
+        errorLine1="                CAPABILITY_TYPE_CALL_COMPOSER_BUSINESS_ONLY + 1;"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/ims/feature/MmTelFeature.java"
+            line="574"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CAPABILITY_TYPE_CALL_COMPOSER_BUSINESS_ONLY` is a flagged API and should be inside an `if (Flags.businessCallComposer())` check (or annotate the surrounding method `toString` with `@FlaggedApi(Flags.FLAG_BUSINESS_CALL_COMPOSER) to transfer requirement to caller`)"
+        errorLine1="            builder.append(isCapable(CAPABILITY_TYPE_CALL_COMPOSER_BUSINESS_ONLY));"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/ims/feature/MmTelFeature.java"
+            line="622"
+            column="38"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isReliable()` is a flagged API and should be inside an `if (Flags.reliableMessage())` check (or annotate the surrounding method `equals` with `@FlaggedApi(Flags.FLAG_RELIABLE_MESSAGE) to transfer requirement to caller`)"
+        errorLine1="                            || (other.isReliable() == mIsReliable))"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/location/NanoAppMessage.java"
+            line="269"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getMessageSequenceNumber()` is a flagged API and should be inside an `if (Flags.reliableMessage())` check (or annotate the surrounding method `equals` with `@FlaggedApi(Flags.FLAG_RELIABLE_MESSAGE) to transfer requirement to caller`)"
+        errorLine1="                            || (other.getMessageSequenceNumber() == mMessageSequenceNumber));"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/location/NanoAppMessage.java"
+            line="271"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SERVICE_TYPE_MMS` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="    public static final int LAST_SERVICE_TYPE = SERVICE_TYPE_MMS;"
+        errorLine2="                                                ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/NetworkRegistrationInfo.java"
+            line="219"
+            column="49"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SERVICE_TYPE_MMS` is a flagged API and should be inside an `if (Flags.carrierEnabledSatelliteFlag())` check (or annotate the surrounding method `serviceTypeToString` with `@FlaggedApi(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="            case SERVICE_TYPE_MMS: return &quot;MMS&quot;;"
+        errorLine2="                 ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/NetworkRegistrationInfo.java"
+            line="759"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getVibrationEffect()` is a flagged API and should be inside an `if (Flags.notificationChannelVibrationEffectApi())` check (or annotate the surrounding method `writeXml` with `@FlaggedApi(Flags.FLAG_NOTIFICATION_CHANNEL_VIBRATION_EFFECT_API) to transfer requirement to caller`)"
+        errorLine1="        if (getVibrationEffect() != null) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/NotificationChannel.java"
+            line="1333"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getVibrationEffect()` is a flagged API and should be inside an `if (Flags.notificationChannelVibrationEffectApi())` check (or annotate the surrounding method `writeXml` with `@FlaggedApi(Flags.FLAG_NOTIFICATION_CHANNEL_VIBRATION_EFFECT_API) to transfer requirement to caller`)"
+        errorLine1="            out.attribute(null, ATT_VIBRATION_EFFECT, vibrationToString(getVibrationEffect()));"
+        errorLine2="                                                                        ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/NotificationChannel.java"
+            line="1334"
+            column="73"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getVibrationEffect()` is a flagged API and should be inside an `if (Flags.notificationChannelVibrationEffectApi())` check (or annotate the surrounding method `toJson` with `@FlaggedApi(Flags.FLAG_NOTIFICATION_CHANNEL_VIBRATION_EFFECT_API) to transfer requirement to caller`)"
+        errorLine1="        if (getVibrationEffect() != null) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/NotificationChannel.java"
+            line="1416"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getVibrationEffect()` is a flagged API and should be inside an `if (Flags.notificationChannelVibrationEffectApi())` check (or annotate the surrounding method `toJson` with `@FlaggedApi(Flags.FLAG_NOTIFICATION_CHANNEL_VIBRATION_EFFECT_API) to transfer requirement to caller`)"
+        errorLine1="            record.put(ATT_VIBRATION_EFFECT, vibrationToString(getVibrationEffect()));"
+        errorLine2="                                                               ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/NotificationChannel.java"
+            line="1417"
+            column="64"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getVibrationEffect()` is a flagged API and should be inside an `if (Flags.notificationChannelVibrationEffectApi())` check (or annotate the surrounding method `equals` with `@FlaggedApi(Flags.FLAG_NOTIFICATION_CHANNEL_VIBRATION_EFFECT_API) to transfer requirement to caller`)"
+        errorLine1="                &amp;&amp; Objects.equals(getVibrationEffect(), that.getVibrationEffect())"
+        errorLine2="                                  ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/NotificationChannel.java"
+            line="1545"
+            column="35"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getVibrationEffect()` is a flagged API and should be inside an `if (Flags.notificationChannelVibrationEffectApi())` check (or annotate the surrounding method `equals` with `@FlaggedApi(Flags.FLAG_NOTIFICATION_CHANNEL_VIBRATION_EFFECT_API) to transfer requirement to caller`)"
+        errorLine1="                &amp;&amp; Objects.equals(getVibrationEffect(), that.getVibrationEffect())"
+        errorLine2="                                                        ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/NotificationChannel.java"
+            line="1545"
+            column="57"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getVibrationEffect()` is a flagged API and should be inside an `if (Flags.notificationChannelVibrationEffectApi())` check (or annotate the surrounding method `hashCode` with `@FlaggedApi(Flags.FLAG_NOTIFICATION_CHANNEL_VIBRATION_EFFECT_API) to transfer requirement to caller`)"
+        errorLine1="                mImportanceLockedDefaultApp, mOriginalImportance, getVibrationEffect(),"
+        errorLine2="                                                                  ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/NotificationChannel.java"
+            line="1563"
+            column="67"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `addAutomaticZenRule()` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `addAutomaticZenRule` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        return addAutomaticZenRule(automaticZenRule, /* fromUser= */ false);"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/NotificationManager.java"
+            line="1368"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `updateAutomaticZenRule()` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `updateAutomaticZenRule` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        return updateAutomaticZenRule(id, automaticZenRule, /* fromUser= */ false);"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/NotificationManager.java"
+            line="1404"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `removeAutomaticZenRule()` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `removeAutomaticZenRule` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        return removeAutomaticZenRule(id, /* fromUser= */ false);"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/NotificationManager.java"
+            line="1473"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `ROLLBACK_USER_IMPACT_LOW` is a flagged API and should be inside an `if (Flags.recoverabilityDetection())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_RECOVERABILITY_DETECTION) to transfer requirement to caller`)"
+        errorLine1="        public int rollbackImpactLevel = PackageManager.ROLLBACK_USER_IMPACT_LOW;"
+        errorLine2="                                                        ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/pm/PackageInstaller.java"
+            line="2789"
+            column="57"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `isArchived` is a flagged API and should be inside an `if (Flags.archiving())` check (or annotate the surrounding method `PackageItemInfo` with `@FlaggedApi(Flags.FLAG_ARCHIVING) to transfer requirement to caller`)"
+        errorLine1="        isArchived = orig.isArchived;"
+        errorLine2="        ~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/pm/PackageItemInfo.java"
+            line="204"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `isArchived` is a flagged API and should be inside an `if (Flags.archiving())` check (or annotate the surrounding method `PackageItemInfo` with `@FlaggedApi(Flags.FLAG_ARCHIVING) to transfer requirement to caller`)"
+        errorLine1="        isArchived = orig.isArchived;"
+        errorLine2="                          ~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/pm/PackageItemInfo.java"
+            line="204"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `isArchived` is a flagged API and should be inside an `if (Flags.archiving())` check (or annotate the surrounding method `writeToParcel` with `@FlaggedApi(Flags.FLAG_ARCHIVING) to transfer requirement to caller`)"
+        errorLine1="        dest.writeBoolean(isArchived);"
+        errorLine2="                          ~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/pm/PackageItemInfo.java"
+            line="470"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `isArchived` is a flagged API and should be inside an `if (Flags.archiving())` check (or annotate the surrounding method `dumpDebug` with `@FlaggedApi(Flags.FLAG_ARCHIVING) to transfer requirement to caller`)"
+        errorLine1="        proto.write(PackageItemInfoProto.IS_ARCHIVED, isArchived);"
+        errorLine2="                                                      ~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/pm/PackageItemInfo.java"
+            line="488"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `isArchived` is a flagged API and should be inside an `if (Flags.archiving())` check (or annotate the surrounding method `PackageItemInfo` with `@FlaggedApi(Flags.FLAG_ARCHIVING) to transfer requirement to caller`)"
+        errorLine1="        isArchived = source.readBoolean();"
+        errorLine2="        ~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/pm/PackageItemInfo.java"
+            line="503"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `PERSISTENT_DEVICE_ID_DEFAULT` is a flagged API and should be inside an `if (Flags.persistentDeviceIdApi())` check (or annotate the surrounding method `onPermissionsChanged` with `@FlaggedApi(Flags.FLAG_PERSISTENT_DEVICE_ID_API) to transfer requirement to caller`)"
+        errorLine1="                    VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT)) {"
+        errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/pm/PackageManager.java"
+            line="766"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `EXTRA_ARCHIVAL` is a flagged API and should be inside an `if (Flags.archiving())` check (or annotate the surrounding method `doHandlePackageEvent` with `@FlaggedApi(Flags.FLAG_ARCHIVING) to transfer requirement to caller`)"
+        errorLine1="                    if (intent.getBooleanExtra(Intent.EXTRA_ARCHIVAL, false)) {"
+        errorLine2="                                                      ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/com/android/internal/content/PackageMonitor.java"
+            line="491"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `ACTION_PACKAGE_UNSTOPPED` is a flagged API and should be inside an `if (Flags.stayStopped())` check (or annotate the surrounding method `doHandlePackageEvent` with `@FlaggedApi(Flags.FLAG_STAY_STOPPED) to transfer requirement to caller`)"
+        errorLine1="        } else if (Intent.ACTION_PACKAGE_UNSTOPPED.equals(action)) {"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/com/android/internal/content/PackageMonitor.java"
+            line="582"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_LEFT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `measureText` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="        setFlags(getFlags() | (TEXT_RUN_FLAG_LEFT_EDGE | TEXT_RUN_FLAG_RIGHT_EDGE));"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/Paint.java"
+            line="2587"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_RIGHT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `measureText` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="        setFlags(getFlags() | (TEXT_RUN_FLAG_LEFT_EDGE | TEXT_RUN_FLAG_RIGHT_EDGE));"
+        errorLine2="                                                         ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/Paint.java"
+            line="2587"
+            column="58"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_LEFT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `measureText` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="        setFlags(getFlags() | (TEXT_RUN_FLAG_LEFT_EDGE | TEXT_RUN_FLAG_RIGHT_EDGE));"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/Paint.java"
+            line="2626"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_RIGHT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `measureText` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="        setFlags(getFlags() | (TEXT_RUN_FLAG_LEFT_EDGE | TEXT_RUN_FLAG_RIGHT_EDGE));"
+        errorLine2="                                                         ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/Paint.java"
+            line="2626"
+            column="58"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_LEFT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `getTextWidths` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="        setFlags(getFlags() | (TEXT_RUN_FLAG_LEFT_EDGE | TEXT_RUN_FLAG_RIGHT_EDGE));"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/Paint.java"
+            line="2846"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_RIGHT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `getTextWidths` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="        setFlags(getFlags() | (TEXT_RUN_FLAG_LEFT_EDGE | TEXT_RUN_FLAG_RIGHT_EDGE));"
+        errorLine2="                                                         ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/Paint.java"
+            line="2846"
+            column="58"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_LEFT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `getTextWidths` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="        setFlags(getFlags() | (TEXT_RUN_FLAG_LEFT_EDGE | TEXT_RUN_FLAG_RIGHT_EDGE));"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/Paint.java"
+            line="2936"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_RIGHT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `getTextWidths` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="        setFlags(getFlags() | (TEXT_RUN_FLAG_LEFT_EDGE | TEXT_RUN_FLAG_RIGHT_EDGE));"
+        errorLine2="                                                         ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/Paint.java"
+            line="2936"
+            column="58"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isMgf1DigestsSpecified()` is a flagged API and should be inside an `if (Flags.mgf1DigestSetterV2())` check (or annotate the surrounding method `writeToParcel` with `@FlaggedApi(Flags.FLAG_MGF1_DIGEST_SETTER_V2) to transfer requirement to caller`)"
+        errorLine1="        if (mSpec.isMgf1DigestsSpecified()) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java"
+            line="98"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getMgf1Digests()` is a flagged API and should be inside an `if (Flags.mgf1DigestSetterV2())` check (or annotate the surrounding method `writeToParcel` with `@FlaggedApi(Flags.FLAG_MGF1_DIGEST_SETTER_V2) to transfer requirement to caller`)"
+        errorLine1="            out.writeStringList(List.copyOf(mSpec.getMgf1Digests()));"
+        errorLine2="                                            ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java"
+            line="99"
+            column="45"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `computeBounds()` is a flagged API and should be inside an `if (Flags.exactComputeBounds())` check (or annotate the surrounding method `computeBounds` with `@FlaggedApi(Flags.FLAG_EXACT_COMPUTE_BOUNDS) to transfer requirement to caller`)"
+        errorLine1="        computeBounds(bounds);"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/Path.java"
+            line="310"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onOneTimePermissionSessionTimeout()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `notifyOneTimePermissionSessionTimeout` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="                onOneTimePermissionSessionTimeout(packageName, deviceId);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/permission/PermissionControllerService.java"
+            line="672"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onRevokeSelfPermissionsOnKill()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `revokeSelfPermissionsOnKill` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="                    onRevokeSelfPermissionsOnKill(packageName, permissions, deviceId,"
+        errorLine2="                    ^">
+        <location
+            file="frameworks/base/core/java/android/permission/PermissionControllerService.java"
+            line="776"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `PERSISTENT_DEVICE_ID_DEFAULT` is a flagged API and should be inside an `if (Flags.persistentDeviceIdApi())` check (or annotate the surrounding method `getIndicatorAppOpUsageData` with `@FlaggedApi(Flags.FLAG_PERSISTENT_DEVICE_ID_API) to transfer requirement to caller`)"
+        errorLine1="                VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT);"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/permission/PermissionManager.java"
+            line="1342"
+            column="38"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `PERSISTENT_DEVICE_ID_DEFAULT` is a flagged API and should be inside an `if (Flags.persistentDeviceIdApi())` check (or annotate the surrounding method `getPersistentDeviceId` with `@FlaggedApi(Flags.FLAG_PERSISTENT_DEVICE_ID_API) to transfer requirement to caller`)"
+        errorLine1="            persistentDeviceId = VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT;"
+        errorLine2="                                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/permission/PermissionManager.java"
+            line="1951"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onPermissionsChanged()` is a flagged API and should be inside an `if (Flags.deviceAwarePermissionApisEnabled())` check (or annotate the surrounding method `handleMessage` with `@FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED) to transfer requirement to caller`)"
+        errorLine1="                    mListener.onPermissionsChanged(uid, persistentDeviceId);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/permission/PermissionManager.java"
+            line="2040"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getPersistentDeviceId()` is a flagged API and should be inside an `if (Flags.vdmPublicApis())` check (or annotate the surrounding method `getOpUsageDataForAllDevices` with `@FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) to transfer requirement to caller`)"
+        errorLine1="            persistentDeviceIds.add(virtualDevices.get(num).getPersistentDeviceId());"
+        errorLine2="                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/permission/PermissionUsageHelper.java"
+            line="381"
+            column="37"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `PERSISTENT_DEVICE_ID_DEFAULT` is a flagged API and should be inside an `if (Flags.persistentDeviceIdApi())` check (or annotate the surrounding method `getOpUsageDataForAllDevices` with `@FlaggedApi(Flags.FLAG_PERSISTENT_DEVICE_ID_API) to transfer requirement to caller`)"
+        errorLine1="        persistentDeviceIds.add(VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT);"
+        errorLine2="                                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/permission/PermissionUsageHelper.java"
+            line="383"
+            column="54"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `PERSISTENT_DEVICE_ID_DEFAULT` is a flagged API and should be inside an `if (Flags.persistentDeviceIdApi())` check (or annotate the surrounding method `getOpUsagesByDevice` with `@FlaggedApi(Flags.FLAG_PERSISTENT_DEVICE_ID_API) to transfer requirement to caller`)"
+        errorLine1="                    VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT)) {"
+        errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/permission/PermissionUsageHelper.java"
+            line="492"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `hasSimultaneousCallingRestriction()` is a flagged API and should be inside an `if (Flags.simultaneousCallingIndications())` check (or annotate the surrounding method `Builder` with `@FlaggedApi(Flags.FLAG_SIMULTANEOUS_CALLING_INDICATIONS) to transfer requirement to caller`)"
+        errorLine1="            if (phoneAccount.hasSimultaneousCallingRestriction()) {"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telecomm/java/android/telecom/PhoneAccount.java"
+            line="585"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getSimultaneousCallingRestriction()` is a flagged API and should be inside an `if (Flags.simultaneousCallingIndications())` check (or annotate the surrounding method `Builder` with `@FlaggedApi(Flags.FLAG_SIMULTANEOUS_CALLING_INDICATIONS) to transfer requirement to caller`)"
+        errorLine1="                mSimultaneousCallingRestriction = phoneAccount.getSimultaneousCallingRestriction();"
+        errorLine2="                                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telecomm/java/android/telecom/PhoneAccount.java"
+            line="586"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `hasSimultaneousCallingRestriction()` is a flagged API and should be inside an `if (Flags.simultaneousCallingIndications())` check (or annotate the surrounding method `toString` with `@FlaggedApi(Flags.FLAG_SIMULTANEOUS_CALLING_INDICATIONS) to transfer requirement to caller`)"
+        errorLine1="        if (hasSimultaneousCallingRestriction()) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telecomm/java/android/telecom/PhoneAccount.java"
+            line="1292"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `STATE_PLAYBACK_SUPPRESSED` is a flagged API and should be inside an `if (Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange())` check (or annotate the surrounding method `isActive` with `@FlaggedApi(Flags.FLAG_ENABLE_NOTIFYING_ACTIVITY_MANAGER_WITH_MEDIA_SESSION_STATUS_CHANGE) to transfer requirement to caller`)"
+        errorLine1="            case PlaybackState.STATE_PLAYBACK_SUPPRESSED:"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/session/PlaybackState.java"
+            line="541"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `STATE_PLAYBACK_SUPPRESSED` is a flagged API and should be inside an `if (Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange())` check (or annotate the surrounding method `getStringForStateInt` with `@FlaggedApi(Flags.FLAG_ENABLE_NOTIFYING_ACTIVITY_MANAGER_WITH_MEDIA_SESSION_STATUS_CHANGE) to transfer requirement to caller`)"
+        errorLine1="            case STATE_PLAYBACK_SUPPRESSED:"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/session/PlaybackState.java"
+            line="587"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="39"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="39"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="39"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="39"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="39"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="39"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="39"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="39"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="39"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="39"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="39"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="39"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="39"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="39"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="39"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="39"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="39"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="39"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="39"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="49"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="49"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="57"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="57"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="94"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="103"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="103"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="115"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="123"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitor.java"
+            line="129"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitorReadings.java"
+            line="29"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitorReadings.java"
+            line="29"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitorReadings.java"
+            line="29"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitorReadings.java"
+            line="29"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitorReadings.java"
+            line="29"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitorReadings.java"
+            line="29"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitorReadings.java"
+            line="29"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitorReadings.java"
+            line="29"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitorReadings.java"
+            line="29"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitorReadings.java"
+            line="29"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitorReadings.java"
+            line="29"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitorReadings.java"
+            line="29"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitorReadings.java"
+            line="29"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitorReadings.java"
+            line="29"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="@FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitorReadings.java"
+            line="29"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitorReadings.java"
+            line="31"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitorReadings.java"
+            line="31"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitorReadings.java"
+            line="60"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/PowerMonitorReadings.java"
+            line="72"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `NETWORK_VALIDATION_UNSUPPORTED` is a flagged API and should be inside an `if (Flags.networkValidation())` check (or annotate the surrounding method `PreciseDataConnectionState` with `@FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) to transfer requirement to caller`)"
+        errorLine1="                        .build(), null, NETWORK_VALIDATION_UNSUPPORTED);"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/PreciseDataConnectionState.java"
+            line="143"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `NETWORK_VALIDATION_UNSUPPORTED` is a flagged API and should be inside an `if (Flags.networkValidation())` check (or annotate the surrounding method `networkValidationStatusToString` with `@FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) to transfer requirement to caller`)"
+        errorLine1="            case NETWORK_VALIDATION_UNSUPPORTED: return &quot;unsupported&quot;;"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/PreciseDataConnectionState.java"
+            line="456"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `NETWORK_VALIDATION_NOT_REQUESTED` is a flagged API and should be inside an `if (Flags.networkValidation())` check (or annotate the surrounding method `networkValidationStatusToString` with `@FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) to transfer requirement to caller`)"
+        errorLine1="            case NETWORK_VALIDATION_NOT_REQUESTED: return &quot;not requested&quot;;"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/PreciseDataConnectionState.java"
+            line="457"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `NETWORK_VALIDATION_IN_PROGRESS` is a flagged API and should be inside an `if (Flags.networkValidation())` check (or annotate the surrounding method `networkValidationStatusToString` with `@FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) to transfer requirement to caller`)"
+        errorLine1="            case NETWORK_VALIDATION_IN_PROGRESS: return &quot;in progress&quot;;"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/PreciseDataConnectionState.java"
+            line="458"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `NETWORK_VALIDATION_SUCCESS` is a flagged API and should be inside an `if (Flags.networkValidation())` check (or annotate the surrounding method `networkValidationStatusToString` with `@FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) to transfer requirement to caller`)"
+        errorLine1="            case NETWORK_VALIDATION_SUCCESS: return &quot;success&quot;;"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/PreciseDataConnectionState.java"
+            line="459"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `NETWORK_VALIDATION_FAILURE` is a flagged API and should be inside an `if (Flags.networkValidation())` check (or annotate the surrounding method `networkValidationStatusToString` with `@FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) to transfer requirement to caller`)"
+        errorLine1="            case NETWORK_VALIDATION_FAILURE: return &quot;failure&quot;;"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/PreciseDataConnectionState.java"
+            line="460"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `NETWORK_VALIDATION_UNSUPPORTED` is a flagged API and should be inside an `if (Flags.networkValidation())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_NETWORK_VALIDATION) to transfer requirement to caller`)"
+        errorLine1="                NETWORK_VALIDATION_UNSUPPORTED;"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/PreciseDataConnectionState.java"
+            line="508"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `LINE_BREAK_WORD_STYLE_AUTO` is a flagged API and should be inside an `if (Flags.wordStyleAuto())` check (or annotate the surrounding method `createMeasuredParagraphsFromPrecomputedText` with `@FlaggedApi(Flags.FLAG_WORD_STYLE_AUTO) to transfer requirement to caller`)"
+        errorLine1="        if (config.getLineBreakWordStyle() == LineBreakConfig.LINE_BREAK_WORD_STYLE_AUTO"
+        errorLine2="                                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/PrecomputedText.java"
+            line="461"
+            column="63"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `merge()` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `createMeasuredParagraphsFromPrecomputedText` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="            config = new LineBreakConfig.Builder()"
+        errorLine2="                     ^">
+        <location
+            file="frameworks/base/core/java/android/text/PrecomputedText.java"
+            line="464"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `LINE_BREAK_WORD_STYLE_AUTO` is a flagged API and should be inside an `if (Flags.wordStyleAuto())` check (or annotate the surrounding method `createMeasuredParagraphs` with `@FlaggedApi(Flags.FLAG_WORD_STYLE_AUTO) to transfer requirement to caller`)"
+        errorLine1="                if (config.getLineBreakWordStyle() == LineBreakConfig.LINE_BREAK_WORD_STYLE_AUTO"
+        errorLine2="                                                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/PrecomputedText.java"
+            line="515"
+            column="71"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isResumed()` is a flagged API and should be inside an `if (Flags.enableNfcMainline())` check (or annotate the surrounding method `onListItemClick` with `@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) to transfer requirement to caller`)"
+        errorLine1="        if (!isResumed()) {"
+        errorLine2="             ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/preference/PreferenceActivity.java"
+            line="1071"
+            column="14"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `PromptContentViewParcelable` is a flagged API and should be inside an `if (Flags.customBiometricPrompt())` check (or annotate the surrounding method `PromptInfo` with `@FlaggedApi(Flags.FLAG_CUSTOM_BIOMETRIC_PROMPT) to transfer requirement to caller`)"
+        errorLine1="        mContentView = in.readParcelable(PromptContentViewParcelable.class.getClassLoader(),"
+        errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/biometrics/PromptInfo.java"
+            line="75"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `PromptContentViewParcelable` is a flagged API and should be inside an `if (Flags.customBiometricPrompt())` check (or annotate the surrounding method `PromptInfo` with `@FlaggedApi(Flags.FLAG_CUSTOM_BIOMETRIC_PROMPT) to transfer requirement to caller`)"
+        errorLine1="                PromptContentViewParcelable.class);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/biometrics/PromptInfo.java"
+            line="76"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="This is a flagged API and should be inside an `if (Flags.customBiometricPrompt())` check (or annotate the surrounding method `isContentViewMoreOptionsButtonUsed` with `@FlaggedApi(Flags.FLAG_CUSTOM_BIOMETRIC_PROMPT) to transfer requirement to caller`)"
+        errorLine1="                &amp;&amp; mContentView instanceof PromptContentViewWithMoreOptionsButton;"
+        errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/biometrics/PromptInfo.java"
+            line="214"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="This is a flagged API and should be inside an `if (Flags.customBiometricPrompt())` check (or annotate the surrounding method `setContentView` with `@FlaggedApi(Flags.FLAG_CUSTOM_BIOMETRIC_PROMPT) to transfer requirement to caller`)"
+        errorLine1="        mContentView = (PromptContentViewParcelable) view;"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/biometrics/PromptInfo.java"
+            line="258"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.media.tv.flags.enable_ad_service_fw&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="610"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.media.tv.flags.enable_ad_service_fw&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="610"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.media.tv.flags.enable_ad_service_fw&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="610"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.media.tv.flags.enable_ad_service_fw&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="610"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.relative_reference_intent_filters&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="693"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.security.asm_restrictions_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="759"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.nfc.nfc_read_polling_loop&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="1300"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.view.flags.sensitive_content_app_protection_api&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="2782"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.res.default_locale&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="3023"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.service.controls.flags.Flags.FLAG_HOME_PANEL_DREAM&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="3599"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.service.controls.flags.Flags.FLAG_HOME_PANEL_DREAM&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="3599"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.service.controls.flags.Flags.FLAG_HOME_PANEL_DREAM&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="3599"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.service.controls.flags.Flags.FLAG_HOME_PANEL_DREAM&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="3599"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.res.manifest_flagging&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="4290"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.relative_reference_intent_filters&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="4870"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.relative_reference_intent_filters&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="4970"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.relative_reference_intent_filters&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="4979"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.relative_reference_intent_filters&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="5032"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.companion.virtual.flags.vdm_custom_ime&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="6857"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.view.inputmethod.ime_switcher_revamp&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="7587"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.view.inputmethod.ime_switcher_revamp&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="7587"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.view.inputmethod.ime_switcher_revamp&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="7587"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.view.inputmethod.ime_switcher_revamp&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="7587"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.sdk_lib_independence&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="9481"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.sdk_lib_independence&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="9481"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.sdk_lib_independence&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="9481"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.sdk_lib_independence&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="9481"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.relative_reference_intent_filters&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="10701"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.relative_reference_intent_filters&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="10727"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.relative_reference_intent_filters&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="10767"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.relative_reference_intent_filters&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="10776"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.pm.relative_reference_intent_filters&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="10785"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.security.content_uri_permission_apis&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="11122"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.text.flags.use_bounds_for_width&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="12404"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.nfc.nfc_observe_mode&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="12438"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.view.inputmethod.connectionless_handwriting&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="13485"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.multiuser.enable_system_user_only_for_services_and_providers&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="13672"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.text.flags.use_bounds_for_width&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="15472"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.text.flags.fix_line_height_for_locale&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="15520"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.view.flags.toolkit_set_frame_rate_read_only&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="16364"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.window.flags.enforce_edge_to_edge&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="16561"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.permission.flags.retail_demo_role_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="18455"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.permission.flags.wallet_role_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="18473"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.security.content_uri_permission_apis&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="25110"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.security.asm_restrictions_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="25837"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.security.asm_restrictions_enabled&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="27173"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.view.inputmethod.ime_switcher_revamp&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="41370"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.companion.virtual.flags.vdm_custom_ime&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="41608"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.view.inputmethod.ime_switcher_revamp&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="41645"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.content.res.default_locale&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="44145"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.nfc.nfc_read_polling_loop&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="45932"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.nfc.nfc_read_polling_loop&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="45956"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.nfc.nfc_read_polling_loop&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="45970"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.nfc.nfc_read_polling_loop&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="45996"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.text.flags.use_bounds_for_width&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="53416"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.text.flags.use_bounds_for_width&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="53416"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.text.flags.use_bounds_for_width&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="53416"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.text.flags.use_bounds_for_width&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="53416"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.text.flags.use_bounds_for_width&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="55227"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.text.flags.fix_line_height_for_locale&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="55238"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;com.android.text.flags.use_bounds_for_width&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="55249"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.view.flags.sensitive_content_app_protection_api&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="62287"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @android.annotation.FlaggedApi(&quot;android.view.flags.sensitive_content_app_protection_api&quot;)"
+        errorLine2="                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/frameworks/base/core/res/framework-res/android_common/gen/android/R.srcjar!/android/R.java"
+            line="64240"
+            column="36"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `METADATA_KEY_COMMENT_SHORT_DESCRIPTION` is a flagged API and should be inside an `if (Flags.hdRadioImproved())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED) to transfer requirement to caller`)"
+        errorLine1="        METADATA_KEYS_TYPE.put(METADATA_KEY_COMMENT_SHORT_DESCRIPTION, METADATA_TYPE_TEXT);"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/radio/RadioMetadata.java"
+            line="249"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `METADATA_KEY_COMMENT_ACTUAL_TEXT` is a flagged API and should be inside an `if (Flags.hdRadioImproved())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED) to transfer requirement to caller`)"
+        errorLine1="        METADATA_KEYS_TYPE.put(METADATA_KEY_COMMENT_ACTUAL_TEXT, METADATA_TYPE_TEXT);"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/radio/RadioMetadata.java"
+            line="250"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `METADATA_KEY_COMMERCIAL` is a flagged API and should be inside an `if (Flags.hdRadioImproved())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED) to transfer requirement to caller`)"
+        errorLine1="        METADATA_KEYS_TYPE.put(METADATA_KEY_COMMERCIAL, METADATA_TYPE_TEXT);"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/radio/RadioMetadata.java"
+            line="251"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `METADATA_KEY_UFIDS` is a flagged API and should be inside an `if (Flags.hdRadioImproved())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED) to transfer requirement to caller`)"
+        errorLine1="        METADATA_KEYS_TYPE.put(METADATA_KEY_UFIDS, METADATA_TYPE_TEXT_ARRAY);"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/radio/RadioMetadata.java"
+            line="252"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `METADATA_KEY_HD_STATION_NAME_SHORT` is a flagged API and should be inside an `if (Flags.hdRadioImproved())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED) to transfer requirement to caller`)"
+        errorLine1="        METADATA_KEYS_TYPE.put(METADATA_KEY_HD_STATION_NAME_SHORT, METADATA_TYPE_TEXT);"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/radio/RadioMetadata.java"
+            line="253"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `METADATA_KEY_HD_STATION_NAME_LONG` is a flagged API and should be inside an `if (Flags.hdRadioImproved())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED) to transfer requirement to caller`)"
+        errorLine1="        METADATA_KEYS_TYPE.put(METADATA_KEY_HD_STATION_NAME_LONG, METADATA_TYPE_TEXT);"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/radio/RadioMetadata.java"
+            line="254"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `METADATA_KEY_HD_SUBCHANNELS_AVAILABLE` is a flagged API and should be inside an `if (Flags.hdRadioImproved())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED) to transfer requirement to caller`)"
+        errorLine1="        METADATA_KEYS_TYPE.put(METADATA_KEY_HD_SUBCHANNELS_AVAILABLE, METADATA_TYPE_INT);"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/radio/RadioMetadata.java"
+            line="255"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isPrivateProfile()` is a flagged API and should be inside an `if (Flags.allowPrivateProfile())` check (or annotate the surrounding method `fetchPrivateProfileUserHandle` with `@FlaggedApi(Flags.FLAG_ALLOW_PRIVATE_PROFILE) to transfer requirement to caller`)"
+        errorLine1="            if (userInfo.isPrivateProfile()) {"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/com/android/internal/app/ResolverActivity.java"
+            line="827"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getDefaultLocale()` is a flagged API and should be inside an `if (Flags.defaultLocale())` check (or annotate the surrounding method `updateConfigurationImpl` with `@FlaggedApi(Flags.FLAG_DEFAULT_LOCALE) to transfer requirement to caller`)"
+        errorLine1="                        if (Flags.defaultLocale() &amp;&amp; (lc.getDefaultLocale() != null)) {"
+        errorLine2="                                                      ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/res/ResourcesImpl.java"
+            line="474"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getDefaultLocale()` is a flagged API and should be inside an `if (Flags.defaultLocale())` check (or annotate the surrounding method `updateConfigurationImpl` with `@FlaggedApi(Flags.FLAG_DEFAULT_LOCALE) to transfer requirement to caller`)"
+        errorLine1="                    if (Flags.defaultLocale() &amp;&amp; (lc.getDefaultLocale() != null)) {"
+        errorLine2="                                                  ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/res/ResourcesImpl.java"
+            line="515"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `ROLLBACK_USER_IMPACT_LOW` is a flagged API and should be inside an `if (Flags.recoverabilityDetection())` check (or annotate the surrounding method `RollbackInfo` with `@FlaggedApi(Flags.FLAG_RECOVERABILITY_DETECTION) to transfer requirement to caller`)"
+        errorLine1="                PackageManager.ROLLBACK_USER_IMPACT_LOW);"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/rollback/RollbackInfo.java"
+            line="80"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getTransferReason()` is a flagged API and should be inside an `if (Flags.enableBuiltInSpeakerRouteSuitabilityStatuses())` check (or annotate the surrounding method `toString` with `@FlaggedApi(Flags.FLAG_ENABLE_BUILT_IN_SPEAKER_ROUTE_SUITABILITY_STATUSES) to transfer requirement to caller`)"
+        errorLine1="                .append(getTransferReason())"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/RoutingSessionInfo.java"
+            line="528"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TRANSFER_REASON_FALLBACK` is a flagged API and should be inside an `if (Flags.enableBuiltInSpeakerRouteSuitabilityStatuses())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_ENABLE_BUILT_IN_SPEAKER_ROUTE_SUITABILITY_STATUSES) to transfer requirement to caller`)"
+        errorLine1="        @TransferReason private int mTransferReason = TRANSFER_REASON_FALLBACK;"
+        errorLine2="                                                      ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/RoutingSessionInfo.java"
+            line="590"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SCREEN_RECORDING_STATE_NOT_VISIBLE` is a flagged API and should be inside an `if (Flags.screenRecordingCallbacks())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_SCREEN_RECORDING_CALLBACKS) to transfer requirement to caller`)"
+        errorLine1="    private @ScreenRecordingState int mState = SCREEN_RECORDING_STATE_NOT_VISIBLE;"
+        errorLine2="                                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/ScreenRecordingCallbacks.java"
+            line="54"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SCREEN_RECORDING_STATE_VISIBLE` is a flagged API and should be inside an `if (Flags.screenRecordingCallbacks())` check (or annotate the surrounding method `onScreenRecordingStateChanged` with `@FlaggedApi(Flags.FLAG_SCREEN_RECORDING_CALLBACKS) to transfer requirement to caller`)"
+        errorLine1="                                                ? SCREEN_RECORDING_STATE_VISIBLE"
+        errorLine2="                                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/ScreenRecordingCallbacks.java"
+            line="85"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SCREEN_RECORDING_STATE_NOT_VISIBLE` is a flagged API and should be inside an `if (Flags.screenRecordingCallbacks())` check (or annotate the surrounding method `onScreenRecordingStateChanged` with `@FlaggedApi(Flags.FLAG_SCREEN_RECORDING_CALLBACKS) to transfer requirement to caller`)"
+        errorLine1="                                                : SCREEN_RECORDING_STATE_NOT_VISIBLE;"
+        errorLine2="                                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/ScreenRecordingCallbacks.java"
+            line="86"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SCREEN_RECORDING_STATE_VISIBLE` is a flagged API and should be inside an `if (Flags.screenRecordingCallbacks())` check (or annotate the surrounding method `addCallback` with `@FlaggedApi(Flags.FLAG_SCREEN_RECORDING_CALLBACKS) to transfer requirement to caller`)"
+        errorLine1="                                    ? SCREEN_RECORDING_STATE_VISIBLE"
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/ScreenRecordingCallbacks.java"
+            line="96"
+            column="39"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SCREEN_RECORDING_STATE_NOT_VISIBLE` is a flagged API and should be inside an `if (Flags.screenRecordingCallbacks())` check (or annotate the surrounding method `addCallback` with `@FlaggedApi(Flags.FLAG_SCREEN_RECORDING_CALLBACKS) to transfer requirement to caller`)"
+        errorLine1="                                    : SCREEN_RECORDING_STATE_NOT_VISIBLE;"
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/ScreenRecordingCallbacks.java"
+            line="97"
+            column="39"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FOREGROUND_SERVICE_TYPE_MEDIA_PROCESSING` is a flagged API and should be inside an `if (Flags.introduceMediaProcessingType())` check (or annotate the surrounding method `foregroundServiceTypeToLabel` with `@FlaggedApi(Flags.FLAG_INTRODUCE_MEDIA_PROCESSING_TYPE) to transfer requirement to caller`)"
+        errorLine1="            case FOREGROUND_SERVICE_TYPE_MEDIA_PROCESSING:"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/pm/ServiceInfo.java"
+            line="707"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isPrivateProfile()` is a flagged API and should be inside an `if (Flags.allowPrivateProfile())` check (or annotate the surrounding method `setLaunchUserSpecificMessage` with `@FlaggedApi(Flags.FLAG_ALLOW_PRIVATE_PROFILE) to transfer requirement to caller`)"
+        errorLine1="            if (userInfo != null &amp;&amp; userInfo.isPrivateProfile()) {"
+        errorLine2="                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/com/android/internal/app/SetScreenLockDialogActivity.java"
+            line="146"
+            column="37"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;com.android.media.flags.enable_privileged_routing_for_media_routing_control&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/provider/Settings.java"
+            line="665"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="        @FlaggedApi(&quot;com.android.server.biometrics.face_vhal_feature&quot;)"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/provider/Settings.java"
+            line="11022"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="        @FlaggedApi(&quot;com.android.server.biometrics.face_vhal_feature&quot;)"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/provider/Settings.java"
+            line="11030"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;com.android.wifi.flags.shared_connectivity_broadcast_receiver_test_api&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManager.java"
+            line="300"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getInputTransferToken()` is a flagged API and should be inside an `if (Flags.surfaceControlInputReceiver())` check (or annotate the surrounding method `createSurfaceView` with `@FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) to transfer requirement to caller`)"
+        errorLine1="                                : attachedSurfaceControl.getInputTransferToken(),"
+        errorLine2="                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/window/SplashScreenView.java"
+            line="342"
+            column="35"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `uptimeNanos()` is a flagged API and should be inside an `if (Flags.adpfGpuReportActualWorkDuration())` check (or annotate the surrounding method `getTime` with `@FlaggedApi(Flags.FLAG_ADPF_GPU_REPORT_ACTUAL_WORK_DURATION) to transfer requirement to caller`)"
+        errorLine1="        return SystemClock.uptimeNanos() / 1000;"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/com/android/internal/util/StatLogger.java"
+            line="94"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setUseBoundsForWidth()` is a flagged API and should be inside an `if (Flags.useBoundsForWidth())` check (or annotate the surrounding method `generate` with `@FlaggedApi(Flags.FLAG_USE_BOUNDS_FOR_WIDTH) to transfer requirement to caller`)"
+        errorLine1="        final LineBreaker lineBreaker = new LineBreaker.Builder()"
+        errorLine2="                                        ^">
+        <location
+            file="frameworks/base/core/java/android/text/StaticLayout.java"
+            line="823"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `computeDrawingBoundingBox()` is a flagged API and should be inside an `if (Flags.useBoundsForWidth())` check (or annotate the surrounding method `computeDrawingBoundingBox` with `@FlaggedApi(Flags.FLAG_USE_BOUNDS_FOR_WIDTH) to transfer requirement to caller`)"
+        errorLine1="            mDrawingBounds = super.computeDrawingBoundingBox();"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/StaticLayout.java"
+            line="1578"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `createNoBreakSpan()` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `applyStyles` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                buffer.setSpan(LineBreakConfigSpan.createNoBreakSpan(),"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/res/StringBlock.java"
+            line="297"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `createNoHyphenationSpan()` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `applyStyles` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                buffer.setSpan(LineBreakConfigSpan.createNoHyphenationSpan(),"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/res/StringBlock.java"
+            line="301"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `LINE_BREAK_STYLE_UNSPECIFIED` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `applyStyles` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                    int lbStyle = LineBreakConfig.LINE_BREAK_STYLE_UNSPECIFIED;"
+        errorLine2="                                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/res/StringBlock.java"
+            line="387"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `LINE_BREAK_STYLE_UNSPECIFIED` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `applyStyles` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                    int lbWordStyle = LineBreakConfig.LINE_BREAK_STYLE_UNSPECIFIED;"
+        errorLine2="                                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/res/StringBlock.java"
+            line="403"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `LINE_BREAK_STYLE_UNSPECIFIED` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `applyStyles` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                    if (lbStyle != LineBreakConfig.LINE_BREAK_STYLE_UNSPECIFIED"
+        errorLine2="                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/res/StringBlock.java"
+            line="415"
+            column="52"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `LINE_BREAK_WORD_STYLE_UNSPECIFIED` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `applyStyles` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                            || lbWordStyle != LineBreakConfig.LINE_BREAK_WORD_STYLE_UNSPECIFIED) {"
+        errorLine2="                                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/res/StringBlock.java"
+            line="416"
+            column="63"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `LineBreakConfigSpan()` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `applyStyles` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                        buffer.setSpan(new LineBreakConfigSpan("
+        errorLine2="                                       ^">
+        <location
+            file="frameworks/base/core/java/android/content/res/StringBlock.java"
+            line="417"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `HYPHENATION_UNSPECIFIED` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `applyStyles` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                                        LineBreakConfig.HYPHENATION_UNSPECIFIED)),"
+        errorLine2="                                                        ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/res/StringBlock.java"
+            line="419"
+            column="57"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setServiceCapabilities()` is a flagged API and should be inside an `if (Flags.dataOnlyCellularService())` check (or annotate the surrounding method `createFromParcel` with `@FlaggedApi(Flags.FLAG_DATA_ONLY_CELLULAR_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            return new Builder()"
+        errorLine2="                   ^">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/SubscriptionInfo.java"
+            line="957"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setTransferStatus()` is a flagged API and should be inside an `if (Flags.supportPsimToEsimConversion())` check (or annotate the surrounding method `createFromParcel` with `@FlaggedApi(Flags.FLAG_SUPPORT_PSIM_TO_ESIM_CONVERSION) to transfer requirement to caller`)"
+        errorLine1="            return new Builder()"
+        errorLine2="                   ^">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/SubscriptionInfo.java"
+            line="957"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SERVICE_CAPABILITY_DATA` is a flagged API and should be inside an `if (Flags.dataOnlyCellularService())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_DATA_ONLY_CELLULAR_SERVICE) to transfer requirement to caller`)"
+        errorLine1="    public static final int SERVICE_CAPABILITY_MAX = SERVICE_CAPABILITY_DATA;"
+        errorLine2="                                                     ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/SubscriptionManager.java"
+            line="1436"
+            column="54"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SERVICE_CAPABILITY_VOICE` is a flagged API and should be inside an `if (Flags.dataOnlyCellularService())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_DATA_ONLY_CELLULAR_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            serviceCapabilityToBitmask(SERVICE_CAPABILITY_VOICE);"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/SubscriptionManager.java"
+            line="1443"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SERVICE_CAPABILITY_SMS` is a flagged API and should be inside an `if (Flags.dataOnlyCellularService())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_DATA_ONLY_CELLULAR_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            serviceCapabilityToBitmask(SERVICE_CAPABILITY_SMS);"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/SubscriptionManager.java"
+            line="1450"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SERVICE_CAPABILITY_DATA` is a flagged API and should be inside an `if (Flags.dataOnlyCellularService())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_DATA_ONLY_CELLULAR_SERVICE) to transfer requirement to caller`)"
+        errorLine1="            serviceCapabilityToBitmask(SERVICE_CAPABILITY_DATA);"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/SubscriptionManager.java"
+            line="1457"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="This is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `addOnSubscriptionsChangedListener` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="        TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)"
+        errorLine2="                                                             ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/SubscriptionManager.java"
+            line="1696"
+            column="62"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `addOnSubscriptionsChangedListener()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `addOnSubscriptionsChangedListener` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="            telephonyRegistryManager.addOnSubscriptionsChangedListener(listener,"
+        errorLine2="            ^">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/SubscriptionManager.java"
+            line="1699"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="This is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `removeOnSubscriptionsChangedListener` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="        TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)"
+        errorLine2="                                                             ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/SubscriptionManager.java"
+            line="1726"
+            column="62"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `removeOnSubscriptionsChangedListener()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `removeOnSubscriptionsChangedListener` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="            telephonyRegistryManager.removeOnSubscriptionsChangedListener(listener);"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/SubscriptionManager.java"
+            line="1729"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="This is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `addOnOpportunisticSubscriptionsChangedListener` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="        TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)"
+        errorLine2="                                                             ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/SubscriptionManager.java"
+            line="1784"
+            column="62"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `addOnOpportunisticSubscriptionsChangedListener()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `addOnOpportunisticSubscriptionsChangedListener` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="            telephonyRegistryManager.addOnOpportunisticSubscriptionsChangedListener("
+        errorLine2="            ^">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/SubscriptionManager.java"
+            line="1787"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="This is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `removeOnOpportunisticSubscriptionsChangedListener` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="        TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager)"
+        errorLine2="                                                             ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/SubscriptionManager.java"
+            line="1808"
+            column="62"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `removeOnOpportunisticSubscriptionsChangedListener()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `removeOnOpportunisticSubscriptionsChangedListener` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="            telephonyRegistryManager.removeOnOpportunisticSubscriptionsChangedListener(listener);"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/SubscriptionManager.java"
+            line="1811"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SERVICE_CAPABILITY_VOICE` is a flagged API and should be inside an `if (Flags.dataOnlyCellularService())` check (or annotate the surrounding method `getServiceCapabilitiesSet` with `@FlaggedApi(Flags.FLAG_DATA_ONLY_CELLULAR_SERVICE) to transfer requirement to caller`)"
+        errorLine1="        for (int i = SERVICE_CAPABILITY_VOICE; i &lt;= SERVICE_CAPABILITY_MAX; i++) {"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/SubscriptionManager.java"
+            line="4800"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CREATOR` is a flagged API and should be inside an `if (Flags.surfaceControlInputReceiver())` check (or annotate the surrounding method `SurfacePackage` with `@FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) to transfer requirement to caller`)"
+        errorLine1="            mInputTransferToken = InputTransferToken.CREATOR.createFromParcel(in);"
+        errorLine2="                                                     ~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/SurfaceControlViewHost.java"
+            line="196"
+            column="54"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `writeToParcel()` is a flagged API and should be inside an `if (Flags.surfaceControlInputReceiver())` check (or annotate the surrounding method `writeToParcel` with `@FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) to transfer requirement to caller`)"
+        errorLine1="            mInputTransferToken.writeToParcel(out, flags);"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/SurfaceControlViewHost.java"
+            line="276"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getInputTransferToken()` is a flagged API and should be inside an `if (Flags.surfaceControlInputReceiver())` check (or annotate the surrounding method `toString` with `@FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) to transfer requirement to caller`)"
+        errorLine1="            return &quot;{inputTransferToken=&quot; + getInputTransferToken() + &quot; remoteInterface=&quot;"
+        errorLine2="                                            ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/SurfaceControlViewHost.java"
+            line="309"
+            column="45"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `InputTransferToken()` is a flagged API and should be inside an `if (Flags.surfaceControlInputReceiver())` check (or annotate the surrounding method `SurfaceControlViewHost` with `@FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) to transfer requirement to caller`)"
+        errorLine1="        this(context, display, hostToken == null ? null : new InputTransferToken(hostToken),"
+        errorLine2="                                                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/SurfaceControlViewHost.java"
+            line="352"
+            column="59"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `transferTouchGesture()` is a flagged API and should be inside an `if (Flags.surfaceControlInputReceiver())` check (or annotate the surrounding method `transferTouchGestureToHost` with `@FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) to transfer requirement to caller`)"
+        errorLine1="        return wm.transferTouchGesture(getInputTransferToken(), mWm.mHostInputTransferToken);"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/SurfaceControlViewHost.java"
+            line="602"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getInputTransferToken()` is a flagged API and should be inside an `if (Flags.surfaceControlInputReceiver())` check (or annotate the surrounding method `requestEmbeddedFocus` with `@FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) to transfer requirement to caller`)"
+        errorLine1="                    mSurfacePackage.getInputTransferToken(), gainFocus);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/SurfaceView.java"
+            line="2155"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `uptimeNanos()` is a flagged API and should be inside an `if (Flags.adpfGpuReportActualWorkDuration())` check (or annotate the surrounding method `uptimeMillis$ravenwood` with `@FlaggedApi(Flags.FLAG_ADPF_GPU_REPORT_ACTUAL_WORK_DURATION) to transfer requirement to caller`)"
+        errorLine1="        return uptimeNanos() / 1_000_000;"
+        errorLine2="               ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/SystemClock.java"
+            line="202"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `uptimeNanos()` is a flagged API and should be inside an `if (Flags.adpfGpuReportActualWorkDuration())` check (or annotate the surrounding method `elapsedRealtimeNanos$ravenwood` with `@FlaggedApi(Flags.FLAG_ADPF_GPU_REPORT_ACTUAL_WORK_DURATION) to transfer requirement to caller`)"
+        errorLine1="        return uptimeNanos() + (DateUtils.HOUR_IN_MILLIS * 1_000_000);"
+        errorLine2="               ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/SystemClock.java"
+            line="276"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/health/SystemHealthManager.java"
+            line="231"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="@FlaggedApi should specify an actual flag constant; raw strings are discouraged (and more importantly, **not enforced**)"
+        errorLine1="    @FlaggedApi(&quot;com.android.server.power.optimization.power_monitor_api&quot;)"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/health/SystemHealthManager.java"
+            line="287"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `null()` is a flagged API and should be inside an `if (Flags.vdmPublicApis())` check (or annotate the surrounding method `setupVirtualDeviceListener` with `@FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) to transfer requirement to caller`)"
+        errorLine1="        mVirtualDeviceListener = new VirtualDeviceManager.VirtualDeviceListener() {"
+        errorLine2="                                 ^">
+        <location
+            file="frameworks/base/core/java/android/hardware/SystemSensorManager.java"
+            line="612"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="This is a flagged API and should be inside an `if (Flags.vdmPublicApis())` check (or annotate the surrounding method `setupVirtualDeviceListener` with `@FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) to transfer requirement to caller`)"
+        errorLine1="        mVirtualDeviceListener = new VirtualDeviceManager.VirtualDeviceListener() {"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/SystemSensorManager.java"
+            line="612"
+            column="38"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `registerVirtualDeviceListener()` is a flagged API and should be inside an `if (Flags.vdmPublicApis())` check (or annotate the surrounding method `setupVirtualDeviceListener` with `@FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) to transfer requirement to caller`)"
+        errorLine1="        mVdm.registerVirtualDeviceListener(mContext.getMainExecutor(), mVirtualDeviceListener);"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/SystemSensorManager.java"
+            line="627"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `SecurityStateManager` is a flagged API and should be inside an `if (Flags.securityStateService())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_SECURITY_STATE_SERVICE) to transfer requirement to caller`)"
+        errorLine1="        registerService(Context.SECURITY_STATE_SERVICE, SecurityStateManager.class,"
+        errorLine2="                                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="676"
+            column="57"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SECURITY_STATE_SERVICE` is a flagged API and should be inside an `if (Flags.securityStateService())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_SECURITY_STATE_SERVICE) to transfer requirement to caller`)"
+        errorLine1="        registerService(Context.SECURITY_STATE_SERVICE, SecurityStateManager.class,"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="676"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SECURITY_STATE_SERVICE` is a flagged API and should be inside an `if (Flags.securityStateService())` check (or annotate the surrounding method `createService` with `@FlaggedApi(Flags.FLAG_SECURITY_STATE_SERVICE) to transfer requirement to caller`)"
+        errorLine1="                                Context.SECURITY_STATE_SERVICE);"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="682"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `SecurityStateManager()` is a flagged API and should be inside an `if (Flags.securityStateService())` check (or annotate the surrounding method `createService` with `@FlaggedApi(Flags.FLAG_SECURITY_STATE_SERVICE) to transfer requirement to caller`)"
+        errorLine1="                        return new SecurityStateManager(service);"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="684"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `TelephonyRegistryManager` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="        registerService(Context.TELEPHONY_REGISTRY_SERVICE, TelephonyRegistryManager.class,"
+        errorLine2="                                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="743"
+            column="61"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `TelephonyRegistryManager()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `createService` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="                    return new TelephonyRegistryManager(ctx);"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="747"
+            column="28"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `TvAdManager` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="        registerService(Context.TV_AD_SERVICE, TvAdManager.class,"
+        errorLine2="                                               ~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1019"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TV_AD_SERVICE` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="        registerService(Context.TV_AD_SERVICE, TvAdManager.class,"
+        errorLine2="                                ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1019"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TV_AD_SERVICE` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `createService` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                                ServiceManager.getServiceOrThrow(Context.TV_AD_SERVICE);"
+        errorLine2="                                                                         ~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1025"
+            column="74"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `TvAdManager()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `createService` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                        return new TvAdManager(service, ctx.getUserId());"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1028"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `PersistentDataBlockManager` is a flagged API and should be inside an `if (Flags.frpEnforcement())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_FRP_ENFORCEMENT) to transfer requirement to caller`)"
+        errorLine1="        registerService(Context.PERSISTENT_DATA_BLOCK_SERVICE, PersistentDataBlockManager.class,"
+        errorLine2="                                                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1067"
+            column="64"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `PERSISTENT_DATA_BLOCK_SERVICE` is a flagged API and should be inside an `if (Flags.frpEnforcement())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_FRP_ENFORCEMENT) to transfer requirement to caller`)"
+        errorLine1="        registerService(Context.PERSISTENT_DATA_BLOCK_SERVICE, PersistentDataBlockManager.class,"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1067"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `PERSISTENT_DATA_BLOCK_SERVICE` is a flagged API and should be inside an `if (Flags.frpEnforcement())` check (or annotate the surrounding method `createService` with `@FlaggedApi(Flags.FLAG_FRP_ENFORCEMENT) to transfer requirement to caller`)"
+        errorLine1="                IBinder b = ServiceManager.getServiceOrThrow(Context.PERSISTENT_DATA_BLOCK_SERVICE);"
+        errorLine2="                                                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1071"
+            column="70"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `PersistentDataBlockManager()` is a flagged API and should be inside an `if (Flags.frpEnforcement())` check (or annotate the surrounding method `createService` with `@FlaggedApi(Flags.FLAG_FRP_ENFORCEMENT) to transfer requirement to caller`)"
+        errorLine1="                    return new PersistentDataBlockManager(persistentDataBlockService);"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1075"
+            column="28"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `ContextualSearchManager` is a flagged API and should be inside an `if (Flags.enableService())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_ENABLE_SERVICE) to transfer requirement to caller`)"
+        errorLine1="        registerService(Context.CONTEXTUAL_SEARCH_SERVICE, ContextualSearchManager.class,"
+        errorLine2="                                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1319"
+            column="60"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CONTEXTUAL_SEARCH_SERVICE` is a flagged API and should be inside an `if (Flags.enableService())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_ENABLE_SERVICE) to transfer requirement to caller`)"
+        errorLine1="        registerService(Context.CONTEXTUAL_SEARCH_SERVICE, ContextualSearchManager.class,"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1319"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CONTEXTUAL_SEARCH_SERVICE` is a flagged API and should be inside an `if (Flags.enableService())` check (or annotate the surrounding method `createService` with `@FlaggedApi(Flags.FLAG_ENABLE_SERVICE) to transfer requirement to caller`)"
+        errorLine1="                        IBinder b = ServiceManager.getService(Context.CONTEXTUAL_SEARCH_SERVICE);"
+        errorLine2="                                                                      ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1324"
+            column="71"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `ContextualSearchManager()` is a flagged API and should be inside an `if (Flags.enableService())` check (or annotate the surrounding method `createService` with `@FlaggedApi(Flags.FLAG_ENABLE_SERVICE) to transfer requirement to caller`)"
+        errorLine1="                        return b == null ? null : new ContextualSearchManager();"
+        errorLine2="                                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1325"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `DeviceStateManager` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="        registerService(Context.DEVICE_STATE_SERVICE, DeviceStateManager.class,"
+        errorLine2="                                                      ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1564"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `DeviceStateManager()` is a flagged API and should be inside an `if (Flags.deviceStatePropertyApi())` check (or annotate the surrounding method `createService` with `@FlaggedApi(Flags.FLAG_DEVICE_STATE_PROPERTY_API) to transfer requirement to caller`)"
+        errorLine1="                        return new DeviceStateManager();"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1568"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `OnDeviceIntelligenceManager` is a flagged API and should be inside an `if (Flags.enableOnDeviceIntelligence())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE) to transfer requirement to caller`)"
+        errorLine1="        registerService(Context.ON_DEVICE_INTELLIGENCE_SERVICE, OnDeviceIntelligenceManager.class,"
+        errorLine2="                                                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1638"
+            column="65"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `ON_DEVICE_INTELLIGENCE_SERVICE` is a flagged API and should be inside an `if (Flags.enableOnDeviceIntelligence())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE) to transfer requirement to caller`)"
+        errorLine1="        registerService(Context.ON_DEVICE_INTELLIGENCE_SERVICE, OnDeviceIntelligenceManager.class,"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1638"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `ON_DEVICE_INTELLIGENCE_SERVICE` is a flagged API and should be inside an `if (Flags.enableOnDeviceIntelligence())` check (or annotate the surrounding method `createService` with `@FlaggedApi(Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE) to transfer requirement to caller`)"
+        errorLine1="                                Context.ON_DEVICE_INTELLIGENCE_SERVICE);"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1644"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `OnDeviceIntelligenceManager()` is a flagged API and should be inside an `if (Flags.enableOnDeviceIntelligence())` check (or annotate the surrounding method `createService` with `@FlaggedApi(Flags.FLAG_ENABLE_ON_DEVICE_INTELLIGENCE) to transfer requirement to caller`)"
+        errorLine1="                        return new OnDeviceIntelligenceManager(ctx.getOuterContext(), manager);"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1647"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `E2eeContactKeysManager` is a flagged API and should be inside an `if (Flags.userKeys())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_USER_KEYS) to transfer requirement to caller`)"
+        errorLine1="        registerService(Context.CONTACT_KEYS_SERVICE, E2eeContactKeysManager.class,"
+        errorLine2="                                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1670"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CONTACT_KEYS_SERVICE` is a flagged API and should be inside an `if (Flags.userKeys())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_USER_KEYS) to transfer requirement to caller`)"
+        errorLine1="        registerService(Context.CONTACT_KEYS_SERVICE, E2eeContactKeysManager.class,"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/SystemServiceRegistry.java"
+            line="1670"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `addView()` is a flagged API and should be inside an `if (Flags.enableArrowIconOnHoverWhenClickable())` check (or annotate the surrounding method `addTab` with `@FlaggedApi(Flags.FLAG_ENABLE_ARROW_ICON_ON_HOVER_WHEN_CLICKABLE) to transfer requirement to caller`)"
+        errorLine1="        mTabWidget.addView(tabIndicator);"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/widget/TabHost.java"
+            line="256"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="This is a flagged API and should be inside an `if (Flags.simultaneousCallingIndications())` check (or annotate the surrounding method `onSimultaneousCallingStateChanged` with `@FlaggedApi(Flags.FLAG_SIMULTANEOUS_CALLING_INDICATIONS) to transfer requirement to caller`)"
+        errorLine1="                    (SimultaneousCellularCallingSupportListener) mTelephonyCallbackWeakRef.get();"
+        errorLine2="                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/telephony/TelephonyCallback.java"
+            line="2065"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onSimultaneousCellularCallingSubscriptionsChanged()` is a flagged API and should be inside an `if (Flags.simultaneousCallingIndications())` check (or annotate the surrounding method `onSimultaneousCallingStateChanged` with `@FlaggedApi(Flags.FLAG_SIMULTANEOUS_CALLING_INDICATIONS) to transfer requirement to caller`)"
+        errorLine1="                            () -> listener.onSimultaneousCellularCallingSubscriptionsChanged("
+        errorLine2="                                  ^">
+        <location
+            file="frameworks/base/core/java/android/telephony/TelephonyCallback.java"
+            line="2070"
+            column="35"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `SatelliteManager` is a flagged API and should be inside an `if (Flags.oemEnabledSatelliteFlag())` check (or annotate the surrounding method `registerServiceWrappers` with `@FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="                SatelliteManager.class,"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/TelephonyFrameworkInitializer.java"
+            line="146"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `SatelliteManager()` is a flagged API and should be inside an `if (Flags.oemEnabledSatelliteFlag())` check (or annotate the surrounding method `registerServiceWrappers` with `@FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG) to transfer requirement to caller`)"
+        errorLine1="                        ? new SatelliteManager(context) : null"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/TelephonyFrameworkInitializer.java"
+            line="148"
+            column="27"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="This is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `listen` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="                (TelephonyRegistryManager)"
+        errorLine2="                 ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/TelephonyManager.java"
+            line="6726"
+            column="18"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `listenFromListener()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `listen` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="            telephonyRegistry.listenFromListener(mSubId, renounceFineLocationAccess,"
+        errorLine2="            ^">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/TelephonyManager.java"
+            line="6734"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="This is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `registerTelephonyCallback` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="        mTelephonyRegistryMgr = (TelephonyRegistryManager)"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/TelephonyManager.java"
+            line="17689"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `registerTelephonyCallback()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `registerTelephonyCallback` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="            mTelephonyRegistryMgr.registerTelephonyCallback("
+        errorLine2="            ^">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/TelephonyManager.java"
+            line="17692"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `TelephonyRegistryManager` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `unregisterTelephonyCallback` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="        mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class);"
+        errorLine2="                                                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/TelephonyManager.java"
+            line="17717"
+            column="59"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `unregisterTelephonyCallback()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `unregisterTelephonyCallback` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="            mTelephonyRegistryMgr.unregisterTelephonyCallback(mSubId, getOpPackageName(),"
+        errorLine2="            ^">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/TelephonyManager.java"
+            line="17719"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `TelephonyRegistryManager` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `registerCarrierPrivilegesCallback` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="        mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class);"
+        errorLine2="                                                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/TelephonyManager.java"
+            line="18688"
+            column="59"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `addCarrierPrivilegesCallback()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `registerCarrierPrivilegesCallback` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="        mTelephonyRegistryMgr.addCarrierPrivilegesCallback(logicalSlotIndex, executor, callback);"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/TelephonyManager.java"
+            line="18692"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Class `TelephonyRegistryManager` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `unregisterCarrierPrivilegesCallback` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="        mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class);"
+        errorLine2="                                                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/TelephonyManager.java"
+            line="18708"
+            column="59"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `removeCarrierPrivilegesCallback()` is a flagged API and should be inside an `if (Flags.telecomResolveHiddenDependencies())` check (or annotate the surrounding method `unregisterCarrierPrivilegesCallback` with `@FlaggedApi(Flags.FLAG_TELECOM_RESOLVE_HIDDEN_DEPENDENCIES) to transfer requirement to caller`)"
+        errorLine1="        mTelephonyRegistryMgr.removeCarrierPrivilegesCallback(callback);"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/telephony/java/android/telephony/TelephonyManager.java"
+            line="18712"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="This is a flagged API and should be inside an `if (Flags.simultaneousCallingIndications())` check (or annotate the surrounding method `getEventsFromCallback` with `@FlaggedApi(Flags.FLAG_SIMULTANEOUS_CALLING_INDICATIONS) to transfer requirement to caller`)"
+        errorLine1="                instanceof TelephonyCallback.SimultaneousCellularCallingSupportListener) {"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/telephony/TelephonyRegistryManager.java"
+            line="1241"
+            column="28"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `EVENT_SIMULTANEOUS_CELLULAR_CALLING_SUBSCRIPTIONS_CHANGED` is a flagged API and should be inside an `if (Flags.simultaneousCallingIndications())` check (or annotate the surrounding method `getEventsFromCallback` with `@FlaggedApi(Flags.FLAG_SIMULTANEOUS_CALLING_INDICATIONS) to transfer requirement to caller`)"
+        errorLine1="                    TelephonyCallback.EVENT_SIMULTANEOUS_CELLULAR_CALLING_SUBSCRIPTIONS_CHANGED);"
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/telephony/TelephonyRegistryManager.java"
+            line="1243"
+            column="39"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_LEFT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `calculateRunFlag` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="            return Paint.TEXT_RUN_FLAG_LEFT_EDGE | Paint.TEXT_RUN_FLAG_RIGHT_EDGE;"
+        errorLine2="                         ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="342"
+            column="26"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_RIGHT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `calculateRunFlag` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="            return Paint.TEXT_RUN_FLAG_LEFT_EDGE | Paint.TEXT_RUN_FLAG_RIGHT_EDGE;"
+        errorLine2="                                                         ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="342"
+            column="58"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_LEFT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `calculateRunFlag` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="                runFlag |= Paint.TEXT_RUN_FLAG_LEFT_EDGE;"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="359"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_RIGHT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `calculateRunFlag` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="                runFlag |= Paint.TEXT_RUN_FLAG_RIGHT_EDGE;"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="361"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_RIGHT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `calculateRunFlag` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="                runFlag |= Paint.TEXT_RUN_FLAG_RIGHT_EDGE;"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="366"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_LEFT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `calculateRunFlag` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="                runFlag |= Paint.TEXT_RUN_FLAG_LEFT_EDGE;"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="368"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_LEFT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `resolveRunFlagForSubSequence` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="        if ((runFlag &amp; Paint.TEXT_RUN_FLAG_LEFT_EDGE) != 0) {"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="394"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_LEFT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `resolveRunFlagForSubSequence` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="                    localRunFlag &amp;= ~Paint.TEXT_RUN_FLAG_LEFT_EDGE;"
+        errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="398"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_LEFT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `resolveRunFlagForSubSequence` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="                    localRunFlag &amp;= ~Paint.TEXT_RUN_FLAG_LEFT_EDGE;"
+        errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="403"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_RIGHT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `resolveRunFlagForSubSequence` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="        if ((runFlag &amp; Paint.TEXT_RUN_FLAG_RIGHT_EDGE) != 0) {"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="407"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_RIGHT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `resolveRunFlagForSubSequence` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="                    localRunFlag &amp;= ~Paint.TEXT_RUN_FLAG_RIGHT_EDGE;"
+        errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="411"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_RIGHT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `resolveRunFlagForSubSequence` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="                    localRunFlag &amp;= ~Paint.TEXT_RUN_FLAG_RIGHT_EDGE;"
+        errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="416"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_LEFT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `handleText` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="        if ((runFlag &amp; Paint.TEXT_RUN_FLAG_LEFT_EDGE) == Paint.TEXT_RUN_FLAG_LEFT_EDGE) {"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="1345"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_LEFT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `handleText` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="        if ((runFlag &amp; Paint.TEXT_RUN_FLAG_LEFT_EDGE) == Paint.TEXT_RUN_FLAG_LEFT_EDGE) {"
+        errorLine2="                                                               ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="1345"
+            column="64"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_LEFT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `handleText` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="            wp.setFlags(wp.getFlags() | Paint.TEXT_RUN_FLAG_LEFT_EDGE);"
+        errorLine2="                                              ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="1346"
+            column="47"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_LEFT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `handleText` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="            wp.setFlags(wp.getFlags() &amp; ~Paint.TEXT_RUN_FLAG_LEFT_EDGE);"
+        errorLine2="                                               ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="1348"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_RIGHT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `handleText` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="        if ((runFlag &amp; Paint.TEXT_RUN_FLAG_RIGHT_EDGE) == Paint.TEXT_RUN_FLAG_RIGHT_EDGE) {"
+        errorLine2="                             ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="1350"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_RIGHT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `handleText` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="        if ((runFlag &amp; Paint.TEXT_RUN_FLAG_RIGHT_EDGE) == Paint.TEXT_RUN_FLAG_RIGHT_EDGE) {"
+        errorLine2="                                                                ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="1350"
+            column="65"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_RIGHT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `handleText` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="            wp.setFlags(wp.getFlags() | Paint.TEXT_RUN_FLAG_RIGHT_EDGE);"
+        errorLine2="                                              ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="1351"
+            column="47"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TEXT_RUN_FLAG_RIGHT_EDGE` is a flagged API and should be inside an `if (Flags.letterSpacingJustification())` check (or annotate the surrounding method `handleText` with `@FlaggedApi(Flags.FLAG_LETTER_SPACING_JUSTIFICATION) to transfer requirement to caller`)"
+        errorLine1="            wp.setFlags(wp.getFlags() &amp; ~Paint.TEXT_RUN_FLAG_RIGHT_EDGE);"
+        errorLine2="                                               ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextLine.java"
+            line="1353"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CREATOR` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `createFromParcel` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="                    span = LineBreakConfigSpan.CREATOR.createFromParcel(p);"
+        errorLine2="                                               ~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/text/TextUtils.java"
+            line="1023"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getFontMetricsForLocale()` is a flagged API and should be inside an `if (Flags.fixLineHeightForLocale())` check (or annotate the surrounding method `getResolvedMinimumFontMetrics` with `@FlaggedApi(Flags.FLAG_FIX_LINE_HEIGHT_FOR_LOCALE) to transfer requirement to caller`)"
+        errorLine1="        mTextPaint.getFontMetricsForLocale(mLocalePreferredFontMetrics);"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/widget/TextView.java"
+            line="10860"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setMinimumFontMetrics()` is a flagged API and should be inside an `if (Flags.fixLineHeightForLocale())` check (or annotate the surrounding method `makeNewLayout` with `@FlaggedApi(Flags.FLAG_FIX_LINE_HEIGHT_FOR_LOCALE) to transfer requirement to caller`)"
+        errorLine1="                StaticLayout.Builder builder = StaticLayout.Builder.obtain(mHint, 0,"
+        errorLine2="                                               ^">
+        <location
+            file="frameworks/base/core/java/android/widget/TextView.java"
+            line="10965"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setUseBoundsForWidth()` is a flagged API and should be inside an `if (Flags.useBoundsForWidth())` check (or annotate the surrounding method `makeNewLayout` with `@FlaggedApi(Flags.FLAG_USE_BOUNDS_FOR_WIDTH) to transfer requirement to caller`)"
+        errorLine1="                StaticLayout.Builder builder = StaticLayout.Builder.obtain(mHint, 0,"
+        errorLine2="                                               ^">
+        <location
+            file="frameworks/base/core/java/android/widget/TextView.java"
+            line="10965"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setLineBreakConfig()` is a flagged API and should be inside an `if (Flags.noBreakNoHyphenationSpan())` check (or annotate the surrounding method `makeSingleLayout` with `@FlaggedApi(Flags.FLAG_NO_BREAK_NO_HYPHENATION_SPAN) to transfer requirement to caller`)"
+        errorLine1="            final DynamicLayout.Builder builder = DynamicLayout.Builder.obtain(mText, mTextPaint,"
+        errorLine2="                                                  ^">
+        <location
+            file="frameworks/base/core/java/android/widget/TextView.java"
+            line="11029"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setMinimumFontMetrics()` is a flagged API and should be inside an `if (Flags.fixLineHeightForLocale())` check (or annotate the surrounding method `makeSingleLayout` with `@FlaggedApi(Flags.FLAG_FIX_LINE_HEIGHT_FOR_LOCALE) to transfer requirement to caller`)"
+        errorLine1="            final DynamicLayout.Builder builder = DynamicLayout.Builder.obtain(mText, mTextPaint,"
+        errorLine2="                                                  ^">
+        <location
+            file="frameworks/base/core/java/android/widget/TextView.java"
+            line="11029"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setUseBoundsForWidth()` is a flagged API and should be inside an `if (Flags.useBoundsForWidth())` check (or annotate the surrounding method `makeSingleLayout` with `@FlaggedApi(Flags.FLAG_USE_BOUNDS_FOR_WIDTH) to transfer requirement to caller`)"
+        errorLine1="            final DynamicLayout.Builder builder = DynamicLayout.Builder.obtain(mText, mTextPaint,"
+        errorLine2="                                                  ^">
+        <location
+            file="frameworks/base/core/java/android/widget/TextView.java"
+            line="11029"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setMinimumFontMetrics()` is a flagged API and should be inside an `if (Flags.fixLineHeightForLocale())` check (or annotate the surrounding method `makeSingleLayout` with `@FlaggedApi(Flags.FLAG_FIX_LINE_HEIGHT_FOR_LOCALE) to transfer requirement to caller`)"
+        errorLine1="            StaticLayout.Builder builder = StaticLayout.Builder.obtain(mTransformed,"
+        errorLine2="                                           ^">
+        <location
+            file="frameworks/base/core/java/android/widget/TextView.java"
+            line="11115"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setUseBoundsForWidth()` is a flagged API and should be inside an `if (Flags.useBoundsForWidth())` check (or annotate the surrounding method `makeSingleLayout` with `@FlaggedApi(Flags.FLAG_USE_BOUNDS_FOR_WIDTH) to transfer requirement to caller`)"
+        errorLine1="            StaticLayout.Builder builder = StaticLayout.Builder.obtain(mTransformed,"
+        errorLine2="                                           ^">
+        <location
+            file="frameworks/base/core/java/android/widget/TextView.java"
+            line="11115"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `computeDrawingBoundingBox()` is a flagged API and should be inside an `if (Flags.useBoundsForWidth())` check (or annotate the surrounding method `desired` with `@FlaggedApi(Flags.FLAG_USE_BOUNDS_FOR_WIDTH) to transfer requirement to caller`)"
+        errorLine1="            max = Math.max(max, layout.computeDrawingBoundingBox().width());"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/widget/TextView.java"
+            line="11181"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getDrawingBoundingBox()` is a flagged API and should be inside an `if (Flags.useBoundsForWidth())` check (or annotate the surrounding method `onMeasure` with `@FlaggedApi(Flags.FLAG_USE_BOUNDS_FOR_WIDTH) to transfer requirement to caller`)"
+        errorLine1="                    RectF bbox = boring.getDrawingBoundingBox();"
+        errorLine2="                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/widget/TextView.java"
+            line="11275"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setMinimumFontMetrics()` is a flagged API and should be inside an `if (Flags.fixLineHeightForLocale())` check (or annotate the surrounding method `suggestedSizeFitsInSpace` with `@FlaggedApi(Flags.FLAG_FIX_LINE_HEIGHT_FOR_LOCALE) to transfer requirement to caller`)"
+        errorLine1="        layoutBuilder.setAlignment(getLayoutAlignment())"
+        errorLine2="        ^">
+        <location
+            file="frameworks/base/core/java/android/widget/TextView.java"
+            line="11502"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setUseBoundsForWidth()` is a flagged API and should be inside an `if (Flags.useBoundsForWidth())` check (or annotate the surrounding method `suggestedSizeFitsInSpace` with `@FlaggedApi(Flags.FLAG_USE_BOUNDS_FOR_WIDTH) to transfer requirement to caller`)"
+        errorLine1="        layoutBuilder.setAlignment(getLayoutAlignment())"
+        errorLine2="        ^">
+        <location
+            file="frameworks/base/core/java/android/widget/TextView.java"
+            line="11502"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CONFIG_FORCE_ANALOG_FM` is a flagged API and should be inside an `if (Flags.hdRadioImproved())` check (or annotate the surrounding method `convertForceAnalogConfigFlag` with `@FlaggedApi(Flags.FLAG_HD_RADIO_IMPROVED) to transfer requirement to caller`)"
+        errorLine1="                &amp;&amp; mTuner.isConfigFlagSupported(RadioManager.CONFIG_FORCE_ANALOG_FM)) {"
+        errorLine2="                                                             ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/radio/TunerAdapter.java"
+            line="427"
+            column="62"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `notifyTvInputSessionData()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `run` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="                        mSession.getAdSession().notifyTvInputSessionData(type, data);"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/TvInputManager.java"
+            line="1498"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onStopPlayback()` is a flagged API and should be inside an `if (Flags.tiafVApis())` check (or annotate the surrounding method `stopPlayback` with `@FlaggedApi(Flags.FLAG_TIAF_V_APIS) to transfer requirement to caller`)"
+        errorLine1="            onStopPlayback(mode);"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/TvInputService.java"
+            line="2113"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onResumePlayback()` is a flagged API and should be inside an `if (Flags.tiafVApis())` check (or annotate the surrounding method `resumePlayback` with `@FlaggedApi(Flags.FLAG_TIAF_V_APIS) to transfer requirement to caller`)"
+        errorLine1="            onResumePlayback();"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/TvInputService.java"
+            line="2120"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onTvAdSessionData()` is a flagged API and should be inside an `if (Flags.enableAdServiceFw())` check (or annotate the surrounding method `notifyTvAdSessionData` with `@FlaggedApi(Flags.FLAG_ENABLE_AD_SERVICE_FW) to transfer requirement to caller`)"
+        errorLine1="            onTvAdSessionData(type, data);"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/TvInputService.java"
+            line="2218"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onCertificate()` is a flagged API and should be inside an `if (Flags.tiafVApis())` check (or annotate the surrounding method `sendCertificate` with `@FlaggedApi(Flags.FLAG_TIAF_V_APIS) to transfer requirement to caller`)"
+        errorLine1="            onCertificate(host, port, cert);"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/interactive/TvInteractiveAppService.java"
+            line="1824"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onVideoFreezeUpdated()` is a flagged API and should be inside an `if (Flags.tiafVApis())` check (or annotate the surrounding method `notifyVideoFreezeUpdated` with `@FlaggedApi(Flags.FLAG_TIAF_V_APIS) to transfer requirement to caller`)"
+        errorLine1="            onVideoFreezeUpdated(isFrozen);"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/interactive/TvInteractiveAppService.java"
+            line="1889"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onSelectedTrackInfo()` is a flagged API and should be inside an `if (Flags.tiafVApis())` check (or annotate the surrounding method `sendSelectedTrackInfo` with `@FlaggedApi(Flags.FLAG_TIAF_V_APIS) to transfer requirement to caller`)"
+        errorLine1="            onSelectedTrackInfo(tracks);"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/interactive/TvInteractiveAppService.java"
+            line="1945"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onRequestSelectedTrackInfo()` is a flagged API and should be inside an `if (Flags.tiafVApis())` check (or annotate the surrounding method `onRequestSelectedTrackInfo` with `@FlaggedApi(Flags.FLAG_TIAF_V_APIS) to transfer requirement to caller`)"
+        errorLine1="                                mCallback.onRequestSelectedTrackInfo(mIAppServiceId);"
+        errorLine2="                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/interactive/TvInteractiveAppView.java"
+            line="1822"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onVideoFreezeUpdated()` is a flagged API and should be inside an `if (Flags.tiafVApis())` check (or annotate the surrounding method `onVideoFreezeUpdated` with `@FlaggedApi(Flags.FLAG_TIAF_V_APIS) to transfer requirement to caller`)"
+        errorLine1="                mCallback.onVideoFreezeUpdated(mInputId, isFrozen);"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/media/java/android/media/tv/TvView.java"
+            line="1779"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `convertSpToDp()` is a flagged API and should be inside an `if (Flags.fontScaleConverterPublic())` check (or annotate the surrounding method `applyDimension` with `@FlaggedApi(Flags.FLAG_FONT_SCALE_CONVERTER_PUBLIC) to transfer requirement to caller`)"
+        errorLine1="                            metrics.fontScaleConverter.convertSpToDp(value),"
+        errorLine2="                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/util/TypedValue.java"
+            line="433"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `convertDpToSp()` is a flagged API and should be inside an `if (Flags.fontScaleConverterPublic())` check (or annotate the surrounding method `deriveDimension` with `@FlaggedApi(Flags.FLAG_FONT_SCALE_CONVERTER_PUBLIC) to transfer requirement to caller`)"
+        errorLine1="                    return metrics.fontScaleConverter.convertDpToSp(dpValue);"
+        errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/util/TypedValue.java"
+            line="479"
+            column="28"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `PERSISTENT_DEVICE_ID_DEFAULT` is a flagged API and should be inside an `if (Flags.persistentDeviceIdApi())` check (or annotate the surrounding method `grantRuntimePermission` with `@FlaggedApi(Flags.FLAG_PERSISTENT_DEVICE_ID_API) to transfer requirement to caller`)"
+        errorLine1="                    VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, userId);"
+        errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/UiAutomationConnection.java"
+            line="367"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `PERSISTENT_DEVICE_ID_DEFAULT` is a flagged API and should be inside an `if (Flags.persistentDeviceIdApi())` check (or annotate the surrounding method `revokeRuntimePermission` with `@FlaggedApi(Flags.FLAG_PERSISTENT_DEVICE_ID_API) to transfer requirement to caller`)"
+        errorLine1="                    VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, userId, null);"
+        errorLine2="                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/app/UiAutomationConnection.java"
+            line="387"
+            column="42"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isResumed()` is a flagged API and should be inside an `if (Flags.enableNfcMainline())` check (or annotate the surrounding method `dump` with `@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) to transfer requirement to caller`)"
+        errorLine1="        pw.print(pfx); pw.print(&quot;resumed: &quot;); pw.println(mActivity.isResumed());"
+        errorLine2="                                                         ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/translation/UiTranslationController.java"
+            line="219"
+            column="58"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `COMPLIANCE_WARNING_INPUT_POWER_LIMITED` is a flagged API and should be inside an `if (Flags.enableUsbDataComplianceWarning())` check (or annotate the surrounding method `complianceWarningsToString` with `@FlaggedApi(Flags.FLAG_ENABLE_USB_DATA_COMPLIANCE_WARNING) to transfer requirement to caller`)"
+        errorLine1="                    case UsbPortStatus.COMPLIANCE_WARNING_INPUT_POWER_LIMITED:"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/usb/UsbPort.java"
+            line="813"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `COMPLIANCE_WARNING_MISSING_DATA_LINES` is a flagged API and should be inside an `if (Flags.enableUsbDataComplianceWarning())` check (or annotate the surrounding method `complianceWarningsToString` with `@FlaggedApi(Flags.FLAG_ENABLE_USB_DATA_COMPLIANCE_WARNING) to transfer requirement to caller`)"
+        errorLine1="                    case UsbPortStatus.COMPLIANCE_WARNING_MISSING_DATA_LINES:"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/usb/UsbPort.java"
+            line="816"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `COMPLIANCE_WARNING_ENUMERATION_FAIL` is a flagged API and should be inside an `if (Flags.enableUsbDataComplianceWarning())` check (or annotate the surrounding method `complianceWarningsToString` with `@FlaggedApi(Flags.FLAG_ENABLE_USB_DATA_COMPLIANCE_WARNING) to transfer requirement to caller`)"
+        errorLine1="                    case UsbPortStatus.COMPLIANCE_WARNING_ENUMERATION_FAIL:"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/usb/UsbPort.java"
+            line="819"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `COMPLIANCE_WARNING_FLAKY_CONNECTION` is a flagged API and should be inside an `if (Flags.enableUsbDataComplianceWarning())` check (or annotate the surrounding method `complianceWarningsToString` with `@FlaggedApi(Flags.FLAG_ENABLE_USB_DATA_COMPLIANCE_WARNING) to transfer requirement to caller`)"
+        errorLine1="                    case UsbPortStatus.COMPLIANCE_WARNING_FLAKY_CONNECTION:"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/usb/UsbPort.java"
+            line="822"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `COMPLIANCE_WARNING_UNRELIABLE_IO` is a flagged API and should be inside an `if (Flags.enableUsbDataComplianceWarning())` check (or annotate the surrounding method `complianceWarningsToString` with `@FlaggedApi(Flags.FLAG_ENABLE_USB_DATA_COMPLIANCE_WARNING) to transfer requirement to caller`)"
+        errorLine1="                    case UsbPortStatus.COMPLIANCE_WARNING_UNRELIABLE_IO:"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/hardware/usb/UsbPort.java"
+            line="825"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `USER_TYPE_PROFILE_MANAGED` is a flagged API and should be inside an `if (Flags.allowPrivateProfile())` check (or annotate the surrounding method `getDefaultUserType` with `@FlaggedApi(Flags.FLAG_ALLOW_PRIVATE_PROFILE) to transfer requirement to caller`)"
+        errorLine1="            case FLAG_MANAGED_PROFILE: return UserManager.USER_TYPE_PROFILE_MANAGED;"
+        errorLine2="                                                          ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/content/pm/UserInfo.java"
+            line="350"
+            column="59"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `USER_TYPE_PROFILE_MANAGED` is a flagged API and should be inside an `if (Flags.allowPrivateProfile())` check (or annotate the surrounding method `isUserTypeManagedProfile` with `@FlaggedApi(Flags.FLAG_ALLOW_PRIVATE_PROFILE) to transfer requirement to caller`)"
+        errorLine1="        return USER_TYPE_PROFILE_MANAGED.equals(userType);"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/UserManager.java"
+            line="3063"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `USER_TYPE_PROFILE_CLONE` is a flagged API and should be inside an `if (Flags.allowPrivateProfile())` check (or annotate the surrounding method `isUserTypeCloneProfile` with `@FlaggedApi(Flags.FLAG_ALLOW_PRIVATE_PROFILE) to transfer requirement to caller`)"
+        errorLine1="        return USER_TYPE_PROFILE_CLONE.equals(userType);"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/UserManager.java"
+            line="3100"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `USER_TYPE_PROFILE_PRIVATE` is a flagged API and should be inside an `if (Flags.allowPrivateProfile())` check (or annotate the surrounding method `isUserTypePrivateProfile` with `@FlaggedApi(Flags.FLAG_ALLOW_PRIVATE_PROFILE) to transfer requirement to caller`)"
+        errorLine1="        return USER_TYPE_PROFILE_PRIVATE.equals(userType);"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/os/UserManager.java"
+            line="3121"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CONTENT_SENSITIVITY_AUTO` is a flagged API and should be inside an `if (Flags.sensitiveContentAppProtectionApi())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_SENSITIVE_CONTENT_APP_PROTECTION_API) to transfer requirement to caller`)"
+        errorLine1="            (CONTENT_SENSITIVITY_AUTO | CONTENT_SENSITIVITY_SENSITIVE"
+        errorLine2="             ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="3929"
+            column="14"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CONTENT_SENSITIVITY_SENSITIVE` is a flagged API and should be inside an `if (Flags.sensitiveContentAppProtectionApi())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_SENSITIVE_CONTENT_APP_PROTECTION_API) to transfer requirement to caller`)"
+        errorLine1="            (CONTENT_SENSITIVITY_AUTO | CONTENT_SENSITIVITY_SENSITIVE"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="3929"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CONTENT_SENSITIVITY_NOT_SENSITIVE` is a flagged API and should be inside an `if (Flags.sensitiveContentAppProtectionApi())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_SENSITIVE_CONTENT_APP_PROTECTION_API) to transfer requirement to caller`)"
+        errorLine1="                    | CONTENT_SENSITIVITY_NOT_SENSITIVE) &lt;&lt; PFLAG4_CONTENT_SENSITIVITY_SHIFT;"
+        errorLine2="                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="3930"
+            column="23"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `REQUESTED_FRAME_RATE_CATEGORY_DEFAULT` is a flagged API and should be inside an `if (Flags.toolkitSetFrameRateReadOnly())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) to transfer requirement to caller`)"
+        errorLine1="    private float mPreferredFrameRate = REQUESTED_FRAME_RATE_CATEGORY_DEFAULT;"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="5784"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CONTENT_SENSITIVITY_AUTO` is a flagged API and should be inside an `if (Flags.sensitiveContentAppProtectionApi())` check (or annotate the surrounding method `View` with `@FlaggedApi(Flags.FLAG_SENSITIVE_CONTENT_APP_PROTECTION_API) to transfer requirement to caller`)"
+        errorLine1="                    setContentSensitivity(a.getInt(attr, CONTENT_SENSITIVITY_AUTO));"
+        errorLine2="                                                         ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="6528"
+            column="58"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setContentSensitivity()` is a flagged API and should be inside an `if (Flags.sensitiveContentAppProtectionApi())` check (or annotate the surrounding method `View` with `@FlaggedApi(Flags.FLAG_SENSITIVE_CONTENT_APP_PROTECTION_API) to transfer requirement to caller`)"
+        errorLine1="                    setContentSensitivity(a.getInt(attr, CONTENT_SENSITIVITY_AUTO));"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="6528"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setPendingCredentialRequest()` is a flagged API and should be inside an `if (Flags.autofillCredmanDevIntegration())` check (or annotate the surrounding method `onProvideStructure` with `@FlaggedApi(Flags.FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION) to transfer requirement to caller`)"
+        errorLine1="                structure.setPendingCredentialRequest("
+        errorLine2="                ^">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="9665"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getPendingCredentialCallback()` is a flagged API and should be inside an `if (Flags.autofillCredmanDevIntegration())` check (or annotate the surrounding method `onGetCredentialResponse` with `@FlaggedApi(Flags.FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION) to transfer requirement to caller`)"
+        errorLine1="        if (getPendingCredentialCallback() == null) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="10070"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getPendingCredentialCallback()` is a flagged API and should be inside an `if (Flags.autofillCredmanDevIntegration())` check (or annotate the surrounding method `onGetCredentialResponse` with `@FlaggedApi(Flags.FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION) to transfer requirement to caller`)"
+        errorLine1="        getPendingCredentialCallback().onResult(response);"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="10074"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getPendingCredentialCallback()` is a flagged API and should be inside an `if (Flags.autofillCredmanDevIntegration())` check (or annotate the surrounding method `onGetCredentialException` with `@FlaggedApi(Flags.FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION) to transfer requirement to caller`)"
+        errorLine1="        if (getPendingCredentialCallback() == null) {"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="10081"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getPendingCredentialCallback()` is a flagged API and should be inside an `if (Flags.autofillCredmanDevIntegration())` check (or annotate the surrounding method `onGetCredentialException` with `@FlaggedApi(Flags.FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION) to transfer requirement to caller`)"
+        errorLine1="        getPendingCredentialCallback().onError(new GetCredentialException(errorType, errorMsg));"
+        errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="10085"
+            column="9"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isContentSensitive()` is a flagged API and should be inside an `if (Flags.sensitiveContentAppProtectionApi())` check (or annotate the surrounding method `updateSensitiveViewsCountIfNeeded` with `@FlaggedApi(Flags.FLAG_SENSITIVE_CONTENT_APP_PROTECTION_API) to transfer requirement to caller`)"
+        errorLine1="        if (appeared &amp;&amp; isContentSensitive()) {"
+        errorLine2="                        ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="10597"
+            column="25"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setPendingCredentialRequest()` is a flagged API and should be inside an `if (Flags.autofillCredmanDevIntegration())` check (or annotate the surrounding method `populateVirtualStructure` with `@FlaggedApi(Flags.FLAG_AUTOFILL_CREDMAN_DEV_INTEGRATION) to transfer requirement to caller`)"
+        errorLine1="            structure.setPendingCredentialRequest("
+        errorLine2="            ^">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="11106"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `CONTENT_SENSITIVITY_AUTO` is a flagged API and should be inside an `if (Flags.sensitiveContentAppProtectionApi())` check (or annotate the surrounding method `setAutofillHints` with `@FlaggedApi(Flags.FLAG_SENSITIVE_CONTENT_APP_PROTECTION_API) to transfer requirement to caller`)"
+        errorLine1="            if (getContentSensitivity() == CONTENT_SENSITIVITY_AUTO) {"
+        errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="13689"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getContentSensitivity()` is a flagged API and should be inside an `if (Flags.sensitiveContentAppProtectionApi())` check (or annotate the surrounding method `setAutofillHints` with `@FlaggedApi(Flags.FLAG_SENSITIVE_CONTENT_APP_PROTECTION_API) to transfer requirement to caller`)"
+        errorLine1="            if (getContentSensitivity() == CONTENT_SENSITIVITY_AUTO) {"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="13689"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `DRAG_FLAG_GLOBAL_SAME_APPLICATION` is a flagged API and should be inside an `if (Flags.delegateUnhandledDrags())` check (or annotate the surrounding method `startDragAndDrop` with `@FlaggedApi(Flags.FLAG_DELEGATE_UNHANDLED_DRAGS) to transfer requirement to caller`)"
+        errorLine1="        if ((flags &amp; DRAG_FLAG_GLOBAL) != 0 &amp;&amp; ((flags &amp; DRAG_FLAG_GLOBAL_SAME_APPLICATION) != 0)) {"
+        errorLine2="                                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="29019"
+            column="58"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getIntentSender()` is a flagged API and should be inside an `if (Flags.delegateUnhandledDrags())` check (or annotate the surrounding method `hasActivityPendingIntents` with `@FlaggedApi(Flags.FLAG_DELEGATE_UNHANDLED_DRAGS) to transfer requirement to caller`)"
+        errorLine1="            if (item.getIntentSender() != null) {"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="29187"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getIntentSender()` is a flagged API and should be inside an `if (Flags.delegateUnhandledDrags())` check (or annotate the surrounding method `hasActivityPendingIntents` with `@FlaggedApi(Flags.FLAG_DELEGATE_UNHANDLED_DRAGS) to transfer requirement to caller`)"
+        errorLine1="                final PendingIntent pi = new PendingIntent(item.getIntentSender().getTarget());"
+        errorLine2="                                                           ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="29188"
+            column="60"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getIntentSender()` is a flagged API and should be inside an `if (Flags.delegateUnhandledDrags())` check (or annotate the surrounding method `cleanUpPendingIntents` with `@FlaggedApi(Flags.FLAG_DELEGATE_UNHANDLED_DRAGS) to transfer requirement to caller`)"
+        errorLine1="            if (item.getIntentSender() != null) {"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="29205"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getIntentSender()` is a flagged API and should be inside an `if (Flags.delegateUnhandledDrags())` check (or annotate the surrounding method `cleanUpPendingIntents` with `@FlaggedApi(Flags.FLAG_DELEGATE_UNHANDLED_DRAGS) to transfer requirement to caller`)"
+        errorLine1="                final PendingIntent pi = new PendingIntent(item.getIntentSender().getTarget());"
+        errorLine2="                                                           ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="29206"
+            column="60"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE` is a flagged API and should be inside an `if (Flags.toolkitSetFrameRateReadOnly())` check (or annotate the surrounding method `votePreferredFrameRate` with `@FlaggedApi(Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) to transfer requirement to caller`)"
+        errorLine1="                    case (int) REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE ->"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="33991"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `REQUESTED_FRAME_RATE_CATEGORY_LOW` is a flagged API and should be inside an `if (Flags.toolkitSetFrameRateReadOnly())` check (or annotate the surrounding method `votePreferredFrameRate` with `@FlaggedApi(Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) to transfer requirement to caller`)"
+        errorLine1="                    case (int) REQUESTED_FRAME_RATE_CATEGORY_LOW ->"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="33994"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `REQUESTED_FRAME_RATE_CATEGORY_NORMAL` is a flagged API and should be inside an `if (Flags.toolkitSetFrameRateReadOnly())` check (or annotate the surrounding method `votePreferredFrameRate` with `@FlaggedApi(Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) to transfer requirement to caller`)"
+        errorLine1="                    case (int) REQUESTED_FRAME_RATE_CATEGORY_NORMAL ->"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="33997"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `REQUESTED_FRAME_RATE_CATEGORY_HIGH` is a flagged API and should be inside an `if (Flags.toolkitSetFrameRateReadOnly())` check (or annotate the surrounding method `votePreferredFrameRate` with `@FlaggedApi(Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) to transfer requirement to caller`)"
+        errorLine1="                    case (int) REQUESTED_FRAME_RATE_CATEGORY_HIGH ->"
+        errorLine2="                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/View.java"
+            line="34000"
+            column="32"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getDesiredHdrHeadroom()` is a flagged API and should be inside an `if (Flags.limitedHdr())` check (or annotate the surrounding method `enableHardwareAcceleration` with `@FlaggedApi(Flags.FLAG_LIMITED_HDR) to transfer requirement to caller`)"
+        errorLine1="                updateColorModeIfNeeded(attrs.getColorMode(), attrs.getDesiredHdrHeadroom());"
+        errorLine2="                                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/ViewRootImpl.java"
+            line="2022"
+            column="63"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getDesiredHdrHeadroom()` is a flagged API and should be inside an `if (Flags.limitedHdr())` check (or annotate the surrounding method `performTraversals` with `@FlaggedApi(Flags.FLAG_LIMITED_HDR) to transfer requirement to caller`)"
+        errorLine1="                updateColorModeIfNeeded(lp.getColorMode(), lp.getDesiredHdrHeadroom());"
+        errorLine2="                                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/ViewRootImpl.java"
+            line="3748"
+            column="60"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getFrameTimeNanos()` is a flagged API and should be inside an `if (Flags.expectedPresentationTimeApi())` check (or annotate the surrounding method `draw` with `@FlaggedApi(Flags.FLAG_EXPECTED_PRESENTATION_TIME_API) to transfer requirement to caller`)"
+        errorLine1="                mChoreographer.getFrameTimeNanos() / TimeUtils.NANOS_PER_MS;"
+        errorLine2="                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/ViewRootImpl.java"
+            line="5597"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `uptimeNanos()` is a flagged API and should be inside an `if (Flags.adpfGpuReportActualWorkDuration())` check (or annotate the surrounding method `draw` with `@FlaggedApi(Flags.FLAG_ADPF_GPU_REPORT_ACTUAL_WORK_DURATION) to transfer requirement to caller`)"
+        errorLine1="                long timeNs = SystemClock.uptimeNanos();"
+        errorLine2="                              ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/ViewRootImpl.java"
+            line="5658"
+            column="31"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getFrameTimeNanos()` is a flagged API and should be inside an `if (Flags.expectedPresentationTimeApi())` check (or annotate the surrounding method `run` with `@FlaggedApi(Flags.FLAG_EXPECTED_PRESENTATION_TIME_API) to transfer requirement to caller`)"
+        errorLine1="                if (doConsumeBatchedInput(mChoreographer.getFrameTimeNanos())) {"
+        errorLine2="                                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/ViewRootImpl.java"
+            line="10449"
+            column="43"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `InputTransferToken()` is a flagged API and should be inside an `if (Flags.surfaceControlInputReceiver())` check (or annotate the surrounding method `getInputTransferToken` with `@FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) to transfer requirement to caller`)"
+        errorLine1="        return new InputTransferToken(inputToken);"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/ViewRootImpl.java"
+            line="11736"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getFrameRateBoostOnTouchEnabled()` is a flagged API and should be inside an `if (Flags.toolkitSetFrameRateReadOnly())` check (or annotate the surrounding method `getFrameRateBoostOnTouchEnabled` with `@FlaggedApi(Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) to transfer requirement to caller`)"
+        errorLine1="        return mWindowAttributes.getFrameRateBoostOnTouchEnabled();"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/ViewRootImpl.java"
+            line="13161"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `isFrameRatePowerSavingsBalanced()` is a flagged API and should be inside an `if (Flags.toolkitSetFrameRateReadOnly())` check (or annotate the surrounding method `isFrameRatePowerSavingsBalanced` with `@FlaggedApi(Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY) to transfer requirement to caller`)"
+        errorLine1="            return mWindowAttributes.isFrameRatePowerSavingsBalanced();"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/ViewRootImpl.java"
+            line="13193"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `POLICY_TYPE_CAMERA` is a flagged API and should be inside an `if (Flags.virtualCamera())` check (or annotate the surrounding method `hasCustomCameraSupport` with `@FlaggedApi(Flags.FLAG_VIRTUAL_CAMERA) to transfer requirement to caller`)"
+        errorLine1="            return mVirtualDevice.getDevicePolicy(POLICY_TYPE_CAMERA) == DEVICE_POLICY_CUSTOM;"
+        errorLine2="                                                  ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/companion/virtual/VirtualDevice.java"
+            line="200"
+            column="51"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `VirtualStylus()` is a flagged API and should be inside an `if (Flags.virtualStylus())` check (or annotate the surrounding method `createVirtualStylus` with `@FlaggedApi(Flags.FLAG_VIRTUAL_STYLUS) to transfer requirement to caller`)"
+        errorLine1="            return new VirtualStylus(config, mVirtualDevice, token);"
+        errorLine2="                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/companion/virtual/VirtualDeviceInternal.java"
+            line="332"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `VirtualCamera()` is a flagged API and should be inside an `if (Flags.virtualCamera())` check (or annotate the surrounding method `createVirtualCamera` with `@FlaggedApi(Flags.FLAG_VIRTUAL_CAMERA) to transfer requirement to caller`)"
+        errorLine1="            return new VirtualCamera(mVirtualDevice, mVirtualDevice.getVirtualCameraId(config),"
+        errorLine2="                   ^">
+        <location
+            file="frameworks/base/core/java/android/companion/virtual/VirtualDeviceInternal.java"
+            line="381"
+            column="20"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onVirtualDeviceCreated()` is a flagged API and should be inside an `if (Flags.vdmPublicApis())` check (or annotate the surrounding method `onVirtualDeviceCreated` with `@FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) to transfer requirement to caller`)"
+        errorLine1="                mExecutor.execute(() -> mListener.onVirtualDeviceCreated(deviceId));"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/companion/virtual/VirtualDeviceManager.java"
+            line="1225"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onVirtualDeviceClosed()` is a flagged API and should be inside an `if (Flags.vdmPublicApis())` check (or annotate the surrounding method `onVirtualDeviceClosed` with `@FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) to transfer requirement to caller`)"
+        errorLine1="                mExecutor.execute(() -> mListener.onVirtualDeviceClosed(deviceId));"
+        errorLine2="                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/companion/virtual/VirtualDeviceManager.java"
+            line="1235"
+            column="41"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `POLICY_TYPE_CLIPBOARD` is a flagged API and should be inside an `if (Flags.crossDeviceClipboard())` check (or annotate the surrounding method `build` with `@FlaggedApi(Flags.FLAG_CROSS_DEVICE_CLIPBOARD) to transfer requirement to caller`)"
+        errorLine1="                mDevicePolicies.delete(POLICY_TYPE_CLIPBOARD);"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/companion/virtual/VirtualDeviceParams.java"
+            line="1170"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `POLICY_TYPE_CAMERA` is a flagged API and should be inside an `if (Flags.virtualCamera())` check (or annotate the surrounding method `build` with `@FlaggedApi(Flags.FLAG_VIRTUAL_CAMERA) to transfer requirement to caller`)"
+        errorLine1="                mDevicePolicies.delete(POLICY_TYPE_CAMERA);"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/companion/virtual/VirtualDeviceParams.java"
+            line="1174"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onSecureConnectionProvided()` is a flagged API and should be inside an `if (Flags.enableProvideWearableConnectionApi())` check (or annotate the surrounding method `provideSecureConnection` with `@FlaggedApi(Flags.FLAG_ENABLE_PROVIDE_WEARABLE_CONNECTION_API) to transfer requirement to caller`)"
+        errorLine1="                    WearableSensingService.this.onSecureConnectionProvided("
+        errorLine2="                    ^">
+        <location
+            file="frameworks/base/core/java/android/service/wearable/WearableSensingService.java"
+            line="142"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onDataRequestObserverRegistered()` is a flagged API and should be inside an `if (Flags.enableDataRequestObserverApi())` check (or annotate the surrounding method `registerDataRequestObserver` with `@FlaggedApi(Flags.FLAG_ENABLE_DATA_REQUEST_OBSERVER_API) to transfer requirement to caller`)"
+        errorLine1="                    WearableSensingService.this.onDataRequestObserverRegistered("
+        errorLine2="                    ^">
+        <location
+            file="frameworks/base/core/java/android/service/wearable/WearableSensingService.java"
+            line="193"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onDataRequestObserverUnregistered()` is a flagged API and should be inside an `if (Flags.enableDataRequestObserverApi())` check (or annotate the surrounding method `unregisterDataRequestObserver` with `@FlaggedApi(Flags.FLAG_ENABLE_DATA_REQUEST_OBSERVER_API) to transfer requirement to caller`)"
+        errorLine1="                    WearableSensingService.this.onDataRequestObserverUnregistered("
+        errorLine2="                    ^">
+        <location
+            file="frameworks/base/core/java/android/service/wearable/WearableSensingService.java"
+            line="217"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onStartHotwordRecognition()` is a flagged API and should be inside an `if (Flags.enableHotwordWearableSensingApi())` check (or annotate the surrounding method `startHotwordRecognition` with `@FlaggedApi(Flags.FLAG_ENABLE_HOTWORD_WEARABLE_SENSING_API) to transfer requirement to caller`)"
+        errorLine1="                    WearableSensingService.this.onStartHotwordRecognition("
+        errorLine2="                    ^">
+        <location
+            file="frameworks/base/core/java/android/service/wearable/WearableSensingService.java"
+            line="237"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onStopHotwordRecognition()` is a flagged API and should be inside an `if (Flags.enableHotwordWearableSensingApi())` check (or annotate the surrounding method `stopHotwordRecognition` with `@FlaggedApi(Flags.FLAG_ENABLE_HOTWORD_WEARABLE_SENSING_API) to transfer requirement to caller`)"
+        errorLine1="                    WearableSensingService.this.onStopHotwordRecognition(statusConsumer);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/wearable/WearableSensingService.java"
+            line="250"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onValidatedByHotwordDetectionService()` is a flagged API and should be inside an `if (Flags.enableHotwordWearableSensingApi())` check (or annotate the surrounding method `onValidatedByHotwordDetectionService` with `@FlaggedApi(Flags.FLAG_ENABLE_HOTWORD_WEARABLE_SENSING_API) to transfer requirement to caller`)"
+        errorLine1="                    WearableSensingService.this.onValidatedByHotwordDetectionService();"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/wearable/WearableSensingService.java"
+            line="256"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onStopHotwordAudioStream()` is a flagged API and should be inside an `if (Flags.enableHotwordWearableSensingApi())` check (or annotate the surrounding method `stopActiveHotwordAudio` with `@FlaggedApi(Flags.FLAG_ENABLE_HOTWORD_WEARABLE_SENSING_API) to transfer requirement to caller`)"
+        errorLine1="                    WearableSensingService.this.onStopHotwordAudioStream();"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/wearable/WearableSensingService.java"
+            line="262"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `STATUS_UNSUPPORTED_OPERATION` is a flagged API and should be inside an `if (Flags.enableUnsupportedOperationStatusCode())` check (or annotate the surrounding method `onSecureConnectionProvided` with `@FlaggedApi(Flags.FLAG_ENABLE_UNSUPPORTED_OPERATION_STATUS_CODE) to transfer requirement to caller`)"
+        errorLine1="        statusConsumer.accept(WearableSensingManager.STATUS_UNSUPPORTED_OPERATION);"
+        errorLine2="                                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/wearable/WearableSensingService.java"
+            line="361"
+            column="54"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `STATUS_UNSUPPORTED_OPERATION` is a flagged API and should be inside an `if (Flags.enableUnsupportedOperationStatusCode())` check (or annotate the surrounding method `onDataRequestObserverRegistered` with `@FlaggedApi(Flags.FLAG_ENABLE_UNSUPPORTED_OPERATION_STATUS_CODE) to transfer requirement to caller`)"
+        errorLine1="        statusConsumer.accept(WearableSensingManager.STATUS_UNSUPPORTED_OPERATION);"
+        errorLine2="                                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/wearable/WearableSensingService.java"
+            line="429"
+            column="54"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `STATUS_UNSUPPORTED_OPERATION` is a flagged API and should be inside an `if (Flags.enableUnsupportedOperationStatusCode())` check (or annotate the surrounding method `onDataRequestObserverUnregistered` with `@FlaggedApi(Flags.FLAG_ENABLE_UNSUPPORTED_OPERATION_STATUS_CODE) to transfer requirement to caller`)"
+        errorLine1="        statusConsumer.accept(WearableSensingManager.STATUS_UNSUPPORTED_OPERATION);"
+        errorLine2="                                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/wearable/WearableSensingService.java"
+            line="457"
+            column="54"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `REQUEST_BUNDLE_KEY` is a flagged API and should be inside an `if (Flags.enableDataRequestObserverApi())` check (or annotate the surrounding method `createDataRequester` with `@FlaggedApi(Flags.FLAG_ENABLE_DATA_REQUEST_OBSERVER_API) to transfer requirement to caller`)"
+        errorLine1="            bundle.putParcelable(WearableSensingDataRequest.REQUEST_BUNDLE_KEY, request);"
+        errorLine2="                                                            ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/wearable/WearableSensingService.java"
+            line="673"
+            column="61"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `REQUEST_STATUS_CALLBACK_BUNDLE_KEY` is a flagged API and should be inside an `if (Flags.enableDataRequestObserverApi())` check (or annotate the surrounding method `createDataRequester` with `@FlaggedApi(Flags.FLAG_ENABLE_DATA_REQUEST_OBSERVER_API) to transfer requirement to caller`)"
+        errorLine1="                    WearableSensingDataRequest.REQUEST_STATUS_CALLBACK_BUNDLE_KEY,"
+        errorLine2="                                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/wearable/WearableSensingService.java"
+            line="682"
+            column="48"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `status` is a flagged API and should be inside an `if (Flags.updateServiceIpcWrapper())` check (or annotate the surrounding method `loadWebViewNativeLibraryFromPackage` with `@FlaggedApi(Flags.FLAG_UPDATE_SERVICE_IPC_WRAPPER) to transfer requirement to caller`)"
+        errorLine1="        if (response.status != LIBLOAD_SUCCESS"
+        errorLine2="                     ~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/webkit/WebViewFactory.java"
+            line="308"
+            column="22"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `status` is a flagged API and should be inside an `if (Flags.updateServiceIpcWrapper())` check (or annotate the surrounding method `loadWebViewNativeLibraryFromPackage` with `@FlaggedApi(Flags.FLAG_UPDATE_SERVICE_IPC_WRAPPER) to transfer requirement to caller`)"
+        errorLine1="                &amp;&amp; response.status != LIBLOAD_FAILED_WAITING_FOR_RELRO) {"
+        errorLine2="                            ~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/webkit/WebViewFactory.java"
+            line="309"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `status` is a flagged API and should be inside an `if (Flags.updateServiceIpcWrapper())` check (or annotate the surrounding method `loadWebViewNativeLibraryFromPackage` with `@FlaggedApi(Flags.FLAG_UPDATE_SERVICE_IPC_WRAPPER) to transfer requirement to caller`)"
+        errorLine1="            return response.status;"
+        errorLine2="                            ~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/webkit/WebViewFactory.java"
+            line="310"
+            column="29"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `packageInfo` is a flagged API and should be inside an `if (Flags.updateServiceIpcWrapper())` check (or annotate the surrounding method `loadWebViewNativeLibraryFromPackage` with `@FlaggedApi(Flags.FLAG_UPDATE_SERVICE_IPC_WRAPPER) to transfer requirement to caller`)"
+        errorLine1="        if (!response.packageInfo.packageName.equals(packageName)) {"
+        errorLine2="                      ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/webkit/WebViewFactory.java"
+            line="312"
+            column="23"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `status` is a flagged API and should be inside an `if (Flags.updateServiceIpcWrapper())` check (or annotate the surrounding method `loadWebViewNativeLibraryFromPackage` with `@FlaggedApi(Flags.FLAG_UPDATE_SERVICE_IPC_WRAPPER) to transfer requirement to caller`)"
+        errorLine1="        if (loadNativeRet == LIBLOAD_SUCCESS) return response.status;"
+        errorLine2="                                                              ~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/webkit/WebViewFactory.java"
+            line="330"
+            column="63"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `status` is a flagged API and should be inside an `if (Flags.updateServiceIpcWrapper())` check (or annotate the surrounding method `getWebViewContextAndSetProvider` with `@FlaggedApi(Flags.FLAG_UPDATE_SERVICE_IPC_WRAPPER) to transfer requirement to caller`)"
+        errorLine1="            if (response.status != LIBLOAD_SUCCESS"
+        errorLine2="                         ~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/webkit/WebViewFactory.java"
+            line="459"
+            column="26"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `status` is a flagged API and should be inside an `if (Flags.updateServiceIpcWrapper())` check (or annotate the surrounding method `getWebViewContextAndSetProvider` with `@FlaggedApi(Flags.FLAG_UPDATE_SERVICE_IPC_WRAPPER) to transfer requirement to caller`)"
+        errorLine1="                    &amp;&amp; response.status != LIBLOAD_FAILED_WAITING_FOR_RELRO) {"
+        errorLine2="                                ~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/webkit/WebViewFactory.java"
+            line="460"
+            column="33"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `status` is a flagged API and should be inside an `if (Flags.updateServiceIpcWrapper())` check (or annotate the surrounding method `getWebViewContextAndSetProvider` with `@FlaggedApi(Flags.FLAG_UPDATE_SERVICE_IPC_WRAPPER) to transfer requirement to caller`)"
+        errorLine1="                        + getWebViewPreparationErrorReason(response.status));"
+        errorLine2="                                                                    ~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/webkit/WebViewFactory.java"
+            line="462"
+            column="69"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `packageInfo` is a flagged API and should be inside an `if (Flags.updateServiceIpcWrapper())` check (or annotate the surrounding method `getWebViewContextAndSetProvider` with `@FlaggedApi(Flags.FLAG_UPDATE_SERVICE_IPC_WRAPPER) to transfer requirement to caller`)"
+        errorLine1="                        response.packageInfo.packageName);"
+        errorLine2="                                 ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/webkit/WebViewFactory.java"
+            line="469"
+            column="34"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `packageInfo` is a flagged API and should be inside an `if (Flags.updateServiceIpcWrapper())` check (or annotate the surrounding method `getWebViewContextAndSetProvider` with `@FlaggedApi(Flags.FLAG_UPDATE_SERVICE_IPC_WRAPPER) to transfer requirement to caller`)"
+        errorLine1="                    response.packageInfo.packageName,"
+        errorLine2="                             ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/webkit/WebViewFactory.java"
+            line="479"
+            column="30"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `packageInfo` is a flagged API and should be inside an `if (Flags.updateServiceIpcWrapper())` check (or annotate the surrounding method `getWebViewContextAndSetProvider` with `@FlaggedApi(Flags.FLAG_UPDATE_SERVICE_IPC_WRAPPER) to transfer requirement to caller`)"
+        errorLine1="            verifyPackageInfo(response.packageInfo, newPackageInfo);"
+        errorLine2="                                       ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/webkit/WebViewFactory.java"
+            line="510"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `InputTransferToken()` is a flagged API and should be inside an `if (Flags.surfaceControlInputReceiver())` check (or annotate the surrounding method `registerBatchedSurfaceControlInputReceiver` with `@FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) to transfer requirement to caller`)"
+        errorLine1="        InputTransferToken inputTransferToken = new InputTransferToken();"
+        errorLine2="                                                ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/WindowManagerGlobal.java"
+            line="874"
+            column="49"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onInputEvent()` is a flagged API and should be inside an `if (Flags.surfaceControlInputReceiver())` check (or annotate the surrounding method `onInputEvent` with `@FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) to transfer requirement to caller`)"
+        errorLine1="                                    boolean handled = receiver.onInputEvent(event);"
+        errorLine2="                                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/WindowManagerGlobal.java"
+            line="885"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `InputTransferToken()` is a flagged API and should be inside an `if (Flags.surfaceControlInputReceiver())` check (or annotate the surrounding method `registerUnbatchedSurfaceControlInputReceiver` with `@FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) to transfer requirement to caller`)"
+        errorLine1="        InputTransferToken inputTransferToken = new InputTransferToken();"
+        errorLine2="                                                ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/WindowManagerGlobal.java"
+            line="897"
+            column="49"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `onInputEvent()` is a flagged API and should be inside an `if (Flags.surfaceControlInputReceiver())` check (or annotate the surrounding method `onInputEvent` with `@FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) to transfer requirement to caller`)"
+        errorLine1="                                    boolean handled = receiver.onInputEvent(event);"
+        errorLine2="                                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/WindowManagerGlobal.java"
+            line="907"
+            column="55"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `SCREEN_RECORDING_STATE_NOT_VISIBLE` is a flagged API and should be inside an `if (Flags.screenRecordingCallbacks())` check (or annotate the surrounding method `addScreenRecordingCallback` with `@FlaggedApi(Flags.FLAG_SCREEN_RECORDING_CALLBACKS) to transfer requirement to caller`)"
+        errorLine1="        return SCREEN_RECORDING_STATE_NOT_VISIBLE;"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/WindowManagerImpl.java"
+            line="594"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `InputTransferToken()` is a flagged API and should be inside an `if (Flags.surfaceControlInputReceiver())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) to transfer requirement to caller`)"
+        errorLine1="    private final InputTransferToken mInputTransferToken = new InputTransferToken();"
+        errorLine2="                                                           ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/WindowlessWindowManager.java"
+            line="94"
+            column="60"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `InputTransferToken()` is a flagged API and should be inside an `if (Flags.surfaceControlInputReceiver())` check (or annotate the surrounding method `addToDisplay` with `@FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER) to transfer requirement to caller`)"
+        errorLine1="                state.mInputTransferToken = new InputTransferToken();"
+        errorLine2="                                            ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/view/WindowlessWindowManager.java"
+            line="214"
+            column="45"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `compressToJpegR()` is a flagged API and should be inside an `if (Flags.yuvImageCompressToUltraHdr())` check (or annotate the surrounding method `compressToJpegR` with `@FlaggedApi(Flags.FLAG_YUV_IMAGE_COMPRESS_TO_ULTRA_HDR) to transfer requirement to caller`)"
+        errorLine1="        return compressToJpegR(sdr, quality, stream, emptyExif);"
+        errorLine2="               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/graphics/java/android/graphics/YuvImage.java"
+            line="276"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `allowPriorityChannels()` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `getDefaultZenPolicy` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        ZenPolicy policy = new ZenPolicy.Builder()"
+        errorLine2="                           ^">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenModeConfig.java"
+            line="379"
+            column="28"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TYPE_OTHER` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `ensureManualZenRule` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="            newRule.type = AutomaticZenRule.TYPE_OTHER;"
+        errorLine2="                                            ~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenModeConfig.java"
+            line="435"
+            column="45"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `zenDeviceEffects` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `writeRuleXml` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if (Flags.modesApi() &amp;&amp; rule.zenDeviceEffects != null) {"
+        errorLine2="                                     ~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenModeConfig.java"
+            line="1206"
+            column="38"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `policyState()` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `toNotificationPolicy` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="            state = Policy.policyState(areChannelsBypassingDnd,"
+        errorLine2="                    ^">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenModeConfig.java"
+            line="1842"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getPriorityChannelsAllowed()` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `toNotificationPolicy` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="                    manualRule.zenPolicy.getPriorityChannelsAllowed() != STATE_DISALLOW);"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenModeConfig.java"
+            line="1843"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `TYPE_UNKNOWN` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `?` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        public int type = AutomaticZenRule.TYPE_UNKNOWN;"
+        errorLine2="                                           ~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenModeConfig.java"
+            line="2482"
+            column="44"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getPriorityChannelsAllowed()` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `areAllPriorityOnlyRingerSoundsMuted` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="                    &amp;&amp; !(config.areChannelsBypassingDnd &amp;&amp; policy.getPriorityChannelsAllowed()"
+        errorLine2="                                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenModeConfig.java"
+            line="2835"
+            column="60"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `mAllowChannels` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `getAllowedChannels` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        return mAllowChannels;"
+        errorLine2="               ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenPolicy.java"
+            line="576"
+            column="16"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `mAllowChannels` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `allowChannels` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="            mZenPolicy.mAllowChannels = channelType;"
+        errorLine2="                       ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenPolicy.java"
+            line="1019"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_MESSAGES` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_MESSAGES) != 0) {"
+        errorLine2="                       ~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenPolicy.java"
+            line="1095"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_CALLS` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_CALLS) != 0) {"
+        errorLine2="                       ~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenPolicy.java"
+            line="1098"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_CONVERSATIONS` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_CONVERSATIONS) != 0) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenPolicy.java"
+            line="1101"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_ALLOW_CHANNELS` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_ALLOW_CHANNELS) != 0) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenPolicy.java"
+            line="1104"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_PRIORITY_CATEGORY_REMINDERS` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_PRIORITY_CATEGORY_REMINDERS) != 0) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenPolicy.java"
+            line="1107"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_PRIORITY_CATEGORY_EVENTS` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_PRIORITY_CATEGORY_EVENTS) != 0) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenPolicy.java"
+            line="1110"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_PRIORITY_CATEGORY_REPEAT_CALLERS` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_PRIORITY_CATEGORY_REPEAT_CALLERS) != 0) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenPolicy.java"
+            line="1113"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_PRIORITY_CATEGORY_ALARMS` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_PRIORITY_CATEGORY_ALARMS) != 0) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenPolicy.java"
+            line="1116"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_PRIORITY_CATEGORY_MEDIA` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_PRIORITY_CATEGORY_MEDIA) != 0) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenPolicy.java"
+            line="1119"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_PRIORITY_CATEGORY_SYSTEM` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_PRIORITY_CATEGORY_SYSTEM) != 0) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenPolicy.java"
+            line="1122"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_VISUAL_EFFECT_FULL_SCREEN_INTENT` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_VISUAL_EFFECT_FULL_SCREEN_INTENT) != 0) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenPolicy.java"
+            line="1125"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_VISUAL_EFFECT_LIGHTS` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_VISUAL_EFFECT_LIGHTS) != 0) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenPolicy.java"
+            line="1128"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_VISUAL_EFFECT_PEEK` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_VISUAL_EFFECT_PEEK) != 0) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenPolicy.java"
+            line="1131"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_VISUAL_EFFECT_STATUS_BAR` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_VISUAL_EFFECT_STATUS_BAR) != 0) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenPolicy.java"
+            line="1134"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_VISUAL_EFFECT_BADGE` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_VISUAL_EFFECT_BADGE) != 0) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenPolicy.java"
+            line="1137"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_VISUAL_EFFECT_AMBIENT` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_VISUAL_EFFECT_AMBIENT) != 0) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenPolicy.java"
+            line="1140"
+            column="24"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FIELD_VISUAL_EFFECT_NOTIFICATION_LIST` is a flagged API and should be inside an `if (Flags.modesApi())` check (or annotate the surrounding method `fieldsToString` with `@FlaggedApi(Flags.FLAG_MODES_API) to transfer requirement to caller`)"
+        errorLine1="        if ((bitmask &amp; FIELD_VISUAL_EFFECT_NOTIFICATION_LIST) != 0) {"
+        errorLine2="                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/core/java/android/service/notification/ZenPolicy.java"
+            line="1143"
+            column="24"/>
+    </issue>
+
 </issues>
\ No newline at end of file
diff --git a/location/Android.bp b/location/Android.bp
index 7f3442c..c0e102a 100644
--- a/location/Android.bp
+++ b/location/Android.bp
@@ -40,6 +40,7 @@
         ],
     },
     lint: {
+        baseline_filename: "lint-baseline.xml",
         warning_checks: [
             "FlaggedApi",
         ],
diff --git a/location/java/android/location/flags/location.aconfig b/location/java/android/location/flags/location.aconfig
index 5f84862..acfe473 100644
--- a/location/java/android/location/flags/location.aconfig
+++ b/location/java/android/location/flags/location.aconfig
@@ -45,13 +45,6 @@
 }
 
 flag {
-    name: "gnss_call_stop_before_set_position_mode"
-    namespace: "location"
-    description: "Flag for calling stop() before setPositionMode()"
-    bug: "306874828"
-}
-
-flag {
     name: "gnss_api_measurement_request_work_source"
     namespace: "location"
     description: "Flag for GnssMeasurementRequest WorkSource API"
diff --git a/location/lint-baseline.xml b/location/lint-baseline.xml
new file mode 100644
index 0000000..a5a2e25
--- /dev/null
+++ b/location/lint-baseline.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="6" by="lint 8.4.0-alpha08" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha08">
+
+    <issue
+        id="FlaggedApi"
+        message="Method `Builder()` is a flagged API and should be inside an `if (Flags.newGeocoder())` check (or annotate the surrounding method `getFromLocation` with `@FlaggedApi(Flags.FLAG_NEW_GEOCODER) to transfer requirement to caller`)"
+        errorLine1="                new ReverseGeocodeRequest.Builder("
+        errorLine2="                ^">
+        <location
+            file="frameworks/base/location/java/android/location/Geocoder.java"
+            line="170"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setCallingAttributionTag()` is a flagged API and should be inside an `if (Flags.newGeocoder())` check (or annotate the surrounding method `getFromLocation` with `@FlaggedApi(Flags.FLAG_NEW_GEOCODER) to transfer requirement to caller`)"
+        errorLine1="            b.setCallingAttributionTag(mContext.getAttributionTag());"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/location/java/android/location/Geocoder.java"
+            line="178"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `build()` is a flagged API and should be inside an `if (Flags.newGeocoder())` check (or annotate the surrounding method `getFromLocation` with `@FlaggedApi(Flags.FLAG_NEW_GEOCODER) to transfer requirement to caller`)"
+        errorLine1="            mService.reverseGeocode(b.build(), new GeocodeCallbackImpl(listener));"
+        errorLine2="                                    ~~~~~~~~~">
+        <location
+            file="frameworks/base/location/java/android/location/Geocoder.java"
+            line="181"
+            column="37"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `Builder()` is a flagged API and should be inside an `if (Flags.newGeocoder())` check (or annotate the surrounding method `getFromLocationName` with `@FlaggedApi(Flags.FLAG_NEW_GEOCODER) to transfer requirement to caller`)"
+        errorLine1="                new ForwardGeocodeRequest.Builder("
+        errorLine2="                ^">
+        <location
+            file="frameworks/base/location/java/android/location/Geocoder.java"
+            line="322"
+            column="17"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `setCallingAttributionTag()` is a flagged API and should be inside an `if (Flags.newGeocoder())` check (or annotate the surrounding method `getFromLocationName` with `@FlaggedApi(Flags.FLAG_NEW_GEOCODER) to transfer requirement to caller`)"
+        errorLine1="            b.setCallingAttributionTag(mContext.getAttributionTag());"
+        errorLine2="            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/location/java/android/location/Geocoder.java"
+            line="333"
+            column="13"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `build()` is a flagged API and should be inside an `if (Flags.newGeocoder())` check (or annotate the surrounding method `getFromLocationName` with `@FlaggedApi(Flags.FLAG_NEW_GEOCODER) to transfer requirement to caller`)"
+        errorLine1="            mService.forwardGeocode(b.build(), new GeocodeCallbackImpl(listener));"
+        errorLine2="                                    ~~~~~~~~~">
+        <location
+            file="frameworks/base/location/java/android/location/Geocoder.java"
+            line="336"
+            column="37"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getWorkSource()` is a flagged API and should be inside an `if (Flags.gnssApiMeasurementRequestWorkSource())` check (or annotate the surrounding method `Builder` with `@FlaggedApi(Flags.FLAG_GNSS_API_MEASUREMENT_REQUEST_WORK_SOURCE) to transfer requirement to caller`)"
+        errorLine1="            mWorkSource = request.getWorkSource();"
+        errorLine2="                          ~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/location/java/android/location/GnssMeasurementRequest.java"
+            line="234"
+            column="27"/>
+    </issue>
+
+</issues>
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 386a606c..25c767a 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -4069,8 +4069,10 @@
     private boolean delegateSoundEffectToVdm(@SystemSoundEffect int effectType) {
         if (hasCustomPolicyVirtualDeviceContext()) {
             VirtualDeviceManager vdm = getVirtualDeviceManager();
-            vdm.playSoundEffect(mOriginalContextDeviceId, effectType);
-            return true;
+            if (vdm != null) {
+                vdm.playSoundEffect(mOriginalContextDeviceId, effectType);
+                return true;
+            }
         }
         return false;
     }
@@ -7005,6 +7007,23 @@
     }
 
     /**
+     * Check whether a user can mute this stream type from a given UI element.
+     *
+     * <p>Only useful for volume controllers.
+     *
+     * @param streamType type of stream to check if it's mutable from UI
+     *
+     * @hide
+     */
+    public boolean isStreamMutableByUi(int streamType) {
+        try {
+            return getService().isStreamMutableByUi(streamType);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Only useful for volume controllers.
      * @hide
      */
@@ -7416,6 +7435,21 @@
     }
 
     /**
+     * @hide
+     * Queries the volume policy
+     * @return the volume policy currently in use
+     */
+    @TestApi
+    @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
+    public @NonNull VolumePolicy getVolumePolicy() {
+        try {
+            return getService().getVolumePolicy();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Set Hdmi Cec system audio mode.
      *
      * @param on whether to be on system audio mode
diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java
index c263245..fd71f86 100644
--- a/media/java/android/media/AudioManagerInternal.java
+++ b/media/java/android/media/AudioManagerInternal.java
@@ -44,8 +44,9 @@
      * Add the UID for a new assistant service
      *
      * @param uid UID of the newly available assistants
+     * @param owningUid UID of the actual assistant app, if {@code uid} is a isolated proc
      */
-    public abstract void addAssistantServiceUid(int uid);
+    public abstract void addAssistantServiceUid(int uid, int owningUid);
 
     /**
      * Remove the UID for an existing assistant service
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index c8b9da5..d42b256 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -305,6 +305,8 @@
 
     boolean isStreamAffectedByMute(int streamType);
 
+    boolean isStreamMutableByUi(int streamType);
+
     void disableSafeMediaVolume(String callingPackage);
 
     oneway void lowerVolumeToRs1(String callingPackage);
@@ -384,6 +386,8 @@
 
     void setVolumePolicy(in VolumePolicy policy);
 
+    VolumePolicy getVolumePolicy();
+
     boolean hasRegisteredDynamicPolicy();
 
     void registerRecordingCallback(in IRecordingConfigDispatcher rcdb);
diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java
index 0589c0f12..e048d5c 100644
--- a/media/java/android/media/MediaRoute2Info.java
+++ b/media/java/android/media/MediaRoute2Info.java
@@ -26,6 +26,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
 import android.annotation.TestApi;
 import android.net.Uri;
 import android.os.Bundle;
@@ -813,6 +814,34 @@
                 || mAllowedPackages.contains(packageName);
     }
 
+    /**
+     * Returns whether this route's type can only be published by the system route provider.
+     *
+     * @see #isSystemRoute()
+     * @hide
+     */
+    // The default case catches all other types.
+    @SuppressLint("SwitchIntDef")
+    public boolean isSystemRouteType() {
+        return switch (mType) {
+            case TYPE_BUILTIN_SPEAKER,
+                            TYPE_BLUETOOTH_A2DP,
+                            TYPE_DOCK,
+                            TYPE_BLE_HEADSET,
+                            TYPE_HEARING_AID,
+                            TYPE_HDMI,
+                            TYPE_HDMI_ARC,
+                            TYPE_HDMI_EARC,
+                            TYPE_USB_ACCESSORY,
+                            TYPE_USB_DEVICE,
+                            TYPE_USB_HEADSET,
+                            TYPE_WIRED_HEADPHONES,
+                            TYPE_WIRED_HEADSET ->
+                    true;
+            default -> false;
+        };
+    }
+
     /** Returns the route suitability status. */
     @SuitabilityStatus
     @FlaggedApi(FLAG_ENABLE_BUILT_IN_SPEAKER_ROUTE_SUITABILITY_STATUSES)
diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java
index cce3d4f..a14f1fd 100644
--- a/media/java/android/media/MediaRoute2ProviderService.java
+++ b/media/java/android/media/MediaRoute2ProviderService.java
@@ -475,9 +475,25 @@
      */
     public final void notifyRoutes(@NonNull Collection<MediaRoute2Info> routes) {
         Objects.requireNonNull(routes, "routes must not be null");
-        mProviderInfo = new MediaRoute2ProviderInfo.Builder()
-                .addRoutes(routes)
-                .build();
+        List<MediaRoute2Info> sanitizedRoutes = new ArrayList<>(routes.size());
+
+        for (MediaRoute2Info route : routes) {
+            if (route.isSystemRouteType()) {
+                Log.w(
+                        TAG,
+                        "Attempting to add a system route type from a non-system route "
+                                + "provider. Overriding type to TYPE_UNKNOWN. Route: "
+                                + route);
+                sanitizedRoutes.add(
+                        new MediaRoute2Info.Builder(route)
+                                .setType(MediaRoute2Info.TYPE_UNKNOWN)
+                                .build());
+            } else {
+                sanitizedRoutes.add(route);
+            }
+        }
+
+        mProviderInfo = new MediaRoute2ProviderInfo.Builder().addRoutes(sanitizedRoutes).build();
         schedulePublishState();
     }
 
diff --git a/media/java/android/media/VolumePolicy.java b/media/java/android/media/VolumePolicy.java
index b193b70..96de72d 100644
--- a/media/java/android/media/VolumePolicy.java
+++ b/media/java/android/media/VolumePolicy.java
@@ -16,39 +16,53 @@
 
 package android.media;
 
+import android.annotation.NonNull;
+import android.annotation.SuppressLint;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
 import java.util.Objects;
 
 /** @hide */
+@TestApi
+@SuppressLint("UnflaggedApi") // @TestApi without associated feature.
 public final class VolumePolicy implements Parcelable {
+    @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
+    @NonNull
     public static final VolumePolicy DEFAULT = new VolumePolicy(false, false, false, 400);
 
     /**
      * Accessibility volume policy where the STREAM_MUSIC volume (i.e. media volume) affects
      * the STREAM_ACCESSIBILITY volume, and vice-versa.
      */
+    @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
     public static final int A11Y_MODE_MEDIA_A11Y_VOLUME = 0;
     /**
      * Accessibility volume policy where the STREAM_ACCESSIBILITY volume is independent from
      * any other volume.
      */
+    @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
     public static final int A11Y_MODE_INDEPENDENT_A11Y_VOLUME = 1;
 
     /** Allow volume adjustments lower from vibrate to enter ringer mode = silent */
+    @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
     public final boolean volumeDownToEnterSilent;
 
     /** Allow volume adjustments higher to exit ringer mode = silent */
+    @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
     public final boolean volumeUpToExitSilent;
 
     /** Automatically enter do not disturb when ringer mode = silent */
+    @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
     public final boolean doNotDisturbWhenSilent;
 
     /** Only allow volume adjustment from vibrate to silent after this
         number of milliseconds since an adjustment from normal to vibrate. */
+    @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
     public final int vibrateToSilentDebounce;
 
+    @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
     public VolumePolicy(boolean volumeDownToEnterSilent, boolean volumeUpToExitSilent,
             boolean doNotDisturbWhenSilent, int vibrateToSilentDebounce) {
         this.volumeDownToEnterSilent = volumeDownToEnterSilent;
@@ -82,19 +96,22 @@
                 && other.vibrateToSilentDebounce == vibrateToSilentDebounce;
     }
 
+    @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
     @Override
     public int describeContents() {
         return 0;
     }
 
+    @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
     @Override
-    public void writeToParcel(Parcel dest, int flags) {
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeInt(volumeDownToEnterSilent ? 1 : 0);
         dest.writeInt(volumeUpToExitSilent ? 1 : 0);
         dest.writeInt(doNotDisturbWhenSilent ? 1 : 0);
         dest.writeInt(vibrateToSilentDebounce);
     }
 
+    @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
     public static final @android.annotation.NonNull Parcelable.Creator<VolumePolicy> CREATOR
             = new Parcelable.Creator<VolumePolicy>() {
         @Override
diff --git a/media/tests/MediaFrameworkTest/Android.bp b/media/tests/MediaFrameworkTest/Android.bp
index 1325fc1..028c97e 100644
--- a/media/tests/MediaFrameworkTest/Android.bp
+++ b/media/tests/MediaFrameworkTest/Android.bp
@@ -24,6 +24,7 @@
         "flag-junit",
         "testng",
         "truth",
+        "collector-device-lib-platform",
     ],
     jni_libs: [
         "libdexmakerjvmtiagent",
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java
index 00068bd..43acbb1 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestUtils.java
@@ -16,6 +16,8 @@
 
 package com.android.mediaframeworktest.helpers;
 
+import android.content.AttributionSourceState;
+import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.ImageFormat;
@@ -2227,4 +2229,26 @@
         else
             return new Size(width, height);
     }
+
+    /**
+     * Constructs an AttributionSourceState with only the uid, pid, and deviceId fields set
+     *
+     * <p>This method is a temporary stopgap in the transition to using AttributionSource. Currently
+     * AttributionSourceState is only used as a vehicle for passing deviceId, uid, and pid
+     * arguments.</p>
+     */
+    public static AttributionSourceState getClientAttribution(Context context) {
+        // TODO: Send the full contextAttribution over aidl, remove USE_CALLING_*
+        AttributionSourceState contextAttribution =
+                context.getAttributionSource().asState();
+        AttributionSourceState clientAttribution =
+                new AttributionSourceState();
+        clientAttribution.uid = -1; // USE_CALLING_UID
+        clientAttribution.pid = -1; // USE_CALLING_PID
+        clientAttribution.deviceId = contextAttribution.deviceId;
+        clientAttribution.packageName = context.getOpPackageName();
+        clientAttribution.attributionTag = context.getAttributionTag();
+        clientAttribution.next = new AttributionSourceState[0];
+        return clientAttribution;
+    }
 }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
index 353366d..ac85ab7 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
@@ -19,6 +19,7 @@
 import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_DEFAULT;
 import static android.content.Context.DEVICE_ID_DEFAULT;
 
+import android.content.AttributionSourceState;
 import android.hardware.CameraInfo;
 import android.hardware.ICamera;
 import android.hardware.ICameraClient;
@@ -38,6 +39,8 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.mediaframeworktest.helpers.CameraTestUtils;
+
 /**
  * <p>
  * Junit / Instrumentation test case for the camera2 api
@@ -78,8 +81,10 @@
 
     @SmallTest
     public void testNumberOfCameras() throws Exception {
+        AttributionSourceState clientAttribution = CameraTestUtils.getClientAttribution(mContext);
+        clientAttribution.deviceId = DEVICE_ID_DEFAULT;
         int numCameras = mUtils.getCameraService().getNumberOfCameras(CAMERA_TYPE_ALL,
-                DEVICE_ID_DEFAULT, DEVICE_POLICY_DEFAULT);
+                clientAttribution, DEVICE_POLICY_DEFAULT);
         assertTrue("At least this many cameras: " + mUtils.getGuessedNumCameras(),
                 numCameras >= mUtils.getGuessedNumCameras());
         Log.v(TAG, "Number of cameras " + numCameras);
@@ -87,9 +92,11 @@
 
     @SmallTest
     public void testCameraInfo() throws Exception {
+        AttributionSourceState clientAttribution = CameraTestUtils.getClientAttribution(mContext);
+        clientAttribution.deviceId = DEVICE_ID_DEFAULT;
         for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
             CameraInfo info = mUtils.getCameraService().getCameraInfo(cameraId,
-                    ICameraService.ROTATION_OVERRIDE_NONE, DEVICE_ID_DEFAULT,
+                    ICameraService.ROTATION_OVERRIDE_NONE, clientAttribution,
                     DEVICE_POLICY_DEFAULT);
             assertTrue("Facing was not set for camera " + cameraId, info.info.facing != -1);
             assertTrue("Orientation was not set for camera " + cameraId,
@@ -154,20 +161,20 @@
 
     @SmallTest
     public void testConnect() throws Exception {
+        AttributionSourceState clientAttribution = CameraTestUtils.getClientAttribution(mContext);
+        clientAttribution.deviceId = DEVICE_ID_DEFAULT;
+        clientAttribution.uid = ICameraService.USE_CALLING_UID;
+        clientAttribution.pid = ICameraService.USE_CALLING_PID;
         for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
 
             ICameraClient dummyCallbacks = new DummyCameraClient();
 
-            String clientPackageName = getContext().getPackageName();
-
             ICamera cameraUser = mUtils.getCameraService()
-                    .connect(dummyCallbacks, cameraId, clientPackageName,
-                            ICameraService.USE_CALLING_UID,
-                            ICameraService.USE_CALLING_PID,
+                    .connect(dummyCallbacks, cameraId,
                             getContext().getApplicationInfo().targetSdkVersion,
                             ICameraService.ROTATION_OVERRIDE_NONE,
                             /*forceSlowJpegMode*/false,
-                            DEVICE_ID_DEFAULT, DEVICE_POLICY_DEFAULT);
+                            clientAttribution, DEVICE_POLICY_DEFAULT);
             assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
 
             Log.v(TAG, String.format("Camera %s connected", cameraId));
@@ -258,16 +265,17 @@
 
             ICameraDeviceCallbacks dummyCallbacks = new DummyCameraDeviceCallbacks();
 
-            String clientPackageName = getContext().getPackageName();
-            String clientAttributionTag = getContext().getAttributionTag();
+            AttributionSourceState clientAttribution =
+                    CameraTestUtils.getClientAttribution(mContext);
+            clientAttribution.deviceId = DEVICE_ID_DEFAULT;
+            clientAttribution.uid = ICameraService.USE_CALLING_UID;
 
             ICameraDeviceUser cameraUser =
                     mUtils.getCameraService().connectDevice(
                         dummyCallbacks, String.valueOf(cameraId),
-                        clientPackageName, clientAttributionTag,
-                        ICameraService.USE_CALLING_UID, 0 /*oomScoreOffset*/,
+                        0 /*oomScoreOffset*/,
                         getContext().getApplicationInfo().targetSdkVersion,
-                        ICameraService.ROTATION_OVERRIDE_NONE, DEVICE_ID_DEFAULT,
+                        ICameraService.ROTATION_OVERRIDE_NONE, clientAttribution,
                         DEVICE_POLICY_DEFAULT);
             assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
index 6cf2a41..35ad924 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
@@ -27,6 +27,7 @@
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 
+import android.content.AttributionSourceState;
 import android.graphics.ImageFormat;
 import android.graphics.SurfaceTexture;
 import android.hardware.ICameraService;
@@ -54,6 +55,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.mediaframeworktest.MediaFrameworkIntegrationTestRunner;
+import com.android.mediaframeworktest.helpers.CameraTestUtils;
 
 import org.mockito.ArgumentCaptor;
 import org.mockito.ArgumentMatcher;
@@ -240,15 +242,15 @@
 
         ICameraDeviceCallbacks.Stub dummyCallbacks = new DummyCameraDeviceCallbacks();
 
-        String clientPackageName = getContext().getPackageName();
-        String clientAttributionTag = getContext().getAttributionTag();
-
         mMockCb = spy(dummyCallbacks);
 
+        AttributionSourceState clientAttribution = CameraTestUtils.getClientAttribution(mContext);
+        clientAttribution.deviceId = DEVICE_ID_DEFAULT;
+        clientAttribution.uid = ICameraService.USE_CALLING_UID;
+
         mCameraUser = mUtils.getCameraService().connectDevice(mMockCb, mCameraId,
-                clientPackageName, clientAttributionTag, ICameraService.USE_CALLING_UID,
                 /*oomScoreOffset*/0, getContext().getApplicationInfo().targetSdkVersion,
-                ICameraService.ROTATION_OVERRIDE_NONE, DEVICE_ID_DEFAULT, DEVICE_POLICY_DEFAULT);
+                ICameraService.ROTATION_OVERRIDE_NONE, clientAttribution, DEVICE_POLICY_DEFAULT);
         assertNotNull(String.format("Camera %s was null", mCameraId), mCameraUser);
         mHandlerThread = new HandlerThread(TAG);
         mHandlerThread.start();
@@ -414,10 +416,13 @@
 
     @SmallTest
     public void testCameraCharacteristics() throws RemoteException {
+        AttributionSourceState clientAttribution = CameraTestUtils.getClientAttribution(mContext);
+        clientAttribution.deviceId = DEVICE_ID_DEFAULT;
+
         CameraMetadataNative info = mUtils.getCameraService().getCameraCharacteristics(mCameraId,
                 getContext().getApplicationInfo().targetSdkVersion,
                 ICameraService.ROTATION_OVERRIDE_NONE,
-                DEVICE_ID_DEFAULT, DEVICE_POLICY_DEFAULT);
+                clientAttribution, DEVICE_POLICY_DEFAULT);
 
         assertFalse(info.isEmpty());
         assertNotNull(info.get(CameraCharacteristics.SCALER_AVAILABLE_FORMATS));
diff --git a/native/android/Android.bp b/native/android/Android.bp
index 8945bd1..c4c4102 100644
--- a/native/android/Android.bp
+++ b/native/android/Android.bp
@@ -41,6 +41,7 @@
         "-Wextra",
         "-Wunused",
         "-Wunreachable-code",
+        "-Wthread-safety",
     ],
 }
 
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index 44fa677..e91c7a9 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -23,6 +23,7 @@
 #include <aidl/android/os/IHintManager.h>
 #include <aidl/android/os/IHintSession.h>
 #include <android-base/stringprintf.h>
+#include <android-base/thread_annotations.h>
 #include <android/binder_manager.h>
 #include <android/binder_status.h>
 #include <android/performance_hint.h>
@@ -111,26 +112,26 @@
     // HAL preferred update rate
     const int64_t mPreferredRateNanos;
     // Target duration for choosing update rate
-    int64_t mTargetDurationNanos;
+    int64_t mTargetDurationNanos GUARDED_BY(sHintMutex);
     // First target hit timestamp
-    int64_t mFirstTargetMetTimestamp;
+    int64_t mFirstTargetMetTimestamp GUARDED_BY(sHintMutex);
     // Last target hit timestamp
-    int64_t mLastTargetMetTimestamp;
+    int64_t mLastTargetMetTimestamp GUARDED_BY(sHintMutex);
     // Last hint reported from sendHint indexed by hint value
-    std::vector<int64_t> mLastHintSentTimestamp;
+    std::vector<int64_t> mLastHintSentTimestamp GUARDED_BY(sHintMutex);
     // Cached samples
-    std::vector<hal::WorkDuration> mActualWorkDurations;
-    std::string mSessionName;
-    static int64_t sIDCounter;
+    std::vector<hal::WorkDuration> mActualWorkDurations GUARDED_BY(sHintMutex);
+    std::string mSessionName GUARDED_BY(sHintMutex);
+    static int64_t sIDCounter GUARDED_BY(sHintMutex);
     // The most recent set of thread IDs
-    std::vector<int32_t> mLastThreadIDs;
-    std::optional<hal::SessionConfig> mSessionConfig;
+    std::vector<int32_t> mLastThreadIDs GUARDED_BY(sHintMutex);
+    std::optional<hal::SessionConfig> mSessionConfig GUARDED_BY(sHintMutex);
     // Tracing helpers
-    void traceThreads(std::vector<int32_t>& tids);
-    void tracePowerEfficient(bool powerEfficient);
-    void traceActualDuration(int64_t actualDuration);
-    void traceBatchSize(size_t batchSize);
-    void traceTargetDuration(int64_t targetDuration);
+    void traceThreads(std::vector<int32_t>& tids) REQUIRES(sHintMutex);
+    void tracePowerEfficient(bool powerEfficient) REQUIRES(sHintMutex);
+    void traceActualDuration(int64_t actualDuration) REQUIRES(sHintMutex);
+    void traceBatchSize(size_t batchSize) REQUIRES(sHintMutex);
+    void traceTargetDuration(int64_t targetDuration) REQUIRES(sHintMutex);
 };
 
 static std::shared_ptr<IHintManager>* gIHintManagerForTesting = nullptr;
@@ -243,6 +244,12 @@
         ALOGE("%s: targetDurationNanos must be positive", __FUNCTION__);
         return EINVAL;
     }
+    {
+        std::scoped_lock lock(sHintMutex);
+        if (mTargetDurationNanos == targetDurationNanos) {
+            return 0;
+        }
+    }
     ndk::ScopedAStatus ret = mHintSession->updateTargetWorkDuration(targetDurationNanos);
     if (!ret.isOk()) {
         ALOGE("%s: HintSession updateTargetWorkDuration failed: %s", __FUNCTION__,
diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
index 78a5357..d19fa98 100644
--- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
+++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
@@ -159,6 +159,10 @@
     int result = APerformanceHint_updateTargetWorkDuration(session, targetDurationNanos);
     EXPECT_EQ(0, result);
 
+    // subsequent call with same target should be ignored but return no error
+    result = APerformanceHint_updateTargetWorkDuration(session, targetDurationNanos);
+    EXPECT_EQ(0, result);
+
     usleep(2); // Sleep for longer than preferredUpdateRateNanos.
     int64_t actualDurationNanos = 20;
     std::vector<int64_t> actualDurations;
diff --git a/native/android/thermal.cpp b/native/android/thermal.cpp
index b43f2f16..f7a3537 100644
--- a/native/android/thermal.cpp
+++ b/native/android/thermal.cpp
@@ -99,21 +99,21 @@
       : mThermalSvc(std::move(service)), mServiceListener(nullptr) {}
 
 AThermalManager::~AThermalManager() {
-    std::unique_lock<std::mutex> listenerLock(mListenerMutex);
-
-    mListeners.clear();
-    if (mServiceListener != nullptr) {
-        bool success = false;
-        mThermalSvc->unregisterThermalStatusListener(mServiceListener, &success);
-        mServiceListener = nullptr;
+    {
+        std::scoped_lock<std::mutex> listenerLock(mListenerMutex);
+        mListeners.clear();
+        if (mServiceListener != nullptr) {
+            bool success = false;
+            mThermalSvc->unregisterThermalStatusListener(mServiceListener, &success);
+            mServiceListener = nullptr;
+        }
     }
-    listenerLock.unlock();
-    std::unique_lock<std::mutex> lock(mThresholdsMutex);
+    std::scoped_lock<std::mutex> lock(mThresholdsMutex);
     delete[] mThresholds;
 }
 
 status_t AThermalManager::notifyStateChange(int32_t status) {
-    std::unique_lock<std::mutex> lock(mListenerMutex);
+    std::scoped_lock<std::mutex> lock(mListenerMutex);
     AThermalStatus thermalStatus = static_cast<AThermalStatus>(status);
 
     for (auto listener : mListeners) {
@@ -123,7 +123,7 @@
 }
 
 status_t AThermalManager::addListener(AThermal_StatusCallback callback, void *data) {
-    std::unique_lock<std::mutex> lock(mListenerMutex);
+    std::scoped_lock<std::mutex> lock(mListenerMutex);
 
     if (callback == nullptr) {
         // Callback can not be nullptr
@@ -157,7 +157,7 @@
 }
 
 status_t AThermalManager::removeListener(AThermal_StatusCallback callback, void *data) {
-    std::unique_lock<std::mutex> lock(mListenerMutex);
+    std::scoped_lock<std::mutex> lock(mListenerMutex);
 
     auto it = std::remove_if(mListeners.begin(),
                              mListeners.end(),
@@ -216,7 +216,7 @@
 
 status_t AThermalManager::getThermalHeadroomThresholds(const AThermalHeadroomThreshold **result,
                                                        size_t *size) {
-    std::unique_lock<std::mutex> lock(mThresholdsMutex);
+    std::scoped_lock<std::mutex> lock(mThresholdsMutex);
     if (mThresholds == nullptr) {
         auto thresholds = std::make_unique<std::vector<float>>();
         binder::Status ret = mThermalSvc->getThermalHeadroomThresholds(thresholds.get());
diff --git a/nfc/java/android/nfc/INfcAdapter.aidl b/nfc/java/android/nfc/INfcAdapter.aidl
index fd77820..90ca92f 100644
--- a/nfc/java/android/nfc/INfcAdapter.aidl
+++ b/nfc/java/android/nfc/INfcAdapter.aidl
@@ -104,6 +104,7 @@
 
     void notifyPollingLoop(in PollingFrame frame);
     void notifyHceDeactivated();
+    void notifyTestHceData(in int technology, in byte[] data);
     int sendVendorNciMessage(int mt, int gid, int oid, in byte[] payload);
     void registerVendorExtensionCallback(in INfcVendorNciCallback callbacks);
     void unregisterVendorExtensionCallback(in INfcVendorNciCallback callbacks);
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
index 1dfc81e..9ce1c82 100644
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ b/nfc/java/android/nfc/NfcAdapter.java
@@ -2857,6 +2857,33 @@
     }
 
    /**
+     * Notifies the system of new HCE data for tests.
+     *
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP)
+    public void notifyTestHceData(int technology, byte[] data) {
+        try {
+            if (sService == null) {
+                attemptDeadServiceRecovery(null);
+            }
+            sService.notifyTestHceData(technology, data);
+        } catch (RemoteException e) {
+            attemptDeadServiceRecovery(e);
+            // Try one more time
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover NFC Service.");
+                return;
+            }
+            try {
+                sService.notifyTestHceData(technology, data);
+            } catch (RemoteException e2) {
+                Log.e(TAG, "Failed to recover NFC Service.");
+            }
+        }
+    }
+
+   /**
      * Notifies the system of a an HCE session being deactivated.
      *     *
      * @hide
diff --git a/nfc/java/android/nfc/flags.aconfig b/nfc/java/android/nfc/flags.aconfig
index b242a76..95945d7 100644
--- a/nfc/java/android/nfc/flags.aconfig
+++ b/nfc/java/android/nfc/flags.aconfig
@@ -110,3 +110,11 @@
     bug: "321311407"
 }
 
+flag {
+    name: "nfc_persist_log"
+    is_exported: true
+    namespace: "nfc"
+    description: "Enable NFC persistent log support"
+    bug: "321310044"
+}
+
diff --git a/nfc/lint-baseline.xml b/nfc/lint-baseline.xml
index d0f797e..dd7b03d 100644
--- a/nfc/lint-baseline.xml
+++ b/nfc/lint-baseline.xml
@@ -212,39 +212,61 @@
 
     <issue
         id="FlaggedApi"
-        message="Method `PollingFrame()` is a flagged API and should be inside an `if (Flags.nfcReadPollingLoop())` check (or annotate the surrounding method `handleMessage` with `@FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP) to transfer requirement to caller`)"
-        errorLine1="                        pollingFrames.add(new PollingFrame(frame));"
-        errorLine2="                                          ~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/nfc/java/android/nfc/cardemulation/HostApduService.java"
-            line="335"
-            column="43"/>
-    </issue>
-
-    <issue
-        id="FlaggedApi"
-        message="Method `processPollingFrames()` is a flagged API and should be inside an `if (Flags.nfcReadPollingLoop())` check (or annotate the surrounding method `handleMessage` with `@FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP) to transfer requirement to caller`)"
-        errorLine1="                    processPollingFrames(pollingFrames);"
-        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
-        <location
-            file="frameworks/base/nfc/java/android/nfc/cardemulation/HostApduService.java"
-            line="337"
-            column="21"/>
-    </issue>
-
-    <issue
-        id="FlaggedApi"
         message="Method `NfcOemExtension()` is a flagged API and should be inside an `if (Flags.nfcOemExtension())` check (or annotate the surrounding method `NfcAdapter` with `@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION) to transfer requirement to caller`)"
         errorLine1="        mNfcOemExtension = new NfcOemExtension(mContext, this);"
         errorLine2="                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
             file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
-            line="895"
+            line="909"
             column="28"/>
     </issue>
 
     <issue
         id="FlaggedApi"
+        message="Field `FLAG_SET_DEFAULT_TECH` is a flagged API and should be inside an `if (Flags.nfcSetDefaultDiscTech())` check (or annotate the surrounding method `setDiscoveryTechnology` with `@FlaggedApi(Flags.FLAG_NFC_SET_DEFAULT_DISC_TECH) to transfer requirement to caller`)"
+        errorLine1="                &amp;&amp; ((pollTechnology &amp; FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH"
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
+            line="1917"
+            column="39"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FLAG_SET_DEFAULT_TECH` is a flagged API and should be inside an `if (Flags.nfcSetDefaultDiscTech())` check (or annotate the surrounding method `setDiscoveryTechnology` with `@FlaggedApi(Flags.FLAG_NFC_SET_DEFAULT_DISC_TECH) to transfer requirement to caller`)"
+        errorLine1="                &amp;&amp; ((pollTechnology &amp; FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH"
+        errorLine2="                                                                ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
+            line="1917"
+            column="65"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FLAG_SET_DEFAULT_TECH` is a flagged API and should be inside an `if (Flags.nfcSetDefaultDiscTech())` check (or annotate the surrounding method `setDiscoveryTechnology` with `@FlaggedApi(Flags.FLAG_NFC_SET_DEFAULT_DISC_TECH) to transfer requirement to caller`)"
+        errorLine1="                || (listenTechnology &amp; FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH)) {"
+        errorLine2="                                       ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
+            line="1918"
+            column="40"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Field `FLAG_SET_DEFAULT_TECH` is a flagged API and should be inside an `if (Flags.nfcSetDefaultDiscTech())` check (or annotate the surrounding method `setDiscoveryTechnology` with `@FlaggedApi(Flags.FLAG_NFC_SET_DEFAULT_DISC_TECH) to transfer requirement to caller`)"
+        errorLine1="                || (listenTechnology &amp; FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH)) {"
+        errorLine2="                                                                 ~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/nfc/java/android/nfc/NfcAdapter.java"
+            line="1918"
+            column="66"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
         message="Method `onVendorNciResponse()` is a flagged API and should be inside an `if (Flags.nfcVendorCmd())` check (or annotate the surrounding method `onVendorResponseReceived` with `@FlaggedApi(Flags.FLAG_NFC_VENDOR_CMD) to transfer requirement to caller`)"
         errorLine1="                    executor.execute(() -> callback.onVendorNciResponse(gid, oid, payload));"
         errorLine2="                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
diff --git a/packages/CarrierDefaultApp/res/values-fa/strings.xml b/packages/CarrierDefaultApp/res/values-fa/strings.xml
index d9afe873..bfc2fec 100644
--- a/packages/CarrierDefaultApp/res/values-fa/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-fa/strings.xml
@@ -5,7 +5,7 @@
     <string name="android_system_label" msgid="2797790869522345065">"شرکت مخابراتی دستگاه همراه"</string>
     <string name="portal_notification_id" msgid="5155057562457079297">"داده تلفن همراه تمام شده است"</string>
     <string name="no_data_notification_id" msgid="668400731803969521">"داده شبکه تلفن همراه شما غیرفعال شده است"</string>
-    <string name="portal_notification_detail" msgid="2295729385924660881">"‏برای رفتن به وب‌سایت %s، ضربه بزنید"</string>
+    <string name="portal_notification_detail" msgid="2295729385924660881">"‏برای رفتن به وب‌سایت %s، تک‌ضرب بزنید"</string>
     <string name="no_data_notification_detail" msgid="3112125343857014825">"‏لطفاً با ارائه‌دهنده خدمات %s خود تماس بگیرید"</string>
     <string name="no_mobile_data_connection_title" msgid="7449525772416200578">"بدون اتصال داده دستگاه همراه"</string>
     <string name="no_mobile_data_connection" msgid="544980465184147010">"‏افزودن طرح داده یا فراگردی ازطریق %s"</string>
diff --git a/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml b/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml
index 54dae62..91da7dc 100644
--- a/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml
@@ -16,7 +16,7 @@
     <string name="ssl_error_continue" msgid="1138548463994095584">"Continuer quand même dans un navigateur"</string>
     <string name="performance_boost_notification_channel" msgid="3475440855635538592">"Optimiseur de performances"</string>
     <string name="performance_boost_notification_title" msgid="3126203390685781861">"Options 5G de votre fournisseur de services"</string>
-    <string name="performance_boost_notification_detail" msgid="216569851036236346">"Consultez le site Web de %s pour voir les options concernant votre expérience de l\'application"</string>
+    <string name="performance_boost_notification_detail" msgid="216569851036236346">"Consultez le site Web de %s pour voir les options concernant votre expérience de l\'appli"</string>
     <string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Plus tard"</string>
     <string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gérer"</string>
     <string name="slice_purchase_app_label" msgid="7170191659233241166">"Achetez un optimiseur de performances."</string>
diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml
index e3dd4cb..9106721 100644
--- a/packages/CompanionDeviceManager/res/values-ar/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml
@@ -20,7 +20,7 @@
     <string name="confirmation_title" msgid="2244241995958340998">"‏هل تريد السماح لـ &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_non_profile" msgid="6035023914517087400">"‏اختيار جهاز ليديره تطبيق &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="chooser_title" msgid="2235819929238267637">"اختيار \"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>\" لإعداده"</string>
+    <string name="chooser_title" msgid="2235819929238267637">"اختيار \"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>\" للإعداد"</string>
     <string name="summary_watch" msgid="7962014927042971830">"سيتم السماح لهذا التطبيق بمزامنة المعلومات، مثلاً اسم المتصل، والوصول إلى هذه الأذونات على \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"‏هل تريد السماح لتطبيق &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_glasses" msgid="3506504967216601277">"جهاز"</string>
diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
index 97abef7..5b58961 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -17,20 +17,20 @@
 <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">"Gestionnaire d\'appareil compagnon"</string>
-    <string name="confirmation_title" msgid="2244241995958340998">"Autoriser l\'application &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
+    <string name="confirmation_title" msgid="2244241995958340998">"Autoriser l\'appli &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à accéder à &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"montre"</string>
     <string name="chooser_title_non_profile" msgid="6035023914517087400">"Choisir un appareil qui sera géré par &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
     <string name="chooser_title" msgid="2235819929238267637">"Choisir un appareil (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) pour le configurer"</string>
-    <string name="summary_watch" msgid="7962014927042971830">"Cette application sera autorisée à synchroniser des informations, comme le nom de l\'appelant, et à accéder à ces autorisations sur votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="summary_watch" msgid="7962014927042971830">"Cette appli sera autorisée à synchroniser des informations, comme le nom de l\'appelant, et à accéder à ces autorisations sur votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à gérer &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="profile_name_glasses" msgid="3506504967216601277">"appareil"</string>
-    <string name="summary_glasses" msgid="2872254734959842579">"Cette application pourra accéder à ces autorisations sur votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</string>
+    <string name="summary_glasses" msgid="2872254734959842579">"Cette appli pourra accéder à ces autorisations sur votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>"</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="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à diffuser les applications de votre téléphone?"</string>
-    <string name="summary_app_streaming" msgid="295548145144086753">"%1$s aura accès à tout ce qui est visible ou lu sur le téléphone, y compris l\'audio, les photos, les mots de passe et les messages.&lt;br/&gt;&lt;br/&gt;%1$s pourra diffuser des applications jusqu\'à ce que vous retiriez l\'accès à cette autorisation."</string>
+    <string name="title_app_streaming_with_mirroring" msgid="3364582597581570658">"Autoriser &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; à diffuser les applis de votre téléphone?"</string>
+    <string name="summary_app_streaming" msgid="295548145144086753">"%1$s aura accès à tout ce qui est visible ou lu sur le téléphone, y compris l\'audio, les photos, les mots de passe et les messages.&lt;br/&gt;&lt;br/&gt;%1$s pourra diffuser des applis jusqu\'à ce que vous retiriez l\'accès à cette autorisation."</string>
     <string name="helper_title_app_streaming" msgid="4151687003439969765">"Services multiappareils"</string>
-    <string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> pour diffuser des applications entre vos appareils"</string>
-    <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation, au nom de votre <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>, d\'afficher et de diffuser des applications entre vos appareils"</string>
+    <string name="helper_summary_app_streaming" msgid="2396773196949578425">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> pour diffuser des applis entre vos appareils"</string>
+    <string name="helper_summary_app_streaming_with_mirroring" msgid="6138581029144467467">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation, au nom de votre <xliff:g id="DISPLAY_NAME">%2$s</xliff:g>, d\'afficher et de diffuser des applis 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>
@@ -38,18 +38,18 @@
     <string name="helper_title_computer" msgid="4671071173916176037">"Services Google Play"</string>
     <string name="helper_summary_computer" msgid="8774832742608187072">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DISPLAY_NAME">%2$s</xliff:g> pour accéder aux photos, aux fichiers multimédias et aux notifications de votre téléphone"</string>
     <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Autoriser &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; à effectuer cette action?"</string>
-    <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Autoriser &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; à diffuser les applications et les fonctionnalités du système de votre téléphone?"</string>
-    <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s aura accès à tout ce qui est visible ou lu sur le téléphone, y compris l\'audio, les photos, les renseignements de paiement, les mots de passe et les messages.&lt;br/&gt;&lt;br/&gt;%1$s pourra diffuser des applications jusqu\'à ce que vous retiriez l\'accès à cette autorisation."</string>
-    <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation, au nom de votre <xliff:g id="DEVICE_NAME">%2$s</xliff:g>, de diffuser des applications et d\'autres fonctionnalités du système sur des appareils à proximité"</string>
+    <string name="title_nearby_device_streaming_with_mirroring" msgid="242855799919611657">"Autoriser &lt;strong&gt;<xliff:g id="DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; à diffuser les applis et les fonctionnalités du système de votre téléphone?"</string>
+    <string name="summary_nearby_device_streaming" msgid="4039565463149145573">"%1$s aura accès à tout ce qui est visible ou lu sur le téléphone, y compris l\'audio, les photos, les renseignements de paiement, les mots de passe et les messages.&lt;br/&gt;&lt;br/&gt;%1$s pourra diffuser des applis jusqu\'à ce que vous retiriez l\'accès à cette autorisation."</string>
+    <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation, au nom de votre <xliff:g id="DEVICE_NAME">%2$s</xliff:g>, de diffuser des applis et d\'autres fonctionnalités du système sur des appareils à proximité"</string>
     <string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
-    <string name="summary_generic" msgid="1761976003668044801">"Cette application pourra synchroniser des informations, comme le nom de l\'appelant, entre votre téléphone et l\'appareil sélectionné"</string>
+    <string name="summary_generic" msgid="1761976003668044801">"Cette appli pourra synchroniser des informations, comme le nom de l\'appelant, entre votre téléphone et l\'appareil sélectionné"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ne pas autoriser"</string>
     <string name="consent_cancel" msgid="5655005528379285841">"Annuler"</string>
     <string name="consent_back" msgid="2560683030046918882">"Retour"</string>
     <string name="permission_expand" msgid="893185038020887411">"Développer <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
     <string name="permission_collapse" msgid="3320833884220844084">"Réduire <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
-    <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Accorder aux applications sur &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; les autorisations déjà accordées sur &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
+    <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"Accorder aux applis sur &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; les autorisations déjà accordées sur &lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="permission_sync_summary" msgid="765497944331294275">"Cela peut inclure l\'accès &lt;strong&gt;au microphone&lt;/strong&gt;, &lt;strong&gt;à l\'appareil photo&lt;/strong&gt;, et &lt;strong&gt;à la position&lt;/strong&gt;, ainsi que d\'autres autorisations sensibles sur &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>&lt;/strong&gt;. &lt;br/&gt;&lt;br/&gt;Vous pouvez modifier ces autorisations à tout moment dans vos paramètres sur &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>&lt;/strong&gt;."</string>
     <string name="vendor_header_button_description" msgid="7994879208461111473">"Plus de renseignements"</string>
     <string name="permission_phone" msgid="2661081078692784919">"Téléphone"</string>
@@ -62,7 +62,7 @@
     <string name="permission_media_routing_control" msgid="5498639511586715253">"Modifier la sortie multimédia"</string>
     <string name="permission_storage" msgid="6831099350839392343">"Photos et fichiers multimédias"</string>
     <string name="permission_notifications" msgid="4099418516590632909">"Notifications"</string>
-    <string name="permission_app_streaming" msgid="6009695219091526422">"Applications"</string>
+    <string name="permission_app_streaming" msgid="6009695219091526422">"Applis"</string>
     <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Diffusion en continu"</string>
     <string name="permission_phone_summary" msgid="8246321093970051702">"Passez et gérez des appels téléphoniques"</string>
     <string name="permission_call_logs_summary" msgid="7545243592757693321">"Lisez et écrivez le journal d\'appels téléphoniques"</string>
@@ -72,11 +72,11 @@
     <string name="permission_microphone_summary" msgid="4862628553869973259">"Enregistrez des fichiers audio"</string>
     <string name="permission_nearby_devices_summary" msgid="1306752848196464817">"Trouvez et déterminez la position relative des appareils à proximité, et connectez-vous à ceux-ci"</string>
     <string name="permission_notification_listener_access_summary" msgid="7856071768185367749">"Lisez toutes les notifications, y compris les renseignements tels que les contacts, les messages et les photos"</string>
-    <string name="permission_notifications_summary" msgid="2272810466047367030">"• Lisez toutes les notifications, y compris les renseignements tels que les contacts, les messages et les photos&lt;br/&gt;• Envoyez des notifications&lt;br/&gt;&lt;br/&gt;Vous pouvez gérer la capacité de cette application à lire et à envoyer des notifications à tout moment dans Paramètres > Notifications."</string>
-    <string name="permission_app_streaming_summary" msgid="606923325679670624">"Diffusez les applications de votre téléphone"</string>
+    <string name="permission_notifications_summary" msgid="2272810466047367030">"• Lisez toutes les notifications, y compris les renseignements tels que les contacts, les messages et les photos&lt;br/&gt;• Envoyez des notifications&lt;br/&gt;&lt;br/&gt;Vous pouvez gérer la capacité de cette appli à lire et à envoyer des notifications à tout moment dans Paramètres > Notifications."</string>
+    <string name="permission_app_streaming_summary" msgid="606923325679670624">"Diffusez les applis de votre téléphone"</string>
     <string name="permission_storage_summary" msgid="3918240895519506417"></string>
-    <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Diffusez des applications et d\'autres fonctionnalités du système à partir de votre téléphone"</string>
-    <string name="permission_media_routing_control_summary" msgid="2714631092321412250">"Accédez à une liste d\'appareils accessibles et contrôlez ceux qui diffusent du contenu audio ou vidéo à partir d\'autres applications"</string>
+    <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Diffusez des applis et d\'autres fonctionnalités du système à partir de votre téléphone"</string>
+    <string name="permission_media_routing_control_summary" msgid="2714631092321412250">"Accédez à une liste d\'appareils accessibles et contrôlez ceux qui diffusent du contenu audio ou vidéo à partir d\'autres applis"</string>
     <string name="device_type" product="default" msgid="8268703872070046263">"téléphone"</string>
     <string name="device_type" product="tablet" msgid="5038791954983067774">"tablette"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionAssociationActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionAssociationActivity.java
index f98908c..e005334 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionAssociationActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionAssociationActivity.java
@@ -16,10 +16,7 @@
 
 package com.android.companiondevicemanager;
 
-import static android.companion.CompanionDeviceManager.REASON_CANCELED;
-import static android.companion.CompanionDeviceManager.REASON_DISCOVERY_TIMEOUT;
-import static android.companion.CompanionDeviceManager.REASON_INTERNAL_ERROR;
-import static android.companion.CompanionDeviceManager.REASON_USER_REJECTED;
+import static android.companion.CompanionDeviceManager.RESULT_CANCELED;
 import static android.companion.CompanionDeviceManager.RESULT_DISCOVERY_TIMEOUT;
 import static android.companion.CompanionDeviceManager.RESULT_INTERNAL_ERROR;
 import static android.companion.CompanionDeviceManager.RESULT_USER_REJECTED;
@@ -27,6 +24,8 @@
 
 import static com.android.companiondevicemanager.CompanionDeviceDiscoveryService.DiscoveryState;
 import static com.android.companiondevicemanager.CompanionDeviceDiscoveryService.DiscoveryState.FINISHED_TIMEOUT;
+import static com.android.companiondevicemanager.CompanionDeviceDiscoveryService.LOCK;
+import static com.android.companiondevicemanager.CompanionDeviceDiscoveryService.sDiscoveryStarted;
 import static com.android.companiondevicemanager.CompanionDeviceResources.PROFILE_ICONS;
 import static com.android.companiondevicemanager.CompanionDeviceResources.PROFILE_NAMES;
 import static com.android.companiondevicemanager.CompanionDeviceResources.PROFILE_PERMISSIONS;
@@ -232,8 +231,7 @@
         boolean forCancelDialog = intent.getBooleanExtra(EXTRA_FORCE_CANCEL_CONFIRMATION, false);
         if (forCancelDialog) {
             Slog.i(TAG, "Cancelling the user confirmation");
-            cancel(/* discoveryTimeOut */ false, /* userRejected */ false,
-                    /* internalError */ false);
+            cancel(RESULT_CANCELED);
             return;
         }
 
@@ -241,8 +239,14 @@
         // yet). We can only "process" one request at a time.
         final IAssociationRequestCallback appCallback = IAssociationRequestCallback.Stub
                 .asInterface(intent.getExtras().getBinder(EXTRA_APPLICATION_CALLBACK));
+
+        if (appCallback == null) {
+            return;
+        }
+        Slog.e(TAG, "More than one AssociationRequests are processing.");
+
         try {
-            requireNonNull(appCallback).onFailure("Busy.");
+            appCallback.onFailure(RESULT_INTERNAL_ERROR);
         } catch (RemoteException ignore) {
         }
     }
@@ -253,8 +257,7 @@
 
         // TODO: handle config changes without cancelling.
         if (!isDone()) {
-            cancel(/* discoveryTimeOut */ false,
-                    /* userRejected */ false, /* internalError */ false); // will finish()
+            cancel(RESULT_CANCELED); // will finish()
         }
     }
 
@@ -326,8 +329,11 @@
     private void onDiscoveryStateChanged(DiscoveryState newState) {
         if (newState == FINISHED_TIMEOUT
                 && CompanionDeviceDiscoveryService.getScanResult().getValue().isEmpty()) {
-            cancel(/* discoveryTimeOut */ true,
-                    /* userRejected */ false, /* internalError */ false);
+            synchronized (LOCK) {
+                if (sDiscoveryStarted) {
+                    cancel(RESULT_DISCOVERY_TIMEOUT);
+                }
+            }
         }
     }
 
@@ -365,7 +371,7 @@
         mCdmServiceReceiver.send(RESULT_CODE_ASSOCIATION_APPROVED, data);
     }
 
-    private void cancel(boolean discoveryTimeout, boolean userRejected, boolean internalError) {
+    private void cancel(int failureCode) {
         if (isDone()) {
             Slog.w(TAG, "Already done: " + (mApproved ? "Approved" : "Cancelled"));
             return;
@@ -373,35 +379,19 @@
         mCancelled = true;
 
         // Stop discovery service if it was used.
-        if (!mRequest.isSelfManaged() || discoveryTimeout) {
+        if (!mRequest.isSelfManaged()) {
             CompanionDeviceDiscoveryService.stop(this);
         }
 
-        final String cancelReason;
-        final int resultCode;
-        if (userRejected) {
-            cancelReason = REASON_USER_REJECTED;
-            resultCode = RESULT_USER_REJECTED;
-        } else if (discoveryTimeout) {
-            cancelReason = REASON_DISCOVERY_TIMEOUT;
-            resultCode = RESULT_DISCOVERY_TIMEOUT;
-        } else if (internalError) {
-            cancelReason = REASON_INTERNAL_ERROR;
-            resultCode = RESULT_INTERNAL_ERROR;
-        } else {
-            cancelReason = REASON_CANCELED;
-            resultCode = CompanionDeviceManager.RESULT_CANCELED;
-        }
-
         // First send callback to the app directly...
         try {
-            Slog.i(TAG, "Sending onFailure to app due to reason=" + cancelReason);
-            mAppCallback.onFailure(cancelReason);
+            Slog.i(TAG, "Sending onFailure to app due to failureCode=" + failureCode);
+            mAppCallback.onFailure(failureCode);
         } catch (RemoteException ignore) {
         }
 
         // ... then set result and finish ("sending" onActivityResult()).
-        setResultAndFinish(null, resultCode);
+        setResultAndFinish(null, failureCode);
     }
 
     private void setResultAndFinish(@Nullable AssociationInfo association, int resultCode) {
@@ -446,8 +436,7 @@
             }
         } catch (PackageManager.NameNotFoundException e) {
             Slog.e(TAG, "Package u" + userId + "/" + packageName + " not found.");
-            cancel(/* discoveryTimeout */ false,
-                    /* userRejected */ false, /* internalError */ true);
+            cancel(RESULT_INTERNAL_ERROR);
             return;
         }
 
@@ -565,9 +554,18 @@
         mSelectedDevice = requireNonNull(selectedDevice);
 
         Slog.d(TAG, "onDeviceClicked(): " + mSelectedDevice.toShortString());
-
+        // The permission consent dialog should not be displayed if it's a isSkipPrompt(true)
+        // AssociationRequest or when there is no device profile available
+        // for the multiple devices dialog.
+        // See AssociationRequestsProcessor#mayAssociateWithoutPrompt.
+        final String deviceProfile = mRequest.getDeviceProfile();
+        if (deviceProfile == null || mRequest.isSkipPrompt()) {
+            onUserSelectedDevice(mSelectedDevice);
+            return;
+        }
+        // The permission consent dialog should be displayed for the multiple device
+        // dialog if a device profile exists.
         updateSingleDeviceUi();
-
         mSummary.setVisibility(View.VISIBLE);
         mButtonAllow.setVisibility(View.VISIBLE);
         mButtonNotAllow.setVisibility(View.VISIBLE);
@@ -597,9 +595,6 @@
         if (deviceProfile == null && mRequest.isSingleDevice()) {
             summary = getHtmlFromResources(this, summaryResourceId, remoteDeviceName);
             mConstraintList.setVisibility(View.GONE);
-        } else if (deviceProfile == null) {
-            onUserSelectedDevice(mSelectedDevice);
-            return;
         } else {
             summary = getHtmlFromResources(
                     this, summaryResourceId, getString(R.string.device_type));
@@ -629,7 +624,7 @@
         // Disable the button, to prevent more clicks.
         v.setEnabled(false);
 
-        cancel(/* discoveryTimeout */ false, /* userRejected */ true, /* internalError */ false);
+        cancel(RESULT_USER_REJECTED);
     }
 
     private void onShowHelperDialog(View view) {
@@ -755,7 +750,7 @@
 
     @Override
     public void onShowHelperDialogFailed() {
-        cancel(/* discoveryTimeout */ false, /* userRejected */ false, /* internalError */ true);
+        cancel(RESULT_INTERNAL_ERROR);
     }
 
     @Override
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java
index e809433..6c1bc4e 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java
@@ -90,9 +90,6 @@
             new MutableLiveData<>(Collections.emptyList());
     private static MutableLiveData<DiscoveryState> sStateLiveData =
             new MutableLiveData<>(DiscoveryState.NOT_STARTED);
-    private static final Object LOCK = new Object();
-    @GuardedBy("LOCK")
-    private static boolean sDiscoveryStarted = false;
 
     private BluetoothManager mBtManager;
     private BluetoothAdapter mBtAdapter;
@@ -109,6 +106,10 @@
 
     private boolean mStopAfterFirstMatch;
 
+    static final Object LOCK = new Object();
+    @GuardedBy("LOCK")
+    static boolean sDiscoveryStarted = false;
+
     /**
      * A state enum for devices' discovery.
      */
@@ -127,6 +128,7 @@
                 return false;
             }
         }
+        sScanResultsLiveData.setValue(Collections.emptyList());
         requireNonNull(associationRequest);
         final Intent intent = new Intent(context, CompanionDeviceDiscoveryService.class);
         intent.setAction(ACTION_START_DISCOVERY);
@@ -192,7 +194,6 @@
             sDiscoveryStarted = true;
         }
         mStopAfterFirstMatch = request.isSingleDevice();
-        sScanResultsLiveData.setValue(Collections.emptyList());
         sStateLiveData.setValue(DiscoveryState.IN_PROGRESS);
 
         final List<DeviceFilter<?>> allFilters = request.getDeviceFilters();
diff --git a/packages/CredentialManager/res/values-el/strings.xml b/packages/CredentialManager/res/values-el/strings.xml
index 2f3aa0b..8436e21 100644
--- a/packages/CredentialManager/res/values-el/strings.xml
+++ b/packages/CredentialManager/res/values-el/strings.xml
@@ -53,7 +53,7 @@
     <string name="save_password_on_other_device_title" msgid="5829084591948321207">"Θέλετε να αποθηκεύσετε τον κωδικό πρόσβασης σε κάποια άλλη συσκευή;"</string>
     <string name="save_sign_in_on_other_device_title" msgid="2827990118560134692">"Θέλετε να αποθηκεύσετε τα στοιχεία σύνδεσης σε κάποια άλλη συσκευή;"</string>
     <string name="use_provider_for_all_title" msgid="4201020195058980757">"Να χρησιμοποιηθεί το <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> για όλες τις συνδέσεις σας;"</string>
-    <string name="use_provider_for_all_description" msgid="1998772715863958997">"Αυτός ο διαχειριστής κωδικών πρόσβασης για τον χρήστη <xliff:g id="USERNAME">%1$s</xliff:g> θα αποθηκεύει τους κωδικούς και τα κλειδιά πρόσβασης, για πιο εύκολη σύνδεση"</string>
+    <string name="use_provider_for_all_description" msgid="1998772715863958997">"Αυτή η διαχείριση κωδικών πρόσβασης για τον χρήστη <xliff:g id="USERNAME">%1$s</xliff:g> θα αποθηκεύει τους κωδικούς και τα κλειδιά πρόσβασης, για πιο εύκολη σύνδεση"</string>
     <string name="set_as_default" msgid="4415328591568654603">"Ορισμός ως προεπιλογής"</string>
     <string name="settings" msgid="6536394145760913145">"Ρυθμίσεις"</string>
     <string name="use_once" msgid="9027366575315399714">"Χρήση μία φορά"</string>
diff --git a/packages/CredentialManager/res/values-fa/strings.xml b/packages/CredentialManager/res/values-fa/strings.xml
index 6147ccc..6e6c22a 100644
--- a/packages/CredentialManager/res/values-fa/strings.xml
+++ b/packages/CredentialManager/res/values-fa/strings.xml
@@ -86,7 +86,7 @@
     <string name="button_label_view_more" msgid="3429098227286495651">"مشاهده موارد بیشتر"</string>
     <string name="get_dialog_heading_for_username" msgid="3456868514554204776">"برای <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_heading_locked_password_managers" msgid="8911514851762862180">"مدیران گذرواژه قفل‌شده"</string>
-    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="6390367581393605009">"برای باز کردن قفل ضربه بزنید"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="6390367581393605009">"برای باز کردن قفل تک‌ضرب بزنید"</string>
     <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="8131725029983174901">"اطلاعات ورود به سیستم موجود نیست"</string>
     <string name="no_sign_in_info_in" msgid="2641118151920288356">"هیچ اطلاعات ورود به سیستمی در <xliff:g id="SOURCE">%1$s</xliff:g> وجود ندارد"</string>
     <string name="get_dialog_heading_manage_sign_ins" msgid="3522556476480676782">"مدیریت ورود به سیستم‌ها"</string>
diff --git a/packages/CredentialManager/res/values-fr-rCA/strings.xml b/packages/CredentialManager/res/values-fr-rCA/strings.xml
index d9715ee..d68de9f 100644
--- a/packages/CredentialManager/res/values-fr-rCA/strings.xml
+++ b/packages/CredentialManager/res/values-fr-rCA/strings.xml
@@ -32,9 +32,9 @@
     <string name="passwordless_technology_title" msgid="2497513482056606668">"Technologie sans mot de passe"</string>
     <string name="passwordless_technology_detail" msgid="6853928846532955882">"Les clés d\'accès vous permettent de vous connecter sans utiliser de mots de passe. Il vous suffit d\'utiliser votre empreinte digitale, la reconnaissance faciale, un NIP ou un schéma de balayage pour vérifier votre identité et créer un mot de passe."</string>
     <string name="public_key_cryptography_title" msgid="6751970819265298039">"Cryptographie à clé publique"</string>
-    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Selon les normes de l\'Alliance FIDO (y compris Google, Apple, Microsoft et plus) et du W3C, les clés d\'accès utilisent des biclés cryptographiques. Contrairement au nom d\'utilisateur et à la chaîne de caractères que nous utilisons pour les mots de passe, une biclé privée-publique est créée pour une application ou un site Web. La clé privée est stockée en toute sécurité sur votre appareil ou votre gestionnaire de mots de passe et confirme votre identité. La clé publique est partagée avec le serveur de l\'application ou du site Web. Avec les clés correspondantes, vous pouvez vous inscrire et vous connecter instantanément."</string>
+    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"Selon les normes de l\'Alliance FIDO (y compris Google, Apple, Microsoft et plus) et du W3C, les clés d\'accès utilisent des biclés cryptographiques. Contrairement au nom d\'utilisateur et à la chaîne de caractères que nous utilisons pour les mots de passe, une biclé privée-publique est créée pour une appli ou un site Web. La clé privée est stockée en toute sécurité sur votre appareil ou votre gestionnaire de mots de passe et confirme votre identité. La clé publique est partagée avec le serveur de l\'appli ou du site Web. Avec les clés correspondantes, vous pouvez vous inscrire et vous connecter instantanément."</string>
     <string name="improved_account_security_title" msgid="1069841917893513424">"Sécurité accrue du compte"</string>
-    <string name="improved_account_security_detail" msgid="9123750251551844860">"Chaque clé est exclusivement liée à l\'application ou au site Web pour lequel elle a été créée, de sorte que vous ne pourrez jamais vous connecter par erreur à une application ou à un site Web frauduleux. En outre, comme les serveurs ne conservent que les clés publiques, le piratage informatique est beaucoup plus difficile."</string>
+    <string name="improved_account_security_detail" msgid="9123750251551844860">"Chaque clé est exclusivement liée à l\'appli ou au site Web pour lequel elle a été créée, de sorte que vous ne pourrez jamais vous connecter par erreur à une appli ou à un site Web frauduleux. En outre, comme les serveurs ne conservent que les clés publiques, le piratage informatique est beaucoup plus difficile."</string>
     <string name="seamless_transition_title" msgid="5335622196351371961">"Transition fluide"</string>
     <string name="seamless_transition_detail" msgid="4475509237171739843">"À mesure que nous nous dirigeons vers un avenir sans mot de passe, ils resteront toujours utilisés parallèlement aux clés d\'accès."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Choisir où enregistrer vos <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-pa/strings.xml b/packages/CredentialManager/res/values-pa/strings.xml
index 517fd82..309299c 100644
--- a/packages/CredentialManager/res/values-pa/strings.xml
+++ b/packages/CredentialManager/res/values-pa/strings.xml
@@ -32,7 +32,7 @@
     <string name="passwordless_technology_title" msgid="2497513482056606668">"ਪਾਸਵਰਡ ਰਹਿਤ ਤਕਨਾਲੋਜੀ"</string>
     <string name="passwordless_technology_detail" msgid="6853928846532955882">"ਪਾਸਕੀਆਂ ਤੁਹਾਨੂੰ ਪਾਸਵਰਡਾਂ \'ਤੇ ਭਰੋਸਾ ਕੀਤੇ ਬਿਨਾਂ ਸਾਈਨ-ਇਨ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦੀਆਂ ਹਨ। ਤੁਹਾਨੂੰ ਆਪਣੀ ਪਛਾਣ ਦੀ ਪੁਸ਼ਟੀ ਕਰਨ ਅਤੇ ਪਾਸਕੀ ਬਣਾਉਣ ਲਈ ਸਿਰਫ਼ ਆਪਣੇ ਫਿੰਗਰਪ੍ਰਿੰਟ, ਚਿਹਰਾ ਪਛਾਣ, ਪਿੰਨ ਜਾਂ ਸਵਾਈਪ ਪੈਟਰਨ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਲੋੜ ਹੈ।"</string>
     <string name="public_key_cryptography_title" msgid="6751970819265298039">"ਜਨਤਕ ਕੁੰਜੀ ਕ੍ਰਿਪਟੋਗ੍ਰਾਫ਼ੀ"</string>
-    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO ਗਠਜੋੜ (ਜਿਸ ਵਿੱਚ Google, Apple, Microsoft ਅਤੇ ਹੋਰ ਸ਼ਾਮਲ ਹਨ) ਅਤੇ W3C ਮਿਆਰਾਂ ਦੇ ਆਧਾਰ \'ਤੇ ਪਾਸਕੀਆਂ ਕ੍ਰਿਪਟੋਗ੍ਰਾਫ਼ਿਕ ਕੁੰਜੀਆਂ ਦੇ ਜੋੜੇ ਵਰਤਦੀਆਂ ਹਨ। ਪਾਸਵਰਡ ਲਈ ਵਰਤੀ ਜਾਂਦੀ ਅੱਖਰ-ਚਿੰਨ੍ਹਾਂ ਦੀ ਸਤਰ ਅਤੇ ਵਰਤੋਂਕਾਰ ਨਾਮ ਤੋਂ ਅਲੱਗ, ਐਪ ਜਾਂ ਵੈੱਬਸਾਈਟ ਲਈ ਨਿੱਜੀ-ਜਨਤਕ ਕੁੰਜੀ ਜੋੜਾ ਬਣਾਇਆ ਜਾਂਦਾ ਹੈ। ਨਿੱਜੀ ਕੁੰਜੀ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਜਾਂ ਪਾਸਵਰਡ ਪ੍ਰਬੰਧਕ \'ਤੇ ਸੁਰੱਖਿਅਤ ਢੰਗ ਨਾਲ ਸਟੋਰ ਕੀਤੀ ਜਾਂਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੀ ਪਛਾਣ ਦੀ ਪੁਸ਼ਟੀ ਕਰਦੀ ਹੈ। ਜਨਤਕ ਕੁੰਜੀ ਐਪ ਜਾਂ ਵੈੱਬਸਾਈਟ ਸਰਵਰ ਨਾਲ ਸਾਂਝੀ ਕੀਤੀ ਜਾਂਦੀ ਹੈ। ਸੰਬੰਧਿਤ ਕੁੰਜੀਆਂ ਨਾਲ, ਤੁਸੀਂ ਤੁਰੰਤ ਰਜਿਸਟਰ ਅਤੇ ਸਾਈਨ-ਇਨ ਕਰ ਸਕਦੇ ਹੋ।"</string>
+    <string name="public_key_cryptography_detail" msgid="6937631710280562213">"FIDO ਗਠਜੋੜ (Google, Apple, Microsoft ਅਤੇ ਹੋਰ) ਅਤੇ W3C ਮਿਆਰਾਂ ਦੇ ਆਧਾਰ \'ਤੇ ਪਾਸਕੀਆਂ ਕ੍ਰਿਪਟੋਗ੍ਰਾਫ਼ਿਕ ਕੁੰਜੀਆਂ ਦੇ ਜੋੜੇ ਵਰਤਦੀਆਂ ਹਨ। ਪਾਸਵਰਡ ਲਈ ਵਰਤੀ ਜਾਂਦੀ ਅੱਖਰ-ਚਿੰਨ੍ਹਾਂ ਦੀ ਸਤਰ ਅਤੇ ਵਰਤੋਂਕਾਰ ਨਾਮ ਤੋਂ ਅਲੱਗ, ਐਪ ਜਾਂ ਵੈੱਬਸਾਈਟ ਲਈ ਪ੍ਰਾਈਵੇਟ-ਜਨਤਕ ਕੁੰਜੀ ਜੋੜਾ ਬਣਾਇਆ ਜਾਂਦਾ ਹੈ। ਪ੍ਰਾਈਵੇਟ ਕੁੰਜੀ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਜਾਂ ਪਾਸਵਰਡ ਪ੍ਰਬੰਧਕ \'ਤੇ ਸੁਰੱਖਿਅਤ ਢੰਗ ਨਾਲ ਸਟੋਰ ਕੀਤੀ ਜਾਂਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੀ ਪਛਾਣ ਦੀ ਪੁਸ਼ਟੀ ਕਰਦੀ ਹੈ। ਜਨਤਕ ਕੁੰਜੀ ਐਪ ਜਾਂ ਵੈੱਬਸਾਈਟ ਸਰਵਰ ਨਾਲ ਸਾਂਝੀ ਕੀਤੀ ਜਾਂਦੀ ਹੈ। ਸੰਬੰਧਿਤ ਕੁੰਜੀਆਂ ਨਾਲ, ਤੁਸੀਂ ਤੁਰੰਤ ਰਜਿਸਟਰ ਅਤੇ ਸਾਈਨ-ਇਨ ਕਰ ਸਕਦੇ ਹੋ।"</string>
     <string name="improved_account_security_title" msgid="1069841917893513424">"ਬਿਹਤਰ ਖਾਤਾ ਸੁਰੱਖਿਆ"</string>
     <string name="improved_account_security_detail" msgid="9123750251551844860">"ਹਰੇਕ ਕੁੰਜੀ ਖਾਸ ਤੌਰ \'ਤੇ ਉਸ ਐਪ ਜਾਂ ਵੈੱਬਸਾਈਟ ਨਾਲ ਲਿੰਕ ਹੁੰਦੀ ਹੈ ਜਿਸ ਲਈ ਉਹ ਬਣਾਈ ਗਈ ਸੀ, ਇਸ ਲਈ ਤੁਸੀਂ ਕਦੇ ਵੀ ਗਲਤੀ ਨਾਲ ਕਿਸੇ ਧੋਖਾਧੜੀ ਵਾਲੀ ਐਪ ਜਾਂ ਵੈੱਬਸਾਈਟ \'ਤੇ ਸਾਈਨ-ਇਨ ਨਹੀਂ ਕਰ ਸਕਦੇ। ਇਸ ਤੋਂ ਇਲਾਵਾ, ਸਿਰਫ਼ ਜਨਤਕ ਕੁੰਜੀਆਂ ਵਾਲੇ ਸਰਵਰਾਂ \'ਤੇ, ਹੈਕਿੰਗ ਕਰਨਾ ਬਹੁਤ ਔਖਾ ਹੁੰਦਾ ਹੈ।"</string>
     <string name="seamless_transition_title" msgid="5335622196351371961">"ਸਹਿਜ ਪਰਿਵਰਤਨ"</string>
diff --git a/packages/CredentialManager/wear/res/values-am/strings.xml b/packages/CredentialManager/wear/res/values-am/strings.xml
new file mode 100644
index 0000000..4aa4af1
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-am/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"የመግቢያ ማስረጃ አስተዳዳሪ"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"የይለፍ ቁልፍ ይጠቀማሉ?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"የይለፍ ቃል ይጠቀማሉ?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"አሰናብት"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"ቀጥል"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"የመግቢያ አማራጮች"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"የመግቢያ አማራጮች"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"መግቢያዎችን ያስተዳድሩ"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"መግቢያ ይምረጡ"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"የይለፍ ቁልፍ ይምረጡ"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"የይለፍ ቃል ይምረጡ"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"በስልክ ላይ ግባ"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"ምንም የመግቢያ መረጃ የለም"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"ለመክፈት መታ ያድርጉ"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-as/strings.xml b/packages/CredentialManager/wear/res/values-as/strings.xml
new file mode 100644
index 0000000..7b6055d
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-as/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"ক্ৰিডেনশ্বিয়েল পৰিচালক"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"পাছকী ব্যৱহাৰ কৰিবনে?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"পাছৱৰ্ড ব্যৱহাৰ কৰিবনে?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"অগ্ৰাহ্য কৰক"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"অব্যাহত ৰাখক"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"ছাইন ইন কৰাৰ বিকল্প"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"ছাইন ইন কৰাৰ বিকল্প"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"ছাইন ইন পৰিচালনা কৰক"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"এটা ছাইন ইনৰ উপায় বাছনি কৰক"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"পাছকী বাছনি কৰক"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"পাছৱৰ্ড বাছনি কৰক"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ফ’নত ছাইন ইন কৰক"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"ছাইন ইনৰ তথ্য নাই"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"আনলক কৰিবলৈ টিপক"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-cs/strings.xml b/packages/CredentialManager/wear/res/values-cs/strings.xml
new file mode 100644
index 0000000..ba60a8c
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-cs/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Správce oprávnění"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"Použít přístupový klíč?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"Použít heslo?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"Zavřít"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"Pokračovat"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Možnosti přihlášení"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"Možnosti přihlášení"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"Spravovat přihlášení"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Vyberte přihlášení"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"Vyberte přístupový klíč"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"Vyberte heslo"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Přihlásit se z telefonu"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Žádné informace o přihlášení"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Klepnutím odemknete"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-el/strings.xml b/packages/CredentialManager/wear/res/values-el/strings.xml
new file mode 100644
index 0000000..1c9d49b
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-el/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Διαχειριστής διαπιστευτηρίων"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"Χρήση κλειδιού πρόσβασης;"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"Χρήση κωδικού πρόσβασης;"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"Παράβλεψη"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"Συνέχεια"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Επιλογές σύνδεσης"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"Επιλογές σύνδεσης"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"Διαχείριση στοιχείων σύνδεσης"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Επιλογή σύνδεσης"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"Επιλογή κλειδιού πρόσβασης"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"Επιλογή κωδικού πρόσβασης"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Σύνδεση στο τηλέφωνο"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Δεν υπάρχουν πληροφορίες σύνδεσης"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Πατήστε για ξεκλείδωμα"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-en-rAU/strings.xml b/packages/CredentialManager/wear/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..75a0a00
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-en-rAU/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"Use passkey?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"Use password?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"Dismiss"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"Continue"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Sign-in options"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"Sign-in options"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"Manage sign-ins"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Choose a sign-in"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"Choose passkey"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"Choose password"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Sign in on phone"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"No sign-in info"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Tap to unlock"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-en-rCA/strings.xml b/packages/CredentialManager/wear/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..a8a2b7a
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-en-rCA/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"Use passkey?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"Use password?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"Dismiss"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"Continue"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Sign-in Options"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"Sign-in Options"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"Manage sign-ins"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Choose a sign in"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"Choose passkey"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"Choose password"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Sign in on phone"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"No sign-in info"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Tap to unlock"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-en-rGB/strings.xml b/packages/CredentialManager/wear/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..75a0a00
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-en-rGB/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"Use passkey?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"Use password?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"Dismiss"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"Continue"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Sign-in options"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"Sign-in options"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"Manage sign-ins"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Choose a sign-in"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"Choose passkey"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"Choose password"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Sign in on phone"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"No sign-in info"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Tap to unlock"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-en-rIN/strings.xml b/packages/CredentialManager/wear/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..75a0a00
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-en-rIN/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"Use passkey?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"Use password?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"Dismiss"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"Continue"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Sign-in options"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"Sign-in options"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"Manage sign-ins"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Choose a sign-in"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"Choose passkey"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"Choose password"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Sign in on phone"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"No sign-in info"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Tap to unlock"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-en-rXC/strings.xml b/packages/CredentialManager/wear/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..fbdd5cf
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-en-rXC/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‏‎‎‏‎‏‎‏‎‎‎‏‏‎‎‎‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‎‎Credential Manager‎‏‎‎‏‎"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‏‎‏‏‎‏‎‎‏‎‏‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‏‎Use passkey?‎‏‎‎‏‎"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‎‏‎‎‎‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‎‏‏‎‏‏‏‎‏‏‎‎‏‏‎‎‎‎‎‏‎‎‎‏‎‎‎‏‏‎‎‎Use password?‎‏‎‎‏‎"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎‎‏‎‎‏‎‏‏‎Dismiss‎‏‎‎‏‎"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‎‏‎‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎Continue‎‏‎‎‏‎"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‏‏‎‎‎‏‏‎‏‏‏‏‎‏‎‎‎‎‎‎‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‏‏‎‎‎‎‎‎‏‏‏‎‎Sign-in Options‎‏‎‎‏‎"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‎‏‏‏‎‏‎‎‎‎‏‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‎‎Sign-in Options‎‏‎‎‏‎"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‎‏‎‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‏‏‏‏‎‏‎‎‎Manage sign-ins‎‏‎‎‏‎"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‎‏‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‏‎‏‎‎‎‏‏‎‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‎‎‏‎‎‎‎‎‎‎‏‎‏‏‎‎‎‏‎‏‎‎Choose a sign in‎‏‎‎‏‎"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎‏‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎Choose passkey‎‏‎‎‏‎"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‎‏‏‎‎‎‎‏‏‏‎‎‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‎‏‏‎‏‏‏‏‏‎‎Choose password‎‏‎‎‏‎"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‏‎‏‎‏‏‎‎‏‎‎‎‎‏‎‏‎‎‏‎‏‏‎‎‏‏‎‎‎‎‎‎‎‏‏‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎‏‏‎Sign in on phone‎‏‎‎‏‎"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎‏‎‎‏‏‎‎‎‎‏‎‏‎‏‎‎‏‏‏‎‎‏‏‏‏‎‏‏‎‏‏‎‎‏‏‏‏‏‎‎‎‏‏‏‏‏‏‎‏‎No sign-in info‎‏‎‎‏‎"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‏‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‎‎‎‏‏‎‎‎‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‎‎Tap to unlock‎‏‎‎‏‎"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-es-rUS/strings.xml b/packages/CredentialManager/wear/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..97bb3e0
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-es-rUS/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"¿Quieres usar una llave de acceso?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"¿Quieres usar una contraseña?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"Descartar"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"Continuar"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Opción para acceder"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"Opción para acceder"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"Administrar accesos"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Elige un acceso"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"Elige una llave de acceso"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"Elige una contraseña"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Acceder desde el teléfono"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"No hay información de acceso"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Presiona para desbloquear"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-fi/strings.xml b/packages/CredentialManager/wear/res/values-fi/strings.xml
new file mode 100644
index 0000000..855f025
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-fi/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Kirjautumistietojen hallinta"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"Käytetäänkö avainkoodia?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"Käytetäänkö salasanaa?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"Hylkää"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"Jatka"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Kirjautumisvaihtoehdot"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"Kirjautumisvaihtoehdot"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"Muuta kirjautumistietoja"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Valitse kirjautumistapa"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"Valitse avainkoodi"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"Valitse salasana"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Kirjaudu sisään puhelimella"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Ei kirjautumistietoja"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Avaa napauttamalla"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-gu/strings.xml b/packages/CredentialManager/wear/res/values-gu/strings.xml
new file mode 100644
index 0000000..ff8d298
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-gu/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"લૉગ ઇન વિગતોના મેનેજર"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"પાસકીનો ઉપયોગ કરીએ?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"પાસવર્ડનો ઉપયોગ કરીએ?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"છોડી દો"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"ચાલુ રાખો"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"સાઇન-ઇનના વિકલ્પો"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"સાઇન-ઇનના વિકલ્પો"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"સાઇન-ઇન મેનેજ કરો"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"સાઇન ઇન કરવાની કોઈ રીત પસંદ કરો"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"પાસકી પસંદ કરો"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"પાસવર્ડ પસંદ કરો"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ફોન પર સાઇન ઇન કરો"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"કોઈ સાઇન-ઇન માહિતી નથી"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"અનલૉક કરવા માટે ટૅપ કરો"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-hi/strings.xml b/packages/CredentialManager/wear/res/values-hi/strings.xml
new file mode 100644
index 0000000..a061453
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-hi/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"क्या आपको पासकी का इस्तेमाल करना है?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"क्या आपको पासवर्ड का इस्तेमाल करना है?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"खारिज करें"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"जारी रखें"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"साइन इन करने के विकल्प"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"साइन इन करने के विकल्प"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"साइन-इन क्रेडेंशियल मैनेज करें"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"साइन इन करने का कोई तरीका चुनें"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"कोई पासकी चुनें"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"कोई पासवर्ड चुनें"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"फ़ोन पर साइन इन करें"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"साइन-इन के लिए कोई क्रेडेंशियल मौजूद नहीं है"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"अनलॉक करने के लिए टैप करें"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-hy/strings.xml b/packages/CredentialManager/wear/res/values-hy/strings.xml
new file mode 100644
index 0000000..cea1112
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-hy/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Մուտքի տվյալների կառավարիչ"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"Օգտագործե՞լ մուտքի բանալին"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"Օգտագործե՞լ գաղտնաբառը"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"Փակել"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"Շարունակել"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Մուտք գործելու եղանակներ"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"Մուտք գործելու եղանակներ"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"Մուտքի կառավարում"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Ընտրեք մուտք գործելու եղանակը"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"Ընտրեք մուտքի բանալին"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"Ընտրեք գաղտնաբառը"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Մուտք գործել հեռախոսում"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Մուտքի տվյալներ չկան"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Հպեք ապակողպելու համար"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-is/strings.xml b/packages/CredentialManager/wear/res/values-is/strings.xml
new file mode 100644
index 0000000..fcd9ce5
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-is/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Skilríkjastjórnun"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"Nota aðgangslykil?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"Nota aðgangsorð?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"Hunsa"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"Halda áfram"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Innskráningarkostir"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"Innskráningarkostir"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"Stjórna innskráningu"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Velja innskráningu"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"Velja aðgangslykil"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"Velja aðgangsorð"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Skráðu þig inn á síma"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Engar innskráningarupplýsingar"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Ýttu til að opna"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ja/strings.xml b/packages/CredentialManager/wear/res/values-ja/strings.xml
new file mode 100644
index 0000000..05a04e3
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ja/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"認証情報マネージャー"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"パスキーを使用しますか?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"パスワードを使用しますか?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"閉じる"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"続行"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"ログイン オプション"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"ログイン オプション"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"ログインの管理"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"ログインの選択"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"パスキーの選択"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"パスワードの選択"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"スマートフォンでログイン"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"ログイン情報はありません"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"タップしてロック解除"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ka/strings.xml b/packages/CredentialManager/wear/res/values-ka/strings.xml
new file mode 100644
index 0000000..2164d1e
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ka/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"ავტორიზაციის მონაცემების მმართველი"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"გსურთ წვდომის გასაღების გამოყენება?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"გსურთ პაროლის გამოყენება?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"დახურვა"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"გაგრძელება"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"სისტემაში შესვლის ვარიანტები"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"სისტემაში შესვლის ვარიანტები"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"სისტემაში შესვლის მართვა"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"სისტემაში შესვლის არჩევა"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"წვდომის გასაღების არჩევა"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"პაროლის არჩევა"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"სისტემაში შესვლა ტელეფონით"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"სისტემაში შესვლისთვის ინფორმაცია არ არის"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"შეეხეთ განსაბლოკად"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-km/strings.xml b/packages/CredentialManager/wear/res/values-km/strings.xml
new file mode 100644
index 0000000..9dcaeb8
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-km/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"ប្រើកូដសម្ងាត់ឬ?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"ប្រើពាក្យ​សម្ងាត់ឬ?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"ច្រានចោល"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"បន្ត"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"ជម្រើសចូលគណនី"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"ជម្រើសចូលគណនី"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"គ្រប់គ្រងការចូល​គណនី"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"ជ្រើសរើសការចូល​គណនី"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"ជ្រើសរើសកូដសម្ងាត់"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"ជ្រើសរើសពាក្យ​សម្ងាត់"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ចូលនៅលើទូរសព្ទ"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"គ្មានព័ត៌មានចូលគណនីទេ"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"ចុចដើម្បីដោះសោ"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-kn/strings.xml b/packages/CredentialManager/wear/res/values-kn/strings.xml
new file mode 100644
index 0000000..fc2f65e
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-kn/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"ಕ್ರೆಡೆನ್ಶಿಯಲ್ ಮ್ಯಾನೇಜರ್"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"ಪಾಸ್‌ಕೀ ಅನ್ನು ಬಳಸಬೇಕೆ?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"ಪಾಸ್‌ವರ್ಡ್ ಅನ್ನು ಬಳಸಬೇಕೆ?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"ವಜಾಗೊಳಿಸಿ"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"ಮುಂದುವರಿಸಿ"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"ಸೈನ್ ಇನ್ ಆಯ್ಕೆಗಳು"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"ಸೈನ್ ಇನ್ ಆಯ್ಕೆಗಳು"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"ಸೈನ್-ಇನ್‌ಗಳನ್ನು ನಿರ್ವಹಿಸಿ"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"ಸೈನ್-ಇನ್ ಅನ್ನು ಆರಿಸಿ"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"ಪಾಸ್‌ಕೀ ಅನ್ನು ಆರಿಸಿ"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"ಪಾಸ್‌ವರ್ಡ್ ಅನ್ನು ಆರಿಸಿ"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ಫೋನ್‌ನಲ್ಲಿ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"ಯಾವುದೇ ಸೈನ್ ಇನ್ ಮಾಹಿತಿಯಿಲ್ಲ"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"ಅನ್‌ಲಾಕ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ko/strings.xml b/packages/CredentialManager/wear/res/values-ko/strings.xml
new file mode 100644
index 0000000..a07fb2a
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ko/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"인증 관리자"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"패스키를 사용하시겠습니까?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"비밀번호를 사용하시겠습니까?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"닫기"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"계속"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"로그인 옵션"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"로그인 옵션"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"로그인 정보 관리"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"로그인 선택"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"패스키 선택"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"비밀번호 선택"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"휴대전화에서 로그인하기"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"로그인 정보 없음"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"탭하여 잠금 해제하기"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-lo/strings.xml b/packages/CredentialManager/wear/res/values-lo/strings.xml
new file mode 100644
index 0000000..c48f88f
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-lo/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"ຕົວຈັດການຂໍ້ມູນການເຂົ້າສູ່ລະບົບ"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"ໃຊ້ກະແຈຜ່ານບໍ?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"ໃຊ້ລະຫັດຜ່ານບໍ?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"ປິດໄວ້"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"ສືບຕໍ່"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"ຕົວເລືອກການເຂົ້າສູ່ລະບົບ"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"ຕົວເລືອກການເຂົ້າສູ່ລະບົບ"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"ຈັດການການເຂົ້າສູ່ລະບົບ"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"ເລືອກການເຂົ້າສູ່ລະບົບ"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"ເລືອກກະແຈຜ່ານ"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"ເລືອກລະຫັດຜ່ານ"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ເຂົ້າສູ່ລະບົບຢູ່ໂທລະສັບ"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"ບໍ່ມີຂໍ້ມູນການເຂົ້າສູ່ລະບົບ"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"ແຕະເພື່ອປົດລັອກ"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ml/strings.xml b/packages/CredentialManager/wear/res/values-ml/strings.xml
new file mode 100644
index 0000000..a935148
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ml/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"ക്രെഡൻഷ്യൽ മാനേജർ"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"പാസ്‌കീ ഉപയോഗിക്കുക"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"പാസ്‌വേഡ് ഉപയോഗിക്കണോ?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"ഡിസ്‌മിസ് ചെയ്യുക"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"തുടരുക"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"സൈൻ ഇൻ ചെയ്യൽ ഓപ്ഷനുകൾ"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"സൈൻ ഇൻ ചെയ്യൽ ഓപ്ഷനുകൾ"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"സൈൻ ഇൻ ചെയ്യലുകൾ മാനേജ് ചെയ്യുക"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"ഒരു സൈൻ-ഇൻ തിരഞ്ഞെടുക്കുക"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"പാസ്‌കീ തിരഞ്ഞെടുക്കുക"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"പാസ്‌കീ തിരഞ്ഞെടുക്കുക"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ഫോണിൽ സൈൻ ഇൻ ചെയ്യുക"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"സൈൻ ഇൻ വിവരങ്ങളൊന്നുമില്ല"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"അൺലോക്ക് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-mr/strings.xml b/packages/CredentialManager/wear/res/values-mr/strings.xml
new file mode 100644
index 0000000..e966d30
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-mr/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"क्रेडेंशियल व्यवस्थापक"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"पासकी वापरायची आहे का?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"पासवर्ड वापरायचा आहे का?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"डिसमिस करा"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"पुढे सुरू ठेवा"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"साइन-इन पर्याय"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"साइन-इन पर्याय"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"साइन-इन व्यवस्थापित करा"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"साइन इन निवडा"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"पासकी निवडा"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"पासवर्ड निवडा"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"फोनवर साइन इन करा"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"साइन-इनची कोणतीही माहिती नाही"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"अनलॉक करण्यासाठी टॅप करा"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ms/strings.xml b/packages/CredentialManager/wear/res/values-ms/strings.xml
new file mode 100644
index 0000000..772bf19
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ms/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Pengurus Bukti Kelayakan"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"Gunakan kunci laluan?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"Gunakan kata laluan?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"Ketepikan"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"Teruskan"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Pilihan Log Masuk"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"Pilihan Log Masuk"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"Urus log masuk"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Pilih log masuk"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"Pilih kunci laluan"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"Pilih kata laluan"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Log masuk pada telefon"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Tiada maklumat log masuk"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Ketik untuk membuka kunci"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-my/strings.xml b/packages/CredentialManager/wear/res/values-my/strings.xml
new file mode 100644
index 0000000..7c38b9e
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-my/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"လျှို့ဝှက်ကီး သုံးမလား။"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"စကားဝှက် သုံးမလား။"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"ပယ်ရန်"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"ရှေ့ဆက်ရန်"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"လက်မှတ်ထိုးဝင်နည်းများ"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"လက်မှတ်ထိုးဝင်နည်းများ"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"လက်မှတ်ထိုးဝင်မှုများ စီမံခြင်း"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"လက်မှတ်ထိုးဝင်မှု ရွေးခြင်း"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"လျှို့ဝှက်ကီးရွေးခြင်း"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"စကားဝှက်ရွေးခြင်း"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ဖုန်းတွင် လက်မှတ်ထိုးဝင်ရန်"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"လက်မှတ်ထိုးဝင်ရန် အချက်အလက် မရှိပါ"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"ဖွင့်ရန် တို့ပါ"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-nb/strings.xml b/packages/CredentialManager/wear/res/values-nb/strings.xml
new file mode 100644
index 0000000..0c45c9c
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-nb/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Legitimasjonsbehandling"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"Vil du bruke passnøkkel?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"Vil du bruke passord?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"Lukk"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"Fortsett"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Påloggingsalternativer"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"Påloggingsalternativer"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"Administrer pålogginger"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Velg en pålogging"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"Velg passnøkkel"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"Velg passord"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Logg på med telefonen"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Ingen påloggingsinformasjon"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Trykk for å låse opp"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-nl/strings.xml b/packages/CredentialManager/wear/res/values-nl/strings.xml
new file mode 100644
index 0000000..1a15ead
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-nl/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Manager Inloggegevens"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"Toegangssleutel gebruiken?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"Wachtwoord gebruiken?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"Sluiten"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"Doorgaan"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Inlogopties"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"Inlogopties"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"Logins beheren"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Een login kiezen"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"Toegangssleutel kiezen"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"Wachtwoord kiezen"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Inloggen op telefoon"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Geen inloggegevens"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Tik om te ontgrendelen"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-pt-rPT/strings.xml b/packages/CredentialManager/wear/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..acec24c
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-pt-rPT/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Gestor de credenciais"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"Usar a chave de acesso?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"Usar a palavra-passe?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"Ignorar"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"Continuar"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Opções de início de sessão"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"Opções de início de sessão"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"Faça a gestão dos inícios de sessão"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Escolha um início de sessão"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"Escolha a chave de acesso"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"Escolha a palavra-passe"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Iniciar sessão no telemóvel"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Sem informações de início de sessão"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Tocar para desbloquear"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-sl/strings.xml b/packages/CredentialManager/wear/res/values-sl/strings.xml
new file mode 100644
index 0000000..b76165e
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-sl/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Upravitelj poverilnic"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"Želite uporabiti ključ za dostop?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"Želite uporabiti geslo?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"Opusti"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"Naprej"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Možnosti prijave"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"Možnosti prijave"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"Upravljanje podatkov za prijavo"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Izbira prijave"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"Izbira ključa za dostop"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"Izbira gesla"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Prijava v telefonu"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Ni nobenih podatkov za prijavo"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Dotaknite se, da odklenete"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-sw/strings.xml b/packages/CredentialManager/wear/res/values-sw/strings.xml
new file mode 100644
index 0000000..509c404
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-sw/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Kidhibiti cha Vitambulisho"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"Ungependa kutumia ufunguo wa siri?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"Ungependa kutumia nenosiri?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"Ondoa"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"Endelea"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Chaguo za Kuingia katika Akaunti"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"Chaguo za Kuingia katika Akaunti"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"Dhibiti michakato ya kuingia katika akaunti"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Chagua mbinu ya kuingia katika akaunti"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"Chagua ufunguo wa siri"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"Chagua nenosiri"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Ingia katika akaunti kwenye simu"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Hakuna maelezo ya kuingia katika akaunti"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Gusa ili ufungue"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ta/strings.xml b/packages/CredentialManager/wear/res/values-ta/strings.xml
new file mode 100644
index 0000000..9f88c81
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ta/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"அனுமதிச் சான்று நிர்வாகி"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"கடவுச்சாவியைப் பயன்படுத்தவா?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"கடவுச்சொல்லைப் பயன்படுத்தவா?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"மூடு"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"தொடர்க"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"உள்நுழைவு விருப்பங்கள்"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"உள்நுழைவு விருப்பங்கள்"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"உள்நுழைவுகளை நிர்வகித்தல்"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"உள்நுழைவைத் தேர்வுசெய்தல்"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"கடவுச்சாவியைத் தேர்வுசெய்தல்"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"கடவுச்சொல்லைத் தேர்வுசெய்தல்"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"மொபைலில் உள்நுழைக"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"உள்நுழைவுத் தகவல் இல்லை"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"அன்லாக் செய்ய தட்டவும்"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-te/strings.xml b/packages/CredentialManager/wear/res/values-te/strings.xml
new file mode 100644
index 0000000..086b109
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-te/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"సైన్-ఇన్ మేనేజర్"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"పాస్-కీని ఉపయోగిస్తారా?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"పాస్‌వర్డ్‌ను ఉపయోగిస్తారా?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"విస్మరించండి"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"కొనసాగించండి"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"సైన్ ఇన్ ఆప్షన్‌లు"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"సైన్ ఇన్ ఆప్షన్‌లు"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"సైన్‌ ఇన్‌లను మేనేజ్ చేయండి"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"సైన్ ఇన్‌ను ఎంచుకోండి"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"పాస్-కీని ఎంచుకోండి"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"పాస్‌వర్డ్‌ను ఎంచుకోండి"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ఫోన్‌లో సైన్ ఇన్ చేయండి"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"సైన్ ఇన్ సమాచారం ఏదీ లేదు"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"అన్‌లాక్ చేయడానికి ట్యాప్ చేయండి"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-th/strings.xml b/packages/CredentialManager/wear/res/values-th/strings.xml
new file mode 100644
index 0000000..5d4f799
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-th/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"ใช้พาสคีย์ไหม"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"ใช้รหัสผ่านไหม"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"ปิด"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"ต่อไป"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"ตัวเลือกการลงชื่อเข้าใช้"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"ตัวเลือกการลงชื่อเข้าใช้"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"จัดการการลงชื่อเข้าใช้"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"เลือกการลงชื่อเข้าใช้"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"เลือกพาสคีย์"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"เลือกรหัสผ่าน"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"ลงชื่อเข้าใช้บนโทรศัพท์"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"ไม่มีข้อมูลการลงชื่อเข้าใช้"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"แตะเพื่อปลดล็อก"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-tl/strings.xml b/packages/CredentialManager/wear/res/values-tl/strings.xml
new file mode 100644
index 0000000..bd3e672
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-tl/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Credential Manager"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"Gamitin ang passkey?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"Gamitin ang password?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"I-dismiss"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"Magpatuloy"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Mga Opsyon sa Pag-sign in"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"Mga Opsyon sa Pag-sign in"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"Pamahalaan ang mga pag-sign in"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Pumili ng pag-sign in"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"Pumili ng passkey"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"Pumili ng password"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Mag-sign in sa telepono"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Walang impormasyon sa pag-sign in"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"I-tap para i-unlock"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-ur/strings.xml b/packages/CredentialManager/wear/res/values-ur/strings.xml
new file mode 100644
index 0000000..60bf163
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-ur/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"اسناد مینیجر"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"پاس کی کا استعمال کریں؟"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"پاس ورڈ کا استعمال کریں؟"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"برخاست کریں"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"جاری رکھیں"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"سائن ان کے اختیارات"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"سائن ان کے اختیارات"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"سائن انز کا نظم کریں"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"سائن ان کا انتخاب کریں"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"پاس کی کا انتخاب کریں"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"پاس ورڈ منتخب کریں"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"فون پر سائن ان کریں"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"سائن ان کی کوئی معلومات نہیں"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"غیر مقفل کرنے کیلئے تھپتھپائیں"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-uz/strings.xml b/packages/CredentialManager/wear/res/values-uz/strings.xml
new file mode 100644
index 0000000..3b630c7
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-uz/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Hisob maʼlumotlari boshqaruvi"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"Kirish kaliti ishlatilsinmi?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"Parol ishlatilsinmi?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"Yopish"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"Davom etish"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Kirish parametrlari"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"Kirish parametrlari"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"Kirishni boshqarish"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Kirish axborotini tanlash"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"Kalit tanlash"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"Parol tanlash"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Telefonda hisobga kirish"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Kirish axboroti topilmadi"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Qulfni ochish uchun bosing"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-vi/strings.xml b/packages/CredentialManager/wear/res/values-vi/strings.xml
new file mode 100644
index 0000000..476d9bc
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-vi/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"Trình quản lý thông tin xác thực"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"Dùng khoá truy cập?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"Dùng mật khẩu?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"Đóng"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"Tiếp tục"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"Phương thức đăng nhập"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"Phương thức đăng nhập"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"Quản lý thông tin đăng nhập"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"Chọn một phương thức đăng nhập"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"Chọn khoá truy cập"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"Chọn mật khẩu"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"Đăng nhập trên điện thoại"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"Không có thông tin đăng nhập"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"Nhấn để mở khoá"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/res/values-zh-rHK/strings.xml b/packages/CredentialManager/wear/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..4e04849
--- /dev/null
+++ b/packages/CredentialManager/wear/res/values-zh-rHK/strings.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  ~ Copyright (C) 2023 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+   -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name" msgid="7384524142163511792">"憑證管理工具"</string>
+    <string name="use_passkey_title" msgid="716598039340757817">"要使用密鑰嗎?"</string>
+    <string name="use_password_title" msgid="4655101984031246476">"要使用密碼嗎?"</string>
+    <string name="dialog_dismiss_button" msgid="989567669882005067">"關閉"</string>
+    <string name="dialog_continue_button" msgid="8630290044077052145">"繼續"</string>
+    <string name="dialog_sign_in_options_button" msgid="448002958902615054">"登入方式"</string>
+    <string name="sign_in_options_title" msgid="6720572645638986680">"登入方式"</string>
+    <string name="provider_list_title" msgid="6803918216129492212">"管理登入方式"</string>
+    <string name="choose_sign_in_title" msgid="3616025924746872202">"選擇登入憑證"</string>
+    <string name="choose_passkey_title" msgid="8459270617632817465">"選擇密鑰"</string>
+    <string name="choose_password_title" msgid="7610721820858017214">"選擇密碼"</string>
+    <string name="sign_in_on_phone_button" msgid="7618621977586522403">"在手機上登入"</string>
+    <string name="locked_credential_entry_label_subtext_no_sign_in" msgid="1733094937495140605">"沒有登入資料"</string>
+    <string name="locked_credential_entry_label_subtext_tap_to_unlock" msgid="4320941096211904568">"輕按即可解鎖"</string>
+</resources>
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorActivity.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorActivity.kt
index 5728c8c..35addb3 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorActivity.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/CredentialSelectorActivity.kt
@@ -24,7 +24,6 @@
 import androidx.activity.viewModels
 import com.android.credentialmanager.ui.theme.WearCredentialSelectorTheme
 import com.android.credentialmanager.ui.WearApp
-import com.google.android.horologist.annotations.ExperimentalHorologistApi
 import dagger.hilt.android.AndroidEntryPoint
 
 @AndroidEntryPoint(ComponentActivity::class)
@@ -32,7 +31,6 @@
 
     private val viewModel: CredentialSelectorViewModel by viewModels()
 
-    @OptIn(ExperimentalHorologistApi::class)
     override fun onCreate(savedInstanceState: Bundle?) {
         Log.d(TAG, "onCreate, intent: $intent")
         super.onCreate(savedInstanceState)
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/CredentialsScreenChip.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/CredentialsScreenChip.kt
index c641d7f..25bc381 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/CredentialsScreenChip.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/CredentialsScreenChip.kt
@@ -15,6 +15,7 @@
  */
 package com.android.credentialmanager.ui.components
 
+import androidx.wear.compose.material.MaterialTheme as WearMaterialTheme
 import androidx.compose.foundation.layout.Row
 import androidx.compose.material3.Icon
 import android.graphics.drawable.Drawable
@@ -22,7 +23,11 @@
 import androidx.compose.foundation.layout.RowScope
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.Lock
+import androidx.compose.material.icons.outlined.LockOpen
 import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.tooling.preview.Preview
@@ -46,7 +51,7 @@
     onClick: () -> Unit,
     secondaryLabel: String? = null,
     icon: Drawable? = null,
-    isAuthenticationEntryLocked: Boolean = false,
+    isAuthenticationEntryLocked: Boolean? = null,
     textAlign: TextAlign = TextAlign.Center,
     modifier: Modifier = Modifier,
     colors: ChipColors = ChipDefaults.secondaryChipColors()
@@ -77,7 +82,7 @@
     text: @Composable () -> Unit,
     secondaryLabel: String? = null,
     icon: Drawable? = null,
-    isAuthenticationEntryLocked: Boolean = false,
+    isAuthenticationEntryLocked: Boolean? = null,
     modifier: Modifier = Modifier,
     colors: ChipColors = ChipDefaults.primaryChipColors(),
     ) {
@@ -94,16 +99,23 @@
                         text = secondaryLabel,
                     )
 
-                    if (isAuthenticationEntryLocked)
-                    // TODO(b/324465527) change this to lock icon and correct size once figma mocks are
-                    // updated
-                        Icon(
-                            bitmap = checkNotNull(icon?.toBitmap()?.asImageBitmap()),
-                            // Decorative purpose only.
-                            contentDescription = null,
-                            modifier = Modifier.size(10.dp),
-                            tint = Color.Unspecified
-                        )
+                    if (isAuthenticationEntryLocked != null) {
+                        if (isAuthenticationEntryLocked) {
+                            Icon(
+                                Icons.Outlined.Lock,
+                                contentDescription = null,
+                                modifier = Modifier.size(12.dp).align(Alignment.CenterVertically),
+                                tint = WearMaterialTheme.colors.onSurfaceVariant
+                            )
+                        } else {
+                            Icon(
+                                Icons.Outlined.LockOpen,
+                                contentDescription = null,
+                                modifier = Modifier.size(12.dp).align(Alignment.CenterVertically),
+                                tint = WearMaterialTheme.colors.onSurfaceVariant
+                            )
+                        }
+                    }
                 }
             }
         }
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/Texts.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/Texts.kt
index 22f6bf0..282fea0 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/Texts.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/components/Texts.kt
@@ -22,7 +22,6 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.text.TextLayoutResult
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.unit.dp
@@ -57,7 +56,6 @@
     text: String,
     textAlign: TextAlign = TextAlign.Center,
     modifier: Modifier = Modifier,
-    onTextLayout: (TextLayoutResult) -> Unit = {},
 ) {
     Text(
         modifier = modifier.padding(start = 8.dp, end = 8.dp).wrapContentSize(),
@@ -67,7 +65,6 @@
         overflow = TextOverflow.Ellipsis,
         textAlign = textAlign,
         maxLines = 2,
-        onTextLayout = onTextLayout,
     )
 }
 
@@ -79,7 +76,6 @@
     maxLines: Int = 1,
     modifier: Modifier = Modifier,
     color: Color = WearMaterialTheme.colors.onSurface,
-    onTextLayout: (TextLayoutResult) -> Unit = {},
 ) {
     Text(
         modifier = modifier.wrapContentSize(),
@@ -89,7 +85,6 @@
         overflow = TextOverflow.Ellipsis,
         textAlign = textAlign,
         maxLines = maxLines,
-        onTextLayout = onTextLayout,
     )
 }
 
@@ -97,7 +92,6 @@
 fun WearSecondaryLabel(
     text: String,
     modifier: Modifier = Modifier,
-    onTextLayout: (TextLayoutResult) -> Unit = {},
 ) {
     Text(
         modifier = modifier.wrapContentSize(),
@@ -107,6 +101,5 @@
         overflow = TextOverflow.Ellipsis,
         textAlign = TextAlign.Start,
         maxLines = 1,
-        onTextLayout = onTextLayout,
     )
 }
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt
index 473094c..2656275 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/mappers/CredentialSelectorUiStateGetMapper.kt
@@ -43,7 +43,8 @@
 
             var icon: Drawable? = null
             // provide icon if all entries have the same provider
-            if (sortedEntries.all {it.providerId == sortedEntries[0].providerId}) {
+            if (sortedEntries.isNotEmpty() &&
+                sortedEntries.all {it.providerId == sortedEntries[0].providerId}) {
                 icon = providerInfos[0].icon
             }
 
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFlattenScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFlattenScreen.kt
index fb81e73..36e9792 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFlattenScreen.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFlattenScreen.kt
@@ -75,7 +75,10 @@
                     CredentialsScreenChip(
                         label = credential.userName,
                         onClick = { selectEntry(credential, false) },
-                        secondaryLabel = credential.credentialTypeDisplayName,
+                        secondaryLabel =
+                        credential.credentialTypeDisplayName.ifEmpty {
+                            credential.providerDisplayName
+                         },
                         icon = credential.icon,
                         textAlign = TextAlign.Start
                     )
diff --git a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFoldScreen.kt b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFoldScreen.kt
index 7addc74..ce2bad0 100644
--- a/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFoldScreen.kt
+++ b/packages/CredentialManager/wear/src/com/android/credentialmanager/ui/screens/multiple/MultiCredentialsFoldScreen.kt
@@ -61,13 +61,12 @@
         val credentials = credentialSelectorUiState.sortedEntries
         item {
             var title = stringResource(R.string.choose_sign_in_title)
-
-            if (credentials.isEmpty()) {
-                title = stringResource(R.string.choose_sign_in_title)
-            } else if (credentials.all{ it.credentialType == CredentialType.PASSKEY }) {
-                title = stringResource(R.string.choose_passkey_title)
-            } else if (credentials.all { it.credentialType == CredentialType.PASSWORD }) {
-                title = stringResource(R.string.choose_password_title)
+            if (credentials.isNotEmpty()) {
+                if (credentials.all { it.credentialType == CredentialType.PASSKEY }) {
+                    title = stringResource(R.string.choose_passkey_title)
+                } else if (credentials.all { it.credentialType == CredentialType.PASSWORD }) {
+                    title = stringResource(R.string.choose_password_title)
+                }
             }
 
             SignInHeader(
@@ -77,16 +76,19 @@
         }
 
         credentials.forEach { credential: CredentialEntryInfo ->
-            item {
-                CredentialsScreenChip(
-                    label = credential.userName,
-                    onClick = { selectEntry(credential, false) },
-                    secondaryLabel = credential.credentialTypeDisplayName,
-                    icon = credential.icon,
-                )
-                CredentialsScreenChipSpacer()
+                item {
+                    CredentialsScreenChip(
+                        label = credential.userName,
+                        onClick = { selectEntry(credential, false) },
+                        secondaryLabel =
+                        credential.credentialTypeDisplayName.ifEmpty {
+                            credential.providerDisplayName
+                        },
+                        icon = credential.icon,
+                    )
+                    CredentialsScreenChipSpacer()
+                }
             }
-        }
 
         credentialSelectorUiState.authenticationEntryList.forEach { authenticationEntryInfo ->
             item {
@@ -96,7 +98,6 @@
                 CredentialsScreenChipSpacer()
             }
         }
-
         item {
             Spacer(modifier = Modifier.size(8.dp))
         }
diff --git a/packages/CtsShim/apk/riscv64/CtsShim.apk b/packages/CtsShim/apk/riscv64/CtsShim.apk
index af306a5..5ab190d 100644
--- a/packages/CtsShim/apk/riscv64/CtsShim.apk
+++ b/packages/CtsShim/apk/riscv64/CtsShim.apk
Binary files differ
diff --git a/packages/CtsShim/apk/riscv64/CtsShimPriv.apk b/packages/CtsShim/apk/riscv64/CtsShimPriv.apk
index 9a9997d..441f86f 100644
--- a/packages/CtsShim/apk/riscv64/CtsShimPriv.apk
+++ b/packages/CtsShim/apk/riscv64/CtsShimPriv.apk
Binary files differ
diff --git a/packages/InputDevices/AndroidManifest.xml b/packages/InputDevices/AndroidManifest.xml
index da8c0d3..01b0bc7 100644
--- a/packages/InputDevices/AndroidManifest.xml
+++ b/packages/InputDevices/AndroidManifest.xml
@@ -19,5 +19,23 @@
             <meta-data android:name="android.hardware.input.metadata.KEYBOARD_LAYOUTS"
                     android:resource="@xml/keyboard_layouts" />
         </receiver>
+
+        <receiver android:name=".KeyGlyphMapProvider"
+                  android:exported="true">
+            <intent-filter>
+                <action android:name="android.hardware.input.action.QUERY_KEYBOARD_GLYPH_MAPS" />
+            </intent-filter>
+            <meta-data android:name="android.hardware.input.metadata.KEYBOARD_GLYPH_MAPS"
+                       android:resource="@xml/keyboard_glyph_maps" />
+        </receiver>
+
+        <receiver android:name=".OverlayKeyGlyphMapProvider"
+                  android:exported="true">
+            <intent-filter>
+                <action android:name="android.hardware.input.action.QUERY_KEYBOARD_GLYPH_MAPS" />
+            </intent-filter>
+            <meta-data android:name="android.hardware.input.metadata.KEYBOARD_GLYPH_MAPS"
+                       android:resource="@xml/keyboard_glyph_maps_overlay" />
+        </receiver>
     </application>
 </manifest>
diff --git a/packages/InputDevices/res/values-en-rCA/strings.xml b/packages/InputDevices/res/values-en-rCA/strings.xml
index 74fd7c5..3fa4bce 100644
--- a/packages/InputDevices/res/values-en-rCA/strings.xml
+++ b/packages/InputDevices/res/values-en-rCA/strings.xml
@@ -54,8 +54,6 @@
     <string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"Thai (Pattachote)"</string>
     <string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"Serbian (Latin)"</string>
     <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"Montenegrin (Latin)"</string>
-    <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
-    <skip />
-    <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
-    <skip />
+    <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"Serbian (Cyrillic)"</string>
+    <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"Montenegrin (Cyrillic)"</string>
 </resources>
diff --git a/packages/InputDevices/res/values-en-rXC/strings.xml b/packages/InputDevices/res/values-en-rXC/strings.xml
index 777d939..2ae35ab 100644
--- a/packages/InputDevices/res/values-en-rXC/strings.xml
+++ b/packages/InputDevices/res/values-en-rXC/strings.xml
@@ -54,8 +54,6 @@
     <string name="keyboard_layout_thai_pattachote" msgid="2547992342794252205">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‏‏‎‎‎‏‎‎‏‎‎‏‏‎‎‏‎‏‎‏‎‏‎‏‎‏‎‏‎‏‏‏‏‏‎‏‎‏‏‎‏‎Thai (Pattachote)‎‏‎‎‏‎"</string>
     <string name="keyboard_layout_serbian_latin" msgid="3128791759390046571">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‏‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‎‏‏‏‎‎‏‏‎‎‏‎‏‎‎‏‏‏‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‏‎Serbian (Latin)‎‏‎‎‏‎"</string>
     <string name="keyboard_layout_montenegrin_latin" msgid="1467832503378949945">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‏‎‎‏‎‏‏‎‏‏‏‎‎‏‏‏‎‎‏‎Montenegrin (Latin)‎‏‎‎‏‎"</string>
-    <!-- no translation found for keyboard_layout_serbian_cyrillic (7013541044323542196) -->
-    <skip />
-    <!-- no translation found for keyboard_layout_montenegrin_cyrillic (2391253952894077421) -->
-    <skip />
+    <string name="keyboard_layout_serbian_cyrillic" msgid="7013541044323542196">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‏‎‏‎‎‎‏‏‎‏‎‎‏‏‎‏‎‏‏‏‎‏‎‎‏‎‎‏‎‎‎‎‏‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎‏‎‎‎Serbian (Cyrillic)‎‏‎‎‏‎"</string>
+    <string name="keyboard_layout_montenegrin_cyrillic" msgid="2391253952894077421">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‏‏‎‎‏‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‎‎‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎Montenegrin (Cyrillic)‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/InputDevices/res/xml/keyboard_glyph_maps.xml b/packages/InputDevices/res/xml/keyboard_glyph_maps.xml
new file mode 100644
index 0000000..b7a6f3f
--- /dev/null
+++ b/packages/InputDevices/res/xml/keyboard_glyph_maps.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<keyboard-glyph-maps xmlns:android="http://schemas.android.com/apk/res/android">
+<!--    <key-glyph-map-->
+<!--        android:glyphMap="@xml/xyz_glyph_map"-->
+<!--        android:vendorId="0x1234"-->
+<!--        android:productId="0x3456" />-->
+</keyboard-glyph-maps>
\ No newline at end of file
diff --git a/packages/InputDevices/res/xml/keyboard_glyph_maps_overlay.xml b/packages/InputDevices/res/xml/keyboard_glyph_maps_overlay.xml
new file mode 100644
index 0000000..7c036eb
--- /dev/null
+++ b/packages/InputDevices/res/xml/keyboard_glyph_maps_overlay.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<keyboard-glyph-maps xmlns:android="http://schemas.android.com/apk/res/android">
+<!-- NOTE: This is reserved for glyph maps to be provided using RRO. For providing glyph maps in
+     AOSP use key_glyph_maps.xml instead -->
+</keyboard-glyph-maps>
\ No newline at end of file
diff --git a/packages/InputDevices/src/com/android/inputdevices/KeyGlyphMapProvider.java b/packages/InputDevices/src/com/android/inputdevices/KeyGlyphMapProvider.java
new file mode 100644
index 0000000..6b508dd
--- /dev/null
+++ b/packages/InputDevices/src/com/android/inputdevices/KeyGlyphMapProvider.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.inputdevices;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class KeyGlyphMapProvider extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        // Nothing to do at this time.
+    }
+}
diff --git a/packages/InputDevices/src/com/android/inputdevices/OverlayKeyGlyphMapProvider.java b/packages/InputDevices/src/com/android/inputdevices/OverlayKeyGlyphMapProvider.java
new file mode 100644
index 0000000..13b5b42
--- /dev/null
+++ b/packages/InputDevices/src/com/android/inputdevices/OverlayKeyGlyphMapProvider.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.inputdevices;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class OverlayKeyGlyphMapProvider extends BroadcastReceiver {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        // Nothing to do at this time.
+    }
+}
diff --git a/packages/PackageInstaller/Android.bp b/packages/PackageInstaller/Android.bp
index 79c810c..bd84b58 100644
--- a/packages/PackageInstaller/Android.bp
+++ b/packages/PackageInstaller/Android.bp
@@ -46,7 +46,6 @@
     sdk_version: "system_current",
     rename_resources_package: false,
     static_libs: [
-        "xz-java",
         "androidx.leanback_leanback",
         "androidx.annotation_annotation",
         "androidx.fragment_fragment",
@@ -79,7 +78,6 @@
     overrides: ["PackageInstaller"],
 
     static_libs: [
-        "xz-java",
         "androidx.leanback_leanback",
         "androidx.fragment_fragment",
         "androidx.lifecycle_lifecycle-livedata",
@@ -112,7 +110,6 @@
     overrides: ["PackageInstaller"],
 
     static_libs: [
-        "xz-java",
         "androidx.leanback_leanback",
         "androidx.annotation_annotation",
         "androidx.fragment_fragment",
diff --git a/packages/PackageInstaller/AndroidManifest.xml b/packages/PackageInstaller/AndroidManifest.xml
index 4437475..68443a7 100644
--- a/packages/PackageInstaller/AndroidManifest.xml
+++ b/packages/PackageInstaller/AndroidManifest.xml
@@ -147,17 +147,6 @@
                 android:configChanges="mnc|mnc|touchscreen|navigation|screenLayout|screenSize|smallestScreenSize|orientation|locale|keyboard|keyboardHidden|fontScale|uiMode|layoutDirection|density"
                 android:exported="false" />
 
-        <!-- Wearable Components -->
-        <service android:name=".wear.WearPackageInstallerService"
-                 android:permission="com.google.android.permission.INSTALL_WEARABLE_PACKAGES"
-                 android:foregroundServiceType="systemExempted"
-                 android:exported="true"/>
-
-        <provider android:name=".wear.WearPackageIconProvider"
-                  android:authorities="com.google.android.packageinstaller.wear.provider"
-                  android:grantUriPermissions="true"
-                  android:exported="false" />
-
         <receiver android:name="androidx.profileinstaller.ProfileInstallReceiver"
             tools:node="remove" />
 
diff --git a/packages/PackageInstaller/res/layout/install_content_view.xml b/packages/PackageInstaller/res/layout/install_content_view.xml
index 524a88a..affcca1 100644
--- a/packages/PackageInstaller/res/layout/install_content_view.xml
+++ b/packages/PackageInstaller/res/layout/install_content_view.xml
@@ -34,7 +34,7 @@
     <TextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        style="@android:style/TextAppearance.Material.Subhead"
+        style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
         android:text="@string/message_staging" />
 
     <ProgressBar
@@ -57,7 +57,7 @@
     <TextView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        style="@android:style/TextAppearance.Material.Subhead"
+        style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
         android:text="@string/installing" />
 
     <ProgressBar
@@ -74,7 +74,7 @@
       android:id="@+id/install_confirm_question"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
-      style="@android:style/TextAppearance.Material.Subhead"
+      style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
       android:text="@string/install_confirm_question"
       android:visibility="invisible"
       android:scrollbars="vertical" />
@@ -83,7 +83,7 @@
       android:id="@+id/install_confirm_question_update"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
-      style="@android:style/TextAppearance.Material.Subhead"
+      style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
       android:text="@string/install_confirm_question_update"
       android:visibility="invisible"
       android:scrollbars="vertical" />
@@ -92,7 +92,7 @@
       android:id="@+id/install_success"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
-      style="@android:style/TextAppearance.Material.Subhead"
+      style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
       android:text="@string/install_done"
       android:visibility="invisible" />
 
@@ -100,7 +100,7 @@
       android:id="@+id/install_failed"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
-      style="@android:style/TextAppearance.Material.Subhead"
+      style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
       android:text="@string/install_failed"
       android:visibility="invisible" />
 
@@ -108,7 +108,7 @@
       android:id="@+id/install_failed_blocked"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
-      style="@android:style/TextAppearance.Material.Subhead"
+      style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
       android:text="@string/install_failed_blocked"
       android:visibility="invisible" />
 
@@ -116,7 +116,7 @@
       android:id="@+id/install_failed_conflict"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
-      style="@android:style/TextAppearance.Material.Subhead"
+      style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
       android:text="@string/install_failed_conflict"
       android:visibility="invisible" />
 
@@ -124,7 +124,7 @@
       android:id="@+id/install_failed_incompatible"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
-      style="@android:style/TextAppearance.Material.Subhead"
+      style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
       android:text="@string/install_failed_incompatible"
       android:visibility="invisible" />
 
@@ -132,7 +132,7 @@
       android:id="@+id/install_failed_invalid_apk"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
-      style="@android:style/TextAppearance.Material.Subhead"
+      style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
       android:text="@string/install_failed_invalid_apk"
       android:visibility="invisible" />
 
diff --git a/packages/PackageInstaller/res/layout/uninstall_content_view.xml b/packages/PackageInstaller/res/layout/uninstall_content_view.xml
index 434e333..d5c5d8b 100644
--- a/packages/PackageInstaller/res/layout/uninstall_content_view.xml
+++ b/packages/PackageInstaller/res/layout/uninstall_content_view.xml
@@ -22,32 +22,32 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content">
 
-  <LinearLayout
-      xmlns:android="http://schemas.android.com/apk/res/android"
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:theme="?android:attr/alertDialogTheme"
-      android:orientation="vertical"
-      android:paddingTop="8dp"
-      android:paddingStart="?android:attr/dialogPreferredPadding"
-      android:paddingEnd="?android:attr/dialogPreferredPadding"
-      android:clipToPadding="false">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:theme="?android:attr/alertDialogTheme"
+        android:orientation="vertical"
+        android:paddingTop="8dp"
+        android:paddingStart="?android:attr/dialogPreferredPadding"
+        android:paddingEnd="?android:attr/dialogPreferredPadding"
+        android:clipToPadding="false">
 
-      <TextView
-          android:id="@+id/message"
-          android:layout_width="match_parent"
-          android:layout_height="wrap_content"
-          style="@android:style/TextAppearance.Material.Subhead" />
+        <TextView
+            android:id="@+id/message"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle" />
 
-      <CheckBox
-          android:id="@+id/keepData"
-          android:layout_width="wrap_content"
-          android:layout_height="wrap_content"
-          android:layout_marginTop="8dp"
-          android:layout_marginStart="-8dp"
-          android:paddingLeft="8sp"
-          android:visibility="gone"
-          style="@android:style/TextAppearance.Material.Subhead" />
+        <CheckBox
+            android:id="@+id/keepData"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="8dp"
+            android:layout_marginStart="-8dp"
+            android:paddingStart="8sp"
+            android:paddingEnd="0sp"
+            android:visibility="gone"
+            style="@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle" />
 
-  </LinearLayout>
+    </LinearLayout>
 </ScrollView>
diff --git a/packages/PackageInstaller/res/values-fr-rCA/strings.xml b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
index 60075e6..2e42339 100644
--- a/packages/PackageInstaller/res/values-fr-rCA/strings.xml
+++ b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
@@ -23,55 +23,55 @@
     <string name="cancel" msgid="1018267193425558088">"Annuler"</string>
     <string name="installing" msgid="4921993079741206516">"Installation en cours…"</string>
     <string name="installing_app" msgid="1165095864863849422">"Installation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> en cours…"</string>
-    <string name="install_done" msgid="5987363587661783896">"Application installée."</string>
-    <string name="install_confirm_question" msgid="7663733664476363311">"Voulez-vous installer cette application?"</string>
-    <string name="install_confirm_question_update" msgid="3348888852318388584">"Voulez-vous mettre à jour cette application?"</string>
-    <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"&lt;p&gt;Mettre à jour cette application à partir de &lt;b&gt;<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>&lt;/b&gt;?&lt;/p&gt;&lt;p&gt;Cette application reçoit normalement des mises à jour de &lt;b&gt;<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>&lt;/b&gt;. En effectuant une mise à jour à partir d\'une source différente, vous pourriez recevoir des mises à jour futures à partir de n\'importe quelle source sur votre tablette. Le fonctionnement de l\'application peut en être modifié.&lt;/p&gt;"</string>
-    <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"&lt;p&gt;Mettre à jour cette application à partir de &lt;b&gt;<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>&lt;/b&gt;?&lt;/p&gt;&lt;p&gt;Cette application reçoit normalement des mises à jour de &lt;b&gt;<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>&lt;/b&gt;. En effectuant une mise à jour à partir d\'une source différente, vous pourriez recevoir des mises à jour futures à partir de n\'importe quelle source sur votre téléviseur. Le fonctionnement de l\'application peut en être modifié.&lt;/p&gt;"</string>
-    <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"&lt;p&gt;Mettre à jour cette application à partir de &lt;b&gt;<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>&lt;/b&gt;?&lt;/p&gt;&lt;p&gt;Cette application reçoit normalement des mises à jour de &lt;b&gt;<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>&lt;/b&gt;. En effectuant une mise à jour à partir d\'une source différente, vous pourriez recevoir des mises à jour futures à partir de n\'importe quelle source sur votre téléphone. Le fonctionnement de l\'application peut en être modifié.&lt;/p&gt;"</string>
-    <string name="install_failed" msgid="5777824004474125469">"Application non installée."</string>
+    <string name="install_done" msgid="5987363587661783896">"Appli installée."</string>
+    <string name="install_confirm_question" msgid="7663733664476363311">"Voulez-vous installer cette appli?"</string>
+    <string name="install_confirm_question_update" msgid="3348888852318388584">"Voulez-vous mettre à jour cette appli?"</string>
+    <string name="install_confirm_question_update_owner_reminder" product="tablet" msgid="7994800761970572198">"&lt;p&gt;Mettre à jour cette appli à partir de &lt;b&gt;<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>&lt;/b&gt;?&lt;/p&gt;&lt;p&gt;Cette appli reçoit normalement des mises à jour de &lt;b&gt;<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>&lt;/b&gt;. En effectuant une mise à jour à partir d\'une source différente, vous pourriez recevoir des mises à jour futures à partir de n\'importe quelle source sur votre tablette. Le fonctionnement de l\'appli peut en être modifié.&lt;/p&gt;"</string>
+    <string name="install_confirm_question_update_owner_reminder" product="tv" msgid="2435174886412089791">"&lt;p&gt;Mettre à jour cette appli à partir de &lt;b&gt;<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>&lt;/b&gt;?&lt;/p&gt;&lt;p&gt;Cette appli reçoit normalement des mises à jour de &lt;b&gt;<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>&lt;/b&gt;. En effectuant une mise à jour à partir d\'une source différente, vous pourriez recevoir des mises à jour futures à partir de n\'importe quelle source sur votre téléviseur. Le fonctionnement de l\'appli peut en être modifié.&lt;/p&gt;"</string>
+    <string name="install_confirm_question_update_owner_reminder" product="default" msgid="7155138616126795839">"&lt;p&gt;Mettre à jour cette appli à partir de &lt;b&gt;<xliff:g id="NEW_UPDATE_OWNER">%1$s</xliff:g>&lt;/b&gt;?&lt;/p&gt;&lt;p&gt;Cette appli reçoit normalement des mises à jour de &lt;b&gt;<xliff:g id="EXISTING_UPDATE_OWNER">%2$s</xliff:g>&lt;/b&gt;. En effectuant une mise à jour à partir d\'une source différente, vous pourriez recevoir des mises à jour futures à partir de n\'importe quelle source sur votre téléphone. Le fonctionnement de l\'appli peut en être modifié.&lt;/p&gt;"</string>
+    <string name="install_failed" msgid="5777824004474125469">"Appli non installée."</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"L\'installation du paquet a été bloquée."</string>
-    <string name="install_failed_conflict" msgid="3493184212162521426">"L\'application n\'a pas été installée, car le paquet entre en conflit avec un paquet existant."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"L\'application n\'a pas été installée, car elle n\'est pas compatible avec votre tablette."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Cette application n\'est pas compatible avec votre téléviseur."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"L\'application n\'a pas été installée, car elle n\'est pas compatible avec votre téléphone."</string>
-    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"L\'application n\'a pas été installée, car elle ne semble pas être valide."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"L\'appli n\'a pas été installée, car le paquet entre en conflit avec un paquet existant."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"L\'appli n\'a pas été installée, car elle n\'est pas compatible avec votre tablette."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Cette appli n\'est pas compatible avec votre téléviseur."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"L\'appli n\'a pas été installée, car elle n\'est pas compatible avec votre téléphone."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"L\'appli n\'a pas été installée, car elle ne semble pas être valide."</string>
     <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g> sur votre tablette."</string>
     <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'a pas pu être installée sur votre téléviseur."</string>
     <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g> sur votre téléphone."</string>
     <string name="launch" msgid="3952550563999890101">"Ouvrir"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Votre administrateur n\'autorise pas l\'installation d\'applications obtenues à partir de sources inconnues"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Cet utilisateur ne peut pas installer d\'applications inconnues"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Cet utilisateur n\'est pas autorisé à installer des applications"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Votre administrateur n\'autorise pas l\'installation d\'applis obtenues à partir de sources inconnues"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Cet utilisateur ne peut pas installer d\'applis inconnues"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Cet utilisateur n\'est pas autorisé à installer des applis"</string>
     <string name="ok" msgid="7871959885003339302">"OK"</string>
     <string name="archive" msgid="4447791830199354721">"Archiver"</string>
     <string name="update_anyway" msgid="8792432341346261969">"Mettre à jour malgré tout"</string>
     <string name="manage_applications" msgid="5400164782453975580">"Gérer les applis"</string>
     <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Espace insuffisant"</string>
     <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g>. Veuillez libérer de l\'espace, puis réessayer."</string>
-    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Application non trouvée"</string>
-    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"L\'application ne figure pas dans la liste des applications installées."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Appli non trouvée"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"L\'appli ne figure pas dans la liste des applis installées."</string>
     <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Non autorisée"</string>
     <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"L\'utilisateur actuel n\'est pas autorisé à effectuer cette désinstallation."</string>
     <string name="generic_error_dlg_title" msgid="5863195085927067752">"Erreur"</string>
-    <string name="generic_error_dlg_text" msgid="5287861443265795232">"L\'application n\'a pas pu être désinstallée."</string>
-    <string name="uninstall_application_title" msgid="4045420072401428123">"Désinstaller l\'application"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"L\'appli n\'a pas pu être désinstallée."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Désinstaller l\'appli"</string>
     <string name="uninstall_update_title" msgid="824411791011583031">"Désinstaller mise à jour"</string>
-    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> fait partie de l\'application suivante :"</string>
-    <string name="uninstall_application_text" msgid="3816830743706143980">"Voulez-vous désinstaller cette application?"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> fait partie de l\'appli suivante :"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Voulez-vous désinstaller cette appli?"</string>
     <string name="archive_application_text" msgid="8482325710714386348">"Vos données personnelles seront enregistrées"</string>
-    <string name="archive_application_text_all_users" msgid="3151229641681672580">"Archiver cette application pour tous les utilisateurs? Vos données personnelles seront enregistrées"</string>
-    <string name="archive_application_text_current_user_work_profile" msgid="1450487362134779752">"Archiver cette application sur votre profil professionnel? Vos données personnelles seront enregistrées"</string>
-    <string name="archive_application_text_user" msgid="2586558895535581451">"Archiver cette application pour <xliff:g id="USERNAME">%1$s</xliff:g>? Vos données personnelles seront enregistrées"</string>
-    <string name="archive_application_text_current_user_private_profile" msgid="1958423158655599132">"Voulez-vous archiver cette application de votre Espace privé? Vos données personnelles seront enregistrées"</string>
-    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Voulez-vous désinstaller cette application pour "<b>"tous"</b>" les utilisateurs? L\'application et ses données seront supprimées pour "<b>"tous"</b>" les utilisateurs de l\'appareil."</string>
-    <string name="uninstall_application_text_user" msgid="498072714173920526">"Voulez-vous désinstaller cette application pour l\'utilisateur <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_application_text_current_user_work_profile" msgid="8788387739022366193">"Voulez-vous désinstaller cette application de votre profil professionnel?"</string>
-    <string name="uninstall_update_text" msgid="863648314632448705">"Remplacer cette application par la version d\'usine? Toutes les données seront supprimées."</string>
-    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Remplacer cette application par la version d\'usine? Toutes les données seront supprimées. Cela touchera tous les utilisateurs de cet appareil, y compris ceux qui utilisent un profil professionnel."</string>
-    <string name="uninstall_keep_data" msgid="7002379587465487550">"Garder <xliff:g id="SIZE">%1$s</xliff:g> de données d\'application."</string>
-    <string name="uninstall_application_text_current_user_clone_profile" msgid="835170400160011636">"Voulez-vous supprimer cette application?"</string>
-    <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"Voulez-vous désinstaller cette application? Le clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sera aussi supprimé."</string>
+    <string name="archive_application_text_all_users" msgid="3151229641681672580">"Archiver cette appli pour tous les utilisateurs? Vos données personnelles seront enregistrées"</string>
+    <string name="archive_application_text_current_user_work_profile" msgid="1450487362134779752">"Archiver cette appli sur votre profil professionnel? Vos données personnelles seront enregistrées"</string>
+    <string name="archive_application_text_user" msgid="2586558895535581451">"Archiver cette appli pour <xliff:g id="USERNAME">%1$s</xliff:g>? Vos données personnelles seront enregistrées"</string>
+    <string name="archive_application_text_current_user_private_profile" msgid="1958423158655599132">"Voulez-vous archiver cette appli de votre Espace privé? Vos données personnelles seront enregistrées"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Voulez-vous désinstaller cette appli pour "<b>"tous"</b>" les utilisateurs? L\'appli et ses données seront supprimées pour "<b>"tous"</b>" les utilisateurs de l\'appareil."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Voulez-vous désinstaller cette appli pour l\'utilisateur <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_application_text_current_user_work_profile" msgid="8788387739022366193">"Voulez-vous désinstaller cette appli de votre profil professionnel?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Remplacer cette appli par la version d\'usine? Toutes les données seront supprimées."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Remplacer cette appli par la version d\'usine? Toutes les données seront supprimées. Cela touchera tous les utilisateurs de cet appareil, y compris ceux qui utilisent un profil professionnel."</string>
+    <string name="uninstall_keep_data" msgid="7002379587465487550">"Garder <xliff:g id="SIZE">%1$s</xliff:g> de données d\'appli."</string>
+    <string name="uninstall_application_text_current_user_clone_profile" msgid="835170400160011636">"Voulez-vous supprimer cette appli?"</string>
+    <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"Voulez-vous désinstaller cette appli? Le clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sera aussi supprimé."</string>
     <string name="uninstall_application_text_current_user_private_profile" msgid="867004464945674674">"Voulez-vous désinstaller cette appli de votre espace privé?"</string>
     <string name="uninstalling_notification_channel" msgid="840153394325714653">"Désinstallations en cours…"</string>
     <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Désinstallations échouées"</string>
@@ -83,47 +83,47 @@
     <string name="uninstall_failed" msgid="1847750968168364332">"Échec de la désinstallation."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"La désinstallation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> n\'a pas réussi."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"Suppression du clone <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Impossible de désinstaller une application d\'administration de l\'appareil active"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Impossible de désinstaller une application d\'administration de l\'appareil active pour <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Cette application est nécessaire pour certains utilisateurs ou profils, et elle a été désinstallée pour d\'autres"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Cette application est nécessaire pour votre profil et ne peut pas être désinstallée."</string>
-    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Imposs. de désinst. l\'application : elle est requise par l\'admin de l\'appareil."</string>
-    <string name="manage_device_administrators" msgid="3092696419363842816">"Gérer les applications d\'administration d\'appareils"</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Impossible de désinstaller une appli d\'administration de l\'appareil active"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Impossible de désinstaller une appli d\'administration de l\'appareil active pour <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Cette appli est nécessaire pour certains utilisateurs ou profils, et elle a été désinstallée pour d\'autres"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Cette appli est nécessaire pour votre profil et ne peut pas être désinstallée."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Imposs. de désinst. l\'appli : elle est requise par l\'admin de l\'appareil."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Gérer les applis d\'administration d\'appareils"</string>
     <string name="manage_users" msgid="1243995386982560813">"Gérer les utilisateurs"</string>
     <string name="uninstall_failed_msg" msgid="2176744834786696012">"Impossible de désinstaller <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Un problème est survenu lors de l\'analyse du paquet."</string>
-    <string name="message_staging" msgid="8032722385658438567">"Pré-production de l\'application en cours…"</string>
+    <string name="message_staging" msgid="8032722385658438567">"Pré-production de l\'appli en cours…"</string>
     <string name="app_name_unknown" msgid="6881210203354323926">"Inconnue"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur cette tablette. Vous pouvez modifier cette option dans les paramètres."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur ce téléviseur. Vous pouvez modifier cette option dans les paramètres."</string>
-    <string name="untrusted_external_source_warning" product="watch" msgid="7195163388090818636">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur cette montre. Vous pouvez modifier cette option dans les paramètres."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur ce téléphone. Vous pouvez modifier cette option dans les paramètres."</string>
-    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Votre téléphone et vos données personnelles sont plus vulnérables aux attaques provenant d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléphone ou de toute perte de données pouvant découler de l\'utilisation de telles applications."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Votre tablette et vos données personnelles sont plus vulnérables aux attaques provenant d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre tablette ou de toute perte de données pouvant découler de l\'utilisation de telles applications."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Votre téléviseur et vos données personnelles sont plus vulnérables aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléviseur ou de toute perte de données pouvant découler de son utilisation."</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="7067510047443133095">"À des fins de sécurité, l\'installation d\'applis inconnues provenant de cette source n\'est pas autorisée sur cette tablette. Vous pouvez modifier cette option dans les paramètres."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="7057271609532508035">"À des fins de sécurité, l\'installation d\'applis inconnues provenant de cette source n\'est pas autorisée sur ce téléviseur. Vous pouvez modifier cette option dans les paramètres."</string>
+    <string name="untrusted_external_source_warning" product="watch" msgid="7195163388090818636">"À des fins de sécurité, l\'installation d\'applis inconnues provenant de cette source n\'est pas autorisée sur cette montre. Vous pouvez modifier cette option dans les paramètres."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="8444191224459138919">"À des fins de sécurité, l\'installation d\'applis inconnues provenant de cette source n\'est pas autorisée sur ce téléphone. Vous pouvez modifier cette option dans les paramètres."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Votre téléphone et vos données personnelles sont plus vulnérables aux attaques provenant d\'applis inconnues. En installant cette appli, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléphone ou de toute perte de données pouvant découler de l\'utilisation de telles applis."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Votre tablette et vos données personnelles sont plus vulnérables aux attaques provenant d\'applis inconnues. En installant cette appli, vous acceptez d\'être le seul responsable de tout dommage causé à votre tablette ou de toute perte de données pouvant découler de l\'utilisation de telles applis."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Votre téléviseur et vos données personnelles sont plus vulnérables aux attaques d\'applis inconnues. En installant cette appli, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléviseur ou de toute perte de données pouvant découler de son utilisation."</string>
     <string name="cloned_app_label" msgid="7503612829833756160">"Clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
     <string name="archiving_app_label" msgid="1127085259724124725">"Archiver <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>?"</string>
     <string name="anonymous_source_continue" msgid="4375745439457209366">"Continuer"</string>
     <string name="external_sources_settings" msgid="4046964413071713807">"Paramètres"</string>
     <string name="wear_app_channel" msgid="1960809674709107850">"Installer/désinstaller applis Google Wear"</string>
-    <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Notification d\'application installée"</string>
+    <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"Notification d\'appli installée"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"Installation réussie"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"Installation de « <xliff:g id="APPNAME">%1$s</xliff:g> » réussie"</string>
     <string name="unarchive_application_title" msgid="7958278328280721421">"Restaurer <xliff:g id="APPNAME">%1$s</xliff:g> à partir de <xliff:g id="INSTALLERNAME">%2$s</xliff:g>?"</string>
-    <string name="unarchive_body_text" msgid="8244155079861708964">"Le téléchargement de cette application commencera en arrière-plan"</string>
+    <string name="unarchive_body_text" msgid="8244155079861708964">"Le téléchargement de cette appli commencera en arrière-plan"</string>
     <string name="restore" msgid="8460854736328970444">"Restaurer"</string>
     <string name="unarchive_error_offline_title" msgid="4021785324565678605">"Vous êtes hors ligne"</string>
-    <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Pour restaurer cette application, vérifiez votre connexion Internet et réessayez."</string>
+    <string name="unarchive_error_offline_body" msgid="2256042209364094099">"Pour restaurer cette appli, vérifiez votre connexion Internet et réessayez."</string>
     <string name="unarchive_error_generic_title" msgid="7123457671482449992">"Un problème est survenu"</string>
-    <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Un problème est survenu lors de la restauration de cette application"</string>
+    <string name="unarchive_error_generic_body" msgid="4486803312463813079">"Un problème est survenu lors de la restauration de cette appli"</string>
     <string name="unarchive_error_storage_title" msgid="5080723357273852630">"Espace de stockage insuffisant"</string>
-    <string name="unarchive_error_storage_body" msgid="6879544407568780524">"Pour restaurer cette application, vous devez libérer de l\'espace de stockage sur cet appareil. Espace de stockage requis : <xliff:g id="BYTES">%1$s</xliff:g>"</string>
+    <string name="unarchive_error_storage_body" msgid="6879544407568780524">"Pour restaurer cette appli, vous devez libérer de l\'espace de stockage sur cet appareil. Espace de stockage requis : <xliff:g id="BYTES">%1$s</xliff:g>"</string>
     <string name="unarchive_action_required_title" msgid="4971245740162604619">"Action requise"</string>
-    <string name="unarchive_action_required_body" msgid="1679431572983989231">"Suivez les étapes suivantes pour restaurer cette application"</string>
+    <string name="unarchive_action_required_body" msgid="1679431572983989231">"Suivez les étapes suivantes pour restaurer cette appli"</string>
     <string name="unarchive_error_installer_disabled_title" msgid="4815715617014985605">"<xliff:g id="INSTALLERNAME">%1$s</xliff:g> est désactivé"</string>
-    <string name="unarchive_error_installer_disabled_body" msgid="4820821285907011729">"Pour restaurer cette application, activez <xliff:g id="INSTALLERNAME">%1$s</xliff:g> dans les paramètres"</string>
+    <string name="unarchive_error_installer_disabled_body" msgid="4820821285907011729">"Pour restaurer cette appli, activez <xliff:g id="INSTALLERNAME">%1$s</xliff:g> dans les paramètres"</string>
     <string name="unarchive_error_installer_uninstalled_title" msgid="3748354109176326489">"<xliff:g id="INSTALLERNAME">%1$s</xliff:g> est désinstallé"</string>
-    <string name="unarchive_error_installer_uninstalled_body" msgid="944733542444183204">"Pour restaurer cette application, vous devrez installer <xliff:g id="INSTALLERNAME">%1$s</xliff:g>"</string>
+    <string name="unarchive_error_installer_uninstalled_body" msgid="944733542444183204">"Pour restaurer cette appli, vous devrez installer <xliff:g id="INSTALLERNAME">%1$s</xliff:g>"</string>
     <string name="unarchive_action_required_continue" msgid="5711202111224184257">"Continuer"</string>
     <string name="unarchive_clear_storage_button" msgid="1549537154535608744">"Effacer le stockage"</string>
     <string name="unarchive_settings_button" msgid="3504171760009177425">"Paramètres"</string>
diff --git a/packages/PackageInstaller/res/values-night/themes.xml b/packages/PackageInstaller/res/values-night/themes.xml
index a5b82b3..37588ad 100644
--- a/packages/PackageInstaller/res/values-night/themes.xml
+++ b/packages/PackageInstaller/res/values-night/themes.xml
@@ -19,7 +19,6 @@
 
     <style name="Theme.AlertDialogActivity"
         parent="@android:style/Theme.DeviceDefault.Dialog.Alert">
-        <item name="alertDialogStyle">@style/AlertDialog</item>
         <item name="android:windowActionBar">false</item>
         <item name="android:windowNoTitle">true</item>
         <item name="android:windowAnimationStyle">@null</item>
diff --git a/packages/PackageInstaller/res/values/themes.xml b/packages/PackageInstaller/res/values/themes.xml
index f5af510..aa48712 100644
--- a/packages/PackageInstaller/res/values/themes.xml
+++ b/packages/PackageInstaller/res/values/themes.xml
@@ -19,7 +19,6 @@
 
     <style name="Theme.AlertDialogActivity"
         parent="@android:style/Theme.DeviceDefault.Light.Dialog.Alert">
-        <item name="alertDialogStyle">@style/AlertDialog</item>
         <item name="android:windowActionBar">false</item>
         <item name="android:windowNoTitle">true</item>
         <item name="android:windowAnimationStyle">@null</item>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
index e0398aa..824dd4a 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
@@ -330,7 +330,8 @@
             // data we still want to count it as "installed".
             mAppInfo = mPm.getApplicationInfo(pkgName,
                     PackageManager.MATCH_UNINSTALLED_PACKAGES);
-            if ((mAppInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
+            // If the package is archived, treat it as update case.
+            if (!mAppInfo.isArchived && (mAppInfo.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
                 mAppInfo = null;
             }
         } catch (NameNotFoundException e) {
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt
index 2e9b7b4..c260426 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt
@@ -95,7 +95,21 @@
      */
     var stagedSessionId = SessionInfo.INVALID_ID
         private set
+
+    /**
+     * UID of the last caller of Pia. This can point to a 3P installer if it uses intents to install
+     * an APK, or receives a
+     * [STATUS_PENDING_USER_ACTION][PackageInstaller.STATUS_PENDING_USER_ACTION] status code.
+     * It may point to Pia, when it receives the STATUS_PENDING_USER_ACTION status code in case of
+     * an update-ownership change.
+     */
     private var callingUid = Process.INVALID_UID
+
+    /**
+     * UID of the origin of the installation. This UID is used to fetch the app-label of the
+     * source of the install, and also check whether the source app has the AppOp to install other
+     * apps.
+     */
     private var originatingUid = Process.INVALID_UID
     private var callingPackage: String? = null
     private var sessionStager: SessionStager? = null
@@ -135,60 +149,60 @@
         stagedSessionId = intent.getIntExtra(EXTRA_STAGED_SESSION_ID, SessionInfo.INVALID_ID)
 
         callingPackage = callerInfo.packageName
-
-        if (sessionId != SessionInfo.INVALID_ID) {
-            val sessionInfo: SessionInfo? = packageInstaller.getSessionInfo(sessionId)
-            callingPackage = sessionInfo?.getInstallerPackageName()
-            callingAttributionTag = sessionInfo?.getInstallerAttributionTag()
-        }
-
-        // Uid of the source package, coming from ActivityManager
         callingUid = callerInfo.uid
-        if (callingUid == Process.INVALID_UID) {
-            Log.e(LOG_TAG, "Could not determine the launching uid.")
-        }
+
         val sourceInfo: ApplicationInfo? = getSourceInfo(callingPackage)
-        // Uid of the source package, with a preference to uid from ApplicationInfo
-        originatingUid = sourceInfo?.uid ?: callingUid
-        appOpRequestInfo = AppOpRequestInfo(
-            getPackageNameForUid(context, originatingUid, callingPackage),
-            originatingUid, callingAttributionTag
-        )
-
-        if(localLogv) {
-            Log.i(LOG_TAG, "Intent: $intent\n" +
-                "sessionId: $sessionId\n" +
-                "staged sessionId: $stagedSessionId\n" +
-                "calling package: $callingPackage\n" +
-                "callingUid: $callingUid\n" +
-                "originatingUid: $originatingUid")
-        }
-
         if (callingUid == Process.INVALID_UID && sourceInfo == null) {
             // Caller's identity could not be determined. Abort the install
             Log.e(LOG_TAG, "Cannot determine caller since UID is invalid and sourceInfo is null")
             return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
         }
 
+        originatingUid = callingUid
+        val sessionInfo: SessionInfo? =
+            if (sessionId != SessionInfo.INVALID_ID)
+                packageInstaller.getSessionInfo(sessionId)
+            else null
+        if (sessionInfo != null) {
+            callingAttributionTag = sessionInfo.installerAttributionTag
+            if (sessionInfo.originatingUid != Process.INVALID_UID) {
+                originatingUid = sessionInfo.originatingUid
+            }
+        }
+
+        appOpRequestInfo = AppOpRequestInfo(
+            getPackageNameForUid(context, originatingUid, callingPackage),
+            originatingUid,
+            callingAttributionTag
+        )
+
+        if (localLogv) {
+            Log.i(
+                LOG_TAG, "Intent: $intent\n" +
+                    "sessionId: $sessionId\n" +
+                    "staged sessionId: $stagedSessionId\n" +
+                    "calling package: $callingPackage\n" +
+                    "callingUid: $callingUid\n" +
+                    "originatingUid: $originatingUid\n" +
+                    "sourceInfo: $sourceInfo"
+            )
+        }
+
         if ((sessionId != SessionInfo.INVALID_ID
-                && !isCallerSessionOwner(packageInstaller, originatingUid, sessionId))
+                && !isCallerSessionOwner(packageInstaller, callingUid, sessionId))
             || (stagedSessionId != SessionInfo.INVALID_ID
                 && !isCallerSessionOwner(packageInstaller, Process.myUid(), stagedSessionId))
         ) {
-            Log.e(LOG_TAG, "UID is not the owner of the session:\n" +
-                "CallingUid: $originatingUid | SessionId: $sessionId\n" +
-                "My UID: ${Process.myUid()} | StagedSessionId: $stagedSessionId")
+            Log.e(
+                LOG_TAG, "UID is not the owner of the session:\n" +
+                    "CallingUid: $callingUid | SessionId: $sessionId\n" +
+                    "My UID: ${Process.myUid()} | StagedSessionId: $stagedSessionId"
+            )
             return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
         }
 
-        isTrustedSource = isInstallRequestFromTrustedSource(sourceInfo, this.intent, originatingUid)
-        if (!isInstallPermissionGrantedOrRequested(
-                context, callingUid, originatingUid, isTrustedSource
-            )
-        ) {
-            Log.e(LOG_TAG, "UID $originatingUid needs to declare " +
-                Manifest.permission.REQUEST_INSTALL_PACKAGES
-            )
+        isTrustedSource = isInstallRequestFromTrustedSource(sourceInfo, this.intent, callingUid)
+        if (!isInstallPermissionGrantedOrRequested(context, callingUid, isTrustedSource)) {
             return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
         }
 
@@ -196,7 +210,7 @@
         if (restriction != null) {
             val adminSupportDetailsIntent =
                 devicePolicyManager!!.createAdminSupportIntent(restriction)
-            Log.e(LOG_TAG, "$restriction set in place. Cannot install." )
+            Log.e(LOG_TAG, "$restriction set in place. Cannot install.")
             return InstallAborted(
                 ABORT_REASON_POLICY, message = restriction, resultIntent = adminSupportDetailsIntent
             )
@@ -221,12 +235,12 @@
     private fun isInstallRequestFromTrustedSource(
         sourceInfo: ApplicationInfo?,
         intent: Intent,
-        originatingUid: Int,
+        callingUid: Int,
     ): Boolean {
         val isNotUnknownSource = intent.getBooleanExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, false)
         return (sourceInfo != null && sourceInfo.isPrivilegedApp
             && (isNotUnknownSource
-            || isPermissionGranted(context, Manifest.permission.INSTALL_PACKAGES, originatingUid)))
+            || isPermissionGranted(context, Manifest.permission.INSTALL_PACKAGES, callingUid)))
     }
 
     private fun getDevicePolicyRestrictions(): String? {
@@ -311,7 +325,7 @@
                             Intent.EXTRA_INSTALL_RESULT, PackageManager.INSTALL_FAILED_INVALID_APK
                         ),
                         activityResultCode = Activity.RESULT_FIRST_USER,
-                        errorDialogType =  if (e is IOException) DLG_PACKAGE_ERROR else DLG_NONE
+                        errorDialogType = if (e is IOException) DLG_PACKAGE_ERROR else DLG_NONE
                     )
                     return
                 }
@@ -392,8 +406,9 @@
                 Log.e(LOG_TAG, "Cannot parse package $debugPathName. Assuming defaults.", e)
                 params.setSize(pfd.statSize)
             } catch (e: IOException) {
-                Log.e(LOG_TAG, "Cannot calculate installed size $debugPathName. " +
-                    "Try only apk size.", e
+                Log.e(
+                    LOG_TAG, "Cannot calculate installed size $debugPathName. " +
+                        "Try only apk size.", e
                 )
             }
         } else {
@@ -651,7 +666,11 @@
     private fun getUpdateMessage(pkgInfo: PackageInfo, userActionReason: Int): String? {
         if (isAppUpdating(pkgInfo)) {
             val existingUpdateOwnerLabel = getExistingUpdateOwnerLabel(pkgInfo)
-            val requestedUpdateOwnerLabel = getApplicationLabel(callingPackage)
+
+            val originatingPackageName =
+                getPackageNameForUid(context, originatingUid, callingPackage)
+            val requestedUpdateOwnerLabel = getApplicationLabel(originatingPackageName)
+
             if (!TextUtils.isEmpty(existingUpdateOwnerLabel)
                 && userActionReason == PackageInstaller.REASON_REMIND_OWNERSHIP
             ) {
@@ -754,14 +773,14 @@
     }
 
     private fun handleUnknownSources(requestInfo: AppOpRequestInfo): InstallStage {
-        if (requestInfo.callingPackage == null) {
+        if (requestInfo.originatingPackage == null) {
             Log.i(LOG_TAG, "No source found for package " + newPackageInfo?.packageName)
             return InstallUserActionRequired(USER_ACTION_REASON_ANONYMOUS_SOURCE)
         }
         // Shouldn't use static constant directly, see b/65534401.
         val appOpStr = AppOpsManager.permissionToOp(Manifest.permission.REQUEST_INSTALL_PACKAGES)
         val appOpMode = appOpsManager!!.noteOpNoThrow(
-            appOpStr!!, requestInfo.originatingUid, requestInfo.callingPackage,
+            appOpStr!!, requestInfo.originatingUid, requestInfo.originatingPackage,
             requestInfo.attributionTag, "Started package installation activity"
         )
         if (localLogv) {
@@ -772,20 +791,20 @@
             AppOpsManager.MODE_DEFAULT, AppOpsManager.MODE_ERRORED -> {
                 if (appOpMode == AppOpsManager.MODE_DEFAULT) {
                     appOpsManager.setMode(
-                        appOpStr, requestInfo.originatingUid, requestInfo.callingPackage,
+                        appOpStr, requestInfo.originatingUid, requestInfo.originatingPackage,
                         AppOpsManager.MODE_ERRORED
                     )
                 }
                 try {
                     val sourceInfo =
-                        packageManager.getApplicationInfo(requestInfo.callingPackage, 0)
+                        packageManager.getApplicationInfo(requestInfo.originatingPackage, 0)
                     val sourceAppSnippet = getAppSnippet(context, sourceInfo)
                     InstallUserActionRequired(
                         USER_ACTION_REASON_UNKNOWN_SOURCE, appSnippet = sourceAppSnippet,
-                        dialogMessage = requestInfo.callingPackage
+                        sourceApp = requestInfo.originatingPackage
                     )
                 } catch (e: PackageManager.NameNotFoundException) {
-                    Log.e(LOG_TAG, "Did not find appInfo for " + requestInfo.callingPackage)
+                    Log.e(LOG_TAG, "Did not find appInfo for " + requestInfo.originatingPackage)
                     InstallAborted(ABORT_REASON_INTERNAL_ERROR)
                 }
             }
@@ -827,8 +846,10 @@
                 setStageBasedOnResult(PackageInstaller.STATUS_SUCCESS, -1, null)
             } catch (e: PackageManager.NameNotFoundException) {
                 setStageBasedOnResult(
-                    PackageInstaller.STATUS_FAILURE, PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
-                    null)
+                    PackageInstaller.STATUS_FAILURE,
+                    PackageManager.INSTALL_FAILED_INTERNAL_ERROR,
+                    null
+                )
             }
             return
         }
@@ -848,7 +869,8 @@
             }
         } catch (e: OutOfIdsException) {
             setStageBasedOnResult(
-                PackageInstaller.STATUS_FAILURE, PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null)
+                PackageInstaller.STATUS_FAILURE, PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null
+            )
             return
         }
         val broadcastIntent = Intent(BROADCAST_ACTION)
@@ -866,7 +888,8 @@
             Log.e(LOG_TAG, "Session $stagedSessionId could not be opened.", e)
             packageInstaller.abandonSession(stagedSessionId)
             setStageBasedOnResult(
-                PackageInstaller.STATUS_FAILURE, PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null)
+                PackageInstaller.STATUS_FAILURE, PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null
+            )
         }
     }
 
@@ -876,9 +899,11 @@
         message: String?,
     ) {
         if (localLogv) {
-            Log.i(LOG_TAG, "Status code: $statusCode\n" +
-                "legacy status: $legacyStatus\n" +
-                "message: $message")
+            Log.i(
+                LOG_TAG, "Status code: $statusCode\n" +
+                    "legacy status: $legacyStatus\n" +
+                    "message: $message"
+            )
         }
         if (statusCode == PackageInstaller.STATUS_SUCCESS) {
             val shouldReturnResult = intent.getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)
@@ -891,11 +916,12 @@
             _installResult.setValue(InstallSuccess(appSnippet, shouldReturnResult, resultIntent))
         } else {
             if (statusCode != PackageInstaller.STATUS_FAILURE_ABORTED) {
-                _installResult.setValue(InstallFailed(appSnippet, statusCode, legacyStatus, message))
+                _installResult.setValue(
+                    InstallFailed(appSnippet, statusCode, legacyStatus, message)
+                )
             } else {
                 _installResult.setValue(InstallAborted(ABORT_REASON_INTERNAL_ERROR))
             }
-
         }
     }
 
@@ -939,7 +965,7 @@
 
     data class CallerInfo(val packageName: String?, val uid: Int)
     data class AppOpRequestInfo(
-        val callingPackage: String?,
+        val originatingPackage: String?,
         val originatingUid: Int,
         val attributionTag: String?,
     )
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallStages.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallStages.kt
index bbb9bca..5dd4d29 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallStages.kt
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallStages.kt
@@ -43,7 +43,10 @@
     val actionReason: Int,
     private val appSnippet: PackageUtil.AppSnippet? = null,
     val isAppUpdating: Boolean = false,
-    val dialogMessage: String? = null,
+    /**
+     * This holds either a package name or the app label of the install source.
+     */
+    val sourceApp: String? = null,
 ) : InstallStage(STAGE_USER_ACTION_REQUIRED) {
 
     val appIcon: Drawable?
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/PackageUtil.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/PackageUtil.kt
index bae6f68..8572852 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/PackageUtil.kt
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/PackageUtil.kt
@@ -128,18 +128,19 @@
 
     /**
      * @param context the [Context] object
-     * @param callingUid the UID of the caller who's permission is being checked
-     * @param originatingUid the UID from where install is being originated. This could be same as
-     * callingUid or it will be the UID of the package performing a session based install
-     * @param isTrustedSource whether install request is coming from a privileged app or an app that
-     * has [Manifest.permission.INSTALL_PACKAGES] permission granted
-     * @return `true` if the package is granted the said permission
+     * @param callingUid the UID of the caller of Pia
+     * @param isTrustedSource indicates whether install request is coming from a privileged app
+     * that has passed EXTRA_NOT_UNKNOWN_SOURCE as `true` in the installation intent, or that has
+     * the [INSTALL_PACKAGES][Manifest.permission.INSTALL_PACKAGES] permission granted.
+     *
+     * @return `true` if the package is either a system downloads provider, a document manager,
+     * a trusted source, or has declared the
+     * [REQUEST_INSTALL_PACKAGES][Manifest.permission.REQUEST_INSTALL_PACKAGES] in its manifest.
      */
     @JvmStatic
     fun isInstallPermissionGrantedOrRequested(
         context: Context,
         callingUid: Int,
-        originatingUid: Int,
         isTrustedSource: Boolean,
     ): Boolean {
         val isDocumentsManager =
@@ -148,19 +149,18 @@
             getSystemDownloadsProviderInfo(context.packageManager, callingUid) != null
 
         if (!isTrustedSource && !isSystemDownloadsProvider && !isDocumentsManager) {
-            val targetSdkVersion = getMaxTargetSdkVersionForUid(context, originatingUid)
+            val targetSdkVersion = getMaxTargetSdkVersionForUid(context, callingUid)
             if (targetSdkVersion < 0) {
-                // Invalid originating uid supplied. Abort install.
-                Log.w(LOG_TAG, "Cannot get target sdk version for uid $originatingUid")
+                // Invalid calling uid supplied. Abort install.
+                Log.e(LOG_TAG, "Cannot get target SDK version for uid $callingUid")
                 return false
             } else if (targetSdkVersion >= Build.VERSION_CODES.O
                 && !isUidRequestingPermission(
-                    context.packageManager, originatingUid,
-                    Manifest.permission.REQUEST_INSTALL_PACKAGES
+                    context.packageManager, callingUid, Manifest.permission.REQUEST_INSTALL_PACKAGES
                 )
             ) {
                 Log.e(
-                    LOG_TAG, "Requesting uid " + originatingUid + " needs to declare permission "
+                    LOG_TAG, "Requesting uid " + callingUid + " needs to declare permission "
                         + Manifest.permission.REQUEST_INSTALL_PACKAGES
                 )
                 return false
@@ -204,13 +204,13 @@
      * @return `true` if the caller is the session owner
      */
     @JvmStatic
-    fun isCallerSessionOwner(pi: PackageInstaller, originatingUid: Int, sessionId: Int): Boolean {
-        if (originatingUid == Process.ROOT_UID) {
+    fun isCallerSessionOwner(pi: PackageInstaller, callingUid: Int, sessionId: Int): Boolean {
+        if (callingUid == Process.ROOT_UID) {
             return true
         }
         val sessionInfo = pi.getSessionInfo(sessionId) ?: return false
         val installerUid = sessionInfo.getInstallerUid()
-        return originatingUid == installerUid
+        return callingUid == installerUid
     }
 
     /**
@@ -362,8 +362,8 @@
      * @return the packageName corresponding to a UID.
      */
     @JvmStatic
-    fun getPackageNameForUid(context: Context, sourceUid: Int, callingPackage: String?): String? {
-        if (sourceUid == Process.INVALID_UID) {
+    fun getPackageNameForUid(context: Context, uid: Int, preferredPkgName: String?): String? {
+        if (uid == Process.INVALID_UID) {
             return null
         }
         // If the sourceUid belongs to the system downloads provider, we explicitly return the
@@ -371,20 +371,21 @@
         // packages, resulting in uncertainty about which package will end up first in the list
         // of packages associated with this UID
         val pm = context.packageManager
-        val systemDownloadProviderInfo = getSystemDownloadsProviderInfo(pm, sourceUid)
+        val systemDownloadProviderInfo = getSystemDownloadsProviderInfo(pm, uid)
         if (systemDownloadProviderInfo != null) {
             return systemDownloadProviderInfo.packageName
         }
-        val packagesForUid = pm.getPackagesForUid(sourceUid) ?: return null
+
+        val packagesForUid = pm.getPackagesForUid(uid) ?: return null
         if (packagesForUid.size > 1) {
-            if (callingPackage != null) {
+            Log.i(LOG_TAG, "Multiple packages found for source uid $uid")
+            if (preferredPkgName != null) {
                 for (packageName in packagesForUid) {
-                    if (packageName == callingPackage) {
+                    if (packageName == preferredPkgName) {
                         return packageName
                     }
                 }
             }
-            Log.i(LOG_TAG, "Multiple packages found for source uid $sourceUid")
         }
         return packagesForUid[0]
     }
@@ -439,7 +440,7 @@
      */
     data class AppSnippet(var label: CharSequence?, var icon: Drawable?) {
         override fun toString(): String {
-            return "AppSnippet[label = ${label}, hasIcon = ${icon != null}]"
+            return "AppSnippet[label = $label, hasIcon = ${icon != null}]"
         }
     }
 }
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ExternalSourcesBlockedFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ExternalSourcesBlockedFragment.java
index a95137d..343a213 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ExternalSourcesBlockedFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ExternalSourcesBlockedFragment.java
@@ -63,7 +63,7 @@
             .setMessage(R.string.untrusted_external_source_warning)
             .setPositiveButton(R.string.external_sources_settings,
                 (dialog, which) -> mInstallActionListener.sendUnknownAppsIntent(
-                    mDialogData.getDialogMessage()))
+                    mDialogData.getSourceApp()))
             .setNegativeButton(R.string.cancel,
                 (dialog, which) -> mInstallActionListener.onNegativeResponse(
                     mDialogData.getStageCode()))
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallConfirmationFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallConfirmationFragment.java
index 99b1eec..e186590 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallConfirmationFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallConfirmationFragment.java
@@ -64,7 +64,7 @@
 
         int positiveBtnTextRes;
         if (mDialogData.isAppUpdating()) {
-            if (mDialogData.getDialogMessage() != null) {
+            if (mDialogData.getSourceApp() != null) {
                 positiveBtnTextRes = R.string.update_anyway;
             } else {
                 positiveBtnTextRes = R.string.update;
@@ -88,9 +88,10 @@
         TextView viewToEnable;
         if (mDialogData.isAppUpdating()) {
             viewToEnable = dialogView.requireViewById(R.id.install_confirm_question_update);
-            String dialogMessage = mDialogData.getDialogMessage();
-            if (dialogMessage != null) {
-                viewToEnable.setText(Html.fromHtml(dialogMessage, Html.FROM_HTML_MODE_LEGACY));
+            String sourcePackageName = mDialogData.getSourceApp();
+            if (sourcePackageName != null) {
+                // Show the update-ownership change message
+                viewToEnable.setText(Html.fromHtml(sourcePackageName, Html.FROM_HTML_MODE_LEGACY));
             }
         } else {
             viewToEnable = dialogView.requireViewById(R.id.install_confirm_question);
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallTask.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallTask.java
deleted file mode 100644
index 53a460d..0000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallTask.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.packageinstaller.wear;
-
-import android.content.Context;
-import android.content.IntentSender;
-import android.content.pm.PackageInstaller;
-import android.os.Looper;
-import android.os.ParcelFileDescriptor;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * Task that installs an APK. This must not be called on the main thread.
- * This code is based off the Finsky/Wearsky implementation
- */
-public class InstallTask {
-    private static final String TAG = "InstallTask";
-
-    private static final int DEFAULT_BUFFER_SIZE = 8192;
-
-    private final Context mContext;
-    private String mPackageName;
-    private ParcelFileDescriptor mParcelFileDescriptor;
-    private PackageInstallerImpl.InstallListener mCallback;
-    private PackageInstaller.Session mSession;
-    private IntentSender mCommitCallback;
-
-    private Exception mException = null;
-    private int mErrorCode = 0;
-    private String mErrorDesc = null;
-
-    public InstallTask(Context context, String packageName,
-            ParcelFileDescriptor parcelFileDescriptor,
-            PackageInstallerImpl.InstallListener callback, PackageInstaller.Session session,
-            IntentSender commitCallback) {
-        mContext = context;
-        mPackageName = packageName;
-        mParcelFileDescriptor = parcelFileDescriptor;
-        mCallback = callback;
-        mSession = session;
-        mCommitCallback = commitCallback;
-    }
-
-    public boolean isError() {
-        return mErrorCode != InstallerConstants.STATUS_SUCCESS || !TextUtils.isEmpty(mErrorDesc);
-    }
-
-    public void execute() {
-        if (Looper.myLooper() == Looper.getMainLooper()) {
-            throw new IllegalStateException("This method cannot be called from the UI thread.");
-        }
-
-        OutputStream sessionStream = null;
-        try {
-            sessionStream = mSession.openWrite(mPackageName, 0, -1);
-
-            // 2b: Stream the asset to the installer. Note:
-            // Note: writeToOutputStreamFromAsset() always safely closes the input stream
-            writeToOutputStreamFromAsset(sessionStream);
-            mSession.fsync(sessionStream);
-        } catch (Exception e) {
-            mException = e;
-            mErrorCode = InstallerConstants.ERROR_INSTALL_COPY_STREAM;
-            mErrorDesc = "Could not write to stream";
-        } finally {
-            if (sessionStream != null) {
-                // 2c: close output stream
-                try {
-                    sessionStream.close();
-                } catch (Exception e) {
-                    // Ignore otherwise
-                    if (mException == null) {
-                        mException = e;
-                        mErrorCode = InstallerConstants.ERROR_INSTALL_CLOSE_STREAM;
-                        mErrorDesc = "Could not close session stream";
-                    }
-                }
-            }
-        }
-
-        if (mErrorCode != InstallerConstants.STATUS_SUCCESS) {
-            // An error occurred, we're done
-            Log.e(TAG, "Exception while installing " + mPackageName + ": " + mErrorCode + ", "
-                    + mErrorDesc + ", " + mException);
-            mSession.close();
-            mCallback.installFailed(mErrorCode, "[" + mPackageName + "]" + mErrorDesc);
-        } else {
-            // 3. Commit the session (this actually installs it.)  Session map
-            // will be cleaned up in the callback.
-            mCallback.installBeginning();
-            mSession.commit(mCommitCallback);
-            mSession.close();
-        }
-    }
-
-    /**
-     * {@code PackageInstaller} works with streams. Get the {@code FileDescriptor}
-     * corresponding to the {@code Asset} and then write the contents into an
-     * {@code OutputStream} that is passed in.
-     * <br>
-     * The {@code FileDescriptor} is closed but the {@code OutputStream} is not closed.
-     */
-    private boolean writeToOutputStreamFromAsset(OutputStream outputStream) {
-        if (outputStream == null) {
-            mErrorCode = InstallerConstants.ERROR_INSTALL_COPY_STREAM_EXCEPTION;
-            mErrorDesc = "Got a null OutputStream.";
-            return false;
-        }
-
-        if (mParcelFileDescriptor == null || mParcelFileDescriptor.getFileDescriptor() == null)  {
-            mErrorCode = InstallerConstants.ERROR_COULD_NOT_GET_FD;
-            mErrorDesc = "Could not get FD";
-            return false;
-        }
-
-        InputStream inputStream = null;
-        try {
-            byte[] inputBuf = new byte[DEFAULT_BUFFER_SIZE];
-            int bytesRead;
-            inputStream = new ParcelFileDescriptor.AutoCloseInputStream(mParcelFileDescriptor);
-
-            while ((bytesRead = inputStream.read(inputBuf)) > -1) {
-                if (bytesRead > 0) {
-                    outputStream.write(inputBuf, 0, bytesRead);
-                }
-            }
-
-            outputStream.flush();
-        } catch (IOException e) {
-            mErrorCode = InstallerConstants.ERROR_INSTALL_APK_COPY_FAILURE;
-            mErrorDesc = "Reading from Asset FD or writing to temp file failed: " + e;
-            return false;
-        } finally {
-            safeClose(inputStream);
-        }
-
-        return true;
-    }
-
-    /**
-     * Quietly close a closeable resource (e.g. a stream or file). The input may already
-     * be closed and it may even be null.
-     */
-    public static void safeClose(Closeable resource) {
-        if (resource != null) {
-            try {
-                resource.close();
-            } catch (IOException ioe) {
-                // Catch and discard the error
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallerConstants.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallerConstants.java
deleted file mode 100644
index 3daf3d8..0000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallerConstants.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.packageinstaller.wear;
-
-/**
- * Constants for Installation / Uninstallation requests.
- * Using the same values as Finsky/Wearsky code for consistency in user analytics of failures
- */
-public class InstallerConstants {
-    /** Request succeeded */
-    public static final int STATUS_SUCCESS = 0;
-
-    /**
-     * The new PackageInstaller also returns a small set of less granular error codes, which
-     * we'll remap to the range -500 and below to keep away from existing installer codes
-     * (which run from -1 to -110).
-     */
-    public final static int ERROR_PACKAGEINSTALLER_BASE = -500;
-
-    public static final int ERROR_COULD_NOT_GET_FD = -603;
-    /** This node is not targeted by this request. */
-
-    /** The install did not complete because could not create PackageInstaller session */
-    public final static int ERROR_INSTALL_CREATE_SESSION = -612;
-    /** The install did not complete because could not open PackageInstaller session  */
-    public final static int ERROR_INSTALL_OPEN_SESSION = -613;
-    /** The install did not complete because could not open PackageInstaller output stream */
-    public final static int ERROR_INSTALL_OPEN_STREAM = -614;
-    /** The install did not complete because of an exception while streaming bytes */
-    public final static int ERROR_INSTALL_COPY_STREAM_EXCEPTION = -615;
-    /** The install did not complete because of an unexpected exception from PackageInstaller */
-    public final static int ERROR_INSTALL_SESSION_EXCEPTION = -616;
-    /** The install did not complete because of an unexpected userActionRequired callback */
-    public final static int ERROR_INSTALL_USER_ACTION_REQUIRED = -617;
-    /** The install did not complete because of an unexpected broadcast (missing fields) */
-    public final static int ERROR_INSTALL_MALFORMED_BROADCAST = -618;
-    /** The install did not complete because of an error while copying from downloaded file */
-    public final static int ERROR_INSTALL_APK_COPY_FAILURE = -619;
-    /** The install did not complete because of an error while copying to the PackageInstaller
-     * output stream */
-    public final static int ERROR_INSTALL_COPY_STREAM = -620;
-    /** The install did not complete because of an error while closing the PackageInstaller
-     * output stream */
-    public final static int ERROR_INSTALL_CLOSE_STREAM = -621;
-}
\ No newline at end of file
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerFactory.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerFactory.java
deleted file mode 100644
index bdc22cf..0000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerFactory.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.packageinstaller.wear;
-
-import android.content.Context;
-
-/**
- * Factory that creates a Package Installer.
- */
-public class PackageInstallerFactory {
-    private static PackageInstallerImpl sPackageInstaller;
-
-    /**
-     * Return the PackageInstaller shared object. {@code init} should have already been called.
-     */
-    public synchronized static PackageInstallerImpl getPackageInstaller(Context context) {
-        if (sPackageInstaller == null) {
-            sPackageInstaller = new PackageInstallerImpl(context);
-        }
-        return sPackageInstaller;
-    }
-}
\ No newline at end of file
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerImpl.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerImpl.java
deleted file mode 100644
index 1e37f15..0000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerImpl.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.packageinstaller.wear;
-
-import android.annotation.TargetApi;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.pm.PackageInstaller;
-import android.os.Build;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Implementation of package manager installation using modern PackageInstaller api.
- *
- * Heavily copied from Wearsky/Finsky implementation
- */
-@TargetApi(Build.VERSION_CODES.LOLLIPOP)
-public class PackageInstallerImpl {
-    private static final String TAG = "PackageInstallerImpl";
-
-    /** Intent actions used for broadcasts from PackageInstaller back to the local receiver */
-    private static final String ACTION_INSTALL_COMMIT =
-            "com.android.vending.INTENT_PACKAGE_INSTALL_COMMIT";
-
-    private final Context mContext;
-    private final PackageInstaller mPackageInstaller;
-    private final Map<String, PackageInstaller.SessionInfo> mSessionInfoMap;
-    private final Map<String, PackageInstaller.Session> mOpenSessionMap;
-
-    public PackageInstallerImpl(Context context) {
-        mContext = context.getApplicationContext();
-        mPackageInstaller = mContext.getPackageManager().getPackageInstaller();
-
-        // Capture a map of known sessions
-        // This list will be pruned a bit later (stale sessions will be canceled)
-        mSessionInfoMap = new HashMap<String, PackageInstaller.SessionInfo>();
-        List<PackageInstaller.SessionInfo> mySessions = mPackageInstaller.getMySessions();
-        for (int i = 0; i < mySessions.size(); i++) {
-            PackageInstaller.SessionInfo sessionInfo = mySessions.get(i);
-            String packageName = sessionInfo.getAppPackageName();
-            PackageInstaller.SessionInfo oldInfo = mSessionInfoMap.put(packageName, sessionInfo);
-
-            // Checking for old info is strictly for logging purposes
-            if (oldInfo != null) {
-                Log.w(TAG, "Multiple sessions for " + packageName + " found. Removing " + oldInfo
-                        .getSessionId() + " & keeping " + mySessions.get(i).getSessionId());
-            }
-        }
-        mOpenSessionMap = new HashMap<String, PackageInstaller.Session>();
-    }
-
-    /**
-     * This callback will be made after an installation attempt succeeds or fails.
-     */
-    public interface InstallListener {
-        /**
-         * This callback signals that preflight checks have succeeded and installation
-         * is beginning.
-         */
-        void installBeginning();
-
-        /**
-         * This callback signals that installation has completed.
-         */
-        void installSucceeded();
-
-        /**
-         * This callback signals that installation has failed.
-         */
-        void installFailed(int errorCode, String errorDesc);
-    }
-
-    /**
-     * This is a placeholder implementation that bundles an entire "session" into a single
-     * call. This will be replaced by more granular versions that allow longer session lifetimes,
-     * download progress tracking, etc.
-     *
-     * This must not be called on main thread.
-     */
-    public void install(final String packageName, ParcelFileDescriptor parcelFileDescriptor,
-            final InstallListener callback) {
-        // 0. Generic try/catch block because I am not really sure what exceptions (other than
-        // IOException) might be thrown by PackageInstaller and I want to handle them
-        // at least slightly gracefully.
-        try {
-            // 1. Create or recover a session, and open it
-            // Try recovery first
-            PackageInstaller.Session session = null;
-            PackageInstaller.SessionInfo sessionInfo = mSessionInfoMap.get(packageName);
-            if (sessionInfo != null) {
-                // See if it's openable, or already held open
-                session = getSession(packageName);
-            }
-            // If open failed, or there was no session, create a new one and open it.
-            // If we cannot create or open here, the failure is terminal.
-            if (session == null) {
-                try {
-                    innerCreateSession(packageName);
-                } catch (IOException ioe) {
-                    Log.e(TAG, "Can't create session for " + packageName + ": " + ioe.getMessage());
-                    callback.installFailed(InstallerConstants.ERROR_INSTALL_CREATE_SESSION,
-                            "Could not create session");
-                    mSessionInfoMap.remove(packageName);
-                    return;
-                }
-                sessionInfo = mSessionInfoMap.get(packageName);
-                try {
-                    session = mPackageInstaller.openSession(sessionInfo.getSessionId());
-                    mOpenSessionMap.put(packageName, session);
-                } catch (SecurityException se) {
-                    Log.e(TAG, "Can't open session for " + packageName + ": " + se.getMessage());
-                    callback.installFailed(InstallerConstants.ERROR_INSTALL_OPEN_SESSION,
-                            "Can't open session");
-                    mSessionInfoMap.remove(packageName);
-                    return;
-                }
-            }
-
-            // 2. Launch task to handle file operations.
-            InstallTask task = new InstallTask( mContext, packageName, parcelFileDescriptor,
-                    callback, session,
-                    getCommitCallback(packageName, sessionInfo.getSessionId(), callback));
-            task.execute();
-            if (task.isError()) {
-                cancelSession(sessionInfo.getSessionId(), packageName);
-            }
-        } catch (Exception e) {
-            Log.e(TAG, "Unexpected exception while installing: " + packageName + ": "
-                    + e.getMessage());
-            callback.installFailed(InstallerConstants.ERROR_INSTALL_SESSION_EXCEPTION,
-                    "Unexpected exception while installing " + packageName);
-        }
-    }
-
-    /**
-     * Retrieve an existing session. Will open if needed, but does not attempt to create.
-     */
-    private PackageInstaller.Session getSession(String packageName) {
-        // Check for already-open session
-        PackageInstaller.Session session = mOpenSessionMap.get(packageName);
-        if (session != null) {
-            try {
-                // Probe the session to ensure that it's still open. This may or may not
-                // throw (if non-open), but it may serve as a canary for stale sessions.
-                session.getNames();
-                return session;
-            } catch (IOException ioe) {
-                Log.e(TAG, "Stale open session for " + packageName + ": " + ioe.getMessage());
-                mOpenSessionMap.remove(packageName);
-            } catch (SecurityException se) {
-                Log.e(TAG, "Stale open session for " + packageName + ": " + se.getMessage());
-                mOpenSessionMap.remove(packageName);
-            }
-        }
-        // Check to see if this is a known session
-        PackageInstaller.SessionInfo sessionInfo = mSessionInfoMap.get(packageName);
-        if (sessionInfo == null) {
-            return null;
-        }
-        // Try to open it. If we fail here, assume that the SessionInfo was stale.
-        try {
-            session = mPackageInstaller.openSession(sessionInfo.getSessionId());
-        } catch (SecurityException se) {
-            Log.w(TAG, "SessionInfo was stale for " + packageName + " - deleting info");
-            mSessionInfoMap.remove(packageName);
-            return null;
-        } catch (IOException ioe) {
-            Log.w(TAG, "IOException opening old session for " + ioe.getMessage()
-                    + " - deleting info");
-            mSessionInfoMap.remove(packageName);
-            return null;
-        }
-        mOpenSessionMap.put(packageName, session);
-        return session;
-    }
-
-    /** This version throws an IOException when the session cannot be created */
-    private void innerCreateSession(String packageName) throws IOException {
-        if (mSessionInfoMap.containsKey(packageName)) {
-            Log.w(TAG, "Creating session for " + packageName + " when one already exists");
-            return;
-        }
-        PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
-                PackageInstaller.SessionParams.MODE_FULL_INSTALL);
-        params.setAppPackageName(packageName);
-
-        // IOException may be thrown at this point
-        int sessionId = mPackageInstaller.createSession(params);
-        PackageInstaller.SessionInfo sessionInfo = mPackageInstaller.getSessionInfo(sessionId);
-        mSessionInfoMap.put(packageName, sessionInfo);
-    }
-
-    /**
-     * Cancel a session based on its sessionId. Package name is for logging only.
-     */
-    private void cancelSession(int sessionId, String packageName) {
-        // Close if currently held open
-        closeSession(packageName);
-        // Remove local record
-        mSessionInfoMap.remove(packageName);
-        try {
-            mPackageInstaller.abandonSession(sessionId);
-        } catch (SecurityException se) {
-            // The session no longer exists, so we can exit quietly.
-            return;
-        }
-    }
-
-    /**
-     * Close a session if it happens to be held open.
-     */
-    private void closeSession(String packageName) {
-        PackageInstaller.Session session = mOpenSessionMap.remove(packageName);
-        if (session != null) {
-            // Unfortunately close() is not idempotent. Try our best to make this safe.
-            try {
-                session.close();
-            } catch (Exception e) {
-                Log.w(TAG, "Unexpected error closing session for " + packageName + ": "
-                        + e.getMessage());
-            }
-        }
-    }
-
-    /**
-     * Creates a commit callback for the package install that's underway. This will be called
-     * some time after calling session.commit() (above).
-     */
-    private IntentSender getCommitCallback(final String packageName, final int sessionId,
-            final InstallListener callback) {
-        // Create a single-use broadcast receiver
-        BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                mContext.unregisterReceiver(this);
-                handleCommitCallback(intent, packageName, sessionId, callback);
-            }
-        };
-        // Create a matching intent-filter and register the receiver
-        String action = ACTION_INSTALL_COMMIT + "." + packageName;
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(action);
-        mContext.registerReceiver(broadcastReceiver, intentFilter,
-                Context.RECEIVER_EXPORTED);
-
-        // Create a matching PendingIntent and use it to generate the IntentSender
-        Intent broadcastIntent = new Intent(action).setPackage(mContext.getPackageName());
-        PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, packageName.hashCode(),
-                broadcastIntent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT
-                        | PendingIntent.FLAG_MUTABLE);
-        return pendingIntent.getIntentSender();
-    }
-
-    /**
-     * Examine the extras to determine information about the package update/install, decode
-     * the result, and call the appropriate callback.
-     *
-     * @param intent The intent, which the PackageInstaller will have added Extras to
-     * @param packageName The package name we created the receiver for
-     * @param sessionId The session Id we created the receiver for
-     * @param callback The callback to report success/failure to
-     */
-    private void handleCommitCallback(Intent intent, String packageName, int sessionId,
-            InstallListener callback) {
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "Installation of " + packageName + " finished with extras "
-                    + intent.getExtras());
-        }
-        String statusMessage = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE);
-        int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, Integer.MIN_VALUE);
-        if (status == PackageInstaller.STATUS_SUCCESS) {
-            cancelSession(sessionId, packageName);
-            callback.installSucceeded();
-        } else if (status == -1 /*PackageInstaller.STATUS_USER_ACTION_REQUIRED*/) {
-            // TODO - use the constant when the correct/final name is in the SDK
-            // TODO This is unexpected, so we are treating as failure for now
-            cancelSession(sessionId, packageName);
-            callback.installFailed(InstallerConstants.ERROR_INSTALL_USER_ACTION_REQUIRED,
-                    "Unexpected: user action required");
-        } else {
-            cancelSession(sessionId, packageName);
-            int errorCode = getPackageManagerErrorCode(status);
-            Log.e(TAG, "Error " + errorCode + " while installing " + packageName + ": "
-                    + statusMessage);
-            callback.installFailed(errorCode, null);
-        }
-    }
-
-    private int getPackageManagerErrorCode(int status) {
-        // This is a hack: because PackageInstaller now reports error codes
-        // with small positive values, we need to remap them into a space
-        // that is more compatible with the existing package manager error codes.
-        // See https://sites.google.com/a/google.com/universal-store/documentation
-        //       /android-client/download-error-codes
-        int errorCode;
-        if (status == Integer.MIN_VALUE) {
-            errorCode = InstallerConstants.ERROR_INSTALL_MALFORMED_BROADCAST;
-        } else {
-            errorCode = InstallerConstants.ERROR_PACKAGEINSTALLER_BASE - status;
-        }
-        return errorCode;
-    }
-}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageArgs.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageArgs.java
deleted file mode 100644
index 2c289b2..0000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageArgs.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.packageinstaller.wear;
-
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-
-/**
- * Installation Util that contains a list of parameters that are needed for
- * installing/uninstalling.
- */
-public class WearPackageArgs {
-    private static final String KEY_PACKAGE_NAME =
-            "com.google.android.clockwork.EXTRA_PACKAGE_NAME";
-    private static final String KEY_ASSET_URI =
-            "com.google.android.clockwork.EXTRA_ASSET_URI";
-    private static final String KEY_START_ID =
-            "com.google.android.clockwork.EXTRA_START_ID";
-    private static final String KEY_PERM_URI =
-            "com.google.android.clockwork.EXTRA_PERM_URI";
-    private static final String KEY_CHECK_PERMS =
-            "com.google.android.clockwork.EXTRA_CHECK_PERMS";
-    private static final String KEY_SKIP_IF_SAME_VERSION =
-            "com.google.android.clockwork.EXTRA_SKIP_IF_SAME_VERSION";
-    private static final String KEY_COMPRESSION_ALG =
-            "com.google.android.clockwork.EXTRA_KEY_COMPRESSION_ALG";
-    private static final String KEY_COMPANION_SDK_VERSION =
-            "com.google.android.clockwork.EXTRA_KEY_COMPANION_SDK_VERSION";
-    private static final String KEY_COMPANION_DEVICE_VERSION =
-            "com.google.android.clockwork.EXTRA_KEY_COMPANION_DEVICE_VERSION";
-    private static final String KEY_SHOULD_CHECK_GMS_DEPENDENCY =
-            "com.google.android.clockwork.EXTRA_KEY_SHOULD_CHECK_GMS_DEPENDENCY";
-    private static final String KEY_SKIP_IF_LOWER_VERSION =
-            "com.google.android.clockwork.EXTRA_SKIP_IF_LOWER_VERSION";
-
-    public static String getPackageName(Bundle b) {
-        return b.getString(KEY_PACKAGE_NAME);
-    }
-
-    public static Bundle setPackageName(Bundle b, String packageName) {
-        b.putString(KEY_PACKAGE_NAME, packageName);
-        return b;
-    }
-
-    public static Uri getAssetUri(Bundle b) {
-        return b.getParcelable(KEY_ASSET_URI);
-    }
-
-    public static Uri getPermUri(Bundle b) {
-        return b.getParcelable(KEY_PERM_URI);
-    }
-
-    public static boolean checkPerms(Bundle b) {
-        return b.getBoolean(KEY_CHECK_PERMS);
-    }
-
-    public static boolean skipIfSameVersion(Bundle b) {
-        return b.getBoolean(KEY_SKIP_IF_SAME_VERSION);
-    }
-
-    public static int getCompanionSdkVersion(Bundle b) {
-        return b.getInt(KEY_COMPANION_SDK_VERSION);
-    }
-
-    public static int getCompanionDeviceVersion(Bundle b) {
-        return b.getInt(KEY_COMPANION_DEVICE_VERSION);
-    }
-
-    public static String getCompressionAlg(Bundle b) {
-        return b.getString(KEY_COMPRESSION_ALG);
-    }
-
-    public static int getStartId(Bundle b) {
-        return b.getInt(KEY_START_ID);
-    }
-
-    public static boolean skipIfLowerVersion(Bundle b) {
-        return b.getBoolean(KEY_SKIP_IF_LOWER_VERSION, false);
-    }
-
-    public static Bundle setStartId(Bundle b, int startId) {
-        b.putInt(KEY_START_ID, startId);
-        return b;
-    }
-}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageIconProvider.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageIconProvider.java
deleted file mode 100644
index 02b9d29..0000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageIconProvider.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.packageinstaller.wear;
-
-import android.annotation.TargetApi;
-import android.app.ActivityManager;
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Binder;
-import android.os.Build;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.List;
-
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-
-public class WearPackageIconProvider extends ContentProvider {
-    private static final String TAG = "WearPackageIconProvider";
-    public static final String AUTHORITY = "com.google.android.packageinstaller.wear.provider";
-
-    private static final String REQUIRED_PERMISSION =
-            "com.google.android.permission.INSTALL_WEARABLE_PACKAGES";
-
-    /** MIME types. */
-    public static final String ICON_TYPE = "vnd.android.cursor.item/cw_package_icon";
-
-    @Override
-    public boolean onCreate() {
-        return true;
-    }
-
-    @Override
-    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
-            String sortOrder) {
-        throw new UnsupportedOperationException("Query is not supported.");
-    }
-
-    @Override
-    public String getType(Uri uri) {
-        if (uri == null) {
-            throw new IllegalArgumentException("URI passed in is null.");
-        }
-
-        if (AUTHORITY.equals(uri.getEncodedAuthority())) {
-            return ICON_TYPE;
-        }
-        return null;
-    }
-
-    @Override
-    public Uri insert(Uri uri, ContentValues values) {
-        throw new UnsupportedOperationException("Insert is not supported.");
-    }
-
-    @Override
-    public int delete(Uri uri, String selection, String[] selectionArgs) {
-        if (uri == null) {
-            throw new IllegalArgumentException("URI passed in is null.");
-        }
-
-        enforcePermissions(uri);
-
-        if (ICON_TYPE.equals(getType(uri))) {
-            final File file = WearPackageUtil.getIconFile(
-                    this.getContext().getApplicationContext(), getPackageNameFromUri(uri));
-            if (file != null) {
-                file.delete();
-            }
-        }
-
-        return 0;
-    }
-
-    @Override
-    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
-        throw new UnsupportedOperationException("Update is not supported.");
-    }
-
-    @Override
-    public ParcelFileDescriptor openFile(
-            Uri uri, @SuppressWarnings("unused") String mode) throws FileNotFoundException {
-        if (uri == null) {
-            throw new IllegalArgumentException("URI passed in is null.");
-        }
-
-        enforcePermissions(uri);
-
-        if (ICON_TYPE.equals(getType(uri))) {
-            final File file = WearPackageUtil.getIconFile(
-                    this.getContext().getApplicationContext(), getPackageNameFromUri(uri));
-            if (file != null) {
-                return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
-            }
-        }
-        return null;
-    }
-
-    public static Uri getUriForPackage(final String packageName) {
-        return Uri.parse("content://" + AUTHORITY + "/icons/" + packageName + ".icon");
-    }
-
-    private String getPackageNameFromUri(Uri uri) {
-        if (uri == null) {
-            return null;
-        }
-        List<String> pathSegments = uri.getPathSegments();
-        String packageName = pathSegments.get(pathSegments.size() - 1);
-
-        if (packageName.endsWith(".icon")) {
-            packageName = packageName.substring(0, packageName.lastIndexOf("."));
-        }
-        return packageName;
-    }
-
-    /**
-     * Make sure the calling app is either a system app or the same app or has the right permission.
-     * @throws SecurityException if the caller has insufficient permissions.
-     */
-    @TargetApi(Build.VERSION_CODES.BASE_1_1)
-    private void enforcePermissions(Uri uri) {
-        // Redo some of the permission check in {@link ContentProvider}. Just add an extra check to
-        // allow System process to access this provider.
-        Context context = getContext();
-        final int pid = Binder.getCallingPid();
-        final int uid = Binder.getCallingUid();
-        final int myUid = android.os.Process.myUid();
-
-        if (uid == myUid || isSystemApp(context, pid)) {
-            return;
-        }
-
-        if (context.checkPermission(REQUIRED_PERMISSION, pid, uid) == PERMISSION_GRANTED) {
-            return;
-        }
-
-        // last chance, check against any uri grants
-        if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION)
-                == PERMISSION_GRANTED) {
-            return;
-        }
-
-        throw new SecurityException("Permission Denial: reading "
-                + getClass().getName() + " uri " + uri + " from pid=" + pid
-                + ", uid=" + uid);
-    }
-
-    /**
-     * From the pid of the calling process, figure out whether this is a system app or not. We do
-     * this by checking the application information corresponding to the pid and then checking if
-     * FLAG_SYSTEM is set.
-     */
-    @TargetApi(Build.VERSION_CODES.CUPCAKE)
-    private boolean isSystemApp(Context context, int pid) {
-        // Get the Activity Manager Object
-        ActivityManager aManager =
-                (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
-        // Get the list of running Applications
-        List<ActivityManager.RunningAppProcessInfo> rapInfoList =
-                aManager.getRunningAppProcesses();
-        for (ActivityManager.RunningAppProcessInfo rapInfo : rapInfoList) {
-            if (rapInfo.pid == pid) {
-                try {
-                    PackageInfo pkgInfo = context.getPackageManager().getPackageInfo(
-                            rapInfo.pkgList[0], 0);
-                    if (pkgInfo != null && pkgInfo.applicationInfo != null &&
-                            (pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
-                        Log.d(TAG, pid + " is a system app.");
-                        return true;
-                    }
-                } catch (PackageManager.NameNotFoundException e) {
-                    Log.e(TAG, "Could not find package information.", e);
-                    return false;
-                }
-            }
-        }
-        return false;
-    }
-}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.java
deleted file mode 100644
index ae0f4ec..0000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.java
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.packageinstaller.wear;
-
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.FeatureInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageInstaller;
-import android.content.pm.PackageManager;
-import android.content.pm.VersionedPackage;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.ParcelFileDescriptor;
-import android.os.PowerManager;
-import android.os.Process;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.Pair;
-import androidx.annotation.Nullable;
-import com.android.packageinstaller.DeviceUtils;
-import com.android.packageinstaller.PackageUtil;
-import com.android.packageinstaller.R;
-import com.android.packageinstaller.common.EventResultPersister;
-import com.android.packageinstaller.common.UninstallEventReceiver;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Service that will install/uninstall packages. It will check for permissions and features as well.
- *
- * -----------
- *
- * Debugging information:
- *
- *  Install Action example:
- *  adb shell am startservice -a com.android.packageinstaller.wear.INSTALL_PACKAGE \
- *     -d package://com.google.android.gms \
- *     --eu com.google.android.clockwork.EXTRA_ASSET_URI content://com.google.android.clockwork.home.provider/host/com.google.android.wearable.app/wearable/com.google.android.gms/apk \
- *     --es android.intent.extra.INSTALLER_PACKAGE_NAME com.google.android.gms \
- *     --ez com.google.android.clockwork.EXTRA_CHECK_PERMS false \
- *     --eu com.google.android.clockwork.EXTRA_PERM_URI content://com.google.android.clockwork.home.provider/host/com.google.android.wearable.app/permissions \
- *     com.android.packageinstaller/com.android.packageinstaller.wear.WearPackageInstallerService
- *
- *  Uninstall Action example:
- *  adb shell am startservice -a com.android.packageinstaller.wear.UNINSTALL_PACKAGE \
- *     -d package://com.google.android.gms \
- *     com.android.packageinstaller/com.android.packageinstaller.wear.WearPackageInstallerService
- *
- *  Retry GMS:
- *  adb shell am startservice -a com.android.packageinstaller.wear.RETRY_GMS \
- *     com.android.packageinstaller/com.android.packageinstaller.wear.WearPackageInstallerService
- */
-public class WearPackageInstallerService extends Service
-        implements EventResultPersister.EventResultObserver {
-    private static final String TAG = "WearPkgInstallerService";
-
-    private static final String WEAR_APPS_CHANNEL = "wear_app_install_uninstall";
-    private static final String BROADCAST_ACTION =
-            "com.android.packageinstaller.ACTION_UNINSTALL_COMMIT";
-
-    private final int START_INSTALL = 1;
-    private final int START_UNINSTALL = 2;
-
-    private int mInstallNotificationId = 1;
-    private final Map<String, Integer> mNotifIdMap = new ArrayMap<>();
-    private final Map<Integer, UninstallParams> mServiceIdToParams = new HashMap<>();
-
-    private class UninstallParams {
-        public String mPackageName;
-        public PowerManager.WakeLock mLock;
-
-        UninstallParams(String packageName, PowerManager.WakeLock lock) {
-            mPackageName = packageName;
-            mLock = lock;
-        }
-    }
-
-    private final class ServiceHandler extends Handler {
-        public ServiceHandler(Looper looper) {
-            super(looper);
-        }
-
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case START_INSTALL:
-                    installPackage(msg.getData());
-                    break;
-                case START_UNINSTALL:
-                    uninstallPackage(msg.getData());
-                    break;
-            }
-        }
-    }
-    private ServiceHandler mServiceHandler;
-    private NotificationChannel mNotificationChannel;
-    private static volatile PowerManager.WakeLock lockStatic = null;
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return null;
-    }
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        HandlerThread thread = new HandlerThread("PackageInstallerThread",
-                Process.THREAD_PRIORITY_BACKGROUND);
-        thread.start();
-
-        mServiceHandler = new ServiceHandler(thread.getLooper());
-    }
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        if (!DeviceUtils.isWear(this)) {
-            Log.w(TAG, "Not running on wearable.");
-            finishServiceEarly(startId);
-            return START_NOT_STICKY;
-        }
-
-        if (intent == null) {
-            Log.w(TAG, "Got null intent.");
-            finishServiceEarly(startId);
-            return START_NOT_STICKY;
-        }
-
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "Got install/uninstall request " + intent);
-        }
-
-        Uri packageUri = intent.getData();
-        if (packageUri == null) {
-            Log.e(TAG, "No package URI in intent");
-            finishServiceEarly(startId);
-            return START_NOT_STICKY;
-        }
-
-        final String packageName = WearPackageUtil.getSanitizedPackageName(packageUri);
-        if (packageName == null) {
-            Log.e(TAG, "Invalid package name in URI (expected package:<pkgName>): " + packageUri);
-            finishServiceEarly(startId);
-            return START_NOT_STICKY;
-        }
-
-        PowerManager.WakeLock lock = getLock(this.getApplicationContext());
-        if (!lock.isHeld()) {
-            lock.acquire();
-        }
-
-        Bundle intentBundle = intent.getExtras();
-        if (intentBundle == null) {
-            intentBundle = new Bundle();
-        }
-        WearPackageArgs.setStartId(intentBundle, startId);
-        WearPackageArgs.setPackageName(intentBundle, packageName);
-        Message msg;
-        String notifTitle;
-        if (Intent.ACTION_INSTALL_PACKAGE.equals(intent.getAction())) {
-            msg = mServiceHandler.obtainMessage(START_INSTALL);
-            notifTitle = getString(R.string.installing);
-        } else if (Intent.ACTION_UNINSTALL_PACKAGE.equals(intent.getAction())) {
-            msg = mServiceHandler.obtainMessage(START_UNINSTALL);
-            notifTitle = getString(R.string.uninstalling);
-        } else {
-            Log.e(TAG, "Unknown action : " + intent.getAction());
-            finishServiceEarly(startId);
-            return START_NOT_STICKY;
-        }
-        Pair<Integer, Notification> notifPair = buildNotification(packageName, notifTitle);
-        startForeground(notifPair.first, notifPair.second);
-        msg.setData(intentBundle);
-        mServiceHandler.sendMessage(msg);
-        return START_NOT_STICKY;
-    }
-
-    private void installPackage(Bundle argsBundle) {
-        int startId = WearPackageArgs.getStartId(argsBundle);
-        final String packageName = WearPackageArgs.getPackageName(argsBundle);
-        final Uri assetUri = WearPackageArgs.getAssetUri(argsBundle);
-        final Uri permUri = WearPackageArgs.getPermUri(argsBundle);
-        boolean checkPerms = WearPackageArgs.checkPerms(argsBundle);
-        boolean skipIfSameVersion = WearPackageArgs.skipIfSameVersion(argsBundle);
-        int companionSdkVersion = WearPackageArgs.getCompanionSdkVersion(argsBundle);
-        int companionDeviceVersion = WearPackageArgs.getCompanionDeviceVersion(argsBundle);
-        String compressionAlg = WearPackageArgs.getCompressionAlg(argsBundle);
-        boolean skipIfLowerVersion = WearPackageArgs.skipIfLowerVersion(argsBundle);
-
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "Installing package: " + packageName + ", assetUri: " + assetUri +
-                    ",permUri: " + permUri + ", startId: " + startId + ", checkPerms: " +
-                    checkPerms + ", skipIfSameVersion: " + skipIfSameVersion +
-                    ", compressionAlg: " + compressionAlg + ", companionSdkVersion: " +
-                    companionSdkVersion + ", companionDeviceVersion: " + companionDeviceVersion +
-                    ", skipIfLowerVersion: " + skipIfLowerVersion);
-        }
-        final PackageManager pm = getPackageManager();
-        File tempFile = null;
-        PowerManager.WakeLock lock = getLock(this.getApplicationContext());
-        boolean messageSent = false;
-        try {
-            PackageInfo existingPkgInfo = null;
-            try {
-                existingPkgInfo = pm.getPackageInfo(packageName,
-                        PackageManager.MATCH_ANY_USER | PackageManager.GET_PERMISSIONS);
-                if (existingPkgInfo != null) {
-                    if (Log.isLoggable(TAG, Log.DEBUG)) {
-                        Log.d(TAG, "Replacing package:" + packageName);
-                    }
-                }
-            } catch (PackageManager.NameNotFoundException e) {
-                // Ignore this exception. We could not find the package, will treat as a new
-                // installation.
-            }
-            // TODO(28021618): This was left as a temp file due to the fact that this code is being
-            //       deprecated and that we need the bare minimum to continue working moving forward
-            //       If this code is used as reference, this permission logic might want to be
-            //       reworked to use a stream instead of a file so that we don't need to write a
-            //       file at all.  Note that there might be some trickiness with opening a stream
-            //       for multiple users.
-            ParcelFileDescriptor parcelFd = getContentResolver()
-                    .openFileDescriptor(assetUri, "r");
-            tempFile = WearPackageUtil.getFileFromFd(WearPackageInstallerService.this,
-                    parcelFd, packageName, compressionAlg);
-            if (tempFile == null) {
-                Log.e(TAG, "Could not create a temp file from FD for " + packageName);
-                return;
-            }
-            PackageInfo pkgInfo = PackageUtil.getPackageInfo(this, tempFile,
-                    PackageManager.GET_PERMISSIONS | PackageManager.GET_CONFIGURATIONS);
-            if (pkgInfo == null) {
-                Log.e(TAG, "Could not parse apk information for " + packageName);
-                return;
-            }
-
-            if (!pkgInfo.packageName.equals(packageName)) {
-                Log.e(TAG, "Wearable Package Name has to match what is provided for " +
-                        packageName);
-                return;
-            }
-
-            ApplicationInfo appInfo = pkgInfo.applicationInfo;
-            appInfo.sourceDir = tempFile.getPath();
-            appInfo.publicSourceDir = tempFile.getPath();
-            getLabelAndUpdateNotification(packageName,
-                    getString(R.string.installing_app, appInfo.loadLabel(pm)));
-
-            List<String> wearablePerms = Arrays.asList(pkgInfo.requestedPermissions);
-
-            // Log if the installed pkg has a higher version number.
-            if (existingPkgInfo != null) {
-                long longVersionCode = pkgInfo.getLongVersionCode();
-                if (existingPkgInfo.getLongVersionCode() == longVersionCode) {
-                    if (skipIfSameVersion) {
-                        Log.w(TAG, "Version number (" + longVersionCode +
-                                ") of new app is equal to existing app for " + packageName +
-                                "; not installing due to versionCheck");
-                        return;
-                    } else {
-                        Log.w(TAG, "Version number of new app (" + longVersionCode +
-                                ") is equal to existing app for " + packageName);
-                    }
-                } else if (existingPkgInfo.getLongVersionCode() > longVersionCode) {
-                    if (skipIfLowerVersion) {
-                        // Starting in Feldspar, we are not going to allow downgrades of any app.
-                        Log.w(TAG, "Version number of new app (" + longVersionCode +
-                                ") is lower than existing app ( "
-                                + existingPkgInfo.getLongVersionCode() +
-                                ") for " + packageName + "; not installing due to versionCheck");
-                        return;
-                    } else {
-                        Log.w(TAG, "Version number of new app (" + longVersionCode +
-                                ") is lower than existing app ( "
-                                + existingPkgInfo.getLongVersionCode() + ") for " + packageName);
-                    }
-                }
-
-                // Following the Android Phone model, we should only check for permissions for any
-                // newly defined perms.
-                if (existingPkgInfo.requestedPermissions != null) {
-                    for (int i = 0; i < existingPkgInfo.requestedPermissions.length; ++i) {
-                        // If the permission is granted, then we will not ask to request it again.
-                        if ((existingPkgInfo.requestedPermissionsFlags[i] &
-                                PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0) {
-                            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                                Log.d(TAG, existingPkgInfo.requestedPermissions[i] +
-                                        " is already granted for " + packageName);
-                            }
-                            wearablePerms.remove(existingPkgInfo.requestedPermissions[i]);
-                        }
-                    }
-                }
-            }
-
-            // Check that the wearable has all the features.
-            boolean hasAllFeatures = true;
-            for (FeatureInfo feature : pkgInfo.reqFeatures) {
-                if (feature.name != null && !pm.hasSystemFeature(feature.name) &&
-                        (feature.flags & FeatureInfo.FLAG_REQUIRED) != 0) {
-                    Log.e(TAG, "Wearable does not have required feature: " + feature +
-                            " for " + packageName);
-                    hasAllFeatures = false;
-                }
-            }
-
-            if (!hasAllFeatures) {
-                return;
-            }
-
-            // Check permissions on both the new wearable package and also on the already installed
-            // wearable package.
-            // If the app is targeting API level 23, we will also start a service in ClockworkHome
-            // which will ultimately prompt the user to accept/reject permissions.
-            if (checkPerms && !checkPermissions(pkgInfo, companionSdkVersion,
-                    companionDeviceVersion, permUri, wearablePerms, tempFile)) {
-                Log.w(TAG, "Wearable does not have enough permissions.");
-                return;
-            }
-
-            // Finally install the package.
-            ParcelFileDescriptor fd = getContentResolver().openFileDescriptor(assetUri, "r");
-            PackageInstallerFactory.getPackageInstaller(this).install(packageName, fd,
-                    new PackageInstallListener(this, lock, startId, packageName));
-
-            messageSent = true;
-            Log.i(TAG, "Sent installation request for " + packageName);
-        } catch (FileNotFoundException e) {
-            Log.e(TAG, "Could not find the file with URI " + assetUri, e);
-        } finally {
-            if (!messageSent) {
-                // Some error happened. If the message has been sent, we can wait for the observer
-                // which will finish the service.
-                if (tempFile != null) {
-                    tempFile.delete();
-                }
-                finishService(lock, startId);
-            }
-        }
-    }
-
-    // TODO: This was left using the old PackageManager API due to the fact that this code is being
-    //       deprecated and that we need the bare minimum to continue working moving forward
-    //       If this code is used as reference, this logic should be reworked to use the new
-    //       PackageInstaller APIs similar to how installPackage was reworked
-    private void uninstallPackage(Bundle argsBundle) {
-        int startId = WearPackageArgs.getStartId(argsBundle);
-        final String packageName = WearPackageArgs.getPackageName(argsBundle);
-
-        PowerManager.WakeLock lock = getLock(this.getApplicationContext());
-
-        UninstallParams params = new UninstallParams(packageName, lock);
-        mServiceIdToParams.put(startId, params);
-
-        final PackageManager pm = getPackageManager();
-        try {
-            PackageInfo pkgInfo = pm.getPackageInfo(packageName, 0);
-            getLabelAndUpdateNotification(packageName,
-                    getString(R.string.uninstalling_app, pkgInfo.applicationInfo.loadLabel(pm)));
-
-            int uninstallId = UninstallEventReceiver.addObserver(this,
-                    EventResultPersister.GENERATE_NEW_ID, this);
-
-            Intent broadcastIntent = new Intent(BROADCAST_ACTION);
-            broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-            broadcastIntent.putExtra(EventResultPersister.EXTRA_ID, uninstallId);
-            broadcastIntent.putExtra(EventResultPersister.EXTRA_SERVICE_ID, startId);
-            broadcastIntent.setPackage(getPackageName());
-
-            PendingIntent pendingIntent = PendingIntent.getBroadcast(this, uninstallId,
-                    broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT
-                            | PendingIntent.FLAG_MUTABLE);
-
-            // Found package, send uninstall request.
-            pm.getPackageInstaller().uninstall(
-                    new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
-                    PackageManager.DELETE_ALL_USERS,
-                    pendingIntent.getIntentSender());
-
-            Log.i(TAG, "Sent delete request for " + packageName);
-        } catch (IllegalArgumentException | PackageManager.NameNotFoundException e) {
-            // Couldn't find the package, no need to call uninstall.
-            Log.w(TAG, "Could not find package, not deleting " + packageName, e);
-            finishService(lock, startId);
-        } catch (EventResultPersister.OutOfIdsException e) {
-            Log.e(TAG, "Fails to start uninstall", e);
-            finishService(lock, startId);
-        }
-    }
-
-    @Override
-    public void onResult(int status, int legacyStatus, @Nullable String message, int serviceId) {
-        if (mServiceIdToParams.containsKey(serviceId)) {
-            UninstallParams params = mServiceIdToParams.get(serviceId);
-            try {
-                if (status == PackageInstaller.STATUS_SUCCESS) {
-                    Log.i(TAG, "Package " + params.mPackageName + " was uninstalled.");
-                } else {
-                    Log.e(TAG, "Package uninstall failed " + params.mPackageName
-                            + ", returnCode " + legacyStatus);
-                }
-            } finally {
-                finishService(params.mLock, serviceId);
-            }
-        }
-    }
-
-    private boolean checkPermissions(PackageInfo pkgInfo, int companionSdkVersion,
-            int companionDeviceVersion, Uri permUri, List<String> wearablePermissions,
-            File apkFile) {
-        // Assumption: We are running on Android O.
-        // If the Phone App is targeting M, all permissions may not have been granted to the phone
-        // app. If the Wear App is then not targeting M, there may be permissions that are not
-        // granted on the Phone app (by the user) right now and we cannot just grant it for the Wear
-        // app.
-        if (pkgInfo.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
-            // Install the app if Wear App is ready for the new perms model.
-            return true;
-        }
-
-        if (!doesWearHaveUngrantedPerms(pkgInfo.packageName, permUri, wearablePermissions)) {
-            // All permissions requested by the watch are already granted on the phone, no need
-            // to do anything.
-            return true;
-        }
-
-        // Log an error if Wear is targeting < 23 and phone is targeting >= 23.
-        if (companionSdkVersion == 0 || companionSdkVersion >= Build.VERSION_CODES.M) {
-            Log.e(TAG, "MNC: Wear app's targetSdkVersion should be at least 23, if "
-                    + "phone app is targeting at least 23, will continue.");
-        }
-
-        return false;
-    }
-
-    /**
-     * Given a {@string packageName} corresponding to a phone app, query the provider for all the
-     * perms that are granted.
-     *
-     * @return true if the Wear App has any perms that have not been granted yet on the phone side.
-     * @return true if there is any error cases.
-     */
-    private boolean doesWearHaveUngrantedPerms(String packageName, Uri permUri,
-            List<String> wearablePermissions) {
-        if (permUri == null) {
-            Log.e(TAG, "Permission URI is null");
-            // Pretend there is an ungranted permission to avoid installing for error cases.
-            return true;
-        }
-        Cursor permCursor = getContentResolver().query(permUri, null, null, null, null);
-        if (permCursor == null) {
-            Log.e(TAG, "Could not get the cursor for the permissions");
-            // Pretend there is an ungranted permission to avoid installing for error cases.
-            return true;
-        }
-
-        Set<String> grantedPerms = new HashSet<>();
-        Set<String> ungrantedPerms = new HashSet<>();
-        while(permCursor.moveToNext()) {
-            // Make sure that the MatrixCursor returned by the ContentProvider has 2 columns and
-            // verify their types.
-            if (permCursor.getColumnCount() == 2
-                    && Cursor.FIELD_TYPE_STRING == permCursor.getType(0)
-                    && Cursor.FIELD_TYPE_INTEGER == permCursor.getType(1)) {
-                String perm = permCursor.getString(0);
-                Integer granted = permCursor.getInt(1);
-                if (granted == 1) {
-                    grantedPerms.add(perm);
-                } else {
-                    ungrantedPerms.add(perm);
-                }
-            }
-        }
-        permCursor.close();
-
-        boolean hasUngrantedPerm = false;
-        for (String wearablePerm : wearablePermissions) {
-            if (!grantedPerms.contains(wearablePerm)) {
-                hasUngrantedPerm = true;
-                if (!ungrantedPerms.contains(wearablePerm)) {
-                    // This is an error condition. This means that the wearable has permissions that
-                    // are not even declared in its host app. This is a developer error.
-                    Log.e(TAG, "Wearable " + packageName + " has a permission \"" + wearablePerm
-                            + "\" that is not defined in the host application's manifest.");
-                } else {
-                    Log.w(TAG, "Wearable " + packageName + " has a permission \"" + wearablePerm +
-                            "\" that is not granted in the host application.");
-                }
-            }
-        }
-        return hasUngrantedPerm;
-    }
-
-    /** Finishes the service after fulfilling obligation to call startForeground. */
-    private void finishServiceEarly(int startId) {
-        Pair<Integer, Notification> notifPair = buildNotification(
-                getApplicationContext().getPackageName(), "");
-        startForeground(notifPair.first, notifPair.second);
-        finishService(null, startId);
-    }
-
-    private void finishService(PowerManager.WakeLock lock, int startId) {
-        if (lock != null && lock.isHeld()) {
-            lock.release();
-        }
-        stopSelf(startId);
-    }
-
-    private synchronized PowerManager.WakeLock getLock(Context context) {
-        if (lockStatic == null) {
-            PowerManager mgr =
-                    (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-            lockStatic = mgr.newWakeLock(
-                    PowerManager.PARTIAL_WAKE_LOCK, context.getClass().getSimpleName());
-            lockStatic.setReferenceCounted(true);
-        }
-        return lockStatic;
-    }
-
-    private class PackageInstallListener implements PackageInstallerImpl.InstallListener {
-        private Context mContext;
-        private PowerManager.WakeLock mWakeLock;
-        private int mStartId;
-        private String mApplicationPackageName;
-        private PackageInstallListener(Context context, PowerManager.WakeLock wakeLock,
-                int startId, String applicationPackageName) {
-            mContext = context;
-            mWakeLock = wakeLock;
-            mStartId = startId;
-            mApplicationPackageName = applicationPackageName;
-        }
-
-        @Override
-        public void installBeginning() {
-            Log.i(TAG, "Package " + mApplicationPackageName + " is being installed.");
-        }
-
-        @Override
-        public void installSucceeded() {
-            try {
-                Log.i(TAG, "Package " + mApplicationPackageName + " was installed.");
-
-                // Delete tempFile from the file system.
-                File tempFile = WearPackageUtil.getTemporaryFile(mContext, mApplicationPackageName);
-                if (tempFile != null) {
-                    tempFile.delete();
-                }
-            } finally {
-                finishService(mWakeLock, mStartId);
-            }
-        }
-
-        @Override
-        public void installFailed(int errorCode, String errorDesc) {
-            Log.e(TAG, "Package install failed " + mApplicationPackageName
-                    + ", errorCode " + errorCode);
-            finishService(mWakeLock, mStartId);
-        }
-    }
-
-    private synchronized Pair<Integer, Notification> buildNotification(final String packageName,
-            final String title) {
-        int notifId;
-        if (mNotifIdMap.containsKey(packageName)) {
-            notifId = mNotifIdMap.get(packageName);
-        } else {
-            notifId = mInstallNotificationId++;
-            mNotifIdMap.put(packageName, notifId);
-        }
-
-        if (mNotificationChannel == null) {
-            mNotificationChannel = new NotificationChannel(WEAR_APPS_CHANNEL,
-                    getString(R.string.wear_app_channel), NotificationManager.IMPORTANCE_MIN);
-            NotificationManager notificationManager = getSystemService(NotificationManager.class);
-            notificationManager.createNotificationChannel(mNotificationChannel);
-        }
-        return new Pair<>(notifId, new Notification.Builder(this, WEAR_APPS_CHANNEL)
-            .setSmallIcon(R.drawable.ic_file_download)
-            .setContentTitle(title)
-            .build());
-    }
-
-    private void getLabelAndUpdateNotification(String packageName, String title) {
-        // Update notification since we have a label now.
-        NotificationManager notificationManager = getSystemService(NotificationManager.class);
-        Pair<Integer, Notification> notifPair = buildNotification(packageName, title);
-        notificationManager.notify(notifPair.first, notifPair.second);
-    }
-}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageUtil.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageUtil.java
deleted file mode 100644
index 6a9145d..0000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageUtil.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.packageinstaller.wear;
-
-import android.content.Context;
-import android.net.Uri;
-import android.os.ParcelFileDescriptor;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.text.TextUtils;
-import android.util.Log;
-
-import org.tukaani.xz.LZMAInputStream;
-import org.tukaani.xz.XZInputStream;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-public class WearPackageUtil {
-    private static final String TAG = "WearablePkgInstaller";
-
-    private static final String COMPRESSION_LZMA = "lzma";
-    private static final String COMPRESSION_XZ = "xz";
-
-    public static File getTemporaryFile(Context context, String packageName) {
-        try {
-            File newFileDir = new File(context.getFilesDir(), "tmp");
-            newFileDir.mkdirs();
-            Os.chmod(newFileDir.getAbsolutePath(), 0771);
-            File newFile = new File(newFileDir, packageName + ".apk");
-            return newFile;
-        }   catch (ErrnoException e) {
-            Log.e(TAG, "Failed to open.", e);
-            return null;
-        }
-    }
-
-    public static File getIconFile(final Context context, final String packageName) {
-        try {
-            File newFileDir = new File(context.getFilesDir(), "images/icons");
-            newFileDir.mkdirs();
-            Os.chmod(newFileDir.getAbsolutePath(), 0771);
-            return new File(newFileDir, packageName + ".icon");
-        }   catch (ErrnoException e) {
-            Log.e(TAG, "Failed to open.", e);
-            return null;
-        }
-    }
-
-    /**
-     * In order to make sure that the Wearable Asset Manager has a reasonable apk that can be used
-     * by the PackageManager, we will parse it before sending it to the PackageManager.
-     * Unfortunately, ParsingPackageUtils needs a file to parse. So, we have to temporarily convert
-     * the fd to a File.
-     *
-     * @param context
-     * @param fd FileDescriptor to convert to File
-     * @param packageName Name of package, will define the name of the file
-     * @param compressionAlg Can be null. For ALT mode the APK will be compressed. We will
-     *                       decompress it here
-     */
-    public static File getFileFromFd(Context context, ParcelFileDescriptor fd,
-            String packageName, String compressionAlg) {
-        File newFile = getTemporaryFile(context, packageName);
-        if (fd == null || fd.getFileDescriptor() == null)  {
-            return null;
-        }
-        InputStream fr = new ParcelFileDescriptor.AutoCloseInputStream(fd);
-        try {
-            if (TextUtils.equals(compressionAlg, COMPRESSION_XZ)) {
-                fr = new XZInputStream(fr);
-            } else if (TextUtils.equals(compressionAlg, COMPRESSION_LZMA)) {
-                fr = new LZMAInputStream(fr);
-            }
-        } catch (IOException e) {
-            Log.e(TAG, "Compression was set to " + compressionAlg + ", but could not decode ", e);
-            return null;
-        }
-
-        int nRead;
-        byte[] data = new byte[1024];
-        try {
-            final FileOutputStream fo = new FileOutputStream(newFile);
-            while ((nRead = fr.read(data, 0, data.length)) != -1) {
-                fo.write(data, 0, nRead);
-            }
-            fo.flush();
-            fo.close();
-            Os.chmod(newFile.getAbsolutePath(), 0644);
-            return newFile;
-        } catch (IOException e) {
-            Log.e(TAG, "Reading from Asset FD or writing to temp file failed ", e);
-            return null;
-        }   catch (ErrnoException e) {
-            Log.e(TAG, "Could not set permissions on file ", e);
-            return null;
-        } finally {
-            try {
-                fr.close();
-            } catch (IOException e) {
-                Log.e(TAG, "Failed to close the file from FD ", e);
-            }
-        }
-    }
-
-    /**
-     * @return com.google.com from expected formats like
-     * Uri: package:com.google.com, package:/com.google.com, package://com.google.com
-     */
-    public static String getSanitizedPackageName(Uri packageUri) {
-        String packageName = packageUri.getEncodedSchemeSpecificPart();
-        if (packageName != null) {
-            return packageName.replaceAll("^/+", "");
-        }
-        return packageName;
-    }
-}
diff --git a/packages/PrintSpooler/res/values-fr-rCA/strings.xml b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
index 6ffad70..c2b82af 100644
--- a/packages/PrintSpooler/res/values-fr-rCA/strings.xml
+++ b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
@@ -33,7 +33,7 @@
     <string name="pages_range_example" msgid="8558694453556945172">"p. ex. 1-5, 8, 11-13"</string>
     <string name="print_preview" msgid="8010217796057763343">"Aperçu avant impression"</string>
     <string name="install_for_print_preview" msgid="6366303997385509332">"Installer un lecteur PDF pour voir l\'aperçu"</string>
-    <string name="printing_app_crashed" msgid="854477616686566398">"L\'application à l\'origine de l\'impression a planté"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"L\'appli à l\'origine de l\'impression a planté"</string>
     <string name="generating_print_job" msgid="3119608742651698916">"Génération tâche impression…"</string>
     <string name="save_as_pdf" msgid="5718454119847596853">"Enregistrer au format PDF"</string>
     <string name="all_printers" msgid="5018829726861876202">"Toutes les imprimantes…"</string>
diff --git a/packages/SettingsLib/ActionButtonsPreference/Android.bp b/packages/SettingsLib/ActionButtonsPreference/Android.bp
index c36b82d..71ecb4c 100644
--- a/packages/SettingsLib/ActionButtonsPreference/Android.bp
+++ b/packages/SettingsLib/ActionButtonsPreference/Android.bp
@@ -19,7 +19,6 @@
 
     static_libs: [
         "androidx.preference_preference",
-        "SettingsLibUtils",
     ],
 
     sdk_version: "system_current",
diff --git a/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java b/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java
index 3e65d94..5dc11cf 100644
--- a/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java
+++ b/packages/SettingsLib/ActionButtonsPreference/src/com/android/settingslib/widget/ActionButtonsPreference.java
@@ -20,6 +20,7 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -31,12 +32,11 @@
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
-import com.android.settingslib.utils.BuildCompatUtils;
+import com.android.settingslib.widget.preference.actionbuttons.R;
+
 import java.util.ArrayList;
 import java.util.List;
 
-import com.android.settingslib.widget.preference.actionbuttons.R;
-
 /**
  * This preference provides a four buttons layout with Settings style.
  * It looks like below
@@ -56,7 +56,7 @@
 public class ActionButtonsPreference extends Preference {
 
     private static final String TAG = "ActionButtonPreference";
-    private static final boolean mIsAtLeastS = BuildCompatUtils.isAtLeastS();
+    private static final boolean mIsAtLeastS = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
     private static final int SINGLE_BUTTON_STYLE = 1;
     private static final int TWO_BUTTONS_STYLE = 2;
     private static final int THREE_BUTTONS_STYLE = 3;
diff --git a/packages/SettingsLib/ActivityEmbedding/Android.bp b/packages/SettingsLib/ActivityEmbedding/Android.bp
index 838a9e5..5561002 100644
--- a/packages/SettingsLib/ActivityEmbedding/Android.bp
+++ b/packages/SettingsLib/ActivityEmbedding/Android.bp
@@ -20,7 +20,6 @@
         "androidx.annotation_annotation",
         "androidx.core_core",
         "androidx.window_window",
-        "SettingsLibUtils",
     ],
     sdk_version: "system_current",
     min_sdk_version: "21",
diff --git a/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java b/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java
index f89be9f..67aa8f4 100644
--- a/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java
+++ b/packages/SettingsLib/ActivityEmbedding/src/com/android/settingslib/activityembedding/ActivityEmbeddingUtils.java
@@ -20,13 +20,11 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.os.Build;
 import android.util.Log;
 
-import androidx.core.os.BuildCompat;
 import androidx.window.embedding.ActivityEmbeddingController;
 
-import com.android.settingslib.utils.BuildCompatUtils;
-
 /**
  * An util class collecting all common methods for the embedding activity features.
  */
@@ -70,7 +68,7 @@
      * enabled (unsupported devices).
      */
     private static ComponentName getEmbeddingActivityComponent(Context context) {
-        if (!BuildCompatUtils.isAtLeastSV2()) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S_V2) {
             return null;
         }
         final Intent intent = new Intent(ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY);
@@ -95,7 +93,7 @@
      *                          Settings app
      */
     public static boolean shouldHideNavigateUpButton(Activity activity, boolean isSecondLayerPage) {
-        if (!BuildCompat.isAtLeastT()) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
             return false;
         }
 
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index d6cbf2a..0cb85d8 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -64,6 +64,7 @@
     srcs: [
         "src/**/*.java",
         "src/**/*.kt",
+        "src/**/I*.aidl",
     ],
 }
 
diff --git a/packages/SettingsLib/AppPreference/res/values-fr-rCA/strings.xml b/packages/SettingsLib/AppPreference/res/values-fr-rCA/strings.xml
index 7be1e97..4771382 100644
--- a/packages/SettingsLib/AppPreference/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/AppPreference/res/values-fr-rCA/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="install_type_instant" msgid="7217305006127216917">"Application instantanée"</string>
+    <string name="install_type_instant" msgid="7217305006127216917">"Appli instantanée"</string>
 </resources>
diff --git a/packages/SettingsLib/BannerMessagePreference/Android.bp b/packages/SettingsLib/BannerMessagePreference/Android.bp
index 07290de..3f671b9 100644
--- a/packages/SettingsLib/BannerMessagePreference/Android.bp
+++ b/packages/SettingsLib/BannerMessagePreference/Android.bp
@@ -20,7 +20,6 @@
     static_libs: [
         "androidx.preference_preference",
         "SettingsLibSettingsTheme",
-        "SettingsLibUtils",
     ],
 
     sdk_version: "system_current",
diff --git a/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java b/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java
index 33775a6..6cd777e 100644
--- a/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java
+++ b/packages/SettingsLib/BannerMessagePreference/src/com/android/settingslib/widget/BannerMessagePreference.java
@@ -38,7 +38,6 @@
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
-import com.android.settingslib.utils.BuildCompatUtils;
 import com.android.settingslib.widget.preference.banner.R;
 /**
  * Banner message is a banner displaying important information (permission request, page error etc),
@@ -84,7 +83,7 @@
     }
 
     private static final String TAG = "BannerPreference";
-    private static final boolean IS_AT_LEAST_S = BuildCompatUtils.isAtLeastS();
+    private static final boolean IS_AT_LEAST_S = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
 
     private final BannerMessagePreference.ButtonInfo mPositiveButtonInfo =
             new BannerMessagePreference.ButtonInfo();
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
index 87ec0b8..b56b944 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/Android.bp
@@ -20,9 +20,9 @@
     static_libs: [
         "androidx.annotation_annotation",
         "androidx.core_core",
+        "androidx.activity_activity",
         "com.google.android.material_material",
         "SettingsLibSettingsTransition",
-        "SettingsLibUtils",
         "SettingsLibSettingsTheme",
     ],
     sdk_version: "system_current",
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/BasePreferencesFragment.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/BasePreferencesFragment.java
index 8ebbac3..b252e5f 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/BasePreferencesFragment.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/BasePreferencesFragment.java
@@ -16,11 +16,11 @@
 
 package com.android.settingslib.collapsingtoolbar;
 
+import android.os.Build;
+
 import androidx.fragment.app.FragmentActivity;
 import androidx.preference.PreferenceFragmentCompat;
 
-import com.android.settingslib.utils.BuildCompatUtils;
-
 import com.google.android.material.appbar.AppBarLayout;
 
 /**
@@ -58,7 +58,7 @@
         if (activity != null) {
             activity.setTitle(getTitle());
 
-            if (BuildCompatUtils.isAtLeastS()) {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                 AppBarLayout appBarLayout = (AppBarLayout) activity.findViewById(R.id.app_bar);
 
                 if (appBarLayout != null) {
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java
index 04c44e6..4659051 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java
@@ -17,6 +17,7 @@
 package com.android.settingslib.collapsingtoolbar;
 
 import android.app.ActionBar;
+import android.os.Build;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -26,8 +27,6 @@
 import androidx.annotation.Nullable;
 import androidx.appcompat.app.AppCompatActivity;
 
-import com.android.settingslib.utils.BuildCompatUtils;
-
 import com.google.android.material.appbar.AppBarLayout;
 import com.google.android.material.appbar.CollapsingToolbarLayout;
 import com.google.android.material.color.DynamicColors;
@@ -65,13 +64,14 @@
 
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
+        EdgeToEdgeUtils.enable(this);
         super.onCreate(savedInstanceState);
-        if (BuildCompatUtils.isAtLeastS()) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
             DynamicColors.applyToActivityIfAvailable(this);
         }
         setTheme(com.android.settingslib.widget.theme.R.style.Theme_SubSettingsBase);
 
-        if (mCustomizeLayoutResId > 0 && !BuildCompatUtils.isAtLeastS()) {
+        if (mCustomizeLayoutResId > 0 && Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
             super.setContentView(mCustomizeLayoutResId);
             return;
         }
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
index 143101f..3965303 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
@@ -18,6 +18,7 @@
 
 import android.app.ActionBar;
 import android.content.pm.PackageManager;
+import android.os.Build;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -27,8 +28,6 @@
 import androidx.annotation.Nullable;
 import androidx.fragment.app.FragmentActivity;
 
-import com.android.settingslib.utils.BuildCompatUtils;
-
 import com.google.android.material.appbar.AppBarLayout;
 import com.google.android.material.appbar.CollapsingToolbarLayout;
 
@@ -58,9 +57,11 @@
 
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
+        EdgeToEdgeUtils.enable(this);
         super.onCreate(savedInstanceState);
         // for backward compatibility on R devices or wearable devices due to small device size.
-        if (mCustomizeLayoutResId > 0 && (!BuildCompatUtils.isAtLeastS() || isWatch())) {
+        if (mCustomizeLayoutResId > 0 && (Build.VERSION.SDK_INT < Build.VERSION_CODES.S
+                || isWatch())) {
             super.setContentView(mCustomizeLayoutResId);
             return;
         }
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/EdgeToEdgeUtils.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/EdgeToEdgeUtils.java
new file mode 100644
index 0000000..6e53012
--- /dev/null
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/EdgeToEdgeUtils.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.collapsingtoolbar;
+
+import android.os.Build;
+
+import androidx.activity.ComponentActivity;
+import androidx.activity.EdgeToEdge;
+import androidx.annotation.NonNull;
+import androidx.core.graphics.Insets;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsCompat;
+
+/**
+ * Util class for edge to edge.
+ */
+public class EdgeToEdgeUtils {
+    private EdgeToEdgeUtils() {
+    }
+
+    /**
+     * Enable Edge to Edge and handle overlaps using insets. It should be called before
+     * setContentView.
+     */
+    static void enable(@NonNull ComponentActivity activity) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
+            return;
+        }
+
+        EdgeToEdge.enable(activity);
+
+        ViewCompat.setOnApplyWindowInsetsListener(activity.findViewById(android.R.id.content),
+                (v, windowInsets) -> {
+                    Insets insets = windowInsets.getInsets(
+                            WindowInsetsCompat.Type.systemBars()
+                                    | WindowInsetsCompat.Type.ime()
+                                    | WindowInsetsCompat.Type.displayCutout());
+                    int statusBarHeight = activity.getWindow().getDecorView().getRootWindowInsets()
+                            .getInsets(WindowInsetsCompat.Type.statusBars()).top;
+                    // Apply the insets paddings to the view.
+                    v.setPadding(insets.left, statusBarHeight, insets.right, insets.bottom);
+
+                    // Return CONSUMED if you don't want the window insets to keep being
+                    // passed down to descendant views.
+                    return WindowInsetsCompat.CONSUMED;
+                });
+    }
+}
diff --git a/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java b/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java
index 493818b..d60290e 100644
--- a/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java
+++ b/packages/SettingsLib/FooterPreference/src/com/android/settingslib/widget/FooterPreference.java
@@ -174,7 +174,7 @@
 
     /** Return the content description of footer preference. */
     @VisibleForTesting
-    CharSequence getContentDescription() {
+    public CharSequence getContentDescription() {
         return mContentDescription;
     }
 
diff --git a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/LottieColorUtils.java b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/LottieColorUtils.java
index 0ab33b7..98a7290 100644
--- a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/LottieColorUtils.java
+++ b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/LottieColorUtils.java
@@ -53,6 +53,12 @@
                 ".grey900",
                 R.color.settingslib_color_grey50);
         map.put(
+                ".red100",
+                R.color.settingslib_color_red500);
+        map.put(
+                ".red200",
+                R.color.settingslib_color_red500);
+        map.put(
                 ".red400",
                 R.color.settingslib_color_red600);
         map.put(
@@ -65,14 +71,14 @@
                 ".blue400",
                 R.color.settingslib_color_blue600);
         map.put(
-                ".green400",
-                R.color.settingslib_color_green600);
+                ".green100",
+                R.color.settingslib_color_green500);
         map.put(
                 ".green200",
                 R.color.settingslib_color_green500);
         map.put(
-                ".red200",
-                R.color.settingslib_color_red500);
+                ".green400",
+                R.color.settingslib_color_green600);
         map.put(
                 ".cream",
                 R.color.settingslib_color_charcoal);
diff --git a/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileSelectFragment.java b/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileSelectFragment.java
index c52386b..7be4482 100644
--- a/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileSelectFragment.java
+++ b/packages/SettingsLib/ProfileSelector/src/com/android/settingslib/widget/ProfileSelectFragment.java
@@ -30,7 +30,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 
-import androidx.core.os.BuildCompat;
 import androidx.fragment.app.Fragment;
 import androidx.viewpager2.widget.ViewPager2;
 
@@ -226,7 +225,8 @@
     // to be here only for this API level - when then private profile was introduced.
     @TargetApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
     private boolean shouldShowPrivateProfileIfItsOne(UserHandle userHandle) {
-        if (!BuildCompat.isAtLeastV() || !android.os.Flags.allowPrivateProfile()) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM
+                || !android.os.Flags.allowPrivateProfile()) {
             return false;
         }
         try {
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v35/themes.xml b/packages/SettingsLib/SettingsTheme/res/values-v35/themes.xml
index 6052be3..b6e80c7 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v35/themes.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v35/themes.xml
@@ -22,6 +22,9 @@
         <item name="android:textColorPrimary">@color/settingslib_materialColorOnSurface</item>
         <item name="android:textColorSecondary">@color/settingslib_text_color_secondary</item>
         <item name="android:textColorTertiary">@color/settingslib_materialColorOutline</item>
+        <!-- Set up edge-to-edge configuration for top app bar -->
+        <item name="android:clipToPadding">false</item>
+        <item name="android:clipChildren">false</item>
     </style>
 
     <style name="Theme.SettingsBase" parent="Theme.SettingsBase_v35" />
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt
index 9a344c3..2ae3b56 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt
@@ -41,23 +41,25 @@
 import androidx.compose.material3.LocalContentColor
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.ProvideTextStyle
-import androidx.compose.material3.Surface
 import androidx.compose.material3.Text
 import androidx.compose.material3.TopAppBarScrollBehavior
 import androidx.compose.material3.TopAppBarState
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.NonRestartableComposable
-import androidx.compose.runtime.SideEffect
 import androidx.compose.runtime.Stable
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableFloatStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clipToBounds
+import androidx.compose.ui.draw.drawBehind
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.graphicsLayer
 import androidx.compose.ui.graphics.lerp
+import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.layout.AlignmentLine
 import androidx.compose.ui.layout.LastBaseline
 import androidx.compose.ui.layout.Layout
@@ -66,6 +68,7 @@
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.semantics.clearAndSetSemantics
 import androidx.compose.ui.semantics.heading
+import androidx.compose.ui.semantics.isTraversalGroup
 import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.style.TextOverflow
@@ -80,11 +83,10 @@
 import kotlin.math.max
 import kotlin.math.roundToInt
 
-private val windowInsets: WindowInsets
+private val safeDrawingWindowInsets: WindowInsets
     @Composable
     @NonRestartableComposable
-    get() = WindowInsets.safeDrawing
-        .only(WindowInsetsSides.Horizontal + WindowInsetsSides.Top)
+    get() = WindowInsets.safeDrawing.only(WindowInsetsSides.Horizontal + WindowInsetsSides.Top)
 
 @Composable
 internal fun CustomizedTopAppBar(
@@ -97,14 +99,12 @@
         titleTextStyle = MaterialTheme.typography.titleMedium,
         navigationIcon = navigationIcon,
         actions = actions,
-        windowInsets = windowInsets,
+        windowInsets = safeDrawingWindowInsets,
         colors = topAppBarColors(),
     )
 }
 
-/**
- * The customized LargeTopAppBar for Settings.
- */
+/** The customized LargeTopAppBar for Settings. */
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
 internal fun CustomizedLargeTopAppBar(
@@ -124,7 +124,7 @@
         navigationIcon = navigationIcon,
         actions = actions,
         colors = topAppBarColors(),
-        windowInsets = windowInsets,
+        windowInsets = safeDrawingWindowInsets,
         pinnedHeight = ContainerHeight,
         scrollBehavior = scrollBehavior,
     )
@@ -134,38 +134,41 @@
 private fun Title(title: String, maxLines: Int = Int.MAX_VALUE) {
     Text(
         text = title,
-        modifier = Modifier.padding(
-            start = SettingsDimension.itemPaddingAround,
-            end = SettingsDimension.itemPaddingEnd,
-        )
-        .semantics { heading() },
+        modifier =
+            Modifier.padding(
+                    start = SettingsDimension.itemPaddingAround,
+                    end = SettingsDimension.itemPaddingEnd,
+                )
+                .semantics { heading() },
         overflow = TextOverflow.Ellipsis,
         maxLines = maxLines,
     )
 }
 
 @Composable
-private fun topAppBarColors() = TopAppBarColors(
-    containerColor = MaterialTheme.colorScheme.settingsBackground,
-    scrolledContainerColor = MaterialTheme.colorScheme.surfaceVariant,
-    navigationIconContentColor = MaterialTheme.colorScheme.onSurface,
-    titleContentColor = MaterialTheme.colorScheme.onSurface,
-    actionIconContentColor = MaterialTheme.colorScheme.onSurfaceVariant,
-)
+private fun topAppBarColors() =
+    TopAppBarColors(
+        containerColor = MaterialTheme.colorScheme.settingsBackground,
+        scrolledContainerColor = MaterialTheme.colorScheme.surfaceVariant,
+        navigationIconContentColor = MaterialTheme.colorScheme.onSurface,
+        titleContentColor = MaterialTheme.colorScheme.onSurface,
+        actionIconContentColor = MaterialTheme.colorScheme.onSurfaceVariant,
+    )
 
 /**
  * Represents the colors used by a top app bar in different states.
+ *
  * This implementation animates the container color according to the top app bar scroll state. It
  * does not animate the leading, headline, or trailing colors.
  *
- * @constructor create an instance with arbitrary colors, see [TopAppBarColors] for a
- * factory method using the default material3 spec
  * @param containerColor the color used for the background of this BottomAppBar. Use
- * [Color.Transparent] to have no color.
+ *   [Color.Transparent] to have no color.
  * @param scrolledContainerColor the container color when content is scrolled behind it
  * @param navigationIconContentColor the content color used for the navigation icon
  * @param titleContentColor the content color used for the title
  * @param actionIconContentColor the content color used for actions
+ * @constructor create an instance with arbitrary colors, see [TopAppBarColors] for a factory method
+ *   using the default material3 spec
  */
 @Stable
 private class TopAppBarColors(
@@ -180,11 +183,11 @@
      * Represents the container color used for the top app bar.
      *
      * A [colorTransitionFraction] provides a percentage value that can be used to generate a color.
-     * Usually, an app bar implementation will pass in a [colorTransitionFraction] read from
-     * the [TopAppBarState.collapsedFraction] or the [TopAppBarState.overlappedFraction].
+     * Usually, an app bar implementation will pass in a [colorTransitionFraction] read from the
+     * [TopAppBarState.collapsedFraction] or the [TopAppBarState.overlappedFraction].
      *
      * @param colorTransitionFraction a `0.0` to `1.0` value that represents a color transition
-     * percentage
+     *   percentage
      */
     @Stable
     fun containerColor(colorTransitionFraction: Float): Color {
@@ -233,29 +236,35 @@
     colors: TopAppBarColors,
 ) {
     // Wrap the given actions in a Row.
-    val actionsRow = @Composable {
-        Row(
-            horizontalArrangement = Arrangement.End,
-            verticalAlignment = Alignment.CenterVertically,
-            content = actions
-        )
-    }
+    val actionsRow =
+        @Composable {
+            Row(
+                horizontalArrangement = Arrangement.End,
+                verticalAlignment = Alignment.CenterVertically,
+                content = actions
+            )
+        }
 
     // Compose a Surface with a TopAppBarLayout content.
-    Surface(color = colors.scrolledContainerColor) {
+    Box(
+        modifier =
+            Modifier.drawBehind { drawRect(color = colors.scrolledContainerColor) }
+                .semantics { isTraversalGroup = true }
+                .pointerInput(Unit) {}
+    ) {
         val height = LocalDensity.current.run { ContainerHeight.toPx() }
         TopAppBarLayout(
-            modifier = Modifier
-                .windowInsetsPadding(windowInsets)
-                // clip after padding so we don't show the title over the inset area
-                .clipToBounds(),
+            modifier =
+                Modifier.windowInsetsPadding(windowInsets)
+                    // clip after padding so we don't show the title over the inset area
+                    .clipToBounds(),
             heightPx = height,
             navigationIconContentColor = colors.navigationIconContentColor,
             titleContentColor = colors.titleContentColor,
             actionIconContentColor = colors.actionIconContentColor,
             title = title,
             titleTextStyle = titleTextStyle,
-            titleAlpha = 1f,
+            titleAlpha = { 1f },
             titleVerticalArrangement = Arrangement.Center,
             titleBottomPadding = 0,
             hideTitleSemantics = false,
@@ -271,7 +280,7 @@
  * composables.
  *
  * @throws [IllegalArgumentException] if the given [MaxHeightWithoutTitle] is equal or smaller than
- * the [pinnedHeight]
+ *   the [pinnedHeight]
  */
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
@@ -308,62 +317,67 @@
 
     // Sets the app bar's height offset limit to hide just the bottom title area and keep top title
     // visible when collapsed.
-    SideEffect {
-        if (scrollBehavior?.state?.heightOffsetLimit != pinnedHeightPx - maxHeightPx.floatValue) {
-            scrollBehavior?.state?.heightOffsetLimit = pinnedHeightPx - maxHeightPx.floatValue
-        }
-    }
+    scrollBehavior?.state?.heightOffsetLimit = pinnedHeightPx - maxHeightPx.floatValue
 
     // Obtain the container Color from the TopAppBarColors using the `collapsedFraction`, as the
     // bottom part of this TwoRowsTopAppBar changes color at the same rate the app bar expands or
     // collapse.
     // This will potentially animate or interpolate a transition between the container color and the
     // container's scrolled color according to the app bar's scroll state.
-    val colorTransitionFraction = scrollBehavior?.state?.collapsedFraction ?: 0f
-    val appBarContainerColor = colors.containerColor(colorTransitionFraction)
+    val colorTransitionFraction = { scrollBehavior?.state?.collapsedFraction ?: 0f }
+    val appBarContainerColor = { colors.containerColor(colorTransitionFraction()) }
 
     // Wrap the given actions in a Row.
-    val actionsRow = @Composable {
-        Row(
-            horizontalArrangement = Arrangement.End,
-            verticalAlignment = Alignment.CenterVertically,
-            content = actions
-        )
-    }
-    val topTitleAlpha = TopTitleAlphaEasing.transform(colorTransitionFraction)
-    val bottomTitleAlpha = 1f - colorTransitionFraction
+    val actionsRow =
+        @Composable {
+            Row(
+                horizontalArrangement = Arrangement.End,
+                verticalAlignment = Alignment.CenterVertically,
+                content = actions
+            )
+        }
+    val topTitleAlpha = { TopTitleAlphaEasing.transform(colorTransitionFraction()) }
+    val bottomTitleAlpha = { 1f - colorTransitionFraction() }
     // Hide the top row title semantics when its alpha value goes below 0.5 threshold.
     // Hide the bottom row title semantics when the top title semantics are active.
-    val hideTopRowSemantics = colorTransitionFraction < 0.5f
+    val hideTopRowSemantics by
+        remember(colorTransitionFraction) { derivedStateOf { colorTransitionFraction() < 0.5f } }
     val hideBottomRowSemantics = !hideTopRowSemantics
 
     // Set up support for resizing the top app bar when vertically dragging the bar itself.
-    val appBarDragModifier = if (scrollBehavior != null && !scrollBehavior.isPinned) {
-        Modifier.draggable(
-            orientation = Orientation.Vertical,
-            state = rememberDraggableState { delta ->
-                scrollBehavior.state.heightOffset += delta
-            },
-            onDragStopped = { velocity ->
-                settleAppBar(
-                    scrollBehavior.state,
-                    velocity,
-                    scrollBehavior.flingAnimationSpec,
-                    scrollBehavior.snapAnimationSpec
-                )
-            }
-        )
-    } else {
-        Modifier
-    }
+    val appBarDragModifier =
+        if (scrollBehavior != null && !scrollBehavior.isPinned) {
+            Modifier.draggable(
+                orientation = Orientation.Vertical,
+                state =
+                    rememberDraggableState { delta -> scrollBehavior.state.heightOffset += delta },
+                onDragStopped = { velocity ->
+                    settleAppBar(
+                        scrollBehavior.state,
+                        velocity,
+                        scrollBehavior.flingAnimationSpec,
+                        scrollBehavior.snapAnimationSpec
+                    )
+                }
+            )
+        } else {
+            Modifier
+        }
 
-    Surface(modifier = modifier.then(appBarDragModifier), color = appBarContainerColor) {
+    Box(
+        modifier =
+            modifier
+                .then(appBarDragModifier)
+                .drawBehind { drawRect(color = appBarContainerColor()) }
+                .semantics { isTraversalGroup = true }
+                .pointerInput(Unit) {}
+    ) {
         Column {
             TopAppBarLayout(
-                modifier = Modifier
-                    .windowInsetsPadding(windowInsets)
-                    // clip after padding so we don't show the title over the inset area
-                    .clipToBounds(),
+                modifier =
+                    Modifier.windowInsetsPadding(windowInsets)
+                        // clip after padding so we don't show the title over the inset area
+                        .clipToBounds(),
                 heightPx = pinnedHeightPx,
                 navigationIconContentColor = colors.navigationIconContentColor,
                 titleContentColor = colors.titleContentColor,
@@ -378,27 +392,37 @@
                 actions = actionsRow,
             )
             TopAppBarLayout(
-                modifier = Modifier
-                    // only apply the horizontal sides of the window insets padding, since the top
-                    // padding will always be applied by the layout above
-                    .windowInsetsPadding(windowInsets.only(WindowInsetsSides.Horizontal))
-                    .clipToBounds(),
-                heightPx = maxHeightPx.floatValue - pinnedHeightPx +
-                    (scrollBehavior?.state?.heightOffset ?: 0f),
+                modifier =
+                    Modifier
+                        // only apply the horizontal sides of the window insets padding, since the
+                        // top
+                        // padding will always be applied by the layout above
+                        .windowInsetsPadding(windowInsets.only(WindowInsetsSides.Horizontal))
+                        .clipToBounds(),
+                heightPx =
+                    maxHeightPx.floatValue - pinnedHeightPx +
+                        (scrollBehavior?.state?.heightOffset ?: 0f),
                 navigationIconContentColor = colors.navigationIconContentColor,
                 titleContentColor = colors.titleContentColor,
                 actionIconContentColor = colors.actionIconContentColor,
                 title = {
-                    Box(modifier = Modifier.onGloballyPositioned { coordinates ->
-                        val measuredMaxHeightPx = density.run {
-                            MaxHeightWithoutTitle.toPx() + coordinates.size.height.toFloat()
-                        }
-                        // Allow larger max height for multi-line title, but do not reduce
-                        // max height to prevent flaky.
-                        if (measuredMaxHeightPx > defaultMaxHeightPx) {
-                            maxHeightPx.floatValue = measuredMaxHeightPx
-                        }
-                    }) { title() }
+                    Box(
+                        modifier =
+                            Modifier.onGloballyPositioned { coordinates ->
+                                val measuredMaxHeightPx =
+                                    density.run {
+                                        MaxHeightWithoutTitle.toPx() +
+                                            coordinates.size.height.toFloat()
+                                    }
+                                // Allow larger max height for multi-line title, but do not reduce
+                                // max height to prevent flaky.
+                                if (measuredMaxHeightPx > defaultMaxHeightPx) {
+                                    maxHeightPx.floatValue = measuredMaxHeightPx
+                                }
+                            }
+                    ) {
+                        title()
+                    }
                 },
                 titleTextStyle = titleTextStyle,
                 titleAlpha = bottomTitleAlpha,
@@ -420,21 +444,21 @@
  * @param modifier a [Modifier]
  * @param heightPx the total height this layout is capped to
  * @param navigationIconContentColor the content color that will be applied via a
- * [LocalContentColor] when composing the navigation icon
+ *   [LocalContentColor] when composing the navigation icon
  * @param titleContentColor the color that will be applied via a [LocalContentColor] when composing
- * the title
+ *   the title
  * @param actionIconContentColor the content color that will be applied via a [LocalContentColor]
- * when composing the action icons
+ *   when composing the action icons
  * @param title the top app bar title (header)
  * @param titleTextStyle the title's text style
  * @param modifier a [Modifier]
  * @param titleAlpha the title's alpha
  * @param titleVerticalArrangement the title's vertical arrangement
  * @param titleBottomPadding the title's bottom padding
- * @param hideTitleSemantics hides the title node from the semantic tree. Apply this
- * boolean when this layout is part of a [TwoRowsTopAppBar] to hide the title's semantics
- * from accessibility services. This is needed to avoid having multiple titles visible to
- * accessibility services at the same time, when animating between collapsed / expanded states.
+ * @param hideTitleSemantics hides the title node from the semantic tree. Apply this boolean when
+ *   this layout is part of a [TwoRowsTopAppBar] to hide the title's semantics from accessibility
+ *   services. This is needed to avoid having multiple titles visible to accessibility services at
+ *   the same time, when animating between collapsed / expanded states.
  * @param navigationIcon a navigation icon [Composable]
  * @param actions actions [Composable]
  * @param titleScaleDisabled whether the title font scaling is disabled. Default is disabled.
@@ -448,7 +472,7 @@
     actionIconContentColor: Color,
     title: @Composable () -> Unit,
     titleTextStyle: TextStyle,
-    titleAlpha: Float,
+    titleAlpha: () -> Float,
     titleVerticalArrangement: Arrangement.Vertical,
     titleBottomPadding: Int,
     hideTitleSemantics: Boolean,
@@ -458,41 +482,33 @@
 ) {
     Layout(
         {
-            Box(
-                Modifier
-                    .layoutId("navigationIcon")
-                    .padding(start = TopAppBarHorizontalPadding)
-            ) {
+            Box(Modifier.layoutId("navigationIcon").padding(start = TopAppBarHorizontalPadding)) {
                 CompositionLocalProvider(
                     LocalContentColor provides navigationIconContentColor,
                     content = navigationIcon
                 )
             }
             Box(
-                Modifier
-                    .layoutId("title")
+                Modifier.layoutId("title")
                     .padding(horizontal = TopAppBarHorizontalPadding)
-                    .then(if (hideTitleSemantics) Modifier.clearAndSetSemantics { } else Modifier)
-                    .graphicsLayer(alpha = titleAlpha)
+                    .then(if (hideTitleSemantics) Modifier.clearAndSetSemantics {} else Modifier)
+                    .graphicsLayer { alpha = titleAlpha() }
             ) {
                 ProvideTextStyle(value = titleTextStyle) {
                     CompositionLocalProvider(
                         LocalContentColor provides titleContentColor,
-                        LocalDensity provides with(LocalDensity.current) {
-                            Density(
-                                density = density,
-                                fontScale = if (titleScaleDisabled) 1f else fontScale,
-                            )
-                        },
+                        LocalDensity provides
+                            with(LocalDensity.current) {
+                                Density(
+                                    density = density,
+                                    fontScale = if (titleScaleDisabled) 1f else fontScale,
+                                )
+                            },
                         content = title
                     )
                 }
             }
-            Box(
-                Modifier
-                    .layoutId("actionIcons")
-                    .padding(end = TopAppBarHorizontalPadding)
-            ) {
+            Box(Modifier.layoutId("actionIcons").padding(end = TopAppBarHorizontalPadding)) {
                 CompositionLocalProvider(
                     LocalContentColor provides actionIconContentColor,
                     content = actions
@@ -502,20 +518,24 @@
         modifier = modifier
     ) { measurables, constraints ->
         val navigationIconPlaceable =
-            measurables.first { it.layoutId == "navigationIcon" }
+            measurables
+                .first { it.layoutId == "navigationIcon" }
                 .measure(constraints.copy(minWidth = 0))
         val actionIconsPlaceable =
-            measurables.first { it.layoutId == "actionIcons" }
+            measurables
+                .first { it.layoutId == "actionIcons" }
                 .measure(constraints.copy(minWidth = 0))
 
-        val maxTitleWidth = if (constraints.maxWidth == Constraints.Infinity) {
-            constraints.maxWidth
-        } else {
-            (constraints.maxWidth - navigationIconPlaceable.width - actionIconsPlaceable.width)
-                .coerceAtLeast(0)
-        }
+        val maxTitleWidth =
+            if (constraints.maxWidth == Constraints.Infinity) {
+                constraints.maxWidth
+            } else {
+                (constraints.maxWidth - navigationIconPlaceable.width - actionIconsPlaceable.width)
+                    .coerceAtLeast(0)
+            }
         val titlePlaceable =
-            measurables.first { it.layoutId == "title" }
+            measurables
+                .first { it.layoutId == "title" }
                 .measure(constraints.copy(minWidth = 0, maxWidth = maxTitleWidth))
 
         // Locate the title's baseline.
@@ -538,19 +558,23 @@
             // Title
             titlePlaceable.placeRelative(
                 x = max(TopAppBarTitleInset.roundToPx(), navigationIconPlaceable.width),
-                y = when (titleVerticalArrangement) {
-                    Arrangement.Center -> (layoutHeight - titlePlaceable.height) / 2
-                    // Apply bottom padding from the title's baseline only when the Arrangement is
-                    // "Bottom".
-                    Arrangement.Bottom ->
-                        if (titleBottomPadding == 0) layoutHeight - titlePlaceable.height
-                        else layoutHeight - titlePlaceable.height - max(
-                            0,
-                            titleBottomPadding - titlePlaceable.height + titleBaseline
-                        )
-                    // Arrangement.Top
-                    else -> 0
-                }
+                y =
+                    when (titleVerticalArrangement) {
+                        Arrangement.Center -> (layoutHeight - titlePlaceable.height) / 2
+                        // Apply bottom padding from the title's baseline only when the Arrangement
+                        // is "Bottom".
+                        Arrangement.Bottom ->
+                            if (titleBottomPadding == 0) layoutHeight - titlePlaceable.height
+                            else
+                                layoutHeight -
+                                    titlePlaceable.height -
+                                    max(
+                                        0,
+                                        titleBottomPadding - titlePlaceable.height + titleBaseline
+                                    )
+                        // Arrangement.Top
+                        else -> 0
+                    }
             )
 
             // Action icons
@@ -562,7 +586,6 @@
     }
 }
 
-
 /**
  * Settles the app bar by flinging, in case the given velocity is greater than zero, and snapping
  * after the fling settles.
@@ -587,9 +610,9 @@
     if (flingAnimationSpec != null && abs(velocity) > 1f) {
         var lastValue = 0f
         AnimationState(
-            initialValue = 0f,
-            initialVelocity = velocity,
-        )
+                initialValue = 0f,
+                initialVelocity = velocity,
+            )
             .animateDecay(flingAnimationSpec) {
                 val delta = value - lastValue
                 val initialHeightOffset = state.heightOffset
@@ -603,9 +626,7 @@
     }
     // Snap if animation specs were provided.
     if (snapAnimationSpec != null) {
-        if (state.heightOffset < 0 &&
-            state.heightOffset > state.heightOffsetLimit
-        ) {
+        if (state.heightOffset < 0 && state.heightOffset > state.heightOffsetLimit) {
             AnimationState(initialValue = state.heightOffset).animateTo(
                 if (state.collapsedFraction < 0.5f) {
                     0f
@@ -613,7 +634,9 @@
                     state.heightOffsetLimit
                 },
                 animationSpec = snapAnimationSpec
-            ) { state.heightOffset = value }
+            ) {
+                state.heightOffset = value
+            }
         }
     }
 
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBarTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBarTest.kt
index ea69eab..0a4f0d9 100644
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBarTest.kt
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBarTest.kt
@@ -37,15 +37,11 @@
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.painter.ColorPainter
 import androidx.compose.ui.input.nestedscroll.nestedScroll
-import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.testTag
 import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.test.assertHeightIsEqualTo
 import androidx.compose.ui.test.assertIsDisplayed
-import androidx.compose.ui.test.assertLeftPositionInRootIsEqualTo
-import androidx.compose.ui.test.assertTopPositionInRootIsEqualTo
 import androidx.compose.ui.test.assertWidthIsEqualTo
-import androidx.compose.ui.test.getUnclippedBoundsInRoot
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
 import androidx.compose.ui.test.onNodeWithText
@@ -53,33 +49,24 @@
 import androidx.compose.ui.test.swipeLeft
 import androidx.compose.ui.test.swipeRight
 import androidx.compose.ui.text.TextStyle
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.height
-import androidx.compose.ui.unit.width
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.android.settingslib.spa.testutils.rootWidth
 import com.android.settingslib.spa.testutils.setContentForSizeAssertions
 import com.google.common.truth.Truth.assertThat
-import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @OptIn(ExperimentalMaterial3Api::class)
-@Ignore("b/346785755")
 @RunWith(AndroidJUnit4::class)
 class CustomizedAppBarTest {
 
-    @get:Rule
-    val rule = createComposeRule()
+    @get:Rule val rule = createComposeRule()
 
     @Test
     fun smallTopAppBar_expandsToScreen() {
         rule
-            .setContentForSizeAssertions {
-                CustomizedTopAppBar(title = { Text("Title") })
-            }
+            .setContentForSizeAssertions { CustomizedTopAppBar(title = { Text("Title") }) }
             .assertHeightIsEqualTo(ContainerHeight)
             .assertWidthIsEqualTo(rule.rootWidth())
     }
@@ -88,51 +75,12 @@
     fun smallTopAppBar_withTitle() {
         val title = "Title"
         rule.setContent {
-            Box(Modifier.testTag(TopAppBarTestTag)) {
-                CustomizedTopAppBar(title = { Text(title) })
-            }
+            Box(Modifier.testTag(TopAppBarTestTag)) { CustomizedTopAppBar(title = { Text(title) }) }
         }
         rule.onNodeWithText(title).assertIsDisplayed()
     }
 
     @Test
-    fun smallTopAppBar_default_positioning() {
-        rule.setContent {
-            Box(Modifier.testTag(TopAppBarTestTag)) {
-                CustomizedTopAppBar(
-                    navigationIcon = {
-                        FakeIcon(Modifier.testTag(NavigationIconTestTag))
-                    },
-                    title = {
-                        Text("Title", Modifier.testTag(TitleTestTag))
-                    },
-                    actions = {
-                        FakeIcon(Modifier.testTag(ActionsTestTag))
-                    }
-                )
-            }
-        }
-        assertSmallDefaultPositioning()
-    }
-
-    @Test
-    fun smallTopAppBar_noNavigationIcon_positioning() {
-        rule.setContent {
-            Box(Modifier.testTag(TopAppBarTestTag)) {
-                CustomizedTopAppBar(
-                    title = {
-                        Text("Title", Modifier.testTag(TitleTestTag))
-                    },
-                    actions = {
-                        FakeIcon(Modifier.testTag(ActionsTestTag))
-                    }
-                )
-            }
-        }
-        assertSmallPositioningWithoutNavigation()
-    }
-
-    @Test
     fun smallTopAppBar_titleDefaultStyle() {
         var textStyle: TextStyle? = null
         var expectedTextStyle: TextStyle? = null
@@ -188,29 +136,6 @@
         assertThat(actionsColor).isEqualTo(expectedActionsColor)
     }
 
-    @Test
-    fun largeTopAppBar_scrolled_positioning() {
-        val content = @Composable { scrollBehavior: TopAppBarScrollBehavior? ->
-            Box(Modifier.testTag(TopAppBarTestTag)) {
-                CustomizedLargeTopAppBar(
-                    navigationIcon = {
-                        FakeIcon(Modifier.testTag(NavigationIconTestTag))
-                    },
-                    title = "Title",
-                    actions = {
-                        FakeIcon(Modifier.testTag(ActionsTestTag))
-                    },
-                    scrollBehavior = scrollBehavior,
-                )
-            }
-        }
-        assertLargeScrolledHeight(
-            MaxHeightWithoutTitle + DefaultTitleHeight,
-            MaxHeightWithoutTitle + DefaultTitleHeight,
-            content,
-        )
-    }
-
     @OptIn(ExperimentalMaterial3Api::class)
     @Test
     fun topAppBar_enterAlways_allowHorizontalScroll() {
@@ -221,14 +146,10 @@
         }
 
         rule.onNodeWithTag(LazyListTag).performTouchInput { swipeLeft() }
-        rule.runOnIdle {
-            assertThat(state.firstVisibleItemIndex).isEqualTo(1)
-        }
+        rule.runOnIdle { assertThat(state.firstVisibleItemIndex).isEqualTo(1) }
 
         rule.onNodeWithTag(LazyListTag).performTouchInput { swipeRight() }
-        rule.runOnIdle {
-            assertThat(state.firstVisibleItemIndex).isEqualTo(0)
-        }
+        rule.runOnIdle { assertThat(state.firstVisibleItemIndex).isEqualTo(0) }
     }
 
     @OptIn(ExperimentalMaterial3Api::class)
@@ -241,14 +162,10 @@
         }
 
         rule.onNodeWithTag(LazyListTag).performTouchInput { swipeLeft() }
-        rule.runOnIdle {
-            assertThat(state.firstVisibleItemIndex).isEqualTo(1)
-        }
+        rule.runOnIdle { assertThat(state.firstVisibleItemIndex).isEqualTo(1) }
 
         rule.onNodeWithTag(LazyListTag).performTouchInput { swipeRight() }
-        rule.runOnIdle {
-            assertThat(state.firstVisibleItemIndex).isEqualTo(0)
-        }
+        rule.runOnIdle { assertThat(state.firstVisibleItemIndex).isEqualTo(0) }
     }
 
     @OptIn(ExperimentalMaterial3Api::class)
@@ -257,21 +174,14 @@
         lateinit var state: LazyListState
         rule.setContent {
             state = rememberLazyListState()
-            MultiPageContent(
-                TopAppBarDefaults.pinnedScrollBehavior(),
-                state
-            )
+            MultiPageContent(TopAppBarDefaults.pinnedScrollBehavior(), state)
         }
 
         rule.onNodeWithTag(LazyListTag).performTouchInput { swipeLeft() }
-        rule.runOnIdle {
-            assertThat(state.firstVisibleItemIndex).isEqualTo(1)
-        }
+        rule.runOnIdle { assertThat(state.firstVisibleItemIndex).isEqualTo(1) }
 
         rule.onNodeWithTag(LazyListTag).performTouchInput { swipeRight() }
-        rule.runOnIdle {
-            assertThat(state.firstVisibleItemIndex).isEqualTo(0)
-        }
+        rule.runOnIdle { assertThat(state.firstVisibleItemIndex).isEqualTo(0) }
     }
 
     @OptIn(ExperimentalMaterial3Api::class)
@@ -285,11 +195,7 @@
                 )
             }
         ) { contentPadding ->
-            LazyRow(
-                Modifier
-                    .fillMaxSize()
-                    .testTag(LazyListTag), state
-            ) {
+            LazyRow(Modifier.fillMaxSize().testTag(LazyListTag), state) {
                 items(2) { page ->
                     LazyColumn(
                         modifier = Modifier.fillParentMaxSize(),
@@ -308,146 +214,19 @@
     }
 
     /**
-     * Checks the app bar's components positioning when it's a [CustomizedTopAppBar]
-     * or a larger app bar that is scrolled up and collapsed into a small
-     * configuration and there is no navigation icon.
-     */
-    private fun assertSmallPositioningWithoutNavigation(isCenteredTitle: Boolean = false) {
-        val appBarBounds = rule.onNodeWithTag(TopAppBarTestTag).getUnclippedBoundsInRoot()
-        val titleBounds = rule.onNodeWithTag(TitleTestTag).getUnclippedBoundsInRoot()
-
-        val titleNode = rule.onNodeWithTag(TitleTestTag)
-        // Title should be vertically centered
-        titleNode.assertTopPositionInRootIsEqualTo((appBarBounds.height - titleBounds.height) / 2)
-        if (isCenteredTitle) {
-            // Title should be horizontally centered
-            titleNode.assertLeftPositionInRootIsEqualTo(
-                (appBarBounds.width - titleBounds.width) / 2
-            )
-        } else {
-            // Title should now be placed 16.dp from the start, as there is no navigation icon
-            // 4.dp padding for the whole app bar + 12.dp inset
-            titleNode.assertLeftPositionInRootIsEqualTo(4.dp + 12.dp)
-        }
-
-        rule.onNodeWithTag(ActionsTestTag)
-            // Action should still be placed at the end
-            .assertLeftPositionInRootIsEqualTo(expectedActionPosition(appBarBounds.width))
-    }
-
-    /**
-     * Checks the app bar's components positioning when it's a [CustomizedTopAppBar].
-     */
-    private fun assertSmallDefaultPositioning(isCenteredTitle: Boolean = false) {
-        val appBarBounds = rule.onNodeWithTag(TopAppBarTestTag).getUnclippedBoundsInRoot()
-        val titleBounds = rule.onNodeWithTag(TitleTestTag).getUnclippedBoundsInRoot()
-        val appBarBottomEdgeY = appBarBounds.top + appBarBounds.height
-
-        rule.onNodeWithTag(NavigationIconTestTag)
-            // Navigation icon should be 4.dp from the start
-            .assertLeftPositionInRootIsEqualTo(AppBarStartAndEndPadding)
-            // Navigation icon should be centered within the height of the app bar.
-            .assertTopPositionInRootIsEqualTo(
-                appBarBottomEdgeY - AppBarTopAndBottomPadding - FakeIconSize
-            )
-
-        val titleNode = rule.onNodeWithTag(TitleTestTag)
-        // Title should be vertically centered
-        titleNode.assertTopPositionInRootIsEqualTo((appBarBounds.height - titleBounds.height) / 2)
-        if (isCenteredTitle) {
-            // Title should be horizontally centered
-            titleNode.assertLeftPositionInRootIsEqualTo(
-                (appBarBounds.width - titleBounds.width) / 2
-            )
-        } else {
-            // Title should be 56.dp from the start
-            // 4.dp padding for the whole app bar + 48.dp icon size + 4.dp title padding.
-            titleNode.assertLeftPositionInRootIsEqualTo(4.dp + FakeIconSize + 4.dp)
-        }
-
-        rule.onNodeWithTag(ActionsTestTag)
-            // Action should be placed at the end
-            .assertLeftPositionInRootIsEqualTo(expectedActionPosition(appBarBounds.width))
-            // Action should be 8.dp from the top
-            .assertTopPositionInRootIsEqualTo(
-                appBarBottomEdgeY - AppBarTopAndBottomPadding - FakeIconSize
-            )
-    }
-
-    /**
-     * Checks that changing values at a [CustomizedLargeTopAppBar] scroll behavior
-     * affects the height of the app bar.
-     *
-     * This check partially and fully collapses the app bar to test its height.
-     *
-     * @param appBarMaxHeight the max height of the app bar [content]
-     * @param appBarMinHeight the min height of the app bar [content]
-     * @param content a Composable that adds a CustomizedLargeTopAppBar
-     */
-    @OptIn(ExperimentalMaterial3Api::class)
-    private fun assertLargeScrolledHeight(
-        appBarMaxHeight: Dp,
-        appBarMinHeight: Dp,
-        content: @Composable (TopAppBarScrollBehavior?) -> Unit
-    ) {
-        val fullyCollapsedOffsetDp = appBarMaxHeight - appBarMinHeight
-        val partiallyCollapsedOffsetDp = fullyCollapsedOffsetDp / 3
-        var partiallyCollapsedHeightOffsetPx = 0f
-        var fullyCollapsedHeightOffsetPx = 0f
-        lateinit var scrollBehavior: TopAppBarScrollBehavior
-        rule.setContent {
-            scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
-            with(LocalDensity.current) {
-                partiallyCollapsedHeightOffsetPx = partiallyCollapsedOffsetDp.toPx()
-                fullyCollapsedHeightOffsetPx = fullyCollapsedOffsetDp.toPx()
-            }
-
-            content(scrollBehavior)
-        }
-
-        // Simulate a partially collapsed app bar.
-        rule.runOnIdle {
-            scrollBehavior.state.heightOffset = -partiallyCollapsedHeightOffsetPx
-            scrollBehavior.state.contentOffset = -partiallyCollapsedHeightOffsetPx
-        }
-        rule.waitForIdle()
-        rule.onNodeWithTag(TopAppBarTestTag)
-            .assertHeightIsEqualTo(
-                appBarMaxHeight - partiallyCollapsedOffsetDp
-            )
-
-        // Simulate a fully collapsed app bar.
-        rule.runOnIdle {
-            scrollBehavior.state.heightOffset = -fullyCollapsedHeightOffsetPx
-            // Simulate additional content scroll beyond the max offset scroll.
-            scrollBehavior.state.contentOffset =
-                -fullyCollapsedHeightOffsetPx - partiallyCollapsedHeightOffsetPx
-        }
-        rule.waitForIdle()
-        // Check that the app bar collapsed to its min height.
-        rule.onNodeWithTag(TopAppBarTestTag).assertHeightIsEqualTo(appBarMinHeight)
-    }
-
-    /**
      * An [IconButton] with an [Icon] inside for testing positions.
      *
      * An [IconButton] is defaulted to be 48X48dp, while its child [Icon] is defaulted to 24x24dp.
      */
-    private val FakeIcon = @Composable { modifier: Modifier ->
-        IconButton(
-            onClick = { /* doSomething() */ },
-            modifier = modifier.semantics(mergeDescendants = true) {}
-        ) {
-            Icon(ColorPainter(Color.Red), null)
+    private val FakeIcon =
+        @Composable { modifier: Modifier ->
+            IconButton(
+                onClick = { /* doSomething() */ },
+                modifier = modifier.semantics(mergeDescendants = true) {}
+            ) {
+                Icon(ColorPainter(Color.Red), null)
+            }
         }
-    }
-
-    private fun expectedActionPosition(appBarWidth: Dp): Dp =
-        appBarWidth - AppBarStartAndEndPadding - FakeIconSize
-
-    private val FakeIconSize = 48.dp
-    private val AppBarStartAndEndPadding = 4.dp
-    private val AppBarTopAndBottomPadding = (ContainerHeight - FakeIconSize) / 2
 
     private val LazyListTag = "lazyList"
     private val TopAppBarTestTag = "bar"
diff --git a/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/ComposeContentTestRuleExt.kt b/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/ComposeContentTestRuleExt.kt
index 0436fc2..53d4531 100644
--- a/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/ComposeContentTestRuleExt.kt
+++ b/packages/SettingsLib/Spa/testutils/src/com/android/settingslib/spa/testutils/ComposeContentTestRuleExt.kt
@@ -17,6 +17,7 @@
 package com.android.settingslib.spa.testutils
 
 import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.safeDrawingPadding
 import androidx.compose.foundation.layout.sizeIn
 import androidx.compose.material3.Surface
 import androidx.compose.runtime.Composable
@@ -75,7 +76,7 @@
     setContent {
         SettingsTheme {
             Surface {
-                Box {
+                Box(Modifier.safeDrawingPadding()) {
                     Box(
                         Modifier
                             .sizeIn(maxWidth = parentMaxWidth, maxHeight = parentMaxHeight)
diff --git a/packages/SettingsLib/SpaPrivileged/res/values-fr-rCA/strings.xml b/packages/SettingsLib/SpaPrivileged/res/values-fr-rCA/strings.xml
index a271ff5..7e73c48 100644
--- a/packages/SettingsLib/SpaPrivileged/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/SpaPrivileged/res/values-fr-rCA/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="no_applications" msgid="5800789569715871963">"Aucune application"</string>
+    <string name="no_applications" msgid="5800789569715871963">"Aucune appli"</string>
     <string name="menu_show_system" msgid="906304605807554788">"Afficher le système"</string>
     <string name="menu_hide_system" msgid="374571689914923020">"Masquer le système"</string>
     <string name="app_permission_summary_allowed" msgid="6115213465364138103">"Autorisé"</string>
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsGlobalBoolean.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsGlobalBoolean.kt
index 5d67f57..42528695 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsGlobalBoolean.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsGlobalBoolean.kt
@@ -21,16 +21,25 @@
 import android.provider.Settings
 import kotlin.properties.ReadWriteProperty
 import kotlin.reflect.KProperty
+import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.conflate
 import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
 
-fun Context.settingsGlobalBoolean(name: String, defaultValue: Boolean = false):
-    ReadWriteProperty<Any?, Boolean> = SettingsGlobalBooleanDelegate(this, name, defaultValue)
+fun Context.settingsGlobalBoolean(
+    name: String,
+    defaultValue: Boolean = false,
+): ReadWriteProperty<Any?, Boolean> = SettingsGlobalBooleanDelegate(this, name, defaultValue)
 
 fun Context.settingsGlobalBooleanFlow(name: String, defaultValue: Boolean = false): Flow<Boolean> {
     val value by settingsGlobalBoolean(name, defaultValue)
-    return settingsGlobalChangeFlow(name).map { value }.distinctUntilChanged()
+    return settingsGlobalChangeFlow(name)
+        .map { value }
+        .distinctUntilChanged()
+        .conflate()
+        .flowOn(Dispatchers.Default)
 }
 
 private class SettingsGlobalBooleanDelegate(
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureBoolean.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureBoolean.kt
index 25090a4..d5f4ec2 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureBoolean.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureBoolean.kt
@@ -22,16 +22,25 @@
 import com.android.settingslib.spaprivileged.database.contentChangeFlow
 import kotlin.properties.ReadWriteProperty
 import kotlin.reflect.KProperty
+import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.conflate
 import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
 
-fun Context.settingsSecureBoolean(name: String, defaultValue: Boolean = false):
-    ReadWriteProperty<Any?, Boolean> = SettingsSecureBooleanDelegate(this, name, defaultValue)
+fun Context.settingsSecureBoolean(
+    name: String,
+    defaultValue: Boolean = false,
+): ReadWriteProperty<Any?, Boolean> = SettingsSecureBooleanDelegate(this, name, defaultValue)
 
 fun Context.settingsSecureBooleanFlow(name: String, defaultValue: Boolean = false): Flow<Boolean> {
     val value by settingsSecureBoolean(name, defaultValue)
-    return contentChangeFlow(Settings.Secure.getUriFor(name)).map { value }.distinctUntilChanged()
+    return contentChangeFlow(Settings.Secure.getUriFor(name))
+        .map { value }
+        .distinctUntilChanged()
+        .conflate()
+        .flowOn(Dispatchers.Default)
 }
 
 private class SettingsSecureBooleanDelegate(
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureString.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureString.kt
new file mode 100644
index 0000000..a706308
--- /dev/null
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureString.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.spaprivileged.settingsprovider
+
+import android.content.ContentResolver
+import android.content.Context
+import android.provider.Settings
+import com.android.settingslib.spaprivileged.database.contentChangeFlow
+import kotlin.properties.ReadWriteProperty
+import kotlin.reflect.KProperty
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.conflate
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+
+fun Context.settingsSecureString(
+    name: String,
+    defaultValue: String = ""
+): ReadWriteProperty<Any?, String> = SettingsSecureStringDelegate(this, name, defaultValue)
+
+fun Context.settingsSecureStringFlow(name: String, defaultValue: String = ""): Flow<String> {
+    val value by settingsSecureString(name, defaultValue)
+    return contentChangeFlow(Settings.Secure.getUriFor(name))
+        .map { value }
+        .distinctUntilChanged()
+        .conflate()
+        .flowOn(Dispatchers.Default)
+}
+
+private class SettingsSecureStringDelegate(
+    context: Context,
+    private val name: String,
+    private val defaultValue: String = "",
+) : ReadWriteProperty<Any?, String> {
+
+    private val contentResolver: ContentResolver = context.contentResolver
+
+    override fun getValue(thisRef: Any?, property: KProperty<*>): String =
+        Settings.Secure.getString(contentResolver, name) ?: defaultValue
+
+    override fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
+        Settings.Secure.putString(contentResolver, name, value)
+    }
+}
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt
index 2a04424..627b248 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt
@@ -19,6 +19,7 @@
 import android.content.Context
 import android.content.pm.ApplicationInfo
 import android.os.Process
+import android.os.UserHandle
 import androidx.compose.runtime.Composable
 import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
 import com.android.settingslib.spa.framework.common.SettingsPageProvider
@@ -88,7 +89,8 @@
  *
  * If true, the app gets all permissions, so the permission toggle always not changeable.
  */
-fun AppRecord.isSystemOrRootUid(): Boolean = app.uid in listOf(Process.SYSTEM_UID, Process.ROOT_UID)
+fun AppRecord.isSystemOrRootUid(): Boolean =
+    UserHandle.getAppId(app.uid) in listOf(Process.SYSTEM_UID, Process.ROOT_UID)
 
 /**
  * Gets whether the permission on / off is changeable for the given app.
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt
index c9934ad..fb23637 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceModel.kt
@@ -115,7 +115,7 @@
             content: @Composable (SwitchPreferenceModel) -> Unit,
         ) {
             val context = LocalContext.current
-            val restrictedSwitchPreferenceModel = remember(restrictedMode, model.title) {
+            val restrictedSwitchPreferenceModel = remember(restrictedMode, model) {
                 RestrictedSwitchPreferenceModel(context, model, restrictedMode)
             }
             restrictedSwitchPreferenceModel.RestrictionWrapper {
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUserTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUserTest.kt
index dd7c036..a59a724 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUserTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/framework/compose/DisposableBroadcastReceiverAsUserTest.kt
@@ -23,8 +23,8 @@
 import android.os.UserHandle
 import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.platform.LocalLifecycleOwner
 import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.lifecycle.compose.LocalLifecycleOwner
 import androidx.lifecycle.testing.TestLifecycleOwner
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import org.junit.Rule
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt
index c60ce41..b1baa86 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/model/app/AppListRepositoryTest.kt
@@ -31,6 +31,8 @@
 import android.os.BadParcelableException
 import android.os.DeadObjectException
 import android.os.UserManager
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
 import android.platform.test.flag.junit.SetFlagsRule
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -76,9 +78,7 @@
     }
 
     private val mockUserManager = mock<UserManager> {
-        on { getUserInfo(ADMIN_USER_ID) } doReturn UserInfo().apply {
-            flags = UserInfo.FLAG_ADMIN
-        }
+        on { getUserInfo(ADMIN_USER_ID) } doReturn UserInfo(0, "admin", UserInfo.FLAG_ADMIN)
         on { getProfileIdsWithDisabled(ADMIN_USER_ID) } doReturn
             intArrayOf(ADMIN_USER_ID, MANAGED_PROFILE_USER_ID)
     }
@@ -281,9 +281,9 @@
         )
     }
 
+    @EnableFlags(Flags.FLAG_PROVIDE_INFO_OF_APK_IN_APEX)
     @Test
     fun loadApps_hasApkInApexInfo_shouldNotIncludeAllHiddenApps() = runTest {
-        mSetFlagsRule.enableFlags(Flags.FLAG_PROVIDE_INFO_OF_APK_IN_APEX)
         packageManager.stub {
             on { getInstalledModules(any()) } doReturn listOf(HIDDEN_MODULE)
         }
@@ -297,9 +297,9 @@
         assertThat(appList).containsExactly(NORMAL_APP)
     }
 
+    @DisableFlags(Flags.FLAG_PROVIDE_INFO_OF_APK_IN_APEX)
     @Test
     fun loadApps_noApkInApexInfo_shouldNotIncludeHiddenSystemModule() = runTest {
-        mSetFlagsRule.disableFlags(Flags.FLAG_PROVIDE_INFO_OF_APK_IN_APEX)
         packageManager.stub {
             on { getInstalledModules(any()) } doReturn listOf(HIDDEN_MODULE)
         }
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureStringTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureStringTest.kt
new file mode 100644
index 0000000..e3d182b
--- /dev/null
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/settingsprovider/SettingsSecureStringTest.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.spaprivileged.settingsprovider
+
+import android.content.Context
+import android.provider.Settings
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settingslib.spa.testutils.firstWithTimeoutOrNull
+import com.android.settingslib.spa.testutils.toListWithTimeout
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.async
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.runBlocking
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class SettingsSecureStringTest {
+
+    private val context: Context = ApplicationProvider.getApplicationContext()
+
+    @Test
+    fun getValue_returnCorrectValue() {
+        Settings.Secure.putString(context.contentResolver, TEST_NAME, VALUE)
+
+        val value by context.settingsSecureString(TEST_NAME)
+
+        assertThat(value).isEqualTo(VALUE)
+    }
+
+    @Test
+    fun setValue_correctValueSet() {
+        var value by context.settingsSecureString(TEST_NAME)
+
+        value = VALUE
+
+        assertThat(Settings.Secure.getString(context.contentResolver, TEST_NAME)).isEqualTo(VALUE)
+    }
+
+    @Test
+    fun settingsSecureStringFlow_valueNotChanged() = runBlocking {
+        var value by context.settingsSecureString(TEST_NAME)
+        value = VALUE
+
+        val flow = context.settingsSecureStringFlow(TEST_NAME)
+
+        assertThat(flow.firstWithTimeoutOrNull()).isEqualTo(VALUE)
+    }
+
+    @Test
+    fun settingsSecureStringFlow_collectAfterValueChanged_onlyKeepLatest() = runBlocking {
+        var value by context.settingsSecureString(TEST_NAME)
+        value = ""
+
+        val flow = context.settingsSecureStringFlow(TEST_NAME)
+        value = VALUE
+
+        assertThat(flow.firstWithTimeoutOrNull()).isEqualTo(VALUE)
+    }
+
+    @Test
+    fun settingsSecureStringFlow_collectBeforeValueChanged_getBoth() = runBlocking {
+        var value by context.settingsSecureString(TEST_NAME)
+        value = ""
+
+        val listDeferred = async { context.settingsSecureStringFlow(TEST_NAME).toListWithTimeout() }
+        delay(100)
+        value = VALUE
+
+        assertThat(listDeferred.await()).containsAtLeast("", VALUE).inOrder()
+    }
+
+    private companion object {
+        const val TEST_NAME = "test_string_delegate"
+        const val VALUE = "value"
+    }
+}
diff --git a/packages/SettingsLib/Utils/src/com/android/settingslib/utils/BuildCompatUtils.java b/packages/SettingsLib/Utils/src/com/android/settingslib/utils/BuildCompatUtils.java
deleted file mode 100644
index bf3651b..0000000
--- a/packages/SettingsLib/Utils/src/com/android/settingslib/utils/BuildCompatUtils.java
+++ /dev/null
@@ -1,60 +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.settingslib.utils;
-
-import android.os.Build;
-
-import androidx.annotation.ChecksSdkIntAtLeast;
-
-/**
- * An util class to check whether the current OS version is higher or equal to sdk version of
- * device.
- */
-public final class BuildCompatUtils {
-
-    /**
-     * Implementation of BuildCompat.isAtLeastS() suitable for use in Settings
-     *
-     * @return Whether the current OS version is higher or equal to S.
-     */
-    @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.S)
-    public static boolean isAtLeastS() {
-        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
-    }
-
-    /**
-     * Implementation of BuildCompat.isAtLeastS() suitable for use in Settings
-     *
-     * @return Whether the current OS version is higher or equal to Sv2.
-     */
-    @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.S_V2)
-    public static boolean isAtLeastSV2() {
-        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S_V2;
-    }
-
-    /**
-     * Implementation of BuildCompat.isAtLeastT() suitable for use in Settings
-     *
-     * @return Whether the current OS version is higher or equal to T.
-     */
-    @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.TIRAMISU)
-    public static boolean isAtLeastT() {
-        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU;
-    }
-
-    private BuildCompatUtils() {}
-}
diff --git a/packages/SettingsLib/aconfig/settingslib.aconfig b/packages/SettingsLib/aconfig/settingslib.aconfig
index 32557b9..403e219 100644
--- a/packages/SettingsLib/aconfig/settingslib.aconfig
+++ b/packages/SettingsLib/aconfig/settingslib.aconfig
@@ -64,13 +64,6 @@
 }
 
 flag {
-  name: "allow_all_widgets_on_lockscreen_by_default"
-  namespace: "systemui"
-  description: "Allow all widgets on the lock screen by default."
-  bug: "328261690"
-}
-
-flag {
     name: "enable_determining_advanced_details_header_with_metadata"
     namespace: "pixel_cross_device_control"
     description: "Use metadata instead of device type to determine whether a bluetooth device should use advanced details header."
@@ -79,3 +72,43 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    name: "enable_determining_spatial_audio_attributes_by_profile"
+    namespace: "cross_device_experiences"
+    description: "Use bluetooth profile connection policy to determine spatial audio attributes"
+    bug: "341005211"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
+    name: "volume_panel_broadcast_fix"
+    namespace: "systemui"
+    description: "Make the volume panel's repository listen for the new ACTION_CONSOLIDATED_NOTIFICATION_POLICY_CHANGED broadcast instead of ACTION_NOTIFICATION_POLICY_CHANGED"
+    bug: "347707024"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
+    name: "volume_dialog_audio_sharing_fix"
+    namespace: "cross_device_experiences"
+    description: "Gates whether to show separate volume bars during audio sharing"
+    bug: "336716411"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
+    name: "extreme_power_low_state_vulnerability"
+    namespace: "pixel_energizer"
+    description: "the battery saver can pause all non-essential apps and their corresponding notification when device is in locked state to introduce the security vulnerability"
+    bug: "346513692"
+    metadata {
+      purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/packages/SettingsLib/res/drawable/ic_do_not_disturb_on_24dp.xml b/packages/SettingsLib/res/drawable/ic_do_not_disturb_on_24dp.xml
new file mode 100644
index 0000000..06c0d8c
--- /dev/null
+++ b/packages/SettingsLib/res/drawable/ic_do_not_disturb_on_24dp.xml
@@ -0,0 +1,28 @@
+<!--
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT 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="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/colorControlNormal">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10c5.52,0 10,-4.48 10,-10C22,6.48 17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8c0,-4.41 3.59,-8 8,-8c4.41,0 8,3.59 8,8C20,16.41 16.41,20 12,20z"/>
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M7,11h10v2h-10z"/>
+</vector>
diff --git a/packages/SettingsLib/res/layout/zen_mode_turn_on_dialog_container.xml b/packages/SettingsLib/res/layout/zen_mode_turn_on_dialog_container.xml
index bc330c7..5cf365b 100644
--- a/packages/SettingsLib/res/layout/zen_mode_turn_on_dialog_container.xml
+++ b/packages/SettingsLib/res/layout/zen_mode_turn_on_dialog_container.xml
@@ -28,7 +28,7 @@
         android:layout_height="match_parent"
         android:orientation="vertical">
 
-        <com.android.settingslib.notification.ZenRadioLayout
+        <com.android.settingslib.notification.modes.ZenRadioLayout
             android:id="@+id/zen_conditions"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
@@ -46,7 +46,7 @@
                 android:layout_width="fill_parent"
                 android:layout_height="fill_parent"
                 android:orientation="vertical"/>
-        </com.android.settingslib.notification.ZenRadioLayout>
+        </com.android.settingslib.notification.modes.ZenRadioLayout>
 
         <TextView
             android:id="@+id/zen_alarm_warning"
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 6b6f803..5632fbd 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Laat laai van GPU-ontfoutlae vir ontfoutapps toe"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Aktiveer woordryke verkoperloginskrywing"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Sluit bykomende toestelspesifieke verkoperloglêers by foutverslae in, wat privaat inligting kan bevat, meer batterykrag kan gebruik, en/of meer berging kan gebruik."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Vensteranimasieskaal"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Oorganganimasieskaal"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator-tydsduurskaal"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Maak dat enige program na eksterne berging geskryf kan word, ongeag manifeswaardes"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Dwing aktiwiteite om verstelbaar te wees"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Maak die groottes van alle aktiwiteite verstelbaar vir veelvuldige vensters, ongeag manifeswaardes."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Aktiveer vormvrye vensters"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktiveer steun vir eksperimentele vormvrye vensters."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Aktiveer vryevormvensters (vorige)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Aktiveer steun vir eksperimentele vorige vryevormvensters."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Werkskerm-rugsteunwagwoord"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Volle rekenaarrugsteune word nie tans beskerm nie"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tik om die wagwoord vir volledige rekenaarrugsteune te verander of te verwyder"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Wekkers en onthounotas"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Laat hierdie app toe om wekkers te stel en tydsensitiewe handelinge te skeduleer. Dit laat die app op die agtergrond werk, wat meer batterykrag kan gebruik.\n\nAs hierdie toestemming af is, sal bestaande wekkers en tydgegronde geleenthede wat deur hierdie app geskeduleer is, nie werk nie."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"skedule, wekker, onthounota, horlosie"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Moenie Steur Nie"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Skakel aan"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Skakel Moenie steur nie aan"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nooit"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Tydsduur"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Vra elke keer"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Totdat jy dit afskakel"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Geen naam nie)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Sopas"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Hierdie foon"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Hierdie tablet"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 6f494f0..4c79154 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ለስህተት ማረሚያ መተግበሪያዎች የጂፒዩ ንብርብሮችን መስቀልን ፍቀድ"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"የዝርክርክ ቃላት አቅራቢ ምዝግብ ማስታወሻን መያዝ አንቃ"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"በሳንካ ሪፖርቶች ውስጥ ተጨማሪ መሣሪያ-ተኮር የአቅራቢ ምዝግብ ማስታወሻዎችን ያካትቱ፣ ይህም የግል መረጃን ሊይዝ፣ ተጨማሪ ባትሪ ሊፈጅ እና/ወይም ተጨማሪ ማከማቻ ሊጠቀም ይችላል።"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"የ Window እነማ ልኬት ለውጥ"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"የእነማ ልኬት ለውጥ ሽግግር"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"እነማ አድራጊ ቆይታ መለኪያ"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"የነጻ ቅርጽ መስኮቶችን ያንቁ"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"የሙከራ ነፃ መልክ መስኮቶች ድጋፍን አንቃ"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"ነፃ ቅርጽ መስኮቶች (የቆየ) ያንቁ"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"የሙከራ የቆዩ የነፃ ቅርጽ መስኮቶች ድጋፍን ያንቁ።"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"የዴስክቶፕ መጠባበቂያ ይለፍ ቃል"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ዴስክቶፕ ሙሉ ምትኬዎች በአሁኑ ሰዓት አልተጠበቁም"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"የዴስክቶፕ ሙሉ ምትኬዎች የይለፍ ቃሉን ለመለወጥ ወይም ለማስወገድ ነካ ያድርጉ"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"ማንቂያዎች እና አስታዋሾች"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ይህ መተግበሪያ ማንቂያዎችን እንዲያቀናብር እና የጊዜ ትብነት ያላቸው እርምጃዎችን መርሐግብር እንዲያስይዝ ይፍቀዱለት። ይህ መተግበሪያው ከበስተጀርባ ማሄድ እንዲችል ያስችለዋል፣ ይህም የበለጠ ባትሪ ሊጠቀም ይችላል።\n\nይህ ፈቃድ ከጠፋ በዚህ መተግበሪያ መርሐግብር የተያዘላቸው ነባር ማንቂያዎች እና ጊዜ-ተኮር ክስተቶች አይሰሩም።"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"የጊዜ መርሐግብር፣ ማንቂያ፣ አስታዋሽ ሰዓት"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"አይረብሹ"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"አብራ"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"አትረብሽን አብራ"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"በጭራሽ"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"የቆይታ ጊዜ"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ሁልጊዜ ጠይቅ"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"እስኪያጠፉት ድረስ"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(ስም የለም)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"ልክ አሁን"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"ይህ ስልክ"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ይህ ጡባዊ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 4b11a76..3da23c8 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"‏السماح بتحميل طبقات تصحيح أخطاء GPU لتطبيقات تصحيح الأخطاء"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"تفعيل التسجيل المطوَّل للمورّد"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"تضمين سجلات المورّدين الإضافية الخاصة بالجهاز في تقارير الخطأ، والتي قد تحتوي على معلومات شخصية و/أو تستهلك المزيد من شحن البطارية و/أو تستهلك المزيد من مساحة التخزين"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"حجم الرسوم المتحركة للنافذة"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"حجم الرسوم المتحركة للنقل"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"طول مدة الرسوم المتحركة"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"تفعيل النوافذ الحرة"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"إتاحة استخدام النوافذ الحرة التجريبية"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"تفعيل النوافذ الحرة (القديمة)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"تفعيل عرض النوافذ الحرة التجريبية القديمة"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"كلمة مرور احتياطية للكمبيوتر"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"النُسخ الاحتياطية الكاملة لسطح المكتب غير محمية في الوقت الحالي"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"انقر لتغيير كلمة مرور النسخ الاحتياطية الكاملة لسطح المكتب أو إزالتها."</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"المنبّهات والتذكيرات"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"يمكنك السماح لهذا التطبيق بضبط المنبّهات وجدولة الإجراءات لتنفيذها في الوقت المناسب. ويسمح هذا الإذن بتشغيل التطبيق في الخلفية، ما قد يستهلك المزيد من البطارية.\n\nفي حال عدم تفعيل هذا الإذن، لن تعمل المنبهات المضبوطة والأحداث المستندة إلى الوقت المجدولة حاليًا في هذا التطبيق."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"جدول زمني، جدولة، منبّه، تذكير، ساعة"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"وضع \"عدم الإزعاج\""</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"تفعيل"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"تفعيل ميزة \"عدم الإزعاج\""</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"مطلقًا"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"المدة"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"السؤال في كل مرة"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"إلى أن يتم إيقاف الوضع"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(بلا اسم)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"للتو"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"هذا الهاتف"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"هذا الجهاز اللوحي"</string>
diff --git a/packages/SettingsLib/res/values-as/arrays.xml b/packages/SettingsLib/res/values-as/arrays.xml
index 5a06cb3..b5dfde5 100644
--- a/packages/SettingsLib/res/values-as/arrays.xml
+++ b/packages/SettingsLib/res/values-as/arrays.xml
@@ -71,7 +71,7 @@
   <string-array name="bt_hci_snoop_log_profile_filter_entries">
     <item msgid="3961868665260627524">"অক্ষম কৰক"</item>
     <item msgid="2505973306504851132">"বৰ্ণৰ ষ্ট্ৰীঙেৰে পূৰ কৰক"</item>
-    <item msgid="5883011000629613855">"কেৱল হেডাৰ এৰক"</item>
+    <item msgid="5883011000629613855">"কেৱল হে’ডাৰ এৰক"</item>
     <item msgid="1051534112762023603">"সম্পূৰ্ণকৈ আঁতৰাওক"</item>
   </string-array>
   <string-array name="bluetooth_avrcp_versions">
@@ -276,8 +276,8 @@
   </string-array>
   <string-array name="usb_configuration_titles">
     <item msgid="3358668781763928157">"চাৰ্জ কৰি থকা হৈছে"</item>
-    <item msgid="7804797564616858506">"এমটিপি (মিডিয়া ট্ৰান্সফাৰ প্ৰ’ট’কল)"</item>
-    <item msgid="910925519184248772">"পিটিপি (পিকচাৰ ট্ৰান্সফাৰ প্ৰ’ট’কল)"</item>
+    <item msgid="7804797564616858506">"এমটিপি (মিডিয়া ট্ৰান্সফাৰ প্ৰ্ৰ\'টকল)"</item>
+    <item msgid="910925519184248772">"পিটিপি (পিকচাৰ ট্ৰান্সফাৰ প্ৰ্ৰ\'টকল)"</item>
     <item msgid="3825132913289380004">"RNDIS (USB ইথাৰনেট)"</item>
     <item msgid="8828567335701536560">"ধ্বনিৰ উৎস"</item>
     <item msgid="8688681727755534982">"এমআইডিআই"</item>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index d021647..b4f6c45 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -132,8 +132,8 @@
     <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>
-    <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"এইচ্ছডি অডি\'অ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"এইচ্ছডি অডিঅ’"</string>
+    <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD অডি\'অ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD অডিঅ’"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="2607867572569689732">"শ্ৰৱণ যন্ত্ৰ"</string>
     <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE অডিঅ’"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="5757754050938807276">"শ্ৰৱণ যন্ত্ৰৰ সৈতে সংযোগ কৰা হৈছে"</string>
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ডিবাগ এপসমূহৰ বাবে জিপিইউ ডিবাগ তৰপ ল\'ড কৰিবলৈ অনুমতি দিয়ক"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"বিক্ৰেতাৰ ভাৰ্ব’ছ লগিং সক্ষম কৰক"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"বাগ ৰিপ’ৰ্টসমূহত অতিৰিক্ত ডিভাইচ নিৰ্দিষ্ট বিক্ৰেতাৰ লগসমূহ অন্তৰ্ভুক্ত কৰক, য’ত ব্যক্তিগত তথ্য থাকিব পাৰে, যি অধিক বেটাৰী আৰু/অথবা ষ্ট’ৰেজ ব্যৱহাৰ কৰিব পাৰে।"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"ৱিণ্ড\' এনিমেশ্বন স্কেল"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ট্ৰাঞ্জিশ্বন এনিমেশ্বন স্কেল"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"এনিমেটৰ কালদৈৰ্ঘ্য স্কেল"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"ফ্ৰিফৰ্ম ৱিণ্ড\'জ সক্ষম কৰক"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"পৰীক্ষামূলক ফ্ৰী-ফৰ্ম ৱিণ্ড’বোৰৰ বাবে সহায়তা সক্ষম কৰক৷"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"ফ্ৰীফৰ্ম ৱিণ্ড’ সক্ষম কৰ (লিগেচী)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"পৰীক্ষামূলক লিগেচী ফ্ৰীফৰ্ম ৱিণ্ড’ৰ সমৰ্থন সক্ষম কৰক।"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"ডেস্কটপ বেকআপ পাছৱৰ্ড"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ডেস্কটপৰ পূৰ্ণ বেকআপ এতিয়ালৈকে সংৰক্ষিত অৱস্থাত নাই"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ডেস্কটপ সম্পূৰ্ণ বেকআপৰ বাবে পাছৱৰ্ডটো সলনি কৰিবলৈ বা আঁতৰাবলৈ টিপক"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"এলাৰ্ম আৰু ৰিমাইণ্ডাৰ"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"এই এপ্‌টোক এলাৰ্ম ছেট কৰিবলৈ আৰু সময় সংবেদনশীল কাৰ্যৰ সময়সূচী নিৰ্ধাৰণ কৰিবলৈ দিয়ক। ই এপ্‌টোক নেপথ্যত চলি থকাৰ অনুমতি দিয়ে যাৰ ফলত অধিক বেটাৰী ব্যৱহাৰ হয়।\n\nএই অনুমতিটো অফ কৰা থাকিলে, ইতিমধ্যে ছেট কৰা এলাৰ্ম আৰু এই এপ্‌টোৱে সময়সূচী নিৰ্ধাৰণ কৰা সময় ভিত্তিক অনুষ্ঠানসমূহে কাম নকৰা হ’ব।"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"সময়সূচী, এলাৰ্ম, ৰিমাইণ্ডাৰ, ঘড়ী"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"অসুবিধা নিদিব"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"অন কৰক"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"অসুবিধা নিদিব অন কৰক"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"কেতিয়াও নহয়"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"সময়সীমা"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"প্ৰতিবাৰতে সোধক"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"আপুনি অফ নকৰা পর্যন্ত"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(কোনো নাম নাই)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"এই মাত্ৰ"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"এই ফ’নটো"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"এই টেবলেটটো"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index b7dda83..77bfd57 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Qrafik prosessor qatları sazlanmasının yüklənməsinə icazə verilsin"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Təfsilatlı təchizatçı jurnalı"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Xəta hesabatına təchizatçının cihaz haqqında əlavə qeydləri daxil edilsin. Qeydlərdə şəxsi məlumatlar ola, onlar artıq yer tuta və enerji sərfiyyatını artıra bilər."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Pəncərə animasiyası"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Keçid animasiyası"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animasiya müddəti"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Manifest dəyərindən asılı olmayaraq tətbiqlərin xarici daşıyıcılarda saxlanmasına icazə verilsin"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Çoxpəncərəli rejimdə ölçü dəyişdirilməsi"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Manifest dəyərindən asılı olmayaraq çoxpəncərəli rejimdə pəncərə ölçüsünün dəyişdirilməsinə icazə verilsin"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"İxtiyari formada pəncərə yaradılsın"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Eksperimental olaraq ixtiyari formada pəncərə yaradılsın"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"İxtiyari formada pəncərələri (köhnə) aktivləşdirin"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Təcrübi köhnə ixtiyari formada pəncərələr üçün dəstəyi aktivləşdirin."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Masaüstü rezerv parolu"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Masaüstü tam rezervlər hazırda qorunmayıblar."</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Masaüstünün tam rezerv kopyalanması üçün parolu dəyişmək və ya silmək üçün basın"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Siqnallar və xatırlatmalar"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Bu tətbiqə siqnallar ayarlamağa və vaxta əsaslanan əməliyyatları planlaşdırmağa icazə verin. Bu, tətbiqin arxa fonda işləməsinə imkan verir ki, nəticədə daha çox enerji istifadə edilə bilər.\n\nBu icazə deaktiv olsa, bu tətbiq tərəfindən planlaşdırılan mövcud siqnallar və vaxta əsaslanan tədbirlər işləməyəcəkdir."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"cədvəl, siqnal, xatırlatma, saat"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Narahat etməyin"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktiv edin"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\"Narahat Etməyin\" rejimini aktiv edin"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Heç vaxt"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Müddət"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Həmişə soruşulsun"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Deaktiv edilənə qədər"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Ad yoxdur)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"İndicə"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Bu telefon"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Bu planşet"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 0e42066..99e3150 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Učitava otklanjanje grešaka GPU-a u apl. za otklanjanje grešaka"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Opširne evidencije prodavca"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Uvrštava u izveštaje o greškama dodatne posebne evidencije prodavca za uređaje, koje mogu da sadrže privatne podatke, da troše više baterije i/ili da koriste više memorije."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Razmera animacije prozora"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Razmera animacije prelaza"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatorova razmera trajanja"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Omogućava upisivanje svih aplikacija u spoljnu memoriju, bez obzira na vrednosti manifesta"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Prinudno omogući promenu veličine aktivnosti"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Omogućava promenu veličine svih aktivnosti za režim sa više prozora, bez obzira na vrednosti manifesta."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Omogući prozore proizvoljnog formata"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Omogućava podršku za eksperimentalne prozore proizvoljnog formata."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Omogući prozore proizvoljnog formata (zastarelo)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Omogućava podršku za zastarele eksperimentalne prozore proizvoljnog formata."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Lozinka rezervne kopije za računar"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Rezervne kopije čitavog sistema trenutno nisu zaštićene"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Dodirnite da biste promenili ili uklonili lozinku za pravljenje rezervnih kopija čitavog sistema na računaru"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmi i podsetnici"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Omogućite ovoj aplikaciji da podešava alarme i zakazuje vremenski osetljive radnje. To omogućava da aplikacija bude pokrenuta u pozadini, što može da troši više baterije.\n\nAko je ova dozvola isključena, postojeći alarmi i događaji zasnovani na vremenu zakazani pomoću ove aplikacije neće raditi."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"zakazati, alarm, podsetnik, sat"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ne uznemiravaj"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Uključi"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Uključite režim Ne uznemiravaj"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikad"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trajanje"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Pitaj svaki put"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Dok ne isključite"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Bez imena)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Upravo"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ovaj telefon"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ovaj tablet"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 95586ea..d66250d 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Загружаць слаі адладкі GPU для праграм адладкі"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Уключыць падрабязны журнал пастаўшчыка"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Дадаваць у справаздачы пра памылкі дадатковыя журналы пастаўшчыка для пэўнай прылады (могуць утрымлівацца прыватныя даныя, можа павышацца выкарыстанне акумулятара і/ці памяці)."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Маштаб анімацыі акна"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Маштаб перадачы анімацыі"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Працягласць анімацыі"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Уключыць адвольную форму вокнаў"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Уключыць падтрымку для эксперыментальнай адвольнай формы акна."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Уключыць адвольную форму вокнаў (устарэлая налада)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Уключыць падтрымку для эксперыментальнай адвольнай формы вокнаў (устарэлая налада)."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Пароль для рэз. копіі ПК"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Поўнае рэзервовае капіраванне працоўнага стала зараз не абаронена"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Краніце, каб змяніць або выдаліць пароль для поўнага рэзервовага капіравання працоўнага стала"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Будзільнікі і напаміны"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Дазвольце гэтай праграме ўключаць будзільнікі і задаваць час дзеянняў. З такім дазволам праграма можа працаваць у фонавым рэжыме і ў выніку хутчэй разраджаць акумулятар.\n\nКалі вы не ўключыце гэты дазвол, існуючыя будзільнікі і запланаваны праграмай час падзей не будуць працаваць."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"расклад, будзільнік, напамін, гадзіннік"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Не турбаваць"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Уключыць"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Уключэнне рэжыму \"Не турбаваць\""</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Ніколі"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Працягласць"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Заўсёды пытацца"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Пакуль не выключыце"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Без назвы)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Толькі што"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Гэты тэлефон"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Гэты планшэт"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 54fef5f..706db07 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Разреш. на зарежд. на слоевете за отстр. на грешки в ГП за съотв. прилож."</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Активиране на подробно регистр. на файлове за доставчиците"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Включване на допълнителни регистрационни файлове за доставчиците на конкретни устройства в сигналите за програмни грешки, които може да съдържат поверителна информация, да изразходват батерията в по-голяма степен и/или да използват повече място в хранилището."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Скала на прозореца на аним."</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Скала на преходната анимация"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Скала за Animator"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Активиране на прозорците в свободна форма"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Активиране на поддръжката за експерименталните прозорци в свободна форма."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Актив. на прозорците в свободна форма (наследени)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Активиране на поддръжката за експерименталните наследени прозорци в свободна форма."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Парола за резервни копия"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Понастоящем пълните резервни копия за настолен компютър не са защитени"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Докоснете, за да промените или премахнете паролата за пълни резервни копия на настолния компютър"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Будилници и напомняния"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Разрешаване на това приложение да задава будилници и да насрочва действия, ограничени във времето. Това му позволява да работи на заден план, при което може да се използва повече батерия.\n\nАко разрешението е изключено, съществуващите будилници и събитията въз основа на времето, насрочени от приложението, няма да работят."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"график, будилник, напомняне, часовник"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Не безпокойте"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Включване"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Включване на режима „Не безпокойте“"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Никога"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Времетраене"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Да се пита винаги"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"До изключване"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Няма име)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Току-що"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Този телефон"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Този таблет"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 1533a19..0e83ff2 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ডিবাগ অ্যাপের জন্য GPU ডিবাগ স্তর লোড হতে দিন"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ভারবোস ভেন্ডর লগ-ইন চালু করুন"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"সমস্যা সংক্রান্ত রিপোর্টগুলিতে অতিরিক্ত ডিভাইস-নির্দিষ্ট ভেন্ডরের লগগুলি অন্তর্ভুক্ত করুন, যার মধ্যে ব্যক্তিগত তথ্য থাকতে পারে, আরও বেশি ব্যাটারি ব্যবহার করতে পারে, এবং/অথবা আরও স্টোরেজ ব্যবহার করতে পারে।"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"উইন্ডো অ্যানিমেশন স্কেল"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ট্র্যানজিশন অ্যানিমেশন স্কেল"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"অ্যানিমেটর সময়কাল স্কেল"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"ফ্রি-ফর্ম উইন্ডো চালু করুন"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"পরীক্ষামূলক ফ্রি-ফর্ম উইন্ডোগুলির জন্য সহায়তা সক্ষম করুন৷"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"ফ্রিফর্ম উইন্ডো (লিগ্যাসি) চালু করুন"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"এক্সপেরিমেন্টাল ফ্রিফর্ম উইন্ডোর জন্য সহায়তা চালু করুন।"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"ডেস্কটপ ব্যাকআপ পাসওয়ার্ড"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ডেস্কটপ পূর্ণ ব্যাকআপ বর্তমানে সুরক্ষিত নয়"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ডেস্কটপের সম্পূর্ণ ব্যাকআপের পাসওয়ার্ডটি পরিবর্তন করতে বা মুছে ফেলতে আলতো চাপুন"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"অ্যালার্ম এবং রিমাইন্ডার"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"অ্যালার্ম এবং সময়ের মধ্যে শেষ করতে হবে এমন অ্যাকশনের শিডিউল সেট করতে এই অ্যাপকে অনুমতি দিন। এর ফলে ব্যাকগ্রাউন্ডে অ্যাপ চলতে পারে, যার জন্য আরও ব্যাটারির চার্জ খরচ হতে পারে।\n\nএই অনুমতি বন্ধ করা থাকলে, আগে থেকে থাকা অ্যালার্ম এবং অ্যাপের মাধ্যমে শিডিউল করা সময় ভিত্তিক ইভেন্টের রিমাইন্ডার কাজ করবে না।"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"শিডিউল, অ্যালার্ম, রিমাইন্ডার, ঘড়ি"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"বিরক্ত করবে না"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"চালু করুন"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'বিরক্ত করবে না\' মোড চালু করুন"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"কখনও নয়"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"সময়কাল"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"প্রতিবার জিজ্ঞেস করা হবে"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"যতক্ষণ না আপনি বন্ধ করছেন"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(কোনও নাম নেই)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"এখনই"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"এই ফোন"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"এই ট্যাবলেট"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 15a9618..fd2b121 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Omogućite slojeve za otkl. grešaka na GPU-u za apl. za otkl. grešaka"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Omogući opširni zapisnik"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"U izvještaje o greškama uključite dodatne zapisnike dobavljača specifične za uređaj, koji mogu sadržavati lične informacije, povećati potrošnju baterije i/ili koristiti više prostora za pohranu."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Skala animacije prozora"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala animacije prijelaza"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Skala trajanja animatora"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Omogućava upisivanje svih aplikacija u vanjsku pohranu, bez obzira na prikazane vrijednosti"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Nametni aktivnostima mijenjanje veličina"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Omogućava mijenjanje veličine svih aktivnosti za prikaz s više prozora, bez obzira na prikazane vrijednosti"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Omogući prozore nepravilnih oblika"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Omogućava podršku za eksperimentalne prozore nepravilnih oblika."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Omogući prilagodljive prozore (staro)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Omogućite podršku za eksperimentalne stare prilagodljive prozore."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Lozinka sigurnosne kopije za računar"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Potpune sigurnosne kopije za računare trenutno nisu zaštićene"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Dodirnite da promijenite ili uklonite lozinku za potpune rezervne kopije s radne površine"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmi i podsjetnici"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Dozvolite ovoj aplikaciji da postavlja alarme i zakazuje vremenski osjetljive radnje. Ovim će se omogućiti aplikaciji da radi u pozadini, čime se može povećati potrošnja baterije.\n\nAko je ovo odobrenje isključeno, postojeći alarmi i događaji zasnovani na vremenu, a koje je ova aplikacija zakazala, neće funkcionirati."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"raspored, alarm, podsjetnik, sat"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ne ometaj"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Uključi"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Uključi način rada Ne ometaj"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikada"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trajanje"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Pitaj svaki put"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Dok ne isključite"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Bez imena)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Upravo"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ovaj telefon"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ovaj tablet"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 45f08da..e685afc 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permet carregar capes de depuració de GPU en aplicacions de depuració"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Activa el registre detallat del proveïdor"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Inclou altres registres de proveïdor específics del dispositiu als informes d’errors; és possible que continguin informació privada, consumeixin més bateria o utilitzin més espai d\'emmagatzematge"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Escala d\'animació de la finestra"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala d\'animació de la transició"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de durada de l\'animació"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Permet que qualsevol aplicació es pugui escriure en un dispositiu d’emmagatzematge extern, independentment dels valors del manifest"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Força l\'ajust de la mida de les activitats"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Permet ajustar la mida de totes les activitats per al mode multifinestra, independentment dels valors del manifest"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Activa les finestres amb format lliure"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Activa la compatibilitat amb finestres experimentals amb format lliure"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Activa les finestres amb format lliure (heretat)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Activa la compatibilitat amb les finestres de format lliure heretades i experimentals."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Contrasenya per a còpies d\'ordinador"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Les còpies de seguretat completes d\'ordinador no estan protegides"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Toca per canviar o suprimir la contrasenya per a les còpies de seguretat completes de l\'ordinador"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes i recordatoris"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permet que aquesta aplicació configuri alarmes i programi accions a una hora determinada. Això permet a l\'aplicació executar-se en segon pla i, per tant, és possible que consumeixi més bateria.\n\nSi aquest permís està desactivat, les alarmes i els esdeveniments que ja hagi programat l\'aplicació no funcionaran."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programació, alarma, recordatori, rellotge"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"No molestis"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activa"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activa el mode No molestis"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Mai"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Durada"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Pregunta sempre"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Fins que no el desactivis"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Sense nom)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Ara mateix"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Aquest telèfon"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Aquesta tauleta"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 194c616..c8c4869 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Povolit načítání vrstev ladění GPU pro ladicí aplikace"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Povolit podrobné protokolování dodavatele"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Zahrnovat do zpráv o chybách dodatečné protokoly dodavatelů specifické pro zařízení, které mohou obsahovat soukromé údaje, více vybíjet baterii nebo využívat více místa v úložišti."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Měřítko animace okna"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Měřítko animace přeměny"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Měřítko délky animace"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Každou aplikaci bude možné zapsat do externího úložiště, bez ohledu na hodnoty manifestu"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Vynutit možnost změny velikosti aktivit"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Umožní změnu velikosti všech aktivit na několik oken (bez ohledu na hodnoty manifestu)"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Aktivovat okna s volným tvarem"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktivuje podporu experimentálních oken s volným tvarem"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Aktivovat okna s volným tvarem (starší nastavení)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Aktivuje podporu starších experimentálních oken s volným tvarem."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Heslo pro zálohy v počítači"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Úplné zálohy v počítači nejsou v současné době chráněny"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tuto možnost vyberte, chcete-li změnit nebo odebrat heslo pro úplné zálohy do počítače"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Budíky a připomenutí"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Když tuto možnost povolíte, aplikace bude moci nastavovat budíky a plánovat akce závislé na čase. Aplikace poběží na pozadí, což může vést k vyšší spotřebě baterie.\n\nPokud toto oprávnění zůstane vypnuté, stávající budíky a události závislé na čase naplánované touto aplikací nebudou fungovat."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"plán, budík, připomenutí, hodiny"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Nerušit"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Zapnout"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Zapněte funkci Nerušit"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikdy"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trvání"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Pokaždé se zeptat"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Dokud funkci nevypnete"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Bez jména)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Právě teď"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Tento telefon"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Tento tablet"</string>
diff --git a/packages/SettingsLib/res/values-da/arrays.xml b/packages/SettingsLib/res/values-da/arrays.xml
index 3c5135b..3d2d6c7 100644
--- a/packages/SettingsLib/res/values-da/arrays.xml
+++ b/packages/SettingsLib/res/values-da/arrays.xml
@@ -156,13 +156,13 @@
     <item msgid="1241278021345116816">"Optimeret til lydkvalitet (990 kbps/909 kbps)"</item>
     <item msgid="3523665555859696539">"Afbalancer lyd- og forbindelseskvalitet (660 kbps/606 kbps)"</item>
     <item msgid="886408010459747589">"Optimeret til forbindelseskvalitet (330 kbps/303 kbps)"</item>
-    <item msgid="3808414041654351577">"Bedste resultat (tilpasset bithastighed)"</item>
+    <item msgid="3808414041654351577">"Bedste resultat (adaptiv bithastighed)"</item>
   </string-array>
   <string-array name="bluetooth_a2dp_codec_ldac_playback_quality_summaries">
     <item msgid="804499336721569838">"Optimeret til lydkvalitet"</item>
     <item msgid="7451422070435297462">"Afbalancer lyd- og forbindelseskvalitet"</item>
     <item msgid="6173114545795428901">"Optimeret til forbindelseskvalitet"</item>
-    <item msgid="4349908264188040530">"Bedste resultat (tilpasset bithastighed)"</item>
+    <item msgid="4349908264188040530">"Bedste resultat (adaptiv bithastighed)"</item>
   </string-array>
   <string-array name="bluetooth_audio_active_device_summaries">
     <item msgid="8019740759207729126"></item>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 9e47d6d..a7cbcd4 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Tillad, at fejlretningslag indlæses for grafikprocessor i apps til fejlretning"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Aktivér detaljeret leverandørlogging"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Medtag yderligere enhedsspecifikke leverandørlogfiler i fejlrapporter, som muligvis indeholder personlige oplysninger. Dette bruger muligvis mere batteri og/eller lagerplads."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Animationsskala for vindue"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Overgangsanimationsskala"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatorvarighedsskala"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Gør det muligt at overføre enhver app til et eksternt lager uafhængigt af manifestværdier"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Gennemtving, at aktiviteter kan tilpasses"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Tillad, at alle aktiviteter kan tilpasses flere vinduer uafhængigt af manifestværdier"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Aktivér vinduer i frit format"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktivér understøttelse af eksperimentelle vinduer i frit format"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Aktivér vinduer i frit format (forældet)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Aktivér understøttelse af eksperimentelle forældede vinduer i frit format."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Kode til lokal sikkerhedskopi"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Lokale komplette backups er i øjeblikket ikke beskyttet"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tryk for at skifte eller fjerne adgangskoden til fuld lokal sikkerhedskopiering"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmer og påmindelser"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Tillad, at denne app indstiller alarmer og planlægger tidsbestemte handlinger. Appen vil køre i baggrunden, hvor den muligvis bruger mere batteri.\n\nHvis denne tilladelse er deaktiveret, vil eksisterende alarmer og tidsbestemte handlinger, der er planlagt af denne app, ikke fungere."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"planlæg, alarm, påmindelse, ur"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Forstyr ikke"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktivér"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktivér Forstyr ikke"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Aldrig"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Varighed"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Spørg hver gang"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Indtil du deaktiverer"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Intet navn)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Lige nu"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Denne telefon"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Denne tablet"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index caeee06..946159d 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Debug-Apps das Laden von GPU-Debug-Ebenen erlauben"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Ausführliche Protokollierung aktivieren"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Schließt zusätzliche gerätespezifische Anbieterprotokolle in Fehlerberichten ein, die private Informationen enthalten, den Akkuverbrauch erhöhen und/oder zusätzlichen Speicher benötigen können."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Fensteranimationsfaktor"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Übergangsanimationsfaktor"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animationsdauerfaktor"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Jede App kann, ungeachtet der Manifestwerte, in den externen Speicher geschrieben werden"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Aktivitätengröße darf immer angepasst werden"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Die Größe aller Aktivitäten darf, ungeachtet der Manifestwerte, für die Mehrfensterdarstellung angepasst werden"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Freiform-Fenster zulassen"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Unterstützung für experimentelle Freiform-Fenster aktivieren"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Freiform-Fenster zulassen (Legacy)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Unterstützung für experimentelle Legacy-Freiform-Fenster aktivieren."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Passwort für Desktop-Sicherung"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Vollständige Desktop-Sicherungen sind momentan nicht passwortgeschützt"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Zum Ändern oder Entfernen des Passworts für vollständige Desktop-Sicherungen tippen"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Wecker und Erinnerungen"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Dieser App erlauben, Wecker zu stellen und zeitgebundene Aktionen zu planen. Dadurch läuft die App im Hintergrund. Dies kann den Akkuverbrauch erhöhen. \n\nWenn diese Berechtigung deaktiviert ist, funktionieren bereits gestellte Wecker und zeitgebundene Ereignisse, die von dieser App geplant sind, nicht wie erwartet."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"planen, Wecker, Erinnerung, Uhr"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Bitte nicht stören"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktivieren"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"„Bitte nicht stören“ aktivieren"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nie"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Dauer"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Jedes Mal fragen"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Bis zur Deaktivierung"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Kein Name)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Gerade eben"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Dieses Smartphone"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Dieses Tablet"</string>
@@ -708,7 +722,7 @@
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Physische Tastatur"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Tastaturlayout wählen"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Standard"</string>
-    <string name="turn_screen_on_title" msgid="2662312432042116026">"Steuerelement zum Aktivieren des Displays"</string>
+    <string name="turn_screen_on_title" msgid="2662312432042116026">"Berechtigung zum Aktivieren des Displays"</string>
     <string name="allow_turn_screen_on" msgid="6194845766392742639">"Aktivieren des Displays erlauben"</string>
     <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Einer App erlauben, das Display zu aktivieren. Wenn du diese Erlaubnis erteilst, kann die App jederzeit das Display aktivieren – auch ohne dass du dies beabsichtigst."</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"<xliff:g id="APP_NAME">%1$s</xliff:g> nicht mehr streamen?"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 94d4297..5b156bf 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Φόρτωση επιπ. εντοπ. σφ. GPU για εφαρμ. αντιμ. σφ."</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Ενεργ. λεπτ. καταγραφής προμ."</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Συμπερίληψη πρόσθετων αρχείων καταγραφής προμηθευτή για συγκεκριμένες συσκευές στις αναφορές σφαλμάτων, τα οποία ενδέχεται να περιέχουν ιδιωτικές πληροφορίες, να χρησιμοποιούν περισσότερη μπαταρία ή/και να χρησιμοποιούν περισσότερο αποθηκευτικό χώρο."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Κλίμακα κίνησης παραθύρου"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Κλίμακα κίνησης μετάβασης"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Κλίμ. διάρ. Animator"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Ενεργοποίηση παραθύρων ελεύθερης μορφής"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Ενεργοποίηση υποστήριξης για πειραματικά παράθυρα ελεύθερης μορφής."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Ενεργ. παραθύρων ελεύθερης μορφής (παλαιού τύπου)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Ενεργοποίηση υποστήριξης για πειραματικά παράθυρα ελεύθερης μορφής παλαιού τύπου."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Εφ/κός κωδικός desktop"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Τα πλήρη αντίγραφα ασφαλείας επιφάνειας εργασίας δεν προστατεύονται αυτή τη στιγμή"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Πατήστε για αλλαγή ή κατάργηση του κωδικού πρόσβασης για τα πλήρη αντίγραφα ασφαλείας επιφάνειας εργασίας"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Ξυπνητήρια και υπενθυμίσεις"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Επιτρέψτε σε αυτή την εφαρμογή να ορίζει ξυπνητήρια και να προγραμματίζει ενέργειες που εξαρτώνται από τον χρόνο. Αυτό επιτρέπει στην εφαρμογή να εκτελείται στο παρασκήνιο και, ως εκ τούτου, μπορεί να καταναλώνει περισσότερη μπαταρία.\n\nΑν αυτή η άδεια δεν είναι ενεργή, τα υπάρχοντα ξυπνητήρια και συμβάντα βάσει χρόνου που έχουν προγραμματιστεί από αυτή την εφαρμογή δεν θα λειτουργούν."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"πρόγραμμα, ξυπνητήρι, υπενθύμιση, ρολόι"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Μην ενοχλείτε"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ενεργοποίηση"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Ενεργοποίηση λειτουργίας \"Μην ενοχλείτε\""</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Ποτέ"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Διάρκεια"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Να ερωτώμαι κάθε φορά"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Μέχρι την απενεργοποίηση"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Χωρίς όνομα)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Μόλις τώρα"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Αυτό το τηλέφωνο"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Αυτό το tablet"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index c4d33e0..b0b3de1 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Allow loading GPU debug layers for debug apps"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Enable verbose vendor logging"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Include additional device-specific vendor logs in bug reports, which may contain private information, use more battery and/or use more storage."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Window animation scale"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Transition animation scale"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator duration scale"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Makes any app eligible to be written to external storage, regardless of manifest values"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Force activities to be resizeable"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Make all activities resizeable for multi-window, regardless of manifest values."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Enable freeform windows"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Enable support for experimental freeform windows."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Enable freeform windows (legacy)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Enable support for experimental legacy freeform windows."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Desktop backup password"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Desktop full backups aren\'t currently protected"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tap to change or remove the password for desktop full backups"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms and reminders"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Do Not Disturb"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Turn on Do Not Disturb"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Never"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duration"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Ask every time"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Until you turn off"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(No name)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Just now"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"This phone"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"This tablet"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 42f9b5f..a77d6c6 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -408,6 +408,12 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Allow loading GPU debug layers for debug apps"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Enable verbose vendor logging"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Include additional device-specific vendor logs in bug reports, which may contain private information, use more battery, and/or use more storage."</string>
+    <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"Disable after one day"</string>
+    <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"Verbose vendor logging has ended"</string>
+    <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"Enabled for one day"</string>
+    <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"Enable for one more day"</string>
+    <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"Disables after one day"</string>
+    <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"Enabled indefinitely"</string>
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Window animation scale"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Transition animation scale"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator duration scale"</string>
@@ -424,8 +430,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Makes any app eligible to be written to external storage, regardless of manifest values"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Force activities to be resizable"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Make all activities resizable for multi-window, regardless of manifest values."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Enable freeform windows"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Enable support for experimental freeform windows."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Enable freeform windows (legacy)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Enable support for experimental legacy freeform windows."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Desktop backup password"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Desktop full backups aren’t currently protected"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tap to change or remove the password for desktop full backups"</string>
@@ -557,6 +563,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms &amp; reminders"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Do Not Disturb"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Turn on Do Not Disturb"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Never"</string>
@@ -569,6 +576,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duration"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Ask every time"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Until you turn off"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(No name)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Just now"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"This phone"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"This tablet"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index c4d33e0..b0b3de1 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Allow loading GPU debug layers for debug apps"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Enable verbose vendor logging"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Include additional device-specific vendor logs in bug reports, which may contain private information, use more battery and/or use more storage."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Window animation scale"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Transition animation scale"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator duration scale"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Makes any app eligible to be written to external storage, regardless of manifest values"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Force activities to be resizeable"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Make all activities resizeable for multi-window, regardless of manifest values."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Enable freeform windows"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Enable support for experimental freeform windows."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Enable freeform windows (legacy)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Enable support for experimental legacy freeform windows."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Desktop backup password"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Desktop full backups aren\'t currently protected"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tap to change or remove the password for desktop full backups"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms and reminders"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Do Not Disturb"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Turn on Do Not Disturb"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Never"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duration"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Ask every time"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Until you turn off"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(No name)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Just now"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"This phone"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"This tablet"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index c4d33e0..b0b3de1 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Allow loading GPU debug layers for debug apps"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Enable verbose vendor logging"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Include additional device-specific vendor logs in bug reports, which may contain private information, use more battery and/or use more storage."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Window animation scale"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Transition animation scale"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator duration scale"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Makes any app eligible to be written to external storage, regardless of manifest values"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Force activities to be resizeable"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Make all activities resizeable for multi-window, regardless of manifest values."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Enable freeform windows"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Enable support for experimental freeform windows."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Enable freeform windows (legacy)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Enable support for experimental legacy freeform windows."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Desktop backup password"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Desktop full backups aren\'t currently protected"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tap to change or remove the password for desktop full backups"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarms and reminders"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Do Not Disturb"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Turn on Do Not Disturb"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Never"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duration"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Ask every time"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Until you turn off"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(No name)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Just now"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"This phone"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"This tablet"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index fd84077..8d6520f 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -408,6 +408,12 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‎‎‏‏‎‏‎‎‏‎‏‎‎‎‎‏‎‎‏‎‎‏‏‎‎‏‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‎‏‎Allow loading GPU debug layers for debug apps‎‏‎‎‏‎"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‏‎‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‎‏‎‏‏‏‏‎‏‎‎‏‎‎‎‏‏‎‎‎‎Enable verbose vendor logging‎‏‎‎‏‎"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‏‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‏‏‏‎‏‎‏‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‎‎‎Include additional device-specific vendor logs in bug reports, which may contain private information, use more battery, and/or use more storage.‎‏‎‎‏‎"</string>
+    <string name="enable_verbose_vendor_logging_checkbox" msgid="3864578373293835530">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‎‎‎‎‏‏‎‏‏‏‏‎‏‏‎‎‎‏‏‏‎‎‎‎‏‏‎‏‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎Disable after one day‎‏‎‎‏‎"</string>
+    <string name="verbose_vendor_logging_notification_title" msgid="6811217272559843592">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‎‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‎‏‎‎‎‎Verbose vendor logging has ended‎‏‎‎‏‎"</string>
+    <string name="verbose_vendor_logging_notification_summary" msgid="5226524769774370942">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‎‏‎‎‎‎‏‎‏‏‎‎‎‏‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎‎‎‏‎‏‏‏‎‏‎‎‎‎‎‎‎‎‏‏‏‏‏‏‎‎Enabled for one day‎‏‎‎‏‎"</string>
+    <string name="verbose_vendor_logging_notification_action" msgid="1190831050259046071">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‏‎‏‎‏‎‏‏‏‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‏‏‎Enable for one more day‎‏‎‎‏‎"</string>
+    <string name="verbose_vendor_logging_preference_summary_will_disable" msgid="6175431593394522553">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‏‎‎‎‏‎‏‎‎‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‎‎‎‎‎‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‎‎‏‎Disables after one day‎‏‎‎‏‎"</string>
+    <string name="verbose_vendor_logging_preference_summary_on" msgid="9017757242481762036">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‎‎‏‏‎‏‎‏‎‎‏‏‎‏‏‏‏‎‏‏‏‏‎‏‎‎‎Enabled indefinitely‎‏‎‎‏‎"</string>
     <string name="window_animation_scale_title" msgid="5236381298376812508">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‏‎‏‏‎‏‎‏‏‏‎‏‎‎‎‎‏‏‎‎‎‎‎‏‏‏‏‎‎‎‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‏‏‎‎‎Window animation scale‎‏‎‎‏‎"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‏‏‎‎‎‎‏‎‎‎‎‏‎‏‎‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‎‏‎‎‏‏‏‎‏‎‎‏‏‏‏‏‎‏‎‎‏‎Transition animation scale‎‏‎‎‏‎"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‎‏‏‏‎‎‏‎‎‎‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‏‏‏‎‎‎‎Animator duration scale‎‏‎‎‏‎"</string>
@@ -424,8 +430,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‎‎‎‏‏‎‎‏‎‏‏‎‎‏‎‏‎‎‎‏‎‏‏‏‏‎‏‎‏‏‎‎‏‏‎‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‎Makes any app eligible to be written to external storage, regardless of manifest values‎‏‎‎‏‎"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‎‎‏‏‎‎‏‏‎‏‎‏‎‏‏‎‎‏‎‏‏‎‎‏‏‎‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‏‎‎‎‏‏‎‏‏‎‎Force activities to be resizable‎‏‎‎‏‎"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‏‎‎‏‎‏‎‎‎‏‎‏‎‏‏‎‎‏‎‎‏‏‎‏‎‏‎‎‏‏‎‏‎‏‏‎‎Make all activities resizable for multi-window, regardless of manifest values.‎‏‎‎‏‎"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‎‎‏‏‎‏‎‎‎‎‏‏‎‏‎‎‏‎‏‏‎‏‎‏‏‎‎‏‏‎‎‎‎‎‏‏‎‏‎Enable freeform windows‎‏‎‎‏‎"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‎‏‎‎‏‎‏‎‏‏‎Enable support for experimental freeform windows.‎‏‎‎‏‎"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‏‎‎‎‎‏‎‏‎‎‏‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‎‏‎‎‎‎‎‏‎‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎‎Enable freeform windows (legacy)‎‏‎‎‏‎"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‎‎Enable support for experimental legacy freeform windows.‎‏‎‎‏‎"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‎‏‎‎‏‎‏‎‏‏‏‎‎‏‎‎‏‎‎‏‏‏‎‏‎‎‏‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎Desktop backup password‎‏‎‎‏‎"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‎‏‏‏‎‏‏‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‎‎Desktop full backups aren’t currently protected‎‏‎‎‏‎"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‎‎‏‎‏‎‏‎‏‏‏‏‏‎‎‎‏‏‎‏‏‎‎‏‎‏‎‏‎‏‎‏‏‏‏‎Tap to change or remove the password for desktop full backups‎‏‎‎‏‎"</string>
@@ -557,6 +563,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‏‎‎‎‎‎Alarms &amp; reminders‎‏‎‎‏‎"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‎‏‎‎‏‎‏‏‏‎‏‎‎‎‏‏‏‏‎Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎If this permission is off, existing alarms and time-based events scheduled by this app won’t work.‎‏‎‎‏‎"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‏‎‏‏‎‏‏‎‏‏‎‏‎‏‏‏‎‎‏‏‏‎‏‎‏‏‎‏‎‎‏‏‎schedule, alarm, reminder, clock‎‏‎‎‏‎"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‏‎‏‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‏‎‎‎‏‎‎‎‏‎‏‎‏‏‎Do Not Disturb‎‏‎‎‏‎"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‏‎‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎Turn on‎‏‎‎‏‎"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‏‏‎‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎‎‏‎‎‎‏‎‏‎‎‎‎Turn on Do Not Disturb‎‏‎‎‏‎"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‏‏‏‎‎‏‎‏‎‎‎‏‎‎‏‎‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎Never‎‏‎‎‏‎"</string>
@@ -569,6 +576,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‏‏‏‎‏‏‏‏‏‎‎‎‎‎‎‎‏‎‏‏‏‎‎‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‎‏‏‏‏‎‎‏‎‎‎‎‏‎Duration‎‏‎‎‏‎"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‏‎‏‏‎‏‏‎‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‎Ask every time‎‏‎‎‏‎"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‏‎‏‎‎‏‏‏‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‏‎‏‏‎Until you turn off‎‏‎‎‏‎"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‏‏‎‎‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‎‏‏‏‎‎‏‏‏‎‎‎‏‎(No name)‎‏‎‎‏‎"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‎‎‎‏‏‏‎‎‏‎‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎Just now‎‏‎‎‏‎"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‏‎‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‏‎‏‎‎‎‏‎This phone‎‏‎‎‏‎"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‏‎‏‎‎‏‎‏‏‎‏‏‎‏‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‎This tablet‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index b96dd33..5f9edd6 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permite cargar capas de depuración de GPU para apps de depuración"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Habilitar registro detallado"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Incluye otros registros de proveedor específicos del dispositivo en los informes de errores, que podrían contener información privada, consumir más batería o usar más espacio de almacenamiento."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animación de ventana"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala de animación de transición"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de duración de animador"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Cualquier app puede escribirse en un almacenamiento externo, sin importar los valores del manifiesto"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Forzar actividades para que cambien de tamaño"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Permitir que todas las actividades puedan cambiar de tamaño para el modo multiventana, sin importar los valores del manifiesto."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Habilitar ventanas de forma libre"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Permite la compatibilidad con ventanas de forma libre experimentales."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Habilitar ventanas de formato libre (heredado)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Permitir la compatibilidad con ventanas de formato libre experimentales (heredado)"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Contraseñas"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Tus copias de seguridad de escritorio no están protegidas por contraseña"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Presiona para cambiar o quitar la contraseña de las copias de seguridad completas de tu escritorio."</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmas y recordatorios"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permite que esta app establezca alarmas y programe acciones para horarios específicos. De esta manera, la app puede ejecutarse en segundo plano, lo que podría aumentar el consumo de batería.\n\nSi se desactiva este permiso, no funcionarán las alarmas ni los eventos basados en el tiempo existentes que programe esta app."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programar, alarma, recordatorio, reloj"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"No interrumpir"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activar"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activar No interrumpir"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nunca"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duración"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Preguntar siempre"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Hasta que lo desactives"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Sin nombre)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Recién"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Este teléfono"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Esta tablet"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 0b96faa..fdba8c4 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permite cargar capas de depuración de GPU en aplicaciones de depuración"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Habilitar registro de proveedor detallado"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Incluye otros registros de proveedor específicos del dispositivo en informes de errores, lo que puede añadir información privada, usar más batería u ocupar más espacio de almacenamiento."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animación de ventana"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala de animación de transición"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de duración de animación"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Permite que cualquier aplicación se pueda escribir en un almacenamiento externo independientemente de los valores de manifiesto"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Forzar que las actividades puedan cambiar de tamaño"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Permite que todas las actividades puedan cambiar de tamaño en multiventana independientemente de los valores de manifiesto"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Habilitar ventanas de forma libre"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Permite la compatibilidad con ventanas de forma libre experimentales"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Habilitar ventanas de forma libre (antiguo)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Habilita la compatibilidad con ventanas de forma libre antiguas y experimentales."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Contraseña para copias de ordenador"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Las copias de seguridad completas de ordenador no están protegidas"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Toca para cambiar o quitar la contraseña de las copias de seguridad completas del escritorio"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmas y recordatorios"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permite que esta aplicación programe alarmas y otras acciones que se llevan a cabo a una hora determinada. Esto hace que la aplicación pueda seguir activa en segundo plano, lo que puede usar más batería.\n\nSi este permiso está desactivado, no funcionarán las alarmas ni los eventos que se activan a una hora determinada que programe esta aplicación."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programar, alarma, recordatorio, reloj"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"No molestar"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activar"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activar el modo No molestar"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nunca"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duración"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Preguntar siempre"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Hasta que lo desactives"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Sin nombre)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"justo ahora"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Este teléfono"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Esta tablet"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 42c20399..feca80f 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"GPU silumise kihtide laadimise lubamine silumisrakendustele"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Luba paljusõnaline logimine"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Veaaruannetesse kaasatakse täiendavad seadmepõhised teenusepakkuja logid, mis võivad sisaldada privaatset teavet, kasutada rohkem akut ja/või salvestusruumi."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Akna animatsioonimastaap"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Ülemineku animatsioonimastaap"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animaatori kestuse mastaap"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Lubab mis tahes rakendusi kirjutada välisesse salvestusruumi manifesti väärtustest olenemata"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Muuda tegevuste suurused muudetavaks"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Muudetakse kõigi tegevuste suurused mitme aknaga vaates muudetavaks (manifesti väärtustest olenemata)."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Luba vabas vormis aknad"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Lubatakse katseliste vabavormis akende tugi."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Luba vabas vormis aknad (pärand)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Lubatakse katseliste pärand vabas vormis akende tugi."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Arvutivarunduse parool"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Täielikud arvutivarundused pole praegu kaitstud"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Puudutage täielike arvutivarunduste parooli muutmiseks või eemaldamiseks"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmid ja meeldetuletused"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Lubage sellel rakendusel määrata alarme ja ajastada ajakriitilisi toiminguid. See võimaldab rakendusel töötada taustal, mistõttu võib akukasutus olla suurem.\n\nKui see luba on välja lülitatud, siis olemasolevad alarmid ja selle rakenduse ajastatud ajapõhised sündmused ei tööta."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ajakava, äratus, meeldetuletus, kell"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Mitte segada"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Lülita sisse"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Valiku Mitte segada sisselülitamine"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Mitte kunagi"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Kestus"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Küsi iga kord"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Kuni välja lülitate"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Nimi puudub)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Äsja"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"See telefon"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"See tahvelarvuti"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 6376ad5..ae783f2 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -288,7 +288,7 @@
     <string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"OEM desblokeoa onartu nahi duzu?"</string>
     <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"ABISUA: ezarpen hau aktibatuta dagoen bitartean, gailua babesteko eginbideek ez dute gailu honetan funtzionatuko."</string>
     <string name="mock_location_app" msgid="6269380172542248304">"Hautatu asmatutako kokapenen aplikazioa"</string>
-    <string name="mock_location_app_not_set" msgid="6972032787262831155">"Ez da ezarri kokapen faltsuen aplikaziorik"</string>
+    <string name="mock_location_app_not_set" msgid="6972032787262831155">"Ez da ezarri asmatutako kokapenen aplikaziorik"</string>
     <string name="mock_location_app_set" msgid="4706722469342913843">"Asmatutako kokapenen aplikazioa: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="debug_networking_category" msgid="6829757985772659599">"Sareak"</string>
     <string name="wifi_display_certification" msgid="1805579519992520381">"Hari gabe bistaratzeko ziurtagiria"</string>
@@ -337,8 +337,8 @@
     <string name="select_logpersist_dialog_title" msgid="7745193591195485594">"Hautatu gailuan gordeta utzi nahi dituzun erregistroen bufferrak"</string>
     <string name="select_usb_configuration_title" msgid="6339801314922294586">"Hautatu USB konfigurazioa"</string>
     <string name="select_usb_configuration_dialog_title" msgid="3579567144722589237">"Hautatu USB konfigurazioa"</string>
-    <string name="allow_mock_location" msgid="2102650981552527884">"Onartu kokapen faltsuak"</string>
-    <string name="allow_mock_location_summary" msgid="179780881081354579">"Onartu kokapen faltsuak"</string>
+    <string name="allow_mock_location" msgid="2102650981552527884">"Baimendu asmatutako kokapenak"</string>
+    <string name="allow_mock_location_summary" msgid="179780881081354579">"Baimendu asmatutako kokapenak"</string>
     <string name="debug_view_attributes" msgid="3539609843984208216">"Gaitu ikuspegiaren atributuak ikuskatzeko aukera"</string>
     <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Mantendu datu-konexioa beti aktibo, baita wifi-konexioa aktibo dagoenean ere (sare batetik bestera bizkor aldatu ahal izateko)."</string>
     <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Erabilgarri badago, erabili konexioa partekatzeko hardwarearen bizkortzea"</string>
@@ -408,6 +408,18 @@
     <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 eta/edo biltegiratzeko toki gehiago hartzea."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <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>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Aplikazioek kanpoko memorian idatz dezakete, ezarritako balioak kontuan izan gabe"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Behartu jardueren tamaina doitu ahal izatera"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Eman aukera jarduera guztien tamaina doitzeko, leiho batean baino gehiagotan erabili ahal izan daitezen, ezarritako balioak kontuan izan gabe"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Gaitu estilo libreko leihoak"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Onartu estilo libreko leiho esperimentalak"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Gaitu estilo libreko leihoak (aurreko bertsiokoak)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Onartu aurreko bertsioko estilo libreko leiho esperimentalak."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Babeskopien pasahitz lokala"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Une honetan, ordenagailuko babeskopia osoak ez daude babestuta"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Ordenagailuko eduki guztiaren babeskopia egiteko erabiltzen den pasahitza aldatzeko edo kentzeko, sakatu hau"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmak eta abisuak"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Eman alarmak ezartzeko eta denbora-muga duten ekintzak programatzeko baimena aplikazioari. Hala, aplikazioak atzeko planoan funtzionatuko du, eta litekeena da bateria gehiago kontsumitzea.\n\nBaimen hori ematen ez baduzu, ez dute funtzionatuko aplikazio honen bidez programatutako alarmek eta denbora-muga duten ekintzek."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programazioa, alarma, abisua, erlojua"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ez molestatzeko modua"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktibatu"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktibatu ez molestatzeko modua"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Inoiz ez"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Iraupena"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Galdetu beti"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Zuk desaktibatu arte"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Izengabea)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Oraintxe"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Telefono hau"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Tableta hau"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 6eb8bd1..7a296f2 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -64,7 +64,7 @@
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"‏اتصال خودکار ازطریق %1$s"</string>
     <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"اتصال خودکار ازطریق ارائه‌دهنده رده‌بندی شبکه"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"متصل شده ازطریق <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="tap_to_sign_up" msgid="5356397741063740395">"برای ثبت‌نام ضربه بزنید"</string>
+    <string name="tap_to_sign_up" msgid="5356397741063740395">"برای ثبت‌نام تک‌ضرب بزنید"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"عدم اتصال به اینترنت"</string>
     <string name="private_dns_broken" msgid="1984159464346556931">"‏سرور DNS خصوصی قابل دسترسی نیست"</string>
     <string name="wifi_limited_connection" msgid="1184778285475204682">"اتصال محدود"</string>
@@ -74,7 +74,7 @@
     <string name="osu_opening_provider" msgid="4318105381295178285">"درحال بازکردن <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string>
     <string name="osu_connect_failed" msgid="9107873364807159193">"متصل نشد"</string>
     <string name="osu_completing_sign_up" msgid="8412636665040390901">"درحال تکمیل ثبت‌نام…"</string>
-    <string name="osu_sign_up_failed" msgid="5605453599586001793">"ثبت‌نام تکمیل نشد. برای امتحان مجدد ضربه بزنید."</string>
+    <string name="osu_sign_up_failed" msgid="5605453599586001793">"ثبت‌نام تکمیل نشد. برای امتحان مجدد تک‌ضرب بزنید."</string>
     <string name="osu_sign_up_complete" msgid="7640183358878916847">"ثبت‌نام کامل شد. درحال اتصال…"</string>
     <string name="speed_label_slow" msgid="6069917670665664161">"آهسته"</string>
     <string name="speed_label_okay" msgid="1253594383880810424">"تأیید"</string>
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"‏مجاز کردن بارگیری لایه‌های اشکال‌زدایی GPU برای برنامه‌های اشکا‌ل‌زدایی"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"فعال کردن گزارش‌گیری مفصل فروشنده"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"شامل گزارشات اشکال تکمیلی ورود به سیستم فروشنده ویژه دستگاه می‌شود که ممکن است دربرگیرنده اطلاعات خصوصی، استفاده بیشتر از باتری، و/یا استفاده بیشتر از فضای ذخیره‌سازی باشد."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"مقیاس پویانمایی پنجره"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"مقیاس پویانمایی انتقالی"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"مقیاس طول مدت انیماتور"</string>
@@ -424,11 +436,11 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"فعال کردن پنجره‌های آزاد"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"فعال کردن پشتیبانی برای پنجره‌های آزاد آزمایشی."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"فعال کردن پنجره‌های با قالب آزاد (قدیمی)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"فعال کردن پشتیبانی از پنجره‌های با قالب آزاد قدیمی آزمایشی."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"گذرواژه پشتیبان‌گیری محلی"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"پشتیبان‌گیری کامل رایانه درحال حاضر محافظت نمی‌شود"</string>
-    <string name="local_backup_password_summary_change" msgid="1707357670383995567">"برای تغییر یا حذف گذرواژه برای نسخه‌های پشتیبان کامل رایانه‌ای ضربه بزنید"</string>
+    <string name="local_backup_password_summary_change" msgid="1707357670383995567">"برای تغییر یا حذف گذرواژه برای نسخه‌های پشتیبان کامل رایانه‌ای تک‌ضرب بزنید"</string>
     <string name="local_backup_password_toast_success" msgid="4891666204428091604">"گذرواژه جدید نسخهٔ پشتیبان تنظیم شد"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="2994718182129097733">"گذرواژه جدید و تأیید آن با یکدیگر مطابقت ندارند"</string>
     <string name="local_backup_password_toast_validation_failure" msgid="714669442363647122">"گذرواژه پشتیبان‌گیری تنظیم نشد"</string>
@@ -444,8 +456,8 @@
     <item msgid="1282170165150762976">"رنگ‌های بهینه‌شده برای محتوای دیجیتالی"</item>
   </string-array>
     <string name="inactive_apps_title" msgid="5372523625297212320">"برنامه‌های آماده به‌کار"</string>
-    <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"غیرفعال. برای تغییر حالت ضربه بزنید."</string>
-    <string name="inactive_app_active_summary" msgid="8047630990208722344">"فعال. برای تغییر حالت ضربه بزنید."</string>
+    <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"غیرفعال. برای تغییر حالت تک‌ضرب بزنید."</string>
+    <string name="inactive_app_active_summary" msgid="8047630990208722344">"فعال. برای تغییر حالت تک‌ضرب بزنید."</string>
     <string name="standby_bucket_summary" msgid="5128193447550429600">"وضعیت حالت آماده به‌کار برنامه:<xliff:g id="BUCKET"> %s</xliff:g>"</string>
     <string name="transcode_settings_title" msgid="2581975870429850549">"تنظیمات تراتبدیل رسانه"</string>
     <string name="transcode_user_control" msgid="6176368544817731314">"ملغی کردن پیش‌فرض‌های تراتبدیل"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"زنگ‌های ساعت و یادآوری‌ها"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"به این برنامه اجازه می‌دهد زنگ ساعت تنظیم کند و کنش‌های حساس به زمان را زمان‌بندی کند. این تنظیم به برنامه اجازه می‌دهد در پس‌زمینه اجرا شود که ممکن است باتری بیشتری مصرف کند.\n\nاگر این اجازه خاموش باشد، زنگ‌های ساعت موجود و رویدادهای زمان‌محور که این برنامه زمان‌بندی کرده است کار نخواهند کرد."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"زمان‌بندی، زنگ ساعت، یادآوری، ساعت"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"مزاحم نشوید"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"روشن کردن"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"روشن کردن «مزاحم نشوید»"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"هرگز"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"مدت"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"هربار پرسیده شود"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"تا زمانی‌که آن را خاموش کنید"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(بدون نام)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"هم‌اکنون"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"این تلفن"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"این رایانه لوحی"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index a0dc830..978b128 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Salli GPU:n virheenkorjauskerrosten lataus"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Käytä laajennettua kirjausta"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Sisällytä virheraportteihin muita laitekohtaisia myyjälokeja, jotka voivat sisältää yksityisiä tietoja, käyttää enemmän akkua ja/tai käyttää enemmän tallennustilaa"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Ikkuna"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Siirtymä"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animaattori"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Mahdollistaa sovelluksen tietojen tallentamisen ulkoiseen tallennustilaan luetteloarvoista riippumatta"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Pakota kaikki toiminnot hyväksymään koon muutos"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Pakota kaikki toiminnot hyväksymään koon muuttaminen usean ikkunan tilassa luettelon arvoista riippumatta"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Ota käyttöön vapaamuotoiset ikkunat"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Ota kokeellisten vapaamuotoisten ikkunoiden tuki käyttöön"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Ota vapaamuotoiset ikkunat käyttöön (vanha)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Ota kokeellinen vapaamuotoisten ikkunoiden tuki käyttöön (vanha)."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Varmuuskop. salasana"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Tietokoneen kaikkien tietojen varmuuskopiointia ei ole tällä hetkellä suojattu"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Vaihda tai poista tietokoneen kaikkien tietojen varmuuskopioinnin salasana koskettamalla."</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Herätykset ja muistutukset"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Anna sovelluksen lisätä herätyksiä ja ajoittaa kiireellisiä tapahtumia. Näin sovellus voi toimia taustalla, mikä voi kuluttaa enemmän virtaa.\n\nIlman tätä lupaa sovelluksen ajoittamat herätykset ja aikaan perustuvat tapahtumat eivät toimi."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ajoitus, herätys, muistutus, kello"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Älä häiritse"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ota käyttöön"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Laita Älä häiritse ‑tila päälle"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Ei koskaan"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Kesto"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Kysy aina"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Kunnes laitat pois päältä"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Ei nimeä)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Äsken"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Tämä puhelin"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Tämä tabletti"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 0e03d18..b620649 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -182,8 +182,8 @@
     <string name="accessibility_wifi_security_type_none" msgid="162352241518066966">"Réseau ouvert"</string>
     <string name="accessibility_wifi_security_type_secured" msgid="2399774097343238942">"Réseau sécurisé"</string>
     <string name="process_kernel_label" msgid="950292573930336765">"Système d\'exploitation Android"</string>
-    <string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"Applications supprimées"</string>
-    <string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"Applications et utilisateurs supprimés"</string>
+    <string name="data_usage_uninstalled_apps" msgid="1933665711856171491">"Applis supprimées"</string>
+    <string name="data_usage_uninstalled_apps_users" msgid="5533981546921913295">"Applis et utilisateurs supprimés"</string>
     <string name="data_usage_ota" msgid="7984667793701597001">"Mises à jour du système"</string>
     <string name="tether_settings_title_usb" msgid="3728686573430917722">"Partage de connexion par USB"</string>
     <string name="tether_settings_title_wifi" msgid="4803402057533895526">"Point d\'accès Wi-Fi mobile"</string>
@@ -241,7 +241,7 @@
     <string name="category_clone" msgid="1554511758987195974">"Cloner"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Options pour les développeurs"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Activer les options pour les développeurs"</string>
-    <string name="development_settings_summary" msgid="8718917813868735095">"Définir les options pour le développement de l\'application"</string>
+    <string name="development_settings_summary" msgid="8718917813868735095">"Définir les options pour le développement de l\'appli"</string>
     <string name="development_settings_not_available" msgid="355070198089140951">"Les options proposées aux développeurs ne sont pas disponibles pour cet utilisateur."</string>
     <string name="vpn_settings_not_available" msgid="2894137119965668920">"Les paramètres de RPV ne sont pas disponibles pour cet utilisateur"</string>
     <string name="tethering_settings_not_available" msgid="266821736434699780">"Les paramètres de partage de connexion ne sont pas disponibles pour cet utilisateur"</string>
@@ -288,8 +288,8 @@
     <string name="confirm_enable_oem_unlock_title" msgid="8249318129774367535">"Permettre le déverrouillage par le fabricant?"</string>
     <string name="confirm_enable_oem_unlock_text" msgid="854131050791011970">"AVERTISSEMENT : Les fonctionnalités de protection de l\'appareil ne fonctionneront pas sur cet appareil lorsque ce paramètre est activé."</string>
     <string name="mock_location_app" msgid="6269380172542248304">"Sélectionner l\'appli de position fictive"</string>
-    <string name="mock_location_app_not_set" msgid="6972032787262831155">"Aucune application de position fictive définie"</string>
-    <string name="mock_location_app_set" msgid="4706722469342913843">"Application de position fictive : <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="mock_location_app_not_set" msgid="6972032787262831155">"Aucune appli de position fictive définie"</string>
+    <string name="mock_location_app_set" msgid="4706722469342913843">"Appli de position fictive : <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="debug_networking_category" msgid="6829757985772659599">"Réseautage"</string>
     <string name="wifi_display_certification" msgid="1805579519992520381">"Certification de l\'affichage sans fil"</string>
     <string name="wifi_verbose_logging" msgid="1785910450009679371">"Autoriser enreg. données Wi-Fi détaillées"</string>
@@ -343,30 +343,30 @@
     <string name="mobile_data_always_on_summary" msgid="1112156365594371019">"Toujours garder les données cellulaires actives, même lorsque le Wi-Fi est activé (pour la commutation rapide entre les réseaux)."</string>
     <string name="tethering_hardware_offload_summary" msgid="7801345335142803029">"Utiliser l\'accélération matérielle du partage de connexion si possible"</string>
     <string name="adb_warning_title" msgid="7708653449506485728">"Autoriser le débogage USB?"</string>
-    <string name="adb_warning_message" msgid="8145270656419669221">"Le débogage USB est conçu uniquement pour le développement. Utilisez-le pour copier des données entre votre ordinateur et votre appareil, installer des applications sur votre appareil sans notification et lire les données de journal."</string>
+    <string name="adb_warning_message" msgid="8145270656419669221">"Le débogage USB est conçu uniquement pour le développement. Utilisez-le pour copier des données entre votre ordinateur et votre appareil, installer des applis sur votre appareil sans notification et lire les données de journal."</string>
     <string name="adbwifi_warning_title" msgid="727104571653031865">"Autoriser le débogage sans fil?"</string>
-    <string name="adbwifi_warning_message" msgid="8005936574322702388">"Le débogage sans fil est conçu uniquement aux fin de conception. Utilisez-le pour copier des données entre votre ordinateur et votre appareil, installer des applications sur votre appareil sans notification et lire les données de journal."</string>
+    <string name="adbwifi_warning_message" msgid="8005936574322702388">"Le débogage sans fil est conçu uniquement aux fin de conception. Utilisez-le pour copier des données entre votre ordinateur et votre appareil, installer des applis sur votre appareil sans notification et lire les données de journal."</string>
     <string name="adb_keys_warning_message" msgid="2968555274488101220">"Voulez-vous vraiment désactiver l\'accès au débogage USB de tous les ordinateurs précédemment autorisés?"</string>
     <string name="dev_settings_warning_title" msgid="8251234890169074553">"Activer les paramètres de développement?"</string>
-    <string name="dev_settings_warning_message" msgid="37741686486073668">"Ces paramètres sont en cours de développement. Ils peuvent endommager votre appareil et les applications qui s\'y trouvent, ou provoquer leur dysfonctionnement."</string>
+    <string name="dev_settings_warning_message" msgid="37741686486073668">"Ces paramètres sont en cours de développement. Ils peuvent endommager votre appareil et les applis qui s\'y trouvent, ou provoquer leur dysfonctionnement."</string>
     <string name="verify_apps_over_usb_title" msgid="6031809675604442636">"Vérifier les applis par USB"</string>
-    <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Vérifier que les applications installées par ADB/ADT ne présentent pas de comportement dangereux."</string>
+    <string name="verify_apps_over_usb_summary" msgid="1317933737581167839">"Vérifier que les applis installées par ADB/ADT ne présentent pas de comportement dangereux."</string>
     <string name="bluetooth_show_devices_without_names_summary" msgid="780964354377854507">"Les appareils Bluetooth sans nom (adresses MAC seulement) seront affichés"</string>
     <string name="bluetooth_disable_absolute_volume_summary" msgid="2006309932135547681">"Désactive la fonctionnalité de volume absolu par Bluetooth en cas de problème de volume sur les appareils à distance, par exemple si le volume est trop élevé ou s\'il ne peut pas être contrôlé."</string>
     <string name="bluetooth_enable_gabeldorsche_summary" msgid="2054730331770712629">"Active la pile de la fonctionnalité Bluetooth Gabeldorsche."</string>
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Active la fonctionnalité Connectivité améliorée."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Terminal local"</string>
-    <string name="enable_terminal_summary" msgid="2481074834856064500">"Activer l\'application Terminal permettant l\'accès au shell local"</string>
+    <string name="enable_terminal_summary" msgid="2481074834856064500">"Activer l\'appli Terminal permettant l\'accès au shell local"</string>
     <string name="hdcp_checking_title" msgid="3155692785074095986">"Vérification HDCP"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"Configurer vérification HDCP"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Débogage"</string>
-    <string name="debug_app" msgid="8903350241392391766">"Sélectionner une application à déboguer"</string>
-    <string name="debug_app_not_set" msgid="1934083001283807188">"Aucune application à déboguer définie"</string>
-    <string name="debug_app_set" msgid="6599535090477753651">"Application à déboguer : <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="select_application" msgid="2543228890535466325">"Sél. application"</string>
+    <string name="debug_app" msgid="8903350241392391766">"Sélectionner une appli à déboguer"</string>
+    <string name="debug_app_not_set" msgid="1934083001283807188">"Aucune appli à déboguer définie"</string>
+    <string name="debug_app_set" msgid="6599535090477753651">"Appli à déboguer : <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="select_application" msgid="2543228890535466325">"Sél. appli"</string>
     <string name="no_application" msgid="9038334538870247690">"Aucune"</string>
     <string name="wait_for_debugger" msgid="7461199843335409809">"Attendre l\'intervention du débogueur"</string>
-    <string name="wait_for_debugger_summary" msgid="6846330006113363286">"Avant de s\'exécuter, l\'application déboguée doit attendre que le débogueur soit attaché."</string>
+    <string name="wait_for_debugger_summary" msgid="6846330006113363286">"Avant de s\'exécuter, l\'appli déboguée doit attendre que le débogueur soit attaché."</string>
     <string name="debug_input_category" msgid="7349460906970849771">"Entrée"</string>
     <string name="debug_drawing_category" msgid="5066171112313666619">"Dessin"</string>
     <string name="debug_hw_drawing_category" msgid="5830815169336975162">"Accélération matérielle"</string>
@@ -401,31 +401,43 @@
     <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Rendre la couleur d\'arrière-plan de la barre de navigation transparente par défaut"</string>
     <string name="window_blurs" msgid="6831008984828425106">"Autoriser le flou au niveau des fenêtres"</string>
     <string name="force_msaa" msgid="4081288296137775550">"Forcer MSAA 4x"</string>
-    <string name="force_msaa_summary" msgid="9070437493586769500">"Activer MSAA 4x dans les applications OpenGL ES 2.0"</string>
+    <string name="force_msaa_summary" msgid="9070437493586769500">"Activer MSAA 4x dans les applis OpenGL ES 2.0"</string>
     <string name="show_non_rect_clip" msgid="7499758654867881817">"Déboguer opérations de découpage non rectangulaire"</string>
     <string name="track_frame_time" msgid="522674651937771106">"Rendu HWUI du profil"</string>
     <string name="enable_gpu_debug_layers" msgid="4986675516188740397">"Activer couches débogage GPU"</string>
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Autoriser couches débogage GPU pour applis de débogage"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Activer le journal détaillé des fournisseurs"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Incluez les journaux supplémentaires du fournisseur propres à l\'appareil dans les rapports de bogue. Ils peuvent contenir des données personnelles, épuiser la pile plus rapidement et/ou utiliser plus d\'espace de stockage."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Échelle animation fenêtres"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Éch. d\'animation des transitions"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Échelle durée animation"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simuler affich. secondaires"</string>
-    <string name="debug_applications_category" msgid="5394089406638954196">"Applications"</string>
+    <string name="debug_applications_category" msgid="5394089406638954196">"Applis"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Ne pas conserver activités"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Supprimer immédiatement les activités abandonnées"</string>
     <string name="app_process_limit_title" msgid="8361367869453043007">"Limite processus arr.-plan"</string>
     <string name="show_all_anrs" msgid="9160563836616468726">"Afficher ANR arrière-plan"</string>
-    <string name="show_all_anrs_summary" msgid="8562788834431971392">"Afficher le message « L\'application ne répond plus » pour les applications en arrière-plan"</string>
+    <string name="show_all_anrs_summary" msgid="8562788834431971392">"Afficher le message « L\'appli ne répond plus » pour les applis en arrière-plan"</string>
     <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Affich. avertiss. canal notification"</string>
     <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Afficher avertiss. à l\'écran quand une appli présente une notif. sans canal valide"</string>
     <string name="force_allow_on_external" msgid="9187902444231637880">"Forcer l\'autor. d\'applis sur stockage externe"</string>
-    <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Rend possible l\'enregistrement de toute application sur un espace de stockage externe, indépendamment des valeurs du fichier manifeste"</string>
+    <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Rend possible l\'enregistrement de toute appli sur un espace de stockage externe, indépendamment des valeurs du fichier manifeste"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Forcer les activités à être redimensionnables"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Permet de redimensionner toutes les activités pour le mode multi-fenêtre, indépendamment des valeurs du fichier manifeste."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Activer les fenêtres de forme libre"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Activer la compatibilité avec les fenêtres de forme libre expérimentales."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Activer fenêtres de forme libre (patrimoniales)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Activer la prise en charge des fenêtres de forme libre patrimoniales expérimentales."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Mot de passe sauvegarde PC"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Les sauvegardes complètes sur PC ne sont pas protégées actuellement"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Touchez pour modifier ou supprimer le mot de passe utilisé pour les sauvegardes complètes sur ordinateur."</string>
@@ -443,14 +455,14 @@
     <item msgid="4548987861791236754">"Couleurs naturelles, comme l\'œil les voit"</item>
     <item msgid="1282170165150762976">"Couleurs optimisées pour le contenu numérique"</item>
   </string-array>
-    <string name="inactive_apps_title" msgid="5372523625297212320">"Applications en veille"</string>
-    <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Application inactive. Touchez ici pour l\'activer."</string>
-    <string name="inactive_app_active_summary" msgid="8047630990208722344">"Application active. Touchez ici pour la désactiver."</string>
-    <string name="standby_bucket_summary" msgid="5128193447550429600">"État de l\'application en veille :<xliff:g id="BUCKET"> %s</xliff:g>"</string>
+    <string name="inactive_apps_title" msgid="5372523625297212320">"Applis en veille"</string>
+    <string name="inactive_app_inactive_summary" msgid="3161222402614236260">"Appli inactive. Touchez ici pour l\'activer."</string>
+    <string name="inactive_app_active_summary" msgid="8047630990208722344">"Appli active. Touchez ici pour la désactiver."</string>
+    <string name="standby_bucket_summary" msgid="5128193447550429600">"État de l\'appli en veille :<xliff:g id="BUCKET"> %s</xliff:g>"</string>
     <string name="transcode_settings_title" msgid="2581975870429850549">"Paramètres de transcodage des éléments multimédias"</string>
     <string name="transcode_user_control" msgid="6176368544817731314">"Remplacer les valeurs par défaut de transcodage"</string>
     <string name="transcode_enable_all" msgid="2411165920039166710">"Activer le transcodage"</string>
-    <string name="transcode_default" msgid="3784803084573509491">"Présumer que les applications prennent en charge les formats modernes"</string>
+    <string name="transcode_default" msgid="3784803084573509491">"Présumer que les applis prennent en charge les formats modernes"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Afficher les notifications de transcodage"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Désactiver le cache de transcodage"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Services en cours d\'exécution"</string>
@@ -535,9 +547,9 @@
     <string name="retail_demo_reset_title" msgid="1866911701095959800">"Mot de passe obligatoire"</string>
     <string name="active_input_method_subtypes" msgid="4232680535471633046">"Modes de saisie actifs"</string>
     <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Utiliser les langues du système"</string>
-    <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Échec de l\'ouverture des paramètres de l\'application <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>."</string>
-    <string name="ime_security_warning" msgid="6547562217880551450">"Ce mode de saisie est susceptible d\'enregistrer le texte que vous saisissez, y compris vos données personnelles, telles que les mots de passe et les numéros de carte de paiement. Il provient de l\'application <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Voulez-vous vraiment l\'activer?"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Remarque : Après un redémarrage, vous ne pouvez pas lancer cette application tant que vous n\'avez pas déverrouillé votre téléphone."</string>
+    <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Échec de l\'ouverture des paramètres de l\'appli <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>."</string>
+    <string name="ime_security_warning" msgid="6547562217880551450">"Ce mode de saisie est susceptible d\'enregistrer le texte que vous saisissez, y compris vos données personnelles, telles que les mots de passe et les numéros de carte de paiement. Il provient de l\'appli <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Voulez-vous vraiment l\'activer?"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Remarque : Après un redémarrage, vous ne pouvez pas lancer cette appli tant que vous n\'avez pas déverrouillé votre téléphone."</string>
     <string name="ims_reg_title" msgid="8197592958123671062">"État d\'enregistrement IMS"</string>
     <string name="ims_reg_status_registered" msgid="884916398194885457">"Enregistré"</string>
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Non enregistré"</string>
@@ -555,8 +567,9 @@
     <string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarmes et rappels"</string>
     <string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Autoriser la création d\'alarmes et de rappels"</string>
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes et rappels"</string>
-    <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Autorisez cette application à créer des alarmes et à programmer des actions urgentes. Cela permet à l’application de s\'exécuter en arrière-plan, ce qui peut nécessiter plus de pile.\n\nSi cette autorisation est désactivée, les alarmes existantes et les événements en temps réel programmés par cette application ne fonctionneront pas."</string>
+    <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Autorisez cette appli à créer des alarmes et à programmer des actions urgentes. Cela permet à l’appli de s\'exécuter en arrière-plan, ce qui peut nécessiter plus de pile.\n\nSi cette autorisation est désactivée, les alarmes existantes et les événements en temps réel programmés par cette appli ne fonctionneront pas."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"horaire, alarme, rappel, horloge"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ne pas déranger"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activer"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activer le mode Ne pas déranger"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Jamais"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Durée"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Toujours demander"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Jusqu\'à la désactivation"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Sans nom)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"À l\'instant"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ce téléphone"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Cette tablette"</string>
@@ -605,20 +619,20 @@
     <string name="blob_expires_text" msgid="7882727111491739331">"Expirent le <xliff:g id="DATE">%s</xliff:g>"</string>
     <string name="shared_data_delete_failure_text" msgid="3842701391009628947">"Une erreur s\'est produite lors de la suppression des données partagées."</string>
     <string name="shared_data_no_accessors_dialog_text" msgid="8903738462570715315">"Il n\'y a aucun bail octroyé pour ces données partagées. Souhaitez-vous les supprimer?"</string>
-    <string name="accessor_info_title" msgid="8289823651512477787">"Applications qui partagent des données"</string>
-    <string name="accessor_no_description_text" msgid="7510967452505591456">"Aucune description fournie par l\'application."</string>
+    <string name="accessor_info_title" msgid="8289823651512477787">"Applis qui partagent des données"</string>
+    <string name="accessor_no_description_text" msgid="7510967452505591456">"Aucune description fournie par l\'appli."</string>
     <string name="accessor_expires_text" msgid="4625619273236786252">"Le bail expire le <xliff:g id="DATE">%s</xliff:g>"</string>
     <string name="delete_blob_text" msgid="2819192607255625697">"Supprimer les données partagées"</string>
     <string name="delete_blob_confirmation_text" msgid="7807446938920827280">"Voulez-vous vraiment supprimer ces données partagées?"</string>
-    <string name="user_add_user_item_summary" msgid="5748424612724703400">"Les utilisateurs disposent de leurs propres applications et de leur propre contenu."</string>
-    <string name="user_add_profile_item_summary" msgid="5418602404308968028">"Vous pouvez limiter l\'accès aux applications et au contenu depuis votre compte."</string>
+    <string name="user_add_user_item_summary" msgid="5748424612724703400">"Les utilisateurs disposent de leurs propres applis et de leur propre contenu."</string>
+    <string name="user_add_profile_item_summary" msgid="5418602404308968028">"Vous pouvez limiter l\'accès aux applis et au contenu depuis votre compte."</string>
     <string name="user_add_user_item_title" msgid="2394272381086965029">"Utilisateur"</string>
     <string name="user_add_profile_item_title" msgid="3111051717414643029">"Profil limité"</string>
     <string name="user_add_user_title" msgid="5457079143694924885">"Ajouter un utilisateur?"</string>
-    <string name="user_add_user_message_long" msgid="1527434966294733380">"Vous pouvez partager cet appareil avec d\'autres personnes en ajoutant des utilisateurs. Chaque utilisateur dispose de son propre espace, où il peut personnaliser, entre autres, ses applications et son fond d\'écran. Chacun peut également modifier les paramètres de l\'appareil, comme les réseaux Wi-Fi, qui touchent tous les utilisateurs.\n\nLorsque vous ajoutez un utilisateur, celui-ci doit configurer son propre espace.\n\nTout utilisateur peut mettre à jour les applications pour les autres utilisateurs. Il se peut que les paramètres et les services d\'accessibilité ne soient pas transférés aux nouveaux utilisateurs."</string>
-    <string name="user_add_user_message_short" msgid="3295959985795716166">"Lorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace.\n\nTout utilisateur peut mettre à jour les applications pour tous les autres utilisateurs."</string>
+    <string name="user_add_user_message_long" msgid="1527434966294733380">"Vous pouvez partager cet appareil avec d\'autres personnes en ajoutant des utilisateurs. Chaque utilisateur dispose de son propre espace, où il peut personnaliser, entre autres, ses applis et son fond d\'écran. Chacun peut également modifier les paramètres de l\'appareil, comme les réseaux Wi-Fi, qui touchent tous les utilisateurs.\n\nLorsque vous ajoutez un utilisateur, celui-ci doit configurer son propre espace.\n\nTout utilisateur peut mettre à jour les applis pour les autres utilisateurs. Il se peut que les paramètres et les services d\'accessibilité ne soient pas transférés aux nouveaux utilisateurs."</string>
+    <string name="user_add_user_message_short" msgid="3295959985795716166">"Lorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace.\n\nTout utilisateur peut mettre à jour les applis pour tous les autres utilisateurs."</string>
     <string name="user_grant_admin_title" msgid="5157031020083343984">"Définir cet utilisateur comme administrateur?"</string>
-    <string name="user_grant_admin_message" msgid="1673791931033486709">"Les administrateurs ont des privilèges spéciaux que les autres utilisateurs n\'ont pas. Un administrateur peut gérer tous les utilisateurs, mettre à jour ou réinitialiser cet appareil, modifier les paramètres, voir toutes les applications installées et accorder ou révoquer les privilèges d\'administrateur à d\'autres personnes."</string>
+    <string name="user_grant_admin_message" msgid="1673791931033486709">"Les administrateurs ont des privilèges spéciaux que les autres utilisateurs n\'ont pas. Un administrateur peut gérer tous les utilisateurs, mettre à jour ou réinitialiser cet appareil, modifier les paramètres, voir toutes les applis installées et accorder ou révoquer les privilèges d\'administrateur à d\'autres personnes."</string>
     <string name="user_grant_admin_button" msgid="5441486731331725756">"Définir comme administrateur"</string>
     <string name="user_setup_dialog_title" msgid="8037342066381939995">"Configurer l\'utilisateur?"</string>
     <string name="user_setup_dialog_message" msgid="269931619868102841">"Assurez-vous que la personne est disponible et qu\'elle peut utiliser l\'appareil pour configurer son espace."</string>
@@ -630,7 +644,7 @@
     <string name="user_new_profile_name" msgid="2405500423304678841">"Nouveau profil"</string>
     <string name="user_info_settings_title" msgid="6351390762733279907">"Informations sur l\'utilisateur"</string>
     <string name="profile_info_settings_title" msgid="105699672534365099">"Informations de profil"</string>
-    <string name="user_need_lock_message" msgid="4311424336209509301">"Avant de créer un profil limité, vous devez définir un écran de verrouillage pour protéger vos applications et vos données personnelles."</string>
+    <string name="user_need_lock_message" msgid="4311424336209509301">"Avant de créer un profil limité, vous devez définir un écran de verrouillage pour protéger vos applis et vos données personnelles."</string>
     <string name="user_set_lock_button" msgid="1427128184982594856">"Définir verrouillage écran"</string>
     <string name="user_switch_to_user" msgid="6975428297154968543">"Passer à <xliff:g id="USER_NAME">%s</xliff:g>"</string>
     <string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Création d\'un utilisateur en cours…"</string>
@@ -649,9 +663,9 @@
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Retirer"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Réinitialisation de la session Invité en cours…"</string>
     <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Réinitialiser la session d\'invité?"</string>
-    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Une nouvelle session d\'invité sera lancée, et toutes les applications et données de la session en cours seront supprimées"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Une nouvelle session d\'invité sera lancée, et toutes les applis et données de la session en cours seront supprimées"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Quitter le mode Invité?"</string>
-    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Les applications et les données de la session d\'invité en cours seront supprimées"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Les applis et les données de la session d\'invité en cours seront supprimées"</string>
     <string name="grant_admin" msgid="4323199171790522574">"Oui, le définir comme administrateur"</string>
     <string name="not_grant_admin" msgid="3557849576157702485">"Non, ne pas le définir comme administrateur"</string>
     <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Quitter"</string>
@@ -710,14 +724,14 @@
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Par défaut"</string>
     <string name="turn_screen_on_title" msgid="2662312432042116026">"Commande d\'activation de l\'écran"</string>
     <string name="allow_turn_screen_on" msgid="6194845766392742639">"Autoriser l\'activation de l\'écran"</string>
-    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Autorisez une application à activer l\'écran. Lorsque vous accordez cette autorisation, l\'application peut activer l\'écran à tout moment sans que vous lui demandiez."</string>
+    <string name="allow_turn_screen_on_description" msgid="43834403291575164">"Autorisez une appli à activer l\'écran. Lorsque vous accordez cette autorisation, l\'appli peut activer l\'écran à tout moment sans que vous lui demandiez."</string>
     <string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"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="268234802198852753">"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="5749813313369517812">"Diffuser <xliff:g id="SWITCHAPP">%1$s</xliff:g>"</string>
     <string name="bt_le_audio_broadcast_dialog_different_output" msgid="2638402023060391333">"Changer la sortie"</string>
     <string name="back_navigation_animation" msgid="8105467568421689484">"Animations pour le retour prédictif"</string>
     <string name="back_navigation_animation_summary" msgid="741292224121599456">"Activer les animations système pour le retour prédictif."</string>
-    <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ce paramètre permet d\'activer les animations du système pour l\'animation des gestes prédictifs. Cela exige de définir le paramètre enableOnBackInvokedCallback à Vrai pour chaque application dans le fichier de configuration."</string>
+    <string name="back_navigation_animation_dialog" msgid="8696966520944625596">"Ce paramètre permet d\'activer les animations du système pour l\'animation des gestes prédictifs. Cela exige de définir le paramètre enableOnBackInvokedCallback à Vrai pour chaque appli dans le fichier de configuration."</string>
     <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
     <string name="not_specified" msgid="5423502443185110328">"Non précisé"</string>
     <string name="neuter" msgid="2075249330106127310">"Neutre"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index ed4bf48..51b0bf0 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Autoriser le chargement de couches de débogage GPU"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Activer la journalisation détaillée du fournisseur"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Inclure les journaux supplémentaires du fournisseur, spécifiques à l\'appareil, dans les rapports de bug. Ils peuvent contenir des informations personnelles, solliciter davantage la batterie et/ou utiliser plus d\'espace de stockage."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Échelle d\'animation des fenêtres"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Échelle d\'animation des transitions"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Échelle de durée d\'animation"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Autoriser l\'enregistrement de toute application sur un espace de stockage externe, indépendamment des valeurs du fichier manifeste"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Forcer le redimensionnement des activités"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Rendre toutes les activités redimensionnables pour le mode multifenêtre, indépendamment des valeurs du fichier manifeste"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Activer les fenêtres de forme libre"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Activer la compatibilité avec les fenêtres de forme libre expérimentales"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Activer les anciennes fenêtres de forme libre"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Permet d\'activer la compatibilité avec les anciennes fenêtres de forme libre expérimentales."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Mot de passe de sauvegarde ordi"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Les sauvegardes complètes sur ordi ne sont actuellement pas protégées"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Appuyez pour modifier ou supprimer le mot de passe des sauvegardes complètes sur ordi."</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes et rappels"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Autoriser cette appli à définir des alarmes et à programmer des actions à certaines heures. Elle s\'exécutera alors en arrière-plan, ce qui peut solliciter davantage la batterie.\n\nSi l\'autorisation est désactivée, les alarmes existantes et les événements programmés par l\'appli ne fonctionneront pas."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"définir, alarme, rappel, horloge"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ne pas déranger"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activer"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activer le mode Ne pas déranger"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Jamais"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Durée"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Toujours demander"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Jusqu\'à ce que vous le désactiviez"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Sans nom)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"À l\'instant"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ce téléphone"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Cette tablette"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 3a08d2f..4f82af3 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permite cargar capas de depuración da GPU para aplicacións de depuración"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Activar rexistro de provedores"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Inclúe outros rexistros de provedores específicos do dispositivo en informes de erros; pode conter información privada, consumir máis batería e ocupar máis espazo de almacenamento"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animación da ventá"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala animación-transición"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala duración animador"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Permite que calquera aplicación compatible se poida escribir nun almacenamento externo, independentemente dos valores do manifesto"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Forzar o axuste do tamaño das actividades"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Permite axustar o tamaño de todas as actividades para o modo multiventá, independentemente dos valores do manifesto"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Activar ventás de forma libre"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Activa a compatibilidade con ventás de forma libre experimentais"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Activar ventás de forma libre (antigas)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Activa a compatibilidade coas ventás de forma libre experimentais antigas."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Contrasinal para copias"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"As copias de seguranza de ordenador completas non están protexidas"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Toca para cambiar ou quitar o contrasinal para as copias de seguranza completas de ordenador"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmas e recordatorios"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permite que esta aplicación defina alarmas e planifique accións que dependan da hora. Con este permiso, a aplicación pode executarse en segundo plano, o que pode provocar un maior consumo de batería.\n\nSe este permiso está desactivado, non funcionarán as alarmas que xa se definisen nin os eventos que dependan da hora planificados por esta aplicación."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"planificar, alarma, recordatorio, reloxo"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Non molestar"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activar"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activar modo Non molestar"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nunca"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duración"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Preguntar sempre"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Ata a desactivación"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Sen nome)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Agora mesmo"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Este teléfono"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Esta tableta"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 07eda9a..9ea6f46 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ડિબગ ઍપ માટે GPU ડિબગ સ્તરો લોડ કરવાની મંજૂરી આપો"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"વર્બોઝ વેન્ડર લૉગિંગ ચાલુ કરો"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ખામીની જાણકારીમાં ડિવાઇસથી જોડાયેલા ચોક્કસ વેન્ડર લૉગ શામેલ કરો, જેમાં ખાનગી માહિતી શામેલ હોઈ શકે છે, તે વધુ બૅટરીનો ઉપયોગ કરી શકે છે અને/અથવા વધુ સ્ટોરેજનો ઉપયોગ કરી શકે છે."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"વિન્ડો ઍનિમેશન સ્કેલ"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ટ્રાન્ઝિશન ઍનિમેશન સ્કેલ"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"ઍનિમેટર અવધિ સ્કેલ"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"ફ્રીફોર્મ વિન્ડો ચાલુ કરો"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"પ્રાયોગિક ફ્રીફોર્મ વિન્ડો માટે સપોર્ટને ચાલુ કરો."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"ફ્રીફોર્મ વિન્ડો ચાલુ કરો (જૂની)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"પ્રાયોગિક જૂની ફ્રીફોર્મ વિન્ડો માટે સપોર્ટ મેળવવાની સુવિધા ચાલુ કરો."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"ડેસ્કટૉપ બૅકઅપ પાસવર્ડ"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ડેસ્કટૉપ સંપૂર્ણ બૅકઅપ હાલમાં સુરક્ષિત નથી"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ડેસ્કટૉપ સંપૂર્ણ બેકઅપ્સ માટેનો પાસવર્ડ બદલવા અથવા દૂર કરવા માટે ટૅચ કરો"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"અલાર્મ અને રિમાઇન્ડર"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"આ ઍપને અલાર્મ સેટ કરવા અને સમય પ્રતિ સંવેદનશીલ ક્રિયાઓ શેડ્યૂલ કરવા માટે મંજૂરી આપો. આ ઍપને બૅકગ્રાઉન્ડમાં ચાલવા દે છે, જેને કારણે બૅટરીનો વધુ વપરાશ થઈ શકે છે.\n\nજો આ પરવાનગી બંધ હોય, તો આ ઍપ દ્વારા શેડ્યૂલ કરવામાં આવેલા વર્તમાન અલાર્મ અને સમય આધારિત ઇવેન્ટ કામ કરશે નહીં."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"શેડ્યૂલ, અલાર્મ, રિમાઇન્ડર, ઘડિયાળ"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"ખલેલ પાડશો નહીં"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ચાલુ કરો"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"ખલેલ પાડશો નહીં ચાલુ કરો"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ક્યારેય નહીં"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"અવધિ"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"દર વખતે પૂછો"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"તમે બંધ ન કરો ત્યાં સુધી"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(નામ નથી)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"હમણાં જ"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"આ ફોન"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"આ ટૅબ્લેટ"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 7db157e..6a7179f 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"डीबग ऐप के लिए जीपीयू डीबग लेयर लोड करने दें"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"वर्बोस वेंडर लॉगिंग चालू करें"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"गड़बड़ियों की रिपोर्ट में डिवाइस से जुड़े अतिरिक्त वेंडर लॉग शामिल करें. इन लॉग में निजी जानकारी, बैटरी का ज़्यादा इस्तेमाल, और/या डिवाइस का स्टोरेज ज़्यादा इस्तेमाल करने की जानकारी हो सकती है."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"विंडो ऐनिमेशन स्‍केल"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ट्रांज़िशन ऐनिमेशन स्‍केल"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"ऐनिमेटर ड्यूरेशन स्केल"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"फ़्रीफ़ॉर्म विंडो (एक साथ कई विंडो दिखाना) चालू करें"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"फ़्रीफ़ॉर्म विंडो आज़माने की सुविधा चालू करें."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"फ़्रीफ़ॉर्म विंडो वाला लेगसी मोड चालू करें"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"एक्सपेरिमेंट के तौर पर उपलब्ध फ़्रीफ़ॉर्म विंडो वाला लेगसी मोड चालू करें."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"डेस्‍कटॉप बैकअप पासवर्ड"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"डेस्‍कटॉप का पूरा बैकअप फ़िलहाल सुरक्षित नहीं है"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"डेस्कटॉप के पूरे बैक अप का पासवर्ड बदलने या हटाने के लिए टैप करें"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"अलार्म और रिमाइंडर"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"इस ऐप्लिकेशन को अलार्म और तय समय पर होने वाली कार्रवाइयों के रिमाइंडर सेट करने की अनुमति दें. ऐसा करने से, ऐप्लिकेशन को बैकग्राउंड में चलने की अनुमति मिलती है. इससे बैटरी ज़्यादा खर्च होती है.\n\nऐप्लिकेशन को यह अनुमति न देने पर, इसकी मदद से सेट किए गए अलार्म और तय समय पर होने वाली कार्रवाइयों के रिमाइंडर काम नहीं करेंगे."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"शेड्यूल, अलार्म, रिमाइंडर, घड़ी"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"परेशान न करें"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"चालू करें"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'परेशान न करें\' चालू करें"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"कभी नहीं"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"अवधि"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"हर बार पूछें"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"जब तक इसे बंद नहीं किया जाता"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(कोई नाम नहीं)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"अभी-अभी"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"यह फ़ोन"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"यह टैबलेट"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index ef0d589..9f88c22 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Omogućuje učitavanje slojeva za otklanjanje pogrešaka GPU-a za aplikacije za otklanjanje pogrešaka"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Omogući opširni zapisnik"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Uključite dodatne zapisnike dobavljača pojedinog uređaja u izvješća o programskim pogreškama koja mogu sadržavati privatne podatke, trošiti više baterije i/ili zauzeti više prostora za pohranu."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Brzina animacije prozora"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Brzina animacije prijelaza"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Razmjer duljine animatora"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Aplikacije se mogu zapisivati u vanjsku pohranu neovisno o vrijednostima manifesta"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Nametni mogućnost promjene veličine za aktivnosti"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Omogući mijenjanje veličine svih aktivnosti za više prozora, neovisno o vrijednostima manifesta."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Omogući prozore slobodnog oblika"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Omogućuje podršku za eksperimentalne prozore slobodnog oblika."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Omogući prozore slobodnog oblika (naslijeđeno)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Omogući podršku za eksperimentalne naslijeđene prozore slobodnog oblika."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Zaporka sigurnosne kopije"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Potpune sigurnosne kopije na stolnom računalu trenutačno nisu zaštićene"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Dodirnite da biste promijenili ili uklonili zaporku za potpune sigurnosne kopije na računalu"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmi i podsjetnici"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Omogućite toj aplikaciji da postavlja alarme i zakazuje radnje u točno određeno vrijeme. To aplikaciji omogućuje da se izvodi u pozadini, pa je moguća dodatna potrošnja baterije.\n\nAko je to dopuštenje isključeno, postojeći alarmi i događaji zakazani putem te aplikacije neće funkcionirati."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"raspored, alarm, podsjetnik, sat"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ne uznemiravaj"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Uključi"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Uključite opciju Ne uznemiravaj."</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikada"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trajanje"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Pitaj svaki put"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Do isključivanja"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Bez imena)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Upravo sad"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ovaj telefon"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ovaj tablet"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index fb142f6..7a8d26f 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"GPU-hibakeresési rétegek betöltésének engedélyezése"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Részletes szolgáltatói naplózás engedélyezése"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"További eszközspecifikus szolgáltatói naplók felvétele a hibajelentésekbe. Ezek a naplók tartalmazhatnak privát információkat, ezenkívül előfordulhat, hogy jobban merítik az akkumulátort, illetve nagyobb tárhelyet foglalnak el."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Ablakanimáció tempója"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Áttűnési animáció tempója"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animáció tempója"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Lehetővé teszi bármely alkalmazás külső tárhelyre való írását a jegyzékértékektől függetlenül"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Tevékenységek átméretezésének kényszerítése"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Legyen az összes tevékenység átméretezhető a többablakos megjelenítés érdekében a jegyzékértékektől függetlenül."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Szabad formájú ablakok engedélyezése"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Kísérleti, szabad formájú ablakok támogatásának engedélyezése."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Szabad formájú ablakok engedélyezése (régi)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Kísérleti, régi szabad formájú ablakok támogatásának engedélyezése."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Asztali mentés jelszava"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Az asztali teljes biztonsági mentések jelenleg nem védettek."</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Koppintson ide az asztali teljes mentések jelszavának módosításához vagy eltávolításához"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Ébresztések és emlékeztetők"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Lehetővé teszi ennek az alkalmazásnak, hogy ébresztéseket állítson be és időérzékeny feladatokat ütemezzen. Ezzel engedélyezi az alkalmazásnak, hogy a háttérben fusson, ami megnövekedett akkumulátorhasználattal járhat.\n\nHa ez az engedély ki van kapcsolva, az alkalmazás által beállított ébresztések és ütemezett időérzékeny események nem fognak működni."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ütemezés, ébresztés, emlékeztető, óra"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ne zavarjanak"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Bekapcsolás"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"A Ne zavarjanak mód bekapcsolása"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Soha"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Időtartam"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Mindig kérdezzen rá"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Kikapcsolásig"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Nincs név)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Az imént"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ez a telefon"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ez a táblagép"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index e7cbf2d..15ea272 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -237,7 +237,7 @@
     <string name="choose_profile" msgid="343803890897657450">"Ընտրեք պրոֆիլ"</string>
     <string name="category_personal" msgid="6236798763159385225">"Անձնական"</string>
     <string name="category_work" msgid="4014193632325996115">"Աշխատանքային"</string>
-    <string name="category_private" msgid="4244892185452788977">"Անձնական"</string>
+    <string name="category_private" msgid="4244892185452788977">"Մասնավոր"</string>
     <string name="category_clone" msgid="1554511758987195974">"Կլոն"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Մշակողի ընտրանքներ"</string>
     <string name="development_settings_enable" msgid="4285094651288242183">"Միացնել մշակողի ընտրանքները"</string>
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Թույլատրել GPU վրիպազերծման շերտերի բեռնումը վրիպազերծման հավելվածների համար"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Մատակարարի մանրամասն գրանցամատյան"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Վրիպակների հաշվետվություններում ներառել կոնկրետ սարքի վերաբերյալ մատակարարի լրացուցիչ մատյանները։ Դա կարող է պարունակել խիստ անձնական տեղեկություններ, ավելի արագ սպառել մարտկոցի լիցքը և/կամ ավելի շատ տարածք օգտագործել։"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Պատուհանի շարժապատկեր"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Անցումների շարժապատկեր"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Շարժանկարի տևողության սանդղակ"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Ակտիվացնել կամայական ձևի պատուհանները"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Միացնել ազատ ձևի փորձնական պատուհանների աջակցումը:"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Միացնել կամայական ձևի պատուհանները (հնացած)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Միացնել կամայական ձևի պատուհանների ստեղծման հնացած փորձնական գործառույթի աջակցումը:"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Աշխատասեղանի պահուստավորման գաղտնաբառ"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Աշխատասեղանի ամբողջական պահուստավորումները այժմ պաշտպանված չեն"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Հպեք՝ աշխատասեղանի ամբողջական պահուստավորման գաղտնաբառը փոխելու կամ հեռացնելու համար"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Զարթուցիչներ և հիշեցումներ"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Թույլատրել այս հավելվածին զարթուցիչներ կարգավորել և որոշակի ժամանակի համար գործողություններ պլանավորել։ Այդ դեպքում հավելվածն աշխատում է ֆոնային ռեժիմում, և արդյունքում մարտկոցի լիցքն ավելի արագ է սպառվում։\n\nԵթե այս թույլտվությունն անջատված է, հավելվածի կողմից կարգավորված զարթուցիչները և գործողությունների ժամանակացույցները չեն աշխատի։"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ժամանակացույց, զարթուցիչ, հիշեցում, ժամացույց"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Չանհանգստացնել"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Միացնել"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Միացրեք «Չանհանգստացնել» ռեժիմը"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Երբեք"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Տևողություն"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Ամեն անգամ հարցնել"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Մինչև անջատեք"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Անանուն)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Հենց նոր"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Այս հեռախոսը"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Այս պլանշետը"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 82a390e..2c36cf1 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Izinkan lapisan debug GPU dimuat di aplikasi debug"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Aktifkan logging vendor panjang"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Sertakan log vendor tambahan khusus perangkat dalam laporan bug, yang mungkin berisi informasi pribadi. Meningkatkan penggunaan baterai dan/atau ruang penyimpanan."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Skala animasi jendela"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala animasi transisi"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Skala durasi animator"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Membuat semua aplikasi dapat ditulis ke penyimpanan eksternal, terlepas dari nilai manifes"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Paksa aktivitas agar ukurannya dapat diubah"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Membuat semua aktivitas dapat diubah ukurannya untuk banyak jendela, terlepas dari nilai manifes."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Aktifkan jendela berformat bebas"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktifkan dukungan untuk jendela eksperimental berformat bebas."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Aktifkan jendela freeform (versi lama)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Aktifkan dukungan untuk jendela freeform eksperimental versi lama."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Sandi cadangan desktop"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Saat ini cadangan desktop penuh tidak dilindungi"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Ketuk guna mengubah atau menghapus sandi untuk cadangan lengkap desktop"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarm &amp; pengingat"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Mengizinkan aplikasi ini menyetel alarm dan menjadwalkan tindakan yang sensitif waktu. Hal ini memungkinkan aplikasi berjalan di latar belakang, sehingga mungkin menggunakan lebih banyak daya baterai.\n\nJika izin ini dinonaktifkan, alarm dan acara berbasis waktu yang dijadwalkan oleh aplikasi ini tidak akan berfungsi."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"jadwal, alarm, pengingat, jam"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Jangan Ganggu"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktifkan"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktifkan mode Jangan Ganggu"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Tidak pernah"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Durasi"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Selalu tanya"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Sampai Anda menonaktifkannya"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Tanpa nama)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Baru saja"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ponsel ini"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Tablet ini"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 47cdcca..793663a 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Leyfa villuleit skjákorts fyrir villuleit forrita"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Nákvæm skráning söluaðila"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Taka með viðbótarannála söluaðila fyrir tiltekin tæki í villutilkynningum, sem gætu innihaldið viðkvæmar upplýsingar, notað meiri rafhlöðuorku og/eða þurft meira geymslupláss."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Kvarði gluggahreyfinga"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Lengd hreyfiumbreytinga"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Tímalengd hreyfiáhrifa"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Gerir öll forrit skrifanleg í ytra geymslurými, óháð gildum í upplýsingaskrá"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Þvinga breytanlega stærð virkni"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Gera stærð allrar virkni breytanlega svo að hún henti fyrir marga glugga, óháð gildum í upplýsingaskrá."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Virkja glugga með frjálsu sniði"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Virkja stuðning við glugga með frjálsu sniði á tilraunastigi."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Virkja glugga á frjálsu sniði (eldra)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Virkja stuðning við eldri tilraunaglugga á frjálsu sniði."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Aðgangsorð tölvuafritunar"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Heildarafritun á tölvu er ekki varin sem stendur."</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Ýttu til að breyta eða fjarlægja aðgangsorðið fyrir heildarafritun á tölvu"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Vekjarar og áminningar"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Leyfa þessu forriti að stilla vekjara og áætla aðgerðir sem þurfa að eiga sér stað innan ákveðins tímaramma. Þetta leyfir forritinu að keyra í bakgrunninum sem getur notað meiri rafhlöðuorku.\n\nEf slökkt er á þessari heimild munu núverandi vekjarar og tímasettir viðburðir sem þetta forrit stillir ekki virka."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"áætlun, vekjari, áminning, klukka"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ónáðið ekki"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Kveikja"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Kveikja á „Ónáðið ekki“"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Aldrei"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Lengd"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Spyrja í hvert skipti"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Þar til þú slekkur"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Nafn vantar)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Rétt í þessu"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Þessi sími"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Þessi spjaldtölva"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 3714593..e88977e 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Consenti caricamento livelli debug GPU per app di debug"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Attiva log dettagliati fornitori"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Includi log aggiuntivi di fornitori relativi a un dispositivo specifico nelle segnalazioni di bug che potrebbero contenere informazioni private, causare un maggior consumo della batteria e/o utilizzare più spazio di archiviazione"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Scala animazione finestra"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Scala animazione transizione"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Scala durata animatore"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Consente l\'installazione di qualsiasi app su memoria esterna, indipendentemente dai valori manifest"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Imponi formato modificabile alle attività"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Rendi il formato di tutte le attività modificabile per la modalità multi-finestra, indipendentemente dai valori manifest"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Attiva finestre a forma libera"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Attiva il supporto delle finestre a forma libera sperimentali"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Attiva finestre a forma libera (legacy)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Attiva il supporto delle finestre a forma libera sperimentali legacy."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Password di backup desktop"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"I backup desktop completi non sono attualmente protetti"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tocca per modificare o rimuovere la password per i backup desktop completi"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Sveglie e promemoria"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Consenti a questa app di impostare sveglie e programmare azioni per orari specifici. L\'app potrà essere eseguita in background, comportando un consumo maggiore della batteria.\n\nSe questa autorizzazione viene disattivata, le sveglie esistenti e gli eventi basati sull\'orario programmati da questa app non funzioneranno."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programmare, sveglia, promemoria, orologio"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Non disturbare"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Attiva"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Attiva Non disturbare"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Mai"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Durata"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Chiedi ogni volta"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Fino alla disattivazione"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Nessun nome)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Adesso"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Questo smartphone"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Questo tablet"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index c2f4a8f..8b08e4f 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -125,7 +125,7 @@
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"אודיו של מדיה"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"שיחות טלפון"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"העברת קבצים"</string>
-    <string name="bluetooth_profile_hid" msgid="2969922922664315866">"התקן קלט"</string>
+    <string name="bluetooth_profile_hid" msgid="2969922922664315866">"מכשיר לקליטת נתונים"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"גישה לאינטרנט"</string>
     <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"אישור גישה אל אנשי הקשר והיסטוריית השיחות"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"המידע הזה ישמש למשל כדי להשמיע התראות על שיחות נכנסות"</string>
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"‏טעינת שכבות לניפוי באגים ב-GPU לאפליקציות ניפוי באגים"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"הפעלת רישום ספקים מפורט ביומן"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"הוספת רישומי יומן של יצרנים למכשירים ספציפיים בדוחות על באגים. דוחות אלה עשויים להכיל מידע פרטי, להגביר את צריכת הסוללה ולצרוך נפח אחסון גדול יותר."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"קנה מידה לאנימציה של חלון"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"קנה מידה לאנימציית מעבר"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"קנה מידה למשך זמן אנימציה"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"הפעלת האפשרות לשנות את הגודל והמיקום של החלונות"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"הפעלת תמיכה בתכונה הניסיונית של שינוי הגודל והמיקום של החלונות."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"הפעלת שינוי הגודל והמיקום של החלונות (מדור קודם)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"הפעלת תמיכה בתכונה הניסיונית מדור קודם של שינוי הגודל והמיקום של החלונות."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"סיסמת גיבוי שולחן העבודה"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"גיבויים מלאים בשולחן העבודה אינם מוגנים כעת"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"יש להקיש כדי לשנות או להסיר את הסיסמה לגיבויים מלאים בשולחן העבודה"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"שעונים מעוררים ותזכורות"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ההרשאה הזו מתירה לאפליקציה להגדיר שעון מעורר ולתזמן פעולות דחופות. האפליקציה תוכל לפעול ברקע ובכך להגביר את צריכת הסוללה.\n\nאם ההרשאה מושבתת, ההתראות והאירועים מבוססי-הזמן שהוגדרו ותוזמנו על ידי האפליקציה לא יפעלו."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"תזמון, שעון מעורר, תזכורת, שעון"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"נא לא להפריע"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"הפעלה"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"הפעלת מצב נא לא להפריע"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"אף פעם"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"משך זמן"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"יש לשאול בכל פעם"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"עד הכיבוי"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(ללא שם)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"הרגע"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"הטלפון הזה"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"הטאבלט הזה"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 17e902e..6cd7505 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"デバッグアプリに GPU デバッグレイヤの読み込みを許可"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ベンダーの詳細なロギングを有効にする"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"バグレポートには、その他のデバイス固有のベンダーログが含まれます。これには、非公開の情報が含まれることがあります。また、バッテリーやストレージの使用量が増えることもあります。"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"ウィンドウ アニメ スケール"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"トランジション アニメ スケール"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator 再生時間スケール"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"フリーフォーム ウィンドウを有効にする"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"試験運用機能のフリーフォーム ウィンドウのサポートを有効にします。"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"フリーフォーム ウィンドウを有効にする(従来版)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"従来の試験運用版のフリーフォーム ウィンドウのサポートを有効にします。"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"PC バックアップ パスワード"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"デスクトップのフルバックアップは現在保護されていません"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"デスクトップのフルバックアップ用のパスワードを変更または削除する場合にタップします"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"アラームとリマインダー"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"アラームの設定や時間ベースのアクション設定を、このアプリに許可します。これによりアプリがバックグラウンドで実行できるようになるため、バッテリーの使用量が増えることがあります。\n\nこの権限が OFF の場合、このアプリで設定された既存のアラームと時間ベースのイベントは機能しなくなります。"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"スケジュール, アラーム, リマインダー, 時計"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"サイレント モード"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ON にする"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"サイレント モードを ON にする"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"なし"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"時間"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"毎回確認"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"OFF にするまで"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(名前なし)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"たった今"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"このデバイス"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"このタブレット"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 4efebc5..4da0f5f 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -412,6 +412,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"გასამართი აპებისთვის GPU-ს შეცდომების გამართვის შრეების გაშვების დაშვება"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ჟურნალებში მომწოდებელთა დაწვრილებითი აღრიცხვის ჩართვა"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"გამყიდველის მოწყობილობისთვის სპეციფიკური დამატებითი ჟურნალები შევიდეს სისტემის ხარვეზის ანგარიშებში, რომლებიც შეიძლება შეიცავდეს პირად ინფორმაციას, ხარჯავდეს ბატარეის მეტ მუხტს და/ან იყენებდეს მეტ მეხსიერებას."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"ფანჯარა: მასშტაბი"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"გადასვლის მასშტაბი"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"ანიმაციების ხანგრძლივობის მასშტაბი"</string>
@@ -428,8 +440,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"თავისუფალი ფორმის მქონე ფანჯრების ჩართვა"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"თავისუფალი ფორმის მქონე ფანჯრების მხარდაჭერის ექსპერიმენტული ფუნქციის ჩართვა."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"თავისუფალი ფორმის ფანჯრების ჩართვა (მოძველებული)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"თავისუფალი ფორმის ექსპერიმენტული მოძველებული ფანჯრების ჩართვა."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"დესკტოპის სარეზერვო ასლის პაროლი"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"დესკტოპის სრული სარეზერვო ასლები ამჟამად დაცული არ არის"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"შეეხეთ დესკტოპის სრული სარეზერვო ასლების პაროლის შესაცვლელად ან წასაშლელად"</string>
@@ -561,6 +573,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"მაღვიძარები და შეხსენებები"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ნებას რთავს ამ აპს, დააყენოს მაღვიძარები და დაგეგმოს დროზე დამოკიდებული მოქმედებები. ეს საშუალებას აძლევს აპს, იმუშაოს ფონურად, რამაც შეიძლება ბატარეის ხარჯი გაზარდოს.\n\nთუ ეს ნებართვა გამორთულია, ამ აპით დაგეგმილი მაღვიძარები და დროზე დამოკიდებული მოვლენები არ იმუშავებს."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"განრიგი, მაღვიძარა, შეხსენება, საათი"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"არ შემაწუხოთ"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ჩართვა"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"„არ შემაწუხოთ“ რეჟიმის ჩართვა"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"არასოდეს"</string>
@@ -573,6 +586,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"ხანგრძლივობა"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ყოველთვის მკითხეთ"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"გამორთვამდე"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(უსახელო)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"ახლახან"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"ეს ტელეფონი"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ამ ტაბლეტზე"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index a1ea070..07f34e2 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -58,7 +58,7 @@
     <string name="wifi_cant_connect_to_ap" msgid="3099667989279700135">"\"<xliff:g id="AP_NAME">%1$s</xliff:g>\" қолданбасына қосылу мүмкін емес"</string>
     <string name="wifi_check_password_try_again" msgid="8817789642851605628">"Құпия сөзді тексеріп, әрекетті қайталаңыз"</string>
     <string name="wifi_not_in_range" msgid="1541760821805777772">"Аумақта жоқ"</string>
-    <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Автоматты қосылмайды"</string>
+    <string name="wifi_no_internet_no_reconnect" msgid="821591791066497347">"Автоматты түрде қосылмайды"</string>
     <string name="wifi_no_internet" msgid="1774198889176926299">"Интернетпен байланыс жоқ"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> сақтаған"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s арқылы автоматты қосылды"</string>
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"GPU түзету қабаттарының жүктелуіне рұқсат ету"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Жеткізуші туралы толық мәліметті тіркеу"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Қате туралы есепте жеткізушінің құрылғыға қатысты қосымша ақпараты қамтылады. Мұнда жеке ақпарат көрсетілуі, батарея шығыны артуы және/немесе қосымша жад пайдаланылуы мүмкін."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Терезе анимациясының өлшемі"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Ауысу анимациясының өлшемі"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Аниматор ұзақтығы"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Еркін пішінді терезелерге рұқсат беру"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Еркін пішінді терезелерді құру эксперименттік функиясын қосу"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Еркін пішінді терезелерге рұқсат беру (бұрынғы)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Эксперименттік бұрынғы еркін пішінді терезелерді қолдауға рұқсат береді."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Компьютердегі сақтық көшірме құпия сөзі"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Компьютердегі толық сақтық көшірмелер қазір қорғалмаған."</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Үстелдік компьютердің толық сақтық көшірмелерінің кілтсөзін өзгерту немесе жою үшін түртіңіз"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Оятқыштар мен еске салғыштар"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Бұл қолданбаға оятқыштарды орнатуға және уақытқа байланысты әрекеттерді жоспарлауға рұқсат береді. Мұндайда қолданба фондық режимде жұмыс істейді, сондықтан батарея шығыны артуы мүмкін.\n\nБұл рұқсат өшірулі болса, осы қолданбада жоспарланған ағымдағы оятқыштар мен уақытқа байланысты іс-шаралар жұмыс істемейді."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"кесте, оятқыш, еске салғыш, сағат"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Мазаламау"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Қосу"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Мазаламау режимін қосу"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Ешқашан"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Ұзақтығы"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Әрдайым сұрау"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Өшірілгенге дейін"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Аты берілмеген)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Дәл қазір"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Осы телефон"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Осы планшет"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 431bdf7..ff594e3 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"អនុញ្ញាតឱ្យ​ផ្ទុក​ស្រទាប់​ជួស​ជុល GPU សម្រាប់​កម្មវិធី​ជួសជុល"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"បើកការកត់ត្រាអ្នកផ្គត់ផ្គង់ឥតសំចៃ"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"រួមបញ្ចូលកំណត់​ហេតុ​អ្នកផ្គត់ផ្គង់​ពាក់ព័ន្ធ​នឹងឧបករណ៍បន្ថែមទៀតនៅក្នុងរបាយការណ៍​អំពីបញ្ហា ដែលអាច​មានផ្ទុកព័ត៌មាន​ឯកជន ប្រើប្រាស់​ថ្មច្រើនជាង និង/ឬប្រើប្រាស់​ទំហំផ្ទុកច្រើនជាង។"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"មាត្រដ្ឋាន​ចលនា​វិនដូ"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"មាត្រដ្ឋាន​ដំណើរ​ផ្លាស់ប្ដូរ​ចលនា"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"មាត្រដ្ឋាន​រយៈពេល​នៃ​កម្មវិធី​ចលនា"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"បើកដំណើរការផ្ទាំងវិនដូទម្រង់សេរី"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"បើកឱ្យអាចប្រើផ្ទាំងវិនដូទម្រង់សេរីពិសោធន៍។"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"បើកវិនដូទម្រង់សេរី (ចាស់)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"បើកជំនួយសម្រាប់វិនដូទម្រង់សេរីចាស់ក្នុងដំណាក់កាលពិសោធន៍។"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"ពាក្យ​សម្ងាត់​បម្រុង​ទុក​លើកុំព្យូទ័រ"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"បច្ចុប្បន្ន ការ​បម្រុង​ទុក​ពេញលេញនៅលើកុំព្យូទ័រមិន​ត្រូវ​បាន​ការពារ​ទេ"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ប៉ះដើម្បីប្ដូរ ឬយកពាក្យសម្ងាត់ចេញសម្រាប់ការបម្រុងទុកពេញលេញលើកុំព្យូទ័រ"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"ម៉ោងរោទ៍ និង​ការរំលឹក"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"អនុញ្ញាតឱ្យ​កម្មវិធីនេះ​កំណត់ម៉ោងរោទ៍ និងកំណត់កាលវិភាគសកម្មភាពដែលតម្រូវឱ្យទាន់ពេលវេលា។ ការធ្វើបែបនេះអនុញ្ញាតឱ្យកម្មវិធីនេះដំណើរការនៅផ្ទៃខាងក្រោយ ដែលអាចប្រើថ្មកាន់តែច្រើន។\n\nប្រសិនបើបិទការអនុញ្ញាតនេះ ម៉ោងរោទ៍ដែលមានស្រាប់ និងព្រឹត្តិការណ៍ផ្អែកលើពេលវេលាដែលកំណត់ដោយកម្មវិធីនេះ​នឹងមិនដំណើរការទេ។"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"កាលវិភាគ ម៉ោងរោទ៍ ការរំលឹក នាឡិកា"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"កុំ​រំខាន"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"បើក"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"បើកមុខងារកុំរំខាន"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"កុំឱ្យសោះ"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"រយៈពេល"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"សួរគ្រប់ពេល"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"រហូតទាល់តែ​អ្នកបិទ"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(គ្មាន​ឈ្មោះ)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"អម្បាញ់មិញ"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"ទូរសព្ទនេះ"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ថេប្លេតនេះ"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index a25e179..afea19f 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ಡೀಬಗ್ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗಾಗಿ GPU ಡೀಬಗ್ ಲೇಯರ್‌ಗಳನ್ನು ಲೋಡ್ ಮಾಡುವುದನ್ನು ಅನುಮತಿಸಿ"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ವರ್‌ಬೋಸ್ ವೆಂಡರ್ ಲಾಗಿಂಗ್‌ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ಬಗ್ ವರದಿಗಳಲ್ಲಿ ಹೆಚ್ಚುವರಿ ಸಾಧನ ನಿರ್ದಿಷ್ಟ ವೆಂಡರ್ ಲಾಗ್‌ಗಳು ಒಳಗೊಂಡಿದೆ, ಇದು ಖಾಸಗಿ ಮಾಹಿತಿ, ಹೆಚ್ಚಿನ ಬ್ಯಾಟರಿ ಬಳಕೆ ಮತ್ತು/ಅಥವಾ ಹೆಚ್ಚಿನ ಸಂಗ್ರಹಣೆಯ ಬಳಕೆಯನ್ನು ಒಳಗೊಂಡಿರಬಹುದು."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Window ಅನಿಮೇಶನ್ ಸ್ಕೇಲ್‌"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ಪರಿವರ್ತನೆ ಅನಿಮೇಶನ್ ಸ್ಕೇಲ್‌"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"ಅನಿಮೇಟರ್ ಅವಧಿಯ ಪ್ರಮಾಣ"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"ಮುಕ್ತಸ್ವರೂಪದ ವಿಂಡೊಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ಪ್ರಾಯೋಗಿಕ ಫ್ರೀಫಾರ್ಮ್ ವಿಂಡೊಗಳಿಗೆ ಬೆಂಬಲವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"ಫ್ರೀಫಾರ್ಮ್ ವಿಂಡೋಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ (ಲೆಗಸಿ)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"ಪ್ರಾಯೋಗಿಕ ಲೆಗಸಿ ಫ್ರೀಫಾರ್ಮ್ ವಿಂಡೋಗಳಿಗೆ ಬೆಂಬಲವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"ಡೆಸ್ಕ್‌ಟಾಪ್ ಬ್ಯಾಕಪ್ ಪಾಸ್‌ವರ್ಡ್"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ಡೆಸ್ಕ್‌ಟಾಪ್‌‌ ಪೂರ್ಣ ಬ್ಯಾಕಪ್‌‌ಗಳನ್ನು ಪ್ರಸ್ತುತ ರಕ್ಷಿಸಲಾಗಿಲ್ಲ"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ಡೆಸ್ಕ್‌ಟಾಪ್‌ನ ಪೂರ್ಣ ಬ್ಯಾಕಪ್‌ಗಳಿಗೆ ಪಾಸ್‌ವರ್ಡ್‌ ಬದಲಾಯಿಸಲು ಅಥವಾ ತೆಗೆದುಹಾಕಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"ಅಲಾರಂಗಳು ಮತ್ತು ರಿಮೈಂಡರ್‌ಗಳು"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ಅಲಾರಂಗಳನ್ನು ಹೊಂದಿಸಲು ಮತ್ತು ಸಮಯ-ಸೂಕ್ಷ್ಮವಾದ ಕ್ರಿಯೆಗಳನ್ನು ನಿಗದಿಪಡಿಸಲು ಈ ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸಿ. ಇದು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ, ಅದರಿಂದ ಹೆಚ್ಚು ಬ್ಯಾಟರಿ ಬಳಕೆಯಾಗಬಹುದು.\n\nಈ ಅನುಮತಿ ಆಫ್ ಆಗಿದ್ದರೆ, ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಅಲಾರಂಗಳು ಮತ್ತು ಈ ಆ್ಯಪ್ ನಿಗದಿಪಡಿಸಿದ ಸಮಯ-ಸೂಕ್ಷ್ಮ ಈವೆಂಟ್‌ಗಳು ಕೆಲಸ ಮಾಡುವುದಿಲ್ಲ."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ವೇಳಾಪಟ್ಟಿ, ಅಲಾರಂ, ರಿಮೈಂಡರ್, ಗಡಿಯಾರ"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ಆನ್ ಮಾಡಿ"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಅನ್ನು ಆನ್ ಮಾಡಿ"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ಎಂದೂ ಇಲ್ಲ"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"ಅವಧಿ"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ಪ್ರತಿ ಬಾರಿ ಕೇಳಿ"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"ನೀವು ಆಫ್ ಮಾಡುವವರೆಗೆ"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(ಯಾವುದೇ ಹೆಸರಿಲ್ಲ)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"ಇದೀಗ"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"ಈ ಫೋನ್"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ಈ ಟ್ಯಾಬ್ಲೆಟ್"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 9cb770f..e88fc04 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"디버그 앱에 GPU 디버그 레이어 로드 허용"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"상세 공급업체 로깅 사용 설정"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"버그 신고에 추가적인 기기별 공급업체 로그를 포함합니다. 여기에는 개인정보가 포함될 수 있으며, 배터리 또는 저장공간 사용량이 늘어날 수 있습니다."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"창 애니메이션 배율"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"전환 애니메이션 배율"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator 길이 배율"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"자유 형식 창 사용"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"자유 형식 창 지원 사용"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"자유 형식 창 사용(레거시)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"실험적인 레거시 자유 형식 창에 대한 지원을 사용하도록 설정합니다."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"데스크톱 백업 비밀번호"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"데스크톱 전체 백업에 비밀번호가 설정되어 있지 않음"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"데스크톱 전체 백업에 대한 비밀번호를 변경하거나 삭제하려면 탭하세요."</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"알람 및 리마인더"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"이 앱이 알람을 설정하고 시간 기반 작업을 예약할 수 있도록 허용합니다. 이렇게 하면 백그라운드에서 앱 실행이 허용되어 배터리 사용량이 증가할 수 있습니다.\n\n이 권한을 사용 중지하면 이 앱에서 예약한 기존의 알람 및 시간 기반 일정이 작동하지 않습니다."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"일정 예약, 알람, 리마인더, 시계"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"방해 금지 모드"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"사용 설정"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"방해 금지 모드 사용 설정"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"사용 안함"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"지속 시간"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"항상 확인"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"사용 중지할 때까지"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(이름 없음)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"조금 전"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"이 휴대전화"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"이 태블릿"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 64180a9..16f2ddb 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"GPU мүчүлүштүктөрдү оңдоо катмарларын иштетет"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Кызмат көрсөтүүчүнүн журналы"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Кызмат көрсөтүүчүнүн түзмөккө байланыштуу кошумча жазуулары мүчүлүштүк тууралуу кабарларга кошулат. Анда купуя маалымат камтылып, батарея тезирээк отуруп жана/же сактагычтан көбүрөөк орун ээлеши мүмкүн."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Терезелердин анимациясы"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Өткөрүү анимацснн шкаласы"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Анимациянын узактыгы"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Эркин формадагы терезелерди түзүүнү иштетүү"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Эркин формадагы терезелерди түзүү боюнча сынамык функциясы иштетилет."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Эркин формадагы терезелерди түзүүнү иштетүү (эски)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Эркин формадагы эски терезелерди түзүү боюнча сынамык функциясы иштетилет."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Камдык көчүрмөнүн сырсөзү"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Толук камдык көчүрмөлөр учурда корголгон эмес"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Иш тактасынын камдалган сырсөзүн өзгөртүү же алып салуу үчүн таптап коюңуз"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Ойготкучтар жана эстеткичтер"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Бул колдонмого ойготкучтарды коюуга жана башка аракеттерди графикке киргизүүгө уруксат бересиз. Ушуну менен колдонмо фондо иштеп, батареяны көбүрөөк сарпташы мүмкүн.\n\nЭгер бул уруксат өчүрүлсө, колдонмодогу ойготкучтар жана графикке киргизилген башка аракеттер иштебейт."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"график, ойготкуч, эстеткич, саат"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Тынчымды алба"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Күйгүзүү"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\"Тынчымды алба\" режимин күйгүзүү"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Эч качан"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Узактыгы"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Ар дайым суралсын"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Бул функция өчүрүлгөнгө чейин"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Аты жок)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Жаңы эле"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ушул телефон"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ушул планшет"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index f6a2681..1eec5a7 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ອະນຸຍາດການໂຫລດຊັ້ນຂໍ້ມູນດີບັກ GPU ສຳລັບແອັບດີບັກ"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ເປີດໃຊ້ການບັນທຶກຜູ້ຂາຍແບບລະອຽດ"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ຮວມທັງການລາຍງານຂໍ້ຜິດພາດການເຂົ້າສູ່ລະບົບຂອງຜູ້ຂາຍສະເພາະອຸປະກອນເພີ່ມເຕີມ, ເຊິ່ງອາດມີຂໍ້ມູນສ່ວນຕົວ, ໃຊ້ແບັດເຕີຣີຫຼາຍຂຶ້ນ ແລະ/ຫຼື ໃຊ້ບ່ອນຈັດເກັບຂໍ້ມູນເພີ່ມເຕີມ."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"ຂະໜາດໜ້າ​ຈໍ​ຂອງອະນິເມຊັນ"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ຂະໜາດສະຫຼັບອະນິເມຊັນ"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"ໄລຍະເວລາອະນິເມຊັນ"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"ເຮັດໃຫ້ທຸກແອັບມີສິດໄດ້ຮັບການຂຽນໃສ່ພື້ນທີ່ຈັດເກັບຂໍ້ມູນພາຍນອກ, ໂດຍບໍ່ຄຳນຶງເຖິງຄ່າ manifest"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"ບັງ​ຄັງ​ໃຫ້​ການ​ເຄື່ອນ​ໄຫວ​ປ່ຽນ​ຂະ​ໜາດ​ໄດ້"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"ເຮັດໃຫ້ທຸກການ​ເຄື່ອນ​ໄຫວສາມາດປັບຂະໜາດໄດ້ສຳລັບຫຼາຍໜ້າຈໍ, ໂດຍບໍ່ຄຳນຶງເຖິງຄ່າ manifest."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"ເປີດໃຊ້ໜ້າຈໍຮູບແບບອິດສະຫຼະ"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ເປີດໃຊ້ການຮອງຮັບໜ້າຈໍຮູບແບບອິດສະຫຼະແບບທົດລອງ."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"ເປີດການນຳໃຊ້ໜ້າຈໍຮູບແບບອິດສະຫຼະ (ແບບເກົ່າ)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"ເປີດການນຳໃຊ້ການຮອງຮັບໜ້າຈໍຮູບແບບອິດສະຫຼະແບບເກົ່າເວີຊັນທົດລອງ."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"ລະຫັດຜ່ານການສຳຮອງຂໍ້ມູນເດັສທັອບ"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ການ​ສຳຮອງ​ຂໍ້ມູນ​ເຕັມຮູບແບບ​ໃນ​ເດັສທັອບ​ຍັງ​ບໍ່​ໄດ້​ຮັບ​ການ​ປ້ອງກັນ​ໃນ​ເວລາ​ນີ້"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ແຕະເພື່ອປ່ຽນ ຫຼື ລຶບລະຫັດຂອງການສຳຮອງຂໍ້ມູນເຕັມຮູບແບບໃນເດັສທັອບ"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"ໂມງປຸກ ແລະ ການແຈ້ງເຕືອນ"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ອະນຸຍາດໃຫ້ແອັບນີ້ຕັ້ງໂມງປຸກ ແລະ ກຳນົດເວລາຄຳສັ່ງທີ່ເນັ້ນເລື່ອງເວລາເປັນສຳຄັນໄດ້. ນີ້ຈະເຮັດໃຫ້ແອັບເຮັດວຽກໄດ້ໃນພື້ນຫຼັງ, ເຊິ່ງອາດໃຊ້ແບັດເຕີຣີຫຼາຍຂຶ້ນ.\n\nຫາກປິດການອະນຸຍາດນີ້ໄວ້, ໂມງປຸກທີ່ມີຢູ່ກ່ອນແລ້ວ ແລະ ເຫດການທີ່ອ້າງອີງເວລາທີ່ກຳນົດໄວ້ໂດຍແອັບນີ້ຈະບໍ່ສາມາດເຮັດວຽກໄດ້."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ກຳນົດເວລາ, ໂມງປຸກ, ການແຈ້ງເຕືອນ, ໂມງ"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"ຫ້າມລົບກວນ"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ເປີດ"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"ເປີດໂໝດຫ້າມລົບກວນ"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ບໍ່ໃຊ້"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"ໄລຍະເວລາ"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ຖາມທຸກເທື່ອ"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"ຈົນກວ່າທ່ານຈະປິດ"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(ບໍ່ມີຊື່)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"ຕອນນີ້"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"ໂທລະສັບນີ້"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ແທັບເລັດນີ້"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 4abde8f..d879c9d 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Leisti įkelti graf. proc. der. sluoks. der. progr."</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Įg. daugiaž. pasl. teik. reg."</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Į pranešimus apie riktą įtraukiami papildomi konkretaus įrenginio paslaugų teikėjo žurnalai, kuriuose gali būti privačios informacijos, kurie gali naudoti daugiau akumuliatoriaus energijos ir (arba) daugiau vietos saugykloje."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Lango animacijos mast."</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Animuoto perėjimo mast."</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator. trukmės skalė"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Nustatoma, kad visas programas būtų galima įrašyti į išorinę saugyklą, nepaisant aprašo verčių"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Priv. nust., kad veiksm. b. g. atl. kelių d. lang."</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Nustatyti, kad visus veiksmus būtų galima atlikti kelių dydžių languose, nepaisant aprašo verčių."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Įgalinti laisvos formos langus"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Įgalinti eksperimentinių laisvos formos langų palaikymą."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Įgalinti laisvos formos langus (pasenę)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Įgalinti eksperimentinių pasenusių laisvos formos langų palaikymą."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Viet. atsrg. kop. slapt."</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Šiuo metu visos vietinės atsarginės kopijos neapsaugotos"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Jei norite pakeisti ar pašalinti visų stalinio kompiuterio atsarginių kopijų slaptažodį, palieskite"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Signalai ir priminimai"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Leiskite šiai programai nustatyti signalus ir suplanuoti veiksmus, kuriems svarbus laiko veiksnys. Dėl to programa gali veikti fone ir sunaudoti daugiau akumuliatoriaus energijos.\n\nJei šis leidimas išjungtas, šios programos suplanuoti esami signalai ir laiku pagrįsti įvykiai neveiks."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"tvarkaraštis, signalas, priminimas, laikrodis"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Netrukdymo režimas"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Įjungti"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Netrukdymo režimo įjungimas"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Niekada"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trukmė"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Klausti kaskart"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Kol išjungsite"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Nėra pavadinimo)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Ką tik"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Šis telefonas"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Šis planšetinis kompiuteris"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index a8c3f5a..ac00d05 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Atļaut GPU atkļūd. slāņu ielādi atkļūd. lietotnēm"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Iespējot izvērsto reģistrēšanu"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Iekļaut kļūdu pārskatos konkrētas ierīces papildu nodrošinātāju žurnālus (var iekļaut privātu informāciju, patērēt vairāk akumulatora enerģijas un/vai aizņemt vairāk vietas krātuvē)."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Loga animācijas mērogs"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Pārejas animācijas mērogs"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animācijas ilguma mērogs"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Ļauj jebkuru lietotni ierakstīt ārējā krātuvē neatkarīgi no manifesta vērtības."</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Pielāgot darbības"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Pielāgot visas darbības vairāku logu režīmam neatkarīgi no vērtībām manifestā."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Iespējot brīvās formas logus"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Iespējot eksperimentālo brīvās formas logu atbalstu."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Iespējot brīvās formas logus (mantots režīms)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Iespējot atbalstu eksperimentālajam, mantotajam brīvās formas logu režīmam."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Datora dublējuma parole"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Darbvirsmas pilnie dublējumi pašlaik nav aizsargāti."</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Pieskarieties, lai mainītu vai noņemtu paroli pilniem datora dublējumiem."</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Signāli un atgādinājumi"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Atļaujiet šai lietotnei iestatīt signālus un ieplānot darbības, kas jāveic konkrētā laikā. Tādējādi lietotne darbosies fonā un, iespējams, patērēs vairāk akumulatora enerģijas.\n\nJa šī atļauja nav piešķirta, esošie signāli un šīs lietotnes ieplānotie notikumi, kas jāizpilda konkrētā laikā, nedarbosies."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ieplānot, signāls, atgādinājums, pulkstenis"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Netraucēt"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ieslēgt"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Režīma “Netraucēt” ieslēgšana"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nekad"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Ilgums"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Vaicāt katru reizi"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Līdz brīdim, kad izslēgsiet"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Nav vārda)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Tikko"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Šis tālrunis"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Šis planšetdators"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index b2456d3..b9fabe6 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Дозволи вчитување GPU-слоеви за отстранув. грешки"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Опширна евиденција на продавачи"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Вклучува дополнителна евиденција на продавачи во извештаите за грешки за конкретен уред, којашто може да содржи приватни податоци, повеќе да ја користи батеријата и/или да користи повеќе капацитет."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Брзина на анимации за прозорци"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Брзина на преодни анимации"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Брзина на општи анимации"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Овозможи прозорци со слободна форма"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Овозможи поддршка за експериментални прозорци со слободна форма."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Овозможи прозорци со менлива големина (застарено)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Овозможете поддршка за експериментални застарени прозорци со менлива големина."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Лозинка за бекап на компјутер"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Целосниот бекап на компјутерот во моментов не е заштитен"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Допрете за да се промени или отстрани лозинката за целосен бекап на компјутерот"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Аларми и потсетници"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Дозволете ѝ на апликацијава да поставува аларми и да закажува дејства со временски рокови. Ова овозможува апликацијата да работи во заднина и така може повеќе да ја троши батеријата.\n\nАко дозволава е исклучена, нема да функционираат постојните аларми и настаните според време закажани од апликацијава."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"закажување, аларм, потсетник, часовник"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Не вознемирувај"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Вклучи"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Исклучување на „Не вознемирувај“"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Никогаш"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Времетраење"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Прашувај секогаш"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Додека не го исклучите"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Без име)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Пред малку"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Овој телефон"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Овој таблет"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 9cf6268..331b0a8 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ഡീബഗ് ആപ്പുകൾക്കായി GPU ഡീബഗ് ലെയറുകൾ ലോഡ് ചെയ്യാൻ അനുവദിക്കുക"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"വെർബോസ് വെണ്ടർ ലോഗ് ചെയ്യൽ പ്രവർത്തനക്ഷമമാക്കൂ"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ബഗ് റിപ്പോർട്ടുകളിൽ ഉപകരണ-നിർദ്ദിഷ്ട വെണ്ടർ അധിക ലോഗുകൾ ഉൾപ്പെടുത്തുക, അതിൽ സ്വകാര്യ വിവരങ്ങൾ അടങ്ങിയിരിക്കാം, കൂടുതൽ ബാറ്ററി ഉപയോഗിക്കാം കൂടാതെ/അല്ലെങ്കിൽ കൂടുതൽ സ്‌റ്റോറേജ് ഇടം ഉപയോഗിക്കാം."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"വിൻഡോ ആനിമേഷൻ സ്‌കെയിൽ"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ട്രാൻസിഷൻ ആനിമേഷൻ സ്‌കെയിൽ"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"ആനിമേറ്റർ ദൈർഘ്യ സ്‌കെയിൽ"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"ഫ്രീഫോം വിൻഡോകൾ പ്രവർത്തനക്ഷമമാക്കുക"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"പരീക്ഷണാത്മക ഫ്രീഫോം വിൻഡോകൾക്കുള്ള പിന്തുണ പ്രവർത്തനക്ഷമമാക്കുക."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"ഫ്രീഫോം വിൻഡോകൾ പ്രവർത്തനക്ഷമമാക്കുക (ലെഗസി)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"പരീക്ഷണാത്മക ലെഗസി ഫ്രീഫോം വിൻഡോകൾക്കുള്ള പിന്തുണ പ്രവർത്തനക്ഷമമാക്കുക."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"ഡെ‌സ്‌ക്ടോപ്പ് ബാക്കപ്പ് പാസ്‌വേഡ്"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ഡെസ്‌ക്‌ടോപ്പ് പൂർണ്ണ ബാക്കപ്പുകൾ നിലവിൽ പരിരക്ഷിച്ചിട്ടില്ല"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ഡെസ്‌ക്‌ടോപ്പ് പൂർണ്ണ ബാക്കപ്പുകൾക്കായി പാസ്‌വേഡുകൾ മാറ്റാനോ നീക്കംചെയ്യാനോ ടാപ്പുചെയ്യുക"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"അലാറങ്ങളും റിമെെൻഡറുകളും"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"അലാറങ്ങൾ സജ്ജീകരിക്കാനും സമയപ്രാധാന്യമുള്ള പ്രവർത്തനങ്ങൾ ഷെഡ്യൂൾ ചെയ്യാനും ഈ ആപ്പിനെ അനുവദിക്കുക. പശ്ചാത്തലത്തിൽ റൺ ചെയ്യാൻ ഇത് ഈ ആപ്പിന് അനുവാദം നൽകുന്നു, ഇതിന് കൂടുതൽ ബാറ്ററി ഉപയോഗിച്ചേക്കാം.\n\nഈ അനുമതി ഓഫാണെങ്കിൽ, ഈ ആപ്പ് നിലവിൽ ഷെഡ്യൂൾ ചെയ്‌ത അലാറങ്ങളും സമയാധിഷ്‌ഠിത ഇവന്റുകളും പ്രവർത്തിക്കില്ല."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ഷെഡ്യൂൾ, അലാറം, റിമെെൻഡർ, ക്ലോക്ക്"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"ശല്യപ്പെടുത്തരുത്"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ഓണാക്കുക"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'ശല്യപ്പെടുത്തരുത്\' ഓണാക്കുക"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ഒരിക്കലും വേണ്ട"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"ദൈർഘ്യം"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"എപ്പോഴും ചോദിക്കുക"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"നിങ്ങൾ ഓഫാക്കുന്നത് വരെ"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(പേരില്ല)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"ഇപ്പോൾ"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"ഈ ഫോൺ"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ഈ ടാബ്‌ലെറ്റ്"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 436326e..3c0a5d85 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Дебаг хийх аппад GPU дебаг хийх давхарга ачаалахыг зөвшөөрөх"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Нийлүүлэгчийн дэлгэрэнгүй логийг идэвхжүүлэх"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Төхөөрөмжийн тодорхойлсон нийлүүлэгчийн нэвтрэх үеийн алдааны нэмэлт мэдээг оруулах бөгөөд энэ нь хувийн мэдээлэл агуулж, батарейг илүү ашиглах болон/эсвэл хадгалах сан илүү ашиглаж болзошгүй."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Цонхны анимацийн масштаб"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Шилжилтийн анимацийн масштаб"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Анимацийн хугацааны масштаб"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Чөлөөт хэлбэрийн цонхыг идэвхжүүлэх"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Туршилтын чөлөөт хэлбэрийн цонхны дэмжлэгийг идэвхжүүлнэ үү."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Чөлөөт хэлбэрийн цонхыг идэвхжүүлэх (уламжлалт)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Туршилтын чөлөөт хэлбэрийн уламжлалт цонхны дэмжлэгийг идэвхжүүлнэ үү."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Компьютерын нөөцлөлтийн нууц үг"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Компьютерын бүрэн нөөцлөлт одоогоор хамгаалалтгүй байна"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Компьютерийн бүтэн нөөцлөлтийн нууц үгийг өөрчлөх, устгах бол дарна уу"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Сэрүүлэг, сануулагч"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Энэ аппад сэрүүлэг тавих болон хугацаанд мэдрэг үйлдлийн хуваарь гаргахыг зөвшөөрнө үү. Энэ нь аппад ард ажиллахыг зөвшөөрөх бөгөөд ингэснээр илүү их батарей ашиглаж магадгүй.\n\nХэрэв энэ зөвшөөрөл унтраалттай бол энэ аппын аль хэдийн тавьсан сэрүүлэг болон хуваарь гаргасан хугацаанд мэдрэг үйл явдал ажиллахгүй."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"хуваарь, сэрүүлэг, сануулагч, цаг"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Бүү саад бол"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Асаах"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Бүү саад бол горимыг асаах"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Хэзээ ч үгүй"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Хугацаа"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Тухай бүрд асуух"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Таныг унтраах хүртэл"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Нэр байхгүй)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Дөнгөж сая"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Энэ утас"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Энэ таблет"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index b68fc71..93613f9 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"डीबग अ‍ॅप्ससाठी GPU डीबग स्तर लोड करण्याची अनुमती द्या"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"व्हर्बोझ विक्रेता लॉगिंग सुरू करा"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"बग रिपोर्टमध्ये अतिरिक्त डिव्हाइस-विशिष्ट विक्रेता लॉगचा समावेश करा ज्यामध्ये खाजगी माहिती असू शकते, अधिक बॅटरी आणि/किंवा अधिक स्टोरेज वापरले जाईल."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"विंडो ॲनिमेशन स्केल"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ट्रांझिशन ॲनिमेशन स्केल"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"ॲनिमेटर कालावधी स्केल"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"freeform windows सुरू करा"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"प्रायोगिक freeform windows साठी सपोर्ट सुरू करा."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"फ्रीफॉर्म विंडो सुरू करा (लेगसी)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"प्रायोगिक लेगसी फ्रीफॉर्म विंडोसाठी सपोर्ट सुरू करा."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"डेस्कटॉप बॅकअप पासवर्ड"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"डेस्कटॉप पूर्ण बॅक अप सध्या संरक्षित नाहीत"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"डेस्कटॉपच्या पूर्ण बॅकअपसाठी असलेला पासवर्ड बदलण्यासाठी किंवा काढण्यासाठी टॅप  करा"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"अलार्म आणि रिमाइंडर"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"या ॲपला अलार्म सेट करण्याची किंवा वेळेनुसार संवेदनशील असलेल्या कृती शेड्युल करण्याची अनुमती द्या. हे ॲपला बॅकग्राउंडमध्ये रन होऊ देते, ज्यामुळे जास्त बॅटरी वापरली जाऊ शकते.\n\nही परवानगी बंद असल्यास, सध्याचे अलार्म आणि या ॲपद्वारे शेड्युल केलेले वेळेवर आधारित इव्हेंट काम करणार नाहीत."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"शेड्युल, अलार्म, रिमाइंडर, घड्याळ"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"व्यत्यय आणू नका"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"सुरू करा"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"व्यत्यय आणू नका सुरू करा"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"कधीही नाही"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"कालावधी"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"प्रत्येक वेळी विचारा"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"तुम्ही बंद करेपर्यंत"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(नाव नाही)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"आत्ताच"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"हा फोन"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"हा टॅबलेट"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 50f0c2e..1a93025 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -236,7 +236,7 @@
   </string-array>
     <string name="choose_profile" msgid="343803890897657450">"Pilih profil"</string>
     <string name="category_personal" msgid="6236798763159385225">"Peribadi"</string>
-    <string name="category_work" msgid="4014193632325996115">"Tempat Kerja"</string>
+    <string name="category_work" msgid="4014193632325996115">"Kerja"</string>
     <string name="category_private" msgid="4244892185452788977">"Persendirian"</string>
     <string name="category_clone" msgid="1554511758987195974">"Klon"</string>
     <string name="development_settings_title" msgid="140296922921597393">"Pilihan pembangun"</string>
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Benarkan pemuatan lapisan nyahpepijat GPU untuk apl penyahpepijatan"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Dayakan pengelogan vendor berjela"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Sertakan log tambahan vendor khusus peranti dalam laporan pepijat, yang mungkin mengandungi maklumat peribadi, menggunakan lebih banyak kuasa bateri dan/atau menggunakan lebih banyak storan."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Skala animasi tetingkap"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala animasi peralihan"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Skala tempoh juruanimasi"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Menjadikan sebarang apl layak ditulis ke storan luaran, tanpa mengambil kira nilai manifes"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Paksa aktiviti supaya boleh diubah saiz"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Bolehkan semua saiz aktiviti diubah untuk berbilang tetingkap, tanpa mengambil kira nilai manifes."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Dayakan tetingkap bentuk bebas"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Dayakan sokongan untuk tetingkap bentuk bebas percubaan."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Dayakan tetingkap bentuk bebas (lama)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Dayakan sokongan untuk tetingkap bentuk bebas lama yang bersifat percubaan."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Kata laluan sandaran desktop"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Sandaran penuh desktop tidak dilindungi pada masa ini"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Ketik untuk menukar atau mengalih keluar kata laluan untuk sandaran penuh desktop"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Penggera &amp; peringatan"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Benarkan apl ini menetapkan penggera dan menjadualkan tindakan yang sensitif masa. Hal ini membolehkan apl berjalan di latar, yang mungkin menggunakan lebih banyak bateri.\n\nJika kebenaran ini dimatikan, penggera sedia ada dan acara berdasarkan masa yang dijadualkan oleh apl ini tidak akan berfungsi."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"jadual, penggera, peringatan, jam"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Jangan Ganggu"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Hidupkan"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Hidupkan Jangan Ganggu"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Jangan sekali-kali"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Tempoh"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Tanya setiap kali"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Sehingga anda matikan"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Tiada nama)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Sebentar tadi"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Telefon ini"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Tablet ini"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index aa21f3c..548358f 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"အမှားရှာအက်ပ်များအတွက် GPU အမှားရှာအလွှာများ ဖွင့်ခွင့်ပြုသည်"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"အကျယ်ရှင်းလင်းချက်ပံ့ပိုးသူ မှတ်တမ်းဖွင့်ရန်"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ချွတ်ယွင်းမှု အစီရင်ခံချက်တွင် စက်ပစ္စည်းအလိုက် ထုတ်လုပ်သူမှတ်တမ်းများကို ထည့်သွင်းခြင်းဖြင့် ကိုယ်ရေးကိုယ်တာ အချက်အလက်များ ပါဝင်ခြင်း၊ ဘက်ထရီပိုသုံးခြင်း နှင့်/သို့မဟုတ် သိုလှောင်ခန်းပိုသုံးခြင်းတို့ ဖြစ်စေနိုင်သည်။"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"လှုပ်ရှားသက်ဝင်ပုံစကေး"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"သက်ဝင်အသွင်ပြောင်းခြင်း"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"လှုပ်ရှားမှုကြာချိန်စကေး"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"ပုံစံမျိုးစုံ ဝင်းဒိုးများ ဖွင့်ရန်"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ပုံစံမျိုးစုံဝင်းဒိုးများ စမ်းသပ်ခြင်းအတွက် ပံ့ပိုးမှုကို ဖွင့်သည်"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"အလွတ်ပုံစံ ဝင်းဒိုးများ ဖွင့်ပါ (အဟောင်း)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"အလွတ်ပုံစံဝင်းဒိုးအဟောင်းများ စမ်းသပ်ရန် ပံ့ပိုးမှုရယူပါ။"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"ဒက်စ်တော့ အရန်စကားဝှက်"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ဒက်စ်တော့ တစ်ခုလုံး အရန်သိမ်းဆည်းခြင်းကို လက်ရှိတွင် ကာကွယ်မထားပါ"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ဒက်စ်တော့ အပြည့်အဝ အရန်သိမ်းခြင်းအတွက် စကားဝှက်ကို ပြောင်းရန် သို့မဟုတ် ဖယ်ရှားရန် တို့ပါ။"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"နှိုးစက်နှင့် သတိပေးချက်များ"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"နှိုးစက်သတ်မှတ်ရန်နှင့် အချိန်တိကျရန် လိုအပ်သည့် လုပ်ဆောင်ချက်များအတွက် အစီအစဉ်ဆွဲရန် ဤအက်ပ်ကို ခွင့်ပြုသည်။ ၎င်းက အက်ပ်ကို နောက်ခံတွင် လုပ်ဆောင်ခွင့်ပေးပြီး ဘက်ထရီပိုသုံးနိုင်သည်။\n\nဤခွင့်ပြုချက်ကို ပိတ်ထားပါက ဤအက်ပ်ဖြင့် အစီအစဉ်ဆွဲထားသော လက်ရှိနှိုးစက်နှင့် အချိန်သတ်မှတ်ထားသည့် အစီအစဉ်များ အလုပ်လုပ်တော့မည် မဟုတ်ပါ။"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"အချိန်ဇယား၊ နှိုးစက်၊ သတိပေးချက်၊ နာရီ"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"မနှောင့်ယှက်ရ"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ဖွင့်ရန်"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'မနှောင့်ယှက်ရ\' ဖွင့်ခြင်း"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ဘယ်တော့မှ"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"ကြာချိန်"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"အမြဲမေးရန်"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"သင်ပိတ်လိုက်သည် အထိ"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(အမည်မရှိ)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"ယခုလေးတင်"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"ဤဖုန်း"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ဤတက်ဘလက်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 1a672c39..691dd3b 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Tillat GPU-feilsøkingslag for feilsøkingsapper"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Detaljert leverandørlogging"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Inkluder flere enhetsspesifikke leverandørlogger i feilrapporter, som kan inneholde privat informasjon, bruke mer batteri og/eller bruke mer lagringsplass."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Animasjonsskala for vindu"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Animasjonsskala for overgang"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Varighetsskala for animasjoner"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Dette gjør at alle apper kan lagres på eksterne lagringsmedier – uavhengig av manifestverdier"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Alle aktiviteter kan endre størrelse"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Gjør at alle aktiviteter kan endre størrelse for flervindusmodus, uavhengig av manifestverdier."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Slå på vinduer i fritt format"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Slå på støtte for vinduer i eksperimentelt fritt format."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Slå på vinduer i fritt format (eldre versjon)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Slå på støtte for eldre versjon av vinduer i eksperimentelt fritt format."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Passord for sikkerhetskopiering på datamaskin"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Fullstendig sikkerhetskopiering på datamaskin er ikke beskyttet"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Trykk for å endre eller fjerne passordet for fullstendige sikkerhetskopier på datamaskinen"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmer og påminnelser"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Gi denne appen tillatelse til å angi alarmer og planlegge tidssensitive handlinger. Dette gir appen tillatelse til å kjøre i bakgrunnen, noe som kan bruke mer batteri.\n\nHvis denne tillatelsen er av, fungerer ikke eksisterende alarmer og tidsbaserte hendelser som er planlagt av denne appen."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"tidsplan, alarm, påminnelse, klokke"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ikke forstyrr"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Slå på"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Slå på Ikke forstyrr"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Aldri"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Varighet"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Spør hver gang"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Til du slår av"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Uten navn)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Nå nettopp"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Denne telefonen"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Dette nettbrettet"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 1e33f88..0607194 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -136,7 +136,7 @@
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD अडियो"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="2607867572569689732">"हियरिङ डिभाइसहरू"</string>
     <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE अडियो"</string>
-    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="5757754050938807276">"श्रवण यन्त्रहरूमा जडान गरियो"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="5757754050938807276">"हियरिङ डिभाइसमा कनेक्ट गरियो"</string>
     <string name="bluetooth_le_audio_profile_summary_connected" msgid="6916226974453480650">"LE अडियोमा कनेक्ट गरिएको छ"</string>
     <string name="bluetooth_a2dp_profile_summary_connected" msgid="7422607970115444153">"मिडिया अडियोसँग जडित"</string>
     <string name="bluetooth_headset_profile_summary_connected" msgid="2420981566026949688">"फोन अडियोमा जडान गरियो"</string>
@@ -154,7 +154,7 @@
     <string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"फोन अडियोको लागि प्रयोग गर्नुहोस्"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"फाइल ट्रान्सफरका लागि प्रयोग गर्नुहोस्"</string>
     <string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"इनपुटको लागि प्रयोग गर्नुहोस्"</string>
-    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="3374057355721486932">"श्रवण यन्त्रहरूका लागि प्रयोग गर्नुहोस्"</string>
+    <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="3374057355721486932">"हियरिङ डिभाइसका लागि प्रयोग गर्नुहोस्"</string>
     <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>
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"डिबग एपका लागि GPU का डिबग लेयर लोड गर्नुहोस्"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"भर्बोज भेन्डर लगिङ अन गर्नुहोस्"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"बग रिपोर्टहरूमा डिभाइस विशेषका विक्रेताका अतिरिक्त लगहरू समावेश गर्नुहोस्। यी लगमा निजी जानकारी समावेश हुन सक्छन्, यिनले ब्याट्रीको खपत बढाउन र/वा थप भण्डारण प्रयोग गर्न सक्छन्।"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"विन्डो एनिमेसन स्केल"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"संक्रमण एनिमेसन स्केल"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"एनिमेसनको अवधि मापन"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"फ्रिफर्म विन्डोहरू अन गर्नुहोस्"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"प्रयोगात्मक फ्रिफर्म विन्डोहरू चल्ने बनाउनुहोस्"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"फ्रिफर्म विन्डोहरू अन गर्नुहोस् (लिगेसी)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"प्रयोगात्मक लिगेसी फ्रिफर्म विन्डोहरू चल्ने बनाउनुहोस्"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"डेस्कटप ब्याकअप पासवर्ड"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"हाल डेस्कटपका सबै ब्याकअप पासवर्ड सुरक्षित छैनन्"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"डेस्कटप पूर्ण ब्याकअपको लागि पासवर्ड बदल्न वा हटाउन ट्याप गर्नुहोस्"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"अलार्म तथा रिमाइन्डर"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"यो एपलाई अलार्म सेट गर्ने र समयमै पूरा गर्नु पर्ने कारबाहीहरूको रुटिन बनाउने अनुमति दिनुहोस्। यो अनुमति दिइएको छ भने यो एप ब्याकग्राउन्डमा चल्छ र धेरै ब्याट्री खपत हुन्छ।\n\nयो अनुमति दिइएको छैन भने सेट गरिएका अलार्म बज्दैनन् र यो एपले तय गरेका गतिविधि चल्दैनन्।"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"समयतालिका, अलार्म, रिमाइन्डर, घडी"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"बाधा नपुऱ्याउनुहोस्"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"अन गर्नुहोस्"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"बाधा नपुऱ्याउनुहोस् नामक मोडलाई अन गर्नुहोस्"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"कहिल्यै होइन"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"अवधि"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"प्रत्येक पटक सोध्नुहोस्"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"तपाईंले अफ नगरेसम्म"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(कुनै नाम छैन)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"अहिले भर्खरै"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"यो फोन"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"यो ट्याब्लेट"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 226f592..c7047a6 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Sta laden van GPU-foutopsporingslagen toe voor foutopsporingsapps"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Uitgebreide leverancierslogboeken aanzetten"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Neem aanvullende apparaatspecifieke leverancierslogboeken op in bugrapporten. Deze kunnen privégegevens bevatten, meer batterijlading gebruiken en/of meer opslagruimte gebruiken"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Venster­animatieschaal"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Overgangs­animatieschaal"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Duur van animatieschaal"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Hiermee komt elke app in aanmerking voor schrijven naar externe opslag, ongeacht de manifestwaarden"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Formaat activiteiten geforceerd aanpasbaar maken"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Maak het formaat van alle activiteiten aanpasbaar, ongeacht de manifestwaarden"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Vensters met vrije vorm aanzetten"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Zet ondersteuning voor vensters met experimentele vrije vorm aan"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Vensters met vrije vorm aanzetten (verouderd)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Zet ondersteuning voor verouderde vensters met experimentele vrije vorm aan."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Wachtwoord desktopback-up"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Volledige back-ups naar desktops zijn momenteel niet beveiligd"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tik om het wachtwoord voor volledige back-ups naar desktops te wijzigen of te verwijderen"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Wekkers en herinneringen"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Sta toe dat deze app wekkers zet en tijdgevoelige acties plant. De app kan hierdoor op de achtergrond worden uitgevoerd, waardoor je misschien meer batterijlading verbruikt.\n\nAls dit recht uitstaat, werken door deze app geplande bestaande wekkers en tijdgebaseerde afspraken niet."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"plannen, schema, wekker, alarm, herinnering, klok"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Niet storen"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aanzetten"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Zet Niet storen aan."</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nooit"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duur"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Altijd vragen"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Totdat je uitzet"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Geen naam)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Zojuist"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Deze telefoon"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Deze tablet"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 562a558..54ad13e 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -125,7 +125,7 @@
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"ମିଡିଆ ଅଡିଓ"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"ଫୋନ କଲ"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ଫାଇଲ୍‌ ଟ୍ରାନ୍ସଫର୍‌"</string>
-    <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ଇନ୍‌ପୁଟ୍‌ ଡିଭାଇସ୍"</string>
+    <string name="bluetooth_profile_hid" msgid="2969922922664315866">"ଇନପୁଟ ଡିଭାଇସ"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"ଇଣ୍ଟରନେଟ ଆକ୍ସେସ"</string>
     <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"କଣ୍ଟାକ୍ଟ ଓ କଲ ଇତିହାସକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"ସୂଚନାକୁ କଲ ଘୋଷଣା ଏବଂ ଆହୁରି ଅଧିକ ପାଇଁ ବ୍ୟବହାର କରାଯିବ"</string>
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ଡିବଗ୍‌ ଆପ୍‌ଗୁଡ଼ିକ ପାଇଁ GPU ଡିବଗ୍‌ ଲେୟର୍‌ ଲୋଡ୍ କରିବାର ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ଭର୍ବୋସ ଭେଣ୍ଡର୍ ଲଗିଂ ସକ୍ଷମ କରନ୍ତୁ"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ବଗ୍ ରିପୋର୍ଟଗୁଡ଼ିକରେ ଅତିରିକ୍ତ ଡିଭାଇସ୍-ନିର୍ଦ୍ଦିଷ୍ଟ ଲଗଗୁଡ଼ିକ ସାମିଲ କରନ୍ତୁ, ଯେଉଁଥିରେ ବ୍ୟକ୍ତିଗତ ସୂଚନା ଥାଇପାରେ, ଯାହା ଅଧିକ ବ୍ୟାଟେରୀ ଏବଂ/କିମ୍ବା ଅଧିକ ଷ୍ଟୋରେଜ୍ ବ୍ୟବହାର କରିପାରେ।"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"ୱିଣ୍ଡୋ ଆନିମେସନ୍‌ ସ୍କେଲ୍‌"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ଟ୍ରାଞ୍ଜିସନ୍‌ ଆନିମେସନ୍‌ ସ୍କେଲ୍‌"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"ଆନିମେଟର୍‌ ଅବଧି ସ୍କେଲ୍‌"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"ଫ୍ରିଫର୍ମ ୱିଣ୍ଡୋକୁ ସକ୍ଷମ କରନ୍ତୁ"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ପରୀକ୍ଷାମୂଳକ ଫ୍ରିଫର୍ମ ୱିଣ୍ଡୋଗୁଡ଼ିକ ପାଇଁ ସପୋର୍ଟକୁ ସକ୍ଷମ କରନ୍ତୁ।"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"ଫ୍ରିଫର୍ମ ୱିଣ୍ଡୋ ସକ୍ଷମ କରନ୍ତୁ (ଲିଗାସି)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"ପରୀକ୍ଷାମୂଳକ ଲିଗାସି ଫ୍ରିଫର୍ମ ୱିଣ୍ଡୋ ପାଇଁ ସପୋର୍ଟ ସକ୍ଷମ କରନ୍ତୁ।"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"ଡେସ୍କଟପ ବେକଅପ ପାସୱାର୍ଡ"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ଡେସ୍କଟପ୍‌ର ସମ୍ପୂର୍ଣ୍ଣ ବ୍ୟାକଅପ୍‌ଗୁଡ଼ିକ ବର୍ତ୍ତମାନ ସୁରକ୍ଷିତ ନୁହେଁ"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ଡେସ୍କଟପ୍‌ର ସମ୍ପୂର୍ଣ୍ଣ ବ୍ୟାକ୍‌ଅପ୍‌ ପାଇଁ ପାସ୍‌ୱର୍ଡ ବଦଳାଇବା କିମ୍ୱା କାଢ଼ିଦେବା ନିମନ୍ତେ ଟାପ୍‌ କରନ୍ତୁ"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"ଆଲାରାମ୍ ଏବଂ ରିମାଇଣ୍ଡରଗୁଡ଼ିକ"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ଏହି ଆପକୁ ଆଲାରାମ୍ ସେଟ୍ କରିବାକୁ ଏବଂ ସମୟ-ସମ୍ବେଦନଶୀଳ କାର୍ଯ୍ୟଗୁଡ଼ିକୁ ସିଡୁଲ୍ କରିବାକୁ ଅନୁମତି ଦିଅନ୍ତୁ। ଏହା ଆପକୁ ପୃଷ୍ଠପଟରେ ଚାଲିବାକୁ ଦେଇଥାଏ, ଯାହା ଅଧିକ ବ୍ୟାଟେରୀ ବ୍ୟବହାର କରିପାରେ।\n\nଯଦି ଏହି ଅନୁମତି ବନ୍ଦ ଅଛି, ତେବେ ଏହି ଆପ୍ ଦ୍ୱାରା ସିଡୁଲ୍ କରାଯାଇଥିବା ପୂର୍ବରୁ ଥିବା ଆଲାରାମ୍ ଏବଂ ସମୟ-ଆଧାରିତ ଇଭେଣ୍ଟଗୁଡ଼ିକ କାମ କରିବ ନାହିଁ।"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ସିଡୁଲ୍, ଆଲାରାମ୍, ରିମାଇଣ୍ଡର୍, ଘଣ୍ଟା"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ଚାଲୁ କରନ୍ତୁ"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅନ୍ କରନ୍ତୁ"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"କଦାପି ନୁହେଁ"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"ଅବଧି"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ପ୍ରତ୍ୟେକ ଥର ପଚାରନ୍ତୁ"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"ଆପଣ ବନ୍ଦ ନକରିବା ପର୍ଯ୍ୟନ୍ତ"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(କୌଣସି ନାମ ନାହିଁ)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"ଏହିକ୍ଷଣି"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"ଏହି ଫୋନ"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ଏହି ଟାବଲେଟ"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index f80ec8d..80d9081 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -316,7 +316,7 @@
     <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"ਬਲੂਟੁੱਥ ਆਡੀਓ LDAC ਕੋਡੇਕ: ਪਲੇਬੈਕ ਕੁਆਲਿਟੀ"</string>
     <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"ਬਲੂਟੁੱਥ ਆਡੀਓ LDAC\nਕੋਡੇਕ ਚੋਣ ਨੂੰ ਟ੍ਰਿਗਰ ਕਰੋ: ਪਲੇਬੈਕ ਕੁਆਲਿਟੀ"</string>
     <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"ਸਟ੍ਰੀਮਿੰਗ: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
-    <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"ਨਿੱਜੀ DNS"</string>
+    <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>
@@ -407,7 +407,19 @@
     <string name="enable_gpu_debug_layers" msgid="4986675516188740397">"GPU ਡੀਬੱਗ ਤਹਿਆਂ ਚਾਲੂ ਕਰੋ"</string>
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"ਡੀਬੱਗ ਐਪਾਂ ਲਈ GPU ਡੀਬੱਗ ਤਹਿਆਂ ਨੂੰ ਲੋਡ ਹੋਣ ਦਿਓ"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"ਵਰਬੋਸ ਵਿਕਰੇਤਾ ਲੌਗਿੰਗ ਚਾਲੂ ਕਰੋ"</string>
-    <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ਬੱਗ ਰਿਪੋਰਟਾਂ ਵਿੱਚ ਵਧੀਕ ਡੀਵਾਈਸ ਨਾਲ ਸੰਬੰਧਿਤ ਵਿਕਰੇਤਾ ਲੌਗ ਸ਼ਾਮਲ ਕਰੋ, ਜਿਨ੍ਹਾਂ ਵਿੱਚ ਨਿੱਜੀ ਜਾਣਕਾਰੀ, ਬੈਟਰੀ ਦੀ ਵਧੇਰੇ ਵਰਤੋਂ, ਅਤੇ/ਜਾਂ ਵਧੇਰੀ ਸਟੋਰੇਜ ਸ਼ਾਮਲ ਹੋ ਸਕਦੀ ਹੈ।"</string>
+    <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ਬੱਗ ਰਿਪੋਰਟਾਂ ਵਿੱਚ ਵਧੀਕ ਡੀਵਾਈਸ ਮੁਤਾਬਕ ਵਿਕਰੇਤਾ ਲੌਗ ਸ਼ਾਮਲ ਕਰੋ, ਜਿਨ੍ਹਾਂ ਵਿੱਚ ਪ੍ਰਾਈਵੇਟ ਜਾਣਕਾਰੀ, ਬੈਟਰੀ ਦੀ ਵਧੇਰੇ ਵਰਤੋਂ ਅਤੇ/ਜਾਂ ਜ਼ਿਆਦਾ ਸਟੋਰੇਜ ਸ਼ਾਮਲ ਹੋ ਸਕਦੀ ਹੈ।"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"ਵਿੰਡੋ ਐਨੀਮੇਸ਼ਨ ਸਕੇਲ"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ਟ੍ਰਾਂਜ਼ਿਸ਼ਨ ਐਨੀਮੇਸ਼ਨ ਸਕੇਲ"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"ਐਨੀਮੇਟਰ ਮਿਆਦ ਸਕੇਲ"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"ਫ੍ਰੀਫਾਰਮ ਵਿੰਡੋਜ਼ ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ਪ੍ਰਯੋਗਮਈ ਫ੍ਰੀਫਾਰਮ ਵਿੰਡੋਜ਼ ਲਈ ਸਮਰਥਨ ਨੂੰ ਚਾਲੂ ਕਰੋ।"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"ਫ੍ਰੀਫਾਰਮ ਵਿੰਡੋਆਂ ਚਾਲੂ ਕਰੋ (ਵਿਰਾਸਤੀ)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"ਪ੍ਰਯੋਗਮਈ ਵਿਰਾਸਤੀ ਫ੍ਰੀਫਾਰਮ ਵਿੰਡੋਆਂ ਲਈ ਸਹਾਇਤਾ ਚਾਲੂ ਕਰੋ।"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"ਡੈਸਕਟਾਪ ਬੈਕਅੱਪ ਪਾਸਵਰਡ"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ਡੈਸਕਟਾਪ ਦੇ ਪੂਰੇ ਬੈਕਅੱਪ ਇਸ ਵੇਲੇ ਸੁਰੱਖਿਅਤ ਨਹੀਂ ਹਨ"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ਡੈਸਕਟਾਪ ਦੇ ਮੁਕੰਮਲ ਬੈਕਅੱਪਾਂ ਲਈ ਪਾਸਵਰਡ ਨੂੰ ਬਦਲਣ ਜਾਂ ਹਟਾਉਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"ਅਲਾਰਮ ਅਤੇ ਰਿਮਾਈਂਡਰ"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ਇਸ ਐਪ ਨੂੰ ਅਲਾਰਮ ਸੈੱਟ ਕਰਨ ਜਾਂ ਹੋਰ ਸਮਾਂ-ਸੰਵੇਦਨਸ਼ੀਲ ਕਾਰਵਾਈਆਂ ਨੂੰ ਨਿਯਤ ਕਰਨ ਦਿਓ। ਇਸ ਨਾਲ ਐਪ ਨੂੰ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲਣ ਦੀ ਇਜਾਜ਼ਤ ਮਿਲਦੀ ਹੈ, ਜਿਸ ਨਾਲ ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਵੱਧ ਸਕਦੀ ਹੈ।\n\nਜੇ ਇਹ ਇਜਾਜ਼ਤ ਬੰਦ ਹੈ, ਤਾਂ ਇਸ ਐਪ ਰਾਹੀਂ ਨਿਯਤ ਕੀਤੇ ਮੌਜੂਦਾ ਅਲਾਰਮ ਅਤੇ ਸਮਾਂ-ਆਧਾਰਿਤ ਇਵੈਂਟ ਕੰਮ ਨਹੀਂ ਕਰਨਗੇ।"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ਸਮਾਂ-ਸੂਚੀ, ਅਲਾਰਮ, ਰਿਮਾਈਂਡਰ, ਘੜੀ"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ਚਾਲੂ ਕਰੋ"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ਕਦੇ ਵੀ ਨਹੀਂ"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"ਮਿਆਦ"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ਹਰ ਵਾਰ ਪੁੱਛੋ"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਬੰਦ ਨਹੀਂ ਕਰਦੇ"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(ਕੋਈ ਨਾਮ ਨਹੀਂ)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"ਹੁਣੇ ਹੀ"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"ਇਹ ਫ਼ੋਨ"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ਇਹ ਟੈਬਲੈੱਟ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 8babb8b..e816e9d 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Zezwalaj na ładowanie warstw debugowania GPU"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Włącz szczegółowe rejestrowanie dostawcy"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Dołączaj do raportów o błędach dodatkowe dane dostawcy dotyczące konkretnego urządzenia, które mogą zawierać dane prywatne oraz wykorzystywać więcej baterii lub pamięci"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Skala animacji okna"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala animacji przejścia"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Skala długości animacji"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Pozwala na zapis aplikacji w pamięci zewnętrznej niezależnie od wartości w pliku manifestu"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Wymuś zmianę rozmiaru okien aktywności"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Zezwalaj na zmianę rozmiaru wszystkich okien aktywności w trybie wielu okien niezależnie od ustawień w pliku manifestu"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Włącz dowolny rozmiar okien"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Włącz obsługę eksperymentalnej funkcji dowolnego rozmiaru okien"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Włącz dowolny rozmiar okien (starsza wersja)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Włącz obsługę eksperymentalnej funkcji dowolnego rozmiaru okien w starszej wersji"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Hasło kopii zapasowej"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Pełne kopie zapasowe na komputerze nie są obecnie chronione"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Dotknij, by zmienić lub usunąć hasło pełnych kopii zapasowych na komputerze."</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmy i przypomnienia"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Zezwalaj tej aplikacji na ustawianie alarmów i planowanie działań, w przypadku których czas jest istotny. Aplikacja będzie mogła działać w tle, co może zwiększyć wykorzystanie baterii.\n\nJeśli nie włączysz tego uprawnienia, istniejące alarmy i zaplanowane wydarzenia z tej aplikacji nie będą działać."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"harmonogram, alarm, przypomnienie, zegar"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Nie przeszkadzać"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Włącz"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Włącz tryb Nie przeszkadzać"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nigdy"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Czas"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Zawsze pytaj"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Dopóki nie wyłączysz"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Bez nazwy)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Przed chwilą"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ten telefon"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ten tablet"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 337b011..db8aac9a 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permitir carregamento de camadas de depuração de GPU p/ apps de depuração"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Ativar registro detalhado de fornecedor"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Incluir mais registros de fornecedores específicos do dispositivo em relatórios de bugs. Isso pode aumentar o uso da bateria e/ou do armazenamento, e os relatórios podem conter informações particulares."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animação da janela"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala de animação de transição"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de duração do Animator"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Qualificar apps para gravação em armazenamento externo, independentemente dos valores do manifesto"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Forçar atividades a serem redimensionáveis"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Tornar todas as atividades redimensionáveis para várias janelas, independentemente dos valores do manifesto"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Ativar janelas de forma livre"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Ativar a compatibilidade com janelas experimentais de forma livre"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Ativar janelas de forma livre (legado)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Ativar a compatibilidade com janelas experimentais legadas de forma livre."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Senha de backup local"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Os backups completos não estão protegidos no momento"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Toque para alterar ou remover a senha de backups completos do desktop"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes e lembretes"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permitir que o app defina alarmes e programe ações com hora marcada. Essa opção autoriza o app a ser executado em segundo plano, o que pode consumir mais bateria.\n\nSe a permissão for desativada, os alarmes e eventos programados pelo app não funcionarão."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programar, alarme, lembrete, relógio"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Não perturbe"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ativar"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Ativar o Não perturbe"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nunca"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duração"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Perguntar sempre"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Até você desativar"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Sem nome)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Agora"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Este telefone"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Este tablet"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index a40b95f..3f253c7 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permite carregamento de camadas de depuração de GPU para apps de depuração"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Ativ. registo do fornecedor"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Inclua registos adicionais de fornecedores específicos de dispositivos em relatórios de erros, que podem conter informações privadas, utilizar mais bateria e/ou utilizar mais armazenamento."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animação de transição"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala de animação de transição"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de duração de animação"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Torna qualquer aplicação elegível para ser gravada no armazenamento externo, independentemente dos valores do manifesto"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Forçar as atividades a serem redimensionáveis"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Tornar todas as atividades redimensionáveis para várias janelas, independentemente dos valores do manifesto."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Ativar janelas de forma livre"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Ativar a compatibilidade com janelas de forma livre experimentais."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Ativar janelas de forma livre (antigo)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Ativar compatibilidade com janelas de forma livre antigas experimentais."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Palavra-passe cópia do computador"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"As cópias de segurança completas no ambiente de trabalho não estão atualmente protegidas"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tocar para alterar ou remover a palavra-passe para cópias de segurança completas no ambiente de trabalho"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes e lembretes"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permita que a app defina alarmes e agende ações com um horário específico. Esta ação permite que a app seja executada em segundo plano, o que pode usar mais bateria.\n\nSe esta autorização estiver desativada, os alarmes existentes e os eventos com base no tempo agendados por esta app não funcionam."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"agendar, alarme, lembrete, relógio"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Não incomodar"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ativar"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Ativar o modo Não incomodar"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nunca"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duração"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Perguntar sempre"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Até desativar"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Sem nome)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Agora mesmo"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Este telemóvel"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Este tablet"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 337b011..db8aac9a 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permitir carregamento de camadas de depuração de GPU p/ apps de depuração"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Ativar registro detalhado de fornecedor"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Incluir mais registros de fornecedores específicos do dispositivo em relatórios de bugs. Isso pode aumentar o uso da bateria e/ou do armazenamento, e os relatórios podem conter informações particulares."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Escala de animação da janela"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Escala de animação de transição"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Escala de duração do Animator"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Qualificar apps para gravação em armazenamento externo, independentemente dos valores do manifesto"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Forçar atividades a serem redimensionáveis"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Tornar todas as atividades redimensionáveis para várias janelas, independentemente dos valores do manifesto"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Ativar janelas de forma livre"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Ativar a compatibilidade com janelas experimentais de forma livre"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Ativar janelas de forma livre (legado)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Ativar a compatibilidade com janelas experimentais legadas de forma livre."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Senha de backup local"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Os backups completos não estão protegidos no momento"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Toque para alterar ou remover a senha de backups completos do desktop"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmes e lembretes"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permitir que o app defina alarmes e programe ações com hora marcada. Essa opção autoriza o app a ser executado em segundo plano, o que pode consumir mais bateria.\n\nSe a permissão for desativada, os alarmes e eventos programados pelo app não funcionarão."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programar, alarme, lembrete, relógio"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Não perturbe"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ativar"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Ativar o Não perturbe"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nunca"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Duração"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Perguntar sempre"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Até você desativar"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Sem nome)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Agora"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Este telefone"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Este tablet"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 4bddeb9a..726e264 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Permite încărcarea nivelurilor de depanare GPU pentru aplicațiile de depanare"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Activează înregistrarea detaliată a furnizorilor"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Include alte jurnale ale furnizorilor de dispozitive în rapoartele de eroare, care pot conține informații private, folosește mai multă baterie și/sau mai mult spațiu de stocare."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Scară animație fereastră"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Scară tranziție animații"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Scară durată Animator"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Permite scrierea oricărei aplicații eligibile în stocarea externă, indiferent de valorile manifestului"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Forțează redimensionarea activităților"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Permite redimensionarea tuturor activităților pentru modul cu ferestre multiple, indiferent de valorile manifestului."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Activează ferestrele cu formă liberă"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Activează compatibilitatea pentru ferestrele experimentale cu formă liberă."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Activează ferestrele cu formă liberă (vechi)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Activează compatibilitatea pentru ferestrele experimentale vechi cu formă liberă."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Parolă backup computer"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"În prezent, backupurile complete pe computer nu sunt protejate"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Atinge ca să modifici sau să elimini parola pentru backupurile complete pe desktop"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarme și mementouri"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permite acestei aplicații să seteze alarme și să planifice acțiuni care trebuie realizate în timp scurt. Astfel, aplicația poate să ruleze în fundal, ceea ce ar putea crește consumul de baterie.\n\nDacă permisiunea este dezactivată, alarmele și evenimentele dependente de timp planificate de aplicație nu vor funcționa."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programare, alarmă, memento, ceas"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Nu deranja"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activează"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activează Nu deranja"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Niciodată"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Durată"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Întreabă de fiecare dată"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Până când dezactivezi"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Fără nume)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Chiar acum"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Acest telefon"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Această tabletă"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index f30a125..f412fed 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Включить загрузку слоев отладки графического процессора"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Подробный журнал поставщика"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Включать в информацию об ошибках дополнительные записи поставщика об устройстве, которые могут содержать личные данные и занимать больше места. Также это может увеличить расход заряда батареи."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Анимация окон"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Анимация переходов"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Длительность анимации"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Разрешить создание окон произвольной формы"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Включить экспериментальную функцию создания окон произвольной формы"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Разрешить окна произвольной формы (устаревшее)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Включить устаревшую экспериментальную функцию для создания окон произвольной формы"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Пароль для резервного копирования"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Полные локальные резервные копии в настоящее время не защищены"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Нажмите, чтобы изменить или удалить пароль для резервного копирования"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Будильники и напоминания"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Вы можете разрешить этому приложению устанавливать будильники и планировать запуск действий в определенное время. В этом случае оно будет работать в фоновом режиме и быстрее расходовать заряд батареи.\n\nЕсли отключить это разрешение, текущие будильники и созданные приложением события перестанут запускаться."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"установить, будильник, напоминание, часы"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Не беспокоить"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Включить"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Включите режим \"Не беспокоить\""</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Никогда"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Длительность"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Всегда спрашивать"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Пока вы не отключите"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"Имя не указано"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Только что"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Этот смартфон"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Этот планшет"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 9f1aca6..9e28d7ca 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"නිදොසීමේ යෙදුම්වලට GPU නිදොසීමේ ස්තර පූරණයට ඉඩ දෙ."</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"verbose vendor පිරීම සබල කරන්න"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"පුද්ගලික තොරතුරු අන්තර්ගත විය හැකි, වැඩි බැටරි බලයක් භාවිත කිරීමට සහ/හෝ වැඩි ගබඩා ඉඩක් භාවිත කිරීමට හැකි අමතර උපාංග නිශ්චිත විකුණුම්කරු ලොග, දෝෂ වාර්තාවල අඩංගු වේ."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"කවුළු සජීවිකරණ පරිමාණය"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"සංක්‍රමණ සජීවන පරිමාණය"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"සජීවක කාල පරාස පරිමාණය"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"අනියම් හැඩැති කවුළු සබල කරන්න"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"පරීක්ෂණාත්මක අනියම් හැඩැති කවුළු සඳහා සහාය සබල කරන්න."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"නිදහස් ආකෘති කවුළු සබල කරන්න (ලෙගසිය)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"පරීක්ෂණාත්මක ලෙගසි නිදහස් ආකෘති කවුළු සඳහා සහාය සබල කරන්න."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"ඩෙස්ක්ටොප් උපස්ථ මුරපදය"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ඩෙස්ක්ටොප් සම්පූර්ණ උපස්ථ දැනට ආරක්ෂා කර නොමැත"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ඩෙස්ක්ටොප් සම්පූර්ණ උපස්ථ සඳහා මුරපදය වෙනස් කිරීමට හෝ ඉවත් කිරීමට තට්ටු කරන්න"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"එලාම සහ සිහිකැඳවීම්"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"එලාම සැකසීමට සහ කාල සංවේදී ක්‍රියා කාලසටහන්ගත කිරීමට මෙම යෙදුමට ඉඩ දෙන්න. මෙය පසුබිමේ ධාවනය වීමට යෙදුමට ඉඩ දෙයි, එය වැඩි බැටරිය වැඩියෙන් භාවිත කළ හැකිය.\n\nමෙම අවසරය ක්‍රියාවිරහිත නම්, මෙම යෙදුම මඟින් සැලසුම් කර ඇති තිබෙන එලාම සහ වේලාව පදනම් කර ගත් සිදුවීම් ක්‍රියා නොකරනු ඇත."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"කාල සටහන, එලාමය, සිහිකැඳවීම, ඔරලෝසුව"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"බාධා නොකරන්න"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ක්‍රියාත්මක කරන්න"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"බාධා නොකරන්න ක්‍රියාත්මක කරන්න"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"කිසි විටක නැත"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"කාල සීමාව"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"සෑම විටම ඉල්ලන්න"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"ඔබ ක්‍රියාවිරහිත කරන තුරු"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(නමක් නොමැත)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"මේ දැන්"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"මෙම දුරකථනය"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"මෙම ටැබ්ලටය"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index db8301a..97bf279 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -261,7 +261,7 @@
     <string name="adb_paired_devices_title" msgid="5268997341526217362">"Spárované zariadenia"</string>
     <string name="adb_wireless_device_connected_summary" msgid="3039660790249148713">"Aktuálne pripojené"</string>
     <string name="adb_wireless_device_details_title" msgid="7129369670526565786">"Podrobnosti o zariadení"</string>
-    <string name="adb_device_forget" msgid="193072400783068417">"Odstrániť"</string>
+    <string name="adb_device_forget" msgid="193072400783068417">"Zabudnúť"</string>
     <string name="adb_device_fingerprint_title_format" msgid="291504822917843701">"Digitálny odtlačok zariadenia: <xliff:g id="FINGERPRINT_PARAM">%1$s</xliff:g>"</string>
     <string name="adb_wireless_connection_failed_title" msgid="664211177427438438">"Pripojenie zlyhalo"</string>
     <string name="adb_wireless_connection_failed_message" msgid="9213896700171602073">"Skontrolujte, či je zariadenie <xliff:g id="DEVICE_NAME">%1$s</xliff:g> pripojené k správnej sieti"</string>
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Povoliť načítanie vrstiev ladenia grafického procesora na ladenie aplikácií"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Aktivovať podrobný zápis dodávateľov do denníka"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Zahŕňať do hlásení chýb ďalšie denníky dodávateľa pre konkrétne zariadenie, ktoré môžu obsahovať osobné údaje, zvýšiť spotrebu batérie alebo zabrať viac ukladacieho priestoru"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Mierka animácie okna"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Mierka animácie premeny"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Mierka dĺžky animácie"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Umožniť zapísať akúkoľvek aplikáciu do externého úložiska bez ohľadu na hodnoty v manifeste"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Vynútiť možnosť zmeny veľkosti aktivít"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Umožniť zmeniť veľkosť všetkých aktivít na niekoľko okien (bez ohľadu na hodnoty manifestu)"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Povoliť okná s voľným tvarom"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Povoliť podporu pre experimentálne okná s voľným tvarom"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Povolenie meniteľných okien (starých)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Povoľte podporu pre experimentálne staré meniteľné okná."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Heslo pre zálohy v počítači"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Úplné zálohy v počítači nie sú momentálne chránené"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Klepnutím zmeníte alebo odstránite heslo pre úplné zálohy do počítača"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Budíky a pripomenutia"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Povoľte tejto aplikácii nastavovať budíky a plánovať akcie s časovým obmedzením. Aplikácii to umožní pracovať na pozadí, čo môže zvýšiť spotrebu batérie.\n\nAk je toto povolenie vypnuté, existujúce budíky a udalosti s časovým obmedzením naplánované touto aplikáciou nebudú fungovať."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"plán, budík, pripomenutie, hodiny"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Režim bez vyrušení"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Zapnúť"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Zapnite režim bez vyrušení"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikdy"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trvanie"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Vždy sa opýtať"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Dokým funkciu nevypnete"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Bez mena)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Teraz"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Tento telefón"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Tento tablet"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 5460c3b..67aeace 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Aplikacijam za odpravljanje napak dovoli nalaganje slojev za odpravljanje napak GPE."</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Omogoči podrobno beleženje za ponudnika"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Vključi dodatne dnevnike ponudnika, odvisne od posamezne naprave, v poročila o napakah. Takšno poročilo lahko vsebuje zasebne podatke, porabi več energije baterije in/ali več shrambe."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Merilo animacije okna"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Merilo animacije prehoda"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Merilo trajanja animacije"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Poskrbi, da je ne glede na vrednosti v manifestu mogoče vsako aplikacijo zapisati v zunanjo shrambo."</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Vsili spremembo velikosti za aktivnosti"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Poskrbi, da je ne glede na vrednosti v manifestu mogoče vsem aktivnostim spremeniti velikost za način z več okni."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Omogoči okna svobodne oblike"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Omogoči podporo za poskusna okna svobodne oblike."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Omogoči okna svobodne oblike (starejše)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Omogoči podporo za poskusna okna svobodne oblike starejše različice."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Geslo za varnostno kopijo namizja"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Popolne varnostne kopije namizja trenutno niso zaščitene."</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Dotaknite se, če želite spremeniti ali odstraniti geslo za popolno varnostno kopiranje namizja"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmi in opomniki"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Tej aplikaciji dovolite nastavljanje alarmov in načrtovanje časovno občutljivih dejanj. S tem aplikaciji omogočite izvajanje v ozadju, kar bo morda povečalo porabo energije baterije.\n\nČe je to dovoljenje izklopljeno, obstoječi alarmi in časovno občutljivi dogodki, ki jih nastavi ta aplikacija, ne bodo delovali."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"načrtovanje, urnik, alarm, opomnik, ura"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ne moti"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Vklopi"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Vklop načina »Ne moti«"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikoli"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Trajanje"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Vedno vprašaj"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Dokler ne izklopite"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Ni imena)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Pravkar"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ta telefon"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ta tablični računalnik"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 3db7146..4aa6a8d 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Lejo ngarkimin e shtresave të korrigjimit të GPU-së për aplikacionet e korrigjimit"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Aktivizo evidencat e tregtuesit me shumë fjalë"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Përfshi evidenca shtesë të treguesve specifike për pajisjen në raportet e defekteve, që mund të përfshijnë informacion privat, mund të përdorin më shumë bateri dhe/ose të përdorin më shumë hapësirë ruajtëse."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Animacioni i dritares"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Animacioni kalimtar"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Kohëzgjatja e animatorit"</string>
@@ -424,8 +436,10 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Bën që çdo aplikacion të jetë i përshtatshëm për t\'u shkruar në hapësirën ruajtëse të jashtme, pavarësisht nga vlerat e manifestit"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Detyro madhësinë e ndryshueshme për aktivitetet"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Bëj që të gjitha aktivitetet të kenë madhësi të ndryshueshme për përdorimin me shumë dritare, pavarësisht vlerave të manifestit."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Aktivizo dritaret me formë të lirë"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktivizo mbështetjen për dritaret eksperimentale me formë të lirë."</string>
+    <!-- no translation found for enable_freeform_support (8409932201445109106) -->
+    <skip />
+    <!-- no translation found for enable_freeform_support_summary (2242481082356957934) -->
+    <skip />
     <string name="local_backup_password_title" msgid="4631017948933578709">"Fjalëkalimi i rezervimit të desktopit"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Rezervimet e plota të desktopit nuk janë të mbrojtura aktualisht"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Trokit për të ndryshuar ose hequr fjalëkalimin për rezervime të plota të desktopit"</string>
@@ -557,6 +571,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmet dhe alarmet rikujtuese"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Lejo që ky aplikacion të caktojë alarmet dhe të planifikojë veprime që kanë një afat të caktuar. Kjo mundëson që aplikacioni të ekzekutohet në sfond, gjë që mund të përdorë më shumë bateri.\n\nNëse kjo leje është caktuar si joaktive, alarmet ekzistuese dhe ngjarjet në bazë kohore të planifikuara nga ky aplikacion nuk do të funksionojnë."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"planifiko, alarm, alarm rikujtues, ora"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Mos shqetëso"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktivizo"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktivizo \"Mos shqetëso\""</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Asnjëherë"</string>
@@ -569,6 +584,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Kohëzgjatja"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Pyet çdo herë"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Derisa ta çaktivizosh"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Pa emër)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Pikërisht tani"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ky telefon"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ky tablet"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index fa94c2e..a67c71a 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Учитава отклањање грешака GPU-a у апл. за отклањање грешака"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Опширне евиденције продавца"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Уврштава у извештаје о грешкама додатне посебне евиденције продавца за уређаје, које могу да садрже приватне податке, да троше више батерије и/или да користе више меморије."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Размера анимације прозора"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Размера анимације прелаза"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Аниматорова размера трајања"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Омогући прозоре произвољног формата"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Омогућава подршку за експерименталне прозоре произвољног формата."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Омогући прозоре произвољног формата (застарело)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Омогућава подршку за застареле експерименталне прозоре произвољног формата."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Лозинка резервне копије за рачунар"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Резервне копије читавог система тренутно нису заштићене"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Додирните да бисте променили или уклонили лозинку за прављење резервних копија читавог система на рачунару"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Аларми и подсетници"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Омогућите овој апликацији да подешава аларме и заказује временски осетљиве радње. То омогућава да апликација буде покренута у позадини, што може да троши више батерије.\n\nАко је ова дозвола искључена, постојећи аларми и догађаји засновани на времену заказани помоћу ове апликације неће радити."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"заказати, аларм, подсетник, сат"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Не узнемиравај"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Укључи"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Укључите режим Не узнемиравај"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Никад"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Трајање"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Питај сваки пут"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Док не искључите"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Без имена)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Управо"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Овај телефон"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Овај таблет"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 636d969..7add088 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Tillåt att felsökningsappar läser in GPU-felsökningslager"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Aktivera utförlig loggning för leverantörer"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Ta med ytterligare enhetsspecifika leverantörsloggar i felrapporter. Dessa kan innehålla privata uppgifter samt använda mer batteri och/eller mer lagringsutrymme."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Skala – fönsteranimering"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Skala – övergångsanimering"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Längdskala för Animator"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Allar appar kan skrivas till extern lagring, oavsett manifestvärden"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Framtvinga storleksanpassning för aktiviteter"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Gör det möjligt att ändra storleken på alla aktiviteter i flerfönsterläge, oavsett manifestvärden."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Aktivera frihandsfönster"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktivera stöd för experimentella frihandsfönster."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Aktivera frihandsfönster (äldre)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Aktivera stöd för äldre experimentella frihandsfönster."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Lösenord för säkerhetskopia av datorn"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"De fullständiga säkerhetskopiorna av datorn är för närvarande inte skyddade"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Tryck om du vill ändra eller ta bort lösenordet för fullständig säkerhetskopiering av datorn"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarm och påminnelser"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Tillåt att den här appen ställer in alarm och schemalägger tidskänsliga åtgärder. Om du tillåter detta kan appen köras i bakgrunden, vilket kan dra mer batteri.\n\nOm behörigheten är inaktiverad fungerar inte befintliga alarm och tidsbaserade händelser som schemalagts av den här appen."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schema, alarm, påminnelse, klocka"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Stör ej"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktivera"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktivera Stör ej."</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Aldrig"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Varaktighet"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Fråga varje gång"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Tills du inaktiverar funktionen"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Inget namn)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Nyss"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Den här telefonen"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Den här surfplattan"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 01b786d..818db3f 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Ruhusu upakiaji wa safu za utatuzi wa GPU za programu za utatuzi"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Washa uwekaji kumbukumbu za muuzaji kwa kutumia sauti"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Jumuisha kumbukumbu zaidi za muuzaji ambazo ni mahususi kwa kifaa kwenye ripoti za hitilafu, ambazo huenda zikawa na maelezo ya faragha, zikatumia chaji nyingi ya betri na/au zikatumia nafasi kubwa ya hifadhi."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Uhuishaji kwenye dirisha"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Mageuzi ya kipimo cha uhuishaji"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Mizani ya muda wa uhuishaji"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Huruhusu programu yoyote iwekwe kwenye hifadhi ya nje, bila kujali thamani za faili ya maelezo"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Lazimisha shughuli ziweze kubadilishwa ukubwa"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Fanya shughuli zote ziweze kubadilishwa ukubwa kwenye madirisha mengi, bila kuzingatia thamani za faili ya maelezo."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Washa madirisha yenye muundo huru"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Ruhusu uwezo wa kutumia madirisha ya majaribio yenye muundo huru."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Washa madirisha yenye muundo huru (yaliyopitwa na wakati)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Ruhusu matumizi ya madirisha ya majaribio yenye muundo huru yaliyopitwa na wakati."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Nenosiri la hifadhi rudufu ya eneo kazi"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Hifadhi rudufu kamili za eneo kazi hazijalindwa kwa sasa"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Gusa ili ubadilishe au uondoe nenosiri la hifadhi rudufu kamili za eneo kazi"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Kengele na vikumbusho"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Ruhusu programu hii iweke kengele na ratiba za vitendo vingine vinavyotegemea wakati. Hatua hii inairuhusu programu itumike chinichini, hali inayoweza kutumia chaji nyingi ya betri.\n\nIkiwa ruhusa hii itazimwa, kengele zilizopo na ratiba za vitendo vinavyotegemea wakati zilizowekwa na programu hii hazitafanya kazi."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ratiba, kengele, kikumbusho, saa"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Usinisumbue"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Washa"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Washa kipengele cha Usinisumbue"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Kamwe usiwashe"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Muda"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Uliza kila wakati"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Hadi utakapoizima"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Hakuna jina)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Sasa hivi"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Simu hii"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Kishikwambi hiki"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 8aaeb5d..47a65f6 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"பிழைத்திருத்த ஆப்ஸிற்கு, GPU பிழைத்திருத்த லேயர்களை ஏற்றுவதற்கு அனுமதி"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"வெர்போஸ் வெண்டார் பதிவை இயக்கு"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"பிழை அறிக்கைகளில் சாதனம் சார்ந்த கூடுதல் வெண்டார் பதிவுகளைச் சேர்க்கவும். அவற்றில் தனிப்பட்ட தகவல்கள், அதிக பேட்டரி உபயோகம் மற்றும்/அல்லது அதிக சேமிப்பிட உபயோகம் குறித்த தகவல்கள் இருக்கக்கூடும்."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"சாளர அனிமேஷன் வேகம்"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"அனிமேஷன் மாற்றத்தின் வேகம்"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"அனிமேட்டர் கால அளவு"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"குறிப்பிட்ட வடிவமில்லாத சாளரங்களை இயக்கு"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"சாளரங்களை அளவுமாற்ற மற்றும் எங்கும் நகர்த்த அனுமதிக்கும் பரிசோதனைக்குரிய அம்சத்திற்கான ஆதரவை இயக்கு."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"குறிப்பிட்ட வடிவமில்லாத சாளரத்தை இயக்குதல் (லெகஸி)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"பரிசோதனைக்குரிய, குறிப்பிட்ட வடிவமில்லாத பழைய சாளரங்களுக்கான ஆதரவை இயக்குதல்."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"டெஸ்க்டாப் காப்புப்பிரதி கடவுச்சொல்"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"டெஸ்க்டாப்பின் முழு காப்புப்பிரதிகள் தற்போது பாதுகாக்கப்படவில்லை"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"டெஸ்க்டாப்பின் முழுக் காப்புப் பிரதிகளுக்கான கடவுச்சொல்லை மாற்ற அல்லது அகற்ற, தட்டவும்"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"அலாரங்கள் &amp; நினைவூட்டல்கள்"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"அலாரங்களை அமைக்கவும் குறிப்பிட்ட கால இடைவெளியில் செயல்களைத் திட்டமிடவும் இந்த ஆப்ஸை அனுமதிக்கும். இது ஆப்ஸ் பின்னணியில் இயங்குவதை அனுமதிக்கும், இதற்காக அதிக பேட்டரியைப் பயன்படுத்தக்கூடும்.\n\nஇந்த அனுமதி முடக்கப்பட்டிருந்தால் இந்த ஆப்ஸ் மூலம் திட்டமிடப்பட்ட ஏற்கெனவே அமைத்த அலாரங்களும் நேர அடிப்படையிலான நிகழ்வுகளும் வேலை செய்யாது."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"திட்டமிடல், அலாரம், நினைவூட்டல், கடிகாரம்"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"தொந்தரவு செய்யாதே"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ஆன் செய்"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"தொந்தரவு செய்ய வேண்டாம் என்பதை ஆன் செய்யும்"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ஒருபோதும் வேண்டாம்"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"கால அளவு"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ஒவ்வொரு முறையும் கேள்"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"ஆஃப் செய்யும் வரை"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(பெயர் இல்லை)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"சற்றுமுன்"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"இந்த மொபைல்"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"இந்த டேப்லெட்"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 16d40c2..11cbf25 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"డీబగ్ యాప్‌ల కోసం GPU డీబగ్ లేయర్‌లను లోడ్ చేయడాన్ని అనుమతించండి"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"వివరణాత్మక వెండార్‌ లాగింగ్‌ను ఎనేబుల్ చేయండి"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"బగ్ రిపోర్ట్‌లలో అదనపు పరికర-నిర్దిష్ట వెండార్ లాగ్‌లను చేర్చండి, అవి ప్రైవేట్ సమాచారాన్ని కలిగి ఉండవచ్చు, మరింత బ్యాటరీని, మరియు/లేదా మరింత స్టోరేజ్‌ను ఉపయోగించవచ్చు."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"విండో యానిమేషన్ స్కేల్"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ట్రాన్సిషన్ యానిమేషన్ స్కేల్"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"యానిమేటర్ వ్యవధి స్కేల్"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"స్వతంత్ర రూప విండోలను ఎనేబుల్ చేయండి"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ప్రయోగాత్మక స్వతంత్ర రూప విండోల కోసం సపోర్ట్‌ను ఎనేబుల్ చేస్తుంది."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"ఫ్రీఫార్మ్ విండోలను ఎనేబుల్ చేయండి (లెగసీ)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"ప్రయోగాత్మక లెగసీ ఫ్రీఫార్మ్ విండోలకు సంబంధించిన సపోర్ట్‌ను ఎనేబుల్ చేయండి."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"డెస్క్‌టాప్ బ్యాకప్ పాస్‌వర్డ్"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"డెస్క్‌టాప్ పూర్తి బ్యాకప్‌లు ప్రస్తుతం రక్షించబడలేదు"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"డెస్క్‌టాప్ పూర్తి బ్యాకప్‌ల కోసం పాస్‌వర్డ్‌ను మార్చడానికి లేదా తీసివేయడానికి నొక్కండి"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"అలారాలు &amp; రిమైండర్‌లు"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"అలారాలను సెట్ చేయడానికి, టైమ్-సెన్సిటివ్ చర్యలను షెడ్యూల్ చేయడానికి ఈ యాప్‌ను అనుమతించండి. ఇది యాప్‌ను బ్యాక్‌గ్రౌండ్‌లో రన్ అవడానికి అనుమతిస్తుంది, ఇది ఎక్కువ బ్యాటరీని ఉపయోగించవచ్చు.\n\nఈ అనుమతిని ఆఫ్ చేస్తే, ఈ యాప్ ద్వారా షెడ్యూల్ చేసినటువంటి ఇప్పటికే ఉన్న అలారాలు, టైమ్-ఆధారిత ఈవెంట్‌లు పనిచేయవు."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"షెడ్యూల్, అలారం, రిమైండర్, గడియారం"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"అంతరాయం కలిగించవద్దు"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ఆన్ చేయండి"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"అంతరాయం కలిగించవద్దును ఆన్ చేయండి"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ఎప్పటికీ వ‌ద్దు"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"వ్యవధి"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ప్రతిసారి అడగాలి"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"మీరు ఆఫ్‌ చేసే వరకు"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(పేరు లేదు)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"ఇప్పుడే"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"ఈ ఫోన్"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ఈ టాబ్లెట్"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 014ba26..40dbcad 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"อนุญาตให้โหลดเลเยอร์การแก้ไขข้อบกพร่อง GPU สำหรับแอปแก้ไขข้อบกพร่อง"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"เปิดการบันทึกเวนเดอร์แบบละเอียด"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"รวมบันทึกเวนเดอร์เพิ่มเติมเฉพาะอุปกรณ์ไว้ในรายงานข้อบกพร่อง ซึ่งอาจมีข้อมูลส่วนตัว ใช้แบตเตอรี่มากขึ้น และ/หรือใช้พื้นที่เก็บข้อมูลมากขึ้น"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"อัตราการเคลื่อนไหวของหน้าต่าง"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"อัตราการเคลื่อนไหวของการเปลี่ยนภาพ"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"อัตราความเร็วตามตัวสร้างภาพเคลื่อนไหว"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"ทำให้เขียนแอปในที่จัดเก็บข้อมูลภายนอกได้ โดยไม่คำนึงถึงค่าในไฟล์ Manifest"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"บังคับให้กิจกรรมปรับขนาดได้"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"ทำให้กิจกรรมทั้งหมดปรับขนาดได้สำหรับหน้าต่างหลายบาน โดยไม่คำนึงถึงค่าในไฟล์ Manifest"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"เปิดใช้หน้าต่างรูปแบบอิสระ"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"เปิดการสนับสนุนหน้าต่างรูปแบบอิสระแบบทดลอง"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"เปิดใช้หน้าต่างรูปแบบอิสระ (แบบเดิม)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"เปิดใช้การรองรับหน้าต่างรูปแบบอิสระแบบเดิมเวอร์ชันทดลอง"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"รหัสผ่านการสำรองข้อมูลในเดสก์ท็อป"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"การสำรองข้อมูลเต็มรูปแบบในเดสก์ท็อปไม่ได้รับการป้องกันในขณะนี้"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"แตะเพื่อเปลี่ยนแปลงหรือลบรหัสผ่านสำหรับการสำรองข้อมูลเต็มรูปแบบในเดสก์ท็อป"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"การปลุกและการช่วยเตือน"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"อนุญาตให้แอปนี้ตั้งปลุกและกำหนดเวลาการดำเนินการที่ต้องคำนึงถึงเวลาเป็นสำคัญ สิทธิ์นี้ช่วยให้แอปทำงานในเบื้องหลังได้ จึงอาจทำให้ใช้แบตเตอรี่มากขึ้น\n\nหากปิดใช้สิทธิ์นี้ การปลุกที่มีอยู่และกิจกรรมที่ต้องคำนึงถึงเวลาเป็นสำคัญซึ่งแอปนี้กำหนดเวลาไว้จะไม่ทำงาน"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"กำหนดเวลา การปลุก การช่วยเตือน นาฬิกา"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"ห้ามรบกวน"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"เปิด"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"เปิด \"ห้ามรบกวน\""</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ไม่เลย"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"ระยะเวลา"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ถามทุกครั้ง"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"จนกว่าคุณจะปิด"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(ไม่มีชื่อ)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"เมื่อสักครู่"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"โทรศัพท์เครื่องนี้"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"แท็บเล็ตเครื่องนี้"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 936f521..221e634 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Payagang i-load ang GPU debug layer sa debug app"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"I-enable ang verbose vendor logging"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Magsama sa mga ulat ng bug ng mga karagdagang log ng vendor na partikular sa device, na posibleng may pribadong impormasyon, gumamit ng mas maraming baterya, at/o gumamit ng mas malaking storage."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Scale ng window animation"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Scale ng transition animation"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Scale ng tagal ng animator"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Ginagawang kwalipikado ang anumang app na mailagay sa external na storage, anuman ang mga value ng manifest"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Sapilitang gawing resizable ang mga aktibidad"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Gawing nare-resize ang lahat ng aktibidad para sa multi-window, anuman ang mga value ng manifest."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"I-enable ang mga freeform window"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"I-enable ang suporta para sa mga pang-eksperimentong freeform window."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"I-enable ang mga freeform window (legacy)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"I-enable ang suporta para sa mga pang-eksperimentong legacy na freeform window."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Password ng pag-backup ng desktop"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Kasalukuyang hindi pinoprotektahan ang mga buong pag-backup ng desktop"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"I-tap upang baguhin o alisin ang password para sa mga kumpletong pag-back up sa desktop"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Mga alarm at paalala"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Payagan ang app na ito na magtakda ng mga alarm at mag-iskedyul ng mga pagkilos na may limitadong oras. Papayagan nitong tumakbo ang app sa background, na posibleng gumamit ng mas maraming baterya.\n\nKung naka-off ang pahintulot na ito, hindi gagana ang mga kasalukuyang alarm at event na nakabatay sa oras na naiskedyul ng app na ito."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"iskedyul, alarm, paalala, orasan"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Huwag Istorbohin"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"I-on"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"I-on ang Huwag Istorbohin"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Hindi kailanman"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Tagal"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Magtanong palagi"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Hanggang sa i-off mo"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Walang pangalan)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Ngayon lang"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Ang teleponong ito"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ang tablet na ito"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index e8bac31..33c4b3a 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Hata ayıklama uygulamaları için GPU hata ayıklama katmanlarının yüklenmesine izin ver"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Ayrıntılı satıcı günlüğünü etkinleştir"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Hata raporlarına cihaza özgü ek satıcı günlükleri ekle. Bu günlükler gizli bilgiler içerebilir, daha fazla pil ve/veya daha fazla depolama alanı kullanabilir."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Pencere animasyonu ölçeği"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Geçiş animasyonu ölçeği"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatör süre ölçeği"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Manifest değerlerinden bağımsız olarak uygulamaları harici depolamaya yazmak için uygun hale getirir"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Etkinlikleri yeniden boyutlandırılabilmeye zorla"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Manifest değerlerinden bağımsız olarak, tüm etkinlikleri birden fazla pencerede yeniden boyutlandırılabilir yap."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Serbest biçimli pencereleri etkinleştir"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Deneysel serbest biçimli pencere desteğini etkinleştir."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Serbest biçimli pencereleri (eski) etkinleştir"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Deneysel eski serbest biçimli pencere desteğini etkinleştir."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Masaüstü yedekleme şifresi"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Masaüstü tam yedeklemeleri şu an korunmuyor"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Masaüstü tam yedeklemelerinin şifresini değiştirmek veya kaldırmak için dokunun"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Alarmlar ve hatırlatıcılar"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Bu uygulamanın alarm kurmasına ve zamana bağlı işlemler programlamasına izin verin. Bu izin, uygulamanın arka planda çalışmasına olanak sağlayarak daha fazla pil harcanmasına neden olabilir.\n\nBu izin verilmezse bu uygulama tarafından programlanmış mevcut alarmlar ve zamana bağlı etkinlikler çalışmaz."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"program, alarm, hatırlatıcı, saat"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Rahatsız Etmeyin"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aç"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Rahatsız Etmeyin\'i açın"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Hiçbir zaman"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Süre"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Her zaman sor"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Siz kapatana kadar"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Adsız)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Az önce"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Bu telefon"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Bu tablet"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index deb0a40..ce4536f 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Дозволити завантажувати шари налагодження ГП для додатків налагодження"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Увімкнути докладний журнал постачальника"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Включати у звіти про помилки додаткові записи постачальника про пристрій, які можуть містити особисті дані, призводити до надмірного споживання заряду акумулятора та/або використовувати більший обсяг пам\'яті."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Анімація вікон"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Анімація переходів"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Тривалість анімації"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Увімкнути вікна довільного формату"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Увімкнути експериментальні вікна довільного формату."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Увімкнути старий формат вікон змінного розміру"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Увімкнути підтримку експериментального старого формату вікон змінного розміру."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Пароль рез. копії на ПК"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Повні резервні копії на комп’ютері наразі не захищені"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Торкніться, щоб змінити або видалити пароль для повного резервного копіювання на комп’ютер"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Будильники й нагадування"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Дозволити цьому додатку налаштовувати будильники й створювати розклад дій. Додаток зможе працювати у фоновому режимі й використовувати більше заряду акумулятора.\n\nЯкщо вимкнути такий дозвіл, наявні будильники й дії, створені цим додатком, не працюватимуть."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"запланувати, будильник, нагадування, годинник"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Не турбувати"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Увімкнути"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Увімкнути режим \"Не турбувати\""</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Ніколи"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Тривалість"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Запитувати щоразу"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Доки не вимкнути"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Без імені)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Щойно"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Цей телефон"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Цей планшет"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 3ac4d95..d7f4561 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"‏ڈیبگ ایپس کیلئے GPU ڈیبگ پرتوں کو لوڈ کرنے دیں"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"وربوس وینڈر لاگنگ فعال کریں"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"اضافی آلہ کے مخصوص وینڈر لاگز کو بگ رپورٹس میں شامل کریں، جن میں نجی معلومات، بیٹری کا زیادہ استعمال اور/یا اسٹوریج کا زیادہ استعمال شامل ہوسکتے ہیں۔"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"ونڈو اینیمیشن اسکیل"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"ٹرانزیشن اینیمیشن اسکیل"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"اینیمیٹر دورانیے کا اسکیل"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"‏manifest اقدار سے قطع نظر، کسی بھی ایپ کو بیرونی اسٹوریج پر لکھے جانے کا اہل بناتا ہے"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"سرگرمیوں کو ری سائز ایبل بنائیں"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"مینی فیسٹ اقدار سے قطع نظر، ملٹی ونڈو کیلئے تمام سرگرمیوں کو ری سائز ایبل بنائیں۔"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"‏freeform ونڈوز فعال کریں"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"تجرباتی فری فارم ونڈوز کیلئے سپورٹ فعال کریں۔"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"‏فریفارم ونڈوز کو فعال کریں (legacy)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"‏تجرباتی legacy فری فارم ونڈوز کیلئے سپورٹ فعال کریں۔"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"ڈیسک ٹاپ کا بیک اپ پاس ورڈ"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ڈیسک ٹاپ کے مکمل بیک اپس فی الحال محفوظ کیے ہوئے نہیں ہیں"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ڈیسک ٹاپ کے مکمل بیک اپس کیلئے پاس ورڈ کو تبدیل کرنے یا ہٹانے کیلئے تھپتھپائیں"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"الارمز اور یاد دہانیاں"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"اس ایپ کو الارمز سیٹ کرنے اور وقت کے لحاظ سے حساس کارروائیوں کو شیڈول کرنے کی اجازت دیں۔ اس سے ایپ کو پس منظر میں چلنے کی اجازت ملتی ہے، جس میں زیادہ بیٹری استعمال ہو سکتی ہے۔\n\n اگر یہ اجازت آف ہے تو موجودہ الارمز اور اس ایپ کے ذریعے شیڈول کردہ وقت پر مبنی ایونٹس کام نہیں کریں گے۔"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"شیڈول، الارم، یاد دہانی، گھڑی"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"ڈسٹرب نہ کریں"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"آن کریں"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'ڈسٹرب نہ کریں\' کو آن کریں"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"کبھی نہیں"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"مدت"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"ہر بار پوچھیں"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"یہاں تک کہ آپ آف کر دیں"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(کوئی نام نہیں)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"ابھی ابھی"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"یہ فون"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"یہ ٹیبلیٹ"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index f285086..774dfc4 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Grafik protsessorni tuzatish qatlamlarini yuklashni yoqish"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Taʼminotchining batafsil jurnali"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Xatoliklar hisobotiga shaxsiy maʼlumotlari bor va koʻp joy olishi mumkin boʻlgan qurilma haqida taʼminotchining qoʻshimcha yozuvlari kiradi. Bunda batareya quvvati tezroq sarflanishi mumkin."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Oynalar animatsiyasi"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"O‘tish animatsiyasi"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animatsiya tezligi"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Manifest qiymatidan qat’i nazar istalgan ilovani tashqi xotiraga saqlash imkonini beradi"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Harakatlarni moslashuvchan o‘lchamga keltirish"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Manifest qiymatidan qat’i nazar barcha harakatlarni ko‘p oynali rejimga moslashtirish."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Erkin shakldagi oynalarni yoqish"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Erkin shakldagi oynalar yaratish uchun mo‘ljallangan tajribaviy funksiyani yoqish."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Erkin shakldagi oynalarni (eskirgan) yoqish"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Eskirgan erkin shakldagi oynalar yaratish uchun moʻljallangan tajribaviy funksiyani yoqish."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Zaxira nusxa uchun parol"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Kompyuterdagi zaxira nusxalar hozirgi vaqtda himoyalanmagan"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Ish stoli to‘liq zaxira nusxalari parolini o‘zgartirish yoki o‘chirish uchun bu yerni bosing"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Signal va eslatmalar"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Bu ilovaga signal oʻrnatish va vaqtga asoslangan amallarni rejalashtirishga ruxsat berish. Bunda ilovaga orqa fonda ishlashiga imkon beriladi, shu sababli batareya ortiqcha sarflanishi mumkin.\n\nAgar bu ruxsat oʻchirilsa, ushbu ilova tomonidan rejalashtirilgan mavjud signallar va vaqtga asoslangan tadbirlar ishlamaydi."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"reja, signal, eslatma, soat"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Bezovta qilinmasin"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Yoqish"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Bezovta qilinmasin rejimini yoqing"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Hech qachon"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Davomiyligi"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Har safar so‘ralsin"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Rejimdan chiqilgunicha"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Ismi koʻrsatilmagan)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Hozir"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Shu telefon"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Shu planshet"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 9bb4ef5..f66b137 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Cho phép tải lớp gỡ lỗi GPU cho ứng dụng gỡ lỗi"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Bật tùy chọn ghi nhật ký chi tiết của nhà cung cấp"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Đưa thêm nhật ký của nhà cung cấp dành riêng cho thiết bị vào các báo cáo lỗi. Nhật ký này có thể chứa thông tin cá nhân, dùng nhiều pin hơn và/hoặc chiếm nhiều dung lượng lưu trữ hơn."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Tỷ lệ hình động của cửa sổ"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Tỷ lệ hình động chuyển tiếp"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Tỷ lệ thời lượng của trình tạo hình động"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Cho phép ghi mọi ứng dụng đủ điều kiện vào bộ nhớ ngoài, bất kể giá trị tệp kê khai là gì"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Buộc các hoạt động có thể thay đổi kích thước"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Cho phép thay đổi kích thước của tất cả các hoạt động cho nhiều cửa sổ, bất kể giá trị tệp kê khai là gì."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Bật cửa sổ dạng tự do"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Bật tính năng hỗ trợ cửa sổ dạng tự do thử nghiệm."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Bật cửa sổ có thể đổi kích thước (cũ)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Bật tính năng hỗ trợ cửa sổ có thể đổi kích thước thử nghiệm (cũ)."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Mật khẩu cho bản sao lưu qua máy tính"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Các bản sao lưu đầy đủ qua máy tính hiện không được bảo vệ"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Nhấn để thay đổi hoặc xóa mật khẩu dành cho các bản sao lưu đầy đủ vào máy tính"</string>
@@ -557,18 +569,20 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Chuông báo và lời nhắc"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Cho phép ứng dụng này đặt chuông báo và lên lịch các hành động cần chính xác về thời gian. Tùy chọn này cho phép ứng dụng chạy ở chế độ nền và có thể làm tiêu hao nhiều pin.\n\nNếu không cấp quyền này, các chuông báo và sự kiện theo thời gian do ứng dụng này lên lịch sẽ không hoạt động."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"lịch biểu, chuông báo, lời nhắc, đồng hồ"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Không làm phiền"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Bật"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Bật chế độ Không làm phiền"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Không bao giờ"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Chỉ cho các mục ưu tiên"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
-    <string name="zen_alarm_warning_indef" msgid="4146527909616457163">"Bạn sẽ không nghe thấy báo thức tiếp theo lúc <xliff:g id="WHEN">%1$s</xliff:g> của mình trừ khi bạn tắt chức năng này trước"</string>
+    <string name="zen_alarm_warning_indef" msgid="4146527909616457163">"Bạn sẽ không nghe thấy báo thức tiếp theo lúc <xliff:g id="WHEN">%1$s</xliff:g> của mình trừ phi bạn tắt chức năng này trước"</string>
     <string name="zen_alarm_warning" msgid="245729928048586280">"Bạn sẽ không nghe thấy báo thức tiếp theo lúc <xliff:g id="WHEN">%1$s</xliff:g> của mình"</string>
     <string name="alarm_template" msgid="3346777418136233330">"lúc <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="alarm_template_far" msgid="6382760514842998629">"vào <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Thời lượng"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Luôn hỏi"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Cho đến khi bạn tắt"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Không có tên)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Vừa xong"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Điện thoại này"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Máy tính bảng này"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index c1d5481..2b6e8f8 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"允许为调试应用加载 GPU 调试层"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"启用详细供应商日志记录"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"在 bug 报告中包含其他设备特定的供应商日志,这些日志可能会含有隐私信息、消耗更多电量和/或使用更多存储空间。"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"窗口动画缩放"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"过渡动画缩放"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator 时长缩放"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"允许将任何应用写入外部存储设备(无论清单值是什么)"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"强制将 activity 设为可调整大小"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"将所有 activity 设为可配合多窗口环境调整大小(无论清单值是什么)。"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"启用可自由调整的窗口"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"启用可自由调整的窗口这一实验性功能。"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"启用可自由调整的窗口(旧版)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"实现对实验性旧版可自由调整的窗口的支持。"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"桌面备份密码"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"桌面完整备份当前未设置密码保护"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"点按即可更改或移除用于保护桌面完整备份的密码"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"闹钟和提醒"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"允许该应用设置闹钟以及安排在特定时间执行某些操作。这项权限开启后,该应用将在后台运行,可能会消耗更多电池电量。\n\n如果您关闭此权限,该应用设置的现有闹钟将不会响起,而且该应用安排在特定时间执行的现有活动也不会执行。"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"设置, 闹钟, 提醒, 时钟, schedule, alarm, reminder, clock"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"勿扰模式"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"开启"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"开启勿扰模式"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"永不"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"持续时间"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"每次都询问"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"直到您将其关闭"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(无姓名)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"刚刚"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"这部手机"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"这部平板电脑"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index d09a281..97b6f66 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"允許為偵錯應用程式載入 GPU 偵錯圖層"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"啟用詳細供應商記錄"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"在錯誤報告中加入其他裝置專屬供應商記錄,其中可能包含私人資料,並會耗用更多電量及/或儲存空間。"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"視窗動畫比例"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"轉場動畫比例"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator 片長比例"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"啟用自由形態視窗"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"啟用實驗版自由形態視窗的支援功能。"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"啟用自由形態視窗 (舊的)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"啟用舊的實驗版自由形態視窗的支援功能。"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"桌面電腦備份密碼"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"桌面電腦的完整備份目前未受保護"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"輕按即可變更或移除桌面電腦完整備份的密碼"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"鬧鐘和提醒"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"允許此應用程式設定鬧鐘及安排具時效性的操作。這讓應用程式在背景中執行,因此可能會較耗電。\n\n如果關閉此權限,此應用程式將不會在預定時間響起已設定的鬧鐘,亦不會就特定時間的活動傳送通知。"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"日程表, 鬧鐘, 提醒, 時鐘"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"請勿騷擾"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"開啟"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"開啟「請勿騷擾」模式"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"永不"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"持續時間"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"每次都詢問"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"直至你關閉為止"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(沒有名稱)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"剛剛"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"此手機"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"此平板電腦"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index fdb4cf3..348b1f6 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"允許載入 GPU 偵錯圖層為應用程式偵錯"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"啟用詳細供應商記錄功能"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"在錯誤報告中附上其他的裝置專屬供應商記錄。如果你這麼做,可能會增加電池用量及/或占用較多儲存空間,報告中可能也會包含私人資訊。"</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"視窗動畫比例"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"轉場動畫比例"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"動畫影片長度比例"</string>
@@ -424,8 +436,8 @@
     <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>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"啟用自由形式視窗"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"啟用實驗版自由形式視窗的支援功能。"</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"啟用自由形式視窗 (舊版)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"啟用實驗性舊版自由形式視窗支援功能。"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"電腦備份密碼"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"尚未設定密碼保護電腦的完整備份"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"輕觸即可變更或移除電腦完整備份的密碼"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"鬧鐘和提醒"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"允許這個應用程式設定鬧鐘及安排有時效性的動作。之後應用程式可以在背景執行,並可能耗用較多電量。\n\n如果關閉這項權限,這個應用程式設定的現有鬧鐘將不會響起,系統也無法在預定的時間發出活動提醒。"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"時間表, 鬧鐘, 提醒, 時鐘"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"零打擾"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"開啟"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"開啟「零打擾」模式"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"永不"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"時間長度"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"每次都詢問"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"直到你關閉為止"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(無顯示名稱)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"剛剛"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"這支手機"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"這台平板電腦"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 0a0fdff..9cc474c 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -408,6 +408,18 @@
     <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"Vumela izendlalelo zokususa amaphutha ze-GPU ngezinhlelo zokusebenza zokususa amaphutha"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"Nika amandla ilogu yomthengisi we-verbose"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"Faka phakathi amalogu athize womthengisi wedivayisi angeziwe, angase afake phakathi ulwazi oluyimfihlo, kusebenzisa ibhethri eningi, futhi/noma kusebenzisa isitoreji esiningi."</string>
+    <!-- no translation found for enable_verbose_vendor_logging_checkbox (3864578373293835530) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_title (6811217272559843592) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_summary (5226524769774370942) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_notification_action (1190831050259046071) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_will_disable (6175431593394522553) -->
+    <skip />
+    <!-- no translation found for verbose_vendor_logging_preference_summary_on (9017757242481762036) -->
+    <skip />
     <string name="window_animation_scale_title" msgid="5236381298376812508">"Iwindi yesilinganisi sesithombe esinyakazayo"</string>
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Isilinganiso sesithombe soku"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Isilinganiso sobude besikhathi somenzi womfanekiso onyakazayo"</string>
@@ -424,8 +436,8 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Yenza noma uluphi uhlelo lokusebenza lifaneleke ukuthi libhalwe kusitoreji sangaphandle, ngaphandle kwamavelu we-manifest"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Imisebenzi yamandla izonikezwa usayizi omusha"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Yenza yonke imisebenzi ibe nosayizi abasha kumawindi amaningi, ngokunganaki amavelu e-manifest."</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"Nika amandla amawindi e-freeform"</string>
-    <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Nika amandla usekelo lwe-windows yokuhlola kwe-freeform."</string>
+    <string name="enable_freeform_support" msgid="8409932201445109106">"Vumela amawindi efreeform (ifa)"</string>
+    <string name="enable_freeform_support_summary" msgid="2242481082356957934">"Nika amandla amawindi efreeform efa elisahlolwa."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Iphasiwedi yokusekela ngokulondoloza ye-Desktop"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Ukusekela ngokulondoloza okugcwele kwe-Desktop akuvikelekile okwamanje."</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Thepha ukushintsha noma ukususa iphasiwedi yokwenziwa kwezipele ngokugcwele kwideskithophu"</string>
@@ -557,6 +569,7 @@
     <string name="alarms_and_reminders_title" msgid="8819933264635406032">"Ama-alamu nezikhumbuzi"</string>
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Vumela le app isethe ama-alamu futhi ushejule izenzo zesikhathi esizwelayo. Lokhu kuvumela i-app iqhubeke ngemuva okungasebenzisa ibhethri lakho eliningi.\n\nUma le mvume ivaliwe, ama-alamu asele nemicimbi esekelwe esikhathini ehlelwe yile app ngeke kusebenze."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ishejuli, i-alamu, isikhumbuzi, iwashi"</string>
+    <string name="zen_mode_settings_title" msgid="7374070457626419755">"Ungaphazamisi"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Vula"</string>
     <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Vula ukungaphazamisi"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Soze"</string>
@@ -569,6 +582,7 @@
     <string name="zen_mode_duration_settings_title" msgid="1553451650289651489">"Ubude besikhathi"</string>
     <string name="zen_mode_duration_always_prompt_title" msgid="3212996860498119555">"Buza njalo"</string>
     <string name="zen_mode_forever" msgid="3339224497605461291">"Uze uvale isikrini"</string>
+    <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(Alikho igama)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"Khona manje"</string>
     <string name="media_transfer_this_device_name" msgid="2357329267148436433">"Le foni"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Le thebhulethi"</string>
diff --git a/packages/SettingsLib/res/values/colors.xml b/packages/SettingsLib/res/values/colors.xml
index 67139b5..f89fe93 100644
--- a/packages/SettingsLib/res/values/colors.xml
+++ b/packages/SettingsLib/res/values/colors.xml
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 
-<resources>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
     <color name="disabled_text_color">#66000000</color> <!-- 38% black -->
 
     <color name="bt_color_icon_1">#b4a50e0e</color> <!-- 72% Material Red 900 -->
@@ -33,8 +34,8 @@
     <color name="bt_color_bg_6">#e9d2fd</color> <!-- Material Purple 100 -->
     <color name="bt_color_bg_7">#cbf0f8</color> <!-- Material Cyan 100 -->
 
-    <color name="dark_mode_icon_color_single_tone">#99000000</color>
-    <color name="light_mode_icon_color_single_tone">#ffffff</color>
+    <color name="black">@*android:color/black</color>
+    <color name="white">@*android:color/white</color>
 
     <color name="user_avatar_color_bg">?android:attr/colorBackgroundFloating</color>
 
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 363045e..cfd74d4 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -953,6 +953,18 @@
     <string name="enable_verbose_vendor_logging">Enable verbose vendor logging</string>
     <!-- UI debug setting: enable verbose vendor logging summary [CHAR LIMIT=NONE] -->
     <string name="enable_verbose_vendor_logging_summary">Include additional device-specific vendor logs in bug reports, which may contain private information, use more battery, and/or use more storage.</string>
+    <!-- UI debug setting: checkbox text to disable verbose vendor logging after one day [CHAR LIMIT=50] -->
+    <string name="enable_verbose_vendor_logging_checkbox">Disable after one day</string>
+    <!-- UI debug setting: verbose vendor logging notification title [CHAR LIMIT=60] -->
+    <string name="verbose_vendor_logging_notification_title">Verbose vendor logging has ended</string>
+    <!-- UI debug setting: verbose vendor logging notification summary [CHAR LIMIT=60] -->
+    <string name="verbose_vendor_logging_notification_summary">Enabled for one day</string>
+    <!-- UI debug setting: verbose vendor logging notification action text [CHAR LIMIT=60] -->
+    <string name="verbose_vendor_logging_notification_action">Enable for one more day</string>
+    <!-- UI debug setting: verbose vendor logging preference summary for disabling after one day [CHAR LIMIT=60] -->
+    <string name="verbose_vendor_logging_preference_summary_will_disable">Disables after one day</string>
+    <!-- UI debug setting: verbose vendor logging preference summary for leaving setting enabled indefinitely [CHAR LIMIT=60] -->
+    <string name="verbose_vendor_logging_preference_summary_on">Enabled indefinitely</string>
 
     <!-- UI debug setting: scaling factor for window animations [CHAR LIMIT=25] -->
     <string name="window_animation_scale_title">Window animation scale</string>
@@ -998,10 +1010,10 @@
     <!-- UI debug setting: force allow on external summary [CHAR LIMIT=150] -->
     <string name="force_resizable_activities_summary">Make all activities resizable for multi-window, regardless of manifest values.</string>
 
-    <!-- UI debug setting: enable freeform window support [CHAR LIMIT=50] -->
-    <string name="enable_freeform_support">Enable freeform windows</string>
-    <!-- UI debug setting: enable freeform window support summary [CHAR LIMIT=150] -->
-    <string name="enable_freeform_support_summary">Enable support for experimental freeform windows.</string>
+    <!-- UI debug setting: enable legacy freeform window support [CHAR LIMIT=50] -->
+    <string name="enable_freeform_support">Enable freeform windows (legacy)</string>
+    <!-- UI debug setting: enable legacy freeform window support summary [CHAR LIMIT=150] -->
+    <string name="enable_freeform_support_summary">Enable support for experimental legacy freeform windows.</string>
 
     <!-- Local (desktop) backup password menu title [CHAR LIMIT=25] -->
     <string name="local_backup_password_title">Desktop backup password</string>
@@ -1349,6 +1361,9 @@
     <!-- Keywords for setting screen for controlling apps that can schedule alarms [CHAR LIMIT=100] -->
     <string name="keywords_alarms_and_reminders">schedule, alarm, reminder, clock</string>
 
+    <!-- Sound: Title for the Do not Disturb option and associated settings page. [CHAR LIMIT=50]-->
+    <string name="zen_mode_settings_title">Do Not Disturb</string>
+
     <!--  Do not disturb: Label for button in enable zen dialog that will turn on zen mode. [CHAR LIMIT=30] -->
     <string name="zen_mode_enable_dialog_turn_on">Turn on</string>
     <!-- Do not disturb: Title for the Do not Disturb dialog to turn on Do not disturb. [CHAR LIMIT=50]-->
@@ -1375,6 +1390,9 @@
     <!-- Do not disturb: Duration option to always have DND on until it is manually turned off [CHAR LIMIT=60] -->
     <string name="zen_mode_forever">Until you turn off</string>
 
+    <!-- [CHAR LIMIT=50] Zen mode settings: placeholder for a Contact name when the name is empty -->
+    <string name="zen_mode_starred_contacts_empty_name">(No name)</string>
+
     <!-- time label for event have that happened very recently [CHAR LIMIT=60] -->
     <string name="time_unit_just_now">Just now</string>
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
index 1597a4b..fc163ce 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
@@ -430,13 +430,21 @@
         return null;
     }
 
+    /**
+     * Retrieves the user ID of a managed profile associated with a specific user.
+     *
+     * <p>This method iterates over the users in the profile group associated with the given user ID
+     * and returns the ID of the user that is identified as a managed profile user.
+     * If no managed profile is found, it returns {@link UserHandle#USER_NULL}.
+     *
+     * @param context The context used to obtain the {@link UserManager} system service.
+     * @param userId  The ID of the user for whom to find the managed profile.
+     * @return The user ID of the managed profile, or {@link UserHandle#USER_NULL} if none exists.
+     */
     private static int getManagedProfileId(Context context, int userId) {
         UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
         List<UserInfo> userProfiles = um.getProfiles(userId);
         for (UserInfo uInfo : userProfiles) {
-            if (uInfo.id == userId) {
-                continue;
-            }
             if (uInfo.isManagedProfile()) {
                 return uInfo.id;
             }
@@ -821,11 +829,11 @@
         }
         EnforcedAdmin admin =
                 RestrictedLockUtils.getProfileOrDeviceOwner(
-                        context, UserHandle.of(UserHandle.USER_SYSTEM));
+                        context, context.getUser());
         if (admin != null) {
             return admin;
         }
-        int profileId = getManagedProfileId(context, UserHandle.USER_SYSTEM);
+        int profileId = getManagedProfileId(context, context.getUserId());
         return RestrictedLockUtils.getProfileOrDeviceOwner(context, UserHandle.of(profileId));
     }
 
@@ -848,7 +856,7 @@
         if (admin != null) {
             return admin;
         }
-        int profileId = getManagedProfileId(context, UserHandle.USER_SYSTEM);
+        int profileId = getManagedProfileId(context, context.getUserId());
         return RestrictedLockUtils.getProfileOrDeviceOwner(context, UserHandle.of(profileId));
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
index 734b92c..6ca9279 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java
@@ -38,8 +38,6 @@
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
-import com.android.settingslib.utils.BuildCompatUtils;
-
 /**
  * Helper class for managing settings preferences that can be disabled
  * by device admins via user restrictions.
@@ -120,9 +118,10 @@
         if (mDisabledSummary) {
             final TextView summaryView = (TextView) holder.findViewById(android.R.id.summary);
             if (summaryView != null) {
-                final CharSequence disabledText = BuildCompatUtils.isAtLeastT()
-                        ? getDisabledByAdminUpdatableString()
-                        : mContext.getString(R.string.disabled_by_admin_summary_text);
+                final CharSequence disabledText =
+                        (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
+                                ? getDisabledByAdminUpdatableString()
+                                : mContext.getString(R.string.disabled_by_admin_summary_text);
                 if (mDisabledByAdmin) {
                     summaryView.setText(disabledText);
                 } else if (mDisabledByEcm) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
index 45754eb..fffbb54 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
@@ -25,6 +25,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.res.TypedArray;
+import android.os.Build;
 import android.os.Process;
 import android.os.UserHandle;
 import android.util.AttributeSet;
@@ -40,8 +41,6 @@
 import androidx.preference.PreferenceViewHolder;
 import androidx.preference.SwitchPreferenceCompat;
 
-import com.android.settingslib.utils.BuildCompatUtils;
-
 /**
  * Version of SwitchPreferenceCompat that can be disabled by a device admin
  * using a user restriction.
@@ -164,7 +163,7 @@
 
     private static String getUpdatableEnterpriseString(
             Context context, String updatableStringId, int resId) {
-        if (!BuildCompatUtils.isAtLeastT()) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
             return context.getString(resId);
         }
         return context.getSystemService(DevicePolicyManager.class).getResources().getString(
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index c2506d3..b02b0c4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -66,7 +66,6 @@
 import com.android.settingslib.drawable.UserIconDrawable;
 import com.android.settingslib.fuelgauge.BatteryStatus;
 import com.android.settingslib.fuelgauge.BatteryUtils;
-import com.android.settingslib.utils.BuildCompatUtils;
 
 import java.util.List;
 
@@ -147,7 +146,7 @@
         String name = info != null ? info.name : null;
         if (info.isManagedProfile()) {
             // We use predefined values for managed profiles
-            return BuildCompatUtils.isAtLeastT()
+            return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
                     ? getUpdatableManagedUserTitle(context)
                     : context.getString(R.string.managed_user_title);
         } else if (info.isGuest()) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
index 721e7b9..53441c0 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
@@ -24,6 +24,7 @@
 import android.net.Uri;
 import android.provider.DeviceConfig;
 import android.provider.MediaStore;
+import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Pair;
@@ -808,7 +809,8 @@
      * <p>If CachedBluetoothDevice#getGroupId is invalid, fetch group id from
      * LeAudioProfile#getGroupId.
      */
-    public static int getGroupId(@NonNull CachedBluetoothDevice cachedDevice) {
+    public static int getGroupId(@Nullable CachedBluetoothDevice cachedDevice) {
+        if (cachedDevice == null) return BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
         int groupId = cachedDevice.getGroupId();
         String anonymizedAddress = cachedDevice.getDevice().getAnonymizedAddress();
         if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID) {
@@ -824,4 +826,44 @@
         Log.d(TAG, "getGroupId return invalid id for device: " + anonymizedAddress);
         return BluetoothCsipSetCoordinator.GROUP_ID_INVALID;
     }
+
+    /** Get primary device Uri in broadcast. */
+    @NonNull
+    public static String getPrimaryGroupIdUriForBroadcast() {
+        return "bluetooth_le_broadcast_fallback_active_group_id";
+    }
+
+    /** Get primary device group id in broadcast. */
+    @WorkerThread
+    public static int getPrimaryGroupIdForBroadcast(@NonNull Context context) {
+        return Settings.Secure.getInt(
+                context.getContentResolver(),
+                getPrimaryGroupIdUriForBroadcast(),
+                BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
+    }
+
+    /** Get secondary {@link CachedBluetoothDevice} in broadcast. */
+    @Nullable
+    @WorkerThread
+    public static CachedBluetoothDevice getSecondaryDeviceForBroadcast(
+            @NonNull Context context, @Nullable LocalBluetoothManager localBtManager) {
+        if (localBtManager == null) return null;
+        int primaryGroupId = getPrimaryGroupIdForBroadcast(context);
+        if (primaryGroupId == BluetoothCsipSetCoordinator.GROUP_ID_INVALID) return null;
+        LocalBluetoothLeBroadcastAssistant assistant =
+                localBtManager.getProfileManager().getLeAudioBroadcastAssistantProfile();
+        CachedBluetoothDeviceManager deviceManager = localBtManager.getCachedDeviceManager();
+        List<BluetoothDevice> devices = assistant.getAllConnectedDevices();
+        for (BluetoothDevice device : devices) {
+            CachedBluetoothDevice cachedDevice = deviceManager.findDevice(device);
+            if (hasConnectedBroadcastSource(cachedDevice, localBtManager)) {
+                int groupId = getGroupId(cachedDevice);
+                if (groupId != BluetoothCsipSetCoordinator.GROUP_ID_INVALID
+                        && groupId != primaryGroupId) {
+                    return cachedDevice;
+                }
+            }
+        }
+        return null;
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
index 9faebe2..148e164 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastAssistant.java
@@ -389,6 +389,14 @@
         return mService.getDevicesMatchingConnectionStates(states);
     }
 
+    /** Gets all connected devices on assistant profile. */
+    public List<BluetoothDevice> getAllConnectedDevices() {
+        if (mService == null) {
+            return new ArrayList<BluetoothDevice>(0);
+        }
+        return mService.getConnectedDevices();
+    }
+
     public boolean isEnabled(BluetoothDevice device) {
         if (mService == null || device == null) {
             return false;
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreference.java
new file mode 100644
index 0000000..1cbb8b4
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreference.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.Objects;
+
+/**
+ * A data class representing an action/switch preference. The preference could be one of the four
+ * following forms: 1. Texted row with action to jump to another page 2. Texted row without action
+ * 3. Texted row with action and switch 4. Texted row with switch
+ */
+public class ActionSwitchPreference extends DeviceSettingPreference implements Parcelable {
+    private final String mTitle;
+    private final String mSummary;
+    private final Bitmap mIcon;
+    private final Intent mIntent;
+    private final boolean mHasSwitch;
+    private final boolean mChecked;
+    private final boolean mIsAllowedChangingState;
+    private final Bundle mExtras;
+
+    ActionSwitchPreference(
+            String title,
+            @Nullable String summary,
+            @Nullable Bitmap icon,
+            @Nullable Intent intent,
+            boolean hasSwitch,
+            boolean checked,
+            boolean allowChangingState,
+            @NonNull Bundle extras) {
+        super(DeviceSettingType.DEVICE_SETTING_TYPE_ACTION_SWITCH);
+        validate(title);
+        mTitle = title;
+        mSummary = summary;
+        mIcon = icon;
+        mIntent = intent;
+        mHasSwitch = hasSwitch;
+        mChecked = checked;
+        mIsAllowedChangingState = allowChangingState;
+        mExtras = extras;
+    }
+
+    private static void validate(String title) {
+        if (Objects.isNull(title)) {
+            throw new IllegalArgumentException("Title must be set");
+        }
+    }
+
+    /**
+     * Reads an {@link ActionSwitchPreference} instance from {@link Parcel}
+     * @param in The parcel to read from
+     * @return The instance read
+     */
+    @NonNull
+    public static ActionSwitchPreference readFromParcel(@NonNull Parcel in) {
+        String title = in.readString();
+        String summary = in.readString();
+        Bitmap icon = in.readParcelable(Bitmap.class.getClassLoader());
+        Intent intent = in.readParcelable(Intent.class.getClassLoader());
+        boolean hasSwitch = in.readBoolean();
+        boolean checked = in.readBoolean();
+        boolean allowChangingState = in.readBoolean();
+        Bundle extras = in.readBundle(Bundle.class.getClassLoader());
+        return new ActionSwitchPreference(
+                title, summary, icon, intent, hasSwitch, checked, allowChangingState, extras);
+    }
+
+    public static final Creator<ActionSwitchPreference> CREATOR =
+            new Creator<>() {
+                @Override
+                @NonNull
+                public ActionSwitchPreference createFromParcel(@NonNull Parcel in) {
+                    in.readInt();
+                    return readFromParcel(in);
+                }
+
+                @Override
+                @NonNull
+                public ActionSwitchPreference[] newArray(int size) {
+                    return new ActionSwitchPreference[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        super.writeToParcel(dest, flags);
+        dest.writeString(mTitle);
+        dest.writeString(mSummary);
+        dest.writeParcelable(mIcon, flags);
+        dest.writeParcelable(mIntent, flags);
+        dest.writeBoolean(mHasSwitch);
+        dest.writeBoolean(mChecked);
+        dest.writeBoolean(mIsAllowedChangingState);
+        dest.writeBundle(mExtras);
+    }
+
+    /** Builder class for {@link ActionSwitchPreference}. */
+    public static final class Builder {
+        private String mTitle;
+        private String mSummary;
+        private Bitmap mIcon;
+        private Intent mIntent;
+        private boolean mHasSwitch;
+        private boolean mChecked;
+        private boolean mIsAllowedChangingState;
+        private Bundle mExtras = Bundle.EMPTY;
+
+        /**
+         * Sets the title of the preference.
+         *
+         * @param title The title of the preference.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setTitle(@NonNull String title) {
+            mTitle = title;
+            return this;
+        }
+
+        /**
+         * Sets the summary of the preference, optional.
+         *
+         * @param summary The preference summary.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setSummary(@Nullable String summary) {
+            mSummary = summary;
+            return this;
+        }
+
+        /**
+         * Sets the icon to be displayed on the left of the preference, optional.
+         *
+         * @param icon The icon.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setIcon(@Nullable Bitmap icon) {
+            mIcon = icon;
+            return this;
+        }
+
+        /**
+         * Sets the Intent to launch when the preference is clicked, optional.
+         *
+         * @param intent The Intent.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setIntent(@Nullable Intent intent) {
+            mIntent = intent;
+            return this;
+        }
+
+        /**
+         * Sets whether the preference will contain a switch.
+         *
+         * @param hasSwitch Whether the preference contains a switch.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setHasSwitch(boolean hasSwitch) {
+            mHasSwitch = hasSwitch;
+            return this;
+        }
+
+        /**
+         * Sets the state of the preference.
+         *
+         * @param checked Whether the switch is checked.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setChecked(boolean checked) {
+            mChecked = checked;
+            return this;
+        }
+
+        /**
+         * Sets whether state can be changed by user.
+         *
+         * @param allowChangingState Whether user is allowed to change state.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setAllowedChangingState(boolean allowChangingState) {
+            mIsAllowedChangingState = allowChangingState;
+            return this;
+        }
+
+        /**
+         * Sets the extras bundle.
+         *
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setExtras(@NonNull Bundle extras) {
+            mExtras = extras;
+            return this;
+        }
+
+        /**
+         * Builds the {@link ActionSwitchPreference} object.
+         *
+         * @return Returns the built {@link ActionSwitchPreference} object.
+         */
+        @NonNull
+        public ActionSwitchPreference build() {
+            return new ActionSwitchPreference(
+                    mTitle,
+                    mSummary,
+                    mIcon,
+                    mIntent,
+                    mHasSwitch,
+                    mChecked,
+                    mIsAllowedChangingState,
+                    mExtras);
+        }
+    }
+
+    /**
+     * Gets the title of the preference.
+     *
+     * @return Returns the title of the preference.
+     */
+    @NonNull
+    public String getTitle() {
+        return mTitle;
+    }
+
+    /**
+     * Gets the summary of the preference.
+     *
+     * @return Returns the summary of the preference.
+     */
+    @Nullable
+    public String getSummary() {
+        return mSummary;
+    }
+
+    /**
+     * Gets the icon of the preference.
+     *
+     * @return Returns the icon of the preference.
+     */
+    @Nullable
+    public Bitmap getIcon() {
+        return mIcon;
+    }
+
+    /**
+     * Gets the Intent to launch when the preference is clicked.
+     *
+     * @return Returns the intent to launch.
+     */
+    @Nullable
+    public Intent getIntent() {
+        return mIntent;
+    }
+
+    /**
+     * Whether the preference contains a switch.
+     *
+     * @return Whether the preference contains a switch.
+     */
+    public boolean hasSwitch() {
+        return mHasSwitch;
+    }
+
+    /**
+     * Whether the switch is checked.
+     *
+     * @return Whether the switch is checked.
+     */
+    public boolean getChecked() {
+        return mChecked;
+    }
+
+    /**
+     * Gets whether the state can be changed by user.
+     *
+     * @return Whether the state can be changed by user.
+     */
+    public boolean isAllowedChangingState() {
+        return mIsAllowedChangingState;
+    }
+
+    /**
+     * Gets the extras bundle.
+     *
+     * @return The extra bundle.
+     */
+    @NonNull
+    public Bundle getExtras() {
+        return mExtras;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceState.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceState.java
new file mode 100644
index 0000000..91c1a59
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceState.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
+/** A data class representing the state of an action/switch preference. */
+public class ActionSwitchPreferenceState extends DeviceSettingPreferenceState
+        implements Parcelable {
+    private final boolean mChecked;
+    private final Bundle mExtras;
+
+    ActionSwitchPreferenceState(boolean checked, @NonNull Bundle extras) {
+        super(DeviceSettingType.DEVICE_SETTING_TYPE_ACTION_SWITCH);
+        mChecked = checked;
+        mExtras = extras;
+    }
+
+    /**
+     * Reads an {@link ActionSwitchPreferenceState} instance from {@link Parcel}
+     * @param in The parcel to read from
+     * @return The instance read
+     */
+    @NonNull
+    public static ActionSwitchPreferenceState readFromParcel(@NonNull Parcel in) {
+        boolean checked = in.readBoolean();
+        Bundle extras = in.readBundle(Bundle.class.getClassLoader());
+        return new ActionSwitchPreferenceState(checked, extras);
+    }
+
+    public static final Creator<ActionSwitchPreferenceState> CREATOR =
+            new Creator<>() {
+                @Override
+                @NonNull
+                public ActionSwitchPreferenceState createFromParcel(@NonNull Parcel in) {
+                    in.readInt();
+                    return readFromParcel(in);
+                }
+
+                @Override
+                @NonNull
+                public ActionSwitchPreferenceState[] newArray(int size) {
+                    return new ActionSwitchPreferenceState[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        super.writeToParcel(dest, flags);
+        dest.writeBoolean(mChecked);
+        dest.writeBundle(mExtras);
+    }
+
+    /** Builder class for {@link ActionSwitchPreferenceState}. */
+    public static final class Builder {
+        private boolean mChecked;
+        private Bundle mExtras = Bundle.EMPTY;
+
+        public Builder() {}
+
+        /**
+         * Sets the state of the preference.
+         *
+         * @param checked Whether the switch is checked.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setChecked(boolean checked) {
+            mChecked = checked;
+            return this;
+        }
+
+        /**
+         * Sets the extras bundle.
+         *
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setExtras(@NonNull Bundle extras) {
+            mExtras = extras;
+            return this;
+        }
+
+        /**
+         * Builds the object.
+         *
+         * @return Returns the built object.
+         */
+        @NonNull
+        public ActionSwitchPreferenceState build() {
+            return new ActionSwitchPreferenceState(mChecked, mExtras);
+        }
+    }
+
+    /**
+     * Whether the switch is checked.
+     *
+     * @return Whether the switch is checked.
+     */
+    public boolean getChecked() {
+        return mChecked;
+    }
+
+    /**
+     * Gets the extras bundle.
+     *
+     * @return The extra bundle.
+     */
+    @NonNull
+    public Bundle getExtras() {
+        return mExtras;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfo.aidl b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfo.aidl
new file mode 100644
index 0000000..acbaf2d
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+parcelable DeviceInfo;
\ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfo.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfo.java
new file mode 100644
index 0000000..52e520e
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfo.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
+import java.util.Objects;
+
+/** A data class representing a bluetooth device. */
+public class DeviceInfo implements Parcelable {
+    private final String mBluetoothAddress;
+    private final Bundle mExtras;
+
+    DeviceInfo(String bluetoothAddress, Bundle extras) {
+        validate(bluetoothAddress);
+        mBluetoothAddress = bluetoothAddress;
+        mExtras = extras;
+    }
+
+    private static void validate(String bluetoothAddress) {
+        if (Objects.isNull(bluetoothAddress)) {
+            throw new IllegalArgumentException("Bluetooth address must be set");
+        }
+    }
+
+    /** Read a {@link DeviceInfo} instance from {@link Parcel} */
+    @NonNull
+    public static DeviceInfo readFromParcel(@NonNull Parcel in) {
+        String bluetoothAddress = in.readString();
+        Bundle extras = in.readBundle(Bundle.class.getClassLoader());
+        return new DeviceInfo(bluetoothAddress, extras);
+    }
+
+    public static final Creator<DeviceInfo> CREATOR =
+            new Creator<>() {
+                @Override
+                @NonNull
+                public DeviceInfo createFromParcel(@NonNull Parcel in) {
+                    return readFromParcel(in);
+                }
+
+                @Override
+                @NonNull
+                public DeviceInfo[] newArray(int size) {
+                    return new DeviceInfo[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(mBluetoothAddress);
+        dest.writeBundle(mExtras);
+    }
+
+    /** Builder class for {@link DeviceInfo}. */
+    public static final class Builder {
+        private String mBluetoothAddress;
+        private Bundle mExtras = Bundle.EMPTY;
+
+        /**
+         * Sets the bluetooth address of the device, from {@link
+         * android.bluetooth.BluetoothDevice#getAddress()}.
+         *
+         * @param bluetoothAddress The bluetooth address.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setBluetoothAddress(@NonNull String bluetoothAddress) {
+            mBluetoothAddress = bluetoothAddress;
+            return this;
+        }
+
+        /**
+         * Sets the extras bundle.
+         *
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setExtras(@NonNull Bundle extras) {
+            mExtras = extras;
+            return this;
+        }
+
+        /**
+         * Builds the {@link DeviceInfo} object.
+         *
+         * @return Returns the built {@link DeviceInfo} object.
+         */
+        @NonNull
+        public DeviceInfo build() {
+            return new DeviceInfo(mBluetoothAddress, mExtras);
+        }
+    }
+
+    /**
+     * Gets the bluetooth address of the device.
+     *
+     * @return The bluetooth address from {@link android.bluetooth.BluetoothDevice#getAddress()}.
+     */
+    @NonNull
+    public String getBluetoothAddress() {
+        return mBluetoothAddress;
+    }
+
+    /**
+     * Gets the extras bundle.
+     *
+     * @return The extra bundle.
+     */
+    @NonNull
+    public Bundle getExtras() {
+        return mExtras;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSetting.aidl b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSetting.aidl
new file mode 100644
index 0000000..043cae3
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSetting.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+parcelable DeviceSetting;
\ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSetting.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSetting.java
new file mode 100644
index 0000000..dc219a9
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSetting.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
+import java.util.Objects;
+
+/** A data class representing a device setting item in bluetooth device details page. */
+public final class DeviceSetting implements Parcelable {
+    @DeviceSettingId private final int mSettingId;
+    private final DeviceSettingPreference mPreference;
+    private final Bundle mExtras;
+
+    DeviceSetting(
+            int settingId, @NonNull DeviceSettingPreference preference, @NonNull Bundle extras) {
+        validate(preference);
+        mSettingId = settingId;
+        mPreference = preference;
+        mExtras = extras;
+    }
+
+    private static void validate(DeviceSettingPreference preference) {
+        if (Objects.isNull(preference)) {
+            throw new IllegalArgumentException("Preference must be set");
+        }
+    }
+
+    /** Read a {@link DeviceSetting} instance from {@link Parcel} */
+    @NonNull
+    public static DeviceSetting readFromParcel(@NonNull Parcel in) {
+        int settingId = in.readInt();
+        Bundle extras = in.readBundle(Bundle.class.getClassLoader());
+        DeviceSettingPreference settingPreference = DeviceSettingPreference.readFromParcel(in);
+        return new DeviceSetting(settingId, settingPreference, extras);
+    }
+
+    public static final Creator<DeviceSetting> CREATOR =
+            new Creator<>() {
+                @Override
+                @NonNull
+                public DeviceSetting createFromParcel(@NonNull Parcel in) {
+                    return readFromParcel(in);
+                }
+
+                @Override
+                @NonNull
+                public DeviceSetting[] newArray(int size) {
+                    return new DeviceSetting[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mSettingId);
+        dest.writeBundle(mExtras);
+        mPreference.writeToParcel(dest, flags);
+    }
+
+    /** Builder class for {@link DeviceSetting}. */
+    public static final class Builder {
+        private int mSettingId;
+        private DeviceSettingPreference mPreference;
+        private Bundle mExtras = Bundle.EMPTY;
+
+        public Builder() {}
+
+        /**
+         * Sets the setting ID, as defined by IntDef {@link DeviceSettingId}.
+         *
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setSettingId(@DeviceSettingId int settingId) {
+            mSettingId = settingId;
+            return this;
+        }
+
+        /**
+         * Sets the setting preference.
+         *
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setPreference(@NonNull DeviceSettingPreference settingPreference) {
+            mPreference = settingPreference;
+            return this;
+        }
+
+        /**
+         * Sets the extras bundle.
+         *
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setExtras(@NonNull Bundle extras) {
+            mExtras = extras;
+            return this;
+        }
+
+        /** Build the object. */
+        @NonNull
+        public DeviceSetting build() {
+            return new DeviceSetting(mSettingId, mPreference, mExtras);
+        }
+    }
+
+    /**
+     * Gets the setting ID as defined by IntDef {@link DeviceSettingId}.
+     *
+     * @return Returns the setting ID.
+     */
+    @DeviceSettingId
+    public int getSettingId() {
+        return mSettingId;
+    }
+
+    /**
+     * Gets the setting preference.
+     *
+     * @return Returns the setting preference.
+     */
+    @NonNull
+    public DeviceSettingPreference getPreference() {
+        return mPreference;
+    }
+
+    /**
+     * Gets the extras Bundle.
+     *
+     * @return Returns a Bundle object.
+     */
+    @NonNull
+    public Bundle getExtras() {
+        return mExtras;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingId.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingId.java
new file mode 100644
index 0000000..20a0339
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingId.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import androidx.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.SOURCE)
+@IntDef(
+        value = {
+            DeviceSettingId.DEVICE_SETTING_ID_UNKNOWN,
+            DeviceSettingId.DEVICE_SETTING_ID_HEADER,
+            DeviceSettingId.DEVICE_SETTING_ID_ADVANCED_HEADER,
+            DeviceSettingId.DEVICE_SETTING_ID_LE_AUDIO_HEADER,
+            DeviceSettingId.DEVICE_SETTING_ID_HEARING_AID_PAIR_OTHER_BUTTON,
+            DeviceSettingId.DEVICE_SETTING_ID_HEARING_AID_SPACE_LAYOUT,
+            DeviceSettingId.DEVICE_SETTING_ID_ACTION_BUTTONS,
+            DeviceSettingId.DEVICE_SETTING_ID_DEVICE_STYLUS,
+            DeviceSettingId.DEVICE_SETTING_ID_BLUETOOTH_EXTRA_CONTROL,
+            DeviceSettingId.DEVICE_SETTING_ID_BLUETOOTH_DEVICE_SLICE_CATEGORY,
+            DeviceSettingId.DEVICE_SETTING_ID_DEVICE_COMPANION_APPS,
+            DeviceSettingId.DEVICE_SETTING_ID_HEARING_DEVICE_GROUP,
+            DeviceSettingId.DEVICE_SETTING_ID_BLUETOOTH_AUDIO_DEVICE_TYPE_GROUP,
+            DeviceSettingId.DEVICE_SETTING_ID_SPATIAL_AUDIO_GROUP,
+            DeviceSettingId.DEVICE_SETTING_ID_BLUETOOTH_PROFILES,
+            DeviceSettingId.DEVICE_SETTING_ID_BLUETOOTH_EXTRA_OPTIONS,
+            DeviceSettingId.DEVICE_SETTING_ID_BLUETOOTH_RELATED_TOOLS,
+            DeviceSettingId.DEVICE_SETTING_ID_DATA_SYNC_GROUP,
+            DeviceSettingId.DEVICE_SETTING_ID_KEYBOARD_SETTINGS,
+            DeviceSettingId.DEVICE_SETTING_ID_DEVICE_DETAILS_FOOTER,
+            DeviceSettingId.DEVICE_SETTING_ID_ANC,
+        },
+        open = true)
+public @interface DeviceSettingId {
+    /** Device setting ID is unknown. */
+    int DEVICE_SETTING_ID_UNKNOWN = 0;
+
+    /** Device setting ID for header. */
+    int DEVICE_SETTING_ID_HEADER = 1;
+
+    /** Device setting ID for advanced header. */
+    int DEVICE_SETTING_ID_ADVANCED_HEADER = 2;
+
+    /** Device setting ID for LeAudio header. */
+    int DEVICE_SETTING_ID_LE_AUDIO_HEADER = 3;
+
+    /** Device setting ID for hearing aid “pair other” button. */
+    int DEVICE_SETTING_ID_HEARING_AID_PAIR_OTHER_BUTTON = 4;
+
+    /** Device setting ID for hearing aid space layout. */
+    int DEVICE_SETTING_ID_HEARING_AID_SPACE_LAYOUT = 5;
+
+    /** Device setting ID for action buttons(Forget, Connect/Disconnect). */
+    int DEVICE_SETTING_ID_ACTION_BUTTONS = 6;
+
+    /** Device setting ID for stylus device. */
+    int DEVICE_SETTING_ID_DEVICE_STYLUS = 7;
+
+    /** Device setting ID for bluetooth extra control. */
+    int DEVICE_SETTING_ID_BLUETOOTH_EXTRA_CONTROL = 8;
+
+    /** Device setting ID for bluetooth device slice category. */
+    int DEVICE_SETTING_ID_BLUETOOTH_DEVICE_SLICE_CATEGORY = 9;
+
+    /** Device setting ID for device companion apps. */
+    int DEVICE_SETTING_ID_DEVICE_COMPANION_APPS = 10;
+
+    /** Device setting ID for hearing device group. */
+    int DEVICE_SETTING_ID_HEARING_DEVICE_GROUP = 11;
+
+    /** Device setting ID for bluetooth audio device type group. */
+    int DEVICE_SETTING_ID_BLUETOOTH_AUDIO_DEVICE_TYPE_GROUP = 12;
+
+    /** Device setting ID for spatial audio group. */
+    int DEVICE_SETTING_ID_SPATIAL_AUDIO_GROUP = 13;
+
+    /** Device setting ID for bluetooth profiles. */
+    int DEVICE_SETTING_ID_BLUETOOTH_PROFILES = 14;
+
+    /** Device setting ID for bluetooth extra options. */
+    int DEVICE_SETTING_ID_BLUETOOTH_EXTRA_OPTIONS = 15;
+
+    /** Device setting ID for bluetooth related tools. */
+    int DEVICE_SETTING_ID_BLUETOOTH_RELATED_TOOLS = 16;
+
+    /** Device setting ID for data sync group. */
+    int DEVICE_SETTING_ID_DATA_SYNC_GROUP = 17;
+
+    /** Device setting ID for keyboard settings. */
+    int DEVICE_SETTING_ID_KEYBOARD_SETTINGS = 18;
+
+    /** Device setting ID for device details footer. */
+    int DEVICE_SETTING_ID_DEVICE_DETAILS_FOOTER = 19;
+
+    /** Device setting ID for ANC. */
+    int DEVICE_SETTING_ID_ANC = 1001;
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingItem.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingItem.kt
new file mode 100644
index 0000000..9ee33b0
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingItem.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings
+
+import android.os.Bundle
+import android.os.Parcel
+import android.os.Parcelable
+
+/**
+ * A data class representing a device settings item in bluetooth device details config.
+ *
+ * @property settingId The setting ID of the item, as defined by IntDef [DeviceSettingId].
+ * @property packageName The package name for service binding.
+ * @property className The class name for service binding.
+ * @property intentAction The intent action for service binding.
+ * @property extras Extra bundle
+ */
+data class DeviceSettingItem(
+    @DeviceSettingId val settingId: Int,
+    val packageName: String,
+    val className: String,
+    val intentAction: String,
+    val extras: Bundle = Bundle.EMPTY,
+) : Parcelable {
+
+    override fun describeContents(): Int = 0
+
+    override fun writeToParcel(parcel: Parcel, flags: Int) {
+        parcel.run {
+            writeInt(settingId)
+            writeString(packageName)
+            writeString(className)
+            writeString(intentAction)
+            writeBundle(extras)
+        }
+    }
+
+    companion object {
+        @JvmField
+        val CREATOR: Parcelable.Creator<DeviceSettingItem> =
+            object : Parcelable.Creator<DeviceSettingItem> {
+                override fun createFromParcel(parcel: Parcel) =
+                    parcel.run {
+                        DeviceSettingItem(
+                            settingId = readInt(),
+                            packageName = readString() ?: "",
+                            className = readString() ?: "",
+                            intentAction = readString() ?: "",
+                            extras = readBundle((Bundle::class.java.classLoader)) ?: Bundle.EMPTY,
+                        )
+                    }
+
+                override fun newArray(size: Int): Array<DeviceSettingItem?> {
+                    return arrayOfNulls(size)
+                }
+            }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPreference.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPreference.java
new file mode 100644
index 0000000..790939a
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPreference.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import android.os.Parcel;
+
+import androidx.annotation.NonNull;
+
+/** An abstract class representing a device setting preference. */
+public abstract class DeviceSettingPreference {
+    @DeviceSettingType private final int mSettingType;
+
+    public static final DeviceSettingPreference UNKNOWN =
+            new DeviceSettingPreference(DeviceSettingType.DEVICE_SETTING_TYPE_UNKNOWN) {};
+
+    protected DeviceSettingPreference(@DeviceSettingType int settingType) {
+        mSettingType = settingType;
+    }
+
+    /** Read a {@link DeviceSettingPreference} instance from {@link Parcel} */
+    @NonNull
+    public static DeviceSettingPreference readFromParcel(@NonNull Parcel in) {
+        int type = in.readInt();
+        switch (type) {
+            case DeviceSettingType.DEVICE_SETTING_TYPE_ACTION_SWITCH:
+                return ActionSwitchPreference.readFromParcel(in);
+            case DeviceSettingType.DEVICE_SETTING_TYPE_MULTI_TOGGLE:
+                return MultiTogglePreference.readFromParcel(in);
+            default:
+                return UNKNOWN;
+        }
+    }
+
+    /** Writes the instance to {@link Parcel}. */
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mSettingType);
+    }
+
+    /**
+     * Gets the setting type, as defined by IntDef {@link DeviceSettingType}.
+     *
+     * @return the setting type.
+     */
+    @DeviceSettingType
+    public int getSettingType() {
+        return mSettingType;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPreferenceState.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPreferenceState.java
new file mode 100644
index 0000000..a982af7
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingPreferenceState.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import android.os.Parcel;
+
+import androidx.annotation.NonNull;
+
+/** An abstract class representing a device setting preference state. */
+public abstract class DeviceSettingPreferenceState {
+    @DeviceSettingType private final int mSettingType;
+
+    public static final DeviceSettingPreferenceState UNKNOWN =
+            new DeviceSettingPreferenceState(DeviceSettingType.DEVICE_SETTING_TYPE_UNKNOWN) {};
+
+    protected DeviceSettingPreferenceState(@DeviceSettingType int settingType) {
+        mSettingType = settingType;
+    }
+
+    /** Reads a {@link DeviceSettingPreferenceState} from {@link Parcel}. */
+    @NonNull
+    public static DeviceSettingPreferenceState readFromParcel(@NonNull Parcel in) {
+        int type = in.readInt();
+        switch (type) {
+            case DeviceSettingType.DEVICE_SETTING_TYPE_ACTION_SWITCH:
+                return ActionSwitchPreferenceState.readFromParcel(in);
+            case DeviceSettingType.DEVICE_SETTING_TYPE_MULTI_TOGGLE:
+                return MultiTogglePreferenceState.readFromParcel(in);
+            default:
+                return UNKNOWN;
+        }
+    }
+
+    /** Writes the object to parcel. */
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mSettingType);
+    }
+
+    /**
+     * Gets the setting type, as defined by IntDef {@link DeviceSettingType}.
+     *
+     * @return The setting type.
+     */
+    @DeviceSettingType
+    public int getSettingType() {
+        return mSettingType;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingState.aidl b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingState.aidl
new file mode 100644
index 0000000..61429a6
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingState.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+parcelable DeviceSettingState;
\ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingState.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingState.java
new file mode 100644
index 0000000..63fd4eb
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingState.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
+import java.util.Objects;
+
+/** A data class representing a device setting state. */
+public class DeviceSettingState implements Parcelable {
+    @DeviceSettingId private final int mSettingId;
+    private final DeviceSettingPreferenceState mPreferenceState;
+    private final Bundle mExtras;
+
+    DeviceSettingState(
+            @DeviceSettingId int settingId,
+            @NonNull DeviceSettingPreferenceState preferenceState,
+            @NonNull Bundle extras) {
+        validate(preferenceState);
+        mSettingId = settingId;
+        mPreferenceState = preferenceState;
+        mExtras = extras;
+    }
+
+    private static void validate(DeviceSettingPreferenceState preferenceState) {
+        if (Objects.isNull(preferenceState)) {
+            throw new IllegalArgumentException("PreferenceState must be set");
+        }
+    }
+
+    /** Reads a {@link DeviceSettingState} from {@link Parcel}. */
+    @NonNull
+    public static DeviceSettingState readFromParcel(@NonNull Parcel in) {
+        int settingId = in.readInt();
+        Bundle extra = in.readBundle(Bundle.class.getClassLoader());
+        DeviceSettingPreferenceState preferenceState =
+                DeviceSettingPreferenceState.readFromParcel(in);
+        return new DeviceSettingState(settingId, preferenceState, extra);
+    }
+
+    public static final Creator<DeviceSettingState> CREATOR =
+            new Creator<>() {
+                @Override
+                @NonNull
+                public DeviceSettingState createFromParcel(@NonNull Parcel in) {
+                    return readFromParcel(in);
+                }
+
+                @Override
+                @NonNull
+                public DeviceSettingState[] newArray(int size) {
+                    return new DeviceSettingState[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Writes the instance to {@link Parcel}. */
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mSettingId);
+        dest.writeBundle(mExtras);
+        mPreferenceState.writeToParcel(dest, flags);
+    }
+
+    /** Builder class for {@link DeviceSettingState}. */
+    public static final class Builder {
+        private int mSettingId;
+        private DeviceSettingPreferenceState mSettingPreferenceState;
+        private Bundle mExtras = Bundle.EMPTY;
+
+        public Builder() {}
+
+        /**
+         * Sets the setting ID, as defined by IntDef {@link DeviceSettingId}.
+         *
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setSettingId(@DeviceSettingId int settingId) {
+            mSettingId = settingId;
+            return this;
+        }
+
+        /**
+         * Sets the setting preference state.
+         *
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setPreferenceState(
+                @NonNull DeviceSettingPreferenceState settingPreferenceState) {
+            mSettingPreferenceState = settingPreferenceState;
+            return this;
+        }
+
+        /**
+         * Sets the extras bundle.
+         *
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setExtras(@NonNull Bundle extras) {
+            mExtras = extras;
+            return this;
+        }
+
+        /** Build the object. */
+        @NonNull
+        public DeviceSettingState build() {
+            return new DeviceSettingState(mSettingId, mSettingPreferenceState, mExtras);
+        }
+    }
+
+    /**
+     * Gets the setting ID, as defined by IntDef {@link DeviceSettingId}.
+     *
+     * @return the setting ID.
+     */
+    @DeviceSettingId
+    public int getSettingId() {
+        return mSettingId;
+    }
+
+    /**
+     * Gets the preference state of the setting.
+     *
+     * @return the setting preference state.
+     */
+    @NonNull
+    public DeviceSettingPreferenceState getPreferenceState() {
+        return mPreferenceState;
+    }
+
+    /**
+     * Gets the extras Bundle.
+     *
+     * @return Returns a Bundle object.
+     */
+    @NonNull
+    public Bundle getExtras() {
+        return mExtras;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingType.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingType.java
new file mode 100644
index 0000000..ee4d90f
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingType.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import androidx.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.SOURCE)
+@IntDef(
+        value = {
+            DeviceSettingType.DEVICE_SETTING_TYPE_UNKNOWN,
+            DeviceSettingType.DEVICE_SETTING_TYPE_ACTION_SWITCH,
+            DeviceSettingType.DEVICE_SETTING_TYPE_MULTI_TOGGLE,
+        },
+        open = true)
+public @interface DeviceSettingType {
+    /** Device setting type is unknown. */
+    int DEVICE_SETTING_TYPE_UNKNOWN = 0;
+
+    /** Device setting type is action/switch preference. */
+    int DEVICE_SETTING_TYPE_ACTION_SWITCH = 1;
+
+    /** Device setting type is multi-toggle preference. */
+    int DEVICE_SETTING_TYPE_MULTI_TOGGLE = 2;
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfig.aidl b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfig.aidl
new file mode 100644
index 0000000..3201d13
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfig.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+parcelable DeviceSettingsConfig;
\ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfig.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfig.kt
new file mode 100644
index 0000000..c8a2e9c
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfig.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings
+
+import android.os.Bundle
+import android.os.Parcel
+import android.os.Parcelable
+
+/**
+ * A data class representing a bluetooth device details config.
+ *
+ * @property mainContentItems The setting items to be shown in main page.
+ * @property moreSettingsItems The setting items to be shown in more settings page.
+ * @property moreSettingsFooter The footer in more settings page.
+ * @property extras Extra bundle
+ */
+data class DeviceSettingsConfig(
+    val mainContentItems: List<DeviceSettingItem>,
+    val moreSettingsItems: List<DeviceSettingItem>,
+    val moreSettingsFooter: String,
+    val extras: Bundle = Bundle.EMPTY,
+) : Parcelable {
+
+    override fun describeContents(): Int = 0
+
+    override fun writeToParcel(parcel: Parcel, flags: Int) {
+        parcel.run {
+            writeTypedList(mainContentItems)
+            writeTypedList(moreSettingsItems)
+            writeString(moreSettingsFooter)
+            writeBundle(extras)
+        }
+    }
+
+    companion object {
+        @JvmField
+        val CREATOR: Parcelable.Creator<DeviceSettingsConfig> =
+            object : Parcelable.Creator<DeviceSettingsConfig> {
+                override fun createFromParcel(parcel: Parcel): DeviceSettingsConfig =
+                    parcel.run {
+                        DeviceSettingsConfig(
+                            mainContentItems =
+                                arrayListOf<DeviceSettingItem>().also {
+                                    readTypedList(it, DeviceSettingItem.CREATOR)
+                                },
+                            moreSettingsItems =
+                                arrayListOf<DeviceSettingItem>().also {
+                                    readTypedList(it, DeviceSettingItem.CREATOR)
+                                },
+                            moreSettingsFooter = readString()!!,
+                            extras = readBundle((Bundle::class.java.classLoader))!!,
+                        )
+                    }
+
+                override fun newArray(size: Int): Array<DeviceSettingsConfig?> {
+                    return arrayOfNulls(size)
+                }
+            }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/IDeviceSettingsListener.aidl b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/IDeviceSettingsListener.aidl
new file mode 100644
index 0000000..385a780
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/IDeviceSettingsListener.aidl
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import com.android.settingslib.bluetooth.devicesettings.DeviceSetting;
+
+interface IDeviceSettingsListener {
+   oneway void onDeviceSettingsChanged(in List<DeviceSetting> settings) = 0;
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/IDeviceSettingsProviderService.aidl b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/IDeviceSettingsProviderService.aidl
new file mode 100644
index 0000000..d5efac9
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/IDeviceSettingsProviderService.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import com.android.settingslib.bluetooth.devicesettings.DeviceInfo;
+import com.android.settingslib.bluetooth.devicesettings.DeviceSettingState;
+import com.android.settingslib.bluetooth.devicesettings.IDeviceSettingsListener;
+
+oneway interface IDeviceSettingsProviderService {
+   void registerDeviceSettingsListener(in DeviceInfo device, in IDeviceSettingsListener callback);
+   void unregisterDeviceSettingsListener(in DeviceInfo device, in IDeviceSettingsListener callback);
+   void updateDeviceSettings(in DeviceInfo device, in DeviceSettingState params);
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreference.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreference.java
new file mode 100644
index 0000000..01bb6f0
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreference.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
+import com.google.common.collect.ImmutableList;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/** A data class representing a multi-toggle preference. */
+public class MultiTogglePreference extends DeviceSettingPreference implements Parcelable {
+    private final String mTitle;
+    private final ImmutableList<ToggleInfo> mToggleInfos;
+    private final int mState;
+    private final boolean mIsAllowedChangingState;
+    private final Bundle mExtras;
+
+    MultiTogglePreference(
+            @NonNull String title,
+            List<ToggleInfo> toggleInfos,
+            int state,
+            boolean allowChangingState,
+            Bundle extras) {
+        super(DeviceSettingType.DEVICE_SETTING_TYPE_MULTI_TOGGLE);
+        validate(title, state);
+        mTitle = title;
+        mToggleInfos = ImmutableList.copyOf(toggleInfos);
+        mState = state;
+        mIsAllowedChangingState = allowChangingState;
+        mExtras = extras;
+    }
+
+    private static void validate(String title, int state) {
+        if (Objects.isNull(title)) {
+            throw new IllegalArgumentException("Title must be set");
+        }
+        if (state < 0) {
+            throw new IllegalArgumentException("State must be a non-negative integer");
+        }
+    }
+
+    /** Read a {@link MultiTogglePreference} from {@link Parcel}. */
+    @NonNull
+    public static MultiTogglePreference readFromParcel(@NonNull Parcel in) {
+        String title = in.readString();
+        List<ToggleInfo> toggleInfos = new ArrayList<>();
+        in.readTypedList(toggleInfos, ToggleInfo.CREATOR);
+        int state = in.readInt();
+        boolean allowChangingState = in.readBoolean();
+        Bundle extras = in.readBundle(Bundle.class.getClassLoader());
+        return new MultiTogglePreference(title, toggleInfos, state, allowChangingState, extras);
+    }
+
+    public static final Creator<MultiTogglePreference> CREATOR =
+            new Creator<>() {
+                @Override
+                @NonNull
+                public MultiTogglePreference createFromParcel(@NonNull Parcel in) {
+                    in.readInt();
+                    return readFromParcel(in);
+                }
+
+                @Override
+                @NonNull
+                public MultiTogglePreference[] newArray(int size) {
+                    return new MultiTogglePreference[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        super.writeToParcel(dest, flags);
+        dest.writeString(mTitle);
+        dest.writeTypedList(mToggleInfos, flags);
+        dest.writeInt(mState);
+        dest.writeBoolean(mIsAllowedChangingState);
+        dest.writeBundle(mExtras);
+    }
+
+    /** Builder class for {@link MultiTogglePreference}. */
+    public static final class Builder {
+        private String mTitle;
+        private ImmutableList.Builder<ToggleInfo> mToggleInfos = new ImmutableList.Builder<>();
+        private int mState;
+        private boolean mAllowChangingState;
+        private Bundle mExtras = Bundle.EMPTY;
+
+        /**
+         * Sets the title of the preference.
+         *
+         * @param title The title of the preference.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setTitle(@NonNull String title) {
+            mTitle = title;
+            return this;
+        }
+
+        /**
+         * Adds a toggle in the preference.
+         *
+         * @param toggleInfo The toggle to add.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder addToggleInfo(@NonNull ToggleInfo toggleInfo) {
+            mToggleInfos.add(toggleInfo);
+            return this;
+        }
+
+        /**
+         * Sets the state of the preference.
+         *
+         * @param state The index of the enabled toggle.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setState(int state) {
+            mState = state;
+            return this;
+        }
+
+        /**
+         * Sets whether state can be changed by user.
+         *
+         * @param allowChangingState Whether user is allowed to change state.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setAllowChangingState(boolean allowChangingState) {
+            mAllowChangingState = allowChangingState;
+            return this;
+        }
+
+        /**
+         * Sets the extras bundle.
+         *
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setExtras(@NonNull Bundle extras) {
+            mExtras = extras;
+            return this;
+        }
+
+        /**
+         * Builds the {@link ToggleInfo} object.
+         *
+         * @return Returns the built {@link ToggleInfo} object.
+         */
+        @NonNull
+        public MultiTogglePreference build() {
+            return new MultiTogglePreference(
+                    mTitle, mToggleInfos.build(), mState, mAllowChangingState, mExtras);
+        }
+    }
+
+    /**
+     * Gets the title of the preference.
+     *
+     * @return The title.
+     */
+    @NonNull
+    public String getTitle() {
+        return mTitle;
+    }
+
+    /**
+     * Gets the state of the {@link MultiTogglePreference}.
+     *
+     * @return Returns the index of the enabled toggle.
+     */
+    public int getState() {
+        return mState;
+    }
+
+    /**
+     * Gets the toggle list in the preference.
+     *
+     * @return the toggle list.
+     */
+    @NonNull
+    public List<ToggleInfo> getToggleInfos() {
+        return mToggleInfos;
+    }
+
+    /**
+     * Gets whether the state can be changed by user.
+     *
+     * @return Whether the state can be changed by user.
+     */
+    public boolean isAllowedChangingState() {
+        return mIsAllowedChangingState;
+    }
+
+    /**
+     * Gets the extras Bundle.
+     *
+     * @return Returns a Bundle object.
+     */
+    @NonNull
+    public Bundle getExtras() {
+        return mExtras;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceState.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceState.java
new file mode 100644
index 0000000..239df0b
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceState.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
+/** A data class representing a multi-toggle preference state. */
+public class MultiTogglePreferenceState extends DeviceSettingPreferenceState implements Parcelable {
+    private final int mState;
+    private final Bundle mExtras;
+
+    MultiTogglePreferenceState(int state, @NonNull Bundle extras) {
+        super(DeviceSettingType.DEVICE_SETTING_TYPE_MULTI_TOGGLE);
+        mState = state;
+        mExtras = extras;
+    }
+
+    /** Reads a {@link MultiTogglePreferenceState} from {@link Parcel}. */
+    @NonNull
+    public static MultiTogglePreferenceState readFromParcel(@NonNull Parcel in) {
+        int state = in.readInt();
+        Bundle extras = in.readBundle(Bundle.class.getClassLoader());
+        return new MultiTogglePreferenceState(state, extras);
+    }
+
+    public static final Creator<MultiTogglePreferenceState> CREATOR =
+            new Creator<>() {
+                @Override
+                @NonNull
+                public MultiTogglePreferenceState createFromParcel(@NonNull Parcel in) {
+                    in.readInt();
+                    return readFromParcel(in);
+                }
+
+                @Override
+                @NonNull
+                public MultiTogglePreferenceState[] newArray(int size) {
+                    return new MultiTogglePreferenceState[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        super.writeToParcel(dest, flags);
+        dest.writeInt(mState);
+        dest.writeBundle(mExtras);
+    }
+
+    /** Builder class for {@link MultiTogglePreferenceState}. */
+    public static final class Builder {
+        private int mState;
+        private Bundle mExtras = Bundle.EMPTY;
+
+        public Builder() {}
+
+        /**
+         * Sets the state of {@link MultiTogglePreference}.
+         *
+         * @return Returns the index of enabled toggle.
+         */
+        @NonNull
+        public Builder setState(int state) {
+            mState = state;
+            return this;
+        }
+
+        /**
+         * Sets the extras bundle.
+         *
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setExtras(@NonNull Bundle extras) {
+            mExtras = extras;
+            return this;
+        }
+
+        /** Builds the object. */
+        @NonNull
+        public MultiTogglePreferenceState build() {
+            return new MultiTogglePreferenceState(mState, mExtras);
+        }
+    }
+
+    /**
+     * Gets the state of the {@link MultiTogglePreference}.
+     *
+     * @return Returns the index of the enabled toggle.
+     */
+    public int getState() {
+        return mState;
+    }
+
+    /**
+     * Gets the extras Bundle.
+     *
+     * @return Returns a Bundle object.
+     */
+    @NonNull
+    public Bundle getExtras() {
+        return mExtras;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ToggleInfo.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ToggleInfo.java
new file mode 100644
index 0000000..7dcf3aa
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/devicesettings/ToggleInfo.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+
+import java.util.Objects;
+
+/** A data class representing a toggle in {@link MultiTogglePreference}. */
+public class ToggleInfo implements Parcelable {
+    private final String mLabel;
+    private final Bitmap mIcon;
+    private final Bundle mExtras;
+
+    ToggleInfo(@NonNull String label, @NonNull Bitmap icon, @NonNull Bundle extras) {
+        validate(label, icon);
+        mLabel = label;
+        mIcon = icon;
+        mExtras = extras;
+    }
+
+    private static void validate(String label, Bitmap icon) {
+        if (Objects.isNull(label)) {
+            throw new IllegalArgumentException("Label must be set");
+        }
+        if (Objects.isNull(icon)) {
+            throw new IllegalArgumentException("Icon must be set");
+        }
+    }
+
+    /** Read a {@link ToggleInfo} instance from {@link Parcel}. */
+    @NonNull
+    public static ToggleInfo readFromParcel(@NonNull Parcel in) {
+        String label = in.readString();
+        Bitmap icon = in.readParcelable(Bitmap.class.getClassLoader());
+        Bundle extras = in.readBundle(Bundle.class.getClassLoader());
+        return new ToggleInfo(label, icon, extras);
+    }
+
+    public static final Creator<ToggleInfo> CREATOR =
+            new Creator<>() {
+                @Override
+                @NonNull
+                public ToggleInfo createFromParcel(@NonNull Parcel in) {
+                    return readFromParcel(in);
+                }
+
+                @Override
+                @NonNull
+                public ToggleInfo[] newArray(int size) {
+                    return new ToggleInfo[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(mLabel);
+        dest.writeParcelable(mIcon, flags);
+        dest.writeBundle(mExtras);
+    }
+
+    /** Builder class for {@link ToggleInfo}. */
+    public static final class Builder {
+        private Bitmap mIcon;
+        private String mLabel;
+        private Bundle mExtras = Bundle.EMPTY;
+
+        /**
+         * Sets the label of the toggle.
+         *
+         * @param label The label of the toggle.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setLabel(@NonNull String label) {
+            mLabel = label;
+            return this;
+        }
+
+        /**
+         * Sets the icon of the toggle.
+         *
+         * @param icon The icon of the toggle.
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setIcon(@NonNull Bitmap icon) {
+            mIcon = icon;
+            return this;
+        }
+
+        /**
+         * Sets the extras bundle.
+         *
+         * @return Returns the Builder object.
+         */
+        @NonNull
+        public Builder setExtras(@NonNull Bundle extras) {
+            mExtras = extras;
+            return this;
+        }
+
+        /**
+         * Builds the {@link ToggleInfo} object.
+         *
+         * @return Returns the built {@link ToggleInfo} object.
+         */
+        @NonNull
+        public ToggleInfo build() {
+            return new ToggleInfo(mLabel, mIcon, mExtras);
+        }
+    }
+
+    /**
+     * Gets the label of the toggle.
+     *
+     * @return the label to be shown under the toggle
+     */
+    @NonNull
+    public String getLabel() {
+        return mLabel;
+    }
+
+    /**
+     * Gets the icon of the toggle.
+     *
+     * @return the icon in toggle
+     */
+    @NonNull
+    public Bitmap getIcon() {
+        return mIcon;
+    }
+
+    /**
+     * Gets the extras Bundle.
+     *
+     * @return Returns a Bundle object.
+     */
+    @NonNull
+    public Bundle getExtras() {
+        return mExtras;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
index ea65ade..84afb9f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
@@ -25,7 +25,6 @@
 import androidx.annotation.EmptySuper;
 import androidx.annotation.NonNull;
 import androidx.annotation.RequiresApi;
-import androidx.core.os.BuildCompat;
 import androidx.lifecycle.LifecycleOwner;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceGroup;
@@ -141,7 +140,7 @@
     @RequiresApi(Build.VERSION_CODES.TIRAMISU)
     protected void replaceEnterpriseStringTitle(PreferenceScreen screen,
             String preferenceKey, String overrideKey, int resource) {
-        if (!BuildCompat.isAtLeastT() || mDevicePolicyManager == null) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || mDevicePolicyManager == null) {
             return;
         }
 
@@ -159,7 +158,7 @@
     @RequiresApi(Build.VERSION_CODES.TIRAMISU)
     protected void replaceEnterpriseStringSummary(
             PreferenceScreen screen, String preferenceKey, String overrideKey, int resource) {
-        if (!BuildCompat.isAtLeastT() || mDevicePolicyManager == null) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || mDevicePolicyManager == null) {
             return;
         }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java b/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java
index f07daa3..243403e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawable/UserIconDrawable.java
@@ -48,8 +48,6 @@
 import androidx.annotation.RequiresApi;
 import androidx.annotation.VisibleForTesting;
 
-import com.android.settingslib.utils.BuildCompatUtils;
-
 /**
  * Converts the user avatar icon to a circularly clipped one with an optional badge and frame
  */
@@ -88,7 +86,7 @@
      * @return drawable containing just the badge
      */
     public static Drawable getManagedUserDrawable(Context context) {
-        if (BuildCompatUtils.isAtLeastT()) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
             return getUpdatableManagedUserDrawable(context);
         } else {
             return getDrawableForDisplayDensity(
@@ -227,7 +225,7 @@
     }
 
     private static Drawable getManagementBadge(Context context) {
-        if (BuildCompatUtils.isAtLeastT()) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
             return getUpdatableManagementBadge(context);
         } else {
             return getDrawableForDisplayDensity(
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
index 8bdbee3..9be3159 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
@@ -16,11 +16,15 @@
 
 package com.android.settingslib.fuelgauge;
 
+import static android.provider.Settings.Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED;
+import static android.provider.Settings.Secure.LOW_POWER_WARNING_ACKNOWLEDGED;
+
 import static com.android.settingslib.fuelgauge.BatterySaverLogging.ACTION_SAVER_STATE_MANUAL_UPDATE;
 import static com.android.settingslib.fuelgauge.BatterySaverLogging.EXTRA_POWER_SAVE_MODE_MANUAL_ENABLED;
 import static com.android.settingslib.fuelgauge.BatterySaverLogging.EXTRA_POWER_SAVE_MODE_MANUAL_ENABLED_REASON;
 import static com.android.settingslib.fuelgauge.BatterySaverLogging.SaverManualEnabledReason;
 
+import android.app.KeyguardManager;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -33,6 +37,10 @@
 import android.util.Log;
 import android.util.Slog;
 
+import androidx.core.util.Function;
+
+import com.android.settingslib.flags.Flags;
+
 /**
  * Utilities related to battery saver.
  */
@@ -125,6 +133,19 @@
             Log.d(TAG, "Battery saver turning " + (enable ? "ON" : "OFF") + ", reason: " + reason);
         }
         final ContentResolver cr = context.getContentResolver();
+        final PowerManager powerManager = context.getSystemService(PowerManager.class);
+
+        if (Flags.extremePowerLowStateVulnerability()) {
+            var keyguardManager = context.getSystemService(KeyguardManager.class);
+            if (enable
+                    && needFirstTimeWarning
+                    && keyguardManager != null
+                    && keyguardManager.isDeviceLocked()) {
+                var result = powerManager.setPowerSaveModeEnabled(true);
+                Log.d(TAG, "Device is locked, setPowerSaveModeEnabled by default. " + result);
+                return result;
+            }
+        }
 
         final Bundle confirmationExtras = new Bundle(1);
         confirmationExtras.putBoolean(EXTRA_CONFIRM_TEXT_ONLY, false);
@@ -136,7 +157,7 @@
             setBatterySaverConfirmationAcknowledged(context);
         }
 
-        if (context.getSystemService(PowerManager.class).setPowerSaveModeEnabled(enable)) {
+        if (powerManager.setPowerSaveModeEnabled(enable)) {
             if (enable) {
                 final int count =
                         Secure.getInt(cr, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, 0) + 1;
@@ -173,10 +194,7 @@
      * @see #EXTRA_POWER_SAVE_MODE_TRIGGER_LEVEL
      */
     public static boolean maybeShowBatterySaverConfirmation(Context context, Bundle extras) {
-        if (Secure.getInt(context.getContentResolver(),
-                Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 0) != 0
-                && Secure.getInt(context.getContentResolver(),
-                Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, 0) != 0) {
+        if (isBatterySaverConfirmationHasBeenShowedBefore(context)) {
             // Already shown.
             return false;
         }
@@ -184,6 +202,17 @@
         return true;
     }
 
+    /**
+     * Returns {@code true} if the battery saver confirmation warning has been acknowledged by the
+     * user in the past before.
+     */
+    public static boolean isBatterySaverConfirmationHasBeenShowedBefore(Context context) {
+        Function<String, Integer> secureGetInt =
+                key -> Secure.getInt(context.getContentResolver(), key, /* def= */ 0);
+        return secureGetInt.apply(LOW_POWER_WARNING_ACKNOWLEDGED) != 0
+                && secureGetInt.apply(EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED) != 0;
+    }
+
     private static void recordBatterySaverEnabledReason(Context context, boolean enable,
             @SaverManualEnabledReason int reason) {
         final Bundle enabledReasonExtras = new Bundle(2);
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerAllowlistBackend.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerAllowlistBackend.java
index c5e86b4..4f2329b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerAllowlistBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerAllowlistBackend.java
@@ -327,4 +327,12 @@
             return sInstance;
         }
     }
+
+    /** Testing only. Reset the instance to avoid tests affecting each other. */
+    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
+    public static void resetInstance() {
+        synchronized (PowerAllowlistBackend.class) {
+            sInstance = null;
+        }
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java b/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java
index ef0f6cb..6c2bd41 100644
--- a/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java
@@ -100,9 +100,9 @@
         mCutoutHeightFraction = context.getResources().getFloat(
                 com.android.internal.R.dimen.config_signalCutoutHeightFraction);
         mDarkModeFillColor = Utils.getColorStateListDefaultColor(context,
-                R.color.dark_mode_icon_color_single_tone);
+                R.color.black);
         mLightModeFillColor = Utils.getColorStateListDefaultColor(context,
-                R.color.light_mode_icon_color_single_tone);
+                R.color.white);
         mIntrinsicSize = context.getResources().getDimensionPixelSize(R.dimen.signal_icon_size);
         mTransparentPaint.setColor(context.getColor(android.R.color.transparent));
         mTransparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
index b7758de..4e1d8e3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -671,7 +671,7 @@
     // MediaRoute2Info.getType was made public on API 34, but exists since API 30.
     @SuppressWarnings("NewApi")
     @VisibleForTesting
-    void addMediaDevice(MediaRoute2Info route, RoutingSessionInfo activeSession) {
+    void addMediaDevice(@NonNull MediaRoute2Info route, @NonNull RoutingSessionInfo activeSession) {
         final int deviceType = route.getType();
         MediaDevice mediaDevice = null;
         switch (deviceType) {
@@ -711,8 +711,13 @@
             case TYPE_HEARING_AID:
             case TYPE_BLUETOOTH_A2DP:
             case TYPE_BLE_HEADSET:
+                if (route.getAddress() == null) {
+                    Log.e(TAG, "Ignoring bluetooth route with no set address: " + route);
+                    break;
+                }
                 final BluetoothDevice device =
-                        BluetoothAdapter.getDefaultAdapter().getRemoteDevice(route.getAddress());
+                        BluetoothAdapter.getDefaultAdapter()
+                                .getRemoteDevice(route.getAddress());
                 final CachedBluetoothDevice cachedDevice =
                         mBluetoothManager.getCachedDeviceManager().findDevice(device);
                 if (cachedDevice != null) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/data/repository/AudioManagerVolumeControllerExt.kt b/packages/SettingsLib/src/com/android/settingslib/media/data/repository/AudioManagerVolumeControllerExt.kt
new file mode 100644
index 0000000..02d684d
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/media/data/repository/AudioManagerVolumeControllerExt.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.media.data.repository
+
+import android.media.AudioManager
+import android.media.IVolumeController
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.buffer
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.launch
+
+/** Returns [AudioManager.setVolumeController] events as a [Flow] */
+fun AudioManager.volumeControllerEvents(): Flow<VolumeControllerEvent> =
+    callbackFlow {
+            volumeController =
+                object : IVolumeController.Stub() {
+                    override fun displaySafeVolumeWarning(flags: Int) {
+                        launch { send(VolumeControllerEvent.DisplaySafeVolumeWarning(flags)) }
+                    }
+
+                    override fun volumeChanged(streamType: Int, flags: Int) {
+                        launch { send(VolumeControllerEvent.VolumeChanged(streamType, flags)) }
+                    }
+
+                    override fun masterMuteChanged(flags: Int) {
+                        launch { send(VolumeControllerEvent.MasterMuteChanged(flags)) }
+                    }
+
+                    override fun setLayoutDirection(layoutDirection: Int) {
+                        launch { send(VolumeControllerEvent.SetLayoutDirection(layoutDirection)) }
+                    }
+
+                    override fun dismiss() {
+                        launch { send(VolumeControllerEvent.Dismiss) }
+                    }
+
+                    override fun setA11yMode(mode: Int) {
+                        launch { send(VolumeControllerEvent.SetA11yMode(mode)) }
+                    }
+
+                    override fun displayCsdWarning(
+                        csdWarning: Int,
+                        displayDurationMs: Int,
+                    ) {
+                        launch {
+                            send(
+                                VolumeControllerEvent.DisplayCsdWarning(
+                                    csdWarning,
+                                    displayDurationMs,
+                                )
+                            )
+                        }
+                    }
+                }
+            awaitClose { volumeController = null }
+        }
+        .buffer()
+
+/** Models events received via [IVolumeController] */
+sealed interface VolumeControllerEvent {
+
+    /** @see [IVolumeController.displaySafeVolumeWarning] */
+    data class DisplaySafeVolumeWarning(val flags: Int) : VolumeControllerEvent
+
+    /** @see [IVolumeController.volumeChanged] */
+    data class VolumeChanged(val streamType: Int, val flags: Int) : VolumeControllerEvent
+
+    /** @see [IVolumeController.masterMuteChanged] */
+    data class MasterMuteChanged(val flags: Int) : VolumeControllerEvent
+
+    /** @see [IVolumeController.setLayoutDirection] */
+    data class SetLayoutDirection(val layoutDirection: Int) : VolumeControllerEvent
+
+    /** @see [IVolumeController.setA11yMode] */
+    data class SetA11yMode(val mode: Int) : VolumeControllerEvent
+
+    /** @see [IVolumeController.displayCsdWarning] */
+    data class DisplayCsdWarning(
+        val csdWarning: Int,
+        val displayDurationMs: Int,
+    ) : VolumeControllerEvent
+
+    /** @see [IVolumeController.dismiss] */
+    data object Dismiss : VolumeControllerEvent
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/DataServiceUtils.java b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/DataServiceUtils.java
index df0e618..8868837 100644
--- a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/DataServiceUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/DataServiceUtils.java
@@ -23,19 +23,8 @@
 import android.telephony.UiccSlotInfo;
 import android.telephony.UiccSlotMapping;
 
-import java.util.List;
-
 public class DataServiceUtils {
 
-    public static <T> boolean shouldUpdateEntityList(List<T> oldList, List<T> newList) {
-        if ((oldList != null &&
-                (newList.isEmpty() || !newList.equals(oldList)))
-                || (!newList.isEmpty() && oldList == null)) {
-            return true;
-        }
-        return false;
-    }
-
     /**
      * Represents columns of the MobileNetworkInfoData table, define these columns from
      * {@see MobileNetworkUtils} or relevant common APIs.
@@ -52,73 +41,16 @@
         public static final String COLUMN_ID = "subId";
 
         /**
-         * The name of the contact discovery enabled state column,
-         * {@see MobileNetworkUtils#isContactDiscoveryEnabled(Context, int)}.
-         */
-        public static final String COLUMN_IS_CONTACT_DISCOVERY_ENABLED =
-                "isContactDiscoveryEnabled";
-
-        /**
-         * The name of the contact discovery visible state column,
-         * {@see MobileNetworkUtils#isContactDiscoveryEnabled(Context, int)}.
-         */
-        public static final String COLUMN_IS_CONTACT_DISCOVERY_VISIBLE =
-                "isContactDiscoveryVisible";
-
-        /**
          * The name of the mobile network data state column,
          * {@see MobileNetworkUtils#isMobileDataEnabled(Context)}.
          */
         public static final String COLUMN_IS_MOBILE_DATA_ENABLED = "isMobileDataEnabled";
 
         /**
-         * The name of the CDMA option state column,
-         * {@see MobileNetworkUtils#isCdmaOptions(Context, int)}.
-         */
-        public static final String COLUMN_IS_CDMA_OPTIONS = "isCdmaOptions";
-
-        /**
-         * The name of the GSM option state column,
-         * {@see MobileNetworkUtils#isGsmOptions(Context, int)}.
-         */
-        public static final String COLUMN_IS_GSM_OPTIONS = "isGsmOptions";
-
-        /**
-         * The name of the world mode state column,
-         * {@see MobileNetworkUtils#isWorldMode(Context, int)}.
-         */
-        public static final String COLUMN_IS_WORLD_MODE = "isWorldMode";
-
-        /**
-         * The name of the display network select options state column,
-         * {@see MobileNetworkUtils#shouldDisplayNetworkSelectOptions(Context, int)}.
-         */
-        public static final String COLUMN_SHOULD_DISPLAY_NETWORK_SELECT_OPTIONS =
-                "shouldDisplayNetworkSelectOptions";
-
-        /**
-         * The name of the TDSCDMA supported state column,
-         * {@see MobileNetworkUtils#isTdscdmaSupported(Context, int)}.
-         */
-        public static final String COLUMN_IS_TDSCDMA_SUPPORTED = "isTdscdmaSupported";
-
-        /**
-         * The name of the active network is cellular state column,
-         * {@see MobileNetworkUtils#activeNetworkIsCellular(Context)}.
-         */
-        public static final String COLUMN_ACTIVE_NETWORK_IS_CELLULAR = "activeNetworkIsCellular";
-
-        /**
          * The name of the show toggle for physicalSim state column,
          * {@see SubscriptionUtil#showToggleForPhysicalSim(SubscriptionManager)}.
          */
         public static final String COLUMN_SHOW_TOGGLE_FOR_PHYSICAL_SIM = "showToggleForPhysicalSim";
-
-        /**
-         * The name of the subscription's data roaming state column,
-         * {@see TelephonyManager#isDataRoamingEnabled()}.
-         */
-        public static final String COLUMN_IS_DATA_ROAMING_ENABLED = "isDataRoamingEnabled";
     }
 
     /**
diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/MobileNetworkInfoEntity.java b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/MobileNetworkInfoEntity.java
index e72346d..13f99e9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/MobileNetworkInfoEntity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/mobile/dataservice/MobileNetworkInfoEntity.java
@@ -26,23 +26,11 @@
 @Entity(tableName = DataServiceUtils.MobileNetworkInfoData.TABLE_NAME)
 public class MobileNetworkInfoEntity {
 
-    public MobileNetworkInfoEntity(@NonNull String subId, boolean isContactDiscoveryEnabled,
-            boolean isContactDiscoveryVisible, boolean isMobileDataEnabled, boolean isCdmaOptions,
-            boolean isGsmOptions, boolean isWorldMode, boolean shouldDisplayNetworkSelectOptions,
-            boolean isTdscdmaSupported, boolean activeNetworkIsCellular,
-            boolean showToggleForPhysicalSim, boolean isDataRoamingEnabled) {
+    public MobileNetworkInfoEntity(@NonNull String subId, boolean isMobileDataEnabled,
+            boolean showToggleForPhysicalSim) {
         this.subId = subId;
-        this.isContactDiscoveryEnabled = isContactDiscoveryEnabled;
-        this.isContactDiscoveryVisible = isContactDiscoveryVisible;
         this.isMobileDataEnabled = isMobileDataEnabled;
-        this.isCdmaOptions = isCdmaOptions;
-        this.isGsmOptions = isGsmOptions;
-        this.isWorldMode = isWorldMode;
-        this.shouldDisplayNetworkSelectOptions = shouldDisplayNetworkSelectOptions;
-        this.isTdscdmaSupported = isTdscdmaSupported;
-        this.activeNetworkIsCellular = activeNetworkIsCellular;
         this.showToggleForPhysicalSim = showToggleForPhysicalSim;
-        this.isDataRoamingEnabled = isDataRoamingEnabled;
     }
 
     @PrimaryKey
@@ -50,55 +38,18 @@
     @NonNull
     public String subId;
 
-    @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_IS_CONTACT_DISCOVERY_ENABLED)
-    public boolean isContactDiscoveryEnabled;
-
-    @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_IS_CONTACT_DISCOVERY_VISIBLE)
-    public boolean isContactDiscoveryVisible;
-
     @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_IS_MOBILE_DATA_ENABLED)
     public boolean isMobileDataEnabled;
 
-    @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_IS_CDMA_OPTIONS)
-    public boolean isCdmaOptions;
-
-    @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_IS_GSM_OPTIONS)
-    public boolean isGsmOptions;
-
-    @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_IS_WORLD_MODE)
-    public boolean isWorldMode;
-
-    @ColumnInfo(name =
-            DataServiceUtils.MobileNetworkInfoData.COLUMN_SHOULD_DISPLAY_NETWORK_SELECT_OPTIONS)
-    public boolean shouldDisplayNetworkSelectOptions;
-
-    @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_IS_TDSCDMA_SUPPORTED)
-    public boolean isTdscdmaSupported;
-
-    @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_ACTIVE_NETWORK_IS_CELLULAR)
-    public boolean activeNetworkIsCellular;
-
     @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_SHOW_TOGGLE_FOR_PHYSICAL_SIM)
     public boolean showToggleForPhysicalSim;
 
-    @ColumnInfo(name = DataServiceUtils.MobileNetworkInfoData.COLUMN_IS_DATA_ROAMING_ENABLED)
-    public boolean isDataRoamingEnabled;
-
     @Override
     public int hashCode() {
         int result = 17;
         result = 31 * result + subId.hashCode();
-        result = 31 * result + Boolean.hashCode(isContactDiscoveryEnabled);
-        result = 31 * result + Boolean.hashCode(isContactDiscoveryVisible);
         result = 31 * result + Boolean.hashCode(isMobileDataEnabled);
-        result = 31 * result + Boolean.hashCode(isCdmaOptions);
-        result = 31 * result + Boolean.hashCode(isGsmOptions);
-        result = 31 * result + Boolean.hashCode(isWorldMode);
-        result = 31 * result + Boolean.hashCode(shouldDisplayNetworkSelectOptions);
-        result = 31 * result + Boolean.hashCode(isTdscdmaSupported);
-        result = 31 * result + Boolean.hashCode(activeNetworkIsCellular);
         result = 31 * result + Boolean.hashCode(showToggleForPhysicalSim);
-        result = 31 * result + Boolean.hashCode(isDataRoamingEnabled);
         return result;
     }
 
@@ -113,45 +64,18 @@
 
         MobileNetworkInfoEntity info = (MobileNetworkInfoEntity) obj;
         return  TextUtils.equals(subId, info.subId)
-                && isContactDiscoveryEnabled == info.isContactDiscoveryEnabled
-                && isContactDiscoveryVisible == info.isContactDiscoveryVisible
                 && isMobileDataEnabled == info.isMobileDataEnabled
-                && isCdmaOptions == info.isCdmaOptions
-                && isGsmOptions == info.isGsmOptions
-                && isWorldMode == info.isWorldMode
-                && shouldDisplayNetworkSelectOptions == info.shouldDisplayNetworkSelectOptions
-                && isTdscdmaSupported == info.isTdscdmaSupported
-                && activeNetworkIsCellular == info.activeNetworkIsCellular
-                && showToggleForPhysicalSim == info.showToggleForPhysicalSim
-                && isDataRoamingEnabled == info.isDataRoamingEnabled;
+                && showToggleForPhysicalSim == info.showToggleForPhysicalSim;
     }
 
     public String toString() {
         StringBuilder builder = new StringBuilder();
         builder.append(" {MobileNetworkInfoEntity(subId = ")
                 .append(subId)
-                .append(", isContactDiscoveryEnabled = ")
-                .append(isContactDiscoveryEnabled)
-                .append(", isContactDiscoveryVisible = ")
-                .append(isContactDiscoveryVisible)
                 .append(", isMobileDataEnabled = ")
                 .append(isMobileDataEnabled)
-                .append(", isCdmaOptions = ")
-                .append(isCdmaOptions)
-                .append(", isGsmOptions = ")
-                .append(isGsmOptions)
-                .append(", isWorldMode = ")
-                .append(isWorldMode)
-                .append(", shouldDisplayNetworkSelectOptions = ")
-                .append(shouldDisplayNetworkSelectOptions)
-                .append(", isTdscdmaSupported = ")
-                .append(isTdscdmaSupported)
                 .append(", activeNetworkIsCellular = ")
-                .append(activeNetworkIsCellular)
-                .append(", showToggleForPhysicalSim = ")
                 .append(showToggleForPhysicalSim)
-                .append(", isDataRoamingEnabled = ")
-                .append(isDataRoamingEnabled)
                 .append(")}");
         return builder.toString();
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java b/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java
deleted file mode 100644
index dfa5ed1..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.settingslib.notification;
-
-import android.app.ActivityManager;
-import android.app.AlarmManager;
-import android.app.AlertDialog;
-import android.app.Flags;
-import android.app.NotificationManager;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.net.Uri;
-import android.provider.Settings;
-import android.service.notification.Condition;
-import android.service.notification.ZenModeConfig;
-import android.text.TextUtils;
-import android.text.format.DateFormat;
-import android.util.Log;
-import android.util.Slog;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.CompoundButton;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.RadioButton;
-import android.widget.RadioGroup;
-import android.widget.ScrollView;
-import android.widget.TextView;
-
-import androidx.annotation.Nullable;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.policy.PhoneWindow;
-import com.android.settingslib.R;
-
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.Locale;
-import java.util.Objects;
-
-public class EnableZenModeDialog {
-    private static final String TAG = "EnableZenModeDialog";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    private static final int[] MINUTE_BUCKETS = ZenModeConfig.MINUTE_BUCKETS;
-    private static final int MIN_BUCKET_MINUTES = MINUTE_BUCKETS[0];
-    private static final int MAX_BUCKET_MINUTES = MINUTE_BUCKETS[MINUTE_BUCKETS.length - 1];
-    private static final int DEFAULT_BUCKET_INDEX = Arrays.binarySearch(MINUTE_BUCKETS, 60);
-
-    @VisibleForTesting
-    protected static final int FOREVER_CONDITION_INDEX = 0;
-    @VisibleForTesting
-    protected static final int COUNTDOWN_CONDITION_INDEX = 1;
-    @VisibleForTesting
-    protected static final int COUNTDOWN_ALARM_CONDITION_INDEX = 2;
-
-    private static final int SECONDS_MS = 1000;
-    private static final int MINUTES_MS = 60 * SECONDS_MS;
-
-    @Nullable
-    private final ZenModeDialogMetricsLogger mMetricsLogger;
-
-    @VisibleForTesting
-    protected Uri mForeverId;
-    private int mBucketIndex = -1;
-
-    @VisibleForTesting
-    protected NotificationManager mNotificationManager;
-    private AlarmManager mAlarmManager;
-    private int mUserId;
-    private boolean mAttached;
-
-    @VisibleForTesting
-    protected Context mContext;
-    private final int mThemeResId;
-    private final boolean mCancelIsNeutral;
-    @VisibleForTesting
-    protected TextView mZenAlarmWarning;
-    @VisibleForTesting
-    protected LinearLayout mZenRadioGroupContent;
-
-    private RadioGroup mZenRadioGroup;
-    private int MAX_MANUAL_DND_OPTIONS = 3;
-
-    @VisibleForTesting
-    protected LayoutInflater mLayoutInflater;
-
-    public EnableZenModeDialog(Context context) {
-        this(context, 0);
-    }
-
-    public EnableZenModeDialog(Context context, int themeResId) {
-        this(context, themeResId, false /* cancelIsNeutral */,
-                new ZenModeDialogMetricsLogger(context));
-    }
-
-    public EnableZenModeDialog(Context context, int themeResId, boolean cancelIsNeutral,
-            ZenModeDialogMetricsLogger metricsLogger) {
-        mContext = context;
-        mThemeResId = themeResId;
-        mCancelIsNeutral = cancelIsNeutral;
-        mMetricsLogger = metricsLogger;
-    }
-
-    public AlertDialog createDialog() {
-        mNotificationManager = (NotificationManager) mContext.
-                getSystemService(Context.NOTIFICATION_SERVICE);
-        mForeverId =  Condition.newId(mContext).appendPath("forever").build();
-        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
-        mUserId = mContext.getUserId();
-        mAttached = false;
-
-        final AlertDialog.Builder builder = new AlertDialog.Builder(mContext, mThemeResId)
-                .setTitle(R.string.zen_mode_settings_turn_on_dialog_title)
-                .setPositiveButton(R.string.zen_mode_enable_dialog_turn_on,
-                        new DialogInterface.OnClickListener() {
-                            @Override
-                            public void onClick(DialogInterface dialog, int which) {
-                                int checkedId = mZenRadioGroup.getCheckedRadioButtonId();
-                                ConditionTag tag = getConditionTagAt(checkedId);
-
-                                if (isForever(tag.condition)) {
-                                    mMetricsLogger.logOnEnableZenModeForever();
-                                } else if (isAlarm(tag.condition)) {
-                                    mMetricsLogger.logOnEnableZenModeUntilAlarm();
-                                } else if (isCountdown(tag.condition)) {
-                                    mMetricsLogger.logOnEnableZenModeUntilCountdown();
-                                } else {
-                                    Slog.d(TAG, "Invalid manual condition: " + tag.condition);
-                                }
-                                // always triggers priority-only dnd with chosen condition
-                                if (Flags.modesApi()) {
-                                    mNotificationManager.setZenMode(
-                                            Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS,
-                                            getRealConditionId(tag.condition), TAG,
-                                            /* fromUser= */ true);
-                                } else {
-                                    mNotificationManager.setZenMode(
-                                            Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS,
-                                            getRealConditionId(tag.condition), TAG);
-                                }
-                            }
-                        });
-
-        if (mCancelIsNeutral) {
-            builder.setNeutralButton(R.string.cancel, null);
-        } else {
-            builder.setNegativeButton(R.string.cancel, null);
-        }
-
-        View contentView = getContentView();
-        bindConditions(forever());
-        builder.setView(contentView);
-        return builder.create();
-    }
-
-    private void hideAllConditions() {
-        final int N = mZenRadioGroupContent.getChildCount();
-        for (int i = 0; i < N; i++) {
-            mZenRadioGroupContent.getChildAt(i).setVisibility(View.GONE);
-        }
-
-        mZenAlarmWarning.setVisibility(View.GONE);
-    }
-
-    protected View getContentView() {
-        if (mLayoutInflater == null) {
-            mLayoutInflater = new PhoneWindow(mContext).getLayoutInflater();
-        }
-        View contentView = mLayoutInflater.inflate(R.layout.zen_mode_turn_on_dialog_container,
-                null);
-        ScrollView container = (ScrollView) contentView.findViewById(R.id.container);
-
-        mZenRadioGroup = container.findViewById(R.id.zen_radio_buttons);
-        mZenRadioGroupContent = container.findViewById(R.id.zen_radio_buttons_content);
-        mZenAlarmWarning = container.findViewById(R.id.zen_alarm_warning);
-
-        for (int i = 0; i < MAX_MANUAL_DND_OPTIONS; i++) {
-            final View radioButton = mLayoutInflater.inflate(R.layout.zen_mode_radio_button,
-                    mZenRadioGroup, false);
-            mZenRadioGroup.addView(radioButton);
-            radioButton.setId(i);
-
-            final View radioButtonContent = mLayoutInflater.inflate(R.layout.zen_mode_condition,
-                    mZenRadioGroupContent, false);
-            radioButtonContent.setId(i + MAX_MANUAL_DND_OPTIONS);
-            mZenRadioGroupContent.addView(radioButtonContent);
-        }
-
-        hideAllConditions();
-        return contentView;
-    }
-
-    @VisibleForTesting
-    protected void bind(final Condition condition, final View row, final int rowId) {
-        if (condition == null) throw new IllegalArgumentException("condition must not be null");
-
-        final boolean enabled = condition.state == Condition.STATE_TRUE;
-        final ConditionTag tag = row.getTag() != null ? (ConditionTag) row.getTag() :
-                new ConditionTag();
-        row.setTag(tag);
-        final boolean first = tag.rb == null;
-        if (tag.rb == null) {
-            tag.rb = (RadioButton) mZenRadioGroup.getChildAt(rowId);
-        }
-        tag.condition = condition;
-        final Uri conditionId = getConditionId(tag.condition);
-        if (DEBUG) Log.d(TAG, "bind i=" + mZenRadioGroupContent.indexOfChild(row) + " first="
-                + first + " condition=" + conditionId);
-        tag.rb.setEnabled(enabled);
-        tag.rb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
-            @Override
-            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-                if (isChecked) {
-                    tag.rb.setChecked(true);
-                    if (DEBUG) Log.d(TAG, "onCheckedChanged " + conditionId);
-                    mMetricsLogger.logOnConditionSelected();
-                    updateAlarmWarningText(tag.condition);
-                }
-                tag.line1.setStateDescription(
-                        isChecked ? buttonView.getContext().getString(
-                                com.android.internal.R.string.selected) : null);
-            }
-        });
-
-        updateUi(tag, row, condition, enabled, rowId, conditionId);
-        row.setVisibility(View.VISIBLE);
-    }
-
-    @VisibleForTesting
-    protected ConditionTag getConditionTagAt(int index) {
-        return (ConditionTag) mZenRadioGroupContent.getChildAt(index).getTag();
-    }
-
-    @VisibleForTesting
-    protected void bindConditions(Condition c) {
-        // forever
-        bind(forever(), mZenRadioGroupContent.getChildAt(FOREVER_CONDITION_INDEX),
-                FOREVER_CONDITION_INDEX);
-        if (c == null) {
-            bindGenericCountdown();
-            bindNextAlarm(getTimeUntilNextAlarmCondition());
-        } else if (isForever(c)) {
-            getConditionTagAt(FOREVER_CONDITION_INDEX).rb.setChecked(true);
-            bindGenericCountdown();
-            bindNextAlarm(getTimeUntilNextAlarmCondition());
-        } else {
-            if (isAlarm(c)) {
-                bindGenericCountdown();
-                bindNextAlarm(c);
-                getConditionTagAt(COUNTDOWN_ALARM_CONDITION_INDEX).rb.setChecked(true);
-            } else if (isCountdown(c)) {
-                bindNextAlarm(getTimeUntilNextAlarmCondition());
-                bind(c, mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX),
-                        COUNTDOWN_CONDITION_INDEX);
-                getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.setChecked(true);
-            } else {
-                Slog.d(TAG, "Invalid manual condition: " + c);
-            }
-        }
-    }
-
-    public static Uri getConditionId(Condition condition) {
-        return condition != null ? condition.id : null;
-    }
-
-    public Condition forever() {
-        Uri foreverId = Condition.newId(mContext).appendPath("forever").build();
-        return new Condition(foreverId, foreverSummary(mContext), "", "", 0 /*icon*/,
-                Condition.STATE_TRUE, 0 /*flags*/);
-    }
-
-    public long getNextAlarm() {
-        final AlarmManager.AlarmClockInfo info = mAlarmManager.getNextAlarmClock(mUserId);
-        return info != null ? info.getTriggerTime() : 0;
-    }
-
-    @VisibleForTesting
-    protected boolean isAlarm(Condition c) {
-        return c != null && ZenModeConfig.isValidCountdownToAlarmConditionId(c.id);
-    }
-
-    @VisibleForTesting
-    protected boolean isCountdown(Condition c) {
-        return c != null && ZenModeConfig.isValidCountdownConditionId(c.id);
-    }
-
-    private boolean isForever(Condition c) {
-        return c != null && mForeverId.equals(c.id);
-    }
-
-    private Uri getRealConditionId(Condition condition) {
-        return isForever(condition) ? null : getConditionId(condition);
-    }
-
-    private String foreverSummary(Context context) {
-        return context.getString(com.android.internal.R.string.zen_mode_forever);
-    }
-
-    private static void setToMidnight(Calendar calendar) {
-        calendar.set(Calendar.HOUR_OF_DAY, 0);
-        calendar.set(Calendar.MINUTE, 0);
-        calendar.set(Calendar.SECOND, 0);
-        calendar.set(Calendar.MILLISECOND, 0);
-    }
-
-    // Returns a time condition if the next alarm is within the next week.
-    @VisibleForTesting
-    protected Condition getTimeUntilNextAlarmCondition() {
-        GregorianCalendar weekRange = new GregorianCalendar();
-        setToMidnight(weekRange);
-        weekRange.add(Calendar.DATE, 6);
-        final long nextAlarmMs = getNextAlarm();
-        if (nextAlarmMs > 0) {
-            GregorianCalendar nextAlarm = new GregorianCalendar();
-            nextAlarm.setTimeInMillis(nextAlarmMs);
-            setToMidnight(nextAlarm);
-
-            if (weekRange.compareTo(nextAlarm) >= 0) {
-                return ZenModeConfig.toNextAlarmCondition(mContext, nextAlarmMs,
-                        ActivityManager.getCurrentUser());
-            }
-        }
-        return null;
-    }
-
-    @VisibleForTesting
-    protected void bindGenericCountdown() {
-        mBucketIndex = DEFAULT_BUCKET_INDEX;
-        Condition countdown = ZenModeConfig.toTimeCondition(mContext,
-                MINUTE_BUCKETS[mBucketIndex], ActivityManager.getCurrentUser());
-        if (!mAttached || getConditionTagAt(COUNTDOWN_CONDITION_INDEX).condition == null) {
-            bind(countdown, mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX),
-                    COUNTDOWN_CONDITION_INDEX);
-        }
-    }
-
-    private void updateUi(ConditionTag tag, View row, Condition condition,
-            boolean enabled, int rowId, Uri conditionId) {
-        if (tag.lines == null) {
-            tag.lines = row.findViewById(android.R.id.content);
-        }
-        if (tag.line1 == null) {
-            tag.line1 = (TextView) row.findViewById(android.R.id.text1);
-        }
-
-        if (tag.line2 == null) {
-            tag.line2 = (TextView) row.findViewById(android.R.id.text2);
-        }
-
-        final String line1 = !TextUtils.isEmpty(condition.line1) ? condition.line1
-                : condition.summary;
-        final String line2 = condition.line2;
-        tag.line1.setText(line1);
-        if (TextUtils.isEmpty(line2)) {
-            tag.line2.setVisibility(View.GONE);
-        } else {
-            tag.line2.setVisibility(View.VISIBLE);
-            tag.line2.setText(line2);
-        }
-        tag.lines.setEnabled(enabled);
-        tag.lines.setAlpha(enabled ? 1 : .4f);
-
-        tag.lines.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                tag.rb.setChecked(true);
-            }
-        });
-
-        final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
-        final ImageView minusButton = (ImageView) row.findViewById(android.R.id.button1);
-        final ImageView plusButton = (ImageView) row.findViewById(android.R.id.button2);
-        if (rowId == COUNTDOWN_CONDITION_INDEX && time > 0) {
-            minusButton.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    onClickTimeButton(row, tag, false /*down*/, rowId);
-                    tag.lines.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
-                }
-            });
-
-            plusButton.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    onClickTimeButton(row, tag, true /*up*/, rowId);
-                    tag.lines.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
-                }
-            });
-            if (mBucketIndex > -1) {
-                minusButton.setEnabled(mBucketIndex > 0);
-                plusButton.setEnabled(mBucketIndex < MINUTE_BUCKETS.length - 1);
-            } else {
-                final long span = time - System.currentTimeMillis();
-                minusButton.setEnabled(span > MIN_BUCKET_MINUTES * MINUTES_MS);
-                final Condition maxCondition = ZenModeConfig.toTimeCondition(mContext,
-                        MAX_BUCKET_MINUTES, ActivityManager.getCurrentUser());
-                plusButton.setEnabled(!Objects.equals(condition.summary, maxCondition.summary));
-            }
-
-            minusButton.setAlpha(minusButton.isEnabled() ? 1f : .5f);
-            plusButton.setAlpha(plusButton.isEnabled() ? 1f : .5f);
-        } else {
-            if (minusButton != null) {
-                ((ViewGroup) row).removeView(minusButton);
-            }
-
-            if (plusButton != null) {
-                ((ViewGroup) row).removeView(plusButton);
-            }
-        }
-    }
-
-    @VisibleForTesting
-    protected void bindNextAlarm(Condition c) {
-        View alarmContent = mZenRadioGroupContent.getChildAt(COUNTDOWN_ALARM_CONDITION_INDEX);
-        ConditionTag tag = (ConditionTag) alarmContent.getTag();
-
-        if (c != null && (!mAttached || tag == null || tag.condition == null)) {
-            bind(c, alarmContent, COUNTDOWN_ALARM_CONDITION_INDEX);
-        }
-
-        // hide the alarm radio button if there isn't a "next alarm condition"
-        tag = (ConditionTag) alarmContent.getTag();
-        boolean showAlarm = tag != null && tag.condition != null;
-        mZenRadioGroup.getChildAt(COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(
-                showAlarm ? View.VISIBLE : View.GONE);
-        alarmContent.setVisibility(showAlarm ? View.VISIBLE : View.GONE);
-    }
-
-    private void onClickTimeButton(View row, ConditionTag tag, boolean up, int rowId) {
-        mMetricsLogger.logOnClickTimeButton(up);
-        Condition newCondition = null;
-        final int N = MINUTE_BUCKETS.length;
-        if (mBucketIndex == -1) {
-            // not on a known index, search for the next or prev bucket by time
-            final Uri conditionId = getConditionId(tag.condition);
-            final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
-            final long now = System.currentTimeMillis();
-            for (int i = 0; i < N; i++) {
-                int j = up ? i : N - 1 - i;
-                final int bucketMinutes = MINUTE_BUCKETS[j];
-                final long bucketTime = now + bucketMinutes * MINUTES_MS;
-                if (up && bucketTime > time || !up && bucketTime < time) {
-                    mBucketIndex = j;
-                    newCondition = ZenModeConfig.toTimeCondition(mContext,
-                            bucketTime, bucketMinutes, ActivityManager.getCurrentUser(),
-                            false /*shortVersion*/);
-                    break;
-                }
-            }
-            if (newCondition == null) {
-                mBucketIndex = DEFAULT_BUCKET_INDEX;
-                newCondition = ZenModeConfig.toTimeCondition(mContext,
-                        MINUTE_BUCKETS[mBucketIndex], ActivityManager.getCurrentUser());
-            }
-        } else {
-            // on a known index, simply increment or decrement
-            mBucketIndex = Math.max(0, Math.min(N - 1, mBucketIndex + (up ? 1 : -1)));
-            newCondition = ZenModeConfig.toTimeCondition(mContext,
-                    MINUTE_BUCKETS[mBucketIndex], ActivityManager.getCurrentUser());
-        }
-        bind(newCondition, row, rowId);
-        updateAlarmWarningText(tag.condition);
-        tag.rb.setChecked(true);
-    }
-
-    private void updateAlarmWarningText(Condition condition) {
-        String warningText = computeAlarmWarningText(condition);
-        mZenAlarmWarning.setText(warningText);
-        mZenAlarmWarning.setVisibility(warningText == null ? View.GONE : View.VISIBLE);
-    }
-
-    @VisibleForTesting
-    protected String computeAlarmWarningText(Condition condition) {
-        boolean allowAlarms = (mNotificationManager.getNotificationPolicy().priorityCategories
-                & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) != 0;
-
-        // don't show alarm warning if alarms are allowed to bypass dnd
-        if (allowAlarms) {
-            return null;
-        }
-
-        final long now = System.currentTimeMillis();
-        final long nextAlarm = getNextAlarm();
-        if (nextAlarm < now) {
-            return null;
-        }
-        int warningRes = 0;
-        if (condition == null || isForever(condition)) {
-            warningRes = R.string.zen_alarm_warning_indef;
-        } else {
-            final long time = ZenModeConfig.tryParseCountdownConditionId(condition.id);
-            if (time > now && nextAlarm < time) {
-                warningRes = R.string.zen_alarm_warning;
-            }
-        }
-        if (warningRes == 0) {
-            return null;
-        }
-
-        return mContext.getResources().getString(warningRes, getTime(nextAlarm, now));
-    }
-
-    @VisibleForTesting
-    protected String getTime(long nextAlarm, long now) {
-        final boolean soon = (nextAlarm - now) < 24 * 60 * 60 * 1000;
-        final boolean is24 = DateFormat.is24HourFormat(mContext, ActivityManager.getCurrentUser());
-        final String skeleton = soon ? (is24 ? "Hm" : "hma") : (is24 ? "EEEHm" : "EEEhma");
-        final String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
-        final CharSequence formattedTime = DateFormat.format(pattern, nextAlarm);
-        final int templateRes = soon ? R.string.alarm_template : R.string.alarm_template_far;
-        return mContext.getResources().getString(templateRes, formattedTime);
-    }
-
-    // used as the view tag on condition rows
-    @VisibleForTesting
-    protected static class ConditionTag {
-        public RadioButton rb;
-        public View lines;
-        public TextView line1;
-        public TextView line2;
-        public Condition condition;
-    }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java b/packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java
deleted file mode 100644
index abbdaa7..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.settingslib.notification;
-
-import android.app.ActivityManager;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.provider.Settings;
-import android.service.notification.Condition;
-import android.service.notification.ZenModeConfig;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.CompoundButton;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.RadioButton;
-import android.widget.RadioGroup;
-import android.widget.ScrollView;
-import android.widget.TextView;
-
-import androidx.annotation.VisibleForTesting;
-import androidx.appcompat.app.AlertDialog;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto;
-import com.android.internal.policy.PhoneWindow;
-import com.android.settingslib.R;
-
-import java.util.Arrays;
-
-public class ZenDurationDialog {
-    private static final int[] MINUTE_BUCKETS = ZenModeConfig.MINUTE_BUCKETS;
-    @VisibleForTesting protected static final int MIN_BUCKET_MINUTES = MINUTE_BUCKETS[0];
-    @VisibleForTesting protected static final int MAX_BUCKET_MINUTES =
-            MINUTE_BUCKETS[MINUTE_BUCKETS.length - 1];
-    private static final int DEFAULT_BUCKET_INDEX = Arrays.binarySearch(MINUTE_BUCKETS, 60);
-    @VisibleForTesting protected int mBucketIndex = -1;
-
-    @VisibleForTesting protected static final int FOREVER_CONDITION_INDEX = 0;
-    @VisibleForTesting protected static final int COUNTDOWN_CONDITION_INDEX = 1;
-    @VisibleForTesting protected static final int ALWAYS_ASK_CONDITION_INDEX = 2;
-
-    @VisibleForTesting protected Context mContext;
-    @VisibleForTesting protected LinearLayout mZenRadioGroupContent;
-    private RadioGroup mZenRadioGroup;
-    private int MAX_MANUAL_DND_OPTIONS = 3;
-
-    @VisibleForTesting protected LayoutInflater mLayoutInflater;
-
-    public ZenDurationDialog(Context context) {
-        mContext = context;
-    }
-
-    public Dialog createDialog() {
-        final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
-        setupDialog(builder);
-        return builder.create();
-    }
-
-    public void setupDialog(AlertDialog.Builder builder) {
-        int zenDuration = Settings.Secure.getInt(
-                mContext.getContentResolver(), Settings.Secure.ZEN_DURATION,
-                Settings.Secure.ZEN_DURATION_FOREVER);
-
-        builder.setTitle(R.string.zen_mode_duration_settings_title)
-                .setNegativeButton(R.string.cancel, null)
-                .setPositiveButton(R.string.okay,
-                        new DialogInterface.OnClickListener() {
-                            @Override
-                            public void onClick(DialogInterface dialog, int which) {
-                                updateZenDuration(zenDuration);
-                            }
-                        });
-
-        View contentView = getContentView();
-        setupRadioButtons(zenDuration);
-        builder.setView(contentView);
-    }
-
-    @VisibleForTesting
-    protected void updateZenDuration(int currZenDuration) {
-        final int checkedRadioButtonId = mZenRadioGroup.getCheckedRadioButtonId();
-
-        int newZenDuration = Settings.Secure.getInt(
-                mContext.getContentResolver(), Settings.Secure.ZEN_DURATION,
-                Settings.Secure.ZEN_DURATION_FOREVER);
-        switch (checkedRadioButtonId) {
-            case FOREVER_CONDITION_INDEX:
-                newZenDuration = Settings.Secure.ZEN_DURATION_FOREVER;
-                MetricsLogger.action(mContext,
-                        MetricsProto.MetricsEvent.
-                                NOTIFICATION_ZEN_MODE_DURATION_FOREVER);
-                break;
-            case COUNTDOWN_CONDITION_INDEX:
-                ConditionTag tag = getConditionTagAt(checkedRadioButtonId);
-                newZenDuration = tag.countdownZenDuration;
-                MetricsLogger.action(mContext,
-                        MetricsProto.MetricsEvent.
-                                NOTIFICATION_ZEN_MODE_DURATION_TIME,
-                        newZenDuration);
-                break;
-            case ALWAYS_ASK_CONDITION_INDEX:
-                newZenDuration = Settings.Secure.ZEN_DURATION_PROMPT;
-                MetricsLogger.action(mContext,
-                        MetricsProto.MetricsEvent.
-                                NOTIFICATION_ZEN_MODE_DURATION_PROMPT);
-                break;
-        }
-
-        if (currZenDuration != newZenDuration) {
-            Settings.Secure.putInt(mContext.getContentResolver(),
-                    Settings.Secure.ZEN_DURATION, newZenDuration);
-        }
-    }
-
-    @VisibleForTesting
-    protected View getContentView() {
-        if (mLayoutInflater == null) {
-            mLayoutInflater = new PhoneWindow(mContext).getLayoutInflater();
-        }
-        View contentView = mLayoutInflater.inflate(R.layout.zen_mode_duration_dialog,
-                null);
-        ScrollView container = (ScrollView) contentView.findViewById(R.id.zen_duration_container);
-
-        mZenRadioGroup = container.findViewById(R.id.zen_radio_buttons);
-        mZenRadioGroupContent = container.findViewById(R.id.zen_radio_buttons_content);
-
-        for (int i = 0; i < MAX_MANUAL_DND_OPTIONS; i++) {
-            final View radioButton = mLayoutInflater.inflate(R.layout.zen_mode_radio_button,
-                    mZenRadioGroup, false);
-            mZenRadioGroup.addView(radioButton);
-            radioButton.setId(i);
-
-            final View radioButtonContent = mLayoutInflater.inflate(R.layout.zen_mode_condition,
-                    mZenRadioGroupContent, false);
-            radioButtonContent.setId(i + MAX_MANUAL_DND_OPTIONS);
-            mZenRadioGroupContent.addView(radioButtonContent);
-        }
-
-        return contentView;
-    }
-
-    @VisibleForTesting
-    protected void setupRadioButtons(int zenDuration) {
-        int checkedIndex = ALWAYS_ASK_CONDITION_INDEX;
-        if (zenDuration == 0) {
-            checkedIndex = FOREVER_CONDITION_INDEX;
-        } else if (zenDuration > 0) {
-            checkedIndex = COUNTDOWN_CONDITION_INDEX;
-        }
-
-        bindTag(zenDuration, mZenRadioGroupContent.getChildAt(FOREVER_CONDITION_INDEX),
-                FOREVER_CONDITION_INDEX);
-        bindTag(zenDuration, mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX),
-                COUNTDOWN_CONDITION_INDEX);
-        bindTag(zenDuration, mZenRadioGroupContent.getChildAt(ALWAYS_ASK_CONDITION_INDEX),
-                ALWAYS_ASK_CONDITION_INDEX);
-        getConditionTagAt(checkedIndex).rb.setChecked(true);
-    }
-
-    private void bindTag(final int currZenDuration, final View row, final int rowIndex) {
-        final ConditionTag tag = row.getTag() != null ? (ConditionTag) row.getTag() :
-                new ConditionTag();
-        row.setTag(tag);
-
-        if (tag.rb == null) {
-            tag.rb = (RadioButton) mZenRadioGroup.getChildAt(rowIndex);
-        }
-
-        // if duration is set to forever or always prompt, then countdown time defaults to 1 hour
-        if (currZenDuration <= 0) {
-            tag.countdownZenDuration = MINUTE_BUCKETS[DEFAULT_BUCKET_INDEX];
-        } else {
-            tag.countdownZenDuration = currZenDuration;
-        }
-
-        tag.rb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
-            @Override
-            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-                if (isChecked) {
-                    tag.rb.setChecked(true);
-                }
-                tag.line1.setStateDescription(
-                        isChecked ? buttonView.getContext().getString(
-                                com.android.internal.R.string.selected) : null);
-            }
-        });
-
-        updateUi(tag, row, rowIndex);
-    }
-
-    @VisibleForTesting
-    protected ConditionTag getConditionTagAt(int index) {
-        return (ConditionTag) mZenRadioGroupContent.getChildAt(index).getTag();
-    }
-
-
-    private void setupUi(ConditionTag tag, View row) {
-        if (tag.lines == null) {
-            tag.lines = row.findViewById(android.R.id.content);
-        }
-
-        if (tag.line1 == null) {
-            tag.line1 = (TextView) row.findViewById(android.R.id.text1);
-        }
-
-        // text2 is not used in zen duration dialog
-        row.findViewById(android.R.id.text2).setVisibility(View.GONE);
-
-        tag.lines.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                tag.rb.setChecked(true);
-            }
-        });
-    }
-
-    private void updateButtons(ConditionTag tag, View row, int rowIndex) {
-        final ImageView minusButton = (ImageView) row.findViewById(android.R.id.button1);
-        final ImageView plusButton = (ImageView) row.findViewById(android.R.id.button2);
-        final long time = tag.countdownZenDuration;
-        if (rowIndex == COUNTDOWN_CONDITION_INDEX) {
-            minusButton.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    onClickTimeButton(row, tag, false /*down*/, rowIndex);
-                    tag.lines.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
-                }
-            });
-
-            plusButton.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    onClickTimeButton(row, tag, true /*up*/, rowIndex);
-                    tag.lines.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
-                }
-            });
-            minusButton.setVisibility(View.VISIBLE);
-            plusButton.setVisibility(View.VISIBLE);
-
-            minusButton.setEnabled(time > MIN_BUCKET_MINUTES);
-            plusButton.setEnabled(tag.countdownZenDuration != MAX_BUCKET_MINUTES);
-
-            minusButton.setAlpha(minusButton.isEnabled() ? 1f : .5f);
-            plusButton.setAlpha(plusButton.isEnabled() ? 1f : .5f);
-        } else {
-            if (minusButton != null) {
-                ((ViewGroup) row).removeView(minusButton);
-            }
-            if (plusButton != null) {
-                ((ViewGroup) row).removeView(plusButton);
-            }
-        }
-    }
-
-    @VisibleForTesting
-    protected void updateUi(ConditionTag tag, View row, int rowIndex) {
-        if (tag.lines == null) {
-            setupUi(tag, row);
-        }
-
-        updateButtons(tag, row, rowIndex);
-
-        String radioContentText = "";
-        switch (rowIndex) {
-            case FOREVER_CONDITION_INDEX:
-                radioContentText = mContext.getString(R.string.zen_mode_forever);
-                break;
-            case COUNTDOWN_CONDITION_INDEX:
-                Condition condition = ZenModeConfig.toTimeCondition(mContext,
-                        tag.countdownZenDuration, ActivityManager.getCurrentUser(), false);
-                radioContentText = condition.line1;
-                break;
-            case ALWAYS_ASK_CONDITION_INDEX:
-                radioContentText = mContext.getString(
-                        R.string.zen_mode_duration_always_prompt_title);
-                break;
-        }
-
-        tag.line1.setText(radioContentText);
-    }
-
-    @VisibleForTesting
-    protected void onClickTimeButton(View row, ConditionTag tag, boolean up, int rowId) {
-        int newDndTimeDuration = -1;
-        final int N = MINUTE_BUCKETS.length;
-        if (mBucketIndex == -1) {
-            // not on a known index, search for the next or prev bucket by time
-            final long time = tag.countdownZenDuration;
-            for (int i = 0; i < N; i++) {
-                int j = up ? i : N - 1 - i;
-                final int bucketMinutes = MINUTE_BUCKETS[j];
-                if (up && bucketMinutes > time || !up && bucketMinutes < time) {
-                    mBucketIndex = j;
-                    newDndTimeDuration = bucketMinutes;
-                    break;
-                }
-            }
-            if (newDndTimeDuration == -1) {
-                mBucketIndex = DEFAULT_BUCKET_INDEX;
-                newDndTimeDuration = MINUTE_BUCKETS[mBucketIndex];
-            }
-        } else {
-            // on a known index, simply increment or decrement
-            mBucketIndex = Math.max(0, Math.min(N - 1, mBucketIndex + (up ? 1 : -1)));
-            newDndTimeDuration = MINUTE_BUCKETS[mBucketIndex];
-        }
-        tag.countdownZenDuration = newDndTimeDuration;
-        bindTag(newDndTimeDuration, row, rowId);
-        tag.rb.setChecked(true);
-    }
-
-    // used as the view tag on condition rows
-    @VisibleForTesting
-    protected static class ConditionTag {
-        public RadioButton rb;
-        public View lines;
-        public TextView line1;
-        public int countdownZenDuration; // only important for countdown radio button
-    }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/ZenModeDialogMetricsLogger.java b/packages/SettingsLib/src/com/android/settingslib/notification/ZenModeDialogMetricsLogger.java
deleted file mode 100644
index 088a37d..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/notification/ZenModeDialogMetricsLogger.java
+++ /dev/null
@@ -1,76 +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.settingslib.notification;
-
-import android.content.Context;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto;
-
-/**
- * Logs ui events for {@link EnableZenModeDialog}.
- */
-public class ZenModeDialogMetricsLogger {
-    private final Context mContext;
-
-    public ZenModeDialogMetricsLogger(Context context) {
-        mContext = context;
-    }
-
-    /**
-     * User enabled DND from the QS DND dialog to last until manually turned off
-     */
-    public void logOnEnableZenModeForever() {
-        MetricsLogger.action(
-                mContext,
-                MetricsProto.MetricsEvent.NOTIFICATION_ZEN_MODE_TOGGLE_ON_FOREVER);
-    }
-
-    /**
-     * User enabled DND from the QS DND dialog to last until the next alarm goes off
-     */
-    public void logOnEnableZenModeUntilAlarm() {
-        MetricsLogger.action(
-                mContext,
-                MetricsProto.MetricsEvent.NOTIFICATION_ZEN_MODE_TOGGLE_ON_ALARM);
-    }
-
-    /**
-     * User enabled DND from the QS DND dialog to last until countdown is done
-     */
-    public void logOnEnableZenModeUntilCountdown() {
-        MetricsLogger.action(
-                mContext,
-                MetricsProto.MetricsEvent.NOTIFICATION_ZEN_MODE_TOGGLE_ON_COUNTDOWN);
-    }
-
-    /**
-     * User selected an option on the DND dialog
-     */
-    public void logOnConditionSelected() {
-        MetricsLogger.action(
-                mContext,
-                MetricsProto.MetricsEvent.QS_DND_CONDITION_SELECT);
-    }
-
-    /**
-     * User increased or decreased countdown duration of DND from the DND dialog
-     */
-    public void logOnClickTimeButton(boolean up) {
-        MetricsLogger.action(mContext, MetricsProto.MetricsEvent.QS_DND_TIME, up);
-    }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/ZenRadioLayout.java b/packages/SettingsLib/src/com/android/settingslib/notification/ZenRadioLayout.java
deleted file mode 100644
index 1140028..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/notification/ZenRadioLayout.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.settingslib.notification;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-
-/**
- * Specialized layout for zen mode that allows the radio buttons to reside within
- * a RadioGroup, but also makes sure that all the heights of the radio buttons align
- * with the corresponding content in the second child of this view.
- */
-public class ZenRadioLayout extends LinearLayout {
-
-    public ZenRadioLayout(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    /**
-     * Run 2 measurement passes, 1 that figures out the size of the content, and another
-     * that sets the size of the radio buttons to the heights of the corresponding content.
-     */
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-
-        ViewGroup radioGroup = (ViewGroup) getChildAt(0);
-        ViewGroup radioContent = (ViewGroup) getChildAt(1);
-        int size = radioGroup.getChildCount();
-        if (size != radioContent.getChildCount()) {
-            throw new IllegalStateException("Expected matching children");
-        }
-        boolean hasChanges = false;
-        View lastView = null;
-        for (int i = 0; i < size; i++) {
-            View radio = radioGroup.getChildAt(i);
-            View content = radioContent.getChildAt(i);
-            if (lastView != null) {
-                radio.setAccessibilityTraversalAfter(lastView.getId());
-            }
-            View contentClick = findFirstClickable(content);
-            if (contentClick != null) contentClick.setAccessibilityTraversalAfter(radio.getId());
-            lastView = findLastClickable(content);
-            if (radio.getLayoutParams().height != content.getMeasuredHeight()) {
-                hasChanges = true;
-                radio.getLayoutParams().height = content.getMeasuredHeight();
-            }
-        }
-        // Measure again if any heights changed.
-        if (hasChanges) {
-            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        }
-    }
-
-    private View findFirstClickable(View content) {
-        if (content.isClickable()) return content;
-        if (content instanceof ViewGroup) {
-            ViewGroup group = (ViewGroup) content;
-            for (int i = 0; i < group.getChildCount(); i++) {
-                View v = findFirstClickable(group.getChildAt(i));
-                if (v != null) return v;
-            }
-        }
-        return null;
-    }
-
-    private View findLastClickable(View content) {
-        if (content.isClickable()) return content;
-        if (content instanceof ViewGroup) {
-            ViewGroup group = (ViewGroup) content;
-            for (int i = group.getChildCount() - 1; i >= 0; i--) {
-                View v = findLastClickable(group.getChildAt(i));
-                if (v != null) return v;
-            }
-        }
-        return null;
-    }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/data/repository/FakeZenModeRepository.kt b/packages/SettingsLib/src/com/android/settingslib/notification/data/repository/FakeZenModeRepository.kt
new file mode 100644
index 0000000..7f6a8ed
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/data/repository/FakeZenModeRepository.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES 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.settingslib.notification.data.repository
+
+import android.app.NotificationManager
+import android.provider.Settings
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+class FakeZenModeRepository : ZenModeRepository {
+
+    private val mutableNotificationPolicy = MutableStateFlow<NotificationManager.Policy?>(null)
+    override val consolidatedNotificationPolicy: StateFlow<NotificationManager.Policy?>
+        get() = mutableNotificationPolicy.asStateFlow()
+
+    private val mutableZenMode = MutableStateFlow(Settings.Global.ZEN_MODE_OFF)
+    override val globalZenMode: StateFlow<Int>
+        get() = mutableZenMode.asStateFlow()
+
+    init {
+        updateNotificationPolicy()
+    }
+
+    fun updateNotificationPolicy(policy: NotificationManager.Policy?) {
+        mutableNotificationPolicy.value = policy
+    }
+
+    fun updateZenMode(zenMode: Int) {
+        mutableZenMode.value = zenMode
+    }
+}
+
+fun FakeZenModeRepository.updateNotificationPolicy(
+    priorityCategories: Int = 0,
+    priorityCallSenders: Int = NotificationManager.Policy.PRIORITY_SENDERS_ANY,
+    priorityMessageSenders: Int = NotificationManager.Policy.CONVERSATION_SENDERS_NONE,
+    suppressedVisualEffects: Int = NotificationManager.Policy.SUPPRESSED_EFFECTS_UNSET,
+    state: Int = NotificationManager.Policy.STATE_UNSET,
+    priorityConversationSenders: Int = NotificationManager.Policy.CONVERSATION_SENDERS_NONE,
+) =
+    updateNotificationPolicy(
+        NotificationManager.Policy(
+            priorityCategories,
+            priorityCallSenders,
+            priorityMessageSenders,
+            suppressedVisualEffects,
+            state,
+            priorityConversationSenders,
+        )
+    )
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/data/repository/ZenModeRepository.kt b/packages/SettingsLib/src/com/android/settingslib/notification/data/repository/ZenModeRepository.kt
new file mode 100644
index 0000000..273a63d
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/data/repository/ZenModeRepository.kt
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES 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.settingslib.notification.data.repository
+
+import android.app.NotificationManager
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.os.Handler
+import com.android.settingslib.flags.Flags
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.flow.shareIn
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
+
+/** Provides state of volume policy and restrictions imposed by notifications. */
+interface ZenModeRepository {
+    /** @see NotificationManager.getConsolidatedNotificationPolicy */
+    val consolidatedNotificationPolicy: StateFlow<NotificationManager.Policy?>
+
+    /** @see NotificationManager.getZenMode */
+    val globalZenMode: StateFlow<Int?>
+}
+
+class ZenModeRepositoryImpl(
+    private val context: Context,
+    private val notificationManager: NotificationManager,
+    val scope: CoroutineScope,
+    val backgroundCoroutineContext: CoroutineContext,
+    // This is nullable just to simplify testing, since SettingsLib doesn't have a good way
+    // to create a fake handler.
+    val backgroundHandler: Handler?,
+) : ZenModeRepository {
+
+    private val notificationBroadcasts =
+        callbackFlow {
+                val receiver =
+                    object : BroadcastReceiver() {
+                        override fun onReceive(context: Context?, intent: Intent?) {
+                            intent?.action?.let { action -> launch { send(action) } }
+                        }
+                    }
+
+                context.registerReceiver(
+                    receiver,
+                    IntentFilter().apply {
+                        addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED)
+                        addAction(NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED)
+                        if (Flags.volumePanelBroadcastFix() && android.app.Flags.modesApi())
+                            addAction(
+                                NotificationManager.ACTION_CONSOLIDATED_NOTIFICATION_POLICY_CHANGED)
+                    },
+                    /* broadcastPermission = */ null,
+                    /* scheduler = */ if (Flags.volumePanelBroadcastFix()) {
+                        backgroundHandler
+                    } else {
+                        null
+                    },
+                )
+
+                awaitClose { context.unregisterReceiver(receiver) }
+            }
+            .let {
+                if (Flags.volumePanelBroadcastFix()) {
+                    it.flowOn(backgroundCoroutineContext)
+                        .stateIn(scope, SharingStarted.WhileSubscribed(), null)
+                } else {
+                    it.shareIn(
+                        started = SharingStarted.WhileSubscribed(),
+                        scope = scope,
+                    )
+                }
+            }
+
+    override val consolidatedNotificationPolicy: StateFlow<NotificationManager.Policy?> =
+        if (Flags.volumePanelBroadcastFix() && android.app.Flags.modesApi())
+            flowFromBroadcast(NotificationManager.ACTION_CONSOLIDATED_NOTIFICATION_POLICY_CHANGED) {
+                notificationManager.consolidatedNotificationPolicy
+            }
+        else
+            flowFromBroadcast(NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED) {
+                notificationManager.consolidatedNotificationPolicy
+            }
+
+    override val globalZenMode: StateFlow<Int?> =
+        flowFromBroadcast(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED) {
+            notificationManager.zenMode
+        }
+
+    private fun <T> flowFromBroadcast(intentAction: String, mapper: () -> T) =
+        notificationBroadcasts
+            .filter { intentAction == it }
+            .map { mapper() }
+            .onStart { emit(mapper()) }
+            .flowOn(backgroundCoroutineContext)
+            .stateIn(scope, SharingStarted.WhileSubscribed(), null)
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/domain/interactor/NotificationsSoundPolicyInteractor.kt b/packages/SettingsLib/src/com/android/settingslib/notification/domain/interactor/NotificationsSoundPolicyInteractor.kt
new file mode 100644
index 0000000..0c2ce4f
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/domain/interactor/NotificationsSoundPolicyInteractor.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES 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.settingslib.notification.domain.interactor
+
+import android.app.NotificationManager
+import android.media.AudioManager
+import android.provider.Settings
+import android.service.notification.ZenModeConfig
+import com.android.settingslib.notification.data.repository.ZenModeRepository
+import com.android.settingslib.volume.shared.model.AudioStream
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.map
+
+/** Determines notification sounds state and limitations. */
+class NotificationsSoundPolicyInteractor(private val repository: ZenModeRepository) {
+
+    /** @see NotificationManager.getNotificationPolicy */
+    private val notificationPolicy: StateFlow<NotificationManager.Policy?>
+        get() = repository.consolidatedNotificationPolicy
+
+    /** @see NotificationManager.getZenMode */
+    val zenMode: StateFlow<Int?>
+        get() = repository.globalZenMode
+
+    /** Checks if [notificationPolicy] allows alarms. */
+    val areAlarmsAllowed: Flow<Boolean?> = notificationPolicy.map { it?.allowAlarms() }
+
+    /** Checks if [notificationPolicy] allows media. */
+    val isMediaAllowed: Flow<Boolean?> = notificationPolicy.map { it?.allowMedia() }
+
+    /** Checks if [notificationPolicy] allows system sounds. */
+    val isSystemAllowed: Flow<Boolean?> = notificationPolicy.map { it?.allowSystem() }
+
+    /** Checks if [notificationPolicy] allows ringer. */
+    val isRingerAllowed: Flow<Boolean?> =
+        notificationPolicy.map { policy ->
+            policy ?: return@map null
+            !ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(policy)
+        }
+
+    /** Checks if the [stream] is muted by either [zenMode] or [notificationPolicy]. */
+    fun isZenMuted(stream: AudioStream): Flow<Boolean> {
+        return combine(
+            zenMode.filterNotNull(),
+            areAlarmsAllowed.filterNotNull(),
+            isMediaAllowed.filterNotNull(),
+            isRingerAllowed.filterNotNull(),
+            isSystemAllowed.filterNotNull(),
+        ) { zenMode, areAlarmsAllowed, isMediaAllowed, isRingerAllowed, isSystemAllowed ->
+            when (zenMode) {
+                // Everything is muted
+                Settings.Global.ZEN_MODE_NO_INTERRUPTIONS -> return@combine true
+                Settings.Global.ZEN_MODE_ALARMS ->
+                    return@combine stream.value == AudioManager.STREAM_RING ||
+                        stream.value == AudioManager.STREAM_NOTIFICATION ||
+                        stream.value == AudioManager.STREAM_SYSTEM
+                Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS -> {
+                    when {
+                        stream.value == AudioManager.STREAM_ALARM && !areAlarmsAllowed ->
+                            return@combine true
+                        stream.value == AudioManager.STREAM_MUSIC && !isMediaAllowed ->
+                            return@combine true
+                        stream.value == AudioManager.STREAM_SYSTEM && !isSystemAllowed ->
+                            return@combine true
+                        (stream.value == AudioManager.STREAM_RING ||
+                            stream.value == AudioManager.STREAM_NOTIFICATION) && !isRingerAllowed ->
+                            return@combine true
+                    }
+                }
+            }
+            return@combine false
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/EnableZenModeDialog.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/EnableZenModeDialog.java
new file mode 100644
index 0000000..054c849
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/EnableZenModeDialog.java
@@ -0,0 +1,543 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.notification.modes;
+
+import android.app.ActivityManager;
+import android.app.AlarmManager;
+import android.app.AlertDialog;
+import android.app.Flags;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.net.Uri;
+import android.provider.Settings;
+import android.service.notification.Condition;
+import android.service.notification.ZenModeConfig;
+import android.text.TextUtils;
+import android.text.format.DateFormat;
+import android.util.Log;
+import android.util.Slog;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CompoundButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RadioButton;
+import android.widget.RadioGroup;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.policy.PhoneWindow;
+import com.android.settingslib.R;
+
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.Objects;
+
+public class EnableZenModeDialog {
+    private static final String TAG = "EnableZenModeDialog";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private static final int[] MINUTE_BUCKETS = ZenModeConfig.MINUTE_BUCKETS;
+    private static final int MIN_BUCKET_MINUTES = MINUTE_BUCKETS[0];
+    private static final int MAX_BUCKET_MINUTES = MINUTE_BUCKETS[MINUTE_BUCKETS.length - 1];
+    private static final int DEFAULT_BUCKET_INDEX = Arrays.binarySearch(MINUTE_BUCKETS, 60);
+
+    @VisibleForTesting
+    protected static final int FOREVER_CONDITION_INDEX = 0;
+    @VisibleForTesting
+    protected static final int COUNTDOWN_CONDITION_INDEX = 1;
+    @VisibleForTesting
+    protected static final int COUNTDOWN_ALARM_CONDITION_INDEX = 2;
+
+    private static final int SECONDS_MS = 1000;
+    private static final int MINUTES_MS = 60 * SECONDS_MS;
+
+    @Nullable
+    private final ZenModeDialogMetricsLogger mMetricsLogger;
+
+    @VisibleForTesting
+    protected Uri mForeverId;
+    private int mBucketIndex = -1;
+
+    @VisibleForTesting
+    protected NotificationManager mNotificationManager;
+    private AlarmManager mAlarmManager;
+    private int mUserId;
+    private boolean mAttached;
+
+    @VisibleForTesting
+    protected Context mContext;
+    private final int mThemeResId;
+    private final boolean mCancelIsNeutral;
+    @VisibleForTesting
+    protected TextView mZenAlarmWarning;
+    @VisibleForTesting
+    protected LinearLayout mZenRadioGroupContent;
+
+    private RadioGroup mZenRadioGroup;
+    private static final int MAX_MANUAL_DND_OPTIONS = 3;
+
+    @VisibleForTesting
+    protected LayoutInflater mLayoutInflater;
+
+    public EnableZenModeDialog(Context context) {
+        this(context, 0);
+    }
+
+    public EnableZenModeDialog(Context context, int themeResId) {
+        this(context, themeResId, false /* cancelIsNeutral */,
+                new ZenModeDialogMetricsLogger(context));
+    }
+
+    public EnableZenModeDialog(Context context, int themeResId, boolean cancelIsNeutral,
+            ZenModeDialogMetricsLogger metricsLogger) {
+        mContext = context;
+        mThemeResId = themeResId;
+        mCancelIsNeutral = cancelIsNeutral;
+        mMetricsLogger = metricsLogger;
+    }
+
+    public AlertDialog createDialog() {
+        mNotificationManager = (NotificationManager) mContext
+                .getSystemService(Context.NOTIFICATION_SERVICE);
+        mForeverId = Condition.newId(mContext).appendPath("forever").build();
+        mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
+        mUserId = mContext.getUserId();
+        mAttached = false;
+
+        final AlertDialog.Builder builder = new AlertDialog.Builder(mContext, mThemeResId)
+                .setTitle(R.string.zen_mode_settings_turn_on_dialog_title)
+                .setPositiveButton(R.string.zen_mode_enable_dialog_turn_on,
+                        new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int which) {
+                                int checkedId = mZenRadioGroup.getCheckedRadioButtonId();
+                                ConditionTag tag = getConditionTagAt(checkedId);
+
+                                if (isForever(tag.condition)) {
+                                    mMetricsLogger.logOnEnableZenModeForever();
+                                } else if (isAlarm(tag.condition)) {
+                                    mMetricsLogger.logOnEnableZenModeUntilAlarm();
+                                } else if (isCountdown(tag.condition)) {
+                                    mMetricsLogger.logOnEnableZenModeUntilCountdown();
+                                } else {
+                                    Slog.d(TAG, "Invalid manual condition: " + tag.condition);
+                                }
+                                // always triggers priority-only dnd with chosen condition
+                                if (Flags.modesApi()) {
+                                    mNotificationManager.setZenMode(
+                                            Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+                                            getRealConditionId(tag.condition), TAG,
+                                            /* fromUser= */ true);
+                                } else {
+                                    mNotificationManager.setZenMode(
+                                            Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+                                            getRealConditionId(tag.condition), TAG);
+                                }
+                            }
+                        });
+
+        if (mCancelIsNeutral) {
+            builder.setNeutralButton(R.string.cancel, null);
+        } else {
+            builder.setNegativeButton(R.string.cancel, null);
+        }
+
+        View contentView = getContentView();
+        bindConditions(forever());
+        builder.setView(contentView);
+        return builder.create();
+    }
+
+    private void hideAllConditions() {
+        final int n = mZenRadioGroupContent.getChildCount();
+        for (int i = 0; i < n; i++) {
+            mZenRadioGroupContent.getChildAt(i).setVisibility(View.GONE);
+        }
+
+        mZenAlarmWarning.setVisibility(View.GONE);
+    }
+
+    protected View getContentView() {
+        if (mLayoutInflater == null) {
+            mLayoutInflater = new PhoneWindow(mContext).getLayoutInflater();
+        }
+        View contentView = mLayoutInflater.inflate(R.layout.zen_mode_turn_on_dialog_container,
+                null);
+        ScrollView container = (ScrollView) contentView.findViewById(R.id.container);
+
+        mZenRadioGroup = container.findViewById(R.id.zen_radio_buttons);
+        mZenRadioGroupContent = container.findViewById(R.id.zen_radio_buttons_content);
+        mZenAlarmWarning = container.findViewById(R.id.zen_alarm_warning);
+
+        for (int i = 0; i < MAX_MANUAL_DND_OPTIONS; i++) {
+            final View radioButton = mLayoutInflater.inflate(R.layout.zen_mode_radio_button,
+                    mZenRadioGroup, false);
+            mZenRadioGroup.addView(radioButton);
+            radioButton.setId(i);
+
+            final View radioButtonContent = mLayoutInflater.inflate(R.layout.zen_mode_condition,
+                    mZenRadioGroupContent, false);
+            radioButtonContent.setId(i + MAX_MANUAL_DND_OPTIONS);
+            mZenRadioGroupContent.addView(radioButtonContent);
+        }
+
+        hideAllConditions();
+        return contentView;
+    }
+
+    @VisibleForTesting
+    protected void bind(final Condition condition, final View row, final int rowId) {
+        if (condition == null) throw new IllegalArgumentException("condition must not be null");
+
+        final boolean enabled = condition.state == Condition.STATE_TRUE;
+        final ConditionTag tag = row.getTag() != null ? (ConditionTag) row.getTag() :
+                new ConditionTag();
+        row.setTag(tag);
+        final boolean first = tag.rb == null;
+        if (tag.rb == null) {
+            tag.rb = (RadioButton) mZenRadioGroup.getChildAt(rowId);
+        }
+        tag.condition = condition;
+        final Uri conditionId = getConditionId(tag.condition);
+        if (DEBUG) {
+            Log.d(TAG, "bind i=" + mZenRadioGroupContent.indexOfChild(row) + " first="
+                    + first + " condition=" + conditionId);
+        }
+        tag.rb.setEnabled(enabled);
+        tag.rb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                if (isChecked) {
+                    tag.rb.setChecked(true);
+                    if (DEBUG) Log.d(TAG, "onCheckedChanged " + conditionId);
+                    mMetricsLogger.logOnConditionSelected();
+                    updateAlarmWarningText(tag.condition);
+                }
+                tag.line1.setStateDescription(
+                        isChecked ? buttonView.getContext().getString(
+                                com.android.internal.R.string.selected) : null);
+            }
+        });
+
+        updateUi(tag, row, condition, enabled, rowId, conditionId);
+        row.setVisibility(View.VISIBLE);
+    }
+
+    @VisibleForTesting
+    protected ConditionTag getConditionTagAt(int index) {
+        return (ConditionTag) mZenRadioGroupContent.getChildAt(index).getTag();
+    }
+
+    @VisibleForTesting
+    protected void bindConditions(Condition c) {
+        // forever
+        bind(forever(), mZenRadioGroupContent.getChildAt(FOREVER_CONDITION_INDEX),
+                FOREVER_CONDITION_INDEX);
+        if (c == null) {
+            bindGenericCountdown();
+            bindNextAlarm(getTimeUntilNextAlarmCondition());
+        } else if (isForever(c)) {
+            getConditionTagAt(FOREVER_CONDITION_INDEX).rb.setChecked(true);
+            bindGenericCountdown();
+            bindNextAlarm(getTimeUntilNextAlarmCondition());
+        } else {
+            if (isAlarm(c)) {
+                bindGenericCountdown();
+                bindNextAlarm(c);
+                getConditionTagAt(COUNTDOWN_ALARM_CONDITION_INDEX).rb.setChecked(true);
+            } else if (isCountdown(c)) {
+                bindNextAlarm(getTimeUntilNextAlarmCondition());
+                bind(c, mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX),
+                        COUNTDOWN_CONDITION_INDEX);
+                getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.setChecked(true);
+            } else {
+                Slog.d(TAG, "Invalid manual condition: " + c);
+            }
+        }
+    }
+
+    public static Uri getConditionId(Condition condition) {
+        return condition != null ? condition.id : null;
+    }
+
+    public Condition forever() {
+        Uri foreverId = Condition.newId(mContext).appendPath("forever").build();
+        return new Condition(foreverId, foreverSummary(mContext), "", "", 0 /*icon*/,
+                Condition.STATE_TRUE, 0 /*flags*/);
+    }
+
+    public long getNextAlarm() {
+        final AlarmManager.AlarmClockInfo info = mAlarmManager.getNextAlarmClock(mUserId);
+        return info != null ? info.getTriggerTime() : 0;
+    }
+
+    @VisibleForTesting
+    protected boolean isAlarm(Condition c) {
+        return c != null && ZenModeConfig.isValidCountdownToAlarmConditionId(c.id);
+    }
+
+    @VisibleForTesting
+    protected boolean isCountdown(Condition c) {
+        return c != null && ZenModeConfig.isValidCountdownConditionId(c.id);
+    }
+
+    private boolean isForever(Condition c) {
+        return c != null && mForeverId.equals(c.id);
+    }
+
+    private Uri getRealConditionId(Condition condition) {
+        return isForever(condition) ? null : getConditionId(condition);
+    }
+
+    private String foreverSummary(Context context) {
+        return context.getString(com.android.internal.R.string.zen_mode_forever);
+    }
+
+    private static void setToMidnight(Calendar calendar) {
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        calendar.set(Calendar.MILLISECOND, 0);
+    }
+
+    // Returns a time condition if the next alarm is within the next week.
+    @VisibleForTesting
+    protected Condition getTimeUntilNextAlarmCondition() {
+        GregorianCalendar weekRange = new GregorianCalendar();
+        setToMidnight(weekRange);
+        weekRange.add(Calendar.DATE, 6);
+        final long nextAlarmMs = getNextAlarm();
+        if (nextAlarmMs > 0) {
+            GregorianCalendar nextAlarm = new GregorianCalendar();
+            nextAlarm.setTimeInMillis(nextAlarmMs);
+            setToMidnight(nextAlarm);
+
+            if (weekRange.compareTo(nextAlarm) >= 0) {
+                return ZenModeConfig.toNextAlarmCondition(mContext, nextAlarmMs,
+                        ActivityManager.getCurrentUser());
+            }
+        }
+        return null;
+    }
+
+    @VisibleForTesting
+    protected void bindGenericCountdown() {
+        mBucketIndex = DEFAULT_BUCKET_INDEX;
+        Condition countdown = ZenModeConfig.toTimeCondition(mContext,
+                MINUTE_BUCKETS[mBucketIndex], ActivityManager.getCurrentUser());
+        if (!mAttached || getConditionTagAt(COUNTDOWN_CONDITION_INDEX).condition == null) {
+            bind(countdown, mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX),
+                    COUNTDOWN_CONDITION_INDEX);
+        }
+    }
+
+    private void updateUi(ConditionTag tag, View row, Condition condition,
+            boolean enabled, int rowId, Uri conditionId) {
+        if (tag.lines == null) {
+            tag.lines = row.findViewById(android.R.id.content);
+        }
+        if (tag.line1 == null) {
+            tag.line1 = (TextView) row.findViewById(android.R.id.text1);
+        }
+
+        if (tag.line2 == null) {
+            tag.line2 = (TextView) row.findViewById(android.R.id.text2);
+        }
+
+        final String line1 = !TextUtils.isEmpty(condition.line1) ? condition.line1
+                : condition.summary;
+        final String line2 = condition.line2;
+        tag.line1.setText(line1);
+        if (TextUtils.isEmpty(line2)) {
+            tag.line2.setVisibility(View.GONE);
+        } else {
+            tag.line2.setVisibility(View.VISIBLE);
+            tag.line2.setText(line2);
+        }
+        tag.lines.setEnabled(enabled);
+        tag.lines.setAlpha(enabled ? 1 : .4f);
+
+        tag.lines.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                tag.rb.setChecked(true);
+            }
+        });
+
+        final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
+        final ImageView minusButton = (ImageView) row.findViewById(android.R.id.button1);
+        final ImageView plusButton = (ImageView) row.findViewById(android.R.id.button2);
+        if (rowId == COUNTDOWN_CONDITION_INDEX && time > 0) {
+            minusButton.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    onClickTimeButton(row, tag, false /*down*/, rowId);
+                    tag.lines.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
+                }
+            });
+
+            plusButton.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    onClickTimeButton(row, tag, true /*up*/, rowId);
+                    tag.lines.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
+                }
+            });
+            if (mBucketIndex > -1) {
+                minusButton.setEnabled(mBucketIndex > 0);
+                plusButton.setEnabled(mBucketIndex < MINUTE_BUCKETS.length - 1);
+            } else {
+                final long span = time - System.currentTimeMillis();
+                minusButton.setEnabled(span > MIN_BUCKET_MINUTES * MINUTES_MS);
+                final Condition maxCondition = ZenModeConfig.toTimeCondition(mContext,
+                        MAX_BUCKET_MINUTES, ActivityManager.getCurrentUser());
+                plusButton.setEnabled(!Objects.equals(condition.summary, maxCondition.summary));
+            }
+
+            minusButton.setAlpha(minusButton.isEnabled() ? 1f : .5f);
+            plusButton.setAlpha(plusButton.isEnabled() ? 1f : .5f);
+        } else {
+            if (minusButton != null) {
+                ((ViewGroup) row).removeView(minusButton);
+            }
+
+            if (plusButton != null) {
+                ((ViewGroup) row).removeView(plusButton);
+            }
+        }
+    }
+
+    @VisibleForTesting
+    protected void bindNextAlarm(Condition c) {
+        View alarmContent = mZenRadioGroupContent.getChildAt(COUNTDOWN_ALARM_CONDITION_INDEX);
+        ConditionTag tag = (ConditionTag) alarmContent.getTag();
+
+        if (c != null && (!mAttached || tag == null || tag.condition == null)) {
+            bind(c, alarmContent, COUNTDOWN_ALARM_CONDITION_INDEX);
+        }
+
+        // hide the alarm radio button if there isn't a "next alarm condition"
+        tag = (ConditionTag) alarmContent.getTag();
+        boolean showAlarm = tag != null && tag.condition != null;
+        mZenRadioGroup.getChildAt(COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(
+                showAlarm ? View.VISIBLE : View.GONE);
+        alarmContent.setVisibility(showAlarm ? View.VISIBLE : View.GONE);
+    }
+
+    private void onClickTimeButton(View row, ConditionTag tag, boolean up, int rowId) {
+        mMetricsLogger.logOnClickTimeButton(up);
+        Condition newCondition = null;
+        final int n = MINUTE_BUCKETS.length;
+        if (mBucketIndex == -1) {
+            // not on a known index, search for the next or prev bucket by time
+            final Uri conditionId = getConditionId(tag.condition);
+            final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
+            final long now = System.currentTimeMillis();
+            for (int i = 0; i < n; i++) {
+                int j = up ? i : n - 1 - i;
+                final int bucketMinutes = MINUTE_BUCKETS[j];
+                final long bucketTime = now + bucketMinutes * MINUTES_MS;
+                if (up && bucketTime > time || !up && bucketTime < time) {
+                    mBucketIndex = j;
+                    newCondition = ZenModeConfig.toTimeCondition(mContext,
+                            bucketTime, bucketMinutes, ActivityManager.getCurrentUser(),
+                            false /*shortVersion*/);
+                    break;
+                }
+            }
+            if (newCondition == null) {
+                mBucketIndex = DEFAULT_BUCKET_INDEX;
+                newCondition = ZenModeConfig.toTimeCondition(mContext,
+                        MINUTE_BUCKETS[mBucketIndex], ActivityManager.getCurrentUser());
+            }
+        } else {
+            // on a known index, simply increment or decrement
+            mBucketIndex = Math.max(0, Math.min(n - 1, mBucketIndex + (up ? 1 : -1)));
+            newCondition = ZenModeConfig.toTimeCondition(mContext,
+                    MINUTE_BUCKETS[mBucketIndex], ActivityManager.getCurrentUser());
+        }
+        bind(newCondition, row, rowId);
+        updateAlarmWarningText(tag.condition);
+        tag.rb.setChecked(true);
+    }
+
+    private void updateAlarmWarningText(Condition condition) {
+        String warningText = computeAlarmWarningText(condition);
+        mZenAlarmWarning.setText(warningText);
+        mZenAlarmWarning.setVisibility(warningText == null ? View.GONE : View.VISIBLE);
+    }
+
+    @VisibleForTesting
+    protected String computeAlarmWarningText(Condition condition) {
+        boolean allowAlarms = (mNotificationManager.getNotificationPolicy().priorityCategories
+                & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) != 0;
+
+        // don't show alarm warning if alarms are allowed to bypass dnd
+        if (allowAlarms) {
+            return null;
+        }
+
+        final long now = System.currentTimeMillis();
+        final long nextAlarm = getNextAlarm();
+        if (nextAlarm < now) {
+            return null;
+        }
+        int warningRes = 0;
+        if (condition == null || isForever(condition)) {
+            warningRes = R.string.zen_alarm_warning_indef;
+        } else {
+            final long time = ZenModeConfig.tryParseCountdownConditionId(condition.id);
+            if (time > now && nextAlarm < time) {
+                warningRes = R.string.zen_alarm_warning;
+            }
+        }
+        if (warningRes == 0) {
+            return null;
+        }
+
+        return mContext.getResources().getString(warningRes, getTime(nextAlarm, now));
+    }
+
+    @VisibleForTesting
+    protected String getTime(long nextAlarm, long now) {
+        final boolean soon = (nextAlarm - now) < 24 * 60 * 60 * 1000;
+        final boolean is24 = DateFormat.is24HourFormat(mContext, ActivityManager.getCurrentUser());
+        final String skeleton = soon ? (is24 ? "Hm" : "hma") : (is24 ? "EEEHm" : "EEEhma");
+        final String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
+        final CharSequence formattedTime = DateFormat.format(pattern, nextAlarm);
+        final int templateRes = soon ? R.string.alarm_template : R.string.alarm_template_far;
+        return mContext.getResources().getString(templateRes, formattedTime);
+    }
+
+    // used as the view tag on condition rows
+    @VisibleForTesting
+    protected static class ConditionTag {
+        public RadioButton rb;
+        public View lines;
+        public TextView line1;
+        public TextView line2;
+        public Condition condition;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenDurationDialog.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenDurationDialog.java
new file mode 100644
index 0000000..98c3edb
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenDurationDialog.java
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.notification.modes;
+
+import android.app.ActivityManager;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.provider.Settings;
+import android.service.notification.Condition;
+import android.service.notification.ZenModeConfig;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CompoundButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RadioButton;
+import android.widget.RadioGroup;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.appcompat.app.AlertDialog;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.internal.policy.PhoneWindow;
+import com.android.settingslib.R;
+
+import java.util.Arrays;
+
+public class ZenDurationDialog {
+    private static final int[] MINUTE_BUCKETS = ZenModeConfig.MINUTE_BUCKETS;
+    @VisibleForTesting
+    protected static final int MIN_BUCKET_MINUTES = MINUTE_BUCKETS[0];
+    @VisibleForTesting
+    protected static final int MAX_BUCKET_MINUTES =
+            MINUTE_BUCKETS[MINUTE_BUCKETS.length - 1];
+    private static final int DEFAULT_BUCKET_INDEX = Arrays.binarySearch(MINUTE_BUCKETS, 60);
+    @VisibleForTesting
+    protected int mBucketIndex = -1;
+
+    @VisibleForTesting
+    protected static final int FOREVER_CONDITION_INDEX = 0;
+    @VisibleForTesting
+    protected static final int COUNTDOWN_CONDITION_INDEX = 1;
+    @VisibleForTesting
+    protected static final int ALWAYS_ASK_CONDITION_INDEX = 2;
+
+    @VisibleForTesting
+    protected Context mContext;
+    @VisibleForTesting
+    protected LinearLayout mZenRadioGroupContent;
+    private RadioGroup mZenRadioGroup;
+    private static final int MAX_MANUAL_DND_OPTIONS = 3;
+
+    @VisibleForTesting
+    protected LayoutInflater mLayoutInflater;
+
+    public ZenDurationDialog(Context context) {
+        mContext = context;
+    }
+
+    public Dialog createDialog() {
+        final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
+        setupDialog(builder);
+        return builder.create();
+    }
+
+    public void setupDialog(AlertDialog.Builder builder) {
+        int zenDuration = Settings.Secure.getInt(
+                mContext.getContentResolver(), Settings.Secure.ZEN_DURATION,
+                Settings.Secure.ZEN_DURATION_FOREVER);
+
+        builder.setTitle(R.string.zen_mode_duration_settings_title)
+                .setNegativeButton(R.string.cancel, null)
+                .setPositiveButton(R.string.okay,
+                        new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int which) {
+                                updateZenDuration(zenDuration);
+                            }
+                        });
+
+        View contentView = getContentView();
+        setupRadioButtons(zenDuration);
+        builder.setView(contentView);
+    }
+
+    @VisibleForTesting
+    protected void updateZenDuration(int currZenDuration) {
+        final int checkedRadioButtonId = mZenRadioGroup.getCheckedRadioButtonId();
+
+        int newZenDuration = Settings.Secure.getInt(
+                mContext.getContentResolver(), Settings.Secure.ZEN_DURATION,
+                Settings.Secure.ZEN_DURATION_FOREVER);
+        switch (checkedRadioButtonId) {
+            case FOREVER_CONDITION_INDEX:
+                newZenDuration = Settings.Secure.ZEN_DURATION_FOREVER;
+                MetricsLogger.action(mContext,
+                        MetricsProto.MetricsEvent
+                                .NOTIFICATION_ZEN_MODE_DURATION_FOREVER);
+                break;
+            case COUNTDOWN_CONDITION_INDEX:
+                ConditionTag tag = getConditionTagAt(checkedRadioButtonId);
+                newZenDuration = tag.countdownZenDuration;
+                MetricsLogger.action(mContext,
+                        MetricsProto.MetricsEvent
+                                .NOTIFICATION_ZEN_MODE_DURATION_TIME,
+                        newZenDuration);
+                break;
+            case ALWAYS_ASK_CONDITION_INDEX:
+                newZenDuration = Settings.Secure.ZEN_DURATION_PROMPT;
+                MetricsLogger.action(mContext,
+                        MetricsProto.MetricsEvent
+                                .NOTIFICATION_ZEN_MODE_DURATION_PROMPT);
+                break;
+        }
+
+        if (currZenDuration != newZenDuration) {
+            Settings.Secure.putInt(mContext.getContentResolver(),
+                    Settings.Secure.ZEN_DURATION, newZenDuration);
+        }
+    }
+
+    @VisibleForTesting
+    protected View getContentView() {
+        if (mLayoutInflater == null) {
+            mLayoutInflater = new PhoneWindow(mContext).getLayoutInflater();
+        }
+        View contentView = mLayoutInflater.inflate(R.layout.zen_mode_duration_dialog,
+                null);
+        ScrollView container = (ScrollView) contentView.findViewById(R.id.zen_duration_container);
+
+        mZenRadioGroup = container.findViewById(R.id.zen_radio_buttons);
+        mZenRadioGroupContent = container.findViewById(R.id.zen_radio_buttons_content);
+
+        for (int i = 0; i < MAX_MANUAL_DND_OPTIONS; i++) {
+            final View radioButton = mLayoutInflater.inflate(R.layout.zen_mode_radio_button,
+                    mZenRadioGroup, false);
+            mZenRadioGroup.addView(radioButton);
+            radioButton.setId(i);
+
+            final View radioButtonContent = mLayoutInflater.inflate(R.layout.zen_mode_condition,
+                    mZenRadioGroupContent, false);
+            radioButtonContent.setId(i + MAX_MANUAL_DND_OPTIONS);
+            mZenRadioGroupContent.addView(radioButtonContent);
+        }
+
+        return contentView;
+    }
+
+    @VisibleForTesting
+    protected void setupRadioButtons(int zenDuration) {
+        int checkedIndex = ALWAYS_ASK_CONDITION_INDEX;
+        if (zenDuration == 0) {
+            checkedIndex = FOREVER_CONDITION_INDEX;
+        } else if (zenDuration > 0) {
+            checkedIndex = COUNTDOWN_CONDITION_INDEX;
+        }
+
+        bindTag(zenDuration, mZenRadioGroupContent.getChildAt(FOREVER_CONDITION_INDEX),
+                FOREVER_CONDITION_INDEX);
+        bindTag(zenDuration, mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX),
+                COUNTDOWN_CONDITION_INDEX);
+        bindTag(zenDuration, mZenRadioGroupContent.getChildAt(ALWAYS_ASK_CONDITION_INDEX),
+                ALWAYS_ASK_CONDITION_INDEX);
+        getConditionTagAt(checkedIndex).rb.setChecked(true);
+    }
+
+    private void bindTag(final int currZenDuration, final View row, final int rowIndex) {
+        final ConditionTag tag = row.getTag() != null ? (ConditionTag) row.getTag() :
+                new ConditionTag();
+        row.setTag(tag);
+
+        if (tag.rb == null) {
+            tag.rb = (RadioButton) mZenRadioGroup.getChildAt(rowIndex);
+        }
+
+        // if duration is set to forever or always prompt, then countdown time defaults to 1 hour
+        if (currZenDuration <= 0) {
+            tag.countdownZenDuration = MINUTE_BUCKETS[DEFAULT_BUCKET_INDEX];
+        } else {
+            tag.countdownZenDuration = currZenDuration;
+        }
+
+        tag.rb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                if (isChecked) {
+                    tag.rb.setChecked(true);
+                }
+                tag.line1.setStateDescription(
+                        isChecked ? buttonView.getContext().getString(
+                                com.android.internal.R.string.selected) : null);
+            }
+        });
+
+        updateUi(tag, row, rowIndex);
+    }
+
+    @VisibleForTesting
+    protected ConditionTag getConditionTagAt(int index) {
+        return (ConditionTag) mZenRadioGroupContent.getChildAt(index).getTag();
+    }
+
+
+    private void setupUi(ConditionTag tag, View row) {
+        if (tag.lines == null) {
+            tag.lines = row.findViewById(android.R.id.content);
+        }
+
+        if (tag.line1 == null) {
+            tag.line1 = (TextView) row.findViewById(android.R.id.text1);
+        }
+
+        // text2 is not used in zen duration dialog
+        row.findViewById(android.R.id.text2).setVisibility(View.GONE);
+
+        tag.lines.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                tag.rb.setChecked(true);
+            }
+        });
+    }
+
+    private void updateButtons(ConditionTag tag, View row, int rowIndex) {
+        final ImageView minusButton = (ImageView) row.findViewById(android.R.id.button1);
+        final ImageView plusButton = (ImageView) row.findViewById(android.R.id.button2);
+        final long time = tag.countdownZenDuration;
+        if (rowIndex == COUNTDOWN_CONDITION_INDEX) {
+            minusButton.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    onClickTimeButton(row, tag, false /*down*/, rowIndex);
+                    tag.lines.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
+                }
+            });
+
+            plusButton.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    onClickTimeButton(row, tag, true /*up*/, rowIndex);
+                    tag.lines.setAccessibilityLiveRegion(View.ACCESSIBILITY_LIVE_REGION_POLITE);
+                }
+            });
+            minusButton.setVisibility(View.VISIBLE);
+            plusButton.setVisibility(View.VISIBLE);
+
+            minusButton.setEnabled(time > MIN_BUCKET_MINUTES);
+            plusButton.setEnabled(tag.countdownZenDuration != MAX_BUCKET_MINUTES);
+
+            minusButton.setAlpha(minusButton.isEnabled() ? 1f : .5f);
+            plusButton.setAlpha(plusButton.isEnabled() ? 1f : .5f);
+        } else {
+            if (minusButton != null) {
+                ((ViewGroup) row).removeView(minusButton);
+            }
+            if (plusButton != null) {
+                ((ViewGroup) row).removeView(plusButton);
+            }
+        }
+    }
+
+    @VisibleForTesting
+    protected void updateUi(ConditionTag tag, View row, int rowIndex) {
+        if (tag.lines == null) {
+            setupUi(tag, row);
+        }
+
+        updateButtons(tag, row, rowIndex);
+
+        String radioContentText = "";
+        switch (rowIndex) {
+            case FOREVER_CONDITION_INDEX:
+                radioContentText = mContext.getString(R.string.zen_mode_forever);
+                break;
+            case COUNTDOWN_CONDITION_INDEX:
+                Condition condition = ZenModeConfig.toTimeCondition(mContext,
+                        tag.countdownZenDuration, ActivityManager.getCurrentUser(), false);
+                radioContentText = condition.line1;
+                break;
+            case ALWAYS_ASK_CONDITION_INDEX:
+                radioContentText = mContext.getString(
+                        R.string.zen_mode_duration_always_prompt_title);
+                break;
+        }
+
+        tag.line1.setText(radioContentText);
+    }
+
+    @VisibleForTesting
+    protected void onClickTimeButton(View row, ConditionTag tag, boolean up, int rowId) {
+        int newDndTimeDuration = -1;
+        final int n = MINUTE_BUCKETS.length;
+        if (mBucketIndex == -1) {
+            // not on a known index, search for the next or prev bucket by time
+            final long time = tag.countdownZenDuration;
+            for (int i = 0; i < n; i++) {
+                int j = up ? i : n - 1 - i;
+                final int bucketMinutes = MINUTE_BUCKETS[j];
+                if (up && bucketMinutes > time || !up && bucketMinutes < time) {
+                    mBucketIndex = j;
+                    newDndTimeDuration = bucketMinutes;
+                    break;
+                }
+            }
+            if (newDndTimeDuration == -1) {
+                mBucketIndex = DEFAULT_BUCKET_INDEX;
+                newDndTimeDuration = MINUTE_BUCKETS[mBucketIndex];
+            }
+        } else {
+            // on a known index, simply increment or decrement
+            mBucketIndex = Math.max(0, Math.min(n - 1, mBucketIndex + (up ? 1 : -1)));
+            newDndTimeDuration = MINUTE_BUCKETS[mBucketIndex];
+        }
+        tag.countdownZenDuration = newDndTimeDuration;
+        bindTag(newDndTimeDuration, row, rowId);
+        tag.rb.setChecked(true);
+    }
+
+    // used as the view tag on condition rows
+    @VisibleForTesting
+    protected static class ConditionTag {
+        public RadioButton rb;
+        public View lines;
+        public TextView line1;
+        public int countdownZenDuration; // only important for countdown radio button
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconLoader.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconLoader.java
new file mode 100644
index 0000000..960df63
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenIconLoader.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.notification.modes;
+
+import static com.google.common.util.concurrent.Futures.immediateFuture;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.DrawableRes;
+import android.annotation.Nullable;
+import android.app.AutomaticZenRule;
+import android.content.Context;
+import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.InsetDrawable;
+import android.service.notification.SystemZenRules;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.LruCache;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.appcompat.content.res.AppCompatResources;
+
+import com.google.common.util.concurrent.FluentFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class ZenIconLoader {
+
+    private static final String TAG = "ZenIconLoader";
+
+    private static final Drawable MISSING = new ColorDrawable();
+
+    @Nullable // Until first usage
+    private static ZenIconLoader sInstance;
+
+    private final LruCache<String, Drawable> mCache;
+    private final ListeningExecutorService mBackgroundExecutor;
+
+    public static ZenIconLoader getInstance() {
+        if (sInstance == null) {
+            sInstance = new ZenIconLoader();
+        }
+        return sInstance;
+    }
+
+    private ZenIconLoader() {
+        this(Executors.newFixedThreadPool(4));
+    }
+
+    @VisibleForTesting
+    ZenIconLoader(ExecutorService backgroundExecutor) {
+        mCache = new LruCache<>(50);
+        mBackgroundExecutor =
+                MoreExecutors.listeningDecorator(backgroundExecutor);
+    }
+
+    @NonNull
+    ListenableFuture<Drawable> getIcon(Context context, @NonNull AutomaticZenRule rule) {
+        if (rule.getIconResId() == 0) {
+            return Futures.immediateFuture(getFallbackIcon(context, rule.getType()));
+        }
+
+        return FluentFuture.from(loadIcon(context, rule.getPackageName(), rule.getIconResId()))
+                .transform(icon ->
+                                icon != null ? icon : getFallbackIcon(context, rule.getType()),
+                        MoreExecutors.directExecutor());
+    }
+
+    @NonNull
+    private ListenableFuture</* @Nullable */ Drawable> loadIcon(Context context, String pkg,
+            int iconResId) {
+        String cacheKey = pkg + ":" + iconResId;
+        synchronized (mCache) {
+            Drawable cachedValue = mCache.get(cacheKey);
+            if (cachedValue != null) {
+                return immediateFuture(cachedValue != MISSING ? cachedValue : null);
+            }
+        }
+
+        return FluentFuture.from(mBackgroundExecutor.submit(() -> {
+            if (TextUtils.isEmpty(pkg) || SystemZenRules.PACKAGE_ANDROID.equals(pkg)) {
+                return context.getDrawable(iconResId);
+            } else {
+                Context appContext = context.createPackageContext(pkg, 0);
+                Drawable appDrawable = AppCompatResources.getDrawable(appContext, iconResId);
+                return getMonochromeIconIfPresent(appDrawable);
+            }
+        })).catching(Exception.class, ex -> {
+            // If we cannot resolve the icon, then store MISSING in the cache below, so
+            // we don't try again.
+            Log.e(TAG, "Error while loading icon " + cacheKey, ex);
+            return null;
+        }, MoreExecutors.directExecutor()).transform(drawable -> {
+            synchronized (mCache) {
+                mCache.put(cacheKey, drawable != null ? drawable : MISSING);
+            }
+            return drawable;
+        }, MoreExecutors.directExecutor());
+    }
+
+    private static Drawable getFallbackIcon(Context context, int ruleType) {
+        int iconResIdFromType = getIconResourceIdFromType(ruleType);
+        return requireNonNull(context.getDrawable(iconResIdFromType));
+    }
+
+    /** Return the default icon resource associated to a {@link AutomaticZenRule.Type} */
+    @DrawableRes
+    public static int getIconResourceIdFromType(@AutomaticZenRule.Type int ruleType) {
+        return switch (ruleType) {
+            case AutomaticZenRule.TYPE_UNKNOWN ->
+                    com.android.internal.R.drawable.ic_zen_mode_type_unknown;
+            case AutomaticZenRule.TYPE_OTHER ->
+                    com.android.internal.R.drawable.ic_zen_mode_type_other;
+            case AutomaticZenRule.TYPE_SCHEDULE_TIME ->
+                    com.android.internal.R.drawable.ic_zen_mode_type_schedule_time;
+            case AutomaticZenRule.TYPE_SCHEDULE_CALENDAR ->
+                    com.android.internal.R.drawable.ic_zen_mode_type_schedule_calendar;
+            case AutomaticZenRule.TYPE_BEDTIME ->
+                    com.android.internal.R.drawable.ic_zen_mode_type_bedtime;
+            case AutomaticZenRule.TYPE_DRIVING ->
+                    com.android.internal.R.drawable.ic_zen_mode_type_driving;
+            case AutomaticZenRule.TYPE_IMMERSIVE ->
+                    com.android.internal.R.drawable.ic_zen_mode_type_immersive;
+            case AutomaticZenRule.TYPE_THEATER ->
+                    com.android.internal.R.drawable.ic_zen_mode_type_theater;
+            case AutomaticZenRule.TYPE_MANAGED ->
+                    com.android.internal.R.drawable.ic_zen_mode_type_managed;
+            default -> com.android.internal.R.drawable.ic_zen_mode_type_unknown;
+        };
+    }
+
+    private static Drawable getMonochromeIconIfPresent(Drawable icon) {
+        // For created rules, the app should've provided a monochrome Drawable. However, implicit
+        // rules have the app's icon, which is not -- but might have a monochrome layer. Thus
+        // we choose it, if present.
+        if (icon instanceof AdaptiveIconDrawable adaptiveIcon) {
+            if (adaptiveIcon.getMonochrome() != null) {
+                // Wrap with negative inset => scale icon (inspired from BaseIconFactory)
+                return new InsetDrawable(adaptiveIcon.getMonochrome(),
+                        -2.0f * AdaptiveIconDrawable.getExtraInsetFraction());
+            }
+        }
+        return icon;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java
new file mode 100644
index 0000000..2cc9112
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.notification.modes;
+
+import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
+import static android.service.notification.SystemZenRules.getTriggerDescriptionForScheduleEvent;
+import static android.service.notification.SystemZenRules.getTriggerDescriptionForScheduleTime;
+import static android.service.notification.ZenModeConfig.tryParseEventConditionId;
+import static android.service.notification.ZenModeConfig.tryParseScheduleConditionId;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.SuppressLint;
+import android.app.AutomaticZenRule;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.service.notification.SystemZenRules;
+import android.service.notification.ZenDeviceEffects;
+import android.service.notification.ZenModeConfig;
+import android.service.notification.ZenPolicy;
+import android.util.Log;
+
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.settingslib.R;
+
+import com.google.common.base.Strings;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
+import java.util.Objects;
+
+/**
+ * Represents either an {@link AutomaticZenRule} or the manual DND rule in a unified way.
+ *
+ * <p>It also adapts other rule features that we don't want to expose in the UI, such as
+ * interruption filters other than {@code PRIORITY}, rules without specific icons, etc.
+ */
+public class ZenMode implements Parcelable {
+
+    private static final String TAG = "ZenMode";
+
+    static final String MANUAL_DND_MODE_ID = "manual_dnd";
+    static final String TEMP_NEW_MODE_ID = "temp_new_mode";
+
+    // Must match com.android.server.notification.ZenModeHelper#applyCustomPolicy.
+    private static final ZenPolicy POLICY_INTERRUPTION_FILTER_ALARMS =
+            new ZenPolicy.Builder()
+                    .disallowAllSounds()
+                    .allowAlarms(true)
+                    .allowMedia(true)
+                    .allowPriorityChannels(false)
+                    .build();
+
+    // Must match com.android.server.notification.ZenModeHelper#applyCustomPolicy.
+    private static final ZenPolicy POLICY_INTERRUPTION_FILTER_NONE =
+            new ZenPolicy.Builder()
+                    .disallowAllSounds()
+                    .hideAllVisualEffects()
+                    .allowPriorityChannels(false)
+                    .build();
+
+    public enum Status {
+        ENABLED,
+        ENABLED_AND_ACTIVE,
+        DISABLED_BY_USER,
+        DISABLED_BY_OTHER
+    }
+
+    private final String mId;
+    private final AutomaticZenRule mRule;
+    private final Status mStatus;
+    private final boolean mIsManualDnd;
+
+    /**
+     * Initializes a {@link ZenMode}, mainly based on the information from the
+     * {@link AutomaticZenRule}.
+     *
+     * <p>Some pieces which are not part of the public API (such as whether the mode is currently
+     * active, or the reason it was disabled) are read from the {@link ZenModeConfig.ZenRule} --
+     * see {@link #computeStatus}.
+     */
+    public ZenMode(String id, @NonNull AutomaticZenRule rule,
+            @NonNull ZenModeConfig.ZenRule zenRuleExtraData) {
+        this(id, rule, computeStatus(zenRuleExtraData), false);
+    }
+
+    private static Status computeStatus(@NonNull ZenModeConfig.ZenRule zenRuleExtraData) {
+        if (zenRuleExtraData.enabled) {
+            if (zenRuleExtraData.isAutomaticActive()) {
+                return Status.ENABLED_AND_ACTIVE;
+            } else {
+                return Status.ENABLED;
+            }
+        } else {
+            if (zenRuleExtraData.disabledOrigin == ZenModeConfig.UPDATE_ORIGIN_USER) {
+                return Status.DISABLED_BY_USER;
+            } else {
+                return Status.DISABLED_BY_OTHER; // by APP, SYSTEM, UNKNOWN.
+            }
+        }
+    }
+
+    public static ZenMode manualDndMode(AutomaticZenRule manualRule, boolean isActive) {
+        return new ZenMode(MANUAL_DND_MODE_ID, manualRule,
+                isActive ? Status.ENABLED_AND_ACTIVE : Status.ENABLED, true);
+    }
+
+    /**
+     * Returns a new {@link ZenMode} instance that can represent a custom_manual mode that is in the
+     * process of being created (and not yet saved).
+     *
+     * @param name mode name
+     * @param iconResId resource id of the chosen icon, {code 0} if none.
+     */
+    public static ZenMode newCustomManual(String name, @DrawableRes int iconResId) {
+        AutomaticZenRule rule = new AutomaticZenRule.Builder(name,
+                ZenModeConfig.toCustomManualConditionId())
+                .setPackage(ZenModeConfig.getCustomManualConditionProvider().getPackageName())
+                .setType(AutomaticZenRule.TYPE_OTHER)
+                .setOwner(ZenModeConfig.getCustomManualConditionProvider())
+                .setIconResId(iconResId)
+                .setManualInvocationAllowed(true)
+                .build();
+        return new ZenMode(TEMP_NEW_MODE_ID, rule, Status.ENABLED, false);
+    }
+
+    private ZenMode(String id, @NonNull AutomaticZenRule rule, Status status, boolean isManualDnd) {
+        mId = id;
+        mRule = rule;
+        mStatus = status;
+        mIsManualDnd = isManualDnd;
+    }
+
+    @NonNull
+    public String getId() {
+        return mId;
+    }
+
+    @NonNull
+    public AutomaticZenRule getRule() {
+        return mRule;
+    }
+
+    @NonNull
+    public String getName() {
+        return Strings.nullToEmpty(mRule.getName());
+    }
+
+    @NonNull
+    public Status getStatus() {
+        return mStatus;
+    }
+
+    @AutomaticZenRule.Type
+    public int getType() {
+        return mRule.getType();
+    }
+
+    @Nullable
+    public String getTriggerDescription() {
+        return mRule.getTriggerDescription();
+    }
+
+    @NonNull
+    public ListenableFuture<Drawable> getIcon(@NonNull Context context,
+            @NonNull ZenIconLoader iconLoader) {
+        if (mIsManualDnd) {
+            return Futures.immediateFuture(requireNonNull(
+                    context.getDrawable(R.drawable.ic_do_not_disturb_on_24dp)));
+        }
+
+        return iconLoader.getIcon(context, mRule);
+    }
+
+    @NonNull
+    public ZenPolicy getPolicy() {
+        switch (mRule.getInterruptionFilter()) {
+            case INTERRUPTION_FILTER_PRIORITY:
+            case NotificationManager.INTERRUPTION_FILTER_ALL:
+                return requireNonNull(mRule.getZenPolicy());
+
+            case NotificationManager.INTERRUPTION_FILTER_ALARMS:
+                return POLICY_INTERRUPTION_FILTER_ALARMS;
+
+            case NotificationManager.INTERRUPTION_FILTER_NONE:
+                return POLICY_INTERRUPTION_FILTER_NONE;
+
+            case NotificationManager.INTERRUPTION_FILTER_UNKNOWN:
+            default:
+                Log.wtf(TAG, "Rule " + mId + " with unexpected interruptionFilter "
+                        + mRule.getInterruptionFilter());
+                return requireNonNull(mRule.getZenPolicy());
+        }
+    }
+
+    /**
+     * Updates the {@link ZenPolicy} of the associated {@link AutomaticZenRule} based on the
+     * supplied policy. In some cases this involves conversions, so that the following call
+     * to {@link #getPolicy} might return a different policy from the one supplied here.
+     */
+    @SuppressLint("WrongConstant")
+    public void setPolicy(@NonNull ZenPolicy policy) {
+        ZenPolicy currentPolicy = getPolicy();
+        if (currentPolicy.equals(policy)) {
+            return;
+        }
+
+        if (mRule.getInterruptionFilter() == INTERRUPTION_FILTER_ALL) {
+            Log.wtf(TAG, "Able to change policy without filtering being enabled");
+        }
+
+        // If policy is customized from any of the "special" ones, make the rule PRIORITY.
+        if (mRule.getInterruptionFilter() != INTERRUPTION_FILTER_PRIORITY) {
+            mRule.setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY);
+        }
+        mRule.setZenPolicy(policy);
+    }
+
+    @NonNull
+    public ZenDeviceEffects getDeviceEffects() {
+        return mRule.getDeviceEffects() != null
+                ? mRule.getDeviceEffects()
+                : new ZenDeviceEffects.Builder().build();
+    }
+
+    public void setCustomModeConditionId(Context context, Uri conditionId) {
+        checkState(SystemZenRules.PACKAGE_ANDROID.equals(mRule.getPackageName()),
+                "Trying to change condition of non-system-owned rule %s (to %s)",
+                mRule, conditionId);
+
+        Uri oldCondition = mRule.getConditionId();
+        mRule.setConditionId(conditionId);
+
+        ZenModeConfig.ScheduleInfo scheduleInfo = tryParseScheduleConditionId(conditionId);
+        if (scheduleInfo != null) {
+            mRule.setType(AutomaticZenRule.TYPE_SCHEDULE_TIME);
+            mRule.setOwner(ZenModeConfig.getScheduleConditionProvider());
+            mRule.setTriggerDescription(
+                    getTriggerDescriptionForScheduleTime(context, scheduleInfo));
+            return;
+        }
+
+        ZenModeConfig.EventInfo eventInfo = tryParseEventConditionId(conditionId);
+        if (eventInfo != null) {
+            mRule.setType(AutomaticZenRule.TYPE_SCHEDULE_CALENDAR);
+            mRule.setOwner(ZenModeConfig.getEventConditionProvider());
+            mRule.setTriggerDescription(getTriggerDescriptionForScheduleEvent(context, eventInfo));
+            return;
+        }
+
+        if (ZenModeConfig.isValidCustomManualConditionId(conditionId)) {
+            mRule.setType(AutomaticZenRule.TYPE_OTHER);
+            mRule.setOwner(ZenModeConfig.getCustomManualConditionProvider());
+            mRule.setTriggerDescription("");
+            return;
+        }
+
+        Log.wtf(TAG, String.format(
+                "Changed condition of rule %s (%s -> %s) but cannot recognize which kind of "
+                        + "condition it was!",
+                mRule, oldCondition, conditionId));
+    }
+
+    public boolean canEditName() {
+        return !isManualDnd();
+    }
+
+    public boolean canEditIcon() {
+        return !isManualDnd();
+    }
+
+    public boolean canBeDeleted() {
+        return !isManualDnd();
+    }
+
+    public boolean isManualDnd() {
+        return mIsManualDnd;
+    }
+
+    public boolean isActive() {
+        return mStatus == Status.ENABLED_AND_ACTIVE;
+    }
+
+    public boolean isSystemOwned() {
+        return SystemZenRules.PACKAGE_ANDROID.equals(mRule.getPackageName());
+    }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        return obj instanceof ZenMode other
+                && mId.equals(other.mId)
+                && mRule.equals(other.mRule)
+                && mStatus.equals(other.mStatus)
+                && mIsManualDnd == other.mIsManualDnd;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mId, mRule, mStatus, mIsManualDnd);
+    }
+
+    @Override
+    public String toString() {
+        return mId + " (" + mStatus + ") -> " + mRule;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(mId);
+        dest.writeParcelable(mRule, 0);
+        dest.writeString(mStatus.name());
+        dest.writeBoolean(mIsManualDnd);
+    }
+
+    public static final Creator<ZenMode> CREATOR = new Creator<ZenMode>() {
+        @Override
+        public ZenMode createFromParcel(Parcel in) {
+            return new ZenMode(
+                    in.readString(),
+                    checkNotNull(in.readParcelable(AutomaticZenRule.class.getClassLoader(),
+                            AutomaticZenRule.class)),
+                    Status.valueOf(in.readString()),
+                    in.readBoolean());
+        }
+
+        @Override
+        public ZenMode[] newArray(int size) {
+            return new ZenMode[size];
+        }
+    };
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModeDialogMetricsLogger.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModeDialogMetricsLogger.java
new file mode 100644
index 0000000..17695e3
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModeDialogMetricsLogger.java
@@ -0,0 +1,76 @@
+/*
+ * 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.settingslib.notification.modes;
+
+import android.content.Context;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto;
+
+/**
+ * Logs ui events for {@link EnableZenModeDialog}.
+ */
+public class ZenModeDialogMetricsLogger {
+    private final Context mContext;
+
+    public ZenModeDialogMetricsLogger(Context context) {
+        mContext = context;
+    }
+
+    /**
+     * User enabled DND from the QS DND dialog to last until manually turned off
+     */
+    public void logOnEnableZenModeForever() {
+        MetricsLogger.action(
+                mContext,
+                MetricsProto.MetricsEvent.NOTIFICATION_ZEN_MODE_TOGGLE_ON_FOREVER);
+    }
+
+    /**
+     * User enabled DND from the QS DND dialog to last until the next alarm goes off
+     */
+    public void logOnEnableZenModeUntilAlarm() {
+        MetricsLogger.action(
+                mContext,
+                MetricsProto.MetricsEvent.NOTIFICATION_ZEN_MODE_TOGGLE_ON_ALARM);
+    }
+
+    /**
+     * User enabled DND from the QS DND dialog to last until countdown is done
+     */
+    public void logOnEnableZenModeUntilCountdown() {
+        MetricsLogger.action(
+                mContext,
+                MetricsProto.MetricsEvent.NOTIFICATION_ZEN_MODE_TOGGLE_ON_COUNTDOWN);
+    }
+
+    /**
+     * User selected an option on the DND dialog
+     */
+    public void logOnConditionSelected() {
+        MetricsLogger.action(
+                mContext,
+                MetricsProto.MetricsEvent.QS_DND_CONDITION_SELECT);
+    }
+
+    /**
+     * User increased or decreased countdown duration of DND from the DND dialog
+     */
+    public void logOnClickTimeButton(boolean up) {
+        MetricsLogger.action(mContext, MetricsProto.MetricsEvent.QS_DND_TIME, up);
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModesBackend.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModesBackend.java
new file mode 100644
index 0000000..d36e2fe
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenModesBackend.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.notification.modes;
+
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.AutomaticZenRule;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.net.Uri;
+import android.provider.Settings;
+import android.service.notification.Condition;
+import android.service.notification.ZenModeConfig;
+import android.util.Log;
+
+import androidx.annotation.DrawableRes;
+
+import com.android.settingslib.R;
+
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Class used for Settings-NMS interactions related to Mode management.
+ *
+ * <p>This class converts {@link AutomaticZenRule} instances, as well as the manual zen mode,
+ * into the unified {@link ZenMode} format.
+ */
+public class ZenModesBackend {
+
+    private static final String TAG = "ZenModeBackend";
+
+    @Nullable // Until first usage
+    private static ZenModesBackend sInstance;
+
+    private final NotificationManager mNotificationManager;
+
+    private final Context mContext;
+
+    public static ZenModesBackend getInstance(Context context) {
+        if (sInstance == null) {
+            sInstance = new ZenModesBackend(context.getApplicationContext());
+        }
+        return sInstance;
+    }
+
+    ZenModesBackend(Context context) {
+        mContext = context;
+        mNotificationManager = context.getSystemService(NotificationManager.class);
+    }
+
+    public List<ZenMode> getModes() {
+        Map<String, AutomaticZenRule> zenRules = mNotificationManager.getAutomaticZenRules();
+        ZenModeConfig currentConfig = mNotificationManager.getZenModeConfig();
+
+        ArrayList<ZenMode> modes = new ArrayList<>();
+        modes.add(getManualDndMode(currentConfig));
+
+        for (Map.Entry<String, AutomaticZenRule> zenRuleEntry : zenRules.entrySet()) {
+            String ruleId = zenRuleEntry.getKey();
+            ZenModeConfig.ZenRule extraData = currentConfig.automaticRules.get(ruleId);
+            if (extraData != null) {
+                modes.add(new ZenMode(ruleId, zenRuleEntry.getValue(), extraData));
+            } else {
+                Log.w(TAG, "Found AZR " + zenRuleEntry.getValue()
+                        + " but no corresponding entry in ZenModeConfig (" + currentConfig
+                        + "). Skipping");
+            }
+        }
+
+        // Manual DND first, then alphabetically.
+        modes.sort(Comparator.comparing(ZenMode::isManualDnd).reversed()
+                .thenComparing(ZenMode::getName));
+
+        return modes;
+    }
+
+    @Nullable
+    public ZenMode getMode(String id) {
+        ZenModeConfig currentConfig = mNotificationManager.getZenModeConfig();
+        if (ZenMode.MANUAL_DND_MODE_ID.equals(id)) {
+            return getManualDndMode(currentConfig);
+        } else {
+            AutomaticZenRule rule = mNotificationManager.getAutomaticZenRule(id);
+            ZenModeConfig.ZenRule extraData = currentConfig.automaticRules.get(id);
+            if (rule == null || extraData == null) {
+                return null;
+            }
+            return new ZenMode(id, rule, extraData);
+        }
+    }
+
+    private ZenMode getManualDndMode(ZenModeConfig config) {
+        ZenModeConfig.ZenRule manualRule = config.manualRule;
+        // TODO: b/333682392 - Replace with final strings for name & trigger description
+        AutomaticZenRule manualDndRule = new AutomaticZenRule.Builder(
+                mContext.getString(R.string.zen_mode_settings_title), manualRule.conditionId)
+                .setType(manualRule.type)
+                .setZenPolicy(manualRule.zenPolicy)
+                .setDeviceEffects(manualRule.zenDeviceEffects)
+                .setManualInvocationAllowed(manualRule.allowManualInvocation)
+                .setConfigurationActivity(null) // No further settings
+                .setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY)
+                .build();
+
+        return ZenMode.manualDndMode(manualDndRule, config != null && config.isManualActive());
+    }
+
+    public void updateMode(ZenMode mode) {
+        if (mode.isManualDnd()) {
+            try {
+                NotificationManager.Policy dndPolicy =
+                        new ZenModeConfig().toNotificationPolicy(mode.getPolicy());
+                mNotificationManager.setNotificationPolicy(dndPolicy, /* fromUser= */ true);
+
+                mNotificationManager.setManualZenRuleDeviceEffects(
+                        mode.getRule().getDeviceEffects());
+            } catch (Exception e) {
+                Log.w(TAG, "Error updating manual mode", e);
+            }
+        } else {
+            mNotificationManager.updateAutomaticZenRule(mode.getId(), mode.getRule(),
+                    /* fromUser= */ true);
+        }
+    }
+
+    public void activateMode(ZenMode mode, @Nullable Duration forDuration) {
+        if (mode.isManualDnd()) {
+            Uri durationConditionId = null;
+            if (forDuration != null) {
+                durationConditionId = ZenModeConfig.toTimeCondition(mContext,
+                        (int) forDuration.toMinutes(), ActivityManager.getCurrentUser(), true).id;
+            }
+            mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS,
+                    durationConditionId, TAG, /* fromUser= */ true);
+
+        } else {
+            if (forDuration != null) {
+                throw new IllegalArgumentException(
+                        "Only the manual DND mode can be activated for a specific duration");
+            }
+            mNotificationManager.setAutomaticZenRuleState(mode.getId(),
+                    new Condition(mode.getRule().getConditionId(), "", Condition.STATE_TRUE,
+                            Condition.SOURCE_USER_ACTION));
+        }
+    }
+
+    public void deactivateMode(ZenMode mode) {
+        if (mode.isManualDnd()) {
+            // When calling with fromUser=true this will not snooze other modes.
+            mNotificationManager.setZenMode(Settings.Global.ZEN_MODE_OFF, null, TAG,
+                    /* fromUser= */ true);
+        } else {
+            // TODO: b/333527800 - This should (potentially) snooze the rule if it was active.
+            mNotificationManager.setAutomaticZenRuleState(mode.getId(),
+                    new Condition(mode.getRule().getConditionId(), "", Condition.STATE_FALSE,
+                            Condition.SOURCE_USER_ACTION));
+        }
+    }
+
+    public void removeMode(ZenMode mode) {
+        if (!mode.canBeDeleted()) {
+            throw new IllegalArgumentException("Mode " + mode + " cannot be deleted!");
+        }
+        mNotificationManager.removeAutomaticZenRule(mode.getId(), /* fromUser= */ true);
+    }
+
+    /**
+     * Creates a new custom mode with the provided {@code name}. The mode will be "manual" (i.e.
+     * not have a schedule), this can be later updated by the user in the mode settings page.
+     *
+     * @param name mode name
+     * @param iconResId resource id of the chosen icon, {code 0} if none.
+     * @return the created mode. Only {@code null} if creation failed due to an internal error
+     */
+    @Nullable
+    public ZenMode addCustomManualMode(String name, @DrawableRes int iconResId) {
+        AutomaticZenRule rule = ZenMode.newCustomManual(name, iconResId).getRule();
+        String ruleId = mNotificationManager.addAutomaticZenRule(rule);
+        return getMode(ruleId);
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenRadioLayout.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenRadioLayout.java
new file mode 100644
index 0000000..ed659f9
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenRadioLayout.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.notification.modes;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+/**
+ * Specialized layout for zen mode that allows the radio buttons to reside within
+ * a RadioGroup, but also makes sure that all the heights of the radio buttons align
+ * with the corresponding content in the second child of this view.
+ */
+public class ZenRadioLayout extends LinearLayout {
+
+    public ZenRadioLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    /**
+     * Run 2 measurement passes, 1 that figures out the size of the content, and another
+     * that sets the size of the radio buttons to the heights of the corresponding content.
+     */
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        ViewGroup radioGroup = (ViewGroup) getChildAt(0);
+        ViewGroup radioContent = (ViewGroup) getChildAt(1);
+        int size = radioGroup.getChildCount();
+        if (size != radioContent.getChildCount()) {
+            throw new IllegalStateException("Expected matching children");
+        }
+        boolean hasChanges = false;
+        View lastView = null;
+        for (int i = 0; i < size; i++) {
+            View radio = radioGroup.getChildAt(i);
+            View content = radioContent.getChildAt(i);
+            if (lastView != null) {
+                radio.setAccessibilityTraversalAfter(lastView.getId());
+            }
+            View contentClick = findFirstClickable(content);
+            if (contentClick != null) contentClick.setAccessibilityTraversalAfter(radio.getId());
+            lastView = findLastClickable(content);
+            if (radio.getLayoutParams().height != content.getMeasuredHeight()) {
+                hasChanges = true;
+                radio.getLayoutParams().height = content.getMeasuredHeight();
+            }
+        }
+        // Measure again if any heights changed.
+        if (hasChanges) {
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        }
+    }
+
+    private View findFirstClickable(View content) {
+        if (content.isClickable()) return content;
+        if (content instanceof ViewGroup) {
+            ViewGroup group = (ViewGroup) content;
+            for (int i = 0; i < group.getChildCount(); i++) {
+                View v = findFirstClickable(group.getChildAt(i));
+                if (v != null) return v;
+            }
+        }
+        return null;
+    }
+
+    private View findLastClickable(View content) {
+        if (content.isClickable()) return content;
+        if (content instanceof ViewGroup) {
+            ViewGroup group = (ViewGroup) content;
+            for (int i = group.getChildCount() - 1; i >= 0; i--) {
+                View v = findLastClickable(group.getChildAt(i));
+                if (v != null) return v;
+            }
+        }
+        return null;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/statusbar/notification/data/model/ZenMode.kt b/packages/SettingsLib/src/com/android/settingslib/statusbar/notification/data/model/ZenMode.kt
deleted file mode 100644
index a696f8c..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/statusbar/notification/data/model/ZenMode.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.settingslib.statusbar.notification.data.model
-
-import android.provider.Settings.Global
-
-/** Validating wrapper for [android.app.NotificationManager.getZenMode] values. */
-@JvmInline
-value class ZenMode(val zenMode: Int) {
-
-    init {
-        require(zenMode in supportedModes) { "Unsupported zenMode=$zenMode" }
-    }
-
-    private companion object {
-
-        val supportedModes =
-            listOf(
-                Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS,
-                Global.ZEN_MODE_NO_INTERRUPTIONS,
-                Global.ZEN_MODE_ALARMS,
-                Global.ZEN_MODE_OFF,
-            )
-    }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/statusbar/notification/data/repository/FakeNotificationsSoundPolicyRepository.kt b/packages/SettingsLib/src/com/android/settingslib/statusbar/notification/data/repository/FakeNotificationsSoundPolicyRepository.kt
deleted file mode 100644
index a939ed1..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/statusbar/notification/data/repository/FakeNotificationsSoundPolicyRepository.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.settingslib.statusbar.notification.data.repository
-
-import android.app.NotificationManager
-import android.provider.Settings
-import com.android.settingslib.statusbar.notification.data.model.ZenMode
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
-
-class FakeNotificationsSoundPolicyRepository : NotificationsSoundPolicyRepository {
-
-    private val mutableNotificationPolicy = MutableStateFlow<NotificationManager.Policy?>(null)
-    override val notificationPolicy: StateFlow<NotificationManager.Policy?>
-        get() = mutableNotificationPolicy.asStateFlow()
-
-    private val mutableZenMode = MutableStateFlow<ZenMode?>(ZenMode(Settings.Global.ZEN_MODE_OFF))
-    override val zenMode: StateFlow<ZenMode?>
-        get() = mutableZenMode.asStateFlow()
-
-    init {
-        updateNotificationPolicy()
-    }
-
-    fun updateNotificationPolicy(policy: NotificationManager.Policy?) {
-        mutableNotificationPolicy.value = policy
-    }
-
-    fun updateZenMode(zenMode: ZenMode?) {
-        mutableZenMode.value = zenMode
-    }
-}
-
-fun FakeNotificationsSoundPolicyRepository.updateNotificationPolicy(
-    priorityCategories: Int = 0,
-    priorityCallSenders: Int = NotificationManager.Policy.PRIORITY_SENDERS_ANY,
-    priorityMessageSenders: Int = NotificationManager.Policy.CONVERSATION_SENDERS_NONE,
-    suppressedVisualEffects: Int = NotificationManager.Policy.SUPPRESSED_EFFECTS_UNSET,
-    state: Int = NotificationManager.Policy.STATE_UNSET,
-    priorityConversationSenders: Int = NotificationManager.Policy.CONVERSATION_SENDERS_NONE,
-) =
-    updateNotificationPolicy(
-        NotificationManager.Policy(
-            priorityCategories,
-            priorityCallSenders,
-            priorityMessageSenders,
-            suppressedVisualEffects,
-            state,
-            priorityConversationSenders,
-        )
-    )
diff --git a/packages/SettingsLib/src/com/android/settingslib/statusbar/notification/data/repository/NotificationsSoundPolicyRepository.kt b/packages/SettingsLib/src/com/android/settingslib/statusbar/notification/data/repository/NotificationsSoundPolicyRepository.kt
deleted file mode 100644
index 0fb8c3f..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/statusbar/notification/data/repository/NotificationsSoundPolicyRepository.kt
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.settingslib.statusbar.notification.data.repository
-
-import android.app.NotificationManager
-import android.content.BroadcastReceiver
-import android.content.Context
-import android.content.Intent
-import android.content.IntentFilter
-import com.android.settingslib.statusbar.notification.data.model.ZenMode
-import kotlin.coroutines.CoroutineContext
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.channels.awaitClose
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.callbackFlow
-import kotlinx.coroutines.flow.filter
-import kotlinx.coroutines.flow.flowOn
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.onStart
-import kotlinx.coroutines.flow.shareIn
-import kotlinx.coroutines.flow.stateIn
-import kotlinx.coroutines.launch
-
-/** Provides state of volume policy and restrictions imposed by notifications. */
-interface NotificationsSoundPolicyRepository {
-
-    /** @see NotificationManager.getNotificationPolicy */
-    val notificationPolicy: StateFlow<NotificationManager.Policy?>
-
-    /** @see NotificationManager.getZenMode */
-    val zenMode: StateFlow<ZenMode?>
-}
-
-class NotificationsSoundPolicyRepositoryImpl(
-    private val context: Context,
-    private val notificationManager: NotificationManager,
-    scope: CoroutineScope,
-    backgroundCoroutineContext: CoroutineContext,
-) : NotificationsSoundPolicyRepository {
-
-    private val notificationBroadcasts =
-        callbackFlow {
-                val receiver =
-                    object : BroadcastReceiver() {
-                        override fun onReceive(context: Context?, intent: Intent?) {
-                            intent?.action?.let { action -> launch { send(action) } }
-                        }
-                    }
-
-                context.registerReceiver(
-                    receiver,
-                    IntentFilter().apply {
-                        addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED)
-                        addAction(NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED)
-                    }
-                )
-
-                awaitClose { context.unregisterReceiver(receiver) }
-            }
-            .shareIn(
-                started = SharingStarted.WhileSubscribed(),
-                scope = scope,
-            )
-
-    override val notificationPolicy: StateFlow<NotificationManager.Policy?> =
-        notificationBroadcasts
-            .filter { NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED == it }
-            .map { notificationManager.consolidatedNotificationPolicy }
-            .onStart { emit(notificationManager.consolidatedNotificationPolicy) }
-            .flowOn(backgroundCoroutineContext)
-            .stateIn(scope, SharingStarted.WhileSubscribed(), null)
-
-    override val zenMode: StateFlow<ZenMode?> =
-        notificationBroadcasts
-            .filter { NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED == it }
-            .map { ZenMode(notificationManager.zenMode) }
-            .onStart { emit(ZenMode(notificationManager.zenMode)) }
-            .flowOn(backgroundCoroutineContext)
-            .stateIn(scope, SharingStarted.WhileSubscribed(), null)
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractor.kt b/packages/SettingsLib/src/com/android/settingslib/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractor.kt
deleted file mode 100644
index 7719c4b..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractor.kt
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.settingslib.statusbar.notification.domain.interactor
-
-import android.app.NotificationManager
-import android.media.AudioManager
-import android.provider.Settings
-import android.service.notification.ZenModeConfig
-import com.android.settingslib.statusbar.notification.data.model.ZenMode
-import com.android.settingslib.statusbar.notification.data.repository.NotificationsSoundPolicyRepository
-import com.android.settingslib.volume.shared.model.AudioStream
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.filterNotNull
-import kotlinx.coroutines.flow.map
-
-/** Determines notification sounds state and limitations. */
-class NotificationsSoundPolicyInteractor(
-    private val repository: NotificationsSoundPolicyRepository
-) {
-
-    /** @see NotificationManager.getNotificationPolicy */
-    val notificationPolicy: StateFlow<NotificationManager.Policy?>
-        get() = repository.notificationPolicy
-
-    /** @see NotificationManager.getZenMode */
-    val zenMode: StateFlow<ZenMode?>
-        get() = repository.zenMode
-
-    /** Checks if [notificationPolicy] allows alarms. */
-    val areAlarmsAllowed: Flow<Boolean?> = notificationPolicy.map { it?.allowAlarms() }
-
-    /** Checks if [notificationPolicy] allows media. */
-    val isMediaAllowed: Flow<Boolean?> = notificationPolicy.map { it?.allowMedia() }
-
-    /** Checks if [notificationPolicy] allows system sounds. */
-    val isSystemAllowed: Flow<Boolean?> = notificationPolicy.map { it?.allowSystem() }
-
-    /** Checks if [notificationPolicy] allows ringer. */
-    val isRingerAllowed: Flow<Boolean?> =
-        notificationPolicy.map { policy ->
-            policy ?: return@map null
-            !ZenModeConfig.areAllPriorityOnlyRingerSoundsMuted(policy)
-        }
-
-    /** Checks if the [stream] is muted by either [zenMode] or [notificationPolicy]. */
-    fun isZenMuted(stream: AudioStream): Flow<Boolean> {
-        return combine(
-            zenMode.filterNotNull(),
-            areAlarmsAllowed.filterNotNull(),
-            isMediaAllowed.filterNotNull(),
-            isRingerAllowed.filterNotNull(),
-            isSystemAllowed.filterNotNull(),
-        ) { zenMode, areAlarmsAllowed, isMediaAllowed, isRingerAllowed, isSystemAllowed ->
-            when (zenMode.zenMode) {
-                // Everything is muted
-                Settings.Global.ZEN_MODE_NO_INTERRUPTIONS -> return@combine true
-                Settings.Global.ZEN_MODE_ALARMS ->
-                    return@combine stream.value == AudioManager.STREAM_RING ||
-                        stream.value == AudioManager.STREAM_NOTIFICATION ||
-                        stream.value == AudioManager.STREAM_SYSTEM
-                Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS -> {
-                    when {
-                        stream.value == AudioManager.STREAM_ALARM && !areAlarmsAllowed ->
-                            return@combine true
-                        stream.value == AudioManager.STREAM_MUSIC && !isMediaAllowed ->
-                            return@combine true
-                        stream.value == AudioManager.STREAM_SYSTEM && !isSystemAllowed ->
-                            return@combine true
-                        (stream.value == AudioManager.STREAM_RING ||
-                            stream.value == AudioManager.STREAM_NOTIFICATION) && !isRingerAllowed ->
-                            return@combine true
-                    }
-                }
-            }
-            return@combine false
-        }
-    }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt
index 20b949f4..c88c4c9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/volume/data/repository/AudioRepository.kt
@@ -20,6 +20,7 @@
 import android.database.ContentObserver
 import android.media.AudioDeviceInfo
 import android.media.AudioManager
+import android.media.AudioManager.AudioDeviceCategory
 import android.media.AudioManager.OnCommunicationDeviceChangedListener
 import android.provider.Settings
 import androidx.concurrent.futures.DirectExecutor
@@ -45,6 +46,7 @@
 import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.launch
@@ -85,6 +87,10 @@
     suspend fun setMuted(audioStream: AudioStream, isMuted: Boolean): Boolean
 
     suspend fun setRingerMode(audioStream: AudioStream, mode: RingerMode)
+
+    /** Gets audio device category. */
+    @AudioDeviceCategory
+    suspend fun getBluetoothAudioDeviceCategory(bluetoothAddress: String): Int
 }
 
 class AudioRepositoryImpl(
@@ -93,6 +99,7 @@
     private val contentResolver: ContentResolver,
     private val backgroundCoroutineContext: CoroutineContext,
     private val coroutineScope: CoroutineScope,
+    private val logger: Logger,
 ) : AudioRepository {
 
     private val streamSettingNames: Map<AudioStream, String> =
@@ -165,6 +172,7 @@
             .conflate()
             .map { getCurrentAudioStream(audioStream) }
             .onStart { emit(getCurrentAudioStream(audioStream)) }
+            .onEach { logger.onVolumeUpdateReceived(audioStream, it) }
             .flowOn(backgroundCoroutineContext)
     }
 
@@ -174,7 +182,7 @@
             minVolume = getMinVolume(audioStream),
             maxVolume = audioManager.getStreamMaxVolume(audioStream.value),
             volume = audioManager.getStreamVolume(audioStream.value),
-            isAffectedByMute = audioManager.isStreamAffectedByMute(audioStream.value),
+            isAffectedByMute = audioManager.isStreamMutableByUi(audioStream.value),
             isAffectedByRingerMode = audioManager.isStreamAffectedByRingerMode(audioStream.value),
             isMuted = audioManager.isStreamMute(audioStream.value),
         )
@@ -188,6 +196,7 @@
 
     override suspend fun setVolume(audioStream: AudioStream, volume: Int) {
         withContext(backgroundCoroutineContext) {
+            logger.onSetVolumeRequested(audioStream, volume)
             audioManager.setStreamVolume(audioStream.value, volume, 0)
         }
     }
@@ -211,6 +220,13 @@
         withContext(backgroundCoroutineContext) { audioManager.ringerMode = mode.value }
     }
 
+    @AudioDeviceCategory
+    override suspend fun getBluetoothAudioDeviceCategory(bluetoothAddress: String): Int {
+        return withContext(backgroundCoroutineContext) {
+            audioManager.getBluetoothAudioDeviceCategory(bluetoothAddress)
+        }
+    }
+
     private fun getMinVolume(stream: AudioStream): Int =
         try {
             audioManager.getStreamMinVolume(stream.value)
@@ -235,4 +251,11 @@
             awaitClose { contentResolver.unregisterContentObserver(observer) }
         }
     }
+
+    interface Logger {
+
+        fun onSetVolumeRequested(audioStream: AudioStream, volume: Int)
+
+        fun onVolumeUpdateReceived(audioStream: AudioStream, model: AudioStreamModel)
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/domain/interactor/AudioVolumeInteractor.kt b/packages/SettingsLib/src/com/android/settingslib/volume/domain/interactor/AudioVolumeInteractor.kt
index 202ff40..08863b5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/volume/domain/interactor/AudioVolumeInteractor.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/volume/domain/interactor/AudioVolumeInteractor.kt
@@ -17,7 +17,7 @@
 package com.android.settingslib.volume.domain.interactor
 
 import android.media.AudioManager
-import com.android.settingslib.statusbar.notification.domain.interactor.NotificationsSoundPolicyInteractor
+import com.android.settingslib.notification.domain.interactor.NotificationsSoundPolicyInteractor
 import com.android.settingslib.volume.data.repository.AudioRepository
 import com.android.settingslib.volume.shared.model.AudioStream
 import com.android.settingslib.volume.shared.model.AudioStreamModel
@@ -61,6 +61,10 @@
     }
 
     suspend fun setMuted(audioStream: AudioStream, isMuted: Boolean) {
+        val streamModel = getAudioStream(audioStream).first()
+        if (!streamModel.isAffectedByMute) {
+            return
+        }
         if (audioStream.value == AudioManager.STREAM_RING) {
             val mode =
                 if (isMuted) AudioManager.RINGER_MODE_VIBRATE else AudioManager.RINGER_MODE_NORMAL
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/shared/model/AudioStream.kt b/packages/SettingsLib/src/com/android/settingslib/volume/shared/model/AudioStream.kt
index 9c48299..c8e4d71 100644
--- a/packages/SettingsLib/src/com/android/settingslib/volume/shared/model/AudioStream.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/volume/shared/model/AudioStream.kt
@@ -17,6 +17,7 @@
 package com.android.settingslib.volume.shared.model
 
 import android.media.AudioManager
+import android.media.AudioSystem
 
 /** Type-safe wrapper for [AudioManager] audio stream. */
 @JvmInline
@@ -25,6 +26,8 @@
         require(value in supportedStreamTypes) { "Unsupported stream=$value" }
     }
 
+    override fun toString(): String = AudioSystem.streamToString(value)
+
     companion object {
         val supportedStreamTypes =
             setOf(
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
index 727c61c..a7e0464 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiUtils.kt
@@ -498,7 +498,7 @@
         ): Job =
             coroutineScope.launch {
                 val wifiManager = context.getSystemService(WifiManager::class.java) ?: return@launch
-                if (wifiManager.queryWepAllowed()) {
+                if (wifiManager.isWepSupported == true && wifiManager.queryWepAllowed()) {
                     onAllowed()
                 } else {
                     val intent = Intent(Intent.ACTION_MAIN).apply {
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/media/data/repository/AudioManagerVolumeControllerExtTest.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/media/data/repository/AudioManagerVolumeControllerExtTest.kt
new file mode 100644
index 0000000..83b612d
--- /dev/null
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/media/data/repository/AudioManagerVolumeControllerExtTest.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.media.data.repository
+
+import android.media.AudioManager
+import android.media.IVolumeController
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class AudioManagerVolumeControllerExtTest {
+
+    private val testScope = TestScope()
+
+    @Captor private lateinit var volumeControllerCaptor: ArgumentCaptor<IVolumeController>
+    @Mock private lateinit var audioManager: AudioManager
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+    }
+
+    @Test
+    fun displaySafeVolumeWarning_emitsEvent() =
+        testEvent(VolumeControllerEvent.DisplaySafeVolumeWarning(1)) { displaySafeVolumeWarning(1) }
+
+    @Test
+    fun volumeChanged_emitsEvent() =
+        testEvent(VolumeControllerEvent.VolumeChanged(1, 2)) { volumeChanged(1, 2) }
+
+    @Test
+    fun masterMuteChanged_emitsEvent() =
+        testEvent(VolumeControllerEvent.MasterMuteChanged(1)) { masterMuteChanged(1) }
+
+    @Test
+    fun setLayoutDirection_emitsEvent() =
+        testEvent(VolumeControllerEvent.SetLayoutDirection(1)) { setLayoutDirection(1) }
+
+    @Test
+    fun setA11yMode_emitsEvent() =
+        testEvent(VolumeControllerEvent.SetA11yMode(1)) { setA11yMode(1) }
+
+    @Test
+    fun displayCsdWarning_emitsEvent() =
+        testEvent(VolumeControllerEvent.DisplayCsdWarning(1, 2)) { displayCsdWarning(1, 2) }
+
+    @Test fun dismiss_emitsEvent() = testEvent(VolumeControllerEvent.Dismiss) { dismiss() }
+
+    private fun testEvent(
+        expectedEvent: VolumeControllerEvent,
+        emit: IVolumeController.() -> Unit,
+    ) =
+        testScope.runTest {
+            var event: VolumeControllerEvent? = null
+            audioManager.volumeControllerEvents().onEach { event = it }.launchIn(backgroundScope)
+            runCurrent()
+            verify(audioManager).volumeController = volumeControllerCaptor.capture()
+
+            volumeControllerCaptor.value.emit()
+            runCurrent()
+
+            assertThat(event).isEqualTo(expectedEvent)
+        }
+}
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/statusbar/notification/data/repository/NotificationsSoundPolicyRepositoryTest.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/statusbar/notification/data/repository/NotificationsSoundPolicyRepositoryTest.kt
deleted file mode 100644
index dfc4c0a..0000000
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/statusbar/notification/data/repository/NotificationsSoundPolicyRepositoryTest.kt
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.settingslib.statusbar.notification.data.repository
-
-import android.app.NotificationManager
-import android.content.BroadcastReceiver
-import android.content.Context
-import android.content.Intent
-import android.provider.Settings.Global
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.settingslib.statusbar.notification.data.model.ZenMode
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.runCurrent
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentCaptor
-import org.mockito.Captor
-import org.mockito.Mock
-import org.mockito.Mockito.any
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when`
-import org.mockito.MockitoAnnotations
-
-@OptIn(ExperimentalCoroutinesApi::class)
-@RunWith(AndroidJUnit4::class)
-@SmallTest
-class NotificationsSoundPolicyRepositoryTest {
-
-    @Mock private lateinit var context: Context
-    @Mock private lateinit var notificationManager: NotificationManager
-    @Captor private lateinit var receiverCaptor: ArgumentCaptor<BroadcastReceiver>
-
-    private lateinit var underTest: NotificationsSoundPolicyRepository
-
-    private val testScope: TestScope = TestScope()
-
-    @Before
-    fun setup() {
-        MockitoAnnotations.initMocks(this)
-
-        underTest =
-            NotificationsSoundPolicyRepositoryImpl(
-                context,
-                notificationManager,
-                testScope.backgroundScope,
-                testScope.testScheduler,
-            )
-    }
-
-    @Test
-    fun policyChanges_repositoryEmits() {
-        testScope.runTest {
-            val values = mutableListOf<NotificationManager.Policy?>()
-            `when`(notificationManager.notificationPolicy).thenReturn(testPolicy1)
-            underTest.notificationPolicy.onEach { values.add(it) }.launchIn(backgroundScope)
-            runCurrent()
-
-            `when`(notificationManager.notificationPolicy).thenReturn(testPolicy2)
-            triggerIntent(NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED)
-            runCurrent()
-
-            assertThat(values)
-                .containsExactlyElementsIn(listOf(null, testPolicy1, testPolicy2))
-                .inOrder()
-        }
-    }
-
-    @Test
-    fun zenModeChanges_repositoryEmits() {
-        testScope.runTest {
-            val values = mutableListOf<ZenMode?>()
-            `when`(notificationManager.zenMode).thenReturn(Global.ZEN_MODE_OFF)
-            underTest.zenMode.onEach { values.add(it) }.launchIn(backgroundScope)
-            runCurrent()
-
-            `when`(notificationManager.zenMode).thenReturn(Global.ZEN_MODE_ALARMS)
-            triggerIntent(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED)
-            runCurrent()
-
-            assertThat(values)
-                .containsExactlyElementsIn(
-                    listOf(null, ZenMode(Global.ZEN_MODE_OFF), ZenMode(Global.ZEN_MODE_ALARMS))
-                )
-                .inOrder()
-        }
-    }
-
-    private fun triggerIntent(action: String) {
-        verify(context).registerReceiver(receiverCaptor.capture(), any())
-        receiverCaptor.value.onReceive(context, Intent(action))
-    }
-
-    private companion object {
-        val testPolicy1 =
-            NotificationManager.Policy(
-                /* priorityCategories = */ 1,
-                /* priorityCallSenders =*/ 1,
-                /* priorityMessageSenders = */ 1,
-            )
-        val testPolicy2 =
-            NotificationManager.Policy(
-                /* priorityCategories = */ 2,
-                /* priorityCallSenders =*/ 2,
-                /* priorityMessageSenders = */ 2,
-            )
-    }
-}
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioRepositoryTest.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioRepositoryTest.kt
index 683759d..0e43acb 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioRepositoryTest.kt
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/AudioRepositoryTest.kt
@@ -64,6 +64,7 @@
     @Mock private lateinit var communicationDevice: AudioDeviceInfo
     @Mock private lateinit var contentResolver: ContentResolver
 
+    private val logger = FakeAudioRepositoryLogger()
     private val eventsReceiver = FakeAudioManagerEventsReceiver()
     private val volumeByStream: MutableMap<Int, Int> = mutableMapOf()
     private val isAffectedByRingerModeByStream: MutableMap<Int, Boolean> = mutableMapOf()
@@ -109,6 +110,7 @@
                 contentResolver,
                 testScope.testScheduler,
                 testScope.backgroundScope,
+                logger,
             )
     }
 
@@ -173,6 +175,15 @@
             underTest.setVolume(audioStream, 50)
             runCurrent()
 
+            assertThat(logger.logs)
+                .isEqualTo(
+                    listOf(
+                        "onVolumeUpdateReceived audioStream=STREAM_SYSTEM",
+                        "onSetVolumeRequested audioStream=STREAM_SYSTEM",
+                        "onVolumeUpdateReceived audioStream=STREAM_SYSTEM",
+                        "onVolumeUpdateReceived audioStream=STREAM_SYSTEM",
+                    )
+                )
             assertThat(streamModel)
                 .isEqualTo(
                     AudioStreamModel(
@@ -247,6 +258,19 @@
         }
     }
 
+    @Test
+    fun getBluetoothAudioDeviceCategory() {
+        testScope.runTest {
+            `when`(audioManager.getBluetoothAudioDeviceCategory("12:34:56:78")).thenReturn(
+                AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES)
+
+            val category = underTest.getBluetoothAudioDeviceCategory("12:34:56:78")
+            runCurrent()
+
+            assertThat(category).isEqualTo(AudioManager.AUDIO_DEVICE_CATEGORY_HEADPHONES)
+        }
+    }
+
     private fun triggerConnectedDeviceChange(communicationDevice: AudioDeviceInfo?) {
         verify(audioManager)
             .addOnCommunicationDeviceChangedListener(
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioRepositoryLogger.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioRepositoryLogger.kt
new file mode 100644
index 0000000..389bf53
--- /dev/null
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/volume/data/repository/FakeAudioRepositoryLogger.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.volume.data.repository
+
+import com.android.settingslib.volume.shared.model.AudioStream
+import com.android.settingslib.volume.shared.model.AudioStreamModel
+
+class FakeAudioRepositoryLogger : AudioRepositoryImpl.Logger {
+
+    private val mutableLogs: MutableList<String> = mutableListOf()
+    val logs: List<String>
+        get() = mutableLogs
+
+    override fun onSetVolumeRequested(audioStream: AudioStream, volume: Int) {
+        synchronized(mutableLogs) {
+            mutableLogs.add("onSetVolumeRequested audioStream=$audioStream")
+        }
+    }
+
+    override fun onVolumeUpdateReceived(audioStream: AudioStream, model: AudioStreamModel) {
+        synchronized(mutableLogs) {
+            mutableLogs.add("onVolumeUpdateReceived audioStream=$audioStream")
+        }
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/Android.bp b/packages/SettingsLib/tests/robotests/Android.bp
index 397fab1..75c40bf 100644
--- a/packages/SettingsLib/tests/robotests/Android.bp
+++ b/packages/SettingsLib/tests/robotests/Android.bp
@@ -52,6 +52,7 @@
         "androidx.fragment_fragment",
         "androidx.test.core",
         "androidx.core_core",
+        "kotlinx_coroutines_test",
         "flag-junit",
         "settingslib_media_flags_lib",
         "settingslib_illustrationpreference_flags_lib",
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
index a638df5..28bf348 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
@@ -22,11 +22,13 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothCsipSetCoordinator;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothLeBroadcastReceiveState;
 import android.content.Context;
@@ -36,10 +38,13 @@
 import android.media.AudioManager;
 import android.net.Uri;
 import android.platform.test.flag.junit.SetFlagsRule;
+import android.provider.Settings;
 import android.util.Pair;
 
 import com.android.settingslib.widget.AdaptiveIcon;
 
+import com.google.common.collect.ImmutableList;
+
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -562,4 +567,77 @@
 
         assertThat(BluetoothUtils.isAvailableHearingDevice(mCachedBluetoothDevice)).isEqualTo(true);
     }
+
+    @Test
+    public void getGroupId_getCsipProfileId() {
+        when(mCachedBluetoothDevice.getGroupId()).thenReturn(1);
+
+        assertThat(BluetoothUtils.getGroupId(mCachedBluetoothDevice)).isEqualTo(1);
+    }
+
+    @Test
+    public void getGroupId_getLeAudioProfileId() {
+        when(mCachedBluetoothDevice.getGroupId())
+                .thenReturn(BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
+        when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
+        LeAudioProfile leAudio = mock(LeAudioProfile.class);
+        when(leAudio.getGroupId(mBluetoothDevice)).thenReturn(1);
+        when(mCachedBluetoothDevice.getProfiles()).thenReturn(ImmutableList.of(leAudio));
+
+        assertThat(BluetoothUtils.getGroupId(mCachedBluetoothDevice)).isEqualTo(1);
+    }
+
+    @Test
+    public void getSecondaryDeviceForBroadcast_errorState_returnNull() {
+        assertThat(BluetoothUtils.getSecondaryDeviceForBroadcast(mContext, mLocalBluetoothManager))
+                .isNull();
+    }
+
+    @Test
+    public void getSecondaryDeviceForBroadcast_noSecondary_returnNull() {
+        Settings.Secure.putInt(
+                mContext.getContentResolver(),
+                BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
+                1);
+        CachedBluetoothDeviceManager deviceManager = mock(CachedBluetoothDeviceManager.class);
+        when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(deviceManager);
+        when(deviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedBluetoothDevice);
+        when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
+        when(mCachedBluetoothDevice.getGroupId()).thenReturn(1);
+        BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class);
+        when(mAssistant.getAllSources(mBluetoothDevice)).thenReturn(ImmutableList.of(state));
+        when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mBluetoothDevice));
+
+        assertThat(BluetoothUtils.getSecondaryDeviceForBroadcast(mContext, mLocalBluetoothManager))
+                .isNull();
+    }
+
+    @Test
+    public void getSecondaryDeviceForBroadcast_returnCorrectDevice() {
+        Settings.Secure.putInt(
+                mContext.getContentResolver(),
+                BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
+                1);
+        CachedBluetoothDeviceManager deviceManager = mock(CachedBluetoothDeviceManager.class);
+        when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(deviceManager);
+        CachedBluetoothDevice cachedBluetoothDevice = mock(CachedBluetoothDevice.class);
+        BluetoothDevice bluetoothDevice = mock(BluetoothDevice.class);
+        when(cachedBluetoothDevice.getDevice()).thenReturn(bluetoothDevice);
+        when(cachedBluetoothDevice.getGroupId()).thenReturn(1);
+        when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
+        when(mCachedBluetoothDevice.getGroupId()).thenReturn(2);
+        when(deviceManager.findDevice(bluetoothDevice)).thenReturn(cachedBluetoothDevice);
+        when(deviceManager.findDevice(mBluetoothDevice)).thenReturn(mCachedBluetoothDevice);
+        BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class);
+        List<Long> bisSyncState = new ArrayList<>();
+        bisSyncState.add(1L);
+        when(state.getBisSyncState()).thenReturn(bisSyncState);
+        when(mAssistant.getAllSources(any(BluetoothDevice.class)))
+                .thenReturn(ImmutableList.of(state));
+        when(mAssistant.getAllConnectedDevices())
+                .thenReturn(ImmutableList.of(mBluetoothDevice, bluetoothDevice));
+
+        assertThat(BluetoothUtils.getSecondaryDeviceForBroadcast(mContext, mLocalBluetoothManager))
+                .isEqualTo(mCachedBluetoothDevice);
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceStateTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceStateTest.java
new file mode 100644
index 0000000..e8e1556
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceStateTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Bundle;
+import android.os.Parcel;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public final class ActionSwitchPreferenceStateTest {
+
+    @Test
+    public void getMethods() {
+        ActionSwitchPreferenceState state1 =
+                new ActionSwitchPreferenceState.Builder()
+                        .setChecked(true)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+        ActionSwitchPreferenceState state2 =
+                new ActionSwitchPreferenceState.Builder()
+                        .setChecked(false)
+                        .setExtras(buildBundle("key2", "value2"))
+                        .build();
+
+        assertThat(state1.getChecked()).isTrue();
+        assertThat(state2.getChecked()).isFalse();
+        assertThat(state1.getExtras().getString("key1")).isEqualTo("value1");
+        assertThat(state2.getExtras().getString("key2")).isEqualTo("value2");
+    }
+
+    @Test
+    public void parcelOperation_notChecked() {
+        ActionSwitchPreferenceState state =
+                new ActionSwitchPreferenceState.Builder()
+                        .setChecked(false)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+
+        ActionSwitchPreferenceState fromParcel = writeAndRead(state);
+
+        assertThat(fromParcel.getChecked()).isEqualTo(state.getChecked());
+        assertThat(fromParcel.getExtras().getString("key1"))
+                .isEqualTo(state.getExtras().getString("key1"));
+    }
+
+    @Test
+    public void parcelOperation_checked() {
+        ActionSwitchPreferenceState state =
+                new ActionSwitchPreferenceState.Builder()
+                        .setChecked(true)
+                        .setExtras(buildBundle("key2", "value2"))
+                        .build();
+
+        ActionSwitchPreferenceState fromParcel = writeAndRead(state);
+
+        assertThat(fromParcel.getChecked()).isEqualTo(state.getChecked());
+        assertThat(fromParcel.getExtras().getString("key2"))
+                .isEqualTo(state.getExtras().getString("key2"));
+    }
+
+    private Bundle buildBundle(String key, String value) {
+        Bundle bundle = new Bundle();
+        bundle.putString(key, value);
+        return bundle;
+    }
+
+    private ActionSwitchPreferenceState writeAndRead(ActionSwitchPreferenceState state) {
+        Parcel parcel = Parcel.obtain();
+        state.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        ActionSwitchPreferenceState fromParcel =
+                ActionSwitchPreferenceState.CREATOR.createFromParcel(parcel);
+        return fromParcel;
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceTest.java
new file mode 100644
index 0000000..354d0f6
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ActionSwitchPreferenceTest.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Parcel;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public final class ActionSwitchPreferenceTest {
+
+    @Test
+    public void build_withoutTitle_fail() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> {
+                    ActionSwitchPreference unused =
+                            new ActionSwitchPreference.Builder().setSummary("summary").build();
+                });
+    }
+
+    @Test
+    public void build_withTitle_successfully() {
+        ActionSwitchPreference unused =
+                new ActionSwitchPreference.Builder().setTitle("title").build();
+    }
+
+    @Test
+    public void build_withAllFields_successfully() {
+        ActionSwitchPreference unused =
+                new ActionSwitchPreference.Builder()
+                        .setTitle("title")
+                        .setSummary("summary")
+                        .setIntent(new Intent("intent_action"))
+                        .setIcon(Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888))
+                        .setHasSwitch(true)
+                        .setChecked(true)
+                        .setAllowedChangingState(true)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+    }
+
+    @Test
+    public void getMethods() {
+        Intent intent = new Intent("intent_action");
+        Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+        ActionSwitchPreference preference = builder().setIcon(icon).setIntent(intent).build();
+
+        assertThat(preference.getTitle()).isEqualTo("title");
+        assertThat(preference.getSummary()).isEqualTo("summary");
+        assertThat(preference.getIcon()).isSameInstanceAs(icon);
+        assertThat(preference.getIntent()).isSameInstanceAs(intent);
+        assertThat(preference.hasSwitch()).isTrue();
+        assertThat(preference.getChecked()).isTrue();
+        assertThat(preference.isAllowedChangingState()).isTrue();
+        assertThat(preference.getExtras().getString("key1")).isEqualTo("value1");
+    }
+
+    @Test
+    public void parcelOperation() {
+        Intent intent = new Intent("intent_action");
+        Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+        ActionSwitchPreference preference = builder().setIcon(icon).setIntent(intent).build();
+
+        ActionSwitchPreference fromParcel = writeAndRead(preference);
+
+        assertThat(fromParcel.getTitle()).isEqualTo(preference.getTitle());
+        assertThat(fromParcel.getSummary()).isEqualTo(preference.getSummary());
+        assertThat(fromParcel.getIcon().sameAs(preference.getIcon())).isTrue();
+        assertThat(fromParcel.getIntent().getAction()).isSameInstanceAs("intent_action");
+        assertThat(fromParcel.hasSwitch()).isEqualTo(preference.hasSwitch());
+        assertThat(fromParcel.getChecked()).isEqualTo(preference.getChecked());
+        assertThat(fromParcel.isAllowedChangingState())
+                .isEqualTo(preference.isAllowedChangingState());
+        assertThat(fromParcel.getExtras().getString("key1"))
+                .isEqualTo(preference.getExtras().getString("key1"));
+    }
+
+    @Test
+    public void parcelOperation_noIntent() {
+        Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+        ActionSwitchPreference preference = builder().setIcon(icon).setIntent(null).build();
+
+        ActionSwitchPreference fromParcel = writeAndRead(preference);
+
+        assertThat(fromParcel.getTitle()).isEqualTo(preference.getTitle());
+        assertThat(fromParcel.getSummary()).isEqualTo(preference.getSummary());
+        assertThat(fromParcel.getIcon().sameAs(preference.getIcon())).isTrue();
+        assertThat(preference.getIntent()).isNull();
+        assertThat(fromParcel.hasSwitch()).isEqualTo(preference.hasSwitch());
+        assertThat(fromParcel.getChecked()).isEqualTo(preference.getChecked());
+        assertThat(fromParcel.isAllowedChangingState())
+                .isEqualTo(preference.isAllowedChangingState());
+        assertThat(fromParcel.getExtras().getString("key1"))
+                .isEqualTo(preference.getExtras().getString("key1"));
+    }
+
+    @Test
+    public void parcelOperation_noIcon() {
+        Intent intent = new Intent("intent_action");
+        ActionSwitchPreference preference = builder().setIcon(null).setIntent(intent).build();
+
+        ActionSwitchPreference fromParcel = writeAndRead(preference);
+
+        assertThat(fromParcel.getTitle()).isEqualTo(preference.getTitle());
+        assertThat(fromParcel.getSummary()).isEqualTo(preference.getSummary());
+        assertThat(fromParcel.getIcon()).isNull();
+        assertThat(fromParcel.getIntent().getAction()).isSameInstanceAs("intent_action");
+        assertThat(fromParcel.hasSwitch()).isEqualTo(preference.hasSwitch());
+        assertThat(fromParcel.getChecked()).isEqualTo(preference.getChecked());
+        assertThat(fromParcel.isAllowedChangingState())
+                .isEqualTo(preference.isAllowedChangingState());
+        assertThat(fromParcel.getExtras().getString("key1"))
+                .isEqualTo(preference.getExtras().getString("key1"));
+    }
+
+    private Bundle buildBundle(String key, String value) {
+        Bundle bundle = new Bundle();
+        bundle.putString(key, value);
+        return bundle;
+    }
+
+    private ActionSwitchPreference writeAndRead(ActionSwitchPreference preference) {
+        Parcel parcel = Parcel.obtain();
+        preference.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        ActionSwitchPreference fromParcel = ActionSwitchPreference.CREATOR.createFromParcel(parcel);
+        return fromParcel;
+    }
+
+    private ActionSwitchPreference.Builder builder() {
+        return new ActionSwitchPreference.Builder()
+                .setTitle("title")
+                .setSummary("summary")
+                .setHasSwitch(true)
+                .setChecked(true)
+                .setAllowedChangingState(true)
+                .setExtras(buildBundle("key1", "value1"));
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfoTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfoTest.java
new file mode 100644
index 0000000..fd5b075
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceInfoTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.os.Bundle;
+import android.os.Parcel;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public final class DeviceInfoTest {
+    @Test
+    public void build_withoutBluetoothAddress_fail() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> {
+                    DeviceInfo unused =
+                            new DeviceInfo.Builder()
+                                    .setExtras(buildBundle("key1", "value1"))
+                                    .build();
+                });
+    }
+
+    @Test
+    public void build_withoutExtra_successfully() {
+        DeviceInfo unused = new DeviceInfo.Builder().setBluetoothAddress("12:34:56:78").build();
+    }
+
+    @Test
+    public void build_withAllFields_successfully() {
+        DeviceInfo unused =
+                new DeviceInfo.Builder()
+                        .setBluetoothAddress("12:34:56:78")
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+    }
+
+    @Test
+    public void getMethods() {
+        DeviceInfo info =
+                new DeviceInfo.Builder()
+                        .setBluetoothAddress("12:34:56:78")
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+
+        assertThat(info.getBluetoothAddress()).isEqualTo("12:34:56:78");
+        assertThat(info.getExtras().getString("key1")).isEqualTo("value1");
+    }
+
+    @Test
+    public void parcelOperation() {
+        DeviceInfo info =
+                new DeviceInfo.Builder()
+                        .setBluetoothAddress("12:34:56:78")
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+
+        DeviceInfo fromParcel = writeAndRead(info);
+
+        assertThat(fromParcel.getBluetoothAddress()).isEqualTo(info.getBluetoothAddress());
+        assertThat(fromParcel.getExtras().getString("key1"))
+                .isEqualTo(info.getExtras().getString("key1"));
+    }
+
+    private Bundle buildBundle(String key, String value) {
+        Bundle bundle = new Bundle();
+        bundle.putString(key, value);
+        return bundle;
+    }
+
+    private DeviceInfo writeAndRead(DeviceInfo state) {
+        Parcel parcel = Parcel.obtain();
+        state.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        DeviceInfo fromParcel = DeviceInfo.CREATOR.createFromParcel(parcel);
+        return fromParcel;
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingItemTest.kt b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingItemTest.kt
new file mode 100644
index 0000000..56e9b6c
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingItemTest.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings
+
+import android.os.Bundle
+import android.os.Parcel
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+
+@RunWith(RobolectricTestRunner::class)
+class DeviceSettingItemTest {
+
+    @Test
+    fun parcelOperation() {
+        val item =
+            DeviceSettingItem(
+                settingId = 1,
+                packageName = "package_name",
+                className = "class_name",
+                intentAction = "intent_action",
+                extras = Bundle().apply { putString("key1", "value1") },
+            )
+
+        val fromParcel = writeAndRead(item)
+
+        assertThat(fromParcel.settingId).isEqualTo(item.settingId)
+        assertThat(fromParcel.packageName).isEqualTo(item.packageName)
+        assertThat(fromParcel.className).isEqualTo(item.className)
+        assertThat(fromParcel.intentAction).isEqualTo(item.intentAction)
+        assertThat(fromParcel.extras.getString("key1")).isEqualTo(item.extras.getString("key1"))
+    }
+
+    private fun writeAndRead(item: DeviceSettingItem): DeviceSettingItem {
+        val parcel = Parcel.obtain()
+        item.writeToParcel(parcel, 0)
+        parcel.setDataPosition(0)
+        return DeviceSettingItem.CREATOR.createFromParcel(parcel)
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingStateTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingStateTest.java
new file mode 100644
index 0000000..12b7a0f
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingStateTest.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.os.Bundle;
+import android.os.Parcel;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public final class DeviceSettingStateTest {
+    private static final ActionSwitchPreferenceState ACTION_SWITCH_PREFERENCE_STATE =
+            new ActionSwitchPreferenceState.Builder().setChecked(true).build();
+    private static final MultiTogglePreferenceState MULTI_TOGGLE_PREFERENCE_STATE =
+            new MultiTogglePreferenceState.Builder().setState(123).build();
+
+    @Test
+    public void build_withoutPreferenceState_fail() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> {
+                    DeviceSettingState unused =
+                            new DeviceSettingState.Builder()
+                                    .setSettingId(123)
+                                    .setExtras(buildBundle("key1", "value1"))
+                                    .build();
+                });
+    }
+
+    @Test
+    public void build_withoutExtra_successfully() {
+        DeviceSettingState unused =
+                new DeviceSettingState.Builder()
+                        .setSettingId(123)
+                        .setPreferenceState(ACTION_SWITCH_PREFERENCE_STATE)
+                        .build();
+    }
+
+    @Test
+    public void build_withAllFields_successfully() {
+        DeviceSettingState unused =
+                new DeviceSettingState.Builder()
+                        .setSettingId(123)
+                        .setPreferenceState(ACTION_SWITCH_PREFERENCE_STATE)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+    }
+
+    @Test
+    public void getMethods_actionSwitchPreferenceState() {
+        DeviceSettingState state =
+                new DeviceSettingState.Builder()
+                        .setSettingId(123)
+                        .setPreferenceState(ACTION_SWITCH_PREFERENCE_STATE)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+
+        assertThat(state.getSettingId()).isEqualTo(123);
+        assertThat(state.getPreferenceState()).isInstanceOf(ActionSwitchPreferenceState.class);
+        assertThat(state.getExtras().getString("key1")).isEqualTo("value1");
+    }
+
+    @Test
+    public void getMethods_multiTogglePreference() {
+        DeviceSettingState state =
+                new DeviceSettingState.Builder()
+                        .setSettingId(123)
+                        .setPreferenceState(MULTI_TOGGLE_PREFERENCE_STATE)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+
+        assertThat(state.getSettingId()).isEqualTo(123);
+        assertThat(state.getPreferenceState()).isInstanceOf(MultiTogglePreferenceState.class);
+        assertThat(state.getExtras().getString("key1")).isEqualTo("value1");
+    }
+
+    @Test
+    public void parcelOperation_actionSwitchPreferenceState() {
+        DeviceSettingState state =
+                new DeviceSettingState.Builder()
+                        .setSettingId(123)
+                        .setPreferenceState(ACTION_SWITCH_PREFERENCE_STATE)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+
+        DeviceSettingState fromParcel = writeAndRead(state);
+
+        assertThat(fromParcel.getSettingId()).isEqualTo(state.getSettingId());
+        assertThat(fromParcel.getPreferenceState()).isInstanceOf(ActionSwitchPreferenceState.class);
+        assertThat(fromParcel.getPreferenceState().getSettingType())
+                .isEqualTo(DeviceSettingType.DEVICE_SETTING_TYPE_ACTION_SWITCH);
+        assertThat(((ActionSwitchPreferenceState) fromParcel.getPreferenceState()).getChecked())
+                .isTrue();
+        assertThat(fromParcel.getExtras().getString("key1"))
+                .isEqualTo(state.getExtras().getString("key1"));
+    }
+
+    @Test
+    public void parcelOperation_multiTogglePreferenceState() {
+        DeviceSettingState state =
+                new DeviceSettingState.Builder()
+                        .setSettingId(123)
+                        .setPreferenceState(MULTI_TOGGLE_PREFERENCE_STATE)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+
+        DeviceSettingState fromParcel = writeAndRead(state);
+
+        assertThat(fromParcel.getSettingId()).isEqualTo(state.getSettingId());
+        assertThat(fromParcel.getPreferenceState()).isInstanceOf(MultiTogglePreferenceState.class);
+        assertThat(fromParcel.getPreferenceState().getSettingType())
+                .isEqualTo(DeviceSettingType.DEVICE_SETTING_TYPE_MULTI_TOGGLE);
+        assertThat(((MultiTogglePreferenceState) fromParcel.getPreferenceState()).getState())
+                .isEqualTo(123);
+        assertThat(fromParcel.getExtras().getString("key1"))
+                .isEqualTo(state.getExtras().getString("key1"));
+    }
+
+    @Test
+    public void parcelOperation_unknownPreferenceState() {
+        DeviceSettingState state =
+                new DeviceSettingState.Builder()
+                        .setSettingId(123)
+                        .setPreferenceState(new DeviceSettingPreferenceState(123) {})
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+
+        DeviceSettingState fromParcel = writeAndRead(state);
+
+        assertThat(fromParcel.getSettingId()).isEqualTo(state.getSettingId());
+        assertThat(fromParcel.getPreferenceState())
+                .isSameInstanceAs(DeviceSettingPreferenceState.UNKNOWN);
+        assertThat(fromParcel.getExtras().getString("key1"))
+                .isEqualTo(state.getExtras().getString("key1"));
+    }
+
+    private Bundle buildBundle(String key, String value) {
+        Bundle bundle = new Bundle();
+        bundle.putString(key, value);
+        return bundle;
+    }
+
+    private DeviceSettingState writeAndRead(DeviceSettingState state) {
+        Parcel parcel = Parcel.obtain();
+        state.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        DeviceSettingState fromParcel = DeviceSettingState.CREATOR.createFromParcel(parcel);
+        return fromParcel;
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingTest.java
new file mode 100644
index 0000000..98dc54b
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingTest.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.os.Bundle;
+import android.os.Parcel;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public final class DeviceSettingTest {
+    private static final ActionSwitchPreference ACTION_SWITCH_PREFERENCE =
+            new ActionSwitchPreference.Builder().setTitle("action_switch_preference").build();
+    private static final MultiTogglePreference MULTI_TOGGLE_PREFERENCE =
+            new MultiTogglePreference.Builder().setTitle("multi_toggle_preference").build();
+
+    @Test
+    public void build_withoutPreference_fail() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> {
+                    DeviceSetting unused =
+                            new DeviceSetting.Builder()
+                                    .setSettingId(123)
+                                    .setExtras(buildBundle("key1", "value1"))
+                                    .build();
+                });
+    }
+
+    @Test
+    public void build_withoutExtra_successfully() {
+        DeviceSetting unused =
+                new DeviceSetting.Builder()
+                        .setSettingId(123)
+                        .setPreference(ACTION_SWITCH_PREFERENCE)
+                        .build();
+    }
+
+    @Test
+    public void build_withAllFields_successfully() {
+        DeviceSetting unused =
+                new DeviceSetting.Builder()
+                        .setSettingId(123)
+                        .setPreference(ACTION_SWITCH_PREFERENCE)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+    }
+
+    @Test
+    public void getMethods_actionSwitchPreference() {
+        DeviceSetting setting =
+                new DeviceSetting.Builder()
+                        .setSettingId(123)
+                        .setPreference(ACTION_SWITCH_PREFERENCE)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+
+        assertThat(setting.getSettingId()).isEqualTo(123);
+        assertThat(setting.getPreference()).isInstanceOf(ActionSwitchPreference.class);
+        assertThat(setting.getExtras().getString("key1")).isEqualTo("value1");
+    }
+
+    @Test
+    public void getMethods_multiTogglePreference() {
+        DeviceSetting setting =
+                new DeviceSetting.Builder()
+                        .setSettingId(123)
+                        .setPreference(MULTI_TOGGLE_PREFERENCE)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+
+        assertThat(setting.getSettingId()).isEqualTo(123);
+        assertThat(setting.getPreference()).isInstanceOf(MultiTogglePreference.class);
+        assertThat(setting.getExtras().getString("key1")).isEqualTo("value1");
+    }
+
+    @Test
+    public void parcelOperation_actionSwitchPreference() {
+        DeviceSetting setting =
+                new DeviceSetting.Builder()
+                        .setSettingId(123)
+                        .setPreference(ACTION_SWITCH_PREFERENCE)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+
+        DeviceSetting fromParcel = writeAndRead(setting);
+
+        assertThat(fromParcel.getSettingId()).isEqualTo(setting.getSettingId());
+        assertThat(fromParcel.getPreference()).isInstanceOf(ActionSwitchPreference.class);
+        assertThat(fromParcel.getPreference().getSettingType())
+                .isEqualTo(DeviceSettingType.DEVICE_SETTING_TYPE_ACTION_SWITCH);
+        assertThat(((ActionSwitchPreference) fromParcel.getPreference()).getTitle())
+                .isEqualTo("action_switch_preference");
+        assertThat(fromParcel.getExtras().getString("key1"))
+                .isEqualTo(setting.getExtras().getString("key1"));
+    }
+
+    @Test
+    public void parcelOperation_multiTogglePreference() {
+        DeviceSetting setting =
+                new DeviceSetting.Builder()
+                        .setSettingId(123)
+                        .setPreference(MULTI_TOGGLE_PREFERENCE)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+
+        DeviceSetting fromParcel = writeAndRead(setting);
+
+        assertThat(fromParcel.getSettingId()).isEqualTo(setting.getSettingId());
+        assertThat(fromParcel.getPreference()).isInstanceOf(MultiTogglePreference.class);
+        assertThat(fromParcel.getPreference().getSettingType())
+                .isEqualTo(DeviceSettingType.DEVICE_SETTING_TYPE_MULTI_TOGGLE);
+        assertThat(((MultiTogglePreference) fromParcel.getPreference()).getTitle())
+                .isEqualTo("multi_toggle_preference");
+        assertThat(fromParcel.getExtras().getString("key1"))
+                .isEqualTo(setting.getExtras().getString("key1"));
+    }
+
+    @Test
+    public void parcelOperation_unknownPreference() {
+        DeviceSetting setting =
+                new DeviceSetting.Builder()
+                        .setSettingId(123)
+                        .setPreference(new DeviceSettingPreference(123) {})
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+
+        DeviceSetting fromParcel = writeAndRead(setting);
+
+        assertThat(fromParcel.getSettingId()).isEqualTo(setting.getSettingId());
+        assertThat(fromParcel.getPreference()).isSameInstanceAs(DeviceSettingPreference.UNKNOWN);
+        assertThat(fromParcel.getExtras().getString("key1"))
+                .isEqualTo(setting.getExtras().getString("key1"));
+    }
+
+    private Bundle buildBundle(String key, String value) {
+        Bundle bundle = new Bundle();
+        bundle.putString(key, value);
+        return bundle;
+    }
+
+    private DeviceSetting writeAndRead(DeviceSetting state) {
+        Parcel parcel = Parcel.obtain();
+        state.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        DeviceSetting fromParcel = DeviceSetting.CREATOR.createFromParcel(parcel);
+        return fromParcel;
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfigTest.kt b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfigTest.kt
new file mode 100644
index 0000000..2b29a6e
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/DeviceSettingsConfigTest.kt
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings
+
+import android.os.Bundle
+import android.os.Parcel
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+
+@RunWith(RobolectricTestRunner::class)
+class DeviceSettingsConfigTest {
+
+    @Test
+    fun parcelOperation() {
+        val config =
+            DeviceSettingsConfig(
+                mainContentItems =
+                    listOf(
+                        DeviceSettingItem(
+                            1,
+                            "package_name_1",
+                            "class_name_1",
+                            "intent_action_1",
+                            Bundle()
+                        )
+                    ),
+                moreSettingsItems =
+                    listOf(
+                        DeviceSettingItem(
+                            2,
+                            "package_name_2",
+                            "class_name_2",
+                            "intent_action_2",
+                            Bundle()
+                        )
+                    ),
+                moreSettingsFooter = "footer",
+                extras = Bundle().apply { putString("key1", "value1") },
+            )
+
+        val fromParcel = writeAndRead(config)
+
+        assertThat(fromParcel.mainContentItems.stream().map { it.settingId }.toList())
+            .containsExactly(1)
+        assertThat(fromParcel.mainContentItems.stream().map { it.packageName }.toList())
+            .containsExactly("package_name_1")
+        assertThat(fromParcel.mainContentItems.stream().map { it.className }.toList())
+            .containsExactly("class_name_1")
+        assertThat(fromParcel.mainContentItems.stream().map { it.intentAction }.toList())
+            .containsExactly("intent_action_1")
+        assertThat(fromParcel.moreSettingsItems.stream().map { it.settingId }.toList())
+            .containsExactly(2)
+        assertThat(fromParcel.moreSettingsItems.stream().map { it.packageName }.toList())
+            .containsExactly("package_name_2")
+        assertThat(fromParcel.moreSettingsItems.stream().map { it.className }.toList())
+            .containsExactly("class_name_2")
+        assertThat(fromParcel.moreSettingsItems.stream().map { it.intentAction }.toList())
+            .containsExactly("intent_action_2")
+        assertThat(fromParcel.moreSettingsFooter).isEqualTo(config.moreSettingsFooter)
+    }
+
+    private fun writeAndRead(item: DeviceSettingsConfig): DeviceSettingsConfig {
+        val parcel = Parcel.obtain()
+        item.writeToParcel(parcel, 0)
+        parcel.setDataPosition(0)
+        return DeviceSettingsConfig.CREATOR.createFromParcel(parcel)
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceStateTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceStateTest.java
new file mode 100644
index 0000000..2645fc5
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceStateTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Bundle;
+import android.os.Parcel;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public final class MultiTogglePreferenceStateTest {
+
+    @Test
+    public void getMethods() {
+        MultiTogglePreferenceState state1 =
+                new MultiTogglePreferenceState.Builder()
+                        .setState(1)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+        MultiTogglePreferenceState state2 =
+                new MultiTogglePreferenceState.Builder()
+                        .setState(2)
+                        .setExtras(buildBundle("key2", "value2"))
+                        .build();
+
+        assertThat(state1.getState()).isEqualTo(1);
+        assertThat(state2.getState()).isEqualTo(2);
+        assertThat(state1.getExtras().getString("key1")).isEqualTo("value1");
+        assertThat(state2.getExtras().getString("key2")).isEqualTo("value2");
+    }
+
+    @Test
+    public void parcelOperation() {
+        MultiTogglePreferenceState state =
+                new MultiTogglePreferenceState.Builder()
+                        .setState(123)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+
+        MultiTogglePreferenceState fromParcel = writeAndRead(state);
+
+        assertThat(fromParcel.getState()).isEqualTo(state.getState());
+        assertThat(fromParcel.getExtras().getString("key1"))
+                .isEqualTo(state.getExtras().getString("key1"));
+    }
+
+    private Bundle buildBundle(String key, String value) {
+        Bundle bundle = new Bundle();
+        bundle.putString(key, value);
+        return bundle;
+    }
+
+    private MultiTogglePreferenceState writeAndRead(MultiTogglePreferenceState state) {
+        Parcel parcel = Parcel.obtain();
+        state.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        MultiTogglePreferenceState fromParcel =
+                MultiTogglePreferenceState.CREATOR.createFromParcel(parcel);
+        return fromParcel;
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceTest.java
new file mode 100644
index 0000000..62fcb5e
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/MultiTogglePreferenceTest.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Parcel;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public final class MultiTogglePreferenceTest {
+    private static final Bitmap ICON = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+    private static final ToggleInfo TOGGLE_INFO_1 =
+            new ToggleInfo.Builder().setLabel("label1").setIcon(ICON).build();
+    private static final ToggleInfo TOGGLE_INFO_2 =
+            new ToggleInfo.Builder().setLabel("label2").setIcon(ICON).build();
+
+    @Test
+    public void build_withoutTitle_fail() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> {
+                    MultiTogglePreference unused =
+                            new MultiTogglePreference.Builder()
+                                    .addToggleInfo(TOGGLE_INFO_1)
+                                    .setState(0)
+                                    .setAllowChangingState(true)
+                                    .setExtras(buildBundle("key1", "value1"))
+                                    .build();
+                });
+    }
+
+    @Test
+    public void build_withNegativeState_fail() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> {
+                    MultiTogglePreference unused =
+                            new MultiTogglePreference.Builder()
+                                    .setTitle("title")
+                                    .addToggleInfo(TOGGLE_INFO_1)
+                                    .setState(-1)
+                                    .setAllowChangingState(true)
+                                    .setExtras(buildBundle("key1", "value1"))
+                                    .build();
+                });
+    }
+
+    @Test
+    public void build_withoutExtra_successfully() {
+        MultiTogglePreference unused =
+                new MultiTogglePreference.Builder()
+                        .setTitle("title")
+                        .addToggleInfo(TOGGLE_INFO_1)
+                        .addToggleInfo(TOGGLE_INFO_2)
+                        .setState(123)
+                        .setAllowChangingState(true)
+                        .build();
+    }
+
+    @Test
+    public void build_withAllFields_successfully() {
+        MultiTogglePreference unused =
+                new MultiTogglePreference.Builder()
+                        .setTitle("title")
+                        .addToggleInfo(TOGGLE_INFO_1)
+                        .addToggleInfo(TOGGLE_INFO_2)
+                        .setState(123)
+                        .setAllowChangingState(true)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+    }
+
+    @Test
+    public void getMethods() {
+        MultiTogglePreference preference =
+                new MultiTogglePreference.Builder()
+                        .setTitle("title")
+                        .addToggleInfo(TOGGLE_INFO_1)
+                        .addToggleInfo(TOGGLE_INFO_2)
+                        .setState(123)
+                        .setAllowChangingState(true)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+
+        assertThat(preference.getTitle()).isEqualTo("title");
+        assertThat(preference.getToggleInfos().stream().map(ToggleInfo::getLabel).toList())
+                .containsExactly("label1", "label2");
+        assertThat(preference.getState()).isEqualTo(123);
+        assertThat(preference.isAllowedChangingState()).isTrue();
+        assertThat(preference.getExtras().getString("key1")).isEqualTo("value1");
+    }
+
+    @Test
+    public void parcelOperation() {
+        MultiTogglePreference preference =
+                new MultiTogglePreference.Builder()
+                        .setTitle("title")
+                        .addToggleInfo(TOGGLE_INFO_1)
+                        .addToggleInfo(TOGGLE_INFO_2)
+                        .setState(123)
+                        .setAllowChangingState(true)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+
+        MultiTogglePreference fromParcel = writeAndRead(preference);
+
+        assertThat(fromParcel.getTitle()).isEqualTo(preference.getTitle());
+        assertThat(fromParcel.getToggleInfos().stream().map(ToggleInfo::getLabel).toList())
+                .containsExactly("label1", "label2");
+        assertThat(fromParcel.getState()).isEqualTo(preference.getState());
+        assertThat(fromParcel.isAllowedChangingState())
+                .isEqualTo(preference.isAllowedChangingState());
+        assertThat(fromParcel.getExtras().getString("key1"))
+                .isEqualTo(preference.getExtras().getString("key1"));
+    }
+
+    private Bundle buildBundle(String key, String value) {
+        Bundle bundle = new Bundle();
+        bundle.putString(key, value);
+        return bundle;
+    }
+
+    private MultiTogglePreference writeAndRead(MultiTogglePreference preference) {
+        Parcel parcel = Parcel.obtain();
+        preference.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        MultiTogglePreference fromParcel = MultiTogglePreference.CREATOR.createFromParcel(parcel);
+        return fromParcel;
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ToggleInfoTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ToggleInfoTest.java
new file mode 100644
index 0000000..439749a
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/devicesettings/ToggleInfoTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.bluetooth.devicesettings;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Parcel;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public final class ToggleInfoTest {
+
+    @Test
+    public void build_withoutIcon_fail() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> {
+                    ToggleInfo unused =
+                            new ToggleInfo.Builder()
+                                    .setLabel("label")
+                                    .setExtras(buildBundle("key1", "value1"))
+                                    .build();
+                });
+    }
+
+    @Test
+    public void build_withoutLabel_fail() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> {
+                    ToggleInfo unused =
+                            new ToggleInfo.Builder()
+                                    .setIcon(Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888))
+                                    .setExtras(buildBundle("key1", "value1"))
+                                    .build();
+                });
+    }
+
+    @Test
+    public void build_withoutExtra_successfully() {
+        ToggleInfo unused =
+                new ToggleInfo.Builder()
+                        .setLabel("label")
+                        .setIcon(Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888))
+                        .build();
+    }
+
+    @Test
+    public void build_withAllFields_successfully() {
+        ToggleInfo unused =
+                new ToggleInfo.Builder()
+                        .setLabel("label")
+                        .setIcon(Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888))
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+    }
+
+    @Test
+    public void getMethods() {
+        Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+        ToggleInfo info =
+                new ToggleInfo.Builder()
+                        .setLabel("label")
+                        .setIcon(icon)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+
+        assertThat(info.getLabel()).isEqualTo("label");
+        assertThat(info.getIcon()).isSameInstanceAs(icon);
+        assertThat(info.getExtras().getString("key1")).isEqualTo("value1");
+    }
+
+    @Test
+    public void parcelOperation() {
+        Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+        ToggleInfo info =
+                new ToggleInfo.Builder()
+                        .setLabel("label")
+                        .setIcon(icon)
+                        .setExtras(buildBundle("key1", "value1"))
+                        .build();
+
+        ToggleInfo fromParcel = writeAndRead(info);
+
+        assertThat(fromParcel.getLabel()).isEqualTo(info.getLabel());
+        assertThat(fromParcel.getIcon().sameAs(info.getIcon())).isTrue();
+        assertThat(fromParcel.getExtras().getString("key1"))
+                .isEqualTo(info.getExtras().getString("key1"));
+    }
+
+    private Bundle buildBundle(String key, String value) {
+        Bundle bundle = new Bundle();
+        bundle.putString(key, value);
+        return bundle;
+    }
+
+    private ToggleInfo writeAndRead(ToggleInfo state) {
+        Parcel parcel = Parcel.obtain();
+        state.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        ToggleInfo fromParcel = ToggleInfo.CREATOR.createFromParcel(parcel);
+        return fromParcel;
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java
index 80301c0..b143b22 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java
@@ -28,23 +28,31 @@
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.KeyguardManager;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.os.PowerManager;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.Settings.Global;
 import android.provider.Settings.Secure;
 
+import com.android.settingslib.flags.Flags;
+
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
 
 import java.util.List;
@@ -54,26 +62,22 @@
     private static final int BATTERY_SAVER_THRESHOLD_1 = 15;
     private static final int BATTERY_SAVER_THRESHOLD_2 = 20;
 
-    @Mock
-    private Context mMockContext;
+    @Rule(order = 0) public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+    @Rule(order = 1) public final MockitoRule mMockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    private ContentResolver mMockResolver;
-
-    @Mock
-    private PowerManager mMockPowerManager;
+    @Mock private Context mMockContext;
+    @Mock private ContentResolver mMockResolver;
+    @Mock private PowerManager mMockPowerManager;
 
     @Before
     public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
         when(mMockContext.getContentResolver()).thenReturn(mMockResolver);
         when(mMockContext.getSystemService(eq(PowerManager.class))).thenReturn(mMockPowerManager);
         when(mMockPowerManager.setPowerSaveModeEnabled(anyBoolean())).thenReturn(true);
     }
 
     @Test
-    public void testSetPowerSaveMode_enableWithWarning_firstCall_needConfirmationWarning() {
+    public void setPowerSaveMode_enableWithWarning_firstCall_needConfirmationWarning() {
         Secure.putString(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, "null");
         Secure.putString(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, "null");
         Secure.putString(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, "null");
@@ -96,7 +100,7 @@
     }
 
     @Test
-    public void testSetPowerSaveMode_enableWithWarning_secondCall_expectUpdateIntent() {
+    public void setPowerSaveMode_enableWithWarning_secondCall_expectUpdateIntent() {
         // Already acked.
         Secure.putInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1);
         Secure.putInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, 1);
@@ -119,7 +123,7 @@
     }
 
     @Test
-    public void testSetPowerSaveMode_enableWithWarning_thirdCall_expectUpdateIntent() {
+    public void setPowerSaveMode_enableWithWarning_thirdCall_expectUpdateIntent() {
         // Already acked.
         Secure.putInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1);
         Secure.putInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, 1);
@@ -142,7 +146,7 @@
     }
 
     @Test
-    public void testSetPowerSaveMode_enableWithWarning_5thCall_needAutoSuggestionWarning() {
+    public void setPowerSaveMode_enableWithWarning_5thCall_needAutoSuggestionWarning() {
         // Already acked.
         Secure.putInt(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1);
         Secure.putInt(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, 1);
@@ -166,7 +170,7 @@
     }
 
     @Test
-    public void testSetPowerSaveMode_enableWithoutWarning_expectUpdateIntent() {
+    public void setPowerSaveMode_enableWithoutWarning_expectUpdateIntent() {
         Secure.putString(mMockResolver, Secure.LOW_POWER_WARNING_ACKNOWLEDGED, "null");
         Secure.putString(mMockResolver, Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED, "null");
         Secure.putString(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, "null");
@@ -187,17 +191,17 @@
     }
 
     @Test
-    public void testSetPowerSaveMode_disableWithoutWarning_expectUpdateIntent() {
+    public void setPowerSaveMode_disableWithoutWarning_expectUpdateIntent() {
         verifyDisablePowerSaveMode(/* needFirstTimeWarning= */ false);
     }
 
     @Test
-    public void testSetPowerSaveMode_disableWithWarning_expectUpdateIntent() {
+    public void setPowerSaveMode_disableWithWarning_expectUpdateIntent() {
         verifyDisablePowerSaveMode(/* needFirstTimeWarning= */ true);
     }
 
     @Test
-    public void testEnsureAutoBatterysaver_setNewPositiveValue_doNotOverwrite() {
+    public void ensureAutoBatterysaver_setNewPositiveValue_doNotOverwrite() {
         Global.putInt(mMockResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
 
         BatterySaverUtils.ensureAutoBatterySaver(mMockContext, BATTERY_SAVER_THRESHOLD_1);
@@ -212,7 +216,7 @@
     }
 
     @Test
-    public void testSetAutoBatterySaverTriggerLevel_setSuppressSuggestion() {
+    public void setAutoBatterySaverTriggerLevel_setSuppressSuggestion() {
         Global.putString(mMockResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, "null");
         Secure.putString(mMockResolver, Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION, "null");
 
@@ -230,7 +234,7 @@
     }
 
     @Test
-    public void testGetBatterySaverScheduleKey_returnExpectedKey() {
+    public void getBatterySaverScheduleKey_returnExpectedKey() {
         Global.putInt(mMockResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
         Global.putInt(mMockResolver, Global.AUTOMATIC_POWER_SAVE_MODE,
                 PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
@@ -253,8 +257,25 @@
                 KEY_NO_SCHEDULE);
     }
 
+    @EnableFlags(Flags.FLAG_EXTREME_POWER_LOW_STATE_VULNERABILITY)
     @Test
-    public void testSetBatterySaverScheduleMode_setSchedule() {
+    public void setPowerSaveMode_1stTimeAndDeviceLocked_enableBatterySaver() {
+        var keyguardManager = mock(KeyguardManager.class);
+        when(mMockContext.getSystemService(KeyguardManager.class)).thenReturn(keyguardManager);
+        when(keyguardManager.isDeviceLocked()).thenReturn(true);
+        when(mMockPowerManager.setPowerSaveModeEnabled(true)).thenReturn(true);
+
+        var enableResult = BatterySaverUtils.setPowerSaveMode(
+                mMockContext,
+                /* enable= */ true,
+                /* needFirstTimeWarning= */ true,
+                /* reason= */ 0);
+
+        assertThat(enableResult).isTrue();
+    }
+
+    @Test
+    public void setBatterySaverScheduleMode_setSchedule() {
         BatterySaverUtils.setBatterySaverScheduleMode(mMockContext, KEY_NO_SCHEDULE, -1);
 
         assertThat(Global.getInt(mMockResolver, Global.AUTOMATIC_POWER_SAVE_MODE, -1))
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
index c9b35a0a..e1447dc 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
@@ -861,6 +861,23 @@
     }
 
     @Test
+    public void addMediaDevice_withAddresslessBluetoothDevice_shouldIgnoreDeviceAndNotCrash() {
+        MediaRoute2Info bluetoothRoute =
+                new MediaRoute2Info.Builder(TEST_BLUETOOTH_ROUTE).setAddress(null).build();
+
+        final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
+                mock(CachedBluetoothDeviceManager.class);
+        when(mLocalBluetoothManager.getCachedDeviceManager())
+                .thenReturn(cachedBluetoothDeviceManager);
+        when(cachedBluetoothDeviceManager.findDevice(any(BluetoothDevice.class))).thenReturn(null);
+
+        mInfoMediaManager.mMediaDevices.clear();
+        mInfoMediaManager.addMediaDevice(bluetoothRoute, TEST_SYSTEM_ROUTING_SESSION);
+
+        assertThat(mInfoMediaManager.mMediaDevices.size()).isEqualTo(0);
+    }
+
+    @Test
     public void onRoutesUpdated_setsFirstSelectedRouteAsCurrentConnectedDevice() {
         final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
                 mock(CachedBluetoothDeviceManager.class);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/EnableZenModeDialogTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/EnableZenModeDialogTest.java
deleted file mode 100644
index 6b81c1a..0000000
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/EnableZenModeDialogTest.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.settingslib.notification;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-import android.app.Fragment;
-import android.app.NotificationManager;
-import android.content.Context;
-import android.content.res.Resources;
-import android.net.Uri;
-import android.service.notification.Condition;
-import android.view.LayoutInflater;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class EnableZenModeDialogTest {
-    private EnableZenModeDialog mController;
-
-    @Mock
-    private Context mContext;
-    @Mock
-    private Resources mResources;
-    @Mock
-    private Fragment mFragment;
-    @Mock
-    private NotificationManager mNotificationManager;
-
-    private Context mShadowContext;
-    private LayoutInflater mLayoutInflater;
-    private Condition mCountdownCondition;
-    private Condition mAlarmCondition;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mShadowContext = RuntimeEnvironment.application;
-        when(mContext.getApplicationContext()).thenReturn(mContext);
-        when(mContext.getResources()).thenReturn(mResources);
-        when(mFragment.getContext()).thenReturn(mShadowContext);
-        mLayoutInflater = LayoutInflater.from(mShadowContext);
-
-        mController = spy(new EnableZenModeDialog(mContext));
-        mController.mContext = mContext;
-        mController.mLayoutInflater = mLayoutInflater;
-        mController.mForeverId =  Condition.newId(mContext).appendPath("forever").build();
-        when(mContext.getString(com.android.internal.R.string.zen_mode_forever))
-                .thenReturn("testSummary");
-        when(mContext.getString(com.android.internal.R.string.selected))
-                .thenReturn("selected");
-        NotificationManager.Policy alarmsEnabledPolicy = new NotificationManager.Policy(
-                NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS, 0, 0, 0);
-        doReturn(alarmsEnabledPolicy).when(mNotificationManager).getNotificationPolicy();
-        mController.mNotificationManager = mNotificationManager;
-        mController.getContentView();
-
-        // these methods use static calls to ZenModeConfig which would normally fail in robotests,
-        // so instead do nothing:
-        doNothing().when(mController).bindGenericCountdown();
-        doReturn(null).when(mController).getTimeUntilNextAlarmCondition();
-        doReturn(0L).when(mController).getNextAlarm();
-        doNothing().when(mController).bindNextAlarm(any());
-
-        // as a result of doing nothing above, must bind manually:
-        Uri alarm =  Condition.newId(mContext).appendPath("alarm").build();
-        mAlarmCondition = new Condition(alarm, "alarm", "", "", 0, 0, 0);
-        Uri countdown =  Condition.newId(mContext).appendPath("countdown").build();
-        mCountdownCondition = new Condition(countdown, "countdown", "", "", 0, 0, 0);
-        mController.bind(mCountdownCondition,
-                mController.mZenRadioGroupContent.getChildAt(
-                        EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX),
-                EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX);
-        mController.bind(mAlarmCondition,
-                mController.mZenRadioGroupContent.getChildAt(
-                        EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX),
-                EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX);
-    }
-
-    @Test
-    public void testForeverChecked() {
-        mController.bindConditions(mController.forever());
-
-        assertTrue(mController.getConditionTagAt(EnableZenModeDialog.FOREVER_CONDITION_INDEX).rb
-                .isChecked());
-        assertFalse(mController.getConditionTagAt(EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX).rb
-                .isChecked());
-        assertFalse(mController.getConditionTagAt(
-                EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked());
-    }
-
-    @Test
-    public void testNoneChecked() {
-        mController.bindConditions(null);
-        assertFalse(mController.getConditionTagAt(EnableZenModeDialog.FOREVER_CONDITION_INDEX).rb
-                .isChecked());
-        assertFalse(mController.getConditionTagAt(EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX).rb
-                .isChecked());
-        assertFalse(mController.getConditionTagAt(
-                EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked());
-    }
-
-    @Test
-    public void testAlarmChecked() {
-        doReturn(false).when(mController).isCountdown(mAlarmCondition);
-        doReturn(true).when(mController).isAlarm(mAlarmCondition);
-
-        mController.bindConditions(mAlarmCondition);
-        assertFalse(mController.getConditionTagAt(EnableZenModeDialog.FOREVER_CONDITION_INDEX).rb
-                .isChecked());
-        assertFalse(mController.getConditionTagAt(EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX).rb
-                .isChecked());
-        assertTrue(mController.getConditionTagAt(
-                EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked());
-    }
-
-    @Test
-    public void testCountdownChecked() {
-        doReturn(false).when(mController).isAlarm(mCountdownCondition);
-        doReturn(true).when(mController).isCountdown(mCountdownCondition);
-
-        mController.bindConditions(mCountdownCondition);
-        assertFalse(mController.getConditionTagAt(EnableZenModeDialog.FOREVER_CONDITION_INDEX).rb
-                .isChecked());
-        assertTrue(mController.getConditionTagAt(EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX).rb
-                .isChecked());
-        assertFalse(mController.getConditionTagAt(
-                EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked());
-    }
-
-    @Test
-    public void testNoAlarmWarning() {
-        // setup alarm
-        long now = System.currentTimeMillis();
-        doReturn(now + 100000).when(mController).getNextAlarm();
-        doReturn("").when(mController).getTime(anyLong(), anyLong());
-
-        // allow alarms
-        when(mNotificationManager.getNotificationPolicy()).thenReturn(
-                new NotificationManager.Policy(
-                        NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS, 0, 0, 0));
-
-        // alarm warning should be null
-        assertNull(mController.computeAlarmWarningText(null));
-    }
-
-    @Test
-    public void testAlarmWarning() {
-        // setup alarm
-        long now = System.currentTimeMillis();
-        doReturn(now + 1000000).when(mController).getNextAlarm();
-        doReturn("").when(mController).getTime(anyLong(), anyLong());
-
-        // don't allow alarms to bypass dnd
-        when(mNotificationManager.getNotificationPolicy()).thenReturn(
-                new NotificationManager.Policy(0, 0, 0, 0));
-
-        // return a string if mResources is asked to retrieve a string
-        when(mResources.getString(anyInt(), anyString())).thenReturn("");
-
-        // alarm warning should NOT be null
-        assertNotNull(mController.computeAlarmWarningText(null));
-    }
-
-    @Test
-    public void testAccessibility() {
-        mController.bindConditions(null);
-        EnableZenModeDialog.ConditionTag forever = mController.getConditionTagAt(
-                ZenDurationDialog.FOREVER_CONDITION_INDEX);
-        EnableZenModeDialog.ConditionTag countdown = mController.getConditionTagAt(
-                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
-        EnableZenModeDialog.ConditionTag alwaysAsk = mController.getConditionTagAt(
-                ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX);
-
-        forever.rb.setChecked(true);
-        assertThat(forever.line1.getStateDescription().toString()).isEqualTo("selected");
-        assertThat(countdown.line1.getStateDescription()).isNull();
-        assertThat(alwaysAsk.line1.getStateDescription()).isNull();
-
-        alwaysAsk.rb.setChecked(true);
-        assertThat(forever.line1.getStateDescription()).isNull();
-        assertThat(countdown.line1.getStateDescription()).isNull();
-        assertThat(alwaysAsk.line1.getStateDescription().toString()).isEqualTo("selected");
-    }
-}
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/ZenDurationDialogTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/ZenDurationDialogTest.java
deleted file mode 100644
index fc45e89..0000000
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/ZenDurationDialogTest.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.settingslib.notification;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import static org.mockito.Mockito.spy;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.provider.Settings;
-import android.view.LayoutInflater;
-import android.view.View;
-
-import androidx.appcompat.app.AlertDialog;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-@RunWith(RobolectricTestRunner.class)
-public class ZenDurationDialogTest {
-    private ZenDurationDialog mController;
-
-    private Context mContext;
-    private LayoutInflater mLayoutInflater;
-    private ContentResolver mContentResolver;
-    private AlertDialog.Builder mBuilder;
-
-    @Before
-    public void setup() {
-        mContext = RuntimeEnvironment.application;
-        mContentResolver = RuntimeEnvironment.application.getContentResolver();
-        mLayoutInflater = LayoutInflater.from(mContext);
-
-        mController = spy(new ZenDurationDialog(mContext));
-        mController.mLayoutInflater = mLayoutInflater;
-        mController.getContentView();
-        mBuilder = new AlertDialog.Builder(mContext);
-    }
-
-    @Test
-    public void testAlwaysPrompt() {
-        Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
-                Settings.Global.ZEN_DURATION_PROMPT);
-        mController.setupDialog(mBuilder);
-
-        assertFalse(mController.getConditionTagAt(ZenDurationDialog.FOREVER_CONDITION_INDEX).rb
-                .isChecked());
-        assertFalse(mController.getConditionTagAt(ZenDurationDialog.COUNTDOWN_CONDITION_INDEX).rb
-                .isChecked());
-        assertTrue(mController.getConditionTagAt(
-                ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX).rb.isChecked());
-    }
-
-    @Test
-    public void testForever() {
-        Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
-                Settings.Secure.ZEN_DURATION_FOREVER);
-        mController.setupDialog(mBuilder);
-
-        assertTrue(mController.getConditionTagAt(ZenDurationDialog.FOREVER_CONDITION_INDEX).rb
-                .isChecked());
-        assertFalse(mController.getConditionTagAt(ZenDurationDialog.COUNTDOWN_CONDITION_INDEX).rb
-                .isChecked());
-        assertFalse(mController.getConditionTagAt(
-                ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX).rb.isChecked());
-    }
-
-    @Test
-    public void testSpecificDuration() {
-        Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION, 45);
-        mController.setupDialog(mBuilder);
-
-        assertFalse(mController.getConditionTagAt(ZenDurationDialog.FOREVER_CONDITION_INDEX).rb
-                .isChecked());
-        assertTrue(mController.getConditionTagAt(ZenDurationDialog.COUNTDOWN_CONDITION_INDEX).rb
-                .isChecked());
-        assertFalse(mController.getConditionTagAt(
-                ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX).rb.isChecked());
-    }
-
-    @Test
-    public void testChooseAlwaysPromptSetting() {
-        Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
-                Settings.Secure.ZEN_DURATION_FOREVER);
-
-        mController.setupDialog(mBuilder);
-        mController.getConditionTagAt(ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX).rb.setChecked(
-                true);
-        mController.updateZenDuration(Settings.Secure.ZEN_DURATION_FOREVER);
-
-        assertEquals(Settings.Secure.ZEN_DURATION_PROMPT, Settings.Secure.getInt(mContentResolver,
-                Settings.Secure.ZEN_DURATION, Settings.Secure.ZEN_DURATION_FOREVER));
-    }
-
-    @Test
-    public void testChooseForeverSetting() {
-        Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
-                Settings.Secure.ZEN_DURATION_PROMPT);
-
-        mController.setupDialog(mBuilder);
-        mController.getConditionTagAt(ZenDurationDialog.FOREVER_CONDITION_INDEX).rb.setChecked(
-                true);
-        mController.updateZenDuration(Settings.Secure.ZEN_DURATION_PROMPT);
-
-        assertEquals(Settings.Secure.ZEN_DURATION_FOREVER, Settings.Secure.getInt(mContentResolver,
-                Settings.Secure.ZEN_DURATION, Settings.Secure.ZEN_DURATION_PROMPT));
-    }
-
-    @Test
-    public void testChooseTimeSetting() {
-        Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
-                Settings.Secure.ZEN_DURATION_PROMPT);
-
-        mController.setupDialog(mBuilder);
-        mController.getConditionTagAt(ZenDurationDialog.COUNTDOWN_CONDITION_INDEX).rb.setChecked(
-                true);
-        mController.updateZenDuration(Settings.Secure.ZEN_DURATION_PROMPT);
-
-        // countdown defaults to 60 minutes:
-        assertEquals(60, Settings.Secure.getInt(mContentResolver,
-                Settings.Secure.ZEN_DURATION, Settings.Secure.ZEN_DURATION_PROMPT));
-    }
-
-    @Test
-    public void testGetTimeFromBucket() {
-        Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
-                Settings.Secure.ZEN_DURATION_PROMPT);
-
-        mController.setupDialog(mBuilder);
-        // click time button starts at 60 minutes
-        // - 1 hour to MAX_BUCKET_MINUTES (12 hours), increments by 1 hour
-        // - 0-60 minutes increments by 15 minutes
-        View view = mController.mZenRadioGroupContent.getChildAt(
-                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
-        ZenDurationDialog.ConditionTag tag = mController.getConditionTagAt(
-                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
-
-        // test incrementing up:
-        mController.onClickTimeButton(view, tag, true, ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
-        assertEquals(120, tag.countdownZenDuration); // goes from 1 hour to 2 hours
-
-        // try clicking up 50 times - should max out at ZenDurationDialog.MAX_BUCKET_MINUTES
-        for (int i = 0; i < 50; i++) {
-            mController.onClickTimeButton(view, tag, true,
-                    ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
-        }
-        assertEquals(ZenDurationDialog.MAX_BUCKET_MINUTES, tag.countdownZenDuration);
-
-        // reset, test incrementing down:
-        mController.mBucketIndex = -1; // reset current bucket index to reset countdownZenDuration
-        tag.countdownZenDuration = 60; // back to default
-        mController.onClickTimeButton(view, tag, false,
-                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
-        assertEquals(45, tag.countdownZenDuration); // goes from 60 minutes to 45 minutes
-
-        // try clicking down 50 times - should stop at MIN_BUCKET_MINUTES
-        for (int i = 0; i < 50; i++) {
-            mController.onClickTimeButton(view, tag, false,
-                    ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
-        }
-        assertEquals(ZenDurationDialog.MIN_BUCKET_MINUTES, tag.countdownZenDuration);
-
-        // reset countdownZenDuration to unbucketed number, should round change to nearest bucket
-        mController.mBucketIndex = -1;
-        tag.countdownZenDuration = 50;
-        mController.onClickTimeButton(view, tag, false,
-                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
-        assertEquals(45, tag.countdownZenDuration);
-
-        mController.mBucketIndex = -1;
-        tag.countdownZenDuration = 50;
-        mController.onClickTimeButton(view, tag, true,
-                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
-        assertEquals(60, tag.countdownZenDuration);
-
-        mController.mBucketIndex = -1;
-        tag.countdownZenDuration = 75;
-        mController.onClickTimeButton(view, tag, false,
-                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
-        assertEquals(60, tag.countdownZenDuration);
-
-        mController.mBucketIndex = -1;
-        tag.countdownZenDuration = 75;
-        mController.onClickTimeButton(view, tag, true,
-                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
-        assertEquals(120, tag.countdownZenDuration);
-    }
-
-    @Test
-    public void testAccessibility() {
-        Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
-                Settings.Secure.ZEN_DURATION_FOREVER);
-        mController.setupDialog(mBuilder);
-        ZenDurationDialog.ConditionTag forever = mController.getConditionTagAt(
-                ZenDurationDialog.FOREVER_CONDITION_INDEX);
-        ZenDurationDialog.ConditionTag countdown = mController.getConditionTagAt(
-                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
-        ZenDurationDialog.ConditionTag alwaysAsk = mController.getConditionTagAt(
-                ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX);
-
-        forever.rb.setChecked(true);
-        assertThat(forever.line1.getStateDescription().toString()).isEqualTo("selected");
-        assertThat(countdown.line1.getStateDescription()).isNull();
-        assertThat(alwaysAsk.line1.getStateDescription()).isNull();
-
-        alwaysAsk.rb.setChecked(true);
-        assertThat(forever.line1.getStateDescription()).isNull();
-        assertThat(countdown.line1.getStateDescription()).isNull();
-        assertThat(alwaysAsk.line1.getStateDescription().toString()).isEqualTo("selected");
-    }
-}
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/data/repository/ZenModeRepositoryTest.kt b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/data/repository/ZenModeRepositoryTest.kt
new file mode 100644
index 0000000..096c25d
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/data/repository/ZenModeRepositoryTest.kt
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES 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.settingslib.notification.data.repository
+
+import android.app.NotificationManager
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.provider.Settings.Global
+import androidx.test.filters.SmallTest
+import com.android.settingslib.flags.Flags
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.any
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
+import org.mockito.MockitoAnnotations
+import org.robolectric.RobolectricTestRunner
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(RobolectricTestRunner::class)
+@SmallTest
+class ZenModeRepositoryTest {
+
+    @Mock private lateinit var context: Context
+
+    @Mock private lateinit var notificationManager: NotificationManager
+
+    @Captor private lateinit var receiverCaptor: ArgumentCaptor<BroadcastReceiver>
+
+    private lateinit var underTest: ZenModeRepository
+
+    private val testScope: TestScope = TestScope()
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+
+        underTest =
+            ZenModeRepositoryImpl(
+                context,
+                notificationManager,
+                testScope.backgroundScope,
+                testScope.testScheduler,
+                backgroundHandler = null,
+            )
+    }
+
+    @DisableFlags(android.app.Flags.FLAG_MODES_API, Flags.FLAG_VOLUME_PANEL_BROADCAST_FIX)
+    @Test
+    fun consolidatedPolicyChanges_repositoryEmits_flagsOff() {
+        testScope.runTest {
+            val values = mutableListOf<NotificationManager.Policy?>()
+            `when`(notificationManager.consolidatedNotificationPolicy).thenReturn(testPolicy1)
+            underTest.consolidatedNotificationPolicy
+                .onEach { values.add(it) }
+                .launchIn(backgroundScope)
+            runCurrent()
+
+            `when`(notificationManager.consolidatedNotificationPolicy).thenReturn(testPolicy2)
+            triggerIntent(NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED)
+            runCurrent()
+
+            assertThat(values)
+                .containsExactlyElementsIn(listOf(null, testPolicy1, testPolicy2))
+                .inOrder()
+        }
+    }
+
+    @EnableFlags(android.app.Flags.FLAG_MODES_API, Flags.FLAG_VOLUME_PANEL_BROADCAST_FIX)
+    @Test
+    fun consolidatedPolicyChanges_repositoryEmits_flagsOn() {
+        testScope.runTest {
+            val values = mutableListOf<NotificationManager.Policy?>()
+            `when`(notificationManager.consolidatedNotificationPolicy).thenReturn(testPolicy1)
+            underTest.consolidatedNotificationPolicy
+                .onEach { values.add(it) }
+                .launchIn(backgroundScope)
+            runCurrent()
+
+            `when`(notificationManager.consolidatedNotificationPolicy).thenReturn(testPolicy2)
+            triggerIntent(NotificationManager.ACTION_CONSOLIDATED_NOTIFICATION_POLICY_CHANGED)
+            runCurrent()
+
+            assertThat(values)
+                .containsExactlyElementsIn(listOf(null, testPolicy1, testPolicy2))
+                .inOrder()
+        }
+    }
+
+    @Test
+    fun zenModeChanges_repositoryEmits() {
+        testScope.runTest {
+            val values = mutableListOf<Int?>()
+            `when`(notificationManager.zenMode).thenReturn(Global.ZEN_MODE_OFF)
+            underTest.globalZenMode.onEach { values.add(it) }.launchIn(backgroundScope)
+            runCurrent()
+
+            `when`(notificationManager.zenMode).thenReturn(Global.ZEN_MODE_ALARMS)
+            triggerIntent(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED)
+            runCurrent()
+
+            assertThat(values)
+                .containsExactlyElementsIn(
+                    listOf(null, Global.ZEN_MODE_OFF, Global.ZEN_MODE_ALARMS))
+                .inOrder()
+        }
+    }
+
+    private fun triggerIntent(action: String) {
+        verify(context).registerReceiver(receiverCaptor.capture(), any())
+        receiverCaptor.value.onReceive(context, Intent(action))
+    }
+
+    private companion object {
+        val testPolicy1 =
+            NotificationManager.Policy(
+                /* priorityCategories = */ 1,
+                /* priorityCallSenders =*/ 1,
+                /* priorityMessageSenders = */ 1,
+            )
+        val testPolicy2 =
+            NotificationManager.Policy(
+                /* priorityCategories = */ 2,
+                /* priorityCallSenders =*/ 2,
+                /* priorityMessageSenders = */ 2,
+            )
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/EnableZenModeDialogTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/EnableZenModeDialogTest.java
new file mode 100644
index 0000000..e397f97
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/EnableZenModeDialogTest.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.notification.modes;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.Fragment;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.res.Resources;
+import android.net.Uri;
+import android.service.notification.Condition;
+import android.view.LayoutInflater;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class EnableZenModeDialogTest {
+    private EnableZenModeDialog mController;
+
+    @Mock
+    private Context mContext;
+    @Mock
+    private Resources mResources;
+    @Mock
+    private Fragment mFragment;
+    @Mock
+    private NotificationManager mNotificationManager;
+
+    private Context mShadowContext;
+    private LayoutInflater mLayoutInflater;
+    private Condition mCountdownCondition;
+    private Condition mAlarmCondition;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mShadowContext = RuntimeEnvironment.application;
+        when(mContext.getApplicationContext()).thenReturn(mContext);
+        when(mContext.getResources()).thenReturn(mResources);
+        when(mFragment.getContext()).thenReturn(mShadowContext);
+        mLayoutInflater = LayoutInflater.from(mShadowContext);
+
+        mController = spy(new EnableZenModeDialog(mContext));
+        mController.mContext = mContext;
+        mController.mLayoutInflater = mLayoutInflater;
+        mController.mForeverId = Condition.newId(mContext).appendPath("forever").build();
+        when(mContext.getString(com.android.internal.R.string.zen_mode_forever))
+                .thenReturn("testSummary");
+        when(mContext.getString(com.android.internal.R.string.selected))
+                .thenReturn("selected");
+        NotificationManager.Policy alarmsEnabledPolicy = new NotificationManager.Policy(
+                NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS, 0, 0, 0);
+        doReturn(alarmsEnabledPolicy).when(mNotificationManager).getNotificationPolicy();
+        mController.mNotificationManager = mNotificationManager;
+        mController.getContentView();
+
+        // these methods use static calls to ZenModeConfig which would normally fail in robotests,
+        // so instead do nothing:
+        doNothing().when(mController).bindGenericCountdown();
+        doReturn(null).when(mController).getTimeUntilNextAlarmCondition();
+        doReturn(0L).when(mController).getNextAlarm();
+        doNothing().when(mController).bindNextAlarm(any());
+
+        // as a result of doing nothing above, must bind manually:
+        Uri alarm = Condition.newId(mContext).appendPath("alarm").build();
+        mAlarmCondition = new Condition(alarm, "alarm", "", "", 0, 0, 0);
+        Uri countdown = Condition.newId(mContext).appendPath("countdown").build();
+        mCountdownCondition = new Condition(countdown, "countdown", "", "", 0, 0, 0);
+        mController.bind(mCountdownCondition,
+                mController.mZenRadioGroupContent.getChildAt(
+                        EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX),
+                EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX);
+        mController.bind(mAlarmCondition,
+                mController.mZenRadioGroupContent.getChildAt(
+                        EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX),
+                EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX);
+    }
+
+    @Test
+    public void testForeverChecked() {
+        mController.bindConditions(mController.forever());
+
+        assertTrue(mController.getConditionTagAt(EnableZenModeDialog.FOREVER_CONDITION_INDEX).rb
+                .isChecked());
+        assertFalse(mController.getConditionTagAt(EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX).rb
+                .isChecked());
+        assertFalse(mController.getConditionTagAt(
+                EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked());
+    }
+
+    @Test
+    public void testNoneChecked() {
+        mController.bindConditions(null);
+        assertFalse(mController.getConditionTagAt(EnableZenModeDialog.FOREVER_CONDITION_INDEX).rb
+                .isChecked());
+        assertFalse(mController.getConditionTagAt(EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX).rb
+                .isChecked());
+        assertFalse(mController.getConditionTagAt(
+                EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked());
+    }
+
+    @Test
+    public void testAlarmChecked() {
+        doReturn(false).when(mController).isCountdown(mAlarmCondition);
+        doReturn(true).when(mController).isAlarm(mAlarmCondition);
+
+        mController.bindConditions(mAlarmCondition);
+        assertFalse(mController.getConditionTagAt(EnableZenModeDialog.FOREVER_CONDITION_INDEX).rb
+                .isChecked());
+        assertFalse(mController.getConditionTagAt(EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX).rb
+                .isChecked());
+        assertTrue(mController.getConditionTagAt(
+                EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked());
+    }
+
+    @Test
+    public void testCountdownChecked() {
+        doReturn(false).when(mController).isAlarm(mCountdownCondition);
+        doReturn(true).when(mController).isCountdown(mCountdownCondition);
+
+        mController.bindConditions(mCountdownCondition);
+        assertFalse(mController.getConditionTagAt(EnableZenModeDialog.FOREVER_CONDITION_INDEX).rb
+                .isChecked());
+        assertTrue(mController.getConditionTagAt(EnableZenModeDialog.COUNTDOWN_CONDITION_INDEX).rb
+                .isChecked());
+        assertFalse(mController.getConditionTagAt(
+                EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked());
+    }
+
+    @Test
+    public void testNoAlarmWarning() {
+        // setup alarm
+        long now = System.currentTimeMillis();
+        doReturn(now + 100000).when(mController).getNextAlarm();
+        doReturn("").when(mController).getTime(anyLong(), anyLong());
+
+        // allow alarms
+        when(mNotificationManager.getNotificationPolicy()).thenReturn(
+                new NotificationManager.Policy(
+                        NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS, 0, 0, 0));
+
+        // alarm warning should be null
+        assertNull(mController.computeAlarmWarningText(null));
+    }
+
+    @Test
+    public void testAlarmWarning() {
+        // setup alarm
+        long now = System.currentTimeMillis();
+        doReturn(now + 1000000).when(mController).getNextAlarm();
+        doReturn("").when(mController).getTime(anyLong(), anyLong());
+
+        // don't allow alarms to bypass dnd
+        when(mNotificationManager.getNotificationPolicy()).thenReturn(
+                new NotificationManager.Policy(0, 0, 0, 0));
+
+        // return a string if mResources is asked to retrieve a string
+        when(mResources.getString(anyInt(), anyString())).thenReturn("");
+
+        // alarm warning should NOT be null
+        assertNotNull(mController.computeAlarmWarningText(null));
+    }
+
+    @Test
+    public void testAccessibility() {
+        mController.bindConditions(null);
+        EnableZenModeDialog.ConditionTag forever = mController.getConditionTagAt(
+                ZenDurationDialog.FOREVER_CONDITION_INDEX);
+        EnableZenModeDialog.ConditionTag countdown = mController.getConditionTagAt(
+                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
+        EnableZenModeDialog.ConditionTag alwaysAsk = mController.getConditionTagAt(
+                ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX);
+
+        forever.rb.setChecked(true);
+        assertThat(forever.line1.getStateDescription().toString()).isEqualTo("selected");
+        assertThat(countdown.line1.getStateDescription()).isNull();
+        assertThat(alwaysAsk.line1.getStateDescription()).isNull();
+
+        alwaysAsk.rb.setChecked(true);
+        assertThat(forever.line1.getStateDescription()).isNull();
+        assertThat(countdown.line1.getStateDescription()).isNull();
+        assertThat(alwaysAsk.line1.getStateDescription().toString()).isEqualTo("selected");
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenDurationDialogTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenDurationDialogTest.java
new file mode 100644
index 0000000..19845a0
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenDurationDialogTest.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.notification.modes;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.Mockito.spy;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.provider.Settings;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import androidx.appcompat.app.AlertDialog;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class ZenDurationDialogTest {
+    private ZenDurationDialog mController;
+
+    private Context mContext;
+    private LayoutInflater mLayoutInflater;
+    private ContentResolver mContentResolver;
+    private AlertDialog.Builder mBuilder;
+
+    @Before
+    public void setup() {
+        mContext = RuntimeEnvironment.application;
+        mContentResolver = RuntimeEnvironment.application.getContentResolver();
+        mLayoutInflater = LayoutInflater.from(mContext);
+
+        mController = spy(new ZenDurationDialog(mContext));
+        mController.mLayoutInflater = mLayoutInflater;
+        mController.getContentView();
+        mBuilder = new AlertDialog.Builder(mContext);
+    }
+
+    @Test
+    public void testAlwaysPrompt() {
+        Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
+                Settings.Global.ZEN_DURATION_PROMPT);
+        mController.setupDialog(mBuilder);
+
+        assertFalse(mController.getConditionTagAt(ZenDurationDialog.FOREVER_CONDITION_INDEX).rb
+                .isChecked());
+        assertFalse(mController.getConditionTagAt(ZenDurationDialog.COUNTDOWN_CONDITION_INDEX).rb
+                .isChecked());
+        assertTrue(mController.getConditionTagAt(
+                ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX).rb.isChecked());
+    }
+
+    @Test
+    public void testForever() {
+        Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
+                Settings.Secure.ZEN_DURATION_FOREVER);
+        mController.setupDialog(mBuilder);
+
+        assertTrue(mController.getConditionTagAt(ZenDurationDialog.FOREVER_CONDITION_INDEX).rb
+                .isChecked());
+        assertFalse(mController.getConditionTagAt(ZenDurationDialog.COUNTDOWN_CONDITION_INDEX).rb
+                .isChecked());
+        assertFalse(mController.getConditionTagAt(
+                ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX).rb.isChecked());
+    }
+
+    @Test
+    public void testSpecificDuration() {
+        Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION, 45);
+        mController.setupDialog(mBuilder);
+
+        assertFalse(mController.getConditionTagAt(ZenDurationDialog.FOREVER_CONDITION_INDEX).rb
+                .isChecked());
+        assertTrue(mController.getConditionTagAt(ZenDurationDialog.COUNTDOWN_CONDITION_INDEX).rb
+                .isChecked());
+        assertFalse(mController.getConditionTagAt(
+                ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX).rb.isChecked());
+    }
+
+    @Test
+    public void testChooseAlwaysPromptSetting() {
+        Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
+                Settings.Secure.ZEN_DURATION_FOREVER);
+
+        mController.setupDialog(mBuilder);
+        mController.getConditionTagAt(ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX).rb.setChecked(
+                true);
+        mController.updateZenDuration(Settings.Secure.ZEN_DURATION_FOREVER);
+
+        assertEquals(Settings.Secure.ZEN_DURATION_PROMPT, Settings.Secure.getInt(mContentResolver,
+                Settings.Secure.ZEN_DURATION, Settings.Secure.ZEN_DURATION_FOREVER));
+    }
+
+    @Test
+    public void testChooseForeverSetting() {
+        Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
+                Settings.Secure.ZEN_DURATION_PROMPT);
+
+        mController.setupDialog(mBuilder);
+        mController.getConditionTagAt(ZenDurationDialog.FOREVER_CONDITION_INDEX).rb.setChecked(
+                true);
+        mController.updateZenDuration(Settings.Secure.ZEN_DURATION_PROMPT);
+
+        assertEquals(Settings.Secure.ZEN_DURATION_FOREVER, Settings.Secure.getInt(mContentResolver,
+                Settings.Secure.ZEN_DURATION, Settings.Secure.ZEN_DURATION_PROMPT));
+    }
+
+    @Test
+    public void testChooseTimeSetting() {
+        Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
+                Settings.Secure.ZEN_DURATION_PROMPT);
+
+        mController.setupDialog(mBuilder);
+        mController.getConditionTagAt(ZenDurationDialog.COUNTDOWN_CONDITION_INDEX).rb.setChecked(
+                true);
+        mController.updateZenDuration(Settings.Secure.ZEN_DURATION_PROMPT);
+
+        // countdown defaults to 60 minutes:
+        assertEquals(60, Settings.Secure.getInt(mContentResolver,
+                Settings.Secure.ZEN_DURATION, Settings.Secure.ZEN_DURATION_PROMPT));
+    }
+
+    @Test
+    public void testGetTimeFromBucket() {
+        Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
+                Settings.Secure.ZEN_DURATION_PROMPT);
+
+        mController.setupDialog(mBuilder);
+        // click time button starts at 60 minutes
+        // - 1 hour to MAX_BUCKET_MINUTES (12 hours), increments by 1 hour
+        // - 0-60 minutes increments by 15 minutes
+        View view = mController.mZenRadioGroupContent.getChildAt(
+                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
+        ZenDurationDialog.ConditionTag tag = mController.getConditionTagAt(
+                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
+
+        // test incrementing up:
+        mController.onClickTimeButton(view, tag, true, ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
+        assertEquals(120, tag.countdownZenDuration); // goes from 1 hour to 2 hours
+
+        // try clicking up 50 times - should max out at ZenDurationDialog.MAX_BUCKET_MINUTES
+        for (int i = 0; i < 50; i++) {
+            mController.onClickTimeButton(view, tag, true,
+                    ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
+        }
+        assertEquals(ZenDurationDialog.MAX_BUCKET_MINUTES, tag.countdownZenDuration);
+
+        // reset, test incrementing down:
+        mController.mBucketIndex = -1; // reset current bucket index to reset countdownZenDuration
+        tag.countdownZenDuration = 60; // back to default
+        mController.onClickTimeButton(view, tag, false,
+                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
+        assertEquals(45, tag.countdownZenDuration); // goes from 60 minutes to 45 minutes
+
+        // try clicking down 50 times - should stop at MIN_BUCKET_MINUTES
+        for (int i = 0; i < 50; i++) {
+            mController.onClickTimeButton(view, tag, false,
+                    ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
+        }
+        assertEquals(ZenDurationDialog.MIN_BUCKET_MINUTES, tag.countdownZenDuration);
+
+        // reset countdownZenDuration to unbucketed number, should round change to nearest bucket
+        mController.mBucketIndex = -1;
+        tag.countdownZenDuration = 50;
+        mController.onClickTimeButton(view, tag, false,
+                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
+        assertEquals(45, tag.countdownZenDuration);
+
+        mController.mBucketIndex = -1;
+        tag.countdownZenDuration = 50;
+        mController.onClickTimeButton(view, tag, true,
+                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
+        assertEquals(60, tag.countdownZenDuration);
+
+        mController.mBucketIndex = -1;
+        tag.countdownZenDuration = 75;
+        mController.onClickTimeButton(view, tag, false,
+                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
+        assertEquals(60, tag.countdownZenDuration);
+
+        mController.mBucketIndex = -1;
+        tag.countdownZenDuration = 75;
+        mController.onClickTimeButton(view, tag, true,
+                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
+        assertEquals(120, tag.countdownZenDuration);
+    }
+
+    @Test
+    public void testAccessibility() {
+        Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
+                Settings.Secure.ZEN_DURATION_FOREVER);
+        mController.setupDialog(mBuilder);
+        ZenDurationDialog.ConditionTag forever = mController.getConditionTagAt(
+                ZenDurationDialog.FOREVER_CONDITION_INDEX);
+        ZenDurationDialog.ConditionTag countdown = mController.getConditionTagAt(
+                ZenDurationDialog.COUNTDOWN_CONDITION_INDEX);
+        ZenDurationDialog.ConditionTag alwaysAsk = mController.getConditionTagAt(
+                ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX);
+
+        forever.rb.setChecked(true);
+        assertThat(forever.line1.getStateDescription().toString()).isEqualTo("selected");
+        assertThat(countdown.line1.getStateDescription()).isNull();
+        assertThat(alwaysAsk.line1.getStateDescription()).isNull();
+
+        alwaysAsk.rb.setChecked(true);
+        assertThat(forever.line1.getStateDescription()).isNull();
+        assertThat(countdown.line1.getStateDescription()).isNull();
+        assertThat(alwaysAsk.line1.getStateDescription().toString()).isEqualTo("selected");
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenIconLoaderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenIconLoaderTest.java
new file mode 100644
index 0000000..20461e3
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenIconLoaderTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.notification.modes;
+
+import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.AutomaticZenRule;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.service.notification.ZenPolicy;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class ZenIconLoaderTest {
+
+    private Context mContext;
+    private ZenIconLoader mLoader;
+
+    @Before
+    public void setUp() {
+        mContext = RuntimeEnvironment.application;
+        mLoader = new ZenIconLoader(MoreExecutors.newDirectExecutorService());
+    }
+
+    @Test
+    public void getIcon_systemOwnedRuleWithIcon_loads() throws Exception {
+        AutomaticZenRule systemRule = newRuleBuilder()
+                .setPackage("android")
+                .setIconResId(android.R.drawable.ic_media_play)
+                .build();
+
+        ListenableFuture<Drawable> loadFuture = mLoader.getIcon(mContext, systemRule);
+        assertThat(loadFuture.isDone()).isTrue();
+        assertThat(loadFuture.get()).isNotNull();
+    }
+
+    @Test
+    public void getIcon_ruleWithoutSpecificIcon_loadsFallback() throws Exception {
+        AutomaticZenRule rule = newRuleBuilder()
+                .setType(AutomaticZenRule.TYPE_DRIVING)
+                .setPackage("com.blah")
+                .build();
+
+        ListenableFuture<Drawable> loadFuture = mLoader.getIcon(mContext, rule);
+        assertThat(loadFuture.isDone()).isTrue();
+        assertThat(loadFuture.get()).isNotNull();
+    }
+
+    @Test
+    public void getIcon_ruleWithAppIconWithLoadFailure_loadsFallback() throws Exception {
+        AutomaticZenRule rule = newRuleBuilder()
+                .setType(AutomaticZenRule.TYPE_DRIVING)
+                .setPackage("com.blah")
+                .setIconResId(-123456)
+                .build();
+
+        ListenableFuture<Drawable> loadFuture = mLoader.getIcon(mContext, rule);
+        assertThat(loadFuture.get()).isNotNull();
+    }
+
+    private static AutomaticZenRule.Builder newRuleBuilder() {
+        return new AutomaticZenRule.Builder("Driving", Uri.parse("drive"))
+                .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
+                .setZenPolicy(new ZenPolicy.Builder().build());
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java
new file mode 100644
index 0000000..9e54312
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.notification.modes;
+
+import static android.app.NotificationManager.INTERRUPTION_FILTER_ALARMS;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.app.AutomaticZenRule;
+import android.net.Uri;
+import android.os.Parcel;
+import android.service.notification.Condition;
+import android.service.notification.ZenModeConfig;
+import android.service.notification.ZenPolicy;
+
+import com.android.internal.R;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+@RunWith(RobolectricTestRunner.class)
+public class ZenModeTest {
+
+    private static final ZenPolicy ZEN_POLICY = new ZenPolicy.Builder().allowAllSounds().build();
+
+    private static final AutomaticZenRule ZEN_RULE =
+            new AutomaticZenRule.Builder("Driving", Uri.parse("drive"))
+                    .setPackage("com.some.driving.thing")
+                    .setType(AutomaticZenRule.TYPE_DRIVING)
+                    .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
+                    .setZenPolicy(ZEN_POLICY)
+                    .build();
+
+    @Test
+    public void testBasicMethods() {
+        ZenMode zenMode = new ZenMode("id", ZEN_RULE, zenConfigRuleFor(ZEN_RULE, true));
+
+        assertThat(zenMode.getId()).isEqualTo("id");
+        assertThat(zenMode.getRule()).isEqualTo(ZEN_RULE);
+        assertThat(zenMode.isManualDnd()).isFalse();
+        assertThat(zenMode.canBeDeleted()).isTrue();
+        assertThat(zenMode.isActive()).isTrue();
+
+        ZenMode manualMode = ZenMode.manualDndMode(ZEN_RULE, false);
+        assertThat(manualMode.getId()).isEqualTo(ZenMode.MANUAL_DND_MODE_ID);
+        assertThat(manualMode.isManualDnd()).isTrue();
+        assertThat(manualMode.canBeDeleted()).isFalse();
+        assertThat(manualMode.isActive()).isFalse();
+    }
+
+    @Test
+    public void constructor_enabledRule_statusEnabled() {
+        AutomaticZenRule azr = new AutomaticZenRule.Builder(ZEN_RULE).setEnabled(true).build();
+        ZenModeConfig.ZenRule configZenRule = zenConfigRuleFor(azr, false);
+
+        ZenMode mode = new ZenMode("id", azr, configZenRule);
+        assertThat(mode.getStatus()).isEqualTo(ZenMode.Status.ENABLED);
+        assertThat(mode.isActive()).isFalse();
+    }
+
+    @Test
+    public void constructor_activeRule_statusActive() {
+        AutomaticZenRule azr = new AutomaticZenRule.Builder(ZEN_RULE).setEnabled(true).build();
+        ZenModeConfig.ZenRule configZenRule = zenConfigRuleFor(azr, true);
+
+        ZenMode mode = new ZenMode("id", azr, configZenRule);
+        assertThat(mode.getStatus()).isEqualTo(ZenMode.Status.ENABLED_AND_ACTIVE);
+        assertThat(mode.isActive()).isTrue();
+    }
+
+    @Test
+    public void constructor_disabledRuleByUser_statusDisabledByUser() {
+        AutomaticZenRule azr = new AutomaticZenRule.Builder(ZEN_RULE).setEnabled(false).build();
+        ZenModeConfig.ZenRule configZenRule = zenConfigRuleFor(azr, false);
+        configZenRule.disabledOrigin = ZenModeConfig.UPDATE_ORIGIN_USER;
+
+        ZenMode mode = new ZenMode("id", azr, configZenRule);
+        assertThat(mode.getStatus()).isEqualTo(ZenMode.Status.DISABLED_BY_USER);
+    }
+
+    @Test
+    public void constructor_disabledRuleByOther_statusDisabledByOther() {
+        AutomaticZenRule azr = new AutomaticZenRule.Builder(ZEN_RULE).setEnabled(false).build();
+        ZenModeConfig.ZenRule configZenRule = zenConfigRuleFor(azr, false);
+        configZenRule.disabledOrigin = ZenModeConfig.UPDATE_ORIGIN_APP;
+
+        ZenMode mode = new ZenMode("id", azr, configZenRule);
+        assertThat(mode.getStatus()).isEqualTo(ZenMode.Status.DISABLED_BY_OTHER);
+    }
+
+    @Test
+    public void getPolicy_interruptionFilterPriority_returnsZenPolicy() {
+        AutomaticZenRule azr = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
+                .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
+                .setZenPolicy(ZEN_POLICY)
+                .build();
+        ZenMode zenMode = new ZenMode("id", azr, zenConfigRuleFor(azr, false));
+
+        assertThat(zenMode.getPolicy()).isEqualTo(ZEN_POLICY);
+    }
+
+    @Test
+    public void getPolicy_interruptionFilterAlarms_returnsPolicyAllowingAlarms() {
+        AutomaticZenRule azr = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
+                .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS)
+                .setZenPolicy(ZEN_POLICY) // should be ignored
+                .build();
+        ZenMode zenMode = new ZenMode("id", azr, zenConfigRuleFor(azr, false));
+
+        assertThat(zenMode.getPolicy()).isEqualTo(
+                new ZenPolicy.Builder()
+                        .disallowAllSounds()
+                        .allowAlarms(true)
+                        .allowMedia(true)
+                        .allowPriorityChannels(false)
+                        .build());
+    }
+
+    @Test
+    public void getPolicy_interruptionFilterNone_returnsPolicyAllowingNothing() {
+        AutomaticZenRule azr = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
+                .setInterruptionFilter(INTERRUPTION_FILTER_NONE)
+                .setZenPolicy(ZEN_POLICY) // should be ignored
+                .build();
+        ZenMode zenMode = new ZenMode("id", azr, zenConfigRuleFor(azr, false));
+
+        assertThat(zenMode.getPolicy()).isEqualTo(
+                new ZenPolicy.Builder()
+                        .disallowAllSounds()
+                        .hideAllVisualEffects()
+                        .allowPriorityChannels(false)
+                        .build());
+    }
+
+    @Test
+    public void setPolicy_setsInterruptionFilterPriority() {
+        AutomaticZenRule azr = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
+                .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS)
+                .build();
+        ZenMode zenMode = new ZenMode("id", azr, zenConfigRuleFor(azr, false));
+
+        zenMode.setPolicy(ZEN_POLICY);
+
+        assertThat(zenMode.getRule().getInterruptionFilter()).isEqualTo(
+                INTERRUPTION_FILTER_PRIORITY);
+        assertThat(zenMode.getPolicy()).isEqualTo(ZEN_POLICY);
+        assertThat(zenMode.getRule().getZenPolicy()).isEqualTo(ZEN_POLICY);
+    }
+
+    @Test
+    public void writeToParcel_equals() {
+        assertUnparceledIsEqualToOriginal("example",
+                new ZenMode("id", ZEN_RULE, zenConfigRuleFor(ZEN_RULE, false)));
+
+        assertUnparceledIsEqualToOriginal("dnd", ZenMode.manualDndMode(ZEN_RULE, true));
+
+        assertUnparceledIsEqualToOriginal("custom_manual",
+                ZenMode.newCustomManual("New mode", R.drawable.ic_zen_mode_type_immersive));
+    }
+
+    private static void assertUnparceledIsEqualToOriginal(String type, ZenMode original) {
+        Parcel parcel = Parcel.obtain();
+        try {
+            original.writeToParcel(parcel, 0);
+            parcel.setDataPosition(0);
+            ZenMode unparceled = ZenMode.CREATOR.createFromParcel(parcel);
+
+            assertWithMessage("Comparing " + type).that(unparceled).isEqualTo(original);
+        } finally {
+            parcel.recycle();
+        }
+    }
+
+    private static ZenModeConfig.ZenRule zenConfigRuleFor(AutomaticZenRule azr, boolean isActive) {
+        ZenModeConfig.ZenRule zenRule = new ZenModeConfig.ZenRule();
+        zenRule.pkg = azr.getPackageName();
+        zenRule.conditionId = azr.getConditionId();
+        zenRule.enabled = azr.isEnabled();
+        if (isActive) {
+            zenRule.condition = new Condition(azr.getConditionId(), "active", Condition.STATE_TRUE);
+        }
+        return zenRule;
+    }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModesBackendTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModesBackendTest.java
new file mode 100644
index 0000000..00c7ae3
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModesBackendTest.java
@@ -0,0 +1,382 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.settingslib.notification.modes;
+
+import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
+import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+import static android.provider.Settings.Global.ZEN_MODE_OFF;
+import static android.service.notification.Condition.SOURCE_UNKNOWN;
+import static android.service.notification.Condition.STATE_FALSE;
+import static android.service.notification.Condition.STATE_TRUE;
+import static android.service.notification.ZenAdapters.notificationPolicyToZenPolicy;
+import static android.service.notification.ZenPolicy.STATE_ALLOW;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.AutomaticZenRule;
+import android.app.Flags;
+import android.app.NotificationManager;
+import android.app.NotificationManager.Policy;
+import android.content.Context;
+import android.net.Uri;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
+import android.provider.Settings;
+import android.service.notification.Condition;
+import android.service.notification.ZenDeviceEffects;
+import android.service.notification.ZenModeConfig;
+import android.service.notification.ZenPolicy;
+
+import com.android.settingslib.R;
+
+import com.google.common.collect.ImmutableMap;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowApplication;
+
+import java.time.Duration;
+import java.util.List;
+
+@RunWith(RobolectricTestRunner.class)
+@EnableFlags(Flags.FLAG_MODES_UI)
+public class ZenModesBackendTest {
+
+    private static final String ZEN_RULE_ID = "rule";
+    private static final AutomaticZenRule ZEN_RULE =
+            new AutomaticZenRule.Builder("Driving", Uri.parse("drive"))
+                    .setType(AutomaticZenRule.TYPE_DRIVING)
+                    .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
+                    .setZenPolicy(new ZenPolicy.Builder().allowAllSounds().build())
+                    .build();
+
+    private static final AutomaticZenRule MANUAL_DND_RULE =
+            new AutomaticZenRule.Builder("Do Not Disturb", Uri.EMPTY)
+                    .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
+                    .setZenPolicy(new ZenPolicy.Builder().allowAllSounds().build())
+                    .build();
+
+    @Mock
+    private NotificationManager mNm;
+
+    private Context mContext;
+    private ZenModesBackend mBackend;
+
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(
+            SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT);
+
+    // Helper methods to add active/inactive rule state to a config. Returns a copy.
+    private static ZenModeConfig configWithManualRule(ZenModeConfig base, boolean active) {
+        ZenModeConfig out = base.copy();
+
+        if (active) {
+            out.manualRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+            out.manualRule.condition =
+                    new Condition(out.manualRule.conditionId, "", STATE_TRUE, SOURCE_UNKNOWN);
+        } else {
+            out.manualRule.zenMode = ZEN_MODE_OFF;
+            out.manualRule.condition =
+                    new Condition(out.manualRule.conditionId, "", STATE_FALSE, SOURCE_UNKNOWN);
+        }
+        return out;
+    }
+
+    private static ZenModeConfig configWithRule(ZenModeConfig base, String ruleId,
+            AutomaticZenRule rule, boolean active) {
+        ZenModeConfig out = base.copy();
+        out.automaticRules.put(ruleId, zenConfigRuleForRule(ruleId, rule, active));
+        return out;
+    }
+
+    private static ZenModeConfig.ZenRule zenConfigRuleForRule(String id, AutomaticZenRule azr,
+            boolean active) {
+        // Note that there are many other fields of zenRule, but here we only set the ones
+        // relevant to determining whether or not it is active.
+        ZenModeConfig.ZenRule zenRule = new ZenModeConfig.ZenRule();
+        zenRule.id = id;
+        zenRule.pkg = "package";
+        zenRule.enabled = azr.isEnabled();
+        zenRule.snoozing = false;
+        zenRule.conditionId = azr.getConditionId();
+        zenRule.condition = new Condition(azr.getConditionId(), "",
+                active ? Condition.STATE_TRUE : Condition.STATE_FALSE,
+                Condition.SOURCE_USER_ACTION);
+        return zenRule;
+    }
+
+    private static ZenMode newZenMode(String id, AutomaticZenRule azr, boolean active) {
+        return new ZenMode(id, azr, zenConfigRuleForRule(id, azr, active));
+    }
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        ShadowApplication shadowApplication = ShadowApplication.getInstance();
+        shadowApplication.setSystemService(Context.NOTIFICATION_SERVICE, mNm);
+
+        mContext = RuntimeEnvironment.application;
+        mBackend = new ZenModesBackend(mContext);
+
+        // Default catch-all case with no data. This isn't realistic, but tests below that rely
+        // on the config to get data on rules active will create those individually.
+        when(mNm.getZenModeConfig()).thenReturn(new ZenModeConfig());
+    }
+
+    @Test
+    public void getModes_containsManualDndAndZenRules() {
+        AutomaticZenRule rule2 = new AutomaticZenRule.Builder("Bedtime", Uri.parse("bed"))
+                .setType(AutomaticZenRule.TYPE_BEDTIME)
+                .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
+                .setZenPolicy(new ZenPolicy.Builder().disallowAllSounds().build())
+                .build();
+        Policy dndPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS,
+                Policy.PRIORITY_SENDERS_CONTACTS, Policy.PRIORITY_SENDERS_CONTACTS);
+        when(mNm.getAutomaticZenRules()).thenReturn(
+                ImmutableMap.of("rule1", ZEN_RULE, "rule2", rule2));
+
+        ZenModeConfig config = new ZenModeConfig();
+        config.applyNotificationPolicy(dndPolicy);
+        config = configWithRule(config, "rule1", ZEN_RULE, false);
+        config = configWithRule(config, "rule2", rule2, false);
+        assertThat(config.manualRule.zenPolicy.getPriorityCategoryAlarms()).isEqualTo(STATE_ALLOW);
+        when(mNm.getZenModeConfig()).thenReturn(config);
+
+        List<ZenMode> modes = mBackend.getModes();
+
+        // all modes exist, but none of them are currently active
+        assertThat(modes).containsExactly(
+                        ZenMode.manualDndMode(
+                                new AutomaticZenRule.Builder(
+                                        mContext.getString(R.string.zen_mode_settings_title),
+                                        Uri.EMPTY)
+                                        .setType(AutomaticZenRule.TYPE_OTHER)
+                                        .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
+                                        .setZenPolicy(notificationPolicyToZenPolicy(dndPolicy))
+                                        .setManualInvocationAllowed(true)
+                                        .build(),
+                                false),
+                        newZenMode("rule2", rule2, false),
+                        newZenMode("rule1", ZEN_RULE, false))
+                .inOrder();
+    }
+
+    @Test
+    public void getMode_manualDnd_returnsMode() {
+        Policy dndPolicy = new Policy(Policy.PRIORITY_CATEGORY_ALARMS,
+                Policy.PRIORITY_SENDERS_CONTACTS, Policy.PRIORITY_SENDERS_CONTACTS);
+        ZenModeConfig config = new ZenModeConfig();
+        config.applyNotificationPolicy(dndPolicy);
+        when(mNm.getZenModeConfig()).thenReturn(config);
+
+        ZenMode mode = mBackend.getMode(ZenMode.MANUAL_DND_MODE_ID);
+
+        assertThat(mode).isEqualTo(
+                ZenMode.manualDndMode(
+                        new AutomaticZenRule.Builder(
+                                mContext.getString(R.string.zen_mode_settings_title), Uri.EMPTY)
+                                .setType(AutomaticZenRule.TYPE_OTHER)
+                                .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY)
+                                .setZenPolicy(notificationPolicyToZenPolicy(dndPolicy))
+                                .setManualInvocationAllowed(true)
+                                .build(), false));
+    }
+
+    @Test
+    public void getMode_zenRule_returnsMode() {
+        when(mNm.getAutomaticZenRule(eq(ZEN_RULE_ID))).thenReturn(ZEN_RULE);
+        when(mNm.getZenModeConfig()).thenReturn(
+                configWithRule(new ZenModeConfig(), ZEN_RULE_ID, ZEN_RULE, false));
+
+        ZenMode mode = mBackend.getMode(ZEN_RULE_ID);
+
+        assertThat(mode).isEqualTo(newZenMode(ZEN_RULE_ID, ZEN_RULE, false));
+    }
+
+    @Test
+    public void getMode_missingRule_returnsNull() {
+        when(mNm.getAutomaticZenRule(any())).thenReturn(null);
+
+        ZenMode mode = mBackend.getMode(ZEN_RULE_ID);
+
+        assertThat(mode).isNull();
+        verify(mNm).getAutomaticZenRule(eq(ZEN_RULE_ID));
+    }
+
+    @Test
+    public void getMode_manualDnd_returnsCorrectActiveState() {
+        // Set up a base config with an active rule to make sure we're looking at the correct info
+        ZenModeConfig configWithActiveRule = configWithRule(new ZenModeConfig(), ZEN_RULE_ID,
+                ZEN_RULE, true);
+
+        // Equivalent to disallowAllSounds()
+        Policy dndPolicy = new Policy(0, 0, 0);
+        configWithActiveRule.applyNotificationPolicy(dndPolicy);
+        when(mNm.getZenModeConfig()).thenReturn(configWithActiveRule);
+
+        ZenMode mode = mBackend.getMode(ZenMode.MANUAL_DND_MODE_ID);
+
+        // By default, manual rule is inactive
+        assertThat(mode).isNotNull();
+        assertThat(mode.isActive()).isFalse();
+
+        // Now the returned config will represent the manual rule being active
+        when(mNm.getZenModeConfig()).thenReturn(configWithManualRule(configWithActiveRule, true));
+        ZenMode activeMode = mBackend.getMode(ZenMode.MANUAL_DND_MODE_ID);
+        assertThat(activeMode).isNotNull();
+        assertThat(activeMode.isActive()).isTrue();
+    }
+
+    @Test
+    public void getMode_zenRule_returnsCorrectActiveState() {
+        // Set up a base config that has an active manual rule and "rule2", to make sure we're
+        // looking at the correct rule's info.
+        ZenModeConfig configWithActiveRules = configWithRule(
+                configWithManualRule(new ZenModeConfig(), true),  // active manual rule
+                "rule2", ZEN_RULE, true);  // active rule 2
+
+        when(mNm.getAutomaticZenRule(eq(ZEN_RULE_ID))).thenReturn(ZEN_RULE);
+        when(mNm.getZenModeConfig()).thenReturn(
+                configWithRule(configWithActiveRules, ZEN_RULE_ID, ZEN_RULE, false));
+
+        // Round 1: the current config should indicate that the rule is not active
+        ZenMode mode = mBackend.getMode(ZEN_RULE_ID);
+        assertThat(mode).isNotNull();
+        assertThat(mode.isActive()).isFalse();
+
+        when(mNm.getZenModeConfig()).thenReturn(
+                configWithRule(configWithActiveRules, ZEN_RULE_ID, ZEN_RULE, true));
+        ZenMode activeMode = mBackend.getMode(ZEN_RULE_ID);
+        assertThat(activeMode).isNotNull();
+        assertThat(activeMode.isActive()).isTrue();
+    }
+
+    @Test
+    public void updateMode_manualDnd_setsDeviceEffects() throws Exception {
+        ZenMode manualDnd = ZenMode.manualDndMode(
+                new AutomaticZenRule.Builder("DND", Uri.EMPTY)
+                        .setZenPolicy(new ZenPolicy())
+                        .setDeviceEffects(new ZenDeviceEffects.Builder()
+                                .setShouldDimWallpaper(true)
+                                .build())
+                        .build(), false);
+
+        mBackend.updateMode(manualDnd);
+
+        verify(mNm).setManualZenRuleDeviceEffects(new ZenDeviceEffects.Builder()
+                .setShouldDimWallpaper(true)
+                .build());
+    }
+
+    @Test
+    public void updateMode_manualDnd_setsNotificationPolicy() {
+        ZenMode manualDnd = ZenMode.manualDndMode(
+                new AutomaticZenRule.Builder("DND", Uri.EMPTY)
+                        .setZenPolicy(new ZenPolicy.Builder().allowAllSounds().build())
+                        .build(), false);
+
+        mBackend.updateMode(manualDnd);
+
+        verify(mNm).setNotificationPolicy(eq(new ZenModeConfig().toNotificationPolicy(
+                new ZenPolicy.Builder().allowAllSounds().build())), eq(true));
+    }
+
+    @Test
+    public void updateMode_zenRule_updatesRule() {
+        ZenMode ruleMode = newZenMode("rule", ZEN_RULE, false);
+
+        mBackend.updateMode(ruleMode);
+
+        verify(mNm).updateAutomaticZenRule(eq("rule"), eq(ZEN_RULE), eq(true));
+    }
+
+    @Test
+    public void activateMode_manualDnd_setsZenModeImportant() {
+        mBackend.activateMode(ZenMode.manualDndMode(MANUAL_DND_RULE, false), null);
+
+        verify(mNm).setZenMode(eq(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS), eq(null),
+                any(), eq(true));
+    }
+
+    @Test
+    public void activateMode_manualDndWithDuration_setsZenModeImportantWithCondition() {
+        mBackend.activateMode(ZenMode.manualDndMode(MANUAL_DND_RULE, false),
+                Duration.ofMinutes(30));
+
+        verify(mNm).setZenMode(eq(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS),
+                eq(ZenModeConfig.toTimeCondition(mContext, 30, 0, true).id),
+                any(),
+                eq(true));
+    }
+
+    @Test
+    public void activateMode_zenRule_setsRuleStateActive() {
+        mBackend.activateMode(newZenMode(ZEN_RULE_ID, ZEN_RULE, false), null);
+
+        verify(mNm).setAutomaticZenRuleState(eq(ZEN_RULE_ID),
+                eq(new Condition(ZEN_RULE.getConditionId(), "", Condition.STATE_TRUE,
+                        Condition.SOURCE_USER_ACTION)));
+    }
+
+    @Test
+    public void activateMode_zenRuleWithDuration_fails() {
+        assertThrows(IllegalArgumentException.class,
+                () -> mBackend.activateMode(newZenMode(ZEN_RULE_ID, ZEN_RULE, false),
+                        Duration.ofMinutes(30)));
+    }
+
+    @Test
+    public void deactivateMode_manualDnd_setsZenModeOff() {
+        mBackend.deactivateMode(ZenMode.manualDndMode(MANUAL_DND_RULE, true));
+
+        verify(mNm).setZenMode(eq(ZEN_MODE_OFF), eq(null), any(), eq(true));
+    }
+
+    @Test
+    public void deactivateMode_zenRule_setsRuleStateInactive() {
+        mBackend.deactivateMode(newZenMode(ZEN_RULE_ID, ZEN_RULE, false));
+
+        verify(mNm).setAutomaticZenRuleState(eq(ZEN_RULE_ID),
+                eq(new Condition(ZEN_RULE.getConditionId(), "", Condition.STATE_FALSE,
+                        Condition.SOURCE_USER_ACTION)));
+    }
+
+    @Test
+    public void removeMode_zenRule_deletesRule() {
+        mBackend.removeMode(newZenMode(ZEN_RULE_ID, ZEN_RULE, false));
+
+        verify(mNm).removeAutomaticZenRule(ZEN_RULE_ID, true);
+    }
+
+    @Test
+    public void removeMode_manualDnd_fails() {
+        assertThrows(IllegalArgumentException.class,
+                () -> mBackend.removeMode(ZenMode.manualDndMode(MANUAL_DND_RULE, false)));
+    }
+}
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 097840e..5ddf005 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -45,7 +45,7 @@
     <integer name="def_location_mode">3</integer>
     <!-- 0 == off, 1 == on-->
     <integer name="def_paired_device_location_mode">1</integer>
-    <bool name="assisted_gps_enabled">true</bool>
+    <bool name="assisted_gps_enabled">false</bool>
     <bool name="def_netstats_enabled">true</bool>
     <bool name="def_usb_mass_storage_enabled">true</bool>
     <bool name="def_wifi_on">false</bool>
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 9f2ab69..5f23651 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -134,6 +134,7 @@
         Settings.Secure.SFPS_PERFORMANT_AUTH_ENABLED,
         Settings.Secure.ACTIVE_UNLOCK_ON_WAKE,
         Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT,
+        Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY,
         Settings.Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL,
         Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS,
         Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO,
@@ -227,6 +228,7 @@
         Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED,
         Settings.Secure.ACCESSIBILITY_MAGNIFICATION_JOYSTICK_ENABLED,
         Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED,
+        Settings.Secure.ACCESSIBILITY_MOUSE_KEYS_ENABLED,
         Settings.Secure.ACCESSIBILITY_PINCH_TO_ZOOM_ANYWHERE_ENABLED,
         Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED,
         Settings.Secure.ODI_CAPTIONS_VOLUME_UI_ENABLED,
@@ -279,5 +281,6 @@
         Settings.Secure.ON_DEVICE_INTELLIGENCE_UNBIND_TIMEOUT_MS,
         Settings.Secure.ON_DEVICE_INFERENCE_UNBIND_TIMEOUT_MS,
         Settings.Secure.ON_DEVICE_INTELLIGENCE_IDLE_TIMEOUT_MS,
+        Settings.Secure.MANDATORY_BIOMETRICS,
     };
 }
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
index 00fb7a1..2cdd0ae 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
@@ -80,6 +80,7 @@
                 Settings.System.SIP_RECEIVE_CALLS,
                 Settings.System.POINTER_SPEED,
                 Settings.System.POINTER_FILL_STYLE,
+                Settings.System.POINTER_STROKE_STYLE,
                 Settings.System.POINTER_SCALE,
                 Settings.System.VIBRATE_ON,
                 Settings.System.VIBRATE_WHEN_RINGING,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index cb7ac45..c8da8af 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -195,6 +195,7 @@
         VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_WAKE, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS, ANY_STRING_VALIDATOR);
         VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO, ANY_STRING_VALIDATOR);
         VALIDATORS.put(Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
@@ -438,5 +439,7 @@
         VALIDATORS.put(Secure.ON_DEVICE_INFERENCE_UNBIND_TIMEOUT_MS, ANY_LONG_VALIDATOR);
         VALIDATORS.put(Secure.ON_DEVICE_INTELLIGENCE_UNBIND_TIMEOUT_MS, ANY_LONG_VALIDATOR);
         VALIDATORS.put(Secure.ON_DEVICE_INTELLIGENCE_IDLE_TIMEOUT_MS, NONE_NEGATIVE_LONG_VALIDATOR);
+        VALIDATORS.put(Secure.ACCESSIBILITY_MOUSE_KEYS_ENABLED, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.MANDATORY_BIOMETRICS, new InclusiveIntegerRangeValidator(0, 1));
     }
 }
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
index 4235bc4..7b927d7 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
@@ -30,6 +30,8 @@
 import static android.view.PointerIcon.LARGE_POINTER_SCALE;
 import static android.view.PointerIcon.POINTER_ICON_VECTOR_STYLE_FILL_BEGIN;
 import static android.view.PointerIcon.POINTER_ICON_VECTOR_STYLE_FILL_END;
+import static android.view.PointerIcon.POINTER_ICON_VECTOR_STYLE_STROKE_BEGIN;
+import static android.view.PointerIcon.POINTER_ICON_VECTOR_STYLE_STROKE_END;
 
 import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -213,6 +215,9 @@
         VALIDATORS.put(System.POINTER_FILL_STYLE,
                 new InclusiveIntegerRangeValidator(POINTER_ICON_VECTOR_STYLE_FILL_BEGIN,
                         POINTER_ICON_VECTOR_STYLE_FILL_END));
+        VALIDATORS.put(System.POINTER_STROKE_STYLE,
+                new InclusiveIntegerRangeValidator(POINTER_ICON_VECTOR_STYLE_STROKE_BEGIN,
+                        POINTER_ICON_VECTOR_STYLE_STROKE_END));
         VALIDATORS.put(System.POINTER_SCALE,
                 new InclusiveFloatRangeValidator(DEFAULT_POINTER_SCALE, LARGE_POINTER_SCALE));
         VALIDATORS.put(System.TOUCHPAD_POINTER_SPEED, new InclusiveIntegerRangeValidator(-7, 7));
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
index e77cf2f..2227943 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DeviceConfigService.java
@@ -189,22 +189,13 @@
 
       public static HashMap<String, String> getAllFlags(IContentProvider provider) {
         HashMap<String, String> allFlags = new HashMap<String, String>();
-        try {
-            Bundle args = new Bundle();
-            args.putInt(Settings.CALL_METHOD_USER_KEY,
-                ActivityManager.getService().getCurrentUser().id);
-            Bundle b = provider.call(new AttributionSource(Process.myUid(),
-                    resolveCallingPackage(), null), Settings.AUTHORITY,
-                    Settings.CALL_METHOD_LIST_CONFIG, null, args);
-            if (b != null) {
-                Map<String, String> flagsToValues =
-                    (HashMap) b.getSerializable(Settings.NameValueTable.VALUE);
-                allFlags.putAll(flagsToValues);
+        for (DeviceConfig.Properties properties : DeviceConfig.getAllProperties()) {
+            List<String> keys = new ArrayList<>(properties.getKeyset());
+            for (String flagName : properties.getKeyset()) {
+                String fullName = properties.getNamespace() + "/" + flagName;
+                allFlags.put(fullName, properties.getString(flagName, null));
             }
-        } catch (RemoteException e) {
-            throw new RuntimeException("Failed in IPC", e);
         }
-
         return allFlags;
       }
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 384cb7e..cd37ad1 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2916,6 +2916,9 @@
                 Settings.System.POINTER_FILL_STYLE,
                 SystemSettingsProto.Pointer.POINTER_FILL_STYLE);
         dumpSetting(s, p,
+                Settings.System.POINTER_STROKE_STYLE,
+                SystemSettingsProto.Pointer.POINTER_STROKE_STYLE);
+        dumpSetting(s, p,
                 Settings.System.POINTER_SCALE,
                 SystemSettingsProto.Pointer.POINTER_SCALE);
         p.end(pointerToken);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index d54236e..e8ef620 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -44,6 +44,7 @@
 import static com.android.providers.settings.SettingsState.makeKey;
 
 import android.Manifest;
+import android.aconfigd.AconfigdFlagInfo;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
@@ -1189,6 +1190,8 @@
 
         synchronized (mLock) {
             if (getSyncDisabledModeConfigLocked() != SYNC_DISABLED_MODE_NONE) {
+                Slog.v(LOG_TAG, "did not write settings for prefix '"
+                                + prefix + "' because sync is disabled");
                 return SET_ALL_RESULT_DISABLED;
             }
             final int key = makeKey(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM);
@@ -1369,10 +1372,27 @@
                 }
             }
 
+            Map<String, AconfigdFlagInfo> aconfigFlagInfos =
+                    settingsState.getAconfigDefaultFlags();
+
             for (int i = 0; i < nameCount; i++) {
                 String name = names.get(i);
                 Setting setting = settingsState.getSettingLocked(name);
-                if (prefix == null || setting.getName().startsWith(prefix)) {
+                if (prefix == null || name.startsWith(prefix)) {
+                    if (Flags.ignoreXmlForReadOnlyFlags()) {
+                        int slashIndex = name.indexOf("/");
+                        boolean validSlashIndex = slashIndex != -1
+                                && slashIndex != 0
+                                && slashIndex != name.length();
+                        if (validSlashIndex) {
+                            String flagName = name.substring(slashIndex + 1);
+                            AconfigdFlagInfo flagInfo = aconfigFlagInfos.get(flagName);
+                            if (flagInfo != null && !flagInfo.getIsReadWrite()) {
+                                continue;
+                            }
+                        }
+                    }
+
                     flagsToValues.put(setting.getName(), setting.getValue());
                 }
             }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 05eb044..452edd9 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -203,6 +203,12 @@
 
     private static final String NULL_VALUE = "null";
 
+    // TOBO(b/312444587): remove after Test Mission 2.
+    // Bulk sync names
+    private static final String BULK_SYNC_MARKER = "aconfigd_marker/bulk_synced";
+    private static final String BULK_SYNC_TRIGGER_COUNTER =
+        "core_experiments_team_internal/BulkSyncTriggerCounterFlag__bulk_sync_trigger_counter";
+
     private static final ArraySet<String> sSystemPackages = new ArraySet<>();
 
     private final Object mWriteLock = new Object();
@@ -409,8 +415,7 @@
                     }
                 }
                 // TOBO(b/312444587): remove the comparison logic after Test Mission 2.
-                if (mSettings.get("aconfigd_marker/bulk_synced").value.equals("true")
-                        && requests == null) {
+                if (requests == null) {
                     Map<String, AconfigdFlagInfo> aconfigdFlagMap =
                             AconfigdJavaUtils.listFlagsValueInNewStorage(localSocket);
                     compareFlagValueInNewStorage(
@@ -534,7 +539,7 @@
             return null;
         }
         AconfigdFlagInfo flag = flagInfoDefault.get(fullFlagName);
-        if (flag == null) {
+        if (flag == null || !namespace.equals(flag.getNamespace())) {
             return null;
         }
 
@@ -553,15 +558,33 @@
     public ProtoOutputStream handleBulkSyncToNewStorage(
             Map<String, AconfigdFlagInfo> aconfigFlagMap) {
         // get marker or add marker if it does not exist
-        final String bulkSyncMarkerName = new String("aconfigd_marker/bulk_synced");
-        Setting markerSetting = mSettings.get(bulkSyncMarkerName);
+        Setting markerSetting = mSettings.get(BULK_SYNC_MARKER);
+        int localCounter = 0;
         if (markerSetting == null) {
-            markerSetting = new Setting(bulkSyncMarkerName, "false", false, "aconfig", "aconfig");
-            mSettings.put(bulkSyncMarkerName, markerSetting);
+            markerSetting = new Setting(BULK_SYNC_MARKER, "0", false, "aconfig", "aconfig");
+            mSettings.put(BULK_SYNC_MARKER, markerSetting);
+        }
+        try {
+            localCounter = Integer.parseInt(markerSetting.value);
+        } catch(NumberFormatException e) {
+            // reset local counter
+            markerSetting.value = "0";
         }
 
         if (enableAconfigStorageDaemon()) {
-            if (markerSetting.value.equals("true")) {
+            Setting bulkSyncCounter = mSettings.get(BULK_SYNC_TRIGGER_COUNTER);
+            int serverCounter = 0;
+            if (bulkSyncCounter != null) {
+                try {
+                    serverCounter = Integer.parseInt(bulkSyncCounter.value);
+                } catch (NumberFormatException e) {
+                    // reset the local value of server counter
+                    bulkSyncCounter.value = "0";
+                }
+            }
+
+            boolean shouldSync = localCounter < serverCounter;
+            if (!shouldSync) {
                 // CASE 1, flag is on, bulk sync marker true, nothing to do
                 return null;
             } else {
@@ -600,20 +623,12 @@
                 }
 
                 // mark sync has been done
-                markerSetting.value = "true";
+                markerSetting.value = String.valueOf(serverCounter);
                 scheduleWriteIfNeededLocked();
                 return requests;
             }
         } else {
-            if (markerSetting.value.equals("true")) {
-                // CASE 3, flag is off, bulk sync marker true, clear the marker
-                markerSetting.value = "false";
-                scheduleWriteIfNeededLocked();
-                return null;
-            } else {
-                // CASE 4, flag is off, bulk sync marker false, nothing to do
-                return null;
-            }
+            return null;
         }
     }
 
@@ -692,6 +707,7 @@
                                     .setFlagName(flag.getName())
                                     .setDefaultFlagValue(flagValue)
                                     .setIsReadWrite(isReadWrite)
+                                    .setNamespace(flag.getNamespace())
                                     .build());
                 }
             }
@@ -724,8 +740,6 @@
     // The settings provider must hold its lock when calling here.
     @GuardedBy("mLock")
     public void removeSettingsForPackageLocked(String packageName) {
-        boolean removedSomething = false;
-
         final int settingCount = mSettings.size();
         for (int i = settingCount - 1; i >= 0; i--) {
             String name = mSettings.keyAt(i);
@@ -736,14 +750,9 @@
             }
             Setting setting = mSettings.valueAt(i);
             if (packageName.equals(setting.packageName)) {
-                mSettings.removeAt(i);
-                removedSomething = true;
+                deleteSettingLocked(setting.name);
             }
         }
-
-        if (removedSomething) {
-            scheduleWriteIfNeededLocked();
-        }
     }
 
     // The settings provider must hold its lock when calling here.
@@ -765,6 +774,13 @@
         }
     }
 
+    @NonNull
+    public Map<String, AconfigdFlagInfo> getAconfigDefaultFlags() {
+        synchronized (mLock) {
+            return mAconfigDefaultFlags;
+        }
+    }
+
     // The settings provider must hold its lock when calling here.
     public Setting getSettingLocked(String name) {
         if (TextUtils.isEmpty(name)) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig b/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig
index d20fbf5..4f5955b 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig
+++ b/packages/SettingsProvider/src/com/android/providers/settings/device_config_service.aconfig
@@ -41,3 +41,14 @@
     description: "If this flag is detected as true on boot, writes a logfile to track storage migration correctness."
     bug: "328444881"
 }
+
+flag {
+    name: "ignore_xml_for_read_only_flags"
+    namespace: "core_experiments_team_internal"
+    description: "When enabled, ignore any flag in the SettingsProvider XML for RO flags."
+    bug: "345007098"
+    is_fixed_read_only: true
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 5f8e933..411decd 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -177,6 +177,7 @@
                     Settings.Global.DESK_UNDOCK_SOUND,
                     Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT,
                     Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS,
+                    Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES,
                     Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES,
                     Settings.Global.DEVELOPMENT_FORCE_RTL,
                     Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW,
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
index 94aeb9b..48ce49d 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
@@ -151,12 +151,14 @@
                                                 .setFlagName("flag1")
                                                 .setDefaultFlagValue("false")
                                                 .setIsReadWrite(true)
+                                                .setNamespace("test_namespace")
                                                 .build();
         AconfigdFlagInfo flag2 = AconfigdFlagInfo.newBuilder()
                                                 .setPackageName("com.android.flags")
                                                 .setFlagName("flag2")
                                                 .setDefaultFlagValue("true")
                                                 .setIsReadWrite(false)
+                                                .setNamespace("test_namespace")
                                                 .build();
         Map<String, AconfigdFlagInfo> flagInfoDefault = new HashMap<>();
 
@@ -986,7 +988,40 @@
     }
 
     @Test
-   public void testGetFlagOverrideToSync() {
+    public void testMemoryUsagePerPackage_StatsUpdatedOnAppDataCleared() {
+        SettingsState settingsState =
+                new SettingsState(
+                        InstrumentationRegistry.getContext(), mLock, mSettingsFile, 1,
+                        SettingsState.MAX_BYTES_PER_APP_PACKAGE_LIMITED, Looper.getMainLooper());
+        final String testKey1 = SETTING_NAME;
+        final String testKey2 = SETTING_NAME + "_2";
+        final String testValue1 = Strings.repeat("A", 9000);
+        final String testValue2 = Strings.repeat("A", 9001);
+        final String packageName = "p";
+        // Inserting the first setting should be okay
+        settingsState.insertSettingLocked(testKey1, testValue1, null, true, packageName);
+        int expectedMemUsageForPackage = (testKey1.length() + testValue1.length()
+                + testValue1.length() /* size for default */) * Character.BYTES;
+        assertEquals(expectedMemUsageForPackage, settingsState.getMemoryUsage(packageName));
+        // Inserting the second setting should fail
+        try {
+            settingsState.insertSettingLocked(testKey2, testValue2, null, true, packageName);
+            fail("Should throw because it exceeded max memory usage per package");
+        } catch (IllegalStateException ex) {
+            assertTrue(ex.getMessage().startsWith("You are adding too many system settings."));
+        }
+        // Now clear app data and check that the memory usage is cleared
+        settingsState.removeSettingsForPackageLocked(packageName);
+        assertEquals(0, settingsState.getMemoryUsage(packageName));
+        // Try inserting the second setting again and it should go through
+        settingsState.insertSettingLocked(testKey2, testValue2, null, true, packageName);
+        expectedMemUsageForPackage = (testKey2.length() + testValue2.length()
+                + testValue2.length() /* size for default */) * Character.BYTES;
+        assertEquals(expectedMemUsageForPackage, settingsState.getMemoryUsage(packageName));
+    }
+
+    @Test
+    public void testGetFlagOverrideToSync() {
         int configKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_CONFIG, 0);
         Object lock = new Object();
         SettingsState settingsState =
@@ -1018,12 +1053,17 @@
                         .setFlagName("flag1")
                         .setDefaultFlagValue("false")
                         .setIsReadWrite(true)
+                        .setNamespace("test_namespace")
                         .build();
 
         flagInfoDefault.put(flag1.getFullFlagName(), flag1);
 
-        // server override
+        // not the right namespace
+        assertNull(
+                settingsState.getFlagOverrideToSync(
+                        "some_namespace/com.android.flags.flag1", "true", flagInfoDefault));
 
+        // server override
         settingsState.getFlagOverrideToSync(
                 "test_namespace/com.android.flags.flag1", "true", flagInfoDefault);
         assertEquals("com.android.flags", flag1.getPackageName());
@@ -1079,21 +1119,45 @@
                         .setIsReadWrite(false)
                         .build());
 
+        String bulkSyncMarker = "aconfigd_marker/bulk_synced";
+        String bulkSyncCounter =
+                "core_experiments_team_internal/" +
+                "BulkSyncTriggerCounterFlag__bulk_sync_trigger_counter";
+
         synchronized (lock) {
-            settingsState.insertSettingLocked(
-                    "aconfigd_marker/bulk_synced", "false", null, false, "aconfig");
+            settingsState.insertSettingLocked(bulkSyncMarker, "0", null, false, "aconfig");
+            settingsState.insertSettingLocked(bulkSyncCounter, "1", null, false,
+                    "com.google.android.platform.core_experiments_team_internal");
 
             // first bulk sync
             ProtoOutputStream requests = settingsState.handleBulkSyncToNewStorage(flags);
             assertTrue(requests != null);
             String value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
-            assertEquals("true", value);
+            assertEquals("1", value);
 
             // send time should no longer bulk sync
             requests = settingsState.handleBulkSyncToNewStorage(flags);
-            assertTrue(requests == null);
+            assertNull(requests);
             value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
-            assertEquals("true", value);
+            assertEquals("1", value);
+
+            // won't sync if the marker is string
+            settingsState.insertSettingLocked(bulkSyncMarker, "true", null, false, "aconfig");
+            settingsState.insertSettingLocked(bulkSyncCounter, "0", null, false,
+                    "com.google.android.platform.core_experiments_team_internal");
+            requests = settingsState.handleBulkSyncToNewStorage(flags);
+            assertNull(requests);
+            value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
+            assertEquals("0", value);
+
+            // won't sync if the marker and counter value are the same
+            settingsState.insertSettingLocked(bulkSyncMarker, "1", null, false, "aconfig");
+            settingsState.insertSettingLocked(bulkSyncCounter, "1", null, false,
+                    "com.google.android.platform.core_experiments_team_internal");
+            requests = settingsState.handleBulkSyncToNewStorage(flags);
+            assertNull(requests);
+            value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
+            assertEquals("1", value);
         }
     }
 
@@ -1107,21 +1171,34 @@
                 SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, Looper.getMainLooper());
 
         Map<String, AconfigdFlagInfo> flags = new HashMap<>();
+        String bulkSyncMarker = "aconfigd_marker/bulk_synced";
+        String bulkSyncCounter =
+                "core_experiments_team_internal/" +
+                "BulkSyncTriggerCounterFlag__bulk_sync_trigger_counter";
         synchronized (lock) {
             settingsState.insertSettingLocked("aconfigd_marker/bulk_synced",
                     "true", null, false, "aconfig");
 
             // when aconfigd is off, should change the marker to false
             ProtoOutputStream requests = settingsState.handleBulkSyncToNewStorage(flags);
-            assertTrue(requests == null);
+            assertNull(requests);
             String value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
-            assertEquals("false", value);
+            assertEquals("0", value);
 
             // marker started with false value, after call, it should remain false
             requests = settingsState.handleBulkSyncToNewStorage(flags);
-            assertTrue(requests == null);
+            assertNull(requests);
             value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
-            assertEquals("false", value);
+            assertEquals("0", value);
+
+            // won't sync
+            settingsState.insertSettingLocked(bulkSyncMarker, "0", null, false, "aconfig");
+            settingsState.insertSettingLocked(bulkSyncCounter, "1", null, false,
+                    "com.google.android.platform.core_experiments_team_internal");
+            requests = settingsState.handleBulkSyncToNewStorage(flags);
+            assertNull(requests);
+            value = settingsState.getSettingLocked("aconfigd_marker/bulk_synced").getValue();
+            assertEquals("0", value);
         }
     }
 
@@ -1164,6 +1241,7 @@
                         .setFlagName("flag1")
                         .setDefaultFlagValue("false")
                         .setIsReadWrite(true)
+                        .setNamespace("test_namespace")
                         .build();
         flagInfoDefault.put(flag1.getFullFlagName(), flag1);
 
@@ -1186,6 +1264,7 @@
                         .setFlagName("flag2")
                         .setDefaultFlagValue("false")
                         .setIsReadWrite(true)
+                        .setNamespace("test_namespace")
                         .build();
         flagInfoDefault.put(flag2.getFullFlagName(), flag2);
         synchronized (lock) {
@@ -1207,6 +1286,7 @@
                         .setFlagName("flag3")
                         .setDefaultFlagValue("false")
                         .setIsReadWrite(false)
+                        .setNamespace("test_namespace")
                         .build();
         flagInfoDefault.put(flag3.getFullFlagName(), flag3);
         synchronized (lock) {
diff --git a/packages/Shell/res/values-fa/strings.xml b/packages/Shell/res/values-fa/strings.xml
index 46c847b..f4a3a50 100644
--- a/packages/Shell/res/values-fa/strings.xml
+++ b/packages/Shell/res/values-fa/strings.xml
@@ -24,10 +24,10 @@
     <string name="bugreport_updating_wait" msgid="3322151947853929470">"لطفاً منتظر بمانید..."</string>
     <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"گزارش مشکل به‌زودی در تلفن نشان داده می‌شود"</string>
     <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"برای هم‌رسانی گزارش اشکالتان، انتخاب کنید"</string>
-    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"برای هم‌رسانی گزارش اشکال، ضربه بزنید"</string>
+    <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"برای هم‌رسانی گزارش اشکال، تک‌ضرب بزنید"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"انتخاب کنید تا گزارش اشکالتان بدون نماگرفت به اشتراک گذاشته شود یا منتظر بمانید گرفتن عکس از صفحه‌نمایش تمام شود"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"برای هم‌رسانی گزارش مشکل بدون نماگرفت، ضربه بزنید یا صبر کنید تا نماگرفت گرفته شود."</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"برای هم‌رسانی گزارش مشکل بدون نماگرفت، ضربه بزنید یا صبر کنید تا نماگرفت گرفته شود."</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"برای هم‌رسانی گزارش مشکل بدون نماگرفت، تک‌ضرب بزنید یا صبر کنید تا نماگرفت گرفته شود."</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"برای هم‌رسانی گزارش مشکل بدون نماگرفت، تک‌ضرب بزنید یا صبر کنید تا نماگرفت گرفته شود."</string>
     <string name="bugreport_confirm" msgid="5917407234515812495">"گزارش‌های اشکال حاوی داده‌هایی از فایل‌های مختلف گزارش سیستم هستند، که ممکن است حاوی داده‌های حساس شما (از قبیل داده‌های استفاده از برنامه و مکان) باشند. گزارش‌های اشکال را فقط با افراد و برنامه‌هایی که به آن‌ها اعتماد دارید به‌اشتراک بگذارید."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"دوباره نشان داده نشود"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"گزارش اشکال"</string>
diff --git a/packages/Shell/res/values-fr-rCA/strings.xml b/packages/Shell/res/values-fr-rCA/strings.xml
index 54ae954..7609050 100644
--- a/packages/Shell/res/values-fr-rCA/strings.xml
+++ b/packages/Shell/res/values-fr-rCA/strings.xml
@@ -28,7 +28,7 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Sélectionnez pour partager le rapport de bogue sans saisie d\'écran ou attendez que la saisie soit prête"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Touchez pour partager le rapport de bogue sans saisie d\'écran ou attendez que la saisie soit prête"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Touchez pour partager le rapport de bogue sans saisie d\'écran ou attendez que la saisie soit prête"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"Les rapports de bogue contiennent des données des fichiers journaux du système, y compris des données que vous considérez comme sensibles (comme des renseignements sur l\'utilisation des applications et des données de localisation). Ne partagez les rapports de bogue qu\'avec les applications et les personnes en qui vous avez confiance."</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"Les rapports de bogue contiennent des données des fichiers journaux du système, y compris des données que vous considérez comme sensibles (comme des renseignements sur l\'utilisation des applis et des données de localisation). Ne partagez les rapports de bogue qu\'avec les applis et les personnes en qui vous avez confiance."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Ne plus afficher"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Rapports de bogues"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Impossible de lire le fichier du rapport de bogue"</string>
diff --git a/packages/Shell/res/values-nb/strings.xml b/packages/Shell/res/values-nb/strings.xml
index ce39385..db83f29 100644
--- a/packages/Shell/res/values-nb/strings.xml
+++ b/packages/Shell/res/values-nb/strings.xml
@@ -25,9 +25,9 @@
     <string name="bugreport_finished_text" product="watch" msgid="1223616207145252689">"Feilrapporten vises snart på telefonen"</string>
     <string name="bugreport_finished_text" product="tv" msgid="5758325479058638893">"Velg for å dele feilrapporten"</string>
     <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Trykk for å dele feilrapporten"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Velg for å dele feilrapporten uten noen skjermdump, eller vent til skjermdumpen er klar"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Trykk for å dele feilrapporten uten noen skjermdump, eller vent til skjermdumpen er klar"</string>
-    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Trykk for å dele feilrapporten uten noen skjermdump, eller vent til skjermdumpen er klar"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Velg for å dele feilrapporten uten noen skjermbilde, eller vent til skjermbildet er klar"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Trykk for å dele feilrapporten uten noen skjermbilde, eller vent til skjermbildet er klar"</string>
+    <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Trykk for å dele feilrapporten uten noen skjermbilde, eller vent til skjermbildet er klar"</string>
     <string name="bugreport_confirm" msgid="5917407234515812495">"Feilrapporter inneholder data fra systemets forskjellige loggfiler. Dette kan inkludere data du ser på som sensitiv (for eksempel appbruk og posisjonsdata). Du bør bare dele feilrapporter med folk og apper du stoler på."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Ikke vis igjen"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Feilrapporter"</string>
@@ -35,7 +35,7 @@
     <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"Kunne ikke legge til informasjon fra feilrapporten i ZIP-filen"</string>
     <string name="bugreport_unnamed" msgid="2800582406842092709">"uten navn"</string>
     <string name="bugreport_info_action" msgid="2158204228510576227">"Detaljer"</string>
-    <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Skjermdump"</string>
+    <string name="bugreport_screenshot_action" msgid="8677781721940614995">"Skjermbilde"</string>
     <string name="bugreport_screenshot_taken" msgid="5684211273096253120">"Skjermdumpen er tatt."</string>
     <string name="bugreport_screenshot_failed" msgid="5853049140806834601">"Skjermdumpen kunne ikke tas."</string>
     <string name="bugreport_info_dialog_title" msgid="1355948594292983332">"Detaljer om feilrapport <xliff:g id="ID">#%d</xliff:g>"</string>
diff --git a/packages/SimAppDialog/res/values-fr-rCA/strings.xml b/packages/SimAppDialog/res/values-fr-rCA/strings.xml
index b607585..0ce7a2a 100644
--- a/packages/SimAppDialog/res/values-fr-rCA/strings.xml
+++ b/packages/SimAppDialog/res/values-fr-rCA/strings.xml
@@ -17,10 +17,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" msgid="8898068901680117589">"Boîte de dialogue de l\'application SIM"</string>
+    <string name="app_name" msgid="8898068901680117589">"Boîte de dialogue de l\'appli SIM"</string>
     <string name="install_carrier_app_title" msgid="334729104862562585">"Activer le service cellulaire"</string>
-    <string name="install_carrier_app_description" msgid="4014303558674923797">"Pour que le nouveau module SIM fonctionne correctement, vous devez installer l\'application <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+    <string name="install_carrier_app_description" msgid="4014303558674923797">"Pour que le nouveau module SIM fonctionne correctement, vous devez installer l\'appli <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="install_carrier_app_description_default" msgid="7356830245205847840">"Pour que le nouveau module SIM fonctionne, vous devez installer l\'appli du fournisseur de services"</string>
     <string name="install_carrier_app_defer_action" msgid="2558576736886876209">"Pas maintenant"</string>
-    <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Télécharger l\'application"</string>
+    <string name="install_carrier_app_download_action" msgid="7859229305958538064">"Télécharger l\'appli"</string>
 </resources>
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index fde7c2c..9cbb1bd 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -23,7 +23,10 @@
 // See: http://go/android-license-faq
 license {
     name: "frameworks_base_packages_SystemUI_license",
-    visibility: [":__subpackages__"],
+    visibility: [
+        ":__subpackages__",
+        "//development/samples/SceneTransitionLayoutDemo:__subpackages__",
+    ],
     license_kinds: [
         "SPDX-license-identifier-Apache-2.0",
     ],
@@ -98,13 +101,66 @@
     ],
 }
 
-// Tests where robolectric failed at runtime. (go/multivalent-tests)
+// Tests where robolectric failed at runtime. (go/central-multivalent)
 filegroup {
     name: "SystemUI-tests-broken-robofiles-run",
     srcs: [
+        "tests/src/**/systemui/ExpandHelperTest.java",
+        "tests/src/**/AAAPlusPlusVerifySysuiRequiredTestPropertiesTest.java",
+        "tests/src/**/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuControllerTest.java",
+        "tests/src/**/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java",
+        "tests/src/**/systemui/screenshot/appclips/AppClipsActivityTest.java",
+        "tests/src/**/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java",
+        "tests/src/**/systemui/screenshot/appclips/AppClipsViewModelTest.java",
+        "tests/src/**/systemui/appops/AppOpsControllerTest.java",
+        "tests/src/**/systemui/biometrics/BiometricNotificationServiceTest.java",
+        "tests/src/**/systemui/bluetooth/BroadcastDialogDelegateTest.java",
+        "tests/src/**/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java",
+        "tests/src/**/systemui/communal/data/backup/CommunalBackupHelperTest.kt",
+        "tests/src/**/systemui/controls/ui/ControlsPopupMenuTest.kt",
+        "tests/src/**/systemui/classifier/DistanceClassifierTest.java",
+        "tests/src/**/systemui/doze/DozeScreenBrightnessTest.java",
+        "tests/src/**/systemui/doze/DozeSensorsTest.java",
+        "tests/src/**/systemui/doze/DozeTriggersTest.java",
+        "tests/src/**/systemui/classifier/FalsingDataProviderTest.java",
+        "tests/src/**/systemui/screenshot/ImageExporterTest.java",
+        "tests/src/**/systemui/bouncer/data/repository/KeyguardBouncerRepositoryTest.kt",
+        "tests/src/**/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractorTest.kt",
+        "tests/src/**/systemui/logcat/LogAccessDialogActivityTest.java",
+        "tests/src/**/systemui/media/controls/domain/pipeline/MediaDeviceManagerTest.kt",
+        "tests/src/**/systemui/media/controls/domain/pipeline/MediaSessionBasedFilterTest.kt",
+        "tests/src/**/systemui/accessibility/floatingmenu/MenuNotificationFactoryTest.java",
+        "tests/src/**/systemui/accessibility/floatingmenu/MenuViewLayerTest.java",
+        "tests/src/**/systemui/accessibility/floatingmenu/MenuViewTest.java",
+        "tests/src/**/systemui/classifier/PointerCountClassifierTest.java",
+        "tests/src/**/systemui/qs/tileimpl/QSIconViewImplTest_311121830.kt",
+        "tests/src/**/systemui/accessibility/floatingmenu/RadiiAnimatorTest.java",
+        "tests/src/**/systemui/screenrecord/RecordingControllerTest.java",
+        "tests/src/**/systemui/screenshot/RequestProcessorTest.kt",
+        "tests/src/**/systemui/media/controls/domain/resume/ResumeMediaBrowserTest.kt",
+        "tests/src/**/systemui/screenshot/SaveImageInBackgroundTaskTest.kt",
+        "tests/src/**/systemui/screenshot/scroll/ScrollCaptureClientTest.java",
+        "tests/src/**/systemui/accessibility/SecureSettingsContentObserverTest.java",
+        "tests/src/**/systemui/media/controls/ui/viewmodel/SeekBarViewModelTest.kt",
+        "tests/src/**/systemui/qs/external/TileServicesTest.java",
+        "tests/src/**/systemui/ambient/touch/TouchMonitorTest.java",
+        "tests/src/**/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java",
+        "tests/src/**/systemui/accessibility/WindowMagnificationSettingsTest.java",
+        "tests/src/androidx/core/animation/AnimatorTestRuleIsolationTest.kt",
+        "tests/src/**/systemui/CameraProtectionLoaderImplTest.kt",
+        "tests/src/**/systemui/DependencyTest.java",
+        "tests/src/**/systemui/InitControllerTest.java",
+        "tests/src/**/systemui/SliceBroadcastRelayHandlerTest.java",
+        "tests/src/**/systemui/SystemUIApplicationTest.kt",
+        "tests/src/**/systemui/SysUICutoutProviderTest.kt",
+        "tests/src/**/keyguard/ActiveUnlockConfigTest.kt",
+        "tests/src/**/keyguard/AdminSecondaryLockScreenControllerTest.java",
+        "tests/src/**/keyguard/KeyguardClockAccessibilityDelegateTest.java",
+        "tests/src/**/keyguard/KeyguardStatusViewControllerTest.java",
         "tests/src/**/systemui/accessibility/AccessibilityButtonModeObserverTest.java",
         "tests/src/**/systemui/accessibility/AccessibilityButtonTargetsObserverTest.java",
         "tests/src/**/systemui/accessibility/FullscreenMagnificationControllerTest.java",
+        "tests/src/**/systemui/accessibility/MagnificationTest.java",
         "tests/src/**/systemui/accessibility/WindowMagnificationAnimationControllerTest.java",
         "tests/src/**/systemui/animation/FontInterpolatorTest.kt",
         "tests/src/**/systemui/animation/TextAnimatorTest.kt",
@@ -140,7 +196,7 @@
         "tests/src/**/systemui/media/dialog/MediaOutputDialogTest.java",
         "tests/src/**/systemui/media/controls/domain/resume/MediaResumeListenerTest.kt",
         "tests/src/**/systemui/mediaprojection/taskswitcher/ui/TaskSwitcherNotificationCoordinatorTest.kt",
-        "tests/src/**/systemui/navigationbar/NavigationBarButtonTest.java",
+        "tests/src/**/systemui/navigationbar/views/NavigationBarButtonTest.java",
         "tests/src/**/systemui/people/PeopleProviderTest.java",
         "tests/src/**/systemui/people/PeopleSpaceUtilsTest.java",
         "tests/src/**/systemui/people/widget/PeopleSpaceWidgetManagerTest.java",
@@ -160,6 +216,7 @@
         "tests/src/**/systemui/statusbar/KeyboardShortcutsTest.java",
         "tests/src/**/systemui/statusbar/KeyguardIndicationControllerWithCoroutinesTest.kt",
         "tests/src/**/systemui/statusbar/notification/AssistantFeedbackControllerTest.java",
+        "tests/src/**/systemui/statusbar/notification/PropertyAnimatorTest.java",
         "tests/src/**/systemui/statusbar/notification/collection/NotifCollectionTest.java",
         "tests/src/**/systemui/statusbar/notification/collection/NotificationEntryTest.java",
         "tests/src/**/systemui/statusbar/notification/collection/render/GroupExpansionManagerTest.kt",
@@ -395,7 +452,7 @@
         "tests/src/**/systemui/doze/DozeScreenStateTest.java",
         "tests/src/**/systemui/keyguard/WorkLockActivityControllerTest.java",
         "tests/src/**/systemui/media/dialog/MediaOutputControllerTest.java",
-        "tests/src/**/systemui/navigationbar/NavigationBarTest.java",
+        "tests/src/**/systemui/navigationbar/views/NavigationBarTest.java",
         "tests/src/**/systemui/power/PowerNotificationWarningsTest.java",
         "tests/src/**/systemui/power/PowerUITest.java",
         "tests/src/**/systemui/qs/QSFooterViewControllerTest.java",
@@ -498,6 +555,7 @@
         "androidx.exifinterface_exifinterface",
         "androidx.room_room-runtime",
         "androidx.room_room-ktx",
+        "androidx.datastore_datastore-preferences",
         "com.google.android.material_material",
         "device_state_flags_lib",
         "kotlinx_coroutines_android",
@@ -651,6 +709,7 @@
         "androidx.exifinterface_exifinterface",
         "androidx.room_room-runtime",
         "androidx.room_room-ktx",
+        "androidx.datastore_datastore-preferences",
         "device_state_flags_lib",
         "kotlinx-coroutines-android",
         "kotlinx-coroutines-core",
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index b37db16..666d939 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -280,6 +280,9 @@
     <!-- to adjust volume in volume panel -->
     <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
 
+    <!-- to get bluetooth audio device category -->
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED" />
+
     <!-- to access ResolverRankerServices -->
     <uses-permission android:name="android.permission.BIND_RESOLVER_RANKER_SERVICE" />
 
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-bn/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-bn/strings.xml
index 9a0ebef..00cc442 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-bn/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-bn/strings.xml
@@ -23,7 +23,7 @@
     <string name="accessibility_menu_description" msgid="4458354794093858297">"আপনার ডিভাইস নিয়ন্ত্রণ করতে, \'অ্যাক্সেসিবিলিটি মেনু\' একটি বড় অন-স্ক্রিন মেনু দেখায়। আপনি ফোন লক, ভলিউম ও উজ্জ্বলতা নিয়ন্ত্রণ, স্ক্রিনশট নেওয়া এবং আরও অনেক কিছু করতে পারবেন।"</string>
     <string name="accessibility_menu_summary" msgid="340071398148208130">"বড় করে দেখানো মেনুর মাধ্যমে ডিভাইস নিয়ন্ত্রণ করুন"</string>
     <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"অ্যাক্সেসিবিলিটি মেনুর সেটিংস"</string>
-    <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"বোতাম বড় করা"</string>
+    <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"বড় বোতাম"</string>
     <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"অ্যাক্সেসিবিলিটি মেনু বোতামের সাইজ বাড়ান"</string>
     <string name="pref_help_title" msgid="6871558837025010641">"সহায়তা"</string>
     <string name="brightness_percentage_label" msgid="7391554573977867369">"উজ্জ্বলতা <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr-rCA/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr-rCA/strings.xml
index 87a9503..e60eac0 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-fr-rCA/strings.xml
@@ -21,7 +21,7 @@
     <string name="previous_button_content_description" msgid="840869171117765966">"Aller à l\'écran précédent"</string>
     <string name="next_button_content_description" msgid="6810058269847364406">"Aller à l\'écran suivant"</string>
     <string name="accessibility_menu_description" msgid="4458354794093858297">"Le menu Accessibilité propose un grand espace à l\'écran à l\'aide duquel vous pouvez contrôler votre appareil. Utilisez-le pour verrouiller votre appareil, régler le volume et la luminosité, prendre des captures d\'écran et plus."</string>
-    <string name="accessibility_menu_summary" msgid="340071398148208130">"contrôler l\'appareil à l\'aide d\'un menu de grande taille"</string>
+    <string name="accessibility_menu_summary" msgid="340071398148208130">"Contrôle l\'appareil à l\'aide d\'un menu de grande taille"</string>
     <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Paramètres du menu Accessibilité"</string>
     <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Boutons de grande taille"</string>
     <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Augmenter la taille des boutons du menu Accessibilité"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-hi/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hi/strings.xml
index 3d59c0b..c9e8858 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-hi/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hi/strings.xml
@@ -22,7 +22,7 @@
     <string name="next_button_content_description" msgid="6810058269847364406">"अगली स्क्रीन पर जाएं"</string>
     <string name="accessibility_menu_description" msgid="4458354794093858297">"सुलभता मेन्यू, डिवाइस की स्क्रीन पर दिखने वाला एक बड़ा मेन्यू होता है. इस मेन्यू में जाकर, डिवाइस को लॉक करने, स्क्रीनशॉट लेने, स्क्रीन की रोशनी और आवाज़ को कंट्रोल करने जैसे कई काम किए जा सकते हैं."</string>
     <string name="accessibility_menu_summary" msgid="340071398148208130">"बड़े मेन्यू की मदद से डिवाइस को कंट्रोल करें"</string>
-    <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"सुलभता मेन्यू सेटिंग"</string>
+    <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"सुलभता मेन्यू की सेटिंग"</string>
     <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"बड़े बटन"</string>
     <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"सुलभता मेन्यू के बटनाें का साइज़ बढ़ाएं"</string>
     <string name="pref_help_title" msgid="6871558837025010641">"सहायता"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-hr/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hr/strings.xml
index 36fcfdc..c5388a8 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-hr/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-hr/strings.xml
@@ -22,9 +22,9 @@
     <string name="next_button_content_description" msgid="6810058269847364406">"Idi na sljedeći zaslon"</string>
     <string name="accessibility_menu_description" msgid="4458354794093858297">"Izbornik pristupačnosti veliki je zaslonski izbornik koji vam omogućuje upravljanje uređajem. Putem njega možete zaključati uređaj, upravljati glasnoćom i svjetlinom, izrađivati snimke zaslona i drugo."</string>
     <string name="accessibility_menu_summary" msgid="340071398148208130">"Upravljajte uređajem pomoću velikog izbornika"</string>
-    <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Postavke izbornika pristupačnosti"</string>
+    <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Postavke izbornika za pristupačnost"</string>
     <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Veliki gumbi"</string>
-    <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Povećanje veličine gumba izbornika Pristupačnosti"</string>
+    <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Povećaj veličinu gumba izbornika za pristupačnost"</string>
     <string name="pref_help_title" msgid="6871558837025010641">"Pomoć"</string>
     <string name="brightness_percentage_label" msgid="7391554573977867369">"Svjetlina <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
     <string name="music_volume_percentage_label" msgid="398635599662604706">"Glasnoća glazbe <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-nb/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-nb/strings.xml
index a3e7ab0..e95d0ed 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-nb/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-nb/strings.xml
@@ -2,7 +2,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="accessibility_menu_service_name" msgid="730136711554740131">"Tilgjengelighetsmeny"</string>
-    <string name="accessibility_menu_intro" msgid="3164193281544042394">"Med tilgjengelighetsmenyen får du en stor meny på skjermen for å kontrollere enheten. Du kan låse enheten, kontrollere volum og lysstyrke, ta skjermdumper med mer."</string>
+    <string name="accessibility_menu_intro" msgid="3164193281544042394">"Med tilgjengelighetsmenyen får du en stor meny på skjermen for å kontrollere enheten. Du kan låse enheten, kontrollere volum og lysstyrke, ta skjermbilder med mer."</string>
     <string name="assistant_label" msgid="6796392082252272356">"Assistent"</string>
     <string name="assistant_utterance" msgid="65509599221141377">"Assistent"</string>
     <string name="a11y_settings_label" msgid="3977714687248445050">"Tilgjengelighetsinnstillinger"</string>
@@ -12,15 +12,15 @@
     <string name="lockscreen_label" msgid="648347953557887087">"Låseskjerm"</string>
     <string name="quick_settings_label" msgid="2999117381487601865">"Hurtiginnstillinger"</string>
     <string name="notifications_label" msgid="6829741046963013567">"Varsler"</string>
-    <string name="screenshot_label" msgid="863978141223970162">"Skjermdump"</string>
-    <string name="screenshot_utterance" msgid="1430760563401895074">"Ta skjermdump"</string>
+    <string name="screenshot_label" msgid="863978141223970162">"Skjermbilde"</string>
+    <string name="screenshot_utterance" msgid="1430760563401895074">"Ta skjermbilde"</string>
     <string name="volume_up_label" msgid="8592766918780362870">"Volum opp"</string>
     <string name="volume_down_label" msgid="8574981863656447346">"Volum ned"</string>
     <string name="brightness_up_label" msgid="8010753822854544846">"Lysstyrke opp"</string>
     <string name="brightness_down_label" msgid="7115662941913272072">"Lysstyrke ned"</string>
     <string name="previous_button_content_description" msgid="840869171117765966">"Gå til forrige skjerm"</string>
     <string name="next_button_content_description" msgid="6810058269847364406">"Gå til neste skjerm"</string>
-    <string name="accessibility_menu_description" msgid="4458354794093858297">"Med tilgjengelighetsmenyen får du en stor meny på skjermen for å kontrollere enheten. Du kan låse enheten, kontrollere volum og lysstyrke, ta skjermdumper med mer."</string>
+    <string name="accessibility_menu_description" msgid="4458354794093858297">"Med tilgjengelighetsmenyen får du en stor meny på skjermen for å kontrollere enheten. Du kan låse enheten, kontrollere volum og lysstyrke, ta skjermbilder med mer."</string>
     <string name="accessibility_menu_summary" msgid="340071398148208130">"Kontroller enheten med en stor meny"</string>
     <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Innstillinger for Tilgjengelighetsmeny"</string>
     <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Store knapper"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-nl/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-nl/strings.xml
index 7535c2b..1e28bff 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-nl/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-nl/strings.xml
@@ -24,7 +24,7 @@
     <string name="accessibility_menu_summary" msgid="340071398148208130">"Bedien het apparaat via een groot menu"</string>
     <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Instellingen toegankelijkheidsmenu"</string>
     <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Grote knoppen"</string>
-    <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Vergroot knoppen in het toegankelijkheidsmenu"</string>
+    <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Maak knoppen in toegankelijkheidsmenu groter"</string>
     <string name="pref_help_title" msgid="6871558837025010641">"Hulp"</string>
     <string name="brightness_percentage_label" msgid="7391554573977867369">"Helderheid <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
     <string name="music_volume_percentage_label" msgid="398635599662604706">"Muziekvolume <xliff:g id="PERCENTAGE">%1$s</xliff:g>%%"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml
index 62f63a8..3c92f83 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml
@@ -22,9 +22,9 @@
     <string name="next_button_content_description" msgid="6810058269847364406">"Prejsť na ďalšiu obrazovku"</string>
     <string name="accessibility_menu_description" msgid="4458354794093858297">"Ponuka dostupnosti spustí na obrazovke telefónu veľkú ponuku, pomocou ktorej môžete ovládať svoje zariadenie. Môžete ho uzamknúť, ovládať hlasitosť a jas, vytvárať snímky obrazovky a mnoho ďalšieho."</string>
     <string name="accessibility_menu_summary" msgid="340071398148208130">"Ovládanie zariadenia pomocou veľkej ponuky"</string>
-    <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Nastavenia ponuky dostupnosti"</string>
+    <string name="accessibility_menu_settings_name" msgid="1716888058785672611">"Nastavenia ponuky Dostupnosť"</string>
     <string name="accessibility_menu_large_buttons_title" msgid="8978499601044961736">"Veľké tlačidlá"</string>
-    <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Zväčšiť tlačidlá ponuky dostupnosti"</string>
+    <string name="accessibility_menu_large_buttons_summary" msgid="236873938502785311">"Zväčšiť tlačidlá ponuky Dostupnosť"</string>
     <string name="pref_help_title" msgid="6871558837025010641">"Pomocník"</string>
     <string name="brightness_percentage_label" msgid="7391554573977867369">"Jas: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
     <string name="music_volume_percentage_label" msgid="398635599662604706">"Hlasitosť hudby: <xliff:g id="PERCENTAGE">%1$s</xliff:g> %%"</string>
diff --git a/packages/SystemUI/aconfig/accessibility.aconfig b/packages/SystemUI/aconfig/accessibility.aconfig
index d201071..0861454 100644
--- a/packages/SystemUI/aconfig/accessibility.aconfig
+++ b/packages/SystemUI/aconfig/accessibility.aconfig
@@ -73,6 +73,13 @@
 }
 
 flag {
+    name: "redesign_magnification_window_size"
+    namespace: "accessibility"
+    description: "Redesigns the window magnification magnifier sizes provided in the settings panel."
+    bug: "288056772"
+}
+
+flag {
     name: "save_and_restore_magnification_settings_buttons"
     namespace: "accessibility"
     description: "Saves the selected button status in magnification settings and restore the status when revisiting the same smallest screen DP."
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 1cbf67e..e2ecda3 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -146,6 +146,16 @@
 }
 
 flag {
+   name: "notification_transparent_header_fix"
+   namespace: "systemui"
+   description: "fix the transparent group header issue for async header inflation."
+   bug: "340161724"
+   metadata {
+        purpose: PURPOSE_BUGFIX
+   }
+}
+
+flag {
    name: "pss_app_selector_abrupt_exit_fix"
    namespace: "systemui"
    description: "Fixes the app selector abruptly disappearing without an animation, when the"
@@ -217,6 +227,17 @@
 }
 
 flag {
+    name: "notification_group_hun_removal_animation_fix"
+    namespace: "systemui"
+    description: "Fix the lack of hun removal animation for group notifications"
+        "(not GROUP_ALERT_SUMMARY)"
+    bug: "343475993"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
     name: "scene_container"
     namespace: "systemui"
     description: "Enables the scene container framework go/flexiglass."
@@ -421,10 +442,13 @@
 }
 
 flag {
-   name: "fast_unlock_transition"
+   name: "faster_unlock_transition"
    namespace: "systemui"
    description: "Faster wallpaper unlock transition"
    bug: "298186160"
+   metadata {
+     purpose: PURPOSE_BUGFIX
+   }
 }
 
 flag {
@@ -510,6 +534,16 @@
 }
 
 flag {
+    name: "use_volume_controller"
+    namespace: "systemui"
+    description: "Adds Volume Controller signals to the AudioRepository to update volume"
+    bug: "349348461"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
     name: "screenshot_action_dismiss_system_windows"
     namespace: "systemui"
     description: "Dismiss existing system windows when starting action from screenshot UI"
@@ -557,13 +591,6 @@
 }
 
 flag {
-    name: "screenshot_shelf_ui2"
-    namespace: "systemui"
-    description: "Use new shelf UI flow for screenshots"
-    bug: "329659738"
-}
-
-flag {
    name: "run_fingerprint_detect_on_dismissible_keyguard"
    namespace: "systemui"
    description: "Run fingerprint detect instead of authenticate if the keyguard is dismissible."
@@ -790,13 +817,6 @@
 }
 
 flag {
-    name: "media_controls_refactor"
-    namespace: "systemui"
-    description: "Refactors media code to follow the recommended architecture"
-    bug: "326408371"
-}
-
-flag {
     name: "qs_tile_focus_state"
     namespace: "systemui"
     description: "enables new focus outline for qs tiles when focused on with physical keyboard"
@@ -864,6 +884,13 @@
 }
 
 flag {
+    name: "keyboard_touchpad_contextual_education"
+    namespace: "systemui"
+    description: "Allow showing education for physical keyboard and touchpad"
+    bug: "317496783"
+}
+
+flag {
   name: "dream_overlay_bouncer_swipe_direction_filtering"
   namespace: "systemui"
   description: "do not initiate bouncer swipe when the direction is opposite of the expansion"
@@ -884,16 +911,6 @@
 }
 
 flag {
-    name: "shade_collapse_activity_launch_fix"
-    namespace: "systemui"
-    description: "Avoid collapsing the shade on activity launch if it is already collapsed, as this causes a flicker."
-    bug: "331591373"
-    metadata {
-      purpose: PURPOSE_BUGFIX
-    }
-}
-
-flag {
     name: "slice_broadcast_relay_in_background"
     namespace: "systemui"
     description: "Move handling of slice broadcast relay broadcasts to background threads"
@@ -1021,24 +1038,13 @@
 }
 
 flag {
-  name: "glanceable_hub_fullscreen_swipe"
+  name: "glanceable_hub_back_gesture"
   namespace: "systemui"
-  description: "Increase swipe area for gestures to bring in glanceable hub"
-  bug: "339665673"
-}
-
-flag {
-  name: "glanceable_hub_shortcut_button"
-  namespace: "systemui"
-  description: "Shows a button over the dream and lock screen to open the glanceable hub"
-  bug: "339667383"
-}
-
-flag {
-  name: "glanceable_hub_gesture_handle"
-  namespace: "systemui"
-  description: "Shows a vertical bar at the right edge to indicate the user can swipe to open the glanceable hub"
-  bug: "339667383"
+  description: "Enables back gesture on the glanceable hub"
+  bug: "346331399"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
 }
 
 flag {
@@ -1048,14 +1054,6 @@
   bug: "343505271"
 }
 
-
-flag {
-  name: "new_touchpad_gestures_tutorial"
-  namespace: "systemui"
-  description: "Enables new interactive tutorial for learning touchpad gestures"
-  bug: "309928033"
-}
-
 flag {
    name: "register_wallpaper_notifier_background"
    namespace: "systemui"
@@ -1105,3 +1103,43 @@
     purpose: PURPOSE_BUGFIX
   }
 }
+
+flag {
+    name: "media_lockscreen_launch_animation"
+    namespace : "systemui"
+    description : "Enable the origin launch animation for UMO when opening on top of lockscreen."
+    bug : "346865769"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
+  name: "expand_heads_up_on_inline_reply"
+  namespace: "systemui"
+  description: "Expands heads up notification when users clicks reply button and activate inline reply"
+  bug: "346976443"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
+  name: "translucent_occluding_activity_fix"
+  namespace: "systemui"
+  description: "Fixes occlusion animation for transluent activities"
+  bug: "303010980"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
+   namespace: "systemui"
+   name: "fetch_bookmarks_xml_keyboard_shortcuts"
+   description: "Fetches application launch keyboard shortcuts from system server rather than building a hardcoded list."
+   bug: "312452252"
+   metadata {
+       purpose: PURPOSE_BUGFIX
+   }
+}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
index b6e4e9b..c14ee62 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
@@ -22,6 +22,7 @@
 import android.app.TaskInfo
 import android.app.WindowConfiguration
 import android.content.ComponentName
+import android.graphics.Color
 import android.graphics.Matrix
 import android.graphics.Rect
 import android.graphics.RectF
@@ -53,6 +54,7 @@
 import com.android.internal.annotations.VisibleForTesting
 import com.android.internal.policy.ScreenDecorationsUtils
 import com.android.systemui.Flags.activityTransitionUseLargestWindow
+import com.android.systemui.Flags.translucentOccludingActivityFix
 import com.android.systemui.shared.Flags.returnAnimationFrameworkLibrary
 import com.android.wm.shell.shared.IShellTransitions
 import com.android.wm.shell.shared.ShellTransitions
@@ -991,7 +993,12 @@
                     controller.createAnimatorState()
                 }
             val windowBackgroundColor =
-                window.taskInfo?.let { callback.getBackgroundColor(it) } ?: window.backgroundColor
+                if (translucentOccludingActivityFix() && window.isTranslucent) {
+                    Color.TRANSPARENT
+                } else {
+                    window.taskInfo?.let { callback.getBackgroundColor(it) }
+                        ?: window.backgroundColor
+                }
 
             // TODO(b/184121838): We should somehow get the top and bottom radius of the window
             // instead of recomputing isExpandingFullyAbove here.
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
index c4659cf..43d51c3 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
@@ -7,22 +7,16 @@
 import androidx.compose.animation.core.rememberInfiniteTransition
 import androidx.compose.animation.core.tween
 import androidx.compose.foundation.background
+import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.isSystemInDarkTheme
-import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxScope
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.width
-import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
-import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.alpha
 import androidx.compose.ui.draw.drawBehind
@@ -31,15 +25,12 @@
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.res.dimensionResource
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import com.android.compose.animation.scene.CommunalSwipeDetector
-import com.android.compose.animation.scene.DefaultSwipeDetector
+import com.android.compose.animation.scene.Back
 import com.android.compose.animation.scene.Edge
 import com.android.compose.animation.scene.ElementKey
 import com.android.compose.animation.scene.ElementMatcher
-import com.android.compose.animation.scene.FixedSizeEdgeDetector
 import com.android.compose.animation.scene.LowestZIndexScenePicker
 import com.android.compose.animation.scene.MutableSceneTransitionLayoutState
 import com.android.compose.animation.scene.SceneKey
@@ -50,8 +41,7 @@
 import com.android.compose.animation.scene.observableTransitionState
 import com.android.compose.animation.scene.transitions
 import com.android.compose.theme.LocalAndroidColorScheme
-import com.android.systemui.Flags
-import com.android.systemui.Flags.glanceableHubFullscreenSwipe
+import com.android.systemui.Flags.glanceableHubBackGesture
 import com.android.systemui.communal.shared.model.CommunalBackgroundType
 import com.android.systemui.communal.shared.model.CommunalScenes
 import com.android.systemui.communal.shared.model.CommunalTransitionKeys
@@ -59,9 +49,10 @@
 import com.android.systemui.communal.ui.compose.extensions.allowGestures
 import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
 import com.android.systemui.communal.util.CommunalColors
-import com.android.systemui.res.R
+import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor.Companion.TO_GONE_DURATION
 import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
 import com.android.systemui.scene.ui.composable.SceneTransitionLayoutDataSource
+import kotlin.time.DurationUnit
 
 object Communal {
     object Elements {
@@ -91,6 +82,10 @@
         spec = tween(durationMillis = 250)
         fade(AllElements)
     }
+    to(CommunalScenes.Blank, key = CommunalTransitionKeys.SimpleFade) {
+        spec = tween(durationMillis = TO_GONE_DURATION.toInt(DurationUnit.MILLISECONDS))
+        fade(AllElements)
+    }
     to(CommunalScenes.Communal) {
         spec = tween(durationMillis = 1000)
         translate(Communal.Elements.Grid, Edge.Right)
@@ -131,6 +126,9 @@
             fade(Communal.Elements.Grid)
         }
     }
+    // Disable horizontal overscroll. If the scene is overscrolled too soon after showing, this
+    // can lead to inconsistent KeyguardState changes.
+    overscroll(CommunalScenes.Communal, Orientation.Horizontal) {}
 }
 
 /**
@@ -150,12 +148,10 @@
     val coroutineScope = rememberCoroutineScope()
     val currentSceneKey: SceneKey by
         viewModel.currentScene.collectAsStateWithLifecycle(CommunalScenes.Blank)
-    val touchesAllowed by viewModel.touchesAllowed.collectAsStateWithLifecycle(initialValue = false)
-    val showGestureIndicator by
-        viewModel.showGestureIndicator.collectAsStateWithLifecycle(initialValue = false)
+    val touchesAllowed by viewModel.touchesAllowed.collectAsStateWithLifecycle()
     val backgroundType by
         viewModel.communalBackground.collectAsStateWithLifecycle(
-            initialValue = CommunalBackgroundType.DEFAULT
+            initialValue = CommunalBackgroundType.ANIMATED
         )
     val state: MutableSceneTransitionLayoutState = remember {
         MutableSceneTransitionLayoutState(
@@ -181,25 +177,11 @@
         onDispose { viewModel.setTransitionState(null) }
     }
 
-    val swipeSourceDetector =
-        if (glanceableHubFullscreenSwipe()) {
-            detector
-        } else {
-            FixedSizeEdgeDetector(dimensionResource(id = R.dimen.communal_gesture_initiation_width))
-        }
-
-    val swipeDetector =
-        if (glanceableHubFullscreenSwipe()) {
-            detector
-        } else {
-            DefaultSwipeDetector
-        }
-
     SceneTransitionLayout(
         state = state,
         modifier = modifier.fillMaxSize(),
-        swipeSourceDetector = swipeSourceDetector,
-        swipeDetector = swipeDetector,
+        swipeSourceDetector = detector,
+        swipeDetector = detector,
     ) {
         scene(
             CommunalScenes.Blank,
@@ -209,27 +191,26 @@
                 )
         ) {
             // This scene shows nothing only allowing for transitions to the communal scene.
-            // TODO(b/339667383): remove this temporary swipe gesture handle
-            Row(modifier = Modifier.fillMaxSize(), horizontalArrangement = Arrangement.End) {
-                if (showGestureIndicator && Flags.glanceableHubGestureHandle()) {
-                    Box(
-                        modifier =
-                            Modifier.height(220.dp)
-                                .width(4.dp)
-                                .align(Alignment.CenterVertically)
-                                .background(color = Color.White, RoundedCornerShape(4.dp))
-                    )
-                    Spacer(modifier = Modifier.width(12.dp))
-                }
-            }
+            Box(modifier = Modifier.fillMaxSize())
         }
 
-        scene(
-            CommunalScenes.Communal,
-            userActions =
-                mapOf(Swipe(SwipeDirection.Right, fromSource = Edge.Left) to CommunalScenes.Blank)
-        ) {
-            CommunalScene(backgroundType, colors, content)
+        val userActions =
+            if (glanceableHubBackGesture()) {
+                mapOf(
+                    Swipe(SwipeDirection.Right) to CommunalScenes.Blank,
+                    Back to CommunalScenes.Blank,
+                )
+            } else {
+                mapOf(Swipe(SwipeDirection.Right) to CommunalScenes.Blank)
+            }
+
+        scene(CommunalScenes.Communal, userActions = userActions) {
+            CommunalScene(
+                backgroundType = backgroundType,
+                colors = colors,
+                content = content,
+                modifier = Modifier.horizontalNestedScrollToScene(),
+            )
         }
     }
 
@@ -248,7 +229,7 @@
 ) {
     Box(modifier = Modifier.element(Communal.Elements.Scrim).fillMaxSize()) {
         when (backgroundType) {
-            CommunalBackgroundType.DEFAULT -> DefaultBackground(colors = colors)
+            CommunalBackgroundType.STATIC -> DefaultBackground(colors = colors)
             CommunalBackgroundType.STATIC_GRADIENT -> StaticLinearGradient()
             CommunalBackgroundType.ANIMATED -> AnimatedLinearGradient()
             CommunalBackgroundType.NONE -> BackgroundTopScrim()
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt
index 18085ab..1ce51af 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt
@@ -27,8 +27,10 @@
 import com.android.compose.theme.LocalAndroidColorScheme
 import com.android.systemui.communal.smartspace.SmartspaceInteractionHandler
 import com.android.systemui.communal.ui.compose.section.AmbientStatusBarSection
+import com.android.systemui.communal.ui.compose.section.CommunalPopupSection
 import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
 import com.android.systemui.keyguard.ui.composable.blueprint.BlueprintAlignmentLines
+import com.android.systemui.keyguard.ui.composable.section.BottomAreaSection
 import com.android.systemui.keyguard.ui.composable.section.LockSection
 import com.android.systemui.statusbar.phone.SystemUIDialogFactory
 import javax.inject.Inject
@@ -41,64 +43,88 @@
     private val interactionHandler: SmartspaceInteractionHandler,
     private val dialogFactory: SystemUIDialogFactory,
     private val lockSection: LockSection,
+    private val bottomAreaSection: BottomAreaSection,
     private val ambientStatusBarSection: AmbientStatusBarSection,
+    private val communalPopupSection: CommunalPopupSection,
 ) {
+
     @Composable
     fun SceneScope.Content(modifier: Modifier = Modifier) {
-        Layout(
-            modifier = modifier.fillMaxSize(),
-            content = {
-                Box(modifier = Modifier.fillMaxSize()) {
-                    with(ambientStatusBarSection) {
-                        AmbientStatusBar(modifier = Modifier.fillMaxWidth())
+        CommunalTouchableSurface(viewModel = viewModel, modifier = modifier) {
+            Layout(
+                modifier = Modifier.fillMaxSize(),
+                content = {
+                    Box(modifier = Modifier.fillMaxSize()) {
+                        with(communalPopupSection) { Popup() }
+                        with(ambientStatusBarSection) {
+                            AmbientStatusBar(modifier = Modifier.fillMaxWidth())
+                        }
+                        CommunalHub(
+                            viewModel = viewModel,
+                            interactionHandler = interactionHandler,
+                            dialogFactory = dialogFactory,
+                            modifier = Modifier.element(Communal.Elements.Grid)
+                        )
                     }
-                    CommunalHub(
-                        viewModel = viewModel,
-                        interactionHandler = interactionHandler,
-                        dialogFactory = dialogFactory,
-                        modifier = Modifier.element(Communal.Elements.Grid)
+                    with(lockSection) {
+                        LockIcon(
+                            overrideColor = LocalAndroidColorScheme.current.onPrimaryContainer,
+                            modifier = Modifier.element(Communal.Elements.LockIcon)
+                        )
+                    }
+                    with(bottomAreaSection) {
+                        IndicationArea(
+                            Modifier.element(Communal.Elements.IndicationArea).fillMaxWidth()
+                        )
+                    }
+                }
+            ) { measurables, constraints ->
+                val communalGridMeasurable = measurables[0]
+                val lockIconMeasurable = measurables[1]
+                val bottomAreaMeasurable = measurables[2]
+
+                val noMinConstraints =
+                    constraints.copy(
+                        minWidth = 0,
+                        minHeight = 0,
+                    )
+
+                val lockIconPlaceable = lockIconMeasurable.measure(noMinConstraints)
+                val lockIconBounds =
+                    IntRect(
+                        left = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Left],
+                        top = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Top],
+                        right = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Right],
+                        bottom = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Bottom],
+                    )
+
+                val bottomAreaPlaceable =
+                    bottomAreaMeasurable.measure(
+                        noMinConstraints.copy(
+                            maxHeight =
+                                (constraints.maxHeight - lockIconBounds.bottom).coerceAtLeast(0)
+                        )
+                    )
+
+                val communalGridPlaceable =
+                    communalGridMeasurable.measure(
+                        noMinConstraints.copy(maxHeight = lockIconBounds.top)
+                    )
+
+                layout(constraints.maxWidth, constraints.maxHeight) {
+                    communalGridPlaceable.place(
+                        x = 0,
+                        y = 0,
+                    )
+                    lockIconPlaceable.place(
+                        x = lockIconBounds.left,
+                        y = lockIconBounds.top,
+                    )
+                    bottomAreaPlaceable.place(
+                        x = 0,
+                        y = constraints.maxHeight - bottomAreaPlaceable.height,
                     )
                 }
-                with(lockSection) {
-                    LockIcon(
-                        overrideColor = LocalAndroidColorScheme.current.onPrimaryContainer,
-                        modifier = Modifier.element(Communal.Elements.LockIcon)
-                    )
-                }
-            }
-        ) { measurables, constraints ->
-            val communalGridMeasurable = measurables[0]
-            val lockIconMeasurable = measurables[1]
-
-            val noMinConstraints =
-                constraints.copy(
-                    minWidth = 0,
-                    minHeight = 0,
-                )
-
-            val lockIconPlaceable = lockIconMeasurable.measure(noMinConstraints)
-            val lockIconBounds =
-                IntRect(
-                    left = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Left],
-                    top = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Top],
-                    right = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Right],
-                    bottom = lockIconPlaceable[BlueprintAlignmentLines.LockIcon.Bottom],
-                )
-
-            val communalGridPlaceable =
-                communalGridMeasurable.measure(
-                    noMinConstraints.copy(maxHeight = lockIconBounds.top)
-                )
-
-            layout(constraints.maxWidth, constraints.maxHeight) {
-                communalGridPlaceable.place(
-                    x = 0,
-                    y = 0,
-                )
-                lockIconPlaceable.place(
-                    x = lockIconBounds.left,
-                    y = lockIconBounds.top,
-                )
             }
         }
     }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
index 927890e..f6535ec0 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
@@ -25,7 +25,6 @@
 import android.widget.RemoteViews
 import androidx.annotation.VisibleForTesting
 import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.animation.AnimatedVisibilityScope
 import androidx.compose.animation.core.LinearEasing
 import androidx.compose.animation.core.Spring
 import androidx.compose.animation.core.animateFloatAsState
@@ -49,13 +48,16 @@
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.RowScope
 import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxHeight
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.heightIn
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.requiredSize
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.widthIn
 import androidx.compose.foundation.layout.wrapContentHeight
 import androidx.compose.foundation.lazy.grid.GridCells
 import androidx.compose.foundation.lazy.grid.GridItemSpan
@@ -68,19 +70,21 @@
 import androidx.compose.material.icons.filled.Check
 import androidx.compose.material.icons.filled.Close
 import androidx.compose.material.icons.outlined.Edit
-import androidx.compose.material.icons.outlined.TouchApp
 import androidx.compose.material.icons.outlined.Widgets
 import androidx.compose.material3.Button
 import androidx.compose.material3.ButtonColors
 import androidx.compose.material3.ButtonDefaults
 import androidx.compose.material3.Card
 import androidx.compose.material3.CardDefaults
+import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.material3.FilledIconButton
 import androidx.compose.material3.Icon
 import androidx.compose.material3.IconButtonColors
 import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.ModalBottomSheet
 import androidx.compose.material3.OutlinedButton
 import androidx.compose.material3.Text
+import androidx.compose.material3.rememberModalBottomSheetState
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.State
@@ -93,14 +97,16 @@
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.drawBehind
+import androidx.compose.ui.geometry.CornerRadius
 import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Size
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.ColorFilter
 import androidx.compose.ui.graphics.ColorMatrix
-import androidx.compose.ui.graphics.TransformOrigin
+import androidx.compose.ui.graphics.SolidColor
+import androidx.compose.ui.graphics.drawscope.Stroke
 import androidx.compose.ui.graphics.graphicsLayer
-import androidx.compose.ui.input.key.onPreviewKeyEvent
-import androidx.compose.ui.input.pointer.motionEventSpy
 import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.layout.LayoutCoordinates
 import androidx.compose.ui.layout.boundsInWindow
@@ -113,6 +119,7 @@
 import androidx.compose.ui.res.dimensionResource
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.semantics.CustomAccessibilityAction
+import androidx.compose.ui.semantics.clearAndSetSemantics
 import androidx.compose.ui.semantics.contentDescription
 import androidx.compose.ui.semantics.customActions
 import androidx.compose.ui.semantics.onClick
@@ -120,14 +127,11 @@
 import androidx.compose.ui.semantics.testTagsAsResourceId
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
 import androidx.compose.ui.unit.times
 import androidx.compose.ui.viewinterop.AndroidView
-import androidx.compose.ui.window.Popup
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import androidx.window.layout.WindowMetricsCalculator
 import com.android.compose.animation.Easings.Emphasized
@@ -138,7 +142,6 @@
 import com.android.systemui.communal.domain.model.CommunalContentModel
 import com.android.systemui.communal.shared.model.CommunalContentSize
 import com.android.systemui.communal.shared.model.CommunalScenes
-import com.android.systemui.communal.ui.compose.Dimensions.CardOutlineWidth
 import com.android.systemui.communal.ui.compose.extensions.allowGestures
 import com.android.systemui.communal.ui.compose.extensions.detectLongPressGesture
 import com.android.systemui.communal.ui.compose.extensions.firstItemAtOffset
@@ -146,14 +149,13 @@
 import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel
 import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel
 import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
-import com.android.systemui.communal.ui.viewmodel.PopupType
 import com.android.systemui.communal.widgets.SmartspaceAppWidgetHostView
 import com.android.systemui.communal.widgets.WidgetConfigurator
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.phone.SystemUIDialogFactory
 import kotlinx.coroutines.launch
 
-@OptIn(ExperimentalComposeUiApi::class)
+@OptIn(ExperimentalComposeUiApi::class, ExperimentalMaterial3Api::class)
 @Composable
 fun CommunalHub(
     modifier: Modifier = Modifier,
@@ -166,7 +168,6 @@
 ) {
     val communalContent by
         viewModel.communalContent.collectAsStateWithLifecycle(initialValue = emptyList())
-    val currentPopup by viewModel.currentPopup.collectAsStateWithLifecycle(initialValue = null)
     var removeButtonCoordinates: LayoutCoordinates? by remember { mutableStateOf(null) }
     var toolbarSize: IntSize? by remember { mutableStateOf(null) }
     var gridCoordinates: LayoutCoordinates? by remember { mutableStateOf(null) }
@@ -208,43 +209,29 @@
                 }
                 .thenIf(!viewModel.isEditMode && !isEmptyState) {
                     Modifier.pointerInput(
-                            gridState,
-                            contentOffset,
-                            communalContent,
-                            gridCoordinates
-                        ) {
-                            detectLongPressGesture { offset ->
-                                // Deduct both grid offset relative to its container and content
-                                // offset.
-                                val adjustedOffset =
-                                    gridCoordinates?.let {
-                                        offset - it.positionInWindow() - contentOffset
-                                    }
-                                val index =
-                                    adjustedOffset?.let { firstIndexAtOffset(gridState, it) }
-                                // Display the button only when the gesture initiates from widgets,
-                                // the CTA tile, or an empty area on the screen. UMO/smartspace have
-                                // their own long-press handlers. To prevent user confusion, we
-                                // should
-                                // not display this button.
-                                if (
-                                    index == null ||
-                                        communalContent[index].isWidgetContent() ||
-                                        communalContent[index] is
-                                            CommunalContentModel.CtaTileInViewMode
-                                ) {
-                                    viewModel.onShowCustomizeWidgetButton()
+                        gridState,
+                        contentOffset,
+                        communalContent,
+                        gridCoordinates
+                    ) {
+                        detectLongPressGesture { offset ->
+                            // Deduct both grid offset relative to its container and content
+                            // offset.
+                            val adjustedOffset =
+                                gridCoordinates?.let {
+                                    offset - it.positionInWindow() - contentOffset
                                 }
-                                val key =
-                                    index?.let { keyAtIndexIfEditable(communalContent, index) }
+                            val index = adjustedOffset?.let { firstIndexAtOffset(gridState, it) }
+                            val key = index?.let { keyAtIndexIfEditable(communalContent, index) }
+                            // Handle long-click on widgets and set the selected index
+                            // correctly. We only handle widgets here because long click on
+                            // empty spaces is handled by CommunalPopupSection.
+                            if (key != null) {
+                                viewModel.onLongClick()
                                 viewModel.setSelectedKey(key)
                             }
                         }
-                        .onPreviewKeyEvent {
-                            onKeyEvent(viewModel)
-                            false
-                        }
-                        .motionEventSpy { onMotionEvent(viewModel) }
+                    }
                 },
     ) {
         AccessibilityContainer(viewModel) {
@@ -337,22 +324,6 @@
                 )
             }
         }
-        if (currentPopup == PopupType.CtaTile) {
-            PopupOnDismissCtaTile(viewModel::onHidePopup)
-        }
-
-        AnimatedVisibility(
-            visible = currentPopup == PopupType.CustomizeWidgetButton,
-            modifier = Modifier.fillMaxSize()
-        ) {
-            ButtonToEditWidgets(
-                onClick = {
-                    viewModel.onHidePopup()
-                    viewModel.onOpenWidgetEditor(selectedKey.value)
-                },
-                onHide = { viewModel.onHidePopup() }
-            )
-        }
 
         if (viewModel is CommunalViewModel && dialogFactory != null) {
             val isEnableWidgetDialogShowing by
@@ -379,24 +350,74 @@
             )
         }
 
-        // This spacer covers the edge of the LazyHorizontalGrid and prevents it from receiving
-        // touches, so that the SceneTransitionLayout can intercept the touches and allow an edge
-        // swipe back to the blank scene.
-        Spacer(
-            Modifier.height(Dimensions.GridHeight)
-                .align(Alignment.CenterStart)
-                .width(Dimensions.Spacing)
-                .pointerInput(Unit) {}
-        )
+        if (viewModel is CommunalEditModeViewModel) {
+            val showBottomSheet by viewModel.showDisclaimer.collectAsStateWithLifecycle(false)
+
+            if (showBottomSheet) {
+                val scope = rememberCoroutineScope()
+                val sheetState = rememberModalBottomSheetState()
+                val colors = LocalAndroidColorScheme.current
+
+                ModalBottomSheet(
+                    onDismissRequest = viewModel::onDisclaimerDismissed,
+                    sheetState = sheetState,
+                    dragHandle = null,
+                    containerColor = colors.surfaceContainer,
+                ) {
+                    DisclaimerBottomSheetContent {
+                        scope
+                            .launch { sheetState.hide() }
+                            .invokeOnCompletion {
+                                if (!sheetState.isVisible) {
+                                    viewModel.onDisclaimerDismissed()
+                                }
+                            }
+                    }
+                }
+            }
+        }
     }
 }
 
-private fun onKeyEvent(viewModel: BaseCommunalViewModel) {
-    viewModel.signalUserInteraction()
-}
+@Composable
+private fun DisclaimerBottomSheetContent(onButtonClicked: () -> Unit) {
+    val colors = LocalAndroidColorScheme.current
 
-private fun onMotionEvent(viewModel: BaseCommunalViewModel) {
-    viewModel.signalUserInteraction()
+    Column(
+        modifier = Modifier.fillMaxWidth().padding(horizontal = 32.dp, vertical = 24.dp),
+        verticalArrangement = Arrangement.Center,
+        horizontalAlignment = Alignment.CenterHorizontally,
+    ) {
+        Icon(
+            imageVector = Icons.Outlined.Widgets,
+            contentDescription = null,
+            tint = colors.primary,
+            modifier = Modifier.size(32.dp)
+        )
+        Spacer(modifier = Modifier.height(16.dp))
+        Text(
+            text = stringResource(R.string.communal_widgets_disclaimer_title),
+            style = MaterialTheme.typography.headlineMedium,
+            color = colors.onSurface,
+        )
+        Spacer(modifier = Modifier.height(16.dp))
+        Text(
+            text = stringResource(R.string.communal_widgets_disclaimer_text),
+            color = colors.onSurfaceVariant,
+        )
+        Button(
+            modifier =
+                Modifier.padding(horizontal = 26.dp, vertical = 16.dp)
+                    .widthIn(min = 200.dp)
+                    .heightIn(min = 56.dp),
+            onClick = { onButtonClicked() }
+        ) {
+            Text(
+                stringResource(R.string.communal_widgets_disclaimer_button),
+                style = MaterialTheme.typography.labelLarge,
+            )
+        }
+    }
 }
 
 /**
@@ -464,6 +485,7 @@
             rememberDragAndDropTargetState(
                 gridState = gridState,
                 contentListState = contentListState,
+                contentOffset = contentOffset,
                 updateDragPositionForRemove = updateDragPositionForRemove
             )
 
@@ -526,7 +548,7 @@
                 }
             } else {
                 CommunalContent(
-                    modifier = cardModifier.animateItemPlacement(),
+                    modifier = cardModifier.animateItem(),
                     model = list[index],
                     viewModel = viewModel,
                     size = size,
@@ -612,10 +634,14 @@
     removeEnabled: Boolean,
     onRemoveClicked: () -> Unit,
     setToolbarSize: (toolbarSize: IntSize) -> Unit,
-    setRemoveButtonCoordinates: (coordinates: LayoutCoordinates) -> Unit,
+    setRemoveButtonCoordinates: (coordinates: LayoutCoordinates?) -> Unit,
     onOpenWidgetPicker: () -> Unit,
     onEditDone: () -> Unit
 ) {
+    if (!removeEnabled) {
+        // Clear any existing coordinates when remove is not enabled.
+        setRemoveButtonCoordinates(null)
+    }
     val removeButtonAlpha: Float by
         animateFloatAsState(
             targetValue = if (removeEnabled) 1f else 0.5f,
@@ -632,14 +658,15 @@
                 )
                 .onSizeChanged { setToolbarSize(it) },
     ) {
+        val addWidgetText = stringResource(R.string.hub_mode_add_widget_button_text)
         ToolbarButton(
             isPrimary = !removeEnabled,
             modifier = Modifier.align(Alignment.CenterStart),
             onClick = onOpenWidgetPicker,
         ) {
-            Icon(Icons.Default.Add, stringResource(R.string.hub_mode_add_widget_button_text))
+            Icon(Icons.Default.Add, null)
             Text(
-                text = stringResource(R.string.hub_mode_add_widget_button_text),
+                text = addWidgetText,
             )
         }
 
@@ -655,7 +682,13 @@
                 contentPadding = Dimensions.ButtonPadding,
                 modifier =
                     Modifier.graphicsLayer { alpha = removeButtonAlpha }
-                        .onGloballyPositioned { setRemoveButtonCoordinates(it) }
+                        .onGloballyPositioned {
+                            // It's possible for this callback to fire after remove has been
+                            // disabled. Check enabled state before setting.
+                            if (removeEnabled) {
+                                setRemoveButtonCoordinates(it)
+                            }
+                        }
             ) {
                 Row(
                     horizontalArrangement =
@@ -665,7 +698,7 @@
                         ),
                     verticalAlignment = Alignment.CenterVertically
                 ) {
-                    Icon(Icons.Default.Close, stringResource(R.string.button_to_remove_widget))
+                    Icon(Icons.Default.Close, contentDescription = null)
                     Text(
                         text = stringResource(R.string.button_to_remove_widget),
                     )
@@ -678,10 +711,7 @@
             modifier = Modifier.align(Alignment.CenterEnd),
             onClick = onEditDone,
         ) {
-            Icon(
-                Icons.Default.Check,
-                stringResource(id = R.string.hub_mode_editing_exit_button_text)
-            )
+            Icon(Icons.Default.Check, contentDescription = null)
             Text(
                 text = stringResource(R.string.hub_mode_editing_exit_button_text),
             )
@@ -748,107 +778,6 @@
 }
 
 @Composable
-private fun AnimatedVisibilityScope.ButtonToEditWidgets(
-    onClick: () -> Unit,
-    onHide: () -> Unit,
-) {
-    Popup(
-        alignment = Alignment.TopCenter,
-        offset = IntOffset(0, 40),
-        onDismissRequest = onHide,
-    ) {
-        val colors = LocalAndroidColorScheme.current
-        Button(
-            modifier =
-                Modifier.height(56.dp)
-                    .graphicsLayer { transformOrigin = TransformOrigin(0f, 0f) }
-                    .animateEnterExit(
-                        enter =
-                            fadeIn(
-                                initialAlpha = 0f,
-                                animationSpec = tween(durationMillis = 83, easing = LinearEasing)
-                            ),
-                        exit =
-                            fadeOut(
-                                animationSpec =
-                                    tween(
-                                        durationMillis = 83,
-                                        delayMillis = 167,
-                                        easing = LinearEasing
-                                    )
-                            )
-                    )
-                    .background(colors.secondary, RoundedCornerShape(50.dp)),
-            onClick = onClick,
-        ) {
-            Row(
-                modifier =
-                    Modifier.animateEnterExit(
-                        enter =
-                            fadeIn(
-                                animationSpec =
-                                    tween(
-                                        durationMillis = 167,
-                                        delayMillis = 83,
-                                        easing = LinearEasing
-                                    )
-                            ),
-                        exit =
-                            fadeOut(
-                                animationSpec = tween(durationMillis = 167, easing = LinearEasing)
-                            )
-                    )
-            ) {
-                Icon(
-                    imageVector = Icons.Outlined.Widgets,
-                    contentDescription = stringResource(R.string.button_to_configure_widgets_text),
-                    tint = colors.onSecondary,
-                    modifier = Modifier.size(20.dp)
-                )
-                Spacer(modifier = Modifier.size(8.dp))
-                Text(
-                    text = stringResource(R.string.button_to_configure_widgets_text),
-                    style = MaterialTheme.typography.titleSmall,
-                    color = colors.onSecondary
-                )
-            }
-        }
-    }
-}
-
-@Composable
-private fun PopupOnDismissCtaTile(onHidePopup: () -> Unit) {
-    Popup(
-        alignment = Alignment.TopCenter,
-        offset = IntOffset(0, 40),
-        onDismissRequest = onHidePopup
-    ) {
-        val colors = LocalAndroidColorScheme.current
-        Row(
-            modifier =
-                Modifier.height(56.dp)
-                    .background(colors.secondary, RoundedCornerShape(50.dp))
-                    .padding(16.dp),
-            horizontalArrangement = Arrangement.Center,
-            verticalAlignment = Alignment.CenterVertically,
-        ) {
-            Icon(
-                imageVector = Icons.Outlined.TouchApp,
-                contentDescription = stringResource(R.string.popup_on_dismiss_cta_tile_text),
-                tint = colors.onSecondary,
-                modifier = Modifier.size(20.dp)
-            )
-            Spacer(modifier = Modifier.size(8.dp))
-            Text(
-                text = stringResource(R.string.popup_on_dismiss_cta_tile_text),
-                style = MaterialTheme.typography.titleSmall,
-                color = colors.onSecondary,
-            )
-        }
-    }
-}
-
-@Composable
 private fun filledButtonColors(): ButtonColors {
     val colors = LocalAndroidColorScheme.current
     return ButtonDefaults.buttonColors(
@@ -895,13 +824,26 @@
 
 /** Creates an empty card used to highlight a particular spot on the grid. */
 @Composable
-fun HighlightedItem(modifier: Modifier = Modifier) {
-    Card(
-        modifier = modifier,
-        colors = CardDefaults.cardColors(containerColor = Color.Transparent),
-        border = BorderStroke(CardOutlineWidth, LocalAndroidColorScheme.current.tertiaryFixed),
-        shape = RoundedCornerShape(16.dp)
-    ) {}
+fun HighlightedItem(modifier: Modifier = Modifier, alpha: Float = 1.0f) {
+    val brush = SolidColor(LocalAndroidColorScheme.current.primaryFixed)
+    Box(
+        modifier =
+            // drawBehind lets us draw outside the bounds of the widgets so that we don't need to
+            // resize grid items to account for the border.
+            modifier.drawBehind {
+                // 8dp of padding between the widget and the highlight on every side.
+                val padding = 8.dp.toPx()
+                drawRoundRect(
+                    brush,
+                    alpha = alpha,
+                    topLeft = Offset(-padding, -padding),
+                    size =
+                        Size(width = size.width + padding * 2, height = size.height + padding * 2),
+                    cornerRadius = CornerRadius(37.dp.toPx()),
+                    style = Stroke(width = 3.dp.toPx())
+                )
+            }
+    )
 }
 
 /** Presents a CTA tile at the end of the grid, to customize the hub. */
@@ -921,52 +863,55 @@
         shape = RoundedCornerShape(68.dp, 34.dp, 68.dp, 34.dp)
     ) {
         Column(
-            modifier = Modifier.fillMaxSize().padding(vertical = 38.dp, horizontal = 70.dp),
+            modifier = Modifier.fillMaxSize().padding(vertical = 32.dp, horizontal = 50.dp),
+            verticalArrangement = Arrangement.Center,
             horizontalAlignment = Alignment.CenterHorizontally,
         ) {
             Icon(
                 imageVector = Icons.Outlined.Widgets,
                 contentDescription = stringResource(R.string.cta_label_to_open_widget_picker),
-                modifier = Modifier.size(Dimensions.IconSize),
+                modifier = Modifier.size(Dimensions.IconSize).clearAndSetSemantics {},
             )
             Spacer(modifier = Modifier.size(6.dp))
             Text(
                 text = stringResource(R.string.cta_label_to_edit_widget),
-                style = MaterialTheme.typography.titleMedium,
-                textAlign = TextAlign.Center,
+                style = MaterialTheme.typography.titleLarge,
+                fontSize = nonScalableTextSize(22.dp),
+                lineHeight = nonScalableTextSize(28.dp),
             )
-            Spacer(modifier = Modifier.size(20.dp))
+            Spacer(modifier = Modifier.size(16.dp))
             Row(
-                modifier = Modifier.fillMaxWidth(),
-                horizontalArrangement = Arrangement.Center,
+                modifier = Modifier.fillMaxWidth().height(56.dp),
+                horizontalArrangement = Arrangement.spacedBy(16.dp, Alignment.CenterHorizontally),
             ) {
                 OutlinedButton(
+                    modifier = Modifier.fillMaxHeight(),
                     colors =
                         ButtonDefaults.buttonColors(
                             contentColor = colors.onPrimary,
                         ),
                     border = BorderStroke(width = 1.0.dp, color = colors.primaryContainer),
-                    contentPadding = Dimensions.ButtonPadding,
+                    contentPadding = PaddingValues(26.dp, 8.dp),
                     onClick = viewModel::onDismissCtaTile,
                 ) {
                     Text(
                         text = stringResource(R.string.cta_tile_button_to_dismiss),
-                        fontSize = 12.sp,
+                        fontSize = nonScalableTextSize(14.dp),
                     )
                 }
-                Spacer(modifier = Modifier.size(14.dp))
                 Button(
+                    modifier = Modifier.fillMaxHeight(),
                     colors =
                         ButtonDefaults.buttonColors(
                             containerColor = colors.primaryContainer,
                             contentColor = colors.onPrimaryContainer,
                         ),
-                    contentPadding = Dimensions.ButtonPadding,
+                    contentPadding = PaddingValues(26.dp, 8.dp),
                     onClick = viewModel::onOpenWidgetEditor
                 ) {
                     Text(
                         text = stringResource(R.string.cta_tile_button_to_open_widget_editor),
-                        fontSize = 12.sp,
+                        fontSize = nonScalableTextSize(14.dp),
                     )
                 }
             }
@@ -1279,6 +1224,13 @@
 }
 
 /**
+ * Text size converted from dp value to the equivalent sp value using the current screen density,
+ * ensuring it does not scale with the font size setting.
+ */
+@Composable
+private fun nonScalableTextSize(sizeInDp: Dp) = with(LocalDensity.current) { sizeInDp.toSp() }
+
+/**
  * Returns the `contentPadding` of the grid. Use the vertical padding to push the grid content area
  * below the toolbar and let the grid take the max size. This ensures the item can be dragged
  * outside the grid over the toolbar, without part of it getting clipped by the container.
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalTouchableSurface.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalTouchableSurface.kt
new file mode 100644
index 0000000..3707a87
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalTouchableSurface.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.communal.ui.compose
+
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.combinedClickable
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.BoxScope
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.input.key.onPreviewKeyEvent
+import androidx.compose.ui.input.pointer.motionEventSpy
+import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
+
+@OptIn(ExperimentalFoundationApi::class, ExperimentalComposeUiApi::class)
+@Composable
+fun CommunalTouchableSurface(
+    viewModel: CommunalViewModel,
+    modifier: Modifier = Modifier,
+    content: @Composable BoxScope.() -> Unit,
+) {
+
+    val interactionSource = remember { MutableInteractionSource() }
+
+    Box(
+        modifier =
+            modifier
+                .combinedClickable(
+                    onLongClick = viewModel::onLongClick,
+                    onClick = viewModel::onClick,
+                    interactionSource = interactionSource,
+                    indication = null,
+                )
+                .onPreviewKeyEvent {
+                    viewModel.signalUserInteraction()
+                    false
+                }
+                .motionEventSpy { viewModel.signalUserInteraction() }
+    ) {
+        content()
+    }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt
index 37fe798..9e6f22a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/DragAndDropTargetState.kt
@@ -41,7 +41,7 @@
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.unit.dp
 import com.android.systemui.communal.domain.model.CommunalContentModel
-import com.android.systemui.communal.ui.compose.extensions.plus
+import com.android.systemui.communal.ui.compose.extensions.firstItemAtOffset
 import com.android.systemui.communal.util.WidgetPickerIntentUtils
 import com.android.systemui.communal.util.WidgetPickerIntentUtils.getWidgetExtraFromIntent
 import kotlinx.coroutines.CoroutineScope
@@ -57,6 +57,7 @@
 @Composable
 internal fun rememberDragAndDropTargetState(
     gridState: LazyGridState,
+    contentOffset: Offset,
     contentListState: ContentListState,
     updateDragPositionForRemove: (offset: Offset) -> Boolean,
 ): DragAndDropTargetState {
@@ -70,6 +71,7 @@
         remember(gridState, contentListState) {
             DragAndDropTargetState(
                 state = gridState,
+                contentOffset = contentOffset,
                 contentListState = contentListState,
                 scope = scope,
                 autoScrollSpeed = autoScrollSpeed,
@@ -145,6 +147,7 @@
  */
 internal class DragAndDropTargetState(
     private val state: LazyGridState,
+    private val contentOffset: Offset,
     private val contentListState: ContentListState,
     private val scope: CoroutineScope,
     private val autoScrollSpeed: MutableState<Float>,
@@ -214,8 +217,7 @@
                 return@let true
             }
             return false
-        }
-            ?: false
+        } ?: false
     }
 
     fun onEnded() {
@@ -249,10 +251,9 @@
     }
 
     private fun findTargetItem(dragEvent: DragEvent): LazyGridItemInfo? =
-        state.layoutInfo.visibleItemsInfo.firstOrNull { item ->
-            dragEvent.x.toInt() in item.offset.x..(item.offset + item.size).x &&
-                dragEvent.y.toInt() in item.offset.y..(item.offset + item.size).y
-        }
+        state.layoutInfo.visibleItemsInfo.firstItemAtOffset(
+            Offset(dragEvent.x, dragEvent.y) - contentOffset
+        )
 
     private fun movePlaceholderTo(index: Int) {
         val currentIndex = contentListState.list.indexOf(placeHolder)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt
index 33d2cc4..07898b0 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/GridDragDropState.kt
@@ -16,10 +16,9 @@
 
 package com.android.systemui.communal.ui.compose
 
-import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.core.Spring
 import androidx.compose.animation.core.animateFloatAsState
-import androidx.compose.animation.fadeIn
-import androidx.compose.animation.fadeOut
+import androidx.compose.animation.core.spring
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.detectDragGesturesAfterLongPress
 import androidx.compose.foundation.gestures.scrollBy
@@ -34,13 +33,10 @@
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.setValue
-import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.graphicsLayer
 import androidx.compose.ui.input.pointer.pointerInput
-import androidx.compose.ui.input.pointer.pointerInteropFilter
-import androidx.compose.ui.semantics.clearAndSetSemantics
 import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.toOffset
 import androidx.compose.ui.unit.toSize
@@ -107,13 +103,17 @@
         get() =
             draggingItemLayoutInfo?.let { item ->
                 draggingItemInitialOffset + draggingItemDraggedDelta - item.offset.toOffset()
-            }
-                ?: Offset.Zero
+            } ?: Offset.Zero
 
     private val draggingItemLayoutInfo: LazyGridItemInfo?
         get() = state.layoutInfo.visibleItemsInfo.firstOrNull { it.index == draggingItemIndex }
 
-    internal fun onDragStart(offset: Offset, contentOffset: Offset) {
+    /**
+     * Called when dragging is initiated.
+     *
+     * @return {@code True} if dragging a grid item, {@code False} otherwise.
+     */
+    internal fun onDragStart(offset: Offset, contentOffset: Offset): Boolean {
         state.layoutInfo.visibleItemsInfo
             .filter { item -> contentListState.isItemEditable(item.index) }
             // grid item offset is based off grid content container so we need to deduct
@@ -123,7 +123,10 @@
                 dragStartPointerOffset = offset - this.offset.toOffset()
                 draggingItemIndex = index
                 draggingItemInitialOffset = this.offset.toOffset()
+                return true
             }
+
+        return false
     }
 
     internal fun onDragInterrupted() {
@@ -221,8 +224,9 @@
                     dragDropState.onDrag(offset = offset)
                 },
                 onDragStart = { offset ->
-                    dragDropState.onDragStart(offset, contentOffset)
-                    viewModel.onReorderWidgetStart()
+                    if (dragDropState.onDragStart(offset, contentOffset)) {
+                        viewModel.onReorderWidgetStart()
+                    }
                 },
                 onDragEnd = {
                     dragDropState.onDragInterrupted()
@@ -238,7 +242,6 @@
 }
 
 /** Wrap LazyGrid item with additional modifier needed for drag and drop. */
-@OptIn(ExperimentalComposeUiApi::class)
 @ExperimentalFoundationApi
 @Composable
 fun LazyGridItemScope.DraggableItem(
@@ -267,25 +270,21 @@
                 alpha = itemAlpha
             }
         } else {
-            Modifier.animateItemPlacement()
+            Modifier.animateItem()
         }
 
+    // Animate the highlight alpha manually as alpha modifier (and AnimatedVisibility) clips the
+    // widget to bounds, which cuts off the highlight as we are drawing outside the widget bounds.
+    val alpha by
+        animateFloatAsState(
+            targetValue =
+                if ((dragging || selected) && !dragDropState.isDraggingToRemove) 1f else 0f,
+            animationSpec = spring(stiffness = Spring.StiffnessMediumLow),
+            label = "Widget outline alpha"
+        )
+
     Box(modifier) {
+        HighlightedItem(Modifier.matchParentSize(), alpha = alpha)
         Box(draggingModifier) { content(dragging) }
-        AnimatedVisibility(
-            modifier =
-                Modifier.matchParentSize()
-                    // Avoid taking focus away from the content when using explore-by-touch with
-                    // accessibility tools.
-                    .clearAndSetSemantics {}
-                    // Do not consume motion events in the highlighted item and pass them down to
-                    // the content.
-                    .pointerInteropFilter { false },
-            visible = (dragging || selected) && !dragDropState.isDraggingToRemove,
-            enter = fadeIn(),
-            exit = fadeOut()
-        ) {
-            HighlightedItem(Modifier.matchParentSize())
-        }
     }
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/CommunalPopupSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/CommunalPopupSection.kt
new file mode 100644
index 0000000..1ea73e1
--- /dev/null
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/section/CommunalPopupSection.kt
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.communal.ui.compose.section
+
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.AnimatedVisibilityScope
+import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.tween
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.fadeOut
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.TouchApp
+import androidx.compose.material.icons.outlined.Widgets
+import androidx.compose.material3.Button
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.TransformOrigin
+import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.window.Popup
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.android.compose.theme.LocalAndroidColorScheme
+import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
+import com.android.systemui.communal.ui.viewmodel.PopupType
+import com.android.systemui.res.R
+import javax.inject.Inject
+
+class CommunalPopupSection
+@Inject
+constructor(
+    private val viewModel: CommunalViewModel,
+) {
+
+    @Composable
+    fun Popup() {
+        val currentPopup by viewModel.currentPopup.collectAsStateWithLifecycle(initialValue = null)
+
+        if (currentPopup == PopupType.CtaTile) {
+            PopupOnDismissCtaTile(viewModel::onHidePopup)
+        }
+
+        AnimatedVisibility(
+            visible = currentPopup == PopupType.CustomizeWidgetButton,
+            modifier = Modifier.fillMaxSize()
+        ) {
+            ButtonToEditWidgets(
+                onClick = {
+                    viewModel.onHidePopup()
+                    viewModel.onOpenWidgetEditor()
+                },
+                onDismissRequest = {
+                    viewModel.onHidePopup()
+                    viewModel.setSelectedKey(null)
+                }
+            )
+        }
+    }
+
+    @Composable
+    private fun AnimatedVisibilityScope.ButtonToEditWidgets(
+        onClick: () -> Unit,
+        onDismissRequest: () -> Unit,
+    ) {
+        Popup(
+            alignment = Alignment.TopCenter,
+            offset = IntOffset(0, 40),
+            onDismissRequest = onDismissRequest,
+        ) {
+            val colors = LocalAndroidColorScheme.current
+            Button(
+                modifier =
+                    Modifier.height(56.dp)
+                        .graphicsLayer { transformOrigin = TransformOrigin(0f, 0f) }
+                        .animateEnterExit(
+                            enter =
+                                fadeIn(
+                                    initialAlpha = 0f,
+                                    animationSpec =
+                                        tween(durationMillis = 83, easing = LinearEasing)
+                                ),
+                            exit =
+                                fadeOut(
+                                    animationSpec =
+                                        tween(
+                                            durationMillis = 83,
+                                            delayMillis = 167,
+                                            easing = LinearEasing
+                                        )
+                                )
+                        )
+                        .background(colors.secondary, RoundedCornerShape(50.dp)),
+                onClick = onClick,
+            ) {
+                Row(
+                    modifier =
+                        Modifier.animateEnterExit(
+                            enter =
+                                fadeIn(
+                                    animationSpec =
+                                        tween(
+                                            durationMillis = 167,
+                                            delayMillis = 83,
+                                            easing = LinearEasing
+                                        )
+                                ),
+                            exit =
+                                fadeOut(
+                                    animationSpec =
+                                        tween(durationMillis = 167, easing = LinearEasing)
+                                )
+                        )
+                ) {
+                    Icon(
+                        imageVector = Icons.Outlined.Widgets,
+                        contentDescription =
+                            stringResource(R.string.button_to_configure_widgets_text),
+                        tint = colors.onSecondary,
+                        modifier = Modifier.size(20.dp)
+                    )
+                    Spacer(modifier = Modifier.size(8.dp))
+                    Text(
+                        text = stringResource(R.string.button_to_configure_widgets_text),
+                        style = MaterialTheme.typography.titleSmall,
+                        color = colors.onSecondary
+                    )
+                }
+            }
+        }
+    }
+
+    @Composable
+    private fun PopupOnDismissCtaTile(onDismissRequest: () -> Unit) {
+        Popup(
+            alignment = Alignment.TopCenter,
+            offset = IntOffset(0, 40),
+            onDismissRequest = onDismissRequest
+        ) {
+            val colors = LocalAndroidColorScheme.current
+            Row(
+                modifier =
+                    Modifier.height(56.dp)
+                        .background(colors.secondary, RoundedCornerShape(50.dp))
+                        .padding(16.dp),
+                horizontalArrangement = Arrangement.Center,
+                verticalAlignment = Alignment.CenterVertically,
+            ) {
+                Icon(
+                    imageVector = Icons.Outlined.TouchApp,
+                    contentDescription = stringResource(R.string.popup_on_dismiss_cta_tile_text),
+                    tint = colors.onSecondary,
+                    modifier = Modifier.size(20.dp)
+                )
+                Spacer(modifier = Modifier.size(8.dp))
+                Text(
+                    text = stringResource(R.string.popup_on_dismiss_cta_tile_text),
+                    style = MaterialTheme.typography.titleSmall,
+                    color = colors.onSecondary,
+                )
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/dialog/ui/composable/AlertDialogContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/dialog/ui/composable/AlertDialogContent.kt
index 418df5c..0b96694 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/dialog/ui/composable/AlertDialogContent.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/dialog/ui/composable/AlertDialogContent.kt
@@ -89,7 +89,7 @@
 
         // Content.
         val contentColor = LocalAndroidColorScheme.current.onSurfaceVariant
-        Box(Modifier.defaultMinSize(minHeight = 48.dp)) {
+        Box {
             CompositionLocalProvider(LocalContentColor provides contentColor) {
                 ProvideTextStyle(
                     MaterialTheme.typography.bodyMedium.copy(textAlign = TextAlign.Center)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt
index 887e349..25e91be 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenContent.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.keyguard.ui.composable
 
+import androidx.compose.foundation.layout.Box
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.getValue
@@ -48,6 +49,16 @@
     fun SceneScope.Content(
         modifier: Modifier = Modifier,
     ) {
+        val isContentVisible: Boolean by viewModel.isContentVisible.collectAsStateWithLifecycle()
+        if (!isContentVisible) {
+            // If the content isn't supposed to be visible, show a large empty box as it's needed
+            // for scene transition animations (can't just skip rendering everything or shared
+            // elements won't have correct final/initial bounds from animating in and out of the
+            // lockscreen scene).
+            Box(modifier)
+            return
+        }
+
         val coroutineScope = rememberCoroutineScope()
         val blueprintId by viewModel.blueprintId(coroutineScope).collectAsStateWithLifecycle()
         val view = LocalView.current
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenLongPress.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenLongPress.kt
index 4555f13..c34fb38 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenLongPress.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenLongPress.kt
@@ -19,9 +19,10 @@
 package com.android.systemui.keyguard.ui.composable
 
 import androidx.compose.foundation.ExperimentalFoundationApi
-import androidx.compose.foundation.combinedClickable
 import androidx.compose.foundation.gestures.awaitEachGesture
 import androidx.compose.foundation.gestures.awaitFirstDown
+import androidx.compose.foundation.gestures.detectTapGestures
+import androidx.compose.foundation.indication
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxScope
@@ -33,12 +34,14 @@
 import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.input.pointer.pointerInput
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel
+import com.android.systemui.communal.ui.compose.extensions.detectLongPressGesture
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardTouchHandlingViewModel
 
 /** Container for lockscreen content that handles long-press to bring up the settings menu. */
 @Composable
+// TODO(b/344879669): now that it's more generic than long-press, rename it.
 fun LockscreenLongPress(
-    viewModel: KeyguardLongPressViewModel,
+    viewModel: KeyguardTouchHandlingViewModel,
     modifier: Modifier = Modifier,
     content: @Composable BoxScope.(onSettingsMenuPlaces: (coordinates: Rect?) -> Unit) -> Unit,
 ) {
@@ -50,14 +53,17 @@
     Box(
         modifier =
             modifier
-                .combinedClickable(
-                    enabled = isEnabled,
-                    onLongClick = viewModel::onLongPress,
-                    onClick = {},
-                    interactionSource = interactionSource,
-                    // Passing null for the indication removes the ripple effect.
-                    indication = null,
-                )
+                .pointerInput(isEnabled) {
+                    if (isEnabled) {
+                        detectLongPressGesture { viewModel.onLongPress() }
+                    }
+                }
+                .pointerInput(Unit) {
+                    detectTapGestures(
+                        onTap = { viewModel.onClick(it.x, it.y) },
+                        onDoubleTap = { viewModel.onDoubleClick() },
+                    )
+                }
                 .pointerInput(settingsMenuBounds) {
                     awaitEachGesture {
                         val pointerInputChange = awaitFirstDown()
@@ -65,7 +71,9 @@
                             viewModel.onTouchedOutside()
                         }
                     }
-                },
+                }
+                // Passing null for the indication removes the ripple effect.
+                .indication(interactionSource, null)
     ) {
         content(setSettingsMenuBounds)
     }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/CommunalBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/CommunalBlueprint.kt
index 6b210af..210ca69 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/CommunalBlueprint.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/CommunalBlueprint.kt
@@ -43,7 +43,7 @@
     @Composable
     override fun SceneScope.Content(modifier: Modifier) {
         LockscreenLongPress(
-            viewModel = viewModel.longPress,
+            viewModel = viewModel.touchHandling,
             modifier = modifier,
         ) { _ ->
             Box(modifier.background(Color.Black)) {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
index a39fa64..0a4c6fd 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/DefaultBlueprint.kt
@@ -72,7 +72,7 @@
         val unfoldTranslations by viewModel.unfoldTranslations.collectAsStateWithLifecycle()
 
         LockscreenLongPress(
-            viewModel = viewModel.longPress,
+            viewModel = viewModel.touchHandling,
             modifier = modifier,
         ) { onSettingsMenuPlaced ->
             Layout(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt
index c83f62c..065f2a2 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/ShortcutsBesideUdfpsBlueprint.kt
@@ -74,7 +74,7 @@
         val unfoldTranslations by viewModel.unfoldTranslations.collectAsStateWithLifecycle()
 
         LockscreenLongPress(
-            viewModel = viewModel.longPress,
+            viewModel = viewModel.touchHandling,
             modifier = modifier,
         ) { onSettingsMenuPlaced ->
             Layout(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt
index 97d5b41..86639fa 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt
@@ -24,6 +24,7 @@
 import androidx.compose.foundation.layout.size
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.res.dimensionResource
 import androidx.compose.ui.unit.DpSize
@@ -183,7 +184,7 @@
         indicationController: KeyguardIndicationController,
         modifier: Modifier = Modifier,
     ) {
-        val (disposable, setDisposable) = mutableStateOf<DisposableHandle?>(null)
+        val (disposable, setDisposable) = remember { mutableStateOf<DisposableHandle?>(null) }
 
         AndroidView(
             factory = { context ->
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SettingsMenuSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SettingsMenuSection.kt
index 44b0535..15032e0 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SettingsMenuSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/SettingsMenuSection.kt
@@ -30,8 +30,8 @@
 import androidx.compose.ui.viewinterop.AndroidView
 import androidx.core.view.isVisible
 import com.android.systemui.keyguard.ui.binder.KeyguardSettingsViewBinder
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardSettingsMenuViewModel
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardTouchHandlingViewModel
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.VibratorHelper
@@ -42,7 +42,7 @@
 @Inject
 constructor(
     private val viewModel: KeyguardSettingsMenuViewModel,
-    private val longPressViewModel: KeyguardLongPressViewModel,
+    private val touchHandlingViewModel: KeyguardTouchHandlingViewModel,
     private val vibratorHelper: VibratorHelper,
     private val activityStarter: ActivityStarter,
 ) {
@@ -69,7 +69,7 @@
                             KeyguardSettingsViewBinder.bind(
                                 view = this,
                                 viewModel = viewModel,
-                                longPressViewModel = longPressViewModel,
+                                touchHandlingViewModel = touchHandlingViewModel,
                                 rootViewModel = null,
                                 vibratorHelper = vibratorHelper,
                                 activityStarter = activityStarter,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationStackContentHeight.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationStackContentHeight.kt
index 9f829cc..22c17f2 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationStackContentHeight.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationStackContentHeight.kt
@@ -24,7 +24,9 @@
 import androidx.compose.ui.node.ModifierNodeElement
 import androidx.compose.ui.node.invalidateMeasurement
 import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.dp
 import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
 
 /**
@@ -32,14 +34,16 @@
  * by the legacy Notification stack scroll view in [NotificationScrollView.intrinsicStackHeight].
  *
  * @param view Notification stack scroll view
- * @param padding extra padding in pixels to be added to the received content height.
+ * @param totalVerticalPadding extra padding to be added to the received stack content height.
  */
-fun Modifier.notificationStackHeight(view: NotificationScrollView, padding: Int = 0) =
-    this then StackLayoutElement(view, padding)
+fun Modifier.notificationStackHeight(
+    view: NotificationScrollView,
+    totalVerticalPadding: Dp = 0.dp,
+) = this then StackLayoutElement(view, totalVerticalPadding)
 
 private data class StackLayoutElement(
     val view: NotificationScrollView,
-    val padding: Int,
+    val padding: Dp,
 ) : ModifierNodeElement<StackLayoutNode>() {
 
     override fun create(): StackLayoutNode = StackLayoutNode(view, padding)
@@ -53,7 +57,7 @@
     }
 }
 
-private class StackLayoutNode(val view: NotificationScrollView, var padding: Int) :
+private class StackLayoutNode(val view: NotificationScrollView, var padding: Dp) :
     LayoutModifierNode, Modifier.Node() {
 
     private val stackHeightChangedListener = Runnable { invalidateMeasureIfAttached() }
@@ -72,7 +76,7 @@
         measurable: Measurable,
         constraints: Constraints
     ): MeasureResult {
-        val contentHeight = padding + view.intrinsicStackHeight
+        val contentHeight = padding.roundToPx() + view.intrinsicStackHeight
         val placeable =
             measurable.measure(
                 constraints.copy(minHeight = contentHeight, maxHeight = contentHeight)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
index 45a8393..12ca997 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
@@ -19,15 +19,23 @@
 
 import android.util.Log
 import androidx.compose.animation.core.Animatable
+import androidx.compose.animation.core.tween
 import androidx.compose.foundation.ScrollState
 import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.foundation.gestures.animateScrollBy
+import androidx.compose.foundation.gestures.rememberScrollableState
 import androidx.compose.foundation.gestures.scrollBy
+import androidx.compose.foundation.gestures.scrollable
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.WindowInsets
+import androidx.compose.foundation.layout.absoluteOffset
 import androidx.compose.foundation.layout.asPaddingValues
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.offset
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.systemBars
@@ -39,9 +47,11 @@
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
 import androidx.compose.runtime.mutableIntStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.setValue
 import androidx.compose.runtime.snapshotFlow
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
@@ -50,6 +60,7 @@
 import androidx.compose.ui.graphics.BlendMode
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
 import androidx.compose.ui.input.nestedscroll.nestedScroll
 import androidx.compose.ui.layout.LayoutCoordinates
 import androidx.compose.ui.layout.boundsInWindow
@@ -57,17 +68,21 @@
 import androidx.compose.ui.layout.onPlaced
 import androidx.compose.ui.layout.onSizeChanged
 import androidx.compose.ui.layout.positionInWindow
+import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.res.dimensionResource
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.Velocity
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.util.lerp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.compose.animation.scene.ElementKey
+import com.android.compose.animation.scene.LowestZIndexScenePicker
 import com.android.compose.animation.scene.NestedScrollBehavior
 import com.android.compose.animation.scene.SceneScope
 import com.android.compose.modifiers.thenIf
+import com.android.internal.policy.SystemBarUtils
 import com.android.systemui.common.ui.compose.windowinsets.LocalRawScreenHeight
 import com.android.systemui.common.ui.compose.windowinsets.LocalScreenCornerRadius
 import com.android.systemui.res.R
@@ -89,8 +104,10 @@
     object Elements {
         val NotificationScrim = ElementKey("NotificationScrim")
         val NotificationStackPlaceholder = ElementKey("NotificationStackPlaceholder")
-        val HeadsUpNotificationPlaceholder = ElementKey("HeadsUpNotificationPlaceholder")
+        val HeadsUpNotificationPlaceholder =
+            ElementKey("HeadsUpNotificationPlaceholder", scenePicker = LowestZIndexScenePicker)
         val ShelfSpace = ElementKey("ShelfSpace")
+        val NotificationStackCutoffGuideline = ElementKey("NotificationStackCutoffGuideline")
     }
 
     // Expansion fraction thresholds (between 0-1f) at which the corresponding value should be
@@ -112,10 +129,10 @@
     modifier: Modifier = Modifier,
     isPeekFromBottom: Boolean = false,
 ) {
-    Element(
-        Notifications.Elements.HeadsUpNotificationPlaceholder,
+    Box(
         modifier =
             modifier
+                .element(Notifications.Elements.HeadsUpNotificationPlaceholder)
                 .fillMaxWidth()
                 .notificationHeadsUpHeight(stackScrollView)
                 .debugBackground(viewModel, DEBUG_HUN_COLOR)
@@ -129,9 +146,88 @@
                     // Note: boundsInWindow doesn't scroll off the screen
                     stackScrollView.setHeadsUpTop(boundsInWindow.top)
                 }
-    ) {
-        content {}
+    )
+}
+
+/**
+ * A version of [HeadsUpNotificationSpace] that can be swiped up off the top edge of the screen by
+ * the user. When swiped up, the heads up notification is snoozed.
+ */
+@Composable
+fun SceneScope.SnoozeableHeadsUpNotificationSpace(
+    stackScrollView: NotificationScrollView,
+    viewModel: NotificationsPlaceholderViewModel,
+) {
+    val context = LocalContext.current
+    val density = LocalDensity.current
+    val statusBarHeight = SystemBarUtils.getStatusBarHeight(context)
+    val headsUpPadding =
+        with(density) { dimensionResource(id = R.dimen.heads_up_status_bar_padding).roundToPx() }
+
+    val isHeadsUp by viewModel.isHeadsUpOrAnimatingAway.collectAsStateWithLifecycle(false)
+
+    var scrollOffset by remember { mutableFloatStateOf(0f) }
+    val minScrollOffset = -(statusBarHeight + headsUpPadding.toFloat())
+    val maxScrollOffset = 0f
+
+    val scrollableState = rememberScrollableState { delta ->
+        consumeDeltaWithinRange(
+            current = scrollOffset,
+            setCurrent = { scrollOffset = it },
+            min = minScrollOffset,
+            max = maxScrollOffset,
+            delta
+        )
     }
+
+    val nestedScrollConnection =
+        object : NestedScrollConnection {
+            override suspend fun onPreFling(available: Velocity): Velocity {
+                if (
+                    velocityOrPositionalThresholdReached(scrollOffset, minScrollOffset, available.y)
+                ) {
+                    scrollableState.animateScrollBy(minScrollOffset, tween())
+                } else {
+                    scrollableState.animateScrollBy(-minScrollOffset, tween())
+                }
+                return available
+            }
+        }
+
+    LaunchedEffect(isHeadsUp) { scrollOffset = 0f }
+
+    LaunchedEffect(scrollableState.isScrollInProgress) {
+        if (!scrollableState.isScrollInProgress && scrollOffset <= minScrollOffset) {
+            viewModel.snoozeHun()
+        }
+    }
+
+    HeadsUpNotificationSpace(
+        stackScrollView = stackScrollView,
+        viewModel = viewModel,
+        modifier =
+            Modifier.absoluteOffset {
+                    IntOffset(
+                        x = 0,
+                        y =
+                            calculateHeadsUpPlaceholderYOffset(
+                                scrollOffset.roundToInt(),
+                                minScrollOffset.roundToInt(),
+                                stackScrollView.topHeadsUpHeight
+                            )
+                    )
+                }
+                .thenIf(isHeadsUp) {
+                    Modifier.verticalNestedScrollToScene(
+                            bottomBehavior = NestedScrollBehavior.EdgeAlways
+                        )
+                        .nestedScroll(nestedScrollConnection)
+                        .scrollable(
+                            orientation = Orientation.Vertical,
+                            state = scrollableState,
+                        )
+                }
+    )
 }
 
 /** Adds the space where notification stack should appear in the scene. */
@@ -155,6 +251,11 @@
             viewModel = viewModel,
             modifier = Modifier.align(Alignment.TopCenter),
         )
+        NotificationStackCutoffGuideline(
+            stackScrollView = stackScrollView,
+            viewModel = viewModel,
+            modifier = Modifier.align(Alignment.BottomCenter),
+        )
     }
 }
 
@@ -171,6 +272,7 @@
     shouldPunchHoleBehindScrim: Boolean,
     shouldFillMaxSize: Boolean = true,
     shouldReserveSpaceForNavBar: Boolean = true,
+    shouldIncludeHeadsUpSpace: Boolean = true,
     shadeMode: ShadeMode,
     modifier: Modifier = Modifier,
 ) {
@@ -187,8 +289,10 @@
         viewModel.isCurrentGestureOverscroll.collectAsStateWithLifecycle(false)
     val expansionFraction by viewModel.expandFraction.collectAsStateWithLifecycle(0f)
 
-    val navBarHeight =
-        with(density) { WindowInsets.systemBars.asPaddingValues().calculateBottomPadding().toPx() }
+    val topPadding = dimensionResource(id = R.dimen.notification_side_paddings)
+    val navBarHeight = WindowInsets.systemBars.asPaddingValues().calculateBottomPadding()
+    val bottomPadding = if (shouldReserveSpaceForNavBar) navBarHeight else 0.dp
+
     val screenHeight = LocalRawScreenHeight.current
 
     /**
@@ -221,6 +325,8 @@
     // The height of the scrim visible on screen when it is in its resting (collapsed) state.
     val minVisibleScrimHeight: () -> Float = { screenHeight - maxScrimTop() }
 
+    val isClickable by viewModel.isClickable.collectAsStateWithLifecycle()
+
     // we are not scrolled to the top unless the scrim is at its maximum offset.
     LaunchedEffect(viewModel, scrimOffset) {
         snapshotFlow { scrimOffset.value >= 0f }
@@ -316,6 +422,9 @@
                         )
                     )
                 }
+                .thenIf(isClickable) {
+                    Modifier.clickable(onClick = { viewModel.onEmptySpaceClicked() })
+                }
     ) {
         // Creates a cutout in the background scrim in the shape of the notifications scrim.
         // Only visible when notif scrim alpha < 1, during shade expansion.
@@ -351,15 +460,18 @@
                             Modifier.nestedScroll(scrimNestedScrollConnection)
                         }
                         .verticalScroll(scrollState)
+                        .padding(top = topPadding)
                         .fillMaxWidth()
                         .notificationStackHeight(
                             view = stackScrollView,
-                            padding = if (shouldReserveSpaceForNavBar) navBarHeight.toInt() else 0
+                            totalVerticalPadding = topPadding + bottomPadding,
                         )
                         .onSizeChanged { size -> stackHeight.intValue = size.height },
             )
         }
-        HeadsUpNotificationSpace(stackScrollView = stackScrollView, viewModel = viewModel)
+        if (shouldIncludeHeadsUpSpace) {
+            HeadsUpNotificationSpace(stackScrollView = stackScrollView, viewModel = viewModel)
+        }
     }
 }
 
@@ -395,6 +507,30 @@
     )
 }
 
+/**
+ * A 0 height horizontal spacer to be placed at the bottom-most position in the current scene, where
+ * the notification contents (stack, footer, shelf) should be drawn.
+ */
+@Composable
+fun SceneScope.NotificationStackCutoffGuideline(
+    stackScrollView: NotificationScrollView,
+    viewModel: NotificationsPlaceholderViewModel,
+    modifier: Modifier = Modifier,
+) {
+    Spacer(
+        modifier =
+            modifier
+                .element(key = Notifications.Elements.NotificationStackCutoffGuideline)
+                .fillMaxWidth()
+                .height(0.dp)
+                .onGloballyPositioned { coordinates ->
+                    val positionY = coordinates.positionInWindow().y
+                    debugLog(viewModel) { "STACK cutoff onGloballyPositioned: y=$positionY" }
+                    stackScrollView.setStackCutoff(positionY)
+                }
+    )
+}
+
 @Composable
 private fun SceneScope.NotificationPlaceholder(
     stackScrollView: NotificationScrollView,
@@ -417,7 +553,6 @@
                     }
                     // NOTE: positionInWindow.y scrolls off screen, but boundsInWindow.top will not
                     stackScrollView.setStackTop(positionInWindow.y)
-                    stackScrollView.setStackBottom(positionInWindow.y + coordinates.size.height)
                 }
     )
 }
@@ -440,6 +575,47 @@
     }
 }
 
+private fun calculateHeadsUpPlaceholderYOffset(
+    scrollOffset: Int,
+    minScrollOffset: Int,
+    topHeadsUpHeight: Int,
+): Int {
+    return -minScrollOffset +
+        (scrollOffset * (-minScrollOffset + topHeadsUpHeight) / -minScrollOffset)
+}
+
+private fun velocityOrPositionalThresholdReached(
+    scrollOffset: Float,
+    minScrollOffset: Float,
+    availableVelocityY: Float,
+): Boolean {
+    return availableVelocityY < HUN_SNOOZE_VELOCITY_THRESHOLD ||
+        (availableVelocityY <= 0f &&
+            scrollOffset < minScrollOffset * HUN_SNOOZE_POSITIONAL_THRESHOLD_FRACTION)
+}
+
+/**
+ * Takes a range, current value, and delta, and updates the current value by the delta, coercing the
+ * result within the given range. Returns how much of the delta was consumed.
+ */
+private fun consumeDeltaWithinRange(
+    current: Float,
+    setCurrent: (Float) -> Unit,
+    min: Float,
+    max: Float,
+    delta: Float
+): Float {
+    return if (delta < 0 && current > min) {
+        val remainder = (current + delta - min).coerceAtMost(0f)
+        setCurrent((current + delta).coerceAtLeast(min))
+        delta - remainder
+    } else if (delta > 0 && current < max) {
+        val remainder = (current + delta).coerceAtLeast(0f)
+        setCurrent((current + delta).coerceAtMost(max))
+        delta - remainder
+    } else 0f
+}
+
 private inline fun debugLog(
     viewModel: NotificationsPlaceholderViewModel,
     msg: () -> Any,
@@ -474,3 +650,5 @@
 private val DEBUG_STACK_COLOR = Color(1f, 0f, 0f, 0.2f)
 private val DEBUG_HUN_COLOR = Color(0f, 0f, 1f, 0.2f)
 private val DEBUG_BOX_COLOR = Color(0f, 1f, 0f, 0.2f)
+private const val HUN_SNOOZE_POSITIONAL_THRESHOLD_FRACTION = 0.25f
+private const val HUN_SNOOZE_VELOCITY_THRESHOLD = -70f
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeScene.kt
index f62a28c..db98bc8f 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/NotificationsShadeScene.kt
@@ -20,7 +20,6 @@
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.padding
 import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
 import com.android.compose.animation.scene.SceneScope
@@ -75,7 +74,6 @@
         OverlayShade(
             modifier = modifier,
             viewModel = overlayShadeViewModel,
-            panelAlignment = Alignment.TopEnd,
             lockscreenContent = lockscreenContent,
         ) {
             Column {
@@ -98,6 +96,12 @@
                     shadeMode = ShadeMode.Dual,
                     modifier = Modifier.fillMaxWidth(),
                 )
+
+                // Communicates the bottom position of the drawable area within the shade to NSSL.
+                NotificationStackCutoffGuideline(
+                    stackScrollView = stackScrollView.get(),
+                    viewModel = notificationsPlaceholderViewModel,
+                )
             }
         }
     }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/BrightnessMirror.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/BrightnessMirror.kt
index 73a624a..aca473d 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/BrightnessMirror.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/BrightnessMirror.kt
@@ -18,8 +18,9 @@
 
 import androidx.compose.animation.core.animateFloatAsState
 import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxHeight
 import androidx.compose.foundation.layout.offset
+import androidx.compose.foundation.layout.wrapContentWidth
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.ui.Alignment
@@ -39,6 +40,7 @@
     viewModel: BrightnessMirrorViewModel,
     qsSceneAdapter: QSSceneAdapter,
     modifier: Modifier = Modifier,
+    measureFromContainer: Boolean = false,
 ) {
     val isShowing by viewModel.isShowing.collectAsStateWithLifecycle()
     val mirrorAlpha by
@@ -47,9 +49,22 @@
             label = "alphaAnimationBrightnessMirrorShowing",
         )
     val mirrorOffsetAndSize by viewModel.locationAndSize.collectAsStateWithLifecycle()
-    val offset = IntOffset(0, mirrorOffsetAndSize.yOffset)
+    val yOffset =
+        if (measureFromContainer) {
+            mirrorOffsetAndSize.yOffsetFromContainer
+        } else {
+            mirrorOffsetAndSize.yOffsetFromWindow
+        }
+    val offset = IntOffset(0, yOffset)
 
-    Box(modifier = modifier.fillMaxSize().graphicsLayer { alpha = mirrorAlpha }) {
+    // Use unbounded=true as the full mirror (with paddings and background offset) may be larger
+    // than the space we have (but it will fit, because the brightness slider fits).
+    Box(
+        modifier =
+            modifier.fillMaxHeight().wrapContentWidth(unbounded = true).graphicsLayer {
+                alpha = mirrorAlpha
+            }
+    ) {
         QuickSettingsTheme {
             // The assumption for using this AndroidView is that there will be only one in view at
             // a given time (which is a reasonable assumption). Because `QSSceneAdapter` (actually
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
index 1b49b67..2d5d259 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
@@ -42,6 +42,8 @@
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.navigationBars
+import androidx.compose.foundation.layout.navigationBarsPadding
+import androidx.compose.foundation.layout.offset
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.wrapContentHeight
 import androidx.compose.foundation.rememberScrollState
@@ -62,6 +64,7 @@
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.LocalLifecycleOwner
 import androidx.compose.ui.res.colorResource
+import androidx.compose.ui.unit.IntOffset
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.compose.animation.scene.SceneScope
@@ -82,6 +85,8 @@
 import com.android.systemui.media.controls.ui.view.MediaHost
 import com.android.systemui.media.dagger.MediaModule
 import com.android.systemui.notifications.ui.composable.HeadsUpNotificationSpace
+import com.android.systemui.notifications.ui.composable.NotificationScrollingStack
+import com.android.systemui.notifications.ui.composable.NotificationStackCutoffGuideline
 import com.android.systemui.qs.footer.ui.compose.FooterActionsWithAnimatedVisibility
 import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaLandscapeTopOffset
 import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaOffset.InQS
@@ -90,6 +95,7 @@
 import com.android.systemui.scene.session.ui.composable.SaveableSession
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.ui.composable.ComposableScene
+import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.shade.ui.composable.CollapsedShadeHeader
 import com.android.systemui.shade.ui.composable.ExpandedShadeHeader
 import com.android.systemui.shade.ui.composable.Shade
@@ -102,6 +108,7 @@
 import dagger.Lazy
 import javax.inject.Inject
 import javax.inject.Named
+import kotlin.math.roundToInt
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.stateIn
@@ -178,7 +185,11 @@
 
     BrightnessMirror(
         viewModel = viewModel.brightnessMirrorViewModel,
-        qsSceneAdapter = viewModel.qsSceneAdapter
+        qsSceneAdapter = viewModel.qsSceneAdapter,
+        modifier =
+            Modifier.thenIf(cutoutLocation != CutoutLocation.CENTER) {
+                Modifier.displayCutoutPadding()
+            }
     )
 
     val shouldPunchHoleBehindScrim =
@@ -400,5 +411,24 @@
             modifier = Modifier.align(Alignment.BottomCenter),
             isPeekFromBottom = true,
         )
+        NotificationScrollingStack(
+            shadeSession = shadeSession,
+            stackScrollView = notificationStackScrollView,
+            viewModel = notificationsPlaceholderViewModel,
+            maxScrimTop = { screenHeight },
+            shouldPunchHoleBehindScrim = shouldPunchHoleBehindScrim,
+            shouldIncludeHeadsUpSpace = false,
+            shadeMode = ShadeMode.Single,
+            modifier =
+                Modifier.fillMaxWidth().offset { IntOffset(x = 0, y = screenHeight.roundToInt()) },
+        )
+        NotificationStackCutoffGuideline(
+            stackScrollView = notificationStackScrollView,
+            viewModel = viewModel.notifications,
+            modifier =
+                Modifier.align(Alignment.BottomCenter).navigationBarsPadding().offset {
+                    IntOffset(x = 0, y = screenHeight.roundToInt())
+                }
+        )
     }
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt
index a0d6be9..422c9f6 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsShadeScene.kt
@@ -16,14 +16,14 @@
 
 package com.android.systemui.qs.ui.composable
 
-import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.AnimatedContent
 import androidx.compose.animation.EnterTransition
 import androidx.compose.animation.ExitTransition
 import androidx.compose.animation.core.tween
 import androidx.compose.animation.fadeIn
 import androidx.compose.animation.fadeOut
+import androidx.compose.animation.togetherWith
 import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
@@ -46,6 +46,9 @@
 import com.android.systemui.keyguard.ui.composable.LockscreenContent
 import com.android.systemui.qs.panels.ui.compose.EditMode
 import com.android.systemui.qs.panels.ui.compose.TileGrid
+import com.android.systemui.qs.ui.composable.QuickSettingsShade.Transitions.QuickSettingsLayoutEnter
+import com.android.systemui.qs.ui.composable.QuickSettingsShade.Transitions.QuickSettingsLayoutExit
+import com.android.systemui.qs.ui.viewmodel.QuickSettingsContainerViewModel
 import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeSceneViewModel
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.ui.composable.ComposableScene
@@ -82,7 +85,6 @@
     ) {
         OverlayShade(
             viewModel = viewModel.overlayShadeViewModel,
-            panelAlignment = Alignment.TopEnd,
             lockscreenContent = lockscreenContent,
             modifier = modifier,
         ) {
@@ -96,7 +98,7 @@
                 )
 
                 ShadeBody(
-                    viewModel = viewModel,
+                    viewModel = viewModel.quickSettingsContainerViewModel,
                 )
             }
         }
@@ -105,39 +107,30 @@
 
 @Composable
 private fun ShadeBody(
-    viewModel: QuickSettingsShadeSceneViewModel,
+    viewModel: QuickSettingsContainerViewModel,
 ) {
     val isEditing by viewModel.editModeViewModel.isEditing.collectAsStateWithLifecycle()
 
-    Box {
-        // The main Quick Settings grid layout.
-        AnimatedVisibility(
-            visible = !isEditing,
-            enter = QuickSettingsShade.Transitions.QuickSettingsLayoutEnter,
-            exit = QuickSettingsShade.Transitions.QuickSettingsLayoutExit,
-        ) {
-            QuickSettingsLayout(
-                viewModel = viewModel,
-            )
-        }
-
-        // The Quick Settings Editor layout.
-        AnimatedVisibility(
-            visible = isEditing,
-            enter = QuickSettingsShade.Transitions.QuickSettingsEditorEnter,
-            exit = QuickSettingsShade.Transitions.QuickSettingsEditorExit,
-        ) {
+    AnimatedContent(
+        targetState = isEditing,
+        transitionSpec = { QuickSettingsLayoutEnter togetherWith QuickSettingsLayoutExit }
+    ) { editing ->
+        if (editing) {
             EditMode(
                 viewModel = viewModel.editModeViewModel,
                 modifier = Modifier.fillMaxWidth().padding(QuickSettingsShade.Dimensions.Padding)
             )
+        } else {
+            QuickSettingsLayout(
+                viewModel = viewModel,
+            )
         }
     }
 }
 
 @Composable
 private fun QuickSettingsLayout(
-    viewModel: QuickSettingsShadeSceneViewModel,
+    viewModel: QuickSettingsContainerViewModel,
     modifier: Modifier = Modifier,
 ) {
     Column(
@@ -155,6 +148,7 @@
             viewModel = viewModel.tileGridViewModel,
             modifier =
                 Modifier.fillMaxWidth().heightIn(max = QuickSettingsShade.Dimensions.GridMaxHeight),
+            viewModel.editModeViewModel::startEditing,
         )
         Button(
             onClick = { viewModel.editModeViewModel.startEditing() },
@@ -169,7 +163,7 @@
     object Dimensions {
         val Padding = 16.dp
         val BrightnessSliderHeight = 64.dp
-        val GridMaxHeight = 400.dp
+        val GridMaxHeight = 800.dp
     }
 
     object Transitions {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/session/ui/composable/Session.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/session/ui/composable/Session.kt
index 924aa54..4eaacf3 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/session/ui/composable/Session.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/session/ui/composable/Session.kt
@@ -86,7 +86,7 @@
  */
 @Composable
 fun <T> Session.rememberSession(vararg inputs: Any?, key: String? = null, init: () -> T): T =
-    rememberSession(key, inputs, init = init)
+    rememberSession(key, *inputs, init = init)
 
 /**
  * An explicit storage for remembering composable state outside of the lifetime of a composition.
@@ -151,7 +151,7 @@
     vararg inputs: Any?,
     key: String? = null,
 ): SaveableSession =
-    rememberSaveable(inputs, SaveableSessionImpl.SessionSaver, key) { SaveableSessionImpl() }
+    rememberSaveable(*inputs, SaveableSessionImpl.SessionSaver, key) { SaveableSessionImpl() }
 
 private class SessionImpl(
     private val storage: SessionStorage = SessionStorage(),
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
index 4e334c2..a44041a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
@@ -17,26 +17,19 @@
 package com.android.systemui.scene.ui.composable
 
 import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.absoluteOffset
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.res.dimensionResource
-import androidx.compose.ui.unit.IntOffset
 import com.android.compose.animation.scene.SceneScope
 import com.android.compose.animation.scene.UserAction
 import com.android.compose.animation.scene.UserActionResult
 import com.android.compose.animation.scene.animateSceneDpAsState
 import com.android.compose.animation.scene.animateSceneFloatAsState
-import com.android.internal.policy.SystemBarUtils
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.notifications.ui.composable.HeadsUpNotificationSpace
+import com.android.systemui.notifications.ui.composable.SnoozeableHeadsUpNotificationSpace
 import com.android.systemui.qs.ui.composable.QuickSettings
 import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaLandscapeTopOffset
 import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaOffset.Default
-import com.android.systemui.res.R
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.ui.viewmodel.GoneSceneViewModel
 import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
@@ -72,28 +65,9 @@
         )
         animateSceneDpAsState(value = Default, key = MediaLandscapeTopOffset, canOverflow = false)
         Spacer(modifier.fillMaxSize())
-        HeadsUpNotificationStack(
+        SnoozeableHeadsUpNotificationSpace(
             stackScrollView = notificationStackScrolLView.get(),
             viewModel = notificationsPlaceholderViewModel
         )
     }
 }
-
-@Composable
-private fun SceneScope.HeadsUpNotificationStack(
-    stackScrollView: NotificationScrollView,
-    viewModel: NotificationsPlaceholderViewModel,
-) {
-    val context = LocalContext.current
-    val density = LocalDensity.current
-    val statusBarHeight = SystemBarUtils.getStatusBarHeight(context)
-    val headsUpPadding =
-        with(density) { dimensionResource(id = R.dimen.heads_up_status_bar_padding).roundToPx() }
-
-    HeadsUpNotificationSpace(
-        stackScrollView = stackScrollView,
-        viewModel = viewModel,
-        modifier =
-            Modifier.absoluteOffset { IntOffset(x = 0, y = statusBarHeight + headsUpPadding) }
-    )
-}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
index 22566e7..9c9e6c6 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
@@ -34,6 +34,8 @@
 import com.android.compose.animation.scene.MutableSceneTransitionLayoutState
 import com.android.compose.animation.scene.SceneKey
 import com.android.compose.animation.scene.SceneTransitionLayout
+import com.android.compose.animation.scene.UserAction
+import com.android.compose.animation.scene.UserActionResult
 import com.android.compose.animation.scene.observableTransitionState
 import com.android.systemui.ribbon.ui.composable.BottomRightCornerRibbon
 import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
@@ -56,7 +58,6 @@
  *   must have entries in this map.
  * @param modifier A modifier.
  */
-@OptIn(ExperimentalComposeUiApi::class)
 @Composable
 fun SceneContainer(
     viewModel: SceneContainerViewModel,
@@ -66,8 +67,6 @@
 ) {
     val coroutineScope = rememberCoroutineScope()
     val currentSceneKey: SceneKey by viewModel.currentScene.collectAsStateWithLifecycle()
-    val currentDestinations by
-        viewModel.currentDestinationScenes(coroutineScope).collectAsStateWithLifecycle()
     val state: MutableSceneTransitionLayoutState = remember {
         MutableSceneTransitionLayoutState(
             initialScene = currentSceneKey,
@@ -88,20 +87,19 @@
         onDispose { viewModel.setTransitionState(null) }
     }
 
+    val userActionsBySceneKey: Map<SceneKey, Map<UserAction, UserActionResult>> =
+        sceneByKey.values.associate { scene ->
+            val userActions by scene.destinationScenes.collectAsStateWithLifecycle(emptyMap())
+            val resolvedUserActions = viewModel.resolveSceneFamilies(userActions)
+            scene.key to resolvedUserActions
+        }
+
     Box(
         modifier = Modifier.fillMaxSize(),
     ) {
         SceneTransitionLayout(state = state, modifier = modifier.fillMaxSize()) {
             sceneByKey.forEach { (sceneKey, composableScene) ->
-                scene(
-                    key = sceneKey,
-                    userActions =
-                        if (sceneKey == currentSceneKey) {
-                            currentDestinations
-                        } else {
-                            viewModel.resolveSceneFamilies(composableScene.destinationScenes.value)
-                        },
-                ) {
+                scene(key = sceneKey, userActions = checkNotNull(userActionsBySceneKey[sceneKey])) {
                     with(composableScene) {
                         this@scene.Content(
                             modifier = Modifier.element(sceneKey.rootElementKey).fillMaxSize(),
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt
index 5dc833b..e433d32 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt
@@ -1,10 +1,12 @@
 package com.android.systemui.scene.ui.composable
 
 import androidx.compose.foundation.gestures.Orientation
+import com.android.compose.animation.scene.Edge
 import com.android.compose.animation.scene.transitions
 import com.android.systemui.bouncer.ui.composable.Bouncer
 import com.android.systemui.notifications.ui.composable.Notifications
 import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.TransitionKeys.OpenBottomShade
 import com.android.systemui.scene.shared.model.TransitionKeys.SlightlyFasterShadeCollapse
 import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade
 import com.android.systemui.scene.ui.composable.transitions.bouncerToGoneTransition
@@ -42,31 +44,28 @@
     // Scene transitions
 
     from(Scenes.Bouncer, to = Scenes.Gone) { bouncerToGoneTransition() }
-    from(Scenes.Gone, to = Scenes.NotificationsShade) { goneToNotificationsShadeTransition() }
-    from(Scenes.Gone, to = Scenes.Shade) { goneToShadeTransition() }
-    from(
-        Scenes.Gone,
-        to = Scenes.Shade,
-        key = ToSplitShade,
-    ) {
-        goneToSplitShadeTransition()
+    from(Scenes.Gone, to = Scenes.NotificationsShade) {
+        goneToNotificationsShadeTransition(Edge.Top)
     }
-    from(
-        Scenes.Gone,
-        to = Scenes.Shade,
-        key = SlightlyFasterShadeCollapse,
-    ) {
+    from(Scenes.Gone, to = Scenes.NotificationsShade, key = OpenBottomShade) {
+        goneToNotificationsShadeTransition(Edge.Bottom)
+    }
+    from(Scenes.Gone, to = Scenes.QuickSettingsShade) {
+        goneToQuickSettingsShadeTransition(Edge.Top)
+    }
+    from(Scenes.Gone, to = Scenes.QuickSettingsShade, key = OpenBottomShade) {
+        goneToQuickSettingsShadeTransition(Edge.Bottom)
+    }
+    from(Scenes.Gone, to = Scenes.Shade) { goneToShadeTransition() }
+    from(Scenes.Gone, to = Scenes.Shade, key = ToSplitShade) { goneToSplitShadeTransition() }
+    from(Scenes.Gone, to = Scenes.Shade, key = SlightlyFasterShadeCollapse) {
         goneToShadeTransition(durationScale = 0.9)
     }
     from(Scenes.Gone, to = Scenes.QuickSettings) { goneToQuickSettingsTransition() }
-    from(
-        Scenes.Gone,
-        to = Scenes.QuickSettings,
-        key = SlightlyFasterShadeCollapse,
-    ) {
+    from(Scenes.Gone, to = Scenes.QuickSettings, key = SlightlyFasterShadeCollapse) {
         goneToQuickSettingsTransition(durationScale = 0.9)
     }
-    from(Scenes.Gone, to = Scenes.QuickSettingsShade) { goneToQuickSettingsShadeTransition() }
+
     from(Scenes.Lockscreen, to = Scenes.Bouncer) { lockscreenToBouncerTransition() }
     from(Scenes.Lockscreen, to = Scenes.Communal) { lockscreenToCommunalTransition() }
     from(Scenes.Lockscreen, to = Scenes.NotificationsShade) {
@@ -76,18 +75,10 @@
         lockscreenToQuickSettingsShadeTransition()
     }
     from(Scenes.Lockscreen, to = Scenes.Shade) { lockscreenToShadeTransition() }
-    from(
-        Scenes.Lockscreen,
-        to = Scenes.Shade,
-        key = ToSplitShade,
-    ) {
+    from(Scenes.Lockscreen, to = Scenes.Shade, key = ToSplitShade) {
         lockscreenToSplitShadeTransition()
     }
-    from(
-        Scenes.Lockscreen,
-        to = Scenes.Shade,
-        key = SlightlyFasterShadeCollapse,
-    ) {
+    from(Scenes.Lockscreen, to = Scenes.Shade, key = SlightlyFasterShadeCollapse) {
         lockscreenToShadeTransition(durationScale = 0.9)
     }
     from(Scenes.Lockscreen, to = Scenes.QuickSettings) { lockscreenToQuickSettingsTransition() }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToNotificationsShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToNotificationsShadeTransition.kt
index 48ec198..fb41374 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToNotificationsShadeTransition.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToNotificationsShadeTransition.kt
@@ -16,10 +16,12 @@
 
 package com.android.systemui.scene.ui.composable.transitions
 
+import com.android.compose.animation.scene.Edge
 import com.android.compose.animation.scene.TransitionBuilder
 
 fun TransitionBuilder.goneToNotificationsShadeTransition(
+    edge: Edge = Edge.Top,
     durationScale: Double = 1.0,
 ) {
-    toNotificationsShadeTransition(durationScale)
+    toNotificationsShadeTransition(edge, durationScale)
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToQuickSettingsShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToQuickSettingsShadeTransition.kt
index 225ca4e..8a03e29 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToQuickSettingsShadeTransition.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromGoneToQuickSettingsShadeTransition.kt
@@ -16,10 +16,12 @@
 
 package com.android.systemui.scene.ui.composable.transitions
 
+import com.android.compose.animation.scene.Edge
 import com.android.compose.animation.scene.TransitionBuilder
 
 fun TransitionBuilder.goneToQuickSettingsShadeTransition(
+    edge: Edge = Edge.Top,
     durationScale: Double = 1.0,
 ) {
-    toQuickSettingsShadeTransition(durationScale)
+    toQuickSettingsShadeTransition(edge, durationScale)
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromLockscreenToNotificationsShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromLockscreenToNotificationsShadeTransition.kt
index 372e4a1a..02664c1 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromLockscreenToNotificationsShadeTransition.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromLockscreenToNotificationsShadeTransition.kt
@@ -21,5 +21,5 @@
 fun TransitionBuilder.lockscreenToNotificationsShadeTransition(
     durationScale: Double = 1.0,
 ) {
-    toNotificationsShadeTransition(durationScale)
+    toNotificationsShadeTransition(durationScale = durationScale)
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromLockscreenToQuickSettingsShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromLockscreenToQuickSettingsShadeTransition.kt
index ce24f5e..19aa3a7 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromLockscreenToQuickSettingsShadeTransition.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/FromLockscreenToQuickSettingsShadeTransition.kt
@@ -16,10 +16,11 @@
 
 package com.android.systemui.scene.ui.composable.transitions
 
+import com.android.compose.animation.scene.Edge
 import com.android.compose.animation.scene.TransitionBuilder
 
 fun TransitionBuilder.lockscreenToQuickSettingsShadeTransition(
     durationScale: Double = 1.0,
 ) {
-    toQuickSettingsShadeTransition(durationScale)
+    toQuickSettingsShadeTransition(Edge.Top, durationScale)
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt
index 6b3b760..05949b2 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt
@@ -32,6 +32,11 @@
 import kotlin.time.Duration.Companion.milliseconds
 
 fun TransitionBuilder.toNotificationsShadeTransition(
+    /**
+     * The edge where the shade will animate from. This is statically determined (i.e. doesn't
+     * change during runtime).
+     */
+    edge: Edge = Edge.Top,
     durationScale: Double = 1.0,
 ) {
     spec = tween(durationMillis = (DefaultDuration * durationScale).inWholeMilliseconds.toInt())
@@ -50,7 +55,7 @@
             }
         }
 
-    translate(OverlayShade.Elements.Panel, Edge.Top)
+    translate(OverlayShade.Elements.Panel, edge)
 
     fractionRange(end = .5f) { fade(OverlayShade.Elements.Scrim) }
 
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToQuickSettingsShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToQuickSettingsShadeTransition.kt
index ec2f14f..9d13647 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToQuickSettingsShadeTransition.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToQuickSettingsShadeTransition.kt
@@ -19,17 +19,15 @@
 import androidx.compose.animation.core.Spring
 import androidx.compose.animation.core.spring
 import androidx.compose.animation.core.tween
-import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.ui.unit.IntSize
 import com.android.compose.animation.scene.Edge
 import com.android.compose.animation.scene.TransitionBuilder
 import com.android.compose.animation.scene.UserActionDistance
-import com.android.compose.animation.scene.UserActionDistanceScope
 import com.android.systemui.shade.ui.composable.OverlayShade
 import com.android.systemui.shade.ui.composable.Shade
 import kotlin.time.Duration.Companion.milliseconds
 
 fun TransitionBuilder.toQuickSettingsShadeTransition(
+    edge: Edge = Edge.Top,
     durationScale: Double = 1.0,
 ) {
     spec = tween(durationMillis = (DefaultDuration * durationScale).inWholeMilliseconds.toInt())
@@ -38,17 +36,9 @@
             stiffness = Spring.StiffnessMediumLow,
             visibilityThreshold = Shade.Dimensions.ScrimVisibilityThreshold,
         )
-    distance =
-        object : UserActionDistance {
-            override fun UserActionDistanceScope.absoluteDistance(
-                fromSceneSize: IntSize,
-                orientation: Orientation,
-            ): Float {
-                return fromSceneSize.height.toFloat() * 2 / 3f
-            }
-        }
+    distance = UserActionDistance { fromSceneSize, _ -> fromSceneSize.height.toFloat() * 2 / 3f }
 
-    translate(OverlayShade.Elements.Panel, Edge.Top)
+    translate(OverlayShade.Elements.Panel, edge)
 
     fractionRange(end = .5f) { fade(OverlayShade.Elements.Scrim) }
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/OverlayShade.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/OverlayShade.kt
index c189d73..8656223 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/OverlayShade.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/OverlayShade.kt
@@ -54,6 +54,7 @@
 import com.android.compose.windowsizeclass.LocalWindowSizeClass
 import com.android.systemui.keyguard.ui.composable.LockscreenContent
 import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.shade.shared.model.ShadeAlignment
 import com.android.systemui.shade.ui.viewmodel.OverlayShadeViewModel
 import com.android.systemui.util.kotlin.getOrNull
 import dagger.Lazy
@@ -63,7 +64,6 @@
 @Composable
 fun SceneScope.OverlayShade(
     viewModel: OverlayShadeViewModel,
-    panelAlignment: Alignment,
     lockscreenContent: Lazy<Optional<LockscreenContent>>,
     modifier: Modifier = Modifier,
     content: @Composable () -> Unit,
@@ -82,7 +82,12 @@
 
         Box(
             modifier = Modifier.fillMaxSize().panelPadding(),
-            contentAlignment = panelAlignment,
+            contentAlignment =
+                if (viewModel.panelAlignment == ShadeAlignment.Top) {
+                    Alignment.TopEnd
+                } else {
+                    Alignment.BottomEnd
+                },
         ) {
             Panel(
                 modifier = Modifier.element(OverlayShade.Elements.Panel).panelSize(),
@@ -188,7 +193,7 @@
     }
 
     object Colors {
-        val ScrimBackground = Color(0, 0, 0, alpha = 255 / 3)
+        val ScrimBackground = Color(0f, 0f, 0f, alpha = 0.2f)
         val PanelBackground: Color
             @Composable @ReadOnlyComposable get() = MaterialTheme.colorScheme.surfaceContainer
     }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
index ec81e23..4a6599a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeScene.kt
@@ -35,7 +35,7 @@
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.navigationBars
-import androidx.compose.foundation.layout.offset
+import androidx.compose.foundation.layout.navigationBarsPadding
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.rememberScrollState
 import androidx.compose.foundation.shape.RoundedCornerShape
@@ -82,6 +82,7 @@
 import com.android.systemui.media.controls.ui.view.MediaHostState
 import com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL
 import com.android.systemui.notifications.ui.composable.NotificationScrollingStack
+import com.android.systemui.notifications.ui.composable.NotificationStackCutoffGuideline
 import com.android.systemui.qs.footer.ui.compose.FooterActionsWithAnimatedVisibility
 import com.android.systemui.qs.ui.composable.BrightnessMirror
 import com.android.systemui.qs.ui.composable.QSMediaMeasurePolicy
@@ -95,6 +96,7 @@
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel
 import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
+import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
 import com.android.systemui.statusbar.phone.StatusBarLocation
 import com.android.systemui.statusbar.phone.ui.StatusBarIconController
 import com.android.systemui.statusbar.phone.ui.TintedIconManager
@@ -136,6 +138,7 @@
     private val shadeSession: SaveableSession,
     private val notificationStackScrollView: Lazy<NotificationScrollView>,
     private val viewModel: ShadeSceneViewModel,
+    private val notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel,
     private val tintedIconManagerFactory: TintedIconManager.Factory,
     private val batteryMeterViewControllerFactory: BatteryMeterViewController.Factory,
     private val statusBarIconController: StatusBarIconController,
@@ -155,6 +158,7 @@
         ShadeScene(
             notificationStackScrollView.get(),
             viewModel = viewModel,
+            notificationsPlaceholderViewModel = notificationsPlaceholderViewModel,
             createTintedIconManager = tintedIconManagerFactory::create,
             createBatteryMeterViewController = batteryMeterViewControllerFactory::create,
             statusBarIconController = statusBarIconController,
@@ -175,6 +179,7 @@
 private fun SceneScope.ShadeScene(
     notificationStackScrollView: NotificationScrollView,
     viewModel: ShadeSceneViewModel,
+    notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel,
     createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager,
     createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController,
     statusBarIconController: StatusBarIconController,
@@ -189,6 +194,7 @@
             SingleShade(
                 notificationStackScrollView = notificationStackScrollView,
                 viewModel = viewModel,
+                notificationsPlaceholderViewModel = notificationsPlaceholderViewModel,
                 createTintedIconManager = createTintedIconManager,
                 createBatteryMeterViewController = createBatteryMeterViewController,
                 statusBarIconController = statusBarIconController,
@@ -201,6 +207,7 @@
             SplitShade(
                 notificationStackScrollView = notificationStackScrollView,
                 viewModel = viewModel,
+                notificationsPlaceholderViewModel = notificationsPlaceholderViewModel,
                 createTintedIconManager = createTintedIconManager,
                 createBatteryMeterViewController = createBatteryMeterViewController,
                 statusBarIconController = statusBarIconController,
@@ -217,6 +224,7 @@
 private fun SceneScope.SingleShade(
     notificationStackScrollView: NotificationScrollView,
     viewModel: ShadeSceneViewModel,
+    notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel,
     createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager,
     createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController,
     statusBarIconController: StatusBarIconController,
@@ -328,7 +336,7 @@
                         NotificationScrollingStack(
                             shadeSession = shadeSession,
                             stackScrollView = notificationStackScrollView,
-                            viewModel = viewModel.notifications,
+                            viewModel = notificationsPlaceholderViewModel,
                             maxScrimTop = { maxNotifScrimTop.value },
                             shadeMode = ShadeMode.Single,
                             shouldPunchHoleBehindScrim = shouldPunchHoleBehindScrim,
@@ -350,6 +358,11 @@
                 notificationsPlaceable.placeRelative(x = 0, y = maxNotifScrimTop.value.roundToInt())
             }
         }
+        NotificationStackCutoffGuideline(
+            stackScrollView = notificationStackScrollView,
+            viewModel = notificationsPlaceholderViewModel,
+            modifier = Modifier.align(Alignment.BottomCenter).navigationBarsPadding()
+        )
     }
 }
 
@@ -357,6 +370,7 @@
 private fun SceneScope.SplitShade(
     notificationStackScrollView: NotificationScrollView,
     viewModel: ShadeSceneViewModel,
+    notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel,
     createTintedIconManager: (ViewGroup, StatusBarLocation) -> TintedIconManager,
     createBatteryMeterViewController: (ViewGroup, StatusBarLocation) -> BatteryMeterViewController,
     statusBarIconController: StatusBarIconController,
@@ -424,8 +438,10 @@
             label = "alphaAnimationBrightnessMirrorContentHiding",
         )
 
-    viewModel.notifications.setAlphaForBrightnessMirror(contentAlpha)
-    DisposableEffect(Unit) { onDispose { viewModel.notifications.setAlphaForBrightnessMirror(1f) } }
+    notificationsPlaceholderViewModel.setAlphaForBrightnessMirror(contentAlpha)
+    DisposableEffect(Unit) {
+        onDispose { notificationsPlaceholderViewModel.setAlphaForBrightnessMirror(1f) }
+    }
 
     val isMediaVisible by viewModel.isMediaVisible.collectAsStateWithLifecycle()
 
@@ -467,9 +483,9 @@
                     BrightnessMirror(
                         viewModel = viewModel.brightnessMirrorViewModel,
                         qsSceneAdapter = viewModel.qsSceneAdapter,
-                        // Need to remove the offset of the header height, as the mirror uses
-                        // the position of the Brightness slider in the window
-                        modifier = Modifier.offset(y = -ShadeHeader.Dimensions.CollapsedHeight)
+                        // Need to use the offset measured from the container as the header
+                        // has to be accounted for
+                        measureFromContainer = true
                     )
                     Column(
                         verticalArrangement = Arrangement.Top,
@@ -526,9 +542,10 @@
                 NotificationScrollingStack(
                     shadeSession = shadeSession,
                     stackScrollView = notificationStackScrollView,
-                    viewModel = viewModel.notifications,
+                    viewModel = notificationsPlaceholderViewModel,
                     maxScrimTop = { 0f },
                     shouldPunchHoleBehindScrim = false,
+                    shouldReserveSpaceForNavBar = false,
                     shadeMode = ShadeMode.Split,
                     modifier =
                         Modifier.weight(1f)
@@ -538,5 +555,10 @@
                 )
             }
         }
+        NotificationStackCutoffGuideline(
+            stackScrollView = notificationStackScrollView,
+            viewModel = notificationsPlaceholderViewModel,
+            modifier = Modifier.align(Alignment.BottomCenter).navigationBarsPadding()
+        )
     }
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
index fbf91b7..a23bb67 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
@@ -48,6 +48,7 @@
 import com.android.compose.PlatformSliderColors
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.common.ui.compose.Icon
+import com.android.systemui.compose.modifiers.sysuiResTag
 import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.SliderState
 
 @Composable
@@ -62,7 +63,7 @@
     val value by valueState(state)
     PlatformSlider(
         modifier =
-            modifier.clearAndSetSemantics {
+            modifier.sysuiResTag(state.label).clearAndSetSemantics {
                 if (state.isEnabled) {
                     contentDescription = state.label
                     state.a11yClickDescription?.let {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt
index ab14911..9da2a1b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt
@@ -25,20 +25,25 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.ui.Alignment
+import androidx.compose.ui.ExperimentalComposeUiApi
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.semantics.paneTitle
 import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.android.systemui.compose.modifiers.sysuiResTag
 import com.android.systemui.res.R
 import com.android.systemui.volume.panel.ui.layout.ComponentsLayout
 import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelState
 import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel
 
+/** Same as android.platform.systemui_tapl.ui.VolumePanel#VolumePanelTestTag */
+private const val VolumePanelTestTag = "VolumePanel"
 private val padding = 24.dp
 
 @Composable
+@OptIn(ExperimentalComposeUiApi::class)
 fun VolumePanelRoot(
     viewModel: VolumePanelViewModel,
     modifier: Modifier = Modifier,
@@ -52,6 +57,7 @@
             Components(
                 componentsState,
                 modifier
+                    .sysuiResTag(VolumePanelTestTag)
                     .semantics { paneTitle = accessibilityTitle }
                     .padding(
                         start = padding,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt
index c2dd803..ea740a8 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateToScene.kt
@@ -48,8 +48,15 @@
     }
 
     return when (transitionState) {
-        is TransitionState.Idle ->
-            animate(layoutState, target, transitionKey, isInitiatedByUserInput = false)
+        is TransitionState.Idle -> {
+            animate(
+                layoutState,
+                target,
+                transitionKey,
+                isInitiatedByUserInput = false,
+                replacedTransition = null,
+            )
+        }
         is TransitionState.Transition -> {
             val isInitiatedByUserInput = transitionState.isInitiatedByUserInput
 
@@ -79,6 +86,7 @@
                         isInitiatedByUserInput,
                         initialProgress = progress,
                         initialVelocity = transitionState.progressVelocity,
+                        replacedTransition = transitionState,
                     )
                 }
             } else if (transitionState.fromScene == target) {
@@ -101,6 +109,7 @@
                         initialProgress = progress,
                         initialVelocity = transitionState.progressVelocity,
                         reversed = true,
+                        replacedTransition = transitionState,
                     )
                 }
             } else {
@@ -137,6 +146,7 @@
                     isInitiatedByUserInput,
                     fromScene = animateFrom,
                     chain = chain,
+                    replacedTransition = null,
                 )
             }
         }
@@ -148,6 +158,7 @@
     targetScene: SceneKey,
     transitionKey: TransitionKey?,
     isInitiatedByUserInput: Boolean,
+    replacedTransition: TransitionState.Transition?,
     initialProgress: Float = 0f,
     initialVelocity: Float = 0f,
     reversed: Boolean = false,
@@ -164,6 +175,7 @@
                 currentScene = targetScene,
                 isInitiatedByUserInput = isInitiatedByUserInput,
                 isUserInputOngoing = false,
+                replacedTransition = replacedTransition,
             )
         } else {
             OneOffTransition(
@@ -173,6 +185,7 @@
                 currentScene = targetScene,
                 isInitiatedByUserInput = isInitiatedByUserInput,
                 isUserInputOngoing = false,
+                replacedTransition = replacedTransition,
             )
         }
 
@@ -214,7 +227,8 @@
     override val currentScene: SceneKey,
     override val isInitiatedByUserInput: Boolean,
     override val isUserInputOngoing: Boolean,
-) : TransitionState.Transition(fromScene, toScene) {
+    replacedTransition: TransitionState.Transition?,
+) : TransitionState.Transition(fromScene, toScene, replacedTransition) {
     /**
      * The animatable used to animate this transition.
      *
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/CommunalSwipeDetector.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/CommunalSwipeDetector.kt
deleted file mode 100644
index 7be34ca..0000000
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/CommunalSwipeDetector.kt
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.compose.animation.scene
-
-import androidx.compose.foundation.gestures.Orientation
-import androidx.compose.ui.input.pointer.PointerInputChange
-import androidx.compose.ui.input.pointer.positionChange
-import androidx.compose.ui.unit.Density
-import androidx.compose.ui.unit.IntOffset
-import androidx.compose.ui.unit.IntSize
-import kotlin.math.abs
-
-private const val TRAVEL_RATIO_THRESHOLD = .5f
-
-/**
- * {@link CommunalSwipeDetector} provides an implementation of {@link SwipeDetector} and {@link
- * SwipeSourceDetector} to enable fullscreen swipe handling to transition to and from the glanceable
- * hub.
- */
-class CommunalSwipeDetector(private var lastDirection: SwipeSource? = null) :
-    SwipeSourceDetector, SwipeDetector {
-    override fun source(
-        layoutSize: IntSize,
-        position: IntOffset,
-        density: Density,
-        orientation: Orientation
-    ): SwipeSource? {
-        return lastDirection
-    }
-
-    override fun detectSwipe(change: PointerInputChange): Boolean {
-        if (change.positionChange().x > 0) {
-            lastDirection = Edge.Left
-        } else {
-            lastDirection = Edge.Right
-        }
-
-        // Determine whether the ratio of the distance traveled horizontally to the distance
-        // traveled vertically exceeds the threshold.
-        return abs(change.positionChange().x / change.positionChange().y) > TRAVEL_RATIO_THRESHOLD
-    }
-}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
index bb17024..d95b388 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
@@ -37,7 +37,7 @@
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.launch
 
-interface DraggableHandler {
+internal interface DraggableHandler {
     /**
      * Start a drag in the given [startedPosition], with the given [overSlop] and number of
      * [pointersDown].
@@ -51,7 +51,7 @@
  * The [DragController] provides control over the transition between two scenes through the [onDrag]
  * and [onStop] methods.
  */
-interface DragController {
+internal interface DragController {
     /** Drag the current scene by [delta] pixels. */
     fun onDrag(delta: Float)
 
@@ -395,10 +395,11 @@
             if (
                 distance != DistanceUnspecified &&
                     shouldCommitSwipe(
-                        offset,
-                        distance,
-                        velocity,
+                        offset = offset,
+                        distance = distance,
+                        velocity = velocity,
                         wasCommitted = swipeTransition._currentScene == toScene,
+                        requiresFullDistanceSwipe = swipeTransition.requiresFullDistanceSwipe,
                     )
             ) {
                 targetScene = toScene
@@ -472,7 +473,12 @@
         distance: Float,
         velocity: Float,
         wasCommitted: Boolean,
+        requiresFullDistanceSwipe: Boolean,
     ): Boolean {
+        if (requiresFullDistanceSwipe && !wasCommitted) {
+            return offset / distance >= 1f
+        }
+
         fun isCloserToTarget(): Boolean {
             return (offset - distance).absoluteValue < offset.absoluteValue
         }
@@ -530,6 +536,8 @@
         userActionDistanceScope = layoutImpl.userActionDistanceScope,
         orientation = orientation,
         isUpOrLeft = isUpOrLeft,
+        requiresFullDistanceSwipe = result.requiresFullDistanceSwipe,
+        replacedTransition = null,
     )
 }
 
@@ -543,7 +551,10 @@
             _toScene = old._toScene,
             userActionDistanceScope = old.userActionDistanceScope,
             orientation = old.orientation,
-            isUpOrLeft = old.isUpOrLeft
+            isUpOrLeft = old.isUpOrLeft,
+            lastDistance = old.lastDistance,
+            requiresFullDistanceSwipe = old.requiresFullDistanceSwipe,
+            replacedTransition = old,
         )
         .apply {
             _currentScene = old._currentScene
@@ -561,8 +572,11 @@
     val userActionDistanceScope: UserActionDistanceScope,
     override val orientation: Orientation,
     override val isUpOrLeft: Boolean,
+    val requiresFullDistanceSwipe: Boolean,
+    replacedTransition: SwipeTransition?,
+    var lastDistance: Float = DistanceUnspecified,
 ) :
-    TransitionState.Transition(_fromScene.key, _toScene.key),
+    TransitionState.Transition(_fromScene.key, _toScene.key, replacedTransition),
     TransitionState.HasOverscrollProperties {
     var _currentScene by mutableStateOf(_fromScene)
     override val currentScene: SceneKey
@@ -620,8 +634,6 @@
                 get() = distance().absoluteValue
         }
 
-    private var lastDistance = DistanceUnspecified
-
     /** Whether [TransitionState.Transition.finish] was called on this transition. */
     var isFinishing = false
         private set
@@ -901,6 +913,7 @@
     private val topOrLeftBehavior: NestedScrollBehavior,
     private val bottomOrRightBehavior: NestedScrollBehavior,
     private val isExternalOverscrollGesture: () -> Boolean,
+    private val pointersInfoOwner: PointersInfoOwner,
 ) {
     private val layoutState = layoutImpl.state
     private val draggableHandler = layoutImpl.draggableHandler(orientation)
@@ -912,25 +925,12 @@
         // moving on to the next scene.
         var canChangeScene = false
 
-        val actionUpOrLeft =
-            Swipe(
-                direction =
-                    when (orientation) {
-                        Orientation.Horizontal -> SwipeDirection.Left
-                        Orientation.Vertical -> SwipeDirection.Up
-                    },
-                pointerCount = 1,
-            )
-
-        val actionDownOrRight =
-            Swipe(
-                direction =
-                    when (orientation) {
-                        Orientation.Horizontal -> SwipeDirection.Right
-                        Orientation.Vertical -> SwipeDirection.Down
-                    },
-                pointerCount = 1,
-            )
+        var _lastPointersInfo: PointersInfo? = null
+        fun pointersInfo(): PointersInfo {
+            return checkNotNull(_lastPointersInfo) {
+                "PointersInfo should be initialized before the transition begins."
+            }
+        }
 
         fun hasNextScene(amount: Float): Boolean {
             val transitionState = layoutState.transitionState
@@ -938,8 +938,30 @@
             val fromScene = layoutImpl.scene(scene)
             val nextScene =
                 when {
-                    amount < 0f -> fromScene.userActions[actionUpOrLeft]
-                    amount > 0f -> fromScene.userActions[actionDownOrRight]
+                    amount < 0f -> {
+                        val actionUpOrLeft =
+                            Swipe(
+                                direction =
+                                    when (orientation) {
+                                        Orientation.Horizontal -> SwipeDirection.Left
+                                        Orientation.Vertical -> SwipeDirection.Up
+                                    },
+                                pointerCount = pointersInfo().pointersDown,
+                            )
+                        fromScene.userActions[actionUpOrLeft]
+                    }
+                    amount > 0f -> {
+                        val actionDownOrRight =
+                            Swipe(
+                                direction =
+                                    when (orientation) {
+                                        Orientation.Horizontal -> SwipeDirection.Right
+                                        Orientation.Vertical -> SwipeDirection.Down
+                                    },
+                                pointerCount = pointersInfo().pointersDown,
+                            )
+                        fromScene.userActions[actionDownOrRight]
+                    }
                     else -> null
                 }
             if (nextScene != null) return true
@@ -973,6 +995,8 @@
                     return@PriorityNestedScrollConnection false
                 }
 
+                _lastPointersInfo = pointersInfoOwner.pointersInfo()
+
                 // If the current swipe transition is *not* closed to 0f or 1f, then we want the
                 // scroll events to intercept the current transition to continue the scene
                 // transition.
@@ -990,6 +1014,8 @@
                 val isZeroOffset =
                     if (isExternalOverscrollGesture()) false else offsetBeforeStart == 0f
 
+                _lastPointersInfo = pointersInfoOwner.pointersInfo()
+
                 val canStart =
                     when (behavior) {
                         NestedScrollBehavior.DuringTransitionBetweenScenes -> {
@@ -1027,6 +1053,8 @@
                 // We could start an overscroll animation
                 canChangeScene = false
 
+                _lastPointersInfo = pointersInfoOwner.pointersInfo()
+
                 val canStart = behavior.canStartOnPostFling && hasNextScene(velocityAvailable)
                 if (canStart) {
                     isIntercepting = false
@@ -1037,10 +1065,11 @@
             canContinueScroll = { true },
             canScrollOnFling = false,
             onStart = { offsetAvailable ->
+                val pointersInfo = pointersInfo()
                 dragController =
                     draggableHandler.onDragStarted(
-                        pointersDown = 1,
-                        startedPosition = null,
+                        pointersDown = pointersInfo.pointersDown,
+                        startedPosition = pointersInfo.startedPosition,
                         overSlop = if (isIntercepting) 0f else offsetAvailable,
                     )
             },
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
index 09d11b7..377b02b 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
@@ -306,7 +306,6 @@
         return layout(placeable.width, placeable.height) { place(transition, placeable) }
     }
 
-    @OptIn(ExperimentalComposeUiApi::class)
     private fun Placeable.PlacementScope.place(
         transition: TransitionState.Transition?,
         placeable: Placeable,
@@ -496,6 +495,10 @@
     transition: TransitionState.Transition,
     previousTransition: TransitionState.Transition,
 ) {
+    if (transition.replacedTransition == previousTransition) {
+        return
+    }
+
     val sceneStates = element.sceneStates
     fun updatedSceneState(key: SceneKey): Element.SceneState? {
         return sceneStates[key]?.also { it.selfUpdateValuesBeforeInterruption() }
@@ -561,10 +564,20 @@
 }
 
 private fun Element.SceneState.selfUpdateValuesBeforeInterruption() {
-    offsetBeforeInterruption = lastOffset
     sizeBeforeInterruption = lastSize
-    scaleBeforeInterruption = lastScale
-    alphaBeforeInterruption = lastAlpha
+
+    if (lastAlpha > 0f) {
+        offsetBeforeInterruption = lastOffset
+        scaleBeforeInterruption = lastScale
+        alphaBeforeInterruption = lastAlpha
+    } else {
+        // Consider the element as not placed in this scene if it was fully transparent.
+        // TODO(b/290930950): Look into using derived state inside place() instead to not even place
+        // the element at all when alpha == 0f.
+        offsetBeforeInterruption = Offset.Unspecified
+        scaleBeforeInterruption = Scale.Unspecified
+        alphaBeforeInterruption = Element.AlphaUnspecified
+    }
 }
 
 private fun Element.SceneState.updateValuesBeforeInterruption(lastState: Element.SceneState) {
@@ -1075,8 +1088,8 @@
             // range.
             val directionSign = if (transition.isUpOrLeft) -1 else 1
             val isToScene = overscroll.scene == transition.toScene
-            val overscrollProgress = transition.progress.let { if (isToScene) it - 1f else it }
-            val progress = directionSign * overscrollProgress
+            val linearProgress = transition.progress.let { if (isToScene) it - 1f else it }
+            val progress = directionSign * overscroll.progressConverter(linearProgress)
             val rangeProgress = propertySpec.range?.progress(progress) ?: progress
 
             // Interpolate between the value at rest and the over scrolled value.
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
index 6001f1f..cdcfc84 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MultiPointerDraggable.kt
@@ -29,18 +29,21 @@
 import androidx.compose.ui.input.pointer.PointerInputChange
 import androidx.compose.ui.input.pointer.PointerInputScope
 import androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNode
-import androidx.compose.ui.input.pointer.changedToDownIgnoreConsumed
+import androidx.compose.ui.input.pointer.changedToDown
 import androidx.compose.ui.input.pointer.changedToUpIgnoreConsumed
 import androidx.compose.ui.input.pointer.positionChange
 import androidx.compose.ui.input.pointer.positionChangeIgnoreConsumed
 import androidx.compose.ui.input.pointer.util.VelocityTracker
 import androidx.compose.ui.input.pointer.util.addPointerInputChange
 import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
+import androidx.compose.ui.node.DelegatableNode
 import androidx.compose.ui.node.DelegatingNode
 import androidx.compose.ui.node.ModifierNodeElement
 import androidx.compose.ui.node.ObserverModifierNode
 import androidx.compose.ui.node.PointerInputModifierNode
+import androidx.compose.ui.node.TraversableNode
 import androidx.compose.ui.node.currentValueOf
+import androidx.compose.ui.node.findNearestAncestor
 import androidx.compose.ui.node.observeReads
 import androidx.compose.ui.platform.LocalViewConfiguration
 import androidx.compose.ui.unit.IntSize
@@ -48,11 +51,12 @@
 import androidx.compose.ui.util.fastAll
 import androidx.compose.ui.util.fastAny
 import androidx.compose.ui.util.fastFirstOrNull
-import androidx.compose.ui.util.fastForEach
+import androidx.compose.ui.util.fastSumBy
 import kotlin.coroutines.cancellation.CancellationException
 import kotlin.math.sign
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.isActive
+import kotlinx.coroutines.launch
 
 /**
  * Make an element draggable in the given [orientation].
@@ -112,6 +116,18 @@
     }
 }
 
+private val TRAVERSE_KEY = Any()
+
+/** Find the nearest [PointersInfoOwner] ancestor or throw. */
+internal fun DelegatableNode.requireAncestorPointersInfoOwner(): PointersInfoOwner {
+    val ancestorNode =
+        checkNotNull(findNearestAncestor(TRAVERSE_KEY)) {
+            "This should never happen! Couldn't find a MultiPointerDraggableNode. " +
+                "Are we inside an SceneTransitionLayout?"
+        }
+    return ancestorNode as PointersInfoOwner
+}
+
 internal class MultiPointerDraggableNode(
     orientation: Orientation,
     enabled: () -> Boolean,
@@ -120,15 +136,19 @@
         (startedPosition: Offset, overSlop: Float, pointersDown: Int) -> DragController,
     var swipeDetector: SwipeDetector = DefaultSwipeDetector,
 ) :
-    PointerInputModifierNode,
     DelegatingNode(),
+    PointerInputModifierNode,
     CompositionLocalConsumerModifierNode,
+    TraversableNode,
+    PointersInfoOwner,
     ObserverModifierNode {
     private val pointerInputHandler: suspend PointerInputScope.() -> Unit = { pointerInput() }
     private val delegate = delegate(SuspendingPointerInputModifierNode(pointerInputHandler))
     private val velocityTracker = VelocityTracker()
     private var previousEnabled: Boolean = false
 
+    override val traverseKey: Any = TRAVERSE_KEY
+
     var enabled: () -> Boolean = enabled
         set(value) {
             // Reset the pointer input whenever enabled changed.
@@ -138,11 +158,26 @@
             }
         }
 
+    private var _toFloat = orientation.toFunctionOffsetToFloat()
+
+    private fun Offset.toFloat(): Float = _toFloat(this)
+
+    private fun Orientation.toFunctionOffsetToFloat(): (Offset) -> Float =
+        when (this) {
+            Orientation.Vertical -> {
+                { it.y }
+            }
+            Orientation.Horizontal -> {
+                { it.x }
+            }
+        }
+
     var orientation: Orientation = orientation
         set(value) {
             // Reset the pointer input whenever orientation changed.
             if (value != field) {
                 field = value
+                _toFloat = field.toFunctionOffsetToFloat()
                 delegate.resetPointerInputHandler()
             }
         }
@@ -170,12 +205,42 @@
         bounds: IntSize
     ) = delegate.onPointerEvent(pointerEvent, pass, bounds)
 
+    private var startedPosition: Offset? = null
+    private var pointersDown: Int = 0
+
+    override fun pointersInfo(): PointersInfo {
+        return PointersInfo(
+            startedPosition = startedPosition,
+            // Note: We could have 0 pointers during fling or for other reasons.
+            pointersDown = pointersDown.coerceAtLeast(1),
+        )
+    }
+
     private suspend fun PointerInputScope.pointerInput() {
         if (!enabled()) {
             return
         }
 
         coroutineScope {
+            launch {
+                // Intercepts pointer inputs and exposes [PointersInfo], via
+                // [requireAncestorPointersInfoOwner], to our descendants.
+                awaitPointerEventScope {
+                    while (isActive) {
+                        // During the Initial pass, we receive the event after our ancestors.
+                        val pointers = awaitPointerEvent(PointerEventPass.Initial).changes
+
+                        pointersDown = pointers.countDown()
+                        if (pointersDown == 0) {
+                            // There are no more pointers down
+                            startedPosition = null
+                        } else if (startedPosition == null) {
+                            startedPosition = pointers.first().position
+                        }
+                    }
+                }
+            }
+
             awaitPointerEventScope {
                 while (isActive) {
                     try {
@@ -299,15 +364,16 @@
             }
 
         if (drag != null) {
-            // Count the number of pressed pointers.
-            val pressed = mutableSetOf<PointerId>()
-            currentEvent.changes.fastForEach { change ->
-                if (change.pressed) {
-                    pressed.add(change.id)
-                }
-            }
-
-            val controller = onDragStart(drag.position, overSlop, pressed.size)
+            val controller =
+                onDragStart(
+                    // The startedPosition is the starting position when a gesture begins (when the
+                    // first pointer touches the screen), not the point where we begin dragging.
+                    // For example, this could be different if one of our children intercepts the
+                    // gesture first and then we do.
+                    requireNotNull(startedPosition),
+                    overSlop,
+                    pointersDown,
+                )
 
             val successful: Boolean
             try {
@@ -347,15 +413,15 @@
         pass: () -> PointerEventPass,
     ): PointerEvent {
         fun canBeConsumed(changes: List<PointerInputChange>): Boolean {
-            // All pointers must be:
-            return changes.fastAll {
-                // A) recently pressed: even if the event has already been consumed, we can still
-                // use the recently added finger event to determine whether to initiate dragging the
-                // scene.
-                it.changedToDownIgnoreConsumed() ||
-                    // B) unconsumed AND in a new position (on the current axis)
-                    it.positionChange().toFloat() != 0f
-            }
+            // At least one pointer down AND
+            return changes.fastAny { it.pressed } &&
+                // All pointers must be either:
+                changes.fastAll {
+                    // A) unconsumed AND recently pressed
+                    it.changedToDown() ||
+                        // B) unconsumed AND in a new position (on the current axis)
+                        it.positionChange().toFloat() != 0f
+                }
         }
 
         var event: PointerEvent
@@ -367,13 +433,6 @@
         return event
     }
 
-    private fun Offset.toFloat(): Float {
-        return when (orientation) {
-            Orientation.Vertical -> y
-            Orientation.Horizontal -> x
-        }
-    }
-
     /**
      * Continues to read drag events until all pointers are up or the drag event is canceled. The
      * initial pointer to use for driving the drag is [initialPointerId]. [hasDragged] passes the
@@ -451,4 +510,15 @@
             }
         }
     }
+
+    private fun List<PointerInputChange>.countDown() = fastSumBy { if (it.pressed) 1 else 0 }
 }
+
+internal fun interface PointersInfoOwner {
+    fun pointersInfo(): PointersInfo
+}
+
+internal data class PointersInfo(
+    val startedPosition: Offset?,
+    val pointersDown: Int,
+)
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/NestedScrollToScene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/NestedScrollToScene.kt
index 1fa6b3f7..ddff2f7 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/NestedScrollToScene.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/NestedScrollToScene.kt
@@ -128,6 +128,7 @@
     bottomOrRightBehavior: NestedScrollBehavior,
     isExternalOverscrollGesture: () -> Boolean,
 ) : DelegatingNode() {
+    lateinit var pointersInfoOwner: PointersInfoOwner
     private var priorityNestedScrollConnection: PriorityNestedScrollConnection =
         scenePriorityNestedScrollConnection(
             layoutImpl = layoutImpl,
@@ -135,6 +136,7 @@
             topOrLeftBehavior = topOrLeftBehavior,
             bottomOrRightBehavior = bottomOrRightBehavior,
             isExternalOverscrollGesture = isExternalOverscrollGesture,
+            pointersInfoOwner = { pointersInfoOwner.pointersInfo() }
         )
 
     private var nestedScrollNode: DelegatableNode =
@@ -144,6 +146,7 @@
         )
 
     override fun onAttach() {
+        pointersInfoOwner = requireAncestorPointersInfoOwner()
         delegate(nestedScrollNode)
     }
 
@@ -171,6 +174,7 @@
                 topOrLeftBehavior = topOrLeftBehavior,
                 bottomOrRightBehavior = bottomOrRightBehavior,
                 isExternalOverscrollGesture = isExternalOverscrollGesture,
+                pointersInfoOwner = pointersInfoOwner,
             )
         nestedScrollNode =
             nestedScrollModifierNode(
@@ -187,6 +191,7 @@
     topOrLeftBehavior: NestedScrollBehavior,
     bottomOrRightBehavior: NestedScrollBehavior,
     isExternalOverscrollGesture: () -> Boolean,
+    pointersInfoOwner: PointersInfoOwner,
 ) =
     NestedScrollHandlerImpl(
             layoutImpl = layoutImpl,
@@ -194,5 +199,6 @@
             topOrLeftBehavior = topOrLeftBehavior,
             bottomOrRightBehavior = bottomOrRightBehavior,
             isExternalOverscrollGesture = isExternalOverscrollGesture,
+            pointersInfoOwner = pointersInfoOwner,
         )
         .connection
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt
new file mode 100644
index 0000000..dfb8c49
--- /dev/null
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.compose.animation.scene
+
+import androidx.activity.BackEventCompat
+import androidx.activity.compose.PredictiveBackHandler
+import androidx.compose.animation.core.Animatable
+import androidx.compose.animation.core.AnimationVector1D
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableFloatStateOf
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import kotlin.coroutines.cancellation.CancellationException
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.CoroutineStart
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.launch
+
+@Composable
+internal fun PredictiveBackHandler(
+    state: BaseSceneTransitionLayoutState,
+    coroutineScope: CoroutineScope,
+    targetSceneForBack: SceneKey? = null,
+) {
+    PredictiveBackHandler(
+        enabled = targetSceneForBack != null,
+    ) { progress: Flow<BackEventCompat> ->
+        val fromScene = state.transitionState.currentScene
+        if (targetSceneForBack == null || targetSceneForBack == fromScene) {
+            // Note: We have to collect progress otherwise PredictiveBackHandler will throw.
+            progress.first()
+            return@PredictiveBackHandler
+        }
+
+        val transition =
+            PredictiveBackTransition(state, coroutineScope, fromScene, toScene = targetSceneForBack)
+        state.startTransition(transition)
+        try {
+            progress.collect { backEvent -> transition.dragProgress = backEvent.progress }
+
+            // Back gesture successful.
+            transition.animateTo(
+                if (state.canChangeScene(targetSceneForBack)) {
+                    targetSceneForBack
+                } else {
+                    fromScene
+                }
+            )
+        } catch (e: CancellationException) {
+            // Back gesture cancelled.
+            transition.animateTo(fromScene)
+        }
+    }
+}
+
+private class PredictiveBackTransition(
+    val state: BaseSceneTransitionLayoutState,
+    val coroutineScope: CoroutineScope,
+    fromScene: SceneKey,
+    toScene: SceneKey,
+) : TransitionState.Transition(fromScene, toScene) {
+    override var currentScene by mutableStateOf(fromScene)
+        private set
+
+    /** The animated progress once the gesture was committed or cancelled. */
+    private var progressAnimatable by mutableStateOf<Animatable<Float, AnimationVector1D>?>(null)
+    var dragProgress: Float by mutableFloatStateOf(0f)
+
+    override val progress: Float
+        get() = progressAnimatable?.value ?: dragProgress
+
+    override val progressVelocity: Float
+        get() = progressAnimatable?.velocity ?: 0f
+
+    override val isInitiatedByUserInput: Boolean
+        get() = true
+
+    override val isUserInputOngoing: Boolean
+        get() = progressAnimatable == null
+
+    private var animationJob: Job? = null
+
+    override fun finish(): Job = animateTo(currentScene)
+
+    fun animateTo(scene: SceneKey): Job {
+        check(scene == fromScene || scene == toScene)
+        animationJob?.let {
+            return it
+        }
+
+        currentScene = scene
+        val targetProgress =
+            when (scene) {
+                fromScene -> 0f
+                toScene -> 1f
+                else -> error("scene $scene should be either $fromScene or $toScene")
+            }
+
+        val animatable = Animatable(dragProgress).also { progressAnimatable = it }
+
+        // Important: We start atomically to make sure that we start the coroutine even if it is
+        // cancelled right after it is launched, so that finishTransition() is correctly called.
+        return coroutineScope
+            .launch(start = CoroutineStart.ATOMIC) {
+                try {
+                    animatable.animateTo(targetProgress)
+                } finally {
+                    state.finishTransition(this@PredictiveBackTransition, scene)
+                }
+            }
+            .also { animationJob = it }
+    }
+}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
index b925130..7c8fce8 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
@@ -459,9 +459,16 @@
 
     /** The key of the transition that should be used. */
     val transitionKey: TransitionKey? = null,
+
+    /**
+     * If `true`, the swipe will be committed and we will settle to [toScene] if only if the user
+     * swiped at least the swipe distance, i.e. the transition progress was already equal to or
+     * bigger than 100% when the user released their finger. `
+     */
+    val requiresFullDistanceSwipe: Boolean = false,
 )
 
-interface UserActionDistance {
+fun interface UserActionDistance {
     /**
      * Return the **absolute** distance of the user action given the size of the scene we are
      * animating from and the [orientation].
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
index 7ea8cbd..6095419 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
@@ -16,7 +16,6 @@
 
 package com.android.compose.animation.scene
 
-import androidx.activity.compose.BackHandler
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.layout.Box
 import androidx.compose.runtime.Composable
@@ -213,16 +212,9 @@
 
     @Composable
     private fun BackHandler() {
-        val targetSceneForBackOrNull =
+        val targetSceneForBack =
             scene(state.transitionState.currentScene).userActions[Back]?.toScene
-        BackHandler(enabled = targetSceneForBackOrNull != null) {
-            targetSceneForBackOrNull?.let { targetSceneForBack ->
-                // TODO(b/290184746): Handle predictive back and use result.distance if specified.
-                if (state.canChangeScene(targetSceneForBack)) {
-                    with(state) { coroutineScope.onChangeScene(targetSceneForBack) }
-                }
-            }
-        }
+        PredictiveBackHandler(state, coroutineScope, targetSceneForBack)
     }
 
     private fun scenesToCompose(): List<Scene> {
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
index a8df6f4..5b4fbf0 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
@@ -224,6 +224,9 @@
 
         /** The scene this transition is going to. Can't be the same as fromScene */
         val toScene: SceneKey,
+
+        /** The transition that `this` transition is replacing, if any. */
+        internal val replacedTransition: Transition? = null,
     ) : TransitionState {
         /**
          * The key of this transition. This should usually be null, but it can be specified to use a
@@ -279,6 +282,11 @@
 
         init {
             check(fromScene != toScene)
+            check(
+                replacedTransition == null ||
+                    (replacedTransition.fromScene == fromScene &&
+                        replacedTransition.toScene == toScene)
+            )
         }
 
         /**
@@ -321,6 +329,10 @@
                 return 0f
             }
 
+            if (replacedTransition != null) {
+                return replacedTransition.interruptionProgress(layoutImpl)
+            }
+
             fun create(): Animatable<Float, AnimationVector1D> {
                 val animatable = Animatable(1f, visibilityThreshold = ProgressVisibilityThreshold)
                 layoutImpl.coroutineScope.launch {
@@ -521,6 +533,10 @@
                     check(transitionStates.size == 1)
                     check(transitionStates[0] is TransitionState.Idle)
                     transitionStates = listOf(transition)
+                } else if (currentState == transition.replacedTransition) {
+                    // Replace the transition.
+                    transitionStates =
+                        transitionStates.subList(0, transitionStates.lastIndex) + transition
                 } else {
                     // Append the new transition.
                     transitionStates = transitionStates + transition
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt
index 0f6a1d2..e30dd356 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitions.kt
@@ -48,7 +48,8 @@
 ) {
     private val transitionCache =
         mutableMapOf<
-            SceneKey, MutableMap<SceneKey, MutableMap<TransitionKey?, TransitionSpecImpl>>
+            SceneKey,
+            MutableMap<SceneKey, MutableMap<TransitionKey?, TransitionSpecImpl>>
         >()
 
     private val overscrollCache =
@@ -87,8 +88,7 @@
         return transition(from, to, key) {
                 (it.from == to && it.to == null) || (it.to == from && it.from == null)
             }
-            ?.reversed()
-            ?: defaultTransition(from, to)
+            ?.reversed() ?: defaultTransition(from, to)
     }
 
     private fun transition(
@@ -257,12 +257,24 @@
 
     /** The [TransformationSpec] associated to this [OverscrollSpec]. */
     val transformationSpec: TransformationSpec
+
+    /**
+     * Function that takes a linear overscroll progress value ranging from 0 to +/- infinity and
+     * outputs the desired **overscroll progress value**.
+     *
+     * When the progress value is:
+     * - 0, the user is not overscrolling.
+     * - 1, the user overscrolled by exactly the [OverscrollBuilder.distance].
+     * - Greater than 1, the user overscrolled more than the [OverscrollBuilder.distance].
+     */
+    val progressConverter: (Float) -> Float
 }
 
 internal class OverscrollSpecImpl(
     override val scene: SceneKey,
     override val orientation: Orientation,
     override val transformationSpec: TransformationSpecImpl,
+    override val progressConverter: (Float) -> Float,
 ) : OverscrollSpec
 
 /**
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt
index 465a410..89ed8d6 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDsl.kt
@@ -185,6 +185,17 @@
 
 @TransitionDsl
 interface OverscrollBuilder : BaseTransitionBuilder {
+    /**
+     * Function that takes a linear overscroll progress value ranging from 0 to +/- infinity and
+     * outputs the desired **overscroll progress value**.
+     *
+     * When the progress value is:
+     * - 0, the user is not overscrolling.
+     * - 1, the user overscrolled by exactly the [distance].
+     * - Greater than 1, the user overscrolled more than the [distance].
+     */
+    var progressConverter: (Float) -> Float
+
     /** Translate the element(s) matching [matcher] by ([x], [y]) pixels. */
     fun translate(
         matcher: ElementMatcher,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt
index 802ab1f..1e67aa9 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/TransitionDslImpl.kt
@@ -81,16 +81,20 @@
         orientation: Orientation,
         builder: OverscrollBuilder.() -> Unit
     ): OverscrollSpec {
-        fun transformationSpec(): TransformationSpecImpl {
-            val impl = OverscrollBuilderImpl().apply(builder)
-            return TransformationSpecImpl(
-                progressSpec = snap(),
-                swipeSpec = null,
-                distance = impl.distance,
-                transformations = impl.transformations,
+        val impl = OverscrollBuilderImpl().apply(builder)
+        val spec =
+            OverscrollSpecImpl(
+                scene = scene,
+                orientation = orientation,
+                transformationSpec =
+                    TransformationSpecImpl(
+                        progressSpec = snap(),
+                        swipeSpec = null,
+                        distance = impl.distance,
+                        transformations = impl.transformations,
+                    ),
+                progressConverter = impl.progressConverter
             )
-        }
-        val spec = OverscrollSpecImpl(scene, orientation, transformationSpec())
         transitionOverscrollSpecs.add(spec)
         return spec
     }
@@ -231,6 +235,8 @@
 }
 
 internal open class OverscrollBuilderImpl : BaseTransitionBuilderImpl(), OverscrollBuilder {
+    override var progressConverter: (Float) -> Float = { it }
+
     override fun translate(
         matcher: ElementMatcher,
         x: OverscrollScope.() -> Float,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/modifiers/SizeMatcher.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/modifiers/SizeMatcher.kt
new file mode 100644
index 0000000..a4bd2be
--- /dev/null
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/modifiers/SizeMatcher.kt
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.compose.animation.scene.modifiers
+
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.layout.Measurable
+import androidx.compose.ui.layout.MeasureResult
+import androidx.compose.ui.layout.MeasureScope
+import androidx.compose.ui.node.LayoutModifierNode
+import androidx.compose.ui.node.ModifierNodeElement
+import androidx.compose.ui.node.invalidateMeasurement
+import androidx.compose.ui.unit.Constraints
+import androidx.compose.ui.unit.IntSize
+import androidx.compose.ui.unit.constrain
+
+/**
+ * An object to make one or more destination node be the same size as a source node.
+ *
+ * Important: Most of the time, you should not use this class and instead use `Box` together with
+ * `Modifier.matchParentSize()`. Use this only if you need to use both `Modifier.element()` and
+ * `Modifier.matchParentSize()` (see b/347910697 for details).
+ *
+ * Example:
+ * ```
+ * Box {
+ *     val sizeMatcher = remember { SizeMatcher() }
+ *
+ *     // The content.
+ *     Content(Modifier.sizeMatcherSource(sizeMatcher))
+ *
+ *     // The background. Note that this has to be composed after Content() so that it
+ *     // is measured after it. We set its zIndex to -1 so that it is still placed
+ *     // (drawn) before/below it. We don't use BoxScope.matchParentSize() because it
+ *     // does not play well with Modifier.element().
+ *     Box(
+ *         Modifier.zIndex(-1f)
+ *             .element(Background)
+ *             // Set the preferred size of this element.
+ *             // Important: This must be *after* the Modifier.element() so that
+ *             // Modifier.element() can override the size.
+ *             .sizeMatcherDestination(sizeMatcher)
+ *             .background(
+ *                 MaterialTheme.colorScheme.primaryContainer,
+ *                 RoundedCornerShape(32.dp),
+ *             )
+ *     )
+ * }
+ * ```
+ *
+ * @see sizeMatcherSource
+ * @see sizeMatcherDestination
+ */
+class SizeMatcher {
+    internal var source: LayoutModifierNode? = null
+        set(value) {
+            if (value != null && field != null && value != field) {
+                error("Exactly one Modifier.sizeMatcherSource() should be specified")
+            }
+        }
+
+    internal var destinations = mutableSetOf<LayoutModifierNode>()
+    internal var sourceSize: IntSize = InvalidSize
+        get() {
+            if (field == InvalidSize) {
+                error(
+                    "SizeMatcher size was retrieved before it was set. You should make sure that " +
+                        "all matcher destination are measured *after* the matcher source."
+                )
+            }
+            return field
+        }
+        set(value) {
+            if (value != field) {
+                field = value
+                destinations.forEach { it.invalidateMeasurement() }
+            }
+        }
+
+    companion object {
+        private val InvalidSize = IntSize(Int.MIN_VALUE, Int.MIN_VALUE)
+    }
+}
+
+/**
+ * Mark this node as the source of a [SizeMatcher].
+ *
+ * Important: There must be only a single source node associated to a [SizeMatcher] and it must be
+ * measured before any destination.
+ */
+fun Modifier.sizeMatcherSource(matcher: SizeMatcher): Modifier {
+    return this.then(SizeMatcherSourceNodeElement(matcher))
+}
+
+/**
+ * Mark this node as the destination of a [SizeMatcher] so that its *preferred* size is the same
+ * size as the source size.
+ *
+ * Important: Destination nodes must be measured *after* the source node, otherwise it might cause
+ * crashes or 1-frame flickers. For most simple layouts (like Box, Row or Column), this usually
+ * means that the destinations nodes must be composed *after* the source node. If doing so is
+ * causing layering issues, you can use `Modifier.zIndex` to explicitly set the placement order of
+ * your composables.
+ */
+fun Modifier.sizeMatcherDestination(matcher: SizeMatcher): Modifier {
+    return this.then(SizeMatcherDestinationElement(matcher))
+}
+
+private data class SizeMatcherSourceNodeElement(
+    private val matcher: SizeMatcher,
+) : ModifierNodeElement<SizeMatcherSourceNode>() {
+    override fun create(): SizeMatcherSourceNode = SizeMatcherSourceNode(matcher)
+
+    override fun update(node: SizeMatcherSourceNode) {
+        node.update(matcher)
+    }
+}
+
+private class SizeMatcherSourceNode(
+    private var matcher: SizeMatcher,
+) : Modifier.Node(), LayoutModifierNode {
+    override fun onAttach() {
+        matcher.source = this
+    }
+
+    override fun onDetach() {
+        matcher.source = null
+    }
+
+    fun update(matcher: SizeMatcher) {
+        val previous = this.matcher
+        this.matcher = matcher
+
+        previous.source = null
+        matcher.source = this
+    }
+
+    override fun MeasureScope.measure(
+        measurable: Measurable,
+        constraints: Constraints
+    ): MeasureResult {
+        return measurable.measure(constraints).run {
+            matcher.sourceSize = IntSize(width, height)
+            layout(width, height) { place(0, 0) }
+        }
+    }
+}
+
+private data class SizeMatcherDestinationElement(
+    private val matcher: SizeMatcher,
+) : ModifierNodeElement<SizeMatcherDestinationNode>() {
+    override fun create(): SizeMatcherDestinationNode = SizeMatcherDestinationNode(matcher)
+
+    override fun update(node: SizeMatcherDestinationNode) {
+        node.update(matcher)
+    }
+}
+
+private class SizeMatcherDestinationNode(
+    private var matcher: SizeMatcher,
+) : Modifier.Node(), LayoutModifierNode {
+    override fun onAttach() {
+        this.matcher.destinations.add(this)
+    }
+
+    override fun onDetach() {
+        this.matcher.destinations.remove(this)
+    }
+
+    fun update(matcher: SizeMatcher) {
+        val previous = this.matcher
+        this.matcher = matcher
+
+        previous.destinations.remove(this)
+        matcher.destinations.add(this)
+    }
+
+    override fun MeasureScope.measure(
+        measurable: Measurable,
+        constraints: Constraints
+    ): MeasureResult {
+        val preferredSize = matcher.sourceSize
+        val preferredConstraints = Constraints.fixed(preferredSize.width, preferredSize.height)
+
+        // Make sure we still respect the incoming constraints.
+        val placeable = measurable.measure(constraints.constrain(preferredConstraints))
+        return layout(placeable.width, placeable.height) { placeable.place(0, 0) }
+    }
+}
diff --git a/packages/SystemUI/compose/scene/src/com/android/systemui/communal/ui/compose/CommunalSwipeDetector.kt b/packages/SystemUI/compose/scene/src/com/android/systemui/communal/ui/compose/CommunalSwipeDetector.kt
new file mode 100644
index 0000000..3fda9b8
--- /dev/null
+++ b/packages/SystemUI/compose/scene/src/com/android/systemui/communal/ui/compose/CommunalSwipeDetector.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.communal.ui.compose
+
+import androidx.compose.foundation.gestures.Orientation
+import androidx.compose.ui.input.pointer.PointerInputChange
+import androidx.compose.ui.input.pointer.positionChange
+import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.IntSize
+import com.android.compose.animation.scene.Edge
+import com.android.compose.animation.scene.SwipeDetector
+import com.android.compose.animation.scene.SwipeSource
+import com.android.compose.animation.scene.SwipeSourceDetector
+import kotlin.math.abs
+
+/**
+ * {@link CommunalSwipeDetector} provides an implementation of {@link SwipeDetector} and {@link
+ * SwipeSourceDetector} to enable fullscreen swipe handling to transition to and from the glanceable
+ * hub.
+ */
+class CommunalSwipeDetector(private var lastDirection: SwipeSource? = null) :
+    SwipeSourceDetector, SwipeDetector {
+    companion object {
+        private const val TRAVEL_RATIO_THRESHOLD = .5f
+    }
+
+    override fun source(
+        layoutSize: IntSize,
+        position: IntOffset,
+        density: Density,
+        orientation: Orientation
+    ): SwipeSource? {
+        return lastDirection
+    }
+
+    override fun detectSwipe(change: PointerInputChange): Boolean {
+        if (change.positionChange().x > 0) {
+            lastDirection = Edge.Left
+        } else {
+            lastDirection = Edge.Right
+        }
+
+        // Determine whether the ratio of the distance traveled horizontally to the distance
+        // traveled vertically exceeds the threshold.
+        return abs(change.positionChange().x / change.positionChange().y) > TRAVEL_RATIO_THRESHOLD
+    }
+}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
index f532e2e..ff83d4b 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/DraggableHandlerTest.kt
@@ -113,7 +113,10 @@
                     orientation = draggableHandler.orientation,
                     topOrLeftBehavior = nestedScrollBehavior,
                     bottomOrRightBehavior = nestedScrollBehavior,
-                    isExternalOverscrollGesture = { isExternalOverscrollGesture }
+                    isExternalOverscrollGesture = { isExternalOverscrollGesture },
+                    pointersInfoOwner = {
+                        PointersInfo(startedPosition = Offset.Zero, pointersDown = 1)
+                    }
                 )
                 .connection
 
@@ -1195,4 +1198,54 @@
         assertThat(transition).hasProgress(0f)
         assertThat(transition).hasOverscrollSpec()
     }
+
+    @Test
+    fun interceptingTransitionKeepsDistance() = runGestureTest {
+        var swipeDistance = 75f
+        layoutState.transitions = transitions {
+            from(SceneA, to = SceneB) { distance = UserActionDistance { _, _ -> swipeDistance } }
+        }
+
+        // Start transition.
+        val controller = onDragStarted(overSlop = -50f)
+        assertTransition(fromScene = SceneA, toScene = SceneB, progress = 50f / 75f)
+
+        // Intercept the transition and change the swipe distance. The original distance and
+        // progress should be the same.
+        swipeDistance = 50f
+        controller.onDragStopped(0f)
+        onDragStartedImmediately()
+        assertTransition(fromScene = SceneA, toScene = SceneB, progress = 50f / 75f)
+    }
+
+    @Test
+    fun requireFullDistanceSwipe() = runGestureTest {
+        mutableUserActionsA[Swipe.Up] = UserActionResult(SceneB, requiresFullDistanceSwipe = true)
+
+        val controller = onDragStarted(overSlop = up(fractionOfScreen = 0.9f))
+        assertTransition(fromScene = SceneA, toScene = SceneB, progress = 0.9f)
+
+        controller.onDragStopped(velocity = 0f)
+        advanceUntilIdle()
+        assertIdle(SceneA)
+
+        val otherController = onDragStarted(overSlop = up(fractionOfScreen = 1f))
+        assertTransition(fromScene = SceneA, toScene = SceneB, progress = 1f)
+        otherController.onDragStopped(velocity = 0f)
+        advanceUntilIdle()
+        assertIdle(SceneB)
+    }
+
+    @Test
+    fun interceptingTransitionReplacesCurrentTransition() = runGestureTest {
+        val controller = onDragStarted(overSlop = up(fractionOfScreen = 0.5f))
+        val transition = assertThat(layoutState.transitionState).isTransition()
+        controller.onDragStopped(velocity = 0f)
+
+        // Intercept the transition.
+        onDragStartedImmediately()
+        val newTransition = assertThat(layoutState.transitionState).isTransition()
+        assertThat(newTransition).isNotSameInstanceAs(transition)
+        assertThat(newTransition.replacedTransition).isSameInstanceAs(transition)
+    }
 }
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
index a18da73..1ae9992 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
@@ -731,7 +731,7 @@
                 onAnimatedFloat = { animatedFloat = it },
             )
 
-        val fooElement = rule.onNodeWithTag(TestElements.Foo.testTag, useUnmergedTree = true)
+        val fooElement = rule.onNodeWithTag(TestElements.Foo.testTag)
         fooElement.assertTopPositionInRootIsEqualTo(0.dp)
         val transition = assertThat(state.transitionState).isTransition()
         assertThat(transition).isNotNull()
@@ -811,7 +811,7 @@
         }
 
         assertThat(state.transitionState).isIdle()
-        val fooElement = rule.onNodeWithTag(TestElements.Foo.testTag, useUnmergedTree = true)
+        val fooElement = rule.onNodeWithTag(TestElements.Foo.testTag)
         fooElement.assertTopPositionInRootIsEqualTo(0.dp)
 
         // Swipe by half of verticalSwipeDistance.
@@ -839,6 +839,80 @@
     }
 
     @Test
+    fun elementTransitionDuringNestedScrollWith2Pointers() {
+        // The draggable touch slop, i.e. the min px distance a touch pointer must move before it is
+        // detected as a drag event.
+        var touchSlop = 0f
+        val translateY = 10.dp
+        val layoutWidth = 200.dp
+        val layoutHeight = 400.dp
+
+        val state =
+            rule.runOnUiThread {
+                MutableSceneTransitionLayoutState(
+                    initialScene = SceneA,
+                    transitions =
+                        transitions {
+                            from(SceneA, to = SceneB) {
+                                translate(TestElements.Foo, y = translateY)
+                            }
+                        },
+                )
+                    as MutableSceneTransitionLayoutStateImpl
+            }
+
+        rule.setContent {
+            touchSlop = LocalViewConfiguration.current.touchSlop
+            SceneTransitionLayout(
+                state = state,
+                modifier = Modifier.size(layoutWidth, layoutHeight)
+            ) {
+                scene(
+                    SceneA,
+                    userActions = mapOf(Swipe(SwipeDirection.Down, pointerCount = 2) to SceneB)
+                ) {
+                    Box(
+                        Modifier
+                            // Unconsumed scroll gesture will be intercepted by STL
+                            .verticalNestedScrollToScene()
+                            // A scrollable that does not consume the scroll gesture
+                            .scrollable(
+                                rememberScrollableState(consumeScrollDelta = { 0f }),
+                                Orientation.Vertical
+                            )
+                            .fillMaxSize()
+                    ) {
+                        Spacer(Modifier.element(TestElements.Foo).fillMaxSize())
+                    }
+                }
+                scene(SceneB) { Spacer(Modifier.fillMaxSize()) }
+            }
+        }
+
+        assertThat(state.transitionState).isIdle()
+        val fooElement = rule.onNodeWithTag(TestElements.Foo.testTag)
+        fooElement.assertTopPositionInRootIsEqualTo(0.dp)
+
+        // Swipe down with 2 pointers by half of verticalSwipeDistance.
+        rule.onRoot().performTouchInput {
+            val middleTop = Offset((layoutWidth / 2).toPx(), 0f)
+            repeat(2) { i -> down(pointerId = i, middleTop) }
+            repeat(2) { i ->
+                // Scroll 50%
+                moveBy(
+                    pointerId = i,
+                    delta = Offset(0f, touchSlop + layoutHeight.toPx() * 0.5f),
+                    delayMillis = 1_000,
+                )
+            }
+        }
+
+        val transition = assertThat(state.transitionState).isTransition()
+        assertThat(transition).hasProgress(0.5f)
+        fooElement.assertTopPositionInRootIsEqualTo(translateY * 0.5f)
+    }
+
+    @Test
     fun elementTransitionWithDistanceDuringOverscroll() {
         val layoutWidth = 200.dp
         val layoutHeight = 400.dp
@@ -858,7 +932,7 @@
                 onAnimatedFloat = { animatedFloat = it },
             )
 
-        val fooElement = rule.onNodeWithTag(TestElements.Foo.testTag, useUnmergedTree = true)
+        val fooElement = rule.onNodeWithTag(TestElements.Foo.testTag)
         fooElement.assertTopPositionInRootIsEqualTo(0.dp)
         assertThat(animatedFloat).isEqualTo(100f)
 
@@ -889,6 +963,63 @@
     }
 
     @Test
+    fun elementTransitionWithDistanceDuringOverscrollWithProgressConverter() {
+        val layoutWidth = 200.dp
+        val layoutHeight = 400.dp
+        var animatedFloat = 0f
+        val state =
+            setupOverscrollScenario(
+                layoutWidth = layoutWidth,
+                layoutHeight = layoutHeight,
+                sceneTransitions = {
+                    overscroll(SceneB, Orientation.Vertical) {
+                        // Overscroll progress will be halved
+                        progressConverter = { it / 2f }
+
+                        // On overscroll 100% -> Foo should translate by layoutHeight
+                        translate(TestElements.Foo, y = { absoluteDistance })
+                    }
+                },
+                firstScroll = 1f, // 100% scroll
+                animatedFloatRange = 0f..100f,
+                onAnimatedFloat = { animatedFloat = it },
+            )
+
+        val fooElement = rule.onNodeWithTag(TestElements.Foo.testTag)
+        fooElement.assertTopPositionInRootIsEqualTo(0.dp)
+        assertThat(animatedFloat).isEqualTo(100f)
+
+        rule.onRoot().performTouchInput {
+            // Scroll another 100%
+            moveBy(Offset(0f, layoutHeight.toPx()), delayMillis = 1_000)
+        }
+
+        val transition = assertThat(state.transitionState).isTransition()
+        assertThat(animatedFloat).isEqualTo(100f)
+
+        // Scroll 200% (100% scroll + 100% overscroll)
+        assertThat(transition).hasProgress(2f)
+        assertThat(transition).hasOverscrollSpec()
+
+        // Overscroll progress is halved, we are at 50% of the overscroll progress.
+        fooElement.assertTopPositionInRootIsEqualTo(layoutHeight * 0.5f)
+        assertThat(animatedFloat).isEqualTo(100f)
+
+        rule.onRoot().performTouchInput {
+            // Scroll another 100%
+            moveBy(Offset(0f, layoutHeight.toPx()), delayMillis = 1_000)
+        }
+
+        // Scroll 300% (100% scroll + 200% overscroll)
+        assertThat(transition).hasProgress(3f)
+        assertThat(transition).hasOverscrollSpec()
+
+        // Overscroll progress is halved, we are at 100% of the overscroll progress.
+        fooElement.assertTopPositionInRootIsEqualTo(layoutHeight)
+        assertThat(animatedFloat).isEqualTo(100f)
+    }
+
+    @Test
     fun elementTransitionWithDistanceDuringOverscrollBouncing() {
         val layoutWidth = 200.dp
         val layoutHeight = 400.dp
@@ -914,7 +1045,7 @@
                 onAnimatedFloat = { animatedFloat = it },
             )
 
-        val fooElement = rule.onNodeWithTag(TestElements.Foo.testTag, useUnmergedTree = true)
+        val fooElement = rule.onNodeWithTag(TestElements.Foo.testTag)
         fooElement.assertTopPositionInRootIsEqualTo(0.dp)
         assertThat(animatedFloat).isEqualTo(100f)
 
@@ -1937,4 +2068,119 @@
             )
             .isEqualTo(Element.SizeUnspecified)
     }
+
+    @Test
+    fun transparentElementIsNotImpactingInterruption() = runTest {
+        val state =
+            rule.runOnIdle {
+                MutableSceneTransitionLayoutStateImpl(
+                    SceneA,
+                    transitions {
+                        from(SceneA, to = SceneB) {
+                            // In A => B, Foo is not shared and first fades out from A then fades in
+                            // B.
+                            sharedElement(TestElements.Foo, enabled = false)
+                            fractionRange(end = 0.5f) { fade(TestElements.Foo.inScene(SceneA)) }
+                            fractionRange(start = 0.5f) { fade(TestElements.Foo.inScene(SceneB)) }
+                        }
+
+                        from(SceneB, to = SceneA) {
+                            // In B => A, Foo is shared.
+                            sharedElement(TestElements.Foo, enabled = true)
+                        }
+                    }
+                )
+            }
+
+        @Composable
+        fun SceneScope.Foo(modifier: Modifier = Modifier) {
+            Box(modifier.element(TestElements.Foo).size(10.dp))
+        }
+
+        rule.setContent {
+            SceneTransitionLayout(state) {
+                scene(SceneB) { Foo(Modifier.offset(40.dp, 60.dp)) }
+
+                // Define A after B so that Foo is placed in A during A <=> B.
+                scene(SceneA) { Foo() }
+            }
+        }
+
+        // Start A => B at 70%.
+        rule.runOnUiThread {
+            state.startTransition(
+                transition(
+                    from = SceneA,
+                    to = SceneB,
+                    progress = { 0.7f },
+                    onFinish = neverFinish(),
+                )
+            )
+        }
+
+        rule.onNode(isElement(TestElements.Foo, SceneA)).assertPositionInRootIsEqualTo(0.dp, 0.dp)
+        rule.onNode(isElement(TestElements.Foo, SceneB)).assertPositionInRootIsEqualTo(40.dp, 60.dp)
+
+        // Start B => A at 50% with interruptionProgress = 100%. Foo is placed in A and should still
+        // be at (40dp, 60dp) given that it was fully transparent in A before the interruption.
+        var interruptionProgress by mutableStateOf(1f)
+        rule.runOnUiThread {
+            state.startTransition(
+                transition(
+                    from = SceneB,
+                    to = SceneA,
+                    progress = { 0.5f },
+                    interruptionProgress = { interruptionProgress },
+                    onFinish = neverFinish(),
+                )
+            )
+        }
+
+        rule.onNode(isElement(TestElements.Foo, SceneA)).assertPositionInRootIsEqualTo(40.dp, 60.dp)
+        rule.onNode(isElement(TestElements.Foo, SceneB)).assertIsNotDisplayed()
+
+        // Set the interruption progress to 0%. Foo should be at (20dp, 30dp) given that B => is at
+        // 50%.
+        interruptionProgress = 0f
+        rule.onNode(isElement(TestElements.Foo, SceneA)).assertPositionInRootIsEqualTo(20.dp, 30.dp)
+        rule.onNode(isElement(TestElements.Foo, SceneB)).assertIsNotDisplayed()
+    }
+
+    @Test
+    fun replacedTransitionDoesNotTriggerInterruption() = runTest {
+        val state = rule.runOnIdle { MutableSceneTransitionLayoutStateImpl(SceneA) }
+
+        @Composable
+        fun SceneScope.Foo(modifier: Modifier = Modifier) {
+            Box(modifier.element(TestElements.Foo).size(10.dp))
+        }
+
+        rule.setContent {
+            SceneTransitionLayout(state) {
+                scene(SceneA) { Foo() }
+                scene(SceneB) { Foo(Modifier.offset(40.dp, 60.dp)) }
+            }
+        }
+
+        // Start A => B at 50%.
+        val aToB1 =
+            transition(from = SceneA, to = SceneB, progress = { 0.5f }, onFinish = neverFinish())
+        rule.runOnUiThread { state.startTransition(aToB1) }
+        rule.onNode(isElement(TestElements.Foo, SceneA)).assertIsNotDisplayed()
+        rule.onNode(isElement(TestElements.Foo, SceneB)).assertPositionInRootIsEqualTo(20.dp, 30.dp)
+
+        // Replace A => B by another A => B at 100%. Even with interruption progress at 100%, Foo
+        // should be at (40dp, 60dp) given that aToB1 was replaced by aToB2.
+        val aToB2 =
+            transition(
+                from = SceneA,
+                to = SceneB,
+                progress = { 1f },
+                interruptionProgress = { 1f },
+                replacedTransition = aToB1,
+            )
+        rule.runOnUiThread { state.startTransition(aToB2) }
+        rule.onNode(isElement(TestElements.Foo, SceneA)).assertIsNotDisplayed()
+        rule.onNode(isElement(TestElements.Foo, SceneB)).assertPositionInRootIsEqualTo(40.dp, 60.dp)
+    }
 }
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/InterruptionHandlerTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/InterruptionHandlerTest.kt
index 09d1a82..3552d3d 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/InterruptionHandlerTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/InterruptionHandlerTest.kt
@@ -131,10 +131,6 @@
         assertThat(state.currentTransitions)
             .comparingElementsUsing(FromToCurrentTriple)
             .containsExactly(
-                // Initial transition A to B. This transition will never be consumed by anyone given
-                // that it has the same (from, to) pair as the next transition.
-                Triple(SceneA, SceneB, SceneB),
-
                 // Initial transition reversed, B back to A.
                 Triple(SceneA, SceneB, SceneA),
 
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt
index 1a0740b..ecafb17 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/MultiPointerDraggableTest.kt
@@ -121,6 +121,82 @@
     }
 
     @Test
+    fun shouldNotStartDragEventsWith0PointersDown() {
+        val size = 200f
+        val middle = Offset(size / 2f, size / 2f)
+
+        var started = false
+        var dragged = false
+        var stopped = false
+        var consumedByDescendant = false
+
+        var touchSlop = 0f
+        rule.setContent {
+            touchSlop = LocalViewConfiguration.current.touchSlop
+            Box(
+                Modifier.size(with(LocalDensity.current) { Size(size, size).toDpSize() })
+                    .multiPointerDraggable(
+                        orientation = Orientation.Vertical,
+                        enabled = { true },
+                        // We want to start a drag gesture immediately
+                        startDragImmediately = { true },
+                        onDragStarted = { _, _, _ ->
+                            started = true
+                            object : DragController {
+                                override fun onDrag(delta: Float) {
+                                    dragged = true
+                                }
+
+                                override fun onStop(velocity: Float, canChangeScene: Boolean) {
+                                    stopped = true
+                                }
+                            }
+                        },
+                    )
+                    .pointerInput(Unit) {
+                        coroutineScope {
+                            awaitPointerEventScope {
+                                while (isActive) {
+                                    val change = awaitPointerEvent().changes.first()
+                                    if (consumedByDescendant) {
+                                        change.consume()
+                                    }
+                                }
+                            }
+                        }
+                    }
+            )
+        }
+
+        // The first part of the gesture is consumed by our descendant
+        consumedByDescendant = true
+        rule.onRoot().performTouchInput {
+            down(middle)
+            moveBy(Offset(0f, touchSlop))
+        }
+
+        // The events were consumed by our descendant, we should not start a drag gesture.
+        assertThat(started).isFalse()
+        assertThat(dragged).isFalse()
+        assertThat(stopped).isFalse()
+
+        // The next events could be consumed by us
+        consumedByDescendant = false
+        rule.onRoot().performTouchInput {
+            // The pointer is moved to a new position without reporting it
+            updatePointerBy(0, Offset(0f, touchSlop))
+
+            // The pointer report an "up" (0 pointers down) with a new position
+            up()
+        }
+
+        // The "up" event should not be used to start a drag gesture
+        assertThat(started).isFalse()
+        assertThat(dragged).isFalse()
+        assertThat(stopped).isFalse()
+    }
+
+    @Test
     fun handleDisappearingScrollableDuringAGesture() {
         val size = 200f
         val middle = Offset(size / 2f, size / 2f)
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
index de6f1cc..41bf630 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutStateTest.kt
@@ -314,7 +314,6 @@
                         }
                     },
             )
-                as MutableSceneTransitionLayoutStateImpl
 
         // Default transition from A to B.
         assertThat(state.setTargetScene(SceneB, coroutineScope = this)).isNotNull()
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
index a8dd572..1c8efb8 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/SceneTransitionLayoutTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.compose.animation.scene
 
+import androidx.activity.BackEventCompat
 import androidx.activity.ComponentActivity
 import androidx.compose.animation.core.FastOutSlowInEasing
 import androidx.compose.animation.core.LinearEasing
@@ -168,12 +169,47 @@
 
         assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
 
-        rule.activity.onBackPressed()
+        rule.runOnUiThread { rule.activity.onBackPressedDispatcher.onBackPressed() }
         rule.waitForIdle()
         assertThat(layoutState.transitionState).hasCurrentScene(SceneB)
     }
 
     @Test
+    fun testPredictiveBack() {
+        rule.setContent { TestContent() }
+
+        assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
+
+        // Start back.
+        val dispatcher = rule.activity.onBackPressedDispatcher
+        rule.runOnUiThread {
+            dispatcher.dispatchOnBackStarted(backEvent())
+            dispatcher.dispatchOnBackProgressed(backEvent(progress = 0.4f))
+        }
+
+        val transition = assertThat(layoutState.transitionState).isTransition()
+        assertThat(transition).hasFromScene(SceneA)
+        assertThat(transition).hasToScene(SceneB)
+        assertThat(transition).hasProgress(0.4f)
+
+        // Cancel it.
+        rule.runOnUiThread { dispatcher.dispatchOnBackCancelled() }
+        rule.waitForIdle()
+        assertThat(layoutState.transitionState).hasCurrentScene(SceneA)
+        assertThat(layoutState.transitionState).isIdle()
+
+        // Start again and commit it.
+        rule.runOnUiThread {
+            dispatcher.dispatchOnBackStarted(backEvent())
+            dispatcher.dispatchOnBackProgressed(backEvent(progress = 0.4f))
+            dispatcher.onBackPressed()
+        }
+        rule.waitForIdle()
+        assertThat(layoutState.transitionState).hasCurrentScene(SceneB)
+        assertThat(layoutState.transitionState).isIdle()
+    }
+
+    @Test
     fun testTransitionState() {
         rule.setContent { TestContent() }
         assertThat(layoutState.transitionState).isIdle()
@@ -524,4 +560,13 @@
         assertThat(keyInB).isEqualTo(SceneB)
         assertThat(keyInC).isEqualTo(SceneC)
     }
+
+    private fun backEvent(progress: Float = 0f): BackEventCompat {
+        return BackEventCompat(
+            touchX = 0f,
+            touchY = 0f,
+            progress = progress,
+            swipeEdge = BackEventCompat.EDGE_LEFT,
+        )
+    }
 }
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/Transition.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/Transition.kt
index 322b035..65f4f9e 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/Transition.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/Transition.kt
@@ -37,8 +37,11 @@
     bouncingScene: SceneKey? = null,
     orientation: Orientation = Orientation.Horizontal,
     onFinish: ((TransitionState.Transition) -> Job)? = null,
+    replacedTransition: TransitionState.Transition? = null,
 ): TransitionState.Transition {
-    return object : TransitionState.Transition(from, to), TransitionState.HasOverscrollProperties {
+    return object :
+        TransitionState.Transition(from, to, replacedTransition),
+        TransitionState.HasOverscrollProperties {
         override val currentScene: SceneKey
             get() = current()
 
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/modifiers/SizeMatcherTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/modifiers/SizeMatcherTest.kt
new file mode 100644
index 0000000..fa24966
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/modifiers/SizeMatcherTest.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.compose.animation.scene.modifiers
+
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.size
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.unit.DpSize
+import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.compose.test.assertSizeIsEqualTo
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class SizeMatcherTest {
+    @get:Rule val rule = createComposeRule()
+
+    @Test
+    fun sizeMatcher() {
+        val contentSize = DpSize(200.dp, 100.dp)
+        val sizeMatcher = SizeMatcher()
+        val backgroundTag = "background"
+
+        rule.setContent {
+            Box {
+                Box(Modifier.sizeMatcherSource(sizeMatcher).size(contentSize))
+                Box(Modifier.testTag(backgroundTag).sizeMatcherDestination(sizeMatcher))
+            }
+        }
+
+        rule.onNodeWithTag(backgroundTag).assertSizeIsEqualTo(contentSize.width, contentSize.height)
+    }
+}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
index 20f87a0..9e0af97 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
@@ -65,7 +65,7 @@
             throw IllegalArgumentException("$id is unsupported by $TAG")
         }
 
-        // TODO: Update placeholder to actual resource
+        // TODO(b/352049256): Update placeholder to actual resource
         return resources.getDrawable(R.drawable.clock_default_thumbnail, null)
     }
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/notifications/data/repository/NotificationSettingsRepository.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/notifications/data/repository/NotificationSettingsRepository.kt
index e39d7ed..9e857deb 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/notifications/data/repository/NotificationSettingsRepository.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/notifications/data/repository/NotificationSettingsRepository.kt
@@ -21,16 +21,16 @@
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.withContext
 
 /** Provides access to state related to notification settings. */
 class NotificationSettingsRepository(
-    scope: CoroutineScope,
+    private val scope: CoroutineScope,
     private val backgroundDispatcher: CoroutineDispatcher,
     private val secureSettingsRepository: SecureSettingsRepository,
 ) {
@@ -41,16 +41,15 @@
             .distinctUntilChanged()
 
     /** The current state of the notification setting. */
-    val isShowNotificationsOnLockScreenEnabled: StateFlow<Boolean> =
+    suspend fun isShowNotificationsOnLockScreenEnabled(): StateFlow<Boolean> =
         secureSettingsRepository
             .intSetting(
                 name = Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
             )
             .map { it == 1 }
+            .flowOn(backgroundDispatcher)
             .stateIn(
                 scope = scope,
-                started = SharingStarted.WhileSubscribed(),
-                initialValue = false,
             )
 
     suspend fun setShowNotificationsOnLockscreenEnabled(enabled: Boolean) {
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/notifications/domain/interactor/NotificationSettingsInteractor.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/notifications/domain/interactor/NotificationSettingsInteractor.kt
index 04e8090..b4105bd 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/notifications/domain/interactor/NotificationSettingsInteractor.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/notifications/domain/interactor/NotificationSettingsInteractor.kt
@@ -26,8 +26,8 @@
     val isNotificationHistoryEnabled = repository.isNotificationHistoryEnabled
 
     /** Should notifications be visible on the lockscreen? */
-    val isShowNotificationsOnLockScreenEnabled: StateFlow<Boolean> =
-        repository.isShowNotificationsOnLockScreenEnabled
+    suspend fun isShowNotificationsOnLockScreenEnabled(): StateFlow<Boolean> =
+        repository.isShowNotificationsOnLockScreenEnabled()
 
     suspend fun setShowNotificationsOnLockscreenEnabled(enabled: Boolean) {
         repository.setShowNotificationsOnLockscreenEnabled(enabled)
@@ -35,7 +35,7 @@
 
     /** Toggles the setting to show or hide notifications on the lock screen. */
     suspend fun toggleShowNotificationsOnLockscreenEnabled() {
-        val current = repository.isShowNotificationsOnLockScreenEnabled.value
+        val current = repository.isShowNotificationsOnLockScreenEnabled().value
         repository.setShowNotificationsOnLockscreenEnabled(!current)
     }
 }
diff --git a/packages/SystemUI/lint-baseline.xml b/packages/SystemUI/lint-baseline.xml
index 4def93f..525839d 100644
--- a/packages/SystemUI/lint-baseline.xml
+++ b/packages/SystemUI/lint-baseline.xml
@@ -128,7 +128,7 @@
         errorLine1="        mUserTracker.addCallback(mUserChangedCallback, mContext.getMainExecutor());"
         errorLine2="                                                                ~~~~~~~~~~~~~~~">
         <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java"
+            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java"
             line="807"
             column="65"/>
     </issue>
@@ -1646,7 +1646,7 @@
         errorLine1="        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);"
         errorLine2="                                               ~~~~~~~~~~~~~~~~">
         <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java"
+            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java"
             line="177"
             column="48"/>
     </issue>
@@ -2086,7 +2086,7 @@
         errorLine1="            WindowManager wm = getContext().getSystemService(WindowManager.class);"
         errorLine2="                                            ~~~~~~~~~~~~~~~~">
         <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java"
+            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java"
             line="729"
             column="45"/>
     </issue>
@@ -2097,7 +2097,7 @@
         errorLine1="        WindowManager wm = getContext().getSystemService(WindowManager.class);"
         errorLine2="                                        ~~~~~~~~~~~~~~~~">
         <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java"
+            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java"
             line="830"
             column="41"/>
     </issue>
@@ -4049,7 +4049,7 @@
         errorLine1="        pw.println(String.format(&quot;      mCurrentView: id=%s (%dx%d) %s %f&quot;,"
         errorLine2="                   ^">
         <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java"
+            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java"
             line="1128"
             column="20"/>
     </issue>
@@ -4060,7 +4060,7 @@
         errorLine1="        pw.println(String.format(&quot;      disabled=0x%08x vertical=%s darkIntensity=%.2f&quot;,"
         errorLine2="                   ^">
         <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java"
+            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java"
             line="1134"
             column="20"/>
     </issue>
@@ -4668,7 +4668,7 @@
         errorLine1="                    500).show();"
         errorLine2="                    ~~~">
         <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java"
+            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java"
             line="1894"
             column="21"/>
     </issue>
@@ -8386,7 +8386,7 @@
         errorLine1="        mUiEventLogger.log(KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_TAP);"
         errorLine2="                                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java"
+            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java"
             line="1500"
             column="60"/>
     </issue>
@@ -23055,7 +23055,7 @@
         errorLine1="            mBarTransitions.setBackgroundFrame(new Rect(0, frameHeight - height, w, h));"
         errorLine2="                                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java"
+            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java"
             line="1001"
             column="48"/>
     </issue>
@@ -25002,7 +25002,7 @@
         errorLine1="        mAudioManager.playSoundEffect(soundConstant, ActivityManager.getCurrentUser());"
         errorLine2="                                                                     ~~~~~~~~~~~~~~">
         <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java"
+            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java"
             line="373"
             column="70"/>
     </issue>
@@ -25222,7 +25222,7 @@
         errorLine1="        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);"
         errorLine2="                                                                         ~~~~~~~~~">
         <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java"
+            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonDrawable.java"
             line="329"
             column="74"/>
     </issue>
@@ -25233,7 +25233,7 @@
         errorLine1="        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);"
         errorLine2="                                                                         ~~~~~~~~~">
         <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java"
+            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonDrawable.java"
             line="357"
             column="74"/>
     </issue>
@@ -25827,7 +25827,7 @@
         errorLine1="        new AsyncTask&lt;Icon, Void, Drawable>() {"
         errorLine2="        ^">
         <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java"
+            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java"
             line="207"
             column="9"/>
     </issue>
@@ -27088,17 +27088,6 @@
 
     <issue
         id="UselessParent"
-        message="This `FrameLayout` layout or its `LinearLayout` parent is unnecessary"
-        errorLine1="    &lt;FrameLayout"
-        errorLine2="     ~~~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/res/layout/media_output_list_item.xml"
-            line="24"
-            column="6"/>
-    </issue>
-
-    <issue
-        id="UselessParent"
         message="This `LinearLayout` layout or its `FrameLayout` parent is possibly unnecessary; transfer the `background` attribute to the other view"
         errorLine1="    &lt;LinearLayout"
         errorLine2="     ~~~~~~~~~~~~">
@@ -29314,7 +29303,7 @@
         errorLine1="    public boolean onTouchEvent(MotionEvent ev) {"
         errorLine2="                   ~~~~~~~~~~~~">
         <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java"
+            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java"
             line="267"
             column="20"/>
     </issue>
@@ -29589,7 +29578,7 @@
         errorLine1="        mView.setOnTouchListener(this::onNavigationTouch);"
         errorLine2="        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
         <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java"
+            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java"
             line="782"
             column="9"/>
     </issue>
@@ -29600,7 +29589,7 @@
         errorLine1="    public boolean onTouchEvent(MotionEvent event) {"
         errorLine2="                   ~~~~~~~~~~~~">
         <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java"
+            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java"
             line="383"
             column="20"/>
     </issue>
@@ -29611,7 +29600,7 @@
         errorLine1="    public boolean onTouchEvent(MotionEvent event) {"
         errorLine2="                   ~~~~~~~~~~~~">
         <location
-            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java"
+            file="frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrame.java"
             line="207"
             column="20"/>
     </issue>
@@ -30587,17 +30576,6 @@
     <issue
         id="ContentDescription"
         message="Missing `contentDescription` attribute on image"
-        errorLine1="            &lt;ImageView"
-        errorLine2="             ~~~~~~~~~">
-        <location
-            file="frameworks/base/packages/SystemUI/res/layout/media_output_list_item.xml"
-            line="54"
-            column="14"/>
-    </issue>
-
-    <issue
-        id="ContentDescription"
-        message="Missing `contentDescription` attribute on image"
         errorLine1="    &lt;ImageView"
         errorLine2="     ~~~~~~~~~">
         <location
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandlerTest.java
index 630bcd6..7ebc224 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandlerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandlerTest.java
@@ -21,6 +21,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
@@ -49,6 +50,7 @@
 import com.android.systemui.ambient.touch.scrim.ScrimController;
 import com.android.systemui.ambient.touch.scrim.ScrimManager;
 import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.settings.FakeUserTracker;
 import com.android.systemui.shade.ShadeExpansionChangeEvent;
 import com.android.systemui.shared.system.InputChannelCompat;
@@ -113,6 +115,9 @@
     LockPatternUtils mLockPatternUtils;
 
     @Mock
+    ActivityStarter mActivityStarter;
+
+    @Mock
     Region mRegion;
 
     @Captor
@@ -148,7 +153,8 @@
                 mFlingAnimationUtilsClosing,
                 TOUCH_REGION,
                 MIN_BOUNCER_HEIGHT,
-                mUiEventLogger);
+                mUiEventLogger,
+                mActivityStarter);
 
         when(mScrimManager.getCurrentController()).thenReturn(mScrimController);
         when(mValueAnimatorCreator.create(anyFloat(), anyFloat())).thenReturn(mValueAnimator);
@@ -397,7 +403,12 @@
                 .isTrue();
         // We should not expand since the keyguard is not secure
         verify(mScrimController, never()).expand(any());
-        // Since we are swiping up, we should wake from dreams.
+
+        // Since we are swiping up, we should dismiss the keyguard and wake from dreams.
+        ArgumentCaptor<Runnable> dismissKeyguardRunnable = ArgumentCaptor.forClass(Runnable.class);
+        verify(mActivityStarter).executeRunnableDismissingKeyguard(
+                dismissKeyguardRunnable.capture(), isNull(), eq(true), eq(true), eq(false));
+        dismissKeyguardRunnable.getValue().run();
         verify(mCentralSurfaces).awakenDreams();
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.java
deleted file mode 100644
index 07d8890..0000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.ambient.touch;
-
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.DreamManager;
-import android.platform.test.annotations.DisableFlags;
-import android.platform.test.annotations.EnableFlags;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.Flags;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.shade.ShadeViewController;
-import com.android.systemui.shared.system.InputChannelCompat;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Optional;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class ShadeTouchHandlerTest extends SysuiTestCase {
-    @Mock
-    CentralSurfaces mCentralSurfaces;
-
-    @Mock
-    ShadeViewController mShadeViewController;
-
-    @Mock
-    DreamManager mDreamManager;
-
-    @Mock
-    TouchHandler.TouchSession mTouchSession;
-
-    ShadeTouchHandler mTouchHandler;
-
-    @Captor
-    ArgumentCaptor<GestureDetector.OnGestureListener> mGestureListenerCaptor;
-    @Captor
-    ArgumentCaptor<InputChannelCompat.InputEventListener> mInputListenerCaptor;
-
-    private static final int TOUCH_HEIGHT = 20;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-
-        mTouchHandler = new ShadeTouchHandler(Optional.of(mCentralSurfaces), mShadeViewController,
-                mDreamManager, TOUCH_HEIGHT);
-    }
-
-    // Verifies that a swipe down in the gesture region is captured by the shade touch handler.
-    @Test
-    public void testSwipeDown_captured() {
-        final boolean captured = swipe(Direction.DOWN);
-
-        assertThat(captured).isTrue();
-    }
-
-    // Verifies that a swipe in the upward direction is not captured.
-    @Test
-    public void testSwipeUp_notCaptured() {
-        final boolean captured = swipe(Direction.UP);
-
-        // Motion events not captured as the swipe is going in the wrong direction.
-        assertThat(captured).isFalse();
-    }
-
-    // Verifies that a swipe down forwards captured touches to central surfaces for handling.
-    @Test
-    @EnableFlags(Flags.FLAG_COMMUNAL_HUB)
-    public void testSwipeDown_communalEnabled_sentToCentralSurfaces() {
-        swipe(Direction.DOWN);
-
-        // Both motion events are sent for central surfaces to process.
-        verify(mCentralSurfaces, times(2)).handleExternalShadeWindowTouch(any());
-    }
-
-    // Verifies that a swipe down forwards captured touches to the shade view for handling.
-    @Test
-    @DisableFlags(Flags.FLAG_COMMUNAL_HUB)
-    public void testSwipeDown_communalDisabled_sentToShadeView() {
-        swipe(Direction.DOWN);
-
-        // Both motion events are sent for the shade view to process.
-        verify(mShadeViewController, times(2)).handleExternalTouch(any());
-    }
-
-    // Verifies that a swipe down while dreaming forwards captured touches to the shade view for
-    // handling.
-    @Test
-    public void testSwipeDown_dreaming_sentToShadeView() {
-        when(mDreamManager.isDreaming()).thenReturn(true);
-
-        swipe(Direction.DOWN);
-
-        // Both motion events are sent for the shade view to process.
-        verify(mShadeViewController, times(2)).handleExternalTouch(any());
-    }
-
-    // Verifies that a swipe up is not forwarded to central surfaces.
-    @Test
-    @EnableFlags(Flags.FLAG_COMMUNAL_HUB)
-    public void testSwipeUp_communalEnabled_touchesNotSent() {
-        swipe(Direction.UP);
-
-        // Motion events are not sent for central surfaces to process as the swipe is going in the
-        // wrong direction.
-        verify(mCentralSurfaces, never()).handleExternalShadeWindowTouch(any());
-    }
-
-    // Verifies that a swipe up is not forwarded to the shade view.
-    @Test
-    @DisableFlags(Flags.FLAG_COMMUNAL_HUB)
-    public void testSwipeUp_communalDisabled_touchesNotSent() {
-        swipe(Direction.UP);
-
-        // Motion events are not sent for the shade view to process as the swipe is going in the
-        // wrong direction.
-        verify(mShadeViewController, never()).handleExternalTouch(any());
-    }
-
-    /**
-     * Simulates a swipe in the given direction and returns true if the touch was intercepted by the
-     * touch handler's gesture listener.
-     * <p>
-     * Swipe down starts from a Y coordinate of 0 and goes downward. Swipe up starts from the edge
-     * of the gesture region, {@link #TOUCH_HEIGHT}, and goes upward to 0.
-     */
-    private boolean swipe(Direction direction) {
-        Mockito.clearInvocations(mTouchSession);
-        mTouchHandler.onSessionStart(mTouchSession);
-
-        verify(mTouchSession).registerGestureListener(mGestureListenerCaptor.capture());
-        verify(mTouchSession).registerInputListener(mInputListenerCaptor.capture());
-
-        final float startY = direction == Direction.UP ? TOUCH_HEIGHT : 0;
-        final float endY = direction == Direction.UP ? 0 : TOUCH_HEIGHT;
-
-        // Send touches to the input and gesture listener.
-        final MotionEvent event1 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, startY, 0);
-        final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, endY, 0);
-        mInputListenerCaptor.getValue().onInputEvent(event1);
-        mInputListenerCaptor.getValue().onInputEvent(event2);
-        final boolean captured = mGestureListenerCaptor.getValue().onScroll(event1, event2, 0,
-                startY - endY);
-
-        return captured;
-    }
-
-    private enum Direction {
-        DOWN, UP,
-    }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.kt
new file mode 100644
index 0000000..4314676
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.kt
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.ambient.touch
+
+import android.app.DreamManager
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.view.GestureDetector
+import android.view.MotionEvent
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.Flags
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.ambient.touch.TouchHandler.TouchSession
+import com.android.systemui.shade.ShadeViewController
+import com.android.systemui.shared.system.InputChannelCompat
+import com.android.systemui.statusbar.phone.CentralSurfaces
+import com.google.common.truth.Truth
+import java.util.Optional
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ShadeTouchHandlerTest : SysuiTestCase() {
+    private var mCentralSurfaces = mock<CentralSurfaces>()
+    private var mShadeViewController = mock<ShadeViewController>()
+    private var mDreamManager = mock<DreamManager>()
+    private var mTouchSession = mock<TouchSession>()
+
+    private lateinit var mTouchHandler: ShadeTouchHandler
+
+    private var mGestureListenerCaptor = argumentCaptor<GestureDetector.OnGestureListener>()
+    private var mInputListenerCaptor = argumentCaptor<InputChannelCompat.InputEventListener>()
+
+    @Before
+    fun setup() {
+        mTouchHandler =
+            ShadeTouchHandler(
+                Optional.of(mCentralSurfaces),
+                mShadeViewController,
+                mDreamManager,
+                TOUCH_HEIGHT
+            )
+    }
+
+    // Verifies that a swipe down in the gesture region is captured by the shade touch handler.
+    @Test
+    fun testSwipeDown_captured() {
+        val captured = swipe(Direction.DOWN)
+        Truth.assertThat(captured).isTrue()
+    }
+
+    // Verifies that a swipe in the upward direction is not captured.
+    @Test
+    fun testSwipeUp_notCaptured() {
+        val captured = swipe(Direction.UP)
+
+        // Motion events not captured as the swipe is going in the wrong direction.
+        Truth.assertThat(captured).isFalse()
+    }
+
+    // Verifies that a swipe down forwards captured touches to central surfaces for handling.
+    @Test
+    @EnableFlags(Flags.FLAG_COMMUNAL_HUB)
+    fun testSwipeDown_communalEnabled_sentToCentralSurfaces() {
+        swipe(Direction.DOWN)
+
+        // Both motion events are sent for central surfaces to process.
+        verify(mCentralSurfaces, times(2)).handleExternalShadeWindowTouch(any())
+    }
+
+    // Verifies that a swipe down forwards captured touches to the shade view for handling.
+    @Test
+    @DisableFlags(Flags.FLAG_COMMUNAL_HUB)
+    fun testSwipeDown_communalDisabled_sentToShadeView() {
+        swipe(Direction.DOWN)
+
+        // Both motion events are sent for the shade view to process.
+        verify(mShadeViewController, times(2)).handleExternalTouch(any())
+    }
+
+    // Verifies that a swipe down while dreaming forwards captured touches to the shade view for
+    // handling.
+    @Test
+    fun testSwipeDown_dreaming_sentToShadeView() {
+        whenever(mDreamManager.isDreaming).thenReturn(true)
+        swipe(Direction.DOWN)
+
+        // Both motion events are sent for the shade view to process.
+        verify(mShadeViewController, times(2)).handleExternalTouch(any())
+    }
+
+    // Verifies that a swipe up is not forwarded to central surfaces.
+    @Test
+    @EnableFlags(Flags.FLAG_COMMUNAL_HUB)
+    fun testSwipeUp_communalEnabled_touchesNotSent() {
+        swipe(Direction.UP)
+
+        // Motion events are not sent for central surfaces to process as the swipe is going in the
+        // wrong direction.
+        verify(mCentralSurfaces, never()).handleExternalShadeWindowTouch(any())
+    }
+
+    // Verifies that a swipe up is not forwarded to the shade view.
+    @Test
+    @DisableFlags(Flags.FLAG_COMMUNAL_HUB)
+    fun testSwipeUp_communalDisabled_touchesNotSent() {
+        swipe(Direction.UP)
+
+        // Motion events are not sent for the shade view to process as the swipe is going in the
+        // wrong direction.
+        verify(mShadeViewController, never()).handleExternalTouch(any())
+    }
+
+    /**
+     * Simulates a swipe in the given direction and returns true if the touch was intercepted by the
+     * touch handler's gesture listener.
+     *
+     * Swipe down starts from a Y coordinate of 0 and goes downward. Swipe up starts from the edge
+     * of the gesture region, [.TOUCH_HEIGHT], and goes upward to 0.
+     */
+    private fun swipe(direction: Direction): Boolean {
+        clearInvocations(mTouchSession)
+        mTouchHandler.onSessionStart(mTouchSession)
+        verify(mTouchSession).registerGestureListener(mGestureListenerCaptor.capture())
+        verify(mTouchSession).registerInputListener(mInputListenerCaptor.capture())
+        val startY = (if (direction == Direction.UP) TOUCH_HEIGHT else 0).toFloat()
+        val endY = (if (direction == Direction.UP) 0 else TOUCH_HEIGHT).toFloat()
+
+        // Send touches to the input and gesture listener.
+        val event1 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0f, startY, 0)
+        val event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0f, endY, 0)
+        mInputListenerCaptor.lastValue.onInputEvent(event1)
+        mInputListenerCaptor.lastValue.onInputEvent(event2)
+        return mGestureListenerCaptor.lastValue.onScroll(event1, event2, 0f, startY - endY)
+    }
+
+    private enum class Direction {
+        DOWN,
+        UP
+    }
+
+    companion object {
+        private const val TOUCH_HEIGHT = 20
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
index 60b48f2..242e822 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
@@ -324,7 +324,6 @@
     fun showUdfpsOverlay_awake() =
         testScope.runTest {
             withReason(REASON_AUTH_KEYGUARD) {
-                mSetFlagsRule.enableFlags(Flags.FLAG_UDFPS_VIEW_PERFORMANCE)
                 powerRepository.updateWakefulness(
                     rawState = WakefulnessState.AWAKE,
                     lastWakeReason = WakeSleepReason.POWER_BUTTON,
@@ -341,7 +340,6 @@
     fun showUdfpsOverlay_whileGoingToSleep() =
         testScope.runTest {
             withReasonSuspend(REASON_AUTH_KEYGUARD) {
-                mSetFlagsRule.enableFlags(Flags.FLAG_UDFPS_VIEW_PERFORMANCE)
                 keyguardTransitionRepository.sendTransitionSteps(
                     from = KeyguardState.OFF,
                     to = KeyguardState.GONE,
@@ -370,7 +368,6 @@
     fun showUdfpsOverlay_whileAsleep() =
         testScope.runTest {
             withReasonSuspend(REASON_AUTH_KEYGUARD) {
-                mSetFlagsRule.enableFlags(Flags.FLAG_UDFPS_VIEW_PERFORMANCE)
                 keyguardTransitionRepository.sendTransitionSteps(
                     from = KeyguardState.OFF,
                     to = KeyguardState.GONE,
@@ -399,7 +396,6 @@
     fun neverRemoveViewThatHasNotBeenAdded() =
         testScope.runTest {
             withReasonSuspend(REASON_AUTH_KEYGUARD) {
-                mSetFlagsRule.enableFlags(Flags.FLAG_UDFPS_VIEW_PERFORMANCE)
                 controllerOverlay.show(udfpsController, overlayParams)
                 val view = controllerOverlay.getTouchOverlay()
                 view?.let {
@@ -414,7 +410,6 @@
     fun showUdfpsOverlay_afterFinishedTransitioningToAOD() =
         testScope.runTest {
             withReasonSuspend(REASON_AUTH_KEYGUARD) {
-                mSetFlagsRule.enableFlags(Flags.FLAG_UDFPS_VIEW_PERFORMANCE)
                 keyguardTransitionRepository.sendTransitionSteps(
                     from = KeyguardState.OFF,
                     to = KeyguardState.GONE,
@@ -542,7 +537,6 @@
     fun addViewPending_layoutIsNotUpdated() =
         testScope.runTest {
             withReasonSuspend(REASON_AUTH_KEYGUARD) {
-                mSetFlagsRule.enableFlags(Flags.FLAG_UDFPS_VIEW_PERFORMANCE)
                 mSetFlagsRule.enableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
 
                 // GIVEN going to sleep
@@ -580,7 +574,6 @@
     fun updateOverlayParams_viewLayoutUpdated() =
         testScope.runTest {
             withReasonSuspend(REASON_AUTH_KEYGUARD) {
-                mSetFlagsRule.enableFlags(Flags.FLAG_UDFPS_VIEW_PERFORMANCE)
                 powerRepository.updateWakefulness(
                     rawState = WakefulnessState.AWAKE,
                     lastWakeReason = WakeSleepReason.POWER_BUTTON,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index fa79ea0..54e0725 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -1284,6 +1284,41 @@
     }
 
     @Test
+    public void onAodDownAndDownTouchReceived() throws RemoteException {
+        final NormalizedTouchData touchData = new NormalizedTouchData(0, 0f, 0f, 0f, 0f, 0f, 0L,
+                0L);
+        final TouchProcessorResult processorResultDown =
+                new TouchProcessorResult.ProcessedTouch(InteractionEvent.DOWN,
+                        -1 /* pointerId */, touchData);
+
+        mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
+                BiometricRequestConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
+        mFgExecutor.runAllReady();
+
+        verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
+
+        // WHEN fingerprint is requested because of AOD interrupt
+        // GIVEN there's been an AoD interrupt
+        when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
+        mScreenObserver.onScreenTurnedOn();
+        mUdfpsController.onAodInterrupt(0, 0, 0, 0);
+        mFgExecutor.runAllReady();
+
+        // and an ACTION_DOWN is received and touch is within sensor
+        when(mSinglePointerTouchProcessor.processTouch(any(), anyInt(), any())).thenReturn(
+                processorResultDown);
+        MotionEvent firstDownEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0);
+        mTouchListenerCaptor.getValue().onTouch(mUdfpsView, firstDownEvent);
+        mBiometricExecutor.runAllReady();
+        firstDownEvent.recycle();
+
+        // THEN the touch is only processed once
+        verify(mFingerprintManager).onPointerDown(anyLong(), anyInt(), anyInt(),
+                anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyFloat(), anyLong(), anyLong(),
+                anyBoolean());
+    }
+
+    @Test
     public void onTouch_pilferPointerWhenAltBouncerShowing()
             throws RemoteException {
         final Pair<TouchProcessorResult, TouchProcessorResult> touchProcessorResult =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt
index 3035481..68cfa28 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt
@@ -29,7 +29,6 @@
 import com.android.systemui.bouncer.data.repository.keyguardBouncerRepository
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
-import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor
 import com.android.systemui.flags.DisableSceneContainer
 import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
@@ -223,23 +222,14 @@
     }
 
     private fun givenAlternateBouncerSupported() {
-        if (DeviceEntryUdfpsRefactor.isEnabled) {
-            kosmos.fingerprintPropertyRepository.supportsUdfps()
-        } else {
-            kosmos.keyguardBouncerRepository.setAlternateBouncerUIAvailable(true)
-        }
+        kosmos.givenAlternateBouncerSupported()
     }
 
     private fun givenCanShowAlternateBouncer() {
-        givenAlternateBouncerSupported()
-        kosmos.keyguardBouncerRepository.setPrimaryShow(false)
-        kosmos.biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
-        kosmos.biometricSettingsRepository.setIsFingerprintAuthCurrentlyAllowed(true)
-        whenever(kosmos.keyguardUpdateMonitor.isFingerprintLockedOut).thenReturn(false)
-        whenever(kosmos.keyguardStateController.isUnlocked).thenReturn(false)
+        kosmos.givenCanShowAlternateBouncer()
     }
 
     private fun givenCannotShowAlternateBouncer() {
-        kosmos.biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
+        kosmos.givenCannotShowAlternateBouncer()
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
index a5acf72..ccddc9c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerViewModelTest.kt
@@ -38,7 +38,7 @@
 import com.android.systemui.flags.Flags
 import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.scene.domain.interactor.sceneContainerStartable
+import com.android.systemui.scene.domain.startable.sceneContainerStartable
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.fakeSceneDataSource
 import com.android.systemui.testKosmos
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt
index fe683e07..dcc9c7a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/CommunalDreamStartableTest.kt
@@ -47,6 +47,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@EnableFlags(Flags.FLAG_COMMUNAL_HUB)
 @RunWith(AndroidJUnit4::class)
 class CommunalDreamStartableTest : SysuiTestCase() {
     private val kosmos = testKosmos()
@@ -76,7 +77,7 @@
         testScope.runTest {
             keyguardRepository.setDreaming(false)
             powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON)
-            whenever(dreamManager.canStartDreaming(/* isScreenOn = */ true)).thenReturn(true)
+            whenever(dreamManager.canStartDreaming(/* isScreenOn= */ true)).thenReturn(true)
             runCurrent()
 
             verify(dreamManager, never()).startDream()
@@ -92,7 +93,7 @@
         testScope.runTest {
             keyguardRepository.setDreaming(false)
             powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON)
-            whenever(dreamManager.canStartDreaming(/* isScreenOn = */ true)).thenReturn(true)
+            whenever(dreamManager.canStartDreaming(/* isScreenOn= */ true)).thenReturn(true)
             runCurrent()
 
             verify(dreamManager, never()).startDream()
@@ -118,7 +119,7 @@
             keyguardRepository.setDreaming(false)
             powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON)
             // Not eligible to dream
-            whenever(dreamManager.canStartDreaming(/* isScreenOn = */ true)).thenReturn(false)
+            whenever(dreamManager.canStartDreaming(/* isScreenOn= */ true)).thenReturn(false)
             transition(from = KeyguardState.DREAMING, to = KeyguardState.GLANCEABLE_HUB)
 
             verify(dreamManager, never()).startDream()
@@ -129,7 +130,7 @@
         testScope.runTest {
             keyguardRepository.setDreaming(true)
             powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON)
-            whenever(dreamManager.canStartDreaming(/* isScreenOn = */ true)).thenReturn(true)
+            whenever(dreamManager.canStartDreaming(/* isScreenOn= */ true)).thenReturn(true)
             transition(from = KeyguardState.DREAMING, to = KeyguardState.GLANCEABLE_HUB)
 
             verify(dreamManager, never()).startDream()
@@ -140,7 +141,7 @@
         testScope.runTest {
             keyguardRepository.setDreaming(true)
             powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON)
-            whenever(dreamManager.canStartDreaming(/* isScreenOn = */ true)).thenReturn(true)
+            whenever(dreamManager.canStartDreaming(/* isScreenOn= */ true)).thenReturn(true)
 
             // Verify we do not trigger dreaming for any other state besides glanceable hub
             for (state in KeyguardState.entries) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalPrefsRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalPrefsRepositoryImplTest.kt
index 5e120b5..a8bdc7c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalPrefsRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalPrefsRepositoryImplTest.kt
@@ -18,8 +18,8 @@
 
 import android.content.Context
 import android.content.Intent
-import android.content.SharedPreferences
 import android.content.pm.UserInfo
+import android.content.pm.UserInfo.FLAG_MAIN
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -30,108 +30,87 @@
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.log.logcatLogBuffer
-import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.settings.UserFileManager
+import com.android.systemui.settings.fakeUserFileManager
 import com.android.systemui.testKosmos
-import com.android.systemui.user.data.repository.FakeUserRepository
-import com.android.systemui.user.data.repository.fakeUserRepository
-import com.android.systemui.util.FakeSharedPreferences
 import com.google.common.truth.Truth.assertThat
-import java.io.File
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito
 import org.mockito.Mockito.atLeastOnce
 import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.spy
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class CommunalPrefsRepositoryImplTest : SysuiTestCase() {
-    @Mock private lateinit var tableLogBuffer: TableLogBuffer
-
-    private lateinit var underTest: CommunalPrefsRepositoryImpl
-
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
 
-    private lateinit var userRepository: FakeUserRepository
-    private lateinit var userFileManager: UserFileManager
+    private val userFileManager: UserFileManager = spy(kosmos.fakeUserFileManager)
 
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-
-        userRepository = kosmos.fakeUserRepository
-        userRepository.setUserInfos(USER_INFOS)
-
-        userFileManager =
-            FakeUserFileManager(
-                mapOf(
-                    USER_INFOS[0].id to FakeSharedPreferences(),
-                    USER_INFOS[1].id to FakeSharedPreferences()
-                )
-            )
+    private val underTest: CommunalPrefsRepositoryImpl by lazy {
+        CommunalPrefsRepositoryImpl(
+            kosmos.testDispatcher,
+            userFileManager,
+            kosmos.broadcastDispatcher,
+            logcatLogBuffer("CommunalPrefsRepositoryImplTest"),
+        )
     }
 
     @Test
     fun isCtaDismissedValue_byDefault_isFalse() =
         testScope.runTest {
-            underTest = createCommunalPrefsRepositoryImpl(userFileManager)
-            val isCtaDismissed by collectLastValue(underTest.isCtaDismissed)
+            val isCtaDismissed by collectLastValue(underTest.isCtaDismissed(MAIN_USER))
             assertThat(isCtaDismissed).isFalse()
         }
 
     @Test
     fun isCtaDismissedValue_onSet_isTrue() =
         testScope.runTest {
-            underTest = createCommunalPrefsRepositoryImpl(userFileManager)
-            val isCtaDismissed by collectLastValue(underTest.isCtaDismissed)
+            val isCtaDismissed by collectLastValue(underTest.isCtaDismissed(MAIN_USER))
 
-            underTest.setCtaDismissedForCurrentUser()
+            underTest.setCtaDismissed(MAIN_USER)
             assertThat(isCtaDismissed).isTrue()
         }
 
     @Test
-    fun isCtaDismissedValue_whenSwitchUser() =
+    fun isCtaDismissedValue_onSetForDifferentUser_isStillFalse() =
         testScope.runTest {
-            underTest = createCommunalPrefsRepositoryImpl(userFileManager)
-            val isCtaDismissed by collectLastValue(underTest.isCtaDismissed)
-            underTest.setCtaDismissedForCurrentUser()
+            val isCtaDismissed by collectLastValue(underTest.isCtaDismissed(MAIN_USER))
 
-            // dismissed true for primary user
-            assertThat(isCtaDismissed).isTrue()
-
-            // switch to secondary user
-            userRepository.setSelectedUserInfo(USER_INFOS[1])
-
-            // dismissed is false for secondary user
+            underTest.setCtaDismissed(SECONDARY_USER)
             assertThat(isCtaDismissed).isFalse()
+        }
 
-            // switch back to primary user
-            userRepository.setSelectedUserInfo(USER_INFOS[0])
+    @Test
+    fun isDisclaimerDismissed_byDefault_isFalse() =
+        testScope.runTest {
+            val isDisclaimerDismissed by
+                collectLastValue(underTest.isDisclaimerDismissed(MAIN_USER))
+            assertThat(isDisclaimerDismissed).isFalse()
+        }
 
-            // dismissed is true for primary user
-            assertThat(isCtaDismissed).isTrue()
+    @Test
+    fun isDisclaimerDismissed_onSet_isTrue() =
+        testScope.runTest {
+            val isDisclaimerDismissed by
+                collectLastValue(underTest.isDisclaimerDismissed(MAIN_USER))
+
+            underTest.setDisclaimerDismissed(MAIN_USER)
+            assertThat(isDisclaimerDismissed).isTrue()
         }
 
     @Test
     fun getSharedPreferences_whenFileRestored() =
         testScope.runTest {
-            val userFileManagerSpy = Mockito.spy(userFileManager)
-            underTest = createCommunalPrefsRepositoryImpl(userFileManagerSpy)
-
-            val isCtaDismissed by collectLastValue(underTest.isCtaDismissed)
-            userRepository.setSelectedUserInfo(USER_INFOS[0])
+            val isCtaDismissed by collectLastValue(underTest.isCtaDismissed(MAIN_USER))
             assertThat(isCtaDismissed).isFalse()
-            clearInvocations(userFileManagerSpy)
+            clearInvocations(userFileManager)
 
             // Received restore finished event.
             kosmos.broadcastDispatcher.sendIntentToMatchingReceiversOnly(
@@ -141,48 +120,12 @@
             runCurrent()
 
             // Get shared preferences from the restored file.
-            verify(userFileManagerSpy, atLeastOnce())
-                .getSharedPreferences(
-                    FILE_NAME,
-                    Context.MODE_PRIVATE,
-                    userRepository.getSelectedUserInfo().id
-                )
+            verify(userFileManager, atLeastOnce())
+                .getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE, MAIN_USER.id)
         }
 
-    private fun createCommunalPrefsRepositoryImpl(userFileManager: UserFileManager) =
-        CommunalPrefsRepositoryImpl(
-            testScope.backgroundScope,
-            kosmos.testDispatcher,
-            userRepository,
-            userFileManager,
-            kosmos.broadcastDispatcher,
-            logcatLogBuffer("CommunalPrefsRepositoryImplTest"),
-            tableLogBuffer,
-        )
-
-    private class FakeUserFileManager(private val sharedPrefs: Map<Int, SharedPreferences>) :
-        UserFileManager {
-        override fun getFile(fileName: String, userId: Int): File {
-            throw UnsupportedOperationException()
-        }
-
-        override fun getSharedPreferences(
-            fileName: String,
-            mode: Int,
-            userId: Int
-        ): SharedPreferences {
-            if (fileName != FILE_NAME) {
-                throw IllegalArgumentException("Preference files must be $FILE_NAME")
-            }
-            return sharedPrefs.getValue(userId)
-        }
-    }
-
     companion object {
-        val USER_INFOS =
-            listOf(
-                UserInfo(/* id= */ 0, "zero", /* flags= */ 0),
-                UserInfo(/* id= */ 1, "secondary", /* flags= */ 0),
-            )
+        val MAIN_USER = UserInfo(0, "main", FLAG_MAIN)
+        val SECONDARY_USER = UserInfo(1, "secondary", 0)
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt
index fb2b33d..0169f99 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt
@@ -20,7 +20,6 @@
 import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE
 import android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL
 import android.app.admin.devicePolicyManager
-import android.appwidget.AppWidgetProviderInfo
 import android.content.Intent
 import android.content.pm.UserInfo
 import android.os.UserManager.USER_TYPE_PROFILE_MANAGED
@@ -29,7 +28,6 @@
 import android.provider.Settings
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.settingslib.flags.Flags.FLAG_ALLOW_ALL_WIDGETS_ON_LOCKSCREEN_BY_DEFAULT
 import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.broadcast.broadcastDispatcher
@@ -183,47 +181,11 @@
                 )
         }
 
-    @EnableFlags(FLAG_COMMUNAL_HUB)
-    @Test
-    fun hubShowsWidgetCategoriesSetByUser() =
-        testScope.runTest {
-            kosmos.fakeSettings.putIntForUser(
-                CommunalSettingsRepositoryImpl.GLANCEABLE_HUB_CONTENT_SETTING,
-                AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
-                PRIMARY_USER.id
-            )
-            val setting by collectLastValue(underTest.getWidgetCategories(PRIMARY_USER))
-            assertThat(setting?.categories)
-                .isEqualTo(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN)
-        }
-
-    @EnableFlags(FLAG_COMMUNAL_HUB)
-    @DisableFlags(FLAG_ALLOW_ALL_WIDGETS_ON_LOCKSCREEN_BY_DEFAULT)
-    @Test
-    fun hubShowsKeyguardWidgetsByDefault() =
-        testScope.runTest {
-            val setting by collectLastValue(underTest.getWidgetCategories(PRIMARY_USER))
-            assertThat(setting?.categories)
-                .isEqualTo(AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD)
-        }
-
-    @EnableFlags(FLAG_COMMUNAL_HUB, FLAG_ALLOW_ALL_WIDGETS_ON_LOCKSCREEN_BY_DEFAULT)
-    @Test
-    fun hubShowsAllWidgetsByDefaultWhenFlagEnabled() =
-        testScope.runTest {
-            val setting by collectLastValue(underTest.getWidgetCategories(PRIMARY_USER))
-            assertThat(setting?.categories)
-                .isEqualTo(
-                    AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD +
-                        AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN
-                )
-        }
-
     @Test
     fun backgroundType_defaultValue() =
         testScope.runTest {
             val backgroundType by collectLastValue(underTest.getBackground(PRIMARY_USER))
-            assertThat(backgroundType).isEqualTo(CommunalBackgroundType.DEFAULT)
+            assertThat(backgroundType).isEqualTo(CommunalBackgroundType.ANIMATED)
         }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
index 3d454a2..7b26db5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
@@ -36,7 +36,6 @@
 import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.broadcast.broadcastDispatcher
-import com.android.systemui.communal.data.repository.CommunalSettingsRepositoryImpl
 import com.android.systemui.communal.data.repository.FakeCommunalMediaRepository
 import com.android.systemui.communal.data.repository.FakeCommunalPrefsRepository
 import com.android.systemui.communal.data.repository.FakeCommunalSceneRepository
@@ -81,7 +80,6 @@
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.nullable
 import com.android.systemui.util.mockito.whenever
-import com.android.systemui.util.settings.fakeSettings
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -488,8 +486,16 @@
     @Test
     fun ctaTile_afterDismiss_doesNotShow() =
         testScope.runTest {
+            // Set to main user, so we can dismiss the tile for the main user.
+            val user = userRepository.asMainUser()
+            userTracker.set(
+                userInfos = listOf(user),
+                selectedUserIndex = 0,
+            )
+            runCurrent()
+
             tutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED)
-            communalPrefsRepository.setCtaDismissedForCurrentUser()
+            communalPrefsRepository.setCtaDismissed(user)
 
             val ctaTileContent by collectLastValue(underTest.ctaTileContent)
 
@@ -907,14 +913,6 @@
             )
             runCurrent()
 
-            // Keyguard widgets are allowed.
-            kosmos.fakeSettings.putIntForUser(
-                CommunalSettingsRepositoryImpl.GLANCEABLE_HUB_CONTENT_SETTING,
-                AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD,
-                mainUser.id
-            )
-            runCurrent()
-
             // When work profile is paused.
             whenever(userManager.isQuietModeEnabled(eq(UserHandle.of(USER_INFO_WORK.id))))
                 .thenReturn(true)
@@ -948,93 +946,6 @@
         }
 
     @Test
-    fun widgetContent_containsDisabledWidgets_whenCategoryNotAllowed() =
-        testScope.runTest {
-            // Communal available, and tutorial completed.
-            keyguardRepository.setKeyguardShowing(true)
-            keyguardRepository.setKeyguardOccluded(false)
-            tutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED)
-
-            val userInfos = listOf(MAIN_USER_INFO, USER_INFO_WORK)
-            userRepository.setUserInfos(userInfos)
-            userTracker.set(
-                userInfos = userInfos,
-                selectedUserIndex = 0,
-            )
-            userRepository.setSelectedUserInfo(MAIN_USER_INFO)
-            runCurrent()
-
-            // Widgets available.
-            val widget1 =
-                createWidgetWithCategory(1, AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN)
-            val widget2 =
-                createWidgetWithCategory(2, AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD)
-            val widget3 =
-                createWidgetWithCategory(3, AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX)
-            val widgets = listOf(widget1, widget2, widget3)
-            widgetRepository.setCommunalWidgets(widgets)
-
-            val widgetContent by collectLastValue(underTest.widgetContent)
-            kosmos.fakeSettings.putIntForUser(
-                CommunalSettingsRepositoryImpl.GLANCEABLE_HUB_CONTENT_SETTING,
-                AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD,
-                mainUser.id
-            )
-
-            // Only the keyguard widget is enabled.
-            assertThat(widgetContent).hasSize(3)
-            assertThat(widgetContent!!.get(0))
-                .isInstanceOf(CommunalContentModel.WidgetContent.DisabledWidget::class.java)
-            assertThat(widgetContent!!.get(1))
-                .isInstanceOf(CommunalContentModel.WidgetContent.Widget::class.java)
-            assertThat(widgetContent!!.get(2))
-                .isInstanceOf(CommunalContentModel.WidgetContent.DisabledWidget::class.java)
-        }
-
-    @Test
-    fun widgetContent_allEnabled_whenCategoryAllowed() =
-        testScope.runTest {
-            // Communal available, and tutorial completed.
-            keyguardRepository.setKeyguardShowing(true)
-            keyguardRepository.setKeyguardOccluded(false)
-            tutorialRepository.setTutorialSettingState(HUB_MODE_TUTORIAL_COMPLETED)
-
-            val userInfos = listOf(MAIN_USER_INFO, USER_INFO_WORK)
-            userRepository.setUserInfos(userInfos)
-            userTracker.set(
-                userInfos = userInfos,
-                selectedUserIndex = 0,
-            )
-            userRepository.setSelectedUserInfo(MAIN_USER_INFO)
-            runCurrent()
-
-            // Widgets available.
-            val widget1 =
-                createWidgetWithCategory(1, AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN)
-            val widget2 =
-                createWidgetWithCategory(2, AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD)
-            val widget3 =
-                createWidgetWithCategory(3, AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD)
-            val widgets = listOf(widget1, widget2, widget3)
-            widgetRepository.setCommunalWidgets(widgets)
-
-            val widgetContent by collectLastValue(underTest.widgetContent)
-            kosmos.fakeSettings.putIntForUser(
-                CommunalSettingsRepositoryImpl.GLANCEABLE_HUB_CONTENT_SETTING,
-                AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD or
-                    AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
-                mainUser.id
-            )
-
-            // All widgets are enabled.
-            assertThat(widgetContent).hasSize(3)
-            widgetContent!!.forEach { model ->
-                assertThat(model)
-                    .isInstanceOf(CommunalContentModel.WidgetContent.Widget::class.java)
-            }
-        }
-
-    @Test
     fun filterWidgets_whenDisallowedByDevicePolicyForWorkProfile() =
         testScope.runTest {
             // Keyguard showing, and tutorial completed.
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalPrefsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalPrefsInteractorTest.kt
new file mode 100644
index 0000000..7b79d28
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalPrefsInteractorTest.kt
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.communal.domain.interactor
+
+import android.content.pm.UserInfo
+import android.content.pm.UserInfo.FLAG_MAIN
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.settings.fakeUserTracker
+import com.android.systemui.testKosmos
+import com.android.systemui.user.data.repository.fakeUserRepository
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class CommunalPrefsInteractorTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+
+    private val underTest by lazy { kosmos.communalPrefsInteractor }
+
+    @Test
+    fun setCtaDismissed_currentUser() =
+        testScope.runTest {
+            setSelectedUser(MAIN_USER)
+            val isCtaDismissed by collectLastValue(underTest.isCtaDismissed)
+
+            assertThat(isCtaDismissed).isFalse()
+            underTest.setCtaDismissed(MAIN_USER)
+            assertThat(isCtaDismissed).isTrue()
+        }
+
+    @Test
+    fun setCtaDismissed_anotherUser() =
+        testScope.runTest {
+            setSelectedUser(MAIN_USER)
+            val isCtaDismissed by collectLastValue(underTest.isCtaDismissed)
+
+            assertThat(isCtaDismissed).isFalse()
+            underTest.setCtaDismissed(SECONDARY_USER)
+            assertThat(isCtaDismissed).isFalse()
+        }
+
+    @Test
+    fun isCtaDismissed_userSwitch() =
+        testScope.runTest {
+            setSelectedUser(MAIN_USER)
+            underTest.setCtaDismissed(MAIN_USER)
+            val isCtaDismissed by collectLastValue(underTest.isCtaDismissed)
+
+            assertThat(isCtaDismissed).isTrue()
+            setSelectedUser(SECONDARY_USER)
+            assertThat(isCtaDismissed).isFalse()
+        }
+
+    @Test
+    fun setDisclaimerDismissed_currentUser() =
+        testScope.runTest {
+            setSelectedUser(MAIN_USER)
+            val isDisclaimerDismissed by collectLastValue(underTest.isDisclaimerDismissed)
+
+            assertThat(isDisclaimerDismissed).isFalse()
+            underTest.setDisclaimerDismissed(MAIN_USER)
+            assertThat(isDisclaimerDismissed).isTrue()
+        }
+
+    @Test
+    fun setDisclaimerDismissed_anotherUser() =
+        testScope.runTest {
+            setSelectedUser(MAIN_USER)
+            val isDisclaimerDismissed by collectLastValue(underTest.isDisclaimerDismissed)
+
+            assertThat(isDisclaimerDismissed).isFalse()
+            underTest.setDisclaimerDismissed(SECONDARY_USER)
+            assertThat(isDisclaimerDismissed).isFalse()
+        }
+
+    @Test
+    fun isDisclaimerDismissed_userSwitch() =
+        testScope.runTest {
+            setSelectedUser(MAIN_USER)
+            underTest.setDisclaimerDismissed(MAIN_USER)
+            val isDisclaimerDismissed by collectLastValue(underTest.isDisclaimerDismissed)
+
+            assertThat(isDisclaimerDismissed).isTrue()
+            setSelectedUser(SECONDARY_USER)
+            assertThat(isDisclaimerDismissed).isFalse()
+        }
+
+    private suspend fun setSelectedUser(user: UserInfo) {
+        with(kosmos.fakeUserRepository) {
+            setUserInfos(listOf(user))
+            setSelectedUserInfo(user)
+        }
+        kosmos.fakeUserTracker.set(userInfos = listOf(user), selectedUserIndex = 0)
+    }
+
+    private companion object {
+        val MAIN_USER = UserInfo(0, "main", FLAG_MAIN)
+        val SECONDARY_USER = UserInfo(1, "secondary", 0)
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorTest.kt
index 6e48b99..43293c7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractorTest.kt
@@ -83,24 +83,27 @@
         }
 
     @Test
-    fun snapToSceneForActivity() =
+    fun changeSceneForActivityStartOnDismissKeyguard() =
         testScope.runTest {
             val currentScene by collectLastValue(underTest.currentScene)
-            assertThat(currentScene).isEqualTo(CommunalScenes.Blank)
-
-            underTest.snapToSceneForActivityStart(CommunalScenes.Communal)
+            underTest.snapToScene(CommunalScenes.Communal)
             assertThat(currentScene).isEqualTo(CommunalScenes.Communal)
+
+            underTest.changeSceneForActivityStartOnDismissKeyguard()
+            assertThat(currentScene).isEqualTo(CommunalScenes.Blank)
         }
 
     @Test
-    fun snapToSceneForActivity_willNotChangeScene_forEditModeActivity() =
+    fun changeSceneForActivityStartOnDismissKeyguard_willNotChangeScene_forEditModeActivity() =
         testScope.runTest {
             val currentScene by collectLastValue(underTest.currentScene)
-            assertThat(currentScene).isEqualTo(CommunalScenes.Blank)
+            underTest.snapToScene(CommunalScenes.Communal)
+            assertThat(currentScene).isEqualTo(CommunalScenes.Communal)
 
             underTest.setEditModeState(EditModeState.STARTING)
-            underTest.snapToSceneForActivityStart(CommunalScenes.Communal)
-            assertThat(currentScene).isEqualTo(CommunalScenes.Blank)
+
+            underTest.changeSceneForActivityStartOnDismissKeyguard()
+            assertThat(currentScene).isEqualTo(CommunalScenes.Communal)
         }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt
new file mode 100644
index 0000000..e4916b1
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.communal.domain.interactor
+
+import android.app.admin.DevicePolicyManager
+import android.app.admin.devicePolicyManager
+import android.content.Intent
+import android.content.pm.UserInfo
+import android.os.UserManager
+import android.os.userManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.broadcastDispatcher
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.settings.FakeUserTracker
+import com.android.systemui.settings.fakeUserTracker
+import com.android.systemui.testKosmos
+import com.android.systemui.user.data.repository.FakeUserRepository
+import com.android.systemui.user.data.repository.fakeUserRepository
+import kotlinx.coroutines.test.runTest
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertNull
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers
+import org.mockito.kotlin.anyOrNull
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class CommunalSettingsInteractorTest : SysuiTestCase() {
+
+    private lateinit var userManager: UserManager
+    private lateinit var userRepository: FakeUserRepository
+    private lateinit var userTracker: FakeUserTracker
+
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+
+    private lateinit var underTest: CommunalSettingsInteractor
+
+    @Before
+    fun setUp() {
+        userManager = kosmos.userManager
+        userRepository = kosmos.fakeUserRepository
+        userTracker = kosmos.fakeUserTracker
+
+        val userInfos = listOf(MAIN_USER_INFO, USER_INFO_WORK)
+        userRepository.setUserInfos(userInfos)
+        userTracker.set(
+            userInfos = userInfos,
+            selectedUserIndex = 0,
+        )
+
+        underTest = kosmos.communalSettingsInteractor
+    }
+
+    @Test
+    fun filterUsers_dontFilteredUsersWhenAllAreAllowed() =
+        testScope.runTest {
+            // If no users have any keyguard features disabled...
+            val disallowedUser by
+                collectLastValue(underTest.workProfileUserDisallowedByDevicePolicy)
+            // ...then the disallowed user should be null
+            assertNull(disallowedUser)
+        }
+
+    @Test
+    fun filterUsers_filterWorkProfileUserWhenDisallowed() =
+        testScope.runTest {
+            // If the work profile user has keyguard widgets disabled...
+            setKeyguardFeaturesDisabled(
+                USER_INFO_WORK,
+                DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL
+            )
+            // ...then the disallowed user match the work profile
+            val disallowedUser by
+                collectLastValue(underTest.workProfileUserDisallowedByDevicePolicy)
+            assertNotNull(disallowedUser)
+            assertEquals(USER_INFO_WORK.id, disallowedUser!!.id)
+        }
+
+    private fun setKeyguardFeaturesDisabled(user: UserInfo, disabledFlags: Int) {
+        whenever(
+                kosmos.devicePolicyManager.getKeyguardDisabledFeatures(
+                    anyOrNull(),
+                    ArgumentMatchers.eq(user.id)
+                )
+            )
+            .thenReturn(disabledFlags)
+        kosmos.broadcastDispatcher.sendIntentToMatchingReceiversOnly(
+            context,
+            Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
+        )
+    }
+
+    private companion object {
+        val MAIN_USER_INFO = UserInfo(0, "primary", UserInfo.FLAG_MAIN)
+        val USER_INFO_WORK =
+            UserInfo(
+                10,
+                "work",
+                /* iconPath= */ "",
+                /* flags= */ 0,
+                UserManager.USER_TYPE_PROFILE_MANAGED,
+            )
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt
index d5fe2a1..0190ccb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalEditModeViewModelTest.kt
@@ -40,6 +40,7 @@
 import com.android.systemui.communal.data.repository.fakeCommunalWidgetRepository
 import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
 import com.android.systemui.communal.domain.interactor.communalInteractor
+import com.android.systemui.communal.domain.interactor.communalPrefsInteractor
 import com.android.systemui.communal.domain.interactor.communalSceneInteractor
 import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
 import com.android.systemui.communal.domain.model.CommunalContentModel
@@ -48,6 +49,8 @@
 import com.android.systemui.communal.shared.model.EditModeState
 import com.android.systemui.communal.ui.viewmodel.CommunalEditModeViewModel
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
@@ -57,6 +60,7 @@
 import com.android.systemui.smartspace.data.repository.FakeSmartspaceRepository
 import com.android.systemui.smartspace.data.repository.fakeSmartspaceRepository
 import com.android.systemui.testKosmos
+import com.android.systemui.user.data.repository.fakeUserRepository
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
@@ -104,10 +108,12 @@
         smartspaceRepository = kosmos.fakeSmartspaceRepository
         mediaRepository = kosmos.fakeCommunalMediaRepository
         communalSceneInteractor = kosmos.communalSceneInteractor
+        kosmos.fakeUserRepository.setUserInfos(listOf(MAIN_USER_INFO))
         kosmos.fakeUserTracker.set(
             userInfos = listOf(MAIN_USER_INFO),
             selectedUserIndex = 0,
         )
+        kosmos.fakeFeatureFlagsClassic.set(Flags.COMMUNAL_SERVICE_ENABLED, true)
         whenever(providerInfo.profile).thenReturn(UserHandle(MAIN_USER_INFO.id))
 
         underTest =
@@ -120,6 +126,7 @@
                 uiEventLogger,
                 logcatLogBuffer("CommunalEditModeViewModelTest"),
                 kosmos.testDispatcher,
+                kosmos.communalPrefsInteractor,
             )
     }
 
@@ -312,6 +319,29 @@
         }
     }
 
+    @Test
+    fun showDisclaimer_trueAfterEditModeShowing() =
+        testScope.runTest {
+            val showDisclaimer by collectLastValue(underTest.showDisclaimer)
+
+            assertThat(showDisclaimer).isFalse()
+            underTest.setEditModeState(EditModeState.SHOWING)
+            assertThat(showDisclaimer).isTrue()
+        }
+
+    @Test
+    fun showDisclaimer_falseWhenDismissed() =
+        testScope.runTest {
+            underTest.setEditModeState(EditModeState.SHOWING)
+            kosmos.fakeUserRepository.setSelectedUserInfo(MAIN_USER_INFO)
+
+            val showDisclaimer by collectLastValue(underTest.showDisclaimer)
+
+            assertThat(showDisclaimer).isTrue()
+            underTest.onDisclaimerDismissed()
+            assertThat(showDisclaimer).isFalse()
+        }
+
     private companion object {
         val MAIN_USER_INFO = UserInfo(0, "primary", UserInfo.FLAG_MAIN)
         const val WIDGET_PICKER_PACKAGE_NAME = "widget_picker_package_name"
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
index e7a7b15..d338774 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/view/viewmodel/CommunalViewModelTest.kt
@@ -69,12 +69,18 @@
 import com.android.systemui.media.controls.ui.view.MediaHost
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
 import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.scene.data.repository.Idle
+import com.android.systemui.scene.data.repository.Transition
+import com.android.systemui.scene.data.repository.setTransition
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.settings.fakeUserTracker
 import com.android.systemui.shade.ShadeTestUtil
 import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.shade.shadeTestUtil
 import com.android.systemui.smartspace.data.repository.FakeSmartspaceRepository
 import com.android.systemui.smartspace.data.repository.fakeSmartspaceRepository
+import com.android.systemui.statusbar.KeyguardIndicationController
 import com.android.systemui.testKosmos
 import com.android.systemui.user.data.repository.FakeUserRepository
 import com.android.systemui.user.data.repository.fakeUserRepository
@@ -91,6 +97,7 @@
 import org.mockito.Mockito
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.mock
 import org.mockito.kotlin.whenever
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
@@ -100,7 +107,6 @@
 @RunWith(ParameterizedAndroidJunit4::class)
 class CommunalViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
     @Mock private lateinit var mediaHost: MediaHost
-    @Mock private lateinit var user: UserInfo
     @Mock private lateinit var providerInfo: AppWidgetProviderInfo
 
     private val kosmos = testKosmos()
@@ -152,16 +158,18 @@
             CommunalViewModel(
                 kosmos.testDispatcher,
                 testScope,
+                kosmos.testScope.backgroundScope,
                 context.resources,
                 kosmos.keyguardTransitionInteractor,
                 kosmos.keyguardInteractor,
+                mock<KeyguardIndicationController>(),
                 kosmos.communalSceneInteractor,
                 kosmos.communalInteractor,
                 kosmos.communalSettingsInteractor,
                 kosmos.communalTutorialInteractor,
                 kosmos.shadeInteractor,
                 mediaHost,
-                logcatLogBuffer("CommunalViewModelTest"),
+                logcatLogBuffer("CommunalViewModelTest")
             )
     }
 
@@ -315,6 +323,7 @@
     @Test
     fun dismissCta_hidesCtaTileAndShowsPopup_thenHidesPopupAfterTimeout() =
         testScope.runTest {
+            setIsMainUser(true)
             tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
 
             val communalContent by collectLastValue(underTest.communalContent)
@@ -338,6 +347,7 @@
     @Test
     fun popup_onDismiss_hidesImmediately() =
         testScope.runTest {
+            setIsMainUser(true)
             tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
 
             val currentPopup by collectLastValue(underTest.currentPopup)
@@ -357,7 +367,7 @@
             val currentPopup by collectLastValue(underTest.currentPopup)
 
             assertThat(currentPopup).isNull()
-            underTest.onShowCustomizeWidgetButton()
+            underTest.onLongClick()
             assertThat(currentPopup).isEqualTo(PopupType.CustomizeWidgetButton)
             advanceTimeBy(POPUP_AUTO_HIDE_TIMEOUT_MS)
             assertThat(currentPopup).isNull()
@@ -369,7 +379,7 @@
             tutorialRepository.setTutorialSettingState(Settings.Secure.HUB_MODE_TUTORIAL_COMPLETED)
             val currentPopup by collectLastValue(underTest.currentPopup)
 
-            underTest.onShowCustomizeWidgetButton()
+            underTest.onLongClick()
             assertThat(currentPopup).isEqualTo(PopupType.CustomizeWidgetButton)
 
             underTest.onHidePopup()
@@ -487,13 +497,16 @@
                 flowOf(ObservableTransitionState.Idle(CommunalScenes.Communal))
             )
             // Transitioned to Glanceable hub.
-            keyguardTransitionRepository.sendTransitionSteps(
-                from = KeyguardState.LOCKSCREEN,
-                to = KeyguardState.GLANCEABLE_HUB,
-                testScope = testScope,
+            kosmos.setTransition(
+                sceneTransition = Idle(Scenes.Communal),
+                stateTransition =
+                    TransitionStep(
+                        from = KeyguardState.LOCKSCREEN,
+                        to = KeyguardState.GLANCEABLE_HUB,
+                    )
             )
             // Shade not expanded.
-            shadeTestUtil.setLockscreenShadeExpansion(0f)
+            if (!SceneContainerFlag.isEnabled) shadeTestUtil.setLockscreenShadeExpansion(0f)
 
             assertThat(isFocusable).isEqualTo(true)
         }
@@ -536,10 +549,13 @@
             keyguardRepository.setKeyguardOccluded(true)
 
             // And on hub
-            keyguardTransitionRepository.sendTransitionSteps(
-                from = KeyguardState.DREAMING,
-                to = KeyguardState.GLANCEABLE_HUB,
-                testScope = testScope,
+            kosmos.setTransition(
+                sceneTransition = Idle(Scenes.Communal),
+                stateTransition =
+                    TransitionStep(
+                        from = KeyguardState.DREAMING,
+                        to = KeyguardState.GLANCEABLE_HUB,
+                    )
             )
 
             // Then flow is not frozen
@@ -553,10 +569,13 @@
             assertThat(isCommunalContentFlowFrozen).isEqualTo(true)
 
             // 3. When transitioned to OCCLUDED and activity shows
-            keyguardTransitionRepository.sendTransitionSteps(
-                from = KeyguardState.GLANCEABLE_HUB,
-                to = KeyguardState.OCCLUDED,
-                testScope = testScope,
+            kosmos.setTransition(
+                sceneTransition = Idle(Scenes.Lockscreen),
+                stateTransition =
+                    TransitionStep(
+                        from = KeyguardState.GLANCEABLE_HUB,
+                        to = KeyguardState.OCCLUDED,
+                    )
             )
 
             // Then flow is not frozen
@@ -574,10 +593,13 @@
             keyguardRepository.setKeyguardOccluded(false)
 
             // And transitioned to hub
-            keyguardTransitionRepository.sendTransitionSteps(
-                from = KeyguardState.LOCKSCREEN,
-                to = KeyguardState.GLANCEABLE_HUB,
-                testScope = testScope,
+            kosmos.setTransition(
+                sceneTransition = Idle(Scenes.Communal),
+                stateTransition =
+                    TransitionStep(
+                        from = KeyguardState.LOCKSCREEN,
+                        to = KeyguardState.GLANCEABLE_HUB,
+                    )
             )
 
             // Then flow is not frozen
@@ -588,30 +610,30 @@
             runCurrent()
 
             // And transitioning to occluded
-            keyguardTransitionRepository.sendTransitionStep(
-                TransitionStep(
-                    from = KeyguardState.GLANCEABLE_HUB,
-                    to = KeyguardState.OCCLUDED,
-                    transitionState = TransitionState.STARTED,
-                )
-            )
-
-            keyguardTransitionRepository.sendTransitionStep(
-                from = KeyguardState.GLANCEABLE_HUB,
-                to = KeyguardState.OCCLUDED,
-                transitionState = TransitionState.RUNNING,
-                value = 0.5f,
+            kosmos.setTransition(
+                sceneTransition = Transition(from = Scenes.Communal, to = Scenes.Lockscreen),
+                stateTransition =
+                    TransitionStep(
+                        from = KeyguardState.GLANCEABLE_HUB,
+                        to = KeyguardState.OCCLUDED,
+                        transitionState = TransitionState.STARTED,
+                        value = 0f,
+                    )
             )
 
             // Then flow is frozen
             assertThat(isCommunalContentFlowFrozen).isEqualTo(true)
 
             // 3. When transition is finished
-            keyguardTransitionRepository.sendTransitionStep(
-                from = KeyguardState.GLANCEABLE_HUB,
-                to = KeyguardState.OCCLUDED,
-                transitionState = TransitionState.FINISHED,
-                value = 1f,
+            kosmos.setTransition(
+                sceneTransition = Idle(Scenes.Lockscreen),
+                stateTransition =
+                    TransitionStep(
+                        from = KeyguardState.GLANCEABLE_HUB,
+                        to = KeyguardState.OCCLUDED,
+                        transitionState = TransitionState.FINISHED,
+                        value = 1f,
+                    )
             )
 
             // Then flow is not frozen
@@ -634,10 +656,13 @@
             keyguardRepository.setKeyguardOccluded(true)
 
             // And transitioned to hub
-            keyguardTransitionRepository.sendTransitionSteps(
-                from = KeyguardState.DREAMING,
-                to = KeyguardState.GLANCEABLE_HUB,
-                testScope = testScope,
+            kosmos.setTransition(
+                sceneTransition = Idle(Scenes.Communal),
+                stateTransition =
+                    TransitionStep(
+                        from = KeyguardState.DREAMING,
+                        to = KeyguardState.GLANCEABLE_HUB,
+                    )
             )
 
             // Widgets available
@@ -743,13 +768,17 @@
         }
 
     private suspend fun setIsMainUser(isMainUser: Boolean) {
-        whenever(user.isMain).thenReturn(isMainUser)
-        userRepository.setUserInfos(listOf(user))
-        userRepository.setSelectedUserInfo(user)
+        val user = if (isMainUser) MAIN_USER_INFO else SECONDARY_USER_INFO
+        with(userRepository) {
+            setUserInfos(listOf(user))
+            setSelectedUserInfo(user)
+        }
+        kosmos.fakeUserTracker.set(userInfos = listOf(user), selectedUserIndex = 0)
     }
 
     private companion object {
         val MAIN_USER_INFO = UserInfo(0, "primary", UserInfo.FLAG_MAIN)
+        val SECONDARY_USER_INFO = UserInfo(1, "secondary", 0)
 
         @JvmStatic
         @Parameters(name = "{0}")
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt
index 7b7d03b..7044895 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/WidgetInteractionHandlerTest.kt
@@ -72,6 +72,7 @@
                 /* animationController = */ notNull(),
                 /* fillInIntent = */ refEq(fillInIntent),
                 /* extraOptions = */ refEq(activityOptions.toBundle()),
+                /* customMessage */ isNull(),
             )
     }
 
@@ -93,6 +94,7 @@
                 /* animationController = */ isNull(),
                 /* fillInIntent = */ refEq(fillInIntent),
                 /* extraOptions = */ refEq(activityOptions.toBundle()),
+                /* customMessage */ isNull(),
             )
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceconfig/data/repository/DeviceConfigRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceconfig/data/repository/DeviceConfigRepositoryTest.kt
new file mode 100644
index 0000000..79115ae
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceconfig/data/repository/DeviceConfigRepositoryTest.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.deviceconfig.data.repository
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.concurrency.fakeExecutor
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.android.systemui.util.fakeDeviceConfigProxy
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class DeviceConfigRepositoryTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val dataSource = kosmos.fakeDeviceConfigProxy
+
+    private val underTest = kosmos.deviceConfigRepository
+
+    @Test
+    fun booleanProperty() =
+        testScope.runTest {
+            val property by collectLastValue(underTest.property("namespace", "name", false))
+            assertThat(property).isFalse()
+
+            dataSource.setProperty("namespace", "name", "true", /* makeDefault= */ false)
+            kosmos.fakeExecutor.runAllReady()
+            assertThat(property).isTrue()
+
+            dataSource.setProperty("namespace", "name", "false", /* makeDefault= */ false)
+            kosmos.fakeExecutor.runAllReady()
+            assertThat(property).isFalse()
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceconfig/domain/interactor/DeviceConfigInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceconfig/domain/interactor/DeviceConfigInteractorTest.kt
new file mode 100644
index 0000000..6ec4cea
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceconfig/domain/interactor/DeviceConfigInteractorTest.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.deviceconfig.domain.interactor
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.concurrency.fakeExecutor
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.android.systemui.util.fakeDeviceConfigProxy
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class DeviceConfigInteractorTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val dataSource = kosmos.fakeDeviceConfigProxy
+
+    private val underTest = kosmos.deviceConfigInteractor
+
+    @Test
+    fun booleanProperty() =
+        testScope.runTest {
+            val property by collectLastValue(underTest.property("namespace", "name", false))
+            assertThat(property).isFalse()
+
+            dataSource.setProperty("namespace", "name", "true", /* makeDefault= */ false)
+            kosmos.fakeExecutor.runAllReady()
+            assertThat(property).isTrue()
+
+            dataSource.setProperty("namespace", "name", "false", /* makeDefault= */ false)
+            kosmos.fakeExecutor.runAllReady()
+            assertThat(property).isFalse()
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
index 84c250c..546510b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
@@ -617,6 +617,33 @@
                 .isEqualTo(DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate)
         }
 
+    @Test
+    fun reportUserPresent_whenDeviceEntered() =
+        testScope.runTest {
+            val isDeviceEntered by collectLastValue(underTest.isDeviceEntered)
+            assertThat(isDeviceEntered).isFalse()
+            assertThat(kosmos.fakeDeviceEntryRepository.userPresentCount).isEqualTo(0)
+
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
+            runCurrent()
+            switchToScene(Scenes.Gone)
+            assertThat(isDeviceEntered).isTrue()
+            assertThat(kosmos.fakeDeviceEntryRepository.userPresentCount).isEqualTo(1)
+
+            switchToScene(Scenes.Lockscreen)
+            assertThat(isDeviceEntered).isFalse()
+            assertThat(kosmos.fakeDeviceEntryRepository.userPresentCount).isEqualTo(1)
+
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
+            switchToScene(Scenes.Gone)
+            assertThat(isDeviceEntered).isTrue()
+            assertThat(kosmos.fakeDeviceEntryRepository.userPresentCount).isEqualTo(2)
+        }
+
     private fun TestScope.verifyRestrictionReasonsForAuthFlags(
         vararg authFlagToDeviceEntryRestriction: Pair<Int, DeviceEntryRestrictionReason?>
     ) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
index c48ced1..6412276 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
@@ -32,11 +32,9 @@
 import android.content.res.Resources;
 import android.graphics.Region;
 import android.os.Handler;
-import android.platform.test.annotations.DisableFlags;
 import android.platform.test.annotations.EnableFlags;
 import android.testing.TestableLooper.RunWithLooper;
 import android.view.AttachedSurfaceControl;
-import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewRootImpl;
 import android.view.ViewTreeObserver;
@@ -46,7 +44,6 @@
 
 import com.android.dream.lowlight.LowLightTransitionCoordinator;
 import com.android.keyguard.BouncerPanelExpansionCalculator;
-import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.ambient.statusbar.ui.AmbientStatusBarViewController;
 import com.android.systemui.ambient.touch.scrim.BouncerlessScrimController;
@@ -101,9 +98,6 @@
     ViewGroup mDreamOverlayContentView;
 
     @Mock
-    View mHubGestureIndicatorView;
-
-    @Mock
     Handler mHandler;
 
     @Mock
@@ -149,6 +143,8 @@
         when(mDreamOverlayContainerView.getRootSurfaceControl())
                 .thenReturn(mAttachedSurfaceControl);
         when(mKeyguardTransitionInteractor.isFinishedInStateWhere(any())).thenReturn(emptyFlow());
+        when(mKeyguardTransitionInteractor.isFinishedIn(any(), any())).thenReturn(emptyFlow());
+        when(mKeyguardTransitionInteractor.isFinishedIn(any())).thenReturn(emptyFlow());
         when(mShadeInteractor.isAnyExpanded()).thenReturn(MutableStateFlow(false));
         when(mCommunalInteractor.isCommunalShowing()).thenReturn(MutableStateFlow(false));
 
@@ -156,7 +152,6 @@
                 mDreamOverlayContainerView,
                 mComplicationHostViewController,
                 mDreamOverlayContentView,
-                mHubGestureIndicatorView,
                 mAmbientStatusBarViewController,
                 mLowLightTransitionCoordinator,
                 mTouchInsetSession,
@@ -177,18 +172,6 @@
                 mDreamManager);
     }
 
-    @DisableFlags(Flags.FLAG_COMMUNAL_HUB)
-    @Test
-    public void testHubGestureIndicatorGoneWhenFlagOff() {
-        verify(mHubGestureIndicatorView, never()).setVisibility(View.VISIBLE);
-    }
-
-    @EnableFlags({Flags.FLAG_COMMUNAL_HUB, Flags.FLAG_GLANCEABLE_HUB_GESTURE_HANDLE})
-    @Test
-    public void testHubGestureIndicatorVisibleWhenFlagOn() {
-        verify(mHubGestureIndicatorView).setVisibility(View.VISIBLE);
-    }
-
     @Test
     public void testRootSurfaceControlInsetSetOnAttach() {
         mController.onViewAttached();
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
index ee8a22c..5a39de8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/DreamOverlayServiceTest.kt
@@ -778,6 +778,7 @@
             DREAM_COMPONENT,
             false /*shouldShowComplication*/
         )
+        testScope.runCurrent()
         mMainExecutor.runAllReady()
         assertThat(lifecycleRegistry.currentState).isEqualTo(Lifecycle.State.STARTED)
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt
new file mode 100644
index 0000000..4a5342a
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.education.data.repository
+
+import android.content.Context
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.SysuiTestableContext
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.shared.education.GestureType.BACK_GESTURE
+import com.google.common.truth.Truth.assertThat
+import java.io.File
+import javax.inject.Provider
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TemporaryFolder
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ContextualEducationRepositoryTest : SysuiTestCase() {
+
+    private lateinit var underTest: ContextualEducationRepository
+    private val kosmos = Kosmos()
+    private val testScope = kosmos.testScope
+    private val dsScopeProvider: Provider<CoroutineScope> = Provider {
+        TestScope(kosmos.testDispatcher).backgroundScope
+    }
+    private val testUserId = 1111
+
+    // For deleting any test files created after the test
+    @get:Rule val tmpFolder: TemporaryFolder = TemporaryFolder.builder().assureDeletion().build()
+
+    @Before
+    fun setUp() {
+        // Create TestContext here because TemporaryFolder.create() is called in @Before. It is
+        // needed before calling TemporaryFolder.newFolder().
+        val testContext = TestContext(context, tmpFolder.newFolder())
+        val userRepository = UserContextualEducationRepository(testContext, dsScopeProvider)
+        underTest = ContextualEducationRepository(userRepository)
+        underTest.setUser(testUserId)
+    }
+
+    @Test
+    fun changeRetrievedValueForNewUser() =
+        testScope.runTest {
+            // Update data for old user.
+            underTest.incrementSignalCount(BACK_GESTURE)
+            val model by collectLastValue(underTest.readGestureEduModelFlow(BACK_GESTURE))
+            assertThat(model?.signalCount).isEqualTo(1)
+
+            // User is changed.
+            underTest.setUser(1112)
+            // Assert count is 0 after user is changed.
+            assertThat(model?.signalCount).isEqualTo(0)
+        }
+
+    @Test
+    fun incrementSignalCount() =
+        testScope.runTest {
+            underTest.incrementSignalCount(BACK_GESTURE)
+            val model by collectLastValue(underTest.readGestureEduModelFlow(BACK_GESTURE))
+            assertThat(model?.signalCount).isEqualTo(1)
+        }
+
+    /** Test context which allows overriding getFilesDir path */
+    private class TestContext(context: Context, private val folder: File) :
+        SysuiTestableContext(context) {
+        override fun getFilesDir(): File {
+            return folder
+        }
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt
index 3d3c778..74eee9b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/qs/QSLongPressEffectTest.kt
@@ -144,7 +144,7 @@
             longPressEffect.handleActionUp()
 
             // THEN the effect reverses
-            assertEffectReverses()
+            assertEffectReverses(QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_UP)
         }
 
     @Test
@@ -171,18 +171,17 @@
             longPressEffect.handleActionCancel()
 
             // THEN the effect gets reversed
-            assertEffectReverses()
+            assertEffectReverses(QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_CANCEL)
         }
 
     @Test
-    fun onAnimationComplete_keyguardDismissible_effectEndsWithPrepare() =
+    fun onAnimationComplete_keyguardDismissible_effectCompletes() =
         testWhileInState(QSLongPressEffect.State.RUNNING_FORWARD) {
             // GIVEN that the animation completes
             longPressEffect.handleAnimationComplete()
 
-            // THEN the long-press effect completes and the view is called to prepare
+            // THEN the long-press effect completes
             assertEffectCompleted()
-            verify(callback, times(1)).onPrepareForLaunch()
         }
 
     @Test
@@ -200,6 +199,26 @@
         }
 
     @Test
+    fun onAnimationComplete_whenRunningBackwardsFromUp_endsWithFinishedReversing() =
+        testWhileInState(QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_UP) {
+            // GIVEN that the animation completes
+            longPressEffect.handleAnimationComplete()
+
+            // THEN the callback for finished reversing is used.
+            verify(callback, times(1)).onEffectFinishedReversing()
+        }
+
+    @Test
+    fun onAnimationComplete_whenRunningBackwardsFromCancel_endsInIdle() =
+        testWhileInState(QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_CANCEL) {
+            // GIVEN that the animation completes
+            longPressEffect.handleAnimationComplete()
+
+            // THEN the effect ends in the idle state.
+            assertThat(longPressEffect.state).isEqualTo(QSLongPressEffect.State.IDLE)
+        }
+
+    @Test
     fun onActionDown_whileRunningBackwards_cancels() =
         testWhileInState(QSLongPressEffect.State.RUNNING_FORWARD) {
             // GIVEN an action cancel occurs and the effect gets reversed
@@ -223,11 +242,8 @@
         }
 
     @Test
-    fun onAnimationComplete_whileRunningBackwards_goesToIdle() =
-        testWhileInState(QSLongPressEffect.State.RUNNING_BACKWARDS) {
-            // GIVEN an action cancel occurs and the effect gets reversed
-            longPressEffect.handleActionCancel()
-
+    fun onAnimationComplete_whileRunningBackwardsFromCancel_goesToIdle() =
+        testWhileInState(QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_CANCEL) {
             // GIVEN that the animation completes
             longPressEffect.handleAnimationComplete()
 
@@ -307,12 +323,16 @@
     /**
      * Asserts that the effect did not start by checking that:
      * 1. No haptics are played
-     * 2. The internal state is not [QSLongPressEffect.State.RUNNING_BACKWARDS] or
-     *    [QSLongPressEffect.State.RUNNING_FORWARD]
+     * 2. The internal state is not [QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_UP] or
+     *    [QSLongPressEffect.State.RUNNING_FORWARD] or
+     *    [QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_CANCEL]
      */
     private fun assertEffectDidNotStart() {
         assertThat(longPressEffect.state).isNotEqualTo(QSLongPressEffect.State.RUNNING_FORWARD)
-        assertThat(longPressEffect.state).isNotEqualTo(QSLongPressEffect.State.RUNNING_BACKWARDS)
+        assertThat(longPressEffect.state)
+            .isNotEqualTo(QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_UP)
+        assertThat(longPressEffect.state)
+            .isNotEqualTo(QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_CANCEL)
         assertThat(vibratorHelper.totalVibrations).isEqualTo(0)
     }
 
@@ -330,12 +350,14 @@
     }
 
     /**
-     * Assert that the effect gets reverted by checking that:
-     * 1. The internal state is [QSLongPressEffect.State.RUNNING_BACKWARDS]
-     * 2. An action to reverse the animator is emitted
+     * Assert that the effect gets reverted by checking that the callback to reverse the animator is
+     * used, and that the state is given reversing state.
+     *
+     * @param[reversingState] Either [QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_CANCEL] or
+     *   [QSLongPressEffect.State.RUNNING_BACKWARDS_FROM_UP]
      */
-    private fun assertEffectReverses() {
-        assertThat(longPressEffect.state).isEqualTo(QSLongPressEffect.State.RUNNING_BACKWARDS)
+    private fun assertEffectReverses(reversingState: QSLongPressEffect.State) {
+        assertThat(longPressEffect.state).isEqualTo(reversingState)
         verify(callback, times(1)).onReverseAnimator()
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
index 977f1db..bbfaf6f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
@@ -24,7 +24,7 @@
 import android.provider.Settings.Secure.ZEN_DURATION_PROMPT
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.settingslib.notification.EnableZenModeDialog
+import com.android.settingslib.notification.modes.EnableZenModeDialog
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.ContentDescription
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
index 49d0399..26fcb23 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
@@ -90,7 +90,6 @@
                             .thenReturn(FakeSharedPreferences())
                     },
                 userTracker = FakeUserTracker(),
-                systemSettings = FakeSettings(),
                 broadcastDispatcher = fakeBroadcastDispatcher,
             )
         settings = FakeSettings()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
index 9ab1ac1..0f3e78b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
@@ -29,7 +29,6 @@
 import com.android.systemui.settings.UserFileManager
 import com.android.systemui.util.FakeSharedPreferences
 import com.android.systemui.util.mockito.whenever
-import com.android.systemui.util.settings.FakeSettings
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -81,7 +80,6 @@
                 context = context,
                 userFileManager = userFileManager,
                 userTracker = userTracker,
-                systemSettings = FakeSettings(),
                 broadcastDispatcher = fakeBroadcastDispatcher,
             )
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
index 4587ea6..c5ba02d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
@@ -528,6 +528,30 @@
     }
 
     @Test
+    fun userChange_isFingerprintEnrolledAndEnabledUpdated() =
+        testScope.runTest {
+            createBiometricSettingsRepository()
+            whenever(authController.isFingerprintEnrolled(ANOTHER_USER_ID)).thenReturn(false)
+            whenever(authController.isFingerprintEnrolled(PRIMARY_USER_ID)).thenReturn(true)
+
+            verify(biometricManager)
+                .registerEnabledOnKeyguardCallback(biometricManagerCallback.capture())
+            val isFingerprintEnrolledAndEnabled =
+                collectLastValue(underTest.isFingerprintEnrolledAndEnabled)
+            biometricManagerCallback.value.onChanged(true, ANOTHER_USER_ID)
+            runCurrent()
+            userRepository.setSelectedUserInfo(ANOTHER_USER)
+            runCurrent()
+            assertThat(isFingerprintEnrolledAndEnabled()).isFalse()
+
+            biometricManagerCallback.value.onChanged(true, PRIMARY_USER_ID)
+            runCurrent()
+            userRepository.setSelectedUserInfo(PRIMARY_USER)
+            runCurrent()
+            assertThat(isFingerprintEnrolledAndEnabled()).isTrue()
+        }
+
+    @Test
     fun userChange_biometricEnabledChange_handlesRaceCondition() =
         testScope.runTest {
             createBiometricSettingsRepository()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
index 159ce36..8e109b4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
@@ -91,7 +91,6 @@
                             .thenReturn(FakeSharedPreferences())
                     },
                 userTracker = userTracker,
-                systemSettings = FakeSettings(),
                 broadcastDispatcher = fakeBroadcastDispatcher,
             )
         client1 = FakeCustomizationProviderClient()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
index 5dac37a..bd6cfff 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
@@ -20,6 +20,7 @@
 import android.hardware.biometrics.BiometricSourceType
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.internal.widget.LockPatternUtils
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.systemui.SysuiTestCase
@@ -73,6 +74,7 @@
     @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
     @Mock private lateinit var dreamOverlayCallbackController: DreamOverlayCallbackController
     @Mock private lateinit var userTracker: UserTracker
+    @Mock private lateinit var lockPatternUtils: LockPatternUtils
     @Captor private lateinit var updateCallbackCaptor: ArgumentCaptor<KeyguardUpdateMonitorCallback>
     private val mainDispatcher = StandardTestDispatcher()
     private val testDispatcher = StandardTestDispatcher()
@@ -100,6 +102,7 @@
                 systemClock,
                 facePropertyRepository,
                 userTracker,
+                lockPatternUtils,
             )
     }
 
@@ -140,6 +143,27 @@
         }
 
     @Test
+    fun panelAlpha() =
+        testScope.runTest {
+            assertThat(underTest.panelAlpha.value).isEqualTo(1f)
+
+            underTest.setPanelAlpha(0.1f)
+            assertThat(underTest.panelAlpha.value).isEqualTo(0.1f)
+
+            underTest.setPanelAlpha(0.2f)
+            assertThat(underTest.panelAlpha.value).isEqualTo(0.2f)
+
+            underTest.setPanelAlpha(0.3f)
+            assertThat(underTest.panelAlpha.value).isEqualTo(0.3f)
+
+            underTest.setPanelAlpha(0.5f)
+            assertThat(underTest.panelAlpha.value).isEqualTo(0.5f)
+
+            underTest.setPanelAlpha(1.0f)
+            assertThat(underTest.panelAlpha.value).isEqualTo(1f)
+        }
+
+    @Test
     fun topClippingBounds() =
         testScope.runTest {
             assertThat(underTest.topClippingBounds.value).isNull()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
index 5f0f24d..2d12150 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
@@ -30,6 +30,7 @@
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -61,7 +62,8 @@
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
-        testScope = TestScope()
+        val testDispatcher = StandardTestDispatcher()
+        testScope = TestScope(testDispatcher)
         userRepository = FakeUserRepository()
         userRepository.setUserInfos(users)
         val logger =
@@ -69,7 +71,13 @@
                 LogBuffer("TestBuffer", 1, mock(LogcatEchoTracker::class.java), false)
             )
         underTest =
-            TrustRepositoryImpl(testScope.backgroundScope, userRepository, trustManager, logger)
+            TrustRepositoryImpl(
+                testScope.backgroundScope,
+                testDispatcher,
+                userRepository,
+                trustManager,
+                logger,
+            )
     }
 
     fun TestScope.init() {
@@ -275,4 +283,11 @@
             userRepository.setSelectedUserInfo(users[1])
             assertThat(trustUsuallyManaged).isFalse()
         }
+
+    @Test
+    fun reportKeyguardShowingChanged() =
+        testScope.runTest {
+            underTest.reportKeyguardShowingChanged()
+            verify(trustManager).reportKeyguardShowingChanged()
+        }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorTest.kt
index d20fec4..5115f5a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorTest.kt
@@ -90,7 +90,11 @@
             )
             reset(transitionRepository)
 
+            kosmos.fakeKeyguardBouncerRepository.setKeyguardAuthenticatedBiometrics(null)
             kosmos.fakeKeyguardRepository.setKeyguardOccluded(true)
+            runCurrent()
+            assertThat(transitionRepository).noTransitionsStarted()
+
             kosmos.fakeKeyguardBouncerRepository.setKeyguardAuthenticatedBiometrics(true)
             runCurrent()
             kosmos.fakeKeyguardBouncerRepository.setKeyguardAuthenticatedBiometrics(null)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
deleted file mode 100644
index 9d34903..0000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.keyguard.domain.interactor
-
-import android.content.Intent
-import android.view.accessibility.accessibilityManagerWrapper
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.internal.logging.testing.UiEventLoggerFake
-import com.android.internal.logging.uiEventLogger
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.flags.Flags
-import com.android.systemui.flags.fakeFeatureFlagsClassic
-import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
-import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.shared.model.KeyguardState
-import com.android.systemui.kosmos.testScope
-import com.android.systemui.res.R
-import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
-import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.whenever
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.test.advanceTimeBy
-import kotlinx.coroutines.test.runCurrent
-import kotlinx.coroutines.test.runTest
-import org.junit.After
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentMatchers.anyInt
-import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
-
-@OptIn(ExperimentalCoroutinesApi::class)
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class KeyguardLongPressInteractorTest : SysuiTestCase() {
-    private val kosmos =
-        testKosmos().apply {
-            this.accessibilityManagerWrapper = mock<AccessibilityManagerWrapper>()
-            this.uiEventLogger = mock<UiEventLoggerFake>()
-        }
-
-    private lateinit var underTest: KeyguardLongPressInteractor
-
-    private val logger = kosmos.uiEventLogger
-    private val testScope = kosmos.testScope
-    private val keyguardRepository = kosmos.fakeKeyguardRepository
-    private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
-
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-        overrideResource(R.bool.long_press_keyguard_customize_lockscreen_enabled, true)
-        whenever(kosmos.accessibilityManagerWrapper.getRecommendedTimeoutMillis(anyInt(), anyInt()))
-            .thenAnswer { it.arguments[0] }
-
-        runBlocking { createUnderTest() }
-    }
-
-    @After
-    fun tearDown() {
-        mContext
-            .getOrCreateTestableResources()
-            .removeOverride(R.bool.long_press_keyguard_customize_lockscreen_enabled)
-    }
-
-    @Test
-    fun isEnabled() =
-        testScope.runTest {
-            val isEnabled = collectLastValue(underTest.isLongPressHandlingEnabled)
-            KeyguardState.values().forEach { keyguardState ->
-                setUpState(
-                    keyguardState = keyguardState,
-                )
-
-                if (keyguardState == KeyguardState.LOCKSCREEN) {
-                    assertThat(isEnabled()).isTrue()
-                } else {
-                    assertThat(isEnabled()).isFalse()
-                }
-            }
-        }
-
-    @Test
-    fun isEnabled_alwaysFalseWhenQuickSettingsAreVisible() =
-        testScope.runTest {
-            val isEnabled = collectLastValue(underTest.isLongPressHandlingEnabled)
-            KeyguardState.values().forEach { keyguardState ->
-                setUpState(
-                    keyguardState = keyguardState,
-                    isQuickSettingsVisible = true,
-                )
-
-                assertThat(isEnabled()).isFalse()
-            }
-        }
-
-    @Test
-    fun isEnabled_alwaysFalseWhenConfigEnabledBooleanIsFalse() =
-        testScope.runTest {
-            overrideResource(R.bool.long_press_keyguard_customize_lockscreen_enabled, false)
-            createUnderTest()
-            val isEnabled by collectLastValue(underTest.isLongPressHandlingEnabled)
-            runCurrent()
-
-            assertThat(isEnabled).isFalse()
-        }
-
-    @Test
-    fun longPressed_menuClicked_showsSettings() =
-        testScope.runTest {
-            val isMenuVisible by collectLastValue(underTest.isMenuVisible)
-            val shouldOpenSettings by collectLastValue(underTest.shouldOpenSettings)
-            runCurrent()
-
-            underTest.onLongPress()
-            assertThat(isMenuVisible).isTrue()
-
-            underTest.onMenuTouchGestureEnded(/* isClick= */ true)
-
-            assertThat(isMenuVisible).isFalse()
-            assertThat(shouldOpenSettings).isTrue()
-        }
-
-    @Test
-    fun onSettingsShown_consumesSettingsShowEvent() =
-        testScope.runTest {
-            val shouldOpenSettings by collectLastValue(underTest.shouldOpenSettings)
-            runCurrent()
-
-            underTest.onLongPress()
-            underTest.onMenuTouchGestureEnded(/* isClick= */ true)
-            assertThat(shouldOpenSettings).isTrue()
-
-            underTest.onSettingsShown()
-            assertThat(shouldOpenSettings).isFalse()
-        }
-
-    @Test
-    fun onTouchedOutside_neverShowsSettings() =
-        testScope.runTest {
-            val isMenuVisible by collectLastValue(underTest.isMenuVisible)
-            val shouldOpenSettings by collectLastValue(underTest.shouldOpenSettings)
-            runCurrent()
-
-            underTest.onTouchedOutside()
-
-            assertThat(isMenuVisible).isFalse()
-            assertThat(shouldOpenSettings).isFalse()
-        }
-
-    @Test
-    fun longPressed_openWppDirectlyEnabled_doesNotShowMenu_opensSettings() =
-        testScope.runTest {
-            createUnderTest(isOpenWppDirectlyEnabled = true)
-            val isMenuVisible by collectLastValue(underTest.isMenuVisible)
-            val shouldOpenSettings by collectLastValue(underTest.shouldOpenSettings)
-            runCurrent()
-
-            underTest.onLongPress()
-
-            assertThat(isMenuVisible).isFalse()
-            assertThat(shouldOpenSettings).isTrue()
-        }
-
-    @Test
-    fun longPressed_closeDialogsBroadcastReceived_popupDismissed() =
-        testScope.runTest {
-            val isMenuVisible by collectLastValue(underTest.isMenuVisible)
-            runCurrent()
-
-            underTest.onLongPress()
-            assertThat(isMenuVisible).isTrue()
-
-            fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
-                context,
-                Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS),
-            )
-
-            assertThat(isMenuVisible).isFalse()
-        }
-
-    @Test
-    fun closesDialogAfterTimeout() =
-        testScope.runTest {
-            val isMenuVisible by collectLastValue(underTest.isMenuVisible)
-            runCurrent()
-
-            underTest.onLongPress()
-            assertThat(isMenuVisible).isTrue()
-
-            advanceTimeBy(KeyguardLongPressInteractor.DEFAULT_POPUP_AUTO_HIDE_TIMEOUT_MS)
-
-            assertThat(isMenuVisible).isFalse()
-        }
-
-    @Test
-    fun closesDialogAfterTimeout_onlyAfterTouchGestureEnded() =
-        testScope.runTest {
-            val isMenuVisible by collectLastValue(underTest.isMenuVisible)
-            runCurrent()
-
-            underTest.onLongPress()
-            assertThat(isMenuVisible).isTrue()
-            underTest.onMenuTouchGestureStarted()
-
-            advanceTimeBy(KeyguardLongPressInteractor.DEFAULT_POPUP_AUTO_HIDE_TIMEOUT_MS)
-            assertThat(isMenuVisible).isTrue()
-
-            underTest.onMenuTouchGestureEnded(/* isClick= */ false)
-            advanceTimeBy(KeyguardLongPressInteractor.DEFAULT_POPUP_AUTO_HIDE_TIMEOUT_MS)
-            assertThat(isMenuVisible).isFalse()
-        }
-
-    @Test
-    fun logsWhenMenuIsShown() =
-        testScope.runTest {
-            collectLastValue(underTest.isMenuVisible)
-            runCurrent()
-
-            underTest.onLongPress()
-
-            verify(logger)
-                .log(KeyguardLongPressInteractor.LogEvents.LOCK_SCREEN_LONG_PRESS_POPUP_SHOWN)
-        }
-
-    @Test
-    fun logsWhenMenuIsClicked() =
-        testScope.runTest {
-            collectLastValue(underTest.isMenuVisible)
-            runCurrent()
-
-            underTest.onLongPress()
-            underTest.onMenuTouchGestureEnded(/* isClick= */ true)
-
-            verify(logger)
-                .log(KeyguardLongPressInteractor.LogEvents.LOCK_SCREEN_LONG_PRESS_POPUP_CLICKED)
-        }
-
-    @Test
-    fun showMenu_leaveLockscreen_returnToLockscreen_menuNotVisible() =
-        testScope.runTest {
-            val isMenuVisible by collectLastValue(underTest.isMenuVisible)
-            runCurrent()
-            underTest.onLongPress()
-            assertThat(isMenuVisible).isTrue()
-
-            keyguardTransitionRepository.sendTransitionSteps(
-                from = KeyguardState.LOCKSCREEN,
-                to = KeyguardState.GONE,
-                testScope
-            )
-            assertThat(isMenuVisible).isFalse()
-
-            keyguardTransitionRepository.sendTransitionSteps(
-                from = KeyguardState.GONE,
-                to = KeyguardState.LOCKSCREEN,
-                testScope
-            )
-            assertThat(isMenuVisible).isFalse()
-        }
-
-    private suspend fun createUnderTest(
-        isLongPressFeatureEnabled: Boolean = true,
-        isRevampedWppFeatureEnabled: Boolean = true,
-        isOpenWppDirectlyEnabled: Boolean = false,
-    ) {
-        // This needs to be re-created for each test outside of kosmos since the flag values are
-        // read during initialization to set up flows. Maybe there is a better way to handle that.
-        underTest =
-            KeyguardLongPressInteractor(
-                appContext = mContext,
-                scope = testScope.backgroundScope,
-                transitionInteractor = kosmos.keyguardTransitionInteractor,
-                repository = keyguardRepository,
-                logger = logger,
-                featureFlags =
-                    kosmos.fakeFeatureFlagsClassic.apply {
-                        set(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED, isLongPressFeatureEnabled)
-                        set(Flags.LOCK_SCREEN_LONG_PRESS_DIRECT_TO_WPP, isOpenWppDirectlyEnabled)
-                    },
-                broadcastDispatcher = fakeBroadcastDispatcher,
-                accessibilityManager = kosmos.accessibilityManagerWrapper
-            )
-        setUpState()
-    }
-
-    private suspend fun setUpState(
-        keyguardState: KeyguardState = KeyguardState.LOCKSCREEN,
-        isQuickSettingsVisible: Boolean = false,
-    ) {
-        keyguardTransitionRepository.sendTransitionSteps(
-            from = KeyguardState.AOD,
-            to = keyguardState,
-            testScope = testScope
-        )
-        keyguardRepository.setQuickSettingsVisible(isVisible = isQuickSettingsVisible)
-    }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractorTest.kt
index 0f5e458..8914c80 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractorTest.kt
@@ -41,6 +41,7 @@
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
+import com.android.systemui.flags.DisableSceneContainer
 import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.data.repository.deviceEntryFingerprintAuthRepository
@@ -54,6 +55,9 @@
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
 import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.scene.data.repository.Transition
+import com.android.systemui.scene.data.repository.setSceneTransition
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
@@ -208,6 +212,7 @@
         }
 
     @Test
+    @DisableSceneContainer
     fun showWhenLockedActivityLaunchedFromPowerGesture_falseIfReturningToGone() =
         testScope.runTest {
             val values by collectValues(underTest.showWhenLockedActivityLaunchedFromPowerGesture)
@@ -245,6 +250,42 @@
 
     @Test
     @EnableSceneContainer
+    fun showWhenLockedActivityLaunchedFromPowerGesture_falseIfReturningToGone_scene_container() =
+        testScope.runTest {
+            val values by collectValues(underTest.showWhenLockedActivityLaunchedFromPowerGesture)
+            powerInteractor.setAwakeForTest()
+            kosmos.setSceneTransition(Transition(Scenes.Lockscreen, Scenes.Gone))
+
+            powerInteractor.setAsleepForTest()
+
+            kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Lockscreen))
+            transitionRepository.sendTransitionSteps(
+                from = KeyguardState.UNDEFINED,
+                to = KeyguardState.AOD,
+                testScope = testScope,
+                throughTransitionState = TransitionState.RUNNING
+            )
+
+            powerInteractor.onCameraLaunchGestureDetected()
+            kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true)
+            powerInteractor.setAwakeForTest()
+            runCurrent()
+
+            kosmos.setSceneTransition(Transition(Scenes.Lockscreen, Scenes.Gone))
+            transitionRepository.sendTransitionSteps(
+                from = KeyguardState.AOD,
+                to = KeyguardState.UNDEFINED,
+                testScope = testScope,
+            )
+
+            assertThat(values)
+                .containsExactly(
+                    false,
+                )
+        }
+
+    @Test
+    @EnableSceneContainer
     fun occludingActivityWillDismissKeyguard() =
         testScope.runTest {
             val occludingActivityWillDismissKeyguard by
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
index 78a1167..2d77f4f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
@@ -148,7 +148,6 @@
                             .thenReturn(FakeSharedPreferences())
                     },
                 userTracker = userTracker,
-                systemSettings = FakeSettings(),
                 broadcastDispatcher = fakeBroadcastDispatcher,
             )
         val remoteUserSelectionManager =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt
new file mode 100644
index 0000000..96b4b43
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractorTest.kt
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyguard.domain.interactor
+
+import android.content.Intent
+import android.view.accessibility.accessibilityManagerWrapper
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.internal.logging.uiEventLogger
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fakeFeatureFlagsClassic
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.res.R
+import com.android.systemui.shade.pulsingGestureListener
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
+import com.android.systemui.testKosmos
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class KeyguardTouchHandlingInteractorTest : SysuiTestCase() {
+    private val kosmos =
+        testKosmos().apply {
+            this.accessibilityManagerWrapper = mock<AccessibilityManagerWrapper>()
+            this.uiEventLogger = mock<UiEventLoggerFake>()
+        }
+
+    private lateinit var underTest: KeyguardTouchHandlingInteractor
+
+    private val logger = kosmos.uiEventLogger
+    private val testScope = kosmos.testScope
+    private val keyguardRepository = kosmos.fakeKeyguardRepository
+    private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        overrideResource(R.bool.long_press_keyguard_customize_lockscreen_enabled, true)
+        whenever(kosmos.accessibilityManagerWrapper.getRecommendedTimeoutMillis(anyInt(), anyInt()))
+            .thenAnswer { it.arguments[0] }
+
+        runBlocking { createUnderTest() }
+    }
+
+    @After
+    fun tearDown() {
+        mContext
+            .getOrCreateTestableResources()
+            .removeOverride(R.bool.long_press_keyguard_customize_lockscreen_enabled)
+    }
+
+    @Test
+    fun isEnabled() =
+        testScope.runTest {
+            val isEnabled = collectLastValue(underTest.isLongPressHandlingEnabled)
+            KeyguardState.values().forEach { keyguardState ->
+                setUpState(
+                    keyguardState = keyguardState,
+                )
+
+                if (keyguardState == KeyguardState.LOCKSCREEN) {
+                    assertThat(isEnabled()).isTrue()
+                } else {
+                    assertThat(isEnabled()).isFalse()
+                }
+            }
+        }
+
+    @Test
+    fun isEnabled_alwaysFalseWhenQuickSettingsAreVisible() =
+        testScope.runTest {
+            val isEnabled = collectLastValue(underTest.isLongPressHandlingEnabled)
+            KeyguardState.values().forEach { keyguardState ->
+                setUpState(
+                    keyguardState = keyguardState,
+                    isQuickSettingsVisible = true,
+                )
+
+                assertThat(isEnabled()).isFalse()
+            }
+        }
+
+    @Test
+    fun isEnabled_alwaysFalseWhenConfigEnabledBooleanIsFalse() =
+        testScope.runTest {
+            overrideResource(R.bool.long_press_keyguard_customize_lockscreen_enabled, false)
+            createUnderTest()
+            val isEnabled by collectLastValue(underTest.isLongPressHandlingEnabled)
+            runCurrent()
+
+            assertThat(isEnabled).isFalse()
+        }
+
+    @Test
+    fun longPressed_menuClicked_showsSettings() =
+        testScope.runTest {
+            val isMenuVisible by collectLastValue(underTest.isMenuVisible)
+            val shouldOpenSettings by collectLastValue(underTest.shouldOpenSettings)
+            runCurrent()
+
+            underTest.onLongPress()
+            assertThat(isMenuVisible).isTrue()
+
+            underTest.onMenuTouchGestureEnded(/* isClick= */ true)
+
+            assertThat(isMenuVisible).isFalse()
+            assertThat(shouldOpenSettings).isTrue()
+        }
+
+    @Test
+    fun onSettingsShown_consumesSettingsShowEvent() =
+        testScope.runTest {
+            val shouldOpenSettings by collectLastValue(underTest.shouldOpenSettings)
+            runCurrent()
+
+            underTest.onLongPress()
+            underTest.onMenuTouchGestureEnded(/* isClick= */ true)
+            assertThat(shouldOpenSettings).isTrue()
+
+            underTest.onSettingsShown()
+            assertThat(shouldOpenSettings).isFalse()
+        }
+
+    @Test
+    fun onTouchedOutside_neverShowsSettings() =
+        testScope.runTest {
+            val isMenuVisible by collectLastValue(underTest.isMenuVisible)
+            val shouldOpenSettings by collectLastValue(underTest.shouldOpenSettings)
+            runCurrent()
+
+            underTest.onTouchedOutside()
+
+            assertThat(isMenuVisible).isFalse()
+            assertThat(shouldOpenSettings).isFalse()
+        }
+
+    @Test
+    fun longPressed_openWppDirectlyEnabled_doesNotShowMenu_opensSettings() =
+        testScope.runTest {
+            createUnderTest(isOpenWppDirectlyEnabled = true)
+            val isMenuVisible by collectLastValue(underTest.isMenuVisible)
+            val shouldOpenSettings by collectLastValue(underTest.shouldOpenSettings)
+            runCurrent()
+
+            underTest.onLongPress()
+
+            assertThat(isMenuVisible).isFalse()
+            assertThat(shouldOpenSettings).isTrue()
+        }
+
+    @Test
+    fun longPressed_closeDialogsBroadcastReceived_popupDismissed() =
+        testScope.runTest {
+            val isMenuVisible by collectLastValue(underTest.isMenuVisible)
+            runCurrent()
+
+            underTest.onLongPress()
+            assertThat(isMenuVisible).isTrue()
+
+            fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+                context,
+                Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS),
+            )
+
+            assertThat(isMenuVisible).isFalse()
+        }
+
+    @Test
+    fun closesDialogAfterTimeout() =
+        testScope.runTest {
+            val isMenuVisible by collectLastValue(underTest.isMenuVisible)
+            runCurrent()
+
+            underTest.onLongPress()
+            assertThat(isMenuVisible).isTrue()
+
+            advanceTimeBy(KeyguardTouchHandlingInteractor.DEFAULT_POPUP_AUTO_HIDE_TIMEOUT_MS)
+
+            assertThat(isMenuVisible).isFalse()
+        }
+
+    @Test
+    fun closesDialogAfterTimeout_onlyAfterTouchGestureEnded() =
+        testScope.runTest {
+            val isMenuVisible by collectLastValue(underTest.isMenuVisible)
+            runCurrent()
+
+            underTest.onLongPress()
+            assertThat(isMenuVisible).isTrue()
+            underTest.onMenuTouchGestureStarted()
+
+            advanceTimeBy(KeyguardTouchHandlingInteractor.DEFAULT_POPUP_AUTO_HIDE_TIMEOUT_MS)
+            assertThat(isMenuVisible).isTrue()
+
+            underTest.onMenuTouchGestureEnded(/* isClick= */ false)
+            advanceTimeBy(KeyguardTouchHandlingInteractor.DEFAULT_POPUP_AUTO_HIDE_TIMEOUT_MS)
+            assertThat(isMenuVisible).isFalse()
+        }
+
+    @Test
+    fun logsWhenMenuIsShown() =
+        testScope.runTest {
+            collectLastValue(underTest.isMenuVisible)
+            runCurrent()
+
+            underTest.onLongPress()
+
+            verify(logger)
+                .log(KeyguardTouchHandlingInteractor.LogEvents.LOCK_SCREEN_LONG_PRESS_POPUP_SHOWN)
+        }
+
+    @Test
+    fun logsWhenMenuIsClicked() =
+        testScope.runTest {
+            collectLastValue(underTest.isMenuVisible)
+            runCurrent()
+
+            underTest.onLongPress()
+            underTest.onMenuTouchGestureEnded(/* isClick= */ true)
+
+            verify(logger)
+                .log(KeyguardTouchHandlingInteractor.LogEvents.LOCK_SCREEN_LONG_PRESS_POPUP_CLICKED)
+        }
+
+    @Test
+    fun showMenu_leaveLockscreen_returnToLockscreen_menuNotVisible() =
+        testScope.runTest {
+            val isMenuVisible by collectLastValue(underTest.isMenuVisible)
+            runCurrent()
+            underTest.onLongPress()
+            assertThat(isMenuVisible).isTrue()
+
+            keyguardTransitionRepository.sendTransitionSteps(
+                from = KeyguardState.LOCKSCREEN,
+                to = KeyguardState.GONE,
+                testScope
+            )
+            assertThat(isMenuVisible).isFalse()
+
+            keyguardTransitionRepository.sendTransitionSteps(
+                from = KeyguardState.GONE,
+                to = KeyguardState.LOCKSCREEN,
+                testScope
+            )
+            assertThat(isMenuVisible).isFalse()
+        }
+
+    private suspend fun createUnderTest(
+        isLongPressFeatureEnabled: Boolean = true,
+        isRevampedWppFeatureEnabled: Boolean = true,
+        isOpenWppDirectlyEnabled: Boolean = false,
+    ) {
+        // This needs to be re-created for each test outside of kosmos since the flag values are
+        // read during initialization to set up flows. Maybe there is a better way to handle that.
+        underTest =
+            KeyguardTouchHandlingInteractor(
+                appContext = mContext,
+                scope = testScope.backgroundScope,
+                transitionInteractor = kosmos.keyguardTransitionInteractor,
+                repository = keyguardRepository,
+                logger = logger,
+                featureFlags =
+                    kosmos.fakeFeatureFlagsClassic.apply {
+                        set(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED, isLongPressFeatureEnabled)
+                        set(Flags.LOCK_SCREEN_LONG_PRESS_DIRECT_TO_WPP, isOpenWppDirectlyEnabled)
+                    },
+                broadcastDispatcher = fakeBroadcastDispatcher,
+                accessibilityManager = kosmos.accessibilityManagerWrapper,
+                pulsingGestureListener = kosmos.pulsingGestureListener,
+            )
+        setUpState()
+    }
+
+    private suspend fun setUpState(
+        keyguardState: KeyguardState = KeyguardState.LOCKSCREEN,
+        isQuickSettingsVisible: Boolean = false,
+    ) {
+        keyguardTransitionRepository.sendTransitionSteps(
+            from = KeyguardState.AOD,
+            to = keyguardState,
+            testScope = testScope
+        )
+        keyguardRepository.setQuickSettingsVisible(isVisible = isQuickSettingsVisible)
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
index 0f061de..a8eccc5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
@@ -19,7 +19,6 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectValues
 import com.android.systemui.flags.DisableSceneContainer
@@ -42,19 +41,15 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.scene.data.repository.Idle
 import com.android.systemui.scene.data.repository.Transition
-import com.android.systemui.scene.data.repository.sceneContainerRepository
 import com.android.systemui.scene.data.repository.setSceneTransition
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import junit.framework.Assert.assertEquals
 import kotlinx.coroutines.flow.MutableSharedFlow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Assert.assertThrows
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -67,36 +62,6 @@
     val repository = kosmos.fakeKeyguardTransitionRepository
     val testScope = kosmos.testScope
 
-    private val sceneTransitions =
-        MutableStateFlow<ObservableTransitionState>(
-            ObservableTransitionState.Idle(Scenes.Lockscreen)
-        )
-
-    private val lsToGone =
-        ObservableTransitionState.Transition(
-            Scenes.Lockscreen,
-            Scenes.Gone,
-            flowOf(Scenes.Lockscreen),
-            flowOf(0f),
-            false,
-            flowOf(false)
-        )
-
-    private val goneToLs =
-        ObservableTransitionState.Transition(
-            Scenes.Gone,
-            Scenes.Lockscreen,
-            flowOf(Scenes.Lockscreen),
-            flowOf(0f),
-            false,
-            flowOf(false)
-        )
-
-    @Before
-    fun setUp() {
-        kosmos.sceneContainerRepository.setTransitionState(sceneTransitions)
-    }
-
     @Test
     fun transitionCollectorsReceivesOnlyAppropriateEvents() =
         testScope.runTest {
@@ -318,7 +283,7 @@
     @Test
     fun isInTransitionToAnyState() =
         testScope.runTest {
-            val inTransition by collectValues(underTest.isInTransitionToAnyState)
+            val inTransition by collectValues(underTest.isInTransition)
 
             assertEquals(
                 listOf(
@@ -374,9 +339,50 @@
         }
 
     @Test
+    @EnableSceneContainer
+    fun isInTransition_withScene() =
+        testScope.runTest {
+            val inTransition by collectValues(underTest.isInTransition)
+
+            assertEquals(
+                listOf(
+                    false,
+                    true, // The repo is seeded with a transition from OFF to LOCKSCREEN.
+                    false,
+                ),
+                inTransition
+            )
+
+            kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Bouncer))
+
+            assertEquals(
+                listOf(
+                    false,
+                    true,
+                    false,
+                    true,
+                ),
+                inTransition
+            )
+
+            kosmos.setSceneTransition(Idle(Scenes.Bouncer))
+
+            assertEquals(
+                listOf(
+                    false,
+                    true,
+                    false,
+                    true,
+                    false,
+                ),
+                inTransition
+            )
+        }
+
+    @Test
     fun isInTransitionToAnyState_finishedStateIsStartedStateAfterCancels() =
         testScope.runTest {
-            val inTransition by collectValues(underTest.isInTransitionToAnyState)
+            val inTransition by collectValues(underTest.isInTransition)
 
             assertEquals(
                 listOf(
@@ -731,92 +737,6 @@
         }
 
     @Test
-    fun isInTransitionFromStateWhere() =
-        testScope.runTest {
-            val results by collectValues(underTest.isInTransitionFromStateWhere { it == DOZING })
-
-            sendSteps(
-                TransitionStep(AOD, DOZING, 0f, STARTED),
-                TransitionStep(AOD, DOZING, 0.5f, RUNNING),
-                TransitionStep(AOD, DOZING, 1f, FINISHED),
-            )
-
-            assertThat(results)
-                .isEqualTo(
-                    listOf(
-                        false,
-                    )
-                )
-
-            sendSteps(
-                TransitionStep(DOZING, GONE, 0f, STARTED),
-            )
-
-            assertThat(results)
-                .isEqualTo(
-                    listOf(
-                        false,
-                        true,
-                    )
-                )
-
-            sendSteps(
-                TransitionStep(DOZING, GONE, 0f, RUNNING),
-            )
-
-            assertThat(results)
-                .isEqualTo(
-                    listOf(
-                        false,
-                        true,
-                    )
-                )
-
-            sendSteps(
-                TransitionStep(DOZING, GONE, 0f, FINISHED),
-            )
-
-            assertThat(results)
-                .isEqualTo(
-                    listOf(
-                        false,
-                        true,
-                        false,
-                    )
-                )
-
-            sendSteps(
-                TransitionStep(GONE, DOZING, 0f, STARTED),
-                TransitionStep(GONE, DOZING, 0f, RUNNING),
-                TransitionStep(GONE, DOZING, 1f, FINISHED),
-            )
-
-            assertThat(results)
-                .isEqualTo(
-                    listOf(
-                        false,
-                        true,
-                        false,
-                    )
-                )
-
-            sendSteps(
-                TransitionStep(DOZING, GONE, 0f, STARTED),
-                TransitionStep(DOZING, GONE, 0f, RUNNING),
-            )
-
-            assertThat(results)
-                .isEqualTo(
-                    listOf(
-                        false,
-                        true,
-                        false,
-                        true,
-                    )
-                )
-        }
-
-    @Test
     fun isInTransitionWhere() =
         testScope.runTest {
             val results by
@@ -1097,9 +1017,10 @@
         }
 
     @Test
+    @DisableSceneContainer
     fun isFinishedInState() =
         testScope.runTest {
-            val results by collectValues(underTest.isFinishedInState(GONE))
+            val results by collectValues(underTest.isFinishedIn(Scenes.Gone, GONE))
 
             sendSteps(
                 TransitionStep(AOD, DOZING, 0f, STARTED),
@@ -1194,6 +1115,89 @@
         }
 
     @Test
+    @EnableSceneContainer
+    fun isFinishedIn() =
+        testScope.runTest {
+            val results by collectValues(underTest.isFinishedIn(Scenes.Gone, GONE))
+
+            sendSteps(
+                TransitionStep(AOD, DOZING, 0f, STARTED),
+                TransitionStep(AOD, DOZING, 0.5f, RUNNING),
+                TransitionStep(AOD, DOZING, 1f, FINISHED),
+            )
+
+            assertThat(results)
+                .isEqualTo(
+                    listOf(
+                        false, // Finished in DOZING, not GONE.
+                    )
+                )
+
+            kosmos.setSceneTransition(Transition(from = Scenes.Lockscreen, to = Scenes.Gone))
+
+            assertThat(results)
+                .isEqualTo(
+                    listOf(
+                        false,
+                    )
+                )
+
+            kosmos.setSceneTransition(Idle(Scenes.Gone))
+
+            assertThat(results)
+                .isEqualTo(
+                    listOf(
+                        false,
+                        true,
+                    )
+                )
+
+            kosmos.setSceneTransition(Transition(from = Scenes.Gone, to = Scenes.Lockscreen))
+
+            assertThat(results)
+                .isEqualTo(
+                    listOf(
+                        false,
+                        true,
+                    )
+                )
+
+            kosmos.setSceneTransition(Idle(Scenes.Lockscreen))
+
+            assertThat(results)
+                .isEqualTo(
+                    listOf(
+                        false,
+                        true,
+                        false,
+                    )
+                )
+
+            kosmos.setSceneTransition(Transition(from = Scenes.Lockscreen, to = Scenes.Gone))
+
+            assertThat(results)
+                .isEqualTo(
+                    listOf(
+                        false,
+                        true,
+                        false,
+                    )
+                )
+
+            kosmos.setSceneTransition(Idle(Scenes.Gone))
+
+            assertThat(results)
+                .isEqualTo(
+                    listOf(
+                        false,
+                        true,
+                        false,
+                        true,
+                    )
+                )
+        }
+
+    @Test
     fun finishedKeyguardState_emitsAgainIfCancelledAndReversed() =
         testScope.runTest {
             val finishedStates by collectValues(underTest.finishedKeyguardState)
@@ -1515,7 +1519,7 @@
             val currentStatesConverted by
                 collectValues(underTest.transition(Edge.create(LOCKSCREEN, UNDEFINED)))
 
-            sceneTransitions.value = lsToGone
+            kosmos.setSceneTransition(Transition(Scenes.Lockscreen, Scenes.Gone))
             val sendStep1 = TransitionStep(LOCKSCREEN, UNDEFINED, 0f, STARTED)
             val sendStep2 = TransitionStep(LOCKSCREEN, UNDEFINED, 1f, FINISHED)
             val sendStep3 = TransitionStep(LOCKSCREEN, AOD, 0f, STARTED)
@@ -1531,7 +1535,7 @@
         testScope.runTest {
             val currentStates by collectValues(underTest.transition(Edge.create(LOCKSCREEN, GONE)))
 
-            sceneTransitions.value = goneToLs
+            kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Lockscreen))
             val sendStep1 = TransitionStep(LOCKSCREEN, UNDEFINED, 0f, STARTED)
             val sendStep2 = TransitionStep(LOCKSCREEN, UNDEFINED, 1f, FINISHED)
             val sendStep3 = TransitionStep(LOCKSCREEN, AOD, 0f, STARTED)
@@ -1547,7 +1551,7 @@
             val currentStates by
                 collectValues(underTest.transition(Edge.create(LOCKSCREEN, DOZING)))
 
-            sceneTransitions.value = goneToLs
+            kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Lockscreen))
             val sendStep1 = TransitionStep(LOCKSCREEN, DOZING, 0f, STARTED)
             val sendStep2 = TransitionStep(LOCKSCREEN, DOZING, 1f, FINISHED)
             val sendStep3 = TransitionStep(LOCKSCREEN, AOD, 0f, STARTED)
@@ -1564,7 +1568,7 @@
             val currentStatesReversed by
                 collectValues(underTest.transition(Edge.create(null, LOCKSCREEN)))
 
-            sceneTransitions.value = goneToLs
+            kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Lockscreen))
             val sendStep1 = TransitionStep(LOCKSCREEN, DOZING, 0f, STARTED)
             val sendStep2 = TransitionStep(LOCKSCREEN, DOZING, 1f, FINISHED)
             val sendStep3 = TransitionStep(LOCKSCREEN, AOD, 0f, STARTED)
@@ -1582,7 +1586,7 @@
             val currentStates by collectValues(underTest.transition(Edge.create(null, UNDEFINED)))
             val currentStatesMapped by collectValues(underTest.transition(Edge.create(null, GONE)))
 
-            sceneTransitions.value = lsToGone
+            kosmos.setSceneTransition(Transition(Scenes.Lockscreen, Scenes.Gone))
             val sendStep1 = TransitionStep(LOCKSCREEN, UNDEFINED, 0f, STARTED)
             val sendStep2 = TransitionStep(LOCKSCREEN, UNDEFINED, 1f, FINISHED)
             val sendStep3 = TransitionStep(UNDEFINED, AOD, 0f, STARTED)
@@ -1599,7 +1603,7 @@
         testScope.runTest {
             val currentStatesMapped by collectValues(underTest.transition(Edge.create(null, GONE)))
 
-            sceneTransitions.value = goneToLs
+            kosmos.setSceneTransition(Transition(Scenes.Gone, Scenes.Lockscreen))
             val sendStep1 = TransitionStep(LOCKSCREEN, UNDEFINED, 0f, STARTED)
             val sendStep2 = TransitionStep(LOCKSCREEN, UNDEFINED, 1f, FINISHED)
             val sendStep3 = TransitionStep(UNDEFINED, AOD, 0f, STARTED)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/shared/model/KeyguardStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/shared/model/KeyguardStateTest.kt
new file mode 100644
index 0000000..f1ffe66
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/shared/model/KeyguardStateTest.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyguard.shared.model
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.EnableSceneContainer
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class KeyguardStateTest : SysuiTestCase() {
+
+    /**
+     * This test makes sure that the result of [deviceIsAwakeInState] are equal for all the states
+     * that are obsolete with scene container enabled and UNDEFINED. This means for example that if
+     * GONE is transformed to UNDEFINED it makes sure that GONE and UNDEFINED need to have the same
+     * value. This assumption is important as with scene container flag enabled call sites will only
+     * check the result passing in UNDEFINED.
+     *
+     * This is true today, but as more states may become obsolete this assumption may not be true
+     * anymore and therefore [deviceIsAwakeInState] would need to be rewritten to factor in the
+     * scene state.
+     */
+    @Test
+    @EnableSceneContainer
+    fun assertUndefinedResultMatchesObsoleteStateResults() {
+        for (state in KeyguardState.entries) {
+            val isAwakeInSceneContainer =
+                KeyguardState.deviceIsAwakeInState(state.mapToSceneContainerState())
+            val isAwake = KeyguardState.deviceIsAwakeInState(state)
+            assertThat(isAwakeInSceneContainer).isEqualTo(isAwake)
+        }
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt
index 519bb6e..63d06a4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt
@@ -55,6 +55,8 @@
 
     @Mock private lateinit var burnInInteractor: BurnInInteractor
     @Mock private lateinit var goneToAodTransitionViewModel: GoneToAodTransitionViewModel
+    @Mock
+    private lateinit var lockscreenToAodTransitionViewModel: LockscreenToAodTransitionViewModel
     @Mock(answer = Answers.RETURNS_DEEP_STUBS) private lateinit var clockController: ClockController
 
     private val kosmos = testKosmos()
@@ -76,7 +78,12 @@
         kosmos.burnInInteractor = burnInInteractor
         whenever(goneToAodTransitionViewModel.enterFromTopTranslationY(anyInt()))
             .thenReturn(emptyFlow())
+        whenever(goneToAodTransitionViewModel.enterFromSideTranslationX(anyInt()))
+            .thenReturn(emptyFlow())
+        whenever(lockscreenToAodTransitionViewModel.enterFromSideTranslationX(anyInt()))
+            .thenReturn(emptyFlow())
         kosmos.goneToAodTransitionViewModel = goneToAodTransitionViewModel
+        kosmos.lockscreenToAodTransitionViewModel = lockscreenToAodTransitionViewModel
         kosmos.fakeKeyguardClockRepository.setCurrentClock(clockController)
 
         underTest = kosmos.aodBurnInViewModel
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelTest.kt
index 6d9c271..b49e546 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModelTest.kt
@@ -227,6 +227,15 @@
             assertThat(accessibilityDelegateHint)
                 .isEqualTo(DeviceEntryIconView.AccessibilityHintType.BOUNCER)
 
+            // udfps running
+            setUpState(
+                isUdfpsSupported = true,
+                isUdfpsRunning = true,
+            )
+
+            assertThat(accessibilityDelegateHint)
+                .isEqualTo(DeviceEntryIconView.AccessibilityHintType.BOUNCER)
+
             // non-interactive lock icon
             fingerprintPropertyRepository.supportsRearFps()
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelTest.kt
new file mode 100644
index 0000000..bab466a
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelTest.kt
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyguard.ui.viewmodel
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.keyguard.ui.StateToValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.power.data.repository.powerRepository
+import com.android.systemui.power.shared.model.WakeSleepReason
+import com.android.systemui.power.shared.model.WakefulnessState
+import com.android.systemui.testKosmos
+import com.google.common.collect.Range
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@ExperimentalCoroutinesApi
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class GoneToAodTransitionViewModelTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val repository = kosmos.fakeKeyguardTransitionRepository
+    private val underTest = kosmos.goneToAodTransitionViewModel
+    private val fingerprintPropertyRepository = kosmos.fingerprintPropertyRepository
+    private val biometricSettingsRepository = kosmos.biometricSettingsRepository
+    private val powerRepository = kosmos.powerRepository
+
+    @Test
+    fun enterFromTopTranslationY_whenNotOnFold() =
+        testScope.runTest {
+            powerRepository.updateWakefulness(
+                rawState = WakefulnessState.STARTING_TO_SLEEP,
+                lastWakeReason = WakeSleepReason.POWER_BUTTON,
+                lastSleepReason = WakeSleepReason.POWER_BUTTON,
+                powerButtonLaunchGestureTriggered = false
+            )
+
+            val pixels = -100f
+            val enterFromTopTranslationY by
+                collectLastValue(underTest.enterFromTopTranslationY(pixels.toInt()))
+            runCurrent()
+
+            // The animation should only start > .4f way through
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(enterFromTopTranslationY)
+                .isEqualTo(
+                    StateToValue(
+                        from = KeyguardState.GONE,
+                        to = KeyguardState.AOD,
+                        transitionState = TransitionState.STARTED,
+                        value = pixels
+                    )
+                )
+
+            repository.sendTransitionStep(step(.55f))
+            assertThat(enterFromTopTranslationY!!.value ?: -1f).isIn(Range.closed(pixels, 0f))
+
+            repository.sendTransitionStep(step(.85f))
+            assertThat(enterFromTopTranslationY!!.value ?: -1f).isIn(Range.closed(pixels, 0f))
+
+            // At the end, the translation should be complete and set to zero
+            repository.sendTransitionStep(step(1f))
+            assertThat(enterFromTopTranslationY)
+                .isEqualTo(
+                    StateToValue(
+                        from = KeyguardState.GONE,
+                        to = KeyguardState.AOD,
+                        transitionState = TransitionState.RUNNING,
+                        value = 0f
+                    )
+                )
+        }
+
+    @Test
+    fun enterFromTopTranslationY_whenOnFold_emitsNothing() =
+        testScope.runTest {
+            powerRepository.updateWakefulness(
+                rawState = WakefulnessState.STARTING_TO_SLEEP,
+                lastWakeReason = WakeSleepReason.POWER_BUTTON,
+                lastSleepReason = WakeSleepReason.FOLD,
+                powerButtonLaunchGestureTriggered = false
+            )
+
+            val pixels = -100f
+            val enterFromTopTranslationY by
+                collectLastValue(underTest.enterFromTopTranslationY(pixels.toInt()))
+            runCurrent()
+
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(enterFromTopTranslationY).isNull()
+
+            repository.sendTransitionStep(step(.55f))
+            assertThat(enterFromTopTranslationY).isNull()
+
+            repository.sendTransitionStep(step(.85f))
+            assertThat(enterFromTopTranslationY).isNull()
+
+            repository.sendTransitionStep(step(1f))
+            assertThat(enterFromTopTranslationY).isNull()
+        }
+
+    @Test
+    fun enterFromSideTranslationX_onFold() =
+        testScope.runTest {
+            powerRepository.updateWakefulness(
+                rawState = WakefulnessState.STARTING_TO_SLEEP,
+                lastWakeReason = WakeSleepReason.POWER_BUTTON,
+                lastSleepReason = WakeSleepReason.FOLD,
+                powerButtonLaunchGestureTriggered = false
+            )
+
+            val pixels = -100f
+            val enterFromSideTranslationX by
+                collectLastValue(underTest.enterFromSideTranslationX(pixels.toInt()))
+            runCurrent()
+
+            // The animation should only start > .4f way through
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(enterFromSideTranslationX)
+                .isEqualTo(
+                    StateToValue(
+                        from = KeyguardState.GONE,
+                        to = KeyguardState.AOD,
+                        transitionState = TransitionState.STARTED,
+                        value = pixels
+                    )
+                )
+
+            repository.sendTransitionStep(step(.55f))
+            assertThat(enterFromSideTranslationX!!.value ?: -1f).isIn(Range.closed(pixels, 0f))
+
+            repository.sendTransitionStep(step(.85f))
+            assertThat(enterFromSideTranslationX!!.value ?: -1f).isIn(Range.closed(pixels, 0f))
+
+            // At the end, the translation should be complete and set to zero
+            repository.sendTransitionStep(step(1f))
+            assertThat(enterFromSideTranslationX)
+                .isEqualTo(
+                    StateToValue(
+                        from = KeyguardState.GONE,
+                        to = KeyguardState.AOD,
+                        transitionState = TransitionState.RUNNING,
+                        value = 0f
+                    )
+                )
+        }
+
+    @Test
+    fun enterFromTopAnimationAlpha() =
+        testScope.runTest {
+            val enterFromTopAnimationAlpha by collectLastValue(underTest.enterFromTopAnimationAlpha)
+            runCurrent()
+
+            // The animation should only start > .4f way through
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(enterFromTopAnimationAlpha).isEqualTo(0f)
+
+            repository.sendTransitionStep(step(0.4f))
+            assertThat(enterFromTopAnimationAlpha).isEqualTo(0f)
+
+            repository.sendTransitionStep(step(.85f))
+            assertThat(enterFromTopAnimationAlpha).isIn(Range.closed(0f, 1f))
+
+            repository.sendTransitionStep(step(1f))
+            assertThat(enterFromTopAnimationAlpha).isEqualTo(1f)
+        }
+
+    @Test
+    fun deviceEntryBackgroundViewAlpha() =
+        testScope.runTest {
+            val deviceEntryBackgroundViewAlpha by
+                collectLastValue(underTest.deviceEntryBackgroundViewAlpha)
+            runCurrent()
+
+            // immediately 0f
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
+
+            repository.sendTransitionStep(step(0.4f))
+            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
+
+            repository.sendTransitionStep(step(.85f))
+            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
+
+            repository.sendTransitionStep(step(1f))
+            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
+        }
+
+    @Test
+    fun deviceEntryParentViewAlpha_udfpsEnrolled() =
+        testScope.runTest {
+            fingerprintPropertyRepository.supportsUdfps()
+            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
+            val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
+            runCurrent()
+
+            // animation doesn't start until the end
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(deviceEntryParentViewAlpha).isEqualTo(0f)
+
+            repository.sendTransitionStep(step(0.5f))
+            assertThat(deviceEntryParentViewAlpha).isEqualTo(0f)
+
+            repository.sendTransitionStep(step(.95f))
+            assertThat(deviceEntryParentViewAlpha).isIn(Range.closed(.01f, 1f))
+
+            repository.sendTransitionStep(step(1f))
+            assertThat(deviceEntryParentViewAlpha).isIn(Range.closed(.99f, 1f))
+
+            repository.sendTransitionStep(step(1f, TransitionState.FINISHED))
+            assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
+        }
+
+    @Test
+    fun deviceEntryParentViewAlpha_rearFpEnrolled() =
+        testScope.runTest {
+            fingerprintPropertyRepository.supportsRearFps()
+            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
+            val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
+            runCurrent()
+
+            // animation doesn't start until the end
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(deviceEntryParentViewAlpha).isNull()
+
+            repository.sendTransitionStep(step(0.5f))
+            assertThat(deviceEntryParentViewAlpha).isNull()
+
+            repository.sendTransitionStep(step(.95f))
+            assertThat(deviceEntryParentViewAlpha).isNull()
+
+            repository.sendTransitionStep(step(1f))
+            assertThat(deviceEntryParentViewAlpha).isNull()
+
+            repository.sendTransitionStep(step(1f, TransitionState.FINISHED))
+            assertThat(deviceEntryParentViewAlpha).isNull()
+        }
+
+    @Test
+    fun deviceEntryParentViewAlpha_udfpsNotEnrolled_noUpdates() =
+        testScope.runTest {
+            fingerprintPropertyRepository.supportsUdfps()
+            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
+            val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
+            runCurrent()
+
+            // animation doesn't start until the end
+            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
+            assertThat(deviceEntryParentViewAlpha).isNull()
+
+            repository.sendTransitionStep(step(0.5f))
+            assertThat(deviceEntryParentViewAlpha).isNull()
+
+            repository.sendTransitionStep(step(.95f))
+            assertThat(deviceEntryParentViewAlpha).isNull()
+
+            repository.sendTransitionStep(step(1f))
+            assertThat(deviceEntryParentViewAlpha).isNull()
+
+            repository.sendTransitionStep(step(1f, TransitionState.FINISHED))
+            assertThat(deviceEntryParentViewAlpha).isNull()
+        }
+
+    private fun step(
+        value: Float,
+        state: TransitionState = TransitionState.RUNNING
+    ): TransitionStep {
+        return TransitionStep(
+            from = KeyguardState.GONE,
+            to = KeyguardState.AOD,
+            value = value,
+            transitionState = state,
+            ownerName = "GoneToAodTransitionViewModelTest"
+        )
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt
index 3777e40..6f74ed3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModelTest.kt
@@ -16,98 +16,108 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
-import androidx.test.ext.junit.runners.AndroidJUnit4
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.flag.junit.FlagsParameterization
 import androidx.test.filters.SmallTest
-import com.android.systemui.Flags as AConfigFlags
+import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.systemui.Flags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR
+import com.android.systemui.Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
-import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
+import com.android.systemui.common.ui.domain.interactor.configurationInteractor
+import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
+import com.android.systemui.communal.domain.interactor.communalSceneInteractor
+import com.android.systemui.communal.shared.model.CommunalScenes
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.doze.util.BurnInHelperWrapper
-import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
 import com.android.systemui.keyguard.domain.interactor.BurnInInteractor
-import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
+import com.android.systemui.keyguard.domain.interactor.keyguardBottomAreaInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.BurnInModel
+import com.android.systemui.keyguard.shared.model.StatusBarState
 import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.anyInt
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(AndroidJUnit4::class)
-class KeyguardIndicationAreaViewModelTest : SysuiTestCase() {
+@RunWith(ParameterizedAndroidJunit4::class)
+class KeyguardIndicationAreaViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
 
-    @Mock private lateinit var burnInHelperWrapper: BurnInHelperWrapper
-    @Mock private lateinit var shortcutsCombinedViewModel: KeyguardQuickAffordancesCombinedViewModel
-
-    @Mock private lateinit var burnInInteractor: BurnInInteractor
-    private val burnInFlow = MutableStateFlow(BurnInModel())
-
-    private lateinit var bottomAreaInteractor: KeyguardBottomAreaInteractor
+    private val bottomAreaInteractor = kosmos.keyguardBottomAreaInteractor
     private lateinit var underTest: KeyguardIndicationAreaViewModel
-    private lateinit var repository: FakeKeyguardRepository
+    private val keyguardRepository = kosmos.fakeKeyguardRepository
+    private val communalSceneRepository = kosmos.fakeCommunalSceneRepository
 
     private val startButtonFlow =
-        MutableStateFlow<KeyguardQuickAffordanceViewModel>(
+        MutableStateFlow(
             KeyguardQuickAffordanceViewModel(
                 slotId = KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId()
             )
         )
     private val endButtonFlow =
-        MutableStateFlow<KeyguardQuickAffordanceViewModel>(
+        MutableStateFlow(
             KeyguardQuickAffordanceViewModel(
                 slotId = KeyguardQuickAffordancePosition.BOTTOM_END.toSlotId()
             )
         )
-    private val alphaFlow = MutableStateFlow<Float>(1f)
+    private val alphaFlow = MutableStateFlow(1f)
+
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags)
+    }
 
     @Before
     fun setUp() {
-        MockitoAnnotations.initMocks(this)
-
-        mSetFlagsRule.disableFlags(AConfigFlags.FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR)
-        mSetFlagsRule.disableFlags(AConfigFlags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
-
-        whenever(burnInHelperWrapper.burnInOffset(anyInt(), any()))
-            .thenReturn(RETURNED_BURN_IN_OFFSET)
-        whenever(burnInInteractor.burnIn(anyInt(), anyInt())).thenReturn(burnInFlow)
-
-        val withDeps = KeyguardInteractorFactory.create()
-        val keyguardInteractor = withDeps.keyguardInteractor
-        repository = withDeps.repository
-
-        val bottomAreaViewModel: KeyguardBottomAreaViewModel = mock()
-        whenever(bottomAreaViewModel.startButton).thenReturn(startButtonFlow)
-        whenever(bottomAreaViewModel.endButton).thenReturn(endButtonFlow)
-        whenever(bottomAreaViewModel.alpha).thenReturn(alphaFlow)
-        bottomAreaInteractor = KeyguardBottomAreaInteractor(repository = repository)
+        val bottomAreaViewModel =
+            mock<KeyguardBottomAreaViewModel> {
+                on { startButton } doReturn startButtonFlow
+                on { endButton } doReturn endButtonFlow
+                on { alpha } doReturn alphaFlow
+            }
+        val burnInInteractor =
+            mock<BurnInInteractor> {
+                on { burnIn(anyInt(), anyInt()) } doReturn flowOf(BurnInModel())
+            }
+        val burnInHelperWrapper =
+            mock<BurnInHelperWrapper> {
+                on { burnInOffset(anyInt(), any()) } doReturn RETURNED_BURN_IN_OFFSET
+            }
+        val shortcutsCombinedViewModel =
+            mock<KeyguardQuickAffordancesCombinedViewModel> {
+                on { startButton } doReturn startButtonFlow
+                on { endButton } doReturn endButtonFlow
+            }
         underTest =
             KeyguardIndicationAreaViewModel(
-                keyguardInteractor = keyguardInteractor,
+                keyguardInteractor = kosmos.keyguardInteractor,
                 bottomAreaInteractor = bottomAreaInteractor,
                 keyguardBottomAreaViewModel = bottomAreaViewModel,
                 burnInHelperWrapper = burnInHelperWrapper,
                 burnInInteractor = burnInInteractor,
                 shortcutsCombinedViewModel = shortcutsCombinedViewModel,
-                configurationInteractor = ConfigurationInteractor(FakeConfigurationRepository()),
+                configurationInteractor = kosmos.configurationInteractor,
                 keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor,
-                backgroundCoroutineContext = kosmos.testDispatcher,
+                backgroundDispatcher = kosmos.testDispatcher,
+                communalSceneInteractor = kosmos.communalSceneInteractor,
                 mainDispatcher = kosmos.testDispatcher
             )
     }
@@ -115,77 +125,120 @@
     @Test
     fun alpha() =
         testScope.runTest {
-            val value = collectLastValue(underTest.alpha)
+            val alpha by collectLastValue(underTest.alpha)
 
-            assertThat(value()).isEqualTo(1f)
+            assertThat(alpha).isEqualTo(1f)
             alphaFlow.value = 0.1f
-            assertThat(value()).isEqualTo(0.1f)
+            assertThat(alpha).isEqualTo(0.1f)
             alphaFlow.value = 0.5f
-            assertThat(value()).isEqualTo(0.5f)
+            assertThat(alpha).isEqualTo(0.5f)
             alphaFlow.value = 0.2f
-            assertThat(value()).isEqualTo(0.2f)
+            assertThat(alpha).isEqualTo(0.2f)
             alphaFlow.value = 0f
-            assertThat(value()).isEqualTo(0f)
+            assertThat(alpha).isEqualTo(0f)
         }
 
     @Test
+    @DisableFlags(FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR)
     fun isIndicationAreaPadded() =
         testScope.runTest {
-            repository.setKeyguardShowing(true)
-            val value = collectLastValue(underTest.isIndicationAreaPadded)
+            keyguardRepository.setKeyguardShowing(true)
+            val isIndicationAreaPadded by collectLastValue(underTest.isIndicationAreaPadded)
 
-            assertThat(value()).isFalse()
+            assertThat(isIndicationAreaPadded).isFalse()
             startButtonFlow.value = startButtonFlow.value.copy(isVisible = true)
-            assertThat(value()).isTrue()
+            assertThat(isIndicationAreaPadded).isTrue()
             endButtonFlow.value = endButtonFlow.value.copy(isVisible = true)
-            assertThat(value()).isTrue()
+            assertThat(isIndicationAreaPadded).isTrue()
             startButtonFlow.value = startButtonFlow.value.copy(isVisible = false)
-            assertThat(value()).isTrue()
+            assertThat(isIndicationAreaPadded).isTrue()
             endButtonFlow.value = endButtonFlow.value.copy(isVisible = false)
-            assertThat(value()).isFalse()
+            assertThat(isIndicationAreaPadded).isFalse()
         }
 
     @Test
+    @DisableFlags(FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT, FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR)
     fun indicationAreaTranslationX() =
         testScope.runTest {
-            val value = collectLastValue(underTest.indicationAreaTranslationX)
+            val translationX by collectLastValue(underTest.indicationAreaTranslationX)
 
-            assertThat(value()).isEqualTo(0f)
+            assertThat(translationX).isEqualTo(0f)
             bottomAreaInteractor.setClockPosition(100, 100)
-            assertThat(value()).isEqualTo(100f)
+            assertThat(translationX).isEqualTo(100f)
             bottomAreaInteractor.setClockPosition(200, 100)
-            assertThat(value()).isEqualTo(200f)
+            assertThat(translationX).isEqualTo(200f)
             bottomAreaInteractor.setClockPosition(200, 200)
-            assertThat(value()).isEqualTo(200f)
+            assertThat(translationX).isEqualTo(200f)
             bottomAreaInteractor.setClockPosition(300, 100)
-            assertThat(value()).isEqualTo(300f)
+            assertThat(translationX).isEqualTo(300f)
         }
 
     @Test
+    @DisableFlags(FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
     fun indicationAreaTranslationY() =
         testScope.runTest {
-            val value =
+            val translationY by
                 collectLastValue(underTest.indicationAreaTranslationY(DEFAULT_BURN_IN_OFFSET))
 
             // Negative 0 - apparently there's a difference in floating point arithmetic - FML
-            assertThat(value()).isEqualTo(-0f)
+            assertThat(translationY).isEqualTo(-0f)
             val expected1 = setDozeAmountAndCalculateExpectedTranslationY(0.1f)
-            assertThat(value()).isEqualTo(expected1)
+            assertThat(translationY).isEqualTo(expected1)
             val expected2 = setDozeAmountAndCalculateExpectedTranslationY(0.2f)
-            assertThat(value()).isEqualTo(expected2)
+            assertThat(translationY).isEqualTo(expected2)
             val expected3 = setDozeAmountAndCalculateExpectedTranslationY(0.5f)
-            assertThat(value()).isEqualTo(expected3)
+            assertThat(translationY).isEqualTo(expected3)
             val expected4 = setDozeAmountAndCalculateExpectedTranslationY(1f)
-            assertThat(value()).isEqualTo(expected4)
+            assertThat(translationY).isEqualTo(expected4)
+        }
+
+    @Test
+    fun visibilityWhenCommunalNotShowing() =
+        testScope.runTest {
+            keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
+            val visible by collectLastValue(underTest.visible)
+
+            assertThat(visible).isTrue()
+            keyguardRepository.setStatusBarState(StatusBarState.SHADE)
+            assertThat(visible).isFalse()
+        }
+
+    @Test
+    fun visibilityWhenCommunalShowing() =
+        testScope.runTest {
+            keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
+            communalSceneRepository.setTransitionState(
+                flowOf(ObservableTransitionState.Idle(CommunalScenes.Communal))
+            )
+
+            val visible by collectLastValue(underTest.visible)
+
+            assertThat(visible).isTrue()
+            keyguardRepository.setStatusBarState(StatusBarState.SHADE)
+            assertThat(visible).isTrue()
+
+            communalSceneRepository.setTransitionState(
+                flowOf(ObservableTransitionState.Idle(CommunalScenes.Blank))
+            )
+            assertThat(visible).isFalse()
         }
 
     private fun setDozeAmountAndCalculateExpectedTranslationY(dozeAmount: Float): Float {
-        repository.setDozeAmount(dozeAmount)
+        keyguardRepository.setDozeAmount(dozeAmount)
         return dozeAmount * (RETURNED_BURN_IN_OFFSET - DEFAULT_BURN_IN_OFFSET)
     }
 
     companion object {
         private const val DEFAULT_BURN_IN_OFFSET = 5
         private const val RETURNED_BURN_IN_OFFSET = 3
+
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return FlagsParameterization.allCombinationsOf(
+                FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR,
+                FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT,
+            )
+        }
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt
index de4b999..875e9e0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelTest.kt
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
 package com.android.systemui.keyguard.ui.viewmodel
 
 import android.platform.test.flag.junit.FlagsParameterization
@@ -27,10 +29,13 @@
 import com.android.systemui.flags.andSceneContainer
 import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.keyguard.data.repository.fakeKeyguardClockRepository
+import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository
 import com.android.systemui.keyguard.shared.model.ClockSize
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.res.R
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shade.data.repository.shadeRepository
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.testKosmos
@@ -38,6 +43,8 @@
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import java.util.Locale
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -201,6 +208,44 @@
             }
         }
 
+    @Test
+    fun isContentVisible_whenNotOccluded_visible() =
+        with(kosmos) {
+            testScope.runTest {
+                val isContentVisible by collectLastValue(underTest.isContentVisible)
+
+                keyguardOcclusionRepository.setShowWhenLockedActivityInfo(false, null)
+                runCurrent()
+                assertThat(isContentVisible).isTrue()
+            }
+        }
+
+    @Test
+    fun isContentVisible_whenOccluded_notVisible() =
+        with(kosmos) {
+            testScope.runTest {
+                val isContentVisible by collectLastValue(underTest.isContentVisible)
+
+                keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true, null)
+                runCurrent()
+                assertThat(isContentVisible).isFalse()
+            }
+        }
+
+    @Test
+    fun isContentVisible_whenOccluded_notVisible_evenIfShadeShown() =
+        with(kosmos) {
+            testScope.runTest {
+                val isContentVisible by collectLastValue(underTest.isContentVisible)
+                keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true, null)
+                runCurrent()
+
+                sceneInteractor.snapToScene(Scenes.Shade, "")
+                runCurrent()
+                assertThat(isContentVisible).isFalse()
+            }
+        }
+
     private fun prepareConfiguration(): Int {
         val configuration = context.resources.configuration
         configuration.setLayoutDirection(Locale.US)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
index 61d8216..4eb146d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
@@ -19,6 +19,7 @@
 package com.android.systemui.keyguard.ui.viewmodel
 
 import android.platform.test.annotations.EnableFlags
+import android.testing.TestableLooper.RunWithLooper
 import androidx.test.filters.SmallTest
 import com.android.compose.animation.scene.Edge
 import com.android.compose.animation.scene.SceneKey
@@ -61,6 +62,7 @@
 
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4::class)
+@RunWithLooper
 @EnableSceneContainer
 class LockscreenSceneViewModelTest : SysuiTestCase() {
 
@@ -265,8 +267,8 @@
             applicationScope = testScope.backgroundScope,
             deviceEntryInteractor = kosmos.deviceEntryInteractor,
             communalInteractor = kosmos.communalInteractor,
-            longPress =
-                KeyguardLongPressViewModel(
+            touchHandling =
+                KeyguardTouchHandlingViewModel(
                     interactor = mock(),
                 ),
             notifications = kosmos.notificationsPlaceholderViewModel,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt
index bc0512a..24672eb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt
@@ -30,11 +30,21 @@
 import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
 import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
 import com.android.systemui.media.controls.shared.model.SmartspaceMediaLoadingModel
+import com.android.systemui.media.controls.util.SmallHash
+import com.android.systemui.media.controls.util.mediaSmartspaceLogger
+import com.android.systemui.media.controls.util.mockMediaSmartspaceLogger
 import com.android.systemui.testKosmos
+import com.android.systemui.util.time.systemClock
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.kotlin.never
+import org.mockito.kotlin.reset
+import org.mockito.kotlin.verify
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
@@ -42,8 +52,20 @@
 
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
+    private val smartspaceLogger = kosmos.mockMediaSmartspaceLogger
+    private val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
+    private val mediaRecommendation =
+        SmartspaceMediaData(
+            targetId = KEY_MEDIA_SMARTSPACE,
+            isActive = true,
+            recommendations = MediaTestHelper.getValidRecommendationList(icon),
+        )
 
-    private val underTest: MediaFilterRepository = kosmos.mediaFilterRepository
+    private val underTest: MediaFilterRepository =
+        with(kosmos) {
+            mediaSmartspaceLogger = mockMediaSmartspaceLogger
+            mediaFilterRepository
+        }
 
     @Test
     fun addSelectedUserMediaEntry_activeThenInactivate() =
@@ -137,14 +159,6 @@
         testScope.runTest {
             val smartspaceMediaData by collectLastValue(underTest.smartspaceMediaData)
 
-            val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
-            val mediaRecommendation =
-                SmartspaceMediaData(
-                    targetId = KEY_MEDIA_SMARTSPACE,
-                    isActive = true,
-                    recommendations = MediaTestHelper.getValidRecommendationList(icon),
-                )
-
             underTest.setRecommendation(mediaRecommendation)
 
             assertThat(smartspaceMediaData).isEqualTo(mediaRecommendation)
@@ -164,16 +178,44 @@
             val playingData = createMediaData("app1", true, LOCAL, false, playingInstanceId)
             val remoteData = createMediaData("app2", true, REMOTE, false, remoteInstanceId)
 
+            underTest.setRecommendation(mediaRecommendation)
+            underTest.setRecommendationsLoadingState(
+                SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, true)
+            )
             underTest.addSelectedUserMediaEntry(playingData)
-            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(playingInstanceId))
-            underTest.addSelectedUserMediaEntry(remoteData)
-            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(remoteInstanceId))
+            underTest.addMediaDataLoadingState(
+                MediaDataLoadingModel.Loaded(playingInstanceId),
+                false
+            )
 
-            assertThat(currentMedia?.size).isEqualTo(2)
+            verify(smartspaceLogger)
+                .logSmartspaceCardReceived(
+                    playingData.smartspaceId,
+                    playingData.appUid,
+                    cardinality = 2
+                )
+
+            underTest.addSelectedUserMediaEntry(remoteData)
+            underTest.addMediaDataLoadingState(
+                MediaDataLoadingModel.Loaded(remoteInstanceId),
+                false
+            )
+
+            verify(smartspaceLogger)
+                .logSmartspaceCardReceived(
+                    remoteData.smartspaceId,
+                    playingData.appUid,
+                    cardinality = 3,
+                    rank = 1
+                )
+            assertThat(currentMedia?.size).isEqualTo(3)
             assertThat(currentMedia)
                 .containsExactly(
                     MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(playingInstanceId)),
-                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(remoteInstanceId))
+                    MediaCommonModel.MediaControl(MediaDataLoadingModel.Loaded(remoteInstanceId)),
+                    MediaCommonModel.MediaRecommendations(
+                        SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, true)
+                    )
                 )
                 .inOrder()
         }
@@ -222,6 +264,16 @@
 
             underTest.setOrderedMedia()
 
+            verify(smartspaceLogger, never())
+                .logSmartspaceCardReceived(
+                    anyInt(),
+                    anyInt(),
+                    anyInt(),
+                    anyBoolean(),
+                    anyBoolean(),
+                    anyInt(),
+                    anyInt()
+                )
             assertThat(currentMedia?.size).isEqualTo(2)
             assertThat(currentMedia)
                 .containsExactly(
@@ -248,14 +300,6 @@
             val stoppedAndRemoteData = createMediaData("app4", false, REMOTE, false, instanceId4)
             val canResumeData = createMediaData("app5", false, LOCAL, true, instanceId5)
 
-            val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
-            val mediaRecommendations =
-                SmartspaceMediaData(
-                    targetId = KEY_MEDIA_SMARTSPACE,
-                    isActive = true,
-                    recommendations = MediaTestHelper.getValidRecommendationList(icon),
-                )
-
             underTest.addSelectedUserMediaEntry(stoppedAndLocalData)
             underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId3))
 
@@ -271,11 +315,33 @@
             underTest.addSelectedUserMediaEntry(playingAndRemoteData)
             underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId2))
 
-            underTest.setRecommendation(mediaRecommendations)
+            underTest.setRecommendation(mediaRecommendation)
             underTest.setRecommendationsLoadingState(
                 SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, true)
             )
+            underTest.setOrderedMedia()
 
+            val smartspaceId = SmallHash.hash(mediaRecommendation.targetId)
+            verify(smartspaceLogger)
+                .logSmartspaceCardReceived(
+                    eq(smartspaceId),
+                    anyInt(),
+                    eq(6),
+                    anyBoolean(),
+                    anyBoolean(),
+                    eq(2),
+                    anyInt()
+                )
+            verify(smartspaceLogger, never())
+                .logSmartspaceCardReceived(
+                    eq(playingAndLocalData.smartspaceId),
+                    anyInt(),
+                    anyInt(),
+                    anyBoolean(),
+                    anyBoolean(),
+                    anyInt(),
+                    anyInt()
+                )
             assertThat(currentMedia?.size).isEqualTo(6)
             assertThat(currentMedia)
                 .containsExactly(
@@ -312,18 +378,10 @@
                     isPlaying = true,
                     notificationKey = KEY_2
                 )
-            val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
-            val mediaRecommendations =
-                SmartspaceMediaData(
-                    targetId = KEY_MEDIA_SMARTSPACE,
-                    isActive = true,
-                    packageName = PACKAGE_NAME,
-                    recommendations = MediaTestHelper.getValidRecommendationList(icon),
-                )
 
             underTest.setMediaFromRecPackageName(PACKAGE_NAME)
             underTest.addSelectedUserMediaEntry(data)
-            underTest.setRecommendation(mediaRecommendations)
+            underTest.setRecommendation(mediaRecommendation)
             underTest.setRecommendationsLoadingState(
                 SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE)
             )
@@ -365,6 +423,89 @@
     fun hasActiveMedia_noMediaSet_returnsFalse() =
         testScope.runTest { assertThat(underTest.hasActiveMedia()).isFalse() }
 
+    @Test
+    fun updateMediaWithLatency_smartspaceIsLogged() =
+        testScope.runTest {
+            val instanceId = InstanceId.fakeInstanceId(123)
+            val data = createMediaData("app", true, LOCAL, false, instanceId)
+
+            underTest.setRecommendation(mediaRecommendation)
+            underTest.setRecommendationsLoadingState(
+                SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, true)
+            )
+
+            val smartspaceId = SmallHash.hash(mediaRecommendation.targetId)
+            verify(smartspaceLogger)
+                .logSmartspaceCardReceived(
+                    eq(smartspaceId),
+                    anyInt(),
+                    eq(1),
+                    eq(true),
+                    anyBoolean(),
+                    eq(0),
+                    anyInt()
+                )
+            reset(smartspaceLogger)
+
+            underTest.addSelectedUserMediaEntry(data)
+            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId), false)
+
+            verify(smartspaceLogger)
+                .logSmartspaceCardReceived(data.smartspaceId, data.appUid, cardinality = 2)
+
+            reset(smartspaceLogger)
+
+            underTest.addSelectedUserMediaEntry(data)
+            underTest.addMediaDataLoadingState(
+                MediaDataLoadingModel.Loaded(instanceId, receivedSmartspaceCardLatency = 123),
+                true
+            )
+
+            verify(smartspaceLogger)
+                .logSmartspaceCardReceived(
+                    SmallHash.hash(data.appUid + kosmos.systemClock.currentTimeMillis().toInt()),
+                    data.appUid,
+                    cardinality = 2,
+                    rank = 0,
+                    receivedLatencyMillis = 123
+                )
+        }
+
+    @Test
+    fun resumeMedia_loadSmartspace_allSmartspaceIsLogged() =
+        testScope.runTest {
+            val resumeInstanceId = InstanceId.fakeInstanceId(123)
+            val data = createMediaData("app", false, LOCAL, true, resumeInstanceId)
+
+            underTest.addSelectedUserMediaEntry(data.copy(active = false))
+            underTest.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(resumeInstanceId))
+            underTest.setRecommendation(mediaRecommendation)
+            underTest.setRecommendationsLoadingState(
+                SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, true)
+            )
+
+            assertThat(underTest.hasActiveMedia()).isFalse()
+            assertThat(underTest.hasAnyMedia()).isTrue()
+            val smartspaceId = SmallHash.hash(mediaRecommendation.targetId)
+            verify(smartspaceLogger)
+                .logSmartspaceCardReceived(
+                    eq(smartspaceId),
+                    anyInt(),
+                    eq(2),
+                    eq(true),
+                    anyBoolean(),
+                    eq(0),
+                    anyInt()
+                )
+            verify(smartspaceLogger)
+                .logSmartspaceCardReceived(
+                    SmallHash.hash(data.appUid + kosmos.systemClock.currentTimeMillis().toInt()),
+                    data.appUid,
+                    cardinality = 2,
+                    rank = 1
+                )
+        }
+
     private fun createMediaData(
         app: String,
         playing: Boolean,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt
index c62195f..414974c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt
@@ -18,6 +18,7 @@
 
 import android.R
 import android.graphics.drawable.Icon
+import android.os.Process
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
@@ -38,12 +39,19 @@
 import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
 import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
 import com.android.systemui.media.controls.shared.model.SmartspaceMediaLoadingModel
+import com.android.systemui.media.controls.util.MediaSmartspaceLogger
+import com.android.systemui.media.controls.util.SmallHash
+import com.android.systemui.media.controls.util.mediaSmartspaceLogger
+import com.android.systemui.media.controls.util.mockMediaSmartspaceLogger
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.Mockito.reset
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
@@ -52,7 +60,11 @@
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
 
-    private val mediaFilterRepository: MediaFilterRepository = kosmos.mediaFilterRepository
+    private val mediaFilterRepository: MediaFilterRepository =
+        with(kosmos) {
+            mediaSmartspaceLogger = mockMediaSmartspaceLogger
+            mediaFilterRepository
+        }
     private val mediaRecommendationsInteractor: MediaRecommendationsInteractor =
         kosmos.mediaRecommendationsInteractor
     val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
@@ -63,6 +75,7 @@
             packageName = PACKAGE_NAME,
             recommendations = MediaTestHelper.getValidRecommendationList(icon),
         )
+    private val smartspaceLogger = kosmos.mockMediaSmartspaceLogger
 
     private val underTest: MediaCarouselInteractor = kosmos.mediaCarouselInteractor
 
@@ -153,6 +166,18 @@
                     MediaCommonModel.MediaControl(mediaLoadingModel, true)
                 )
                 .inOrder()
+
+            underTest.logSmartspaceSeenCard(0, 1, false)
+
+            verify(smartspaceLogger)
+                .logSmartspaceCardUIEvent(
+                    MediaSmartspaceLogger.SMARTSPACE_CARD_SEEN_EVENT,
+                    SmallHash.hash(mediaRecommendation.targetId),
+                    Process.INVALID_UID,
+                    surface = SURFACE,
+                    2,
+                    true
+                )
         }
 
     @Test
@@ -239,7 +264,7 @@
                 .inOrder()
 
             mediaFilterRepository.addSelectedUserMediaEntry(data.copy(isPlaying = true))
-            mediaFilterRepository.addMediaDataLoadingState(MediaDataLoadingModel.Loaded(instanceId))
+            mediaFilterRepository.addMediaDataLoadingState(mediaLoadingModel)
 
             assertThat(currentMedia)
                 .containsExactly(
@@ -249,9 +274,83 @@
                 .inOrder()
         }
 
+    @Test
+    fun loadMediaAndRecommendation_logSmartspaceSeenCard() {
+        val instanceId = InstanceId.fakeInstanceId(123)
+        val data =
+            MediaData(
+                active = true,
+                instanceId = instanceId,
+                packageName = PACKAGE_NAME,
+                notificationKey = KEY
+            )
+        val smartspaceLoadingModel = SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE)
+        val mediaLoadingModel = MediaDataLoadingModel.Loaded(instanceId)
+
+        mediaFilterRepository.addSelectedUserMediaEntry(data)
+        mediaFilterRepository.addMediaDataLoadingState(mediaLoadingModel)
+        underTest.logSmartspaceSeenCard(0, 1, false)
+
+        verify(smartspaceLogger)
+            .logSmartspaceCardUIEvent(
+                MediaSmartspaceLogger.SMARTSPACE_CARD_SEEN_EVENT,
+                data.smartspaceId,
+                data.appUid,
+                surface = SURFACE,
+                1
+            )
+
+        reset(smartspaceLogger)
+        mediaFilterRepository.addSelectedUserMediaEntry(data)
+        mediaFilterRepository.addMediaDataLoadingState(mediaLoadingModel)
+        underTest.logSmartspaceSeenCard(0, 1, true)
+
+        verify(smartspaceLogger, never())
+            .logSmartspaceCardUIEvent(
+                MediaSmartspaceLogger.SMARTSPACE_CARD_SEEN_EVENT,
+                data.smartspaceId,
+                data.appUid,
+                surface = SURFACE,
+                2
+            )
+
+        reset(smartspaceLogger)
+        mediaFilterRepository.setRecommendation(mediaRecommendation)
+        mediaFilterRepository.setRecommendationsLoadingState(smartspaceLoadingModel)
+        underTest.logSmartspaceSeenCard(1, 1, true)
+
+        verify(smartspaceLogger)
+            .logSmartspaceCardUIEvent(
+                MediaSmartspaceLogger.SMARTSPACE_CARD_SEEN_EVENT,
+                SmallHash.hash(mediaRecommendation.targetId),
+                Process.INVALID_UID,
+                surface = SURFACE,
+                2,
+                true,
+                rank = 1
+            )
+
+        reset(smartspaceLogger)
+        mediaFilterRepository.addSelectedUserMediaEntry(data)
+        mediaFilterRepository.addMediaDataLoadingState(
+            mediaLoadingModel.copy(receivedSmartspaceCardLatency = 1)
+        )
+        underTest.logSmartspaceSeenCard(0, 1, true)
+
+        verify(smartspaceLogger)
+            .logSmartspaceCardUIEvent(
+                MediaSmartspaceLogger.SMARTSPACE_CARD_SEEN_EVENT,
+                data.smartspaceId,
+                data.appUid,
+                surface = SURFACE,
+                2
+            )
+    }
+
     companion object {
         private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
         private const val PACKAGE_NAME = "com.android.example"
         private const val KEY = "key"
+        private const val SURFACE = 4
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaControlInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaControlInteractorTest.kt
index 856c3fe..d594f3a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaControlInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaControlInteractorTest.kt
@@ -16,7 +16,9 @@
 
 package com.android.systemui.media.controls.domain.interactor
 
+import android.R
 import android.app.PendingIntent
+import android.graphics.drawable.Icon
 import android.os.Bundle
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
@@ -30,6 +32,7 @@
 import com.android.systemui.concurrency.fakeExecutor
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.media.controls.MediaTestHelper
 import com.android.systemui.media.controls.data.repository.mediaDataRepository
 import com.android.systemui.media.controls.domain.pipeline.MediaDataFilterImpl
 import com.android.systemui.media.controls.domain.pipeline.MediaDataProcessor
@@ -38,7 +41,12 @@
 import com.android.systemui.media.controls.domain.pipeline.mediaDataFilter
 import com.android.systemui.media.controls.domain.pipeline.mediaDataProcessor
 import com.android.systemui.media.controls.shared.model.MediaData
+import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
+import com.android.systemui.media.controls.util.MediaSmartspaceLogger.Companion.SMARTSPACE_CARD_CLICK_EVENT
+import com.android.systemui.media.controls.util.MediaSmartspaceLogger.Companion.SMARTSPACE_CARD_DISMISS_EVENT
 import com.android.systemui.media.controls.util.mediaInstanceId
+import com.android.systemui.media.controls.util.mediaSmartspaceLogger
+import com.android.systemui.media.controls.util.mockMediaSmartspaceLogger
 import com.android.systemui.media.mediaOutputDialogManager
 import com.android.systemui.mockActivityIntentHelper
 import com.android.systemui.plugins.activityStarter
@@ -49,6 +57,8 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.Mockito.anyBoolean
+import org.mockito.Mockito.anyInt
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 import org.mockito.kotlin.any
@@ -63,11 +73,23 @@
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
 
-    private val mediaDataFilter: MediaDataFilterImpl = kosmos.mediaDataFilter
+    private val mediaDataFilter: MediaDataFilterImpl =
+        with(kosmos) {
+            mediaSmartspaceLogger = mockMediaSmartspaceLogger
+            mediaDataFilter
+        }
     private val activityStarter = kosmos.activityStarter
     private val keyguardStateController = kosmos.keyguardStateController
     private val instanceId: InstanceId = kosmos.mediaInstanceId
     private val notificationLockscreenUserManager = kosmos.notificationLockscreenUserManager
+    private val smartspaceLogger = kosmos.mockMediaSmartspaceLogger
+    private val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
+    private val mediaRecommendation =
+        SmartspaceMediaData(
+            targetId = KEY_MEDIA_SMARTSPACE,
+            isActive = true,
+            recommendations = MediaTestHelper.getValidRecommendationList(icon),
+        )
 
     private val underTest: MediaControlInteractor =
         with(kosmos) {
@@ -124,13 +146,15 @@
         val clickIntent = mock<PendingIntent> { whenever(it.isActivity).thenReturn(true) }
         val expandable = mock<Expandable>()
 
-        underTest.startClickIntent(expandable, clickIntent)
+        underTest.startClickIntent(expandable, clickIntent, SMARTSPACE_CARD_CLICK_EVENT, 1)
 
         verify(clickIntent).send(any<Bundle>())
     }
 
     @Test
     fun startClickIntent_hideOverLockscreen() {
+        whenever(notificationLockscreenUserManager.isCurrentProfile(USER_ID)).thenReturn(true)
+        whenever(notificationLockscreenUserManager.isProfileAvailable(USER_ID)).thenReturn(true)
         whenever(keyguardStateController.isShowing).thenReturn(false)
 
         val clickIntent = mock<PendingIntent> { whenever(it.isActivity).thenReturn(true) }
@@ -138,8 +162,20 @@
         val activityController = mock<ActivityTransitionAnimator.Controller>()
         whenever(expandable.activityTransitionController(any())).thenReturn(activityController)
 
-        underTest.startClickIntent(expandable, clickIntent)
+        val mediaData = MediaData(userId = USER_ID, instanceId = instanceId, artist = ARTIST)
+        mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, mediaRecommendation, true)
+        mediaDataFilter.onMediaDataLoaded(KEY, null, mediaData)
+        underTest.startClickIntent(expandable, clickIntent, SMARTSPACE_CARD_CLICK_EVENT, 1)
 
+        verify(smartspaceLogger)
+            .logSmartspaceCardUIEvent(
+                SMARTSPACE_CARD_CLICK_EVENT,
+                mediaData.smartspaceId,
+                mediaData.appUid,
+                surface = SURFACE,
+                cardinality = 2,
+                rank = 1
+            )
         verify(activityStarter)
             .postStartActivityDismissingKeyguard(eq(clickIntent), eq(activityController))
     }
@@ -217,17 +253,62 @@
     }
 
     @Test
-    fun removeMediaControl() {
+    fun removeMediaControl_noRecommendation() {
+        whenever(notificationLockscreenUserManager.isCurrentProfile(USER_ID)).thenReturn(true)
+        whenever(notificationLockscreenUserManager.isProfileAvailable(USER_ID)).thenReturn(true)
         val listener = mock<MediaDataProcessor.Listener>()
         kosmos.mediaDataProcessor.addInternalListener(listener)
 
-        var mediaData = MediaData(userId = USER_ID, instanceId = instanceId, artist = ARTIST)
+        val mediaData = MediaData(userId = USER_ID, instanceId = instanceId, artist = ARTIST)
         kosmos.mediaDataRepository.addMediaEntry(KEY, mediaData)
+        kosmos.mediaDataFilter.onMediaDataLoaded(KEY, null, mediaData)
 
-        underTest.removeMediaControl(null, instanceId, 0L)
+        underTest.removeMediaControl(null, instanceId, 0L, SMARTSPACE_CARD_DISMISS_EVENT, 1)
         kosmos.fakeExecutor.advanceClockToNext()
         kosmos.fakeExecutor.runAllReady()
 
+        verify(smartspaceLogger, never())
+            .logSmartspaceCardUIEvent(
+                anyInt(),
+                anyInt(),
+                anyInt(),
+                anyInt(),
+                anyInt(),
+                anyBoolean(),
+                anyBoolean(),
+                anyInt(),
+                anyInt(),
+                anyInt(),
+                anyBoolean()
+            )
+        verify(listener).onMediaDataRemoved(eq(KEY), eq(true))
+    }
+
+    @Test
+    fun removeMediaControl_recommendationsExist() {
+        whenever(notificationLockscreenUserManager.isCurrentProfile(USER_ID)).thenReturn(true)
+        whenever(notificationLockscreenUserManager.isProfileAvailable(USER_ID)).thenReturn(true)
+        val listener = mock<MediaDataProcessor.Listener>()
+        kosmos.mediaDataProcessor.addInternalListener(listener)
+
+        val mediaData = MediaData(userId = USER_ID, instanceId = instanceId, artist = ARTIST)
+        kosmos.mediaDataRepository.addMediaEntry(KEY, mediaData)
+        mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, mediaRecommendation, true)
+        mediaDataFilter.onMediaDataLoaded(KEY, null, mediaData)
+
+        underTest.removeMediaControl(null, instanceId, 0L, SMARTSPACE_CARD_DISMISS_EVENT, 1)
+        kosmos.fakeExecutor.advanceClockToNext()
+        kosmos.fakeExecutor.runAllReady()
+
+        verify(smartspaceLogger)
+            .logSmartspaceCardUIEvent(
+                SMARTSPACE_CARD_DISMISS_EVENT,
+                mediaData.smartspaceId,
+                mediaData.appUid,
+                surface = SURFACE,
+                cardinality = 2,
+                rank = 1
+            )
         verify(listener).onMediaDataRemoved(eq(KEY), eq(true))
     }
 
@@ -238,5 +319,7 @@
         private const val APP_NAME = "app"
         private const val ARTIST = "artist"
         private const val ARTIST_2 = "artist2"
+        private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
+        private const val SURFACE = 4
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaRecommendationsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaRecommendationsInteractorTest.kt
index 9656511..8af7e1d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaRecommendationsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaRecommendationsInteractorTest.kt
@@ -21,6 +21,7 @@
 import android.content.Intent
 import android.content.applicationContext
 import android.graphics.drawable.Icon
+import android.os.Process
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -40,10 +41,14 @@
 import com.android.systemui.media.controls.shared.model.MediaRecModel
 import com.android.systemui.media.controls.shared.model.MediaRecommendationsModel
 import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
+import com.android.systemui.media.controls.util.MediaSmartspaceLogger.Companion.SMARTSPACE_CARD_CLICK_EVENT
+import com.android.systemui.media.controls.util.MediaSmartspaceLogger.Companion.SMARTSPACE_CARD_DISMISS_EVENT
+import com.android.systemui.media.controls.util.SmallHash
+import com.android.systemui.media.controls.util.mediaSmartspaceLogger
+import com.android.systemui.media.controls.util.mockMediaSmartspaceLogger
 import com.android.systemui.plugins.activityStarter
 import com.android.systemui.testKosmos
 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.whenever
 import com.google.common.truth.Truth.assertThat
@@ -53,6 +58,7 @@
 import org.mockito.Mockito.doNothing
 import org.mockito.Mockito.spy
 import org.mockito.Mockito.verify
+import org.mockito.kotlin.eq
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
@@ -62,7 +68,11 @@
     private val kosmos = testKosmos().apply { applicationContext = spyContext }
     private val testScope = kosmos.testScope
 
-    private val mediaDataFilter: MediaDataFilterImpl = kosmos.mediaDataFilter
+    private val mediaDataFilter: MediaDataFilterImpl =
+        with(kosmos) {
+            mediaSmartspaceLogger = mockMediaSmartspaceLogger
+            mediaDataFilter
+        }
     private val activityStarter = kosmos.activityStarter
     private val icon: Icon = Icon.createWithResource(context, R.drawable.ic_media_play)
     private val smartspaceMediaData: SmartspaceMediaData =
@@ -72,6 +82,7 @@
             packageName = PACKAGE_NAME,
             recommendations = MediaTestHelper.getValidRecommendationList(icon),
         )
+    private val smartspaceLogger = kosmos.mockMediaSmartspaceLogger
 
     private val underTest: MediaRecommendationsInteractor =
         with(kosmos) {
@@ -138,8 +149,24 @@
 
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
 
-        underTest.removeMediaRecommendations(KEY_MEDIA_SMARTSPACE, intent, 0)
+        mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, smartspaceMediaData)
+        underTest.removeMediaRecommendations(
+            KEY_MEDIA_SMARTSPACE,
+            intent,
+            0,
+            SMARTSPACE_CARD_DISMISS_EVENT,
+            1
+        )
 
+        verify(smartspaceLogger)
+            .logSmartspaceCardUIEvent(
+                SMARTSPACE_CARD_DISMISS_EVENT,
+                SmallHash.hash(smartspaceMediaData.targetId),
+                Process.INVALID_UID,
+                surface = SURFACE,
+                cardinality = 1,
+                isRecommendationCard = true,
+            )
         verify(kosmos.mockBroadcastSender).sendBroadcast(eq(intent))
     }
 
@@ -151,7 +178,13 @@
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
         intent.component = ComponentName(PACKAGE_NAME, EXPORTED_SMARTSPACE_TRAMPOLINE_ACTIVITY_NAME)
 
-        underTest.removeMediaRecommendations(KEY_MEDIA_SMARTSPACE, intent, 0)
+        underTest.removeMediaRecommendations(
+            KEY_MEDIA_SMARTSPACE,
+            intent,
+            0,
+            SMARTSPACE_CARD_DISMISS_EVENT,
+            1
+        )
 
         verify(spyContext).startActivity(eq(intent))
     }
@@ -171,13 +204,26 @@
 
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
 
-        underTest.startClickIntent(expandable, intent)
+        mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, smartspaceMediaData)
+        underTest.startClickIntent(expandable, intent, SMARTSPACE_CARD_CLICK_EVENT, 1, 2, 3)
 
+        verify(smartspaceLogger)
+            .logSmartspaceCardUIEvent(
+                SMARTSPACE_CARD_CLICK_EVENT,
+                SmallHash.hash(smartspaceMediaData.targetId),
+                Process.INVALID_UID,
+                surface = SURFACE,
+                cardinality = 1,
+                isRecommendationCard = true,
+                interactedSubcardRank = 2,
+                interactedSubcardCardinality = 3
+            )
         verify(spyContext).startActivity(eq(intent))
     }
 
     companion object {
         private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
         private const val PACKAGE_NAME = "com.example.app"
+        private const val SURFACE = 4
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/util/MediaDiffUtilTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/util/MediaDiffUtilTest.kt
index 71685a4..005424b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/util/MediaDiffUtilTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/util/MediaDiffUtilTest.kt
@@ -47,7 +47,7 @@
                 oldList,
                 newList,
                 { commonViewModel, _ -> assertThat(commonViewModel).isEqualTo(mediaControl) },
-                { fail("Unexpected to update $it") },
+                { commonViewModel, _ -> fail("Unexpected to update $commonViewModel") },
                 { fail("Unexpected to remove $it") },
                 { commonViewModel, _, _ -> fail("Unexpected to move $commonViewModel ") },
             )
@@ -66,7 +66,7 @@
                 oldList,
                 newList,
                 { commonViewModel, _ -> assertThat(commonViewModel).isEqualTo(mediaRecs) },
-                { fail("Unexpected to update $it") },
+                { commonViewModel, _ -> fail("Unexpected to update $commonViewModel") },
                 { fail("Unexpected to remove $it") },
                 { commonViewModel, _, _ -> fail("Unexpected to move $commonViewModel ") },
             )
@@ -85,7 +85,7 @@
                 oldList,
                 newList,
                 { commonViewModel, _ -> fail("Unexpected to add $commonViewModel") },
-                { commonViewModel -> assertThat(commonViewModel).isNotEqualTo(mediaControl) },
+                { commonViewModel, _ -> assertThat(commonViewModel).isNotEqualTo(mediaControl) },
                 { fail("Unexpected to remove $it") },
                 { commonViewModel, _, _ -> fail("Unexpected to move $commonViewModel ") },
             )
@@ -104,7 +104,7 @@
                 oldList,
                 newList,
                 { commonViewModel, _ -> fail("Unexpected to add $commonViewModel") },
-                { commonViewModel -> assertThat(commonViewModel).isNotEqualTo(mediaRecs) },
+                { commonViewModel, _ -> assertThat(commonViewModel).isNotEqualTo(mediaRecs) },
                 { fail("Unexpected to remove $it") },
                 { commonViewModel, _, _ -> fail("Unexpected to move $commonViewModel ") },
             )
@@ -124,7 +124,7 @@
                 oldList,
                 newList,
                 { commonViewModel, _ -> fail("Unexpected to add $commonViewModel") },
-                { fail("Unexpected to update $it") },
+                { commonViewModel, _ -> fail("Unexpected to update $commonViewModel") },
                 { fail("Unexpected to remove $it") },
                 { commonViewModel, _, _ -> assertThat(commonViewModel).isEqualTo(mediaControl1) },
             )
@@ -145,7 +145,7 @@
                 oldList,
                 newList,
                 { commonViewModel, _ -> fail("Unexpected to add $commonViewModel") },
-                { fail("Unexpected to update $it") },
+                { commonViewModel, _ -> fail("Unexpected to update $commonViewModel") },
                 { fail("Unexpected to remove $it") },
                 { commonViewModel, _, _ -> assertThat(commonViewModel).isEqualTo(mediaRecs) },
             )
@@ -164,7 +164,7 @@
                 oldList,
                 newList,
                 { commonViewModel, _ -> fail("Unexpected to add $commonViewModel") },
-                { fail("Unexpected to update $it") },
+                { commonViewModel, _ -> fail("Unexpected to update $commonViewModel") },
                 { commonViewModel -> assertThat(commonViewModel).isEqualTo(mediaControl) },
                 { commonViewModel, _, _ -> fail("Unexpected to move $commonViewModel ") },
             )
@@ -183,7 +183,7 @@
                 oldList,
                 newList,
                 { commonViewModel, _ -> fail("Unexpected to add $commonViewModel") },
-                { fail("Unexpected to update $it") },
+                { commonViewModel, _ -> fail("Unexpected to update $commonViewModel") },
                 { commonViewModel -> assertThat(commonViewModel).isEqualTo(mediaRecs) },
                 { commonViewModel, _, _ -> fail("Unexpected to move $commonViewModel ") },
             )
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelTest.kt
index 0551bfb..067b00c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelTest.kt
@@ -33,13 +33,14 @@
 import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
 import com.android.systemui.media.controls.domain.pipeline.interactor.mediaRecommendationsInteractor
 import com.android.systemui.media.controls.domain.pipeline.mediaDataFilter
+import com.android.systemui.media.controls.shared.mediaLogger
+import com.android.systemui.media.controls.shared.mockMediaLogger
 import com.android.systemui.media.controls.shared.model.MediaData
 import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
 import com.android.systemui.statusbar.notification.collection.provider.visualStabilityProvider
 import com.android.systemui.statusbar.notificationLockscreenUserManager
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
@@ -48,12 +49,16 @@
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers
 import org.mockito.Mockito
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.never
+import org.mockito.kotlin.reset
+import org.mockito.kotlin.verify
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class MediaCarouselViewModelTest : SysuiTestCase() {
 
-    private val kosmos = testKosmos()
+    private val kosmos = testKosmos().apply { mediaLogger = mockMediaLogger }
     private val testScope = kosmos.testScope
 
     private val mediaDataFilter: MediaDataFilterImpl = kosmos.mediaDataFilter
@@ -166,6 +171,64 @@
             assertThat(mediaControl.isMediaFromRec).isTrue()
         }
 
+    @Test
+    fun addMediaControlThenRemove_mediaEventsAreLogged() =
+        testScope.runTest {
+            val sortedMedia by collectLastValue(underTest.mediaItems)
+            val instanceId = InstanceId.fakeInstanceId(123)
+
+            loadMediaControl(KEY, instanceId)
+
+            val mediaControl = sortedMedia?.get(0) as MediaCommonViewModel.MediaControl
+            assertThat(mediaControl.instanceId).isEqualTo(instanceId)
+
+            // when media control is added to carousel
+            mediaControl.onAdded(mediaControl)
+
+            verify(kosmos.mediaLogger).logMediaCardAdded(eq(instanceId))
+
+            reset(kosmos.mediaLogger)
+
+            // when media control is updated.
+            mediaControl.onUpdated(mediaControl)
+
+            verify(kosmos.mediaLogger, never()).logMediaCardAdded(eq(instanceId))
+
+            mediaDataFilter.onMediaDataRemoved(KEY, true)
+            assertThat(sortedMedia).isEmpty()
+
+            // when media control is removed from carousel
+            mediaControl.onRemoved(true)
+
+            verify(kosmos.mediaLogger).logMediaCardRemoved(eq(instanceId))
+        }
+
+    @Test
+    fun addMediaRecommendationThenRemove_mediaEventsAreLogged() =
+        testScope.runTest {
+            val sortedMedia by collectLastValue(underTest.mediaItems)
+            kosmos.fakeFeatureFlagsClassic.set(Flags.MEDIA_RETAIN_RECOMMENDATIONS, false)
+
+            loadMediaRecommendations()
+
+            val mediaRecommendations =
+                sortedMedia?.get(0) as MediaCommonViewModel.MediaRecommendations
+            assertThat(mediaRecommendations.key).isEqualTo(KEY_MEDIA_SMARTSPACE)
+
+            // when media recommendation is added to carousel
+            mediaRecommendations.onAdded(mediaRecommendations)
+
+            verify(kosmos.mediaLogger).logMediaRecommendationCardAdded(eq(KEY_MEDIA_SMARTSPACE))
+
+            mediaDataFilter.onSmartspaceMediaDataRemoved(KEY, true)
+            assertThat(sortedMedia).isEmpty()
+
+            // when media recommendation is removed from carousel
+            mediaRecommendations.onRemoved(true)
+
+            verify(kosmos.mediaLogger).logMediaRecommendationCardRemoved(eq(KEY_MEDIA_SMARTSPACE))
+        }
+
     private fun loadMediaControl(key: String, instanceId: InstanceId, isPlaying: Boolean = true) {
         whenever(notificationLockscreenUserManager.isCurrentProfile(USER_ID)).thenReturn(true)
         whenever(notificationLockscreenUserManager.isProfileAvailable(USER_ID)).thenReturn(true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/navigation/data/repository/NavigationRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/navigation/data/repository/NavigationRepositoryTest.kt
new file mode 100644
index 0000000..e45aa05
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/navigation/data/repository/NavigationRepositoryTest.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.navigation.data.repository
+
+import android.view.WindowManagerPolicyConstants
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.navigationbar.NavigationModeController.ModeChangedListener
+import com.android.systemui.navigationbar.navigationModeController
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class NavigationRepositoryTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val navigationModeControllerMock = kosmos.navigationModeController
+
+    private val underTest = kosmos.navigationRepository
+
+    private var currentMode = WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON
+    private val modeChangedListeners = mutableListOf<ModeChangedListener>()
+
+    @Before
+    fun setUp() {
+        whenever(navigationModeControllerMock.addListener(any())).thenAnswer { invocation ->
+            val listener = invocation.arguments[0] as ModeChangedListener
+            modeChangedListeners.add(listener)
+            currentMode
+        }
+    }
+
+    @Test
+    fun isGesturalMode() =
+        testScope.runTest {
+            val isGesturalMode by collectLastValue(underTest.isGesturalMode)
+            assertThat(isGesturalMode).isFalse()
+
+            currentMode = WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL
+            notifyModeChangedListeners()
+            assertThat(isGesturalMode).isTrue()
+
+            currentMode = WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON
+            notifyModeChangedListeners()
+            assertThat(isGesturalMode).isFalse()
+        }
+
+    private fun notifyModeChangedListeners() {
+        modeChangedListeners.forEach { listener -> listener.onNavigationModeChanged(currentMode) }
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/navigation/domain/interactor/NavigationInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/navigation/domain/interactor/NavigationInteractorTest.kt
new file mode 100644
index 0000000..88beeb2
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/navigation/domain/interactor/NavigationInteractorTest.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.navigation.domain.interactor
+
+import android.view.WindowManagerPolicyConstants
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.navigationbar.NavigationModeController.ModeChangedListener
+import com.android.systemui.navigationbar.navigationModeController
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class NavigationInteractorTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val navigationModeControllerMock = kosmos.navigationModeController
+
+    private val underTest = kosmos.navigationInteractor
+
+    private var currentMode = WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON
+    private val modeChangedListeners = mutableListOf<ModeChangedListener>()
+
+    @Before
+    fun setUp() {
+        whenever(navigationModeControllerMock.addListener(any())).thenAnswer { invocation ->
+            val listener = invocation.arguments[0] as ModeChangedListener
+            modeChangedListeners.add(listener)
+            currentMode
+        }
+    }
+
+    @Test
+    fun isGesturalMode() =
+        testScope.runTest {
+            val isGesturalMode by collectLastValue(underTest.isGesturalMode)
+            assertThat(isGesturalMode).isFalse()
+
+            currentMode = WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL
+            notifyModeChangedListeners()
+            assertThat(isGesturalMode).isTrue()
+
+            currentMode = WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON
+            notifyModeChangedListeners()
+            assertThat(isGesturalMode).isFalse()
+        }
+
+    private fun notifyModeChangedListeners() {
+        modeChangedListeners.forEach { listener -> listener.onNavigationModeChanged(currentMode) }
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneViewModelTest.kt
index cb4e2d3..16c7090 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneViewModelTest.kt
@@ -28,12 +28,14 @@
 import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
 import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
 import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.domain.resolver.homeSceneFamilyResolver
 import com.android.systemui.scene.shared.model.SceneFamilies
 import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.shade.data.repository.fakeShadeRepository
 import com.android.systemui.shade.ui.viewmodel.notificationsShadeSceneViewModel
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
@@ -56,7 +58,7 @@
     private val sceneInteractor by lazy { kosmos.sceneInteractor }
     private val deviceUnlockedInteractor by lazy { kosmos.deviceUnlockedInteractor }
 
-    private val underTest = kosmos.notificationsShadeSceneViewModel
+    private val underTest by lazy { kosmos.notificationsShadeSceneViewModel }
 
     @Test
     fun upTransitionSceneKey_deviceLocked_lockscreen() =
@@ -65,11 +67,23 @@
             lockDevice()
 
             assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(SceneFamilies.Home)
+            assertThat(destinationScenes?.get(Swipe.Down)).isNull()
             assertThat(kosmos.homeSceneFamilyResolver.resolvedScene.value)
                 .isEqualTo(Scenes.Lockscreen)
         }
 
     @Test
+    fun upTransitionSceneKey_deviceLocked_keyguardDisabled_gone() =
+        testScope.runTest {
+            val destinationScenes by collectLastValue(underTest.destinationScenes)
+            lockDevice()
+            kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(false)
+
+            assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(SceneFamilies.Home)
+            assertThat(kosmos.homeSceneFamilyResolver.resolvedScene.value).isEqualTo(Scenes.Gone)
+        }
+
+    @Test
     fun upTransitionSceneKey_deviceUnlocked_gone() =
         testScope.runTest {
             val destinationScenes by collectLastValue(underTest.destinationScenes)
@@ -77,6 +91,33 @@
             unlockDevice()
 
             assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(SceneFamilies.Home)
+            assertThat(destinationScenes?.get(Swipe.Down)).isNull()
+            assertThat(sceneInteractor.currentScene.value).isEqualTo(Scenes.Gone)
+        }
+
+    @Test
+    fun downTransitionSceneKey_deviceLocked_bottomAligned_lockscreen() =
+        testScope.runTest {
+            kosmos.fakeShadeRepository.setDualShadeAlignedToBottom(true)
+            val destinationScenes by collectLastValue(underTest.destinationScenes)
+            lockDevice()
+
+            assertThat(destinationScenes?.get(Swipe.Down)?.toScene).isEqualTo(SceneFamilies.Home)
+            assertThat(destinationScenes?.get(Swipe.Up)).isNull()
+            assertThat(kosmos.homeSceneFamilyResolver.resolvedScene.value)
+                .isEqualTo(Scenes.Lockscreen)
+        }
+
+    @Test
+    fun downTransitionSceneKey_deviceUnlocked_bottomAligned_gone() =
+        testScope.runTest {
+            kosmos.fakeShadeRepository.setDualShadeAlignedToBottom(true)
+            val destinationScenes by collectLastValue(underTest.destinationScenes)
+            lockDevice()
+            unlockDevice()
+
+            assertThat(destinationScenes?.get(Swipe.Down)?.toScene).isEqualTo(SceneFamilies.Home)
+            assertThat(destinationScenes?.get(Swipe.Up)).isNull()
             assertThat(sceneInteractor.currentScene.value).isEqualTo(Scenes.Gone)
         }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/PaginatedGridRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/PaginatedGridRepositoryTest.kt
new file mode 100644
index 0000000..14d6094
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/PaginatedGridRepositoryTest.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.data.repository
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.res.R
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class PaginatedGridRepositoryTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+
+    val underTest = kosmos.paginatedGridRepository
+
+    @Test
+    fun rows_followsConfig() =
+        with(kosmos) {
+            testScope.runTest {
+                val rows by collectLastValue(underTest.rows)
+
+                setRowsInConfig(3)
+                assertThat(rows).isEqualTo(3)
+
+                setRowsInConfig(6)
+                assertThat(rows).isEqualTo(6)
+            }
+        }
+
+    private fun setRowsInConfig(rows: Int) =
+        with(kosmos) {
+            testCase.context.orCreateTestableResources.addOverride(
+                R.integer.quick_settings_max_rows,
+                rows,
+            )
+            fakeConfigurationRepository.onConfigurationChange()
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepositoryTest.kt
new file mode 100644
index 0000000..8ac5b6c
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QSPreferencesRepositoryTest.kt
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.data.repository
+
+import android.content.Context
+import android.content.SharedPreferences
+import android.content.pm.UserInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.settings.userFileManager
+import com.android.systemui.testKosmos
+import com.android.systemui.user.data.repository.fakeUserRepository
+import com.android.systemui.user.data.repository.userRepository
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class QSPreferencesRepositoryTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+    private val underTest = with(kosmos) { qsPreferencesRepository }
+
+    @Test
+    fun showLabels_updatesFromSharedPreferences() =
+        with(kosmos) {
+            testScope.runTest {
+                val latest by collectLastValue(underTest.showLabels)
+                assertThat(latest).isFalse()
+
+                setShowLabelsInSharedPreferences(true)
+                assertThat(latest).isTrue()
+
+                setShowLabelsInSharedPreferences(false)
+                assertThat(latest).isFalse()
+            }
+        }
+
+    @Test
+    fun showLabels_updatesFromUserChange() =
+        with(kosmos) {
+            testScope.runTest {
+                fakeUserRepository.setUserInfos(USERS)
+                val latest by collectLastValue(underTest.showLabels)
+
+                fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)
+                setShowLabelsInSharedPreferences(false)
+
+                fakeUserRepository.setSelectedUserInfo(ANOTHER_USER)
+                setShowLabelsInSharedPreferences(true)
+
+                fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)
+                assertThat(latest).isFalse()
+            }
+        }
+
+    @Test
+    fun setShowLabels_inSharedPreferences() {
+        underTest.setShowLabels(false)
+        assertThat(getShowLabelsFromSharedPreferences(true)).isFalse()
+
+        underTest.setShowLabels(true)
+        assertThat(getShowLabelsFromSharedPreferences(false)).isTrue()
+    }
+
+    @Test
+    fun setShowLabels_forDifferentUser() =
+        with(kosmos) {
+            testScope.runTest {
+                fakeUserRepository.setUserInfos(USERS)
+
+                fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)
+                underTest.setShowLabels(false)
+                assertThat(getShowLabelsFromSharedPreferences(true)).isFalse()
+
+                fakeUserRepository.setSelectedUserInfo(ANOTHER_USER)
+                underTest.setShowLabels(true)
+                assertThat(getShowLabelsFromSharedPreferences(false)).isTrue()
+
+                fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)
+                assertThat(getShowLabelsFromSharedPreferences(true)).isFalse()
+            }
+        }
+
+    private fun getSharedPreferences(): SharedPreferences =
+        with(kosmos) {
+            return userFileManager.getSharedPreferences(
+                QSPreferencesRepository.FILE_NAME,
+                Context.MODE_PRIVATE,
+                userRepository.getSelectedUserInfo().id,
+            )
+        }
+
+    private fun setShowLabelsInSharedPreferences(value: Boolean) {
+        getSharedPreferences().edit().putBoolean(ICON_LABELS_KEY, value).apply()
+    }
+
+    private fun getShowLabelsFromSharedPreferences(defaultValue: Boolean): Boolean {
+        return getSharedPreferences().getBoolean(ICON_LABELS_KEY, defaultValue)
+    }
+
+    companion object {
+        private const val ICON_LABELS_KEY = "show_icon_labels"
+        private const val PRIMARY_USER_ID = 0
+        private val PRIMARY_USER = UserInfo(PRIMARY_USER_ID, "user 0", UserInfo.FLAG_MAIN)
+        private const val ANOTHER_USER_ID = 1
+        private val ANOTHER_USER = UserInfo(ANOTHER_USER_ID, "user 1", UserInfo.FLAG_FULL)
+        private val USERS = listOf(PRIMARY_USER, ANOTHER_USER)
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryTest.kt
new file mode 100644
index 0000000..ae6f576
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryTest.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.data.repository
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.res.R
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class QuickQuickSettingsRowRepositoryTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+
+    private val underTest = kosmos.quickQuickSettingsRowRepository
+
+    @Test
+    fun rows_followsConfig() =
+        with(kosmos) {
+            testScope.runTest {
+                val rows by collectLastValue(underTest.rows)
+
+                setRowsInConfig(2)
+                assertThat(rows).isEqualTo(2)
+
+                setRowsInConfig(3)
+                assertThat(rows).isEqualTo(3)
+            }
+        }
+
+    private fun setRowsInConfig(rows: Int) =
+        with(kosmos) {
+            testCase.context.orCreateTestableResources.addOverride(
+                R.integer.quick_qs_panel_max_rows,
+                rows,
+            )
+            fakeConfigurationRepository.onConfigurationChange()
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/GridConsistencyInteractorTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractorTest.kt
new file mode 100644
index 0000000..7ad904e
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractorTest.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.domain.interactor
+
+import android.content.pm.UserInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.android.systemui.user.data.repository.fakeUserRepository
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class IconLabelVisibilityInteractorTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+    private val underTest = with(kosmos) { iconLabelVisibilityInteractor }
+
+    @Before
+    fun setUp() {
+        with(kosmos) { fakeUserRepository.setUserInfos(USERS) }
+    }
+
+    @Test
+    fun changingShowLabels_receivesCorrectShowLabels() =
+        with(kosmos) {
+            testScope.runTest {
+                val showLabels by collectLastValue(underTest.showLabels)
+
+                underTest.setShowLabels(false)
+                runCurrent()
+                assertThat(showLabels).isFalse()
+
+                underTest.setShowLabels(true)
+                runCurrent()
+                assertThat(showLabels).isTrue()
+            }
+        }
+
+    @Test
+    fun changingUser_receivesCorrectShowLabels() =
+        with(kosmos) {
+            testScope.runTest {
+                val showLabels by collectLastValue(underTest.showLabels)
+
+                fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)
+                underTest.setShowLabels(false)
+                runCurrent()
+                assertThat(showLabels).isFalse()
+
+                fakeUserRepository.setSelectedUserInfo(ANOTHER_USER)
+                underTest.setShowLabels(true)
+                runCurrent()
+                assertThat(showLabels).isTrue()
+
+                fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)
+                runCurrent()
+                assertThat(showLabels).isFalse()
+            }
+        }
+
+    companion object {
+        private val PRIMARY_USER = UserInfo(0, "user 0", UserInfo.FLAG_MAIN)
+        private val ANOTHER_USER = UserInfo(1, "user 1", UserInfo.FLAG_FULL)
+        private val USERS = listOf(PRIMARY_USER, ANOTHER_USER)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorTest.kt
similarity index 100%
rename from packages/SystemUI/tests/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorTest.kt
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropStateTest.kt
new file mode 100644
index 0000000..1c3021e
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropStateTest.kt
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.ui.compose
+
+import androidx.compose.runtime.mutableStateOf
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.common.shared.model.Text
+import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class DragAndDropStateTest : SysuiTestCase() {
+    private val listState = EditTileListState(TestEditTiles)
+    private val underTest = DragAndDropState(mutableStateOf(null), listState)
+
+    @Test
+    fun isMoving_returnsCorrectValue() {
+        // Asserts no tiles is moving
+        TestEditTiles.forEach { assertThat(underTest.isMoving(it.tileSpec)).isFalse() }
+
+        // Start the drag movement
+        val movingTileSpec = TestEditTiles[0].tileSpec
+        underTest.onStarted(movingTileSpec)
+
+        // Assert that the correct tile is marked as moving
+        TestEditTiles.forEach {
+            assertThat(underTest.isMoving(it.tileSpec)).isEqualTo(movingTileSpec == it.tileSpec)
+        }
+    }
+
+    @Test
+    fun onMoved_updatesList() {
+        val movingTileSpec = TestEditTiles[0].tileSpec
+
+        // Start the drag movement
+        underTest.onStarted(movingTileSpec)
+
+        // Move the tile to the end of the list
+        underTest.onMoved(listState.tiles[5].tileSpec)
+        assertThat(underTest.currentPosition()).isEqualTo(5)
+
+        // Move the tile to the middle of the list
+        underTest.onMoved(listState.tiles[2].tileSpec)
+        assertThat(underTest.currentPosition()).isEqualTo(2)
+    }
+
+    @Test
+    fun onDrop_resetsMovingTile() {
+        val movingTileSpec = TestEditTiles[0].tileSpec
+
+        // Start the drag movement
+        underTest.onStarted(movingTileSpec)
+
+        // Move the tile to the end of the list
+        underTest.onMoved(listState.tiles[5].tileSpec)
+
+        // Drop the tile
+        underTest.onDrop()
+
+        // Asserts no tiles is moving
+        TestEditTiles.forEach { assertThat(underTest.isMoving(it.tileSpec)).isFalse() }
+    }
+
+    companion object {
+        private fun createEditTile(tileSpec: String): EditTileViewModel {
+            return EditTileViewModel(
+                tileSpec = TileSpec.create(tileSpec),
+                icon = Icon.Resource(0, null),
+                label = Text.Loaded("unused"),
+                appName = null,
+                isCurrent = true,
+                availableEditActions = emptySet(),
+            )
+        }
+
+        private val TestEditTiles =
+            listOf(
+                createEditTile("tileA"),
+                createEditTile("tileB"),
+                createEditTile("tileC"),
+                createEditTile("tileD"),
+                createEditTile("tileE"),
+                createEditTile("tileF"),
+            )
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt
new file mode 100644
index 0000000..517b601
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.ui.compose
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.common.shared.model.Text
+import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class EditTileListStateTest : SysuiTestCase() {
+    val underTest = EditTileListState(TestEditTiles)
+
+    @Test
+    fun movingNonExistentTile_listUnchanged() {
+        underTest.move(TileSpec.create("other_tile"), TestEditTiles[0].tileSpec)
+
+        assertThat(underTest.tiles).containsExactly(*TestEditTiles.toTypedArray())
+    }
+
+    @Test
+    fun movingTileToNonExistentTarget_listUnchanged() {
+        underTest.move(TestEditTiles[0].tileSpec, TileSpec.create("other_tile"))
+
+        assertThat(underTest.tiles).containsExactly(*TestEditTiles.toTypedArray())
+    }
+
+    @Test
+    fun movingTileToItself_listUnchanged() {
+        underTest.move(TestEditTiles[0].tileSpec, TestEditTiles[0].tileSpec)
+
+        assertThat(underTest.tiles).containsExactly(*TestEditTiles.toTypedArray())
+    }
+
+    @Test
+    fun movingTileToSameSection_listUpdates() {
+        // Move tile at index 0 to index 1. Tile 0 should remain current.
+        underTest.move(TestEditTiles[0].tileSpec, TestEditTiles[1].tileSpec)
+
+        // Assert the tiles 0 and 1 have changed places.
+        assertThat(underTest.tiles[0]).isEqualTo(TestEditTiles[1])
+        assertThat(underTest.tiles[1]).isEqualTo(TestEditTiles[0])
+
+        // Assert the rest of the list is unchanged
+        assertThat(underTest.tiles.subList(2, 5))
+            .containsExactly(*TestEditTiles.subList(2, 5).toTypedArray())
+    }
+
+    @Test
+    fun movingTileToDifferentSection_listAndTileUpdates() {
+        // Move tile at index 0 to index 3. Tile 0 should no longer be current.
+        underTest.move(TestEditTiles[0].tileSpec, TestEditTiles[3].tileSpec)
+
+        // Assert tile 0 is now at index 3 and is no longer current.
+        assertThat(underTest.tiles[3]).isEqualTo(TestEditTiles[0].copy(isCurrent = false))
+
+        // Assert previous tiles have shifted places
+        assertThat(underTest.tiles[0]).isEqualTo(TestEditTiles[1])
+        assertThat(underTest.tiles[1]).isEqualTo(TestEditTiles[2])
+        assertThat(underTest.tiles[2]).isEqualTo(TestEditTiles[3])
+
+        // Assert the rest of the list is unchanged
+        assertThat(underTest.tiles.subList(4, 5))
+            .containsExactly(*TestEditTiles.subList(4, 5).toTypedArray())
+    }
+
+    companion object {
+        private fun createEditTile(tileSpec: String, isCurrent: Boolean): EditTileViewModel {
+            return EditTileViewModel(
+                tileSpec = TileSpec.create(tileSpec),
+                icon = Icon.Resource(0, null),
+                label = Text.Loaded("unused"),
+                appName = null,
+                isCurrent = isCurrent,
+                availableEditActions = emptySet(),
+            )
+        }
+
+        private val TestEditTiles =
+            listOf(
+                createEditTile("tileA", true),
+                createEditTile("tileB", true),
+                createEditTile("tileC", true),
+                createEditTile("tileD", false),
+                createEditTile("tileE", false),
+                createEditTile("tileF", false),
+            )
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayoutTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayoutTest.kt
new file mode 100644
index 0000000..914a095
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayoutTest.kt
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.ui.compose
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.qs.panels.data.repository.IconTilesRepository
+import com.android.systemui.qs.panels.data.repository.iconTilesRepository
+import com.android.systemui.qs.panels.ui.viewmodel.MockTileViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.fixedColumnsSizeViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.iconTilesViewModel
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class InfiniteGridLayoutTest : SysuiTestCase() {
+    private val kosmos =
+        testKosmos().apply {
+            iconTilesRepository =
+                object : IconTilesRepository {
+                    override fun isIconTile(spec: TileSpec): Boolean {
+                        return spec.spec.startsWith("small")
+                    }
+                }
+        }
+
+    private val underTest =
+        with(kosmos) {
+            InfiniteGridLayout(
+                iconTilesViewModel,
+                fixedColumnsSizeViewModel,
+            )
+        }
+
+    @Test
+    fun correctPagination_underOnePage_sameOrder() =
+        with(kosmos) {
+            testScope.runTest {
+                val rows = 3
+                val columns = 4
+
+                val tiles =
+                    listOf(
+                        largeTile(),
+                        smallTile(),
+                        smallTile(),
+                        largeTile(),
+                        largeTile(),
+                        smallTile()
+                    )
+
+                val pages = underTest.splitIntoPages(tiles, rows = rows, columns = columns)
+
+                assertThat(pages).hasSize(1)
+                assertThat(pages[0]).isEqualTo(tiles)
+            }
+        }
+
+    @Test
+    fun correctPagination_twoPages_sameOrder() =
+        with(kosmos) {
+            testScope.runTest {
+                val rows = 3
+                val columns = 4
+
+                val tiles =
+                    listOf(
+                        largeTile(),
+                        smallTile(),
+                        smallTile(),
+                        largeTile(),
+                        largeTile(),
+                        smallTile(),
+                        smallTile(),
+                        largeTile(),
+                        largeTile(),
+                        smallTile(),
+                        smallTile(),
+                        largeTile(),
+                    )
+                // --- Page 1 ---
+                // [L L] [S] [S]
+                // [L L] [L L]
+                // [S] [S] [L L]
+                // --- Page 2 ---
+                // [L L] [S] [S]
+                // [L L]
+
+                val pages = underTest.splitIntoPages(tiles, rows = rows, columns = columns)
+
+                assertThat(pages).hasSize(2)
+                assertThat(pages[0]).isEqualTo(tiles.take(8))
+                assertThat(pages[1]).isEqualTo(tiles.drop(8))
+            }
+        }
+
+    companion object {
+        fun largeTile() = MockTileViewModel(TileSpec.create("large"))
+
+        fun smallTile() = MockTileViewModel(TileSpec.create("small"))
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/PaginatableGridLayoutTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/PaginatableGridLayoutTest.kt
new file mode 100644
index 0000000..6df3f8d
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/PaginatableGridLayoutTest.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.ui.compose
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.qs.panels.shared.model.SizedTile
+import com.android.systemui.qs.panels.ui.viewmodel.MockTileViewModel
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class PaginatableGridLayoutTest : SysuiTestCase() {
+    @Test
+    fun correctRows_gapsAtEnd() {
+        val columns = 6
+
+        val sizedTiles =
+            listOf(
+                largeTile(),
+                extraLargeTile(),
+                largeTile(),
+                smallTile(),
+                largeTile(),
+            )
+
+        // [L L] [XL XL XL]
+        // [L L] [S] [L L]
+
+        val rows = PaginatableGridLayout.splitInRows(sizedTiles, columns)
+
+        assertThat(rows).hasSize(2)
+        assertThat(rows[0]).isEqualTo(sizedTiles.take(2))
+        assertThat(rows[1]).isEqualTo(sizedTiles.drop(2))
+    }
+
+    @Test
+    fun correctRows_fullLastRow_noEmptyRow() {
+        val columns = 6
+
+        val sizedTiles =
+            listOf(
+                largeTile(),
+                extraLargeTile(),
+                smallTile(),
+            )
+
+        // [L L] [XL XL XL] [S]
+
+        val rows = PaginatableGridLayout.splitInRows(sizedTiles, columns)
+
+        assertThat(rows).hasSize(1)
+        assertThat(rows[0]).isEqualTo(sizedTiles)
+    }
+
+    companion object {
+        fun extraLargeTile() = SizedTile(MockTileViewModel(TileSpec.create("XLarge")), 3)
+
+        fun largeTile() = SizedTile(MockTileViewModel(TileSpec.create("large")), 2)
+
+        fun smallTile() = SizedTile(MockTileViewModel(TileSpec.create("small")), 1)
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayoutTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayoutTest.kt
new file mode 100644
index 0000000..3354b4d4
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayoutTest.kt
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.ui.compose
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.qs.panels.data.repository.IconTilesRepository
+import com.android.systemui.qs.panels.data.repository.iconTilesRepository
+import com.android.systemui.qs.panels.ui.viewmodel.MockTileViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.iconTilesViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.partitionedGridViewModel
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class PartitionedGridLayoutTest : SysuiTestCase() {
+    private val kosmos =
+        testKosmos().apply {
+            iconTilesRepository =
+                object : IconTilesRepository {
+                    override fun isIconTile(spec: TileSpec): Boolean {
+                        return spec.spec.startsWith("small")
+                    }
+                }
+        }
+
+    private val underTest = with(kosmos) { PartitionedGridLayout(partitionedGridViewModel) }
+
+    @Test
+    fun correctPagination_underOnePage_partitioned_sameRelativeOrder() =
+        with(kosmos) {
+            testScope.runTest {
+                val rows = 3
+                val columns = 4
+
+                val tiles =
+                    listOf(
+                        largeTile(),
+                        smallTile(),
+                        smallTile(),
+                        largeTile(),
+                        largeTile(),
+                        smallTile()
+                    )
+                val (smallTiles, largeTiles) =
+                    tiles.partition { iconTilesViewModel.isIconTile(it.spec) }
+
+                // [L L] [L L]
+                // [L L]
+                // [S] [S] [S]
+
+                val pages = underTest.splitIntoPages(tiles, rows = rows, columns = columns)
+
+                Truth.assertThat(pages).hasSize(1)
+                Truth.assertThat(pages[0]).isEqualTo(largeTiles + smallTiles)
+            }
+        }
+
+    @Test
+    fun correctPagination_twoPages_partitioned_sameRelativeOrder() =
+        with(kosmos) {
+            testScope.runTest {
+                val rows = 3
+                val columns = 4
+
+                val tiles =
+                    listOf(
+                        largeTile(),
+                        smallTile(),
+                        smallTile(),
+                        largeTile(),
+                        smallTile(),
+                        smallTile(),
+                        largeTile(),
+                        smallTile(),
+                        smallTile(),
+                    )
+                // --- Page 1 ---
+                // [L L] [L L]
+                // [L L]
+                // [S] [S] [S] [S]
+                // --- Page 2 ---
+                // [S] [S]
+
+                val (smallTiles, largeTiles) =
+                    tiles.partition { iconTilesViewModel.isIconTile(it.spec) }
+
+                val pages = underTest.splitIntoPages(tiles, rows = rows, columns = columns)
+
+                val expectedPage0 = largeTiles + smallTiles.take(4)
+                val expectedPage1 = smallTiles.drop(4)
+
+                Truth.assertThat(pages).hasSize(2)
+                Truth.assertThat(pages[0]).isEqualTo(expectedPage0)
+                Truth.assertThat(pages[1]).isEqualTo(expectedPage1)
+            }
+        }
+
+    companion object {
+        fun largeTile() = MockTileViewModel(TileSpec.create("large"))
+
+        fun smallTile() = MockTileViewModel(TileSpec.create("small"))
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
index 8b49d43..601779f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
@@ -54,8 +54,10 @@
 import com.android.systemui.settings.userTracker
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -103,9 +105,7 @@
             appName2,
         )
 
-    private val underTest: EditModeViewModel by lazy {
-        kosmos.editModeViewModel
-    }
+    private val underTest: EditModeViewModel by lazy { kosmos.editModeViewModel }
 
     @Before
     fun setUp() {
@@ -461,31 +461,87 @@
         }
 
     @Test
-    fun tileNotAvailable_notShowing() = with(kosmos) {
-        testScope.runTest {
-            val unavailableTile = "work"
-            qsTileFactory = FakeQSFactory { spec ->
-                FakeQSTile(userTracker.userId, spec != unavailableTile)
-            }
-            tileAvailabilityInteractorsMap = mapOf(
-                    unavailableTile to FakeTileAvailabilityInteractor(
-                            emptyMap<Int, Flow<Boolean>>().withDefault { flowOf(false) }
+    fun tileNotAvailable_notShowing() =
+        with(kosmos) {
+            testScope.runTest {
+                val unavailableTile = "work"
+                qsTileFactory = FakeQSFactory { spec ->
+                    FakeQSTile(userTracker.userId, spec != unavailableTile)
+                }
+                tileAvailabilityInteractorsMap =
+                    mapOf(
+                        unavailableTile to
+                            FakeTileAvailabilityInteractor(
+                                emptyMap<Int, Flow<Boolean>>().withDefault { flowOf(false) }
+                            )
                     )
-            )
-            val tiles by collectLastValue(underTest.tiles)
-            val currentTiles =
+                val tiles by collectLastValue(underTest.tiles)
+                val currentTiles =
                     mutableListOf(
-                            TileSpec.create("flashlight"),
-                            TileSpec.create("airplane"),
-                            TileSpec.create("alarm"),
+                        TileSpec.create("flashlight"),
+                        TileSpec.create("airplane"),
+                        TileSpec.create("alarm"),
                     )
-            currentTilesInteractor.setTiles(currentTiles)
+                currentTilesInteractor.setTiles(currentTiles)
 
-            underTest.startEditing()
+                underTest.startEditing()
 
-            assertThat(tiles!!.none { it.tileSpec == TileSpec.create(unavailableTile) }).isTrue()
+                assertThat(tiles!!.none { it.tileSpec == TileSpec.create(unavailableTile) })
+                    .isTrue()
+            }
         }
-    }
+
+    @OptIn(ExperimentalCoroutinesApi::class)
+    @Test
+    fun currentTiles_moveTileDown() =
+        with(kosmos) {
+            testScope.runTest {
+                val tiles by collectLastValue(underTest.tiles)
+                val currentTiles =
+                    mutableListOf(
+                        TileSpec.create("flashlight"),
+                        TileSpec.create("airplane"),
+                        TileSpec.create("internet"),
+                        TileSpec.create("alarm"),
+                    )
+                currentTilesInteractor.setTiles(currentTiles)
+                underTest.startEditing()
+                runCurrent()
+
+                // Move flashlight tile to index 3
+                underTest.addTile(TileSpec.create("flashlight"), 3)
+
+                assertThat(tiles!!.filter { it.isCurrent }.map { it.tileSpec.spec })
+                    .containsExactly("airplane", "internet", "alarm", "flashlight")
+                    .inOrder()
+            }
+        }
+
+    @OptIn(ExperimentalCoroutinesApi::class)
+    @Test
+    fun currentTiles_moveTileUp() =
+        with(kosmos) {
+            testScope.runTest {
+                val tiles by collectLastValue(underTest.tiles)
+                val currentTiles =
+                    mutableListOf(
+                        TileSpec.create("flashlight"),
+                        TileSpec.create("airplane"),
+                        TileSpec.create("internet"),
+                        TileSpec.create("alarm"),
+                    )
+                currentTilesInteractor.setTiles(currentTiles)
+                underTest.startEditing()
+                runCurrent()
+
+                // Move alarm tile to index 0
+                underTest.addTile(TileSpec.create("alarm"), 0)
+
+                assertThat(tiles!!.filter { it.isCurrent }.map { it.tileSpec.spec })
+                    .containsExactly("alarm", "flashlight", "airplane", "internet")
+                    .inOrder()
+            }
+        }
 
     companion object {
         private val drawable1 = TestStubDrawable("drawable1")
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelTest.kt
new file mode 100644
index 0000000..d36a81b
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelTest.kt
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.ui.viewmodel
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.qs.panels.data.repository.IconTilesRepository
+import com.android.systemui.qs.panels.data.repository.iconTilesRepository
+import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.res.R
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class QuickQuickSettingsViewModelTest : SysuiTestCase() {
+
+    private val kosmos =
+        testKosmos().apply {
+            iconTilesRepository =
+                object : IconTilesRepository {
+                    override fun isIconTile(spec: TileSpec): Boolean {
+                        return spec.spec.startsWith(PREFIX_SMALL)
+                    }
+                }
+        }
+
+    private val underTest = kosmos.quickQuickSettingsViewModel
+
+    private val tiles =
+        listOf(
+                "$PREFIX_SMALL:1",
+                "$PREFIX_SMALL:2",
+                "$PREFIX_LARGE:3",
+                "$PREFIX_SMALL:4",
+                "$PREFIX_LARGE:5",
+                "$PREFIX_LARGE:6",
+                "$PREFIX_SMALL:7",
+                "$PREFIX_SMALL:8",
+                "$PREFIX_LARGE:9",
+            )
+            .map(TileSpec::create)
+
+    @Before
+    fun setUp() {
+        kosmos.setTiles(tiles)
+    }
+
+    @Test
+    fun splitIntoRows_onlyFirstTwoRowsOfTiles() =
+        with(kosmos) {
+            testScope.runTest {
+                setRows(2)
+                val columns by collectLastValue(underTest.columns)
+                val tileViewModels by collectLastValue(underTest.tileViewModels)
+
+                assertThat(columns).isEqualTo(4)
+                // All tiles in 4 columns
+                // [1] [2] [3 3]
+                // [4] [5 5]
+                // [6 6] [7] [8]
+                // [9 9]
+
+                assertThat(tileViewModels!!.map { it.tile.spec }).isEqualTo(tiles.take(5))
+            }
+        }
+
+    @Test
+    fun changeRows_tilesChange() =
+        with(kosmos) {
+            testScope.runTest {
+                setRows(2)
+                val columns by collectLastValue(underTest.columns)
+                val tileViewModels by collectLastValue(underTest.tileViewModels)
+
+                assertThat(columns).isEqualTo(4)
+                // All tiles in 4 columns
+                // [1] [2] [3 3]
+                // [4] [5 5]
+                // [6 6] [7] [8]
+                // [9 9]
+
+                setRows(3)
+                assertThat(tileViewModels!!.map { it.tile.spec }).isEqualTo(tiles.take(8))
+                setRows(1)
+                assertThat(tileViewModels!!.map { it.tile.spec }).isEqualTo(tiles.take(3))
+            }
+        }
+
+    @Test
+    fun changeTiles_tilesChange() =
+        with(kosmos) {
+            testScope.runTest {
+                setRows(2)
+                val columns by collectLastValue(underTest.columns)
+                val tileViewModels by collectLastValue(underTest.tileViewModels)
+
+                assertThat(columns).isEqualTo(4)
+                // All tiles in 4 columns
+                // [1] [2] [3 3]
+                // [4] [5 5]
+                // [6 6] [7] [8]
+                // [9 9]
+
+                // Remove tile small:4
+                currentTilesInteractor.removeTiles(setOf(tiles[3]))
+
+                assertThat(tileViewModels!!.map { it.tile.spec })
+                    .isEqualTo(
+                        listOf(
+                                "$PREFIX_SMALL:1",
+                                "$PREFIX_SMALL:2",
+                                "$PREFIX_LARGE:3",
+                                "$PREFIX_LARGE:5",
+                                "$PREFIX_LARGE:6",
+                            )
+                            .map(TileSpec::create)
+                    )
+            }
+        }
+
+    private fun Kosmos.setTiles(tiles: List<TileSpec>) {
+        currentTilesInteractor.setTiles(tiles)
+    }
+
+    private fun Kosmos.setRows(rows: Int) {
+        testCase.context.orCreateTestableResources.addOverride(
+            R.integer.quick_qs_panel_max_rows,
+            rows,
+        )
+        fakeConfigurationRepository.onConfigurationChange()
+    }
+
+    private companion object {
+        const val PREFIX_SMALL = "small"
+        const val PREFIX_LARGE = "large"
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt
index 9bb591e..8ad647d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt
@@ -25,6 +25,7 @@
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.qs.tiles.CastTile
 import com.android.systemui.statusbar.policy.CastController
+import com.android.systemui.statusbar.policy.CastDevice
 import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
@@ -73,9 +74,12 @@
     @Test
     fun onCastDevicesChanged_deviceNotConnectedOrConnecting_noSignal() = runTest {
         val device =
-            CastController.CastDevice().apply {
-                state = CastController.CastDevice.STATE_DISCONNECTED
-            }
+            CastDevice(
+                id = "id",
+                name = null,
+                state = CastDevice.CastState.Disconnected,
+                origin = CastDevice.CastOrigin.MediaProjection,
+            )
         whenever(castController.castDevices).thenReturn(listOf(device))
 
         val signal by collectLastValue(underTest.autoAddSignal(0))
@@ -91,11 +95,19 @@
     @Test
     fun onCastDevicesChanged_someDeviceConnecting_addSignal() = runTest {
         val disconnectedDevice =
-            CastController.CastDevice().apply {
-                state = CastController.CastDevice.STATE_DISCONNECTED
-            }
+            CastDevice(
+                id = "id",
+                name = null,
+                state = CastDevice.CastState.Disconnected,
+                origin = CastDevice.CastOrigin.MediaProjection,
+            )
         val connectingDevice =
-            CastController.CastDevice().apply { state = CastController.CastDevice.STATE_CONNECTING }
+            CastDevice(
+                id = "id",
+                name = null,
+                state = CastDevice.CastState.Connecting,
+                origin = CastDevice.CastOrigin.MediaProjection,
+            )
         whenever(castController.castDevices)
             .thenReturn(listOf(disconnectedDevice, connectingDevice))
 
@@ -112,11 +124,19 @@
     @Test
     fun onCastDevicesChanged_someDeviceConnected_addSignal() = runTest {
         val disconnectedDevice =
-            CastController.CastDevice().apply {
-                state = CastController.CastDevice.STATE_DISCONNECTED
-            }
+            CastDevice(
+                id = "id",
+                name = null,
+                state = CastDevice.CastState.Disconnected,
+                origin = CastDevice.CastOrigin.MediaProjection,
+            )
         val connectedDevice =
-            CastController.CastDevice().apply { state = CastController.CastDevice.STATE_CONNECTED }
+            CastDevice(
+                id = "id",
+                name = null,
+                state = CastDevice.CastState.Connected,
+                origin = CastDevice.CastOrigin.MediaProjection,
+            )
         whenever(castController.castDevices).thenReturn(listOf(disconnectedDevice, connectedDevice))
 
         val signal by collectLastValue(underTest.autoAddSignal(0))
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt
index b7e08da..ff40e43 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt
@@ -54,7 +54,7 @@
     @Before
     fun setup() {
         MockitoAnnotations.initMocks(this)
-        whenever(logBufferFactory.create(any(), any(), any())).thenReturn(logBuffer)
+        whenever(logBufferFactory.create(any(), any(), any(), any())).thenReturn(logBuffer)
         val tileSpec: TileSpec = TileSpec.create("chatty_tile")
         underTest =
             QSTileLogger(mapOf(tileSpec to chattyLogBuffer), logBufferFactory, statusBarController)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingDataInteractorTest.kt
new file mode 100644
index 0000000..2194c75
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingDataInteractorTest.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.impl.irecording
+
+import android.os.UserHandle
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.recordissue.IssueRecordingState
+import com.android.systemui.settings.fakeUserFileManager
+import com.android.systemui.settings.userTracker
+import com.google.common.truth.Truth
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class IssueRecordingDataInteractorTest : SysuiTestCase() {
+
+    private val kosmos = Kosmos().also { it.testCase = this }
+    private val userTracker = kosmos.userTracker
+    private val userFileManager = kosmos.fakeUserFileManager
+    private val testUser = UserHandle.of(1)
+
+    lateinit var state: IssueRecordingState
+    private lateinit var underTest: IssueRecordingDataInteractor
+
+    @Before
+    fun setup() {
+        state = IssueRecordingState(userTracker, userFileManager)
+        underTest = IssueRecordingDataInteractor(state, kosmos.testScope.testScheduler)
+    }
+
+    @OptIn(ExperimentalCoroutinesApi::class)
+    @Test
+    fun emitsEvent_whenIsRecordingStatusChanges_correctly() {
+        kosmos.testScope.runTest {
+            val data by
+                collectLastValue(
+                    underTest.tileData(testUser, flowOf(DataUpdateTrigger.InitialRequest))
+                )
+            runCurrent()
+            Truth.assertThat(data?.isRecording).isFalse()
+
+            state.isRecording = true
+            runCurrent()
+            Truth.assertThat(data?.isRecording).isTrue()
+
+            state.isRecording = false
+            runCurrent()
+            Truth.assertThat(data?.isRecording).isFalse()
+        }
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapperTest.kt
new file mode 100644
index 0000000..2444229
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapperTest.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.impl.irecording
+
+import android.content.res.mainResources
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testCase
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.qsEventLogger
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
+import com.android.systemui.recordissue.RecordIssueModule
+import com.android.systemui.res.R
+import com.google.common.truth.Truth
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class IssueRecordingMapperTest : SysuiTestCase() {
+    private val kosmos = Kosmos().also { it.testCase = this }
+    private val uiConfig =
+        QSTileUIConfig.Resource(R.drawable.qs_record_issue_icon_off, R.string.qs_record_issue_label)
+    private val config =
+        QSTileConfig(
+            TileSpec.create(RecordIssueModule.TILE_SPEC),
+            uiConfig,
+            kosmos.qsEventLogger.getNewInstanceId()
+        )
+    private val resources = kosmos.mainResources
+    private val theme = resources.newTheme()
+
+    @Test
+    fun whenData_isRecording_useCorrectResources() {
+        val underTest = IssueRecordingMapper(resources, theme)
+        val tileState = underTest.map(config, IssueRecordingModel(true))
+        Truth.assertThat(tileState.activationState).isEqualTo(QSTileState.ActivationState.ACTIVE)
+    }
+
+    @Test
+    fun whenData_isNotRecording_useCorrectResources() {
+        val underTest = IssueRecordingMapper(resources, theme)
+        val tileState = underTest.map(config, IssueRecordingModel(false))
+        Truth.assertThat(tileState.activationState).isEqualTo(QSTileState.ActivationState.INACTIVE)
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractorTest.kt
new file mode 100644
index 0000000..4e58069
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractorTest.kt
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.impl.irecording
+
+import android.os.UserHandle
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.dialogTransitionAnimator
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testCase
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.plugins.activityStarter
+import com.android.systemui.plugins.statusbar.statusBarStateController
+import com.android.systemui.qs.pipeline.domain.interactor.panelInteractor
+import com.android.systemui.qs.tiles.base.interactor.QSTileInput
+import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+import com.android.systemui.recordissue.RecordIssueDialogDelegate
+import com.android.systemui.settings.UserContextProvider
+import com.android.systemui.settings.userTracker
+import com.android.systemui.statusbar.phone.KeyguardDismissUtil
+import com.android.systemui.statusbar.policy.keyguardStateController
+import com.google.common.truth.Truth
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.mock
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class IssueRecordingUserActionInteractorTest : SysuiTestCase() {
+
+    val user = UserHandle(1)
+    val kosmos = Kosmos().also { it.testCase = this }
+
+    private lateinit var userContextProvider: UserContextProvider
+    private lateinit var underTest: IssueRecordingUserActionInteractor
+
+    private var hasCreatedDialogDelegate: Boolean = false
+
+    @Before
+    fun setup() {
+        hasCreatedDialogDelegate = false
+        with(kosmos) {
+            val factory =
+                object : RecordIssueDialogDelegate.Factory {
+                    override fun create(onStarted: Runnable): RecordIssueDialogDelegate {
+                        hasCreatedDialogDelegate = true
+
+                        // Inside some tests in presubmit, createDialog throws an error because
+                        // the test thread's looper hasn't been prepared, and Dialog.class
+                        // internally is creating a new handler. For testing, we only care that the
+                        // dialog is created, so using a mock is acceptable here.
+                        return mock(RecordIssueDialogDelegate::class.java)
+                    }
+                }
+
+            userContextProvider = userTracker
+            underTest =
+                IssueRecordingUserActionInteractor(
+                    testDispatcher,
+                    KeyguardDismissUtil(
+                        keyguardStateController,
+                        statusBarStateController,
+                        activityStarter
+                    ),
+                    keyguardStateController,
+                    dialogTransitionAnimator,
+                    panelInteractor,
+                    userTracker,
+                    factory
+                )
+        }
+    }
+
+    @Test
+    fun handleInput_showsPromptToStartRecording_whenNotRecordingAlready() {
+        kosmos.testScope.runTest {
+            underTest.handleInput(
+                QSTileInput(user, QSTileUserAction.Click(null), IssueRecordingModel(false))
+            )
+            Truth.assertThat(hasCreatedDialogDelegate).isTrue()
+        }
+    }
+
+    @Test
+    fun handleInput_attemptsToStopRecording_whenRecording() {
+        kosmos.testScope.runTest {
+            val input = QSTileInput(user, QSTileUserAction.Click(null), IssueRecordingModel(true))
+            try {
+                underTest.handleInput(input)
+            } catch (e: NullPointerException) {
+                // As of 06/07/2024, PendingIntent.startService is not easily mockable and throws
+                // an NPE inside IActivityManager. Catching that here and ignore it, then verify
+                // mock interactions were done correctly
+            }
+            Truth.assertThat(hasCreatedDialogDelegate).isFalse()
+        }
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
index 9ce2e0f..c33e2a4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
@@ -92,7 +92,8 @@
             runCurrent()
 
             assertThat(states()).isNotEmpty()
-            assertThat(states().first().label).isEqualTo(testTileData)
+            assertThat(states().last()).isNotNull()
+            assertThat(states().last()!!.label).isEqualTo(testTileData)
             verify(qsTileLogger).logInitialRequest(eq(tileConfig.tileSpec))
         }
 
@@ -196,6 +197,7 @@
             qsTileLogger,
             FakeSystemClock(),
             testCoroutineDispatcher,
+            testCoroutineDispatcher,
             scope.backgroundScope,
         )
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt
index 6066d24..7955f2f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt
@@ -256,6 +256,7 @@
             qsTileLogger,
             FakeSystemClock(),
             testCoroutineDispatcher,
+            testCoroutineDispatcher,
             scope.backgroundScope,
         )
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
index 5b6fea5..9249621 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.qs.ui.viewmodel
 
+import android.testing.TestableLooper.RunWithLooper
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.compose.animation.scene.Back
@@ -32,6 +33,7 @@
 import com.android.systemui.flags.Flags
 import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
 import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.media.controls.data.repository.mediaFilterRepository
@@ -42,9 +44,9 @@
 import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter
 import com.android.systemui.res.R
 import com.android.systemui.scene.domain.interactor.sceneBackInteractor
-import com.android.systemui.scene.domain.interactor.sceneContainerStartable
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.domain.resolver.homeSceneFamilyResolver
+import com.android.systemui.scene.domain.startable.sceneContainerStartable
 import com.android.systemui.scene.shared.model.SceneFamilies
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModel
@@ -64,6 +66,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
+@RunWithLooper
 @EnableSceneContainer
 class QuickSettingsSceneViewModelTest : SysuiTestCase() {
 
@@ -160,6 +163,37 @@
         }
 
     @Test
+    fun destinations_whenNotCustomizing_withPreviousSceneLockscreen_butLockscreenDisabled() =
+        testScope.runTest {
+            overrideResource(R.bool.config_use_split_notification_shade, false)
+            qsFlexiglassAdapter.setCustomizing(false)
+            val destinations by collectLastValue(underTest.destinationScenes)
+
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            val backScene by collectLastValue(sceneBackInteractor.backScene)
+            val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
+            sceneInteractor.changeScene(Scenes.Lockscreen, "reason")
+            sceneInteractor.changeScene(Scenes.QuickSettings, "reason")
+
+            kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(false)
+
+            assertThat(currentScene).isEqualTo(Scenes.Gone)
+            assertThat(backScene).isNull()
+            assertThat(destinations)
+                .isEqualTo(
+                    mapOf(
+                        Back to UserActionResult(Scenes.Shade),
+                        Swipe(SwipeDirection.Up) to UserActionResult(Scenes.Shade),
+                        Swipe(
+                            fromSource = Edge.Bottom,
+                            direction = SwipeDirection.Up,
+                        ) to UserActionResult(SceneFamilies.Home)
+                    )
+                )
+            assertThat(homeScene).isEqualTo(Scenes.Gone)
+        }
+
+    @Test
     fun destinations_whenNotCustomizing_authMethodSwipe_lockscreenNotDismissed() =
         testScope.runTest {
             overrideResource(R.bool.config_use_split_notification_shade, false)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelTest.kt
index ac67ac8..a7a3a0f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelTest.kt
@@ -19,6 +19,7 @@
 import android.testing.TestableLooper
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.compose.animation.scene.Back
 import com.android.compose.animation.scene.Swipe
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
@@ -28,13 +29,15 @@
 import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
 import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
 import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.qs.panels.ui.viewmodel.editModeViewModel
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.domain.resolver.homeSceneFamilyResolver
 import com.android.systemui.scene.shared.model.SceneFamilies
 import com.android.systemui.scene.shared.model.Scenes
-import com.android.systemui.shade.ui.viewmodel.quickSettingsShadeSceneViewModel
+import com.android.systemui.shade.data.repository.fakeShadeRepository
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -56,7 +59,7 @@
     private val sceneInteractor = kosmos.sceneInteractor
     private val deviceUnlockedInteractor = kosmos.deviceUnlockedInteractor
 
-    private val underTest = kosmos.quickSettingsShadeSceneViewModel
+    private val underTest by lazy { kosmos.quickSettingsShadeSceneViewModel }
 
     @Test
     fun upTransitionSceneKey_deviceLocked_lockscreen() =
@@ -66,10 +69,23 @@
             lockDevice()
 
             assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(SceneFamilies.Home)
+            assertThat(destinationScenes?.get(Swipe.Down)).isNull()
             assertThat(homeScene).isEqualTo(Scenes.Lockscreen)
         }
 
     @Test
+    fun upTransitionSceneKey_deviceLocked_keyguardDisabled_gone() =
+        testScope.runTest {
+            val destinationScenes by collectLastValue(underTest.destinationScenes)
+            val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
+            lockDevice()
+            kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(false)
+
+            assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(SceneFamilies.Home)
+            assertThat(homeScene).isEqualTo(Scenes.Gone)
+        }
+
+    @Test
     fun upTransitionSceneKey_deviceUnlocked_gone() =
         testScope.runTest {
             val destinationScenes by collectLastValue(underTest.destinationScenes)
@@ -78,6 +94,34 @@
             unlockDevice()
 
             assertThat(destinationScenes?.get(Swipe.Up)?.toScene).isEqualTo(SceneFamilies.Home)
+            assertThat(destinationScenes?.get(Swipe.Down)).isNull()
+            assertThat(homeScene).isEqualTo(Scenes.Gone)
+        }
+
+    @Test
+    fun downTransitionSceneKey_deviceLocked_bottomAligned_lockscreen() =
+        testScope.runTest {
+            kosmos.fakeShadeRepository.setDualShadeAlignedToBottom(true)
+            val destinationScenes by collectLastValue(underTest.destinationScenes)
+            val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
+            lockDevice()
+
+            assertThat(destinationScenes?.get(Swipe.Down)?.toScene).isEqualTo(SceneFamilies.Home)
+            assertThat(destinationScenes?.get(Swipe.Up)).isNull()
+            assertThat(homeScene).isEqualTo(Scenes.Lockscreen)
+        }
+
+    @Test
+    fun downTransitionSceneKey_deviceUnlocked_bottomAligned_gone() =
+        testScope.runTest {
+            kosmos.fakeShadeRepository.setDualShadeAlignedToBottom(true)
+            val destinationScenes by collectLastValue(underTest.destinationScenes)
+            val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
+            lockDevice()
+            unlockDevice()
+
+            assertThat(destinationScenes?.get(Swipe.Down)?.toScene).isEqualTo(SceneFamilies.Home)
+            assertThat(destinationScenes?.get(Swipe.Up)).isNull()
             assertThat(homeScene).isEqualTo(Scenes.Gone)
         }
 
@@ -112,6 +156,24 @@
             assertThat(homeScene).isEqualTo(Scenes.Gone)
         }
 
+    @Test
+    fun backTransitionSceneKey_notEditing_Home() =
+        testScope.runTest {
+            val destinationScenes by collectLastValue(underTest.destinationScenes)
+
+            assertThat(destinationScenes?.get(Back)?.toScene).isEqualTo(SceneFamilies.Home)
+        }
+
+    @Test
+    fun backTransition_editing_noDestination() =
+        testScope.runTest {
+            val destinationScenes by collectLastValue(underTest.destinationScenes)
+            kosmos.editModeViewModel.startEditing()
+
+            assertThat(destinationScenes!!).isNotEmpty()
+            assertThat(destinationScenes?.get(Back)).isNull()
+        }
+
     private fun TestScope.lockDevice() {
         val deviceUnlockStatus by collectLastValue(deviceUnlockedInteractor.deviceUnlockStatus)
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
index 4d5d22c..39b3662 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -48,33 +48,28 @@
 import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.flags.Flags
 import com.android.systemui.flags.fakeFeatureFlagsClassic
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardTouchHandlingViewModel
 import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
 import com.android.systemui.power.domain.interactor.powerInteractor
-import com.android.systemui.qs.footerActionsController
-import com.android.systemui.qs.footerActionsViewModelFactory
-import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter
-import com.android.systemui.scene.domain.interactor.sceneContainerStartable
+import com.android.systemui.qs.ui.adapter.fakeQSSceneAdapter
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.domain.resolver.homeSceneFamilyResolver
+import com.android.systemui.scene.domain.startable.sceneContainerStartable
 import com.android.systemui.scene.shared.model.SceneFamilies
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.fakeSceneDataSource
 import com.android.systemui.scene.ui.viewmodel.SceneContainerViewModel
-import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModel
 import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel
-import com.android.systemui.shade.ui.viewmodel.shadeHeaderViewModel
+import com.android.systemui.shade.ui.viewmodel.shadeSceneViewModel
 import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationsPlaceholderViewModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository
 import com.android.systemui.telephony.data.repository.fakeTelephonyRepository
 import com.android.systemui.testKosmos
-import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
@@ -138,7 +133,6 @@
                 sceneInteractor = sceneInteractor,
                 falsingInteractor = kosmos.falsingInteractor,
                 powerInteractor = kosmos.powerInteractor,
-                scenes = kosmos.scenes,
             )
             .apply { setTransitionState(transitionState) }
     }
@@ -152,8 +146,8 @@
             applicationScope = testScope.backgroundScope,
             deviceEntryInteractor = deviceEntryInteractor,
             communalInteractor = communalInteractor,
-            longPress =
-                KeyguardLongPressViewModel(
+            touchHandling =
+                KeyguardTouchHandlingViewModel(
                     interactor = mock(),
                 ),
             notifications = kosmos.notificationsPlaceholderViewModel,
@@ -167,7 +161,7 @@
 
     private var bouncerSceneJob: Job? = null
 
-    private val qsFlexiglassAdapter = FakeQSSceneAdapter(inflateDelegate = { mock() })
+    private val qsFlexiglassAdapter = kosmos.fakeQSSceneAdapter
 
     private lateinit var emergencyAffordanceManager: EmergencyAffordanceManager
     private lateinit var telecomManager: TelecomManager
@@ -200,20 +194,7 @@
         bouncerActionButtonInteractor = kosmos.bouncerActionButtonInteractor
         bouncerViewModel = kosmos.bouncerViewModel
 
-        shadeSceneViewModel =
-            ShadeSceneViewModel(
-                applicationScope = testScope.backgroundScope,
-                shadeHeaderViewModel = kosmos.shadeHeaderViewModel,
-                qsSceneAdapter = qsFlexiglassAdapter,
-                notifications = kosmos.notificationsPlaceholderViewModel,
-                brightnessMirrorViewModel = kosmos.brightnessMirrorViewModel,
-                mediaCarouselInteractor = kosmos.mediaCarouselInteractor,
-                shadeInteractor = kosmos.shadeInteractor,
-                footerActionsController = kosmos.footerActionsController,
-                footerActionsViewModelFactory = kosmos.footerActionsViewModelFactory,
-                sceneInteractor = sceneInteractor,
-                unfoldTransitionInteractor = kosmos.unfoldTransitionInteractor,
-            )
+        shadeSceneViewModel = kosmos.shadeSceneViewModel
 
         val startable = kosmos.sceneContainerStartable
         startable.start()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneBackInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneBackInteractorTest.kt
index e3108ad..1f3454d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneBackInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneBackInteractorTest.kt
@@ -28,6 +28,7 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.domain.startable.sceneContainerStartable
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
index ec7150b..e3a69a9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
@@ -24,8 +24,10 @@
 import com.android.compose.animation.scene.SceneKey
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
 import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
 import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.scene.data.repository.Idle
@@ -47,6 +49,7 @@
 import kotlinx.coroutines.flow.toList
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
+import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -61,6 +64,14 @@
 
     private val underTest = kosmos.sceneInteractor
 
+    @Before
+    fun setUp() {
+        // Init lazy Fixtures. Accessing them once makes sure that the singletons are initialized
+        // and therefore starts to collect StateFlows eagerly (when there are any).
+        kosmos.deviceUnlockedInteractor
+        kosmos.keyguardEnabledInteractor
+    }
+
     @Test
     fun allSceneKeys() {
         assertThat(underTest.allSceneKeys()).isEqualTo(kosmos.sceneKeys)
@@ -450,4 +461,16 @@
             progress.value = 0.9f
             assertThat(transitionValue).isEqualTo(0f)
         }
+
+    @Test
+    fun changeScene_toGone_whenKeyguardDisabled_doesNotThrow() =
+        testScope.runTest {
+            val currentScene by collectLastValue(underTest.currentScene)
+            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+            kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(false)
+
+            underTest.changeScene(Scenes.Gone, "")
+
+            assertThat(currentScene).isEqualTo(Scenes.Gone)
+        }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/KeyguardStateCallbackStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/KeyguardStateCallbackStartableTest.kt
new file mode 100644
index 0000000..695edaf
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/KeyguardStateCallbackStartableTest.kt
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.scene.domain.startable
+
+import android.content.pm.UserInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.internal.policy.IKeyguardStateCallback
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.data.repository.fakeTrustRepository
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.data.repository.setSceneTransition
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository
+import com.android.systemui.testKosmos
+import com.android.systemui.user.data.repository.fakeUserRepository
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@EnableSceneContainer
+class KeyguardStateCallbackStartableTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+
+    private val underTest = kosmos.keyguardStateCallbackStartable
+
+    @Test
+    fun addCallback_hydratesAllWithCurrentState() =
+        testScope.runTest {
+            val testState = setUpTest()
+            val callback = mockCallback()
+
+            underTest.addCallback(callback)
+            runCurrent()
+
+            with(testState) {
+                val captor = argumentCaptor<Boolean>()
+                verify(callback, atLeastOnce()).onShowingStateChanged(captor.capture(), eq(userId))
+                assertThat(captor.lastValue).isEqualTo(isKeyguardShowing)
+                verify(callback, atLeastOnce()).onInputRestrictedStateChanged(captor.capture())
+                assertThat(captor.lastValue).isEqualTo(isInputRestricted)
+                verify(callback, atLeastOnce()).onSimSecureStateChanged(captor.capture())
+                assertThat(captor.lastValue).isEqualTo(isSimSecure)
+                verify(callback, atLeastOnce()).onTrustedChanged(captor.capture())
+                assertThat(captor.lastValue).isEqualTo(isTrusted)
+            }
+        }
+
+    @Test
+    fun hydrateKeyguardShowingState() =
+        testScope.runTest {
+            setUpTest(isKeyguardShowing = true)
+            val callback = mockCallback()
+            underTest.addCallback(callback)
+            runCurrent()
+            verify(callback, atLeastOnce()).onShowingStateChanged(eq(true), anyInt())
+
+            unlockDevice()
+            runCurrent()
+
+            verify(callback).onShowingStateChanged(eq(false), anyInt())
+        }
+
+    @Test
+    fun hydrateInputRestrictedState() =
+        testScope.runTest {
+            setUpTest(isKeyguardShowing = true)
+            val callback = mockCallback()
+            underTest.addCallback(callback)
+            runCurrent()
+            val captor = argumentCaptor<Boolean>()
+            verify(callback, atLeastOnce()).onInputRestrictedStateChanged(captor.capture())
+            assertThat(captor.lastValue).isTrue()
+
+            unlockDevice()
+            runCurrent()
+
+            verify(callback, atLeastOnce()).onInputRestrictedStateChanged(captor.capture())
+            assertThat(captor.lastValue).isFalse()
+        }
+
+    @Test
+    fun hydrateSimSecureState() =
+        testScope.runTest {
+            setUpTest(isSimSecure = false)
+            val callback = mockCallback()
+            underTest.addCallback(callback)
+            runCurrent()
+            val captor = argumentCaptor<Boolean>()
+            verify(callback, atLeastOnce()).onSimSecureStateChanged(captor.capture())
+            assertThat(captor.lastValue).isFalse()
+
+            kosmos.fakeMobileConnectionsRepository.isAnySimSecure.value = true
+            runCurrent()
+
+            verify(callback, atLeastOnce()).onSimSecureStateChanged(captor.capture())
+            assertThat(captor.lastValue).isTrue()
+        }
+
+    @Test
+    fun notifyWhenKeyguardShowingChanged() =
+        testScope.runTest {
+            setUpTest(isKeyguardShowing = true)
+            val callback = mockCallback()
+            underTest.addCallback(callback)
+            runCurrent()
+            assertThat(kosmos.fakeTrustRepository.keyguardShowingChangeEventCount).isEqualTo(1)
+
+            unlockDevice()
+            runCurrent()
+
+            assertThat(kosmos.fakeTrustRepository.keyguardShowingChangeEventCount).isEqualTo(2)
+        }
+
+    @Test
+    fun notifyWhenTrustChanged() =
+        testScope.runTest {
+            setUpTest(isTrusted = false)
+            val callback = mockCallback()
+            underTest.addCallback(callback)
+            runCurrent()
+            val captor = argumentCaptor<Boolean>()
+            verify(callback, atLeastOnce()).onTrustedChanged(captor.capture())
+            assertThat(captor.lastValue).isFalse()
+
+            kosmos.fakeTrustRepository.setCurrentUserTrusted(true)
+            runCurrent()
+
+            verify(callback, atLeastOnce()).onTrustedChanged(captor.capture())
+            assertThat(captor.lastValue).isTrue()
+        }
+
+    private suspend fun TestScope.setUpTest(
+        isKeyguardShowing: Boolean = true,
+        userId: Int = selectedUser.id,
+        isInputRestricted: Boolean = true,
+        isSimSecure: Boolean = false,
+        isTrusted: Boolean = false,
+    ): TestState {
+        val testState =
+            TestState(
+                isKeyguardShowing = isKeyguardShowing,
+                userId = userId,
+                isInputRestricted = isInputRestricted,
+                isSimSecure = isSimSecure,
+                isTrusted = isTrusted,
+            )
+
+        if (isKeyguardShowing) {
+            lockDevice()
+        } else {
+            unlockDevice()
+        }
+
+        kosmos.fakeUserRepository.setUserInfos(listOf(selectedUser))
+        kosmos.fakeUserRepository.setSelectedUserInfo(selectedUser)
+
+        if (isInputRestricted && !isKeyguardShowing) {
+            // TODO(b/348644111): add support for mNeedToReshowWhenReenabled
+        } else if (!isInputRestricted) {
+            assertWithMessage(
+                    "If isInputRestricted is false, isKeyguardShowing must also be false!"
+                )
+                .that(isKeyguardShowing)
+                .isFalse()
+        }
+
+        kosmos.fakeMobileConnectionsRepository.isAnySimSecure.value = isSimSecure
+
+        kosmos.fakeTrustRepository.setCurrentUserTrusted(isTrusted)
+
+        runCurrent()
+
+        underTest.start()
+
+        return testState
+    }
+
+    private fun lockDevice() {
+        kosmos.setSceneTransition(ObservableTransitionState.Idle(Scenes.Lockscreen))
+        kosmos.sceneInteractor.changeScene(Scenes.Lockscreen, "")
+    }
+
+    private fun unlockDevice() {
+        kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+            SuccessFingerprintAuthenticationStatus(0, true)
+        )
+        kosmos.setSceneTransition(ObservableTransitionState.Idle(Scenes.Gone))
+        kosmos.sceneInteractor.changeScene(Scenes.Gone, "")
+    }
+
+    private fun mockCallback(): IKeyguardStateCallback {
+        return mock()
+    }
+
+    private data class TestState(
+        val isKeyguardShowing: Boolean,
+        val userId: Int,
+        val isInputRestricted: Boolean,
+        val isSimSecure: Boolean,
+        val isTrusted: Boolean,
+    )
+
+    companion object {
+        private val selectedUser =
+            UserInfo(
+                /* id= */ 100,
+                /* name= */ "First user",
+                /* flags= */ 0,
+            )
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index e40c8ee..b5e47d1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -26,22 +26,35 @@
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.compose.animation.scene.SceneKey
 import com.android.internal.logging.uiEventLoggerFake
+import com.android.internal.policy.IKeyguardDismissCallback
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
 import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
+import com.android.systemui.authentication.domain.interactor.authenticationInteractor
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
 import com.android.systemui.bouncer.domain.interactor.bouncerInteractor
 import com.android.systemui.bouncer.shared.logging.BouncerUiEvent
 import com.android.systemui.classifier.FalsingCollector
 import com.android.systemui.classifier.falsingCollector
 import com.android.systemui.classifier.falsingManager
+import com.android.systemui.concurrency.fakeExecutor
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
 import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.keyguard.data.repository.deviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
 import com.android.systemui.keyguard.data.repository.fakeTrustRepository
+import com.android.systemui.keyguard.data.repository.keyguardRepository
+import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
+import com.android.systemui.keyguard.dismissCallbackRegistry
+import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.domain.interactor.scenetransition.lockscreenSceneTransitionInteractor
+import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.model.sysUiState
@@ -51,7 +64,7 @@
 import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.power.shared.model.WakeSleepReason
 import com.android.systemui.power.shared.model.WakefulnessState
-import com.android.systemui.scene.domain.interactor.sceneContainerStartable
+import com.android.systemui.scene.data.repository.Transition
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.fakeSceneDataSource
@@ -72,6 +85,7 @@
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -168,6 +182,7 @@
 
             kosmos.headsUpNotificationRepository.activeHeadsUpRows.value =
                 buildNotificationRows(isPinned = false)
+            advanceTimeBy(50L) // account for HeadsUpNotificationInteractor debounce
             assertThat(isVisible).isFalse()
         }
 
@@ -384,6 +399,64 @@
         }
 
     @Test
+    fun switchToAOD_whenAvailable_whenDeviceSleepsLocked() =
+        testScope.runTest {
+            kosmos.lockscreenSceneTransitionInteractor.start()
+            val asleepState by
+                collectLastValue(kosmos.keyguardTransitionInteractor.asleepKeyguardState)
+            val currentTransitionInfo by
+                collectLastValue(kosmos.keyguardTransitionRepository.currentTransitionInfoInternal)
+            val transitionState =
+                prepareState(
+                    isDeviceUnlocked = false,
+                    initialSceneKey = Scenes.Shade,
+                )
+            kosmos.keyguardRepository.setAodAvailable(true)
+            runCurrent()
+            assertThat(asleepState).isEqualTo(KeyguardState.AOD)
+            underTest.start()
+            powerInteractor.setAsleepForTest()
+            runCurrent()
+            transitionState.value =
+                ObservableTransitionState.Transition(
+                    fromScene = Scenes.Shade,
+                    toScene = Scenes.Lockscreen,
+                    currentScene = flowOf(Scenes.Lockscreen),
+                    progress = flowOf(0.5f),
+                    isInitiatedByUserInput = true,
+                    isUserInputOngoing = flowOf(false),
+                )
+            runCurrent()
+
+            assertThat(currentTransitionInfo?.to).isEqualTo(KeyguardState.AOD)
+        }
+
+    @Test
+    fun switchToDozing_whenAodUnavailable_whenDeviceSleepsLocked() =
+        testScope.runTest {
+            kosmos.lockscreenSceneTransitionInteractor.start()
+            val asleepState by
+                collectLastValue(kosmos.keyguardTransitionInteractor.asleepKeyguardState)
+            val currentTransitionInfo by
+                collectLastValue(kosmos.keyguardTransitionRepository.currentTransitionInfoInternal)
+            val transitionState =
+                prepareState(
+                    isDeviceUnlocked = false,
+                    initialSceneKey = Scenes.Shade,
+                )
+            kosmos.keyguardRepository.setAodAvailable(false)
+            runCurrent()
+            assertThat(asleepState).isEqualTo(KeyguardState.DOZING)
+            underTest.start()
+            powerInteractor.setAsleepForTest()
+            runCurrent()
+            transitionState.value = Transition(from = Scenes.Shade, to = Scenes.Lockscreen)
+            runCurrent()
+
+            assertThat(currentTransitionInfo?.to).isEqualTo(KeyguardState.DOZING)
+        }
+
+    @Test
     fun switchToGoneWhenDoubleTapPowerGestureIsTriggeredFromGone() =
         testScope.runTest {
             val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
@@ -402,15 +475,7 @@
                 lastSleepReason = WakeSleepReason.POWER_BUTTON,
                 powerButtonLaunchGestureTriggered = false,
             )
-            transitionStateFlow.value =
-                ObservableTransitionState.Transition(
-                    fromScene = Scenes.Gone,
-                    toScene = Scenes.Lockscreen,
-                    currentScene = flowOf(Scenes.Lockscreen),
-                    progress = flowOf(0.5f),
-                    isInitiatedByUserInput = true,
-                    isUserInputOngoing = flowOf(false),
-                )
+            transitionStateFlow.value = Transition(from = Scenes.Shade, to = Scenes.Lockscreen)
             assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
 
             kosmos.fakePowerRepository.updateWakefulness(
@@ -484,6 +549,11 @@
                         QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING != 0L
                 )
                 .isFalse()
+            assertThat(
+                    sysUiState.flags and
+                        QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED != 0L
+                )
+                .isFalse()
 
             kosmos.keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop(false)
             runCurrent()
@@ -497,6 +567,11 @@
                         QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING != 0L
                 )
                 .isTrue()
+            assertThat(
+                    sysUiState.flags and
+                        QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED != 0L
+                )
+                .isTrue()
         }
 
     @Test
@@ -1340,6 +1415,152 @@
             assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
         }
 
+    @Test
+    fun switchToGone_whenKeyguardBecomesDisabled() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            prepareState()
+            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+            underTest.start()
+
+            kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(false)
+            runCurrent()
+
+            assertThat(currentScene).isEqualTo(Scenes.Gone)
+        }
+
+    @Test
+    fun switchToGone_whenKeyguardBecomesDisabled_whenOnShadeScene() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            prepareState(
+                initialSceneKey = Scenes.Shade,
+            )
+            assertThat(currentScene).isEqualTo(Scenes.Shade)
+            underTest.start()
+
+            kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(false)
+            runCurrent()
+
+            assertThat(currentScene).isEqualTo(Scenes.Gone)
+        }
+
+    @Test
+    fun doesNotSwitchToGone_whenKeyguardBecomesDisabled_whenInLockdownMode() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            prepareState()
+            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+            underTest.start()
+
+            kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(true)
+            kosmos.fakeBiometricSettingsRepository.setIsUserInLockdown(true)
+            kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(false)
+            runCurrent()
+
+            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+        }
+
+    @Test
+    fun doesNotSwitchToGone_whenKeyguardBecomesDisabled_whenDeviceEntered() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            prepareState(
+                isDeviceUnlocked = true,
+                initialSceneKey = Scenes.Gone,
+            )
+            assertThat(currentScene).isEqualTo(Scenes.Gone)
+            assertThat(kosmos.deviceEntryInteractor.isDeviceEntered.value).isTrue()
+            underTest.start()
+            sceneInteractor.changeScene(Scenes.Shade, "")
+            assertThat(currentScene).isEqualTo(Scenes.Shade)
+            assertThat(kosmos.deviceEntryInteractor.isDeviceEntered.value).isTrue()
+
+            kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(false)
+            runCurrent()
+
+            assertThat(currentScene).isEqualTo(Scenes.Shade)
+        }
+
+    @Test
+    fun switchToLockscreen_whenKeyguardBecomesEnabled_afterHidingWhenDisabled() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            prepareState()
+            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+            underTest.start()
+            kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(false)
+            runCurrent()
+            assertThat(currentScene).isEqualTo(Scenes.Gone)
+
+            kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(true)
+            runCurrent()
+
+            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+        }
+
+    @Test
+    fun doesNotSwitchToLockscreen_whenKeyguardBecomesEnabled_ifAuthMethodBecameInsecure() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            prepareState()
+            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+            underTest.start()
+            kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(false)
+            runCurrent()
+            assertThat(currentScene).isEqualTo(Scenes.Gone)
+            kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
+                AuthenticationMethodModel.None
+            )
+            runCurrent()
+
+            kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(true)
+            runCurrent()
+
+            assertThat(currentScene).isEqualTo(Scenes.Gone)
+        }
+
+    @Test
+    fun notifyKeyguardDismissCallbacks_whenUnlocking_onDismissSucceeded() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            prepareState()
+            underTest.start()
+            val dismissCallback: IKeyguardDismissCallback = mock()
+            kosmos.dismissCallbackRegistry.addCallback(dismissCallback)
+
+            // Switch to bouncer and unlock device:
+            sceneInteractor.changeScene(Scenes.Bouncer, "")
+            assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+            kosmos.authenticationInteractor.authenticate(FakeAuthenticationRepository.DEFAULT_PIN)
+            assertThat(currentScene).isEqualTo(Scenes.Gone)
+            kosmos.fakeExecutor.runAllReady()
+
+            verify(dismissCallback).onDismissSucceeded()
+        }
+
+    @Test
+    fun notifyKeyguardDismissCallbacks_whenLeavingBouncer_onDismissCancelled() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            prepareState()
+            underTest.start()
+            val dismissCallback: IKeyguardDismissCallback = mock()
+            kosmos.dismissCallbackRegistry.addCallback(dismissCallback)
+
+            // Switch to bouncer:
+            sceneInteractor.changeScene(Scenes.Bouncer, "")
+            assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+
+            // Return to lockscreen:
+            sceneInteractor.changeScene(Scenes.Lockscreen, "")
+            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+            runCurrent()
+            kosmos.fakeExecutor.runAllReady()
+
+            verify(dismissCallback).onDismissCancelled()
+        }
+
     private fun TestScope.emulateSceneTransition(
         transitionStateFlow: MutableStateFlow<ObservableTransitionState>,
         toScene: SceneKey,
@@ -1382,15 +1603,10 @@
         isDeviceProvisioned: Boolean = true,
         isInteractive: Boolean = true,
     ): MutableStateFlow<ObservableTransitionState> {
-        if (authenticationMethod?.isSecure == true) {
-            assert(isLockscreenEnabled) {
-                "Lockscreen cannot be disabled while having a secure authentication method"
-            }
-            if (isDeviceUnlocked) {
-                kosmos.deviceEntryFingerprintAuthRepository.setAuthenticationStatus(
-                    SuccessFingerprintAuthenticationStatus(0, true)
-                )
-            }
+        if (isDeviceUnlocked) {
+            kosmos.deviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
         }
 
         check(initialSceneKey != Scenes.Gone || isDeviceUnlocked) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/StatusBarStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/StatusBarStartableTest.kt
new file mode 100644
index 0000000..9601f20
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/StatusBarStartableTest.kt
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.scene.domain.startable
+
+import android.app.StatusBarManager
+import android.provider.DeviceConfig
+import android.view.WindowManagerPolicyConstants
+import androidx.test.filters.SmallTest
+import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.compose.animation.scene.SceneKey
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
+import com.android.internal.statusbar.statusBarService
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
+import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.concurrency.fakeExecutor
+import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.navigationbar.NavigationModeController
+import com.android.systemui.navigationbar.navigationModeController
+import com.android.systemui.power.data.repository.fakePowerRepository
+import com.android.systemui.power.shared.model.WakeSleepReason
+import com.android.systemui.power.shared.model.WakefulnessState
+import com.android.systemui.scene.data.repository.setSceneTransition
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
+import com.android.systemui.testKosmos
+import com.android.systemui.util.fakeDeviceConfigProxy
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import kotlin.reflect.full.memberProperties
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.BeforeClass
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+import platform.test.runner.parameterized.Parameter
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+
+@SmallTest
+@RunWith(ParameterizedAndroidJunit4::class)
+@EnableSceneContainer
+class StatusBarStartableTest : SysuiTestCase() {
+
+    companion object {
+        @Parameters(name = "{0}")
+        @JvmStatic
+        fun testSpecs(): List<TestSpec> {
+            return listOf(
+                TestSpec(
+                    id = 0,
+                    expectedFlags = StatusBarManager.DISABLE_NONE,
+                    Preconditions(
+                        isForceHideHomeAndRecents = false,
+                        isKeyguardShowing = false,
+                        isPowerGestureIntercepted = false,
+                    ),
+                ),
+                TestSpec(
+                    id = 1,
+                    expectedFlags = StatusBarManager.DISABLE_NONE,
+                    Preconditions(
+                        isForceHideHomeAndRecents = false,
+                        isKeyguardShowing = true,
+                        isOccluded = true,
+                        isPowerGestureIntercepted = false,
+                    ),
+                ),
+                TestSpec(
+                    id = 2,
+                    expectedFlags = StatusBarManager.DISABLE_NONE,
+                    Preconditions(
+                        isForceHideHomeAndRecents = false,
+                        isKeyguardShowing = false,
+                        isPowerGestureIntercepted = true,
+                        isOccluded = false,
+                    ),
+                ),
+                TestSpec(
+                    id = 3,
+                    expectedFlags = StatusBarManager.DISABLE_NONE,
+                    Preconditions(
+                        isForceHideHomeAndRecents = false,
+                        isKeyguardShowing = true,
+                        isOccluded = true,
+                        isPowerGestureIntercepted = true,
+                        isAuthenticationMethodSecure = false,
+                    ),
+                ),
+                TestSpec(
+                    id = 4,
+                    expectedFlags = StatusBarManager.DISABLE_NONE,
+                    Preconditions(
+                        isForceHideHomeAndRecents = false,
+                        isKeyguardShowing = true,
+                        isOccluded = true,
+                        isPowerGestureIntercepted = true,
+                        isAuthenticationMethodSecure = true,
+                        isFaceEnrolledAndEnabled = false,
+                    ),
+                ),
+                TestSpec(
+                    id = 5,
+                    expectedFlags = StatusBarManager.DISABLE_RECENT,
+                    Preconditions(
+                        isForceHideHomeAndRecents = false,
+                        isKeyguardShowing = true,
+                        isOccluded = true,
+                        isPowerGestureIntercepted = true,
+                        isAuthenticationMethodSecure = true,
+                        isFaceEnrolledAndEnabled = true,
+                    ),
+                ),
+                TestSpec(
+                    id = 6,
+                    expectedFlags = StatusBarManager.DISABLE_RECENT,
+                    Preconditions(
+                        isForceHideHomeAndRecents = true,
+                        isShowHomeOverLockscreen = true,
+                        isGesturalMode = true,
+                        isPowerGestureIntercepted = false,
+                    ),
+                ),
+                TestSpec(
+                    id = 7,
+                    expectedFlags = StatusBarManager.DISABLE_RECENT,
+                    Preconditions(
+                        isForceHideHomeAndRecents = false,
+                        isKeyguardShowing = true,
+                        isOccluded = false,
+                        isShowHomeOverLockscreen = true,
+                        isGesturalMode = true,
+                        isPowerGestureIntercepted = false,
+                    ),
+                ),
+                TestSpec(
+                    id = 8,
+                    expectedFlags =
+                        StatusBarManager.DISABLE_RECENT or StatusBarManager.DISABLE_HOME,
+                    Preconditions(
+                        isForceHideHomeAndRecents = true,
+                        isShowHomeOverLockscreen = true,
+                        isGesturalMode = false,
+                        isPowerGestureIntercepted = false,
+                    ),
+                ),
+                TestSpec(
+                    id = 9,
+                    expectedFlags =
+                        StatusBarManager.DISABLE_RECENT or StatusBarManager.DISABLE_HOME,
+                    Preconditions(
+                        isForceHideHomeAndRecents = false,
+                        isKeyguardShowing = true,
+                        isOccluded = false,
+                        isShowHomeOverLockscreen = false,
+                        isPowerGestureIntercepted = false,
+                    ),
+                ),
+            )
+        }
+
+        @BeforeClass
+        @JvmStatic
+        fun setUpClass() {
+            val seenIds = mutableSetOf<Int>()
+            testSpecs().forEach { testSpec ->
+                assertWithMessage("Duplicate TestSpec id=${testSpec.id}")
+                    .that(seenIds)
+                    .doesNotContain(testSpec.id)
+                seenIds.add(testSpec.id)
+            }
+        }
+    }
+
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+
+    private val statusBarServiceMock = kosmos.statusBarService
+    private val flagsCaptor = argumentCaptor<Int>()
+
+    private val navigationModeControllerMock = kosmos.navigationModeController
+    private var currentNavigationMode = WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON
+        set(value) {
+            field = value
+            modeChangedListeners.forEach { listener -> listener.onNavigationModeChanged(field) }
+        }
+
+    private val modeChangedListeners = mutableListOf<NavigationModeController.ModeChangedListener>()
+
+    private val underTest = kosmos.statusBarStartable
+
+    @JvmField @Parameter(0) var testSpec: TestSpec? = null
+
+    @Before
+    fun setUp() {
+        whenever(navigationModeControllerMock.addListener(any())).thenAnswer { invocation ->
+            val listener = invocation.arguments[0] as NavigationModeController.ModeChangedListener
+            modeChangedListeners.add(listener)
+            currentNavigationMode
+        }
+
+        underTest.start()
+    }
+
+    @Test
+    fun test() =
+        testScope.runTest {
+            val preconditions = checkNotNull(testSpec).preconditions
+            preconditions.assertValid()
+
+            setUpWith(preconditions)
+
+            runCurrent()
+
+            verify(statusBarServiceMock, atLeastOnce())
+                .disableForUser(flagsCaptor.capture(), any(), any(), anyInt())
+            assertThat(flagsCaptor.lastValue).isEqualTo(checkNotNull(testSpec).expectedFlags)
+        }
+
+    /** Sets up the state to match what's specified in the given [preconditions]. */
+    private fun TestScope.setUpWith(
+        preconditions: Preconditions,
+    ) {
+        if (!preconditions.isKeyguardShowing) {
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
+        }
+        if (preconditions.isForceHideHomeAndRecents) {
+            whenIdle(Scenes.Bouncer)
+        } else if (preconditions.isKeyguardShowing) {
+            whenIdle(Scenes.Lockscreen)
+        } else {
+            whenIdle(Scenes.Gone)
+        }
+        runCurrent()
+
+        kosmos.keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop(
+            showWhenLockedActivityOnTop = preconditions.isOccluded,
+            taskInfo = if (preconditions.isOccluded) mock() else null,
+        )
+
+        kosmos.fakeDeviceConfigProxy.setProperty(
+            DeviceConfig.NAMESPACE_SYSTEMUI,
+            SystemUiDeviceConfigFlags.NAV_BAR_HANDLE_SHOW_OVER_LOCKSCREEN,
+            preconditions.isShowHomeOverLockscreen.toString(),
+            /* makeDefault= */ false,
+        )
+        kosmos.fakeExecutor.runAllReady()
+
+        currentNavigationMode =
+            if (preconditions.isGesturalMode) {
+                WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL
+            } else {
+                WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON
+            }
+
+        kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
+            if (preconditions.isAuthenticationMethodSecure) {
+                AuthenticationMethodModel.Pin
+            } else {
+                AuthenticationMethodModel.None
+            }
+        )
+
+        kosmos.fakePowerRepository.updateWakefulness(
+            rawState =
+                if (preconditions.isPowerGestureIntercepted) WakefulnessState.AWAKE
+                else WakefulnessState.ASLEEP,
+            lastWakeReason = WakeSleepReason.POWER_BUTTON,
+            lastSleepReason = WakeSleepReason.POWER_BUTTON,
+            powerButtonLaunchGestureTriggered = preconditions.isPowerGestureIntercepted,
+        )
+
+        kosmos.fakeBiometricSettingsRepository.setIsFaceAuthEnrolledAndEnabled(
+            preconditions.isFaceEnrolledAndEnabled
+        )
+
+        runCurrent()
+    }
+
+    /** Sets up an idle state on the given [on] scene. */
+    private fun whenIdle(on: SceneKey) {
+        kosmos.setSceneTransition(ObservableTransitionState.Idle(on))
+        kosmos.sceneInteractor.changeScene(on, "")
+    }
+
+    data class Preconditions(
+        val isForceHideHomeAndRecents: Boolean = false,
+        val isKeyguardShowing: Boolean = true,
+        val isOccluded: Boolean = false,
+        val isPowerGestureIntercepted: Boolean = false,
+        val isShowHomeOverLockscreen: Boolean = false,
+        val isGesturalMode: Boolean = true,
+        val isAuthenticationMethodSecure: Boolean = true,
+        val isFaceEnrolledAndEnabled: Boolean = false,
+    ) {
+        override fun toString(): String {
+            // Only include values set to true:
+            return buildString {
+                append("(")
+                append(
+                    Preconditions::class
+                        .memberProperties
+                        .filter { it.get(this@Preconditions) == true }
+                        .joinToString(", ") { "${it.name}=true" }
+                )
+                append(")")
+            }
+        }
+
+        fun assertValid() {
+            assertWithMessage(
+                    "isForceHideHomeAndRecents means that the bouncer is showing so keyguard must" +
+                        " be showing"
+                )
+                .that(!isForceHideHomeAndRecents || isKeyguardShowing)
+                .isTrue()
+            assertWithMessage("Cannot be occluded if the keyguard isn't showing")
+                .that(!isOccluded || isKeyguardShowing)
+                .isTrue()
+        }
+    }
+
+    data class TestSpec(
+        val id: Int,
+        val expectedFlags: Int,
+        val preconditions: Preconditions,
+    ) {
+        override fun toString(): String {
+            return "id=$id, expected=$expectedFlags, preconditions=$preconditions"
+        }
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
index 5c30379..ea95aab 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModelTest.kt
@@ -28,10 +28,8 @@
 import com.android.systemui.power.data.repository.fakePowerRepository
 import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.fakeScenes
 import com.android.systemui.scene.sceneContainerConfig
 import com.android.systemui.scene.sceneKeys
-import com.android.systemui.scene.scenes
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.fakeSceneDataSource
 import com.android.systemui.testKosmos
@@ -66,7 +64,6 @@
                 sceneInteractor = sceneInteractor,
                 falsingInteractor = kosmos.falsingInteractor,
                 powerInteractor = kosmos.powerInteractor,
-                scenes = kosmos.scenes,
             )
     }
 
@@ -217,23 +214,4 @@
 
             assertThat(isVisible).isFalse()
         }
-
-    @Test
-    fun currentDestinationScenes_onlyTheCurrentSceneIsCollected() =
-        testScope.runTest {
-            val unused by collectLastValue(underTest.currentDestinationScenes(backgroundScope))
-            val currentScene by collectLastValue(sceneInteractor.currentScene)
-            kosmos.fakeScenes.forEach { scene ->
-                fakeSceneDataSource.changeScene(toScene = scene.key)
-                runCurrent()
-                assertThat(currentScene).isEqualTo(scene.key)
-
-                assertThat(scene.isDestinationScenesBeingCollected).isTrue()
-                kosmos.fakeScenes
-                    .filter { it.key != scene.key }
-                    .forEach { otherScene ->
-                        assertThat(otherScene.isDestinationScenesBeingCollected).isFalse()
-                    }
-            }
-        }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflaterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflaterTest.kt
index 6de7f40..13b61bc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflaterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflaterTest.kt
@@ -68,4 +68,27 @@
 
         Assert.setTestThread(null)
     }
+
+    @Test
+    fun inflate_frameHasPadding() {
+        Assert.setTestThread(Thread.currentThread())
+
+        val (frame, _) =
+            BrightnessMirrorInflater.inflate(
+                themedContext,
+                kosmos.brightnessSliderControllerFactory,
+            )
+
+        assertThat(frame.visibility).isEqualTo(View.VISIBLE)
+
+        val padding =
+            context.resources.getDimensionPixelSize(R.dimen.rounded_slider_background_padding)
+
+        assertThat(frame.paddingLeft).isEqualTo(padding)
+        assertThat(frame.paddingTop).isEqualTo(padding)
+        assertThat(frame.paddingRight).isEqualTo(padding)
+        assertThat(frame.paddingBottom).isEqualTo(padding)
+
+        Assert.setTestThread(null)
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/viewmodel/BrightnessMirrorViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/viewmodel/BrightnessMirrorViewModelTest.kt
index 09fc6f9..90c11d4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/viewmodel/BrightnessMirrorViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/settings/brightness/ui/viewmodel/BrightnessMirrorViewModelTest.kt
@@ -16,10 +16,9 @@
 
 package com.android.systemui.settings.brightness.ui.viewmodel
 
-import android.content.applicationContext
 import android.content.res.mainResources
-import android.view.ContextThemeWrapper
 import android.view.View
+import android.widget.FrameLayout
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -27,12 +26,10 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.res.R
 import com.android.systemui.settings.brightness.domain.interactor.brightnessMirrorShowingInteractor
-import com.android.systemui.settings.brightness.ui.binder.BrightnessMirrorInflater
 import com.android.systemui.settings.brightness.ui.viewModel.BrightnessMirrorViewModel
 import com.android.systemui.settings.brightness.ui.viewModel.LocationAndSize
 import com.android.systemui.settings.brightnessSliderControllerFactory
 import com.android.systemui.testKosmos
-import com.android.systemui.util.Assert
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
@@ -47,9 +44,6 @@
 
     private val kosmos = testKosmos()
 
-    private val themedContext =
-        ContextThemeWrapper(kosmos.applicationContext, R.style.Theme_SystemUI_QuickSettings)
-
     private val underTest =
         with(kosmos) {
             BrightnessMirrorViewModel(
@@ -76,7 +70,7 @@
         }
 
     @Test
-    fun setLocationInWindow_correctLocationAndSize() =
+    fun locationInWindowAndContainer_correctLocationAndSize() =
         with(kosmos) {
             testScope.runTest {
                 val locationAndSize by collectLastValue(underTest.locationAndSize)
@@ -101,6 +95,7 @@
                         whenever(measuredHeight).thenReturn(height)
                         whenever(measuredWidth).thenReturn(width)
                     }
+                val yOffsetFromContainer = setContainerViewHierarchy(mockView)
 
                 underTest.setLocationAndSize(mockView)
 
@@ -108,7 +103,8 @@
                     .isEqualTo(
                         // Adjust for padding around the view
                         LocationAndSize(
-                            yOffset = y - padding,
+                            yOffsetFromWindow = y - padding,
+                            yOffsetFromContainer = yOffsetFromContainer - padding,
                             width = width + 2 * padding,
                             height = height + 2 * padding,
                         )
@@ -116,31 +112,20 @@
             }
         }
 
-    @Test
-    fun setLocationInWindow_paddingSetToRootView() =
-        with(kosmos) {
-            Assert.setTestThread(Thread.currentThread())
-            val padding =
-                mainResources.getDimensionPixelSize(R.dimen.rounded_slider_background_padding)
+    private fun setContainerViewHierarchy(mockView: View): Int {
+        val rootView = FrameLayout(context)
+        val containerView = FrameLayout(context).apply { id = R.id.quick_settings_container }
+        val otherView = FrameLayout(context)
 
-            val view = mock<View>()
+        rootView.addView(containerView)
+        containerView.addView(otherView)
+        otherView.addView(mockView)
 
-            val (_, sliderController) =
-                BrightnessMirrorInflater.inflate(
-                    themedContext,
-                    brightnessSliderControllerFactory,
-                )
-            underTest.setToggleSlider(sliderController)
+        containerView.setLeftTopRightBottom(1, /* top= */ 1, 1, 1)
+        otherView.setLeftTopRightBottom(0, /* top= */ 2, 0, 0)
+        whenever(mockView.parent).thenReturn(otherView)
+        whenever(mockView.top).thenReturn(3)
 
-            underTest.setLocationAndSize(view)
-
-            with(sliderController.rootView) {
-                assertThat(paddingBottom).isEqualTo(padding)
-                assertThat(paddingTop).isEqualTo(padding)
-                assertThat(paddingLeft).isEqualTo(padding)
-                assertThat(paddingRight).isEqualTo(padding)
-            }
-
-            Assert.setTestThread(null)
-        }
+        return 2 + 3
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
index c53cdf8..673d5ef 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
@@ -32,31 +32,24 @@
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
 import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
 import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.media.controls.data.repository.mediaFilterRepository
-import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
-import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
 import com.android.systemui.media.controls.shared.model.MediaData
-import com.android.systemui.qs.footerActionsController
-import com.android.systemui.qs.footerActionsViewModelFactory
-import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter
+import com.android.systemui.qs.ui.adapter.fakeQSSceneAdapter
+import com.android.systemui.qs.ui.adapter.qsSceneAdapter
 import com.android.systemui.res.R
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.domain.resolver.homeSceneFamilyResolver
 import com.android.systemui.scene.shared.model.SceneFamilies
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade
-import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModel
 import com.android.systemui.shade.data.repository.shadeRepository
-import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.shade.domain.startable.shadeStartable
 import com.android.systemui.shade.shared.model.ShadeMode
-import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationsPlaceholderViewModel
 import com.android.systemui.testKosmos
-import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor
 import com.android.systemui.unfold.fakeUnfoldTransitionProgressProvider
-import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
 import java.util.Locale
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -65,11 +58,8 @@
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
@@ -82,32 +72,9 @@
     private val testScope = kosmos.testScope
     private val sceneInteractor by lazy { kosmos.sceneInteractor }
     private val shadeRepository by lazy { kosmos.shadeRepository }
+    private val qsSceneAdapter by lazy { kosmos.fakeQSSceneAdapter }
 
-    private val qsSceneAdapter = FakeQSSceneAdapter({ mock() })
-
-    private lateinit var underTest: ShadeSceneViewModel
-
-    @Mock private lateinit var mediaDataManager: MediaDataManager
-
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-
-        underTest =
-            ShadeSceneViewModel(
-                applicationScope = testScope.backgroundScope,
-                shadeHeaderViewModel = kosmos.shadeHeaderViewModel,
-                qsSceneAdapter = qsSceneAdapter,
-                notifications = kosmos.notificationsPlaceholderViewModel,
-                brightnessMirrorViewModel = kosmos.brightnessMirrorViewModel,
-                mediaCarouselInteractor = kosmos.mediaCarouselInteractor,
-                shadeInteractor = kosmos.shadeInteractor,
-                footerActionsViewModelFactory = kosmos.footerActionsViewModelFactory,
-                footerActionsController = kosmos.footerActionsController,
-                sceneInteractor = kosmos.sceneInteractor,
-                unfoldTransitionInteractor = kosmos.unfoldTransitionInteractor,
-            )
-    }
+    private val underTest: ShadeSceneViewModel by lazy { kosmos.shadeSceneViewModel }
 
     @Test
     fun upTransitionSceneKey_deviceLocked_lockScreen() =
@@ -139,6 +106,21 @@
         }
 
     @Test
+    fun upTransitionSceneKey_keyguardDisabled_gone() =
+        testScope.runTest {
+            val destinationScenes by collectLastValue(underTest.destinationScenes)
+            val homeScene by collectLastValue(kosmos.homeSceneFamilyResolver.resolvedScene)
+            kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
+                AuthenticationMethodModel.Pin
+            )
+            kosmos.keyguardEnabledInteractor.notifyKeyguardEnabled(false)
+
+            assertThat(destinationScenes?.get(Swipe(SwipeDirection.Up))?.toScene)
+                .isEqualTo(SceneFamilies.Home)
+            assertThat(homeScene).isEqualTo(Scenes.Gone)
+        }
+
+    @Test
     fun upTransitionSceneKey_authMethodSwipe_lockscreenNotDismissed_goesToLockscreen() =
         testScope.runTest {
             val destinationScenes by collectLastValue(underTest.destinationScenes)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/CommunalSmartspaceControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/CommunalSmartspaceControllerTest.kt
index ad4b98b..eac86e5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/CommunalSmartspaceControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/CommunalSmartspaceControllerTest.kt
@@ -20,6 +20,7 @@
 import android.app.smartspace.SmartspaceTarget
 import android.content.Context
 import android.graphics.drawable.Drawable
+import android.os.Handler
 import android.testing.TestableLooper
 import android.view.View
 import android.widget.FrameLayout
@@ -86,6 +87,8 @@
 
         override fun setUiSurface(uiSurface: String) {}
 
+        override fun setBgHandler(bgHandler: Handler?) {}
+
         override fun setDozeAmount(amount: Float) {}
 
         override fun setIntentStarter(intentStarter: BcSmartspaceDataPlugin.IntentStarter?) {}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
index 3a38631..e774aed 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
@@ -20,6 +20,7 @@
 import android.app.smartspace.SmartspaceTarget
 import android.content.Context
 import android.graphics.drawable.Drawable
+import android.os.Handler
 import android.testing.TestableLooper
 import android.view.View
 import android.view.ViewGroup
@@ -119,6 +120,8 @@
 
         override fun setUiSurface(uiSurface: String) {}
 
+        override fun setBgHandler(bgHandler: Handler?) {}
+
         override fun setDozeAmount(amount: Float) {}
 
         override fun setIntentStarter(intentStarter: BcSmartspaceDataPlugin.IntentStarter?) {}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
index f06e04b..355669b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
@@ -38,11 +38,16 @@
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
+import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.scene.data.repository.Idle
+import com.android.systemui.scene.data.repository.setTransition
+import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
 import com.android.systemui.testKosmos
 import com.android.systemui.util.kotlin.JavaAdapter
 import com.android.systemui.util.mockito.mock
@@ -105,6 +110,7 @@
                     { kosmos.shadeInteractor },
                     { kosmos.deviceUnlockedInteractor },
                     { kosmos.sceneInteractor },
+                    { kosmos.sceneContainerOcclusionInteractor },
                     { kosmos.keyguardClockInteractor },
                 ) {
                 override fun createDarkAnimator(): ObjectAnimator {
@@ -336,6 +342,47 @@
         }
 
     @Test
+    @EnableSceneContainer
+    fun start_hydratesStatusBarState_whileOccluded() =
+        testScope.runTest {
+            var statusBarState = underTest.state
+            val listener =
+                object : StatusBarStateController.StateListener {
+                    override fun onStateChanged(newState: Int) {
+                        statusBarState = newState
+                    }
+                }
+            underTest.addCallback(listener)
+
+            val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene)
+            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
+            val isOccluded by
+                collectLastValue(kosmos.sceneContainerOcclusionInteractor.invisibleDueToOcclusion)
+            kosmos.keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop(
+                showWhenLockedActivityOnTop = true,
+                taskInfo = mock(),
+            )
+            runCurrent()
+            assertThat(isOccluded).isTrue()
+
+            // Call start to begin hydrating based on the scene framework:
+            underTest.start()
+
+            kosmos.sceneInteractor.changeScene(toScene = Scenes.Shade, loggingReason = "reason")
+            runCurrent()
+            assertThat(currentScene).isEqualTo(Scenes.Shade)
+            assertThat(statusBarState).isEqualTo(StatusBarState.SHADE)
+
+            kosmos.sceneInteractor.changeScene(
+                toScene = Scenes.QuickSettings,
+                loggingReason = "reason"
+            )
+            runCurrent()
+            assertThat(currentScene).isEqualTo(Scenes.QuickSettings)
+            assertThat(statusBarState).isEqualTo(StatusBarState.SHADE)
+        }
+
+    @Test
     fun leaveOpenOnKeyguard_whenGone_isFalse() =
         testScope.runTest {
             underTest.start()
@@ -348,11 +395,15 @@
             )
             assertThat(underTest.leaveOpenOnKeyguardHide()).isEqualTo(true)
 
-            keyguardTransitionRepository.sendTransitionSteps(
-                from = KeyguardState.LOCKSCREEN,
-                to = KeyguardState.GONE,
-                testScope = testScope,
+            kosmos.setTransition(
+                sceneTransition = Idle(Scenes.Gone),
+                stateTransition =
+                    TransitionStep(
+                        from = KeyguardState.LOCKSCREEN,
+                        to = KeyguardState.GONE,
+                    )
             )
+
             assertThat(underTest.leaveOpenOnKeyguardHide()).isEqualTo(false)
         }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
index ca4434d2..23b28e3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
@@ -18,6 +18,7 @@
 
 package com.android.systemui.statusbar.notification
 
+import android.testing.TestableLooper.RunWithLooper
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.compose.animation.scene.ObservableTransitionState
@@ -32,6 +33,8 @@
 import com.android.systemui.scene.shared.model.fakeSceneDataSource
 import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
 import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimShape
+import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationTransitionThresholds.EXPANSION_FOR_DELAYED_STACK_FADE_IN
+import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationTransitionThresholds.EXPANSION_FOR_MAX_SCRIM_ALPHA
 import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationScrollViewModel
 import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationsPlaceholderViewModel
 import com.android.systemui.testKosmos
@@ -46,6 +49,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
+@RunWithLooper
 @EnableSceneContainer
 class NotificationStackAppearanceIntegrationTest : SysuiTestCase() {
 
@@ -169,6 +173,22 @@
         }
 
     @Test
+    fun shadeExpansion_idleOnQs() =
+        testScope.runTest {
+            val transitionState =
+                MutableStateFlow<ObservableTransitionState>(
+                    ObservableTransitionState.Idle(currentScene = Scenes.QuickSettings)
+                )
+            sceneInteractor.setTransitionState(transitionState)
+            val expandFraction by collectLastValue(scrollViewModel.expandFraction)
+            assertThat(expandFraction).isEqualTo(1f)
+
+            fakeSceneDataSource.changeScene(toScene = Scenes.QuickSettings)
+            val isScrollable by collectLastValue(scrollViewModel.isScrollable)
+            assertThat(isScrollable).isFalse()
+        }
+
+    @Test
     fun shadeExpansion_shadeToQs() =
         testScope.runTest {
             val transitionState =
@@ -208,4 +228,50 @@
             assertThat(expandFraction).isEqualTo(1f)
             assertThat(isScrollable).isFalse()
         }
+
+    @Test
+    fun shadeExpansion_goneToQs() =
+        testScope.runTest {
+            val transitionState =
+                MutableStateFlow<ObservableTransitionState>(
+                    ObservableTransitionState.Idle(currentScene = Scenes.Gone)
+                )
+            sceneInteractor.setTransitionState(transitionState)
+            val expandFraction by collectLastValue(scrollViewModel.expandFraction)
+            assertThat(expandFraction).isEqualTo(0f)
+
+            fakeSceneDataSource.changeScene(toScene = Scenes.Gone)
+            val isScrollable by collectLastValue(scrollViewModel.isScrollable)
+            assertThat(isScrollable).isFalse()
+
+            fakeSceneDataSource.pause()
+
+            sceneInteractor.changeScene(Scenes.QuickSettings, "reason")
+            val transitionProgress = MutableStateFlow(0f)
+            transitionState.value =
+                ObservableTransitionState.Transition(
+                    fromScene = Scenes.Gone,
+                    toScene = Scenes.QuickSettings,
+                    currentScene = flowOf(Scenes.QuickSettings),
+                    progress = transitionProgress,
+                    isInitiatedByUserInput = false,
+                    isUserInputOngoing = flowOf(false),
+                )
+            val steps = 10
+            repeat(steps) { repetition ->
+                val progress = (1f / steps) * (repetition + 1)
+                transitionProgress.value = progress
+                runCurrent()
+                assertThat(expandFraction)
+                    .isEqualTo(
+                        (progress / EXPANSION_FOR_MAX_SCRIM_ALPHA -
+                                EXPANSION_FOR_DELAYED_STACK_FADE_IN)
+                            .coerceIn(0f, 1f)
+                    )
+            }
+
+            fakeSceneDataSource.unpause(expectedScene = Scenes.QuickSettings)
+            assertThat(expandFraction).isEqualTo(1f)
+            assertThat(isScrollable).isFalse()
+        }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/BundleCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/BundleCoordinatorTest.kt
new file mode 100644
index 0000000..8a9720e
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/BundleCoordinatorTest.kt
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 android.app.NotificationChannel
+import android.app.NotificationChannel.NEWS_ID
+import android.app.NotificationChannel.PROMOTIONS_ID
+import android.app.NotificationChannel.RECS_ID
+import android.app.NotificationChannel.SOCIAL_MEDIA_ID
+import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.collection.render.NodeController
+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
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@TestableLooper.RunWithLooper
+class BundleCoordinatorTest : SysuiTestCase() {
+    @Mock private lateinit var newsController: NodeController
+    @Mock private lateinit var socialController: NodeController
+    @Mock private lateinit var recsController: NodeController
+    @Mock private lateinit var promoController: NodeController
+
+    private lateinit var coordinator: BundleCoordinator
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        coordinator =
+            BundleCoordinator(
+                newsController,
+                socialController,
+                recsController,
+                promoController
+            )
+    }
+
+    @Test
+    fun newsSectioner() {
+        assertThat(coordinator.newsSectioner.isInSection(makeEntryOfChannelType(NEWS_ID))).isTrue()
+        assertThat(coordinator.newsSectioner.isInSection(makeEntryOfChannelType("news"))).isFalse()
+    }
+
+    @Test
+    fun socialSectioner() {
+        assertThat(coordinator.socialSectioner.isInSection(makeEntryOfChannelType(SOCIAL_MEDIA_ID)))
+            .isTrue()
+        assertThat(coordinator.socialSectioner.isInSection(makeEntryOfChannelType("social")))
+            .isFalse()
+    }
+
+    @Test
+    fun recsSectioner() {
+        assertThat(coordinator.recsSectioner.isInSection(makeEntryOfChannelType(RECS_ID))).isTrue()
+        assertThat(coordinator.recsSectioner.isInSection(makeEntryOfChannelType("recommendations")))
+            .isFalse()
+    }
+
+    @Test
+    fun promoSectioner() {
+        assertThat(coordinator.promoSectioner.isInSection(makeEntryOfChannelType(PROMOTIONS_ID)))
+            .isTrue()
+        assertThat(coordinator.promoSectioner.isInSection(makeEntryOfChannelType("promo"))).
+        isFalse()
+    }
+
+    private fun makeEntryOfChannelType(
+        type: String,
+        buildBlock: NotificationEntryBuilder.() -> Unit = {}
+    ): NotificationEntry {
+        val channel: NotificationChannel = NotificationChannel(type, type, 2)
+        val entry =
+            NotificationEntryBuilder()
+                .updateRanking {
+                    it.setChannel(channel)
+                }
+                .also(buildBlock)
+                .build()
+        return entry
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt
index 8b4265f..5ef3485 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractorTest.kt
@@ -23,6 +23,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.coroutines.collectValues
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
@@ -279,6 +280,64 @@
         }
 
     @Test
+    fun isHeadsUpOrAnimatingAway_falseOnStart() =
+        testScope.runTest {
+            val isHeadsUpOrAnimatingAway by collectLastValue(underTest.isHeadsUpOrAnimatingAway)
+
+            runCurrent()
+
+            assertThat(isHeadsUpOrAnimatingAway).isFalse()
+        }
+
+    @Test
+    fun isHeadsUpOrAnimatingAway_hasPinnedRows() =
+        testScope.runTest {
+            val isHeadsUpOrAnimatingAway by collectLastValue(underTest.isHeadsUpOrAnimatingAway)
+
+            // WHEN a row is pinned
+            headsUpRepository.setNotifications(fakeHeadsUpRowRepository("key 0", isPinned = true))
+            runCurrent()
+
+            assertThat(isHeadsUpOrAnimatingAway).isTrue()
+        }
+
+    @Test
+    fun isHeadsUpOrAnimatingAway_headsUpAnimatingAway() =
+        testScope.runTest {
+            val isHeadsUpOrAnimatingAway by collectLastValue(underTest.isHeadsUpOrAnimatingAway)
+
+            // WHEN the last row is animating away
+            headsUpRepository.setHeadsUpAnimatingAway(true)
+            runCurrent()
+
+            assertThat(isHeadsUpOrAnimatingAway).isTrue()
+        }
+
+    @Test
+    fun isHeadsUpOrAnimatingAway_headsUpAnimatingAwayDebounced() =
+        testScope.runTest {
+            val values by collectValues(underTest.isHeadsUpOrAnimatingAway)
+
+            // GIVEN a row is pinned
+            headsUpRepository.setNotifications(fakeHeadsUpRowRepository("key 0", isPinned = true))
+            runCurrent()
+            assertThat(values.size).isEqualTo(2)
+            assertThat(values.first()).isFalse() // initial value
+            assertThat(values.last()).isTrue()
+
+            // WHEN the last row is removed
+            headsUpRepository.setNotifications(emptyList())
+            runCurrent()
+            // AND starts to animate away
+            headsUpRepository.setHeadsUpAnimatingAway(true)
+            runCurrent()
+
+            // THEN isHeadsUpOrAnimatingAway remained true
+            assertThat(values.size).isEqualTo(2)
+            assertThat(values.last()).isTrue()
+        }
+
+    @Test
     fun showHeadsUpStatusBar_true() =
         testScope.runTest {
             val showHeadsUpStatusBar by collectLastValue(underTest.showHeadsUpStatusBar)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractorTest.kt
index 8e765f7..0195e9d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractorTest.kt
@@ -21,13 +21,13 @@
 import android.provider.Settings.Global
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.settingslib.statusbar.notification.data.model.ZenMode
-import com.android.settingslib.statusbar.notification.data.repository.updateNotificationPolicy
-import com.android.settingslib.statusbar.notification.domain.interactor.NotificationsSoundPolicyInteractor
+import com.android.settingslib.notification.data.repository.updateNotificationPolicy
+import com.android.settingslib.notification.domain.interactor.NotificationsSoundPolicyInteractor
 import com.android.settingslib.volume.shared.model.AudioStream
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.statusbar.policy.data.repository.zenModeRepository
 import com.android.systemui.testKosmos
 import com.google.common.truth.Expect
 import com.google.common.truth.Truth.assertThat
@@ -52,24 +52,20 @@
 
     @Before
     fun setup() {
-        with(kosmos) {
-            underTest = NotificationsSoundPolicyInteractor(notificationsSoundPolicyRepository)
-        }
+        with(kosmos) { underTest = NotificationsSoundPolicyInteractor(zenModeRepository) }
     }
 
     @Test
     fun onlyAlarmsCategory_areAlarmsAllowed_isTrue() {
         with(kosmos) {
             testScope.runTest {
-                notificationsSoundPolicyRepository.updateZenMode(ZenMode(Global.ZEN_MODE_OFF))
+                zenModeRepository.updateZenMode(Global.ZEN_MODE_OFF)
                 val expectedByCategory =
                     NotificationManager.Policy.ALL_PRIORITY_CATEGORIES.associateWith {
                         it == NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS
                     }
                 expectedByCategory.forEach { entry ->
-                    notificationsSoundPolicyRepository.updateNotificationPolicy(
-                        priorityCategories = entry.key
-                    )
+                    zenModeRepository.updateNotificationPolicy(priorityCategories = entry.key)
 
                     val areAlarmsAllowed by collectLastValue(underTest.areAlarmsAllowed)
                     runCurrent()
@@ -84,15 +80,13 @@
     fun onlyMediaCategory_areAlarmsAllowed_isTrue() {
         with(kosmos) {
             testScope.runTest {
-                notificationsSoundPolicyRepository.updateZenMode(ZenMode(Global.ZEN_MODE_OFF))
+                zenModeRepository.updateZenMode(Global.ZEN_MODE_OFF)
                 val expectedByCategory =
                     NotificationManager.Policy.ALL_PRIORITY_CATEGORIES.associateWith {
                         it == NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA
                     }
                 expectedByCategory.forEach { entry ->
-                    notificationsSoundPolicyRepository.updateNotificationPolicy(
-                        priorityCategories = entry.key
-                    )
+                    zenModeRepository.updateNotificationPolicy(priorityCategories = entry.key)
 
                     val isMediaAllowed by collectLastValue(underTest.isMediaAllowed)
                     runCurrent()
@@ -108,7 +102,7 @@
         with(kosmos) {
             testScope.runTest {
                 for (category in NotificationManager.Policy.ALL_PRIORITY_CATEGORIES) {
-                    notificationsSoundPolicyRepository.updateNotificationPolicy(
+                    zenModeRepository.updateNotificationPolicy(
                         priorityCategories = category,
                         state = NotificationManager.Policy.STATE_UNSET,
                     )
@@ -126,7 +120,7 @@
     fun allCategoriesAllowed_isRingerAllowed_isTrue() {
         with(kosmos) {
             testScope.runTest {
-                notificationsSoundPolicyRepository.updateNotificationPolicy(
+                zenModeRepository.updateNotificationPolicy(
                     priorityCategories =
                         NotificationManager.Policy.ALL_PRIORITY_CATEGORIES.reduce { acc, value ->
                             acc or value
@@ -146,7 +140,7 @@
     fun noCategoriesAndBlocked_isRingerAllowed_isFalse() {
         with(kosmos) {
             testScope.runTest {
-                notificationsSoundPolicyRepository.updateNotificationPolicy(
+                zenModeRepository.updateNotificationPolicy(
                     priorityCategories = 0,
                     state = NotificationManager.Policy.STATE_PRIORITY_CHANNELS_BLOCKED,
                 )
@@ -163,10 +157,8 @@
     fun zenModeNoInterruptions_allStreams_muted() {
         with(kosmos) {
             testScope.runTest {
-                notificationsSoundPolicyRepository.updateNotificationPolicy()
-                notificationsSoundPolicyRepository.updateZenMode(
-                    ZenMode(Global.ZEN_MODE_NO_INTERRUPTIONS)
-                )
+                zenModeRepository.updateNotificationPolicy()
+                zenModeRepository.updateZenMode(Global.ZEN_MODE_NO_INTERRUPTIONS)
 
                 for (stream in AudioStream.supportedStreamTypes) {
                     val isZenMuted by collectLastValue(underTest.isZenMuted(AudioStream(stream)))
@@ -182,8 +174,8 @@
     fun zenModeOff_allStreams_notMuted() {
         with(kosmos) {
             testScope.runTest {
-                notificationsSoundPolicyRepository.updateNotificationPolicy()
-                notificationsSoundPolicyRepository.updateZenMode(ZenMode(Global.ZEN_MODE_OFF))
+                zenModeRepository.updateNotificationPolicy()
+                zenModeRepository.updateZenMode(Global.ZEN_MODE_OFF)
 
                 for (stream in AudioStream.supportedStreamTypes) {
                     val isZenMuted by collectLastValue(underTest.isZenMuted(AudioStream(stream)))
@@ -205,8 +197,8 @@
                     AudioManager.STREAM_SYSTEM,
                 )
             testScope.runTest {
-                notificationsSoundPolicyRepository.updateNotificationPolicy()
-                notificationsSoundPolicyRepository.updateZenMode(ZenMode(Global.ZEN_MODE_ALARMS))
+                zenModeRepository.updateNotificationPolicy()
+                zenModeRepository.updateZenMode(Global.ZEN_MODE_ALARMS)
 
                 for (stream in AudioStream.supportedStreamTypes) {
                     val isZenMuted by collectLastValue(underTest.isZenMuted(AudioStream(stream)))
@@ -222,10 +214,8 @@
     fun alarms_allowed_notMuted() {
         with(kosmos) {
             testScope.runTest {
-                notificationsSoundPolicyRepository.updateZenMode(
-                    ZenMode(Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
-                )
-                notificationsSoundPolicyRepository.updateNotificationPolicy(
+                zenModeRepository.updateZenMode(Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
+                zenModeRepository.updateNotificationPolicy(
                     priorityCategories = NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS
                 )
 
@@ -242,10 +232,8 @@
     fun media_allowed_notMuted() {
         with(kosmos) {
             testScope.runTest {
-                notificationsSoundPolicyRepository.updateZenMode(
-                    ZenMode(Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
-                )
-                notificationsSoundPolicyRepository.updateNotificationPolicy(
+                zenModeRepository.updateZenMode(Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
+                zenModeRepository.updateNotificationPolicy(
                     priorityCategories = NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA
                 )
 
@@ -262,10 +250,8 @@
     fun ringer_allowed_notificationsNotMuted() {
         with(kosmos) {
             testScope.runTest {
-                notificationsSoundPolicyRepository.updateZenMode(
-                    ZenMode(Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
-                )
-                notificationsSoundPolicyRepository.updateNotificationPolicy(
+                zenModeRepository.updateZenMode(Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
+                zenModeRepository.updateNotificationPolicy(
                     priorityCategories =
                         NotificationManager.Policy.ALL_PRIORITY_CATEGORIES.reduce { acc, value ->
                             acc or value
@@ -288,10 +274,8 @@
     fun ringer_allowed_ringNotMuted() {
         with(kosmos) {
             testScope.runTest {
-                notificationsSoundPolicyRepository.updateZenMode(
-                    ZenMode(Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
-                )
-                notificationsSoundPolicyRepository.updateNotificationPolicy(
+                zenModeRepository.updateZenMode(Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
+                zenModeRepository.updateNotificationPolicy(
                     priorityCategories =
                         NotificationManager.Policy.ALL_PRIORITY_CATEGORIES.reduce { acc, value ->
                             acc or value
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/TimerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/TimerViewModelTest.kt
new file mode 100644
index 0000000..5e87f46
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/TimerViewModelTest.kt
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.statusbar.notification.row.ui.viewmodel
+
+import android.app.PendingIntent
+import android.platform.test.annotations.EnableFlags
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.statusbar.notification.row.data.repository.fakeNotificationRowRepository
+import com.android.systemui.statusbar.notification.row.shared.IconModel
+import com.android.systemui.statusbar.notification.row.shared.RichOngoingNotificationFlag
+import com.android.systemui.statusbar.notification.row.shared.TimerContentModel
+import com.android.systemui.statusbar.notification.row.shared.TimerContentModel.TimerState.Paused
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import java.time.Duration
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+@EnableFlags(RichOngoingNotificationFlag.FLAG_NAME)
+class TimerViewModelTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val repository = kosmos.fakeNotificationRowRepository
+
+    private var contentModel: TimerContentModel?
+        get() = repository.richOngoingContentModel.value as? TimerContentModel
+        set(value) {
+            repository.richOngoingContentModel.value = value
+        }
+
+    private lateinit var underTest: TimerViewModel
+
+    @Before
+    fun setup() {
+        underTest = kosmos.getTimerViewModel(repository)
+    }
+
+    @Test
+    fun labelShowsTheTimerName() =
+        testScope.runTest {
+            val label by collectLastValue(underTest.label)
+            contentModel = pausedTimer(name = "Example Timer Name")
+            assertThat(label).isEqualTo("Example Timer Name")
+        }
+
+    @Test
+    fun pausedTimeRemainingFormatsWell() =
+        testScope.runTest {
+            val label by collectLastValue(underTest.pausedTime)
+            contentModel = pausedTimer(timeRemaining = Duration.ofMinutes(3))
+            assertThat(label).isEqualTo("3:00")
+            contentModel = pausedTimer(timeRemaining = Duration.ofSeconds(119))
+            assertThat(label).isEqualTo("1:59")
+            contentModel = pausedTimer(timeRemaining = Duration.ofSeconds(121))
+            assertThat(label).isEqualTo("2:01")
+            contentModel = pausedTimer(timeRemaining = Duration.ofHours(1))
+            assertThat(label).isEqualTo("1:00:00")
+            contentModel = pausedTimer(timeRemaining = Duration.ofHours(24))
+            assertThat(label).isEqualTo("24:00:00")
+        }
+
+    private fun pausedTimer(
+        icon: IconModel = mock(),
+        name: String = "example",
+        timeRemaining: Duration = Duration.ofMinutes(3),
+        resumeIntent: PendingIntent? = null,
+        resetIntent: PendingIntent? = null
+    ) =
+        TimerContentModel(
+            icon = icon,
+            name = name,
+            state =
+                Paused(
+                    timeRemaining = timeRemaining,
+                    resumeIntent = resumeIntent,
+                    resetIntent = resetIntent,
+                )
+        )
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelTest.kt
index 9fde116..ba7ddce 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationListViewModelTest.kt
@@ -23,6 +23,7 @@
 import android.platform.test.flag.junit.FlagsParameterization
 import android.provider.Settings
 import androidx.test.filters.SmallTest
+import com.android.settingslib.notification.data.repository.updateNotificationPolicy
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.flags.Flags
@@ -56,7 +57,6 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.MockitoAnnotations
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
@@ -97,7 +97,9 @@
 
     @Before
     fun setUp() {
-        MockitoAnnotations.initMocks(this)
+        // "Why is this not lazily initialised above?" you may ask. There's a simple answer: likely
+        // due to some timing issue with how the flags are getting initialised for parameterization,
+        // some tests start failing when this isn't initialised this way. You can just leave it be.
         underTest = kosmos.notificationListViewModel
     }
 
@@ -146,36 +148,40 @@
             assertThat(important).isTrue()
         }
 
+    // NOTE: The empty shade view and the footer view should be mutually exclusive.
+
     @Test
-    fun shouldIncludeEmptyShadeView_trueWhenNoNotifs() =
+    fun shouldShowEmptyShadeView_trueWhenNoNotifs() =
         testScope.runTest {
-            val shouldInclude by collectLastValue(underTest.shouldShowEmptyShadeView)
+            val shouldShowEmptyShadeView by collectLastValue(underTest.shouldShowEmptyShadeView)
+            val shouldIncludeFooterView by collectLastValue(underTest.shouldIncludeFooterView)
 
             // WHEN has no notifs
             activeNotificationListRepository.setActiveNotifs(count = 0)
             runCurrent()
 
             // THEN empty shade is visible
-            assertThat(shouldInclude).isTrue()
+            assertThat(shouldShowEmptyShadeView).isTrue()
+            assertThat(shouldIncludeFooterView?.value).isFalse()
         }
 
     @Test
-    fun shouldIncludeEmptyShadeView_falseWhenNotifs() =
+    fun shouldShowEmptyShadeView_falseWhenNotifs() =
         testScope.runTest {
-            val shouldInclude by collectLastValue(underTest.shouldShowEmptyShadeView)
+            val shouldShowEmptyShadeView by collectLastValue(underTest.shouldShowEmptyShadeView)
 
             // WHEN has notifs
             activeNotificationListRepository.setActiveNotifs(count = 2)
             runCurrent()
 
             // THEN empty shade is not visible
-            assertThat(shouldInclude).isFalse()
+            assertThat(shouldShowEmptyShadeView).isFalse()
         }
 
     @Test
-    fun shouldIncludeEmptyShadeView_falseWhenQsExpandedDefault() =
+    fun shouldShowEmptyShadeView_falseWhenQsExpandedDefault() =
         testScope.runTest {
-            val shouldInclude by collectLastValue(underTest.shouldShowEmptyShadeView)
+            val shouldShow by collectLastValue(underTest.shouldShowEmptyShadeView)
 
             // WHEN has no notifs
             activeNotificationListRepository.setActiveNotifs(count = 0)
@@ -184,13 +190,14 @@
             runCurrent()
 
             // THEN empty shade is not visible
-            assertThat(shouldInclude).isFalse()
+            assertThat(shouldShow).isFalse()
         }
 
     @Test
-    fun shouldIncludeEmptyShadeView_trueWhenQsExpandedInSplitShade() =
+    fun shouldShowEmptyShadeView_trueWhenQsExpandedInSplitShade() =
         testScope.runTest {
-            val shouldInclude by collectLastValue(underTest.shouldShowEmptyShadeView)
+            val shouldShowEmptyShadeView by collectLastValue(underTest.shouldShowEmptyShadeView)
+            val shouldIncludeFooterView by collectLastValue(underTest.shouldIncludeFooterView)
 
             // WHEN has no notifs
             activeNotificationListRepository.setActiveNotifs(count = 0)
@@ -203,13 +210,15 @@
             runCurrent()
 
             // THEN empty shade is visible
-            assertThat(shouldInclude).isTrue()
+            assertThat(shouldShowEmptyShadeView).isTrue()
+            assertThat(shouldIncludeFooterView?.value).isFalse()
         }
 
     @Test
-    fun shouldIncludeEmptyShadeView_trueWhenLockedShade() =
+    fun shouldShowEmptyShadeView_trueWhenLockedShade() =
         testScope.runTest {
-            val shouldInclude by collectLastValue(underTest.shouldShowEmptyShadeView)
+            val shouldShowEmptyShadeView by collectLastValue(underTest.shouldShowEmptyShadeView)
+            val shouldIncludeFooterView by collectLastValue(underTest.shouldIncludeFooterView)
 
             // WHEN has no notifs
             activeNotificationListRepository.setActiveNotifs(count = 0)
@@ -218,13 +227,14 @@
             runCurrent()
 
             // THEN empty shade is visible
-            assertThat(shouldInclude).isTrue()
+            assertThat(shouldShowEmptyShadeView).isTrue()
+            assertThat(shouldIncludeFooterView?.value).isFalse()
         }
 
     @Test
-    fun shouldIncludeEmptyShadeView_falseWhenKeyguard() =
+    fun shouldShowEmptyShadeView_falseWhenKeyguard() =
         testScope.runTest {
-            val shouldInclude by collectLastValue(underTest.shouldShowEmptyShadeView)
+            val shouldShow by collectLastValue(underTest.shouldShowEmptyShadeView)
 
             // WHEN has no notifs
             activeNotificationListRepository.setActiveNotifs(count = 0)
@@ -233,13 +243,13 @@
             runCurrent()
 
             // THEN empty shade is not visible
-            assertThat(shouldInclude).isFalse()
+            assertThat(shouldShow).isFalse()
         }
 
     @Test
-    fun shouldIncludeEmptyShadeView_falseWhenStartingToSleep() =
+    fun shouldShowEmptyShadeView_falseWhenStartingToSleep() =
         testScope.runTest {
-            val shouldInclude by collectLastValue(underTest.shouldShowEmptyShadeView)
+            val shouldShow by collectLastValue(underTest.shouldShowEmptyShadeView)
 
             // WHEN has no notifs
             activeNotificationListRepository.setActiveNotifs(count = 0)
@@ -250,7 +260,7 @@
             runCurrent()
 
             // THEN empty shade is not visible
-            assertThat(shouldInclude).isFalse()
+            assertThat(shouldShow).isFalse()
         }
 
     @Test
@@ -258,8 +268,10 @@
         testScope.runTest {
             val hidden by collectLastValue(underTest.areNotificationsHiddenInShade)
 
-            zenModeRepository.setSuppressedVisualEffects(Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST)
-            zenModeRepository.zenMode.value = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
+            zenModeRepository.updateNotificationPolicy(
+                suppressedVisualEffects = Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST
+            )
+            zenModeRepository.updateZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
             runCurrent()
 
             assertThat(hidden).isTrue()
@@ -270,8 +282,10 @@
         testScope.runTest {
             val hidden by collectLastValue(underTest.areNotificationsHiddenInShade)
 
-            zenModeRepository.setSuppressedVisualEffects(Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST)
-            zenModeRepository.zenMode.value = Settings.Global.ZEN_MODE_OFF
+            zenModeRepository.updateNotificationPolicy(
+                suppressedVisualEffects = Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST
+            )
+            zenModeRepository.updateZenMode(Settings.Global.ZEN_MODE_OFF)
             runCurrent()
 
             assertThat(hidden).isFalse()
@@ -302,7 +316,8 @@
     @Test
     fun shouldIncludeFooterView_trueWhenShade() =
         testScope.runTest {
-            val shouldInclude by collectLastValue(underTest.shouldIncludeFooterView)
+            val shouldIncludeFooterView by collectLastValue(underTest.shouldIncludeFooterView)
+            val shouldShowEmptyShadeView by collectLastValue(underTest.shouldShowEmptyShadeView)
 
             // WHEN has notifs
             activeNotificationListRepository.setActiveNotifs(count = 2)
@@ -312,13 +327,15 @@
             runCurrent()
 
             // THEN footer is visible
-            assertThat(shouldInclude?.value).isTrue()
+            assertThat(shouldIncludeFooterView?.value).isTrue()
+            assertThat(shouldShowEmptyShadeView).isFalse()
         }
 
     @Test
     fun shouldIncludeFooterView_trueWhenLockedShade() =
         testScope.runTest {
-            val shouldInclude by collectLastValue(underTest.shouldIncludeFooterView)
+            val shouldIncludeFooterView by collectLastValue(underTest.shouldIncludeFooterView)
+            val shouldShowEmptyShadeView by collectLastValue(underTest.shouldShowEmptyShadeView)
 
             // WHEN has notifs
             activeNotificationListRepository.setActiveNotifs(count = 2)
@@ -328,7 +345,8 @@
             runCurrent()
 
             // THEN footer is visible
-            assertThat(shouldInclude?.value).isTrue()
+            assertThat(shouldIncludeFooterView?.value).isTrue()
+            assertThat(shouldShowEmptyShadeView).isFalse()
         }
 
     @Test
@@ -404,7 +422,8 @@
     @Test
     fun shouldIncludeFooterView_trueWhenQsExpandedSplitShade() =
         testScope.runTest {
-            val shouldInclude by collectLastValue(underTest.shouldIncludeFooterView)
+            val shouldIncludeFooterView by collectLastValue(underTest.shouldIncludeFooterView)
+            val shouldShowEmptyShadeView by collectLastValue(underTest.shouldShowEmptyShadeView)
 
             // WHEN has notifs
             activeNotificationListRepository.setActiveNotifs(count = 2)
@@ -419,7 +438,8 @@
             runCurrent()
 
             // THEN footer is visible
-            assertThat(shouldInclude?.value).isTrue()
+            assertThat(shouldIncludeFooterView?.value).isTrue()
+            assertThat(shouldShowEmptyShadeView).isFalse()
         }
 
     @Test
@@ -528,9 +548,7 @@
                     FakeHeadsUpRowRepository(key = "1"),
                     FakeHeadsUpRowRepository(key = "2"),
                 )
-            headsUpRepository.setNotifications(
-                rows,
-            )
+            headsUpRepository.setNotifications(rows)
             runCurrent()
 
             // THEN the list is empty
@@ -566,7 +584,7 @@
 
             headsUpRepository.setNotifications(
                 FakeHeadsUpRowRepository(key = "0", isPinned = true),
-                FakeHeadsUpRowRepository(key = "1")
+                FakeHeadsUpRowRepository(key = "1"),
             )
             runCurrent()
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelTest.kt
index ee9fd349..4944c8b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.notification.stack.ui.viewmodel
 
+import android.testing.TestableLooper.RunWithLooper
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -31,9 +32,10 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
+@RunWithLooper
 class NotificationsPlaceholderViewModelTest : SysuiTestCase() {
     private val kosmos = testKosmos()
-    private val underTest = kosmos.notificationsPlaceholderViewModel
+    private val underTest by lazy { kosmos.notificationsPlaceholderViewModel }
 
     @Test
     fun onBoundsChanged() =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
index 497484f90..f14c96ded 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
@@ -23,11 +23,15 @@
 import android.platform.test.annotations.EnableFlags
 import android.platform.test.flag.junit.FlagsParameterization
 import androidx.test.filters.SmallTest
+import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.systemui.Flags.FLAG_CENTRALIZED_STATUS_BAR_HEIGHT_FIX
 import com.android.systemui.Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.bouncer.data.repository.keyguardBouncerRepository
 import com.android.systemui.common.shared.model.NotificationContainerBounds
 import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
+import com.android.systemui.communal.data.repository.communalSceneRepository
+import com.android.systemui.communal.shared.model.CommunalScenes
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
 import com.android.systemui.flags.BrokenWithSceneContainer
@@ -134,6 +138,9 @@
     val largeScreenHeaderHelper
         get() = kosmos.mockLargeScreenHeaderHelper
 
+    val communalSceneRepository
+        get() = kosmos.communalSceneRepository
+
     lateinit var underTest: SharedNotificationContainerViewModel
 
     @Before
@@ -845,26 +852,24 @@
     @Test
     @DisableSceneContainer
     fun updateBounds_fromGone_withoutTransitions() =
-            testScope.runTest {
-                // Start step is already at 1.0
-                val runningStep = TransitionStep(GONE, AOD, 1.0f, TransitionState.RUNNING)
-                val finishStep = TransitionStep(GONE, AOD, 1.0f, TransitionState.FINISHED)
+        testScope.runTest {
+            // Start step is already at 1.0
+            val runningStep = TransitionStep(GONE, AOD, 1.0f, TransitionState.RUNNING)
+            val finishStep = TransitionStep(GONE, AOD, 1.0f, TransitionState.FINISHED)
 
-                val bounds by collectLastValue(underTest.bounds)
-                val top = 123f
-                val bottom = 456f
+            val bounds by collectLastValue(underTest.bounds)
+            val top = 123f
+            val bottom = 456f
 
-                kosmos.fakeKeyguardTransitionRepository.sendTransitionStep(runningStep)
-                runCurrent()
-                kosmos.fakeKeyguardTransitionRepository.sendTransitionStep(finishStep)
-                runCurrent()
-                keyguardRootViewModel.onNotificationContainerBoundsChanged(top, bottom)
-                runCurrent()
+            kosmos.fakeKeyguardTransitionRepository.sendTransitionStep(runningStep)
+            runCurrent()
+            kosmos.fakeKeyguardTransitionRepository.sendTransitionStep(finishStep)
+            runCurrent()
+            keyguardRootViewModel.onNotificationContainerBoundsChanged(top, bottom)
+            runCurrent()
 
-                assertThat(bounds).isEqualTo(
-                        NotificationContainerBounds(top = top, bottom = bottom)
-                )
-            }
+            assertThat(bounds).isEqualTo(NotificationContainerBounds(top = top, bottom = bottom))
+        }
 
     @Test
     fun alphaOnFullQsExpansion() =
@@ -1020,6 +1025,230 @@
             assertThat(fadeIn[0]).isEqualTo(false)
         }
 
+    @Test
+    @BrokenWithSceneContainer(330311871)
+    fun alpha_isZero_fromPrimaryBouncerToGoneWhileCommunalSceneVisible() =
+        testScope.runTest {
+            val viewState = ViewStateAccessor()
+            val alpha by collectLastValue(underTest.keyguardAlpha(viewState))
+
+            showPrimaryBouncer()
+            showCommunalScene()
+
+            // PRIMARY_BOUNCER->GONE transition is started
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.PRIMARY_BOUNCER,
+                    to = GONE,
+                    transitionState = TransitionState.STARTED,
+                    value = 0f,
+                )
+            )
+            runCurrent()
+
+            // PRIMARY_BOUNCER->GONE transition running
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.PRIMARY_BOUNCER,
+                    to = GONE,
+                    transitionState = TransitionState.RUNNING,
+                    value = 0.1f,
+                )
+            )
+            runCurrent()
+            assertThat(alpha).isEqualTo(0f)
+
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.PRIMARY_BOUNCER,
+                    to = GONE,
+                    transitionState = TransitionState.RUNNING,
+                    value = 0.9f,
+                )
+            )
+            runCurrent()
+            assertThat(alpha).isEqualTo(0f)
+
+            hideCommunalScene()
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.PRIMARY_BOUNCER,
+                    to = GONE,
+                    transitionState = TransitionState.FINISHED,
+                    value = 1f
+                )
+            )
+            runCurrent()
+            assertThat(alpha).isEqualTo(0f)
+        }
+
+    @Test
+    @BrokenWithSceneContainer(330311871)
+    fun alpha_fromPrimaryBouncerToGoneWhenCommunalSceneNotVisible() =
+        testScope.runTest {
+            val viewState = ViewStateAccessor()
+            val alpha by collectLastValue(underTest.keyguardAlpha(viewState))
+
+            showPrimaryBouncer()
+            hideCommunalScene()
+
+            // PRIMARY_BOUNCER->GONE transition is started
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.PRIMARY_BOUNCER,
+                    to = GONE,
+                    transitionState = TransitionState.STARTED,
+                )
+            )
+            runCurrent()
+
+            // PRIMARY_BOUNCER->GONE transition running
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.PRIMARY_BOUNCER,
+                    to = GONE,
+                    transitionState = TransitionState.RUNNING,
+                    value = 0.1f,
+                )
+            )
+            runCurrent()
+            assertThat(alpha).isIn(Range.closedOpen(0f, 1f))
+
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.PRIMARY_BOUNCER,
+                    to = GONE,
+                    transitionState = TransitionState.RUNNING,
+                    value = 0.9f,
+                )
+            )
+            runCurrent()
+            assertThat(alpha).isIn(Range.closedOpen(0f, 1f))
+
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.PRIMARY_BOUNCER,
+                    to = GONE,
+                    transitionState = TransitionState.FINISHED,
+                    value = 1f
+                )
+            )
+            runCurrent()
+            assertThat(alpha).isEqualTo(0f)
+        }
+
+    @Test
+    @BrokenWithSceneContainer(330311871)
+    fun alpha_isZero_fromAlternateBouncerToGoneWhileCommunalSceneVisible() =
+        testScope.runTest {
+            val viewState = ViewStateAccessor()
+            val alpha by collectLastValue(underTest.keyguardAlpha(viewState))
+
+            showAlternateBouncer()
+            showCommunalScene()
+
+            // ALTERNATE_BOUNCER->GONE transition is started
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.ALTERNATE_BOUNCER,
+                    to = GONE,
+                    transitionState = TransitionState.STARTED,
+                    value = 0f,
+                )
+            )
+            runCurrent()
+
+            // ALTERNATE_BOUNCER->GONE transition running
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.ALTERNATE_BOUNCER,
+                    to = GONE,
+                    transitionState = TransitionState.RUNNING,
+                    value = 0.1f,
+                )
+            )
+            runCurrent()
+            assertThat(alpha).isEqualTo(0f)
+
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.ALTERNATE_BOUNCER,
+                    to = GONE,
+                    transitionState = TransitionState.RUNNING,
+                    value = 0.9f,
+                )
+            )
+            runCurrent()
+            assertThat(alpha).isEqualTo(0f)
+
+            hideCommunalScene()
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.ALTERNATE_BOUNCER,
+                    to = GONE,
+                    transitionState = TransitionState.FINISHED,
+                    value = 1f
+                )
+            )
+            runCurrent()
+            assertThat(alpha).isEqualTo(0f)
+        }
+
+    @Test
+    @BrokenWithSceneContainer(330311871)
+    fun alpha_fromAlternateBouncerToGoneWhenCommunalSceneNotVisible() =
+        testScope.runTest {
+            val viewState = ViewStateAccessor()
+            val alpha by collectLastValue(underTest.keyguardAlpha(viewState))
+
+            showAlternateBouncer()
+            hideCommunalScene()
+
+            // ALTERNATE_BOUNCER->GONE transition is started
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.ALTERNATE_BOUNCER,
+                    to = GONE,
+                    transitionState = TransitionState.STARTED,
+                )
+            )
+            runCurrent()
+
+            // ALTERNATE_BOUNCER->GONE transition running
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.ALTERNATE_BOUNCER,
+                    to = GONE,
+                    transitionState = TransitionState.RUNNING,
+                    value = 0.1f,
+                )
+            )
+            runCurrent()
+            assertThat(alpha).isIn(Range.closedOpen(0f, 1f))
+
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.ALTERNATE_BOUNCER,
+                    to = GONE,
+                    transitionState = TransitionState.RUNNING,
+                    value = 0.9f,
+                )
+            )
+            runCurrent()
+            assertThat(alpha).isIn(Range.closedOpen(0f, 1f))
+
+            keyguardTransitionRepository.sendTransitionStep(
+                TransitionStep(
+                    from = KeyguardState.ALTERNATE_BOUNCER,
+                    to = GONE,
+                    transitionState = TransitionState.FINISHED,
+                    value = 1f
+                )
+            )
+            runCurrent()
+            assertThat(alpha).isEqualTo(0f)
+        }
+
     private suspend fun TestScope.showLockscreen() {
         shadeTestUtil.setQsExpansion(0f)
         shadeTestUtil.setLockscreenShadeExpansion(0f)
@@ -1071,4 +1300,52 @@
             testScope,
         )
     }
+
+    private suspend fun TestScope.showPrimaryBouncer() {
+        shadeTestUtil.setQsExpansion(0f)
+        shadeTestUtil.setLockscreenShadeExpansion(0f)
+        runCurrent()
+        keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
+        runCurrent()
+        kosmos.keyguardBouncerRepository.setPrimaryShow(true)
+        runCurrent()
+        keyguardTransitionRepository.sendTransitionSteps(
+            from = KeyguardState.GLANCEABLE_HUB,
+            to = KeyguardState.PRIMARY_BOUNCER,
+            testScope,
+        )
+    }
+
+    private suspend fun TestScope.showAlternateBouncer() {
+        shadeTestUtil.setQsExpansion(0f)
+        shadeTestUtil.setLockscreenShadeExpansion(0f)
+        runCurrent()
+        keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
+        runCurrent()
+        kosmos.keyguardBouncerRepository.setPrimaryShow(false)
+        runCurrent()
+        keyguardTransitionRepository.sendTransitionSteps(
+            from = KeyguardState.GLANCEABLE_HUB,
+            to = KeyguardState.ALTERNATE_BOUNCER,
+            testScope,
+        )
+    }
+
+    private fun TestScope.showCommunalScene() {
+        val transitionState =
+            MutableStateFlow<ObservableTransitionState>(
+                ObservableTransitionState.Idle(CommunalScenes.Communal)
+            )
+        communalSceneRepository.setTransitionState(transitionState)
+        runCurrent()
+    }
+
+    private fun TestScope.hideCommunalScene() {
+        val transitionState =
+            MutableStateFlow<ObservableTransitionState>(
+                ObservableTransitionState.Idle(CommunalScenes.Blank)
+            )
+        communalSceneRepository.setTransitionState(transitionState)
+        runCurrent()
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImplTest.kt
index 57d3251..ccd78ee 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImplTest.kt
@@ -20,8 +20,11 @@
 import android.app.PendingIntent
 import android.content.Intent
 import android.os.Bundle
+import android.os.Handler
 import android.os.RemoteException
 import android.os.UserHandle
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
 import android.view.View
 import android.widget.FrameLayout
 import android.window.SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR
@@ -29,6 +32,7 @@
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.ActivityIntentHelper
+import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ActivityTransitionAnimator
 import com.android.systemui.animation.LaunchableView
@@ -36,7 +40,6 @@
 import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
 import com.android.systemui.keyguard.KeyguardViewMediator
 import com.android.systemui.keyguard.WakefulnessLifecycle
-import com.android.systemui.plugins.ActivityStarter.OnDismissAction
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.shade.ShadeController
 import com.android.systemui.shade.data.repository.FakeShadeRepository
@@ -51,26 +54,27 @@
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.statusbar.window.StatusBarWindowController
 import com.android.systemui.util.concurrency.FakeExecutor
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.argumentCaptor
-import com.android.systemui.util.mockito.eq
-import com.android.systemui.util.mockito.nullable
-import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
 import java.util.Optional
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyBoolean
 import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.nullable
 import org.mockito.Mock
-import org.mockito.Mockito.anyBoolean
 import org.mockito.Mockito.mock
-import org.mockito.Mockito.never
-import org.mockito.Mockito.times
-import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.never
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
 
 @ExperimentalCoroutinesApi
 @SmallTest
@@ -131,21 +135,41 @@
                 mainExecutor = mainExecutor,
                 communalSceneInteractor = communalSceneInteractor,
             )
-        whenever(userTracker.userHandle).thenReturn(UserHandle.OWNER)
+        `when`(userTracker.userHandle).thenReturn(UserHandle.OWNER)
+        `when`(communalSceneInteractor.isIdleOnCommunal).thenReturn(MutableStateFlow(false))
     }
 
     @Test
     fun startPendingIntentDismissingKeyguard_keyguardShowing_dismissWithAction() {
         val pendingIntent = mock(PendingIntent::class.java)
-        whenever(pendingIntent.isActivity).thenReturn(true)
-        whenever(keyguardStateController.isShowing).thenReturn(true)
-        whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+        `when`(pendingIntent.isActivity).thenReturn(true)
+        `when`(keyguardStateController.isShowing).thenReturn(true)
+        `when`(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
 
         underTest.startPendingIntentDismissingKeyguard(intent = pendingIntent, dismissShade = true)
         mainExecutor.runAllReady()
 
         verify(statusBarKeyguardViewManager)
-            .dismissWithAction(any(OnDismissAction::class.java), eq(null), anyBoolean(), eq(null))
+            .dismissWithAction(any(), eq(null), anyBoolean(), eq(null))
+    }
+
+    @Test
+    fun startPendingIntentDismissingKeyguard_withCustomMessage_dismissWithAction() {
+        val pendingIntent = mock(PendingIntent::class.java)
+        `when`(pendingIntent.isActivity).thenReturn(true)
+        `when`(keyguardStateController.isShowing).thenReturn(true)
+        `when`(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+        val customMessage = "Custom unlock reason"
+
+        underTest.startPendingIntentDismissingKeyguard(
+            intent = pendingIntent,
+            dismissShade = true,
+            customMessage = customMessage
+        )
+        mainExecutor.runAllReady()
+
+        verify(statusBarKeyguardViewManager)
+            .dismissWithAction(any(), eq(null), anyBoolean(), eq(customMessage))
     }
 
     @Test
@@ -158,10 +182,10 @@
             }
         parent.addView(view)
         val controller = ActivityTransitionAnimator.Controller.fromView(view)
-        whenever(pendingIntent.isActivity).thenReturn(true)
-        whenever(keyguardStateController.isShowing).thenReturn(true)
-        whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
-        whenever(activityIntentHelper.wouldPendingShowOverLockscreen(eq(pendingIntent), anyInt()))
+        `when`(pendingIntent.isActivity).thenReturn(true)
+        `when`(keyguardStateController.isShowing).thenReturn(true)
+        `when`(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+        `when`(activityIntentHelper.wouldPendingShowOverLockscreen(eq(pendingIntent), anyInt()))
             .thenReturn(true)
 
         startPendingIntentMaybeDismissingKeyguard(
@@ -173,9 +197,9 @@
 
         verify(activityTransitionAnimator)
             .startPendingIntentWithAnimation(
-                nullable(),
+                nullable(ActivityTransitionAnimator.Controller::class.java),
                 eq(true),
-                nullable(),
+                nullable(String::class.java),
                 eq(true),
                 any(),
             )
@@ -191,10 +215,10 @@
             }
         parent.addView(view)
         val controller = ActivityTransitionAnimator.Controller.fromView(view)
-        whenever(pendingIntent.isActivity).thenReturn(true)
-        whenever(keyguardStateController.isShowing).thenReturn(true)
-        whenever(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
-        whenever(activityIntentHelper.wouldPendingShowOverLockscreen(eq(pendingIntent), anyInt()))
+        `when`(pendingIntent.isActivity).thenReturn(true)
+        `when`(keyguardStateController.isShowing).thenReturn(true)
+        `when`(deviceProvisionedController.isDeviceProvisioned).thenReturn(true)
+        `when`(activityIntentHelper.wouldPendingShowOverLockscreen(eq(pendingIntent), anyInt()))
             .thenReturn(false)
 
         // extra activity options to set on pending intent
@@ -218,12 +242,12 @@
                 eq(context),
                 eq(0),
                 eq(fillInIntent),
-                nullable(),
-                nullable(),
-                nullable(),
+                nullable(PendingIntent.OnFinished::class.java),
+                nullable(Handler::class.java),
+                nullable(String::class.java),
                 bundleCaptor.capture()
             )
-        val options = ActivityOptions.fromBundle(bundleCaptor.value)
+        val options = ActivityOptions.fromBundle(bundleCaptor.firstValue)
         assertThat(options.isPendingIntentBackgroundActivityLaunchAllowedByPermission).isFalse()
         assertThat(options.splashScreenStyle).isEqualTo(SPLASH_SCREEN_STYLE_SOLID_COLOR)
     }
@@ -243,6 +267,74 @@
         verify(centralSurfaces).getAnimatorControllerFromNotification(associatedView)
     }
 
+    @EnableFlags(Flags.FLAG_MEDIA_LOCKSCREEN_LAUNCH_ANIMATION)
+    @Test
+    fun startPendingIntentDismissingKeyguard_transitionAnimator_animateOverOcclusion() {
+        val parent = FrameLayout(context)
+        val view =
+            object : View(context), LaunchableView {
+                override fun setShouldBlockVisibilityChanges(block: Boolean) {}
+            }
+        parent.addView(view)
+        val controller = ActivityTransitionAnimator.Controller.fromView(view)
+        val pendingIntent = mock(PendingIntent::class.java)
+        `when`(pendingIntent.isActivity).thenReturn(true)
+        `when`(keyguardStateController.isShowing).thenReturn(true)
+        `when`(keyguardStateController.isOccluded).thenReturn(true)
+
+        underTest.startPendingIntentDismissingKeyguard(
+            intent = pendingIntent,
+            dismissShade = true,
+            animationController = controller,
+            showOverLockscreen = true,
+            skipLockscreenChecks = true
+        )
+        mainExecutor.runAllReady()
+
+        verify(activityTransitionAnimator)
+            .startPendingIntentWithAnimation(
+                nullable(ActivityTransitionAnimator.Controller::class.java),
+                eq(true),
+                nullable(String::class.java),
+                eq(true),
+                any(),
+            )
+    }
+
+    @DisableFlags(Flags.FLAG_MEDIA_LOCKSCREEN_LAUNCH_ANIMATION)
+    @Test
+    fun startPendingIntentDismissingKeyguard_transitionAnimator_doNotAnimateOverOcclusion() {
+        val parent = FrameLayout(context)
+        val view =
+            object : View(context), LaunchableView {
+                override fun setShouldBlockVisibilityChanges(block: Boolean) {}
+            }
+        parent.addView(view)
+        val controller = ActivityTransitionAnimator.Controller.fromView(view)
+        val pendingIntent = mock(PendingIntent::class.java)
+        `when`(pendingIntent.isActivity).thenReturn(true)
+        `when`(keyguardStateController.isShowing).thenReturn(true)
+        `when`(keyguardStateController.isOccluded).thenReturn(true)
+
+        underTest.startPendingIntentDismissingKeyguard(
+            intent = pendingIntent,
+            dismissShade = true,
+            animationController = controller,
+            showOverLockscreen = true,
+            skipLockscreenChecks = true
+        )
+        mainExecutor.runAllReady()
+
+        verify(activityTransitionAnimator)
+            .startPendingIntentWithAnimation(
+                nullable(ActivityTransitionAnimator.Controller::class.java),
+                eq(false),
+                nullable(String::class.java),
+                eq(true),
+                any(),
+            )
+    }
+
     @Test
     fun startActivity_noUserHandleProvided_getUserHandle() {
         val intent = mock(Intent::class.java)
@@ -252,13 +344,66 @@
         verify(userTracker).userHandle
     }
 
+    @EnableFlags(Flags.FLAG_MEDIA_LOCKSCREEN_LAUNCH_ANIMATION)
+    @Test
+    fun startActivity_transitionAnimator_animateOverOcclusion() {
+        val intent = mock(Intent::class.java)
+        val parent = FrameLayout(context)
+        val view =
+            object : View(context), LaunchableView {
+                override fun setShouldBlockVisibilityChanges(block: Boolean) {}
+            }
+        parent.addView(view)
+        val controller = ActivityTransitionAnimator.Controller.fromView(view)
+        `when`(keyguardStateController.isShowing).thenReturn(true)
+        `when`(keyguardStateController.isOccluded).thenReturn(true)
+
+        mainExecutor.runAllReady()
+        underTest.startActivity(intent, true, controller, true, null)
+
+        verify(activityTransitionAnimator)
+            .startIntentWithAnimation(
+                nullable(ActivityTransitionAnimator.Controller::class.java),
+                eq(true),
+                nullable(String::class.java),
+                eq(true),
+                any(),
+            )
+    }
+
+    @DisableFlags(Flags.FLAG_MEDIA_LOCKSCREEN_LAUNCH_ANIMATION)
+    @Test
+    fun startActivity_transitionAnimator_doNotAnimateOverOcclusion() {
+        val intent = mock(Intent::class.java)
+        val parent = FrameLayout(context)
+        val view =
+            object : View(context), LaunchableView {
+                override fun setShouldBlockVisibilityChanges(block: Boolean) {}
+            }
+        parent.addView(view)
+        val controller = ActivityTransitionAnimator.Controller.fromView(view)
+        `when`(keyguardStateController.isShowing).thenReturn(true)
+        `when`(keyguardStateController.isOccluded).thenReturn(true)
+
+        mainExecutor.runAllReady()
+        underTest.startActivity(intent, true, controller, true, null)
+
+        verify(activityTransitionAnimator)
+            .startIntentWithAnimation(
+                nullable(ActivityTransitionAnimator.Controller::class.java),
+                eq(false),
+                nullable(String::class.java),
+                eq(true),
+                any(),
+            )
+    }
+
     @Test
     fun dismissKeyguardThenExecute_startWakeAndUnlock() {
-        whenever(wakefulnessLifecycle.wakefulness)
-            .thenReturn(WakefulnessLifecycle.WAKEFULNESS_ASLEEP)
-        whenever(keyguardStateController.canDismissLockScreen()).thenReturn(true)
-        whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(false)
-        whenever(dozeServiceHost.isPulsing).thenReturn(true)
+        `when`(wakefulnessLifecycle.wakefulness).thenReturn(WakefulnessLifecycle.WAKEFULNESS_ASLEEP)
+        `when`(keyguardStateController.canDismissLockScreen()).thenReturn(true)
+        `when`(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(false)
+        `when`(dozeServiceHost.isPulsing).thenReturn(true)
 
         underTest.dismissKeyguardThenExecute({ true }, {}, false)
 
@@ -269,25 +414,20 @@
     @Test
     fun dismissKeyguardThenExecute_keyguardIsShowing_dismissWithAction() {
         val customMessage = "Enter your pin."
-        whenever(keyguardStateController.isShowing).thenReturn(true)
+        `when`(keyguardStateController.isShowing).thenReturn(true)
 
         underTest.dismissKeyguardThenExecute({ true }, {}, false, customMessage)
 
         verify(statusBarKeyguardViewManager)
-            .dismissWithAction(
-                any(OnDismissAction::class.java),
-                any(Runnable::class.java),
-                eq(false),
-                eq(customMessage)
-            )
+            .dismissWithAction(any(), any(), eq(false), eq(customMessage))
     }
 
     @Test
     fun dismissKeyguardThenExecute_awakeDreams() {
         val customMessage = "Enter your pin."
         var dismissActionExecuted = false
-        whenever(keyguardStateController.isShowing).thenReturn(false)
-        whenever(keyguardUpdateMonitor.isDreaming).thenReturn(true)
+        `when`(keyguardStateController.isShowing).thenReturn(false)
+        `when`(keyguardUpdateMonitor.isDreaming).thenReturn(true)
 
         underTest.dismissKeyguardThenExecute(
             {
@@ -306,9 +446,9 @@
     @Test
     @Throws(RemoteException::class)
     fun executeRunnableDismissingKeyguard_dreaming_notShowing_awakenDreams() {
-        whenever(keyguardStateController.isShowing).thenReturn(false)
-        whenever(keyguardStateController.isOccluded).thenReturn(false)
-        whenever(keyguardUpdateMonitor.isDreaming).thenReturn(true)
+        `when`(keyguardStateController.isShowing).thenReturn(false)
+        `when`(keyguardStateController.isOccluded).thenReturn(false)
+        `when`(keyguardUpdateMonitor.isDreaming).thenReturn(true)
 
         underTest.executeRunnableDismissingKeyguard(
             runnable = {},
@@ -324,9 +464,9 @@
     @Test
     @Throws(RemoteException::class)
     fun executeRunnableDismissingKeyguard_notDreaming_notShowing_doNotAwakenDreams() {
-        whenever(keyguardStateController.isShowing).thenReturn(false)
-        whenever(keyguardStateController.isOccluded).thenReturn(false)
-        whenever(keyguardUpdateMonitor.isDreaming).thenReturn(false)
+        `when`(keyguardStateController.isShowing).thenReturn(false)
+        `when`(keyguardStateController.isOccluded).thenReturn(false)
+        `when`(keyguardUpdateMonitor.isDreaming).thenReturn(false)
 
         underTest.executeRunnableDismissingKeyguard(
             runnable = {},
@@ -345,6 +485,7 @@
         animationController: ActivityTransitionAnimator.Controller?,
         fillInIntent: Intent? = null,
         extraOptions: Bundle? = null,
+        customMessage: String? = null,
     ) {
         underTest.startPendingIntentDismissingKeyguard(
             intent = intent,
@@ -354,6 +495,7 @@
             showOverLockscreen = true,
             fillInIntent = fillInIntent,
             extraOptions = extraOptions,
+            customMessage = customMessage,
         )
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt
index 6b5d072..495ab61 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt
@@ -16,6 +16,7 @@
 package com.android.systemui.statusbar.policy
 
 import android.app.Notification
+import android.os.Handler
 import android.platform.test.annotations.EnableFlags
 import android.testing.TestableLooper.RunWithLooper
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -59,6 +60,9 @@
     // For creating TestableHeadsUpManager
     @Mock private val mAccessibilityMgr: AccessibilityManagerWrapper? = null
     private val mUiEventLoggerFake = UiEventLoggerFake()
+
+    @Mock private lateinit var mBgHandler: Handler
+
     private val mLogger = Mockito.spy(HeadsUpManagerLogger(logcatLogBuffer()))
     private val mGlobalSettings = FakeGlobalSettings()
     private val mSystemClock = FakeSystemClock()
@@ -78,7 +82,7 @@
 
         // Initialize AvalancheController and TestableHeadsUpManager during setUp instead of
         // declaration, where mocks are null
-        mAvalancheController = AvalancheController(dumpManager, mUiEventLoggerFake)
+        mAvalancheController = AvalancheController(dumpManager, mUiEventLoggerFake, mBgHandler)
 
         testableHeadsUpManager =
             TestableHeadsUpManager(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
index 206b39c..df07b44 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
@@ -38,6 +38,7 @@
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.app.Person;
+import android.os.Handler;
 import android.platform.test.annotations.DisableFlags;
 import android.platform.test.annotations.EnableFlags;
 import android.platform.test.flag.junit.FlagsParameterization;
@@ -81,7 +82,7 @@
 
     private UiEventLoggerFake mUiEventLoggerFake = new UiEventLoggerFake();
     private final HeadsUpManagerLogger mLogger = spy(new HeadsUpManagerLogger(logcatLogBuffer()));
-
+    @Mock private Handler mBgHandler;
     @Mock private DumpManager dumpManager;
     private AvalancheController mAvalancheController;
 
@@ -148,7 +149,7 @@
     @Override
     public void SysuiSetup() throws Exception {
         super.SysuiSetup();
-        mAvalancheController = new AvalancheController(dumpManager, mUiEventLoggerFake);
+        mAvalancheController = new AvalancheController(dumpManager, mUiEventLoggerFake, mBgHandler);
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.java
index 200e92e..3d3438e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.java
@@ -26,6 +26,7 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.os.Handler;
 import android.platform.test.flag.junit.FlagsParameterization;
 import android.testing.TestableLooper;
 
@@ -85,6 +86,8 @@
     @Mock private DumpManager dumpManager;
     private AvalancheController mAvalancheController;
 
+    @Mock private Handler mBgHandler;
+
     private static final class TestableHeadsUpManagerPhone extends HeadsUpManagerPhone {
         TestableHeadsUpManagerPhone(
                 Context context,
@@ -167,7 +170,7 @@
         mContext.getOrCreateTestableResources().addOverride(
                 R.integer.ambient_notification_extension_time, 500);
 
-        mAvalancheController = new AvalancheController(dumpManager, mUiEventLogger);
+        mAvalancheController = new AvalancheController(dumpManager, mUiEventLogger, mBgHandler);
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorTest.kt
new file mode 100644
index 0000000..88431f0
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorTest.kt
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.policy.domain.interactor
+
+import android.app.NotificationManager.Policy
+import android.provider.Settings
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.settingslib.notification.data.repository.updateNotificationPolicy
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.statusbar.policy.data.repository.fakeZenModeRepository
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class ZenModeInteractorTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val repository = kosmos.fakeZenModeRepository
+
+    private val underTest = kosmos.zenModeInteractor
+
+    @Test
+    fun isZenModeEnabled_off() =
+        testScope.runTest {
+            val enabled by collectLastValue(underTest.isZenModeEnabled)
+
+            repository.updateZenMode(Settings.Global.ZEN_MODE_OFF)
+            runCurrent()
+
+            assertThat(enabled).isFalse()
+        }
+
+    @Test
+    fun isZenModeEnabled_alarms() =
+        testScope.runTest {
+            val enabled by collectLastValue(underTest.isZenModeEnabled)
+
+            repository.updateZenMode(Settings.Global.ZEN_MODE_ALARMS)
+            runCurrent()
+
+            assertThat(enabled).isTrue()
+        }
+
+    @Test
+    fun isZenModeEnabled_importantInterruptions() =
+        testScope.runTest {
+            val enabled by collectLastValue(underTest.isZenModeEnabled)
+
+            repository.updateZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
+            runCurrent()
+
+            assertThat(enabled).isTrue()
+        }
+
+    @Test
+    fun isZenModeEnabled_noInterruptions() =
+        testScope.runTest {
+            val enabled by collectLastValue(underTest.isZenModeEnabled)
+
+            repository.updateZenMode(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS)
+            runCurrent()
+
+            assertThat(enabled).isTrue()
+        }
+
+    @Test
+    fun testIsZenModeEnabled_unknown() =
+        testScope.runTest {
+            val enabled by collectLastValue(underTest.isZenModeEnabled)
+
+            repository.updateZenMode(4) // this should fail if we ever add another zen mode type
+            runCurrent()
+
+            assertThat(enabled).isFalse()
+        }
+
+    @Test
+    fun areNotificationsHiddenInShade_noPolicy() =
+        testScope.runTest {
+            val hidden by collectLastValue(underTest.areNotificationsHiddenInShade)
+
+            repository.updateNotificationPolicy(null)
+            repository.updateZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
+            runCurrent()
+
+            assertThat(hidden).isFalse()
+        }
+
+    @Test
+    fun areNotificationsHiddenInShade_zenOffShadeSuppressed() =
+        testScope.runTest {
+            val hidden by collectLastValue(underTest.areNotificationsHiddenInShade)
+
+            repository.updateNotificationPolicy(
+                suppressedVisualEffects = Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST
+            )
+            repository.updateZenMode(Settings.Global.ZEN_MODE_OFF)
+            runCurrent()
+
+            assertThat(hidden).isFalse()
+        }
+
+    @Test
+    fun areNotificationsHiddenInShade_zenOnShadeNotSuppressed() =
+        testScope.runTest {
+            val hidden by collectLastValue(underTest.areNotificationsHiddenInShade)
+
+            repository.updateNotificationPolicy(
+                suppressedVisualEffects = Policy.SUPPRESSED_EFFECT_STATUS_BAR
+            )
+            repository.updateZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
+            runCurrent()
+
+            assertThat(hidden).isFalse()
+        }
+
+    @Test
+    fun areNotificationsHiddenInShade_zenOnShadeSuppressed() =
+        testScope.runTest {
+            val hidden by collectLastValue(underTest.areNotificationsHiddenInShade)
+
+            repository.updateNotificationPolicy(
+                suppressedVisualEffects = Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST
+            )
+            repository.updateZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
+            runCurrent()
+
+            assertThat(hidden).isTrue()
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.kt
new file mode 100644
index 0000000..1b704b4
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.kt
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.service
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.concurrency.fakeExecutor
+import com.android.systemui.dump.dumpManager
+import com.android.systemui.testKosmos
+import com.android.systemui.util.service.ObservableServiceConnection.DISCONNECT_REASON_DISCONNECTED
+import com.android.systemui.util.time.fakeSystemClock
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class PersistentConnectionManagerTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+
+    private val fakeClock = kosmos.fakeSystemClock
+    private val fakeExecutor = kosmos.fakeExecutor
+
+    private class Proxy {
+        // Fake proxy class
+    }
+
+    private val connection: ObservableServiceConnection<Proxy> = mock()
+    private val observer: Observer = mock()
+
+    private val underTest: PersistentConnectionManager<Proxy> by lazy {
+        PersistentConnectionManager(
+            /* clock = */ fakeClock,
+            /* bgExecutor = */ fakeExecutor,
+            /* dumpManager = */ kosmos.dumpManager,
+            /* dumpsysName = */ DUMPSYS_NAME,
+            /* serviceConnection = */ connection,
+            /* maxReconnectAttempts = */ MAX_RETRIES,
+            /* baseReconnectDelayMs = */ RETRY_DELAY_MS,
+            /* minConnectionDurationMs = */ CONNECTION_MIN_DURATION_MS,
+            /* observer = */ observer
+        )
+    }
+
+    /** Validates initial connection. */
+    @Test
+    fun testConnect() {
+        underTest.start()
+        captureCallbackAndVerifyBind(connection).onConnected(connection, mock<Proxy>())
+    }
+
+    /** Ensures reconnection on disconnect. */
+    @Test
+    fun testExponentialRetryOnDisconnect() {
+        underTest.start()
+
+        // IF service is connected...
+        val captor = argumentCaptor<ObservableServiceConnection.Callback<Proxy>>()
+        verify(connection, times(1)).bind()
+        verify(connection).addCallback(captor.capture())
+        val callback = captor.lastValue
+        callback.onConnected(connection, mock<Proxy>())
+
+        // ...AND service becomes disconnected within CONNECTION_MIN_DURATION_MS
+        callback.onDisconnected(connection, DISCONNECT_REASON_DISCONNECTED)
+
+        // THEN verify we retry to bind after the retry delay. (RETRY #1)
+        verify(connection, times(1)).bind()
+        fakeClock.advanceTime(RETRY_DELAY_MS.toLong())
+        verify(connection, times(2)).bind()
+
+        // IF service becomes disconnected for a second time after first retry...
+        callback.onConnected(connection, mock<Proxy>())
+        callback.onDisconnected(connection, DISCONNECT_REASON_DISCONNECTED)
+
+        // THEN verify we retry after a longer delay of 2 * RETRY_DELAY_MS (RETRY #2)
+        fakeClock.advanceTime(RETRY_DELAY_MS.toLong())
+        verify(connection, times(2)).bind()
+        fakeClock.advanceTime(RETRY_DELAY_MS.toLong())
+        verify(connection, times(3)).bind()
+
+        // IF service becomes disconnected for a third time after the second retry...
+        callback.onConnected(connection, mock<Proxy>())
+        callback.onDisconnected(connection, DISCONNECT_REASON_DISCONNECTED)
+
+        // THEN verify we retry after a longer delay of 4 * RETRY_DELAY_MS (RETRY #3)
+        fakeClock.advanceTime(3 * RETRY_DELAY_MS.toLong())
+        verify(connection, times(3)).bind()
+        fakeClock.advanceTime(RETRY_DELAY_MS.toLong())
+        verify(connection, times(4)).bind()
+    }
+
+    @Test
+    fun testDoesNotRetryAfterMaxRetries() {
+        underTest.start()
+
+        val captor = argumentCaptor<ObservableServiceConnection.Callback<Proxy>>()
+        verify(connection).addCallback(captor.capture())
+        val callback = captor.lastValue
+
+        // IF we retry MAX_TRIES times...
+        for (attemptCount in 0 until MAX_RETRIES + 1) {
+            verify(connection, times(attemptCount + 1)).bind()
+            callback.onConnected(connection, mock<Proxy>())
+            callback.onDisconnected(connection, DISCONNECT_REASON_DISCONNECTED)
+            fakeClock.advanceTime(Math.scalb(RETRY_DELAY_MS.toDouble(), attemptCount).toLong())
+        }
+
+        // THEN we should not retry again after the last attempt.
+        fakeExecutor.advanceClockToLast()
+        verify(connection, times(MAX_RETRIES + 1)).bind()
+    }
+
+    @Test
+    fun testEnsureNoRetryIfServiceNeverConnectsAfterRetry() {
+        underTest.start()
+
+        with(captureCallbackAndVerifyBind(connection)) {
+            // IF service initially connects and then disconnects...
+            onConnected(connection, mock<Proxy>())
+            onDisconnected(connection, DISCONNECT_REASON_DISCONNECTED)
+            fakeExecutor.advanceClockToLast()
+            fakeExecutor.runAllReady()
+
+            // ...AND we retry once.
+            verify(connection, times(1)).bind()
+
+            // ...AND service disconnects after initial retry without ever connecting again.
+            onDisconnected(connection, DISCONNECT_REASON_DISCONNECTED)
+            fakeExecutor.advanceClockToLast()
+            fakeExecutor.runAllReady()
+
+            // THEN verify another retry is not triggered.
+            verify(connection, times(1)).bind()
+        }
+    }
+
+    @Test
+    fun testEnsureNoRetryIfServiceNeverInitiallyConnects() {
+        underTest.start()
+
+        with(captureCallbackAndVerifyBind(connection)) {
+            // IF service never connects and we just receive the disconnect signal...
+            onDisconnected(connection, DISCONNECT_REASON_DISCONNECTED)
+            fakeExecutor.advanceClockToLast()
+            fakeExecutor.runAllReady()
+
+            // THEN do not retry
+            verify(connection, never()).bind()
+        }
+    }
+
+    /** Ensures manual unbind does not reconnect. */
+    @Test
+    fun testStopDoesNotReconnect() {
+        underTest.start()
+
+        val connectionCallbackCaptor = argumentCaptor<ObservableServiceConnection.Callback<Proxy>>()
+        verify(connection).addCallback(connectionCallbackCaptor.capture())
+        verify(connection).bind()
+        clearInvocations(connection)
+
+        underTest.stop()
+        fakeExecutor.advanceClockToNext()
+        fakeExecutor.runAllReady()
+        verify(connection, never()).bind()
+    }
+
+    /** Ensures rebind on package change. */
+    @Test
+    fun testAttemptOnPackageChange() {
+        underTest.start()
+
+        verify(connection).bind()
+
+        val callbackCaptor = argumentCaptor<Observer.Callback>()
+        captureCallbackAndVerifyBind(connection).onConnected(connection, mock<Proxy>())
+
+        verify(observer).addCallback(callbackCaptor.capture())
+        callbackCaptor.lastValue.onSourceChanged()
+        verify(connection).bind()
+    }
+
+    @Test
+    fun testAddConnectionCallback() {
+        val connectionCallback: ObservableServiceConnection.Callback<Proxy> = mock()
+        underTest.addConnectionCallback(connectionCallback)
+        verify(connection).addCallback(connectionCallback)
+    }
+
+    @Test
+    fun testRemoveConnectionCallback() {
+        val connectionCallback: ObservableServiceConnection.Callback<Proxy> = mock()
+        underTest.removeConnectionCallback(connectionCallback)
+        verify(connection).removeCallback(connectionCallback)
+    }
+
+    /** Helper method to capture the [ObservableServiceConnection.Callback] */
+    private fun captureCallbackAndVerifyBind(
+        mConnection: ObservableServiceConnection<Proxy>,
+    ): ObservableServiceConnection.Callback<Proxy> {
+
+        val connectionCallbackCaptor = argumentCaptor<ObservableServiceConnection.Callback<Proxy>>()
+        verify(mConnection).addCallback(connectionCallbackCaptor.capture())
+        verify(mConnection).bind()
+        clearInvocations(mConnection)
+
+        return connectionCallbackCaptor.lastValue
+    }
+
+    companion object {
+        private const val MAX_RETRIES = 3
+        private const val RETRY_DELAY_MS = 1000
+        private const val CONNECTION_MIN_DURATION_MS = 5000
+        private const val DUMPSYS_NAME = "dumpsys_name"
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioVolumeInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioVolumeInteractorTest.kt
index d620639..1ea8a6b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioVolumeInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/domain/interactor/AudioVolumeInteractorTest.kt
@@ -20,8 +20,7 @@
 import android.provider.Settings
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.settingslib.statusbar.notification.data.model.ZenMode
-import com.android.settingslib.statusbar.notification.data.repository.updateNotificationPolicy
+import com.android.settingslib.notification.data.repository.updateNotificationPolicy
 import com.android.settingslib.volume.domain.interactor.AudioVolumeInteractor
 import com.android.settingslib.volume.shared.model.AudioStream
 import com.android.settingslib.volume.shared.model.RingerMode
@@ -29,13 +28,14 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.statusbar.notification.domain.interactor.notificationsSoundPolicyInteractor
-import com.android.systemui.statusbar.notification.domain.interactor.notificationsSoundPolicyRepository
+import com.android.systemui.statusbar.policy.data.repository.zenModeRepository
 import com.android.systemui.testKosmos
 import com.android.systemui.volume.data.repository.audioRepository
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
+import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -49,6 +49,20 @@
     private val underTest: AudioVolumeInteractor =
         with(kosmos) { AudioVolumeInteractor(audioRepository, notificationsSoundPolicyInteractor) }
 
+    @Before
+    fun setUp() =
+        with(kosmos) {
+            audioRepository.setAudioStreamModel(
+                audioRepository.getAudioStream(audioStream).value.copy(isAffectedByMute = true)
+            )
+            audioRepository.setAudioStreamModel(
+                audioRepository
+                    .getAudioStream(AudioStream(AudioManager.STREAM_RING))
+                    .value
+                    .copy(isAffectedByMute = true)
+            )
+        }
+
     @Test
     fun setMuted_mutesStream() {
         with(kosmos) {
@@ -104,10 +118,8 @@
     fun zenMuted_cantChange() {
         with(kosmos) {
             testScope.runTest {
-                notificationsSoundPolicyRepository.updateNotificationPolicy()
-                notificationsSoundPolicyRepository.updateZenMode(
-                    ZenMode(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS)
-                )
+                zenModeRepository.updateNotificationPolicy()
+                zenModeRepository.updateZenMode(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS)
 
                 val canChangeVolume by
                     collectLastValue(
@@ -141,9 +153,7 @@
         with(kosmos) {
             testScope.runTest {
                 audioRepository.setLastAudibleVolume(audioStream, 30)
-                notificationsSoundPolicyRepository.updateZenMode(
-                    ZenMode(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS)
-                )
+                zenModeRepository.updateZenMode(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS)
 
                 val model by collectLastValue(underTest.getAudioStream(audioStream))
                 runCurrent()
@@ -194,10 +204,14 @@
             testScope.runTest {
                 val audioStreamModel by collectLastValue(underTest.getAudioStream(audioStream))
                 audioRepository.setAudioStreamModel(
-                    audioStreamModel!!.copy(isAffectedByMute = false)
+                    audioStreamModel!!.copy(isAffectedByMute = false, isMuted = false)
                 )
 
+                underTest.setMuted(audioStream, true)
+                runCurrent()
+
                 assertThat(audioStreamModel!!.isAffectedByMute).isFalse()
+                assertThat(audioStreamModel!!.isMuted).isFalse()
             }
         }
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/SpatialAudioComponentKosmos.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/SpatialAudioComponentKosmos.kt
index 777240c..5826b3f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/SpatialAudioComponentKosmos.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/SpatialAudioComponentKosmos.kt
@@ -17,8 +17,10 @@
 package com.android.systemui.volume.panel.component.spatial
 
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.backgroundCoroutineContext
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.media.spatializerInteractor
+import com.android.systemui.volume.data.repository.audioRepository
 import com.android.systemui.volume.domain.interactor.audioOutputInteractor
 import com.android.systemui.volume.panel.component.spatial.domain.interactor.SpatialAudioComponentInteractor
 
@@ -27,6 +29,8 @@
         SpatialAudioComponentInteractor(
             audioOutputInteractor,
             spatializerInteractor,
+            audioRepository,
+            backgroundCoroutineContext,
             testScope.backgroundScope
         )
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/domain/SpatialAudioAvailabilityCriteriaTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/domain/SpatialAudioAvailabilityCriteriaTest.kt
index 2f69942..ebc78d8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/domain/SpatialAudioAvailabilityCriteriaTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/domain/SpatialAudioAvailabilityCriteriaTest.kt
@@ -16,6 +16,8 @@
 
 package com.android.systemui.volume.panel.component.spatial.domain
 
+import android.bluetooth.BluetoothDevice
+import android.bluetooth.BluetoothProfile
 import android.media.AudioDeviceAttributes
 import android.media.AudioDeviceInfo
 import android.media.session.MediaSession
@@ -24,12 +26,14 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.settingslib.bluetooth.LeAudioProfile
 import com.android.settingslib.media.BluetoothMediaDevice
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.media.spatializerRepository
 import com.android.systemui.testKosmos
+import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.volume.localMediaController
@@ -56,8 +60,15 @@
     @Before
     fun setup() {
         with(kosmos) {
+            val leAudioProfile =
+                mock<LeAudioProfile> {
+                    whenever(profileId).thenReturn(BluetoothProfile.LE_AUDIO)
+                    whenever(isEnabled(any())).thenReturn(true)
+                }
             val cachedBluetoothDevice: CachedBluetoothDevice = mock {
                 whenever(address).thenReturn("test_address")
+                whenever(profiles).thenReturn(listOf(leAudioProfile))
+                whenever(device).thenReturn(mock<BluetoothDevice> {})
             }
             localMediaRepository.updateCurrentConnectedDevice(
                 mock<BluetoothMediaDevice> {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractorTest.kt
index c6c46fa..d5566ad 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractorTest.kt
@@ -16,14 +16,22 @@
 
 package com.android.systemui.volume.panel.component.spatial.domain.interactor
 
+import android.bluetooth.BluetoothDevice
+import android.bluetooth.BluetoothProfile
 import android.media.AudioDeviceAttributes
 import android.media.AudioDeviceInfo
 import android.media.session.MediaSession
 import android.media.session.PlaybackState
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
 import android.testing.TestableLooper
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.settingslib.bluetooth.A2dpProfile
 import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.settingslib.bluetooth.HearingAidProfile
+import com.android.settingslib.bluetooth.LeAudioProfile
+import com.android.settingslib.flags.Flags
 import com.android.settingslib.media.BluetoothMediaDevice
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
@@ -44,6 +52,7 @@
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -52,15 +61,33 @@
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 class SpatialAudioComponentInteractorTest : SysuiTestCase() {
+    @get:Rule val setFlagsRule = SetFlagsRule()
 
     private val kosmos = testKosmos()
     private lateinit var underTest: SpatialAudioComponentInteractor
 
+    private val bluetoothDevice: BluetoothDevice = mock {}
+    private val a2dpProfile: A2dpProfile = mock {
+        whenever(profileId).thenReturn(BluetoothProfile.A2DP)
+        whenever(isEnabled(bluetoothDevice)).thenReturn(false)
+    }
+    private val leAudioProfile: LeAudioProfile = mock {
+        whenever(profileId).thenReturn(BluetoothProfile.LE_AUDIO)
+        whenever(isEnabled(bluetoothDevice)).thenReturn(true)
+    }
+    private val hearingAidProfile: HearingAidProfile = mock {
+        whenever(profileId).thenReturn(BluetoothProfile.HEARING_AID)
+        whenever(isEnabled(bluetoothDevice)).thenReturn(false)
+    }
+
     @Before
     fun setup() {
         with(kosmos) {
             val cachedBluetoothDevice: CachedBluetoothDevice = mock {
                 whenever(address).thenReturn("test_address")
+                whenever(device).thenReturn(bluetoothDevice)
+                whenever(profiles)
+                    .thenReturn(listOf(a2dpProfile, leAudioProfile, hearingAidProfile))
             }
             localMediaRepository.updateCurrentConnectedDevice(
                 mock<BluetoothMediaDevice> {
@@ -83,7 +110,7 @@
     fun setEnabled_changesIsEnabled() {
         with(kosmos) {
             testScope.runTest {
-                spatializerRepository.setIsSpatialAudioAvailable(headset, true)
+                spatializerRepository.setIsSpatialAudioAvailable(bleHeadsetAttributes, true)
                 val values by collectValues(underTest.isEnabled)
 
                 underTest.setEnabled(SpatialAudioEnabledModel.Disabled)
@@ -106,10 +133,39 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DETERMINING_SPATIAL_AUDIO_ATTRIBUTES_BY_PROFILE)
+    fun setEnabled_determinedByBluetoothProfile_a2dpProfileEnabled() {
+        with(kosmos) {
+            testScope.runTest {
+                whenever(a2dpProfile.isEnabled(bluetoothDevice)).thenReturn(true)
+                whenever(leAudioProfile.isEnabled(bluetoothDevice)).thenReturn(false)
+                whenever(hearingAidProfile.isEnabled(bluetoothDevice)).thenReturn(false)
+                spatializerRepository.setIsSpatialAudioAvailable(a2dpAttributes, true)
+                val values by collectValues(underTest.isEnabled)
+
+                underTest.setEnabled(SpatialAudioEnabledModel.Disabled)
+                runCurrent()
+                underTest.setEnabled(SpatialAudioEnabledModel.SpatialAudioEnabled)
+                runCurrent()
+
+                assertThat(values)
+                    .containsExactly(
+                        SpatialAudioEnabledModel.Unknown,
+                        SpatialAudioEnabledModel.Disabled,
+                        SpatialAudioEnabledModel.SpatialAudioEnabled,
+                    )
+                    .inOrder()
+                assertThat(spatializerRepository.getSpatialAudioCompatibleDevices())
+                    .containsExactly(a2dpAttributes)
+            }
+        }
+    }
+
+    @Test
     fun connectedDeviceSupports_isAvailable_SpatialAudio() {
         with(kosmos) {
             testScope.runTest {
-                spatializerRepository.setIsSpatialAudioAvailable(headset, true)
+                spatializerRepository.setIsSpatialAudioAvailable(bleHeadsetAttributes, true)
 
                 val isAvailable by collectLastValue(underTest.isAvailable)
 
@@ -123,8 +179,8 @@
     fun connectedDeviceSupportsHeadTracking_isAvailable_HeadTracking() {
         with(kosmos) {
             testScope.runTest {
-                spatializerRepository.setIsSpatialAudioAvailable(headset, true)
-                spatializerRepository.setIsHeadTrackingAvailable(headset, true)
+                spatializerRepository.setIsSpatialAudioAvailable(bleHeadsetAttributes, true)
+                spatializerRepository.setIsHeadTrackingAvailable(bleHeadsetAttributes, true)
 
                 val isAvailable by collectLastValue(underTest.isAvailable)
 
@@ -138,7 +194,7 @@
     fun connectedDeviceDoesntSupport_isAvailable_Unavailable() {
         with(kosmos) {
             testScope.runTest {
-                spatializerRepository.setIsSpatialAudioAvailable(headset, false)
+                spatializerRepository.setIsSpatialAudioAvailable(bleHeadsetAttributes, false)
 
                 val isAvailable by collectLastValue(underTest.isAvailable)
 
@@ -179,7 +235,13 @@
     }
 
     private companion object {
-        val headset =
+        val a2dpAttributes =
+            AudioDeviceAttributes(
+                AudioDeviceAttributes.ROLE_OUTPUT,
+                AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
+                "test_address"
+            )
+        val bleHeadsetAttributes =
             AudioDeviceAttributes(
                 AudioDeviceAttributes.ROLE_OUTPUT,
                 AudioDeviceInfo.TYPE_BLE_HEADSET,
diff --git a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
index 9ad4012..074277c 100644
--- a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
+++ b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java
@@ -24,6 +24,7 @@
 import android.content.ActivityNotFoundException;
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
+import android.os.Handler;
 import android.os.Parcelable;
 import android.util.Log;
 import android.view.View;
@@ -123,6 +124,9 @@
          */
         void setUiSurface(String uiSurface);
 
+        /** Set background handler to make binder calls. */
+        void setBgHandler(Handler bgHandler);
+
         /**
          * Range [0.0 - 1.0] when transitioning from Lockscreen to/from AOD
          */
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
index 7cf56aa..abb721a 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
@@ -84,14 +84,17 @@
      * Similar to {@link #startPendingIntentMaybeDismissingKeyguard(PendingIntent, Runnable,
      * ActivityTransitionAnimator.Controller)}, but also specifies a fill-in intent and extra
      * option that could be used to populate the pending intent and launch the activity. This also
-     * allows the caller to avoid dismissing the shade.
+     * allows the caller to avoid dismissing the shade. An optional custom message can be set as
+     * the unlock reason in the alternate bouncer.
      */
     void startPendingIntentMaybeDismissingKeyguard(PendingIntent intent,
             boolean dismissShade,
             @Nullable Runnable intentSentUiThreadCallback,
             @Nullable ActivityTransitionAnimator.Controller animationController,
             @Nullable Intent fillInIntent,
-            @Nullable Bundle extraOptions);
+            @Nullable Bundle extraOptions,
+            @Nullable String customMessage
+        );
 
     /**
      * The intent flag can be specified in startActivity().
@@ -134,14 +137,20 @@
     void dismissKeyguardThenExecute(OnDismissAction action, @Nullable Runnable cancel,
             boolean afterKeyguardGone);
 
-    /** Authenticates if needed and dismisses keyguard to execute an action. */
+    /**
+     * Authenticates if needed and dismisses keyguard to execute an action.
+     *
+     * TODO(b/348431835) Display the custom message in the new alternate bouncer, when the
+     * device_entry_udfps_refactor flag is enabled.
+     */
     void dismissKeyguardThenExecute(OnDismissAction action, @Nullable Runnable cancel,
             boolean afterKeyguardGone, @Nullable String customMessage);
 
     /** Starts an activity and dismisses keyguard. */
     void startActivityDismissingKeyguard(Intent intent,
             boolean onlyProvisioned,
-            boolean dismissShade);
+            boolean dismissShade,
+            @Nullable String customMessage);
 
     /** Starts an activity and dismisses keyguard. */
     void startActivityDismissingKeyguard(Intent intent,
diff --git a/packages/SystemUI/res-keyguard/layout/alternate_bouncer.xml b/packages/SystemUI/res-keyguard/layout/alternate_bouncer.xml
index cf9ca15..c9850f2 100644
--- a/packages/SystemUI/res-keyguard/layout/alternate_bouncer.xml
+++ b/packages/SystemUI/res-keyguard/layout/alternate_bouncer.xml
@@ -19,8 +19,6 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:sysui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/alternate_bouncer"
-    android:focusable="true"
-    android:clickable="true"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index 186bd7c..ba0d7de 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -175,4 +175,6 @@
     <dimen name="sfps_progress_bar_padding_from_edge">7dp</dimen>
 
     <dimen name="keyguard_presentation_width">410dp</dimen>
+
+    <dimen name="appclips_backlinks_icon_size">24dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res-product/values-fa/strings.xml b/packages/SystemUI/res-product/values-fa/strings.xml
index 30121cc..40f8d0d 100644
--- a/packages/SystemUI/res-product/values-fa/strings.xml
+++ b/packages/SystemUI/res-product/values-fa/strings.xml
@@ -43,18 +43,18 @@
     <string name="thermal_shutdown_title" product="default" msgid="8039593017174903505">"تلفن به‌علت گرم شدن خاموش شد"</string>
     <string name="thermal_shutdown_title" product="device" msgid="2954206342842856379">"دستگاه به‌علت گرم شدن خاموش شد"</string>
     <string name="thermal_shutdown_title" product="tablet" msgid="8941033526856177533">"رایانه لوحی به‌علت گرم شدن خاموش شد"</string>
-    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"اکنون عملکرد تلفنتان به حالت عادی برگشته است.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
-    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"اکنون عملکرد دستگاهتان به حالت عادی برگشته است.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
-    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"اکنون عملکرد رایانه لوحی‌تان به حالت عادی برگشته است.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
+    <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"اکنون عملکرد تلفنتان به حالت عادی برگشته است.\nبرای اطلاعات بیشتر تک‌ضرب بزنید"</string>
+    <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"اکنون عملکرد دستگاهتان به حالت عادی برگشته است.\nبرای اطلاعات بیشتر تک‌ضرب بزنید"</string>
+    <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"اکنون عملکرد رایانه لوحی‌تان به حالت عادی برگشته است.\nبرای اطلاعات بیشتر تک‌ضرب بزنید"</string>
     <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"تلفنتان خیلی گرم شده بود، بنابراین خاموش شد تا خنک شود. اکنون تلفنتان عملکرد معمولش را دارد.\n\nتلفنتان ممکن است خیلی گرم شود، اگر:\n	• از برنامه‌های نیازمند پردازش زیاد (مثل بازی، ویدیو، یا برنامه‌های ناوبری) استفاده کنید\n	• فایل‌های بزرگ بارگیری یا بارگذاری کنید\n	• در دماهای بالا از تلفنتان استفاده کنید"</string>
     <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"دستگاهتان خیلی گرم شده بود، بنابراین خاموش شد تا خنک شود. اکنون دستگاهتان عملکرد معمولش را دارد.\n\nدستگاهتان ممکن است خیلی گرم شود، اگر:\n	• از برنامه‌های نیازمند پردازش زیاد (مثل بازی، ویدیو، یا برنامه‌های ناوبری) استفاده کنید\n	• فایل‌های بزرگ بارگیری یا بارگذاری کنید\n	• در دماهای بالا از دستگاهتان استفاده کنید"</string>
     <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"رایانه لوحی‌تان خیلی گرم شده بود، بنابراین خاموش شد تا خنک شود. اکنون رایانه لوحی‌تان عملکرد معمولش را دارد.\n\nرایانه لوحی‌تان ممکن است خیلی گرم شود، اگر:\n	• از برنامه‌های نیازمند پردازش زیاد (مثل بازی، ویدیو، یا برنامه‌های ناوبری) استفاده کنید\n	• فایل‌های بزرگ بارگیری یا بارگذاری کنید\n	• در دماهای بالا از رایانه لوحی‌تان استفاده کنید"</string>
     <string name="high_temp_title" product="default" msgid="5365000411304924115">"تلفن درحال گرم شدن است"</string>
     <string name="high_temp_title" product="device" msgid="6622009907401563664">"دستگاه درحال گرم شدن است"</string>
     <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"رایانه لوحی درحال گرم شدن است"</string>
-    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"وقتی تلفن درحال خنک شدن است، بعضی‌از ویژگی‌ها محدود می‌شوند.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
-    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"وقتی دستگاه درحال خنک شدن است، بعضی‌از ویژگی‌ها محدود می‌شوند.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
-    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"وقتی رایانه لوحی درحال خنک شدن است، بعضی‌از ویژگی‌ها محدود می‌شوند.\nبرای اطلاعات بیشتر ضربه بزنید"</string>
+    <string name="high_temp_notif_message" product="default" msgid="3928947950087257452">"وقتی تلفن درحال خنک شدن است، بعضی‌از ویژگی‌ها محدود می‌شوند.\nبرای اطلاعات بیشتر تک‌ضرب بزنید"</string>
+    <string name="high_temp_notif_message" product="device" msgid="6105125771372547292">"وقتی دستگاه درحال خنک شدن است، بعضی‌از ویژگی‌ها محدود می‌شوند.\nبرای اطلاعات بیشتر تک‌ضرب بزنید"</string>
+    <string name="high_temp_notif_message" product="tablet" msgid="7799279192797476850">"وقتی رایانه لوحی درحال خنک شدن است، بعضی‌از ویژگی‌ها محدود می‌شوند.\nبرای اطلاعات بیشتر تک‌ضرب بزنید"</string>
     <string name="high_temp_dialog_message" product="default" msgid="4272882413847595625">"تلفنتان به‌طور خودکار سعی می‌کند خنک شود. همچنان می‌توانید از تلفنتان استفاده کنید، اما ممکن است کندتر عمل کند.\n\nوقتی تلفن خنک شد، عملکرد عادی‌اش از سرگرفته می‌شود."</string>
     <string name="high_temp_dialog_message" product="device" msgid="263861943935989046">"دستگاهتان به‌طور خودکار سعی می‌کند خنک شود. همچنان می‌توانید از دستگاهتان استفاده کنید، اما ممکن است کندتر عمل کند.\n\nوقتی دستگاه خنک شد، عملکرد عادی‌اش از سرگرفته می‌شود."</string>
     <string name="high_temp_dialog_message" product="tablet" msgid="5613713326841935537">"رایانه لوحی‌تان به‌طور خودکار سعی می‌کند خنک شود. همچنان می‌توانید از رایانه لوحی‌تان استفاده کنید، اما ممکن است کندتر عمل کند.\n\nوقتی رایانه لوحی خنک شد، عملکرد عادی‌اش از سرگرفته می‌شود."</string>
diff --git a/packages/SystemUI/res-product/values-fr-rCA/strings.xml b/packages/SystemUI/res-product/values-fr-rCA/strings.xml
index 1b6c6099..15d3606 100644
--- a/packages/SystemUI/res-product/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res-product/values-fr-rCA/strings.xml
@@ -46,9 +46,9 @@
     <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"Votre téléphone fonctionne normalement maintenant.\nTouchez pour en savoir plus"</string>
     <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"Votre appareil fonctionne normalement maintenant.\nTouchez pour en savoir plus"</string>
     <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"Votre tablette fonctionne normalement maintenant.\nTouchez pour en savoir plus."</string>
-    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Votre téléphone surchauffait et s\'est éteint afin de se refroidir. Il fonctionne normalement maintenant.\n\nIl peut surchauffer si vous :\n	• utilisez. des applications qui utilisent beaucoup de ressources (jeux, vidéo, navigation, etc.)\n	• téléchargez ou téléversez des fichiers lourds \n	• si vous l\'utilisez lors de températures élevées."</string>
-    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Votre téléphone surchauffait et s\'est éteint afin de se refroidir. Il fonctionne normalement maintenant.\n\nIl peut surchauffer si vous :\n	• utilisez. des applications qui utilisent beaucoup de ressources (jeux, vidéo, navigation, etc.)\n	• téléchargez ou téléversez des fichiers lourds \n	• ou si vous l\'utilisez lors de températures élevées."</string>
-    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Votre tablette surchauffait et s\'est éteinte afin de se refroidir. Elle fonctionne normalement maintenant.\n\nElle peut surchauffer si vous :\n	• utilisez. des applications qui utilisent beaucoup de ressources (jeux, vidéo, navigation, etc.)\n	• téléchargez ou téléversez des fichiers lourds \n	• si vous l\'utilisez lors de températures élevées."</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"Votre téléphone surchauffait et s\'est éteint afin de se refroidir. Il fonctionne normalement maintenant.\n\nIl peut surchauffer si vous :\n	• utilisez. des applis qui utilisent beaucoup de ressources (jeux, vidéo, navigation, etc.)\n	• téléchargez ou téléversez des fichiers lourds \n	• si vous l\'utilisez lors de températures élevées."</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"Votre téléphone surchauffait et s\'est éteint afin de se refroidir. Il fonctionne normalement maintenant.\n\nIl peut surchauffer si vous :\n	• utilisez. des applis qui utilisent beaucoup de ressources (jeux, vidéo, navigation, etc.)\n	• téléchargez ou téléversez des fichiers lourds \n	• ou si vous l\'utilisez lors de températures élevées."</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"Votre tablette surchauffait et s\'est éteinte afin de se refroidir. Elle fonctionne normalement maintenant.\n\nElle peut surchauffer si vous :\n	• utilisez. des applis qui utilisent beaucoup de ressources (jeux, vidéo, navigation, etc.)\n	• téléchargez ou téléversez des fichiers lourds \n	• si vous l\'utilisez lors de températures élevées."</string>
     <string name="high_temp_title" product="default" msgid="5365000411304924115">"Le téléphone surchauffe"</string>
     <string name="high_temp_title" product="device" msgid="6622009907401563664">"L\'appareil surchauffe"</string>
     <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"La tablette surchauffe"</string>
diff --git a/packages/SystemUI/res/color/connected_network_primary_color.xml b/packages/SystemUI/res/color/connected_network_primary_color.xml
new file mode 100644
index 0000000..f173c8d
--- /dev/null
+++ b/packages/SystemUI/res/color/connected_network_primary_color.xml
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+    <item android:color="?androidprv:attr/materialColorOnPrimaryContainer" />
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/backlinks_rounded_rectangle.xml b/packages/SystemUI/res/drawable/backlinks_rounded_rectangle.xml
new file mode 100644
index 0000000..225f7bd
--- /dev/null
+++ b/packages/SystemUI/res/drawable/backlinks_rounded_rectangle.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:insetBottom="4dp"
+    android:insetTop="4dp">
+    <shape android:shape="rectangle">
+        <corners android:radius="8dp" />
+        <solid android:color="@android:color/system_surface_container_highest_light" />
+    </shape>
+</inset>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/face_dialog_dark_to_checkmark.xml b/packages/SystemUI/res/drawable/face_dialog_dark_to_checkmark.xml
deleted file mode 100644
index fb30249..0000000
--- a/packages/SystemUI/res/drawable/face_dialog_dark_to_checkmark.xml
+++ /dev/null
@@ -1,637 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-  ~ Copyright (C) 2018 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT 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">
-    <aapt:attr name="android:drawable">
-        <vector
-            android:width="60dp"
-            android:height="60dp"
-            android:viewportWidth="60"
-            android:viewportHeight="60">
-            <group android:name="_R_G">
-                <group
-                    android:name="_R_G_L_0_G_N_2_T_0"
-                    android:translateX="30"
-                    android:translateY="30">
-                    <group
-                        android:name="_R_G_L_0_G"
-                        android:translateX="-30"
-                        android:translateY="-30">
-                        <group
-                            android:name="_R_G_L_0_G_D_0_P_0_G_0_T_0"
-                            android:scaleX="0.08"
-                            android:scaleY="0.08"
-                            android:translateX="30.1"
-                            android:translateY="30.083">
-                            <path
-                                android:name="_R_G_L_0_G_D_0_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="@color/biometric_dialog_face_checkmark"
-                                android:fillType="nonZero"
-                                android:pathData=" M-116 -16.5 C-116,-16.5 -31.25,68.5 -31.25,68.5 C-31.25,68.5 108.75,-71.5 108.75,-71.5 "
-                                android:trimPathStart="0"
-                                android:trimPathEnd="0"
-                                android:trimPathOffset="0" />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_D_1_P_0_G_0_T_0"
-                            android:scaleX="0.08"
-                            android:scaleY="0.08"
-                            android:translateX="30.1"
-                            android:translateY="30.083">
-                            <path
-                                android:name="_R_G_L_0_G_D_1_P_0"
-                                android:pathData=" M-116 -16.5 C-116,-16.5 -31.25,68.5 -31.25,68.5 C-31.25,68.5 108.75,-71.5 108.75,-71.5 "
-                                android:strokeWidth="20"
-                                android:strokeAlpha="1"
-                                android:strokeColor="@color/biometric_dialog_face_checkmark"
-                                android:trimPathStart="0"
-                                android:trimPathEnd="0"
-                                android:trimPathOffset="0" />
-                        </group>
-                        <path
-                            android:name="_R_G_L_0_G_D_2_P_0"
-                            android:pathData=" M30 6.2 C16.9,6.2 6.3,16.8 6.3,30 C6.3,43.2 16.9,53.8 30,53.8 C43.1,53.8 53.8,43.2 53.8,30 C53.8,16.8 43.1,6.2 30,6.2c "
-                            android:strokeWidth="2.5"
-                            android:strokeAlpha="1"
-                            android:strokeColor="@color/biometric_dialog_face_checkmark"
-                            android:trimPathStart="0"
-                            android:trimPathEnd="1"
-                            android:trimPathOffset="0" />
-                        <group
-                            android:name="_R_G_L_0_G_D_3_P_0_G_0_T_0"
-                            android:pivotX="1.05"
-                            android:pivotY="-9.891"
-                            android:scaleX="1"
-                            android:scaleY="1"
-                            android:translateX="29.044"
-                            android:translateY="41.647">
-                            <path
-                                android:name="_R_G_L_0_G_D_3_P_0"
-                                android:pathData=" M4.71 1.1 C3.71,2.12 2.32,2.75 0.79,2.75 C-2.25,2.75 -4.7,0.29 -4.7,-2.75 "
-                                android:strokeWidth="2"
-                                android:strokeAlpha="1"
-                                android:strokeColor="@color/biometric_dialog_accent"
-                                android:trimPathStart="0"
-                                android:trimPathEnd="1"
-                                android:trimPathOffset="0" />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_D_4_P_0_G_0_T_0"
-                            android:scaleX="1"
-                            android:scaleY="1"
-                            android:translateX="41.1"
-                            android:translateY="23.8">
-                            <path
-                                android:name="_R_G_L_0_G_D_4_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="@color/biometric_dialog_accent"
-                                android:fillType="nonZero"
-                                android:pathData=" M-2.1 0 C-2.1,1.2 -1.2,2.1 0,2.1 C1.1,2.1 2.1,1.2 2.1,0 C2.1,-1.2 1.2,-2.1 0,-2.1 C-1.2,-2.1 -2.1,-1.2 -2.1,0c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_D_5_P_0_G_0_T_0"
-                            android:scaleX="1"
-                            android:scaleY="1"
-                            android:translateX="18.6"
-                            android:translateY="23.8">
-                            <path
-                                android:name="_R_G_L_0_G_D_5_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="@color/biometric_dialog_accent"
-                                android:fillType="nonZero"
-                                android:pathData=" M-2.1 0 C-2.1,1.2 -1.2,2.1 0,2.1 C1.2,2.1 2.1,1.2 2.1,0 C2.1,-1.2 1.2,-2.1 0,-2.1 C-1.2,-2.1 -2.1,-1.2 -2.1,0c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_D_6_P_0_G_0_T_0"
-                            android:scaleX="1"
-                            android:scaleY="1"
-                            android:translateX="30.727"
-                            android:translateY="31.703">
-                            <path
-                                android:name="_R_G_L_0_G_D_6_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="@color/biometric_dialog_accent"
-                                android:fillType="nonZero"
-                                android:pathData=" M2.6 3.25 C2.6,3.25 -2.6,3.25 -2.6,3.25 C-2.6,3.25 -2.6,1.25 -2.6,1.25 C-2.6,1.25 0.6,1.25 0.6,1.25 C0.6,1.25 0.6,-3.25 0.6,-3.25 C0.6,-3.25 2.6,-3.25 2.6,-3.25 C2.6,-3.25 2.6,3.25 2.6,3.25c " />
-                        </group>
-                    </group>
-                </group>
-            </group>
-            <group android:name="time_group" />
-        </vector>
-    </aapt:attr>
-    <target android:name="_R_G_L_0_G_D_0_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="33"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="0.08"
-                    android:valueTo="0.08"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.537,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="33"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="0.08"
-                    android:valueTo="0.08"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.537,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="scaleX"
-                    android:startOffset="33"
-                    android:valueFrom="0.08"
-                    android:valueTo="0.12789"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.537,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="scaleY"
-                    android:startOffset="33"
-                    android:valueFrom="0.08"
-                    android:valueTo="0.12789"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.537,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="scaleX"
-                    android:startOffset="200"
-                    android:valueFrom="0.12789"
-                    android:valueTo="0.12241"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.441,0 0.533,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="scaleY"
-                    android:startOffset="200"
-                    android:valueFrom="0.12789"
-                    android:valueTo="0.12241"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.441,0 0.533,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="67"
-                    android:propertyName="scaleX"
-                    android:startOffset="300"
-                    android:valueFrom="0.12241"
-                    android:valueTo="0.125"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.424,0 0.486,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="67"
-                    android:propertyName="scaleY"
-                    android:startOffset="300"
-                    android:valueFrom="0.12241"
-                    android:valueTo="0.125"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.424,0 0.486,1 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="33"
-                    android:propertyName="trimPathEnd"
-                    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.292,0 0.155,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="trimPathEnd"
-                    android:startOffset="33"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.292,0 0.155,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_1_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="33"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="0.08"
-                    android:valueTo="0.08"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.537,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="33"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="0.08"
-                    android:valueTo="0.08"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.537,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="scaleX"
-                    android:startOffset="33"
-                    android:valueFrom="0.08"
-                    android:valueTo="0.12789"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.537,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="scaleY"
-                    android:startOffset="33"
-                    android:valueFrom="0.08"
-                    android:valueTo="0.12789"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.537,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="scaleX"
-                    android:startOffset="200"
-                    android:valueFrom="0.12789"
-                    android:valueTo="0.12241"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.441,0 0.533,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="scaleY"
-                    android:startOffset="200"
-                    android:valueFrom="0.12789"
-                    android:valueTo="0.12241"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.441,0 0.533,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="67"
-                    android:propertyName="scaleX"
-                    android:startOffset="300"
-                    android:valueFrom="0.12241"
-                    android:valueTo="0.125"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.424,0 0.486,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="67"
-                    android:propertyName="scaleY"
-                    android:startOffset="300"
-                    android:valueFrom="0.12241"
-                    android:valueTo="0.125"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.424,0 0.486,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="33"
-                    android:propertyName="trimPathEnd"
-                    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.292,0 0.155,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="trimPathEnd"
-                    android:startOffset="33"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.292,0 0.155,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="67"
-                    android:propertyName="strokeColor"
-                    android:startOffset="0"
-                    android:valueFrom="@color/biometric_dialog_accent"
-                    android:valueTo="@color/biometric_dialog_face_checkmark"
-                    android:valueType="colorType">
-                    <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="strokeColor"
-                    android:startOffset="67"
-                    android:valueFrom="@color/biometric_dialog_accent"
-                    android:valueTo="@color/biometric_dialog_face_checkmark"
-                    android:valueType="colorType">
-                    <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_3_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="50"
-                    android:propertyName="strokeAlpha"
-                    android:startOffset="0"
-                    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_3_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="67"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0.65"
-                    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>
-                <objectAnimator
-                    android:duration="67"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0.65"
-                    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="_R_G_L_0_G_D_3_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="83"
-                    android:propertyName="trimPathStart"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="0.5"
-                    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="_R_G_L_0_G_D_3_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="83"
-                    android:propertyName="trimPathEnd"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0.5"
-                    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="_R_G_L_0_G_D_4_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="50"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="0"
-                    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_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="83"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    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>
-                <objectAnimator
-                    android:duration="83"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    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="_R_G_L_0_G_D_5_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="50"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="0"
-                    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_5_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="83"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    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>
-                <objectAnimator
-                    android:duration="83"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    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="_R_G_L_0_G_D_6_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="50"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="0"
-                    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_6_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="83"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.287,0.12 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="83"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.287,0.12 0.667,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="383"
-                    android:propertyName="translateX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-</animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/face_dialog_dark_to_error.xml b/packages/SystemUI/res/drawable/face_dialog_dark_to_error.xml
deleted file mode 100644
index 0c05019..0000000
--- a/packages/SystemUI/res/drawable/face_dialog_dark_to_error.xml
+++ /dev/null
@@ -1,473 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-  ~ Copyright (C) 2018 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT 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">
-    <aapt:attr name="android:drawable">
-        <vector
-            android:width="60dp"
-            android:height="60dp"
-            android:viewportWidth="60"
-            android:viewportHeight="60">
-            <group android:name="_R_G">
-                <group
-                    android:name="_R_G_L_0_G_N_1_T_0"
-                    android:translateX="30"
-                    android:translateY="30">
-                    <group
-                        android:name="_R_G_L_0_G"
-                        android:translateX="-30"
-                        android:translateY="-30">
-                        <path
-                            android:name="_R_G_L_0_G_D_0_P_0"
-                            android:pathData=" M30 6.2 C16.9,6.2 6.3,16.8 6.3,30 C6.3,43.2 16.9,53.8 30,53.8 C43.1,53.8 53.8,43.2 53.8,30 C53.8,16.8 43.1,6.2 30,6.2c "
-                            android:strokeWidth="2.5"
-                            android:strokeAlpha="1"
-                            android:strokeColor="@color/biometric_dialog_gray"
-                            android:trimPathStart="0"
-                            android:trimPathEnd="1"
-                            android:trimPathOffset="0" />
-                        <path
-                            android:name="_R_G_L_0_G_D_1_P_0"
-                            android:pathData=" M33.75 42.75 C32.75,43.76 31.37,44.39 29.83,44.39 C26.8,44.39 24.34,41.93 24.34,38.9 "
-                            android:strokeWidth="2"
-                            android:strokeAlpha="1"
-                            android:strokeColor="@color/biometric_dialog_gray"
-                            android:trimPathStart="0"
-                            android:trimPathEnd="1"
-                            android:trimPathOffset="0" />
-                        <group
-                            android:name="_R_G_L_0_G_D_2_P_0_G_0_T_0"
-                            android:scaleX="1"
-                            android:scaleY="1"
-                            android:translateX="41.1"
-                            android:translateY="23.8">
-                            <path
-                                android:name="_R_G_L_0_G_D_2_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="@color/biometric_dialog_gray"
-                                android:fillType="nonZero"
-                                android:pathData=" M-2.1 0 C-2.1,1.2 -1.2,2.1 0,2.1 C1.1,2.1 2.1,1.2 2.1,0 C2.1,-1.2 1.2,-2.1 0,-2.1 C-1.2,-2.1 -2.1,-1.2 -2.1,0c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_D_3_P_0_G_0_T_0"
-                            android:scaleX="1"
-                            android:scaleY="1"
-                            android:translateX="18.6"
-                            android:translateY="23.8">
-                            <path
-                                android:name="_R_G_L_0_G_D_3_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="@color/biometric_dialog_gray"
-                                android:fillType="nonZero"
-                                android:pathData=" M-2.1 0 C-2.1,1.2 -1.2,2.1 0,2.1 C1.2,2.1 2.1,1.2 2.1,0 C2.1,-1.2 1.2,-2.1 0,-2.1 C-1.2,-2.1 -2.1,-1.2 -2.1,0c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_D_4_P_0_G_0_T_0"
-                            android:translateX="30.3"
-                            android:translateY="31.45">
-                            <path
-                                android:name="_R_G_L_0_G_D_4_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="@color/biometric_dialog_gray"
-                                android:fillType="nonZero"
-                                android:pathData=" M2.6 3.25 C2.6,3.25 -2.6,3.25 -2.6,3.25 C-2.6,3.25 -2.6,1.25 -2.6,1.25 C-2.6,1.25 0.6,1.25 0.6,1.25 C0.6,1.25 0.6,-3.25 0.6,-3.25 C0.6,-3.25 2.6,-3.25 2.6,-3.25 C2.6,-3.25 2.6,3.25 2.6,3.25c " />
-                        </group>
-                    </group>
-                </group>
-            </group>
-            <group android:name="time_group" />
-        </vector>
-    </aapt:attr>
-    <target android:name="_R_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="50"
-                    android:propertyName="strokeColor"
-                    android:startOffset="0"
-                    android:valueFrom="@color/biometric_dialog_gray"
-                    android:valueTo="@color/biometric_dialog_gray"
-                    android:valueType="colorType">
-                    <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="strokeColor"
-                    android:startOffset="50"
-                    android:valueFrom="@color/biometric_dialog_gray"
-                    android:valueTo="@color/biometric_dialog_error"
-                    android:valueType="colorType">
-                    <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="50"
-                    android:propertyName="strokeColor"
-                    android:startOffset="0"
-                    android:valueFrom="@color/biometric_dialog_gray"
-                    android:valueTo="@color/biometric_dialog_gray"
-                    android:valueType="colorType">
-                    <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="strokeColor"
-                    android:startOffset="50"
-                    android:valueFrom="@color/biometric_dialog_gray"
-                    android:valueTo="@color/biometric_dialog_error"
-                    android:valueType="colorType">
-                    <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="217"
-                    android:propertyName="strokeWidth"
-                    android:startOffset="0"
-                    android:valueFrom="2"
-                    android:valueTo="2.5"
-                    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="_R_G_L_0_G_D_1_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="pathData"
-                    android:startOffset="0"
-                    android:valueFrom="M33.75 42.75 C32.75,43.76 31.37,44.39 29.83,44.39 C26.8,44.39 24.34,41.93 24.34,38.9 "
-                    android:valueTo="M34.78 38.76 C33.83,38.75 31.54,38.75 30.01,38.75 C26.97,38.75 26.14,38.75 24.3,38.76 "
-                    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="_R_G_L_0_G_D_1_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="trimPathStart"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="0.34"
-                    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="_R_G_L_0_G_D_1_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="trimPathEnd"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0.5700000000000001"
-                    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="_R_G_L_0_G_D_2_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="50"
-                    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="50"
-                    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_2_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="67"
-                    android:pathData="M 41.1,23.8C 40.547981774806985,23.08834635019302 38.34001822519301,20.24165364980698 37.788,19.53"
-                    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.4,0 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_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="67"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0.3"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.999,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="67"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0.3"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.999,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="50"
-                    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="50"
-                    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_3_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="67"
-                    android:pathData="M 18.6,23.8C 19.16757813692093,23.08502601385117 21.43742186307907,20.224973986148832 22.005,19.51"
-                    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.4,0 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_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="67"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0.3"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.999,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="67"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0.3"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.999,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="50"
-                    android:propertyName="fillColor"
-                    android:startOffset="0"
-                    android:valueFrom="@color/biometric_dialog_gray"
-                    android:valueTo="@color/biometric_dialog_gray"
-                    android:valueType="colorType">
-                    <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="fillColor"
-                    android:startOffset="50"
-                    android:valueFrom="@color/biometric_dialog_gray"
-                    android:valueTo="@color/biometric_dialog_error"
-                    android:valueType="colorType">
-                    <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_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="67"
-                    android:pathData="M 30.3,31.45C 30.3,31.07740886211395 30.3,31.82259113788605 30.3,31.45"
-                    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.4,0 0.2,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="150"
-                    android:pathData="M 30.3,31.45C 30.3,31.07740886211395 30.3,29.58759113788605 30.3,29.215"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="67">
-                    <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="_R_G_L_0_G_D_4_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="67"
-                    android:propertyName="pathData"
-                    android:startOffset="0"
-                    android:valueFrom="M2.6 3.25 C2.6,3.25 -2.6,3.25 -2.6,3.25 C-2.6,3.25 -2.6,1.25 -2.6,1.25 C-2.6,1.25 0.6,1.25 0.6,1.25 C0.6,1.25 0.6,-3.25 0.6,-3.25 C0.6,-3.25 2.6,-3.25 2.6,-3.25 C2.6,-3.25 2.6,3.25 2.6,3.25c "
-                    android:valueTo="M0.9 3.25 C0.9,3.25 -1.5,3.25 -1.5,3.25 C-1.5,3.25 -1.5,1.25 -1.5,1.25 C-1.5,1.25 -1.5,1.25 -1.5,1.25 C-1.5,1.25 -1.5,-3.25 -1.5,-3.25 C-1.5,-3.25 0.9,-3.25 0.9,-3.25 C0.9,-3.25 0.9,3.25 0.9,3.25c "
-                    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>
-                <objectAnimator
-                    android:duration="150"
-                    android:propertyName="pathData"
-                    android:startOffset="67"
-                    android:valueFrom="M0.9 3.25 C0.9,3.25 -1.5,3.25 -1.5,3.25 C-1.5,3.25 -1.5,1.25 -1.5,1.25 C-1.5,1.25 -1.5,1.25 -1.5,1.25 C-1.5,1.25 -1.5,-3.25 -1.5,-3.25 C-1.5,-3.25 0.9,-3.25 0.9,-3.25 C0.9,-3.25 0.9,3.25 0.9,3.25c "
-                    android:valueTo="M0.9 3.25 C0.9,3.25 -1.5,3.25 -1.5,3.25 C-1.5,3.25 -1.5,1.25 -1.5,1.25 C-1.5,1.25 -1.5,1.25 -1.5,1.25 C-1.5,1.25 -1.5,-13.15 -1.5,-13.15 C-1.5,-13.15 0.9,-13.15 0.9,-13.15 C0.9,-13.15 0.9,3.25 0.9,3.25c "
-                    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>
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="pathData"
-                    android:startOffset="217"
-                    android:valueFrom="M0.9 3.25 C0.9,3.25 -1.5,3.25 -1.5,3.25 C-1.5,3.25 -1.5,1.25 -1.5,1.25 C-1.5,1.25 -1.5,1.25 -1.5,1.25 C-1.5,1.25 -1.5,-13.15 -1.5,-13.15 C-1.5,-13.15 0.9,-13.15 0.9,-13.15 C0.9,-13.15 0.9,3.25 0.9,3.25c "
-                    android:valueTo="M0.9 3.25 C0.9,3.25 -1.5,3.25 -1.5,3.25 C-1.5,3.25 -1.5,1.25 -1.5,1.25 C-1.5,1.25 -1.5,1.25 -1.5,1.25 C-1.5,1.25 -1.5,-11.71 -1.5,-11.71 C-1.5,-11.71 0.9,-11.71 0.9,-11.71 C0.9,-11.71 0.9,3.25 0.9,3.25c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.667,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="333"
-                    android:propertyName="translateX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-</animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/face_dialog_error_to_idle.xml b/packages/SystemUI/res/drawable/face_dialog_error_to_idle.xml
deleted file mode 100644
index d3cee25..0000000
--- a/packages/SystemUI/res/drawable/face_dialog_error_to_idle.xml
+++ /dev/null
@@ -1,509 +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
-  -->
-
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:aapt="http://schemas.android.com/aapt">
-    <aapt:attr name="android:drawable">
-        <vector
-            android:width="60dp"
-            android:height="60dp"
-            android:viewportWidth="60"
-            android:viewportHeight="60">
-            <group android:name="_R_G">
-                <group android:name="_R_G_L_0_G">
-                    <path
-                        android:name="_R_G_L_0_G_D_0_P_0"
-                        android:pathData=" M30 6.2 C16.9,6.2 6.3,16.8 6.3,30 C6.3,43.2 16.9,53.8 30,53.8 C43.1,53.8 53.8,43.2 53.8,30 C53.8,16.8 43.1,6.2 30,6.2c "
-                        android:strokeWidth="2.5"
-                        android:strokeAlpha="1"
-                        android:strokeColor="@color/biometric_dialog_error"
-                        android:trimPathStart="0"
-                        android:trimPathEnd="1"
-                        android:trimPathOffset="0" />
-                    <path
-                        android:name="_R_G_L_0_G_D_1_P_0"
-                        android:pathData=" M34.78 38.76 C33.83,38.75 31.54,38.75 30.01,38.75 C26.97,38.75 26.14,38.75 24.3,38.76 "
-                        android:strokeWidth="2.5"
-                        android:strokeAlpha="1"
-                        android:strokeColor="@color/biometric_dialog_error"
-                        android:trimPathStart="0.34"
-                        android:trimPathEnd="0.5700000000000001"
-                        android:trimPathOffset="0" />
-                    <group
-                        android:name="_R_G_L_0_G_D_2_P_0_G_0_T_0"
-                        android:scaleX="0.3"
-                        android:scaleY="0.3"
-                        android:translateX="37.788"
-                        android:translateY="19.53">
-                        <path
-                            android:name="_R_G_L_0_G_D_2_P_0"
-                            android:fillAlpha="0"
-                            android:fillColor="@color/biometric_dialog_gray"
-                            android:fillType="nonZero"
-                            android:pathData=" M-2.1 0 C-2.1,1.2 -1.2,2.1 0,2.1 C1.1,2.1 2.1,1.2 2.1,0 C2.1,-1.2 1.2,-2.1 0,-2.1 C-1.2,-2.1 -2.1,-1.2 -2.1,0c " />
-                    </group>
-                    <group
-                        android:name="_R_G_L_0_G_D_3_P_0_G_0_T_0"
-                        android:scaleX="0.3"
-                        android:scaleY="0.3"
-                        android:translateX="22.005"
-                        android:translateY="19.51">
-                        <path
-                            android:name="_R_G_L_0_G_D_3_P_0"
-                            android:fillAlpha="0"
-                            android:fillColor="@color/biometric_dialog_gray"
-                            android:fillType="nonZero"
-                            android:pathData=" M-2.1 0 C-2.1,1.2 -1.2,2.1 0,2.1 C1.2,2.1 2.1,1.2 2.1,0 C2.1,-1.2 1.2,-2.1 0,-2.1 C-1.2,-2.1 -2.1,-1.2 -2.1,0c " />
-                    </group>
-                    <group
-                        android:name="_R_G_L_0_G_D_4_P_0_G_0_T_0"
-                        android:translateX="30.3"
-                        android:translateY="29.215">
-                        <path
-                            android:name="_R_G_L_0_G_D_4_P_0"
-                            android:fillAlpha="1"
-                            android:fillColor="@color/biometric_dialog_error"
-                            android:fillType="nonZero"
-                            android:pathData=" M0.9 3.25 C0.9,3.25 -1.5,3.25 -1.5,3.25 C-1.5,3.25 -1.5,1.25 -1.5,1.25 C-1.5,1.25 -1.5,1.25 -1.5,1.25 C-1.5,1.25 -1.5,-11.71 -1.5,-11.71 C-1.5,-11.71 0.9,-11.71 0.9,-11.71 C0.9,-11.71 0.9,3.25 0.9,3.25c " />
-                    </group>
-                </group>
-            </group>
-            <group android:name="time_group" />
-        </vector>
-    </aapt:attr>
-    <target android:name="_R_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="83"
-                    android:propertyName="strokeColor"
-                    android:startOffset="0"
-                    android:valueFrom="@color/biometric_dialog_error"
-                    android:valueTo="@color/biometric_dialog_error"
-                    android:valueType="colorType">
-                    <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="strokeColor"
-                    android:startOffset="83"
-                    android:valueFrom="@color/biometric_dialog_error"
-                    android:valueTo="@color/biometric_dialog_gray"
-                    android:valueType="colorType">
-                    <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="83"
-                    android:propertyName="strokeColor"
-                    android:startOffset="0"
-                    android:valueFrom="@color/biometric_dialog_error"
-                    android:valueTo="@color/biometric_dialog_error"
-                    android:valueType="colorType">
-                    <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="strokeColor"
-                    android:startOffset="83"
-                    android:valueFrom="@color/biometric_dialog_error"
-                    android:valueTo="@color/biometric_dialog_gray"
-                    android:valueType="colorType">
-                    <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="217"
-                    android:propertyName="strokeWidth"
-                    android:startOffset="0"
-                    android:valueFrom="2.5"
-                    android:valueTo="2"
-                    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="_R_G_L_0_G_D_1_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="pathData"
-                    android:startOffset="0"
-                    android:valueFrom="M34.78 38.76 C33.83,38.75 31.54,38.75 30.01,38.75 C26.97,38.75 26.14,38.75 24.3,38.76 "
-                    android:valueTo="M33.75 42.75 C32.75,43.76 31.37,44.39 29.83,44.39 C26.8,44.39 24.34,41.93 24.34,38.9 "
-                    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="_R_G_L_0_G_D_1_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="trimPathStart"
-                    android:startOffset="0"
-                    android:valueFrom="0.34"
-                    android:valueTo="0"
-                    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="_R_G_L_0_G_D_1_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="trimPathEnd"
-                    android:startOffset="0"
-                    android:valueFrom="0.5700000000000001"
-                    android:valueTo="1"
-                    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="_R_G_L_0_G_D_2_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="83"
-                    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="17"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="83"
-                    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_2_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="50"
-                    android:pathData="M 37.788,19.53C 38.3400184636116,20.241653709411622 37.235981536388394,18.81834629058838 37.788,19.53"
-                    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.4,0 0.2,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="167"
-                    android:pathData="M 37.788,19.53C 38.3400184636116,20.241653709411622 40.5479815363884,23.08834629058838 41.1,23.8"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="50">
-                    <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="_R_G_L_0_G_D_2_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="50"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="0.3"
-                    android:valueTo="0.3"
-                    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>
-                <objectAnimator
-                    android:duration="50"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="0.3"
-                    android:valueTo="0.3"
-                    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>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleX"
-                    android:startOffset="50"
-                    android:valueFrom="0.3"
-                    android:valueTo="1"
-                    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>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleY"
-                    android:startOffset="50"
-                    android:valueFrom="0.3"
-                    android:valueTo="1"
-                    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="_R_G_L_0_G_D_3_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="83"
-                    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="17"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="83"
-                    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_3_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="50"
-                    android:pathData="M 22.005,19.51C 21.43742198228836,20.224974105358122 22.57257801771164,18.79502589464188 22.005,19.51"
-                    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.4,0 0.2,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="167"
-                    android:pathData="M 22.005,19.51C 21.43742198228836,20.224974105358122 19.16757801771164,23.08502589464188 18.6,23.8"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="50">
-                    <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="_R_G_L_0_G_D_3_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="50"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="0.3"
-                    android:valueTo="0.3"
-                    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>
-                <objectAnimator
-                    android:duration="50"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="0.3"
-                    android:valueTo="0.3"
-                    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>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleX"
-                    android:startOffset="50"
-                    android:valueFrom="0.3"
-                    android:valueTo="1"
-                    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>
-                <objectAnimator
-                    android:duration="117"
-                    android:propertyName="scaleY"
-                    android:startOffset="50"
-                    android:valueFrom="0.3"
-                    android:valueTo="1"
-                    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="_R_G_L_0_G_D_4_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="83"
-                    android:propertyName="fillColor"
-                    android:startOffset="0"
-                    android:valueFrom="@color/biometric_dialog_error"
-                    android:valueTo="@color/biometric_dialog_error"
-                    android:valueType="colorType">
-                    <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="fillColor"
-                    android:startOffset="83"
-                    android:valueFrom="@color/biometric_dialog_error"
-                    android:valueTo="@color/biometric_dialog_gray"
-                    android:valueType="colorType">
-                    <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_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="150"
-                    android:pathData="M 30.3,29.215C 30.3,29.58759101867676 30.3,31.077408981323238 30.3,31.45"
-                    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.4,0 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="83"
-                    android:propertyName="pathData"
-                    android:startOffset="0"
-                    android:valueFrom="M0.9 3.25 C0.9,3.25 -1.5,3.25 -1.5,3.25 C-1.5,3.25 -1.5,1.25 -1.5,1.25 C-1.5,1.25 -1.5,1.25 -1.5,1.25 C-1.5,1.25 -1.5,-11.71 -1.5,-11.71 C-1.5,-11.71 0.9,-11.71 0.9,-11.71 C0.9,-11.71 0.9,3.25 0.9,3.25c "
-                    android:valueTo="M0.9 3.25 C0.9,3.25 -1.5,3.25 -1.5,3.25 C-1.5,3.25 -1.5,1.25 -1.5,1.25 C-1.5,1.25 -1.5,1.25 -1.5,1.25 C-1.5,1.25 -1.5,-3.25 -1.5,-3.25 C-1.5,-3.25 0.9,-3.25 0.9,-3.25 C0.9,-3.25 0.9,3.25 0.9,3.25c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.321,0 0.67,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="pathData"
-                    android:startOffset="83"
-                    android:valueFrom="M0.9 3.25 C0.9,3.25 -1.5,3.25 -1.5,3.25 C-1.5,3.25 -1.5,1.25 -1.5,1.25 C-1.5,1.25 -1.5,1.25 -1.5,1.25 C-1.5,1.25 -1.5,-3.25 -1.5,-3.25 C-1.5,-3.25 0.9,-3.25 0.9,-3.25 C0.9,-3.25 0.9,3.25 0.9,3.25c "
-                    android:valueTo="M2.6 3.25 C2.6,3.25 -2.6,3.25 -2.6,3.25 C-2.6,3.25 -2.6,1.25 -2.6,1.25 C-2.6,1.25 0.6,1.25 0.6,1.25 C0.6,1.25 0.6,-3.25 0.6,-3.25 C0.6,-3.25 2.6,-3.25 2.6,-3.25 C2.6,-3.25 2.6,3.25 2.6,3.25c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.568,0 0.456,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>
-</animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/face_dialog_idle_static.xml b/packages/SystemUI/res/drawable/face_dialog_idle_static.xml
deleted file mode 100644
index 6ad8e83..0000000
--- a/packages/SystemUI/res/drawable/face_dialog_idle_static.xml
+++ /dev/null
@@ -1,276 +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
-  -->
-
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:aapt="http://schemas.android.com/aapt">
-    <aapt:attr name="android:drawable">
-        <vector
-            android:width="60dp"
-            android:height="60dp"
-            android:viewportWidth="60"
-            android:viewportHeight="60">
-            <group android:name="_R_G">
-                <group
-                    android:name="_R_G_L_0_G"
-                    android:pivotX="30"
-                    android:pivotY="30"
-                    android:scaleX="1.03"
-                    android:scaleY="1.03">
-                    <path
-                        android:name="_R_G_L_0_G_D_0_P_0"
-                        android:pathData=" M30 6.2 C16.9,6.2 6.3,16.8 6.3,30 C6.3,43.2 16.9,53.8 30,53.8 C43.1,53.8 53.8,43.2 53.8,30 C53.8,16.8 43.1,6.2 30,6.2c "
-                        android:strokeWidth="2.5"
-                        android:strokeAlpha="1.0"
-                        android:strokeColor="@color/biometric_dialog_gray"
-                        android:trimPathStart="0"
-                        android:trimPathEnd="1"
-                        android:trimPathOffset="0" />
-                    <path
-                        android:name="_R_G_L_0_G_D_1_P_0"
-                        android:pathData=" M33.75 42.75 C32.75,43.77 31.37,44.39 29.83,44.39 C26.8,44.39 24.34,41.93 24.34,38.9 "
-                        android:strokeWidth="2"
-                        android:strokeAlpha="1.0"
-                        android:strokeColor="@color/biometric_dialog_gray"
-                        android:trimPathStart="0"
-                        android:trimPathEnd="1"
-                        android:trimPathOffset="0" />
-                    <path
-                        android:name="_R_G_L_0_G_D_2_P_0"
-                        android:fillAlpha="1.0"
-                        android:fillColor="@color/biometric_dialog_gray"
-                        android:fillType="nonZero"
-                        android:pathData=" M39 23.8 C39,25 39.9,25.9 41.1,25.9 C42.2,25.9 43.2,25 43.2,23.8 C43.2,22.6 42.3,21.7 41.1,21.7 C39.9,21.7 39,22.6 39,23.8c " />
-                    <path
-                        android:name="_R_G_L_0_G_D_3_P_0"
-                        android:fillAlpha="1.0"
-                        android:fillColor="@color/biometric_dialog_gray"
-                        android:fillType="nonZero"
-                        android:pathData=" M16.5 23.8 C16.5,25 17.4,25.9 18.6,25.9 C19.8,25.9 20.7,25 20.7,23.8 C20.7,22.6 19.8,21.7 18.6,21.7 C17.4,21.7 16.5,22.6 16.5,23.8c " />
-                    <path
-                        android:name="_R_G_L_0_G_D_4_P_0"
-                        android:fillAlpha="1.0"
-                        android:fillColor="@color/biometric_dialog_gray"
-                        android:fillType="nonZero"
-                        android:pathData=" M33.33 34.95 C33.33,34.95 28.13,34.95 28.13,34.95 C28.13,34.95 28.13,32.95 28.13,32.95 C28.13,32.95 31.33,32.95 31.33,32.95 C31.33,32.95 31.33,28.45 31.33,28.45 C31.33,28.45 33.33,28.45 33.33,28.45 C33.33,28.45 33.33,34.95 33.33,34.95c " />
-                </group>
-            </group>
-            <group android:name="time_group" />
-        </vector>
-    </aapt:attr>
-    <target android:name="_R_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="500"
-                    android:propertyName="strokeAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="1.0"
-                    android:valueTo="1.0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.118,1.266 0.419,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="500"
-                    android:propertyName="strokeAlpha"
-                    android:startOffset="500"
-                    android:valueFrom="1.0"
-                    android:valueTo="1.0"
-                    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="_R_G_L_0_G_D_1_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="500"
-                    android:propertyName="strokeAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="1.0"
-                    android:valueTo="1.0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.118,1.266 0.419,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="500"
-                    android:propertyName="strokeAlpha"
-                    android:startOffset="500"
-                    android:valueFrom="1.0"
-                    android:valueTo="1.0"
-                    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="_R_G_L_0_G_D_2_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="500"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="1.0"
-                    android:valueTo="1.0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.118,1.266 0.419,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="500"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="500"
-                    android:valueFrom="1.0"
-                    android:valueTo="1.0"
-                    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="_R_G_L_0_G_D_3_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="500"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="1.0"
-                    android:valueTo="1.0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.118,1.266 0.419,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="500"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="500"
-                    android:valueFrom="1.0"
-                    android:valueTo="1.0"
-                    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="_R_G_L_0_G_D_4_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="500"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="1.0"
-                    android:valueTo="1.0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.118,1.266 0.419,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="500"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="500"
-                    android:valueFrom="1.0"
-                    android:valueTo="1.0"
-                    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="_R_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="500"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="1.03"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <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="500"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="1.03"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <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="500"
-                    android:propertyName="scaleX"
-                    android:startOffset="500"
-                    android:valueFrom="1"
-                    android:valueTo="1.03"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.204,0.46 0.568,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="500"
-                    android:propertyName="scaleY"
-                    android:startOffset="500"
-                    android:valueFrom="1"
-                    android:valueTo="1.03"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.204,0.46 0.568,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="1017"
-                    android:propertyName="translateX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-</animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/face_dialog_pulse_dark_to_light.xml b/packages/SystemUI/res/drawable/face_dialog_pulse_dark_to_light.xml
deleted file mode 100644
index 427be14..0000000
--- a/packages/SystemUI/res/drawable/face_dialog_pulse_dark_to_light.xml
+++ /dev/null
@@ -1,183 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:aapt="http://schemas.android.com/aapt">
-    <aapt:attr name="android:drawable">
-        <vector
-            android:width="60dp"
-            android:height="60dp"
-            android:viewportWidth="60"
-            android:viewportHeight="60">
-            <group android:name="_R_G">
-                <group
-                    android:name="_R_G_L_0_G"
-                    android:pivotX="30"
-                    android:pivotY="30"
-                    android:scaleX="1"
-                    android:scaleY="1">
-                    <path
-                        android:name="_R_G_L_0_G_D_0_P_0"
-                        android:pathData=" M30 6.2 C16.9,6.2 6.3,16.8 6.3,30 C6.3,43.2 16.9,53.8 30,53.8 C43.1,53.8 53.8,43.2 53.8,30 C53.8,16.8 43.1,6.2 30,6.2c "
-                        android:strokeWidth="2.5"
-                        android:strokeAlpha="1"
-                        android:strokeColor="@color/biometric_dialog_accent"
-                        android:trimPathStart="0"
-                        android:trimPathEnd="1"
-                        android:trimPathOffset="0" />
-                    <path
-                        android:name="_R_G_L_0_G_D_1_P_0"
-                        android:pathData=" M33.75 42.75 C32.75,43.77 31.37,44.39 29.83,44.39 C26.8,44.39 24.34,41.93 24.34,38.9 "
-                        android:strokeWidth="2"
-                        android:strokeAlpha="1"
-                        android:strokeColor="@color/biometric_dialog_accent"
-                        android:trimPathStart="0"
-                        android:trimPathEnd="1"
-                        android:trimPathOffset="0" />
-                    <path
-                        android:name="_R_G_L_0_G_D_2_P_0"
-                        android:fillAlpha="1"
-                        android:fillColor="@color/biometric_dialog_accent"
-                        android:fillType="nonZero"
-                        android:pathData=" M39 23.8 C39,25 39.9,25.9 41.1,25.9 C42.2,25.9 43.2,25 43.2,23.8 C43.2,22.6 42.3,21.7 41.1,21.7 C39.9,21.7 39,22.6 39,23.8c " />
-                    <path
-                        android:name="_R_G_L_0_G_D_3_P_0"
-                        android:fillAlpha="1"
-                        android:fillColor="@color/biometric_dialog_accent"
-                        android:fillType="nonZero"
-                        android:pathData=" M16.5 23.8 C16.5,25 17.4,25.9 18.6,25.9 C19.8,25.9 20.7,25 20.7,23.8 C20.7,22.6 19.8,21.7 18.6,21.7 C17.4,21.7 16.5,22.6 16.5,23.8c " />
-                    <path
-                        android:name="_R_G_L_0_G_D_4_P_0"
-                        android:fillAlpha="1"
-                        android:fillColor="@color/biometric_dialog_accent"
-                        android:fillType="nonZero"
-                        android:pathData=" M33.33 34.95 C33.33,34.95 28.13,34.95 28.13,34.95 C28.13,34.95 28.13,32.95 28.13,32.95 C28.13,32.95 31.33,32.95 31.33,32.95 C31.33,32.95 31.33,28.45 31.33,28.45 C31.33,28.45 33.33,28.45 33.33,28.45 C33.33,28.45 33.33,34.95 33.33,34.95c " />
-                </group>
-            </group>
-            <group android:name="time_group" />
-        </vector>
-    </aapt:attr>
-    <target android:name="_R_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="strokeAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0.5"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.317,0 0.287,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="333"
-                    android:propertyName="strokeAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0.5"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.317,0 0.287,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="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0.5"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.317,0 0.287,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="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0.5"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.317,0 0.287,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="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0.5"
-                    android:valueType="floatType">
-                    <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>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="1.03"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.317,0 0.287,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="1.03"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.317,0 0.287,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>
-</animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/face_dialog_pulse_light_to_dark.xml b/packages/SystemUI/res/drawable/face_dialog_pulse_light_to_dark.xml
deleted file mode 100644
index ab26408..0000000
--- a/packages/SystemUI/res/drawable/face_dialog_pulse_light_to_dark.xml
+++ /dev/null
@@ -1,183 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:aapt="http://schemas.android.com/aapt">
-    <aapt:attr name="android:drawable">
-        <vector
-            android:width="60dp"
-            android:height="60dp"
-            android:viewportWidth="60"
-            android:viewportHeight="60">
-            <group android:name="_R_G">
-                <group
-                    android:name="_R_G_L_0_G"
-                    android:pivotX="30"
-                    android:pivotY="30"
-                    android:scaleX="1.03"
-                    android:scaleY="1.03">
-                    <path
-                        android:name="_R_G_L_0_G_D_0_P_0"
-                        android:pathData=" M30 6.2 C16.9,6.2 6.3,16.8 6.3,30 C6.3,43.2 16.9,53.8 30,53.8 C43.1,53.8 53.8,43.2 53.8,30 C53.8,16.8 43.1,6.2 30,6.2c "
-                        android:strokeWidth="2.5"
-                        android:strokeAlpha="0.5"
-                        android:strokeColor="@color/biometric_dialog_accent"
-                        android:trimPathStart="0"
-                        android:trimPathEnd="1"
-                        android:trimPathOffset="0" />
-                    <path
-                        android:name="_R_G_L_0_G_D_1_P_0"
-                        android:pathData=" M33.75 42.75 C32.75,43.77 31.37,44.39 29.83,44.39 C26.8,44.39 24.34,41.93 24.34,38.9 "
-                        android:strokeWidth="2"
-                        android:strokeAlpha="0.5"
-                        android:strokeColor="@color/biometric_dialog_accent"
-                        android:trimPathStart="0"
-                        android:trimPathEnd="1"
-                        android:trimPathOffset="0" />
-                    <path
-                        android:name="_R_G_L_0_G_D_2_P_0"
-                        android:fillAlpha="0.5"
-                        android:fillColor="@color/biometric_dialog_accent"
-                        android:fillType="nonZero"
-                        android:pathData=" M39 23.8 C39,25 39.9,25.9 41.1,25.9 C42.2,25.9 43.2,25 43.2,23.8 C43.2,22.6 42.3,21.7 41.1,21.7 C39.9,21.7 39,22.6 39,23.8c " />
-                    <path
-                        android:name="_R_G_L_0_G_D_3_P_0"
-                        android:fillAlpha="0.5"
-                        android:fillColor="@color/biometric_dialog_accent"
-                        android:fillType="nonZero"
-                        android:pathData=" M16.5 23.8 C16.5,25 17.4,25.9 18.6,25.9 C19.8,25.9 20.7,25 20.7,23.8 C20.7,22.6 19.8,21.7 18.6,21.7 C17.4,21.7 16.5,22.6 16.5,23.8c " />
-                    <path
-                        android:name="_R_G_L_0_G_D_4_P_0"
-                        android:fillAlpha="0.5"
-                        android:fillColor="@color/biometric_dialog_accent"
-                        android:fillType="nonZero"
-                        android:pathData=" M33.33 34.95 C33.33,34.95 28.13,34.95 28.13,34.95 C28.13,34.95 28.13,32.95 28.13,32.95 C28.13,32.95 31.33,32.95 31.33,32.95 C31.33,32.95 31.33,28.45 31.33,28.45 C31.33,28.45 33.33,28.45 33.33,28.45 C33.33,28.45 33.33,34.95 33.33,34.95c " />
-                </group>
-            </group>
-            <group android:name="time_group" />
-        </vector>
-    </aapt:attr>
-    <target android:name="_R_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="strokeAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="0.5"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.317,0 0.287,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="333"
-                    android:propertyName="strokeAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="0.5"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.317,0 0.287,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="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="0.5"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.317,0 0.287,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="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="0.5"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.317,0 0.287,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="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="0.5"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <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>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="1.03"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.317,0 0.287,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="1.03"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.317,0 0.287,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>
-</animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/face_dialog_wink_from_dark.xml b/packages/SystemUI/res/drawable/face_dialog_wink_from_dark.xml
deleted file mode 100644
index 0cd542d..0000000
--- a/packages/SystemUI/res/drawable/face_dialog_wink_from_dark.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:aapt="http://schemas.android.com/aapt">
-    <aapt:attr name="android:drawable">
-        <vector
-            android:width="60dp"
-            android:height="60dp"
-            android:viewportWidth="60"
-            android:viewportHeight="60">
-            <group android:name="_R_G">
-                <group android:name="_R_G_L_1_G">
-                    <path
-                        android:name="_R_G_L_1_G_D_0_P_0"
-                        android:pathData=" M30 6.2 C16.9,6.2 6.3,16.8 6.3,30 C6.3,43.2 16.9,53.8 30,53.8 C43.1,53.8 53.8,43.2 53.8,30 C53.8,16.8 43.1,6.2 30,6.2c "
-                        android:strokeWidth="2.5"
-                        android:strokeAlpha="1"
-                        android:strokeColor="@color/biometric_dialog_accent"
-                        android:trimPathStart="0"
-                        android:trimPathEnd="1"
-                        android:trimPathOffset="0" />
-                </group>
-                <group
-                    android:name="_R_G_L_0_G"
-                    android:pivotX="30"
-                    android:pivotY="30"
-                    android:rotation="0"
-                    android:scaleX="1"
-                    android:scaleY="1">
-                    <path
-                        android:name="_R_G_L_0_G_D_0_P_0"
-                        android:pathData=" M33.75 42.75 C32.75,43.77 31.37,44.39 29.83,44.39 C26.8,44.39 24.34,41.93 24.34,38.9 "
-                        android:strokeWidth="2"
-                        android:strokeAlpha="1"
-                        android:strokeColor="@color/biometric_dialog_accent"
-                        android:trimPathStart="0"
-                        android:trimPathEnd="1"
-                        android:trimPathOffset="0" />
-                    <path
-                        android:name="_R_G_L_0_G_D_1_P_0"
-                        android:fillAlpha="1"
-                        android:fillColor="@color/biometric_dialog_accent"
-                        android:fillType="nonZero"
-                        android:pathData=" M39 23.8 C39,25 39.9,25.9 41.1,25.9 C42.2,25.9 43.2,25 43.2,23.8 C43.2,22.6 42.3,21.7 41.1,21.7 C39.9,21.7 39,22.6 39,23.8c " />
-                    <group
-                        android:name="_R_G_L_0_G_D_2_P_0_G_0_T_0"
-                        android:scaleX="1"
-                        android:scaleY="1"
-                        android:translateX="18.6"
-                        android:translateY="23.8">
-                        <path
-                            android:name="_R_G_L_0_G_D_2_P_0"
-                            android:fillAlpha="1"
-                            android:fillColor="@color/biometric_dialog_accent"
-                            android:fillType="nonZero"
-                            android:pathData=" M-2.1 0 C-2.1,1.2 -1.2,2.1 0,2.1 C1.2,2.1 2.1,1.2 2.1,0 C2.1,-1.2 1.2,-2.1 0,-2.1 C-1.2,-2.1 -2.1,-1.2 -2.1,0c " />
-                    </group>
-                    <path
-                        android:name="_R_G_L_0_G_D_3_P_0"
-                        android:fillAlpha="1"
-                        android:fillColor="@color/biometric_dialog_accent"
-                        android:fillType="nonZero"
-                        android:pathData=" M33.33 34.95 C33.33,34.95 28.13,34.95 28.13,34.95 C28.13,34.95 28.13,32.95 28.13,32.95 C28.13,32.95 31.33,32.95 31.33,32.95 C31.33,32.95 31.33,28.45 31.33,28.45 C31.33,28.45 33.33,28.45 33.33,28.45 C33.33,28.45 33.33,34.95 33.33,34.95c " />
-                </group>
-            </group>
-            <group android:name="time_group" />
-        </vector>
-    </aapt:attr>
-    <target android:name="_R_G_L_0_G_D_2_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="433"
-                    android:propertyName="scaleX"
-                    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.4,0 0.2,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="433"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="0.26"
-                    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>
-                <objectAnimator
-                    android:duration="317"
-                    android:propertyName="scaleX"
-                    android:startOffset="433"
-                    android:valueFrom="1"
-                    android:valueTo="1"
-                    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>
-                <objectAnimator
-                    android:duration="317"
-                    android:propertyName="scaleY"
-                    android:startOffset="433"
-                    android:valueFrom="0.26"
-                    android:valueTo="1"
-                    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="_R_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="433"
-                    android:propertyName="rotation"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="-14"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.2,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="317"
-                    android:propertyName="rotation"
-                    android:startOffset="433"
-                    android:valueFrom="-14"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.305,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="433"
-                    android:propertyName="scaleX"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="1.06"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.2,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="433"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="1"
-                    android:valueTo="1.06"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.2,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="317"
-                    android:propertyName="scaleX"
-                    android:startOffset="433"
-                    android:valueFrom="1.06"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.305,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="317"
-                    android:propertyName="scaleY"
-                    android:startOffset="433"
-                    android:valueFrom="1.06"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.305,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="1017"
-                    android:propertyName="translateX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-</animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/hub_handle.xml b/packages/SystemUI/res/drawable/hub_handle.xml
deleted file mode 100644
index 8bc276f..0000000
--- a/packages/SystemUI/res/drawable/hub_handle.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-  ~ Copyright (C) 2024 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <corners android:radius="4dp" />
-    <solid android:color="#FFFFFF" />
-</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_check_box.xml b/packages/SystemUI/res/drawable/ic_check_box.xml
deleted file mode 100644
index a8d1a65..0000000
--- a/packages/SystemUI/res/drawable/ic_check_box.xml
+++ /dev/null
@@ -1,26 +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
-  -->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item
-        android:id="@+id/checked"
-        android:state_checked="true"
-        android:drawable="@drawable/ic_check_box_blue_24dp" />
-    <item
-        android:id="@+id/unchecked"
-        android:state_checked="false"
-        android:drawable="@drawable/ic_check_box_outline_24dp" />
-</selector>
diff --git a/packages/SystemUI/res/drawable/ic_check_box_blue_24dp.xml b/packages/SystemUI/res/drawable/ic_check_box_blue_24dp.xml
deleted file mode 100644
index 43cae69..0000000
--- a/packages/SystemUI/res/drawable/ic_check_box_blue_24dp.xml
+++ /dev/null
@@ -1,26 +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
-  -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24"
-        android:viewportHeight="24">
-    <path
-        android:pathData="M19,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.11,0 2,-0.9 2,-2L21,5c0,-1.1 -0.89,-2 -2,-2zM10,17l-5,-5 1.41,-1.41L10,14.17l7.59,-7.59L19,8l-9,9z"
-        android:fillColor="#4285F4"/>
-</vector>
-
diff --git a/packages/SystemUI/res/drawable/ic_check_box_outline_24dp.xml b/packages/SystemUI/res/drawable/ic_check_box_outline_24dp.xml
deleted file mode 100644
index f6f453a..0000000
--- a/packages/SystemUI/res/drawable/ic_check_box_outline_24dp.xml
+++ /dev/null
@@ -1,26 +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
-  -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24"
-        android:viewportHeight="24">
-    <path
-        android:pathData="M19,5v14H5V5h14m0,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2z"
-        android:fillColor="#757575"/>
-</vector>
-
diff --git a/packages/SystemUI/res/drawable/ic_speaker_group_black_24dp.xml b/packages/SystemUI/res/drawable/ic_speaker_group_black_24dp.xml
deleted file mode 100644
index ae0d562..0000000
--- a/packages/SystemUI/res/drawable/ic_speaker_group_black_24dp.xml
+++ /dev/null
@@ -1,31 +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
-  -->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24"
-        android:viewportHeight="24">
-    <path
-        android:pathData="M18.2,1L9.8,1C8.81,1 8,1.81 8,2.8v14.4c0,0.99 0.81,1.79 1.8,1.79l8.4,0.01c0.99,0 1.8,-0.81 1.8,-1.8L20,2.8c0,-0.99 -0.81,-1.8 -1.8,-1.8zM14,3c1.1,0 2,0.89 2,2s-0.9,2 -2,2 -2,-0.89 -2,-2 0.9,-2 2,-2zM14,16.5c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4 4,1.79 4,4 -1.79,4 -4,4z"
-        android:fillColor="#000000"/>
-    <path
-        android:pathData="M14,12.5m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"
-        android:fillColor="#000000"/>
-    <path
-        android:pathData="M6,5H4v16c0,1.1 0.89,2 2,2h10v-2H6V5z"
-        android:fillColor="#000000"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_widgets.xml b/packages/SystemUI/res/drawable/ic_widgets.xml
deleted file mode 100644
index b21d047..0000000
--- a/packages/SystemUI/res/drawable/ic_widgets.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--
-  ~ Copyright (C) 2024 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<!-- go/gm2-icons, from gs_widgets_vd_theme_24.xml -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:tint="?attr/colorControlNormal"
-    android:viewportHeight="960"
-    android:viewportWidth="960">
-    <path
-        android:fillColor="@android:color/black"
-        android:pathData="M666,520L440,294L666,68L892,294L666,520ZM120,440L120,120L440,120L440,440L120,440ZM520,840L520,520L840,520L840,840L520,840ZM120,840L120,520L440,520L440,840L120,840ZM200,360L360,360L360,200L200,200L200,360ZM667,408L780,295L667,182L554,295L667,408ZM600,760L760,760L760,600L600,600L600,760ZM200,760L360,760L360,600L200,600L200,760ZM360,360L360,360L360,360L360,360L360,360ZM554,295L554,295L554,295L554,295L554,295ZM360,600L360,600L360,600L360,600L360,600ZM600,600L600,600L600,600L600,600L600,600Z" />
-</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/placeholder_touchpad_back_gesture.png b/packages/SystemUI/res/drawable/placeholder_touchpad_back_gesture.png
new file mode 100644
index 0000000..526b585
--- /dev/null
+++ b/packages/SystemUI/res/drawable/placeholder_touchpad_back_gesture.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/placeholder_touchpad_tablet_back_gesture.png b/packages/SystemUI/res/drawable/placeholder_touchpad_tablet_back_gesture.png
new file mode 100644
index 0000000..cba2d20
--- /dev/null
+++ b/packages/SystemUI/res/drawable/placeholder_touchpad_tablet_back_gesture.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/settingslib_switch_bar_bg_on.xml b/packages/SystemUI/res/drawable/settingslib_switch_bar_bg_on.xml
index 250188b..fab2d8d 100644
--- a/packages/SystemUI/res/drawable/settingslib_switch_bar_bg_on.xml
+++ b/packages/SystemUI/res/drawable/settingslib_switch_bar_bg_on.xml
@@ -16,10 +16,11 @@
   -->
 
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:color="?android:attr/colorControlHighlight">
     <item>
         <shape android:shape="rectangle">
-            <solid android:color="@color/settingslib_state_on_color"/>
+            <solid android:color="?androidprv:attr/materialColorPrimaryContainer"/>
             <corners android:radius="@dimen/settingslib_switch_bar_radius"/>
         </shape>
     </item>
diff --git a/packages/SystemUI/res/drawable/settingslib_thumb_on.xml b/packages/SystemUI/res/drawable/settingslib_thumb_on.xml
index 5566ea3..e316a93 100644
--- a/packages/SystemUI/res/drawable/settingslib_thumb_on.xml
+++ b/packages/SystemUI/res/drawable/settingslib_thumb_on.xml
@@ -15,7 +15,8 @@
   limitations under the License.
   -->
 
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
     <item
         android:top="@dimen/settingslib_switch_thumb_margin"
         android:bottom="@dimen/settingslib_switch_thumb_margin">
@@ -23,7 +24,7 @@
             <size
                 android:height="@dimen/settingslib_switch_thumb_size"
                 android:width="@dimen/settingslib_switch_thumb_size"/>
-            <solid android:color="@color/settingslib_state_on_color"/>
+            <solid android:color="?androidprv:attr/materialColorOnPrimary"/>
         </shape>
     </item>
 </layer-list>
diff --git a/packages/SystemUI/res/drawable/settingslib_track_on_background.xml b/packages/SystemUI/res/drawable/settingslib_track_on_background.xml
index 1d9dacd..e2e6468 100644
--- a/packages/SystemUI/res/drawable/settingslib_track_on_background.xml
+++ b/packages/SystemUI/res/drawable/settingslib_track_on_background.xml
@@ -16,11 +16,12 @@
   -->
 
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:shape="rectangle"
     android:width="@dimen/settingslib_switch_track_width"
     android:height="@dimen/settingslib_switch_track_height">
     <padding android:left="@dimen/settingslib_switch_thumb_margin"
              android:right="@dimen/settingslib_switch_thumb_margin"/>
-    <solid android:color="@color/settingslib_track_on_color"/>
+    <solid android:color="?androidprv:attr/materialColorPrimary"/>
     <corners android:radius="@dimen/settingslib_switch_track_radius"/>
 </shape>
diff --git a/packages/SystemUI/res/layout/alert_dialog_systemui.xml b/packages/SystemUI/res/layout/alert_dialog_systemui.xml
index fd06238..14751ef 100644
--- a/packages/SystemUI/res/layout/alert_dialog_systemui.xml
+++ b/packages/SystemUI/res/layout/alert_dialog_systemui.xml
@@ -31,7 +31,6 @@
         android:id="@*android:id/contentPanel"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:minHeight="48dp"
         android:paddingStart="@dimen/dialog_side_padding"
         android:paddingEnd="@dimen/dialog_side_padding"
     >
diff --git a/packages/SystemUI/res/layout/app_clips_screenshot.xml b/packages/SystemUI/res/layout/app_clips_screenshot.xml
index bcc7bca..b09d35d 100644
--- a/packages/SystemUI/res/layout/app_clips_screenshot.xml
+++ b/packages/SystemUI/res/layout/app_clips_screenshot.xml
@@ -16,6 +16,7 @@
   -->
 <androidx.constraintlayout.widget.ConstraintLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:background="@null"
@@ -30,9 +31,10 @@
         android:layout_height="48dp"
         android:layout_marginStart="8dp"
         android:background="@drawable/overlay_button_background"
+        android:backgroundTint="?androidprv:attr/materialColorPrimary"
         android:paddingHorizontal="24dp"
         android:text="@string/app_clips_save_add_to_note"
-        android:textColor="?android:textColorSecondary"
+        android:textColor="?androidprv:attr/materialColorOnPrimary"
         app:layout_constraintBottom_toTopOf="@id/preview"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent" />
@@ -51,6 +53,32 @@
         app:layout_constraintStart_toEndOf="@id/save"
         app:layout_constraintTop_toTopOf="parent" />
 
+    <CheckBox
+        android:id="@+id/backlinks_include_data"
+        android:layout_width="wrap_content"
+        android:layout_height="48dp"
+        android:layout_marginStart="16dp"
+        android:checked="true"
+        android:text="@string/backlinks_include_link"
+        android:visibility="gone"
+        app:layout_constraintBottom_toTopOf="@id/preview"
+        app:layout_constraintStart_toEndOf="@id/cancel"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <TextView
+        android:id="@+id/backlinks_data"
+        android:layout_width="wrap_content"
+        android:layout_height="48dp"
+        android:layout_marginStart="16dp"
+        android:background="@drawable/backlinks_rounded_rectangle"
+        android:drawablePadding="4dp"
+        android:gravity="center"
+        android:paddingHorizontal="8dp"
+        android:visibility="gone"
+        app:layout_constraintBottom_toTopOf="@id/preview"
+        app:layout_constraintStart_toEndOf="@id/backlinks_include_data"
+        app:layout_constraintTop_toTopOf="parent" />
+
     <ImageView
         android:id="@+id/preview"
         android:layout_width="0px"
diff --git a/packages/SystemUI/res/layout/back.xml b/packages/SystemUI/res/layout/back.xml
index 046aecd..acefaae 100644
--- a/packages/SystemUI/res/layout/back.xml
+++ b/packages/SystemUI/res/layout/back.xml
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 
-<com.android.systemui.navigationbar.buttons.KeyButtonView
+<com.android.systemui.navigationbar.views.buttons.KeyButtonView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/back"
diff --git a/packages/SystemUI/res/layout/clipboard_overlay.xml b/packages/SystemUI/res/layout/clipboard_overlay.xml
index 2500769..65005f8 100644
--- a/packages/SystemUI/res/layout/clipboard_overlay.xml
+++ b/packages/SystemUI/res/layout/clipboard_overlay.xml
@@ -24,18 +24,29 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:contentDescription="@string/clipboard_overlay_window_name">
-    <ImageView
+    <!-- Min edge spacing guideline off of which the preview and actions can be anchored (without
+         this we'd need to express margins as the sum of two different dimens). -->
+    <androidx.constraintlayout.widget.Guideline
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@+id/min_edge_guideline"
+        app:layout_constraintGuide_begin="@dimen/overlay_action_container_minimum_edge_spacing"
+        android:orientation="vertical"/>
+    <!-- Negative horizontal margin because this container background must render beyond the thing
+         it's constrained by (the actions themselves). -->
+    <FrameLayout
         android:id="@+id/actions_container_background"
         android:visibility="gone"
         android:layout_height="0dp"
         android:layout_width="0dp"
         android:elevation="4dp"
-        android:background="@drawable/action_chip_container_background"
-        android:layout_marginStart="@dimen/overlay_action_container_margin_horizontal"
+        android:background="@drawable/shelf_action_chip_container_background"
+        android:layout_marginStart="@dimen/negative_overlay_action_container_minimum_edge_spacing"
+        android:layout_marginEnd="@dimen/negative_overlay_action_container_minimum_edge_spacing"
         android:layout_marginBottom="@dimen/overlay_action_container_margin_bottom"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="@+id/actions_container"
-        app:layout_constraintEnd_toEndOf="@+id/actions_container"
+        app:layout_constraintStart_toStartOf="@id/min_edge_guideline"
+        app:layout_constraintTop_toTopOf="@id/actions_container"
+        app:layout_constraintEnd_toEndOf="@id/actions_container"
         app:layout_constraintBottom_toBottomOf="parent"/>
     <HorizontalScrollView
         android:id="@+id/actions_container"
@@ -56,10 +67,13 @@
             android:id="@+id/actions"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:paddingStart="@dimen/shelf_action_chip_margin_start"
+            android:showDividers="middle"
+            android:divider="@drawable/shelf_action_chip_divider"
             android:animateLayoutChanges="true">
-            <include layout="@layout/overlay_action_chip"
+            <include layout="@layout/shelf_action_chip"
                      android:id="@+id/share_chip"/>
-            <include layout="@layout/overlay_action_chip"
+            <include layout="@layout/shelf_action_chip"
                      android:id="@+id/remote_copy_chip"/>
         </LinearLayout>
     </HorizontalScrollView>
@@ -73,7 +87,7 @@
         android:layout_marginBottom="@dimen/overlay_preview_container_margin"
         android:elevation="7dp"
         android:background="@drawable/overlay_border"
-        app:layout_constraintStart_toStartOf="@id/actions_container_background"
+        app:layout_constraintStart_toStartOf="@id/min_edge_guideline"
         app:layout_constraintTop_toTopOf="@id/clipboard_preview"
         app:layout_constraintEnd_toEndOf="@id/clipboard_preview"
         app:layout_constraintBottom_toBottomOf="@id/actions_container_background"/>
diff --git a/packages/SystemUI/res/layout/clipboard_overlay2.xml b/packages/SystemUI/res/layout/clipboard_overlay2.xml
deleted file mode 100644
index 65005f8..0000000
--- a/packages/SystemUI/res/layout/clipboard_overlay2.xml
+++ /dev/null
@@ -1,202 +0,0 @@
-<?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.
-  -->
-<com.android.systemui.clipboardoverlay.ClipboardOverlayView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/clipboard_ui"
-    android:theme="@style/FloatingOverlay"
-    android:alpha="0"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:contentDescription="@string/clipboard_overlay_window_name">
-    <!-- Min edge spacing guideline off of which the preview and actions can be anchored (without
-         this we'd need to express margins as the sum of two different dimens). -->
-    <androidx.constraintlayout.widget.Guideline
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:id="@+id/min_edge_guideline"
-        app:layout_constraintGuide_begin="@dimen/overlay_action_container_minimum_edge_spacing"
-        android:orientation="vertical"/>
-    <!-- Negative horizontal margin because this container background must render beyond the thing
-         it's constrained by (the actions themselves). -->
-    <FrameLayout
-        android:id="@+id/actions_container_background"
-        android:visibility="gone"
-        android:layout_height="0dp"
-        android:layout_width="0dp"
-        android:elevation="4dp"
-        android:background="@drawable/shelf_action_chip_container_background"
-        android:layout_marginStart="@dimen/negative_overlay_action_container_minimum_edge_spacing"
-        android:layout_marginEnd="@dimen/negative_overlay_action_container_minimum_edge_spacing"
-        android:layout_marginBottom="@dimen/overlay_action_container_margin_bottom"
-        app:layout_constraintStart_toStartOf="@id/min_edge_guideline"
-        app:layout_constraintTop_toTopOf="@id/actions_container"
-        app:layout_constraintEnd_toEndOf="@id/actions_container"
-        app:layout_constraintBottom_toBottomOf="parent"/>
-    <HorizontalScrollView
-        android:id="@+id/actions_container"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_marginEnd="@dimen/overlay_action_container_margin_horizontal"
-        android:paddingEnd="@dimen/overlay_action_container_padding_end"
-        android:paddingVertical="@dimen/overlay_action_container_padding_vertical"
-        android:elevation="4dp"
-        android:scrollbars="none"
-        app:layout_constraintHorizontal_bias="0"
-        app:layout_constraintWidth_percent="1.0"
-        app:layout_constraintWidth_max="wrap"
-        app:layout_constraintStart_toEndOf="@+id/preview_border"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintBottom_toBottomOf="@id/actions_container_background">
-        <LinearLayout
-            android:id="@+id/actions"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:paddingStart="@dimen/shelf_action_chip_margin_start"
-            android:showDividers="middle"
-            android:divider="@drawable/shelf_action_chip_divider"
-            android:animateLayoutChanges="true">
-            <include layout="@layout/shelf_action_chip"
-                     android:id="@+id/share_chip"/>
-            <include layout="@layout/shelf_action_chip"
-                     android:id="@+id/remote_copy_chip"/>
-        </LinearLayout>
-    </HorizontalScrollView>
-    <View
-        android:id="@+id/preview_border"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        android:layout_marginStart="@dimen/overlay_preview_container_margin"
-        android:layout_marginTop="@dimen/overlay_border_width_neg"
-        android:layout_marginEnd="@dimen/overlay_border_width_neg"
-        android:layout_marginBottom="@dimen/overlay_preview_container_margin"
-        android:elevation="7dp"
-        android:background="@drawable/overlay_border"
-        app:layout_constraintStart_toStartOf="@id/min_edge_guideline"
-        app:layout_constraintTop_toTopOf="@id/clipboard_preview"
-        app:layout_constraintEnd_toEndOf="@id/clipboard_preview"
-        app:layout_constraintBottom_toBottomOf="@id/actions_container_background"/>
-    <FrameLayout
-        android:id="@+id/clipboard_preview"
-        android:layout_width="@dimen/clipboard_preview_size"
-        android:layout_height="wrap_content"
-        android:layout_marginStart="@dimen/overlay_border_width"
-        android:layout_marginBottom="@dimen/overlay_border_width"
-        android:layout_gravity="center"
-        android:elevation="7dp"
-        android:background="@drawable/overlay_preview_background"
-        android:clipChildren="true"
-        android:clipToOutline="true"
-        android:clipToPadding="true"
-        app:layout_constraintStart_toStartOf="@id/preview_border"
-        app:layout_constraintBottom_toBottomOf="@id/preview_border">
-        <TextView android:id="@+id/text_preview"
-                  android:textFontWeight="500"
-                  android:padding="8dp"
-                  android:gravity="center|start"
-                  android:ellipsize="end"
-                  android:autoSizeTextType="uniform"
-                  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"/>
-        <ImageView
-            android:id="@+id/image_preview"
-            android:scaleType="fitCenter"
-            android:adjustViewBounds="true"
-            android:contentDescription="@string/clipboard_image_preview"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"/>
-        <TextView
-            android:id="@+id/hidden_preview"
-            android:visibility="gone"
-            android:textFontWeight="500"
-            android:padding="8dp"
-            android:gravity="center"
-            android:textSize="14sp"
-            android:textColor="?attr/overlayButtonTextColor"
-            android:background="?androidprv:attr/colorAccentSecondary"
-            android:layout_width="@dimen/clipboard_preview_size"
-            android:layout_height="@dimen/clipboard_preview_size"/>
-    </FrameLayout>
-    <LinearLayout
-        android:id="@+id/minimized_preview"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:visibility="gone"
-        android:elevation="7dp"
-        android:padding="8dp"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        android:layout_marginStart="@dimen/overlay_action_container_margin_horizontal"
-        android:layout_marginBottom="@dimen/overlay_action_container_margin_bottom"
-        android:background="@drawable/clipboard_minimized_background">
-        <ImageView
-            android:src="@drawable/ic_content_paste"
-            android:tint="?attr/overlayButtonTextColor"
-            android:layout_width="24dp"
-            android:layout_height="24dp"/>
-        <ImageView
-            android:src="@*android:drawable/ic_chevron_end"
-            android:tint="?attr/overlayButtonTextColor"
-            android:layout_width="24dp"
-            android:layout_height="24dp"
-            android:paddingEnd="-8dp"
-            android:paddingStart="-4dp"/>
-    </LinearLayout>
-    <androidx.constraintlayout.widget.Barrier
-        android:id="@+id/clipboard_content_top"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        app:barrierDirection="top"
-        app:constraint_referenced_ids="clipboard_preview,minimized_preview"/>
-    <androidx.constraintlayout.widget.Barrier
-        android:id="@+id/clipboard_content_end"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        app:barrierDirection="end"
-        app:constraint_referenced_ids="clipboard_preview,minimized_preview"/>
-    <FrameLayout
-        android:id="@+id/dismiss_button"
-        android:layout_width="@dimen/overlay_dismiss_button_tappable_size"
-        android:layout_height="@dimen/overlay_dismiss_button_tappable_size"
-        android:elevation="10dp"
-        android:visibility="gone"
-        android:alpha="0"
-        app:layout_constraintStart_toEndOf="@id/clipboard_content_end"
-        app:layout_constraintEnd_toEndOf="@id/clipboard_content_end"
-        app:layout_constraintTop_toTopOf="@id/clipboard_content_top"
-        app:layout_constraintBottom_toTopOf="@id/clipboard_content_top"
-        android:contentDescription="@string/clipboard_dismiss_description">
-        <ImageView
-            android:id="@+id/dismiss_image"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_margin="@dimen/overlay_dismiss_button_margin"
-            android:background="@drawable/circular_background"
-            android:backgroundTint="?androidprv:attr/materialColorPrimaryFixedDim"
-            android:tint="?androidprv:attr/materialColorOnPrimaryFixed"
-            android:padding="4dp"
-            android:src="@drawable/ic_close"/>
-    </FrameLayout>
-</com.android.systemui.clipboardoverlay.ClipboardOverlayView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/contextual.xml b/packages/SystemUI/res/layout/contextual.xml
index 2cd7926..ac840d8 100644
--- a/packages/SystemUI/res/layout/contextual.xml
+++ b/packages/SystemUI/res/layout/contextual.xml
@@ -24,7 +24,7 @@
              android:clipChildren="false"
              android:clipToPadding="false"
              >
-    <com.android.systemui.navigationbar.buttons.KeyButtonView
+    <com.android.systemui.navigationbar.views.buttons.KeyButtonView
         android:id="@+id/menu"
         android:layout_height="match_parent"
         android:layout_width="match_parent"
@@ -47,7 +47,7 @@
              android:layout_height="match_parent"
              android:visibility="invisible"
     />
-    <com.android.systemui.navigationbar.buttons.KeyButtonView
+    <com.android.systemui.navigationbar.views.buttons.KeyButtonView
         android:id="@+id/accessibility_button"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/custom_key.xml b/packages/SystemUI/res/layout/custom_key.xml
index dc65777..0b0f4fa 100644
--- a/packages/SystemUI/res/layout/custom_key.xml
+++ b/packages/SystemUI/res/layout/custom_key.xml
@@ -13,7 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.systemui.navigationbar.buttons.KeyButtonView
+<com.android.systemui.navigationbar.views.buttons.KeyButtonView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_width="@dimen/navigation_side_padding"
diff --git a/packages/SystemUI/res/layout/dream_overlay_container.xml b/packages/SystemUI/res/layout/dream_overlay_container.xml
index dcd3fa6..be1652b 100644
--- a/packages/SystemUI/res/layout/dream_overlay_container.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_container.xml
@@ -21,19 +21,6 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <ImageView
-        android:id="@+id/glanceable_hub_handle"
-        android:layout_width="4dp"
-        android:layout_height="220dp"
-        android:layout_centerVertical="true"
-        android:layout_marginEnd="12dp"
-        android:background="@drawable/hub_handle"
-        android:visibility="gone"
-        android:contentDescription="UI indicator for swiping open the glanceable hub"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
-
     <androidx.constraintlayout.widget.ConstraintLayout
         android:id="@+id/dream_overlay_content"
         android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/dream_overlay_open_hub_chip.xml b/packages/SystemUI/res/layout/dream_overlay_open_hub_chip.xml
deleted file mode 100644
index be063a9..0000000
--- a/packages/SystemUI/res/layout/dream_overlay_open_hub_chip.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2024 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
--->
-<com.android.systemui.animation.view.LaunchableImageView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="@dimen/dream_overlay_bottom_affordance_height"
-    android:layout_width="@dimen/dream_overlay_bottom_affordance_width"
-    android:layout_gravity="bottom|start"
-    android:padding="@dimen/dream_overlay_bottom_affordance_padding"
-    android:scaleType="fitCenter"
-    android:tint="?android:attr/textColorPrimary"
-    android:src="@drawable/ic_widgets"
-    android:contentDescription="@string/accessibility_action_open_communal_hub" />
diff --git a/packages/SystemUI/res/layout/home.xml b/packages/SystemUI/res/layout/home.xml
index 84eed6a..227e390 100644
--- a/packages/SystemUI/res/layout/home.xml
+++ b/packages/SystemUI/res/layout/home.xml
@@ -13,7 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.systemui.navigationbar.buttons.KeyButtonView
+<com.android.systemui.navigationbar.views.buttons.KeyButtonView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/home"
diff --git a/packages/SystemUI/res/layout/ime_switcher.xml b/packages/SystemUI/res/layout/ime_switcher.xml
index a2c8308..fa9a12b 100644
--- a/packages/SystemUI/res/layout/ime_switcher.xml
+++ b/packages/SystemUI/res/layout/ime_switcher.xml
@@ -15,7 +15,7 @@
   ~ limitations under the License
   -->
 
-<com.android.systemui.navigationbar.buttons.KeyButtonView
+<com.android.systemui.navigationbar.views.buttons.KeyButtonView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/ime_switcher"
     android:layout_width="@dimen/navigation_key_width"
diff --git a/packages/SystemUI/res/layout/media_output_list_item.xml b/packages/SystemUI/res/layout/media_output_list_item.xml
deleted file mode 100644
index 5b1ec7f..0000000
--- a/packages/SystemUI/res/layout/media_output_list_item.xml
+++ /dev/null
@@ -1,146 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2020 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/device_container"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical">
-    <FrameLayout
-        android:layout_width="match_parent"
-        android:layout_height="64dp"
-        android:layout_marginStart="16dp"
-        android:layout_marginEnd="16dp"
-        android:layout_marginBottom="12dp">
-        <FrameLayout
-            android:id="@+id/item_layout"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:background="@drawable/media_output_item_background"
-            android:layout_gravity="center_vertical|start">
-            <com.android.systemui.media.dialog.MediaOutputSeekbar
-                android:id="@+id/volume_seekbar"
-                android:splitTrack="false"
-                android:visibility="gone"
-                android:paddingStart="0dp"
-                android:paddingEnd="0dp"
-                android:background="@null"
-                android:contentDescription="@string/media_output_dialog_accessibility_seekbar"
-                android:progressDrawable="@drawable/media_output_dialog_seekbar_background"
-                android:thumb="@null"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"/>
-        </FrameLayout>
-
-        <FrameLayout
-            android:layout_width="56dp"
-            android:layout_height="64dp"
-            android:layout_gravity="center_vertical|start">
-            <ImageView
-                android:id="@+id/title_icon"
-                android:layout_width="24dp"
-                android:layout_height="24dp"
-                android:layout_gravity="center"/>
-        </FrameLayout>
-
-        <TextView
-            android:id="@+id/title"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical|start"
-            android:layout_marginStart="56dp"
-            android:layout_marginEnd="56dp"
-            android:ellipsize="end"
-            android:maxLines="1"
-            android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
-            android:textSize="16sp"/>
-
-        <LinearLayout
-            android:id="@+id/two_line_layout"
-            android:orientation="vertical"
-            android:layout_width="wrap_content"
-            android:layout_gravity="center_vertical|start"
-            android:layout_height="48dp"
-            android:layout_marginEnd="56dp"
-            android:layout_marginStart="56dp">
-            <TextView
-                android:id="@+id/two_line_title"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:ellipsize="end"
-                android:maxLines="1"
-                android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
-                android:textColor="@color/media_dialog_item_main_content"
-                android:textSize="16sp"/>
-            <TextView
-                android:id="@+id/subtitle"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:ellipsize="end"
-                android:maxLines="1"
-                android:textColor="@color/media_dialog_item_main_content"
-                android:textSize="14sp"
-                android:fontFamily="@*android:string/config_bodyFontFamily"
-                android:visibility="gone"/>
-        </LinearLayout>
-
-        <ProgressBar
-            android:id="@+id/volume_indeterminate_progress"
-            style="?android:attr/progressBarStyleSmallTitle"
-            android:layout_width="24dp"
-            android:layout_height="24dp"
-            android:layout_marginEnd="16dp"
-            android:indeterminate="true"
-            android:layout_gravity="end|center"
-            android:indeterminateOnly="true"
-            android:visibility="gone"/>
-
-        <ImageView
-            android:id="@+id/media_output_item_status"
-            android:layout_width="24dp"
-            android:layout_height="24dp"
-            android:layout_marginEnd="16dp"
-            android:indeterminate="true"
-            android:layout_gravity="end|center"
-            android:indeterminateOnly="true"
-            android:importantForAccessibility="no"
-            android:visibility="gone"/>
-
-        <LinearLayout
-            android:id="@+id/end_action_area"
-            android:visibility="gone"
-            android:orientation="vertical"
-            android:layout_width="48dp"
-            android:layout_height="64dp"
-            android:layout_gravity="end|center"
-            android:gravity="center_vertical">
-            <CheckBox
-                android:id="@+id/check_box"
-                android:focusable="false"
-                android:importantForAccessibility="no"
-                android:layout_width="24dp"
-                android:layout_height="24dp"
-                android:layout_marginEnd="16dp"
-                android:layout_gravity="end"
-                android:button="@drawable/ic_circle_check_box"
-                android:visibility="gone"
-            />
-
-        </LinearLayout>
-    </FrameLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/menu_ime.xml b/packages/SystemUI/res/layout/menu_ime.xml
index 0bb622b..443e4e3 100644
--- a/packages/SystemUI/res/layout/menu_ime.xml
+++ b/packages/SystemUI/res/layout/menu_ime.xml
@@ -25,7 +25,7 @@
     are placed inside a view that has a size controlled by weight. Ensure weight is large enough to
     support icon size. Use layout_width=navigation_side_padding like other navbar buttons. -->
 
-    <com.android.systemui.navigationbar.buttons.KeyButtonView
+    <com.android.systemui.navigationbar.views.buttons.KeyButtonView
         android:id="@+id/menu"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
@@ -43,7 +43,7 @@
         android:paddingStart="0dp"
         android:paddingEnd="0dp"
         />
-    <com.android.systemui.navigationbar.buttons.KeyButtonView
+    <com.android.systemui.navigationbar.views.buttons.KeyButtonView
         android:id="@+id/rotate_suggestion"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
@@ -51,7 +51,7 @@
         android:scaleType="centerInside"
         android:contentDescription="@string/accessibility_rotate_button"
         />
-    <com.android.systemui.navigationbar.buttons.KeyButtonView
+    <com.android.systemui.navigationbar.views.buttons.KeyButtonView
         android:id="@+id/accessibility_button"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
index 5f59e78..a868ec4 100644
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -17,7 +17,7 @@
 */
 -->
 
-<com.android.systemui.navigationbar.NavigationBarView
+<com.android.systemui.navigationbar.views.NavigationBarView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/navigation_bar_view"
     android:layout_height="match_parent"
@@ -26,11 +26,11 @@
     android:clipToPadding="false"
     android:background="@drawable/system_bar_background">
 
-    <com.android.systemui.navigationbar.NavigationBarInflaterView
+    <com.android.systemui.navigationbar.views.NavigationBarInflaterView
         android:id="@+id/navigation_inflater"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:clipChildren="false"
         android:clipToPadding="false" />
 
-</com.android.systemui.navigationbar.NavigationBarView>
+</com.android.systemui.navigationbar.views.NavigationBarView>
diff --git a/packages/SystemUI/res/layout/navigation_bar_window.xml b/packages/SystemUI/res/layout/navigation_bar_window.xml
index b2473cd..9442124 100644
--- a/packages/SystemUI/res/layout/navigation_bar_window.xml
+++ b/packages/SystemUI/res/layout/navigation_bar_window.xml
@@ -16,7 +16,7 @@
 ** limitations under the License.
 */
 -->
-<com.android.systemui.navigationbar.NavigationBarFrame
+<com.android.systemui.navigationbar.views.NavigationBarFrame
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/navigation_bar_frame"
@@ -24,4 +24,4 @@
     android:layout_height="match_parent"
     android:layout_width="match_parent">
 
-</com.android.systemui.navigationbar.NavigationBarFrame>
+</com.android.systemui.navigationbar.views.NavigationBarFrame>
diff --git a/packages/SystemUI/res/layout/navigation_layout.xml b/packages/SystemUI/res/layout/navigation_layout.xml
index 46f238c..5c6c9a4 100644
--- a/packages/SystemUI/res/layout/navigation_layout.xml
+++ b/packages/SystemUI/res/layout/navigation_layout.xml
@@ -27,7 +27,7 @@
     android:clipToPadding="false"
     android:id="@+id/horizontal">
 
-    <com.android.systemui.navigationbar.buttons.NearestTouchFrame
+    <com.android.systemui.navigationbar.views.buttons.NearestTouchFrame
         android:id="@+id/nav_buttons"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
@@ -53,6 +53,6 @@
             android:clipToPadding="false"
             android:clipChildren="false" />
 
-    </com.android.systemui.navigationbar.buttons.NearestTouchFrame>
+    </com.android.systemui.navigationbar.views.buttons.NearestTouchFrame>
 
 </FrameLayout>
diff --git a/packages/SystemUI/res/layout/navigation_layout_vertical.xml b/packages/SystemUI/res/layout/navigation_layout_vertical.xml
index 42e9324..c64e3f7 100644
--- a/packages/SystemUI/res/layout/navigation_layout_vertical.xml
+++ b/packages/SystemUI/res/layout/navigation_layout_vertical.xml
@@ -25,7 +25,7 @@
     android:paddingBottom="@dimen/nav_content_padding"
     android:id="@+id/vertical">
 
-    <com.android.systemui.navigationbar.buttons.NearestTouchFrame
+    <com.android.systemui.navigationbar.views.buttons.NearestTouchFrame
         android:id="@+id/nav_buttons"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
@@ -33,7 +33,7 @@
         android:clipToPadding="false"
         systemui:isVertical="true">
 
-        <com.android.systemui.navigationbar.buttons.ReverseLinearLayout
+        <com.android.systemui.navigationbar.views.buttons.ReverseLinearLayout
             android:id="@+id/ends_group"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
@@ -41,7 +41,7 @@
             android:clipToPadding="false"
             android:clipChildren="false" />
 
-        <com.android.systemui.navigationbar.buttons.ReverseLinearLayout
+        <com.android.systemui.navigationbar.views.buttons.ReverseLinearLayout
             android:id="@+id/center_group"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
@@ -50,6 +50,6 @@
             android:clipToPadding="false"
             android:clipChildren="false" />
 
-    </com.android.systemui.navigationbar.buttons.NearestTouchFrame>
+    </com.android.systemui.navigationbar.views.buttons.NearestTouchFrame>
 
 </FrameLayout>
diff --git a/packages/SystemUI/res/layout/ongoing_activity_chip.xml b/packages/SystemUI/res/layout/ongoing_activity_chip.xml
index cd5c37d..154397d 100644
--- a/packages/SystemUI/res/layout/ongoing_activity_chip.xml
+++ b/packages/SystemUI/res/layout/ongoing_activity_chip.xml
@@ -34,18 +34,20 @@
         android:background="@drawable/ongoing_activity_chip_bg"
         android:paddingStart="@dimen/ongoing_activity_chip_side_padding"
         android:paddingEnd="@dimen/ongoing_activity_chip_side_padding"
-        android:contentDescription="@string/ongoing_phone_call_content_description"
         android:minWidth="@dimen/min_clickable_item_size"
     >
 
         <ImageView
             android:src="@*android:drawable/ic_phone"
             android:id="@+id/ongoing_activity_chip_icon"
+            android:contentDescription="@string/ongoing_phone_call_content_description"
             android:layout_width="@dimen/ongoing_activity_chip_icon_size"
             android:layout_height="@dimen/ongoing_activity_chip_icon_size"
             android:tint="?android:attr/colorPrimary"
         />
 
+        <!-- Only one of [ongoing_activity_chip_time, ongoing_activity_chip_text] will ever
+             be shown at one time. -->
         <com.android.systemui.statusbar.chips.ui.view.ChipChronometer
             android:id="@+id/ongoing_activity_chip_time"
             android:layout_width="wrap_content"
@@ -58,5 +60,19 @@
             android:textColor="?android:attr/colorPrimary"
         />
 
+        <!-- Used to show generic text in the chip instead of a timer. -->
+        <TextView
+            android:id="@+id/ongoing_activity_chip_text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:singleLine="true"
+            android:gravity="center|start"
+            android:paddingStart="@dimen/ongoing_activity_chip_icon_text_padding"
+            android:textAppearance="@android:style/TextAppearance.Material.Small"
+            android:fontFamily="@*android:string/config_headlineFontFamily"
+            android:textColor="?android:attr/colorPrimary"
+            android:visibility="gone"
+            />
+
     </com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer>
 </FrameLayout>
diff --git a/packages/SystemUI/res/layout/recent_apps.xml b/packages/SystemUI/res/layout/recent_apps.xml
index e2b1374..767e16c 100644
--- a/packages/SystemUI/res/layout/recent_apps.xml
+++ b/packages/SystemUI/res/layout/recent_apps.xml
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 
-<com.android.systemui.navigationbar.buttons.KeyButtonView
+<com.android.systemui.navigationbar.views.buttons.KeyButtonView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/recent_apps"
diff --git a/packages/SystemUI/res/layout/rich_ongoing_timer_notification.xml b/packages/SystemUI/res/layout/rich_ongoing_timer_notification.xml
new file mode 100644
index 0000000..f2bfbe5c9
--- /dev/null
+++ b/packages/SystemUI/res/layout/rich_ongoing_timer_notification.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<com.android.systemui.statusbar.notification.row.ui.view.TimerView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <androidx.constraintlayout.widget.Guideline
+        android:id="@+id/topBaseline"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        app:layout_constraintGuide_begin="22sp"
+        />
+
+    <ImageView
+        android:id="@+id/icon"
+        android:layout_width="24dp"
+        android:layout_height="24dp"
+        android:src="@drawable/ic_close"
+        app:tint="@android:color/white"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toStartOf="@id/label"
+        android:baseline="18dp"
+        app:layout_constraintBaseline_toTopOf="@id/topBaseline"
+        />
+    <TextView
+        android:id="@+id/label"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        app:layout_constraintStart_toEndOf="@id/icon"
+        app:layout_constraintEnd_toStartOf="@id/chronoRemaining"
+        android:singleLine="true"
+        tools:text="15s Timer"
+        app:layout_constraintBaseline_toTopOf="@id/topBaseline"
+        android:paddingEnd="4dp"
+        />
+    <Chronometer
+        android:id="@+id/chronoRemaining"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:singleLine="true"
+        android:textSize="20sp"
+        android:gravity="end"
+        tools:text="0:12"
+        app:layout_constraintBaseline_toTopOf="@id/topBaseline"
+        app:layout_constraintEnd_toStartOf="@id/pausedTimeRemaining"
+        app:layout_constraintStart_toEndOf="@id/label"
+        android:countDown="true"
+        android:paddingEnd="4dp"
+        />
+    <TextView
+        android:id="@+id/pausedTimeRemaining"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:singleLine="true"
+        android:textSize="20sp"
+        android:gravity="end"
+        tools:text="0:12"
+        app:layout_constraintBaseline_toTopOf="@id/topBaseline"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@id/chronoRemaining"
+        android:paddingEnd="4dp"
+        />
+
+    <androidx.constraintlayout.widget.Barrier
+        android:id="@+id/bottomOfTop"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        app:barrierDirection="bottom"
+        app:constraint_referenced_ids="icon,label,chronoRemaining,pausedTimeRemaining"
+        />
+
+    <com.android.systemui.statusbar.notification.row.ui.view.TimerButtonView
+        android:id="@+id/mainButton"
+        android:layout_width="124dp"
+        android:layout_height="wrap_content"
+        tools:text="Reset"
+        tools:drawableStart="@android:drawable/ic_menu_add"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toStartOf="@id/altButton"
+        app:layout_constraintTop_toBottomOf="@id/bottomOfTop"
+        app:layout_constraintHorizontal_chainStyle="spread"
+        android:paddingEnd="4dp"
+        />
+
+    <com.android.systemui.statusbar.notification.row.ui.view.TimerButtonView
+        android:id="@+id/altButton"
+        tools:text="Reset"
+        tools:drawableStart="@android:drawable/ic_menu_add"
+        android:drawablePadding="2dp"
+        android:drawableTint="@android:color/white"
+        android:layout_width="124dp"
+        android:layout_height="wrap_content"
+        app:layout_constraintTop_toBottomOf="@id/bottomOfTop"
+        app:layout_constraintStart_toEndOf="@id/mainButton"
+        app:layout_constraintEnd_toEndOf="parent"
+        android:paddingEnd="4dp"
+        />
+</com.android.systemui.statusbar.notification.row.ui.view.TimerView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/screen_share_dialog.xml b/packages/SystemUI/res/layout/screen_share_dialog.xml
index 2616e8a..aa083ad 100644
--- a/packages/SystemUI/res/layout/screen_share_dialog.xml
+++ b/packages/SystemUI/res/layout/screen_share_dialog.xml
@@ -46,7 +46,7 @@
             android:layout_marginTop="@dimen/screenrecord_title_margin_top"
             android:gravity="center"/>
         <Spinner
-            android:id="@+id/screen_share_mode_spinner"
+            android:id="@+id/screen_share_mode_options"
             android:layout_width="match_parent"
             android:layout_height="@dimen/screenrecord_spinner_height"
             android:layout_marginTop="@dimen/screenrecord_spinner_margin"
diff --git a/packages/SystemUI/res/layout/screenshot_shelf.xml b/packages/SystemUI/res/layout/screenshot_shelf.xml
index 84ab0f1..fff1de7 100644
--- a/packages/SystemUI/res/layout/screenshot_shelf.xml
+++ b/packages/SystemUI/res/layout/screenshot_shelf.xml
@@ -51,7 +51,6 @@
             android:layout_marginBottom="@dimen/overlay_border_width"
             android:layout_gravity="center"
             android:elevation="4dp"
-            android:contentDescription="@string/screenshot_edit_description"
             android:scaleType="fitEnd"
             android:background="@drawable/overlay_preview_background"
             android:adjustViewBounds="true"
@@ -67,7 +66,6 @@
             android:layout_marginBottom="@dimen/overlay_border_width"
             android:layout_gravity="center"
             android:elevation="4dp"
-            android:contentDescription="@string/screenshot_edit_description"
             android:scaleType="fitEnd"
             android:background="@drawable/overlay_preview_background"
             android:adjustViewBounds="true"
diff --git a/packages/SystemUI/res/layout/sidefps_view.xml b/packages/SystemUI/res/layout/sidefps_view.xml
index fc4bf8a..e80ed26 100644
--- a/packages/SystemUI/res/layout/sidefps_view.xml
+++ b/packages/SystemUI/res/layout/sidefps_view.xml
@@ -22,5 +22,4 @@
     android:layout_height="wrap_content"
     app:lottie_autoPlay="true"
     app:lottie_loop="true"
-    app:lottie_rawRes="@raw/sfps_pulse"
-    android:importantForAccessibility="no"/>
\ No newline at end of file
+    app:lottie_rawRes="@raw/sfps_pulse"/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/raw/face_dialog_authenticating.json b/packages/SystemUI/res/raw/face_dialog_authenticating.json
index 4e25e6d..896816e 100644
--- a/packages/SystemUI/res/raw/face_dialog_authenticating.json
+++ b/packages/SystemUI/res/raw/face_dialog_authenticating.json
@@ -1 +1 @@
-{"v":"5.7.13","fr":60,"ip":0,"op":61,"w":64,"h":64,"nm":"face_scanning 3","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".blue200","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[32,32,0],"ix":2,"l":2},"a":{"a":0,"k":[27.25,27.25,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":30,"s":[95,95,100]},{"t":60,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.243],[-1.244,0],[0,1.243],[1.242,0]],"o":[[0,1.243],[1.242,0],[0,-1.243],[-1.244,0]],"v":[[-2.249,0.001],[0.001,2.251],[2.249,0.001],[0.001,-2.251]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[15.1,20.495],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.243],[-1.242,0],[0,1.243],[1.242,0]],"o":[[0,1.243],[1.242,0],[0,-1.243],[-1.242,0]],"v":[[-2.249,0],[0.001,2.25],[2.249,0],[0.001,-2.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[39.4,20.495],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[2.814,3.523],[-2.814,3.523],[-2.814,1.363],[0.652,1.363],[0.652,-3.523],[2.814,-3.523]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[27.791,28.479],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.154,0.15],[0,0],[0.117,-0.095],[0,0],[0.228,-0.121],[0.358,-0.103],[0.922,0.261],[0.3,0.16],[0.24,0.185],[0.14,0.139],[0.178,0.261],[0.143,0.451],[0,0],[0,0.494],[0,0],[-0.214,-0.676],[-0.392,-0.572],[-0.323,-0.317],[-0.228,-0.177],[-0.333,-0.179],[-0.503,-0.145],[-0.662,0],[-0.653,0.184],[-0.437,0.233],[-0.336,0.258],[0,0],[0,0]],"o":[[0,0],[-0.107,0.106],[0,0],[-0.24,0.185],[-0.301,0.16],[-0.92,0.261],[-0.357,-0.103],[-0.228,-0.121],[-0.158,-0.122],[-0.225,-0.221],[-0.272,-0.393],[0,0],[-0.147,-0.466],[0,0],[0,0.716],[0.206,0.656],[0.256,0.372],[0.204,0.201],[0.336,0.258],[0.436,0.233],[0.655,0.184],[0.662,0],[0.503,-0.145],[0.332,-0.179],[0,0],[0,0],[0.165,-0.136]],"v":[[6.094,1.465],[4.579,-0.076],[4.242,0.225],[4.124,0.315],[3.43,0.771],[2.439,1.165],[-0.342,1.165],[-1.331,0.771],[-2.027,0.315],[-2.48,-0.075],[-3.087,-0.801],[-3.712,-2.075],[-3.712,-2.075],[-3.934,-3.523],[-6.094,-3.523],[-5.771,-1.424],[-4.868,0.424],[-3.995,1.465],[-3.344,2.027],[-2.35,2.676],[-0.934,3.243],[1.049,3.523],[3.031,3.243],[4.449,2.676],[5.441,2.027],[5.482,1.997],[5.615,1.895]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[26.201,40.411],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-13.398,0],[0,-13.4],[13.398,0],[0,13.4]],"o":[[13.398,0],[0,13.4],[-13.398,0],[0,-13.4]],"v":[[0,-24.3],[24.3,0],[0,24.3],[-24.3,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[14.904,0],[0,-14.904],[-14.904,0],[0,14.904]],"o":[[-14.904,0],[0,14.904],[14.904,0],[0,-14.904]],"v":[[0,-27],[-27,0],[0,27],[27,0]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[27.25,27.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":4,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
+{"v":"5.7.13","fr":60,"ip":0,"op":61,"w":68,"h":68,"nm":"face_dialog_authenticating","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".blue200","cl":"blue200","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[34,34,0],"ix":2,"l":2},"a":{"a":0,"k":[27.25,27.25,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":30,"s":[95,95,100]},{"t":60,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.243],[-1.244,0],[0,1.243],[1.242,0]],"o":[[0,1.243],[1.242,0],[0,-1.243],[-1.244,0]],"v":[[-2.249,0.001],[0.001,2.251],[2.249,0.001],[0.001,-2.251]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[15.1,20.495],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.243],[-1.242,0],[0,1.243],[1.242,0]],"o":[[0,1.243],[1.242,0],[0,-1.243],[-1.242,0]],"v":[[-2.249,0],[0.001,2.25],[2.249,0],[0.001,-2.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[39.4,20.495],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[2.814,3.523],[-2.814,3.523],[-2.814,1.363],[0.652,1.363],[0.652,-3.523],[2.814,-3.523]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[27.791,28.479],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.154,0.15],[0,0],[0.117,-0.095],[0,0],[0.228,-0.121],[0.358,-0.103],[0.922,0.261],[0.3,0.16],[0.24,0.185],[0.14,0.139],[0.178,0.261],[0.143,0.451],[0,0],[0,0.494],[0,0],[-0.214,-0.676],[-0.392,-0.572],[-0.323,-0.317],[-0.228,-0.177],[-0.333,-0.179],[-0.503,-0.145],[-0.662,0],[-0.653,0.184],[-0.437,0.233],[-0.336,0.258],[0,0],[0,0]],"o":[[0,0],[-0.107,0.106],[0,0],[-0.24,0.185],[-0.301,0.16],[-0.92,0.261],[-0.357,-0.103],[-0.228,-0.121],[-0.158,-0.122],[-0.225,-0.221],[-0.272,-0.393],[0,0],[-0.147,-0.466],[0,0],[0,0.716],[0.206,0.656],[0.256,0.372],[0.204,0.201],[0.336,0.258],[0.436,0.233],[0.655,0.184],[0.662,0],[0.503,-0.145],[0.332,-0.179],[0,0],[0,0],[0.165,-0.136]],"v":[[6.094,1.465],[4.579,-0.076],[4.242,0.225],[4.124,0.315],[3.43,0.771],[2.439,1.165],[-0.342,1.165],[-1.331,0.771],[-2.027,0.315],[-2.48,-0.075],[-3.087,-0.801],[-3.712,-2.075],[-3.712,-2.075],[-3.934,-3.523],[-6.094,-3.523],[-5.771,-1.424],[-4.868,0.424],[-3.995,1.465],[-3.344,2.027],[-2.35,2.676],[-0.934,3.243],[1.049,3.523],[3.031,3.243],[4.449,2.676],[5.441,2.027],[5.482,1.997],[5.615,1.895]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[26.201,40.411],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-13.398,0],[0,-13.4],[13.398,0],[0,13.4]],"o":[[13.398,0],[0,13.4],[-13.398,0],[0,-13.4]],"v":[[0,-24.3],[24.3,0],[0,24.3],[-24.3,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[14.904,0],[0,-14.904],[-14.904,0],[0,14.904]],"o":[[-14.904,0],[0,14.904],[14.904,0],[0,-14.904]],"v":[[0,-27],[-27,0],[0,27],[27,0]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823529412,0.780392216701,0.980392216701,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[60]},{"t":60,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[27.25,27.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":4,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/packages/SystemUI/res/raw/face_dialog_dark_to_checkmark.json b/packages/SystemUI/res/raw/face_dialog_dark_to_checkmark.json
new file mode 100644
index 0000000..512ca30
--- /dev/null
+++ b/packages/SystemUI/res/raw/face_dialog_dark_to_checkmark.json
@@ -0,0 +1 @@
+{"v":"5.7.13","fr":60,"ip":0,"op":23,"w":68,"h":68,"nm":"face_dialog_dark_to_checkmark","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".green100","cl":"green100","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[34,34,0],"ix":2,"l":2},"a":{"a":0,"k":[30,30,0],"ix":1,"l":2},"s":{"a":0,"k":[106.667,106.667,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-116,-16.5],[-31.25,68.5],[108.75,-71.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.155],"y":[1]},"o":{"x":[0.292],"y":[0]},"t":2,"s":[0]},{"t":16,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.76862745098,0.933333333333,0.81568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[30.1,30.083],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.537,0.537],"y":[1,1]},"o":{"x":[0.333,0.333],"y":[0,0]},"t":2,"s":[8,8]},{"i":{"x":[0.533,0.533],"y":[1,1]},"o":{"x":[0.441,0.441],"y":[0,0]},"t":12,"s":[12.789,12.789]},{"i":{"x":[0.486,0.486],"y":[1,1]},"o":{"x":[0.424,0.424],"y":[0,0]},"t":18,"s":[12.241,12.241]},{"t":22,"s":[12.5,12.5]}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Checkmark","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":23,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".green100","cl":"green100","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[34,34,0],"ix":2,"l":2},"a":{"a":0,"k":[30,30,0],"ix":1,"l":2},"s":{"a":0,"k":[106.667,106.667,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.1,0],[0,-13.2],[-13.1,0],[0,13.2]],"o":[[-13.1,0],[0,13.2],[13.1,0],[0,-13.2]],"v":[[-0.05,-23.8],[-23.75,0],[-0.05,23.8],[23.75,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.768627464771,0.933333337307,0.815686285496,1],"ix":3},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[0]},{"t":7,"s":[100]}],"ix":4},"w":{"a":0,"k":2.5,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[30.05,30],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Outline","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":23,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".blue200","cl":"blue200","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[34,34,0],"ix":2,"l":2},"a":{"a":0,"k":[30,30,0],"ix":1,"l":2},"s":{"a":0,"k":[106.667,106.667,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.1,0],[0,-13.2],[-13.1,0],[0,13.2]],"o":[[-13.1,0],[0,13.2],[13.1,0],[0,-13.2]],"v":[[-0.05,-23.8],[-23.75,0],[-0.05,23.8],[23.75,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.658823529412,0.780392156863,0.980392156863,1],"ix":3},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":2,"s":[100]},{"t":7,"s":[0]}],"ix":4},"w":{"a":0,"k":2.5,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[30.05,30],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Outline","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":23,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".blue200","cl":"blue200","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[34,34,0],"ix":2,"l":2},"a":{"a":0,"k":[30,30,0],"ix":1,"l":2},"s":{"a":0,"k":[106.667,106.667,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[2.6,3.25],[-2.6,3.25],[-2.6,1.25],[0.6,1.25],[0.6,-3.25],[2.6,-3.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823549747,0.780392169952,0.980392158031,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"t":3,"s":[0]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[30.727,31.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.287,0.287],"y":[0.12,0.12]},"t":0,"s":[100,100]},{"t":5,"s":[0,0]}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Nose","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.2],[-1.2,0],[0,1.2],[1.2,0]],"o":[[0,1.2],[1.2,0],[0,-1.2],[-1.2,0]],"v":[[-2.1,0],[0,2.1],[2.1,0],[0,-2.1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823549747,0.780392169952,0.980392158031,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"t":3,"s":[0]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[18.6,23.8],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.4,0.4],"y":[0,0]},"t":0,"s":[100,100]},{"t":5,"s":[0,0]}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eye_L","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.2],[-1.2,0],[0,1.2],[1.2,0]],"o":[[0,1.2],[1.1,0],[0,-1.2],[-1.2,0]],"v":[[-2.1,0],[0,2.1],[2.1,0],[0,-2.1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823549747,0.780392169952,0.980392158031,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"t":3,"s":[0]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[41.1,23.8],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.4,0.4],"y":[0,0]},"t":0,"s":[100,100]},{"t":5,"s":[0,0]}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eye_R\r","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[1.534,0],[0,3.034]],"o":[[-0.996,1.015],[-3.033,0],[0,0]],"v":[[4.705,1.103],[0.787,2.747],[-4.705,-2.747]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":0,"s":[0]},{"t":5,"s":[50]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":0,"s":[100]},{"t":5,"s":[50]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.658823549747,0.780392169952,0.980392158031,1],"ix":3},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[100]},{"t":3,"s":[0]}],"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[30.094,31.756],"ix":2},"a":{"a":0,"k":[1.05,-9.891],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.4,0.4],"y":[0,0]},"t":0,"s":[100,100]},{"t":4,"s":[65,65]}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Mouth","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":23,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/packages/SystemUI/res/raw/face_dialog_dark_to_error.json b/packages/SystemUI/res/raw/face_dialog_dark_to_error.json
new file mode 100644
index 0000000..9578cb4
--- /dev/null
+++ b/packages/SystemUI/res/raw/face_dialog_dark_to_error.json
@@ -0,0 +1 @@
+{"v":"5.7.13","fr":60,"ip":0,"op":20,"w":68,"h":68,"nm":"face_dialog_dark_to_error","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".red100","cl":"red100","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[34,34,0],"ix":2,"l":2},"a":{"a":0,"k":[30,30,0],"ix":1,"l":2},"s":{"a":0,"k":[106.667,106.667,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[2.6,3.25],[-2.6,3.25],[-2.6,1.25],[0.6,1.25],[0.6,-3.25],[2.6,-3.25]],"c":true}]},{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":4,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[0.9,3.25],[-1.5,3.25],[-1.5,1.25],[-1.5,1.25],[-1.5,-3.25],[0.9,-3.25]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":13,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[0.9,3.25],[-1.5,3.25],[-1.5,1.25],[-1.5,1.25],[-1.5,-13.15],[0.9,-13.15]],"c":true}]},{"t":19,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[0.9,3.25],[-1.5,3.25],[-1.5,1.25],[-1.5,1.25],[-1.5,-11.712],[0.9,-11.712]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[0.658823549747,0.780392169952,0.980392158031,1]},{"t":4,"s":[0.949019610882,0.721568644047,0.709803938866,1]}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":4,"s":[30.3,31.45],"to":[0,-0.373],"ti":[0,0.373]},{"t":13,"s":[30.3,29.215]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Nose","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.2],[-1.2,0],[0,1.2],[1.2,0]],"o":[[0,1.2],[1.2,0],[0,-1.2],[-1.2,0]],"v":[[-2.1,0],[0,2.1],[2.1,0],[0,-2.1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823549747,0.780392169952,0.980392158031,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[100]},{"t":4,"s":[0]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[18.6,23.8],"to":[0.568,-0.715],"ti":[-0.568,0.715]},{"t":4,"s":[22.005,19.51]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.999,0.999],"y":[1,1]},"o":{"x":[0.4,0.4],"y":[0,0]},"t":0,"s":[100,100]},{"t":4,"s":[30,30]}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eye_L","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.2],[-1.2,0],[0,1.2],[1.2,0]],"o":[[0,1.2],[1.1,0],[0,-1.2],[-1.2,0]],"v":[[-2.1,0],[0,2.1],[2.1,0],[0,-2.1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823549747,0.780392169952,0.980392158031,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[100]},{"t":4,"s":[0]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[41.1,23.8],"to":[-0.552,-0.712],"ti":[0.552,0.712]},{"t":4,"s":[37.788,19.53]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.999,0.999],"y":[1,1]},"o":{"x":[0.4,0.4],"y":[0,0]},"t":0,"s":[100,100]},{"t":4,"s":[30,30]}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eye_R\r","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[{"i":[[0,0],[1.534,0],[0,3.034]],"o":[[-0.996,1.015],[-3.033,0],[0,0]],"v":[[4.705,1.103],[0.787,2.747],[-4.705,-2.747]],"c":false}]},{"t":13,"s":[{"i":[[0,0],[1.534,0],[1.832,-0.006]],"o":[[-0.948,-0.005],[-3.033,0],[0,0]],"v":[[5.734,-2.889],[0.961,-2.894],[-4.74,-2.887]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":0,"s":[0]},{"t":13,"s":[34]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":0,"s":[100]},{"t":13,"s":[57]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[0.658823549747,0.780392169952,0.980392158031,1]},{"t":4,"s":[0.949019610882,0.721568644047,0.709803938866,1]}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":0,"s":[2]},{"t":13,"s":[2.5]}],"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[29.044,41.646],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Mouth","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.1,0],[0,-13.2],[-13.1,0],[0,13.2]],"o":[[-13.1,0],[0,13.2],[13.1,0],[0,-13.2]],"v":[[-0.05,-23.8],[-23.75,0],[-0.05,23.8],[23.75,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[0.658823549747,0.780392169952,0.980392158031,1]},{"t":4,"s":[0.949019610882,0.721568644047,0.709803938866,1]}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2.5,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[30.05,30],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Outline","np":3,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":4,"op":20,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".blue200","cl":"blue200","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[34,34,0],"ix":2,"l":2},"a":{"a":0,"k":[30,30,0],"ix":1,"l":2},"s":{"a":0,"k":[106.667,106.667,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[2.6,3.25],[-2.6,3.25],[-2.6,1.25],[0.6,1.25],[0.6,-3.25],[2.6,-3.25]],"c":true}]},{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":4,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[0.9,3.25],[-1.5,3.25],[-1.5,1.25],[-1.5,1.25],[-1.5,-3.25],[0.9,-3.25]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"t":13,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[0.9,3.25],[-1.5,3.25],[-1.5,1.25],[-1.5,1.25],[-1.5,-13.15],[0.9,-13.15]],"c":true}]},{"t":19,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[0.9,3.25],[-1.5,3.25],[-1.5,1.25],[-1.5,1.25],[-1.5,-11.712],[0.9,-11.712]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[0.658823549747,0.780392169952,0.980392158031,1]},{"t":4,"s":[0.949019610882,0.721568644047,0.709803938866,1]}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":4,"s":[30.3,31.45],"to":[0,-0.373],"ti":[0,0.373]},{"t":13,"s":[30.3,29.215]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Nose","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.2],[-1.2,0],[0,1.2],[1.2,0]],"o":[[0,1.2],[1.2,0],[0,-1.2],[-1.2,0]],"v":[[-2.1,0],[0,2.1],[2.1,0],[0,-2.1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823549747,0.780392169952,0.980392158031,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[100]},{"t":4,"s":[0]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[18.6,23.8],"to":[0.568,-0.715],"ti":[-0.568,0.715]},{"t":4,"s":[22.005,19.51]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.999,0.999],"y":[1,1]},"o":{"x":[0.4,0.4],"y":[0,0]},"t":0,"s":[100,100]},{"t":4,"s":[30,30]}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eye_L","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.2],[-1.2,0],[0,1.2],[1.2,0]],"o":[[0,1.2],[1.1,0],[0,-1.2],[-1.2,0]],"v":[[-2.1,0],[0,2.1],[2.1,0],[0,-2.1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823549747,0.780392169952,0.980392158031,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[100]},{"t":4,"s":[0]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[41.1,23.8],"to":[-0.552,-0.712],"ti":[0.552,0.712]},{"t":4,"s":[37.788,19.53]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.999,0.999],"y":[1,1]},"o":{"x":[0.4,0.4],"y":[0,0]},"t":0,"s":[100,100]},{"t":4,"s":[30,30]}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eye_R\r","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[{"i":[[0,0],[1.534,0],[0,3.034]],"o":[[-0.996,1.015],[-3.033,0],[0,0]],"v":[[4.705,1.103],[0.787,2.747],[-4.705,-2.747]],"c":false}]},{"t":13,"s":[{"i":[[0,0],[1.534,0],[1.832,-0.006]],"o":[[-0.948,-0.005],[-3.033,0],[0,0]],"v":[[5.734,-2.889],[0.961,-2.894],[-4.74,-2.887]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":0,"s":[0]},{"t":13,"s":[34]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":0,"s":[100]},{"t":13,"s":[57]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[0.658823549747,0.780392169952,0.980392158031,1]},{"t":4,"s":[0.949019610882,0.721568644047,0.709803938866,1]}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":0,"s":[2]},{"t":13,"s":[2.5]}],"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[29.044,41.646],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Mouth","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.1,0],[0,-13.2],[-13.1,0],[0,13.2]],"o":[[-13.1,0],[0,13.2],[13.1,0],[0,-13.2]],"v":[[-0.05,-23.8],[-23.75,0],[-0.05,23.8],[23.75,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[0.658823549747,0.780392169952,0.980392158031,1]},{"t":4,"s":[0.949019610882,0.721568644047,0.709803938866,1]}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2.5,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[30.05,30],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Outline","np":3,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":4,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/packages/SystemUI/res/raw/face_dialog_error_to_idle.json b/packages/SystemUI/res/raw/face_dialog_error_to_idle.json
new file mode 100644
index 0000000..f944314
--- /dev/null
+++ b/packages/SystemUI/res/raw/face_dialog_error_to_idle.json
@@ -0,0 +1 @@
+{"v":"5.7.13","fr":60,"ip":0,"op":14,"w":68,"h":68,"nm":"face_error_to_idle","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".blue200","cl":"blue200","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[34,34,0],"ix":2,"l":2},"a":{"a":0,"k":[30,30,0],"ix":1,"l":2},"s":{"a":0,"k":[106.329,106.329,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.67,"y":1},"o":{"x":0.321,"y":0},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[0.9,3.25],[-1.5,3.25],[-1.5,1.25],[-1.5,1.25],[-1.5,-11.712],[0.9,-11.712]],"c":true}]},{"i":{"x":0.456,"y":1},"o":{"x":0.568,"y":0},"t":5,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[0.9,3.25],[-1.5,3.25],[-1.5,1.25],[-1.5,1.25],[-1.5,-3.25],[0.9,-3.25]],"c":true}]},{"t":13,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[2.6,3.25],[-2.6,3.25],[-2.6,1.25],[0.6,1.25],[0.6,-3.25],[2.6,-3.25]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823549747,0.780392169952,0.980392158031,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[30.3,29.215],"to":[0,0.373],"ti":[0,-0.373]},{"t":9,"s":[30.3,31.45]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Nose","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.2],[-1.2,0],[0,1.2],[1.2,0]],"o":[[0,1.2],[1.2,0],[0,-1.2],[-1.2,0]],"v":[[-2.1,0],[0,2.1],[2.1,0],[0,-2.1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823549747,0.780392169952,0.980392158031,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[0]},{"t":6,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":3,"s":[22.005,19.51],"to":[-0.568,0.715],"ti":[0.568,-0.715]},{"t":13,"s":[18.6,23.8]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.4,0.4],"y":[0,0]},"t":3,"s":[30,30]},{"t":10,"s":[100,100]}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eye_L","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.2],[-1.2,0],[0,1.2],[1.2,0]],"o":[[0,1.2],[1.1,0],[0,-1.2],[-1.2,0]],"v":[[-2.1,0],[0,2.1],[2.1,0],[0,-2.1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823549747,0.780392169952,0.980392158031,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[0]},{"t":6,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":3,"s":[37.788,19.53],"to":[0.552,0.712],"ti":[-0.552,-0.712]},{"t":13,"s":[41.1,23.8]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.4,0.4],"y":[0,0]},"t":3,"s":[30,30]},{"t":10,"s":[100,100]}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eye_R\r","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[{"i":[[0,0],[1.534,0],[1.832,-0.006]],"o":[[-0.948,-0.005],[-3.033,0],[0,0]],"v":[[5.734,-2.889],[0.961,-2.894],[-4.74,-2.887]],"c":false}]},{"t":13,"s":[{"i":[[0,0],[1.534,0],[0,3.034]],"o":[[-0.996,1.015],[-3.033,0],[0,0]],"v":[[4.705,1.103],[0.787,2.747],[-4.705,-2.747]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":0,"s":[34]},{"t":13,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":0,"s":[57]},{"t":13,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[0.949019610882,0.721568644047,0.709803938866,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":6,"s":[0.741176486015,0.75686275959,0.776470601559,1]},{"t":7,"s":[0.658823549747,0.780392169952,0.980392158031,1]}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":0,"s":[2.5]},{"t":13,"s":[2]}],"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[29.044,41.646],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Mouth","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.1,0],[0,-13.2],[-13.1,0],[0,13.2]],"o":[[-13.1,0],[0,13.2],[13.1,0],[0,-13.2]],"v":[[-0.05,-23.8],[-23.75,0],[-0.05,23.8],[23.75,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[0.949019610882,0.721568644047,0.709803938866,1]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":6,"s":[0.741176486015,0.75686275959,0.776470601559,1]},{"t":7,"s":[0.658823549747,0.780392169952,0.980392158031,1]}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2.5,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[30.05,30],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Outline","np":3,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":6,"op":14,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".red100","cl":"red100","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[34,34,0],"ix":2,"l":2},"a":{"a":0,"k":[30,30,0],"ix":1,"l":2},"s":{"a":0,"k":[106.329,106.329,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.67,"y":1},"o":{"x":0.321,"y":0},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[0.9,3.25],[-1.5,3.25],[-1.5,1.25],[-1.5,1.25],[-1.5,-11.712],[0.9,-11.712]],"c":true}]},{"i":{"x":0.456,"y":1},"o":{"x":0.568,"y":0},"t":5,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[0.9,3.25],[-1.5,3.25],[-1.5,1.25],[-1.5,1.25],[-1.5,-3.25],[0.9,-3.25]],"c":true}]},{"t":13,"s":[{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[2.6,3.25],[-2.6,3.25],[-2.6,1.25],[0.6,1.25],[0.6,-3.25],[2.6,-3.25]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[0.949019610882,0.721568644047,0.709803938866,1]},{"t":6,"s":[0.741176486015,0.75686275959,0.776470601559,1]}],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[30.3,29.215],"to":[0,0.373],"ti":[0,-0.373]},{"t":9,"s":[30.3,31.45]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Nose","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.2],[-1.2,0],[0,1.2],[1.2,0]],"o":[[0,1.2],[1.2,0],[0,-1.2],[-1.2,0]],"v":[[-2.1,0],[0,2.1],[2.1,0],[0,-2.1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[0]},{"t":6,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":3,"s":[22.005,19.51],"to":[-0.568,0.715],"ti":[0.568,-0.715]},{"t":13,"s":[18.6,23.8]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.4,0.4],"y":[0,0]},"t":3,"s":[30,30]},{"t":10,"s":[100,100]}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eye_L","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.2],[-1.2,0],[0,1.2],[1.2,0]],"o":[[0,1.2],[1.1,0],[0,-1.2],[-1.2,0]],"v":[[-2.1,0],[0,2.1],[2.1,0],[0,-2.1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[0]},{"t":6,"s":[100]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":3,"s":[37.788,19.53],"to":[0.552,0.712],"ti":[-0.552,-0.712]},{"t":13,"s":[41.1,23.8]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.4,0.4],"y":[0,0]},"t":3,"s":[30,30]},{"t":10,"s":[100,100]}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eye_R\r","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.2,"y":1},"o":{"x":0.4,"y":0},"t":0,"s":[{"i":[[0,0],[1.534,0],[1.832,-0.006]],"o":[[-0.948,-0.005],[-3.033,0],[0,0]],"v":[[5.734,-2.889],[0.961,-2.894],[-4.74,-2.887]],"c":false}]},{"t":13,"s":[{"i":[[0,0],[1.534,0],[0,3.034]],"o":[[-0.996,1.015],[-3.033,0],[0,0]],"v":[[4.705,1.103],[0.787,2.747],[-4.705,-2.747]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":0,"s":[34]},{"t":13,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":0,"s":[57]},{"t":13,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[0.949019610882,0.721568644047,0.709803938866,1]},{"t":6,"s":[0.741176486015,0.75686275959,0.776470601559,1]}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":0,"s":[2.5]},{"t":13,"s":[2]}],"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[29.044,41.646],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Mouth","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.1,0],[0,-13.2],[-13.1,0],[0,13.2]],"o":[[-13.1,0],[0,13.2],[13.1,0],[0,-13.2]],"v":[[-0.05,-23.8],[-23.75,0],[-0.05,23.8],[23.75,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[0.949019610882,0.721568644047,0.709803938866,1]},{"t":6,"s":[0.741176486015,0.75686275959,0.776470601559,1]}],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2.5,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[30.05,30],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Outline","np":3,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":6,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/packages/SystemUI/res/raw/face_dialog_idle_static.json b/packages/SystemUI/res/raw/face_dialog_idle_static.json
new file mode 100644
index 0000000..2d3a7a4
--- /dev/null
+++ b/packages/SystemUI/res/raw/face_dialog_idle_static.json
@@ -0,0 +1 @@
+{"v":"5.7.13","fr":60,"ip":0,"op":14,"w":68,"h":68,"nm":"face_dialog_idle_static","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".blue200","cl":"blue200","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[34,34,0],"ix":2,"l":2},"a":{"a":0,"k":[30,30,0],"ix":1,"l":2},"s":{"a":0,"k":[106.329,106.329,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[2.6,3.25],[-2.6,3.25],[-2.6,1.25],[0.6,1.25],[0.6,-3.25],[2.6,-3.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823549747,0.780392169952,0.980392158031,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[30.3,31.45],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Nose","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.2],[-1.2,0],[0,1.2],[1.2,0]],"o":[[0,1.2],[1.2,0],[0,-1.2],[-1.2,0]],"v":[[-2.1,0],[0,2.1],[2.1,0],[0,-2.1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823549747,0.780392169952,0.980392158031,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[18.6,23.8],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eye_L","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.2],[-1.2,0],[0,1.2],[1.2,0]],"o":[[0,1.2],[1.1,0],[0,-1.2],[-1.2,0]],"v":[[-2.1,0],[0,2.1],[2.1,0],[0,-2.1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823549747,0.780392169952,0.980392158031,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[41.1,23.8],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eye_R\r","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[1.534,0],[0,3.034]],"o":[[-0.996,1.015],[-3.033,0],[0,0]],"v":[[4.705,1.103],[0.787,2.747],[-4.705,-2.747]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.658823549747,0.780392169952,0.980392158031,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[29.044,41.646],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Mouth","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.1,0],[0,-13.2],[-13.1,0],[0,13.2]],"o":[[-13.1,0],[0,13.2],[13.1,0],[0,-13.2]],"v":[[-0.05,-23.8],[-23.75,0],[-0.05,23.8],[23.75,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.658823549747,0.780392169952,0.980392158031,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2.5,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[30.05,30],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Outline","np":3,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":14,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/packages/SystemUI/res/raw/face_dialog_wink_from_dark.json b/packages/SystemUI/res/raw/face_dialog_wink_from_dark.json
new file mode 100644
index 0000000..05b55c9
--- /dev/null
+++ b/packages/SystemUI/res/raw/face_dialog_wink_from_dark.json
@@ -0,0 +1 @@
+{"v":"5.7.13","fr":60,"ip":0,"op":61,"w":68,"h":68,"nm":"face_dialog_wink_from_dark","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".blue200","cl":"blue200","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.5],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.305],"y":[1]},"o":{"x":[0.4],"y":[0]},"t":26,"s":[-14]},{"t":45,"s":[0]}],"ix":10},"p":{"a":0,"k":[30,30,0],"ix":2,"l":2},"a":{"a":0,"k":[30,30,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.2],"y":[1,1,1]},"o":{"x":[0.5,0.5,0.4],"y":[0,0,0]},"t":0,"s":[100,100,100]},{"i":{"x":[0.305,0.305,0.2],"y":[1,1,1]},"o":{"x":[0.4,0.4,0.4],"y":[0,0,0]},"t":26,"s":[106,106,100]},{"t":45,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[2.6,3.25],[-2.6,3.25],[-2.6,1.25],[0.6,1.25],[0.6,-3.25],[2.6,-3.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823549747,0.780392169952,0.980392158031,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[30.727,31.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Nose","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.2],[-1.2,0],[0,1.2],[1.2,0]],"o":[[0,1.2],[1.2,0],[0,-1.2],[-1.2,0]],"v":[[-2.1,0],[0,2.1],[2.1,0],[0,-2.1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823549747,0.780392169952,0.980392158031,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[18.6,23.8],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.4,0.4],"y":[0,0]},"t":0,"s":[100,100]},{"i":{"x":[0.2,0.2],"y":[1,1]},"o":{"x":[0.4,0.4],"y":[0,0]},"t":26,"s":[100,26]},{"t":45,"s":[100,100]}],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eye_L","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-1.2],[-1.2,0],[0,1.2],[1.2,0]],"o":[[0,1.2],[1.1,0],[0,-1.2],[-1.2,0]],"v":[[-2.1,0],[0,2.1],[2.1,0],[0,-2.1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.658823549747,0.780392169952,0.980392158031,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[41.1,23.8],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Eye_R\r","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[1.534,0],[0,3.034]],"o":[[-0.996,1.015],[-3.033,0],[0,0]],"v":[[4.705,1.103],[0.787,2.747],[-4.705,-2.747]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.658823529412,0.780392156863,0.980392156863,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[30.094,31.756],"ix":2},"a":{"a":0,"k":[1.05,-9.891],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Mouth","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":80,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".blue200","cl":"blue200","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[34,34,0],"ix":2,"l":2},"a":{"a":0,"k":[30,30,0],"ix":1,"l":2},"s":{"a":0,"k":[106.329,106.329,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[13.1,0],[0,-13.2],[-13.1,0],[0,13.2]],"o":[[-13.1,0],[0,13.2],[13.1,0],[0,-13.2]],"v":[[-0.05,-23.8],[-23.75,0],[-0.05,23.8],[23.75,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.658823529412,0.780392156863,0.980392156863,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2.5,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[30.05,30],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Outline","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":80,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index c775336..a4b6dea 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> het hierdie skermskoot bespeur."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> en ander oop apps het hierdie skermskoot bespeur."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Voeg by nota"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Sluit skakel in"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Skermopnemer"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Verwerk tans skermopname"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Deurlopende kennisgewing vir \'n skermopnamesessie"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Jy sal ophou om &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; op te neem"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Deel tans skerm"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Jy sal ophou om &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; te deel"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Skerm word tans uitgesaai"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Jy sal ophou om &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uit te saai"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ontsluit met gesig. Druk om voort te gaan."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Gesig is herken. Druk om voort te gaan."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gesig is herken. Druk die ontsluitikoon om voort te gaan."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Ontsluit met gesig. Tik om voort te gaan."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Gestaaf"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Kanselleer stawing"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Meer opsies"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Kenmerke soos Kitsdeel en Kry My Toestel gebruik Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth sal môreoggend aanskakel"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Deel oudio"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Deel tans oudio"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batterykrag"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Oudio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Kopstuk"</string>
@@ -378,7 +383,7 @@
     <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Skermopname"</string>
     <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Begin"</string>
     <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stop"</string>
-    <string name="qs_record_issue_label" msgid="8166290137285529059">"Neem kwessie op"</string>
+    <string name="qs_record_issue_label" msgid="8166290137285529059">"Teken kwessie aan"</string>
     <string name="qs_record_issue_start" msgid="2979831312582567056">"Begin"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"Stop"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Foutverslag"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Voeg meer legstukke by"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Langdruk om legstukke te pasmaak"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Pasmaak legstukke"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Ontsluit om legstukke te pasmaak"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App-ikoon vir gedeaktiveerde legstuk"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Appikoon vir ’n legstuk wat geïnstalleer word"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Wysig legstuk"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"kies legstuk"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"verwyder legstuk"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"plaas gekose legstuk"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Wissel gebruiker"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"aftrekkieslys"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle programme en data in hierdie sessie sal uitgevee word."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Begin nou"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Geen kennisgewings nie"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Geen nuwe kennisgewings nie"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Aanpasbare kennisgewings is aan"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Jou toestel verlaag nou die volume en verminder opspringers op die skerm vir tot twee minute wanneer jy baie kennisgewings in ’n kort tydperk ontvang."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Skakel af"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ontsluit om ouer kennisgewings te sien"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Hierdie toestel word deur jou ouer bestuur"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Jou organisasie besit hierdie toestel en kan netwerkverkeer monitor"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tik vir meer inligting"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Geen wekker nie"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"voer skermslot in"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Raak die vingerafdruksensor. Dis die korter knoppie aan die sykant van die foon"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Vingerafdruksensor"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"staaf"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"gaan by toestel in"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Word gebruik deur <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Onlangs gebruik deur <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Stelsel"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Stelselkontroles"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Stelselapps"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Verrigting van veelvuldige take"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Onlangse apps"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Verdeelde skerm"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Invoer"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Appkortpaaie"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Toeganklikheid"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Gaan terug"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Swiep enige plek op die raakpaneel links of regs met drie vingers om terug te gaan."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Raakpaneel wat drie vingers wat regs en links beweeg wys"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Toestelskerm wat animasie vir teruggebaar wys"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Sleutelbordlig"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Vlak %1$d van %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Huiskontroles"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index de4138f..784d1ab 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ይህን ቅጽበታዊ ገፅ ዕይታ ለይቷል።"</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> እና ሌሎች ክፍት መተግበሪያዎች ይህን ቅጽበታዊ ገፅ ዕይታ ለይተዋል።"</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ወደ ማስታወሻ አክል"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"አገናኝ አካትት"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"የማያ መቅረጫ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"የማያ ገፅ ቀረጻን በማሰናዳት ላይ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ለአንድ የማያ ገፅ ቀረጻ ክፍለ-ጊዜ በመካሄድ ያለ ማሳወቂያ"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"እርስዎ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; መቅረጽ ያቆማሉ"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ማያ ገፅን በማጋራት ላይ"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"እርስዎ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ማጋራት ያቆማሉ"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"ማያ ገፅን Cast በማድረግ ላይ"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"እርስዎ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; cast ማድረግ ያቆማሉ"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"በመልክ ተከፍቷል። ለመቀጠል ይጫኑ።"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"መልክ ተለይቶ ታውቋል። ለመቀጠል ይጫኑ።"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"መልክ ተለይቶ ታውቋል። ለመቀጠል የመክፈቻ አዶውን ይጫኑ።"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"በመልክ ተከፍቷል። ለመቀጠል መታ ያድርጉ።"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"የተረጋገጠ"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ማረጋገጥን ሰርዝ"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ተጨማሪ አማራጮች"</string>
@@ -469,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ተጨማሪ ምግብሮችን ያክሉ"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ምግብሮችን ለማበጀት በረጅሙ ይጫኑ"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ምግብሮችን አብጅ"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ምግብሮችን ለማበጀት ይክፈቱ"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"የመተግበሪያ አዶ ለተሰናከለ ምግብር"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"የምግብር የመተግበሪያ አዶ ሲጫን"</string>
     <string name="edit_widget" msgid="9030848101135393954">"ምግብርን አርትዕ"</string>
@@ -487,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ምግብር ይምረጡ"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ምግብር አስወግድ"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"በቦታ የተመረጠ ምግብር"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ተጠቃሚ ቀይር"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ወደታች ተጎታች ምናሌ"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"በዚህ ክፍለ-ጊዜ ውስጥ ያሉ ሁሉም መተግበሪያዎች እና ውሂብ ይሰረዛሉ።"</string>
@@ -540,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"አሁን ጀምር"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"ምንም ማሳወቂያ የለም"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"ምንም አዲስ ማሳወቂያዎች የሉም"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"ተለማማጅ ማሳወቂያዎች በርተዋል"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"በአጭር የጊዜ ቆይታ ውስጥ ብዙ ማሳወቂያዎች ሲደርሱዎት መሣሪያዎ አሁን ድምፁን ይቀንሳል እና በማያ ገፁ ላይ ብቅ ባዮችን እስከ ሁለት ደቂቃዎች ይቀንሳል።"</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"አጥፋ"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"የቆዩ ማሳወቂያዎችን ለማየት ይክፈቱ"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ይህ መሣሪያ በእርስዎ ወላጅ የሚተዳደር ነው።"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"የእርስዎ ድርጅት የዚህ መሣሪያ ባለቤት ነው፣ እና የአውታረ መረብ ትራፊክን ሊከታተል ይችላል"</string>
@@ -1195,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ለበለጠ መረጃ መታ ያድርጉ"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ምንም ማንቂያ አልተቀናበረም"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"ማያ ገጽ መቆለፊያ ያስገቡ"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"የጣት አሻራ ዳሳሹን ይንኩ። በስልኩ ጎን በኩል አጠር ያለው አዝራር ነው"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"የጣት አሻራ ዳሳሽ"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"ያረጋግጡ"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"መሣሪያን ያስገቡ"</string>
@@ -1336,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"በ<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ጥቅም ላይ እየዋለ ነው"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"በቅርብ ጊዜ በ<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ጥቅም ላይ ውሏል"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"ሥርዓት"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"የሥርዓት መቆጣጠሪያዎች"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"የሥርዓት መተግበሪያዎች"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ብዙ ተግባራትን በተመሳሳይ ጊዜ ማከናወን"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"የቅርብ ጊዜ መተግበሪያዎች"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"የተከፈለ ማያ ገፅ"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"ግብዓት"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"የመተግበሪያ አቋራጮች"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ተደራሽነት"</string>
@@ -1353,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ወደኋላ ተመለስ"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ወደኋላ ለመመለስ በመዳሰሻ ሰሌዳው ላይ በየትኛውም ቦታ ሦስት ጣቶችን በመጠቀም ወደግራ ወይም ወደቀኝ ያንሸራትቱ።"</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ሦስት ጣቶች ወደቀኝ እና ግራ ሲንቀሳቀሱ የሚያሳይ የመዳሰሻ ሰሌዳ"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"የኋላ ምልክት እነማ የሚያሳይ የመሣሪያ ማያ ገፅ"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"የቁልፍ ሰሌዳ የጀርባ ብርሃን"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"ደረጃ %1$d ከ %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"የቤት ውስጥ ቁጥጥሮች"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 8bd52d6..3a8b063 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"رصَد تطبيق \"<xliff:g id="APPNAME">%1$s</xliff:g>\" لقطة الشاشة هذه."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"رصَد تطبيق \"<xliff:g id="APPNAME">%1$s</xliff:g>\" والتطبيقات المفتوحة الأخرى لقطة الشاشة هذه."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"إضافة إلى الملاحظة"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"تضمين الرابط"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"مسجّل الشاشة"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"جارٍ معالجة تسجيل الشاشة"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"إشعار مستمر لجلسة تسجيل شاشة"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"‏سيتم إيقاف تسجيل محتوى &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"جارِ مشاركة محتوى الشاشة"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"‏سيتم إيقاف مشاركة محتوى &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"جارٍ بثّ محتوى الشاشة"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"‏سيتم إيقاف بث محتوى &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"تم فتح الجهاز بالتعرّف على وجهك. اضغط للمتابعة."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"تم التعرّف على الوجه. اضغط للمتابعة."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"تم التعرّف على الوجه. للمتابعة، اضغط على رمز فتح القفل."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"تمّ فتح قفل جهازك باستخدام بصمة الوجه. انقر للمتابعة."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"مصادقة"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"إلغاء المصادقة"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"مزيد من الخيارات"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"‏يُستخدَم البلوتوث في ميزات مثل Quick Share و\"العثور على جهازي\""</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"سيتم تفعيل البلوتوث صباح الغد"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"مشاركة الصوت"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"جارٍ مشاركة الصوت"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"إضافة المزيد من التطبيقات المصغّرة"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"اضغط مع الاستمرار لتخصيص التطبيقات المصغّرة."</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"تخصيص التطبيقات المصغَّرة"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"يجب فتح القفل لتخصيص التطبيقات المصغّرة"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"رمز التطبيق المصغّر غير المفعّل"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"رمز تطبيق مصغَّر جارٍ تثبيته"</string>
     <string name="edit_widget" msgid="9030848101135393954">"تعديل التطبيق المصغَّر"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"اختيار التطبيق المصغّر"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"إزالة التطبيق المصغّر"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"إضافة التطبيق المصغّر المحدَّد"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"تبديل المستخدم"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"القائمة المنسدلة"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"سيتم حذف كل التطبيقات والبيانات في هذه الجلسة."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"البدء الآن"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"ما مِن إشعارات"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"ما مِن إشعارات جديدة"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"\"الإشعارات التكيّفية\" مفعَّلة"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"عند تلقّي إشعارات متعددة في فترة زمنية قصيرة، يخفِّض جهازك الصوت ويقلّل من ظهور النوافذ المنبثقة على الشاشة لمدة تصل إلى دقيقتين."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"إيقاف"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"افتَح قفل الشاشة لعرض الإشعارات الأقدم."</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"يتولّى أحد الوالدين إدارة هذا الجهاز."</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"تملك مؤسستك هذا الجهاز ويمكنها تتبّع حركة بيانات الشبكة."</string>
@@ -783,7 +798,7 @@
     <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"البحث في الاختصارات"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"لم يُعثَر على اختصارات."</string>
     <string name="keyboard_shortcut_search_category_system" msgid="1151182120757052669">"النظام"</string>
-    <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"إدخال"</string>
+    <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"الإدخال"</string>
     <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"فتح التطبيقات"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"التطبيق الحالي"</string>
     <string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"جارٍ عرض نتائج البحث"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"انقر للحصول على مزيد من المعلومات."</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"لم يتم ضبط منبّه"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"إدخال الرمز لفتح القفل"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"المس أداة استشعار بصمة الإصبع المدمَجة في الزر الأقصر في جانب الهاتف"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"مستشعر بصمات الإصبع"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"المصادقة"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"الدخول إلى الجهاز"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"قيد الاستخدام في <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"تم الاستخدام مؤخرًا في <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"النظام"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"عناصر التحكّم في النظام"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"تطبيقات النظام"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"تعدُّد المهام"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"التطبيقات المستخدمة مؤخرًا"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"تقسيم الشاشة"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"الإدخال"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"اختصارات التطبيقات"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"تسهيل الاستخدام"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"رجوع"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"للرجوع، مرِّر سريعًا لليسار أو لليمين باستخدام ثلاثة أصابع في أي مكان على لوحة اللمس."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"لوحة لمس تعرض ثلاثة أصابع تتحرك يمينًا ويسارًا"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"شاشة جهاز تعرض صورة متحركة لإيماءة الرجوع"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"الإضاءة الخلفية للوحة المفاتيح"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"‏مستوى الإضاءة: %1$d من %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"إدارة المنزل آليًّا"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 77774cc..53241dd 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>এ এই স্ক্ৰীনশ্বটটো চিনাক্ত কৰিছে।"</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> আৰু আন খোলা এপ্‌সমূহে এই স্ক্ৰীনশ্বটটো চিনাক্ত কৰিছে।"</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"টোকাত যোগ দিয়ক"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"লিংক অন্তৰ্ভুক্ত কৰক"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"স্ক্ৰীন ৰেকৰ্ডাৰ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"স্ক্রীন ৰেকৰ্ডিঙৰ প্ৰক্ৰিয়াকৰণ হৈ আছে"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"স্ক্রীন ৰেকৰ্ডিং ছেশ্বন চলি থকা সময়ত পোৱা জাননী"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"আপুনি &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ৰেকৰ্ড কৰা বন্ধ কৰিব"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"স্ক্ৰীন শ্বেয়াৰ কৰি থকা হৈছে"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"আপুনি &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; শ্বেয়াৰ কৰা বন্ধ কৰিব"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"স্ক্ৰীন কাষ্ট কৰি থকা হৈছে"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"আপুনি &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; কাষ্ট কৰা বন্ধ কৰিব"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। অব্যাহত ৰাখিবলৈ টিপক।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। অব্যাহত ৰাখিবলৈ টিপক।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। অব্যাহত ৰাখিবলৈ আনলক কৰক চিহ্নটোত টিপক।"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"মুখাৱয়বৰ জৰিয়তে আনলক কৰা হৈছে। অব্যাহত ৰাখিবলৈ টিপক।"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ বাতিল কৰক"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"অধিক বিকল্প"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share আৰু Find My Deviceৰ দৰে সুবিধাসমূহে ব্লুটুথ ব্যৱহাৰ কৰে"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"কাইলৈ পুৱা ব্লুটুথ অন হ’ব"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"অডিঅ’ শ্বেয়াৰ কৰক"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"অডিঅ’ শ্বেয়াৰ কৰি থকা হৈছে"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"অধিক ৱিজেট যোগ দিয়ক"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ৱিজেট কাষ্টমাইজ কৰিবলৈ দীঘলীয়াকৈ টিপক"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ৱিজেট কাষ্টমাইজ কৰক"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ৱিজেট কাষ্টমাইজ কৰিবলৈ আনলক কৰক"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"অক্ষম কৰা ৱিজেটৰ বাবে এপৰ চিহ্ন"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ইনষ্টল কৰি থকা এটা ৱিজেটৰ বাবে এপৰ চিহ্ন"</string>
     <string name="edit_widget" msgid="9030848101135393954">"ৱিজেট সম্পাদনা কৰক"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ৱিজেট বাছনি কৰক"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ৱিজেট আঁতৰাওক"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"বাছনি কৰা ৱিজেটটো ৰাখক"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ব্যৱহাৰকাৰী সলনি কৰক"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"পুল-ডাউনৰ মেনু"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই ছেশ্বনৰ আটাইবোৰ এপ্ আৰু ডেটা মচা হ\'ব।"</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"এতিয়াই আৰম্ভ কৰক"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"কোনো জাননী নাই"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"কোনো নতুন জাননী নাই"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"অভিযোজিত জাননী অন কৰা আছে"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"আপোনাৰ ডিভাইচে এতিয়া ভলিউম কমায়, কম সময়ৰ ভিতৰত বহুতো জাননী পালে ২ মিনিটলৈকে স্ক্ৰীনত ওলোৱা পপ-আপ কমায়।"</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"অফ কৰক"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"পুৰণি জাননী চবলৈ আনলক কৰক"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"এই ডিভাইচটো আপোনাৰ অভিভাৱকে পৰিচালনা কৰে"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"এই ডিভাইচটোৰ গৰাকী আপোনাৰ প্ৰতিষ্ঠান আৰু ই নেটৱৰ্কৰ ট্ৰেফিক নিৰীক্ষণ কৰিব পাৰে"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"অধিক তথ্যৰ বাবে টিপক"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"কোনো এলাৰ্ম ছেট কৰা হোৱা নাই"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"স্ক্ৰীন লকটো দিয়ক"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো স্পৰ্শ কৰক। এইটো হৈছে আপোনাৰ ফ’নটোৰ কাষৰফালে থকা চুটি বুটামটো"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰ"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"বিশ্বাসযোগ্যতা প্ৰমাণ কৰক"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"ডিভাইচ আনলক কৰক"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)এ ব্যৱহাৰ কৰি আছে"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"শেহতীয়াকৈ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)এ ব্যৱহাৰ কৰিছে"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"ছিষ্টেম"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ছিষ্টেমৰ নিয়ন্ত্ৰণ"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"ছিষ্টেম এপ্‌"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"মাল্টিটাস্কিং"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"শেহতীয়া এপ্‌সমূহ"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"বিভাজিত স্ক্ৰীন"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"ইনপুট"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"এপ্ শ্বৰ্টকাটসমূহ"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"সাধ্য সুবিধা"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"উভতি যাওক"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"উভতি যাবলৈ, টাচ্চপেডৰ যিকোনো স্থানত তিনিটা আঙুলি ব্যৱহাৰ কৰি বাওঁ বা সোঁফালে ছোৱাইপ কৰক।"</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"তিনিটা আঙুলি সোঁ আৰু বাওঁফালে লৰচৰ কৰা দেখুওৱা টাচ্চপেড"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"পিছফালৰ নিৰ্দেশৰ এনিমেশ্বন দেখুওৱা ডিভাইচ স্ক্ৰীন"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"কীব’ৰ্ডৰ বেকলাইট"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dৰ %1$d স্তৰ"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ঘৰৰ সা-সৰঞ্জামৰ নিয়ন্ত্ৰণ"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index bf24c07..7fd21bf 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> bu skrinşotu aşkarladı."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> və digər açıq tətbiqlər bu skrinşotu aşkarladı."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Qeydə əlavə edin"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Keçid daxil edin"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Ekran yazıcısı"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran çəkilişi emal edilir"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekranın video çəkimi ərzində silinməyən bildiriş"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tətbiqinin çəkilməsini dayandıracaqsınız"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekran paylaşılır"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tətbiqinin paylaşılmasını dayandıracaqsınız"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Ekran yayımlanır"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tətbiqinin yayımlanmasını dayandıracaqsınız"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Üz ilə kiliddən çıxarılıb. Davam etmək üçün basın."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Üz tanınıb. Davam etmək üçün basın."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Üz tanınıb. \"Kiliddən çıxar\" ikonasına basıb davam edin."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Üz ilə kiliddən çıxarılıb. Davam etmək üçün toxunun."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Doğrulandı"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"İdentifikasiyanı ləğv edin"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Digər seçimlər"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Cəld Paylaşım və Cihazın Tapılması kimi funksiyalar Bluetooth istifadə edir"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth sabah səhər aktiv ediləcək"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Audio paylaşın"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Audio paylaşılır"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batareya"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Qulaqlıq"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Vidcetlər əlavə edin"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Basıb saxlayaraq vidcetləri fərdiləşdirin"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Vidcetləri fərdiləşdirin"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Vidcetləri fərdiləşdirmək üçün kiliddən çıxarın"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Deaktiv edilmiş vidcet üçün tətbiq ikonası"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Quraşdırılan vidcet üçün tətbiq ikonası"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Vidceti redaktə edin"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vidcet seçin"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"vidceti silin"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"seçilmiş vidceti yerləşdirin"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"aşağı çəkilən menyu"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu sessiyada bütün tətbiqlər və data silinəcək."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"İndi başlayın"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Heç bir bildiriş yoxdur"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Yeni bildiriş yoxdur"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptiv bildirişlər aktivdir"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Qısa vaxtda çoxlu bildiriş alanda cihaz səsi azaldır, ekranda popapları iki dəqiqəyə qədər qısaldır."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Deaktiv edin"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Köhnə bildirişləri görmək üçün kilidi açın"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Bu cihaz valideyniniz tərəfindən idarə olunur"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Təşkilatınız bu cihazın sahibidir və şəbəkə trafikinə nəzarət edə bilər"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ətraflı məlumat üçün toxunun"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Siqnal ayarlanmayıb"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"ekran kilidi daxil edin"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Barmaq izi sensoruna toxunun. Telefonun yan tərəfindəki qısa düymədir"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Barmaq izi sensoru"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"doğrulayın"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"cihaz daxil edin"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) istifadə edir"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Bu yaxınlarda <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) istifadə edib"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistem nizamlayıcıları"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistem tətbiqləri"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Çoxsaylı tapşırıq icrası"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Son tətbiqlər"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Bölünmüş ekran"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Daxiletmə"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Tətbiq qısayolları"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Xüsusi imkanlar"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Geri qayıdın"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Geri qayıtmaq üçün taçpedin istənilən yerində üç barmaqla sola və ya sağa çəkin."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Üç barmağın sağa və sola hərəkət etdiyini göstərən taçped"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Geri jesti üçün animasiya göstərən cihaz ekranı"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatura işığı"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Səviyyə %1$d/%2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Ev nizamlayıcıları"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 02271f0..3b34af8 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> je otkrila ovaj snimak ekrana."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> i druge otvorene aplikacije su otkrile ovaj snimak ekrana."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj u belešku"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Uvrsti link"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Snimač ekrana"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrađujemo video snimka ekrana"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Obaveštenje o sesiji snimanja ekrana je aktivno"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Zaustavićete snimanje za: &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekran se deli"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Zaustavićete deljenje za: &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Prebacuje se ekran"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Zaustavićete prebacivanje za: &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano je licem. Pritisnite da biste nastavili."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice je prepoznato. Pritisnite da biste nastavili."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice prepoznato. Pritisnite ikonu otključavanja za nastavak."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Otključano je licem. Dodirnite da biste nastavili."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Identitet je potvrđen"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Otkažite potvrdu identiteta"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Još opcija"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funkcije kao što su Quick Share i Pronađi moj uređaj koriste Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth će se uključiti sutra ujutru"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Deli zvuk"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Deli se zvuk"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Nivo baterije je <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Slušalice"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodajte još vidžeta"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Dugi pritisak za prilagođavanje vidžeta"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagodi vidžete"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Otključajte da biste prilagodili vidžete"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacije za onemogućen vidžet"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona aplikacije za vidžet koji se instalira"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Izmeni vidžet"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"izaberite vidžet"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"uklonite vidžet"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"postavite izabrani vidžet"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zameni korisnika"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući meni"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci u ovoj sesiji će biti izbrisani."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Započni"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nema obaveštenja"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Nema novih obaveštenja"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Prilag. obaveštenja su uključena"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Uređaj sada smanjuje zvuk i broj iskačućih prozora na ekranu do 2 minuta kad primite mnogo obaveštenja u kratkom roku."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Isključi"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Otključajte za starija obaveštenja"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja roditelj"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizacija je vlasnik uređaja i može da nadgleda mrežni saobraćaj"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nije podešen"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"unesite otključavanje ekrana"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Dodirnite senzor za otisak prsta. To je kraće dugme na bočnoj strani telefona"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Senzor za otisak prsta"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"potvrdite identitet"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"unesite uređaj"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Koriste <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nedavno koristila aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistemske kontrole"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistemske aplikacije"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Obavljanje više zadataka istovremeno"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nedavne aplikacije"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Podeljeni ekran"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Unos"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Prečice za aplikacije"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Nazad"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Da biste se vratili, prevucite ulevo ili udesno sa tri prsta bilo gde na tačpedu."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Tačped sa prikazom tri prsta koji se pomeraju udesno i ulevo"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Ekran uređaja sa prikazom animacije pokreta za nazad"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvetljenje tastature"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. nivo od %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrole za dom"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index ed44819..87f5bf1 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"Праграма \"<xliff:g id="APPNAME">%1$s</xliff:g>\" выявіла гэты здымак экрана."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> і іншыя адкрытыя праграмы выявілі гэты здымак экрана."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Дадаць у нататку"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Дадаць спасылку"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Запіс экрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Апрацоўваецца запіс экрана"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Бягучае апавяшчэнне для сеанса запісу экрана"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Запіс з праграмы &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; будзе спынены"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Экран абагульваецца"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Абагульванне з праграмы &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; будзе спынена"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Экран трансліруецца"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Трансляцыя праграмы &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; будзе спынена"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Разблакіравана распазнаваннем твару. Націсніце для працягу."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Твар распазнаны. Націсніце для працягу."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Твар распазнаны. Для працягу націсніце значок разблакіроўкі."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Твар распазнаны. Націсніце, каб працягнуць."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Распазнана"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Скасаваць аўтэнтыфікацыю"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Іншыя варыянты"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Bluetooth выкарыстоўваецца такімі функцыямі і сэрвісамі, як Хуткае абагульванне і Знайсці прыладу"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth уключыцца заўтра раніцай"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Абагуліць аўдыя"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Ідзе абагульванне аўдыя"</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>
@@ -379,7 +384,7 @@
     <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Пачаць"</string>
     <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Спыніць"</string>
     <string name="qs_record_issue_label" msgid="8166290137285529059">"Запіс праблемы"</string>
-    <string name="qs_record_issue_start" msgid="2979831312582567056">"Пачынайце"</string>
+    <string name="qs_record_issue_start" msgid="2979831312582567056">"Пачаць"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"Спыніцеся"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Справаздача"</string>
     <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"З чым была звязана праблема, якая вам сустрэлася?"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Дадаць іншыя віджэты"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Доўга націскайце, каб наладзіць віджэты"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Наладзіць віджэты"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Разблакіруйце, каб наладзіць віджэты"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Значок праграмы для адключанага віджэта"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Значок праграмы для віджэта ў працэсе ўсталявання"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Змяніць віджэт"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"выбраць віджэт"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"выдаліць віджэт"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"размясціць выбраны віджэт"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Перайсці да іншага карыстальніка"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"высоўнае меню"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усе праграмы і даныя гэтага сеанса будуць выдалены."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Пачаць зараз"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Апавяшчэнняў няма"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Няма новых апавяшчэнняў"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Адаптыўныя апавяшчэнні ўключаны"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Пры атрыманні шматлікіх апавяшчэнняў за кароткі час прылада памяншае гучнасць і колькасць усплывальных вокнаў на 2 хв."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Выключыць"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Разблакіруйце, каб убачыць усе апавяшчэнні"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Гэта прылада знаходзіцца пад кантролем бацькоў"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ваша арганізацыя валодае гэтай прыладай і можа кантраляваць сеткавы трафік"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Націсніце, каб убачыць больш"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Няма будзільнікаў"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"прыступіць да разблакіроўкі экрана"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Дакраніцеся да сканера адбіткаў пальцаў. Гэта кароткая кнопка на баку вашага тэлефона"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сканер адбіткаў пальцаў"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"правесці аўтэнтыфікацыю"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"адкрыць галоўны экран прылады"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Зараз выкарыстоўваецца праграмай \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Нядаўна выкарыстоўваўся праграмай \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Сістэма"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Элементы кіравання сістэмай"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Сістэмныя праграмы"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Шматзадачнасць"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Нядаўнія праграмы"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Падзелены экран"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Увод"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Ярлыкі праграм"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Спецыяльныя магчымасці"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Каб вярнуцца на папярэдні экран, правядзіце трыма пальцамі ўлева або ўправа ў любым месцы сэнсарнай панэлі."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Паказваецца, як на сэнсарнай панэлі тры пальцы рухаюцца ўправа і ўлева"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"На экране прылады паказваецца анімацыя жэста \"Назад\""</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Падсветка клавіятуры"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Узровень %1$d з %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Кіраванне домам"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index b88e0e4..1e4bf0c 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> установи заснемането на тази екранна снимка."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> и други отворени приложения установиха заснемането на тази екранна снимка."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Добавяне към бележката"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Включване на връзката"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Запис на екрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Записът на екрана се обработва"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Текущо известие за сесия за записване на екрана"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Ще спрете да записвате &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Екранът се споделя"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Ще спрете да споделяте &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Екранът се предава"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Ще спрете да предавате &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Отключено с лице. Натиснете, за да продължите."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лицето бе разпознато. Натиснете, за да продължите."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицето бе разпознато. Продължете чрез иконата за отключване."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Отключено с лице. Докоснете, за да продължите."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Удостоверено"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Анулиране на удостоверяването"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Още опции"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Функции като „Бързо споделяне“ и „Намиране на устройството ми“ използват Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ще се включи утре сутрин"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Споделяне на звука"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Звукът се споделя"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Добавете още приспособления"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Натиснете продължително за персонализ. на приспос."</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Персонализиране на приспособленията"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Отключете, за да персонализирате приспособленията"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Икона на приложение за деактивирано приспособление"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Икона на приложение, чието приспособление се инсталира"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Редактиране на приспособлението"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"избиране на приспособление"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"премахване на приспособлението"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"поставяне на избраното приспособление"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Превключване между потребителите"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"падащо меню"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Всички приложения и данни в тази сесия ще бъдат изтрити."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Стартиране сега"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Няма известия"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Няма нови известия"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Адаптивните известия са вкл."</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"У-вото ви намалява силата на звука и броя на изскачащите прозорци за период до 2 мин, ако получавате много известия за кратко време."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Изключване"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Отключете за достъп до по-стари известия"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Това устройство се управлява от родителя ви"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организацията ви притежава това устройство и може да наблюдава трафика в мрежата"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Докоснете за още информация"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Няма зададен будилник"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"въведете опция за заключване на екрана"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Докоснете сензора за отпечатъци. Това е по-късият бутон отстрани на телефона"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сензор за отпечатъци"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"удостоверяване"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"вход в устройството"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Използва се от <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Наскоро използвано от <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Системни"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Системни контроли"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системни приложения"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Изпълняване на няколко задачи едновременно"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Скорошни приложения"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Разделен екран"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Въвеждане"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Преки пътища към приложения"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Достъпност"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"За да се върнете назад, прекарайте три пръста наляво или надясно по сензорния панел."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Сензорен панел, върху който три пръста се движат надясно и наляво"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Екран на устройство, показващ анимация за жеста за връщане назад"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Подсветка на клавиатурата"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Ниво %1$d от %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Контроли за дома"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 0e44b3c..b7439ca 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>, এই স্ক্রিনশট শনাক্ত করেছে।"</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> এবং খোলা থাকা অন্য অ্যাপ এই স্ক্রিনশট শনাক্ত করেছে।"</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"নোটে যোগ করুন"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"লিঙ্ক যোগ করুন"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"স্ক্রিন রেকর্ডার"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"স্ক্রিন রেকর্ডিং প্রসেস হচ্ছে"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"স্ক্রিন রেকর্ডিং সেশন চলার বিজ্ঞপ্তি"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"এটির জন্য &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; অ্যাপের কন্টেন্ট রেকর্ড হওয়া বন্ধ হয়ে যাবে"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"স্ক্রিন শেয়ার করা হচ্ছে"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"এটির জন্য &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; অ্যাপের কন্টেন্ট শেয়ার করা বন্ধ হয়ে যাবে"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"স্ক্রিন কাস্ট করা হচ্ছে"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"এটির জন্য &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; অ্যাপের কন্টেন্ট কাস্ট হওয়া বন্ধ হয়ে যাবে"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ফেসের সাহায্যে আনলক করা হয়েছে। চালিয়ে যেতে প্রেস করুন।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ফেস শনাক্ত করা হয়েছে। চালিয়ে যেতে প্রেস করুন।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ফেস শনাক্ত করা হয়েছে। চালিয়ে যেতে আনলক আইকন প্রেস করুন।"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"ফেসের সাহায্যে আনলক করা হয়েছে। চালিয়ে যেতে ট্যাপ করুন।"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"প্রমাণীকৃত"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"যাচাইকরণ বাতিল করুন"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"আরও বিকল্প"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"দ্রুত শেয়ার ও Find My Device-এর মতো ফিচার ব্লুটুথ ব্যবহার করে"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ব্লুটুথ আগামীকাল সকালে চালু হয়ে যাবে"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"অডিও শেয়ার করুন"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"অডিও শেয়ার করা হচ্ছে"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"আরও উইজেট যোগ করুন"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"উইজেট কাস্টমাইজ করতে বেশিক্ষণ প্রেস করুন"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"উইজেট কাস্টমাইজ করুন"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"উইজেট কাস্টমাইজ করতে আনলক করুন"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"বন্ধ করা উইজেটের জন্য অ্যাপের আইকন"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ইনস্টল করা হচ্ছে এমন উইজেটের অ্যাপ আইকন"</string>
     <string name="edit_widget" msgid="9030848101135393954">"উইজেট এডিট করুন"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"উইজেট বেছে নিন"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"উইজেট সরান"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"বেছে নেওয়া উইজেটটি রাখুন"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ব্যবহারকারী পাল্টে দিন"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"পুলডাউন মেনু"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"এই সেশনের সব অ্যাপ ও ডেটা মুছে ফেলা হবে।"</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"এখন শুরু করুন"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"কোনও বিজ্ঞপ্তি নেই"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"নতুন কোনও বিজ্ঞপ্তি নেই"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"অ্যাডাপ্টিভ বিজ্ঞপ্তি চালু আছে"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"অল্প সময়ে অনেক বেশি বিজ্ঞপ্তি পেলে, আপনার ডিভাইস এখন ২ মিনিটের জন্য ভলিউম ও স্ক্রিনে আসা পপ-আপ কমায়।"</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"বন্ধ করুন"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"পুরনো বিজ্ঞপ্তি দেখতে আনলক করুন"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"আপনার অভিভাবক এই ডিভাইস ম্যানেজ করেন"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"এই ডিভাইসটি আপনার প্রতিষ্ঠানের এবং এরা ডিভাইসের নেটওয়ার্ক ট্রাফিক মনিটর করতে পারে"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"আরও তথ্যের জন্য ট্যাপ করুন"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"কোনও অ্যালার্ম সেট করা নেই"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"স্ক্রিন লক খুলুন"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ফিঙ্গারপ্রিন্ট সেন্সর টাচ করুন। এটি ফোনের পাশের দিকে থাকা তুলনামূলক ছোট বোতাম"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ফিঙ্গারপ্রিন্ট সেন্সর"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"যাচাই করিয়ে নিন"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"ডিভাইস আনলক করুন"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপে (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ব্যবহার করা হচ্ছে"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"সম্প্রতি <xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপে (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ব্যবহার করা হয়েছে"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"সিস্টেম"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"সিস্টেম কন্ট্রোল"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"সিস্টেম অ্যাপ"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"মাল্টিটাস্কিং"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"সম্প্রতি ব্যবহার করা অ্যাপ"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"স্প্লিট স্ক্রিন"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"ইনপুট"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"অ্যাপ শর্টকাট"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"অ্যাক্সেসিবিলিটি"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ফিরে যান"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ফিরে যেতে, টাচপ্যাডের যেকোনও জায়গায় তিনটি আঙুল দিয়ে ডান বা বাঁদিকে সোয়াইপ করুন।"</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"টাচপ্যাডে, তিনটি আঙুল ডান ও বাঁদিকে সরানো দেখানো হচ্ছে"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"ডিভাইসের স্ক্রিনে ফিরে যাওয়ার জেসচারের অ্যানিমেশন দেখানো হচ্ছে"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"কীবোর্ড ব্যাকলাইট"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d-এর মধ্যে %1$d লেভেল"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"হোম কন্ট্রোল"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index a7f9068..d187843 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> je otkrila ovaj snimak ekrana."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> i druge otvorene aplikacije su otkrile ovaj snimak ekrana."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj u bilješku"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Uključi link"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Snimač ekrana"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrađivanje snimka ekrana"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Obavještenje za sesiju snimanja ekrana je u toku"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Zaustavit ćete snimanje aplikacije &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Dijeljenje ekrana"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Zaustavit ćete dijeljenje aplikacije &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Emitiranje ekrana"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Zaustavit ćete emitiranje aplikacije &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano licem. Pritisnite da nastavite."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice prepoznato. Pritisnite da nastavite."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice prepoznato. Pritisnite ikonu za otklj. da nastavite."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Otključano je licem. Dodirnite da nastavite."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentificirano"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Otkažite autentifikaciju"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Više opcija"</string>
@@ -304,7 +311,7 @@
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funkcije kao što su Quick Share i Pronađi moj uređaj koriste Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth će se uključiti sutra ujutro"</string>
     <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Dijeli zvuk"</string>
-    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Zajedničko slušanje"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Dijeljenje zvuka"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> baterije"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Zvuk"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Slušalice"</string>
@@ -376,7 +383,7 @@
     <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Snimanje ekrana"</string>
     <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Započnite"</string>
     <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Zaustavite"</string>
-    <string name="qs_record_issue_label" msgid="8166290137285529059">"Snimite problem"</string>
+    <string name="qs_record_issue_label" msgid="8166290137285529059">"Zabilježite problem"</string>
     <string name="qs_record_issue_start" msgid="2979831312582567056">"Pokrenite"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"Zaustavite"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Izvještaj o grešci"</string>
@@ -469,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodajte još vidžeta"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pritisnite i zadržite da prilagodite vidžete"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagodite vidžete"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Otključajte da prilagodite vidžete"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacije za onemogućeni vidžet"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona aplikacije za vidžet koji se instalira"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Uredite vidžet"</string>
@@ -487,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"odabir vidžeta"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"uklanjanje vidžeta"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"postavljanje odabranog vidžeta"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Zamijeni korisnika"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući meni"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Sve aplikacije i podaci iz ove sesije će se izbrisati."</string>
@@ -540,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Započni odmah"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nema obavještenja"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Nema novih obavještenja"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Prilagodljiva obavještenja su uključena"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Uređaj smanjuje jačinu zvuka i broj skočnih prozora na ekranu do dvije minute kada dobijate mnogo obavještenja unutar kratkog vremenskog raspona."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Isključi"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Otključajte da vidite starija obavještenja"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja tvoj roditelj"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša organizacija je vlasnik ovog uređaja i može nadzirati mrežni saobraćaj"</string>
@@ -778,7 +795,7 @@
     <string name="keyboard_shortcut_join" msgid="3578314570034512676">"ili"</string>
     <string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"Brisanje upita za pretraživanje"</string>
     <string name="keyboard_shortcut_search_list_title" msgid="4271769465397671138">"Prečice na tastaturi"</string>
-    <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Pretraživanje prečica"</string>
+    <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Pretražite prečice"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Nisu pronađene prečice"</string>
     <string name="keyboard_shortcut_search_category_system" msgid="1151182120757052669">"Sistem"</string>
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Unos"</string>
@@ -1195,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nema nijednog alarma"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"unos zaključavanja ekrana"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Dodirnite senzor za otisak prsta. To je kraće dugme na bočnoj strani telefona"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Senzor za otisak prsta"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentificiranje"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"pristup uređaju"</string>
@@ -1336,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Koristi aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nedavno je koristila aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistemske kontrole"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistemske aplikacije"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nedavne aplikacije"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Podijeljeni ekran"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Unos"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Prečice aplikacije"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
@@ -1353,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Nazad"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Da se vratite, prevucite ulijevo ili udesno s tri prsta bilo gdje na dodirnoj podlozi."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Dodirna podloga prikazuje tri prsta koji se pomjeraju desno-lijevo"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Ekran uređaja pokazuje animaciju pokreta unazad"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvjetljenje tastature"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. nivo od %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrole za dom"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 4f055d4..13203df 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ha detectat aquesta captura de pantalla."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> i altres aplicacions obertes han detectat aquesta captura de pantalla."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Afegeix a una nota"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Inclou l\'enllaç"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Gravació de pantalla"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processant gravació de pantalla"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificació en curs d\'una sessió de gravació de la pantalla"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Deixaràs de gravar &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"S\'està compartint la pantalla"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Deixaràs de compartir &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"S\'està emetent la pantalla"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Deixaràs d\'emetre &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"S\'ha desbloquejat amb la cara. Prem per continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"S\'ha reconegut la cara. Prem per continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"S\'ha reconegut la cara. Prem la icona per continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"S\'ha desbloquejat amb la cara. Toca per continuar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticat"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel·la l\'autenticació"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Més opcions"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Les funcions com Quick Share i Troba el meu dispositiu utilitzen el Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"El Bluetooth s\'activarà demà al matí"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Comparteix l\'àudio"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"S\'està compartint l\'àudio"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de bateria"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Àudio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auriculars"</string>
@@ -382,7 +387,7 @@
     <string name="qs_record_issue_start" msgid="2979831312582567056">"Inicia"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"Atura"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Informe d\'errors"</string>
-    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"L\'experiència amb el dispositiu s\'ha vist afectada?"</string>
+    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Quina part de l\'experiència s\'ha vist afectada?"</string>
     <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Selecciona el tipus de problema"</string>
     <string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Gravació de pantalla"</string>
     <string name="performance" msgid="6552785217174378320">"Rendiment"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Afegeix més widgets"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantén premut per personalitzar els widgets"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalitza els widgets"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Desbloqueja per personalitzar els widgets"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icona de l\'aplicació per a widget desactivat"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Icona de l\'aplicació d\'un widget que s\'està instal·lant"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Edita el widget"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selecciona el widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"suprimeix el widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"col·loca el widget seleccionat"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Canvia d\'usuari"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú desplegable"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Totes les aplicacions i les dades d\'aquesta sessió se suprimiran."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Comença ara"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"No hi ha cap notificació"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"No hi ha cap notificació nova"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notif. adaptatives activades"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"El dispositiu abaixa el volum i redueix les notificacions emergents durant un màxim de 2 minuts quan reps moltes notificacions en poc temps."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactiva"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloqueja per veure notif. anteriors"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Els teus pares gestionen aquest dispositiu"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"La teva organització és propietària del dispositiu i és possible que supervisi el trànsit de xarxa"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toca per obtenir més informació"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Cap alarma definida"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"utilitza el bloqueig de pantalla"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Toca el sensor d\'empremtes digitals. És el botó més curt del lateral del telèfon."</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor d\'empremtes digitals"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"accedir al dispositiu"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"En ús per <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Utilitzat recentment per <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controls del sistema"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplicacions del sistema"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasca"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Aplicacions recents"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Pantalla dividida"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Dreceres d\'aplicacions"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilitat"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Torna"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Per tornar enrere, llisca cap a l\'esquerra o cap a la dreta amb tres dits en qualsevol lloc del ratolí tàctil."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Ratolí tàctil que mostra tres dits que es mouen cap a la dreta i cap a l\'esquerra"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Pantalla del dispositiu que mostra l\'animació del gest per anar enrere"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroil·luminació del teclat"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivell %1$d de %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Controls de la llar"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index e50fea5..3110f05 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -103,11 +103,12 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikace <xliff:g id="APPNAME">%1$s</xliff:g> objevila tento snímek obrazovky."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> a ostatní otevřené aplikace objevily tento snímek obrazovky."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Přidat do poznámky"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Zahrnout odkaz"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Nahrávání obrazovky"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Záznam obrazovky se zpracovává"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Trvalé oznámení o relaci nahrávání"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Začít nahrávat?"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Během nahrávání má Android přístup k veškerému obsahu, který je viditelný na obrazovce nebo se přehrává v zařízení. Buďte proto opatrní s věcmi, jako jsou hesla, platební údaje, zprávy, fotografie, zvuk a video."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Během nahrávání má Android přístup k veškerému obsahu, který je viditelný na obrazovce nebo se přehrává v zařízení. Dejte proto pozor na hesla, platební údaje, zprávy, fotografie, zvukové záznamy nebo videa."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Během nahrávání aplikace má Android přístup k veškerému obsahu, který je v dané aplikaci zobrazen nebo přehráván. Buďte proto opatrní s informacemi, jako jsou hesla, platební údaje, zprávy, fotky, zvukové záznamy nebo videa."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Začít nahrávat"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Nahrávat zvuk"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Přestane se nahrávat aplikace &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sdílení obrazovky"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Přestane se sdílet aplikace &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Odesílání obsahu obrazovky"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Přestane se odesílat aplikace &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odemknuto obličejem. Pokračujte stisknutím."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Obličej rozpoznán. Pokračujte stisknutím."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Obličej rozpoznán. Klepněte na ikonu odemknutí."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Odemknuto obličejem. Pokračujte klepnutím."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Ověřeno"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Zrušit ověření"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Další možnosti"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Bluetooth využívají funkce jako Quick Share a Najdi moje zařízení."</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth se zapne zítra ráno."</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Sdílet zvuk"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Zvuk se sdílí"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterie: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Zvuk"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Sluchátka"</string>
@@ -383,7 +388,7 @@
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"Ukončit"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Zpráva o chybě"</string>
     <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Co v zařízení bylo ovlivněno?"</string>
-    <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Vyberte druh problém"</string>
+    <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Vyberte druh problému"</string>
     <string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Záznam obrazovky"</string>
     <string name="performance" msgid="6552785217174378320">"Výkon"</string>
     <string name="user_interface" msgid="3712869377953950887">"Uživatelské rozhraní"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Přidat další widgety"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Dlouhým stisknutím můžete přizpůsobit widgety"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Přizpůsobit widgety"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Widgety lze přizpůsobit po odemknutí"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikace s deaktivovaným widgetem"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona aplikace při probíhající instalaci widgetu"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Upravit widget"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vybrat widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"odstranit widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"umístit vybraný widget"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Přepnout uživatele"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rozbalovací nabídka"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Veškeré aplikace a data v této relaci budou vymazána."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Spustit"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Žádná oznámení"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Žádná nová oznámení"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Jsou zapnutá adaptivní oznámení"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Když během krátké chvíle obdržíte mnoho oznámení, zařízení teď až na dvě minuty sníží hlasitost a omezí na obrazovce vyskakovací okna."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Vypnout"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Starší oznámení se zobrazí po odemknutí"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Toto zařízení spravuje rodič"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Toto zařízení vlastní vaše organizace, která může sledovat síťový provoz"</string>
@@ -618,11 +633,11 @@
     <string name="screen_pinning_negative" msgid="6882816864569211666">"Ne, děkuji"</string>
     <string name="screen_pinning_start" msgid="7483998671383371313">"Aplikace byla připnuta"</string>
     <string name="screen_pinning_exit" msgid="4553787518387346893">"Aplikace byla odepnuta"</string>
-    <string name="stream_voice_call" msgid="7468348170702375660">"Hovor"</string>
+    <string name="stream_voice_call" msgid="7468348170702375660">"Hovory"</string>
     <string name="stream_system" msgid="7663148785370565134">"Systém"</string>
     <string name="stream_ring" msgid="7550670036738697526">"Vyzvánění"</string>
     <string name="stream_music" msgid="2188224742361847580">"Média"</string>
-    <string name="stream_alarm" msgid="16058075093011694">"Budík"</string>
+    <string name="stream_alarm" msgid="16058075093011694">"Budíky"</string>
     <string name="stream_notification" msgid="7930294049046243939">"Oznámení"</string>
     <string name="stream_bluetooth_sco" msgid="6234562365528664331">"Bluetooth"</string>
     <string name="stream_dtmf" msgid="7322536356554673067">"Tónová volba"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Klepnutím zobrazíte další informace"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Budík nenastaven"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"zadejte zámek obrazovky"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Dotkněte se snímače otisků prstů. Vypínač je kratší tlačítko na boku telefonu."</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Snímač otisků prstů"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"ověříte"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"zadáte zařízení"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Právě používán aplikací <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nedávno použila aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Systém"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Ovládací prvky systému"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Systémové aplikace"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Poslední aplikace"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Rozdělená obrazovka"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Vstup"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Zkratky aplikací"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Přístupnost"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Zpět"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Pokud se chcete vrátit zpět, stačí kdekoli na touchpadu přejet třemi prsty doleva nebo doprava."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad se třemi prsty, které se pohybují doprava a doleva"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Obrazovka zařízení s animaci gesta k vrácení zpět"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podsvícení klávesnice"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Úroveň %1$d z %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Ovládání domácnosti"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 310f2b1..24d6d68 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> har registreret dette screenshot."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> og andre åbne apps har registreret dette screenshot."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Føj til note"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Inkluder link"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Skærmoptagelse"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandler skærmoptagelse"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Konstant notifikation om skærmoptagelse"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Du stopper optagelse af &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Skærmen deles"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Du stopper deling af &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Skærmen castes"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Du stopper casting af &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Låst op ved hjælp af ansigt. Tryk for at fortsætte."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansigt genkendt. Tryk for at fortsætte."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansigt genkendt. Tryk på oplåsningsikonet for at fortsætte."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Låst op ved hjælp af ansigt. Tryk for at fortsætte."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Godkendt"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Annuller godkendelsen"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Flere valgmuligheder"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funktioner som f.eks. Quick Share og Find min enhed anvender Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth aktiveres i morgen tidlig"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Del lyd"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Deler lyd"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batteri"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Lyd"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
@@ -378,7 +383,7 @@
     <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Skærmoptagelse"</string>
     <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Start"</string>
     <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Stop"</string>
-    <string name="qs_record_issue_label" msgid="8166290137285529059">"Optag problem"</string>
+    <string name="qs_record_issue_label" msgid="8166290137285529059">"Registrer problem"</string>
     <string name="qs_record_issue_start" msgid="2979831312582567056">"Start"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"Stop"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Fejlrapport"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Tilføj flere widgets"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Hold fingeren nede for at tilpasse widgets"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tilpas widgets"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Lås op for at tilpasse widgets"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Appikon for deaktiveret widget"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Appikonet for en widget er ved at blive installeret"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Rediger widget"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vælg widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"fjern widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"placer valgt widget"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Skift bruger"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rullemenu"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps og data i denne session slettes."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start nu"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Ingen notifikationer"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Ingen nye notifikationer"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptive notifikationer er aktiveret"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Din enhed skruer nu ned for lydstyrken og reducerer pop op-vinduer på skærmen i op til to minutter, når du modtager mange notifikationer over kort tid."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Deaktiver"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Lås op for at se ældre notifikationer"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Denne enhed administreres af din forælder"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Din organisation ejer denne enhed og overvåger muligvis netværkstrafikken"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tryk for at få flere oplysninger"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ingen alarm er indstillet"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"angiv skærmlås"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Sæt fingeren på fingeraftrykssensoren. Det er den mindste knap på siden af telefonen"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingeraftrykssensor"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"godkende"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"få adgang til enheden"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Bruges af <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Brugt for nylig af <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Systemstyring"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Systemapps"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Seneste apps"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Opdelt skærm"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Appgenveje"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Hjælpefunktioner"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Gå tilbage"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Du kan gå tilbage ved at stryge mod venstre eller højre med tre fingre et vilkårligt sted på touchpladen."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchplade viser tre fingre, der bevæger sig til højre og venstre"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Enhedsskærm, der viser en animation, som demonstrerer, hvordan man går tilbage"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Tastaturets baggrundslys"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d af %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Hjemmestyring"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 27f6b57..412c46a 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> hat diesen Screenshot erkannt."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> und andere geöffnete Apps haben diesen Screenshot erkannt."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Zu Notiz hinzufügen"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Link einschließen"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Bildschirmaufzeichnung"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Bildschirmaufzeichnung…"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Fortlaufende Benachrichtigung für eine Bildschirmaufzeichnung"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; wird dann nicht mehr aufgezeichnet"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Bildschirm wird geteilt"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; wird dann nicht mehr geteilt"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Bildschirm wird übertragen"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; wird dann nicht mehr übertragen"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Gerät mit dem Gesicht entsperrt. Tippe, um fortzufahren."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Gesicht erkannt. Tippe, um fortzufahren."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gesicht erkannt. Tippe zum Fortfahren auf das Symbol „Entsperren“."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Per Gesichtserkennung entsperrt. Tippe, um fortzufahren."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifiziert"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Authentifizierung abbrechen"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Weitere Optionen"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funktionen wie „Quick Share“ und „Mein Gerät finden“ verwenden Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth wird morgen früh aktiviert"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Audioinhalte freigeben"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Audioinhalte werden freigegeben"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akkustand: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
@@ -379,10 +384,10 @@
     <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Starten"</string>
     <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Beenden"</string>
     <string name="qs_record_issue_label" msgid="8166290137285529059">"Problem aufnehmen"</string>
-    <string name="qs_record_issue_start" msgid="2979831312582567056">"Aufnahme starten"</string>
+    <string name="qs_record_issue_start" msgid="2979831312582567056">"Starten"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"Aufnahme beenden"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Fehlerbericht"</string>
-    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Welche Bereiche des Geräts waren betroffen?"</string>
+    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Welche Probleme sind bei deinem Gerät aufgetreten?"</string>
     <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Art des Problems auswählen"</string>
     <string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Bildschirmaufnahme"</string>
     <string name="performance" msgid="6552785217174378320">"Leistung"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Weitere Widgets hinzufügen"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Lange drücken, um Widgets anzupassen"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Widgets anpassen"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Entsperren, um Widgets zu personalisieren"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App-Symbol für deaktiviertes Widget"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App-Symbol für ein Widget, das gerade installiert wird"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Widget bearbeiten"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"Widget auswählen"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"Widget entfernen"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ausgewähltes Widget in den Bearbeitungsmodus versetzen"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Nutzer wechseln"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"Pull-down-Menü"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle Apps und Daten in dieser Sitzung werden gelöscht."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Jetzt starten"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Keine Benachrichtigungen"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Keine neuen Benachrichtigungen"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptive Benachrichtigungen an"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Wenn du in kurzer Zeit viele Benachrichtigungen erhältst, reduziert dein Gerät jetzt die Lautstärke und Pop-ups bis zu 2 Minuten lang."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Deaktivieren"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Für ältere Benachrichtigungen entsperren"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Dieses Gerät wird von deinen Eltern verwaltet"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Deine Organisation verwaltet dieses Gerät und kann den Netzwerkverkehr überwachen"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Für weitere Informationen tippen"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Kein Wecker gestellt"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"Displaysperre eingeben"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Berühre den Fingerabdrucksensor. Das ist die kürzere Taste an der Seite des Smartphones."</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingerabdrucksensor"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"Authentifizieren"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"Eingeben des Geräts"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Verwendet von <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Kürzlich von <xliff:g id="APP_NAME">%1$s</xliff:g> verwendet (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"System­steuerelemente"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"System-Apps"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Zuletzt aktive Apps"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Splitscreen"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Eingabe"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App-Verknüpfungen"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Bedienungshilfen"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Zurück"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Wenn du zurückgehen möchtest, wische an einer beliebigen Stelle des Touchpads mit drei Fingern nach links oder rechts."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad mit drei Fingern, die sich nach links und rechts bewegen"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Bildschirm zeigt eine Animation der Touch-Geste „Zurück“"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Tastaturbeleuchtung"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d von %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Smart-Home-Steuerung"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index e2480b2e..64b3c39 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"Η εφαρμογή <xliff:g id="APPNAME">%1$s</xliff:g> εντόπισε αυτό το στιγμιότυπο οθόνης."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Η εφαρμογή <xliff:g id="APPNAME">%1$s</xliff:g> και άλλες ανοικτές εφαρμογές εντόπισαν το στιγμιότυπο οθόνης."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Προσθήκη σε σημείωση"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Συμπερίληψη συνδέσμου"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Εγγραφή οθόνης"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Επεξεργασία εγγραφής οθόνης"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ειδοποίηση σε εξέλιξη για μια περίοδο λειτουργίας εγγραφής οθόνης"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Θα διακόψετε την εγγραφή της εφαρμογής &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Γίνεται κοινοποίηση οθόνης"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Θα διακόψετε την κοινή χρήση της εφαρμογής &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Μετάδοση οθόνης"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Θα διακόψετε τη μετάδοση της εφαρμογής &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ξεκλείδωμα με αναγνώριση προσώπου. Πατήστε για συνέχεια."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Το πρόσωπο αναγνωρίστηκε. Πατήστε για συνέχεια."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Το πρόσωπο αναγνωρ. Πατήστε το εικον. ξεκλειδ. για συνέχεια."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Ξεκλείδωμα με αναγνώριση προσώπου. Πατήστε για συνέχεια."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Ολοκληρώθηκε ο έλεγχος ταυτότητας"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Ακύρωση ελέγχου ταυτότητας"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Περισσότερες επιλογές"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Λειτουργίες όπως το Quick Share και η Εύρεση συσκευής χρησιμοποιούν το Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Το Bluetooth θα ενεργοποιηθεί αύριο το πρωί"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Κοινή χρήση ήχου"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Κοινή χρήση ήχου σε εξέλιξη"</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>
@@ -390,7 +395,7 @@
     <string name="thermal" msgid="6758074791325414831">"Θερμικό"</string>
     <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Λειτουργία ενός χεριού"</string>
     <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Συσκευές ακοής"</string>
-    <string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Ενεργά"</string>
+    <string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Ενεργές"</string>
     <string name="quick_settings_hearing_devices_disconnected" msgid="8907061223998176187">"Αποσυνδεδεμένα"</string>
     <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Συσκευές ακοής"</string>
     <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Σύζευξη νέας συσκευής"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Προσθήκη περισσότερων γραφικών στοιχείων"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Παρατεταμένο πάτημα για προσαρμογή γραφ. στοιχείων"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Προσαρμογή γραφικών στοιχείων"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Ξεκλειδώστε για προσαρμογή των γραφικών στοιχείων"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Εικονίδιο εφαρμογής για απενεργοποιημένο γραφικό στοιχείο"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Εικονίδιο εφαρμογής για ένα γραφικό στοιχείου που εγκαθίσταται"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Επεξεργασία γραφικού στοιχείου"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"επιλογή γραφικού στοιχείου"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"κατάργηση γραφικού στοιχείου"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"τοποθέτηση επιλεγμένου γραφικού στοιχείου"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Εναλλαγή χρήστη"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"αναπτυσσόμενο μενού"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Όλες οι εφαρμογές και τα δεδομένα αυτής της περιόδου σύνδεσης θα διαγραφούν."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Έναρξη τώρα"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Δεν υπάρχουν ειδοποιήσεις"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Δεν υπάρχουν νέες ειδοποιήσεις"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Προσαρμοστ. ειδοπ. – Ενεργές"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Όταν λαμβάνετε πολλές ειδοποιήσεις σε σύντομο χρονικό διάστημα, η συσκευή θα χαμηλώνει την ένταση και θα μειώνει τα αναδυόμενα για έως και 2 λεπτά."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Απενεργοποίηση"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ξεκλειδώστε για εμφάνιση παλαιότ. ειδοπ."</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Αυτή η συσκευή είναι διαχειριζόμενη από τον γονέα σου"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ο οργανισμός σας κατέχει αυτήν τη συσκευή και μπορεί να παρακολουθεί την επισκεψιμότητα δικτύου."</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Πατήστε για περισσότερες πληροφορίες."</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Δεν ορίστηκε ξυπνητ."</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"εισαγωγή κλειδώματος οθόνης"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Αγγίξτε τον αισθητήρα δακτυλικών αποτυπωμάτων. Είναι το πιο κοντό κουμπί στην πλευρά του τηλεφώνου."</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Αισθητήρας δακτυλικών αποτυπωμάτων"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"έλεγχος ταυτότητας"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"εισαγωγή συσκευής"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Χρησιμοποιείται από την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Χρησιμοποιήθηκε πρόσφατα από την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Σύστημα"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Στοιχεία ελέγχου συστήματος"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Εφαρμογές συστήματος"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Πολυδιεργασία"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Πρόσφατες εφαρμογές"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Διαχωρισμός οθόνης"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Είσοδος"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Συντομεύσεις εφαρμογών"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Προσβασιμότητα"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Επιστροφή"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Για επιστροφή, σύρετε προς τα αριστερά ή προς τα δεξιά χρησιμοποιώντας τρία δάχτυλα οπουδήποτε στην επιφάνεια αφής."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Επιφάνεια αφής στην οποία εμφανίζονται τρία δάχτυλα να κινούνται δεξιά και αριστερά"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Οθόνη συσκευής που εμφανίζει μια κινούμενη εικόνα σχετικά με την κίνηση επιστροφής"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Οπίσθιος φωτισμός πληκτρολογίου"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Επίπεδο %1$d από %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Οικιακοί έλεγχοι"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 303e922..f1d6d51 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Add to note"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Include link"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Screen recorder"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"You will stop recording &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sharing screen"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"You will stop sharing &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Casting screen"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"You will stop casting &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Unlocked by face. Tap to continue."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel authentication"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"More options"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Features like Quick Share and Find My Device use Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth will turn on tomorrow morning"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Share audio"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Sharing audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customise widgets"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customise widgets"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Unlock to customise widgets"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App icon for a widget being installed"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"select widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remove widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"place selected widget"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"No new notifications"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptive notifications is on"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Your device now lowers the volume and reduces pop-ups on the screen for up to 2 minutes when you receive many notifications in a short time span."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Turn off"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Unlock to see older notifications"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"enter screen lock"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Touch the fingerprint sensor. It\'s the shorter button on the side of the phone"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingerprint sensor"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"Authenticate"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"In use by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Recently used by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"System controls"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"System apps"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Recent apps"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Split screen"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App shortcuts"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Go back"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"To go back, swipe left or right using 3 fingers anywhere on the touchpad."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad showing 3 fingers moving right and left"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Device screen showing animation for back gesture"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Home controls"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 042d06e..321f5b9 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Add to note"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Include link"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Screen Recorder"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -125,26 +126,21 @@
     <string name="screenrecord_save_text" msgid="3008973099800840163">"Tap to view"</string>
     <string name="screenrecord_save_error" msgid="5862648532560118815">"Error saving screen recording"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"Error starting screen recording"</string>
-    <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
-    <skip />
-    <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
-    <skip />
-    <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
-    <skip />
-    <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
-    <skip />
-    <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
-    <skip />
-    <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
-    <skip />
-    <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
-    <skip />
-    <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
-    <skip />
-    <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
-    <skip />
-    <!-- no translation found for close_dialog_button (4749497706540104133) -->
-    <skip />
+    <string name="screenrecord_stop_dialog_title" msgid="2685522129492260887">"Stop recording screen?"</string>
+    <string name="screenrecord_stop_dialog_message" msgid="1926783607059442889">"You will stop recording your screen"</string>
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"You will stop recording &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
+    <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Stop recording"</string>
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sharing screen"</string>
+    <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Stop sharing screen?"</string>
+    <string name="share_to_app_stop_dialog_message" msgid="3181723638915877339">"You will stop sharing your screen"</string>
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"You will stop sharing &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
+    <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"Stop sharing"</string>
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Casting screen"</string>
+    <string name="cast_to_other_device_stop_dialog_title" msgid="1910372600290258193">"Stop casting screen?"</string>
+    <string name="cast_to_other_device_stop_dialog_message" msgid="1502520537030715412">"You will stop casting your screen"</string>
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"You will stop casting &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
+    <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"Stop casting"</string>
+    <string name="close_dialog_button" msgid="4749497706540104133">"Close"</string>
     <string name="issuerecord_title" msgid="286627115110121849">"Issue Recorder"</string>
     <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"Processing issue recording"</string>
     <string name="issuerecord_channel_description" msgid="6142326363431474632">"Ongoing notification for an issue collection session"</string>
@@ -155,8 +151,7 @@
     <string name="issuerecord_save_error" msgid="6913040083446722726">"Error saving issue recording"</string>
     <string name="issuerecord_start_error" msgid="3402782952722871190">"Error starting issue recording"</string>
     <string name="immersive_cling_title" msgid="8372056499315585941">"Viewing full screen"</string>
-    <!-- no translation found for immersive_cling_description (2717426731830851921) -->
-    <skip />
+    <string name="immersive_cling_description" msgid="2717426731830851921">"To exit, swipe down from the top of your screen"</string>
     <string name="immersive_cling_positive" msgid="3076681691468978568">"Got it"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"Back"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"Home"</string>
@@ -189,6 +184,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognized. Press to continue."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognized. Press the unlock icon to continue."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Unlocked by face. Tap to continue."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel Authentication"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"More Options"</string>
@@ -299,8 +295,7 @@
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Saved"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"disconnect"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"activate"</string>
-    <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
-    <skip />
+    <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"Automatically turn on tomorrow"</string>
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Features like Quick Share and Find My Device use Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth will turn on tomorrow morning"</string>
     <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Share audio"</string>
@@ -469,6 +464,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customize widgets"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customize widgets"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Unlock to customize widgets"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App icon for a widget being installed"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
@@ -487,6 +483,9 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"select widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remove widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"place selected widget"</string>
+    <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"Lock screen widgets"</string>
+    <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"To open an app using a widget, you’ll need to verify it’s you. Also, keep in mind that anyone can view them, even when your tablet’s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here."</string>
+    <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"Got it"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
@@ -540,6 +539,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"No new notifications"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptive notifications is on"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Your device now lowers the volume and reduces pop-ups on the screen for up to two minutes when you receive many notifications in a short time span."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Turn off"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Unlock to see older notifications"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organization owns this device and may monitor network traffic"</string>
@@ -1195,6 +1197,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"enter screen lock"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Touch the fingerprint sensor. It’s the shorter button on the side of the phone"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingerprint sensor"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"authenticate"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string>
@@ -1336,7 +1339,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"In use by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Recently used by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"System controls"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"System apps"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Recent apps"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Split screen"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App shortcuts"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
@@ -1345,14 +1352,16 @@
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"Collapse icon"</string>
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"Expand icon"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"or"</string>
-    <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
+    <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"Back gesture"</string>
+    <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"Home gesture"</string>
+    <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"Action key"</string>
+    <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"Done"</string>
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
     <skip />
-    <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
-    <skip />
-    <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
-    <skip />
-    <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
-    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Go back"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"To go back, swipe left or right using three fingers anywhere on the touchpad."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad showing three fingers moving right and left"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Device screen showing animation for back gesture"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Home Controls"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 303e922..f1d6d51 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Add to note"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Include link"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Screen recorder"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"You will stop recording &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sharing screen"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"You will stop sharing &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Casting screen"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"You will stop casting &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Unlocked by face. Tap to continue."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel authentication"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"More options"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Features like Quick Share and Find My Device use Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth will turn on tomorrow morning"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Share audio"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Sharing audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customise widgets"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customise widgets"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Unlock to customise widgets"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App icon for a widget being installed"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"select widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remove widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"place selected widget"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"No new notifications"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptive notifications is on"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Your device now lowers the volume and reduces pop-ups on the screen for up to 2 minutes when you receive many notifications in a short time span."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Turn off"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Unlock to see older notifications"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"enter screen lock"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Touch the fingerprint sensor. It\'s the shorter button on the side of the phone"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingerprint sensor"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"Authenticate"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"In use by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Recently used by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"System controls"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"System apps"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Recent apps"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Split screen"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App shortcuts"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Go back"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"To go back, swipe left or right using 3 fingers anywhere on the touchpad."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad showing 3 fingers moving right and left"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Device screen showing animation for back gesture"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Home controls"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 303e922..f1d6d51 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detected this screenshot."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> and other open apps detected this screenshot."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Add to note"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Include link"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Screen recorder"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processing screen recording"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ongoing notification for a screen record session"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"You will stop recording &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Sharing screen"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"You will stop sharing &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Casting screen"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"You will stop casting &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Unlocked by face. Press to continue."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Face recognised. Press to continue."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Unlocked by face. Tap to continue."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel authentication"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"More options"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Features like Quick Share and Find My Device use Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth will turn on tomorrow morning"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Share audio"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Sharing audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> battery"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Add more widgets"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Long press to customise widgets"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Customise widgets"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Unlock to customise widgets"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App icon for disabled widget"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App icon for a widget being installed"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"select widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remove widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"place selected widget"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Switch user"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"All apps and data in this session will be deleted."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start now"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"No notifications"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"No new notifications"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptive notifications is on"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Your device now lowers the volume and reduces pop-ups on the screen for up to 2 minutes when you receive many notifications in a short time span."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Turn off"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Unlock to see older notifications"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"This device is managed by your parent"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Your organisation owns this device and may monitor network traffic"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tap for more information"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No alarm set"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"enter screen lock"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Touch the fingerprint sensor. It\'s the shorter button on the side of the phone"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingerprint sensor"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"Authenticate"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"enter device"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"In use by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Recently used by <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"System controls"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"System apps"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Recent apps"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Split screen"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App shortcuts"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Go back"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"To go back, swipe left or right using 3 fingers anywhere on the touchpad."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad showing 3 fingers moving right and left"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Device screen showing animation for back gesture"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Keyboard backlight"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d of %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Home controls"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 5a5af96..a196720 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‎‏‏‏‏‎‎‎‏‎‎‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‎‎‎‏‏‎‏‎‎‎‎‏‏‎‏‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="APPNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ detected this screenshot.‎‏‎‎‏‎"</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‏‎‎‏‎‎‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="APPNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ and other open apps detected this screenshot.‎‏‎‎‏‎"</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‎‏‎‎‎‏‏‎‏‎‎‏‎‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎Add to note‎‏‎‎‏‎"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎‎‏‏‏‏‎‏‎‎‎‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎Include link‎‏‎‎‏‎"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‎‎‎‎‎Screen Recorder‎‏‎‎‏‎"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‏‎‎Processing screen recording‎‏‎‎‏‎"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‏‎‏‎‏‏‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‏‎Ongoing notification for a screen record session‎‏‎‎‏‎"</string>
@@ -125,26 +126,21 @@
     <string name="screenrecord_save_text" msgid="3008973099800840163">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‎‎‎‏‏‎Tap to view‎‏‎‎‏‎"</string>
     <string name="screenrecord_save_error" msgid="5862648532560118815">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎Error saving screen recording‎‏‎‎‏‎"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‎‎‏‏‏‎‏‎‎‎‎‎‎‎Error starting screen recording‎‏‎‎‏‎"</string>
-    <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
-    <skip />
-    <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
-    <skip />
-    <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
-    <skip />
-    <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
-    <skip />
-    <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
-    <skip />
-    <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
-    <skip />
-    <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
-    <skip />
-    <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
-    <skip />
-    <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
-    <skip />
-    <!-- no translation found for close_dialog_button (4749497706540104133) -->
-    <skip />
+    <string name="screenrecord_stop_dialog_title" msgid="2685522129492260887">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‎‎‏‎‎‏‏‏‎‎‏‎‎‎‎‏‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‎‎‎‏‏‏‎‎‎‎‎‎‏‎‏‏‏‎Stop recording screen?‎‏‎‎‏‎"</string>
+    <string name="screenrecord_stop_dialog_message" msgid="1926783607059442889">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‏‏‎‏‎‎‏‎‏‏‏‎‏‏‎‎‏‏‎‎‏‎‎‏‎You will stop recording your screen‎‏‎‎‏‎"</string>
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‎‏‎‎‎‏‎‏‏‎‏‏‏‎‎‎‎‏‎‎‎‏‎‎‎‎‏‏‎‎You will stop recording &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt;‎‏‎‎‏‎"</string>
+    <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‎‎‎‏‎‏‎‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎Stop recording‎‏‎‎‏‎"</string>
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎‏‎‏‏‏‎‎‏‎‏‏‏‏‎‎‏‎Sharing screen‎‏‎‎‏‎"</string>
+    <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‎‎‏‏‏‎‏‏‎‏‎‏‏‎‏‎‏‏‏‏‎‏‎‏‏‏‎‎‎‏‏‎‎Stop sharing screen?‎‏‎‎‏‎"</string>
+    <string name="share_to_app_stop_dialog_message" msgid="3181723638915877339">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‎‎‏‏‏‏‏‎‎‎‎‎‎‏‏‎‎‏‎‏‎‏‏‎‎‎‏‏‏‎‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‏‎You will stop sharing your screen‎‏‎‎‏‎"</string>
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‎‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‏‎‎‏‎You will stop sharing &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt;‎‏‎‎‏‎"</string>
+    <string name="share_to_app_stop_dialog_button" msgid="6334056916284230217">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‏‏‎‎‏‏‎‏‎‎‏‏‎‎‎‎‏‎‎‎‏‏‏‎‏‎‎‏‎‎‏‎‏‎‎‏‎‎‏‎‎‏‎Stop sharing‎‏‎‎‏‎"</string>
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‎‏‎‏‏‎‏‏‏‏‎‎‏‏‎‎‏‏‏‎‏‏‎‎‏‏‎‎‎‏‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‎‎‏‎‎Casting screen‎‏‎‎‏‎"</string>
+    <string name="cast_to_other_device_stop_dialog_title" msgid="1910372600290258193">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‎‎‏‏‎‎‎‎‎‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‏‎‎‎‏‎Stop casting screen?‎‏‎‎‏‎"</string>
+    <string name="cast_to_other_device_stop_dialog_message" msgid="1502520537030715412">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‎‏‎‎‎‎‎‎‏‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‎‎‏‏‏‏‎‏‎‎‎‎‎‎‏‎‏‎‎‎You will stop casting your screen‎‏‎‎‏‎"</string>
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‏‏‎‎‎‏‎‎‏‎‎‎‏‏‏‏‏‎‏‎‎You will stop casting &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt;‎‏‎‎‏‎"</string>
+    <string name="cast_to_other_device_stop_dialog_button" msgid="6420183747435521834">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎‏‎‏‎‏‎‎‎‎‏‎‏‏‎‎‏‏‏‎‎‏‎‏‎‏‎‎Stop casting‎‏‎‎‏‎"</string>
+    <string name="close_dialog_button" msgid="4749497706540104133">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎Close‎‏‎‎‏‎"</string>
     <string name="issuerecord_title" msgid="286627115110121849">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‎‎‎‏‎‏‏‏‏‎‎‏‎Issue Recorder‎‏‎‎‏‎"</string>
     <string name="issuerecord_background_processing_label" msgid="1666840264959336876">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‎‎‏‏‏‎‎‏‏‏‎‎‏‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‏‎‎‎‎‎‏‎‎‎‎‏‏‎‏‎‏‏‎‎‎Processing issue recording‎‏‎‎‏‎"</string>
     <string name="issuerecord_channel_description" msgid="6142326363431474632">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‎‏‏‎‎‏‎‏‎‏‏‏‎‎‏‎‎‎‎Ongoing notification for an issue collection session‎‏‎‎‏‎"</string>
@@ -155,8 +151,7 @@
     <string name="issuerecord_save_error" msgid="6913040083446722726">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‏‎‏‎‏‎‏‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‎‎‏‎‏‎‎‏‏‎‎Error saving issue recording‎‏‎‎‏‎"</string>
     <string name="issuerecord_start_error" msgid="3402782952722871190">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‎‏‎‎‎‏‎‎‎‏‎‎‎‏‏‎‎‎‏‏‎‎‏‏‎‏‎‎‏‏‎‎‏‏‏‎‎‏‎‏‏‎‎Error starting issue recording‎‏‎‎‏‎"</string>
     <string name="immersive_cling_title" msgid="8372056499315585941">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‏‏‏‎‎‎‎‏‎‏‎‎‎‎‎‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‎‏‎‎‏‎‏‏‎‎‏‏‏‎‎‏‎‏‎‏‎Viewing full screen‎‏‎‎‏‎"</string>
-    <!-- no translation found for immersive_cling_description (2717426731830851921) -->
-    <skip />
+    <string name="immersive_cling_description" msgid="2717426731830851921">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‏‎‏‎‎‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‏‏‎‏‏‎‏‏‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‎To exit, swipe down from the top of your screen‎‏‎‎‏‎"</string>
     <string name="immersive_cling_positive" msgid="3076681691468978568">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‎‏‏‎‎‏‎‏‎‎‎‏‎‏‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‏‎‎‎‏‎‎‎‎Got it‎‏‎‎‏‎"</string>
     <string name="accessibility_back" msgid="6530104400086152611">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‎‏‏‎‏‎‏‏‎‏‎‎‎‏‏‎Back‎‏‎‎‏‎"</string>
     <string name="accessibility_home" msgid="5430449841237966217">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‎‏‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎Home‎‏‎‎‏‎"</string>
@@ -189,6 +184,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‎‏‎Unlocked by face. Press to continue.‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‏‏‏‎‎‎‎‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‏‎‎‎Face recognized. Press to continue.‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‏‏‎‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎Face recognized. Press the unlock icon to continue.‎‏‎‎‏‎"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‎‏‎‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎‎‏‎‎‎‎Unlocked by face. Tap to continue.‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‎‎Authenticated‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‏‏‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‎‎‎‏‎‎‎‏‎‎‏‏‎‏‎Cancel Authentication‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‏‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‎More Options‎‏‎‎‏‎"</string>
@@ -299,8 +295,7 @@
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‏‎‎‏‏‎‏‏‎‏‏‏‎‎‎‏‏‎‎‎‏‏‏‎‏‏‎‎‏‎‏‎Saved‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‏‎‎‎‏‎‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‎‎‏‏‎‏‎‎‏‏‏‏‎‎disconnect‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‎‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‏‏‎‏‎‏‏‏‎‏‎‏‏‎‎‎‏‏‎‏‎‎‏‎‏‏‎‏‏‎activate‎‏‎‎‏‎"</string>
-    <!-- no translation found for turn_on_bluetooth_auto_tomorrow (3345758139235739006) -->
-    <skip />
+    <string name="turn_on_bluetooth_auto_tomorrow" msgid="3345758139235739006">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‎‏‎‎‎‎‏‎‏‎‏‎‎‏‏‎‏‎‎‎‏‎‎‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‏‎‏‏‏‏‏‏‎‎Automatically turn on tomorrow‎‏‎‎‏‎"</string>
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‎‎‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‏‎‎‎‏‏‎‎‎Features like Quick Share and Find My Device use Bluetooth‎‏‎‎‏‎"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‎‎‎‏‏‏‎‎‎‏‎‏‏‎‎‏‎‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‎‏‎‎‏‎‏‏‏‎Bluetooth will turn on tomorrow morning‎‏‎‎‏‎"</string>
     <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‏‏‎‎‏‏‏‎‎‎‎‎‏‎‏‎‎‏‏‏‏‎‎‎‎‎‎‏‏‎‏‏‎‎‎‏‏‎‎‎‎‎‏‏‏‎‎Share audio‎‏‎‎‏‎"</string>
@@ -469,6 +464,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‏‏‏‎‎‏‏‏‏‏‎‏‏‎Add more widgets‎‏‎‎‏‎"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‎‏‎‎‏‏‎‏‏‏‏‎‎‏‎‏‎‏‏‏‎‎‏‎‎‎‎‏‎‎‏‏‎‏‎‏‎‎‎‎‎‏‏‎Long press to customize widgets‎‏‎‎‏‎"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‏‏‏‏‏‎‏‎‎‎‎‏‏‎‏‏‎‎‎‎‏‎‎‎‏‏‏‎‎‏‎‏‏‎‏‏‏‏‏‏‏‎‎‎‏‎‏‎Customize widgets‎‏‎‎‏‎"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‏‎‏‏‏‏‎‎‎‎‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎Unlock to customize widgets‎‏‎‎‏‎"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‎‏‏‎‏‏‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‎‎‎‏‎‏‎‏‏‎‏‏‎‎‎‏‎‎‎‏‏‏‏‏‎App icon for disabled widget‎‏‎‎‏‎"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‏‏‏‏‏‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‎‏‏‏‎‏‎‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‏‎‏‏‎App icon for a widget being installed‎‏‎‎‏‎"</string>
     <string name="edit_widget" msgid="9030848101135393954">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‎‎‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‎‎‏‎‎Edit widget‎‏‎‎‏‎"</string>
@@ -487,6 +483,9 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‏‎‏‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‎‎‏‎‏‏‏‏‎select widget‎‏‎‎‏‎"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‏‎‎‏‎‏‎‎‎‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‎‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‏‏‎‎remove widget‎‏‎‎‏‎"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‎‎‎‎‏‏‏‏‎‎‎‏‎‎‎‏‎‎‏‎‎place selected widget‎‏‎‎‏‎"</string>
+    <string name="communal_widgets_disclaimer_title" msgid="1150954395585308868">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‎‏‎‏‏‏‎‏‏‎‎‏‎‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‎‏‎‎‎Lock screen widgets‎‏‎‎‏‎"</string>
+    <string name="communal_widgets_disclaimer_text" msgid="1423545475160506349">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‎‏‎‏‎‎‎‎‎‎‏‎‎‎‏‏‏‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎To open an app using a widget, you’ll need to verify it’s you. Also, keep in mind that anyone can view them, even when your tablet’s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here.‎‏‎‎‏‎"</string>
+    <string name="communal_widgets_disclaimer_button" msgid="4423059765740780753">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‎‏‏‏‎‏‎‏‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‏‏‏‏‎‎‏‏‎‏‎‎‎‏‎Got it‎‏‎‎‏‎"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‎‎‎‎‏‏‏‎‏‎‏‏‏‎‏‏‏‎‎‎‎‏‎‏‏‎‏‎‎‎Switch user‎‏‎‎‏‎"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‏‏‎‏‎‎‏‏‎‎‎‎‎‎‎‏‏‏‏‎‎‏‎‏‎‎‏‏‎‎‎‎‏‏‏‏‏‏‏‎pulldown menu‎‏‎‎‏‎"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‎‏‏‎‎‏‏‎‏‎‎‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‏‎All apps and data in this session will be deleted.‎‏‎‎‏‎"</string>
@@ -540,6 +539,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‎‎‎‏‏‏‎‎‏‎‎‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‎‎Start now‎‏‎‎‏‎"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‏‎‏‎‏‎‎‏‎‎‎‏‎‎‏‎‎‎No notifications‎‏‎‎‏‎"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‏‎‏‎‎‏‎‎‏‎‎‏‎‎‏‏‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‎‎‏‎‎‎‎‏‎‏‎‎No new notifications‎‏‎‎‏‎"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‎‏‎‎‏‎‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‎‎‏‏‎‏‎‎‏‎‏‎‏‎‏‎Adaptive notifications is on‎‏‎‎‏‎"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‎‎‎‎‏‏‏‎‏‏‏‎‎‏‎‎‎‏‎‎‎‏‎‏‎‎‏‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‏‎‏‎‏‏‎‎‏‎Your device now lowers the volume and reduces pop-ups on the screen for up to two minutes when you receive many notifications in a short time span.‎‏‎‎‏‎"</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‏‎‎‎‏‎‏‎‏‎‏‏‎‏‎‏‎‏‎‎‏‏‏‏‎‏‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‎‏‏‏‏‎Turn off‎‏‎‎‏‎"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‎‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‎Unlock to see older notifications‎‏‎‎‏‎"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‎‏‏‎‏‎‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‎This device is managed by your parent‎‏‎‎‏‎"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‎‏‎‏‎‏‎‎‎‏‏‎‏‏‏‎‏‏‎‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‏‏‏‎‎‏‎‎‎Your organization owns this device and may monitor network traffic‎‏‎‎‏‎"</string>
@@ -1195,6 +1197,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‏‎‎‎‏‎‎‎‏‏‎Tap for more information‎‏‎‎‏‎"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‎‏‏‎No alarm set‎‏‎‎‏‎"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎‏‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‎‎‏‎‎‏‎‏‎‎‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎enter screen lock‎‏‎‎‏‎"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎‏‏‏‏‎‏‎‏‏‎‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‏‎‎‎‎‎‎‎Touch the fingerprint sensor. It’s the shorter button on the side of the phone‎‏‎‎‏‎"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‎‎‎‎‎‎‎‏‏‎‏‏‏‎‏‏‎‎‏‏‎‏‎‎‎‎‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‏‎‎‎Fingerprint sensor‎‏‎‎‏‎"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‏‎‏‏‎‎‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‎‎‏‎authenticate‎‏‎‎‏‎"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‎‏‎‎‏‎‎‎‎‏‎‏‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎enter device‎‏‎‎‏‎"</string>
@@ -1336,7 +1339,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎‎‎‎‏‎‎‎‎‏‎‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‏‏‏‎In use by ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ (‎‏‎‎‏‏‎<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>‎‏‎‎‏‏‏‎ • ‎‏‎‎‏‏‎<xliff:g id="PROXY_LABEL">%3$s</xliff:g>‎‏‎‎‏‏‏‎)‎‏‎‎‏‎"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‎‏‎‏‎‏‎‏‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎Recently used by ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ (‎‏‎‎‏‏‎<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g>‎‏‎‎‏‏‏‎ • ‎‏‎‎‏‏‎<xliff:g id="PROXY_LABEL">%3$s</xliff:g>‎‏‎‎‏‏‏‎)‎‏‎‎‏‎"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‎‏‏‎‏‎‎‏‎‏‏‎‎‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎System‎‏‎‎‏‎"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‎‎‎‎‏‎‏‏‏‎‏‏‏‎‎‎‏‎‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‏‎‎‎‎‏‏‎‏‏‎‎‎System controls‎‏‎‎‏‎"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‏‎‏‎‏‎‎‎‎‏‏‎‏‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎System apps‎‏‎‎‏‎"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‎‎‏‏‎‎‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‎‏‏‎‎‎‎Multitasking‎‏‎‎‏‎"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‎‏‎‏‏‏‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‎Recent apps‎‏‎‎‏‎"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‎‎‎‏‎‏‏‏‎‎‎‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‏‎‏‎‎‎Split screen‎‏‎‎‏‎"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‎‎‎‎‎‎‏‎‎‏‎‎‏‏‏‎‎‎‏‏‏‎‎‏‎‎‎‏‎‎‏‎‏‎‎‎‏‏‏‎‎Input‎‏‎‎‏‎"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‎‏‎‎‎‎‏‎‎‎‎‏‎‎‎‎‏‎‏‎‏‎‎‏‏‎‏‏‎‏‎App shortcuts‎‏‎‎‏‎"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‎‏‎‎‎‎‏‎‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎Accessibility‎‏‎‎‏‎"</string>
@@ -1345,14 +1352,16 @@
     <string name="shortcut_helper_content_description_collapse_icon" msgid="8028015738431664954">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‎‏‏‎‏‏‏‏‎‎‏‏‎‎‏‏‏‎‏‎‎Collapse icon‎‏‎‎‏‎"</string>
     <string name="shortcut_helper_content_description_expand_icon" msgid="1084435697860417390">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‏‏‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎‎‏‎‎‎‏‎‏‏‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‎‏‏‏‎‎Expand icon‎‏‎‎‏‎"</string>
     <string name="shortcut_helper_key_combinations_or_separator" msgid="7082902112102125540">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‎‎‎‏‏‎‏‏‎‎‏‎‏‎‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‎or‎‏‎‎‏‎"</string>
-    <!-- no translation found for touchpad_tutorial_back_gesture_button (2746834288077265946) -->
+    <string name="touchpad_tutorial_back_gesture_button" msgid="2746834288077265946">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‎‎‎‎‏‏‎‏‎‎Back gesture‎‏‎‎‏‎"</string>
+    <string name="touchpad_tutorial_home_gesture_button" msgid="7640544867625955304">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‏‎‏‏‎‎‎‏‎‎‏‏‎‏‏‎‎‏‎‏‎‏‎‎‎‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎Home gesture‎‏‎‎‏‎"</string>
+    <string name="touchpad_tutorial_action_key_button" msgid="3220074511852927267">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‎‎‎‎‎‎‎‎‎‎‎‏‎‏‏‎‏‎‏‎‎‏‏‎‏‎‏‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎Action key‎‏‎‎‏‎"</string>
+    <string name="touchpad_tutorial_done_button" msgid="176168488821755503">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‎‎‎‏‏‏‎‎‏‏‎‏‏‏‏‎Done‎‏‎‎‏‎"</string>
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
     <skip />
-    <!-- no translation found for touchpad_tutorial_home_gesture_button (7640544867625955304) -->
-    <skip />
-    <!-- no translation found for touchpad_tutorial_action_key_button (3220074511852927267) -->
-    <skip />
-    <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
-    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‎‏‏‎‎‎‎‏‎‏‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‏‏‏‏‎Go back‎‏‎‎‏‎"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‏‎‎‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎‎To go back, swipe left or right using three fingers anywhere on the touchpad.‎‏‎‎‏‎"</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‏‏‎‎‎‏‏‎‏‏‏‎‎‏‎‏‏‎‏‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‎‎‏‎‏‎‏‎‏‎‎‎‏‏‏‎‎Touchpad showing three fingers moving right and left‎‏‎‎‏‎"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‏‎‎‎‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎Device screen showing animation for back gesture‎‏‎‎‏‎"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‎‎Keyboard backlight‎‏‎‎‏‎"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‎‎‎‎‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎‎‎‏‎‏‎‎‎‏‎‏‏‎‏‎‎‏‎‏‎‏‎‎‎‎‏‎‎Level %1$d of %2$d‎‏‎‎‏‎"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‏‎‏‎‎‎‎‏‎Home Controls‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index ce5bd5e..c551253 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detectó que tomaste una captura de pantalla."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> y otras apps en ejecución detectaron que tomaste una captura de pantalla."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Agregar a la nota"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Incluir vínculo"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Grabadora de pantalla"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando grabación pantalla"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación constante para una sesión de grabación de pantalla"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Dejarás de grabar contenido de &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Compartiendo pantalla"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Dejarás de compartir contenido de &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Transmitiendo pantalla"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Dejarás de transmitir contenido de &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueo con rostro. Presiona para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rostro reconocido. Presiona para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rostro reconocido. Presiona el desbloqueo para continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Se desbloqueó con el rostro. Presiona para continuar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticación"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Más opciones"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Las funciones como Quick Share y Encontrar mi dispositivo usan Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"El Bluetooth se activará mañana a la mañana"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Compartir audio"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Compartiendo audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auriculares"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Agregar más widgets"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantén presionado para personalizar los widgets"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Desbloquea para personalizar los widgets"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ícono de la app de widget inhabilitado"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ícono de la app para un widget que se está instalando"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Modificar widget"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"Seleccionar widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"quitar widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"colocar widget seleccionado"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar usuario"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú expandible"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán las aplicaciones y los datos de esta sesión."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Comenzar ahora"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"No hay notificaciones"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"No hay notificaciones nuevas"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notific. adaptables activadas"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Tu dispositivo ahora baja el volumen y reduce las ventanas emergentes en la pantalla por hasta dos minutos si recibes muchas notificaciones en poco tiempo."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactivar"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloquea para ver notificaciones anteriores"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Tu padre o madre administra este dispositivo"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Tu organización es propietaria de este dispositivo y podría controlar el tráfico de red"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Presiona para obtener más información"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"No establecida"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"ingresa el bloqueo pantalla"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Toca el sensor de huellas dactilares. Es el botón más corto del lateral del teléfono"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de huellas dactilares"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"ingresar al dispositivo"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"En uso por <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Uso reciente en <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controles del sistema"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Apps del sistema"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Tareas múltiples"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Apps recientes"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Pantalla dividida"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Accesos directos a aplicaciones"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidad"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Atrás"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para volver, desliza tres dedos hacia la derecha o izquierda en cualquier lugar del panel táctil."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Panel táctil en el que aparecen tres dedos que se mueven hacia la derecha y la izquierda"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Pantalla de un dispositivo en la que aparece una animación del gesto atrás"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroiluminación del teclado"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivel %1$d de %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Controles de la casa"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 000db75..ae0527e 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ha detectado esta captura de pantalla."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> y otras aplicaciones abiertas han detectado esta captura de pantalla."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Añadir a nota"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Incluir enlace"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Grabación de pantalla"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando grabación de pantalla"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación continua de una sesión de grabación de la pantalla"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Dejarás de grabar &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Compartiendo pantalla"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Dejarás de compartir &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Enviando pantalla"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Dejarás de enviar &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado con la cara. Pulsa para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Cara reconocida. Pulsa para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Cara reconocida. Pulsa el icono de desbloquear para continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Desbloqueado con la cara. Toca para continuar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Se ha autenticado"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticación"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Más opciones"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Las funciones como Quick Share y Encontrar mi dispositivo usan Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"El Bluetooth se activará mañana por la mañana"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Compartir audio"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Compartiendo audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auriculares"</string>
@@ -387,7 +392,7 @@
     <string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Grabar pantalla"</string>
     <string name="performance" msgid="6552785217174378320">"Rendimiento"</string>
     <string name="user_interface" msgid="3712869377953950887">"Interfaz de usuario"</string>
-    <string name="thermal" msgid="6758074791325414831">"Térmico"</string>
+    <string name="thermal" msgid="6758074791325414831">"Temperatura"</string>
     <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Modo Una mano"</string>
     <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Audífonos"</string>
     <string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Activos"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Añade más widgets"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantén pulsado para personalizar los widgets"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Desbloquea para personalizar los widgets"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icono de la aplicación de widget inhabilitado"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Instalando icono de aplicación para widget"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"seleccionar widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"eliminar widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"colocar widget seleccionado"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar de usuario"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú desplegable"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Se eliminarán todas las aplicaciones y datos de esta sesión."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Empezar ahora"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"No hay notificaciones"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"No hay notificaciones nuevas"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notif. adaptativas activadas"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Tu dispositivo baja el volumen y reduce las ventanas emergentes durante un máximo de 2 minutos cuando recibes muchas notificaciones en poco tiempo."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactivar"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloquea para ver notificaciones anteriores"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo lo gestionan tu padre o tu madre"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"El dispositivo pertenece a tu organización, que puede monitorizar su tráfico de red"</string>
@@ -675,7 +690,7 @@
     <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para usar"</string>
     <string name="wallet_error_generic" msgid="257704570182963611">"Se ha producido un problema al obtener tus tarjetas. Inténtalo de nuevo más tarde."</string>
     <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Ajustes de pantalla de bloqueo"</string>
-    <string name="qr_code_scanner_title" msgid="1938155688725760702">"Escáner de códigos QR"</string>
+    <string name="qr_code_scanner_title" msgid="1938155688725760702">"Escáner QR"</string>
     <string name="qr_code_scanner_updating_secondary_label" msgid="8344598017007876352">"Actualizando"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Perfil de trabajo"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Modo Avión"</string>
@@ -1041,7 +1056,7 @@
     <string name="accessibility_floating_button_action_remove_menu" msgid="6730432848162552135">"Quitar"</string>
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"activar/desactivar"</string>
     <string name="accessibility_floating_button_action_edit" msgid="1688227814600463987">"Editar"</string>
-    <string name="quick_controls_title" msgid="6839108006171302273">"Control de dispositivos"</string>
+    <string name="quick_controls_title" msgid="6839108006171302273">"Control disposit."</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Elige una aplicación para añadir controles"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control añadido.}many{# controles añadidos.}other{# controles añadidos.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Quitado"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toca la pantalla para consultar más información"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ninguna puesta"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"Poner bloqueo de pantalla"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Toca el sensor de huellas digitales. Es el botón más pequeño del lateral del teléfono."</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de huellas digitales"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticarte"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"acceder al dispositivo"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"En uso por <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Usado recientemente por <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controles del sistema"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplicaciones del sistema"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitarea"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Aplicaciones recientes"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Pantalla dividida"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Accesos directos a aplicaciones"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidad"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Atrás"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para volver, desliza tres dedos hacia la izquierda o la derecha en cualquier punto del panel táctil."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Panel táctil con tres dedos moviéndose hacia la derecha y la izquierda"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Pantalla del dispositivo que muestra una animación del gesto para volver atrás"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroiluminación del teclado"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivel %1$d de %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Controles de la casa"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index fa10a8a..0bc2302 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> tuvastas selle ekraanipildi."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ja muud avatud rakendused tuvastasid selle ekraanipildi."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Lisa märkmesse"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Kaasa link"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Ekraanisalvesti"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekraanisalvestuse töötlemine"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pooleli märguanne ekraanikuva salvestamise seansi puhul"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Lõpetate rakenduse &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; sisu salvestamise"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekraani jagamine"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Lõpetate rakenduse &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; sisu jagamise"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Ekraanikuva ülekandmine"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Lõpetate rakenduse &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; sisu ülekandmise"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Avati näoga. Vajutage jätkamiseks."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Nägu tuvastati. Vajutage jätkamiseks."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Nägu tuvastati. Jätkamiseks vajutage avamise ikooni."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Avati näoga. Puudutage jätkamiseks."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenditud"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Tühista autentimine"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Rohkem valikuid"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Sellised funktsioonid nagu Kiirjagamine ja Leia mu seade kasutavad Bluetoothi."</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth lülitub sisse homme hommikul"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Jaga heli"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Heli jagamine"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> akut"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Heli"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Peakomplekt"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Lisage rohkem vidinaid"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Vajutage pikalt vidinate kohandamiseks"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Kohanda vidinaid"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Avage vidinate kohandamiseks"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Keelatud vidina rakenduseikoon"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Installitava vidina rakenduseikoon"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Muuda vidinat"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vidina valimine"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"eemaldage vidin"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"asetage valitud vidin"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Kasutaja vahetamine"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rippmenüü"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Seansi kõik rakendused ja andmed kustutatakse."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Alusta kohe"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Märguandeid pole"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Uusi märguandeid ei ole"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Kohanduvad märguanded on sees"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Seade vähendab nüüd helitugevust ja ekraanil kuvatavaid hüpikaknaid kuni kaheks minutiks, kui saate lühikese aja jooksul palju märguandeid."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Lülita välja"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Vanemate märguannete nägemiseks avage"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Seda seadet haldab sinu vanem"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Teie organisatsioon on selle seadme omanik ja võib jälgida võrguliiklust"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Puudutage lisateabe saamiseks"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Äratust pole"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"sisesta ekraanilukk"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Puudutage sõrmejäljeandurit. See on lühem nupp telefoni küljel."</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sõrmejäljeandur"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentimiseks"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"seadmesse sisenemiseks"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Seda kasutab <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Kasutas hiljuti rakendus <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Süsteem"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Süsteemi juhtelemendid"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Süsteemirakendused"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitegumtöö"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Hiljutised rakendused"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Jagatud ekraanikuva"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Sisend"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Rakenduse otseteed"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Juurdepääsetavus"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Tagasi"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Tagasiliikumiseks pühkige puuteplaadil kolme sõrmega vasakule või paremale."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Puuteplaat kolme paremale ja vasakule liikuva sõrmega"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Seadme ekraanil näidatakse tagasiliigutuse animatsiooni"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatuuri taustavalgustus"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Tase %1$d/%2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Kodu juhtelemendid"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 960a92f..0307b0e 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> aplikazioak pantaila-argazkia hauteman du."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> aplikazioak eta irekitako beste aplikazio batzuek pantaila-argazkia hauteman dute."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Gehitu oharrean"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Sartu esteka"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Pantaila-grabagailua"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Pantaila-grabaketa prozesatzen"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pantailaren grabaketa-saioaren jakinarazpen jarraitua"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; grabatzeari utziko diozu"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Pantaila partekatzen"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; partekatzeari utziko diozu"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Pantaila igortzen"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; igortzeari utziko diozu"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Aurpegiaren bidez desblokeatu da. Sakatu aurrera egiteko."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ezagutu da aurpegia. Sakatu aurrera egiteko."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ezagutu da aurpegia. Aurrera egiteko, sakatu desblokeatzeko ikonoa."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Aurpegiaren bidez desblokeatu da. Sakatu hau aurrera egiteko."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikatuta"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Utzi bertan behera autentifikazioa"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Aukera gehiago"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share, Bilatu nire gailua eta beste eginbide batzuek Bluetootha erabiltzen dute"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bihar goizean aktibatuko da Bluetootha"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Partekatu audioa"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Audioa partekatzen"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audioa"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Entzungailua"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Gehitu widget gehiago"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Widgetak pertsonalizatzeko, sakatu luze"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Pertsonalizatu widgetak"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Desblokeatu hau widgetak pertsonalizatzeko"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Desgaitutako widgetaren aplikazio-ikonoa"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Instalatzen ari den widget bati dagokion aplikazioaren ikonoa"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Editatu widgeta"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"hautatu widget bat"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"kendu widgeta"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"kokatu hautatutako widgeta"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Aldatu erabiltzailea"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"zabaldu menua"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Saioko aplikazio eta datu guztiak ezabatuko dira."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Hasi"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Ez dago jakinarazpenik"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Ez dago jakinarazpen berririk"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Jakinarazpen egokituak aktibatuta"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Epe labur batean jakinarazpen ugari jasotzen badituzu, bolumena jaitsi, eta pantailako leiho gainerakorrak murriztuko ditu gailuak orain, gehienez 2 minutuz."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desaktibatu"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Jakinarazpen zaharragoak ikusteko, desblokeatu"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Zure gurasoak kudeatzen du gailua"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Gailu hau zure erakundearena da, eta baliteke hark sareko trafikoa gainbegiratzea"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Informazio gehiago lortzeko, sakatu hau"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Alarmarik ez"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"erabili pantailaren blokeoa"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Ukitu hatz-marken sentsorea. Pantailaren albo batean dagoen botoi laburra da."</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Hatz-marken sentsorea"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentifikatu"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"sartu gailuan"</string>
@@ -1320,7 +1336,7 @@
     <string name="dismiss_dialog" msgid="2195508495854675882">"Baztertu"</string>
     <string name="connected_display_icon_desc" msgid="6373560639989971997">"Konektatutako pantaila"</string>
     <string name="privacy_dialog_title" msgid="7839968133469098311">"Mikrofonoa eta kamera"</string>
-    <string name="privacy_dialog_summary" msgid="2458769652125995409">"Aplikazioen azken erabilera"</string>
+    <string name="privacy_dialog_summary" msgid="2458769652125995409">"Aplikazioen azkenaldiko erabilera"</string>
     <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Ikusi azkenaldiko sarbidea"</string>
     <string name="privacy_dialog_done_button" msgid="4504330708531434263">"Eginda"</string>
     <string name="privacy_dialog_expand_action" msgid="9129262348628331377">"Zabaldu eta erakutsi aukerak"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioak darabil (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) aplikazioak erabili du duela gutxi"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistema kontrolatzeko aukerak"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistemaren aplikazioak"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Zeregin bat baino gehiago aldi berean exekutatzea"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Azkenaldiko aplikazioak"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Pantaila zatitzea"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Sarrera"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Aplikazioetarako lasterbideak"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Erabilerraztasuna"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Egin atzera"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Atzera egiteko, pasatu 3 hatz ezkerrera edo eskuinera ukipen-panelean."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"3 hatz ukipen-panel baten gainean eskuinera eta ezkerrera mugitzen erakusten duen irudia"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Gailuaren pantailan atzera egiteko keinuaren animazioa erakusten duen irudia"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Teklatuaren hondoko argia"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d/%2$d maila"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Etxeko gailuen kontrola"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index f02c248..752cc61 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"‫«<xliff:g id="APPNAME">%1$s</xliff:g>» این نماگرفت را تشخیص داد."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> و سایر برنامه‌های باز این نماگرفت را تشخیص دادند."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"افزودن به یادداشت"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"اضافه کردن پیوند"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"ضبط‌کن صفحه‌نمایش"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"درحال پردازش ضبط صفحه‌نمایش"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"اعلان درحال انجام برای جلسه ضبط صفحه‌نمایش"</string>
@@ -122,25 +123,30 @@
     <string name="screenrecord_stop_label" msgid="72699670052087989">"متوقف کردن"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"هم‌رسانی"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"قطعه ضبط‌شده از صفحه‌نمایش ذخیره شد"</string>
-    <string name="screenrecord_save_text" msgid="3008973099800840163">"برای مشاهده ضربه بزنید"</string>
+    <string name="screenrecord_save_text" msgid="3008973099800840163">"برای مشاهده تک‌ضرب بزنید"</string>
     <string name="screenrecord_save_error" msgid="5862648532560118815">"خطا در ذخیره‌سازی ضبط صفحه‌نمایش"</string>
     <string name="screenrecord_start_error" msgid="2200660692479682368">"خطا هنگام شروع ضبط صفحه‌نمایش"</string>
     <!-- no translation found for screenrecord_stop_dialog_title (2685522129492260887) -->
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"‏ضبط &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; را متوقف خواهید کرد"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"درحال هم‌رسانی صفحه‌نمایش"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"‏هم‌رسانی &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; را متوقف خواهید کرد"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"درحال پخش محتوای صفحه‌نمایش"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"‏پخش محتوای &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; را متوقف خواهید کرد"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -151,7 +157,7 @@
     <string name="issuerecord_ongoing_screen_only" msgid="6248206059935015722">"درحال ضبط کردن مشکل"</string>
     <string name="issuerecord_share_label" msgid="3992657993619876199">"هم‌رسانی"</string>
     <string name="issuerecord_save_title" msgid="4161043023696751591">"ضبط مشکل ذخیره شد"</string>
-    <string name="issuerecord_save_text" msgid="1205985304551521495">"برای مشاهده ضربه بزنید"</string>
+    <string name="issuerecord_save_text" msgid="1205985304551521495">"برای مشاهده تک‌ضرب بزنید"</string>
     <string name="issuerecord_save_error" msgid="6913040083446722726">"هنگام ذخیره کردن ضبط مشکل، خطایی پیش آمد"</string>
     <string name="issuerecord_start_error" msgid="3402782952722871190">"هنگام شروع ضبط مشکل، خطایی پیش آمد"</string>
     <string name="immersive_cling_title" msgid="8372056499315585941">"درحال مشاهده در حالت تمام‌صفحه"</string>
@@ -179,16 +185,17 @@
   </string-array>
     <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>
     <string name="biometric_dialog_face_icon_description_confirmed" msgid="7918067993953940778">"تأیید شد"</string>
-    <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"برای تکمیل، روی تأیید ضربه بزنید"</string>
+    <string name="biometric_dialog_tap_confirm" msgid="9166350738859143358">"برای تکمیل، روی تأیید تک‌ضرب بزنید"</string>
     <string name="biometric_dialog_tap_confirm_with_face" msgid="2378151312221818694">"قفل با چهره باز شد"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"قفلْ با چهره باز شد. برای ادامه، فشار دهید."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"چهره شناسایی شد. برای ادامه، فشار دهید."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"چهره شناسایی شد. برای ادامه، نماد قفل‌گشایی را فشار دهید."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"قفل با چهره باز شد. برای ادامه ضربه بزنید."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"راستی‌آزمایی‌شده"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"لغو اصالت‌سنجی"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"گزینه‌های بیشتر"</string>
@@ -290,7 +297,7 @@
     <string name="quick_settings_dnd_label" msgid="7728690179108024338">"مزاحم نشوید"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"بلوتوث"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"هیچ دستگاه مرتبط شده‌ای موجود نیست"</string>
-    <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"برای اتصال یا قطع اتصال دستگاه، ضربه بزنید"</string>
+    <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"برای اتصال یا قطع اتصال دستگاه، تک‌ضرب بزنید"</string>
     <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"جفت کردن دستگاه جدید"</string>
     <string name="see_all_bluetooth_devices" msgid="1761596816620200433">"دیدن همه"</string>
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"استفاده از بلوتوث"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ویژگی‌هایی مثل «هم‌رسانی سریع» و «پیدا کردن دستگاهم» از بلوتوث استفاده می‌کنند"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"بلوتوث فردا صبح روشن خواهد شد"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"هم‌رسانی صدا"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"درحال هم‌رسانی صدا"</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>
@@ -431,8 +436,8 @@
     <string name="zen_priority_customize_button" msgid="4119213187257195047">"سفارشی کردن"</string>
     <string name="zen_silence_introduction_voice" msgid="853573681302712348">"این کار «همه» صداها و لرزش‌ها (شامل هشدار، موسیقی، ویدیو و بازی) را مسدود می‌کند. همچنان می‌توانید تماس تلفنی برقرار کنید."</string>
     <string name="zen_silence_introduction" msgid="6117517737057344014">"این کار «همه» صداها و لرزش‌ها از جمله هشدارها، موسیقی، ویدئوها و بازی‌ها را مسدود می‌کند."</string>
-    <string name="notification_tap_again" msgid="4477318164947497249">"دوباره ضربه بزنید تا باز شود"</string>
-    <string name="tap_again" msgid="1315420114387908655">"دوباره ضربه بزنید"</string>
+    <string name="notification_tap_again" msgid="4477318164947497249">"دوباره تک‌ضرب بزنید تا باز شود"</string>
+    <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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"افزودن ابزارک‌های بیشتر"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"برای سفارشی‌سازی ابزارک‌ها، فشار طولانی دهید"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"سفارشی‌سازی ابزارک‌ها"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"برای سفارشی‌سازی ابزاره‌ها، قفل دستگاه را باز کنید"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"نماد برنامه برای ابزارک غیرفعال"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"نماد برنامه مربوط به ابزارکی که درحال نصب است"</string>
     <string name="edit_widget" msgid="9030848101135393954">"ویرایش ابزارک"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"انتخاب ابزارک"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"برداشتن ابزارک"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"جای‌گذاری ابزارک انتخاب‌شده"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"تغییر کاربر"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"منوی پایین‌پر"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"همه برنامه‌ها و داده‌های این جلسه حذف خواهد شد."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"اکنون شروع کنید"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"اعلانی موجود نیست"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"اعلان جدیدی وجود ندارد"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"اعلان‌های تطبیقی روشن است"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"ازاین‌پس هروقت اعلان‌های زیادی در یک بازه زمانی کوتاه دریافت کنید، دستگاهتان تا دو دقیقه صدا را کم می‌کند و تعداد پنجره‌های بالاپر را در صفحه‌نمایش کاهش می‌دهد."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"خاموش کردن"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"برای دیدن اعلان‌های قبلی قفل را باز کنید"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"این دستگاه را ولی‌تان مدیریت می‌کند"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"مالک این دستگاه سازمان شما است و ممکن است ترافیک شبکه را پایش کند"</string>
@@ -634,17 +649,17 @@
     <string name="stream_notification_unavailable" msgid="4313854556205836435">"دردسترس نیست، چون زنگ بی‌صدا شده است"</string>
     <string name="stream_alarm_unavailable" msgid="4059817189292197839">"دردسترس نیست زیرا «مزاحم نشوید» روشن است"</string>
     <string name="stream_media_unavailable" msgid="6823020894438959853">"دردسترس نیست زیرا «مزاحم نشوید» روشن است"</string>
-    <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"‏%1$s. برای باصدا کردن ضربه بزنید."</string>
-    <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"‏%1$s. برای تنظیم روی لرزش ضربه بزنید. ممکن است سرویس‌های دسترس‌پذیری بی‌صدا شوند."</string>
-    <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"‏%1$s. برای صامت کردن ضربه بزنید. ممکن است سرویس‌های دسترس‌پذیری صامت شود."</string>
-    <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"‏%1$s. برای تنظیم روی لرزش، ضربه بزنید."</string>
-    <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"‏%1$s. برای صامت کردن ضربه بزنید."</string>
+    <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"‏%1$s. برای باصدا کردن تک‌ضرب بزنید."</string>
+    <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"‏%1$s. برای تنظیم روی لرزش تک‌ضرب بزنید. ممکن است سرویس‌های دسترس‌پذیری بی‌صدا شوند."</string>
+    <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"‏%1$s. برای صامت کردن تک‌ضرب بزنید. ممکن است سرویس‌های دسترس‌پذیری صامت شود."</string>
+    <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"‏%1$s. برای تنظیم روی لرزش، تک‌ضرب بزنید."</string>
+    <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"‏%1$s. برای صامت کردن تک‌ضرب بزنید."</string>
     <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"کنترل صدای محیط"</string>
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"صدای فضایی"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"خاموش"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ثابت"</string>
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ردیابی سر"</string>
-    <string name="volume_ringer_change" msgid="3574969197796055532">"برای تغییر حالت زنگ، ضربه بزنید"</string>
+    <string name="volume_ringer_change" msgid="3574969197796055532">"برای تغییر حالت زنگ، تک‌ضرب بزنید"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"صامت کردن"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"باصدا کردن"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"لرزش"</string>
@@ -670,7 +685,7 @@
     <string name="wallet_title" msgid="5369767670735827105">"کیف پول"</string>
     <string name="wallet_empty_state_label" msgid="7776761245237530394">"برای خرید سریع‌تر و امن‌تر با تلفن، راه‌اندازی کنید"</string>
     <string name="wallet_app_button_label" msgid="7123784239111190992">"نمایش همه"</string>
-    <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"برای باز کردن ضربه بزنید"</string>
+    <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"برای باز کردن تک‌ضرب بزنید"</string>
     <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>
@@ -936,7 +951,7 @@
     <string name="instant_apps" msgid="8337185853050247304">"برنامه‌های فوری"</string>
     <string name="instant_apps_title" msgid="8942706782103036910">"‫‫<xliff:g id="APP">%1$s</xliff:g> درحال اجرا"</string>
     <string name="instant_apps_message" msgid="6112428971833011754">"برنامه بدون نصب شدن باز شد."</string>
-    <string name="instant_apps_message_with_help" msgid="1816952263531203932">"برنامه بدون نصب شدن باز شد. برای اطلاعات بیشتر ضربه بزنید."</string>
+    <string name="instant_apps_message_with_help" msgid="1816952263531203932">"برنامه بدون نصب شدن باز شد. برای اطلاعات بیشتر تک‌ضرب بزنید."</string>
     <string name="app_info" msgid="5153758994129963243">"اطلاعات برنامه"</string>
     <string name="go_to_web" msgid="636673528981366511">"رفتن به مرورگر"</string>
     <string name="mobile_data" msgid="4564407557775397216">"داده تلفن همراه"</string>
@@ -950,7 +965,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>
@@ -965,7 +980,7 @@
     <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_deny" msgid="6870256451658176895">"مجاز نبودن"</string>
-    <string name="auto_saver_title" msgid="6873691178754086596">"برای زمان‌بندی «بهینه‌سازی باتری» ضربه بزنید"</string>
+    <string name="auto_saver_title" msgid="6873691178754086596">"برای زمان‌بندی «بهینه‌سازی باتری» تک‌ضرب بزنید"</string>
     <string name="auto_saver_text" msgid="3214960308353838764">"وقتی باتری روبه‌اتمام است، بهینه‌سازی باتری را روشن کنید"</string>
     <string name="no_auto_saver_action" msgid="7467924389609773835">"نه متشکرم"</string>
     <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"استفاده شده"</string>
@@ -1025,11 +1040,11 @@
     <string name="accessibility_magnification_done" msgid="263349129937348512">"تمام"</string>
     <string name="accessibility_magnifier_edit" msgid="1522877239671820636">"ویرایش"</string>
     <string name="accessibility_magnification_magnifier_window_settings" msgid="2834685072221468434">"تنظیمات پنجره ذره‌بین"</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_undo" msgid="511112888715708241">"واگرد"</string>
     <string name="accessibility_floating_button_hidden_notification_title" msgid="4115036997406994799">"دکمه دسترس‌پذیری پنهان شده است"</string>
-    <string name="accessibility_floating_button_hidden_notification_text" msgid="1457021647040915658">"برای نمایش دکمه دسترس‌پذیری ضربه بزنید"</string>
+    <string name="accessibility_floating_button_hidden_notification_text" msgid="1457021647040915658">"برای نمایش دکمه دسترس‌پذیری تک‌ضرب بزنید"</string>
     <string name="accessibility_floating_button_undo_message_label_text" msgid="9017658016426242640">"میان‌بر «<xliff:g id="FEATURE_NAME">%s</xliff:g>» برداشته شد"</string>
     <string name="accessibility_floating_button_undo_message_number_text" msgid="4909270290725226075">"{count,plural, =1{میان‌بر «#» برداشته شد}one{میان‌بر «#» برداشته شد}other{میان‌بر «#» برداشته شد}}"</string>
     <string name="accessibility_floating_button_action_move_top_left" msgid="6253520703618545705">"انتقال به بالا سمت راست"</string>
@@ -1130,7 +1145,7 @@
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"۱ دستگاه انتخاب شد"</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_connect_failed" msgid="3080972621975339387">"عوض نمی‌شود. برای تلاش مجدد تک‌ضرب بزنید."</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>
@@ -1159,7 +1174,7 @@
     <string name="build_number_copy_toast" msgid="877720921605503046">"شماره ساخت در بریده‌دان کپی شد."</string>
     <string name="basic_status" msgid="2315371112182658176">"باز کردن مکالمه"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"ابزارک‌های مکالمه"</string>
-    <string name="select_conversation_text" msgid="3376048251434956013">"روی مکالمه‌ای ضربه بزنید تا به «صفحه اصلی» اضافه شود"</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"روی مکالمه‌ای تک‌ضرب بزنید تا به «صفحه اصلی» اضافه شود"</string>
     <string name="no_conversations_text" msgid="5354115541282395015">"آخرین مکالمه‌های شما اینجا نشان داده می‌شود"</string>
     <string name="priority_conversations" msgid="3967482288896653039">"مکالمه‌های اولویت‌دار"</string>
     <string name="recent_conversations" msgid="8531874684782574622">"گفتگوهای اخیر"</string>
@@ -1194,9 +1209,10 @@
     <string name="new_status_content_description" msgid="6046637888641308327">"<xliff:g id="NAME">%1$s</xliff:g> وضعیتش را به‌روزرسانی کرد: <xliff:g id="STATUS">%2$s</xliff:g>"</string>
     <string name="person_available" msgid="2318599327472755472">"دردسترس"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"مشکلی در خواندن میزان باتری وجود دارد"</string>
-    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"برای اطلاعات بیشتر ضربه بزنید"</string>
+    <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"برای اطلاعات بیشتر تک‌ضرب بزنید"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"هشداری تنظیم نشده"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"وارد کردن قفل صفحه"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"حسگر اثر انگشت را لمس کنید. این حسگر همان دکمه کوچک‌تر در کنار تلفن است"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"حسگر اثرانگشت"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"اصالت‌سنجی کردن"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"وارد شدن به دستگاه"</string>
@@ -1213,7 +1229,7 @@
     <string name="non_carrier_network_unavailable" msgid="770049357024492372">"شبکه دیگری وجود ندارد"</string>
     <string name="all_network_unavailable" msgid="4112774339909373349">"شبکه‌ای در دسترس نیست"</string>
     <string name="turn_on_wifi" msgid="1308379840799281023">"Wi-Fi"</string>
-    <string name="tap_a_network_to_connect" msgid="1565073330852369558">"برای اتصال به شبکه روی آن ضربه بزنید"</string>
+    <string name="tap_a_network_to_connect" msgid="1565073330852369558">"برای اتصال به شبکه روی آن تک‌ضرب بزنید"</string>
     <string name="unlock_to_view_networks" msgid="5072880496312015676">"برای مشاهده شبکه‌ها، قفل صفحه را باز کنید"</string>
     <string name="wifi_empty_list_wifi_on" msgid="3864376632067585377">"درحال جستجوی شبکه…"</string>
     <string name="wifi_failed_connect_message" msgid="4161863112079000071">"اتصال به شبکه برقرار نشد"</string>
@@ -1239,7 +1255,7 @@
     <string name="clipboard_edit_text_description" msgid="805254383912962103">"ویرایش نوشتار کپی‌شده"</string>
     <string name="clipboard_edit_image_description" msgid="8904857948976041306">"ویرایش تصویر کپی‌شده"</string>
     <string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ارسال به دستگاهی در اطراف"</string>
-    <string name="clipboard_text_hidden" msgid="7926899867471812305">"برای مشاهده، ضربه بزنید"</string>
+    <string name="clipboard_text_hidden" msgid="7926899867471812305">"برای مشاهده، تک‌ضرب بزنید"</string>
     <string name="clipboard_text_copied" msgid="5100836834278976679">"نوشتار کپی شد"</string>
     <string name="clipboard_image_copied" msgid="3793365360174328722">"تصویر کپی شد"</string>
     <string name="clipboard_content_copied" msgid="144452398567828145">"محتوا کپی شد"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> از آن استفاده می‌کند (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"اخیراً <xliff:g id="APP_NAME">%1$s</xliff:g> از آن استفاده کرده است (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"سیستم"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"کنترل‌های سیستم"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"برنامه‌های سیستم"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"چندوظیفگی"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"برنامه‌های اخیر"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"صفحهٔ دونیمه"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"ورودی"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"میان‌برهای برنامه"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"دسترس‌پذیری"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"برگشتن"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"برای برگشتن، در هر جایی از صفحه لمسی، با سه انگشت تند به‌چپ یا راست بکشید."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"صفحه لمسی که سه انگشت را درحال حرکت به‌سمت راست و چپ نشان می‌دهد"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"صفحه‌نمایش دستگاه درحال نمایش پویانمایی مربوط به اشاره برگشتن"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"نور پس‌زمینه صفحه‌کلید"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"‏سطح %1$d از %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"کنترل خانه هوشمند"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 9a24082..b9eae3d 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> havaitsi tämän kuvakaappauksen."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ja jotkin muut sovellukset havaitsivat tämän kuvakaappauksen."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Lisää muistiinpanoon"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Lisää linkki"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Näytön tallentaja"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Näytön tallennusta käsitellään"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pysyvä ilmoitus näytön tallentamisesta"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ei enää tallenna sisältöä"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Näyttöä jaetaan"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ei enää jaa sisältöä"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Näyttöä striimataan"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ei enää striimaa sisältöä"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Avattu kasvojen avulla. Jatka painamalla."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Kasvot tunnistettu. Jatka painamalla."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Kasvot tunnistettu. Jatka lukituksen avauskuvakkeella."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Avattu kasvojen avulla. Jatka napauttamalla."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Todennettu"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Peruuta todennus"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Lisää vaihtoehtoja"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share, Paikanna laite ja tietyt muut ominaisuudet käyttävät Bluetoothia"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth menee päälle huomisaamuna"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Jaa audio"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Audiota jaetaan"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akun taso <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Ääni"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Lisää widgetejä"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Yksilöi widgetit pitkällä painalluksella"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Muokkaa widgettejä"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Avaa widgetien yksilöintiä varten"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Käytöstä poistetun widgetin sovelluskuvake"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Sovelluskuvake widgetin asentamisesta"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Muokkaa widgetiä"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"valitse widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"poista widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"aseta valittu widget"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Vaihda käyttäjää"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"alasvetovalikko"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Kaikki sovellukset ja tämän istunnon tiedot poistetaan."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Aloita nyt"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Ei ilmoituksia"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Ei uusia ilmoituksia"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Mukautuvat ilmoitukset päällä"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Laite vähentää nyt äänenvoimakkuutta ja ponnahdusikkunoiden määrää enintään kahdeksi minuutiksi, kun saat monta ilmoitusta lyhyellä aikavälillä."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Laita pois päältä"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Avaa lukitus niin näet ilmoituksia"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Vanhempasi ylläpitää tätä laitetta"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisaatiosi omistaa laitteen ja voi valvoa verkkoliikennettä"</string>
@@ -814,8 +829,8 @@
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Syöttötapa"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Vaihda seuraavaan kieleen"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Vaihda aiempaan kieleen"</string>
-    <string name="input_access_emoji" msgid="8105642858900406351">"Emojien käyttö"</string>
-    <string name="input_access_voice_typing" msgid="7291201476395326141">"Puhekirjoituksen käyttö"</string>
+    <string name="input_access_emoji" msgid="8105642858900406351">"Käytä emojeja"</string>
+    <string name="input_access_voice_typing" msgid="7291201476395326141">"Käytä puhekirjoitusta"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Sovellukset"</string>
     <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
     <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Selain"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Saat lisätietoja napauttamalla"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ei herätyksiä"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"käytä näytön lukitustapaa"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Kosketa sormenjälkitunnistinta. Se on puhelimen sivussa oleva lyhyempi painike."</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sormenjälkitunnistin"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"todentaaksesi"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"avataksesi laitteen"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Tämän käytössä: <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> käytti tätä äskettäin (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Järjestelmä"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Järjestelmän hallinta"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Järjestelmäsovellukset"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitaskaus"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Viimeisimmät sovellukset"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Jaettu näyttö"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Syöte"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Sovellusten pikakuvakkeet"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Saavutettavuus"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Takaisin"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Jos haluat siirtyä takaisin, pyyhkäise kosketuslevyllä vasemmalle tai oikealle kolmella sormella."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Kosketuslevy, jolla kolme sormea liikkuu oikealle ja vasemmalle"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Laitteen näyttö, jolla näkyy animaatio takaisin-eleestä"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Näppämistön taustavalo"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Taso %1$d/%2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Kodin ohjaus"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA-ldrtl/strings.xml b/packages/SystemUI/res/values-fr-rCA-ldrtl/strings.xml
index 899fec0..9421af3 100644
--- a/packages/SystemUI/res/values-fr-rCA-ldrtl/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA-ldrtl/strings.xml
@@ -19,5 +19,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="recents_quick_scrub_onboarding" msgid="2452671841151577157">"Balayez l\'écran vers la gauche pour changer rapidement d\'application"</string>
+    <string name="recents_quick_scrub_onboarding" msgid="2452671841151577157">"Balayez l\'écran vers la gauche pour changer rapidement d\'appli"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 77335de..b1aec7d 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -35,16 +35,16 @@
     <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Extrême"</string>
     <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rotation auto de l\'écran"</string>
     <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
-    <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Autorisé <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nCette application n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait enregistrer du contenu audio par l\'intermédiaire de cet appareil USB."</string>
+    <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Autorisé <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nCette appli n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait enregistrer du contenu audio par l\'intermédiaire de cet appareil USB."</string>
     <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
     <string name="usb_audio_device_confirm_prompt_title" msgid="8828406516732985696">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour utiliser <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
-    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Cette application n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait capturer du contenu audio par l\'intermédiaire de cet appareil USB. L\'utilisation de <xliff:g id="APPLICATION">%1$s</xliff:g> avec cet appareil peut empêcher d\'entendre les appels, les notifications et les alarmes."</string>
+    <string name="usb_audio_device_prompt_warn" msgid="2504972133361130335">"Cette appli n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait capturer du contenu audio par l\'intermédiaire de cet appareil USB. L\'utilisation de <xliff:g id="APPLICATION">%1$s</xliff:g> avec cet appareil peut empêcher d\'entendre les appels, les notifications et les alarmes."</string>
     <string name="usb_audio_device_prompt" msgid="7944987408206252949">"L\'utilisation de <xliff:g id="APPLICATION">%1$s</xliff:g> avec cet appareil peut empêcher d\'entendre les appels, les notifications et les alarmes."</string>
     <string name="usb_accessory_permission_prompt" msgid="717963550388312123">"Autoriser <xliff:g id="APPLICATION">%1$s</xliff:g> à accéder à <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
     <string name="usb_device_confirm_prompt" msgid="4091711472439910809">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour utiliser <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
-    <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour gérer <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nCette application n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait enregistrer du contenu audio par l\'intermédiaire de cet appareil USB."</string>
+    <string name="usb_device_confirm_prompt_warn" msgid="990208659736311769">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour gérer <xliff:g id="USB_DEVICE">%2$s</xliff:g>?\nCette appli n\'a pas été autorisée à effectuer des enregistrements, mais elle pourrait enregistrer du contenu audio par l\'intermédiaire de cet appareil USB."</string>
     <string name="usb_accessory_confirm_prompt" msgid="5728408382798643421">"Ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> pour utiliser <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>?"</string>
-    <string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"Aucune application installée compatible avec accessoire USB. En savoir plus sur <xliff:g id="URL">%1$s</xliff:g>"</string>
+    <string name="usb_accessory_uri_prompt" msgid="6756649383432542382">"Aucune appli installée compatible avec accessoire USB. En savoir plus sur <xliff:g id="URL">%1$s</xliff:g>"</string>
     <string name="title_usb_accessory" msgid="1236358027511638648">"Accessoire USB"</string>
     <string name="label_view" msgid="6815442985276363364">"Afficher"</string>
     <string name="always_use_device" msgid="210535878779644679">"Toujours ouvrir <xliff:g id="APPLICATION">%1$s</xliff:g> lorsque <xliff:g id="USB_DEVICE">%2$s</xliff:g> est connecté"</string>
@@ -83,7 +83,7 @@
     <string name="screenshot_failed_to_save_user_locked_text" msgid="6156607948256936920">"L\'appareil doit être déverrouillé avant qu\'une capture d\'écran puisse être enregistrée"</string>
     <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Essayez de faire une autre capture d\'écran"</string>
     <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Impossible d\'enregistrer la capture d\'écran"</string>
-    <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"L\'application ou votre organisation n\'autorise pas les saisies d\'écran"</string>
+    <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"L\'appli ou votre organisation n\'autorise pas les saisies d\'écran"</string>
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"La prise de captures d\'écran est bloquée par votre administrateur informatique"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Modifier"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Modifier la capture d\'écran"</string>
@@ -101,14 +101,15 @@
     <string name="screenshot_private_profile_notification" msgid="1704440899154243171">"Enregistré dans <xliff:g id="APP">%1$s</xliff:g> dans le profil privé"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Fichiers"</string>
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> a détecté cette capture d\'écran."</string>
-    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> et d\'autres applications ouvertes ont détecté cette capture d\'écran."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> et d\'autres applis ouvertes ont détecté cette capture d\'écran."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ajouter à une note"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Inclure le lien"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Enregistreur d\'écran"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Trait. de l\'enregist. d\'écran…"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notification en cours pour une session d\'enregistrement d\'écran"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Commencer l\'enregistrement?"</string>
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Pendant l\'enregistrement, Android a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Lorsque vous enregistrez une application, Android a accès à tout ce qui est visible ou lu sur cette application. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Lorsque vous enregistrez une appli, Android a accès à tout ce qui est visible ou lu sur cette appli. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Commencer l\'enregistrement"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Enregistrer des fichiers audio"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Audio de l\'appareil"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Vous arrêterez d\'enregistrer &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Partage d\'écran en cours…"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Vous arrêterez de partager &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Diffusion de l\'écran en cours…"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Vous arrêterez de diffuser &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -174,7 +180,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Numérisation du visage"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Envoyer"</string>
     <string name="cancel" msgid="1089011503403416730">"Annuler"</string>
-    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logo de l\'application"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logo de l\'appli"</string>
   <string-array name="biometric_dialog_package_names_for_logo_with_overrides">
   </string-array>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmer"</string>
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Déverr. par reconnaissance faciale. Appuyez pour continuer."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Visage reconnu. Appuyez pour continuer."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Visage reconnu. Appuyez sur Déverrouiller pour continuer."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Déverrouillé avec le visage. Touchez pour continuer."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifié"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Annuler l\'authentification"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Plus d\'options"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Les fonctionnalités comme Partage rapide et Localiser mon appareil utilisent le Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Le Bluetooth s\'activera demain matin"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Partager l\'audio"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Partage de l\'audio en cours…"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Pile : <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Écouteurs"</string>
@@ -357,7 +362,7 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="6798849610647988987">"Quantité de données utilisées :<xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"Limite : <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"Avertissement : <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Applications professionnelles"</string>
+    <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Applis professionnelles"</string>
     <string name="quick_settings_work_mode_paused_state" msgid="6681788236383735976">"En pause"</string>
     <string name="quick_settings_night_display_label" msgid="8180030659141778180">"Éclairage nocturne"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Activé la nuit"</string>
@@ -401,9 +406,9 @@
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Débloquer le microphone de l\'appareil?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Débloquer l\'appareil photo de l\'appareil?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Débloquer l\'appareil photo et le microphone?"</string>
-    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Cette action débloque l\'accès pour toutes les applications et tous les services autorisés à utiliser le microphone."</string>
-    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Cette action débloque l\'accès pour toutes les applications et pour tous les services autorisés à utiliser l\'appareil photo."</string>
-    <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Cette action débloque l\'accès pour toutes les applications et tous les services autorisés à utiliser l\'appareil photo ou le microphone."</string>
+    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Cette action débloque l\'accès pour toutes les applis et tous les services autorisés à utiliser le microphone."</string>
+    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Cette action débloque l\'accès pour toutes les applis et pour tous les services autorisés à utiliser l\'appareil photo."</string>
+    <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Cette action débloque l\'accès pour toutes les applis et tous les services autorisés à utiliser l\'appareil photo ou le microphone."</string>
     <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"Le microphone est bloqué"</string>
     <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"L\'appareil photo est bloqué"</string>
     <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"Le microphone et l\'appareil photo sont bloqués"</string>
@@ -415,13 +420,13 @@
     <string name="sensor_privacy_mic_camera_unblocked_toast_content" msgid="7339355093282661115">"Microphone et appareil photo disponibles"</string>
     <string name="sensor_privacy_mic_turned_on_dialog_title" msgid="6348853159838376513">"Microphone activé"</string>
     <string name="sensor_privacy_mic_turned_off_dialog_title" msgid="5760464281790732849">"Microphone désactivé"</string>
-    <string name="sensor_privacy_mic_unblocked_dialog_content" msgid="4889961886199270224">"Le microphone est activé pour toutes les applications et tous les services."</string>
-    <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"L\'accès au microphone est désactivé pour toutes les applications et tous les services. Vous pouvez l\'activer dans Paramètres &gt; Confidentialité &gt; Microphone."</string>
-    <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"L\'accès au microphone est désactivé pour toutes les applications et tous les services. Vous pouvez modifier cette option dans Paramètres &gt; Confidentialité &gt; Microphone."</string>
+    <string name="sensor_privacy_mic_unblocked_dialog_content" msgid="4889961886199270224">"Le microphone est activé pour toutes les applis et tous les services."</string>
+    <string name="sensor_privacy_mic_blocked_no_exception_dialog_content" msgid="5864898470772965394">"L\'accès au microphone est désactivé pour toutes les applis et tous les services. Vous pouvez l\'activer dans Paramètres &gt; Confidentialité &gt; Microphone."</string>
+    <string name="sensor_privacy_mic_blocked_with_exception_dialog_content" msgid="810289713700437896">"L\'accès au microphone est désactivé pour toutes les applis et tous les services. Vous pouvez modifier cette option dans Paramètres &gt; Confidentialité &gt; Microphone."</string>
     <string name="sensor_privacy_camera_turned_on_dialog_title" msgid="8039095295100075952">"Appareil photo activé"</string>
     <string name="sensor_privacy_camera_turned_off_dialog_title" msgid="1936603903120742696">"Appareil photo désactivé"</string>
-    <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"L\'appareil photo est activé pour toutes les applications et tous les services."</string>
-    <string name="sensor_privacy_camera_blocked_dialog_content" msgid="3182428709314874616">"L\'accès à l\'appareil photo est désactivé pour toutes les applications et tous les services."</string>
+    <string name="sensor_privacy_camera_unblocked_dialog_content" msgid="7847190103011782278">"L\'appareil photo est activé pour toutes les applis et tous les services."</string>
+    <string name="sensor_privacy_camera_blocked_dialog_content" msgid="3182428709314874616">"L\'accès à l\'appareil photo est désactivé pour toutes les applis et tous les services."</string>
     <string name="sensor_privacy_htt_blocked_dialog_content" msgid="3333321592997666441">"Pour utiliser le bouton du microphone, activez l\'accès au microphone dans les paramètres."</string>
     <string name="sensor_privacy_dialog_open_settings" msgid="5635865896053011859">"Ouvrir les paramètres"</string>
     <string name="media_seamless_other_device" msgid="4654849800789196737">"Autre appareil"</string>
@@ -471,14 +476,15 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Ajouter plus de widgets"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Maintenez le doigt pour personnaliser les widgets"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personnaliser les widgets"</string>
-    <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icône d\'application pour un widget désactivé"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Déverrouiller pour personnaliser des widgets"</string>
+    <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icône d\'appli pour un widget désactivé"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Icône d\'appli indiquant qu\'un widget est en cours d\'installation"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Modifier le widget"</string>
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Retirer"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Ajouter un widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Terminé"</string>
     <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Ajouter des widgets"</string>
-    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Accédez rapidement aux widgets de vos applications préférées sans déverrouiller votre tablette."</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Accédez rapidement aux widgets de vos applis préférées sans déverrouiller votre tablette."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Autoriser n\'importe quel widget sur l\'écran de verrouillage?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Ouvrir les paramètres"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Réactiver les applis pros?"</string>
@@ -489,47 +495,53 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"sélectionner le widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"retirer le widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"placer le widget sélectionné"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Changer d\'utilisateur"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu déroulant"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applis et les données de cette session seront supprimées."</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Bienvenue à nouveau dans la session Invité"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Voulez-vous poursuivre la session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recommencer"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Oui, continuer"</string>
     <string name="guest_notification_app_name" msgid="2110425506754205509">"Mode Invité"</string>
     <string name="guest_notification_session_active" msgid="5567273684713471450">"Vous êtes en mode Invité"</string>
-    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Si vous ajoutez un nouvel utilisateur, vous quitterez le mode Invité, et toutes les applications et données de la session d\'invité en cours seront supprimées."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Si vous ajoutez un nouvel utilisateur, vous quitterez le mode Invité, et toutes les applis et données de la session d\'invité en cours seront supprimées."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite d\'utilisateurs atteinte"</string>
     <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Vous ne pouvez créer qu\'un seul utilisateur.}one{Vous pouvez ajouter jusqu\'à # utilisateur.}many{Vous pouvez ajouter jusqu\'à # d\'utilisateurs.}other{Vous pouvez ajouter jusqu\'à # utilisateurs.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Supprimer l\'utilisateur?"</string>
-    <string name="user_remove_user_message" msgid="6702834122128031833">"Toutes les applications et les données de cet utilisateur seront supprimées."</string>
+    <string name="user_remove_user_message" msgid="6702834122128031833">"Toutes les applis et les données de cet utilisateur seront supprimées."</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"Supprimer"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Commencer à enregistrer ou à diffuser avec <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
     <string name="media_projection_dialog_warning" msgid="1303664408388363598">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aura accès à toute l\'information qui est visible sur votre écran ou lue sur votre appareil durant l\'enregistrement ou la diffusion. Cela comprend des renseignements comme les mots de passe, les détails du paiement, les photos, les messages et les contenus audio que vous faites jouer."</string>
     <string name="media_projection_sys_service_dialog_title" msgid="3751133258891897878">"Commencer à enregistrer ou à diffuser?"</string>
     <string name="media_projection_sys_service_dialog_warning" msgid="2443872865267330320">"Le service offrant cette fonction aura accès à toute l\'information qui est visible sur votre écran ou lu sur votre appareil pendant que vous enregistrez ou diffusez. Cela comprend des renseignements comme les mots de passe, les détails du paiement, les photos, les messages et le contenu audio que vous faites jouer."</string>
     <string name="screen_share_permission_dialog_option_entire_screen" msgid="3131200488455089620">"Écran entier"</string>
-    <string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"Une seule application"</string>
-    <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Partager ou enregistrer une application"</string>
+    <string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"Une seule appli"</string>
+    <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Partager ou enregistrer une appli"</string>
     <string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"Commencer à enregistrer ou à diffuser avec <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
     <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Lorsque vous partagez, enregistrez ou diffusez, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
-    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Lorsque vous partagez, enregistrez ou diffusez une application, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> a accès à tout ce qui est visible sur votre écran ou lu sur cette application. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
+    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Lorsque vous partagez, enregistrez ou diffusez une appli, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> a accès à tout ce qui est visible sur votre écran ou lu sur cette appli. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
     <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Commencer"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> a désactivé cette option"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Commencer la diffusion?"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Lorsque vous diffusez, Android a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Lorsque vous diffusez une application, Android a accès à tout ce qui est visible sur votre écran ou lu sur cette application. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Lorsque vous diffusez une appli, Android a accès à tout ce qui est visible sur votre écran ou lu sur cette appli. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Commencer la diffusion"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Commencer à partager?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Lorsque vous partagez, enregistrez ou diffusez, Android a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
-    <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Lorsque vous partagez, enregistrez ou diffusez une application, Android a accès à tout ce qui est visible sur votre écran ou lu sur cette application. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
+    <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Lorsque vous partagez, enregistrez ou diffusez une appli, Android a accès à tout ce qui est visible sur votre écran ou lu sur cette appli. Par conséquent, soyez prudent avec les mots de passe, les détails du paiement, les messages, les photos et les contenus audio et vidéo."</string>
     <string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Commencer"</string>
-    <string name="media_projection_task_switcher_text" msgid="590885489897412359">"Le partage s\'interrompt lorsque vous changez d\'application"</string>
-    <string name="media_projection_task_switcher_action_switch" msgid="8682258717291921123">"Partager plutôt cette application"</string>
+    <string name="media_projection_task_switcher_text" msgid="590885489897412359">"Le partage s\'interrompt lorsque vous changez d\'appli"</string>
+    <string name="media_projection_task_switcher_action_switch" msgid="8682258717291921123">"Partager plutôt cette appli"</string>
     <string name="media_projection_task_switcher_action_back" msgid="5324164224147845282">"Revenir en arrière"</string>
-    <string name="media_projection_task_switcher_notification_channel" msgid="7613206306777814253">"Commutateur d\'application"</string>
+    <string name="media_projection_task_switcher_notification_channel" msgid="7613206306777814253">"Commutateur d\'appli"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Bloquée par votre administrateur informatique"</string>
-    <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"La fonctionnalité de capture d\'écran est désactivée par l\'application Device Policy"</string>
+    <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"La fonctionnalité de capture d\'écran est désactivée par l\'appli Device Policy"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Tout effacer"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Gérer"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Historique"</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Aucune notification"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Aucune nouvelle notification"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notifications adaptatives actives"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Votre appareil réduit le volume et les fenêtres contextuelles à l\'écran pendant 2 minutes max. quand vous recevez plusieurs notifications rapidement."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Désactiver"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Déverr. pour voir les anciennes notif."</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Cet appareil est géré par ton parent"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Votre organisation possède cet appareil et peut contrôler le trafic réseau"</string>
@@ -558,8 +573,8 @@
     <string name="quick_settings_disclosure_managed_profile_network_activity" msgid="2636594621387832827">"Votre administrateur informatique a accès à l\'activité sur le réseau de votre profil professionnel"</string>
     <string name="quick_settings_disclosure_monitoring" msgid="8548019955631378680">"Le réseau peut être surveillé"</string>
     <string name="quick_settings_disclosure_vpns" msgid="3586175303518266301">"Cet appareil est connecté à Internet par l\'intermédiaire de RPV"</string>
-    <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Vos applications professionnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
-    <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Vos applications personnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_managed_profile_named_vpn" msgid="153393105176944100">"Vos applis professionnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
+    <string name="quick_settings_disclosure_personal_profile_named_vpn" msgid="451254750289172191">"Vos applis personnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="quick_settings_disclosure_named_vpn" msgid="6191822916936028208">"Cet appareil est connecté à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>"</string>
     <string name="monitoring_title_financed_device" msgid="3659962357973919387">"Cet appareil est fourni par <xliff:g id="ORGANIZATION_NAME">%s</xliff:g>"</string>
     <string name="monitoring_title_device_owned" msgid="7029691083837606324">"Gestion d\'appareils"</string>
@@ -568,9 +583,9 @@
     <string name="monitoring_subtitle_ca_certificate" msgid="8588092029755175800">"Certificats CA"</string>
     <string name="monitoring_button_view_policies" msgid="3869724835853502410">"Afficher les politiques"</string>
     <string name="monitoring_button_view_controls" msgid="8316440345340701117">"Afficher les commandes"</string>
-    <string name="monitoring_description_named_management" msgid="505833016545056036">"Votre appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVotre administrateur informatique peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applications, les données associées à l\'appareil et les renseignements sur sa position.\n\nPour obtenir plus d\'information, communiquez avec votre administrateur informatique."</string>
-    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> pourrait être en mesure d\'accéder aux données associées à cet appareil, de modifier ses paramètres et de gérer des applications.\n\nSi vous avez des questions, communiquez avec <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
-    <string name="monitoring_description_management" msgid="4308879039175729014">"Cet appareil appartient à votre organisation.\n\nVotre administrateur informatique peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applications, les données associées à votre appareil et les renseignements sur sa position.\n\nPour obtenir plus d\'information, communiquez avec votre administrateur informatique."</string>
+    <string name="monitoring_description_named_management" msgid="505833016545056036">"Votre appareil appartient à <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g>.\n\nVotre administrateur informatique peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applis, les données associées à l\'appareil et les renseignements sur sa position.\n\nPour obtenir plus d\'information, communiquez avec votre administrateur informatique."</string>
+    <string name="monitoring_financed_description_named_management" msgid="6108439201399938668">"<xliff:g id="ORGANIZATION_NAME_0">%1$s</xliff:g> pourrait être en mesure d\'accéder aux données associées à cet appareil, de modifier ses paramètres et de gérer des applis.\n\nSi vous avez des questions, communiquez avec <xliff:g id="ORGANIZATION_NAME_1">%2$s</xliff:g>."</string>
+    <string name="monitoring_description_management" msgid="4308879039175729014">"Cet appareil appartient à votre organisation.\n\nVotre administrateur informatique peut contrôler et gérer les paramètres, l\'accès aux données d\'entreprise, les applis, les données associées à votre appareil et les renseignements sur sa position.\n\nPour obtenir plus d\'information, communiquez avec votre administrateur informatique."</string>
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"Votre entreprise a installé une autorité de certification sur cet appareil. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"Votre entreprise a installé une autorité de certification dans votre profil professionnel. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"Une autorité de certification est installée sur cet appareil. Votre trafic sur le réseau sécurisé peut être contrôlé ou modifié."</string>
@@ -579,11 +594,11 @@
     <string name="monitoring_description_named_vpn" msgid="8220190039787149671">"Cet appareil est connecté à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>. Votre activité réseau, y compris les courriels et les données de navigation, est visible par le fournisseur de RPV."</string>
     <string name="monitoring_description_managed_device_named_vpn" msgid="7693648349547785255">"Cet appareil est connecté à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>. Votre activité réseau, y compris les courriels et les données de navigation, est visible par votre administrateur informatique."</string>
     <string name="monitoring_description_two_named_vpns" msgid="6726394451199620634">"Cet appareil est connecté à Internet par l\'intermédiaire de <xliff:g id="VPN_APP_0">%1$s</xliff:g> et de <xliff:g id="VPN_APP_1">%2$s</xliff:g>. Votre activité réseau, y compris les courriels et les données de navigation, est visible par votre administrateur informatique."</string>
-    <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Vos applications professionnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>. Votre activité réseau dans les applications professionnelles, y compris les courriels et les données de navigation, est visible par votre administrateur informatique et par votre fournisseur de RPV."</string>
-    <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Vos applications personnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>. Votre activité réseau, y compris les courriels et les données de navigation, est visible par votre fournisseur de RPV."</string>
+    <string name="monitoring_description_managed_profile_named_vpn" msgid="7254359257263069766">"Vos applis professionnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>. Votre activité réseau dans les applis professionnelles, y compris les courriels et les données de navigation, est visible par votre administrateur informatique et par votre fournisseur de RPV."</string>
+    <string name="monitoring_description_personal_profile_named_vpn" msgid="5083909710727365452">"Vos applis personnelles sont connectées à Internet par l\'intermédiaire de <xliff:g id="VPN_APP">%1$s</xliff:g>. Votre activité réseau, y compris les courriels et les données de navigation, est visible par votre fournisseur de RPV."</string>
     <string name="monitoring_description_vpn_settings_separator" msgid="8292589617720435430">" "</string>
     <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"Ouvrir les paramètres RPV"</string>
-    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Cet appareil est géré par ton parent. Ton parent peut voir et gérer de l\'information, comme les applications que tu utilises, ta position et ton temps d\'utilisation des écrans."</string>
+    <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Cet appareil est géré par ton parent. Ton parent peut voir et gérer de l\'information, comme les applis que tu utilises, ta position et ton temps d\'utilisation des écrans."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"RPV"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Maintenu déverrouillé par TrustAgent"</string>
     <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"L\'appareil a été verrouillé : trop de tentatives d\'authentification"</string>
@@ -603,21 +618,21 @@
     <string name="csd_500_system_lowered_text" product="default" msgid="7414943302186884124">"Le niveau du volume des écouteurs a dépassé la limite de sécurité pour cette semaine"</string>
     <string name="csd_button_keep_listening" product="default" msgid="4093794049149286784">"Poursuivre l\'écoute"</string>
     <string name="csd_button_lower_volume" product="default" msgid="5347210412376264579">"Diminuer le volume"</string>
-    <string name="screen_pinning_title" msgid="9058007390337841305">"L\'application est épinglée"</string>
+    <string name="screen_pinning_title" msgid="9058007390337841305">"L\'appli est épinglée"</string>
     <string name="screen_pinning_description" msgid="8699395373875667743">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'opération. Pour annuler l\'épinglage, maintenez le doigt sur « Retour » et « Aperçu »."</string>
     <string name="screen_pinning_description_recents_invisible" msgid="4564466648700390037">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'opération. Pour annuler l\'épinglage, maintenez le doigt sur les touches Retour et Accueil."</string>
     <string name="screen_pinning_description_gestural" msgid="7246323931831232068">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'épinglage. Pour annuler l\'épinglage, balayez l\'écran vers le haut et gardez le doigt dessus."</string>
     <string name="screen_pinning_description_accessible" msgid="7386449191953535332">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'opération. Pour annuler l\'épinglage, maintenez le doigt sur « Aperçu »."</string>
     <string name="screen_pinning_description_recents_invisible_accessible" msgid="2857071808674481986">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'opération. Pour annuler l\'épinglage, maintenez le doigt sur la touche Accueil."</string>
     <string name="screen_pinning_exposes_personal_data" msgid="8189852022981524789">"Certaines données personnelles pourraient être accessibles (comme les contacts et le contenu des courriels)."</string>
-    <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"L\'application épinglée peut ouvrir d\'autres applications."</string>
-    <string name="screen_pinning_toast" msgid="8177286912533744328">"Pour annuler l\'épinglage de cette application, maintenez un doigt sur les touches Retour et Aperçu"</string>
-    <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Pour annuler l\'épinglage de cette application, maintenez un doigt sur les touches Retour et Accueil"</string>
-    <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Pour annuler l\'épinglage de cette application, balayez-la vers le haut et maintenez-la"</string>
+    <string name="screen_pinning_can_open_other_apps" msgid="7529756813231421455">"L\'appli épinglée peut ouvrir d\'autres applis."</string>
+    <string name="screen_pinning_toast" msgid="8177286912533744328">"Pour annuler l\'épinglage de cette appli, maintenez un doigt sur les touches Retour et Aperçu"</string>
+    <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Pour annuler l\'épinglage de cette appli, maintenez un doigt sur les touches Retour et Accueil"</string>
+    <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Pour annuler l\'épinglage de cette appli, balayez-la vers le haut et maintenez-la"</string>
     <string name="screen_pinning_positive" msgid="3285785989665266984">"OK"</string>
     <string name="screen_pinning_negative" msgid="6882816864569211666">"Non, merci"</string>
-    <string name="screen_pinning_start" msgid="7483998671383371313">"Application épinglée"</string>
-    <string name="screen_pinning_exit" msgid="4553787518387346893">"L\'épinglage de l\'application a été annulé"</string>
+    <string name="screen_pinning_start" msgid="7483998671383371313">"Appli épinglée"</string>
+    <string name="screen_pinning_exit" msgid="4553787518387346893">"L\'épinglage de l\'appli a été annulé"</string>
     <string name="stream_voice_call" msgid="7468348170702375660">"Appeler"</string>
     <string name="stream_system" msgid="7663148785370565134">"Système"</string>
     <string name="stream_ring" msgid="7550670036738697526">"Sonnerie"</string>
@@ -789,34 +804,34 @@
     <string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"Affichage des résultats de recherche en cours…"</string>
     <string name="keyboard_shortcut_a11y_filter_system" msgid="7744143131119370483">"Affichage des raccourcis du système en cours…"</string>
     <string name="keyboard_shortcut_a11y_filter_input" msgid="4589316004510335529">"Affichage des raccourcis d\'entrée en cours…"</string>
-    <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Affichage des raccourcis qui ouvrent les applications en cours…"</string>
-    <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Affichage des raccourcis de l\'application actuelle en cours…"</string>
+    <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Affichage des raccourcis qui ouvrent les applis en cours…"</string>
+    <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Affichage des raccourcis de l\'appli actuelle en cours…"</string>
     <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Afficher les notifications"</string>
     <string name="group_system_full_screenshot" msgid="5742204844232667785">"Prendre une capture d\'écran"</string>
     <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Afficher les raccourcis"</string>
     <string name="group_system_go_back" msgid="2730322046244918816">"Retour"</string>
     <string name="group_system_access_home_screen" msgid="4130366993484706483">"Aller à l’écran d’accueil"</string>
-    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Afficher les applications récentes"</string>
-    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Parcourir les applications récentes"</string>
-    <string name="group_system_cycle_back" msgid="8194102916946802902">"Parcourir les applications récentes en sens inverse"</string>
-    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Ouvrir la liste des applications"</string>
+    <string name="group_system_overview_open_apps" msgid="5659958952937994104">"Afficher les applis récentes"</string>
+    <string name="group_system_cycle_forward" msgid="5478663965957647805">"Parcourir les applis récentes"</string>
+    <string name="group_system_cycle_back" msgid="8194102916946802902">"Parcourir les applis récentes en sens inverse"</string>
+    <string name="group_system_access_all_apps_search" msgid="1553588630154197469">"Ouvrir la liste des applis"</string>
     <string name="group_system_access_system_settings" msgid="8731721963449070017">"Ouvrir les paramètres"</string>
     <string name="group_system_access_google_assistant" msgid="7210074957915968110">"Ouvrir l\'Assistant"</string>
     <string name="group_system_lock_screen" msgid="7391191300363416543">"Écran de verrouillage"</string>
     <string name="group_system_quick_memo" msgid="3764560265935722903">"Prendre une note"</string>
     <string name="keyboard_shortcut_group_system_multitasking" msgid="6967816258924795558">"Multitâche"</string>
-    <string name="system_multitasking_rhs" msgid="8714224917276297810">"Utiliser l\'Écran divisé avec l\'application actuelle à droite"</string>
-    <string name="system_multitasking_lhs" msgid="8402954791206308783">"Utiliser l\'Écran divisé avec l\'application actuelle à gauche"</string>
+    <string name="system_multitasking_rhs" msgid="8714224917276297810">"Utiliser l\'Écran divisé avec l\'appli actuelle à droite"</string>
+    <string name="system_multitasking_lhs" msgid="8402954791206308783">"Utiliser l\'Écran divisé avec l\'appli actuelle à gauche"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Passer de l\'écran divisé au plein écran"</string>
-    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passer à l\'application à droite ou en dessous avec l\'Écran divisé"</string>
-    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passer à l\'application à gauche ou au-dessus avec l\'Écran divisé"</string>
-    <string name="system_multitasking_replace" msgid="7410071959803642125">"En mode d\'écran divisé : remplacer une application par une autre"</string>
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passer à l\'appli à droite ou en dessous avec l\'Écran divisé"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passer à l\'appli à gauche ou au-dessus avec l\'Écran divisé"</string>
+    <string name="system_multitasking_replace" msgid="7410071959803642125">"En mode d\'écran divisé : remplacer une appli par une autre"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrée"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Passer à la langue suivante"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"Passer à la langue précédente"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"Accéder aux émojis"</string>
     <string name="input_access_voice_typing" msgid="7291201476395326141">"Accéder à l\'entrée vocale"</string>
-    <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Applications"</string>
+    <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"Applis"</string>
     <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Assistant"</string>
     <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"Navigateur"</string>
     <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Contacts"</string>
@@ -916,27 +931,27 @@
     <string name="lockscreen_unlock_left" msgid="1417801334370269374">"Le raccourci gauche déverrouille aussi :"</string>
     <string name="lockscreen_unlock_right" msgid="4658008735541075346">"Le raccourci droit déverrouille aussi :"</string>
     <string name="lockscreen_none" msgid="4710862479308909198">"Aucun"</string>
-    <string name="tuner_launch_app" msgid="3906265365971743305">"Lancer l\'application <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="tuner_other_apps" msgid="7767462881742291204">"Autres applications"</string>
+    <string name="tuner_launch_app" msgid="3906265365971743305">"Lancer l\'appli <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="tuner_other_apps" msgid="7767462881742291204">"Autres applis"</string>
     <string name="tuner_circle" msgid="5270591778160525693">"Cercle"</string>
     <string name="tuner_plus" msgid="4130366441154416484">"Plus"</string>
     <string name="tuner_minus" msgid="5258518368944598545">"Moins"</string>
     <string name="tuner_left" msgid="5758862558405684490">"Gauche"</string>
     <string name="tuner_right" msgid="8247571132790812149">"Droite"</string>
     <string name="tuner_menu" msgid="363690665924769420">"Menu"</string>
-    <string name="tuner_app" msgid="6949280415826686972">"Application <xliff:g id="APP">%1$s</xliff:g>"</string>
+    <string name="tuner_app" msgid="6949280415826686972">"Appli <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Alertes"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Pile"</string>
     <string name="notification_channel_screenshot" msgid="7665814998932211997">"Saisies d\'écran"</string>
-    <string name="notification_channel_instant" msgid="7556135423486752680">"Applications instantanées"</string>
+    <string name="notification_channel_instant" msgid="7556135423486752680">"Applis instantanées"</string>
     <string name="notification_channel_setup" msgid="7660580986090760350">"Configuration"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Stockage"</string>
     <string name="notification_channel_hints" msgid="7703783206000346876">"Conseils"</string>
     <string name="notification_channel_accessibility" msgid="8956203986976245820">"Accessibilité"</string>
-    <string name="instant_apps" msgid="8337185853050247304">"Applications instantanées"</string>
+    <string name="instant_apps" msgid="8337185853050247304">"Applis instantanées"</string>
     <string name="instant_apps_title" msgid="8942706782103036910">"<xliff:g id="APP">%1$s</xliff:g> en cours d\'exécution"</string>
-    <string name="instant_apps_message" msgid="6112428971833011754">"Application ouverte sans avoir été installée."</string>
-    <string name="instant_apps_message_with_help" msgid="1816952263531203932">"Application ouverte sans avoir été installée. Touchez ici pour en savoir plus."</string>
+    <string name="instant_apps_message" msgid="6112428971833011754">"Appli ouverte sans avoir été installée."</string>
+    <string name="instant_apps_message_with_help" msgid="1816952263531203932">"Appli ouverte sans avoir été installée. Touchez ici pour en savoir plus."</string>
     <string name="app_info" msgid="5153758994129963243">"Détails de l\'appli"</string>
     <string name="go_to_web" msgid="636673528981366511">"Ouvrir le navigateur"</string>
     <string name="mobile_data" msgid="4564407557775397216">"Données cellulaires"</string>
@@ -947,9 +962,9 @@
     <string name="dnd_is_off" msgid="3185706903793094463">"Le mode Ne pas déranger est désactivé"</string>
     <string name="dnd_is_on" msgid="7009368176361546279">"Mode Ne pas déranger activé"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"Le mode Ne pas déranger a été activé par une règle automatique (<xliff:g id="ID_1">%s</xliff:g>)."</string>
-    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Le mode Ne pas déranger a été activé par une application (<xliff:g id="ID_1">%s</xliff:g>)."</string>
-    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Le mode Ne pas déranger a été activé par une règle automatique ou une application."</string>
-    <string name="running_foreground_services_title" msgid="5137313173431186685">"Applications qui fonctionnent en arrière-plan"</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"Le mode Ne pas déranger a été activé par une appli (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"Le mode Ne pas déranger a été activé par une règle automatique ou une appli."</string>
+    <string name="running_foreground_services_title" msgid="5137313173431186685">"Applis qui fonctionnent en arrière-plan"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Touchez pour afficher des détails sur l\'utilisation de la pile et des données"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Désactiver les données cellulaires?"</string>
     <string name="mobile_data_disable_message" msgid="8604966027899770415">"Vous n\'aurez pas accès aux données ni à Internet avec <xliff:g id="CARRIER">%s</xliff:g>. Vous ne pourrez accéder à Internet que par Wi-Fi."</string>
@@ -958,18 +973,18 @@
     <string name="auto_data_switch_disable_message" msgid="5885533647399535852">"Il n\'y aura pas de basculement automatique entre les données mobiles selon la disponibilité"</string>
     <string name="auto_data_switch_dialog_negative_button" msgid="2370876875999891444">"Non merci"</string>
     <string name="auto_data_switch_dialog_positive_button" msgid="8531782041263087564">"Oui, basculer"</string>
-    <string name="touch_filtered_warning" msgid="8119511393338714836">"Une application obscurcit une demande d\'autorisation, alors Paramètres ne peut pas vérifier votre réponse."</string>
+    <string name="touch_filtered_warning" msgid="8119511393338714836">"Une appli obscurcit une demande d\'autorisation, alors Paramètres ne peut pas vérifier votre réponse."</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"Autoriser <xliff:g id="APP_0">%1$s</xliff:g> à afficher <xliff:g id="APP_2">%2$s</xliff:g> tranches?"</string>
     <string name="slice_permission_text_1" msgid="6675965177075443714">"- Il peut lire de l\'information de <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="slice_permission_text_2" msgid="6758906940360746983">"- Il peut effectuer des actions dans <xliff:g id="APP">%1$s</xliff:g>"</string>
-    <string name="slice_permission_checkbox" msgid="4242888137592298523">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à afficher des tranches de n\'importe quelle application"</string>
+    <string name="slice_permission_checkbox" msgid="4242888137592298523">"Autoriser <xliff:g id="APP">%1$s</xliff:g> à afficher des tranches de n\'importe quelle appli"</string>
     <string name="slice_permission_allow" msgid="6340449521277951123">"Autoriser"</string>
     <string name="slice_permission_deny" msgid="6870256451658176895">"Refuser"</string>
     <string name="auto_saver_title" msgid="6873691178754086596">"Toucher pour activer la fonction Économiseur de pile"</string>
     <string name="auto_saver_text" msgid="3214960308353838764">"Activer si la pile est susceptible de s\'épuiser totalement"</string>
     <string name="no_auto_saver_action" msgid="7467924389609773835">"Non merci"</string>
     <string name="ongoing_privacy_dialog_a11y_title" msgid="2205794093673327974">"En cours d\'utilisation"</string>
-    <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Des applications utilisent votre <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+    <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8341216022442383954">"Des applis utilisent votre <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
     <string name="ongoing_privacy_dialog_separator" msgid="1866222499727706187">", "</string>
     <string name="ongoing_privacy_dialog_last_separator" msgid="5615876114268009767">" et "</string>
     <string name="ongoing_privacy_dialog_using_op" msgid="426635338010011796">"En cours d\'utilisation par : <xliff:g id="APPLICATION_NAME">%1$s</xliff:g>"</string>
@@ -1042,7 +1057,7 @@
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"basculer"</string>
     <string name="accessibility_floating_button_action_edit" msgid="1688227814600463987">"Modifier"</string>
     <string name="quick_controls_title" msgid="6839108006171302273">"Commandes des appareils"</string>
-    <string name="controls_providers_title" msgid="6879775889857085056">"Sélectionnez l\'application pour laquelle ajouter des commandes"</string>
+    <string name="controls_providers_title" msgid="6879775889857085056">"Sélectionnez l\'appli pour laquelle ajouter des commandes"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# commande ajoutée.}one{# commande ajoutée.}many{# de commandes ajoutées.}other{# commandes ajoutées.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Supprimé"</string>
     <string name="controls_panel_authorization_title" msgid="267429338785864842">"Ajouter <xliff:g id="APPNAME">%s</xliff:g>?"</string>
@@ -1059,11 +1074,11 @@
     <string name="controls_favorite_rearrange" msgid="5616952398043063519">"Faites glisser les commandes pour les réorganiser"</string>
     <string name="controls_favorite_removed" msgid="5276978408529217272">"Toutes les commandes ont été retirées"</string>
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Modifications non enregistrées"</string>
-    <string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Afficher autres applications"</string>
+    <string name="controls_favorite_see_other_apps" msgid="7709087332255283460">"Afficher autres applis"</string>
     <string name="controls_favorite_rearrange_button" msgid="2942788904364641185">"Réorganiser"</string>
     <string name="controls_favorite_add_controls" msgid="1221420435546694004">"Ajouter des commandes"</string>
     <string name="controls_favorite_back_to_editing" msgid="184125114090062713">"Retour à la modification"</string>
-    <string name="controls_favorite_load_error" msgid="5126216176144877419">"Impossible de charger les commandes. Vérifiez l\'application <xliff:g id="APP">%s</xliff:g> pour vous assurer que les paramètres de l\'application n\'ont pas changé."</string>
+    <string name="controls_favorite_load_error" msgid="5126216176144877419">"Impossible de charger les commandes. Vérifiez l\'appli <xliff:g id="APP">%s</xliff:g> pour vous assurer que les paramètres de l\'appli n\'ont pas changé."</string>
     <string name="controls_favorite_load_none" msgid="7687593026725357775">"Les commandes compatibles ne sont pas accessibles"</string>
     <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Autre"</string>
     <string name="controls_dialog_title" msgid="2343565267424406202">"Ajouter aux commandes des appareils"</string>
@@ -1072,9 +1087,9 @@
     <string name="controls_dialog_message" msgid="342066938390663844">"Suggestion de <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="controls_tile_locked" msgid="731547768182831938">"Appareil verrouillé"</string>
     <string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Afficher et contrôler les appareils à partir de l\'écran de verrouillage?"</string>
-    <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Vous pouvez ajouter des commandes pour vos appareils externes à l\'écran de verrouillage.\n\nL\'application de votre appareil peut vous permettre de contrôler certains appareils sans déverrouiller votre téléphone ou votre tablette.\n\nVous pouvez apporter des modifications à tout moment dans les paramètres."</string>
+    <string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Vous pouvez ajouter des commandes pour vos appareils externes à l\'écran de verrouillage.\n\nL\'appli de votre appareil peut vous permettre de contrôler certains appareils sans déverrouiller votre téléphone ou votre tablette.\n\nVous pouvez apporter des modifications à tout moment dans les paramètres."</string>
     <string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Contrôler les appareils à partir de l\'écran de verrouillage?"</string>
-    <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Vous pouvez contrôler certains appareils sans déverrouiller votre téléphone ou votre tablette. L\'application de votre appareil détermine quels appareils peuvent être contrôlés de cette manière."</string>
+    <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Vous pouvez contrôler certains appareils sans déverrouiller votre téléphone ou votre tablette. L\'appli de votre appareil détermine quels appareils peuvent être contrôlés de cette manière."</string>
     <string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Non merci"</string>
     <string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Oui"</string>
     <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Le NIP contient des lettres ou des symboles"</string>
@@ -1117,14 +1132,14 @@
     <string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifiez l\'appli"</string>
     <string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"La commande n\'est pas accessible"</string>
-    <string name="controls_error_removed_message" msgid="2885911717034750542">"Impossible d\'accéder à <xliff:g id="DEVICE">%1$s</xliff:g>. Vérifiez l\'application <xliff:g id="APPLICATION">%2$s</xliff:g> pour vous assurer que la commande est toujours offerte et que les paramètres de l\'application n\'ont pas changé."</string>
-    <string name="controls_open_app" msgid="483650971094300141">"Ouvrir l\'application"</string>
+    <string name="controls_error_removed_message" msgid="2885911717034750542">"Impossible d\'accéder à <xliff:g id="DEVICE">%1$s</xliff:g>. Vérifiez l\'appli <xliff:g id="APPLICATION">%2$s</xliff:g> pour vous assurer que la commande est toujours offerte et que les paramètres de l\'appli n\'ont pas changé."</string>
+    <string name="controls_open_app" msgid="483650971094300141">"Ouvrir l\'appli"</string>
     <string name="controls_error_generic" msgid="352500456918362905">"Impossible de charger l\'état"</string>
     <string name="controls_error_failed" msgid="960228639198558525">"Erreur. Veuillez réessayer."</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Ajouter des commandes"</string>
     <string name="controls_menu_edit" msgid="890623986951347062">"Modifier des commandes"</string>
-    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Ajouter une application"</string>
-    <string name="controls_menu_remove" msgid="3006525275966023468">"Retirer l\'application"</string>
+    <string name="controls_menu_add_another_app" msgid="8661172304650786705">"Ajouter une appli"</string>
+    <string name="controls_menu_remove" msgid="3006525275966023468">"Retirer l\'appli"</string>
     <string name="media_output_dialog_add_output" msgid="5642703238877329518">"Ajouter des sorties"</string>
     <string name="media_output_dialog_group" msgid="5571251347877452212">"Groupe"</string>
     <string name="media_output_dialog_single_device" msgid="3102758980643351058">"Un appareil sélectionné"</string>
@@ -1132,8 +1147,8 @@
     <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="5098212763195577270">"Connecter un appareil"</string>
-    <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_launch_app_text" msgid="1527413319632586259">"Pour diffuser 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>
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"Appareils disponibles pour la sortie audio."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"Volume"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Touchez pour en savoir plus"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Aucune alarme définie"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"entrer verrouillage de l\'écran"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Toucher le capteur d\'empreintes digitales. Il s\'agit du bouton le plus court sur le côté du téléphone"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Capteur d\'empreintes digitales"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"authentifier"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"accéder à l\'appareil"</string>
@@ -1220,13 +1236,13 @@
     <string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Connexion automatique au Wi-Fi impossible pour le moment"</string>
     <string name="see_all_networks" msgid="3773666844913168122">"Tout afficher"</string>
     <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Pour changer de réseau, débranchez le câble Ethernet"</string>
-    <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Pour améliorer l\'expérience de l\'appareil, les applications et les services peuvent quand même rechercher des réseaux Wi-Fi en tout temps, même lorsque le Wi-Fi est désactivé. Vous pouvez modifier vos préférences dans les paramètres de recherche de réseaux Wi-Fi. "<annotation id="link">"Modifier"</annotation></string>
+    <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Pour améliorer l\'expérience de l\'appareil, les applis et les services peuvent quand même rechercher des réseaux Wi-Fi en tout temps, même lorsque le Wi-Fi est désactivé. Vous pouvez modifier vos préférences dans les paramètres de recherche de réseaux Wi-Fi. "<annotation id="link">"Modifier"</annotation></string>
     <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Désactiver le mode Avion"</string>
-    <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"L\'application <xliff:g id="APPNAME">%1$s</xliff:g> veut ajouter la tuile suivante au menu Paramètres rapides"</string>
+    <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"L\'appli <xliff:g id="APPNAME">%1$s</xliff:g> veut ajouter la tuile suivante au menu Paramètres rapides"</string>
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Ajouter la tuile"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ne pas ajouter de tuile"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"Choisir l\'utilisateur"</string>
-    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# application est active}one{# application est active}many{# d\'applications sont actives}other{# applications sont actives}}"</string>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# appli est active}one{# appli est active}many{# d\'applis sont actives}other{# applis sont actives}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"Nouvelle information"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"Applis actives"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"Ces applis sont actives et s\'exécutent même lorsque vous ne les utilisez pas. Cela améliore leur fonctionnalité, mais peut également affecter l\'autonomie de la pile."</string>
@@ -1272,16 +1288,16 @@
     <string name="log_access_confirmation_title" msgid="4843557604739943395">"Autoriser <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> à accéder à l\'ensemble des journaux de l\'appareil?"</string>
     <string name="log_access_confirmation_allow" msgid="752147861593202968">"Autoriser un accès unique"</string>
     <string name="log_access_confirmation_deny" msgid="2389461495803585795">"Ne pas autoriser"</string>
-    <string name="log_access_confirmation_body" msgid="6883031912003112634">"Les journaux de l\'appareil enregistrent ce qui se passe sur celui-ci. Les applications peuvent utiliser ces journaux pour trouver et résoudre des problèmes.\n\nCertains journaux peuvent contenir des renseignements confidentiels. N\'autorisez donc que les applications auxquelles vous faites confiance puisque celles-ci pourront accéder à l\'ensemble des journaux de l\'appareil. \n\nMême si vous n\'autorisez pas cette application à accéder à l\'ensemble des journaux de l\'appareil, elle aura toujours accès à ses propres journaux. Le fabricant de votre appareil pourrait toujours être en mesure d\'accéder à certains journaux ou renseignements sur votre appareil."</string>
+    <string name="log_access_confirmation_body" msgid="6883031912003112634">"Les journaux de l\'appareil enregistrent ce qui se passe sur celui-ci. Les applis peuvent utiliser ces journaux pour trouver et résoudre des problèmes.\n\nCertains journaux peuvent contenir des renseignements confidentiels. N\'autorisez donc que les applis auxquelles vous faites confiance puisque celles-ci pourront accéder à l\'ensemble des journaux de l\'appareil. \n\nMême si vous n\'autorisez pas cette appli à accéder à l\'ensemble des journaux de l\'appareil, elle aura toujours accès à ses propres journaux. Le fabricant de votre appareil pourrait toujours être en mesure d\'accéder à certains journaux ou renseignements sur votre appareil."</string>
     <string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"En savoir plus"</string>
     <string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"En savoir plus : <xliff:g id="URL">%s</xliff:g>"</string>
     <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Ouvrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
-    <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Pour ajouter l\'application portefeuille sous forme de raccourci, assurez-vous que l\'application est installée"</string>
-    <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Pour ajouter l\'application Portefeuille sous forme de raccourci, assurez-vous qu\'au moins une carte a été ajoutée"</string>
-    <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Pour ajouter l\'application Home sous forme de raccourci, assurez-vous que l\'application est installée"</string>
+    <string name="wallet_quick_affordance_unavailable_install_the_app" msgid="7298552910007208368">"Pour ajouter l\'appli portefeuille sous forme de raccourci, assurez-vous que l\'appli est installée"</string>
+    <string name="wallet_quick_affordance_unavailable_configure_the_app" msgid="4387433357429873258">"Pour ajouter l\'appli Portefeuille sous forme de raccourci, assurez-vous qu\'au moins une carte a été ajoutée"</string>
+    <string name="home_quick_affordance_unavailable_install_the_app" msgid="6187820778998446168">"Pour ajouter l\'appli Home sous forme de raccourci, assurez-vous que l\'appli est installée"</string>
     <string name="home_quick_affordance_unavailable_configure_the_app" msgid="604424593994493281">"• Au moins un appareil ou un panneau d\'appareils est accessible"</string>
-    <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Sélectionnez une application de prise de notes par défaut pour utiliser le raccourci de prise de notes"</string>
-    <string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Sélectionner l\'application"</string>
+    <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Sélectionnez une appli de prise de notes par défaut pour utiliser le raccourci de prise de notes"</string>
+    <string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Sélectionner l\'appli"</string>
     <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Maintenir le doigt sur raccourci"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Annuler"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Changer d\'écran maintenant"</string>
@@ -1298,10 +1314,10 @@
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"Connectez votre stylet à un chargeur"</string>
     <string name="stylus_battery_low" msgid="7134370101603167096">"Pile du stylet faible"</string>
     <string name="video_camera" msgid="7654002575156149298">"Caméra"</string>
-    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Impossible d\'appeler à partir d\'une application personnelle"</string>
-    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Votre organisation vous autorise à passer des appels uniquement à partir d\'applications professionnelles"</string>
+    <string name="call_from_work_profile_title" msgid="5418253516453177114">"Impossible d\'appeler à partir d\'une appli personnelle"</string>
+    <string name="call_from_work_profile_text" msgid="2856337395968118274">"Votre organisation vous autorise à passer des appels uniquement à partir d\'applis professionnelles"</string>
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Passer au profil professionnel"</string>
-    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Installer une application de téléphone professionnelle"</string>
+    <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Installer une appli de téléphone professionnelle"</string>
     <string name="call_from_work_profile_close" msgid="5830072964434474143">"Annuler"</string>
     <string name="lock_screen_settings" msgid="6152703934761402399">"Personn. l\'écran de verrouillage"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Déverrouiller pour personnaliser l\'écran de verrouillage"</string>
@@ -1311,8 +1327,8 @@
     <string name="microphone_blocked_dream_overlay_content_description" msgid="5466897982130007033">"Microphone bloqué"</string>
     <string name="priority_mode_dream_overlay_content_description" msgid="3361628029609329182">"Ne pas déranger"</string>
     <string name="assistant_attention_content_description" msgid="4166330881435263596">"La présence d\'un utilisateur est détectée"</string>
-    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Définir l\'application de prise de notes par défaut dans les Paramètres"</string>
-    <string name="install_app" msgid="5066668100199613936">"Installer l\'application"</string>
+    <string name="set_default_notes_app_toast_content" msgid="2812374329662610753">"Définir l\'appli de prise de notes par défaut dans les Paramètres"</string>
+    <string name="install_app" msgid="5066668100199613936">"Installer l\'appli"</string>
     <string name="dismissible_keyguard_swipe" msgid="8377597870094949432">"Balayer vers le haut pour continuer"</string>
     <string name="connected_display_dialog_start_mirroring" msgid="6237895789920854982">"Dupliquer l\'écran sur un moniteur externe?"</string>
     <string name="connected_display_dialog_dual_display_stop_warning" msgid="4174707498892447947">"Votre écran intérieur sera dupliqué. Votre écran frontal sera désactivé."</string>
@@ -1320,12 +1336,12 @@
     <string name="dismiss_dialog" msgid="2195508495854675882">"Fermer"</string>
     <string name="connected_display_icon_desc" msgid="6373560639989971997">"Écran connecté"</string>
     <string name="privacy_dialog_title" msgid="7839968133469098311">"Microphone et appareil photo"</string>
-    <string name="privacy_dialog_summary" msgid="2458769652125995409">"Utilisation récente par les applications"</string>
+    <string name="privacy_dialog_summary" msgid="2458769652125995409">"Utilisation récente par les applis"</string>
     <string name="privacy_dialog_more_button" msgid="7610604080293562345">"Afficher l\'accès récent"</string>
     <string name="privacy_dialog_done_button" msgid="4504330708531434263">"OK"</string>
     <string name="privacy_dialog_expand_action" msgid="9129262348628331377">"Développer et afficher les options"</string>
     <string name="privacy_dialog_collapse_action" msgid="277419962019466347">"Réduire"</string>
-    <string name="privacy_dialog_close_app_button" msgid="8006250171305878606">"Fermer cette application"</string>
+    <string name="privacy_dialog_close_app_button" msgid="8006250171305878606">"Fermer cette appli"</string>
     <string name="privacy_dialog_close_app_message" msgid="1316408652526310985">"<xliff:g id="APP_NAME">%1$s</xliff:g> fermé"</string>
     <string name="privacy_dialog_manage_service" msgid="8320590856621823604">"Gérer le service"</string>
     <string name="privacy_dialog_manage_permissions" msgid="2543451567190470413">"Gérer l\'accès"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Utilisé par <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Récemment utilisé par <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Système"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Commandes système"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Applis système"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitâche"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Applis récentes"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Écran divisé"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrée"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Raccourcis des applis"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilité"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Retour"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Pour revenir en arrière, balayez vers la gauche ou la droite en utilisant trois doigts n\'importe où sur le pavé tactile."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Pavé tactile montrant trois doigts se déplaçant à droite et à gauche"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Écran de l\'appareil montrant l\'animation pour le geste de retour"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Rétroéclairage du clavier"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d de %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Domotique"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 98bfc72..8618b38 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> a détecté cette capture d\'écran."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> et d\'autres applis ouvertes ont détecté cette capture d\'écran."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ajouter à la note"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Inclure le lien"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Enregistreur d\'écran"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Enregistrement de l\'écran…"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notification en cours pour une session d\'enregistrement de l\'écran"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Vous arrêterez d\'enregistrer &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Partage de l\'écran…"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Vous arrêterez de partager &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Diffusion de l\'écran…"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Vous arrêterez de caster &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Déverrouillé par visage. Appuyez pour continuer."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Visage reconnu. Appuyez pour continuer."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Visage reconnu. Appuyez sur l\'icône de déverrouillage pour continuer."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Déverrouillé par le visage. Appuyez pour continuer."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifié"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Annuler l\'authentification"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Plus d\'options"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Certaines fonctionnalités, telles que Quick Share et Localiser mon appareil, utilisent le Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Le Bluetooth sera activé demain matin"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Partager le contenu audio"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Audio partagé"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batterie"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Casque"</string>
@@ -379,7 +384,7 @@
     <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Démarrer"</string>
     <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Arrêter"</string>
     <string name="qs_record_issue_label" msgid="8166290137285529059">"Enregistrer le problème"</string>
-    <string name="qs_record_issue_start" msgid="2979831312582567056">"Début"</string>
+    <string name="qs_record_issue_start" msgid="2979831312582567056">"Lancer"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"Arrêter"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Rapport de bug"</string>
     <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Quel problème avez-vous rencontré avec votre appareil ?"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Ajouter des widgets"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Appuyez de manière prolongée pour personnaliser les widgets"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personnaliser les widgets"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Déverrouiller pour personnaliser les widgets"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icône d\'appli du widget désactivé"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Icône d\'application indiquant qu\'un widget est en cours d\'installation"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Modifier le widget"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"sélectionner un widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"supprimer le widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"positionner le widget sélectionné"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Changer d\'utilisateur"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu déroulant"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toutes les applications et les données de cette session seront supprimées."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Commencer"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Aucune notification"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Aucune nouvelle notification"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Les notifications intelligentes sont activées"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Désormais, lorsque vous recevez de nombreuses notifications en peu de temps, votre appareil baisse le volume et réduit les pop-up qui apparaissent à l\'écran pendant deux minutes maximum."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Désactiver"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Déverrouiller pour voir anciennes notifications"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Cet appareil est géré par tes parents"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Cet appareil appartient à votre organisation, qui peut contrôler votre trafic réseau"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Appuyer pour en savoir plus"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Pas d\'alarme définie"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"accéder au verrouillage de l\'écran"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Appuyez sur le lecteur d\'empreinte digitale. Il s\'agit du plus petit bouton sur le côté du téléphone."</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Lecteur d\'empreinte digitale"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"s\'authentifier"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"accéder à l\'appareil"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"En cours d\'utilisation par <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Récemment utilisé par <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Système"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Commandes système"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Applis système"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitâche"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Applis récentes"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Écran partagé"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrée"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Raccourcis d\'application"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilité"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Retour"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Pour retourner en arrière, balayez vers la gauche avec trois doigts n\'importe où sur le pavé tactile."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Pavé tactile sur lequel trois doigts glissent vers la droite, puis vers la gauche"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Écran d\'un appareil affichant l\'animation du geste Retour"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Rétroéclairage du clavier"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d sur %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Contrôle de la maison"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 28cf92a..b44dc45 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> detectou esta captura de pantalla."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e outras aplicacións abertas detectaron esta captura de pantalla."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Engadir a unha nota"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Incluír ligazón"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Gravadora da pantalla"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando gravación pantalla"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación de actividade en curso sobre unha sesión de gravación de pantalla"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Deixarás de gravar a aplicación &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Compartindo pantalla"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Deixarás de compartir a aplicación &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Emitindo pantalla"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Deixarás de emitir a aplicación &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Usouse o desbloqueo facial. Preme para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Recoñeceuse a cara. Preme para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Recoñeceuse a cara. Preme a icona de desbloquear."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Usouse o desbloqueo facial. Toca para continuar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar a autenticación"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Máis opcións"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"As funcións como Quick Share e Localizar o meu dispositivo utilizan o Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"O Bluetooth activarase mañá á mañá"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Compartir audio"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Compartindo audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de batería"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Auriculares"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Engadir máis widgets"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pulsación longa para personalizar os widgets"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Desbloquea o dispositivo para personalizar os widgets"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icona da aplicación de widget desactivado"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Icona da aplicación para un widget que se está instalando"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"seleccionar widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"quitar o widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"colocar o widget seleccionado"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambiar usuario"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menú despregable"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Eliminaranse todas as aplicacións e datos desta sesión."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Non hai notificacións"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Non hai notificacións novas"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notificacións intelix. activas"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"O dispositivo baixa o volume e reduce as ventás emerxentes na pantalla durante 2 min como máximo cando recibes moitas notificacións en pouco tempo."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desactivar"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloquea para ver máis notificacións"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"O teu pai ou nai xestiona este dispositivo"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"A túa organización é propietaria deste dispositivo e pode controlar o tráfico de rede"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toca para obter máis información"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Sen alarmas postas"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"introducir o bloqueo de pantalla"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Toca o sensor de impresión dixital. É o botón máis pequeno no lateral do teléfono"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de impresión dixital"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"poñer o dispositivo"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"En uso por <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"En uso recentemente por <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controis do sistema"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplicacións do sistema"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitarefa"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Aplicacións recentes"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Pantalla dividida"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Atallos de aplicacións"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilidade"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Volver"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para volver, pasa tres dedos cara á esquerda ou cara á dereita en calquera lugar do panel táctil."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Panel táctil que mostra tres dedos movéndose á dereita e á esquerda"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Pantalla do dispositivo que mostra unha animación do xesto de retroceso"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroiluminación do teclado"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivel %1$d de %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Controis domóticos"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 2914bad..5e384e3 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> દ્વારા આ સ્ક્રીનશૉટ લેવાયાની ભાળ મેળવવામાં આવી."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> અને કામ કરતી અન્ય ઍપ દ્વારા આ સ્ક્રીનશૉટ લેવાયાની ભાળ મેળવવામાં આવી."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"નોંધમાં ઉમેરો"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"લિંક શામેલ કરો"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"સ્ક્રીન રેકોર્ડર"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"સ્ક્રીન રેકૉર્ડિંગ ચાલુ છે"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"સ્ક્રીન રેકોર્ડિંગ સત્ર માટે ચાલુ નોટિફિકેશન"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"તમે &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને રેકોર્ડ કરવાનું બંધ કરશો"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"સ્ક્રીન શેર કરી રહ્યાં છીએ"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"તમે &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને શેર કરવાનું બંધ કરશો"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"સ્ક્રીન કાસ્ટ કરી રહ્યાં છીએ"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"તમે &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને કાસ્ટ કરવાનું બંધ કરશો"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ચહેરા દ્વારા અનલૉક કર્યું. આગળ વધવા માટે દબાવો."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ચહેરો ઓળખ્યો. આગળ વધવા માટે દબાવો."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ચહેરો ઓળખ્યો. આગળ વધવા \'અનલૉક કરો\' આઇકન દબાવો."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"ચહેરા દ્વારા અનલૉક કર્યું. ચાલુ રાખવા માટે ટૅપ કરો."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"પ્રમાણિત"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"પ્રમાણીકરણ રદ કરો"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"વધુ વિકલ્પો"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ક્વિક શેર અને Find My Device જેવી સુવિધાઓ બ્લૂટૂથનો ઉપયોગ કરે છે"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"બ્લૂટૂથ આવતીકાલે સવારે ચાલુ થશે"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ઑડિયો શેર કરો"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"ઑડિયો શેર કરી રહ્યાં છીએ"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"વધુ વિજેટ ઉમેરો"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"વિજેટ કસ્ટમાઇઝ કરવા માટે થોડીવાર દબાવી રાખો"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"વિજેટ કસ્ટમાઇઝ કરો"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"વિજેટ કસ્ટમાઇઝ કરવા માટે, અનલૉક કરો"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"બંધ કરેલા વિજેટ માટેની ઍપનું આઇકન"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ઇન્સ્ટૉલ થઈ રહેલા વિજેટ માટે ઍપનું આઇકન"</string>
     <string name="edit_widget" msgid="9030848101135393954">"વિજેટમાં ફેરફાર કરો"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"વિજેટ પસંદ કરો"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"વિજેટ કાઢી નાખો"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"પસંદ કરેલું વિજેટ મૂકો"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"વપરાશકર્તા સ્વિચ કરો"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"પુલડાઉન મેનૂ"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"આ સત્રમાંની તમામ ઍપ અને ડેટા કાઢી નાખવામાં આવશે."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"હવે શરૂ કરો"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"કોઈ નોટિફિકેશન નથી"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"કોઈ નવું નોટિફિકેશન નથી"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"અડૅપ્ટિવ નોટિફિકેશન ચાલુ છે"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"તમને ટૂંકા સમયગાળામાં ઘણાં નોટિફિકેશન મળે, ત્યારે ડિવાઇસ બે મિનિટ સુધી વૉલ્યૂમ ઓછું કરે છે અને સ્ક્રીન પરના પૉપ-અપની સંખ્યા ઓછી કરે છે."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"બંધ કરો"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"જૂના નોટિફિકેશન જોવા માટે અનલૉક કરો"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"આ ડિવાઇસ તમારા માતાપિતા દ્વારા મેનેજ કરવામાં આવે છે"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"તમારી સંસ્થા આ ડિવાઇસની માલિકી ધરાવે છે અને નેટવર્ક ટ્રાફિકનું નિરીક્ષણ કરી શકે છે"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"વધુ માહિતી માટે ટૅપ કરો"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"કોઈ અલાર્મ સેટ નથી"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"સ્ક્રીન લૉક દાખલ કરો"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ફિંગરપ્રિન્ટ સેન્સરને ટચ કરો. ફોનની બાજુમાં આવેલું આ કોઈ નાનું બટન છે"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ફિંગરપ્રિન્ટ સેન્સર"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"ખાતરી કરો"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"ડિવાઇસ અનલૉક કરો"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) દ્વારા ઉપયોગ ચાલુ છે"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) દ્વારા તાજેતરમાં ઉપયોગ કરવામાં આવ્યો"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"સિસ્ટમ"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"સિસ્ટમના નિયંત્રણો"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"સિસ્ટમ ઍપ"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"એકથી વધુ કાર્યો કરવા"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"તાજેતરની ઍપ"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"સ્ક્રીનને વિભાજિત કરો"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"ઇનપુટ"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ઍપ શૉર્ટકટ"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ઍક્સેસિબિલિટી"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"પાછા જાઓ"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"પાછા જવા માટે, ત્રણ આંગળીઓનો ઉપયોગ કરીને ટચપૅડ પર કોઈપણ જગ્યાએ ડાબે કે જમણે સ્વાઇપ કરો."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"જમણી અને ડાબી તરફ ખસી રહેલી ત્રણ આંગળીઓ બતાવતું ટચપૅડ"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"પાછા જવા માટેના સંકેત માટેનું ઍનિમેશન બતાવતી ડિવાઇસ સ્ક્રીન"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"કીબોર્ડની બૅકલાઇટ"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dમાંથી %1$d લેવલ"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ઘરેલું સાધનોના નિયંત્રણો"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index a6bc9b5..54bcede 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> को इस स्क्रीनशॉट का पता चला है."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> और खुले हुए अन्य ऐप्लिकेशन को इस स्क्रीनशॉट का पता चला है."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"नोट में जोड़ें"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"लिंक जोड़ें"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"स्क्रीन रिकॉर्डर"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रिकॉर्डिंग को प्रोसेस किया जा रहा है"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रिकॉर्ड सेशन के लिए जारी सूचना"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"इससे &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; का कॉन्टेंट रिकॉर्ड होना बंद हो जाएगा"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"स्क्रीन शेयर की जा रही है"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"इससे &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; का कॉन्टेंट शेयर होना बंद हो जाएगा"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"स्क्रीन कास्ट की जा रही है"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"इससे &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; का कॉन्टेंट कास्ट होना बंद हो जाएगा"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"चेहरे से अनलॉक किया गया. जारी रखने के लिए टैप करें."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"चेहरे की पहचान हो गई. जारी रखने के लिए टैप करें."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"चेहरे की पहचान हो गई. जारी रखने के लिए अनलॉक आइकॉन को टैप करें."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"चेहरे से अनलॉक किया गया. जारी रखने के लिए टैप करें."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"पुष्टि हो गई"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"पुष्टि करने की प्रोसेस को रद्द करें"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ज़्यादा विकल्प"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"क्विक शेयर और Find My Device जैसी सुविधाएं, ब्लूटूथ का इस्तेमाल करती हैं"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ब्लूटूथ कल सुबह चालू होगा"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ऑडियो शेयर करें"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"ऑडियो शेयर किया जा रहा है"</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>
@@ -382,7 +387,7 @@
     <string name="qs_record_issue_start" msgid="2979831312582567056">"शुरू करें"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"रोकें"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"गड़बड़ी की रिपोर्ट"</string>
-    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"आपके डिवाइस की कौनसी सुविधा पर असर पड़ा था?"</string>
+    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"आपके डिवाइस की किस सुविधा में समस्या आ रही थी?"</string>
     <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"समस्या का टाइप चुनें"</string>
     <string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"स्क्रीन रिकॉर्डर"</string>
     <string name="performance" msgid="6552785217174378320">"परफ़ॉर्मेंस"</string>
@@ -393,7 +398,7 @@
     <string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"ऐक्टिव"</string>
     <string name="quick_settings_hearing_devices_disconnected" msgid="8907061223998176187">"डिसकनेक्ट हो गया"</string>
     <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"कान की मशीनें"</string>
-    <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"नया डिवाइस जोड़ें"</string>
+    <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"कान की नई मशीन जोड़ें"</string>
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"नया डिवाइस जोड़ने के लिए क्लिक करें"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"प्रीसेट अपडेट नहीं किया जा सका"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"प्रीसेट"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ज़्यादा विजेट जोड़ें"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"विजेट पसंद के मुताबिक बनाने के लिए उसे दबाकर रखें"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"विजेट अपनी पसंद के मुताबिक बनाएं"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"विजेट को पसंद के मुताबिक बनाने के लिए, डिवाइस अनलॉक करें"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"बंद किए गए विजेट के लिए ऐप्लिकेशन आइकॉन"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"इंस्टॉल हो रहे विजेट के लिए ऐप्लिकेशन आइकॉन"</string>
     <string name="edit_widget" msgid="9030848101135393954">"विजेट में बदलाव करें"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"विजेट चुनें"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"विजेट हटाएं"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"चुने गए विजेट के लिए जगह चुनें"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"उपयोगकर्ता बदलें"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"पुलडाउन मेन्यू"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"इस सेशन के सभी ऐप्लिकेशन और डेटा को हटा दिया जाएगा."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"अभी शुरू करें"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"कोई सूचना नहीं है"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"कोई नई सूचना नहीं है"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"अडैप्टिव नोटिफ़िकेशन चालू हैं"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"अब आपका डिवाइस, तुरंत कई सूचनाएं मिलने पर दो मिनट तक, इनसे होने वाली आवाज़ें कम कर सकता है और स्क्रीन पर कम पॉप-अप दिखा सकता है."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"बंद करें"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"पुरानी सूचाएं देखने के लिए अनलॉक करें"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"इस डिवाइस का प्रबंधन आपके अभिभावक करते हैं"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"इस डिवाइस का मालिकाना हक आपके संगठन के पास है. आपका संगठन, नेटवर्क के ट्रैफ़िक की निगरानी कर सकता है"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ज़्यादा जानकारी के लिए टैप करें"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"कोई अलार्म सेट नहीं है"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"स्क्रीन लॉक डालें"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"फ़िंगरप्रिंट सेंसर को छुएं. यह फ़ोन की साइड में मौजूद एक छोटा बटन होता है"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"फ़िंगरप्रिंट सेंसर"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"पुष्टि करें"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"डिवाइस की होम स्क्रीन पर जाएं"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) पर इस्तेमाल किया जा रहा है"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"हाल ही में, <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ने इस्तेमाल किया"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"सिस्टम"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"सिस्टम से जुड़े कंट्रोल"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"सिस्टम के ऐप्लिकेशन"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"मल्टीटास्किंग (एक साथ कई काम करना)"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"हाल ही में इस्तेमाल किए गए ऐप्लिकेशन"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"स्प्लिट स्क्रीन"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"इनपुट"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ऐप शॉर्टकट"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"सुलभता"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"वापस जाएं"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"वापस जाने के लिए, टचपैड पर कहीं भी तीन उंगलियों से बाईं या दाईं तरफ़ स्वाइप करें."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"टचपैड पर तीन उंगलियों को दाईं और बाईं तरफ़ ले जाया जा रहा है"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"डिवाइस की स्क्रीन पर, पिछले पेज पर जाने के लिए हाथ के जेस्चर का ऐनिमेशन दिख रहा है"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"कीबोर्ड की बैकलाइट"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d में से %1$d लेवल"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"होम कंट्रोल"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index ba82bdd..cac83e6 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> otkrila je ovu snimku zaslona."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> i druge otvorene aplikacije otkrile su ovu snimku zaslona."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj bilješci"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Uključi vezu"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Snimač zaslona"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrada snimanja zaslona"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Tekuća obavijest za sesiju snimanja zaslona"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Zaustavit ćete snimanje aplikacije &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Dijeljenje zaslona"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Zaustavit ćete dijeljenje aplikacije &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Emitiranje zaslona"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Zaustavit ćete emitiranje aplikacije &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Otključano pomoću lica. Pritisnite da biste nastavili."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Lice je prepoznato. Pritisnite da biste nastavili."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice je prepoznato. Pritisnite ikonu otključavanja da biste nastavili."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Otključano licem. Dodirnite za nastavak."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikacija izvršena"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Otkaži autentifikaciju"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Više opcija"</string>
@@ -376,11 +383,11 @@
     <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Snimanje zaslona"</string>
     <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Početak"</string>
     <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Zaustavi"</string>
-    <string name="qs_record_issue_label" msgid="8166290137285529059">"Zabilježi poteškoću"</string>
+    <string name="qs_record_issue_label" msgid="8166290137285529059">"Zabilježite poteškoću"</string>
     <string name="qs_record_issue_start" msgid="2979831312582567056">"Pokreni"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"Zaustavi"</string>
-    <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Izvješće o pogrešci"</string>
-    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Na koji dio doživljaja na uređaju to utjecalo?"</string>
+    <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Izvješće o programskim pogreškama"</string>
+    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Na koji je dio doživljaja na uređaju to utjecalo?"</string>
     <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Odaberite vrstu problema"</string>
     <string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Snimanje zaslona"</string>
     <string name="performance" msgid="6552785217174378320">"Izvedba"</string>
@@ -469,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodavanje još widgeta"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Dugo pritisnite za prilagodbu widgeta"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagodi widgete"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Otključajte da biste prilagodili widgete"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacije za onemogućeni widget"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona aplikacije za widget koji se instalira"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Uredi widget"</string>
@@ -487,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"odaberi widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ukloni widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"postavi odabrani widget"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Promjena korisnika"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"padajući izbornik"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Izbrisat će se sve aplikacije i podaci u ovoj sesiji."</string>
@@ -540,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Pokreni"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nema obavijesti"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Nema novih obavijesti"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Prilagodljive obavijesti uklj."</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Uređaj sada stišava zvuk i smanjuje broj skočnih prozora na zaslonu na 2 minute kada primite jako puno obavijesti u kratkom vremenskom razdoblju."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Isključi"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Otključajte za starije obavijesti"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Ovim uređajem upravlja tvoj roditelj"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša je organizacija vlasnik ovog uređaja i može nadzirati mrežni promet"</string>
@@ -1195,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nema nijednog alarma"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"unesite zaključavanje zaslona"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Dodirnite senzor otiska prsta. To je kraća tipka s bočne strane telefona"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Senzor otiska prsta"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentificirali"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"pristupili uređaju"</string>
@@ -1336,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Koristi: <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nedavno koristila aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sustav"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Kontrole sustava"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplikacije sustava"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Obavljanje više zadataka"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nedavne aplikacije"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Podijeljeni zaslon"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Unos"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Prečaci aplikacija"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pristupačnost"</string>
@@ -1353,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Natrag"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Za povratak trima prstima prijeđite ulijevo ili udesno bilo gdje na dodirnoj podlozi."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Dodirna podloga prikazuje tri prsta koji se kreću udesno i ulijevo"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Na zaslonu uređaja prikazuje se animacija za pokret za povratak"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Pozadinsko osvjetljenje tipkovnice"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Razina %1$d od %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Upravljanje uređajima"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index bb22807..c408e30 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> észlelte ezt a képernyőképet."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> és más nyitott alkalmazások észlelték ezt a képernyőképet."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Hozzáadás jegyzethez"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Linkkel együtt"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Képernyőrögzítő"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Képernyőrögzítés feldolgozása"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Folyamatban lévő értesítés képernyőrögzítési munkamenethez"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Le fogja állítani a(z) &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; rögzítését"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Képernyő megosztása…"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Le fogja állítani a(z) &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; megosztását"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Képernyőtartalom átküldése…"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Le fogja állítani a(z) &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; átküldését"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Zárolás arccal feloldva. Koppintson a folytatáshoz."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Arc felismerve. Koppintson a folytatáshoz."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Arc felismerve. A folytatáshoz koppintson a Feloldásra."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Zárolás arccal feloldva. Koppintson a folytatáshoz."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Hitelesítve"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Hitelesítés megszakítása"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"További lehetőségek"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Egyes funkciók (például a Quick Share és a Készülékkereső) Bluetootht használnak"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"A Bluetooth holnap reggel bekapcsol"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Hang megosztása"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Hang megosztása…"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akkumulátor: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Hang"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
@@ -325,7 +330,7 @@
     <string name="quick_settings_user_title" msgid="8673045967216204537">"Felhasználó"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_networks_available" msgid="1875138606855420438">"Használhatók hálózatok"</string>
+    <string name="quick_settings_networks_available" msgid="1875138606855420438">"Elérhető hálózatok"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Nem használhatók hálózatok"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"Nincs elérhető Wi-Fi-hálózat"</string>
     <string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"Bekapcsolás…"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"További modulok hozzáadása"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Nyomja meg hosszan a modulok személyre szabásához"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Modulok személyre szabása"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"A feloldással személyre szabhatja a modulokat"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Letiltott modul alkalmazásikonja"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Folyamatban van egy modul alkalmazásikonjának telepítése"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Modul szerkesztése"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"modul kiválasztása"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"modul törlése"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"kijelölt modul áthelyezése"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Felhasználóváltás"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"lehúzható menü"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"A munkamenetben található összes alkalmazás és adat törlődni fog."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Indítás most"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nincs értesítés"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Nincsenek új értesítések"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Alkalmazkodó értesítések bekapcsolva"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Eszköze most legalább két percre csökkenti a hangerőt és a képernyőn előugró ablakok számát, amikor rövid időn belül sok értesítést kap."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Igen"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"A régebbiek feloldás után láthatók"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Az eszközt a szülőd felügyeli"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Az eszköz az Ön szervezetének tulajdonában van, és lehetséges, hogy a hálózati forgalmat is figyelik"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Koppintással további információkat érhet el."</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nincs ébresztés"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"képernyőzár megadása"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Érintse meg az ujjlenyomat-érzékelőt. Ez a rövidebb gomb a telefon oldalán."</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Ujjlenyomat-érzékelő"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"a hitelesítéshez"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"eszköz megadásához"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Használatban a következő által: <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Legutóbb használta: <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Rendszer"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Rendszervezérlők"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Rendszeralkalmazások"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Legutóbbi alkalmazások"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Osztott képernyő"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Bevitel"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Alkalmazás-parancsikonok"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Kisegítő lehetőségek"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Vissza"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"A visszalépéshez csúsztasson három ujjal gyorsan balra vagy a jobbra az érintőpad tetszőleges területén."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Három, jobbra és balra mozgó ujjat ábrázoló érintőpad"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"A Vissza kézmozdulat animációját megjelenítő eszközképernyő"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"A billentyűzet háttérvilágítása"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Fényerő: %2$d/%1$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Otthon vezérlése"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 14db87a..c898fca 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> հավելվածը հայտնաբերել է այս սքրինշոթը։"</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g>-ն ու բացված այլ հավելվածներ հայտնաբերել են այս սքրինշոթը։"</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ավելացնել նշմանը"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Ներառել հղումը"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Էկրանի տեսագրում"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Էկրանի տեսագրության մշակում"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Էկրանի տեսագրման աշխատաշրջանի ընթացիկ ծանուցում"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Դուք կկանգնեցնեք &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; հավելվածից բովանդակության տեսագրումը"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Միացված է էկրանի ցուցադրումը"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Դուք կկանգնեցնեք &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; հավելվածից բովանդակության փոխանցումը"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Էկրանի հեռարձակում"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Դուք կկանգնեցնեք &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; հավելվածից բովանդակության հեռարձակումը"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ապակողպվել է դեմքով։ Սեղմեք շարունակելու համար։"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Դեմքը ճանաչվեց։ Սեղմեք շարունակելու համար։"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Դեմքը ճանաչվեց։ Սեղմեք ապակողպման պատկերակը։"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Ապակողպվել է դեմքով։ Հպեք շարունակելու համար:"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Նույնականացված է"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Չեղարկել իսկորոշումը"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Լրացուցիչ ընտրանքներ"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Bluetooth-ն օգտագործում են, օրինակ, Quick Share և «Գտնել իմ սարքը» գործառույթները"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth-ը կմիանա վաղն առավոտյան"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Փոխանցել աուդիո"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Աուդիոյի փոխանցում"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Ավելացնել վիջեթներ"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Երկար սեղմեք՝ վիջեթները հարմարեցնելու համար"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Հարմարեցնել վիջեթները"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Ապակողպեք՝ վիջեթներն անհատականացնելու համար"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Հավելվածի պատկերակ անջատված վիջեթի համար"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Տեղադրվող վիջեթի հավելվածի պատկերակ"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Փոփոխել վիջեթը"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ընտրել վիջեթ"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"հեռացնել վիջեթը"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"տեղադրել ընտրված վիջեթը"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Անջատել օգտվողին"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"իջնող ընտրացանկ"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Այս աշխատաշրջանի բոլոր հավելվածներն ու տվյալները կջնջվեն:"</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Սկսել հիմա"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Ծանուցումներ չկան"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Նոր ծանուցումներ չկան"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Հարմարվող ծանուցումները միացված են"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Եթե կարճ ժամանակամիջոցում շատ ծանուցումներ ստանաք, ձայնը և ելնող պատուհանների թիվը կնվազեցվի մինչև երկու րոպեով։"</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Անջատել"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ապակողպեք՝ տեսնելու հին ծանուցումները"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Այս սարքը կառավարում է ձեր ծնողը"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ձեր կազմակերպությունը այս սարքի սեփականատերն է և կարող է վերահսկել ցանցային թրաֆիկը"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Հպեք՝ ավելին իմանալու համար"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Զարթուցիչ դրված չէ"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"ապակողպել էկրանը"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Հպեք մատնահետքի սկաներին։ Այն հեռախոսի կողքի ավելի կարճ կոճակն է"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Մատնահետքի սկաներ"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"նույնականացնել"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"նշել սարքը"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Օգտագործվում է <xliff:g id="APP_NAME">%1$s</xliff:g>ի կողմից (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Վերջերս օգտագործվել է <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի կողմից (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Համակարգ"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Համակարգի կառավարման տարրեր"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Համակարգային հավելվածներ"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Բազմախնդրություն"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Վերջին օգտագործած հավելվածները"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Տրոհված էկրան"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Ներածում"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Հավելվածի դյուրանցումներ"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Հատուկ գործառույթներ"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Հետ գնալ"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Հետ գնալու համար հպահարթակի վրա երեք մատով սահեցրեք ձախ կամ աջ։"</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Երեք մատները աջ ու ձախ են շարժվում հպահարթակի վրա"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Սարքի էկրանին ցուցադրվում է շարժանկար՝ հետ գնալու ժեստի համար"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Հետին լուսավորությամբ ստեղնաշար"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d՝ %2$d-ից"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Տան կառավարման տարրեր"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index f9f6370..9546cf0 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> mendeteksi screenshot ini."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> dan aplikasi terbuka lainnya mendeteksi screenshot ini."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Tambahkan ke catatan"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Sertakan link"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Perekam Layar"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Memproses perekaman layar"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifikasi yang sedang berjalan untuk sesi rekaman layar"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Anda akan berhenti merekam &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Membagikan layar"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Anda akan berhenti membagikan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Mentransmisikan layar"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Anda akan berhenti mentransmisikan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Kunci dibuka dengan wajah. Tekan untuk melanjutkan."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Wajah dikenali. Tekan untuk melanjutkan."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Wajah dikenali. Tekan ikon buka kunci untuk melanjutkan."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Kunci dibuka dengan wajah. Ketuk untuk melanjutkan."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Diautentikasi"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Batalkan Autentikasi"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Opsi Lainnya"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Fitur seperti Quick Share dan Temukan Perangkat Saya menggunakan Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth akan dinyalakan besok pagi"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Bagikan audio"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Berbagi audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterai <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
@@ -382,7 +387,7 @@
     <string name="qs_record_issue_start" msgid="2979831312582567056">"Mulai"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"Berhenti"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Laporan Bug"</string>
-    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Bagian pengalaman perangkat mana yang terpengaruh?"</string>
+    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Hal apa yang terpengaruh?"</string>
     <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Pilih jenis masalah"</string>
     <string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Perekaman layar"</string>
     <string name="performance" msgid="6552785217174378320">"Performa"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Tambahkan widget lainnya"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Tekan lama untuk menyesuaikan widget"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Sesuaikan widget"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Buka kunci untuk menyesuaikan widget"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikon aplikasi untuk widget yang dinonaktifkan"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikon aplikasi untuk widget yang sedang diinstal"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"pilih widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"hapus widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"letakkan widget yang dipilih"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Beralih pengguna"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu pulldown"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua aplikasi dan data dalam sesi ini akan dihapus."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Mulai sekarang"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Tidak ada notifikasi"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Tidak ada notifikasi baru"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notifikasi adaptif aktif"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Perangkat Anda kini akan menurunkan volume dan mengurangi jendela pop-up di layar hingga dua menit saat Anda menerima banyak notifikasi dalam waktu singkat."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Nonaktifkan"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Buka kunci untuk melihat notifikasi lama"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Perangkat ini dikelola oleh orang tuamu"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisasi Anda memiliki perangkat ini dan mungkin memantau traffic jaringan"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ketuk untuk informasi selengkapnya"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Alarm tidak disetel"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"masukkan kunci layar"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Sentuh sensor sidik jari. Sensor terletak di tombol yang lebih pendek di samping layar ponsel"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor sidik jari"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentikasi"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"masukkan perangkat"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Sedang digunakan oleh <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Baru saja digunakan oleh <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Kontrol sistem"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplikasi sistem"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Aplikasi terbaru"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Layar terpisah"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Pintasan aplikasi"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Aksesibilitas"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Kembali"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Untuk kembali, geser ke kiri atau ke kanan menggunakan tiga jari ke mana saja di touchpad."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad menampilkan tiga jari yang bergerak ke kanan dan ke kiri"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Layar perangkat menampilkan animasi untuk gestur kembali"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Lampu latar keyboard"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Tingkat %1$d dari %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrol Rumah"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 0266cb2..a6c7f88 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> greindi skjámyndina."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> og önnur opin forrit greindu skjámyndina."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Bæta við glósu"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Hafa tengil með"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Skjáupptaka"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Vinnur úr skjáupptöku"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Áframhaldandi tilkynning fyrir skjáupptökulotu"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Þú munt hætta upptöku úr &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Deilir skjá"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Þú munt hætta að deila úr &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Varpar skjá"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Þú munt hætta vörpun úr &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Opnað með andliti. Ýttu til að halda áfram."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Andlitið var greint. Ýttu til að halda áfram."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Andlitið var greint. Ýttu á opnunartáknið til að halda áfr."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Opnað með andliti. Ýttu til að halda áfram."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Auðkennt"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Hætta við auðkenningu"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Fleiri valkostir"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Eiginleikar eins og Flýtideiling og Finna tækið mitt nota Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Kveikt verður á Bluetooth í fyrramálið"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Deila hljóði"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Deilir hljóði"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> rafhlöðuhleðsla"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Hljóð"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Höfuðtól"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Bæta við fleiri græjum"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Haltu inni til að sérsníða græjur"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Sérsníða græjur"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Opnaðu til að sérsníða græjur"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Forritstákn fyrir græju sem slökkt er á"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Forritatákn fyrir græju sem verið er að setja upp"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Breyta græju"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"velja græju"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"fjarlægja græju"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"koma valinni græju fyrir"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Skipta um notanda"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"Fellivalmynd"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Öllum forritum og gögnum í þessari lotu verður eytt."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Byrja núna"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Engar tilkynningar"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Engar nýjar tilkynningar"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Kveikt á breytil. tilkynningum"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Tækið þitt lækkar nú hljóðstyrkinn og fækkar sprettigluggum á skjánum í allt að tvær mínútur þegar þú færð margar tilkynningar á stuttum tíma."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Slökkva"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Taktu úr lás til að sjá eldri tilkynningar"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Foreldri þitt stjórnar þessu tæki"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Fyrirtækið þitt á þetta tæki og fylgist hugsanlega með netumferð"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ýttu til að fá frekari upplýsingar"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Enginn vekjari"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"sláðu inn skjálás"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Snertu fingrafaralesarann. Það er styttri hnappurinn á hlið símans"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingrafaralesari"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"auðkenna"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"opna tæki"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Í notkun í <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nýlega notað af <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Kerfi"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Kerfisstýringar"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Kerfisforrit"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Fjölvinnsla"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nýleg forrit"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Skjáskipting"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Inntak"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Flýtileiðir forrita"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Aðgengi"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Til baka"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Strjúktu til vinstri eða hægri með þrem fingrum hvar sem er á snertifletinum til að fara til baka."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Snertiflötur sem sýnir þrjá fingur færast til hægri og vinstri"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Skjár tækis sem sýnir hreyfimynd fyrir bendinguna „til baka“."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Baklýsing lyklaborðs"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Stig %1$d af %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Heimastýringar"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 9cc5124..6067329 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ha rilevato questo screenshot."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e altre app aperte hanno rilevato questo screenshot."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Aggiungi alla nota"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Includi link"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Registrazione dello schermo"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Elaborazione registrazione…"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifica costante per una sessione di registrazione dello schermo"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Interromperai la registrazione di &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Condivisione dello schermo in corso"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Interromperai la condivisione di &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Trasmissione dello schermo attiva"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Interromperai la trasmissione di &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Sbloccato con il volto. Premi per continuare."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Volto riconosciuto. Premi per continuare."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Volto riconosciuto. Premi l\'icona Sblocca e continua."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Sbloccato con il volto. Tocca per continuare."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticazione eseguita"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Annulla autenticazione"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Altre opzioni"</string>
@@ -469,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Aggiungi altri widget"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Premi a lungo per personalizzare i widget"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizza widget"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Sblocca per personalizzare i widget"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icona dell\'app per widget disattivati"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Icona dell\'app per un widget in fase di installazione"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Modifica widget"</string>
@@ -487,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"seleziona widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"rimuovi widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"posiziona il widget selezionato"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Cambio utente"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu a discesa"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tutte le app e i dati di questa sessione verranno eliminati."</string>
@@ -540,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Avvia adesso"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nessuna notifica"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Nessuna nuova notifica"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notifiche adattive attivate"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Il dispositivo abbassa il volume e riduce i popup fino a 2 minuti quando ricevi molte notifiche."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Disattiva"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Sblocca per vedere le notifiche meno recenti"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Questo dispositivo è gestito dai tuoi genitori"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Questo dispositivo appartiene alla tua organizzazione, che potrebbe monitorare il traffico di rete"</string>
@@ -1195,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tocca per ulteriori informazioni"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nessuna"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"inserisci blocco schermo"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Tocca il sensore di impronte digitali. È il tasto più corto sul lato dello smartphone"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensore di impronte digitali"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"effettuare l\'autenticazione"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"accedere al dispositivo"</string>
@@ -1336,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"In uso da <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Recentemente in uso da <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controlli di sistema"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"App di sistema"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"App recenti"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Schermo diviso"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Scorciatoie app"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibilità"</string>
@@ -1353,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Indietro"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Per tornare indietro, scorri verso sinistra o verso destra utilizzando tre dita in un punto qualsiasi del touchpad."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad che mostra tre dita che si muovono verso destra e sinistra"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Schermata del dispositivo che mostra l\'animazione del gesto per tornare indietro"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Retroilluminazione della tastiera"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Livello %1$d di %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Controlli della casa"</string>
diff --git a/packages/SystemUI/res/values-it/tiles_states_strings.xml b/packages/SystemUI/res/values-it/tiles_states_strings.xml
index aa76983..2fd4f6d 100644
--- a/packages/SystemUI/res/values-it/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-it/tiles_states_strings.xml
@@ -188,7 +188,7 @@
   </string-array>
   <string-array name="tile_states_hearing_devices">
     <item msgid="1235334096484287173">"Non disponibile"</item>
-    <item msgid="3079622119444911877">"Off"</item>
-    <item msgid="3028994095749238254">"On"</item>
+    <item msgid="3079622119444911877">"Disattivi"</item>
+    <item msgid="3028994095749238254">"Attivi"</item>
   </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 734e7da..fba9920 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -103,11 +103,12 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"האפליקציה <xliff:g id="APPNAME">%1$s</xliff:g> זיהתה את צילום המסך הזה."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"האפליקציה <xliff:g id="APPNAME">%1$s</xliff:g> ואפליקציות פתוחות נוספות זיהו את צילום המסך הזה."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"הוספה לפתק"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"הכנסת הקישור"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"מקליט המסך"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"מתבצע עיבוד של הקלטת מסך"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"התראה מתמשכת לסשן הקלטת מסך"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"להתחיל את ההקלטה?"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"‏בזמן ההקלטה, תהיה ל-Android גישה לכל מה שמופיע במסך שלך או מנוגן במכשיר שלך. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"‏בזמן ההקלטה, תהיה ל-Android גישה לכל מה שמופיע במסך שלך או מופעל במכשיר שלך. מומלץ להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"‏בזמן הקלטה של אפליקציה, תהיה ל-Android גישה לכל מה שגלוי באפליקציה או מופעל מהאפליקציה. כדאי להיזהר עם סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"התחלת ההקלטה"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"הקלטת אודיו"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"‏ההקלטה של &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; תיפסק"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"שיתוף המסך מתבצע"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"‏השיתוף של &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; יופסק"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"‏הפעלת Cast של המסך מתבצעת"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"‏הפעלת ה-Cast‏ של &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; תיפסק"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"הנעילה בוטלה באמצעות זיהוי הפנים. יש ללחוץ כדי להמשיך."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"הפנים זוהו. יש ללחוץ כדי להמשיך."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"הפנים זוהו. להמשך יש ללחוץ על סמל ביטול הנעילה."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"הנעילה בוטלה באמצעות זיהוי הפנים. צריך להקיש כדי להמשיך."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"מאומת"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ביטול האימות"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"אפשרויות נוספות"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"‏תכונות כמו \'שיתוף מהיר\' ו\'איפה המכשיר שלי\' משתמשות ב-Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"‏חיבור ה-Bluetooth יופעל מחר בבוקר"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"שיתוף האודיו"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"מתבצע שיתוף של האודיו"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"הוספת ווידג\'טים"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"לוחצים לחיצה ארוכה כדי להתאים אישית את הווידג\'טים"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"התאמה אישית של ווידג\'טים"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"כדי להתאים אישית את הווידג\'טים, צריך לבטל את הנעילה"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"סמל האפליקציה לווידג\'ט שהושבת"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"סמל האפליקציה של ווידג\'ט בתהליך התקנה"</string>
     <string name="edit_widget" msgid="9030848101135393954">"עריכת הווידג\'ט"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"צריך לבחור ווידג\'ט"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"הסרת הווידג\'ט"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"צריך למקם את הווידג\'ט שנבחר"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"החלפת משתמש"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"תפריט במשיכה למטה"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"כל האפליקציות והנתונים בסשן הזה יימחקו."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"כן, אפשר להתחיל"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"אין התראות"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"אין התראות חדשות"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"ההתראות המותאמות מופעלות"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"מעכשיו, כשיש התראות רבות בזמן קצר, עוצמת הקול מופחתת ומופיעים פחות חלונות קופצים במשך עד שתי דקות."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"השבתה"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"יש לבטל את הנעילה כדי לראות התראות ישנות"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"המכשיר הזה מנוהל על ידי ההורה שלך"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"הארגון שלך הוא הבעלים של המכשיר הזה והוא עשוי לנטר את התנועה ברשת"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"יש להקיש כדי להציג מידע נוסף"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"לא הוגדרה"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"הזנת קוד נעילת המסך"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"צריך לגעת בחיישן טביעות האצבע. זה הלחצן הקצר יותר בצד של הטלפון"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"חיישן טביעות אצבע"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"אימות"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"הזנת מכשיר"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"בשימוש על ידי <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"נעשה שימוש לאחרונה על ידי <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"מערכת"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"הגדרות המערכת"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"אפליקציות מערכת"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ריבוי משימות"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"אפליקציות אחרונות"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"מסך מפוצל"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"קלט"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"קיצורי דרך של אפליקציות"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"נגישות"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"חזרה"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"כדי לחזור אחורה, מחליקים שמאלה או ימינה עם שלוש אצבעות בכל מקום על לוח המגע."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"לוח מגע שמראה שלוש אצבעות זזות ימינה ושמאלה"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"מסך מכשיר שמראה אנימציה לתנועה אחורה"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"התאורה האחורית במקלדת"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"‏רמה %1$d מתוך %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"שליטה במכשירים"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 6e62972..5a57016 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> がこのスクリーンショットを検出しました。"</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> とその他の開いているアプリがこのスクリーンショットを検出しました。"</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"メモに追加"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"リンクを含める"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"スクリーン レコーダー"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"画面の録画を処理しています"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"画面の録画セッション中の通知"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; の記録を停止します"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"画面を共有しています"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; の共有を停止します"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"画面をキャストしています"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; のキャストを停止します"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"顔でロック解除しました。押して続行してください。"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"顔を認識しました。押して続行してください。"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"顔を認識しました。ロック解除アイコンを押して続行します。"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"顔認証でロック解除しました。タップして続行します。"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"認証済み"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"認証をキャンセルします"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"その他のオプション"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share や「デバイスを探す」などの機能は Bluetooth を使用します"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"明日の朝に Bluetooth が ON になります"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"音声を共有"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"音声を共有中"</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>
@@ -383,7 +388,7 @@
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"停止"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"バグレポート"</string>
     <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"デバイスのどの部分が影響を受けましたか?"</string>
-    <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"問題の種類を選択する"</string>
+    <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"問題の種類を選択"</string>
     <string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"スクリーン レコード"</string>
     <string name="performance" msgid="6552785217174378320">"パフォーマンス"</string>
     <string name="user_interface" msgid="3712869377953950887">"ユーザー インターフェース"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ウィジェットの追加"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"長押ししてウィジェットをカスタマイズ"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ウィジェットのカスタマイズ"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ウィジェットをカスタマイズするにはロックを解除してください"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"無効なウィジェットのアプリアイコン"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"インストール中のウィジェットのアプリアイコン"</string>
     <string name="edit_widget" msgid="9030848101135393954">"ウィジェットを編集"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ウィジェットを選択"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ウィジェットを削除"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"選択したウィジェットを配置"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ユーザーを切り替える"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"プルダウン メニュー"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"このセッションでのアプリとデータはすべて削除されます。"</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"今すぐ開始"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"通知はありません"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"新しい通知はありません"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"通知の自動調整は ON です"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"短期間に多くの通知が届いたときに最長 2 分間デバイスの音量を下げて画面上のポップアップを減らします。"</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"OFF にする"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ロック解除して以前の通知を表示"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"このデバイスは保護者によって管理されています"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"これは組織が所有するデバイスで、ネットワーク トラフィックが監視されることもあります"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"タップすると詳細が表示されます"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"アラーム未設定"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"画面ロックを設定"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"指紋認証センサーに触れてください。スマートフォンの側面にある高さが低い方のボタンです。"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"指紋認証センサー"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"認証"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"デバイスを入力"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> が使用中(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> が最近使用(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"システム"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"システム コントロール"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"システムアプリ"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"マルチタスク"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"最近使ったアプリ"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"分割画面"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"入力"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"アプリのショートカット"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ユーザー補助"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"戻る"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"戻るには、3 本の指でタッチパッドを左右にスワイプします。"</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"タッチパッドで 3 本の指を左右に動かしている様子"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"デバイスの画面で「戻る」ジェスチャーのアニメーションが表示されている様子"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"キーボード バックライト"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"レベル %1$d/%2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ホーム コントロール"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 5914f12..dd92fee 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>-მა აღმოაჩინა ეკრანის ეს ანაბეჭდი"</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g>-მა და სხვა გახსნილმა აპებმა აღმოაჩინეს ეკრანის ეს ანაბეჭდი."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"დაამატეთ შენიშვნა"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"ბმულის დართვა"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"ეკრანის ჩამწერი"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ეკრანის ჩანაწერი მუშავდება"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"უწყვეტი შეტყობინება ეკრანის ჩაწერის სესიისთვის"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"თქვენ შეწყვეტთ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>-ის&lt;/b&gt; ჩაწერას"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"მიმდინარეობს ეკრანის გაზიარება"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"თქვენ შეწყვეტთ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>-ის&lt;/b&gt; გაზიარებას"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"მიმდინარეობს ეკრანის ტრანსლირება"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"თქვენ შეწყვეტთ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>-ის&lt;/b&gt; ტრანსლირებას"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"განიბლოკა სახით. დააჭირეთ გასაგრძელებლად."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ამოცნობილია სახით. დააჭირეთ გასაგრძელებლად."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ამოცნობილია სახით. გასაგრძელებლად დააჭირეთ განბლოკვის ხატულას."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"განიბლოკა სახით. შეეხეთ გასაგრძელებლად."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ავტორიზებულია"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ავტორიზაციის გაუქმება"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"სხვა ვარიანტები"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ისეთი ფუნქციები, როგორიცაა სწრაფი გაზიარება და ჩემი მოწყობილობის პოვნა, იყენებს Bluetooth-ს"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ჩაირთვება ხვალ დილით"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"აუდიოს გაზიარება"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"მიმდინარებოს აუდიოს გაზიარება"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ვიჯეტების დამატება"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ხანგრძლივად დააჭირეთ ვიჯეტების მოსარგებად"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ვიჯეტების მორგება"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ვიჯეტების მოსარგებად განბლოკეთ"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"აპის ხატულა გათიშული ვიჯეტისთვის"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ინსტალაციის პროცესში მყოფი ვიჯეტის აპის ხატულა"</string>
     <string name="edit_widget" msgid="9030848101135393954">"ვიჯეტის რედაქტირება"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ვიჯეტის არჩევა"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ვიჯეტის ამოშლა"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"არჩეული ვიჯეტის განთავსება"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"მომხმარებლის გადართვა"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ჩამოშლადი მენიუ"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ამ სესიის ყველა აპი და მონაცემი წაიშლება."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"დაწყება ახლავე"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"შეტყობინებები არ არის."</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"ახალი შეტყობინებები არ არის"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"მორგებადი შეტყობინებები ჩართულია"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"მოკლე დროში ბევრი შეტყობინების მიღებისას თქვენი მოწყობილობა ახლა უკვე ამცირებს ხმას და ეკრანზე ამომხტარი ფანჯრების რაოდენობას."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"გამორთვა"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"განბლოკეთ ძველი შეტყობინებების სანახავად"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"მოწყობილობას თქვენი მშობელი მართავს"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ამ მოწყობილობას ფლობს თქვენი ორგანიზაცია და მას ქსელის ტრაფიკის მონიტორინგი შეუძლია"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"შეეხეთ მეტი ინფორმაციისთვის"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"მაღვიძარა არ არის"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"ეკრანის დაბლოკვის შეყვანა"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"შეეხეთ თითის ანაბეჭდის სენსორს. ის მოკლე ღილაკია ტელეფონის კიდეზე"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"თითის ანაბეჭდის სენსორი"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"ავტორიზაცია"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"მოწყობილობის შეყვანა"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"გამოიყენება <xliff:g id="APP_NAME">%1$s</xliff:g>-ის მიერ (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"ახლახან გამოყენებულია <xliff:g id="APP_NAME">%1$s</xliff:g>-ის მიერ (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"სისტემა"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"სისტემის მართვის საშუალებები"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"სისტემის აპები"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"მრავალამოცანიანი რეჟიმი"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"ბოლოდროინდელი აპები"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"ეკრანის გაყოფა"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"შეყვანა"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"აპის მალსახმობები"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"მისაწვდომობა"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"უკან დაბრუნება"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"უკან დასაბრუნებლად, სენსორულ პანელზე ნებისმიერ ადგილას სამი თითის გამოყენებით გადაფურცლეთ მარცხნივ ან მარჯვნივ."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"სენსორული პანელი, რომელიც აჩვენებს მარჯვენა და მარცხენა მიმართულებით მოძრავ სამ თითს"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"მოწყობილობის ეკრანი, რომელიც აჩვენებს უკან დაბრუნების ჟესტის ანიმაციას"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"კლავიატურის შენათება"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"დონე: %1$d %2$d-დან"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"სახლის კონტროლი"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 40b9149..2c7d43d 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -103,11 +103,12 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> қолданбасы осы скриншотты анықтады."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> және басқа да ашық қолданбалар осы скриншотты анықтады."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ескертпеге қосу"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Сілтеме қосу"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Экран жазғыш"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Экран жазғыш бейнесін өңдеу"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды бейнеге жазудың ағымдағы хабарландыруы"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Жазу басталсын ба?"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Жазу кезінде Android жүйесі экраныңызда көрінетін не құрылғыңызда ойнатылатын барлық нәрсені пайдалана алады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізген кезде сақ болыңыз."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Жазу кезінде Android жүйесі экраныңызда көрінетін не құрылғыңызда ойнатылатын барлық нәрсені пайдалана алады. Сондықтан құпия сөздерге, төлем туралы мәліметке, хабарларға, фотосуреттерге, аудиоконтент пен бейнелерге сақ болыңыз."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Қолданбаны жазу кезінде Android жүйесі қолданбада көрінетін не ойнатылатын барлық нәрсені пайдалана алады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізген кезде сақ болыңыз."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Жазуды бастау"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Аудио жазу"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; қолданбасының контентін жазуды тоқтатасыз."</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Экранды бөлісіп жатыр."</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; қолданбасының контентін бөлісуді тоқтатасыз."</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Экранды трансляциялап жатыр."</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; қолданбасының контентін трансляциялауды тоқтатасыз."</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Бетпен ашылды. Жалғастыру үшін басыңыз."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Бет танылды. Жалғастыру үшін басыңыз."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Бет танылды. Жалғастыру үшін құлыпты ашу белгішесін басыңыз."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Бетпен ашылды. Жалғастыру үшін түртіңіз."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аутентификацияланған"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Аутентификациядан бас тарту"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Қосымша опциялар"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share және Find My Device сияқты функциялар Bluetooth-ты пайдаланады."</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ертең таңертең қосылады."</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Аудионы бөлісу"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Аудио бөлісіліп жатыр"</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">"Aудио"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Гарнитура"</string>
@@ -383,9 +388,9 @@
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"Тоқтату"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Қате туралы есеп"</string>
     <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Құрылғы қызметінің қандай түріне әсер етті?"</string>
-    <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Мәселе түрін таңдаңыз."</string>
+    <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Ақау түрін таңдаңыз"</string>
     <string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Экранды жазу"</string>
-    <string name="performance" msgid="6552785217174378320">"Өнімділік режимі"</string>
+    <string name="performance" msgid="6552785217174378320">"Өнімділік"</string>
     <string name="user_interface" msgid="3712869377953950887">"Пайдаланушы интерфейсі"</string>
     <string name="thermal" msgid="6758074791325414831">"Термовизия"</string>
     <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Бір қолмен басқару режимі"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Басқа виджеттер қосыңыз."</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Виджеттерді бейімдеу үшін ұзақ басып тұрыңыз."</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Виджеттерді реттеу"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Виджеттерді бейімдеу үшін құлыпты ашыңыз."</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Өшірілген виджеттің қолданба белгішесі"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Виджетке арналған қолдана белгішесі орнатылып жатыр."</string>
     <string name="edit_widget" msgid="9030848101135393954">"Виджетті өзгерту"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"виджет таңдау"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"виджетті өшіру"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"таңдалған виджетті орналастыру"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Пайдаланушыны ауыстыру"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ашылмалы мәзір"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Осы сеанстағы барлық қолданба мен дерек жойылады."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Қазір бастау"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Хабарландырулар жоқ"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Жаңа хабарландырулар жоқ"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Бейімделетін хабарландырулар қосулы"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Қысқа уақыт аралығында көп хабарландыру алсаңыз, құрылғыңыз дыбыс деңгейін және экранда шығатын қалқымалы терезелердің уақытын екі минутқа дейін азайтады."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Өшіру"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ескі хабарландырулар үшін құлыпты ашыңыз"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Бұл құрылғыны ата-анаңыз басқарады."</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ұйымыңыз осы құрылғыны басқарады және желі трафигін бақылауы мүмкін."</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Толығырақ ақпарат алу үшін түртіңіз."</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Оятқыш орнатылмаған."</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"экран құлпын енгізу"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Саусақ ізін оқу сканерін түртіңіз. Ол – телефонның бүйіріндегі шағын түйме."</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Саусақ ізін оқу сканері"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"аутентификациялау"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"құрылғыны енгізу"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) қолданбасы пайдаланып жатыр"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Соңғы рет <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) қолданбасы пайдаланды."</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Жүйе"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Жүйені басқару элементтері"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Жүйелік қолданбалар"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Мультитаскинг"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Соңғы қолданбалар"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Экранды бөлу"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Кіріс"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Қолданба таңбашалары"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Арнайы мүмкіндіктер"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Артқа"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Артқа қайту үшін сенсорлық тақтаның кез келген жерінен үш саусақпен солға немесе оңға сырғытыңыз."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Оңға және солға жылжитын үш саусақты көрсетіп тұрған сенсорлық тақта."</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Артқа қайту қимылын көрсетіп тұрған құрылғы экраны."</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Пернетақта жарығы"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Деңгей: %1$d/%2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Үй басқару элементтері"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 3836d7d..e16225b 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> បានរកឃើញ​រូបថតអេក្រង់នេះ។"</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> និងកម្មវិធីដែលបើក​ផ្សេងទៀតបានរកឃើញ​រូបថតអេក្រង់នេះ។"</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"បញ្ចូលទៅក្នុងកំណត់ចំណាំ"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"រួមបញ្ចូល​តំណ"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"មុខងារថត​វីដេអូអេក្រង់"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"កំពុង​ដំណើរការ​ការថតអេក្រង់"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ការជូនដំណឹង​ដែល​កំពុង​ដំណើរការ​សម្រាប់​រយៈពេលប្រើ​ការថត​សកម្មភាព​អេក្រង់"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"អ្នកនឹងឈប់ថត &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"កំពុងបង្ហាញអេក្រង់"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"អ្នកនឹងឈប់ចែករំលែក &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"កំពុង​បញ្ជូន​អេក្រង់"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"អ្នកនឹងឈប់បញ្ជូន &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"បានដោះសោដោយប្រើមុខ។ សូមចុច ដើម្បីបន្ត។"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"បានស្គាល់មុខ។ សូមចុច ដើម្បីបន្ត។"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"បានស្គាល់មុខ។ សូមចុចរូបដោះសោ ដើម្បីបន្ត។"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"បានដោះសោដោយប្រើមុខ។ ចុច​ ដើម្បី​បន្ត។"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"បាន​ផ្ទៀងផ្ទាត់"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"បោះបង់ការផ្ទៀងផ្ទាត់"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ជម្រើស​ច្រើន​ទៀត"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"មុខងារដូចជា Quick Share និង \"រកឧបករណ៍របស់ខ្ញុំ\" ប្រើប៊្លូធូស"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ប៊្លូធូសនឹងបើកនៅព្រឹកស្អែក"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ស្ដាប់សំឡេងរួមគ្នា"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"កំពុងស្ដាប់សំឡេងរួមគ្នា"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"បញ្ចូលធាតុ​ក្រាហ្វិកច្រើនទៀត"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ចុច​ឱ្យ​យូរ ដើម្បីប្ដូរធាតុ​ក្រាហ្វិកតាមបំណង"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ប្ដូរ​ធាតុ​ក្រាហ្វិកតាម​បំណង"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ដោះសោ​ដើម្បីប្ដូរធាតុ​ក្រាហ្វិកតាមបំណង"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"រូបកម្មវិធីសម្រាប់ធាតុ​ក្រាហ្វិកដែលបានបិទ"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"រូបតំណាងកម្មវិធីសម្រាប់ធាតុ​ក្រាហ្វិកកំពុងត្រូវបានដំឡើង"</string>
     <string name="edit_widget" msgid="9030848101135393954">"កែធាតុ​ក្រាហ្វិក"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ជ្រើសរើសធាតុ​ក្រាហ្វិក"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ដកធាតុ​ក្រាហ្វិកចេញ"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ដាក់ធាតុ​ក្រាហ្វិកដែលបានជ្រើសរើស"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ប្ដូរ​អ្នក​ប្រើ"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ម៉ឺនុយ​ទាញចុះ"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"កម្មវិធី និងទិន្នន័យ​ទាំងអស់​ក្នុង​វគ្គ​នេះ​នឹង​ត្រូវ​លុប។"</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"ចាប់ផ្ដើម​ឥឡូវ"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"គ្មាន​ការ​ជូនដំណឹង"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"គ្មាន​ការ​ជូន​ដំណឹង​​ថ្មីៗទេ"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"ការជូនដំណឹងដែលបត់បែនត្រូវបានបើក"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"ឥឡូវនេះ ឧបករណ៍របស់អ្នកបន្ថយកម្រិតសំឡេង និងកាត់បន្ថយផ្ទាំងលោតឡើងនៅលើអេក្រង់រយៈពេលរហូតដល់ពីរនាទី នៅពេលអ្នកទទួលបានការជូនដំណឹងច្រើនក្នុងរយៈពេលខ្លី។"</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"បិទ"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ដោះសោដើម្បីមើលការជូនដំណឹងចាស់ៗ"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ឧបករណ៍​នេះ​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​របស់មាតាបិតាអ្នក"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ស្ថាប័ន​របស់អ្នក​ជាម្ចាស់​ឧបករណ៍​នេះ ហើយ​អាចនឹង​តាមដាន​ចរាចរណ៍បណ្តាញ"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ចុចដើម្បីទទួលបាន​ព័ត៌មានបន្ថែម"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"មិនបាន​កំណត់​ម៉ោងរោទ៍​ទេ"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"បញ្ចូលព័ត៌មានផ្ទៀងផ្ទាត់សម្រាប់ការចាក់សោអេក្រង់"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ប៉ះ​សេនស័រចាប់ស្នាមម្រាមដៃ។ វាជាប៊ូតុងខ្លីនៅចំហៀងទូរសព្ទ"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ឧបករណ៍​ចាប់ស្នាមម្រាមដៃ"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"ផ្ទៀងផ្ទាត់"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"បញ្ចូល​ឧបករណ៍"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"កំពុងប្រើដោយ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"បានប្រើនាពេលថ្មីៗនេះដោយ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"ប្រព័ន្ធ"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ការគ្រប់គ្រង​ប្រព័ន្ធ"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"កម្មវិធី​ប្រព័ន្ធ"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ការដំណើរការបានច្រើន"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"កម្មវិធី​ថ្មីៗ"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"មុខងារ​បំបែកអេក្រង់"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"ធាតុចូល"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ផ្លូវកាត់​កម្មវិធី"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ភាពងាយស្រួល"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ថយ​ក្រោយ"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ដើម្បីថយក្រោយ សូមអូសទៅឆ្វេង ឬស្ដាំដោយប្រើម្រាមដៃបីនៅកន្លែងណាមួយនៅលើផ្ទាំងប៉ះ។"</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ផ្ទាំងប៉ះដែលបង្ហាញម្រាមដៃបីដែលផ្លាស់ទីទៅស្ដាំ និងឆ្វេង"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"អេក្រង់ឧបករណ៍ដែលបង្ហាញរូបមានចលនាសម្រាប់ចលនាថយក្រោយ"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ពន្លឺក្រោយក្ដារចុច"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"កម្រិតទី %1$d នៃ %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ការគ្រប់គ្រង​ផ្ទះ"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 85d67cd..24f5bb5 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"ಈ ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ಅನ್ನು <xliff:g id="APPNAME">%1$s</xliff:g> ಪತ್ತೆಹಚ್ಚಿದೆ."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ಹಾಗೂ ತೆರೆದಿರುವ ಇತರ ಆ್ಯಪ್‌ಗಳು ಈ ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ಅನ್ನು ಪತ್ತೆಹಚ್ಚಿವೆ."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ಟಿಪ್ಪಣಿಗೆ ಸೇರಿಸಿ"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"ಲಿಂಕ್ ಅನ್ನು ಸೇರಿಸಿ"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡರ್"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಆಗುತ್ತಿದೆ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಸೆಶನ್‌ಗಾಗಿ ಚಾಲ್ತಿಯಲ್ಲಿರುವ ನೋಟಿಫಿಕೇಶನ್"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"ಇದರಿಂದ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ನ ಕಂಟೆಂಟ್ ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡುವುದು ನಿಂತುಹೋಗುತ್ತದೆ"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ಪರದೆಯನ್ನು ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತಿದೆ"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"ಇದರಿಂದ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ನ ಕಂಟೆಂಟ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳುವುದು ನಿಂತುಹೋಗುತ್ತದೆ"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"ಪರದೆಯನ್ನು ಬಿತ್ತರಿಸಲಾಗುತ್ತಿದೆ"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"ಇದರಿಂದ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ನ ಕಂಟೆಂಟ್ ಅನ್ನು ಬಿತ್ತರಿಸುವುದು ನಿಂತುಹೋಗುತ್ತದೆ"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಒತ್ತಿ."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಒತ್ತಿ."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"ಮುಖವನ್ನು ಬಳಸಿ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ದೃಢೀಕರಣವನ್ನು ರದ್ದುಗೊಳಿಸಿ"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ಇನ್ನಷ್ಟು ಆಯ್ಕೆಗಳು"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ಕ್ವಿಕ್ ಶೇರ್ ಮತ್ತು Find My Device ನಂತಹ ಫೀಚರ್‌ಗಳು ಬ್ಲೂಟೂತ್ ಅನ್ನು ಬಳಸುತ್ತವೆ"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ಬ್ಲೂಟೂತ್ ನಾಳೆ ಬೆಳಗ್ಗೆ ಆನ್ ಆಗುತ್ತದೆ"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ಆಡಿಯೋ ಹಂಚಿಕೊಳ್ಳಿ"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"ಆಡಿಯೋವನ್ನು ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತಿದೆ"</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>
@@ -382,7 +387,7 @@
     <string name="qs_record_issue_start" msgid="2979831312582567056">"ಪ್ರಾರಂಭಿಸಿ"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"ನಿಲ್ಲಿಸಿ"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"ಬಗ್ ವರದಿ ಮಾಡುವಿಕೆ"</string>
-    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"ಸಾಧನ ಬಳಸುವಾಗ ನೀವು ಯಾವ ರೀತಿಯ ಸಮಸ್ಯೆ ಎದುರಿಸುತ್ತೀರಿ?"</string>
+    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"ನಿಮ್ಮ ಸಾಧನದ ಯಾವ ಭಾಗದಲ್ಲಿ ಸಮಸ್ಯೆ ಉಂಟಾಗಿದೆ?"</string>
     <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"ಸಮಸ್ಯೆಯ ಪ್ರಕಾರವನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡ್"</string>
     <string name="performance" msgid="6552785217174378320">"ಪರ್ಫಾರ್ಮೆನ್ಸ್"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ಹೆಚ್ಚಿನ ವಿಜೆಟ್‌ಗಳನ್ನು ಸೇರಿಸಿ"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ವಿಜೆಟ್‌ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಲು ದೀರ್ಘಕಾಲ ಒತ್ತಿರಿ"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ವಿಜೆಟ್‌ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ವಿಜೆಟ್‌ಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಲು ಅನ್‌ಲಾಕ್ ಮಾಡಿ"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾದ ವಿಜೆಟ್‌ಗಾಗಿ ಆ್ಯಪ್ ಐಕಾನ್"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲಾದ ವಿಜೆಟ್‌ಗಾಗಿ ಆ್ಯಪ್ ಐಕಾನ್"</string>
     <string name="edit_widget" msgid="9030848101135393954">"ವಿಜೆಟ್ ಅನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ವಿಜೆಟ್ ಅನ್ನು ಆಯ್ಕೆ ಮಾಡಿ"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ವಿಜೆಟ್ ಅನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ಆಯ್ಕೆಮಾಡಿದ ವಿಜೆಟ್ ಅನ್ನು ಇರಿಸಿ"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ಬಳಕೆದಾರರನ್ನು ಬದಲಿಸಿ"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ಪುಲ್‌ಡೌನ್ ಮೆನು"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ಈ ಸೆಶನ್‌ನಲ್ಲಿನ ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"ಈಗ ಪ್ರಾರಂಭಿಸಿ"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"ಯಾವುದೇ ಅಧಿಸೂಚನೆಗಳಿಲ್ಲ"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"ಯಾವುದೇ ಹೊಸ ಅಧಿಸೂಚನೆಗಳಿಲ್ಲ"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"ಅಡಾಪ್ಟಿವ್ ನೋಟಿಫಿಕೇಶನ್ ಆನ್ ಇದೆ"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"ಅಲ್ಪಾವಧಿಯಲ್ಲಿ ಹಲವು ನೋಟಿಫಿಕೇಶನ್ ಬಂದಾಗ 2 ನಿಮಿಷದವರೆಗೆ ಸಾಧನವು ಈಗ ವಾಲ್ಯೂಮ್ ಕಡಿಮೆ ಮಾಡುತ್ತದೆ ಹಾಗೂ ಸ್ಕ್ರೀನ್ ಮೇಲಿನ ಪಾಪ್-ಅಪ್ ಕಡಿಮೆ ಮಾಡುತ್ತದೆ."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ಆಫ್ ಮಾಡಿ"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ಹಳೆಯ ಅಧಿಸೂಚನೆಗಳನ್ನು ನೋಡಲು ಅನ್‌ಲಾಕ್ ಮಾಡಿ"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ಈ ಸಾಧನವನ್ನು ನಿಮ್ಮ ಪೋಷಕರು ನಿರ್ವಹಿಸುತ್ತಿದ್ದಾರೆ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಸಾಧನದ ಮಾಲೀಕತ್ವವನ್ನು ಹೊಂದಿದೆ ಮತ್ತು ಅದು ನೆಟ್‌ವರ್ಕ್ ಟ್ರಾಫಿಕ್‌ನ ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಬಹುದು"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ಇನ್ನಷ್ಟು ಮಾಹಿತಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ಅಲಾರಾಂ ಸೆಟ್ ಆಗಿಲ್ಲ"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ನಮೂದಿಸಿ"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್‌‌ ಅನ್ನು ಸ್ಪರ್ಶಿಸಿ. ಇದು ಫೋನ್‌ನ ಬದಿಯಲ್ಲಿರುವ ಚಿಕ್ಕ ಬಟನ್ ಆಗಿದೆ"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"ದೃಢೀಕರಿಸಿ"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"ಸಾಧನವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನಿಂದ ಬಳಕೆಯಲ್ಲಿದೆ (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"ಇತ್ತೀಚೆಗೆ <xliff:g id="APP_NAME">%1$s</xliff:g> ಇದನ್ನು ಬಳಸಿದೆ (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"ಸಿಸ್ಟಂ"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ಸಿಸ್ಟಂ ನಿಯಂತ್ರಣಗಳು"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"ಸಿಸ್ಟಂ ಆ್ಯಪ್‌ಗಳು"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ಮಲ್ಟಿಟಾಸ್ಕಿಂಗ್"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"ಇತ್ತೀಚಿನ ಆ್ಯಪ್‌ಗಳು"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"ಇನ್‌ಪುಟ್"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ಆ್ಯಪ್ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ಹಿಂತಿರುಗಿ"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ಹಿಂತಿರುಗಲು, ಟಚ್‌ಪ್ಯಾಡ್‌ನಲ್ಲಿ ಎಲ್ಲಿಯಾದರೂ ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಎಡ ಅಥವಾ ಬಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ಮೂರು ಬೆರಳುಗಳು ಬಲಕ್ಕೆ ಮತ್ತು ಎಡಕ್ಕೆ ಚಲಿಸುತ್ತಿರುವುದನ್ನು ತೋರಿಸುತ್ತಿರುವ ಟಚ್‌ಪ್ಯಾಡ್"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"ಬ್ಯಾಕ್ ಗೆಸ್ಚರ್‌ಗೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯನಿಮೇಶನ್ ಅನ್ನು ತೋರಿಸುತ್ತಿರುವ ಸಾಧನದ ಸ್ಕ್ರೀನ್"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ಕೀಬೋರ್ಡ್ ಬ್ಯಾಕ್‌ಲೈಟ್"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ರಲ್ಲಿ %1$d ಮಟ್ಟ"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ಮನೆ ನಿಯಂತ್ರಣಗಳು"</string>
diff --git a/packages/SystemUI/res/values-kn/tiles_states_strings.xml b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
index afc7c1a..c7cb2b1 100644
--- a/packages/SystemUI/res/values-kn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
@@ -188,7 +188,7 @@
   </string-array>
   <string-array name="tile_states_hearing_devices">
     <item msgid="1235334096484287173">"ಲಭ್ಯವಿಲ್ಲ"</item>
-    <item msgid="3079622119444911877">"ಆಫ್ ಆಗಿದೆ"</item>
+    <item msgid="3079622119444911877">"ಆಫ್"</item>
     <item msgid="3028994095749238254">"ಆನ್"</item>
   </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 4c26ed2..89acb42 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>에서 이 스크린샷을 감지했습니다."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> 및 기타 공개 앱에서 이 스크린샷을 감지했습니다."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"메모에 추가"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"링크 포함"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"화면 녹화"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"화면 녹화 처리 중"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"화면 녹화 세션에 관한 지속적인 알림"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; 녹화가 중단됩니다."</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"화면 공유 중"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; 공유가 중단됩니다."</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"화면 전송 중"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; 전송이 중단됩니다."</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"얼굴 인식으로 잠금 해제되었습니다. 계속하려면 누르세요."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"얼굴이 인식되었습니다. 계속하려면 누르세요."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"얼굴이 인식되었습니다. 계속하려면 아이콘을 누르세요."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"얼굴 인식으로 잠금 해제되었습니다. 계속하려면 탭하세요."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"인증됨"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"인증 취소"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"옵션 더보기"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share, 내 기기 찾기 등의 기능에서 블루투스를 사용합니다."</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"블루투스가 내일 아침에 켜집니다."</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"오디오 공유"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"오디오 공유 중"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"더 많은 위젯 추가"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"위젯을 맞춤설정하려면 길게 누르기"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"위젯 맞춤설정"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"위젯을 맞춤설정하려면 잠금 해제하세요."</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"사용 중지된 위젯의 앱 아이콘"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"설치 중인 위젯의 앱 아이콘"</string>
     <string name="edit_widget" msgid="9030848101135393954">"위젯 수정"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"위젯 선택"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"위젯 삭제"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"선택한 위젯 배치"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"사용자 전환"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"풀다운 메뉴"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"이 세션에 있는 모든 앱과 데이터가 삭제됩니다."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"시작하기"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"알림 없음"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"새로운 알림 없음"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"적응형 알림 사용 중"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"이제 짧은 시간 동안 많은 알림을 받으면 최대 2분 동안 기기의 볼륨을 낮추고 화면의 팝업을 줄입니다."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"사용 중지"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"잠금 해제하여 이전 알림 보기"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"부모님이 관리하는 기기입니다."</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"내 조직에서 이 기기를 소유하며 네트워크 트래픽을 모니터링할 수 있습니다."</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"탭하여 자세한 정보를 확인하세요."</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"설정된 알람 없음"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"화면 잠금 입력"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"지문 센서를 터치하세요. 휴대전화 측면에 있는 더 짧은 버튼입니다"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"지문 센서"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"인증"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"기기 입력"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 사용 중(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"최근 <xliff:g id="APP_NAME">%1$s</xliff:g>에서 사용됨(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"시스템"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"시스템 컨트롤"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"시스템 앱"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"멀티태스킹"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"최근 앱"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"화면 분할"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"입력"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"앱 바로가기"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"접근성"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"뒤로"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"돌아가려면 세 손가락을 사용해 터치패드의 아무 곳이나 왼쪽 또는 오른쪽으로 스와이프합니다."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"터치패드에서 세 손가락을 좌우로 움직이는 모습"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"뒤로 동작 애니메이션을 보여 주는 기기 화면"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"키보드 백라이트"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d단계 중 %1$d단계"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"홈 컨트롤"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index ae91a7c..db6816a 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ушул скриншотту аныктады."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> жана ачылып турган башка колдонмолор ушул скриншотту аныктады."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Кыска жазууга кошуу"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Шилтеме кошуу"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Экрандан видео жаздырып алуу"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Экрандан жаздырылып алынган видео иштетилүүдө"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды жаздыруу сеансы боюнча учурдагы билдирме"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосун жаздырууну токтотосуз"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Экран бөлүшүлүүдө"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосун бөлүшүүнү токтотосуз"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Тышкы экранга чыгарылууда"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосун тышкы экранга чыгарууну токтотосуз"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -153,7 +159,7 @@
     <string name="issuerecord_save_title" msgid="4161043023696751591">"Жаздырылган маселе сакталды"</string>
     <string name="issuerecord_save_text" msgid="1205985304551521495">"Көрүү үчүн таптаңыз"</string>
     <string name="issuerecord_save_error" msgid="6913040083446722726">"Жаздырылган маселе сакталган жок"</string>
-    <string name="issuerecord_start_error" msgid="3402782952722871190">"Маселени жаздыруу башталбай койду"</string>
+    <string name="issuerecord_start_error" msgid="3402782952722871190">"Башталбай койду"</string>
     <string name="immersive_cling_title" msgid="8372056499315585941">"Толук экран режимин көрүү"</string>
     <!-- no translation found for immersive_cling_description (2717426731830851921) -->
     <skip />
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Кулпуну жүзүңүз менен ачтыңыз. Улантуу үчүн басыңыз."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Жүз таанылды. Улантуу үчүн басыңыз."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Жүз таанылды. Улантуу үчүн кулпусун ачуу сүрөтчөсүн басыңыз."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Кулпусун жүзүңүз менен ачтыңыз. Улантуу үчүн таптап коюңуз."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аныктыгы текшерилди"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Аныктыгын текшерүүнү жокко чыгаруу"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Дагы параметрлер"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Bluetooth Тез бөлүшүү жана Түзмөгүм кайда? сыяктуу функцияларда колдонулат"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth эртең таңда күйөт"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Чогуу угуу"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Чогуу угулууда"</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>
@@ -382,15 +387,15 @@
     <string name="qs_record_issue_start" msgid="2979831312582567056">"Баштоо"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"Токтотуу"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Мүчүлүштүк тууралуу кабарлоо"</string>
-    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Түзмөгүңүздүн кайсы бөлүгүнө кедергиси тийди?"</string>
-    <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Маселенин түрүн тандоо"</string>
+    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Кандай маселеге кабылдыңыз?"</string>
+    <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Маселенин түрүн тандаңыз"</string>
     <string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Экрандан видео жаздырып алуу"</string>
     <string name="performance" msgid="6552785217174378320">"Иштин майнаптуулугу"</string>
     <string name="user_interface" msgid="3712869377953950887">"Колдонуучунун интерфейси"</string>
     <string name="thermal" msgid="6758074791325414831">"Жылуулук"</string>
     <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Бир кол режими"</string>
     <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Угуу аппараттары"</string>
-    <string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Жигердүү"</string>
+    <string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Иштеп жатат"</string>
     <string name="quick_settings_hearing_devices_disconnected" msgid="8907061223998176187">"Ажыратылды"</string>
     <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Угуу аппараттары"</string>
     <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Жаңы түзмөк кошуу"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Көбүрөөк виджеттерди кошуу"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Виджеттерди ыңгайлаштыруу үчүн кое бербей басып туруңуз"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Виджеттерди ыңгайлаштыруу"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Виджеттерди ыңгайлаштыруу үчүн кулпуну ачыңыз"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Өчүрүлгөн виджет үчүн колдонмонун сүрөтчөсү"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Виджет үчүн колдонмонун сүрөтчөсү орнотулууда"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Виджетти түзөтүү"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"виджет тандоо"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"виджетти алып салуу"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"тандалган виджетти жайгаштыруу"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Колдонуучуну которуу"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ылдый түшүүчү меню"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Бул сеанстагы бардык колдонмолор жана аларга байланыштуу нерселер өчүрүлөт."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Азыр баштоо"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Билдирме жок"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Жаңы билдирмелер жок"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Адаптивдүү билдирмелер күйүк"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Эгер кыска убакыттын ичинде билдирмелер көп келсе, үн көлөмү жана экрандагы калкыма терезелердин саны эки мүнөткө чейин азайтылат."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Өчүрүү"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Билдирмелерди көрүү үчүн кулпуну ачыңыз"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Бул түзмөктү ата-энең башкарат"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Бул түзмөк уюмуңузга таандык. Уюмуңуз тармактын трафигин көзөмөлдөй алат"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Кеңири маалымат алуу үчүн таптап коюңуз"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ойготкуч коюлган жок"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"экран кулпусун киргизүү"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Манжа изинин сенсорун басыңыз. Ал телефондун капталындагы кыска баскыч"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Манжа изинин сенсору"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"аныктыгын текшерүү"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"түзмөккө кирүү"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосунда иштеп жатат (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Акыркы жолу <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) колдонмосунда иштетилди"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Система"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Системанын башкаруу элементтери"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системанын колдонмолору"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Бир нече тапшырма аткаруу"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Акыркы колдонмолор"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Экранды бөлүү"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Киргизүү"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Колдонмодогу кыска жолдор"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Атайын мүмкүнчүлүктөр"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Артка кайтуу"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Кайтуу үчүн сенсордук тактанын каалаган жерин үч манжаңыз менен солго же оңго сүрүңүз."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Үч манжанын оңго жана солго жылып жатканы көрсөтүлгөн сенсордук такта"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Артка жаңсоосунун анимациясы көрсөтүлгөн түзмөктүн экраны"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Баскычтоптун жарыгы"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ичинен %1$d-деңгээл"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Үйдөгү түзмөктөрдү тескөө"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 30f8a65..7652e4b 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ກວດພົບຮູບໜ້າຈໍນີ້."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ແລະ ແອັບອື່ນໆທີ່ເປີດຢູ່ກວດພົບຮູບໜ້າຈໍນີ້."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ເພີ່ມໃສ່ບັນທຶກ"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"ຮວມລິ້ງ"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"ໂປຣແກຣມບັນທຶກໜ້າຈໍ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ກຳລັງປະມວນຜົນການບັນທຶກໜ້າຈໍ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ການແຈ້ງເຕືອນສຳລັບເຊດຊັນການບັນທຶກໜ້າຈໍໃດໜຶ່ງ"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"ທ່ານຈະຢຸດການບັນທຶກ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ກຳລັງແບ່ງປັນໜ້າຈໍ"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"ທ່ານຈະຢຸດການແບ່ງປັນ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"ກຳລັງສົ່ງສັນຍານໜ້າຈໍ"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"ທ່ານຈະຢຸດການສົ່ງສັນຍານ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ປົດລັອກດ້ວຍໜ້າແລ້ວ. ກົດເພື່ອສືບຕໍ່."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດເພື່ອສືບຕໍ່."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດໄອຄອນປົດລັອກເພື່ອສືບຕໍ່."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"ປົດລັອກດ້ວຍໃບໜ້າແລ້ວ. ແຕະເພື່ອສືບຕໍ່."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ຮັບຮອງຄວາມຖືກຕ້ອງແລ້ວ"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ຍົກເລີກການພິສູດຢືນຢັນ"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ຕົວເລືອກເພີ່ມເຕີມ"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ຄຸນສົມບັດຕ່າງໆໃຊ້ Bluetooth ເຊັ່ນ: ການແຊຣ໌ດ່ວນ ແລະ ຊອກຫາອຸປະກອນຂອງຂ້ອຍ"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ຈະເປີດມື້ອື່ນເຊົ້າ"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ແບ່ງປັນສຽງ"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"ກຳລັງແບ່ງປັນສຽງ"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ເພີ່ມວິດເຈັດເພີ່ມເຕີມ"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ກົດຄ້າງໄວ້ເພື່ອປັບແຕ່ງວິດເຈັດ"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ປັບແຕ່ງວິດເຈັດ"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ປົດລັອກເພື່ອປັບແຕ່ງວິດເຈັດ"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ໄອຄອນແອັບສຳລັບວິດເຈັດທີ່ຖືກປິດການນຳໃຊ້"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ກຳລັງຕິດຕັ້ງໄອຄອນແອັບສຳລັບວິດເຈັດ"</string>
     <string name="edit_widget" msgid="9030848101135393954">"ແກ້ໄຂວິດເຈັດ"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ເລືອກວິດເຈັດ"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ລຶບວິດເຈັດອອກ"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ວາງວິດເຈັດທີ່ເລືອກ"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ສະຫຼັບຜູ້ໃຊ້"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ເມນູແບບດຶງລົງ"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ແອັບຯ​ແລະ​ຂໍ້​ມູນ​ທັງ​ໝົດ​ໃນ​ເຊດ​ຊັນ​ນີ້​ຈະ​ຖືກ​ລຶບ​ອອກ."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"ເລີ່ມດຽວນີ້"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"ບໍ່ມີການແຈ້ງເຕືອນ"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"ບໍ່ມີການແຈ້ງເຕືອນໃໝ່"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"ການແຈ້ງເຕືອນແບບປັບອັດຕະໂນມັດເປີດຢູ່"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"ຈາກນີ້ໄປອຸປະກອນຂອງທ່ານຈະຫຼຸດລະດັບສຽງ ແລະ ຈຳນວນປັອບອັບຢູ່ໜ້າຈໍເປັນເວລາສູງສຸດ 2 ນາທີເມື່ອທ່ານໄດ້ຮັບການແຈ້ງເຕືອນຈຳນວນຫຼາຍໃນໄລຍະເວລາສັ້ນໆ."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ປິດ"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ປົດລັອກເພື່ອເບິ່ງການແຈ້ງເຕືອນເກົ່າ"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ອຸປະກອນນີ້ແມ່ນຈັດການໂດຍພໍ່ແມ່ຂອງທ່ານ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ອົງການຂອງທ່ານເປັນເຈົ້າຂອງອຸປະກອນນີ້ ແລະ ສາມາດຕິດຕາມທຣາບຟິກເຄືອຂ່າຍໄດ້"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ແຕະເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ບໍ່ໄດ້ຕັ້ງໂມງປຸກ"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"ໃສ່ຂໍ້ມູນການລັອກໜ້າຈໍ"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ແຕະເຊັນເຊີລາຍນິ້ວມື. ໂດຍເປັນປຸ່ມທີ່ສັ້ນກວ່າເຊິ່ງຢູ່ທາງຂ້າງໂທລະສັບ"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ເຊັນ​ເຊີລາຍນິ້ວ​ມື"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"ພິສູດຢືນຢັນ"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"ເຂົ້າອຸປະກອນ"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"ໃຊ້ຢູ່ໂດຍ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"ໃຊ້ຫຼ້າສຸດໂດຍ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"ລະບົບ"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ການຄວບຄຸມລະບົບ"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"ແອັບລະບົບ"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ການເຮັດຫຼາຍໜ້າວຽກພ້ອມກັນ"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"ແອັບຫຼ້າສຸດ"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"ແບ່ງໜ້າຈໍ"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"ອິນພຸດ"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ທາງລັດແອັບ"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ການຊ່ວຍເຂົ້າເຖິງ"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ກັບຄືນ"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ເພື່ອກັບຄືນ, ໃຫ້ໃຊ້ 3 ນິ້ວປັດຊ້າຍ ຫຼື ຂວາບ່ອນໃດກໍໄດ້ເທິງແຜ່ນສໍາຜັດ."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ແຜ່ນສໍາຜັດສະແດງພາບ 3 ນິ້ວເລື່ອນໄປທາງຂວາ ແລະ ຊ້າຍ"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"ໜ້າຈໍອຸປະກອນສະແດງພາບເຄື່ອນໄຫວຂອງທ່າທາງກັບຄືນ"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ໄຟປຸ່ມແປ້ນພິມ"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"ລະດັບທີ %1$d ຈາກ %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ການຄວບຄຸມເຮືອນ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 4fffb3d..2787a84 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"„<xliff:g id="APPNAME">%1$s</xliff:g>“ aptiko šią ekrano kopiją."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"„<xliff:g id="APPNAME">%1$s</xliff:g>“ ir kitos atidarytos programos aptiko šią ekrano kopiją."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Pridėti prie užrašo"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Įtraukti nuorodą"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Ekrano vaizdo įrašytuvas"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Apdorojam. ekrano vaizdo įraš."</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Šiuo metu rodomas ekrano įrašymo sesijos pranešimas"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Programos (&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;) turinio įrašymas bus sustabdytas."</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Bendrinamas ekranas"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Programos (&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;) turinio bendrinimas bus sustabdytas."</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Perduodamas ekranas"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Programos (&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;) turinio perdavimas bus sustabdytas."</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Atrakinta pagal veidą. Paspauskite, jei norite tęsti."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Veidas atpažintas. Paspauskite, jei norite tęsti."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Veidas atpažintas. Tęskite paspaudę atrakinimo piktogramą."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Atrakinta pagal veidą. Palieskite ir tęskite."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikuota"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Atšaukti autentifikavimą"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Daugiau parinkčių"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Tokioms funkcijoms kaip „Spartusis bendrinimas“ ir „Rasti įrenginį“ naudojamas „Bluetooth“ ryšys"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"„Bluetooth“ ryšys bus įjungtas rytoj ryte"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Bendrinti garsą"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Bendrinamas garsas"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akumuliatorius: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Garsas"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Virtualiosios realybės įrenginys"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Pridėkite daugiau valdiklių"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Ilgai paspauskite, kad tinkintumėte valdiklius"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tinkinti valdiklius"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Atrakinkite, kad galėtumėte tinkinti valdiklius"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Išjungto valdiklio programos piktograma"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Įdiegiamo valdiklio programos piktograma"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Redaguoti valdiklį"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"pasirinkite valdiklį"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"pašalinti valdiklį"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"padėti pasirinktą valdiklį"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Perjungti naudotoją"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"išplečiamasis meniu"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bus ištrintos visos šios sesijos programos ir duomenys."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Pradėti dabar"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nėra įspėjimų"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Naujų pranešimų nėra"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptyvieji pranešimai įjungti"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Dabar, gaunant daug pranešimų per trumpą laiką, sumažinamas įrenginio garsumas ir iššokančiųjų langų skaičius ekrane iki dviejų minučių."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Išjungti"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Atrakinę matykite senesnius pranešimus"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Šį įrenginį tvarko vienas iš tavo tėvų"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Šis įrenginys priklauso jūsų organizacijai ir ji gali stebėti tinklo srautą"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Palieskite, kad sužinotumėte daugiau informacijos"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenustatyta signalų"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"įvesti ekrano užraktą"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Palieskite piršto antspaudo jutiklį. Tai yra trumpesnis mygtukas telefono šone"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Kontrolinio kodo jutiklis"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"nustatytumėte tapatybę"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"pasiektumėte įrenginį"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Naudoja <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Neseniai naudojo „<xliff:g id="APP_NAME">%1$s</xliff:g>“ (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistemos valdikliai"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistemos programos"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Kelių užduočių atlikimas"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Naujausios programos"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Išskaidyto ekrano režimas"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Įvestis"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Programos šaukiniai"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pritaikomumas"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Grįžti"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Jei norite grįžti, trimis pirštais perbraukite kairėn arba dešinėn bet kurioje jutiklinės dalies vietoje."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Jutiklinė dalis, kurioje rodomi trys dešinėn ir kairėn judantys pirštai"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Įrenginio ekranas, kuriame rodoma grįžimo gesto animacija"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatūros foninis apšvietimas"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d lygis iš %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Namų sistemos valdymas"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 28b15d0..76d943f 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> konstatēja, ka tika veikts ekrānuzņēmums."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> un citas atvērtas lietotnes konstatēja, ka tika veikts ekrānuzņēmums."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Pievienot piezīmei"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Iekļaut saiti"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Ekrāna ierakstītājs"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekrāna ieraksta apstrāde"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Aktīvs paziņojums par ekrāna ierakstīšanas sesiju"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Tiks pārtraukta lietotnes &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; satura ierakstīšana"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Notiek ekrāna kopīgošana"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Tiks pārtraukta lietotnes &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; satura kopīgošana"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Notiek ekrāna apraide"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Tiks pārtraukta lietotnes &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; satura apraide"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ierīce atbloķēta ar seju. Nospiediet, lai turpinātu."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Seja atpazīta. Nospiediet, lai turpinātu."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Seja atpazīta. Lai turpinātu, nospiediet atbloķēšanas ikonu."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Ierīce atbloķēta pēc sejas. Pieskarieties, lai turpinātu."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikācija veikta"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Atcelt autentificēšanu"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Citas opcijas"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Tādas funkcijas kā “Ātrā kopīgošana” un “Atrast ierīci” izmanto Bluetooth savienojumu"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth savienojums tiks ieslēgts rīt no rīta"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Kopīgot audio"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Notiek audio kopīgošana…"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Akumulators: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Austiņas"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Pievienot citus logrīkus"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Nospiediet un turiet, lai pielāgotu logrīkus."</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Pielāgot logrīkus"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Atbloķējiet, lai pielāgotu logrīkus"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Lietotnes ikona atspējotam logrīkam"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Tiek instalēta lietotnes ikona logrīkam."</string>
     <string name="edit_widget" msgid="9030848101135393954">"Rediģēt logrīku"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"atlasīt logrīku"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"noņemt logrīku"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"novietot atlasīto logrīku"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Mainīt lietotāju"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"novelkamā izvēlne"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tiks dzēstas visas šīs sesijas lietotnes un dati."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Sākt tūlīt"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nav paziņojumu"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Nav jaunu paziņojumu"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptīvie paziņojumi ieslēgti"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Jūsu ierīce tagad līdz pat 2 minūtēm samazina skaļuma līmeni un ierobežo uznirstošo elementu skaitu, kad īsā laika posmā saņemat daudzu paziņojumu."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Izslēgt"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Atbloķējiet vecāku paziņojumu skatīšanai"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Šo ierīci pārvalda viens no jūsu vecākiem."</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Šī ierīce pieder jūsu organizācijai, un jūsu organizācija var uzraudzīt tīkla datplūsmu."</string>
@@ -784,7 +799,7 @@
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Nav atrasti"</string>
     <string name="keyboard_shortcut_search_category_system" msgid="1151182120757052669">"Sistēma"</string>
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Ievade"</string>
-    <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Atvērtās"</string>
+    <string name="keyboard_shortcut_search_category_open_apps" msgid="1450959949739257562">"Atvērtās lietotnes"</string>
     <string name="keyboard_shortcut_search_category_current_app" msgid="2011953559133734491">"Pašreizējā"</string>
     <string name="keyboard_shortcut_a11y_show_search_results" msgid="2865241062981833705">"Tiek rādīti meklēšanas rezultāti"</string>
     <string name="keyboard_shortcut_a11y_filter_system" msgid="7744143131119370483">"Tiek rādīti sistēmas īsinājumtaustiņi"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Pieskarieties, lai iegūtu plašāku informāciju."</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nav iestatīts signāls"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"ievadīt ekrāna bloķēšanas informāciju"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Pieskarieties pirksta nospieduma sensoram. Tā ir īsākā poga tālruņa malā."</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Pirksta nospieduma sensors"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"veiktu autentificēšanu"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"izmantotu ierīci"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"To izmanto lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nesen to izmantoja lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistēma"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistēmas vadīklas"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistēmas lietotnes"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Vairākuzdevumu režīms"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Pēdējās izmantotās lietotnes"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Ekrāna sadalīšana"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Ievade"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Lietotņu saīsnes"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Pieejamība"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Atpakaļ"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Lai pārietu atpakaļ, ar trim pirkstiem velciet pa kreisi vai pa labi jebkurā vietā uz skārienpaliktņa"</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Attēls ar skārienpaliktni, uz kura trīs pirksti kustas pa labi un pa kreisi"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Ierīces ekrāns, kurā redzama animācija ar žestu pāriešanai atpakaļ"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Tastatūras fona apgaismojums"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Līmenis numur %1$d, kopā ir %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Mājas kontrolierīces"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index bf71f8e..2d27181 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ја откри оваа слика од екранот."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> и други отворени апликации ја открија оваа слика од екранот."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Додај во белешка"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Опфати линк"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Снимач на екран"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Се обработува снимка од екран"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Тековно известување за сесија за снимање на екранот"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Ќе го сопрете снимањето на &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Се споделува екранот"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Ќе го сопрете споделувањето на &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Се емитува екранот"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Ќе го сопрете емитувањето на &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Отклучено со лик. Притиснете за да продолжите."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лицето е препознаено. Притиснете за да продолжите."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицето е препознаено. Притиснете ја иконата за отклучување за да продолжите."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Отклучено со лик. Допрете за да продолжите."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Проверена"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Откажување автентикација"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Повеќе опции"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Функциите како „Брзо споделување“ и „Најди го мојот уред“ користат Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ќе се вклучи утре наутро"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Споделувај аудио"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Се споделува аудио"</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>
@@ -393,7 +398,7 @@
     <string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Активно"</string>
     <string name="quick_settings_hearing_devices_disconnected" msgid="8907061223998176187">"Не е поврзано"</string>
     <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Слушни апарати"</string>
-    <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Спари нов уред"</string>
+    <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Спарете нов уред"</string>
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Кликнете за да спарите нов уред"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Не можеше да се ажурира зададената вредност"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Зададени вредности"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Додајте повеќе виџети"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Притиснете долго за да ги приспособите виџетите"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Приспособете ги виџетите"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Отклучете за да ги приспособите виџетите"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Икона за апликација за оневозможен виџет"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Икона за апликација за виџет што се инсталира"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Изменување виџети"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"изберете виџет"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"отстранете го виџетот"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"поставете го избраниот виџет"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Промени го корисникот"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"паѓачко мени"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Сите апликации и податоци во сесијава ќе се избришат."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Започни сега"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Нема известувања"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Нема нови известувања"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Адаптивни известув.: вклучено"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Уредот сега ја намалува јачината на звукот и ги намалува скокачките прозорци на екранот до 2 мин. кога добивате многу известувања за кратко време."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Исклучи"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Отклучете за да ги видите старите известувања"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Родителот управува со уредов"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организацијата е сопственик на уредов и може да го следи мрежниот сообраќај"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Допрете за повеќе информации"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Не е поставен аларм"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"внесете PIN/шема/лозинка"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Допрете го сензорот за отпечатоци. Тоа е пократкото копче отстрана на телефонот"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сензор за отпечатоци"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"автентицирате"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"внесете уред"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Се користи од <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Неодамна користено од <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Систем"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Системски контроли"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системски апликации"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Мултитаскинг"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Неодамнешни апликации"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Поделен екран"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Внесување"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Кратенки за апликации"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Пристапност"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"За да се вратите назад, повлечете налево или надесно со три прста каде било на допирната подлога."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Допирната подлога покажува три прста што се движат десно и лево"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Екранот на уредот покажува анимација за движење назад"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Осветлување на тастатура"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Ниво %1$d од %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Контроли за домот"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 2031af0..3c99184 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ഈ സ്ക്രീൻഷോട്ട് തിരിച്ചറിഞ്ഞു."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> എന്ന ആപ്പും തുറന്നിരിക്കുന്ന മറ്റ് ആപ്പും ഈ സ്ക്രീൻഷോട്ട് തിരിച്ചറിഞ്ഞു."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"കുറിപ്പിലേക്ക് ചേർക്കുക"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"ലിങ്ക് ഉൾപ്പെടുത്തുക"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"സ്ക്രീൻ റെക്കോർഡർ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"സ്ക്രീൻ റെക്കോർഡിംഗ് പ്രോസസുചെയ്യുന്നു"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ഒരു സ്ക്രീൻ റെക്കോർഡിംഗ് സെഷനായി നിലവിലുള്ള അറിയിപ്പ്"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; റെക്കോർഡ് ചെയ്യുന്നത് നിങ്ങൾ അവസാനിപ്പിക്കും"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"സ്‌ക്രീൻ പങ്കിടുന്നു"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; പങ്കിടുന്നത് നിങ്ങൾ അവസാനിപ്പിക്കും"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"സ്‌ക്രീൻ കാസ്‌റ്റ് ചെയ്യുന്നു"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; കാസ്റ്റ് ചെയ്യുന്നത് നിങ്ങൾ അവസാനിപ്പിക്കും"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"മുഖം ഉപയോഗിച്ച് അൺലോക്ക് ചെയ്‌തു. തുടരാൻ അമർത്തുക."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"മുഖം തിരിച്ചറിഞ്ഞു. തുടരാൻ അമർത്തുക."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"മുഖം തിരിച്ചറിഞ്ഞു. തുടരാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"മുഖം വഴി അൺലോക്കുചെയ്തു. തുടരാൻ ടാപ്പ് ചെയ്യുക."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"പരിശോധിച്ചുറപ്പിച്ചു"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"പരിശോധിച്ചുറപ്പിക്കൽ റദ്ദാക്കുക"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"കൂടുതൽ ഓപ്‌ഷനുകൾ"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ക്വിക്ക് ഷെയർ, Find My Device പോലുള്ള ഫീച്ചറുകൾ Bluetooth ഉപയോഗിക്കുന്നു"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth നാളെ രാവിലെ ഓണാകും"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ഓഡിയോ പങ്കിടുക"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"ഓഡിയോ പങ്കിടുന്നു"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"കൂടുതൽ വിജറ്റുകൾ ചേർക്കുക"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"വിജറ്റുകൾ ഇഷ്ടാനുസൃതമാക്കാൻ ദീർഘനേരം അമർത്തുക"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"വിജറ്റുകൾ ഇഷ്ടാനുസൃതമാക്കുക"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"വിജറ്റുകൾ ഇഷ്ടാനുസൃതമാക്കാൻ അൺലോക്ക് ചെയ്യുക"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"പ്രവർത്തനരഹിതമാക്കിയ വിജറ്റിനുള്ള ആപ്പ് ഐക്കൺ"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"വിജറ്റിനുള്ള ആപ്പ് ഐക്കൺ ഇൻസ്റ്റാൾ ചെയ്തു"</string>
     <string name="edit_widget" msgid="9030848101135393954">"വിജറ്റ് എഡിറ്റ് ചെയ്യുക"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"വിജറ്റ് തിരഞ്ഞെടുക്കുക"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"വിജറ്റ് നീക്കം ചെയ്യുക"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"തിരഞ്ഞെടുത്ത വിജറ്റ് നൽകുക"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ഉപയോക്താവ് മാറുക"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"പുൾഡൗൺ മെനു"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ഈ സെഷനിലെ എല്ലാ ആപ്പുകളും ഡാറ്റയും ഇല്ലാതാക്കും."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"ഇപ്പോൾ ആരംഭിക്കുക"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"അറിയിപ്പുകൾ ഒന്നുമില്ല"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"പുതിയ അറിയിപ്പുകളൊന്നുമില്ല"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"അഡാപ്‌റ്റീവ് അറിയിപ്പുകൾ ഓണാണ്"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"ചെറിയ കാലയളവിനുള്ളിൽ നിങ്ങൾക്ക് നിരവധി അറിയിപ്പുകൾ ലഭിക്കുമ്പോൾ ഉപകരണം ഇപ്പോൾ വോളിയം കുറയ്ക്കുകയും സ്ക്രീനിൽ പോപ്പ് അപ്പുകൾ രണ്ട് മിനിറ്റ് വരെ ചുരുക്കുകയും ചെയ്യുന്നു."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ഓഫാക്കുക"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"പഴയ അറിയിപ്പുകൾ കാണാൻ അൺലോക്ക് ചെയ്യുക"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ഈ ഉപകരണം മാനേജ് ചെയ്യുന്നത് നിങ്ങളുടെ രക്ഷിതാവാണ്"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ഈ ഉപകരണം നിങ്ങളുടെ സ്ഥാപനത്തിന്റെ ഉടമസ്ഥതയിലായതിനാൽ നെറ്റ്‌വർക്ക് ട്രാഫിക്ക് നിരീക്ഷിച്ചേക്കാം"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"കൂടുതൽ വിവരങ്ങൾക്ക് ടാപ്പ് ചെയ്യുക"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"അലാറം സജ്ജീകരിച്ചിട്ടില്ല"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"സ്‌ക്രീൻ ലോക്ക് നൽകുക"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ഫിംഗർപ്രിന്റ് സെൻസർ സ്‌പർശിക്കുക. ഇത് ഫോണിന്റെ വശത്തുള്ള ചെറിയ ബട്ടണാണ്"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ഫിംഗർപ്രിന്റ് സെൻസർ"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"പരിശോധിച്ചുറപ്പിക്കുക"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"ഉപകരണം നൽകുക"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ഉപയോഗിക്കുന്നു"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) അടുത്തിടെ ഉപയോഗിച്ചു"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"സിസ്റ്റം"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"സിസ്‌റ്റം നിയന്ത്രണങ്ങൾ"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"സിസ്‌റ്റം ആപ്പുകൾ"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"മൾട്ടിടാസ്‌കിംഗ്"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"അടുത്തിടെ ഉപയോഗിച്ച ആപ്പുകൾ"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"സ്‌ക്രീൻ വിഭജന മോഡ്"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"ഇൻപുട്ട്"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ആപ്പ് കുറുക്കുവഴികൾ"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ഉപയോഗസഹായി"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"മടങ്ങുക"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"തിരികെ പോകാൻ, ടച്ച്പാഡിൽ എവിടെയെങ്കിലും മൂന്ന് വിരലുകൾ ഉപയോഗിച്ച് ഇടത്തേക്കോ വലത്തേക്കോ സ്വൈപ്പ് ചെയ്യുക."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"വലത്തേക്കും ഇടത്തേക്കും ചലിക്കുന്ന മൂന്ന് വിരലുകൾ കാണിക്കുന്ന ടച്ച്പാഡ്"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"ബാക്ക് ജെസ്ച്ചറിനായി ആനിമേഷൻ കാണിക്കുന്ന ഉപകരണ സ്‌ക്രീൻ"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"കീബോഡ് ബാക്ക്‌ലൈറ്റ്"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d-ൽ %1$d-ാമത്തെ ലെവൽ"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ഹോം കൺട്രോളുകൾ"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 556d205..2f4adf6 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> энэ дэлгэцийн агшныг илрүүлсэн."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> болон бусад нээлттэй апп энэ дэлгэцийн агшныг илрүүлсэн."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Тэмдэглэлд нэмэх"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Холбоосыг оруулах"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Дэлгэцийн үйлдэл бичигч"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Дэлгэц бичлэг боловсруулж байна"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Дэлгэц бичих горимын үргэлжилж буй мэдэгдэл"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Та &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-г бичихээ болино"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Дэлгэцийг хуваалцаж байна"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Та &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-г хуваалцахаа болино"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Дэлгэцийг дамжуулж байна"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Та &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-г дамжуулахаа болино"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Царайгаар түгжээг тайлсан. Үргэлжлүүлэхийн тулд дарна уу."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Царайг таньсан. Үргэлжлүүлэхийн тулд дарна уу."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Царайг таньсан. Үргэлжлүүлэх бол түгжээг тайлах дүрсийг дар."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Царайгаар түгжээг тайлсан. Үргэлжлүүлэхийн тулд товшино уу."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Баталгаажуулагдсан"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Баталгаажуулалтыг цуцлах"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Бусад сонголт"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Түргэн хуваалцах, Миний төхөөрөмжийг олох зэрэг онцлогууд Bluetooth-г ашигладаг"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth-г маргааш өглөө асаана"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Аудио хуваалцах"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Аудио хуваалцаж байна"</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>
@@ -378,7 +383,7 @@
     <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>
-    <string name="qs_record_issue_label" msgid="8166290137285529059">"Асуудлыг бичих"</string>
+    <string name="qs_record_issue_label" msgid="8166290137285529059">"Асуудлыг бүртгэх"</string>
     <string name="qs_record_issue_start" msgid="2979831312582567056">"Эхлүүлэх"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"Зогсоох"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Алдааны мэдээ"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Илүү олон виджет нэмэх"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Виджетүүдийг өөрчлөхийн тулд удаан дарна уу"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Виджетүүдийг өөрчлөх"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Виджетийг өөрчлөхийн тулд түгжээг тайлна уу"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Идэвхгүй болгосон виджетийн аппын дүрс тэмдэг"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Виджет суулгах явцын аппын дүрс тэмдэг"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Виджетийг засах"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"виджет сонгох"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"виджетийг хасах"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"сонгосон виджетийг байрлуулах"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Хэрэглэгчийг сэлгэх"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"эвхмэл цэс"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Энэ харилцан үйлдлийн бүх апп болон дата устах болно."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Одоо эхлүүлэх"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Мэдэгдэл байхгүй"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Шинэ мэдэгдэл алга"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Дасан зохицох мэдэгдэл ассан"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Таныг богино хугацаанд олон мэдэгдэл авахад таны төхөөрөмж одоо дууны түвшнийг багасгаж, дэлгэц дээрх попапыг хоёр хүртэлх минутын турш багасгана."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Унтраах"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Хуучин мэдэгдлийг харах бол түгжээг тайл"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Энэ төхөөрөмжийг таны эцэг эх удирддаг"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Танай байгууллага энэ төхөөрөмжийг эзэмшдэг бөгөөд сүлжээний ачааллыг хянаж болно"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Нэмэлт мэдээлэл авахын тулд товшино уу"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Сэрүүлэг тавиагүй"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"дэлгэцийн түгжээ оруулах"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Хурууны хээ мэдрэгчид хүрнэ үү. Энэ нь утасны хажуу талын арай богино товчлуур юм"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Хурууны хээ мэдрэгч"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"баталгаажуулах"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"төхөөрөмж оруулах"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ашиглаж байна"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Саяхан <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ашигласан"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Систем"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Системийн тохиргоо"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системийн аппууд"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Олон ажил зэрэг хийх"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Саяхны аппууд"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Дэлгэцийг хуваах"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Оролт"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Аппын товчлол"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Хандалт"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Буцах"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Буцаж очихын тулд мэдрэгч самбар дээр гурван хуруугаараа хүссэн газраа зүүн эсвэл баруун тийш шударна уу."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Гурван хуруу баруун болон зүүн тийш хөдөлж буйг харуулсан мэдрэгч самбар"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Буцах зангаанд зориулсан анимацийг харуулсан төхөөрөмжийн дэлгэц"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Гарын арын гэрэл"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d-с %1$d-р түвшин"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Гэрийн удирдлага"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index a009fe1..a5633a2 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ने हा स्क्रीनशॉट डिटेक्ट केला."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> आणि उघडलेल्या इतर अ‍ॅप्सनी हा स्क्रीनशॉट डिटेक्ट केला."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"टीप जोडा"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"लिंकचा समावेश करा"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"स्क्रीन रेकॉर्डर"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रेकॉर्डिंग प्रोसेस सुरू"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रेकॉर्ड सत्रासाठी सुरू असलेली सूचना"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"तुम्ही &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; रेकॉर्ड करणे बंद कराल"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"स्क्रीन शेअर करत आहे"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"तुम्ही &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; शेअर करणे बंद कराल"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"स्‍क्रीन कास्‍ट करत आहे"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"तुम्ही &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; कास्ट करणे बंद कराल"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"चेहऱ्याने अनलॉक केले आहे. पुढे सुरू ठेवण्यासाठी प्रेस करा."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"चेहरा ओळखला आहे. पुढे सुरू ठेवण्यासाठी प्रेस करा."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"चेहरा ओळखला आहे. पुढे सुरू ठेवण्यासाठी अनलॉक करा आयकन प्रेस करा."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"चेहऱ्याने अनलॉक केले आहे. सुरू ठेवण्यासाठी टॅप करा."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ऑथेंटिकेशन केलेले"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ऑथेंटिकेशन रद्द करा"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"अधिक पर्याय"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"क्विक शेअर आणि Find My Device यांसारखी वैशिष्‍ट्ये ब्लूटूथ वापरतात"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ब्लूटूथ उद्या सकाळी सुरू होईल"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ऑडिओ शेअर करा"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"ऑडिओ शेअर करत आहे"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"आणखी विजेट जोडा"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"विजेट कस्टमाइझ करण्यासाठी प्रेस करून ठेवा"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"विजेट कस्टमाइझ करा"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"विजेट कस्टमाइझ करण्यासाठी अनलॉक करा"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"बंद केलेल्या विजेटच्या अ‍ॅपचे आयकन"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"इंस्टॉल होत असलेल्या विजेटसाठी अ‍ॅपचा आयकन"</string>
     <string name="edit_widget" msgid="9030848101135393954">"विजेट संपादित करा"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"विजेट निवडा"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"विजेट काढून टाका"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"निवडलेले विजेट ठेवा"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"वापरकर्ता स्विच करा"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"पुलडाउन मेनू"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"या सत्रातील सर्व अ‍ॅप्स आणि डेटा हटवला जाईल."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"आता सुरू करा"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"सूचना नाहीत"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"नवीन सूचना नाहीत"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"अडॅप्टिव्ह नोटिफिकेशन सुरू आहे"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"कमी वेळेत खूप नोटिफिकेशन मिळल्यास डिव्हाइस आता कमाल २ मिनिटे व्हॉल्यूम, स्क्रीनवरील पॉप-अप कमी करते."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"बंद करा"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"जुन्या सूचना पाहण्यासाठी अनलॉक करा"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"हे डिव्हाइस तुमच्या पालकाने व्यवस्थापित केले आहे"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"तुमच्‍या संस्‍थेकडे या डिव्हाइसची मालकी आहे आणि ती नेटवर्क ट्रॅफिकचे परीक्षण करू शकते"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"अधिक माहितीसाठी टॅप करा"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"अलार्म सेट केला नाही"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"स्क्रीन लॉक एंटर करा"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"फिंगरप्रिंट सेन्सरला स्पर्श करा. हे फोनच्या बाजूला असलेले लहान बटण आहे"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"फिंगरप्रिंट सेन्सर"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"ऑथेंटिकेट करा"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"डिव्हाइस एंटर करा"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) द्वारे वापरले जात आहे"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"अलीकडे <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ने वापरले"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"सिस्टीम"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"सिस्‍टीमची नियंत्रणे"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"सिस्टीम अ‍ॅप्स"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"मल्टिटास्किंग"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"अलीकडील अ‍ॅप्स"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"स्प्लिट स्क्रीन"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"इनपुट"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"अ‍ॅप शॉर्टकट"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"अ‍ॅक्सेसिबिलिटी"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"मागे जा"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"मागे जाण्यासाठी, टचपॅडवर कुठेही तीन बोटांनी डावीकडे किंवा उजवीकडे स्‍वाइप करा."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"तीन बोट उजवीकडे आणि डावीकडे हलताना दाखवणारे टचपॅड"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"मागील जेश्चरसाठी अ‍ॅनिमेशन दाखवणारी डिव्हाइस स्क्रीन"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"कीबोर्ड बॅकलाइट"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d पैकी %1$d पातळी"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"होम कंट्रोल"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 59c4071..984fe3a 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -103,11 +103,12 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> telah mengesan tangkapan skrin ini."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> dan apl lain yang dibuka telah mengesan tangkapan skrin ini."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Tambahkan pada nota"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Sertakan pautan"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Perakam Skrin"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Memproses rakaman skrin"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pemberitahuan breterusan untuk sesi rakaman skrin"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Mulakan Rakaman?"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Apabila anda merakam, Android boleh mengakses apa-apa sahaja yang kelihatan pada skrin anda atau dimainkan pada peranti anda. Oleh hal yang demikian, berhati-hati apabila memasukkan kata laluan, butiran pembayaran, mesej, foto, audio dan video."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Semasa anda merakam, Android boleh mengakses apa-apa sahaja yang kelihatan pada skrin atau dimainkan pada peranti anda. Oleh hal yang demikian, berhati-hati apabila memasukkan kata laluan, butiran pembayaran, mesej, foto, audio dan video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Semasa anda merakam apl, Android boleh mengakses apa-apa sahaja yang ditunjukkan atau dimainkan pada apl itu. Oleh hal yang demikian, berhati-hati ketika memasukkan kata laluan, butiran pembayaran, mesej, foto, audio dan video."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Mulakan rakaman"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Rakam audio"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Anda akan berhenti merakam &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Berkongsi skrin"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Anda akan berhenti berkongsi &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Menghantar skrin"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Anda akan berhenti menghantar &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Dibuka kunci dengan wajah. Tekan untuk meneruskan."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Wajah dicam. Tekan untuk meneruskan."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Wajah dicam. Tekan ikon buka kunci untuk meneruskan."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Dibuka kunci dengan wajah. Ketik untuk meneruskan proses."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Disahkan"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Batalkan Pengesahan"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Lagi Pilihan"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Ciri seperti Quick Share dan Find My Device menggunakan Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth akan dihidupkan esok pagi"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Kongsi audio"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Perkongsian audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> bateri"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Set Kepala"</string>
@@ -378,11 +383,11 @@
     <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Rakam skrin"</string>
     <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Mula"</string>
     <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Berhenti"</string>
-    <string name="qs_record_issue_label" msgid="8166290137285529059">"Rekodkan masalah"</string>
+    <string name="qs_record_issue_label" msgid="8166290137285529059">"Rekodkan Masalah"</string>
     <string name="qs_record_issue_start" msgid="2979831312582567056">"Mula"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"Hentikan"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Laporan Pepijat"</string>
-    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Pengalaman peranti yang manakah yang terjejas?"</string>
+    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Apakah pengalaman peranti yang terjejas?"</string>
     <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Pilih jenis masalah"</string>
     <string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Rakam skrin"</string>
     <string name="performance" msgid="6552785217174378320">"Prestasi"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Tambahkan lagi widget"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Tekan lama untuk menyesuaikan widget"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Sesuaikan widget"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Buka kunci untuk menyesuaikan widget"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikon apl untuk melumpuhkan widget"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikon apl untuk widget yang sedang dipasang"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Edit widget"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"pilih widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"alih keluar widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"letakkan widget dipilih"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Tukar pengguna"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu tarik turun"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Semua apl dan data dalam sesi ini akan dipadam."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Mulakan sekarang"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Tiada pemberitahuan"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Tiada pemberitahuan baharu"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Pemberitahuan boleh suai dihidupkan"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Kelantangan &amp; tetingkap timbul pada skrin peranti anda dikurangkan selama dua minit apabila banyak pemberitahuan diterima dalam masa yang singkat."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Matikan"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Buka kunci untuk melihat pemberitahuan lama"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Peranti ini diurus oleh ibu bapa anda"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisasi anda memiliki peranti ini dan mungkin memantau trafik rangkaian"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Ketik untuk mendapatkan maklumat lanjut"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Tiada penggera"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"masukkan kunci skrin"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Sentuh penderia cap jari. Penderia cap jari ialah butang yang lebih pendek di sisi telefon"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Penderia cap jari"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"sahkan"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"akses peranti"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Digunakan oleh <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Digunakan baru-baru ini oleh <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Kawalan sistem"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Apl sistem"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Berbilang tugas"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Apl terbaharu"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Skrin pisah"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Pintasan apl"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Kebolehaksesan"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Kembali"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Untuk kembali, leret ke kiri atau kanan menggunakan tiga jari di mana-mana sahaja pada pad sentuh."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Pad sentuh menunjukkan tiga jari bergerak ke kanan dan kiri"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Skrin peranti menunjukkan animasi untuk gerak isyarat kembali"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Cahaya latar papan kekunci"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Tahap %1$d daripada %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Kawalan Rumah"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index d13ee63..c916e31 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -103,10 +103,11 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> က ဤဖန်သားပြင်ဓာတ်ပုံကို တွေ့ရှိသည်။"</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> နှင့် အခြားဖွင့်ထားသော အက်ပ်များက ဤဖန်သားပြင်ဓာတ်ပုံကို တွေ့ရှိသည်။"</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"မှတ်စုတွင် ထည့်ရန်"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"လင့်ခ်ထည့်သွင်းရန်"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"ဖန်သားပြင်ရိုက်ကူးစက်"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"စကရင်ရိုက်ကူးမှု အပြီးသတ်နေသည်"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ဖန်သားပြင် ရိုက်ကူးသည့် စက်ရှင်အတွက် ဆက်တိုက်လာနေသော အကြောင်းကြားချက်"</string>
-    <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"ရိုက်သံဖမ်းခြင်း စတင်မလား။"</string>
+    <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"ရုပ်သံဖမ်းခြင်း စတင်မလား။"</string>
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"ရုပ်သံဖမ်းနေစဉ် Android သည် သင့်ဖန်သားပြင်တွင် မြင်နိုင်သည့် (သို့) သင့်စက်တွင် ဖွင့်ထားသည့် အရာအားလုံးကို တွေ့နိုင်သည်။ စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ်၊ ဓာတ်ပုံ၊ အသံနှင့် ဗီဒီယိုကဲ့သို့ အရာများကို ဂရုစိုက်ပါ။"</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"အက်ပ်တစ်ခုကို ရုပ်သံဖမ်းနေစဉ် Android သည် ယင်းအက်ပ်တွင် ပြထားသည့် (သို့) ဖွင့်ထားသည့် အရာအားလုံးကို တွေ့နိုင်သည်။ ထို့ကြောင့် စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ်၊ ဓာတ်ပုံ၊ အသံနှင့် ဗီဒီယိုကဲ့သို့ အရာများကို ဂရုစိုက်ပါ။"</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"ရုပ်သံ စဖမ်းရန်"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ၏ အကြောင်းအရာ ရိုက်ကူးခြင်းကို ရပ်ပါမည်"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ဖန်သားပြင်ကို မျှဝေနေသည်"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ၏ အကြောင်းအရာ မျှဝေခြင်းကို ရပ်ပါမည်"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"ဖန်သားပြင်ကို ကာစ်လုပ်နေသည်"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ၏ အကြောင်းအရာ ကာစ်လုပ်ခြင်းကို ရပ်ပါမည်"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"မျက်နှာဖြင့် ဖွင့်ထားသည်။ ရှေ့ဆက်ရန် နှိပ်ပါ။"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"မျက်နှာ မှတ်မိသည်။ ရှေ့ဆက်ရန် နှိပ်ပါ။"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"မျက်နှာ မှတ်မိသည်။ ရှေ့ဆက်ရန် လော့ခ်ဖွင့်သင်္ကေတကို နှိပ်ပါ။"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"မျက်နှာဖြင့် ဖွင့်ထားသည်။ ဆက်လုပ်ရန် တို့ပါ။"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"အထောက်အထားစိစစ်ပြီးပြီ"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"အထောက်အထားစိစစ်ခြင်းကို ပယ်ဖျက်ရန်"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"နောက်ထပ်ရွေးစရာများ"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"‘အမြန် မျှဝေပါ’ နှင့် Find My Device ကဲ့သို့ တူးလ်များသည် ဘလူးတုသ်သုံးသည်"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"မနက်ဖြန်နံနက်တွင် ဘလူးတုသ် ပွင့်ပါမည်"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"အသံမျှဝေရန်"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"အသံမျှဝေနေသည်"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"နောက်ထပ်ဝိဂျက်များ ထည့်ရန်"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ဝိဂျက်များ စိတ်ကြိုက်လုပ်ရန် ကြာကြာနှိပ်ထားပါ"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ဝိဂျက်များကို စိတ်ကြိုက်လုပ်ရန်"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ဝိဂျက်များ စိတ်ကြိုက်လုပ်ရန် ဖွင့်နိုင်သည်"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ပိတ်ထားသော ဝိဂျက်အတွက် အက်ပ်သင်္ကေတ"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ထည့်သွင်းနေသော ဝိဂျက်အတွက် အက်ပ်သင်္ကေတ"</string>
     <string name="edit_widget" msgid="9030848101135393954">"ဝိဂျက်ပြင်ရန်"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ဝိဂျက် ရွေးရန်"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ဝိဂျက် ဖယ်ရှားရန်"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ရွေးချယ်ထားသော ဝိဂျက်ကို တင်ရန်"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"အသုံးပြုသူကို ပြောင်းလဲရန်"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ဆွဲချမီနူး"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ဒီချိတ်ဆက်မှု ထဲက အက်ပ်များ အားလုံး နှင့် ဒေတာကို ဖျက်ပစ်မည်။"</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"ယခု စတင်ပါ"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"အကြောင်းကြားချက် မရှိပါ"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"အကြောင်းကြားချက်သစ် မရှိပါ"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"အလိုက်သင့်အကြောင်းကြားချက် ဖွင့်ထားသည်"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"သင့်စက်သည် အချိန်တိုအတွင်း အကြောင်းကြားချက်များစွာ ရပါက အသံတိုးပြီး စခရင်ရှိ ပေါ့ပ်အပ်များကို နှစ်မိနစ်အထိ လျှော့ပေးသည်။"</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ပိတ်ရန်"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"အကြောင်းကြားချက်ဟောင်းကြည့်ရန် လော့ခ်ဖွင့်ပါ"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ဤစက်ပစ္စည်းကို သင့်မိဘက စီမံခန့်ခွဲသည်"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ဤစက်ကို သင့်အဖွဲ့အစည်းကပိုင်ဆိုင်ပြီး ကွန်ရက်ဒေတာ စီးဆင်းမှုကို စောင့်ကြည့်နိုင်ပါသည်"</string>
@@ -780,7 +795,7 @@
     <string name="keyboard_shortcut_join" msgid="3578314570034512676">"သို့မဟုတ်"</string>
     <string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"ရှာဖွေစာလုံး ရှင်းထုတ်ရန်"</string>
     <string name="keyboard_shortcut_search_list_title" msgid="4271769465397671138">"လက်ကွက်ဖြတ်လမ်းများ"</string>
-    <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"ဖြတ်လမ်းလင့်ခ်များ ရှာပါ"</string>
+    <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"ဖြတ်လမ်းများ ရှာရန်"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"ဖြတ်လမ်းလင့်ခ် မတွေ့ပါ"</string>
     <string name="keyboard_shortcut_search_category_system" msgid="1151182120757052669">"စနစ်"</string>
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"စာရိုက်ခြင်း"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"နောက်ထပ်အချက်အလက်များအတွက် တို့ပါ"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"နှိုးစက်ပေးမထားပါ"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"ဖန်သားပြင်လော့ခ် ထည့်ရန်"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"လက်ဗွေ အာရုံခံကိရိယာကို တို့ပါ။ ၎င်းသည် ဖုန်းဘေးရှိ ခလုတ်အတို ဖြစ်သည်"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"လက်ဗွေ အာရုံခံကိရိယာ"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"အထောက်အထားစိစစ်ရန်"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"စက်ပစ္စည်းသို့ ဝင်ရန်"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) က သုံးနေသည်"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) က လတ်တလောသုံးထားသည်"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"စနစ်"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"စနစ် ထိန်းချုပ်မှုများ"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"စနစ် အက်ပ်များ"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"တစ်ပြိုင်နက် များစွာလုပ်ခြင်း"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"မကြာသေးမီက အက်ပ်များ"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"မျက်နှာပြင် ခွဲ၍ပြသခြင်း"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"ထည့်သွင်းမှု"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"အက်ပ်ဖြတ်လမ်းလင့်ခ်များ"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"အများသုံးနိုင်မှု"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ပြန်သွားရန်"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ပြန်သွားရန်အတွက် တာ့ချ်ပက်တွင် မည်သည့်နေရာ၌မဆို လက်သုံးချောင်းသုံး၍ ဘယ် (သို့) ညာသို့ ပွတ်ဆွဲပါ။"</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"တာ့ချ်ပက်တွင် ဘယ်ညာရွှေ့နေသော လက်သုံးချောင်းကို ပြထားသည်"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"စက်စခရင်တွင် နောက်သို့လက်ဟန်အတွက် လှုပ်ရှားသက်ဝင်ပုံကို ပြထားသည်"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ကီးဘုတ်နောက်မီး"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"အဆင့် %2$d အနက် %1$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"အိမ်ထိန်းချုပ်မှုများ"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 91ef466..8fccf1a 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -71,28 +71,28 @@
     <string name="usb_port_enabled" msgid="531823867664717018">"Registrering av ladere og tilbehør er slått på for USB-porten"</string>
     <string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Slå på USB"</string>
     <string name="learn_more" msgid="4690632085667273811">"Finn ut mer"</string>
-    <string name="global_action_screenshot" msgid="2760267567509131654">"Skjermdump"</string>
+    <string name="global_action_screenshot" msgid="2760267567509131654">"Skjermbilde"</string>
     <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Hold ulåst er slått av"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"har sendt et bilde"</string>
-    <string name="screenshot_saving_title" msgid="2298349784913287333">"Lagrer skjermdumpen …"</string>
-    <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Lagrer skjermdumpen i jobbprofilen …"</string>
-    <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Lagrer skjermdump i den private profilen"</string>
+    <string name="screenshot_saving_title" msgid="2298349784913287333">"Lagrer skjermbildet …"</string>
+    <string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Lagrer skjermbildet i jobbprofilen …"</string>
+    <string name="screenshot_saving_private_profile" msgid="8934706048497093297">"Lagrer skjermbilde i den private profilen"</string>
     <string name="screenshot_saved_title" msgid="8893267638659083153">"Skjermdumpen er lagret"</string>
-    <string name="screenshot_failed_title" msgid="3259148215671936891">"Kunne ikke lagre skjermdump"</string>
+    <string name="screenshot_failed_title" msgid="3259148215671936891">"Kunne ikke lagre skjermbilde"</string>
     <string name="screenshot_failed_external_display_indication" msgid="6555673132061101936">"Ekstern skjerm"</string>
-    <string name="screenshot_failed_to_save_user_locked_text" msgid="6156607948256936920">"Enheten må være låst opp før skjermdumpen kan lagres"</string>
-    <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Prøv å ta skjermdump på nytt"</string>
-    <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Kan ikke lagre skjermdumpen"</string>
-    <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Appen eller organisasjonen din tillater ikke at du tar skjermdumper"</string>
-    <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Funksjonen for å ta skjermdumper er blokkert av IT-administratoren din"</string>
+    <string name="screenshot_failed_to_save_user_locked_text" msgid="6156607948256936920">"Enheten må være låst opp før skjermbildet kan lagres"</string>
+    <string name="screenshot_failed_to_save_unknown_text" msgid="1506621600548684129">"Prøv å ta skjermbilde på nytt"</string>
+    <string name="screenshot_failed_to_save_text" msgid="7232739948999195960">"Kan ikke lagre skjermbildet"</string>
+    <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Appen eller organisasjonen din tillater ikke at du tar skjermbilder"</string>
+    <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Funksjonen for å ta skjermbilder er blokkert av IT-administratoren din"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Rediger"</string>
-    <string name="screenshot_edit_description" msgid="3333092254706788906">"Rediger skjermdumpen"</string>
+    <string name="screenshot_edit_description" msgid="3333092254706788906">"Rediger skjermbildet"</string>
     <string name="screenshot_share_label" msgid="1653061117238861559">"Del"</string>
-    <string name="screenshot_share_description" msgid="2861628935812656612">"Del skjermdumpen"</string>
-    <string name="screenshot_scroll_label" msgid="2930198809899329367">"Utvidet skjermdump"</string>
-    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Avvis skjermdumpen"</string>
+    <string name="screenshot_share_description" msgid="2861628935812656612">"Del skjermbildet"</string>
+    <string name="screenshot_scroll_label" msgid="2930198809899329367">"Utvidet skjermbilde"</string>
+    <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Avvis skjermbildet"</string>
     <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"Avvis melding fra jobbprofilen"</string>
-    <string name="screenshot_preview_description" msgid="7606510140714080474">"Forhåndsvisning av skjermdump"</string>
+    <string name="screenshot_preview_description" msgid="7606510140714080474">"Forhåndsvisning av skjermbilde"</string>
     <string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"Øvre grense <xliff:g id="PERCENT">%1$d</xliff:g> prosent"</string>
     <string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"Nedre grense <xliff:g id="PERCENT">%1$d</xliff:g> prosent"</string>
     <string name="screenshot_left_boundary_pct" msgid="8502323556112287469">"Venstre grense <xliff:g id="PERCENT">%1$d</xliff:g> prosent"</string>
@@ -100,9 +100,10 @@
     <string name="screenshot_work_profile_notification" msgid="203041724052970693">"Lagret i <xliff:g id="APP">%1$s</xliff:g> i jobbprofilen"</string>
     <string name="screenshot_private_profile_notification" msgid="1704440899154243171">"Lagret i <xliff:g id="APP">%1$s</xliff:g> i den private profilen"</string>
     <string name="screenshot_default_files_app_name" msgid="8721579578575161912">"Filer"</string>
-    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> har registrert denne skjermdumpen."</string>
-    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> og andre åpne apper har registrert denne skjermdumpen."</string>
+    <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> har registrert dette skjermbildet."</string>
+    <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> og andre åpne apper har registrert dette skjermbildet."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Legg til i notat"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Inkluder linken"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Skjermopptak"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandler skjermopptaket"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Vedvarende varsel for et skjermopptak"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Du slutter å ta opp &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Deler skjermen"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Du slutter å dele &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Caster skjermen"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Du slutter å caste &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <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>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Låst opp med ansiktet. Trykk for å fortsette."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentisert"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Avbryt autentisering"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Flere alternativer"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funksjoner som Quick Share og Finn enheten min bruker Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth slås på i morgen tidlig"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Del lyd"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Deler lyd"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batteri"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Lyd"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Hodetelefoner"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Legg til flere moduler"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Trykk lenge for å tilpasse modulene"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tilpass moduler"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Lås opp for å tilpasse moduler"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Appikon for deaktivert modul"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Appikon for en modul som installeres"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Endre modul"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"velg modul"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"fjern modul"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"plasser den valgte modulen"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Bytt bruker"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rullegardinmeny"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apper og data i denne økten blir slettet."</string>
@@ -529,7 +541,7 @@
     <string name="media_projection_task_switcher_action_back" msgid="5324164224147845282">"Bytt tilbake"</string>
     <string name="media_projection_task_switcher_notification_channel" msgid="7613206306777814253">"Appbytte"</string>
     <string name="screen_capturing_disabled_by_policy_dialog_title" msgid="2113331792064527203">"Blokkert av IT-administratoren"</string>
-    <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Skjermdumper er deaktivert av enhetsinnstillingene"</string>
+    <string name="screen_capturing_disabled_by_policy_dialog_description" msgid="6015975736747696431">"Skjermbilder er deaktivert av enhetsinnstillingene"</string>
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Fjern alt"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Administrer"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Logg"</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Start nå"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Ingen varsler"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Ingen nye varsler"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Tilpassbare varsler er på"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Den nye enheten din senker volumet og reduserer antall forgrunnsvinduer på skjermen i opptil to minutter når du mottar mange varsler på kort tid."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Slå av"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Lås opp for å se eldre varsler"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Denne enheten administreres av forelderen din"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisasjonen din eier denne enheten og kan overvåke nettverkstrafikken"</string>
@@ -792,7 +807,7 @@
     <string name="keyboard_shortcut_a11y_filter_open_apps" msgid="6175417687221004059">"Viser snarveier som åpner apper"</string>
     <string name="keyboard_shortcut_a11y_filter_current_app" msgid="7944592357493737911">"Viser snarveier for den gjeldende appen"</string>
     <string name="group_system_access_notification_shade" msgid="1619028907006553677">"Se varsler"</string>
-    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Ta skjermdump"</string>
+    <string name="group_system_full_screenshot" msgid="5742204844232667785">"Ta skjermbilde"</string>
     <string name="group_system_access_system_app_shortcuts" msgid="8562482996626694026">"Vis snarveier"</string>
     <string name="group_system_go_back" msgid="2730322046244918816">"Gå tilbake"</string>
     <string name="group_system_access_home_screen" msgid="4130366993484706483">"Gå til startskjermen"</string>
@@ -927,7 +942,7 @@
     <string name="tuner_app" msgid="6949280415826686972">"<xliff:g id="APP">%1$s</xliff:g>-appen"</string>
     <string name="notification_channel_alerts" msgid="3385787053375150046">"Varsler"</string>
     <string name="notification_channel_battery" msgid="9219995638046695106">"Batteri"</string>
-    <string name="notification_channel_screenshot" msgid="7665814998932211997">"Skjermdumper"</string>
+    <string name="notification_channel_screenshot" msgid="7665814998932211997">"Skjermbilder"</string>
     <string name="notification_channel_instant" msgid="7556135423486752680">"Instant Apps"</string>
     <string name="notification_channel_setup" msgid="7660580986090760350">"Konfigurering"</string>
     <string name="notification_channel_storage" msgid="2720725707628094977">"Lagring"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Trykk for å få mer informasjon"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ingen alarm angitt"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"legg inn skjermlåsen"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Trykk på fingeravtrykkssensoren. Det er den korte knappen på siden av telefonen."</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingeravtrykkssensor"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentiser"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"åpne enheten"</string>
@@ -1289,8 +1305,8 @@
     <string name="rear_display_unfolded_bottom_sheet_title" msgid="6291111173057304055">"Vil du bytte skjerm?"</string>
     <string name="rear_display_folded_bottom_sheet_description" msgid="6842767125783222695">"Bruk baksidekameraet for å få høyere oppløsning"</string>
     <string name="rear_display_unfolded_bottom_sheet_description" msgid="7229961336309960201">"Brett ut telefonen for å få høyere oppløsning"</string>
-    <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En sammenleggbar enhet blir brettet ut"</string>
-    <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En sammenleggbar enhet blir snudd"</string>
+    <string name="rear_display_accessibility_folded_animation" msgid="1538121649587978179">"En foldbar enhet blir brettet ut"</string>
+    <string name="rear_display_accessibility_unfolded_animation" msgid="1946153682258289040">"En foldbar enhet blir snudd"</string>
     <string name="quick_settings_rotation_posture_folded" msgid="2430280856312528289">"lagt sammen"</string>
     <string name="quick_settings_rotation_posture_unfolded" msgid="6372316273574167114">"åpen"</string>
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s/%2$s"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"I bruk av <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nylig brukt av <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Systemkontroller"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Systemapper"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nylige apper"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Delt skjerm"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Inndata"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App-snarveier"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Tilgjengelighet"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Gå tilbake"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"For å gå tilbake, sveip til venstre eller høyre med tre fingre hvor som helst på styreflaten."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"En styreflate med tre fingre som beveger seg til høyre og venstre"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Enhetsskjerm med animasjonen for tilbakebevegelse"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Bakgrunnslys for tastatur"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivå %1$d av %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Hjemkontroller"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 10d64b7..8fae08d 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ले यो स्क्रिनसट भेट्टाएको छ।"</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> र खुला रहेका अन्य एपहरूले यो स्क्रिनसट भेट्टाएका छन्।"</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"नोटमा सेभ गर्नुहोस्"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"लिंक समावेश गर्नुहोस्"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"स्क्रिन रेकर्डर"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रिन रेकर्डिङको प्रक्रिया अघि बढाइँदै"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"कुनै स्क्रिन रेकर्ड गर्ने सत्रका लागि चलिरहेको सूचना"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; का सामग्री रेकर्ड हुन छाड्ने छन्"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"स्क्रिन सेयर गरिँदै छ"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; का सामग्री सेयर हुन छाड्ने छन्"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"स्क्रिन कास्ट गरिँदै छ"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; का सामग्री कास्ट हुन छाड्ने छन्"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"अनुहार प्रयोग गरी अनलक गरियो। जारी राख्न थिच्नुहोस्।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"अनुहार पहिचान गरियो। जारी राख्न थिच्नुहोस्।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"अनुहार पहिचान गरियो। जारी राख्न अनलक आइकनमा थिच्नुहोस्।"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"अनुहार प्रयोग गरी अनलक गरिएको छ। जारी राख्न ट्याप गर्नुहोस्।"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"प्रमाणीकरण गरियो"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"प्रमाणीकरण रद्द गर्नुहोस्"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"थप विकल्पहरू"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"क्विक सेयर र Find My Device जस्ता सुविधाहरू प्रयोग गर्न ब्लुटुथ चाहिन्छ"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ब्लुटुथ भोलि बिहान अन हुने छ"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"अडियो सेयर गर्नुहोस्"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"अडियो सेयर गरिँदै छ"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"थप विजेटहरू हाल्नुहोस्"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"विजेटहरू कस्टमाइज गर्न केही बेरसम्म थिच्नुहोस्"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"विजेटहरू कस्टमाइज गर्नुहोस्"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"विजेटहरू कस्टमाइज गर्न अन लक गर्नुहोस्"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"अफ गरिएको विजेटको एप जनाउने आइकन"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"इन्स्टल भइरहेको विजेटको एप आइकन"</string>
     <string name="edit_widget" msgid="9030848101135393954">"विजेट सम्पादन गर्नुहोस्"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"विजेट चयन गर्नुहोस्"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"विजेट हटाउनुहोस्"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"चयन गरिएका विजेटका लागि ठाउँ चयन गर्नुहोस्"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"प्रयोगकर्ता फेर्नुहोस्"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"पुलडाउन मेनु"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"यो सत्रमा भएका सबै एपहरू र डेटा मेटाइने छ।"</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"अहिले न"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"कुनै सूचनाहरू छैनन्"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"कुनै पनि नयाँ सूचना छैन"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"एड्याप्टिभ नोटिफिकेसन अन छ"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"तपाईंले छोटो समयमा धेरै नोटिफिकेसन प्राप्त गर्दा तपाईंको डिभाइसले अब दुई मिनेटसम्म भोल्युम र स्क्रिनमा देखिने पप-अपको सङ्ख्या घटाउँछ।"</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"अफ गर्नुहोस्"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"पुराना सूचनाहरू हेर्न अनलक गर्नुहोस्"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"यो डिभाइस तपाईंका अभिभावक व्यवस्थापन गर्नुहुन्छ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"यो डिभाइस तपाईंको सङ्गठनको स्वामित्वमा छ र उक्त सङ्गठनले यसको नेटवर्क ट्राफिक अनुगमन गर्न सक्छ"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"थप जानकारी प्राप्त गर्न ट्याप गर्नुहोस्"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"अलार्म राखिएको छैन"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"स्क्रिन लक हाल्नुहोस्"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"फिंगरप्रिन्ट सेन्सरमा छुनुहोस्। यो फोनको साइडमा भएको अलि सानो चाहिँ बटन हो"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"फिंगरप्रिन्ट सेन्सर"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"प्रमाणित गर्नुहोस्"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"डिभाइस हाल्नुहोस्"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ले प्रयोग गरिरहेको छ"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ले हालसालै प्रयोग गरेको"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"सिस्टम"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"सिस्टमसँग सम्बन्धित नियन्त्रणहरू"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"सिस्टम एपहरू"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"एकै पटक एकभन्दा बढी एप चलाउन मिल्ने सुविधा"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"हालसालै चलाइएका एपहरू"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"स्प्लिट स्क्रिन"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"इनपुट"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"एपका सर्टकटहरू"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"सर्वसुलभता"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"पछाडि जानुहोस्"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"पछाडि जान तिन वटा औँलाले टचप्याडमा कतै छोएर बायाँ वा दायाँतिर स्वाइप गर्नुहोस्।"</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"तिन वटा औँला दायाँ र बायाँ सारेको देखाइएको टचप्याड"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"पछाडि जाने जेस्चरको एनिमेसन देखाइएको डिभाइसको स्क्रिन"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"किबोर्ड ब्याकलाइट"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d मध्ये %1$d औँ स्तर"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"होम कन्ट्रोलहरू"</string>
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index d377e01..21f1cfb 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -104,10 +104,6 @@
 
     <color name="people_tile_background">@color/material_dynamic_secondary20</color>
 
-    <!-- Internet Dialog -->
-    <color name="connected_network_primary_color">@color/material_dynamic_primary80</color>
-    <color name="connected_network_secondary_color">@color/material_dynamic_secondary80</color>
-
     <!-- Keyboard shortcut helper dialog -->
     <color name="ksh_key_item_color">@*android:color/system_on_surface_variant_dark</color>
 </resources>
diff --git a/packages/SystemUI/res/values-night/styles.xml b/packages/SystemUI/res/values-night/styles.xml
index 546bf1c..e9dd039f3 100644
--- a/packages/SystemUI/res/values-night/styles.xml
+++ b/packages/SystemUI/res/values-night/styles.xml
@@ -60,18 +60,6 @@
         <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
     </style>
 
-    <style name="TextAppearance.InternetDialog.Active">
-        <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
-        <item name="android:textSize">16sp</item>
-        <item name="android:textColor">@color/material_dynamic_primary80</item>
-        <item name="android:textDirection">locale</item>
-    </style>
-
-    <style name="TextAppearance.InternetDialog.Secondary.Active">
-        <item name="android:textSize">14sp</item>
-        <item name="android:textColor">@color/material_dynamic_secondary80</item>
-    </style>
-
     <style name="ShortcutHelperTheme" parent="@style/ShortcutHelperThemeCommon">
         <item name="android:windowLightNavigationBar">false</item>
     </style>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index c990cab..6dbd8fb 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> heeft dit screenshot waargenomen."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> en andere geopende apps hebben dit screenshot waargenomen."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Toevoegen aan notitie"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Link opnemen"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Schermopname"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Schermopname verwerken"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Doorlopende melding voor een schermopname-sessie"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Je stopt met het opnemen van &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Scherm delen"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Je stopt met het delen van &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Scherm casten"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Je stopt met het casten van &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Ontgrendeld via gezicht. Druk om door te gaan."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Gezicht herkend. Druk om door te gaan."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gezicht herkend. Druk op het ontgrendelicoon."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Ontgrendeld via gezicht. Tik om door te gaan."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Geverifieerd"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Verificatie annuleren"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Meer opties"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Functies zoals Quick Share en Vind mijn apparaat gebruiken bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth wordt morgenochtend aangezet"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Audio delen"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Audio delen"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batterijniveau"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Meer widgets toevoegen"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Houd lang ingedrukt om widgets aan te passen"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Widgets aanpassen"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Ontgrendel om widgets aan te passen"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"App-icoon voor uitgezette widget"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"App-icoon voor een widget die wordt geïnstalleerd"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Widget bewerken"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"widget selecteren"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"widget verwijderen"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"geselecteerde widget plaatsen"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Gebruiker wijzigen"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pull-downmenu"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alle apps en gegevens in deze sessie worden verwijderd."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Nu starten"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Geen meldingen"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Geen nieuwe meldingen"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Aanpasbare meldingen staan aan"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Je apparaat verlaagt nu het volume en vermindert pop-ups op het scherm gedurende maximaal 2 minuten als je in korte tijd veel meldingen krijgt."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Uitzetten"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Ontgrendel om oudere meldingen te zien"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Dit apparaat wordt beheerd door je ouder"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Je organisatie is eigenaar van dit apparaat en kan het netwerkverkeer bijhouden"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tik hier voor meer informatie"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Geen wekker gezet"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"schermvergrendeling invoeren"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Raak de vingerafdruksensor aan. Dit is de kortere knop aan de zijkant van de telefoon."</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Vingerafdruksensor"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"verifiëren"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"apparaat opgeven"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Gebruikt door <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Recent gebruikt door <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Systeem"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Systeemopties"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Systeem-apps"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Recente apps"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Gesplitst scherm"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Invoer"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"App-snelkoppelingen"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Toegankelijkheid"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Terug"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Als je wilt teruggaan, swipe je met 3 vingers naar links of rechts op de touchpad."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad met 3 vingers die naar rechts en links bewegen"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Apparaatscherm met animatie voor teruggebaar"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Achtergrondverlichting van toetsenbord"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveau %1$d van %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Bediening voor in huis"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 49a3268..0f05982 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ଏହି ସ୍କ୍ରିନସଟକୁ ଚିହ୍ନଟ କରିଛି।"</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ଏବଂ ଅନ୍ୟ ଓପନ ଆପ୍ସ ଏହି ସ୍କ୍ରିନସଟକୁ ଚିହ୍ନଟ କରିଛି।"</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ନୋଟରେ ଯୋଗ କରନ୍ତୁ"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"ଲିଙ୍କକୁ ଅନ୍ତର୍ଭୁକ୍ତ କରନ୍ତୁ"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"ସ୍କ୍ରିନ ରେକର୍ଡର"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ସ୍କ୍ରିନ ରେକର୍ଡିଂର ପ୍ରକ୍ରିୟାକରଣ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ଏକ ସ୍କ୍ରି‍ନ୍‍ ରେକର୍ଡ୍‍ ସେସନ୍‍ ପାଇଁ ଚାଲୁଥିବା ବିଜ୍ଞପ୍ତି"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"ଆପଣ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;କୁ ରେକର୍ଡ କରିବା ବନ୍ଦ କରିବେ"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ସ୍କ୍ରିନ ସେୟାର କରାଯାଉଛି"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"ଆପଣ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;କୁ ସେୟାର କରିବା ବନ୍ଦ କରିବେ"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"ସ୍କ୍ରିନ କାଷ୍ଟ କରାଯାଉଛି"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"ଆପଣ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;କୁ କାଷ୍ଟ କରିବା ବନ୍ଦ କରିବେ"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଦବାନ୍ତୁ।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଦବାନ୍ତୁ।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ।"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"ଫେସ ମାଧ୍ୟମରେ ଅନଲକ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ପ୍ରାମାଣିକତା ହୋଇଛି"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ପ୍ରମାଣୀକରଣକୁ ବାତିଲ କରନ୍ତୁ"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ଅଧିକ ବିକଳ୍ପ"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share ଏବଂ Find My Device ପରି ଫିଚରଗୁଡ଼ିକ ବ୍ଲୁଟୁଥ ବ୍ୟବହାର କରେ"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ବ୍ଲୁଟୁଥ ଆସନ୍ତା କାଲି ସକାଳେ ଚାଲୁ ହେବ"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ଅଡିଓ ସେୟାର କରନ୍ତୁ"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"ଅଡିଓ ସେୟାର କରାଯାଉଛି"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ଅଧିକ ୱିଜେଟ ଯୋଗ କରନ୍ତୁ"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ୱିଜେଟଗୁଡ଼ିକୁ କଷ୍ଟମାଇଜ କରିବା ପାଇଁ ଅଧିକ ସମୟ ଦବାନ୍ତୁ"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ୱିଜେଟଗୁଡ଼ିକୁ କଷ୍ଟମାଇଜ କରନ୍ତୁ"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ୱିଜେଟ କଷ୍ଟମାଇଜ କରିବାକୁ ଅନଲକ କରନ୍ତୁ"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ଅକ୍ଷମ କରାଯାଇଥିବା ୱିଜେଟ ପାଇଁ ଆପ ଆଇକନ"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ଏକ ୱିଜେଟ ପାଇଁ ଆପ ଆଇକନକୁ ଇନଷ୍ଟଲ କରାଯାଉଛି"</string>
     <string name="edit_widget" msgid="9030848101135393954">"ୱିଜେଟକୁ ଏଡିଟ କରନ୍ତୁ"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ୱିଜେଟ ଚୟନ କରନ୍ତୁ"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ୱିଜେଟକୁ କାଢ଼ି ଦିଅନ୍ତୁ"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ଚୟନିତ ୱିଜେଟ ରଖନ୍ତୁ"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ୟୁଜର୍‍ ବଦଳାନ୍ତୁ"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ପୁଲଡାଉନ ମେନୁ"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ଏହି ସେସନର ସମସ୍ତ ଆପ୍‌ ଓ ଡାଟା ଡିଲିଟ୍‌ ହୋଇଯିବ।"</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"ବର୍ତ୍ତମାନ ଆରମ୍ଭ କରନ୍ତୁ"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"କୌଣସି ବିଜ୍ଞପ୍ତି ନାହିଁ"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"କୌଣସି ନୂଆ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ନାହିଁ"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"ଆଡେପ୍ଟିଭ ବିଜ୍ଞପ୍ତି ଚାଲୁ ଅଛି"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"କମ ସମୟ ମଧ୍ୟରେ ଅନେକ ବିଜ୍ଞପ୍ତି ପାଇଲେ ଆପଣଙ୍କ ଡିଭାଇସ ଏବେ ଦୁଇ ମିନିଟ ପର୍ଯ୍ୟନ୍ତ ଭଲ୍ୟୁମକୁ କମ କରି ସ୍କ୍ରିନରେ ଥିବା ପପ-ଅପକୁ କମ କରେ।"</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ପୁରୁଣା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଦେଖିବାକୁ ଅନଲକ କରନ୍ତୁ"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ଏହି ଡିଭାଇସ୍ ଆପଣଙ୍କ ବାପାମାଙ୍କ ଦ୍ୱାରା ପରିଚାଳିତ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ଏହି ଡିଭାଇସର ମାଲିକାନା ଆପଣଙ୍କ ସଂସ୍ଥା ପାଖରେ ଅଛି ଏବଂ ଏହା ନେଟୱାର୍କ ଟ୍ରାଫିକର ନିରୀକ୍ଷଣ କରିପାରେ"</string>
@@ -811,7 +826,7 @@
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ବ୍ୟବହାର କରିବା ସମୟରେ ଡାହାଣପଟର ବା ତଳର ଆପକୁ ସୁଇଚ କରନ୍ତୁ"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ବ୍ୟବହାର କରିବା ସମୟରେ ବାମପଟର ବା ଉପରର ଆପକୁ ସୁଇଚ କରନ୍ତୁ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ସମୟରେ: କୌଣସି ଆପକୁ ଗୋଟିଏରୁ ଅନ୍ୟ ଏକ ଆପରେ ବଦଳାନ୍ତୁ"</string>
-    <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ଇନପୁଟ କରନ୍ତୁ"</string>
+    <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ଇନପୁଟ"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"ପରବର୍ତ୍ତୀ ଭାଷାକୁ ସୁଇଚ କରନ୍ତୁ"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"ପୂର୍ବବର୍ତ୍ତୀ ଭାଷାକୁ ସୁଇଚ କରନ୍ତୁ"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"ଇମୋଜି ଆକ୍ସେସ କରନ୍ତୁ"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ଅଧିକ ସୂଚନା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ଆଲାରାମ ସେଟ ହୋଇନାହିଁ"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"ସ୍କ୍ରିନ ଲକ ଲେଖନ୍ତୁ"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ଟିପଚିହ୍ନ ସେନ୍ସରକୁ ସ୍ପର୍ଶ କରନ୍ତୁ ଏହା ଫୋନର ପାର୍ଶ୍ୱରେ ଥିବା ଛୋଟ ବଟନ ଅଟେ"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ଟିପଚିହ୍ନ ସେନ୍ସର୍"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"ପ୍ରମାଣୀକରଣ କରନ୍ତୁ"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"ଡିଭାଇସ୍ ବିଷୟରେ ସୂଚନା ଲେଖନ୍ତୁ"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଦ୍ୱାରା ବ୍ୟବହାର କରାଯାଉଛି (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"ଏବେ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ଦ୍ୱାରା ବ୍ୟବହାର କରାଯାଉଛି"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"ସିଷ୍ଟମ"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ସିଷ୍ଟମ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"ସିଷ୍ଟମ ଆପ୍ସ"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ମଲ୍ଟିଟାସ୍କିଂ"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"ବର୍ତ୍ତମାନର ଆପ୍ସ"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"ଇନପୁଟ"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ଆପ ସର୍ଟକଟ"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ଆକ୍ସେସିବିଲିଟୀ"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ପଛକୁ ଫେରନ୍ତୁ"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ପଛକୁ ଫେରିବା ପାଇଁ ଯେ କୌଣସି ସ୍ଥାନରେ ତିନି ଆଙ୍ଗୁଠି ବ୍ୟବହାର କରି ବାମ କିମ୍ବା ଡାହାଣକୁ ସ୍ୱାଇପ କରନ୍ତୁ।"</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ଡାହାଣ ଏବଂ ବାମକୁ ତିନି ଆଙ୍ଗୁଠି ମୁଭ କରୁଥିବା ଟଚପେଡ ଦେଖାଉଛି"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"ଡିଭାଇସ ସ୍କ୍ରିନ ବେକ ଜେଶ୍ଚର ପାଇଁ ଆନିମେସନ ଦେଖାଉଛି"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"କୀବୋର୍ଡ ବେକଲାଇଟ"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dରୁ %1$d ନମ୍ବର ଲେଭେଲ"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ହୋମ କଣ୍ଟ୍ରୋଲ୍ସ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 6a7e9e8..3cb2e6d 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ਨੂੰ ਇਸ ਸਕ੍ਰੀਨਸ਼ਾਟ ਦਾ ਪਤਾ ਲੱਗਿਆ ਹੈ।"</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ਅਤੇ ਹੋਰ ਖੁੱਲ੍ਹੀਆਂ ਐਪਾਂ ਨੂੰ ਇਸ ਸਕ੍ਰੀਨਸ਼ਾਟ ਦਾ ਪਤਾ ਲੱਗਿਆ ਹੈ।"</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"ਨੋਟ ਵਿੱਚ ਸ਼ਾਮਲ ਕਰੋ"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"ਲਿੰਕ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਰ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਜਾਰੀ ਹੈ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ਕਿਸੇ ਸਕ੍ਰੀਨ ਰਿਕਾਰਡ ਸੈਸ਼ਨ ਲਈ ਚੱਲ ਰਹੀ ਸੂਚਨਾ"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"ਤੁਸੀਂ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਨੂੰ ਰਿਕਾਰਡ ਕਰਨਾ ਬੰਦ ਕਰ ਦੇਵੋਗੇ"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"ਸਕ੍ਰੀਨ ਸਾਂਝੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"ਤੁਸੀਂ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਨੂੰ ਸਾਂਝਾ ਕਰਨਾ ਬੰਦ ਕਰ ਦੇਵੋਗੇ"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"ਸਕ੍ਰੀਨ \'ਤੇ ਕਾਸਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"ਤੁਸੀਂ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਨੂੰ ਕਾਸਟ ਕਰਨਾ ਬੰਦ ਕਰ ਦੇਵੋਗੇ"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਦਬਾਓ।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਦਬਾਓ।"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਜਾਰੀ ਰੱਖਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ।"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"ਚਿਹਰੇ ਰਾਹੀਂ ਅਣਲਾਕ ਕੀਤਾ ਗਿਆ। ਜਾਰੀ ਰੱਖਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ਪ੍ਰਮਾਣਿਤ ਹੋਇਆ"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ਪ੍ਰਮਾਣੀਕਰਨ ਰੱਦ ਕਰੋ"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ਹੋਰ ਵਿਕਲਪ"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ਕਵਿੱਕ ਸ਼ੇਅਰ ਅਤੇ Find My Device ਵਰਗੀਆਂ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਬਲੂਟੁੱਥ ਵਰਤਦੀਆਂ ਹਨ"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"ਬਲੂਟੁੱਥ ਕੱਲ੍ਹ ਸਵੇਰੇ ਚਾਲੂ ਹੋ ਜਾਵੇਗਾ"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ਆਡੀਓ ਨੂੰ ਸਾਂਝਾ ਕਰੋ"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"ਆਡੀਓ ਨੂੰ ਸਾਂਝਾ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"ਹੋਰ ਵਿਜੇਟ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ਵਿਜੇਟਾਂ ਨੂੰ ਵਿਉਂਤਬੱਧ ਕਰਨ ਲਈ ਦਬਾਈ ਰੱਖੋ"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ਵਿਜੇਟ ਵਿਉਂਤਬੱਧ ਕਰੋ"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ਵਿਜੇਟਾਂ ਨੂੰ ਵਿਉਂਤਬੱਧ ਕਰਨ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ਬੰਦ ਵਿਜੇਟ ਲਈ ਐਪ ਪ੍ਰਤੀਕ"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ਸਥਾਪਤ ਕੀਤੇ ਜਾ ਰਹੇ ਵਿਜੇਟ ਲਈ ਐਪ ਪ੍ਰਤੀਕ"</string>
     <string name="edit_widget" msgid="9030848101135393954">"ਵਿਜੇਟ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ਵਿਜੇਟ ਚੁਣੋ"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ਵਿਜੇਟ ਹਟਾਓ"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ਚੁਣੇ ਗਏ ਵਿਜੇਟ ਲਈ ਥਾਂ ਚੁਣੋ"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ਵਰਤੋਂਕਾਰ ਸਵਿੱਚ ਕਰੋ"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ਪੁੱਲਡਾਊਨ ਮੀਨੂ"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ਇਸ ਸੈਸ਼ਨ ਵਿਚਲੀਆਂ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟੇ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"ਹੁਣੇ ਸ਼ੁਰੂ ਕਰੋ"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"ਕੋਈ ਸੂਚਨਾ ਨਹੀਂ"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"ਕੋਈ ਨਵੀਂ ਸੂਚਨਾ ਨਹੀਂ ਹੈ"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"ਅਡੈਪਟਿਵ ਸੂਚਨਾਵਾਂ ਚਾਲੂ ਹਨ"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"ਘੱਟ ਸਮੇਂ \'ਚ ਕਈ ਸੂਚਨਾਵਾਂ ਮਿਲਣ \'ਤੇ, ਡੀਵਾਈਸ ਹੁਣ ਦੋ ਮਿੰਟਾਂ ਲਈ ਸਕ੍ਰੀਨ \'ਤੇ ਅਵਾਜ਼ ਅਤੇ ਪੌਪ-ਅੱਪ ਘਟਾ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ਬੰਦ ਕਰੋ"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ਪੁਰਾਣੀਆਂ ਸੂਚਨਾਵਾਂ ਦੇਖਣ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੇ ਮਾਂ-ਪਿਓ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਕੋਲ ਇਸ ਡੀਵਾਈਸ ਦੀ ਮਲਕੀਅਤ ਹੈ ਅਤੇ ਇਹ ਨੈੱਟਵਰਕ ਟਰੈਫ਼ਿਕ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ਕੋਈ ਅਲਾਰਮ ਸੈੱਟ ਨਹੀਂ"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"ਸਕ੍ਰੀਨ ਲਾਕ ਦਾਖਲ ਕਰੋ"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨੂੰ ਸਪਰਸ਼ ਕਰੋ। ਇਹ ਫ਼ੋਨ ਦੇ ਇੱਕ ਪਾਸੇ ਦਿੱਤਾ ਛੋਟਾ ਜਿਹਾ ਬਟਨ ਹੈ"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"ਪ੍ਰਮਾਣਿਤ ਕਰੋ"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"ਡੀਵਾਈਸ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ਵੱਲੋਂ ਵਰਤੋਂ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"ਹਾਲ ਹੀ ਵਿੱਚ <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ਵੱਲੋਂ ਵਰਤਿਆ ਗਿਆ"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"ਸਿਸਟਮ"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"ਸਿਸਟਮ ਸੰਬੰਧੀ ਕੰਟਰੋਲ"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"ਸਿਸਟਮ ਐਪਾਂ"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ਮਲਟੀਟਾਸਕਿੰਗ"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"ਹਾਲੀਆ ਐਪਾਂ"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"ਇਨਪੁੱਟ"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ਐਪ ਸ਼ਾਰਟਕੱਟ"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ਪਹੁੰਚਯੋਗਤਾ"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ਵਾਪਸ ਜਾਓ"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ਵਾਪਸ ਜਾਣ ਲਈ, ਟੱਚਪੈਡ \'ਤੇ ਕਿਤੇ ਵੀ ਤਿੰਨ ਉਂਗਲਾਂ ਦੀ ਵਰਤੋਂ ਕਰ ਕੇ ਖੱਬੇ ਜਾਂ ਸੱਜੇ ਪਾਸੇ ਵੱਲ ਸਵਾਈਪ ਕਰੋ।"</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ਟੱਚਪੈਡ \'ਤੇ ਤਿੰਨ ਉਂਗਲਾਂ ਨੂੰ ਸੱਜੇ ਅਤੇ ਖੱਬੇ ਪਾਸੇ ਵੱਲ ਲਿਜਾਂਦੇ ਹੋਏ ਦਿਖਾਇਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"ਡੀਵਾਈਸ ਦੀ ਸਕ੍ਰੀਨ \'ਤੇ ਪਿੱਛੇ ਜਾਣ ਵਾਲੇ ਇਸ਼ਾਰੇ ਲਈ ਐਨੀਮੇਸ਼ਨ ਦਿਖਾਇਆ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ਕੀ-ਬੋਰਡ ਬੈਕਲਾਈਟ"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$d ਵਿੱਚੋਂ %1$d ਪੱਧਰ"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ਹੋਮ ਕੰਟਰੋਲ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index c154fc9b..b679e82 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacja <xliff:g id="APPNAME">%1$s</xliff:g> wykryła ten zrzut ekranu."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Aplikacja <xliff:g id="APPNAME">%1$s</xliff:g> i inne aplikacje wykryły ten zrzut ekranu."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj do notatek"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Dołącz link"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Nagrywanie ekranu"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Przetwarzam nagrywanie ekranu"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Stałe powiadomienie o sesji rejestrowania zawartości ekranu"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Przestaniesz nagrywać treści z aplikacji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Udostępniam ekran"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Przestaniesz udostępniać treści z aplikacji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Przesyłam ekran"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Przestaniesz przesyłać treści z aplikacji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odblokowano rozpoznawaniem twarzy. Kliknij, aby kontynuować."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Twarz rozpoznana. Kliknij, aby kontynuować."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Twarz rozpoznana. Aby kontynuować, kliknij ikonę odblokowywania."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Odblokowano skanem twarzy. Kliknij, aby kontynuować."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Uwierzytelniono"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Anuluj uwierzytelnianie"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Więcej opcji"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Bluetootha używają funkcje takie jak szybkie udostępnianie czy Znajdź moje urządzenie"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth włączy się jutro rano"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Udostępnij dźwięk"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Udostępnia dźwięk"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> naładowania baterii"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Dźwięk"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Zestaw słuchawkowy"</string>
@@ -390,7 +395,7 @@
     <string name="thermal" msgid="6758074791325414831">"Termografia"</string>
     <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Tryb jednej ręki"</string>
     <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Urządzenia słuchowe"</string>
-    <string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Aktywny"</string>
+    <string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Aktywne"</string>
     <string name="quick_settings_hearing_devices_disconnected" msgid="8907061223998176187">"Rozłączono"</string>
     <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Urządzenia słuchowe"</string>
     <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Sparuj nowe urządzenie"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodaj więcej widżetów"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Przytrzymaj, aby dostosować widżety"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Dostosuj widżety"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Odblokuj, aby dostosować widżety"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacji z wyłączonym widżetem"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona aplikacji instalowanego widżetu"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Edytuj widżet"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"wybierz widżet"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"usuń widżet"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"umieść wybrany widżet"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Przełącz użytkownika"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Wszystkie aplikacje i dane w tej sesji zostaną usunięte."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Rozpocznij teraz"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Brak powiadomień"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Brak nowych powiadomień"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Powiadomienia adaptacyjne włączone"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Urządzenie zmniejszy teraz głośność i ograniczy wyskakujące okienka przez maks. 2 minuty, gdy w krótkim czasie otrzymujesz wiele powiadomień."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Wyłącz"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Odblokuj i zobacz starsze powiadomienia"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Tym urządzeniem zarządza Twój rodzic"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Twoja organizacja jest właścicielem tego urządzenia i może monitorować ruch w sieci"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Kliknij, aby uzyskać więcej informacji"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nie ustawiono alarmu"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"Wprowadź blokadę ekranu"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Dotknij czytnika linii papilarnych. To ten krótszy przycisk z boku telefonu"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Czytnik linii papilarnych"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"uwierzytelnij"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"otwórz urządzenie"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Używany przez aplikację <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Ostatnio używany przez aplikację <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Systemowe elementy sterujące"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplikacje systemowe"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Wielozadaniowość"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Ostatnie aplikacje"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Podzielony ekran"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Wprowadzanie"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Skróty do aplikacji"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ułatwienia dostępu"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Wróć"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Aby wrócić, przesuń 3 palcami w lewo lub w prawo w dowolnym miejscu touchpada."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"3 palce na touchpadzie poruszające się w prawo i w lewo"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Ekran urządzenia z animacją gestu cofania"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podświetlenie klawiatury"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Poziom %1$d z %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Sterowanie domem"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 2e64391..29b8452 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -103,11 +103,12 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"O app <xliff:g id="APPNAME">%1$s</xliff:g> detectou essa captura de tela."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e outros apps abertos detectaram essa captura de tela."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Incluir anotação"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Incluir link"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Gravador de tela"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processando gravação de tela"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação contínua para uma sessão de gravação de tela"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Iniciar gravação?"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Enquanto você grava, o Android tem acesso a todas as informações na tela ou reproduzidas no dispositivo. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Durante a gravação, o Android tem acesso às informações na tela ou reproduzidas no dispositivo. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Enquanto você grava um app, o Android tem acesso a todas as informações visíveis ou reproduzidas nele. Tenha cuidado com senhas, detalhes de pagamento, mensagens fotos, áudios e vídeos."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Iniciar gravação"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Gravar áudio"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Você vai parar de gravar o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Compartilhando a tela"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Você vai parar de compartilhar o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Transmitindo a tela"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Você vai parar de transmitir o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado pelo rosto. Pressione para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rosto reconhecido. Pressione para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Pressione o ícone para continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Desbloqueado pelo rosto. Toque para continuar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticação"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Mais opções"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Recursos como o Quick Share e o Encontre Meu Dispositivo usam Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"O Bluetooth será ativado amanhã de manhã"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Compartilhar áudio"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Compartilhando áudio"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Áudio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Fone de ouvido"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Adicione mais widgets"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantenha pressionado para personalizar widgets"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Desbloqueie para personalizar widgets"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ícone do app para widget desativado"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ícone do app para um widget que está sendo instalado"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selecionar widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remover widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"posicionar widget selecionado"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Trocar usuário"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu suspenso"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Sem notificações"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Nenhuma notificação nova"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notificações adaptáveis ativadas"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"O dispositivo agora diminui o volume e reduz os pop-ups na tela por até 2 minutos quando você recebe muitas notificações em pouco tempo."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desativar"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloqueie p/ acessar notificações antigas"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo é gerenciado pelo seu familiar responsável"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Sua organização é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
@@ -1041,7 +1056,7 @@
     <string name="accessibility_floating_button_action_remove_menu" msgid="6730432848162552135">"Remover"</string>
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"alternar"</string>
     <string name="accessibility_floating_button_action_edit" msgid="1688227814600463987">"Editar"</string>
-    <string name="quick_controls_title" msgid="6839108006171302273">"Controles do dispositivo"</string>
+    <string name="quick_controls_title" msgid="6839108006171302273">"Controles do disp."</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Escolha um app para adicionar controles"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controle adicionado.}one{# controle adicionado.}many{# de controles adicionados.}other{# controles adicionados.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para mais informações"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenhum alarme definido"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"inserir bloqueio de tela"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Toque no sensor de impressão digital. É o menor botão na lateral do smartphone"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de impressão digital"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"acessar o dispositivo"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Em uso pelo app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Usado recentemente pelo app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controles do sistema"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Apps do sistema"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitarefas"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Apps recentes"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Tela dividida"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Atalhos de apps"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Voltar"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para voltar, deslize para a esquerda ou direita usando 3 dedos em qualquer lugar do touchpad."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad mostrando 3 dedos deslizando para a direita e esquerda"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Tela do dispositivo mostrando a animação do gesto de volta"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Luz de fundo do teclado"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Automação residencial"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index ca0f171..cdec12e 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"A app <xliff:g id="APPNAME">%1$s</xliff:g> detetou esta captura de ecrã."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"A app <xliff:g id="APPNAME">%1$s</xliff:g> e outras apps abertas detetaram esta captura de ecrã."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Adicionar a uma nota"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Incluir link"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Gravador de ecrã"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"A processar a gravação de ecrã"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação persistente de uma sessão de gravação de ecrã"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Vai parar de gravar &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"A partilhar o ecrã"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Vai parar de partilhar &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"A transmitir o ecrã"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Vai parar de transmitir &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado com o rosto. Prima para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rosto reconhecido. Prima para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Prima ícone de desbloqueio para continuar"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Desbloqueado com o rosto. Toque para continuar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticação"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Mais opções"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funcionalidades como a Partilha rápida e o serviço Localizar o meu dispositivo usam o Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"O Bluetooth vai ser ativado amanhã de manhã"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Partilhar áudio"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"A partilhar áudio"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> de bateria"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Áudio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Ausc. c/ mic. integ."</string>
@@ -382,14 +387,14 @@
     <string name="qs_record_issue_start" msgid="2979831312582567056">"Iniciar"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"Parar"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Relatório de erro"</string>
-    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Que parte da experiência do disposit. foi afetada?"</string>
+    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Que parte do dispositivo foi afetada?"</string>
     <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Selecione o tipo de problema"</string>
     <string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"Gravação de ecrã"</string>
     <string name="performance" msgid="6552785217174378320">"Desempenho"</string>
     <string name="user_interface" msgid="3712869377953950887">"Interface do utilizador"</string>
     <string name="thermal" msgid="6758074791325414831">"Térmico"</string>
     <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Modo para uma mão"</string>
-    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Dispositivos auditivos"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Disp. auditivos"</string>
     <string name="quick_settings_hearing_devices_connected" msgid="6519069502397037781">"Ativos"</string>
     <string name="quick_settings_hearing_devices_disconnected" msgid="8907061223998176187">"Desligados"</string>
     <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Dispositivos auditivos"</string>
@@ -469,8 +474,9 @@
     <string name="cta_tile_button_to_dismiss" msgid="3377597875997861754">"Ignorar"</string>
     <string name="cta_label_to_edit_widget" msgid="6496885074209203756">"Adicionar, remover e reordenar widgets neste espaço"</string>
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Adicionar mais widgets"</string>
-    <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantenha premido para personalizar os widgets"</string>
+    <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantenha pressionado para personalizar os widgets"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Desbloqueie para personalizar widgets"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ícone da app do widget desativado"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ícone da app para um widget que está a ser instalado"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selecionar widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remover widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"posicionar widget selecionado"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Mudar utilizador"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu pendente"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todas as apps e dados desta sessão serão eliminados."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Começar agora"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Sem notificações"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Não existem novas notificações"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notificações adaptáveis ativas"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"O disp. diminui o vol. e reduz os pop-ups por até 2 min quando recebe muitas notificações seguidas."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desativar"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloqueie e veja notificações antigas"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo é gerido pelos teus pais"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"A sua entidade gere este dispositivo e pode monitorizar o tráfego de rede."</string>
@@ -621,7 +636,7 @@
     <string name="stream_voice_call" msgid="7468348170702375660">"Chamada"</string>
     <string name="stream_system" msgid="7663148785370565134">"Sistema"</string>
     <string name="stream_ring" msgid="7550670036738697526">"Toque"</string>
-    <string name="stream_music" msgid="2188224742361847580">"Suporte de dados"</string>
+    <string name="stream_music" msgid="2188224742361847580">"Multimédia"</string>
     <string name="stream_alarm" msgid="16058075093011694">"Alarme"</string>
     <string name="stream_notification" msgid="7930294049046243939">"Notificação"</string>
     <string name="stream_bluetooth_sco" msgid="6234562365528664331">"Bluetooth"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para obter mais informações"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenhum alarme definido"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"introduzir bloqueio de ecrã"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Toque no sensor de impressões digitais. É o botão mais pequeno na parte lateral do telemóvel"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de impressões digitais"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"entrar no dispositivo"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Em utilização pela app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Usado recentemente pela app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controlos do sistema"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Apps do sistema"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Execução de várias tarefas em simultâneo"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Apps recentes"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Ecrã dividido"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Atalhos de apps"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Voltar"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para retroceder, deslize rapidamente para a esquerda ou direita com três dedos em qualquer parte do touchpad."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad a mostrar três dedos a moverem-se para a direita e esquerda"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Ecrã de dispositivo a mostrar uma animação do gesto para retroceder"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Luz do teclado"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Controlos domésticos"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 2e64391..29b8452 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -103,11 +103,12 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"O app <xliff:g id="APPNAME">%1$s</xliff:g> detectou essa captura de tela."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> e outros apps abertos detectaram essa captura de tela."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Incluir anotação"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Incluir link"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Gravador de tela"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processando gravação de tela"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificação contínua para uma sessão de gravação de tela"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Iniciar gravação?"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Enquanto você grava, o Android tem acesso a todas as informações na tela ou reproduzidas no dispositivo. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Durante a gravação, o Android tem acesso às informações na tela ou reproduzidas no dispositivo. Portanto, tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Enquanto você grava um app, o Android tem acesso a todas as informações visíveis ou reproduzidas nele. Tenha cuidado com senhas, detalhes de pagamento, mensagens fotos, áudios e vídeos."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Iniciar gravação"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Gravar áudio"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Você vai parar de gravar o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Compartilhando a tela"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Você vai parar de compartilhar o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Transmitindo a tela"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Você vai parar de transmitir o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Desbloqueado pelo rosto. Pressione para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Rosto reconhecido. Pressione para continuar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Pressione o ícone para continuar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Desbloqueado pelo rosto. Toque para continuar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticação"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Mais opções"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Recursos como o Quick Share e o Encontre Meu Dispositivo usam Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"O Bluetooth será ativado amanhã de manhã"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Compartilhar áudio"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Compartilhando áudio"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Bateria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Áudio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Fone de ouvido"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Adicione mais widgets"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantenha pressionado para personalizar widgets"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Desbloqueie para personalizar widgets"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ícone do app para widget desativado"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ícone do app para um widget que está sendo instalado"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Editar widget"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selecionar widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"remover widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"posicionar widget selecionado"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Trocar usuário"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menu suspenso"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Todos os apps e dados nesta sessão serão excluídos."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Iniciar agora"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Sem notificações"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Nenhuma notificação nova"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notificações adaptáveis ativadas"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"O dispositivo agora diminui o volume e reduz os pop-ups na tela por até 2 minutos quando você recebe muitas notificações em pouco tempo."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Desativar"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Desbloqueie p/ acessar notificações antigas"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Este dispositivo é gerenciado pelo seu familiar responsável"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Sua organização é dona deste dispositivo e pode monitorar o tráfego de rede"</string>
@@ -1041,7 +1056,7 @@
     <string name="accessibility_floating_button_action_remove_menu" msgid="6730432848162552135">"Remover"</string>
     <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"alternar"</string>
     <string name="accessibility_floating_button_action_edit" msgid="1688227814600463987">"Editar"</string>
-    <string name="quick_controls_title" msgid="6839108006171302273">"Controles do dispositivo"</string>
+    <string name="quick_controls_title" msgid="6839108006171302273">"Controles do disp."</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Escolha um app para adicionar controles"</string>
     <string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controle adicionado.}one{# controle adicionado.}many{# de controles adicionados.}other{# controles adicionados.}}"</string>
     <string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Toque para mais informações"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nenhum alarme definido"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"inserir bloqueio de tela"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Toque no sensor de impressão digital. É o menor botão na lateral do smartphone"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor de impressão digital"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"autenticar"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"acessar o dispositivo"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Em uso pelo app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Usado recentemente pelo app <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistema"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Controles do sistema"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Apps do sistema"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitarefas"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Apps recentes"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Tela dividida"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Entrada"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Atalhos de apps"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Acessibilidade"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Voltar"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para voltar, deslize para a esquerda ou direita usando 3 dedos em qualquer lugar do touchpad."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad mostrando 3 dedos deslizando para a direita e esquerda"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Tela do dispositivo mostrando a animação do gesto de volta"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Luz de fundo do teclado"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nível %1$d de %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Automação residencial"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 36457fd..4da9b70 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> a detectat această captură de ecran."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> și alte aplicații deschise au detectat această captură de ecran."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Adaugă în notă"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Include linkul"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Recorder pentru ecran"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Se procesează înregistrarea"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificare în curs pentru o sesiune de înregistrare a ecranului"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Nu vei mai înregistra &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Se permite accesul la ecran"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Nu vei mai permite accesul la &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Se proiectează ecranul"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Nu vei mai proiecta &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"S-a deblocat cu ajutorul feței. Apasă pentru a continua."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Chipul a fost recunoscut. Apasă pentru a continua."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Chip recunoscut. Apasă pictograma Deblocare ca să continui."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"S-a deblocat folosind fața. Atinge pentru a continua."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentificat"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Anulează autentificarea"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Mai multe opțiuni"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funcții precum Quick Share și Găsește-mi dispozitivul folosesc Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth se va activa mâine dimineață"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Trimite audio"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Se permite accesul la conținutul audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Nivelul bateriei: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Căști"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Adaugă mai multe widgeturi"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Apasă lung pentru a personaliza widgeturi"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizează widgeturile"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Deblochează ca să personalizezi widgeturi"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Pictograma aplicației pentru widgetul dezactivat"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Pictograma aplicației pentru un widget care se instalează"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Editează widgetul"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"selectează un widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"elimină widgetul"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"plasează widgetul selectat"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Schimbă utilizatorul"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"meniu vertical"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Toate aplicațiile și datele din această sesiune vor fi șterse."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Începe acum"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Nicio notificare"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Nicio notificare nouă"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Notificări adaptabile activate"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Dispozitivul reduce acum volumul și numărul de ferestre pop-up de pe ecran timp de până la două minute când primești multe notificări într-un timp scurt"</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Dezactivează"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Deblochează ca să vezi notificări vechi"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Dispozitivul este gestionat de unul dintre părinți"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizația ta deține acest dispozitiv și poate monitoriza traficul de rețea"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Atinge pentru mai multe informații"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nicio alarmă setată"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"intră în blocarea ecranului"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Atinge senzorul de amprentă. Acesta este butonul mai scurt de pe partea laterală a telefonului"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Senzor de amprentă"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentifică-te"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"Accesează dispozitivul"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Se folosește pentru <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Folosit recent de <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Comenzile sistemului"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplicații de sistem"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Aplicații recente"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Ecran împărțit"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Intrare"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Comenzi rapide pentru aplicații"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accesibilitate"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Înapoi"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Pentru a reveni, glisează spre stânga sau spre dreapta cu trei degete oriunde pe touchpad."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad cu trei degete care se mișcă spre dreapta și spre stânga"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Ecran de dispozitiv cu o animație pentru gestul Înapoi"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Iluminarea din spate a tastaturii"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivelul %1$d din %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Comenzi pentru locuință"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index fe0e8db..4e28df5 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"Приложение \"<xliff:g id="APPNAME">%1$s</xliff:g>\" обнаружило создание скриншота."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Приложение \"<xliff:g id="APPNAME">%1$s</xliff:g>\" и другие запущенные продукты обнаружили создание скриншота."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Добавить в заметку"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Добавить ссылку"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Запись видео с экрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обработка записи с экрана…"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Текущее уведомление для записи видео с экрана"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Запись в приложении &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; будет прекращена."</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Демонстрация экрана"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Демонстрация экрана приложения &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; будет прекращена."</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Трансляция экрана"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Трансляция из приложения &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; будет прекращена."</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Разблокировано сканированием лица. Нажмите, чтобы продолжить."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лицо распознано. Нажмите, чтобы продолжить."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицо распознано. Нажмите на значок разблокировки."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Сканирование лица выполнено. Нажмите, чтобы продолжить."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аутентификация выполнена"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Отмена распознавания лица"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Ещё"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Bluetooth используется в таких функциях и сервисах, как \"Быстрая отправка\" и \"Найти устройство\""</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth включится завтра утром"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Отправить аудио"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Отправка аудио"</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>
@@ -397,7 +402,7 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Нажмите, чтобы подключить новое устройство"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Не удалось обновить набор настроек."</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Набор настроек"</string>
-    <string name="live_caption_title" msgid="8916875614623730005">"Автоматические субтитры"</string>
+    <string name="live_caption_title" msgid="8916875614623730005">"Автосубтитры"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Разблокировать микрофон устройства?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Разблокировать камеру устройства?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Разблокировать камеру и микрофон устройства?"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Добавить виджеты"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Нажмите и удерживайте, чтобы настроить виджеты."</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Настроить виджеты"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Чтобы настроить виджеты, разблокируйте устройство."</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Значок приложения для отключенного виджета"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Значок приложения для устанавливаемого виджета"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Изменить виджет"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"выбрать виджет"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"удалить виджет"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"разместить выбранный виджет"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Сменить пользователя."</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"раскрывающееся меню"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Все приложения и данные этого профиля будут удалены."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Начать"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Нет уведомлений."</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Новых уведомлений нет"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Адаптивные уведомления включены"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Если за короткий промежуток времени придет много уведомлений, громкость звуков и количество всплывающих окон будут уменьшены на срок до двух минут."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Отключить"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Разблокируйте, чтобы увидеть уведомления"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Устройством управляет один из родителей."</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Ваша организация управляет этим устройством и может отслеживать сетевой трафик"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Нажмите, чтобы узнать больше."</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Нет будильников"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"разблокировать экран"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Коснитесь сканера отпечатков пальцев. Это самая короткая кнопка сбоку на телефоне."</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сканер отпечатков пальцев"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"выполнить аутентификацию"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"указать устройство"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Сейчас используется приложением \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Недавно использовалось приложением \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Система"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Управление системой"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системные приложения"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Многозадачность"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Недавние приложения"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Разделение экрана"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Ввод"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Ярлыки приложений"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Специальные возможности"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Чтобы вернуться, проведите тремя пальцами влево или вправо по сенсорной панели."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Три пальца двигаются вправо и влево по сенсорной панели"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"На экране устройства показана анимация для жеста \"Назад\""</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Подсветка клавиатуры"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Уровень %1$d из %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Управление домом"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 8357008..bd9488d 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> මෙම තිර රුව අනාවරණය කර ගෙන ඇත."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> සහ අනෙකුත් විවෘත යෙදුම් මෙම තිර රුව අනාවරණය කර ගෙන ඇත."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"සටහනට එක් කරන්න"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"සබැඳිය ඇතුළත් කරන්න"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"තිර රෙකෝඩරය"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"තිර පටිගත කිරීම සකසමින්"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"තිර පටිගත කිරීමේ සැසියක් සඳහා කෙරෙන දැනුම් දීම"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"ඔබ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; පටිගත කිරීම නතර කරනු ඇත"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"තිරය ​​බෙදා ගැනීම"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"ඔබ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; බෙදා ගැනීම නතර කරනු ඇත"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"විකාශ තිරය"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"ඔබ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; විකාශය නතර කරනු ඇත"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"මුහුණ මගින් අගුලු හරින ලදි. ඉදිරියට යාමට ඔබන්න."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"මුහුණ හඳුනා ගන්නා ලදි. ඉදිරියට යාමට ඔබන්න."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"මුහුණ හඳුනා ගන්නා ලදි. ඉදිරියට යාමට අගුලු හැරීමේ නිරූපකය ඔබන්න."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"මුහුණ මගින් අගුළු හරින ලදි. ඉදිරියට යාමට තට්ටු කරන්න."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"සත්‍යාපනය විය"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"සත්‍යාපනය අවලංගු කරන්න"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"තවත් විකල්ප"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ඉක්මන් බෙදා ගැනීම සහ මගේ උපාංගය සෙවීම වැනි විශේෂාංග බ්ලූටූත් භාවිත කරයි"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"බ්ලූටූත් හෙට උදේ සක්‍රීය වෙයි"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ශ්‍රව්‍ය බෙදා ගන්න"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"ශ්‍රව්‍ය බෙදා ගැනීම"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"තවත් විජට් එක් කරන්න"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"විජට් අභිරුචිකරණය කිරීමට දිගු ඔබන්න"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"විජට්ටු අභිරුචි කරන්න"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"විජට් අභිරුචිකරණය කිරීමට අගුළු හරින්න"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"අබල කළ විජට් සඳහා යෙදුම් නිරූපකය"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"විජට්ටුවක් සඳහා ස්ථාපන කරනු ලබන යෙදුම් නිරූපකය"</string>
     <string name="edit_widget" msgid="9030848101135393954">"විජට්ටු සංස්කරණ කරන්න"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"විජට්ටුව තෝරන්න"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"විජට්ටුව ඉවත් කරන්න"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"තෝරන ලද විජට්ටුව තබන්න"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"පරිශීලක මාරුව"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"නිපතන මෙනුව"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"මෙම සැසියේ සියළුම යෙදුම් සහ දත්ත මකාවී."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"දැන් අරඹන්න"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"දැනුම්දීම් නැත"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"නව දැනුම්දීම් නැත"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"අනුවර්තන දැනුම්දීම් ක්‍රියාත්මකයි"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"ඔබේ උපාංගය දැන් ශබ්දය අඩු කරන අතර ඔබට කෙටි කාල පරාසයක් තුළ බොහෝ දැනුම්දීම් ලැබෙන විට තිරය මත උත්පතන විනාඩි දෙකක් දක්වා අඩු කරයි."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ක්‍රියාවිරහිත කරන්න"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"පැරණි දැනුම්දීම් බැලීමට අගුළු හරින්න"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"මෙම උපාංගය ඔබගේ මාපියන්ගෙන් අයකු විසින් කළමනාකරණය කෙරේ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ඔබේ සංවිධානයට මෙම උපාංගය අයිති අතර ජාල තදබදය නිරීක්ෂණය කළ හැකිය"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"තවත් තොරතුරු සඳහා තට්ටු කරන්න"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"එලාම සකසා නැත"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"තිර අගුල ඇතුළු කරන්න"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"ඇඟිලි සලකුණු සංවේදකය ස්පර්ශ කරන්න. එය දුරකථනයේ පැත්තේ ඇති කෙටි බොත්තමයි"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ඇඟිලි සලකුණු සංවේදකය"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"සත්‍යාපනය කරන්න"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"උපාංගය ඇතුළු කරන්න"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> භාවිත කරයි (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> විසින් මෑතකදී භාවිත කරන ලදි (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"පද්ධතිය"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"පද්ධති පාලන"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"පද්ධති යෙදුම්"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"බහුකාර්ය"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"මෑත යෙදුම්"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"බෙදුම් තිරය"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"ආදානය"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"යෙදුම් කෙටිමං"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ප්‍රවේශ්‍යතාව"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ආපස්සට යන්න"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"ආපසු යාමට, ස්පර්ශ පුවරුවේ ඕනෑම තැනක ඇඟිලි තුනක් භාවිතයෙන් වමට හෝ දකුණට ස්වයිප් කරන්න."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ඇඟිලි තුනක් දකුණට සහ වමට චලනය වන බව පෙන්වන ස්පර්ශක පුවරුව"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"පසුපස අභිනය සඳහා සජීවිකරණය පෙන්වන උපාංග තිරය"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"යතුරු පුවරු පසු ආලෝකය"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dන් %1$d වැනි මට්ටම"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"නිවෙස් පාලන"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 148b390..796b2e1 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikácia <xliff:g id="APPNAME">%1$s</xliff:g> zaznamenala túto snímku obrazovky."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> a ďalšie otvorené aplikácie zaznamenali túto snímku obrazovky."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Pridať do poznámky"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Zahrnúť odkaz"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Rekordér obrazovky"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Spracúva sa záznam obrazovky"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Zobrazuje sa upozornenie týkajúce sa relácie záznamu obrazovky"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Prestante zaznamenávať obsah aplikácie &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Zdieľa sa obrazovka"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Prestanete zdieľať obsah aplikácie &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Prenáša sa obrazovka"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Prestanete prenášať obsah aplikácie &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odomknuté tvárou. Pokračujte stlačením."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Tvár bola rozpoznaná. Pokračujte stlačením."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Tvár bola rozpoznaná. Pokračujte stlačením ikony odomknutia"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Odomknuté tvárou. Pokračujte klepnutím."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Overené"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Zrušiť overenie"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Ďalšie možnosti"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funkcie ako Quick Share a Nájdi moje zariadenie používajú Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth sa zapne zajtra ráno"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Zdieľať zvuk"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Zdieľa sa zvuk"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Batéria: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Zvuk"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Náhlavná súprava"</string>
@@ -378,8 +383,8 @@
     <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Rekordér obrazovky"</string>
     <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Začať"</string>
     <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Ukončiť"</string>
-    <string name="qs_record_issue_label" msgid="8166290137285529059">"Problém s nahrávaním"</string>
-    <string name="qs_record_issue_start" msgid="2979831312582567056">"Začnite"</string>
+    <string name="qs_record_issue_label" msgid="8166290137285529059">"Nahrať problém"</string>
+    <string name="qs_record_issue_start" msgid="2979831312582567056">"Začať"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"Zastavte"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Hlásenie chyby"</string>
     <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Čo v zariadení bolo ovplyvnené?"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Pridať ďalšie miniaplikácie"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Miniaplikácie prispôsobíte dlhým stlačením"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prispôsobiť miniaplikácie"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Odomknite a prispôsobte si miniaplikácie"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona deaktivovanej miniaplikácie"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona inštalovanej miniaplikácie"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Upraviť miniaplikáciu"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vybrať miniaplikáciu"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"odstrániť miniaplikáciu"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"prepnúť vybranú miniaplikáciu"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Prepnutie používateľa"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rozbaľovacia ponuka"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Všetky aplikácie a údaje v tejto relácii budú odstránené."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Spustiť"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Žiadne upozornenia"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Žiadne nové upozornenia"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptívne upozornenia sú zap."</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Zariadenie teraz zníži hlasitosť a zredukuje vyskakovacie okná na obrazovke na dve až štyri minúty, keď dostanete veľa upozornení v krátkom čase."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Vypnúť"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Odomknutím zobrazíte staršie upozornenia"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Toto zariadenie spravuje tvoj rodič"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša organizácia spravuje toto zariadenie a môže sledovať sieťovú premávku"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Klepnutím si zobrazíte ďalšie informácie"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Žiadny budík"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"zadať zámku obrazovky"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Dotknite sa senzora odtlačkov prstov. Ide o kratšie tlačidlo na boku telefónu."</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Senzor odtlačkov prstov"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"overte"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"vstúpte do zariadenia"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Využíva <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nedávno využila aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Systém"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Ovládanie systému"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Systémové aplikácie"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multitasking"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nedávne aplikácie"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Rozdelená obrazovka"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Vstup"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Odkazy do aplikácií"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Dostupnosť"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Prejsť späť"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Ak chcete prejsť späť, potiahnite doľava alebo doprava troma prstami kdekoľvek na touchpade."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Tri prsty na touchpade pohybujúce sa doprava a doľava"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Obrazovka zariadenia, na ktorej je animácia gesta späť"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Podsvietenie klávesnice"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. úroveň z %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Ovládanie domácnosti"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 489551d..2b8d8af 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"Aplikacija <xliff:g id="APPNAME">%1$s</xliff:g> je zaznala ta posnetek zaslona."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> in druge odprte aplikacije so zaznale ta posnetek zaslona."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Dodaj v zapisek"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Vključi povezavo"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Snemalnik zaslona"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obdelava videoposnetka zaslona"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Nenehno obveščanje o seji snemanja zaslona"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Ustavili boste snemanje aplikacije &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Deljenje zaslona"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Ustavili boste deljenje aplikacije &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Predvajanje vsebine zaslona"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Ustavili boste predvajanje aplikacije &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Odklenjeno z obrazom. Pritisnite za nadaljevanje."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Obraz je prepoznan. Pritisnite za nadaljevanje."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Obraz je prepoznan. Za nadaljevanje pritisnite ikono za odklepanje."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Odklenjeno z obrazom. Dotaknite se, če želite nadaljevati."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Preverjena pristnost"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Prekliči preverjanje pristnosti"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Več možnosti"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funkcije, kot sta Hitro deljenje in Poišči mojo napravo, uporabljajo Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth se bo vklopil jutri zjutraj"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Deli zvok"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Poteka deljenje zvoka"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Baterija na <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Zvok"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Slušalke z mikrofonom"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Dodajte več pripomočkov"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pridržite za prilagajanje pripomočkov"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Prilagajanje pripomočkov"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Odklenite, če želite prilagoditi pripomočke"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona aplikacije za onemogočen pripomoček"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona aplikacije za nameščanje pripomočka"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Urejanje pripomočka"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"izberite pripomoček"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"odstranitev pripomočka"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"postavitev izbranega pripomočka"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Preklop med uporabniki"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"spustni meni"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Vse aplikacije in podatki v tej seji bodo izbrisani."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Začni zdaj"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Ni obvestil"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Ni novih obvestil"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Prilagodljiva obvestila so vklopljena"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Naprava za do dve minuti zmanjša glasnost in število pojavnih elementov na zaslonu, ko v kratkem času prejmete veliko obvestil."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Izklopi"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Odklenite za ogled starejših obvestil"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"To napravo upravlja tvoj starš"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Vaša organizacija je lastnica te naprave in lahko nadzira omrežni promet"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dotaknite se za več informacij"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ni nastavljenih alarmov"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"odklenite zaslon"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Dotaknite se tipala prstnih odtisov. To je krajši gumb ob strani telefona."</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Tipalo prstnih odtisov"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"preverjanje pristnosti"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"vstop v napravo"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Uporablja aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Nedavno uporabljala aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistemski kontrolniki"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistemske aplikacije"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Večopravilnost"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Nedavne aplikacije"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Razdeljen zaslon"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Vnos"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Bližnjice do aplikacij"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Dostopnost"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Nazaj"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Za pomik nazaj povlecite levo ali desno s tremi prsti kjer koli na sledilni ploščici."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Sledilna ploščica s tremi prsti, ki se premikajo desno in levo"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Zaslon naprave z animacijo, ki prikazuje potezo za pomik nazaj"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Osvetlitev tipkovnice"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Stopnja %1$d od %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrolniki za dom"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 5b74b1e..27d2c6c 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> zbuloi këtë pamje ekrani."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> dhe aplikacionet e tjera të hapura zbuluan këtë pamje ekrani."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Shto te shënimi"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Përfshi lidhjen"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Regjistruesi i ekranit"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Regjistrimi i ekranit po përpunohet"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Njoftim i vazhdueshëm për një seancë regjistrimi të ekranit"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Do të ndalosh regjistrimin me &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekrani po ndahet"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Do të ndalosh ndarjen e &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Po transmeton ekranin"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Do të ndalosh transmetimin e &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"U shkyç me fytyrë. Shtyp për të vazhduar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Fytyra u njoh. Shtyp për të vazhduar."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Fytyra u njoh. Shtyp ikonën e shkyçjes për të vazhduar."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"U shkyç me fytyrë. Trokit për të vazhduar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"U vërtetua"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Anulo vërtetimin"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Opsione të tjera"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Veçoritë e tilla si \"Ndarja e shpejtë\" dhe \"Gjej pajisjen time\" përdorin Bluetooth-in"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth-i do të aktivizohet nesër në mëngjes"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Ndaj audion"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Audioja po ndahet"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> bateri"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Kufje me mikrofon"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Shto miniaplikacione të tjera"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Shtyp gjatë për të personalizuar miniaplikacionet"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizo miniaplikacionet"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Shkyç për të personalizuar miniaplikacionet"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Ikona e aplikacionit për miniaplikacionin e çaktivizuar"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ikona e aplikacionit për një miniaplikacion që po instalohet"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Modifiko miniaplikacionin"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"zgjidh miniaplikacionin"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"hiq miniaplikacionin"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"vendos miniaplikacionin e zgjedhur"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Ndërro përdorues"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menyja me tërheqje poshtë"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Të gjitha aplikacionet dhe të dhënat në këtë sesion do të fshihen."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Fillo tani"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Asnjë njoftim"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Nuk ka njoftime të reja"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Njoftimet me përshtatje janë aktive"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Pajisja jote tani ul volumin dhe zvogëlon numrin e dritareve kërcyese në ekran për deri në dy minuta kur ti merr shumë njoftime në një periudhë të shkurtër kohe."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Çaktivizo"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Shkyç për të parë njoftimet e vjetra"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Kjo pajisje menaxhohet nga prindi yt"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organizata jote e zotëron këtë pajisje dhe mund të monitorojë trafikun e rrjetit"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Trokit për më shumë informacione"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nuk është caktuar asnjë alarm"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"hyr te kyçja e ekranit"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Prek sensorin e gjurmës së gishtit. Është butoni më i shkurtër në pjesën anësore të telefonit"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensori i gjurmës së gishtit"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"për ta vërtetuar"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"për të hyrë në pajisje"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Në përdorim nga <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Përdorur së fundi nga <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistemi"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Kontrollet e sistemit"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Aplikacionet e sistemit"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Kryerja e shumë detyrave"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Aplikacionet e fundit"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Ekrani i ndarë"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Hyrja"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Shkurtoret e aplikacionit"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Qasshmëria"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Kthehu prapa"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Për t\'u kthyer prapa, rrëshqit shpejt majtas ose djathtas duke përdorur tre gishta kudo në bllokun me prekje."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Blloku me prekje që tregon tre gishta që lëvizin djathtas dhe majtas"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Ekrani i pajisjes që tregon një animacion për gjestin e kthimit prapa"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Drita e sfondit e tastierës"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Niveli: %1$d nga %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Kontrollet e shtëpisë"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 1877274..a1ede04 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"Апликација <xliff:g id="APPNAME">%1$s</xliff:g> је открила овај снимак екрана."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> и друге отворене апликације су откриле овај снимак екрана."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Додај у белешку"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Уврсти линк"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Снимач екрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обрађујемо видео снимка екрана"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Обавештење о сесији снимања екрана је активно"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Зауставићете снимање за: &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Екран се дели"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Зауставићете дељење за: &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Пребацује се екран"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Зауставићете пребацивање за: &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Откључано је лицем. Притисните да бисте наставили."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Лице је препознато. Притисните да бисте наставили."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лице препознато. Притисните икону откључавања за наставак."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Откључано је лицем. Додирните да бисте наставили."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Идентитет је потврђен"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Откажите потврду идентитета"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Још опција"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Функције као што су Quick Share и Пронађи мој уређај користе Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ће се укључити сутра ујутру"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Дели звук"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Дели се звук"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Додајте још виџета"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Дуги притисак за прилагођавање виџета"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Прилагоди виџете"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Откључајте да бисте прилагодили виџете"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Икона апликације за онемогућен виџет"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Икона апликације за виџет који се инсталира"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Измени виџет"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"изаберите виџет"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"уклоните виџет"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"поставите изабрани виџет"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Замени корисника"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"падајући мени"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Све апликације и подаци у овој сесији ће бити избрисани."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Започни"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Нема обавештења"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Нема нових обавештења"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Прилаг. обавештења су укључена"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Уређај сада смањује звук и број искачућих прозора на екрану до 2 минута кад примите много обавештења у кратком року."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Искључи"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Откључајте за старија обавештења"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Овим уређајем управља родитељ"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Организација је власник уређаја и може да надгледа мрежни саобраћај"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Додирните за више информација"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Није подешен"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"унесите откључавање екрана"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Додирните сензор за отисак прста. То је краће дугме на бочној страни телефона"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сензор за отисак прста"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"потврдите идентитет"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"унесите уређај"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Користе <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Недавно користила апликација <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Систем"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Системске контроле"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системске апликације"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Обављање више задатака истовремено"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Недавне апликације"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Подељени екран"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Унос"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Пречице за апликације"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Приступачност"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Да бисте се вратили, превуците улево или удесно са три прста било где на тачпеду."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Тачпед са приказом три прста који се померају удесно и улево"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Екран уређаја са приказом анимације покрета за назад"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Позадинско осветљење тастатуре"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%1$d. ниво од %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Контроле за дом"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index dc4dea1..1824a40 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> identifierade skärmbilden."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> och andra öppna appar identifierade skärmbilden."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Lägg till i anteckning"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Inkludera länk"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Skärminspelare"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandlar skärminspelning"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Avisering om att skärminspelning pågår"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Du slutar att spela in &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Skärmen delas"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Du slutar att dela &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Skärmen castas"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Du slutar att casta &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Upplåst med ansiktslås. Tryck för att fortsätta."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ansiktet har identifierats. Tryck för att fortsätta."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansiktet har identifierats. Tryck på ikonen lås upp."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Upplåst med ansiktslås. Tryck för att fortsätta."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentiserad"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Avbryt autentiseringen"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Fler alternativ"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Funktioner som Snabbdelning och Hitta min enhet använder Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth aktiveras i morgon bitti"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Dela ljud"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Delar ljud"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> batteri"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Ljud"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Lägg till fler widgetar"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Tryck länge för att anpassa widgetar"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Anpassa widgetar"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Lås upp för att anpassa widgetar"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Appikon för inaktiverad widget"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Appikon för en widget som installeras"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Redigera widget"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"välj widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ta bort widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"placera vald widget"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Byt användare"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"rullgardinsmeny"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Alla appar och data i denna session kommer att raderas."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Starta nu"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Inga aviseringar"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Det finns inga nya aviseringar"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Anpassade aviseringar är på"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Om du får många aviseringar tätt inpå varandra sänker nu enheten volymen och minskar antalet popuper i upp till två minuter."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Inaktivera"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Lås upp för att se äldre aviseringar"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Den här enheten hanteras av din förälder"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Organisationen äger den här enheten och kan övervaka nätverkstrafiken"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Tryck för mer information"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Inget inställt alarm"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"ange skärmlåset"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Tryck på fingeravtryckssensorn. Det är den mindre knappen på sidan av telefonen"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Fingeravtryckssensor"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentisera"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"ange enhet"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Används av <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Användes nyligen av <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Systeminställningar"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Systemappar"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multikörning"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Senaste apparna"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Delad skärm"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Ingång"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Genvägar till appar"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Tillgänglighet"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Tillbaka"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Gå tillbaka genom att svepa åt vänster eller höger med tre fingrar var som helst på styrplattan."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Tre fingrar rör sig åt höger och vänster på en styrplatta"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"En enhetsskärm visar en animation för rörelsen Tillbaka"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Bakgrundsbelysning för tangentbord"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Nivå %1$d av %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Hemstyrning"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 7bfef43..a01dd71 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -103,11 +103,12 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> imetambua picha hii ya skrini."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> na zingine zinazotumika zimetambua picha hii ya skrini."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Ongeza kwenye dokezo"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Jumuisha kiungo"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Kinasa Skrini"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Inachakata rekodi ya skrini"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Arifa inayoendelea ya kipindi cha kurekodi skrini"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Ungependa kuanza kurekodi?"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Unaporekodi, Android inaweza kufikia kitu chochote kitakachoonekana kwenye skrini yako au kuchezwa kwenye kifaa chako. Kwa hivyo kuwa mwangalifu na vitu kama vile manenosiri, maelezo ya malipo, ujumbe, picha na sauti na video."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Unaporekodi, Android inaweza kufikia kitu chochote kitakachoonekana kwenye skrini yako au kuchezwa kwenye kifaa chako. Kwa hivyo kuwa mwangalifu na vitu kama vile manenosiri, maelezo ya malipo, ujumbe, picha, sauti na video."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Unaporekodi programu, Android inaweza kufikia kitu chochote kitakachoonekana au kuchezwa kwenye programu hiyo. Kwa hivyo kuwa mwangalifu na vitu kama vile manenosiri, maelezo ya malipo, ujumbe, picha na sauti na video."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Anza kurekodi"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Rekodi sauti"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Utaacha kurekodi maudhui ya &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Inaruhusu ufikiaji kwenye skrini"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Utakomesha ufikiaji wa maudhui ya &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Inatuma skrini"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Utaacha kutuma maudhui ya &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Imefunguliwa kwa kutumia uso wako. Bonyeza ili uendelee."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Uso umetambuliwa. Bonyeza ili uendelee."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Uso umetambuliwa. Bonyeza aikoni ya kufungua ili uendelee."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Imefunguliwa kwa kutumia uso wako. Gusa ili uendelee."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Umethibitishwa"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Ghairi Uthibitishaji"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Chaguo Zaidi"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Vipengele kama vile Kutuma Haraka na Tafuta Kifaa Changu hutumia Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth itawaka kesho asubuhi"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Sikiliza pamoja na wengine"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Mnasikiliza pamoja"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Chaji ya betri ni <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Sauti"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Vifaa vya sauti"</string>
@@ -378,7 +383,7 @@
     <string name="quick_settings_screen_record_label" msgid="8650355346742003694">"Rekodi ya skrini"</string>
     <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Anza kurekodi"</string>
     <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Acha kurekodi"</string>
-    <string name="qs_record_issue_label" msgid="8166290137285529059">"Hitilafu ya Kurekodi"</string>
+    <string name="qs_record_issue_label" msgid="8166290137285529059">"Rekodi Hitilafu"</string>
     <string name="qs_record_issue_start" msgid="2979831312582567056">"Anza"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"Simamisha"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"Ripoti ya Hitilafu"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Weka wijeti zingine"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Bonyeza kwa muda mrefu uweke mapendeleo ya wijeti"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Badilisha wijeti upendavyo"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Fungua ili ubadilishe wijeti upendavyo"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Aikoni ya programu ya wijeti iliyozimwa"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Aikoni ya programu ya wijeti inayowekwa"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Badilisha wijeti"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"chagua wijeti"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ondoa wijeti"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"weka wijeti uliyochagua"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Badili mtumiaji"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"menyu ya kuvuta chini"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Data na programu zote katika kipindi hiki zitafutwa."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Anza sasa"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Hakuna arifa"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Hakuna arifa mpya"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Umewasha arifa zinazojirekebisha"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Sasa kifaa chako kinapunguza sauti na idadi ya madirisha ibukizi kwenye skrini kwa hadi dakika mbili ukipokea arifa nyingi kwa muda mfupi."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Zima"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Fungua ili uone arifa za zamani"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Kifaa hiki kinadhibitiwa na mzazi wako"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Shirika lako linamiliki kifaa hiki na huenda likafuatilia trafiki ya mtandao"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Gusa ili upate maelezo zaidi"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Hujaweka kengele"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"weka kifunga skrini"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Gusa kitambuzi cha alama ya kidole. Ni kitufe kifupi zaidi kilicho pembeni mwa simu"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Kitambua alama ya kidole"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"thibitisha"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"weka kifaa"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Inatumiwa na <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Ilitumiwa hivi majuzi na <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Mfumo"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Vidhibiti vya mfumo"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Programu za mfumo"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Majukumu mengi"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Programu za hivi majuzi"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Gawa skrini"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Kifaa cha kuingiza data"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Njia za mikato za programu"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ufikivu"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Rudi nyuma"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Ili kurudi nyuma, telezesha vidole vitatu kushoto au kulia mahali popote kwenye padi ya kugusa."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Padi ya kugusa inayoonyesha vidole vitatu vikisonga kulia na kushoto"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Skrini ya kifaa inayoonyesha uhuishaji wa mguso wa nyuma"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Mwanga chini ya kibodi"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Kiwango cha %1$d kati ya %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Dhibiti Vifaa Nyumbani"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 6298363..93e47ff 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"இந்த ஸ்கிரீன்ஷாட்டை <xliff:g id="APPNAME">%1$s</xliff:g> கண்டறிந்துள்ளது."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"இந்த ஸ்கிரீன்ஷாட்டை <xliff:g id="APPNAME">%1$s</xliff:g> மற்றும் திறந்திருக்கும் பிற ஆப்ஸ் கண்டறிந்துள்ளன."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"குறிப்பில் சேர்"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"இணைப்பைச் சேர்"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"ஸ்கிரீன் ரெக்கார்டர்"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ஸ்க்ரீன் ரெக்கார்டிங் செயலாக்கப்படுகிறது"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"திரை ரெக்கார்டிங் அமர்விற்கான தொடர் அறிவிப்பு"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ஆப்ஸை ரெக்கார்டு செய்வதை நிறுத்துவீர்கள்"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"திரையைப் பகிர்கிறது"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ஆப்ஸைப் பகிர்வதை நிறுத்துவீர்கள்"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"திரையை அலைபரப்புகிறது"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ஆப்ஸை அலைபரப்புவதை நிறுத்துவீர்கள்"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"முகம் மூலம் அன்லாக் செய்யப்பட்டது. தொடர அழுத்தவும்."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"முகம் அங்கீகரிக்கப்பட்டது. தொடர அழுத்தவும்."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"முகம் அங்கீகரிக்கப்பட்டது. தொடர அன்லாக் ஐகானை அழுத்தவும்."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"முகம் கொண்டு அன்லாக் செய்யப்பட்டது. தொடர தட்டவும்."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"அங்கீகரிக்கப்பட்டது"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"அங்கீகரிப்பை ரத்துசெய்"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"கூடுதல் விருப்பங்கள்"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"விரைவுப் பகிர்தல், Find My Device போன்ற அம்சங்கள் புளூடூத்தைப் பயன்படுத்துகின்றன"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"நாளை காலை புளூடூத் இயக்கப்படும்"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ஆடியோவைப் பகிர்"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"ஆடியோ பகிரப்படுகிறது"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"கூடுதல் விட்ஜெட்களைச் சேருங்கள்"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"விட்ஜெட்களைப் பிரத்தியேகமாக்க நீண்ட நேரம் அழுத்துக"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"விட்ஜெட்களைப் பிரத்தியேகமாக்குங்கள்"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"விட்ஜெட்களைப் பிரத்தியேகப்படுத்த அன்லாக் செய்யுங்கள்"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"முடக்கப்பட்ட விட்ஜெட்டுக்கான ஆப்ஸ் ஐகான்"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"நிறுவப்படும் விட்ஜெட்டுக்கான ஆப்ஸ் ஐகான்"</string>
     <string name="edit_widget" msgid="9030848101135393954">"விட்ஜெட்டைத் திருத்து"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"விட்ஜெட்டைத் தேர்ந்தெடுக்கும்"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"விட்ஜெட்டை அகற்றும்"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"தேர்ந்தெடுத்த விட்ஜெட்டைக் காட்சிப்படுத்தும்"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"பயனரை மாற்று"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"கீழ் இழுக்கும் மெனு"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"இந்த அமர்வின் எல்லா ஆப்ஸும் தரவும் நீக்கப்படும்."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"இப்போது தொடங்கு"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"அறிவிப்புகள் இல்லை"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"புதிய அறிவிப்புகள் இல்லை"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"சூழல்சார் அறிவிப்புகள் இயக்கப்பட்டது"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"குறைந்த நேரத்தில் அதிக அறிவிப்பைப் பெறும்போது இரண்டு நிமிடங்கள் வரை உங்கள் சாதனம் ஒலியையும், திரையில் காட்டப்படும் பாப்-அப்களின் எண்ணிக்கையையும் குறைக்கிறது."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"முடக்கு"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"பழைய அறிவிப்பைப் பார்க்க அன்லாக் செய்க"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"இந்தச் சாதனம் உங்கள் பெற்றோரால் நிர்வகிக்கப்படுகிறது"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"இந்த சாதனம் உங்கள் நிறுவனத்துக்கு உரியது, நெட்வொர்க் ட்ராஃபிக்கையும் நிறுவனமே கண்காணிக்கக்கூடும்"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"மேலும் தகவல்களுக்கு தட்டவும்"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"அலாரம் எதுவுமில்லை"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"திரைப் பூட்டை உள்ளிடலாம்"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"கைரேகை சென்சாரைத் தொடவும். இது மொபைலின் பக்கவாட்டில் உள்ள சிறிய பட்டன் ஆகும்"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"கைரேகை சென்சார்"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"அங்கீகரி"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"சாதனத்தைத் திற"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ஆப்ஸால் பயன்படுத்தப்படுகிறது"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ஆப்ஸால் சமீபத்தில் பயன்படுத்தப்பட்டது"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"சிஸ்டம்"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"சிஸ்டம் கட்டுப்பாடுகள்"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"சிஸ்டம் ஆப்ஸ்"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"பல வேலைகளைச் செய்தல்"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"சமீபத்திய ஆப்ஸ்"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"திரைப் பிரிப்பு"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"உள்ளீடு"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ஆப்ஸ் ஷார்ட்கட்கள்"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"அணுகல்தன்மை"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"பின்செல்"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"பின்செல்ல, உங்கள் டச்பேடில் எங்கு வேண்டுமானாலும் இடது அல்லது வலதுபுறமாக மூன்று விரல்களால் ஸ்வைப் செய்யவும்."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"மூன்று விரல்கள் வலது மற்றும் இடதுபுறம் நகர்வதை டச்பேட் காட்டுகிறது"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"பின்செல்லும் சைகைக்கான அனிமேஷனை சாதனத்தின் திரை காட்டுகிறது"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"கீபோர்டு பேக்லைட்"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"நிலை, %2$d இல் %1$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ஹோம் கன்ட்ரோல்கள்"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index e3238fe..759b6ca 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g>, ఈ స్క్రీన్‌షాట్‌ను గుర్తించింది."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g>, ఇతర ఓపెన్ యాప్‌లు ఈ స్క్రీన్‌షాట్‌ను గుర్తించాయి."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"గమనికకు జోడించండి"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"లింక్‌ను చేర్చండి"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"స్క్రీన్ రికార్డర్"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"స్క్రీన్ రికార్డింగ్ అవుతోంది"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"స్క్రీన్ రికార్డ్ సెషన్ కోసం ఆన్‌గోయింగ్ నోటిఫికేషన్"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"మీరు &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ను రికార్డ్ చేయడం ఆపివేస్తారు"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"స్క్రీన్‌ను షేర్ చేస్తోంది"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"మీరు &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ను షేర్ చేయడం ఆపివేస్తారు"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"స్క్రీన్‌ను ప్రసారం చేస్తోంది"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"మీరు &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ను ప్రసారం చేయడం ఆపివేస్తారు"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ముఖం ద్వారా అన్‌లాక్ చేయబడింది. కొనసాగించడానికి నొక్కండి."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"ముఖం గుర్తించబడింది. కొనసాగించడానికి నొక్కండి."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ముఖం గుర్తించబడింది. కొనసాగడానికి అన్‌లాక్ చిహ్నం నొక్కండి."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"ముఖం ద్వారా అన్‌లాక్ అయింది. కొనసాగడానికి ట్యాప్ చేయండి."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ప్రామాణీకరించబడింది"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ప్రామాణీకరణను రద్దు చేయండి"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"మరిన్ని ఆప్షన్‌లు"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"క్విక్ షేర్, Find My Device వంటి ఫీచర్‌లు బ్లూటూత్‌ను ఉపయోగిస్తాయి"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"బ్లూటూత్ రేపు ఉదయం ఆన్ అవుతుంది"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"ఆడియోను షేర్ చేయండి"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"ఆడియోను షేర్ చేస్తున్నారు"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"మరిన్ని విడ్జెట్‌లను జోడించండి"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"విడ్జెట్‌లను అనుకూలీకరించడానికి, నొక్కి, ఉంచండి"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"విడ్జెట్‌లను అనుకూలంగా మార్చండి"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"విడ్జెట్‌లను అనుకూలంగా మార్చుకోవడానికి అన్‌లాక్ చేయండి"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"డిజేబుల్ చేయబడిన విడ్జెట్ కోసం యాప్ చిహ్నం"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ఇన్‌స్టాల్ చేస్తున్న విడ్జెట్ కోసం యాప్ చిహ్నం"</string>
     <string name="edit_widget" msgid="9030848101135393954">"విడ్జెట్‌ను ఎడిట్ చేయండి"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"విడ్జెట్‌ను ఎంచుకోండి"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"విడ్జెట్‌ను తీసివేయండి"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ఎంచుకున్న విడ్జెట్ కోసం ప్లేస్‌ను ఎంచుకోండి"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"వినియోగదారుని మార్చు"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"పుల్‌డౌన్ మెనూ"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ఈ సెషన్‌లోని అన్ని యాప్‌లు మరియు డేటా తొలగించబడతాయి."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"ఇప్పుడే ప్రారంభించండి"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"నోటిఫికేషన్‌లు లేవు"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"కొత్త నోటిఫికేషన్‌లు ఏవీ లేవు"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"అనుకూల నోటిఫికేషన్‌లు ఆన్‌లో ఉన్నాయి"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"మీరు తక్కువ సమయంలో అనేక నోటిఫికేషన్‌లను స్వీకరించినప్పుడు మీ పరికరం ఇప్పుడు వాల్యూమ్‌ను తగ్గిస్తుంది, స్క్రీన్‌పై పాప్-అప్‌లను రెండు నిమిషాల వరకు తగ్గిస్తుంది."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ఆఫ్ చేయండి"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"పాత నోటిఫికేషన్‌ల కోసం అన్‌లాక్ చేయండి"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ఈ పరికరాన్ని మీ తల్లి/తండ్రి మేనేజ్ చేస్తున్నారు"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"ఈ పరికరం మీ సంస్థకు చెందినది, కాబట్టి అది నెట్‌వర్క్ ట్రాఫిక్‌ను పర్యవేక్షించవచ్చు"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"మరింత సమాచారం కోసం ట్యాప్ చేయండి"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"అలారం సెట్ చేయలేదు"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"స్క్రీన్ లాక్‌ను ఎంటర్ చేయండి"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"వేలిముద్ర సెన్సార్‌ను తాకండి. ఇది ఫోన్‌కు పక్కన ఉండే బటన్‌లలో చిన్నది"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"వేలిముద్ర సెన్సార్"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"ప్రామాణీకరించండి"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"పరికరాన్ని ఎంటర్ చేయండి"</string>
@@ -1296,7 +1312,7 @@
     <string name="rotation_tile_with_posture_secondary_label_template" msgid="7648496484163318886">"%1$s / %2$s"</string>
     <string name="stylus_battery_low_percentage" msgid="2564243323894629626">"స్టయిలస్ బ్యాటరీ <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="stylus_battery_low_subtitle" msgid="3583843128908823273">"మీ స్టైలస్‌ను ఛార్జర్‌కి కనెక్ట్ చేయండి"</string>
-    <string name="stylus_battery_low" msgid="7134370101603167096">"తక్కువ స్టైలస్ బ్యాటరీ"</string>
+    <string name="stylus_battery_low" msgid="7134370101603167096">"తక్కువ స్టయిలస్ బ్యాటరీ"</string>
     <string name="video_camera" msgid="7654002575156149298">"వీడియో కెమెరా"</string>
     <string name="call_from_work_profile_title" msgid="5418253516453177114">"వ్యక్తిగత యాప్ నుండి కాల్ చేయడం సాధ్యం కాదు"</string>
     <string name="call_from_work_profile_text" msgid="2856337395968118274">"మీ సంస్థ, వర్క్ యాప్‌ల నుండి మాత్రమే కాల్స్ చేయడానికి మిమ్మల్ని అనుమతిస్తుంది"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ద్వారా వినియోగంలో ఉంది"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ద్వారా ఇటీవల ఉపయోగించబడింది"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"సిస్టమ్"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"సిస్టమ్ కంట్రోల్స్"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"సిస్టమ్ యాప్‌లు"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"మల్టీ-టాస్కింగ్"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"ఇటీవలి యాప్‌లు"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"స్ప్లిట్ స్క్రీన్"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"ఇన్‌పుట్"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"యాప్ షార్ట్‌కట్‌లు"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"యాక్సెసిబిలిటీ"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"వెనుకకు"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"వెనుకకు వెళ్లడానికి, టచ్‌ప్యాడ్‌లో ఎక్కడైనా మూడు వేళ్లను ఉపయోగించి ఎడమ లేదా కుడికి స్వైప్ చేయండి."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"మూడు వేళ్లు కుడి, ఎడమకు కదులుతున్నట్లు చూపే టచ్‌ప్యాడ్"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"వెనుక సంజ్ఞ కోసం యానిమేషన్‌ను చూపుతున్న పరికర స్క్రీన్"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"కీబోర్డ్ బ్యాక్‌లైట్"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"%2$dలో %1$dవ స్థాయి"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"హోమ్ కంట్రోల్స్"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index d21bf5e..4ed8a03 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> ตรวจพบภาพหน้าจอนี้"</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> และแอปอื่นๆ ที่เปิดอยู่ตรวจพบภาพหน้าจอนี้"</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"เพิ่มลงในโน้ต"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"รวมลิงก์"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"โปรแกรมบันทึกหน้าจอ"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"กำลังประมวลผลการอัดหน้าจอ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"การแจ้งเตือนต่อเนื่องสำหรับเซสชันการบันทึกหน้าจอ"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"คุณจะหยุดการบันทึก &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"กำลังแชร์หน้าจอ"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"คุณจะหยุดการแชร์ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"กำลังแคสต์หน้าจอ"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"คุณจะหยุดการแคสต์ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"ปลดล็อกด้วยใบหน้าแล้ว กดเพื่อดำเนินการต่อ"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"จดจำใบหน้าได้ กดเพื่อดำเนินการต่อ"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"จดจำใบหน้าได้ กดไอคอนปลดล็อกเพื่อดำเนินการต่อ"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"ปลดล็อกด้วยใบหน้าแล้ว แตะเพื่อดำเนินการต่อ"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ตรวจสอบสิทธิ์แล้ว"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ยกเลิกการตรวจสอบสิทธิ์"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ตัวเลือกเพิ่มเติม"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"ฟีเจอร์ต่างๆ เช่น Quick Share และ \"หาอุปกรณ์ของฉัน\" ใช้บลูทูธ"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"บลูทูธจะเปิดพรุ่งนี้เช้า"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"แชร์เสียง"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"กำลังแชร์เสียง"</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>
@@ -378,7 +383,7 @@
     <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>
-    <string name="qs_record_issue_label" msgid="8166290137285529059">"ปัญหาการบันทึก"</string>
+    <string name="qs_record_issue_label" msgid="8166290137285529059">"บันทึกปัญหา"</string>
     <string name="qs_record_issue_start" msgid="2979831312582567056">"เริ่ม"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"หยุด"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"รายงานข้อบกพร่อง"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"เพิ่มวิดเจ็ตอีก"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"กดค้างเพื่อปรับแต่งวิดเจ็ต"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ปรับแต่งวิดเจ็ต"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ปลดล็อกเพื่อปรับแต่งวิดเจ็ต"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"ไอคอนแอปสำหรับวิดเจ็ตที่ปิดใช้อยู่"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"ไอคอนแอปสำหรับวิดเจ็ตที่กำลังติดตั้ง"</string>
     <string name="edit_widget" msgid="9030848101135393954">"แก้ไขวิดเจ็ต"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"เลือกวิดเจ็ต"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"นำวิดเจ็ตออก"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"จัดวางวิดเจ็ตที่เลือก"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"สลับผู้ใช้"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"เมนูแบบเลื่อนลง"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ระบบจะลบแอปและข้อมูลทั้งหมดในเซสชันนี้"</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"เริ่มเลย"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"ไม่มีการแจ้งเตือน"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"ไม่มีการแจ้งเตือนใหม่"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"การแจ้งเตือนแบบปรับอัตโนมัติเปิดอยู่"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"จากนี้ไปอุปกรณ์จะลดระดับเสียงและจำนวนป๊อปอัปบนหน้าจอสูงสุด 2 นาทีเมื่อคุณได้รับการแจ้งเตือนจำนวนมากในระยะเวลาสั้นๆ"</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"ปิด"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ปลดล็อกเพื่อดูการแจ้งเตือนเก่า"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"อุปกรณ์นี้จัดการโดยผู้ปกครอง"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"องค์กรของคุณเป็นเจ้าของอุปกรณ์นี้และอาจตรวจสอบการจราจรของข้อมูลในเครือข่าย"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"แตะดูข้อมูลเพิ่มเติม"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ไม่มีการตั้งปลุก"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"ป้อนข้อมูลการล็อกหน้าจอ"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"แตะเซ็นเซอร์ลายนิ้วมือ ซึ่งเป็นปุ่มสั้นๆ ที่อยู่ด้านข้างโทรศัพท์"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"เซ็นเซอร์ลายนิ้วมือ"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"ตรวจสอบสิทธิ์"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"เข้าถึงอุปกรณ์"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"ใช้อยู่โดย <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"ใช้ล่าสุดโดย <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"ระบบ"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"การควบคุมระบบ"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"แอประบบ"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"การทํางานหลายอย่างพร้อมกัน"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"แอปล่าสุด"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"แยกหน้าจอ"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"อินพุต"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"แป้นพิมพ์ลัดของแอป"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"การช่วยเหลือพิเศษ"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"ย้อนกลับ"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"หากต้องการย้อนกลับ ให้ใช้ 3 นิ้วปัดไปทางซ้ายหรือขวาที่ใดก็ได้บนทัชแพด"</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ทัชแพดแสดงภาพ 3 นิ้วเลื่อนไปทางขวาและซ้าย"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"หน้าจออุปกรณ์แสดงภาพเคลื่อนไหวของท่าทางสัมผัสย้อนกลับ"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"ไฟแบ็กไลต์ของแป้นพิมพ์"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"ระดับที่ %1$d จาก %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ระบบควบคุมอุปกรณ์สมาร์ทโฮม"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index b63d282..421283c 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"Na-detect ng <xliff:g id="APPNAME">%1$s</xliff:g> ang screenshot. na ito"</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"Na-detect ng <xliff:g id="APPNAME">%1$s</xliff:g> at ng iba pang bukas na app ang screenshot na ito."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Idagdag sa tala"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Isama ang link"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Recorder ng Screen"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Pinoproseso screen recording"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Kasalukuyang notification para sa session ng pag-record ng screen"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Hihinto ka sa pag-record ng &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ibinabahagi ang screen"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Hihinto ka sa pagbabahagi ng &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Kina-cast ang screen"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Hihinto ka sa pag-cast ng &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Na-unlock gamit ang mukha. Pindutin para magpatuloy."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Nakilala ang mukha. Pindutin para magpatuloy."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Nakilala ang mukha. Pindutin ang unlock para magpatuloy."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Na-unlock gamit ang mukha. I-tap para magpatuloy."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Na-authenticate"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Kanselahin ang Pag-authenticate"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Higit Pang Opsyon"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Gumagamit ng Bluetooth ang mga feature tulad ng Quick Share at Hanapin ang Aking Device"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Mag-o-on ang Bluetooth bukas ng umaga"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Ibahagi ang audio"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Ibinabahagi ang audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> na baterya"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Headset"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Magdagdag ng higit pang widget"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Pindutin nang matagal para i-customize ang mga widget"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"I-customize ang mga widget"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Mag-unlock para ma-customize ang mga widget"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Icon ng app para sa na-disable na widget"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Ini-install ang icon ng app para sa isang widget"</string>
     <string name="edit_widget" msgid="9030848101135393954">"I-edit ang widget"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"pumili ng widget"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"alisin ang widget"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"ilagay ang napiling widget"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Magpalit ng user"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"pulldown menu"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ide-delete ang lahat ng app at data sa session na ito."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Magsimula ngayon"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Walang mga notification"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Walang bagong notification"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"On ang adaptive notifications"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Hinihinaan ng device ang volume at binabawasan nito ang pop-ups nang hanggang 2 minuto kapag nakatanggap ng maraming notification sa maikling oras."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"I-off"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"I-unlock para makita ang mga mas lumang notification"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Pinapamahalaan ng magulang mo itong device"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Pagmamay-ari ng organisasyon mo ang device na ito at puwede nitong subaybayan ang trapiko sa network"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"I-tap para sa higit pang impormasyon"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Walang alarm"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"ilagay ang lock ng screen"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Pindutin ang sensor para sa fingerprint. Ito ang mas maikling button sa gilid ng telepono"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Sensor para sa fingerprint"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"i-authenticate"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"ilagay ang device"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Ginagamit ng <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Kamakailang ginamit ng <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"System"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Mga kontrol ng system"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Mga system app"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Pag-multitask"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Kamakailang mga app"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Split screen"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Input"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Mga shortcut ng app"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Accessibility"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Bumalik"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Para bumalik, mag-swipe pakaliwa o pakanan gamit ang tatlong daliri kahit saan sa touchpad."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Touchpad na nagpapakita ng tatlong daliring gumagalaw pakanan at pakaliwa"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Screen ng device na nagpapakita ng animation para sa galaw sa pagbalik"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Backlight ng keyboard"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Level %1$d sa %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Mga Home Control"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index f78afe4..8ad6dee 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> bu ekran görüntüsünü algıladı."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> ve diğer açık uygulamalar bu ekran görüntüsünü algıladı."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Nota ekle"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Bağlantıyı dahil et"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Ekran Kaydedicisi"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran kaydı işleniyor"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekran kaydı oturumu için devam eden bildirim"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; içeriğini kaydetmeyi durdurursunuz"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekran paylaşılıyor"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; içeriğini paylaşmayı durdurursunuz"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Ekran yayınlanıyor"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; içeriğini yayınlamayı durdurursunuz"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Cihazın kilidini yüzünüzle açtınız. Devam etmek için basın."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Yüzünüz tanındı. Devam etmek için basın."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Yüzünüz tanındı. Kilit açma simgesine basın."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Kilidi yüzünüzle açtınız. Devam etmek için dokunun."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Kimliği Doğrulandı"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Kimlik doğrulamayı iptal et"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Diğer Seçenekler"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Quick Share ve Cihazımı Bul gibi özellikler Bluetooth\'u kullanır"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth yarın sabah açılacak"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Sesi paylaş"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Ses paylaşılıyor"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Pil düzeyi <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Ses"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Mikrofonlu kulaklık"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Daha fazla widget ekle"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Widget\'ları özelleştirmek için uzun basın"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Widget\'ları özelleştir"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Widget\'ları özelleştirmek için kilidi açın"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Devre dışı bırakılan widget\'ın uygulama simgesi"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Yüklenmeye devam eden bir widget\'ın uygulama simgesi"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Widget\'ı düzenle"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"widget seçin"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"widget\'ı kaldır"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"seçilen widget\'ı yerleştir"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Kullanıcı değiştirme"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"açılır menü"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Bu oturumdaki tüm uygulamalar ve veriler silinecek."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Şimdi başlat"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Bildirim yok"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Yeni bildirim yok"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Uyarlanabilir bildirimler açık"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Cihazınız, kısa süre içinde çok sayıda bildirim aldığınızda artık iki dakika boyunca sesi kısar ve ekrandaki pop-up\'ları azaltır."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Kapat"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Eski bildirimler için kilidi açın"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Bu cihaz ebeveyniniz tarafından yönetiliyor"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Bu cihaz, kuruluşunuza ait olup ağ trafiği kuruluşunuz tarafından izlenebilir"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Daha fazla bilgi için dokunun"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Alarm yok"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"ekran kilidini gir"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Parmak izi sensörüne dokunun. Sensör, telefonun yan tarafındaki daha kısa olan düğmedir."</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Parmak izi sensörü"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"kimlik doğrulaması yapın"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"cihaz girin"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) tarafından kullanılıyor"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"En son <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) tarafından kullanıldı"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Sistem"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Sistem kontrolleri"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Sistem uygulamaları"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Çoklu görev becerisi"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Son uygulamalar"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Bölünmüş ekran"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Giriş"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Uygulama kısayolları"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Erişilebilirlik"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Geri dön"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Geri dönmek için dokunmatik alanın herhangi bir yerinde üç parmağınızla sola veya sağa kaydırın."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Sağa ve sola hareket eden üç parmağın gösterildiği dokunmatik alan"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Geri hareketi animasyonunu gösteren cihaz ekranı"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klavye aydınlatması"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Seviye %1$d / %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Ev Kontrolleri"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 46d0619..17931cff4 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"Додаток <xliff:g id="APPNAME">%1$s</xliff:g> виявив цей знімок екрана."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> та інші відкриті додатки виявили цей знімок екрана."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Додати до примітки"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Додати посилання"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Запис відео з екрана"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обробка записування екрана"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Сповіщення про сеанс запису екрана"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Ви зупините запис контенту з додатка &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Показ екрана"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Ви зупините надсилання контенту з додатка &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Трансляція екрана"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Ви зупините трансляцію контенту з додатка &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Розблоковано (фейс-контроль). Натисніть, щоб продовжити."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Обличчя розпізнано. Натисніть, щоб продовжити."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Обличчя розпізнано. Натисніть значок розблокування."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Розблоковано (фейс-контроль). Натисніть, щоб продовжити."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Автентифіковано"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Скасувати автентифікацію"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Інші опції"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Такі функції, як швидкий обмін і \"Знайти пристрій\", використовують Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth увімкнеться завтра вранці"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Поділитись аудіо"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Надсилання аудіо"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Додати більше віджетів"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Утримуйте, щоб налаштувати віджети"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Налаштувати віджети"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Розблокуйте екран, щоб налаштувати віджети"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Значок додатка для вимкненого віджета"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Значок додатка для віджета, що встановлюється"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Редагувати віджет"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"виберіть віджет"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"видалити віджет"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"розмістити вибраний віджет"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Змінити користувача"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"спадне меню"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Усі додатки й дані з цього сеансу буде видалено."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Почати зараз"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Сповіщень немає"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Немає нових сповіщень"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Адаптивні сповіщення ввімкнено"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Пристрій знижує гучність і зменшує кількість спливаючих вікон на екрані на період до двох хвилин, коли ви отримуєте багато сповіщень за короткий час."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Вимкнути"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Розблокуйте, щоб переглянути старіші"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Цим пристроєм керує батько або мати"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Цей пристрій належить вашій організації. Її адміністратор може відстежувати мережевий трафік"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Натисніть, щоб дізнатися більше"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Немає будильників"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"показати способи розблокування екрана"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Торкніться сканера відбитків пальців. Це менша кнопка на бічній панелі телефона."</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сканер відбитків пальців"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"пройти автентифікацію"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"відкрити пристрій"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Використовується додатком <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Нещодавно використано (<xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Система"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Елементи керування системою"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Системні додатки"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Багатозадачність"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Нещодавні додатки"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Розділити екран"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Введення"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Комбінації клавіш для додатків"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Доступність"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Назад"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Щоб перейти назад, проведіть трьома пальцями вліво або вправо по сенсорній панелі."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Сенсорна панель із зображенням трьох пальців, що рухаються вправо й уліво"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Екран пристрою, на якому показано анімацію щодо жесту \"Назад\""</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Підсвічування клавіатури"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Рівень %1$d з %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Автоматизація дому"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 38bddf7..d597d49 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"‫<xliff:g id="APPNAME">%1$s</xliff:g> نے اس اسکرین شاٹ کا پتا لگایا۔"</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"‫<xliff:g id="APPNAME">%1$s</xliff:g> اور دیگر کھلی ایپس نے اس اسکرین شاٹ کا پتا لگایا۔"</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"نوٹ میں شامل کریں"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"لنک شامل کریں"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"اسکرین ریکارڈر"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"سکرین ریکارڈنگ پروسیس ہورہی ہے"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"اسکرین ریکارڈ سیشن کیلئے جاری اطلاع"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"‏آپ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; کو ریکارڈ نہیں کر پائیں گے"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"اسکرین کا اشتراک ہو رہا ہے"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"‏آپ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; کا اشتراک نہیں کر پائیں گے"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"اسکرین کاسٹ ہو رہی ہے"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"‏آپ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; کو کاسٹ نہیں کر پائیں گے"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"چہرے سے انلاک کیا گیا۔ جاری رکھنے کے لیے دبائیں۔"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"چہرے کی شناخت ہو گئی۔ جاری رکھنے کے لیے دبائیں۔"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"چہرے کی شناخت ہو گئی۔ جاری رکھنے کیلئے انلاک آئیکن دبائیں۔"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"چہرے سے غیر مقفل کیا گیا۔ جاری رکھنے کیلئے تھپتھپائیں۔"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"تصدیق کردہ"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"تصدیق کو منسوخ کریں"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"مزید اختیارات"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"فوری اشتراک اور \'میرا آلہ ڈھونڈیں\' جیسی خصوصیات بلوٹوتھ کا استعمال کرتی ہیں"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"بلوٹوتھ کل صبح آن ہو جائے گا"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"آڈیو کا اشتراک کریں"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"آڈیو کا اشتراک ہو رہا ہے"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"مزید ویجٹس شامل کریں"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"ویجٹس کو حسب ضرورت بنانے کے لیے لانگ پریس کریں"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"ویجیٹس کو حسب ضرورت بنائیں"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"ویجیٹس کو حسب ضرورت بنانے کے لیے غیر مقفل کریں"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"غیر فعال ویجیٹ کے لئے ایپ آئیکن"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"انسٹال ہونے والے ویجیٹ کا ایپ آئیکن"</string>
     <string name="edit_widget" msgid="9030848101135393954">"ویجیٹ میں ترمیم کریں"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"ویجیٹ منتخب کریں"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"ویجیٹ ہٹائیں"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"منتخب ویجیٹ رکھیں"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"صارف سوئچ کریں"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"پل ڈاؤن مینیو"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"اس سیشن میں موجود سبھی ایپس اور ڈیٹا کو حذف کر دیا جائے گا۔"</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"ابھی شروع کریں"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"کوئی اطلاعات نہیں ہیں"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"کوئی نئی اطلاعات نہیں"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"تغیر پذیر اطلاعات آن ہیں"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"کم وقت میں متعدد اطلاعات ملنے پر آپ کا آلہ اب دو منٹ تک سکرین پر والیوم اور پوپ اپس کم کر دیتا ہے۔"</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"آف کریں"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"پرانی اطلاعات دیکھنے کیلئے غیر مقفل کریں"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"یہ آلہ آپ کے والدین کے زیر انتظام ہے"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"آپ کی تنظیم اس آلے کی مالک ہے اور نیٹ ورک ٹریفک کی نگرانی کر سکتی ہے"</string>
@@ -1201,6 +1216,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"مزید معلومات کے لیے تھپتھپائیں"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"کوئی الارم سیٹ نہیں ہے"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"اسکرین لاک درج کریں"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"فنگر پرنٹ سینسر کو ٹچ کریں۔ یہ فون کے سائیڈ میں چھوٹا سا بٹن ہے۔"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"فنگر پرنٹ سینسر"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"تصدیق کریں"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"آلہ درج کریں"</string>
@@ -1342,7 +1358,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) کے زیر استعمال"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) کے ذریعے حال ہی میں استعمال کیا گیا"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"سسٹم"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"سسٹم کنٹرولز"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"سسٹم ایپس"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"ملٹی ٹاسکنگ"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"حالیہ ایپس"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"اسپلٹ اسکرین"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"ان پٹ"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"ایپ شارٹ کٹس"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"ایکسیسبیلٹی"</string>
@@ -1359,6 +1379,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"واپس جائیں"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"واپس جانے کے لیے، ٹچ پیڈ پر کہیں بھی تین انگلیوں کی مدد سے دائیں یا بائیں سوائپ کریں۔"</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"ٹچ پیڈ دائیں اور بائیں حرکت کرتی ہوئی تین انگلیاں دکھا رہا ہے"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"آلہ کی اسکرین پیچھے جانے کے اشارے کے لیے اینیمیشن دکھا رہی ہے"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"کی بورڈ بیک لائٹ"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"‏%2$d میں سے ‎%1$d کا لیول"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"ہوم کنٹرولز"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 52ecbc3..6ef4026 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> skrinshot olinganini aniqladi."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> va boshqa ochiq ilovalar skrinshot olinganini aniqladi."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Qaydga qoʻshish"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Havolani kiritish"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Ekranni yozib olish"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran yozib olinmoqda"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekrandan yozib olish seansi uchun joriy bildirishnoma"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; yozib olinishini toʻxtatasiz"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Ekran ulashilmoqda"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ulashuvini toʻxtatasiz"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Ekran namoyish qilinmoqda"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; translatsiyasini toʻxtatasiz"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Yuz orqali ochildi. Davom etish uchun bosing."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Yuz aniqlandi. Davom etish uchun bosing."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Yuz aniqlandi. Davom etish uchun ochish belgisini bosing."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Yuz bilan ochildi. Davom etish uchun bosing."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Tasdiqlandi"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Autentifikatsiyani bekor qilish"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Boshqa parametrlar"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Tezkor ulashuv va Qurilmamni top kabi funksiyalar Bluetooth ishlatadi"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth ertaga ertalab yoqiladi"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Audioni ulashish"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Audio ulashuvi yoniq"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"Batareya quvvati: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Audio"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Garnitura"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Koʻproq vidjetlar qoʻshish"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Vidjetlarni sozlash uchun bosib turing"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Vidjetlarni moslashtirish"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Vidjetlarni moslash uchun qulfdan chiqaring"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Faolsizlantirilgan vidjet uchun ilova belgisi"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Oʻrnatilayotgan vidjet uchun ilova belgisi"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Vidjetni tahrirlash"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"vidjet tanlash"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"vidjetni olib tashlash"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"tanlangan vidjetni joylash"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Foydalanuvchini almashtirish"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"tortib tushiriladigan menyu"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Ushbu seansdagi barcha ilovalar va ma’lumotlar o‘chirib tashlanadi."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Boshlash"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Bildirishnomalar yo‘q"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Yangi bildirishoma yoʻq"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Adaptiv bildirishnomalar yoniq"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Qisqa vaqt oraligʻida koʻp bildirishnoma kelsa, qurilmadagi tovush balandligi hamda bildirgi oynalar soni ikki daqiqagacha kamaytiriladi."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Faolsizlantirish"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Eskilarini koʻrish uchun qulfni yeching"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Bu qurilmani ota-onangiz boshqaradi"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Bu qurilma tashkilotingizga tegishli va tarmoq trafigi tashkilotingiz tomonidan kuzatilishi mumkin"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Batafsil axborot olish uchun bosing"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Signal sozlanmagan"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"ekran qulfini kiriting"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Barmoq izi skaneriga tegining. Bu – telefonning yon tomonidagi qisqa tugma"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Barmoq izi skaneri"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentifikatsiya"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"qurilmani ochish"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ishlatmoqda"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Yaqinda <xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) ishlatgan"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Tizim"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Tizim boshqaruvi tugmalari"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Tizim ilovalari"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Multi-vazifalilik"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Oxirgi ilovalar"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Ekranni ikkiga ajratish"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Kiritish"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Ilova yorliqlari"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Qulayliklar"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Orqaga qaytish"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Ortga qaytish uchun sensorli panelda uchta barmoqni chapga yoki oʻngga suring."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Sensorli panelda uchta barmoq chapga va oʻngga harakatlanishi"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Qurilma ekranidagi ortga qaytish ishorasi animatsiyasi"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Klaviatura orqa yoritkichi"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Daraja: %1$d / %2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Uy boshqaruvi"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 041da41..88fe436 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> đã phát hiện thấy ảnh chụp màn hình này."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> và các ứng dụng đang mở khác đã phát hiện thấy ảnh chụp màn hình này."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Thêm vào ghi chú"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Thêm đường liên kết"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Trình ghi màn hình"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Đang xử lý video ghi màn hình"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Thông báo đang diễn ra về phiên ghi màn hình"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Bạn sẽ dừng ghi âm nội dung của &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Đang chia sẻ màn hình"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Bạn sẽ dừng chia sẻ nội dung của &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Đang truyền màn hình"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Bạn sẽ dừng truyền nội dung của &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Đã mở khoá bằng khuôn mặt. Hãy nhấn để tiếp tục."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Đã nhận diện khuôn mặt. Hãy nhấn để tiếp tục."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Đã nhận diện khuôn mặt. Nhấn biểu tượng mở khoá để tiếp tục."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Đã mở khoá bằng khuôn mặt. Nhấn để tiếp tục."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Đã xác thực"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Huỷ quy trình xác thực"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Tuỳ chọn khác"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Các tính năng như Chia sẻ nhanh và Tìm thiết bị của tôi đều sử dụng Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"Bluetooth sẽ bật vào sáng mai"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Chia sẻ âm thanh"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Đang chia sẻ âm thanh"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> pin"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Âm thanh"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Tai nghe"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Thêm tiện ích khác"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Nhấn và giữ để tuỳ chỉnh tiện ích"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Tuỳ chỉnh tiện ích"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Mở khoá để tuỳ chỉnh các tiện ích"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Biểu tượng ứng dụng của tiện ích đã bị vô hiệu hoá"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Đang cài đặt biểu tượng ứng dụng của một tiện ích"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Chỉnh sửa tiện ích"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"chọn tiện ích"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"xoá tiện ích"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"đặt tiện ích đã chọn vào vị trí"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Chuyển đổi người dùng"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"trình đơn kéo xuống"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Tất cả ứng dụng và dữ liệu trong phiên này sẽ bị xóa."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Bắt đầu ngay"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Không có thông báo nào"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Không có thông báo mới"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Thông báo thích ứng đang bật"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Giờ đây, thiết bị sẽ giảm âm lượng và giảm số cửa sổ bật lên trên màn hình trong tối đa 2 phút khi bạn nhận được nhiều thông báo trong một khoảng thời gian ngắn."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Tắt"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Mở khoá để xem thông báo cũ"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Thiết bị này do cha mẹ của bạn quản lý"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Tổ chức của bạn sở hữu thiết bị này và có thể giám sát lưu lượng truy cập mạng"</string>
@@ -780,7 +795,7 @@
     <string name="keyboard_shortcut_join" msgid="3578314570034512676">"hoặc"</string>
     <string name="keyboard_shortcut_clear_text" msgid="6631051796030377857">"Xoá cụm từ tìm kiếm"</string>
     <string name="keyboard_shortcut_search_list_title" msgid="4271769465397671138">"Phím tắt"</string>
-    <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Lối tắt tìm kiếm"</string>
+    <string name="keyboard_shortcut_search_list_hint" msgid="5982623262974326746">"Tìm lối tắt"</string>
     <string name="keyboard_shortcut_search_list_no_result" msgid="6819302191660875501">"Không tìm thấy lối tắt"</string>
     <string name="keyboard_shortcut_search_category_system" msgid="1151182120757052669">"Hệ thống"</string>
     <string name="keyboard_shortcut_search_category_input" msgid="5440558509904296233">"Đầu vào"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Nhấn để biết thêm thông tin"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Chưa đặt chuông báo"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"nhập phương thức mở khoá màn hình"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Hãy chạm vào cảm biến vân tay. Đó là nút ngắn ở cạnh bên của điện thoại"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Cảm biến vân tay"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"xác thực"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"truy cập thiết bị"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) đang dùng"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>) đã dùng gần đây"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Hệ thống"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Cài đặt hệ thống"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Ứng dụng hệ thống"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Đa nhiệm"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Ứng dụng gần đây"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Chia đôi màn hình"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Phương thức nhập"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Lối tắt ứng dụng"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Hỗ trợ tiếp cận"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Quay lại"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Để quay lại, hãy vuốt sang trái hoặc sang phải bằng 3 ngón tay ở vị trí bất kỳ trên bàn di chuột."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Minh hoạ thao tác di chuyển sang phải và sang trái bằng 3 ngón tay trên bàn di chuột"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Màn hình thiết bị hiện ảnh động minh hoạ cử chỉ quay lại"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Đèn nền bàn phím"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Độ sáng %1$d/%2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Điều khiển nhà"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 9df7a50..3a89e35 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> 检测到此屏幕截图。"</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> 及其他打开的应用检测到此屏幕截图。"</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"添加到备注中"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"包括链接"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"屏幕录制器"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"正在处理屏幕录制视频"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"持续显示屏幕录制会话通知"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"将停止录制&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;的内容"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"正在共享屏幕"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"将停止分享&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;的内容"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"正在投放屏幕"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"将停止投放&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;的内容"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"已通过面孔识别解锁。点按即可继续。"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"识别出面孔。点按即可继续。"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"识别出面孔。按下解锁图标即可继续。"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"已通过面孔识别解锁。点按即可继续。"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"已经过身份验证"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"取消身份验证"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"更多选项"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"快速分享、查找我的设备等功能会使用蓝牙"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"蓝牙将在明天早上开启"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"分享音频"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"正在分享音频"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"添加更多微件"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"长按即可自定义微件"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"自定义微件"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"解锁即可自定义微件"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"已停用微件的应用图标"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"代表正在安装的微件的应用图标"</string>
     <string name="edit_widget" msgid="9030848101135393954">"修改微件"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"选择微件"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"移除微件"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"放置所选微件"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切换用户"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉菜单"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"此会话中的所有应用和数据都将被删除。"</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"立即开始"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"没有通知"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"没有新通知"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"自适应通知功能已开启"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"现在,当在短时间内收到许多通知时,您的设备会调低音量并减少屏幕上的弹出式窗口,最多持续两分钟。"</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"关闭"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"解锁即可查看旧通知"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"此设备由您的家长管理"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"贵单位拥有此设备,且可能会监控网络流量"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"点按即可了解详情"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"未设置闹钟"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"输入屏幕解锁信息"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"请轻触指纹传感器,即手机侧面较短的那个按钮"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"指纹传感器"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"身份验证"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"进入设备"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正在使用(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”最近使用过(<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"系统"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"系统控件"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"系统应用"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"多任务处理"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"最近用过的应用"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"分屏"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"输入"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"应用快捷键"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"无障碍功能"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"返回"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"如要返回,请使用三根手指在触控板上的任意位置左滑或右滑。"</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"触控板,其中显示了三根手指右移和左移"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"设备屏幕,其中显示了返回手势的动画"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"键盘背光"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 级,共 %2$d 级"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"家居控制"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
index 9467b9b..0446a1b 100644
--- a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
@@ -188,7 +188,7 @@
   </string-array>
   <string-array name="tile_states_hearing_devices">
     <item msgid="1235334096484287173">"不可用"</item>
-    <item msgid="3079622119444911877">"关闭"</item>
-    <item msgid="3028994095749238254">"开启"</item>
+    <item msgid="3079622119444911877">"已关闭"</item>
+    <item msgid="3028994095749238254">"已开启"</item>
   </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index fdb7759..1603b9b 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"<xliff:g id="APPNAME">%1$s</xliff:g> 偵測到此螢幕截圖。"</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"<xliff:g id="APPNAME">%1$s</xliff:g> 和其他開啟的應用程式偵測到此螢幕截圖。"</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"新增至筆記"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"加入連結"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"螢幕錄影機"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"正在處理螢幕錄影內容"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"持續顯示錄影畫面工作階段通知"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"你將停止錄影「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;b&gt;&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"正在分享螢幕"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"你將停止分享「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;b&gt;&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"正在投放螢幕"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"你將停止投放「<xliff:g id="APP_NAME">%1$s</xliff:g>」&lt;b&gt;&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"已使用面孔解鎖。按下即可繼續操作。"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"已識別面孔。按下即可繼續操作。"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"已識別面孔。按解鎖圖示即可繼續。"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"已使用面孔解鎖,輕按即可繼續。"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"驗證咗"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"取消驗證"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"更多選項"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"「快速共享」和「尋找我的裝置」等功能都會使用藍牙"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"藍牙將於明天上午開啟"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"分享音訊"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"正在分享音訊"</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>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"新增更多小工具"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"長按即可自訂小工具"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"自訂小工具"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"解鎖即可自訂小工具"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"已停用小工具的應用程式圖示"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"此應用程式圖示用來表示安裝中的小工具"</string>
     <string name="edit_widget" msgid="9030848101135393954">"編輯小工具"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"揀小工具"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"移除小工具"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"放置所選小工具"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切換使用者"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉式選單"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會被刪除。"</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"沒有通知"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"沒有新通知"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"已啟用自動調節通知"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"現在每當你於短時間內收到大量通知,裝置便會調低音量並減少螢幕上的彈出式視窗最多兩分鐘。"</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"關閉"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"解鎖即可查看舊通知"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"此裝置由你的家長管理"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"你的機構擁有此裝置,並可能會監察網絡流量"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"輕按即可瞭解詳情"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"未設定鬧鐘"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"輸入螢幕鎖定憑證"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"輕輕掂下指紋感應器,即係手機側邊短啲嗰粒掣"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"指紋感應器"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"驗證"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"進入裝置"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"<xliff:g id="APP_NAME">%1$s</xliff:g> 正在使用 (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」最近使用過此權限 (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"系統"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"系統控制項"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"系統應用程式"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"多工處理"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"最近使用的應用程式"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"分割螢幕"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"輸入"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"應用程式捷徑"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"無障礙功能"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"返回"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"用三隻手指在觸控板上任何一處左右滑動即可返回。"</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"觸控板上有三隻手指左右移動"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"裝置畫面顯示返回手勢動畫"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"鍵盤背光"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 級,共 %2$d 級"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"智能家居"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index cbeb38a..3a1d369 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"「<xliff:g id="APPNAME">%1$s</xliff:g>」偵測到這張螢幕截圖。"</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"「<xliff:g id="APPNAME">%1$s</xliff:g>」和其他開啟的應用程式偵測到這張螢幕截圖。"</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"新增至記事本"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"包含連結"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"螢幕錄影器"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"處理螢幕錄影內容"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"持續顯示螢幕畫面錄製工作階段通知"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"系統將停止錄製「&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;」的內容"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"正在分享畫面"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"系統將停止分享「&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;」的內容"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"正在投放畫面"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"系統將停止投放「&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;」的內容"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"裝置已透過你的臉解鎖,按下即可繼續操作。"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"臉孔辨識完成,按下即可繼續操作。"</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"臉孔辨識完成,按下「解鎖」圖示即可繼續操作。"</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"裝置已透過你的臉解鎖,輕觸這裡即可繼續。"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"已通過驗證"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"取消驗證"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"更多選項"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"「快速分享」和「尋找我的裝置」等功能都需要使用藍牙技術"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"藍牙會在明天早上開啟"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"分享音訊"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"正在分享音訊"</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>
@@ -382,7 +387,7 @@
     <string name="qs_record_issue_start" msgid="2979831312582567056">"開始"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"停止"</string>
     <string name="qs_record_issue_bug_report" msgid="8229031766918650079">"錯誤報告"</string>
-    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"哪些裝置使用體驗受到影響?"</string>
+    <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"哪方面的裝置使用體驗受到影響?"</string>
     <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"選取問題類型"</string>
     <string name="qs_record_issue_dropdown_screenrecord" msgid="6396141928484257626">"螢幕錄影"</string>
     <string name="performance" msgid="6552785217174378320">"效能"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"新增更多小工具"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"長按即可自訂小工具"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"自訂小工具"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"解鎖即可自訂小工具"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"所停用小工具的應用程式圖示"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"這個應用程式圖示用來表示安裝中的小工具"</string>
     <string name="edit_widget" msgid="9030848101135393954">"編輯小工具"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"選取小工具"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"移除小工具"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"放置所選小工具"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切換使用者"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉式選單"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會刪除。"</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"立即開始"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"沒有通知"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"沒有新通知"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"自動調整通知功能已開啟"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"如果在短時間內收到多則通知,裝置會在最長兩分鐘內調降音量,並減少在畫面上顯示彈出式視窗。"</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"關閉"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"解鎖即可查看舊通知"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"這個裝置是由你的家長管理"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"貴機構擁有這部裝置,而且可能會監控網路流量"</string>
@@ -815,7 +830,7 @@
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"切換到下一個語言"</string>
     <string name="input_switch_input_language_previous" msgid="6043341362202336623">"切換到上一個語言"</string>
     <string name="input_access_emoji" msgid="8105642858900406351">"存取表情符號"</string>
-    <string name="input_access_voice_typing" msgid="7291201476395326141">"存取語音輸入內容"</string>
+    <string name="input_access_voice_typing" msgid="7291201476395326141">"使用語音輸入功能"</string>
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"應用程式"</string>
     <string name="keyboard_shortcut_group_applications_assist" msgid="6772492350416591448">"Google 助理"</string>
     <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"瀏覽器"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"輕觸即可瞭解詳情"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"未設定鬧鐘"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"輸入螢幕鎖定憑證"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"請輕觸指紋感應器,也就是手機側邊較短的按鈕"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"指紋感應器"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"驗證"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"進入裝置"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"正由「<xliff:g id="APP_NAME">%1$s</xliff:g>」使用 (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」最近用過這項權限 (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"系統"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"系統控制選項"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"系統應用程式"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"多工處理"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"最近使用的應用程式"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"分割畫面"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"輸入"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"應用程式捷徑"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"無障礙"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"返回"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"如要返回,請用三指在觸控板上向左或右滑動。"</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"動畫顯示三指正在觸控板上向左右移動"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"裝置畫面顯示返回手勢的動畫"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"鍵盤背光"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"第 %1$d 級,共 %2$d 級"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"居家控制"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 2117568..7aa4288 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -103,6 +103,7 @@
     <string name="screenshot_detected_template" msgid="7940376642921719915">"I-<xliff:g id="APPNAME">%1$s</xliff:g> ithole lesi sithombe-skrini."</string>
     <string name="screenshot_detected_multiple_template" msgid="7644827792093819241">"I-<xliff:g id="APPNAME">%1$s</xliff:g> namanye ama-app avuliwe athole lesi sithombe-skrini."</string>
     <string name="app_clips_save_add_to_note" msgid="3460200751278069445">"Engeza kunothi"</string>
+    <string name="backlinks_include_link" msgid="4562093591148248158">"Faka ilinki"</string>
     <string name="screenrecord_title" msgid="4257171601439507792">"Okokuqopha iskrini"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Icubungula okokuqopha iskrini"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Isaziso esiqhubekayo seseshini yokurekhoda isikrini"</string>
@@ -129,18 +130,23 @@
     <skip />
     <!-- no translation found for screenrecord_stop_dialog_message (1926783607059442889) -->
     <skip />
+    <string name="screenrecord_stop_dialog_message_specific_app" msgid="5285148796772616326">"Uzoyeka ukurekhoda &lt;b&gt;i-<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for screenrecord_stop_dialog_button (2883812564938194350) -->
     <skip />
+    <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Yabelana ngesikrini"</string>
     <!-- no translation found for share_to_app_stop_dialog_title (9212915050910250438) -->
     <skip />
     <!-- no translation found for share_to_app_stop_dialog_message (3181723638915877339) -->
     <skip />
+    <string name="share_to_app_stop_dialog_message_specific_app" msgid="124371406810544777">"Uzoyeka ukwaba &lt;b&gt;i-<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for share_to_app_stop_dialog_button (6334056916284230217) -->
     <skip />
+    <string name="cast_to_other_device_chip_accessibility_label" msgid="1680650146639059938">"Isikrini sokusakaza"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_title (1910372600290258193) -->
     <skip />
     <!-- no translation found for cast_to_other_device_stop_dialog_message (1502520537030715412) -->
     <skip />
+    <string name="cast_to_other_device_stop_dialog_message_specific_app" msgid="4891536209254041850">"Uzoyeka ukusakaza &lt;b&gt;i-<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
     <!-- no translation found for cast_to_other_device_stop_dialog_button (6420183747435521834) -->
     <skip />
     <!-- no translation found for close_dialog_button (4749497706540104133) -->
@@ -189,6 +195,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_1" msgid="439152621640507113">"Vula ngobuso. Cindezela ukuze uqhubeke."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_2" msgid="8586608186457385108">"Ubuso buyaziwa. Cindezela ukuze uqhubeke."</string>
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ubuso buyaziwa. Cindezela isithonjana sokuvula ukuze uqhubeke."</string>
+    <string name="biometric_dialog_tap_confirm_with_face_sfps" msgid="2499213248903257928">"Kuvulwe ngobuso. Thepha ukuze uqhubeke."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Kugunyaziwe"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Khansela Ukuqinisekisa"</string>
     <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Okukhethwayo Okwengeziwe"</string>
@@ -303,10 +310,8 @@
     <skip />
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="682984290339848844">"Izakhi ezifana nokuthi Ukwabelana Ngokushesha kanye nokuthi Thola Idivayisi Yami zisebenzisa i-Bluetooth"</string>
     <string name="turn_on_bluetooth_auto_info_enabled" msgid="7440944034584560279">"IBluetooth izovuleka kusasa ekuseni"</string>
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button (7545274861795853838) -->
-    <skip />
-    <!-- no translation found for quick_settings_bluetooth_audio_sharing_button_sharing (3069309588231072128) -->
-    <skip />
+    <string name="quick_settings_bluetooth_audio_sharing_button" msgid="7545274861795853838">"Yabelana ngomsindo"</string>
+    <string name="quick_settings_bluetooth_audio_sharing_button_sharing" msgid="3069309588231072128">"Yabelana ngomsindo"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g> ibhethri"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"Umsindo"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"Ihedisethi"</string>
@@ -471,6 +476,7 @@
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Engeza amawijethi engeziwe"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Cindezela isikhathi eside ukuze wenze ngokwezifiso amawijethi"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Yenza ngokwezifiso amawijethi"</string>
+    <string name="unlock_reason_to_customize_widgets" msgid="5011909432460546033">"Vula ukuze uhlele amawijethi ngendlela oyifisayo"</string>
     <string name="icon_description_for_disabled_widget" msgid="4693151565003206943">"Isithonjana se-app sewijethi evaliwe"</string>
     <string name="icon_description_for_pending_widget" msgid="8413816401868001755">"Isithonjana se-app sewijethi siyafakwa"</string>
     <string name="edit_widget" msgid="9030848101135393954">"Hlela amawijethi"</string>
@@ -489,6 +495,12 @@
     <string name="accessibility_action_label_select_widget" msgid="8897281501387398191">"khetha iwijethi"</string>
     <string name="accessibility_action_label_remove_widget" msgid="3373779447448758070">"susa iwijethi"</string>
     <string name="accessibility_action_label_place_widget" msgid="1914197458644168978">"beka iwijethi ekhethiwe"</string>
+    <!-- no translation found for communal_widgets_disclaimer_title (1150954395585308868) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_text (1423545475160506349) -->
+    <skip />
+    <!-- no translation found for communal_widgets_disclaimer_button (4423059765740780753) -->
+    <skip />
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Shintsha umsebenzisi"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"imenyu yokudonsela phansi"</string>
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Wonke ama-app nedatha kulesi sikhathi azosuswa."</string>
@@ -542,6 +554,9 @@
     <string name="media_projection_action_text" msgid="3634906766918186440">"Qala manje"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"Azikho izaziso"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"Azikho izaziso ezintsha"</string>
+    <string name="adaptive_notification_edu_hun_title" msgid="5720882373252389461">"Izaziso zokuzijwayeza zivuliwe"</string>
+    <string name="adaptive_notification_edu_hun_text" msgid="4260536236101821273">"Idivayisi yakho manje yehlisa ivolumu futhi yehlisa okwesikhashana esikrinini kuze kufike emizuzwini emibili lapho uthola izaziso eziningi ngesikhathi esifushane."</string>
+    <string name="go_to_adaptive_notification_settings" msgid="2423690125178298479">"Vala"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"Vula ukuze ubone izaziso ezindala"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"Le divayisi iphethwe ngumzali wakho"</string>
     <string name="quick_settings_disclosure_management_monitoring" msgid="8231336875820702180">"Inhlangano yakho ingumnikazi wale divayisi futhi ingaqapha ithrafikhi yenethiwekhi"</string>
@@ -1197,6 +1212,7 @@
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Thepha ukuze uthole olunye ulwazi"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Akukho alamu esethiwe"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"faka ukukhiya isikrini"</string>
+    <string name="accessibility_side_fingerprint_indicator_label" msgid="1673807833352363712">"Thinta inzwa yesigxivizo somunwe Inkinobho emfushane ehlangothini lwefoni"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Inzwa yesigxivizo somunwe"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"gunyaza"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"faka idivayisi"</string>
@@ -1338,7 +1354,11 @@
     <string name="privacy_dialog_active_app_usage_2" msgid="2770926061339921767">"Isetshenziswa yi-<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="privacy_dialog_recent_app_usage_2" msgid="2874689735085367167">"Kusetshenziswe kamuva yi-<xliff:g id="APP_NAME">%1$s</xliff:g> (<xliff:g id="ATTRIBUTION_LABEL">%2$s</xliff:g> • <xliff:g id="PROXY_LABEL">%3$s</xliff:g>)"</string>
     <string name="shortcut_helper_category_system" msgid="462110876978937359">"Isistimu"</string>
+    <string name="shortcut_helper_category_system_controls" msgid="3153344561395751020">"Izilawuli zesistimu"</string>
+    <string name="shortcut_helper_category_system_apps" msgid="6001757545472556810">"Ama-app esistimu"</string>
     <string name="shortcut_helper_category_multitasking" msgid="7413381961404090136">"Ukwenza imisebenzi eminingi"</string>
+    <string name="shortcutHelper_category_recent_apps" msgid="7918731953612377145">"Ama-app wakamuva"</string>
+    <string name="shortcutHelper_category_split_screen" msgid="1159669813444812244">"Hlukanisa isikrini"</string>
     <string name="shortcut_helper_category_input" msgid="8674018654124839566">"Okokufaka"</string>
     <string name="shortcut_helper_category_app_shortcuts" msgid="8010249408308587117">"Izinqamuleli Zohlelo lokusebenza"</string>
     <string name="shortcut_helper_category_a11y" msgid="6314444792641773464">"Ukufinyeleleka"</string>
@@ -1355,6 +1375,12 @@
     <skip />
     <!-- no translation found for touchpad_tutorial_done_button (176168488821755503) -->
     <skip />
+    <!-- no translation found for touchpad_tutorial_gesture_done (4784438360736821255) -->
+    <skip />
+    <string name="touchpad_back_gesture_action_title" msgid="7199067250654332735">"Buyela emuva"</string>
+    <string name="touchpad_back_gesture_guidance" msgid="4222430588599527272">"Ukuze ubuyele emuva, swayiphela kwesokunxele noma kwesokudla usebenzisa iminwe emithathu noma yikuphi ephedini yokuthinta."</string>
+    <string name="touchpad_back_gesture_animation_content_description" msgid="2646107450922379918">"Iphedi yokuthinta ebonisa iminwe emithathu iya kwesokudla nakwesokunxele"</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description" msgid="4036267494237748710">"Isikrini sedivayisi esibonisa opopayi bokuthinta kwasemuva"</string>
     <string name="keyboard_backlight_dialog_title" msgid="8273102932345564724">"Ilambu lekhibhodi"</string>
     <string name="keyboard_backlight_value" msgid="7336398765584393538">"Ileveli %1$d ka-%2$d"</string>
     <string name="home_controls_dream_label" msgid="6567105701292324257">"Izilawuli Zasekhaya"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index ba59c2f9..ca55c23 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -18,7 +18,6 @@
 -->
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-    <drawable name="notification_number_text_color">#ffffffff</drawable>
     <drawable name="system_bar_background">@color/system_bar_background_opaque</drawable>
     <color name="system_bar_background_opaque">#ff000000</color>
     <color name="system_bar_background_transparent">#00000000</color>
@@ -101,8 +100,8 @@
     <!-- The color of the navigation bar icons. Need to be in sync with ic_sysbar_* -->
     <color name="navigation_bar_icon_color">#E5FFFFFF</color>
 
-    <color name="navigation_bar_home_handle_light_color">#EBffffff</color>
-    <color name="navigation_bar_home_handle_dark_color">#99000000</color>
+    <color name="white">@*android:color/white</color>
+    <color name="black">@*android:color/black</color>
 
     <!-- The shadow color for light navigation bar icons. -->
     <color name="nav_key_button_shadow_color">#30000000</color>
@@ -237,11 +236,8 @@
     <!-- Internet Dialog -->
     <!-- Material next state on color-->
     <color name="settingslib_state_on_color">@color/settingslib_state_on</color>
-    <!-- Material next track on color-->
-    <color name="settingslib_track_on_color">@color/settingslib_track_on</color>
     <!-- Material next track off color-->
     <color name="settingslib_track_off_color">@color/settingslib_track_off</color>
-    <color name="connected_network_primary_color">#191C18</color>
     <color name="connected_network_secondary_color">#41493D</color>
 
     <color name="dream_overlay_camera_mic_off_dot_color">#FCBE03</color>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index f8762f0..84d5dcb 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -25,9 +25,6 @@
      (package/class)  -->
     <string name="config_recentsComponent" translatable="false">com.android.systemui.recents.OverviewProxyRecentsImpl</string>
 
-    <!-- Whether or not we show the number in the bar. -->
-    <bool name="config_statusBarShowNumber">false</bool>
-
     <!-- For how long the lock screen can be on before the display turns off. -->
     <integer name="config_lockScreenDisplayTimeout">10000</integer>
 
@@ -59,7 +56,7 @@
          enabled for OLED devices to reduce/prevent burn in on the navigation bar (because of the
          black background and static button placements) and disabled for all other devices to
          prevent wasting cpu cycles on the dimming animation -->
-    <bool name="config_navigation_bar_enable_auto_dim_no_visible_wallpaper">true</bool>
+    <bool name="config_navigation_bar_enable_auto_dim_no_visible_wallpaper">false</bool>
 
     <!-- The maximum number of tiles in the QuickQSPanel -->
     <integer name="quick_qs_panel_max_tiles">4</integer>
@@ -1049,4 +1046,7 @@
 
     <!-- The width of the shortcut helper container, as a fraction of the screen's width. -->
     <item name="shortcut_helper_screen_width_fraction" format="float" type="dimen">1.0</item>
+
+    <!-- Only applicable for dual shade - Allow Notifications/QS shade to anchor to the bottom. -->
+    <bool name="config_dualShadeAlignedToBottom">false</bool>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index cf91326..40bdc3e 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -810,6 +810,8 @@
     <dimen name="keyguard_smartspace_top_offset">12dp</dimen>
     <!-- The amount to translate lockscreen elements on the GONE->AOD transition -->
     <dimen name="keyguard_enter_from_top_translation_y">-100dp</dimen>
+    <!-- The amount to translate lockscreen elements on the GONE->AOD transition, on device fold -->
+    <dimen name="keyguard_enter_from_side_translation_x">-100dp</dimen>
 
     <dimen name="notification_scrim_corner_radius">32dp</dimen>
 
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 177ba598..212dae2 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -233,6 +233,7 @@
     <item type="id" name="smart_space_barrier_bottom" />
     <item type="id" name="small_clock_guideline_top" />
     <item type="id" name="weather_clock_date_and_icons_barrier_bottom" />
+    <item type="id" name="weather_clock_bc_smartspace_bottom" />
     <item type="id" name="accessibility_actions_view" />
 
     <!-- Privacy dialog -->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 8381812..dee5528 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -269,6 +269,7 @@
     <string name="screenshot_detected_multiple_template"><xliff:g id="appName" example="Google Chrome">%1$s</xliff:g> and other open apps detected this screenshot.</string>
     <!-- Add to note button used in App Clips flow to return the saved screenshot image to notes app. [CHAR LIMIT=NONE] -->
     <string name="app_clips_save_add_to_note">Add to note</string>
+    <string name="backlinks_include_link">Include link</string>
 
     <!-- Notification title displayed for screen recording [CHAR LIMIT=50]-->
     <string name="screenrecord_title">Screen Recorder</string>
@@ -320,29 +321,45 @@
     <!-- A toast message shown when the screen recording cannot be started due to a generic error [CHAR LIMIT=NONE] -->
     <string name="screenrecord_start_error">Error starting screen recording</string>
     <!-- Title for a dialog shown to the user that will let them stop recording their screen [CHAR LIMIT=50] -->
-    <string name="screenrecord_stop_dialog_title">Stop recording screen?</string>
-    <!-- Text telling a user that they will stop recording their screen if they click the "Stop recording" button [CHAR LIMIT=100] -->
-    <string name="screenrecord_stop_dialog_message">You will stop recording your screen</string>
-    <!-- Text telling a user that they will stop recording the contents of the specified [app_name] if they click the "Stop recording" button. Note that the app name will appear in bold. [CHAR LIMIT=100] -->
-    <string name="screenrecord_stop_dialog_message_specific_app">You will stop recording &lt;b><xliff:g id="app_name" example="Photos App">%1$s</xliff:g>&lt;/b></string>
+    <string name="screenrecord_stop_dialog_title">Stop recording?</string>
+    <!-- Text telling a user that they're currently recording their screen [CHAR LIMIT=100] -->
+    <string name="screenrecord_stop_dialog_message">You\'re currently recording your entire screen</string>
+    <!-- Text telling a user that they're currently recording the contents of the specified [app_name]. [CHAR LIMIT=100] -->
+    <string name="screenrecord_stop_dialog_message_specific_app">You\'re currently recording <xliff:g id="app_name" example="Photos App">%1$s</xliff:g></string>
     <!-- Button to stop a screen recording [CHAR LIMIT=35] -->
     <string name="screenrecord_stop_dialog_button">Stop recording</string>
 
+    <!-- Content description for the status bar chip shown to the user when they're sharing their screen to another app on the device [CHAR LIMIT=NONE] -->
+    <string name="share_to_app_chip_accessibility_label">Sharing screen</string>
     <!-- Title for a dialog shown to the user that will let them stop sharing their screen to another app on the device [CHAR LIMIT=50] -->
     <string name="share_to_app_stop_dialog_title">Stop sharing screen?</string>
-    <!-- Text telling a user that they will stop sharing their screen if they click the "Stop sharing" button [CHAR LIMIT=100] -->
-    <string name="share_to_app_stop_dialog_message">You will stop sharing your screen</string>
-    <!-- Text telling a user that they will stop sharing the contents of the specified [app_name] if they click the "Stop sharing" button. Note that the app name will appear in bold. [CHAR LIMIT=100] -->
-    <string name="share_to_app_stop_dialog_message_specific_app">You will stop sharing &lt;b><xliff:g id="app_name" example="Photos App">%1$s</xliff:g>&lt;/b></string>
+    <!-- Text telling a user that they're currently sharing their entire screen to [host_app_name] (i.e. [host_app_name] can currently see all screen content) [CHAR LIMIT=150] -->
+    <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app">You\'re currently sharing your entire screen with <xliff:g id="host_app_name" example="Screen Recorder App">%1$s</xliff:g></string>
+    <!-- Text telling a user that they're currently sharing their entire screen to an app (but we don't know what app) [CHAR LIMIT=150] -->
+    <string name="share_to_app_stop_dialog_message_entire_screen">You\'re currently sharing your entire screen with an app</string>
+    <!-- Text telling a user that they're currently sharing the contents of [app_being_shared_name]. (i.e. some app can currently see the content of [app_being_shared_name]). [CHAR LIMIT=150] -->
+    <string name="share_to_app_stop_dialog_message_single_app_specific">You\'re currently sharing <xliff:g id="app_being_shared_name" example="Photos App">%1$s</xliff:g></string>
+    <!-- Text telling a user that they're currently sharing their screen [CHAR LIMIT=150] -->
+    <string name="share_to_app_stop_dialog_message_single_app_generic">You\'re currently sharing an app</string>
     <!-- Button to stop screen sharing [CHAR LIMIT=35] -->
     <string name="share_to_app_stop_dialog_button">Stop sharing</string>
 
-    <!-- Title for a dialog shown to the user that will let them stop casting their screen to a different device [CHAR LIMIT=50] -->
-    <string name="cast_to_other_device_stop_dialog_title">Stop casting screen?</string>
-    <!-- Text telling a user that they will stop casting their screen to a different device if they click the "Stop casting" button [CHAR LIMIT=100] -->
-    <string name="cast_to_other_device_stop_dialog_message">You will stop casting your screen</string>
-    <!-- Text telling a user that they will stop casting the contents of the specified [app_name] to a different device if they click the "Stop casting" button. Note that the app name will appear in bold.  [CHAR LIMIT=100] -->
-    <string name="cast_to_other_device_stop_dialog_message_specific_app">You will stop casting &lt;b><xliff:g id="app_name" example="Photos App">%1$s</xliff:g>&lt;/b></string>
+    <!-- Content description for the status bar chip shown to the user when they're casting their screen to a different device [CHAR LIMIT=NONE] -->
+    <string name="cast_screen_to_other_device_chip_accessibility_label">Casting screen</string>
+    <!-- Title for a dialog shown to the user that will let them stop casting to a different device [CHAR LIMIT=50] -->
+    <string name="cast_to_other_device_stop_dialog_title">Stop casting?</string>
+    <!-- Text telling a user that they're currently casting their screen to a different device. The device receiving the cast is named [device_name]. [CHAR LIMIT=150] -->
+    <string name="cast_to_other_device_stop_dialog_message_entire_screen_with_device">You\'re currently casting your entire screen to <xliff:g id="device_name" example="Living Room Device">%1$s</xliff:g></string>
+    <!-- Text telling a user that they're currently casting their screen to a nearby device. [CHAR LIMIT=150] -->
+    <string name="cast_to_other_device_stop_dialog_message_entire_screen">You\'re currently casting your entire screen to a nearby device</string>
+    <!-- Text telling a user that they're currently casting the contents of [app_being_shared_name] to a different device. The device receiving the cast is named [device_name]. [CHAR LIMIT=150] -->
+    <string name="cast_to_other_device_stop_dialog_message_specific_app_with_device">You\'re currently casting <xliff:g id="app_being_shared_name" example="Photos App">%1$s</xliff:g> to <xliff:g id="device_name" example="Living Room Device">%2$s</xliff:g></string>
+    <!-- Text telling a user that they're currently casting the contents of [app_being_shared_name] to a different device. [CHAR LIMIT=150] -->
+    <string name="cast_to_other_device_stop_dialog_message_specific_app">You\'re currently casting <xliff:g id="app_being_shared_name" example="Photos App">%1$s</xliff:g> to a nearby device</string>
+    <!-- Text telling a user that they're currently casting to a different device. The device receiving the cast is named [device_name]. [CHAR LIMIT=100] -->
+    <string name="cast_to_other_device_stop_dialog_message_generic_with_device">You\'re currently casting to <xliff:g id="device_name" example="Living Room Device">%1$s</xliff:g></string>
+    <!-- Text telling a user that they're currently casting to a nearby device [CHAR LIMIT=100] -->
+    <string name="cast_to_other_device_stop_dialog_message_generic">You\'re currently casting to a nearby device</string>
     <!-- Button to stop screen casting to a different device [CHAR LIMIT=35] -->
     <string name="cast_to_other_device_stop_dialog_button">Stop casting</string>
 
@@ -441,6 +458,8 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_2">Face recognized. Press to continue.</string>
     <!-- Message shown when a biometric has authenticated with a user's face and is waiting for the user to confirm authentication [CHAR LIMIT=60]-->
     <string name="biometric_dialog_tap_confirm_with_face_alt_3">Face recognized. Press the unlock icon to continue.</string>
+    <!-- Message shown when a biometric has authenticated with a user's face and is waiting for the user to confirm authentication with SFPS [CHAR LIMIT=60]-->
+    <string name="biometric_dialog_tap_confirm_with_face_sfps">Unlocked by face. Tap to continue.</string>
     <!-- Talkback string when a biometric is authenticated [CHAR LIMIT=NONE] -->
     <string name="biometric_dialog_authenticated">Authenticated</string>
     <!-- Talkback string when a canceling authentication [CHAR LIMIT=NONE] -->
@@ -1186,6 +1205,8 @@
     <string name="popup_on_dismiss_cta_tile_text">Long press to customize widgets</string>
     <!-- Text for the button to configure widgets after long press. [CHAR LIMIT=50] -->
     <string name="button_to_configure_widgets_text">Customize widgets</string>
+    <!-- Text for unlock reason on the bouncer before customizing widgets. [CHAR LIMIT=NONE] -->
+    <string name="unlock_reason_to_customize_widgets">Unlock to customize widgets</string>
     <!-- Description for the App icon of disabled widget. [CHAR LIMIT=NONE] -->
     <string name="icon_description_for_disabled_widget">App icon for disabled widget</string>
     <!-- Description for the App icon of a package that is currently being installed. [CHAR LIMIT=NONE] -->
@@ -1222,6 +1243,16 @@
     <string name="accessibility_action_label_remove_widget">remove widget</string>
     <!-- Label for accessibility action to place a widget in edit mode after selecting move widget. [CHAR LIMIT=NONE] -->
     <string name="accessibility_action_label_place_widget">place selected widget</string>
+    <!-- Title in the communal widget picker. [CHAR LIMIT=50] -->
+    <string name="communal_widget_picker_title">Lock screen widgets</string>
+    <!-- Text displayed below the title in the communal widget picker providing additional details about the communal surface. [CHAR LIMIT=80] -->
+    <string name="communal_widget_picker_description">Anyone can view widgets on your lock screen, even if your tablet\'s locked.</string>
+    <!-- Title shown above information regarding lock screen widgets. [CHAR LIMIT=50] -->
+    <string name="communal_widgets_disclaimer_title">Lock screen widgets</string>
+    <!-- Information about lock screen widgets presented to the user. [CHAR LIMIT=NONE] -->
+    <string name="communal_widgets_disclaimer_text">To open an app using a widget, you\u2019ll need to verify it\u2019s you. Also, keep in mind that anyone can view them, even when your tablet\u2019s locked. Some widgets may not have been intended for your lock screen and may be unsafe to add here.</string>
+    <!-- Button for user to verify they understand the information presented. [CHAR LIMIT=50] -->
+    <string name="communal_widgets_disclaimer_button">Got it</string>
 
     <!-- Related to user switcher --><skip/>
 
@@ -1380,6 +1411,15 @@
     <!-- Text which is shown in the expanded notification shade when there are currently no notifications visible that the user hasn't already seen. [CHAR LIMIT=30] -->
     <string name="no_unseen_notif_text">No new notifications</string>
 
+    <!-- Title of heads up notification for adaptive notifications user education. [CHAR LIMIT=50] -->
+    <string name="adaptive_notification_edu_hun_title">Adaptive notifications is on</string>
+
+    <!-- Text of heads up notification for adaptive notifications user education. [CHAR LIMIT=100] -->
+    <string name="adaptive_notification_edu_hun_text">Your device now lowers the volume and reduces pop-ups on the screen for up to two minutes when you receive many notifications in a short time span.</string>
+
+    <!-- Action label for going to adaptive notification settings [CHAR LIMIT=20] -->
+    <string name="go_to_adaptive_notification_settings">Turn off</string>
+
     <!-- Text which is shown in the locked notification shade when there are currently no notifications, but if the user were to unlock, notifications would appear. [CHAR LIMIT=40] -->
     <string name="unlock_to_see_notif_text">Unlock to see older notifications</string>
 
@@ -3526,10 +3566,26 @@
          shows the user which keyboard shortcuts they can use. The "System" shortcuts are for
          example "Take a screenshot" or "Go back". [CHAR LIMIT=NONE] -->
     <string name="shortcut_helper_category_system">System</string>
+    <!-- Title of the keyboard shortcut helper category "System controls". The helper is a component
+         that shows the user which keyboard shortcuts they can use. The "System controls" shortcuts
+         are for example "Go to home screen" or "App apps search". [CHAR LIMIT=NONE] -->
+    <string name="shortcut_helper_category_system_controls">System controls</string>
+    <!-- Title of the keyboard shortcut helper category "System apps". The helper is a component
+         that shows the user which keyboard shortcuts they can use. The "System apps" shortcuts
+         are for example "Settings" or "Take a note". [CHAR LIMIT=NONE] -->
+    <string name="shortcut_helper_category_system_apps">System apps</string>
     <!-- Title of the keyboard shortcut helper category "Multitasking". The helper is a component
          that shows the user which keyboard shortcuts they can use. The "Multitasking" shortcuts are
          for example "Enter split screen". [CHAR LIMIT=NONE] -->
     <string name="shortcut_helper_category_multitasking">Multitasking</string>
+    <!-- Title of the keyboard shortcut helper category "Recent apps". The helper is a component
+         that shows the user which keyboard shortcuts they can use. The "Recent apps" shortcuts are
+         for example "Cycle through recent apps". [CHAR LIMIT=NONE] -->
+    <string name="shortcutHelper_category_recent_apps">Recent apps</string>
+    <!-- Title of the keyboard shortcut helper category "Split screen". The helper is a component
+         that shows the user which keyboard shortcuts they can use. The "Split screen" shortcuts are
+         for example "Move current app to left split". [CHAR LIMIT=NONE] -->
+    <string name="shortcutHelper_category_split_screen">Split screen</string>
     <!-- Title of the keyboard shortcut helper category "Input". The helper is a component
          that shows the user which keyboard shortcuts they can use. The "Input" shortcuts are
          the ones provided by the keyboard. Examples are "Access emoji" or "Switch to next language"
@@ -3577,6 +3633,14 @@
     <string name="touchpad_tutorial_action_key_button">Action key</string>
     <!-- Label for button finishing touchpad tutorial [CHAR LIMIT=NONE] -->
     <string name="touchpad_tutorial_done_button">Done</string>
+    <!-- Screen title after gesture was done successfully [CHAR LIMIT=NONE] -->
+    <string name="touchpad_tutorial_gesture_done">Great job!</string>
+    <!-- Touchpad back gesture action name in tutorial [CHAR LIMIT=NONE] -->
+    <string name="touchpad_back_gesture_action_title">Go back</string>
+    <!-- Touchpad back gesture guidance in gestures tutorial [CHAR LIMIT=NONE] -->
+    <string name="touchpad_back_gesture_guidance">To go back, swipe left or right using three fingers anywhere on the touchpad.</string>
+    <string name="touchpad_back_gesture_animation_content_description">Touchpad showing three fingers moving right and left</string>
+    <string name="touchpad_back_gesture_screen_animation_content_description">Device screen showing animation for back gesture</string>
 
     <!-- Content description for keyboard backlight brightness dialog [CHAR LIMIT=NONE] -->
     <string name="keyboard_backlight_dialog_title">Keyboard backlight</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 73b7586..047578c 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -622,14 +622,14 @@
     <style name="DualToneLightTheme">
         <item name="iconBackgroundColor">@color/light_mode_icon_color_dual_tone_background</item>
         <item name="fillColor">@color/light_mode_icon_color_dual_tone_fill</item>
-        <item name="singleToneColor">@color/light_mode_icon_color_single_tone</item>
-        <item name="homeHandleColor">@color/navigation_bar_home_handle_light_color</item>
+        <item name="singleToneColor">@color/white</item>
+        <item name="homeHandleColor">@color/white</item>
     </style>
     <style name="DualToneDarkTheme">
         <item name="iconBackgroundColor">@color/dark_mode_icon_color_dual_tone_background</item>
         <item name="fillColor">@color/dark_mode_icon_color_dual_tone_fill</item>
-        <item name="singleToneColor">@color/dark_mode_icon_color_single_tone</item>
-        <item name="homeHandleColor">@color/navigation_bar_home_handle_dark_color</item>
+        <item name="singleToneColor">@color/black</item>
+        <item name="homeHandleColor">@color/black</item>
     </style>
     <style name="QSHeaderDarkTheme">
         <item name="iconBackgroundColor">@color/dark_mode_qs_icon_color_dual_tone_background</item>
@@ -648,7 +648,7 @@
         <item name="singleToneColor">?android:attr/textColorPrimary</item>
     </style>
     <style name="ScreenPinningRequestTheme" parent="@*android:style/ThemeOverlay.DeviceDefault.Accent">
-        <item name="singleToneColor">@color/light_mode_icon_color_single_tone</item>
+        <item name="singleToneColor">@color/white</item>
     </style>
 
     <style name="TextAppearance.Volume">
@@ -1315,7 +1315,7 @@
         <item name="android:background">?android:attr/selectableItemBackground</item>
     </style>
 
-    <style name="MainSwitch.Settingslib" parent="@android:style/Theme.DeviceDefault">
+    <style name="MainSwitch.Settingslib" parent="@android:style/Theme.DeviceDefault.DayNight">
         <item name="android:switchMinWidth">@dimen/settingslib_min_switch_width</item>
     </style>
 
@@ -1358,6 +1358,7 @@
 
     <style name="InternetDialog.NetworkTitle.Active">
         <item name="android:textAppearance">@style/TextAppearance.InternetDialog.Active</item>
+        <item name="android:textColor">?androidprv:attr/materialColorOnPrimaryContainer</item>
     </style>
 
     <style name="InternetDialog.NetworkSummary">
@@ -1370,18 +1371,19 @@
     <style name="InternetDialog.NetworkSummary.Active">
         <item name="android:textAppearance">@style/TextAppearance.InternetDialog.Secondary.Active
         </item>
+        <item name="android:textColor">?androidprv:attr/materialColorOnPrimaryContainer</item>
     </style>
 
     <style name="TextAppearance.InternetDialog">
         <item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
         <item name="android:textSize">16sp</item>
-        <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="android:textColor">?androidprv:attr/materialColorOnSurface</item>
         <item name="android:textDirection">locale</item>
     </style>
 
     <style name="TextAppearance.InternetDialog.Secondary">
         <item name="android:textSize">14sp</item>
-        <item name="android:textColor">?android:attr/textColorSecondary</item>
+        <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
     </style>
 
     <style name="TextAppearance.InternetDialog.Active"/>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/education/GestureType.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/education/GestureType.kt
new file mode 100644
index 0000000..9a5c77a
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/education/GestureType.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.education
+
+enum class GestureType {
+    BACK_GESTURE,
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
index d5bc10a..c00007b 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl
@@ -22,7 +22,7 @@
 import android.view.MotionEvent;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 
-// Next ID: 29
+// Next ID: 34
 oneway interface IOverviewProxy {
 
     void onActiveNavBarRegionChanges(in Region activeRegion) = 11;
@@ -83,6 +83,11 @@
     void onSystemBarAttributesChanged(int displayId, int behavior) = 20;
 
     /**
+     * Sent when {@link TaskbarDelegate#onTransitionModeUpdated} is called.
+     */
+    void onTransitionModeUpdated(int barMode, boolean checkBarModes) = 21;
+
+    /**
      * Sent when the desired dark intensity of the nav buttons has changed
      */
     void onNavButtonsDarkIntensityChanged(float darkIntensity) = 22;
@@ -101,4 +106,30 @@
      * Sent when the task bar stash state is toggled.
      */
     void onTaskbarToggled() = 27;
+
+    /**
+     * Sent when the wallpaper visibility is updated.
+     */
+    void updateWallpaperVisibility(int displayId, boolean visible) = 29;
+
+    /**
+     * Sent when {@link TaskbarDelegate#checkNavBarModes} is called.
+     */
+    void checkNavBarModes() = 30;
+
+    /**
+     * Sent when {@link TaskbarDelegate#finishBarAnimations} is called.
+     */
+    void finishBarAnimations() = 31;
+
+    /**
+     * Sent when {@link TaskbarDelegate#touchAutoDim} is called. {@param reset} is true, when auto
+     * dim is reset after a timeout.
+     */
+    void touchAutoDim(boolean reset) = 32;
+
+    /**
+     * Sent when {@link TaskbarDelegate#transitionTo} is called.
+     */
+    void transitionTo(int barMode, boolean animate) = 33;
 }
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 f06e333..edf855f 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
@@ -246,6 +246,12 @@
     public ActivityManager.RecentTaskInfo.PersistedTaskSnapshotData lastSnapshotData =
             new ActivityManager.RecentTaskInfo.PersistedTaskSnapshotData();
 
+    @ViewDebug.ExportedProperty(category="recents")
+    public boolean isVisible;
+
+    @ViewDebug.ExportedProperty(category = "recents")
+    public boolean isMinimized;
+
     public Task() {
         // Do nothing
     }
@@ -279,6 +285,8 @@
         lastSnapshotData.set(other.lastSnapshotData);
         positionInParent = other.positionInParent;
         appBounds = other.appBounds;
+        isVisible = other.isVisible;
+        isMinimized = other.isMinimized;
     }
 
     /**
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/PreviewPositionHelper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/PreviewPositionHelper.java
index 3cb5bc7..ea73216 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/PreviewPositionHelper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/PreviewPositionHelper.java
@@ -10,7 +10,6 @@
 import android.graphics.RectF;
 
 import com.android.systemui.shared.recents.model.ThumbnailData;
-import com.android.wm.shell.util.SplitBounds;
 
 /**
  * Utility class to position the thumbnail in the TaskView
@@ -35,8 +34,6 @@
 
     private final Matrix mMatrix = new Matrix();
     private boolean mIsOrientationChanged;
-    private SplitBounds mSplitBounds;
-    private int mDesiredStagePosition;
 
     public Matrix getMatrix() {
         return mMatrix;
@@ -50,11 +47,6 @@
         return mIsOrientationChanged;
     }
 
-    public void setSplitBounds(SplitBounds splitBounds, int desiredStagePosition) {
-        mSplitBounds = splitBounds;
-        mDesiredStagePosition = desiredStagePosition;
-    }
-
     /**
      * Updates the matrix based on the provided parameters
      */
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
index 660f0db..2eac393 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
@@ -53,6 +53,9 @@
 import android.view.animation.Interpolator;
 import android.view.animation.LinearInterpolator;
 
+import androidx.annotation.Nullable;
+import androidx.annotation.WorkerThread;
+
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.UiEvent;
 import com.android.internal.logging.UiEventLogger;
@@ -142,12 +145,14 @@
     };
 
     private final IRotationWatcher.Stub mRotationWatcher = new IRotationWatcher.Stub() {
+        @WorkerThread
         @Override
         public void onRotationChanged(final int rotation) {
+            @Nullable Boolean rotationLocked = RotationPolicyUtil.isRotationLocked(mContext);
             // We need this to be scheduled as early as possible to beat the redrawing of
             // window in response to the orientation change.
             mMainThreadHandler.postAtFrontOfQueue(() -> {
-                onRotationWatcherChanged(rotation);
+                onRotationWatcherChanged(rotation, rotationLocked);
             });
         }
     };
@@ -281,8 +286,8 @@
         TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
     }
 
-    public void setRotationLockedAtAngle(int rotationSuggestion, String caller) {
-        final Boolean isLocked = isRotationLocked();
+    public void setRotationLockedAtAngle(
+            @Nullable Boolean isLocked, int rotationSuggestion, String caller) {
         if (isLocked == null) {
             // Ignore if we can't read the setting for the current user
             return;
@@ -291,21 +296,6 @@
                 /* rotation= */ rotationSuggestion, caller);
     }
 
-    /**
-     * @return whether rotation is currently locked, or <code>null</code> if the setting couldn't
-     *         be read
-     */
-    public Boolean isRotationLocked() {
-        try {
-            return RotationPolicy.isRotationLocked(mContext);
-        } catch (SecurityException e) {
-            // TODO(b/279561841): RotationPolicy uses the current user to resolve the setting which
-            //                    may change before the rotation watcher can be unregistered
-            Log.e(TAG, "Failed to get isRotationLocked", e);
-            return null;
-        }
-    }
-
     public void setRotateSuggestionButtonState(boolean visible) {
         setRotateSuggestionButtonState(visible, false /* force */);
     }
@@ -469,7 +459,7 @@
      * Called when the rotation watcher rotation changes, either from the watcher registered
      * internally in this class, or a signal propagated from NavBarHelper.
      */
-    public void onRotationWatcherChanged(int rotation) {
+    public void onRotationWatcherChanged(int rotation, @Nullable Boolean isRotationLocked) {
         if (!mListenersRegistered) {
             // Ignore if not registered
             return;
@@ -477,17 +467,16 @@
 
         // If the screen rotation changes while locked, potentially update lock to flow with
         // new screen rotation and hide any showing suggestions.
-        Boolean rotationLocked = isRotationLocked();
-        if (rotationLocked == null) {
+        if (isRotationLocked == null) {
             // Ignore if we can't read the setting for the current user
             return;
         }
         // The isVisible check makes the rotation button disappear when we are not locked
         // (e.g. for tabletop auto-rotate).
-        if (rotationLocked || mRotationButton.isVisible()) {
+        if (isRotationLocked || mRotationButton.isVisible()) {
             // Do not allow a change in rotation to set user rotation when docked.
-            if (shouldOverrideUserLockPrefs(rotation) && rotationLocked && !mDocked) {
-                setRotationLockedAtAngle(rotation, /* caller= */
+            if (shouldOverrideUserLockPrefs(rotation) && isRotationLocked && !mDocked) {
+                setRotationLockedAtAngle(true, rotation, /* caller= */
                         "RotationButtonController#onRotationWatcherChanged");
             }
             setRotateSuggestionButtonState(false /* visible */, true /* forced */);
@@ -592,7 +581,8 @@
     private void onRotateSuggestionClick(View v) {
         mUiEventLogger.log(RotationButtonEvent.ROTATION_SUGGESTION_ACCEPTED);
         incrementNumAcceptedRotationSuggestionsIfNeeded();
-        setRotationLockedAtAngle(mLastRotationSuggestion,
+        setRotationLockedAtAngle(
+                RotationPolicyUtil.isRotationLocked(mContext), mLastRotationSuggestion,
                 /* caller= */ "RotationButtonController#onRotateSuggestionClick");
         Log.i(TAG, "onRotateSuggestionClick() mLastRotationSuggestion=" + mLastRotationSuggestion);
         v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationPolicyUtil.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationPolicyUtil.kt
new file mode 100644
index 0000000..eac4a10
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationPolicyUtil.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.rotation
+
+import android.content.Context
+import android.util.Log
+import com.android.internal.view.RotationPolicy
+
+class RotationPolicyUtil {
+    companion object {
+        /**
+         * Recommend to be called on bg thread, or reuse the results. It's because
+         * [RotationPolicy.isRotationLocked] may make a binder call to query settings.
+         *
+         * @return whether rotation is currently locked, or <code>null</code> if the setting
+         *   couldn't be read
+         */
+        @JvmStatic
+        fun isRotationLocked(context: Context): Boolean? {
+            try {
+                return RotationPolicy.isRotationLocked(context)
+            } catch (e: SecurityException) {
+                // TODO(b/279561841): RotationPolicy uses the current user to resolve the setting
+                // which may change before the rotation watcher can be unregistered
+                Log.e("RotationPolicy", "Failed to get isRotationLocked", e)
+                return null
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/statusbar/phone/BarTransitions.java b/packages/SystemUI/shared/src/com/android/systemui/shared/statusbar/phone/BarTransitions.java
new file mode 100644
index 0000000..c123306
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/statusbar/phone/BarTransitions.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.statusbar.phone;
+
+import android.annotation.ColorInt;
+import android.annotation.IntDef;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.View;
+
+import com.android.app.animation.Interpolators;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+public class BarTransitions {
+    private static final boolean DEBUG = false;
+    private static final boolean DEBUG_COLORS = false;
+
+    @ColorInt
+    private static final int SYSTEM_BAR_BACKGROUND_OPAQUE = Color.BLACK;
+    @ColorInt
+    private static final int SYSTEM_BAR_BACKGROUND_TRANSPARENT = Color.TRANSPARENT;
+
+    public static final int MODE_TRANSPARENT = 0;
+    public static final int MODE_SEMI_TRANSPARENT = 1;
+    public static final int MODE_TRANSLUCENT = 2;
+    public static final int MODE_LIGHTS_OUT = 3;
+    public static final int MODE_OPAQUE = 4;
+    public static final int MODE_WARNING = 5;
+    public static final int MODE_LIGHTS_OUT_TRANSPARENT = 6;
+
+    @IntDef(flag = true, prefix = { "MODE_" }, value = {
+            MODE_OPAQUE,
+            MODE_SEMI_TRANSPARENT,
+            MODE_TRANSLUCENT,
+            MODE_LIGHTS_OUT,
+            MODE_TRANSPARENT,
+            MODE_WARNING,
+            MODE_LIGHTS_OUT_TRANSPARENT
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TransitionMode {}
+
+    public static final int LIGHTS_IN_DURATION = 250;
+    public static final int LIGHTS_OUT_DURATION = 1500;
+    public static final int BACKGROUND_DURATION = 200;
+
+    private final String mTag;
+    private final View mView;
+    protected final BarBackgroundDrawable mBarBackground;
+
+    private @TransitionMode int mMode;
+    private boolean mAlwaysOpaque = false;
+
+    public BarTransitions(View view, int gradientResourceId) {
+        mTag = "BarTransitions." + view.getClass().getSimpleName();
+        mView = view;
+        mBarBackground = new BarBackgroundDrawable(mView.getContext(), gradientResourceId);
+        mView.setBackground(mBarBackground);
+    }
+
+    public void destroy() {
+        // To be overridden
+    }
+
+    public int getMode() {
+        return mMode;
+    }
+
+    public void setAutoDim(boolean autoDim) {
+        // Default is don't care.
+    }
+
+    /**
+     * @param alwaysOpaque if {@code true}, the bar's background will always be opaque, regardless
+     *         of what mode it is currently set to.
+     */
+    public void setAlwaysOpaque(boolean alwaysOpaque) {
+        mAlwaysOpaque = alwaysOpaque;
+    }
+
+    public boolean isAlwaysOpaque() {
+        // Low-end devices do not support translucent modes, fallback to opaque
+        return mAlwaysOpaque;
+    }
+
+    public void transitionTo(int mode, boolean animate) {
+        if (isAlwaysOpaque() && (mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSLUCENT
+                || mode == MODE_TRANSPARENT)) {
+            mode = MODE_OPAQUE;
+        }
+        if (isAlwaysOpaque() && (mode == MODE_LIGHTS_OUT_TRANSPARENT)) {
+            mode = MODE_LIGHTS_OUT;
+        }
+        if (mMode == mode) return;
+        int oldMode = mMode;
+        mMode = mode;
+        if (DEBUG) Log.d(mTag, String.format("%s -> %s animate=%s",
+                modeToString(oldMode), modeToString(mode),  animate));
+        onTransition(oldMode, mMode, animate);
+    }
+
+    protected void onTransition(int oldMode, int newMode, boolean animate) {
+        applyModeBackground(oldMode, newMode, animate);
+    }
+
+    protected void applyModeBackground(int oldMode, int newMode, boolean animate) {
+        if (DEBUG) Log.d(mTag, String.format("applyModeBackground oldMode=%s newMode=%s animate=%s",
+                modeToString(oldMode), modeToString(newMode), animate));
+        mBarBackground.applyModeBackground(oldMode, newMode, animate);
+    }
+
+    public static String modeToString(int mode) {
+        if (mode == MODE_OPAQUE) return "MODE_OPAQUE";
+        if (mode == MODE_SEMI_TRANSPARENT) return "MODE_SEMI_TRANSPARENT";
+        if (mode == MODE_TRANSLUCENT) return "MODE_TRANSLUCENT";
+        if (mode == MODE_LIGHTS_OUT) return "MODE_LIGHTS_OUT";
+        if (mode == MODE_TRANSPARENT) return "MODE_TRANSPARENT";
+        if (mode == MODE_WARNING) return "MODE_WARNING";
+        if (mode == MODE_LIGHTS_OUT_TRANSPARENT) return "MODE_LIGHTS_OUT_TRANSPARENT";
+        throw new IllegalArgumentException("Unknown mode " + mode);
+    }
+
+    public void finishAnimations() {
+        mBarBackground.finishAnimation();
+    }
+
+    protected boolean isLightsOut(int mode) {
+        return mode == MODE_LIGHTS_OUT || mode == MODE_LIGHTS_OUT_TRANSPARENT;
+    }
+
+    protected static class BarBackgroundDrawable extends Drawable {
+        private final int mOpaque;
+        private final int mSemiTransparent;
+        private final int mTransparent;
+        private final int mWarning;
+        private final Drawable mGradient;
+
+        private int mMode = -1;
+        private boolean mAnimating;
+        private long mStartTime;
+        private long mEndTime;
+
+        private int mGradientAlpha;
+        private int mColor;
+        private float mOverrideAlpha = 1f;
+        private PorterDuffColorFilter mTintFilter;
+        private Paint mPaint = new Paint();
+
+        private int mGradientAlphaStart;
+        private int mColorStart;
+        private Rect mFrame;
+
+
+        public BarBackgroundDrawable(Context context, int gradientResourceId) {
+            final Resources res = context.getResources();
+            if (DEBUG_COLORS) {
+                mOpaque = 0xff0000ff;
+                mSemiTransparent = 0x7f0000ff;
+                mTransparent = 0x2f0000ff;
+                mWarning = 0xffff0000;
+            } else {
+                mOpaque = SYSTEM_BAR_BACKGROUND_OPAQUE;
+                mSemiTransparent = context.getColor(
+                        com.android.internal.R.color.system_bar_background_semi_transparent);
+                mTransparent = SYSTEM_BAR_BACKGROUND_TRANSPARENT;
+                mWarning = getColorAttrDefaultColor(context, android.R.attr.colorError, 0);
+            }
+            mGradient = context.getDrawable(gradientResourceId);
+        }
+
+        public void setFrame(Rect frame) {
+            mFrame = frame;
+        }
+
+        public void setOverrideAlpha(float overrideAlpha) {
+            mOverrideAlpha = overrideAlpha;
+            invalidateSelf();
+        }
+
+        public float getOverrideAlpha() {
+            return mOverrideAlpha;
+        }
+
+        public int getColor() {
+            return mColor;
+        }
+
+        public Rect getFrame() {
+            return mFrame;
+        }
+
+        @Override
+        public void setAlpha(int alpha) {
+            // noop
+        }
+
+        @Override
+        public void setColorFilter(ColorFilter colorFilter) {
+            // noop
+        }
+
+        @Override
+        public void setTint(int color) {
+            PorterDuff.Mode targetMode = mTintFilter == null ? Mode.SRC_IN :
+                    mTintFilter.getMode();
+            if (mTintFilter == null || mTintFilter.getColor() != color) {
+                mTintFilter = new PorterDuffColorFilter(color, targetMode);
+            }
+            invalidateSelf();
+        }
+
+        @Override
+        public void setTintMode(Mode tintMode) {
+            int targetColor = mTintFilter == null ? 0 : mTintFilter.getColor();
+            if (mTintFilter == null || mTintFilter.getMode() != tintMode) {
+                mTintFilter = new PorterDuffColorFilter(targetColor, tintMode);
+            }
+            invalidateSelf();
+        }
+
+        @Override
+        protected void onBoundsChange(Rect bounds) {
+            super.onBoundsChange(bounds);
+            mGradient.setBounds(bounds);
+        }
+
+        public void applyModeBackground(int oldMode, int newMode, boolean animate) {
+            if (mMode == newMode) return;
+            mMode = newMode;
+            mAnimating = animate;
+            if (animate) {
+                long now = SystemClock.elapsedRealtime();
+                mStartTime = now;
+                mEndTime = now + BACKGROUND_DURATION;
+                mGradientAlphaStart = mGradientAlpha;
+                mColorStart = mColor;
+            }
+            invalidateSelf();
+        }
+
+        @Override
+        public int getOpacity() {
+            return PixelFormat.TRANSLUCENT;
+        }
+
+        public void finishAnimation() {
+            if (mAnimating) {
+                mAnimating = false;
+                invalidateSelf();
+            }
+        }
+
+        @Override
+        public void draw(Canvas canvas) {
+            int targetGradientAlpha = 0, targetColor = 0;
+            if (mMode == MODE_WARNING) {
+                targetColor = mWarning;
+            } else if (mMode == MODE_TRANSLUCENT) {
+                targetColor = mSemiTransparent;
+            } else if (mMode == MODE_SEMI_TRANSPARENT) {
+                targetColor = mSemiTransparent;
+            } else if (mMode == MODE_TRANSPARENT || mMode == MODE_LIGHTS_OUT_TRANSPARENT) {
+                targetColor = mTransparent;
+            } else {
+                targetColor = mOpaque;
+            }
+
+            if (!mAnimating) {
+                mColor = targetColor;
+                mGradientAlpha = targetGradientAlpha;
+            } else {
+                final long now = SystemClock.elapsedRealtime();
+                if (now >= mEndTime) {
+                    mAnimating = false;
+                    mColor = targetColor;
+                    mGradientAlpha = targetGradientAlpha;
+                } else {
+                    final float t = (now - mStartTime) / (float)(mEndTime - mStartTime);
+                    final float v = Math.max(0, Math.min(
+                            Interpolators.LINEAR.getInterpolation(t), 1));
+                    mGradientAlpha = (int)(v * targetGradientAlpha + mGradientAlphaStart * (1 - v));
+                    mColor = Color.argb(
+                            (int) (v * Color.alpha(targetColor) + Color.alpha(mColorStart) * (1
+                                    - v)),
+                            (int) (v * Color.red(targetColor) + Color.red(mColorStart) * (1 - v)),
+                            (int) (v * Color.green(targetColor) + Color.green(mColorStart) * (1
+                                    - v)),
+                            (int) (v * Color.blue(targetColor) + Color.blue(mColorStart) * (1
+                                    - v)));
+                }
+            }
+            if (mGradientAlpha > 0) {
+                mGradient.setAlpha(mGradientAlpha);
+                mGradient.draw(canvas);
+            }
+
+            if (Color.alpha(mColor) > 0) {
+                mPaint.setColor(mColor);
+                if (mTintFilter != null) {
+                    mPaint.setColorFilter(mTintFilter);
+                }
+                mPaint.setAlpha((int) (Color.alpha(mColor) * mOverrideAlpha));
+                if (mFrame != null) {
+                    canvas.drawRect(mFrame, mPaint);
+                } else {
+                    canvas.drawPaint(mPaint);
+                }
+            }
+            if (mAnimating) {
+                invalidateSelf();  // keep going
+            }
+        }
+    }
+
+    /** Get color styled attribute {@code attr}, default to {@code defValue} if not found. */
+    @ColorInt
+    public static int getColorAttrDefaultColor(Context context, int attr, @ColorInt int defValue) {
+        TypedArray ta = context.obtainStyledAttributes(new int[] {attr});
+        @ColorInt int colorAccent = ta.getColor(0, defValue);
+        ta.recycle();
+        return colorAccent;
+    }
+}
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 c0c8b75..4ef1f93 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
@@ -124,6 +124,10 @@
     public static final long SYSUI_STATE_SHORTCUT_HELPER_SHOWING = 1L << 32;
     // Touchpad gestures are disabled
     public static final long SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED = 1L << 33;
+    // PiP animation is running
+    public static final long SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING = 1L << 34;
+    // Communal hub is showing
+    public static final long SYSUI_STATE_COMMUNAL_HUB_SHOWING = 1L << 35;
 
     // Mask for SystemUiStateFlags to isolate SYSUI_STATE_AWAKE and
     // SYSUI_STATE_WAKEFULNESS_TRANSITION, to match WAKEFULNESS_* constants
@@ -173,6 +177,8 @@
             SYSUI_STATE_STATUS_BAR_KEYGUARD_GOING_AWAY,
             SYSUI_STATE_SHORTCUT_HELPER_SHOWING,
             SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED,
+            SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING,
+            SYSUI_STATE_COMMUNAL_HUB_SHOWING,
     })
     public @interface SystemUiStateFlags {}
 
@@ -277,6 +283,12 @@
         if ((flags & SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED) != 0) {
             str.add("touchpad_gestures_disabled");
         }
+        if ((flags & SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING) != 0) {
+            str.add("disable_gesture_pip_animating");
+        }
+        if ((flags & SYSUI_STATE_COMMUNAL_HUB_SHOWING) != 0) {
+            str.add("communal_hub_showing");
+        }
 
         return str.toString();
     }
@@ -330,7 +342,8 @@
         // the keyguard)
         if ((sysuiStateFlags & SYSUI_STATE_BOUNCER_SHOWING) != 0
                 || (sysuiStateFlags & SYSUI_STATE_DIALOG_SHOWING) != 0
-                || (sysuiStateFlags & SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING) != 0) {
+                || (sysuiStateFlags & SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING) != 0
+                || (sysuiStateFlags & SYSUI_STATE_COMMUNAL_HUB_SHOWING) != 0) {
             return false;
         }
         if ((sysuiStateFlags & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) != 0) {
diff --git a/packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt b/packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt
index af29b05..8d1de0e 100644
--- a/packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt
+++ b/packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt
@@ -62,6 +62,8 @@
      * @param error: a [Throwable] to log.
      * @param message: a lazily evaluated message you wish to log.
      */
+    @JvmOverloads
+    @JvmName("logcatMessage")
     inline fun Any.debugLog(
         enabled: Boolean = Build.IS_DEBUGGABLE,
         priority: Int = Log.DEBUG,
diff --git a/packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt b/packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt
index 2764a1f..e29ce2d 100644
--- a/packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt
+++ b/packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt
@@ -22,6 +22,7 @@
 /** An empty logger for release builds. */
 object DebugLogger {
 
+    @JvmOverloads
     @JvmName("logcatMessage")
     inline fun Any.debugLog(
         enabled: Boolean = Build.IS_DEBUGGABLE,
diff --git a/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt b/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
index 5e76801..bf1f93f 100644
--- a/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
@@ -28,6 +28,7 @@
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT
+import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_WAKE
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS
@@ -86,6 +87,12 @@
          * Trigger ActiveUnlock when the assistant is triggered.
          */
         ASSISTANT,
+        /**
+         * Trigger ActiveUnlock on legacy unlock intents. This includes tapping on the empty space
+         * of the notification shadse when face auth is enrolled and re-trying face auth on the
+         * primary bouncer.
+         */
+        UNLOCK_INTENT_LEGACY,
     }
 
     /**
@@ -99,6 +106,7 @@
     }
 
     private var requestActiveUnlockOnWakeup = false
+    private var requestActiveUnlockOnUnlockIntentLegacy = false
     private var requestActiveUnlockOnUnlockIntent = false
     private var requestActiveUnlockOnBioFail = false
 
@@ -110,6 +118,8 @@
 
     private val settingsObserver = object : ContentObserver(handler) {
         private val wakeUri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_WAKE)
+        private val unlockIntentLegacyUri =
+            secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY)
         private val unlockIntentUri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT)
         private val bioFailUri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_BIOMETRIC_FAIL)
         private val faceErrorsUri = secureSettings.getUriFor(ACTIVE_UNLOCK_ON_FACE_ERRORS)
@@ -164,6 +174,15 @@
                         ACTIVE_UNLOCK_ON_WAKE, 0, selectedUserInteractor.getSelectedUserId()) == 1
             }
 
+            if (selfChange || uris.contains(unlockIntentLegacyUri)) {
+                requestActiveUnlockOnUnlockIntentLegacy =
+                    secureSettings.getIntForUser(
+                        ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY,
+                        0,
+                        selectedUserInteractor.getSelectedUserId()
+                    ) == 1
+            }
+
             if (selfChange || uris.contains(unlockIntentUri)) {
                 requestActiveUnlockOnUnlockIntent = secureSettings.getIntForUser(
                         ACTIVE_UNLOCK_ON_UNLOCK_INTENT, 0,
@@ -257,7 +276,7 @@
      */
     fun isActiveUnlockEnabled(): Boolean {
         return requestActiveUnlockOnWakeup || requestActiveUnlockOnUnlockIntent ||
-                requestActiveUnlockOnBioFail
+            requestActiveUnlockOnBioFail || requestActiveUnlockOnUnlockIntentLegacy
     }
 
     /**
@@ -299,15 +318,18 @@
     fun shouldAllowActiveUnlockFromOrigin(requestOrigin: ActiveUnlockRequestOrigin): Boolean {
         return when (requestOrigin) {
             ActiveUnlockRequestOrigin.WAKE -> requestActiveUnlockOnWakeup
-
+            ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY ->
+                requestActiveUnlockOnUnlockIntentLegacy
             ActiveUnlockRequestOrigin.UNLOCK_INTENT ->
-                requestActiveUnlockOnUnlockIntent || requestActiveUnlockOnWakeup ||
-                        (shouldRequestActiveUnlockOnUnlockIntentFromBiometricEnrollment())
-
+                requestActiveUnlockOnUnlockIntent ||
+                    requestActiveUnlockOnUnlockIntentLegacy ||
+                    requestActiveUnlockOnWakeup ||
+                    (shouldRequestActiveUnlockOnUnlockIntentFromBiometricEnrollment())
             ActiveUnlockRequestOrigin.BIOMETRIC_FAIL ->
-                requestActiveUnlockOnBioFail || requestActiveUnlockOnUnlockIntent ||
-                        requestActiveUnlockOnWakeup
-
+                requestActiveUnlockOnBioFail ||
+                    requestActiveUnlockOnUnlockIntentLegacy ||
+                    requestActiveUnlockOnUnlockIntent ||
+                    requestActiveUnlockOnWakeup
             ActiveUnlockRequestOrigin.ASSISTANT -> isActiveUnlockEnabled()
         }
     }
@@ -345,6 +367,9 @@
     override fun dump(pw: PrintWriter, args: Array<out String>) {
         pw.println("Settings:")
         pw.println("   requestActiveUnlockOnWakeup=$requestActiveUnlockOnWakeup")
+        pw.println(
+            "   requestActiveUnlockOnUnlockIntentLegacy=$requestActiveUnlockOnUnlockIntentLegacy"
+        )
         pw.println("   requestActiveUnlockOnUnlockIntent=$requestActiveUnlockOnUnlockIntent")
         pw.println("   requestActiveUnlockOnBioFail=$requestActiveUnlockOnBioFail")
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index 4af366c..0f11717 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -39,7 +39,7 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dagger.qualifiers.UiBackground;
 import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarView;
+import com.android.systemui.navigationbar.views.NavigationBarView;
 import com.android.systemui.settings.DisplayTracker;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 70465bc..4217820 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -1097,7 +1097,8 @@
             int yTranslation = mResources.getDimensionPixelSize(R.dimen.disappear_y_translation);
 
             AnimatorSet anims = new AnimatorSet();
-            ObjectAnimator yAnim = ObjectAnimator.ofFloat(mView, View.TRANSLATION_Y, yTranslation);
+            ObjectAnimator yAnim = ObjectAnimator.ofFloat(mViewFlipper, View.TRANSLATION_Y,
+                    yTranslation);
             ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(mUserSwitcherViewGroup, View.ALPHA,
                     0f);
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 42838ae..428cd0e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -351,7 +351,7 @@
             mDeviceEntryFaceAuthInteractor.onSwipeUpOnBouncer();
             if (mDeviceEntryFaceAuthInteractor.isFaceAuthEnabledAndEnrolled()) {
                 mUpdateMonitor.requestActiveUnlock(
-                        ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT,
+                        ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY,
                         "swipeUpOnBouncer");
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 4b07402..56de5a3 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -38,7 +38,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.VisibleForTesting;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.systemui.dagger.GlobalRootComponent;
 import com.android.systemui.dagger.SysUIComponent;
 import com.android.systemui.dump.DumpManager;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/AccessibilityModule.kt b/packages/SystemUI/src/com/android/systemui/accessibility/AccessibilityModule.kt
index 004d5db..c2c5277 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/AccessibilityModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/AccessibilityModule.kt
@@ -42,4 +42,7 @@
     fun accessibilityQsShortcutsRepository(
         impl: AccessibilityQsShortcutsRepositoryImpl
     ): AccessibilityQsShortcutsRepository
+
+    @Binds
+    fun magnification(impl: MagnificationImpl): Magnification
 }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/FullscreenMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/FullscreenMagnificationController.java
index 3c4c003..3c0ac9a 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/FullscreenMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/FullscreenMagnificationController.java
@@ -56,7 +56,7 @@
 import java.util.concurrent.Executor;
 import java.util.function.Supplier;
 
-class FullscreenMagnificationController implements ComponentCallbacks {
+public class FullscreenMagnificationController implements ComponentCallbacks {
 
     private static final String TAG = "FullscreenMagnificationController";
     private final Context mContext;
@@ -87,7 +87,7 @@
     };
     private final long mLongAnimationTimeMs;
 
-    FullscreenMagnificationController(
+    public FullscreenMagnificationController(
             @UiContext Context context,
             @Main Handler handler,
             @Main Executor executor,
@@ -157,7 +157,7 @@
      * there is an activation change.
      */
     @UiThread
-    void onFullscreenMagnificationActivationChanged(boolean activated) {
+    public void onFullscreenMagnificationActivationChanged(boolean activated) {
         final boolean changed = (mFullscreenMagnificationActivated != activated);
         if (changed) {
             mFullscreenMagnificationActivated = activated;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java
index e22a4e4..48e5f0b 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java
@@ -16,618 +16,54 @@
 
 package com.android.systemui.accessibility;
 
-import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
-import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
-import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
-
-import static com.android.systemui.accessibility.AccessibilityLogger.MagnificationSettingsEvent;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_MAGNIFICATION_OVERLAP;
-
 import android.annotation.MainThread;
 import android.annotation.Nullable;
-import android.content.Context;
-import android.graphics.Rect;
-import android.hardware.display.DisplayManager;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.util.SparseArray;
-import android.view.Display;
-import android.view.IWindowManager;
-import android.view.SurfaceControl;
-import android.view.SurfaceControlViewHost;
-import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
-import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.IMagnificationConnection;
 import android.view.accessibility.IRemoteMagnificationAnimationCallback;
-import android.window.InputTransferToken;
 
-import androidx.annotation.NonNull;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
 import com.android.systemui.CoreStartable;
-import com.android.systemui.Flags;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.model.SysUiState;
-import com.android.systemui.recents.OverviewProxyService;
-import com.android.systemui.settings.DisplayTracker;
-import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.util.settings.SecureSettings;
 
-import java.io.PrintWriter;
-import java.util.concurrent.Executor;
-import java.util.function.Supplier;
-
-import javax.inject.Inject;
-
-/**
- * Class to handle the interaction with
- * {@link com.android.server.accessibility.AccessibilityManagerService}. It invokes
- * {@link AccessibilityManager#setMagnificationConnection(IMagnificationConnection)}
- * when {@code IStatusBar#requestWindowMagnificationConnection(boolean)} is called.
- */
-@SysUISingleton
-public class Magnification implements CoreStartable, CommandQueue.Callbacks {
-    private static final String TAG = "Magnification";
-
-    @VisibleForTesting static final int DELAY_SHOW_MAGNIFICATION_TIMEOUT_MS = 300;
-    private static final int MSG_SHOW_MAGNIFICATION_BUTTON_INTERNAL = 1;
-
-    private final ModeSwitchesController mModeSwitchesController;
-    private final Context mContext;
-    private final Handler mHandler;
-    private final Executor mExecutor;
-    private final AccessibilityManager mAccessibilityManager;
-    private final CommandQueue mCommandQueue;
-    private final OverviewProxyService mOverviewProxyService;
-    private final DisplayTracker mDisplayTracker;
-    private final AccessibilityLogger mA11yLogger;
-
-    private MagnificationConnectionImpl mMagnificationConnectionImpl;
-    private SysUiState mSysUiState;
-
-    @VisibleForTesting
-    SparseArray<SparseArray<Float>> mUsersScales = new SparseArray();
-
-    private static class WindowMagnificationControllerSupplier extends
-            DisplayIdIndexSupplier<WindowMagnificationController> {
-
-        private final Context mContext;
-        private final Handler mHandler;
-        private final WindowMagnifierCallback mWindowMagnifierCallback;
-        private final SysUiState mSysUiState;
-        private final SecureSettings mSecureSettings;
-
-        WindowMagnificationControllerSupplier(Context context, Handler handler,
-                WindowMagnifierCallback windowMagnifierCallback,
-                DisplayManager displayManager, SysUiState sysUiState,
-                SecureSettings secureSettings) {
-            super(displayManager);
-            mContext = context;
-            mHandler = handler;
-            mWindowMagnifierCallback = windowMagnifierCallback;
-            mSysUiState = sysUiState;
-            mSecureSettings = secureSettings;
-        }
-
-        @Override
-        protected WindowMagnificationController createInstance(Display display) {
-            final Context windowContext = mContext.createWindowContext(display,
-                    Flags.createWindowlessWindowMagnifier()
-                            ? TYPE_ACCESSIBILITY_OVERLAY
-                            : TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY,
-                    /* options */ null);
-            windowContext.setTheme(com.android.systemui.res.R.style.Theme_SystemUI);
-
-            Supplier<SurfaceControlViewHost> scvhSupplier = () ->
-                    Flags.createWindowlessWindowMagnifier() ? new SurfaceControlViewHost(mContext,
-                            mContext.getDisplay(), new InputTransferToken(), TAG) : null;
-
-            return new WindowMagnificationController(
-                    windowContext,
-                    mHandler,
-                    new WindowMagnificationAnimationController(windowContext),
-                    /* mirrorWindowControl= */ null,
-                    new SurfaceControl.Transaction(),
-                    mWindowMagnifierCallback,
-                    mSysUiState,
-                    mSecureSettings,
-                    scvhSupplier,
-                    new SfVsyncFrameCallbackProvider(),
-                    WindowManagerGlobal::getWindowSession);
-        }
-    }
-
-    @VisibleForTesting
-    DisplayIdIndexSupplier<WindowMagnificationController> mWindowMagnificationControllerSupplier;
-
-    private static class FullscreenMagnificationControllerSupplier extends
-            DisplayIdIndexSupplier<FullscreenMagnificationController> {
-
-        private final Context mContext;
-        private final Handler mHandler;
-        private final Executor mExecutor;
-        private final IWindowManager mIWindowManager;
-
-        FullscreenMagnificationControllerSupplier(Context context,
-                DisplayManager displayManager,
-                Handler handler,
-                Executor executor, IWindowManager iWindowManager) {
-            super(displayManager);
-            mContext = context;
-            mHandler = handler;
-            mExecutor = executor;
-            mIWindowManager = iWindowManager;
-        }
-
-        @Override
-        protected FullscreenMagnificationController createInstance(Display display) {
-            final Context windowContext = mContext.createWindowContext(display,
-                    TYPE_ACCESSIBILITY_OVERLAY, /* options */ null);
-            Supplier<SurfaceControlViewHost> scvhSupplier = () -> new SurfaceControlViewHost(
-                    mContext, mContext.getDisplay(), new InputTransferToken(), TAG);
-            windowContext.setTheme(com.android.systemui.res.R.style.Theme_SystemUI);
-            return new FullscreenMagnificationController(
-                    windowContext,
-                    mHandler,
-                    mExecutor,
-                    windowContext.getSystemService(AccessibilityManager.class),
-                    windowContext.getSystemService(WindowManager.class),
-                    mIWindowManager,
-                    scvhSupplier);
-        }
-    }
-
-    @VisibleForTesting
-    DisplayIdIndexSupplier<FullscreenMagnificationController>
-            mFullscreenMagnificationControllerSupplier;
-
-    private static class SettingsSupplier extends
-            DisplayIdIndexSupplier<MagnificationSettingsController> {
-
-        private final Context mContext;
-        private final MagnificationSettingsController.Callback mSettingsControllerCallback;
-        private final SecureSettings mSecureSettings;
-
-        SettingsSupplier(Context context,
-                MagnificationSettingsController.Callback settingsControllerCallback,
-                DisplayManager displayManager,
-                SecureSettings secureSettings) {
-            super(displayManager);
-            mContext = context;
-            mSettingsControllerCallback = settingsControllerCallback;
-            mSecureSettings = secureSettings;
-        }
-
-        @Override
-        protected MagnificationSettingsController createInstance(Display display) {
-            final Context windowContext = mContext.createWindowContext(display,
-                    TYPE_ACCESSIBILITY_OVERLAY, /* options */ null);
-            windowContext.setTheme(com.android.systemui.res.R.style.Theme_SystemUI);
-            return new MagnificationSettingsController(
-                    windowContext,
-                    new SfVsyncFrameCallbackProvider(),
-                    mSettingsControllerCallback,
-                    mSecureSettings);
-        }
-    }
-
-    @VisibleForTesting
-    DisplayIdIndexSupplier<MagnificationSettingsController> mMagnificationSettingsSupplier;
-
-    @Inject
-    public Magnification(Context context,
-            @Main Handler mainHandler, @Main Executor executor,
-            CommandQueue commandQueue, ModeSwitchesController modeSwitchesController,
-            SysUiState sysUiState, OverviewProxyService overviewProxyService,
-            SecureSettings secureSettings, DisplayTracker displayTracker,
-            DisplayManager displayManager, AccessibilityLogger a11yLogger,
-            IWindowManager iWindowManager) {
-        this(context, mainHandler.getLooper(), executor, commandQueue,
-                modeSwitchesController, sysUiState, overviewProxyService, secureSettings,
-                displayTracker, displayManager, a11yLogger, iWindowManager);
-    }
-
-    @VisibleForTesting
-    public Magnification(Context context, Looper looper, @Main Executor executor,
-            CommandQueue commandQueue, ModeSwitchesController modeSwitchesController,
-            SysUiState sysUiState, OverviewProxyService overviewProxyService,
-            SecureSettings secureSettings, DisplayTracker displayTracker,
-            DisplayManager displayManager, AccessibilityLogger a11yLogger,
-            IWindowManager iWindowManager) {
-        mContext = context;
-        mHandler = new Handler(looper) {
-            @Override
-            public void handleMessage(@NonNull Message msg) {
-                if (msg.what == MSG_SHOW_MAGNIFICATION_BUTTON_INTERNAL) {
-                    showMagnificationButtonInternal(msg.arg1, msg.arg2);
-                }
-            }
-        };
-        mExecutor = executor;
-        mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class);
-        mCommandQueue = commandQueue;
-        mModeSwitchesController = modeSwitchesController;
-        mSysUiState = sysUiState;
-        mOverviewProxyService = overviewProxyService;
-        mDisplayTracker = displayTracker;
-        mA11yLogger = a11yLogger;
-        mWindowMagnificationControllerSupplier = new WindowMagnificationControllerSupplier(context,
-                mHandler, mWindowMagnifierCallback,
-                displayManager, sysUiState, secureSettings);
-        mFullscreenMagnificationControllerSupplier = new FullscreenMagnificationControllerSupplier(
-                context, displayManager, mHandler, mExecutor, iWindowManager);
-        mMagnificationSettingsSupplier = new SettingsSupplier(context,
-                mMagnificationSettingsControllerCallback, displayManager, secureSettings);
-
-        mModeSwitchesController.setClickListenerDelegate(
-                displayId -> mHandler.post(() -> {
-                    toggleSettingsPanelVisibility(displayId);
-                }));
-    }
-
-    @Override
-    public void start() {
-        mCommandQueue.addCallback(this);
-        mOverviewProxyService.addCallback(new OverviewProxyService.OverviewProxyListener() {
-            @Override
-            public void onConnectionChanged(boolean isConnected) {
-                if (isConnected) {
-                    updateSysUiStateFlag();
-                }
-            }
-        });
-    }
-
-    private void updateSysUiStateFlag() {
-        //TODO(b/187510533): support multi-display once SysuiState supports it.
-        final WindowMagnificationController controller =
-                mWindowMagnificationControllerSupplier.valueAt(
-                        mDisplayTracker.getDefaultDisplayId());
-        if (controller != null) {
-            controller.updateSysUIStateFlag();
-        } else {
-            // The instance is initialized when there is an IPC request. Considering
-            // self-crash cases, we need to reset the flag in such situation.
-            mSysUiState.setFlag(SYSUI_STATE_MAGNIFICATION_OVERLAP, false)
-                    .commitUpdate(mDisplayTracker.getDefaultDisplayId());
-        }
-    }
+/** Interface for managing magnification connection calls from system process. */
+public interface Magnification extends CoreStartable {
 
     @MainThread
-    void enableWindowMagnification(int displayId, float scale, float centerX, float centerY,
-            float magnificationFrameOffsetRatioX, float magnificationFrameOffsetRatioY,
-            @Nullable IRemoteMagnificationAnimationCallback callback) {
-        final WindowMagnificationController windowMagnificationController =
-                mWindowMagnificationControllerSupplier.get(displayId);
-        if (windowMagnificationController != null) {
-            windowMagnificationController.enableWindowMagnification(scale, centerX, centerY,
-                    magnificationFrameOffsetRatioX, magnificationFrameOffsetRatioY, callback);
-        }
-    }
+    void enableWindowMagnification(
+            int displayId,
+            float scale,
+            float centerX,
+            float centerY,
+            float magnificationFrameOffsetRatioX,
+            float magnificationFrameOffsetRatioY,
+            @Nullable IRemoteMagnificationAnimationCallback callback);
 
     @MainThread
-    void setScaleForWindowMagnification(int displayId, float scale) {
-        final WindowMagnificationController windowMagnificationController =
-                mWindowMagnificationControllerSupplier.get(displayId);
-        if (windowMagnificationController != null) {
-            windowMagnificationController.setScale(scale);
-        }
-    }
+    void setScaleForWindowMagnification(int displayId, float scale);
 
     @MainThread
-    void moveWindowMagnifier(int displayId, float offsetX, float offsetY) {
-        final WindowMagnificationController windowMagnificationcontroller =
-                mWindowMagnificationControllerSupplier.get(displayId);
-        if (windowMagnificationcontroller != null) {
-            windowMagnificationcontroller.moveWindowMagnifier(offsetX, offsetY);
-        }
-    }
+    void moveWindowMagnifier(int displayId, float offsetX, float offsetY);
 
     @MainThread
-    void moveWindowMagnifierToPositionInternal(int displayId, float positionX, float positionY,
-            IRemoteMagnificationAnimationCallback callback) {
-        final WindowMagnificationController windowMagnificationController =
-                mWindowMagnificationControllerSupplier.get(displayId);
-        if (windowMagnificationController != null) {
-            windowMagnificationController.moveWindowMagnifierToPosition(positionX, positionY,
-                    callback);
-        }
-    }
+    void disableWindowMagnification(
+            int displayId, @Nullable IRemoteMagnificationAnimationCallback callback);
 
     @MainThread
-    void disableWindowMagnification(int displayId,
-            @Nullable IRemoteMagnificationAnimationCallback callback) {
-        final WindowMagnificationController windowMagnificationController =
-                mWindowMagnificationControllerSupplier.get(displayId);
-        if (windowMagnificationController != null) {
-            windowMagnificationController.deleteWindowMagnification(callback);
-        }
-    }
+    void onFullscreenMagnificationActivationChanged(int displayId, boolean activated);
 
     @MainThread
-    void onFullscreenMagnificationActivationChanged(int displayId, boolean activated) {
-        final FullscreenMagnificationController fullscreenMagnificationController =
-                mFullscreenMagnificationControllerSupplier.get(displayId);
-        if (fullscreenMagnificationController != null) {
-            fullscreenMagnificationController.onFullscreenMagnificationActivationChanged(activated);
-        }
-    }
+    void showMagnificationButton(int displayId, int magnificationMode);
 
     @MainThread
-    void toggleSettingsPanelVisibility(int displayId) {
-        final MagnificationSettingsController magnificationSettingsController =
-                mMagnificationSettingsSupplier.get(displayId);
-        if (magnificationSettingsController != null) {
-            magnificationSettingsController.toggleSettingsPanelVisibility();
-        }
-    }
+    void removeMagnificationButton(int displayId);
 
     @MainThread
-    void hideMagnificationSettingsPanel(int displayId) {
-        final MagnificationSettingsController magnificationSettingsController =
-                mMagnificationSettingsSupplier.get(displayId);
-        if (magnificationSettingsController != null) {
-            magnificationSettingsController.closeMagnificationSettings();
-        }
-    }
-
-    boolean isMagnificationSettingsPanelShowing(int displayId) {
-        final MagnificationSettingsController magnificationSettingsController =
-                mMagnificationSettingsSupplier.get(displayId);
-        if (magnificationSettingsController != null) {
-            return magnificationSettingsController.isMagnificationSettingsShowing();
-        }
-        return false;
-    }
+    void setUserMagnificationScale(int userId, int displayId, float scale);
 
     @MainThread
-    void showMagnificationButton(int displayId, int magnificationMode) {
-        if (Flags.delayShowMagnificationButton()) {
-            if (mHandler.hasMessages(MSG_SHOW_MAGNIFICATION_BUTTON_INTERNAL)) {
-                return;
-            }
-            mHandler.sendMessageDelayed(
-                    mHandler.obtainMessage(
-                            MSG_SHOW_MAGNIFICATION_BUTTON_INTERNAL, displayId, magnificationMode),
-                    DELAY_SHOW_MAGNIFICATION_TIMEOUT_MS);
-        } else {
-            showMagnificationButtonInternal(displayId, magnificationMode);
-        }
-    }
+    void hideMagnificationSettingsPanel(int displayId);
 
     @MainThread
-    private void showMagnificationButtonInternal(int displayId, int magnificationMode) {
-        // not to show mode switch button if settings panel is already showing to
-        // prevent settings panel be covered by the button.
-        if (isMagnificationSettingsPanelShowing(displayId)) {
-            return;
-        }
-        mModeSwitchesController.showButton(displayId, magnificationMode);
-    }
-
-    @MainThread
-    void removeMagnificationButton(int displayId) {
-        if (Flags.delayShowMagnificationButton()) {
-            mHandler.removeMessages(MSG_SHOW_MAGNIFICATION_BUTTON_INTERNAL);
-        }
-        mModeSwitchesController.removeButton(displayId);
-    }
-
-    @MainThread
-    void setUserMagnificationScale(int userId, int displayId, float scale) {
-        SparseArray<Float> scales = mUsersScales.get(userId);
-        if (scales == null) {
-            scales = new SparseArray<>();
-            mUsersScales.put(userId, scales);
-        }
-        if (scales.contains(displayId) && scales.get(displayId) == scale) {
-            return;
-        }
-        scales.put(displayId, scale);
-
-        final MagnificationSettingsController magnificationSettingsController =
-                mMagnificationSettingsSupplier.get(displayId);
-        magnificationSettingsController.setMagnificationScale(scale);
-    }
-
-    @VisibleForTesting
-    final WindowMagnifierCallback mWindowMagnifierCallback = new WindowMagnifierCallback() {
-        @Override
-        public void onWindowMagnifierBoundsChanged(int displayId, Rect frame) {
-            if (mMagnificationConnectionImpl != null) {
-                mMagnificationConnectionImpl.onWindowMagnifierBoundsChanged(displayId, frame);
-            }
-        }
-
-        @Override
-        public void onSourceBoundsChanged(int displayId, Rect sourceBounds) {
-            if (mMagnificationConnectionImpl != null) {
-                mMagnificationConnectionImpl.onSourceBoundsChanged(displayId, sourceBounds);
-            }
-        }
-
-        @Override
-        public void onPerformScaleAction(int displayId, float scale, boolean updatePersistence) {
-            if (mMagnificationConnectionImpl != null) {
-                mMagnificationConnectionImpl.onPerformScaleAction(
-                        displayId, scale, updatePersistence);
-            }
-        }
-
-        @Override
-        public void onAccessibilityActionPerformed(int displayId) {
-            if (mMagnificationConnectionImpl != null) {
-                mMagnificationConnectionImpl.onAccessibilityActionPerformed(displayId);
-            }
-        }
-
-        @Override
-        public void onMove(int displayId) {
-            if (mMagnificationConnectionImpl != null) {
-                mMagnificationConnectionImpl.onMove(displayId);
-            }
-        }
-
-        @Override
-        public void onClickSettingsButton(int displayId) {
-            mHandler.post(() -> {
-                toggleSettingsPanelVisibility(displayId);
-            });
-        }
-    };
-
-    @VisibleForTesting
-    final MagnificationSettingsController.Callback mMagnificationSettingsControllerCallback =
-            new MagnificationSettingsController.Callback() {
-                @Override
-                public void onSetMagnifierSize(int displayId, int index) {
-                    mHandler.post(() -> onSetMagnifierSizeInternal(displayId, index));
-                    mA11yLogger.logWithPosition(
-                            MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_WINDOW_SIZE_SELECTED,
-                            index
-                    );
-                }
-
-                @Override
-                public void onSetDiagonalScrolling(int displayId, boolean enable) {
-                    mHandler.post(() -> onSetDiagonalScrollingInternal(displayId, enable));
-                }
-
-                @Override
-                public void onEditMagnifierSizeMode(int displayId, boolean enable) {
-                    mHandler.post(() -> onEditMagnifierSizeModeInternal(displayId, enable));
-                    mA11yLogger.log(enable
-                            ?
-                            MagnificationSettingsEvent
-                                    .MAGNIFICATION_SETTINGS_SIZE_EDITING_ACTIVATED
-                            : MagnificationSettingsEvent
-                                    .MAGNIFICATION_SETTINGS_SIZE_EDITING_DEACTIVATED);
-                }
-
-                @Override
-                public void onMagnifierScale(int displayId, float scale,
-                        boolean updatePersistence) {
-                    if (mMagnificationConnectionImpl != null) {
-                        mMagnificationConnectionImpl.onPerformScaleAction(
-                                displayId, scale, updatePersistence);
-                    }
-                    mA11yLogger.logThrottled(
-                            MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_ZOOM_SLIDER_CHANGED
-                    );
-                }
-
-                @Override
-                public void onModeSwitch(int displayId, int newMode) {
-                    mHandler.post(() -> onModeSwitchInternal(displayId, newMode));
-                }
-
-                @Override
-                public void onSettingsPanelVisibilityChanged(int displayId, boolean shown) {
-                    mHandler.post(() -> onSettingsPanelVisibilityChangedInternal(displayId, shown));
-                }
-            };
-
-    @MainThread
-    private void onSetMagnifierSizeInternal(int displayId, int index) {
-        final WindowMagnificationController windowMagnificationController =
-                mWindowMagnificationControllerSupplier.get(displayId);
-        if (windowMagnificationController != null) {
-            windowMagnificationController.changeMagnificationSize(index);
-        }
-    }
-
-    @MainThread
-    private void onSetDiagonalScrollingInternal(int displayId, boolean enable) {
-        final WindowMagnificationController windowMagnificationController =
-                mWindowMagnificationControllerSupplier.get(displayId);
-        if (windowMagnificationController != null) {
-            windowMagnificationController.setDiagonalScrolling(enable);
-        }
-    }
-
-    @MainThread
-    private void onEditMagnifierSizeModeInternal(int displayId, boolean enable) {
-        final WindowMagnificationController windowMagnificationController =
-                mWindowMagnificationControllerSupplier.get(displayId);
-        if (windowMagnificationController != null && windowMagnificationController.isActivated()) {
-            windowMagnificationController.setEditMagnifierSizeMode(enable);
-        }
-    }
-
-    @MainThread
-    private void onModeSwitchInternal(int displayId, int newMode) {
-        final WindowMagnificationController windowMagnificationController =
-                mWindowMagnificationControllerSupplier.get(displayId);
-        final boolean isWindowMagnifierActivated = windowMagnificationController.isActivated();
-        final boolean isSwitchToWindowMode = (newMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
-        final boolean changed = isSwitchToWindowMode ^ isWindowMagnifierActivated;
-        if (changed) {
-            final MagnificationSettingsController magnificationSettingsController =
-                    mMagnificationSettingsSupplier.get(displayId);
-            if (magnificationSettingsController != null) {
-                magnificationSettingsController.closeMagnificationSettings();
-            }
-            if (mMagnificationConnectionImpl != null) {
-                mMagnificationConnectionImpl.onChangeMagnificationMode(displayId, newMode);
-            }
-        }
-    }
-
-    @MainThread
-    private void onSettingsPanelVisibilityChangedInternal(int displayId, boolean shown) {
-        final WindowMagnificationController windowMagnificationController =
-                mWindowMagnificationControllerSupplier.get(displayId);
-        if (windowMagnificationController != null) {
-            boolean isWindowMagnifierActivated = windowMagnificationController.isActivated();
-            if (isWindowMagnifierActivated) {
-                windowMagnificationController.updateDragHandleResourcesIfNeeded(shown);
-            }
-
-            if (shown) {
-                mA11yLogger.logWithPosition(
-                        MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_PANEL_OPENED,
-                        isWindowMagnifierActivated
-                                ? ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW
-                                : ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
-                );
-            } else {
-                mA11yLogger.log(MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_PANEL_CLOSED);
-            }
-        }
-    }
-
-    @Override
-    public void requestMagnificationConnection(boolean connect) {
-        if (connect) {
-            setMagnificationConnection();
-        } else {
-            clearMagnificationConnection();
-        }
-    }
-
-    @Override
-    public void dump(PrintWriter pw, String[] args) {
-        pw.println(TAG);
-        mWindowMagnificationControllerSupplier.forEach(
-                magnificationController -> magnificationController.dump(pw));
-    }
-
-    private void setMagnificationConnection() {
-        if (mMagnificationConnectionImpl == null) {
-            mMagnificationConnectionImpl = new MagnificationConnectionImpl(this,
-                    mHandler);
-        }
-        mAccessibilityManager.setMagnificationConnection(
-                mMagnificationConnectionImpl);
-    }
-
-    private void clearMagnificationConnection() {
-        mAccessibilityManager.setMagnificationConnection(null);
-        //TODO: destroy controllers.
-    }
+    void moveWindowMagnifierToPosition(
+            int displayId,
+            float positionX,
+            float positionY,
+            IRemoteMagnificationAnimationCallback callback);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java
index b5f3aef..c8b53ee 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java
@@ -32,7 +32,7 @@
  *
  * @see IMagnificationConnection
  */
-class MagnificationConnectionImpl extends IMagnificationConnection.Stub {
+public class MagnificationConnectionImpl extends IMagnificationConnection.Stub {
 
     private static final String TAG = "WindowMagnificationConnectionImpl";
 
@@ -40,7 +40,7 @@
     private final Magnification mMagnification;
     private final Handler mHandler;
 
-    MagnificationConnectionImpl(@NonNull Magnification magnification,
+    public MagnificationConnectionImpl(@NonNull Magnification magnification,
             @Main Handler mainHandler) {
         mMagnification = magnification;
         mHandler = mainHandler;
@@ -83,7 +83,7 @@
     @Override
     public void moveWindowMagnifierToPosition(int displayId, float positionX, float positionY,
             IRemoteMagnificationAnimationCallback callback) {
-        mHandler.post(() -> mMagnification.moveWindowMagnifierToPositionInternal(
+        mHandler.post(() -> mMagnification.moveWindowMagnifierToPosition(
                 displayId, positionX, positionY, callback));
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationImpl.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationImpl.java
new file mode 100644
index 0000000..6e5e44e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationImpl.java
@@ -0,0 +1,641 @@
+/*
+ * 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.accessibility;
+
+import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
+import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
+import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
+
+import static com.android.systemui.accessibility.AccessibilityLogger.MagnificationSettingsEvent;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_MAGNIFICATION_OVERLAP;
+
+import android.annotation.MainThread;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.SparseArray;
+import android.view.Display;
+import android.view.IWindowManager;
+import android.view.SurfaceControl;
+import android.view.SurfaceControlViewHost;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.IMagnificationConnection;
+import android.view.accessibility.IRemoteMagnificationAnimationCallback;
+import android.window.InputTransferToken;
+
+import androidx.annotation.NonNull;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
+import com.android.systemui.Flags;
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.model.SysUiState;
+import com.android.systemui.recents.OverviewProxyService;
+import com.android.systemui.settings.DisplayTracker;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.util.settings.SecureSettings;
+
+import java.io.PrintWriter;
+import java.util.concurrent.Executor;
+import java.util.function.Supplier;
+
+import javax.inject.Inject;
+
+/**
+ * Class to handle the interaction with
+ * {@link com.android.server.accessibility.AccessibilityManagerService}. It invokes
+ * {@link AccessibilityManager#setMagnificationConnection(IMagnificationConnection)}
+ * when {@code IStatusBar#requestWindowMagnificationConnection(boolean)} is called.
+ */
+@SysUISingleton
+public class MagnificationImpl implements Magnification, CommandQueue.Callbacks {
+    private static final String TAG = "Magnification";
+
+    @VisibleForTesting static final int DELAY_SHOW_MAGNIFICATION_TIMEOUT_MS = 300;
+    private static final int MSG_SHOW_MAGNIFICATION_BUTTON_INTERNAL = 1;
+
+    private final ModeSwitchesController mModeSwitchesController;
+    private final Handler mHandler;
+    private final Executor mExecutor;
+    private final AccessibilityManager mAccessibilityManager;
+    private final CommandQueue mCommandQueue;
+    private final OverviewProxyService mOverviewProxyService;
+    private final DisplayTracker mDisplayTracker;
+    private final AccessibilityLogger mA11yLogger;
+
+    private MagnificationConnectionImpl mMagnificationConnectionImpl;
+    private SysUiState mSysUiState;
+
+    @VisibleForTesting
+    SparseArray<SparseArray<Float>> mUsersScales = new SparseArray();
+
+    private static class WindowMagnificationControllerSupplier extends
+            DisplayIdIndexSupplier<WindowMagnificationController> {
+
+        private final Context mContext;
+        private final Handler mHandler;
+        private final WindowMagnifierCallback mWindowMagnifierCallback;
+        private final SysUiState mSysUiState;
+        private final SecureSettings mSecureSettings;
+
+        WindowMagnificationControllerSupplier(Context context, Handler handler,
+                WindowMagnifierCallback windowMagnifierCallback,
+                DisplayManager displayManager, SysUiState sysUiState,
+                SecureSettings secureSettings) {
+            super(displayManager);
+            mContext = context;
+            mHandler = handler;
+            mWindowMagnifierCallback = windowMagnifierCallback;
+            mSysUiState = sysUiState;
+            mSecureSettings = secureSettings;
+        }
+
+        @Override
+        protected WindowMagnificationController createInstance(Display display) {
+            final Context windowContext = mContext.createWindowContext(display,
+                    Flags.createWindowlessWindowMagnifier()
+                            ? TYPE_ACCESSIBILITY_OVERLAY
+                            : TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY,
+                    /* options */ null);
+            windowContext.setTheme(com.android.systemui.res.R.style.Theme_SystemUI);
+
+            Supplier<SurfaceControlViewHost> scvhSupplier = () ->
+                    Flags.createWindowlessWindowMagnifier() ? new SurfaceControlViewHost(mContext,
+                            mContext.getDisplay(), new InputTransferToken(), TAG) : null;
+
+            return new WindowMagnificationController(
+                    windowContext,
+                    mHandler,
+                    new WindowMagnificationAnimationController(windowContext),
+                    /* mirrorWindowControl= */ null,
+                    new SurfaceControl.Transaction(),
+                    mWindowMagnifierCallback,
+                    mSysUiState,
+                    mSecureSettings,
+                    scvhSupplier,
+                    new SfVsyncFrameCallbackProvider(),
+                    WindowManagerGlobal::getWindowSession);
+        }
+    }
+
+    @VisibleForTesting
+    DisplayIdIndexSupplier<WindowMagnificationController> mWindowMagnificationControllerSupplier;
+
+    private static class FullscreenMagnificationControllerSupplier extends
+            DisplayIdIndexSupplier<FullscreenMagnificationController> {
+
+        private final Context mContext;
+        private final Handler mHandler;
+        private final Executor mExecutor;
+        private final IWindowManager mIWindowManager;
+
+        FullscreenMagnificationControllerSupplier(Context context,
+                DisplayManager displayManager,
+                Handler handler,
+                Executor executor, IWindowManager iWindowManager) {
+            super(displayManager);
+            mContext = context;
+            mHandler = handler;
+            mExecutor = executor;
+            mIWindowManager = iWindowManager;
+        }
+
+        @Override
+        protected FullscreenMagnificationController createInstance(Display display) {
+            final Context windowContext = mContext.createWindowContext(display,
+                    TYPE_ACCESSIBILITY_OVERLAY, /* options */ null);
+            Supplier<SurfaceControlViewHost> scvhSupplier = () -> new SurfaceControlViewHost(
+                    mContext, mContext.getDisplay(), new InputTransferToken(), TAG);
+            windowContext.setTheme(com.android.systemui.res.R.style.Theme_SystemUI);
+            return new FullscreenMagnificationController(
+                    windowContext,
+                    mHandler,
+                    mExecutor,
+                    windowContext.getSystemService(AccessibilityManager.class),
+                    windowContext.getSystemService(WindowManager.class),
+                    mIWindowManager,
+                    scvhSupplier);
+        }
+    }
+
+    @VisibleForTesting
+    DisplayIdIndexSupplier<FullscreenMagnificationController>
+            mFullscreenMagnificationControllerSupplier;
+
+    private static class SettingsSupplier extends
+            DisplayIdIndexSupplier<MagnificationSettingsController> {
+
+        private final Context mContext;
+        private final MagnificationSettingsController.Callback mSettingsControllerCallback;
+        private final SecureSettings mSecureSettings;
+
+        SettingsSupplier(Context context,
+                MagnificationSettingsController.Callback settingsControllerCallback,
+                DisplayManager displayManager,
+                SecureSettings secureSettings) {
+            super(displayManager);
+            mContext = context;
+            mSettingsControllerCallback = settingsControllerCallback;
+            mSecureSettings = secureSettings;
+        }
+
+        @Override
+        protected MagnificationSettingsController createInstance(Display display) {
+            final Context windowContext = mContext.createWindowContext(display,
+                    TYPE_ACCESSIBILITY_OVERLAY, /* options */ null);
+            windowContext.setTheme(com.android.systemui.res.R.style.Theme_SystemUI);
+            return new MagnificationSettingsController(
+                    windowContext,
+                    new SfVsyncFrameCallbackProvider(),
+                    mSettingsControllerCallback,
+                    mSecureSettings);
+        }
+    }
+
+    @VisibleForTesting
+    DisplayIdIndexSupplier<MagnificationSettingsController> mMagnificationSettingsSupplier;
+
+    @Inject
+    public MagnificationImpl(Context context,
+            @Main Handler mainHandler, @Main Executor executor,
+            CommandQueue commandQueue, ModeSwitchesController modeSwitchesController,
+            SysUiState sysUiState, OverviewProxyService overviewProxyService,
+            SecureSettings secureSettings, DisplayTracker displayTracker,
+            DisplayManager displayManager, AccessibilityLogger a11yLogger,
+            IWindowManager iWindowManager, AccessibilityManager accessibilityManager) {
+        this(context, mainHandler.getLooper(), executor, commandQueue,
+                modeSwitchesController, sysUiState, overviewProxyService, secureSettings,
+                displayTracker, displayManager, a11yLogger, iWindowManager, accessibilityManager);
+    }
+
+    @VisibleForTesting
+    public MagnificationImpl(Context context, Looper looper, @Main Executor executor,
+            CommandQueue commandQueue, ModeSwitchesController modeSwitchesController,
+            SysUiState sysUiState, OverviewProxyService overviewProxyService,
+            SecureSettings secureSettings, DisplayTracker displayTracker,
+            DisplayManager displayManager, AccessibilityLogger a11yLogger,
+            IWindowManager iWindowManager,
+            AccessibilityManager accessibilityManager) {
+        mHandler = new Handler(looper) {
+            @Override
+            public void handleMessage(@NonNull Message msg) {
+                if (msg.what == MSG_SHOW_MAGNIFICATION_BUTTON_INTERNAL) {
+                    showMagnificationButtonInternal(msg.arg1, msg.arg2);
+                }
+            }
+        };
+        mExecutor = executor;
+        mAccessibilityManager = accessibilityManager;
+        mCommandQueue = commandQueue;
+        mModeSwitchesController = modeSwitchesController;
+        mSysUiState = sysUiState;
+        mOverviewProxyService = overviewProxyService;
+        mDisplayTracker = displayTracker;
+        mA11yLogger = a11yLogger;
+        mWindowMagnificationControllerSupplier = new WindowMagnificationControllerSupplier(context,
+                mHandler, mWindowMagnifierCallback,
+                displayManager, sysUiState, secureSettings);
+        mFullscreenMagnificationControllerSupplier = new FullscreenMagnificationControllerSupplier(
+                context, displayManager, mHandler, mExecutor, iWindowManager);
+        mMagnificationSettingsSupplier = new SettingsSupplier(context,
+                mMagnificationSettingsControllerCallback, displayManager, secureSettings);
+
+        mModeSwitchesController.setClickListenerDelegate(
+                displayId -> mHandler.post(() -> {
+                    toggleSettingsPanelVisibility(displayId);
+                }));
+    }
+
+    @Override
+    public void start() {
+        mCommandQueue.addCallback(this);
+        mOverviewProxyService.addCallback(new OverviewProxyService.OverviewProxyListener() {
+            @Override
+            public void onConnectionChanged(boolean isConnected) {
+                if (isConnected) {
+                    updateSysUiStateFlag();
+                }
+            }
+        });
+    }
+
+    private void updateSysUiStateFlag() {
+        //TODO(b/187510533): support multi-display once SysuiState supports it.
+        final WindowMagnificationController controller =
+                mWindowMagnificationControllerSupplier.valueAt(
+                        mDisplayTracker.getDefaultDisplayId());
+        if (controller != null) {
+            controller.updateSysUIStateFlag();
+        } else {
+            // The instance is initialized when there is an IPC request. Considering
+            // self-crash cases, we need to reset the flag in such situation.
+            mSysUiState.setFlag(SYSUI_STATE_MAGNIFICATION_OVERLAP, false)
+                    .commitUpdate(mDisplayTracker.getDefaultDisplayId());
+        }
+    }
+
+    @Override
+    @MainThread
+    public void enableWindowMagnification(int displayId, float scale, float centerX, float centerY,
+            float magnificationFrameOffsetRatioX, float magnificationFrameOffsetRatioY,
+            @Nullable IRemoteMagnificationAnimationCallback callback) {
+        final WindowMagnificationController windowMagnificationController =
+                mWindowMagnificationControllerSupplier.get(displayId);
+        if (windowMagnificationController != null) {
+            windowMagnificationController.enableWindowMagnification(scale, centerX, centerY,
+                    magnificationFrameOffsetRatioX, magnificationFrameOffsetRatioY, callback);
+        }
+    }
+
+    @Override
+    @MainThread
+    public void setScaleForWindowMagnification(int displayId, float scale) {
+        final WindowMagnificationController windowMagnificationController =
+                mWindowMagnificationControllerSupplier.get(displayId);
+        if (windowMagnificationController != null) {
+            windowMagnificationController.setScale(scale);
+        }
+    }
+
+    @Override
+    @MainThread
+    public void moveWindowMagnifier(int displayId, float offsetX, float offsetY) {
+        final WindowMagnificationController windowMagnificationcontroller =
+                mWindowMagnificationControllerSupplier.get(displayId);
+        if (windowMagnificationcontroller != null) {
+            windowMagnificationcontroller.moveWindowMagnifier(offsetX, offsetY);
+        }
+    }
+
+    @Override
+    @MainThread
+    public void moveWindowMagnifierToPosition(int displayId, float positionX, float positionY,
+            IRemoteMagnificationAnimationCallback callback) {
+        final WindowMagnificationController windowMagnificationController =
+                mWindowMagnificationControllerSupplier.get(displayId);
+        if (windowMagnificationController != null) {
+            windowMagnificationController.moveWindowMagnifierToPosition(positionX, positionY,
+                    callback);
+        }
+    }
+
+    @Override
+    @MainThread
+    public void disableWindowMagnification(int displayId,
+            @Nullable IRemoteMagnificationAnimationCallback callback) {
+        final WindowMagnificationController windowMagnificationController =
+                mWindowMagnificationControllerSupplier.get(displayId);
+        if (windowMagnificationController != null) {
+            windowMagnificationController.deleteWindowMagnification(callback);
+        }
+    }
+
+    @Override
+    @MainThread
+    public void onFullscreenMagnificationActivationChanged(int displayId, boolean activated) {
+        final FullscreenMagnificationController fullscreenMagnificationController =
+                mFullscreenMagnificationControllerSupplier.get(displayId);
+        if (fullscreenMagnificationController != null) {
+            fullscreenMagnificationController.onFullscreenMagnificationActivationChanged(activated);
+        }
+    }
+
+    @MainThread
+    void toggleSettingsPanelVisibility(int displayId) {
+        final MagnificationSettingsController magnificationSettingsController =
+                mMagnificationSettingsSupplier.get(displayId);
+        if (magnificationSettingsController != null) {
+            magnificationSettingsController.toggleSettingsPanelVisibility();
+        }
+    }
+
+    @Override
+    @MainThread
+    public void hideMagnificationSettingsPanel(int displayId) {
+        final MagnificationSettingsController magnificationSettingsController =
+                mMagnificationSettingsSupplier.get(displayId);
+        if (magnificationSettingsController != null) {
+            magnificationSettingsController.closeMagnificationSettings();
+        }
+    }
+
+    boolean isMagnificationSettingsPanelShowing(int displayId) {
+        final MagnificationSettingsController magnificationSettingsController =
+                mMagnificationSettingsSupplier.get(displayId);
+        if (magnificationSettingsController != null) {
+            return magnificationSettingsController.isMagnificationSettingsShowing();
+        }
+        return false;
+    }
+
+    @Override
+    @MainThread
+    public void showMagnificationButton(int displayId, int magnificationMode) {
+        if (Flags.delayShowMagnificationButton()) {
+            if (mHandler.hasMessages(MSG_SHOW_MAGNIFICATION_BUTTON_INTERNAL)) {
+                return;
+            }
+            mHandler.sendMessageDelayed(
+                    mHandler.obtainMessage(
+                            MSG_SHOW_MAGNIFICATION_BUTTON_INTERNAL, displayId, magnificationMode),
+                    DELAY_SHOW_MAGNIFICATION_TIMEOUT_MS);
+        } else {
+            showMagnificationButtonInternal(displayId, magnificationMode);
+        }
+    }
+
+    @MainThread
+    private void showMagnificationButtonInternal(int displayId, int magnificationMode) {
+        // not to show mode switch button if settings panel is already showing to
+        // prevent settings panel be covered by the button.
+        if (isMagnificationSettingsPanelShowing(displayId)) {
+            return;
+        }
+        mModeSwitchesController.showButton(displayId, magnificationMode);
+    }
+
+    @Override
+    @MainThread
+    public void removeMagnificationButton(int displayId) {
+        if (Flags.delayShowMagnificationButton()) {
+            mHandler.removeMessages(MSG_SHOW_MAGNIFICATION_BUTTON_INTERNAL);
+        }
+        mModeSwitchesController.removeButton(displayId);
+    }
+
+    @Override
+    @MainThread
+    public void setUserMagnificationScale(int userId, int displayId, float scale) {
+        SparseArray<Float> scales = mUsersScales.get(userId);
+        if (scales == null) {
+            scales = new SparseArray<>();
+            mUsersScales.put(userId, scales);
+        }
+        if (scales.contains(displayId) && scales.get(displayId) == scale) {
+            return;
+        }
+        scales.put(displayId, scale);
+
+        final MagnificationSettingsController magnificationSettingsController =
+                mMagnificationSettingsSupplier.get(displayId);
+        magnificationSettingsController.setMagnificationScale(scale);
+    }
+
+    @VisibleForTesting
+    final WindowMagnifierCallback mWindowMagnifierCallback = new WindowMagnifierCallback() {
+        @Override
+        public void onWindowMagnifierBoundsChanged(int displayId, Rect frame) {
+            if (mMagnificationConnectionImpl != null) {
+                mMagnificationConnectionImpl.onWindowMagnifierBoundsChanged(displayId, frame);
+            }
+        }
+
+        @Override
+        public void onSourceBoundsChanged(int displayId, Rect sourceBounds) {
+            if (mMagnificationConnectionImpl != null) {
+                mMagnificationConnectionImpl.onSourceBoundsChanged(displayId, sourceBounds);
+            }
+        }
+
+        @Override
+        public void onPerformScaleAction(int displayId, float scale, boolean updatePersistence) {
+            if (mMagnificationConnectionImpl != null) {
+                mMagnificationConnectionImpl.onPerformScaleAction(
+                        displayId, scale, updatePersistence);
+            }
+        }
+
+        @Override
+        public void onAccessibilityActionPerformed(int displayId) {
+            if (mMagnificationConnectionImpl != null) {
+                mMagnificationConnectionImpl.onAccessibilityActionPerformed(displayId);
+            }
+        }
+
+        @Override
+        public void onMove(int displayId) {
+            if (mMagnificationConnectionImpl != null) {
+                mMagnificationConnectionImpl.onMove(displayId);
+            }
+        }
+
+        @Override
+        public void onClickSettingsButton(int displayId) {
+            mHandler.post(() -> {
+                toggleSettingsPanelVisibility(displayId);
+            });
+        }
+    };
+
+    @VisibleForTesting
+    final MagnificationSettingsController.Callback mMagnificationSettingsControllerCallback =
+            new MagnificationSettingsController.Callback() {
+                @Override
+                public void onSetMagnifierSize(int displayId, int index) {
+                    mHandler.post(() -> onSetMagnifierSizeInternal(displayId, index));
+                    mA11yLogger.logWithPosition(
+                            MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_WINDOW_SIZE_SELECTED,
+                            index
+                    );
+                }
+
+                @Override
+                public void onSetDiagonalScrolling(int displayId, boolean enable) {
+                    mHandler.post(() -> onSetDiagonalScrollingInternal(displayId, enable));
+                }
+
+                @Override
+                public void onEditMagnifierSizeMode(int displayId, boolean enable) {
+                    mHandler.post(() -> onEditMagnifierSizeModeInternal(displayId, enable));
+                    mA11yLogger.log(enable
+                            ?
+                            MagnificationSettingsEvent
+                                    .MAGNIFICATION_SETTINGS_SIZE_EDITING_ACTIVATED
+                            : MagnificationSettingsEvent
+                                    .MAGNIFICATION_SETTINGS_SIZE_EDITING_DEACTIVATED);
+                }
+
+                @Override
+                public void onMagnifierScale(int displayId, float scale,
+                        boolean updatePersistence) {
+                    if (mMagnificationConnectionImpl != null) {
+                        mMagnificationConnectionImpl.onPerformScaleAction(
+                                displayId, scale, updatePersistence);
+                    }
+                    mA11yLogger.logThrottled(
+                            MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_ZOOM_SLIDER_CHANGED
+                    );
+                }
+
+                @Override
+                public void onModeSwitch(int displayId, int newMode) {
+                    mHandler.post(() -> onModeSwitchInternal(displayId, newMode));
+                }
+
+                @Override
+                public void onSettingsPanelVisibilityChanged(int displayId, boolean shown) {
+                    mHandler.post(() -> onSettingsPanelVisibilityChangedInternal(displayId, shown));
+                }
+            };
+
+    @MainThread
+    private void onSetMagnifierSizeInternal(int displayId, int index) {
+        final WindowMagnificationController windowMagnificationController =
+                mWindowMagnificationControllerSupplier.get(displayId);
+        if (windowMagnificationController != null) {
+            windowMagnificationController.changeMagnificationSize(index);
+        }
+    }
+
+    @MainThread
+    private void onSetDiagonalScrollingInternal(int displayId, boolean enable) {
+        final WindowMagnificationController windowMagnificationController =
+                mWindowMagnificationControllerSupplier.get(displayId);
+        if (windowMagnificationController != null) {
+            windowMagnificationController.setDiagonalScrolling(enable);
+        }
+    }
+
+    @MainThread
+    private void onEditMagnifierSizeModeInternal(int displayId, boolean enable) {
+        final WindowMagnificationController windowMagnificationController =
+                mWindowMagnificationControllerSupplier.get(displayId);
+        if (windowMagnificationController != null && windowMagnificationController.isActivated()) {
+            windowMagnificationController.setEditMagnifierSizeMode(enable);
+        }
+    }
+
+    @MainThread
+    private void onModeSwitchInternal(int displayId, int newMode) {
+        final WindowMagnificationController windowMagnificationController =
+                mWindowMagnificationControllerSupplier.get(displayId);
+        final boolean isWindowMagnifierActivated = windowMagnificationController.isActivated();
+        final boolean isSwitchToWindowMode = (newMode == ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+        final boolean changed = isSwitchToWindowMode ^ isWindowMagnifierActivated;
+        if (changed) {
+            final MagnificationSettingsController magnificationSettingsController =
+                    mMagnificationSettingsSupplier.get(displayId);
+            if (magnificationSettingsController != null) {
+                magnificationSettingsController.closeMagnificationSettings();
+            }
+            if (mMagnificationConnectionImpl != null) {
+                mMagnificationConnectionImpl.onChangeMagnificationMode(displayId, newMode);
+            }
+        }
+    }
+
+    @MainThread
+    private void onSettingsPanelVisibilityChangedInternal(int displayId, boolean shown) {
+        final WindowMagnificationController windowMagnificationController =
+                mWindowMagnificationControllerSupplier.get(displayId);
+        if (windowMagnificationController != null) {
+            boolean isWindowMagnifierActivated = windowMagnificationController.isActivated();
+            if (isWindowMagnifierActivated) {
+                windowMagnificationController.updateDragHandleResourcesIfNeeded(shown);
+            }
+
+            if (shown) {
+                mA11yLogger.logWithPosition(
+                        MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_PANEL_OPENED,
+                        isWindowMagnifierActivated
+                                ? ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW
+                                : ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN
+                );
+            } else {
+                mA11yLogger.log(MagnificationSettingsEvent.MAGNIFICATION_SETTINGS_PANEL_CLOSED);
+            }
+        }
+    }
+
+    @Override
+    public void requestMagnificationConnection(boolean connect) {
+        if (connect) {
+            setMagnificationConnection();
+        } else {
+            clearMagnificationConnection();
+        }
+    }
+
+    @Override
+    public void dump(PrintWriter pw, String[] args) {
+        pw.println(TAG);
+        mWindowMagnificationControllerSupplier.forEach(
+                magnificationController -> magnificationController.dump(pw));
+    }
+
+    private void setMagnificationConnection() {
+        if (mMagnificationConnectionImpl == null) {
+            mMagnificationConnectionImpl = new MagnificationConnectionImpl(this,
+                    mHandler);
+        }
+        mAccessibilityManager.setMagnificationConnection(
+                mMagnificationConnectionImpl);
+    }
+
+    private void clearMagnificationConnection() {
+        mAccessibilityManager.setMagnificationConnection(null);
+        //TODO: destroy controllers.
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
index 37e9dc1a..7750f6b 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
@@ -233,7 +233,7 @@
         // NotificationShadeWindowController.registerCallback() only keeps weak references.
         mNotificationShadeCallback =
                 (keyguardShowing, keyguardOccluded, keyguardGoingAway, bouncerShowing, mDozing,
-                        panelExpanded, isDreaming) ->
+                        panelExpanded, isDreaming, communalShowing) ->
                         registerOrUnregisterDismissNotificationShadeAction();
         mScreenshotHelper = new ScreenshotHelper(mContext);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index 5458ab1..b37ba89 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -1631,8 +1631,23 @@
         boolean bRTL = isRTL(mContext);
         final int initSize = Math.min(mWindowBounds.width(), mWindowBounds.height()) / 3;
 
-        final int maxHeightSize = mWindowBounds.height() - 2 * mMirrorSurfaceMargin;
-        final int maxWidthSize = mWindowBounds.width() - 2 * mMirrorSurfaceMargin;
+        int maxHeightSize;
+        int maxWidthSize;
+        if (Flags.redesignMagnificationWindowSize()) {
+            // mOuterBorderSize = transparent margin area
+            // mMirrorSurfaceMargin = transparent margin area + orange border width
+            // We would like to allow the width and height to be full size. Therefore, the max
+            // frame size could be calculated as (window bounds - 2 * orange border width).
+            maxHeightSize =
+                    mWindowBounds.height() - 2 * (mMirrorSurfaceMargin - mOuterBorderSize);
+            maxWidthSize  =
+                    mWindowBounds.width() - 2 * (mMirrorSurfaceMargin - mOuterBorderSize);
+        } else {
+            maxHeightSize =
+                    mWindowBounds.height() - 2 * mMirrorSurfaceMargin;
+            maxWidthSize  =
+                    mWindowBounds.width() - 2 * mMirrorSurfaceMargin;
+        }
 
         Rect tempRect = new Rect();
         tempRect.set(mMagnificationFrame);
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/data/repository/AccessibilityRepository.kt b/packages/SystemUI/src/com/android/systemui/accessibility/data/repository/AccessibilityRepository.kt
index 6032f0b..b33924c 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/data/repository/AccessibilityRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/data/repository/AccessibilityRepository.kt
@@ -18,10 +18,10 @@
 
 import android.view.accessibility.AccessibilityManager
 import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener
-import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
+import com.android.app.tracing.FlowTracing.tracedAwaitClose
+import com.android.app.tracing.FlowTracing.tracedConflatedCallbackFlow
 import dagger.Module
 import dagger.Provides
-import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.distinctUntilChanged
 
@@ -38,24 +38,28 @@
     }
 }
 
+private const val TAG = "AccessibilityRepository"
+
 private class AccessibilityRepositoryImpl(
     manager: AccessibilityManager,
 ) : AccessibilityRepository {
     override val isTouchExplorationEnabled: Flow<Boolean> =
-        conflatedCallbackFlow {
+        tracedConflatedCallbackFlow(TAG) {
                 val listener = TouchExplorationStateChangeListener(::trySend)
                 manager.addTouchExplorationStateChangeListener(listener)
                 trySend(manager.isTouchExplorationEnabled)
-                awaitClose { manager.removeTouchExplorationStateChangeListener(listener) }
+                tracedAwaitClose(TAG) {
+                    manager.removeTouchExplorationStateChangeListener(listener)
+                }
             }
             .distinctUntilChanged()
 
     override val isEnabled: Flow<Boolean> =
-        conflatedCallbackFlow {
+        tracedConflatedCallbackFlow(TAG) {
                 val listener = AccessibilityManager.AccessibilityStateChangeListener(::trySend)
                 manager.addAccessibilityStateChangeListener(listener)
                 trySend(manager.isEnabled)
-                awaitClose { manager.removeAccessibilityStateChangeListener(listener) }
+                tracedAwaitClose(TAG) { manager.removeAccessibilityStateChangeListener(listener) }
             }
             .distinctUntilChanged()
 }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java
index dafd5f8..030d147 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java
@@ -72,6 +72,7 @@
     private final Handler mHandler;
     private boolean mIsFadeEffectEnabled;
     private Runnable mSpringAnimationsEndAction;
+    private PointF mAnimationEndPosition = new PointF();
 
     // Cache the animations state of {@link DynamicAnimation.TRANSLATION_X} and {@link
     // DynamicAnimation.TRANSLATION_Y} to be well controlled by the touch handler
@@ -104,10 +105,12 @@
                     @Override
                     public void onRadiiAnimationStop() {}
                 });
+        mAnimationEndPosition = mMenuView.getMenuPosition();
     }
 
     void moveToPosition(PointF position) {
         moveToPosition(position, /* animateMovement = */ false);
+        mAnimationEndPosition = position;
     }
 
     /* Moves position without updating underlying percentage position. Can be animated. */
@@ -129,6 +132,7 @@
         } else {
             DynamicAnimation.TRANSLATION_X.setValue(mMenuView, positionX);
         }
+        mAnimationEndPosition.x = positionX;
     }
 
     void moveToPositionY(float positionY) {
@@ -144,6 +148,7 @@
         } else {
             DynamicAnimation.TRANSLATION_Y.setValue(mMenuView, positionY);
         }
+        mAnimationEndPosition.y = positionY;
     }
 
     void moveToPositionYIfNeeded(float positionY) {
@@ -259,6 +264,9 @@
 
         cancelAnimation(property);
         mPositionAnimations.put(property, flingAnimation);
+        if (finalPosition != null) {
+            setAnimationEndPosition(property, finalPosition);
+        }
         flingAnimation.start();
     }
 
@@ -292,6 +300,7 @@
 
         cancelAnimation(property);
         mPositionAnimations.put(property, springAnimation);
+        setAnimationEndPosition(property, finalPosition);
         springAnimation.animateToFinalPosition(finalPosition);
     }
 
@@ -385,6 +394,21 @@
         mPositionAnimations.get(property).cancel();
     }
 
+    private void setAnimationEndPosition(
+            DynamicAnimation.ViewProperty property, Float endPosition) {
+        if (property.equals(DynamicAnimation.TRANSLATION_X)) {
+            mAnimationEndPosition.x = endPosition;
+        }
+        if (property.equals(DynamicAnimation.TRANSLATION_Y)) {
+            mAnimationEndPosition.y = endPosition;
+        }
+    }
+
+    void skipAnimations() {
+        cancelAnimations();
+        moveToPosition(mAnimationEndPosition, false);
+    }
+
     @VisibleForTesting
     DynamicAnimation getAnimation(DynamicAnimation.ViewProperty property) {
         return mPositionAnimations.getOrDefault(property, null);
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
index 0c67c50..4a28d8b 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
@@ -205,8 +205,9 @@
                         return;
                     }
 
-                    setAccessibilityServiceState(getContext(), serviceComponentName, /* enabled= */
-                            false);
+                    setAccessibilityServiceState(
+                            getContext(), serviceComponentName, /* enabled= */ false,
+                            mSecureSettings.getRealUserHandle(UserHandle.USER_CURRENT));
                 });
             }
 
@@ -334,6 +335,7 @@
         mDragToInteractView.updateResources();
         mDismissView.updateResources();
         mDragToInteractAnimationController.updateResources();
+        mMenuAnimationController.skipAnimations();
     }
 
     @Override
@@ -467,6 +469,7 @@
 
     private void onSpringAnimationsEndAction() {
         if (mShouldShowDockTooltip) {
+            mEduTooltipView.ifPresent(this::removeTooltip);
             mEduTooltipView = Optional.of(new MenuEduTooltipView(mContext, mMenuViewAppearance));
             mEduTooltipView.ifPresent(view -> addTooltipView(view,
                     getContext().getText(R.string.accessibility_floating_button_docking_tooltip),
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesPresetsController.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesPresetsController.java
index 02fa003..f81124e 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesPresetsController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesPresetsController.java
@@ -220,7 +220,8 @@
         if (mActiveHearingDevice == null) {
             return emptyList();
         }
-        return mHapClientProfile.getAllPresetInfo(mActiveHearingDevice.getDevice());
+        return mHapClientProfile.getAllPresetInfo(mActiveHearingDevice.getDevice()).stream().filter(
+                BluetoothHapPresetInfo::isAvailable).toList();
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandler.java b/packages/SystemUI/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandler.java
index f905241..636bc5b 100644
--- a/packages/SystemUI/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/ambient/touch/BouncerSwipeTouchHandler.java
@@ -38,6 +38,7 @@
 import com.android.systemui.ambient.touch.scrim.ScrimController;
 import com.android.systemui.ambient.touch.scrim.ScrimManager;
 import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shade.ShadeExpansionChangeEvent;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
@@ -103,6 +104,8 @@
 
     private final UiEventLogger mUiEventLogger;
 
+    private final ActivityStarter mActivityStarter;
+
     private final ScrimManager.Callback mScrimManagerCallback = new ScrimManager.Callback() {
         @Override
         public void onScrimControllerChanged(ScrimController controller) {
@@ -149,11 +152,16 @@
                         return true;
                     }
 
-                    // If scrolling up and keyguard is not locked, dismiss the dream since there's
-                    // no bouncer to show.
+                    // If scrolling up and keyguard is not locked, dismiss both keyguard and the
+                    // dream since there's no bouncer to show.
                     if (e1.getY() > e2.getY()
                             && !mLockPatternUtils.isSecure(mUserTracker.getUserId())) {
-                        mCentralSurfaces.get().awakenDreams();
+                        mActivityStarter.executeRunnableDismissingKeyguard(
+                                () -> mCentralSurfaces.get().awakenDreams(),
+                                /* cancelAction= */ null,
+                                /* dismissShade= */ true,
+                                /* afterKeyguardGone= */ true,
+                                /* deferred= */ false);
                         return true;
                     }
 
@@ -162,7 +170,6 @@
                     // bouncer. As that view's expansion shrinks, the bouncer appears. The bouncer
                     // is fully hidden at full expansion (1) and fully visible when fully collapsed
                     // (0).
-                    final float dragDownAmount = e2.getY() - e1.getY();
                     final float screenTravelPercentage = Math.abs(e1.getY() - e2.getY())
                             / mTouchSession.getBounds().height();
                     setPanelExpansion(1 - screenTravelPercentage);
@@ -216,7 +223,8 @@
             FlingAnimationUtils flingAnimationUtilsClosing,
             @Named(BouncerSwipeModule.SWIPE_TO_BOUNCER_START_REGION) float swipeRegionPercentage,
             @Named(BouncerSwipeModule.MIN_BOUNCER_ZONE_SCREEN_PERCENTAGE) float minRegionPercentage,
-            UiEventLogger uiEventLogger) {
+            UiEventLogger uiEventLogger,
+            ActivityStarter activityStarter) {
         mCentralSurfaces = centralSurfaces;
         mScrimManager = scrimManager;
         mNotificationShadeWindowController = notificationShadeWindowController;
@@ -229,6 +237,7 @@
         mValueAnimatorCreator = valueAnimatorCreator;
         mVelocityTrackerFactory = velocityTrackerFactory;
         mUiEventLogger = uiEventLogger;
+        mActivityStarter = activityStarter;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/ambient/touch/TouchMonitor.java b/packages/SystemUI/src/com/android/systemui/ambient/touch/TouchMonitor.java
index 61b4401..4035e95 100644
--- a/packages/SystemUI/src/com/android/systemui/ambient/touch/TouchMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/ambient/touch/TouchMonitor.java
@@ -323,12 +323,15 @@
 
         // When we stop monitoring touches, we must ensure that all active touch sessions and
         // descendants informed of the removal so any cleanup for active tracking can proceed.
-        mMainExecutor.execute(() -> mActiveTouchSessions.forEach(touchSession -> {
-            while (touchSession != null) {
-                touchSession.onRemoved();
-                touchSession = touchSession.getPredecessor();
-            }
-        }));
+        mMainExecutor.execute(() -> {
+            mActiveTouchSessions.forEach(touchSession -> {
+                while (touchSession != null) {
+                    touchSession.onRemoved();
+                    touchSession = touchSession.getPredecessor();
+                }
+            });
+            mActiveTouchSessions.clear();
+        });
 
         mCurrentInputSession.dispose();
         mCurrentInputSession = null;
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index d30f33f..a67dcdb 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -515,7 +515,7 @@
     }
 
     @Nullable
-    private ComponentName getAssistInfo() {
+    public ComponentName getAssistInfo() {
         return getAssistInfoForUser(mSelectedUserInteractor.getSelectedUserId());
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
index 0cdb376..7dfa4f9 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
@@ -31,9 +31,9 @@
 import android.view.View;
 
 import com.android.settingslib.Utils;
-import com.android.systemui.navigationbar.NavigationBar;
 import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarTransitions;
+import com.android.systemui.navigationbar.views.NavigationBar;
+import com.android.systemui.navigationbar.views.NavigationBarTransitions;
 import com.android.systemui.res.R;
 
 import java.util.ArrayList;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index d6d40f2..b466f31 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -995,6 +995,16 @@
     }
 
     /**
+     * @return true if ultrasonic udfps HW is supported on this device. Can return true even if
+     * the user has not enrolled udfps. This may be false if called before
+     * onAllAuthenticatorsRegistered.
+     */
+    public boolean isUltrasonicUdfpsSupported() {
+        return getUdfpsProps() != null && !getUdfpsProps().isEmpty() && getUdfpsProps()
+                .get(0).isUltrasonicUdfps();
+    }
+
+    /**
      * @return true if sfps HW is supported on this device. Can return true even if the user has
      * not enrolled sfps. This may be false if called before onAllAuthenticatorsRegistered.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index ad142a8..3dd3758 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -270,6 +270,7 @@
         @Override
         public void showUdfpsOverlay(long requestId, int sensorId, int reason,
                 @NonNull IUdfpsOverlayControllerCallback callback) {
+            mUdfpsOverlayInteractor.setRequestId(requestId);
             mFgExecutor.execute(() -> UdfpsController.this.showUdfpsOverlay(
                     new UdfpsControllerOverlay(
                         mContext,
@@ -404,6 +405,15 @@
                     handler::post,
                     authenticationCallback);
         }
+
+        /**
+         * Debug to run setIgnoreDisplayTouches
+         */
+        public void debugSetIgnoreDisplayTouches(boolean ignoreTouch) {
+            final long requestId = (mOverlay != null) ? mOverlay.getRequestId() : 0L;
+            UdfpsController.this.mFingerprintManager.setIgnoreDisplayTouches(
+                    requestId, mSensorProps.sensorId, ignoreTouch);
+        }
     }
 
     /**
@@ -558,7 +568,12 @@
                 Log.w(TAG, "onTouch down received without a preceding up");
             }
             mActivePointerId = MotionEvent.INVALID_POINTER_ID;
-            mOnFingerDown = false;
+
+            // It's possible on some devices to get duplicate touches from both doze and the
+            // normal touch listener. Don't reset the down in this case to avoid duplicate downs
+            if (!mIsAodInterruptActive) {
+                mOnFingerDown = false;
+            }
         } else if (!DeviceEntryUdfpsRefactor.isEnabled()) {
             if ((mLockscreenShadeTransitionController.getQSDragProgress() != 0f
                     && !mAlternateBouncerInteractor.isVisibleState())
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
index 01cc33c..e03d160 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
@@ -45,7 +45,6 @@
 import androidx.annotation.LayoutRes
 import androidx.annotation.VisibleForTesting
 import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.systemui.Flags.udfpsViewPerformance
 import com.android.systemui.animation.ActivityTransitionAnimator
 import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor
 import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
@@ -82,67 +81,66 @@
 
 private const val TAG = "UdfpsControllerOverlay"
 
-@VisibleForTesting
-const val SETTING_REMOVE_ENROLLMENT_UI = "udfps_overlay_remove_enrollment_ui"
+@VisibleForTesting const val SETTING_REMOVE_ENROLLMENT_UI = "udfps_overlay_remove_enrollment_ui"
 
 /**
  * Keeps track of the overlay state and UI resources associated with a single FingerprintService
- * request. This state can persist across configuration changes via the [show] and [hide]
- * methods.
+ * request. This state can persist across configuration changes via the [show] and [hide] methods.
  */
 @ExperimentalCoroutinesApi
 @UiThread
-class UdfpsControllerOverlay @JvmOverloads constructor(
-        private val context: Context,
-        private val inflater: LayoutInflater,
-        private val windowManager: WindowManager,
-        private val accessibilityManager: AccessibilityManager,
-        private val statusBarStateController: StatusBarStateController,
-        private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager,
-        private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
-        private val dialogManager: SystemUIDialogManager,
-        private val dumpManager: DumpManager,
-        private val transitionController: LockscreenShadeTransitionController,
-        private val configurationController: ConfigurationController,
-        private val keyguardStateController: KeyguardStateController,
-        private val unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController,
-        private var udfpsDisplayModeProvider: UdfpsDisplayModeProvider,
-        val requestId: Long,
-        @RequestReason val requestReason: Int,
-        private val controllerCallback: IUdfpsOverlayControllerCallback,
-        private val onTouch: (View, MotionEvent, Boolean) -> Boolean,
-        private val activityTransitionAnimator: ActivityTransitionAnimator,
-        private val primaryBouncerInteractor: PrimaryBouncerInteractor,
-        private val alternateBouncerInteractor: AlternateBouncerInteractor,
-        private val isDebuggable: Boolean = Build.IS_DEBUGGABLE,
-        private val udfpsKeyguardAccessibilityDelegate: UdfpsKeyguardAccessibilityDelegate,
-        private val transitionInteractor: KeyguardTransitionInteractor,
-        private val selectedUserInteractor: SelectedUserInteractor,
-        private val deviceEntryUdfpsTouchOverlayViewModel:
-            Lazy<DeviceEntryUdfpsTouchOverlayViewModel>,
-        private val defaultUdfpsTouchOverlayViewModel: Lazy<DefaultUdfpsTouchOverlayViewModel>,
-        private val shadeInteractor: ShadeInteractor,
-        private val udfpsOverlayInteractor: UdfpsOverlayInteractor,
-        private val powerInteractor: PowerInteractor,
-        @Application private val scope: CoroutineScope,
+class UdfpsControllerOverlay
+@JvmOverloads
+constructor(
+    private val context: Context,
+    private val inflater: LayoutInflater,
+    private val windowManager: WindowManager,
+    private val accessibilityManager: AccessibilityManager,
+    private val statusBarStateController: StatusBarStateController,
+    private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager,
+    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
+    private val dialogManager: SystemUIDialogManager,
+    private val dumpManager: DumpManager,
+    private val transitionController: LockscreenShadeTransitionController,
+    private val configurationController: ConfigurationController,
+    private val keyguardStateController: KeyguardStateController,
+    private val unlockedScreenOffAnimationController: UnlockedScreenOffAnimationController,
+    private var udfpsDisplayModeProvider: UdfpsDisplayModeProvider,
+    val requestId: Long,
+    @RequestReason val requestReason: Int,
+    private val controllerCallback: IUdfpsOverlayControllerCallback,
+    private val onTouch: (View, MotionEvent, Boolean) -> Boolean,
+    private val activityTransitionAnimator: ActivityTransitionAnimator,
+    private val primaryBouncerInteractor: PrimaryBouncerInteractor,
+    private val alternateBouncerInteractor: AlternateBouncerInteractor,
+    private val isDebuggable: Boolean = Build.IS_DEBUGGABLE,
+    private val udfpsKeyguardAccessibilityDelegate: UdfpsKeyguardAccessibilityDelegate,
+    private val transitionInteractor: KeyguardTransitionInteractor,
+    private val selectedUserInteractor: SelectedUserInteractor,
+    private val deviceEntryUdfpsTouchOverlayViewModel: Lazy<DeviceEntryUdfpsTouchOverlayViewModel>,
+    private val defaultUdfpsTouchOverlayViewModel: Lazy<DefaultUdfpsTouchOverlayViewModel>,
+    private val shadeInteractor: ShadeInteractor,
+    private val udfpsOverlayInteractor: UdfpsOverlayInteractor,
+    private val powerInteractor: PowerInteractor,
+    @Application private val scope: CoroutineScope,
 ) {
     private val currentStateUpdatedToOffAodOrDozing: Flow<Unit> =
         transitionInteractor.currentKeyguardState
             .filter {
-                it == KeyguardState.OFF ||
-                    it == KeyguardState.AOD ||
-                    it == KeyguardState.DOZING
+                it == KeyguardState.OFF || it == KeyguardState.AOD || it == KeyguardState.DOZING
             }
-            .map { } // map to Unit
+            .map {} // map to Unit
     private var listenForCurrentKeyguardState: Job? = null
     private var addViewRunnable: Runnable? = null
     private var overlayViewLegacy: UdfpsView? = null
         private set
+
     private var overlayTouchView: UdfpsTouchOverlay? = null
 
     /**
-     * Get the current UDFPS overlay touch view which is a different View depending on whether
-     * the DeviceEntryUdfpsRefactor flag is enabled or not.
+     * Get the current UDFPS overlay touch view which is a different View depending on whether the
+     * DeviceEntryUdfpsRefactor flag is enabled or not.
+     *
      * @return The view, when [isShowing], else null
      */
     fun getTouchOverlay(): View? {
@@ -158,23 +156,28 @@
 
     private var overlayTouchListener: TouchExplorationStateChangeListener? = null
 
-    private val coreLayoutParams = WindowManager.LayoutParams(
-        WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
-        0 /* flags set in computeLayoutParams() */,
-        PixelFormat.TRANSLUCENT
-    ).apply {
-        title = TAG
-        fitInsetsTypes = 0
-        gravity = android.view.Gravity.TOP or android.view.Gravity.LEFT
-        layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
-        flags = (Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS or
-                WindowManager.LayoutParams.FLAG_SPLIT_TOUCH)
-        privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY or
-                WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION
-        // Avoid announcing window title.
-        accessibilityTitle = " "
-        inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_SPY
-    }
+    private val coreLayoutParams =
+        WindowManager.LayoutParams(
+                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
+                0 /* flags set in computeLayoutParams() */,
+                PixelFormat.TRANSLUCENT
+            )
+            .apply {
+                title = TAG
+                fitInsetsTypes = 0
+                gravity = android.view.Gravity.TOP or android.view.Gravity.LEFT
+                layoutInDisplayCutoutMode =
+                    WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
+                flags =
+                    (Utils.FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS or
+                        WindowManager.LayoutParams.FLAG_SPLIT_TOUCH)
+                privateFlags =
+                    WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY or
+                        WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION
+                // Avoid announcing window title.
+                accessibilityTitle = " "
+                inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_SPY
+            }
 
     /** If the overlay is currently showing. */
     val isShowing: Boolean
@@ -209,51 +212,51 @@
             sensorBounds = Rect(params.sensorBounds)
             try {
                 if (DeviceEntryUdfpsRefactor.isEnabled) {
-                    overlayTouchView = (inflater.inflate(
-                            R.layout.udfps_touch_overlay, null, false
-                    ) as UdfpsTouchOverlay).apply {
-                        // This view overlaps the sensor area
-                        // prevent it from being selectable during a11y
-                        if (requestReason.isImportantForAccessibility()) {
-                            importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
-                        }
+                    overlayTouchView =
+                        (inflater.inflate(R.layout.udfps_touch_overlay, null, false)
+                                as UdfpsTouchOverlay)
+                            .apply {
+                                // This view overlaps the sensor area
+                                // prevent it from being selectable during a11y
+                                if (requestReason.isImportantForAccessibility()) {
+                                    importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
+                                }
 
-                        addViewNowOrLater(this, null)
-                        when (requestReason) {
-                            REASON_AUTH_KEYGUARD ->
-                                UdfpsTouchOverlayBinder.bind(
-                                    view = this,
-                                    viewModel = deviceEntryUdfpsTouchOverlayViewModel.get(),
-                                    udfpsOverlayInteractor = udfpsOverlayInteractor,
-                                )
-                            else ->
-                                UdfpsTouchOverlayBinder.bind(
-                                    view = this,
-                                    viewModel = defaultUdfpsTouchOverlayViewModel.get(),
-                                    udfpsOverlayInteractor = udfpsOverlayInteractor,
-                                )
-                        }
-                    }
+                                addViewNowOrLater(this, null)
+                                when (requestReason) {
+                                    REASON_AUTH_KEYGUARD ->
+                                        UdfpsTouchOverlayBinder.bind(
+                                            view = this,
+                                            viewModel = deviceEntryUdfpsTouchOverlayViewModel.get(),
+                                            udfpsOverlayInteractor = udfpsOverlayInteractor,
+                                        )
+                                    else ->
+                                        UdfpsTouchOverlayBinder.bind(
+                                            view = this,
+                                            viewModel = defaultUdfpsTouchOverlayViewModel.get(),
+                                            udfpsOverlayInteractor = udfpsOverlayInteractor,
+                                        )
+                                }
+                            }
                 } else {
-                    overlayViewLegacy = (inflater.inflate(
-                            R.layout.udfps_view, null, false
-                    ) as UdfpsView).apply {
-                        overlayParams = params
-                        setUdfpsDisplayModeProvider(udfpsDisplayModeProvider)
-                        val animation = inflateUdfpsAnimation(this, controller)
-                        if (animation != null) {
-                            animation.init()
-                            animationViewController = animation
-                        }
-                        // This view overlaps the sensor area
-                        // prevent it from being selectable during a11y
-                        if (requestReason.isImportantForAccessibility()) {
-                            importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
-                        }
+                    overlayViewLegacy =
+                        (inflater.inflate(R.layout.udfps_view, null, false) as UdfpsView).apply {
+                            overlayParams = params
+                            setUdfpsDisplayModeProvider(udfpsDisplayModeProvider)
+                            val animation = inflateUdfpsAnimation(this, controller)
+                            if (animation != null) {
+                                animation.init()
+                                animationViewController = animation
+                            }
+                            // This view overlaps the sensor area
+                            // prevent it from being selectable during a11y
+                            if (requestReason.isImportantForAccessibility()) {
+                                importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO
+                            }
 
-                        addViewNowOrLater(this, animation)
-                        sensorRect = sensorBounds
-                    }
+                            addViewNowOrLater(this, animation)
+                            sensorRect = sensorBounds
+                        }
                 }
                 getTouchOverlay()?.apply {
                     touchExplorationEnabled = accessibilityManager.isTouchExplorationEnabled
@@ -269,7 +272,7 @@
                         }
                     }
                     accessibilityManager.addTouchExplorationStateChangeListener(
-                            overlayTouchListener!!
+                        overlayTouchListener!!
                     )
                     overlayTouchListener?.onTouchExplorationStateChanged(true)
                 }
@@ -284,30 +287,18 @@
     }
 
     private fun addViewNowOrLater(view: View, animation: UdfpsAnimationViewController<*>?) {
-        if (udfpsViewPerformance()) {
-            addViewRunnable = kotlinx.coroutines.Runnable {
+        addViewRunnable =
+            kotlinx.coroutines.Runnable {
                 Trace.setCounter("UdfpsAddView", 1)
-                windowManager.addView(
-                        view,
-                        coreLayoutParams.updateDimensions(animation)
-                )
+                windowManager.addView(view, coreLayoutParams.updateDimensions(animation))
             }
-            if (powerInteractor.detailedWakefulness.value.isAwake()) {
-                // Device is awake, so we add the view immediately.
-                addViewIfPending()
-            } else {
-                listenForCurrentKeyguardState?.cancel()
-                listenForCurrentKeyguardState = scope.launch {
-                    currentStateUpdatedToOffAodOrDozing.collect {
-                        addViewIfPending()
-                    }
-                }
-            }
+        if (powerInteractor.detailedWakefulness.value.isAwake()) {
+            // Device is awake, so we add the view immediately.
+            addViewIfPending()
         } else {
-            windowManager.addView(
-                    view,
-                    coreLayoutParams.updateDimensions(animation)
-            )
+            listenForCurrentKeyguardState?.cancel()
+            listenForCurrentKeyguardState =
+                scope.launch { currentStateUpdatedToOffAodOrDozing.collect { addViewIfPending() } }
         }
     }
 
@@ -340,23 +331,26 @@
     ): UdfpsAnimationViewController<*>? {
         DeviceEntryUdfpsRefactor.assertInLegacyMode()
 
-        val isEnrollment = when (requestReason) {
-            REASON_ENROLL_FIND_SENSOR, REASON_ENROLL_ENROLLING -> true
-            else -> false
-        }
+        val isEnrollment =
+            when (requestReason) {
+                REASON_ENROLL_FIND_SENSOR,
+                REASON_ENROLL_ENROLLING -> true
+                else -> false
+            }
 
-        val filteredRequestReason = if (isEnrollment && shouldRemoveEnrollmentUi()) {
-            REASON_AUTH_OTHER
-        } else {
-            requestReason
-        }
+        val filteredRequestReason =
+            if (isEnrollment && shouldRemoveEnrollmentUi()) {
+                REASON_AUTH_OTHER
+            } else {
+                requestReason
+            }
 
         return when (filteredRequestReason) {
             REASON_ENROLL_FIND_SENSOR,
             REASON_ENROLL_ENROLLING -> {
                 // Enroll udfps UI is handled by settings, so use empty view here
                 UdfpsFpmEmptyViewController(
-                    view.addUdfpsView(R.layout.udfps_fpm_empty_view){
+                    view.addUdfpsView(R.layout.udfps_fpm_empty_view) {
                         updateAccessibilityViewLocation(sensorBounds)
                     },
                     statusBarStateController,
@@ -434,14 +428,10 @@
             udfpsDisplayModeProvider.disable(null)
         }
         getTouchOverlay()?.apply {
-            if (udfpsViewPerformance()) {
-                if (this.parent != null) {
-                    windowManager.removeView(this)
-                }
-                Trace.setCounter("UdfpsAddView", 0)
-            } else {
+            if (this.parent != null) {
                 windowManager.removeView(this)
             }
+            Trace.setCounter("UdfpsAddView", 0)
             setOnTouchListener(null)
             setOnHoverListener(null)
             overlayTouchListener?.let {
@@ -475,22 +465,19 @@
         val paddingX = animation?.paddingX ?: 0
         val paddingY = animation?.paddingY ?: 0
 
-        val isEnrollment = when (requestReason) {
-            REASON_ENROLL_FIND_SENSOR, REASON_ENROLL_ENROLLING -> true
-            else -> false
-        }
+        val isEnrollment =
+            when (requestReason) {
+                REASON_ENROLL_FIND_SENSOR,
+                REASON_ENROLL_ENROLLING -> true
+                else -> false
+            }
 
         // Use expanded overlay unless touchExploration enabled
         var rotatedBounds =
             if (accessibilityManager.isTouchExplorationEnabled && isEnrollment) {
                 Rect(overlayParams.sensorBounds)
             } else {
-                Rect(
-                    0,
-                    0,
-                    overlayParams.naturalDisplayWidth,
-                    overlayParams.naturalDisplayHeight
-                )
+                Rect(0, 0, overlayParams.naturalDisplayWidth, overlayParams.naturalDisplayHeight)
             }
 
         val rot = overlayParams.rotation
@@ -498,7 +485,8 @@
             if (!shouldRotate(animation)) {
                 Log.v(
                     TAG,
-                    "Skip rotating UDFPS bounds " + Surface.rotationToString(rot) +
+                    "Skip rotating UDFPS bounds " +
+                        Surface.rotationToString(rot) +
                         " animation=$animation" +
                         " isGoingToSleep=${keyguardUpdateMonitor.isGoingToSleep}" +
                         " isOccluded=${keyguardStateController.isOccluded}"
@@ -559,6 +547,4 @@
 
 @RequestReason
 private fun Int.isImportantForAccessibility() =
-    this == REASON_ENROLL_FIND_SENSOR ||
-            this == REASON_ENROLL_ENROLLING ||
-            this == REASON_AUTH_BP
+    this == REASON_ENROLL_FIND_SENSOR || this == REASON_ENROLL_ENROLLING || this == REASON_AUTH_BP
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt
index f5e3d29..97ece11 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt
@@ -75,6 +75,8 @@
             simFingerUp()
         } else if (args.size == 1 && args[0] == "biometricPrompt") {
             launchBiometricPrompt()
+        } else if (args.size == 2 && args[0] == "setIgnoreDisplayTouches") {
+            setIgnoreDisplayTouches(args[1].toBoolean())
         } else {
             invalidCommand(pw)
         }
@@ -186,6 +188,11 @@
         upEvent?.recycle()
     }
 
+    @VisibleForTesting
+    fun setIgnoreDisplayTouches(ignoreTouches: Boolean) {
+        udfpsOverlayController?.debugSetIgnoreDisplayTouches(ignoreTouches)
+    }
+
     private fun obtainMotionEvent(
         action: Int,
         x: Float,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt
index a742c0e..8c64b76 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractor.kt
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
 package com.android.systemui.biometrics.domain.interactor
 
 import android.hardware.biometrics.AuthenticateOptions
@@ -21,16 +23,22 @@
 import android.util.Log
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
 import com.android.systemui.display.data.repository.DeviceStateRepository
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import dagger.Lazy
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.cancel
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.catch
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.map
@@ -76,22 +84,36 @@
     deviceStateRepository: DeviceStateRepository,
     keyguardTransitionInteractor: KeyguardTransitionInteractor,
     udfpsOverlayInteractor: UdfpsOverlayInteractor,
+    deviceEntryInteractor: Lazy<DeviceEntryInteractor>,
 ) : LogContextInteractor {
 
-    override val displayState =
-        keyguardTransitionInteractor.startedKeyguardTransitionStep.map {
-            when (it.to) {
-                KeyguardState.LOCKSCREEN,
-                KeyguardState.OCCLUDED,
-                KeyguardState.ALTERNATE_BOUNCER,
-                KeyguardState.PRIMARY_BOUNCER -> AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN
-                KeyguardState.AOD -> AuthenticateOptions.DISPLAY_STATE_AOD
-                KeyguardState.OFF,
-                KeyguardState.DOZING -> AuthenticateOptions.DISPLAY_STATE_NO_UI
-                KeyguardState.DREAMING -> AuthenticateOptions.DISPLAY_STATE_SCREENSAVER
-                else -> AuthenticateOptions.DISPLAY_STATE_UNKNOWN
+    override val displayState: Flow<Int> by lazy {
+        if (SceneContainerFlag.isEnabled) {
+            combine(
+                deviceEntryInteractor.get().isDeviceEntered,
+                keyguardTransitionInteractor.startedKeyguardTransitionStep,
+            ) { isDeviceEntered, transitionStep ->
+                if (isDeviceEntered) {
+                    AuthenticateOptions.DISPLAY_STATE_UNKNOWN
+                } else {
+                    transitionStep.toAuthenticateOptions(
+                        // Here when isDeviceEntered=false which always means that the device is on
+                        // top of the keyguard. Therefore, any KeyguardState that doesn't have a
+                        // more specific mapping as a sub-state of keyguard, maps to LOCKSCREEN
+                        // instead of UNKNOWN, because it _is_ a known display state and that
+                        // display state is undeniably LOCKSCREEN.
+                        default = AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN
+                    )
+                }
+            }
+        } else {
+            keyguardTransitionInteractor.startedKeyguardTransitionStep.map { transitionStep ->
+                transitionStep.toAuthenticateOptions(
+                    default = AuthenticateOptions.DISPLAY_STATE_UNKNOWN
+                )
             }
         }
+    }
 
     override val isHardwareIgnoringTouches: Flow<Boolean> =
         udfpsOverlayInteractor.shouldHandleTouches.map { shouldHandle -> !shouldHandle }
@@ -152,6 +174,21 @@
         }
     }
 
+    private fun TransitionStep.toAuthenticateOptions(default: Int): Int {
+        return when (this.to) {
+            KeyguardState.LOCKSCREEN,
+            KeyguardState.OCCLUDED,
+            KeyguardState.ALTERNATE_BOUNCER,
+            KeyguardState.PRIMARY_BOUNCER -> AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN
+            KeyguardState.AOD -> AuthenticateOptions.DISPLAY_STATE_AOD
+            KeyguardState.OFF,
+            KeyguardState.DOZING -> AuthenticateOptions.DISPLAY_STATE_NO_UI
+            KeyguardState.DREAMING -> AuthenticateOptions.DISPLAY_STATE_SCREENSAVER
+            KeyguardState.GONE -> AuthenticateOptions.DISPLAY_STATE_UNKNOWN
+            else -> default
+        }
+    }
+
     companion object {
         private const val TAG = "ContextRepositoryImpl"
     }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt
index c08756f..5e2b5ff 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/PromptSelectorInteractor.kt
@@ -74,7 +74,7 @@
     val isConfirmationRequired: Flow<Boolean>
 
     /** Fingerprint sensor type */
-    val sensorType: Flow<FingerprintSensorType>
+    val fingerprintSensorType: Flow<FingerprintSensorType>
 
     /** Switch to the credential view. */
     fun onSwitchToCredential()
@@ -154,7 +154,8 @@
             }
         }
 
-    override val sensorType: Flow<FingerprintSensorType> = fingerprintPropertyRepository.sensorType
+    override val fingerprintSensorType: Flow<FingerprintSensorType> =
+        fingerprintPropertyRepository.sensorType
 
     override fun onSwitchToCredential() {
         val modalities: BiometricModalities =
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt
index a77cc1f..bb450c0 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.biometrics.domain.interactor
 
 import android.content.Context
+import android.hardware.fingerprint.FingerprintManager
 import android.util.Log
 import android.view.MotionEvent
 import com.android.systemui.biometrics.AuthController
@@ -46,6 +47,7 @@
     @Application private val context: Context,
     private val authController: AuthController,
     private val selectedUserInteractor: SelectedUserInteractor,
+    private val fingerprintManager: FingerprintManager?,
     @Application scope: CoroutineScope
 ) {
     private fun calculateIconSize(): Int {
@@ -70,8 +72,25 @@
         return isUdfpsEnrolled && isWithinOverlayBounds
     }
 
+    private var _requestId = MutableStateFlow(0L)
+
+    /** RequestId of current AcquisitionClient */
+    val requestId: StateFlow<Long> = _requestId.asStateFlow()
+
+    fun setRequestId(requestId: Long) {
+        _requestId.value = requestId
+    }
+
     /** Sets whether Udfps overlay should handle touches */
     fun setHandleTouches(shouldHandle: Boolean = true) {
+        if (authController.isUltrasonicUdfpsSupported
+                && shouldHandle != _shouldHandleTouches.value) {
+            fingerprintManager?.setIgnoreDisplayTouches(
+                requestId.value,
+                authController.udfpsProps!!.get(0).sensorId,
+                !shouldHandle
+            )
+        }
         _shouldHandleTouches.value = shouldHandle
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
index 408e2c2..c868d01 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
@@ -580,18 +580,23 @@
         }
     }
 
-    private suspend fun getHelpForSuccessfulAuthentication(
+    private fun getHelpForSuccessfulAuthentication(
         authenticatedModality: BiometricModality,
-    ): Int? =
-        when {
-            // for coex, show a message when face succeeds after fingerprint has also started
-            modalities.hasFaceAndFingerprint &&
-                (viewModel.fingerprintStartMode.first() != FingerprintStartMode.Pending) &&
-                (authenticatedModality == BiometricModality.Face) ->
-                R.string.biometric_dialog_tap_confirm_with_face_alt_1
-            else -> null
+    ): Int? {
+        // for coex, show a message when face succeeds after fingerprint has also started
+        if (authenticatedModality != BiometricModality.Face) {
+            return null
         }
 
+        if (modalities.hasUdfps) {
+            return R.string.biometric_dialog_tap_confirm_with_face_alt_1
+        }
+        if (modalities.hasSfps) {
+            return R.string.biometric_dialog_tap_confirm_with_face_sfps
+        }
+        return null
+    }
+
     fun onAuthenticationFailed(
         @BiometricAuthenticator.Modality modality: Int,
         failureReason: String,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
index 900d7cc..5e0e2bb 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
@@ -17,15 +17,11 @@
 
 package com.android.systemui.biometrics.ui.binder
 
-import android.graphics.drawable.AnimatedVectorDrawable
 import android.util.Log
-import androidx.constraintlayout.widget.ConstraintLayout
-import androidx.constraintlayout.widget.ConstraintSet
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
 import com.airbnb.lottie.LottieAnimationView
 import com.airbnb.lottie.LottieOnCompositionLoadedListener
-import com.airbnb.lottie.LottieListener
 import com.android.settingslib.widget.LottieColorUtils
 import com.android.systemui.Flags.constraintBp
 import com.android.systemui.biometrics.ui.viewmodel.PromptIconViewModel
@@ -66,85 +62,35 @@
                     iconOverlayView.layoutParams.height = iconViewLayoutParamSizeOverride.second
                 }
 
-                var faceIcon: AnimatedVectorDrawable? = null
-
-                fun updateXmlIconAsset(
-                    iconAsset: Int,
-                    shouldAnimateIconView: Boolean,
-                    activeAuthType: AuthType
-                ) {
-                    faceIcon?.stop()
-                    faceIcon = iconView.context.getDrawable(iconAsset) as AnimatedVectorDrawable
-                    faceIcon?.apply {
-                        iconView.setIconFailureListener(iconAsset, activeAuthType)
-                        iconView.setImageDrawable(this)
-                        if (shouldAnimateIconView) {
-                            forceAnimationOnUI()
-                            start()
-                        }
-                    }
-                }
-
-                fun updateJsonIconAsset(
-                    iconAsset: Int,
-                    shouldAnimateIconView: Boolean,
-                    activeAuthType: AuthType
-                ) {
-                    iconView.setIconFailureListener(iconAsset, activeAuthType)
-                    iconView.setAnimation(iconAsset)
-                    iconView.frame = 0
-
-                    if (shouldAnimateIconView) {
-                        iconView.playAnimation()
-                    }
-                }
-
                 if (!constraintBp()) {
                     launch {
                         var lottieOnCompositionLoadedListener: LottieOnCompositionLoadedListener? =
                             null
 
-                        combine(viewModel.activeAuthType, viewModel.iconSize, ::Pair).collect {
-                            (activeAuthType, iconSize) ->
-                            // Every time after bp shows, [isIconViewLoaded] is set to false in
-                            // [BiometricViewSizeBinder]. Then when biometric prompt view is redrew
-                            // (when size or activeAuthType changes), we need to update
-                            // [isIconViewLoaded] here to keep it correct.
-                            when (activeAuthType) {
-                                AuthType.Fingerprint,
-                                AuthType.Coex -> {
-                                    /**
-                                     * View is only set visible in BiometricViewSizeBinder once
-                                     * PromptSize is determined that accounts for iconView size, to
-                                     * prevent prompt resizing being visible to the user.
-                                     *
-                                     * TODO(b/288175072): May be able to remove this once constraint
-                                     *   layout is implemented
-                                     */
-                                    if (lottieOnCompositionLoadedListener != null) {
-                                        iconView.removeLottieOnCompositionLoadedListener(
-                                            lottieOnCompositionLoadedListener!!
-                                        )
-                                    }
-                                    lottieOnCompositionLoadedListener =
-                                        LottieOnCompositionLoadedListener {
-                                            promptViewModel.setIsIconViewLoaded(true)
-                                        }
-                                    iconView.addLottieOnCompositionLoadedListener(
-                                        lottieOnCompositionLoadedListener!!
-                                    )
-                                }
-                                AuthType.Face -> {
-                                    /**
-                                     * Set to true by default since face icon is a drawable, which
-                                     * doesn't have a LottieOnCompositionLoadedListener equivalent.
-                                     *
-                                     * TODO(b/318569643): To be updated once face assets are updated
-                                     *   from drawables
-                                     */
-                                    promptViewModel.setIsIconViewLoaded(true)
-                                }
+                        viewModel.iconSize.collect { iconSize ->
+                            /**
+                             * When we bind the BiometricPrompt View and ViewModel in
+                             * [BiometricViewBinder], the view is set invisible and
+                             * [isIconViewLoaded] is set to false. We configure the iconView with a
+                             * LottieOnCompositionLoadedListener that sets [isIconViewLoaded] to
+                             * true, in order to wait for the iconView to load before determining
+                             * the prompt size, and prevent any prompt resizing from being visible
+                             * to the user.
+                             *
+                             * TODO(b/288175072): May be able to remove this once constraint layout
+                             *   is unflagged
+                             */
+                            if (lottieOnCompositionLoadedListener != null) {
+                                iconView.removeLottieOnCompositionLoadedListener(
+                                    lottieOnCompositionLoadedListener!!
+                                )
                             }
+                            lottieOnCompositionLoadedListener = LottieOnCompositionLoadedListener {
+                                promptViewModel.setIsIconViewLoaded(true)
+                            }
+                            iconView.addLottieOnCompositionLoadedListener(
+                                lottieOnCompositionLoadedListener!!
+                            )
 
                             if (iconViewLayoutParamSizeOverride == null) {
                                 iconView.layoutParams.width = iconSize.first
@@ -171,51 +117,12 @@
                         .collect { (iconAsset, activeAuthType, shouldAnimateIconView, showingError)
                             ->
                             if (iconAsset != -1) {
-                                when (activeAuthType) {
-                                    AuthType.Fingerprint,
-                                    AuthType.Coex -> {
-                                        // TODO(b/318569643): Until assets unified to one type, this
-                                        // check
-                                        //  is needed in face-auth-error-triggered implicit ->
-                                        // explicit
-                                        //  coex auth transition, in case iconAsset updates to
-                                        //  face_dialog_dark_to_error (XML) after activeAuthType
-                                        // updates
-                                        //  from AuthType.Face (which expects XML)
-                                        //  to AuthType.Coex (which expects JSON)
-                                        if (iconAsset == R.drawable.face_dialog_dark_to_error) {
-                                            updateXmlIconAsset(
-                                                iconAsset,
-                                                shouldAnimateIconView,
-                                                activeAuthType
-                                            )
-                                        } else {
-                                            updateJsonIconAsset(
-                                                iconAsset,
-                                                shouldAnimateIconView,
-                                                activeAuthType
-                                            )
-                                        }
-                                    }
-                                    AuthType.Face -> {
-                                        // TODO(b/318569643): Consolidate logic once all face auth
-                                        // assets are migrated from drawable to json
-                                        if (iconAsset == R.raw.face_dialog_authenticating) {
-                                            updateJsonIconAsset(
-                                                iconAsset,
-                                                shouldAnimateIconView,
-                                                activeAuthType
-                                            )
-                                        } else {
-                                            updateXmlIconAsset(
-                                                iconAsset,
-                                                shouldAnimateIconView,
-                                                activeAuthType
-                                            )
-                                        }
-                                    }
-                                }
-                                LottieColorUtils.applyDynamicColors(iconView.context, iconView)
+                                iconView.updateAsset(
+                                    "iconAsset",
+                                    iconAsset,
+                                    shouldAnimateIconView,
+                                    activeAuthType
+                                )
                                 viewModel.setPreviousIconWasError(showingError)
                             }
                         }
@@ -233,17 +140,12 @@
                         )
                         .collect { (iconOverlayAsset, shouldAnimateIconOverlay, showingError) ->
                             if (iconOverlayAsset != -1) {
-                                iconOverlayView.setIconOverlayFailureListener(iconOverlayAsset)
-                                iconOverlayView.setAnimation(iconOverlayAsset)
-                                iconOverlayView.frame = 0
-                                LottieColorUtils.applyDynamicColors(
-                                    iconOverlayView.context,
-                                    iconOverlayView
+                                iconOverlayView.updateAsset(
+                                    "iconOverlayAsset",
+                                    iconOverlayAsset,
+                                    shouldAnimateIconOverlay,
+                                    AuthType.Fingerprint
                                 )
-
-                                if (shouldAnimateIconOverlay) {
-                                    iconOverlayView.playAnimation()
-                                }
                                 viewModel.setPreviousIconOverlayWasError(showingError)
                             }
                         }
@@ -313,11 +215,11 @@
         R.raw.biometricprompt_symbol_fingerprint_to_success_portrait_topleft to
             "biometricprompt_symbol_fingerprint_to_success_portrait_topleft",
         // Face assets
-        R.drawable.face_dialog_wink_from_dark to "face_dialog_wink_from_dark",
-        R.drawable.face_dialog_dark_to_checkmark to "face_dialog_dark_to_checkmark",
-        R.drawable.face_dialog_dark_to_error to "face_dialog_dark_to_error",
-        R.drawable.face_dialog_error_to_idle to "face_dialog_error_to_idle",
-        R.drawable.face_dialog_idle_static to "face_dialog_idle_static",
+        R.raw.face_dialog_wink_from_dark to "face_dialog_wink_from_dark",
+        R.raw.face_dialog_dark_to_checkmark to "face_dialog_dark_to_checkmark",
+        R.raw.face_dialog_dark_to_error to "face_dialog_dark_to_error",
+        R.raw.face_dialog_error_to_idle to "face_dialog_error_to_idle",
+        R.raw.face_dialog_idle_static to "face_dialog_idle_static",
         R.raw.face_dialog_authenticating to "face_dialog_authenticating",
         // Co-ex assets
         R.raw.fingerprint_dialogue_unlocked_to_checkmark_success_lottie to
@@ -332,31 +234,35 @@
     return assetIdToString.getOrDefault(id, "Asset $id not found")
 }
 
-private fun LottieAnimationView.setIconFailureListener(iconAsset: Int, activeAuthType: AuthType) {
-    setFailureListener(
-        LottieListener<Throwable> { result: Throwable? ->
-            Log.d(
-                TAG,
-                "Collecting iconAsset | " +
-                    "activeAuthType = $activeAuthType | " +
-                    "Invalid resource id: $iconAsset, " +
-                    "name ${getAssetNameFromId(iconAsset)}",
-                result
-            )
+fun LottieAnimationView.updateAsset(
+    type: String,
+    asset: Int,
+    shouldAnimateIconView: Boolean,
+    activeAuthType: AuthType
+) {
+    setFailureListener(type, asset, activeAuthType)
+    setAnimation(asset)
+    frame = 0
+    if (shouldAnimateIconView) {
+        if (asset == R.raw.face_dialog_authenticating) {
+            loop(true)
+        } else {
+            loop(false)
         }
-    )
+        playAnimation()
+    }
+    LottieColorUtils.applyDynamicColors(context, this)
 }
 
-private fun LottieAnimationView.setIconOverlayFailureListener(iconOverlayAsset: Int) {
-    setFailureListener(
-        LottieListener<Throwable> { result: Throwable? ->
-            Log.d(
-                TAG,
-                "Collecting iconOverlayAsset | " +
-                    "Invalid resource id: $iconOverlayAsset, " +
-                    "name ${getAssetNameFromId(iconOverlayAsset)}",
-                result
-            )
-        }
-    )
+private fun LottieAnimationView.setFailureListener(type: String, asset: Int, authType: AuthType) {
+    setFailureListener { result: Throwable? ->
+        Log.d(
+            TAG,
+            "Collecting $type | " +
+                "activeAuthType = $authType | " +
+                "Invalid resource id: $asset, " +
+                "name ${getAssetNameFromId(asset)}",
+            result
+        )
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt
index 9cc4650..9578da4 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinder.kt
@@ -139,6 +139,11 @@
         overlayView!!.visibility = View.INVISIBLE
         Log.d(TAG, "show(): adding overlayView $overlayView")
         windowManager.get().addView(overlayView, overlayViewModel.defaultOverlayViewParams)
+        overlayView!!.announceForAccessibility(
+            applicationContext.resources.getString(
+                R.string.accessibility_side_fingerprint_indicator_label
+            )
+        )
     }
 
     /** Hide the side fingerprint sensor indicator */
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
index 7081661..6c83dac 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
@@ -17,11 +17,9 @@
 
 package com.android.systemui.biometrics.ui.viewmodel
 
-import android.annotation.DrawableRes
 import android.annotation.RawRes
 import android.content.res.Configuration
 import android.graphics.Rect
-import android.hardware.face.Face
 import android.util.RotationUtils
 import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
 import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor
@@ -137,7 +135,7 @@
                         displayStateInteractor.currentRotation,
                         displayStateInteractor.isFolded,
                         displayStateInteractor.isInRearDisplayMode,
-                        promptSelectorInteractor.sensorType,
+                        promptSelectorInteractor.fingerprintSensorType,
                         promptViewModel.isAuthenticated,
                         promptViewModel.isAuthenticating,
                         promptViewModel.showingError
@@ -183,7 +181,7 @@
                         displayStateInteractor.currentRotation,
                         displayStateInteractor.isFolded,
                         displayStateInteractor.isInRearDisplayMode,
-                        promptSelectorInteractor.sensorType,
+                        promptSelectorInteractor.fingerprintSensorType,
                         promptViewModel.isAuthenticated,
                         promptViewModel.isAuthenticating,
                         promptViewModel.isPendingConfirmation,
@@ -268,7 +266,7 @@
                 }
         }
 
-    @DrawableRes
+    @RawRes
     private fun getFaceIconViewAsset(
         authState: PromptAuthState,
         isAuthenticating: Boolean,
@@ -276,17 +274,17 @@
         showingError: Boolean
     ): Int =
         if (authState.isAuthenticated && isPendingConfirmation) {
-            R.drawable.face_dialog_wink_from_dark
+            R.raw.face_dialog_wink_from_dark
         } else if (authState.isAuthenticated) {
-            R.drawable.face_dialog_dark_to_checkmark
+            R.raw.face_dialog_dark_to_checkmark
         } else if (isAuthenticating) {
             R.raw.face_dialog_authenticating
         } else if (showingError) {
-            R.drawable.face_dialog_dark_to_error
+            R.raw.face_dialog_dark_to_error
         } else if (_previousIconWasError.value) {
-            R.drawable.face_dialog_error_to_idle
+            R.raw.face_dialog_error_to_idle
         } else {
-            R.drawable.face_dialog_idle_static
+            R.raw.face_dialog_idle_static
         }
 
     @RawRes
@@ -330,7 +328,7 @@
                 AuthType.Coex ->
                     combine(
                         displayStateInteractor.currentRotation,
-                        promptSelectorInteractor.sensorType,
+                        promptSelectorInteractor.fingerprintSensorType,
                         promptViewModel.isAuthenticated,
                         promptViewModel.isAuthenticating,
                         promptViewModel.showingError
@@ -430,7 +428,7 @@
                 AuthType.Fingerprint,
                 AuthType.Coex ->
                     combine(
-                        promptSelectorInteractor.sensorType,
+                        promptSelectorInteractor.fingerprintSensorType,
                         promptViewModel.isAuthenticated,
                         promptViewModel.isAuthenticating,
                         promptViewModel.isPendingConfirmation,
@@ -508,7 +506,7 @@
             when (activeAuthType) {
                 AuthType.Fingerprint ->
                     combine(
-                        promptSelectorInteractor.sensorType,
+                        promptSelectorInteractor.fingerprintSensorType,
                         promptViewModel.isAuthenticated,
                         promptViewModel.isAuthenticating,
                         promptViewModel.showingError
@@ -546,7 +544,7 @@
                     }
                 AuthType.Coex ->
                     combine(
-                        promptSelectorInteractor.sensorType,
+                        promptSelectorInteractor.fingerprintSensorType,
                         promptViewModel.isAuthenticated,
                         promptViewModel.isAuthenticating,
                         promptViewModel.isPendingConfirmation,
@@ -606,7 +604,7 @@
                 AuthType.Fingerprint,
                 AuthType.Coex ->
                     combine(
-                        promptSelectorInteractor.sensorType,
+                        promptSelectorInteractor.fingerprintSensorType,
                         promptViewModel.isAuthenticated,
                         promptViewModel.isAuthenticating,
                         promptViewModel.showingError
@@ -642,7 +640,7 @@
                 AuthType.Fingerprint,
                 AuthType.Coex ->
                     combine(
-                        promptSelectorInteractor.sensorType,
+                        promptSelectorInteractor.fingerprintSensorType,
                         displayStateInteractor.currentRotation
                     ) { sensorType: FingerprintSensorType, rotation: DisplayRotation ->
                         when (sensorType) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
index ac8807d..3904ee1 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
@@ -50,6 +50,7 @@
 import com.android.systemui.biometrics.shared.model.BiometricModality
 import com.android.systemui.biometrics.shared.model.DisplayRotation
 import com.android.systemui.biometrics.shared.model.PromptKind
+import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.keyguard.shared.model.AcquiredFingerprintAuthenticationStatus
 import com.android.systemui.res.R
@@ -132,11 +133,11 @@
             R.dimen.biometric_prompt_landscape_medium_horizontal_padding
         )
 
+    val udfpsOverlayParams: StateFlow<UdfpsOverlayParams> =
+        udfpsOverlayInteractor.udfpsOverlayParams
+
     private val udfpsSensorBounds: Flow<Rect> =
-        combine(
-                udfpsOverlayInteractor.udfpsOverlayParams,
-                displayStateInteractor.currentRotation
-            ) { params, rotation ->
+        combine(udfpsOverlayParams, displayStateInteractor.currentRotation) { params, rotation ->
                 val rotatedBounds = Rect(params.sensorBounds)
                 RotationUtils.rotateBounds(
                     rotatedBounds,
@@ -153,32 +154,27 @@
             }
             .distinctUntilChanged()
 
+    private val udfpsSensorWidth: Flow<Int> = udfpsOverlayParams.map { it.sensorBounds.width() }
+    private val udfpsSensorHeight: Flow<Int> = udfpsOverlayParams.map { it.sensorBounds.height() }
+
     val legacyFingerprintSensorWidth: Flow<Int> =
-        combine(modalities, udfpsOverlayInteractor.udfpsOverlayParams) { modalities, overlayParams
-            ->
+        combine(modalities, udfpsSensorWidth) { modalities, udfpsSensorWidth ->
             if (modalities.hasUdfps) {
-                overlayParams.sensorBounds.width()
+                udfpsSensorWidth
             } else {
                 fingerprintIconWidth
             }
         }
 
     val legacyFingerprintSensorHeight: Flow<Int> =
-        combine(modalities, udfpsOverlayInteractor.udfpsOverlayParams) { modalities, overlayParams
-            ->
+        combine(modalities, udfpsSensorHeight) { modalities, udfpsSensorHeight ->
             if (modalities.hasUdfps) {
-                overlayParams.sensorBounds.height()
+                udfpsSensorHeight
             } else {
                 fingerprintIconHeight
             }
         }
 
-    val fingerprintSensorWidth: Int =
-        udfpsOverlayInteractor.udfpsOverlayParams.value.sensorBounds.width()
-
-    val fingerprintSensorHeight: Int =
-        udfpsOverlayInteractor.udfpsOverlayParams.value.sensorBounds.height()
-
     private val _accessibilityHint = MutableSharedFlow<String>()
 
     /** Hint for talkback directional guidance */
@@ -442,12 +438,16 @@
 
     /** The size of the biometric icon */
     val iconSize: Flow<Pair<Int, Int>> =
-        combine(iconViewModel.activeAuthType, modalities) { activeAuthType, modalities ->
+        combine(iconViewModel.activeAuthType, modalities, udfpsSensorWidth, udfpsSensorHeight) {
+            activeAuthType,
+            modalities,
+            udfpsSensorWidth,
+            udfpsSensorHeight ->
             if (activeAuthType == PromptIconViewModel.AuthType.Face) {
                 Pair(faceIconWidth, faceIconHeight)
             } else {
                 if (modalities.hasUdfps) {
-                    Pair(fingerprintSensorWidth, fingerprintSensorHeight)
+                    Pair(udfpsSensorWidth, udfpsSensorHeight)
                 } else {
                     Pair(fingerprintIconWidth, fingerprintIconHeight)
                 }
@@ -921,13 +921,13 @@
                 udfpsUtils.getTouchInNativeCoordinates(
                     event.getPointerId(0),
                     event,
-                    udfpsOverlayInteractor.udfpsOverlayParams.value
+                    udfpsOverlayParams.value
                 )
             if (
                 !udfpsUtils.isWithinSensorArea(
                     event.getPointerId(0),
                     event,
-                    udfpsOverlayInteractor.udfpsOverlayParams.value
+                    udfpsOverlayParams.value
                 )
             ) {
                 _accessibilityHint.emit(
@@ -936,7 +936,7 @@
                         context,
                         scaledTouch.x,
                         scaledTouch.y,
-                        udfpsOverlayInteractor.udfpsOverlayParams.value
+                        udfpsOverlayParams.value
                     )
                 )
             }
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt
index 94f465d..eaddc42 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt
@@ -288,11 +288,13 @@
     private fun startSettingsActivity(intent: Intent, view: View) {
         if (job?.isActive == true) {
             intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
-            activityStarter.postStartActivityDismissingKeyguard(
-                intent,
-                0,
-                dialogTransitionAnimator.createActivityTransitionController(view)
-            )
+            val controller = dialogTransitionAnimator.createActivityTransitionController(view)
+            // The controller will be null when the screen is locked and going to show the
+            // primary bouncer. In this case we dismiss the dialog manually.
+            if (controller == null) {
+                cancelJob()
+            }
+            activityStarter.postStartActivityDismissingKeyguard(intent, 0, controller)
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt
index 1d11dfb..4984fc6 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt
@@ -102,11 +102,7 @@
                 if (alternateBouncerSupported) {
                     combine(
                             keyguardTransitionInteractor.get().currentKeyguardState,
-                            if (SceneContainerFlag.isEnabled) {
-                                sceneInteractor.get().currentScene
-                            } else {
-                                flowOf(Scenes.Lockscreen)
-                            },
+                            sceneInteractor.get().currentScene,
                             ::Pair
                         )
                         .flatMapLatest { (currentKeyguardState, transitionState) ->
@@ -220,6 +216,7 @@
         return (systemClock.uptimeMillis() - bouncerRepository.lastAlternateBouncerVisibleTime) >
             MIN_VISIBILITY_DURATION_UNTIL_TOUCHES_DISMISS_ALTERNATE_BOUNCER_MS
     }
+
     /**
      * Should only be called through StatusBarKeyguardViewManager which propagates the source of
      * truth to other concerned controllers. Will hide the alternate bouncer if it's no longer
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractor.kt
index 7d3075a..ed931bd 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/SimBouncerInteractor.kt
@@ -43,10 +43,11 @@
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.SharedFlow
+import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 
@@ -68,7 +69,12 @@
     mobileConnectionsRepository: MobileConnectionsRepository,
 ) {
     val subId: StateFlow<Int> = repository.subscriptionId
-    val isAnySimSecure: Flow<Boolean> = mobileConnectionsRepository.isAnySimSecure
+    val isAnySimSecure: StateFlow<Boolean> =
+        mobileConnectionsRepository.isAnySimSecure.stateIn(
+            scope = applicationScope,
+            started = SharingStarted.WhileSubscribed(),
+            initialValue = mobileConnectionsRepository.getIsAnySimSecure(),
+        )
     val isLockedEsim: StateFlow<Boolean?> = repository.isLockedEsim
     val errorDialogMessage: StateFlow<String?> = repository.errorDialogMessage
 
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt b/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
index f991d5b..8270db1 100644
--- a/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
+++ b/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
@@ -16,7 +16,7 @@
 
 package com.android.systemui.brightness.ui.compose
 
-import androidx.compose.animation.core.animateIntAsState
+import androidx.compose.animation.core.animateFloatAsState
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.size
@@ -57,12 +57,12 @@
 ) {
     var value by remember(gammaValue) { mutableIntStateOf(gammaValue) }
     val animatedValue by
-        animateIntAsState(targetValue = value, label = "BrightnessSliderAnimatedValue")
+        animateFloatAsState(targetValue = value.toFloat(), label = "BrightnessSliderAnimatedValue")
     val floatValueRange = valueRange.first.toFloat()..valueRange.last.toFloat()
-    val isRestricted = restriction is PolicyRestriction.Restricted
+    val isRestricted = remember(restriction) { restriction is PolicyRestriction.Restricted }
 
     PlatformSlider(
-        value = animatedValue.toFloat(),
+        value = animatedValue,
         valueRange = floatValueRange,
         enabled = !isRestricted,
         onValueChange = {
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/HistoryTracker.java b/packages/SystemUI/src/com/android/systemui/classifier/HistoryTracker.java
index 09bf04c..9cb26f3 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/HistoryTracker.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/HistoryTracker.java
@@ -20,9 +20,10 @@
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.util.time.SystemClock;
 
-import java.util.ArrayList;
+import com.google.common.collect.Sets;
+
 import java.util.Collection;
-import java.util.List;
+import java.util.Set;
 import java.util.concurrent.DelayQueue;
 import java.util.concurrent.Delayed;
 import java.util.concurrent.TimeUnit;
@@ -52,7 +53,7 @@
     private final SystemClock mSystemClock;
 
     DelayQueue<CombinedResult> mResults = new DelayQueue<>();
-    private final List<BeliefListener> mBeliefListeners = new ArrayList<>();
+    private final Set<BeliefListener> mBeliefListeners = Sets.newConcurrentHashSet();
 
     @Inject
     HistoryTracker(SystemClock systemClock) {
@@ -161,11 +162,15 @@
     }
 
     void addBeliefListener(BeliefListener listener) {
-        mBeliefListeners.add(listener);
+        if (listener != null) {
+            mBeliefListeners.add(listener);
+        }
     }
 
     void removeBeliefListener(BeliefListener listener) {
-        mBeliefListeners.remove(listener);
+        if (listener != null) {
+            mBeliefListeners.remove(listener);
+        }
     }
     /**
      * Represents a falsing score combing all the classifiers together.
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java
index ba236ba..1762d82 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayView.java
@@ -18,8 +18,6 @@
 
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 
-import static com.android.systemui.Flags.screenshotShelfUi2;
-
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
@@ -61,7 +59,6 @@
 import com.android.systemui.res.R;
 import com.android.systemui.screenshot.DraggableConstraintLayout;
 import com.android.systemui.screenshot.FloatingWindowUtil;
-import com.android.systemui.screenshot.OverlayActionChip;
 import com.android.systemui.screenshot.ui.binder.ActionButtonViewBinder;
 import com.android.systemui.screenshot.ui.viewmodel.ActionButtonAppearance;
 import com.android.systemui.screenshot.ui.viewmodel.ActionButtonViewModel;
@@ -152,66 +149,47 @@
     }
 
     private void bindDefaultActionChips() {
-        if (screenshotShelfUi2()) {
-            mActionButtonViewBinder.bind(mRemoteCopyChip,
-                    ActionButtonViewModel.Companion.withNextId(
-                            new ActionButtonAppearance(
-                                    Icon.createWithResource(mContext,
-                                            R.drawable.ic_baseline_devices_24).loadDrawable(
-                                            mContext),
-                                    null,
-                                    mContext.getString(R.string.clipboard_send_nearby_description),
-                                    true),
-                            new Function0<>() {
-                                @Override
-                                public Unit invoke() {
-                                    if (mClipboardCallbacks != null) {
-                                        mClipboardCallbacks.onRemoteCopyButtonTapped();
-                                    }
-                                    return null;
+        mActionButtonViewBinder.bind(mRemoteCopyChip,
+                ActionButtonViewModel.Companion.withNextId(
+                        new ActionButtonAppearance(
+                                Icon.createWithResource(mContext,
+                                        R.drawable.ic_baseline_devices_24).loadDrawable(
+                                        mContext),
+                                null,
+                                mContext.getString(R.string.clipboard_send_nearby_description),
+                                true),
+                        new Function0<>() {
+                            @Override
+                            public Unit invoke() {
+                                if (mClipboardCallbacks != null) {
+                                    mClipboardCallbacks.onRemoteCopyButtonTapped();
                                 }
-                            }));
-            mActionButtonViewBinder.bind(mShareChip,
-                    ActionButtonViewModel.Companion.withNextId(
-                            new ActionButtonAppearance(
-                                    Icon.createWithResource(mContext,
-                                            R.drawable.ic_screenshot_share).loadDrawable(mContext),
-                                    null,
-                                    mContext.getString(com.android.internal.R.string.share),
-                                    true),
-                            new Function0<>() {
-                                @Override
-                                public Unit invoke() {
-                                    if (mClipboardCallbacks != null) {
-                                        mClipboardCallbacks.onShareButtonTapped();
-                                    }
-                                    return null;
+                                return null;
+                            }
+                        }));
+        mActionButtonViewBinder.bind(mShareChip,
+                ActionButtonViewModel.Companion.withNextId(
+                        new ActionButtonAppearance(
+                                Icon.createWithResource(mContext,
+                                        R.drawable.ic_screenshot_share).loadDrawable(mContext),
+                                null,
+                                mContext.getString(com.android.internal.R.string.share),
+                                true),
+                        new Function0<>() {
+                            @Override
+                            public Unit invoke() {
+                                if (mClipboardCallbacks != null) {
+                                    mClipboardCallbacks.onShareButtonTapped();
                                 }
-                            }));
-        } else {
-            mShareChip.setAlpha(1);
-            mRemoteCopyChip.setAlpha(1);
-
-            ((ImageView) mRemoteCopyChip.findViewById(R.id.overlay_action_chip_icon)).setImageIcon(
-                    Icon.createWithResource(mContext, R.drawable.ic_baseline_devices_24));
-            ((ImageView) mShareChip.findViewById(R.id.overlay_action_chip_icon)).setImageIcon(
-                    Icon.createWithResource(mContext, R.drawable.ic_screenshot_share));
-
-            mShareChip.setContentDescription(
-                    mContext.getString(com.android.internal.R.string.share));
-            mRemoteCopyChip.setContentDescription(
-                    mContext.getString(R.string.clipboard_send_nearby_description));
-        }
+                                return null;
+                            }
+                        }));
     }
 
     @Override
     public void setCallbacks(SwipeDismissCallbacks callbacks) {
         super.setCallbacks(callbacks);
         ClipboardOverlayCallbacks clipboardCallbacks = (ClipboardOverlayCallbacks) callbacks;
-        if (!screenshotShelfUi2()) {
-            mShareChip.setOnClickListener(v -> clipboardCallbacks.onShareButtonTapped());
-            mRemoteCopyChip.setOnClickListener(v -> clipboardCallbacks.onRemoteCopyButtonTapped());
-        }
         mDismissButton.setOnClickListener(v -> clipboardCallbacks.onDismissButtonTapped());
         mClipboardPreview.setOnClickListener(v -> clipboardCallbacks.onPreviewTapped());
         mMinimizedPreview.setOnClickListener(v -> clipboardCallbacks.onMinimizedViewTapped());
@@ -495,12 +473,7 @@
 
     void setActionChip(RemoteAction action, Runnable onFinish) {
         mActionContainerBackground.setVisibility(View.VISIBLE);
-        View chip;
-        if (screenshotShelfUi2()) {
-            chip = constructShelfActionChip(action, onFinish);
-        } else {
-            chip = constructActionChip(action, onFinish);
-        }
+        View chip = constructShelfActionChip(action, onFinish);
         mActionContainer.addView(chip);
         mActionChips.add(chip);
     }
@@ -534,17 +507,6 @@
         return chip;
     }
 
-    private OverlayActionChip constructActionChip(RemoteAction action, Runnable onFinish) {
-        OverlayActionChip chip = (OverlayActionChip) LayoutInflater.from(mContext).inflate(
-                R.layout.overlay_action_chip, mActionContainer, false);
-        chip.setText(action.getTitle());
-        chip.setContentDescription(action.getTitle());
-        chip.setIcon(action.getIcon(), false);
-        chip.setPendingIntent(action.getActionIntent(), onFinish);
-        chip.setAlpha(1);
-        return chip;
-    }
-
     private static void updateTextSize(CharSequence text, TextView textView) {
         Paint paint = new Paint(textView.getPaint());
         Resources res = textView.getResources();
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java
index 740a93e..ff9fba4 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/dagger/ClipboardOverlayModule.java
@@ -18,8 +18,6 @@
 
 import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
 
-import static com.android.systemui.Flags.screenshotShelfUi2;
-
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import android.content.Context;
@@ -59,13 +57,8 @@
      */
     @Provides
     static ClipboardOverlayView provideClipboardOverlayView(@OverlayWindowContext Context context) {
-        if (screenshotShelfUi2()) {
-            return (ClipboardOverlayView) LayoutInflater.from(context).inflate(
-                    R.layout.clipboard_overlay2, null);
-        } else {
-            return (ClipboardOverlayView) LayoutInflater.from(context).inflate(
-                    R.layout.clipboard_overlay, null);
-        }
+        return (ClipboardOverlayView) LayoutInflater.from(context).inflate(
+                R.layout.clipboard_overlay, null);
     }
 
     @Qualifier
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/binder/IconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/common/ui/binder/IconViewBinder.kt
index 108e22b..64dedea 100644
--- a/packages/SystemUI/src/com/android/systemui/common/ui/binder/IconViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/binder/IconViewBinder.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.common.ui.binder
 
+import android.view.View
 import android.widget.ImageView
 import com.android.systemui.common.shared.model.Icon
 
@@ -30,4 +31,13 @@
             is Icon.Resource -> view.setImageResource(icon.res)
         }
     }
+
+    fun bindNullable(icon: Icon?, view: ImageView) {
+        if (icon != null) {
+            view.visibility = View.VISIBLE
+            bind(icon, view)
+        } else {
+            view.visibility = View.GONE
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalWidgetCategories.kt b/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalWidgetCategories.kt
index 5cd15f2..75f0bad 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalWidgetCategories.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/model/CommunalWidgetCategories.kt
@@ -17,7 +17,6 @@
 package com.android.systemui.communal.data.model
 
 import android.appwidget.AppWidgetProviderInfo
-import com.android.settingslib.flags.Flags.allowAllWidgetsOnLockscreenByDefault
 
 /**
  * The widget categories to display on communal hub (where categories is a bitfield with values that
@@ -31,9 +30,7 @@
         val defaultCategories: Int
             get() {
                 return AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD or
-                    if (allowAllWidgetsOnLockscreenByDefault())
-                        AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN
-                    else 0
+                    AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN
             }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalPrefsRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalPrefsRepository.kt
index b27fcfc..d8067b8 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalPrefsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalPrefsRepository.kt
@@ -27,26 +27,17 @@
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.core.Logger
 import com.android.systemui.log.dagger.CommunalLog
-import com.android.systemui.log.dagger.CommunalTableLog
-import com.android.systemui.log.table.TableLogBuffer
-import com.android.systemui.log.table.logDiffsForTable
 import com.android.systemui.settings.UserFileManager
-import com.android.systemui.user.data.repository.UserRepository
 import com.android.systemui.util.kotlin.SharedPreferencesExt.observe
 import com.android.systemui.util.kotlin.emitOnStart
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.flow.onStart
-import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.withContext
 
 /**
@@ -56,10 +47,16 @@
 interface CommunalPrefsRepository {
 
     /** Whether the CTA tile has been dismissed. */
-    val isCtaDismissed: Flow<Boolean>
+    fun isCtaDismissed(user: UserInfo): Flow<Boolean>
+
+    /** Whether the lock screen widget disclaimer has been dismissed by the user. */
+    fun isDisclaimerDismissed(user: UserInfo): Flow<Boolean>
 
     /** Save the CTA tile dismissed state for the current user. */
-    suspend fun setCtaDismissedForCurrentUser()
+    suspend fun setCtaDismissed(user: UserInfo)
+
+    /** Save the lock screen widget disclaimer dismissed state for the current user. */
+    suspend fun setDisclaimerDismissed(user: UserInfo)
 }
 
 @OptIn(ExperimentalCoroutinesApi::class)
@@ -67,75 +64,43 @@
 class CommunalPrefsRepositoryImpl
 @Inject
 constructor(
-    @Background private val backgroundScope: CoroutineScope,
     @Background private val bgDispatcher: CoroutineDispatcher,
-    private val userRepository: UserRepository,
     private val userFileManager: UserFileManager,
     broadcastDispatcher: BroadcastDispatcher,
     @CommunalLog logBuffer: LogBuffer,
-    @CommunalTableLog tableLogBuffer: TableLogBuffer,
 ) : CommunalPrefsRepository {
+    private val logger by lazy { Logger(logBuffer, TAG) }
 
-    private val logger = Logger(logBuffer, "CommunalPrefsRepositoryImpl")
+    override fun isCtaDismissed(user: UserInfo): Flow<Boolean> =
+        readKeyForUser(user, CTA_DISMISSED_STATE)
+
+    override fun isDisclaimerDismissed(user: UserInfo): Flow<Boolean> =
+        readKeyForUser(user, DISCLAIMER_DISMISSED_STATE)
 
     /**
-     * Emits an event each time a Backup & Restore restoration job is completed. Does not emit an
-     * initial value.
+     * Emits an event each time a Backup & Restore restoration job is completed, and once at the
+     * start of collection.
      */
     private val backupRestorationEvents: Flow<Unit> =
-        broadcastDispatcher.broadcastFlow(
-            filter = IntentFilter(BackupHelper.ACTION_RESTORE_FINISHED),
-            flags = Context.RECEIVER_NOT_EXPORTED,
-            permission = BackupHelper.PERMISSION_SELF,
-        )
-
-    override val isCtaDismissed: Flow<Boolean> =
-        combine(
-                userRepository.selectedUserInfo,
-                // Make sure combine can emit even if we never get a Backup & Restore event,
-                // which is the most common case as restoration only happens on initial device
-                // setup.
-                backupRestorationEvents.emitOnStart().onEach {
-                    logger.i("Restored state for communal preferences.")
-                },
-            ) { user, _ ->
-                user
-            }
-            .flatMapLatest(::observeCtaDismissState)
-            .logDiffsForTable(
-                tableLogBuffer = tableLogBuffer,
-                columnPrefix = "",
-                columnName = "isCtaDismissed",
-                initialValue = false,
+        broadcastDispatcher
+            .broadcastFlow(
+                filter = IntentFilter(BackupHelper.ACTION_RESTORE_FINISHED),
+                flags = Context.RECEIVER_NOT_EXPORTED,
+                permission = BackupHelper.PERMISSION_SELF,
             )
-            .stateIn(
-                scope = backgroundScope,
-                started = SharingStarted.WhileSubscribed(),
-                initialValue = false,
-            )
+            .onEach { logger.i("Restored state for communal preferences.") }
+            .emitOnStart()
 
-    override suspend fun setCtaDismissedForCurrentUser() =
+    override suspend fun setCtaDismissed(user: UserInfo) =
         withContext(bgDispatcher) {
-            getSharedPrefsForUser(userRepository.getSelectedUserInfo())
-                .edit()
-                .putBoolean(CTA_DISMISSED_STATE, true)
-                .apply()
-
+            getSharedPrefsForUser(user).edit().putBoolean(CTA_DISMISSED_STATE, true).apply()
             logger.i("Dismissed CTA tile")
         }
 
-    private fun observeCtaDismissState(user: UserInfo): Flow<Boolean> =
-        getSharedPrefsForUser(user)
-            .observe()
-            // Emit at the start of collection to ensure we get an initial value
-            .onStart { emit(Unit) }
-            .map { getCtaDismissedState() }
-            .flowOn(bgDispatcher)
-
-    private suspend fun getCtaDismissedState(): Boolean =
+    override suspend fun setDisclaimerDismissed(user: UserInfo) =
         withContext(bgDispatcher) {
-            getSharedPrefsForUser(userRepository.getSelectedUserInfo())
-                .getBoolean(CTA_DISMISSED_STATE, false)
+            getSharedPrefsForUser(user).edit().putBoolean(DISCLAIMER_DISMISSED_STATE, true).apply()
+            logger.i("Dismissed widget disclaimer")
         }
 
     private fun getSharedPrefsForUser(user: UserInfo): SharedPreferences {
@@ -146,9 +111,19 @@
         )
     }
 
+    private fun readKeyForUser(user: UserInfo, key: String): Flow<Boolean> {
+        return backupRestorationEvents
+            .flatMapLatest {
+                val sharedPrefs = getSharedPrefsForUser(user)
+                sharedPrefs.observe().emitOnStart().map { sharedPrefs.getBoolean(key, false) }
+            }
+            .flowOn(bgDispatcher)
+    }
+
     companion object {
-        const val TAG = "CommunalRepository"
+        const val TAG = "CommunalPrefsRepository"
         const val FILE_NAME = "communal_hub_prefs"
         const val CTA_DISMISSED_STATE = "cta_dismissed"
+        const val DISCLAIMER_DISMISSED_STATE = "disclaimer_dismissed"
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
index 1c47e50..e3ef6bb 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
@@ -24,7 +24,6 @@
 import com.android.systemui.Flags.communalHub
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.communal.data.model.CommunalEnabledState
-import com.android.systemui.communal.data.model.CommunalWidgetCategories
 import com.android.systemui.communal.data.model.DisabledReason
 import com.android.systemui.communal.data.model.DisabledReason.DISABLED_REASON_DEVICE_POLICY
 import com.android.systemui.communal.data.model.DisabledReason.DISABLED_REASON_FLAG
@@ -52,12 +51,6 @@
     /** A [CommunalEnabledState] for the specified user. */
     fun getEnabledState(user: UserInfo): Flow<CommunalEnabledState>
 
-    /**
-     * A flow that reports the widget categories to show on the hub as selected by the user in
-     * Settings.
-     */
-    fun getWidgetCategories(user: UserInfo): Flow<CommunalWidgetCategories>
-
     /** Keyguard widgets enabled state by Device Policy Manager for the specified user. */
     fun getAllowedByDevicePolicy(user: UserInfo): Flow<Boolean>
 
@@ -104,22 +97,6 @@
             .flowOn(bgDispatcher)
     }
 
-    override fun getWidgetCategories(user: UserInfo): Flow<CommunalWidgetCategories> =
-        secureSettings
-            .observerFlow(userId = user.id, names = arrayOf(GLANCEABLE_HUB_CONTENT_SETTING))
-            // Force an update
-            .onStart { emit(Unit) }
-            .map {
-                CommunalWidgetCategories(
-                    secureSettings.getIntForUser(
-                        GLANCEABLE_HUB_CONTENT_SETTING,
-                        CommunalWidgetCategories.defaultCategories,
-                        user.id
-                    )
-                )
-            }
-            .flowOn(bgDispatcher)
-
     override fun getAllowedByDevicePolicy(user: UserInfo): Flow<Boolean> =
         broadcastDispatcher
             .broadcastFlow(
@@ -138,11 +115,11 @@
                 val intType =
                     secureSettings.getIntForUser(
                         GLANCEABLE_HUB_BACKGROUND_SETTING,
-                        CommunalBackgroundType.DEFAULT.value,
+                        CommunalBackgroundType.ANIMATED.value,
                         user.id
                     )
                 CommunalBackgroundType.entries.find { type -> type.value == intType }
-                    ?: CommunalBackgroundType.DEFAULT
+                    ?: CommunalBackgroundType.ANIMATED
             }
 
     private fun getEnabledByUser(user: UserInfo): Flow<Boolean> =
@@ -159,7 +136,6 @@
             }
 
     companion object {
-        const val GLANCEABLE_HUB_CONTENT_SETTING = "glanceable_hub_content_setting"
         const val GLANCEABLE_HUB_BACKGROUND_SETTING = "glanceable_hub_background"
         private const val ENABLED_SETTING_DEFAULT = 1
     }
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
index 00678a8..86f5fe1 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
@@ -20,6 +20,7 @@
 import android.content.ComponentName
 import android.content.Intent
 import android.content.IntentFilter
+import android.content.pm.UserInfo
 import android.os.UserHandle
 import android.os.UserManager
 import android.provider.Settings
@@ -28,7 +29,6 @@
 import com.android.compose.animation.scene.TransitionKey
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.communal.data.repository.CommunalMediaRepository
-import com.android.systemui.communal.data.repository.CommunalPrefsRepository
 import com.android.systemui.communal.data.repository.CommunalWidgetRepository
 import com.android.systemui.communal.domain.model.CommunalContentModel
 import com.android.systemui.communal.domain.model.CommunalContentModel.WidgetContent
@@ -99,7 +99,7 @@
     @Background val bgDispatcher: CoroutineDispatcher,
     broadcastDispatcher: BroadcastDispatcher,
     private val widgetRepository: CommunalWidgetRepository,
-    private val communalPrefsRepository: CommunalPrefsRepository,
+    private val communalPrefsInteractor: CommunalPrefsInteractor,
     private val mediaRepository: CommunalMediaRepository,
     smartspaceRepository: SmartspaceRepository,
     keyguardInteractor: KeyguardInteractor,
@@ -325,7 +325,7 @@
     }
 
     /** Dismiss the CTA tile from the hub in view mode. */
-    suspend fun dismissCtaTile() = communalPrefsRepository.setCtaDismissedForCurrentUser()
+    suspend fun dismissCtaTile() = communalPrefsInteractor.setCtaDismissed()
 
     /** Add a widget at the specified position. */
     fun addWidget(
@@ -387,32 +387,23 @@
         combine(
             widgetRepository.communalWidgets
                 .map { filterWidgetsByExistingUsers(it) }
-                .combine(communalSettingsInteractor.allowedByDevicePolicyForWorkProfile) {
+                .combine(communalSettingsInteractor.workProfileUserDisallowedByDevicePolicy) {
                     // exclude widgets under work profile if not allowed by device policy
                     widgets,
-                    allowedForWorkProfile ->
-                    filterWidgetsAllowedByDevicePolicy(widgets, allowedForWorkProfile)
+                    disallowedByPolicyUser ->
+                    filterWidgetsAllowedByDevicePolicy(widgets, disallowedByPolicyUser)
                 },
-            communalSettingsInteractor.communalWidgetCategories,
             updateOnWorkProfileBroadcastReceived,
-        ) { widgets, allowedCategories, _ ->
+        ) { widgets, _ ->
             widgets.map { widget ->
                 when (widget) {
                     is CommunalWidgetContentModel.Available -> {
-                        if (widget.providerInfo.widgetCategory and allowedCategories != 0) {
-                            // At least one category this widget specified is allowed, so show it
-                            WidgetContent.Widget(
-                                appWidgetId = widget.appWidgetId,
-                                providerInfo = widget.providerInfo,
-                                appWidgetHost = appWidgetHost,
-                                inQuietMode = isQuietModeEnabled(widget.providerInfo.profile)
-                            )
-                        } else {
-                            WidgetContent.DisabledWidget(
-                                appWidgetId = widget.appWidgetId,
-                                providerInfo = widget.providerInfo,
-                            )
-                        }
+                        WidgetContent.Widget(
+                            appWidgetId = widget.appWidgetId,
+                            providerInfo = widget.providerInfo,
+                            appWidgetHost = appWidgetHost,
+                            inQuietMode = isQuietModeEnabled(widget.providerInfo.profile)
+                        )
                     }
                     is CommunalWidgetContentModel.Pending -> {
                         WidgetContent.PendingWidget(
@@ -428,13 +419,11 @@
     /** Filter widgets based on whether their associated profile is allowed by device policy. */
     private fun filterWidgetsAllowedByDevicePolicy(
         list: List<CommunalWidgetContentModel>,
-        allowedByDevicePolicyForWorkProfile: Boolean
+        disallowedByDevicePolicyUser: UserInfo?
     ): List<CommunalWidgetContentModel> =
-        if (allowedByDevicePolicyForWorkProfile) {
+        if (disallowedByDevicePolicyUser == null) {
             list
         } else {
-            // Get associated work profile for the currently selected user.
-            val workProfile = userTracker.userProfiles.find { it.isManagedProfile }
             list.filter { model ->
                 val uid =
                     when (model) {
@@ -442,7 +431,7 @@
                             model.providerInfo.profile.identifier
                         is CommunalWidgetContentModel.Pending -> model.user.identifier
                     }
-                uid != workProfile?.id
+                uid != disallowedByDevicePolicyUser.id
             }
         }
 
@@ -461,7 +450,7 @@
 
     /** CTA tile to be displayed in the glanceable hub (view mode). */
     val ctaTileContent: Flow<List<CommunalContentModel.CtaTileInViewMode>> =
-        communalPrefsRepository.isCtaDismissed.map { isDismissed ->
+        communalPrefsInteractor.isCtaDismissed.map { isDismissed ->
             if (isDismissed) emptyList() else listOf(CommunalContentModel.CtaTileInViewMode())
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalPrefsInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalPrefsInteractor.kt
new file mode 100644
index 0000000..3517650
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalPrefsInteractor.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.communal.domain.interactor
+
+import android.content.pm.UserInfo
+import com.android.app.tracing.coroutines.launch
+import com.android.systemui.communal.data.repository.CommunalPrefsRepository
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.log.dagger.CommunalTableLog
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.log.table.logDiffsForTable
+import com.android.systemui.settings.UserTracker
+import com.android.systemui.user.domain.interactor.SelectedUserInteractor
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.stateIn
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SysUISingleton
+class CommunalPrefsInteractor
+@Inject
+constructor(
+    @Background private val bgScope: CoroutineScope,
+    private val repository: CommunalPrefsRepository,
+    userInteractor: SelectedUserInteractor,
+    private val userTracker: UserTracker,
+    @CommunalTableLog tableLogBuffer: TableLogBuffer
+) {
+
+    val isCtaDismissed: Flow<Boolean> =
+        userInteractor.selectedUserInfo
+            .flatMapLatest { user -> repository.isCtaDismissed(user) }
+            .logDiffsForTable(
+                tableLogBuffer = tableLogBuffer,
+                columnPrefix = "",
+                columnName = "isCtaDismissed",
+                initialValue = false,
+            )
+            .stateIn(
+                scope = bgScope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = false,
+            )
+
+    suspend fun setCtaDismissed(user: UserInfo = userTracker.userInfo) =
+        repository.setCtaDismissed(user)
+
+    val isDisclaimerDismissed: Flow<Boolean> =
+        userInteractor.selectedUserInfo
+            .flatMapLatest { user -> repository.isDisclaimerDismissed(user) }
+            .logDiffsForTable(
+                tableLogBuffer = tableLogBuffer,
+                columnPrefix = "",
+                columnName = "isDisclaimerDismissed",
+                initialValue = false,
+            )
+            .stateIn(
+                scope = bgScope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = false,
+            )
+
+    fun setDisclaimerDismissed(user: UserInfo = userTracker.userInfo) {
+        bgScope.launch("$TAG#setDisclaimerDismissed") { repository.setDisclaimerDismissed(user) }
+    }
+
+    private companion object {
+        const val TAG = "CommunalPrefsInteractor"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
index 20d8a2a..fd540c4 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSceneInteractor.kt
@@ -22,6 +22,7 @@
 import com.android.systemui.communal.data.repository.CommunalSceneRepository
 import com.android.systemui.communal.domain.model.CommunalTransitionProgressModel
 import com.android.systemui.communal.shared.model.CommunalScenes
+import com.android.systemui.communal.shared.model.CommunalTransitionKeys
 import com.android.systemui.communal.shared.model.EditModeState
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
@@ -60,14 +61,14 @@
         communalSceneRepository.snapToScene(newScene, delayMillis)
     }
 
-    /** Immediately snaps to the new scene when activity is started. */
-    fun snapToSceneForActivityStart(newScene: SceneKey, delayMillis: Long = 0) {
+    /** Changes to Blank scene when starting an activity after dismissing keyguard. */
+    fun changeSceneForActivityStartOnDismissKeyguard() {
         // skip if we're starting edit mode activity, as it will be handled later by changeScene
         // with transition key [CommunalTransitionKeys.ToEditMode].
         if (_editModeState.value == EditModeState.STARTING) {
             return
         }
-        snapToScene(newScene, delayMillis)
+        changeScene(CommunalScenes.Blank, CommunalTransitionKeys.SimpleFade)
     }
 
     /**
@@ -144,8 +145,14 @@
      *
      * This flow will be true during any transition and when idle on the communal scene.
      */
-    val isCommunalVisible: Flow<Boolean> =
-        transitionState.map {
-            !(it is ObservableTransitionState.Idle && it.currentScene == CommunalScenes.Blank)
-        }
+    val isCommunalVisible: StateFlow<Boolean> =
+        transitionState
+            .map {
+                !(it is ObservableTransitionState.Idle && it.currentScene == CommunalScenes.Blank)
+            }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = false,
+            )
 }
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt
index f043d58..3b01aec 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt
@@ -19,7 +19,6 @@
 import android.content.pm.UserInfo
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.communal.data.model.CommunalEnabledState
-import com.android.systemui.communal.data.model.CommunalWidgetCategories
 import com.android.systemui.communal.data.repository.CommunalSettingsRepository
 import com.android.systemui.communal.shared.model.CommunalBackgroundType
 import com.android.systemui.dagger.SysUISingleton
@@ -70,18 +69,6 @@
             // Start this eagerly since the value is accessed synchronously in many places.
             .stateIn(scope = bgScope, started = SharingStarted.Eagerly, initialValue = false)
 
-    /** What widget categories to show on the hub. */
-    val communalWidgetCategories: StateFlow<Int> =
-        userInteractor.selectedUserInfo
-            .flatMapLatest { user -> repository.getWidgetCategories(user) }
-            .map { categories -> categories.categories }
-            .stateIn(
-                scope = bgScope,
-                // Start this eagerly since the value can be accessed synchronously.
-                started = SharingStarted.Eagerly,
-                initialValue = CommunalWidgetCategories.defaultCategories
-            )
-
     /** The type of background to use for the hub. Used to experiment with different backgrounds */
     val communalBackground: Flow<CommunalBackgroundType> =
         userInteractor.selectedUserInfo
@@ -105,15 +92,22 @@
         awaitClose { userTracker.removeCallback(callback) }
     }
 
-    /** Whether or not keyguard widgets are allowed for work profile by device policy manager. */
-    val allowedByDevicePolicyForWorkProfile: StateFlow<Boolean> =
+    /**
+     * A user that device policy says shouldn't allow communal widgets, or null if there are no
+     * restrictions.
+     */
+    val workProfileUserDisallowedByDevicePolicy: StateFlow<UserInfo?> =
         workProfileUserInfoCallbackFlow
             .flatMapLatest { workProfile ->
-                workProfile?.let { repository.getAllowedByDevicePolicy(it) } ?: flowOf(false)
+                workProfile?.let {
+                    repository.getAllowedByDevicePolicy(it).map { allowed ->
+                        if (!allowed) it else null
+                    }
+                } ?: flowOf(null)
             }
             .stateIn(
                 scope = bgScope,
                 started = SharingStarted.WhileSubscribed(),
-                initialValue = false
+                initialValue = null
             )
 }
diff --git a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalBackgroundType.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalBackgroundType.kt
index 4eaba06..3b23ba9 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalBackgroundType.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/shared/model/CommunalBackgroundType.kt
@@ -18,7 +18,7 @@
 
 /** Models the types of background that can be shown on the hub. */
 enum class CommunalBackgroundType(val value: Int) {
-    DEFAULT(0),
+    STATIC(0),
     STATIC_GRADIENT(1),
     ANIMATED(2),
     NONE(3),
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
index cc90730..6ec6ec1 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/BaseCommunalViewModel.kt
@@ -129,7 +129,6 @@
 
     /** Called as the UI requests opening the widget editor with an optional preselected widget. */
     open fun onOpenWidgetEditor(
-        preselectedKey: String? = null,
         shouldOpenWidgetPickerOnStart: Boolean = false,
     ) {}
 
@@ -146,7 +145,7 @@
     open fun onReorderWidgetCancel() {}
 
     /** Called as the user request to show the customize widget button. */
-    open fun onShowCustomizeWidgetButton() {}
+    open fun onLongClick() {}
 
     /** Set the key of the currently selected item */
     fun setSelectedKey(key: String?) {
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
index c0c5861..91f4c1c 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalEditModeViewModel.kt
@@ -25,7 +25,9 @@
 import androidx.activity.result.ActivityResultLauncher
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.Flags.enableWidgetPickerSizeFilter
+import com.android.systemui.communal.data.model.CommunalWidgetCategories
 import com.android.systemui.communal.domain.interactor.CommunalInteractor
+import com.android.systemui.communal.domain.interactor.CommunalPrefsInteractor
 import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
 import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
 import com.android.systemui.communal.domain.model.CommunalContentModel
@@ -41,7 +43,9 @@
 import com.android.systemui.media.controls.ui.view.MediaHost
 import com.android.systemui.media.dagger.MediaModule
 import com.android.systemui.res.R
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.util.kotlin.BooleanFlowOperators.allOf
+import com.android.systemui.util.kotlin.BooleanFlowOperators.not
 import javax.inject.Inject
 import javax.inject.Named
 import kotlinx.coroutines.CoroutineDispatcher
@@ -67,6 +71,7 @@
     private val uiEventLogger: UiEventLogger,
     @CommunalLog logBuffer: LogBuffer,
     @Background private val backgroundDispatcher: CoroutineDispatcher,
+    private val communalPrefsInteractor: CommunalPrefsInteractor,
 ) : BaseCommunalViewModel(communalSceneInteractor, communalInteractor, mediaHost) {
 
     private val logger = Logger(logBuffer, "CommunalEditModeViewModel")
@@ -76,13 +81,23 @@
     override val isCommunalContentVisible: Flow<Boolean> =
         communalSceneInteractor.editModeState.map { it == EditModeState.SHOWING }
 
+    val showDisclaimer: Flow<Boolean> =
+        allOf(isCommunalContentVisible, not(communalPrefsInteractor.isDisclaimerDismissed))
+
+    fun onDisclaimerDismissed() {
+        communalPrefsInteractor.setDisclaimerDismissed()
+    }
+
     /**
-     * Emits when edit mode activity can show, after we've transitioned to [KeyguardState.GONE]
-     * and edit mode is open.
+     * Emits when edit mode activity can show, after we've transitioned to [KeyguardState.GONE] and
+     * edit mode is open.
      */
     val canShowEditMode =
         allOf(
-                keyguardTransitionInteractor.isFinishedInState(KeyguardState.GONE),
+                keyguardTransitionInteractor.isFinishedIn(
+                    scene = Scenes.Gone,
+                    stateWithoutSceneContainer = KeyguardState.GONE
+                ),
                 communalInteractor.editModeOpen
             )
             .filter { it }
@@ -173,9 +188,18 @@
             }
             putExtra(
                 AppWidgetManager.EXTRA_CATEGORY_FILTER,
-                communalSettingsInteractor.communalWidgetCategories.value
+                CommunalWidgetCategories.defaultCategories
             )
+
+            communalSettingsInteractor.workProfileUserDisallowedByDevicePolicy.value?.let {
+                putExtra(EXTRA_USER_ID_FILTER, arrayListOf(it.id))
+            }
             putExtra(EXTRA_UI_SURFACE_KEY, EXTRA_UI_SURFACE_VALUE)
+            putExtra(EXTRA_PICKER_TITLE, resources.getString(R.string.communal_widget_picker_title))
+            putExtra(
+                EXTRA_PICKER_DESCRIPTION,
+                resources.getString(R.string.communal_widget_picker_description)
+            )
             putParcelableArrayListExtra(EXTRA_ADDED_APP_WIDGETS_KEY, excludeList)
         }
     }
@@ -203,8 +227,11 @@
 
         private const val EXTRA_DESIRED_WIDGET_WIDTH = "desired_widget_width"
         private const val EXTRA_DESIRED_WIDGET_HEIGHT = "desired_widget_height"
+        private const val EXTRA_PICKER_TITLE = "picker_title"
+        private const val EXTRA_PICKER_DESCRIPTION = "picker_description"
         private const val EXTRA_UI_SURFACE_KEY = "ui_surface"
         private const val EXTRA_UI_SURFACE_VALUE = "widgets_hub"
+        private const val EXTRA_USER_ID_FILTER = "filtered_user_ids"
         const val EXTRA_ADDED_APP_WIDGETS_KEY = "added_app_widgets"
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
index 11247df..780bf70 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
@@ -27,6 +27,7 @@
 import com.android.systemui.communal.shared.model.CommunalBackgroundType
 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 com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -39,7 +40,9 @@
 import com.android.systemui.media.controls.ui.view.MediaHostState
 import com.android.systemui.media.dagger.MediaModule
 import com.android.systemui.res.R
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.statusbar.KeyguardIndicationController
 import com.android.systemui.util.kotlin.BooleanFlowOperators.allOf
 import com.android.systemui.util.kotlin.BooleanFlowOperators.not
 import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
@@ -54,6 +57,8 @@
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
@@ -63,6 +68,7 @@
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.launch
 
 /** The default view model used for showing the communal hub. */
@@ -73,12 +79,14 @@
 constructor(
     @Main val mainDispatcher: CoroutineDispatcher,
     @Application private val scope: CoroutineScope,
+    @Background private val bgScope: CoroutineScope,
     @Main private val resources: Resources,
     keyguardTransitionInteractor: KeyguardTransitionInteractor,
     keyguardInteractor: KeyguardInteractor,
+    private val keyguardIndicationController: KeyguardIndicationController,
     communalSceneInteractor: CommunalSceneInteractor,
     private val communalInteractor: CommunalInteractor,
-    private val communalSettingsInteractor: CommunalSettingsInteractor,
+    communalSettingsInteractor: CommunalSettingsInteractor,
     tutorialInteractor: CommunalTutorialInteractor,
     private val shadeInteractor: ShadeInteractor,
     @Named(MediaModule.COMMUNAL_HUB) mediaHost: MediaHost,
@@ -137,7 +145,10 @@
      */
     override val isCommunalContentFlowFrozen: Flow<Boolean> =
         allOf(
-                keyguardTransitionInteractor.isFinishedInState(KeyguardState.GLANCEABLE_HUB),
+                keyguardTransitionInteractor.isFinishedIn(
+                    scene = Scenes.Communal,
+                    stateWithoutSceneContainer = KeyguardState.GLANCEABLE_HUB
+                ),
                 keyguardInteractor.isKeyguardOccluded,
                 not(keyguardInteractor.isAbleToDream)
             )
@@ -170,7 +181,10 @@
     // opened.
     override val isFocusable: Flow<Boolean> =
         combine(
-                keyguardTransitionInteractor.isFinishedInState(KeyguardState.GLANCEABLE_HUB),
+                keyguardTransitionInteractor.isFinishedIn(
+                    scene = Scenes.Communal,
+                    stateWithoutSceneContainer = KeyguardState.GLANCEABLE_HUB
+                ),
                 communalInteractor.isIdleOnCommunal,
                 shadeInteractor.isAnyFullyExpanded,
             ) { transitionedToGlanceableHub, isIdleOnCommunal, isAnyFullyExpanded ->
@@ -218,9 +232,8 @@
     }
 
     override fun onOpenWidgetEditor(
-        preselectedKey: String?,
         shouldOpenWidgetPickerOnStart: Boolean,
-    ) = communalInteractor.showWidgetEditor(preselectedKey, shouldOpenWidgetPickerOnStart)
+    ) = communalInteractor.showWidgetEditor(selectedKey.value, shouldOpenWidgetPickerOnStart)
 
     override fun onDismissCtaTile() {
         scope.launch {
@@ -229,7 +242,11 @@
         }
     }
 
-    override fun onShowCustomizeWidgetButton() {
+    fun onClick() {
+        keyguardIndicationController.showActionToUnlock()
+    }
+
+    override fun onLongClick() {
         setCurrentPopupType(PopupType.CustomizeWidgetButton)
     }
 
@@ -298,16 +315,12 @@
      *
      * This is needed because the notification shade does not block touches in blank areas and these
      * fall through to the glanceable hub, which we don't want.
+     *
+     * Using a StateFlow as the value does not necessarily change when hub becomes available.
      */
-    val touchesAllowed: Flow<Boolean> = not(shadeInteractor.isAnyFullyExpanded)
-
-    // TODO(b/339667383): remove this temporary swipe gesture handle
-    /**
-     * The dream overlay has its own gesture handle as the SysUI window is not visible above the
-     * dream. This flow will be false when dreaming so that we don't show a duplicate handle when
-     * opening the hub over the dream.
-     */
-    val showGestureIndicator: Flow<Boolean> = not(keyguardInteractor.isDreaming)
+    val touchesAllowed: StateFlow<Boolean> =
+        not(shadeInteractor.isAnyFullyExpanded)
+            .stateIn(bgScope, SharingStarted.Eagerly, initialValue = false)
 
     /** The type of background to use for the hub. */
     val communalBackground: Flow<CommunalBackgroundType> =
@@ -319,7 +332,7 @@
 }
 
 sealed class PopupType {
-    object CtaTile : PopupType()
+    data object CtaTile : PopupType()
 
-    object CustomizeWidgetButton : PopupType()
+    data object CustomizeWidgetButton : PopupType()
 }
diff --git a/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt b/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt
index 1e04fe7..4217744 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/util/CommunalColors.kt
@@ -56,7 +56,7 @@
         Color.valueOf(
             Utils.getColorAttrDefaultColor(
                 context,
-                com.android.internal.R.attr.materialColorOutlineVariant
+                com.android.internal.R.attr.materialColorPrimary
             )
         )
 }
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
index 40df6cec..46f802f 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
@@ -96,7 +96,8 @@
                                 run { Log.w(TAG, "No AppWidgetProviderInfo found in result.") }
                             }
                         }
-                    } ?: run { Log.w(TAG, "No data in result.") }
+                    }
+                        ?: run { Log.w(TAG, "No data in result.") }
                 }
                 else ->
                     Log.w(
@@ -127,7 +128,7 @@
                 Box(
                     modifier =
                         Modifier.fillMaxSize()
-                            .background(LocalAndroidColorScheme.current.outlineVariant),
+                            .background(LocalAndroidColorScheme.current.onSecondaryFixed),
                 ) {
                     CommunalHub(
                         viewModel = communalViewModel,
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivityStarter.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivityStarter.kt
index 76be005..af87f09 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivityStarter.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivityStarter.kt
@@ -22,6 +22,7 @@
 import com.android.systemui.communal.widgets.EditWidgetsActivity.Companion.EXTRA_PRESELECTED_KEY
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.res.R
 import javax.inject.Inject
 
 interface EditWidgetsActivityStarter {
@@ -48,6 +49,7 @@
                 },
             /* onlyProvisioned = */ true,
             /* dismissShade = */ true,
+            applicationContext.resources.getString(R.string.unlock_reason_to_customize_widgets),
         )
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt
index cbc6c97..72f9180 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/WidgetInteractionHandler.kt
@@ -34,10 +34,11 @@
     private val activityStarter: ActivityStarter,
 ) : RemoteViews.InteractionHandler {
 
-    private val delegate = InteractionHandlerDelegate(
-        findViewToAnimate = { view -> view is CommunalAppWidgetHostView },
-        intentStarter = this::startIntent,
-    )
+    private val delegate =
+        InteractionHandlerDelegate(
+            findViewToAnimate = { view -> view is CommunalAppWidgetHostView },
+            intentStarter = this::startIntent,
+        )
 
     override fun onInteraction(
         view: View,
@@ -45,7 +46,6 @@
         response: RemoteViews.RemoteResponse
     ): Boolean = delegate.onInteraction(view, pendingIntent, response)
 
-
     private fun startIntent(
         pendingIntent: PendingIntent,
         fillInIntent: Intent,
@@ -59,6 +59,8 @@
             controller,
             fillInIntent,
             extraOptions.toBundle(),
+            // TODO(b/325110448): UX to provide copy
+            /* customMessage = */ null,
         )
         return true
     }
diff --git a/packages/SystemUI/src/com/android/systemui/complication/DreamHomeControlsComplication.java b/packages/SystemUI/src/com/android/systemui/complication/DreamHomeControlsComplication.java
index 92108e9..afa2375 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/DreamHomeControlsComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/complication/DreamHomeControlsComplication.java
@@ -18,7 +18,6 @@
 
 import static com.android.systemui.complication.dagger.DreamHomeControlsComplicationComponent.DreamHomeControlsModule.DREAM_HOME_CONTROLS_CHIP_VIEW;
 import static com.android.systemui.complication.dagger.RegisteredComplicationsModule.DREAM_HOME_CONTROLS_CHIP_LAYOUT_PARAMS;
-import static com.android.systemui.complication.dagger.RegisteredComplicationsModule.OPEN_HUB_CHIP_REPLACE_HOME_CONTROLS;
 import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE;
 import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK;
 import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.UNAVAILABLE;
@@ -90,7 +89,6 @@
         private final DreamHomeControlsComplication mComplication;
         private final DreamOverlayStateController mDreamOverlayStateController;
         private final ControlsComponent mControlsComponent;
-        private final boolean mReplacedByOpenHub;
 
         private boolean mOverlayActive = false;
 
@@ -118,13 +116,11 @@
         public Registrant(DreamHomeControlsComplication complication,
                 DreamOverlayStateController dreamOverlayStateController,
                 ControlsComponent controlsComponent,
-                @SystemUser Monitor monitor,
-                @Named(OPEN_HUB_CHIP_REPLACE_HOME_CONTROLS) boolean replacedByOpenHub) {
+                @SystemUser Monitor monitor) {
             super(monitor);
             mComplication = complication;
             mControlsComponent = controlsComponent;
             mDreamOverlayStateController = dreamOverlayStateController;
-            mReplacedByOpenHub = replacedByOpenHub;
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/complication/OpenHubComplication.java b/packages/SystemUI/src/com/android/systemui/complication/OpenHubComplication.java
deleted file mode 100644
index 05df2bb..0000000
--- a/packages/SystemUI/src/com/android/systemui/complication/OpenHubComplication.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.complication;
-
-import static com.android.systemui.complication.dagger.OpenHubComplicationComponent.OpenHubModule.OPEN_HUB_CHIP_VIEW;
-import static com.android.systemui.complication.dagger.RegisteredComplicationsModule.OPEN_HUB_CHIP_LAYOUT_PARAMS;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.util.Log;
-import android.view.View;
-import android.widget.ImageView;
-
-import com.android.settingslib.Utils;
-import com.android.systemui.CoreStartable;
-import com.android.systemui.communal.domain.interactor.CommunalInteractor;
-import com.android.systemui.communal.shared.model.CommunalScenes;
-import com.android.systemui.complication.dagger.OpenHubComplicationComponent;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dagger.qualifiers.SystemUser;
-import com.android.systemui.dreams.DreamOverlayStateController;
-import com.android.systemui.shared.condition.Monitor;
-import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.systemui.util.ViewController;
-import com.android.systemui.util.condition.ConditionalCoreStartable;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-
-/**
- * A dream complication that shows a chip to open the glanceable hub.
- */
-// TODO(b/339667383): delete or properly implement this once a product decision is made
-public class OpenHubComplication implements Complication {
-    private final Resources mResources;
-    private final OpenHubComplicationComponent.Factory mComponentFactory;
-
-    @Inject
-    public OpenHubComplication(
-            @Main Resources resources,
-            OpenHubComplicationComponent.Factory componentFactory) {
-        mResources = resources;
-        mComponentFactory = componentFactory;
-    }
-
-    @Override
-    public ViewHolder createView(ComplicationViewModel model) {
-        return mComponentFactory.create(mResources).getViewHolder();
-    }
-
-    @Override
-    public int getRequiredTypeAvailability() {
-        // TODO(b/339667383): create a new complication type if we decide to productionize this
-        return COMPLICATION_TYPE_NONE;
-    }
-
-    /**
-     * {@link CoreStartable} for registering the complication with SystemUI on startup.
-     */
-    public static class Registrant extends ConditionalCoreStartable {
-        private final OpenHubComplication mComplication;
-        private final DreamOverlayStateController mDreamOverlayStateController;
-
-        private boolean mOverlayActive = false;
-
-        private final DreamOverlayStateController.Callback mOverlayStateCallback =
-                new DreamOverlayStateController.Callback() {
-                    @Override
-                    public void onStateChanged() {
-                        if (mOverlayActive == mDreamOverlayStateController.isOverlayActive()) {
-                            return;
-                        }
-
-                        mOverlayActive = !mOverlayActive;
-
-                        if (mOverlayActive) {
-                            updateOpenHubComplication();
-                        }
-                    }
-                };
-
-        @Inject
-        public Registrant(OpenHubComplication complication,
-                DreamOverlayStateController dreamOverlayStateController,
-                @SystemUser Monitor monitor) {
-            super(monitor);
-            mComplication = complication;
-            mDreamOverlayStateController = dreamOverlayStateController;
-        }
-
-        @Override
-        public void onStart() {
-            mDreamOverlayStateController.addCallback(mOverlayStateCallback);
-        }
-
-        private void updateOpenHubComplication() {
-            // TODO(b/339667383): don't show the complication if glanceable hub is disabled
-//            if (Flags.glanceableHubShortcutButton()) {
-//                mDreamOverlayStateController.addComplication(mComplication);
-//            } else {
-//                mDreamOverlayStateController.removeComplication(mComplication);
-//            }
-        }
-    }
-
-    /**
-     * Contains values/logic associated with the dream complication view.
-     */
-    public static class OpenHubChipViewHolder implements ViewHolder {
-        private final ImageView mView;
-        private final ComplicationLayoutParams mLayoutParams;
-        private final OpenHubChipViewController mViewController;
-
-        @Inject
-        OpenHubChipViewHolder(
-                OpenHubChipViewController dreamOpenHubChipViewController,
-                @Named(OPEN_HUB_CHIP_VIEW) ImageView view,
-                @Named(OPEN_HUB_CHIP_LAYOUT_PARAMS) ComplicationLayoutParams layoutParams
-        ) {
-            mView = view;
-            mLayoutParams = layoutParams;
-            mViewController = dreamOpenHubChipViewController;
-            mViewController.init();
-        }
-
-        @Override
-        public ImageView getView() {
-            return mView;
-        }
-
-        @Override
-        public ComplicationLayoutParams getLayoutParams() {
-            return mLayoutParams;
-        }
-    }
-
-    /**
-     * Controls behavior of the dream complication.
-     */
-    static class OpenHubChipViewController extends ViewController<ImageView> {
-        private static final String TAG = "OpenHubCtrl";
-        private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-        private final Context mContext;
-        private final ConfigurationController mConfigurationController;
-
-        private final ConfigurationController.ConfigurationListener mConfigurationListener =
-                new ConfigurationController.ConfigurationListener() {
-                    @Override
-                    public void onUiModeChanged() {
-                        reloadResources();
-                    }
-                };
-        private final CommunalInteractor mCommunalInteractor;
-
-        @Inject
-        OpenHubChipViewController(
-                @Named(OPEN_HUB_CHIP_VIEW) ImageView view,
-                Context context,
-                ConfigurationController configurationController,
-                CommunalInteractor communalInteractor) {
-            super(view);
-
-            mContext = context;
-            mConfigurationController = configurationController;
-            mCommunalInteractor = communalInteractor;
-        }
-
-        @Override
-        protected void onViewAttached() {
-            reloadResources();
-            mView.setOnClickListener(this::onClickOpenHub);
-            mConfigurationController.addCallback(mConfigurationListener);
-        }
-
-        @Override
-        protected void onViewDetached() {
-            mConfigurationController.removeCallback(mConfigurationListener);
-        }
-
-        private void reloadResources() {
-            mView.setImageTintList(Utils.getColorAttr(mContext, android.R.attr.textColorPrimary));
-            final Drawable background = mView.getBackground();
-            if (background != null) {
-                background.setTintList(
-                        Utils.getColorAttr(mContext, com.android.internal.R.attr.colorSurface));
-            }
-        }
-
-        private void onClickOpenHub(View v) {
-            if (DEBUG) Log.d(TAG, "open hub complication tapped");
-
-            mCommunalInteractor.changeScene(CommunalScenes.Communal, null);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/complication/dagger/OpenHubComplicationComponent.java b/packages/SystemUI/src/com/android/systemui/complication/dagger/OpenHubComplicationComponent.java
deleted file mode 100644
index 501601e..0000000
--- a/packages/SystemUI/src/com/android/systemui/complication/dagger/OpenHubComplicationComponent.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.complication.dagger;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.view.LayoutInflater;
-import android.widget.ImageView;
-
-import com.android.systemui.complication.OpenHubComplication;
-import com.android.systemui.res.R;
-import com.android.systemui.shared.shadow.DoubleShadowIconDrawable;
-import com.android.systemui.shared.shadow.DoubleShadowTextHelper;
-
-import dagger.BindsInstance;
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import javax.inject.Named;
-import javax.inject.Scope;
-
-/**
- * Responsible for generating dependencies for the {@link OpenHubComplication}.
- */
-@Subcomponent(modules = OpenHubComplicationComponent.OpenHubModule.class)
-@OpenHubComplicationComponent.OpenHubComplicationScope
-public interface OpenHubComplicationComponent {
-    /**
-     * Creates a view holder for the open hub complication.
-     */
-    OpenHubComplication.OpenHubChipViewHolder getViewHolder();
-
-    /**
-     * Scope of the open hub complication.
-     */
-    @Documented
-    @Retention(RUNTIME)
-    @Scope
-    @interface OpenHubComplicationScope {
-    }
-
-    /**
-     * Factory that generates a {@link OpenHubComplicationComponent}.
-     */
-    @Subcomponent.Factory
-    interface Factory {
-        /**
-         * Creates an instance of {@link OpenHubComplicationComponent}.
-         */
-        OpenHubComplicationComponent create(@BindsInstance Resources resources);
-    }
-
-    /**
-     * Scoped injected values for the {@link OpenHubComplicationComponent}.
-     */
-    @Module
-    interface OpenHubModule {
-        String OPEN_HUB_CHIP_VIEW = "open_hub_chip_view";
-        String OPEN_HUB_BACKGROUND_DRAWABLE = "open_hub_background_drawable";
-
-        /**
-         * Provides the dream open hub chip view.
-         */
-        @Provides
-        @OpenHubComplicationScope
-        @Named(OPEN_HUB_CHIP_VIEW)
-        static ImageView provideOpenHubChipView(
-                LayoutInflater layoutInflater,
-                @Named(OPEN_HUB_BACKGROUND_DRAWABLE) Drawable backgroundDrawable) {
-            final ImageView chip =
-                    (ImageView) layoutInflater.inflate(R.layout.dream_overlay_open_hub_chip,
-                            null, false);
-            chip.setBackground(backgroundDrawable);
-
-            return chip;
-        }
-
-        /**
-         * Provides the background drawable for the open hub chip.
-         */
-        @Provides
-        @OpenHubComplicationScope
-        @Named(OPEN_HUB_BACKGROUND_DRAWABLE)
-        static Drawable providesOpenHubBackground(Context context, Resources resources) {
-            return new DoubleShadowIconDrawable(createShadowInfo(
-                    resources,
-                    R.dimen.dream_overlay_bottom_affordance_key_text_shadow_radius,
-                    R.dimen.dream_overlay_bottom_affordance_key_text_shadow_dx,
-                    R.dimen.dream_overlay_bottom_affordance_key_text_shadow_dy,
-                    R.dimen.dream_overlay_bottom_affordance_key_shadow_alpha
-            ),
-                    createShadowInfo(
-                            resources,
-                            R.dimen.dream_overlay_bottom_affordance_ambient_text_shadow_radius,
-                            R.dimen.dream_overlay_bottom_affordance_ambient_text_shadow_dx,
-                            R.dimen.dream_overlay_bottom_affordance_ambient_text_shadow_dy,
-                            R.dimen.dream_overlay_bottom_affordance_ambient_shadow_alpha
-                    ),
-                    resources.getDrawable(R.drawable.dream_overlay_bottom_affordance_bg),
-                    resources.getDimensionPixelOffset(
-                            R.dimen.dream_overlay_bottom_affordance_width),
-                    resources.getDimensionPixelSize(R.dimen.dream_overlay_bottom_affordance_inset)
-            );
-        }
-
-        private static DoubleShadowTextHelper.ShadowInfo createShadowInfo(Resources resources,
-                int blurId, int offsetXId, int offsetYId, int alphaId) {
-
-            return new DoubleShadowTextHelper.ShadowInfo(
-                    resources.getDimension(blurId),
-                    resources.getDimension(offsetXId),
-                    resources.getDimension(offsetYId),
-                    resources.getFloat(alphaId)
-            );
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/complication/dagger/RegisteredComplicationsModule.java b/packages/SystemUI/src/com/android/systemui/complication/dagger/RegisteredComplicationsModule.java
index edb5ff7..6f1b098 100644
--- a/packages/SystemUI/src/com/android/systemui/complication/dagger/RegisteredComplicationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/complication/dagger/RegisteredComplicationsModule.java
@@ -25,7 +25,6 @@
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.res.R;
-import com.android.systemui.util.settings.SystemSettings;
 
 import dagger.Module;
 import dagger.Provides;
@@ -40,7 +39,6 @@
         subcomponents = {
                 DreamClockTimeComplicationComponent.class,
                 DreamHomeControlsComplicationComponent.class,
-                OpenHubComplicationComponent.class,
                 DreamMediaEntryComplicationComponent.class
         })
 public interface RegisteredComplicationsModule {
@@ -48,8 +46,6 @@
     String DREAM_SMARTSPACE_LAYOUT_PARAMS = "smartspace_layout_params";
     String DREAM_HOME_CONTROLS_CHIP_LAYOUT_PARAMS = "home_controls_chip_layout_params";
     String DREAM_MEDIA_ENTRY_LAYOUT_PARAMS = "media_entry_layout_params";
-    String OPEN_HUB_CHIP_LAYOUT_PARAMS = "open_hub_chip_layout_params";
-    String OPEN_HUB_CHIP_REPLACE_HOME_CONTROLS = "open_hub_chip_replace_home_controls";
 
     int DREAM_CLOCK_TIME_COMPLICATION_WEIGHT = 1;
     int DREAM_CLOCK_TIME_COMPLICATION_WEIGHT_NO_SMARTSPACE = 2;
@@ -113,26 +109,6 @@
     }
 
     /**
-     * Provides layout parameters for the open hub complication.
-     */
-    @Provides
-    @Named(OPEN_HUB_CHIP_LAYOUT_PARAMS)
-    static ComplicationLayoutParams provideOpenHubLayoutParams(
-            @Named(OPEN_HUB_CHIP_REPLACE_HOME_CONTROLS) boolean replaceHomeControls) {
-        int position = ComplicationLayoutParams.POSITION_BOTTOM | (replaceHomeControls
-                ? ComplicationLayoutParams.POSITION_START
-                : ComplicationLayoutParams.POSITION_END);
-        int direction = replaceHomeControls ? ComplicationLayoutParams.DIRECTION_END
-                : ComplicationLayoutParams.DIRECTION_START;
-        return new ComplicationLayoutParams(
-                ViewGroup.LayoutParams.WRAP_CONTENT,
-                ViewGroup.LayoutParams.WRAP_CONTENT,
-                position,
-                direction,
-                DREAM_HOME_CONTROLS_CHIP_COMPLICATION_WEIGHT);
-    }
-
-    /**
      * Provides layout parameters for the smartspace complication.
      */
     @Provides
@@ -148,14 +124,4 @@
                 res.getDimensionPixelSize(R.dimen.dream_overlay_complication_smartspace_padding),
                 res.getDimensionPixelSize(R.dimen.dream_overlay_complication_smartspace_max_width));
     }
-
-    /**
-     * If true, the home controls chip should not be shown and the open hub chip should be shown in
-     * its place.
-     */
-    @Provides
-    @Named(OPEN_HUB_CHIP_REPLACE_HOME_CONTROLS)
-    static boolean providesOpenHubChipReplaceHomeControls(SystemSettings systemSettings) {
-        return systemSettings.getBool(OPEN_HUB_CHIP_REPLACE_HOME_CONTROLS, false);
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
index 9f0fc51..9ae63a1 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
@@ -25,7 +25,9 @@
 import com.android.keyguard.KeyguardViewController;
 import com.android.systemui.CoreStartable;
 import com.android.systemui.ScreenDecorationsModule;
+import com.android.systemui.accessibility.AccessibilityModule;
 import com.android.systemui.accessibility.SystemActionsModule;
+import com.android.systemui.accessibility.data.repository.AccessibilityRepositoryModule;
 import com.android.systemui.battery.BatterySaverModule;
 import com.android.systemui.display.ui.viewmodel.ConnectingDisplayViewModel;
 import com.android.systemui.dock.DockManager;
@@ -107,6 +109,8 @@
  * SystemUI code that variants of SystemUI _must_ include to function correctly.
  */
 @Module(includes = {
+        AccessibilityModule.class,
+        AccessibilityRepositoryModule.class,
         AospPolicyModule.class,
         BatterySaverModule.class,
         CollapsedStatusBarFragmentStartableModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index a7ff3c3..1771f4d 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -32,8 +32,6 @@
 import com.android.systemui.CameraProtectionModule;
 import com.android.systemui.CoreStartable;
 import com.android.systemui.SystemUISecondaryUserService;
-import com.android.systemui.accessibility.AccessibilityModule;
-import com.android.systemui.accessibility.data.repository.AccessibilityRepositoryModule;
 import com.android.systemui.ambient.dagger.AmbientModule;
 import com.android.systemui.appops.dagger.AppOpsModule;
 import com.android.systemui.assist.AssistModule;
@@ -63,6 +61,7 @@
 import com.android.systemui.doze.dagger.DozeComponent;
 import com.android.systemui.dreams.dagger.DreamModule;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.education.dagger.ContextualEducationModule;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.FlagDependenciesModule;
 import com.android.systemui.flags.FlagsModule;
@@ -76,6 +75,7 @@
 import com.android.systemui.mediaprojection.MediaProjectionModule;
 import com.android.systemui.mediaprojection.appselector.MediaProjectionActivitiesModule;
 import com.android.systemui.mediaprojection.taskswitcher.MediaProjectionTaskSwitcherModule;
+import com.android.systemui.mediarouter.MediaRouterModule;
 import com.android.systemui.model.SceneContainerPlugin;
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.motiontool.MotionToolModule;
@@ -111,6 +111,7 @@
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
+import com.android.systemui.statusbar.chips.StatusBarChipsModule;
 import com.android.systemui.statusbar.connectivity.ConnectivityModule;
 import com.android.systemui.statusbar.dagger.StatusBarModule;
 import com.android.systemui.statusbar.disableflags.dagger.DisableFlagsModule;
@@ -187,8 +188,6 @@
  * may not appreciate that.
  */
 @Module(includes = {
-        AccessibilityModule.class,
-        AccessibilityRepositoryModule.class,
         AmbientModule.class,
         AppOpsModule.class,
         AssistModule.class,
@@ -224,6 +223,7 @@
         MediaProjectionActivitiesModule.class,
         MediaProjectionModule.class,
         MediaProjectionTaskSwitcherModule.class,
+        MediaRouterModule.class,
         MotionToolModule.class,
         NotificationIconAreaControllerModule.class,
         PeopleHubModule.class,
@@ -246,6 +246,7 @@
         SmartspaceModule.class,
         StatusBarEventsModule.class,
         StatusBarModule.class,
+        StatusBarChipsModule.class,
         StatusBarPipelineModule.class,
         StatusBarPolicyModule.class,
         StatusBarViewBinderModule.class,
@@ -261,7 +262,8 @@
         UserModule.class,
         UtilModule.class,
         NoteTaskModule.class,
-        WalletModule.class
+        WalletModule.class,
+        ContextualEducationModule.class
         },
         subcomponents = {
             ComplicationComponent.class,
diff --git a/packages/SystemUI/src/com/android/systemui/deviceconfig/data/repository/DeviceConfigRepository.kt b/packages/SystemUI/src/com/android/systemui/deviceconfig/data/repository/DeviceConfigRepository.kt
new file mode 100644
index 0000000..250b432
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/deviceconfig/data/repository/DeviceConfigRepository.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.deviceconfig.data.repository
+
+import android.provider.DeviceConfig
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.util.DeviceConfigProxy
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
+import java.util.concurrent.Executor
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOn
+
+@SysUISingleton
+class DeviceConfigRepository
+@Inject
+constructor(
+    @Background private val backgroundExecutor: Executor,
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
+    private val dataSource: DeviceConfigProxy,
+) {
+
+    fun property(namespace: String, name: String, default: Boolean): Flow<Boolean> {
+        return conflatedCallbackFlow {
+                val listener = { properties: DeviceConfig.Properties ->
+                    if (properties.keyset.contains(name)) {
+                        trySend(properties.getBoolean(name, default))
+                    }
+                }
+
+                dataSource.addOnPropertiesChangedListener(
+                    namespace,
+                    backgroundExecutor,
+                    listener,
+                )
+                trySend(dataSource.getBoolean(namespace, name, default))
+
+                awaitClose { dataSource.removeOnPropertiesChangedListener(listener) }
+            }
+            .flowOn(backgroundDispatcher)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/deviceconfig/domain/interactor/DeviceConfigInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceconfig/domain/interactor/DeviceConfigInteractor.kt
new file mode 100644
index 0000000..d04f8bc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/deviceconfig/domain/interactor/DeviceConfigInteractor.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.deviceconfig.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.deviceconfig.data.repository.DeviceConfigRepository
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class DeviceConfigInteractor
+@Inject
+constructor(
+    private val repository: DeviceConfigRepository,
+) {
+
+    fun property(namespace: String, name: String, default: Boolean): Flow<Boolean> {
+        return repository.property(namespace, name, default)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt
index 813fccf..fa52dad 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryFaceAuthRepository.kt
@@ -58,6 +58,7 @@
 import com.android.systemui.log.table.TableLogBuffer
 import com.android.systemui.power.domain.interactor.PowerInteractor
 import com.android.systemui.res.R
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.user.data.model.SelectionStatus
 import com.android.systemui.user.data.repository.UserRepository
@@ -221,8 +222,7 @@
                 trySendWithFailureLogging(it.bypassEnabled, TAG, "BypassStateChanged")
                 awaitClose { it.unregisterOnBypassStateChangedListener(callback) }
             }
-        }
-            ?: flowOf(false)
+        } ?: flowOf(false)
 
     override fun setLockedOut(isLockedOut: Boolean) {
         _isLockedOut.value = isLockedOut
@@ -303,7 +303,10 @@
 
     private fun listenForSchedulingWatchdog() {
         keyguardTransitionInteractor
-            .transition(Edge.create(to = KeyguardState.GONE))
+            .transition(
+                edge = Edge.create(to = Scenes.Gone),
+                edgeWithoutSceneContainer = Edge.create(to = KeyguardState.GONE),
+            )
             .filter { it.transitionState == TransitionState.FINISHED }
             .onEach {
                 // We deliberately want to run this in background because scheduleWatchdog does
@@ -322,7 +325,10 @@
         merge(
                 powerInteractor.isAsleep,
                 combine(
-                    keyguardTransitionInteractor.isFinishedInState(KeyguardState.GONE),
+                    keyguardTransitionInteractor.isFinishedIn(
+                        scene = Scenes.Gone,
+                        stateWithoutSceneContainer = KeyguardState.GONE,
+                    ),
                     keyguardInteractor.statusBarState,
                 ) { isFinishedInGoneState, statusBarState ->
                     // When the user is dragging the primary bouncer in (up) by manually scrolling
@@ -394,7 +400,7 @@
             Pair(keyguardRepository.isKeyguardGoingAway.isFalse(), "keyguardNotGoingAway"),
             Pair(
                 keyguardTransitionInteractor
-                    .isInTransitionToStateWhere(KeyguardState::deviceIsAsleepInState)
+                    .isInTransitionWhere(toStatePredicate = KeyguardState::deviceIsAsleepInState)
                     .isFalse(),
                 "deviceNotTransitioningToAsleepState"
             ),
@@ -733,6 +739,7 @@
         pw.println("  lockscreenBypassEnabled: ${keyguardBypassController?.bypassEnabled ?: false}")
     }
 }
+
 /** Combine two boolean flows by and-ing both of them */
 private fun and(flow: Flow<Boolean>, anotherFlow: Flow<Boolean>) =
     flow.combine(anotherFlow) { a, b -> a && b }
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt
index f779ac8..0f18978 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt
@@ -39,6 +39,12 @@
      * the lockscreen.
      */
     val isBypassEnabled: StateFlow<Boolean>
+
+    /**
+     * Reports, to system server, that the user is "present" now. This is a signal that system
+     * server uses to know that the device has been entered.
+     */
+    suspend fun reportUserPresent()
 }
 
 /** Encapsulates application state for device entry. */
@@ -79,6 +85,13 @@
                 initialValue = keyguardBypassController.bypassEnabled,
             )
 
+    override suspend fun reportUserPresent() {
+        withContext(backgroundDispatcher) {
+            val selectedUserId = userRepository.selectedUser.value.userInfo.id
+            lockPatternUtils.userPresent(selectedUserId)
+        }
+    }
+
     companion object {
         private const val TAG = "DeviceEntryRepositoryImpl"
     }
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
index 10d6881..425bb96 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
@@ -42,6 +42,7 @@
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.launch
 
@@ -108,6 +109,11 @@
                     false
                 }
             }
+            .onEach { isDeviceEntered ->
+                if (isDeviceEntered) {
+                    repository.reportUserPresent()
+                }
+            }
             .stateIn(
                 scope = applicationScope,
                 started = SharingStarted.Eagerly,
@@ -211,6 +217,9 @@
             }
         }
 
+    /** Whether the device is in lockdown mode, where bouncer input is required to unlock. */
+    val isInLockdown: Flow<Boolean> = deviceEntryRestrictionReason.map { it.isInLockdown() }
+
     /**
      * Attempt to enter the device and dismiss the lockscreen. If authentication is required to
      * unlock the device it will transition to bouncer.
@@ -259,6 +268,27 @@
         return repository.isLockscreenEnabled()
     }
 
+    fun DeviceEntryRestrictionReason?.isInLockdown(): Boolean {
+        return when (this) {
+            DeviceEntryRestrictionReason.UserLockdown -> true
+            DeviceEntryRestrictionReason.PolicyLockdown -> true
+
+            // Add individual enum value instead of using "else" so new reasons are guaranteed
+            // to be added here at compile-time.
+            null -> false
+            DeviceEntryRestrictionReason.DeviceNotUnlockedSinceReboot -> false
+            DeviceEntryRestrictionReason.BouncerLockedOut -> false
+            DeviceEntryRestrictionReason.AdaptiveAuthRequest -> false
+            DeviceEntryRestrictionReason.NonStrongBiometricsSecurityTimeout -> false
+            DeviceEntryRestrictionReason.TrustAgentDisabled -> false
+            DeviceEntryRestrictionReason.StrongBiometricsLockedOut -> false
+            DeviceEntryRestrictionReason.SecurityTimeout -> false
+            DeviceEntryRestrictionReason.DeviceNotUnlockedSinceMainlineUpdate -> false
+            DeviceEntryRestrictionReason.UnattendedUpdate -> false
+            DeviceEntryRestrictionReason.NonStrongFaceLockedOut -> false
+        }
+    }
+
     /**
      * Whether lockscreen bypass is enabled. When enabled, the lockscreen will be automatically
      * dismissed once the authentication challenge is completed. For example, completing a biometric
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
index 9d6c2bf..0bcfa96 100644
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
@@ -47,7 +47,6 @@
 import kotlinx.coroutines.flow.filterIsInstance
 import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.flow.scan
 import kotlinx.coroutines.flow.shareIn
@@ -155,10 +154,11 @@
                             is DisplayEvent.Changed -> previousIds + id
                         }
                     }
-                    .shareIn(
+                    .distinctUntilChanged()
+                    .stateIn(
                         bgApplicationScope,
-                        started = SharingStarted.WhileSubscribed(),
-                        replay = 1
+                        SharingStarted.WhileSubscribed(),
+                        emptySet(),
                     )
             } else {
                 oldEnabledDisplays.map { enabledDisplaysSet ->
@@ -177,7 +177,16 @@
             enabledDisplayIds
                 .mapElementsLazily { displayId -> getDisplay(displayId) }
                 .flowOn(backgroundCoroutineDispatcher)
-                .debugLog("enabledDisplayIds")
+                .debugLog("enabledDisplays")
+                .stateIn(
+                    bgApplicationScope,
+                    started = SharingStarted.WhileSubscribed(),
+                    initialValue =
+                        setOf(
+                            getDisplay(Display.DEFAULT_DISPLAY)
+                                ?: error("Unable to get default display.")
+                        )
+                )
         } else {
             oldEnabledDisplays
         }
@@ -355,20 +364,31 @@
      * [createValue] returns a null element, it will not be added in the output set.
      */
     private fun <T, V> Flow<Set<T>>.mapElementsLazily(createValue: (T) -> V?): Flow<Set<V>> {
-        var initialSet = emptySet<T>()
-        val currentMap = mutableMapOf<T, V>()
-        var resultSet = emptySet<V>()
-        return onEach { currentSet ->
-                val removed = initialSet - currentSet
-                val added = currentSet - initialSet
-                if (added.isNotEmpty() || removed.isNotEmpty()) {
-                    added.forEach { key: T -> createValue(key)?.let { currentMap[key] = it } }
-                    removed.forEach { key: T -> currentMap.remove(key) }
-                    resultSet = currentMap.values.toSet() // Creates a **copy** of values
+        data class State<T, V>(
+            val previousSet: Set<T>,
+            // Caches T values from the previousSet that were already converted to V
+            val valueMap: Map<T, V>,
+            val resultSet: Set<V>
+        )
+
+        val initialState = State(emptySet<T>(), emptyMap(), emptySet<V>())
+
+        return this.scan(initialState) { state, currentSet ->
+                if (currentSet == state.previousSet) {
+                    state
+                } else {
+                    val removed = state.previousSet - currentSet
+                    val added = currentSet - state.previousSet
+                    val newMap = state.valueMap.toMutableMap()
+
+                    added.forEach { key -> createValue(key)?.let { newMap[key] = it } }
+                    removed.forEach { key -> newMap.remove(key) }
+
+                    val resultSet = newMap.values.toSet()
+                    State(currentSet, newMap, resultSet)
                 }
-                initialSet = currentSet
             }
-            .map { resultSet }
+            .map { it.resultSet }
     }
 
     private companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractor.kt b/packages/SystemUI/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractor.kt
index 73b7a8a..e4b290d 100644
--- a/packages/SystemUI/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractor.kt
@@ -85,7 +85,7 @@
 class ConnectedDisplayInteractorImpl
 @Inject
 constructor(
-    private val virtualDeviceManager: VirtualDeviceManager,
+    private val virtualDeviceManager: VirtualDeviceManager?,
     keyguardRepository: KeyguardRepository,
     displayRepository: DisplayRepository,
     deviceStateRepository: DeviceStateRepository,
@@ -156,6 +156,7 @@
 
     private fun isVirtualDeviceOwnedMirrorDisplay(display: Display): Boolean {
         return Flags.interactiveScreenMirror() &&
+            virtualDeviceManager != null &&
             virtualDeviceManager.isVirtualDeviceOwnedMirrorDisplay(display.displayId)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index 8776ec5..17b455d 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -18,6 +18,8 @@
 
 import android.annotation.NonNull;
 
+import androidx.annotation.MainThread;
+
 /**
  * Interface the doze service uses to communicate with the rest of system UI.
  */
@@ -27,6 +29,7 @@
     void startDozing();
     void pulseWhileDozing(@NonNull PulseCallback callback, int reason);
     void stopDozing();
+    @MainThread
     void dozeTimeTick();
     boolean isPowerSaveActive();
     boolean isPulsingBlocked();
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 1a06418..9def81a 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -27,6 +27,8 @@
 import android.text.format.Formatter;
 import android.util.Log;
 
+import androidx.annotation.AnyThread;
+
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.doze.dagger.DozeScope;
@@ -55,7 +57,7 @@
     private final DozeParameters mDozeParameters;
     private final DozeLog mDozeLog;
     private final DelayableExecutor mBgExecutor;
-    private long mLastTimeTickElapsed = 0;
+    private volatile long mLastTimeTickElapsed = 0;
     // If time tick is scheduled and there's not a pending runnable to cancel:
     private volatile boolean mTimeTickScheduled;
     private final Runnable mCancelTimeTickerRunnable =  new Runnable() {
@@ -218,10 +220,15 @@
         return calendar.getTimeInMillis();
     }
 
+    @AnyThread
     private void onTimeTick() {
         verifyLastTimeTick();
 
-        mHost.dozeTimeTick();
+        if (dozeuiSchedulingAlarmsBackgroundExecution()) {
+            mHandler.post(mHost::dozeTimeTick);
+        } else {
+            mHost.dozeTimeTick();
+        }
 
         // Keep wakelock until a frame has been pushed.
         mHandler.post(mWakeLock.wrap(() -> {}));
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
index 245def8..76c7d23 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
@@ -21,8 +21,6 @@
 import static com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerProgress;
 import static com.android.keyguard.BouncerPanelExpansionCalculator.getDreamAlphaScaledExpansion;
 import static com.android.keyguard.BouncerPanelExpansionCalculator.getDreamYPositionScaledExpansion;
-import static com.android.systemui.Flags.communalHub;
-import static com.android.systemui.Flags.glanceableHubGestureHandle;
 import static com.android.systemui.complication.ComplicationLayoutParams.POSITION_BOTTOM;
 import static com.android.systemui.complication.ComplicationLayoutParams.POSITION_TOP;
 import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
@@ -53,6 +51,7 @@
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
 import com.android.systemui.keyguard.shared.model.KeyguardState;
 import com.android.systemui.res.R;
+import com.android.systemui.scene.shared.model.Scenes;
 import com.android.systemui.shade.ShadeExpansionChangeEvent;
 import com.android.systemui.shade.domain.interactor.ShadeInteractor;
 import com.android.systemui.statusbar.BlurUtils;
@@ -191,7 +190,6 @@
             DreamOverlayContainerView containerView,
             ComplicationHostViewController complicationHostViewController,
             @Named(DreamOverlayModule.DREAM_OVERLAY_CONTENT_VIEW) ViewGroup contentView,
-            @Named(DreamOverlayModule.HUB_GESTURE_INDICATOR_VIEW) View hubGestureIndicatorView,
             AmbientStatusBarViewController statusBarViewController,
             LowLightTransitionCoordinator lowLightTransitionCoordinator,
             TouchInsetManager.TouchInsetSession touchInsetSession,
@@ -229,12 +227,6 @@
         mComplicationHostViewController = complicationHostViewController;
         mDreamOverlayMaxTranslationY = resources.getDimensionPixelSize(
                 R.dimen.dream_overlay_y_offset);
-
-        if (communalHub() && glanceableHubGestureHandle()) {
-            // TODO(b/339667383): remove this temporary swipe gesture handle
-            hubGestureIndicatorView.setVisibility(View.VISIBLE);
-        }
-
         final View view = mComplicationHostViewController.getView();
 
         mDreamOverlayContentView.addView(view,
@@ -274,13 +266,19 @@
             collectFlow(
                     mView,
                     FlowKt.distinctUntilChanged(combineFlows(
-                            mKeyguardTransitionInteractor.isFinishedInStateWhere(
-                                    KeyguardState::isBouncerState),
+                            mKeyguardTransitionInteractor.isFinishedIn(
+                                    Scenes.Bouncer, KeyguardState.PRIMARY_BOUNCER),
+                            mKeyguardTransitionInteractor.isFinishedIn(
+                                    KeyguardState.ALTERNATE_BOUNCER),
                             mShadeInteractor.isAnyExpanded(),
                             mCommunalInteractor.isCommunalShowing(),
-                            (anyBouncerShowing, shadeExpanded, communalShowing) -> {
-                                mAnyBouncerShowing = anyBouncerShowing;
-                                return anyBouncerShowing || shadeExpanded || communalShowing;
+                            (primaryBouncerShowing,
+                                    alternateBouncerShowing,
+                                    shadeExpanded,
+                                    communalShowing) -> {
+                                mAnyBouncerShowing = primaryBouncerShowing
+                                        || alternateBouncerShowing;
+                                return mAnyBouncerShowing || shadeExpanded || communalShowing;
                             })),
                     mDreamManager::setDreamIsObscured,
                     mBackgroundDispatcher);
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
index 76fcabd..12984efb 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
@@ -18,7 +18,6 @@
 
 import android.content.res.Resources;
 import android.view.LayoutInflater;
-import android.view.View;
 import android.view.ViewGroup;
 
 import androidx.lifecycle.Lifecycle;
@@ -42,7 +41,6 @@
 @Module
 public abstract class DreamOverlayModule {
     public static final String DREAM_OVERLAY_CONTENT_VIEW = "dream_overlay_content_view";
-    public static final String HUB_GESTURE_INDICATOR_VIEW = "hub_gesture_indicator_view";
     public static final String MAX_BURN_IN_OFFSET = "max_burn_in_offset";
     public static final String BURN_IN_PROTECTION_UPDATE_INTERVAL =
             "burn_in_protection_update_interval";
@@ -75,18 +73,6 @@
                 "R.id.dream_overlay_content must not be null");
     }
 
-    /**
-     * Gesture indicator bar on the right edge of the screen to indicate to users that they can
-     * swipe to see their widgets on lock screen.
-     */
-    @Provides
-    @DreamOverlayComponent.DreamOverlayScope
-    @Named(HUB_GESTURE_INDICATOR_VIEW)
-    public static View providesHubGestureIndicatorView(DreamOverlayContainerView view) {
-        return Preconditions.checkNotNull(view.findViewById(R.id.glanceable_hub_handle),
-                "R.id.glanceable_hub_handle must not be null");
-    }
-
     /** */
     @Provides
     public static TouchInsetManager.TouchInsetSession providesTouchInsetSession(
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/homecontrols/TaskFragmentComponent.kt b/packages/SystemUI/src/com/android/systemui/dreams/homecontrols/TaskFragmentComponent.kt
index 297ad84..befd822 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/homecontrols/TaskFragmentComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/dreams/homecontrols/TaskFragmentComponent.kt
@@ -161,5 +161,6 @@
             TASK_FRAGMENT_TRANSIT_CLOSE,
             false
         )
+        organizer.unregisterOrganizer()
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/education/dagger/ContextualEducationModule.kt b/packages/SystemUI/src/com/android/systemui/education/dagger/ContextualEducationModule.kt
new file mode 100644
index 0000000..e2bcb6b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/education/dagger/ContextualEducationModule.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.education.dagger
+
+import com.android.systemui.dagger.qualifiers.Background
+import dagger.Module
+import dagger.Provides
+import javax.inject.Qualifier
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.SupervisorJob
+
+@Module
+interface ContextualEducationModule {
+    @Qualifier annotation class EduDataStoreScope
+
+    companion object {
+        @EduDataStoreScope
+        @Provides
+        fun provideEduDataStoreScope(
+            @Background bgDispatcher: CoroutineDispatcher
+        ): CoroutineScope {
+            return CoroutineScope(bgDispatcher + SupervisorJob())
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/education/data/model/GestureEduModel.kt b/packages/SystemUI/src/com/android/systemui/education/data/model/GestureEduModel.kt
new file mode 100644
index 0000000..af35e8c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/education/data/model/GestureEduModel.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.education.data.model
+
+/**
+ * Model to store education data related to each gesture (e.g. Back, Home, All Apps, Overview). Each
+ * gesture stores its own model separately.
+ */
+data class GestureEduModel(
+    val signalCount: Int,
+    val educationShownCount: Int,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/education/data/repository/ContextualEducationRepository.kt b/packages/SystemUI/src/com/android/systemui/education/data/repository/ContextualEducationRepository.kt
new file mode 100644
index 0000000..c9dd833
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/education/data/repository/ContextualEducationRepository.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.education.data.repository
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.shared.education.GestureType
+import javax.inject.Inject
+
+/**
+ * Provide methods to read and update on field level and allow setting datastore when user is
+ * changed
+ */
+@SysUISingleton
+class ContextualEducationRepository
+@Inject
+constructor(private val userEduRepository: UserContextualEducationRepository) {
+    /** To change data store when user is changed */
+    fun setUser(userId: Int) = userEduRepository.setUser(userId)
+
+    fun readGestureEduModelFlow(gestureType: GestureType) =
+        userEduRepository.readGestureEduModelFlow(gestureType)
+
+    suspend fun incrementSignalCount(gestureType: GestureType) {
+        userEduRepository.updateGestureEduModel(gestureType) {
+            it.copy(signalCount = it.signalCount + 1)
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/education/data/repository/UserContextualEducationRepository.kt b/packages/SystemUI/src/com/android/systemui/education/data/repository/UserContextualEducationRepository.kt
new file mode 100644
index 0000000..229511a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/education/data/repository/UserContextualEducationRepository.kt
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.education.data.repository
+
+import android.content.Context
+import androidx.datastore.core.DataStore
+import androidx.datastore.preferences.core.PreferenceDataStoreFactory
+import androidx.datastore.preferences.core.Preferences
+import androidx.datastore.preferences.core.edit
+import androidx.datastore.preferences.core.intPreferencesKey
+import androidx.datastore.preferences.preferencesDataStoreFile
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.education.dagger.ContextualEducationModule.EduDataStoreScope
+import com.android.systemui.education.data.model.GestureEduModel
+import com.android.systemui.shared.education.GestureType
+import javax.inject.Inject
+import javax.inject.Provider
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.map
+
+/**
+ * A contextual education repository to:
+ * 1) store education data per user
+ * 2) provide methods to read and update data on model-level
+ * 3) provide method to enable changing datastore when user is changed
+ */
+@SysUISingleton
+class UserContextualEducationRepository
+@Inject
+constructor(
+    @Application private val applicationContext: Context,
+    @EduDataStoreScope private val dataStoreScopeProvider: Provider<CoroutineScope>
+) {
+    companion object {
+        const val SIGNAL_COUNT_SUFFIX = "_SIGNAL_COUNT"
+        const val NUMBER_OF_EDU_SHOWN_SUFFIX = "_NUMBER_OF_EDU_SHOWN"
+
+        const val DATASTORE_DIR = "education/USER%s_ContextualEducation"
+    }
+
+    private var dataStoreScope: CoroutineScope? = null
+
+    private val datastore = MutableStateFlow<DataStore<Preferences>?>(null)
+
+    @OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class)
+    private val prefData: Flow<Preferences> = datastore.filterNotNull().flatMapLatest { it.data }
+
+    internal fun setUser(userId: Int) {
+        dataStoreScope?.cancel()
+        val newDsScope = dataStoreScopeProvider.get()
+        datastore.value =
+            PreferenceDataStoreFactory.create(
+                produceFile = {
+                    applicationContext.preferencesDataStoreFile(
+                        String.format(DATASTORE_DIR, userId)
+                    )
+                },
+                scope = newDsScope,
+            )
+        dataStoreScope = newDsScope
+    }
+
+    internal fun readGestureEduModelFlow(gestureType: GestureType): Flow<GestureEduModel> =
+        prefData.map { preferences -> getGestureEduModel(gestureType, preferences) }
+
+    private fun getGestureEduModel(
+        gestureType: GestureType,
+        preferences: Preferences
+    ): GestureEduModel {
+        return GestureEduModel(
+            signalCount = preferences[getSignalCountKey(gestureType)] ?: 0,
+            educationShownCount = preferences[getEducationShownCountKey(gestureType)] ?: 0,
+        )
+    }
+
+    internal suspend fun updateGestureEduModel(
+        gestureType: GestureType,
+        transform: (GestureEduModel) -> GestureEduModel
+    ) {
+        datastore.filterNotNull().first().edit { preferences ->
+            val currentModel = getGestureEduModel(gestureType, preferences)
+            val updatedModel = transform(currentModel)
+            preferences[getSignalCountKey(gestureType)] = updatedModel.signalCount
+            preferences[getEducationShownCountKey(gestureType)] = updatedModel.educationShownCount
+        }
+    }
+
+    private fun getSignalCountKey(gestureType: GestureType): Preferences.Key<Int> =
+        intPreferencesKey(gestureType.name + SIGNAL_COUNT_SUFFIX)
+
+    private fun getEducationShownCountKey(gestureType: GestureType): Preferences.Key<Int> =
+        intPreferencesKey(gestureType.name + NUMBER_OF_EDU_SHOWN_SUFFIX)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt b/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt
index 1404340..af7ecf6 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt
@@ -29,6 +29,7 @@
 import com.android.systemui.keyguard.MigrateClocksToBlueprint
 import com.android.systemui.keyguard.shared.ComposeLockscreen
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.shade.shared.flag.DualShade
 import com.android.systemui.statusbar.notification.collection.SortBySectionTimeFlag
 import com.android.systemui.statusbar.notification.footer.shared.FooterViewRefactor
 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionRefactor
@@ -62,6 +63,9 @@
 
         // CommunalHub dependencies
         communalHub dependsOn MigrateClocksToBlueprint.token
+
+        // DualShade dependencies
+        DualShade.token dependsOn SceneContainerFlag.getMainAconfigFlag()
     }
 
     private inline val politeNotifications
diff --git a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt
index be4c903..7b5139a 100644
--- a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt
+++ b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffect.kt
@@ -97,14 +97,15 @@
             State.IDLE -> {
                 setState(State.TIMEOUT_WAIT)
             }
-            State.RUNNING_BACKWARDS -> callback?.onCancelAnimator()
+            State.RUNNING_BACKWARDS_FROM_UP,
+            State.RUNNING_BACKWARDS_FROM_CANCEL -> callback?.onCancelAnimator()
             else -> {}
         }
     }
 
     fun handleActionUp() {
         if (state == State.RUNNING_FORWARD) {
-            setState(State.RUNNING_BACKWARDS)
+            setState(State.RUNNING_BACKWARDS_FROM_UP)
             callback?.onReverseAnimator()
         }
     }
@@ -113,7 +114,7 @@
         when (state) {
             State.TIMEOUT_WAIT -> setState(State.IDLE)
             State.RUNNING_FORWARD -> {
-                setState(State.RUNNING_BACKWARDS)
+                setState(State.RUNNING_BACKWARDS_FROM_CANCEL)
                 callback?.onReverseAnimator()
             }
             else -> {}
@@ -127,20 +128,24 @@
 
     /** This function is called both when an animator completes or gets cancelled */
     fun handleAnimationComplete() {
-        if (state == State.RUNNING_FORWARD) {
-            setState(State.IDLE)
-            vibrate(snapEffect)
-            if (keyguardStateController.isUnlocked) {
-                callback?.onPrepareForLaunch()
-                qsTile?.longClick(expandable)
-            } else {
-                callback?.onResetProperties()
-                qsTile?.longClick(expandable)
+        when (state) {
+            State.RUNNING_FORWARD -> {
+                setState(State.IDLE)
+                vibrate(snapEffect)
+                if (keyguardStateController.isUnlocked) {
+                    qsTile?.longClick(expandable)
+                } else {
+                    callback?.onResetProperties()
+                    qsTile?.longClick(expandable)
+                }
             }
-        }
-        if (state != State.TIMEOUT_WAIT) {
-            // This will happen if the animator did not finish by being cancelled
-            setState(State.IDLE)
+            State.RUNNING_BACKWARDS_FROM_UP -> {
+                setState(State.IDLE)
+                callback?.onEffectFinishedReversing()
+                qsTile?.click(expandable)
+            }
+            State.RUNNING_BACKWARDS_FROM_CANCEL -> setState(State.IDLE)
+            else -> {}
         }
     }
 
@@ -191,20 +196,23 @@
 
     enum class State {
         IDLE, /* The effect is idle waiting for touch input */
-        TIMEOUT_WAIT, /* The effect is waiting for a [PRESSED_TIMEOUT] period */
+        TIMEOUT_WAIT, /* The effect is waiting for a tap timeout period */
         RUNNING_FORWARD, /* The effect is running normally */
-        RUNNING_BACKWARDS, /* The effect was interrupted and is now running backwards */
+        /* The effect was interrupted by an ACTION_UP and is now running backwards */
+        RUNNING_BACKWARDS_FROM_UP,
+        /* The effect was interrupted by an ACTION_CANCEL and is now running backwards */
+        RUNNING_BACKWARDS_FROM_CANCEL,
     }
 
     /** Callbacks to notify view and animator actions */
     interface Callback {
 
-        /** Prepare for an activity launch */
-        fun onPrepareForLaunch()
-
         /** Reset the tile visual properties */
         fun onResetProperties()
 
+        /** Event where the effect completed by being reversed */
+        fun onEffectFinishedReversing()
+
         /** Start the effect animator */
         fun onStartAnimator()
 
diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/data/repository/InputDeviceRepository.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/data/repository/InputDeviceRepository.kt
new file mode 100644
index 0000000..3b161b6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/inputdevice/data/repository/InputDeviceRepository.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.inputdevice.data.repository
+
+import android.annotation.SuppressLint
+import android.hardware.input.InputManager
+import android.os.Handler
+import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.SendChannel
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.shareIn
+
+@SysUISingleton
+class InputDeviceRepository
+@Inject
+constructor(
+    @Background private val backgroundHandler: Handler,
+    @Background private val backgroundScope: CoroutineScope,
+    private val inputManager: InputManager
+) {
+
+    sealed interface DeviceChange
+
+    data class DeviceAdded(val deviceId: Int) : DeviceChange
+
+    data object DeviceRemoved : DeviceChange
+
+    data object FreshStart : DeviceChange
+
+    /**
+     * Emits collection of all currently connected keyboards and what was the last [DeviceChange].
+     * It emits collection so that every new subscriber to this SharedFlow can get latest state of
+     * all keyboards. Otherwise we might get into situation where subscriber timing on
+     * initialization matter and later subscriber will only get latest device and will miss all
+     * previous devices.
+     */
+    // TODO(b/351984587): Replace with StateFlow
+    @SuppressLint("SharedFlowCreation")
+    val deviceChange: Flow<Pair<Collection<Int>, DeviceChange>> =
+        conflatedCallbackFlow {
+                var connectedDevices = inputManager.inputDeviceIds.toSet()
+                val listener =
+                    object : InputManager.InputDeviceListener {
+                        override fun onInputDeviceAdded(deviceId: Int) {
+                            connectedDevices = connectedDevices + deviceId
+                            sendWithLogging(connectedDevices to DeviceAdded(deviceId))
+                        }
+
+                        override fun onInputDeviceChanged(deviceId: Int) = Unit
+
+                        override fun onInputDeviceRemoved(deviceId: Int) {
+                            connectedDevices = connectedDevices - deviceId
+                            sendWithLogging(connectedDevices to DeviceRemoved)
+                        }
+                    }
+                sendWithLogging(connectedDevices to FreshStart)
+                inputManager.registerInputDeviceListener(listener, backgroundHandler)
+                awaitClose { inputManager.unregisterInputDeviceListener(listener) }
+            }
+            .shareIn(
+                scope = backgroundScope,
+                started = SharingStarted.Lazily,
+                replay = 1,
+            )
+
+    private fun <T> SendChannel<T>.sendWithLogging(element: T) {
+        trySendWithFailureLogging(element, TAG)
+    }
+
+    companion object {
+        const val TAG = "InputDeviceRepository"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/data/repository/KeyboardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyboard/data/repository/KeyboardRepository.kt
index 91d5280..817849c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/data/repository/KeyboardRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/data/repository/KeyboardRepository.kt
@@ -21,21 +21,23 @@
 import android.hardware.input.InputManager.KeyboardBacklightListener
 import android.hardware.input.KeyboardBacklightState
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
-import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.inputdevice.data.repository.InputDeviceRepository
+import com.android.systemui.inputdevice.data.repository.InputDeviceRepository.DeviceAdded
+import com.android.systemui.inputdevice.data.repository.InputDeviceRepository.DeviceChange
+import com.android.systemui.inputdevice.data.repository.InputDeviceRepository.DeviceRemoved
+import com.android.systemui.inputdevice.data.repository.InputDeviceRepository.FreshStart
 import com.android.systemui.keyboard.data.model.Keyboard
 import com.android.systemui.keyboard.shared.model.BacklightModel
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
 import java.util.concurrent.Executor
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.FlowPreview
 import kotlinx.coroutines.channels.SendChannel
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.asFlow
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.emptyFlow
@@ -44,7 +46,6 @@
 import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.mapNotNull
-import kotlinx.coroutines.flow.shareIn
 
 /**
  * Provides information about physical keyboard states. [CommandLineKeyboardRepository] can be
@@ -71,50 +72,15 @@
 class KeyboardRepositoryImpl
 @Inject
 constructor(
-    @Application private val applicationScope: CoroutineScope,
     @Background private val backgroundDispatcher: CoroutineDispatcher,
     private val inputManager: InputManager,
+    inputDeviceRepository: InputDeviceRepository
 ) : KeyboardRepository {
 
-    private sealed interface DeviceChange
-    private data class DeviceAdded(val deviceId: Int) : DeviceChange
-    private object DeviceRemoved : DeviceChange
-    private object FreshStart : DeviceChange
-
-    /**
-     * Emits collection of all currently connected keyboards and what was the last [DeviceChange].
-     * It emits collection so that every new subscriber to this SharedFlow can get latest state of
-     * all keyboards. Otherwise we might get into situation where subscriber timing on
-     * initialization matter and later subscriber will only get latest device and will miss all
-     * previous devices.
-     */
     private val keyboardsChange: Flow<Pair<Collection<Int>, DeviceChange>> =
-        conflatedCallbackFlow {
-                var connectedDevices = inputManager.inputDeviceIds.toSet()
-                val listener =
-                    object : InputManager.InputDeviceListener {
-                        override fun onInputDeviceAdded(deviceId: Int) {
-                            connectedDevices = connectedDevices + deviceId
-                            sendWithLogging(connectedDevices to DeviceAdded(deviceId))
-                        }
-
-                        override fun onInputDeviceChanged(deviceId: Int) = Unit
-
-                        override fun onInputDeviceRemoved(deviceId: Int) {
-                            connectedDevices = connectedDevices - deviceId
-                            sendWithLogging(connectedDevices to DeviceRemoved)
-                        }
-                    }
-                sendWithLogging(connectedDevices to FreshStart)
-                inputManager.registerInputDeviceListener(listener, /* handler= */ null)
-                awaitClose { inputManager.unregisterInputDeviceListener(listener) }
-            }
-            .map { (ids, change) -> ids.filter { id -> isPhysicalFullKeyboard(id) } to change }
-            .shareIn(
-                scope = applicationScope,
-                started = SharingStarted.Lazily,
-                replay = 1,
-            )
+        inputDeviceRepository.deviceChange.map { (ids, change) ->
+            ids.filter { id -> isPhysicalFullKeyboard(id) } to change
+        }
 
     @FlowPreview
     override val newlyConnectedKeyboard: Flow<Keyboard> =
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt
index 5635f80..1f0aef8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt
@@ -19,7 +19,16 @@
 import android.app.Activity
 import com.android.systemui.CoreStartable
 import com.android.systemui.Flags.keyboardShortcutHelperRewrite
-import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperRepository
+import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperStateRepository
+import com.android.systemui.keyboard.shortcut.data.source.AppCategoriesShortcutsSource
+import com.android.systemui.keyboard.shortcut.data.source.InputShortcutsSource
+import com.android.systemui.keyboard.shortcut.data.source.KeyboardShortcutGroupsSource
+import com.android.systemui.keyboard.shortcut.data.source.MultitaskingShortcutsSource
+import com.android.systemui.keyboard.shortcut.data.source.SystemShortcutsSource
+import com.android.systemui.keyboard.shortcut.qualifiers.AppCategoriesShortcuts
+import com.android.systemui.keyboard.shortcut.qualifiers.InputShortcuts
+import com.android.systemui.keyboard.shortcut.qualifiers.MultitaskingShortcuts
+import com.android.systemui.keyboard.shortcut.qualifiers.SystemShortcuts
 import com.android.systemui.keyboard.shortcut.ui.ShortcutHelperActivityStarter
 import com.android.systemui.keyboard.shortcut.ui.view.ShortcutHelperActivity
 import dagger.Binds
@@ -37,6 +46,24 @@
     @ClassKey(ShortcutHelperActivity::class)
     fun activity(impl: ShortcutHelperActivity): Activity
 
+    @Binds
+    @SystemShortcuts
+    fun systemShortcutsSource(impl: SystemShortcutsSource): KeyboardShortcutGroupsSource
+
+    @Binds
+    @MultitaskingShortcuts
+    fun multitaskingShortcutsSource(impl: MultitaskingShortcutsSource): KeyboardShortcutGroupsSource
+
+    @Binds
+    @InputShortcuts
+    fun inputShortcutsSources(impl: InputShortcutsSource): KeyboardShortcutGroupsSource
+
+    @Binds
+    @AppCategoriesShortcuts
+    fun appCategoriesShortcutsSource(
+        impl: AppCategoriesShortcutsSource
+    ): KeyboardShortcutGroupsSource
+
     companion object {
         @Provides
         @IntoMap
@@ -52,8 +79,8 @@
 
         @Provides
         @IntoMap
-        @ClassKey(ShortcutHelperRepository::class)
-        fun repo(implLazy: Lazy<ShortcutHelperRepository>): CoreStartable {
+        @ClassKey(ShortcutHelperStateRepository::class)
+        fun repo(implLazy: Lazy<ShortcutHelperStateRepository>): CoreStartable {
             return if (keyboardShortcutHelperRewrite()) {
                 implLazy.get()
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/model/KeyboardShortcutInfo.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/model/KeyboardShortcutInfo.kt
new file mode 100644
index 0000000..8e94901
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/model/KeyboardShortcutInfo.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.data.model
+
+import android.view.KeyboardShortcutInfo
+
+class KeyboardShortcutInfoBuilder(val label: String) {
+
+    private var modifiers = 0
+    private var keyCode = 0
+
+    fun command(modifiers: Int, keyCode: Int = 0) {
+        this.modifiers = modifiers
+        this.keyCode = keyCode
+    }
+
+    fun build() = KeyboardShortcutInfo(label, keyCode, modifiers)
+}
+
+fun shortcutInfo(label: String, block: KeyboardShortcutInfoBuilder.() -> Unit) =
+    KeyboardShortcutInfoBuilder(label).apply(block).build()
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt
new file mode 100644
index 0000000..7b0c25e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.data.repository
+
+import android.content.Context
+import android.graphics.drawable.Icon
+import android.hardware.input.InputManager
+import android.util.Log
+import android.view.KeyCharacterMap
+import android.view.KeyEvent
+import android.view.KeyboardShortcutGroup
+import android.view.KeyboardShortcutInfo
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.keyboard.shortcut.data.source.KeyboardShortcutGroupsSource
+import com.android.systemui.keyboard.shortcut.qualifiers.AppCategoriesShortcuts
+import com.android.systemui.keyboard.shortcut.qualifiers.InputShortcuts
+import com.android.systemui.keyboard.shortcut.qualifiers.MultitaskingShortcuts
+import com.android.systemui.keyboard.shortcut.qualifiers.SystemShortcuts
+import com.android.systemui.keyboard.shortcut.shared.model.Shortcut
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.APP_CATEGORIES
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.IME
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MULTI_TASKING
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.SYSTEM
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState.Active
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutIcon
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.withContext
+
+@SysUISingleton
+class ShortcutHelperCategoriesRepository
+@Inject
+constructor(
+    private val context: Context,
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
+    @SystemShortcuts private val systemShortcutsSource: KeyboardShortcutGroupsSource,
+    @MultitaskingShortcuts private val multitaskingShortcutsSource: KeyboardShortcutGroupsSource,
+    @AppCategoriesShortcuts private val appCategoriesShortcutsSource: KeyboardShortcutGroupsSource,
+    @InputShortcuts private val inputShortcutsSource: KeyboardShortcutGroupsSource,
+    private val inputManager: InputManager,
+    stateRepository: ShortcutHelperStateRepository
+) {
+
+    private val activeInputDevice =
+        stateRepository.state.map {
+            if (it is Active) {
+                withContext(backgroundDispatcher) { inputManager.getInputDevice(it.deviceId) }
+            } else {
+                null
+            }
+        }
+
+    val systemShortcutsCategory =
+        activeInputDevice.map {
+            if (it != null) {
+                toShortcutCategory(
+                    it.keyCharacterMap,
+                    SYSTEM,
+                    systemShortcutsSource.shortcutGroups(it.id),
+                    keepIcons = true,
+                )
+            } else {
+                null
+            }
+        }
+
+    val multitaskingShortcutsCategory =
+        activeInputDevice.map {
+            if (it != null) {
+                toShortcutCategory(
+                    it.keyCharacterMap,
+                    MULTI_TASKING,
+                    multitaskingShortcutsSource.shortcutGroups(it.id),
+                    keepIcons = true,
+                )
+            } else {
+                null
+            }
+        }
+
+    val appCategoriesShortcutsCategory =
+        activeInputDevice.map {
+            if (it != null) {
+                toShortcutCategory(
+                    it.keyCharacterMap,
+                    APP_CATEGORIES,
+                    appCategoriesShortcutsSource.shortcutGroups(it.id),
+                    keepIcons = true,
+                )
+            } else {
+                null
+            }
+        }
+
+    val imeShortcutsCategory =
+        activeInputDevice.map {
+            if (it != null) {
+                toShortcutCategory(
+                    it.keyCharacterMap,
+                    IME,
+                    inputShortcutsSource.shortcutGroups(it.id),
+                    keepIcons = false,
+                )
+            } else {
+                null
+            }
+        }
+
+    private fun toShortcutCategory(
+        keyCharacterMap: KeyCharacterMap,
+        type: ShortcutCategoryType,
+        shortcutGroups: List<KeyboardShortcutGroup>,
+        keepIcons: Boolean,
+    ): ShortcutCategory? {
+        val subCategories =
+            shortcutGroups
+                .map { shortcutGroup ->
+                    ShortcutSubCategory(
+                        shortcutGroup.label.toString(),
+                        toShortcuts(keyCharacterMap, shortcutGroup.items, keepIcons)
+                    )
+                }
+                .filter { it.shortcuts.isNotEmpty() }
+        return if (subCategories.isEmpty()) {
+            Log.wtf(TAG, "Empty sub categories after converting $shortcutGroups")
+            null
+        } else {
+            ShortcutCategory(type, subCategories)
+        }
+    }
+
+    private fun toShortcuts(
+        keyCharacterMap: KeyCharacterMap,
+        infoList: List<KeyboardShortcutInfo>,
+        keepIcons: Boolean,
+    ) = infoList.mapNotNull { toShortcut(keyCharacterMap, it, keepIcons) }
+
+    private fun toShortcut(
+        keyCharacterMap: KeyCharacterMap,
+        shortcutInfo: KeyboardShortcutInfo,
+        keepIcon: Boolean,
+    ): Shortcut? {
+        val shortcutCommand = toShortcutCommand(keyCharacterMap, shortcutInfo) ?: return null
+        return Shortcut(
+            label = shortcutInfo.label!!.toString(),
+            icon = toShortcutIcon(keepIcon, shortcutInfo),
+            commands = listOf(shortcutCommand)
+        )
+    }
+
+    private fun toShortcutIcon(
+        keepIcon: Boolean,
+        shortcutInfo: KeyboardShortcutInfo
+    ): ShortcutIcon? {
+        if (!keepIcon) {
+            return null
+        }
+        val icon = shortcutInfo.icon ?: return null
+        // For now only keep icons of type resource, which is what the "default apps" shortcuts
+        // provide.
+        if (icon.type != Icon.TYPE_RESOURCE || icon.resPackage.isNullOrEmpty() || icon.resId <= 0) {
+            return null
+        }
+        return ShortcutIcon(packageName = icon.resPackage, resourceId = icon.resId)
+    }
+
+    private fun toShortcutCommand(
+        keyCharacterMap: KeyCharacterMap,
+        info: KeyboardShortcutInfo
+    ): ShortcutCommand? {
+        val keys = mutableListOf<ShortcutKey>()
+        var remainingModifiers = info.modifiers
+        SUPPORTED_MODIFIERS.forEach { supportedModifier ->
+            if ((supportedModifier and remainingModifiers) != 0) {
+                keys += toShortcutKey(keyCharacterMap, supportedModifier) ?: return null
+                // "Remove" the modifier from the remaining modifiers
+                remainingModifiers = remainingModifiers and supportedModifier.inv()
+            }
+        }
+        if (remainingModifiers != 0) {
+            // There is a remaining modifier we don't support
+            Log.wtf(TAG, "Unsupported modifiers remaining: $remainingModifiers")
+            return null
+        }
+        if (info.keycode != 0) {
+            keys += toShortcutKey(keyCharacterMap, info.keycode, info.baseCharacter) ?: return null
+        }
+        if (keys.isEmpty()) {
+            Log.wtf(TAG, "No keys for $info")
+            return null
+        }
+        return ShortcutCommand(keys)
+    }
+
+    private fun toShortcutKey(
+        keyCharacterMap: KeyCharacterMap,
+        keyCode: Int,
+        baseCharacter: Char = Char.MIN_VALUE,
+    ): ShortcutKey? {
+        val iconResId = ShortcutHelperKeys.keyIcons[keyCode]
+        if (iconResId != null) {
+            return ShortcutKey.Icon(iconResId)
+        }
+        if (baseCharacter > Char.MIN_VALUE) {
+            return ShortcutKey.Text(baseCharacter.toString())
+        }
+        val specialKeyLabel = ShortcutHelperKeys.specialKeyLabels[keyCode]
+        if (specialKeyLabel != null) {
+            val label = specialKeyLabel(context)
+            return ShortcutKey.Text(label)
+        }
+        val displayLabelCharacter = keyCharacterMap.getDisplayLabel(keyCode)
+        if (displayLabelCharacter.code != 0) {
+            return ShortcutKey.Text(displayLabelCharacter.toString())
+        }
+        Log.wtf(TAG, "Couldn't find label or icon for key: $keyCode")
+        return null
+    }
+
+    companion object {
+        private const val TAG = "SHCategoriesRepo"
+
+        private val SUPPORTED_MODIFIERS =
+            listOf(
+                KeyEvent.META_META_ON,
+                KeyEvent.META_CTRL_ON,
+                KeyEvent.META_ALT_ON,
+                KeyEvent.META_SHIFT_ON,
+                KeyEvent.META_SYM_ON,
+                KeyEvent.META_FUNCTION_ON
+            )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt
new file mode 100644
index 0000000..0aced8c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperKeys.kt
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.data.repository
+
+import android.content.Context
+import android.view.KeyEvent.KEYCODE_ALT_LEFT
+import android.view.KeyEvent.KEYCODE_ALT_RIGHT
+import android.view.KeyEvent.KEYCODE_BACK
+import android.view.KeyEvent.KEYCODE_BREAK
+import android.view.KeyEvent.KEYCODE_BUTTON_A
+import android.view.KeyEvent.KEYCODE_BUTTON_B
+import android.view.KeyEvent.KEYCODE_BUTTON_C
+import android.view.KeyEvent.KEYCODE_BUTTON_L1
+import android.view.KeyEvent.KEYCODE_BUTTON_L2
+import android.view.KeyEvent.KEYCODE_BUTTON_MODE
+import android.view.KeyEvent.KEYCODE_BUTTON_R1
+import android.view.KeyEvent.KEYCODE_BUTTON_R2
+import android.view.KeyEvent.KEYCODE_BUTTON_SELECT
+import android.view.KeyEvent.KEYCODE_BUTTON_START
+import android.view.KeyEvent.KEYCODE_BUTTON_X
+import android.view.KeyEvent.KEYCODE_BUTTON_Y
+import android.view.KeyEvent.KEYCODE_BUTTON_Z
+import android.view.KeyEvent.KEYCODE_CTRL_LEFT
+import android.view.KeyEvent.KEYCODE_CTRL_RIGHT
+import android.view.KeyEvent.KEYCODE_DEL
+import android.view.KeyEvent.KEYCODE_DPAD_CENTER
+import android.view.KeyEvent.KEYCODE_DPAD_DOWN
+import android.view.KeyEvent.KEYCODE_DPAD_LEFT
+import android.view.KeyEvent.KEYCODE_DPAD_RIGHT
+import android.view.KeyEvent.KEYCODE_DPAD_UP
+import android.view.KeyEvent.KEYCODE_EISU
+import android.view.KeyEvent.KEYCODE_ENTER
+import android.view.KeyEvent.KEYCODE_EQUALS
+import android.view.KeyEvent.KEYCODE_ESCAPE
+import android.view.KeyEvent.KEYCODE_F1
+import android.view.KeyEvent.KEYCODE_F10
+import android.view.KeyEvent.KEYCODE_F11
+import android.view.KeyEvent.KEYCODE_F12
+import android.view.KeyEvent.KEYCODE_F2
+import android.view.KeyEvent.KEYCODE_F3
+import android.view.KeyEvent.KEYCODE_F4
+import android.view.KeyEvent.KEYCODE_F5
+import android.view.KeyEvent.KEYCODE_F6
+import android.view.KeyEvent.KEYCODE_F7
+import android.view.KeyEvent.KEYCODE_F8
+import android.view.KeyEvent.KEYCODE_F9
+import android.view.KeyEvent.KEYCODE_FORWARD_DEL
+import android.view.KeyEvent.KEYCODE_GRAVE
+import android.view.KeyEvent.KEYCODE_HENKAN
+import android.view.KeyEvent.KEYCODE_HOME
+import android.view.KeyEvent.KEYCODE_INSERT
+import android.view.KeyEvent.KEYCODE_KATAKANA_HIRAGANA
+import android.view.KeyEvent.KEYCODE_MEDIA_FAST_FORWARD
+import android.view.KeyEvent.KEYCODE_MEDIA_NEXT
+import android.view.KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE
+import android.view.KeyEvent.KEYCODE_MEDIA_PREVIOUS
+import android.view.KeyEvent.KEYCODE_MEDIA_REWIND
+import android.view.KeyEvent.KEYCODE_MEDIA_STOP
+import android.view.KeyEvent.KEYCODE_MINUS
+import android.view.KeyEvent.KEYCODE_MOVE_END
+import android.view.KeyEvent.KEYCODE_MOVE_HOME
+import android.view.KeyEvent.KEYCODE_MUHENKAN
+import android.view.KeyEvent.KEYCODE_NUMPAD_0
+import android.view.KeyEvent.KEYCODE_NUMPAD_1
+import android.view.KeyEvent.KEYCODE_NUMPAD_2
+import android.view.KeyEvent.KEYCODE_NUMPAD_3
+import android.view.KeyEvent.KEYCODE_NUMPAD_4
+import android.view.KeyEvent.KEYCODE_NUMPAD_5
+import android.view.KeyEvent.KEYCODE_NUMPAD_6
+import android.view.KeyEvent.KEYCODE_NUMPAD_7
+import android.view.KeyEvent.KEYCODE_NUMPAD_8
+import android.view.KeyEvent.KEYCODE_NUMPAD_9
+import android.view.KeyEvent.KEYCODE_NUMPAD_ADD
+import android.view.KeyEvent.KEYCODE_NUMPAD_COMMA
+import android.view.KeyEvent.KEYCODE_NUMPAD_DIVIDE
+import android.view.KeyEvent.KEYCODE_NUMPAD_DOT
+import android.view.KeyEvent.KEYCODE_NUMPAD_ENTER
+import android.view.KeyEvent.KEYCODE_NUMPAD_EQUALS
+import android.view.KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN
+import android.view.KeyEvent.KEYCODE_NUMPAD_MULTIPLY
+import android.view.KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN
+import android.view.KeyEvent.KEYCODE_NUMPAD_SUBTRACT
+import android.view.KeyEvent.KEYCODE_NUM_LOCK
+import android.view.KeyEvent.KEYCODE_PAGE_DOWN
+import android.view.KeyEvent.KEYCODE_PAGE_UP
+import android.view.KeyEvent.KEYCODE_PERIOD
+import android.view.KeyEvent.KEYCODE_SCROLL_LOCK
+import android.view.KeyEvent.KEYCODE_SHIFT_LEFT
+import android.view.KeyEvent.KEYCODE_SHIFT_RIGHT
+import android.view.KeyEvent.KEYCODE_SPACE
+import android.view.KeyEvent.KEYCODE_SYSRQ
+import android.view.KeyEvent.KEYCODE_TAB
+import android.view.KeyEvent.KEYCODE_ZENKAKU_HANKAKU
+import android.view.KeyEvent.META_ALT_ON
+import android.view.KeyEvent.META_CTRL_ON
+import android.view.KeyEvent.META_FUNCTION_ON
+import android.view.KeyEvent.META_META_ON
+import android.view.KeyEvent.META_SHIFT_ON
+import android.view.KeyEvent.META_SYM_ON
+import com.android.systemui.res.R
+
+object ShortcutHelperKeys {
+
+    val keyIcons =
+        mapOf(
+            META_META_ON to R.drawable.ic_ksh_key_meta,
+        )
+
+    val specialKeyLabels =
+        mapOf<Int, (Context) -> String>(
+            KEYCODE_HOME to { context -> context.getString(R.string.keyboard_key_home) },
+            KEYCODE_BACK to { context -> context.getString(R.string.keyboard_key_back) },
+            KEYCODE_DPAD_UP to { context -> context.getString(R.string.keyboard_key_dpad_up) },
+            KEYCODE_DPAD_DOWN to { context -> context.getString(R.string.keyboard_key_dpad_down) },
+            KEYCODE_DPAD_LEFT to { context -> context.getString(R.string.keyboard_key_dpad_left) },
+            KEYCODE_DPAD_RIGHT to
+                { context ->
+                    context.getString(R.string.keyboard_key_dpad_right)
+                },
+            KEYCODE_DPAD_CENTER to
+                { context ->
+                    context.getString(R.string.keyboard_key_dpad_center)
+                },
+            KEYCODE_PERIOD to { "." },
+            KEYCODE_TAB to { context -> context.getString(R.string.keyboard_key_tab) },
+            KEYCODE_SPACE to { context -> context.getString(R.string.keyboard_key_space) },
+            KEYCODE_ENTER to { context -> context.getString(R.string.keyboard_key_enter) },
+            KEYCODE_DEL to { context -> context.getString(R.string.keyboard_key_backspace) },
+            KEYCODE_MEDIA_PLAY_PAUSE to
+                { context ->
+                    context.getString(R.string.keyboard_key_media_play_pause)
+                },
+            KEYCODE_MEDIA_STOP to
+                { context ->
+                    context.getString(R.string.keyboard_key_media_stop)
+                },
+            KEYCODE_MEDIA_NEXT to
+                { context ->
+                    context.getString(R.string.keyboard_key_media_next)
+                },
+            KEYCODE_MEDIA_PREVIOUS to
+                { context ->
+                    context.getString(R.string.keyboard_key_media_previous)
+                },
+            KEYCODE_MEDIA_REWIND to
+                { context ->
+                    context.getString(R.string.keyboard_key_media_rewind)
+                },
+            KEYCODE_MEDIA_FAST_FORWARD to
+                { context ->
+                    context.getString(R.string.keyboard_key_media_fast_forward)
+                },
+            KEYCODE_PAGE_UP to { context -> context.getString(R.string.keyboard_key_page_up) },
+            KEYCODE_PAGE_DOWN to { context -> context.getString(R.string.keyboard_key_page_down) },
+            KEYCODE_BUTTON_A to
+                { context ->
+                    context.getString(R.string.keyboard_key_button_template, "A")
+                },
+            KEYCODE_BUTTON_B to
+                { context ->
+                    context.getString(R.string.keyboard_key_button_template, "B")
+                },
+            KEYCODE_BUTTON_C to
+                { context ->
+                    context.getString(R.string.keyboard_key_button_template, "C")
+                },
+            KEYCODE_BUTTON_X to
+                { context ->
+                    context.getString(R.string.keyboard_key_button_template, "X")
+                },
+            KEYCODE_BUTTON_Y to
+                { context ->
+                    context.getString(R.string.keyboard_key_button_template, "Y")
+                },
+            KEYCODE_BUTTON_Z to
+                { context ->
+                    context.getString(R.string.keyboard_key_button_template, "Z")
+                },
+            KEYCODE_BUTTON_L1 to
+                { context ->
+                    context.getString(R.string.keyboard_key_button_template, "L1")
+                },
+            KEYCODE_BUTTON_R1 to
+                { context ->
+                    context.getString(R.string.keyboard_key_button_template, "R1")
+                },
+            KEYCODE_BUTTON_L2 to
+                { context ->
+                    context.getString(R.string.keyboard_key_button_template, "L2")
+                },
+            KEYCODE_BUTTON_R2 to
+                { context ->
+                    context.getString(R.string.keyboard_key_button_template, "R2")
+                },
+            KEYCODE_BUTTON_START to
+                { context ->
+                    context.getString(R.string.keyboard_key_button_template, "Start")
+                },
+            KEYCODE_BUTTON_SELECT to
+                { context ->
+                    context.getString(R.string.keyboard_key_button_template, "Select")
+                },
+            KEYCODE_BUTTON_MODE to
+                { context ->
+                    context.getString(R.string.keyboard_key_button_template, "Mode")
+                },
+            KEYCODE_FORWARD_DEL to
+                { context ->
+                    context.getString(R.string.keyboard_key_forward_del)
+                },
+            KEYCODE_ESCAPE to { "Esc" },
+            KEYCODE_SYSRQ to { "SysRq" },
+            KEYCODE_BREAK to { "Break" },
+            KEYCODE_SCROLL_LOCK to { "Scroll Lock" },
+            KEYCODE_MOVE_HOME to { context -> context.getString(R.string.keyboard_key_move_home) },
+            KEYCODE_MOVE_END to { context -> context.getString(R.string.keyboard_key_move_end) },
+            KEYCODE_INSERT to { context -> context.getString(R.string.keyboard_key_insert) },
+            KEYCODE_F1 to { "F1" },
+            KEYCODE_F2 to { "F2" },
+            KEYCODE_F3 to { "F3" },
+            KEYCODE_F4 to { "F4" },
+            KEYCODE_F5 to { "F5" },
+            KEYCODE_F6 to { "F6" },
+            KEYCODE_F7 to { "F7" },
+            KEYCODE_F8 to { "F8" },
+            KEYCODE_F9 to { "F9" },
+            KEYCODE_F10 to { "F10" },
+            KEYCODE_F11 to { "F11" },
+            KEYCODE_F12 to { "F12" },
+            KEYCODE_NUM_LOCK to { context -> context.getString(R.string.keyboard_key_num_lock) },
+            KEYCODE_MINUS to { "-" },
+            KEYCODE_GRAVE to { "`" },
+            KEYCODE_EQUALS to { "=" },
+            KEYCODE_NUMPAD_0 to
+                { context ->
+                    context.getString(R.string.keyboard_key_numpad_template, "0")
+                },
+            KEYCODE_NUMPAD_1 to
+                { context ->
+                    context.getString(R.string.keyboard_key_numpad_template, "1")
+                },
+            KEYCODE_NUMPAD_2 to
+                { context ->
+                    context.getString(R.string.keyboard_key_numpad_template, "2")
+                },
+            KEYCODE_NUMPAD_3 to
+                { context ->
+                    context.getString(R.string.keyboard_key_numpad_template, "3")
+                },
+            KEYCODE_NUMPAD_4 to
+                { context ->
+                    context.getString(R.string.keyboard_key_numpad_template, "4")
+                },
+            KEYCODE_NUMPAD_5 to
+                { context ->
+                    context.getString(R.string.keyboard_key_numpad_template, "5")
+                },
+            KEYCODE_NUMPAD_6 to
+                { context ->
+                    context.getString(R.string.keyboard_key_numpad_template, "6")
+                },
+            KEYCODE_NUMPAD_7 to
+                { context ->
+                    context.getString(R.string.keyboard_key_numpad_template, "7")
+                },
+            KEYCODE_NUMPAD_8 to
+                { context ->
+                    context.getString(R.string.keyboard_key_numpad_template, "8")
+                },
+            KEYCODE_NUMPAD_9 to
+                { context ->
+                    context.getString(R.string.keyboard_key_numpad_template, "9")
+                },
+            KEYCODE_NUMPAD_DIVIDE to
+                { context ->
+                    context.getString(R.string.keyboard_key_numpad_template, "/")
+                },
+            KEYCODE_NUMPAD_MULTIPLY to
+                { context ->
+                    context.getString(R.string.keyboard_key_numpad_template, "*")
+                },
+            KEYCODE_NUMPAD_SUBTRACT to
+                { context ->
+                    context.getString(R.string.keyboard_key_numpad_template, "-")
+                },
+            KEYCODE_NUMPAD_ADD to
+                { context ->
+                    context.getString(R.string.keyboard_key_numpad_template, "+")
+                },
+            KEYCODE_NUMPAD_DOT to
+                { context ->
+                    context.getString(R.string.keyboard_key_numpad_template, ".")
+                },
+            KEYCODE_NUMPAD_COMMA to
+                { context ->
+                    context.getString(R.string.keyboard_key_numpad_template, ",")
+                },
+            KEYCODE_NUMPAD_ENTER to
+                { context ->
+                    context.getString(
+                        R.string.keyboard_key_numpad_template,
+                        context.getString(R.string.keyboard_key_enter)
+                    )
+                },
+            KEYCODE_NUMPAD_EQUALS to
+                { context ->
+                    context.getString(R.string.keyboard_key_numpad_template, "=")
+                },
+            KEYCODE_NUMPAD_LEFT_PAREN to
+                { context ->
+                    context.getString(R.string.keyboard_key_numpad_template, "(")
+                },
+            KEYCODE_NUMPAD_RIGHT_PAREN to
+                { context ->
+                    context.getString(R.string.keyboard_key_numpad_template, ")")
+                },
+            KEYCODE_ZENKAKU_HANKAKU to { "半角/全角" },
+            KEYCODE_EISU to { "英数" },
+            KEYCODE_MUHENKAN to { "無変換" },
+            KEYCODE_HENKAN to { "変換" },
+            KEYCODE_KATAKANA_HIRAGANA to { "かな" },
+            KEYCODE_ALT_LEFT to { "Alt" },
+            KEYCODE_ALT_RIGHT to { "Alt" },
+            KEYCODE_CTRL_LEFT to { "Ctrl" },
+            KEYCODE_CTRL_RIGHT to { "Ctrl" },
+            KEYCODE_SHIFT_LEFT to { "Shift" },
+            KEYCODE_SHIFT_RIGHT to { "Shift" },
+
+            // Modifiers
+            META_META_ON to { "Meta" },
+            META_CTRL_ON to { "Ctrl" },
+            META_ALT_ON to { "Alt" },
+            META_SHIFT_ON to { "Shift" },
+            META_SYM_ON to { "Sym" },
+            META_FUNCTION_ON to { "Fn" },
+        )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperRepository.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperRepository.kt
deleted file mode 100644
index ec92ca9..0000000
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperRepository.kt
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.keyboard.shortcut.data.repository
-
-import android.content.BroadcastReceiver
-import android.content.Context
-import android.content.Intent
-import android.content.IntentFilter
-import android.os.UserHandle
-import com.android.systemui.CoreStartable
-import com.android.systemui.broadcast.BroadcastDispatcher
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState.Active
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState.Inactive
-import com.android.systemui.statusbar.CommandQueue
-import javax.inject.Inject
-import kotlinx.coroutines.flow.MutableStateFlow
-
-@SysUISingleton
-class ShortcutHelperRepository
-@Inject
-constructor(
-    private val commandQueue: CommandQueue,
-    private val broadcastDispatcher: BroadcastDispatcher,
-) : CoreStartable {
-
-    val state = MutableStateFlow<ShortcutHelperState>(Inactive)
-
-    override fun start() {
-        registerBroadcastReceiver(
-            action = Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS,
-            onReceive = { state.value = Active() }
-        )
-        registerBroadcastReceiver(
-            action = Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS,
-            onReceive = { state.value = Inactive }
-        )
-        registerBroadcastReceiver(
-            action = Intent.ACTION_CLOSE_SYSTEM_DIALOGS,
-            onReceive = { state.value = Inactive }
-        )
-        commandQueue.addCallback(
-            object : CommandQueue.Callbacks {
-                override fun dismissKeyboardShortcutsMenu() {
-                    state.value = Inactive
-                }
-
-                override fun toggleKeyboardShortcutsMenu(deviceId: Int) {
-                    state.value =
-                        if (state.value is Inactive) {
-                            Active(deviceId)
-                        } else {
-                            Inactive
-                        }
-                }
-            }
-        )
-    }
-
-    fun hide() {
-        state.value = Inactive
-    }
-
-    private fun registerBroadcastReceiver(action: String, onReceive: () -> Unit) {
-        broadcastDispatcher.registerReceiver(
-            receiver =
-                object : BroadcastReceiver() {
-                    override fun onReceive(context: Context, intent: Intent) {
-                        onReceive()
-                    }
-                },
-            filter = IntentFilter(action),
-            flags = Context.RECEIVER_EXPORTED or Context.RECEIVER_VISIBLE_TO_INSTANT_APPS,
-            user = UserHandle.ALL,
-        )
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperStateRepository.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperStateRepository.kt
new file mode 100644
index 0000000..82df95d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperStateRepository.kt
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.data.repository
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.hardware.input.InputManager
+import android.os.UserHandle
+import android.view.KeyCharacterMap.VIRTUAL_KEYBOARD
+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.keyboard.shortcut.shared.model.ShortcutHelperState
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState.Active
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState.Inactive
+import com.android.systemui.shared.hardware.findInputDevice
+import com.android.systemui.statusbar.CommandQueue
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+@SysUISingleton
+class ShortcutHelperStateRepository
+@Inject
+constructor(
+    private val commandQueue: CommandQueue,
+    private val broadcastDispatcher: BroadcastDispatcher,
+    private val inputManager: InputManager,
+    @Background private val backgroundScope: CoroutineScope,
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
+) : CoreStartable {
+
+    val state = MutableStateFlow<ShortcutHelperState>(Inactive)
+
+    override fun start() {
+        registerBroadcastReceiver(
+            action = Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS,
+            onReceive = {
+                backgroundScope.launch { state.value = Active(findPhysicalKeyboardId()) }
+            }
+        )
+        registerBroadcastReceiver(
+            action = Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS,
+            onReceive = { state.value = Inactive }
+        )
+        registerBroadcastReceiver(
+            action = Intent.ACTION_CLOSE_SYSTEM_DIALOGS,
+            onReceive = { state.value = Inactive }
+        )
+        commandQueue.addCallback(
+            object : CommandQueue.Callbacks {
+                override fun dismissKeyboardShortcutsMenu() {
+                    state.value = Inactive
+                }
+
+                override fun toggleKeyboardShortcutsMenu(deviceId: Int) {
+                    state.value =
+                        if (state.value is Inactive) {
+                            Active(deviceId)
+                        } else {
+                            Inactive
+                        }
+                }
+            }
+        )
+    }
+
+    private suspend fun findPhysicalKeyboardId() =
+        withContext(backgroundDispatcher) {
+            val firstEnabledPhysicalKeyboard =
+                inputManager.findInputDevice { it.isEnabled && it.isFullKeyboard && !it.isVirtual }
+            return@withContext firstEnabledPhysicalKeyboard?.id ?: VIRTUAL_KEYBOARD
+        }
+
+    fun hide() {
+        state.value = Inactive
+    }
+
+    private fun registerBroadcastReceiver(action: String, onReceive: () -> Unit) {
+        broadcastDispatcher.registerReceiver(
+            receiver =
+                object : BroadcastReceiver() {
+                    override fun onReceive(context: Context, intent: Intent) {
+                        onReceive()
+                    }
+                },
+            filter = IntentFilter(action),
+            flags = Context.RECEIVER_EXPORTED or Context.RECEIVER_VISIBLE_TO_INSTANT_APPS,
+            user = UserHandle.ALL,
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/AppCategoriesShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/AppCategoriesShortcutsSource.kt
new file mode 100644
index 0000000..d7cb7db
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/AppCategoriesShortcutsSource.kt
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.data.source
+
+import android.content.Intent
+import android.content.res.Resources
+import android.view.KeyEvent
+import android.view.KeyboardShortcutGroup
+import android.view.KeyboardShortcutInfo
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.res.R
+import com.android.systemui.util.icons.AppCategoryIconProvider
+import javax.inject.Inject
+
+class AppCategoriesShortcutsSource
+@Inject
+constructor(
+    private val appCategoryIconProvider: AppCategoryIconProvider,
+    @Main private val resources: Resources,
+) : KeyboardShortcutGroupsSource {
+
+    override suspend fun shortcutGroups(deviceId: Int) =
+        listOf(
+            KeyboardShortcutGroup(
+                /* label = */ resources.getString(R.string.keyboard_shortcut_group_applications),
+                /* items = */ shortcuts()
+            )
+        )
+
+    private suspend fun shortcuts(): List<KeyboardShortcutInfo> =
+        listOfNotNull(
+                assistantAppShortcutInfo(),
+                appCategoryShortcutInfo(
+                    Intent.CATEGORY_APP_BROWSER,
+                    R.string.keyboard_shortcut_group_applications_browser,
+                    KeyEvent.KEYCODE_B
+                ),
+                appCategoryShortcutInfo(
+                    Intent.CATEGORY_APP_CONTACTS,
+                    R.string.keyboard_shortcut_group_applications_contacts,
+                    KeyEvent.KEYCODE_C
+                ),
+                appCategoryShortcutInfo(
+                    Intent.CATEGORY_APP_EMAIL,
+                    R.string.keyboard_shortcut_group_applications_email,
+                    KeyEvent.KEYCODE_E
+                ),
+                appCategoryShortcutInfo(
+                    Intent.CATEGORY_APP_CALENDAR,
+                    R.string.keyboard_shortcut_group_applications_calendar,
+                    KeyEvent.KEYCODE_K
+                ),
+                appCategoryShortcutInfo(
+                    Intent.CATEGORY_APP_MAPS,
+                    R.string.keyboard_shortcut_group_applications_maps,
+                    KeyEvent.KEYCODE_M
+                ),
+                appCategoryShortcutInfo(
+                    Intent.CATEGORY_APP_MUSIC,
+                    R.string.keyboard_shortcut_group_applications_music,
+                    KeyEvent.KEYCODE_P
+                ),
+                appCategoryShortcutInfo(
+                    Intent.CATEGORY_APP_MESSAGING,
+                    R.string.keyboard_shortcut_group_applications_sms,
+                    KeyEvent.KEYCODE_S
+                ),
+                appCategoryShortcutInfo(
+                    Intent.CATEGORY_APP_CALCULATOR,
+                    R.string.keyboard_shortcut_group_applications_calculator,
+                    KeyEvent.KEYCODE_U
+                ),
+            )
+            .sortedBy { it.label!!.toString().lowercase() }
+
+    private suspend fun assistantAppShortcutInfo(): KeyboardShortcutInfo? {
+        val assistantIcon = appCategoryIconProvider.assistantAppIcon() ?: return null
+        return KeyboardShortcutInfo(
+            /* label = */ resources.getString(R.string.keyboard_shortcut_group_applications_assist),
+            /* icon = */ assistantIcon,
+            /* keycode = */ KeyEvent.KEYCODE_A,
+            /* modifiers = */ KeyEvent.META_META_ON,
+        )
+    }
+
+    private suspend fun appCategoryShortcutInfo(category: String, labelResId: Int, keycode: Int) =
+        KeyboardShortcutInfo(
+            /* label = */ resources.getString(labelResId),
+            /* icon = */ appCategoryIconProvider.categoryAppIcon(category),
+            /* keycode = */ keycode,
+            /* modifiers = */ KeyEvent.META_META_ON,
+        )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSource.kt
new file mode 100644
index 0000000..aba4415
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/InputShortcutsSource.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.data.source
+
+import android.content.res.Resources
+import android.view.KeyEvent.KEYCODE_SPACE
+import android.view.KeyEvent.META_CTRL_ON
+import android.view.KeyEvent.META_SHIFT_ON
+import android.view.KeyboardShortcutGroup
+import android.view.WindowManager
+import android.view.WindowManager.KeyboardShortcutsReceiver
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.keyboard.shortcut.data.model.shortcutInfo
+import com.android.systemui.res.R
+import javax.inject.Inject
+import kotlinx.coroutines.suspendCancellableCoroutine
+
+class InputShortcutsSource
+@Inject
+constructor(@Main private val resources: Resources, private val windowManager: WindowManager) :
+    KeyboardShortcutGroupsSource {
+    override suspend fun shortcutGroups(deviceId: Int): List<KeyboardShortcutGroup> =
+        getInputLanguageShortcutGroup() + getImeShortcutGroup(deviceId)
+
+    private fun getInputLanguageShortcutGroup() =
+        listOf(
+            KeyboardShortcutGroup(
+                resources.getString(R.string.shortcut_helper_category_input),
+                inputLanguageShortcuts()
+            )
+        )
+
+    private fun inputLanguageShortcuts() =
+        listOf(
+            /* Switch input language (next language): Ctrl + Space */
+            shortcutInfo(resources.getString(R.string.input_switch_input_language_next)) {
+                command(META_CTRL_ON, KEYCODE_SPACE)
+            },
+            /* Switch previous language (next language): Ctrl + Shift + Space */
+            shortcutInfo(resources.getString(R.string.input_switch_input_language_previous)) {
+                command(META_CTRL_ON or META_SHIFT_ON, KEYCODE_SPACE)
+            }
+        )
+
+    private suspend fun getImeShortcutGroup(deviceId: Int): List<KeyboardShortcutGroup> =
+        suspendCancellableCoroutine { continuation ->
+            val shortcutsReceiver = KeyboardShortcutsReceiver {
+                continuation.resumeWith(Result.success(it))
+            }
+            windowManager.requestImeKeyboardShortcuts(shortcutsReceiver, deviceId)
+        }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/KeyboardShortcutGroupsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/KeyboardShortcutGroupsSource.kt
new file mode 100644
index 0000000..39d0377
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/KeyboardShortcutGroupsSource.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.data.source
+
+import android.view.KeyboardShortcutGroup
+
+interface KeyboardShortcutGroupsSource {
+
+    suspend fun shortcutGroups(deviceId: Int): List<KeyboardShortcutGroup>
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
new file mode 100644
index 0000000..eddac4d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/MultitaskingShortcutsSource.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.data.source
+
+import android.content.res.Resources
+import android.view.KeyEvent.KEYCODE_DPAD_LEFT
+import android.view.KeyEvent.KEYCODE_DPAD_RIGHT
+import android.view.KeyEvent.KEYCODE_DPAD_UP
+import android.view.KeyEvent.KEYCODE_TAB
+import android.view.KeyEvent.META_ALT_ON
+import android.view.KeyEvent.META_CTRL_ON
+import android.view.KeyEvent.META_META_ON
+import android.view.KeyEvent.META_SHIFT_ON
+import android.view.KeyboardShortcutGroup
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.keyboard.shortcut.data.model.shortcutInfo
+import com.android.systemui.res.R
+import javax.inject.Inject
+
+class MultitaskingShortcutsSource @Inject constructor(@Main private val resources: Resources) :
+    KeyboardShortcutGroupsSource {
+
+    override suspend fun shortcutGroups(deviceId: Int) =
+        listOf(
+            KeyboardShortcutGroup(
+                resources.getString(R.string.shortcutHelper_category_recent_apps),
+                recentsShortcuts()
+            ),
+            KeyboardShortcutGroup(
+                resources.getString(R.string.shortcutHelper_category_split_screen),
+                splitScreenShortcuts()
+            )
+        )
+
+    private fun splitScreenShortcuts() =
+        listOf(
+            //  Enter Split screen with current app to RHS:
+            //   - Meta + Ctrl + Right arrow
+            shortcutInfo(resources.getString(R.string.system_multitasking_rhs)) {
+                command(META_META_ON or META_CTRL_ON, KEYCODE_DPAD_RIGHT)
+            },
+            //  Enter Split screen with current app to LHS:
+            //   - Meta + Ctrl + Left arrow
+            shortcutInfo(resources.getString(R.string.system_multitasking_lhs)) {
+                command(META_META_ON or META_CTRL_ON, KEYCODE_DPAD_LEFT)
+            },
+            //  Switch from Split screen to full screen:
+            //   - Meta + Ctrl + Up arrow
+            shortcutInfo(resources.getString(R.string.system_multitasking_full_screen)) {
+                command(META_META_ON or META_CTRL_ON, KEYCODE_DPAD_UP)
+            },
+            //  Change split screen focus to RHS:
+            //   - Meta + Alt + Right arrow
+            shortcutInfo(resources.getString(R.string.system_multitasking_splitscreen_focus_rhs)) {
+                command(META_META_ON or META_ALT_ON, KEYCODE_DPAD_RIGHT)
+            },
+            //  Change split screen focus to LHS:
+            //   - Meta + Alt + Left arrow
+            shortcutInfo(resources.getString(R.string.system_multitasking_splitscreen_focus_rhs)) {
+                command(META_META_ON or META_ALT_ON, KEYCODE_DPAD_LEFT)
+            },
+        )
+
+    private fun recentsShortcuts() =
+        listOf(
+            // Cycle through recent apps (forward):
+            //  - Alt + Tab
+            shortcutInfo(resources.getString(R.string.group_system_cycle_forward)) {
+                command(META_ALT_ON, KEYCODE_TAB)
+            },
+            // Cycle through recent apps (back):
+            //  - Shift + Alt + Tab
+            shortcutInfo(resources.getString(R.string.group_system_cycle_back)) {
+                command(META_SHIFT_ON or META_ALT_ON, KEYCODE_TAB)
+            },
+        )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt
new file mode 100644
index 0000000..e55e339
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/SystemShortcutsSource.kt
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.data.source
+
+import android.content.res.Resources
+import android.view.KeyEvent.KEYCODE_A
+import android.view.KeyEvent.KEYCODE_DEL
+import android.view.KeyEvent.KEYCODE_DPAD_LEFT
+import android.view.KeyEvent.KEYCODE_ENTER
+import android.view.KeyEvent.KEYCODE_ESCAPE
+import android.view.KeyEvent.KEYCODE_H
+import android.view.KeyEvent.KEYCODE_I
+import android.view.KeyEvent.KEYCODE_L
+import android.view.KeyEvent.KEYCODE_N
+import android.view.KeyEvent.KEYCODE_S
+import android.view.KeyEvent.KEYCODE_SLASH
+import android.view.KeyEvent.KEYCODE_TAB
+import android.view.KeyEvent.META_CTRL_ON
+import android.view.KeyEvent.META_META_ON
+import android.view.KeyboardShortcutGroup
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.keyboard.shortcut.data.model.shortcutInfo
+import com.android.systemui.res.R
+import javax.inject.Inject
+
+class SystemShortcutsSource @Inject constructor(@Main private val resources: Resources) :
+    KeyboardShortcutGroupsSource {
+
+    override suspend fun shortcutGroups(deviceId: Int) =
+        listOf(
+            KeyboardShortcutGroup(
+                resources.getString(R.string.shortcut_helper_category_system_controls),
+                systemControlsShortcuts()
+            ),
+            KeyboardShortcutGroup(
+                resources.getString(R.string.shortcut_helper_category_system_apps),
+                systemAppsShortcuts()
+            )
+        )
+
+    private fun systemControlsShortcuts() =
+        listOf(
+            // Access list of all apps and search (i.e. Search/Launcher):
+            //  - Meta
+            shortcutInfo(resources.getString(R.string.group_system_access_all_apps_search)) {
+                command(META_META_ON)
+            },
+            // Access home screen:
+            //  - Meta + H
+            //  - Meta + Enter
+            shortcutInfo(resources.getString(R.string.group_system_access_home_screen)) {
+                command(META_META_ON, KEYCODE_H)
+            },
+            shortcutInfo(resources.getString(R.string.group_system_access_home_screen)) {
+                command(META_META_ON, KEYCODE_ENTER)
+            },
+            // Overview of open apps:
+            //  - Meta + Tab
+            shortcutInfo(resources.getString(R.string.group_system_overview_open_apps)) {
+                command(META_META_ON, KEYCODE_TAB)
+            },
+            // Back: go back to previous state (back button)
+            //  - Meta + Escape OR
+            //  - Meta + Backspace OR
+            //  - Meta + Left arrow
+            shortcutInfo(resources.getString(R.string.group_system_go_back)) {
+                command(META_META_ON, KEYCODE_ESCAPE)
+            },
+            shortcutInfo(resources.getString(R.string.group_system_go_back)) {
+                command(META_META_ON, KEYCODE_DEL)
+            },
+            shortcutInfo(resources.getString(R.string.group_system_go_back)) {
+                command(META_META_ON, KEYCODE_DPAD_LEFT)
+            },
+            // Take a full screenshot:
+            //  - Meta + Ctrl + S
+            shortcutInfo(resources.getString(R.string.group_system_full_screenshot)) {
+                command(META_META_ON or META_CTRL_ON, KEYCODE_S)
+            },
+            // Access list of system / apps shortcuts:
+            //  - Meta + /
+            shortcutInfo(resources.getString(R.string.group_system_access_system_app_shortcuts)) {
+                command(META_META_ON, KEYCODE_SLASH)
+            },
+            // Access notification shade:
+            //  - Meta + N
+            shortcutInfo(resources.getString(R.string.group_system_access_notification_shade)) {
+                command(META_META_ON, KEYCODE_N)
+            },
+            // Lock screen:
+            //  - Meta + L
+            shortcutInfo(resources.getString(R.string.group_system_lock_screen)) {
+                command(META_META_ON, KEYCODE_L)
+            },
+        )
+
+    private fun systemAppsShortcuts() =
+        listOf(
+            // Pull up Notes app for quick memo:
+            //  - Meta + Ctrl + N
+            shortcutInfo(resources.getString(R.string.group_system_quick_memo)) {
+                command(META_META_ON or META_CTRL_ON, KEYCODE_N)
+            },
+            // Access system settings:
+            //  - Meta + I
+            shortcutInfo(resources.getString(R.string.group_system_access_system_settings)) {
+                command(META_META_ON, KEYCODE_I)
+            },
+            // Access Assistant:
+            //  - Meta + A
+            shortcutInfo(resources.getString(R.string.group_system_access_google_assistant)) {
+                command(META_META_ON, KEYCODE_A)
+            },
+        )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt
new file mode 100644
index 0000000..d41d21a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractor.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperCategoriesRepository
+import com.android.systemui.keyboard.shortcut.shared.model.Shortcut
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+
+@SysUISingleton
+class ShortcutHelperCategoriesInteractor
+@Inject
+constructor(
+    categoriesRepository: ShortcutHelperCategoriesRepository,
+) {
+
+    val shortcutCategories: Flow<List<ShortcutCategory>> =
+        combine(
+            categoriesRepository.systemShortcutsCategory,
+            categoriesRepository.multitaskingShortcutsCategory,
+            categoriesRepository.imeShortcutsCategory,
+            categoriesRepository.appCategoriesShortcutsCategory,
+        ) { shortcutCategories ->
+            shortcutCategories.filterNotNull().map { groupSubCategoriesInCategory(it) }
+        }
+
+    private fun groupSubCategoriesInCategory(shortcutCategory: ShortcutCategory): ShortcutCategory {
+        val subCategoriesWithGroupedShortcuts =
+            shortcutCategory.subCategories.map {
+                ShortcutSubCategory(
+                    label = it.label,
+                    shortcuts = groupShortcutsInSubcategory(it.shortcuts)
+                )
+            }
+        return ShortcutCategory(
+            type = shortcutCategory.type,
+            subCategories = subCategoriesWithGroupedShortcuts
+        )
+    }
+
+    private fun groupShortcutsInSubcategory(shortcuts: List<Shortcut>) =
+        shortcuts
+            .groupBy { it.label }
+            .entries
+            .map { (commonLabel, groupedShortcuts) ->
+                Shortcut(
+                    label = commonLabel,
+                    icon = groupedShortcuts.firstOrNull()?.icon,
+                    commands = groupedShortcuts.flatMap { it.commands }
+                )
+            }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperInteractor.kt
deleted file mode 100644
index 44f1c1e..0000000
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperInteractor.kt
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.keyboard.shortcut.domain.interactor
-
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperRepository
-import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState
-import com.android.systemui.model.SysUiState
-import com.android.systemui.settings.DisplayTracker
-import com.android.systemui.shared.system.QuickStepContract
-import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.launch
-
-@SysUISingleton
-class ShortcutHelperInteractor
-@Inject
-constructor(
-    private val displayTracker: DisplayTracker,
-    @Background private val backgroundScope: CoroutineScope,
-    private val sysUiState: SysUiState,
-    private val repository: ShortcutHelperRepository
-) {
-
-    val state: Flow<ShortcutHelperState> = repository.state
-
-    fun onViewClosed() {
-        repository.hide()
-        setSysUiStateFlagEnabled(false)
-    }
-
-    fun onViewOpened() {
-        setSysUiStateFlagEnabled(true)
-    }
-
-    private fun setSysUiStateFlagEnabled(enabled: Boolean) {
-        backgroundScope.launch {
-            sysUiState
-                .setFlag(QuickStepContract.SYSUI_STATE_SHORTCUT_HELPER_SHOWING, enabled)
-                .commitUpdate(displayTracker.defaultDisplayId)
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperStateInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperStateInteractor.kt
new file mode 100644
index 0000000..299628e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperStateInteractor.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperStateRepository
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState
+import com.android.systemui.model.SysUiState
+import com.android.systemui.settings.DisplayTracker
+import com.android.systemui.shared.system.QuickStepContract
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.launch
+
+@SysUISingleton
+class ShortcutHelperStateInteractor
+@Inject
+constructor(
+    private val displayTracker: DisplayTracker,
+    @Background private val backgroundScope: CoroutineScope,
+    private val sysUiState: SysUiState,
+    private val repository: ShortcutHelperStateRepository
+) {
+
+    val state: Flow<ShortcutHelperState> = repository.state.asStateFlow()
+
+    fun onViewClosed() {
+        repository.hide()
+        setSysUiStateFlagEnabled(false)
+    }
+
+    fun onViewOpened() {
+        setSysUiStateFlagEnabled(true)
+    }
+
+    private fun setSysUiStateFlagEnabled(enabled: Boolean) {
+        backgroundScope.launch {
+            sysUiState
+                .setFlag(QuickStepContract.SYSUI_STATE_SHORTCUT_HELPER_SHOWING, enabled)
+                .commitUpdate(displayTracker.defaultDisplayId)
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/AppCategoriesShortcuts.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/AppCategoriesShortcuts.kt
new file mode 100644
index 0000000..b105ff6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/AppCategoriesShortcuts.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.qualifiers
+
+import javax.inject.Qualifier
+
+@Qualifier annotation class AppCategoriesShortcuts
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/InputShortcuts.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/InputShortcuts.kt
new file mode 100644
index 0000000..f8a4a49
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/InputShortcuts.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.qualifiers
+
+import javax.inject.Qualifier
+
+@Qualifier annotation class InputShortcuts
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/MultitaskingShortcuts.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/MultitaskingShortcuts.kt
new file mode 100644
index 0000000..479299c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/MultitaskingShortcuts.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.qualifiers
+
+import javax.inject.Qualifier
+
+@Qualifier annotation class MultitaskingShortcuts
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/SystemShortcuts.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/SystemShortcuts.kt
new file mode 100644
index 0000000..1bcc2b8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/qualifiers/SystemShortcuts.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.qualifiers
+
+import javax.inject.Qualifier
+
+@Qualifier annotation class SystemShortcuts
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/Shortcut.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/Shortcut.kt
new file mode 100644
index 0000000..5f8570c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/Shortcut.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.shared.model
+
+data class Shortcut(
+    val label: String,
+    val commands: List<ShortcutCommand>,
+    val icon: ShortcutIcon? = null,
+)
+
+class ShortcutBuilder(private val label: String) {
+    val commands = mutableListOf<ShortcutCommand>()
+
+    fun command(builder: ShortcutCommandBuilder.() -> Unit) {
+        commands += ShortcutCommandBuilder().apply(builder).build()
+    }
+
+    fun build() = Shortcut(label, commands)
+}
+
+fun shortcut(label: String, block: ShortcutBuilder.() -> Unit): Shortcut =
+    ShortcutBuilder(label).apply(block).build()
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt
new file mode 100644
index 0000000..63e167a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCategory.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.shared.model
+
+enum class ShortcutCategoryType {
+    SYSTEM,
+    MULTI_TASKING,
+    IME,
+    APP_CATEGORIES,
+}
+
+data class ShortcutCategory(
+    val type: ShortcutCategoryType,
+    val subCategories: List<ShortcutSubCategory>
+)
+
+class ShortcutCategoryBuilder(val type: ShortcutCategoryType) {
+    private val subCategories = mutableListOf<ShortcutSubCategory>()
+
+    fun subCategory(label: String, builder: ShortcutSubCategoryBuilder.() -> Unit) {
+        subCategories += ShortcutSubCategoryBuilder(label).apply(builder).build()
+    }
+
+    fun build() = ShortcutCategory(type, subCategories)
+}
+
+fun shortcutCategory(type: ShortcutCategoryType, block: ShortcutCategoryBuilder.() -> Unit) =
+    ShortcutCategoryBuilder(type).apply(block).build()
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCommand.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCommand.kt
new file mode 100644
index 0000000..e5b8096
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutCommand.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.shared.model
+
+import androidx.annotation.DrawableRes
+
+data class ShortcutCommand(val keys: List<ShortcutKey>)
+
+class ShortcutCommandBuilder {
+    private val keys = mutableListOf<ShortcutKey>()
+
+    fun key(text: String) {
+        keys += ShortcutKey.Text(text)
+    }
+
+    fun key(@DrawableRes drawableResId: Int) {
+        keys += ShortcutKey.Icon(drawableResId)
+    }
+
+    fun build() = ShortcutCommand(keys)
+}
+
+fun shortcutCommand(block: ShortcutCommandBuilder.() -> Unit) =
+    ShortcutCommandBuilder().apply(block).build()
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutHelperState.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutHelperState.kt
index d22d6c8..1f22141 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutHelperState.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutHelperState.kt
@@ -19,5 +19,5 @@
 sealed interface ShortcutHelperState {
     data object Inactive : ShortcutHelperState
 
-    data class Active(val deviceId: Int? = null) : ShortcutHelperState
+    data class Active(val deviceId: Int) : ShortcutHelperState
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutIcon.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutIcon.kt
new file mode 100644
index 0000000..8b720a5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutIcon.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.shared.model
+
+data class ShortcutIcon(val packageName: String, val resourceId: Int)
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutKey.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutKey.kt
new file mode 100644
index 0000000..1abb78c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutKey.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.shared.model
+
+import androidx.annotation.DrawableRes
+
+sealed interface ShortcutKey {
+    data class Text(val value: String) : ShortcutKey
+
+    data class Icon(@DrawableRes val drawableResId: Int) : ShortcutKey
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutSubCategory.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutSubCategory.kt
new file mode 100644
index 0000000..1401678
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutSubCategory.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.shared.model
+
+data class ShortcutSubCategory(val label: String, val shortcuts: List<Shortcut>)
+
+class ShortcutSubCategoryBuilder(val label: String) {
+    private val shortcuts = mutableListOf<Shortcut>()
+
+    fun shortcut(label: String, builder: ShortcutBuilder.() -> Unit) {
+        shortcuts += ShortcutBuilder(label).apply(builder).build()
+    }
+
+    fun build() = ShortcutSubCategory(label, shortcuts)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
index 271e79b..3b037bc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelper.kt
@@ -16,8 +16,10 @@
 
 package com.android.systemui.keyboard.shortcut.ui.composable
 
+import android.graphics.drawable.Icon
 import androidx.compose.animation.AnimatedVisibility
 import androidx.compose.animation.core.animateFloatAsState
+import androidx.compose.foundation.Image
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
@@ -43,8 +45,12 @@
 import androidx.compose.foundation.verticalScroll
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.automirrored.filled.OpenInNew
+import androidx.compose.material.icons.filled.Apps
 import androidx.compose.material.icons.filled.ExpandMore
+import androidx.compose.material.icons.filled.Keyboard
 import androidx.compose.material.icons.filled.Search
+import androidx.compose.material.icons.filled.Tv
+import androidx.compose.material.icons.filled.VerticalSplit
 import androidx.compose.material3.CenterAlignedTopAppBar
 import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.material3.HorizontalDivider
@@ -72,7 +78,9 @@
 import androidx.compose.ui.graphics.graphicsLayer
 import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.input.nestedscroll.nestedScroll
+import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
+import androidx.compose.ui.res.painterResource
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.semantics.Role
 import androidx.compose.ui.semantics.role
@@ -82,20 +90,45 @@
 import androidx.compose.ui.unit.sp
 import androidx.compose.ui.util.fastForEach
 import androidx.compose.ui.util.fastForEachIndexed
+import com.android.compose.ui.graphics.painter.rememberDrawablePainter
 import com.android.compose.windowsizeclass.LocalWindowSizeClass
+import com.android.systemui.keyboard.shortcut.shared.model.Shortcut
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutIcon
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
+import com.android.systemui.keyboard.shortcut.ui.model.ShortcutsUiState
 import com.android.systemui.res.R
 
 @Composable
 fun ShortcutHelper(
     onKeyboardSettingsClicked: () -> Unit,
     modifier: Modifier = Modifier,
-    categories: List<ShortcutHelperCategory> = ShortcutHelperTemporaryData.categories,
+    shortcutsUiState: ShortcutsUiState,
     useSinglePane: @Composable () -> Boolean = { shouldUseSinglePane() },
 ) {
-    if (useSinglePane()) {
-        ShortcutHelperSinglePane(modifier, categories, onKeyboardSettingsClicked)
-    } else {
-        ShortcutHelperTwoPane(modifier, categories, onKeyboardSettingsClicked)
+    when (shortcutsUiState) {
+        is ShortcutsUiState.Active -> {
+            if (useSinglePane()) {
+                ShortcutHelperSinglePane(
+                    modifier,
+                    shortcutsUiState.shortcutCategories,
+                    onKeyboardSettingsClicked
+                )
+            } else {
+                ShortcutHelperTwoPane(
+                    modifier,
+                    shortcutsUiState.shortcutCategories,
+                    shortcutsUiState.defaultSelectedCategory,
+                    onKeyboardSettingsClicked
+                )
+            }
+        }
+        is ShortcutsUiState.Inactive -> {
+            // No-op for now.
+        }
     }
 }
 
@@ -107,7 +140,7 @@
 @Composable
 private fun ShortcutHelperSinglePane(
     modifier: Modifier = Modifier,
-    categories: List<ShortcutHelperCategory>,
+    categories: List<ShortcutCategory>,
     onKeyboardSettingsClicked: () -> Unit,
 ) {
     Column(
@@ -129,9 +162,9 @@
 
 @Composable
 private fun CategoriesPanelSinglePane(
-    categories: List<ShortcutHelperCategory>,
+    categories: List<ShortcutCategory>,
 ) {
-    var expandedCategory by remember { mutableStateOf<ShortcutHelperCategory?>(null) }
+    var expandedCategory by remember { mutableStateOf<ShortcutCategory?>(null) }
     Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
         categories.fastForEachIndexed { index, category ->
             val isExpanded = expandedCategory == category
@@ -162,7 +195,7 @@
 
 @Composable
 private fun CategoryItemSinglePane(
-    category: ShortcutHelperCategory,
+    category: ShortcutCategory,
     isExpanded: Boolean,
     onClick: () -> Unit,
     shape: Shape,
@@ -188,6 +221,24 @@
     }
 }
 
+private val ShortcutCategory.icon: ImageVector
+    get() =
+        when (type) {
+            ShortcutCategoryType.SYSTEM -> Icons.Default.Tv
+            ShortcutCategoryType.MULTI_TASKING -> Icons.Default.VerticalSplit
+            ShortcutCategoryType.IME -> Icons.Default.Keyboard
+            ShortcutCategoryType.APP_CATEGORIES -> Icons.Default.Apps
+        }
+
+private val ShortcutCategory.labelResId: Int
+    get() =
+        when (type) {
+            ShortcutCategoryType.SYSTEM -> R.string.shortcut_helper_category_system
+            ShortcutCategoryType.MULTI_TASKING -> R.string.shortcut_helper_category_multitasking
+            ShortcutCategoryType.IME -> R.string.shortcut_helper_category_input
+            ShortcutCategoryType.APP_CATEGORIES -> R.string.shortcut_helper_category_app_shortcuts
+        }
+
 @Composable
 private fun RotatingExpandCollapseIcon(isExpanded: Boolean) {
     val expandIconRotationDegrees by
@@ -219,7 +270,7 @@
 }
 
 @Composable
-private fun ShortcutCategoryDetailsSinglePane(category: ShortcutHelperCategory) {
+private fun ShortcutCategoryDetailsSinglePane(category: ShortcutCategory) {
     Column(Modifier.padding(horizontal = 16.dp)) {
         category.subCategories.fastForEach { subCategory ->
             ShortcutSubCategorySinglePane(subCategory)
@@ -228,7 +279,7 @@
 }
 
 @Composable
-private fun ShortcutSubCategorySinglePane(subCategory: SubCategory) {
+private fun ShortcutSubCategorySinglePane(subCategory: ShortcutSubCategory) {
     // This @Composable is expected to be in a Column.
     SubCategoryTitle(subCategory.label)
     subCategory.shortcuts.fastForEachIndexed { index, shortcut ->
@@ -251,10 +302,12 @@
 @Composable
 private fun ShortcutHelperTwoPane(
     modifier: Modifier = Modifier,
-    categories: List<ShortcutHelperCategory>,
+    categories: List<ShortcutCategory>,
+    defaultSelectedCategory: ShortcutCategoryType,
     onKeyboardSettingsClicked: () -> Unit,
 ) {
-    var selectedCategory by remember { mutableStateOf(categories.first()) }
+    var selectedCategoryType by remember { mutableStateOf(defaultSelectedCategory) }
+    val selectedCategory = categories.first { it.type == selectedCategoryType }
     Column(modifier = modifier.fillMaxSize().padding(start = 24.dp, end = 24.dp, top = 26.dp)) {
         TitleBar()
         Spacer(modifier = Modifier.height(12.dp))
@@ -262,8 +315,8 @@
             StartSidePanel(
                 modifier = Modifier.fillMaxWidth(fraction = 0.32f),
                 categories = categories,
-                selectedCategory = selectedCategory,
-                onCategoryClicked = { selectedCategory = it },
+                selectedCategory = selectedCategoryType,
+                onCategoryClicked = { selectedCategoryType = it.type },
                 onKeyboardSettingsClicked = onKeyboardSettingsClicked,
             )
             Spacer(modifier = Modifier.width(24.dp))
@@ -273,7 +326,7 @@
 }
 
 @Composable
-private fun EndSidePanel(modifier: Modifier, category: ShortcutHelperCategory) {
+private fun EndSidePanel(modifier: Modifier, category: ShortcutCategory) {
     LazyColumn(modifier.nestedScroll(rememberNestedScrollInteropConnection())) {
         items(items = category.subCategories, key = { item -> item.label }) {
             SubCategoryContainerDualPane(it)
@@ -283,7 +336,7 @@
 }
 
 @Composable
-private fun SubCategoryContainerDualPane(subCategory: SubCategory) {
+private fun SubCategoryContainerDualPane(subCategory: ShortcutSubCategory) {
     Surface(
         modifier = Modifier.fillMaxWidth(),
         shape = RoundedCornerShape(28.dp),
@@ -314,17 +367,47 @@
 @Composable
 private fun ShortcutViewDualPane(shortcut: Shortcut) {
     Row(Modifier.padding(vertical = 16.dp)) {
-        ShortcutDescriptionText(
-            modifier = Modifier.weight(0.25f).align(Alignment.CenterVertically),
-            shortcut = shortcut,
-        )
+        Row(
+            modifier = Modifier.width(160.dp).align(Alignment.CenterVertically),
+            horizontalArrangement = Arrangement.spacedBy(16.dp),
+            verticalAlignment = Alignment.CenterVertically,
+        ) {
+            if (shortcut.icon != null) {
+                ShortcutIcon(
+                    shortcut.icon,
+                    modifier = Modifier.size(36.dp),
+                )
+            }
+            ShortcutDescriptionText(
+                shortcut = shortcut,
+            )
+        }
+        Spacer(modifier = Modifier.width(16.dp))
         ShortcutKeyCombinations(
-            modifier = Modifier.weight(0.75f),
+            modifier = Modifier.weight(1f),
             shortcut = shortcut,
         )
     }
 }
 
+@Composable
+fun ShortcutIcon(
+    icon: ShortcutIcon,
+    modifier: Modifier = Modifier,
+    contentDescription: String? = null,
+) {
+    val context = LocalContext.current
+    val drawable =
+        remember(icon.packageName, icon.resourceId) {
+            Icon.createWithResource(icon.packageName, icon.resourceId).loadDrawable(context)
+        } ?: return
+    Image(
+        painter = rememberDrawablePainter(drawable),
+        contentDescription = contentDescription,
+        modifier = modifier,
+    )
+}
+
 @OptIn(ExperimentalLayoutApi::class)
 @Composable
 private fun ShortcutKeyCombinations(
@@ -343,16 +426,17 @@
 
 @Composable
 private fun ShortcutCommand(command: ShortcutCommand) {
-    // This @Composable is expected to be in a Row or FlowRow.
-    command.keys.forEachIndexed { keyIndex, key ->
-        if (keyIndex > 0) {
-            Spacer(Modifier.width(4.dp))
-        }
-        ShortcutKeyContainer {
-            if (key is ShortcutKey.Text) {
-                ShortcutTextKey(key)
-            } else if (key is ShortcutKey.Icon) {
-                ShortcutIconKey(key)
+    Row {
+        command.keys.forEachIndexed { keyIndex, key ->
+            if (keyIndex > 0) {
+                Spacer(Modifier.width(4.dp))
+            }
+            ShortcutKeyContainer {
+                if (key is ShortcutKey.Text) {
+                    ShortcutTextKey(key)
+                } else if (key is ShortcutKey.Icon) {
+                    ShortcutIconKey(key)
+                }
             }
         }
     }
@@ -384,7 +468,7 @@
 @Composable
 private fun BoxScope.ShortcutIconKey(key: ShortcutKey.Icon) {
     Icon(
-        imageVector = key.value,
+        painter = painterResource(key.drawableResId),
         contentDescription = null,
         modifier = Modifier.align(Alignment.Center).padding(6.dp)
     )
@@ -418,10 +502,10 @@
 @Composable
 private fun StartSidePanel(
     modifier: Modifier,
-    categories: List<ShortcutHelperCategory>,
+    categories: List<ShortcutCategory>,
     onKeyboardSettingsClicked: () -> Unit,
-    selectedCategory: ShortcutHelperCategory,
-    onCategoryClicked: (ShortcutHelperCategory) -> Unit,
+    selectedCategory: ShortcutCategoryType,
+    onCategoryClicked: (ShortcutCategory) -> Unit,
 ) {
     Column(modifier) {
         ShortcutsSearchBar()
@@ -434,16 +518,16 @@
 
 @Composable
 private fun CategoriesPanelTwoPane(
-    categories: List<ShortcutHelperCategory>,
-    selectedCategory: ShortcutHelperCategory,
-    onCategoryClicked: (ShortcutHelperCategory) -> Unit
+    categories: List<ShortcutCategory>,
+    selectedCategory: ShortcutCategoryType,
+    onCategoryClicked: (ShortcutCategory) -> Unit
 ) {
     Column {
         categories.fastForEach {
             CategoryItemTwoPane(
                 label = stringResource(it.labelResId),
                 icon = it.icon,
-                selected = selectedCategory == it,
+                selected = selectedCategory == it.type,
                 onClick = { onCategoryClicked(it) }
             )
         }
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelperTemporaryData.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelperTemporaryData.kt
deleted file mode 100644
index fa2388f..0000000
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/ShortcutHelperTemporaryData.kt
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.keyboard.shortcut.ui.composable
-
-import androidx.annotation.StringRes
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.Accessibility
-import androidx.compose.material.icons.filled.Apps
-import androidx.compose.material.icons.filled.ArrowBackIosNew
-import androidx.compose.material.icons.filled.Keyboard
-import androidx.compose.material.icons.filled.KeyboardCommandKey
-import androidx.compose.material.icons.filled.RadioButtonUnchecked
-import androidx.compose.material.icons.filled.Tv
-import androidx.compose.material.icons.filled.VerticalSplit
-import androidx.compose.ui.graphics.vector.ImageVector
-import com.android.systemui.res.R
-
-/** Temporary data classes and data below just to populate the UI. */
-data class ShortcutHelperCategory(
-    @StringRes val labelResId: Int,
-    val icon: ImageVector,
-    val subCategories: List<SubCategory>,
-)
-
-data class SubCategory(
-    val label: String,
-    val shortcuts: List<Shortcut>,
-)
-
-data class Shortcut(val label: String, val commands: List<ShortcutCommand>)
-
-data class ShortcutCommand(val keys: List<ShortcutKey>)
-
-sealed interface ShortcutKey {
-    data class Text(val value: String) : ShortcutKey
-
-    data class Icon(val value: ImageVector) : ShortcutKey
-}
-
-// DSL Builder Functions
-private fun shortcutHelperCategory(
-    labelResId: Int,
-    icon: ImageVector,
-    block: ShortcutHelperCategoryBuilder.() -> Unit
-): ShortcutHelperCategory = ShortcutHelperCategoryBuilder(labelResId, icon).apply(block).build()
-
-private fun ShortcutHelperCategoryBuilder.subCategory(
-    label: String,
-    block: SubCategoryBuilder.() -> Unit
-) {
-    subCategories.add(SubCategoryBuilder(label).apply(block).build())
-}
-
-private fun SubCategoryBuilder.shortcut(label: String, block: ShortcutBuilder.() -> Unit) {
-    shortcuts.add(ShortcutBuilder(label).apply(block).build())
-}
-
-private fun ShortcutBuilder.command(block: ShortcutCommandBuilder.() -> Unit) {
-    commands.add(ShortcutCommandBuilder().apply(block).build())
-}
-
-private fun ShortcutCommandBuilder.key(value: String) {
-    keys.add(ShortcutKey.Text(value))
-}
-
-private fun ShortcutCommandBuilder.key(value: ImageVector) {
-    keys.add(ShortcutKey.Icon(value))
-}
-
-private class ShortcutHelperCategoryBuilder(
-    private val labelResId: Int,
-    private val icon: ImageVector
-) {
-    val subCategories = mutableListOf<SubCategory>()
-
-    fun build() = ShortcutHelperCategory(labelResId, icon, subCategories)
-}
-
-private class SubCategoryBuilder(private val label: String) {
-    val shortcuts = mutableListOf<Shortcut>()
-
-    fun build() = SubCategory(label, shortcuts)
-}
-
-private class ShortcutBuilder(private val label: String) {
-    val commands = mutableListOf<ShortcutCommand>()
-
-    fun build() = Shortcut(label, commands)
-}
-
-private class ShortcutCommandBuilder {
-    val keys = mutableListOf<ShortcutKey>()
-
-    fun build() = ShortcutCommand(keys)
-}
-
-object ShortcutHelperTemporaryData {
-
-    // Some shortcuts and their strings below are made up just to populate the UI for now.
-    // For this reason they are not in translatable resources yet.
-    val categories =
-        listOf(
-            shortcutHelperCategory(R.string.shortcut_helper_category_system, Icons.Default.Tv) {
-                subCategory("System controls") {
-                    shortcut("Go to home screen") {
-                        command { key(Icons.Default.RadioButtonUnchecked) }
-                        command {
-                            key(Icons.Default.KeyboardCommandKey)
-                            key("H")
-                        }
-                        command {
-                            key(Icons.Default.KeyboardCommandKey)
-                            key("Return")
-                        }
-                    }
-                    shortcut("View recent apps") {
-                        command {
-                            key(Icons.Default.KeyboardCommandKey)
-                            key("Tab")
-                        }
-                    }
-                    shortcut("All apps search") {
-                        command { key(Icons.Default.KeyboardCommandKey) }
-                    }
-                }
-                subCategory("System apps") {
-                    shortcut("Go back") {
-                        command { key(Icons.Default.ArrowBackIosNew) }
-                        command {
-                            key(Icons.Default.KeyboardCommandKey)
-                            key("Left arrow")
-                        }
-                        command {
-                            key(Icons.Default.KeyboardCommandKey)
-                            key("ESC")
-                        }
-                        command {
-                            key(Icons.Default.KeyboardCommandKey)
-                            key("Backspace")
-                        }
-                    }
-                    shortcut("View notifications") {
-                        command {
-                            key(Icons.Default.KeyboardCommandKey)
-                            key("N")
-                        }
-                    }
-                    shortcut("Take a screenshot") {
-                        command { key(Icons.Default.KeyboardCommandKey) }
-                        command { key("CTRL") }
-                        command { key("S") }
-                    }
-                    shortcut("Open Settings") {
-                        command {
-                            key(Icons.Default.KeyboardCommandKey)
-                            key("I")
-                        }
-                    }
-                }
-            },
-            shortcutHelperCategory(
-                R.string.shortcut_helper_category_multitasking,
-                Icons.Default.VerticalSplit
-            ) {
-                subCategory("Multitasking & windows") {
-                    shortcut("Take a screenshot") {
-                        command { key(Icons.Default.KeyboardCommandKey) }
-                        command { key("CTRL") }
-                        command { key("S") }
-                    }
-                }
-            },
-            shortcutHelperCategory(
-                R.string.shortcut_helper_category_input,
-                Icons.Default.Keyboard
-            ) {
-                subCategory("Input") {
-                    shortcut("Open Settings") {
-                        command {
-                            key(Icons.Default.KeyboardCommandKey)
-                            key("I")
-                        }
-                    }
-                    shortcut("View notifications") {
-                        command {
-                            key(Icons.Default.KeyboardCommandKey)
-                            key("N")
-                        }
-                    }
-                }
-            },
-            shortcutHelperCategory(
-                R.string.shortcut_helper_category_app_shortcuts,
-                Icons.Default.Apps
-            ) {
-                subCategory("App shortcuts") {
-                    shortcut("Open Settings") {
-                        command {
-                            key(Icons.Default.KeyboardCommandKey)
-                            key("I")
-                        }
-                    }
-                    shortcut("Go back") {
-                        command { key(Icons.Default.ArrowBackIosNew) }
-                        command {
-                            key(Icons.Default.KeyboardCommandKey)
-                            key("Left arrow")
-                        }
-                        command {
-                            key(Icons.Default.KeyboardCommandKey)
-                            key("ESC")
-                        }
-                        command {
-                            key(Icons.Default.KeyboardCommandKey)
-                            key("Backspace")
-                        }
-                    }
-                }
-            },
-            shortcutHelperCategory(
-                R.string.shortcut_helper_category_a11y,
-                Icons.Default.Accessibility
-            ) {
-                subCategory("Accessibility shortcuts") {
-                    shortcut("View recent apps") {
-                        command {
-                            key(Icons.Default.KeyboardCommandKey)
-                            key("Tab")
-                        }
-                    }
-                    shortcut("All apps search") {
-                        command { key(Icons.Default.KeyboardCommandKey) }
-                    }
-                }
-            }
-        )
-}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutsUiState.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutsUiState.kt
new file mode 100644
index 0000000..daafc3f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/model/ShortcutsUiState.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.ui.model
+
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
+
+sealed interface ShortcutsUiState {
+
+    data class Active(
+        val shortcutCategories: List<ShortcutCategory>,
+        val defaultSelectedCategory: ShortcutCategoryType,
+    ) : ShortcutsUiState
+
+    data object Inactive : ShortcutsUiState
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/view/ShortcutHelperActivity.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/view/ShortcutHelperActivity.kt
index 04fa749..d0e3ab4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/view/ShortcutHelperActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/view/ShortcutHelperActivity.kt
@@ -26,8 +26,10 @@
 import androidx.activity.BackEventCompat
 import androidx.activity.ComponentActivity
 import androidx.activity.OnBackPressedCallback
+import androidx.compose.runtime.getValue
 import androidx.compose.ui.platform.ComposeView
 import androidx.core.view.updatePadding
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import androidx.lifecycle.flowWithLifecycle
 import androidx.lifecycle.lifecycleScope
 import com.android.compose.theme.PlatformTheme
@@ -78,7 +80,9 @@
         requireViewById<ComposeView>(R.id.shortcut_helper_compose_container).apply {
             setContent {
                 PlatformTheme {
+                    val shortcutsUiState by viewModel.shortcutsUiState.collectAsStateWithLifecycle()
                     ShortcutHelper(
+                        shortcutsUiState = shortcutsUiState,
                         onKeyboardSettingsClicked = ::onKeyboardSettingsClicked,
                     )
                 }
@@ -123,7 +127,7 @@
             resources.getFloat(R.dimen.shortcut_helper_screen_width_fraction)
         // maxWidth needs to be set before the sheet is drawn, otherwise the call will have no
         // effect.
-        val screenWidth = resources.displayMetrics.widthPixels
+        val screenWidth = windowManager.maximumWindowMetrics.bounds.width()
         bottomSheetBehavior.maxWidth = (sheetScreenWidthFraction * screenWidth).toInt()
     }
 
@@ -132,7 +136,7 @@
             val safeDrawingInsets = insets.safeDrawing
             // Make sure the bottom sheet is not covered by the status bar.
             bottomSheetBehavior.maxHeight =
-                resources.displayMetrics.heightPixels - safeDrawingInsets.top
+                windowManager.maximumWindowMetrics.bounds.height() - safeDrawingInsets.top
             // Make sure the contents inside of the bottom sheet are not hidden by system bars, or
             // cutouts.
             bottomSheet.updatePadding(
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
index c623f5c..e602cad 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
@@ -17,32 +17,57 @@
 package com.android.systemui.keyboard.shortcut.ui.viewmodel
 
 import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutHelperInteractor
+import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutHelperCategoriesInteractor
+import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutHelperStateInteractor
 import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState
+import com.android.systemui.keyboard.shortcut.ui.model.ShortcutsUiState
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
 
 class ShortcutHelperViewModel
 @Inject
 constructor(
+    @Background private val backgroundScope: CoroutineScope,
     @Background private val backgroundDispatcher: CoroutineDispatcher,
-    private val interactor: ShortcutHelperInteractor
+    private val stateInteractor: ShortcutHelperStateInteractor,
+    categoriesInteractor: ShortcutHelperCategoriesInteractor,
 ) {
 
     val shouldShow =
-        interactor.state
+        stateInteractor.state
             .map { it is ShortcutHelperState.Active }
             .distinctUntilChanged()
             .flowOn(backgroundDispatcher)
 
+    val shortcutsUiState =
+        categoriesInteractor.shortcutCategories
+            .map {
+                if (it.isEmpty()) {
+                    ShortcutsUiState.Inactive
+                } else {
+                    ShortcutsUiState.Active(
+                        shortcutCategories = it,
+                        defaultSelectedCategory = it.first().type,
+                    )
+                }
+            }
+            .stateIn(
+                scope = backgroundScope,
+                started = SharingStarted.Lazily,
+                initialValue = ShortcutsUiState.Inactive
+            )
+
     fun onViewClosed() {
-        interactor.onViewClosed()
+        stateInteractor.onViewClosed()
     }
 
     fun onViewOpened() {
-        interactor.onViewOpened()
+        stateInteractor.onViewOpened()
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 209bc7a..9f33113 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -81,6 +81,7 @@
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.keyguard.domain.interactor.KeyguardEnabledInteractor;
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
+import com.android.systemui.keyguard.domain.interactor.KeyguardWakeDirectlyToGoneInteractor;
 import com.android.systemui.keyguard.ui.binder.KeyguardSurfaceBehindParamsApplier;
 import com.android.systemui.keyguard.ui.binder.KeyguardSurfaceBehindViewBinder;
 import com.android.systemui.keyguard.ui.binder.WindowManagerLockscreenVisibilityViewBinder;
@@ -89,6 +90,7 @@
 import com.android.systemui.power.domain.interactor.PowerInteractor;
 import com.android.systemui.power.shared.model.ScreenPowerState;
 import com.android.systemui.scene.domain.interactor.SceneInteractor;
+import com.android.systemui.scene.domain.startable.KeyguardStateCallbackStartable;
 import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.scene.shared.model.Scenes;
 import com.android.systemui.settings.DisplayTracker;
@@ -122,6 +124,7 @@
     private final KeyguardInteractor mKeyguardInteractor;
     private final Lazy<SceneInteractor> mSceneInteractorLazy;
     private final Executor mMainExecutor;
+    private final Lazy<KeyguardStateCallbackStartable> mKeyguardStateCallbackStartableLazy;
 
     private static RemoteAnimationTarget[] wrap(TransitionInfo info, boolean wallpapers,
             SurfaceControl.Transaction t, ArrayMap<SurfaceControl, SurfaceControl> leashMap,
@@ -315,7 +318,7 @@
 
     private final WindowManagerOcclusionManager mWmOcclusionManager;
     private final KeyguardEnabledInteractor mKeyguardEnabledInteractor;
-
+    private final KeyguardWakeDirectlyToGoneInteractor mKeyguardWakeDirectlyToGoneInteractor;
     private final Lazy<FoldGracePeriodProvider> mFoldGracePeriodProvider = new Lazy<>() {
         @Override
         public FoldGracePeriodProvider get() {
@@ -341,7 +344,9 @@
             Lazy<SceneInteractor> sceneInteractorLazy,
             @Main Executor mainExecutor,
             KeyguardInteractor keyguardInteractor,
-            KeyguardEnabledInteractor keyguardEnabledInteractor) {
+            KeyguardEnabledInteractor keyguardEnabledInteractor,
+            Lazy<KeyguardStateCallbackStartable> keyguardStateCallbackStartableLazy,
+            KeyguardWakeDirectlyToGoneInteractor keyguardWakeDirectlyToGoneInteractor) {
         super();
         mKeyguardViewMediator = keyguardViewMediator;
         mKeyguardLifecyclesDispatcher = keyguardLifecyclesDispatcher;
@@ -353,6 +358,7 @@
         mKeyguardInteractor = keyguardInteractor;
         mSceneInteractorLazy = sceneInteractorLazy;
         mMainExecutor = mainExecutor;
+        mKeyguardStateCallbackStartableLazy = keyguardStateCallbackStartableLazy;
 
         if (KeyguardWmStateRefactor.isEnabled()) {
             WindowManagerLockscreenVisibilityViewBinder.bind(
@@ -368,6 +374,7 @@
 
         mWmOcclusionManager = windowManagerOcclusionManager;
         mKeyguardEnabledInteractor = keyguardEnabledInteractor;
+        mKeyguardWakeDirectlyToGoneInteractor = keyguardWakeDirectlyToGoneInteractor;
     }
 
     @Override
@@ -440,7 +447,11 @@
         public void addStateMonitorCallback(IKeyguardStateCallback callback) {
             trace("addStateMonitorCallback");
             checkPermission();
-            mKeyguardViewMediator.addStateMonitorCallback(callback);
+            if (SceneContainerFlag.isEnabled()) {
+                mKeyguardStateCallbackStartableLazy.get().addCallback(callback);
+            } else {
+                mKeyguardViewMediator.addStateMonitorCallback(callback);
+            }
         }
 
         @Override // Binder interface
@@ -478,6 +489,7 @@
         public void onDreamingStarted() {
             trace("onDreamingStarted");
             checkPermission();
+            mKeyguardWakeDirectlyToGoneInteractor.onDreamingStarted();
             mKeyguardInteractor.setDreaming(true);
             mKeyguardViewMediator.onDreamingStarted();
         }
@@ -486,6 +498,7 @@
         public void onDreamingStopped() {
             trace("onDreamingStopped");
             checkPermission();
+            mKeyguardWakeDirectlyToGoneInteractor.onDreamingStopped();
             mKeyguardInteractor.setDreaming(false);
             mKeyguardViewMediator.onDreamingStopped();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index 00566c1..d1a8463 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -27,6 +27,7 @@
 import android.os.Handler
 import android.os.PowerManager
 import android.os.RemoteException
+import android.os.Trace
 import android.util.Log
 import android.view.RemoteAnimationTarget
 import android.view.SurfaceControl
@@ -39,7 +40,7 @@
 import com.android.internal.R
 import com.android.keyguard.KeyguardClockSwitchController
 import com.android.keyguard.KeyguardViewController
-import com.android.systemui.Flags.fastUnlockTransition
+import com.android.systemui.Flags.fasterUnlockTransition
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.flags.FeatureFlags
@@ -102,7 +103,14 @@
  * swiped away via a touch gesture, or when it's flinging expanded/collapsed after a swipe.
  */
 const val LEGACY_UNLOCK_ANIMATION_DURATION_MS = 200L
-const val UNLOCK_ANIMATION_DURATION_MS = 167L
+const val UNLOCK_ANIMATION_DURATION_MS = 300L
+
+/**
+ * If there are two different wallpapers on home and lock screen, duration and delay of the lock
+ * wallpaper fade out.
+ */
+const val LOCK_WALLPAPER_FADE_OUT_DURATION = 150L
+const val LOCK_WALLPAPER_FADE_OUT_START_DELAY = 150L
 
 /**
  * How long the in-window launcher icon animation takes. This is used if the launcher is underneath
@@ -115,23 +123,24 @@
 
 /**
  * How long to wait for the shade to get out of the way before starting the canned unlock animation.
+ * If there are two different wallpapers on home and lock screen, this is also the duration and
+ * delay of the home wallpaper fade in.
  */
 const val LEGACY_CANNED_UNLOCK_START_DELAY = 100L
-const val CANNED_UNLOCK_START_DELAY = 67L
+const val CANNED_UNLOCK_START_DELAY = 25L
 
 /**
  * Duration for the alpha animation on the surface behind. This plays to fade in the surface during
  * a swipe to unlock (and to fade it back out if the swipe is cancelled).
  */
-const val LEGACY_SURFACE_BEHIND_SWIPE_FADE_DURATION_MS = 175L
-const val SURFACE_BEHIND_FADE_OUT_DURATION_MS = 83L
+const val SURFACE_BEHIND_SWIPE_FADE_DURATION_MS = 175L
 
 /**
  * Start delay for the surface behind animation, used so that the lockscreen can get out of the way
  * before the surface begins appearing.
  */
 const val LEGACY_UNLOCK_ANIMATION_SURFACE_BEHIND_START_DELAY_MS = 75L
-const val SURFACE_BEHIND_FADE_OUT_START_DELAY_MS = 0L
+const val UNLOCK_ANIMATION_SURFACE_BEHIND_START_DELAY_MS = 67L
 
 /**
  * Initiates, controls, and ends the keyguard unlock animation.
@@ -158,7 +167,7 @@
         private val statusBarStateController: SysuiStatusBarStateController,
         private val notificationShadeWindowController: NotificationShadeWindowController,
         private val powerManager: PowerManager,
-        private val wallpaperManager: WallpaperManager
+        private val wallpaperManager: WallpaperManager,
 ) : KeyguardStateController.Callback, ISysuiUnlockAnimationController.Stub() {
 
     interface KeyguardUnlockAnimationListener {
@@ -268,7 +277,8 @@
     @VisibleForTesting
     var surfaceTransactionApplier: SyncRtSurfaceTransactionApplier? = null
     private var surfaceBehindRemoteAnimationTargets: Array<RemoteAnimationTarget>? = null
-    private var wallpaperTargets: Array<RemoteAnimationTarget>? = null
+    private var openingWallpaperTargets: Array<RemoteAnimationTarget>? = null
+    private var closingWallpaperTargets: Array<RemoteAnimationTarget>? = null
     private var surfaceBehindRemoteAnimationStartTime: Long = 0
 
     /**
@@ -286,6 +296,8 @@
 
     var wallpaperCannedUnlockAnimator = ValueAnimator.ofFloat(0f, 1f)
 
+    var wallpaperFadeOutUnlockAnimator = ValueAnimator.ofFloat(1f, 0f)
+
     /**
      * Matrix applied to [surfaceBehindRemoteAnimationTarget], which is the surface of the
      * app/launcher behind the keyguard.
@@ -335,7 +347,7 @@
 
     init {
         with(surfaceBehindAlphaAnimator) {
-            duration = surfaceBehindFadeOutDurationMs()
+            duration = SURFACE_BEHIND_SWIPE_FADE_DURATION_MS
             interpolator = Interpolators.LINEAR
             addUpdateListener { valueAnimator: ValueAnimator ->
                 surfaceBehindAlpha = valueAnimator.animatedValue as Float
@@ -351,7 +363,8 @@
                     if (surfaceBehindAlpha == 0f) {
                         Log.d(TAG, "surfaceBehindAlphaAnimator#onAnimationEnd")
                         surfaceBehindRemoteAnimationTargets = null
-                        wallpaperTargets = null
+                        openingWallpaperTargets = null
+                        closingWallpaperTargets = null
                         keyguardViewMediator.get().finishSurfaceBehindRemoteAnimation(
                             false /* cancelled */)
                     } else {
@@ -363,22 +376,40 @@
         }
 
         with(wallpaperCannedUnlockAnimator) {
-            duration = if (fastUnlockTransition()) UNLOCK_ANIMATION_DURATION_MS
+            duration = if (fasterUnlockTransition()) UNLOCK_ANIMATION_DURATION_MS
                     else LAUNCHER_ICONS_ANIMATION_DURATION_MS
-            interpolator = if (fastUnlockTransition()) Interpolators.LINEAR
+            interpolator = if (fasterUnlockTransition()) Interpolators.LINEAR
                     else Interpolators.ALPHA_OUT
             addUpdateListener { valueAnimator: ValueAnimator ->
-                setWallpaperAppearAmount(valueAnimator.animatedValue as Float)
+                setWallpaperAppearAmount(
+                        valueAnimator.animatedValue as Float, openingWallpaperTargets)
             }
             addListener(object : AnimatorListenerAdapter() {
+                override fun onAnimationStart(animation: Animator) {
+                    super.onAnimationStart(animation)
+                    Trace.asyncTraceBegin(Trace.TRACE_TAG_APP, "WallpaperAlphaAnimation", 0)
+                }
                 override fun onAnimationEnd(animation: Animator) {
                     Log.d(TAG, "wallpaperCannedUnlockAnimator#onAnimationEnd")
                     keyguardViewMediator.get().exitKeyguardAndFinishSurfaceBehindRemoteAnimation(
                         false /* cancelled */)
+                    Trace.asyncTraceEnd(Trace.TRACE_TAG_APP, "WallpaperAlphaAnimation", 0)
                 }
             })
         }
 
+        if (fasterUnlockTransition()) {
+            with(wallpaperFadeOutUnlockAnimator) {
+                duration = LOCK_WALLPAPER_FADE_OUT_DURATION
+                startDelay = LOCK_WALLPAPER_FADE_OUT_START_DELAY
+                interpolator = Interpolators.LINEAR
+                addUpdateListener { valueAnimator: ValueAnimator ->
+                    setWallpaperAppearAmount(
+                            valueAnimator.animatedValue as Float, closingWallpaperTargets)
+                }
+            }
+        }
+
         with(surfaceBehindEntryAnimator) {
             duration = unlockAnimationDurationMs()
             startDelay = surfaceBehindFadeOutStartDelayMs()
@@ -546,7 +577,8 @@
      */
     fun notifyStartSurfaceBehindRemoteAnimation(
         targets: Array<RemoteAnimationTarget>,
-        wallpapers: Array<RemoteAnimationTarget>,
+        openingWallpapers: Array<RemoteAnimationTarget>,
+        closingWallpapers: Array<RemoteAnimationTarget>,
         startTime: Long,
         requestedShowSurfaceBehindKeyguard: Boolean
     ) {
@@ -556,7 +588,8 @@
         }
 
         surfaceBehindRemoteAnimationTargets = targets
-        wallpaperTargets = wallpapers
+        openingWallpaperTargets = openingWallpapers
+        closingWallpaperTargets = closingWallpapers
         surfaceBehindRemoteAnimationStartTime = startTime
 
         // If we specifically requested that the surface behind be made visible (vs. it being made
@@ -613,14 +646,12 @@
         val isWakeAndUnlockNotFromDream = biometricUnlockControllerLazy.get().isWakeAndUnlock &&
             biometricUnlockControllerLazy.get().mode != MODE_WAKE_AND_UNLOCK_FROM_DREAM
 
-        val duration = if (fastUnlockTransition()) UNLOCK_ANIMATION_DURATION_MS
-                else LAUNCHER_ICONS_ANIMATION_DURATION_MS
         listeners.forEach {
             it.onUnlockAnimationStarted(
                 playingCannedUnlockAnimation /* playingCannedAnimation */,
                 isWakeAndUnlockNotFromDream /* isWakeAndUnlockNotFromDream */,
                 cannedUnlockStartDelayMs() /* unlockStartDelay */,
-                duration /* unlockAnimationDuration */) }
+                LAUNCHER_ICONS_ANIMATION_DURATION_MS /* unlockAnimationDuration */) }
 
         // Finish the keyguard remote animation if the dismiss amount has crossed the threshold.
         // Check it here in case there is no more change to the dismiss amount after the last change
@@ -712,6 +743,10 @@
         // As soon as the shade starts animating out of the way, start the canned unlock animation,
         // which will finish keyguard exit when it completes. The in-window animations in the
         // Launcher window will end on their own.
+        if (fasterUnlockTransition() && openingWallpaperTargets?.isNotEmpty() == true) {
+            fadeOutWallpaper()
+        }
+
         handler.postDelayed({
             if (keyguardViewMediator.get().isShowingAndNotOccluded &&
                 !keyguardStateController.isKeyguardGoingAway) {
@@ -720,7 +755,7 @@
                 return@postDelayed
             }
 
-            if ((wallpaperTargets?.isNotEmpty() == true)) {
+            if (openingWallpaperTargets?.isNotEmpty() == true) {
                 fadeInWallpaper()
                 hideKeyguardViewAfterRemoteAnimation()
             } else {
@@ -855,7 +890,8 @@
     /**
      * Scales in and translates up the surface behind the keyguard. This is used during unlock
      * animations and swipe gestures to animate the surface's entry (and exit, if the swipe is
-     * cancelled).
+     * cancelled). When called with [wallpapers]=true, if there are different home and lock screen
+     * wallpapers, this transitions between the two wallpapers
      */
     fun setSurfaceBehindAppearAmount(amount: Float, wallpapers: Boolean = true) {
         val animationAlpha = when {
@@ -923,13 +959,27 @@
         }
 
         if (wallpapers) {
-            setWallpaperAppearAmount(amount)
+            if (!fasterUnlockTransition()) setWallpaperAppearAmount(amount, openingWallpaperTargets)
+            else {
+                // Use the amount to compute the fadeInAmount and fadeOutAmount of the home and lock
+                // screen wallpapers to manually imitate the canned unlock animation.
+                val total = (UNLOCK_ANIMATION_DURATION_MS + CANNED_UNLOCK_START_DELAY).toFloat()
+                val fadeInStart = CANNED_UNLOCK_START_DELAY / total
+                val fadeInAmount = maxOf(0f, (amount - fadeInStart) / (1f - fadeInStart))
+
+                val fadeOutStart = LOCK_WALLPAPER_FADE_OUT_START_DELAY / total
+                val fadeOutEnd = fadeOutStart + LOCK_WALLPAPER_FADE_OUT_DURATION / total
+                val fadeOutAmount = ((amount - fadeOutStart) / (fadeOutEnd - fadeOutStart))
+                        .coerceIn(0f, 1f)
+
+                setWallpaperAppearAmount(fadeInAmount, openingWallpaperTargets)
+                setWallpaperAppearAmount(1 - fadeOutAmount, closingWallpaperTargets)
+            }
         }
     }
 
-    fun setWallpaperAppearAmount(amount: Float) {
+    fun setWallpaperAppearAmount(amount: Float, wallpaperTargets: Array<RemoteAnimationTarget>?) {
         val animationAlpha = amount
-
         wallpaperTargets?.forEach { wallpaper ->
             // SyncRtSurfaceTransactionApplier cannot apply transaction when the target view is
             // unable to draw
@@ -988,10 +1038,12 @@
         surfaceBehindAlphaAnimator.cancel()
         surfaceBehindEntryAnimator.cancel()
         wallpaperCannedUnlockAnimator.cancel()
+        if (fasterUnlockTransition()) wallpaperFadeOutUnlockAnimator.cancel()
 
         // That target is no longer valid since the animation finished, null it out.
         surfaceBehindRemoteAnimationTargets = null
-        wallpaperTargets = null
+        openingWallpaperTargets = null
+        if (fasterUnlockTransition()) closingWallpaperTargets = null
 
         playingCannedUnlockAnimation = false
         dismissAmountThresholdsReached = false
@@ -1035,6 +1087,12 @@
         wallpaperCannedUnlockAnimator.start()
     }
 
+    private fun fadeOutWallpaper() {
+        Log.d(TAG, "fadeOutWallpaper")
+        wallpaperFadeOutUnlockAnimator.cancel()
+        wallpaperFadeOutUnlockAnimator.start()
+    }
+
     private fun fadeOutSurfaceBehind() {
         Log.d(TAG, "fadeOutSurfaceBehind")
         surfaceBehindAlphaAnimator.cancel()
@@ -1148,7 +1206,7 @@
      * TODO (b/298186160) replace references with the constant itself when flag is removed
      */
     private fun cannedUnlockStartDelayMs(): Long {
-        return if (fastUnlockTransition()) CANNED_UNLOCK_START_DELAY
+        return if (fasterUnlockTransition()) CANNED_UNLOCK_START_DELAY
                 else LEGACY_CANNED_UNLOCK_START_DELAY
     }
 
@@ -1157,7 +1215,7 @@
      * TODO (b/298186160) replace references with the constant itself when flag is removed
      */
     private fun unlockAnimationDurationMs(): Long {
-        return if (fastUnlockTransition()) UNLOCK_ANIMATION_DURATION_MS
+        return if (fasterUnlockTransition()) UNLOCK_ANIMATION_DURATION_MS
                 else LEGACY_UNLOCK_ANIMATION_DURATION_MS
     }
 
@@ -1165,17 +1223,8 @@
      * Temporary method for b/298186160
      * TODO (b/298186160) replace references with the constant itself when flag is removed
      */
-    private fun surfaceBehindFadeOutDurationMs(): Long {
-        return if (fastUnlockTransition()) SURFACE_BEHIND_FADE_OUT_DURATION_MS
-                else LEGACY_SURFACE_BEHIND_SWIPE_FADE_DURATION_MS
-    }
-
-    /**
-     * Temporary method for b/298186160
-     * TODO (b/298186160) replace references with the constant itself when flag is removed
-     */
     private fun surfaceBehindFadeOutStartDelayMs(): Long {
-        return if (fastUnlockTransition()) SURFACE_BEHIND_FADE_OUT_START_DELAY_MS
+        return if (fasterUnlockTransition()) UNLOCK_ANIMATION_SURFACE_BEHIND_START_DELAY_MS
                 else LEGACY_UNLOCK_ANIMATION_SURFACE_BEHIND_START_DELAY_MS
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
index 608e25a..33f9209 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
@@ -42,6 +42,7 @@
 import com.android.systemui.biometrics.ui.binder.DeviceEntryUnlockTrackerViewBinder
 import com.android.systemui.common.ui.ConfigurationState
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryHapticsInteractor
 import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor
 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
@@ -73,6 +74,7 @@
 import dagger.Lazy
 import java.util.Optional
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.DisposableHandle
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 
@@ -108,6 +110,7 @@
     private val clockInteractor: KeyguardClockInteractor,
     private val keyguardViewMediator: KeyguardViewMediator,
     private val deviceEntryUnlockTrackerViewBinder: Optional<DeviceEntryUnlockTrackerViewBinder>,
+    @Main private val mainDispatcher: CoroutineDispatcher,
 ) : CoreStartable {
 
     private var rootViewHandle: DisposableHandle? = null
@@ -215,6 +218,7 @@
                 vibratorHelper,
                 falsingManager,
                 keyguardViewMediator,
+                mainDispatcher,
             )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 2d60fcc..fe81b20c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -42,6 +42,7 @@
 import static com.android.systemui.DejankUtils.whitelistIpcs;
 import static com.android.systemui.Flags.notifyPowerManagerUserActivityBackground;
 import static com.android.systemui.Flags.refactorGetCurrentUser;
+import static com.android.systemui.Flags.translucentOccludingActivityFix;
 import static com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel.DREAMING_ANIMATION_DURATION_MS;
 
 import android.animation.Animator;
@@ -151,6 +152,7 @@
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.res.R;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.shade.ShadeExpansionStateManager;
@@ -178,6 +180,8 @@
 
 import dagger.Lazy;
 
+import kotlinx.coroutines.CoroutineDispatcher;
+
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -187,8 +191,6 @@
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 
-import kotlinx.coroutines.CoroutineDispatcher;
-
 /**
  * Mediates requests related to the keyguard.  This includes queries about the
  * state of the keyguard, power management events that effect whether the keyguard
@@ -1035,6 +1037,17 @@
                                 (int) (fullWidth - initialWidth) /* left */,
                                 fullWidth /* right */,
                                 mWindowCornerRadius, mWindowCornerRadius);
+                    } else if (translucentOccludingActivityFix()
+                            && mOccludingRemoteAnimationTarget != null
+                            && mOccludingRemoteAnimationTarget.isTranslucent) {
+                        // Animating in a transparent window looks really weird. Just let it be
+                        // fullscreen and the app can do an internal animation if it wants to.
+                        return new TransitionAnimator.State(
+                                0,
+                                fullHeight,
+                                0,
+                                fullWidth,
+                                0f, 0f);
                     } else {
                         final float initialHeight = fullHeight / 2f;
                         final float initialWidth = fullWidth / 2f;
@@ -1398,6 +1411,11 @@
     private final Lazy<DreamViewModel> mDreamViewModel;
     private final Lazy<CommunalTransitionViewModel> mCommunalTransitionViewModel;
     private RemoteAnimationTarget mRemoteAnimationTarget;
+
+    /**
+     * The most recent RemoteAnimationTarget provided for an occluding activity animation.
+     */
+    private RemoteAnimationTarget mOccludingRemoteAnimationTarget;
     private boolean mShowCommunalWhenUnoccluding = false;
 
     private final Lazy<WindowManagerLockscreenVisibilityManager> mWmLockscreenVisibilityManager;
@@ -2704,13 +2722,13 @@
         if (mGoingToSleep) {
             mUpdateMonitor.clearFingerprintRecognizedWhenKeyguardDone(currentUser);
             Log.i(TAG, "Device is going to sleep, aborting keyguardDone");
-            return;
-        }
-        setPendingLock(false); // user may have authenticated during the screen off animation
+        } else {
+            setPendingLock(false); // user may have authenticated during the screen off animation
 
-        handleHide();
-        mKeyguardInteractor.keyguardDoneAnimationsFinished();
-        mUpdateMonitor.clearFingerprintRecognizedWhenKeyguardDone(currentUser);
+            handleHide();
+            mKeyguardInteractor.keyguardDoneAnimationsFinished();
+            mUpdateMonitor.clearFingerprintRecognizedWhenKeyguardDone(currentUser);
+        }
         Trace.endSection();
     }
 
@@ -3142,9 +3160,13 @@
                         w -> w.mode == RemoteAnimationTarget.MODE_OPENING).toArray(
                         RemoteAnimationTarget[]::new);
 
+                RemoteAnimationTarget[] closingWallpapers = Arrays.stream(wallpapers).filter(
+                        w -> w.mode == RemoteAnimationTarget.MODE_CLOSING).toArray(
+                        RemoteAnimationTarget[]::new);
+
                 mKeyguardUnlockAnimationControllerLazy.get()
                         .notifyStartSurfaceBehindRemoteAnimation(
-                                openingApps, openingWallpapers, startTime,
+                                openingApps, openingWallpapers, closingWallpapers, startTime,
                                 mSurfaceBehindRemoteAnimationRequested);
             } else {
                 mInteractionJankMonitor.begin(
@@ -3502,12 +3524,14 @@
                         +  " --> flags=0x" + Integer.toHexString(flags));
             }
 
-            try {
-                mStatusBarService.disableForUser(flags, mStatusBarDisableToken,
-                        mContext.getPackageName(),
-                        mSelectedUserInteractor.getSelectedUserId(true));
-            } catch (RemoteException e) {
-                Log.d(TAG, "Failed to set disable flags: " + flags, e);
+            if (!SceneContainerFlag.isEnabled()) {
+                try {
+                    mStatusBarService.disableForUser(flags, mStatusBarDisableToken,
+                            mContext.getPackageName(),
+                            mSelectedUserInteractor.getSelectedUserId(true));
+                } catch (RemoteException e) {
+                    Log.d(TAG, "Failed to set disable flags: " + flags, e);
+                }
             }
         }
     }
@@ -3798,6 +3822,10 @@
     }
 
     private void notifyDefaultDisplayCallbacks(boolean showing) {
+        if (SceneContainerFlag.isEnabled()) {
+            return;
+        }
+
         // TODO(b/140053364)
         whitelistIpcs(() -> {
             int size = mKeyguardStateCallbacks.size();
@@ -3930,6 +3958,13 @@
         public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
                 RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
                 IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
+            // Save mRemoteAnimationTarget for reference in the animation controller. Needs to be
+            // called prior to super.onAnimationStart() since that's the call that eventually asks
+            // the animation controller to configure the animation state.
+            if (apps.length > 0) {
+                mOccludingRemoteAnimationTarget = apps[0];
+            }
+
             super.onAnimationStart(transit, apps, wallpapers, nonApps, finishedCallback);
 
             mInteractionJankMonitor.begin(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt
index 97ea16d..b9e5135 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ResourceTrimmer.kt
@@ -24,11 +24,7 @@
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
-import com.android.systemui.keyguard.shared.model.Edge
 import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
-import com.android.systemui.keyguard.shared.model.TransitionState
-import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.utils.GlobalWindowManager
 import javax.inject.Inject
@@ -52,24 +48,15 @@
     private val globalWindowManager: GlobalWindowManager,
     @Application private val applicationScope: CoroutineScope,
     @Background private val bgDispatcher: CoroutineDispatcher,
-    private val sceneInteractor: SceneInteractor,
 ) : CoreStartable {
 
     override fun start() {
         Log.d(LOG_TAG, "Resource trimmer registered.")
         applicationScope.launch(bgDispatcher) {
-            // We drop 1 to avoid triggering on initial collect().
-            if (SceneContainerFlag.isEnabled) {
-                sceneInteractor.transitionState
-                    .filter { it.isIdle(Scenes.Gone) }
-                    .collect { onKeyguardGone() }
-            } else {
-                keyguardTransitionInteractor.transition(Edge.create(to = GONE)).collect {
-                    if (it.transitionState == TransitionState.FINISHED) {
-                        onKeyguardGone()
-                    }
-                }
-            }
+            keyguardTransitionInteractor
+                .isFinishedIn(scene = Scenes.Gone, stateWithoutSceneContainer = GONE)
+                .filter { isOnGone -> isOnGone }
+                .collect { onKeyguardGone() }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt
index 0863cd7..80675d3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/BuiltInKeyguardQuickAffordanceKeys.kt
@@ -28,8 +28,6 @@
     const val CREATE_NOTE = "create_note"
     const val DO_NOT_DISTURB = "do_not_disturb"
     const val FLASHLIGHT = "flashlight"
-    // TODO(b/339667383): delete or properly implement this once a product decision is made
-    const val GLANCEABLE_HUB = "glanceable_hub"
     const val HOME_CONTROLS = "home"
     const val MUTE = "mute"
     const val QR_CODE_SCANNER = "qr_code_scanner"
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
index 9b5f461..406b9f6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfig.kt
@@ -25,9 +25,8 @@
 import android.provider.Settings.Secure.ZEN_DURATION_FOREVER
 import android.provider.Settings.Secure.ZEN_DURATION_PROMPT
 import android.service.notification.ZenModeConfig
-import com.android.settingslib.notification.EnableZenModeDialog
-import com.android.settingslib.notification.ZenModeDialogMetricsLogger
-import com.android.systemui.res.R
+import com.android.settingslib.notification.modes.EnableZenModeDialog
+import com.android.settingslib.notification.modes.ZenModeDialogMetricsLogger
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
@@ -36,6 +35,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
+import com.android.systemui.res.R
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.statusbar.policy.ZenModeController
 import com.android.systemui.util.settings.SecureSettings
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt
deleted file mode 100644
index 5d54126..0000000
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/GlanceableHubQuickAffordanceConfig.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.keyguard.data.quickaffordance
-
-import com.android.systemui.Flags
-import com.android.systemui.animation.Expandable
-import com.android.systemui.common.shared.model.ContentDescription
-import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.communal.data.repository.CommunalSceneRepository
-import com.android.systemui.communal.shared.model.CommunalScenes
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.res.R
-import javax.inject.Inject
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.flowOf
-
-/** Shortcut that opens the glanceable hub. */
-// TODO(b/339667383): delete or properly implement this once a product decision is made
-@SysUISingleton
-class GlanceableHubQuickAffordanceConfig
-@Inject
-constructor(
-    private val communalRepository: CommunalSceneRepository,
-) : KeyguardQuickAffordanceConfig {
-
-    override val key: String = BuiltInKeyguardQuickAffordanceKeys.GLANCEABLE_HUB
-
-    override fun pickerName(): String = "Glanceable hub"
-
-    override val pickerIconResourceId = R.drawable.ic_widgets
-
-    override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState> by lazy {
-        if (Flags.glanceableHubShortcutButton()) {
-            val contentDescription = ContentDescription.Loaded(pickerName())
-            val icon = Icon.Resource(pickerIconResourceId, contentDescription)
-            flowOf(KeyguardQuickAffordanceConfig.LockScreenState.Visible(icon))
-        } else {
-            flowOf(KeyguardQuickAffordanceConfig.LockScreenState.Hidden)
-        }
-    }
-
-    override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState {
-        return KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
-    }
-
-    override fun onTriggered(
-        expandable: Expandable?
-    ): KeyguardQuickAffordanceConfig.OnTriggeredResult {
-        communalRepository.changeScene(CommunalScenes.Communal, null)
-        return KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt
index 93296f0..4556195 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardDataQuickAffordanceModule.kt
@@ -36,7 +36,6 @@
             camera: CameraQuickAffordanceConfig,
             doNotDisturb: DoNotDisturbQuickAffordanceConfig,
             flashlight: FlashlightQuickAffordanceConfig,
-            glanceableHub: GlanceableHubQuickAffordanceConfig,
             home: HomeControlsKeyguardQuickAffordanceConfig,
             mute: MuteQuickAffordanceConfig,
             quickAccessWallet: QuickAccessWalletKeyguardQuickAffordanceConfig,
@@ -47,7 +46,6 @@
                 camera,
                 doNotDisturb,
                 flashlight,
-                glanceableHub,
                 home,
                 mute,
                 quickAccessWallet,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt
index 0748979..796374a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManager.kt
@@ -20,7 +20,6 @@
 import android.content.Context
 import android.content.IntentFilter
 import android.content.SharedPreferences
-import com.android.systemui.Flags
 import com.android.systemui.backup.BackupHelper
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
@@ -30,7 +29,6 @@
 import com.android.systemui.res.R
 import com.android.systemui.settings.UserFileManager
 import com.android.systemui.settings.UserTracker
-import com.android.systemui.util.settings.SystemSettings
 import javax.inject.Inject
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.channels.awaitClose
@@ -52,7 +50,6 @@
     @Application private val context: Context,
     private val userFileManager: UserFileManager,
     private val userTracker: UserTracker,
-    private val systemSettings: SystemSettings,
     broadcastDispatcher: BroadcastDispatcher,
 ) : KeyguardQuickAffordanceSelectionManager {
 
@@ -73,22 +70,6 @@
     }
 
     private val defaults: Map<String, List<String>> by lazy {
-        // Quick hack to allow testing out a lock screen shortcut to open the glanceable hub. This
-        // flag will not be rolled out and is only used for local testing.
-        // TODO(b/339667383): delete or properly implement this once a product decision is made
-        if (Flags.glanceableHubShortcutButton()) {
-            if (systemSettings.getBool("open_hub_chip_replace_home_controls", false)) {
-                return@lazy mapOf(
-                    "bottom_start" to listOf("glanceable_hub"),
-                    "bottom_end" to listOf("create_note")
-                )
-            } else {
-                return@lazy mapOf(
-                    "bottom_start" to listOf("home"),
-                    "bottom_end" to listOf("glanceable_hub")
-                )
-            }
-        }
         context.resources
             .getStringArray(R.array.config_keyguardQuickAffordanceDefaults)
             .associate { item ->
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManager.kt
index e9bd889..e6bab4c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManager.kt
@@ -19,8 +19,9 @@
 
 import android.content.Context
 import android.os.UserHandle
+import com.android.app.tracing.FlowTracing.tracedAwaitClose
+import com.android.app.tracing.FlowTracing.tracedConflatedCallbackFlow
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
-import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.settings.UserTracker
@@ -28,7 +29,6 @@
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
@@ -55,19 +55,20 @@
     private val userHandle: UserHandle,
 ) : KeyguardQuickAffordanceSelectionManager {
 
-    private val userId: Flow<Int> = conflatedCallbackFlow {
-        val callback =
-            object : UserTracker.Callback {
-                override fun onUserChanged(newUser: Int, userContext: Context) {
-                    trySendWithFailureLogging(newUser, TAG)
+    private val userId: Flow<Int> =
+        tracedConflatedCallbackFlow("userId") {
+            val callback =
+                object : UserTracker.Callback {
+                    override fun onUserChanged(newUser: Int, userContext: Context) {
+                        trySendWithFailureLogging(newUser, TAG)
+                    }
                 }
-            }
 
-        userTracker.addCallback(callback) { it.run() }
-        trySendWithFailureLogging(userTracker.userId, TAG)
+            userTracker.addCallback(callback) { it.run() }
+            trySendWithFailureLogging(userTracker.userId, TAG)
 
-        awaitClose { userTracker.removeCallback(callback) }
-    }
+            tracedAwaitClose("userId") { userTracker.removeCallback(callback) }
+        }
 
     private val clientOrNull: StateFlow<CustomizationProviderClient?> =
         userId
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt
index 1fe94d5..a145214 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfig.kt
@@ -21,7 +21,6 @@
 import android.media.AudioManager
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.Observer
-import com.android.systemui.res.R
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.common.shared.model.ContentDescription
@@ -31,6 +30,7 @@
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
+import com.android.systemui.res.R
 import com.android.systemui.settings.UserFileManager
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.util.RingerModeTracker
@@ -86,8 +86,8 @@
                         audioManager.isVolumeFixed ->
                             ActivationState.NotSupported to R.string.volume_ringer_hint_mute
                         mode == AudioManager.RINGER_MODE_SILENT ->
-                            ActivationState.Active to R.string.volume_ringer_hint_mute
-                        else -> ActivationState.Inactive to R.string.volume_ringer_hint_unmute
+                            ActivationState.Active to R.string.volume_ringer_hint_unmute
+                        else -> ActivationState.Inactive to R.string.volume_ringer_hint_mute
                     }
 
                 KeyguardQuickAffordanceConfig.LockScreenState.Visible(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
index b3d9a76..56b520e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
@@ -59,7 +59,7 @@
 
     override val key: String = BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET
 
-    override fun pickerName(): String = context.getString(R.string.accessibility_wallet_button)
+    override fun pickerName(): String = context.getString(R.string.wallet_title)
 
     override val pickerIconResourceId = R.drawable.ic_wallet_lockscreen
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt
index 882f231..dd3e619 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepository.kt
@@ -188,35 +188,33 @@
         )
 
     private val isFingerprintEnrolled: Flow<Boolean> =
-        selectedUserId
-            .flatMapLatest { currentUserId ->
-                conflatedCallbackFlow {
-                    val callback =
-                        object : AuthController.Callback {
-                            override fun onEnrollmentsChanged(
-                                sensorBiometricType: BiometricType,
-                                userId: Int,
-                                hasEnrollments: Boolean
-                            ) {
-                                if (sensorBiometricType.isFingerprint && userId == currentUserId) {
-                                    trySendWithFailureLogging(
-                                        hasEnrollments,
-                                        TAG,
-                                        "update fpEnrollment"
-                                    )
-                                }
+        selectedUserId.flatMapLatest { currentUserId ->
+            conflatedCallbackFlow {
+                val callback =
+                    object : AuthController.Callback {
+                        override fun onEnrollmentsChanged(
+                            sensorBiometricType: BiometricType,
+                            userId: Int,
+                            hasEnrollments: Boolean
+                        ) {
+                            if (sensorBiometricType.isFingerprint && userId == currentUserId) {
+                                trySendWithFailureLogging(
+                                    hasEnrollments,
+                                    TAG,
+                                    "update fpEnrollment"
+                                )
                             }
                         }
-                    authController.addCallback(callback)
-                    awaitClose { authController.removeCallback(callback) }
-                }
+                    }
+                authController.addCallback(callback)
+                trySendWithFailureLogging(
+                    authController.isFingerprintEnrolled(currentUserId),
+                    TAG,
+                    "Initial value of fingerprint enrollment"
+                )
+                awaitClose { authController.removeCallback(callback) }
             }
-            .stateIn(
-                scope,
-                started = SharingStarted.Eagerly,
-                initialValue =
-                    authController.isFingerprintEnrolled(userRepository.getSelectedUserInfo().id)
-            )
+        }
 
     private val isFaceEnrolled: Flow<Boolean> =
         selectedUserId.flatMapLatest { selectedUserId: Int ->
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
index d508b2b..ae751db 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardRepository.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.keyguard.data.repository
 
 import android.graphics.Point
+import com.android.internal.widget.LockPatternUtils
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.systemui.biometrics.AuthController
@@ -39,6 +40,7 @@
 import com.android.systemui.keyguard.shared.model.KeyguardDone
 import com.android.systemui.keyguard.shared.model.StatusBarState
 import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.time.SystemClock
@@ -60,6 +62,7 @@
 import kotlinx.coroutines.flow.mapLatest
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
 
 /** Defines interface for classes that encapsulate application state for the keyguard. */
 interface KeyguardRepository {
@@ -78,6 +81,8 @@
 
     val keyguardAlpha: StateFlow<Float>
 
+    val panelAlpha: MutableStateFlow<Float>
+
     /**
      * Observable for whether the keyguard is showing.
      *
@@ -122,6 +127,30 @@
      */
     val isKeyguardEnabled: StateFlow<Boolean>
 
+    /**
+     * Whether we can transition directly back to GONE from AOD/DOZING without any authentication
+     * events (such as a fingerprint wake and unlock), even though authentication would normally be
+     * required. This means that if you tap the screen or press the power button, you'll return
+     * directly to the unlocked app content without seeing the lockscreen, even if a secure
+     * authentication method (PIN/password/biometrics) is set.
+     *
+     * This is true in these cases:
+     * - The screen timed out, but the "lock after screen timeout" duration (default 5 seconds) has
+     *   not yet elapsed.
+     * - The power button was pressed, but "power button instantly locks" is not enabled, and the
+     *   "lock after screen timeout" duration has not elapsed.
+     *
+     * Note that this value specifically tells us if we can *ignore* authentication that would
+     * otherwise be required to transition from AOD/DOZING -> GONE. AOD/DOZING -> GONE is also
+     * possible if keyguard is disabled, either from an app request or because security is set to
+     * "none", but in that case, auth is not required so this boolean is not relevant.
+     *
+     * See [KeyguardWakeToGoneInteractor].
+     */
+    val canIgnoreAuthAndReturnToGone: StateFlow<Boolean>
+
+    fun setCanIgnoreAuthAndReturnToGone(canWake: Boolean)
+
     /** Is the always-on display available to be used? */
     val isAodAvailable: StateFlow<Boolean>
 
@@ -250,6 +279,9 @@
     /** Sets the current amount of alpha that should be used for rendering the keyguard. */
     fun setKeyguardAlpha(alpha: Float)
 
+    /** Temporary shim for fading out content when the brightness slider is used */
+    fun setPanelAlpha(alpha: Float)
+
     /** Whether the device is actively dreaming */
     fun setDreaming(isDreaming: Boolean)
 
@@ -288,6 +320,15 @@
 
     /** Sets whether the keyguard is enabled (see [isKeyguardEnabled]). */
     fun setKeyguardEnabled(enabled: Boolean)
+
+    /** @see isShowKeyguardWhenReenabled */
+    fun setShowKeyguardWhenReenabled(isShowKeyguardWhenReenabled: Boolean)
+
+    /**
+     * Returns `true` if the keyguard should be re-shown once it becomes re-enabled again; `false`
+     * otherwise.
+     */
+    fun isShowKeyguardWhenReenabled(): Boolean
 }
 
 /** Encapsulates application state for the keyguard. */
@@ -306,6 +347,7 @@
     private val systemClock: SystemClock,
     facePropertyRepository: FacePropertyRepository,
     private val userTracker: UserTracker,
+    lockPatternUtils: LockPatternUtils,
 ) : KeyguardRepository {
     private val _dismissAction: MutableStateFlow<DismissAction> =
         MutableStateFlow(DismissAction.None)
@@ -338,35 +380,15 @@
     private val _keyguardAlpha = MutableStateFlow(1f)
     override val keyguardAlpha = _keyguardAlpha.asStateFlow()
 
+    override val panelAlpha: MutableStateFlow<Float> = MutableStateFlow(1f)
+
     private val _clockShouldBeCentered = MutableStateFlow(true)
     override val clockShouldBeCentered: Flow<Boolean> = _clockShouldBeCentered.asStateFlow()
 
     override val topClippingBounds = MutableStateFlow<Int?>(null)
 
-    override val isKeyguardShowing: Flow<Boolean> =
-        conflatedCallbackFlow {
-                val callback =
-                    object : KeyguardStateController.Callback {
-                        override fun onKeyguardShowingChanged() {
-                            trySendWithFailureLogging(
-                                keyguardStateController.isShowing,
-                                TAG,
-                                "updated isKeyguardShowing"
-                            )
-                        }
-                    }
-
-                keyguardStateController.addCallback(callback)
-                // Adding the callback does not send an initial update.
-                trySendWithFailureLogging(
-                    keyguardStateController.isShowing,
-                    TAG,
-                    "initial isKeyguardShowing"
-                )
-
-                awaitClose { keyguardStateController.removeCallback(callback) }
-            }
-            .distinctUntilChanged()
+    override val isKeyguardShowing: MutableStateFlow<Boolean> =
+        MutableStateFlow(keyguardStateController.isShowing)
 
     private val _isAodAvailable = MutableStateFlow(false)
     override val isAodAvailable: StateFlow<Boolean> = _isAodAvailable.asStateFlow()
@@ -375,98 +397,31 @@
         _isAodAvailable.value = value
     }
 
-    override val isKeyguardOccluded: Flow<Boolean> =
-        conflatedCallbackFlow {
-                val callback =
-                    object : KeyguardStateController.Callback {
-                        override fun onKeyguardShowingChanged() {
-                            trySendWithFailureLogging(
-                                keyguardStateController.isOccluded,
-                                TAG,
-                                "updated isKeyguardOccluded"
-                            )
-                        }
-                    }
+    override val isKeyguardOccluded: MutableStateFlow<Boolean> =
+        MutableStateFlow(keyguardStateController.isOccluded)
 
-                keyguardStateController.addCallback(callback)
-                // Adding the callback does not send an initial update.
-                trySendWithFailureLogging(
-                    keyguardStateController.isOccluded,
-                    TAG,
-                    "initial isKeyguardOccluded"
-                )
+    override val isKeyguardDismissible: MutableStateFlow<Boolean> =
+        MutableStateFlow(keyguardStateController.isUnlocked)
 
-                awaitClose { keyguardStateController.removeCallback(callback) }
-            }
-            .distinctUntilChanged()
+    override val isKeyguardGoingAway: MutableStateFlow<Boolean> =
+        MutableStateFlow(keyguardStateController.isKeyguardGoingAway)
 
-    override val isKeyguardDismissible: StateFlow<Boolean> =
-        conflatedCallbackFlow {
-                val callback =
-                    object : KeyguardStateController.Callback {
-                        override fun onUnlockedChanged() {
-                            trySendWithFailureLogging(
-                                keyguardStateController.isUnlocked,
-                                TAG,
-                                "updated isKeyguardDismissible due to onUnlockedChanged"
-                            )
-                        }
-
-                        override fun onKeyguardShowingChanged() {
-                            trySendWithFailureLogging(
-                                keyguardStateController.isUnlocked,
-                                TAG,
-                                "updated isKeyguardDismissible due to onKeyguardShowingChanged"
-                            )
-                        }
-                    }
-
-                keyguardStateController.addCallback(callback)
-                // Adding the callback does not send an initial update.
-                trySendWithFailureLogging(
-                    keyguardStateController.isUnlocked,
-                    TAG,
-                    "initial isKeyguardUnlocked"
-                )
-
-                awaitClose { keyguardStateController.removeCallback(callback) }
-            }
-            .distinctUntilChanged()
-            .stateIn(
-                scope,
-                SharingStarted.Eagerly,
-                initialValue = false,
-            )
-
-    override val isKeyguardGoingAway: Flow<Boolean> = conflatedCallbackFlow {
-        val callback =
-            object : KeyguardStateController.Callback {
-                override fun onKeyguardGoingAwayChanged() {
-                    trySendWithFailureLogging(
-                        keyguardStateController.isKeyguardGoingAway,
-                        TAG,
-                        "updated isKeyguardGoingAway"
-                    )
-                }
-            }
-
-        keyguardStateController.addCallback(callback)
-        // Adding the callback does not send an initial update.
-        trySendWithFailureLogging(
-            keyguardStateController.isKeyguardGoingAway,
-            TAG,
-            "initial isKeyguardGoingAway"
-        )
-
-        awaitClose { keyguardStateController.removeCallback(callback) }
-    }
-
-    private val _isKeyguardEnabled = MutableStateFlow(true)
+    private val _isKeyguardEnabled =
+        MutableStateFlow(!lockPatternUtils.isLockScreenDisabled(userTracker.userId))
     override val isKeyguardEnabled: StateFlow<Boolean> = _isKeyguardEnabled.asStateFlow()
 
+    private val _canIgnoreAuthAndReturnToGone = MutableStateFlow(false)
+    override val canIgnoreAuthAndReturnToGone = _canIgnoreAuthAndReturnToGone.asStateFlow()
+
+    override fun setCanIgnoreAuthAndReturnToGone(canWakeToGone: Boolean) {
+        _canIgnoreAuthAndReturnToGone.value = canWakeToGone
+    }
+
     private val _isDozing = MutableStateFlow(statusBarStateController.isDozing)
     override val isDozing: StateFlow<Boolean> = _isDozing.asStateFlow()
 
+    private var isShowKeyguardWhenReenabled: Boolean = false
+
     override fun setIsDozing(isDozing: Boolean) {
         _isDozing.value = isDozing
     }
@@ -647,6 +602,35 @@
     private val _isActiveDreamLockscreenHosted = MutableStateFlow(false)
     override val isActiveDreamLockscreenHosted = _isActiveDreamLockscreenHosted.asStateFlow()
 
+    init {
+        val callback =
+            object : KeyguardStateController.Callback {
+                override fun onKeyguardShowingChanged() {
+                    isKeyguardShowing.value = keyguardStateController.isShowing
+                    isKeyguardOccluded.value = keyguardStateController.isOccluded
+                    isKeyguardDismissible.value = keyguardStateController.isUnlocked
+                }
+
+                override fun onUnlockedChanged() {
+                    isKeyguardDismissible.value = keyguardStateController.isUnlocked
+                }
+
+                override fun onKeyguardGoingAwayChanged() {
+                    isKeyguardGoingAway.value = keyguardStateController.isKeyguardGoingAway
+                }
+            }
+
+        keyguardStateController.addCallback(callback)
+
+        scope
+            .launch {
+                isKeyguardShowing.collect {
+                    // no-op to allow for callback removal
+                }
+            }
+            .invokeOnCompletion { keyguardStateController.removeCallback(callback) }
+    }
+
     override fun setAnimateDozingTransitions(animate: Boolean) {
         _animateBottomAreaDozingTransitions.value = animate
     }
@@ -659,6 +643,10 @@
         _keyguardAlpha.value = alpha
     }
 
+    override fun setPanelAlpha(alpha: Float) {
+        panelAlpha.value = alpha
+    }
+
     override fun setDreaming(isDreaming: Boolean) {
         this.isDreaming.value = isDreaming
     }
@@ -681,6 +669,16 @@
         _isKeyguardEnabled.value = enabled
     }
 
+    override fun setShowKeyguardWhenReenabled(isShowKeyguardWhenReenabled: Boolean) {
+        SceneContainerFlag.assertInNewMode()
+        this.isShowKeyguardWhenReenabled = isShowKeyguardWhenReenabled
+    }
+
+    override fun isShowKeyguardWhenReenabled(): Boolean {
+        SceneContainerFlag.assertInNewMode()
+        return isShowKeyguardWhenReenabled
+    }
+
     private fun statusBarStateIntToObject(value: Int): StatusBarState {
         return when (value) {
             0 -> StatusBarState.SHADE
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt
index 6522439..bd5d096 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt
@@ -23,11 +23,13 @@
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.keyguard.shared.model.ActiveUnlockModel
 import com.android.systemui.keyguard.shared.model.TrustManagedModel
 import com.android.systemui.keyguard.shared.model.TrustModel
 import com.android.systemui.user.data.repository.UserRepository
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.channels.awaitClose
@@ -44,6 +46,7 @@
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.flow.shareIn
 import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.withContext
 
 /** Encapsulates any state relevant to trust agents and trust grants. */
 interface TrustRepository {
@@ -51,7 +54,7 @@
     val isCurrentUserTrustUsuallyManaged: StateFlow<Boolean>
 
     /** Flow representing whether the current user is trusted. */
-    val isCurrentUserTrusted: Flow<Boolean>
+    val isCurrentUserTrusted: StateFlow<Boolean>
 
     /** Flow representing whether active unlock is running for the current user. */
     val isCurrentUserActiveUnlockRunning: Flow<Boolean>
@@ -63,6 +66,9 @@
 
     /** A trust agent is requesting to dismiss the keyguard from a trust change. */
     val trustAgentRequestingToDismissKeyguard: Flow<TrustModel>
+
+    /** Reports a keyguard visibility change. */
+    suspend fun reportKeyguardShowingChanged()
 }
 
 @OptIn(ExperimentalCoroutinesApi::class)
@@ -71,6 +77,7 @@
 @Inject
 constructor(
     @Application private val applicationScope: CoroutineScope,
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
     private val userRepository: UserRepository,
     private val trustManager: TrustManager,
     private val logger: TrustRepositoryLogger,
@@ -191,11 +198,26 @@
     private fun isUserTrustManaged(userId: Int) =
         trustManagedForUser[userId]?.isTrustManaged ?: false
 
-    override val isCurrentUserTrusted: Flow<Boolean>
+    override val isCurrentUserTrusted: StateFlow<Boolean>
         get() =
             combine(trust, userRepository.selectedUserInfo, ::Pair)
-                .map { latestTrustModelForUser[it.second.id]?.isTrusted ?: false }
+                .map { isCurrentUserTrusted(it.second.id) }
                 .distinctUntilChanged()
                 .onEach { logger.isCurrentUserTrusted(it) }
                 .onStart { emit(false) }
+                .stateIn(
+                    scope = applicationScope,
+                    started = SharingStarted.WhileSubscribed(),
+                    initialValue = isCurrentUserTrusted(),
+                )
+
+    private fun isCurrentUserTrusted(
+        selectedUserId: Int = userRepository.getSelectedUserInfo().id
+    ): Boolean {
+        return latestTrustModelForUser[selectedUserId]?.isTrusted ?: false
+    }
+
+    override suspend fun reportKeyguardShowingChanged() {
+        withContext(backgroundDispatcher) { trustManager.reportKeyguardShowingChanged() }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
index 49d00af..b44a8cf 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
@@ -40,6 +40,7 @@
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.drop
 import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.flatMapLatest
@@ -55,6 +56,7 @@
 @Inject
 constructor(
     override val transitionRepository: KeyguardTransitionRepository,
+    override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
     transitionInteractor: KeyguardTransitionInteractor,
     @Background private val scope: CoroutineScope,
     @Background bgDispatcher: CoroutineDispatcher,
@@ -168,7 +170,9 @@
                     keyguardInteractor.isKeyguardGoingAway.filter { it }.map {}, // map to Unit
                     keyguardInteractor.isKeyguardOccluded.flatMapLatest { keyguardOccluded ->
                         if (keyguardOccluded) {
-                            primaryBouncerInteractor.keyguardAuthenticatedBiometricsHandled
+                            primaryBouncerInteractor.keyguardAuthenticatedBiometricsHandled.drop(
+                                1
+                            ) // drop the initial state
                         } else {
                             emptyFlow()
                         }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
index 2a9ee9f..d41c0c5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
@@ -44,6 +44,7 @@
 @Inject
 constructor(
     override val transitionRepository: KeyguardTransitionRepository,
+    override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
     transitionInteractor: KeyguardTransitionInteractor,
     @Background private val scope: CoroutineScope,
     @Background bgDispatcher: CoroutineDispatcher,
@@ -52,6 +53,7 @@
     powerInteractor: PowerInteractor,
     keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
     val deviceEntryRepository: DeviceEntryRepository,
+    private val wakeToGoneInteractor: KeyguardWakeDirectlyToGoneInteractor,
 ) :
     TransitionInteractor(
         fromState = KeyguardState.AOD,
@@ -97,6 +99,7 @@
                     keyguardInteractor.primaryBouncerShowing,
                     keyguardInteractor.isKeyguardOccluded,
                     canDismissLockscreen,
+                    wakeToGoneInteractor.canWakeDirectlyToGone,
                 )
                 .collect {
                     (
@@ -106,6 +109,7 @@
                         primaryBouncerShowing,
                         isKeyguardOccludedLegacy,
                         canDismissLockscreen,
+                        canWakeDirectlyToGone,
                     ) ->
                     if (!maybeHandleInsecurePowerGesture()) {
                         val shouldTransitionToLockscreen =
@@ -130,10 +134,11 @@
 
                         val shouldTransitionToGone =
                             (!KeyguardWmStateRefactor.isEnabled && canDismissLockscreen) ||
-                                (KeyguardWmStateRefactor.isEnabled &&
-                                    !deviceEntryRepository.isLockscreenEnabled())
+                                (KeyguardWmStateRefactor.isEnabled && canWakeDirectlyToGone)
 
                         if (shouldTransitionToGone) {
+                            // TODO(b/336576536): Check if adaptation for scene framework is needed
+                            if (SceneContainerFlag.isEnabled) return@collect
                             startTransitionTo(
                                 toState = KeyguardState.GONE,
                             )
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
index f3692bd..aee65a8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
@@ -28,6 +28,7 @@
 import com.android.systemui.keyguard.shared.model.BiometricUnlockMode.Companion.isWakeAndUnlock
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.util.kotlin.Utils.Companion.sample
 import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
@@ -44,6 +45,7 @@
 @Inject
 constructor(
     override val transitionRepository: KeyguardTransitionRepository,
+    override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
     transitionInteractor: KeyguardTransitionInteractor,
     @Background private val scope: CoroutineScope,
     @Background bgDispatcher: CoroutineDispatcher,
@@ -53,6 +55,7 @@
     private val communalInteractor: CommunalInteractor,
     keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
     val deviceEntryRepository: DeviceEntryRepository,
+    private val wakeToGoneInteractor: KeyguardWakeDirectlyToGoneInteractor,
 ) :
     TransitionInteractor(
         fromState = KeyguardState.DOZING,
@@ -99,10 +102,14 @@
                         biometricUnlockState,
                     ) ->
                     if (isWakeAndUnlock(biometricUnlockState.mode)) {
-                        startTransitionTo(
-                            KeyguardState.GONE,
-                            ownerReason = "biometric wake and unlock",
-                        )
+                        if (SceneContainerFlag.isEnabled) {
+                            // TODO(b/336576536): Check if adaptation for scene framework is needed
+                        } else {
+                            startTransitionTo(
+                                KeyguardState.GONE,
+                                ownerReason = "biometric wake and unlock",
+                            )
+                        }
                     }
                 }
         }
@@ -130,21 +137,35 @@
                         isIdleOnCommunal,
                         canTransitionToGoneOnWake,
                         primaryBouncerShowing) ->
-                    startTransitionTo(
-                        if (!deviceEntryRepository.isLockscreenEnabled()) {
-                            KeyguardState.GONE
-                        } else if (canTransitionToGoneOnWake) {
-                            KeyguardState.GONE
-                        } else if (primaryBouncerShowing) {
-                            KeyguardState.PRIMARY_BOUNCER
-                        } else if (occluded) {
-                            KeyguardState.OCCLUDED
-                        } else if (isIdleOnCommunal) {
-                            KeyguardState.GLANCEABLE_HUB
+                    if (!deviceEntryRepository.isLockscreenEnabled()) {
+                        if (SceneContainerFlag.isEnabled) {
+                            // TODO(b/336576536): Check if adaptation for scene framework is needed
                         } else {
-                            KeyguardState.LOCKSCREEN
+                            startTransitionTo(KeyguardState.GONE)
                         }
-                    )
+                    } else if (canTransitionToGoneOnWake) {
+                        if (SceneContainerFlag.isEnabled) {
+                            // TODO(b/336576536): Check if adaptation for scene framework is needed
+                        } else {
+                            startTransitionTo(KeyguardState.GONE)
+                        }
+                    } else if (primaryBouncerShowing) {
+                        if (SceneContainerFlag.isEnabled) {
+                            // TODO(b/336576536): Check if adaptation for scene framework is needed
+                        } else {
+                            startTransitionTo(KeyguardState.PRIMARY_BOUNCER)
+                        }
+                    } else if (occluded) {
+                        startTransitionTo(KeyguardState.OCCLUDED)
+                    } else if (isIdleOnCommunal) {
+                        if (SceneContainerFlag.isEnabled) {
+                            // TODO(b/336576536): Check if adaptation for scene framework is needed
+                        } else {
+                            startTransitionTo(KeyguardState.GLANCEABLE_HUB)
+                        }
+                    } else {
+                        startTransitionTo(KeyguardState.LOCKSCREEN)
+                    }
                 }
         }
     }
@@ -161,7 +182,7 @@
                 .sample(
                     communalInteractor.isIdleOnCommunal,
                     keyguardInteractor.biometricUnlockState,
-                    canTransitionToGoneOnWake,
+                    wakeToGoneInteractor.canWakeDirectlyToGone,
                     keyguardInteractor.primaryBouncerShowing,
                 )
                 .collect {
@@ -169,30 +190,49 @@
                         _,
                         isIdleOnCommunal,
                         biometricUnlockState,
-                        canDismissLockscreen,
+                        canWakeDirectlyToGone,
                         primaryBouncerShowing) ->
                     if (
                         !maybeStartTransitionToOccludedOrInsecureCamera() &&
                             // Handled by dismissFromDozing().
                             !isWakeAndUnlock(biometricUnlockState.mode)
                     ) {
-                        startTransitionTo(
-                            if (!KeyguardWmStateRefactor.isEnabled && canDismissLockscreen) {
-                                KeyguardState.GONE
-                            } else if (
-                                KeyguardWmStateRefactor.isEnabled &&
-                                    !deviceEntryRepository.isLockscreenEnabled()
-                            ) {
-                                KeyguardState.GONE
-                            } else if (primaryBouncerShowing) {
-                                KeyguardState.PRIMARY_BOUNCER
-                            } else if (isIdleOnCommunal) {
-                                KeyguardState.GLANCEABLE_HUB
+                        if (canWakeDirectlyToGone) {
+                            if (SceneContainerFlag.isEnabled) {
+                                // TODO(b/336576536): Check if adaptation for scene framework is
+                                // needed
                             } else {
-                                KeyguardState.LOCKSCREEN
-                            },
-                            ownerReason = "waking from dozing"
-                        )
+                                startTransitionTo(
+                                    KeyguardState.GONE,
+                                    ownerReason = "waking from dozing"
+                                )
+                            }
+                        } else if (primaryBouncerShowing) {
+                            if (SceneContainerFlag.isEnabled) {
+                                // TODO(b/336576536): Check if adaptation for scene framework is
+                                // needed
+                            } else {
+                                startTransitionTo(
+                                    KeyguardState.PRIMARY_BOUNCER,
+                                    ownerReason = "waking from dozing"
+                                )
+                            }
+                        } else if (isIdleOnCommunal) {
+                            if (SceneContainerFlag.isEnabled) {
+                                // TODO(b/336576536): Check if adaptation for scene framework is
+                                // needed
+                            } else {
+                                startTransitionTo(
+                                    KeyguardState.GLANCEABLE_HUB,
+                                    ownerReason = "waking from dozing"
+                                )
+                            }
+                        } else {
+                            startTransitionTo(
+                                KeyguardState.LOCKSCREEN,
+                                ownerReason = "waking from dozing"
+                            )
+                        }
                     }
                 }
         }
@@ -216,5 +256,6 @@
         val TO_LOCKSCREEN_DURATION = DEFAULT_DURATION
         val TO_GONE_DURATION = DEFAULT_DURATION
         val TO_PRIMARY_BOUNCER_DURATION = DEFAULT_DURATION
+        val TO_GLANCEABLE_HUB_DURATION = DEFAULT_DURATION
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractor.kt
index 47aa02a..117dbcf 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractor.kt
@@ -41,6 +41,7 @@
 @Inject
 constructor(
     override val transitionRepository: KeyguardTransitionRepository,
+    override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
     transitionInteractor: KeyguardTransitionInteractor,
     @Background private val scope: CoroutineScope,
     @Background bgDispatcher: CoroutineDispatcher,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
index 7fa197c..cfb161c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
@@ -23,6 +23,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.deviceentry.domain.interactor.DeviceEntryInteractor
 import com.android.systemui.keyguard.KeyguardWmStateRefactor
 import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.BiometricUnlockMode
@@ -37,16 +38,20 @@
 import kotlin.time.Duration.Companion.seconds
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.FlowPreview
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.debounce
+import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.launch
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SysUISingleton
 class FromDreamingTransitionInteractor
 @Inject
 constructor(
     override val transitionRepository: KeyguardTransitionRepository,
+    override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
     transitionInteractor: KeyguardTransitionInteractor,
     @Background private val scope: CoroutineScope,
     @Background bgDispatcher: CoroutineDispatcher,
@@ -55,6 +60,7 @@
     private val glanceableHubTransitions: GlanceableHubTransitions,
     powerInteractor: PowerInteractor,
     keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
+    private val deviceEntryInteractor: DeviceEntryInteractor,
 ) :
     TransitionInteractor(
         fromState = KeyguardState.DREAMING,
@@ -71,7 +77,7 @@
         listenForDreamingToOccluded()
         listenForDreamingToGoneWhenDismissable()
         listenForDreamingToGoneFromBiometricUnlock()
-        listenForDreamingToLockscreen()
+        listenForDreamingToLockscreenOrGone()
         listenForDreamingToAodOrDozing()
         listenForTransitionToCamera(scope, keyguardInteractor)
         listenForDreamingToGlanceableHub()
@@ -90,8 +96,8 @@
 
     private fun listenForDreamingToGlanceableHub() {
         if (!communalHub()) return
-        if (SceneContainerFlag.isEnabled)
-            return // TODO(b/336576536): Check if adaptation for scene framework is needed
+        // TODO(b/336576536): Check if adaptation for scene framework is needed
+        if (SceneContainerFlag.isEnabled) return
         scope.launch("$TAG#listenForDreamingToGlanceableHub", mainDispatcher) {
             glanceableHubTransitions.listenForGlanceableHubTransition(
                 transitionOwnerName = TAG,
@@ -102,6 +108,8 @@
     }
 
     private fun listenForDreamingToPrimaryBouncer() {
+        // TODO(b/336576536): Check if adaptation for scene framework is needed
+        if (SceneContainerFlag.isEnabled) return
         scope.launch {
             keyguardInteractor.primaryBouncerShowing
                 .sample(startedKeyguardTransitionStep, ::Pair)
@@ -129,17 +137,7 @@
 
     @OptIn(FlowPreview::class)
     private fun listenForDreamingToOccluded() {
-        if (KeyguardWmStateRefactor.isEnabled) {
-            scope.launch {
-                combine(
-                        keyguardInteractor.isDreaming,
-                        keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop,
-                        ::Pair
-                    )
-                    .filterRelevantKeyguardStateAnd { (isDreaming, _) -> !isDreaming }
-                    .collect { maybeStartTransitionToOccludedOrInsecureCamera() }
-            }
-        } else {
+        if (!KeyguardWmStateRefactor.isEnabled) {
             scope.launch {
                 combine(
                         keyguardInteractor.isKeyguardOccluded,
@@ -165,21 +163,41 @@
         }
     }
 
-    private fun listenForDreamingToLockscreen() {
+    private fun listenForDreamingToLockscreenOrGone() {
         if (!KeyguardWmStateRefactor.isEnabled) {
             return
         }
 
         scope.launch {
-            keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop
-                .filterRelevantKeyguardStateAnd { onTop -> !onTop }
-                .collect { startTransitionTo(KeyguardState.LOCKSCREEN) }
+            keyguardInteractor.isDreaming
+                .filter { !it }
+                .sample(deviceEntryInteractor.isUnlocked, ::Pair)
+                .collect { (_, dismissable) ->
+                    // TODO(b/349837588): Add check for -> OCCLUDED.
+                    if (dismissable) {
+                        startTransitionTo(
+                            KeyguardState.GONE,
+                            ownerReason = "No longer dreaming; dismissable"
+                        )
+                    } else {
+                        startTransitionTo(
+                            KeyguardState.LOCKSCREEN,
+                            ownerReason = "No longer dreaming"
+                        )
+                    }
+                }
         }
     }
 
     private fun listenForDreamingToGoneWhenDismissable() {
-        if (SceneContainerFlag.isEnabled)
+        if (SceneContainerFlag.isEnabled) {
             return // TODO(b/336576536): Check if adaptation for scene framework is needed
+        }
+
+        if (KeyguardWmStateRefactor.isEnabled) {
+            return
+        }
+
         scope.launch {
             keyguardInteractor.isAbleToDream
                 .sampleCombine(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
index e516fa3..2eca9e1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
@@ -50,6 +50,7 @@
     private val glanceableHubTransitions: GlanceableHubTransitions,
     keyguardInteractor: KeyguardInteractor,
     override val transitionRepository: KeyguardTransitionRepository,
+    override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
     transitionInteractor: KeyguardTransitionInteractor,
     powerInteractor: PowerInteractor,
     keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
@@ -166,6 +167,8 @@
     }
 
     private fun listenForHubToGone() {
+        // TODO(b/336576536): Check if adaptation for scene framework is needed
+        if (SceneContainerFlag.isEnabled) return
         scope.launch {
             keyguardInteractor.isKeyguardGoingAway
                 .filterRelevantKeyguardStateAnd { isKeyguardGoingAway -> isKeyguardGoingAway }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
index f5b12a2..b084824 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
@@ -45,6 +45,7 @@
 @Inject
 constructor(
     override val transitionRepository: KeyguardTransitionRepository,
+    override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
     transitionInteractor: KeyguardTransitionInteractor,
     @Background private val scope: CoroutineScope,
     @Background bgDispatcher: CoroutineDispatcher,
@@ -99,19 +100,21 @@
                     }
             }
 
-            scope.launch {
-                keyguardRepository.isKeyguardEnabled
-                    .filterRelevantKeyguardStateAnd { enabled -> enabled }
-                    .sample(keyguardEnabledInteractor.showKeyguardWhenReenabled)
-                    .filter { reshow -> reshow }
-                    .collect {
-                        startTransitionTo(
-                            KeyguardState.LOCKSCREEN,
-                            ownerReason =
-                                "Keyguard was re-enabled, and we weren't GONE when it " +
-                                    "was originally disabled"
-                        )
-                    }
+            if (!SceneContainerFlag.isEnabled) {
+                scope.launch {
+                    keyguardRepository.isKeyguardEnabled
+                        .filterRelevantKeyguardStateAnd { enabled -> enabled }
+                        .sample(keyguardEnabledInteractor.showKeyguardWhenReenabled)
+                        .filter { reshow -> reshow }
+                        .collect {
+                            startTransitionTo(
+                                KeyguardState.LOCKSCREEN,
+                                ownerReason =
+                                    "Keyguard was re-enabled, and we weren't GONE when it " +
+                                        "was originally disabled"
+                            )
+                        }
+                }
             }
         } else {
             scope.launch("$TAG#listenForGoneToLockscreenOrHub") {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
index f30eef0..343a135 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
@@ -34,6 +34,7 @@
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.power.shared.model.WakeSleepReason.FOLD
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shade.data.repository.ShadeRepository
@@ -56,6 +57,7 @@
 @Inject
 constructor(
     override val transitionRepository: KeyguardTransitionRepository,
+    override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
     transitionInteractor: KeyguardTransitionInteractor,
     @Background private val scope: CoroutineScope,
     @Background bgDispatcher: CoroutineDispatcher,
@@ -127,7 +129,7 @@
             keyguardInteractor.isAbleToDream
                 .filterRelevantKeyguardState()
                 .sampleCombine(
-                    transitionInteractor.currentTransitionInfoInternal,
+                    internalTransitionInteractor.currentTransitionInfoInternal,
                     finishedKeyguardState,
                     keyguardInteractor.isActiveDreamLockscreenHosted,
                 )
@@ -184,7 +186,7 @@
             shadeRepository.legacyShadeExpansion
                 .sampleCombine(
                     startedKeyguardTransitionStep,
-                    transitionInteractor.currentTransitionInfoInternal,
+                    internalTransitionInteractor.currentTransitionInfoInternal,
                     keyguardInteractor.statusBarState,
                     keyguardInteractor.isKeyguardDismissible,
                 )
@@ -270,10 +272,9 @@
     }
 
     private fun listenForLockscreenToGone() {
-        if (KeyguardWmStateRefactor.isEnabled) {
-            return
-        }
-
+        // TODO(b/336576536): Check if adaptation for scene framework is needed
+        if (SceneContainerFlag.isEnabled) return
+        if (KeyguardWmStateRefactor.isEnabled) return
         scope.launch("$TAG#listenForLockscreenToGone") {
             keyguardInteractor.isKeyguardGoingAway
                 .filterRelevantKeyguardStateAnd { isKeyguardGoingAway -> isKeyguardGoingAway }
@@ -287,6 +288,7 @@
     }
 
     private fun listenForLockscreenToGoneDragging() {
+        // TODO(b/336576536): Check if adaptation for scene framework is needed
         if (SceneContainerFlag.isEnabled) return
         if (KeyguardWmStateRefactor.isEnabled) {
             // When the refactor is enabled, we no longer use isKeyguardGoingAway.
@@ -368,7 +370,12 @@
                     // being delayed in KeyguardViewMediator
                     KeyguardState.DREAMING -> TO_DREAMING_DURATION + 100.milliseconds
                     KeyguardState.OCCLUDED -> TO_OCCLUDED_DURATION
-                    KeyguardState.AOD -> TO_AOD_DURATION
+                    KeyguardState.AOD ->
+                        if (powerInteractor.detailedWakefulness.value.lastSleepReason == FOLD) {
+                            TO_AOD_FOLD_DURATION
+                        } else {
+                            TO_AOD_DURATION
+                        }
                     KeyguardState.DOZING -> TO_DOZING_DURATION
                     KeyguardState.DREAMING_LOCKSCREEN_HOSTED -> TO_DREAMING_HOSTED_DURATION
                     KeyguardState.GLANCEABLE_HUB -> TO_GLANCEABLE_HUB_DURATION
@@ -385,6 +392,7 @@
         val TO_DREAMING_HOSTED_DURATION = 933.milliseconds
         val TO_OCCLUDED_DURATION = 450.milliseconds
         val TO_AOD_DURATION = 500.milliseconds
+        val TO_AOD_FOLD_DURATION = 1100.milliseconds
         val TO_PRIMARY_BOUNCER_DURATION = DEFAULT_DURATION
         val TO_GONE_DURATION = 633.milliseconds
         val TO_GLANCEABLE_HUB_DURATION = 1.seconds
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
index 86d4cfb..84ca667 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
@@ -41,6 +41,7 @@
 @Inject
 constructor(
     override val transitionRepository: KeyguardTransitionRepository,
+    override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
     transitionInteractor: KeyguardTransitionInteractor,
     @Background private val scope: CoroutineScope,
     @Background bgDispatcher: CoroutineDispatcher,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
index f8208b3..2429088 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
@@ -40,7 +40,6 @@
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.launch
@@ -50,6 +49,7 @@
 @Inject
 constructor(
     override val transitionRepository: KeyguardTransitionRepository,
+    override val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
     transitionInteractor: KeyguardTransitionInteractor,
     @Background private val scope: CoroutineScope,
     @Background bgDispatcher: CoroutineDispatcher,
@@ -80,25 +80,18 @@
     }
 
     val surfaceBehindVisibility: Flow<Boolean?> =
-        if (SceneContainerFlag.isEnabled) {
-            // The edge Scenes.Bouncer <-> Scenes.Gone is handled by STL
-            flowOf(null)
-        } else {
-            transitionInteractor
-                .transition(
-                    edge = Edge.INVALID,
-                    edgeWithoutSceneContainer =
-                        Edge.create(from = KeyguardState.PRIMARY_BOUNCER, to = KeyguardState.GONE)
-                )
-                .map<TransitionStep, Boolean?> {
-                    it.value > TO_GONE_SURFACE_BEHIND_VISIBLE_THRESHOLD
-                }
-                .onStart {
-                    // Default to null ("don't care, use a reasonable default").
-                    emit(null)
-                }
-                .distinctUntilChanged()
-        }
+        transitionInteractor
+            .transition(
+                edge = Edge.INVALID,
+                edgeWithoutSceneContainer =
+                    Edge.create(from = KeyguardState.PRIMARY_BOUNCER, to = KeyguardState.GONE)
+            )
+            .map<TransitionStep, Boolean?> { it.value > TO_GONE_SURFACE_BEHIND_VISIBLE_THRESHOLD }
+            .onStart {
+                // Default to null ("don't care, use a reasonable default").
+                emit(null)
+            }
+            .distinctUntilChanged()
 
     fun dismissPrimaryBouncer() {
         scope.launch { startTransitionTo(KeyguardState.GONE) }
@@ -233,6 +226,7 @@
                     KeyguardState.DOZING -> TO_DOZING_DURATION
                     KeyguardState.GONE -> TO_GONE_DURATION
                     KeyguardState.LOCKSCREEN -> TO_LOCKSCREEN_DURATION
+                    KeyguardState.GLANCEABLE_HUB -> TO_GLANCEABLE_HUB_DURATION
                     else -> DEFAULT_DURATION
                 }.inWholeMilliseconds
         }
@@ -245,6 +239,7 @@
         val TO_GONE_DURATION = 500.milliseconds
         val TO_GONE_SHORT_DURATION = 200.milliseconds
         val TO_LOCKSCREEN_DURATION = 450.milliseconds
+        val TO_GLANCEABLE_HUB_DURATION = DEFAULT_DURATION
         val TO_GONE_SURFACE_BEHIND_VISIBLE_THRESHOLD = 0.5f
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/InternalKeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/InternalKeyguardTransitionInteractor.kt
new file mode 100644
index 0000000..a51421c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/InternalKeyguardTransitionInteractor.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyguard.domain.interactor
+
+import android.annotation.FloatRange
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.TransitionInfo
+import com.android.systemui.keyguard.shared.model.TransitionState
+import java.util.UUID
+import javax.inject.Inject
+import kotlinx.coroutines.flow.StateFlow
+
+/**
+ * This interactor provides direct access to [KeyguardTransitionRepository] internals and exposes
+ * functions to directly modify the transition state.
+ */
+@SysUISingleton
+class InternalKeyguardTransitionInteractor
+@Inject
+constructor(
+    private val repository: KeyguardTransitionRepository,
+) {
+
+    /**
+     * The [TransitionInfo] of the most recent call to
+     * [KeyguardTransitionRepository.startTransition].
+     *
+     * This should only be used by keyguard transition internals (From*TransitionInteractor and
+     * related classes). Other consumers of keyguard state in System UI should use
+     * [startedKeyguardState], [currentKeyguardState], and related flows.
+     *
+     * Keyguard internals use this to determine the most up-to-date KeyguardState that we've
+     * requested a transition to, even if the animator running the transition on the main thread has
+     * not yet emitted the STARTED TransitionStep.
+     *
+     * For example: if we're finished in GONE and press the power button twice very quickly, we may
+     * request a transition to AOD, but then receive the second power button press prior to the
+     * STARTED -> AOD transition step emitting. We still need the FromAodTransitionInteractor to
+     * request a transition from AOD -> LOCKSCREEN in response to the power press, even though the
+     * main thread animator hasn't emitted STARTED > AOD yet (which means [startedKeyguardState] is
+     * still GONE, which is not relevant to FromAodTransitionInteractor). In this case, the
+     * interactor can use this current transition info to determine that a STARTED -> AOD step
+     * *will* be emitted, and therefore that it can safely request an AOD -> LOCKSCREEN transition
+     * which will subsequently cancel GONE -> AOD.
+     */
+    internal val currentTransitionInfoInternal: StateFlow<TransitionInfo> =
+        repository.currentTransitionInfoInternal
+
+    suspend fun startTransition(info: TransitionInfo) = repository.startTransition(info)
+
+    fun updateTransition(
+        transitionId: UUID,
+        @FloatRange(from = 0.0, to = 1.0) value: Float,
+        state: TransitionState
+    ) = repository.updateTransition(transitionId, value, state)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt
index 8dede01..4aef808 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractor.kt
@@ -21,12 +21,15 @@
 import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
 import com.android.systemui.keyguard.data.repository.KeyguardRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.launch
 
 /**
@@ -46,27 +49,21 @@
     val repository: KeyguardRepository,
     val biometricSettingsRepository: BiometricSettingsRepository,
     transitionInteractor: KeyguardTransitionInteractor,
+    internalTransitionInteractor: InternalKeyguardTransitionInteractor,
 ) {
 
-    init {
-        /**
-         * Whenever keyguard is disabled, transition to GONE unless we're in lockdown or already
-         * GONE.
-         */
-        scope.launch {
-            repository.isKeyguardEnabled
-                .filter { enabled -> !enabled }
-                .sampleCombine(
-                    biometricSettingsRepository.isCurrentUserInLockdown,
-                    transitionInteractor.currentTransitionInfoInternal,
-                )
-                .collect { (_, inLockdown, currentTransitionInfo) ->
-                    if (currentTransitionInfo.to != KeyguardState.GONE && !inLockdown) {
-                        transitionInteractor.startDismissKeyguardTransition("keyguard disabled")
-                    }
-                }
-        }
-    }
+    /**
+     * Whether the keyguard is enabled, per [KeyguardService]. If the keyguard is not enabled, the
+     * lockscreen cannot be shown and the device will go from AOD/DOZING directly to GONE.
+     *
+     * Keyguard can be disabled by selecting Security: "None" in settings, or by apps that hold
+     * permission to do so (such as Phone).
+     *
+     * If the keyguard is disabled while we're locked, we will transition to GONE unless we're in
+     * lockdown mode. If the keyguard is re-enabled, we'll transition back to LOCKSCREEN if we were
+     * locked when it was disabled.
+     */
+    val isKeyguardEnabled: StateFlow<Boolean> = repository.isKeyguardEnabled
 
     /**
      * Whether we need to show the keyguard when the keyguard is re-enabled, since we hid it when it
@@ -74,10 +71,11 @@
      */
     val showKeyguardWhenReenabled: Flow<Boolean> =
         repository.isKeyguardEnabled
+            .onEach { SceneContainerFlag.assertInLegacyMode() }
             // Whenever the keyguard is disabled...
             .filter { enabled -> !enabled }
             .sampleCombine(
-                transitionInteractor.currentTransitionInfoInternal,
+                internalTransitionInteractor.currentTransitionInfoInternal,
                 biometricSettingsRepository.isCurrentUserInLockdown
             )
             .map { (_, transitionInfo, inLockdown) ->
@@ -86,7 +84,31 @@
                 transitionInfo.to != KeyguardState.GONE && !inLockdown
             }
 
+    init {
+        /**
+         * Whenever keyguard is disabled, transition to GONE unless we're in lockdown or already
+         * GONE.
+         */
+        scope.launch {
+            if (!SceneContainerFlag.isEnabled) {
+                showKeyguardWhenReenabled
+                    .filter { shouldDismiss -> shouldDismiss }
+                    .collect {
+                        transitionInteractor.startDismissKeyguardTransition("keyguard disabled")
+                    }
+            }
+        }
+    }
+
     fun notifyKeyguardEnabled(enabled: Boolean) {
         repository.setKeyguardEnabled(enabled)
     }
+
+    fun setShowKeyguardWhenReenabled(isShowKeyguardWhenReenabled: Boolean) {
+        repository.setShowKeyguardWhenReenabled(isShowKeyguardWhenReenabled)
+    }
+
+    fun isShowKeyguardWhenReenabled(): Boolean {
+        return repository.isShowKeyguardWhenReenabled()
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index ef96be0..ec03a6d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -23,9 +23,10 @@
 import android.graphics.Point
 import android.util.MathUtils
 import com.android.app.animation.Interpolators
+import com.android.app.tracing.FlowTracing.tracedAwaitClose
+import com.android.app.tracing.FlowTracing.tracedConflatedCallbackFlow
 import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository
 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
-import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.common.shared.model.NotificationContainerBounds
 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
 import com.android.systemui.dagger.SysUISingleton
@@ -51,14 +52,12 @@
 import com.android.systemui.statusbar.notification.NotificationUtils.interpolate
 import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
 import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine
-import com.android.systemui.util.kotlin.Utils.Companion.sampleFilter
 import com.android.systemui.util.kotlin.pairwise
 import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
 import javax.inject.Provider
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -198,22 +197,22 @@
     val isActiveDreamLockscreenHosted: StateFlow<Boolean> = repository.isActiveDreamLockscreenHosted
 
     /** Event for when the camera gesture is detected */
-    val onCameraLaunchDetected: Flow<CameraLaunchSourceModel> = conflatedCallbackFlow {
-        val callback =
-            object : CommandQueue.Callbacks {
-                override fun onCameraLaunchGestureDetected(source: Int) {
-                    trySendWithFailureLogging(
-                        cameraLaunchSourceIntToModel(source),
-                        TAG,
-                        "updated onCameraLaunchGestureDetected"
-                    )
+    val onCameraLaunchDetected: Flow<CameraLaunchSourceModel> =
+        tracedConflatedCallbackFlow("KeyguardInteractor#onCameraLaunchDetected") {
+            val callback =
+                object : CommandQueue.Callbacks {
+                    override fun onCameraLaunchGestureDetected(source: Int) {
+                        trySendWithFailureLogging(
+                            cameraLaunchSourceIntToModel(source),
+                            TAG,
+                            "updated onCameraLaunchGestureDetected")
+                    }
                 }
-            }
 
-        commandQueue.addCallback(callback)
+            commandQueue.addCallback(callback)
 
-        awaitClose { commandQueue.removeCallback(callback) }
-    }
+            tracedAwaitClose("onCameraLaunchDetected") { commandQueue.removeCallback(callback) }
+        }
 
     /**
      * Dozing and dreaming have overlapping events. If the doze state remains in FINISH, it means
@@ -251,13 +250,17 @@
 
     /** Keyguard can be clipped at the top as the shade is dragged */
     val topClippingBounds: Flow<Int?> by lazy {
-        repository.topClippingBounds
-            .sampleFilter(
+        combineTransform(
                 keyguardTransitionInteractor
                     .transitionValue(scene = Scenes.Gone, stateWithoutSceneContainer = GONE)
-                    .onStart { emit(0f) }
-            ) { goneValue ->
-                goneValue != 1f
+                    .map { it == 1f }
+                    .onStart { emit(false) }
+                    .distinctUntilChanged(),
+                repository.topClippingBounds
+            ) { isGone, topClippingBounds ->
+                if (!isGone) {
+                    emit(topClippingBounds)
+                }
             }
             .distinctUntilChanged()
     }
@@ -321,6 +324,10 @@
     @Deprecated("Use the relevant TransitionViewModel")
     val keyguardAlpha: Flow<Float> = repository.keyguardAlpha
 
+    /** Temporary shim for fading out content when the brightness slider is used */
+    @Deprecated("SceneContainer uses NotificationStackAppearanceInteractor")
+    val panelAlpha: StateFlow<Float> = repository.panelAlpha.asStateFlow()
+
     /**
      * When the lockscreen can be dismissed, emit an alpha value as the user swipes up. This is
      * useful just before the code commits to moving to GONE.
@@ -458,6 +465,10 @@
         repository.setKeyguardAlpha(alpha)
     }
 
+    fun setPanelAlpha(alpha: Float) {
+        repository.setPanelAlpha(alpha)
+    }
+
     fun setAnimateDozingTransitions(animate: Boolean) {
         repository.setAnimateDozingTransitions(animate)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt
deleted file mode 100644
index bb6215a..0000000
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractor.kt
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.keyguard.domain.interactor
-
-import android.content.Context
-import android.content.Intent
-import android.content.IntentFilter
-import android.view.accessibility.AccessibilityManager
-import androidx.annotation.VisibleForTesting
-import com.android.internal.logging.UiEvent
-import com.android.internal.logging.UiEventLogger
-import com.android.systemui.broadcast.BroadcastDispatcher
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.flags.Flags
-import com.android.systemui.keyguard.data.repository.KeyguardRepository
-import com.android.systemui.keyguard.shared.model.KeyguardState
-import com.android.systemui.res.R
-import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
-import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.flow.stateIn
-import kotlinx.coroutines.launch
-
-/** Business logic for use-cases related to the keyguard long-press feature. */
-@OptIn(ExperimentalCoroutinesApi::class)
-@SysUISingleton
-class KeyguardLongPressInteractor
-@Inject
-constructor(
-    @Application private val appContext: Context,
-    @Application private val scope: CoroutineScope,
-    transitionInteractor: KeyguardTransitionInteractor,
-    repository: KeyguardRepository,
-    private val logger: UiEventLogger,
-    private val featureFlags: FeatureFlags,
-    broadcastDispatcher: BroadcastDispatcher,
-    private val accessibilityManager: AccessibilityManagerWrapper,
-) {
-    /** Whether the long-press handling feature should be enabled. */
-    val isLongPressHandlingEnabled: StateFlow<Boolean> =
-        if (isFeatureEnabled()) {
-                combine(
-                    transitionInteractor.finishedKeyguardState.map {
-                        it == KeyguardState.LOCKSCREEN
-                    },
-                    repository.isQuickSettingsVisible,
-                ) { isFullyTransitionedToLockScreen, isQuickSettingsVisible ->
-                    isFullyTransitionedToLockScreen && !isQuickSettingsVisible
-                }
-            } else {
-                flowOf(false)
-            }
-            .stateIn(
-                scope = scope,
-                started = SharingStarted.WhileSubscribed(),
-                initialValue = false,
-            )
-
-    private val _isMenuVisible = MutableStateFlow(false)
-    /** Model for whether the menu should be shown. */
-    val isMenuVisible: StateFlow<Boolean> =
-        isLongPressHandlingEnabled
-            .flatMapLatest { isEnabled ->
-                if (isEnabled) {
-                    _isMenuVisible.asStateFlow()
-                } else {
-                    // Reset the state so we don't see a menu when long-press handling is enabled
-                    // again in the future.
-                    _isMenuVisible.value = false
-                    flowOf(false)
-                }
-            }
-            .stateIn(
-                scope = scope,
-                started = SharingStarted.WhileSubscribed(),
-                initialValue = false,
-            )
-
-    private val _shouldOpenSettings = MutableStateFlow(false)
-    /**
-     * Whether the long-press accessible "settings" flow should be opened.
-     *
-     * Note that [onSettingsShown] must be invoked to consume this, once the settings are opened.
-     */
-    val shouldOpenSettings = _shouldOpenSettings.asStateFlow()
-
-    private var delayedHideMenuJob: Job? = null
-
-    init {
-        if (isFeatureEnabled()) {
-            broadcastDispatcher
-                .broadcastFlow(
-                    IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS),
-                )
-                .onEach { hideMenu() }
-                .launchIn(scope)
-        }
-    }
-
-    /** Notifies that the user has long-pressed on the lock screen. */
-    fun onLongPress() {
-        if (!isLongPressHandlingEnabled.value) {
-            return
-        }
-
-        if (featureFlags.isEnabled(Flags.LOCK_SCREEN_LONG_PRESS_DIRECT_TO_WPP)) {
-            showSettings()
-        } else {
-            showMenu()
-        }
-    }
-
-    /** Notifies that the user has touched outside of the pop-up. */
-    fun onTouchedOutside() {
-        hideMenu()
-    }
-
-    /** Notifies that the user has started a touch gesture on the menu. */
-    fun onMenuTouchGestureStarted() {
-        cancelAutomaticMenuHiding()
-    }
-
-    /** Notifies that the user has started a touch gesture on the menu. */
-    fun onMenuTouchGestureEnded(isClick: Boolean) {
-        if (isClick) {
-            hideMenu()
-            logger.log(LogEvents.LOCK_SCREEN_LONG_PRESS_POPUP_CLICKED)
-            showSettings()
-        } else {
-            scheduleAutomaticMenuHiding()
-        }
-    }
-
-    /** Notifies that the settings UI has been shown, consuming the event to show it. */
-    fun onSettingsShown() {
-        _shouldOpenSettings.value = false
-    }
-
-    private fun showSettings() {
-        _shouldOpenSettings.value = true
-    }
-
-    private fun isFeatureEnabled(): Boolean {
-        return featureFlags.isEnabled(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED) &&
-            appContext.resources.getBoolean(R.bool.long_press_keyguard_customize_lockscreen_enabled)
-    }
-
-    /** Updates application state to ask to show the menu. */
-    private fun showMenu() {
-        _isMenuVisible.value = true
-        scheduleAutomaticMenuHiding()
-        logger.log(LogEvents.LOCK_SCREEN_LONG_PRESS_POPUP_SHOWN)
-    }
-
-    private fun scheduleAutomaticMenuHiding() {
-        cancelAutomaticMenuHiding()
-        delayedHideMenuJob =
-            scope.launch {
-                delay(timeOutMs())
-                hideMenu()
-            }
-    }
-
-    /** Updates application state to ask to hide the menu. */
-    private fun hideMenu() {
-        cancelAutomaticMenuHiding()
-        _isMenuVisible.value = false
-    }
-
-    private fun cancelAutomaticMenuHiding() {
-        delayedHideMenuJob?.cancel()
-        delayedHideMenuJob = null
-    }
-
-    private fun timeOutMs(): Long {
-        return accessibilityManager
-            .getRecommendedTimeoutMillis(
-                DEFAULT_POPUP_AUTO_HIDE_TIMEOUT_MS.toInt(),
-                AccessibilityManager.FLAG_CONTENT_ICONS or
-                    AccessibilityManager.FLAG_CONTENT_TEXT or
-                    AccessibilityManager.FLAG_CONTENT_CONTROLS,
-            )
-            .toLong()
-    }
-
-    enum class LogEvents(
-        private val _id: Int,
-    ) : UiEventLogger.UiEventEnum {
-        @UiEvent(doc = "The lock screen was long-pressed and we showed the settings popup menu.")
-        LOCK_SCREEN_LONG_PRESS_POPUP_SHOWN(1292),
-        @UiEvent(doc = "The lock screen long-press popup menu was clicked.")
-        LOCK_SCREEN_LONG_PRESS_POPUP_CLICKED(1293),
-        ;
-
-        override fun getId() = _id
-    }
-
-    companion object {
-        @VisibleForTesting const val DEFAULT_POPUP_AUTO_HIDE_TIMEOUT_MS = 5000L
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractor.kt
index f385671..7f1e881 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractor.kt
@@ -24,6 +24,7 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.power.domain.interactor.PowerInteractor
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.util.kotlin.sample
 import dagger.Lazy
 import javax.inject.Inject
@@ -53,6 +54,7 @@
     private val repository: KeyguardOcclusionRepository,
     private val powerInteractor: PowerInteractor,
     private val transitionInteractor: KeyguardTransitionInteractor,
+    private val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
     keyguardInteractor: KeyguardInteractor,
     deviceUnlockedInteractor: Lazy<DeviceUnlockedInteractor>,
 ) {
@@ -78,7 +80,7 @@
         // *_BOUNCER -> LOCKSCREEN.
         return powerInteractor.detailedWakefulness.value.powerButtonLaunchGestureTriggered &&
             KeyguardState.deviceIsAsleepInState(
-                transitionInteractor.currentTransitionInfoInternal.value.to
+                internalTransitionInteractor.currentTransitionInfoInternal.value.to
             )
     }
 
@@ -93,10 +95,15 @@
                 // currently
                 // GONE, in which case we're going back to GONE and launching the insecure camera).
                 powerInteractor.detailedWakefulness
-                    .sample(transitionInteractor.currentKeyguardState, ::Pair)
-                    .map { (wakefulness, currentKeyguardState) ->
-                        wakefulness.powerButtonLaunchGestureTriggered &&
-                            currentKeyguardState != KeyguardState.GONE
+                    .sample(
+                        transitionInteractor.isFinishedIn(
+                            scene = Scenes.Gone,
+                            stateWithoutSceneContainer = KeyguardState.GONE,
+                        ),
+                        ::Pair
+                    )
+                    .map { (wakefulness, isOnGone) ->
+                        wakefulness.powerButtonLaunchGestureTriggered && !isOnGone
                     },
                 // Emit false once that activity goes away.
                 isShowWhenLockedActivityOnTop.filter { !it }.map { false }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt
index 82255a0..377a03e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractor.kt
@@ -19,9 +19,10 @@
 import android.content.Context
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.data.repository.KeyguardSurfaceBehindRepository
-import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor.Companion.isSurfaceVisible
+import com.android.systemui.keyguard.shared.model.Edge
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.KeyguardSurfaceBehindModel
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor
 import com.android.systemui.util.kotlin.sample
 import com.android.systemui.util.kotlin.toPx
@@ -56,12 +57,18 @@
      */
     val viewParams: Flow<KeyguardSurfaceBehindModel> =
         combine(
-                transitionInteractor.startedKeyguardTransitionStep,
-                transitionInteractor.currentKeyguardState,
+                transitionInteractor.isInTransition(
+                    edge = Edge.create(to = Scenes.Gone),
+                    edgeWithoutSceneContainer = Edge.create(to = KeyguardState.GONE),
+                ),
+                transitionInteractor.isFinishedIn(
+                    scene = Scenes.Gone,
+                    stateWithoutSceneContainer = KeyguardState.GONE,
+                ),
                 notificationLaunchInteractor.isLaunchAnimationRunning,
-            ) { startedStep, currentState, notifAnimationRunning ->
+            ) { transitioningToGone, isOnGone, notifAnimationRunning ->
                 // If we're in transition to GONE, special unlock animation params apply.
-                if (startedStep.to == KeyguardState.GONE && currentState != KeyguardState.GONE) {
+                if (transitioningToGone) {
                     if (notifAnimationRunning) {
                         // If the notification launch animation is running, leave the alpha at 0f.
                         // The ActivityLaunchAnimator will morph it from the notification at the
@@ -87,14 +94,14 @@
                             animateFromTranslationY =
                                 SURFACE_TRANSLATION_Y_DISTANCE_DP.toPx(context).toFloat(),
                             translationY = 0f,
-                            startVelocity = swipeToDismissInteractor.dismissFling.value?.velocity
-                                    ?: 0f,
+                            startVelocity =
+                                swipeToDismissInteractor.dismissFling.value?.velocity ?: 0f,
                         )
                     }
                 }
 
                 // Default to the visibility of the current state, with no animations.
-                KeyguardSurfaceBehindModel(alpha = if (isSurfaceVisible(currentState)) 1f else 0f)
+                KeyguardSurfaceBehindModel(alpha = if (isOnGone) 1f else 0f)
             }
             .distinctUntilChanged()
 
@@ -103,10 +110,14 @@
      */
     private val isNotificationLaunchAnimationRunningOnKeyguard =
         notificationLaunchInteractor.isLaunchAnimationRunning
-            .sample(transitionInteractor.finishedKeyguardState, ::Pair)
-            .map { (animationRunning, finishedState) ->
-                animationRunning && finishedState != KeyguardState.GONE
-            }
+            .sample(
+                transitionInteractor.isFinishedIn(
+                    scene = Scenes.Gone,
+                    stateWithoutSceneContainer = KeyguardState.GONE,
+                ),
+                ::Pair
+            )
+            .map { (animationRunning, isOnGone) -> animationRunning && !isOnGone }
             .onStart { emit(false) }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt
new file mode 100644
index 0000000..7a06d2f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTouchHandlingInteractor.kt
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyguard.domain.interactor
+
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.view.accessibility.AccessibilityManager
+import androidx.annotation.VisibleForTesting
+import com.android.internal.logging.UiEvent
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.data.repository.KeyguardRepository
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.res.R
+import com.android.systemui.shade.PulsingGestureListener
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
+
+/** Business logic for use-cases related to top-level touch handling in the lock screen. */
+@OptIn(ExperimentalCoroutinesApi::class)
+@SysUISingleton
+class KeyguardTouchHandlingInteractor
+@Inject
+constructor(
+    @Application private val appContext: Context,
+    @Application private val scope: CoroutineScope,
+    transitionInteractor: KeyguardTransitionInteractor,
+    repository: KeyguardRepository,
+    private val logger: UiEventLogger,
+    private val featureFlags: FeatureFlags,
+    broadcastDispatcher: BroadcastDispatcher,
+    private val accessibilityManager: AccessibilityManagerWrapper,
+    private val pulsingGestureListener: PulsingGestureListener,
+) {
+    /** Whether the long-press handling feature should be enabled. */
+    val isLongPressHandlingEnabled: StateFlow<Boolean> =
+        if (isFeatureEnabled()) {
+                combine(
+                    transitionInteractor.finishedKeyguardState.map {
+                        it == KeyguardState.LOCKSCREEN
+                    },
+                    repository.isQuickSettingsVisible,
+                ) { isFullyTransitionedToLockScreen, isQuickSettingsVisible ->
+                    isFullyTransitionedToLockScreen && !isQuickSettingsVisible
+                }
+            } else {
+                flowOf(false)
+            }
+            .stateIn(
+                scope = scope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = false,
+            )
+
+    private val _isMenuVisible = MutableStateFlow(false)
+    /** Model for whether the menu should be shown. */
+    val isMenuVisible: StateFlow<Boolean> =
+        isLongPressHandlingEnabled
+            .flatMapLatest { isEnabled ->
+                if (isEnabled) {
+                    _isMenuVisible.asStateFlow()
+                } else {
+                    // Reset the state so we don't see a menu when long-press handling is enabled
+                    // again in the future.
+                    _isMenuVisible.value = false
+                    flowOf(false)
+                }
+            }
+            .stateIn(
+                scope = scope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = false,
+            )
+
+    private val _shouldOpenSettings = MutableStateFlow(false)
+    /**
+     * Whether the long-press accessible "settings" flow should be opened.
+     *
+     * Note that [onSettingsShown] must be invoked to consume this, once the settings are opened.
+     */
+    val shouldOpenSettings = _shouldOpenSettings.asStateFlow()
+
+    private var delayedHideMenuJob: Job? = null
+
+    init {
+        if (isFeatureEnabled()) {
+            broadcastDispatcher
+                .broadcastFlow(
+                    IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS),
+                )
+                .onEach { hideMenu() }
+                .launchIn(scope)
+        }
+    }
+
+    /** Notifies that the user has long-pressed on the lock screen. */
+    fun onLongPress() {
+        if (!isLongPressHandlingEnabled.value) {
+            return
+        }
+
+        if (featureFlags.isEnabled(Flags.LOCK_SCREEN_LONG_PRESS_DIRECT_TO_WPP)) {
+            showSettings()
+        } else {
+            showMenu()
+        }
+    }
+
+    /** Notifies that the user has touched outside of the pop-up. */
+    fun onTouchedOutside() {
+        hideMenu()
+    }
+
+    /** Notifies that the user has started a touch gesture on the menu. */
+    fun onMenuTouchGestureStarted() {
+        cancelAutomaticMenuHiding()
+    }
+
+    /** Notifies that the user has started a touch gesture on the menu. */
+    fun onMenuTouchGestureEnded(isClick: Boolean) {
+        if (isClick) {
+            hideMenu()
+            logger.log(LogEvents.LOCK_SCREEN_LONG_PRESS_POPUP_CLICKED)
+            showSettings()
+        } else {
+            scheduleAutomaticMenuHiding()
+        }
+    }
+
+    /** Notifies that the settings UI has been shown, consuming the event to show it. */
+    fun onSettingsShown() {
+        _shouldOpenSettings.value = false
+    }
+
+    /** Notifies that the lockscreen has been clicked at position [x], [y]. */
+    fun onClick(x: Float, y: Float) {
+        pulsingGestureListener.onSingleTapUp(x, y)
+    }
+
+    /** Notifies that the lockscreen has been double clicked. */
+    fun onDoubleClick() {
+        pulsingGestureListener.onDoubleTapEvent()
+    }
+
+    private fun showSettings() {
+        _shouldOpenSettings.value = true
+    }
+
+    private fun isFeatureEnabled(): Boolean {
+        return featureFlags.isEnabled(Flags.LOCK_SCREEN_LONG_PRESS_ENABLED) &&
+            appContext.resources.getBoolean(R.bool.long_press_keyguard_customize_lockscreen_enabled)
+    }
+
+    /** Updates application state to ask to show the menu. */
+    private fun showMenu() {
+        _isMenuVisible.value = true
+        scheduleAutomaticMenuHiding()
+        logger.log(LogEvents.LOCK_SCREEN_LONG_PRESS_POPUP_SHOWN)
+    }
+
+    private fun scheduleAutomaticMenuHiding() {
+        cancelAutomaticMenuHiding()
+        delayedHideMenuJob =
+            scope.launch {
+                delay(timeOutMs())
+                hideMenu()
+            }
+    }
+
+    /** Updates application state to ask to hide the menu. */
+    private fun hideMenu() {
+        cancelAutomaticMenuHiding()
+        _isMenuVisible.value = false
+    }
+
+    private fun cancelAutomaticMenuHiding() {
+        delayedHideMenuJob?.cancel()
+        delayedHideMenuJob = null
+    }
+
+    private fun timeOutMs(): Long {
+        return accessibilityManager
+            .getRecommendedTimeoutMillis(
+                DEFAULT_POPUP_AUTO_HIDE_TIMEOUT_MS.toInt(),
+                AccessibilityManager.FLAG_CONTENT_ICONS or
+                    AccessibilityManager.FLAG_CONTENT_TEXT or
+                    AccessibilityManager.FLAG_CONTENT_CONTROLS,
+            )
+            .toLong()
+    }
+
+    enum class LogEvents(
+        private val _id: Int,
+    ) : UiEventLogger.UiEventEnum {
+        @UiEvent(doc = "The lock screen was long-pressed and we showed the settings popup menu.")
+        LOCK_SCREEN_LONG_PRESS_POPUP_SHOWN(1292),
+        @UiEvent(doc = "The lock screen long-press popup menu was clicked.")
+        LOCK_SCREEN_LONG_PRESS_POPUP_CLICKED(1293),
+        ;
+
+        override fun getId() = _id
+    }
+
+    companion object {
+        @VisibleForTesting const val DEFAULT_POPUP_AUTO_HIDE_TIMEOUT_MS = 5000L
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractor.kt
index 5ad7762..805dbb0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractor.kt
@@ -22,7 +22,10 @@
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
 import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
-import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
+import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
+import com.android.systemui.keyguard.shared.model.KeyguardState.OFF
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.statusbar.policy.domain.interactor.DeviceProvisioningInteractor
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
@@ -40,6 +43,7 @@
     val deviceEntryInteractor: DeviceEntryInteractor,
     val deviceProvisioningInteractor: DeviceProvisioningInteractor,
     val keyguardTransitionInteractor: KeyguardTransitionInteractor,
+    val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
     val repository: KeyguardTransitionRepository,
 ) : CoreStartable {
 
@@ -56,17 +60,7 @@
 
     override fun start() {
         scope.launch {
-            val state =
-                if (showLockscreenOnBoot.first()) {
-                    KeyguardState.LOCKSCREEN
-                } else {
-                    KeyguardState.GONE
-                }
-
-            if (
-                keyguardTransitionInteractor.currentTransitionInfoInternal.value.from !=
-                    KeyguardState.OFF
-            ) {
+            if (internalTransitionInteractor.currentTransitionInfoInternal.value.from != OFF) {
                 Log.e(
                     "KeyguardTransitionInteractor",
                     "showLockscreenOnBoot emitted, but we've already " +
@@ -74,7 +68,23 @@
                         "transition, but this should not happen."
                 )
             } else {
-                repository.emitInitialStepsFromOff(state)
+                if (SceneContainerFlag.isEnabled) {
+                    // TODO(b/336576536): Some part of the transition implemented for flag off is
+                    //  missing here. There are two things achieved with this:
+                    //  1. Keyguard is hidden when the setup wizard is shown. This part is already
+                    //     implemented in scene container by disabling visibility instead of going
+                    //     to Gone. See [SceneContainerStartable.hydrateVisibility]. We might want
+                    //     to unify this logic here.
+                    //  2. When the auth method is set to NONE device boots into Gone (Launcher).
+                    //     For this we would just need to call changeScene(Scene.Gone).
+                    //     Unfortunately STL doesn't seem to be initialized at this point, therefore
+                    //     it needs a different solution.
+                    repository.emitInitialStepsFromOff(LOCKSCREEN)
+                } else {
+                    repository.emitInitialStepsFromOff(
+                        if (showLockscreenOnBoot.first()) LOCKSCREEN else GONE
+                    )
+                }
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
index 37272dc..f9bfaff 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
@@ -17,7 +17,6 @@
 
 package com.android.systemui.keyguard.domain.interactor
 
-import android.annotation.FloatRange
 import android.annotation.SuppressLint
 import android.util.Log
 import com.android.compose.animation.scene.SceneKey
@@ -33,14 +32,12 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
 import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
 import com.android.systemui.keyguard.shared.model.KeyguardState.UNDEFINED
-import com.android.systemui.keyguard.shared.model.TransitionInfo
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.util.kotlin.pairwise
-import java.util.UUID
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -50,6 +47,7 @@
 import kotlinx.coroutines.flow.SharedFlow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.map
@@ -75,7 +73,7 @@
     private val fromAlternateBouncerTransitionInteractor:
         dagger.Lazy<FromAlternateBouncerTransitionInteractor>,
     private val fromDozingTransitionInteractor: dagger.Lazy<FromDozingTransitionInteractor>,
-    private val sceneInteractor: dagger.Lazy<SceneInteractor>,
+    private val sceneInteractor: SceneInteractor,
 ) {
     private val transitionMap = mutableMapOf<Edge.StateToState, MutableSharedFlow<TransitionStep>>()
 
@@ -194,7 +192,7 @@
                 fun SceneKey?.isLockscreenOrNull() = this == Scenes.Lockscreen || this == null
 
                 return@filter (fromScene.isLockscreenOrNull() && toScene.isLockscreenOrNull()) ||
-                    sceneInteractor.get().transitionState.value.isTransitioning(fromScene, toScene)
+                    sceneInteractor.transitionState.value.isTransitioning(fromScene, toScene)
             }
         } else {
             flow
@@ -228,7 +226,7 @@
         stateWithoutSceneContainer: KeyguardState,
     ): Flow<Float> {
         return if (SceneContainerFlag.isEnabled) {
-            sceneInteractor.get().transitionProgress(scene)
+            sceneInteractor.transitionProgress(scene)
         } else {
             transitionValue(stateWithoutSceneContainer)
         }
@@ -383,33 +381,14 @@
             .distinctUntilChanged()
             .stateIn(scope, SharingStarted.Eagerly, KeyguardState.OFF)
 
-    /**
-     * The [TransitionInfo] of the most recent call to
-     * [KeyguardTransitionRepository.startTransition].
-     *
-     * This should only be used by keyguard transition internals (From*TransitionInteractor and
-     * related classes). Other consumers of keyguard state in System UI should use
-     * [startedKeyguardState], [currentKeyguardState], and related flows.
-     *
-     * Keyguard internals use this to determine the most up-to-date KeyguardState that we've
-     * requested a transition to, even if the animator running the transition on the main thread has
-     * not yet emitted the STARTED TransitionStep.
-     *
-     * For example: if we're finished in GONE and press the power button twice very quickly, we may
-     * request a transition to AOD, but then receive the second power button press prior to the
-     * STARTED -> AOD transition step emitting. We still need the FromAodTransitionInteractor to
-     * request a transition from AOD -> LOCKSCREEN in response to the power press, even though the
-     * main thread animator hasn't emitted STARTED > AOD yet (which means [startedKeyguardState] is
-     * still GONE, which is not relevant to FromAodTransitionInteractor). In this case, the
-     * interactor can use this current transition info to determine that a STARTED -> AOD step
-     * *will* be emitted, and therefore that it can safely request an AOD -> LOCKSCREEN transition
-     * which will subsequently cancel GONE -> AOD.
-     */
-    internal val currentTransitionInfoInternal: StateFlow<TransitionInfo> =
-        repository.currentTransitionInfoInternal
-
-    /** Whether we've currently STARTED a transition and haven't yet FINISHED it. */
-    val isInTransitionToAnyState = isInTransitionWhere({ true }, { true })
+    val isInTransition =
+        combine(
+            isInTransitionWhere({ true }, { true }),
+            sceneInteractor.transitionState,
+        ) { isKeyguardTransitioning, sceneTransitionState ->
+            isKeyguardTransitioning ||
+                (SceneContainerFlag.isEnabled && sceneTransitionState.isTransitioning())
+        }
 
     /**
      * Called to start a transition that will ultimately dismiss the keyguard from the current
@@ -422,7 +401,7 @@
         // TODO(b/336576536): Check if adaptation for scene framework is needed
         if (SceneContainerFlag.isEnabled) return
         Log.d(TAG, "#startDismissKeyguardTransition(reason=$reason)")
-        when (val startedState = currentTransitionInfoInternal.value.to) {
+        when (val startedState = repository.currentTransitionInfoInternal.value.to) {
             LOCKSCREEN -> fromLockscreenTransitionInteractor.get().dismissKeyguard()
             PRIMARY_BOUNCER -> fromPrimaryBouncerTransitionInteractor.get().dismissPrimaryBouncer()
             ALTERNATE_BOUNCER ->
@@ -448,7 +427,7 @@
     fun isInTransition(edge: Edge, edgeWithoutSceneContainer: Edge? = null): Flow<Boolean> {
         return if (SceneContainerFlag.isEnabled) {
                 if (edge.isSceneWildcardEdge()) {
-                    sceneInteractor.get().transitionState.map {
+                    sceneInteractor.transitionState.map {
                         when (edge) {
                             is Edge.StateToState ->
                                 throw IllegalStateException("Should not be reachable.")
@@ -469,30 +448,6 @@
     }
 
     /**
-     * Whether we're in a transition to a [KeyguardState] that matches the given predicate, but
-     * haven't yet completed it.
-     *
-     * If you only care about a single state, instead use the optimized [isInTransition].
-     */
-    fun isInTransitionToStateWhere(
-        stateMatcher: (KeyguardState) -> Boolean,
-    ): Flow<Boolean> {
-        return isInTransitionWhere(fromStatePredicate = { true }, toStatePredicate = stateMatcher)
-    }
-
-    /**
-     * Whether we're in a transition out of a [KeyguardState] that matches the given predicate, but
-     * haven't yet completed it.
-     *
-     * If you only care about a single state, instead use the optimized [isInTransition].
-     */
-    fun isInTransitionFromStateWhere(
-        stateMatcher: (KeyguardState) -> Boolean,
-    ): Flow<Boolean> {
-        return isInTransitionWhere(fromStatePredicate = stateMatcher, toStatePredicate = { true })
-    }
-
-    /**
      * Whether we're in a transition between two [KeyguardState]s that match the given predicates,
      * but haven't yet completed it.
      *
@@ -500,27 +455,15 @@
      * [isInTransition].
      */
     fun isInTransitionWhere(
-        fromStatePredicate: (KeyguardState) -> Boolean,
-        toStatePredicate: (KeyguardState) -> Boolean,
-    ): Flow<Boolean> {
-        return isInTransitionWhere { from, to -> fromStatePredicate(from) && toStatePredicate(to) }
-    }
-
-    /**
-     * Whether we're in a transition between two [KeyguardState]s that match the given predicates,
-     * but haven't yet completed it.
-     *
-     * If you only care about a single state for both from and to, instead use the optimized
-     * [isInTransition].
-     */
-    private fun isInTransitionWhere(
-        fromToStatePredicate: (KeyguardState, KeyguardState) -> Boolean
+        fromStatePredicate: (KeyguardState) -> Boolean = { true },
+        toStatePredicate: (KeyguardState) -> Boolean = { true },
     ): Flow<Boolean> {
         return repository.transitions
             .filter { it.transitionState != TransitionState.CANCELED }
             .mapLatest {
                 it.transitionState != TransitionState.FINISHED &&
-                    fromToStatePredicate(it.from, it.to)
+                    fromStatePredicate(it.from) &&
+                    toStatePredicate(it.to)
             }
             .distinctUntilChanged()
     }
@@ -530,17 +473,21 @@
         return finishedKeyguardState.map { stateMatcher(it) }.distinctUntilChanged()
     }
 
-    /** Whether we've FINISHED a transition to a state that matches the given predicate. */
-    fun isFinishedInState(state: KeyguardState): Flow<Boolean> {
-        return finishedKeyguardState.map { it == state }.distinctUntilChanged()
+    fun isFinishedIn(scene: SceneKey, stateWithoutSceneContainer: KeyguardState): Flow<Boolean> {
+        return if (SceneContainerFlag.isEnabled) {
+            sceneInteractor.transitionState
+                .map { it.isIdle(scene) || it.isTransitioning(from = scene) }
+                .distinctUntilChanged()
+        } else {
+            isFinishedIn(stateWithoutSceneContainer)
+        }
     }
 
-    /**
-     * Whether we've FINISHED a transition to a state that matches the given predicate. Consider
-     * using [isFinishedInStateWhere] whenever possible instead
-     */
-    fun isFinishedInStateWhereValue(stateMatcher: (KeyguardState) -> Boolean) =
-        stateMatcher(finishedKeyguardState.replayCache.last())
+    /** Whether we've FINISHED a transition to a state */
+    fun isFinishedIn(state: KeyguardState): Flow<Boolean> {
+        state.checkValidState()
+        return finishedKeyguardState.map { it == state }.distinctUntilChanged()
+    }
 
     fun getCurrentState(): KeyguardState {
         return currentKeyguardState.replayCache.last()
@@ -554,14 +501,6 @@
         return finishedKeyguardState.replayCache.last()
     }
 
-    suspend fun startTransition(info: TransitionInfo) = repository.startTransition(info)
-
-    fun updateTransition(
-        transitionId: UUID,
-        @FloatRange(from = 0.0, to = 1.0) value: Float,
-        state: TransitionState
-    ) = repository.updateTransition(transitionId, value, state)
-
     companion object {
         private val TAG = KeyguardTransitionInteractor::class.simpleName
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractor.kt
new file mode 100644
index 0000000..6a1b7cf
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractor.kt
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyguard.domain.interactor
+
+import android.annotation.SuppressLint
+import android.app.AlarmManager
+import android.app.PendingIntent
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.provider.Settings
+import android.provider.Settings.Secure
+import com.android.internal.widget.LockPatternUtils
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.keyguard.KeyguardViewMediator
+import com.android.systemui.keyguard.data.repository.KeyguardRepository
+import com.android.systemui.keyguard.shared.model.BiometricUnlockMode
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.KeyguardState.Companion.deviceIsAsleepInState
+import com.android.systemui.keyguard.shared.model.KeyguardState.Companion.deviceIsAwakeInState
+import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.power.shared.model.WakeSleepReason
+import com.android.systemui.user.domain.interactor.SelectedUserInteractor
+import com.android.systemui.util.kotlin.sample
+import com.android.systemui.util.settings.SecureSettings
+import com.android.systemui.util.settings.SystemSettings
+import com.android.systemui.util.time.SystemClock
+import javax.inject.Inject
+import kotlin.math.max
+import kotlin.math.min
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.distinctUntilChangedBy
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+
+/**
+ * Logic related to the ability to wake directly to GONE from asleep (AOD/DOZING), without going
+ * through LOCKSCREEN or a BOUNCER state.
+ *
+ * This is possible in the following scenarios:
+ * - The lockscreen is disabled, either from an app request (SUW does this), or by the security
+ *   "None" setting.
+ * - A biometric authentication event occurred while we were asleep (fingerprint auth, etc). This
+ *   specifically is referred to throughout the codebase as "wake and unlock".
+ * - The screen timed out, but the "lock after screen timeout" duration has not elapsed.
+ * - The power button was pressed, but "power button instantly locks" is disabled and the "lock
+ *   after screen timeout" duration has not elapsed.
+ *
+ * In these cases, no (further) authentication is required, and we can transition directly from
+ * AOD/DOZING -> GONE.
+ */
+@SysUISingleton
+class KeyguardWakeDirectlyToGoneInteractor
+@Inject
+constructor(
+    @Application private val scope: CoroutineScope,
+    private val context: Context,
+    private val repository: KeyguardRepository,
+    private val systemClock: SystemClock,
+    private val alarmManager: AlarmManager,
+    private val transitionInteractor: KeyguardTransitionInteractor,
+    private val powerInteractor: PowerInteractor,
+    private val secureSettings: SecureSettings,
+    private val lockPatternUtils: LockPatternUtils,
+    private val systemSettings: SystemSettings,
+    private val selectedUserInteractor: SelectedUserInteractor,
+) {
+
+    /**
+     * Whether the lockscreen was disabled as of the last wake/sleep event, according to
+     * LockPatternUtils.
+     *
+     * This will always be true if [repository.isKeyguardServiceEnabled]=false, but it can also be
+     * true when the keyguard service is enabled if the lockscreen has been disabled via adb using
+     * the `adb shell locksettings set-disabled true` command, which is often done in tests.
+     *
+     * Unlike keyguardServiceEnabled, changes to this value should *not* immediately show or hide
+     * the keyguard. If the lockscreen is disabled in this way, it will just not show on the next
+     * sleep/wake.
+     */
+    private val isLockscreenDisabled: Flow<Boolean> =
+        powerInteractor.isAwake.map { isLockscreenDisabled() }
+
+    /**
+     * Whether we can wake from AOD/DOZING directly to GONE, bypassing LOCKSCREEN/BOUNCER states.
+     *
+     * This is possible in the following cases:
+     * - Keyguard is disabled, either from an app request or from security being set to "None".
+     * - We're wake and unlocking (fingerprint auth occurred while asleep).
+     * - We're allowed to ignore auth and return to GONE, due to timeouts not elapsing.
+     */
+    val canWakeDirectlyToGone =
+        combine(
+                repository.isKeyguardEnabled,
+                isLockscreenDisabled,
+                repository.biometricUnlockState,
+                repository.canIgnoreAuthAndReturnToGone,
+            ) {
+                keyguardEnabled,
+                isLockscreenDisabled,
+                biometricUnlockState,
+                canIgnoreAuthAndReturnToGone ->
+                (!keyguardEnabled || isLockscreenDisabled) ||
+                    BiometricUnlockMode.isWakeAndUnlock(biometricUnlockState.mode) ||
+                    canIgnoreAuthAndReturnToGone
+            }
+            .distinctUntilChanged()
+
+    /**
+     * Counter that is incremented every time we wake up or stop dreaming. Upon sleeping/dreaming,
+     * we put the current value of this counter into the intent extras of the timeout alarm intent.
+     * If this value has changed by the time we receive the intent, it is discarded since it's out
+     * of date.
+     */
+    var timeoutCounter = 0
+
+    var isAwake = false
+
+    private val broadcastReceiver: BroadcastReceiver =
+        object : BroadcastReceiver() {
+            override fun onReceive(context: Context, intent: Intent) {
+                if (DELAYED_KEYGUARD_ACTION == intent.action) {
+                    val sequence = intent.getIntExtra(SEQ_EXTRA_KEY, 0)
+                    synchronized(this) {
+                        if (timeoutCounter == sequence) {
+                            // If the sequence # matches, we have not woken up or stopped dreaming
+                            // since
+                            // the alarm was set. That means this is still relevant - the lock
+                            // timeout
+                            // has elapsed, so let the repository know that we can no longer return
+                            // to
+                            // GONE without authenticating.
+                            repository.setCanIgnoreAuthAndReturnToGone(false)
+                        }
+                    }
+                }
+            }
+        }
+
+    init {
+        setOrCancelAlarmFromWakefulness()
+        listenForWakeToClearCanIgnoreAuth()
+        registerBroadcastReceiver()
+    }
+
+    fun onDreamingStarted() {
+        // If we start dreaming while awake, lock after the normal timeout.
+        if (isAwake) {
+            setResetCanIgnoreAuthAlarm()
+        }
+    }
+
+    fun onDreamingStopped() {
+        // Cancel the timeout if we stop dreaming while awake.
+        if (isAwake) {
+            cancelCanIgnoreAuthAlarm()
+        }
+    }
+
+    private fun setOrCancelAlarmFromWakefulness() {
+        scope.launch {
+            powerInteractor.detailedWakefulness
+                .distinctUntilChangedBy { it.isAwake() }
+                .sample(transitionInteractor.currentKeyguardState, ::Pair)
+                .collect { (wakefulness, currentState) ->
+                    // Save isAwake for use in onDreamingStarted/onDreamingStopped.
+                    this@KeyguardWakeDirectlyToGoneInteractor.isAwake = wakefulness.isAwake()
+
+                    // If we're sleeping from GONE, check the timeout and lock instantly settings.
+                    // These are not relevant if we're coming from non-GONE states.
+                    if (!isAwake && currentState == KeyguardState.GONE) {
+                        val lockTimeoutDuration = getCanIgnoreAuthAndReturnToGoneDuration()
+
+                        // If the screen timed out and went to sleep, and the lock timeout is > 0ms,
+                        // then we can return to GONE until that duration elapses. If the power
+                        // button was pressed but "instantly locks" is disabled, then we can also
+                        // return to GONE until the timeout duration elapses.
+                        if (
+                            (wakefulness.lastSleepReason == WakeSleepReason.TIMEOUT &&
+                                lockTimeoutDuration > 0) ||
+                                (wakefulness.lastSleepReason == WakeSleepReason.POWER_BUTTON &&
+                                    !willLockImmediately())
+                        ) {
+
+                            // Let the repository know that we can return to GONE until we notify
+                            // it otherwise.
+                            repository.setCanIgnoreAuthAndReturnToGone(true)
+                            setResetCanIgnoreAuthAlarm()
+                        }
+                    } else if (isAwake) {
+                        // If we're waking up, ignore the alarm if it goes off since it's no longer
+                        // relevant. Once a wake KeyguardTransition is started, we'll also clear the
+                        // canIgnoreAuthAndReturnToGone value in listenForWakeToClearCanIgnoreAuth.
+                        cancelCanIgnoreAuthAlarm()
+                    }
+                }
+        }
+    }
+
+    /** Clears the canIgnoreAuthAndReturnToGone value upon waking. */
+    private fun listenForWakeToClearCanIgnoreAuth() {
+        scope.launch {
+            transitionInteractor
+                .isInTransitionWhere(
+                    fromStatePredicate = { deviceIsAsleepInState(it) },
+                    toStatePredicate = { deviceIsAwakeInState(it) },
+                )
+                .collect {
+                    // This value is reset when the timeout alarm fires, but if the device is woken
+                    // back up before then, it needs to be reset here. The alarm is cancelled
+                    // immediately upon waking up, but since this value is used by keyguard
+                    // transition internals to decide whether we can transition to GONE, wait until
+                    // that decision is made before resetting it.
+                    repository.setCanIgnoreAuthAndReturnToGone(false)
+                }
+        }
+    }
+
+    /**
+     * Registers the broadcast receiver to receive the alarm intent.
+     *
+     * TODO(b/351817381): Investigate using BroadcastDispatcher vs. ignoring this lint warning.
+     */
+    @SuppressLint("WrongConstant", "RegisterReceiverViaContext")
+    private fun registerBroadcastReceiver() {
+        val delayedActionFilter = IntentFilter()
+        delayedActionFilter.addAction(KeyguardViewMediator.DELAYED_KEYGUARD_ACTION)
+        // TODO(b/346803756): Listen for DELAYED_LOCK_PROFILE_ACTION.
+        delayedActionFilter.priority = IntentFilter.SYSTEM_HIGH_PRIORITY
+        context.registerReceiver(
+            broadcastReceiver,
+            delayedActionFilter,
+            SYSTEMUI_PERMISSION,
+            null /* scheduler */,
+            Context.RECEIVER_EXPORTED_UNAUDITED
+        )
+    }
+
+    /** Set an alarm for */
+    private fun setResetCanIgnoreAuthAlarm() {
+        val intent =
+            Intent(DELAYED_KEYGUARD_ACTION).apply {
+                setPackage(context.packageName)
+                putExtra(SEQ_EXTRA_KEY, timeoutCounter)
+                addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
+            }
+
+        val sender =
+            PendingIntent.getBroadcast(
+                context,
+                0,
+                intent,
+                PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE
+            )
+
+        val time = systemClock.elapsedRealtime() + getCanIgnoreAuthAndReturnToGoneDuration()
+        alarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, time, sender)
+
+        // TODO(b/346803756): Migrate support for child profiles.
+    }
+
+    /**
+     * Cancel the timeout by incrementing the counter so that we ignore the intent when it's
+     * received.
+     */
+    private fun cancelCanIgnoreAuthAlarm() {
+        timeoutCounter++
+    }
+
+    /**
+     * Whether pressing the power button locks the device immediately; vs. waiting for a specified
+     * timeout first.
+     */
+    private fun willLockImmediately(
+        userId: Int = selectedUserInteractor.getSelectedUserId()
+    ): Boolean {
+        return lockPatternUtils.getPowerButtonInstantlyLocks(userId) ||
+            !lockPatternUtils.isSecure(userId)
+    }
+
+    /**
+     * Returns whether the lockscreen is disabled, either because the keyguard service is disabled
+     * or because an adb command has disabled the lockscreen.
+     */
+    private fun isLockscreenDisabled(
+        userId: Int = selectedUserInteractor.getSelectedUserId()
+    ): Boolean {
+        return lockPatternUtils.isLockScreenDisabled(userId)
+    }
+
+    /**
+     * Returns the duration within which we can return to GONE without auth after a screen timeout
+     * (or power button press, if lock instantly is disabled).
+     *
+     * This takes into account the user's settings as well as device policy maximums.
+     */
+    private fun getCanIgnoreAuthAndReturnToGoneDuration(
+        userId: Int = selectedUserInteractor.getSelectedUserId()
+    ): Long {
+        // The timeout duration from settings (Security > Device Unlock > Gear icon > "Lock after
+        // screen timeout".
+        val durationSetting: Long =
+            secureSettings
+                .getIntForUser(
+                    Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
+                    KEYGUARD_CAN_IGNORE_AUTH_DURATION,
+                    userId
+                )
+                .toLong()
+
+        // Device policy maximum timeout.
+        val durationDevicePolicyMax =
+            lockPatternUtils.devicePolicyManager.getMaximumTimeToLock(null, userId)
+
+        return if (durationDevicePolicyMax <= 0) {
+            durationSetting
+        } else {
+            var displayTimeout =
+                systemSettings
+                    .getIntForUser(
+                        Settings.System.SCREEN_OFF_TIMEOUT,
+                        KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT,
+                        userId
+                    )
+                    .toLong()
+
+            // Ignore negative values. I don't know why this would be negative, but this check has
+            // been around since 2016 and I see no upside to removing it.
+            displayTimeout = max(displayTimeout, 0)
+
+            // Respect the shorter of: the device policy (maximum duration between last user action
+            // and fully locking) or the "Lock after screen timeout" setting.
+            max(min(durationDevicePolicyMax - displayTimeout, durationSetting), 0)
+        }
+    }
+
+    companion object {
+        private const val DELAYED_KEYGUARD_ACTION =
+            "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD"
+        private const val DELAYED_LOCK_PROFILE_ACTION =
+            "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_LOCK"
+        private const val SYSTEMUI_PERMISSION = "com.android.systemui.permission.SELF"
+        private const val SEQ_EXTRA_KEY = "count"
+
+        private const val KEYGUARD_CAN_IGNORE_AUTH_DURATION = 5000
+        private const val KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/ToAodFoldTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/ToAodFoldTransitionInteractor.kt
index 6729246..21b9e53 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/ToAodFoldTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/ToAodFoldTransitionInteractor.kt
@@ -16,30 +16,17 @@
 
 package com.android.systemui.keyguard.domain.interactor
 
-import android.animation.ValueAnimator
 import android.view.ViewGroup
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
-import com.android.systemui.keyguard.shared.model.TransitionInfo
-import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
 import com.android.systemui.shade.NotificationPanelViewController
 import com.android.systemui.shade.ShadeFoldAnimator
 import javax.inject.Inject
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
 
 @SysUISingleton
 class ToAodFoldTransitionInteractor
 @Inject
 constructor(
     private val keyguardClockInteractor: KeyguardClockInteractor,
-    private val transitionInteractor: KeyguardTransitionInteractor,
-    private val transitionRepository: KeyguardTransitionRepository,
-    @Application private val mainScope: CoroutineScope,
-    @Main private val mainDispatcher: CoroutineDispatcher,
 ) {
     private var parentAnimator: NotificationPanelViewController.ShadeFoldAnimatorImpl? = null
 
@@ -50,7 +37,6 @@
                 get() = throw NotImplementedError("Deprecated. Do not call.")
 
             override fun prepareFoldToAodAnimation() {
-                forceToAod()
                 parentAnimator?.prepareFoldToAodAnimation()
             }
 
@@ -78,21 +64,6 @@
             parentAnimator as? NotificationPanelViewController.ShadeFoldAnimatorImpl?
     }
 
-    /** Forces the keyguard into AOD or Doze */
-    private fun forceToAod() {
-        mainScope.launch(mainDispatcher) {
-            transitionRepository.startTransition(
-                TransitionInfo(
-                    "$TAG (Fold transition triggered)",
-                    transitionInteractor.getCurrentState(),
-                    transitionInteractor.asleepKeyguardState.value,
-                    ValueAnimator().apply { duration = 0 },
-                    TransitionModeOnCanceled.LAST_VALUE,
-                )
-            )
-        }
-    }
-
     companion object {
         private val TAG = ToAodFoldTransitionInteractor::class.simpleName!!
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt
index e148207..bbc3d76 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt
@@ -25,6 +25,7 @@
 import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.util.kotlin.sample
 import java.util.UUID
 import kotlinx.coroutines.CoroutineDispatcher
@@ -57,6 +58,8 @@
 ) {
     val name = this::class.simpleName ?: "UnknownTransitionInteractor"
     abstract val transitionRepository: KeyguardTransitionRepository
+    abstract val internalTransitionInteractor: InternalKeyguardTransitionInteractor
+
     abstract fun start()
 
     /* Use background dispatcher for all [KeyguardTransitionInteractor] flows. Necessary because
@@ -79,14 +82,15 @@
         // a bugreport.
         ownerReason: String = "",
     ): UUID? {
-        if (fromState != transitionInteractor.currentTransitionInfoInternal.value.to) {
+        toState.checkValidState()
+        if (fromState != internalTransitionInteractor.currentTransitionInfoInternal.value.to) {
             Log.e(
                 name,
                 "Ignoring startTransition: This interactor asked to transition from " +
                     "$fromState -> $toState, but we last transitioned to " +
-                    "${transitionInteractor.currentTransitionInfoInternal.value.to}, not " +
-                    "$fromState. This should never happen - check currentTransitionInfoInternal " +
-                    "or use filterRelevantKeyguardState before starting transitions."
+                    "${internalTransitionInteractor.currentTransitionInfoInternal.value.to}, not" +
+                    " $fromState. This should never happen - check currentTransitionInfoInternal" +
+                    " or use filterRelevantKeyguardState before starting transitions."
             )
 
             if (fromState == transitionInteractor.finishedKeyguardState.replayCache.last()) {
@@ -164,6 +168,8 @@
      */
     @Deprecated("Will be merged into maybeStartTransitionToOccludedOrInsecureCamera")
     suspend fun maybeHandleInsecurePowerGesture(): Boolean {
+        // TODO(b/336576536): Check if adaptation for scene framework is needed
+        if (SceneContainerFlag.isEnabled) return true
         if (keyguardOcclusionInteractor.shouldTransitionFromPowerButtonGesture()) {
             if (keyguardInteractor.isKeyguardDismissible.value) {
                 startTransitionTo(
@@ -238,12 +244,11 @@
      * Whether we're in the KeyguardState relevant to this From*TransitionInteractor (which we know
      * from [fromState]).
      *
-     * This uses [KeyguardTransitionInteractor.currentTransitionInfoInternal], which is more up to
-     * date than [startedKeyguardState] as it does not wait for the emission of the first STARTED
-     * step.
+     * This uses [currentTransitionInfoInternal], which is more up to date than
+     * [startedKeyguardState] as it does not wait for the emission of the first STARTED step.
      */
     fun inOrTransitioningToRelevantKeyguardState(): Boolean {
-        return transitionInteractor.currentTransitionInfoInternal.value.to == fromState
+        return internalTransitionInteractor.currentTransitionInfoInternal.value.to == fromState
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TrustInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TrustInteractor.kt
index 2ff6e16..73248bb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TrustInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TrustInteractor.kt
@@ -17,14 +17,21 @@
 package com.android.systemui.keyguard.domain.interactor
 
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.keyguard.data.repository.TrustRepository
 import javax.inject.Inject
-import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.launch
 
 /** Encapsulates any state relevant to trust agents and trust grants. */
 @SysUISingleton
-class TrustInteractor @Inject constructor(repository: TrustRepository) {
+class TrustInteractor
+@Inject
+constructor(
+    @Application private val applicationScope: CoroutineScope,
+    private val repository: TrustRepository,
+) {
     /**
      * Whether the current user has a trust agent enabled. This is true if the user has at least one
      * trust agent enabled in settings.
@@ -39,5 +46,10 @@
     val isTrustAgentCurrentlyAllowed: StateFlow<Boolean> = repository.isCurrentUserTrustManaged
 
     /** Whether the current user is trusted by any of the enabled trust agents. */
-    val isTrusted: Flow<Boolean> = repository.isCurrentUserTrusted
+    val isTrusted: StateFlow<Boolean> = repository.isCurrentUserTrusted
+
+    /** Reports a keyguard visibility change. */
+    fun reportKeyguardShowingChanged() {
+        applicationScope.launch { repository.reportKeyguardShowingChanged() }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
index 069f65b..0985e69 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractor.kt
@@ -21,14 +21,17 @@
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
+import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.BiometricUnlockMode
 import com.android.systemui.keyguard.shared.model.Edge
 import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.KeyguardState.Companion.deviceIsAsleepInState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.statusbar.notification.domain.interactor.NotificationLaunchAnimationInteractor
+import com.android.systemui.util.kotlin.Utils.Companion.toTriple
 import com.android.systemui.util.kotlin.sample
 import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
 import dagger.Lazy
@@ -41,11 +44,13 @@
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SysUISingleton
 class WindowManagerLockscreenVisibilityInteractor
 @Inject
 constructor(
     keyguardInteractor: KeyguardInteractor,
+    transitionRepository: KeyguardTransitionRepository,
     transitionInteractor: KeyguardTransitionInteractor,
     surfaceBehindInteractor: KeyguardSurfaceBehindInteractor,
     fromLockscreenInteractor: FromLockscreenTransitionInteractor,
@@ -54,9 +59,15 @@
     notificationLaunchAnimationInteractor: NotificationLaunchAnimationInteractor,
     sceneInteractor: Lazy<SceneInteractor>,
     deviceEntryInteractor: Lazy<DeviceEntryInteractor>,
+    wakeToGoneInteractor: KeyguardWakeDirectlyToGoneInteractor,
 ) {
     private val defaultSurfaceBehindVisibility =
-        transitionInteractor.finishedKeyguardState.map(::isSurfaceVisible)
+        combine(
+            transitionInteractor.finishedKeyguardState,
+            wakeToGoneInteractor.canWakeDirectlyToGone,
+        ) { finishedState, canWakeDirectlyToGone ->
+            isSurfaceVisible(finishedState) || canWakeDirectlyToGone
+        }
 
     /**
      * Surface visibility provided by the From*TransitionInteractor responsible for the currently
@@ -129,7 +140,7 @@
                     }
                 }
             } else {
-                transitionInteractor.isInTransitionToAnyState.flatMapLatest { isInTransition ->
+                transitionInteractor.isInTransition.flatMapLatest { isInTransition ->
                     if (!isInTransition) {
                         defaultSurfaceBehindVisibility
                     } else {
@@ -203,26 +214,47 @@
         if (SceneContainerFlag.isEnabled) {
             isDeviceNotEntered
         } else {
-            transitionInteractor.currentKeyguardState
-                .sample(transitionInteractor.startedStepWithPrecedingStep, ::Pair)
-                .map { (currentState, startedWithPrev) ->
-                    val startedFromStep = startedWithPrev?.previousValue
-                    val startedStep = startedWithPrev?.newValue
+            combine(
+                    transitionInteractor.currentKeyguardState,
+                    wakeToGoneInteractor.canWakeDirectlyToGone,
+                    ::Pair
+                )
+                .sample(transitionInteractor.startedStepWithPrecedingStep, ::toTriple)
+                .map { (currentState, canWakeDirectlyToGone, startedWithPrev) ->
+                    val startedFromStep = startedWithPrev.previousValue
+                    val startedStep = startedWithPrev.newValue
                     val returningToGoneAfterCancellation =
-                        startedStep?.to == KeyguardState.GONE &&
-                            startedFromStep?.transitionState == TransitionState.CANCELED &&
+                        startedStep.to == KeyguardState.GONE &&
+                            startedFromStep.transitionState == TransitionState.CANCELED &&
                             startedFromStep.from == KeyguardState.GONE
 
-                    if (!returningToGoneAfterCancellation) {
-                        // By default, apply the lockscreen visibility of the current state.
-                        deviceEntryInteractor.get().isLockscreenEnabled() &&
-                            KeyguardState.lockscreenVisibleInState(currentState)
-                    } else {
-                        // If we're transitioning to GONE after a prior canceled transition from
-                        // GONE, then this is the camera launch transition from an asleep state back
-                        // to GONE. We don't want to show the lockscreen since we're aborting the
-                        // lock and going back to GONE.
+                    val transitionInfo = transitionRepository.currentTransitionInfoInternal.value
+                    val wakingDirectlyToGone =
+                        deviceIsAsleepInState(transitionInfo.from) &&
+                            transitionInfo.to == KeyguardState.GONE
+
+                    if (returningToGoneAfterCancellation || wakingDirectlyToGone) {
+                        // GONE -> AOD/DOZING (cancel) -> GONE is the camera launch transition,
+                        // which means we never want to show the lockscreen throughout the
+                        // transition. Same for waking directly to gone, due to the lockscreen being
+                        // disabled or because the device was woken back up before the lock timeout
+                        // duration elapsed.
                         KeyguardState.lockscreenVisibleInState(KeyguardState.GONE)
+                    } else if (canWakeDirectlyToGone) {
+                        // Never show the lockscreen if we can wake directly to GONE. This means
+                        // that the lock timeout has not yet elapsed, or the keyguard is disabled.
+                        // In either case, we don't show the activity lock screen until one of those
+                        // conditions changes.
+                        false
+                    } else if (
+                        currentState == KeyguardState.DREAMING &&
+                            deviceEntryInteractor.get().isUnlocked.value
+                    ) {
+                        // Dreams dismiss keyguard and return to GONE if they can.
+                        false
+                    } else {
+                        // Otherwise, use the visibility of the current state.
+                        KeyguardState.lockscreenVisibleInState(currentState)
                     }
                 }
                 .distinctUntilChanged()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
index 9b3ba7d..3248114 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.keyguard.data.repository.LockscreenSceneTransitionRepository
 import com.android.systemui.keyguard.data.repository.LockscreenSceneTransitionRepository.Companion.DEFAULT_STATE
+import com.android.systemui.keyguard.domain.interactor.InternalKeyguardTransitionInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.KeyguardState.UNDEFINED
@@ -67,7 +68,8 @@
 class LockscreenSceneTransitionInteractor
 @Inject
 constructor(
-    val transitionInteractor: KeyguardTransitionInteractor,
+    private val transitionInteractor: KeyguardTransitionInteractor,
+    private val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
     @Application private val applicationScope: CoroutineScope,
     private val sceneInteractor: SceneInteractor,
     private val repository: LockscreenSceneTransitionRepository,
@@ -123,7 +125,7 @@
     }
 
     private fun finishCurrentTransition() {
-        transitionInteractor.updateTransition(currentTransitionId!!, 1f, FINISHED)
+        internalTransitionInteractor.updateTransition(currentTransitionId!!, 1f, FINISHED)
         resetTransitionData()
     }
 
@@ -131,13 +133,13 @@
         val newTransition =
             TransitionInfo(
                 ownerName = this::class.java.simpleName,
-                from = transitionInteractor.currentTransitionInfoInternal.value.to,
+                from = internalTransitionInteractor.currentTransitionInfoInternal.value.to,
                 to = state,
                 animator = null,
                 modeOnCanceled = TransitionModeOnCanceled.REVERSE
             )
-        currentTransitionId = transitionInteractor.startTransition(newTransition)
-        transitionInteractor.updateTransition(currentTransitionId!!, 1f, FINISHED)
+        currentTransitionId = internalTransitionInteractor.startTransition(newTransition)
+        internalTransitionInteractor.updateTransition(currentTransitionId!!, 1f, FINISHED)
         resetTransitionData()
     }
 
@@ -150,7 +152,8 @@
     private suspend fun handleTransition(transition: ObservableTransitionState.Transition) {
         if (transition.fromScene == Scenes.Lockscreen) {
             if (currentTransitionId != null) {
-                val currentToState = transitionInteractor.currentTransitionInfoInternal.value.to
+                val currentToState =
+                    internalTransitionInteractor.currentTransitionInfoInternal.value.to
                 if (currentToState == UNDEFINED) {
                     transitionKtfTo(transitionInteractor.getStartedFromState())
                 }
@@ -201,7 +204,7 @@
     }
 
     private suspend fun startTransitionFromLockscreen() {
-        val currentState = transitionInteractor.currentTransitionInfoInternal.value.to
+        val currentState = internalTransitionInteractor.currentTransitionInfoInternal.value.to
         val newTransition =
             TransitionInfo(
                 ownerName = this::class.java.simpleName,
@@ -217,12 +220,12 @@
         if (currentTransitionId != null) {
             resetTransitionData()
         }
-        currentTransitionId = transitionInteractor.startTransition(transitionInfo)
+        currentTransitionId = internalTransitionInteractor.startTransition(transitionInfo)
     }
 
     private fun updateProgress(progress: Float) {
         if (currentTransitionId == null) return
-        transitionInteractor.updateTransition(
+        internalTransitionInteractor.updateTransition(
             currentTransitionId!!,
             progress.coerceIn(0f, 1f),
             RUNNING
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt
index 6a2bb5f..9504352 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/shared/model/KeyguardState.kt
@@ -15,7 +15,9 @@
  */
 package com.android.systemui.keyguard.shared.model
 
+import android.util.Log
 import com.android.compose.animation.scene.SceneKey
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.model.Scenes
 
 /** List of all possible states to transition to/from */
@@ -87,6 +89,22 @@
     /** An activity is displaying over the keyguard. */
     OCCLUDED;
 
+    fun checkValidState() {
+        val isStateValid: Boolean
+        val isEnabled: String
+        if (SceneContainerFlag.isEnabled) {
+            isStateValid = this === mapToSceneContainerState()
+            isEnabled = "enabled"
+        } else {
+            isStateValid = this !== UNDEFINED
+            isEnabled = "disabled"
+        }
+
+        if (!isStateValid) {
+            Log.e("KeyguardState", "$this is not a valid state when scene container is $isEnabled")
+        }
+    }
+
     fun mapToSceneContainerState(): KeyguardState {
         return when (this) {
             OFF,
@@ -125,20 +143,16 @@
 
         /** Whether the lockscreen is visible when we're FINISHED in the given state. */
         fun lockscreenVisibleInState(state: KeyguardState): Boolean {
+            // TODO(b/349784682): Transform deprecated states for Flexiglass
             return state != GONE
         }
 
-        /** Whether either of the bouncers are visible when we're FINISHED in the given state. */
-        @JvmStatic
-        fun isBouncerState(state: KeyguardState): Boolean {
-            return state == PRIMARY_BOUNCER || state == ALTERNATE_BOUNCER
-        }
-
         /**
          * Whether the device is awake ([PowerInteractor.isAwake]) when we're FINISHED in the given
          * keyguard state.
          */
         fun deviceIsAwakeInState(state: KeyguardState): Boolean {
+            state.checkValidState()
             return when (state) {
                 OFF -> false
                 DOZING -> false
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt
index 6550937..db33acb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt
@@ -86,7 +86,10 @@
                     privateFlags =
                         WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY or
                             WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION
+                    // Avoid announcing window title.
+                    accessibilityTitle = " "
                 }
+
     private var alternateBouncerView: ConstraintLayout? = null
 
     override fun start() {
@@ -112,13 +115,28 @@
     }
 
     private fun removeViewFromWindowManager() {
-        if (alternateBouncerView == null || !alternateBouncerView!!.isAttachedToWindow) {
-            return
-        }
+        alternateBouncerView?.let {
+            alternateBouncerView = null
+            if (it.isAttachedToWindow) {
+                it.removeOnAttachStateChangeListener(onAttachAddBackGestureHandler)
+                Log.d(TAG, "Removing alternate bouncer view immediately")
+                windowManager.get().removeView(it)
+            } else {
+                // once the view is attached, remove it
+                it.addOnAttachStateChangeListener(
+                    object : View.OnAttachStateChangeListener {
+                        override fun onViewAttachedToWindow(view: View) {
+                            it.removeOnAttachStateChangeListener(this)
+                            it.removeOnAttachStateChangeListener(onAttachAddBackGestureHandler)
+                            Log.d(TAG, "Removing alternate bouncer view on attached")
+                            windowManager.get().removeView(it)
+                        }
 
-        windowManager.get().removeView(alternateBouncerView)
-        alternateBouncerView!!.removeOnAttachStateChangeListener(onAttachAddBackGestureHandler)
-        alternateBouncerView = null
+                        override fun onViewDetachedFromWindow(view: View) {}
+                    }
+                )
+            }
+        }
     }
 
     private val onAttachAddBackGestureHandler =
@@ -148,7 +166,7 @@
         }
 
     private fun addViewToWindowManager() {
-        if (alternateBouncerView?.isAttachedToWindow == true) {
+        if (alternateBouncerView != null) {
             return
         }
 
@@ -156,6 +174,7 @@
             layoutInflater.get().inflate(R.layout.alternate_bouncer, null, false)
                 as ConstraintLayout
 
+        Log.d(TAG, "Adding alternate bouncer view")
         windowManager.get().addView(alternateBouncerView, layoutParams)
         alternateBouncerView!!.addOnAttachStateChangeListener(onAttachAddBackGestureHandler)
     }
@@ -304,6 +323,7 @@
             }
         }
     }
+
     companion object {
         private const val TAG = "AlternateBouncerViewBinder"
         private const val swipeTag = "AlternateBouncer-SWIPE"
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/DeviceEntryIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/DeviceEntryIconViewBinder.kt
index 1c7b4d9..76f7749 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/DeviceEntryIconViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/DeviceEntryIconViewBinder.kt
@@ -38,7 +38,9 @@
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.VibratorHelper
+import com.android.systemui.util.kotlin.DisposableHandles
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.DisposableHandle
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.launch
 
@@ -64,8 +66,9 @@
         falsingManager: FalsingManager,
         vibratorHelper: VibratorHelper,
         overrideColor: Color? = null,
-    ) {
+    ): DisposableHandle {
         DeviceEntryUdfpsRefactor.isUnexpectedlyInLegacyMode()
+        val disposables = DisposableHandles()
         val longPressHandlingView = view.longPressHandlingView
         val fgIconView = view.iconView
         val bgView = view.bgView
@@ -83,118 +86,125 @@
                 }
             }
 
-        view.repeatWhenAttached {
-            // Repeat on CREATED so that the view will always observe the entire
-            // GONE => AOD transition (even though the view may not be visible until the middle
-            // of the transition.
-            repeatOnLifecycle(Lifecycle.State.CREATED) {
-                launch("$TAG#viewModel.isVisible") {
-                    viewModel.isVisible.collect { isVisible ->
-                        longPressHandlingView.isInvisible = !isVisible
+        disposables +=
+            view.repeatWhenAttached {
+                // Repeat on CREATED so that the view will always observe the entire
+                // GONE => AOD transition (even though the view may not be visible until the middle
+                // of the transition.
+                repeatOnLifecycle(Lifecycle.State.CREATED) {
+                    launch("$TAG#viewModel.isVisible") {
+                        viewModel.isVisible.collect { isVisible ->
+                            longPressHandlingView.isInvisible = !isVisible
+                        }
                     }
-                }
-                launch("$TAG#viewModel.isLongPressEnabled") {
-                    viewModel.isLongPressEnabled.collect { isEnabled ->
-                        longPressHandlingView.setLongPressHandlingEnabled(isEnabled)
+                    launch("$TAG#viewModel.isLongPressEnabled") {
+                        viewModel.isLongPressEnabled.collect { isEnabled ->
+                            longPressHandlingView.setLongPressHandlingEnabled(isEnabled)
+                        }
                     }
-                }
-                launch("$TAG#viewModel.isUdfpsSupported") {
-                    viewModel.isUdfpsSupported.collect { udfpsSupported ->
-                        longPressHandlingView.longPressDuration =
-                            if (udfpsSupported) {
-                                {
-                                    view.resources
-                                        .getInteger(R.integer.config_udfpsDeviceEntryIconLongPress)
-                                        .toLong()
+                    launch("$TAG#viewModel.isUdfpsSupported") {
+                        viewModel.isUdfpsSupported.collect { udfpsSupported ->
+                            longPressHandlingView.longPressDuration =
+                                if (udfpsSupported) {
+                                    {
+                                        view.resources
+                                            .getInteger(
+                                                R.integer.config_udfpsDeviceEntryIconLongPress
+                                            )
+                                            .toLong()
+                                    }
+                                } else {
+                                    {
+                                        view.resources
+                                            .getInteger(R.integer.config_lockIconLongPress)
+                                            .toLong()
+                                    }
+                                }
+                        }
+                    }
+                    launch("$TAG#viewModel.accessibilityDelegateHint") {
+                        viewModel.accessibilityDelegateHint.collect { hint ->
+                            view.accessibilityHintType = hint
+                            if (hint != DeviceEntryIconView.AccessibilityHintType.NONE) {
+                                view.setOnClickListener {
+                                    vibratorHelper.performHapticFeedback(
+                                        view,
+                                        HapticFeedbackConstants.CONFIRM,
+                                    )
+                                    applicationScope.launch { viewModel.onUserInteraction() }
                                 }
                             } else {
-                                {
-                                    view.resources
-                                        .getInteger(R.integer.config_lockIconLongPress)
-                                        .toLong()
-                                }
+                                view.setOnClickListener(null)
                             }
+                        }
                     }
-                }
-                launch("$TAG#viewModel.accessibilityDelegateHint") {
-                    viewModel.accessibilityDelegateHint.collect { hint ->
-                        view.accessibilityHintType = hint
-                        if (hint != DeviceEntryIconView.AccessibilityHintType.NONE) {
-                            view.setOnClickListener {
-                                vibratorHelper.performHapticFeedback(
-                                    view,
-                                    HapticFeedbackConstants.CONFIRM,
-                                )
-                                applicationScope.launch { viewModel.onUserInteraction() }
+                    launch("$TAG#viewModel.useBackgroundProtection") {
+                        viewModel.useBackgroundProtection.collect { useBackgroundProtection ->
+                            if (useBackgroundProtection) {
+                                bgView.visibility = View.VISIBLE
+                            } else {
+                                bgView.visibility = View.GONE
                             }
-                        } else {
-                            view.setOnClickListener(null)
                         }
                     }
-                }
-                launch("$TAG#viewModel.useBackgroundProtection") {
-                    viewModel.useBackgroundProtection.collect { useBackgroundProtection ->
-                        if (useBackgroundProtection) {
-                            bgView.visibility = View.VISIBLE
-                        } else {
-                            bgView.visibility = View.GONE
+                    launch("$TAG#viewModel.burnInOffsets") {
+                        viewModel.burnInOffsets.collect { burnInOffsets ->
+                            view.translationX = burnInOffsets.x.toFloat()
+                            view.translationY = burnInOffsets.y.toFloat()
+                            view.aodFpDrawable.progress = burnInOffsets.progress
                         }
                     }
-                }
-                launch("$TAG#viewModel.burnInOffsets") {
-                    viewModel.burnInOffsets.collect { burnInOffsets ->
-                        view.translationX = burnInOffsets.x.toFloat()
-                        view.translationY = burnInOffsets.y.toFloat()
-                        view.aodFpDrawable.progress = burnInOffsets.progress
-                    }
-                }
 
-                launch("$TAG#viewModel.deviceEntryViewAlpha") {
-                    viewModel.deviceEntryViewAlpha.collect { alpha -> view.alpha = alpha }
-                }
-            }
-        }
-
-        fgIconView.repeatWhenAttached {
-            repeatOnLifecycle(Lifecycle.State.STARTED) {
-                // Start with an empty state
-                fgIconView.setImageState(StateSet.NOTHING, /* merge */ false)
-                launch("$TAG#fpIconView.viewModel") {
-                    fgViewModel.viewModel.collect { viewModel ->
-                        fgIconView.setImageState(
-                            view.getIconState(viewModel.type, viewModel.useAodVariant),
-                            /* merge */ false
-                        )
-                        if (viewModel.type.contentDescriptionResId != -1) {
-                            fgIconView.contentDescription =
-                                fgIconView.resources.getString(
-                                    viewModel.type.contentDescriptionResId
-                                )
-                        }
-                        fgIconView.imageTintList =
-                            ColorStateList.valueOf(overrideColor?.toArgb() ?: viewModel.tint)
-                        fgIconView.setPadding(
-                            viewModel.padding,
-                            viewModel.padding,
-                            viewModel.padding,
-                            viewModel.padding,
-                        )
+                    launch("$TAG#viewModel.deviceEntryViewAlpha") {
+                        viewModel.deviceEntryViewAlpha.collect { alpha -> view.alpha = alpha }
                     }
                 }
             }
-        }
 
-        bgView.repeatWhenAttached {
-            repeatOnLifecycle(Lifecycle.State.CREATED) {
-                launch("$TAG#bgViewModel.alpha") {
-                    bgViewModel.alpha.collect { alpha -> bgView.alpha = alpha }
-                }
-                launch("$TAG#bgViewModel.color") {
-                    bgViewModel.color.collect { color ->
-                        bgView.imageTintList = ColorStateList.valueOf(color)
+        disposables +=
+            fgIconView.repeatWhenAttached {
+                repeatOnLifecycle(Lifecycle.State.STARTED) {
+                    // Start with an empty state
+                    fgIconView.setImageState(StateSet.NOTHING, /* merge */ false)
+                    launch("$TAG#fpIconView.viewModel") {
+                        fgViewModel.viewModel.collect { viewModel ->
+                            fgIconView.setImageState(
+                                view.getIconState(viewModel.type, viewModel.useAodVariant),
+                                /* merge */ false
+                            )
+                            if (viewModel.type.contentDescriptionResId != -1) {
+                                fgIconView.contentDescription =
+                                    fgIconView.resources.getString(
+                                        viewModel.type.contentDescriptionResId
+                                    )
+                            }
+                            fgIconView.imageTintList =
+                                ColorStateList.valueOf(overrideColor?.toArgb() ?: viewModel.tint)
+                            fgIconView.setPadding(
+                                viewModel.padding,
+                                viewModel.padding,
+                                viewModel.padding,
+                                viewModel.padding,
+                            )
+                        }
                     }
                 }
             }
-        }
+
+        disposables +=
+            bgView.repeatWhenAttached {
+                repeatOnLifecycle(Lifecycle.State.CREATED) {
+                    launch("$TAG#bgViewModel.alpha") {
+                        bgViewModel.alpha.collect { alpha -> bgView.alpha = alpha }
+                    }
+                    launch("$TAG#bgViewModel.color") {
+                        bgViewModel.color.collect { color ->
+                            bgView.imageTintList = ColorStateList.valueOf(color)
+                        }
+                    }
+                }
+            }
+
+        return disposables
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt
index f2821a0..ba9f018 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt
@@ -37,6 +37,12 @@
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.plugins.clocks.AodClockBurnInModel
 import com.android.systemui.plugins.clocks.ClockController
+import com.android.systemui.util.kotlin.DisposableHandles
+import com.android.systemui.util.ui.value
+import kotlinx.coroutines.DisposableHandle
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.launch
 
 object KeyguardClockViewBinder {
@@ -52,80 +58,94 @@
         keyguardClockInteractor: KeyguardClockInteractor,
         blueprintInteractor: KeyguardBlueprintInteractor,
         rootViewModel: KeyguardRootViewModel,
-    ) {
-        keyguardRootView.repeatWhenAttached {
-            repeatOnLifecycle(Lifecycle.State.CREATED) {
-                keyguardClockInteractor.clockEventController.registerListeners(keyguardRootView)
+    ): DisposableHandle {
+        val disposables = DisposableHandles()
+        disposables +=
+            keyguardRootView.repeatWhenAttached {
+                repeatOnLifecycle(Lifecycle.State.CREATED) {
+                    keyguardClockInteractor.clockEventController.registerListeners(keyguardRootView)
+                }
             }
-        }
 
-        keyguardRootView.repeatWhenAttached {
-            repeatOnLifecycle(Lifecycle.State.CREATED) {
-                launch {
-                    if (!MigrateClocksToBlueprint.isEnabled) return@launch
-                    viewModel.currentClock.collect { currentClock ->
-                        cleanupClockViews(currentClock, keyguardRootView, viewModel.burnInLayer)
-                        addClockViews(currentClock, keyguardRootView)
-                        updateBurnInLayer(keyguardRootView, viewModel, viewModel.clockSize.value)
-                        applyConstraints(clockSection, keyguardRootView, true)
-                    }
-                }
-
-                launch {
-                    if (!MigrateClocksToBlueprint.isEnabled) return@launch
-                    viewModel.clockSize.collect { clockSize ->
-                        updateBurnInLayer(keyguardRootView, viewModel, clockSize)
-                        blueprintInteractor.refreshBlueprint(Type.ClockSize)
-                    }
-                }
-
-                launch {
-                    if (!MigrateClocksToBlueprint.isEnabled) return@launch
-                    viewModel.clockShouldBeCentered.collect {
-                        viewModel.currentClock.value?.let {
-                            // TODO(b/301502635): remove "!it.config.useCustomClockScene" when
-                            // migrate clocks to blueprint is fully rolled out
-                            if (
-                                it.largeClock.config.hasCustomPositionUpdatedAnimation &&
-                                    !it.config.useCustomClockScene
-                            ) {
-                                blueprintInteractor.refreshBlueprint(Type.DefaultClockStepping)
-                            } else {
-                                blueprintInteractor.refreshBlueprint(Type.DefaultTransition)
-                            }
-                        }
-                    }
-                }
-
-                launch {
-                    if (!MigrateClocksToBlueprint.isEnabled) return@launch
-                    viewModel.isAodIconsVisible.collect {
-                        viewModel.currentClock.value?.let {
-                            if (
-                                viewModel.isLargeClockVisible.value && it.config.useCustomClockScene
-                            ) {
-                                blueprintInteractor.refreshBlueprint(Type.DefaultTransition)
-                            }
-                        }
-                    }
-                }
-
-                launch {
-                    if (!MigrateClocksToBlueprint.isEnabled) return@launch
-                    rootViewModel.burnInModel.collect { burnInModel ->
-                        viewModel.currentClock.value?.let {
-                            it.largeClock.layout.applyAodBurnIn(
-                                AodClockBurnInModel(
-                                    translationX = burnInModel.translationX.toFloat(),
-                                    translationY = burnInModel.translationY.toFloat(),
-                                    scale = burnInModel.scale
-                                )
+        disposables +=
+            keyguardRootView.repeatWhenAttached {
+                repeatOnLifecycle(Lifecycle.State.CREATED) {
+                    launch {
+                        if (!MigrateClocksToBlueprint.isEnabled) return@launch
+                        viewModel.currentClock.collect { currentClock ->
+                            cleanupClockViews(currentClock, keyguardRootView, viewModel.burnInLayer)
+                            addClockViews(currentClock, keyguardRootView)
+                            updateBurnInLayer(
+                                keyguardRootView,
+                                viewModel,
+                                viewModel.clockSize.value
                             )
+                            applyConstraints(clockSection, keyguardRootView, true)
+                        }
+                    }
+
+                    launch {
+                        if (!MigrateClocksToBlueprint.isEnabled) return@launch
+                        viewModel.clockSize.collect { clockSize ->
+                            updateBurnInLayer(keyguardRootView, viewModel, clockSize)
+                            blueprintInteractor.refreshBlueprint(Type.ClockSize)
+                        }
+                    }
+
+                    launch {
+                        if (!MigrateClocksToBlueprint.isEnabled) return@launch
+                        viewModel.clockShouldBeCentered.collect {
+                            viewModel.currentClock.value?.let {
+                                // TODO(b/301502635): remove "!it.config.useCustomClockScene" when
+                                // migrate clocks to blueprint is fully rolled out
+                                if (
+                                    it.largeClock.config.hasCustomPositionUpdatedAnimation &&
+                                        !it.config.useCustomClockScene
+                                ) {
+                                    blueprintInteractor.refreshBlueprint(Type.DefaultClockStepping)
+                                } else {
+                                    blueprintInteractor.refreshBlueprint(Type.DefaultTransition)
+                                }
+                            }
+                        }
+                    }
+
+                    launch {
+                        if (!MigrateClocksToBlueprint.isEnabled) return@launch
+                        combine(
+                                viewModel.hasAodIcons,
+                                rootViewModel.isNotifIconContainerVisible.map { it.value }
+                            ) { hasIcon, isVisible ->
+                                hasIcon && isVisible
+                            }
+                            .distinctUntilChanged()
+                            .collect { _ ->
+                                viewModel.currentClock.value?.let {
+                                    if (it.config.useCustomClockScene) {
+                                        blueprintInteractor.refreshBlueprint(Type.DefaultTransition)
+                                    }
+                                }
+                            }
+                    }
+
+                    launch {
+                        if (!MigrateClocksToBlueprint.isEnabled) return@launch
+                        rootViewModel.burnInModel.collect { burnInModel ->
+                            viewModel.currentClock.value?.let {
+                                it.largeClock.layout.applyAodBurnIn(
+                                    AodClockBurnInModel(
+                                        translationX = burnInModel.translationX.toFloat(),
+                                        translationY = burnInModel.translationY.toFloat(),
+                                        scale = burnInModel.scale
+                                    )
+                                )
+                            }
                         }
                     }
                 }
             }
-        }
+
+        return disposables
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt
index 23c2491..ba94f45 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt
@@ -29,6 +29,7 @@
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.KeyguardIndicationController
+import com.android.systemui.util.kotlin.DisposableHandles
 import kotlinx.coroutines.DisposableHandle
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -53,7 +54,15 @@
         viewModel: KeyguardIndicationAreaViewModel,
         indicationController: KeyguardIndicationController,
     ): DisposableHandle {
-        indicationController.setIndicationArea(view)
+        val disposables = DisposableHandles()
+
+        // As the indication controller is a singleton, reset the view back to the previous view
+        // once the current view is disposed.
+        val previous = indicationController.indicationArea
+        indicationController.indicationArea = view
+        disposables += DisposableHandle {
+            previous?.let { indicationController.indicationArea = it }
+        }
 
         val indicationText: TextView = view.requireViewById(R.id.keyguard_indication_text)
         val indicationTextBottom: TextView =
@@ -63,7 +72,7 @@
         view.clipToPadding = false
 
         val configurationBasedDimensions = MutableStateFlow(loadFromResources(view))
-        val disposableHandle =
+        disposables +=
             view.repeatWhenAttached {
                 repeatOnLifecycle(Lifecycle.State.STARTED) {
                     launch("$TAG#viewModel.alpha") {
@@ -124,9 +133,15 @@
                             configurationBasedDimensions.value = loadFromResources(view)
                         }
                     }
+
+                    launch("$TAG#viewModel.visible") {
+                        viewModel.visible.collect { visible ->
+                            indicationController.setVisible(visible)
+                        }
+                    }
                 }
             }
-        return disposableHandle
+        return disposables
     }
 
     private fun loadFromResources(view: View): ConfigurationBasedDimensions {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardLongPressViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardLongPressViewBinder.kt
index 09fe067..057b4f9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardLongPressViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardLongPressViewBinder.kt
@@ -22,7 +22,7 @@
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.app.tracing.coroutines.launch
 import com.android.systemui.common.ui.view.LongPressHandlingView
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardTouchHandlingViewModel
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.plugins.FalsingManager
 
@@ -39,7 +39,7 @@
     @JvmStatic
     fun bind(
         view: LongPressHandlingView,
-        viewModel: KeyguardLongPressViewModel,
+        viewModel: KeyguardTouchHandlingViewModel,
         onSingleTap: () -> Unit,
         falsingManager: FalsingManager,
     ) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
index fc92afe..f96f053 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
@@ -37,6 +37,7 @@
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.app.animation.Interpolators
+import com.android.app.tracing.coroutines.launch
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.jank.InteractionJankMonitor.CUJ_SCREEN_OFF_SHOW_AOD
 import com.android.systemui.Flags.newAodTransition
@@ -80,6 +81,7 @@
 import com.android.systemui.util.ui.stopAnimating
 import com.android.systemui.util.ui.value
 import kotlin.math.min
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.DisposableHandle
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.coroutineScope
@@ -110,6 +112,7 @@
         vibratorHelper: VibratorHelper?,
         falsingManager: FalsingManager?,
         keyguardViewMediator: KeyguardViewMediator?,
+        mainImmediateDispatcher: CoroutineDispatcher,
     ): DisposableHandle {
         val disposables = DisposableHandles()
         val childViews = mutableMapOf<Int, View>()
@@ -128,6 +131,30 @@
 
         val burnInParams = MutableStateFlow(BurnInParameters())
         val viewState = ViewStateAccessor(alpha = { view.alpha })
+
+        disposables +=
+            view.repeatWhenAttached(mainImmediateDispatcher) {
+                repeatOnLifecycle(Lifecycle.State.CREATED) {
+                    if (MigrateClocksToBlueprint.isEnabled) {
+                        launch("$TAG#topClippingBounds") {
+                            val clipBounds = Rect()
+                            viewModel.topClippingBounds.collect { clipTop ->
+                                if (clipTop == null) {
+                                    view.setClipBounds(null)
+                                } else {
+                                    clipBounds.apply {
+                                        top = clipTop
+                                        left = view.getLeft()
+                                        right = view.getRight()
+                                        bottom = view.getBottom()
+                                    }
+                                    view.setClipBounds(clipBounds)
+                                }
+                            }
+                        }
+                    }
+                }
+            }
         disposables +=
             view.repeatWhenAttached {
                 repeatOnLifecycle(Lifecycle.State.CREATED) {
@@ -192,23 +219,6 @@
                         }
 
                         launch {
-                            val clipBounds = Rect()
-                            viewModel.topClippingBounds.collect { clipTop ->
-                                if (clipTop == null) {
-                                    view.setClipBounds(null)
-                                } else {
-                                    clipBounds.apply {
-                                        top = clipTop
-                                        left = view.getLeft()
-                                        right = view.getRight()
-                                        bottom = view.getBottom()
-                                    }
-                                    view.setClipBounds(clipBounds)
-                                }
-                            }
-                        }
-
-                        launch {
                             viewModel.lockscreenStateAlpha(viewState).collect { alpha ->
                                 childViews[statusViewId]?.alpha = alpha
                             }
@@ -267,6 +277,23 @@
                             }
                         }
 
+                        launch {
+                            blueprintViewModel.currentTransition.collect { currentTransition ->
+                                // When blueprint/clock transitions end (null), make sure NSSL is in
+                                // the right place
+                                if (currentTransition == null) {
+                                    childViews[nsslPlaceholderId]?.let { notificationListPlaceholder
+                                        ->
+                                        viewModel.onNotificationContainerBoundsChanged(
+                                            notificationListPlaceholder.top.toFloat(),
+                                            notificationListPlaceholder.bottom.toFloat(),
+                                            animate = true,
+                                        )
+                                    }
+                                }
+                            }
+                        }
+
                         if (NotificationIconContainerRefactor.isEnabled) {
                             launch {
                                 val iconsAppearTranslationPx =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt
index fa57565..4150ceb 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt
@@ -26,9 +26,9 @@
 import com.android.systemui.animation.ActivityTransitionAnimator
 import com.android.systemui.common.ui.binder.IconViewBinder
 import com.android.systemui.common.ui.binder.TextViewBinder
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardSettingsMenuViewModel
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardTouchHandlingViewModel
 import com.android.systemui.keyguard.util.WallpaperPickerIntentUtils
 import com.android.systemui.keyguard.util.WallpaperPickerIntentUtils.LAUNCH_SOURCE_KEYGUARD
 import com.android.systemui.lifecycle.repeatWhenAttached
@@ -44,7 +44,7 @@
     fun bind(
         view: View,
         viewModel: KeyguardSettingsMenuViewModel,
-        longPressViewModel: KeyguardLongPressViewModel,
+        touchHandlingViewModel: KeyguardTouchHandlingViewModel,
         rootViewModel: KeyguardRootViewModel?,
         vibratorHelper: VibratorHelper,
         activityStarter: ActivityStarter
@@ -97,7 +97,7 @@
                                 val hitRect = Rect()
                                 view.getHitRect(hitRect)
                                 if (!hitRect.contains(point.x, point.y)) {
-                                    longPressViewModel.onTouchedOutside()
+                                    touchHandlingViewModel.onTouchedOutside()
                                 }
                             }
                         }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt
index 191056c..8b74f5d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt
@@ -31,6 +31,7 @@
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.res.R
 import com.android.systemui.shared.R as sharedR
+import kotlinx.coroutines.DisposableHandle
 
 object KeyguardSmartspaceViewBinder {
     @JvmStatic
@@ -39,8 +40,8 @@
         clockViewModel: KeyguardClockViewModel,
         smartspaceViewModel: KeyguardSmartspaceViewModel,
         blueprintInteractor: KeyguardBlueprintInteractor,
-    ) {
-        keyguardRootView.repeatWhenAttached {
+    ): DisposableHandle {
+        return keyguardRootView.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.CREATED) {
                 launch("$TAG#clockViewModel.hasCustomWeatherDataDisplay") {
                     if (!MigrateClocksToBlueprint.isEnabled) return@launch
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index 777c873..bc5b7b9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -197,8 +197,7 @@
                 initiallySelectedSlotId =
                     bundle.getString(
                         KeyguardPreviewConstants.KEY_INITIALLY_SELECTED_SLOT_ID,
-                    )
-                        ?: KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
+                    ) ?: KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
                 shouldHighlightSelectedAffordance = shouldHighlightSelectedAffordance,
             )
         } else {
@@ -230,8 +229,7 @@
             val previewContext =
                 display?.let {
                     ContextThemeWrapper(context.createDisplayContext(it), context.getTheme())
-                }
-                    ?: context
+                } ?: context
 
             val rootView = FrameLayout(previewContext)
 
@@ -318,8 +316,8 @@
      */
     private fun setUpSmartspace(previewContext: Context, parentView: ViewGroup) {
         if (
-            !lockscreenSmartspaceController.isEnabled() ||
-                !lockscreenSmartspaceController.isDateWeatherDecoupled()
+            !lockscreenSmartspaceController.isEnabled ||
+                !lockscreenSmartspaceController.isDateWeatherDecoupled
         ) {
             return
         }
@@ -396,6 +394,7 @@
                     null, // device entry haptics not required for preview mode
                     null, // falsing manager not required for preview mode
                     null, // keyguard view mediator is not required for preview mode
+                    mainDispatcher,
                 )
         }
         rootView.addView(
@@ -654,6 +653,7 @@
             clockController.clock = clock
         }
     }
+
     private fun onClockChanged() {
         if (MigrateClocksToBlueprint.isEnabled) {
             return
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/DeviceEntryIconTransitionModule.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/DeviceEntryIconTransitionModule.kt
index ecdc21c..dc7a649 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/DeviceEntryIconTransitionModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/transitions/DeviceEntryIconTransitionModule.kt
@@ -24,6 +24,7 @@
 import com.android.systemui.keyguard.ui.viewmodel.AodToLockscreenTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.AodToOccludedTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.AodToPrimaryBouncerTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.DozingToGlanceableHubTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.DozingToGoneTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.DozingToLockscreenTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.DozingToOccludedTransitionViewModel
@@ -49,6 +50,7 @@
 import com.android.systemui.keyguard.ui.viewmodel.OffToLockscreenTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToAodTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToDozingTransitionViewModel
+import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGlanceableHubTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToLockscreenTransitionViewModel
 import dagger.Binds
 import dagger.Module
@@ -253,4 +255,16 @@
     abstract fun goneToGlanceableHub(
         impl: GoneToGlanceableHubTransitionViewModel
     ): DeviceEntryIconTransition
+
+    @Binds
+    @IntoSet
+    abstract fun primaryBouncerToGlanceableHub(
+        impl: PrimaryBouncerToGlanceableHubTransitionViewModel
+    ): DeviceEntryIconTransition
+
+    @Binds
+    @IntoSet
+    abstract fun dozingToGlanceableHub(
+        impl: DozingToGlanceableHubTransitionViewModel
+    ): DeviceEntryIconTransition
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/DeviceEntryIconView.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/DeviceEntryIconView.kt
index 215ac46..1c63235 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/DeviceEntryIconView.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/DeviceEntryIconView.kt
@@ -73,14 +73,14 @@
                         AccessibilityNodeInfoCompat.ACTION_CLICK,
                         resources.getString(R.string.accessibility_enter_hint)
                     )
+
                 override fun onInitializeAccessibilityNodeInfo(
                     v: View,
                     info: AccessibilityNodeInfo
                 ) {
                     super.onInitializeAccessibilityNodeInfo(v, info)
                     when (accessibilityHintType) {
-                        AccessibilityHintType.BOUNCER ->
-                            info.addAction(accessibilityBouncerHint)
+                        AccessibilityHintType.BOUNCER -> info.addAction(accessibilityBouncerHint)
                         AccessibilityHintType.ENTER -> info.addAction(accessibilityEnterHint)
                         AccessibilityHintType.NONE -> return
                     }
@@ -204,12 +204,12 @@
             /* reversible */ false,
         )
 
-        // LockscreenFingerprint <=> LockscreenLocked
+        // LockscreenFingerprint => LockscreenLocked
         animatedIconDrawable.addTransition(
             R.id.locked_fp,
             R.id.locked,
             context.getDrawable(R.drawable.fp_to_locked) as AnimatedVectorDrawable,
-            /* reversible */ true,
+            /* reversible */ false,
         )
 
         // LockscreenUnlocked <=> AodLocked
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
index 34a1da5..91e48b5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
@@ -45,8 +45,10 @@
 import com.android.systemui.plugins.clocks.ClockFaceLayout
 import com.android.systemui.res.R
 import com.android.systemui.shared.R as sharedR
+import com.android.systemui.util.ui.value
 import dagger.Lazy
 import javax.inject.Inject
+import kotlinx.coroutines.DisposableHandle
 
 internal fun ConstraintSet.setVisibility(
     views: Iterable<View>,
@@ -69,20 +71,24 @@
     val blueprintInteractor: Lazy<KeyguardBlueprintInteractor>,
     private val rootViewModel: KeyguardRootViewModel,
 ) : KeyguardSection() {
+    private var disposableHandle: DisposableHandle? = null
+
     override fun addViews(constraintLayout: ConstraintLayout) {}
+
     override fun bindData(constraintLayout: ConstraintLayout) {
         if (!MigrateClocksToBlueprint.isEnabled) {
             return
         }
-
-        KeyguardClockViewBinder.bind(
-            this,
-            constraintLayout,
-            keyguardClockViewModel,
-            clockInteractor,
-            blueprintInteractor.get(),
-            rootViewModel,
-        )
+        disposableHandle?.dispose()
+        disposableHandle =
+            KeyguardClockViewBinder.bind(
+                this,
+                constraintLayout,
+                keyguardClockViewModel,
+                clockInteractor,
+                blueprintInteractor.get(),
+                rootViewModel,
+            )
     }
 
     override fun applyConstraints(constraintSet: ConstraintSet) {
@@ -95,7 +101,13 @@
         }
     }
 
-    override fun removeViews(constraintLayout: ConstraintLayout) {}
+    override fun removeViews(constraintLayout: ConstraintLayout) {
+        if (!MigrateClocksToBlueprint.isEnabled) {
+            return
+        }
+
+        disposableHandle?.dispose()
+    }
 
     private fun buildConstraints(
         clock: ClockController,
@@ -121,35 +133,39 @@
     private fun getTargetClockFace(clock: ClockController): ClockFaceLayout =
         if (keyguardClockViewModel.isLargeClockVisible.value) clock.largeClock.layout
         else clock.smallClock.layout
+
     private fun getNonTargetClockFace(clock: ClockController): ClockFaceLayout =
         if (keyguardClockViewModel.isLargeClockVisible.value) clock.smallClock.layout
         else clock.largeClock.layout
 
     fun constrainWeatherClockDateIconsBarrier(constraints: ConstraintSet) {
         constraints.apply {
-            if (keyguardClockViewModel.isAodIconsVisible.value) {
+            createBarrier(
+                R.id.weather_clock_bc_smartspace_bottom,
+                Barrier.BOTTOM,
+                getDimen(ENHANCED_SMARTSPACE_HEIGHT),
+                (custR.id.weather_clock_time)
+            )
+            if (
+                rootViewModel.isNotifIconContainerVisible.value.value &&
+                    keyguardClockViewModel.hasAodIcons.value
+            ) {
                 createBarrier(
                     R.id.weather_clock_date_and_icons_barrier_bottom,
                     Barrier.BOTTOM,
                     0,
-                    *intArrayOf(sharedR.id.bc_smartspace_view, R.id.aod_notification_icon_container)
+                    *intArrayOf(
+                        R.id.aod_notification_icon_container,
+                        R.id.weather_clock_bc_smartspace_bottom
+                    )
                 )
             } else {
-                if (smartspaceViewModel.bcSmartspaceVisibility.value == VISIBLE) {
-                    createBarrier(
-                        R.id.weather_clock_date_and_icons_barrier_bottom,
-                        Barrier.BOTTOM,
-                        0,
-                        (sharedR.id.bc_smartspace_view)
-                    )
-                } else {
-                    createBarrier(
-                        R.id.weather_clock_date_and_icons_barrier_bottom,
-                        Barrier.BOTTOM,
-                        getDimen(ENHANCED_SMARTSPACE_HEIGHT),
-                        (R.id.lockscreen_clock_view)
-                    )
-                }
+                createBarrier(
+                    R.id.weather_clock_date_and_icons_barrier_bottom,
+                    Barrier.BOTTOM,
+                    0,
+                    *intArrayOf(R.id.weather_clock_bc_smartspace_bottom)
+                )
             }
         }
     }
@@ -198,6 +214,7 @@
     companion object {
         private const val DATE_WEATHER_VIEW_HEIGHT = "date_weather_view_height"
         private const val ENHANCED_SMARTSPACE_HEIGHT = "enhanced_smartspace_height"
+
         fun getDimen(context: Context, name: String): Int {
             val res = context.packageManager.getResourcesForApplication(context.packageName)
             val id = res.getIdentifier(name, "dimen", context.packageName)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt
index e01f0a1..51230dd 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt
@@ -49,6 +49,7 @@
 import dagger.Lazy
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.DisposableHandle
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 
 /** Includes the device entry icon. */
@@ -70,6 +71,7 @@
     private val vibratorHelper: Lazy<VibratorHelper>,
 ) : KeyguardSection() {
     private val deviceEntryIconViewId = R.id.device_entry_icon_view
+    private var disposableHandle: DisposableHandle? = null
 
     override fun addViews(constraintLayout: ConstraintLayout) {
         if (
@@ -97,15 +99,17 @@
     override fun bindData(constraintLayout: ConstraintLayout) {
         if (DeviceEntryUdfpsRefactor.isEnabled) {
             constraintLayout.findViewById<DeviceEntryIconView?>(deviceEntryIconViewId)?.let {
-                DeviceEntryIconViewBinder.bind(
-                    applicationScope,
-                    it,
-                    deviceEntryIconViewModel.get(),
-                    deviceEntryForegroundViewModel.get(),
-                    deviceEntryBackgroundViewModel.get(),
-                    falsingManager.get(),
-                    vibratorHelper.get(),
-                )
+                disposableHandle?.dispose()
+                disposableHandle =
+                    DeviceEntryIconViewBinder.bind(
+                        applicationScope,
+                        it,
+                        deviceEntryIconViewModel.get(),
+                        deviceEntryForegroundViewModel.get(),
+                        deviceEntryBackgroundViewModel.get(),
+                        falsingManager.get(),
+                        vibratorHelper.get(),
+                    )
             }
         } else {
             constraintLayout.findViewById<LockIconView?>(R.id.lock_icon_view)?.let {
@@ -178,6 +182,7 @@
     override fun removeViews(constraintLayout: ConstraintLayout) {
         if (DeviceEntryUdfpsRefactor.isEnabled) {
             constraintLayout.removeView(deviceEntryIconViewId)
+            disposableHandle?.dispose()
         } else {
             constraintLayout.removeView(R.id.lock_icon_view)
         }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultSettingsPopupMenuSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultSettingsPopupMenuSection.kt
index 32e76d0..5cd5172 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultSettingsPopupMenuSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultSettingsPopupMenuSection.kt
@@ -34,9 +34,9 @@
 import com.android.systemui.keyguard.KeyguardBottomAreaRefactor
 import com.android.systemui.keyguard.shared.model.KeyguardSection
 import com.android.systemui.keyguard.ui.binder.KeyguardSettingsViewBinder
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardSettingsMenuViewModel
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardTouchHandlingViewModel
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.VibratorHelper
@@ -48,7 +48,7 @@
 constructor(
     @Main private val resources: Resources,
     private val keyguardSettingsMenuViewModel: KeyguardSettingsMenuViewModel,
-    private val keyguardLongPressViewModel: KeyguardLongPressViewModel,
+    private val keyguardTouchHandlingViewModel: KeyguardTouchHandlingViewModel,
     private val keyguardRootViewModel: KeyguardRootViewModel,
     private val vibratorHelper: VibratorHelper,
     private val activityStarter: ActivityStarter,
@@ -76,7 +76,7 @@
                 KeyguardSettingsViewBinder.bind(
                     constraintLayout.requireViewById<View>(R.id.keyguard_settings_button),
                     keyguardSettingsMenuViewModel,
-                    keyguardLongPressViewModel,
+                    keyguardTouchHandlingViewModel,
                     keyguardRootViewModel,
                     vibratorHelper,
                     activityStarter,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/KeyguardSliceViewSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/KeyguardSliceViewSection.kt
index a17c5e5..b33d552 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/KeyguardSliceViewSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/KeyguardSliceViewSection.kt
@@ -35,7 +35,7 @@
 ) : KeyguardSection() {
     override fun addViews(constraintLayout: ConstraintLayout) {
         if (!MigrateClocksToBlueprint.isEnabled) return
-        if (smartspaceController.isEnabled()) return
+        if (smartspaceController.isEnabled) return
 
         constraintLayout.findViewById<View?>(R.id.keyguard_slice_view)?.let {
             (it.parent as ViewGroup).removeView(it)
@@ -47,7 +47,7 @@
 
     override fun applyConstraints(constraintSet: ConstraintSet) {
         if (!MigrateClocksToBlueprint.isEnabled) return
-        if (smartspaceController.isEnabled()) return
+        if (smartspaceController.isEnabled) return
 
         constraintSet.apply {
             connect(
@@ -82,7 +82,7 @@
 
     override fun removeViews(constraintLayout: ConstraintLayout) {
         if (!MigrateClocksToBlueprint.isEnabled) return
-        if (smartspaceController.isEnabled()) return
+        if (smartspaceController.isEnabled) return
 
         constraintLayout.removeView(R.id.keyguard_slice_view)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt
index 8a751f0..55fc718 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt
@@ -37,6 +37,7 @@
 import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController
 import dagger.Lazy
 import javax.inject.Inject
+import kotlinx.coroutines.DisposableHandle
 
 @SysUISingleton
 open class SmartspaceSection
@@ -56,6 +57,7 @@
 
     private var smartspaceVisibilityListener: OnGlobalLayoutListener? = null
     private var pastVisibility: Int = -1
+    private var disposableHandle: DisposableHandle? = null
 
     override fun onRebuildBegin() {
         smartspaceController.suppressDisconnects = true
@@ -96,12 +98,14 @@
     override fun bindData(constraintLayout: ConstraintLayout) {
         if (!MigrateClocksToBlueprint.isEnabled) return
         if (!keyguardSmartspaceViewModel.isSmartspaceEnabled) return
-        KeyguardSmartspaceViewBinder.bind(
-            constraintLayout,
-            keyguardClockViewModel,
-            keyguardSmartspaceViewModel,
-            blueprintInteractor.get(),
-        )
+        disposableHandle?.dispose()
+        disposableHandle =
+            KeyguardSmartspaceViewBinder.bind(
+                constraintLayout,
+                keyguardClockViewModel,
+                keyguardSmartspaceViewModel,
+                blueprintInteractor.get(),
+            )
     }
 
     override fun applyConstraints(constraintSet: ConstraintSet) {
@@ -188,6 +192,8 @@
         }
         smartspaceView?.viewTreeObserver?.removeOnGlobalLayoutListener(smartspaceVisibilityListener)
         smartspaceVisibilityListener = null
+
+        disposableHandle?.dispose()
     }
 
     private fun updateVisibility(constraintSet: ConstraintSet) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModel.kt
index 4128c52..5cf100e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModel.kt
@@ -34,8 +34,8 @@
     alternateBouncerInteractor: AlternateBouncerInteractor,
     keyguardTransitionInteractor: KeyguardTransitionInteractor,
 ) {
-    val canShowAlternateBouncer: Flow<Boolean> = alternateBouncerInteractor.canShowAlternateBouncer
-
+    private val deviceSupportsAlternateBouncer: Flow<Boolean> =
+        alternateBouncerInteractor.alternateBouncerSupported
     private val isTransitioningToOrFromOrShowingAlternateBouncer: Flow<Boolean> =
         keyguardTransitionInteractor
             .transitionValue(KeyguardState.ALTERNATE_BOUNCER)
@@ -43,8 +43,8 @@
             .distinctUntilChanged()
 
     val alternateBouncerWindowRequired: Flow<Boolean> =
-        canShowAlternateBouncer.flatMapLatest { canShowAlternateBouncer ->
-            if (canShowAlternateBouncer) {
+        deviceSupportsAlternateBouncer.flatMapLatest { deviceSupportsAlternateBouncer ->
+            if (deviceSupportsAlternateBouncer) {
                 isTransitioningToOrFromOrShowingAlternateBouncer
             } else {
                 flowOf(false)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
index d9a6d64..62b4782 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
@@ -55,6 +55,7 @@
     private val keyguardInteractor: KeyguardInteractor,
     private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
     private val goneToAodTransitionViewModel: GoneToAodTransitionViewModel,
+    private val lockscreenToAodTransitionViewModel: LockscreenToAodTransitionViewModel,
     private val aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel,
     private val occludedToLockscreenTransitionViewModel: OccludedToLockscreenTransitionViewModel,
     private val keyguardClockViewModel: KeyguardClockViewModel,
@@ -74,13 +75,30 @@
                 burnInParams
             }
         return configurationInteractor
-            .dimensionPixelSize(R.dimen.keyguard_enter_from_top_translation_y)
-            .flatMapLatest { enterFromTopAmount ->
+            .dimensionPixelSize(
+                setOf(
+                    R.dimen.keyguard_enter_from_top_translation_y,
+                    R.dimen.keyguard_enter_from_side_translation_x,
+                )
+            )
+            .flatMapLatest { dimens ->
                 combine(
                     keyguardInteractor.keyguardTranslationY.onStart { emit(0f) },
                     burnIn(params).onStart { emit(BurnInModel()) },
                     goneToAodTransitionViewModel
-                        .enterFromTopTranslationY(enterFromTopAmount)
+                        .enterFromTopTranslationY(
+                            dimens[R.dimen.keyguard_enter_from_top_translation_y]!!
+                        )
+                        .onStart { emit(StateToValue()) },
+                    goneToAodTransitionViewModel
+                        .enterFromSideTranslationX(
+                            dimens[R.dimen.keyguard_enter_from_side_translation_x]!!
+                        )
+                        .onStart { emit(StateToValue()) },
+                    lockscreenToAodTransitionViewModel
+                        .enterFromSideTranslationX(
+                            dimens[R.dimen.keyguard_enter_from_side_translation_x]!!
+                        )
                         .onStart { emit(StateToValue()) },
                     occludedToLockscreenTransitionViewModel.lockscreenTranslationY.onStart {
                         emit(0f)
@@ -88,21 +106,31 @@
                     aodToLockscreenTransitionViewModel.translationY(params.translationY).onStart {
                         emit(StateToValue())
                     },
-                ) {
-                    keyguardTranslationY,
-                    burnInModel,
-                    goneToAod,
-                    occludedToLockscreen,
-                    aodToLockscreen ->
+                ) { flows ->
+                    val keyguardTranslationY = flows[0] as Float
+                    val burnInModel = flows[1] as BurnInModel
+                    val goneToAodTranslationY = flows[2] as StateToValue
+                    val goneToAodTranslationX = flows[3] as StateToValue
+                    val lockscreenToAodTranslationX = flows[4] as StateToValue
+                    val occludedToLockscreen = flows[5] as Float
+                    val aodToLockscreen = flows[6] as StateToValue
+
                     val translationY =
                         if (aodToLockscreen.transitionState.isTransitioning()) {
                             aodToLockscreen.value ?: 0f
-                        } else if (goneToAod.transitionState.isTransitioning()) {
-                            (goneToAod.value ?: 0f) + burnInModel.translationY
+                        } else if (goneToAodTranslationY.transitionState.isTransitioning()) {
+                            (goneToAodTranslationY.value ?: 0f) + burnInModel.translationY
                         } else {
                             burnInModel.translationY + occludedToLockscreen + keyguardTranslationY
                         }
-                    burnInModel.copy(translationY = translationY.toInt())
+                    val translationX =
+                        burnInModel.translationX +
+                            (goneToAodTranslationX.value ?: 0f) +
+                            (lockscreenToAodTranslationX.value ?: 0f)
+                    burnInModel.copy(
+                        translationX = translationX.toInt(),
+                        translationY = translationY.toInt(),
+                    )
                 }
             }
             .distinctUntilChanged()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt
index caa0436..8485a26 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt
@@ -22,6 +22,7 @@
 import com.android.systemui.keyguard.shared.model.Edge
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
+import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
 import com.android.systemui.keyguard.shared.model.ScrimAlpha
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
@@ -75,9 +76,12 @@
         return animationFlow
             .setup(
                 duration = duration,
-                // TODO(b/330311871): from can be PRIMARY_BOUNCER which would be a scene -> scene
-                //  transition
-                edge = Edge.create(from = from, to = Scenes.Gone)
+                edge =
+                    if (from == PRIMARY_BOUNCER) {
+                        Edge.INVALID
+                    } else {
+                        Edge.create(from = from, to = Scenes.Gone)
+                    }
             )
             .setupWithoutSceneContainer(
                 edge = Edge.create(from = from, to = GONE),
@@ -105,9 +109,12 @@
             animationFlow
                 .setup(
                     duration = duration,
-                    // TODO(b/330311871): from can be PRIMARY_BOUNCER which would be a scene ->
-                    //  scene transition
-                    edge = Edge.create(from = fromState, to = Scenes.Gone),
+                    edge =
+                        if (fromState == PRIMARY_BOUNCER) {
+                            Edge.INVALID
+                        } else {
+                            Edge.create(from = fromState, to = Scenes.Gone)
+                        }
                 )
                 .setupWithoutSceneContainer(
                     edge = Edge.create(from = fromState, to = GONE),
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
index 4688088..5ce1b5e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
@@ -284,9 +284,9 @@
     private fun DeviceEntryIconView.IconType.toAccessibilityHintType():
         DeviceEntryIconView.AccessibilityHintType {
         return when (this) {
+            DeviceEntryIconView.IconType.FINGERPRINT,
             DeviceEntryIconView.IconType.LOCK -> DeviceEntryIconView.AccessibilityHintType.BOUNCER
             DeviceEntryIconView.IconType.UNLOCK -> DeviceEntryIconView.AccessibilityHintType.ENTER
-            DeviceEntryIconView.IconType.FINGERPRINT,
             DeviceEntryIconView.IconType.NONE -> DeviceEntryIconView.AccessibilityHintType.NONE
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGlanceableHubTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGlanceableHubTransitionViewModel.kt
new file mode 100644
index 0000000..aee34e1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToGlanceableHubTransitionViewModel.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyguard.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromDozingTransitionInteractor.Companion.TO_GLANCEABLE_HUB_DURATION
+import com.android.systemui.keyguard.shared.model.Edge
+import com.android.systemui.keyguard.shared.model.KeyguardState.DOZING
+import com.android.systemui.keyguard.shared.model.KeyguardState.GLANCEABLE_HUB
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
+import com.android.systemui.scene.shared.model.Scenes
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class DozingToGlanceableHubTransitionViewModel
+@Inject
+constructor(animationFlow: KeyguardTransitionAnimationFlow) : DeviceEntryIconTransition {
+    private val transitionAnimation =
+        animationFlow
+            .setup(
+                duration = TO_GLANCEABLE_HUB_DURATION,
+                edge = Edge.create(DOZING, Scenes.Communal)
+            )
+            .setupWithoutSceneContainer(edge = Edge.create(DOZING, GLANCEABLE_HUB))
+
+    override val deviceEntryParentViewAlpha: Flow<Float> =
+        transitionAnimation.immediatelyTransitionTo(1f)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModel.kt
index 74f7d75..2bc8e51 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModel.kt
@@ -26,13 +26,17 @@
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
 import com.android.systemui.keyguard.ui.StateToValue
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
+import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.power.shared.model.WakeSleepReason.FOLD
 import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.transform
 
 /** Breaks down GONE->AOD transition into discrete steps for corresponding views to consume. */
 @ExperimentalCoroutinesApi
@@ -41,6 +45,7 @@
 @Inject
 constructor(
     deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
+    private val powerInteractor: PowerInteractor,
     animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition {
 
@@ -56,13 +61,38 @@
 
     /** y-translation from the top of the screen for AOD */
     fun enterFromTopTranslationY(translatePx: Int): Flow<StateToValue> {
-        return transitionAnimation.sharedFlowWithState(
-            startTime = 600.milliseconds,
-            duration = 500.milliseconds,
-            onStep = { translatePx + it * -translatePx },
-            onFinish = { 0f },
-            interpolator = EMPHASIZED_DECELERATE,
-        )
+        return transitionAnimation
+            .sharedFlowWithState(
+                startTime = 600.milliseconds,
+                duration = 500.milliseconds,
+                onStep = { translatePx + it * -translatePx },
+                onFinish = { 0f },
+                interpolator = EMPHASIZED_DECELERATE,
+            )
+            .sample(powerInteractor.detailedWakefulness, ::Pair)
+            .transform { (stateToValue, wakefulness) ->
+                if (wakefulness.lastSleepReason != FOLD) {
+                    emit(stateToValue)
+                }
+            }
+    }
+
+    /** x-translation from the side of the screen for fold animation */
+    fun enterFromSideTranslationX(translatePx: Int): Flow<StateToValue> {
+        return transitionAnimation
+            .sharedFlowWithState(
+                startTime = 500.milliseconds,
+                duration = 600.milliseconds,
+                onStep = { translatePx + it * -translatePx },
+                onFinish = { 0f },
+                interpolator = EMPHASIZED_DECELERATE,
+            )
+            .sample(powerInteractor.detailedWakefulness, ::Pair)
+            .transform { (stateToValue, wakefulness) ->
+                if (wakefulness.lastSleepReason == FOLD) {
+                    emit(stateToValue)
+                }
+            }
     }
 
     val notificationAlpha: Flow<Float> =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToGlanceableHubTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToGlanceableHubTransitionViewModel.kt
index 8eab406..6a3573a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToGlanceableHubTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToGlanceableHubTransitionViewModel.kt
@@ -23,7 +23,6 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
-import com.android.systemui.scene.shared.model.Scenes
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.flow.Flow
@@ -37,7 +36,7 @@
 
     private val transitionAnimation =
         animationFlow
-            .setup(duration = TO_GLANCEABLE_HUB_DURATION, edge = Edge.create(GONE, Scenes.Communal))
+            .setup(duration = TO_GLANCEABLE_HUB_DURATION, edge = Edge.INVALID)
             .setupWithoutSceneContainer(edge = Edge.create(GONE, GLANCEABLE_HUB))
 
     override val deviceEntryParentViewAlpha: Flow<Float> =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
index 3e6f8e6..6fe51ae 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModel.kt
@@ -44,7 +44,7 @@
     private val quickAffordanceInteractor: KeyguardQuickAffordanceInteractor,
     private val bottomAreaInteractor: KeyguardBottomAreaInteractor,
     private val burnInHelperWrapper: BurnInHelperWrapper,
-    private val longPressViewModel: KeyguardLongPressViewModel,
+    private val keyguardTouchHandlingViewModel: KeyguardTouchHandlingViewModel,
     val settingsMenuViewModel: KeyguardSettingsMenuViewModel,
 ) {
     data class PreviewMode(
@@ -162,7 +162,7 @@
      * the lock screen settings menu item pop-up.
      */
     fun onTouchedOutsideLockScreenSettingsMenu() {
-        longPressViewModel.onTouchedOutside()
+        keyguardTouchHandlingViewModel.onTouchedOutside()
     }
 
     private fun button(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
index f5c521a..573b75e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
@@ -31,7 +31,6 @@
 import com.android.systemui.res.R
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
-import com.android.systemui.statusbar.notification.domain.interactor.NotificationsKeyguardInteractor
 import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerAlwaysOnDisplayViewModel
 import com.android.systemui.statusbar.ui.SystemBarUtilsProxy
 import javax.inject.Inject
@@ -50,7 +49,6 @@
     keyguardClockInteractor: KeyguardClockInteractor,
     @Application private val applicationScope: CoroutineScope,
     aodNotificationIconViewModel: NotificationIconContainerAlwaysOnDisplayViewModel,
-    notifsKeyguardInteractor: NotificationsKeyguardInteractor,
     @get:VisibleForTesting val shadeInteractor: ShadeInteractor,
     private val systemBarUtils: SystemBarUtilsProxy,
     configurationInteractor: ConfigurationInteractor,
@@ -90,14 +88,13 @@
                 currentClock?.let { clock ->
                     val face = if (isLargeClock) clock.largeClock else clock.smallClock
                     face.config.hasCustomWeatherDataDisplay
-                }
-                    ?: false
+                } ?: false
             }
             .stateIn(
                 scope = applicationScope,
                 started = SharingStarted.WhileSubscribed(),
-                initialValue = currentClock.value?.largeClock?.config?.hasCustomWeatherDataDisplay
-                        ?: false
+                initialValue =
+                    currentClock.value?.largeClock?.config?.hasCustomWeatherDataDisplay ?: false
             )
 
     val clockShouldBeCentered: StateFlow<Boolean> =
@@ -109,15 +106,14 @@
 
     // To translate elements below smartspace in weather clock to avoid overlapping between date
     // element in weather clock and aod icons
-    val isAodIconsVisible: StateFlow<Boolean> = combine(aodNotificationIconViewModel.icons.map {
-        it.visibleIcons.isNotEmpty()
-    }, notifsKeyguardInteractor.areNotificationsFullyHidden) { hasIcons, visible ->
-        hasIcons && visible
-    }.stateIn(
-            scope = applicationScope,
-            started = SharingStarted.WhileSubscribed(),
-            initialValue = false
-        )
+    val hasAodIcons: StateFlow<Boolean> =
+        aodNotificationIconViewModel.icons
+            .map { it.visibleIcons.isNotEmpty() }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = false
+            )
 
     val currentClockLayout: StateFlow<ClockLayout> =
         combine(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt
index a758720d..609b571d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardIndicationAreaViewModel.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.keyguard.ui.viewmodel
 
 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
+import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.doze.util.BurnInHelperWrapper
@@ -28,9 +29,10 @@
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.BurnInModel
 import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.StatusBarState
 import com.android.systemui.res.R
+import com.android.systemui.util.kotlin.BooleanFlowOperators.anyOf
 import javax.inject.Inject
-import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
@@ -44,14 +46,15 @@
 @Inject
 constructor(
     private val keyguardInteractor: KeyguardInteractor,
-    private val bottomAreaInteractor: KeyguardBottomAreaInteractor,
+    bottomAreaInteractor: KeyguardBottomAreaInteractor,
     keyguardBottomAreaViewModel: KeyguardBottomAreaViewModel,
     private val burnInHelperWrapper: BurnInHelperWrapper,
-    private val burnInInteractor: BurnInInteractor,
-    private val shortcutsCombinedViewModel: KeyguardQuickAffordancesCombinedViewModel,
+    burnInInteractor: BurnInInteractor,
+    shortcutsCombinedViewModel: KeyguardQuickAffordancesCombinedViewModel,
     configurationInteractor: ConfigurationInteractor,
     keyguardTransitionInteractor: KeyguardTransitionInteractor,
-    @Background private val backgroundCoroutineContext: CoroutineContext,
+    communalSceneInteractor: CommunalSceneInteractor,
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
     @Main private val mainDispatcher: CoroutineDispatcher,
 ) {
 
@@ -61,6 +64,13 @@
     /** An observable for the alpha level for the entire bottom area. */
     val alpha: Flow<Float> = keyguardBottomAreaViewModel.alpha
 
+    /** An observable for the visibility value for the indication area view. */
+    val visible: Flow<Boolean> =
+        anyOf(
+            keyguardInteractor.statusBarState.map { state -> state == StatusBarState.KEYGUARD },
+            communalSceneInteractor.isCommunalVisible
+        )
+
     /** An observable for whether the indication area should be padded. */
     val isIndicationAreaPadded: Flow<Boolean> =
         if (KeyguardBottomAreaRefactor.isEnabled) {
@@ -97,7 +107,7 @@
                 )
             }
             .distinctUntilChanged()
-            .flowOn(backgroundCoroutineContext)
+            .flowOn(backgroundDispatcher)
 
     /** An observable for the x-offset by which the indication area should be translated. */
     val indicationAreaTranslationX: Flow<Float> =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardLongPressViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardLongPressViewModel.kt
deleted file mode 100644
index c73931a..0000000
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardLongPressViewModel.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.keyguard.ui.viewmodel
-
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.keyguard.domain.interactor.KeyguardLongPressInteractor
-import javax.inject.Inject
-import kotlinx.coroutines.flow.Flow
-
-/** Models UI state to support the lock screen long-press feature. */
-@SysUISingleton
-class KeyguardLongPressViewModel
-@Inject
-constructor(
-    private val interactor: KeyguardLongPressInteractor,
-) {
-
-    /** Whether the long-press handling feature should be enabled. */
-    val isLongPressHandlingEnabled: Flow<Boolean> = interactor.isLongPressHandlingEnabled
-
-    /** Notifies that the user has long-pressed on the lock screen. */
-    fun onLongPress() {
-        interactor.onLongPress()
-    }
-
-    /**
-     * Notifies that some input gesture has started somewhere outside of the lock screen settings
-     * menu item pop-up.
-     */
-    fun onTouchedOutside() {
-        interactor.onTouchedOutside()
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
index c4383fc..680f966 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModel.kt
@@ -18,6 +18,7 @@
 package com.android.systemui.keyguard.ui.viewmodel
 
 import androidx.annotation.VisibleForTesting
+import com.android.app.tracing.FlowTracing.traceEmissionCount
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -229,7 +230,7 @@
                     )
                 }
                 .distinctUntilChanged()
-        }
+        }.traceEmissionCount({"QuickAfforcances#button${position.toSlotId()}"})
     }
 
     private fun KeyguardQuickAffordanceModel.toViewModel(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
index aefff7d..0fb29c2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
@@ -143,7 +143,7 @@
 
     private val isOnLockscreen: Flow<Boolean> =
         combine(
-                keyguardTransitionInteractor.isFinishedInState(LOCKSCREEN).onStart { emit(false) },
+                keyguardTransitionInteractor.isFinishedIn(LOCKSCREEN).onStart { emit(false) },
                 anyOf(
                     keyguardTransitionInteractor.isInTransition(Edge.create(to = LOCKSCREEN)),
                     keyguardTransitionInteractor.isInTransition(Edge.create(from = LOCKSCREEN)),
@@ -251,6 +251,7 @@
                         goneToDreamingTransitionViewModel.lockscreenAlpha,
                         goneToLockscreenTransitionViewModel.lockscreenAlpha,
                         lockscreenToAodTransitionViewModel.lockscreenAlpha(viewState),
+                        lockscreenToAodTransitionViewModel.lockscreenAlphaOnFold,
                         lockscreenToDozingTransitionViewModel.lockscreenAlpha,
                         lockscreenToDreamingTransitionViewModel.lockscreenAlpha,
                         lockscreenToGlanceableHubTransitionViewModel.keyguardAlpha,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSettingsMenuViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSettingsMenuViewModel.kt
index 66ceded..36a342b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSettingsMenuViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSettingsMenuViewModel.kt
@@ -17,10 +17,10 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
-import com.android.systemui.res.R
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.common.shared.model.Text
-import com.android.systemui.keyguard.domain.interactor.KeyguardLongPressInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTouchHandlingInteractor
+import com.android.systemui.res.R
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
 
@@ -28,7 +28,7 @@
 class KeyguardSettingsMenuViewModel
 @Inject
 constructor(
-    private val interactor: KeyguardLongPressInteractor,
+    private val interactor: KeyguardTouchHandlingInteractor,
 ) {
     val isVisible: Flow<Boolean> = interactor.isMenuVisible
     val shouldOpenSettings: Flow<Boolean> = interactor.shouldOpenSettings
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt
index c0b1f95..e30ddc6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt
@@ -40,12 +40,12 @@
     smartspaceInteractor: KeyguardSmartspaceInteractor,
 ) {
     /** Whether the smartspace section is available in the build. */
-    val isSmartspaceEnabled: Boolean = smartspaceController.isEnabled()
+    val isSmartspaceEnabled: Boolean = smartspaceController.isEnabled
     /** Whether the weather area is available in the build. */
     private val isWeatherEnabled: StateFlow<Boolean> = smartspaceInteractor.isWeatherEnabled
 
     /** Whether the data and weather areas are decoupled in the build. */
-    val isDateWeatherDecoupled: Boolean = smartspaceController.isDateWeatherDecoupled()
+    val isDateWeatherDecoupled: Boolean = smartspaceController.isDateWeatherDecoupled
 
     /** Whether the date area should be visible. */
     val isDateVisible: StateFlow<Boolean> =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardTouchHandlingViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardTouchHandlingViewModel.kt
new file mode 100644
index 0000000..f1cbf25
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardTouchHandlingViewModel.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyguard.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.KeyguardTouchHandlingInteractor
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+
+/** Models UI state to support top-level touch handling in the lock screen. */
+@SysUISingleton
+class KeyguardTouchHandlingViewModel
+@Inject
+constructor(
+    private val interactor: KeyguardTouchHandlingInteractor,
+) {
+
+    /** Whether the long-press handling feature should be enabled. */
+    val isLongPressHandlingEnabled: Flow<Boolean> = interactor.isLongPressHandlingEnabled
+
+    /** Notifies that the user has long-pressed on the lock screen. */
+    fun onLongPress() {
+        interactor.onLongPress()
+    }
+
+    /**
+     * Notifies that some input gesture has started somewhere outside of the lock screen settings
+     * menu item pop-up.
+     */
+    fun onTouchedOutside() {
+        interactor.onTouchedOutside()
+    }
+
+    /** Notifies that the lockscreen has been clicked at position [x], [y]. */
+    fun onClick(x: Float, y: Float) {
+        interactor.onClick(x, y)
+    }
+
+    /** Notifies that the lockscreen has been double clicked. */
+    fun onDoubleClick() {
+        interactor.onDoubleClick()
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt
index b33eaa2..8a29f96 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt
@@ -25,6 +25,7 @@
 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
 import com.android.systemui.keyguard.shared.model.ClockSize
 import com.android.systemui.res.R
+import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor
@@ -44,10 +45,11 @@
     clockInteractor: KeyguardClockInteractor,
     private val interactor: KeyguardBlueprintInteractor,
     private val authController: AuthController,
-    val longPress: KeyguardLongPressViewModel,
+    val touchHandling: KeyguardTouchHandlingViewModel,
     val shadeInteractor: ShadeInteractor,
     @Application private val applicationScope: CoroutineScope,
     unfoldTransitionInteractor: UnfoldTransitionInteractor,
+    occlusionInteractor: SceneContainerOcclusionInteractor,
 ) {
     @VisibleForTesting val clockSize = clockInteractor.clockSize
 
@@ -93,6 +95,16 @@
                 initialValue = UnfoldTranslations(),
             )
 
+    /** Whether the content of the scene UI should be shown. */
+    val isContentVisible: StateFlow<Boolean> =
+        occlusionInteractor.isOccludingActivityShown
+            .map { !it }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = true,
+            )
+
     fun getSmartSpacePaddingTop(resources: Resources): Int {
         return if (clockSize.value == ClockSize.LARGE) {
             resources.getDimensionPixelSize(R.dimen.keyguard_smartspace_top_offset) +
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
index 10cfd6b..630dcca 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModel.kt
@@ -53,7 +53,7 @@
     deviceEntryInteractor: DeviceEntryInteractor,
     communalInteractor: CommunalInteractor,
     shadeInteractor: ShadeInteractor,
-    val longPress: KeyguardLongPressViewModel,
+    val touchHandling: KeyguardTouchHandlingViewModel,
     val notifications: NotificationsPlaceholderViewModel,
 ) {
     val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt
index 8b5b347..5408428 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModel.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.keyguard.ui.viewmodel
 
 import android.util.MathUtils
+import com.android.app.animation.Interpolators.EMPHASIZED_DECELERATE
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
 import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor
@@ -24,12 +25,17 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
 import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.StateToValue
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
+import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.power.shared.model.WakeSleepReason.FOLD
+import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.transform
 
 /**
  * Breaks down LOCKSCREEN->AOD transition into discrete steps for corresponding views to consume.
@@ -40,6 +46,7 @@
 @Inject
 constructor(
     deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
+    private val powerInteractor: PowerInteractor,
     shadeDependentFlows: ShadeDependentFlows,
     animationFlow: KeyguardTransitionAnimationFlow,
 ) : DeviceEntryIconTransition {
@@ -50,6 +57,12 @@
             edge = Edge.create(from = LOCKSCREEN, to = AOD),
         )
 
+    private val transitionAnimationOnFold =
+        animationFlow.setup(
+            duration = FromLockscreenTransitionInteractor.TO_AOD_FOLD_DURATION,
+            edge = Edge.create(from = LOCKSCREEN, to = AOD),
+        )
+
     val deviceEntryBackgroundViewAlpha: Flow<Float> =
         shadeDependentFlows.transitionFlow(
             flowWhenShadeIsExpanded = transitionAnimation.immediatelyTransitionTo(0f),
@@ -71,11 +84,64 @@
 
     fun lockscreenAlpha(viewState: ViewStateAccessor): Flow<Float> {
         var startAlpha = 1f
-        return transitionAnimation.sharedFlow(
-            duration = 500.milliseconds,
-            onStart = { startAlpha = viewState.alpha() },
-            onStep = { MathUtils.lerp(startAlpha, 1f, it) },
-        )
+        return transitionAnimation
+            .sharedFlow(
+                duration = 500.milliseconds,
+                onStart = { startAlpha = viewState.alpha() },
+                onStep = { MathUtils.lerp(startAlpha, 1f, it) },
+            )
+            .sample(powerInteractor.detailedWakefulness, ::Pair)
+            .transform { (alpha, wakefulness) ->
+                if (wakefulness.lastSleepReason != FOLD) {
+                    emit(alpha)
+                }
+            }
+    }
+
+    val lockscreenAlphaOnFold: Flow<Float> =
+        transitionAnimationOnFold
+            .sharedFlow(
+                startTime = 600.milliseconds,
+                duration = 500.milliseconds,
+                onStep = { it },
+            )
+            .sample(powerInteractor.detailedWakefulness, ::Pair)
+            .transform { (alpha, wakefulness) ->
+                if (wakefulness.lastSleepReason == FOLD) {
+                    emit(alpha)
+                }
+            }
+
+    val notificationAlphaOnFold: Flow<Float> =
+        transitionAnimationOnFold
+            .sharedFlow(
+                duration = 1100.milliseconds,
+                onStep = { 0f },
+                onFinish = { 1f },
+            )
+            .sample(powerInteractor.detailedWakefulness, ::Pair)
+            .transform { (alpha, wakefulness) ->
+                if (wakefulness.lastSleepReason == FOLD) {
+                    emit(alpha)
+                }
+            }
+
+    /** x-translation from the side of the screen for fold animation */
+    fun enterFromSideTranslationX(translatePx: Int): Flow<StateToValue> {
+        return transitionAnimationOnFold
+            .sharedFlowWithState(
+                startTime = 600.milliseconds,
+                duration = 500.milliseconds,
+                onStep = { translatePx + it * -translatePx },
+                onFinish = { 0f },
+                interpolator = EMPHASIZED_DECELERATE,
+            )
+            .sample(powerInteractor.detailedWakefulness, ::Pair)
+            .transform { (stateToValue, wakefulness) ->
+                if (wakefulness.lastSleepReason == FOLD) {
+                    emit(stateToValue)
+                }
+            }
     }
 
     override val deviceEntryParentViewAlpha: Flow<Float> =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModel.kt
new file mode 100644
index 0000000..754fb94
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGlanceableHubTransitionViewModel.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyguard.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor.Companion.TO_GLANCEABLE_HUB_DURATION
+import com.android.systemui.keyguard.shared.model.Edge
+import com.android.systemui.keyguard.shared.model.KeyguardState.GLANCEABLE_HUB
+import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
+import com.android.systemui.scene.shared.model.Scenes
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class PrimaryBouncerToGlanceableHubTransitionViewModel
+@Inject
+constructor(animationFlow: KeyguardTransitionAnimationFlow) : DeviceEntryIconTransition {
+    private val transitionAnimation =
+        animationFlow
+            .setup(
+                duration = TO_GLANCEABLE_HUB_DURATION,
+                edge = Edge.create(PRIMARY_BOUNCER, Scenes.Communal)
+            )
+            .setupWithoutSceneContainer(edge = Edge.create(PRIMARY_BOUNCER, GLANCEABLE_HUB))
+
+    override val deviceEntryParentViewAlpha: Flow<Float> =
+        transitionAnimation.immediatelyTransitionTo(1f)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
index 7ae4558..46ba5d1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.keyguard.shared.model.ScrimAlpha
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
-import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.statusbar.SysuiStatusBarStateController
 import dagger.Lazy
 import javax.inject.Inject
@@ -54,7 +53,7 @@
         animationFlow
             .setup(
                 duration = TO_GONE_DURATION,
-                edge = Edge.create(from = PRIMARY_BOUNCER, to = Scenes.Gone),
+                edge = Edge.INVALID,
             )
             .setupWithoutSceneContainer(
                 edge = Edge.create(from = PRIMARY_BOUNCER, to = GONE),
diff --git a/packages/SystemUI/src/com/android/systemui/log/LogBufferFactory.kt b/packages/SystemUI/src/com/android/systemui/log/LogBufferFactory.kt
index e4465ac..6351d7d 100644
--- a/packages/SystemUI/src/com/android/systemui/log/LogBufferFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/LogBufferFactory.kt
@@ -19,10 +19,13 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.log.LogBufferHelper.Companion.adjustMaxSize
+import com.android.systemui.log.echo.LogcatEchoTrackerAlways
 import javax.inject.Inject
 
 @SysUISingleton
-class LogBufferFactory @Inject constructor(
+class LogBufferFactory
+@Inject
+constructor(
     private val dumpManager: DumpManager,
     private val logcatEchoTracker: LogcatEchoTracker
 ) {
@@ -30,9 +33,11 @@
     fun create(
         name: String,
         maxSize: Int,
-        systrace: Boolean = true
+        systrace: Boolean = true,
+        alwaysLogToLogcat: Boolean = false,
     ): LogBuffer {
-        val buffer = LogBuffer(name, adjustMaxSize(maxSize), logcatEchoTracker, systrace)
+        val echoTracker = if (alwaysLogToLogcat) LogcatEchoTrackerAlways else logcatEchoTracker
+        val buffer = LogBuffer(name, adjustMaxSize(maxSize), echoTracker, systrace)
         dumpManager.registerBuffer(name, buffer)
         return buffer
     }
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index 1e79f42..d1c9b8e 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -369,9 +369,9 @@
      */
     @Provides
     @SysUISingleton
-    @MediaLoadingLog
-    public static LogBuffer providesMediaLoadingLogBuffer(LogBufferFactory factory) {
-        return factory.create("MediaLoadingLog", 20);
+    @MediaLog
+    public static LogBuffer providesMediaLogBuffer(LogBufferFactory factory) {
+        return factory.create("MediaLog", 20);
     }
 
     /** Allows logging buffers to be tweaked via adb on debug builds but not on prod builds. */
@@ -622,7 +622,8 @@
     @SysUISingleton
     @SceneFrameworkLog
     public static LogBuffer provideSceneFrameworkLogBuffer(LogBufferFactory factory) {
-        return factory.create("SceneFramework", 50);
+        return factory
+                .create("SceneFramework", 50, /* systrace */ true, /* alwaysLogToLogcat */  true);
     }
 
     /** Provides a {@link LogBuffer} for the bluetooth QS tile dialog. */
@@ -673,4 +674,11 @@
         return factory.create("DeviceEntryIconLog", 100);
     }
 
+    /** Provides a {@link LogBuffer} for use by the volume loggers. */
+    @Provides
+    @SysUISingleton
+    @VolumeLog
+    public static LogBuffer provideVolumeLogBuffer(LogBufferFactory factory) {
+        return factory.create("VolumeLog", 50);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/MediaLoadingLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/MediaLoadingLog.kt
deleted file mode 100644
index 05e1b2e..0000000
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/MediaLoadingLog.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.log.dagger
-
-import com.android.systemui.log.LogBuffer
-import javax.inject.Qualifier
-
-/** A [LogBuffer] for [com.android.systemui.media.controls.domain.pipeline.MediaLoadingLogger] */
-@Qualifier
-@MustBeDocumented
-@Retention(AnnotationRetention.RUNTIME)
-annotation class MediaLoadingLog
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/MediaLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/MediaLog.kt
new file mode 100644
index 0000000..d1dc6f3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/MediaLog.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.log.dagger
+
+import com.android.systemui.log.LogBuffer
+import javax.inject.Qualifier
+
+/** A [LogBuffer] for [com.android.systemui.media.controls.shared.MediaLogger] */
+@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class MediaLog
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/NavBarButtonClickLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/NavBarButtonClickLog.java
index 939dab2..28bdbb2 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/NavBarButtonClickLog.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/NavBarButtonClickLog.java
@@ -20,13 +20,14 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.android.systemui.log.LogBuffer;
+import com.android.systemui.navigationbar.views.NavigationBar;
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.Retention;
 
 import javax.inject.Qualifier;
 
-/** A {@link LogBuffer} for {@link com.android.systemui.navigationbar.NavigationBar}. */
+/** A {@link LogBuffer} for {@link NavigationBar}. */
 @Qualifier
 @Documented
 @Retention(RUNTIME)
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/NavbarOrientationTrackingLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/NavbarOrientationTrackingLog.java
index 46790a6..d09eeb2 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/NavbarOrientationTrackingLog.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/NavbarOrientationTrackingLog.java
@@ -19,13 +19,14 @@
 import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
 import com.android.systemui.log.LogBuffer;
+import com.android.systemui.navigationbar.views.NavigationBar;
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.Retention;
 
 import javax.inject.Qualifier;
 
-/** A {@link LogBuffer} for {@link com.android.systemui.navigationbar.NavigationBar}. */
+/** A {@link LogBuffer} for {@link NavigationBar}. */
 @Qualifier
 @Documented
 @Retention(RUNTIME)
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/VolumeLog.kt b/packages/SystemUI/src/com/android/systemui/log/dagger/VolumeLog.kt
new file mode 100644
index 0000000..bc3858a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/VolumeLog.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.log.dagger
+
+import javax.inject.Qualifier
+
+/** A [com.android.systemui.log.LogBuffer] for volume. */
+@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class VolumeLog
diff --git a/packages/SystemUI/src/com/android/systemui/log/echo/LogcatEchoTrackerAlways.kt b/packages/SystemUI/src/com/android/systemui/log/echo/LogcatEchoTrackerAlways.kt
new file mode 100644
index 0000000..ce096b3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/echo/LogcatEchoTrackerAlways.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.log.echo
+
+import com.android.systemui.log.LogcatEchoTracker
+import com.android.systemui.log.core.LogLevel
+
+/**
+ * The buffer and all of its tags will be logged to logcat at all times.
+ *
+ * This can be used for buffers that are important and should appear in bugreports in logcat
+ * directly.
+ */
+object LogcatEchoTrackerAlways : LogcatEchoTracker {
+    override fun isBufferLoggable(bufferName: String, level: LogLevel): Boolean = true
+
+    override fun isTagLoggable(tagName: String, level: LogLevel): Boolean = true
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java b/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
index 1b3b473..18a04ec 100644
--- a/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/media/NotificationPlayer.java
@@ -43,7 +43,7 @@
 public class NotificationPlayer implements OnCompletionListener, OnErrorListener {
     private static final int PLAY = 1;
     private static final int STOP = 2;
-    private static final boolean DEBUG = false;
+    private static final boolean DEBUG = true;
 
     private static final class Command {
         int code;
@@ -158,7 +158,7 @@
                 }
                 if (mp != null) {
                     if (DEBUG) {
-                        Log.d(mTag, "mPlayer.pause+release piid:" + player.getPlayerIId());
+                        Log.d(mTag, "mp.pause+release piid:" + mp.getPlayerIId());
                     }
                     mp.pause();
                     try {
diff --git a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
index 3ab0420..bda0069 100644
--- a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
@@ -17,6 +17,7 @@
 package com.android.systemui.media;
 
 import android.annotation.Nullable;
+import android.content.ContentProvider;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -53,7 +54,7 @@
 @SysUISingleton
 public class RingtonePlayer implements CoreStartable {
     private static final String TAG = "RingtonePlayer";
-    private static final boolean LOGD = false;
+    private static final boolean LOGD = true;
     private final Context mContext;
 
     // TODO: support Uri switching under same IBinder
@@ -123,9 +124,13 @@
                 boolean looping, @Nullable VolumeShaper.Configuration volumeShaperConfig)
                 throws RemoteException {
             if (LOGD) {
-                Log.d(TAG, "play(token=" + token + ", uri=" + uri + ", uid="
-                        + Binder.getCallingUid() + ")");
+                Log.d(TAG, "play(token=" + token + ", uri=" + uri
+                        + ", uid=" + Binder.getCallingUid()
+                        + ") uriUserId=" + ContentProvider.getUserIdFromUri(uri)
+                        + " callingUserId=" + Binder.getCallingUserHandle().getIdentifier());
             }
+            enforceUriUserId(uri);
+
             Client client;
             synchronized (mClients) {
                 client = mClients.get(token);
@@ -207,6 +212,7 @@
 
         @Override
         public String getTitle(Uri uri) {
+            enforceUriUserId(uri);
             final UserHandle user = Binder.getCallingUserHandle();
             return Ringtone.getTitle(getContextForUser(user), uri,
                     false /*followSettingsUri*/, false /*allowRemote*/);
@@ -239,6 +245,25 @@
             }
             throw new SecurityException("Uri is not ringtone, alarm, or notification: " + uri);
         }
+
+        /**
+         * Must be called from the Binder calling thread.
+         * Ensures caller is from the same userId as the content they're trying to access.
+         * @param uri the URI to check
+         * @throws SecurityException when non-system call or userId in uri differs from the
+         *                           caller's userId
+         */
+        private void enforceUriUserId(Uri uri) throws SecurityException {
+            final int uriUserId = ContentProvider.getUserIdFromUri(uri);
+            final int callerUserId = Binder.getCallingUserHandle().getIdentifier();
+            // for a non-system call, verify the URI to play belongs to the same user as the caller
+            if (UserHandle.isApp(Binder.getCallingUid()) && uriUserId != callerUserId) {
+                throw new SecurityException("Illegal access to uri=" + uri
+                        + " content associated with user=" + uriUserId
+                        + ", request originates from user=" + callerUserId);
+            }
+        }
+
     };
 
     private Context getContextForUser(UserHandle user) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt b/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt
index 6a91d1b..341b8d8 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt
@@ -26,6 +26,10 @@
 import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
 import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
 import com.android.systemui.media.controls.shared.model.SmartspaceMediaLoadingModel
+import com.android.systemui.media.controls.util.MediaSmartspaceLogger
+import com.android.systemui.media.controls.util.MediaSmartspaceLogger.Companion.SMARTSPACE_CARD_DISMISS_EVENT
+import com.android.systemui.media.controls.util.MediaSmartspaceLogger.Companion.SMARTSPACE_CARD_SEEN_EVENT
+import com.android.systemui.media.controls.util.SmallHash
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.util.time.SystemClock
 import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
@@ -43,9 +47,10 @@
 class MediaFilterRepository
 @Inject
 constructor(
-    @Application applicationContext: Context,
+    @Application private val applicationContext: Context,
     private val systemClock: SystemClock,
     private val configurationController: ConfigurationController,
+    private val smartspaceLogger: MediaSmartspaceLogger,
 ) {
 
     val onAnyMediaConfigurationChange: Flow<Unit> = conflatedCallbackFlow {
@@ -133,10 +138,13 @@
         return mediaData
     }
 
-    fun addSelectedUserMediaEntry(data: MediaData) {
+    /** @return whether the added media data already exists. */
+    fun addSelectedUserMediaEntry(data: MediaData): Boolean {
         val entries = LinkedHashMap<InstanceId, MediaData>(_selectedUserEntries.value)
+        val update = _selectedUserEntries.value.containsKey(data.instanceId)
         entries[data.instanceId] = data
         _selectedUserEntries.value = entries
+        return update
     }
 
     /**
@@ -180,7 +188,10 @@
         _reactivatedId.value = instanceId
     }
 
-    fun addMediaDataLoadingState(mediaDataLoadingModel: MediaDataLoadingModel) {
+    fun addMediaDataLoadingState(
+        mediaDataLoadingModel: MediaDataLoadingModel,
+        isUpdate: Boolean = true
+    ) {
         val sortedMap = TreeMap<MediaSortKeyModel, MediaCommonModel>(comparator)
         sortedMap.putAll(
             sortedMedia.filter { (_, commonModel) ->
@@ -208,7 +219,8 @@
                     MediaCommonModel.MediaControl(
                         mediaDataLoadingModel,
                         canBeRemoved(it),
-                        isMediaFromRec(it)
+                        isMediaFromRec(it),
+                        if (isUpdate) systemClock.currentTimeMillis() else 0,
                     )
                 sortedMap[sortKey] = newCommonModel
 
@@ -218,30 +230,50 @@
                         mediaFromRecPackageName = null
                         _currentMedia.value = sortedMap.values.toList()
                     }
-                } else if (sortedMap.size > _currentMedia.value.size && it.active) {
-                    _currentMedia.value = sortedMap.values.toList()
                 } else {
-                    // When loading an update for an existing media control.
+                    var isNewToCurrentMedia = true
                     val currentList =
                         mutableListOf<MediaCommonModel>().apply { addAll(_currentMedia.value) }
                     currentList.forEachIndexed { index, mediaCommonModel ->
                         if (
                             mediaCommonModel is MediaCommonModel.MediaControl &&
                                 mediaCommonModel.mediaLoadedModel.instanceId ==
-                                    mediaDataLoadingModel.instanceId &&
-                                mediaCommonModel != newCommonModel
+                                    mediaDataLoadingModel.instanceId
                         ) {
-                            // Update media model if changed.
-                            currentList[index] = newCommonModel
+                            // When loading an update for an existing media control.
+                            isNewToCurrentMedia = false
+                            if (mediaCommonModel != newCommonModel) {
+                                // Update media model if changed.
+                                currentList[index] = newCommonModel
+                            }
                         }
                     }
-                    _currentMedia.value = currentList
+                    if (isNewToCurrentMedia && it.active) {
+                        _currentMedia.value = sortedMap.values.toList()
+                    } else {
+                        _currentMedia.value = currentList
+                    }
+                }
+
+                sortedMedia = sortedMap
+
+                if (!isUpdate) {
+                    val rank = sortedMedia.values.indexOf(newCommonModel)
+                    if (isSmartspaceLoggingEnabled(newCommonModel, rank)) {
+                        smartspaceLogger.logSmartspaceCardReceived(
+                            it.smartspaceId,
+                            it.appUid,
+                            cardinality = _currentMedia.value.size,
+                            isSsReactivated = mediaDataLoadingModel.isSsReactivated,
+                            rank = rank,
+                        )
+                    }
+                } else if (mediaDataLoadingModel.receivedSmartspaceCardLatency != 0) {
+                    logSmartspaceAllMediaCards(mediaDataLoadingModel.receivedSmartspaceCardLatency)
                 }
             }
         }
 
-        sortedMedia = sortedMap
-
         // On removal we want to keep the order being shown to user.
         if (mediaDataLoadingModel is MediaDataLoadingModel.Removed) {
             _currentMedia.value =
@@ -249,6 +281,7 @@
                     commonModel !is MediaCommonModel.MediaControl ||
                         mediaDataLoadingModel.instanceId != commonModel.mediaLoadedModel.instanceId
                 }
+            sortedMedia = sortedMap
         }
     }
 
@@ -271,21 +304,45 @@
                 isPlaying = false,
                 active = _smartspaceMediaData.value.isActive,
             )
+        val newCommonModel = MediaCommonModel.MediaRecommendations(smartspaceMediaLoadingModel)
         when (smartspaceMediaLoadingModel) {
-            is SmartspaceMediaLoadingModel.Loaded ->
-                sortedMap[sortKey] =
-                    MediaCommonModel.MediaRecommendations(smartspaceMediaLoadingModel)
-            is SmartspaceMediaLoadingModel.Removed ->
+            is SmartspaceMediaLoadingModel.Loaded -> {
+                sortedMap[sortKey] = newCommonModel
+                _currentMedia.value = sortedMap.values.toList()
+                sortedMedia = sortedMap
+
+                if (isRecommendationActive()) {
+                    val hasActivatedExistedResumeMedia =
+                        !hasActiveMedia() &&
+                            hasAnyMedia() &&
+                            smartspaceMediaLoadingModel.isPrioritized
+                    if (hasActivatedExistedResumeMedia) {
+                        // Log resume card received if resumable media card is reactivated and
+                        // recommendation card is valid and ranked first
+                        logSmartspaceAllMediaCards(
+                            (systemClock.currentTimeMillis() -
+                                    _smartspaceMediaData.value.headphoneConnectionTimeMillis)
+                                .toInt()
+                        )
+                    }
+
+                    smartspaceLogger.logSmartspaceCardReceived(
+                        SmallHash.hash(_smartspaceMediaData.value.targetId),
+                        _smartspaceMediaData.value.getUid(applicationContext),
+                        cardinality = _currentMedia.value.size,
+                        isRecommendationCard = true,
+                        rank = _currentMedia.value.indexOf(newCommonModel),
+                    )
+                }
+            }
+            is SmartspaceMediaLoadingModel.Removed -> {
                 _currentMedia.value =
                     _currentMedia.value.filter { commonModel ->
                         commonModel !is MediaCommonModel.MediaRecommendations
                     }
+                sortedMedia = sortedMap
+            }
         }
-
-        if (sortedMap.size > sortedMedia.size) {
-            _currentMedia.value = sortedMap.values.toList()
-        }
-        sortedMedia = sortedMap
     }
 
     fun setOrderedMedia() {
@@ -304,10 +361,118 @@
         return _selectedUserEntries.value.entries.isNotEmpty()
     }
 
+    fun hasActiveMediaOrRecommendation(): Boolean {
+        return _selectedUserEntries.value.any { it.value.active } ||
+            (isRecommendationActive() &&
+                (_smartspaceMediaData.value.isValid() || _reactivatedId.value != null))
+    }
+
     fun isRecommendationActive(): Boolean {
         return _smartspaceMediaData.value.isActive
     }
 
+    /** Log visible card given [visibleIndex]. */
+    fun logSmartspaceCardSeen(surface: Int, visibleIndex: Int, isMediaCardUpdate: Boolean) {
+        if (_currentMedia.value.size <= visibleIndex) return
+
+        when (val mediaCommonModel = _currentMedia.value[visibleIndex]) {
+            is MediaCommonModel.MediaControl -> {
+                if (
+                    !isMediaCardUpdate ||
+                        mediaCommonModel.mediaLoadedModel.receivedSmartspaceCardLatency != 0
+                ) {
+                    logSmartspaceMediaCardUserEvent(
+                        mediaCommonModel.mediaLoadedModel.instanceId,
+                        visibleIndex,
+                        SMARTSPACE_CARD_SEEN_EVENT,
+                        surface,
+                        mediaCommonModel.mediaLoadedModel.isSsReactivated,
+                    )
+                }
+            }
+            is MediaCommonModel.MediaRecommendations -> {
+                if (isRecommendationActive()) {
+                    logSmarspaceRecommendationCardUserEvent(
+                        SMARTSPACE_CARD_SEEN_EVENT,
+                        surface,
+                        visibleIndex
+                    )
+                }
+            }
+        }
+    }
+
+    /** Log user event on media card if smartspace logging is enabled. */
+    fun logSmartspaceCardUserEvent(
+        eventId: Int,
+        surface: Int,
+        interactedSubCardRank: Int = 0,
+        interactedSubCardCardinality: Int = 0,
+        instanceId: InstanceId? = null,
+        isRec: Boolean = false
+    ) {
+        _currentMedia.value.forEachIndexed { index, mediaCommonModel ->
+            when (mediaCommonModel) {
+                is MediaCommonModel.MediaControl -> {
+                    if (mediaCommonModel.mediaLoadedModel.instanceId == instanceId) {
+                        if (isSmartspaceLoggingEnabled(mediaCommonModel, index)) {
+                            logSmartspaceMediaCardUserEvent(
+                                instanceId,
+                                index,
+                                eventId,
+                                surface,
+                                mediaCommonModel.mediaLoadedModel.isSsReactivated,
+                                interactedSubCardRank,
+                                interactedSubCardCardinality
+                            )
+                        }
+                        return
+                    }
+                }
+                is MediaCommonModel.MediaRecommendations -> {
+                    if (isRec) {
+                        if (isSmartspaceLoggingEnabled(mediaCommonModel, index)) {
+                            logSmarspaceRecommendationCardUserEvent(
+                                eventId,
+                                surface,
+                                index,
+                                interactedSubCardRank,
+                                interactedSubCardCardinality
+                            )
+                        }
+                        return
+                    }
+                }
+            }
+        }
+    }
+
+    /** Log media and recommendation cards dismissal if smartspace logging is enabled for each. */
+    fun logSmartspaceCardsOnSwipeToDismiss(surface: Int) {
+        _currentMedia.value.forEachIndexed { index, mediaCommonModel ->
+            if (isSmartspaceLoggingEnabled(mediaCommonModel, index)) {
+                when (mediaCommonModel) {
+                    is MediaCommonModel.MediaControl ->
+                        logSmartspaceMediaCardUserEvent(
+                            mediaCommonModel.mediaLoadedModel.instanceId,
+                            index,
+                            SMARTSPACE_CARD_DISMISS_EVENT,
+                            surface,
+                            mediaCommonModel.mediaLoadedModel.isSsReactivated,
+                            isSwipeToDismiss = true
+                        )
+                    is MediaCommonModel.MediaRecommendations ->
+                        logSmarspaceRecommendationCardUserEvent(
+                            SMARTSPACE_CARD_DISMISS_EVENT,
+                            surface,
+                            index,
+                            isSwipeToDismiss = true
+                        )
+                }
+            }
+        }
+    }
+
     private fun canBeRemoved(data: MediaData): Boolean {
         return data.isPlaying?.let { !it } ?: data.isClearable && !data.active
     }
@@ -315,4 +480,83 @@
     private fun isMediaFromRec(data: MediaData): Boolean {
         return data.isPlaying == true && mediaFromRecPackageName == data.packageName
     }
+
+    /** Log all media cards if smartspace logging is enabled for each. */
+    private fun logSmartspaceAllMediaCards(receivedSmartspaceCardLatency: Int) {
+        sortedMedia.values.forEachIndexed { index, mediaCommonModel ->
+            if (mediaCommonModel is MediaCommonModel.MediaControl) {
+                _selectedUserEntries.value[mediaCommonModel.mediaLoadedModel.instanceId]?.let {
+                    it.smartspaceId =
+                        SmallHash.hash(it.appUid + systemClock.currentTimeMillis().toInt())
+                    it.isImpressed = false
+
+                    if (isSmartspaceLoggingEnabled(mediaCommonModel, index)) {
+                        smartspaceLogger.logSmartspaceCardReceived(
+                            it.smartspaceId,
+                            it.appUid,
+                            cardinality = _currentMedia.value.size,
+                            isSsReactivated = mediaCommonModel.mediaLoadedModel.isSsReactivated,
+                            rank = index,
+                            receivedLatencyMillis = receivedSmartspaceCardLatency,
+                        )
+                    }
+                }
+            }
+        }
+    }
+
+    private fun logSmartspaceMediaCardUserEvent(
+        instanceId: InstanceId,
+        index: Int,
+        eventId: Int,
+        surface: Int,
+        isReactivated: Boolean,
+        interactedSubCardRank: Int = 0,
+        interactedSubCardCardinality: Int = 0,
+        isSwipeToDismiss: Boolean = false
+    ) {
+        _selectedUserEntries.value[instanceId]?.let {
+            smartspaceLogger.logSmartspaceCardUIEvent(
+                eventId,
+                it.smartspaceId,
+                it.appUid,
+                surface,
+                _currentMedia.value.size,
+                isSsReactivated = isReactivated,
+                interactedSubcardRank = interactedSubCardRank,
+                interactedSubcardCardinality = interactedSubCardCardinality,
+                rank = index,
+                isSwipeToDismiss = isSwipeToDismiss,
+            )
+        }
+    }
+
+    private fun logSmarspaceRecommendationCardUserEvent(
+        eventId: Int,
+        surface: Int,
+        index: Int,
+        interactedSubCardRank: Int = 0,
+        interactedSubCardCardinality: Int = 0,
+        isSwipeToDismiss: Boolean = false
+    ) {
+        smartspaceLogger.logSmartspaceCardUIEvent(
+            eventId,
+            SmallHash.hash(_smartspaceMediaData.value.targetId),
+            _smartspaceMediaData.value.getUid(applicationContext),
+            surface,
+            _currentMedia.value.size,
+            isRecommendationCard = true,
+            interactedSubcardRank = interactedSubCardRank,
+            interactedSubcardCardinality = interactedSubCardCardinality,
+            rank = index,
+            isSwipeToDismiss = isSwipeToDismiss,
+        )
+    }
+
+    private fun isSmartspaceLoggingEnabled(commonModel: MediaCommonModel, index: Int): Boolean {
+        return sortedMedia.size > index &&
+            (_smartspaceMediaData.value.expiryTimeMs != 0L ||
+                isRecommendationActive() ||
+                commonModel is MediaCommonModel.MediaRecommendations)
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt
index f78a0f9..68f1af3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt
@@ -27,6 +27,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.media.controls.data.repository.MediaFilterRepository
+import com.android.systemui.media.controls.shared.MediaLogger
 import com.android.systemui.media.controls.shared.model.EXTRA_KEY_TRIGGER_RESUME
 import com.android.systemui.media.controls.shared.model.MediaData
 import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
@@ -70,7 +71,7 @@
     private val logger: MediaUiEventLogger,
     private val mediaFlags: MediaFlags,
     private val mediaFilterRepository: MediaFilterRepository,
-    private val mediaLoadingLogger: MediaLoadingLogger,
+    private val mediaLogger: MediaLogger,
 ) : MediaDataManager.Listener {
     /** Non-UI listeners to media changes. */
     private val _listeners: MutableSet<MediaDataProcessor.Listener> = mutableSetOf()
@@ -116,11 +117,12 @@
             return
         }
 
-        mediaFilterRepository.addSelectedUserMediaEntry(data)
+        val isUpdate = mediaFilterRepository.addSelectedUserMediaEntry(data)
 
-        mediaLoadingLogger.logMediaLoaded(data.instanceId, data.active, "loading media")
+        mediaLogger.logMediaLoaded(data.instanceId, data.active, "loading media")
         mediaFilterRepository.addMediaDataLoadingState(
-            MediaDataLoadingModel.Loaded(data.instanceId)
+            MediaDataLoadingModel.Loaded(data.instanceId),
+            isUpdate
         )
 
         // Notify listeners
@@ -180,9 +182,15 @@
                     mediaData.instanceId
                 )
                 mediaFilterRepository.addMediaDataLoadingState(
-                    MediaDataLoadingModel.Loaded(lastActiveId)
+                    MediaDataLoadingModel.Loaded(
+                        lastActiveId,
+                        receivedSmartspaceCardLatency =
+                            (systemClock.currentTimeMillis() - data.headphoneConnectionTimeMillis)
+                                .toInt(),
+                        isSsReactivated = true
+                    )
                 )
-                mediaLoadingLogger.logMediaLoaded(
+                mediaLogger.logMediaLoaded(
                     mediaData.instanceId,
                     mediaData.active,
                     "reactivating media instead of smartspace"
@@ -219,7 +227,7 @@
         mediaFilterRepository.setRecommendationsLoadingState(
             SmartspaceMediaLoadingModel.Loaded(key, shouldPrioritizeMutable)
         )
-        mediaLoadingLogger.logRecommendationLoaded(key, data.isActive, "loading recommendations")
+        mediaLogger.logRecommendationLoaded(key, data.isActive, "loading recommendations")
         listeners.forEach { it.onSmartspaceMediaDataLoaded(key, data, shouldPrioritizeMutable) }
     }
 
@@ -230,7 +238,7 @@
                 mediaFilterRepository.addMediaDataLoadingState(
                     MediaDataLoadingModel.Removed(instanceId)
                 )
-                mediaLoadingLogger.logMediaRemoved(instanceId, "removing media card")
+                mediaLogger.logMediaRemoved(instanceId, "removing media card")
                 // Only notify listeners if something actually changed
                 listeners.forEach { it.onMediaDataRemoved(key, userInitiated) }
             }
@@ -246,11 +254,7 @@
                 mediaFilterRepository.addMediaDataLoadingState(
                     MediaDataLoadingModel.Loaded(lastActiveId, immediately)
                 )
-                mediaLoadingLogger.logMediaLoaded(
-                    lastActiveId,
-                    it.active,
-                    "expiring reactivated id"
-                )
+                mediaLogger.logMediaLoaded(lastActiveId, it.active, "expiring reactivated id")
                 listeners.forEach { listener ->
                     getKey(lastActiveId)?.let { lastActiveKey ->
                         listener.onMediaDataLoaded(lastActiveKey, lastActiveKey, it, immediately)
@@ -271,11 +275,7 @@
         mediaFilterRepository.setRecommendationsLoadingState(
             SmartspaceMediaLoadingModel.Removed(key, immediately)
         )
-        mediaLoadingLogger.logRecommendationRemoved(
-            key,
-            immediately,
-            "removing recommendations card"
-        )
+        mediaLogger.logRecommendationRemoved(key, immediately, "removing recommendations card")
         listeners.forEach { it.onSmartspaceMediaDataRemoved(key, immediately) }
     }
 
@@ -289,10 +289,7 @@
                 mediaFilterRepository.addMediaDataLoadingState(
                     MediaDataLoadingModel.Removed(data.instanceId)
                 )
-                mediaLoadingLogger.logMediaRemoved(
-                    data.instanceId,
-                    "Removing $key after profile change"
-                )
+                mediaLogger.logMediaRemoved(data.instanceId, "Removing $key after profile change")
                 listeners.forEach { listener -> listener.onMediaDataRemoved(key, false) }
             }
         }
@@ -309,7 +306,7 @@
             mediaFilterRepository.addMediaDataLoadingState(
                 MediaDataLoadingModel.Removed(instanceId)
             )
-            mediaLoadingLogger.logMediaRemoved(instanceId, "Removing media after user change")
+            mediaLogger.logMediaRemoved(instanceId, "Removing media after user change")
             getKey(instanceId)?.let {
                 listenersCopy.forEach { listener -> listener.onMediaDataRemoved(it, false) }
             }
@@ -317,11 +314,12 @@
 
         mediaFilterRepository.allUserEntries.value.forEach { (key, data) ->
             if (lockscreenUserManager.isCurrentProfile(data.userId)) {
-                mediaFilterRepository.addSelectedUserMediaEntry(data)
+                val isUpdate = mediaFilterRepository.addSelectedUserMediaEntry(data)
                 mediaFilterRepository.addMediaDataLoadingState(
-                    MediaDataLoadingModel.Loaded(data.instanceId)
+                    MediaDataLoadingModel.Loaded(data.instanceId),
+                    isUpdate
                 )
-                mediaLoadingLogger.logMediaLoaded(
+                mediaLogger.logMediaLoaded(
                     data.instanceId,
                     data.active,
                     "Re-adding $key after user change"
@@ -332,8 +330,9 @@
     }
 
     /** Invoked when the user has dismissed the media carousel */
-    fun onSwipeToDismiss() {
+    fun onSwipeToDismiss(surface: Int) {
         if (DEBUG) Log.d(TAG, "Media carousel swiped away")
+        mediaFilterRepository.logSmartspaceCardsOnSwipeToDismiss(surface)
         val mediaEntries = mediaFilterRepository.allUserEntries.value.entries
         mediaEntries.forEach { (key, data) ->
             if (mediaFilterRepository.selectedUserEntries.value.containsKey(data.instanceId)) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessor.kt
index 37dffd1..adcfba7 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessor.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataProcessor.kt
@@ -86,6 +86,7 @@
 import com.android.systemui.media.controls.util.MediaDataUtils
 import com.android.systemui.media.controls.util.MediaFlags
 import com.android.systemui.media.controls.util.MediaUiEventLogger
+import com.android.systemui.media.controls.util.SmallHash
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.BcSmartspaceDataPlugin
 import com.android.systemui.res.R
@@ -721,6 +722,7 @@
                     appUid = appUid,
                     isExplicit = isExplicit,
                     resumeProgress = progress,
+                    smartspaceId = SmallHash.hash(appUid + systemClock.currentTimeMillis().toInt()),
                 )
             )
         }
@@ -902,6 +904,7 @@
                     instanceId = instanceId,
                     appUid = appUid,
                     isExplicit = isExplicit,
+                    smartspaceId = SmallHash.hash(appUid + systemClock.currentTimeMillis().toInt()),
                 )
             )
         }
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceManager.kt
index 8b2f619..eab0d48 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDeviceManager.kt
@@ -354,10 +354,21 @@
 
                     activeDevice =
                         routingSession?.let {
+                            val icon = if (it.selectedRoutes.size > 1) {
+                                context.getDrawable(
+                                        com.android.settingslib.R.drawable.ic_media_group_device)
+                            } else {
+                                connectedDevice?.icon // Single route. We don't change the icon.
+                            }
                             // For a remote session, always use the current device from
-                            // LocalMediaManager. Override with routing session name if available to
-                            // show dynamic group name.
-                            connectedDevice?.copy(name = it.name ?: connectedDevice.name)
+                            // LocalMediaManager. Override with routing session information if
+                            // available:
+                            //   - Name: To show the dynamic group name.
+                            //   - Icon: To show the group icon if there's more than one selected
+                            //           route.
+                            connectedDevice?.copy(
+                                    name = it.name ?: connectedDevice.name,
+                                    icon = icon)
                         } ?: MediaDeviceData(
                             enabled = false,
                             icon = context.getDrawable(R.drawable.ic_media_home_devices),
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaLoadingLogger.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaLoadingLogger.kt
deleted file mode 100644
index c6cfd65..0000000
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaLoadingLogger.kt
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.controls.domain.pipeline
-
-import com.android.internal.logging.InstanceId
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.log.LogBuffer
-import com.android.systemui.log.core.LogLevel
-import com.android.systemui.log.dagger.MediaLoadingLog
-import javax.inject.Inject
-
-/** A buffered log for media loading events. */
-@SysUISingleton
-class MediaLoadingLogger @Inject constructor(@MediaLoadingLog private val buffer: LogBuffer) {
-
-    fun logMediaLoaded(instanceId: InstanceId, active: Boolean, reason: String) {
-        buffer.log(
-            TAG,
-            LogLevel.DEBUG,
-            {
-                str1 = instanceId.toString()
-                bool1 = active
-                str2 = reason
-            },
-            { "add media $str1, active: $bool1, reason: $str2" }
-        )
-    }
-
-    fun logMediaRemoved(instanceId: InstanceId, reason: String) {
-        buffer.log(
-            TAG,
-            LogLevel.DEBUG,
-            {
-                str1 = instanceId.toString()
-                str2 = reason
-            },
-            { "removing media $str1, reason: $str2" }
-        )
-    }
-
-    fun logRecommendationLoaded(key: String, isActive: Boolean, reason: String) {
-        buffer.log(
-            TAG,
-            LogLevel.DEBUG,
-            {
-                str1 = key
-                bool1 = isActive
-                str2 = reason
-            },
-            { "add recommendation $str1, active $bool1, reason: $str2" }
-        )
-    }
-
-    fun logRecommendationRemoved(key: String, immediately: Boolean, reason: String) {
-        buffer.log(
-            TAG,
-            LogLevel.DEBUG,
-            {
-                str1 = key
-                bool1 = immediately
-                str2 = reason
-            },
-            { "removing recommendation $str1, immediate=$bool1, reason: $str2" }
-        )
-    }
-
-    companion object {
-        private const val TAG = "MediaLoadingLog"
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt
index 0630cbd..9d7160c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt
@@ -36,6 +36,7 @@
 import com.android.systemui.media.controls.domain.resume.MediaResumeListener
 import com.android.systemui.media.controls.shared.model.MediaCommonModel
 import com.android.systemui.media.controls.util.MediaFlags
+import com.android.systemui.media.controls.util.MediaSmartspaceLogger
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import java.io.PrintWriter
 import javax.inject.Inject
@@ -204,11 +205,14 @@
         mediaDataProcessor.setMediaResumptionEnabled(isEnabled)
     }
 
-    override fun onSwipeToDismiss() {
-        mediaDataFilter.onSwipeToDismiss()
+    override fun onSwipeToDismiss() = unsupported
+
+    fun onSwipeToDismiss(location: Int) {
+        mediaDataFilter.onSwipeToDismiss(MediaSmartspaceLogger.getSurface(location))
     }
 
-    override fun hasActiveMediaOrRecommendation() = hasActiveMediaOrRecommendation.value
+    override fun hasActiveMediaOrRecommendation() =
+        mediaFilterRepository.hasActiveMediaOrRecommendation()
 
     override fun hasAnyMediaOrRecommendation() = hasAnyMediaOrRecommendation.value
 
@@ -222,6 +226,14 @@
         mediaFilterRepository.setOrderedMedia()
     }
 
+    fun logSmartspaceSeenCard(visibleIndex: Int, location: Int, isMediaCardUpdate: Boolean) {
+        mediaFilterRepository.logSmartspaceCardSeen(
+            MediaSmartspaceLogger.getSurface(location),
+            visibleIndex,
+            isMediaCardUpdate
+        )
+    }
+
     /** Add a listener for internal events. */
     private fun addInternalListener(listener: MediaDataManager.Listener) =
         mediaDataProcessor.addInternalListener(listener)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractor.kt
index 3f75938..245f6f8 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractor.kt
@@ -19,7 +19,6 @@
 import android.app.ActivityOptions
 import android.app.BroadcastOptions
 import android.app.PendingIntent
-import android.content.Context
 import android.content.Intent
 import android.media.session.MediaSession
 import android.provider.Settings
@@ -31,11 +30,11 @@
 import com.android.systemui.animation.DialogTransitionAnimator
 import com.android.systemui.animation.Expandable
 import com.android.systemui.bluetooth.BroadcastDialogController
-import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.media.controls.data.repository.MediaFilterRepository
 import com.android.systemui.media.controls.domain.pipeline.MediaDataProcessor
 import com.android.systemui.media.controls.shared.model.MediaControlModel
 import com.android.systemui.media.controls.shared.model.MediaData
+import com.android.systemui.media.controls.util.MediaSmartspaceLogger
 import com.android.systemui.media.dialog.MediaOutputDialogManager
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.statusbar.NotificationLockscreenUserManager
@@ -50,9 +49,8 @@
 class MediaControlInteractor
 @AssistedInject
 constructor(
-    @Application applicationContext: Context,
     @Assisted private val instanceId: InstanceId,
-    repository: MediaFilterRepository,
+    private val repository: MediaFilterRepository,
     private val mediaDataProcessor: MediaDataProcessor,
     private val keyguardStateController: KeyguardStateController,
     private val activityStarter: ActivityStarter,
@@ -72,8 +70,11 @@
     fun removeMediaControl(
         token: MediaSession.Token?,
         instanceId: InstanceId,
-        delayMs: Long
+        delayMs: Long,
+        eventId: Int,
+        location: Int
     ): Boolean {
+        logSmartspaceUserEvent(eventId, location)
         val dismissed =
             mediaDataProcessor.dismissMediaData(instanceId, delayMs, userInitiated = true)
         if (!dismissed) {
@@ -114,7 +115,13 @@
         activityStarter.startActivity(SETTINGS_INTENT, /* dismissShade= */ true)
     }
 
-    fun startClickIntent(expandable: Expandable, clickIntent: PendingIntent) {
+    fun startClickIntent(
+        expandable: Expandable,
+        clickIntent: PendingIntent,
+        eventId: Int,
+        location: Int
+    ) {
+        logSmartspaceUserEvent(eventId, location)
         if (!launchOverLockscreen(clickIntent)) {
             activityStarter.postStartActivityDismissingKeyguard(
                 clickIntent,
@@ -176,6 +183,14 @@
         )
     }
 
+    fun logSmartspaceUserEvent(eventId: Int, location: Int) {
+        repository.logSmartspaceCardUserEvent(
+            eventId,
+            MediaSmartspaceLogger.getSurface(location),
+            instanceId = instanceId
+        )
+    }
+
     private fun Expandable.dialogController(): DialogTransitionAnimator.Controller? {
         return dialogTransitionController(
             cuj =
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractor.kt
index dd6b264..c3a36b2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractor.kt
@@ -31,6 +31,7 @@
 import com.android.systemui.media.controls.shared.model.MediaRecModel
 import com.android.systemui.media.controls.shared.model.MediaRecommendationsModel
 import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
+import com.android.systemui.media.controls.util.MediaSmartspaceLogger
 import com.android.systemui.plugins.ActivityStarter
 import java.net.URISyntaxException
 import javax.inject.Inject
@@ -67,7 +68,14 @@
 
     val onAnyMediaConfigurationChange: Flow<Unit> = repository.onAnyMediaConfigurationChange
 
-    fun removeMediaRecommendations(key: String, dismissIntent: Intent?, delayMs: Long) {
+    fun removeMediaRecommendations(
+        key: String,
+        dismissIntent: Intent?,
+        delayMs: Long,
+        eventId: Int,
+        location: Int
+    ) {
+        logSmartspaceCardUserEvent(eventId, location)
         mediaDataProcessor.dismissSmartspaceRecommendation(key, delayMs)
         if (dismissIntent == null) {
             Log.w(TAG, "Cannot create dismiss action click action: extras missing dismiss_intent.")
@@ -87,7 +95,25 @@
         activityStarter.startActivity(SETTINGS_INTENT, /* dismissShade= */ true)
     }
 
-    fun startClickIntent(expandable: Expandable, intent: Intent) {
+    fun startClickIntent(
+        expandable: Expandable,
+        intent: Intent,
+        eventId: Int,
+        location: Int,
+        interactedSubCardRank: Int,
+        interactedSubCardCardinality: Int
+    ) {
+        if (interactedSubCardRank == -1) {
+            logSmartspaceCardUserEvent(eventId, MediaSmartspaceLogger.getSurface(location))
+        } else {
+            repository.logSmartspaceCardUserEvent(
+                eventId,
+                MediaSmartspaceLogger.getSurface(location),
+                interactedSubCardRank = interactedSubCardRank,
+                interactedSubCardCardinality = interactedSubCardCardinality,
+                isRec = true
+            )
+        }
         if (shouldActivityOpenInForeground(intent)) {
             // Request to unlock the device if the activity needs to be opened in foreground.
             activityStarter.postStartActivityDismissingKeyguard(
@@ -103,6 +129,14 @@
         }
     }
 
+    private fun logSmartspaceCardUserEvent(eventId: Int, location: Int) {
+        repository.logSmartspaceCardUserEvent(
+            eventId,
+            MediaSmartspaceLogger.getSurface(location),
+            isRec = true
+        )
+    }
+
     /** Returns if the action will open the activity in foreground. */
     private fun shouldActivityOpenInForeground(intent: Intent): Boolean {
         val intentString = intent.extras?.getString(EXTRAS_SMARTSPACE_INTENT) ?: return false
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/shared/MediaLogger.kt b/packages/SystemUI/src/com/android/systemui/media/controls/shared/MediaLogger.kt
new file mode 100644
index 0000000..2b710b5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/shared/MediaLogger.kt
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.controls.shared
+
+import com.android.internal.logging.InstanceId
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.log.dagger.MediaLog
+import javax.inject.Inject
+
+/** A buffered log for media loading events. */
+@SysUISingleton
+class MediaLogger @Inject constructor(@MediaLog private val buffer: LogBuffer) {
+
+    fun logMediaLoaded(instanceId: InstanceId, active: Boolean, reason: String) {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = instanceId.toString()
+                bool1 = active
+                str2 = reason
+            },
+            { "add media $str1, active: $bool1, reason: $str2" }
+        )
+    }
+
+    fun logMediaRemoved(instanceId: InstanceId, reason: String) {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = instanceId.toString()
+                str2 = reason
+            },
+            { "removing media $str1, reason: $str2" }
+        )
+    }
+
+    fun logRecommendationLoaded(key: String, isActive: Boolean, reason: String) {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = key
+                bool1 = isActive
+                str2 = reason
+            },
+            { "add recommendation $str1, active $bool1, reason: $str2" }
+        )
+    }
+
+    fun logRecommendationRemoved(key: String, immediately: Boolean, reason: String) {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = key
+                bool1 = immediately
+                str2 = reason
+            },
+            { "removing recommendation $str1, immediate=$bool1, reason: $str2" }
+        )
+    }
+
+    fun logMediaCardAdded(instanceId: InstanceId) {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            { str1 = instanceId.toString() },
+            { "adding media card $str1 to carousel" }
+        )
+    }
+
+    fun logMediaCardRemoved(instanceId: InstanceId) {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            { str1 = instanceId.toString() },
+            { "removing media card $str1 from carousel" }
+        )
+    }
+
+    fun logMediaRecommendationCardAdded(key: String) {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            { str1 = key },
+            { "adding recommendation card $str1 to carousel" }
+        )
+    }
+
+    fun logMediaRecommendationCardRemoved(key: String) {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            { str1 = key },
+            { "removing recommendation card $str1 from carousel" }
+        )
+    }
+
+    companion object {
+        private const val TAG = "MediaLog"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaCommonModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaCommonModel.kt
index 56cc618..3d5d47b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaCommonModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaCommonModel.kt
@@ -22,6 +22,7 @@
         val mediaLoadedModel: MediaDataLoadingModel.Loaded,
         val canBeRemoved: Boolean = false,
         val isMediaFromRec: Boolean = false,
+        val updateTime: Long = 0L,
     ) : MediaCommonModel()
 
     data class MediaRecommendations(val recsLoadingModel: SmartspaceMediaLoadingModel) :
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaData.kt
index 11a5629..40b3477 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaData.kt
@@ -99,6 +99,12 @@
 
     /** Track progress (0 - 1) to display for players where [resumption] is true */
     val resumeProgress: Double? = null,
+
+    /** Smartspace Id, used for logging. */
+    var smartspaceId: Int = -1,
+
+    /** If media card was visible to user, used for logging. */
+    var isImpressed: Boolean = false,
 ) {
     companion object {
         /** Media is playing on the local device */
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaDataLoadingModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaDataLoadingModel.kt
index 170f1f7..c8a02fa 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaDataLoadingModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaDataLoadingModel.kt
@@ -27,6 +27,8 @@
     data class Loaded(
         override val instanceId: InstanceId,
         val immediatelyUpdateUi: Boolean = true,
+        val receivedSmartspaceCardLatency: Int = 0,
+        val isSsReactivated: Boolean = false,
     ) : MediaDataLoadingModel()
 
     /** Media data has been removed. */
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/SmartspaceMediaData.kt b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/SmartspaceMediaData.kt
index 9e15dbb..96c3fa8 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/SmartspaceMediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/SmartspaceMediaData.kt
@@ -48,6 +48,8 @@
     val instanceId: InstanceId? = null,
     /** The timestamp in milliseconds indicating when the card should be removed */
     val expiryTimeMs: Long = 0L,
+    /** If recommendation card was visible to user, used for logging. */
+    var isImpressed: Boolean = false,
 ) {
     /**
      * Indicates if all the data is valid.
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
index 72fb218..62759a4 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
@@ -109,6 +109,10 @@
         mainDispatcher: CoroutineDispatcher,
         mediaFlags: MediaFlags,
     ) {
+        // Set up media control location and its listener.
+        viewModel.onLocationChanged(viewController.currentEndLocation)
+        viewController.locationChangeListener = viewModel.onLocationChanged
+
         with(viewHolder) {
             // AlbumView uses a hardware layer so that clipping of the foreground is handled with
             // clipping the album art. Otherwise album art shows through at the edges.
@@ -221,7 +225,7 @@
             dismiss.isEnabled = model.isDismissEnabled
             dismiss.setOnClickListener {
                 if (!falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
-                    model.onDismissClicked.invoke()
+                    model.onDismissClicked()
                 }
             }
             cancelText.background = model.cancelTextBackground
@@ -349,7 +353,7 @@
         if (actionViewModel.isEnabled) {
             button.setOnClickListener {
                 if (!falsingManager.isFalseTap(FalsingManager.MODERATE_PENALTY)) {
-                    actionViewModel.onClicked.invoke(it.id)
+                    actionViewModel.onClicked(it.id)
 
                     viewController.multiRippleController.play(
                         createTouchRippleAnimation(
@@ -469,8 +473,7 @@
                         transitionDrawable.startTransition(
                             if (viewModel.shouldAddGradient) 333 else 80
                         )
-                    }
-                        ?: albumView.setImageDrawable(artwork)
+                    } ?: albumView.setImageDrawable(artwork)
                 }
                 viewController.isArtworkBound = viewModel.shouldAddGradient
                 viewController.prevArtwork = artwork
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt
index bd4d435..5e8a879 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt
@@ -71,14 +71,18 @@
     fun bindRecsCard(
         viewHolder: RecommendationViewHolder,
         viewModel: MediaRecsCardViewModel,
-        mediaViewController: MediaViewController,
+        viewController: MediaViewController,
         falsingManager: FalsingManager,
     ) {
+        // Set up media control location and its listener.
+        viewModel.onLocationChanged(viewController.currentEndLocation)
+        viewController.locationChangeListener = viewModel.onLocationChanged
+
         // Bind main card.
         viewHolder.cardTitle.setTextColor(viewModel.cardTitleColor)
         viewHolder.recommendations.backgroundTintList = ColorStateList.valueOf(viewModel.cardColor)
         viewHolder.recommendations.contentDescription =
-            viewModel.contentDescription.invoke(mediaViewController.isGutsVisible)
+            viewModel.contentDescription.invoke(viewController.isGutsVisible)
 
         viewHolder.recommendations.setOnClickListener {
             if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return@setOnClickListener
@@ -88,21 +92,21 @@
         viewHolder.recommendations.setOnLongClickListener {
             if (falsingManager.isFalseLongTap(FalsingManager.LOW_PENALTY))
                 return@setOnLongClickListener true
-            if (!mediaViewController.isGutsVisible) {
-                openGuts(viewHolder, viewModel, mediaViewController)
+            if (!viewController.isGutsVisible) {
+                openGuts(viewHolder, viewModel, viewController)
             } else {
-                closeGuts(viewHolder, viewModel, mediaViewController)
+                closeGuts(viewHolder, viewModel, viewController)
             }
             return@setOnLongClickListener true
         }
 
         // Bind all recommendations.
         bindRecommendationsList(viewHolder, viewModel.mediaRecs, falsingManager)
-        updateRecommendationsVisibility(mediaViewController, viewHolder.recommendations)
+        updateRecommendationsVisibility(viewController, viewHolder.recommendations)
 
         // Set visibility of recommendations.
-        val expandedSet: ConstraintSet = mediaViewController.expandedLayout
-        val collapsedSet: ConstraintSet = mediaViewController.collapsedLayout
+        val expandedSet: ConstraintSet = viewController.expandedLayout
+        val collapsedSet: ConstraintSet = viewController.collapsedLayout
         viewHolder.mediaTitles.forEach {
             setVisibleAndAlpha(expandedSet, it.id, viewModel.areTitlesVisible)
             setVisibleAndAlpha(collapsedSet, it.id, viewModel.areTitlesVisible)
@@ -112,15 +116,15 @@
             setVisibleAndAlpha(collapsedSet, it.id, viewModel.areSubtitlesVisible)
         }
 
-        bindRecommendationsGuts(viewHolder, viewModel, mediaViewController, falsingManager)
+        bindRecommendationsGuts(viewHolder, viewModel, viewController, falsingManager)
 
-        mediaViewController.refreshState()
+        viewController.refreshState()
     }
 
     private fun bindRecommendationsGuts(
         viewHolder: RecommendationViewHolder,
         viewModel: MediaRecsCardViewModel,
-        mediaViewController: MediaViewController,
+        viewController: MediaViewController,
         falsingManager: FalsingManager,
     ) {
         val gutsViewHolder = viewHolder.gutsViewHolder
@@ -131,14 +135,14 @@
         gutsViewHolder.dismiss.isEnabled = true
         gutsViewHolder.dismiss.setOnClickListener {
             if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return@setOnClickListener
-            closeGuts(viewHolder, viewModel, mediaViewController)
-            gutsViewModel.onDismissClicked.invoke()
+            closeGuts(viewHolder, viewModel, viewController)
+            gutsViewModel.onDismissClicked()
         }
 
         gutsViewHolder.cancelText.background = gutsViewModel.cancelTextBackground
         gutsViewHolder.cancel.setOnClickListener {
             if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
-                closeGuts(viewHolder, viewModel, mediaViewController)
+                closeGuts(viewHolder, viewModel, viewController)
             }
         }
 
@@ -173,7 +177,7 @@
             val mediaCoverContainer = viewHolder.mediaCoverContainers[index]
             mediaCoverContainer.setOnClickListener {
                 if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return@setOnClickListener
-                mediaRecViewModel.onClicked.invoke(Expandable.fromView(it), index)
+                mediaRecViewModel.onClicked(Expandable.fromView(it), index)
             }
             mediaCoverContainer.setOnLongClickListener {
                 if (falsingManager.isFalseLongTap(FalsingManager.LOW_PENALTY))
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
index 53794d2..48970f5 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
@@ -42,6 +42,7 @@
 import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.systemui.Dumpable
 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 com.android.systemui.dump.DumpManager
@@ -106,6 +107,7 @@
 import kotlinx.coroutines.flow.collectLatest
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.launch
@@ -123,6 +125,7 @@
 class MediaCarouselController
 @Inject
 constructor(
+    @Application applicationScope: CoroutineScope,
     private val context: Context,
     private val mediaControlPanelFactory: Provider<MediaControlPanel>,
     private val visualStabilityProvider: VisualStabilityProvider,
@@ -387,18 +390,18 @@
             repeatOnLifecycle(Lifecycle.State.STARTED) {
                 listenForAnyStateToGoneKeyguardTransition(this)
                 listenForAnyStateToLockscreenTransition(this)
-                listenForLockscreenSettingChanges(this)
 
                 if (!mediaFlags.isSceneContainerEnabled()) return@repeatOnLifecycle
                 listenForMediaItemsChanges(this)
             }
         }
+        listenForLockscreenSettingChanges(applicationScope)
 
         // Notifies all active players about animation scale changes.
         bgExecutor.execute {
             globalSettings.registerContentObserverSync(
-                    Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE),
-                    animationScaleObserver
+                Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE),
+                animationScaleObserver
             )
         }
     }
@@ -659,13 +662,9 @@
     @VisibleForTesting
     internal fun listenForAnyStateToGoneKeyguardTransition(scope: CoroutineScope): Job {
         return scope.launch {
-            if (SceneContainerFlag.isEnabled) {
-                    sceneInteractor.transitionState.filter { it.isIdle(Scenes.Gone) }
-                } else {
-                    keyguardTransitionInteractor.transition(Edge.create(to = GONE)).filter {
-                        it.transitionState == TransitionState.FINISHED
-                    }
-                }
+            keyguardTransitionInteractor
+                .isFinishedIn(scene = Scenes.Gone, stateWithoutSceneContainer = GONE)
+                .filter { it }
                 .collect {
                     showMediaCarousel()
                     updateHostVisibility()
@@ -696,6 +695,7 @@
                 .onStart { emit(Unit) }
                 .map { getMediaLockScreenSetting() }
                 .distinctUntilChanged()
+                .flowOn(backgroundDispatcher)
                 .collectLatest {
                     allowMediaPlayerOnLockScreen = it
                     updateHostVisibility()
@@ -764,6 +764,7 @@
                 mediaContent.addView(viewHolder.recommendations, position)
             }
         }
+        onAddOrUpdateVisibleToUserCard(position, isMediaCardUpdate = false)
         viewController.setListening(mediaCarouselScrollHandler.visibleToUser && currentlyExpanded)
         controllerByViewModel[commonViewModel] = viewController
         updateViewControllerToState(viewController, noAnimation = true)
@@ -781,10 +782,14 @@
         commonViewModel.onAdded(commonViewModel)
     }
 
-    private fun onUpdated(commonViewModel: MediaCommonViewModel) {
+    private fun onUpdated(commonViewModel: MediaCommonViewModel, position: Int) {
         commonViewModel.onUpdated(commonViewModel)
         updatePageIndicator()
         mediaCarouselScrollHandler.onPlayersChanged()
+        onAddOrUpdateVisibleToUserCard(
+            position,
+            commonViewModel is MediaCommonViewModel.MediaControl
+        )
     }
 
     private fun onRemoved(commonViewModel: MediaCommonViewModel) {
@@ -821,6 +826,20 @@
         mediaCarouselScrollHandler.onPlayersChanged()
     }
 
+    private fun onAddOrUpdateVisibleToUserCard(position: Int, isMediaCardUpdate: Boolean) {
+        if (
+            mediaCarouselScrollHandler.visibleToUser &&
+                mediaCarouselScrollHandler.visibleMediaIndex == position
+        ) {
+            mediaCarouselViewModel.onCardVisibleToUser(
+                mediaCarouselScrollHandler.qsExpanded,
+                mediaCarouselScrollHandler.visibleMediaIndex,
+                currentEndLocation,
+                isMediaCardUpdate
+            )
+        }
+    }
+
     private fun setNewViewModelsList(viewModels: List<MediaCommonViewModel>) {
         commonViewModels.clear()
         commonViewModels.addAll(viewModels)
@@ -884,8 +903,7 @@
                     val previousVisibleIndex =
                         MediaPlayerData.playerKeys().indexOfFirst { key -> it == key }
                     mediaCarouselScrollHandler.scrollToPlayer(previousVisibleIndex, mediaIndex)
-                }
-                    ?: mediaCarouselScrollHandler.scrollToPlayer(destIndex = mediaIndex)
+                } ?: mediaCarouselScrollHandler.scrollToPlayer(destIndex = mediaIndex)
             }
         } else if (isRtl && mediaContent.childCount > 0) {
             // In RTL, Scroll to the first player as it is the rightmost player in media carousel.
@@ -1435,6 +1453,14 @@
 
     /** Log the user impression for media card at visibleMediaIndex. */
     fun logSmartspaceImpression(qsExpanded: Boolean) {
+        if (SceneContainerFlag.isEnabled) {
+            mediaCarouselViewModel.onCardVisibleToUser(
+                qsExpanded,
+                mediaCarouselScrollHandler.visibleMediaIndex,
+                currentEndLocation
+            )
+            return
+        }
         val visibleMediaIndex = mediaCarouselScrollHandler.visibleMediaIndex
         if (MediaPlayerData.players().size > visibleMediaIndex) {
             val mediaControlPanel = MediaPlayerData.getMediaControlPanel(visibleMediaIndex)
@@ -1547,7 +1573,7 @@
     @VisibleForTesting
     fun onSwipeToDismiss() {
         if (mediaFlags.isSceneContainerEnabled()) {
-            mediaCarouselViewModel.onSwipeToDismiss()
+            mediaCarouselViewModel.onSwipeToDismiss(currentEndLocation)
             return
         }
         MediaPlayerData.players().forEachIndexed { index, it ->
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java
index 5ec4f88..69a157f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java
@@ -19,6 +19,7 @@
 import static android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS;
 
 import static com.android.settingslib.flags.Flags.legacyLeAudioSharing;
+import static com.android.systemui.Flags.mediaLockscreenLaunchAnimation;
 import static com.android.systemui.media.controls.shared.model.SmartspaceMediaDataKt.NUM_REQUIRED_RECOMMENDATIONS;
 
 import android.animation.Animator;
@@ -577,13 +578,24 @@
                         && mActivityIntentHelper.wouldPendingShowOverLockscreen(clickIntent,
                         mLockscreenUserManager.getCurrentUserId());
                 if (showOverLockscreen) {
-                    try {
-                        ActivityOptions opts = ActivityOptions.makeBasic();
-                        opts.setPendingIntentBackgroundActivityStartMode(
-                                ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
-                        clickIntent.send(opts.toBundle());
-                    } catch (PendingIntent.CanceledException e) {
-                        Log.e(TAG, "Pending intent for " + key + " was cancelled");
+                    if (mediaLockscreenLaunchAnimation()) {
+                        mActivityStarter.startPendingIntentMaybeDismissingKeyguard(
+                                clickIntent,
+                                /* dismissShade = */ true,
+                                /* intentSentUiThreadCallback = */ null,
+                                buildLaunchAnimatorController(mMediaViewHolder.getPlayer()),
+                                /* fillIntent = */ null,
+                                /* extraOptions = */ null,
+                                /* customMessage */ null);
+                    } else {
+                        try {
+                            ActivityOptions opts = ActivityOptions.makeBasic();
+                            opts.setPendingIntentBackgroundActivityStartMode(
+                                    ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
+                            clickIntent.send(opts.toBundle());
+                        } catch (PendingIntent.CanceledException e) {
+                            Log.e(TAG, "Pending intent for " + key + " was cancelled");
+                        }
                     }
                 } else {
                     mActivityStarter.postStartActivityDismissingKeyguard(clickIntent,
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt
index 9d07232..681bf39 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt
@@ -103,6 +103,7 @@
     lateinit var sizeChangedListener: () -> Unit
     lateinit var configurationChangeListener: () -> Unit
     lateinit var recsConfigurationChangeListener: (MediaViewController, TransitionLayout) -> Unit
+    var locationChangeListener: (Int) -> Unit = {}
     private var firstRefresh: Boolean = true
     @VisibleForTesting private var transitionLayout: TransitionLayout? = null
     private val layoutController = TransitionLayoutController()
@@ -119,7 +120,15 @@
      * The ending location of the view where it ends when all animations and transitions have
      * finished
      */
-    @MediaLocation var currentEndLocation: Int = -1
+    @MediaLocation
+    var currentEndLocation: Int = -1
+        set(value) {
+            if (field != value) {
+                field = value
+                if (!mediaFlags.isSceneContainerEnabled()) return
+                locationChangeListener(value)
+            }
+        }
 
     /** The starting location of the view where it starts for all animations and transitions */
     @MediaLocation private var currentStartLocation: Int = -1
@@ -799,7 +808,7 @@
     fun bindSeekBar(onSeek: () -> Unit, onBindSeekBar: (SeekBarViewModel) -> Unit) {
         if (!mediaFlags.isSceneContainerEnabled()) return
         seekBarViewModel.logSeek = onSeek
-        onBindSeekBar.invoke(seekBarViewModel)
+        onBindSeekBar(seekBarViewModel)
     }
 
     fun setUpTurbulenceNoise() {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaViewModelCallback.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaViewModelCallback.kt
index 952b134..f28edd6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaViewModelCallback.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaViewModelCallback.kt
@@ -54,7 +54,8 @@
             oldItem is MediaCommonViewModel.MediaControl &&
                 newItem is MediaCommonViewModel.MediaControl
         ) {
-            oldItem.immediatelyUpdateUi == newItem.immediatelyUpdateUi
+            oldItem.immediatelyUpdateUi == newItem.immediatelyUpdateUi &&
+                oldItem.updateTime == newItem.updateTime
         } else if (
             oldItem is MediaCommonViewModel.MediaRecommendations &&
                 newItem is MediaCommonViewModel.MediaRecommendations
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaViewModelListUpdateCallback.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaViewModelListUpdateCallback.kt
index bd81e44..709723f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaViewModelListUpdateCallback.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaViewModelListUpdateCallback.kt
@@ -24,7 +24,7 @@
     private val old: List<MediaCommonViewModel>,
     private val new: List<MediaCommonViewModel>,
     private val onAdded: (MediaCommonViewModel, Int) -> Unit,
-    private val onUpdated: (MediaCommonViewModel) -> Unit,
+    private val onUpdated: (MediaCommonViewModel, Int) -> Unit,
     private val onRemoved: (MediaCommonViewModel) -> Unit,
     private val onMoved: (MediaCommonViewModel, Int, Int) -> Unit,
 ) : ListUpdateCallback {
@@ -47,7 +47,7 @@
 
     override fun onChanged(position: Int, count: Int, payload: Any?) {
         for (i in position until position + count) {
-            onUpdated(new[i])
+            onUpdated(new[i], position)
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt
index f0d8df5..e7f7171 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModel.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor
 import com.android.systemui.media.controls.domain.pipeline.interactor.factory.MediaControlInteractorFactory
+import com.android.systemui.media.controls.shared.MediaLogger
 import com.android.systemui.media.controls.shared.model.MediaCommonModel
 import com.android.systemui.media.controls.util.MediaFlags
 import com.android.systemui.media.controls.util.MediaUiEventLogger
@@ -52,6 +53,7 @@
     private val recommendationsViewModel: MediaRecommendationsViewModel,
     private val logger: MediaUiEventLogger,
     private val mediaFlags: MediaFlags,
+    private val mediaLogger: MediaLogger,
 ) {
 
     val mediaItems: StateFlow<List<MediaCommonViewModel>> =
@@ -98,9 +100,9 @@
 
     private var allowReorder = false
 
-    fun onSwipeToDismiss() {
+    fun onSwipeToDismiss(location: Int) {
         logger.logSwipeDismiss()
-        interactor.onSwipeToDismiss()
+        interactor.onSwipeToDismiss(location)
     }
 
     fun onReorderingAllowed() {
@@ -108,24 +110,41 @@
         interactor.reorderMedia()
     }
 
+    fun onCardVisibleToUser(
+        qsExpanded: Boolean,
+        visibleIndex: Int,
+        location: Int,
+        isUpdate: Boolean = false
+    ) {
+        // Skip logging if on LS or QQS, and there is no active media card
+        if (!qsExpanded && !interactor.hasActiveMediaOrRecommendation()) return
+        interactor.logSmartspaceSeenCard(visibleIndex, location, isUpdate)
+    }
+
     private fun toViewModel(
         commonModel: MediaCommonModel.MediaControl
     ): MediaCommonViewModel.MediaControl {
         val instanceId = commonModel.mediaLoadedModel.instanceId
         return mediaControlByInstanceId[instanceId]?.copy(
-            immediatelyUpdateUi = commonModel.mediaLoadedModel.immediatelyUpdateUi
+            immediatelyUpdateUi = commonModel.mediaLoadedModel.immediatelyUpdateUi,
+            updateTime = commonModel.updateTime
         )
             ?: MediaCommonViewModel.MediaControl(
                     instanceId = instanceId,
                     immediatelyUpdateUi = commonModel.mediaLoadedModel.immediatelyUpdateUi,
                     controlViewModel = createMediaControlViewModel(instanceId),
-                    onAdded = { onMediaControlAddedOrUpdated(it, commonModel) },
+                    onAdded = {
+                        mediaLogger.logMediaCardAdded(instanceId)
+                        onMediaControlAddedOrUpdated(it, commonModel)
+                    },
                     onRemoved = {
                         interactor.removeMediaControl(instanceId, delay = 0L)
                         mediaControlByInstanceId.remove(instanceId)
+                        mediaLogger.logMediaCardRemoved(instanceId)
                     },
                     onUpdated = { onMediaControlAddedOrUpdated(it, commonModel) },
-                    isMediaFromRec = commonModel.isMediaFromRec
+                    isMediaFromRec = commonModel.isMediaFromRec,
+                    updateTime = commonModel.updateTime
                 )
                 .also { mediaControlByInstanceId[instanceId] = it }
     }
@@ -155,6 +174,9 @@
                             mediaFlags.isPersistentSsCardEnabled(),
                     recsViewModel = recommendationsViewModel,
                     onAdded = { commonViewModel ->
+                        mediaLogger.logMediaRecommendationCardAdded(
+                            commonModel.recsLoadingModel.key
+                        )
                         onMediaRecommendationAddedOrUpdated(
                             commonViewModel as MediaCommonViewModel.MediaRecommendations
                         )
@@ -175,7 +197,6 @@
         commonViewModel: MediaCommonViewModel,
         commonModel: MediaCommonModel.MediaControl
     ) {
-        // TODO (b/330897926) log smartspace card reported (SMARTSPACE_CARD_RECEIVED)
         if (commonModel.canBeRemoved && !Utils.useMediaResumption(applicationContext)) {
             // This media control is due for removal as it is now paused + timed out, and resumption
             // setting is off.
@@ -196,8 +217,6 @@
             if (!mediaFlags.isPersistentSsCardEnabled()) {
                 commonViewModel.onRemoved(true)
             }
-        } else {
-            // TODO (b/330897926) log smartspace card reported (SMARTSPACE_CARD_RECEIVED)
         }
     }
 
@@ -205,6 +224,7 @@
         commonModel: MediaCommonModel.MediaRecommendations,
         immediatelyRemove: Boolean
     ) {
+        mediaLogger.logMediaRecommendationCardRemoved(commonModel.recsLoadingModel.key)
         if (immediatelyRemove || isReorderingAllowed()) {
             interactor.dismissSmartspaceRecommendation(commonModel.recsLoadingModel.key, 0L)
             mediaRecs = null
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCommonViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCommonViewModel.kt
index a96d75c..52cb173 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCommonViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaCommonViewModel.kt
@@ -33,6 +33,7 @@
         override val onRemoved: (Boolean) -> Unit,
         override val onUpdated: (MediaCommonViewModel) -> Unit,
         val isMediaFromRec: Boolean = false,
+        val updateTime: Long = 0,
     ) : MediaCommonViewModel()
 
     data class MediaRecommendations(
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt
index 099991d..64820e0 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt
@@ -37,6 +37,8 @@
 import com.android.systemui.media.controls.ui.animation.surfaceFromScheme
 import com.android.systemui.media.controls.ui.animation.textPrimaryFromScheme
 import com.android.systemui.media.controls.ui.util.MediaArtworkHelper
+import com.android.systemui.media.controls.util.MediaSmartspaceLogger.Companion.SMARTSPACE_CARD_CLICK_EVENT
+import com.android.systemui.media.controls.util.MediaSmartspaceLogger.Companion.SMARTSPACE_CARD_DISMISS_EVENT
 import com.android.systemui.media.controls.util.MediaUiEventLogger
 import com.android.systemui.monet.ColorScheme
 import com.android.systemui.monet.Style
@@ -72,6 +74,7 @@
 
     private var isPlaying = false
     private var isAnyButtonClicked = false
+    private var location = -1
 
     private fun onDismissMediaData(
         token: Token?,
@@ -80,7 +83,13 @@
         instanceId: InstanceId
     ) {
         logger.logLongPressDismiss(uid, packageName, instanceId)
-        interactor.removeMediaControl(token, instanceId, MEDIA_PLAYER_ANIMATION_DELAY)
+        interactor.removeMediaControl(
+            token,
+            instanceId,
+            MEDIA_PLAYER_ANIMATION_DELAY,
+            SMARTSPACE_CARD_DISMISS_EVENT,
+            location
+        )
     }
 
     private suspend fun toViewModel(model: MediaControlModel): MediaPlayerViewModel? {
@@ -100,7 +109,7 @@
                     TAG,
                     Style.CONTENT
                 )
-                    ?: return null
+                ?: return null
 
         val gutsViewModel = toGutsViewModel(model, scheme)
 
@@ -144,8 +153,12 @@
             onClicked = { expandable ->
                 model.clickIntent?.let { clickIntent ->
                     logger.logTapContentView(model.uid, model.packageName, model.instanceId)
-                    // TODO (b/330897926) log smartspace card reported (SMARTSPACE_CARD_CLICK_EVENT)
-                    interactor.startClickIntent(expandable, clickIntent)
+                    interactor.startClickIntent(
+                        expandable,
+                        clickIntent,
+                        SMARTSPACE_CARD_CLICK_EVENT,
+                        location
+                    )
                 }
             },
             onLongClicked = {
@@ -153,7 +166,7 @@
             },
             onSeek = {
                 logger.logSeek(model.uid, model.packageName, model.instanceId)
-                // TODO (b/330897926) log smartspace card reported (SMARTSPACE_CARD_CLICK_EVENT)
+                interactor.logSmartspaceUserEvent(SMARTSPACE_CARD_CLICK_EVENT, location)
             },
             onBindSeekbar = { seekBarViewModel ->
                 if (model.isResume && model.resumeProgress != null) {
@@ -163,7 +176,8 @@
                         seekBarViewModel.updateController(mediaController)
                     }
                 }
-            }
+            },
+            onLocationChanged = { location = it }
         )
     }
 
@@ -179,8 +193,7 @@
                     it,
                     applicationContext.getString(R.string.broadcasting_description_is_broadcasting)
                 )
-            }
-                ?: false
+            } ?: false
         val useDisabledAlpha =
             if (showBroadcastButton) {
                 !isCurrentBroadcastApp
@@ -197,7 +210,8 @@
         return MediaOutputSwitcherViewModel(
             isTapEnabled = showBroadcastButton || !useDisabledAlpha,
             deviceString = deviceString,
-            deviceIcon = device?.icon?.let { Icon.Loaded(it, null) }
+            deviceIcon =
+                device?.icon?.let { Icon.Loaded(it, null) }
                     ?: if (showBroadcastButton) {
                         Icon.Resource(R.drawable.settings_input_antenna, null)
                     } else {
@@ -364,7 +378,7 @@
         action: Runnable
     ) {
         logger.logTapAction(id, uid, packageName, instanceId)
-        // TODO (b/330897926) log smartspace card reported (SMARTSPACE_CARD_CLICK_EVENT)
+        interactor.logSmartspaceUserEvent(SMARTSPACE_CARD_CLICK_EVENT, location)
         isAnyButtonClicked = true
         action.run()
     }
@@ -385,8 +399,7 @@
             SEMANTIC_ACTIONS_HIDE_WHEN_SCRUBBING.stream().allMatch { id: Int ->
                 semanticActions.getActionById(id) != null
             }
-        }
-            ?: false
+        } ?: false
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaPlayerViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaPlayerViewModel.kt
index 4334341..96e7fc7 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaPlayerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaPlayerViewModel.kt
@@ -42,4 +42,5 @@
     val onLongClicked: () -> Unit,
     val onSeek: () -> Unit,
     val onBindSeekbar: (SeekBarViewModel) -> Unit,
+    val onLocationChanged: (Int) -> Unit,
 )
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt
index 52c4bc5..1fd9c4f0 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt
@@ -37,6 +37,7 @@
 import com.android.systemui.media.controls.domain.pipeline.interactor.MediaRecommendationsInteractor
 import com.android.systemui.media.controls.shared.model.MediaRecModel
 import com.android.systemui.media.controls.shared.model.MediaRecommendationsModel
+import com.android.systemui.media.controls.shared.model.NUM_REQUIRED_RECOMMENDATIONS
 import com.android.systemui.media.controls.ui.animation.accentPrimaryFromScheme
 import com.android.systemui.media.controls.ui.animation.surfaceFromScheme
 import com.android.systemui.media.controls.ui.animation.textPrimaryFromScheme
@@ -44,6 +45,8 @@
 import com.android.systemui.media.controls.ui.controller.MediaViewController.Companion.GUTS_ANIMATION_DURATION
 import com.android.systemui.media.controls.ui.util.MediaArtworkHelper
 import com.android.systemui.media.controls.util.MediaDataUtils
+import com.android.systemui.media.controls.util.MediaSmartspaceLogger.Companion.SMARTSPACE_CARD_CLICK_EVENT
+import com.android.systemui.media.controls.util.MediaSmartspaceLogger.Companion.SMARTSPACE_CARD_DISMISS_EVENT
 import com.android.systemui.media.controls.util.MediaUiEventLogger
 import com.android.systemui.monet.ColorScheme
 import com.android.systemui.monet.Style
@@ -78,6 +81,8 @@
             .distinctUntilChanged()
             .flowOn(backgroundDispatcher)
 
+    private var location = -1
+
     /**
      * Called whenever the recommendation has been expired or removed by the user. This method
      * removes the recommendation card entirely from the carousel.
@@ -89,9 +94,14 @@
         dismissIntent: Intent?,
         instanceId: InstanceId?
     ) {
-        // TODO (b/330897926) log smartspace card reported (SMARTSPACE_CARD_DISMISS_EVENT).
         logger.logLongPressDismiss(uid, packageName, instanceId)
-        interactor.removeMediaRecommendations(key, dismissIntent, GUTS_DISMISS_DELAY_MS_DURATION)
+        interactor.removeMediaRecommendations(
+            key,
+            dismissIntent,
+            GUTS_DISMISS_DELAY_MS_DURATION,
+            SMARTSPACE_CARD_DISMISS_EVENT,
+            location
+        )
     }
 
     private fun onClicked(
@@ -111,12 +121,18 @@
         } else {
             logger.logRecommendationItemTap(packageName, instanceId, index)
         }
-        // TODO (b/330897926) log smartspace card reported (SMARTSPACE_CARD_CLICK_EVENT).
 
         // set the package name of the player added by recommendation once the media is loaded.
         interactor.switchToMediaControl(packageName)
 
-        interactor.startClickIntent(expandable, intent)
+        interactor.startClickIntent(
+            expandable,
+            intent,
+            SMARTSPACE_CARD_CLICK_EVENT,
+            location,
+            index,
+            NUM_REQUIRED_RECOMMENDATIONS
+        )
     }
 
     private suspend fun toRecsViewModel(model: MediaRecommendationsModel): MediaRecsCardViewModel? {
@@ -212,6 +228,7 @@
             areTitlesVisible = areTitlesVisible,
             areSubtitlesVisible = areSubtitlesVisible,
             gutsMenu = toGutsViewModel(model, scheme),
+            onLocationChanged = { location = it }
         )
     }
 
@@ -259,8 +276,7 @@
                         width,
                         height
                     )
-                }
-                ?: ColorDrawable(Color.TRANSPARENT)
+                } ?: ColorDrawable(Color.TRANSPARENT)
         }
 
     private fun addGradientToRecommendationAlbum(
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecsCardViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecsCardViewModel.kt
index d1713b5..5ecbcb2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecsCardViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecsCardViewModel.kt
@@ -30,4 +30,5 @@
     val areTitlesVisible: Boolean,
     val areSubtitlesVisible: Boolean,
     val gutsMenu: GutsViewModel,
+    val onLocationChanged: (Int) -> Unit,
 )
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaSmartspaceLogger.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaSmartspaceLogger.kt
new file mode 100644
index 0000000..9c59aa2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaSmartspaceLogger.kt
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.controls.util
+
+import android.util.Log
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.shared.system.SysUiStatsLog
+import javax.inject.Inject
+
+/** Logger class for Smartspace logging events. */
+@SysUISingleton
+class MediaSmartspaceLogger @Inject constructor() {
+    /**
+     * Log Smartspace card received event
+     *
+     * @param instanceId id to uniquely identify a card.
+     * @param uid uid for the application that media comes from.
+     * @param cardinality number of card in carousel.
+     * @param isRecommendationCard whether media card being logged is a recommendations card.
+     * @param isSsReactivated indicates resume media card is reactivated by Smartspace
+     *   recommendation signal
+     * @param rank the rank for media card in the media carousel, starting from 0
+     * @param receivedLatencyMillis latency in milliseconds for card received events.
+     */
+    fun logSmartspaceCardReceived(
+        instanceId: Int,
+        uid: Int,
+        cardinality: Int,
+        isRecommendationCard: Boolean = false,
+        isSsReactivated: Boolean = false,
+        rank: Int = 0,
+        receivedLatencyMillis: Int = 0,
+    ) {
+        logSmartspaceCardReported(
+            SMARTSPACE_CARD_RECEIVED_EVENT,
+            instanceId,
+            uid,
+            surfaces =
+                intArrayOf(
+                    SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__SHADE,
+                    SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__LOCKSCREEN,
+                    SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__DREAM_OVERLAY,
+                ),
+            cardinality,
+            isRecommendationCard,
+            isSsReactivated,
+            rank = rank,
+            receivedLatencyMillis = receivedLatencyMillis,
+        )
+    }
+
+    /**
+     * Log Smartspace card UI event
+     *
+     * @param eventId id of the event. eg: dismiss, click, or seen.
+     * @param instanceId id to uniquely identify a card.
+     * @param uid uid for the application that media comes from.
+     * @param surface location of media carousel holding media card.
+     * @param cardinality number of card in carousel.
+     * @param isRecommendationCard whether media card being logged is a recommendations card.
+     * @param isSsReactivated indicates resume media card is reactivated by Smartspace
+     *   recommendation signal
+     * @param rank the rank for media card in the media carousel, starting from 0
+     * @param isSwipeToDismiss whether is to log swipe-to-dismiss event
+     */
+    fun logSmartspaceCardUIEvent(
+        eventId: Int,
+        instanceId: Int,
+        uid: Int,
+        surface: Int,
+        cardinality: Int,
+        isRecommendationCard: Boolean = false,
+        isSsReactivated: Boolean = false,
+        interactedSubcardRank: Int = 0,
+        interactedSubcardCardinality: Int = 0,
+        rank: Int = 0,
+        isSwipeToDismiss: Boolean = false,
+    ) {
+        logSmartspaceCardReported(
+            eventId,
+            instanceId,
+            uid,
+            surfaces = intArrayOf(surface),
+            cardinality,
+            isRecommendationCard,
+            isSsReactivated,
+            interactedSubcardRank,
+            interactedSubcardCardinality,
+            rank = rank,
+            isSwipeToDismiss = isSwipeToDismiss,
+        )
+    }
+
+    /**
+     * Log Smartspace events
+     *
+     * @param eventId UI event id (e.g. 800 for SMARTSPACE_CARD_SEEN)
+     * @param instanceId id to uniquely identify a card, e.g. each headphone generates a new
+     *   instanceId
+     * @param uid uid for the application that media comes from
+     * @param surfaces list of display surfaces the media card is on (e.g. lockscreen, shade) when
+     *   the event happened
+     * @param cardinality number of card in carousel.
+     * @param isRecommendationCard whether media card being logged is a recommendations card.
+     * @param isSsReactivated indicates resume media card is reactivated by Smartspace
+     *   recommendation signal
+     * @param interactedSubcardRank the rank for interacted media item for recommendation card, -1
+     *   for tapping on card but not on any media item, 0 for first media item, 1 for second, etc.
+     * @param interactedSubcardCardinality how many media items were shown to the user when there is
+     *   user interaction
+     * @param rank the rank for media card in the media carousel, starting from 0
+     * @param receivedLatencyMillis latency in milliseconds for card received events. E.g. latency
+     *   between headphone connection to sysUI displays media recommendation card
+     * @param isSwipeToDismiss whether is to log swipe-to-dismiss event
+     */
+    private fun logSmartspaceCardReported(
+        eventId: Int,
+        instanceId: Int,
+        uid: Int,
+        surfaces: IntArray,
+        cardinality: Int,
+        isRecommendationCard: Boolean,
+        isSsReactivated: Boolean,
+        interactedSubcardRank: Int = 0,
+        interactedSubcardCardinality: Int = 0,
+        rank: Int = 0,
+        receivedLatencyMillis: Int = 0,
+        isSwipeToDismiss: Boolean = false,
+    ) {
+        surfaces.forEach { surface ->
+            SysUiStatsLog.write(
+                SysUiStatsLog.SMARTSPACE_CARD_REPORTED,
+                eventId,
+                instanceId,
+                // Deprecated, replaced with AiAi feature type so we don't need to create logging
+                // card type for each new feature.
+                SysUiStatsLog.SMART_SPACE_CARD_REPORTED__CARD_TYPE__UNKNOWN_CARD,
+                surface,
+                // Use -1 as rank value to indicate user swipe to dismiss the card
+                if (isSwipeToDismiss) -1 else rank,
+                cardinality,
+                if (isRecommendationCard) {
+                    15 // MEDIA_RECOMMENDATION
+                } else if (isSsReactivated) {
+                    43 // MEDIA_RESUME_SS_ACTIVATED
+                } else {
+                    31 // MEDIA_RESUME
+                },
+                uid,
+                interactedSubcardRank,
+                interactedSubcardCardinality,
+                receivedLatencyMillis,
+                null, // Media cards cannot have subcards.
+                null // Media cards don't have dimensions today.
+            )
+
+            if (DEBUG) {
+                Log.d(
+                    TAG,
+                    "Log Smartspace card event id: $eventId instance id: $instanceId" +
+                        " surface: $surface rank: $rank cardinality: $cardinality " +
+                        "isRecommendationCard: $isRecommendationCard " +
+                        "isSsReactivated: $isSsReactivated" +
+                        "uid: $uid " +
+                        "interactedSubcardRank: $interactedSubcardRank " +
+                        "interactedSubcardCardinality: $interactedSubcardCardinality " +
+                        "received_latency_millis: $receivedLatencyMillis"
+                )
+            }
+        }
+    }
+
+    companion object {
+        private const val TAG = "MediaSmartspaceLogger"
+        private val DEBUG = Log.isLoggable(TAG, Log.DEBUG)
+        private const val SMARTSPACE_CARD_RECEIVED_EVENT = 759
+        const val SMARTSPACE_CARD_CLICK_EVENT = 760
+        const val SMARTSPACE_CARD_DISMISS_EVENT = 761
+        const val SMARTSPACE_CARD_SEEN_EVENT = 800
+
+        /**
+         * Get the location of media view given [currentEndLocation]
+         *
+         * @return location used for Smartspace logging
+         */
+        fun getSurface(location: Int): Int {
+            SceneContainerFlag.isUnexpectedlyInLegacyMode()
+            return when (location) {
+                MediaHierarchyManager.LOCATION_QQS,
+                MediaHierarchyManager.LOCATION_QS -> {
+                    SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__SHADE
+                }
+                MediaHierarchyManager.LOCATION_LOCKSCREEN -> {
+                    SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__LOCKSCREEN
+                }
+                MediaHierarchyManager.LOCATION_DREAM_OVERLAY -> {
+                    SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__DREAM_OVERLAY
+                }
+                else -> SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__DEFAULT_SURFACE
+            }
+        }
+    }
+}
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 1e86563..b48b409 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -85,6 +85,7 @@
 import com.android.systemui.animation.DialogTransitionAnimator;
 import com.android.systemui.broadcast.BroadcastSender;
 import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.media.dialog.MediaItem.MediaItemType;
 import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
 import com.android.systemui.monet.ColorScheme;
 import com.android.systemui.plugins.ActivityStarter;
@@ -110,6 +111,7 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.Executor;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /**
@@ -661,28 +663,38 @@
                             /* connectedMediaDevice */ null,
                             devices,
                             needToHandleMutingExpectedDevice);
+                } else {
+                    // selected device exist
+                    return categorizeMediaItemsLocked(
+                            connectedMediaDevice,
+                            devices,
+                            /* needToHandleMutingExpectedDevice */ false);
                 }
-                // selected device exist
-                return categorizeMediaItemsLocked(
-                        connectedMediaDevice,
-                        devices,
-                        /* needToHandleMutingExpectedDevice */ false);
             }
             // To keep the same list order
             final List<MediaDevice> targetMediaDevices = new ArrayList<>();
             final Map<Integer, MediaItem> dividerItems = new HashMap<>();
+
+            Map<String, MediaDevice> idToMediaDeviceMap =
+                    devices.stream()
+                            .collect(Collectors.toMap(MediaDevice::getId, Function.identity()));
+
             for (MediaItem originalMediaItem : oldMediaItems) {
-                for (MediaDevice newDevice : devices) {
-                    if (originalMediaItem.getMediaDevice().isPresent()
-                            && TextUtils.equals(originalMediaItem.getMediaDevice().get().getId(),
-                            newDevice.getId())) {
-                        targetMediaDevices.add(newDevice);
-                        break;
+                switch (originalMediaItem.getMediaItemType()) {
+                    case MediaItemType.TYPE_GROUP_DIVIDER -> {
+                        dividerItems.put(
+                                oldMediaItems.indexOf(originalMediaItem), originalMediaItem);
                     }
-                }
-                if (originalMediaItem.getMediaItemType()
-                        == MediaItem.MediaItemType.TYPE_GROUP_DIVIDER) {
-                    dividerItems.put(oldMediaItems.indexOf(originalMediaItem), originalMediaItem);
+                    case MediaItemType.TYPE_DEVICE -> {
+                        String originalMediaItemId =
+                                originalMediaItem.getMediaDevice().orElseThrow().getId();
+                        if (idToMediaDeviceMap.containsKey(originalMediaItemId)) {
+                            targetMediaDevices.add(idToMediaDeviceMap.get(originalMediaItemId));
+                        }
+                    }
+                    case MediaItemType.TYPE_PAIR_NEW_DEVICE -> {
+                        // Do nothing.
+                    }
                 }
             }
             if (targetMediaDevices.size() != devices.size()) {
@@ -723,12 +735,10 @@
                 finalMediaItems.add(0, MediaItem.createDeviceMediaItem(device));
             } else {
                 if (device.isSuggestedDevice() && !suggestedDeviceAdded) {
-                    attachGroupDivider(finalMediaItems, mContext.getString(
-                            R.string.media_output_group_title_suggested_device));
+                    addSuggestedDeviceGroupDivider(finalMediaItems);
                     suggestedDeviceAdded = true;
                 } else if (!device.isSuggestedDevice() && !displayGroupAdded) {
-                    attachGroupDivider(finalMediaItems, mContext.getString(
-                            R.string.media_output_group_title_speakers_and_displays));
+                    addSpeakersAndDisplaysGroupDivider(finalMediaItems);
                     displayGroupAdded = true;
                 }
                 finalMediaItems.add(MediaItem.createDeviceMediaItem(device));
@@ -738,8 +748,17 @@
         return finalMediaItems;
     }
 
-    private void attachGroupDivider(List<MediaItem> mediaItems, String title) {
-        mediaItems.add(MediaItem.createGroupDividerMediaItem(title));
+    private void addSuggestedDeviceGroupDivider(List<MediaItem> mediaItems) {
+        mediaItems.add(
+                MediaItem.createGroupDividerMediaItem(
+                        mContext.getString(R.string.media_output_group_title_suggested_device)));
+    }
+
+    private void addSpeakersAndDisplaysGroupDivider(List<MediaItem> mediaItems) {
+        mediaItems.add(
+                MediaItem.createGroupDividerMediaItem(
+                        mContext.getString(
+                                R.string.media_output_group_title_speakers_and_displays)));
     }
 
     private void attachConnectNewDeviceItemIfNeeded(List<MediaItem> mediaItems) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogManager.kt b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogManager.kt
index ee816942..47e0691 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogManager.kt
@@ -98,7 +98,7 @@
         createAndShow(
             packageName = null,
             aboveStatusBar = false,
-            dialogTransitionAnimatorController = null,
+            dialogTransitionAnimatorController = controller,
             includePlaybackAndAppMetadata = false,
             userHandle = null,
         )
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseMediaProjectionPermissionDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseMediaProjectionPermissionDialogDelegate.kt
index 6224170..83f694b 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseMediaProjectionPermissionDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseMediaProjectionPermissionDialogDelegate.kt
@@ -104,7 +104,7 @@
 
     private fun initScreenShareSpinner() {
         val adapter = OptionsAdapter(dialog.context.applicationContext, screenShareOptions)
-        screenShareModeSpinner = dialog.requireViewById(R.id.screen_share_mode_spinner)
+        screenShareModeSpinner = dialog.requireViewById(R.id.screen_share_mode_options)
         screenShareModeSpinner.adapter = adapter
         screenShareModeSpinner.onItemSelectedListener = this
 
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegate.kt
index 8858041a..9ce8070 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegate.kt
@@ -30,7 +30,7 @@
     private val onStartRecordingClicked: Consumer<MediaProjectionPermissionDialogDelegate>,
     private val onCancelClicked: Runnable,
     private val appName: String?,
-    private val forceShowPartialScreenshare: Boolean,
+    forceShowPartialScreenshare: Boolean,
     hostUid: Int,
     mediaProjectionMetricsLogger: MediaProjectionMetricsLogger,
 ) :
diff --git a/packages/SystemUI/src/com/android/systemui/mediarouter/MediaRouterModule.kt b/packages/SystemUI/src/com/android/systemui/mediarouter/MediaRouterModule.kt
new file mode 100644
index 0000000..c07e3a0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/mediarouter/MediaRouterModule.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.mediarouter
+
+import com.android.systemui.mediarouter.data.repository.MediaRouterRepository
+import com.android.systemui.mediarouter.data.repository.MediaRouterRepositoryImpl
+import dagger.Binds
+import dagger.Module
+
+@Module
+interface MediaRouterModule {
+    @Binds fun mediaRouterRepository(impl: MediaRouterRepositoryImpl): MediaRouterRepository
+}
diff --git a/packages/SystemUI/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepository.kt b/packages/SystemUI/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepository.kt
new file mode 100644
index 0000000..998d76c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepository.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.mediarouter.data.repository
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.statusbar.policy.CastController
+import com.android.systemui.statusbar.policy.CastDevice
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.stateIn
+
+/** A repository for data coming from MediaRouter APIs. */
+interface MediaRouterRepository {
+    /** A list of the cast devices that MediaRouter is currently aware of. */
+    val castDevices: StateFlow<List<CastDevice>>
+
+    /** Stops the cast to the given device. */
+    fun stopCasting(device: CastDevice)
+}
+
+@SysUISingleton
+class MediaRouterRepositoryImpl
+@Inject
+constructor(
+    @Application private val scope: CoroutineScope,
+    private val castController: CastController,
+) : MediaRouterRepository {
+    override val castDevices: StateFlow<List<CastDevice>> =
+        conflatedCallbackFlow {
+                val callback =
+                    CastController.Callback {
+                        val mediaRouterCastDevices =
+                            castController.castDevices.filter {
+                                it.origin == CastDevice.CastOrigin.MediaRouter
+                            }
+                        trySend(mediaRouterCastDevices)
+                    }
+                castController.addCallback(callback)
+                awaitClose { castController.removeCallback(callback) }
+            }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), emptyList())
+
+    override fun stopCasting(device: CastDevice) {
+        castController.stopCasting(device)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt b/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt
index c8e896d..42f66cc 100644
--- a/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt
+++ b/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt
@@ -18,12 +18,14 @@
 
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.compose.animation.scene.SceneKey
+import com.android.systemui.Flags.glanceableHubBackGesture
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING
+import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_COMMUNAL_HUB_SHOWING
 import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED
 import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE
 import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED
@@ -84,9 +86,13 @@
                 SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE to { it.scene != Scenes.Gone },
                 SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED to
                     {
-                        it.scene == Scenes.Lockscreen ||
-                            it.scene == Scenes.NotificationsShade ||
-                            it.scene == Scenes.Shade
+                        when {
+                            it.invisibleDueToOcclusion -> false
+                            it.scene == Scenes.Lockscreen -> true
+                            it.scene == Scenes.NotificationsShade -> true
+                            it.scene == Scenes.Shade -> true
+                            else -> false
+                        }
                     },
                 SYSUI_STATE_QUICK_SETTINGS_EXPANDED to
                     {
@@ -101,6 +107,10 @@
                     {
                         it.scene == Scenes.Lockscreen && it.invisibleDueToOcclusion
                     },
+                SYSUI_STATE_COMMUNAL_HUB_SHOWING to
+                    {
+                        glanceableHubBackGesture() && it.scene == Scenes.Communal
+                    }
             )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/navigation/data/repository/NavigationRepository.kt b/packages/SystemUI/src/com/android/systemui/navigation/data/repository/NavigationRepository.kt
new file mode 100644
index 0000000..4409e2c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigation/data/repository/NavigationRepository.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.navigation.data.repository
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.navigationbar.NavigationModeController
+import com.android.systemui.shared.system.QuickStepContract
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
+import javax.inject.Inject
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class NavigationRepository
+@Inject
+constructor(
+    private val controller: NavigationModeController,
+) {
+
+    /** Whether the current navigation bar mode is edge-to-edge. */
+    val isGesturalMode: Flow<Boolean> = conflatedCallbackFlow {
+        val listener =
+            NavigationModeController.ModeChangedListener { mode ->
+                trySend(QuickStepContract.isGesturalMode(mode))
+            }
+
+        val currentMode = controller.addListener(listener)
+        trySend(QuickStepContract.isGesturalMode(currentMode))
+
+        awaitClose { controller.removeListener(listener) }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/navigation/domain/interactor/NavigationInteractor.kt b/packages/SystemUI/src/com/android/systemui/navigation/domain/interactor/NavigationInteractor.kt
new file mode 100644
index 0000000..0f9c883
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigation/domain/interactor/NavigationInteractor.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.navigation.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.navigation.data.repository.NavigationRepository
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class NavigationInteractor
+@Inject
+constructor(
+    repository: NavigationRepository,
+) {
+
+    /** Whether the current navigation bar mode is edge-to-edge. */
+    val isGesturalMode: Flow<Boolean> = repository.isGesturalMode
+}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarButtonClickLogger.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarButtonClickLogger.kt
deleted file mode 100644
index 408acf3..0000000
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarButtonClickLogger.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.navigationbar
-
-import com.android.systemui.log.LogBuffer
-import com.android.systemui.log.core.LogLevel
-import com.android.systemui.log.dagger.NavBarButtonClickLog
-import javax.inject.Inject
-
-class NavBarButtonClickLogger
-@Inject
-constructor(@NavBarButtonClickLog private val buffer: LogBuffer) {
-    fun logHomeButtonClick() {
-        buffer.log(TAG, LogLevel.DEBUG, {}, { "Home Button Triggered" })
-    }
-
-    fun logBackButtonClick() {
-        buffer.log(TAG, LogLevel.DEBUG, {}, { "Back Button Triggered" })
-    }
-
-    fun logRecentsButtonClick() {
-        buffer.log(TAG, LogLevel.DEBUG, {}, { "Recents Button Triggered" })
-    }
-
-    fun logImeSwitcherClick() {
-        buffer.log(TAG, LogLevel.DEBUG, {}, { "Ime Switcher Triggered" })
-    }
-
-    fun logAccessibilityButtonClick() {
-        buffer.log(TAG, LogLevel.DEBUG, {}, { "Accessibility Button Triggered" })
-    }
-}
-
-private const val TAG = "NavBarButtonClick"
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
index 80c4379..13a786a 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
@@ -27,11 +27,11 @@
 import static com.android.systemui.accessibility.SystemActions.SYSTEM_ACTION_ID_ACCESSIBILITY_BUTTON_CHOOSER;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_OPAQUE;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
 
 import android.content.ContentResolver;
 import android.content.Context;
@@ -56,6 +56,8 @@
 import android.view.accessibility.AccessibilityManager;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.WorkerThread;
 
 import com.android.internal.accessibility.common.ShortcutConstants;
 import com.android.systemui.Dumpable;
@@ -64,16 +66,18 @@
 import com.android.systemui.accessibility.SystemActions;
 import com.android.systemui.assist.AssistManager;
 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.navigationbar.gestural.EdgeBackGestureHandler;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.settings.DisplayTracker;
 import com.android.systemui.settings.UserTracker;
+import com.android.systemui.shared.rotation.RotationPolicyUtil;
+import com.android.systemui.shared.statusbar.phone.BarTransitions.TransitionMode;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
-import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -108,6 +112,7 @@
 
     private final Handler mHandler = new Handler(Looper.getMainLooper());
     private final Executor mMainExecutor;
+    private final Handler mBgHandler;
     private final AccessibilityManager mAccessibilityManager;
     private final Lazy<AssistManager> mAssistManagerLazy;
     private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
@@ -160,13 +165,15 @@
 
     // Listens for changes to display rotation
     private final IRotationWatcher mRotationWatcher = new IRotationWatcher.Stub() {
+        @WorkerThread
         @Override
         public void onRotationChanged(final int rotation) {
             // We need this to be scheduled as early as possible to beat the redrawing of
             // window in response to the orientation change.
+            @Nullable Boolean isRotationLocked = RotationPolicyUtil.isRotationLocked(mContext);
             mHandler.postAtFrontOfQueue(() -> {
                 mRotationWatcherRotation = rotation;
-                dispatchRotationChanged(rotation);
+                dispatchRotationChanged(rotation, isRotationLocked);
             });
         }
     };
@@ -194,7 +201,8 @@
             ConfigurationController configurationController,
             DumpManager dumpManager,
             CommandQueue commandQueue,
-            @Main Executor mainExecutor) {
+            @Main Executor mainExecutor,
+            @Background Handler bgHandler) {
         // b/319489709: This component shouldn't be running for a non-primary user
         if (!Process.myUserHandle().equals(UserHandle.SYSTEM)) {
             Log.wtf(TAG, "Unexpected initialization for non-primary user", new Throwable());
@@ -215,6 +223,7 @@
         mDefaultDisplayId = displayTracker.getDefaultDisplayId();
         mEdgeBackGestureHandler = edgeBackGestureHandlerFactory.create(context);
         mMainExecutor = mainExecutor;
+        mBgHandler = bgHandler;
 
         mNavBarMode = navigationModeController.addListener(this);
         mCommandQueue.addCallback(this);
@@ -322,7 +331,13 @@
             listener.updateAssistantAvailable(mAssistantAvailable, mLongPressHomeEnabled);
         }
         listener.updateWallpaperVisibility(mWallpaperVisible, mDefaultDisplayId);
-        listener.updateRotationWatcherState(mRotationWatcherRotation);
+
+        mBgHandler.post(() -> {
+            Boolean isRotationLocked = RotationPolicyUtil.isRotationLocked(mContext);
+            mMainExecutor.execute(
+                    () -> listener.updateRotationWatcherState(
+                            mRotationWatcherRotation, isRotationLocked));
+        });
     }
 
     /**
@@ -526,9 +541,9 @@
         }
     }
 
-    private void dispatchRotationChanged(int rotation) {
+    private void dispatchRotationChanged(int rotation, @Nullable Boolean isRotationLocked) {
         for (NavbarTaskbarStateUpdater listener : mStateListeners) {
-            listener.updateRotationWatcherState(rotation);
+            listener.updateRotationWatcherState(rotation, isRotationLocked);
         }
     }
 
@@ -544,7 +559,7 @@
         void updateAccessibilityServicesState();
         void updateAssistantAvailable(boolean available, boolean longPressHomeEnabled);
         default void updateWallpaperVisibility(boolean visible, int displayId) {}
-        default void updateRotationWatcherState(int rotation) {}
+        default void updateRotationWatcherState(int rotation, @Nullable Boolean isRotationLocked) {}
     }
 
     /** Data class to help Taskbar/Navbar initiate state correctly when switching between the two.*/
@@ -558,7 +573,7 @@
         }
     }
 
-    static @TransitionMode int transitionMode(boolean isTransient, int appearance) {
+    public static @TransitionMode int transitionMode(boolean isTransient, int appearance) {
         final int lightsOutOpaque = APPEARANCE_LOW_PROFILE_BARS | APPEARANCE_OPAQUE_NAVIGATION_BARS;
         if (isTransient) {
             return MODE_SEMI_TRANSPARENT;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavbarOrientationTrackingLogger.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/NavbarOrientationTrackingLogger.kt
deleted file mode 100644
index b1bd286..0000000
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavbarOrientationTrackingLogger.kt
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.navigationbar
-
-import android.view.Surface
-import com.android.systemui.log.LogBuffer
-import com.android.systemui.log.core.LogLevel
-import com.android.systemui.log.dagger.NavbarOrientationTrackingLog
-import javax.inject.Inject
-
-class NavbarOrientationTrackingLogger
-@Inject
-constructor(@NavbarOrientationTrackingLog private val buffer: LogBuffer) {
-    fun logPrimaryAndSecondaryVisibility(
-        methodName: String,
-        isViewVisible: Boolean,
-        isImmersiveMode: Boolean,
-        isSecondaryHandleVisible: Boolean,
-        currentRotation: Int,
-        startingQuickSwitchRotation: Int
-    ) {
-        buffer.log(
-            TAG,
-            LogLevel.DEBUG,
-            {
-                str1 = methodName
-                bool1 = isViewVisible
-                bool2 = isImmersiveMode
-                bool3 = isSecondaryHandleVisible
-                int1 = startingQuickSwitchRotation
-                int2 = currentRotation
-            },
-            {
-                "Caller Method: $str1\n" +
-                    "\tNavbar Visible: $bool1\n" +
-                    "\tImmersive Mode: $bool2\n" +
-                    "\tSecondary Handle Visible: $bool3\n" +
-                    "\tDelta Rotation: ${getDeltaRotation(int1, int2)}\n" +
-                    "\tStarting QuickSwitch Rotation: $int1\n" +
-                    "\tCurrent Rotation: $int2\n"
-            }
-        )
-    }
-
-    private fun getDeltaRotation(oldRotation: Int, newRotation: Int): String {
-        var rotation: String = "0"
-        when (deltaRotation(oldRotation, newRotation)) {
-            Surface.ROTATION_90 -> {
-                rotation = "90"
-            }
-            Surface.ROTATION_180 -> {
-                rotation = "180"
-            }
-            Surface.ROTATION_270 -> {
-                rotation = "270"
-            }
-        }
-        return rotation
-    }
-
-    private fun deltaRotation(oldRotation: Int, newRotation: Int): Int {
-        var delta = newRotation - oldRotation
-        if (delta < 0) delta += 4
-        return delta
-    }
-}
-
-private const val TAG = "NavbarOrientationTracking"
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
deleted file mode 100644
index 07289cb..0000000
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ /dev/null
@@ -1,2088 +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.navigationbar;
-
-import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
-import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
-import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN;
-import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
-import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
-import static android.app.StatusBarManager.WindowType;
-import static android.app.StatusBarManager.WindowVisibleState;
-import static android.app.StatusBarManager.windowStateToString;
-import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
-import static android.inputmethodservice.InputMethodService.ENABLE_HIDE_IME_CAPTION_BAR;
-import static android.view.InsetsSource.FLAG_SUPPRESS_SCRIM;
-import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
-import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
-
-import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
-import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.HOME_BUTTON_LONG_PRESS_DURATION_MS;
-import static com.android.systemui.navigationbar.NavBarHelper.transitionMode;
-import static com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
-import static com.android.systemui.shared.recents.utilities.Utilities.isLargeScreen;
-import static com.android.systemui.shared.rotation.RotationButtonController.DEBUG_ROTATION;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
-import static com.android.systemui.shared.system.QuickStepContract.isGesturalMode;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
-import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
-import static com.android.systemui.statusbar.phone.CentralSurfaces.DEBUG_WINDOW_STATE;
-import static com.android.systemui.statusbar.phone.CentralSurfaces.dumpBarTransitions;
-import static com.android.systemui.util.Utils.isGesturalModeOnDefaultDisplay;
-
-import android.annotation.IdRes;
-import android.annotation.NonNull;
-import android.app.ActivityTaskManager;
-import android.app.IActivityTaskManager;
-import android.app.StatusBarManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.graphics.Insets;
-import android.graphics.PixelFormat;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.Region;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.Trace;
-import android.provider.DeviceConfig;
-import android.telecom.TelecomManager;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.Display;
-import android.view.Gravity;
-import android.view.HapticFeedbackConstants;
-import android.view.InsetsFrameProvider;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.Surface;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewTreeObserver;
-import android.view.ViewTreeObserver.InternalInsetsInfo;
-import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
-import android.view.WindowInsets;
-import android.view.WindowInsets.Type.InsetsType;
-import android.view.WindowInsetsController.Appearance;
-import android.view.WindowInsetsController.Behavior;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.inputmethod.InputMethodManager;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity;
-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.LetterboxDetails;
-import com.android.internal.util.LatencyTracker;
-import com.android.internal.view.AppearanceRegion;
-import com.android.systemui.Gefingerpoken;
-import com.android.systemui.assist.AssistManager;
-import com.android.systemui.dagger.qualifiers.Background;
-import com.android.systemui.dagger.qualifiers.DisplayId;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.keyguard.WakefulnessLifecycle;
-import com.android.systemui.model.SysUiState;
-import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope;
-import com.android.systemui.navigationbar.NavigationModeController.ModeChangedListener;
-import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
-import com.android.systemui.navigationbar.buttons.DeadZone;
-import com.android.systemui.navigationbar.buttons.KeyButtonView;
-import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
-import com.android.systemui.navigationbar.gestural.QuickswitchOrientedNavHandle;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.recents.OverviewProxyService;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.res.R;
-import com.android.systemui.settings.DisplayTracker;
-import com.android.systemui.settings.UserContextProvider;
-import com.android.systemui.settings.UserTracker;
-import com.android.systemui.shade.ShadeViewController;
-import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor;
-import com.android.systemui.shared.navigationbar.RegionSamplingHelper;
-import com.android.systemui.shared.recents.utilities.Utilities;
-import com.android.systemui.shared.rotation.RotationButtonController;
-import com.android.systemui.shared.system.QuickStepContract;
-import com.android.systemui.shared.system.SysUiStatsLog;
-import com.android.systemui.shared.system.TaskStackChangeListener;
-import com.android.systemui.shared.system.TaskStackChangeListeners;
-import com.android.systemui.statusbar.AutoHideUiElement;
-import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.CommandQueue.Callbacks;
-import com.android.systemui.statusbar.NotificationRemoteInputManager;
-import com.android.systemui.statusbar.NotificationShadeDepthController;
-import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
-import com.android.systemui.statusbar.phone.AutoHideController;
-import com.android.systemui.statusbar.phone.BarTransitions;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
-import com.android.systemui.statusbar.phone.LightBarController;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.util.DeviceConfigProxy;
-import com.android.systemui.util.ViewController;
-import com.android.wm.shell.back.BackAnimation;
-import com.android.wm.shell.pip.Pip;
-
-import dagger.Lazy;
-
-import java.io.PrintWriter;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.Executor;
-
-import javax.inject.Inject;
-
-/**
- * Contains logic for a navigation bar view.
- */
-@NavigationBarScope
-public class NavigationBar extends ViewController<NavigationBarView> implements Callbacks {
-
-    public static final String TAG = "NavigationBar";
-    private static final boolean DEBUG = false;
-    private static final String EXTRA_DISABLE_STATE = "disabled_state";
-    private static final String EXTRA_DISABLE2_STATE = "disabled2_state";
-    private static final String EXTRA_APPEARANCE = "appearance";
-    private static final String EXTRA_BEHAVIOR = "behavior";
-    private static final String EXTRA_TRANSIENT_STATE = "transient_state";
-
-    /** Allow some time inbetween the long press for back and recents. */
-    private static final int LOCK_TO_APP_GESTURE_TOLERANCE = 200;
-    private static final long AUTODIM_TIMEOUT_MS = 2250;
-    private static final float QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON = 3f;
-
-    private final Context mContext;
-    private final Bundle mSavedState;
-    private final WindowManager mWindowManager;
-    private final AccessibilityManager mAccessibilityManager;
-    private final DeviceProvisionedController mDeviceProvisionedController;
-    private final StatusBarStateController mStatusBarStateController;
-    private final MetricsLogger mMetricsLogger;
-    private final Lazy<AssistManager> mAssistManagerLazy;
-    private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
-    private final SysUiState mSysUiFlagsContainer;
-    private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
-    private final KeyguardStateController mKeyguardStateController;
-    private final ShadeViewController mShadeViewController;
-    private final PanelExpansionInteractor mPanelExpansionInteractor;
-    private final NotificationRemoteInputManager mNotificationRemoteInputManager;
-    private final OverviewProxyService mOverviewProxyService;
-    private final NavigationModeController mNavigationModeController;
-    private final UserTracker mUserTracker;
-    private final CommandQueue mCommandQueue;
-    private final Optional<Pip> mPipOptional;
-    private final Optional<Recents> mRecentsOptional;
-    private final DeviceConfigProxy mDeviceConfigProxy;
-    private final NavigationBarTransitions mNavigationBarTransitions;
-    private final Optional<BackAnimation> mBackAnimation;
-    private final Handler mHandler;
-    private final UiEventLogger mUiEventLogger;
-    private final NavBarHelper mNavBarHelper;
-    private final NotificationShadeDepthController mNotificationShadeDepthController;
-    private final OnComputeInternalInsetsListener mOnComputeInternalInsetsListener;
-    private final UserContextProvider mUserContextProvider;
-    private final WakefulnessLifecycle mWakefulnessLifecycle;
-    private final DisplayTracker mDisplayTracker;
-    private final RegionSamplingHelper mRegionSamplingHelper;
-    private final int mNavColorSampleMargin;
-    private EdgeBackGestureHandler mEdgeBackGestureHandler;
-    private NavigationBarFrame mFrame;
-    private MotionEvent mCurrentDownEvent;
-
-    private @WindowVisibleState int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
-
-    private int mNavigationIconHints = 0;
-    private @TransitionMode int mTransitionMode;
-    private boolean mLongPressHomeEnabled;
-
-    private int mDisabledFlags1;
-    private int mDisabledFlags2;
-    private long mLastLockToAppLongPress;
-
-    private Locale mLocale;
-    private int mLayoutDirection;
-
-    private Optional<Long> mHomeButtonLongPressDurationMs;
-    private Optional<Long> mOverrideHomeButtonLongPressDurationMs = Optional.empty();
-    private Optional<Float> mOverrideHomeButtonLongPressSlopMultiplier = Optional.empty();
-    private boolean mHomeButtonLongPressHapticEnabled = true;
-
-    /** @see android.view.WindowInsetsController#setSystemBarsAppearance(int, int) */
-    private @Appearance int mAppearance;
-
-    /** @see android.view.WindowInsetsController#setSystemBarsBehavior(int) */
-    private @Behavior int mBehavior;
-
-    private boolean mTransientShown;
-    private boolean mTransientShownFromGestureOnSystemBar;
-    private int mNavBarMode = NAV_BAR_MODE_3BUTTON;
-    private LightBarController mLightBarController;
-    private final LightBarController mMainLightBarController;
-    private final LightBarController.Factory mLightBarControllerFactory;
-    private AutoHideController mAutoHideController;
-    private final AutoHideController mMainAutoHideController;
-    private final AutoHideController.Factory mAutoHideControllerFactory;
-    private final Optional<TelecomManager> mTelecomManagerOptional;
-    private final InputMethodManager mInputMethodManager;
-    private final TaskStackChangeListeners mTaskStackChangeListeners;
-
-    @VisibleForTesting
-    public int mDisplayId;
-    private boolean mIsOnDefaultDisplay;
-    private boolean mHomeBlockedThisTouch;
-
-    /**
-     * When user is QuickSwitching between apps of different orientations, we'll draw a fake
-     * home handle on the orientation they originally touched down to start their swipe
-     * gesture to indicate to them that they can continue in that orientation without having to
-     * rotate the phone
-     * The secondary handle will show when we get
-     * {@link OverviewProxyListener#notifyPrioritizedRotation(int)} callback with the
-     * original handle hidden and we'll flip the visibilities once the
-     * {@link #mTasksFrozenListener} fires
-     */
-    private QuickswitchOrientedNavHandle mOrientationHandle;
-    private WindowManager.LayoutParams mOrientationParams;
-    private int mStartingQuickSwitchRotation = -1;
-    private int mCurrentRotation;
-    private ViewTreeObserver.OnGlobalLayoutListener mOrientationHandleGlobalLayoutListener;
-    private boolean mShowOrientedHandleForImmersiveMode;
-    private final DeadZone mDeadZone;
-    private boolean mImeVisible;
-    private final Rect mSamplingBounds = new Rect();
-    private final Binder mInsetsSourceOwner = new Binder();
-    private final NavBarButtonClickLogger mNavBarButtonClickLogger;
-    private final NavbarOrientationTrackingLogger mNavbarOrientationTrackingLogger;
-
-    /**
-     * When quickswitching between apps of different orientations, we draw a secondary home handle
-     * in the position of the first app's orientation. This rect represents the region of that
-     * home handle so we can apply the correct light/dark luma on that.
-     * @see {@link NavigationBar#mOrientationHandle}
-     */
-    @android.annotation.Nullable
-    private Rect mOrientedHandleSamplingRegion;
-
-    @com.android.internal.annotations.VisibleForTesting
-    public enum NavBarActionEvent implements UiEventLogger.UiEventEnum {
-
-        @UiEvent(doc = "Assistant invoked via home button long press.")
-        NAVBAR_ASSIST_LONGPRESS(550);
-
-        private final int mId;
-
-        NavBarActionEvent(int id) {
-            mId = id;
-        }
-
-        @Override
-        public int getId() {
-            return mId;
-        }
-    }
-
-    private final AutoHideUiElement mAutoHideUiElement = new AutoHideUiElement() {
-        @Override
-        public void synchronizeState() {
-            checkNavBarModes();
-        }
-
-        @Override
-        public boolean shouldHideOnTouch() {
-            return !mNotificationRemoteInputManager.isRemoteInputActive();
-        }
-
-        @Override
-        public boolean isVisible() {
-            return isTransientShown();
-        }
-
-        @Override
-        public void hide() {
-            clearTransient();
-        }
-    };
-
-    private final NavBarHelper.NavbarTaskbarStateUpdater mNavbarTaskbarStateUpdater =
-            new NavBarHelper.NavbarTaskbarStateUpdater() {
-                @Override
-                public void updateAccessibilityServicesState() {
-                    updateAccessibilityStateFlags();
-                }
-
-                @Override
-                public void updateAssistantAvailable(boolean available,
-                        boolean longPressHomeEnabled) {
-                    // TODO(b/198002034): Content observers currently can still be called back after
-                    //  being unregistered, and in this case we can ignore the change if the nav bar
-                    //  has been destroyed already
-                    if (mView == null) {
-                        return;
-                    }
-                    mLongPressHomeEnabled = longPressHomeEnabled;
-                    updateAssistantEntrypoints(available, longPressHomeEnabled);
-                }
-
-                @Override
-                public void updateWallpaperVisibility(boolean visible, int displayId) {
-                    mNavigationBarTransitions.setWallpaperVisibility(visible);
-                }
-
-                @Override
-                public void updateRotationWatcherState(int rotation) {
-                    if (mIsOnDefaultDisplay && mView != null) {
-                        mView.getRotationButtonController().onRotationWatcherChanged(rotation);
-                        if (mView.needsReorient(rotation)) {
-                            repositionNavigationBar(rotation);
-                        }
-                    }
-                }
-            };
-
-    private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() {
-        @Override
-        public void onConnectionChanged(boolean isConnected) {
-            mView.onOverviewProxyConnectionChange(
-                    mOverviewProxyService.isEnabled());
-            mView.setShouldShowSwipeUpUi(mOverviewProxyService.shouldShowSwipeUpUI());
-            updateScreenPinningGestures();
-        }
-
-        @Override
-        public void onPrioritizedRotation(@Surface.Rotation int rotation) {
-            mStartingQuickSwitchRotation = rotation;
-            if (rotation == -1) {
-                mShowOrientedHandleForImmersiveMode = false;
-            }
-            orientSecondaryHomeHandle();
-        }
-
-        @Override
-        public void startAssistant(Bundle bundle) {
-            mAssistManagerLazy.get().startAssist(bundle);
-        }
-
-        @Override
-        public void setAssistantOverridesRequested(int[] invocationTypes) {
-            mAssistManagerLazy.get().setAssistantOverridesRequested(invocationTypes);
-        }
-
-        @Override
-        public void animateNavBarLongPress(boolean isTouchDown, boolean shrink, long durationMs) {
-            mView.getHomeHandle().animateLongPress(isTouchDown, shrink, durationMs);
-        }
-
-        @Override
-        public void setOverrideHomeButtonLongPress(long duration, float slopMultiplier,
-                boolean haptic) {
-            Log.d(TAG, "setOverrideHomeButtonLongPress receives: " + duration + ";"
-                    + slopMultiplier + ";" + haptic);
-            mOverrideHomeButtonLongPressDurationMs = Optional.of(duration)
-                    .filter(value -> value > 0);
-            mOverrideHomeButtonLongPressSlopMultiplier = Optional.of(slopMultiplier)
-                    .filter(value -> value > 0);
-            mHomeButtonLongPressHapticEnabled = haptic;
-            mOverrideHomeButtonLongPressDurationMs.ifPresent(aLong
-                    -> Log.d(TAG, "Use duration override: " + aLong));
-            mOverrideHomeButtonLongPressSlopMultiplier.ifPresent(aFloat
-                    -> Log.d(TAG, "Use slop multiplier override: " + aFloat));
-            if (mView != null) {
-                reconfigureHomeLongClick();
-            }
-        }
-
-        @Override
-        public void onHomeRotationEnabled(boolean enabled) {
-            mView.getRotationButtonController().setHomeRotationEnabled(enabled);
-        }
-
-        @Override
-        public void onOverviewShown(boolean fromHome) {
-            // If the overview has fixed orientation that may change display to natural rotation,
-            // we don't want the user rotation to be reset. So after user returns to application,
-            // it can keep in the original rotation.
-            mView.getRotationButtonController().setSkipOverrideUserLockPrefsOnce();
-        }
-
-        @Override
-        public void onTaskbarStatusUpdated(boolean visible, boolean stashed) {
-            mView.getFloatingRotationButton().onTaskbarStateChanged(visible, stashed);
-        }
-
-        @Override
-        public void onToggleRecentApps() {
-            // The same case as onOverviewShown but only for 3-button navigation.
-            mView.getRotationButtonController().setSkipOverrideUserLockPrefsOnce();
-        }
-    };
-
-    private NavigationBarTransitions.DarkIntensityListener mOrientationHandleIntensityListener =
-            new NavigationBarTransitions.DarkIntensityListener() {
-                @Override
-                public void onDarkIntensity(float darkIntensity) {
-                    mOrientationHandle.setDarkIntensity(darkIntensity);
-                }
-            };
-
-    private final Runnable mAutoDim = () -> getBarTransitions().setAutoDim(true);
-    private final Runnable mEnableLayoutTransitions = () -> mView.setLayoutTransitionsEnabled(true);
-    private final Runnable mOnVariableDurationHomeLongClick = () -> {
-        if (onHomeLongClick(mView.getHomeButton().getCurrentView())) {
-            if (mHomeButtonLongPressHapticEnabled) {
-                mView.getHomeButton().getCurrentView().performHapticFeedback(
-                        HapticFeedbackConstants.LONG_PRESS,
-                        HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
-            }
-        }
-    };
-
-    private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener =
-            new DeviceConfig.OnPropertiesChangedListener() {
-                @Override
-                public void onPropertiesChanged(DeviceConfig.Properties properties) {
-                    if (properties.getKeyset().contains(HOME_BUTTON_LONG_PRESS_DURATION_MS)) {
-                        mHomeButtonLongPressDurationMs = Optional.of(
-                            properties.getLong(HOME_BUTTON_LONG_PRESS_DURATION_MS, 0))
-                                .filter(duration -> duration != 0);
-                        if (mView != null) {
-                            reconfigureHomeLongClick();
-                        }
-                    }
-                }
-            };
-
-    private final NotificationShadeDepthController.DepthListener mDepthListener =
-            new NotificationShadeDepthController.DepthListener() {
-                boolean mHasBlurs;
-
-                @Override
-                public void onWallpaperZoomOutChanged(float zoomOut) {
-                }
-
-                @Override
-                public void onBlurRadiusChanged(int radius) {
-                    boolean hasBlurs = radius != 0;
-                    if (hasBlurs == mHasBlurs) {
-                        return;
-                    }
-                    mHasBlurs = hasBlurs;
-                    mRegionSamplingHelper.setWindowHasBlurs(hasBlurs);
-                }
-            };
-
-    private final WakefulnessLifecycle.Observer mWakefulnessObserver =
-            new WakefulnessLifecycle.Observer() {
-                private void notifyScreenStateChanged(boolean isScreenOn) {
-                    notifyNavigationBarScreenOn();
-                    mView.onScreenStateChanged(isScreenOn);
-                }
-
-                @Override
-                public void onStartedWakingUp() {
-                    notifyScreenStateChanged(true);
-                    if (isGesturalModeOnDefaultDisplay(getContext(), mDisplayTracker,
-                            mNavBarMode)) {
-                        mRegionSamplingHelper.start(mSamplingBounds);
-                    }
-                }
-
-                @Override
-                public void onFinishedGoingToSleep() {
-                    notifyScreenStateChanged(false);
-                    mRegionSamplingHelper.stop();
-                }
-            };
-
-    private boolean mScreenPinningActive = false;
-    private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
-        @Override
-        public void onLockTaskModeChanged(int mode) {
-            mScreenPinningActive = (mode == LOCK_TASK_MODE_PINNED);
-            mSysUiFlagsContainer.setFlag(SYSUI_STATE_SCREEN_PINNING, mScreenPinningActive)
-                    .commitUpdate(mDisplayId);
-            mView.setInScreenPinning(mScreenPinningActive);
-            updateScreenPinningGestures();
-        }
-    };
-
-    @Inject
-    NavigationBar(
-            NavigationBarView navigationBarView,
-            NavigationBarFrame navigationBarFrame,
-            @Nullable Bundle savedState,
-            @DisplayId Context context,
-            @DisplayId WindowManager windowManager,
-            Lazy<AssistManager> assistManagerLazy,
-            AccessibilityManager accessibilityManager,
-            DeviceProvisionedController deviceProvisionedController,
-            MetricsLogger metricsLogger,
-            OverviewProxyService overviewProxyService,
-            NavigationModeController navigationModeController,
-            StatusBarStateController statusBarStateController,
-            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
-            SysUiState sysUiFlagsContainer,
-            UserTracker userTracker,
-            CommandQueue commandQueue,
-            Optional<Pip> pipOptional,
-            Optional<Recents> recentsOptional,
-            Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
-            KeyguardStateController keyguardStateController,
-            ShadeViewController shadeViewController,
-            PanelExpansionInteractor panelExpansionInteractor,
-            NotificationRemoteInputManager notificationRemoteInputManager,
-            NotificationShadeDepthController notificationShadeDepthController,
-            @Main Handler mainHandler,
-            @Main Executor mainExecutor,
-            @Background Executor bgExecutor,
-            UiEventLogger uiEventLogger,
-            NavBarHelper navBarHelper,
-            LightBarController mainLightBarController,
-            LightBarController.Factory lightBarControllerFactory,
-            AutoHideController mainAutoHideController,
-            AutoHideController.Factory autoHideControllerFactory,
-            Optional<TelecomManager> telecomManagerOptional,
-            InputMethodManager inputMethodManager,
-            DeadZone deadZone,
-            DeviceConfigProxy deviceConfigProxy,
-            NavigationBarTransitions navigationBarTransitions,
-            Optional<BackAnimation> backAnimation,
-            UserContextProvider userContextProvider,
-            WakefulnessLifecycle wakefulnessLifecycle,
-            TaskStackChangeListeners taskStackChangeListeners,
-            DisplayTracker displayTracker,
-            NavBarButtonClickLogger navBarButtonClickLogger,
-            NavbarOrientationTrackingLogger navbarOrientationTrackingLogger) {
-        super(navigationBarView);
-        mFrame = navigationBarFrame;
-        mContext = context;
-        mSavedState = savedState;
-        mWindowManager = windowManager;
-        mAccessibilityManager = accessibilityManager;
-        mDeviceProvisionedController = deviceProvisionedController;
-        mStatusBarStateController = statusBarStateController;
-        mMetricsLogger = metricsLogger;
-        mAssistManagerLazy = assistManagerLazy;
-        mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
-        mSysUiFlagsContainer = sysUiFlagsContainer;
-        mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
-        mKeyguardStateController = keyguardStateController;
-        mShadeViewController = shadeViewController;
-        mPanelExpansionInteractor = panelExpansionInteractor;
-        mNotificationRemoteInputManager = notificationRemoteInputManager;
-        mOverviewProxyService = overviewProxyService;
-        mNavigationModeController = navigationModeController;
-        mUserTracker = userTracker;
-        mCommandQueue = commandQueue;
-        mPipOptional = pipOptional;
-        mRecentsOptional = recentsOptional;
-        mDeadZone = deadZone;
-        mDeviceConfigProxy = deviceConfigProxy;
-        mNavigationBarTransitions = navigationBarTransitions;
-        mBackAnimation = backAnimation;
-        mHandler = mainHandler;
-        mUiEventLogger = uiEventLogger;
-        mNavBarHelper = navBarHelper;
-        mNotificationShadeDepthController = notificationShadeDepthController;
-        mMainLightBarController = mainLightBarController;
-        mLightBarControllerFactory = lightBarControllerFactory;
-        mMainAutoHideController = mainAutoHideController;
-        mAutoHideControllerFactory = autoHideControllerFactory;
-        mTelecomManagerOptional = telecomManagerOptional;
-        mInputMethodManager = inputMethodManager;
-        mUserContextProvider = userContextProvider;
-        mWakefulnessLifecycle = wakefulnessLifecycle;
-        mTaskStackChangeListeners = taskStackChangeListeners;
-        mDisplayTracker = displayTracker;
-        mEdgeBackGestureHandler = navBarHelper.getEdgeBackGestureHandler();
-        mNavBarButtonClickLogger = navBarButtonClickLogger;
-        mNavbarOrientationTrackingLogger = navbarOrientationTrackingLogger;
-
-        mNavColorSampleMargin = getResources()
-                .getDimensionPixelSize(R.dimen.navigation_handle_sample_horizontal_margin);
-
-        mOnComputeInternalInsetsListener = info -> {
-            // When the nav bar is in 2-button or 3-button mode, or when IME is visible in fully
-            // gestural mode, the entire nav bar should be touchable.
-            if (!mEdgeBackGestureHandler.isHandlingGestures()) {
-                // We're in 2/3 button mode OR back button force-shown in SUW
-                if (!mImeVisible) {
-                    // IME not showing, take all touches
-                    info.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
-                    return;
-                }
-                if (!mView.isImeRenderingNavButtons()) {
-                    // IME showing but not drawing any buttons, take all touches
-                    info.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
-                    return;
-                }
-            }
-
-            // When in gestural and the IME is showing, don't use the nearest region since it will
-            // take gesture space away from the IME
-            info.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
-            info.touchableRegion.set(
-                    getButtonLocations(false /* inScreen */, false /* useNearestRegion */));
-        };
-
-        mRegionSamplingHelper = new RegionSamplingHelper(mView,
-                new RegionSamplingHelper.SamplingCallback() {
-                    @Override
-                    public void onRegionDarknessChanged(boolean isRegionDark) {
-                        getBarTransitions().getLightTransitionsController().setIconsDark(
-                                !isRegionDark, true /* animate */);
-                    }
-
-                    @Override
-                    public Rect getSampledRegion(View sampledView) {
-                        if (mOrientedHandleSamplingRegion != null) {
-                            return mOrientedHandleSamplingRegion;
-                        }
-
-                        return calculateSamplingRect();
-                    }
-
-                    @Override
-                    public boolean isSamplingEnabled() {
-                        return isGesturalModeOnDefaultDisplay(getContext(), mDisplayTracker,
-                                mNavBarMode);
-                    }
-                }, mainExecutor, bgExecutor);
-
-        mView.setBackgroundExecutor(bgExecutor);
-        mView.setEdgeBackGestureHandler(mEdgeBackGestureHandler);
-        mView.setDisplayTracker(mDisplayTracker);
-        mNavBarMode = mNavigationModeController.addListener(mModeChangedListener);
-    }
-
-    public NavigationBarView getView() {
-        return mView;
-    }
-
-    @Override
-    public void onInit() {
-        // TODO: A great deal of this code should probably live in onViewAttached.
-        // It should also has corresponding cleanup in onViewDetached.
-        mView.setBarTransitions(mNavigationBarTransitions);
-        mView.setTouchHandler(mTouchHandler);
-        setNavBarMode(mNavBarMode);
-        mEdgeBackGestureHandler.setStateChangeCallback(mView::updateStates);
-        mEdgeBackGestureHandler.setButtonForcedVisibleChangeCallback((forceVisible) -> {
-            repositionNavigationBar(mCurrentRotation);
-        });
-        mNavigationBarTransitions.addListener(this::onBarTransition);
-        mView.updateRotationButton();
-
-        mView.setVisibility(
-                mStatusBarKeyguardViewManager.isNavBarVisible() ? View.VISIBLE : View.INVISIBLE);
-
-        if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mView);
-
-        mWindowManager.addView(mFrame,
-                getBarLayoutParams(mContext.getResources().getConfiguration().windowConfiguration
-                        .getRotation()));
-        mDisplayId = mContext.getDisplayId();
-        mIsOnDefaultDisplay = mDisplayId == mDisplayTracker.getDefaultDisplayId();
-
-        // Ensure we try to get currentSysuiState from navBarHelper before command queue callbacks
-        // start firing, since the latter is source of truth
-        parseCurrentSysuiState();
-        mCommandQueue.addCallback(this);
-        mHomeButtonLongPressDurationMs = Optional.of(mDeviceConfigProxy.getLong(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                HOME_BUTTON_LONG_PRESS_DURATION_MS,
-                /* defaultValue = */ 0
-        )).filter(duration -> duration != 0);
-        // This currently MUST be called after mHomeButtonLongPressDurationMs is initialized since
-        // the registration callbacks will trigger code that uses it
-        mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
-        mDeviceConfigProxy.addOnPropertiesChangedListener(
-                DeviceConfig.NAMESPACE_SYSTEMUI, mHandler::post, mOnPropertiesChangedListener);
-
-        if (mSavedState != null) {
-            mDisabledFlags1 = mSavedState.getInt(EXTRA_DISABLE_STATE, 0);
-            mDisabledFlags2 = mSavedState.getInt(EXTRA_DISABLE2_STATE, 0);
-            mAppearance = mSavedState.getInt(EXTRA_APPEARANCE, 0);
-            mBehavior = mSavedState.getInt(EXTRA_BEHAVIOR, 0);
-            mTransientShown = mSavedState.getBoolean(EXTRA_TRANSIENT_STATE, false);
-        }
-
-        // Respect the latest disabled-flags.
-        mCommandQueue.recomputeDisableFlags(mDisplayId, false);
-
-        mNotificationShadeDepthController.addListener(mDepthListener);
-        mTaskStackChangeListeners.registerTaskStackListener(mTaskStackListener);
-    }
-
-    public void destroyView() {
-        Trace.beginSection("NavigationBar#destroyView");
-        try {
-            setAutoHideController(/* autoHideController */ null);
-            mCommandQueue.removeCallback(this);
-            Trace.beginSection("NavigationBar#removeViewImmediate");
-            try {
-                mWindowManager.removeViewImmediate(mView.getRootView());
-            } finally {
-                Trace.endSection();
-            }
-            mNavigationModeController.removeListener(mModeChangedListener);
-            mEdgeBackGestureHandler.setStateChangeCallback(null);
-
-            mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
-            mNotificationShadeDepthController.removeListener(mDepthListener);
-
-            mDeviceConfigProxy.removeOnPropertiesChangedListener(mOnPropertiesChangedListener);
-            mTaskStackChangeListeners.unregisterTaskStackListener(mTaskStackListener);
-        } finally {
-            Trace.endSection();
-        }
-    }
-
-    @Override
-    public void onViewAttached() {
-        final Display display = mView.getDisplay();
-        mView.setComponents(mRecentsOptional);
-        if (mCentralSurfacesOptionalLazy.get().isPresent()) {
-            mView.setComponents(mShadeViewController, mPanelExpansionInteractor);
-        }
-        mView.setDisabledFlags(mDisabledFlags1, mSysUiFlagsContainer);
-        mView.setOnVerticalChangedListener(this::onVerticalChanged);
-        mView.setOnTouchListener(this::onNavigationTouch);
-        if (mSavedState != null) {
-            getBarTransitions().getLightTransitionsController().restoreState(mSavedState);
-        }
-        setNavigationIconHints(mNavigationIconHints);
-        setWindowVisible(isNavBarWindowVisible());
-        mView.setBehavior(mBehavior);
-        setNavBarMode(mNavBarMode);
-        repositionNavigationBar(mCurrentRotation);
-        mView.setUpdateActiveTouchRegionsCallback(
-                () -> mOverviewProxyService.onActiveNavBarRegionChanges(
-                        getButtonLocations(true /* inScreen */, true /* useNearestRegion */)));
-
-        mView.getViewTreeObserver().addOnComputeInternalInsetsListener(
-                mOnComputeInternalInsetsListener);
-
-        mPipOptional.ifPresent(mView::addPipExclusionBoundsChangeListener);
-        mBackAnimation.ifPresent(mView::registerBackAnimation);
-
-        prepareNavigationBarView();
-        checkNavBarModes();
-
-        mUserTracker.addCallback(mUserChangedCallback, mContext.getMainExecutor());
-        mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
-        notifyNavigationBarScreenOn();
-
-        mOverviewProxyService.addCallback(mOverviewProxyListener);
-        updateSystemUiStateFlags();
-
-        // Currently there is no accelerometer sensor on non-default display.
-        if (mIsOnDefaultDisplay) {
-            final RotationButtonController rotationButtonController =
-                    mView.getRotationButtonController();
-
-            // Reset user rotation pref to match that of the WindowManager if starting in locked
-            // mode. This will automatically happen when switching from auto-rotate to locked mode.
-            if (display != null && rotationButtonController.isRotationLocked()) {
-                rotationButtonController.setRotationLockedAtAngle(
-                        display.getRotation(), /* caller= */ "NavigationBar#onViewAttached");
-            }
-        } else {
-            mDisabledFlags2 |= StatusBarManager.DISABLE2_ROTATE_SUGGESTIONS;
-        }
-        setDisabled2Flags(mDisabledFlags2);
-
-        initSecondaryHomeHandleForRotation();
-
-        // Unfortunately, we still need it because status bar needs LightBarController
-        // before notifications creation. We cannot directly use getLightBarController()
-        // from NavigationBarFragment directly.
-        LightBarController lightBarController = mIsOnDefaultDisplay
-                ? mMainLightBarController : mLightBarControllerFactory.create(mContext);
-        setLightBarController(lightBarController);
-
-        // TODO(b/118592525): to support multi-display, we start to add something which is
-        //                    per-display, while others may be global. I think it's time to
-        //                    add a new class maybe named DisplayDependency to solve
-        //                    per-display Dependency problem.
-        // Alternative: this is a good case for a Dagger subcomponent. Same with LightBarController.
-        AutoHideController autoHideController = mIsOnDefaultDisplay
-                ? mMainAutoHideController : mAutoHideControllerFactory.create(mContext);
-        setAutoHideController(autoHideController);
-        restoreAppearanceAndTransientState();
-    }
-
-    @Override
-    public void onViewDetached() {
-        mView.setUpdateActiveTouchRegionsCallback(null);
-        getBarTransitions().destroy();
-        mOverviewProxyService.removeCallback(mOverviewProxyListener);
-        mUserTracker.removeCallback(mUserChangedCallback);
-        mWakefulnessLifecycle.removeObserver(mWakefulnessObserver);
-        if (mOrientationHandle != null) {
-            resetSecondaryHandle();
-            getBarTransitions().removeDarkIntensityListener(mOrientationHandleIntensityListener);
-            mWindowManager.removeView(mOrientationHandle);
-            mOrientationHandle.getViewTreeObserver().removeOnGlobalLayoutListener(
-                    mOrientationHandleGlobalLayoutListener);
-        }
-        mView.getViewTreeObserver().removeOnComputeInternalInsetsListener(
-                mOnComputeInternalInsetsListener);
-        mHandler.removeCallbacks(mAutoDim);
-        mHandler.removeCallbacks(mOnVariableDurationHomeLongClick);
-        mHandler.removeCallbacks(mEnableLayoutTransitions);
-        mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
-        mPipOptional.ifPresent(mView::removePipExclusionBoundsChangeListener);
-        mFrame = null;
-        mOrientationHandle = null;
-    }
-
-    // TODO: Remove this when we update nav bar recreation
-    public void onSaveInstanceState(Bundle outState) {
-        outState.putInt(EXTRA_DISABLE_STATE, mDisabledFlags1);
-        outState.putInt(EXTRA_DISABLE2_STATE, mDisabledFlags2);
-        outState.putInt(EXTRA_APPEARANCE, mAppearance);
-        outState.putInt(EXTRA_BEHAVIOR, mBehavior);
-        outState.putBoolean(EXTRA_TRANSIENT_STATE, mTransientShown);
-        getBarTransitions().getLightTransitionsController().saveState(outState);
-    }
-
-    /**
-     * Called when a non-reloading configuration change happens and we need to update.
-     */
-    public void onConfigurationChanged(Configuration newConfig) {
-        final int rotation = newConfig.windowConfiguration.getRotation();
-        final Locale locale = mContext.getResources().getConfiguration().locale;
-        final int ld = TextUtils.getLayoutDirectionFromLocale(locale);
-        if (!locale.equals(mLocale) || ld != mLayoutDirection) {
-            if (DEBUG) {
-                Log.v(TAG, String.format(
-                        "config changed locale/LD: %s (%d) -> %s (%d)", mLocale, mLayoutDirection,
-                        locale, ld));
-            }
-            mLocale = locale;
-            mLayoutDirection = ld;
-            refreshLayout(ld);
-        }
-        repositionNavigationBar(rotation);
-        if (canShowSecondaryHandle()) {
-            if (rotation != mCurrentRotation) {
-                mCurrentRotation = rotation;
-                orientSecondaryHomeHandle();
-            }
-        }
-    }
-
-    private void initSecondaryHomeHandleForRotation() {
-        if (mNavBarMode != NAV_BAR_MODE_GESTURAL) {
-            return;
-        }
-
-        mOrientationHandle = new QuickswitchOrientedNavHandle(mContext);
-        mOrientationHandle.setId(R.id.secondary_home_handle);
-
-        getBarTransitions().addDarkIntensityListener(mOrientationHandleIntensityListener);
-        mOrientationParams = new WindowManager.LayoutParams(0, 0,
-                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
-                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                        | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-                        | WindowManager.LayoutParams.FLAG_SLIPPERY,
-                PixelFormat.TRANSLUCENT);
-        mOrientationParams.setTitle("SecondaryHomeHandle" + mContext.getDisplayId());
-        mOrientationParams.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION
-                | WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
-        mWindowManager.addView(mOrientationHandle, mOrientationParams);
-        mOrientationHandle.setVisibility(View.GONE);
-
-        logNavbarOrientation("initSecondaryHomeHandleForRotation");
-        mOrientationParams.setFitInsetsTypes(0 /* types*/);
-        mOrientationHandleGlobalLayoutListener =
-                () -> {
-                    if (mStartingQuickSwitchRotation == -1) {
-                        return;
-                    }
-
-                    RectF boundsOnScreen = mOrientationHandle.computeHomeHandleBounds();
-                    mOrientationHandle.mapRectFromViewToScreenCoords(boundsOnScreen, true);
-                    Rect boundsRounded = new Rect();
-                    boundsOnScreen.roundOut(boundsRounded);
-                    setOrientedHandleSamplingRegion(boundsRounded);
-                };
-        mOrientationHandle.getViewTreeObserver().addOnGlobalLayoutListener(
-                mOrientationHandleGlobalLayoutListener);
-    }
-
-    private void orientSecondaryHomeHandle() {
-        if (!canShowSecondaryHandle()) {
-            return;
-        }
-
-        if (mStartingQuickSwitchRotation == -1) {
-            resetSecondaryHandle();
-        } else {
-            int deltaRotation = deltaRotation(mCurrentRotation, mStartingQuickSwitchRotation);
-            if (mStartingQuickSwitchRotation == -1 || deltaRotation == -1) {
-                // Curious if starting quickswitch can change between the if check and our delta
-                Log.d(TAG, "secondary nav delta rotation: " + deltaRotation
-                        + " current: " + mCurrentRotation
-                        + " starting: " + mStartingQuickSwitchRotation);
-            }
-            int height = 0;
-            int width = 0;
-            Rect dispSize = mWindowManager.getCurrentWindowMetrics().getBounds();
-            mOrientationHandle.setDeltaRotation(deltaRotation);
-            switch (deltaRotation) {
-                case Surface.ROTATION_90:
-                case Surface.ROTATION_270:
-                    height = dispSize.height();
-                    width = mView.getHeight();
-                    break;
-                case Surface.ROTATION_180:
-                case Surface.ROTATION_0:
-                    // TODO(b/152683657): Need to determine best UX for this
-                    if (!mShowOrientedHandleForImmersiveMode) {
-                        resetSecondaryHandle();
-                        return;
-                    }
-                    width = dispSize.width();
-                    height = mView.getHeight();
-                    break;
-            }
-
-            mOrientationParams.gravity =
-                    deltaRotation == Surface.ROTATION_0 ? Gravity.BOTTOM :
-                            (deltaRotation == Surface.ROTATION_90 ? Gravity.LEFT : Gravity.RIGHT);
-            mOrientationParams.height = height;
-            mOrientationParams.width = width;
-            mWindowManager.updateViewLayout(mOrientationHandle, mOrientationParams);
-            mView.setVisibility(View.GONE);
-            mOrientationHandle.setVisibility(View.VISIBLE);
-            logNavbarOrientation("orientSecondaryHomeHandle");
-        }
-    }
-
-    private void resetSecondaryHandle() {
-        if (mOrientationHandle != null) {
-            // Case where nav mode is changed w/o ever invoking a quickstep
-            // mOrientedHandle is initialized lazily
-            mOrientationHandle.setVisibility(View.GONE);
-        }
-        mView.setVisibility(View.VISIBLE);
-        logNavbarOrientation("resetSecondaryHandle");
-        setOrientedHandleSamplingRegion(null);
-    }
-
-    /**
-     * Logging method for issues concerning Navbar/secondary handle visibility.
-     */
-    private void logNavbarOrientation(String methodName) {
-        boolean isViewVisible = (mView != null) && (mView.getVisibility() == View.VISIBLE);
-        boolean isSecondaryHandleVisible =
-                (mOrientationHandle != null) && (mOrientationHandle.getVisibility()
-                        == View.VISIBLE);
-        mNavbarOrientationTrackingLogger.logPrimaryAndSecondaryVisibility(methodName, isViewVisible,
-                mShowOrientedHandleForImmersiveMode, isSecondaryHandleVisible, mCurrentRotation,
-                mStartingQuickSwitchRotation);
-    }
-
-    private void parseCurrentSysuiState() {
-        NavBarHelper.CurrentSysuiState state = mNavBarHelper.getCurrentSysuiState();
-        if (state.mWindowStateDisplayId == mDisplayId) {
-            mNavigationBarWindowState = state.mWindowState;
-        }
-    }
-
-    private void reconfigureHomeLongClick() {
-        if (mView.getHomeButton().getCurrentView() == null) {
-            return;
-        }
-        if (mHomeButtonLongPressDurationMs.isPresent()
-                || mOverrideHomeButtonLongPressDurationMs.isPresent()
-                || mOverrideHomeButtonLongPressSlopMultiplier.isPresent()
-                || !mLongPressHomeEnabled) {
-            mView.getHomeButton().getCurrentView().setLongClickable(false);
-            mView.getHomeButton().getCurrentView().setHapticFeedbackEnabled(false);
-            mView.getHomeButton().setOnLongClickListener(null);
-        } else {
-            mView.getHomeButton().getCurrentView().setLongClickable(true);
-            mView.getHomeButton().getCurrentView().setHapticFeedbackEnabled(
-                    mHomeButtonLongPressHapticEnabled);
-            mView.getHomeButton().setOnLongClickListener(this::onHomeLongClick);
-        }
-    }
-
-    private int deltaRotation(int oldRotation, int newRotation) {
-        int delta = newRotation - oldRotation;
-        if (delta < 0) delta += 4;
-        return delta;
-    }
-
-    public void dump(PrintWriter pw) {
-        pw.println("NavigationBar (displayId=" + mDisplayId + "):");
-        pw.println("  mStartingQuickSwitchRotation=" + mStartingQuickSwitchRotation);
-        pw.println("  mCurrentRotation=" + mCurrentRotation);
-        pw.println("  mHomeButtonLongPressDurationMs=" + mHomeButtonLongPressDurationMs);
-        pw.println("  mOverrideHomeButtonLongPressDurationMs="
-                + mOverrideHomeButtonLongPressDurationMs);
-        pw.println("  mOverrideHomeButtonLongPressSlopMultiplier="
-                + mOverrideHomeButtonLongPressSlopMultiplier);
-        pw.println("  mLongPressHomeEnabled=" + mLongPressHomeEnabled);
-        pw.println("  mNavigationBarWindowState="
-                + windowStateToString(mNavigationBarWindowState));
-        pw.println("  mTransitionMode="
-                + BarTransitions.modeToString(mTransitionMode));
-        pw.println("  mTransientShown=" + mTransientShown);
-        pw.println("  mTransientShownFromGestureOnSystemBar="
-                + mTransientShownFromGestureOnSystemBar);
-        pw.println("  mScreenPinningActive=" + mScreenPinningActive);
-        dumpBarTransitions(pw, "mNavigationBarView", getBarTransitions());
-
-        pw.println("  mOrientedHandleSamplingRegion: " + mOrientedHandleSamplingRegion);
-        mView.dump(pw);
-        mRegionSamplingHelper.dump(pw);
-        if (mAutoHideController != null) {
-            mAutoHideController.dump(pw);
-        }
-    }
-
-    // ----- CommandQueue Callbacks -----
-
-    @Override
-    public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
-            boolean showImeSwitcher) {
-        if (displayId != mDisplayId) {
-            return;
-        }
-        boolean imeShown = mNavBarHelper.isImeShown(vis);
-        showImeSwitcher = imeShown && showImeSwitcher;
-        int hints = Utilities.calculateBackDispositionHints(mNavigationIconHints, backDisposition,
-                imeShown, showImeSwitcher);
-        if (hints == mNavigationIconHints) return;
-
-        setNavigationIconHints(hints);
-        checkBarModes();
-        updateSystemUiStateFlags();
-    }
-
-    @Override
-    public void setWindowState(
-            int displayId, @WindowType int window, @WindowVisibleState int state) {
-        if (displayId == mDisplayId
-                && window == StatusBarManager.WINDOW_NAVIGATION_BAR
-                && mNavigationBarWindowState != state) {
-            mNavigationBarWindowState = state;
-            updateSystemUiStateFlags();
-            mShowOrientedHandleForImmersiveMode = state == WINDOW_STATE_HIDDEN;
-            if (mOrientationHandle != null
-                    && mStartingQuickSwitchRotation != -1) {
-                orientSecondaryHomeHandle();
-            }
-            if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
-            setWindowVisible(isNavBarWindowVisible());
-        }
-    }
-
-    @Override
-    public void onRotationProposal(final int rotation, boolean isValid) {
-        // The CommandQueue callbacks are added when the view is created to ensure we track other
-        // states, but until the view is attached (at the next traversal), the view's display is
-        // not valid.  Just ignore the rotation in this case.
-        if (!mView.isAttachedToWindow()) return;
-
-        final boolean rotateSuggestionsDisabled = RotationButtonController
-                .hasDisable2RotateSuggestionFlag(mDisabledFlags2);
-        final RotationButtonController rotationButtonController =
-                mView.getRotationButtonController();
-        if (DEBUG_ROTATION) {
-            Log.v(TAG, "onRotationProposal proposedRotation=" + Surface.rotationToString(rotation)
-                    + ", isValid=" + isValid + ", mNavBarWindowState="
-                    + StatusBarManager.windowStateToString(mNavigationBarWindowState)
-                    + ", rotateSuggestionsDisabled=" + rotateSuggestionsDisabled
-                    + ", isRotateButtonVisible="
-                    + rotationButtonController.getRotationButton().isVisible());
-        }
-        // Respect the disabled flag, no need for action as flag change callback will handle hiding
-        if (rotateSuggestionsDisabled) return;
-
-        rotationButtonController.onRotationProposal(rotation, isValid);
-    }
-
-    @Override
-    public void onRecentsAnimationStateChanged(boolean running) {
-        mView.getRotationButtonController().setRecentsAnimationRunning(running);
-    }
-
-    /** Restores the appearance and the transient saved state to {@link NavigationBar}. */
-    public void restoreAppearanceAndTransientState() {
-        final int transitionMode = transitionMode(mTransientShown, mAppearance);
-        mTransitionMode = transitionMode;
-        checkNavBarModes();
-        if (mAutoHideController != null) {
-            mAutoHideController.touchAutoHide();
-        }
-        if (mLightBarController != null) {
-            mLightBarController.onNavigationBarAppearanceChanged(mAppearance,
-                    true /* nbModeChanged */, transitionMode, false /* navbarColorManagedByIme */);
-        }
-    }
-
-    @Override
-    public void onSystemBarAttributesChanged(int displayId, @Appearance int appearance,
-            AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme,
-            @Behavior int behavior, @InsetsType int requestedVisibleTypes, String packageName,
-            LetterboxDetails[] letterboxDetails) {
-        if (displayId != mDisplayId) {
-            return;
-        }
-        boolean nbModeChanged = false;
-        if (mAppearance != appearance) {
-            mAppearance = appearance;
-            nbModeChanged = updateTransitionMode(transitionMode(mTransientShown, appearance));
-        }
-        if (mLightBarController != null) {
-            mLightBarController.onNavigationBarAppearanceChanged(appearance, nbModeChanged,
-                    mTransitionMode, navbarColorManagedByIme);
-        }
-        if (mBehavior != behavior) {
-            mBehavior = behavior;
-            mView.setBehavior(behavior);
-            updateSystemUiStateFlags();
-        }
-    }
-
-    @Override
-    public void showTransient(int displayId, @InsetsType int types, boolean isGestureOnSystemBar) {
-        if (displayId != mDisplayId) {
-            return;
-        }
-        if ((types & WindowInsets.Type.navigationBars()) == 0) {
-            return;
-        }
-        if (!mTransientShown) {
-            mTransientShown = true;
-            mTransientShownFromGestureOnSystemBar = isGestureOnSystemBar;
-            handleTransientChanged();
-        }
-    }
-
-    @Override
-    public void abortTransient(int displayId, @InsetsType int types) {
-        if (displayId != mDisplayId) {
-            return;
-        }
-        if ((types & WindowInsets.Type.navigationBars()) == 0) {
-            return;
-        }
-        clearTransient();
-    }
-
-    private void clearTransient() {
-        if (mTransientShown) {
-            mTransientShown = false;
-            mTransientShownFromGestureOnSystemBar = false;
-            handleTransientChanged();
-        }
-    }
-
-    private void handleTransientChanged() {
-        mEdgeBackGestureHandler.onNavBarTransientStateChanged(mTransientShown);
-
-        final int transitionMode = transitionMode(mTransientShown, mAppearance);
-        if (updateTransitionMode(transitionMode) && mLightBarController != null) {
-            mLightBarController.onNavigationBarModeChanged(transitionMode);
-        }
-    }
-
-    // Returns true if the bar mode is changed.
-    private boolean updateTransitionMode(int barMode) {
-        if (mTransitionMode != barMode) {
-            mTransitionMode = barMode;
-            checkNavBarModes();
-            if (mAutoHideController != null) {
-                mAutoHideController.touchAutoHide();
-            }
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void disable(int displayId, int state1, int state2, boolean animate) {
-        if (displayId != mDisplayId) {
-            return;
-        }
-        // Navigation bar flags are in both state1 and state2.
-        final int masked = state1 & (StatusBarManager.DISABLE_HOME
-                | StatusBarManager.DISABLE_RECENT
-                | StatusBarManager.DISABLE_BACK
-                | StatusBarManager.DISABLE_SEARCH);
-        if (masked != mDisabledFlags1) {
-            mDisabledFlags1 = masked;
-            mView.setDisabledFlags(state1, mSysUiFlagsContainer);
-            updateScreenPinningGestures();
-        }
-
-        // Only default display supports rotation suggestions.
-        if (mIsOnDefaultDisplay) {
-            final int masked2 = state2 & (StatusBarManager.DISABLE2_ROTATE_SUGGESTIONS);
-            if (masked2 != mDisabledFlags2) {
-                mDisabledFlags2 = masked2;
-                setDisabled2Flags(masked2);
-            }
-        }
-    }
-
-    private void setDisabled2Flags(int state2) {
-        // Method only called on change of disable2 flags
-        mView.getRotationButtonController().onDisable2FlagChanged(state2);
-    }
-
-    // ----- Internal stuff -----
-
-    private void refreshLayout(int layoutDirection) {
-        mView.setLayoutDirection(layoutDirection);
-    }
-
-    private boolean shouldDisableNavbarGestures() {
-        return !mDeviceProvisionedController.isDeviceProvisioned()
-                || (mDisabledFlags1 & StatusBarManager.DISABLE_SEARCH) != 0;
-    }
-
-    private void repositionNavigationBar(int rotation) {
-        if (mView == null || !mView.isAttachedToWindow()) return;
-
-        prepareNavigationBarView();
-
-        mWindowManager.updateViewLayout(mFrame, getBarLayoutParams(rotation));
-    }
-
-    private void updateScreenPinningGestures() {
-        // Change the cancel pin gesture to home and back if recents button is invisible
-        ButtonDispatcher backButton = mView.getBackButton();
-        ButtonDispatcher recentsButton = mView.getRecentsButton();
-        if (mScreenPinningActive) {
-            boolean recentsVisible = mView.isRecentsButtonVisible();
-            backButton.setOnLongClickListener(recentsVisible
-                    ? this::onLongPressBackRecents
-                    : this::onLongPressBackHome);
-            recentsButton.setOnLongClickListener(this::onLongPressBackRecents);
-        } else {
-            backButton.setOnLongClickListener(null);
-            recentsButton.setOnLongClickListener(null);
-        }
-        // Note, this needs to be set after even if we're setting the listener to null
-        backButton.setLongClickable(mScreenPinningActive);
-        recentsButton.setLongClickable(mScreenPinningActive);
-    }
-
-    private void notifyNavigationBarScreenOn() {
-        mView.updateNavButtonIcons();
-    }
-
-    private void prepareNavigationBarView() {
-        mView.reorient();
-
-        ButtonDispatcher recentsButton = mView.getRecentsButton();
-        recentsButton.setOnClickListener(this::onRecentsClick);
-        recentsButton.setOnTouchListener(this::onRecentsTouch);
-
-        ButtonDispatcher homeButton = mView.getHomeButton();
-        homeButton.setOnTouchListener(this::onHomeTouch);
-        homeButton.setNavBarButtonClickLogger(mNavBarButtonClickLogger);
-
-        ButtonDispatcher backButton = mView.getBackButton();
-        backButton.setNavBarButtonClickLogger(mNavBarButtonClickLogger);
-
-        reconfigureHomeLongClick();
-
-        ButtonDispatcher accessibilityButton = mView.getAccessibilityButton();
-        accessibilityButton.setOnClickListener(this::onAccessibilityClick);
-        accessibilityButton.setOnLongClickListener(this::onAccessibilityLongClick);
-        updateAccessibilityStateFlags();
-
-        ButtonDispatcher imeSwitcherButton = mView.getImeSwitchButton();
-        imeSwitcherButton.setOnClickListener(this::onImeSwitcherClick);
-
-        updateScreenPinningGestures();
-    }
-
-    @VisibleForTesting
-    boolean onHomeTouch(View v, MotionEvent event) {
-        if (mHomeBlockedThisTouch && event.getActionMasked() != MotionEvent.ACTION_DOWN) {
-            return true;
-        }
-        // If an incoming call is ringing, HOME is totally disabled.
-        // (The user is already on the InCallUI at this point,
-        // and their ONLY options are to answer or reject the call.)
-        final Optional<CentralSurfaces> centralSurfacesOptional = mCentralSurfacesOptionalLazy.get();
-        switch (event.getAction()) {
-            case MotionEvent.ACTION_DOWN:
-                if (mCurrentDownEvent != null) {
-                    mCurrentDownEvent.recycle();
-                }
-                mCurrentDownEvent = MotionEvent.obtain(event);
-                mHomeBlockedThisTouch = false;
-                if (mTelecomManagerOptional.isPresent()
-                        && mTelecomManagerOptional.get().isRinging()) {
-                    if (mKeyguardStateController.isShowing()) {
-                        Log.i(TAG, "Ignoring HOME; there's a ringing incoming call. " +
-                                "No heads up");
-                        mHomeBlockedThisTouch = true;
-                        return true;
-                    }
-                }
-                if (mLongPressHomeEnabled) {
-                    if (mOverrideHomeButtonLongPressDurationMs.isPresent()) {
-                        Log.d(TAG, "ACTION_DOWN Launcher override duration: "
-                                + mOverrideHomeButtonLongPressDurationMs.get());
-                        mHandler.postDelayed(mOnVariableDurationHomeLongClick,
-                                mOverrideHomeButtonLongPressDurationMs.get());
-                    } else if (mOverrideHomeButtonLongPressSlopMultiplier.isPresent()) {
-                        // If override timeout doesn't exist but override touch slop exists, we use
-                        // system default long press duration
-                        Log.d(TAG, "ACTION_DOWN default duration: "
-                                + ViewConfiguration.getLongPressTimeout());
-                        mHandler.postDelayed(mOnVariableDurationHomeLongClick,
-                                ViewConfiguration.getLongPressTimeout());
-                    } else {
-                        mHomeButtonLongPressDurationMs.ifPresent(longPressDuration -> {
-                            Log.d(TAG, "ACTION_DOWN original duration: " + longPressDuration);
-                            mHandler.postDelayed(mOnVariableDurationHomeLongClick,
-                                    longPressDuration);
-                        });
-                    }
-                }
-                break;
-            case MotionEvent.ACTION_MOVE:
-                if (!mHandler.hasCallbacks(mOnVariableDurationHomeLongClick)) {
-                    Log.v(TAG, "ACTION_MOVE no callback. Don't handle touch slop.");
-                    break;
-                }
-                Log.v(TAG, "ACTION_MOVE handle touch slop");
-                float customSlopMultiplier = mOverrideHomeButtonLongPressSlopMultiplier.orElse(1f);
-                float touchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
-                float calculatedTouchSlop =
-                        customSlopMultiplier * QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON * touchSlop;
-                float touchSlopSquared = calculatedTouchSlop * calculatedTouchSlop;
-
-                float dx = event.getX() - mCurrentDownEvent.getX();
-                float dy = event.getY() - mCurrentDownEvent.getY();
-                double distanceSquared = (dx * dx) + (dy * dy);
-                if (distanceSquared > touchSlopSquared) {
-                    Log.i(TAG, "Touch slop passed. Abort.");
-                    mView.abortCurrentGesture();
-                    mHandler.removeCallbacks(mOnVariableDurationHomeLongClick);
-                }
-                break;
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL:
-                mHandler.removeCallbacks(mOnVariableDurationHomeLongClick);
-                centralSurfacesOptional.ifPresent(CentralSurfaces::awakenDreams);
-                break;
-        }
-        return false;
-    }
-
-    private void onVerticalChanged(boolean isVertical) {
-        // This check can probably be safely removed. It only remained to reduce regression
-        // risk for a broad change that removed the CentralSurfaces reference in the if block
-        if (mCentralSurfacesOptionalLazy.get().isPresent()) {
-            mShadeViewController.setQsScrimEnabled(!isVertical);
-        }
-    }
-
-    private boolean onNavigationTouch(View v, MotionEvent event) {
-        if (mAutoHideController != null) {
-            mAutoHideController.checkUserAutoHide(event);
-        }
-        return false;
-    }
-
-    @VisibleForTesting
-    boolean onHomeLongClick(View v) {
-        if (!mView.isRecentsButtonVisible() && mScreenPinningActive) {
-            return onLongPressBackHome(v);
-        }
-        if (shouldDisableNavbarGestures()) {
-            return false;
-        }
-        mMetricsLogger.action(MetricsEvent.ACTION_ASSIST_LONG_PRESS);
-        mUiEventLogger.log(NavBarActionEvent.NAVBAR_ASSIST_LONGPRESS);
-        Bundle args = new Bundle();
-        args.putInt(
-                AssistManager.INVOCATION_TYPE_KEY,
-                AssistManager.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS);
-        // If Launcher has requested to override long press home, add a delay for the ripple.
-        // TODO(b/304146255): Remove this delay once we can exclude 3-button nav from screenshot.
-        boolean delayAssistInvocation = mAssistManagerLazy.get().shouldOverrideAssist(
-                AssistManager.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS);
-        // In practice, I think v should always be a KeyButtonView, but just being safe.
-        if (delayAssistInvocation && v instanceof KeyButtonView) {
-            ((KeyButtonView) v).setOnRippleInvisibleRunnable(
-                    () -> mAssistManagerLazy.get().startAssist(args));
-        } else {
-            mAssistManagerLazy.get().startAssist(args);
-        }
-        mCentralSurfacesOptionalLazy.get().ifPresent(CentralSurfaces::awakenDreams);
-        mView.abortCurrentGesture();
-        return true;
-    }
-
-    // additional optimization when we have software system buttons - start loading the recent
-    // tasks on touch down
-    private boolean onRecentsTouch(View v, MotionEvent event) {
-        int action = event.getAction() & MotionEvent.ACTION_MASK;
-        if (action == MotionEvent.ACTION_DOWN) {
-            mCommandQueue.preloadRecentApps();
-        } else if (action == MotionEvent.ACTION_CANCEL) {
-            mCommandQueue.cancelPreloadRecentApps();
-        } else if (action == MotionEvent.ACTION_UP) {
-            if (!v.isPressed()) {
-                mCommandQueue.cancelPreloadRecentApps();
-            }
-        }
-        return false;
-    }
-
-    private void onRecentsClick(View v) {
-        mNavBarButtonClickLogger.logRecentsButtonClick();
-
-        if (LatencyTracker.isEnabled(mContext)) {
-            LatencyTracker.getInstance(mContext).onActionStart(
-                    LatencyTracker.ACTION_TOGGLE_RECENTS);
-        }
-        mCentralSurfacesOptionalLazy.get().ifPresent(CentralSurfaces::awakenDreams);
-        mCommandQueue.toggleRecentApps();
-    }
-
-    private void onImeSwitcherClick(View v) {
-        mNavBarButtonClickLogger.logImeSwitcherClick();
-        mInputMethodManager.showInputMethodPickerFromSystem(
-                true /* showAuxiliarySubtypes */, mDisplayId);
-        mUiEventLogger.log(KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_TAP);
-    };
-
-    private boolean onLongPressBackHome(View v) {
-        return onLongPressNavigationButtons(v, R.id.back, R.id.home);
-    }
-
-    private boolean onLongPressBackRecents(View v) {
-        return onLongPressNavigationButtons(v, R.id.back, R.id.recent_apps);
-    }
-
-    /**
-     * This handles long-press of both back and recents/home. Back is the common button with
-     * combination of recents if it is visible or home if recents is invisible.
-     * They are handled together to capture them both being long-pressed
-     * at the same time to exit screen pinning (lock task).
-     *
-     * When accessibility mode is on, only a long-press from recents/home
-     * is required to exit.
-     *
-     * In all other circumstances we try to pass through long-press events
-     * for Back, so that apps can still use it.  Which can be from two things.
-     * 1) Not currently in screen pinning (lock task).
-     * 2) Back is long-pressed without recents/home.
-     */
-    private boolean onLongPressNavigationButtons(View v, @IdRes int btnId1, @IdRes int btnId2) {
-        try {
-            boolean sendBackLongPress = false;
-            IActivityTaskManager activityManager = ActivityTaskManager.getService();
-            boolean touchExplorationEnabled = mAccessibilityManager.isTouchExplorationEnabled();
-            boolean inLockTaskMode = activityManager.isInLockTaskMode();
-            boolean stopLockTaskMode = false;
-            try {
-                if (inLockTaskMode && !touchExplorationEnabled) {
-                    long time = System.currentTimeMillis();
-
-                    // If we recently long-pressed the other button then they were
-                    // long-pressed 'together'
-                    if ((time - mLastLockToAppLongPress) < LOCK_TO_APP_GESTURE_TOLERANCE) {
-                        stopLockTaskMode = true;
-                        return true;
-                    } else if (v.getId() == btnId1) {
-                        ButtonDispatcher button = btnId2 == R.id.recent_apps
-                                ? mView.getRecentsButton() : mView.getHomeButton();
-                        if (!button.getCurrentView().isPressed()) {
-                            // If we aren't pressing recents/home right now then they presses
-                            // won't be together, so send the standard long-press action.
-                            sendBackLongPress = true;
-                        }
-                    }
-                    mLastLockToAppLongPress = time;
-                } else {
-                    // If this is back still need to handle sending the long-press event.
-                    if (v.getId() == btnId1) {
-                        sendBackLongPress = true;
-                    } else if (touchExplorationEnabled && inLockTaskMode) {
-                        // When in accessibility mode a long press that is recents/home (not back)
-                        // should stop lock task.
-                        stopLockTaskMode = true;
-                        return true;
-                    } else if (v.getId() == btnId2) {
-                        return btnId2 == R.id.recent_apps
-                                ? false
-                                : onHomeLongClick(mView.getHomeButton().getCurrentView());
-                    }
-                }
-            } finally {
-                if (stopLockTaskMode) {
-                    activityManager.stopSystemLockTaskMode();
-                    // When exiting refresh disabled flags.
-                    mView.updateNavButtonIcons();
-                }
-            }
-
-            if (sendBackLongPress) {
-                KeyButtonView keyButtonView = (KeyButtonView) v;
-                keyButtonView.sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
-                keyButtonView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
-                return true;
-            }
-        } catch (RemoteException e) {
-            Log.d(TAG, "Unable to reach activity manager", e);
-        }
-        return false;
-    }
-
-    private void onAccessibilityClick(View v) {
-        mNavBarButtonClickLogger.logAccessibilityButtonClick();
-        final Display display = v.getDisplay();
-        mAccessibilityManager.notifyAccessibilityButtonClicked(
-                display != null ? display.getDisplayId() : mDisplayTracker.getDefaultDisplayId());
-    }
-
-    private boolean onAccessibilityLongClick(View v) {
-        final Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-        final String chooserClassName = AccessibilityButtonChooserActivity.class.getName();
-        intent.setClassName(CHOOSER_PACKAGE_NAME, chooserClassName);
-        mContext.startActivityAsUser(intent, mUserTracker.getUserHandle());
-        return true;
-    }
-
-    void updateAccessibilityStateFlags() {
-        mLongPressHomeEnabled = mNavBarHelper.getLongPressHomeEnabled();
-        if (mView != null) {
-            long a11yFlags = mNavBarHelper.getA11yButtonState();
-            boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
-            boolean longClickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
-            mView.setAccessibilityButtonState(clickable, longClickable);
-        }
-        updateSystemUiStateFlags();
-    }
-
-    public void updateSystemUiStateFlags() {
-        long a11yFlags = mNavBarHelper.getA11yButtonState();
-        boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
-        boolean longClickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
-
-        mSysUiFlagsContainer.setFlag(SYSUI_STATE_A11Y_BUTTON_CLICKABLE, clickable)
-                .setFlag(SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE, longClickable)
-                .setFlag(SYSUI_STATE_NAV_BAR_HIDDEN, !isNavBarWindowVisible())
-                .setFlag(SYSUI_STATE_IME_SHOWING,
-                        (mNavigationIconHints & NAVIGATION_HINT_BACK_ALT) != 0)
-                .setFlag(SYSUI_STATE_IME_SWITCHER_SHOWING,
-                        (mNavigationIconHints & NAVIGATION_HINT_IME_SWITCHER_SHOWN) != 0)
-                .setFlag(SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY,
-                        allowSystemGestureIgnoringBarVisibility())
-                .commitUpdate(mDisplayId);
-    }
-
-    private void updateAssistantEntrypoints(boolean assistantAvailable,
-            boolean longPressHomeEnabled) {
-        if (mOverviewProxyService.getProxy() != null) {
-            try {
-                mOverviewProxyService.getProxy().onAssistantAvailable(assistantAvailable,
-                        longPressHomeEnabled);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Unable to send assistant availability data to launcher");
-            }
-        }
-        reconfigureHomeLongClick();
-    }
-
-    // ----- Methods that DisplayNavigationBarController talks to -----
-
-    /** Applies auto dimming animation on navigation bar when touched. */
-    public void touchAutoDim() {
-        getBarTransitions().setAutoDim(false);
-        mHandler.removeCallbacks(mAutoDim);
-        int state = mStatusBarStateController.getState();
-        if (state != StatusBarState.KEYGUARD && state != StatusBarState.SHADE_LOCKED) {
-            mHandler.postDelayed(mAutoDim, AUTODIM_TIMEOUT_MS);
-        }
-    }
-
-    public void setLightBarController(LightBarController lightBarController) {
-        mLightBarController = lightBarController;
-        if (mLightBarController != null) {
-            mLightBarController.setNavigationBar(
-                    getBarTransitions().getLightTransitionsController());
-        }
-    }
-
-    private void setWindowVisible(boolean visible) {
-        mRegionSamplingHelper.setWindowVisible(visible);
-        mView.setWindowVisible(visible);
-    }
-
-    /** Sets {@link AutoHideController} to the navigation bar. */
-    private void setAutoHideController(AutoHideController autoHideController) {
-        mAutoHideController = autoHideController;
-        if (mAutoHideController != null) {
-            mAutoHideController.setNavigationBar(mAutoHideUiElement);
-        }
-        mView.setAutoHideController(autoHideController);
-    }
-
-    private boolean isTransientShown() {
-        return mTransientShown;
-    }
-
-    private void checkBarModes() {
-        // We only have status bar on default display now.
-        if (mIsOnDefaultDisplay) {
-            mCentralSurfacesOptionalLazy.get().ifPresent(CentralSurfaces::checkBarModes);
-        } else {
-            checkNavBarModes();
-        }
-    }
-
-    public boolean isNavBarWindowVisible() {
-        return mNavigationBarWindowState == WINDOW_STATE_SHOWING;
-    }
-
-    private boolean allowSystemGestureIgnoringBarVisibility() {
-        return mBehavior != BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
-    }
-
-    /**
-     * Checks current navigation bar mode and make transitions.
-     */
-    public void checkNavBarModes() {
-        final boolean anim =
-                mCentralSurfacesOptionalLazy.get().map(CentralSurfaces::isDeviceInteractive)
-                        .orElse(false)
-                && mNavigationBarWindowState != WINDOW_STATE_HIDDEN;
-        getBarTransitions().transitionTo(mTransitionMode, anim);
-    }
-
-    public void disableAnimationsDuringHide(long delay) {
-        mView.setLayoutTransitionsEnabled(false);
-        mHandler.postDelayed(mEnableLayoutTransitions,
-                delay + StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE);
-    }
-
-    /**
-     * Performs transitions on navigation bar.
-     *
-     * @param barMode transition bar mode.
-     * @param animate shows animations if {@code true}.
-     */
-    public void transitionTo(@TransitionMode int barMode, boolean animate) {
-        getBarTransitions().transitionTo(barMode, animate);
-    }
-
-    public NavigationBarTransitions getBarTransitions() {
-        return mNavigationBarTransitions;
-    }
-
-    public void finishBarAnimations() {
-        getBarTransitions().finishAnimations();
-    }
-
-    private WindowManager.LayoutParams getBarLayoutParams(int rotation) {
-        WindowManager.LayoutParams lp = getBarLayoutParamsForRotation(rotation);
-        lp.paramsForRotation = new WindowManager.LayoutParams[4];
-        for (int rot = Surface.ROTATION_0; rot <= Surface.ROTATION_270; rot++) {
-            lp.paramsForRotation[rot] = getBarLayoutParamsForRotation(rot);
-        }
-        return lp;
-    }
-
-    private WindowManager.LayoutParams getBarLayoutParamsForRotation(int rotation) {
-        int width = WindowManager.LayoutParams.MATCH_PARENT;
-        int height = WindowManager.LayoutParams.MATCH_PARENT;
-        int insetsHeight = -1;
-        int gravity = Gravity.BOTTOM;
-        boolean navBarCanMove = true;
-        final Context userContext = mUserContextProvider.createCurrentUserContext(mContext);
-        if (mWindowManager != null && mWindowManager.getCurrentWindowMetrics() != null) {
-            Rect displaySize = mWindowManager.getCurrentWindowMetrics().getBounds();
-            navBarCanMove = displaySize.width() != displaySize.height()
-                    && userContext.getResources().getBoolean(
-                    com.android.internal.R.bool.config_navBarCanMove);
-        }
-        if (!navBarCanMove) {
-            height = userContext.getResources().getDimensionPixelSize(
-                    com.android.internal.R.dimen.navigation_bar_frame_height);
-            insetsHeight = userContext.getResources().getDimensionPixelSize(
-                    com.android.internal.R.dimen.navigation_bar_height);
-        } else {
-            switch (rotation) {
-                case ROTATION_UNDEFINED:
-                case Surface.ROTATION_0:
-                case Surface.ROTATION_180:
-                    height = userContext.getResources().getDimensionPixelSize(
-                            com.android.internal.R.dimen.navigation_bar_frame_height);
-                    insetsHeight = userContext.getResources().getDimensionPixelSize(
-                            com.android.internal.R.dimen.navigation_bar_height);
-                    break;
-                case Surface.ROTATION_90:
-                    gravity = Gravity.RIGHT;
-                    width = userContext.getResources().getDimensionPixelSize(
-                            com.android.internal.R.dimen.navigation_bar_width);
-                    break;
-                case Surface.ROTATION_270:
-                    gravity = Gravity.LEFT;
-                    width = userContext.getResources().getDimensionPixelSize(
-                            com.android.internal.R.dimen.navigation_bar_width);
-                    break;
-            }
-        }
-        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                width,
-                height,
-                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
-                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
-                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
-                        | WindowManager.LayoutParams.FLAG_SLIPPERY,
-                PixelFormat.TRANSLUCENT);
-        lp.gravity = gravity;
-        lp.providedInsets = getInsetsFrameProvider(insetsHeight, userContext);
-
-        lp.token = new Binder();
-        lp.accessibilityTitle = userContext.getString(R.string.nav_bar);
-        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC
-                | WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
-        lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
-        lp.windowAnimations = 0;
-        lp.setTitle("NavigationBar" + userContext.getDisplayId());
-        lp.setFitInsetsTypes(0 /* types */);
-        lp.setTrustedOverlay();
-        return lp;
-    }
-
-    private InsetsFrameProvider[] getInsetsFrameProvider(int insetsHeight, Context userContext) {
-        final InsetsFrameProvider navBarProvider =
-                new InsetsFrameProvider(mInsetsSourceOwner, 0, WindowInsets.Type.navigationBars());
-        if (!ENABLE_HIDE_IME_CAPTION_BAR) {
-            navBarProvider.setInsetsSizeOverrides(new InsetsFrameProvider.InsetsSizeOverride[] {
-                    new InsetsFrameProvider.InsetsSizeOverride(TYPE_INPUT_METHOD, null)
-            });
-        }
-        if (insetsHeight != -1 && !mEdgeBackGestureHandler.isButtonForcedVisible()) {
-            navBarProvider.setInsetsSize(Insets.of(0, 0, 0, insetsHeight));
-        }
-        final boolean needsScrim = userContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_navBarNeedsScrim);
-        navBarProvider.setFlags(needsScrim ? 0 : FLAG_SUPPRESS_SCRIM, FLAG_SUPPRESS_SCRIM);
-
-        final InsetsFrameProvider tappableElementProvider = new InsetsFrameProvider(
-                mInsetsSourceOwner, 0, WindowInsets.Type.tappableElement());
-        final boolean tapThrough = userContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_navBarTapThrough);
-        if (tapThrough) {
-            tappableElementProvider.setInsetsSize(Insets.NONE);
-        }
-
-        final int gestureHeight = userContext.getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.navigation_bar_gesture_height);
-        final boolean handlingGesture = mEdgeBackGestureHandler.isHandlingGestures();
-        final InsetsFrameProvider mandatoryGestureProvider = new InsetsFrameProvider(
-                mInsetsSourceOwner, 0, WindowInsets.Type.mandatorySystemGestures());
-        if (handlingGesture) {
-            mandatoryGestureProvider.setInsetsSize(Insets.of(0, 0, 0, gestureHeight));
-        }
-        final int gestureInsetsLeft = handlingGesture
-                ? mEdgeBackGestureHandler.getEdgeWidthLeft() : 0;
-        final int gestureInsetsRight = handlingGesture
-                ? mEdgeBackGestureHandler.getEdgeWidthRight() : 0;
-        return new InsetsFrameProvider[] {
-                navBarProvider,
-                tappableElementProvider,
-                mandatoryGestureProvider,
-                new InsetsFrameProvider(mInsetsSourceOwner, 0, WindowInsets.Type.systemGestures())
-                        .setSource(InsetsFrameProvider.SOURCE_DISPLAY)
-                        .setInsetsSize(Insets.of(gestureInsetsLeft, 0, 0, 0))
-                        .setMinimalInsetsSizeInDisplayCutoutSafe(
-                                Insets.of(gestureInsetsLeft, 0, 0, 0)),
-                new InsetsFrameProvider(mInsetsSourceOwner, 1, WindowInsets.Type.systemGestures())
-                        .setSource(InsetsFrameProvider.SOURCE_DISPLAY)
-                        .setInsetsSize(Insets.of(0, 0, gestureInsetsRight, 0))
-                        .setMinimalInsetsSizeInDisplayCutoutSafe(
-                                Insets.of(0, 0, gestureInsetsRight, 0))
-        };
-    }
-
-    private boolean canShowSecondaryHandle() {
-        return mNavBarMode == NAV_BAR_MODE_GESTURAL && mOrientationHandle != null;
-    }
-
-    private final UserTracker.Callback mUserChangedCallback =
-            new UserTracker.Callback() {
-                @Override
-                public void onUserChanged(int newUser, @NonNull Context userContext) {
-                    // The accessibility settings may be different for the new user
-                    updateAccessibilityStateFlags();
-                }
-            };
-
-    @VisibleForTesting
-    int getNavigationIconHints() {
-        return mNavigationIconHints;
-    }
-
-    private void setNavigationIconHints(int hints) {
-        if (hints == mNavigationIconHints) return;
-        if (!isLargeScreen(mContext)) {
-            // All IME functions handled by launcher via Sysui flags for large screen
-            final boolean newBackAlt = (hints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
-            final boolean oldBackAlt =
-                    (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
-            if (newBackAlt != oldBackAlt) {
-                mView.onImeVisibilityChanged(newBackAlt);
-                mImeVisible = newBackAlt;
-            }
-
-            mView.setNavigationIconHints(hints);
-        }
-        if (DEBUG) {
-            android.widget.Toast.makeText(mContext,
-                    "Navigation icon hints = " + hints,
-                    500).show();
-        }
-        mNavigationIconHints = hints;
-    }
-
-    /**
-     * @param inScreenSpace Whether to return values in screen space or window space
-     * @param useNearestRegion Whether to use the nearest region instead of the actual button bounds
-     * @return
-     */
-    Region getButtonLocations(boolean inScreenSpace, boolean useNearestRegion) {
-        if (useNearestRegion && !inScreenSpace) {
-            // We currently don't support getting the nearest region in anything but screen space
-            useNearestRegion = false;
-        }
-        Region region = new Region();
-        Map<View, Rect> touchRegionCache = mView.getButtonTouchRegionCache();
-        updateButtonLocation(
-                region, touchRegionCache, mView.getBackButton(), inScreenSpace, useNearestRegion);
-        updateButtonLocation(
-                region, touchRegionCache, mView.getHomeButton(), inScreenSpace, useNearestRegion);
-        updateButtonLocation(region, touchRegionCache, mView.getRecentsButton(), inScreenSpace,
-                useNearestRegion);
-        updateButtonLocation(region, touchRegionCache, mView.getImeSwitchButton(), inScreenSpace,
-                useNearestRegion);
-        updateButtonLocation(
-                region, touchRegionCache, mView.getAccessibilityButton(), inScreenSpace,
-                useNearestRegion);
-        if (mView.getFloatingRotationButton().isVisible()) {
-            // Note: this button is floating so the nearest region doesn't apply
-            updateButtonLocation(
-                    region, mView.getFloatingRotationButton().getCurrentView(), inScreenSpace);
-        }
-        return region;
-    }
-
-    private void updateButtonLocation(
-            Region region,
-            Map<View, Rect> touchRegionCache,
-            ButtonDispatcher button,
-            boolean inScreenSpace,
-            boolean useNearestRegion) {
-        if (button == null) {
-            return;
-        }
-        View view = button.getCurrentView();
-        if (view == null || !button.isVisible()) {
-            return;
-        }
-        // If the button is tappable from perspective of NearestTouchFrame, then we'll
-        // include the regions where the tap is valid instead of just the button layout location
-        if (useNearestRegion && touchRegionCache.containsKey(view)) {
-            region.op(touchRegionCache.get(view), Region.Op.UNION);
-            return;
-        }
-        updateButtonLocation(region, view, inScreenSpace);
-    }
-
-    private void updateButtonLocation(Region region, View view, boolean inScreenSpace) {
-        Rect bounds = new Rect();
-        if (inScreenSpace) {
-            view.getBoundsOnScreen(bounds);
-        } else {
-            int[] location = new int[2];
-            view.getLocationInWindow(location);
-            bounds.set(location[0], location[1],
-                    location[0] + view.getWidth(),
-                    location[1] + view.getHeight());
-        }
-        region.op(bounds, Region.Op.UNION);
-    }
-
-    void setOrientedHandleSamplingRegion(Rect orientedHandleSamplingRegion) {
-        mOrientedHandleSamplingRegion = orientedHandleSamplingRegion;
-        mRegionSamplingHelper.updateSamplingRect();
-    }
-
-    private Rect calculateSamplingRect() {
-        mSamplingBounds.setEmpty();
-        // TODO: Extend this to 2/3 button layout as well
-        View view = mView.getHomeHandle().getCurrentView();
-
-        if (view != null) {
-            int[] pos = new int[2];
-            view.getLocationOnScreen(pos);
-            Point displaySize = new Point();
-            view.getContext().getDisplay().getRealSize(displaySize);
-            final Rect samplingBounds = new Rect(pos[0] - mNavColorSampleMargin,
-                    displaySize.y - mView.getNavBarHeight(),
-                    pos[0] + view.getWidth() + mNavColorSampleMargin,
-                    displaySize.y);
-            mSamplingBounds.set(samplingBounds);
-        }
-
-        return mSamplingBounds;
-    }
-
-    void setNavigationBarLumaSamplingEnabled(boolean enable) {
-        if (enable) {
-            mRegionSamplingHelper.start(mSamplingBounds);
-        } else {
-            mRegionSamplingHelper.stop();
-        }
-    }
-
-    private void setNavBarMode(int mode) {
-        mView.setNavBarMode(mode, mNavigationModeController.getImeDrawsImeNavBar());
-        if (isGesturalMode(mode)) {
-            mRegionSamplingHelper.start(mSamplingBounds);
-        } else {
-            mRegionSamplingHelper.stop();
-        }
-    }
-
-    void onBarTransition(int newMode) {
-        if (newMode == MODE_OPAQUE) {
-            // If the nav bar background is opaque, stop auto tinting since we know the icons are
-            // showing over a dark background
-            mRegionSamplingHelper.stop();
-            getBarTransitions().getLightTransitionsController().setIconsDark(
-                    false /* dark */, true /* animate */);
-        } else {
-            mRegionSamplingHelper.start(mSamplingBounds);
-        }
-    }
-
-    private final ModeChangedListener mModeChangedListener = new ModeChangedListener() {
-        @Override
-        public void onNavigationModeChanged(int mode) {
-            mNavBarMode = mode;
-
-            if (!QuickStepContract.isGesturalMode(mode)) {
-                // Reset the override alpha
-                if (getBarTransitions() != null) {
-                    getBarTransitions().setBackgroundOverrideAlpha(1f);
-                }
-            }
-
-            // Update the window layout params when the nav mode changes as that will affect the
-            // system gesture insets
-            setNavBarMode(mode);
-            repositionNavigationBar(mCurrentRotation);
-
-            if (!canShowSecondaryHandle()) {
-                resetSecondaryHandle();
-            }
-            mView.setShouldShowSwipeUpUi(mOverviewProxyService.shouldShowSwipeUpUI());
-        }
-    };
-
-    private final Gefingerpoken mTouchHandler = new Gefingerpoken() {
-        private boolean mDeadZoneConsuming;
-
-        @Override
-        public boolean onInterceptTouchEvent(MotionEvent ev) {
-            if (isGesturalMode(mNavBarMode) && mImeVisible
-                    && ev.getAction() == MotionEvent.ACTION_DOWN) {
-                SysUiStatsLog.write(SysUiStatsLog.IME_TOUCH_REPORTED,
-                        (int) ev.getX(), (int) ev.getY());
-            }
-            return shouldDeadZoneConsumeTouchEvents(ev);
-        }
-
-        @Override
-        public boolean onTouchEvent(MotionEvent ev) {
-            shouldDeadZoneConsumeTouchEvents(ev);
-            return false;
-        }
-
-        private boolean shouldDeadZoneConsumeTouchEvents(MotionEvent event) {
-            int action = event.getActionMasked();
-            if (action == MotionEvent.ACTION_DOWN) {
-                mDeadZoneConsuming = false;
-            }
-            if (mDeadZone.onTouchEvent(event) || mDeadZoneConsuming) {
-                switch (action) {
-                    case MotionEvent.ACTION_DOWN:
-                        // Allow gestures starting in the deadzone to be slippery
-                        mView.setSlippery(true);
-                        mDeadZoneConsuming = true;
-                        break;
-                    case MotionEvent.ACTION_CANCEL:
-                    case MotionEvent.ACTION_UP:
-                        // When a gesture started in the deadzone is finished, restore
-                        // slippery state
-                        mView.updateSlippery();
-                        mDeadZoneConsuming = false;
-                        break;
-                }
-                return true;
-            }
-            return false;
-        }
-    };
-}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarComponent.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarComponent.java
index 4f713d6..abd8bb9 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarComponent.java
@@ -24,6 +24,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.systemui.dagger.qualifiers.DisplayId;
+import com.android.systemui.navigationbar.views.NavigationBar;
 
 import dagger.BindsInstance;
 import dagger.Subcomponent;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
index a601d7f..49fa3ba 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
@@ -19,7 +19,9 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.statusbar.RegisterStatusBarResult;
-import com.android.systemui.statusbar.phone.BarTransitions;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
+import com.android.systemui.navigationbar.views.NavigationBar;
+import com.android.systemui.navigationbar.views.NavigationBarView;
 
 /** A controller to handle navigation bars. */
 public interface NavigationBarController {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt
index e73b078..c392c2f 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt
@@ -18,7 +18,9 @@
 
 import com.android.internal.statusbar.RegisterStatusBarResult
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.phone.BarTransitions
+import com.android.systemui.shared.statusbar.phone.BarTransitions
+import com.android.systemui.navigationbar.views.NavigationBar
+import com.android.systemui.navigationbar.views.NavigationBarView
 import javax.inject.Inject
 
 /** A no-op version of [NavigationBarController] for variants like Arc and TV. */
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
index b177b0b..1dbdec9 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
@@ -23,6 +23,7 @@
 import static com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler.DEBUG_MISSING_GESTURE_TAG;
 import static com.android.systemui.shared.recents.utilities.Utilities.isLargeScreen;
 import static com.android.wm.shell.Flags.enableTaskbarNavbarUnification;
+import static com.android.wm.shell.Flags.enableTaskbarOnPhones;
 
 import android.content.Context;
 import android.content.pm.ActivityInfo;
@@ -53,13 +54,15 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.model.SysUiState;
+import com.android.systemui.navigationbar.views.NavigationBar;
+import com.android.systemui.navigationbar.views.NavigationBarView;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.settings.DisplayTracker;
+import com.android.systemui.shared.statusbar.phone.BarTransitions.TransitionMode;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.TaskStackChangeListeners;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.AutoHideController;
-import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
 import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.util.settings.SecureSettings;
@@ -285,8 +288,10 @@
 
     @VisibleForTesting
     boolean supportsTaskbar() {
-        // Enable for tablets, unfolded state on a foldable device or (non handheld AND flag is set)
-        return mIsLargeScreen || (!mIsPhone && enableTaskbarNavbarUnification());
+        // Enable for tablets, unfolded state on a foldable device, (non handheld AND flag is set),
+        // or handheld when enableTaskbarOnPhones() returns true.
+        boolean foldedOrPhone = !mIsPhone || enableTaskbarOnPhones();
+        return mIsLargeScreen || (foldedOrPhone && enableTaskbarNavbarUnification());
     }
 
     private final CommandQueue.Callbacks mCommandQueueCallbacks = new CommandQueue.Callbacks() {
@@ -428,6 +433,8 @@
         NavigationBar navBar = mNavigationBars.get(displayId);
         if (navBar != null) {
             navBar.checkNavBarModes();
+        } else {
+            mTaskbarDelegate.checkNavBarModes();
         }
     }
 
@@ -436,6 +443,8 @@
         NavigationBar navBar = mNavigationBars.get(displayId);
         if (navBar != null) {
             navBar.finishBarAnimations();
+        } else {
+            mTaskbarDelegate.finishBarAnimations();
         }
     }
 
@@ -444,6 +453,8 @@
         NavigationBar navBar = mNavigationBars.get(displayId);
         if (navBar != null) {
             navBar.touchAutoDim();
+        } else {
+            mTaskbarDelegate.touchAutoDim();
         }
     }
 
@@ -452,6 +463,8 @@
         NavigationBar navBar = mNavigationBars.get(displayId);
         if (navBar != null) {
             navBar.transitionTo(barMode, animate);
+        } else {
+            mTaskbarDelegate.transitionTo(barMode, animate);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarFrame.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarFrame.java
deleted file mode 100644
index 6c531d8..0000000
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarFrame.java
+++ /dev/null
@@ -1,61 +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.navigationbar;
-
-import static android.view.MotionEvent.ACTION_OUTSIDE;
-
-import android.annotation.AttrRes;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.widget.FrameLayout;
-
-import com.android.systemui.navigationbar.buttons.DeadZone;
-
-public class NavigationBarFrame extends FrameLayout {
-
-    private DeadZone mDeadZone = null;
-
-    public NavigationBarFrame(@NonNull Context context) {
-        super(context);
-    }
-
-    public NavigationBarFrame(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public NavigationBarFrame(@NonNull Context context, @Nullable AttributeSet attrs,
-            @AttrRes int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public void setDeadZone(@NonNull DeadZone deadZone) {
-        mDeadZone = deadZone;
-    }
-
-    @Override
-    public boolean dispatchTouchEvent(MotionEvent event) {
-        if (event.getAction() == ACTION_OUTSIDE) {
-            if (mDeadZone != null) {
-                return mDeadZone.onTouchEvent(event);
-            }
-        }
-        return super.dispatchTouchEvent(event);
-    }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java
deleted file mode 100644
index 2ae0709..0000000
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java
+++ /dev/null
@@ -1,503 +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.navigationbar;
-
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.graphics.drawable.Icon;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.Space;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.Dependency;
-import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
-import com.android.systemui.navigationbar.buttons.KeyButtonView;
-import com.android.systemui.navigationbar.buttons.ReverseLinearLayout;
-import com.android.systemui.navigationbar.buttons.ReverseLinearLayout.ReverseRelativeLayout;
-import com.android.systemui.recents.OverviewProxyService;
-import com.android.systemui.res.R;
-import com.android.systemui.shared.system.QuickStepContract;
-
-import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
-import java.util.Objects;
-
-public class NavigationBarInflaterView extends FrameLayout {
-    private static final String TAG = "NavBarInflater";
-
-    public static final String NAV_BAR_VIEWS = "sysui_nav_bar";
-    public static final String NAV_BAR_LEFT = "sysui_nav_bar_left";
-    public static final String NAV_BAR_RIGHT = "sysui_nav_bar_right";
-
-    public static final String MENU_IME_ROTATE = "menu_ime";
-    public static final String BACK = "back";
-    public static final String HOME = "home";
-    public static final String RECENT = "recent";
-    public static final String NAVSPACE = "space";
-    public static final String CLIPBOARD = "clipboard";
-    public static final String HOME_HANDLE = "home_handle";
-    public static final String KEY = "key";
-    public static final String LEFT = "left";
-    public static final String RIGHT = "right";
-    public static final String CONTEXTUAL = "contextual";
-    public static final String IME_SWITCHER = "ime_switcher";
-
-    public static final String GRAVITY_SEPARATOR = ";";
-    public static final String BUTTON_SEPARATOR = ",";
-
-    public static final String SIZE_MOD_START = "[";
-    public static final String SIZE_MOD_END = "]";
-
-    public static final String KEY_CODE_START = "(";
-    public static final String KEY_IMAGE_DELIM = ":";
-    public static final String KEY_CODE_END = ")";
-    private static final String WEIGHT_SUFFIX = "W";
-    private static final String WEIGHT_CENTERED_SUFFIX = "WC";
-    private static final String ABSOLUTE_SUFFIX = "A";
-    private static final String ABSOLUTE_VERTICAL_CENTERED_SUFFIX = "C";
-
-    private static class Listener implements NavigationModeController.ModeChangedListener {
-        private final WeakReference<NavigationBarInflaterView> mSelf;
-
-        Listener(NavigationBarInflaterView self) {
-            mSelf = new WeakReference<>(self);
-        }
-
-        @Override
-        public void onNavigationModeChanged(int mode) {
-            NavigationBarInflaterView self = mSelf.get();
-            if (self != null) {
-                self.onNavigationModeChanged(mode);
-            }
-        }
-    }
-
-    private final Listener mListener;
-
-    protected LayoutInflater mLayoutInflater;
-    protected LayoutInflater mLandscapeInflater;
-
-    protected FrameLayout mHorizontal;
-    protected FrameLayout mVertical;
-
-    @VisibleForTesting
-    SparseArray<ButtonDispatcher> mButtonDispatchers;
-    private String mCurrentLayout;
-
-    private View mLastPortrait;
-    private View mLastLandscape;
-
-    private boolean mIsVertical;
-    private boolean mAlternativeOrder;
-
-    private OverviewProxyService mOverviewProxyService;
-    private int mNavBarMode = NAV_BAR_MODE_3BUTTON;
-
-    public NavigationBarInflaterView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        createInflaters();
-        mOverviewProxyService = Dependency.get(OverviewProxyService.class);
-        mListener = new Listener(this);
-        mNavBarMode = Dependency.get(NavigationModeController.class).addListener(mListener);
-    }
-
-    @VisibleForTesting
-    void createInflaters() {
-        mLayoutInflater = LayoutInflater.from(mContext);
-        Configuration landscape = new Configuration();
-        landscape.setTo(mContext.getResources().getConfiguration());
-        landscape.orientation = Configuration.ORIENTATION_LANDSCAPE;
-        mLandscapeInflater = LayoutInflater.from(mContext.createConfigurationContext(landscape));
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        inflateChildren();
-        clearViews();
-        inflateLayout(getDefaultLayout());
-    }
-
-    private void inflateChildren() {
-        removeAllViews();
-        mHorizontal = (FrameLayout) mLayoutInflater.inflate(R.layout.navigation_layout,
-                this /* root */, false /* attachToRoot */);
-        addView(mHorizontal);
-        mVertical = (FrameLayout) mLayoutInflater.inflate(R.layout.navigation_layout_vertical,
-                this /* root */, false /* attachToRoot */);
-        addView(mVertical);
-        updateAlternativeOrder();
-    }
-
-    protected String getDefaultLayout() {
-        final int defaultResource = QuickStepContract.isGesturalMode(mNavBarMode)
-                ? R.string.config_navBarLayoutHandle
-                : mOverviewProxyService.shouldShowSwipeUpUI()
-                        ? R.string.config_navBarLayoutQuickstep
-                        : R.string.config_navBarLayout;
-        return getContext().getString(defaultResource);
-    }
-
-    private void onNavigationModeChanged(int mode) {
-        mNavBarMode = mode;
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        Dependency.get(NavigationModeController.class).removeListener(mListener);
-        super.onDetachedFromWindow();
-    }
-
-    public void onLikelyDefaultLayoutChange() {
-        // Reevaluate new layout
-        final String newValue = getDefaultLayout();
-        if (!Objects.equals(mCurrentLayout, newValue)) {
-            clearViews();
-            inflateLayout(newValue);
-        }
-    }
-
-    public void setButtonDispatchers(SparseArray<ButtonDispatcher> buttonDispatchers) {
-        mButtonDispatchers = buttonDispatchers;
-        clearDispatcherViews();
-        for (int i = 0; i < buttonDispatchers.size(); i++) {
-            initiallyFill(buttonDispatchers.valueAt(i));
-        }
-    }
-
-    void updateButtonDispatchersCurrentView() {
-        if (mButtonDispatchers != null) {
-            View view = mIsVertical ? mVertical : mHorizontal;
-            for (int i = 0; i < mButtonDispatchers.size(); i++) {
-                final ButtonDispatcher dispatcher = mButtonDispatchers.valueAt(i);
-                dispatcher.setCurrentView(view);
-            }
-        }
-    }
-
-    void setVertical(boolean vertical) {
-        if (vertical != mIsVertical) {
-            mIsVertical = vertical;
-        }
-    }
-
-    void setAlternativeOrder(boolean alternativeOrder) {
-        if (alternativeOrder != mAlternativeOrder) {
-            mAlternativeOrder = alternativeOrder;
-            updateAlternativeOrder();
-        }
-    }
-
-    private void updateAlternativeOrder() {
-        updateAlternativeOrder(mHorizontal.findViewById(R.id.ends_group));
-        updateAlternativeOrder(mHorizontal.findViewById(R.id.center_group));
-        updateAlternativeOrder(mVertical.findViewById(R.id.ends_group));
-        updateAlternativeOrder(mVertical.findViewById(R.id.center_group));
-    }
-
-    private void updateAlternativeOrder(View v) {
-        if (v instanceof ReverseLinearLayout) {
-            ((ReverseLinearLayout) v).setAlternativeOrder(mAlternativeOrder);
-        }
-    }
-
-    private void initiallyFill(ButtonDispatcher buttonDispatcher) {
-        addAll(buttonDispatcher, mHorizontal.findViewById(R.id.ends_group));
-        addAll(buttonDispatcher, mHorizontal.findViewById(R.id.center_group));
-        addAll(buttonDispatcher, mVertical.findViewById(R.id.ends_group));
-        addAll(buttonDispatcher, mVertical.findViewById(R.id.center_group));
-    }
-
-    private void addAll(ButtonDispatcher buttonDispatcher, ViewGroup parent) {
-        for (int i = 0; i < parent.getChildCount(); i++) {
-            // Need to manually search for each id, just in case each group has more than one
-            // of a single id.  It probably mostly a waste of time, but shouldn't take long
-            // and will only happen once.
-            if (parent.getChildAt(i).getId() == buttonDispatcher.getId()) {
-                buttonDispatcher.addView(parent.getChildAt(i));
-            }
-            if (parent.getChildAt(i) instanceof ViewGroup) {
-                addAll(buttonDispatcher, (ViewGroup) parent.getChildAt(i));
-            }
-        }
-    }
-
-    protected void inflateLayout(String newLayout) {
-        mCurrentLayout = newLayout;
-        if (newLayout == null) {
-            newLayout = getDefaultLayout();
-        }
-        String[] sets = newLayout.split(GRAVITY_SEPARATOR, 3);
-        if (sets.length != 3) {
-            Log.d(TAG, "Invalid layout.");
-            newLayout = getDefaultLayout();
-            sets = newLayout.split(GRAVITY_SEPARATOR, 3);
-        }
-        String[] start = sets[0].split(BUTTON_SEPARATOR);
-        String[] center = sets[1].split(BUTTON_SEPARATOR);
-        String[] end = sets[2].split(BUTTON_SEPARATOR);
-        // Inflate these in start to end order or accessibility traversal will be messed up.
-        inflateButtons(start, mHorizontal.findViewById(R.id.ends_group),
-                false /* landscape */, true /* start */);
-        inflateButtons(start, mVertical.findViewById(R.id.ends_group),
-                true /* landscape */, true /* start */);
-
-        inflateButtons(center, mHorizontal.findViewById(R.id.center_group),
-                false /* landscape */, false /* start */);
-        inflateButtons(center, mVertical.findViewById(R.id.center_group),
-                true /* landscape */, false /* start */);
-
-        addGravitySpacer(mHorizontal.findViewById(R.id.ends_group));
-        addGravitySpacer(mVertical.findViewById(R.id.ends_group));
-
-        inflateButtons(end, mHorizontal.findViewById(R.id.ends_group),
-                false /* landscape */, false /* start */);
-        inflateButtons(end, mVertical.findViewById(R.id.ends_group),
-                true /* landscape */, false /* start */);
-
-        updateButtonDispatchersCurrentView();
-    }
-
-    private void addGravitySpacer(LinearLayout layout) {
-        layout.addView(new Space(mContext), new LinearLayout.LayoutParams(0, 0, 1));
-    }
-
-    private void inflateButtons(String[] buttons, ViewGroup parent, boolean landscape,
-            boolean start) {
-        for (int i = 0; i < buttons.length; i++) {
-            inflateButton(buttons[i], parent, landscape, start);
-        }
-    }
-
-    private ViewGroup.LayoutParams copy(ViewGroup.LayoutParams layoutParams) {
-        if (layoutParams instanceof LinearLayout.LayoutParams) {
-            return new LinearLayout.LayoutParams(layoutParams.width, layoutParams.height,
-                    ((LinearLayout.LayoutParams) layoutParams).weight);
-        }
-        return new LayoutParams(layoutParams.width, layoutParams.height);
-    }
-
-    @Nullable
-    protected View inflateButton(String buttonSpec, ViewGroup parent, boolean landscape,
-            boolean start) {
-        LayoutInflater inflater = landscape ? mLandscapeInflater : mLayoutInflater;
-        View v = createView(buttonSpec, parent, inflater);
-        if (v == null) return null;
-
-        v = applySize(v, buttonSpec, landscape, start);
-        parent.addView(v);
-        addToDispatchers(v);
-        View lastView = landscape ? mLastLandscape : mLastPortrait;
-        View accessibilityView = v;
-        if (v instanceof ReverseRelativeLayout) {
-            accessibilityView = ((ReverseRelativeLayout) v).getChildAt(0);
-        }
-        if (lastView != null) {
-            accessibilityView.setAccessibilityTraversalAfter(lastView.getId());
-        }
-        if (landscape) {
-            mLastLandscape = accessibilityView;
-        } else {
-            mLastPortrait = accessibilityView;
-        }
-        return v;
-    }
-
-    private View applySize(View v, String buttonSpec, boolean landscape, boolean start) {
-        String sizeStr = extractSize(buttonSpec);
-        if (sizeStr == null) return v;
-
-        if (sizeStr.contains(WEIGHT_SUFFIX) || sizeStr.contains(ABSOLUTE_SUFFIX)) {
-            // To support gravity, wrap in RelativeLayout and apply gravity to it.
-            // Children wanting to use gravity must be smaller then the frame.
-            ReverseRelativeLayout frame = new ReverseRelativeLayout(mContext);
-            LayoutParams childParams = new LayoutParams(v.getLayoutParams());
-
-            // Compute gravity to apply
-            int gravity = (landscape) ? (start ? Gravity.TOP : Gravity.BOTTOM)
-                    : (start ? Gravity.START : Gravity.END);
-            if (sizeStr.endsWith(WEIGHT_CENTERED_SUFFIX)) {
-                gravity = Gravity.CENTER;
-            } else if (sizeStr.endsWith(ABSOLUTE_VERTICAL_CENTERED_SUFFIX)) {
-                gravity = Gravity.CENTER_VERTICAL;
-            }
-
-            // Set default gravity, flipped if needed in reversed layouts (270 RTL and 90 LTR)
-            frame.setDefaultGravity(gravity);
-            frame.setGravity(gravity); // Apply gravity to root
-
-            frame.addView(v, childParams);
-
-            if (sizeStr.contains(WEIGHT_SUFFIX)) {
-                // Use weighting to set the width of the frame
-                float weight = Float.parseFloat(
-                        sizeStr.substring(0, sizeStr.indexOf(WEIGHT_SUFFIX)));
-                frame.setLayoutParams(new LinearLayout.LayoutParams(0, MATCH_PARENT, weight));
-            } else {
-                int width = (int) convertDpToPx(mContext,
-                        Float.parseFloat(sizeStr.substring(0, sizeStr.indexOf(ABSOLUTE_SUFFIX))));
-                frame.setLayoutParams(new LinearLayout.LayoutParams(width, MATCH_PARENT));
-            }
-
-            // Ensure ripples can be drawn outside bounds
-            frame.setClipChildren(false);
-            frame.setClipToPadding(false);
-
-            return frame;
-        }
-
-        float size = Float.parseFloat(sizeStr);
-        ViewGroup.LayoutParams params = v.getLayoutParams();
-        params.width = (int) (params.width * size);
-        return v;
-    }
-
-    View createView(String buttonSpec, ViewGroup parent, LayoutInflater inflater) {
-        View v = null;
-        String button = extractButton(buttonSpec);
-        if (LEFT.equals(button)) {
-            button = extractButton(NAVSPACE);
-        } else if (RIGHT.equals(button)) {
-            button = extractButton(MENU_IME_ROTATE);
-        }
-        if (HOME.equals(button)) {
-            v = inflater.inflate(R.layout.home, parent, false);
-        } else if (BACK.equals(button)) {
-            v = inflater.inflate(R.layout.back, parent, false);
-        } else if (RECENT.equals(button)) {
-            v = inflater.inflate(R.layout.recent_apps, parent, false);
-        } else if (MENU_IME_ROTATE.equals(button)) {
-            v = inflater.inflate(R.layout.menu_ime, parent, false);
-        } else if (NAVSPACE.equals(button)) {
-            v = inflater.inflate(R.layout.nav_key_space, parent, false);
-        } else if (CLIPBOARD.equals(button)) {
-            v = inflater.inflate(R.layout.clipboard, parent, false);
-        } else if (CONTEXTUAL.equals(button)) {
-            v = inflater.inflate(R.layout.contextual, parent, false);
-        } else if (HOME_HANDLE.equals(button)) {
-            v = inflater.inflate(R.layout.home_handle, parent, false);
-        } else if (IME_SWITCHER.equals(button)) {
-            v = inflater.inflate(R.layout.ime_switcher, parent, false);
-        } else if (button.startsWith(KEY)) {
-            String uri = extractImage(button);
-            int code = extractKeycode(button);
-            v = inflater.inflate(R.layout.custom_key, parent, false);
-            ((KeyButtonView) v).setCode(code);
-            if (uri != null) {
-                if (uri.contains(":")) {
-                    ((KeyButtonView) v).loadAsync(Icon.createWithContentUri(uri));
-                } else if (uri.contains("/")) {
-                    int index = uri.indexOf('/');
-                    String pkg = uri.substring(0, index);
-                    int id = Integer.parseInt(uri.substring(index + 1));
-                    ((KeyButtonView) v).loadAsync(Icon.createWithResource(pkg, id));
-                }
-            }
-        }
-        return v;
-    }
-
-    public static String extractImage(String buttonSpec) {
-        if (!buttonSpec.contains(KEY_IMAGE_DELIM)) {
-            return null;
-        }
-        final int start = buttonSpec.indexOf(KEY_IMAGE_DELIM);
-        String subStr = buttonSpec.substring(start + 1, buttonSpec.indexOf(KEY_CODE_END));
-        return subStr;
-    }
-
-    public static int extractKeycode(String buttonSpec) {
-        if (!buttonSpec.contains(KEY_CODE_START)) {
-            return 1;
-        }
-        final int start = buttonSpec.indexOf(KEY_CODE_START);
-        String subStr = buttonSpec.substring(start + 1, buttonSpec.indexOf(KEY_IMAGE_DELIM));
-        return Integer.parseInt(subStr);
-    }
-
-    public static String extractSize(String buttonSpec) {
-        if (!buttonSpec.contains(SIZE_MOD_START)) {
-            return null;
-        }
-        final int sizeStart = buttonSpec.indexOf(SIZE_MOD_START);
-        return buttonSpec.substring(sizeStart + 1, buttonSpec.indexOf(SIZE_MOD_END));
-    }
-
-    public static String extractButton(String buttonSpec) {
-        if (!buttonSpec.contains(SIZE_MOD_START)) {
-            return buttonSpec;
-        }
-        return buttonSpec.substring(0, buttonSpec.indexOf(SIZE_MOD_START));
-    }
-
-    private void addToDispatchers(View v) {
-        if (mButtonDispatchers != null) {
-            final int indexOfKey = mButtonDispatchers.indexOfKey(v.getId());
-            if (indexOfKey >= 0) {
-                mButtonDispatchers.valueAt(indexOfKey).addView(v);
-            }
-            if (v instanceof ViewGroup) {
-                final ViewGroup viewGroup = (ViewGroup)v;
-                final int N = viewGroup.getChildCount();
-                for (int i = 0; i < N; i++) {
-                    addToDispatchers(viewGroup.getChildAt(i));
-                }
-            }
-        }
-    }
-
-    private void clearDispatcherViews() {
-        if (mButtonDispatchers != null) {
-            for (int i = 0; i < mButtonDispatchers.size(); i++) {
-                mButtonDispatchers.valueAt(i).clear();
-            }
-        }
-    }
-
-    private void clearViews() {
-        clearDispatcherViews();
-        clearAllChildren(mHorizontal.findViewById(R.id.nav_buttons));
-        clearAllChildren(mVertical.findViewById(R.id.nav_buttons));
-    }
-
-    private void clearAllChildren(ViewGroup group) {
-        for (int i = 0; i < group.getChildCount(); i++) {
-            ((ViewGroup) group.getChildAt(i)).removeAllViews();
-        }
-    }
-
-    private static float convertDpToPx(Context context, float dp) {
-        return dp * context.getResources().getDisplayMetrics().density;
-    }
-
-    public void dump(PrintWriter pw) {
-        pw.println("NavigationBarInflaterView");
-        pw.println("  mCurrentLayout: " + mCurrentLayout);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java
index aab4fea..e2ba761 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java
@@ -24,6 +24,8 @@
 import com.android.systemui.dagger.qualifiers.DisplayId;
 import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope;
 import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
+import com.android.systemui.navigationbar.views.NavigationBarFrame;
+import com.android.systemui.navigationbar.views.NavigationBarView;
 import com.android.systemui.res.R;
 
 import dagger.Module;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java
deleted file mode 100644
index 201e586..0000000
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarTransitions.java
+++ /dev/null
@@ -1,256 +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.navigationbar;
-
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
-
-import static com.android.systemui.util.Utils.isGesturalModeOnDefaultDisplay;
-
-import android.graphics.Rect;
-import android.util.SparseArray;
-import android.view.View;
-
-import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope;
-import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
-import com.android.systemui.res.R;
-import com.android.systemui.settings.DisplayTracker;
-import com.android.systemui.statusbar.phone.BarTransitions;
-import com.android.systemui.statusbar.phone.LightBarTransitionsController;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.inject.Inject;
-
-/** */
-@NavigationBarScope
-public final class NavigationBarTransitions extends BarTransitions implements
-        LightBarTransitionsController.DarkIntensityApplier {
-
-    public static final int MIN_COLOR_ADAPT_TRANSITION_TIME = 400;
-    public static final int DEFAULT_COLOR_ADAPT_TRANSITION_TIME = 1700;
-    private List<Listener> mListeners = new ArrayList<>();
-
-    /**
-     * Notified when the color of nav bar elements changes.
-     */
-    public interface DarkIntensityListener {
-        /**
-         * Called when the color of nav bar elements changes.
-         * @param darkIntensity 0 is the lightest color, 1 is the darkest.
-         */
-        void onDarkIntensity(float darkIntensity);
-    }
-
-    private final NavigationBarView mView;
-    private final LightBarTransitionsController mLightTransitionsController;
-    private final DisplayTracker mDisplayTracker;
-    private final boolean mAllowAutoDimWallpaperNotVisible;
-    private boolean mWallpaperVisible;
-
-    private boolean mLightsOut;
-    private boolean mAutoDim;
-    private View mNavButtons;
-    private int mNavBarMode = NAV_BAR_MODE_3BUTTON;
-    private List<DarkIntensityListener> mDarkIntensityListeners;
-
-    @Inject
-    public NavigationBarTransitions(
-            NavigationBarView view,
-            LightBarTransitionsController.Factory lightBarTransitionsControllerFactory,
-            DisplayTracker displayTracker) {
-        super(view, R.drawable.nav_background);
-
-        mView = view;
-        mLightTransitionsController = lightBarTransitionsControllerFactory.create(this);
-        mDisplayTracker = displayTracker;
-        mAllowAutoDimWallpaperNotVisible = view.getContext().getResources()
-                .getBoolean(R.bool.config_navigation_bar_enable_auto_dim_no_visible_wallpaper);
-        mDarkIntensityListeners = new ArrayList();
-
-        mView.addOnLayoutChangeListener(
-                (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
-                    View currentView = mView.getCurrentView();
-                    if (currentView != null) {
-                        mNavButtons = currentView.findViewById(R.id.nav_buttons);
-                        applyLightsOut(false, true);
-                    }
-                });
-        View currentView = mView.getCurrentView();
-        if (currentView != null) {
-            mNavButtons = currentView.findViewById(R.id.nav_buttons);
-        }
-    }
-
-    public void init() {
-        applyModeBackground(-1, getMode(), false /*animate*/);
-        applyLightsOut(false /*animate*/, true /*force*/);
-    }
-
-    @Override
-    public void destroy() {
-        mLightTransitionsController.destroy();
-    }
-
-    void setWallpaperVisibility(boolean visible) {
-        mWallpaperVisible = visible;
-        applyLightsOut(true, false);
-    }
-
-    @Override
-    public void setAutoDim(boolean autoDim) {
-        // Ensure we aren't in gestural nav if we are triggering auto dim
-        if (autoDim && isGesturalModeOnDefaultDisplay(mView.getContext(), mDisplayTracker,
-                mNavBarMode)) {
-            return;
-        }
-        if (mAutoDim == autoDim) return;
-        mAutoDim = autoDim;
-        applyLightsOut(true, false);
-    }
-
-    void setBackgroundFrame(Rect frame) {
-        mBarBackground.setFrame(frame);
-    }
-
-    void setBackgroundOverrideAlpha(float alpha) {
-        mBarBackground.setOverrideAlpha(alpha);
-    }
-
-    @Override
-    protected boolean isLightsOut(int mode) {
-        return super.isLightsOut(mode) || (mAllowAutoDimWallpaperNotVisible && mAutoDim
-                && !mWallpaperVisible && mode != MODE_WARNING);
-    }
-
-    public LightBarTransitionsController getLightTransitionsController() {
-        return mLightTransitionsController;
-    }
-
-    @Override
-    protected void onTransition(int oldMode, int newMode, boolean animate) {
-        super.onTransition(oldMode, newMode, animate);
-        applyLightsOut(animate, false /*force*/);
-        for (Listener listener : mListeners) {
-            listener.onTransition(newMode);
-        }
-    }
-
-    private void applyLightsOut(boolean animate, boolean force) {
-        // apply to lights out
-        applyLightsOut(isLightsOut(getMode()), animate, force);
-    }
-
-    private void applyLightsOut(boolean lightsOut, boolean animate, boolean force) {
-        if (!force && lightsOut == mLightsOut) return;
-
-        mLightsOut = lightsOut;
-        if (mNavButtons == null) return;
-
-        // ok, everyone, stop it right there
-        mNavButtons.animate().cancel();
-
-        // Bump percentage by 10% if dark.
-        float darkBump = mLightTransitionsController.getCurrentDarkIntensity() / 10;
-        final float navButtonsAlpha = lightsOut ? 0.6f + darkBump : 1f;
-
-        if (!animate) {
-            mNavButtons.setAlpha(navButtonsAlpha);
-        } else {
-            final int duration = lightsOut ? LIGHTS_OUT_DURATION : LIGHTS_IN_DURATION;
-            mNavButtons.animate()
-                .alpha(navButtonsAlpha)
-                .setDuration(duration)
-                .start();
-        }
-    }
-
-    public void reapplyDarkIntensity() {
-        applyDarkIntensity(mLightTransitionsController.getCurrentDarkIntensity());
-    }
-
-    @Override
-    public void applyDarkIntensity(float darkIntensity) {
-        SparseArray<ButtonDispatcher> buttonDispatchers = mView.getButtonDispatchers();
-        for (int i = buttonDispatchers.size() - 1; i >= 0; i--) {
-            buttonDispatchers.valueAt(i).setDarkIntensity(darkIntensity);
-        }
-        mView.getRotationButtonController().setDarkIntensity(darkIntensity);
-
-        for (DarkIntensityListener listener : mDarkIntensityListeners) {
-            listener.onDarkIntensity(darkIntensity);
-        }
-        if (mAutoDim) {
-            applyLightsOut(false, true);
-        }
-    }
-
-    @Override
-    public int getTintAnimationDuration() {
-        if (isGesturalModeOnDefaultDisplay(mView.getContext(), mDisplayTracker, mNavBarMode)) {
-            return Math.max(DEFAULT_COLOR_ADAPT_TRANSITION_TIME, MIN_COLOR_ADAPT_TRANSITION_TIME);
-        }
-        return LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION;
-    }
-
-    public void onNavigationModeChanged(int mode) {
-        mNavBarMode = mode;
-    }
-
-    /**
-     * Register {@code listener} to be notified when the color of nav bar elements changes.
-     *
-     * Returns the current nav bar color.
-     */
-    public float addDarkIntensityListener(DarkIntensityListener listener) {
-        mDarkIntensityListeners.add(listener);
-        return mLightTransitionsController.getCurrentDarkIntensity();
-    }
-
-    /**
-     * Remove {@code listener} from being notified when the color of nav bar elements changes.
-     */
-    public void removeDarkIntensityListener(DarkIntensityListener listener) {
-        mDarkIntensityListeners.remove(listener);
-    }
-
-    public void dump(PrintWriter pw) {
-        pw.println("NavigationBarTransitions:");
-        pw.println("  mMode: " + getMode());
-        pw.println("  mAlwaysOpaque: " + isAlwaysOpaque());
-        pw.println("  mAllowAutoDimWallpaperNotVisible: " + mAllowAutoDimWallpaperNotVisible);
-        pw.println("  mWallpaperVisible: " + mWallpaperVisible);
-        pw.println("  mLightsOut: " + mLightsOut);
-        pw.println("  mAutoDim: " + mAutoDim);
-        pw.println("  bg overrideAlpha: " + mBarBackground.getOverrideAlpha());
-        pw.println("  bg color: " + mBarBackground.getColor());
-        pw.println("  bg frame: " + mBarBackground.getFrame());
-    }
-
-    void addListener(Listener listener) {
-        mListeners.add(listener);
-    }
-
-    void removeListener(Listener listener) {
-        mListeners.remove(listener);
-    }
-
-    interface Listener {
-        void onTransition(int newMode);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
deleted file mode 100644
index 2c6e297..0000000
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ /dev/null
@@ -1,1211 +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.navigationbar;
-
-import static android.inputmethodservice.InputMethodService.canImeRenderGesturalNavButtons;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
-
-import static com.android.systemui.Flags.enableViewCaptureTracing;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SEARCH_DISABLED;
-import static com.android.systemui.shared.system.QuickStepContract.isGesturalMode;
-
-import android.animation.LayoutTransition;
-import android.animation.LayoutTransition.TransitionListener;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.animation.TimeInterpolator;
-import android.animation.ValueAnimator;
-import android.annotation.DrawableRes;
-import android.app.StatusBarManager;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.graphics.Canvas;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.media.permission.SafeCloseable;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.ContextThemeWrapper;
-import android.view.Display;
-import android.view.MotionEvent;
-import android.view.Surface;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowInsets;
-import android.view.WindowInsetsController.Behavior;
-import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
-import android.widget.FrameLayout;
-
-import androidx.annotation.Nullable;
-
-import com.android.app.animation.Interpolators;
-import com.android.app.viewcapture.ViewCaptureFactory;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.settingslib.Utils;
-import com.android.systemui.Gefingerpoken;
-import com.android.systemui.model.SysUiState;
-import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
-import com.android.systemui.navigationbar.buttons.ContextualButton;
-import com.android.systemui.navigationbar.buttons.ContextualButtonGroup;
-import com.android.systemui.navigationbar.buttons.DeadZone;
-import com.android.systemui.navigationbar.buttons.KeyButtonDrawable;
-import com.android.systemui.navigationbar.buttons.NearestTouchFrame;
-import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.res.R;
-import com.android.systemui.settings.DisplayTracker;
-import com.android.systemui.shade.ShadeViewController;
-import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor;
-import com.android.systemui.shared.rotation.FloatingRotationButton;
-import com.android.systemui.shared.rotation.RotationButton.RotationButtonUpdatesCallback;
-import com.android.systemui.shared.rotation.RotationButtonController;
-import com.android.systemui.shared.system.QuickStepContract;
-import com.android.systemui.statusbar.phone.AutoHideController;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
-import com.android.systemui.statusbar.phone.LightBarTransitionsController;
-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;
-
-/** */
-public class NavigationBarView extends FrameLayout {
-    final static boolean DEBUG = false;
-    final static String TAG = "NavBarView";
-
-    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;
-    private View mHorizontal;
-
-    /** Indicates that navigation bar is vertical. */
-    private boolean mIsVertical;
-    private int mCurrentRotation = -1;
-
-    boolean mLongClickableAccessibilityButton;
-    int mDisabledFlags = 0;
-    int mNavigationIconHints = 0;
-    private int mNavBarMode;
-    private boolean mImeDrawsImeNavBar;
-
-    private KeyButtonDrawable mBackIcon;
-    private KeyButtonDrawable mHomeDefaultIcon;
-    private KeyButtonDrawable mRecentIcon;
-    private KeyButtonDrawable mDockedIcon;
-    private Context mLightContext;
-    private int mLightIconColor;
-    private int mDarkIconColor;
-
-    private EdgeBackGestureHandler mEdgeBackGestureHandler;
-    private DisplayTracker mDisplayTracker;
-    private final DeadZone mDeadZone;
-    private NavigationBarTransitions mBarTransitions;
-    @Nullable
-    private AutoHideController mAutoHideController;
-
-    // performs manual animation in sync with layout transitions
-    private final NavTransitionListener mTransitionListener = new NavTransitionListener();
-
-    private OnVerticalChangedListener mOnVerticalChangedListener;
-    private boolean mLayoutTransitionsEnabled = true;
-    private boolean mWakeAndUnlocking;
-    private boolean mUseCarModeUi = false;
-    private boolean mInCarMode = false;
-    private boolean mDockedStackExists;
-    private boolean mScreenOn = true;
-
-    private final SparseArray<ButtonDispatcher> mButtonDispatchers = new SparseArray<>();
-    private final ContextualButtonGroup mContextualButtonGroup;
-    private Configuration mConfiguration;
-    private Configuration mTmpLastConfiguration;
-
-    private NavigationBarInflaterView mNavigationInflaterView;
-    private Optional<Recents> mRecentsOptional = Optional.empty();
-    @Nullable
-    private ShadeViewController mShadeViewController;
-    @Nullable
-    private PanelExpansionInteractor mPanelExpansionInteractor;
-    private FloatingRotationButton mFloatingRotationButton;
-    private RotationButtonController mRotationButtonController;
-
-    /**
-     * Helper that is responsible for showing the right toast when a disallowed activity operation
-     * occurred. In pinned mode, we show instructions on how to break out of this mode, whilst in
-     * fully locked mode we only show that unlocking is blocked.
-     */
-    private ScreenPinningNotify mScreenPinningNotify;
-    private boolean mScreenPinningActive = false;
-
-    /**
-     * {@code true} if the IME can render the back button and the IME switcher button.
-     *
-     * <p>The value must be used when and only when
-     * {@link com.android.systemui.shared.system.QuickStepContract#isGesturalMode(int)} returns
-     * {@code true}</p>
-     *
-     * <p>Cache the value here for better performance.</p>
-     */
-    private final boolean mImeCanRenderGesturalNavButtons = canImeRenderGesturalNavButtons();
-    private Gefingerpoken mTouchHandler;
-    private boolean mOverviewProxyEnabled;
-    private boolean mShowSwipeUpUi;
-    private UpdateActiveTouchRegionsCallback mUpdateActiveTouchRegionsCallback;
-    private SafeCloseable mViewCaptureCloseable;
-
-    private class NavTransitionListener implements TransitionListener {
-        private boolean mBackTransitioning;
-        private boolean mHomeAppearing;
-        private long mStartDelay;
-        private long mDuration;
-        private TimeInterpolator mInterpolator;
-
-        @Override
-        public void startTransition(LayoutTransition transition, ViewGroup container,
-                View view, int transitionType) {
-            if (view.getId() == R.id.back) {
-                mBackTransitioning = true;
-            } else if (view.getId() == R.id.home && transitionType == LayoutTransition.APPEARING) {
-                mHomeAppearing = true;
-                mStartDelay = transition.getStartDelay(transitionType);
-                mDuration = transition.getDuration(transitionType);
-                mInterpolator = transition.getInterpolator(transitionType);
-            }
-        }
-
-        @Override
-        public void endTransition(LayoutTransition transition, ViewGroup container,
-                View view, int transitionType) {
-            if (view.getId() == R.id.back) {
-                mBackTransitioning = false;
-            } else if (view.getId() == R.id.home && transitionType == LayoutTransition.APPEARING) {
-                mHomeAppearing = false;
-            }
-        }
-
-        public void onBackAltCleared() {
-            ButtonDispatcher backButton = getBackButton();
-
-            // When dismissing ime during unlock, force the back button to run the same appearance
-            // animation as home (if we catch this condition early enough).
-            if (!mBackTransitioning && backButton.getVisibility() == VISIBLE
-                    && mHomeAppearing && getHomeButton().getAlpha() == 0) {
-                getBackButton().setAlpha(0);
-                ValueAnimator a = ObjectAnimator.ofFloat(backButton, "alpha", 0, 1);
-                a.setStartDelay(mStartDelay);
-                a.setDuration(mDuration);
-                a.setInterpolator(mInterpolator);
-                a.start();
-            }
-        }
-    }
-
-    private final AccessibilityDelegate mQuickStepAccessibilityDelegate =
-            new AccessibilityDelegate() {
-                private AccessibilityAction mToggleOverviewAction;
-
-                @Override
-                public void onInitializeAccessibilityNodeInfo(View host,
-                        AccessibilityNodeInfo info) {
-                    super.onInitializeAccessibilityNodeInfo(host, info);
-                    if (mToggleOverviewAction == null) {
-                        mToggleOverviewAction = new AccessibilityAction(
-                                R.id.action_toggle_overview, getContext().getString(
-                                R.string.quick_step_accessibility_toggle_overview));
-                    }
-                    info.addAction(mToggleOverviewAction);
-                }
-
-                @Override
-                public boolean performAccessibilityAction(View host, int action, Bundle args) {
-                    if (action == R.id.action_toggle_overview) {
-                        mRecentsOptional.ifPresent(Recents::toggleRecentApps);
-                    } else {
-                        return super.performAccessibilityAction(host, action, args);
-                    }
-                    return true;
-                }
-            };
-
-    private final RotationButtonUpdatesCallback mRotationButtonListener =
-            new RotationButtonUpdatesCallback() {
-                @Override
-                public void onVisibilityChanged(boolean visible) {
-                    if (visible && mAutoHideController != null) {
-                        // If the button will actually become visible and the navbar is about
-                        // to hide, tell the statusbar to keep it around for longer
-                        mAutoHideController.touchAutoHide();
-                    }
-                    notifyActiveTouchRegions();
-                }
-
-                @Override
-                public void onPositionChanged() {
-                    notifyActiveTouchRegions();
-                }
-            };
-
-    public NavigationBarView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        final Context darkContext = new ContextThemeWrapper(context,
-                Utils.getThemeAttr(context, R.attr.darkIconTheme));
-        mLightContext = new ContextThemeWrapper(context,
-                Utils.getThemeAttr(context, R.attr.lightIconTheme));
-        mLightIconColor = Utils.getColorAttrDefaultColor(mLightContext, R.attr.singleToneColor);
-        mDarkIconColor = Utils.getColorAttrDefaultColor(darkContext, R.attr.singleToneColor);
-        mIsVertical = false;
-        mLongClickableAccessibilityButton = false;
-
-        // Set up the context group of buttons
-        mContextualButtonGroup = new ContextualButtonGroup(R.id.menu_container);
-        final ContextualButton imeSwitcherButton = new ContextualButton(R.id.ime_switcher,
-                mLightContext, R.drawable.ic_ime_switcher_default);
-        final ContextualButton accessibilityButton =
-                new ContextualButton(R.id.accessibility_button, mLightContext,
-                        R.drawable.ic_sysbar_accessibility_button);
-        mContextualButtonGroup.addButton(imeSwitcherButton);
-        mContextualButtonGroup.addButton(accessibilityButton);
-        mFloatingRotationButton = new FloatingRotationButton(mContext,
-                R.string.accessibility_rotate_button,
-                R.layout.rotate_suggestion,
-                R.id.rotate_suggestion,
-                R.dimen.floating_rotation_button_min_margin,
-                R.dimen.rounded_corner_content_padding,
-                R.dimen.floating_rotation_button_taskbar_left_margin,
-                R.dimen.floating_rotation_button_taskbar_bottom_margin,
-                R.dimen.floating_rotation_button_diameter,
-                R.dimen.key_button_ripple_max_width,
-                R.bool.floating_rotation_button_position_left);
-        mRotationButtonController = new RotationButtonController(mLightContext, mLightIconColor,
-                mDarkIconColor, R.drawable.ic_sysbar_rotate_button_ccw_start_0,
-                R.drawable.ic_sysbar_rotate_button_ccw_start_90,
-                R.drawable.ic_sysbar_rotate_button_cw_start_0,
-                R.drawable.ic_sysbar_rotate_button_cw_start_90,
-                () -> mCurrentRotation);
-
-        mConfiguration = new Configuration();
-        mTmpLastConfiguration = new Configuration();
-        mConfiguration.updateFrom(context.getResources().getConfiguration());
-
-        mScreenPinningNotify = new ScreenPinningNotify(mContext);
-
-        mButtonDispatchers.put(R.id.back, new ButtonDispatcher(R.id.back));
-        mButtonDispatchers.put(R.id.home, new ButtonDispatcher(R.id.home));
-        mButtonDispatchers.put(R.id.home_handle, new ButtonDispatcher(R.id.home_handle));
-        mButtonDispatchers.put(R.id.recent_apps, new ButtonDispatcher(R.id.recent_apps));
-        mButtonDispatchers.put(R.id.ime_switcher, imeSwitcherButton);
-        mButtonDispatchers.put(R.id.accessibility_button, accessibilityButton);
-        mButtonDispatchers.put(R.id.menu_container, mContextualButtonGroup);
-        mDeadZone = new DeadZone(this);
-    }
-
-    public void setEdgeBackGestureHandler(EdgeBackGestureHandler edgeBackGestureHandler) {
-        mEdgeBackGestureHandler = edgeBackGestureHandler;
-    }
-
-    void setBarTransitions(NavigationBarTransitions navigationBarTransitions) {
-        mBarTransitions = navigationBarTransitions;
-    }
-
-    public void setAutoHideController(AutoHideController autoHideController) {
-        mAutoHideController = autoHideController;
-    }
-
-    public LightBarTransitionsController getLightTransitionsController() {
-        return mBarTransitions.getLightTransitionsController();
-    }
-
-    public void setComponents(Optional<Recents> recentsOptional) {
-        mRecentsOptional = recentsOptional;
-    }
-
-    /** */
-    public void setComponents(ShadeViewController svc, PanelExpansionInteractor pei) {
-        mShadeViewController = svc;
-        mPanelExpansionInteractor = pei;
-        updatePanelSystemUiStateFlags();
-    }
-
-    public void setOnVerticalChangedListener(OnVerticalChangedListener onVerticalChangedListener) {
-        mOnVerticalChangedListener = onVerticalChangedListener;
-        notifyVerticalChangedListener(mIsVertical);
-    }
-
-    public void setBackgroundExecutor(Executor bgExecutor) {
-        mBgExecutor = bgExecutor;
-        mRotationButtonController.setBgExecutor(bgExecutor);
-    }
-
-    public void setDisplayTracker(DisplayTracker displayTracker) {
-        mDisplayTracker = displayTracker;
-    }
-
-    public void setTouchHandler(Gefingerpoken touchHandler) {
-        mTouchHandler = touchHandler;
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent event) {
-        return mTouchHandler.onInterceptTouchEvent(event) || super.onInterceptTouchEvent(event);
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        mTouchHandler.onTouchEvent(event);
-        return super.onTouchEvent(event);
-    }
-
-    public void abortCurrentGesture() {
-        getHomeButton().abortCurrentGesture();
-    }
-
-    public View getCurrentView() {
-        return mCurrentView;
-    }
-
-    /**
-     * Applies {@param consumer} to each of the nav bar views.
-     */
-    public void forEachView(Consumer<View> consumer) {
-        if (mVertical != null) {
-            consumer.accept(mVertical);
-        }
-        if (mHorizontal != null) {
-            consumer.accept(mHorizontal);
-        }
-    }
-
-    public RotationButtonController getRotationButtonController() {
-        return mRotationButtonController;
-    }
-
-    public FloatingRotationButton getFloatingRotationButton() {
-        return mFloatingRotationButton;
-    }
-
-    public ButtonDispatcher getRecentsButton() {
-        return mButtonDispatchers.get(R.id.recent_apps);
-    }
-
-    public ButtonDispatcher getBackButton() {
-        return mButtonDispatchers.get(R.id.back);
-    }
-
-    public ButtonDispatcher getHomeButton() {
-        return mButtonDispatchers.get(R.id.home);
-    }
-
-    public ButtonDispatcher getImeSwitchButton() {
-        return mButtonDispatchers.get(R.id.ime_switcher);
-    }
-
-    public ButtonDispatcher getAccessibilityButton() {
-        return mButtonDispatchers.get(R.id.accessibility_button);
-    }
-
-    public ButtonDispatcher getHomeHandle() {
-        return mButtonDispatchers.get(R.id.home_handle);
-    }
-
-    public SparseArray<ButtonDispatcher> getButtonDispatchers() {
-        return mButtonDispatchers;
-    }
-
-    public boolean isRecentsButtonVisible() {
-        return getRecentsButton().getVisibility() == View.VISIBLE;
-    }
-
-    public boolean isOverviewEnabled() {
-        return (mDisabledFlags & View.STATUS_BAR_DISABLE_RECENT) == 0;
-    }
-
-    private boolean isQuickStepSwipeUpEnabled() {
-        return mShowSwipeUpUi && isOverviewEnabled();
-    }
-
-    private void reloadNavIcons() {
-        updateIcons(Configuration.EMPTY);
-    }
-
-    private void updateIcons(Configuration oldConfig) {
-        final boolean orientationChange = oldConfig.orientation != mConfiguration.orientation;
-        final boolean densityChange = oldConfig.densityDpi != mConfiguration.densityDpi;
-        final boolean dirChange = oldConfig.getLayoutDirection() != mConfiguration.getLayoutDirection();
-
-        if (orientationChange || densityChange) {
-            mDockedIcon = getDrawable(R.drawable.ic_sysbar_docked);
-            mHomeDefaultIcon = getHomeDrawable();
-        }
-        if (densityChange || dirChange) {
-            mRecentIcon = getDrawable(R.drawable.ic_sysbar_recent);
-            mContextualButtonGroup.updateIcons(mLightIconColor, mDarkIconColor);
-        }
-        if (orientationChange || densityChange || dirChange) {
-            mBackIcon = getBackDrawable();
-        }
-    }
-
-    /**
-     * Updates the rotation button based on the current navigation mode.
-     */
-    void updateRotationButton() {
-        mRotationButtonController.setRotationButton(mFloatingRotationButton,
-                mRotationButtonListener);
-    }
-
-    public KeyButtonDrawable getBackDrawable() {
-        KeyButtonDrawable drawable = getDrawable(R.drawable.ic_sysbar_back);
-        orientBackButton(drawable);
-        return drawable;
-    }
-
-    public KeyButtonDrawable getHomeDrawable() {
-        KeyButtonDrawable drawable = mShowSwipeUpUi
-                ? getDrawable(R.drawable.ic_sysbar_home_quick_step)
-                : getDrawable(R.drawable.ic_sysbar_home);
-        orientHomeButton(drawable);
-        return drawable;
-    }
-
-    private void orientBackButton(KeyButtonDrawable drawable) {
-        final boolean useAltBack =
-                (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
-        final boolean isRtl = mConfiguration.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
-        float degrees = useAltBack ? (isRtl ? 90 : -90) : 0;
-        if (drawable.getRotation() == degrees) {
-            return;
-        }
-
-        if (isGesturalMode(mNavBarMode)) {
-            drawable.setRotation(degrees);
-            return;
-        }
-
-        // Animate the back button's rotation to the new degrees and only in portrait move up the
-        // back button to line up with the other buttons
-        float targetY = !mShowSwipeUpUi && !mIsVertical && useAltBack
-                ? - getResources().getDimension(R.dimen.navbar_back_button_ime_offset)
-                : 0;
-        ObjectAnimator navBarAnimator = ObjectAnimator.ofPropertyValuesHolder(drawable,
-                PropertyValuesHolder.ofFloat(KeyButtonDrawable.KEY_DRAWABLE_ROTATE, degrees),
-                PropertyValuesHolder.ofFloat(KeyButtonDrawable.KEY_DRAWABLE_TRANSLATE_Y, targetY));
-        navBarAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
-        navBarAnimator.setDuration(200);
-        navBarAnimator.start();
-    }
-
-    private void orientHomeButton(KeyButtonDrawable drawable) {
-        drawable.setRotation(mIsVertical ? 90 : 0);
-    }
-
-    private KeyButtonDrawable getDrawable(@DrawableRes int icon) {
-        return KeyButtonDrawable.create(mLightContext, mLightIconColor, mDarkIconColor, icon,
-                true /* hasShadow */, null /* ovalBackgroundColor */);
-    }
-
-    /** To be called when screen lock/unlock state changes */
-    public void onScreenStateChanged(boolean isScreenOn) {
-        mScreenOn = isScreenOn;
-    }
-
-    public void setWindowVisible(boolean visible) {
-        mRotationButtonController.onNavigationBarWindowVisibilityChange(visible);
-    }
-
-    public void setBehavior(@Behavior int behavior) {
-        mRotationButtonController.onBehaviorChanged(mDisplayTracker.getDefaultDisplayId(),
-                behavior);
-    }
-
-    @Override
-    public void setLayoutDirection(int layoutDirection) {
-        reloadNavIcons();
-
-        super.setLayoutDirection(layoutDirection);
-    }
-
-    void setNavigationIconHints(int hints) {
-        if (hints == mNavigationIconHints) return;
-        mNavigationIconHints = hints;
-        updateNavButtonIcons();
-    }
-
-    void onImeVisibilityChanged(boolean visible) {
-        if (!visible) {
-            mTransitionListener.onBackAltCleared();
-        }
-    }
-
-    void setDisabledFlags(int disabledFlags, SysUiState sysUiState) {
-        if (mDisabledFlags == disabledFlags) return;
-
-        final boolean overviewEnabledBefore = isOverviewEnabled();
-        mDisabledFlags = disabledFlags;
-
-        // Update icons if overview was just enabled to ensure the correct icons are present
-        if (!overviewEnabledBefore && isOverviewEnabled()) {
-            reloadNavIcons();
-        }
-
-        updateNavButtonIcons();
-        updateSlippery();
-        updateDisabledSystemUiStateFlags(sysUiState);
-    }
-
-    public void updateNavButtonIcons() {
-        // We have to replace or restore the back and home button icons when exiting or entering
-        // carmode, respectively. Recents are not available in CarMode in nav bar so change
-        // to recent icon is not required.
-        final boolean useAltBack =
-                (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
-        KeyButtonDrawable backIcon = mBackIcon;
-        orientBackButton(backIcon);
-        KeyButtonDrawable homeIcon = mHomeDefaultIcon;
-        if (!mUseCarModeUi) {
-            orientHomeButton(homeIcon);
-        }
-        getHomeButton().setImageDrawable(homeIcon);
-        getBackButton().setImageDrawable(backIcon);
-
-        updateRecentsIcon();
-
-        // Update IME button visibility, a11y and rotate button always overrides the appearance
-        boolean disableImeSwitcher =
-                (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN) == 0
-                || isImeRenderingNavButtons();
-        mContextualButtonGroup.setButtonVisibility(R.id.ime_switcher, !disableImeSwitcher);
-
-        mBarTransitions.reapplyDarkIntensity();
-
-        boolean disableHome = isGesturalMode(mNavBarMode)
-                || ((mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
-
-        // Always disable recents when alternate car mode UI is active and for secondary displays.
-        boolean disableRecent = isRecentsButtonDisabled();
-
-        // Disable the home handle if both hone and recents are disabled
-        boolean disableHomeHandle = disableRecent
-                && ((mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
-
-        boolean disableBack = !useAltBack && (mEdgeBackGestureHandler.isHandlingGestures()
-                || ((mDisabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0))
-                || isImeRenderingNavButtons();
-
-        // When screen pinning, don't hide back and home when connected service or back and
-        // recents buttons when disconnected from launcher service in screen pinning mode,
-        // as they are used for exiting.
-        if (mOverviewProxyEnabled) {
-            // Force disable recents when not in legacy mode
-            disableRecent |= !QuickStepContract.isLegacyMode(mNavBarMode);
-            if (mScreenPinningActive && !QuickStepContract.isGesturalMode(mNavBarMode)) {
-                disableBack = disableHome = false;
-            }
-        } else if (mScreenPinningActive) {
-            disableBack = disableRecent = false;
-        }
-
-        ViewGroup navButtons = getCurrentView().findViewById(R.id.nav_buttons);
-        if (navButtons != null) {
-            LayoutTransition lt = navButtons.getLayoutTransition();
-            if (lt != null) {
-                if (!lt.getTransitionListeners().contains(mTransitionListener)) {
-                    lt.addTransitionListener(mTransitionListener);
-                }
-            }
-        }
-
-        getBackButton().setVisibility(disableBack       ? View.INVISIBLE : View.VISIBLE);
-        getHomeButton().setVisibility(disableHome       ? View.INVISIBLE : View.VISIBLE);
-        getRecentsButton().setVisibility(disableRecent  ? View.INVISIBLE : View.VISIBLE);
-        getHomeHandle().setVisibility(disableHomeHandle ? View.INVISIBLE : View.VISIBLE);
-        notifyActiveTouchRegions();
-    }
-
-    /**
-     * Returns whether the IME is currently visible and drawing the nav buttons.
-     */
-    boolean isImeRenderingNavButtons() {
-        return mImeDrawsImeNavBar
-                && mImeCanRenderGesturalNavButtons
-                && (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) != 0;
-    }
-
-    @VisibleForTesting
-    boolean isRecentsButtonDisabled() {
-        return mUseCarModeUi || !isOverviewEnabled()
-                || getContext().getDisplayId() != mDisplayTracker.getDefaultDisplayId();
-    }
-
-    private Display getContextDisplay() {
-        return getContext().getDisplay();
-    }
-
-    public void setLayoutTransitionsEnabled(boolean enabled) {
-        mLayoutTransitionsEnabled = enabled;
-        updateLayoutTransitionsEnabled();
-    }
-
-    public void setWakeAndUnlocking(boolean wakeAndUnlocking) {
-        setUseFadingAnimations(wakeAndUnlocking);
-        mWakeAndUnlocking = wakeAndUnlocking;
-        updateLayoutTransitionsEnabled();
-    }
-
-    private void updateLayoutTransitionsEnabled() {
-        boolean enabled = !mWakeAndUnlocking && mLayoutTransitionsEnabled;
-        ViewGroup navButtons = (ViewGroup) getCurrentView().findViewById(R.id.nav_buttons);
-        LayoutTransition lt = navButtons.getLayoutTransition();
-        if (lt != null) {
-            if (enabled) {
-                lt.enableTransitionType(LayoutTransition.APPEARING);
-                lt.enableTransitionType(LayoutTransition.DISAPPEARING);
-                lt.enableTransitionType(LayoutTransition.CHANGE_APPEARING);
-                lt.enableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
-            } else {
-                lt.disableTransitionType(LayoutTransition.APPEARING);
-                lt.disableTransitionType(LayoutTransition.DISAPPEARING);
-                lt.disableTransitionType(LayoutTransition.CHANGE_APPEARING);
-                lt.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
-            }
-        }
-    }
-
-    private void setUseFadingAnimations(boolean useFadingAnimations) {
-        WindowManager.LayoutParams lp = (WindowManager.LayoutParams) ((ViewGroup) getParent())
-                .getLayoutParams();
-        if (lp != null) {
-            boolean old = lp.windowAnimations != 0;
-            if (!old && useFadingAnimations) {
-                lp.windowAnimations = R.style.Animation_NavigationBarFadeIn;
-            } else if (old && !useFadingAnimations) {
-                lp.windowAnimations = 0;
-            } else {
-                return;
-            }
-            WindowManager wm = getContext().getSystemService(WindowManager.class);
-            wm.updateViewLayout((View) getParent(), lp);
-        }
-    }
-
-    public void onStatusBarPanelStateChanged() {
-        updateSlippery();
-    }
-
-    /** */
-    public void updateDisabledSystemUiStateFlags(SysUiState sysUiState) {
-        int displayId = mContext.getDisplayId();
-
-        sysUiState.setFlag(SYSUI_STATE_OVERVIEW_DISABLED,
-                        (mDisabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0)
-                .setFlag(SYSUI_STATE_HOME_DISABLED,
-                        (mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0)
-                .setFlag(SYSUI_STATE_SEARCH_DISABLED,
-                        (mDisabledFlags & View.STATUS_BAR_DISABLE_SEARCH) != 0)
-                .commitUpdate(displayId);
-    }
-
-    public void setInScreenPinning(boolean active) {
-        mScreenPinningActive = active;
-    }
-
-    private void updatePanelSystemUiStateFlags() {
-        if (SysUiState.DEBUG) {
-            Log.d(TAG, "Updating panel sysui state flags: panelView=" + mShadeViewController);
-        }
-        if (mShadeViewController != null) {
-            mShadeViewController.updateSystemUiStateFlags();
-        }
-    }
-
-    void onOverviewProxyConnectionChange(boolean enabled) {
-        mOverviewProxyEnabled = enabled;
-    }
-
-    void setShouldShowSwipeUpUi(boolean showSwipeUpUi) {
-        mShowSwipeUpUi = showSwipeUpUi;
-        updateStates();
-    }
-
-    /** */
-    public void updateStates() {
-        if (mNavigationInflaterView != null) {
-            // Reinflate the navbar if needed, no-op unless the swipe up state changes
-            mNavigationInflaterView.onLikelyDefaultLayoutChange();
-        }
-
-        updateSlippery();
-        reloadNavIcons();
-        updateNavButtonIcons();
-        mBgExecutor.execute(() -> setNavBarVirtualKeyHapticFeedbackEnabled(!mShowSwipeUpUi));
-        getHomeButton().setAccessibilityDelegate(
-                mShowSwipeUpUi ? mQuickStepAccessibilityDelegate : null);
-    }
-
-    /**
-     * Enable or disable haptic feedback on the navigation bar buttons.
-     */
-    private void setNavBarVirtualKeyHapticFeedbackEnabled(boolean enabled) {
-        try {
-            WindowManagerGlobal.getWindowManagerService()
-                    .setNavBarVirtualKeyHapticFeedbackEnabled(enabled);
-        } catch (RemoteException e) {
-            Log.w(TAG, "Failed to enable or disable navigation bar button haptics: ", e);
-        }
-    }
-
-    /**
-     * Updates the {@link WindowManager.LayoutParams.FLAG_SLIPPERY} state dependent on if swipe up
-     * is enabled, or the notifications is fully opened without being in an animated state. If
-     * slippery is enabled, touch events will leave the nav bar window and enter into the fullscreen
-     * app/home window, if not nav bar will receive a cancelled touch event once gesture leaves bar.
-     */
-    void updateSlippery() {
-        setSlippery(!isQuickStepSwipeUpEnabled() ||
-                (mPanelExpansionInteractor != null && mPanelExpansionInteractor.isFullyExpanded()
-                        && !mPanelExpansionInteractor.isCollapsing()));
-    }
-
-    void setSlippery(boolean slippery) {
-        setWindowFlag(WindowManager.LayoutParams.FLAG_SLIPPERY, slippery);
-    }
-
-    private void setWindowFlag(int flags, boolean enable) {
-        final ViewGroup navbarView = ((ViewGroup) getParent());
-        if (navbarView == null) {
-            return;
-        }
-        WindowManager.LayoutParams lp = (WindowManager.LayoutParams) navbarView.getLayoutParams();
-        if (lp == null || enable == ((lp.flags & flags) != 0)) {
-            return;
-        }
-        if (enable) {
-            lp.flags |= flags;
-        } else {
-            lp.flags &= ~flags;
-        }
-        WindowManager wm = getContext().getSystemService(WindowManager.class);
-        wm.updateViewLayout(navbarView, lp);
-    }
-
-    void setNavBarMode(int mode, boolean imeDrawsImeNavBar) {
-        mNavBarMode = mode;
-        mImeDrawsImeNavBar = imeDrawsImeNavBar;
-        mBarTransitions.onNavigationModeChanged(mNavBarMode);
-        mEdgeBackGestureHandler.onNavigationModeChanged(mNavBarMode);
-        mRotationButtonController.onNavigationModeChanged(mNavBarMode);
-        updateRotationButton();
-    }
-
-    public void setAccessibilityButtonState(final boolean visible, final boolean longClickable) {
-        mLongClickableAccessibilityButton = longClickable;
-        getAccessibilityButton().setLongClickable(longClickable);
-        mContextualButtonGroup.setButtonVisibility(R.id.accessibility_button, visible);
-    }
-
-    @Override
-    public void onFinishInflate() {
-        super.onFinishInflate();
-        mNavigationInflaterView = findViewById(R.id.navigation_inflater);
-        mNavigationInflaterView.setButtonDispatchers(mButtonDispatchers);
-
-        updateOrientationViews();
-        reloadNavIcons();
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        mDeadZone.onDraw(canvas);
-        super.onDraw(canvas);
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-
-        notifyActiveTouchRegions();
-    }
-
-    /**
-     * Notifies the overview service of the active touch regions.
-     */
-    public void notifyActiveTouchRegions() {
-        if (mUpdateActiveTouchRegionsCallback != null) {
-            mUpdateActiveTouchRegionsCallback.update();
-        }
-    }
-
-    void setUpdateActiveTouchRegionsCallback(UpdateActiveTouchRegionsCallback callback) {
-        mUpdateActiveTouchRegionsCallback = callback;
-        notifyActiveTouchRegions();
-    }
-
-    Map<View, Rect> getButtonTouchRegionCache() {
-        FrameLayout navBarLayout = mIsVertical
-                ? mNavigationInflaterView.mVertical
-                : mNavigationInflaterView.mHorizontal;
-        return ((NearestTouchFrame) navBarLayout
-                .findViewById(R.id.nav_buttons)).getFullTouchableChildRegions();
-    }
-
-    private void updateOrientationViews() {
-        mHorizontal = findViewById(R.id.horizontal);
-        mVertical = findViewById(R.id.vertical);
-
-        updateCurrentView();
-    }
-
-    boolean needsReorient(int rotation) {
-        return mCurrentRotation != rotation;
-    }
-
-    private void updateCurrentRotation() {
-        final int rotation = mConfiguration.windowConfiguration.getDisplayRotation();
-        if (mCurrentRotation == rotation) {
-            return;
-        }
-        mCurrentRotation = rotation;
-        mNavigationInflaterView.setAlternativeOrder(mCurrentRotation == Surface.ROTATION_90);
-        mDeadZone.onConfigurationChanged(mCurrentRotation);
-        if (DEBUG) {
-            Log.d(TAG, "updateCurrentRotation(): rot=" + mCurrentRotation);
-        }
-    }
-
-    private void updateCurrentView() {
-        resetViews();
-        mCurrentView = mIsVertical ? mVertical : mHorizontal;
-        mCurrentView.setVisibility(View.VISIBLE);
-        mNavigationInflaterView.setVertical(mIsVertical);
-        mNavigationInflaterView.updateButtonDispatchersCurrentView();
-        updateLayoutTransitionsEnabled();
-        updateCurrentRotation();
-    }
-
-    private void resetViews() {
-        mHorizontal.setVisibility(View.GONE);
-        mVertical.setVisibility(View.GONE);
-    }
-
-    private void updateRecentsIcon() {
-        mDockedIcon.setRotation(mDockedStackExists && mIsVertical ? 90 : 0);
-        getRecentsButton().setImageDrawable(mDockedStackExists ? mDockedIcon : mRecentIcon);
-        mBarTransitions.reapplyDarkIntensity();
-    }
-
-    public void showPinningEnterExitToast(boolean entering) {
-        if (entering) {
-            mScreenPinningNotify.showPinningStartToast();
-        } else {
-            mScreenPinningNotify.showPinningExitToast();
-        }
-    }
-
-    public void showPinningEscapeToast() {
-        mScreenPinningNotify.showEscapeToast(
-                mNavBarMode == NAV_BAR_MODE_GESTURAL, isRecentsButtonVisible());
-    }
-
-    public boolean isVertical() {
-        return mIsVertical;
-    }
-
-    public void reorient() {
-        updateCurrentView();
-        ((NavigationBarFrame) getRootView()).setDeadZone(mDeadZone);
-
-        // force the low profile & disabled states into compliance
-        mBarTransitions.init();
-
-        // Resolve layout direction if not resolved since components changing layout direction such
-        // as changing languages will recreate this view and the direction will be resolved later
-        if (!isLayoutDirectionResolved()) {
-            resolveLayoutDirection();
-        }
-        updateNavButtonIcons();
-
-        getHomeButton().setVertical(mIsVertical);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        int w = MeasureSpec.getSize(widthMeasureSpec);
-        int h = MeasureSpec.getSize(heightMeasureSpec);
-        if (DEBUG) Log.d(TAG, String.format(
-                "onMeasure: (%dx%d) old: (%dx%d)", w, h, getMeasuredWidth(), getMeasuredHeight()));
-
-        final boolean newVertical = w > 0 && h > w
-                && !isGesturalMode(mNavBarMode);
-        if (newVertical != mIsVertical) {
-            mIsVertical = newVertical;
-            if (DEBUG) {
-                Log.d(TAG, String.format("onMeasure: h=%d, w=%d, vert=%s", h, w,
-                        mIsVertical ? "y" : "n"));
-            }
-            reorient();
-            notifyVerticalChangedListener(newVertical);
-        }
-
-        if (isGesturalMode(mNavBarMode)) {
-            // Update the nav bar background to match the height of the visible nav bar
-            int height = mIsVertical
-                    ? getResources().getDimensionPixelSize(
-                            com.android.internal.R.dimen.navigation_bar_height_landscape)
-                    : getResources().getDimensionPixelSize(
-                            com.android.internal.R.dimen.navigation_bar_height);
-            int frameHeight = getResources().getDimensionPixelSize(
-                    com.android.internal.R.dimen.navigation_bar_frame_height);
-            mBarTransitions.setBackgroundFrame(new Rect(0, frameHeight - height, w, h));
-        } else {
-            mBarTransitions.setBackgroundFrame(null);
-        }
-
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-    }
-
-    int getNavBarHeight() {
-        return mIsVertical
-                ? getResources().getDimensionPixelSize(
-                com.android.internal.R.dimen.navigation_bar_height_landscape)
-                : getResources().getDimensionPixelSize(
-                        com.android.internal.R.dimen.navigation_bar_height);
-    }
-
-    private void notifyVerticalChangedListener(boolean newVertical) {
-        if (mOnVerticalChangedListener != null) {
-            mOnVerticalChangedListener.onVerticalChanged(newVertical);
-        }
-    }
-
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        mTmpLastConfiguration.updateFrom(mConfiguration);
-        final int changes = mConfiguration.updateFrom(newConfig);
-        mFloatingRotationButton.onConfigurationChanged(changes);
-
-        boolean uiCarModeChanged = updateCarMode();
-        updateIcons(mTmpLastConfiguration);
-        updateRecentsIcon();
-        updateCurrentRotation();
-        if (uiCarModeChanged || mTmpLastConfiguration.densityDpi != mConfiguration.densityDpi
-                || mTmpLastConfiguration.getLayoutDirection() != mConfiguration.getLayoutDirection()) {
-            // If car mode or density changes, we need to reset the icons.
-            updateNavButtonIcons();
-        }
-    }
-
-    /**
-     * If the configuration changed, update the carmode and return that it was updated.
-     */
-    private boolean updateCarMode() {
-        boolean uiCarModeChanged = false;
-        if (mConfiguration != null) {
-            int uiMode = mConfiguration.uiMode & Configuration.UI_MODE_TYPE_MASK;
-            final boolean isCarMode = (uiMode == Configuration.UI_MODE_TYPE_CAR);
-
-            if (isCarMode != mInCarMode) {
-                mInCarMode = isCarMode;
-                if (ALTERNATE_CAR_MODE_UI) {
-                    mUseCarModeUi = isCarMode;
-                    uiCarModeChanged = true;
-                } else {
-                    // Don't use car mode behavior if ALTERNATE_CAR_MODE_UI not set.
-                    mUseCarModeUi = false;
-                }
-            }
-        }
-        return uiCarModeChanged;
-    }
-
-    private String getResourceName(int resId) {
-        if (resId != 0) {
-            final android.content.res.Resources res = getContext().getResources();
-            try {
-                return res.getResourceName(resId);
-            } catch (android.content.res.Resources.NotFoundException ex) {
-                return "(unknown)";
-            }
-        } else {
-            return "(null)";
-        }
-    }
-
-    private static String visibilityToString(int vis) {
-        switch (vis) {
-            case View.INVISIBLE:
-                return "INVISIBLE";
-            case View.GONE:
-                return "GONE";
-            default:
-                return "VISIBLE";
-        }
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        requestApplyInsets();
-        reorient();
-        if (mRotationButtonController != null) {
-            mRotationButtonController.registerListeners(false /* registerRotationWatcher */);
-        }
-
-        updateNavButtonIcons();
-        if (enableViewCaptureTracing()) {
-            mViewCaptureCloseable = ViewCaptureFactory.getInstance(getContext())
-                    .startCapture(getRootView(), ".NavigationBarView");
-        }
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        for (int i = 0; i < mButtonDispatchers.size(); ++i) {
-            mButtonDispatchers.valueAt(i).onDestroy();
-        }
-        if (mRotationButtonController != null) {
-            mFloatingRotationButton.hide();
-            mRotationButtonController.unregisterListeners();
-        }
-        if (mViewCaptureCloseable != null) {
-            mViewCaptureCloseable.close();
-        }
-    }
-
-    void dump(PrintWriter pw) {
-        final Rect r = new Rect();
-        final Point size = new Point();
-        getContextDisplay().getRealSize(size);
-
-        pw.println("NavigationBarView:");
-        pw.println(String.format("      this: " + CentralSurfaces.viewInfo(this)
-                        + " " + visibilityToString(getVisibility())));
-
-        getWindowVisibleDisplayFrame(r);
-        final boolean offscreen = r.right > size.x || r.bottom > size.y;
-        pw.println("      window: "
-                + r.toShortString()
-                + " " + visibilityToString(getWindowVisibility())
-                + (offscreen ? " OFFSCREEN!" : ""));
-
-        pw.println(String.format("      mCurrentView: id=%s (%dx%d) %s %f",
-                        getResourceName(getCurrentView().getId()),
-                        getCurrentView().getWidth(), getCurrentView().getHeight(),
-                        visibilityToString(getCurrentView().getVisibility()),
-                        getCurrentView().getAlpha()));
-
-        pw.println(String.format("      disabled=0x%08x vertical=%s darkIntensity=%.2f",
-                        mDisabledFlags,
-                        mIsVertical ? "true" : "false",
-                        getLightTransitionsController().getCurrentDarkIntensity()));
-
-        pw.println("    mScreenOn: " + mScreenOn);
-
-
-        dumpButton(pw, "back", getBackButton());
-        dumpButton(pw, "home", getHomeButton());
-        dumpButton(pw, "handle", getHomeHandle());
-        dumpButton(pw, "rcnt", getRecentsButton());
-        dumpButton(pw, "a11y", getAccessibilityButton());
-        dumpButton(pw, "ime", getImeSwitchButton());
-
-        if (mNavigationInflaterView != null) {
-            mNavigationInflaterView.dump(pw);
-        }
-        mBarTransitions.dump(pw);
-        mContextualButtonGroup.dump(pw);
-        mEdgeBackGestureHandler.dump(pw);
-    }
-
-    @Override
-    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
-        int leftInset = insets.getSystemWindowInsetLeft();
-        int rightInset = insets.getSystemWindowInsetRight();
-        setPadding(leftInset, insets.getSystemWindowInsetTop(), rightInset,
-                insets.getSystemWindowInsetBottom());
-        // we're passing the insets onto the gesture handler since the back arrow is only
-        // conditionally added and doesn't always get all the insets.
-        mEdgeBackGestureHandler.setInsets(leftInset, rightInset);
-
-        // this allows assist handle to be drawn outside its bound so that it can align screen
-        // bottom by translating its y position.
-        final boolean shouldClip =
-                !isGesturalMode(mNavBarMode) || insets.getSystemWindowInsetBottom() == 0;
-        setClipChildren(shouldClip);
-        setClipToPadding(shouldClip);
-
-        return super.onApplyWindowInsets(insets);
-    }
-
-    void addPipExclusionBoundsChangeListener(Pip pip) {
-        pip.addPipExclusionBoundsChangeListener(mPipListener);
-    }
-
-    void removePipExclusionBoundsChangeListener(Pip pip) {
-        pip.removePipExclusionBoundsChangeListener(mPipListener);
-    }
-
-    void registerBackAnimation(BackAnimation backAnimation) {
-        mEdgeBackGestureHandler.setBackAnimation(backAnimation);
-    }
-
-    private static void dumpButton(PrintWriter pw, String caption, ButtonDispatcher button) {
-        pw.print("      " + caption + ": ");
-        if (button == null) {
-            pw.print("null");
-        } else {
-            pw.print(visibilityToString(button.getVisibility())
-                    + " alpha=" + button.getAlpha()
-                    );
-        }
-        pw.println();
-    }
-
-    public interface OnVerticalChangedListener {
-        void onVerticalChanged(boolean isVertical);
-    }
-
-    private final Consumer<Boolean> mDockedListener = exists -> post(() -> {
-        mDockedStackExists = exists;
-        updateRecentsIcon();
-    });
-
-    private final Consumer<Rect> mPipListener = bounds -> post(() -> {
-        mEdgeBackGestureHandler.setPipStashExclusionBounds(bounds);
-    });
-
-
-    interface UpdateActiveTouchRegionsCallback {
-        void update();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
index b360af0..d022c1c 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
@@ -24,6 +24,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 
 import static com.android.systemui.navigationbar.NavBarHelper.transitionMode;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.TransitionMode;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY;
@@ -34,7 +35,6 @@
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
-import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
 
 import android.app.StatusBarManager;
 import android.app.StatusBarManager.WindowVisibleState;
@@ -63,13 +63,16 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.shared.recents.utilities.Utilities;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.shared.system.TaskStackChangeListeners;
 import com.android.systemui.statusbar.AutoHideUiElement;
 import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.phone.AutoHideController;
 import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.phone.LightBarTransitionsController;
@@ -117,6 +120,11 @@
                         boolean longPressHomeEnabled) {
                     updateAssistantAvailability(available, longPressHomeEnabled);
                 }
+
+                @Override
+                public void updateWallpaperVisibility(boolean visible, int displayId) {
+                    updateWallpaperVisible(displayId, visible);
+                }
             };
     private int mDisabledFlags;
     private @WindowVisibleState int mTaskBarWindowState = WINDOW_STATE_SHOWING;
@@ -150,6 +158,7 @@
     private final AutoHideUiElement mAutoHideUiElement = new AutoHideUiElement() {
         @Override
         public void synchronizeState() {
+            checkNavBarModes();
         }
 
         @Override
@@ -165,11 +174,13 @@
 
     private BackAnimation mBackAnimation;
 
-    private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    private final StatusBarStateController mStatusBarStateController;
     @Inject
     public TaskbarDelegate(Context context,
             LightBarTransitionsController.Factory lightBarTransitionsControllerFactory,
-            StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
+            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+            StatusBarStateController statusBarStateController) {
         mLightBarTransitionsControllerFactory = lightBarTransitionsControllerFactory;
 
         mContext = context;
@@ -179,6 +190,7 @@
         };
         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
         mStatusBarKeyguardViewManager.setTaskbarDelegate(this);
+        mStatusBarStateController = statusBarStateController;
     }
 
     public void setDependencies(CommandQueue commandQueue,
@@ -324,6 +336,68 @@
         return (mSysUiState.getFlags() & View.STATUS_BAR_DISABLE_RECENT) == 0;
     }
 
+    void onTransitionModeUpdated(int barMode, boolean checkBarModes) {
+        if (mOverviewProxyService.getProxy() == null) {
+            return;
+        }
+
+        try {
+            mOverviewProxyService.getProxy().onTransitionModeUpdated(barMode, checkBarModes);
+        } catch (RemoteException e) {
+            Log.e(TAG, "onTransitionModeUpdated() failed, barMode: " + barMode, e);
+        }
+    }
+
+    void checkNavBarModes() {
+        if (mOverviewProxyService.getProxy() == null) {
+            return;
+        }
+
+        try {
+            mOverviewProxyService.getProxy().checkNavBarModes();
+        } catch (RemoteException e) {
+            Log.e(TAG, "checkNavBarModes() failed", e);
+        }
+    }
+
+    void finishBarAnimations() {
+        if (mOverviewProxyService.getProxy() == null) {
+            return;
+        }
+
+        try {
+            mOverviewProxyService.getProxy().finishBarAnimations();
+        } catch (RemoteException e) {
+            Log.e(TAG, "finishBarAnimations() failed", e);
+        }
+    }
+
+    void touchAutoDim() {
+        if (mOverviewProxyService.getProxy() == null) {
+            return;
+        }
+
+        try {
+            int state = mStatusBarStateController.getState();
+            boolean shouldReset =
+                    state != StatusBarState.KEYGUARD && state != StatusBarState.SHADE_LOCKED;
+            mOverviewProxyService.getProxy().touchAutoDim(shouldReset);
+        } catch (RemoteException e) {
+            Log.e(TAG, "touchAutoDim() failed", e);
+        }
+    }
+
+    void transitionTo(@BarTransitions.TransitionMode int barMode, boolean animate) {
+        if (mOverviewProxyService.getProxy() == null) {
+            return;
+        }
+
+        try {
+            mOverviewProxyService.getProxy().transitionTo(barMode, animate);
+        } catch (RemoteException e) {
+            Log.e(TAG, "transitionTo() failed, barMode: " + barMode, e);
+        }
+    }
     private void updateAssistantAvailability(boolean assistantAvailable,
             boolean longPressHomeEnabled) {
         if (mOverviewProxyService.getProxy() == null) {
@@ -338,6 +412,18 @@
         }
     }
 
+    private void updateWallpaperVisible(int displayId, boolean visible) {
+        if (mOverviewProxyService.getProxy() == null) {
+            return;
+        }
+
+        try {
+            mOverviewProxyService.getProxy().updateWallpaperVisibility(displayId, visible);
+        } catch (RemoteException e) {
+            Log.e(TAG, "updateWallpaperVisibility() failed, visible: " + visible, e);
+        }
+    }
+
     @Override
     public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
             boolean showImeSwitcher) {
@@ -465,9 +551,11 @@
     private boolean updateTransitionMode(int barMode) {
         if (mTransitionMode != barMode) {
             mTransitionMode = barMode;
+            onTransitionModeUpdated(barMode, true);
             if (mAutoHideController != null) {
                 mAutoHideController.touchAutoHide();
             }
+
             return true;
         }
         return false;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java
deleted file mode 100644
index fc37b9f..0000000
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonDispatcher.java
+++ /dev/null
@@ -1,380 +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.navigationbar.buttons;
-
-import static com.android.app.animation.Interpolators.LINEAR;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.view.View;
-import android.view.View.AccessibilityDelegate;
-import android.view.ViewGroup;
-
-import com.android.systemui.navigationbar.NavBarButtonClickLogger;
-
-import java.util.ArrayList;
-
-/**
- * Dispatches common view calls to multiple views.  This is used to handle
- * multiples of the same nav bar icon appearing.
- */
-public class ButtonDispatcher {
-    private static final int FADE_DURATION_IN = 150;
-    private static final int FADE_DURATION_OUT = 250;
-
-    private final ArrayList<View> mViews = new ArrayList<>();
-
-    private final int mId;
-
-    private View.OnClickListener mClickListener;
-    private View.OnTouchListener mTouchListener;
-    private View.OnLongClickListener mLongClickListener;
-    private View.OnHoverListener mOnHoverListener;
-    private Boolean mLongClickable;
-    private Float mAlpha;
-    private Float mDarkIntensity;
-    private Integer mVisibility = View.VISIBLE;
-    private Boolean mDelayTouchFeedback;
-    private KeyButtonDrawable mImageDrawable;
-    private View mCurrentView;
-    private boolean mVertical;
-    private ValueAnimator mFadeAnimator;
-    private AccessibilityDelegate mAccessibilityDelegate;
-    private NavBarButtonClickLogger mNavBarButtonClickLogger;
-
-    private final ValueAnimator.AnimatorUpdateListener mAlphaListener = animation ->
-            setAlpha(
-                    (float) animation.getAnimatedValue(),
-                    false /* animate */,
-                    false /* cancelAnimator */);
-
-    private final AnimatorListenerAdapter mFadeListener = new AnimatorListenerAdapter() {
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            mFadeAnimator = null;
-            setVisibility(getAlpha() == 1 ? View.VISIBLE : View.INVISIBLE);
-        }
-    };
-
-    public ButtonDispatcher(int id) {
-        mId = id;
-    }
-
-    public void clear() {
-        mViews.clear();
-    }
-
-    public void addView(View view) {
-        mViews.add(view);
-        view.setOnClickListener(mClickListener);
-        view.setOnTouchListener(mTouchListener);
-        view.setOnLongClickListener(mLongClickListener);
-        view.setOnHoverListener(mOnHoverListener);
-        if (mLongClickable != null) {
-            view.setLongClickable(mLongClickable);
-        }
-        if (mAlpha != null) {
-            view.setAlpha(mAlpha);
-        }
-        if (mVisibility != null) {
-            view.setVisibility(mVisibility);
-        }
-        if (mAccessibilityDelegate != null) {
-            view.setAccessibilityDelegate(mAccessibilityDelegate);
-        }
-        if (view instanceof ButtonInterface) {
-            final ButtonInterface button = (ButtonInterface) view;
-            if (mDarkIntensity != null) {
-                button.setDarkIntensity(mDarkIntensity);
-            }
-            if (mImageDrawable != null) {
-                button.setImageDrawable(mImageDrawable);
-            }
-            if (mDelayTouchFeedback != null) {
-                button.setDelayTouchFeedback(mDelayTouchFeedback);
-            }
-            button.setVertical(mVertical);
-        }
-    }
-
-    public int getId() {
-        return mId;
-    }
-
-    public int getVisibility() {
-        return mVisibility != null ? mVisibility : View.VISIBLE;
-    }
-
-    public boolean isVisible() {
-        return getVisibility() == View.VISIBLE;
-    }
-
-    public float getAlpha() {
-        return mAlpha != null ? mAlpha : 1;
-    }
-
-    public KeyButtonDrawable getImageDrawable() {
-        return mImageDrawable;
-    }
-
-    public void setImageDrawable(KeyButtonDrawable drawable) {
-        mImageDrawable = drawable;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
-            if (mViews.get(i) instanceof ButtonInterface) {
-                ((ButtonInterface) mViews.get(i)).setImageDrawable(mImageDrawable);
-            }
-        }
-        if (mImageDrawable != null) {
-            mImageDrawable.setCallback(mCurrentView);
-        }
-    }
-
-    public void setVisibility(int visibility) {
-        if (mVisibility == visibility) return;
-        if (mFadeAnimator != null) {
-            mFadeAnimator.cancel();
-        }
-
-        mVisibility = visibility;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
-            mViews.get(i).setVisibility(mVisibility);
-        }
-    }
-
-    public void abortCurrentGesture() {
-        // This seems to be an instantaneous thing, so not going to persist it.
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
-            if (mViews.get(i) instanceof ButtonInterface) {
-                ((ButtonInterface) mViews.get(i)).abortCurrentGesture();
-            }
-        }
-    }
-
-    public void setAlpha(float alpha) {
-        setAlpha(alpha, false /* animate */);
-    }
-
-    public void setAlpha(float alpha, boolean animate) {
-        setAlpha(alpha, animate, true /* cancelAnimator */);
-    }
-
-    public void setAlpha(float alpha, boolean animate, long duration) {
-        setAlpha(alpha, animate, duration, true /* cancelAnimator */);
-    }
-
-    public void setAlpha(float alpha, boolean animate, boolean cancelAnimator) {
-        setAlpha(
-                alpha,
-                animate,
-                (getAlpha() < alpha) ? FADE_DURATION_IN : FADE_DURATION_OUT,
-                cancelAnimator);
-    }
-
-    public void setAlpha(float alpha, boolean animate, long duration, boolean cancelAnimator) {
-        if (mFadeAnimator != null && (cancelAnimator || animate)) {
-            mFadeAnimator.cancel();
-        }
-        if (animate) {
-            setVisibility(View.VISIBLE);
-            mFadeAnimator = ValueAnimator.ofFloat(getAlpha(), alpha);
-            mFadeAnimator.setDuration(duration);
-            mFadeAnimator.setInterpolator(LINEAR);
-            mFadeAnimator.addListener(mFadeListener);
-            mFadeAnimator.addUpdateListener(mAlphaListener);
-            mFadeAnimator.start();
-        } else {
-            // Discretize the alpha updates to prevent too frequent updates when there is a long
-            // alpha animation
-            int prevAlpha = (int) (getAlpha() * 255);
-            int nextAlpha = (int) (alpha * 255);
-            if (prevAlpha != nextAlpha) {
-                mAlpha = nextAlpha / 255f;
-                final int N = mViews.size();
-                for (int i = 0; i < N; i++) {
-                    mViews.get(i).setAlpha(mAlpha);
-                }
-            }
-        }
-    }
-
-    public void setDarkIntensity(float darkIntensity) {
-        mDarkIntensity = darkIntensity;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
-            if (mViews.get(i) instanceof ButtonInterface) {
-                ((ButtonInterface) mViews.get(i)).setDarkIntensity(darkIntensity);
-            }
-        }
-    }
-
-    public void setDelayTouchFeedback(boolean delay) {
-        mDelayTouchFeedback = delay;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
-            if (mViews.get(i) instanceof ButtonInterface) {
-                ((ButtonInterface) mViews.get(i)).setDelayTouchFeedback(delay);
-            }
-        }
-    }
-
-    public void setOnClickListener(View.OnClickListener clickListener) {
-        mClickListener = clickListener;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
-            mViews.get(i).setOnClickListener(mClickListener);
-        }
-    }
-
-    public void setOnTouchListener(View.OnTouchListener touchListener) {
-        mTouchListener = touchListener;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
-            mViews.get(i).setOnTouchListener(mTouchListener);
-        }
-    }
-
-    public void animateLongPress(boolean isTouchDown, boolean shrink, long durationMs) {
-        for (int i = 0; i < mViews.size(); i++) {
-            if (mViews.get(i) instanceof ButtonInterface) {
-                ((ButtonInterface) mViews.get(i)).animateLongPress(isTouchDown, shrink, durationMs);
-            }
-        }
-    }
-
-    public void setLongClickable(boolean isLongClickable) {
-        mLongClickable = isLongClickable;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
-            mViews.get(i).setLongClickable(mLongClickable);
-        }
-    }
-
-    public void setOnLongClickListener(View.OnLongClickListener longClickListener) {
-        mLongClickListener = longClickListener;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
-            mViews.get(i).setOnLongClickListener(mLongClickListener);
-        }
-    }
-
-    public void setOnHoverListener(View.OnHoverListener hoverListener) {
-        mOnHoverListener = hoverListener;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
-            mViews.get(i).setOnHoverListener(mOnHoverListener);
-        }
-    }
-
-    public void setAccessibilityDelegate(AccessibilityDelegate delegate) {
-        mAccessibilityDelegate = delegate;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
-            mViews.get(i).setAccessibilityDelegate(delegate);
-        }
-    }
-
-    public void setClickable(boolean clickable) {
-        abortCurrentGesture();
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
-            mViews.get(i).setClickable(clickable);
-        }
-    }
-
-    public void setTranslation(int x, int y, int z) {
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
-            final View view = mViews.get(i);
-            view.setTranslationX(x);
-            view.setTranslationY(y);
-            view.setTranslationZ(z);
-        }
-    }
-
-    public ArrayList<View> getViews() {
-        return mViews;
-    }
-
-    public View getCurrentView() {
-        return mCurrentView;
-    }
-
-    public void setCurrentView(View currentView) {
-        mCurrentView = currentView.findViewById(mId);
-        if (mImageDrawable != null) {
-            mImageDrawable.setCallback(mCurrentView);
-        }
-        if (mCurrentView != null) {
-            mCurrentView.setTranslationX(0);
-            mCurrentView.setTranslationY(0);
-            mCurrentView.setTranslationZ(0);
-        }
-    }
-
-    public void setVertical(boolean vertical) {
-        mVertical = vertical;
-        final int N = mViews.size();
-        for (int i = 0; i < N; i++) {
-            final View view = mViews.get(i);
-            if (view instanceof ButtonInterface) {
-                ((ButtonInterface) view).setVertical(vertical);
-            }
-        }
-    }
-
-    /**
-     * Executes when button is detached from window.
-     */
-    public void onDestroy() {
-    }
-
-    /**
-     * Sets the NavBarButtonClickLogger for all the KeyButtonViews respectively.
-     */
-    public void setNavBarButtonClickLogger(NavBarButtonClickLogger navBarButtonClickLogger) {
-        if (navBarButtonClickLogger != null) {
-            mNavBarButtonClickLogger = navBarButtonClickLogger;
-            final int size = mViews.size();
-            for (int i = 0; i < size; i++) {
-                final View v = mViews.get(i);
-                setNavBarButtonClickLoggerForViewChildren(v);
-            }
-        }
-    }
-
-    /**
-     * Recursively explores view hierarchy until the children of provided view are of type
-     * KeyButtonView, so the NavBarButtonClickLogger can be set on them.
-     */
-    private void setNavBarButtonClickLoggerForViewChildren(View v) {
-        if (v instanceof KeyButtonView) {
-            ((KeyButtonView) v).setNavBarButtonClickLogger(mNavBarButtonClickLogger);
-            return;
-        }
-
-        if (v instanceof ViewGroup viewGroup) {
-            final int childrenCount = viewGroup.getChildCount();
-            for (int i = 0; i < childrenCount; i++) {
-                setNavBarButtonClickLoggerForViewChildren(viewGroup.getChildAt(i));
-            }
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonInterface.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonInterface.java
deleted file mode 100644
index 5f8fafd..0000000
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ButtonInterface.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.navigationbar.buttons;
-
-import android.annotation.Nullable;
-import android.graphics.drawable.Drawable;
-
-public interface ButtonInterface {
-
-    void setImageDrawable(@Nullable Drawable drawable);
-
-    void abortCurrentGesture();
-
-    void setVertical(boolean vertical);
-
-    void setDarkIntensity(float intensity);
-
-    void setDelayTouchFeedback(boolean shouldDelay);
-
-    /**
-     * Animate the button being long-pressed.
-     *
-     * @param isTouchDown {@code true} if the button is starting to be pressed ({@code false} if
-     *                    released or canceled)
-     * @param shrink      {@code true} if the handle should shrink, {@code false} if it should grow
-     * @param durationMs  how long the animation should take (for the {@code isTouchDown} case, this
-     *                    should be the same as the amount of time to trigger a long-press)
-     */
-    default void animateLongPress(boolean isTouchDown, boolean shrink, long durationMs) {}
-}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButton.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButton.java
deleted file mode 100644
index 517f8e7..0000000
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButton.java
+++ /dev/null
@@ -1,127 +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.navigationbar.buttons;
-
-import android.annotation.DrawableRes;
-import android.annotation.IdRes;
-import android.annotation.NonNull;
-import android.content.Context;
-import android.view.View;
-
-/**
- * Simple contextual button that is added to the {@link ContextualButtonGroup}. Extend if need extra
- * functionality.
- */
-public class ContextualButton extends ButtonDispatcher {
-
-    private ContextButtonListener mListener;
-    private ContextualButtonGroup mGroup;
-
-    protected final Context mLightContext;
-    protected final @DrawableRes int mIconResId;
-
-    /**
-      * Create a contextual button that will use a {@link KeyButtonView} and
-      * {@link KeyButtonDrawable} get and show the button from xml to its icon drawable.
-      * @param buttonResId the button view from xml layout
-      * @param iconResId icon resource to be used
-      */
-    public ContextualButton(@IdRes int buttonResId, Context lightContext,
-            @DrawableRes int iconResId) {
-        super(buttonResId);
-        mLightContext = lightContext;
-        mIconResId = iconResId;
-    }
-
-    /**
-     * Reload the drawable from resource id, should reapply the previous dark intensity.
-     */
-    public void updateIcon(int lightIconColor, int darkIconColor) {
-        if (mIconResId == 0) {
-            return;
-        }
-        final KeyButtonDrawable currentDrawable = getImageDrawable();
-        KeyButtonDrawable drawable = getNewDrawable(lightIconColor, darkIconColor);
-        if (currentDrawable != null) {
-            drawable.setDarkIntensity(currentDrawable.getDarkIntensity());
-        }
-        setImageDrawable(drawable);
-    }
-
-    @Override
-    public void setVisibility(int visibility) {
-        super.setVisibility(visibility);
-
-        // Stop any active animations if hidden
-        final KeyButtonDrawable currentDrawable = getImageDrawable();
-        if (visibility != View.VISIBLE && currentDrawable != null && currentDrawable.canAnimate()) {
-            currentDrawable.clearAnimationCallbacks();
-            currentDrawable.resetAnimation();
-        }
-
-        if (mListener != null) {
-            mListener.onVisibilityChanged(this, visibility == View.VISIBLE);
-        }
-    }
-
-    public void setListener(ContextButtonListener listener) {
-        mListener = listener;
-    }
-
-    /**
-     * Show this button based on its priority compared to other buttons in the group. If not
-     * attached to a group it will set its own visibility to be visible.
-     * @return if visible
-     */
-    public boolean show() {
-        if (mGroup == null) {
-            setVisibility(View.VISIBLE);
-            return true;
-        }
-        return mGroup.setButtonVisibility(getId(), true /* visible */) == View.VISIBLE;
-    }
-
-    /**
-     * Hide this button.
-     * @return if visible
-     */
-    public boolean hide() {
-        if (mGroup == null) {
-            setVisibility(View.INVISIBLE);
-            return false;
-        }
-        return mGroup.setButtonVisibility(getId(), false /* visible */) != View.VISIBLE;
-    }
-
-    /**
-     * Called when this button was added to the group. Keep a reference to the group to show based
-     * on priority compared to other buttons.
-     * @param group the holder of all the buttons
-     */
-    void attachToGroup(@NonNull ContextualButtonGroup group) {
-        mGroup = group;
-    }
-
-    protected KeyButtonDrawable getNewDrawable(int lightIconColor, int darkIconColor) {
-        return KeyButtonDrawable.create(mLightContext, lightIconColor, darkIconColor, mIconResId,
-                false /* shadow */, null /* ovalBackground */);
-    }
-
-    public interface ContextButtonListener {
-        void onVisibilityChanged(ContextualButton button, boolean visible);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButtonGroup.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButtonGroup.java
deleted file mode 100644
index 2ace303..0000000
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ContextualButtonGroup.java
+++ /dev/null
@@ -1,173 +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.navigationbar.buttons;
-
-import android.annotation.IdRes;
-import android.annotation.NonNull;
-import android.view.View;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-public class ContextualButtonGroup extends ButtonDispatcher {
-    private static final int INVALID_INDEX = -1;
-
-    // List of pairs that contains the button and if the button was visible within this group
-    private final List<ButtonData> mButtonData = new ArrayList<>();
-
-    public ContextualButtonGroup(@IdRes int containerId) {
-        super(containerId);
-    }
-
-    /**
-     * Add a contextual button to the group. The order of adding increases in its priority. The
-     * priority is used to determine which button should be visible when setting multiple button's
-     * visibility {@see setButtonVisibility}.
-     * @param button the button added to the group
-     */
-    public void addButton(@NonNull ContextualButton button) {
-        // By default buttons in the context group are not visible until
-        // {@link #setButtonVisibility()) is called to show one of the buttons
-        button.setVisibility(View.INVISIBLE);
-        button.attachToGroup(this);
-        mButtonData.add(new ButtonData(button));
-    }
-
-    /**
-     * Removes a contextual button from the group.
-     */
-    public void removeButton(@IdRes int buttonResId) {
-        int index = getContextButtonIndex(buttonResId);
-        if (index != INVALID_INDEX) {
-            mButtonData.remove(index);
-        }
-    }
-
-    public ContextualButton getContextButton(@IdRes int buttonResId) {
-        int index = getContextButtonIndex(buttonResId);
-        if (index != INVALID_INDEX) {
-            return mButtonData.get(index).button;
-        }
-        return null;
-    }
-
-    public ContextualButton getVisibleContextButton() {
-        for (int i = mButtonData.size() - 1; i >= 0; --i) {
-            if (mButtonData.get(i).markedVisible) {
-                return mButtonData.get(i).button;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Set the visibility of the button by {@param buttonResId} with {@param visible}. Only one
-     * button is shown at a time. The input button will only show up if it has higher priority than
-     * a previous button, otherwise it will be marked as visible and shown later if all higher
-     * priority buttons are invisible. Therefore hiding a button will show the next marked visible
-     * button. This group's view will be visible if at least one button is visible.
-     * @return if the button is visible after operation
-     * @throws RuntimeException if the input id does not match any of the ids in the group
-     */
-    public int setButtonVisibility(@IdRes int buttonResId, boolean visible) {
-        final int index = getContextButtonIndex(buttonResId);
-        if (index == INVALID_INDEX) {
-            throw new RuntimeException("Cannot find the button id of " + buttonResId
-                    + " in context group");
-        }
-        setVisibility(View.INVISIBLE);
-        mButtonData.get(index).markedVisible = visible;
-
-        // Make all buttons invisible except the first markedVisible button
-        boolean alreadyFoundVisibleButton = false;
-        int i = mButtonData.size() - 1;
-        for (; i >= 0; --i) {
-            final ButtonData buttonData = mButtonData.get(i);
-            if (!alreadyFoundVisibleButton && buttonData.markedVisible) {
-                buttonData.setVisibility(View.VISIBLE);
-                setVisibility(View.VISIBLE);
-                alreadyFoundVisibleButton = true;
-            } else {
-                buttonData.setVisibility(View.INVISIBLE);
-            }
-        }
-        return mButtonData.get(index).button.getVisibility();
-    }
-
-    /**
-     * See if button is group visible. Group visible determines if a button can be visible when
-     * higher priority buttons go invisible.
-     * @param buttonResId the button to see if it is group visible
-     * @return true if button is group visible
-     */
-    public boolean isButtonVisibleWithinGroup(@IdRes int buttonResId) {
-        final int index = getContextButtonIndex(buttonResId);
-        return index != INVALID_INDEX && mButtonData.get(index).markedVisible;
-    }
-
-    /**
-     * Update all the icons that are attached to this group. This will get all the buttons to update
-     * their icons for their buttons.
-     */
-    public void updateIcons(int lightIconColor, int darkIconColor) {
-        for (ButtonData data : mButtonData) {
-            data.button.updateIcon(lightIconColor, darkIconColor);
-        }
-    }
-
-    public void dump(PrintWriter pw) {
-        View view = getCurrentView();
-        pw.println("ContextualButtonGroup");
-        pw.println("  getVisibleContextButton(): " + getVisibleContextButton());
-        pw.println("  isVisible(): " + isVisible());
-        pw.println("  attached(): " + (view != null && view.isAttachedToWindow()));
-        pw.println("  mButtonData [ ");
-        for (int i = mButtonData.size() - 1; i >= 0; --i) {
-            final ButtonData data = mButtonData.get(i);
-            view = data.button.getCurrentView();
-            pw.println("    " + i + ": markedVisible=" + data.markedVisible
-                    + " visible=" + data.button.getVisibility()
-                    + " attached=" + (view != null && view.isAttachedToWindow())
-                    + " alpha=" + data.button.getAlpha());
-        }
-        pw.println("  ]");
-    }
-
-    private int getContextButtonIndex(@IdRes int buttonResId) {
-        for (int i = 0; i < mButtonData.size(); ++i) {
-            if (mButtonData.get(i).button.getId() == buttonResId) {
-                return i;
-            }
-        }
-        return INVALID_INDEX;
-    }
-
-    private final static class ButtonData {
-        ContextualButton button;
-        boolean markedVisible;
-
-        ButtonData(ContextualButton button) {
-            this.button = button;
-            this.markedVisible = false;
-        }
-
-        void setVisibility(int visiblity) {
-            button.setVisibility(visiblity);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java
deleted file mode 100644
index 8177fde..0000000
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/DeadZone.java
+++ /dev/null
@@ -1,238 +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.navigationbar.buttons;
-
-import android.animation.ObjectAnimator;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.os.SystemClock;
-import android.util.FloatProperty;
-import android.util.Slog;
-import android.view.MotionEvent;
-import android.view.Surface;
-
-import com.android.systemui.Dependency;
-import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarView;
-import com.android.systemui.res.R;
-
-import javax.inject.Inject;
-
-/**
- * The "dead zone" consumes unintentional taps along the top edge of the navigation bar.
- * When users are typing quickly on an IME they may attempt to hit the space bar, overshoot, and
- * accidentally hit the home button. The DeadZone expands temporarily after each tap in the UI
- * outside the navigation bar (since this is when accidental taps are more likely), then contracts
- * back over time (since a later tap might be intended for the top of the bar).
- */
-public class DeadZone {
-    public static final String TAG = "DeadZone";
-
-    public static final boolean DEBUG = false;
-    public static final int HORIZONTAL = 0;  // Consume taps along the top edge.
-    public static final int VERTICAL = 1;  // Consume taps along the left edge.
-
-    private static final boolean CHATTY = true; // print to logcat when we eat a click
-
-    private static final FloatProperty<DeadZone> FLASH_PROPERTY =
-            new FloatProperty<DeadZone>("DeadZoneFlash") {
-        @Override
-        public void setValue(DeadZone object, float value) {
-            object.setFlash(value);
-        }
-
-        @Override
-        public Float get(DeadZone object) {
-            return object.getFlash();
-        }
-    };
-
-    private final boolean mUseDeadZone;
-    private final NavigationBarController mNavBarController;
-    private final NavigationBarView mNavigationBarView;
-
-    private boolean mShouldFlash;
-    private float mFlashFrac = 0f;
-
-    private int mSizeMax;
-    private int mSizeMin;
-    // Upon activity elsewhere in the UI, the dead zone will hold steady for
-    // mHold ms, then move back over the course of mDecay ms
-    private int mHold, mDecay;
-    private boolean mVertical;
-    private long mLastPokeTime;
-    private int mDisplayRotation;
-    private final int mDisplayId;
-
-    private final Runnable mDebugFlash = new Runnable() {
-        @Override
-        public void run() {
-            ObjectAnimator.ofFloat(DeadZone.this, FLASH_PROPERTY, 1f, 0f).setDuration(150).start();
-        }
-    };
-
-    @Inject
-    public DeadZone(NavigationBarView view) {
-        mUseDeadZone = view.getResources().getBoolean(R.bool.config_useDeadZone);
-
-        mNavigationBarView = view;
-        mNavBarController = Dependency.get(NavigationBarController.class);
-        mDisplayId = view.getContext().getDisplayId();
-
-        onConfigurationChanged(HORIZONTAL);
-    }
-
-    static float lerp(float a, float b, float f) {
-        return (b - a) * f + a;
-    }
-
-    private float getSize(long now) {
-        if (mSizeMax == 0)
-            return 0;
-        long dt = (now - mLastPokeTime);
-        if (dt > mHold + mDecay)
-            return mSizeMin;
-        if (dt < mHold)
-            return mSizeMax;
-        return (int) lerp(mSizeMax, mSizeMin, (float) (dt - mHold) / mDecay);
-    }
-
-    public void setFlashOnTouchCapture(boolean dbg) {
-        if (!mUseDeadZone) {
-            return;
-        }
-
-        mShouldFlash = dbg;
-        mFlashFrac = 0f;
-        mNavigationBarView.postInvalidate();
-    }
-
-    public void onConfigurationChanged(int rotation) {
-        if (!mUseDeadZone) {
-            return;
-        }
-
-        mDisplayRotation = rotation;
-
-        final Resources res = mNavigationBarView.getResources();
-        mHold = res.getInteger(R.integer.navigation_bar_deadzone_hold);
-        mDecay = res.getInteger(R.integer.navigation_bar_deadzone_decay);
-
-        mSizeMin = res.getDimensionPixelSize(R.dimen.navigation_bar_deadzone_size);
-        mSizeMax = res.getDimensionPixelSize(R.dimen.navigation_bar_deadzone_size_max);
-        int index = res.getInteger(R.integer.navigation_bar_deadzone_orientation);
-        mVertical = (index == VERTICAL);
-
-        if (DEBUG) {
-            Slog.v(TAG, this + " size=[" + mSizeMin + "-" + mSizeMax + "] hold=" + mHold
-                    + (mVertical ? " vertical" : " horizontal"));
-        }
-        setFlashOnTouchCapture(res.getBoolean(R.bool.config_dead_zone_flash));
-    }
-
-    // I made you a touch event...
-    public boolean onTouchEvent(MotionEvent event) {
-        if (!mUseDeadZone) {
-            return false;
-        }
-
-        if (DEBUG) {
-            Slog.v(TAG, this + " onTouch: " + MotionEvent.actionToString(event.getAction()));
-        }
-
-        // Don't consume events for high precision pointing devices. For this purpose a stylus is
-        // considered low precision (like a finger), so its events may be consumed.
-        if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) {
-            return false;
-        }
-
-        final int action = event.getAction();
-        if (action == MotionEvent.ACTION_OUTSIDE) {
-            poke(event);
-            return true;
-        } else if (action == MotionEvent.ACTION_DOWN) {
-            if (DEBUG) {
-                Slog.v(TAG, this + " ACTION_DOWN: " + event.getX() + "," + event.getY());
-            }
-            mNavBarController.touchAutoDim(mDisplayId);
-            int size = (int) getSize(event.getEventTime());
-            // In the vertical orientation consume taps along the left edge.
-            // In horizontal orientation consume taps along the top edge.
-            final boolean consumeEvent;
-            if (mVertical) {
-                if (mDisplayRotation == Surface.ROTATION_270) {
-                    consumeEvent = event.getX() > mNavigationBarView.getWidth() - size;
-                } else {
-                    consumeEvent = event.getX() < size;
-                }
-            } else {
-                consumeEvent = event.getY() < size;
-            }
-            if (consumeEvent) {
-                if (CHATTY) {
-                    Slog.v(TAG, "consuming errant click: (" + event.getX() + "," + event.getY() + ")");
-                }
-                if (mShouldFlash) {
-                    mNavigationBarView.post(mDebugFlash);
-                    mNavigationBarView.postInvalidate();
-                }
-                return true; // ...but I eated it
-            }
-        }
-        return false;
-    }
-
-    private void poke(MotionEvent event) {
-        mLastPokeTime = event.getEventTime();
-        if (DEBUG)
-            Slog.v(TAG, "poked! size=" + getSize(mLastPokeTime));
-        if (mShouldFlash) mNavigationBarView.postInvalidate();
-    }
-
-    private void setFlash(float f) {
-        mFlashFrac = f;
-        mNavigationBarView.postInvalidate();
-    }
-
-    private float getFlash() {
-        return mFlashFrac;
-    }
-
-    public void onDraw(Canvas can) {
-        if (!mUseDeadZone || !mShouldFlash || mFlashFrac <= 0f) {
-            return;
-        }
-
-        final int size = (int) getSize(SystemClock.uptimeMillis());
-        if (mVertical) {
-            if (mDisplayRotation == Surface.ROTATION_270) {
-                can.clipRect(can.getWidth() - size, 0, can.getWidth(), can.getHeight());
-            } else {
-                can.clipRect(0, 0, size, can.getHeight());
-            }
-        } else {
-            can.clipRect(0, 0, can.getWidth(), size);
-        }
-
-        final float frac = DEBUG ? (mFlashFrac - 0.5f) + 0.5f : mFlashFrac;
-        can.drawARGB((int) (frac * 0xFF), 0xDD, 0xEE, 0xAA);
-
-        if (DEBUG && size > mSizeMin)
-            // Very aggressive redrawing here, for debugging only
-            mNavigationBarView.postInvalidateDelayed(100);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java
deleted file mode 100644
index 686facc..0000000
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonDrawable.java
+++ /dev/null
@@ -1,491 +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.navigationbar.buttons;
-
-import android.animation.ArgbEvaluator;
-import android.annotation.ColorInt;
-import android.annotation.DrawableRes;
-import android.annotation.NonNull;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BlurMaskFilter;
-import android.graphics.BlurMaskFilter.Blur;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.Paint;
-import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffColorFilter;
-import android.graphics.Rect;
-import android.graphics.drawable.AnimatedVectorDrawable;
-import android.graphics.drawable.Drawable;
-import android.util.FloatProperty;
-import android.view.View;
-
-import com.android.settingslib.Utils;
-import com.android.systemui.res.R;
-
-/**
- * Drawable for {@link KeyButtonView}s that supports tinting between two colors, rotation and shows
- * a shadow. AnimatedVectorDrawable will only support tinting from intensities but has no support
- * for shadows nor rotations.
- */
-public class KeyButtonDrawable extends Drawable {
-
-    public static final FloatProperty<KeyButtonDrawable> KEY_DRAWABLE_ROTATE =
-        new FloatProperty<KeyButtonDrawable>("KeyButtonRotation") {
-            @Override
-            public void setValue(KeyButtonDrawable drawable, float degree) {
-                drawable.setRotation(degree);
-            }
-
-            @Override
-            public Float get(KeyButtonDrawable drawable) {
-                return drawable.getRotation();
-            }
-        };
-
-    public static final FloatProperty<KeyButtonDrawable> KEY_DRAWABLE_TRANSLATE_Y =
-        new FloatProperty<KeyButtonDrawable>("KeyButtonTranslateY") {
-            @Override
-            public void setValue(KeyButtonDrawable drawable, float y) {
-                drawable.setTranslationY(y);
-            }
-
-            @Override
-            public Float get(KeyButtonDrawable drawable) {
-                return drawable.getTranslationY();
-            }
-        };
-
-    private final Paint mIconPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
-    private final Paint mShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
-    private final ShadowDrawableState mState;
-    private AnimatedVectorDrawable mAnimatedDrawable;
-    private final Callback mAnimatedDrawableCallback = new Callback() {
-        @Override
-        public void invalidateDrawable(@NonNull Drawable who) {
-            invalidateSelf();
-        }
-
-        @Override
-        public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {
-            scheduleSelf(what, when);
-        }
-
-        @Override
-        public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {
-            unscheduleSelf(what);
-        }
-    };
-
-    public KeyButtonDrawable(Drawable d, @ColorInt int lightColor, @ColorInt int darkColor,
-            boolean horizontalFlip, Color ovalBackgroundColor) {
-        this(d, new ShadowDrawableState(lightColor, darkColor,
-                d instanceof AnimatedVectorDrawable, horizontalFlip, ovalBackgroundColor));
-    }
-
-    private KeyButtonDrawable(Drawable d, ShadowDrawableState state) {
-        mState = state;
-        if (d != null) {
-            mState.mBaseHeight = d.getIntrinsicHeight();
-            mState.mBaseWidth = d.getIntrinsicWidth();
-            mState.mChangingConfigurations = d.getChangingConfigurations();
-            mState.mChildState = d.getConstantState();
-        }
-        if (canAnimate()) {
-            mAnimatedDrawable = (AnimatedVectorDrawable) mState.mChildState.newDrawable().mutate();
-            mAnimatedDrawable.setCallback(mAnimatedDrawableCallback);
-            setDrawableBounds(mAnimatedDrawable);
-        }
-    }
-
-    public void setDarkIntensity(float intensity) {
-        mState.mDarkIntensity = intensity;
-        final int color = (int) ArgbEvaluator.getInstance()
-                .evaluate(intensity, mState.mLightColor, mState.mDarkColor);
-        updateShadowAlpha();
-        setColorFilter(new PorterDuffColorFilter(color, Mode.SRC_ATOP));
-    }
-
-    public void setRotation(float degrees) {
-        if (canAnimate()) {
-            // AnimatedVectorDrawables will not support rotation
-            return;
-        }
-        if (mState.mRotateDegrees != degrees) {
-            mState.mRotateDegrees = degrees;
-            invalidateSelf();
-        }
-    }
-
-    public void setTranslationX(float x) {
-        setTranslation(x, mState.mTranslationY);
-    }
-
-    public void setTranslationY(float y) {
-        setTranslation(mState.mTranslationX, y);
-    }
-
-    public void setTranslation(float x, float y) {
-        if (mState.mTranslationX != x || mState.mTranslationY != y) {
-            mState.mTranslationX = x;
-            mState.mTranslationY = y;
-            invalidateSelf();
-        }
-    }
-
-    public void setShadowProperties(int x, int y, int size, int color) {
-        if (canAnimate()) {
-            // AnimatedVectorDrawables will not support shadows
-            return;
-        }
-        if (mState.mShadowOffsetX != x || mState.mShadowOffsetY != y
-                || mState.mShadowSize != size || mState.mShadowColor != color) {
-            mState.mShadowOffsetX = x;
-            mState.mShadowOffsetY = y;
-            mState.mShadowSize = size;
-            mState.mShadowColor = color;
-            mShadowPaint.setColorFilter(
-                    new PorterDuffColorFilter(mState.mShadowColor, Mode.SRC_ATOP));
-            updateShadowAlpha();
-            invalidateSelf();
-        }
-    }
-
-    @Override
-    public boolean setVisible(boolean visible, boolean restart) {
-        boolean changed = super.setVisible(visible, restart);
-        if (changed) {
-            // End any existing animations when the visibility changes
-            jumpToCurrentState();
-        }
-        return changed;
-    }
-
-    @Override
-    public void jumpToCurrentState() {
-        super.jumpToCurrentState();
-        if (mAnimatedDrawable != null) {
-            mAnimatedDrawable.jumpToCurrentState();
-        }
-    }
-
-    @Override
-    public void setAlpha(int alpha) {
-        mState.mAlpha = alpha;
-        mIconPaint.setAlpha(alpha);
-        updateShadowAlpha();
-        invalidateSelf();
-    }
-
-    @Override
-    public void setColorFilter(ColorFilter colorFilter) {
-        mIconPaint.setColorFilter(colorFilter);
-        if (mAnimatedDrawable != null) {
-            if (hasOvalBg()) {
-                mAnimatedDrawable.setColorFilter(
-                        new PorterDuffColorFilter(mState.mLightColor, PorterDuff.Mode.SRC_IN));
-            } else {
-                mAnimatedDrawable.setColorFilter(colorFilter);
-            }
-        }
-        invalidateSelf();
-    }
-
-    public float getDarkIntensity() {
-        return mState.mDarkIntensity;
-    }
-
-    public float getRotation() {
-        return mState.mRotateDegrees;
-    }
-
-    public float getTranslationX() {
-        return mState.mTranslationX;
-    }
-
-    public float getTranslationY() {
-        return mState.mTranslationY;
-    }
-
-    @Override
-    public ConstantState getConstantState() {
-        return mState;
-    }
-
-    @Override
-    public int getOpacity() {
-        return PixelFormat.TRANSLUCENT;
-    }
-
-    @Override
-    public int getIntrinsicHeight() {
-        return mState.mBaseHeight + (mState.mShadowSize + Math.abs(mState.mShadowOffsetY)) * 2;
-    }
-
-    @Override
-    public int getIntrinsicWidth() {
-        return mState.mBaseWidth + (mState.mShadowSize + Math.abs(mState.mShadowOffsetX)) * 2;
-    }
-
-    public boolean canAnimate() {
-        return mState.mSupportsAnimation;
-    }
-
-    public void startAnimation() {
-        if (mAnimatedDrawable != null) {
-            mAnimatedDrawable.start();
-        }
-    }
-
-    public void resetAnimation() {
-        if (mAnimatedDrawable != null) {
-            mAnimatedDrawable.reset();
-        }
-    }
-
-    public void clearAnimationCallbacks() {
-        if (mAnimatedDrawable != null) {
-            mAnimatedDrawable.clearAnimationCallbacks();
-        }
-    }
-
-    @Override
-    public void draw(Canvas canvas) {
-        Rect bounds = getBounds();
-        if (bounds.isEmpty()) {
-            return;
-        }
-
-        if (mAnimatedDrawable != null) {
-            mAnimatedDrawable.draw(canvas);
-        } else {
-            // If no cache or previous cached bitmap is hardware/software acceleration does not
-            // match the current canvas on draw then regenerate
-            boolean hwBitmapChanged = mState.mIsHardwareBitmap != canvas.isHardwareAccelerated();
-            if (hwBitmapChanged) {
-                mState.mIsHardwareBitmap = canvas.isHardwareAccelerated();
-            }
-            if (mState.mLastDrawnIcon == null || hwBitmapChanged) {
-                regenerateBitmapIconCache();
-            }
-            canvas.save();
-            canvas.translate(mState.mTranslationX, mState.mTranslationY);
-            canvas.rotate(mState.mRotateDegrees, getIntrinsicWidth() / 2, getIntrinsicHeight() / 2);
-
-            if (mState.mShadowSize > 0) {
-                if (mState.mLastDrawnShadow == null || hwBitmapChanged) {
-                    regenerateBitmapShadowCache();
-                }
-
-                // Translate (with rotation offset) before drawing the shadow
-                final float radians = (float) (mState.mRotateDegrees * Math.PI / 180);
-                final float shadowOffsetX = (float) (Math.sin(radians) * mState.mShadowOffsetY
-                        + Math.cos(radians) * mState.mShadowOffsetX) - mState.mTranslationX;
-                final float shadowOffsetY = (float) (Math.cos(radians) * mState.mShadowOffsetY
-                        - Math.sin(radians) * mState.mShadowOffsetX) - mState.mTranslationY;
-                canvas.drawBitmap(mState.mLastDrawnShadow, shadowOffsetX, shadowOffsetY,
-                        mShadowPaint);
-            }
-            canvas.drawBitmap(mState.mLastDrawnIcon, null, bounds, mIconPaint);
-            canvas.restore();
-        }
-    }
-
-    @Override
-    public boolean canApplyTheme() {
-        return mState.canApplyTheme();
-    }
-
-    @ColorInt int getDrawableBackgroundColor() {
-        return mState.mOvalBackgroundColor.toArgb();
-    }
-
-    boolean hasOvalBg() {
-        return mState.mOvalBackgroundColor != null;
-    }
-
-    private void regenerateBitmapIconCache() {
-        final int width = getIntrinsicWidth();
-        final int height = getIntrinsicHeight();
-        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-        final Canvas canvas = new Canvas(bitmap);
-
-        // Call mutate, so that the pixel allocation by the underlying vector drawable is cleared.
-        final Drawable d = mState.mChildState.newDrawable().mutate();
-        setDrawableBounds(d);
-        canvas.save();
-        if (mState.mHorizontalFlip) {
-            canvas.scale(-1f, 1f, width * 0.5f, height * 0.5f);
-        }
-        d.draw(canvas);
-        canvas.restore();
-
-        if (mState.mIsHardwareBitmap) {
-            bitmap = bitmap.copy(Bitmap.Config.HARDWARE, false);
-        }
-        mState.mLastDrawnIcon = bitmap;
-    }
-
-    private void regenerateBitmapShadowCache() {
-        if (mState.mShadowSize == 0) {
-            // No shadow
-            mState.mLastDrawnIcon = null;
-            return;
-        }
-
-        final int width = getIntrinsicWidth();
-        final int height = getIntrinsicHeight();
-        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-        Canvas canvas = new Canvas(bitmap);
-
-        // Call mutate, so that the pixel allocation by the underlying vector drawable is cleared.
-        final Drawable d = mState.mChildState.newDrawable().mutate();
-        setDrawableBounds(d);
-        canvas.save();
-        if (mState.mHorizontalFlip) {
-            canvas.scale(-1f, 1f, width * 0.5f, height * 0.5f);
-        }
-        d.draw(canvas);
-        canvas.restore();
-
-        // Draws the shadow from original drawable
-        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
-        paint.setMaskFilter(new BlurMaskFilter(mState.mShadowSize, Blur.NORMAL));
-        int[] offset = new int[2];
-        final Bitmap shadow = bitmap.extractAlpha(paint, offset);
-        paint.setMaskFilter(null);
-        bitmap.eraseColor(Color.TRANSPARENT);
-        canvas.drawBitmap(shadow, offset[0], offset[1], paint);
-
-        if (mState.mIsHardwareBitmap) {
-            bitmap = bitmap.copy(Bitmap.Config.HARDWARE, false);
-        }
-        mState.mLastDrawnShadow = bitmap;
-    }
-
-    /**
-     * Set the alpha of the shadow. As dark intensity increases, drop the alpha of the shadow since
-     * dark color and shadow should not be visible at the same time.
-     */
-    private void updateShadowAlpha() {
-        // Update the color from the original color's alpha as the max
-        int alpha = Color.alpha(mState.mShadowColor);
-        mShadowPaint.setAlpha(
-                Math.round(alpha * (mState.mAlpha / 255f) * (1 - mState.mDarkIntensity)));
-    }
-
-    /**
-     * Prevent shadow clipping by offsetting the drawable bounds by the shadow and its offset
-     * @param d the drawable to set the bounds
-     */
-    private void setDrawableBounds(Drawable d) {
-        final int offsetX = mState.mShadowSize + Math.abs(mState.mShadowOffsetX);
-        final int offsetY = mState.mShadowSize + Math.abs(mState.mShadowOffsetY);
-        d.setBounds(offsetX, offsetY, getIntrinsicWidth() - offsetX,
-                getIntrinsicHeight() - offsetY);
-    }
-
-    private static class ShadowDrawableState extends ConstantState {
-        int mChangingConfigurations;
-        int mBaseWidth;
-        int mBaseHeight;
-        float mRotateDegrees;
-        float mTranslationX;
-        float mTranslationY;
-        int mShadowOffsetX;
-        int mShadowOffsetY;
-        int mShadowSize;
-        int mShadowColor;
-        float mDarkIntensity;
-        int mAlpha;
-        boolean mHorizontalFlip;
-
-        boolean mIsHardwareBitmap;
-        Bitmap mLastDrawnIcon;
-        Bitmap mLastDrawnShadow;
-        ConstantState mChildState;
-
-        final int mLightColor;
-        final int mDarkColor;
-        final boolean mSupportsAnimation;
-        final Color mOvalBackgroundColor;
-
-        public ShadowDrawableState(@ColorInt int lightColor, @ColorInt int darkColor,
-                boolean animated, boolean horizontalFlip, Color ovalBackgroundColor) {
-            mLightColor = lightColor;
-            mDarkColor = darkColor;
-            mSupportsAnimation = animated;
-            mAlpha = 255;
-            mHorizontalFlip = horizontalFlip;
-            mOvalBackgroundColor = ovalBackgroundColor;
-        }
-
-        @Override
-        public Drawable newDrawable() {
-            return new KeyButtonDrawable(null, this);
-        }
-
-        @Override
-        public int getChangingConfigurations() {
-            return mChangingConfigurations;
-        }
-
-        @Override
-        public boolean canApplyTheme() {
-            return true;
-        }
-    }
-
-    /**
-     * Creates a KeyButtonDrawable with a shadow given its icon. For more information, see
-     * {@link #create(Context, int, boolean, boolean)}.
-     */
-    public static KeyButtonDrawable create(Context lightContext, Context darkContext,
-            @DrawableRes int iconResId, boolean hasShadow, Color ovalBackgroundColor) {
-        return create(lightContext,
-            Utils.getColorAttrDefaultColor(lightContext, R.attr.singleToneColor),
-            Utils.getColorAttrDefaultColor(darkContext, R.attr.singleToneColor),
-            iconResId, hasShadow, ovalBackgroundColor);
-    }
-
-    /**
-     * Creates a KeyButtonDrawable with a shadow given its icon. For more information, see
-     * {@link #create(Context, int, boolean, boolean)}.
-     */
-    public static KeyButtonDrawable create(Context context, @ColorInt int lightColor,
-            @ColorInt int darkColor, @DrawableRes int iconResId, boolean hasShadow,
-            Color ovalBackgroundColor) {
-        final Resources res = context.getResources();
-        boolean isRtl = res.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
-        Drawable d = context.getDrawable(iconResId);
-        final KeyButtonDrawable drawable = new KeyButtonDrawable(d, lightColor, darkColor,
-                isRtl && d.isAutoMirrored(), ovalBackgroundColor);
-        if (hasShadow) {
-            int offsetX = res.getDimensionPixelSize(R.dimen.nav_key_button_shadow_offset_x);
-            int offsetY = res.getDimensionPixelSize(R.dimen.nav_key_button_shadow_offset_y);
-            int radius = res.getDimensionPixelSize(R.dimen.nav_key_button_shadow_radius);
-            int color = context.getColor(R.color.nav_key_button_shadow_color);
-            drawable.setShadowProperties(offsetX, offsetY, radius, color);
-        }
-        return drawable;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java
deleted file mode 100644
index dbe87ea..0000000
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java
+++ /dev/null
@@ -1,506 +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.navigationbar.buttons;
-
-import static android.view.Display.INVALID_DISPLAY;
-import static android.view.KeyEvent.KEYCODE_UNKNOWN;
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.Icon;
-import android.hardware.input.InputManager;
-import android.hardware.input.InputManagerGlobal;
-import android.media.AudioManager;
-import android.metrics.LogMaker;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.HapticFeedbackConstants;
-import android.view.InputDevice;
-import android.view.KeyCharacterMap;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.SoundEffectConstants;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.widget.ImageView;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.UiEvent;
-import com.android.internal.logging.UiEventLogger;
-import com.android.internal.logging.UiEventLoggerImpl;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.Dependency;
-import com.android.systemui.assist.AssistManager;
-import com.android.systemui.navigationbar.NavBarButtonClickLogger;
-import com.android.systemui.recents.OverviewProxyService;
-import com.android.systemui.res.R;
-import com.android.systemui.shared.navigationbar.KeyButtonRipple;
-import com.android.systemui.shared.system.QuickStepContract;
-
-public class KeyButtonView extends ImageView implements ButtonInterface {
-    private static final String TAG = KeyButtonView.class.getSimpleName();
-
-    private final boolean mPlaySounds;
-    private final UiEventLogger mUiEventLogger;
-    private int mContentDescriptionRes;
-    private long mDownTime;
-    private int mCode;
-    private int mTouchDownX;
-    private int mTouchDownY;
-    private boolean mIsVertical;
-    private AudioManager mAudioManager;
-    private boolean mGestureAborted;
-    @VisibleForTesting boolean mLongClicked;
-    private OnClickListener mOnClickListener;
-    private final KeyButtonRipple mRipple;
-    private final OverviewProxyService mOverviewProxyService;
-    private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
-    private final InputManagerGlobal mInputManagerGlobal;
-    private final Paint mOvalBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
-    private float mDarkIntensity;
-    private boolean mHasOvalBg = false;
-    private NavBarButtonClickLogger mNavBarButtonClickLogger;
-
-    @VisibleForTesting
-    public enum NavBarButtonEvent implements UiEventLogger.UiEventEnum {
-
-        @UiEvent(doc = "The home button was pressed in the navigation bar.")
-        NAVBAR_HOME_BUTTON_TAP(533),
-
-        @UiEvent(doc = "The back button was pressed in the navigation bar.")
-        NAVBAR_BACK_BUTTON_TAP(534),
-
-        @UiEvent(doc = "The overview button was pressed in the navigation bar.")
-        NAVBAR_OVERVIEW_BUTTON_TAP(535),
-
-        @UiEvent(doc = "The ime switcher button was pressed in the navigation bar.")
-        NAVBAR_IME_SWITCHER_BUTTON_TAP(923),
-
-        @UiEvent(doc = "The home button was long-pressed in the navigation bar.")
-        NAVBAR_HOME_BUTTON_LONGPRESS(536),
-
-        @UiEvent(doc = "The back button was long-pressed in the navigation bar.")
-        NAVBAR_BACK_BUTTON_LONGPRESS(537),
-
-        @UiEvent(doc = "The overview button was long-pressed in the navigation bar.")
-        NAVBAR_OVERVIEW_BUTTON_LONGPRESS(538),
-
-        NONE(0);  // an event we should not log
-
-        private final int mId;
-
-        NavBarButtonEvent(int id) {
-            mId = id;
-        }
-
-        @Override
-        public int getId() {
-            return mId;
-        }
-    }
-    private final Runnable mCheckLongPress = new Runnable() {
-        public void run() {
-            if (isPressed()) {
-                // Log.d("KeyButtonView", "longpressed: " + this);
-                if (isLongClickable()) {
-                    // Just an old-fashioned ImageView
-                    performLongClick();
-                    mLongClicked = true;
-                } else {
-                    if (mCode != KEYCODE_UNKNOWN) {
-                        sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
-                        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
-                    }
-                    mLongClicked = true;
-                }
-            }
-        }
-    };
-
-    public KeyButtonView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public KeyButtonView(Context context, AttributeSet attrs, int defStyle) {
-        this(context, attrs, defStyle, InputManagerGlobal.getInstance(), new UiEventLoggerImpl());
-    }
-
-    @VisibleForTesting
-    public KeyButtonView(Context context, AttributeSet attrs, int defStyle,
-            InputManagerGlobal manager, UiEventLogger uiEventLogger) {
-        super(context, attrs);
-        mUiEventLogger = uiEventLogger;
-
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyButtonView,
-                defStyle, 0);
-
-        mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, KEYCODE_UNKNOWN);
-
-        mPlaySounds = a.getBoolean(R.styleable.KeyButtonView_playSound, true);
-
-        TypedValue value = new TypedValue();
-        if (a.getValue(R.styleable.KeyButtonView_android_contentDescription, value)) {
-            mContentDescriptionRes = value.resourceId;
-        }
-
-        a.recycle();
-
-        setClickable(true);
-        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
-
-        mRipple = new KeyButtonRipple(context, this, R.dimen.key_button_ripple_max_width);
-        mOverviewProxyService = Dependency.get(OverviewProxyService.class);
-        mInputManagerGlobal = manager;
-        setBackground(mRipple);
-        setWillNotDraw(false);
-        forceHasOverlappingRendering(false);
-    }
-
-    @Override
-    public boolean isClickable() {
-        return mCode != KEYCODE_UNKNOWN || super.isClickable();
-    }
-
-    public void setCode(int code) {
-        mCode = code;
-    }
-
-    @Override
-    public void setOnClickListener(OnClickListener onClickListener) {
-        super.setOnClickListener(onClickListener);
-        mOnClickListener = onClickListener;
-    }
-
-    public void setNavBarButtonClickLogger(NavBarButtonClickLogger navBarButtonClickLogger) {
-        mNavBarButtonClickLogger = navBarButtonClickLogger;
-    }
-
-    public void loadAsync(Icon icon) {
-        new AsyncTask<Icon, Void, Drawable>() {
-            @Override
-            protected Drawable doInBackground(Icon... params) {
-                return params[0].loadDrawable(mContext);
-            }
-
-            @Override
-            protected void onPostExecute(Drawable drawable) {
-                setImageDrawable(drawable);
-            }
-        }.execute(icon);
-    }
-
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-
-        if (mContentDescriptionRes != 0) {
-            setContentDescription(mContext.getString(mContentDescriptionRes));
-        }
-    }
-
-    @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        if (mCode != KEYCODE_UNKNOWN) {
-            info.addAction(new AccessibilityNodeInfo.AccessibilityAction(ACTION_CLICK, null));
-            if (isLongClickable()) {
-                info.addAction(
-                        new AccessibilityNodeInfo.AccessibilityAction(ACTION_LONG_CLICK, null));
-            }
-        }
-    }
-
-    @Override
-    protected void onWindowVisibilityChanged(int visibility) {
-        super.onWindowVisibilityChanged(visibility);
-        if (visibility != View.VISIBLE) {
-            jumpDrawablesToCurrentState();
-        }
-    }
-
-    @Override
-    public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
-        if (action == ACTION_CLICK && mCode != KEYCODE_UNKNOWN) {
-            sendEvent(KeyEvent.ACTION_DOWN, 0, SystemClock.uptimeMillis());
-            sendEvent(KeyEvent.ACTION_UP, 0);
-            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
-            playSoundEffect(SoundEffectConstants.CLICK);
-            return true;
-        } else if (action == ACTION_LONG_CLICK && mCode != KEYCODE_UNKNOWN) {
-            sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
-            sendEvent(KeyEvent.ACTION_UP, 0);
-            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
-            return true;
-        }
-        return super.performAccessibilityActionInternal(action, arguments);
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        final boolean showSwipeUI = mOverviewProxyService.shouldShowSwipeUpUI();
-        final int action = ev.getAction();
-        int x, y;
-        if (action == MotionEvent.ACTION_DOWN) {
-            mGestureAborted = false;
-        }
-        if (mGestureAborted) {
-            setPressed(false);
-            return false;
-        }
-
-        switch (action) {
-            case MotionEvent.ACTION_DOWN:
-                mDownTime = SystemClock.uptimeMillis();
-                mLongClicked = false;
-                setPressed(true);
-
-                mTouchDownX = (int) ev.getX();
-                mTouchDownY = (int) ev.getY();
-                if (mCode != KEYCODE_UNKNOWN) {
-                    sendEvent(KeyEvent.ACTION_DOWN, 0, mDownTime);
-                } else {
-                    // Provide the same haptic feedback that the system offers for virtual keys.
-                    performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
-                }
-                if (!showSwipeUI) {
-                    playSoundEffect(SoundEffectConstants.CLICK);
-                }
-                removeCallbacks(mCheckLongPress);
-                postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
-                break;
-            case MotionEvent.ACTION_MOVE:
-                x = (int) ev.getX();
-                y = (int) ev.getY();
-
-                float slop = QuickStepContract.getQuickStepTouchSlopPx(getContext());
-                if (Math.abs(x - mTouchDownX) > slop || Math.abs(y - mTouchDownY) > slop) {
-                    // When quick step is enabled, prevent animating the ripple triggered by
-                    // setPressed and decide to run it on touch up
-                    setPressed(false);
-                    removeCallbacks(mCheckLongPress);
-                }
-                break;
-            case MotionEvent.ACTION_CANCEL:
-                setPressed(false);
-                if (mCode != KEYCODE_UNKNOWN) {
-                    sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
-                }
-                removeCallbacks(mCheckLongPress);
-                break;
-            case MotionEvent.ACTION_UP:
-                final boolean doIt = isPressed() && !mLongClicked;
-                setPressed(false);
-                final boolean doHapticFeedback = (SystemClock.uptimeMillis() - mDownTime) > 150;
-                if (showSwipeUI) {
-                    if (doIt) {
-                        // Apply haptic feedback on touch up since there is none on touch down
-                        performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
-                        playSoundEffect(SoundEffectConstants.CLICK);
-                    }
-                } else if (doHapticFeedback && !mLongClicked) {
-                    // Always send a release ourselves because it doesn't seem to be sent elsewhere
-                    // and it feels weird to sometimes get a release haptic and other times not.
-                    performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY_RELEASE);
-                }
-                if (mCode != KEYCODE_UNKNOWN) {
-                    if (doIt) {
-                        sendEvent(KeyEvent.ACTION_UP, 0);
-                        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
-                    } else {
-                        sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
-                    }
-                } else {
-                    // no key code, just a regular ImageView
-                    if (doIt && mOnClickListener != null) {
-                        mOnClickListener.onClick(this);
-                        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
-                    }
-                }
-                removeCallbacks(mCheckLongPress);
-                break;
-        }
-
-        return true;
-    }
-
-    @Override
-    public void setImageDrawable(Drawable drawable) {
-        super.setImageDrawable(drawable);
-
-        if (drawable == null) {
-            return;
-        }
-        KeyButtonDrawable keyButtonDrawable = (KeyButtonDrawable) drawable;
-        keyButtonDrawable.setDarkIntensity(mDarkIntensity);
-        mHasOvalBg = keyButtonDrawable.hasOvalBg();
-        if (mHasOvalBg) {
-            mOvalBgPaint.setColor(keyButtonDrawable.getDrawableBackgroundColor());
-        }
-        mRipple.setType(keyButtonDrawable.hasOvalBg() ? KeyButtonRipple.Type.OVAL
-                : KeyButtonRipple.Type.ROUNDED_RECT);
-    }
-
-    public void playSoundEffect(int soundConstant) {
-        if (!mPlaySounds) return;
-        mAudioManager.playSoundEffect(soundConstant, ActivityManager.getCurrentUser());
-    }
-
-    public void sendEvent(int action, int flags) {
-        sendEvent(action, flags, SystemClock.uptimeMillis());
-    }
-
-    private void logSomePresses(int action, int flags) {
-        boolean longPressSet = (flags & KeyEvent.FLAG_LONG_PRESS) != 0;
-        NavBarButtonEvent uiEvent = NavBarButtonEvent.NONE;
-        if (action == MotionEvent.ACTION_UP && mLongClicked) {
-            return;  // don't log the up after a long press
-        }
-        if (action == MotionEvent.ACTION_DOWN && !longPressSet) {
-            return;  // don't log a down unless it is also the long press marker
-        }
-        if ((flags & KeyEvent.FLAG_CANCELED) != 0
-                || (flags & KeyEvent.FLAG_CANCELED_LONG_PRESS) != 0) {
-            return;  // don't log various cancels
-        }
-        switch(mCode) {
-            case KeyEvent.KEYCODE_BACK:
-                uiEvent = longPressSet
-                        ? NavBarButtonEvent.NAVBAR_BACK_BUTTON_LONGPRESS
-                        : NavBarButtonEvent.NAVBAR_BACK_BUTTON_TAP;
-
-                if (mNavBarButtonClickLogger != null) {
-                    mNavBarButtonClickLogger.logBackButtonClick();
-                }
-                break;
-            case KeyEvent.KEYCODE_HOME:
-                uiEvent = longPressSet
-                        ? NavBarButtonEvent.NAVBAR_HOME_BUTTON_LONGPRESS
-                        : NavBarButtonEvent.NAVBAR_HOME_BUTTON_TAP;
-
-                if (mNavBarButtonClickLogger != null) {
-                    mNavBarButtonClickLogger.logHomeButtonClick();
-                }
-                break;
-            case KeyEvent.KEYCODE_APP_SWITCH:
-                uiEvent = longPressSet
-                        ? NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_LONGPRESS
-                        : NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_TAP;
-                break;
-        }
-        if (uiEvent != NavBarButtonEvent.NONE) {
-            mUiEventLogger.log(uiEvent);
-        }
-    }
-
-    private void sendEvent(int action, int flags, long when) {
-        mMetricsLogger.write(new LogMaker(MetricsEvent.ACTION_NAV_BUTTON_EVENT)
-                .setType(MetricsEvent.TYPE_ACTION)
-                .setSubtype(mCode)
-                .addTaggedData(MetricsEvent.FIELD_NAV_ACTION, action)
-                .addTaggedData(MetricsEvent.FIELD_FLAGS, flags));
-        logSomePresses(action, flags);
-        if (mCode == KeyEvent.KEYCODE_BACK && flags != KeyEvent.FLAG_LONG_PRESS) {
-            Log.i(TAG, "Back button event: " + KeyEvent.actionToString(action));
-        }
-        final int repeatCount = (flags & KeyEvent.FLAG_LONG_PRESS) != 0 ? 1 : 0;
-        final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, repeatCount,
-                0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
-                flags | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
-                InputDevice.SOURCE_KEYBOARD);
-
-        int displayId = INVALID_DISPLAY;
-
-        // Make KeyEvent work on multi-display environment
-        if (getDisplay() != null) {
-            displayId = getDisplay().getDisplayId();
-        }
-        if (displayId != INVALID_DISPLAY) {
-            ev.setDisplayId(displayId);
-        }
-        mInputManagerGlobal.injectInputEvent(ev,
-                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
-    }
-
-    @Override
-    public void abortCurrentGesture() {
-        Log.d("b/63783866", "KeyButtonView.abortCurrentGesture");
-        if (mCode != KeyEvent.KEYCODE_UNKNOWN) {
-            sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
-        }
-        // When aborting long-press home and Launcher has requested to override it, fade out the
-        // ripple more quickly.
-        if (mCode == KeyEvent.KEYCODE_HOME && Dependency.get(AssistManager.class)
-                .shouldOverrideAssist(AssistManager.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS)) {
-            mRipple.speedUpNextFade();
-        }
-        setPressed(false);
-        mRipple.abortDelayedRipple();
-        mGestureAborted = true;
-    }
-
-    /** Run when the ripple for this button is next invisible. Only used once. */
-    public void setOnRippleInvisibleRunnable(Runnable onRippleInvisibleRunnable) {
-        mRipple.setOnInvisibleRunnable(onRippleInvisibleRunnable);
-    }
-
-    @Override
-    public void setDarkIntensity(float darkIntensity) {
-        mDarkIntensity = darkIntensity;
-
-        Drawable drawable = getDrawable();
-        if (drawable != null) {
-            ((KeyButtonDrawable) drawable).setDarkIntensity(darkIntensity);
-            // Since we reuse the same drawable for multiple views, we need to invalidate the view
-            // manually.
-            invalidate();
-        }
-        mRipple.setDarkIntensity(darkIntensity);
-    }
-
-    @Override
-    public void setDelayTouchFeedback(boolean shouldDelay) {
-        mRipple.setDelayTouchFeedback(shouldDelay);
-    }
-
-    @Override
-    public void draw(Canvas canvas) {
-        if (mHasOvalBg) {
-            int d = Math.min(getWidth(), getHeight());
-            canvas.drawOval(0, 0, d, d, mOvalBgPaint);
-        }
-        super.draw(canvas);
-    }
-
-    @Override
-    public void setVertical(boolean vertical) {
-        mIsVertical = vertical;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java
deleted file mode 100644
index d780f7c..0000000
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/NearestTouchFrame.java
+++ /dev/null
@@ -1,229 +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.navigationbar.buttons;
-
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.TypedArray;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.android.systemui.res.R;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Redirects touches that aren't handled by any child view to the nearest
- * clickable child. Only takes effect on <sw600dp.
- */
-public class NearestTouchFrame extends FrameLayout {
-
-    private final List<View> mClickableChildren = new ArrayList<>();
-    private final List<View> mAttachedChildren = new ArrayList<>();
-    private final boolean mIsActive;
-    private final int[] mTmpInt = new int[2];
-    private final int[] mOffset = new int[2];
-    private boolean mIsVertical;
-    private View mTouchingChild;
-    private final Map<View, Rect> mTouchableRegions = new HashMap<>();
-    /**
-     * Used to sort all child views either by their left position or their top position,
-     * depending on if this layout is used horizontally or vertically, respectively
-     */
-    private final Comparator<View> mChildRegionComparator =
-            (view1, view2) -> {
-                int leftTopIndex = 0;
-                if (mIsVertical) {
-                    // Compare view bound's "top" values
-                    leftTopIndex = 1;
-                }
-                view1.getLocationInWindow(mTmpInt);
-                int startingCoordView1 = mTmpInt[leftTopIndex] - mOffset[leftTopIndex];
-                view2.getLocationInWindow(mTmpInt);
-                int startingCoordView2 = mTmpInt[leftTopIndex] - mOffset[leftTopIndex];
-
-                return startingCoordView1 - startingCoordView2;
-            };
-
-    public NearestTouchFrame(Context context, AttributeSet attrs) {
-        this(context, attrs, context.getResources().getConfiguration());
-    }
-
-    @VisibleForTesting
-    NearestTouchFrame(Context context, AttributeSet attrs, Configuration c) {
-        super(context, attrs);
-        mIsActive = c.smallestScreenWidthDp < 600;
-        int[] attrsArray = new int[] {R.attr.isVertical};
-        TypedArray ta = context.obtainStyledAttributes(attrs, attrsArray);
-        mIsVertical = ta.getBoolean(0, false);
-        ta.recycle();
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-        mClickableChildren.clear();
-        mAttachedChildren.clear();
-        mTouchableRegions.clear();
-        addClickableChildren(this);
-        getLocationInWindow(mOffset);
-        cacheClosestChildLocations();
-    }
-
-    /**
-     * Populates {@link #mTouchableRegions} with the regions where each clickable child is the
-     * closest for a given point on this layout.
-     */
-    private void cacheClosestChildLocations() {
-        if (getWidth() == 0 || getHeight() == 0) {
-            return;
-        }
-
-        // Sort by either top or left depending on mIsVertical, then take out all children
-        // that are not attached to window
-        mClickableChildren.sort(mChildRegionComparator);
-        mClickableChildren.stream()
-                .filter(View::isAttachedToWindow)
-                .forEachOrdered(mAttachedChildren::add);
-
-        // Cache bounds of children
-        // Mark coordinates where the actual child layout resides in this frame's window
-        for (int i = 0; i < mAttachedChildren.size(); i++) {
-            View child = mAttachedChildren.get(i);
-            if (!child.isAttachedToWindow()) {
-                continue;
-            }
-            Rect childRegion = getChildsBounds(child);
-
-            // We compute closest child from this child to the previous one
-            if (i == 0) {
-                // First child, nothing to the left/top of it
-                if (mIsVertical) {
-                    childRegion.top = 0;
-                } else {
-                    childRegion.left = 0;
-                }
-                mTouchableRegions.put(child, childRegion);
-                continue;
-            }
-
-            View previousChild = mAttachedChildren.get(i - 1);
-            Rect previousChildBounds = mTouchableRegions.get(previousChild);
-            int midPoint;
-            if (mIsVertical) {
-                int distance = childRegion.top - previousChildBounds.bottom;
-                midPoint = distance / 2;
-                childRegion.top -= midPoint;
-                previousChildBounds.bottom += midPoint - ((distance % 2) == 0 ? 1 : 0);
-            } else {
-                int distance = childRegion.left - previousChildBounds.right;
-                midPoint = distance / 2;
-                childRegion.left -= midPoint;
-                previousChildBounds.right += midPoint - ((distance % 2) == 0 ? 1 : 0);
-            }
-
-            if (i == mClickableChildren.size() - 1) {
-                // Last child, nothing to right/bottom of it
-                if (mIsVertical) {
-                    childRegion.bottom = getHeight();
-                } else {
-                    childRegion.right = getWidth();
-                }
-            }
-
-            mTouchableRegions.put(child, childRegion);
-        }
-    }
-
-    @VisibleForTesting
-    void setIsVertical(boolean isVertical) {
-        mIsVertical = isVertical;
-    }
-
-    private Rect getChildsBounds(View child) {
-        child.getLocationInWindow(mTmpInt);
-        int left = mTmpInt[0] - mOffset[0];
-        int top = mTmpInt[1] - mOffset[1];
-        int right = left + child.getWidth();
-        int bottom = top + child.getHeight();
-        return new Rect(left, top, right, bottom);
-    }
-
-    private void addClickableChildren(ViewGroup group) {
-        final int N = group.getChildCount();
-        for (int i = 0; i < N; i++) {
-            View child = group.getChildAt(i);
-            if (child.isClickable()) {
-                mClickableChildren.add(child);
-            } else if (child instanceof ViewGroup) {
-                addClickableChildren((ViewGroup) child);
-            }
-        }
-    }
-
-    /**
-     * @return A Map where the key is the view object of the button and the value
-     * is the Rect where that button will receive a touch event if pressed. This Rect will
-     * usually be larger than the layout bounds for the button.
-     * The Rect is in screen coordinates.
-     */
-    public Map<View, Rect> getFullTouchableChildRegions() {
-        Map<View, Rect> fullTouchRegions = new HashMap<>(mTouchableRegions.size());
-        getLocationOnScreen(mTmpInt);
-        for (Map.Entry<View, Rect> entry : mTouchableRegions.entrySet()) {
-            View child = entry.getKey();
-            Rect screenRegion = new Rect(entry.getValue());
-            screenRegion.offset(mTmpInt[0], mTmpInt[1]);
-            fullTouchRegions.put(child, screenRegion);
-        }
-        return fullTouchRegions;
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        if (mIsActive) {
-            int x = (int) event.getX();
-            int y = (int) event.getY();
-            if (event.getAction() == MotionEvent.ACTION_DOWN) {
-                mTouchingChild = mClickableChildren
-                        .stream()
-                        .filter(View::isAttachedToWindow)
-                        .filter(view -> mTouchableRegions.get(view).contains(x, y))
-                        .findFirst()
-                        .orElse(null);
-
-            }
-            if (mTouchingChild != null) {
-                event.offsetLocation(mTouchingChild.getWidth() / 2 - x,
-                        mTouchingChild.getHeight() / 2 - y);
-                return mTouchingChild.getVisibility() == VISIBLE
-                        && mTouchingChild.dispatchTouchEvent(event);
-            }
-        }
-        return super.onTouchEvent(event);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ReverseLinearLayout.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ReverseLinearLayout.java
deleted file mode 100644
index f1e1366..0000000
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/ReverseLinearLayout.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.navigationbar.buttons;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
-
-import java.util.ArrayList;
-
-/**
- * Automatically reverses the order of children as they are added.
- * Also reverse the width and height values of layout params
- */
-public class ReverseLinearLayout extends LinearLayout {
-
-    /** If true, the layout is reversed vs. a regular linear layout */
-    private boolean mIsLayoutReverse;
-
-    /** If true, the layout is opposite to it's natural reversity from the layout direction */
-    private boolean mIsAlternativeOrder;
-
-    public ReverseLinearLayout(Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        updateOrder();
-    }
-
-    @Override
-    public void addView(View child) {
-        reverseParams(child.getLayoutParams(), child, mIsLayoutReverse);
-        if (mIsLayoutReverse) {
-            super.addView(child, 0);
-        } else {
-            super.addView(child);
-        }
-    }
-
-    @Override
-    public void addView(View child, ViewGroup.LayoutParams params) {
-        reverseParams(params, child, mIsLayoutReverse);
-        if (mIsLayoutReverse) {
-            super.addView(child, 0, params);
-        } else {
-            super.addView(child, params);
-        }
-    }
-
-    @Override
-    public void onRtlPropertiesChanged(int layoutDirection) {
-        super.onRtlPropertiesChanged(layoutDirection);
-        updateOrder();
-    }
-
-    public void setAlternativeOrder(boolean alternative) {
-        mIsAlternativeOrder = alternative;
-        updateOrder();
-    }
-
-    /**
-     * In landscape, the LinearLayout is not auto mirrored since it is vertical. Therefore we
-     * have to do it manually
-     */
-    private void updateOrder() {
-        boolean isLayoutRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
-        boolean isLayoutReverse = isLayoutRtl ^ mIsAlternativeOrder;
-
-        if (mIsLayoutReverse != isLayoutReverse) {
-            // reversity changed, swap the order of all views.
-            int childCount = getChildCount();
-            ArrayList<View> childList = new ArrayList<>(childCount);
-            for (int i = 0; i < childCount; i++) {
-                childList.add(getChildAt(i));
-            }
-            removeAllViews();
-            for (int i = childCount - 1; i >= 0; i--) {
-                final View child = childList.get(i);
-                super.addView(child);
-            }
-            mIsLayoutReverse = isLayoutReverse;
-        }
-    }
-
-    private static void reverseParams(ViewGroup.LayoutParams params, View child,
-            boolean isLayoutReverse) {
-        if (child instanceof Reversable) {
-            ((Reversable) child).reverse(isLayoutReverse);
-        }
-        if (child.getPaddingLeft() == child.getPaddingRight()
-                && child.getPaddingTop() == child.getPaddingBottom()) {
-            child.setPadding(child.getPaddingTop(), child.getPaddingLeft(),
-                    child.getPaddingTop(), child.getPaddingLeft());
-        }
-        if (params == null) {
-            return;
-        }
-        int width = params.width;
-        params.width = params.height;
-        params.height = width;
-    }
-
-    public interface Reversable {
-        void reverse(boolean isLayoutReverse);
-    }
-
-    public static class ReverseRelativeLayout extends RelativeLayout implements Reversable {
-
-        public ReverseRelativeLayout(Context context) {
-            super(context);
-        }
-
-        @Override
-        public void reverse(boolean isLayoutReverse) {
-            updateGravity(isLayoutReverse);
-            reverseGroup(this, isLayoutReverse);
-        }
-
-        private int mDefaultGravity = Gravity.NO_GRAVITY;
-        public void setDefaultGravity(int gravity) {
-            mDefaultGravity = gravity;
-        }
-
-        public void updateGravity(boolean isLayoutReverse) {
-            // Flip gravity if top of bottom is used
-            if (mDefaultGravity != Gravity.TOP && mDefaultGravity != Gravity.BOTTOM) return;
-
-            // Use the default (intended for 270 LTR and 90 RTL) unless layout is otherwise
-            int gravityToApply = mDefaultGravity;
-            if (isLayoutReverse) {
-                gravityToApply = mDefaultGravity == Gravity.TOP ? Gravity.BOTTOM : Gravity.TOP;
-            }
-
-            if (getGravity() != gravityToApply) setGravity(gravityToApply);
-        }
-    }
-    
-    private static void reverseGroup(ViewGroup group, boolean isLayoutReverse) {
-        for (int i = 0; i < group.getChildCount(); i++) {
-            final View child = group.getChildAt(i);
-            reverseParams(child.getLayoutParams(), child, isLayoutReverse);
-
-            // Recursively reverse all children
-            if (child instanceof ViewGroup) {
-                reverseGroup((ViewGroup) child, isLayoutReverse);
-            }
-        }
-    }
-
-}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java
index d1ce1f6..1b985d20 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationHandle.java
@@ -32,7 +32,7 @@
 
 import com.android.app.animation.Interpolators;
 import com.android.settingslib.Utils;
-import com.android.systemui.navigationbar.buttons.ButtonInterface;
+import com.android.systemui.navigationbar.views.buttons.ButtonInterface;
 import com.android.systemui.res.R;
 
 public class NavigationHandle extends View implements ButtonInterface {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
new file mode 100644
index 0000000..e832abb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
@@ -0,0 +1,2096 @@
+/*
+ * 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.navigationbar.views;
+
+import static android.app.ActivityManager.LOCK_TASK_MODE_PINNED;
+import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
+import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN;
+import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
+import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
+import static android.app.StatusBarManager.WindowType;
+import static android.app.StatusBarManager.WindowVisibleState;
+import static android.app.StatusBarManager.windowStateToString;
+import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
+import static android.inputmethodservice.InputMethodService.ENABLE_HIDE_IME_CAPTION_BAR;
+import static android.view.InsetsSource.FLAG_SUPPRESS_SCRIM;
+import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
+
+import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.HOME_BUTTON_LONG_PRESS_DURATION_MS;
+import static com.android.systemui.navigationbar.NavBarHelper.transitionMode;
+import static com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
+import static com.android.systemui.shared.recents.utilities.Utilities.isLargeScreen;
+import static com.android.systemui.shared.rotation.RotationButtonController.DEBUG_ROTATION;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
+import static com.android.systemui.shared.system.QuickStepContract.isGesturalMode;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_OPAQUE;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.TransitionMode;
+import static com.android.systemui.statusbar.phone.CentralSurfaces.DEBUG_WINDOW_STATE;
+import static com.android.systemui.statusbar.phone.CentralSurfaces.dumpBarTransitions;
+import static com.android.systemui.util.Utils.isGesturalModeOnDefaultDisplay;
+
+import android.annotation.IdRes;
+import android.annotation.NonNull;
+import android.app.ActivityTaskManager;
+import android.app.IActivityTaskManager;
+import android.app.StatusBarManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.graphics.Insets;
+import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Region;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.Trace;
+import android.provider.DeviceConfig;
+import android.telecom.TelecomManager;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Display;
+import android.view.Gravity;
+import android.view.HapticFeedbackConstants;
+import android.view.InsetsFrameProvider;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.Surface;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.InternalInsetsInfo;
+import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
+import android.view.WindowInsets;
+import android.view.WindowInsets.Type.InsetsType;
+import android.view.WindowInsetsController.Appearance;
+import android.view.WindowInsetsController.Behavior;
+import android.view.WindowManager;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.inputmethod.InputMethodManager;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity;
+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.LetterboxDetails;
+import com.android.internal.util.LatencyTracker;
+import com.android.internal.view.AppearanceRegion;
+import com.android.systemui.Gefingerpoken;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.DisplayId;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.model.SysUiState;
+import com.android.systemui.navigationbar.views.buttons.NavBarButtonClickLogger;
+import com.android.systemui.navigationbar.NavBarHelper;
+import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope;
+import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.navigationbar.NavigationModeController.ModeChangedListener;
+import com.android.systemui.navigationbar.views.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.views.buttons.DeadZone;
+import com.android.systemui.navigationbar.views.buttons.KeyButtonView;
+import com.android.systemui.navigationbar.views.buttons.NavbarOrientationTrackingLogger;
+import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
+import com.android.systemui.navigationbar.gestural.QuickswitchOrientedNavHandle;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.recents.OverviewProxyService;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.res.R;
+import com.android.systemui.settings.DisplayTracker;
+import com.android.systemui.settings.UserContextProvider;
+import com.android.systemui.settings.UserTracker;
+import com.android.systemui.shade.ShadeViewController;
+import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor;
+import com.android.systemui.shared.navigationbar.RegionSamplingHelper;
+import com.android.systemui.shared.recents.utilities.Utilities;
+import com.android.systemui.shared.rotation.RotationButtonController;
+import com.android.systemui.shared.rotation.RotationPolicyUtil;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
+import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.shared.system.SysUiStatsLog;
+import com.android.systemui.shared.system.TaskStackChangeListener;
+import com.android.systemui.shared.system.TaskStackChangeListeners;
+import com.android.systemui.statusbar.AutoHideUiElement;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.CommandQueue.Callbacks;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationShadeDepthController;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
+import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.LightBarController;
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.DeviceConfigProxy;
+import com.android.systemui.util.ViewController;
+import com.android.wm.shell.back.BackAnimation;
+import com.android.wm.shell.pip.Pip;
+
+import dagger.Lazy;
+
+import java.io.PrintWriter;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.Executor;
+
+import javax.inject.Inject;
+
+/**
+ * Contains logic for a navigation bar view.
+ */
+@NavigationBarScope
+public class NavigationBar extends ViewController<NavigationBarView> implements Callbacks {
+
+    public static final String TAG = "NavigationBar";
+    private static final boolean DEBUG = false;
+    private static final String EXTRA_DISABLE_STATE = "disabled_state";
+    private static final String EXTRA_DISABLE2_STATE = "disabled2_state";
+    private static final String EXTRA_APPEARANCE = "appearance";
+    private static final String EXTRA_BEHAVIOR = "behavior";
+    private static final String EXTRA_TRANSIENT_STATE = "transient_state";
+
+    /** Allow some time inbetween the long press for back and recents. */
+    private static final int LOCK_TO_APP_GESTURE_TOLERANCE = 200;
+    private static final long AUTODIM_TIMEOUT_MS = 2250;
+    private static final float QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON = 3f;
+
+    private final Context mContext;
+    private final Bundle mSavedState;
+    private final WindowManager mWindowManager;
+    private final AccessibilityManager mAccessibilityManager;
+    private final DeviceProvisionedController mDeviceProvisionedController;
+    private final StatusBarStateController mStatusBarStateController;
+    private final MetricsLogger mMetricsLogger;
+    private final Lazy<AssistManager> mAssistManagerLazy;
+    private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    private final SysUiState mSysUiFlagsContainer;
+    private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
+    private final KeyguardStateController mKeyguardStateController;
+    private final ShadeViewController mShadeViewController;
+    private final PanelExpansionInteractor mPanelExpansionInteractor;
+    private final NotificationRemoteInputManager mNotificationRemoteInputManager;
+    private final OverviewProxyService mOverviewProxyService;
+    private final NavigationModeController mNavigationModeController;
+    private final UserTracker mUserTracker;
+    private final CommandQueue mCommandQueue;
+    private final Optional<Pip> mPipOptional;
+    private final Optional<Recents> mRecentsOptional;
+    private final DeviceConfigProxy mDeviceConfigProxy;
+    private final NavigationBarTransitions mNavigationBarTransitions;
+    private final Optional<BackAnimation> mBackAnimation;
+    private final Handler mHandler;
+    private final UiEventLogger mUiEventLogger;
+    private final NavBarHelper mNavBarHelper;
+    private final NotificationShadeDepthController mNotificationShadeDepthController;
+    private final OnComputeInternalInsetsListener mOnComputeInternalInsetsListener;
+    private final UserContextProvider mUserContextProvider;
+    private final WakefulnessLifecycle mWakefulnessLifecycle;
+    private final DisplayTracker mDisplayTracker;
+    private final RegionSamplingHelper mRegionSamplingHelper;
+    private final int mNavColorSampleMargin;
+    private EdgeBackGestureHandler mEdgeBackGestureHandler;
+    private NavigationBarFrame mFrame;
+    private MotionEvent mCurrentDownEvent;
+
+    private @WindowVisibleState int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
+
+    private int mNavigationIconHints = 0;
+    private @TransitionMode int mTransitionMode;
+    private boolean mLongPressHomeEnabled;
+
+    private int mDisabledFlags1;
+    private int mDisabledFlags2;
+    private long mLastLockToAppLongPress;
+
+    private Locale mLocale;
+    private int mLayoutDirection;
+
+    private Optional<Long> mHomeButtonLongPressDurationMs;
+    private Optional<Long> mOverrideHomeButtonLongPressDurationMs = Optional.empty();
+    private Optional<Float> mOverrideHomeButtonLongPressSlopMultiplier = Optional.empty();
+    private boolean mHomeButtonLongPressHapticEnabled = true;
+
+    /** @see android.view.WindowInsetsController#setSystemBarsAppearance(int, int) */
+    private @Appearance int mAppearance;
+
+    /** @see android.view.WindowInsetsController#setSystemBarsBehavior(int) */
+    private @Behavior int mBehavior;
+
+    private boolean mTransientShown;
+    private boolean mTransientShownFromGestureOnSystemBar;
+    private int mNavBarMode = NAV_BAR_MODE_3BUTTON;
+    private LightBarController mLightBarController;
+    private final LightBarController mMainLightBarController;
+    private final LightBarController.Factory mLightBarControllerFactory;
+    private AutoHideController mAutoHideController;
+    private final AutoHideController mMainAutoHideController;
+    private final AutoHideController.Factory mAutoHideControllerFactory;
+    private final Optional<TelecomManager> mTelecomManagerOptional;
+    private final InputMethodManager mInputMethodManager;
+    private final TaskStackChangeListeners mTaskStackChangeListeners;
+
+    @VisibleForTesting
+    public int mDisplayId;
+    private boolean mIsOnDefaultDisplay;
+    private boolean mHomeBlockedThisTouch;
+
+    /**
+     * When user is QuickSwitching between apps of different orientations, we'll draw a fake
+     * home handle on the orientation they originally touched down to start their swipe
+     * gesture to indicate to them that they can continue in that orientation without having to
+     * rotate the phone
+     * The secondary handle will show when we get
+     * {@link OverviewProxyListener#notifyPrioritizedRotation(int)} callback with the
+     * original handle hidden and we'll flip the visibilities once the
+     * {@link #mTasksFrozenListener} fires
+     */
+    private QuickswitchOrientedNavHandle mOrientationHandle;
+    private WindowManager.LayoutParams mOrientationParams;
+    private int mStartingQuickSwitchRotation = -1;
+    private int mCurrentRotation;
+    private ViewTreeObserver.OnGlobalLayoutListener mOrientationHandleGlobalLayoutListener;
+    private boolean mShowOrientedHandleForImmersiveMode;
+    private final DeadZone mDeadZone;
+    private boolean mImeVisible;
+    private final Rect mSamplingBounds = new Rect();
+    private final Binder mInsetsSourceOwner = new Binder();
+    private final NavBarButtonClickLogger mNavBarButtonClickLogger;
+    private final NavbarOrientationTrackingLogger mNavbarOrientationTrackingLogger;
+
+    /**
+     * When quickswitching between apps of different orientations, we draw a secondary home handle
+     * in the position of the first app's orientation. This rect represents the region of that
+     * home handle so we can apply the correct light/dark luma on that.
+     * @see {@link NavigationBar#mOrientationHandle}
+     */
+    @android.annotation.Nullable
+    private Rect mOrientedHandleSamplingRegion;
+
+    @com.android.internal.annotations.VisibleForTesting
+    public enum NavBarActionEvent implements UiEventLogger.UiEventEnum {
+
+        @UiEvent(doc = "Assistant invoked via home button long press.")
+        NAVBAR_ASSIST_LONGPRESS(550);
+
+        private final int mId;
+
+        NavBarActionEvent(int id) {
+            mId = id;
+        }
+
+        @Override
+        public int getId() {
+            return mId;
+        }
+    }
+
+    private final AutoHideUiElement mAutoHideUiElement = new AutoHideUiElement() {
+        @Override
+        public void synchronizeState() {
+            checkNavBarModes();
+        }
+
+        @Override
+        public boolean shouldHideOnTouch() {
+            return !mNotificationRemoteInputManager.isRemoteInputActive();
+        }
+
+        @Override
+        public boolean isVisible() {
+            return isTransientShown();
+        }
+
+        @Override
+        public void hide() {
+            clearTransient();
+        }
+    };
+
+    private final NavBarHelper.NavbarTaskbarStateUpdater mNavbarTaskbarStateUpdater =
+            new NavBarHelper.NavbarTaskbarStateUpdater() {
+                @Override
+                public void updateAccessibilityServicesState() {
+                    updateAccessibilityStateFlags();
+                }
+
+                @Override
+                public void updateAssistantAvailable(boolean available,
+                        boolean longPressHomeEnabled) {
+                    // TODO(b/198002034): Content observers currently can still be called back after
+                    //  being unregistered, and in this case we can ignore the change if the nav bar
+                    //  has been destroyed already
+                    if (mView == null) {
+                        return;
+                    }
+                    mLongPressHomeEnabled = longPressHomeEnabled;
+                    updateAssistantEntrypoints(available, longPressHomeEnabled);
+                }
+
+                @Override
+                public void updateWallpaperVisibility(boolean visible, int displayId) {
+                    mNavigationBarTransitions.setWallpaperVisibility(visible);
+                }
+
+                @Override
+                public void updateRotationWatcherState(
+                        int rotation, @Nullable Boolean isRotationLocked) {
+                    if (mIsOnDefaultDisplay && mView != null) {
+                        RotationButtonController controller = mView.getRotationButtonController();
+                        controller.onRotationWatcherChanged(rotation, isRotationLocked);
+                        if (mView.needsReorient(rotation)) {
+                            repositionNavigationBar(rotation);
+                        }
+                    }
+                }
+            };
+
+    private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() {
+        @Override
+        public void onConnectionChanged(boolean isConnected) {
+            mView.onOverviewProxyConnectionChange(
+                    mOverviewProxyService.isEnabled());
+            mView.setShouldShowSwipeUpUi(mOverviewProxyService.shouldShowSwipeUpUI());
+            updateScreenPinningGestures();
+        }
+
+        @Override
+        public void onPrioritizedRotation(@Surface.Rotation int rotation) {
+            mStartingQuickSwitchRotation = rotation;
+            if (rotation == -1) {
+                mShowOrientedHandleForImmersiveMode = false;
+            }
+            orientSecondaryHomeHandle();
+        }
+
+        @Override
+        public void startAssistant(Bundle bundle) {
+            mAssistManagerLazy.get().startAssist(bundle);
+        }
+
+        @Override
+        public void setAssistantOverridesRequested(int[] invocationTypes) {
+            mAssistManagerLazy.get().setAssistantOverridesRequested(invocationTypes);
+        }
+
+        @Override
+        public void animateNavBarLongPress(boolean isTouchDown, boolean shrink, long durationMs) {
+            mView.getHomeHandle().animateLongPress(isTouchDown, shrink, durationMs);
+        }
+
+        @Override
+        public void setOverrideHomeButtonLongPress(long duration, float slopMultiplier,
+                boolean haptic) {
+            Log.d(TAG, "setOverrideHomeButtonLongPress receives: " + duration + ";"
+                    + slopMultiplier + ";" + haptic);
+            mOverrideHomeButtonLongPressDurationMs = Optional.of(duration)
+                    .filter(value -> value > 0);
+            mOverrideHomeButtonLongPressSlopMultiplier = Optional.of(slopMultiplier)
+                    .filter(value -> value > 0);
+            mHomeButtonLongPressHapticEnabled = haptic;
+            mOverrideHomeButtonLongPressDurationMs.ifPresent(aLong
+                    -> Log.d(TAG, "Use duration override: " + aLong));
+            mOverrideHomeButtonLongPressSlopMultiplier.ifPresent(aFloat
+                    -> Log.d(TAG, "Use slop multiplier override: " + aFloat));
+            if (mView != null) {
+                reconfigureHomeLongClick();
+            }
+        }
+
+        @Override
+        public void onHomeRotationEnabled(boolean enabled) {
+            mView.getRotationButtonController().setHomeRotationEnabled(enabled);
+        }
+
+        @Override
+        public void onOverviewShown(boolean fromHome) {
+            // If the overview has fixed orientation that may change display to natural rotation,
+            // we don't want the user rotation to be reset. So after user returns to application,
+            // it can keep in the original rotation.
+            mView.getRotationButtonController().setSkipOverrideUserLockPrefsOnce();
+        }
+
+        @Override
+        public void onTaskbarStatusUpdated(boolean visible, boolean stashed) {
+            mView.getFloatingRotationButton().onTaskbarStateChanged(visible, stashed);
+        }
+
+        @Override
+        public void onToggleRecentApps() {
+            // The same case as onOverviewShown but only for 3-button navigation.
+            mView.getRotationButtonController().setSkipOverrideUserLockPrefsOnce();
+        }
+    };
+
+    private NavigationBarTransitions.DarkIntensityListener mOrientationHandleIntensityListener =
+            new NavigationBarTransitions.DarkIntensityListener() {
+                @Override
+                public void onDarkIntensity(float darkIntensity) {
+                    mOrientationHandle.setDarkIntensity(darkIntensity);
+                }
+            };
+
+    private final Runnable mAutoDim = () -> getBarTransitions().setAutoDim(true);
+    private final Runnable mEnableLayoutTransitions = () -> mView.setLayoutTransitionsEnabled(true);
+    private final Runnable mOnVariableDurationHomeLongClick = () -> {
+        if (onHomeLongClick(mView.getHomeButton().getCurrentView())) {
+            if (mHomeButtonLongPressHapticEnabled) {
+                mView.getHomeButton().getCurrentView().performHapticFeedback(
+                        HapticFeedbackConstants.LONG_PRESS,
+                        HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
+            }
+        }
+    };
+
+    private final DeviceConfig.OnPropertiesChangedListener mOnPropertiesChangedListener =
+            new DeviceConfig.OnPropertiesChangedListener() {
+                @Override
+                public void onPropertiesChanged(DeviceConfig.Properties properties) {
+                    if (properties.getKeyset().contains(HOME_BUTTON_LONG_PRESS_DURATION_MS)) {
+                        mHomeButtonLongPressDurationMs = Optional.of(
+                            properties.getLong(HOME_BUTTON_LONG_PRESS_DURATION_MS, 0))
+                                .filter(duration -> duration != 0);
+                        if (mView != null) {
+                            reconfigureHomeLongClick();
+                        }
+                    }
+                }
+            };
+
+    private final NotificationShadeDepthController.DepthListener mDepthListener =
+            new NotificationShadeDepthController.DepthListener() {
+                boolean mHasBlurs;
+
+                @Override
+                public void onWallpaperZoomOutChanged(float zoomOut) {
+                }
+
+                @Override
+                public void onBlurRadiusChanged(int radius) {
+                    boolean hasBlurs = radius != 0;
+                    if (hasBlurs == mHasBlurs) {
+                        return;
+                    }
+                    mHasBlurs = hasBlurs;
+                    mRegionSamplingHelper.setWindowHasBlurs(hasBlurs);
+                }
+            };
+
+    private final WakefulnessLifecycle.Observer mWakefulnessObserver =
+            new WakefulnessLifecycle.Observer() {
+                private void notifyScreenStateChanged(boolean isScreenOn) {
+                    notifyNavigationBarScreenOn();
+                    mView.onScreenStateChanged(isScreenOn);
+                }
+
+                @Override
+                public void onStartedWakingUp() {
+                    notifyScreenStateChanged(true);
+                    if (isGesturalModeOnDefaultDisplay(getContext(), mDisplayTracker,
+                            mNavBarMode)) {
+                        mRegionSamplingHelper.start(mSamplingBounds);
+                    }
+                }
+
+                @Override
+                public void onFinishedGoingToSleep() {
+                    notifyScreenStateChanged(false);
+                    mRegionSamplingHelper.stop();
+                }
+            };
+
+    private boolean mScreenPinningActive = false;
+    private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
+        @Override
+        public void onLockTaskModeChanged(int mode) {
+            mScreenPinningActive = (mode == LOCK_TASK_MODE_PINNED);
+            mSysUiFlagsContainer.setFlag(SYSUI_STATE_SCREEN_PINNING, mScreenPinningActive)
+                    .commitUpdate(mDisplayId);
+            mView.setInScreenPinning(mScreenPinningActive);
+            updateScreenPinningGestures();
+        }
+    };
+
+    @Inject
+    NavigationBar(
+            NavigationBarView navigationBarView,
+            NavigationBarFrame navigationBarFrame,
+            @Nullable Bundle savedState,
+            @DisplayId Context context,
+            @DisplayId WindowManager windowManager,
+            Lazy<AssistManager> assistManagerLazy,
+            AccessibilityManager accessibilityManager,
+            DeviceProvisionedController deviceProvisionedController,
+            MetricsLogger metricsLogger,
+            OverviewProxyService overviewProxyService,
+            NavigationModeController navigationModeController,
+            StatusBarStateController statusBarStateController,
+            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
+            SysUiState sysUiFlagsContainer,
+            UserTracker userTracker,
+            CommandQueue commandQueue,
+            Optional<Pip> pipOptional,
+            Optional<Recents> recentsOptional,
+            Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
+            KeyguardStateController keyguardStateController,
+            ShadeViewController shadeViewController,
+            PanelExpansionInteractor panelExpansionInteractor,
+            NotificationRemoteInputManager notificationRemoteInputManager,
+            NotificationShadeDepthController notificationShadeDepthController,
+            @Main Handler mainHandler,
+            @Main Executor mainExecutor,
+            @Background Executor bgExecutor,
+            UiEventLogger uiEventLogger,
+            NavBarHelper navBarHelper,
+            LightBarController mainLightBarController,
+            LightBarController.Factory lightBarControllerFactory,
+            AutoHideController mainAutoHideController,
+            AutoHideController.Factory autoHideControllerFactory,
+            Optional<TelecomManager> telecomManagerOptional,
+            InputMethodManager inputMethodManager,
+            DeadZone deadZone,
+            DeviceConfigProxy deviceConfigProxy,
+            NavigationBarTransitions navigationBarTransitions,
+            Optional<BackAnimation> backAnimation,
+            UserContextProvider userContextProvider,
+            WakefulnessLifecycle wakefulnessLifecycle,
+            TaskStackChangeListeners taskStackChangeListeners,
+            DisplayTracker displayTracker,
+            NavBarButtonClickLogger navBarButtonClickLogger,
+            NavbarOrientationTrackingLogger navbarOrientationTrackingLogger) {
+        super(navigationBarView);
+        mFrame = navigationBarFrame;
+        mContext = context;
+        mSavedState = savedState;
+        mWindowManager = windowManager;
+        mAccessibilityManager = accessibilityManager;
+        mDeviceProvisionedController = deviceProvisionedController;
+        mStatusBarStateController = statusBarStateController;
+        mMetricsLogger = metricsLogger;
+        mAssistManagerLazy = assistManagerLazy;
+        mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
+        mSysUiFlagsContainer = sysUiFlagsContainer;
+        mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
+        mKeyguardStateController = keyguardStateController;
+        mShadeViewController = shadeViewController;
+        mPanelExpansionInteractor = panelExpansionInteractor;
+        mNotificationRemoteInputManager = notificationRemoteInputManager;
+        mOverviewProxyService = overviewProxyService;
+        mNavigationModeController = navigationModeController;
+        mUserTracker = userTracker;
+        mCommandQueue = commandQueue;
+        mPipOptional = pipOptional;
+        mRecentsOptional = recentsOptional;
+        mDeadZone = deadZone;
+        mDeviceConfigProxy = deviceConfigProxy;
+        mNavigationBarTransitions = navigationBarTransitions;
+        mBackAnimation = backAnimation;
+        mHandler = mainHandler;
+        mUiEventLogger = uiEventLogger;
+        mNavBarHelper = navBarHelper;
+        mNotificationShadeDepthController = notificationShadeDepthController;
+        mMainLightBarController = mainLightBarController;
+        mLightBarControllerFactory = lightBarControllerFactory;
+        mMainAutoHideController = mainAutoHideController;
+        mAutoHideControllerFactory = autoHideControllerFactory;
+        mTelecomManagerOptional = telecomManagerOptional;
+        mInputMethodManager = inputMethodManager;
+        mUserContextProvider = userContextProvider;
+        mWakefulnessLifecycle = wakefulnessLifecycle;
+        mTaskStackChangeListeners = taskStackChangeListeners;
+        mDisplayTracker = displayTracker;
+        mEdgeBackGestureHandler = navBarHelper.getEdgeBackGestureHandler();
+        mNavBarButtonClickLogger = navBarButtonClickLogger;
+        mNavbarOrientationTrackingLogger = navbarOrientationTrackingLogger;
+
+        mNavColorSampleMargin = getResources()
+                .getDimensionPixelSize(R.dimen.navigation_handle_sample_horizontal_margin);
+
+        mOnComputeInternalInsetsListener = info -> {
+            // When the nav bar is in 2-button or 3-button mode, or when IME is visible in fully
+            // gestural mode, the entire nav bar should be touchable.
+            if (!mEdgeBackGestureHandler.isHandlingGestures()) {
+                // We're in 2/3 button mode OR back button force-shown in SUW
+                if (!mImeVisible) {
+                    // IME not showing, take all touches
+                    info.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
+                    return;
+                }
+                if (!mView.isImeRenderingNavButtons()) {
+                    // IME showing but not drawing any buttons, take all touches
+                    info.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
+                    return;
+                }
+            }
+
+            // When in gestural and the IME is showing, don't use the nearest region since it will
+            // take gesture space away from the IME
+            info.setTouchableInsets(InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+            info.touchableRegion.set(
+                    getButtonLocations(false /* inScreen */, false /* useNearestRegion */));
+        };
+
+        mRegionSamplingHelper = new RegionSamplingHelper(mView,
+                new RegionSamplingHelper.SamplingCallback() {
+                    @Override
+                    public void onRegionDarknessChanged(boolean isRegionDark) {
+                        getBarTransitions().getLightTransitionsController().setIconsDark(
+                                !isRegionDark, true /* animate */);
+                    }
+
+                    @Override
+                    public Rect getSampledRegion(View sampledView) {
+                        if (mOrientedHandleSamplingRegion != null) {
+                            return mOrientedHandleSamplingRegion;
+                        }
+
+                        return calculateSamplingRect();
+                    }
+
+                    @Override
+                    public boolean isSamplingEnabled() {
+                        return isGesturalModeOnDefaultDisplay(getContext(), mDisplayTracker,
+                                mNavBarMode);
+                    }
+                }, mainExecutor, bgExecutor);
+
+        mView.setBackgroundExecutor(bgExecutor);
+        mView.setEdgeBackGestureHandler(mEdgeBackGestureHandler);
+        mView.setDisplayTracker(mDisplayTracker);
+        mNavBarMode = mNavigationModeController.addListener(mModeChangedListener);
+    }
+
+    public NavigationBarView getView() {
+        return mView;
+    }
+
+    @Override
+    public void onInit() {
+        // TODO: A great deal of this code should probably live in onViewAttached.
+        // It should also has corresponding cleanup in onViewDetached.
+        mView.setBarTransitions(mNavigationBarTransitions);
+        mView.setTouchHandler(mTouchHandler);
+        setNavBarMode(mNavBarMode);
+        mEdgeBackGestureHandler.setStateChangeCallback(mView::updateStates);
+        mEdgeBackGestureHandler.setButtonForcedVisibleChangeCallback((forceVisible) -> {
+            repositionNavigationBar(mCurrentRotation);
+        });
+        mNavigationBarTransitions.addListener(this::onBarTransition);
+        mView.updateRotationButton();
+
+        mView.setVisibility(
+                mStatusBarKeyguardViewManager.isNavBarVisible() ? View.VISIBLE : View.INVISIBLE);
+
+        if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mView);
+
+        mWindowManager.addView(mFrame,
+                getBarLayoutParams(mContext.getResources().getConfiguration().windowConfiguration
+                        .getRotation()));
+        mDisplayId = mContext.getDisplayId();
+        mIsOnDefaultDisplay = mDisplayId == mDisplayTracker.getDefaultDisplayId();
+
+        // Ensure we try to get currentSysuiState from navBarHelper before command queue callbacks
+        // start firing, since the latter is source of truth
+        parseCurrentSysuiState();
+        mCommandQueue.addCallback(this);
+        mHomeButtonLongPressDurationMs = Optional.of(mDeviceConfigProxy.getLong(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                HOME_BUTTON_LONG_PRESS_DURATION_MS,
+                /* defaultValue = */ 0
+        )).filter(duration -> duration != 0);
+        // This currently MUST be called after mHomeButtonLongPressDurationMs is initialized since
+        // the registration callbacks will trigger code that uses it
+        mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
+        mDeviceConfigProxy.addOnPropertiesChangedListener(
+                DeviceConfig.NAMESPACE_SYSTEMUI, mHandler::post, mOnPropertiesChangedListener);
+
+        if (mSavedState != null) {
+            mDisabledFlags1 = mSavedState.getInt(EXTRA_DISABLE_STATE, 0);
+            mDisabledFlags2 = mSavedState.getInt(EXTRA_DISABLE2_STATE, 0);
+            mAppearance = mSavedState.getInt(EXTRA_APPEARANCE, 0);
+            mBehavior = mSavedState.getInt(EXTRA_BEHAVIOR, 0);
+            mTransientShown = mSavedState.getBoolean(EXTRA_TRANSIENT_STATE, false);
+        }
+
+        // Respect the latest disabled-flags.
+        mCommandQueue.recomputeDisableFlags(mDisplayId, false);
+
+        mNotificationShadeDepthController.addListener(mDepthListener);
+        mTaskStackChangeListeners.registerTaskStackListener(mTaskStackListener);
+    }
+
+    public void destroyView() {
+        Trace.beginSection("NavigationBar#destroyView");
+        try {
+            setAutoHideController(/* autoHideController */ null);
+            mCommandQueue.removeCallback(this);
+            Trace.beginSection("NavigationBar#removeViewImmediate");
+            try {
+                mWindowManager.removeViewImmediate(mView.getRootView());
+            } finally {
+                Trace.endSection();
+            }
+            mNavigationModeController.removeListener(mModeChangedListener);
+            mEdgeBackGestureHandler.setStateChangeCallback(null);
+
+            mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
+            mNotificationShadeDepthController.removeListener(mDepthListener);
+
+            mDeviceConfigProxy.removeOnPropertiesChangedListener(mOnPropertiesChangedListener);
+            mTaskStackChangeListeners.unregisterTaskStackListener(mTaskStackListener);
+        } finally {
+            Trace.endSection();
+        }
+    }
+
+    @Override
+    public void onViewAttached() {
+        final Display display = mView.getDisplay();
+        mView.setComponents(mRecentsOptional);
+        if (mCentralSurfacesOptionalLazy.get().isPresent()) {
+            mView.setComponents(mShadeViewController, mPanelExpansionInteractor);
+        }
+        mView.setDisabledFlags(mDisabledFlags1, mSysUiFlagsContainer);
+        mView.setOnVerticalChangedListener(this::onVerticalChanged);
+        mView.setOnTouchListener(this::onNavigationTouch);
+        if (mSavedState != null) {
+            getBarTransitions().getLightTransitionsController().restoreState(mSavedState);
+        }
+        setNavigationIconHints(mNavigationIconHints);
+        setWindowVisible(isNavBarWindowVisible());
+        mView.setBehavior(mBehavior);
+        setNavBarMode(mNavBarMode);
+        repositionNavigationBar(mCurrentRotation);
+        mView.setUpdateActiveTouchRegionsCallback(
+                () -> mOverviewProxyService.onActiveNavBarRegionChanges(
+                        getButtonLocations(true /* inScreen */, true /* useNearestRegion */)));
+
+        mView.getViewTreeObserver().addOnComputeInternalInsetsListener(
+                mOnComputeInternalInsetsListener);
+
+        mPipOptional.ifPresent(mView::addPipExclusionBoundsChangeListener);
+        mBackAnimation.ifPresent(mView::registerBackAnimation);
+
+        prepareNavigationBarView();
+        checkNavBarModes();
+
+        mUserTracker.addCallback(mUserChangedCallback, mContext.getMainExecutor());
+        mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
+        notifyNavigationBarScreenOn();
+
+        mOverviewProxyService.addCallback(mOverviewProxyListener);
+        updateSystemUiStateFlags();
+
+        // Currently there is no accelerometer sensor on non-default display.
+        if (mIsOnDefaultDisplay) {
+            final RotationButtonController rotationButtonController =
+                    mView.getRotationButtonController();
+
+            // Reset user rotation pref to match that of the WindowManager if starting in locked
+            // mode. This will automatically happen when switching from auto-rotate to locked mode.
+            @Nullable Boolean isRotationLocked = RotationPolicyUtil.isRotationLocked(mContext);
+            if (display != null && isRotationLocked) {
+                rotationButtonController.setRotationLockedAtAngle(isRotationLocked,
+                        display.getRotation(), /* caller= */ "NavigationBar#onViewAttached");
+            }
+        } else {
+            mDisabledFlags2 |= StatusBarManager.DISABLE2_ROTATE_SUGGESTIONS;
+        }
+        setDisabled2Flags(mDisabledFlags2);
+
+        initSecondaryHomeHandleForRotation();
+
+        // Unfortunately, we still need it because status bar needs LightBarController
+        // before notifications creation. We cannot directly use getLightBarController()
+        // from NavigationBarFragment directly.
+        LightBarController lightBarController = mIsOnDefaultDisplay
+                ? mMainLightBarController : mLightBarControllerFactory.create(mContext);
+        setLightBarController(lightBarController);
+
+        // TODO(b/118592525): to support multi-display, we start to add something which is
+        //                    per-display, while others may be global. I think it's time to
+        //                    add a new class maybe named DisplayDependency to solve
+        //                    per-display Dependency problem.
+        // Alternative: this is a good case for a Dagger subcomponent. Same with LightBarController.
+        AutoHideController autoHideController = mIsOnDefaultDisplay
+                ? mMainAutoHideController : mAutoHideControllerFactory.create(mContext);
+        setAutoHideController(autoHideController);
+        restoreAppearanceAndTransientState();
+    }
+
+    @Override
+    public void onViewDetached() {
+        mView.setUpdateActiveTouchRegionsCallback(null);
+        getBarTransitions().destroy();
+        mOverviewProxyService.removeCallback(mOverviewProxyListener);
+        mUserTracker.removeCallback(mUserChangedCallback);
+        mWakefulnessLifecycle.removeObserver(mWakefulnessObserver);
+        if (mOrientationHandle != null) {
+            resetSecondaryHandle();
+            getBarTransitions().removeDarkIntensityListener(mOrientationHandleIntensityListener);
+            mWindowManager.removeView(mOrientationHandle);
+            mOrientationHandle.getViewTreeObserver().removeOnGlobalLayoutListener(
+                    mOrientationHandleGlobalLayoutListener);
+        }
+        mView.getViewTreeObserver().removeOnComputeInternalInsetsListener(
+                mOnComputeInternalInsetsListener);
+        mHandler.removeCallbacks(mAutoDim);
+        mHandler.removeCallbacks(mOnVariableDurationHomeLongClick);
+        mHandler.removeCallbacks(mEnableLayoutTransitions);
+        mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
+        mPipOptional.ifPresent(mView::removePipExclusionBoundsChangeListener);
+        mFrame = null;
+        mOrientationHandle = null;
+    }
+
+    // TODO: Remove this when we update nav bar recreation
+    public void onSaveInstanceState(Bundle outState) {
+        outState.putInt(EXTRA_DISABLE_STATE, mDisabledFlags1);
+        outState.putInt(EXTRA_DISABLE2_STATE, mDisabledFlags2);
+        outState.putInt(EXTRA_APPEARANCE, mAppearance);
+        outState.putInt(EXTRA_BEHAVIOR, mBehavior);
+        outState.putBoolean(EXTRA_TRANSIENT_STATE, mTransientShown);
+        getBarTransitions().getLightTransitionsController().saveState(outState);
+    }
+
+    /**
+     * Called when a non-reloading configuration change happens and we need to update.
+     */
+    public void onConfigurationChanged(Configuration newConfig) {
+        final int rotation = newConfig.windowConfiguration.getRotation();
+        final Locale locale = mContext.getResources().getConfiguration().locale;
+        final int ld = TextUtils.getLayoutDirectionFromLocale(locale);
+        if (!locale.equals(mLocale) || ld != mLayoutDirection) {
+            if (DEBUG) {
+                Log.v(TAG, String.format(
+                        "config changed locale/LD: %s (%d) -> %s (%d)", mLocale, mLayoutDirection,
+                        locale, ld));
+            }
+            mLocale = locale;
+            mLayoutDirection = ld;
+            refreshLayout(ld);
+        }
+        repositionNavigationBar(rotation);
+        if (canShowSecondaryHandle()) {
+            if (rotation != mCurrentRotation) {
+                mCurrentRotation = rotation;
+                orientSecondaryHomeHandle();
+            }
+        }
+    }
+
+    private void initSecondaryHomeHandleForRotation() {
+        if (mNavBarMode != NAV_BAR_MODE_GESTURAL) {
+            return;
+        }
+
+        mOrientationHandle = new QuickswitchOrientedNavHandle(mContext);
+        mOrientationHandle.setId(R.id.secondary_home_handle);
+
+        getBarTransitions().addDarkIntensityListener(mOrientationHandleIntensityListener);
+        mOrientationParams = new WindowManager.LayoutParams(0, 0,
+                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
+                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                        | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                        | WindowManager.LayoutParams.FLAG_SLIPPERY,
+                PixelFormat.TRANSLUCENT);
+        mOrientationParams.setTitle("SecondaryHomeHandle" + mContext.getDisplayId());
+        mOrientationParams.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION
+                | WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
+        mWindowManager.addView(mOrientationHandle, mOrientationParams);
+        mOrientationHandle.setVisibility(View.GONE);
+
+        logNavbarOrientation("initSecondaryHomeHandleForRotation");
+        mOrientationParams.setFitInsetsTypes(0 /* types*/);
+        mOrientationHandleGlobalLayoutListener =
+                () -> {
+                    if (mStartingQuickSwitchRotation == -1) {
+                        return;
+                    }
+
+                    RectF boundsOnScreen = mOrientationHandle.computeHomeHandleBounds();
+                    mOrientationHandle.mapRectFromViewToScreenCoords(boundsOnScreen, true);
+                    Rect boundsRounded = new Rect();
+                    boundsOnScreen.roundOut(boundsRounded);
+                    setOrientedHandleSamplingRegion(boundsRounded);
+                };
+        mOrientationHandle.getViewTreeObserver().addOnGlobalLayoutListener(
+                mOrientationHandleGlobalLayoutListener);
+    }
+
+    private void orientSecondaryHomeHandle() {
+        if (!canShowSecondaryHandle()) {
+            return;
+        }
+
+        if (mStartingQuickSwitchRotation == -1) {
+            resetSecondaryHandle();
+        } else {
+            int deltaRotation = deltaRotation(mCurrentRotation, mStartingQuickSwitchRotation);
+            if (mStartingQuickSwitchRotation == -1 || deltaRotation == -1) {
+                // Curious if starting quickswitch can change between the if check and our delta
+                Log.d(TAG, "secondary nav delta rotation: " + deltaRotation
+                        + " current: " + mCurrentRotation
+                        + " starting: " + mStartingQuickSwitchRotation);
+            }
+            int height = 0;
+            int width = 0;
+            Rect dispSize = mWindowManager.getCurrentWindowMetrics().getBounds();
+            mOrientationHandle.setDeltaRotation(deltaRotation);
+            switch (deltaRotation) {
+                case Surface.ROTATION_90:
+                case Surface.ROTATION_270:
+                    height = dispSize.height();
+                    width = mView.getHeight();
+                    break;
+                case Surface.ROTATION_180:
+                case Surface.ROTATION_0:
+                    // TODO(b/152683657): Need to determine best UX for this
+                    if (!mShowOrientedHandleForImmersiveMode) {
+                        resetSecondaryHandle();
+                        return;
+                    }
+                    width = dispSize.width();
+                    height = mView.getHeight();
+                    break;
+            }
+
+            mOrientationParams.gravity =
+                    deltaRotation == Surface.ROTATION_0 ? Gravity.BOTTOM :
+                            (deltaRotation == Surface.ROTATION_90 ? Gravity.LEFT : Gravity.RIGHT);
+            mOrientationParams.height = height;
+            mOrientationParams.width = width;
+            mWindowManager.updateViewLayout(mOrientationHandle, mOrientationParams);
+            mView.setVisibility(View.GONE);
+            mOrientationHandle.setVisibility(View.VISIBLE);
+            logNavbarOrientation("orientSecondaryHomeHandle");
+        }
+    }
+
+    private void resetSecondaryHandle() {
+        if (mOrientationHandle != null) {
+            // Case where nav mode is changed w/o ever invoking a quickstep
+            // mOrientedHandle is initialized lazily
+            mOrientationHandle.setVisibility(View.GONE);
+        }
+        mView.setVisibility(View.VISIBLE);
+        logNavbarOrientation("resetSecondaryHandle");
+        setOrientedHandleSamplingRegion(null);
+    }
+
+    /**
+     * Logging method for issues concerning Navbar/secondary handle visibility.
+     */
+    private void logNavbarOrientation(String methodName) {
+        boolean isViewVisible = (mView != null) && (mView.getVisibility() == View.VISIBLE);
+        boolean isSecondaryHandleVisible =
+                (mOrientationHandle != null) && (mOrientationHandle.getVisibility()
+                        == View.VISIBLE);
+        mNavbarOrientationTrackingLogger.logPrimaryAndSecondaryVisibility(methodName, isViewVisible,
+                mShowOrientedHandleForImmersiveMode, isSecondaryHandleVisible, mCurrentRotation,
+                mStartingQuickSwitchRotation);
+    }
+
+    private void parseCurrentSysuiState() {
+        NavBarHelper.CurrentSysuiState state = mNavBarHelper.getCurrentSysuiState();
+        if (state.mWindowStateDisplayId == mDisplayId) {
+            mNavigationBarWindowState = state.mWindowState;
+        }
+    }
+
+    private void reconfigureHomeLongClick() {
+        if (mView.getHomeButton().getCurrentView() == null) {
+            return;
+        }
+        if (mHomeButtonLongPressDurationMs.isPresent()
+                || mOverrideHomeButtonLongPressDurationMs.isPresent()
+                || mOverrideHomeButtonLongPressSlopMultiplier.isPresent()
+                || !mLongPressHomeEnabled) {
+            mView.getHomeButton().getCurrentView().setLongClickable(false);
+            mView.getHomeButton().getCurrentView().setHapticFeedbackEnabled(false);
+            mView.getHomeButton().setOnLongClickListener(null);
+        } else {
+            mView.getHomeButton().getCurrentView().setLongClickable(true);
+            mView.getHomeButton().getCurrentView().setHapticFeedbackEnabled(
+                    mHomeButtonLongPressHapticEnabled);
+            mView.getHomeButton().setOnLongClickListener(this::onHomeLongClick);
+        }
+    }
+
+    private int deltaRotation(int oldRotation, int newRotation) {
+        int delta = newRotation - oldRotation;
+        if (delta < 0) delta += 4;
+        return delta;
+    }
+
+    public void dump(PrintWriter pw) {
+        pw.println("NavigationBar (displayId=" + mDisplayId + "):");
+        pw.println("  mStartingQuickSwitchRotation=" + mStartingQuickSwitchRotation);
+        pw.println("  mCurrentRotation=" + mCurrentRotation);
+        pw.println("  mHomeButtonLongPressDurationMs=" + mHomeButtonLongPressDurationMs);
+        pw.println("  mOverrideHomeButtonLongPressDurationMs="
+                + mOverrideHomeButtonLongPressDurationMs);
+        pw.println("  mOverrideHomeButtonLongPressSlopMultiplier="
+                + mOverrideHomeButtonLongPressSlopMultiplier);
+        pw.println("  mLongPressHomeEnabled=" + mLongPressHomeEnabled);
+        pw.println("  mNavigationBarWindowState="
+                + windowStateToString(mNavigationBarWindowState));
+        pw.println("  mTransitionMode="
+                + BarTransitions.modeToString(mTransitionMode));
+        pw.println("  mTransientShown=" + mTransientShown);
+        pw.println("  mTransientShownFromGestureOnSystemBar="
+                + mTransientShownFromGestureOnSystemBar);
+        pw.println("  mScreenPinningActive=" + mScreenPinningActive);
+        dumpBarTransitions(pw, "mNavigationBarView", getBarTransitions());
+
+        pw.println("  mOrientedHandleSamplingRegion: " + mOrientedHandleSamplingRegion);
+        mView.dump(pw);
+        mRegionSamplingHelper.dump(pw);
+        if (mAutoHideController != null) {
+            mAutoHideController.dump(pw);
+        }
+    }
+
+    // ----- CommandQueue Callbacks -----
+
+    @Override
+    public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
+            boolean showImeSwitcher) {
+        if (displayId != mDisplayId) {
+            return;
+        }
+        boolean imeShown = mNavBarHelper.isImeShown(vis);
+        showImeSwitcher = imeShown && showImeSwitcher;
+        int hints = Utilities.calculateBackDispositionHints(mNavigationIconHints, backDisposition,
+                imeShown, showImeSwitcher);
+        if (hints == mNavigationIconHints) return;
+
+        setNavigationIconHints(hints);
+        checkBarModes();
+        updateSystemUiStateFlags();
+    }
+
+    @Override
+    public void setWindowState(
+            int displayId, @WindowType int window, @WindowVisibleState int state) {
+        if (displayId == mDisplayId
+                && window == StatusBarManager.WINDOW_NAVIGATION_BAR
+                && mNavigationBarWindowState != state) {
+            mNavigationBarWindowState = state;
+            updateSystemUiStateFlags();
+            mShowOrientedHandleForImmersiveMode = state == WINDOW_STATE_HIDDEN;
+            if (mOrientationHandle != null
+                    && mStartingQuickSwitchRotation != -1) {
+                orientSecondaryHomeHandle();
+            }
+            if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
+            setWindowVisible(isNavBarWindowVisible());
+        }
+    }
+
+    @Override
+    public void onRotationProposal(final int rotation, boolean isValid) {
+        // The CommandQueue callbacks are added when the view is created to ensure we track other
+        // states, but until the view is attached (at the next traversal), the view's display is
+        // not valid.  Just ignore the rotation in this case.
+        if (!mView.isAttachedToWindow()) return;
+
+        final boolean rotateSuggestionsDisabled = RotationButtonController
+                .hasDisable2RotateSuggestionFlag(mDisabledFlags2);
+        final RotationButtonController rotationButtonController =
+                mView.getRotationButtonController();
+        if (DEBUG_ROTATION) {
+            Log.v(TAG, "onRotationProposal proposedRotation=" + Surface.rotationToString(rotation)
+                    + ", isValid=" + isValid + ", mNavBarWindowState="
+                    + StatusBarManager.windowStateToString(mNavigationBarWindowState)
+                    + ", rotateSuggestionsDisabled=" + rotateSuggestionsDisabled
+                    + ", isRotateButtonVisible="
+                    + rotationButtonController.getRotationButton().isVisible());
+        }
+        // Respect the disabled flag, no need for action as flag change callback will handle hiding
+        if (rotateSuggestionsDisabled) return;
+
+        rotationButtonController.onRotationProposal(rotation, isValid);
+    }
+
+    @Override
+    public void onRecentsAnimationStateChanged(boolean running) {
+        mView.getRotationButtonController().setRecentsAnimationRunning(running);
+    }
+
+    /** Restores the appearance and the transient saved state to {@link NavigationBar}. */
+    public void restoreAppearanceAndTransientState() {
+        final int transitionMode = transitionMode(mTransientShown, mAppearance);
+        mTransitionMode = transitionMode;
+        checkNavBarModes();
+        if (mAutoHideController != null) {
+            mAutoHideController.touchAutoHide();
+        }
+        if (mLightBarController != null) {
+            mLightBarController.onNavigationBarAppearanceChanged(mAppearance,
+                    true /* nbModeChanged */, transitionMode, false /* navbarColorManagedByIme */);
+        }
+    }
+
+    @Override
+    public void onSystemBarAttributesChanged(int displayId, @Appearance int appearance,
+            AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme,
+            @Behavior int behavior, @InsetsType int requestedVisibleTypes, String packageName,
+            LetterboxDetails[] letterboxDetails) {
+        if (displayId != mDisplayId) {
+            return;
+        }
+        boolean nbModeChanged = false;
+        if (mAppearance != appearance) {
+            mAppearance = appearance;
+            nbModeChanged = updateTransitionMode(transitionMode(mTransientShown, appearance));
+        }
+        if (mLightBarController != null) {
+            mLightBarController.onNavigationBarAppearanceChanged(appearance, nbModeChanged,
+                    mTransitionMode, navbarColorManagedByIme);
+        }
+        if (mBehavior != behavior) {
+            mBehavior = behavior;
+            mView.setBehavior(behavior);
+            updateSystemUiStateFlags();
+        }
+    }
+
+    @Override
+    public void showTransient(int displayId, @InsetsType int types, boolean isGestureOnSystemBar) {
+        if (displayId != mDisplayId) {
+            return;
+        }
+        if ((types & WindowInsets.Type.navigationBars()) == 0) {
+            return;
+        }
+        if (!mTransientShown) {
+            mTransientShown = true;
+            mTransientShownFromGestureOnSystemBar = isGestureOnSystemBar;
+            handleTransientChanged();
+        }
+    }
+
+    @Override
+    public void abortTransient(int displayId, @InsetsType int types) {
+        if (displayId != mDisplayId) {
+            return;
+        }
+        if ((types & WindowInsets.Type.navigationBars()) == 0) {
+            return;
+        }
+        clearTransient();
+    }
+
+    private void clearTransient() {
+        if (mTransientShown) {
+            mTransientShown = false;
+            mTransientShownFromGestureOnSystemBar = false;
+            handleTransientChanged();
+        }
+    }
+
+    private void handleTransientChanged() {
+        mEdgeBackGestureHandler.onNavBarTransientStateChanged(mTransientShown);
+
+        final int transitionMode = transitionMode(mTransientShown, mAppearance);
+        if (updateTransitionMode(transitionMode) && mLightBarController != null) {
+            mLightBarController.onNavigationBarModeChanged(transitionMode);
+        }
+    }
+
+    // Returns true if the bar mode is changed.
+    private boolean updateTransitionMode(int barMode) {
+        if (mTransitionMode != barMode) {
+            mTransitionMode = barMode;
+            checkNavBarModes();
+            if (mAutoHideController != null) {
+                mAutoHideController.touchAutoHide();
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void disable(int displayId, int state1, int state2, boolean animate) {
+        if (displayId != mDisplayId) {
+            return;
+        }
+        // Navigation bar flags are in both state1 and state2.
+        final int masked = state1 & (StatusBarManager.DISABLE_HOME
+                | StatusBarManager.DISABLE_RECENT
+                | StatusBarManager.DISABLE_BACK
+                | StatusBarManager.DISABLE_SEARCH);
+        if (masked != mDisabledFlags1) {
+            mDisabledFlags1 = masked;
+            mView.setDisabledFlags(state1, mSysUiFlagsContainer);
+            updateScreenPinningGestures();
+        }
+
+        // Only default display supports rotation suggestions.
+        if (mIsOnDefaultDisplay) {
+            final int masked2 = state2 & (StatusBarManager.DISABLE2_ROTATE_SUGGESTIONS);
+            if (masked2 != mDisabledFlags2) {
+                mDisabledFlags2 = masked2;
+                setDisabled2Flags(masked2);
+            }
+        }
+    }
+
+    private void setDisabled2Flags(int state2) {
+        // Method only called on change of disable2 flags
+        mView.getRotationButtonController().onDisable2FlagChanged(state2);
+    }
+
+    // ----- Internal stuff -----
+
+    private void refreshLayout(int layoutDirection) {
+        mView.setLayoutDirection(layoutDirection);
+    }
+
+    private boolean shouldDisableNavbarGestures() {
+        return !mDeviceProvisionedController.isDeviceProvisioned()
+                || (mDisabledFlags1 & StatusBarManager.DISABLE_SEARCH) != 0;
+    }
+
+    private void repositionNavigationBar(int rotation) {
+        if (mView == null || !mView.isAttachedToWindow()) return;
+
+        prepareNavigationBarView();
+
+        mWindowManager.updateViewLayout(mFrame, getBarLayoutParams(rotation));
+    }
+
+    private void updateScreenPinningGestures() {
+        // Change the cancel pin gesture to home and back if recents button is invisible
+        ButtonDispatcher backButton = mView.getBackButton();
+        ButtonDispatcher recentsButton = mView.getRecentsButton();
+        if (mScreenPinningActive) {
+            boolean recentsVisible = mView.isRecentsButtonVisible();
+            backButton.setOnLongClickListener(recentsVisible
+                    ? this::onLongPressBackRecents
+                    : this::onLongPressBackHome);
+            recentsButton.setOnLongClickListener(this::onLongPressBackRecents);
+        } else {
+            backButton.setOnLongClickListener(null);
+            recentsButton.setOnLongClickListener(null);
+        }
+        // Note, this needs to be set after even if we're setting the listener to null
+        backButton.setLongClickable(mScreenPinningActive);
+        recentsButton.setLongClickable(mScreenPinningActive);
+    }
+
+    private void notifyNavigationBarScreenOn() {
+        mView.updateNavButtonIcons();
+    }
+
+    private void prepareNavigationBarView() {
+        mView.reorient();
+
+        ButtonDispatcher recentsButton = mView.getRecentsButton();
+        recentsButton.setOnClickListener(this::onRecentsClick);
+        recentsButton.setOnTouchListener(this::onRecentsTouch);
+
+        ButtonDispatcher homeButton = mView.getHomeButton();
+        homeButton.setOnTouchListener(this::onHomeTouch);
+        homeButton.setNavBarButtonClickLogger(mNavBarButtonClickLogger);
+
+        ButtonDispatcher backButton = mView.getBackButton();
+        backButton.setNavBarButtonClickLogger(mNavBarButtonClickLogger);
+
+        reconfigureHomeLongClick();
+
+        ButtonDispatcher accessibilityButton = mView.getAccessibilityButton();
+        accessibilityButton.setOnClickListener(this::onAccessibilityClick);
+        accessibilityButton.setOnLongClickListener(this::onAccessibilityLongClick);
+        updateAccessibilityStateFlags();
+
+        ButtonDispatcher imeSwitcherButton = mView.getImeSwitchButton();
+        imeSwitcherButton.setOnClickListener(this::onImeSwitcherClick);
+
+        updateScreenPinningGestures();
+    }
+
+    @VisibleForTesting
+    boolean onHomeTouch(View v, MotionEvent event) {
+        if (mHomeBlockedThisTouch && event.getActionMasked() != MotionEvent.ACTION_DOWN) {
+            return true;
+        }
+        // If an incoming call is ringing, HOME is totally disabled.
+        // (The user is already on the InCallUI at this point,
+        // and their ONLY options are to answer or reject the call.)
+        final Optional<CentralSurfaces> centralSurfacesOptional = mCentralSurfacesOptionalLazy.get();
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                if (mCurrentDownEvent != null) {
+                    mCurrentDownEvent.recycle();
+                }
+                mCurrentDownEvent = MotionEvent.obtain(event);
+                mHomeBlockedThisTouch = false;
+                if (mTelecomManagerOptional.isPresent()
+                        && mTelecomManagerOptional.get().isRinging()) {
+                    if (mKeyguardStateController.isShowing()) {
+                        Log.i(TAG, "Ignoring HOME; there's a ringing incoming call. " +
+                                "No heads up");
+                        mHomeBlockedThisTouch = true;
+                        return true;
+                    }
+                }
+                if (mLongPressHomeEnabled) {
+                    if (mOverrideHomeButtonLongPressDurationMs.isPresent()) {
+                        Log.d(TAG, "ACTION_DOWN Launcher override duration: "
+                                + mOverrideHomeButtonLongPressDurationMs.get());
+                        mHandler.postDelayed(mOnVariableDurationHomeLongClick,
+                                mOverrideHomeButtonLongPressDurationMs.get());
+                    } else if (mOverrideHomeButtonLongPressSlopMultiplier.isPresent()) {
+                        // If override timeout doesn't exist but override touch slop exists, we use
+                        // system default long press duration
+                        Log.d(TAG, "ACTION_DOWN default duration: "
+                                + ViewConfiguration.getLongPressTimeout());
+                        mHandler.postDelayed(mOnVariableDurationHomeLongClick,
+                                ViewConfiguration.getLongPressTimeout());
+                    } else {
+                        mHomeButtonLongPressDurationMs.ifPresent(longPressDuration -> {
+                            Log.d(TAG, "ACTION_DOWN original duration: " + longPressDuration);
+                            mHandler.postDelayed(mOnVariableDurationHomeLongClick,
+                                    longPressDuration);
+                        });
+                    }
+                }
+                break;
+            case MotionEvent.ACTION_MOVE:
+                if (!mHandler.hasCallbacks(mOnVariableDurationHomeLongClick)) {
+                    Log.v(TAG, "ACTION_MOVE no callback. Don't handle touch slop.");
+                    break;
+                }
+                Log.v(TAG, "ACTION_MOVE handle touch slop");
+                float customSlopMultiplier = mOverrideHomeButtonLongPressSlopMultiplier.orElse(1f);
+                float touchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
+                float calculatedTouchSlop =
+                        customSlopMultiplier * QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON * touchSlop;
+                float touchSlopSquared = calculatedTouchSlop * calculatedTouchSlop;
+
+                float dx = event.getX() - mCurrentDownEvent.getX();
+                float dy = event.getY() - mCurrentDownEvent.getY();
+                double distanceSquared = (dx * dx) + (dy * dy);
+                if (distanceSquared > touchSlopSquared) {
+                    Log.i(TAG, "Touch slop passed. Abort.");
+                    mView.abortCurrentGesture();
+                    mHandler.removeCallbacks(mOnVariableDurationHomeLongClick);
+                }
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                mHandler.removeCallbacks(mOnVariableDurationHomeLongClick);
+                centralSurfacesOptional.ifPresent(CentralSurfaces::awakenDreams);
+                break;
+        }
+        return false;
+    }
+
+    private void onVerticalChanged(boolean isVertical) {
+        // This check can probably be safely removed. It only remained to reduce regression
+        // risk for a broad change that removed the CentralSurfaces reference in the if block
+        if (mCentralSurfacesOptionalLazy.get().isPresent()) {
+            mShadeViewController.setQsScrimEnabled(!isVertical);
+        }
+    }
+
+    private boolean onNavigationTouch(View v, MotionEvent event) {
+        if (mAutoHideController != null) {
+            mAutoHideController.checkUserAutoHide(event);
+        }
+        return false;
+    }
+
+    @VisibleForTesting
+    boolean onHomeLongClick(View v) {
+        if (!mView.isRecentsButtonVisible() && mScreenPinningActive) {
+            return onLongPressBackHome(v);
+        }
+        if (shouldDisableNavbarGestures()) {
+            return false;
+        }
+        mMetricsLogger.action(MetricsEvent.ACTION_ASSIST_LONG_PRESS);
+        mUiEventLogger.log(NavBarActionEvent.NAVBAR_ASSIST_LONGPRESS);
+        Bundle args = new Bundle();
+        args.putInt(
+                AssistManager.INVOCATION_TYPE_KEY,
+                AssistManager.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS);
+        // If Launcher has requested to override long press home, add a delay for the ripple.
+        // TODO(b/304146255): Remove this delay once we can exclude 3-button nav from screenshot.
+        boolean delayAssistInvocation = mAssistManagerLazy.get().shouldOverrideAssist(
+                AssistManager.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS);
+        // In practice, I think v should always be a KeyButtonView, but just being safe.
+        if (delayAssistInvocation && v instanceof KeyButtonView) {
+            ((KeyButtonView) v).setOnRippleInvisibleRunnable(
+                    () -> mAssistManagerLazy.get().startAssist(args));
+        } else {
+            mAssistManagerLazy.get().startAssist(args);
+        }
+        mCentralSurfacesOptionalLazy.get().ifPresent(CentralSurfaces::awakenDreams);
+        mView.abortCurrentGesture();
+        return true;
+    }
+
+    // additional optimization when we have software system buttons - start loading the recent
+    // tasks on touch down
+    private boolean onRecentsTouch(View v, MotionEvent event) {
+        int action = event.getAction() & MotionEvent.ACTION_MASK;
+        if (action == MotionEvent.ACTION_DOWN) {
+            mCommandQueue.preloadRecentApps();
+        } else if (action == MotionEvent.ACTION_CANCEL) {
+            mCommandQueue.cancelPreloadRecentApps();
+        } else if (action == MotionEvent.ACTION_UP) {
+            if (!v.isPressed()) {
+                mCommandQueue.cancelPreloadRecentApps();
+            }
+        }
+        return false;
+    }
+
+    private void onRecentsClick(View v) {
+        mNavBarButtonClickLogger.logRecentsButtonClick();
+
+        if (LatencyTracker.isEnabled(mContext)) {
+            LatencyTracker.getInstance(mContext).onActionStart(
+                    LatencyTracker.ACTION_TOGGLE_RECENTS);
+        }
+        mCentralSurfacesOptionalLazy.get().ifPresent(CentralSurfaces::awakenDreams);
+        mCommandQueue.toggleRecentApps();
+    }
+
+    private void onImeSwitcherClick(View v) {
+        mNavBarButtonClickLogger.logImeSwitcherClick();
+        mInputMethodManager.showInputMethodPickerFromSystem(
+                true /* showAuxiliarySubtypes */, mDisplayId);
+        mUiEventLogger.log(KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_TAP);
+    };
+
+    private boolean onLongPressBackHome(View v) {
+        return onLongPressNavigationButtons(v, R.id.back, R.id.home);
+    }
+
+    private boolean onLongPressBackRecents(View v) {
+        return onLongPressNavigationButtons(v, R.id.back, R.id.recent_apps);
+    }
+
+    /**
+     * This handles long-press of both back and recents/home. Back is the common button with
+     * combination of recents if it is visible or home if recents is invisible.
+     * They are handled together to capture them both being long-pressed
+     * at the same time to exit screen pinning (lock task).
+     *
+     * When accessibility mode is on, only a long-press from recents/home
+     * is required to exit.
+     *
+     * In all other circumstances we try to pass through long-press events
+     * for Back, so that apps can still use it.  Which can be from two things.
+     * 1) Not currently in screen pinning (lock task).
+     * 2) Back is long-pressed without recents/home.
+     */
+    private boolean onLongPressNavigationButtons(View v, @IdRes int btnId1, @IdRes int btnId2) {
+        try {
+            boolean sendBackLongPress = false;
+            IActivityTaskManager activityManager = ActivityTaskManager.getService();
+            boolean touchExplorationEnabled = mAccessibilityManager.isTouchExplorationEnabled();
+            boolean inLockTaskMode = activityManager.isInLockTaskMode();
+            boolean stopLockTaskMode = false;
+            try {
+                if (inLockTaskMode && !touchExplorationEnabled) {
+                    long time = System.currentTimeMillis();
+
+                    // If we recently long-pressed the other button then they were
+                    // long-pressed 'together'
+                    if ((time - mLastLockToAppLongPress) < LOCK_TO_APP_GESTURE_TOLERANCE) {
+                        stopLockTaskMode = true;
+                        return true;
+                    } else if (v.getId() == btnId1) {
+                        ButtonDispatcher button = btnId2 == R.id.recent_apps
+                                ? mView.getRecentsButton() : mView.getHomeButton();
+                        if (!button.getCurrentView().isPressed()) {
+                            // If we aren't pressing recents/home right now then they presses
+                            // won't be together, so send the standard long-press action.
+                            sendBackLongPress = true;
+                        }
+                    }
+                    mLastLockToAppLongPress = time;
+                } else {
+                    // If this is back still need to handle sending the long-press event.
+                    if (v.getId() == btnId1) {
+                        sendBackLongPress = true;
+                    } else if (touchExplorationEnabled && inLockTaskMode) {
+                        // When in accessibility mode a long press that is recents/home (not back)
+                        // should stop lock task.
+                        stopLockTaskMode = true;
+                        return true;
+                    } else if (v.getId() == btnId2) {
+                        return btnId2 == R.id.recent_apps
+                                ? false
+                                : onHomeLongClick(mView.getHomeButton().getCurrentView());
+                    }
+                }
+            } finally {
+                if (stopLockTaskMode) {
+                    activityManager.stopSystemLockTaskMode();
+                    // When exiting refresh disabled flags.
+                    mView.updateNavButtonIcons();
+                }
+            }
+
+            if (sendBackLongPress) {
+                KeyButtonView keyButtonView = (KeyButtonView) v;
+                keyButtonView.sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
+                keyButtonView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
+                return true;
+            }
+        } catch (RemoteException e) {
+            Log.d(TAG, "Unable to reach activity manager", e);
+        }
+        return false;
+    }
+
+    private void onAccessibilityClick(View v) {
+        mNavBarButtonClickLogger.logAccessibilityButtonClick();
+        final Display display = v.getDisplay();
+        mAccessibilityManager.notifyAccessibilityButtonClicked(
+                display != null ? display.getDisplayId() : mDisplayTracker.getDefaultDisplayId());
+    }
+
+    private boolean onAccessibilityLongClick(View v) {
+        final Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        final String chooserClassName = AccessibilityButtonChooserActivity.class.getName();
+        intent.setClassName(CHOOSER_PACKAGE_NAME, chooserClassName);
+        mContext.startActivityAsUser(intent, mUserTracker.getUserHandle());
+        return true;
+    }
+
+    void updateAccessibilityStateFlags() {
+        mLongPressHomeEnabled = mNavBarHelper.getLongPressHomeEnabled();
+        if (mView != null) {
+            long a11yFlags = mNavBarHelper.getA11yButtonState();
+            boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
+            boolean longClickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
+            mView.setAccessibilityButtonState(clickable, longClickable);
+        }
+        updateSystemUiStateFlags();
+    }
+
+    public void updateSystemUiStateFlags() {
+        long a11yFlags = mNavBarHelper.getA11yButtonState();
+        boolean clickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
+        boolean longClickable = (a11yFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
+
+        mSysUiFlagsContainer.setFlag(SYSUI_STATE_A11Y_BUTTON_CLICKABLE, clickable)
+                .setFlag(SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE, longClickable)
+                .setFlag(SYSUI_STATE_NAV_BAR_HIDDEN, !isNavBarWindowVisible())
+                .setFlag(SYSUI_STATE_IME_SHOWING,
+                        (mNavigationIconHints & NAVIGATION_HINT_BACK_ALT) != 0)
+                .setFlag(SYSUI_STATE_IME_SWITCHER_SHOWING,
+                        (mNavigationIconHints & NAVIGATION_HINT_IME_SWITCHER_SHOWN) != 0)
+                .setFlag(SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY,
+                        allowSystemGestureIgnoringBarVisibility())
+                .commitUpdate(mDisplayId);
+    }
+
+    private void updateAssistantEntrypoints(boolean assistantAvailable,
+            boolean longPressHomeEnabled) {
+        if (mOverviewProxyService.getProxy() != null) {
+            try {
+                mOverviewProxyService.getProxy().onAssistantAvailable(assistantAvailable,
+                        longPressHomeEnabled);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Unable to send assistant availability data to launcher");
+            }
+        }
+        reconfigureHomeLongClick();
+    }
+
+    // ----- Methods that DisplayNavigationBarController talks to -----
+
+    /** Applies auto dimming animation on navigation bar when touched. */
+    public void touchAutoDim() {
+        getBarTransitions().setAutoDim(false);
+        mHandler.removeCallbacks(mAutoDim);
+        int state = mStatusBarStateController.getState();
+        if (state != StatusBarState.KEYGUARD && state != StatusBarState.SHADE_LOCKED) {
+            mHandler.postDelayed(mAutoDim, AUTODIM_TIMEOUT_MS);
+        }
+    }
+
+    public void setLightBarController(LightBarController lightBarController) {
+        mLightBarController = lightBarController;
+        if (mLightBarController != null) {
+            mLightBarController.setNavigationBar(
+                    getBarTransitions().getLightTransitionsController());
+        }
+    }
+
+    private void setWindowVisible(boolean visible) {
+        mRegionSamplingHelper.setWindowVisible(visible);
+        mView.setWindowVisible(visible);
+    }
+
+    /** Sets {@link AutoHideController} to the navigation bar. */
+    private void setAutoHideController(AutoHideController autoHideController) {
+        mAutoHideController = autoHideController;
+        if (mAutoHideController != null) {
+            mAutoHideController.setNavigationBar(mAutoHideUiElement);
+        }
+        mView.setAutoHideController(autoHideController);
+    }
+
+    private boolean isTransientShown() {
+        return mTransientShown;
+    }
+
+    private void checkBarModes() {
+        // We only have status bar on default display now.
+        if (mIsOnDefaultDisplay) {
+            mCentralSurfacesOptionalLazy.get().ifPresent(CentralSurfaces::checkBarModes);
+        } else {
+            checkNavBarModes();
+        }
+    }
+
+    public boolean isNavBarWindowVisible() {
+        return mNavigationBarWindowState == WINDOW_STATE_SHOWING;
+    }
+
+    private boolean allowSystemGestureIgnoringBarVisibility() {
+        return mBehavior != BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
+    }
+
+    /**
+     * Checks current navigation bar mode and make transitions.
+     */
+    public void checkNavBarModes() {
+        final boolean anim =
+                mCentralSurfacesOptionalLazy.get().map(CentralSurfaces::isDeviceInteractive)
+                        .orElse(false)
+                && mNavigationBarWindowState != WINDOW_STATE_HIDDEN;
+        getBarTransitions().transitionTo(mTransitionMode, anim);
+    }
+
+    public void disableAnimationsDuringHide(long delay) {
+        mView.setLayoutTransitionsEnabled(false);
+        mHandler.postDelayed(mEnableLayoutTransitions,
+                delay + StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE);
+    }
+
+    /**
+     * Performs transitions on navigation bar.
+     *
+     * @param barMode transition bar mode.
+     * @param animate shows animations if {@code true}.
+     */
+    public void transitionTo(@TransitionMode int barMode, boolean animate) {
+        getBarTransitions().transitionTo(barMode, animate);
+    }
+
+    public NavigationBarTransitions getBarTransitions() {
+        return mNavigationBarTransitions;
+    }
+
+    public void finishBarAnimations() {
+        getBarTransitions().finishAnimations();
+    }
+
+    private WindowManager.LayoutParams getBarLayoutParams(int rotation) {
+        WindowManager.LayoutParams lp = getBarLayoutParamsForRotation(rotation);
+        lp.paramsForRotation = new WindowManager.LayoutParams[4];
+        for (int rot = Surface.ROTATION_0; rot <= Surface.ROTATION_270; rot++) {
+            lp.paramsForRotation[rot] = getBarLayoutParamsForRotation(rot);
+        }
+        return lp;
+    }
+
+    private WindowManager.LayoutParams getBarLayoutParamsForRotation(int rotation) {
+        int width = WindowManager.LayoutParams.MATCH_PARENT;
+        int height = WindowManager.LayoutParams.MATCH_PARENT;
+        int insetsHeight = -1;
+        int gravity = Gravity.BOTTOM;
+        boolean navBarCanMove = true;
+        final Context userContext = mUserContextProvider.createCurrentUserContext(mContext);
+        if (mWindowManager != null && mWindowManager.getCurrentWindowMetrics() != null) {
+            Rect displaySize = mWindowManager.getCurrentWindowMetrics().getBounds();
+            navBarCanMove = displaySize.width() != displaySize.height()
+                    && userContext.getResources().getBoolean(
+                    com.android.internal.R.bool.config_navBarCanMove);
+        }
+        if (!navBarCanMove) {
+            height = userContext.getResources().getDimensionPixelSize(
+                    com.android.internal.R.dimen.navigation_bar_frame_height);
+            insetsHeight = userContext.getResources().getDimensionPixelSize(
+                    com.android.internal.R.dimen.navigation_bar_height);
+        } else {
+            switch (rotation) {
+                case ROTATION_UNDEFINED:
+                case Surface.ROTATION_0:
+                case Surface.ROTATION_180:
+                    height = userContext.getResources().getDimensionPixelSize(
+                            com.android.internal.R.dimen.navigation_bar_frame_height);
+                    insetsHeight = userContext.getResources().getDimensionPixelSize(
+                            com.android.internal.R.dimen.navigation_bar_height);
+                    break;
+                case Surface.ROTATION_90:
+                    gravity = Gravity.RIGHT;
+                    width = userContext.getResources().getDimensionPixelSize(
+                            com.android.internal.R.dimen.navigation_bar_width);
+                    break;
+                case Surface.ROTATION_270:
+                    gravity = Gravity.LEFT;
+                    width = userContext.getResources().getDimensionPixelSize(
+                            com.android.internal.R.dimen.navigation_bar_width);
+                    break;
+            }
+        }
+        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                width,
+                height,
+                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
+                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
+                        | WindowManager.LayoutParams.FLAG_SLIPPERY,
+                PixelFormat.TRANSLUCENT);
+        lp.gravity = gravity;
+        lp.providedInsets = getInsetsFrameProvider(insetsHeight, userContext);
+
+        lp.token = new Binder();
+        lp.accessibilityTitle = userContext.getString(R.string.nav_bar);
+        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC
+                | WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
+        lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+        lp.windowAnimations = 0;
+        lp.setTitle("NavigationBar" + userContext.getDisplayId());
+        lp.setFitInsetsTypes(0 /* types */);
+        lp.setTrustedOverlay();
+        return lp;
+    }
+
+    private InsetsFrameProvider[] getInsetsFrameProvider(int insetsHeight, Context userContext) {
+        final InsetsFrameProvider navBarProvider =
+                new InsetsFrameProvider(mInsetsSourceOwner, 0, WindowInsets.Type.navigationBars());
+        if (!ENABLE_HIDE_IME_CAPTION_BAR) {
+            navBarProvider.setInsetsSizeOverrides(new InsetsFrameProvider.InsetsSizeOverride[] {
+                    new InsetsFrameProvider.InsetsSizeOverride(TYPE_INPUT_METHOD, null)
+            });
+        }
+        if (insetsHeight != -1 && !mEdgeBackGestureHandler.isButtonForcedVisible()) {
+            navBarProvider.setInsetsSize(Insets.of(0, 0, 0, insetsHeight));
+        }
+        final boolean needsScrim = userContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_navBarNeedsScrim);
+        navBarProvider.setFlags(needsScrim ? 0 : FLAG_SUPPRESS_SCRIM, FLAG_SUPPRESS_SCRIM);
+
+        final InsetsFrameProvider tappableElementProvider = new InsetsFrameProvider(
+                mInsetsSourceOwner, 0, WindowInsets.Type.tappableElement());
+        final boolean tapThrough = userContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_navBarTapThrough);
+        if (tapThrough) {
+            tappableElementProvider.setInsetsSize(Insets.NONE);
+        }
+
+        final int gestureHeight = userContext.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.navigation_bar_gesture_height);
+        final boolean handlingGesture = mEdgeBackGestureHandler.isHandlingGestures();
+        final InsetsFrameProvider mandatoryGestureProvider = new InsetsFrameProvider(
+                mInsetsSourceOwner, 0, WindowInsets.Type.mandatorySystemGestures());
+        if (handlingGesture) {
+            mandatoryGestureProvider.setInsetsSize(Insets.of(0, 0, 0, gestureHeight));
+        }
+        final int gestureInsetsLeft = handlingGesture
+                ? mEdgeBackGestureHandler.getEdgeWidthLeft() : 0;
+        final int gestureInsetsRight = handlingGesture
+                ? mEdgeBackGestureHandler.getEdgeWidthRight() : 0;
+        return new InsetsFrameProvider[] {
+                navBarProvider,
+                tappableElementProvider,
+                mandatoryGestureProvider,
+                new InsetsFrameProvider(mInsetsSourceOwner, 0, WindowInsets.Type.systemGestures())
+                        .setSource(InsetsFrameProvider.SOURCE_DISPLAY)
+                        .setInsetsSize(Insets.of(gestureInsetsLeft, 0, 0, 0))
+                        .setMinimalInsetsSizeInDisplayCutoutSafe(
+                                Insets.of(gestureInsetsLeft, 0, 0, 0)),
+                new InsetsFrameProvider(mInsetsSourceOwner, 1, WindowInsets.Type.systemGestures())
+                        .setSource(InsetsFrameProvider.SOURCE_DISPLAY)
+                        .setInsetsSize(Insets.of(0, 0, gestureInsetsRight, 0))
+                        .setMinimalInsetsSizeInDisplayCutoutSafe(
+                                Insets.of(0, 0, gestureInsetsRight, 0))
+        };
+    }
+
+    private boolean canShowSecondaryHandle() {
+        return mNavBarMode == NAV_BAR_MODE_GESTURAL && mOrientationHandle != null;
+    }
+
+    private final UserTracker.Callback mUserChangedCallback =
+            new UserTracker.Callback() {
+                @Override
+                public void onUserChanged(int newUser, @NonNull Context userContext) {
+                    // The accessibility settings may be different for the new user
+                    updateAccessibilityStateFlags();
+                }
+            };
+
+    @VisibleForTesting
+    int getNavigationIconHints() {
+        return mNavigationIconHints;
+    }
+
+    private void setNavigationIconHints(int hints) {
+        if (hints == mNavigationIconHints) return;
+        if (!isLargeScreen(mContext)) {
+            // All IME functions handled by launcher via Sysui flags for large screen
+            final boolean newBackAlt = (hints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
+            final boolean oldBackAlt =
+                    (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
+            if (newBackAlt != oldBackAlt) {
+                mView.onImeVisibilityChanged(newBackAlt);
+                mImeVisible = newBackAlt;
+            }
+
+            mView.setNavigationIconHints(hints);
+        }
+        if (DEBUG) {
+            android.widget.Toast.makeText(mContext,
+                    "Navigation icon hints = " + hints,
+                    500).show();
+        }
+        mNavigationIconHints = hints;
+    }
+
+    /**
+     * @param inScreenSpace Whether to return values in screen space or window space
+     * @param useNearestRegion Whether to use the nearest region instead of the actual button bounds
+     * @return
+     */
+    Region getButtonLocations(boolean inScreenSpace, boolean useNearestRegion) {
+        if (useNearestRegion && !inScreenSpace) {
+            // We currently don't support getting the nearest region in anything but screen space
+            useNearestRegion = false;
+        }
+        Region region = new Region();
+        Map<View, Rect> touchRegionCache = mView.getButtonTouchRegionCache();
+        updateButtonLocation(
+                region, touchRegionCache, mView.getBackButton(), inScreenSpace, useNearestRegion);
+        updateButtonLocation(
+                region, touchRegionCache, mView.getHomeButton(), inScreenSpace, useNearestRegion);
+        updateButtonLocation(region, touchRegionCache, mView.getRecentsButton(), inScreenSpace,
+                useNearestRegion);
+        updateButtonLocation(region, touchRegionCache, mView.getImeSwitchButton(), inScreenSpace,
+                useNearestRegion);
+        updateButtonLocation(
+                region, touchRegionCache, mView.getAccessibilityButton(), inScreenSpace,
+                useNearestRegion);
+        if (mView.getFloatingRotationButton().isVisible()) {
+            // Note: this button is floating so the nearest region doesn't apply
+            updateButtonLocation(
+                    region, mView.getFloatingRotationButton().getCurrentView(), inScreenSpace);
+        }
+        return region;
+    }
+
+    private void updateButtonLocation(
+            Region region,
+            Map<View, Rect> touchRegionCache,
+            ButtonDispatcher button,
+            boolean inScreenSpace,
+            boolean useNearestRegion) {
+        if (button == null) {
+            return;
+        }
+        View view = button.getCurrentView();
+        if (view == null || !button.isVisible()) {
+            return;
+        }
+        // If the button is tappable from perspective of NearestTouchFrame, then we'll
+        // include the regions where the tap is valid instead of just the button layout location
+        if (useNearestRegion && touchRegionCache.containsKey(view)) {
+            region.op(touchRegionCache.get(view), Region.Op.UNION);
+            return;
+        }
+        updateButtonLocation(region, view, inScreenSpace);
+    }
+
+    private void updateButtonLocation(Region region, View view, boolean inScreenSpace) {
+        Rect bounds = new Rect();
+        if (inScreenSpace) {
+            view.getBoundsOnScreen(bounds);
+        } else {
+            int[] location = new int[2];
+            view.getLocationInWindow(location);
+            bounds.set(location[0], location[1],
+                    location[0] + view.getWidth(),
+                    location[1] + view.getHeight());
+        }
+        region.op(bounds, Region.Op.UNION);
+    }
+
+    void setOrientedHandleSamplingRegion(Rect orientedHandleSamplingRegion) {
+        mOrientedHandleSamplingRegion = orientedHandleSamplingRegion;
+        mRegionSamplingHelper.updateSamplingRect();
+    }
+
+    private Rect calculateSamplingRect() {
+        mSamplingBounds.setEmpty();
+        // TODO: Extend this to 2/3 button layout as well
+        View view = mView.getHomeHandle().getCurrentView();
+
+        if (view != null) {
+            int[] pos = new int[2];
+            view.getLocationOnScreen(pos);
+            Point displaySize = new Point();
+            view.getContext().getDisplay().getRealSize(displaySize);
+            final Rect samplingBounds = new Rect(pos[0] - mNavColorSampleMargin,
+                    displaySize.y - mView.getNavBarHeight(),
+                    pos[0] + view.getWidth() + mNavColorSampleMargin,
+                    displaySize.y);
+            mSamplingBounds.set(samplingBounds);
+        }
+
+        return mSamplingBounds;
+    }
+
+    public void setNavigationBarLumaSamplingEnabled(boolean enable) {
+        if (enable) {
+            mRegionSamplingHelper.start(mSamplingBounds);
+        } else {
+            mRegionSamplingHelper.stop();
+        }
+    }
+
+    private void setNavBarMode(int mode) {
+        mView.setNavBarMode(mode, mNavigationModeController.getImeDrawsImeNavBar());
+        if (isGesturalMode(mode)) {
+            mRegionSamplingHelper.start(mSamplingBounds);
+        } else {
+            mRegionSamplingHelper.stop();
+        }
+    }
+
+    void onBarTransition(int newMode) {
+        if (newMode == MODE_OPAQUE) {
+            // If the nav bar background is opaque, stop auto tinting since we know the icons are
+            // showing over a dark background
+            mRegionSamplingHelper.stop();
+            getBarTransitions().getLightTransitionsController().setIconsDark(
+                    false /* dark */, true /* animate */);
+        } else {
+            mRegionSamplingHelper.start(mSamplingBounds);
+        }
+    }
+
+    private final ModeChangedListener mModeChangedListener = new ModeChangedListener() {
+        @Override
+        public void onNavigationModeChanged(int mode) {
+            mNavBarMode = mode;
+
+            if (!QuickStepContract.isGesturalMode(mode)) {
+                // Reset the override alpha
+                if (getBarTransitions() != null) {
+                    getBarTransitions().setBackgroundOverrideAlpha(1f);
+                }
+            }
+
+            // Update the window layout params when the nav mode changes as that will affect the
+            // system gesture insets
+            setNavBarMode(mode);
+            repositionNavigationBar(mCurrentRotation);
+
+            if (!canShowSecondaryHandle()) {
+                resetSecondaryHandle();
+            }
+            mView.setShouldShowSwipeUpUi(mOverviewProxyService.shouldShowSwipeUpUI());
+        }
+    };
+
+    private final Gefingerpoken mTouchHandler = new Gefingerpoken() {
+        private boolean mDeadZoneConsuming;
+
+        @Override
+        public boolean onInterceptTouchEvent(MotionEvent ev) {
+            if (isGesturalMode(mNavBarMode) && mImeVisible
+                    && ev.getAction() == MotionEvent.ACTION_DOWN) {
+                SysUiStatsLog.write(SysUiStatsLog.IME_TOUCH_REPORTED,
+                        (int) ev.getX(), (int) ev.getY());
+            }
+            return shouldDeadZoneConsumeTouchEvents(ev);
+        }
+
+        @Override
+        public boolean onTouchEvent(MotionEvent ev) {
+            shouldDeadZoneConsumeTouchEvents(ev);
+            return false;
+        }
+
+        private boolean shouldDeadZoneConsumeTouchEvents(MotionEvent event) {
+            int action = event.getActionMasked();
+            if (action == MotionEvent.ACTION_DOWN) {
+                mDeadZoneConsuming = false;
+            }
+            if (mDeadZone.onTouchEvent(event) || mDeadZoneConsuming) {
+                switch (action) {
+                    case MotionEvent.ACTION_DOWN:
+                        // Allow gestures starting in the deadzone to be slippery
+                        mView.setSlippery(true);
+                        mDeadZoneConsuming = true;
+                        break;
+                    case MotionEvent.ACTION_CANCEL:
+                    case MotionEvent.ACTION_UP:
+                        // When a gesture started in the deadzone is finished, restore
+                        // slippery state
+                        mView.updateSlippery();
+                        mDeadZoneConsuming = false;
+                        break;
+                }
+                return true;
+            }
+            return false;
+        }
+    };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarFrame.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarFrame.java
new file mode 100644
index 0000000..3388f93
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarFrame.java
@@ -0,0 +1,61 @@
+/*
+ * 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.navigationbar.views;
+
+import static android.view.MotionEvent.ACTION_OUTSIDE;
+
+import android.annotation.AttrRes;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.widget.FrameLayout;
+
+import com.android.systemui.navigationbar.views.buttons.DeadZone;
+
+public class NavigationBarFrame extends FrameLayout {
+
+    private DeadZone mDeadZone = null;
+
+    public NavigationBarFrame(@NonNull Context context) {
+        super(context);
+    }
+
+    public NavigationBarFrame(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public NavigationBarFrame(@NonNull Context context, @Nullable AttributeSet attrs,
+            @AttrRes int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public void setDeadZone(@NonNull DeadZone deadZone) {
+        mDeadZone = deadZone;
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent event) {
+        if (event.getAction() == ACTION_OUTSIDE) {
+            if (mDeadZone != null) {
+                return mDeadZone.onTouchEvent(event);
+            }
+        }
+        return super.dispatchTouchEvent(event);
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarInflaterView.java
new file mode 100644
index 0000000..96b730c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarInflaterView.java
@@ -0,0 +1,504 @@
+/*
+ * 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.navigationbar.views;
+
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.drawable.Icon;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.Space;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.Dependency;
+import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.navigationbar.views.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.views.buttons.KeyButtonView;
+import com.android.systemui.navigationbar.views.buttons.ReverseLinearLayout;
+import com.android.systemui.navigationbar.views.buttons.ReverseLinearLayout.ReverseRelativeLayout;
+import com.android.systemui.recents.OverviewProxyService;
+import com.android.systemui.res.R;
+import com.android.systemui.shared.system.QuickStepContract;
+
+import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
+import java.util.Objects;
+
+public class NavigationBarInflaterView extends FrameLayout {
+    private static final String TAG = "NavBarInflater";
+
+    public static final String NAV_BAR_VIEWS = "sysui_nav_bar";
+    public static final String NAV_BAR_LEFT = "sysui_nav_bar_left";
+    public static final String NAV_BAR_RIGHT = "sysui_nav_bar_right";
+
+    public static final String MENU_IME_ROTATE = "menu_ime";
+    public static final String BACK = "back";
+    public static final String HOME = "home";
+    public static final String RECENT = "recent";
+    public static final String NAVSPACE = "space";
+    public static final String CLIPBOARD = "clipboard";
+    public static final String HOME_HANDLE = "home_handle";
+    public static final String KEY = "key";
+    public static final String LEFT = "left";
+    public static final String RIGHT = "right";
+    public static final String CONTEXTUAL = "contextual";
+    public static final String IME_SWITCHER = "ime_switcher";
+
+    public static final String GRAVITY_SEPARATOR = ";";
+    public static final String BUTTON_SEPARATOR = ",";
+
+    public static final String SIZE_MOD_START = "[";
+    public static final String SIZE_MOD_END = "]";
+
+    public static final String KEY_CODE_START = "(";
+    public static final String KEY_IMAGE_DELIM = ":";
+    public static final String KEY_CODE_END = ")";
+    private static final String WEIGHT_SUFFIX = "W";
+    private static final String WEIGHT_CENTERED_SUFFIX = "WC";
+    private static final String ABSOLUTE_SUFFIX = "A";
+    private static final String ABSOLUTE_VERTICAL_CENTERED_SUFFIX = "C";
+
+    private static class Listener implements NavigationModeController.ModeChangedListener {
+        private final WeakReference<NavigationBarInflaterView> mSelf;
+
+        Listener(NavigationBarInflaterView self) {
+            mSelf = new WeakReference<>(self);
+        }
+
+        @Override
+        public void onNavigationModeChanged(int mode) {
+            NavigationBarInflaterView self = mSelf.get();
+            if (self != null) {
+                self.onNavigationModeChanged(mode);
+            }
+        }
+    }
+
+    private final Listener mListener;
+
+    protected LayoutInflater mLayoutInflater;
+    protected LayoutInflater mLandscapeInflater;
+
+    protected FrameLayout mHorizontal;
+    protected FrameLayout mVertical;
+
+    @VisibleForTesting
+    SparseArray<ButtonDispatcher> mButtonDispatchers;
+    private String mCurrentLayout;
+
+    private View mLastPortrait;
+    private View mLastLandscape;
+
+    private boolean mIsVertical;
+    private boolean mAlternativeOrder;
+
+    private OverviewProxyService mOverviewProxyService;
+    private int mNavBarMode = NAV_BAR_MODE_3BUTTON;
+
+    public NavigationBarInflaterView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        createInflaters();
+        mOverviewProxyService = Dependency.get(OverviewProxyService.class);
+        mListener = new Listener(this);
+        mNavBarMode = Dependency.get(NavigationModeController.class).addListener(mListener);
+    }
+
+    @VisibleForTesting
+    void createInflaters() {
+        mLayoutInflater = LayoutInflater.from(mContext);
+        Configuration landscape = new Configuration();
+        landscape.setTo(mContext.getResources().getConfiguration());
+        landscape.orientation = Configuration.ORIENTATION_LANDSCAPE;
+        mLandscapeInflater = LayoutInflater.from(mContext.createConfigurationContext(landscape));
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        inflateChildren();
+        clearViews();
+        inflateLayout(getDefaultLayout());
+    }
+
+    private void inflateChildren() {
+        removeAllViews();
+        mHorizontal = (FrameLayout) mLayoutInflater.inflate(R.layout.navigation_layout,
+                this /* root */, false /* attachToRoot */);
+        addView(mHorizontal);
+        mVertical = (FrameLayout) mLayoutInflater.inflate(R.layout.navigation_layout_vertical,
+                this /* root */, false /* attachToRoot */);
+        addView(mVertical);
+        updateAlternativeOrder();
+    }
+
+    protected String getDefaultLayout() {
+        final int defaultResource = QuickStepContract.isGesturalMode(mNavBarMode)
+                ? R.string.config_navBarLayoutHandle
+                : mOverviewProxyService.shouldShowSwipeUpUI()
+                        ? R.string.config_navBarLayoutQuickstep
+                        : R.string.config_navBarLayout;
+        return getContext().getString(defaultResource);
+    }
+
+    private void onNavigationModeChanged(int mode) {
+        mNavBarMode = mode;
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        Dependency.get(NavigationModeController.class).removeListener(mListener);
+        super.onDetachedFromWindow();
+    }
+
+    public void onLikelyDefaultLayoutChange() {
+        // Reevaluate new layout
+        final String newValue = getDefaultLayout();
+        if (!Objects.equals(mCurrentLayout, newValue)) {
+            clearViews();
+            inflateLayout(newValue);
+        }
+    }
+
+    public void setButtonDispatchers(SparseArray<ButtonDispatcher> buttonDispatchers) {
+        mButtonDispatchers = buttonDispatchers;
+        clearDispatcherViews();
+        for (int i = 0; i < buttonDispatchers.size(); i++) {
+            initiallyFill(buttonDispatchers.valueAt(i));
+        }
+    }
+
+    void updateButtonDispatchersCurrentView() {
+        if (mButtonDispatchers != null) {
+            View view = mIsVertical ? mVertical : mHorizontal;
+            for (int i = 0; i < mButtonDispatchers.size(); i++) {
+                final ButtonDispatcher dispatcher = mButtonDispatchers.valueAt(i);
+                dispatcher.setCurrentView(view);
+            }
+        }
+    }
+
+    void setVertical(boolean vertical) {
+        if (vertical != mIsVertical) {
+            mIsVertical = vertical;
+        }
+    }
+
+    void setAlternativeOrder(boolean alternativeOrder) {
+        if (alternativeOrder != mAlternativeOrder) {
+            mAlternativeOrder = alternativeOrder;
+            updateAlternativeOrder();
+        }
+    }
+
+    private void updateAlternativeOrder() {
+        updateAlternativeOrder(mHorizontal.findViewById(R.id.ends_group));
+        updateAlternativeOrder(mHorizontal.findViewById(R.id.center_group));
+        updateAlternativeOrder(mVertical.findViewById(R.id.ends_group));
+        updateAlternativeOrder(mVertical.findViewById(R.id.center_group));
+    }
+
+    private void updateAlternativeOrder(View v) {
+        if (v instanceof ReverseLinearLayout) {
+            ((ReverseLinearLayout) v).setAlternativeOrder(mAlternativeOrder);
+        }
+    }
+
+    private void initiallyFill(ButtonDispatcher buttonDispatcher) {
+        addAll(buttonDispatcher, mHorizontal.findViewById(R.id.ends_group));
+        addAll(buttonDispatcher, mHorizontal.findViewById(R.id.center_group));
+        addAll(buttonDispatcher, mVertical.findViewById(R.id.ends_group));
+        addAll(buttonDispatcher, mVertical.findViewById(R.id.center_group));
+    }
+
+    private void addAll(ButtonDispatcher buttonDispatcher, ViewGroup parent) {
+        for (int i = 0; i < parent.getChildCount(); i++) {
+            // Need to manually search for each id, just in case each group has more than one
+            // of a single id.  It probably mostly a waste of time, but shouldn't take long
+            // and will only happen once.
+            if (parent.getChildAt(i).getId() == buttonDispatcher.getId()) {
+                buttonDispatcher.addView(parent.getChildAt(i));
+            }
+            if (parent.getChildAt(i) instanceof ViewGroup) {
+                addAll(buttonDispatcher, (ViewGroup) parent.getChildAt(i));
+            }
+        }
+    }
+
+    protected void inflateLayout(String newLayout) {
+        mCurrentLayout = newLayout;
+        if (newLayout == null) {
+            newLayout = getDefaultLayout();
+        }
+        String[] sets = newLayout.split(GRAVITY_SEPARATOR, 3);
+        if (sets.length != 3) {
+            Log.d(TAG, "Invalid layout.");
+            newLayout = getDefaultLayout();
+            sets = newLayout.split(GRAVITY_SEPARATOR, 3);
+        }
+        String[] start = sets[0].split(BUTTON_SEPARATOR);
+        String[] center = sets[1].split(BUTTON_SEPARATOR);
+        String[] end = sets[2].split(BUTTON_SEPARATOR);
+        // Inflate these in start to end order or accessibility traversal will be messed up.
+        inflateButtons(start, mHorizontal.findViewById(R.id.ends_group),
+                false /* landscape */, true /* start */);
+        inflateButtons(start, mVertical.findViewById(R.id.ends_group),
+                true /* landscape */, true /* start */);
+
+        inflateButtons(center, mHorizontal.findViewById(R.id.center_group),
+                false /* landscape */, false /* start */);
+        inflateButtons(center, mVertical.findViewById(R.id.center_group),
+                true /* landscape */, false /* start */);
+
+        addGravitySpacer(mHorizontal.findViewById(R.id.ends_group));
+        addGravitySpacer(mVertical.findViewById(R.id.ends_group));
+
+        inflateButtons(end, mHorizontal.findViewById(R.id.ends_group),
+                false /* landscape */, false /* start */);
+        inflateButtons(end, mVertical.findViewById(R.id.ends_group),
+                true /* landscape */, false /* start */);
+
+        updateButtonDispatchersCurrentView();
+    }
+
+    private void addGravitySpacer(LinearLayout layout) {
+        layout.addView(new Space(mContext), new LinearLayout.LayoutParams(0, 0, 1));
+    }
+
+    private void inflateButtons(String[] buttons, ViewGroup parent, boolean landscape,
+            boolean start) {
+        for (int i = 0; i < buttons.length; i++) {
+            inflateButton(buttons[i], parent, landscape, start);
+        }
+    }
+
+    private ViewGroup.LayoutParams copy(ViewGroup.LayoutParams layoutParams) {
+        if (layoutParams instanceof LinearLayout.LayoutParams) {
+            return new LinearLayout.LayoutParams(layoutParams.width, layoutParams.height,
+                    ((LinearLayout.LayoutParams) layoutParams).weight);
+        }
+        return new LayoutParams(layoutParams.width, layoutParams.height);
+    }
+
+    @Nullable
+    protected View inflateButton(String buttonSpec, ViewGroup parent, boolean landscape,
+            boolean start) {
+        LayoutInflater inflater = landscape ? mLandscapeInflater : mLayoutInflater;
+        View v = createView(buttonSpec, parent, inflater);
+        if (v == null) return null;
+
+        v = applySize(v, buttonSpec, landscape, start);
+        parent.addView(v);
+        addToDispatchers(v);
+        View lastView = landscape ? mLastLandscape : mLastPortrait;
+        View accessibilityView = v;
+        if (v instanceof ReverseRelativeLayout) {
+            accessibilityView = ((ReverseRelativeLayout) v).getChildAt(0);
+        }
+        if (lastView != null) {
+            accessibilityView.setAccessibilityTraversalAfter(lastView.getId());
+        }
+        if (landscape) {
+            mLastLandscape = accessibilityView;
+        } else {
+            mLastPortrait = accessibilityView;
+        }
+        return v;
+    }
+
+    private View applySize(View v, String buttonSpec, boolean landscape, boolean start) {
+        String sizeStr = extractSize(buttonSpec);
+        if (sizeStr == null) return v;
+
+        if (sizeStr.contains(WEIGHT_SUFFIX) || sizeStr.contains(ABSOLUTE_SUFFIX)) {
+            // To support gravity, wrap in RelativeLayout and apply gravity to it.
+            // Children wanting to use gravity must be smaller then the frame.
+            ReverseRelativeLayout frame = new ReverseRelativeLayout(mContext);
+            LayoutParams childParams = new LayoutParams(v.getLayoutParams());
+
+            // Compute gravity to apply
+            int gravity = (landscape) ? (start ? Gravity.TOP : Gravity.BOTTOM)
+                    : (start ? Gravity.START : Gravity.END);
+            if (sizeStr.endsWith(WEIGHT_CENTERED_SUFFIX)) {
+                gravity = Gravity.CENTER;
+            } else if (sizeStr.endsWith(ABSOLUTE_VERTICAL_CENTERED_SUFFIX)) {
+                gravity = Gravity.CENTER_VERTICAL;
+            }
+
+            // Set default gravity, flipped if needed in reversed layouts (270 RTL and 90 LTR)
+            frame.setDefaultGravity(gravity);
+            frame.setGravity(gravity); // Apply gravity to root
+
+            frame.addView(v, childParams);
+
+            if (sizeStr.contains(WEIGHT_SUFFIX)) {
+                // Use weighting to set the width of the frame
+                float weight = Float.parseFloat(
+                        sizeStr.substring(0, sizeStr.indexOf(WEIGHT_SUFFIX)));
+                frame.setLayoutParams(new LinearLayout.LayoutParams(0, MATCH_PARENT, weight));
+            } else {
+                int width = (int) convertDpToPx(mContext,
+                        Float.parseFloat(sizeStr.substring(0, sizeStr.indexOf(ABSOLUTE_SUFFIX))));
+                frame.setLayoutParams(new LinearLayout.LayoutParams(width, MATCH_PARENT));
+            }
+
+            // Ensure ripples can be drawn outside bounds
+            frame.setClipChildren(false);
+            frame.setClipToPadding(false);
+
+            return frame;
+        }
+
+        float size = Float.parseFloat(sizeStr);
+        ViewGroup.LayoutParams params = v.getLayoutParams();
+        params.width = (int) (params.width * size);
+        return v;
+    }
+
+    View createView(String buttonSpec, ViewGroup parent, LayoutInflater inflater) {
+        View v = null;
+        String button = extractButton(buttonSpec);
+        if (LEFT.equals(button)) {
+            button = extractButton(NAVSPACE);
+        } else if (RIGHT.equals(button)) {
+            button = extractButton(MENU_IME_ROTATE);
+        }
+        if (HOME.equals(button)) {
+            v = inflater.inflate(R.layout.home, parent, false);
+        } else if (BACK.equals(button)) {
+            v = inflater.inflate(R.layout.back, parent, false);
+        } else if (RECENT.equals(button)) {
+            v = inflater.inflate(R.layout.recent_apps, parent, false);
+        } else if (MENU_IME_ROTATE.equals(button)) {
+            v = inflater.inflate(R.layout.menu_ime, parent, false);
+        } else if (NAVSPACE.equals(button)) {
+            v = inflater.inflate(R.layout.nav_key_space, parent, false);
+        } else if (CLIPBOARD.equals(button)) {
+            v = inflater.inflate(R.layout.clipboard, parent, false);
+        } else if (CONTEXTUAL.equals(button)) {
+            v = inflater.inflate(R.layout.contextual, parent, false);
+        } else if (HOME_HANDLE.equals(button)) {
+            v = inflater.inflate(R.layout.home_handle, parent, false);
+        } else if (IME_SWITCHER.equals(button)) {
+            v = inflater.inflate(R.layout.ime_switcher, parent, false);
+        } else if (button.startsWith(KEY)) {
+            String uri = extractImage(button);
+            int code = extractKeycode(button);
+            v = inflater.inflate(R.layout.custom_key, parent, false);
+            ((KeyButtonView) v).setCode(code);
+            if (uri != null) {
+                if (uri.contains(":")) {
+                    ((KeyButtonView) v).loadAsync(Icon.createWithContentUri(uri));
+                } else if (uri.contains("/")) {
+                    int index = uri.indexOf('/');
+                    String pkg = uri.substring(0, index);
+                    int id = Integer.parseInt(uri.substring(index + 1));
+                    ((KeyButtonView) v).loadAsync(Icon.createWithResource(pkg, id));
+                }
+            }
+        }
+        return v;
+    }
+
+    public static String extractImage(String buttonSpec) {
+        if (!buttonSpec.contains(KEY_IMAGE_DELIM)) {
+            return null;
+        }
+        final int start = buttonSpec.indexOf(KEY_IMAGE_DELIM);
+        String subStr = buttonSpec.substring(start + 1, buttonSpec.indexOf(KEY_CODE_END));
+        return subStr;
+    }
+
+    public static int extractKeycode(String buttonSpec) {
+        if (!buttonSpec.contains(KEY_CODE_START)) {
+            return 1;
+        }
+        final int start = buttonSpec.indexOf(KEY_CODE_START);
+        String subStr = buttonSpec.substring(start + 1, buttonSpec.indexOf(KEY_IMAGE_DELIM));
+        return Integer.parseInt(subStr);
+    }
+
+    public static String extractSize(String buttonSpec) {
+        if (!buttonSpec.contains(SIZE_MOD_START)) {
+            return null;
+        }
+        final int sizeStart = buttonSpec.indexOf(SIZE_MOD_START);
+        return buttonSpec.substring(sizeStart + 1, buttonSpec.indexOf(SIZE_MOD_END));
+    }
+
+    public static String extractButton(String buttonSpec) {
+        if (!buttonSpec.contains(SIZE_MOD_START)) {
+            return buttonSpec;
+        }
+        return buttonSpec.substring(0, buttonSpec.indexOf(SIZE_MOD_START));
+    }
+
+    private void addToDispatchers(View v) {
+        if (mButtonDispatchers != null) {
+            final int indexOfKey = mButtonDispatchers.indexOfKey(v.getId());
+            if (indexOfKey >= 0) {
+                mButtonDispatchers.valueAt(indexOfKey).addView(v);
+            }
+            if (v instanceof ViewGroup) {
+                final ViewGroup viewGroup = (ViewGroup)v;
+                final int N = viewGroup.getChildCount();
+                for (int i = 0; i < N; i++) {
+                    addToDispatchers(viewGroup.getChildAt(i));
+                }
+            }
+        }
+    }
+
+    private void clearDispatcherViews() {
+        if (mButtonDispatchers != null) {
+            for (int i = 0; i < mButtonDispatchers.size(); i++) {
+                mButtonDispatchers.valueAt(i).clear();
+            }
+        }
+    }
+
+    private void clearViews() {
+        clearDispatcherViews();
+        clearAllChildren(mHorizontal.findViewById(R.id.nav_buttons));
+        clearAllChildren(mVertical.findViewById(R.id.nav_buttons));
+    }
+
+    private void clearAllChildren(ViewGroup group) {
+        for (int i = 0; i < group.getChildCount(); i++) {
+            ((ViewGroup) group.getChildAt(i)).removeAllViews();
+        }
+    }
+
+    private static float convertDpToPx(Context context, float dp) {
+        return dp * context.getResources().getDisplayMetrics().density;
+    }
+
+    public void dump(PrintWriter pw) {
+        pw.println("NavigationBarInflaterView");
+        pw.println("  mCurrentLayout: " + mCurrentLayout);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarTransitions.java
new file mode 100644
index 0000000..251745d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarTransitions.java
@@ -0,0 +1,256 @@
+/*
+ * 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.navigationbar.views;
+
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
+
+import static com.android.systemui.util.Utils.isGesturalModeOnDefaultDisplay;
+
+import android.graphics.Rect;
+import android.util.SparseArray;
+import android.view.View;
+
+import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope;
+import com.android.systemui.navigationbar.views.buttons.ButtonDispatcher;
+import com.android.systemui.res.R;
+import com.android.systemui.settings.DisplayTracker;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
+import com.android.systemui.statusbar.phone.LightBarTransitionsController;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+/** */
+@NavigationBarScope
+public final class NavigationBarTransitions extends BarTransitions implements
+        LightBarTransitionsController.DarkIntensityApplier {
+
+    public static final int MIN_COLOR_ADAPT_TRANSITION_TIME = 400;
+    public static final int DEFAULT_COLOR_ADAPT_TRANSITION_TIME = 1700;
+    private List<Listener> mListeners = new ArrayList<>();
+
+    /**
+     * Notified when the color of nav bar elements changes.
+     */
+    public interface DarkIntensityListener {
+        /**
+         * Called when the color of nav bar elements changes.
+         * @param darkIntensity 0 is the lightest color, 1 is the darkest.
+         */
+        void onDarkIntensity(float darkIntensity);
+    }
+
+    private final NavigationBarView mView;
+    private final LightBarTransitionsController mLightTransitionsController;
+    private final DisplayTracker mDisplayTracker;
+    private final boolean mAllowAutoDimWallpaperNotVisible;
+    private boolean mWallpaperVisible;
+
+    private boolean mLightsOut;
+    private boolean mAutoDim;
+    private View mNavButtons;
+    private int mNavBarMode = NAV_BAR_MODE_3BUTTON;
+    private List<DarkIntensityListener> mDarkIntensityListeners;
+
+    @Inject
+    public NavigationBarTransitions(
+            NavigationBarView view,
+            LightBarTransitionsController.Factory lightBarTransitionsControllerFactory,
+            DisplayTracker displayTracker) {
+        super(view, R.drawable.nav_background);
+
+        mView = view;
+        mLightTransitionsController = lightBarTransitionsControllerFactory.create(this);
+        mDisplayTracker = displayTracker;
+        mAllowAutoDimWallpaperNotVisible = view.getContext().getResources()
+                .getBoolean(R.bool.config_navigation_bar_enable_auto_dim_no_visible_wallpaper);
+        mDarkIntensityListeners = new ArrayList();
+
+        mView.addOnLayoutChangeListener(
+                (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
+                    View currentView = mView.getCurrentView();
+                    if (currentView != null) {
+                        mNavButtons = currentView.findViewById(R.id.nav_buttons);
+                        applyLightsOut(false, true);
+                    }
+                });
+        View currentView = mView.getCurrentView();
+        if (currentView != null) {
+            mNavButtons = currentView.findViewById(R.id.nav_buttons);
+        }
+    }
+
+    public void init() {
+        applyModeBackground(-1, getMode(), false /*animate*/);
+        applyLightsOut(false /*animate*/, true /*force*/);
+    }
+
+    @Override
+    public void destroy() {
+        mLightTransitionsController.destroy();
+    }
+
+    void setWallpaperVisibility(boolean visible) {
+        mWallpaperVisible = visible;
+        applyLightsOut(true, false);
+    }
+
+    @Override
+    public void setAutoDim(boolean autoDim) {
+        // Ensure we aren't in gestural nav if we are triggering auto dim
+        if (autoDim && isGesturalModeOnDefaultDisplay(mView.getContext(), mDisplayTracker,
+                mNavBarMode)) {
+            return;
+        }
+        if (mAutoDim == autoDim) return;
+        mAutoDim = autoDim;
+        applyLightsOut(true, false);
+    }
+
+    void setBackgroundFrame(Rect frame) {
+        mBarBackground.setFrame(frame);
+    }
+
+    void setBackgroundOverrideAlpha(float alpha) {
+        mBarBackground.setOverrideAlpha(alpha);
+    }
+
+    @Override
+    protected boolean isLightsOut(int mode) {
+        return super.isLightsOut(mode) || (mAllowAutoDimWallpaperNotVisible && mAutoDim
+                && !mWallpaperVisible && mode != MODE_WARNING);
+    }
+
+    public LightBarTransitionsController getLightTransitionsController() {
+        return mLightTransitionsController;
+    }
+
+    @Override
+    protected void onTransition(int oldMode, int newMode, boolean animate) {
+        super.onTransition(oldMode, newMode, animate);
+        applyLightsOut(animate, false /*force*/);
+        for (Listener listener : mListeners) {
+            listener.onTransition(newMode);
+        }
+    }
+
+    private void applyLightsOut(boolean animate, boolean force) {
+        // apply to lights out
+        applyLightsOut(isLightsOut(getMode()), animate, force);
+    }
+
+    private void applyLightsOut(boolean lightsOut, boolean animate, boolean force) {
+        if (!force && lightsOut == mLightsOut) return;
+
+        mLightsOut = lightsOut;
+        if (mNavButtons == null) return;
+
+        // ok, everyone, stop it right there
+        mNavButtons.animate().cancel();
+
+        // Bump percentage by 10% if dark.
+        float darkBump = mLightTransitionsController.getCurrentDarkIntensity() / 10;
+        final float navButtonsAlpha = lightsOut ? 0.6f + darkBump : 1f;
+
+        if (!animate) {
+            mNavButtons.setAlpha(navButtonsAlpha);
+        } else {
+            final int duration = lightsOut ? LIGHTS_OUT_DURATION : LIGHTS_IN_DURATION;
+            mNavButtons.animate()
+                .alpha(navButtonsAlpha)
+                .setDuration(duration)
+                .start();
+        }
+    }
+
+    public void reapplyDarkIntensity() {
+        applyDarkIntensity(mLightTransitionsController.getCurrentDarkIntensity());
+    }
+
+    @Override
+    public void applyDarkIntensity(float darkIntensity) {
+        SparseArray<ButtonDispatcher> buttonDispatchers = mView.getButtonDispatchers();
+        for (int i = buttonDispatchers.size() - 1; i >= 0; i--) {
+            buttonDispatchers.valueAt(i).setDarkIntensity(darkIntensity);
+        }
+        mView.getRotationButtonController().setDarkIntensity(darkIntensity);
+
+        for (DarkIntensityListener listener : mDarkIntensityListeners) {
+            listener.onDarkIntensity(darkIntensity);
+        }
+        if (mAutoDim) {
+            applyLightsOut(false, true);
+        }
+    }
+
+    @Override
+    public int getTintAnimationDuration() {
+        if (isGesturalModeOnDefaultDisplay(mView.getContext(), mDisplayTracker, mNavBarMode)) {
+            return Math.max(DEFAULT_COLOR_ADAPT_TRANSITION_TIME, MIN_COLOR_ADAPT_TRANSITION_TIME);
+        }
+        return LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION;
+    }
+
+    public void onNavigationModeChanged(int mode) {
+        mNavBarMode = mode;
+    }
+
+    /**
+     * Register {@code listener} to be notified when the color of nav bar elements changes.
+     *
+     * Returns the current nav bar color.
+     */
+    public float addDarkIntensityListener(DarkIntensityListener listener) {
+        mDarkIntensityListeners.add(listener);
+        return mLightTransitionsController.getCurrentDarkIntensity();
+    }
+
+    /**
+     * Remove {@code listener} from being notified when the color of nav bar elements changes.
+     */
+    public void removeDarkIntensityListener(DarkIntensityListener listener) {
+        mDarkIntensityListeners.remove(listener);
+    }
+
+    public void dump(PrintWriter pw) {
+        pw.println("NavigationBarTransitions:");
+        pw.println("  mMode: " + getMode());
+        pw.println("  mAlwaysOpaque: " + isAlwaysOpaque());
+        pw.println("  mAllowAutoDimWallpaperNotVisible: " + mAllowAutoDimWallpaperNotVisible);
+        pw.println("  mWallpaperVisible: " + mWallpaperVisible);
+        pw.println("  mLightsOut: " + mLightsOut);
+        pw.println("  mAutoDim: " + mAutoDim);
+        pw.println("  bg overrideAlpha: " + mBarBackground.getOverrideAlpha());
+        pw.println("  bg color: " + mBarBackground.getColor());
+        pw.println("  bg frame: " + mBarBackground.getFrame());
+    }
+
+    void addListener(Listener listener) {
+        mListeners.add(listener);
+    }
+
+    void removeListener(Listener listener) {
+        mListeners.remove(listener);
+    }
+
+    interface Listener {
+        void onTransition(int newMode);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java
new file mode 100644
index 0000000..0f36097
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java
@@ -0,0 +1,1212 @@
+/*
+ * 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.navigationbar.views;
+
+import static android.inputmethodservice.InputMethodService.canImeRenderGesturalNavButtons;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
+
+import static com.android.systemui.Flags.enableViewCaptureTracing;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SEARCH_DISABLED;
+import static com.android.systemui.shared.system.QuickStepContract.isGesturalMode;
+
+import android.animation.LayoutTransition;
+import android.animation.LayoutTransition.TransitionListener;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
+import android.annotation.DrawableRes;
+import android.app.StatusBarManager;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Canvas;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.media.permission.SafeCloseable;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.ContextThemeWrapper;
+import android.view.Display;
+import android.view.MotionEvent;
+import android.view.Surface;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowInsets;
+import android.view.WindowInsetsController.Behavior;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+import android.widget.FrameLayout;
+
+import androidx.annotation.Nullable;
+
+import com.android.app.animation.Interpolators;
+import com.android.app.viewcapture.ViewCaptureFactory;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.settingslib.Utils;
+import com.android.systemui.Gefingerpoken;
+import com.android.systemui.model.SysUiState;
+import com.android.systemui.navigationbar.ScreenPinningNotify;
+import com.android.systemui.navigationbar.views.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.views.buttons.ContextualButton;
+import com.android.systemui.navigationbar.views.buttons.ContextualButtonGroup;
+import com.android.systemui.navigationbar.views.buttons.DeadZone;
+import com.android.systemui.navigationbar.views.buttons.KeyButtonDrawable;
+import com.android.systemui.navigationbar.views.buttons.NearestTouchFrame;
+import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.res.R;
+import com.android.systemui.settings.DisplayTracker;
+import com.android.systemui.shade.ShadeViewController;
+import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor;
+import com.android.systemui.shared.rotation.FloatingRotationButton;
+import com.android.systemui.shared.rotation.RotationButton.RotationButtonUpdatesCallback;
+import com.android.systemui.shared.rotation.RotationButtonController;
+import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
+import com.android.systemui.statusbar.phone.LightBarTransitionsController;
+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;
+
+/** */
+public class NavigationBarView extends FrameLayout {
+    final static boolean DEBUG = false;
+    final static String TAG = "NavBarView";
+
+    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;
+    private View mHorizontal;
+
+    /** Indicates that navigation bar is vertical. */
+    private boolean mIsVertical;
+    private int mCurrentRotation = -1;
+
+    boolean mLongClickableAccessibilityButton;
+    int mDisabledFlags = 0;
+    int mNavigationIconHints = 0;
+    private int mNavBarMode;
+    private boolean mImeDrawsImeNavBar;
+
+    private KeyButtonDrawable mBackIcon;
+    private KeyButtonDrawable mHomeDefaultIcon;
+    private KeyButtonDrawable mRecentIcon;
+    private KeyButtonDrawable mDockedIcon;
+    private Context mLightContext;
+    private int mLightIconColor;
+    private int mDarkIconColor;
+
+    private EdgeBackGestureHandler mEdgeBackGestureHandler;
+    private DisplayTracker mDisplayTracker;
+    private final DeadZone mDeadZone;
+    private NavigationBarTransitions mBarTransitions;
+    @Nullable
+    private AutoHideController mAutoHideController;
+
+    // performs manual animation in sync with layout transitions
+    private final NavTransitionListener mTransitionListener = new NavTransitionListener();
+
+    private OnVerticalChangedListener mOnVerticalChangedListener;
+    private boolean mLayoutTransitionsEnabled = true;
+    private boolean mWakeAndUnlocking;
+    private boolean mUseCarModeUi = false;
+    private boolean mInCarMode = false;
+    private boolean mDockedStackExists;
+    private boolean mScreenOn = true;
+
+    private final SparseArray<ButtonDispatcher> mButtonDispatchers = new SparseArray<>();
+    private final ContextualButtonGroup mContextualButtonGroup;
+    private Configuration mConfiguration;
+    private Configuration mTmpLastConfiguration;
+
+    private NavigationBarInflaterView mNavigationInflaterView;
+    private Optional<Recents> mRecentsOptional = Optional.empty();
+    @Nullable
+    private ShadeViewController mShadeViewController;
+    @Nullable
+    private PanelExpansionInteractor mPanelExpansionInteractor;
+    private FloatingRotationButton mFloatingRotationButton;
+    private RotationButtonController mRotationButtonController;
+
+    /**
+     * Helper that is responsible for showing the right toast when a disallowed activity operation
+     * occurred. In pinned mode, we show instructions on how to break out of this mode, whilst in
+     * fully locked mode we only show that unlocking is blocked.
+     */
+    private ScreenPinningNotify mScreenPinningNotify;
+    private boolean mScreenPinningActive = false;
+
+    /**
+     * {@code true} if the IME can render the back button and the IME switcher button.
+     *
+     * <p>The value must be used when and only when
+     * {@link com.android.systemui.shared.system.QuickStepContract#isGesturalMode(int)} returns
+     * {@code true}</p>
+     *
+     * <p>Cache the value here for better performance.</p>
+     */
+    private final boolean mImeCanRenderGesturalNavButtons = canImeRenderGesturalNavButtons();
+    private Gefingerpoken mTouchHandler;
+    private boolean mOverviewProxyEnabled;
+    private boolean mShowSwipeUpUi;
+    private UpdateActiveTouchRegionsCallback mUpdateActiveTouchRegionsCallback;
+    private SafeCloseable mViewCaptureCloseable;
+
+    private class NavTransitionListener implements TransitionListener {
+        private boolean mBackTransitioning;
+        private boolean mHomeAppearing;
+        private long mStartDelay;
+        private long mDuration;
+        private TimeInterpolator mInterpolator;
+
+        @Override
+        public void startTransition(LayoutTransition transition, ViewGroup container,
+                View view, int transitionType) {
+            if (view.getId() == R.id.back) {
+                mBackTransitioning = true;
+            } else if (view.getId() == R.id.home && transitionType == LayoutTransition.APPEARING) {
+                mHomeAppearing = true;
+                mStartDelay = transition.getStartDelay(transitionType);
+                mDuration = transition.getDuration(transitionType);
+                mInterpolator = transition.getInterpolator(transitionType);
+            }
+        }
+
+        @Override
+        public void endTransition(LayoutTransition transition, ViewGroup container,
+                View view, int transitionType) {
+            if (view.getId() == R.id.back) {
+                mBackTransitioning = false;
+            } else if (view.getId() == R.id.home && transitionType == LayoutTransition.APPEARING) {
+                mHomeAppearing = false;
+            }
+        }
+
+        public void onBackAltCleared() {
+            ButtonDispatcher backButton = getBackButton();
+
+            // When dismissing ime during unlock, force the back button to run the same appearance
+            // animation as home (if we catch this condition early enough).
+            if (!mBackTransitioning && backButton.getVisibility() == VISIBLE
+                    && mHomeAppearing && getHomeButton().getAlpha() == 0) {
+                getBackButton().setAlpha(0);
+                ValueAnimator a = ObjectAnimator.ofFloat(backButton, "alpha", 0, 1);
+                a.setStartDelay(mStartDelay);
+                a.setDuration(mDuration);
+                a.setInterpolator(mInterpolator);
+                a.start();
+            }
+        }
+    }
+
+    private final AccessibilityDelegate mQuickStepAccessibilityDelegate =
+            new AccessibilityDelegate() {
+                private AccessibilityAction mToggleOverviewAction;
+
+                @Override
+                public void onInitializeAccessibilityNodeInfo(View host,
+                        AccessibilityNodeInfo info) {
+                    super.onInitializeAccessibilityNodeInfo(host, info);
+                    if (mToggleOverviewAction == null) {
+                        mToggleOverviewAction = new AccessibilityAction(
+                                R.id.action_toggle_overview, getContext().getString(
+                                R.string.quick_step_accessibility_toggle_overview));
+                    }
+                    info.addAction(mToggleOverviewAction);
+                }
+
+                @Override
+                public boolean performAccessibilityAction(View host, int action, Bundle args) {
+                    if (action == R.id.action_toggle_overview) {
+                        mRecentsOptional.ifPresent(Recents::toggleRecentApps);
+                    } else {
+                        return super.performAccessibilityAction(host, action, args);
+                    }
+                    return true;
+                }
+            };
+
+    private final RotationButtonUpdatesCallback mRotationButtonListener =
+            new RotationButtonUpdatesCallback() {
+                @Override
+                public void onVisibilityChanged(boolean visible) {
+                    if (visible && mAutoHideController != null) {
+                        // If the button will actually become visible and the navbar is about
+                        // to hide, tell the statusbar to keep it around for longer
+                        mAutoHideController.touchAutoHide();
+                    }
+                    notifyActiveTouchRegions();
+                }
+
+                @Override
+                public void onPositionChanged() {
+                    notifyActiveTouchRegions();
+                }
+            };
+
+    public NavigationBarView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        final Context darkContext = new ContextThemeWrapper(context,
+                Utils.getThemeAttr(context, R.attr.darkIconTheme));
+        mLightContext = new ContextThemeWrapper(context,
+                Utils.getThemeAttr(context, R.attr.lightIconTheme));
+        mLightIconColor = Utils.getColorAttrDefaultColor(mLightContext, R.attr.singleToneColor);
+        mDarkIconColor = Utils.getColorAttrDefaultColor(darkContext, R.attr.singleToneColor);
+        mIsVertical = false;
+        mLongClickableAccessibilityButton = false;
+
+        // Set up the context group of buttons
+        mContextualButtonGroup = new ContextualButtonGroup(R.id.menu_container);
+        final ContextualButton imeSwitcherButton = new ContextualButton(R.id.ime_switcher,
+                mLightContext, R.drawable.ic_ime_switcher_default);
+        final ContextualButton accessibilityButton =
+                new ContextualButton(R.id.accessibility_button, mLightContext,
+                        R.drawable.ic_sysbar_accessibility_button);
+        mContextualButtonGroup.addButton(imeSwitcherButton);
+        mContextualButtonGroup.addButton(accessibilityButton);
+        mFloatingRotationButton = new FloatingRotationButton(mContext,
+                R.string.accessibility_rotate_button,
+                R.layout.rotate_suggestion,
+                R.id.rotate_suggestion,
+                R.dimen.floating_rotation_button_min_margin,
+                R.dimen.rounded_corner_content_padding,
+                R.dimen.floating_rotation_button_taskbar_left_margin,
+                R.dimen.floating_rotation_button_taskbar_bottom_margin,
+                R.dimen.floating_rotation_button_diameter,
+                R.dimen.key_button_ripple_max_width,
+                R.bool.floating_rotation_button_position_left);
+        mRotationButtonController = new RotationButtonController(mLightContext, mLightIconColor,
+                mDarkIconColor, R.drawable.ic_sysbar_rotate_button_ccw_start_0,
+                R.drawable.ic_sysbar_rotate_button_ccw_start_90,
+                R.drawable.ic_sysbar_rotate_button_cw_start_0,
+                R.drawable.ic_sysbar_rotate_button_cw_start_90,
+                () -> mCurrentRotation);
+
+        mConfiguration = new Configuration();
+        mTmpLastConfiguration = new Configuration();
+        mConfiguration.updateFrom(context.getResources().getConfiguration());
+
+        mScreenPinningNotify = new ScreenPinningNotify(mContext);
+
+        mButtonDispatchers.put(R.id.back, new ButtonDispatcher(R.id.back));
+        mButtonDispatchers.put(R.id.home, new ButtonDispatcher(R.id.home));
+        mButtonDispatchers.put(R.id.home_handle, new ButtonDispatcher(R.id.home_handle));
+        mButtonDispatchers.put(R.id.recent_apps, new ButtonDispatcher(R.id.recent_apps));
+        mButtonDispatchers.put(R.id.ime_switcher, imeSwitcherButton);
+        mButtonDispatchers.put(R.id.accessibility_button, accessibilityButton);
+        mButtonDispatchers.put(R.id.menu_container, mContextualButtonGroup);
+        mDeadZone = new DeadZone(this);
+    }
+
+    public void setEdgeBackGestureHandler(EdgeBackGestureHandler edgeBackGestureHandler) {
+        mEdgeBackGestureHandler = edgeBackGestureHandler;
+    }
+
+    void setBarTransitions(NavigationBarTransitions navigationBarTransitions) {
+        mBarTransitions = navigationBarTransitions;
+    }
+
+    public void setAutoHideController(AutoHideController autoHideController) {
+        mAutoHideController = autoHideController;
+    }
+
+    public LightBarTransitionsController getLightTransitionsController() {
+        return mBarTransitions.getLightTransitionsController();
+    }
+
+    public void setComponents(Optional<Recents> recentsOptional) {
+        mRecentsOptional = recentsOptional;
+    }
+
+    /** */
+    public void setComponents(ShadeViewController svc, PanelExpansionInteractor pei) {
+        mShadeViewController = svc;
+        mPanelExpansionInteractor = pei;
+        updatePanelSystemUiStateFlags();
+    }
+
+    public void setOnVerticalChangedListener(OnVerticalChangedListener onVerticalChangedListener) {
+        mOnVerticalChangedListener = onVerticalChangedListener;
+        notifyVerticalChangedListener(mIsVertical);
+    }
+
+    public void setBackgroundExecutor(Executor bgExecutor) {
+        mBgExecutor = bgExecutor;
+        mRotationButtonController.setBgExecutor(bgExecutor);
+    }
+
+    public void setDisplayTracker(DisplayTracker displayTracker) {
+        mDisplayTracker = displayTracker;
+    }
+
+    public void setTouchHandler(Gefingerpoken touchHandler) {
+        mTouchHandler = touchHandler;
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent event) {
+        return mTouchHandler.onInterceptTouchEvent(event) || super.onInterceptTouchEvent(event);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        mTouchHandler.onTouchEvent(event);
+        return super.onTouchEvent(event);
+    }
+
+    public void abortCurrentGesture() {
+        getHomeButton().abortCurrentGesture();
+    }
+
+    public View getCurrentView() {
+        return mCurrentView;
+    }
+
+    /**
+     * Applies {@param consumer} to each of the nav bar views.
+     */
+    public void forEachView(Consumer<View> consumer) {
+        if (mVertical != null) {
+            consumer.accept(mVertical);
+        }
+        if (mHorizontal != null) {
+            consumer.accept(mHorizontal);
+        }
+    }
+
+    public RotationButtonController getRotationButtonController() {
+        return mRotationButtonController;
+    }
+
+    public FloatingRotationButton getFloatingRotationButton() {
+        return mFloatingRotationButton;
+    }
+
+    public ButtonDispatcher getRecentsButton() {
+        return mButtonDispatchers.get(R.id.recent_apps);
+    }
+
+    public ButtonDispatcher getBackButton() {
+        return mButtonDispatchers.get(R.id.back);
+    }
+
+    public ButtonDispatcher getHomeButton() {
+        return mButtonDispatchers.get(R.id.home);
+    }
+
+    public ButtonDispatcher getImeSwitchButton() {
+        return mButtonDispatchers.get(R.id.ime_switcher);
+    }
+
+    public ButtonDispatcher getAccessibilityButton() {
+        return mButtonDispatchers.get(R.id.accessibility_button);
+    }
+
+    public ButtonDispatcher getHomeHandle() {
+        return mButtonDispatchers.get(R.id.home_handle);
+    }
+
+    public SparseArray<ButtonDispatcher> getButtonDispatchers() {
+        return mButtonDispatchers;
+    }
+
+    public boolean isRecentsButtonVisible() {
+        return getRecentsButton().getVisibility() == View.VISIBLE;
+    }
+
+    public boolean isOverviewEnabled() {
+        return (mDisabledFlags & View.STATUS_BAR_DISABLE_RECENT) == 0;
+    }
+
+    private boolean isQuickStepSwipeUpEnabled() {
+        return mShowSwipeUpUi && isOverviewEnabled();
+    }
+
+    private void reloadNavIcons() {
+        updateIcons(Configuration.EMPTY);
+    }
+
+    private void updateIcons(Configuration oldConfig) {
+        final boolean orientationChange = oldConfig.orientation != mConfiguration.orientation;
+        final boolean densityChange = oldConfig.densityDpi != mConfiguration.densityDpi;
+        final boolean dirChange = oldConfig.getLayoutDirection() != mConfiguration.getLayoutDirection();
+
+        if (orientationChange || densityChange) {
+            mDockedIcon = getDrawable(R.drawable.ic_sysbar_docked);
+            mHomeDefaultIcon = getHomeDrawable();
+        }
+        if (densityChange || dirChange) {
+            mRecentIcon = getDrawable(R.drawable.ic_sysbar_recent);
+            mContextualButtonGroup.updateIcons(mLightIconColor, mDarkIconColor);
+        }
+        if (orientationChange || densityChange || dirChange) {
+            mBackIcon = getBackDrawable();
+        }
+    }
+
+    /**
+     * Updates the rotation button based on the current navigation mode.
+     */
+    void updateRotationButton() {
+        mRotationButtonController.setRotationButton(mFloatingRotationButton,
+                mRotationButtonListener);
+    }
+
+    public KeyButtonDrawable getBackDrawable() {
+        KeyButtonDrawable drawable = getDrawable(R.drawable.ic_sysbar_back);
+        orientBackButton(drawable);
+        return drawable;
+    }
+
+    public KeyButtonDrawable getHomeDrawable() {
+        KeyButtonDrawable drawable = mShowSwipeUpUi
+                ? getDrawable(R.drawable.ic_sysbar_home_quick_step)
+                : getDrawable(R.drawable.ic_sysbar_home);
+        orientHomeButton(drawable);
+        return drawable;
+    }
+
+    private void orientBackButton(KeyButtonDrawable drawable) {
+        final boolean useAltBack =
+                (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
+        final boolean isRtl = mConfiguration.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+        float degrees = useAltBack ? (isRtl ? 90 : -90) : 0;
+        if (drawable.getRotation() == degrees) {
+            return;
+        }
+
+        if (isGesturalMode(mNavBarMode)) {
+            drawable.setRotation(degrees);
+            return;
+        }
+
+        // Animate the back button's rotation to the new degrees and only in portrait move up the
+        // back button to line up with the other buttons
+        float targetY = !mShowSwipeUpUi && !mIsVertical && useAltBack
+                ? - getResources().getDimension(R.dimen.navbar_back_button_ime_offset)
+                : 0;
+        ObjectAnimator navBarAnimator = ObjectAnimator.ofPropertyValuesHolder(drawable,
+                PropertyValuesHolder.ofFloat(KeyButtonDrawable.KEY_DRAWABLE_ROTATE, degrees),
+                PropertyValuesHolder.ofFloat(KeyButtonDrawable.KEY_DRAWABLE_TRANSLATE_Y, targetY));
+        navBarAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+        navBarAnimator.setDuration(200);
+        navBarAnimator.start();
+    }
+
+    private void orientHomeButton(KeyButtonDrawable drawable) {
+        drawable.setRotation(mIsVertical ? 90 : 0);
+    }
+
+    private KeyButtonDrawable getDrawable(@DrawableRes int icon) {
+        return KeyButtonDrawable.create(mLightContext, mLightIconColor, mDarkIconColor, icon,
+                true /* hasShadow */, null /* ovalBackgroundColor */);
+    }
+
+    /** To be called when screen lock/unlock state changes */
+    public void onScreenStateChanged(boolean isScreenOn) {
+        mScreenOn = isScreenOn;
+    }
+
+    public void setWindowVisible(boolean visible) {
+        mRotationButtonController.onNavigationBarWindowVisibilityChange(visible);
+    }
+
+    public void setBehavior(@Behavior int behavior) {
+        mRotationButtonController.onBehaviorChanged(mDisplayTracker.getDefaultDisplayId(),
+                behavior);
+    }
+
+    @Override
+    public void setLayoutDirection(int layoutDirection) {
+        reloadNavIcons();
+
+        super.setLayoutDirection(layoutDirection);
+    }
+
+    void setNavigationIconHints(int hints) {
+        if (hints == mNavigationIconHints) return;
+        mNavigationIconHints = hints;
+        updateNavButtonIcons();
+    }
+
+    void onImeVisibilityChanged(boolean visible) {
+        if (!visible) {
+            mTransitionListener.onBackAltCleared();
+        }
+    }
+
+    void setDisabledFlags(int disabledFlags, SysUiState sysUiState) {
+        if (mDisabledFlags == disabledFlags) return;
+
+        final boolean overviewEnabledBefore = isOverviewEnabled();
+        mDisabledFlags = disabledFlags;
+
+        // Update icons if overview was just enabled to ensure the correct icons are present
+        if (!overviewEnabledBefore && isOverviewEnabled()) {
+            reloadNavIcons();
+        }
+
+        updateNavButtonIcons();
+        updateSlippery();
+        updateDisabledSystemUiStateFlags(sysUiState);
+    }
+
+    public void updateNavButtonIcons() {
+        // We have to replace or restore the back and home button icons when exiting or entering
+        // carmode, respectively. Recents are not available in CarMode in nav bar so change
+        // to recent icon is not required.
+        final boolean useAltBack =
+                (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
+        KeyButtonDrawable backIcon = mBackIcon;
+        orientBackButton(backIcon);
+        KeyButtonDrawable homeIcon = mHomeDefaultIcon;
+        if (!mUseCarModeUi) {
+            orientHomeButton(homeIcon);
+        }
+        getHomeButton().setImageDrawable(homeIcon);
+        getBackButton().setImageDrawable(backIcon);
+
+        updateRecentsIcon();
+
+        // Update IME button visibility, a11y and rotate button always overrides the appearance
+        boolean disableImeSwitcher =
+                (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN) == 0
+                || isImeRenderingNavButtons();
+        mContextualButtonGroup.setButtonVisibility(R.id.ime_switcher, !disableImeSwitcher);
+
+        mBarTransitions.reapplyDarkIntensity();
+
+        boolean disableHome = isGesturalMode(mNavBarMode)
+                || ((mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
+
+        // Always disable recents when alternate car mode UI is active and for secondary displays.
+        boolean disableRecent = isRecentsButtonDisabled();
+
+        // Disable the home handle if both hone and recents are disabled
+        boolean disableHomeHandle = disableRecent
+                && ((mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
+
+        boolean disableBack = !useAltBack && (mEdgeBackGestureHandler.isHandlingGestures()
+                || ((mDisabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0))
+                || isImeRenderingNavButtons();
+
+        // When screen pinning, don't hide back and home when connected service or back and
+        // recents buttons when disconnected from launcher service in screen pinning mode,
+        // as they are used for exiting.
+        if (mOverviewProxyEnabled) {
+            // Force disable recents when not in legacy mode
+            disableRecent |= !QuickStepContract.isLegacyMode(mNavBarMode);
+            if (mScreenPinningActive && !QuickStepContract.isGesturalMode(mNavBarMode)) {
+                disableBack = disableHome = false;
+            }
+        } else if (mScreenPinningActive) {
+            disableBack = disableRecent = false;
+        }
+
+        ViewGroup navButtons = getCurrentView().findViewById(R.id.nav_buttons);
+        if (navButtons != null) {
+            LayoutTransition lt = navButtons.getLayoutTransition();
+            if (lt != null) {
+                if (!lt.getTransitionListeners().contains(mTransitionListener)) {
+                    lt.addTransitionListener(mTransitionListener);
+                }
+            }
+        }
+
+        getBackButton().setVisibility(disableBack       ? View.INVISIBLE : View.VISIBLE);
+        getHomeButton().setVisibility(disableHome       ? View.INVISIBLE : View.VISIBLE);
+        getRecentsButton().setVisibility(disableRecent  ? View.INVISIBLE : View.VISIBLE);
+        getHomeHandle().setVisibility(disableHomeHandle ? View.INVISIBLE : View.VISIBLE);
+        notifyActiveTouchRegions();
+    }
+
+    /**
+     * Returns whether the IME is currently visible and drawing the nav buttons.
+     */
+    boolean isImeRenderingNavButtons() {
+        return mImeDrawsImeNavBar
+                && mImeCanRenderGesturalNavButtons
+                && (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) != 0;
+    }
+
+    @VisibleForTesting
+    boolean isRecentsButtonDisabled() {
+        return mUseCarModeUi || !isOverviewEnabled()
+                || getContext().getDisplayId() != mDisplayTracker.getDefaultDisplayId();
+    }
+
+    private Display getContextDisplay() {
+        return getContext().getDisplay();
+    }
+
+    public void setLayoutTransitionsEnabled(boolean enabled) {
+        mLayoutTransitionsEnabled = enabled;
+        updateLayoutTransitionsEnabled();
+    }
+
+    public void setWakeAndUnlocking(boolean wakeAndUnlocking) {
+        setUseFadingAnimations(wakeAndUnlocking);
+        mWakeAndUnlocking = wakeAndUnlocking;
+        updateLayoutTransitionsEnabled();
+    }
+
+    private void updateLayoutTransitionsEnabled() {
+        boolean enabled = !mWakeAndUnlocking && mLayoutTransitionsEnabled;
+        ViewGroup navButtons = (ViewGroup) getCurrentView().findViewById(R.id.nav_buttons);
+        LayoutTransition lt = navButtons.getLayoutTransition();
+        if (lt != null) {
+            if (enabled) {
+                lt.enableTransitionType(LayoutTransition.APPEARING);
+                lt.enableTransitionType(LayoutTransition.DISAPPEARING);
+                lt.enableTransitionType(LayoutTransition.CHANGE_APPEARING);
+                lt.enableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
+            } else {
+                lt.disableTransitionType(LayoutTransition.APPEARING);
+                lt.disableTransitionType(LayoutTransition.DISAPPEARING);
+                lt.disableTransitionType(LayoutTransition.CHANGE_APPEARING);
+                lt.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
+            }
+        }
+    }
+
+    private void setUseFadingAnimations(boolean useFadingAnimations) {
+        WindowManager.LayoutParams lp = (WindowManager.LayoutParams) ((ViewGroup) getParent())
+                .getLayoutParams();
+        if (lp != null) {
+            boolean old = lp.windowAnimations != 0;
+            if (!old && useFadingAnimations) {
+                lp.windowAnimations = R.style.Animation_NavigationBarFadeIn;
+            } else if (old && !useFadingAnimations) {
+                lp.windowAnimations = 0;
+            } else {
+                return;
+            }
+            WindowManager wm = getContext().getSystemService(WindowManager.class);
+            wm.updateViewLayout((View) getParent(), lp);
+        }
+    }
+
+    public void onStatusBarPanelStateChanged() {
+        updateSlippery();
+    }
+
+    /** */
+    public void updateDisabledSystemUiStateFlags(SysUiState sysUiState) {
+        int displayId = mContext.getDisplayId();
+
+        sysUiState.setFlag(SYSUI_STATE_OVERVIEW_DISABLED,
+                        (mDisabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0)
+                .setFlag(SYSUI_STATE_HOME_DISABLED,
+                        (mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0)
+                .setFlag(SYSUI_STATE_SEARCH_DISABLED,
+                        (mDisabledFlags & View.STATUS_BAR_DISABLE_SEARCH) != 0)
+                .commitUpdate(displayId);
+    }
+
+    public void setInScreenPinning(boolean active) {
+        mScreenPinningActive = active;
+    }
+
+    private void updatePanelSystemUiStateFlags() {
+        if (SysUiState.DEBUG) {
+            Log.d(TAG, "Updating panel sysui state flags: panelView=" + mShadeViewController);
+        }
+        if (mShadeViewController != null) {
+            mShadeViewController.updateSystemUiStateFlags();
+        }
+    }
+
+    void onOverviewProxyConnectionChange(boolean enabled) {
+        mOverviewProxyEnabled = enabled;
+    }
+
+    void setShouldShowSwipeUpUi(boolean showSwipeUpUi) {
+        mShowSwipeUpUi = showSwipeUpUi;
+        updateStates();
+    }
+
+    /** */
+    public void updateStates() {
+        if (mNavigationInflaterView != null) {
+            // Reinflate the navbar if needed, no-op unless the swipe up state changes
+            mNavigationInflaterView.onLikelyDefaultLayoutChange();
+        }
+
+        updateSlippery();
+        reloadNavIcons();
+        updateNavButtonIcons();
+        mBgExecutor.execute(() -> setNavBarVirtualKeyHapticFeedbackEnabled(!mShowSwipeUpUi));
+        getHomeButton().setAccessibilityDelegate(
+                mShowSwipeUpUi ? mQuickStepAccessibilityDelegate : null);
+    }
+
+    /**
+     * Enable or disable haptic feedback on the navigation bar buttons.
+     */
+    private void setNavBarVirtualKeyHapticFeedbackEnabled(boolean enabled) {
+        try {
+            WindowManagerGlobal.getWindowManagerService()
+                    .setNavBarVirtualKeyHapticFeedbackEnabled(enabled);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to enable or disable navigation bar button haptics: ", e);
+        }
+    }
+
+    /**
+     * Updates the {@link WindowManager.LayoutParams.FLAG_SLIPPERY} state dependent on if swipe up
+     * is enabled, or the notifications is fully opened without being in an animated state. If
+     * slippery is enabled, touch events will leave the nav bar window and enter into the fullscreen
+     * app/home window, if not nav bar will receive a cancelled touch event once gesture leaves bar.
+     */
+    void updateSlippery() {
+        setSlippery(!isQuickStepSwipeUpEnabled() ||
+                (mPanelExpansionInteractor != null && mPanelExpansionInteractor.isFullyExpanded()
+                        && !mPanelExpansionInteractor.isCollapsing()));
+    }
+
+    void setSlippery(boolean slippery) {
+        setWindowFlag(WindowManager.LayoutParams.FLAG_SLIPPERY, slippery);
+    }
+
+    private void setWindowFlag(int flags, boolean enable) {
+        final ViewGroup navbarView = ((ViewGroup) getParent());
+        if (navbarView == null) {
+            return;
+        }
+        WindowManager.LayoutParams lp = (WindowManager.LayoutParams) navbarView.getLayoutParams();
+        if (lp == null || enable == ((lp.flags & flags) != 0)) {
+            return;
+        }
+        if (enable) {
+            lp.flags |= flags;
+        } else {
+            lp.flags &= ~flags;
+        }
+        WindowManager wm = getContext().getSystemService(WindowManager.class);
+        wm.updateViewLayout(navbarView, lp);
+    }
+
+    void setNavBarMode(int mode, boolean imeDrawsImeNavBar) {
+        mNavBarMode = mode;
+        mImeDrawsImeNavBar = imeDrawsImeNavBar;
+        mBarTransitions.onNavigationModeChanged(mNavBarMode);
+        mEdgeBackGestureHandler.onNavigationModeChanged(mNavBarMode);
+        mRotationButtonController.onNavigationModeChanged(mNavBarMode);
+        updateRotationButton();
+    }
+
+    public void setAccessibilityButtonState(final boolean visible, final boolean longClickable) {
+        mLongClickableAccessibilityButton = longClickable;
+        getAccessibilityButton().setLongClickable(longClickable);
+        mContextualButtonGroup.setButtonVisibility(R.id.accessibility_button, visible);
+    }
+
+    @Override
+    public void onFinishInflate() {
+        super.onFinishInflate();
+        mNavigationInflaterView = findViewById(R.id.navigation_inflater);
+        mNavigationInflaterView.setButtonDispatchers(mButtonDispatchers);
+
+        updateOrientationViews();
+        reloadNavIcons();
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        mDeadZone.onDraw(canvas);
+        super.onDraw(canvas);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+
+        notifyActiveTouchRegions();
+    }
+
+    /**
+     * Notifies the overview service of the active touch regions.
+     */
+    public void notifyActiveTouchRegions() {
+        if (mUpdateActiveTouchRegionsCallback != null) {
+            mUpdateActiveTouchRegionsCallback.update();
+        }
+    }
+
+    void setUpdateActiveTouchRegionsCallback(UpdateActiveTouchRegionsCallback callback) {
+        mUpdateActiveTouchRegionsCallback = callback;
+        notifyActiveTouchRegions();
+    }
+
+    Map<View, Rect> getButtonTouchRegionCache() {
+        FrameLayout navBarLayout = mIsVertical
+                ? mNavigationInflaterView.mVertical
+                : mNavigationInflaterView.mHorizontal;
+        return ((NearestTouchFrame) navBarLayout
+                .findViewById(R.id.nav_buttons)).getFullTouchableChildRegions();
+    }
+
+    private void updateOrientationViews() {
+        mHorizontal = findViewById(R.id.horizontal);
+        mVertical = findViewById(R.id.vertical);
+
+        updateCurrentView();
+    }
+
+    boolean needsReorient(int rotation) {
+        return mCurrentRotation != rotation;
+    }
+
+    private void updateCurrentRotation() {
+        final int rotation = mConfiguration.windowConfiguration.getDisplayRotation();
+        if (mCurrentRotation == rotation) {
+            return;
+        }
+        mCurrentRotation = rotation;
+        mNavigationInflaterView.setAlternativeOrder(mCurrentRotation == Surface.ROTATION_90);
+        mDeadZone.onConfigurationChanged(mCurrentRotation);
+        if (DEBUG) {
+            Log.d(TAG, "updateCurrentRotation(): rot=" + mCurrentRotation);
+        }
+    }
+
+    private void updateCurrentView() {
+        resetViews();
+        mCurrentView = mIsVertical ? mVertical : mHorizontal;
+        mCurrentView.setVisibility(View.VISIBLE);
+        mNavigationInflaterView.setVertical(mIsVertical);
+        mNavigationInflaterView.updateButtonDispatchersCurrentView();
+        updateLayoutTransitionsEnabled();
+        updateCurrentRotation();
+    }
+
+    private void resetViews() {
+        mHorizontal.setVisibility(View.GONE);
+        mVertical.setVisibility(View.GONE);
+    }
+
+    private void updateRecentsIcon() {
+        mDockedIcon.setRotation(mDockedStackExists && mIsVertical ? 90 : 0);
+        getRecentsButton().setImageDrawable(mDockedStackExists ? mDockedIcon : mRecentIcon);
+        mBarTransitions.reapplyDarkIntensity();
+    }
+
+    public void showPinningEnterExitToast(boolean entering) {
+        if (entering) {
+            mScreenPinningNotify.showPinningStartToast();
+        } else {
+            mScreenPinningNotify.showPinningExitToast();
+        }
+    }
+
+    public void showPinningEscapeToast() {
+        mScreenPinningNotify.showEscapeToast(
+                mNavBarMode == NAV_BAR_MODE_GESTURAL, isRecentsButtonVisible());
+    }
+
+    public boolean isVertical() {
+        return mIsVertical;
+    }
+
+    public void reorient() {
+        updateCurrentView();
+        ((NavigationBarFrame) getRootView()).setDeadZone(mDeadZone);
+
+        // force the low profile & disabled states into compliance
+        mBarTransitions.init();
+
+        // Resolve layout direction if not resolved since components changing layout direction such
+        // as changing languages will recreate this view and the direction will be resolved later
+        if (!isLayoutDirectionResolved()) {
+            resolveLayoutDirection();
+        }
+        updateNavButtonIcons();
+
+        getHomeButton().setVertical(mIsVertical);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int w = MeasureSpec.getSize(widthMeasureSpec);
+        int h = MeasureSpec.getSize(heightMeasureSpec);
+        if (DEBUG) Log.d(TAG, String.format(
+                "onMeasure: (%dx%d) old: (%dx%d)", w, h, getMeasuredWidth(), getMeasuredHeight()));
+
+        final boolean newVertical = w > 0 && h > w
+                && !isGesturalMode(mNavBarMode);
+        if (newVertical != mIsVertical) {
+            mIsVertical = newVertical;
+            if (DEBUG) {
+                Log.d(TAG, String.format("onMeasure: h=%d, w=%d, vert=%s", h, w,
+                        mIsVertical ? "y" : "n"));
+            }
+            reorient();
+            notifyVerticalChangedListener(newVertical);
+        }
+
+        if (isGesturalMode(mNavBarMode)) {
+            // Update the nav bar background to match the height of the visible nav bar
+            int height = mIsVertical
+                    ? getResources().getDimensionPixelSize(
+                            com.android.internal.R.dimen.navigation_bar_height_landscape)
+                    : getResources().getDimensionPixelSize(
+                            com.android.internal.R.dimen.navigation_bar_height);
+            int frameHeight = getResources().getDimensionPixelSize(
+                    com.android.internal.R.dimen.navigation_bar_frame_height);
+            mBarTransitions.setBackgroundFrame(new Rect(0, frameHeight - height, w, h));
+        } else {
+            mBarTransitions.setBackgroundFrame(null);
+        }
+
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+    }
+
+    int getNavBarHeight() {
+        return mIsVertical
+                ? getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.navigation_bar_height_landscape)
+                : getResources().getDimensionPixelSize(
+                        com.android.internal.R.dimen.navigation_bar_height);
+    }
+
+    private void notifyVerticalChangedListener(boolean newVertical) {
+        if (mOnVerticalChangedListener != null) {
+            mOnVerticalChangedListener.onVerticalChanged(newVertical);
+        }
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        mTmpLastConfiguration.updateFrom(mConfiguration);
+        final int changes = mConfiguration.updateFrom(newConfig);
+        mFloatingRotationButton.onConfigurationChanged(changes);
+
+        boolean uiCarModeChanged = updateCarMode();
+        updateIcons(mTmpLastConfiguration);
+        updateRecentsIcon();
+        updateCurrentRotation();
+        if (uiCarModeChanged || mTmpLastConfiguration.densityDpi != mConfiguration.densityDpi
+                || mTmpLastConfiguration.getLayoutDirection() != mConfiguration.getLayoutDirection()) {
+            // If car mode or density changes, we need to reset the icons.
+            updateNavButtonIcons();
+        }
+    }
+
+    /**
+     * If the configuration changed, update the carmode and return that it was updated.
+     */
+    private boolean updateCarMode() {
+        boolean uiCarModeChanged = false;
+        if (mConfiguration != null) {
+            int uiMode = mConfiguration.uiMode & Configuration.UI_MODE_TYPE_MASK;
+            final boolean isCarMode = (uiMode == Configuration.UI_MODE_TYPE_CAR);
+
+            if (isCarMode != mInCarMode) {
+                mInCarMode = isCarMode;
+                if (ALTERNATE_CAR_MODE_UI) {
+                    mUseCarModeUi = isCarMode;
+                    uiCarModeChanged = true;
+                } else {
+                    // Don't use car mode behavior if ALTERNATE_CAR_MODE_UI not set.
+                    mUseCarModeUi = false;
+                }
+            }
+        }
+        return uiCarModeChanged;
+    }
+
+    private String getResourceName(int resId) {
+        if (resId != 0) {
+            final android.content.res.Resources res = getContext().getResources();
+            try {
+                return res.getResourceName(resId);
+            } catch (android.content.res.Resources.NotFoundException ex) {
+                return "(unknown)";
+            }
+        } else {
+            return "(null)";
+        }
+    }
+
+    private static String visibilityToString(int vis) {
+        switch (vis) {
+            case View.INVISIBLE:
+                return "INVISIBLE";
+            case View.GONE:
+                return "GONE";
+            default:
+                return "VISIBLE";
+        }
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        requestApplyInsets();
+        reorient();
+        if (mRotationButtonController != null) {
+            mRotationButtonController.registerListeners(false /* registerRotationWatcher */);
+        }
+
+        updateNavButtonIcons();
+        if (enableViewCaptureTracing()) {
+            mViewCaptureCloseable = ViewCaptureFactory.getInstance(getContext())
+                    .startCapture(getRootView(), ".NavigationBarView");
+        }
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        for (int i = 0; i < mButtonDispatchers.size(); ++i) {
+            mButtonDispatchers.valueAt(i).onDestroy();
+        }
+        if (mRotationButtonController != null) {
+            mFloatingRotationButton.hide();
+            mRotationButtonController.unregisterListeners();
+        }
+        if (mViewCaptureCloseable != null) {
+            mViewCaptureCloseable.close();
+        }
+    }
+
+    void dump(PrintWriter pw) {
+        final Rect r = new Rect();
+        final Point size = new Point();
+        getContextDisplay().getRealSize(size);
+
+        pw.println("NavigationBarView:");
+        pw.println(String.format("      this: " + CentralSurfaces.viewInfo(this)
+                        + " " + visibilityToString(getVisibility())));
+
+        getWindowVisibleDisplayFrame(r);
+        final boolean offscreen = r.right > size.x || r.bottom > size.y;
+        pw.println("      window: "
+                + r.toShortString()
+                + " " + visibilityToString(getWindowVisibility())
+                + (offscreen ? " OFFSCREEN!" : ""));
+
+        pw.println(String.format("      mCurrentView: id=%s (%dx%d) %s %f",
+                        getResourceName(getCurrentView().getId()),
+                        getCurrentView().getWidth(), getCurrentView().getHeight(),
+                        visibilityToString(getCurrentView().getVisibility()),
+                        getCurrentView().getAlpha()));
+
+        pw.println(String.format("      disabled=0x%08x vertical=%s darkIntensity=%.2f",
+                        mDisabledFlags,
+                        mIsVertical ? "true" : "false",
+                        getLightTransitionsController().getCurrentDarkIntensity()));
+
+        pw.println("    mScreenOn: " + mScreenOn);
+
+
+        dumpButton(pw, "back", getBackButton());
+        dumpButton(pw, "home", getHomeButton());
+        dumpButton(pw, "handle", getHomeHandle());
+        dumpButton(pw, "rcnt", getRecentsButton());
+        dumpButton(pw, "a11y", getAccessibilityButton());
+        dumpButton(pw, "ime", getImeSwitchButton());
+
+        if (mNavigationInflaterView != null) {
+            mNavigationInflaterView.dump(pw);
+        }
+        mBarTransitions.dump(pw);
+        mContextualButtonGroup.dump(pw);
+        mEdgeBackGestureHandler.dump(pw);
+    }
+
+    @Override
+    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+        int leftInset = insets.getSystemWindowInsetLeft();
+        int rightInset = insets.getSystemWindowInsetRight();
+        setPadding(leftInset, insets.getSystemWindowInsetTop(), rightInset,
+                insets.getSystemWindowInsetBottom());
+        // we're passing the insets onto the gesture handler since the back arrow is only
+        // conditionally added and doesn't always get all the insets.
+        mEdgeBackGestureHandler.setInsets(leftInset, rightInset);
+
+        // this allows assist handle to be drawn outside its bound so that it can align screen
+        // bottom by translating its y position.
+        final boolean shouldClip =
+                !isGesturalMode(mNavBarMode) || insets.getSystemWindowInsetBottom() == 0;
+        setClipChildren(shouldClip);
+        setClipToPadding(shouldClip);
+
+        return super.onApplyWindowInsets(insets);
+    }
+
+    void addPipExclusionBoundsChangeListener(Pip pip) {
+        pip.addPipExclusionBoundsChangeListener(mPipListener);
+    }
+
+    void removePipExclusionBoundsChangeListener(Pip pip) {
+        pip.removePipExclusionBoundsChangeListener(mPipListener);
+    }
+
+    void registerBackAnimation(BackAnimation backAnimation) {
+        mEdgeBackGestureHandler.setBackAnimation(backAnimation);
+    }
+
+    private static void dumpButton(PrintWriter pw, String caption, ButtonDispatcher button) {
+        pw.print("      " + caption + ": ");
+        if (button == null) {
+            pw.print("null");
+        } else {
+            pw.print(visibilityToString(button.getVisibility())
+                    + " alpha=" + button.getAlpha()
+                    );
+        }
+        pw.println();
+    }
+
+    public interface OnVerticalChangedListener {
+        void onVerticalChanged(boolean isVertical);
+    }
+
+    private final Consumer<Boolean> mDockedListener = exists -> post(() -> {
+        mDockedStackExists = exists;
+        updateRecentsIcon();
+    });
+
+    private final Consumer<Rect> mPipListener = bounds -> post(() -> {
+        mEdgeBackGestureHandler.setPipStashExclusionBounds(bounds);
+    });
+
+
+    interface UpdateActiveTouchRegionsCallback {
+        void update();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ButtonDispatcher.java
new file mode 100644
index 0000000..6799a4f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ButtonDispatcher.java
@@ -0,0 +1,378 @@
+/*
+ * 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.navigationbar.views.buttons;
+
+import static com.android.app.animation.Interpolators.LINEAR;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.view.View;
+import android.view.View.AccessibilityDelegate;
+import android.view.ViewGroup;
+
+import java.util.ArrayList;
+
+/**
+ * Dispatches common view calls to multiple views.  This is used to handle
+ * multiples of the same nav bar icon appearing.
+ */
+public class ButtonDispatcher {
+    private static final int FADE_DURATION_IN = 150;
+    private static final int FADE_DURATION_OUT = 250;
+
+    private final ArrayList<View> mViews = new ArrayList<>();
+
+    private final int mId;
+
+    private View.OnClickListener mClickListener;
+    private View.OnTouchListener mTouchListener;
+    private View.OnLongClickListener mLongClickListener;
+    private View.OnHoverListener mOnHoverListener;
+    private Boolean mLongClickable;
+    private Float mAlpha;
+    private Float mDarkIntensity;
+    private Integer mVisibility = View.VISIBLE;
+    private Boolean mDelayTouchFeedback;
+    private KeyButtonDrawable mImageDrawable;
+    private View mCurrentView;
+    private boolean mVertical;
+    private ValueAnimator mFadeAnimator;
+    private AccessibilityDelegate mAccessibilityDelegate;
+    private NavBarButtonClickLogger mNavBarButtonClickLogger;
+
+    private final ValueAnimator.AnimatorUpdateListener mAlphaListener = animation ->
+            setAlpha(
+                    (float) animation.getAnimatedValue(),
+                    false /* animate */,
+                    false /* cancelAnimator */);
+
+    private final AnimatorListenerAdapter mFadeListener = new AnimatorListenerAdapter() {
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            mFadeAnimator = null;
+            setVisibility(getAlpha() == 1 ? View.VISIBLE : View.INVISIBLE);
+        }
+    };
+
+    public ButtonDispatcher(int id) {
+        mId = id;
+    }
+
+    public void clear() {
+        mViews.clear();
+    }
+
+    public void addView(View view) {
+        mViews.add(view);
+        view.setOnClickListener(mClickListener);
+        view.setOnTouchListener(mTouchListener);
+        view.setOnLongClickListener(mLongClickListener);
+        view.setOnHoverListener(mOnHoverListener);
+        if (mLongClickable != null) {
+            view.setLongClickable(mLongClickable);
+        }
+        if (mAlpha != null) {
+            view.setAlpha(mAlpha);
+        }
+        if (mVisibility != null) {
+            view.setVisibility(mVisibility);
+        }
+        if (mAccessibilityDelegate != null) {
+            view.setAccessibilityDelegate(mAccessibilityDelegate);
+        }
+        if (view instanceof ButtonInterface) {
+            final ButtonInterface button = (ButtonInterface) view;
+            if (mDarkIntensity != null) {
+                button.setDarkIntensity(mDarkIntensity);
+            }
+            if (mImageDrawable != null) {
+                button.setImageDrawable(mImageDrawable);
+            }
+            if (mDelayTouchFeedback != null) {
+                button.setDelayTouchFeedback(mDelayTouchFeedback);
+            }
+            button.setVertical(mVertical);
+        }
+    }
+
+    public int getId() {
+        return mId;
+    }
+
+    public int getVisibility() {
+        return mVisibility != null ? mVisibility : View.VISIBLE;
+    }
+
+    public boolean isVisible() {
+        return getVisibility() == View.VISIBLE;
+    }
+
+    public float getAlpha() {
+        return mAlpha != null ? mAlpha : 1;
+    }
+
+    public KeyButtonDrawable getImageDrawable() {
+        return mImageDrawable;
+    }
+
+    public void setImageDrawable(KeyButtonDrawable drawable) {
+        mImageDrawable = drawable;
+        final int N = mViews.size();
+        for (int i = 0; i < N; i++) {
+            if (mViews.get(i) instanceof ButtonInterface) {
+                ((ButtonInterface) mViews.get(i)).setImageDrawable(mImageDrawable);
+            }
+        }
+        if (mImageDrawable != null) {
+            mImageDrawable.setCallback(mCurrentView);
+        }
+    }
+
+    public void setVisibility(int visibility) {
+        if (mVisibility == visibility) return;
+        if (mFadeAnimator != null) {
+            mFadeAnimator.cancel();
+        }
+
+        mVisibility = visibility;
+        final int N = mViews.size();
+        for (int i = 0; i < N; i++) {
+            mViews.get(i).setVisibility(mVisibility);
+        }
+    }
+
+    public void abortCurrentGesture() {
+        // This seems to be an instantaneous thing, so not going to persist it.
+        final int N = mViews.size();
+        for (int i = 0; i < N; i++) {
+            if (mViews.get(i) instanceof ButtonInterface) {
+                ((ButtonInterface) mViews.get(i)).abortCurrentGesture();
+            }
+        }
+    }
+
+    public void setAlpha(float alpha) {
+        setAlpha(alpha, false /* animate */);
+    }
+
+    public void setAlpha(float alpha, boolean animate) {
+        setAlpha(alpha, animate, true /* cancelAnimator */);
+    }
+
+    public void setAlpha(float alpha, boolean animate, long duration) {
+        setAlpha(alpha, animate, duration, true /* cancelAnimator */);
+    }
+
+    public void setAlpha(float alpha, boolean animate, boolean cancelAnimator) {
+        setAlpha(
+                alpha,
+                animate,
+                (getAlpha() < alpha) ? FADE_DURATION_IN : FADE_DURATION_OUT,
+                cancelAnimator);
+    }
+
+    public void setAlpha(float alpha, boolean animate, long duration, boolean cancelAnimator) {
+        if (mFadeAnimator != null && (cancelAnimator || animate)) {
+            mFadeAnimator.cancel();
+        }
+        if (animate) {
+            setVisibility(View.VISIBLE);
+            mFadeAnimator = ValueAnimator.ofFloat(getAlpha(), alpha);
+            mFadeAnimator.setDuration(duration);
+            mFadeAnimator.setInterpolator(LINEAR);
+            mFadeAnimator.addListener(mFadeListener);
+            mFadeAnimator.addUpdateListener(mAlphaListener);
+            mFadeAnimator.start();
+        } else {
+            // Discretize the alpha updates to prevent too frequent updates when there is a long
+            // alpha animation
+            int prevAlpha = (int) (getAlpha() * 255);
+            int nextAlpha = (int) (alpha * 255);
+            if (prevAlpha != nextAlpha) {
+                mAlpha = nextAlpha / 255f;
+                final int N = mViews.size();
+                for (int i = 0; i < N; i++) {
+                    mViews.get(i).setAlpha(mAlpha);
+                }
+            }
+        }
+    }
+
+    public void setDarkIntensity(float darkIntensity) {
+        mDarkIntensity = darkIntensity;
+        final int N = mViews.size();
+        for (int i = 0; i < N; i++) {
+            if (mViews.get(i) instanceof ButtonInterface) {
+                ((ButtonInterface) mViews.get(i)).setDarkIntensity(darkIntensity);
+            }
+        }
+    }
+
+    public void setDelayTouchFeedback(boolean delay) {
+        mDelayTouchFeedback = delay;
+        final int N = mViews.size();
+        for (int i = 0; i < N; i++) {
+            if (mViews.get(i) instanceof ButtonInterface) {
+                ((ButtonInterface) mViews.get(i)).setDelayTouchFeedback(delay);
+            }
+        }
+    }
+
+    public void setOnClickListener(View.OnClickListener clickListener) {
+        mClickListener = clickListener;
+        final int N = mViews.size();
+        for (int i = 0; i < N; i++) {
+            mViews.get(i).setOnClickListener(mClickListener);
+        }
+    }
+
+    public void setOnTouchListener(View.OnTouchListener touchListener) {
+        mTouchListener = touchListener;
+        final int N = mViews.size();
+        for (int i = 0; i < N; i++) {
+            mViews.get(i).setOnTouchListener(mTouchListener);
+        }
+    }
+
+    public void animateLongPress(boolean isTouchDown, boolean shrink, long durationMs) {
+        for (int i = 0; i < mViews.size(); i++) {
+            if (mViews.get(i) instanceof ButtonInterface) {
+                ((ButtonInterface) mViews.get(i)).animateLongPress(isTouchDown, shrink, durationMs);
+            }
+        }
+    }
+
+    public void setLongClickable(boolean isLongClickable) {
+        mLongClickable = isLongClickable;
+        final int N = mViews.size();
+        for (int i = 0; i < N; i++) {
+            mViews.get(i).setLongClickable(mLongClickable);
+        }
+    }
+
+    public void setOnLongClickListener(View.OnLongClickListener longClickListener) {
+        mLongClickListener = longClickListener;
+        final int N = mViews.size();
+        for (int i = 0; i < N; i++) {
+            mViews.get(i).setOnLongClickListener(mLongClickListener);
+        }
+    }
+
+    public void setOnHoverListener(View.OnHoverListener hoverListener) {
+        mOnHoverListener = hoverListener;
+        final int N = mViews.size();
+        for (int i = 0; i < N; i++) {
+            mViews.get(i).setOnHoverListener(mOnHoverListener);
+        }
+    }
+
+    public void setAccessibilityDelegate(AccessibilityDelegate delegate) {
+        mAccessibilityDelegate = delegate;
+        final int N = mViews.size();
+        for (int i = 0; i < N; i++) {
+            mViews.get(i).setAccessibilityDelegate(delegate);
+        }
+    }
+
+    public void setClickable(boolean clickable) {
+        abortCurrentGesture();
+        final int N = mViews.size();
+        for (int i = 0; i < N; i++) {
+            mViews.get(i).setClickable(clickable);
+        }
+    }
+
+    public void setTranslation(int x, int y, int z) {
+        final int N = mViews.size();
+        for (int i = 0; i < N; i++) {
+            final View view = mViews.get(i);
+            view.setTranslationX(x);
+            view.setTranslationY(y);
+            view.setTranslationZ(z);
+        }
+    }
+
+    public ArrayList<View> getViews() {
+        return mViews;
+    }
+
+    public View getCurrentView() {
+        return mCurrentView;
+    }
+
+    public void setCurrentView(View currentView) {
+        mCurrentView = currentView.findViewById(mId);
+        if (mImageDrawable != null) {
+            mImageDrawable.setCallback(mCurrentView);
+        }
+        if (mCurrentView != null) {
+            mCurrentView.setTranslationX(0);
+            mCurrentView.setTranslationY(0);
+            mCurrentView.setTranslationZ(0);
+        }
+    }
+
+    public void setVertical(boolean vertical) {
+        mVertical = vertical;
+        final int N = mViews.size();
+        for (int i = 0; i < N; i++) {
+            final View view = mViews.get(i);
+            if (view instanceof ButtonInterface) {
+                ((ButtonInterface) view).setVertical(vertical);
+            }
+        }
+    }
+
+    /**
+     * Executes when button is detached from window.
+     */
+    public void onDestroy() {
+    }
+
+    /**
+     * Sets the NavBarButtonClickLogger for all the KeyButtonViews respectively.
+     */
+    public void setNavBarButtonClickLogger(NavBarButtonClickLogger navBarButtonClickLogger) {
+        if (navBarButtonClickLogger != null) {
+            mNavBarButtonClickLogger = navBarButtonClickLogger;
+            final int size = mViews.size();
+            for (int i = 0; i < size; i++) {
+                final View v = mViews.get(i);
+                setNavBarButtonClickLoggerForViewChildren(v);
+            }
+        }
+    }
+
+    /**
+     * Recursively explores view hierarchy until the children of provided view are of type
+     * KeyButtonView, so the NavBarButtonClickLogger can be set on them.
+     */
+    private void setNavBarButtonClickLoggerForViewChildren(View v) {
+        if (v instanceof KeyButtonView) {
+            ((KeyButtonView) v).setNavBarButtonClickLogger(mNavBarButtonClickLogger);
+            return;
+        }
+
+        if (v instanceof ViewGroup viewGroup) {
+            final int childrenCount = viewGroup.getChildCount();
+            for (int i = 0; i < childrenCount; i++) {
+                setNavBarButtonClickLoggerForViewChildren(viewGroup.getChildAt(i));
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ButtonInterface.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ButtonInterface.java
new file mode 100644
index 0000000..c1b4944
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ButtonInterface.java
@@ -0,0 +1,44 @@
+/*
+ * 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.navigationbar.views.buttons;
+
+import android.annotation.Nullable;
+import android.graphics.drawable.Drawable;
+
+public interface ButtonInterface {
+
+    void setImageDrawable(@Nullable Drawable drawable);
+
+    void abortCurrentGesture();
+
+    void setVertical(boolean vertical);
+
+    void setDarkIntensity(float intensity);
+
+    void setDelayTouchFeedback(boolean shouldDelay);
+
+    /**
+     * Animate the button being long-pressed.
+     *
+     * @param isTouchDown {@code true} if the button is starting to be pressed ({@code false} if
+     *                    released or canceled)
+     * @param shrink      {@code true} if the handle should shrink, {@code false} if it should grow
+     * @param durationMs  how long the animation should take (for the {@code isTouchDown} case, this
+     *                    should be the same as the amount of time to trigger a long-press)
+     */
+    default void animateLongPress(boolean isTouchDown, boolean shrink, long durationMs) {}
+}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ContextualButton.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ContextualButton.java
new file mode 100644
index 0000000..5e6bfa8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ContextualButton.java
@@ -0,0 +1,127 @@
+/*
+ * 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.navigationbar.views.buttons;
+
+import android.annotation.DrawableRes;
+import android.annotation.IdRes;
+import android.annotation.NonNull;
+import android.content.Context;
+import android.view.View;
+
+/**
+ * Simple contextual button that is added to the {@link ContextualButtonGroup}. Extend if need extra
+ * functionality.
+ */
+public class ContextualButton extends ButtonDispatcher {
+
+    private ContextButtonListener mListener;
+    private ContextualButtonGroup mGroup;
+
+    protected final Context mLightContext;
+    protected final @DrawableRes int mIconResId;
+
+    /**
+      * Create a contextual button that will use a {@link KeyButtonView} and
+      * {@link KeyButtonDrawable} get and show the button from xml to its icon drawable.
+      * @param buttonResId the button view from xml layout
+      * @param iconResId icon resource to be used
+      */
+    public ContextualButton(@IdRes int buttonResId, Context lightContext,
+            @DrawableRes int iconResId) {
+        super(buttonResId);
+        mLightContext = lightContext;
+        mIconResId = iconResId;
+    }
+
+    /**
+     * Reload the drawable from resource id, should reapply the previous dark intensity.
+     */
+    public void updateIcon(int lightIconColor, int darkIconColor) {
+        if (mIconResId == 0) {
+            return;
+        }
+        final KeyButtonDrawable currentDrawable = getImageDrawable();
+        KeyButtonDrawable drawable = getNewDrawable(lightIconColor, darkIconColor);
+        if (currentDrawable != null) {
+            drawable.setDarkIntensity(currentDrawable.getDarkIntensity());
+        }
+        setImageDrawable(drawable);
+    }
+
+    @Override
+    public void setVisibility(int visibility) {
+        super.setVisibility(visibility);
+
+        // Stop any active animations if hidden
+        final KeyButtonDrawable currentDrawable = getImageDrawable();
+        if (visibility != View.VISIBLE && currentDrawable != null && currentDrawable.canAnimate()) {
+            currentDrawable.clearAnimationCallbacks();
+            currentDrawable.resetAnimation();
+        }
+
+        if (mListener != null) {
+            mListener.onVisibilityChanged(this, visibility == View.VISIBLE);
+        }
+    }
+
+    public void setListener(ContextButtonListener listener) {
+        mListener = listener;
+    }
+
+    /**
+     * Show this button based on its priority compared to other buttons in the group. If not
+     * attached to a group it will set its own visibility to be visible.
+     * @return if visible
+     */
+    public boolean show() {
+        if (mGroup == null) {
+            setVisibility(View.VISIBLE);
+            return true;
+        }
+        return mGroup.setButtonVisibility(getId(), true /* visible */) == View.VISIBLE;
+    }
+
+    /**
+     * Hide this button.
+     * @return if visible
+     */
+    public boolean hide() {
+        if (mGroup == null) {
+            setVisibility(View.INVISIBLE);
+            return false;
+        }
+        return mGroup.setButtonVisibility(getId(), false /* visible */) != View.VISIBLE;
+    }
+
+    /**
+     * Called when this button was added to the group. Keep a reference to the group to show based
+     * on priority compared to other buttons.
+     * @param group the holder of all the buttons
+     */
+    void attachToGroup(@NonNull ContextualButtonGroup group) {
+        mGroup = group;
+    }
+
+    protected KeyButtonDrawable getNewDrawable(int lightIconColor, int darkIconColor) {
+        return KeyButtonDrawable.create(mLightContext, lightIconColor, darkIconColor, mIconResId,
+                false /* shadow */, null /* ovalBackground */);
+    }
+
+    public interface ContextButtonListener {
+        void onVisibilityChanged(ContextualButton button, boolean visible);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ContextualButtonGroup.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ContextualButtonGroup.java
new file mode 100644
index 0000000..c68d25f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ContextualButtonGroup.java
@@ -0,0 +1,173 @@
+/*
+ * 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.navigationbar.views.buttons;
+
+import android.annotation.IdRes;
+import android.annotation.NonNull;
+import android.view.View;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ContextualButtonGroup extends ButtonDispatcher {
+    private static final int INVALID_INDEX = -1;
+
+    // List of pairs that contains the button and if the button was visible within this group
+    private final List<ButtonData> mButtonData = new ArrayList<>();
+
+    public ContextualButtonGroup(@IdRes int containerId) {
+        super(containerId);
+    }
+
+    /**
+     * Add a contextual button to the group. The order of adding increases in its priority. The
+     * priority is used to determine which button should be visible when setting multiple button's
+     * visibility {@see setButtonVisibility}.
+     * @param button the button added to the group
+     */
+    public void addButton(@NonNull ContextualButton button) {
+        // By default buttons in the context group are not visible until
+        // {@link #setButtonVisibility()) is called to show one of the buttons
+        button.setVisibility(View.INVISIBLE);
+        button.attachToGroup(this);
+        mButtonData.add(new ButtonData(button));
+    }
+
+    /**
+     * Removes a contextual button from the group.
+     */
+    public void removeButton(@IdRes int buttonResId) {
+        int index = getContextButtonIndex(buttonResId);
+        if (index != INVALID_INDEX) {
+            mButtonData.remove(index);
+        }
+    }
+
+    public ContextualButton getContextButton(@IdRes int buttonResId) {
+        int index = getContextButtonIndex(buttonResId);
+        if (index != INVALID_INDEX) {
+            return mButtonData.get(index).button;
+        }
+        return null;
+    }
+
+    public ContextualButton getVisibleContextButton() {
+        for (int i = mButtonData.size() - 1; i >= 0; --i) {
+            if (mButtonData.get(i).markedVisible) {
+                return mButtonData.get(i).button;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Set the visibility of the button by {@param buttonResId} with {@param visible}. Only one
+     * button is shown at a time. The input button will only show up if it has higher priority than
+     * a previous button, otherwise it will be marked as visible and shown later if all higher
+     * priority buttons are invisible. Therefore hiding a button will show the next marked visible
+     * button. This group's view will be visible if at least one button is visible.
+     * @return if the button is visible after operation
+     * @throws RuntimeException if the input id does not match any of the ids in the group
+     */
+    public int setButtonVisibility(@IdRes int buttonResId, boolean visible) {
+        final int index = getContextButtonIndex(buttonResId);
+        if (index == INVALID_INDEX) {
+            throw new RuntimeException("Cannot find the button id of " + buttonResId
+                    + " in context group");
+        }
+        setVisibility(View.INVISIBLE);
+        mButtonData.get(index).markedVisible = visible;
+
+        // Make all buttons invisible except the first markedVisible button
+        boolean alreadyFoundVisibleButton = false;
+        int i = mButtonData.size() - 1;
+        for (; i >= 0; --i) {
+            final ButtonData buttonData = mButtonData.get(i);
+            if (!alreadyFoundVisibleButton && buttonData.markedVisible) {
+                buttonData.setVisibility(View.VISIBLE);
+                setVisibility(View.VISIBLE);
+                alreadyFoundVisibleButton = true;
+            } else {
+                buttonData.setVisibility(View.INVISIBLE);
+            }
+        }
+        return mButtonData.get(index).button.getVisibility();
+    }
+
+    /**
+     * See if button is group visible. Group visible determines if a button can be visible when
+     * higher priority buttons go invisible.
+     * @param buttonResId the button to see if it is group visible
+     * @return true if button is group visible
+     */
+    public boolean isButtonVisibleWithinGroup(@IdRes int buttonResId) {
+        final int index = getContextButtonIndex(buttonResId);
+        return index != INVALID_INDEX && mButtonData.get(index).markedVisible;
+    }
+
+    /**
+     * Update all the icons that are attached to this group. This will get all the buttons to update
+     * their icons for their buttons.
+     */
+    public void updateIcons(int lightIconColor, int darkIconColor) {
+        for (ButtonData data : mButtonData) {
+            data.button.updateIcon(lightIconColor, darkIconColor);
+        }
+    }
+
+    public void dump(PrintWriter pw) {
+        View view = getCurrentView();
+        pw.println("ContextualButtonGroup");
+        pw.println("  getVisibleContextButton(): " + getVisibleContextButton());
+        pw.println("  isVisible(): " + isVisible());
+        pw.println("  attached(): " + (view != null && view.isAttachedToWindow()));
+        pw.println("  mButtonData [ ");
+        for (int i = mButtonData.size() - 1; i >= 0; --i) {
+            final ButtonData data = mButtonData.get(i);
+            view = data.button.getCurrentView();
+            pw.println("    " + i + ": markedVisible=" + data.markedVisible
+                    + " visible=" + data.button.getVisibility()
+                    + " attached=" + (view != null && view.isAttachedToWindow())
+                    + " alpha=" + data.button.getAlpha());
+        }
+        pw.println("  ]");
+    }
+
+    private int getContextButtonIndex(@IdRes int buttonResId) {
+        for (int i = 0; i < mButtonData.size(); ++i) {
+            if (mButtonData.get(i).button.getId() == buttonResId) {
+                return i;
+            }
+        }
+        return INVALID_INDEX;
+    }
+
+    private final static class ButtonData {
+        ContextualButton button;
+        boolean markedVisible;
+
+        ButtonData(ContextualButton button) {
+            this.button = button;
+            this.markedVisible = false;
+        }
+
+        void setVisibility(int visiblity) {
+            button.setVisibility(visiblity);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/DeadZone.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/DeadZone.java
new file mode 100644
index 0000000..a6be314
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/DeadZone.java
@@ -0,0 +1,238 @@
+/*
+ * 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.navigationbar.views.buttons;
+
+import android.animation.ObjectAnimator;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.os.SystemClock;
+import android.util.FloatProperty;
+import android.util.Slog;
+import android.view.MotionEvent;
+import android.view.Surface;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.navigationbar.NavigationBarController;
+import com.android.systemui.navigationbar.views.NavigationBarView;
+import com.android.systemui.res.R;
+
+import javax.inject.Inject;
+
+/**
+ * The "dead zone" consumes unintentional taps along the top edge of the navigation bar.
+ * When users are typing quickly on an IME they may attempt to hit the space bar, overshoot, and
+ * accidentally hit the home button. The DeadZone expands temporarily after each tap in the UI
+ * outside the navigation bar (since this is when accidental taps are more likely), then contracts
+ * back over time (since a later tap might be intended for the top of the bar).
+ */
+public class DeadZone {
+    public static final String TAG = "DeadZone";
+
+    public static final boolean DEBUG = false;
+    public static final int HORIZONTAL = 0;  // Consume taps along the top edge.
+    public static final int VERTICAL = 1;  // Consume taps along the left edge.
+
+    private static final boolean CHATTY = true; // print to logcat when we eat a click
+
+    private static final FloatProperty<DeadZone> FLASH_PROPERTY =
+            new FloatProperty<DeadZone>("DeadZoneFlash") {
+        @Override
+        public void setValue(DeadZone object, float value) {
+            object.setFlash(value);
+        }
+
+        @Override
+        public Float get(DeadZone object) {
+            return object.getFlash();
+        }
+    };
+
+    private final boolean mUseDeadZone;
+    private final NavigationBarController mNavBarController;
+    private final NavigationBarView mNavigationBarView;
+
+    private boolean mShouldFlash;
+    private float mFlashFrac = 0f;
+
+    private int mSizeMax;
+    private int mSizeMin;
+    // Upon activity elsewhere in the UI, the dead zone will hold steady for
+    // mHold ms, then move back over the course of mDecay ms
+    private int mHold, mDecay;
+    private boolean mVertical;
+    private long mLastPokeTime;
+    private int mDisplayRotation;
+    private final int mDisplayId;
+
+    private final Runnable mDebugFlash = new Runnable() {
+        @Override
+        public void run() {
+            ObjectAnimator.ofFloat(DeadZone.this, FLASH_PROPERTY, 1f, 0f).setDuration(150).start();
+        }
+    };
+
+    @Inject
+    public DeadZone(NavigationBarView view) {
+        mUseDeadZone = view.getResources().getBoolean(R.bool.config_useDeadZone);
+
+        mNavigationBarView = view;
+        mNavBarController = Dependency.get(NavigationBarController.class);
+        mDisplayId = view.getContext().getDisplayId();
+
+        onConfigurationChanged(HORIZONTAL);
+    }
+
+    static float lerp(float a, float b, float f) {
+        return (b - a) * f + a;
+    }
+
+    private float getSize(long now) {
+        if (mSizeMax == 0)
+            return 0;
+        long dt = (now - mLastPokeTime);
+        if (dt > mHold + mDecay)
+            return mSizeMin;
+        if (dt < mHold)
+            return mSizeMax;
+        return (int) lerp(mSizeMax, mSizeMin, (float) (dt - mHold) / mDecay);
+    }
+
+    public void setFlashOnTouchCapture(boolean dbg) {
+        if (!mUseDeadZone) {
+            return;
+        }
+
+        mShouldFlash = dbg;
+        mFlashFrac = 0f;
+        mNavigationBarView.postInvalidate();
+    }
+
+    public void onConfigurationChanged(int rotation) {
+        if (!mUseDeadZone) {
+            return;
+        }
+
+        mDisplayRotation = rotation;
+
+        final Resources res = mNavigationBarView.getResources();
+        mHold = res.getInteger(R.integer.navigation_bar_deadzone_hold);
+        mDecay = res.getInteger(R.integer.navigation_bar_deadzone_decay);
+
+        mSizeMin = res.getDimensionPixelSize(R.dimen.navigation_bar_deadzone_size);
+        mSizeMax = res.getDimensionPixelSize(R.dimen.navigation_bar_deadzone_size_max);
+        int index = res.getInteger(R.integer.navigation_bar_deadzone_orientation);
+        mVertical = (index == VERTICAL);
+
+        if (DEBUG) {
+            Slog.v(TAG, this + " size=[" + mSizeMin + "-" + mSizeMax + "] hold=" + mHold
+                    + (mVertical ? " vertical" : " horizontal"));
+        }
+        setFlashOnTouchCapture(res.getBoolean(R.bool.config_dead_zone_flash));
+    }
+
+    // I made you a touch event...
+    public boolean onTouchEvent(MotionEvent event) {
+        if (!mUseDeadZone) {
+            return false;
+        }
+
+        if (DEBUG) {
+            Slog.v(TAG, this + " onTouch: " + MotionEvent.actionToString(event.getAction()));
+        }
+
+        // Don't consume events for high precision pointing devices. For this purpose a stylus is
+        // considered low precision (like a finger), so its events may be consumed.
+        if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) {
+            return false;
+        }
+
+        final int action = event.getAction();
+        if (action == MotionEvent.ACTION_OUTSIDE) {
+            poke(event);
+            return true;
+        } else if (action == MotionEvent.ACTION_DOWN) {
+            if (DEBUG) {
+                Slog.v(TAG, this + " ACTION_DOWN: " + event.getX() + "," + event.getY());
+            }
+            mNavBarController.touchAutoDim(mDisplayId);
+            int size = (int) getSize(event.getEventTime());
+            // In the vertical orientation consume taps along the left edge.
+            // In horizontal orientation consume taps along the top edge.
+            final boolean consumeEvent;
+            if (mVertical) {
+                if (mDisplayRotation == Surface.ROTATION_270) {
+                    consumeEvent = event.getX() > mNavigationBarView.getWidth() - size;
+                } else {
+                    consumeEvent = event.getX() < size;
+                }
+            } else {
+                consumeEvent = event.getY() < size;
+            }
+            if (consumeEvent) {
+                if (CHATTY) {
+                    Slog.v(TAG, "consuming errant click: (" + event.getX() + "," + event.getY() + ")");
+                }
+                if (mShouldFlash) {
+                    mNavigationBarView.post(mDebugFlash);
+                    mNavigationBarView.postInvalidate();
+                }
+                return true; // ...but I eated it
+            }
+        }
+        return false;
+    }
+
+    private void poke(MotionEvent event) {
+        mLastPokeTime = event.getEventTime();
+        if (DEBUG)
+            Slog.v(TAG, "poked! size=" + getSize(mLastPokeTime));
+        if (mShouldFlash) mNavigationBarView.postInvalidate();
+    }
+
+    private void setFlash(float f) {
+        mFlashFrac = f;
+        mNavigationBarView.postInvalidate();
+    }
+
+    private float getFlash() {
+        return mFlashFrac;
+    }
+
+    public void onDraw(Canvas can) {
+        if (!mUseDeadZone || !mShouldFlash || mFlashFrac <= 0f) {
+            return;
+        }
+
+        final int size = (int) getSize(SystemClock.uptimeMillis());
+        if (mVertical) {
+            if (mDisplayRotation == Surface.ROTATION_270) {
+                can.clipRect(can.getWidth() - size, 0, can.getWidth(), can.getHeight());
+            } else {
+                can.clipRect(0, 0, size, can.getHeight());
+            }
+        } else {
+            can.clipRect(0, 0, can.getWidth(), size);
+        }
+
+        final float frac = DEBUG ? (mFlashFrac - 0.5f) + 0.5f : mFlashFrac;
+        can.drawARGB((int) (frac * 0xFF), 0xDD, 0xEE, 0xAA);
+
+        if (DEBUG && size > mSizeMin)
+            // Very aggressive redrawing here, for debugging only
+            mNavigationBarView.postInvalidateDelayed(100);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonDrawable.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonDrawable.java
new file mode 100644
index 0000000..072a4db
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonDrawable.java
@@ -0,0 +1,491 @@
+/*
+ * 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.navigationbar.views.buttons;
+
+import android.animation.ArgbEvaluator;
+import android.annotation.ColorInt;
+import android.annotation.DrawableRes;
+import android.annotation.NonNull;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BlurMaskFilter;
+import android.graphics.BlurMaskFilter.Blur;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.Rect;
+import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.Drawable;
+import android.util.FloatProperty;
+import android.view.View;
+
+import com.android.settingslib.Utils;
+import com.android.systemui.res.R;
+
+/**
+ * Drawable for {@link KeyButtonView}s that supports tinting between two colors, rotation and shows
+ * a shadow. AnimatedVectorDrawable will only support tinting from intensities but has no support
+ * for shadows nor rotations.
+ */
+public class KeyButtonDrawable extends Drawable {
+
+    public static final FloatProperty<KeyButtonDrawable> KEY_DRAWABLE_ROTATE =
+        new FloatProperty<KeyButtonDrawable>("KeyButtonRotation") {
+            @Override
+            public void setValue(KeyButtonDrawable drawable, float degree) {
+                drawable.setRotation(degree);
+            }
+
+            @Override
+            public Float get(KeyButtonDrawable drawable) {
+                return drawable.getRotation();
+            }
+        };
+
+    public static final FloatProperty<KeyButtonDrawable> KEY_DRAWABLE_TRANSLATE_Y =
+        new FloatProperty<KeyButtonDrawable>("KeyButtonTranslateY") {
+            @Override
+            public void setValue(KeyButtonDrawable drawable, float y) {
+                drawable.setTranslationY(y);
+            }
+
+            @Override
+            public Float get(KeyButtonDrawable drawable) {
+                return drawable.getTranslationY();
+            }
+        };
+
+    private final Paint mIconPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+    private final Paint mShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+    private final ShadowDrawableState mState;
+    private AnimatedVectorDrawable mAnimatedDrawable;
+    private final Callback mAnimatedDrawableCallback = new Callback() {
+        @Override
+        public void invalidateDrawable(@NonNull Drawable who) {
+            invalidateSelf();
+        }
+
+        @Override
+        public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {
+            scheduleSelf(what, when);
+        }
+
+        @Override
+        public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {
+            unscheduleSelf(what);
+        }
+    };
+
+    public KeyButtonDrawable(Drawable d, @ColorInt int lightColor, @ColorInt int darkColor,
+            boolean horizontalFlip, Color ovalBackgroundColor) {
+        this(d, new ShadowDrawableState(lightColor, darkColor,
+                d instanceof AnimatedVectorDrawable, horizontalFlip, ovalBackgroundColor));
+    }
+
+    private KeyButtonDrawable(Drawable d, ShadowDrawableState state) {
+        mState = state;
+        if (d != null) {
+            mState.mBaseHeight = d.getIntrinsicHeight();
+            mState.mBaseWidth = d.getIntrinsicWidth();
+            mState.mChangingConfigurations = d.getChangingConfigurations();
+            mState.mChildState = d.getConstantState();
+        }
+        if (canAnimate()) {
+            mAnimatedDrawable = (AnimatedVectorDrawable) mState.mChildState.newDrawable().mutate();
+            mAnimatedDrawable.setCallback(mAnimatedDrawableCallback);
+            setDrawableBounds(mAnimatedDrawable);
+        }
+    }
+
+    public void setDarkIntensity(float intensity) {
+        mState.mDarkIntensity = intensity;
+        final int color = (int) ArgbEvaluator.getInstance()
+                .evaluate(intensity, mState.mLightColor, mState.mDarkColor);
+        updateShadowAlpha();
+        setColorFilter(new PorterDuffColorFilter(color, Mode.SRC_ATOP));
+    }
+
+    public void setRotation(float degrees) {
+        if (canAnimate()) {
+            // AnimatedVectorDrawables will not support rotation
+            return;
+        }
+        if (mState.mRotateDegrees != degrees) {
+            mState.mRotateDegrees = degrees;
+            invalidateSelf();
+        }
+    }
+
+    public void setTranslationX(float x) {
+        setTranslation(x, mState.mTranslationY);
+    }
+
+    public void setTranslationY(float y) {
+        setTranslation(mState.mTranslationX, y);
+    }
+
+    public void setTranslation(float x, float y) {
+        if (mState.mTranslationX != x || mState.mTranslationY != y) {
+            mState.mTranslationX = x;
+            mState.mTranslationY = y;
+            invalidateSelf();
+        }
+    }
+
+    public void setShadowProperties(int x, int y, int size, int color) {
+        if (canAnimate()) {
+            // AnimatedVectorDrawables will not support shadows
+            return;
+        }
+        if (mState.mShadowOffsetX != x || mState.mShadowOffsetY != y
+                || mState.mShadowSize != size || mState.mShadowColor != color) {
+            mState.mShadowOffsetX = x;
+            mState.mShadowOffsetY = y;
+            mState.mShadowSize = size;
+            mState.mShadowColor = color;
+            mShadowPaint.setColorFilter(
+                    new PorterDuffColorFilter(mState.mShadowColor, Mode.SRC_ATOP));
+            updateShadowAlpha();
+            invalidateSelf();
+        }
+    }
+
+    @Override
+    public boolean setVisible(boolean visible, boolean restart) {
+        boolean changed = super.setVisible(visible, restart);
+        if (changed) {
+            // End any existing animations when the visibility changes
+            jumpToCurrentState();
+        }
+        return changed;
+    }
+
+    @Override
+    public void jumpToCurrentState() {
+        super.jumpToCurrentState();
+        if (mAnimatedDrawable != null) {
+            mAnimatedDrawable.jumpToCurrentState();
+        }
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+        mState.mAlpha = alpha;
+        mIconPaint.setAlpha(alpha);
+        updateShadowAlpha();
+        invalidateSelf();
+    }
+
+    @Override
+    public void setColorFilter(ColorFilter colorFilter) {
+        mIconPaint.setColorFilter(colorFilter);
+        if (mAnimatedDrawable != null) {
+            if (hasOvalBg()) {
+                mAnimatedDrawable.setColorFilter(
+                        new PorterDuffColorFilter(mState.mLightColor, PorterDuff.Mode.SRC_IN));
+            } else {
+                mAnimatedDrawable.setColorFilter(colorFilter);
+            }
+        }
+        invalidateSelf();
+    }
+
+    public float getDarkIntensity() {
+        return mState.mDarkIntensity;
+    }
+
+    public float getRotation() {
+        return mState.mRotateDegrees;
+    }
+
+    public float getTranslationX() {
+        return mState.mTranslationX;
+    }
+
+    public float getTranslationY() {
+        return mState.mTranslationY;
+    }
+
+    @Override
+    public ConstantState getConstantState() {
+        return mState;
+    }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.TRANSLUCENT;
+    }
+
+    @Override
+    public int getIntrinsicHeight() {
+        return mState.mBaseHeight + (mState.mShadowSize + Math.abs(mState.mShadowOffsetY)) * 2;
+    }
+
+    @Override
+    public int getIntrinsicWidth() {
+        return mState.mBaseWidth + (mState.mShadowSize + Math.abs(mState.mShadowOffsetX)) * 2;
+    }
+
+    public boolean canAnimate() {
+        return mState.mSupportsAnimation;
+    }
+
+    public void startAnimation() {
+        if (mAnimatedDrawable != null) {
+            mAnimatedDrawable.start();
+        }
+    }
+
+    public void resetAnimation() {
+        if (mAnimatedDrawable != null) {
+            mAnimatedDrawable.reset();
+        }
+    }
+
+    public void clearAnimationCallbacks() {
+        if (mAnimatedDrawable != null) {
+            mAnimatedDrawable.clearAnimationCallbacks();
+        }
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        Rect bounds = getBounds();
+        if (bounds.isEmpty()) {
+            return;
+        }
+
+        if (mAnimatedDrawable != null) {
+            mAnimatedDrawable.draw(canvas);
+        } else {
+            // If no cache or previous cached bitmap is hardware/software acceleration does not
+            // match the current canvas on draw then regenerate
+            boolean hwBitmapChanged = mState.mIsHardwareBitmap != canvas.isHardwareAccelerated();
+            if (hwBitmapChanged) {
+                mState.mIsHardwareBitmap = canvas.isHardwareAccelerated();
+            }
+            if (mState.mLastDrawnIcon == null || hwBitmapChanged) {
+                regenerateBitmapIconCache();
+            }
+            canvas.save();
+            canvas.translate(mState.mTranslationX, mState.mTranslationY);
+            canvas.rotate(mState.mRotateDegrees, getIntrinsicWidth() / 2, getIntrinsicHeight() / 2);
+
+            if (mState.mShadowSize > 0) {
+                if (mState.mLastDrawnShadow == null || hwBitmapChanged) {
+                    regenerateBitmapShadowCache();
+                }
+
+                // Translate (with rotation offset) before drawing the shadow
+                final float radians = (float) (mState.mRotateDegrees * Math.PI / 180);
+                final float shadowOffsetX = (float) (Math.sin(radians) * mState.mShadowOffsetY
+                        + Math.cos(radians) * mState.mShadowOffsetX) - mState.mTranslationX;
+                final float shadowOffsetY = (float) (Math.cos(radians) * mState.mShadowOffsetY
+                        - Math.sin(radians) * mState.mShadowOffsetX) - mState.mTranslationY;
+                canvas.drawBitmap(mState.mLastDrawnShadow, shadowOffsetX, shadowOffsetY,
+                        mShadowPaint);
+            }
+            canvas.drawBitmap(mState.mLastDrawnIcon, null, bounds, mIconPaint);
+            canvas.restore();
+        }
+    }
+
+    @Override
+    public boolean canApplyTheme() {
+        return mState.canApplyTheme();
+    }
+
+    @ColorInt int getDrawableBackgroundColor() {
+        return mState.mOvalBackgroundColor.toArgb();
+    }
+
+    boolean hasOvalBg() {
+        return mState.mOvalBackgroundColor != null;
+    }
+
+    private void regenerateBitmapIconCache() {
+        final int width = getIntrinsicWidth();
+        final int height = getIntrinsicHeight();
+        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+        final Canvas canvas = new Canvas(bitmap);
+
+        // Call mutate, so that the pixel allocation by the underlying vector drawable is cleared.
+        final Drawable d = mState.mChildState.newDrawable().mutate();
+        setDrawableBounds(d);
+        canvas.save();
+        if (mState.mHorizontalFlip) {
+            canvas.scale(-1f, 1f, width * 0.5f, height * 0.5f);
+        }
+        d.draw(canvas);
+        canvas.restore();
+
+        if (mState.mIsHardwareBitmap) {
+            bitmap = bitmap.copy(Bitmap.Config.HARDWARE, false);
+        }
+        mState.mLastDrawnIcon = bitmap;
+    }
+
+    private void regenerateBitmapShadowCache() {
+        if (mState.mShadowSize == 0) {
+            // No shadow
+            mState.mLastDrawnIcon = null;
+            return;
+        }
+
+        final int width = getIntrinsicWidth();
+        final int height = getIntrinsicHeight();
+        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(bitmap);
+
+        // Call mutate, so that the pixel allocation by the underlying vector drawable is cleared.
+        final Drawable d = mState.mChildState.newDrawable().mutate();
+        setDrawableBounds(d);
+        canvas.save();
+        if (mState.mHorizontalFlip) {
+            canvas.scale(-1f, 1f, width * 0.5f, height * 0.5f);
+        }
+        d.draw(canvas);
+        canvas.restore();
+
+        // Draws the shadow from original drawable
+        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+        paint.setMaskFilter(new BlurMaskFilter(mState.mShadowSize, Blur.NORMAL));
+        int[] offset = new int[2];
+        final Bitmap shadow = bitmap.extractAlpha(paint, offset);
+        paint.setMaskFilter(null);
+        bitmap.eraseColor(Color.TRANSPARENT);
+        canvas.drawBitmap(shadow, offset[0], offset[1], paint);
+
+        if (mState.mIsHardwareBitmap) {
+            bitmap = bitmap.copy(Bitmap.Config.HARDWARE, false);
+        }
+        mState.mLastDrawnShadow = bitmap;
+    }
+
+    /**
+     * Set the alpha of the shadow. As dark intensity increases, drop the alpha of the shadow since
+     * dark color and shadow should not be visible at the same time.
+     */
+    private void updateShadowAlpha() {
+        // Update the color from the original color's alpha as the max
+        int alpha = Color.alpha(mState.mShadowColor);
+        mShadowPaint.setAlpha(
+                Math.round(alpha * (mState.mAlpha / 255f) * (1 - mState.mDarkIntensity)));
+    }
+
+    /**
+     * Prevent shadow clipping by offsetting the drawable bounds by the shadow and its offset
+     * @param d the drawable to set the bounds
+     */
+    private void setDrawableBounds(Drawable d) {
+        final int offsetX = mState.mShadowSize + Math.abs(mState.mShadowOffsetX);
+        final int offsetY = mState.mShadowSize + Math.abs(mState.mShadowOffsetY);
+        d.setBounds(offsetX, offsetY, getIntrinsicWidth() - offsetX,
+                getIntrinsicHeight() - offsetY);
+    }
+
+    private static class ShadowDrawableState extends ConstantState {
+        int mChangingConfigurations;
+        int mBaseWidth;
+        int mBaseHeight;
+        float mRotateDegrees;
+        float mTranslationX;
+        float mTranslationY;
+        int mShadowOffsetX;
+        int mShadowOffsetY;
+        int mShadowSize;
+        int mShadowColor;
+        float mDarkIntensity;
+        int mAlpha;
+        boolean mHorizontalFlip;
+
+        boolean mIsHardwareBitmap;
+        Bitmap mLastDrawnIcon;
+        Bitmap mLastDrawnShadow;
+        ConstantState mChildState;
+
+        final int mLightColor;
+        final int mDarkColor;
+        final boolean mSupportsAnimation;
+        final Color mOvalBackgroundColor;
+
+        public ShadowDrawableState(@ColorInt int lightColor, @ColorInt int darkColor,
+                boolean animated, boolean horizontalFlip, Color ovalBackgroundColor) {
+            mLightColor = lightColor;
+            mDarkColor = darkColor;
+            mSupportsAnimation = animated;
+            mAlpha = 255;
+            mHorizontalFlip = horizontalFlip;
+            mOvalBackgroundColor = ovalBackgroundColor;
+        }
+
+        @Override
+        public Drawable newDrawable() {
+            return new KeyButtonDrawable(null, this);
+        }
+
+        @Override
+        public int getChangingConfigurations() {
+            return mChangingConfigurations;
+        }
+
+        @Override
+        public boolean canApplyTheme() {
+            return true;
+        }
+    }
+
+    /**
+     * Creates a KeyButtonDrawable with a shadow given its icon. For more information, see
+     * {@link #create(Context, int, boolean, boolean)}.
+     */
+    public static KeyButtonDrawable create(Context lightContext, Context darkContext,
+            @DrawableRes int iconResId, boolean hasShadow, Color ovalBackgroundColor) {
+        return create(lightContext,
+            Utils.getColorAttrDefaultColor(lightContext, R.attr.singleToneColor),
+            Utils.getColorAttrDefaultColor(darkContext, R.attr.singleToneColor),
+            iconResId, hasShadow, ovalBackgroundColor);
+    }
+
+    /**
+     * Creates a KeyButtonDrawable with a shadow given its icon. For more information, see
+     * {@link #create(Context, int, boolean, boolean)}.
+     */
+    public static KeyButtonDrawable create(Context context, @ColorInt int lightColor,
+            @ColorInt int darkColor, @DrawableRes int iconResId, boolean hasShadow,
+            Color ovalBackgroundColor) {
+        final Resources res = context.getResources();
+        boolean isRtl = res.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+        Drawable d = context.getDrawable(iconResId);
+        final KeyButtonDrawable drawable = new KeyButtonDrawable(d, lightColor, darkColor,
+                isRtl && d.isAutoMirrored(), ovalBackgroundColor);
+        if (hasShadow) {
+            int offsetX = res.getDimensionPixelSize(R.dimen.nav_key_button_shadow_offset_x);
+            int offsetY = res.getDimensionPixelSize(R.dimen.nav_key_button_shadow_offset_y);
+            int radius = res.getDimensionPixelSize(R.dimen.nav_key_button_shadow_radius);
+            int color = context.getColor(R.color.nav_key_button_shadow_color);
+            drawable.setShadowProperties(offsetX, offsetY, radius, color);
+        }
+        return drawable;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java
new file mode 100644
index 0000000..1e85d6c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java
@@ -0,0 +1,505 @@
+/*
+ * 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.navigationbar.views.buttons;
+
+import static android.view.Display.INVALID_DISPLAY;
+import static android.view.KeyEvent.KEYCODE_UNKNOWN;
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+import android.hardware.input.InputManager;
+import android.hardware.input.InputManagerGlobal;
+import android.media.AudioManager;
+import android.metrics.LogMaker;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.HapticFeedbackConstants;
+import android.view.InputDevice;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.SoundEffectConstants;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.ImageView;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
+import com.android.internal.logging.UiEventLoggerImpl;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.Dependency;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.recents.OverviewProxyService;
+import com.android.systemui.res.R;
+import com.android.systemui.shared.navigationbar.KeyButtonRipple;
+import com.android.systemui.shared.system.QuickStepContract;
+
+public class KeyButtonView extends ImageView implements ButtonInterface {
+    private static final String TAG = KeyButtonView.class.getSimpleName();
+
+    private final boolean mPlaySounds;
+    private final UiEventLogger mUiEventLogger;
+    private int mContentDescriptionRes;
+    private long mDownTime;
+    private int mCode;
+    private int mTouchDownX;
+    private int mTouchDownY;
+    private boolean mIsVertical;
+    private AudioManager mAudioManager;
+    private boolean mGestureAborted;
+    @VisibleForTesting boolean mLongClicked;
+    private OnClickListener mOnClickListener;
+    private final KeyButtonRipple mRipple;
+    private final OverviewProxyService mOverviewProxyService;
+    private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
+    private final InputManagerGlobal mInputManagerGlobal;
+    private final Paint mOvalBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+    private float mDarkIntensity;
+    private boolean mHasOvalBg = false;
+    private NavBarButtonClickLogger mNavBarButtonClickLogger;
+
+    @VisibleForTesting
+    public enum NavBarButtonEvent implements UiEventLogger.UiEventEnum {
+
+        @UiEvent(doc = "The home button was pressed in the navigation bar.")
+        NAVBAR_HOME_BUTTON_TAP(533),
+
+        @UiEvent(doc = "The back button was pressed in the navigation bar.")
+        NAVBAR_BACK_BUTTON_TAP(534),
+
+        @UiEvent(doc = "The overview button was pressed in the navigation bar.")
+        NAVBAR_OVERVIEW_BUTTON_TAP(535),
+
+        @UiEvent(doc = "The ime switcher button was pressed in the navigation bar.")
+        NAVBAR_IME_SWITCHER_BUTTON_TAP(923),
+
+        @UiEvent(doc = "The home button was long-pressed in the navigation bar.")
+        NAVBAR_HOME_BUTTON_LONGPRESS(536),
+
+        @UiEvent(doc = "The back button was long-pressed in the navigation bar.")
+        NAVBAR_BACK_BUTTON_LONGPRESS(537),
+
+        @UiEvent(doc = "The overview button was long-pressed in the navigation bar.")
+        NAVBAR_OVERVIEW_BUTTON_LONGPRESS(538),
+
+        NONE(0);  // an event we should not log
+
+        private final int mId;
+
+        NavBarButtonEvent(int id) {
+            mId = id;
+        }
+
+        @Override
+        public int getId() {
+            return mId;
+        }
+    }
+    private final Runnable mCheckLongPress = new Runnable() {
+        public void run() {
+            if (isPressed()) {
+                // Log.d("KeyButtonView", "longpressed: " + this);
+                if (isLongClickable()) {
+                    // Just an old-fashioned ImageView
+                    performLongClick();
+                    mLongClicked = true;
+                } else {
+                    if (mCode != KEYCODE_UNKNOWN) {
+                        sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
+                        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
+                    }
+                    mLongClicked = true;
+                }
+            }
+        }
+    };
+
+    public KeyButtonView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public KeyButtonView(Context context, AttributeSet attrs, int defStyle) {
+        this(context, attrs, defStyle, InputManagerGlobal.getInstance(), new UiEventLoggerImpl());
+    }
+
+    @VisibleForTesting
+    public KeyButtonView(Context context, AttributeSet attrs, int defStyle,
+            InputManagerGlobal manager, UiEventLogger uiEventLogger) {
+        super(context, attrs);
+        mUiEventLogger = uiEventLogger;
+
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyButtonView,
+                defStyle, 0);
+
+        mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, KEYCODE_UNKNOWN);
+
+        mPlaySounds = a.getBoolean(R.styleable.KeyButtonView_playSound, true);
+
+        TypedValue value = new TypedValue();
+        if (a.getValue(R.styleable.KeyButtonView_android_contentDescription, value)) {
+            mContentDescriptionRes = value.resourceId;
+        }
+
+        a.recycle();
+
+        setClickable(true);
+        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+
+        mRipple = new KeyButtonRipple(context, this, R.dimen.key_button_ripple_max_width);
+        mOverviewProxyService = Dependency.get(OverviewProxyService.class);
+        mInputManagerGlobal = manager;
+        setBackground(mRipple);
+        setWillNotDraw(false);
+        forceHasOverlappingRendering(false);
+    }
+
+    @Override
+    public boolean isClickable() {
+        return mCode != KEYCODE_UNKNOWN || super.isClickable();
+    }
+
+    public void setCode(int code) {
+        mCode = code;
+    }
+
+    @Override
+    public void setOnClickListener(OnClickListener onClickListener) {
+        super.setOnClickListener(onClickListener);
+        mOnClickListener = onClickListener;
+    }
+
+    public void setNavBarButtonClickLogger(NavBarButtonClickLogger navBarButtonClickLogger) {
+        mNavBarButtonClickLogger = navBarButtonClickLogger;
+    }
+
+    public void loadAsync(Icon icon) {
+        new AsyncTask<Icon, Void, Drawable>() {
+            @Override
+            protected Drawable doInBackground(Icon... params) {
+                return params[0].loadDrawable(mContext);
+            }
+
+            @Override
+            protected void onPostExecute(Drawable drawable) {
+                setImageDrawable(drawable);
+            }
+        }.execute(icon);
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+
+        if (mContentDescriptionRes != 0) {
+            setContentDescription(mContext.getString(mContentDescriptionRes));
+        }
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        if (mCode != KEYCODE_UNKNOWN) {
+            info.addAction(new AccessibilityNodeInfo.AccessibilityAction(ACTION_CLICK, null));
+            if (isLongClickable()) {
+                info.addAction(
+                        new AccessibilityNodeInfo.AccessibilityAction(ACTION_LONG_CLICK, null));
+            }
+        }
+    }
+
+    @Override
+    protected void onWindowVisibilityChanged(int visibility) {
+        super.onWindowVisibilityChanged(visibility);
+        if (visibility != View.VISIBLE) {
+            jumpDrawablesToCurrentState();
+        }
+    }
+
+    @Override
+    public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
+        if (action == ACTION_CLICK && mCode != KEYCODE_UNKNOWN) {
+            sendEvent(KeyEvent.ACTION_DOWN, 0, SystemClock.uptimeMillis());
+            sendEvent(KeyEvent.ACTION_UP, 0);
+            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
+            playSoundEffect(SoundEffectConstants.CLICK);
+            return true;
+        } else if (action == ACTION_LONG_CLICK && mCode != KEYCODE_UNKNOWN) {
+            sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
+            sendEvent(KeyEvent.ACTION_UP, 0);
+            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
+            return true;
+        }
+        return super.performAccessibilityActionInternal(action, arguments);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        final boolean showSwipeUI = mOverviewProxyService.shouldShowSwipeUpUI();
+        final int action = ev.getAction();
+        int x, y;
+        if (action == MotionEvent.ACTION_DOWN) {
+            mGestureAborted = false;
+        }
+        if (mGestureAborted) {
+            setPressed(false);
+            return false;
+        }
+
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                mDownTime = SystemClock.uptimeMillis();
+                mLongClicked = false;
+                setPressed(true);
+
+                mTouchDownX = (int) ev.getX();
+                mTouchDownY = (int) ev.getY();
+                if (mCode != KEYCODE_UNKNOWN) {
+                    sendEvent(KeyEvent.ACTION_DOWN, 0, mDownTime);
+                } else {
+                    // Provide the same haptic feedback that the system offers for virtual keys.
+                    performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
+                }
+                if (!showSwipeUI) {
+                    playSoundEffect(SoundEffectConstants.CLICK);
+                }
+                removeCallbacks(mCheckLongPress);
+                postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
+                break;
+            case MotionEvent.ACTION_MOVE:
+                x = (int) ev.getX();
+                y = (int) ev.getY();
+
+                float slop = QuickStepContract.getQuickStepTouchSlopPx(getContext());
+                if (Math.abs(x - mTouchDownX) > slop || Math.abs(y - mTouchDownY) > slop) {
+                    // When quick step is enabled, prevent animating the ripple triggered by
+                    // setPressed and decide to run it on touch up
+                    setPressed(false);
+                    removeCallbacks(mCheckLongPress);
+                }
+                break;
+            case MotionEvent.ACTION_CANCEL:
+                setPressed(false);
+                if (mCode != KEYCODE_UNKNOWN) {
+                    sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
+                }
+                removeCallbacks(mCheckLongPress);
+                break;
+            case MotionEvent.ACTION_UP:
+                final boolean doIt = isPressed() && !mLongClicked;
+                setPressed(false);
+                final boolean doHapticFeedback = (SystemClock.uptimeMillis() - mDownTime) > 150;
+                if (showSwipeUI) {
+                    if (doIt) {
+                        // Apply haptic feedback on touch up since there is none on touch down
+                        performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
+                        playSoundEffect(SoundEffectConstants.CLICK);
+                    }
+                } else if (doHapticFeedback && !mLongClicked) {
+                    // Always send a release ourselves because it doesn't seem to be sent elsewhere
+                    // and it feels weird to sometimes get a release haptic and other times not.
+                    performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY_RELEASE);
+                }
+                if (mCode != KEYCODE_UNKNOWN) {
+                    if (doIt) {
+                        sendEvent(KeyEvent.ACTION_UP, 0);
+                        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
+                    } else {
+                        sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
+                    }
+                } else {
+                    // no key code, just a regular ImageView
+                    if (doIt && mOnClickListener != null) {
+                        mOnClickListener.onClick(this);
+                        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
+                    }
+                }
+                removeCallbacks(mCheckLongPress);
+                break;
+        }
+
+        return true;
+    }
+
+    @Override
+    public void setImageDrawable(Drawable drawable) {
+        super.setImageDrawable(drawable);
+
+        if (drawable == null) {
+            return;
+        }
+        KeyButtonDrawable keyButtonDrawable = (KeyButtonDrawable) drawable;
+        keyButtonDrawable.setDarkIntensity(mDarkIntensity);
+        mHasOvalBg = keyButtonDrawable.hasOvalBg();
+        if (mHasOvalBg) {
+            mOvalBgPaint.setColor(keyButtonDrawable.getDrawableBackgroundColor());
+        }
+        mRipple.setType(keyButtonDrawable.hasOvalBg() ? KeyButtonRipple.Type.OVAL
+                : KeyButtonRipple.Type.ROUNDED_RECT);
+    }
+
+    public void playSoundEffect(int soundConstant) {
+        if (!mPlaySounds) return;
+        mAudioManager.playSoundEffect(soundConstant, ActivityManager.getCurrentUser());
+    }
+
+    public void sendEvent(int action, int flags) {
+        sendEvent(action, flags, SystemClock.uptimeMillis());
+    }
+
+    private void logSomePresses(int action, int flags) {
+        boolean longPressSet = (flags & KeyEvent.FLAG_LONG_PRESS) != 0;
+        NavBarButtonEvent uiEvent = NavBarButtonEvent.NONE;
+        if (action == MotionEvent.ACTION_UP && mLongClicked) {
+            return;  // don't log the up after a long press
+        }
+        if (action == MotionEvent.ACTION_DOWN && !longPressSet) {
+            return;  // don't log a down unless it is also the long press marker
+        }
+        if ((flags & KeyEvent.FLAG_CANCELED) != 0
+                || (flags & KeyEvent.FLAG_CANCELED_LONG_PRESS) != 0) {
+            return;  // don't log various cancels
+        }
+        switch(mCode) {
+            case KeyEvent.KEYCODE_BACK:
+                uiEvent = longPressSet
+                        ? NavBarButtonEvent.NAVBAR_BACK_BUTTON_LONGPRESS
+                        : NavBarButtonEvent.NAVBAR_BACK_BUTTON_TAP;
+
+                if (mNavBarButtonClickLogger != null) {
+                    mNavBarButtonClickLogger.logBackButtonClick();
+                }
+                break;
+            case KeyEvent.KEYCODE_HOME:
+                uiEvent = longPressSet
+                        ? NavBarButtonEvent.NAVBAR_HOME_BUTTON_LONGPRESS
+                        : NavBarButtonEvent.NAVBAR_HOME_BUTTON_TAP;
+
+                if (mNavBarButtonClickLogger != null) {
+                    mNavBarButtonClickLogger.logHomeButtonClick();
+                }
+                break;
+            case KeyEvent.KEYCODE_APP_SWITCH:
+                uiEvent = longPressSet
+                        ? NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_LONGPRESS
+                        : NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_TAP;
+                break;
+        }
+        if (uiEvent != NavBarButtonEvent.NONE) {
+            mUiEventLogger.log(uiEvent);
+        }
+    }
+
+    private void sendEvent(int action, int flags, long when) {
+        mMetricsLogger.write(new LogMaker(MetricsEvent.ACTION_NAV_BUTTON_EVENT)
+                .setType(MetricsEvent.TYPE_ACTION)
+                .setSubtype(mCode)
+                .addTaggedData(MetricsEvent.FIELD_NAV_ACTION, action)
+                .addTaggedData(MetricsEvent.FIELD_FLAGS, flags));
+        logSomePresses(action, flags);
+        if (mCode == KeyEvent.KEYCODE_BACK && flags != KeyEvent.FLAG_LONG_PRESS) {
+            Log.i(TAG, "Back button event: " + KeyEvent.actionToString(action));
+        }
+        final int repeatCount = (flags & KeyEvent.FLAG_LONG_PRESS) != 0 ? 1 : 0;
+        final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, repeatCount,
+                0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
+                flags | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
+                InputDevice.SOURCE_KEYBOARD);
+
+        int displayId = INVALID_DISPLAY;
+
+        // Make KeyEvent work on multi-display environment
+        if (getDisplay() != null) {
+            displayId = getDisplay().getDisplayId();
+        }
+        if (displayId != INVALID_DISPLAY) {
+            ev.setDisplayId(displayId);
+        }
+        mInputManagerGlobal.injectInputEvent(ev,
+                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+    }
+
+    @Override
+    public void abortCurrentGesture() {
+        Log.d("b/63783866", "KeyButtonView.abortCurrentGesture");
+        if (mCode != KeyEvent.KEYCODE_UNKNOWN) {
+            sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
+        }
+        // When aborting long-press home and Launcher has requested to override it, fade out the
+        // ripple more quickly.
+        if (mCode == KeyEvent.KEYCODE_HOME && Dependency.get(AssistManager.class)
+                .shouldOverrideAssist(AssistManager.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS)) {
+            mRipple.speedUpNextFade();
+        }
+        setPressed(false);
+        mRipple.abortDelayedRipple();
+        mGestureAborted = true;
+    }
+
+    /** Run when the ripple for this button is next invisible. Only used once. */
+    public void setOnRippleInvisibleRunnable(Runnable onRippleInvisibleRunnable) {
+        mRipple.setOnInvisibleRunnable(onRippleInvisibleRunnable);
+    }
+
+    @Override
+    public void setDarkIntensity(float darkIntensity) {
+        mDarkIntensity = darkIntensity;
+
+        Drawable drawable = getDrawable();
+        if (drawable != null) {
+            ((KeyButtonDrawable) drawable).setDarkIntensity(darkIntensity);
+            // Since we reuse the same drawable for multiple views, we need to invalidate the view
+            // manually.
+            invalidate();
+        }
+        mRipple.setDarkIntensity(darkIntensity);
+    }
+
+    @Override
+    public void setDelayTouchFeedback(boolean shouldDelay) {
+        mRipple.setDelayTouchFeedback(shouldDelay);
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        if (mHasOvalBg) {
+            int d = Math.min(getWidth(), getHeight());
+            canvas.drawOval(0, 0, d, d, mOvalBgPaint);
+        }
+        super.draw(canvas);
+    }
+
+    @Override
+    public void setVertical(boolean vertical) {
+        mIsVertical = vertical;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavBarButtonClickLogger.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavBarButtonClickLogger.kt
new file mode 100644
index 0000000..ca58718
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavBarButtonClickLogger.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.navigationbar.views.buttons
+
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.log.dagger.NavBarButtonClickLog
+import javax.inject.Inject
+
+class NavBarButtonClickLogger
+@Inject
+constructor(@NavBarButtonClickLog private val buffer: LogBuffer) {
+    fun logHomeButtonClick() {
+        buffer.log(TAG, LogLevel.DEBUG, {}, { "Home Button Triggered" })
+    }
+
+    fun logBackButtonClick() {
+        buffer.log(TAG, LogLevel.DEBUG, {}, { "Back Button Triggered" })
+    }
+
+    fun logRecentsButtonClick() {
+        buffer.log(TAG, LogLevel.DEBUG, {}, { "Recents Button Triggered" })
+    }
+
+    fun logImeSwitcherClick() {
+        buffer.log(TAG, LogLevel.DEBUG, {}, { "Ime Switcher Triggered" })
+    }
+
+    fun logAccessibilityButtonClick() {
+        buffer.log(TAG, LogLevel.DEBUG, {}, { "Accessibility Button Triggered" })
+    }
+}
+
+private const val TAG = "NavBarButtonClick"
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavbarOrientationTrackingLogger.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavbarOrientationTrackingLogger.kt
new file mode 100644
index 0000000..a5ba17b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NavbarOrientationTrackingLogger.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.navigationbar.views.buttons
+
+import android.view.Surface
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.log.dagger.NavbarOrientationTrackingLog
+import javax.inject.Inject
+
+class NavbarOrientationTrackingLogger
+@Inject
+constructor(@NavbarOrientationTrackingLog private val buffer: LogBuffer) {
+    fun logPrimaryAndSecondaryVisibility(
+        methodName: String,
+        isViewVisible: Boolean,
+        isImmersiveMode: Boolean,
+        isSecondaryHandleVisible: Boolean,
+        currentRotation: Int,
+        startingQuickSwitchRotation: Int
+    ) {
+        buffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = methodName
+                bool1 = isViewVisible
+                bool2 = isImmersiveMode
+                bool3 = isSecondaryHandleVisible
+                int1 = startingQuickSwitchRotation
+                int2 = currentRotation
+            },
+            {
+                "Caller Method: $str1\n" +
+                    "\tNavbar Visible: $bool1\n" +
+                    "\tImmersive Mode: $bool2\n" +
+                    "\tSecondary Handle Visible: $bool3\n" +
+                    "\tDelta Rotation: ${getDeltaRotation(int1, int2)}\n" +
+                    "\tStarting QuickSwitch Rotation: $int1\n" +
+                    "\tCurrent Rotation: $int2\n"
+            }
+        )
+    }
+
+    private fun getDeltaRotation(oldRotation: Int, newRotation: Int): String {
+        var rotation: String = "0"
+        when (deltaRotation(oldRotation, newRotation)) {
+            Surface.ROTATION_90 -> {
+                rotation = "90"
+            }
+            Surface.ROTATION_180 -> {
+                rotation = "180"
+            }
+            Surface.ROTATION_270 -> {
+                rotation = "270"
+            }
+        }
+        return rotation
+    }
+
+    private fun deltaRotation(oldRotation: Int, newRotation: Int): Int {
+        var delta = newRotation - oldRotation
+        if (delta < 0) delta += 4
+        return delta
+    }
+}
+
+private const val TAG = "NavbarOrientationTracking"
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrame.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrame.java
new file mode 100644
index 0000000..e1a1a9f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrame.java
@@ -0,0 +1,229 @@
+/*
+ * 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.navigationbar.views.buttons;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.TypedArray;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.systemui.res.R;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Redirects touches that aren't handled by any child view to the nearest
+ * clickable child. Only takes effect on <sw600dp.
+ */
+public class NearestTouchFrame extends FrameLayout {
+
+    private final List<View> mClickableChildren = new ArrayList<>();
+    private final List<View> mAttachedChildren = new ArrayList<>();
+    private final boolean mIsActive;
+    private final int[] mTmpInt = new int[2];
+    private final int[] mOffset = new int[2];
+    private boolean mIsVertical;
+    private View mTouchingChild;
+    private final Map<View, Rect> mTouchableRegions = new HashMap<>();
+    /**
+     * Used to sort all child views either by their left position or their top position,
+     * depending on if this layout is used horizontally or vertically, respectively
+     */
+    private final Comparator<View> mChildRegionComparator =
+            (view1, view2) -> {
+                int leftTopIndex = 0;
+                if (mIsVertical) {
+                    // Compare view bound's "top" values
+                    leftTopIndex = 1;
+                }
+                view1.getLocationInWindow(mTmpInt);
+                int startingCoordView1 = mTmpInt[leftTopIndex] - mOffset[leftTopIndex];
+                view2.getLocationInWindow(mTmpInt);
+                int startingCoordView2 = mTmpInt[leftTopIndex] - mOffset[leftTopIndex];
+
+                return startingCoordView1 - startingCoordView2;
+            };
+
+    public NearestTouchFrame(Context context, AttributeSet attrs) {
+        this(context, attrs, context.getResources().getConfiguration());
+    }
+
+    @VisibleForTesting
+    NearestTouchFrame(Context context, AttributeSet attrs, Configuration c) {
+        super(context, attrs);
+        mIsActive = c.smallestScreenWidthDp < 600;
+        int[] attrsArray = new int[] {R.attr.isVertical};
+        TypedArray ta = context.obtainStyledAttributes(attrs, attrsArray);
+        mIsVertical = ta.getBoolean(0, false);
+        ta.recycle();
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        mClickableChildren.clear();
+        mAttachedChildren.clear();
+        mTouchableRegions.clear();
+        addClickableChildren(this);
+        getLocationInWindow(mOffset);
+        cacheClosestChildLocations();
+    }
+
+    /**
+     * Populates {@link #mTouchableRegions} with the regions where each clickable child is the
+     * closest for a given point on this layout.
+     */
+    private void cacheClosestChildLocations() {
+        if (getWidth() == 0 || getHeight() == 0) {
+            return;
+        }
+
+        // Sort by either top or left depending on mIsVertical, then take out all children
+        // that are not attached to window
+        mClickableChildren.sort(mChildRegionComparator);
+        mClickableChildren.stream()
+                .filter(View::isAttachedToWindow)
+                .forEachOrdered(mAttachedChildren::add);
+
+        // Cache bounds of children
+        // Mark coordinates where the actual child layout resides in this frame's window
+        for (int i = 0; i < mAttachedChildren.size(); i++) {
+            View child = mAttachedChildren.get(i);
+            if (!child.isAttachedToWindow()) {
+                continue;
+            }
+            Rect childRegion = getChildsBounds(child);
+
+            // We compute closest child from this child to the previous one
+            if (i == 0) {
+                // First child, nothing to the left/top of it
+                if (mIsVertical) {
+                    childRegion.top = 0;
+                } else {
+                    childRegion.left = 0;
+                }
+                mTouchableRegions.put(child, childRegion);
+                continue;
+            }
+
+            View previousChild = mAttachedChildren.get(i - 1);
+            Rect previousChildBounds = mTouchableRegions.get(previousChild);
+            int midPoint;
+            if (mIsVertical) {
+                int distance = childRegion.top - previousChildBounds.bottom;
+                midPoint = distance / 2;
+                childRegion.top -= midPoint;
+                previousChildBounds.bottom += midPoint - ((distance % 2) == 0 ? 1 : 0);
+            } else {
+                int distance = childRegion.left - previousChildBounds.right;
+                midPoint = distance / 2;
+                childRegion.left -= midPoint;
+                previousChildBounds.right += midPoint - ((distance % 2) == 0 ? 1 : 0);
+            }
+
+            if (i == mClickableChildren.size() - 1) {
+                // Last child, nothing to right/bottom of it
+                if (mIsVertical) {
+                    childRegion.bottom = getHeight();
+                } else {
+                    childRegion.right = getWidth();
+                }
+            }
+
+            mTouchableRegions.put(child, childRegion);
+        }
+    }
+
+    @VisibleForTesting
+    void setIsVertical(boolean isVertical) {
+        mIsVertical = isVertical;
+    }
+
+    private Rect getChildsBounds(View child) {
+        child.getLocationInWindow(mTmpInt);
+        int left = mTmpInt[0] - mOffset[0];
+        int top = mTmpInt[1] - mOffset[1];
+        int right = left + child.getWidth();
+        int bottom = top + child.getHeight();
+        return new Rect(left, top, right, bottom);
+    }
+
+    private void addClickableChildren(ViewGroup group) {
+        final int N = group.getChildCount();
+        for (int i = 0; i < N; i++) {
+            View child = group.getChildAt(i);
+            if (child.isClickable()) {
+                mClickableChildren.add(child);
+            } else if (child instanceof ViewGroup) {
+                addClickableChildren((ViewGroup) child);
+            }
+        }
+    }
+
+    /**
+     * @return A Map where the key is the view object of the button and the value
+     * is the Rect where that button will receive a touch event if pressed. This Rect will
+     * usually be larger than the layout bounds for the button.
+     * The Rect is in screen coordinates.
+     */
+    public Map<View, Rect> getFullTouchableChildRegions() {
+        Map<View, Rect> fullTouchRegions = new HashMap<>(mTouchableRegions.size());
+        getLocationOnScreen(mTmpInt);
+        for (Map.Entry<View, Rect> entry : mTouchableRegions.entrySet()) {
+            View child = entry.getKey();
+            Rect screenRegion = new Rect(entry.getValue());
+            screenRegion.offset(mTmpInt[0], mTmpInt[1]);
+            fullTouchRegions.put(child, screenRegion);
+        }
+        return fullTouchRegions;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        if (mIsActive) {
+            int x = (int) event.getX();
+            int y = (int) event.getY();
+            if (event.getAction() == MotionEvent.ACTION_DOWN) {
+                mTouchingChild = mClickableChildren
+                        .stream()
+                        .filter(View::isAttachedToWindow)
+                        .filter(view -> mTouchableRegions.get(view).contains(x, y))
+                        .findFirst()
+                        .orElse(null);
+
+            }
+            if (mTouchingChild != null) {
+                event.offsetLocation(mTouchingChild.getWidth() / 2 - x,
+                        mTouchingChild.getHeight() / 2 - y);
+                return mTouchingChild.getVisibility() == VISIBLE
+                        && mTouchingChild.dispatchTouchEvent(event);
+            }
+        }
+        return super.onTouchEvent(event);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ReverseLinearLayout.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ReverseLinearLayout.java
new file mode 100644
index 0000000..9d50bd6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/ReverseLinearLayout.java
@@ -0,0 +1,172 @@
+/*
+ * 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 com.android.systemui.navigationbar.views.buttons;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+
+import java.util.ArrayList;
+
+/**
+ * Automatically reverses the order of children as they are added.
+ * Also reverse the width and height values of layout params
+ */
+public class ReverseLinearLayout extends LinearLayout {
+
+    /** If true, the layout is reversed vs. a regular linear layout */
+    private boolean mIsLayoutReverse;
+
+    /** If true, the layout is opposite to it's natural reversity from the layout direction */
+    private boolean mIsAlternativeOrder;
+
+    public ReverseLinearLayout(Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        updateOrder();
+    }
+
+    @Override
+    public void addView(View child) {
+        reverseParams(child.getLayoutParams(), child, mIsLayoutReverse);
+        if (mIsLayoutReverse) {
+            super.addView(child, 0);
+        } else {
+            super.addView(child);
+        }
+    }
+
+    @Override
+    public void addView(View child, ViewGroup.LayoutParams params) {
+        reverseParams(params, child, mIsLayoutReverse);
+        if (mIsLayoutReverse) {
+            super.addView(child, 0, params);
+        } else {
+            super.addView(child, params);
+        }
+    }
+
+    @Override
+    public void onRtlPropertiesChanged(int layoutDirection) {
+        super.onRtlPropertiesChanged(layoutDirection);
+        updateOrder();
+    }
+
+    public void setAlternativeOrder(boolean alternative) {
+        mIsAlternativeOrder = alternative;
+        updateOrder();
+    }
+
+    /**
+     * In landscape, the LinearLayout is not auto mirrored since it is vertical. Therefore we
+     * have to do it manually
+     */
+    private void updateOrder() {
+        boolean isLayoutRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
+        boolean isLayoutReverse = isLayoutRtl ^ mIsAlternativeOrder;
+
+        if (mIsLayoutReverse != isLayoutReverse) {
+            // reversity changed, swap the order of all views.
+            int childCount = getChildCount();
+            ArrayList<View> childList = new ArrayList<>(childCount);
+            for (int i = 0; i < childCount; i++) {
+                childList.add(getChildAt(i));
+            }
+            removeAllViews();
+            for (int i = childCount - 1; i >= 0; i--) {
+                final View child = childList.get(i);
+                super.addView(child);
+            }
+            mIsLayoutReverse = isLayoutReverse;
+        }
+    }
+
+    private static void reverseParams(ViewGroup.LayoutParams params, View child,
+            boolean isLayoutReverse) {
+        if (child instanceof Reversable) {
+            ((Reversable) child).reverse(isLayoutReverse);
+        }
+        if (child.getPaddingLeft() == child.getPaddingRight()
+                && child.getPaddingTop() == child.getPaddingBottom()) {
+            child.setPadding(child.getPaddingTop(), child.getPaddingLeft(),
+                    child.getPaddingTop(), child.getPaddingLeft());
+        }
+        if (params == null) {
+            return;
+        }
+        int width = params.width;
+        params.width = params.height;
+        params.height = width;
+    }
+
+    public interface Reversable {
+        void reverse(boolean isLayoutReverse);
+    }
+
+    public static class ReverseRelativeLayout extends RelativeLayout implements Reversable {
+
+        public ReverseRelativeLayout(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void reverse(boolean isLayoutReverse) {
+            updateGravity(isLayoutReverse);
+            reverseGroup(this, isLayoutReverse);
+        }
+
+        private int mDefaultGravity = Gravity.NO_GRAVITY;
+        public void setDefaultGravity(int gravity) {
+            mDefaultGravity = gravity;
+        }
+
+        public void updateGravity(boolean isLayoutReverse) {
+            // Flip gravity if top of bottom is used
+            if (mDefaultGravity != Gravity.TOP && mDefaultGravity != Gravity.BOTTOM) return;
+
+            // Use the default (intended for 270 LTR and 90 RTL) unless layout is otherwise
+            int gravityToApply = mDefaultGravity;
+            if (isLayoutReverse) {
+                gravityToApply = mDefaultGravity == Gravity.TOP ? Gravity.BOTTOM : Gravity.TOP;
+            }
+
+            if (getGravity() != gravityToApply) setGravity(gravityToApply);
+        }
+    }
+    
+    private static void reverseGroup(ViewGroup group, boolean isLayoutReverse) {
+        for (int i = 0; i < group.getChildCount(); i++) {
+            final View child = group.getChildAt(i);
+            reverseParams(child.getLayoutParams(), child, isLayoutReverse);
+
+            // Recursively reverse all children
+            if (child instanceof ViewGroup) {
+                reverseGroup((ViewGroup) child, isLayoutReverse);
+            }
+        }
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
index de490a5..311cbfb 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfig.kt
@@ -96,12 +96,27 @@
                 logDebug { "lockScreenState:isConfigSelected=$isConfigSelected" }
                 logDebug { "lockScreenState:isDefaultNotesAppSet=$isDefaultNotesAppSet" }
 
+                val isCustomLockScreenShortcutEnabled =
+                    context.resources.getBoolean(R.bool.custom_lockscreen_shortcuts_enabled)
+                val isShortcutSelectedOrDefaultEnabled =
+                    if (isCustomLockScreenShortcutEnabled) {
+                        isConfigSelected
+                    } else {
+                        isStylusEverUsed
+                    }
+                logDebug {
+                    "lockScreenState:isCustomLockScreenShortcutEnabled=" +
+                        isCustomLockScreenShortcutEnabled
+                }
+                logDebug {
+                    "lockScreenState:isShortcutSelectedOrDefaultEnabled=" +
+                        isShortcutSelectedOrDefaultEnabled
+                }
                 if (
                     isEnabled &&
                         isUserUnlocked &&
                         isDefaultNotesAppSet &&
-                        isConfigSelected &&
-                        isStylusEverUsed
+                        isShortcutSelectedOrDefaultEnabled
                 ) {
                     val contentDescription = ContentDescription.Resource(pickerNameResourceId)
                     val icon = Icon.Resource(pickerIconResourceId, contentDescription)
diff --git a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneViewModel.kt
index d0c7fbc..1f74716 100644
--- a/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/notifications/ui/viewmodel/NotificationsShadeSceneViewModel.kt
@@ -22,6 +22,8 @@
 import com.android.compose.animation.scene.UserActionResult
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.scene.shared.model.SceneFamilies
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.shared.model.ShadeAlignment
 import javax.inject.Inject
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
@@ -29,11 +31,19 @@
 
 /** Models UI state and handles user input for the Notifications Shade scene. */
 @SysUISingleton
-class NotificationsShadeSceneViewModel @Inject constructor() {
+class NotificationsShadeSceneViewModel
+@Inject
+constructor(
+    shadeInteractor: ShadeInteractor,
+) {
     val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> =
         MutableStateFlow(
                 mapOf(
-                    Swipe.Up to SceneFamilies.Home,
+                    if (shadeInteractor.shadeAlignment == ShadeAlignment.Top) {
+                        Swipe.Up
+                    } else {
+                        Swipe.Down
+                    } to SceneFamilies.Home,
                     Back to SceneFamilies.Home,
                 )
             )
diff --git a/packages/SystemUI/src/com/android/systemui/power/shared/model/WakeSleepReason.kt b/packages/SystemUI/src/com/android/systemui/power/shared/model/WakeSleepReason.kt
index 75055668..776a8f4 100644
--- a/packages/SystemUI/src/com/android/systemui/power/shared/model/WakeSleepReason.kt
+++ b/packages/SystemUI/src/com/android/systemui/power/shared/model/WakeSleepReason.kt
@@ -54,7 +54,10 @@
     OTHER(isTouch = false, PowerManager.WAKE_REASON_UNKNOWN),
 
     /** Device goes to sleep due to folding of a foldable device. */
-    FOLD(isTouch = false, PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD);
+    FOLD(isTouch = false, PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD),
+
+    /** Device goes to sleep because it timed out. */
+    TIMEOUT(isTouch = false, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
 
     companion object {
         fun fromPowerManagerWakeReason(reason: Int): WakeSleepReason {
@@ -75,6 +78,7 @@
         fun fromPowerManagerSleepReason(reason: Int): WakeSleepReason {
             return when (reason) {
                 PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON -> POWER_BUTTON
+                PowerManager.GO_TO_SLEEP_REASON_TIMEOUT -> TIMEOUT
                 PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD -> FOLD
                 else -> OTHER
             }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index e77bd03..4018320 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -103,8 +103,7 @@
     }
     private int mLastMaxHeight = -1;
 
-    @Override
-    public void setPageMargin(int marginPixels) {
+    public void setPageMargin(int marginPixelsStart, int marginPixelsEnd) {
         // Using page margins creates some rounding issues that interfere with the correct position
         // in the onPageChangedListener and therefore present bad positions to the PageIndicator.
         // Instead, we use negative margins in the container and positive padding in the pages,
@@ -113,14 +112,19 @@
         // QSContainerImpl resources are set onAttachedView, so this view will always have the right
         // values when attached.
         MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
-        lp.setMarginStart(-marginPixels);
-        lp.setMarginEnd(-marginPixels);
+        lp.setMarginStart(-marginPixelsStart);
+        lp.setMarginEnd(-marginPixelsEnd);
         setLayoutParams(lp);
 
         int nPages = mPages.size();
         for (int i = 0; i < nPages; i++) {
             View v = mPages.get(i);
-            v.setPadding(marginPixels, v.getPaddingTop(), marginPixels, v.getPaddingBottom());
+            v.setPadding(
+                    marginPixelsStart,
+                    v.getPaddingTop(),
+                    marginPixelsEnd,
+                    v.getPaddingBottom()
+            );
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index cc0901f..db0676e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -35,6 +35,7 @@
 import com.android.systemui.Dumpable;
 import com.android.systemui.qs.customize.QSCustomizer;
 import com.android.systemui.res.R;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.shade.LargeScreenHeaderHelper;
 import com.android.systemui.shade.TouchLogger;
 import com.android.systemui.util.LargeScreenUtils;
@@ -300,7 +301,7 @@
                 // QS panel lays out some of its content full width
                 qsPanelController.setContentMargins(mContentHorizontalPadding,
                         mContentHorizontalPadding);
-                qsPanelController.setPageMargin(mTilesPageMargin);
+                setPageMargins(qsPanelController);
             } else if (view == mHeader) {
                 quickStatusBarHeaderController.setContentMargins(mContentHorizontalPadding,
                         mContentHorizontalPadding);
@@ -318,6 +319,18 @@
         }
     }
 
+    private void setPageMargins(QSPanelController qsPanelController) {
+        if (SceneContainerFlag.isEnabled()) {
+            if (mHorizontalMargins == mTilesPageMargin * 2 + 1) {
+                qsPanelController.setPageMargin(mTilesPageMargin, mTilesPageMargin + 1);
+            } else {
+                qsPanelController.setPageMargin(mTilesPageMargin, mTilesPageMargin);
+            }
+        } else {
+            qsPanelController.setPageMargin(mTilesPageMargin, mTilesPageMargin);
+        }
+    }
+
     /**
      * Clip QS bottom using a concave shape.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index abc2b7f..032891f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -638,9 +638,9 @@
         return mListening;
     }
 
-    protected void setPageMargin(int pageMargin) {
+    protected void setPageMargin(int pageMarginStart, int pageMarginEnd) {
         if (mTileLayout instanceof PagedTileLayout) {
-            ((PagedTileLayout) mTileLayout).setPageMargin(pageMargin);
+            ((PagedTileLayout) mTileLayout).setPageMargin(pageMarginStart, pageMarginEnd);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
index f76183e..d5cd8dc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -284,8 +284,8 @@
         return mView.isExpanded();
     }
 
-    void setPageMargin(int pageMargin) {
-        mView.setPageMargin(pageMargin);
+    void setPageMargin(int pageMarginStart, int pageMarginEnd) {
+        mView.setPageMargin(pageMarginStart, pageMarginEnd);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
index 24b7a01..96df728 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
@@ -224,6 +224,10 @@
         });
     }
 
+    boolean isBound() {
+        return mBound.get();
+    }
+
     @WorkerThread
     private void setBindService(boolean bind) {
         if (mBound.get() && mUnbindImmediate.get()) {
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 6bc5095..d10471d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServiceManager.java
@@ -217,7 +217,11 @@
             Log.e(TAG, "Service already bound");
             return;
         }
-        mPendingBind = true;
+        if (!mStateManager.isBound()) {
+            // If we are bound, we don't need to set a pending bind. There's either one already or
+            // we are fully bound.
+            mPendingBind = true;
+        }
         mBound = true;
         mJustBound = true;
         mHandler.postDelayed(mJustBoundOver, MIN_BIND_TIME);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PaginatedBaseLayoutType.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PaginatedBaseLayoutType.kt
new file mode 100644
index 0000000..0285cbd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PaginatedBaseLayoutType.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.dagger
+
+import javax.inject.Qualifier
+
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class PaginatedBaseLayoutType
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt
index 7b67993..ff20707 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/dagger/PanelsModule.kt
@@ -30,18 +30,21 @@
 import com.android.systemui.qs.panels.shared.model.GridLayoutType
 import com.android.systemui.qs.panels.shared.model.IconLabelVisibilityLog
 import com.android.systemui.qs.panels.shared.model.InfiniteGridLayoutType
+import com.android.systemui.qs.panels.shared.model.PaginatedGridLayoutType
 import com.android.systemui.qs.panels.shared.model.PartitionedGridLayoutType
 import com.android.systemui.qs.panels.shared.model.StretchedGridLayoutType
 import com.android.systemui.qs.panels.ui.compose.GridLayout
 import com.android.systemui.qs.panels.ui.compose.InfiniteGridLayout
+import com.android.systemui.qs.panels.ui.compose.PaginatableGridLayout
+import com.android.systemui.qs.panels.ui.compose.PaginatedGridLayout
 import com.android.systemui.qs.panels.ui.compose.PartitionedGridLayout
 import com.android.systemui.qs.panels.ui.compose.StretchedGridLayout
+import com.android.systemui.qs.panels.ui.viewmodel.FixedColumnsSizeViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.FixedColumnsSizeViewModelImpl
 import com.android.systemui.qs.panels.ui.viewmodel.IconLabelVisibilityViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.IconLabelVisibilityViewModelImpl
 import com.android.systemui.qs.panels.ui.viewmodel.IconTilesViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.IconTilesViewModelImpl
-import com.android.systemui.qs.panels.ui.viewmodel.InfiniteGridSizeViewModel
-import com.android.systemui.qs.panels.ui.viewmodel.InfiniteGridSizeViewModelImpl
 import dagger.Binds
 import dagger.Module
 import dagger.Provides
@@ -62,14 +65,24 @@
 
     @Binds fun bindIconTilesViewModel(impl: IconTilesViewModelImpl): IconTilesViewModel
 
-    @Binds fun bindGridSizeViewModel(impl: InfiniteGridSizeViewModelImpl): InfiniteGridSizeViewModel
+    @Binds fun bindGridSizeViewModel(impl: FixedColumnsSizeViewModelImpl): FixedColumnsSizeViewModel
 
     @Binds
     fun bindIconLabelVisibilityViewModel(
         impl: IconLabelVisibilityViewModelImpl
     ): IconLabelVisibilityViewModel
 
-    @Binds @Named("Default") fun bindDefaultGridLayout(impl: PartitionedGridLayout): GridLayout
+    @Binds
+    @PaginatedBaseLayoutType
+    fun bindPaginatedBaseGridLayout(impl: InfiniteGridLayout): PaginatableGridLayout
+
+    @Binds
+    @PaginatedBaseLayoutType
+    fun bindPaginatedBaseConsistencyInteractor(
+        impl: NoopGridConsistencyInteractor
+    ): GridTypeConsistencyInteractor
+
+    @Binds @Named("Default") fun bindDefaultGridLayout(impl: PaginatedGridLayout): GridLayout
 
     companion object {
         @Provides
@@ -109,6 +122,14 @@
         }
 
         @Provides
+        @IntoSet
+        fun providePaginatedGridLayout(
+            gridLayout: PaginatedGridLayout
+        ): Pair<GridLayoutType, GridLayout> {
+            return Pair(PaginatedGridLayoutType, gridLayout)
+        }
+
+        @Provides
         fun provideGridLayoutMap(
             entries: Set<@JvmSuppressWildcards Pair<GridLayoutType, GridLayout>>
         ): Map<GridLayoutType, GridLayout> {
@@ -147,6 +168,14 @@
         }
 
         @Provides
+        @IntoSet
+        fun providePaginatedGridConsistencyInteractor(
+            @PaginatedBaseLayoutType consistencyInteractor: GridTypeConsistencyInteractor,
+        ): Pair<GridLayoutType, GridTypeConsistencyInteractor> {
+            return Pair(PaginatedGridLayoutType, consistencyInteractor)
+        }
+
+        @Provides
         fun provideGridConsistencyInteractorMap(
             entries: Set<@JvmSuppressWildcards Pair<GridLayoutType, GridTypeConsistencyInteractor>>
         ): Map<GridLayoutType, GridTypeConsistencyInteractor> {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/FixedColumnsRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/FixedColumnsRepository.kt
new file mode 100644
index 0000000..32ce973
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/FixedColumnsRepository.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.data.repository
+
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+@SysUISingleton
+class FixedColumnsRepository @Inject constructor() {
+    // Number of columns in the narrowest state for consistency
+    private val _columns = MutableStateFlow(4)
+    val columns: StateFlow<Int> = _columns.asStateFlow()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepository.kt
index 44d8688..47c4ffd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/GridLayoutTypeRepository.kt
@@ -18,7 +18,7 @@
 
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.qs.panels.shared.model.GridLayoutType
-import com.android.systemui.qs.panels.shared.model.PartitionedGridLayoutType
+import com.android.systemui.qs.panels.shared.model.PaginatedGridLayoutType
 import javax.inject.Inject
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
@@ -26,13 +26,14 @@
 
 interface GridLayoutTypeRepository {
     val layout: StateFlow<GridLayoutType>
+
     fun setLayout(type: GridLayoutType)
 }
 
 @SysUISingleton
 class GridLayoutTypeRepositoryImpl @Inject constructor() : GridLayoutTypeRepository {
     private val _layout: MutableStateFlow<GridLayoutType> =
-        MutableStateFlow(PartitionedGridLayoutType)
+        MutableStateFlow(PaginatedGridLayoutType)
     override val layout = _layout.asStateFlow()
 
     override fun setLayout(type: GridLayoutType) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/InfiniteGridSizeRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/InfiniteGridSizeRepository.kt
deleted file mode 100644
index 43ccdf66..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/InfiniteGridSizeRepository.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.panels.data.repository
-
-import com.android.systemui.dagger.SysUISingleton
-import javax.inject.Inject
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
-
-@SysUISingleton
-class InfiniteGridSizeRepository @Inject constructor() {
-    // Number of columns in the narrowest state for consistency
-    private val _columns = MutableStateFlow(4)
-    val columns: StateFlow<Int> = _columns.asStateFlow()
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/PaginatedGridRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/PaginatedGridRepository.kt
new file mode 100644
index 0000000..26b2e2b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/PaginatedGridRepository.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.data.repository
+
+import android.content.res.Resources
+import com.android.systemui.common.ui.data.repository.ConfigurationRepository
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.res.R
+import com.android.systemui.util.kotlin.emitOnStart
+import javax.inject.Inject
+import kotlinx.coroutines.flow.map
+
+/**
+ * Provides the number of [rows] to use with a paginated grid, by tracking the resource
+ * [R.integer.quick_settings_max_rows].
+ */
+@SysUISingleton
+class PaginatedGridRepository
+@Inject
+constructor(
+    @Main private val resources: Resources,
+    configurationRepository: ConfigurationRepository,
+) {
+    val rows =
+        configurationRepository.onConfigurationChange.emitOnStart().map {
+            resources.getInteger(R.integer.quick_settings_max_rows)
+        }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepository.kt
new file mode 100644
index 0000000..f7c71ce
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepository.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.data.repository
+
+import android.content.res.Resources
+import com.android.systemui.common.ui.data.repository.ConfigurationRepository
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.res.R
+import com.android.systemui.util.kotlin.emitOnStart
+import javax.inject.Inject
+import kotlinx.coroutines.flow.map
+
+@SysUISingleton
+class QuickQuickSettingsRowRepository
+@Inject
+constructor(
+    @Main private val resources: Resources,
+    configurationRepository: ConfigurationRepository,
+) {
+    val rows =
+        configurationRepository.onConfigurationChange.emitOnStart().map {
+            resources.getInteger(R.integer.quick_qs_panel_max_rows)
+        }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/FixedColumnsSizeInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/FixedColumnsSizeInteractor.kt
new file mode 100644
index 0000000..9591002
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/FixedColumnsSizeInteractor.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.qs.panels.data.repository.FixedColumnsRepository
+import javax.inject.Inject
+import kotlinx.coroutines.flow.StateFlow
+
+@SysUISingleton
+class FixedColumnsSizeInteractor @Inject constructor(repo: FixedColumnsRepository) {
+    val columns: StateFlow<Int> = repo.columns
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractor.kt
index e99c64c..0fe79af 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractor.kt
@@ -28,7 +28,7 @@
 @Inject
 constructor(
     private val iconTilesInteractor: IconTilesInteractor,
-    private val gridSizeInteractor: InfiniteGridSizeInteractor
+    private val gridSizeInteractor: FixedColumnsSizeInteractor
 ) : GridTypeConsistencyInteractor {
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridSizeInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridSizeInteractor.kt
deleted file mode 100644
index 13c6072..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridSizeInteractor.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.panels.domain.interactor
-
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.qs.panels.data.repository.InfiniteGridSizeRepository
-import javax.inject.Inject
-import kotlinx.coroutines.flow.StateFlow
-
-@SysUISingleton
-class InfiniteGridSizeInteractor @Inject constructor(repo: InfiniteGridSizeRepository) {
-    val columns: StateFlow<Int> = repo.columns
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/NoopConsistencyInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/NoopConsistencyInteractor.kt
deleted file mode 100644
index 97ceacc..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/NoopConsistencyInteractor.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.panels.domain.interactor
-
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.qs.pipeline.shared.TileSpec
-import javax.inject.Inject
-
-@SysUISingleton
-class NoopConsistencyInteractor @Inject constructor() : GridTypeConsistencyInteractor {
-    override fun reconcileTiles(tiles: List<TileSpec>): List<TileSpec> = tiles
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/PaginatedGridInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/PaginatedGridInteractor.kt
new file mode 100644
index 0000000..d7d1ce9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/PaginatedGridInteractor.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.qs.panels.data.repository.PaginatedGridRepository
+import javax.inject.Inject
+
+@SysUISingleton
+class PaginatedGridInteractor
+@Inject
+constructor(paginatedGridRepository: PaginatedGridRepository) {
+    val rows = paginatedGridRepository.rows
+
+    val defaultRows = 4
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractor.kt
new file mode 100644
index 0000000..5f001df
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractor.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.qs.panels.data.repository.QuickQuickSettingsRowRepository
+import javax.inject.Inject
+
+@SysUISingleton
+class QuickQuickSettingsRowInteractor
+@Inject
+constructor(
+    quickQuickSettingsRowRepository: QuickQuickSettingsRowRepository,
+) {
+    val rows = quickQuickSettingsRowRepository.rows
+
+    val defaultRows = 2
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/GridLayoutType.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/GridLayoutType.kt
index 9550ddb..b1942fe 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/GridLayoutType.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/GridLayoutType.kt
@@ -34,3 +34,6 @@
 
 /** Grid type grouping large tiles on top and icon tiles at the bottom. */
 data object PartitionedGridLayoutType : GridLayoutType
+
+/** Grid type for a paginated list of tiles. It will delegate to some other layout type. */
+data object PaginatedGridLayoutType : GridLayoutType
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/DragAndDropState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/DragAndDropState.kt
new file mode 100644
index 0000000..007ec3a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/DragAndDropState.kt
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalFoundationApi::class)
+
+package com.android.systemui.qs.panels.ui.compose
+
+import android.content.ClipData
+import androidx.compose.foundation.ExperimentalFoundationApi
+import androidx.compose.foundation.draganddrop.dragAndDropSource
+import androidx.compose.foundation.draganddrop.dragAndDropTarget
+import androidx.compose.foundation.gestures.detectTapGestures
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draganddrop.DragAndDropEvent
+import androidx.compose.ui.draganddrop.DragAndDropTarget
+import androidx.compose.ui.draganddrop.DragAndDropTransferData
+import androidx.compose.ui.draganddrop.mimeTypes
+import com.android.systemui.qs.pipeline.shared.TileSpec
+
+@Composable
+fun rememberDragAndDropState(listState: EditTileListState): DragAndDropState {
+    val sourceSpec: MutableState<TileSpec?> = remember { mutableStateOf(null) }
+    return remember(listState) { DragAndDropState(sourceSpec, listState) }
+}
+
+/**
+ * Holds the [TileSpec] of the tile being moved and modify the [EditTileListState] based on drag and
+ * drop events.
+ */
+class DragAndDropState(
+    val sourceSpec: MutableState<TileSpec?>,
+    private val listState: EditTileListState
+) {
+    /** Returns index of the dragged tile if it's present in the list. Returns -1 if not. */
+    fun currentPosition(): Int {
+        return sourceSpec.value?.let { listState.indexOf(it) } ?: -1
+    }
+
+    fun isMoving(tileSpec: TileSpec): Boolean {
+        return sourceSpec.value?.let { it == tileSpec } ?: false
+    }
+
+    fun onStarted(spec: TileSpec) {
+        sourceSpec.value = spec
+    }
+
+    fun onMoved(targetSpec: TileSpec) {
+        sourceSpec.value?.let { listState.move(it, targetSpec) }
+    }
+
+    fun onDrop() {
+        sourceSpec.value = null
+    }
+}
+
+/**
+ * Registers a tile as a [DragAndDropTarget] to receive drag events and update the
+ * [DragAndDropState] with the tile's position, which can be used to insert a temporary placeholder.
+ *
+ * @param dragAndDropState The [DragAndDropState] using the tiles list
+ * @param tileSpec The [TileSpec] of the tile
+ * @param acceptDrops Whether the tile should accept a drop based on a given [TileSpec]
+ * @param onDrop Action to be executed when a [TileSpec] is dropped on the tile
+ */
+@Composable
+fun Modifier.dragAndDropTile(
+    dragAndDropState: DragAndDropState,
+    tileSpec: TileSpec,
+    acceptDrops: (TileSpec) -> Boolean,
+    onDrop: (TileSpec, Int) -> Unit,
+): Modifier {
+    val target =
+        remember(dragAndDropState) {
+            object : DragAndDropTarget {
+                override fun onDrop(event: DragAndDropEvent): Boolean {
+                    return dragAndDropState.sourceSpec.value?.let {
+                        onDrop(it, dragAndDropState.currentPosition())
+                        dragAndDropState.onDrop()
+                        true
+                    } ?: false
+                }
+
+                override fun onEntered(event: DragAndDropEvent) {
+                    dragAndDropState.onMoved(tileSpec)
+                }
+            }
+        }
+    return dragAndDropTarget(
+        shouldStartDragAndDrop = { event ->
+            event.mimeTypes().contains(QsDragAndDrop.TILESPEC_MIME_TYPE) &&
+                dragAndDropState.sourceSpec.value?.let { acceptDrops(it) } ?: false
+        },
+        target = target,
+    )
+}
+
+/**
+ * Registers a tile list as a [DragAndDropTarget] to receive drop events. Use this on list
+ * containers to catch drops outside of tiles.
+ *
+ * @param dragAndDropState The [DragAndDropState] using the tiles list
+ * @param acceptDrops Whether the tile should accept a drop based on a given [TileSpec]
+ * @param onDrop Action to be executed when a [TileSpec] is dropped on the tile
+ */
+@Composable
+fun Modifier.dragAndDropTileList(
+    dragAndDropState: DragAndDropState,
+    acceptDrops: (TileSpec) -> Boolean,
+    onDrop: (TileSpec, Int) -> Unit,
+): Modifier {
+    val target =
+        remember(dragAndDropState) {
+            object : DragAndDropTarget {
+                override fun onDrop(event: DragAndDropEvent): Boolean {
+                    return dragAndDropState.sourceSpec.value?.let {
+                        onDrop(it, dragAndDropState.currentPosition())
+                        dragAndDropState.onDrop()
+                        true
+                    } ?: false
+                }
+            }
+        }
+    return dragAndDropTarget(
+        target = target,
+        shouldStartDragAndDrop = { event ->
+            event.mimeTypes().contains(QsDragAndDrop.TILESPEC_MIME_TYPE) &&
+                dragAndDropState.sourceSpec.value?.let { acceptDrops(it) } ?: false
+        },
+    )
+}
+
+fun Modifier.dragAndDropTileSource(
+    tileSpec: TileSpec,
+    onTap: (TileSpec) -> Unit,
+    dragAndDropState: DragAndDropState
+): Modifier {
+    return dragAndDropSource {
+        detectTapGestures(
+            onTap = { onTap(tileSpec) },
+            onLongPress = {
+                dragAndDropState.onStarted(tileSpec)
+
+                // The tilespec from the ClipData transferred isn't actually needed as we're moving
+                // a tile within the same application. We're using a custom MIME type to limit the
+                // drag event to QS.
+                startTransfer(
+                    DragAndDropTransferData(
+                        ClipData(
+                            QsDragAndDrop.CLIPDATA_LABEL,
+                            arrayOf(QsDragAndDrop.TILESPEC_MIME_TYPE),
+                            ClipData.Item(tileSpec.spec)
+                        )
+                    )
+                )
+            }
+        )
+    }
+}
+
+private object QsDragAndDrop {
+    const val CLIPDATA_LABEL = "tilespec"
+    const val TILESPEC_MIME_TYPE = "qstile/tilespec"
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt
new file mode 100644
index 0000000..482c498
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/EditTileListState.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.ui.compose
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.snapshots.SnapshotStateList
+import androidx.compose.runtime.toMutableStateList
+import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
+import com.android.systemui.qs.pipeline.shared.TileSpec
+
+@Composable
+fun rememberEditListState(
+    tiles: List<EditTileViewModel>,
+): EditTileListState {
+    return remember(tiles) { EditTileListState(tiles) }
+}
+
+/** Holds the temporary state of the tile list during a drag movement where we move tiles around. */
+class EditTileListState(tiles: List<EditTileViewModel>) {
+    val tiles: SnapshotStateList<EditTileViewModel> = tiles.toMutableStateList()
+
+    fun move(tileSpec: TileSpec, target: TileSpec) {
+        val fromIndex = indexOf(tileSpec)
+        val toIndex = indexOf(target)
+
+        if (fromIndex == -1 || toIndex == -1 || fromIndex == toIndex) {
+            return
+        }
+
+        val isMovingToCurrent = tiles[toIndex].isCurrent
+        tiles.apply { add(toIndex, removeAt(fromIndex).copy(isCurrent = isMovingToCurrent)) }
+    }
+
+    fun indexOf(tileSpec: TileSpec): Int {
+        return tiles.indexOfFirst { it.tileSpec == tileSpec }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt
index 8806931..e2f6bcf 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/GridLayout.kt
@@ -18,15 +18,19 @@
 
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
+import com.android.systemui.qs.panels.shared.model.SizedTile
+import com.android.systemui.qs.panels.shared.model.TileRow
 import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
 import com.android.systemui.qs.pipeline.shared.TileSpec
 
+/** A layout of tiles, indicating how they should be composed when showing in QS or in edit mode. */
 interface GridLayout {
     @Composable
     fun TileGrid(
         tiles: List<TileViewModel>,
         modifier: Modifier,
+        editModeStart: () -> Unit,
     )
 
     @Composable
@@ -37,3 +41,49 @@
         onRemoveTile: (TileSpec) -> Unit,
     )
 }
+
+/**
+ * A type of [GridLayout] that can be paginated, to use together with [PaginatedGridLayout].
+ *
+ * [splitIntoPages] determines how to split a list of tiles based on the number of rows and columns
+ * available.
+ */
+interface PaginatableGridLayout : GridLayout {
+    fun splitIntoPages(
+        tiles: List<TileViewModel>,
+        rows: Int,
+        columns: Int,
+    ): List<List<TileViewModel>>
+
+    companion object {
+
+        /**
+         * Splits a list of [SizedTile] into rows, each with at most [columns] occupied.
+         *
+         * It will leave gaps at the end of a row if the next [SizedTile] has [SizedTile.width] that
+         * is larger than the space remaining in the row.
+         */
+        fun splitInRows(
+            tiles: List<SizedTile<TileViewModel>>,
+            columns: Int
+        ): List<List<SizedTile<TileViewModel>>> {
+            val row = TileRow<TileViewModel>(columns)
+
+            return buildList {
+                for (tile in tiles) {
+                    check(tile.width <= columns)
+                    if (!row.maybeAddTile(tile)) {
+                        // Couldn't add tile to previous row, create a row with the current tiles
+                        // and start a new one
+                        add(row.tiles)
+                        row.clear()
+                        row.maybeAddTile(tile)
+                    }
+                }
+                if (row.tiles.isNotEmpty()) {
+                    add(row.tiles)
+                }
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt
index 2f0fe22..ea97f0d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/InfiniteGridLayout.kt
@@ -26,9 +26,10 @@
 import androidx.compose.ui.res.dimensionResource
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.qs.panels.shared.model.SizedTile
 import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.FixedColumnsSizeViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.IconTilesViewModel
-import com.android.systemui.qs.panels.ui.viewmodel.InfiniteGridSizeViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.res.R
@@ -39,13 +40,14 @@
 @Inject
 constructor(
     private val iconTilesViewModel: IconTilesViewModel,
-    private val gridSizeViewModel: InfiniteGridSizeViewModel,
-) : GridLayout {
+    private val gridSizeViewModel: FixedColumnsSizeViewModel,
+) : PaginatableGridLayout {
 
     @Composable
     override fun TileGrid(
         tiles: List<TileViewModel>,
         modifier: Modifier,
+        editModeStart: () -> Unit,
     ) {
         DisposableEffect(tiles) {
             val token = Any()
@@ -55,16 +57,8 @@
         val columns by gridSizeViewModel.columns.collectAsStateWithLifecycle()
 
         TileLazyGrid(modifier = modifier, columns = GridCells.Fixed(columns)) {
-            items(
-                tiles.size,
-                span = { index ->
-                    if (iconTilesViewModel.isIconTile(tiles[index].spec)) {
-                        GridItemSpan(1)
-                    } else {
-                        GridItemSpan(2)
-                    }
-                }
-            ) { index ->
+            items(tiles.size, span = { index -> GridItemSpan(tiles[index].spec.width()) }) { index
+                ->
                 Tile(
                     tile = tiles[index],
                     iconOnly = iconTilesViewModel.isIconTile(tiles[index].spec),
@@ -92,4 +86,22 @@
             onRemoveTile = onRemoveTile,
         )
     }
+
+    override fun splitIntoPages(
+        tiles: List<TileViewModel>,
+        rows: Int,
+        columns: Int,
+    ): List<List<TileViewModel>> {
+
+        return PaginatableGridLayout.splitInRows(
+                tiles.map { SizedTile(it, it.spec.width()) },
+                columns,
+            )
+            .chunked(rows)
+            .map { it.flatten().map { it.tile } }
+    }
+
+    private fun TileSpec.width(): Int {
+        return if (iconTilesViewModel.isIconTile(this)) 1 else 2
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PagerDots.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PagerDots.kt
new file mode 100644
index 0000000..7de22161
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PagerDots.kt
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.ui.compose
+
+import androidx.compose.animation.core.animateDpAsState
+import androidx.compose.foundation.Canvas
+import androidx.compose.foundation.layout.Arrangement.spacedBy
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.wrapContentWidth
+import androidx.compose.foundation.pager.PagerState
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.CornerRadius
+import androidx.compose.ui.geometry.Size
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.drawscope.DrawScope
+import androidx.compose.ui.semantics.pageLeft
+import androidx.compose.ui.semantics.pageRight
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.semantics.stateDescription
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.LayoutDirection
+import androidx.compose.ui.unit.dp
+import kotlin.math.absoluteValue
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+
+@Composable
+fun PagerDots(
+    pagerState: PagerState,
+    activeColor: Color,
+    nonActiveColor: Color,
+    modifier: Modifier = Modifier,
+    dotSize: Dp = 6.dp,
+    spaceSize: Dp = 4.dp,
+) {
+    if (pagerState.pageCount < 2) {
+        return
+    }
+    val inPageTransition by
+        remember(pagerState) {
+            derivedStateOf {
+                pagerState.currentPageOffsetFraction.absoluteValue > 0.01 &&
+                    !pagerState.isOverscrolling()
+            }
+        }
+    val coroutineScope = rememberCoroutineScope()
+    Row(
+        modifier =
+            modifier
+                .wrapContentWidth()
+                .pagerDotsSemantics(
+                    pagerState,
+                    coroutineScope,
+                ),
+        horizontalArrangement = spacedBy(spaceSize),
+        verticalAlignment = Alignment.CenterVertically
+    ) {
+        if (!inPageTransition) {
+            repeat(pagerState.pageCount) { i ->
+                // We use canvas directly to only invalidate the draw phase when the page is
+                // changing.
+                Canvas(Modifier.size(dotSize)) {
+                    if (pagerState.currentPage == i) {
+                        drawCircle(activeColor)
+                    } else {
+                        drawCircle(nonActiveColor)
+                    }
+                }
+            }
+        } else {
+            val doubleDotWidth = dotSize * 2 + spaceSize
+            val cornerRadius = dotSize / 2
+            val width by
+                animateDpAsState(targetValue = if (inPageTransition) doubleDotWidth else dotSize)
+
+            fun DrawScope.drawDoubleRect() {
+                drawRoundRect(
+                    color = activeColor,
+                    size = Size(width.toPx(), dotSize.toPx()),
+                    cornerRadius = CornerRadius(cornerRadius.toPx(), cornerRadius.toPx())
+                )
+            }
+
+            repeat(pagerState.pageCount) { page ->
+                Canvas(Modifier.size(dotSize)) {
+                    val withPrevious = pagerState.currentPageOffsetFraction < 0
+                    val ltr = layoutDirection == LayoutDirection.Ltr
+                    if (
+                        withPrevious && page == (pagerState.currentPage - 1) ||
+                            !withPrevious && page == pagerState.currentPage
+                    ) {
+                        if (ltr) {
+                            drawDoubleRect()
+                        }
+                    } else if (
+                        withPrevious && page == pagerState.currentPage ||
+                            !withPrevious && page == (pagerState.currentPage + 1)
+                    ) {
+                        if (!ltr) {
+                            drawDoubleRect()
+                        }
+                    } else {
+                        drawCircle(nonActiveColor)
+                    }
+                }
+            }
+        }
+    }
+}
+
+private fun Modifier.pagerDotsSemantics(
+    pagerState: PagerState,
+    coroutineScope: CoroutineScope,
+): Modifier {
+    return then(
+        Modifier.semantics {
+            pageLeft {
+                if (pagerState.canScrollBackward) {
+                    coroutineScope.launch {
+                        pagerState.animateScrollToPage(pagerState.currentPage - 1)
+                    }
+                    true
+                } else {
+                    false
+                }
+            }
+            pageRight {
+                if (pagerState.canScrollForward) {
+                    coroutineScope.launch {
+                        pagerState.animateScrollToPage(pagerState.currentPage + 1)
+                    }
+                    true
+                } else {
+                    false
+                }
+            }
+            stateDescription = "Page ${pagerState.settledPage + 1} of ${pagerState.pageCount}"
+        }
+    )
+}
+
+private fun PagerState.isOverscrolling(): Boolean {
+    val position = currentPage + currentPageOffsetFraction
+    return position < 0 || position > pageCount - 1
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
new file mode 100644
index 0000000..2ee957e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.ui.compose
+
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.pager.HorizontalPager
+import androidx.compose.foundation.pager.rememberPagerState
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Edit
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.LocalContentColor
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.android.systemui.qs.panels.dagger.PaginatedBaseLayoutType
+import com.android.systemui.qs.panels.ui.compose.PaginatedGridLayout.Dimensions.FooterHeight
+import com.android.systemui.qs.panels.ui.compose.PaginatedGridLayout.Dimensions.InterPageSpacing
+import com.android.systemui.qs.panels.ui.viewmodel.PaginatedGridViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
+import com.android.systemui.res.R
+import javax.inject.Inject
+
+class PaginatedGridLayout
+@Inject
+constructor(
+    private val viewModel: PaginatedGridViewModel,
+    @PaginatedBaseLayoutType private val delegateGridLayout: PaginatableGridLayout,
+) : GridLayout by delegateGridLayout {
+    @Composable
+    override fun TileGrid(
+        tiles: List<TileViewModel>,
+        modifier: Modifier,
+        editModeStart: () -> Unit,
+    ) {
+        DisposableEffect(tiles) {
+            val token = Any()
+            tiles.forEach { it.startListening(token) }
+            onDispose { tiles.forEach { it.stopListening(token) } }
+        }
+        val columns by viewModel.columns.collectAsStateWithLifecycle()
+        val rows by viewModel.rows.collectAsStateWithLifecycle()
+
+        val pages =
+            remember(tiles, columns, rows) {
+                delegateGridLayout.splitIntoPages(tiles, rows = rows, columns = columns)
+            }
+
+        val pagerState = rememberPagerState(0) { pages.size }
+
+        Column {
+            HorizontalPager(
+                state = pagerState,
+                modifier = Modifier,
+                pageSpacing = if (pages.size > 1) InterPageSpacing else 0.dp,
+                beyondViewportPageCount = 1,
+                verticalAlignment = Alignment.Top,
+            ) {
+                val page = pages[it]
+
+                delegateGridLayout.TileGrid(tiles = page, modifier = Modifier, editModeStart = {})
+            }
+            Box(
+                modifier = Modifier.height(FooterHeight).fillMaxWidth(),
+            ) {
+                PagerDots(
+                    pagerState = pagerState,
+                    activeColor = MaterialTheme.colorScheme.primary,
+                    nonActiveColor = MaterialTheme.colorScheme.surfaceVariant,
+                    modifier = Modifier.align(Alignment.Center)
+                )
+                CompositionLocalProvider(value = LocalContentColor provides Color.White) {
+                    IconButton(
+                        onClick = editModeStart,
+                        modifier = Modifier.align(Alignment.CenterEnd),
+                    ) {
+                        Icon(
+                            imageVector = Icons.Default.Edit,
+                            contentDescription = stringResource(id = R.string.qs_edit)
+                        )
+                    }
+                }
+            }
+        }
+    }
+
+    private object Dimensions {
+        val FooterHeight = 48.dp
+        val InterPageSpacing = 16.dp
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayout.kt
index 9233e76..092ad44 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PartitionedGridLayout.kt
@@ -53,6 +53,7 @@
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.compose.modifiers.background
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.qs.panels.shared.model.SizedTile
 import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.PartitionedGridViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
@@ -63,9 +64,13 @@
 
 @SysUISingleton
 class PartitionedGridLayout @Inject constructor(private val viewModel: PartitionedGridViewModel) :
-    GridLayout {
+    PaginatableGridLayout {
     @Composable
-    override fun TileGrid(tiles: List<TileViewModel>, modifier: Modifier) {
+    override fun TileGrid(
+        tiles: List<TileViewModel>,
+        modifier: Modifier,
+        editModeStart: () -> Unit,
+    ) {
         DisposableEffect(tiles) {
             val token = Any()
             tiles.forEach { it.startListening(token) }
@@ -105,12 +110,15 @@
         tiles: List<EditTileViewModel>,
         modifier: Modifier,
         onAddTile: (TileSpec, Int) -> Unit,
-        onRemoveTile: (TileSpec) -> Unit
+        onRemoveTile: (TileSpec) -> Unit,
     ) {
         val columns by viewModel.columns.collectAsStateWithLifecycle()
         val showLabels by viewModel.showLabels.collectAsStateWithLifecycle()
 
-        val (currentTiles, otherTiles) = tiles.partition { it.isCurrent }
+        val listState = rememberEditListState(tiles)
+        val dragAndDropState = rememberDragAndDropState(listState)
+
+        val (currentTiles, otherTiles) = listState.tiles.partition { it.isCurrent }
         val addTileToEnd: (TileSpec) -> Unit by rememberUpdatedState {
             onAddTile(it, CurrentTilesInteractor.POSITION_AT_END)
         }
@@ -151,34 +159,54 @@
                 largeTileHeight = largeTileHeight,
                 iconTileHeight = iconTileHeight,
                 tilePadding = tilePadding,
-                onRemoveTile = onRemoveTile,
+                onAdd = onAddTile,
+                onRemove = onRemoveTile,
                 isIconOnly = viewModel::isIconTile,
                 columns = columns,
                 showLabels = showLabels,
+                dragAndDropState = dragAndDropState,
             )
             AvailableTiles(
-                tiles = otherTiles,
+                tiles = otherTiles.filter { !dragAndDropState.isMoving(it.tileSpec) },
                 largeTileHeight = largeTileHeight,
                 iconTileHeight = iconTileHeight,
                 tilePadding = tilePadding,
                 addTileToEnd = addTileToEnd,
+                onRemove = onRemoveTile,
                 isIconOnly = viewModel::isIconTile,
                 showLabels = showLabels,
                 columns = columns,
+                dragAndDropState = dragAndDropState,
             )
         }
     }
 
+    override fun splitIntoPages(
+        tiles: List<TileViewModel>,
+        rows: Int,
+        columns: Int,
+    ): List<List<TileViewModel>> {
+        val (smallTiles, largeTiles) = tiles.partition { viewModel.isIconTile(it.spec) }
+
+        val sizedLargeTiles = largeTiles.map { SizedTile(it, 2) }
+        val sizedSmallTiles = smallTiles.map { SizedTile(it, 1) }
+        val largeTilesRows = PaginatableGridLayout.splitInRows(sizedLargeTiles, columns)
+        val smallTilesRows = PaginatableGridLayout.splitInRows(sizedSmallTiles, columns)
+        return (largeTilesRows + smallTilesRows).chunked(rows).map { it.flatten().map { it.tile } }
+    }
+
     @Composable
     private fun CurrentTiles(
         tiles: List<EditTileViewModel>,
         largeTileHeight: Dp,
         iconTileHeight: Dp,
         tilePadding: Dp,
-        onRemoveTile: (TileSpec) -> Unit,
+        onAdd: (TileSpec, Int) -> Unit,
+        onRemove: (TileSpec) -> Unit,
         isIconOnly: (TileSpec) -> Boolean,
         showLabels: Boolean,
         columns: Int,
+        dragAndDropState: DragAndDropState,
     ) {
         val (smallTiles, largeTiles) = tiles.partition { isIconOnly(it.tileSpec) }
 
@@ -188,29 +216,40 @@
         CurrentTilesContainer {
             TileLazyGrid(
                 columns = GridCells.Fixed(columns),
-                modifier = Modifier.height(largeGridHeight),
+                modifier =
+                    Modifier.height(largeGridHeight)
+                        .dragAndDropTileList(dragAndDropState, { !isIconOnly(it) }, onAdd)
             ) {
                 editTiles(
-                    largeTiles,
-                    ClickAction.REMOVE,
-                    onRemoveTile,
-                    { false },
-                    indicatePosition = true
+                    tiles = largeTiles,
+                    clickAction = ClickAction.REMOVE,
+                    onClick = onRemove,
+                    isIconOnly = { false },
+                    dragAndDropState = dragAndDropState,
+                    acceptDrops = { !isIconOnly(it) },
+                    onDrop = onAdd,
+                    indicatePosition = true,
                 )
             }
         }
+
         CurrentTilesContainer {
             TileLazyGrid(
                 columns = GridCells.Fixed(columns),
-                modifier = Modifier.height(smallGridHeight),
+                modifier =
+                    Modifier.height(smallGridHeight)
+                        .dragAndDropTileList(dragAndDropState, { isIconOnly(it) }, onAdd)
             ) {
                 editTiles(
-                    smallTiles,
-                    ClickAction.REMOVE,
-                    onRemoveTile,
-                    { true },
+                    tiles = smallTiles,
+                    clickAction = ClickAction.REMOVE,
+                    onClick = onRemove,
+                    isIconOnly = { true },
                     showLabels = showLabels,
-                    indicatePosition = true
+                    dragAndDropState = dragAndDropState,
+                    acceptDrops = { isIconOnly(it) },
+                    onDrop = onAdd,
+                    indicatePosition = true,
                 )
             }
         }
@@ -223,9 +262,11 @@
         iconTileHeight: Dp,
         tilePadding: Dp,
         addTileToEnd: (TileSpec) -> Unit,
+        onRemove: (TileSpec) -> Unit,
         isIconOnly: (TileSpec) -> Boolean,
         showLabels: Boolean,
         columns: Int,
+        dragAndDropState: DragAndDropState,
     ) {
         val (tilesStock, tilesCustom) = tiles.partition { it.appName == null }
         val (smallTiles, largeTiles) = tilesStock.partition { isIconOnly(it.tileSpec) }
@@ -239,13 +280,27 @@
         val gridHeight =
             largeGridHeight + smallGridHeight + largeGridHeightCustom + (tilePadding * 2)
 
+        val onDrop: (TileSpec, Int) -> Unit by rememberUpdatedState { tileSpec, _ ->
+            onRemove(tileSpec)
+        }
+
         AvailableTilesContainer {
             TileLazyGrid(
                 columns = GridCells.Fixed(columns),
-                modifier = Modifier.height(gridHeight),
+                modifier =
+                    Modifier.height(gridHeight)
+                        .dragAndDropTileList(dragAndDropState, { true }, onDrop)
             ) {
                 // Large tiles
-                editTiles(largeTiles, ClickAction.ADD, addTileToEnd, isIconOnly)
+                editTiles(
+                    largeTiles,
+                    ClickAction.ADD,
+                    addTileToEnd,
+                    isIconOnly,
+                    dragAndDropState,
+                    acceptDrops = { true },
+                    onDrop = onDrop,
+                )
                 fillUpRow(nTiles = largeTiles.size, columns = columns / 2)
 
                 // Small tiles
@@ -254,7 +309,10 @@
                     ClickAction.ADD,
                     addTileToEnd,
                     isIconOnly,
-                    showLabels = showLabels
+                    showLabels = showLabels,
+                    dragAndDropState = dragAndDropState,
+                    acceptDrops = { true },
+                    onDrop = onDrop,
                 )
                 fillUpRow(nTiles = smallTiles.size, columns = columns)
 
@@ -264,7 +322,10 @@
                     ClickAction.ADD,
                     addTileToEnd,
                     isIconOnly,
-                    showLabels = showLabels
+                    showLabels = showLabels,
+                    dragAndDropState = dragAndDropState,
+                    acceptDrops = { true },
+                    onDrop = onDrop,
                 )
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
new file mode 100644
index 0000000..9b4d10f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.ui.compose
+
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.lazy.grid.GridCells
+import androidx.compose.foundation.lazy.grid.GridItemSpan
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.dimensionResource
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.android.systemui.qs.panels.ui.viewmodel.QuickQuickSettingsViewModel
+import com.android.systemui.res.R
+
+@Composable
+fun QuickQuickSettings(
+    viewModel: QuickQuickSettingsViewModel,
+    modifier: Modifier = Modifier,
+) {
+    val sizedTiles by
+        viewModel.tileViewModels.collectAsStateWithLifecycle(initialValue = emptyList())
+    val tiles = sizedTiles.map { it.tile }
+
+    DisposableEffect(tiles) {
+        val token = Any()
+        tiles.forEach { it.startListening(token) }
+        onDispose { tiles.forEach { it.stopListening(token) } }
+    }
+    val columns by viewModel.columns.collectAsStateWithLifecycle()
+
+    TileLazyGrid(modifier = modifier, columns = GridCells.Fixed(columns)) {
+        items(
+            tiles.size,
+            key = { index -> sizedTiles[index].tile.spec.spec },
+            span = { index -> GridItemSpan(sizedTiles[index].width) }
+        ) { index ->
+            Tile(
+                tile = tiles[index],
+                iconOnly = sizedTiles[index].width == 1,
+                modifier = Modifier.height(dimensionResource(id = R.dimen.qs_tile_height))
+            )
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/StretchedGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/StretchedGridLayout.kt
index 7f4e0a7..4a90102 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/StretchedGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/StretchedGridLayout.kt
@@ -30,8 +30,8 @@
 import com.android.systemui.qs.panels.shared.model.SizedTile
 import com.android.systemui.qs.panels.shared.model.TileRow
 import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.FixedColumnsSizeViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.IconTilesViewModel
-import com.android.systemui.qs.panels.ui.viewmodel.InfiniteGridSizeViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.res.R
@@ -42,13 +42,14 @@
 @Inject
 constructor(
     private val iconTilesViewModel: IconTilesViewModel,
-    private val gridSizeViewModel: InfiniteGridSizeViewModel,
+    private val gridSizeViewModel: FixedColumnsSizeViewModel,
 ) : GridLayout {
 
     @Composable
     override fun TileGrid(
         tiles: List<TileViewModel>,
         modifier: Modifier,
+        editModeStart: () -> Unit,
     ) {
         DisposableEffect(tiles) {
             val token = Any()
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
index bbb98d3..127ef84 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
@@ -22,6 +22,7 @@
 import android.service.quicksettings.Tile.STATE_ACTIVE
 import android.service.quicksettings.Tile.STATE_INACTIVE
 import android.text.TextUtils
+import android.util.Log
 import androidx.appcompat.content.res.AppCompatResources
 import androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi
 import androidx.compose.animation.graphics.res.animatedVectorResource
@@ -74,14 +75,13 @@
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.compose.animation.Expandable
+import com.android.compose.modifiers.thenIf
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.common.ui.compose.Icon
 import com.android.systemui.common.ui.compose.load
 import com.android.systemui.plugins.qs.QSTile
-import com.android.systemui.qs.panels.ui.viewmodel.AvailableEditActions
 import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
-import com.android.systemui.qs.panels.ui.viewmodel.TileUiState
 import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.toUiState
 import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
@@ -91,7 +91,6 @@
 import java.util.function.Supplier
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.mapLatest
 
 object TileType
 
@@ -103,30 +102,30 @@
     showLabels: Boolean = false,
     modifier: Modifier,
 ) {
-    val state: TileUiState by
-        tile.state
-            .mapLatest { it.toUiState() }
-            .collectAsStateWithLifecycle(tile.currentState.toUiState())
-    val colors = TileDefaults.getColorForState(state.state)
+    val state by tile.state.collectAsStateWithLifecycle(tile.currentState)
+    val uiState = remember(state) { state.toUiState() }
+    val colors = TileDefaults.getColorForState(uiState.state)
 
     TileContainer(
         colors = colors,
         showLabels = showLabels,
-        label = state.label.toString(),
+        label = uiState.label,
         iconOnly = iconOnly,
+        clickEnabled = true,
         onClick = tile::onClick,
         onLongClick = tile::onLongClick,
         modifier = modifier,
     ) {
-        val icon = getTileIcon(icon = state.icon)
+        val icon = getTileIcon(icon = uiState.icon)
         if (iconOnly) {
             TileIcon(icon = icon, color = colors.icon, modifier = Modifier.align(Alignment.Center))
         } else {
             LargeTileContent(
-                label = state.label.toString(),
-                secondaryLabel = state.secondaryLabel.toString(),
+                label = uiState.label,
+                secondaryLabel = uiState.secondaryLabel,
                 icon = icon,
                 colors = colors,
+                clickEnabled = true,
                 onClick = tile::onSecondaryClick,
                 onLongClick = tile::onLongClick,
             )
@@ -140,7 +139,7 @@
     showLabels: Boolean,
     label: String,
     iconOnly: Boolean,
-    clickEnabled: Boolean = true,
+    clickEnabled: Boolean = false,
     onClick: (Expandable) -> Unit = {},
     onLongClick: (Expandable) -> Unit = {},
     modifier: Modifier = Modifier,
@@ -168,11 +167,12 @@
             Box(
                 modifier =
                     Modifier.fillMaxSize()
-                        .combinedClickable(
-                            enabled = clickEnabled,
-                            onClick = { onClick(it) },
-                            onLongClick = { onLongClick(it) }
-                        )
+                        .thenIf(clickEnabled) {
+                            Modifier.combinedClickable(
+                                onClick = { onClick(it) },
+                                onLongClick = { onLongClick(it) }
+                            )
+                        }
                         .tilePadding(),
             ) {
                 content()
@@ -197,7 +197,7 @@
     secondaryLabel: String?,
     icon: Icon,
     colors: TileColors,
-    clickEnabled: Boolean = true,
+    clickEnabled: Boolean = false,
     onClick: (Expandable) -> Unit = {},
     onLongClick: (Expandable) -> Unit = {},
 ) {
@@ -212,13 +212,12 @@
         ) {
             Box(
                 modifier =
-                    Modifier.fillMaxSize()
-                        .clip(TileDefaults.TileShape)
-                        .combinedClickable(
-                            enabled = clickEnabled,
+                    Modifier.fillMaxSize().clip(TileDefaults.TileShape).thenIf(clickEnabled) {
+                        Modifier.combinedClickable(
                             onClick = { onClick(it) },
                             onLongClick = { onLongClick(it) }
                         )
+                    }
             ) {
                 TileIcon(
                     icon = icon,
@@ -232,19 +231,26 @@
             Text(
                 label,
                 color = colors.label,
-                modifier = Modifier.basicMarquee(),
+                modifier = Modifier.tileMarquee(),
             )
             if (!TextUtils.isEmpty(secondaryLabel)) {
                 Text(
                     secondaryLabel ?: "",
                     color = colors.secondaryLabel,
-                    modifier = Modifier.basicMarquee(),
+                    modifier = Modifier.tileMarquee(),
                 )
             }
         }
     }
 }
 
+private fun Modifier.tileMarquee(): Modifier {
+    return basicMarquee(
+        iterations = 1,
+        initialDelayMillis = 200,
+    )
+}
+
 @Composable
 fun TileLazyGrid(
     modifier: Modifier = Modifier,
@@ -269,13 +275,29 @@
     onAddTile: (TileSpec, Int) -> Unit,
     onRemoveTile: (TileSpec) -> Unit,
 ) {
-    val (currentTiles, otherTiles) = tiles.partition { it.isCurrent }
-    val (otherTilesStock, otherTilesCustom) = otherTiles.partition { it.appName == null }
+    val currentListState = rememberEditListState(tiles)
+    val dragAndDropState = rememberDragAndDropState(currentListState)
+
+    val (currentTiles, otherTiles) = currentListState.tiles.partition { it.isCurrent }
+    val (otherTilesStock, otherTilesCustom) =
+        otherTiles
+            .filter { !dragAndDropState.isMoving(it.tileSpec) }
+            .partition { it.appName == null }
     val addTileToEnd: (TileSpec) -> Unit by rememberUpdatedState {
         onAddTile(it, CurrentTilesInteractor.POSITION_AT_END)
     }
 
-    TileLazyGrid(modifier = modifier, columns = columns) {
+    val onDropAdd: (TileSpec, Int) -> Unit by rememberUpdatedState { tileSpec, position ->
+        onAddTile(tileSpec, position)
+    }
+    val onDropRemove: (TileSpec, Int) -> Unit by rememberUpdatedState { tileSpec, _ ->
+        onRemoveTile(tileSpec)
+    }
+
+    TileLazyGrid(
+        modifier = modifier.dragAndDropTileList(dragAndDropState, { true }, onDropAdd),
+        columns = columns
+    ) {
         // These Text are just placeholders to see the different sections. Not final UI.
         item(span = { GridItemSpan(maxLineSpan) }) { Text("Current tiles", color = Color.White) }
 
@@ -285,6 +307,9 @@
             onRemoveTile,
             isIconOnly,
             indicatePosition = true,
+            dragAndDropState = dragAndDropState,
+            acceptDrops = { true },
+            onDrop = onDropAdd,
         )
 
         item(span = { GridItemSpan(maxLineSpan) }) { Text("Tiles to add", color = Color.White) }
@@ -294,6 +319,9 @@
             ClickAction.ADD,
             addTileToEnd,
             isIconOnly,
+            dragAndDropState = dragAndDropState,
+            acceptDrops = { true },
+            onDrop = onDropRemove,
         )
 
         item(span = { GridItemSpan(maxLineSpan) }) {
@@ -305,6 +333,9 @@
             ClickAction.ADD,
             addTileToEnd,
             isIconOnly,
+            dragAndDropState = dragAndDropState,
+            acceptDrops = { true },
+            onDrop = onDropRemove,
         )
     }
 }
@@ -314,6 +345,9 @@
     clickAction: ClickAction,
     onClick: (TileSpec) -> Unit,
     isIconOnly: (TileSpec) -> Boolean,
+    dragAndDropState: DragAndDropState,
+    acceptDrops: (TileSpec) -> Boolean,
+    onDrop: (TileSpec, Int) -> Unit,
     showLabels: Boolean = false,
     indicatePosition: Boolean = false,
 ) {
@@ -322,41 +356,44 @@
         key = { tiles[it].tileSpec.spec },
         span = { GridItemSpan(if (isIconOnly(tiles[it].tileSpec)) 1 else 2) },
         contentType = { TileType }
-    ) {
-        val viewModel = tiles[it]
-        val canClick =
-            when (clickAction) {
-                ClickAction.ADD -> AvailableEditActions.ADD in viewModel.availableEditActions
-                ClickAction.REMOVE -> AvailableEditActions.REMOVE in viewModel.availableEditActions
-            }
-        val onClickActionName =
-            when (clickAction) {
-                ClickAction.ADD ->
-                    stringResource(id = R.string.accessibility_qs_edit_tile_add_action)
-                ClickAction.REMOVE ->
-                    stringResource(id = R.string.accessibility_qs_edit_remove_tile_action)
-            }
-        val stateDescription =
-            if (indicatePosition) {
-                stringResource(id = R.string.accessibility_qs_edit_position, it + 1)
-            } else {
-                ""
-            }
-
+    ) { index ->
+        val viewModel = tiles[index]
         val iconOnly = isIconOnly(viewModel.tileSpec)
         val tileHeight = tileHeight(iconOnly && showLabels)
-        EditTile(
-            tileViewModel = viewModel,
-            iconOnly = iconOnly,
-            showLabels = showLabels,
-            clickEnabled = canClick,
-            onClick = { onClick.invoke(viewModel.tileSpec) },
-            modifier =
-                Modifier.height(tileHeight).animateItem().semantics {
-                    onClick(onClickActionName) { false }
-                    this.stateDescription = stateDescription
+
+        if (!dragAndDropState.isMoving(viewModel.tileSpec)) {
+            val onClickActionName =
+                when (clickAction) {
+                    ClickAction.ADD ->
+                        stringResource(id = R.string.accessibility_qs_edit_tile_add_action)
+                    ClickAction.REMOVE ->
+                        stringResource(id = R.string.accessibility_qs_edit_remove_tile_action)
                 }
-        )
+            val stateDescription =
+                if (indicatePosition) {
+                    stringResource(id = R.string.accessibility_qs_edit_position, index + 1)
+                } else {
+                    ""
+                }
+            EditTile(
+                tileViewModel = viewModel,
+                iconOnly = iconOnly,
+                showLabels = showLabels,
+                modifier =
+                    Modifier.height(tileHeight)
+                        .animateItem()
+                        .semantics {
+                            onClick(onClickActionName) { false }
+                            this.stateDescription = stateDescription
+                        }
+                        .dragAndDropTile(dragAndDropState, viewModel.tileSpec, acceptDrops, onDrop)
+                        .dragAndDropTileSource(
+                            viewModel.tileSpec,
+                            onClick,
+                            dragAndDropState,
+                        )
+            )
+        }
     }
 }
 
@@ -365,8 +402,6 @@
     tileViewModel: EditTileViewModel,
     iconOnly: Boolean,
     showLabels: Boolean,
-    clickEnabled: Boolean,
-    onClick: () -> Unit,
     modifier: Modifier = Modifier,
 ) {
     val label = tileViewModel.label.load() ?: tileViewModel.tileSpec.spec
@@ -377,9 +412,6 @@
         showLabels = showLabels,
         label = label,
         iconOnly = iconOnly,
-        clickEnabled = clickEnabled,
-        onClick = { onClick() },
-        onLongClick = { onClick() },
         modifier = modifier,
     ) {
         if (iconOnly) {
@@ -394,9 +426,6 @@
                 secondaryLabel = tileViewModel.appName?.load(),
                 icon = tileViewModel.icon,
                 colors = colors,
-                clickEnabled = clickEnabled,
-                onClick = { onClick() },
-                onLongClick = { onClick() },
             )
         }
     }
@@ -427,6 +456,7 @@
     animateToEnd: Boolean = false,
     modifier: Modifier = Modifier,
 ) {
+    Log.d("Fabian", "Recomposing tile icon")
     val iconModifier = modifier.size(dimensionResource(id = R.dimen.qs_icon_size))
     val context = LocalContext.current
     val loadedDrawable =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt
index 2dab7c3..8c57d41 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileGrid.kt
@@ -23,9 +23,13 @@
 import com.android.systemui.qs.panels.ui.viewmodel.TileGridViewModel
 
 @Composable
-fun TileGrid(viewModel: TileGridViewModel, modifier: Modifier = Modifier) {
+fun TileGrid(
+    viewModel: TileGridViewModel,
+    modifier: Modifier = Modifier,
+    editModeStart: () -> Unit
+) {
     val gridLayout by viewModel.gridLayout.collectAsStateWithLifecycle()
     val tiles by viewModel.tileViewModels.collectAsStateWithLifecycle(emptyList())
 
-    gridLayout.TileGrid(tiles, modifier)
+    gridLayout.TileGrid(tiles, modifier, editModeStart)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
index 19b8c66..62bfc72 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
@@ -27,6 +27,8 @@
 import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor.Companion.POSITION_AT_END
 import com.android.systemui.qs.pipeline.domain.interactor.MinimumTilesInteractor
 import com.android.systemui.qs.pipeline.shared.TileSpec
+import javax.inject.Inject
+import javax.inject.Named
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -37,22 +39,20 @@
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
-import javax.inject.Inject
-import javax.inject.Named
 
 @SysUISingleton
 @OptIn(ExperimentalCoroutinesApi::class)
 class EditModeViewModel
 @Inject
 constructor(
-        private val editTilesListInteractor: EditTilesListInteractor,
-        private val currentTilesInteractor: CurrentTilesInteractor,
-        private val tilesAvailabilityInteractor: TilesAvailabilityInteractor,
-        private val minTilesInteractor: MinimumTilesInteractor,
-        @Named("Default") private val defaultGridLayout: GridLayout,
-        @Application private val applicationScope: CoroutineScope,
-        gridLayoutTypeInteractor: GridLayoutTypeInteractor,
-        gridLayoutMap: Map<GridLayoutType, @JvmSuppressWildcards GridLayout>,
+    private val editTilesListInteractor: EditTilesListInteractor,
+    private val currentTilesInteractor: CurrentTilesInteractor,
+    private val tilesAvailabilityInteractor: TilesAvailabilityInteractor,
+    private val minTilesInteractor: MinimumTilesInteractor,
+    @Named("Default") private val defaultGridLayout: GridLayout,
+    @Application private val applicationScope: CoroutineScope,
+    gridLayoutTypeInteractor: GridLayoutTypeInteractor,
+    gridLayoutMap: Map<GridLayoutType, @JvmSuppressWildcards GridLayout>,
 ) {
     private val _isEditing = MutableStateFlow(false)
 
@@ -93,10 +93,12 @@
                 val editTilesData = editTilesListInteractor.getTilesToEdit()
                 // Query only the non current platform tiles, as any current tile is clearly
                 // available
-                val unavailable = tilesAvailabilityInteractor.getUnavailableTiles(
-                        editTilesData.stockTiles.map { it.tileSpec }
-                                .minus(currentTilesInteractor.currentTilesSpecs.toSet())
-                )
+                val unavailable =
+                    tilesAvailabilityInteractor.getUnavailableTiles(
+                        editTilesData.stockTiles
+                            .map { it.tileSpec }
+                            .minus(currentTilesInteractor.currentTilesSpecs.toSet())
+                    )
                 currentTilesInteractor.currentTiles.map { tiles ->
                     val currentSpecs = tiles.map { it.spec }
                     val canRemoveTiles = currentSpecs.size > minimumTiles
@@ -106,28 +108,28 @@
                     val nonCurrentTiles = allTiles.filter { it.tileSpec !in currentSpecs }
 
                     (currentTiles + nonCurrentTiles)
-                            .filterNot { it.tileSpec in unavailable }
-                            .map {
-                                val current = it.tileSpec in currentSpecs
-                                val availableActions = buildSet {
-                                    if (current) {
-                                        add(AvailableEditActions.MOVE)
-                                        if (canRemoveTiles) {
-                                            add(AvailableEditActions.REMOVE)
-                                        }
-                                    } else {
-                                        add(AvailableEditActions.ADD)
+                        .filterNot { it.tileSpec in unavailable }
+                        .map {
+                            val current = it.tileSpec in currentSpecs
+                            val availableActions = buildSet {
+                                if (current) {
+                                    add(AvailableEditActions.MOVE)
+                                    if (canRemoveTiles) {
+                                        add(AvailableEditActions.REMOVE)
                                     }
+                                } else {
+                                    add(AvailableEditActions.ADD)
                                 }
-                                EditTileViewModel(
-                                        it.tileSpec,
-                                        it.icon,
-                                        it.label,
-                                        it.appName,
-                                        current,
-                                        availableActions
-                                )
                             }
+                            EditTileViewModel(
+                                it.tileSpec,
+                                it.icon,
+                                it.label,
+                                it.appName,
+                                current,
+                                availableActions
+                            )
+                        }
                 }
             } else {
                 emptyFlow()
@@ -144,13 +146,16 @@
         _isEditing.value = false
     }
 
-    /** Immediately moves [tileSpec] to [position]. */
-    fun moveTile(tileSpec: TileSpec, position: Int) {
-        throw NotImplementedError("This is not supported yet")
-    }
-
-    /** Immediately adds [tileSpec] to the current tiles at [position]. */
+    /**
+     * Immediately adds [tileSpec] to the current tiles at [position]. If the [tileSpec] was already
+     * present, it will be moved to the new position.
+     */
     fun addTile(tileSpec: TileSpec, position: Int = POSITION_AT_END) {
+        // Removing tile if it's already present to insert it at the new index.
+        if (currentTilesInteractor.currentTilesSpecs.contains(tileSpec)) {
+            removeTile(tileSpec)
+        }
+
         currentTilesInteractor.addTile(tileSpec, position)
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditTileViewModel.kt
index ba9a044..a4c8638 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditTileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditTileViewModel.kt
@@ -26,7 +26,7 @@
  * [isCurrent] indicates whether this tile is part of the current set of tiles that the user sees in
  * Quick Settings.
  */
-class EditTileViewModel(
+data class EditTileViewModel(
     val tileSpec: TileSpec,
     val icon: Icon,
     val label: Text,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/FixedColumnsSizeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/FixedColumnsSizeViewModel.kt
new file mode 100644
index 0000000..865c86b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/FixedColumnsSizeViewModel.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.qs.panels.domain.interactor.FixedColumnsSizeInteractor
+import javax.inject.Inject
+import kotlinx.coroutines.flow.StateFlow
+
+interface FixedColumnsSizeViewModel {
+    val columns: StateFlow<Int>
+}
+
+@SysUISingleton
+class FixedColumnsSizeViewModelImpl @Inject constructor(interactor: FixedColumnsSizeInteractor) :
+    FixedColumnsSizeViewModel {
+    override val columns: StateFlow<Int> = interactor.columns
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridSizeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridSizeViewModel.kt
deleted file mode 100644
index a4ee58f..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridSizeViewModel.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.panels.ui.viewmodel
-
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.qs.panels.domain.interactor.InfiniteGridSizeInteractor
-import javax.inject.Inject
-import kotlinx.coroutines.flow.StateFlow
-
-interface InfiniteGridSizeViewModel {
-    val columns: StateFlow<Int>
-}
-
-@SysUISingleton
-class InfiniteGridSizeViewModelImpl @Inject constructor(interactor: InfiniteGridSizeInteractor) :
-    InfiniteGridSizeViewModel {
-    override val columns: StateFlow<Int> = interactor.columns
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
new file mode 100644
index 0000000..28bf474
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModel.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.qs.panels.domain.interactor.PaginatedGridInteractor
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.stateIn
+
+@SysUISingleton
+class PaginatedGridViewModel
+@Inject
+constructor(
+    iconTilesViewModel: IconTilesViewModel,
+    gridSizeViewModel: FixedColumnsSizeViewModel,
+    iconLabelVisibilityViewModel: IconLabelVisibilityViewModel,
+    paginatedGridInteractor: PaginatedGridInteractor,
+    @Application applicationScope: CoroutineScope,
+) :
+    IconTilesViewModel by iconTilesViewModel,
+    FixedColumnsSizeViewModel by gridSizeViewModel,
+    IconLabelVisibilityViewModel by iconLabelVisibilityViewModel {
+    val rows =
+        paginatedGridInteractor.rows.stateIn(
+            applicationScope,
+            SharingStarted.WhileSubscribed(),
+            paginatedGridInteractor.defaultRows,
+        )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PartitionedGridViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PartitionedGridViewModel.kt
index 730cf63..2049edb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PartitionedGridViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/PartitionedGridViewModel.kt
@@ -24,9 +24,9 @@
 @Inject
 constructor(
     iconTilesViewModel: IconTilesViewModel,
-    gridSizeViewModel: InfiniteGridSizeViewModel,
+    gridSizeViewModel: FixedColumnsSizeViewModel,
     iconLabelVisibilityViewModel: IconLabelVisibilityViewModel,
 ) :
     IconTilesViewModel by iconTilesViewModel,
-    InfiniteGridSizeViewModel by gridSizeViewModel,
+    FixedColumnsSizeViewModel by gridSizeViewModel,
     IconLabelVisibilityViewModel by iconLabelVisibilityViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt
new file mode 100644
index 0000000..bb00494
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModel.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.ui.viewmodel
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.qs.panels.domain.interactor.QuickQuickSettingsRowInteractor
+import com.android.systemui.qs.panels.shared.model.SizedTile
+import com.android.systemui.qs.panels.shared.model.TileRow
+import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.mapLatest
+import kotlinx.coroutines.flow.stateIn
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SysUISingleton
+class QuickQuickSettingsViewModel
+@Inject
+constructor(
+    tilesInteractor: CurrentTilesInteractor,
+    fixedColumnsSizeViewModel: FixedColumnsSizeViewModel,
+    quickQuickSettingsRowInteractor: QuickQuickSettingsRowInteractor,
+    private val iconTilesViewModel: IconTilesViewModel,
+    @Application private val applicationScope: CoroutineScope,
+) {
+
+    val columns = fixedColumnsSizeViewModel.columns
+
+    private val rows =
+        quickQuickSettingsRowInteractor.rows.stateIn(
+            applicationScope,
+            SharingStarted.WhileSubscribed(),
+            quickQuickSettingsRowInteractor.defaultRows
+        )
+
+    val tileViewModels: StateFlow<List<SizedTile<TileViewModel>>> =
+        columns
+            .flatMapLatest { columns ->
+                tilesInteractor.currentTiles.combine(rows, ::Pair).mapLatest { (tiles, rows) ->
+                    tiles
+                        .map { SizedTile(TileViewModel(it.tile, it.spec), it.spec.width) }
+                        .let { splitInRowsSequence(it, columns).take(rows).toList().flatten() }
+                }
+            }
+            .stateIn(
+                applicationScope,
+                SharingStarted.WhileSubscribed(),
+                tilesInteractor.currentTiles.value
+                    .map { SizedTile(TileViewModel(it.tile, it.spec), it.spec.width) }
+                    .let {
+                        splitInRowsSequence(it, columns.value).take(rows.value).toList().flatten()
+                    }
+            )
+
+    private val TileSpec.width: Int
+        get() = if (iconTilesViewModel.isIconTile(this)) 1 else 2
+
+    companion object {
+        private fun splitInRowsSequence(
+            tiles: List<SizedTile<TileViewModel>>,
+            columns: Int,
+        ): Sequence<List<SizedTile<TileViewModel>>> = sequence {
+            val row = TileRow<TileViewModel>(columns)
+            for (tile in tiles) {
+                check(tile.width <= columns)
+                if (!row.maybeAddTile(tile)) {
+                    // Couldn't add tile to previous row, create a row with the current tiles
+                    // and start a new one
+                    yield(row.tiles)
+                    row.clear()
+                    row.maybeAddTile(tile)
+                }
+            }
+            if (row.tiles.isNotEmpty()) {
+                yield(row.tiles)
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt
index 578a292..4ec59c9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileUiState.kt
@@ -16,20 +16,22 @@
 
 package com.android.systemui.qs.panels.ui.viewmodel
 
+import androidx.compose.runtime.Immutable
 import com.android.systemui.plugins.qs.QSTile
 import java.util.function.Supplier
 
+@Immutable
 data class TileUiState(
-    val label: CharSequence,
-    val secondaryLabel: CharSequence,
+    val label: String,
+    val secondaryLabel: String,
     val state: Int,
     val icon: Supplier<QSTile.Icon>,
 )
 
 fun QSTile.State.toUiState(): TileUiState {
     return TileUiState(
-        label ?: "",
-        secondaryLabel ?: "",
+        label?.toString() ?: "",
+        secondaryLabel?.toString() ?: "",
         state,
         icon?.let { Supplier { icon } } ?: iconSupplier,
     )
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileViewModel.kt
index 7505b90..8578bb0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/TileViewModel.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.qs.panels.ui.viewmodel
 
+import androidx.compose.runtime.Immutable
 import com.android.systemui.animation.Expandable
 import com.android.systemui.plugins.qs.QSTile
 import com.android.systemui.qs.pipeline.shared.TileSpec
@@ -25,6 +26,7 @@
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.onStart
 
+@Immutable
 class TileViewModel(private val tile: QSTile, val spec: TileSpec) {
     val state: Flow<QSTile.State> =
         conflatedCallbackFlow {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddable.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddable.kt
index b5bef9f..88f7169 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddable.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddable.kt
@@ -41,12 +41,7 @@
 
     override fun ProducerScope<AutoAddSignal>.getCallback(): CastController.Callback {
         return CastController.Callback {
-            val isCasting =
-                controller.castDevices.any {
-                    it.state == CastController.CastDevice.STATE_CONNECTED ||
-                        it.state == CastController.CastDevice.STATE_CONNECTING
-                }
-            if (isCasting) {
+            if (controller.castDevices.any { it.isCasting }) {
                 sendAdd()
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
index b1b67cf..44c846b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -350,6 +350,10 @@
 
         initialLongPressProperties?.width = width
         finalLongPressProperties?.width = LONG_PRESS_EFFECT_WIDTH_SCALE * width
+
+        val deltaW = (LONG_PRESS_EFFECT_WIDTH_SCALE - 1f) * width
+        paddingForLaunch.left = -deltaW.toInt() / 2
+        paddingForLaunch.right = deltaW.toInt() / 2
     }
 
     private fun maybeUpdateLongPressEffectHeight(height: Float) {
@@ -357,6 +361,10 @@
 
         initialLongPressProperties?.height = height
         finalLongPressProperties?.height = LONG_PRESS_EFFECT_HEIGHT_SCALE * height
+
+        val deltaH = (LONG_PRESS_EFFECT_HEIGHT_SCALE - 1f) * height
+        paddingForLaunch.top = -deltaH.toInt() / 2
+        paddingForLaunch.bottom = deltaH.toInt() / 2
     }
 
     override fun onFocusChanged(gainFocus: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
@@ -432,14 +440,16 @@
         longPressEffect?.callback =
             object : QSLongPressEffect.Callback {
 
-                override fun onPrepareForLaunch() {
-                    prepareForLaunch()
-                }
-
                 override fun onResetProperties() {
                     resetLongPressEffectProperties()
                 }
 
+                override fun onEffectFinishedReversing() {
+                    // The long-press effect properties finished at the same starting point.
+                    // This is the same as if the properties were reset
+                    haveLongPressPropertiesBeenReset = true
+                }
+
                 override fun onStartAnimator() {
                     if (longPressEffectAnimator?.isRunning != true) {
                         longPressEffectAnimator =
@@ -1043,6 +1053,7 @@
                 getOverlayColorForState(Tile.STATE_ACTIVE),
                 Utils.getColorAttrDefaultColor(context, R.attr.onShadeActive),
             )
+        prepareForLaunch()
     }
 
     private fun changeCornerRadius(radius: Float) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 169cdc1..8a72e8d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -60,7 +60,7 @@
 import com.android.systemui.statusbar.pipeline.shared.data.model.DefaultConnectionModel;
 import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository;
 import com.android.systemui.statusbar.policy.CastController;
-import com.android.systemui.statusbar.policy.CastController.CastDevice;
+import com.android.systemui.statusbar.policy.CastDevice;
 import com.android.systemui.statusbar.policy.HotspotController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.DialogKt;
@@ -193,14 +193,13 @@
     // case where multiple devices were active :-/.
     private boolean willPopDialog() {
         List<CastDevice> activeDevices = getActiveDevices();
-        return activeDevices.isEmpty() || (activeDevices.get(0).tag instanceof RouteInfo);
+        return activeDevices.isEmpty() || (activeDevices.get(0).getTag() instanceof RouteInfo);
     }
 
     private List<CastDevice> getActiveDevices() {
         ArrayList<CastDevice> activeDevices = new ArrayList<>();
         for (CastDevice device : mController.getCastDevices()) {
-            if (device.state == CastDevice.STATE_CONNECTED
-                    || device.state == CastDevice.STATE_CONNECTING) {
+            if (device.isCasting()) {
                 activeDevices.add(device);
             }
         }
@@ -276,7 +275,7 @@
         // We always choose the first device that's in the CONNECTED state in the case where
         // multiple devices are CONNECTED at the same time.
         for (CastDevice device : devices) {
-            if (device.state == CastDevice.STATE_CONNECTED) {
+            if (device.getState() == CastDevice.CastState.Connected) {
                 state.value = true;
                 state.secondaryLabel = getDeviceName(device);
                 state.stateDescription = state.stateDescription + ","
@@ -284,7 +283,7 @@
                         R.string.accessibility_cast_name, state.label);
                 connecting = false;
                 break;
-            } else if (device.state == CastDevice.STATE_CONNECTING) {
+            } else if (device.getState() == CastDevice.CastState.Connecting) {
                 connecting = true;
             }
         }
@@ -315,7 +314,7 @@
     }
 
     private String getDeviceName(CastDevice device) {
-        return device.name != null ? device.name
+        return device.getName() != null ? device.getName()
                 : mContext.getString(R.string.quick_settings_cast_device_default_name);
     }
 
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 4ebebea..bdf935e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -42,7 +42,7 @@
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settingslib.notification.EnableZenModeDialog;
+import com.android.settingslib.notification.modes.EnableZenModeDialog;
 import com.android.systemui.Prefs;
 import com.android.systemui.animation.DialogCuj;
 import com.android.systemui.animation.DialogTransitionAnimator;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt
index 70f3b84..a3feb2b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/RecordIssueTile.kt
@@ -46,6 +46,7 @@
 import com.android.systemui.recordissue.IssueRecordingService
 import com.android.systemui.recordissue.IssueRecordingState
 import com.android.systemui.recordissue.RecordIssueDialogDelegate
+import com.android.systemui.recordissue.RecordIssueModule.Companion.TILE_SPEC
 import com.android.systemui.recordissue.TraceurMessageSender
 import com.android.systemui.res.R
 import com.android.systemui.screenrecord.RecordingService
@@ -197,8 +198,4 @@
             expandedAccessibilityClassName = Switch::class.java.name
         }
     }
-
-    companion object {
-        const val TILE_SPEC = "record_issue"
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
index 4715230..284239a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
@@ -47,6 +47,7 @@
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.res.R;
 import com.android.systemui.screenrecord.RecordingController;
+import com.android.systemui.screenrecord.data.model.ScreenRecordModel;
 import com.android.systemui.settings.UserContextProvider;
 import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -146,8 +147,9 @@
         if (isRecording) {
             state.secondaryLabel = mContext.getString(R.string.quick_settings_screen_record_stop);
         } else if (isStarting) {
-            // round, since the timer isn't exact
-            int countdown = (int) Math.floorDiv(mMillisUntilFinished + 500, 1000);
+            int countdown =
+                    (int) ScreenRecordModel.Starting.Companion.toCountdownSeconds(
+                            mMillisUntilFinished);
             state.secondaryLabel = String.format("%d...", countdown);
         } else {
             state.secondaryLabel = mContext.getString(R.string.quick_settings_screen_record_start);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelFactory.kt
index 4c21080..8c75cf0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelFactory.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.qs.tiles.base.viewmodel
 
 import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.UiBackground
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.qs.tiles.base.analytics.QSTileAnalytics
@@ -61,6 +62,7 @@
         private val qsTileConfigProvider: QSTileConfigProvider,
         private val systemClock: SystemClock,
         @Background private val backgroundDispatcher: CoroutineDispatcher,
+        @UiBackground private val uiBackgroundDispatcher: CoroutineDispatcher,
         private val customTileComponentBuilder: CustomTileComponent.Builder,
     ) : QSTileViewModelFactory<CustomTileDataModel> {
 
@@ -86,6 +88,7 @@
                 qsTileLogger,
                 systemClock,
                 backgroundDispatcher,
+                uiBackgroundDispatcher,
                 component.coroutineScope(),
             )
         }
@@ -106,6 +109,7 @@
         private val qsTileConfigProvider: QSTileConfigProvider,
         private val systemClock: SystemClock,
         @Background private val backgroundDispatcher: CoroutineDispatcher,
+        @UiBackground private val uiBackgroundDispatcher: CoroutineDispatcher,
         private val coroutineScopeFactory: QSTileCoroutineScopeFactory,
     ) : QSTileViewModelFactory<T> {
 
@@ -136,6 +140,7 @@
                 qsTileLogger,
                 systemClock,
                 backgroundDispatcher,
+                uiBackgroundDispatcher,
                 coroutineScopeFactory.create(),
             )
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt
index 8782524..9e84f01 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt
@@ -40,6 +40,7 @@
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.cancel
+import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -59,7 +60,9 @@
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.flow.shareIn
 import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.flow.transformLatest
 import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
 
 /**
  * Provides a hassle-free way to implement new tiles according to current System UI architecture
@@ -81,6 +84,7 @@
     private val qsTileLogger: QSTileLogger,
     private val systemClock: SystemClock,
     private val backgroundDispatcher: CoroutineDispatcher,
+    uiBackgroundDispatcher: CoroutineDispatcher,
     private val tileScope: CoroutineScope,
 ) : QSTileViewModel, Dumpable {
 
@@ -93,18 +97,16 @@
 
     private val tileData: SharedFlow<DATA_TYPE> = createTileDataFlow()
 
-    override val state: SharedFlow<QSTileState> =
+    override val state: StateFlow<QSTileState?> =
         tileData
             .map { data ->
-                mapper().map(config, data).also { state ->
-                    qsTileLogger.logStateUpdate(spec, state, data)
-                }
+                withContext(uiBackgroundDispatcher) { mapper().map(config, data) }
+                    .also { state -> qsTileLogger.logStateUpdate(spec, state, data) }
             }
-            .flowOn(backgroundDispatcher)
-            .shareIn(
+            .stateIn(
                 tileScope,
                 SharingStarted.WhileSubscribed(),
-                replay = 1,
+                null,
             )
     override val isAvailable: StateFlow<Boolean> =
         users
@@ -147,26 +149,26 @@
 
     private fun createTileDataFlow(): SharedFlow<DATA_TYPE> =
         users
-            .flatMapLatest { user ->
-                val updateTriggers =
-                    merge(
-                            userInputFlow(user),
-                            forceUpdates
-                                .map { DataUpdateTrigger.ForceUpdate }
-                                .onEach { qsTileLogger.logForceUpdate(spec) },
-                        )
-                        .onStart {
-                            emit(DataUpdateTrigger.InitialRequest)
-                            qsTileLogger.logInitialRequest(spec)
-                        }
-                        .shareIn(tileScope, SharingStarted.WhileSubscribed())
-                tileDataInteractor()
-                    .tileData(user, updateTriggers)
-                    // combine makes sure updateTriggers is always listened even if
-                    // tileDataInteractor#tileData doesn't flatMapLatest on it
-                    .combine(updateTriggers) { data, _ -> data }
-                    .cancellable()
-                    .flowOn(backgroundDispatcher)
+            .transformLatest { user ->
+                coroutineScope {
+                    val updateTriggers: Flow<DataUpdateTrigger> =
+                        merge(
+                                userInputFlow(user),
+                                forceUpdates
+                                    .map { DataUpdateTrigger.ForceUpdate }
+                                    .onEach { qsTileLogger.logForceUpdate(spec) },
+                            )
+                            .onStart { qsTileLogger.logInitialRequest(spec) }
+                            .stateIn(this, SharingStarted.Eagerly, DataUpdateTrigger.InitialRequest)
+                    tileDataInteractor()
+                        .tileData(user, updateTriggers)
+                        // combine makes sure updateTriggers is always listened even if
+                        // tileDataInteractor#tileData doesn't transformLatest on it
+                        .combine(updateTriggers) { data, _ -> data }
+                        .cancellable()
+                        .flowOn(backgroundDispatcher)
+                        .collect { emit(it) }
+                }
             }
             .distinctUntilChanged()
             .shareIn(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/QSZenModeDialogMetricsLogger.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/QSZenModeDialogMetricsLogger.java
index 1b81a99..b3f66a6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/QSZenModeDialogMetricsLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/QSZenModeDialogMetricsLogger.java
@@ -19,7 +19,7 @@
 import android.content.Context;
 
 import com.android.internal.logging.UiEventLogger;
-import com.android.settingslib.notification.ZenModeDialogMetricsLogger;
+import com.android.settingslib.notification.modes.ZenModeDialogMetricsLogger;
 import com.android.systemui.qs.QSDndEvent;
 import com.android.systemui.qs.QSEvents;
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingDataInteractor.kt
new file mode 100644
index 0000000..1af328e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingDataInteractor.kt
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.impl.irecording
+
+import android.os.UserHandle
+import com.android.systemui.Flags
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.recordissue.IssueRecordingState
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
+import javax.inject.Inject
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.onStart
+
+class IssueRecordingDataInteractor
+@Inject
+constructor(
+    private val state: IssueRecordingState,
+    @Background private val bgCoroutineContext: CoroutineContext,
+) : QSTileDataInteractor<IssueRecordingModel> {
+
+    override fun tileData(
+        user: UserHandle,
+        triggers: Flow<DataUpdateTrigger>
+    ): Flow<IssueRecordingModel> =
+        conflatedCallbackFlow {
+                val listener = Runnable { trySend(IssueRecordingModel(state.isRecording)) }
+                state.addListener(listener)
+                awaitClose { state.removeListener(listener) }
+            }
+            .onStart { emit(IssueRecordingModel(state.isRecording)) }
+            .distinctUntilChanged()
+            .flowOn(bgCoroutineContext)
+
+    override fun availability(user: UserHandle): Flow<Boolean> =
+        flowOf(android.os.Build.IS_DEBUGGABLE && Flags.recordIssueQsTile())
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapper.kt
new file mode 100644
index 0000000..ff931b3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapper.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.impl.irecording
+
+import android.content.res.Resources
+import android.content.res.Resources.Theme
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.res.R
+import javax.inject.Inject
+
+class IssueRecordingMapper
+@Inject
+constructor(
+    @Main private val resources: Resources,
+    private val theme: Theme,
+) : QSTileDataToStateMapper<IssueRecordingModel> {
+    override fun map(config: QSTileConfig, data: IssueRecordingModel): QSTileState =
+        QSTileState.build(resources, theme, config.uiConfig) {
+            if (data.isRecording) {
+                activationState = QSTileState.ActivationState.ACTIVE
+                secondaryLabel = resources.getString(R.string.qs_record_issue_stop)
+                icon = { Icon.Resource(R.drawable.qs_record_issue_icon_on, null) }
+            } else {
+                icon = { Icon.Resource(R.drawable.qs_record_issue_icon_off, null) }
+                activationState = QSTileState.ActivationState.INACTIVE
+                secondaryLabel = resources.getString(R.string.qs_record_issue_start)
+            }
+            supportedActions = setOf(QSTileState.UserAction.CLICK)
+            contentDescription = "$label, $secondaryLabel"
+        }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingModel.kt
new file mode 100644
index 0000000..260729b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingModel.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.impl.irecording
+
+@JvmInline value class IssueRecordingModel(val isRecording: Boolean)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractor.kt
new file mode 100644
index 0000000..4971fef
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractor.kt
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.impl.irecording
+
+import android.app.AlertDialog
+import android.app.BroadcastOptions
+import android.app.PendingIntent
+import android.util.Log
+import com.android.internal.jank.InteractionJankMonitor
+import com.android.systemui.animation.DialogCuj
+import com.android.systemui.animation.DialogTransitionAnimator
+import com.android.systemui.animation.Expandable
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
+import com.android.systemui.qs.tiles.base.interactor.QSTileInput
+import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+import com.android.systemui.recordissue.IssueRecordingService
+import com.android.systemui.recordissue.RecordIssueDialogDelegate
+import com.android.systemui.recordissue.RecordIssueModule.Companion.TILE_SPEC
+import com.android.systemui.screenrecord.RecordingService
+import com.android.systemui.settings.UserContextProvider
+import com.android.systemui.statusbar.phone.KeyguardDismissUtil
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import javax.inject.Inject
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.withContext
+
+private const val TAG = "IssueRecordingActionInteractor"
+
+class IssueRecordingUserActionInteractor
+@Inject
+constructor(
+    @Main private val mainCoroutineContext: CoroutineContext,
+    private val keyguardDismissUtil: KeyguardDismissUtil,
+    private val keyguardStateController: KeyguardStateController,
+    private val dialogTransitionAnimator: DialogTransitionAnimator,
+    private val panelInteractor: PanelInteractor,
+    private val userContextProvider: UserContextProvider,
+    private val delegateFactory: RecordIssueDialogDelegate.Factory,
+) : QSTileUserActionInteractor<IssueRecordingModel> {
+
+    override suspend fun handleInput(input: QSTileInput<IssueRecordingModel>) {
+        if (input.action is QSTileUserAction.Click) {
+            if (input.data.isRecording) {
+                stopIssueRecordingService()
+            } else {
+                withContext(mainCoroutineContext) { showPrompt(input.action.expandable) }
+            }
+        } else {
+            Log.v(TAG, "the RecordIssueTile doesn't handle ${input.action} events yet.")
+        }
+    }
+
+    private fun showPrompt(expandable: Expandable?) {
+        val dialog: AlertDialog =
+            delegateFactory
+                .create {
+                    startIssueRecordingService()
+                    dialogTransitionAnimator.disableAllCurrentDialogsExitAnimations()
+                    panelInteractor.collapsePanels()
+                }
+                .createDialog()
+        val dismissAction =
+            ActivityStarter.OnDismissAction {
+                // We animate from the touched view only if we are not on the keyguard, given
+                // that if we are we will dismiss it which will also collapse the shade.
+                if (expandable != null && !keyguardStateController.isShowing) {
+                    expandable
+                        .dialogTransitionController(
+                            DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN, TILE_SPEC)
+                        )
+                        ?.let { dialogTransitionAnimator.show(dialog, it) } ?: dialog.show()
+                } else {
+                    dialog.show()
+                }
+                false
+            }
+        keyguardDismissUtil.executeWhenUnlocked(dismissAction, false, true)
+    }
+
+    private fun startIssueRecordingService() =
+        PendingIntent.getForegroundService(
+                userContextProvider.userContext,
+                RecordingService.REQUEST_CODE,
+                IssueRecordingService.getStartIntent(userContextProvider.userContext),
+                PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
+            )
+            .send(BroadcastOptions.makeBasic().apply { isInteractive = true }.toBundle())
+
+    private fun stopIssueRecordingService() =
+        PendingIntent.getService(
+                userContextProvider.userContext,
+                RecordingService.REQUEST_CODE,
+                IssueRecordingService.getStopIntent(userContextProvider.userContext),
+                PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
+            )
+            .send(BroadcastOptions.makeBasic().apply { isInteractive = true }.toBundle())
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractor.kt
index 1e8ce58..233e913 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractor.kt
@@ -30,11 +30,9 @@
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.onStart
-import kotlinx.coroutines.flow.stateIn
 
 /** Observes one qr scanner state changes providing the [QRCodeScannerTileModel]. */
 class QRCodeScannerTileDataInteractor
@@ -66,11 +64,6 @@
             }
             .onStart { emit(generateModel()) }
             .flowOn(bgCoroutineContext)
-            .stateIn(
-                scope,
-                SharingStarted.WhileSubscribed(),
-                QRCodeScannerTileModel.TemporarilyUnavailable
-            )
 
     override fun availability(user: UserHandle): Flow<Boolean> =
         flowOf(qrController.isCameraAvailable)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/ui/ScreenRecordTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/ui/ScreenRecordTileMapper.kt
index 7446708..e74e77f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/ui/ScreenRecordTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/ui/ScreenRecordTileMapper.kt
@@ -61,7 +61,7 @@
                             contentDescription = null
                         )
                     icon = { loadedIcon }
-                    val countDown = Math.floorDiv(data.millisUntilStarted + 500, 1000)
+                    val countDown = data.countdownSeconds
                     sideViewIcon = QSTileState.SideViewIcon.None
                     secondaryLabel = String.format("%d...", countDown)
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
index ae6c014..30247c4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
@@ -54,18 +54,21 @@
             resources: Resources,
             theme: Theme,
             config: QSTileUIConfig,
-            build: Builder.() -> Unit
+            builder: Builder.() -> Unit
         ): QSTileState {
             val iconDrawable = resources.getDrawable(config.iconRes, theme)
             return build(
                 { Icon.Loaded(iconDrawable, null) },
                 resources.getString(config.labelRes),
-                build,
+                builder,
             )
         }
 
-        fun build(icon: () -> Icon?, label: CharSequence, build: Builder.() -> Unit): QSTileState =
-            Builder(icon, label).apply(build).build()
+        fun build(
+            icon: () -> Icon?,
+            label: CharSequence,
+            builder: Builder.() -> Unit
+        ): QSTileState = Builder(icon, label).apply { builder() }.build()
     }
 
     enum class ActivationState(val legacyState: Int) {
@@ -107,7 +110,9 @@
 
     sealed interface SideViewIcon {
         data class Custom(val icon: Icon) : SideViewIcon
+
         data object Chevron : SideViewIcon
+
         data object None : SideViewIcon
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt
index 226e2fa0..b1b0001 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt
@@ -17,7 +17,6 @@
 package com.android.systemui.qs.tiles.viewmodel
 
 import android.os.UserHandle
-import kotlinx.coroutines.flow.SharedFlow
 import kotlinx.coroutines.flow.StateFlow
 
 /**
@@ -31,7 +30,7 @@
 interface QSTileViewModel {
 
     /** State of the tile to be shown by the view. */
-    val state: SharedFlow<QSTileState>
+    val state: StateFlow<QSTileState?>
 
     val config: QSTileConfig
 
@@ -62,9 +61,7 @@
 }
 
 /**
- * Returns the immediate state of the tile or null if the state haven't been collected yet. Favor
- * reactive consumption over the [currentState], because there is no guarantee that current value
- * would be available at any time.
+ * Returns the immediate state of the tile or null if the state haven't been collected yet.
  */
 val QSTileViewModel.currentState: QSTileState?
-    get() = state.replayCache.lastOrNull()
+    get() = state.value
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
index 7be13e0..ba0a8d6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
@@ -38,6 +38,7 @@
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.flow.collectIndexed
+import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.map
@@ -168,6 +169,7 @@
                 if (listeningClients.size == 1) {
                     stateJob =
                         qsTileViewModel.state
+                            .filterNotNull()
                             .map { mapState(context, it, qsTileViewModel.config) }
                             .onEach { legacyState ->
                                 synchronized(callbacks) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/StubQSTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/StubQSTileViewModel.kt
index 64f1fd3..00b7e61 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/StubQSTileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/StubQSTileViewModel.kt
@@ -17,12 +17,11 @@
 package com.android.systemui.qs.tiles.viewmodel
 
 import android.os.UserHandle
-import kotlinx.coroutines.flow.SharedFlow
 import kotlinx.coroutines.flow.StateFlow
 
 object StubQSTileViewModel : QSTileViewModel {
 
-    override val state: SharedFlow<QSTileState>
+    override val state: StateFlow<QSTileState?>
         get() = error("Don't call stubs")
 
     override val config: QSTileConfig
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
index a04fa38..6ccd169 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
@@ -19,6 +19,7 @@
 import com.android.systemui.brightness.ui.viewmodel.BrightnessSliderViewModel
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.qs.panels.ui.viewmodel.EditModeViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.QuickQuickSettingsViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.TileGridViewModel
 import javax.inject.Inject
 
@@ -29,4 +30,5 @@
     val brightnessSliderViewModel: BrightnessSliderViewModel,
     val tileGridViewModel: TileGridViewModel,
     val editModeViewModel: EditModeViewModel,
+    val quickQuickSettingsViewModel: QuickQuickSettingsViewModel,
 )
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModel.kt
index bd748d5..66fcbac 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModel.kt
@@ -20,35 +20,54 @@
 import com.android.compose.animation.scene.Swipe
 import com.android.compose.animation.scene.UserAction
 import com.android.compose.animation.scene.UserActionResult
-import com.android.systemui.brightness.ui.viewmodel.BrightnessSliderViewModel
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.qs.panels.ui.viewmodel.EditModeViewModel
-import com.android.systemui.qs.panels.ui.viewmodel.TileGridViewModel
-import com.android.systemui.qs.ui.adapter.QSSceneAdapter
+import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.scene.shared.model.SceneFamilies
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.shared.model.ShadeAlignment
 import com.android.systemui.shade.ui.viewmodel.OverlayShadeViewModel
 import javax.inject.Inject
-import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
 
 /** Models UI state and handles user input for the Quick Settings Shade scene. */
 @SysUISingleton
 class QuickSettingsShadeSceneViewModel
 @Inject
 constructor(
+    private val shadeInteractor: ShadeInteractor,
     val overlayShadeViewModel: OverlayShadeViewModel,
-    val brightnessSliderViewModel: BrightnessSliderViewModel,
-    val tileGridViewModel: TileGridViewModel,
-    val editModeViewModel: EditModeViewModel,
-    val qsSceneAdapter: QSSceneAdapter,
+    val quickSettingsContainerViewModel: QuickSettingsContainerViewModel,
+    @Application applicationScope: CoroutineScope,
 ) {
+
+    val isEditing: StateFlow<Boolean> = quickSettingsContainerViewModel.editModeViewModel.isEditing
+
     val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> =
-        MutableStateFlow(
-                mapOf(
-                    Swipe.Up to SceneFamilies.Home,
-                    Back to SceneFamilies.Home,
-                )
+        isEditing
+            .map { editing -> destinations(editing) }
+            .stateIn(
+                applicationScope,
+                SharingStarted.WhileSubscribed(),
+                destinations(isEditing.value)
             )
-            .asStateFlow()
+
+    private fun destinations(editing: Boolean): Map<UserAction, UserActionResult> {
+        return buildMap {
+            put(
+                if (shadeInteractor.shadeAlignment == ShadeAlignment.Top) {
+                    Swipe.Up
+                } else {
+                    Swipe.Down
+                },
+                UserActionResult(SceneFamilies.Home)
+            )
+            if (!editing) {
+                put(Back, UserActionResult(SceneFamilies.Home))
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 23faf7d..b3624ad 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -26,11 +26,13 @@
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
 
 import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
+import static com.android.systemui.Flags.glanceableHubBackGesture;
 import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
 import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNFOLD_ANIMATION_FORWARDER;
 import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_AWAKE;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_COMMUNAL_HUB_SHOWING;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DOZING;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DREAMING;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE;
@@ -62,6 +64,7 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.util.Log;
 import android.view.InputDevice;
 import android.view.KeyCharacterMap;
@@ -90,11 +93,11 @@
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.keyguard.ui.view.InWindowLauncherUnlockAnimationManager;
 import com.android.systemui.model.SysUiState;
-import com.android.systemui.navigationbar.NavigationBar;
 import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarView;
 import com.android.systemui.navigationbar.NavigationModeController;
-import com.android.systemui.navigationbar.buttons.KeyButtonView;
+import com.android.systemui.navigationbar.views.NavigationBar;
+import com.android.systemui.navigationbar.views.NavigationBarView;
+import com.android.systemui.navigationbar.views.buttons.KeyButtonView;
 import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
 import com.android.systemui.scene.domain.interactor.SceneInteractor;
 import com.android.systemui.scene.shared.flag.SceneContainerFlag;
@@ -112,7 +115,7 @@
 import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
 import com.android.systemui.statusbar.policy.CallbackController;
 import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder;
-import com.android.wm.shell.shared.DesktopModeStatus;
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.sysui.ShellInterface;
 
 import dagger.Lazy;
@@ -177,7 +180,7 @@
     private boolean mBound;
     private boolean mIsEnabled;
 
-    private boolean mIsNonPrimaryUser;
+    private boolean mIsSystemOrVisibleBgUser;
     private int mCurrentBoundedUserId = -1;
     private boolean mInputFocusTransferStarted;
     private float mInputFocusTransferStartY;
@@ -629,6 +632,7 @@
             SysUiState sysUiState,
             Provider<SceneInteractor> sceneInteractor,
             UserTracker userTracker,
+            UserManager userManager,
             WakefulnessLifecycle wakefulnessLifecycle,
             UiEventLogger uiEventLogger,
             DisplayTracker displayTracker,
@@ -639,10 +643,18 @@
             Optional<UnfoldTransitionProgressForwarder> unfoldTransitionProgressForwarder,
             BroadcastDispatcher broadcastDispatcher
     ) {
-        // b/241601880: This component shouldn't be running for a non-primary user
-        mIsNonPrimaryUser = !Process.myUserHandle().equals(UserHandle.SYSTEM);
-        if (mIsNonPrimaryUser) {
-            Log.wtf(TAG_OPS, "Unexpected initialization for non-primary user", new Throwable());
+        // b/241601880: This component should only be running for primary users or
+        // secondaryUsers when visibleBackgroundUsers are supported.
+        boolean isSystemUser = Process.myUserHandle().equals(UserHandle.SYSTEM);
+        boolean isVisibleBackgroundUser =
+                userManager.isVisibleBackgroundUsersSupported() && !userManager.isUserForeground();
+        if (!isSystemUser && isVisibleBackgroundUser) {
+            Log.d(TAG_OPS, "Initialization for visibleBackgroundUser");
+        }
+        mIsSystemOrVisibleBgUser = isSystemUser || isVisibleBackgroundUser;
+        if (!mIsSystemOrVisibleBgUser) {
+            Log.wtf(TAG_OPS, "Unexpected initialization for non-system foreground user",
+                    new Throwable());
         }
 
         mContext = context;
@@ -782,7 +794,7 @@
 
     private void onStatusBarStateChanged(boolean keyguardShowing, boolean keyguardOccluded,
             boolean keyguardGoingAway, boolean bouncerShowing, boolean isDozing,
-            boolean panelExpanded, boolean isDreaming) {
+            boolean panelExpanded, boolean isDreaming, boolean communalShowing) {
         mSysUiState.setFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
                         keyguardShowing && !keyguardOccluded)
                 .setFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED,
@@ -792,6 +804,8 @@
                 .setFlag(SYSUI_STATE_BOUNCER_SHOWING, bouncerShowing)
                 .setFlag(SYSUI_STATE_DEVICE_DOZING, isDozing)
                 .setFlag(SYSUI_STATE_DEVICE_DREAMING, isDreaming)
+                .setFlag(SYSUI_STATE_COMMUNAL_HUB_SHOWING,
+                        glanceableHubBackGesture() && communalShowing)
                 .commitUpdate(mContext.getDisplayId());
     }
 
@@ -833,11 +847,12 @@
     }
 
     private void internalConnectToCurrentUser(String reason) {
-        if (mIsNonPrimaryUser) {
+        if (!mIsSystemOrVisibleBgUser) {
             // This should not happen, but if any per-user SysUI component has a dependency on OPS,
             // then this could get triggered
-            Log.w(TAG_OPS, "Skipping connection to overview service due to non-primary user "
-                    + "caller");
+            Log.w(TAG_OPS,
+                    "Skipping connection to overview service due to non-system foreground user "
+                            + "caller");
             return;
         }
         disconnectFromLauncherService(reason);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
index 2b717cb..8d0a386 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
@@ -57,8 +57,8 @@
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarView;
 import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.navigationbar.views.NavigationBarView;
 import com.android.systemui.res.R;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shared.system.QuickStepContract;
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt
index 4a4c73b..98a61df 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingService.kt
@@ -74,7 +74,7 @@
         when (intent?.action) {
             ACTION_START -> {
                 bgExecutor.execute {
-                    traceurMessageSender.startTracing(issueRecordingState.traceType)
+                    traceurMessageSender.startTracing(issueRecordingState.traceConfig)
                 }
                 issueRecordingState.isRecording = true
                 if (!issueRecordingState.recordScreen) {
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingState.kt b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingState.kt
index 4ea3345..7612900 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingState.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/IssueRecordingState.kt
@@ -18,11 +18,12 @@
 
 import android.content.Context
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.qs.tiles.RecordIssueTile
+import com.android.systemui.recordissue.RecordIssueModule.Companion.TILE_SPEC
 import com.android.systemui.res.R
 import com.android.systemui.settings.UserFileManager
 import com.android.systemui.settings.UserTracker
-import com.android.traceur.TraceUtils.PresetTraceType
+import com.android.traceur.PresetTraceConfigs
+import com.android.traceur.TraceConfig
 import java.util.concurrent.CopyOnWriteArrayList
 import javax.inject.Inject
 
@@ -35,11 +36,7 @@
 ) {
 
     private val prefs =
-        userFileManager.getSharedPreferences(
-            RecordIssueTile.TILE_SPEC,
-            Context.MODE_PRIVATE,
-            userTracker.userId
-        )
+        userFileManager.getSharedPreferences(TILE_SPEC, Context.MODE_PRIVATE, userTracker.userId)
 
     var takeBugreport
         get() = prefs.getBoolean(KEY_TAKE_BUG_REPORT, false)
@@ -57,8 +54,8 @@
         get() = prefs.getInt(KEY_ISSUE_TYPE_RES, ISSUE_TYPE_NOT_SET)
         set(value) = prefs.edit().putInt(KEY_ISSUE_TYPE_RES, value).apply()
 
-    val traceType: PresetTraceType
-        get() = ALL_ISSUE_TYPES[issueTypeRes] ?: PresetTraceType.UNSET
+    val traceConfig: TraceConfig
+        get() = ALL_ISSUE_TYPES[issueTypeRes] ?: PresetTraceConfigs.getDefaultConfig()
 
     private val listeners = CopyOnWriteArrayList<Runnable>()
 
@@ -87,12 +84,12 @@
         const val KEY_ISSUE_TYPE_RES = "key_issueTypeRes"
         const val ISSUE_TYPE_NOT_SET = -1
 
-        val ALL_ISSUE_TYPES: Map<Int, PresetTraceType> =
+        val ALL_ISSUE_TYPES: Map<Int, TraceConfig?> =
             hashMapOf(
-                Pair(R.string.performance, PresetTraceType.PERFORMANCE),
-                Pair(R.string.user_interface, PresetTraceType.UI),
-                Pair(R.string.battery, PresetTraceType.BATTERY),
-                Pair(R.string.thermal, PresetTraceType.THERMAL)
+                Pair(R.string.performance, PresetTraceConfigs.getPerformanceConfig()),
+                Pair(R.string.user_interface, PresetTraceConfigs.getUiConfig()),
+                Pair(R.string.battery, PresetTraceConfigs.getBatteryConfig()),
+                Pair(R.string.thermal, PresetTraceConfigs.getThermalConfig()),
             )
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
index bbf4e51..8a51ad4 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
@@ -87,7 +87,10 @@
             setNegativeButton(R.string.cancel) { _, _ -> }
             setPositiveButton(R.string.qs_record_issue_start) { _, _ -> onStarted.run() }
         }
-        bgExecutor.execute { traceurMessageSender.bindToTraceur(dialog.context) }
+        bgExecutor.execute {
+            traceurMessageSender.onBoundToTraceur.add { traceurMessageSender.getTags() }
+            traceurMessageSender.bindToTraceur(dialog.context)
+        }
     }
 
     override fun createDialog(): SystemUIDialog = factory.create(this)
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt
index 26af9a7..907b92c 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt
@@ -16,12 +16,20 @@
 
 package com.android.systemui.recordissue
 
+import com.android.systemui.Flags
 import com.android.systemui.qs.QsEventLogger
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.qs.tiles.RecordIssueTile
+import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
+import com.android.systemui.qs.tiles.impl.irecording.IssueRecordingDataInteractor
+import com.android.systemui.qs.tiles.impl.irecording.IssueRecordingMapper
+import com.android.systemui.qs.tiles.impl.irecording.IssueRecordingModel
+import com.android.systemui.qs.tiles.impl.irecording.IssueRecordingUserActionInteractor
 import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
 import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.viewmodel.StubQSTileViewModel
 import com.android.systemui.res.R
 import dagger.Binds
 import dagger.Module
@@ -34,19 +42,19 @@
     /** Inject RecordIssueTile into tileMap in QSModule */
     @Binds
     @IntoMap
-    @StringKey(RecordIssueTile.TILE_SPEC)
+    @StringKey(TILE_SPEC)
     fun bindRecordIssueTile(recordIssueTile: RecordIssueTile): QSTileImpl<*>
 
     companion object {
 
-        const val RECORD_ISSUE_TILE_SPEC = "record_issue"
+        const val TILE_SPEC = "record_issue"
 
         @Provides
         @IntoMap
-        @StringKey(RECORD_ISSUE_TILE_SPEC)
+        @StringKey(TILE_SPEC)
         fun provideRecordIssueTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
             QSTileConfig(
-                tileSpec = TileSpec.create(RECORD_ISSUE_TILE_SPEC),
+                tileSpec = TileSpec.create(TILE_SPEC),
                 uiConfig =
                     QSTileUIConfig.Resource(
                         iconRes = R.drawable.qs_record_issue_icon_off,
@@ -54,5 +62,24 @@
                     ),
                 instanceId = uiEventLogger.getNewInstanceId(),
             )
+
+        /** Inject FlashlightTile into tileViewModelMap in QSModule */
+        @Provides
+        @IntoMap
+        @StringKey(TILE_SPEC)
+        fun provideIssueRecordingTileViewModel(
+            factory: QSTileViewModelFactory.Static<IssueRecordingModel>,
+            mapper: IssueRecordingMapper,
+            stateInteractor: IssueRecordingDataInteractor,
+            userActionInteractor: IssueRecordingUserActionInteractor
+        ): QSTileViewModel =
+            if (Flags.qsNewTilesFuture())
+                factory.create(
+                    TileSpec.create(TILE_SPEC),
+                    userActionInteractor,
+                    stateInteractor,
+                    mapper,
+                )
+            else StubQSTileViewModel
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/TraceurMessageSender.kt b/packages/SystemUI/src/com/android/systemui/recordissue/TraceurMessageSender.kt
index 51744aa..a31a9ef 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/TraceurMessageSender.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/TraceurMessageSender.kt
@@ -35,7 +35,7 @@
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.traceur.FileSender
 import com.android.traceur.MessageConstants
-import com.android.traceur.TraceUtils.PresetTraceType
+import com.android.traceur.TraceConfig
 import javax.inject.Inject
 
 private const val TAG = "TraceurMessageSender"
@@ -45,11 +45,15 @@
     private var binder: Messenger? = null
     private var isBound: Boolean = false
 
+    val onBoundToTraceur = mutableListOf<Runnable>()
+
     private val traceurConnection =
         object : ServiceConnection {
             override fun onServiceConnected(className: ComponentName, service: IBinder) {
                 binder = Messenger(service)
                 isBound = true
+                onBoundToTraceur.forEach(Runnable::run)
+                onBoundToTraceur.clear()
             }
 
             override fun onServiceDisconnected(className: ComponentName) {
@@ -93,9 +97,9 @@
     }
 
     @WorkerThread
-    fun startTracing(traceType: PresetTraceType) {
+    fun startTracing(traceType: TraceConfig) {
         val data =
-            Bundle().apply { putSerializable(MessageConstants.INTENT_EXTRA_TRACE_TYPE, traceType) }
+            Bundle().apply { putParcelable(MessageConstants.INTENT_EXTRA_TRACE_TYPE, traceType) }
         notifyTraceur(MessageConstants.START_WHAT, data)
     }
 
@@ -103,11 +107,17 @@
 
     @WorkerThread
     fun shareTraces(context: Context, screenRecord: Uri?) {
-        val replyHandler = Messenger(TraceurMessageHandler(context, screenRecord, backgroundLooper))
+        val replyHandler = Messenger(ShareFilesHandler(context, screenRecord, backgroundLooper))
         notifyTraceur(MessageConstants.SHARE_WHAT, replyTo = replyHandler)
     }
 
     @WorkerThread
+    fun getTags() {
+        val replyHandler = Messenger(TagsHandler(backgroundLooper))
+        notifyTraceur(MessageConstants.TAGS_WHAT, replyTo = replyHandler)
+    }
+
+    @WorkerThread
     private fun notifyTraceur(what: Int, data: Bundle = Bundle(), replyTo: Messenger? = null) {
         try {
             binder!!.send(
@@ -122,7 +132,7 @@
         }
     }
 
-    private class TraceurMessageHandler(
+    private class ShareFilesHandler(
         private val context: Context,
         private val screenRecord: Uri?,
         looper: Looper,
@@ -154,4 +164,29 @@
             context.startActivity(fileSharingIntent)
         }
     }
+
+    private class TagsHandler(looper: Looper) : Handler(looper) {
+
+        override fun handleMessage(msg: Message) {
+            if (MessageConstants.TAGS_WHAT == msg.what) {
+                val keys = msg.data.getStringArrayList(MessageConstants.BUNDLE_KEY_TAGS)
+                val values =
+                    msg.data.getStringArrayList(MessageConstants.BUNDLE_KEY_TAG_DESCRIPTIONS)
+                if (keys == null || values == null) {
+                    throw IllegalArgumentException(
+                        "Neither keys: $keys, nor values: $values can " + "be null"
+                    )
+                }
+
+                val tags = keys.zip(values).map { "${it.first}: ${it.second}" }.toSet()
+                Log.e(
+                    TAG,
+                    "These tags: $tags will be saved and used for the Custom Trace" +
+                        " Config dialog in a future CL. This log will be removed."
+                )
+            } else {
+                throw IllegalArgumentException("received unknown msg.what: " + msg.what)
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt
index 323ca87..6e89973 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/KeyguardlessSceneContainerFrameworkModule.kt
@@ -23,8 +23,10 @@
 import com.android.systemui.scene.domain.resolver.HomeSceneFamilyResolverModule
 import com.android.systemui.scene.domain.resolver.NotifShadeSceneFamilyResolverModule
 import com.android.systemui.scene.domain.resolver.QuickSettingsSceneFamilyResolverModule
+import com.android.systemui.scene.domain.startable.KeyguardStateCallbackStartable
 import com.android.systemui.scene.domain.startable.SceneContainerStartable
 import com.android.systemui.scene.domain.startable.ScrimStartable
+import com.android.systemui.scene.domain.startable.StatusBarStartable
 import com.android.systemui.scene.shared.model.SceneContainerConfig
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shade.shared.flag.DualShade
@@ -66,6 +68,16 @@
 
     @Binds
     @IntoMap
+    @ClassKey(StatusBarStartable::class)
+    fun statusBarStartable(impl: StatusBarStartable): CoreStartable
+
+    @Binds
+    @IntoMap
+    @ClassKey(KeyguardStateCallbackStartable::class)
+    fun keyguardStateCallbackStartable(impl: KeyguardStateCallbackStartable): CoreStartable
+
+    @Binds
+    @IntoMap
     @ClassKey(WindowRootViewVisibilityInteractor::class)
     fun bindWindowRootViewVisibilityInteractor(
         impl: WindowRootViewVisibilityInteractor
diff --git a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
index 4691eba..7d63b4c 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/SceneContainerFrameworkModule.kt
@@ -24,8 +24,10 @@
 import com.android.systemui.scene.domain.resolver.HomeSceneFamilyResolverModule
 import com.android.systemui.scene.domain.resolver.NotifShadeSceneFamilyResolverModule
 import com.android.systemui.scene.domain.resolver.QuickSettingsSceneFamilyResolverModule
+import com.android.systemui.scene.domain.startable.KeyguardStateCallbackStartable
 import com.android.systemui.scene.domain.startable.SceneContainerStartable
 import com.android.systemui.scene.domain.startable.ScrimStartable
+import com.android.systemui.scene.domain.startable.StatusBarStartable
 import com.android.systemui.scene.shared.model.SceneContainerConfig
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shade.shared.flag.DualShade
@@ -72,6 +74,16 @@
 
     @Binds
     @IntoMap
+    @ClassKey(StatusBarStartable::class)
+    fun statusBarStartable(impl: StatusBarStartable): CoreStartable
+
+    @Binds
+    @IntoMap
+    @ClassKey(KeyguardStateCallbackStartable::class)
+    fun keyguardStateCallbackStartable(impl: KeyguardStateCallbackStartable): CoreStartable
+
+    @Binds
+    @IntoMap
     @ClassKey(WindowRootViewVisibilityInteractor::class)
     fun bindWindowRootViewVisibilityInteractor(
         impl: WindowRootViewVisibilityInteractor
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt
index 6bcd923..2d510e1 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt
@@ -43,8 +43,14 @@
     sceneInteractor: SceneInteractor,
     keyguardTransitionInteractor: KeyguardTransitionInteractor,
 ) {
-    /** Whether a show-when-locked activity is at the top of the current activity stack. */
-    private val isOccludingActivityShown: StateFlow<Boolean> =
+    /**
+     * Whether a show-when-locked activity is at the top of the current activity stack.
+     *
+     * Note: this isn't enough to figure out whether the scene container UI should be invisible as
+     * that also depends on the things like the state of AOD and the current scene. If the code
+     * needs that, [invisibleDueToOcclusion] should be collected instead.
+     */
+    val isOccludingActivityShown: StateFlow<Boolean> =
         keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop.stateIn(
             scope = applicationScope,
             started = SharingStarted.WhileSubscribed(),
@@ -69,6 +75,9 @@
     /**
      * Whether the scene container should become invisible due to "occlusion" by an in-foreground
      * "show when locked" activity.
+     *
+     * Note: this returns `false` when an overlaid scene (like shade or QS) is shown above the
+     * occluding activity.
      */
     val invisibleDueToOcclusion: StateFlow<Boolean> =
         combine(
@@ -121,7 +130,7 @@
     private val SceneKey.canBeOccluded: Boolean
         get() =
             when (this) {
-                Scenes.Bouncer -> true
+                Scenes.Bouncer -> false
                 Scenes.Communal -> true
                 Scenes.Gone -> true
                 Scenes.Lockscreen -> true
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
index 08175c3..5885193 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
@@ -22,11 +22,13 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardEnabledInteractor
 import com.android.systemui.scene.data.repository.SceneContainerRepository
 import com.android.systemui.scene.domain.resolver.SceneResolver
 import com.android.systemui.scene.shared.logger.SceneLogger
 import com.android.systemui.scene.shared.model.SceneFamilies
 import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.util.kotlin.getValue
 import com.android.systemui.util.kotlin.pairwiseBy
 import dagger.Lazy
 import javax.inject.Inject
@@ -41,6 +43,7 @@
 import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.stateIn
 
 /**
@@ -58,7 +61,8 @@
     private val repository: SceneContainerRepository,
     private val logger: SceneLogger,
     private val sceneFamilyResolvers: Lazy<Map<SceneKey, @JvmSuppressWildcards SceneResolver>>,
-    private val deviceUnlockedInteractor: DeviceUnlockedInteractor,
+    private val deviceUnlockedInteractor: Lazy<DeviceUnlockedInteractor>,
+    private val keyguardEnabledInteractor: Lazy<KeyguardEnabledInteractor>,
 ) {
 
     interface OnSceneAboutToChangeListener {
@@ -102,7 +106,14 @@
      * 2. When transitioning, which scenes are being transitioned between.
      * 3. When transitioning, what the progress of the transition is.
      */
-    val transitionState: StateFlow<ObservableTransitionState> = repository.transitionState
+    val transitionState: StateFlow<ObservableTransitionState> =
+        repository.transitionState
+            .onEach { logger.logSceneTransition(it) }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.Eagerly,
+                initialValue = repository.transitionState.value,
+            )
 
     /**
      * The key of the scene that the UI is currently transitioning to or `null` if there is no
@@ -157,6 +168,10 @@
                 initialValue = isVisibleInternal()
             )
 
+    /** Whether there's an ongoing remotely-initiated user interaction. */
+    val isRemoteUserInteractionOngoing: StateFlow<Boolean> =
+        repository.isRemoteUserInteractionOngoing
+
     /**
      * The amount of transition into or out of the given [scene].
      *
@@ -373,7 +388,8 @@
         val isChangeAllowed =
             to != Scenes.Gone ||
                 inMidTransitionFromGone ||
-                deviceUnlockedInteractor.deviceUnlockStatus.value.isUnlocked
+                deviceUnlockedInteractor.get().deviceUnlockStatus.value.isUnlocked ||
+                !keyguardEnabledInteractor.get().isKeyguardEnabled.value
         check(isChangeAllowed) {
             "Cannot change to the Gone scene while the device is locked and not currently" +
                 " transitioning from Gone. Current transition state is ${transitionState.value}." +
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/resolver/HomeSceneFamilyResolver.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/resolver/HomeSceneFamilyResolver.kt
index 9e91b66..41a3c8a 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/resolver/HomeSceneFamilyResolver.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/resolver/HomeSceneFamilyResolver.kt
@@ -22,6 +22,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardEnabledInteractor
 import com.android.systemui.scene.shared.model.SceneFamilies
 import com.android.systemui.scene.shared.model.Scenes
 import dagger.Binds
@@ -45,11 +46,13 @@
 constructor(
     @Application private val applicationScope: CoroutineScope,
     deviceEntryInteractor: DeviceEntryInteractor,
+    keyguardEnabledInteractor: KeyguardEnabledInteractor,
 ) : SceneResolver {
     override val targetFamily: SceneKey = SceneFamilies.Home
 
     override val resolvedScene: StateFlow<SceneKey> =
         combine(
+                keyguardEnabledInteractor.isKeyguardEnabled,
                 deviceEntryInteractor.canSwipeToEnter,
                 deviceEntryInteractor.isDeviceEntered,
                 deviceEntryInteractor.isUnlocked,
@@ -60,20 +63,23 @@
                 started = SharingStarted.Eagerly,
                 initialValue =
                     homeScene(
-                        deviceEntryInteractor.canSwipeToEnter.value,
-                        deviceEntryInteractor.isDeviceEntered.value,
-                        deviceEntryInteractor.isUnlocked.value,
+                        isKeyguardEnabled = keyguardEnabledInteractor.isKeyguardEnabled.value,
+                        canSwipeToEnter = deviceEntryInteractor.canSwipeToEnter.value,
+                        isDeviceEntered = deviceEntryInteractor.isDeviceEntered.value,
+                        isUnlocked = deviceEntryInteractor.isUnlocked.value,
                     )
             )
 
     override fun includesScene(scene: SceneKey): Boolean = scene in homeScenes
 
     private fun homeScene(
+        isKeyguardEnabled: Boolean,
         canSwipeToEnter: Boolean?,
         isDeviceEntered: Boolean,
         isUnlocked: Boolean,
     ): SceneKey =
         when {
+            !isKeyguardEnabled -> Scenes.Gone
             canSwipeToEnter == true -> Scenes.Lockscreen
             !isDeviceEntered -> Scenes.Lockscreen
             !isUnlocked -> Scenes.Lockscreen
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/KeyguardStateCallbackStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/KeyguardStateCallbackStartable.kt
new file mode 100644
index 0000000..6d1c1a7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/KeyguardStateCallbackStartable.kt
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.scene.domain.startable
+
+import android.os.DeadObjectException
+import android.os.RemoteException
+import com.android.internal.policy.IKeyguardStateCallback
+import com.android.systemui.CoreStartable
+import com.android.systemui.bouncer.domain.interactor.SimBouncerInteractor
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
+import com.android.systemui.keyguard.domain.interactor.TrustInteractor
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.user.domain.interactor.SelectedUserInteractor
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+/** Keeps all [IKeyguardStateCallback]s hydrated with the latest state. */
+@SysUISingleton
+class KeyguardStateCallbackStartable
+@Inject
+constructor(
+    @Application private val applicationScope: CoroutineScope,
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
+    private val sceneInteractor: SceneInteractor,
+    private val selectedUserInteractor: SelectedUserInteractor,
+    private val deviceEntryInteractor: DeviceEntryInteractor,
+    private val simBouncerInteractor: SimBouncerInteractor,
+    private val trustInteractor: TrustInteractor,
+) : CoreStartable {
+
+    private val callbacks = mutableListOf<IKeyguardStateCallback>()
+
+    override fun start() {
+        if (!SceneContainerFlag.isEnabled) {
+            return
+        }
+
+        hydrateKeyguardShowingAndInputRestrictionStates()
+        hydrateSimSecureState()
+        notifyWhenKeyguardShowingChanged()
+        notifyWhenTrustChanged()
+    }
+
+    fun addCallback(callback: IKeyguardStateCallback) {
+        SceneContainerFlag.assertInNewMode()
+
+        callbacks.add(callback)
+
+        applicationScope.launch(backgroundDispatcher) {
+            callback.onShowingStateChanged(
+                !deviceEntryInteractor.isDeviceEntered.value,
+                selectedUserInteractor.getSelectedUserId(),
+            )
+            callback.onTrustedChanged(trustInteractor.isTrusted.value)
+            callback.onSimSecureStateChanged(simBouncerInteractor.isAnySimSecure.value)
+            // TODO(b/348644111): add support for mNeedToReshowWhenReenabled
+            callback.onInputRestrictedStateChanged(!deviceEntryInteractor.isDeviceEntered.value)
+        }
+    }
+
+    private fun hydrateKeyguardShowingAndInputRestrictionStates() {
+        applicationScope.launch {
+            combine(
+                    selectedUserInteractor.selectedUser,
+                    deviceEntryInteractor.isDeviceEntered,
+                    ::Pair
+                )
+                .collectLatest { (selectedUserId, isDeviceEntered) ->
+                    val iterator = callbacks.iterator()
+                    withContext(backgroundDispatcher) {
+                        while (iterator.hasNext()) {
+                            val callback = iterator.next()
+                            try {
+                                callback.onShowingStateChanged(!isDeviceEntered, selectedUserId)
+                                // TODO(b/348644111): add support for mNeedToReshowWhenReenabled
+                                callback.onInputRestrictedStateChanged(!isDeviceEntered)
+                            } catch (e: RemoteException) {
+                                if (e is DeadObjectException) {
+                                    iterator.remove()
+                                }
+                            }
+                        }
+                    }
+                }
+        }
+    }
+
+    private fun hydrateSimSecureState() {
+        applicationScope.launch {
+            simBouncerInteractor.isAnySimSecure.collectLatest { isSimSecured ->
+                val iterator = callbacks.iterator()
+                withContext(backgroundDispatcher) {
+                    while (iterator.hasNext()) {
+                        val callback = iterator.next()
+                        try {
+                            callback.onSimSecureStateChanged(isSimSecured)
+                        } catch (e: RemoteException) {
+                            if (e is DeadObjectException) {
+                                iterator.remove()
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private fun notifyWhenKeyguardShowingChanged() {
+        applicationScope.launch {
+            // This is equivalent to isDeviceEntered but it waits for the full transition animation
+            // to finish before emitting a new value and not just for the current scene to be
+            // switched.
+            sceneInteractor.transitionState
+                .filter { it.isIdle(Scenes.Gone) || it.isIdle(Scenes.Lockscreen) }
+                .map { it.isIdle(Scenes.Lockscreen) }
+                .distinctUntilChanged()
+                .collectLatest { trustInteractor.reportKeyguardShowingChanged() }
+        }
+    }
+
+    private fun notifyWhenTrustChanged() {
+        applicationScope.launch {
+            trustInteractor.isTrusted.collectLatest { isTrusted ->
+                val iterator = callbacks.iterator()
+                withContext(backgroundDispatcher) {
+                    while (iterator.hasNext()) {
+                        val callback = iterator.next()
+                        try {
+                            callback.onTrustedChanged(isTrusted)
+                        } catch (e: RemoteException) {
+                            if (e is DeadObjectException) {
+                                iterator.remove()
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
index 1e689bd..1f4820a 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
@@ -38,7 +38,10 @@
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
 import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
 import com.android.systemui.deviceentry.shared.model.DeviceUnlockSource
+import com.android.systemui.keyguard.DismissCallbackRegistry
+import com.android.systemui.keyguard.domain.interactor.KeyguardEnabledInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor
 import com.android.systemui.model.SceneContainerPlugin
 import com.android.systemui.model.SysUiState
@@ -82,6 +85,7 @@
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.filterIsInstance
 import kotlinx.coroutines.flow.filterNot
+import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOf
@@ -104,6 +108,7 @@
     private val deviceUnlockedInteractor: DeviceUnlockedInteractor,
     private val bouncerInteractor: BouncerInteractor,
     private val keyguardInteractor: KeyguardInteractor,
+    private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
     private val sysUiState: SysUiState,
     @DisplayId private val displayId: Int,
     private val sceneLogger: SceneLogger,
@@ -123,6 +128,8 @@
     private val sceneBackInteractor: SceneBackInteractor,
     private val shadeSessionStorage: SessionStorage,
     private val windowMgrLockscreenVisInteractor: WindowManagerLockscreenVisibilityInteractor,
+    private val keyguardEnabledInteractor: KeyguardEnabledInteractor,
+    private val dismissCallbackRegistry: DismissCallbackRegistry,
 ) : CoreStartable {
     private val centralSurfaces: CentralSurfaces?
         get() = centralSurfacesOptLazy.get().getOrNull()
@@ -140,6 +147,8 @@
             hydrateWindowController()
             hydrateBackStack()
             resetShadeSessions()
+            handleKeyguardEnabledness()
+            notifyKeyguardDismissCallbacks()
         } else {
             sceneLogger.logFrameworkEnabled(
                 isEnabled = false,
@@ -413,9 +422,9 @@
             powerInteractor.isAsleep.collect { isAsleep ->
                 if (isAsleep) {
                     switchToScene(
-                        // TODO(b/336581871): add sceneState?
                         targetSceneKey = Scenes.Lockscreen,
                         loggingReason = "device is starting to sleep",
+                        sceneState = keyguardTransitionInteractor.asleepKeyguardState.value,
                     )
                 } else {
                     val canSwipeToEnter = deviceEntryInteractor.canSwipeToEnter.value
@@ -650,10 +659,60 @@
         }
     }
 
-    private fun switchToScene(targetSceneKey: SceneKey, loggingReason: String) {
+    private fun handleKeyguardEnabledness() {
+        // Automatically switches scenes when keyguard is enabled or disabled, as needed.
+        applicationScope.launch {
+            keyguardEnabledInteractor.isKeyguardEnabled
+                .sample(
+                    combine(
+                        deviceEntryInteractor.isInLockdown,
+                        deviceEntryInteractor.isDeviceEntered,
+                        ::Pair,
+                    )
+                ) { isKeyguardEnabled, (isInLockdown, isDeviceEntered) ->
+                    when {
+                        !isKeyguardEnabled && !isInLockdown && !isDeviceEntered -> {
+                            keyguardEnabledInteractor.setShowKeyguardWhenReenabled(true)
+                            Scenes.Gone to "Keyguard became disabled"
+                        }
+                        isKeyguardEnabled &&
+                            keyguardEnabledInteractor.isShowKeyguardWhenReenabled() -> {
+                            keyguardEnabledInteractor.setShowKeyguardWhenReenabled(false)
+                            Scenes.Lockscreen to "Keyguard became enabled"
+                        }
+                        else -> null
+                    }
+                }
+                .filterNotNull()
+                .collect { (targetScene, loggingReason) ->
+                    switchToScene(targetScene, loggingReason)
+                }
+        }
+
+        // Clears the showKeyguardWhenReenabled if the auth method changes to an insecure one.
+        applicationScope.launch {
+            authenticationInteractor
+                .get()
+                .authenticationMethod
+                .map { it.isSecure }
+                .distinctUntilChanged()
+                .collect { isAuthenticationMethodSecure ->
+                    if (!isAuthenticationMethodSecure) {
+                        keyguardEnabledInteractor.setShowKeyguardWhenReenabled(false)
+                    }
+                }
+        }
+    }
+
+    private fun switchToScene(
+        targetSceneKey: SceneKey,
+        loggingReason: String,
+        sceneState: Any? = null
+    ) {
         sceneInteractor.changeScene(
             toScene = targetSceneKey,
             loggingReason = loggingReason,
+            sceneState = sceneState,
         )
     }
 
@@ -664,4 +723,16 @@
             }
         }
     }
+
+    private fun notifyKeyguardDismissCallbacks() {
+        applicationScope.launch {
+            sceneInteractor.currentScene.pairwise().collect { (from, to) ->
+                when {
+                    from != Scenes.Bouncer -> Unit
+                    to == Scenes.Gone -> dismissCallbackRegistry.notifyDismissSucceeded()
+                    else -> dismissCallbackRegistry.notifyDismissCancelled()
+                }
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/StatusBarStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/StatusBarStartable.kt
new file mode 100644
index 0000000..893f030
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/StatusBarStartable.kt
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.scene.domain.startable
+
+import android.annotation.SuppressLint
+import android.app.StatusBarManager
+import android.content.Context
+import android.os.Binder
+import android.os.IBinder
+import android.os.RemoteException
+import android.provider.DeviceConfig
+import android.util.Log
+import com.android.compose.animation.scene.SceneKey
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
+import com.android.internal.statusbar.IStatusBarService
+import com.android.systemui.CoreStartable
+import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
+import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.deviceconfig.domain.interactor.DeviceConfigInteractor
+import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor
+import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
+import com.android.systemui.navigation.domain.interactor.NavigationInteractor
+import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.power.shared.model.WakeSleepReason
+import com.android.systemui.power.shared.model.WakefulnessModel
+import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
+import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.user.domain.interactor.SelectedUserInteractor
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+@SysUISingleton
+class StatusBarStartable
+@Inject
+constructor(
+    @Application private val applicationScope: CoroutineScope,
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
+    @Application private val applicationContext: Context,
+    private val selectedUserInteractor: SelectedUserInteractor,
+    private val sceneInteractor: SceneInteractor,
+    private val deviceEntryInteractor: DeviceEntryInteractor,
+    private val sceneContainerOcclusionInteractor: SceneContainerOcclusionInteractor,
+    private val deviceConfigInteractor: DeviceConfigInteractor,
+    private val navigationInteractor: NavigationInteractor,
+    private val authenticationInteractor: AuthenticationInteractor,
+    private val powerInteractor: PowerInteractor,
+    private val deviceEntryFaceAuthInteractor: DeviceEntryFaceAuthInteractor,
+    private val statusBarService: IStatusBarService,
+) : CoreStartable {
+
+    private val disableToken: IBinder = Binder()
+
+    override fun start() {
+        if (!SceneContainerFlag.isEnabled) {
+            return
+        }
+
+        applicationScope.launch {
+            combine(
+                    selectedUserInteractor.selectedUser,
+                    sceneInteractor.currentScene,
+                    deviceEntryInteractor.isDeviceEntered,
+                    sceneContainerOcclusionInteractor.invisibleDueToOcclusion,
+                    deviceConfigInteractor.property(
+                        namespace = DeviceConfig.NAMESPACE_SYSTEMUI,
+                        name = SystemUiDeviceConfigFlags.NAV_BAR_HANDLE_SHOW_OVER_LOCKSCREEN,
+                        default = true,
+                    ),
+                    navigationInteractor.isGesturalMode,
+                    authenticationInteractor.authenticationMethod,
+                    powerInteractor.detailedWakefulness,
+                ) { values ->
+                    val selectedUserId = values[0] as Int
+                    val currentScene = values[1] as SceneKey
+                    val isDeviceEntered = values[2] as Boolean
+                    val isOccluded = values[3] as Boolean
+                    val isShowHomeOverLockscreen = values[4] as Boolean
+                    val isGesturalMode = values[5] as Boolean
+                    val authenticationMethod = values[6] as AuthenticationMethodModel
+                    val wakefulnessModel = values[7] as WakefulnessModel
+
+                    val isForceHideHomeAndRecents = currentScene == Scenes.Bouncer
+                    val isKeyguardShowing = !isDeviceEntered
+                    val isPowerGestureIntercepted =
+                        with(wakefulnessModel) {
+                            isAwake() &&
+                                powerButtonLaunchGestureTriggered &&
+                                lastSleepReason == WakeSleepReason.POWER_BUTTON
+                        }
+
+                    var flags = StatusBarManager.DISABLE_NONE
+
+                    if (isForceHideHomeAndRecents || (isKeyguardShowing && !isOccluded)) {
+                        if (!isShowHomeOverLockscreen || !isGesturalMode) {
+                            flags = flags or StatusBarManager.DISABLE_HOME
+                        }
+                        flags = flags or StatusBarManager.DISABLE_RECENT
+                    }
+
+                    if (
+                        isPowerGestureIntercepted &&
+                            isOccluded &&
+                            authenticationMethod.isSecure &&
+                            deviceEntryFaceAuthInteractor.isFaceAuthEnabledAndEnrolled()
+                    ) {
+                        flags = flags or StatusBarManager.DISABLE_RECENT
+                    }
+
+                    selectedUserId to flags
+                }
+                .distinctUntilChanged()
+                .collect { (selectedUserId, flags) ->
+                    @SuppressLint("WrongConstant", "NonInjectedService")
+                    if (applicationContext.getSystemService(Context.STATUS_BAR_SERVICE) == null) {
+                        Log.w(TAG, "Could not get status bar manager")
+                        return@collect
+                    }
+
+                    withContext(backgroundDispatcher) {
+                        try {
+                            statusBarService.disableForUser(
+                                flags,
+                                disableToken,
+                                applicationContext.packageName,
+                                selectedUserId,
+                            )
+                        } catch (e: RemoteException) {
+                            Log.d(TAG, "Failed to set disable flags: $flags", e)
+                        }
+                    }
+                }
+        }
+    }
+
+    override fun onBootCompleted() {
+        applicationScope.launch(backgroundDispatcher) {
+            try {
+                statusBarService.disableForUser(
+                    StatusBarManager.DISABLE_NONE,
+                    disableToken,
+                    applicationContext.packageName,
+                    selectedUserInteractor.getSelectedUserId(true),
+                )
+            } catch (e: RemoteException) {
+                Log.d(TAG, "Failed to clear flags", e)
+            }
+        }
+    }
+
+    companion object {
+        private const val TAG = "StatusBarStartable"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt
index cf33c4a..6c63c97 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlag.kt
@@ -39,13 +39,14 @@
     inline val isEnabled
         get() =
             sceneContainer() && // mainAconfigFlag
-            ComposeLockscreen.isEnabled &&
+                ComposeLockscreen.isEnabled &&
                 KeyguardBottomAreaRefactor.isEnabled &&
                 KeyguardWmStateRefactor.isEnabled &&
                 MigrateClocksToBlueprint.isEnabled &&
                 NotificationsHeadsUpRefactor.isEnabled &&
                 PredictiveBackSysUiFlag.isEnabled &&
                 DeviceEntryUdfpsRefactor.isEnabled
+
     // NOTE: Changes should also be made in getSecondaryFlags and @EnableSceneContainer
 
     /** The main aconfig flag. */
@@ -91,6 +92,14 @@
     @JvmStatic
     inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, DESCRIPTION)
 
+    /**
+     * Called to ensure the new code is only run when the flag is enabled. This will throw an
+     * exception if the flag is disabled to ensure that the refactor author catches issues in
+     * testing.
+     */
+    @JvmStatic
+    inline fun assertInNewMode() = RefactorFlagUtils.assertInNewMode(isEnabled, DESCRIPTION)
+
     /** Returns a developer-readable string that describes the current requirement list. */
     @JvmStatic
     fun requirementDescription(): String {
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/logger/SceneLogger.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/logger/SceneLogger.kt
index 9d6720b..cf1518e 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/logger/SceneLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/logger/SceneLogger.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.scene.shared.logger
 
+import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.compose.animation.scene.SceneKey
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.core.LogLevel
@@ -84,6 +85,30 @@
         )
     }
 
+    fun logSceneTransition(transitionState: ObservableTransitionState) {
+        when (transitionState) {
+            is ObservableTransitionState.Transition -> {
+                logBuffer.log(
+                    tag = TAG,
+                    level = LogLevel.INFO,
+                    messageInitializer = {
+                        str1 = transitionState.fromScene.toString()
+                        str2 = transitionState.toScene.toString()
+                    },
+                    messagePrinter = { "Scene transition started: $str1 → $str2" },
+                )
+            }
+            is ObservableTransitionState.Idle -> {
+                logBuffer.log(
+                    tag = TAG,
+                    level = LogLevel.INFO,
+                    messageInitializer = { str1 = transitionState.currentScene.toString() },
+                    messagePrinter = { "Scene transition idle on: $str1" },
+                )
+            }
+        }
+    }
+
     fun logVisibilityChange(
         from: Boolean,
         to: Boolean,
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/TransitionKeys.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/TransitionKeys.kt
index ef393e4..be95441 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/TransitionKeys.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/TransitionKeys.kt
@@ -31,6 +31,11 @@
     val CollapseShadeInstantly = TransitionKey("CollapseShadeInstantly")
 
     /**
+     * Reference to a scene transition that brings up the shade from the bottom instead of the top.
+     */
+    val OpenBottomShade = TransitionKey("OpenBottomShade")
+
+    /**
      * Reference to a scene transition that can collapse the shade scene slightly faster than a
      * normal collapse would.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModel.kt
index c34a6cd..9f48ee9 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/GoneSceneViewModel.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.scene.ui.viewmodel
 
+import androidx.compose.ui.Alignment
 import com.android.compose.animation.scene.Edge
 import com.android.compose.animation.scene.Swipe
 import com.android.compose.animation.scene.SwipeDirection
@@ -24,6 +25,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.scene.shared.model.SceneFamilies
+import com.android.systemui.scene.shared.model.TransitionKeys.OpenBottomShade
 import com.android.systemui.scene.shared.model.TransitionKeys.ToSplitShade
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
@@ -39,7 +41,7 @@
 @Inject
 constructor(
     @Application private val applicationScope: CoroutineScope,
-    shadeInteractor: ShadeInteractor,
+    private val shadeInteractor: ShadeInteractor,
 ) {
     val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> =
         shadeInteractor.shadeMode
@@ -62,23 +64,38 @@
                     // TODO(b/338577208): Remove this once we add Dual Shade invocation zones.
                     shadeMode is ShadeMode.Dual
             ) {
-                put(
-                    Swipe(
-                        pointerCount = 2,
-                        fromSource = Edge.Top,
-                        direction = SwipeDirection.Down,
-                    ),
-                    UserActionResult(SceneFamilies.QuickSettings)
-                )
+                if (shadeInteractor.shadeAlignment == Alignment.BottomEnd) {
+                    put(
+                        Swipe(
+                            pointerCount = 2,
+                            fromSource = Edge.Bottom,
+                            direction = SwipeDirection.Up,
+                        ),
+                        UserActionResult(SceneFamilies.QuickSettings, OpenBottomShade)
+                    )
+                } else {
+                    put(
+                        Swipe(
+                            pointerCount = 2,
+                            fromSource = Edge.Top,
+                            direction = SwipeDirection.Down,
+                        ),
+                        UserActionResult(SceneFamilies.QuickSettings)
+                    )
+                }
             }
 
-            put(
-                Swipe(direction = SwipeDirection.Down),
-                UserActionResult(
-                    SceneFamilies.NotifShade,
-                    ToSplitShade.takeIf { shadeMode is ShadeMode.Split }
+            if (shadeInteractor.shadeAlignment == Alignment.BottomEnd) {
+                put(Swipe.Up, UserActionResult(SceneFamilies.NotifShade, OpenBottomShade))
+            } else {
+                put(
+                    Swipe.Down,
+                    UserActionResult(
+                        SceneFamilies.NotifShade,
+                        ToSplitShade.takeIf { shadeMode is ShadeMode.Split }
+                    )
                 )
-            )
+            }
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
index d380251..a28222e 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/ui/viewmodel/SceneContainerViewModel.kt
@@ -26,17 +26,12 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.power.domain.interactor.PowerInteractor
 import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.model.Scene
 import com.android.systemui.scene.shared.model.Scenes
-import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
 import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.stateIn
 
 /** Models UI state for the scene container. */
 @SysUISingleton
@@ -46,7 +41,6 @@
     private val sceneInteractor: SceneInteractor,
     private val falsingInteractor: FalsingInteractor,
     private val powerInteractor: PowerInteractor,
-    scenes: Set<@JvmSuppressWildcards Scene>,
 ) {
     /**
      * Keys of all scenes in the container.
@@ -62,25 +56,6 @@
     /** Whether the container is visible. */
     val isVisible: StateFlow<Boolean> = sceneInteractor.isVisible
 
-    private val destinationScenesBySceneKey =
-        scenes.associate { scene ->
-            scene.key to scene.destinationScenes.flatMapLatestConflated { replaceSceneFamilies(it) }
-        }
-
-    fun currentDestinationScenes(
-        scope: CoroutineScope,
-    ): StateFlow<Map<UserAction, UserActionResult>> {
-        return currentScene
-            .flatMapLatestConflated { currentSceneKey ->
-                checkNotNull(destinationScenesBySceneKey[currentSceneKey])
-            }
-            .stateIn(
-                scope = scope,
-                started = SharingStarted.WhileSubscribed(),
-                initialValue = emptyMap(),
-            )
-    }
-
     /**
      * Binds the given flow so the system remembers it.
      *
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/data/model/ScreenRecordModel.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/data/model/ScreenRecordModel.kt
index b225444..ada5d8c0 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/data/model/ScreenRecordModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/data/model/ScreenRecordModel.kt
@@ -22,7 +22,17 @@
     data object Recording : ScreenRecordModel
 
     /** A screen recording will begin in [millisUntilStarted] ms. */
-    data class Starting(val millisUntilStarted: Long) : ScreenRecordModel
+    data class Starting(val millisUntilStarted: Long) : ScreenRecordModel {
+        val countdownSeconds = millisUntilStarted.toCountdownSeconds()
+
+        companion object {
+            /**
+             * Returns the number of seconds until screen recording will start, used to show a 3-2-1
+             * countdown.
+             */
+            fun Long.toCountdownSeconds() = Math.floorDiv(this + 500, 1000)
+        }
+    }
 
     /** There's nothing related to screen recording happening. */
     data object DoingNothing : ScreenRecordModel
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/HeadlessScreenshotHandler.kt b/packages/SystemUI/src/com/android/systemui/screenshot/HeadlessScreenshotHandler.kt
new file mode 100644
index 0000000..6730d2d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/HeadlessScreenshotHandler.kt
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.screenshot
+
+import android.net.Uri
+import android.os.UserManager
+import android.util.Log
+import android.view.WindowManager
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.res.R
+import com.google.common.util.concurrent.ListenableFuture
+import java.util.UUID
+import java.util.concurrent.Executor
+import java.util.concurrent.Executors
+import java.util.function.Consumer
+import javax.inject.Inject
+
+/**
+ * A ScreenshotHandler that just saves the screenshot and calls back as appropriate, with no UI.
+ *
+ * Basically, ScreenshotController with all the UI bits ripped out.
+ */
+class HeadlessScreenshotHandler
+@Inject
+constructor(
+    private val imageExporter: ImageExporter,
+    @Main private val mainExecutor: Executor,
+    private val imageCapture: ImageCapture,
+    private val userManager: UserManager,
+    private val uiEventLogger: UiEventLogger,
+    private val notificationsControllerFactory: ScreenshotNotificationsController.Factory,
+) : ScreenshotHandler {
+
+    override fun handleScreenshot(
+        screenshot: ScreenshotData,
+        finisher: Consumer<Uri?>,
+        requestCallback: TakeScreenshotService.RequestCallback
+    ) {
+        if (screenshot.type == WindowManager.TAKE_SCREENSHOT_FULLSCREEN) {
+            screenshot.bitmap = imageCapture.captureDisplay(screenshot.displayId, crop = null)
+        }
+
+        if (screenshot.bitmap == null) {
+            Log.e(TAG, "handleScreenshot: Screenshot bitmap was null")
+            notificationsControllerFactory
+                .create(screenshot.displayId)
+                .notifyScreenshotError(R.string.screenshot_failed_to_capture_text)
+            requestCallback.reportError()
+            return
+        }
+
+        val future: ListenableFuture<ImageExporter.Result> =
+            imageExporter.export(
+                Executors.newSingleThreadExecutor(),
+                UUID.randomUUID(),
+                screenshot.bitmap,
+                screenshot.getUserOrDefault(),
+                screenshot.displayId
+            )
+        future.addListener(
+            {
+                try {
+                    val result = future.get()
+                    Log.d(TAG, "Saved screenshot: $result")
+                    logScreenshotResultStatus(result.uri, screenshot)
+                    finisher.accept(result.uri)
+                    requestCallback.onFinish()
+                } catch (e: Exception) {
+                    Log.d(TAG, "Failed to store screenshot", e)
+                    finisher.accept(null)
+                    requestCallback.reportError()
+                }
+            },
+            mainExecutor
+        )
+    }
+
+    private fun logScreenshotResultStatus(uri: Uri?, screenshot: ScreenshotData) {
+        if (uri == null) {
+            uiEventLogger.log(ScreenshotEvent.SCREENSHOT_NOT_SAVED, 0, screenshot.packageNameString)
+            notificationsControllerFactory
+                .create(screenshot.displayId)
+                .notifyScreenshotError(R.string.screenshot_failed_to_save_text)
+        } else {
+            uiEventLogger.log(ScreenshotEvent.SCREENSHOT_SAVED, 0, screenshot.packageNameString)
+            if (userManager.isManagedProfile(screenshot.getUserOrDefault().identifier)) {
+                uiEventLogger.log(
+                    ScreenshotEvent.SCREENSHOT_SAVED_TO_WORK_PROFILE,
+                    0,
+                    screenshot.packageNameString
+                )
+            }
+        }
+    }
+
+    companion object {
+        const val TAG = "HeadlessScreenshotHandler"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsController.kt
index 2ffb783..5f16886 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsController.kt
@@ -18,6 +18,7 @@
 
 import android.app.assist.AssistContent
 import com.android.systemui.screenshot.ui.viewmodel.ActionButtonAppearance
+import com.android.systemui.screenshot.ui.viewmodel.PreviewAction
 import com.android.systemui.screenshot.ui.viewmodel.ScreenshotViewModel
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
@@ -84,9 +85,9 @@
     }
 
     inner class ActionsCallback(private val screenshotId: UUID) {
-        fun providePreviewAction(onClick: () -> Unit) {
+        fun providePreviewAction(previewAction: PreviewAction) {
             if (screenshotId == currentScreenshotId) {
-                viewModel.setPreviewAction(onClick)
+                viewModel.setPreviewAction(previewAction)
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt
index b8029c8..c216f1d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt
@@ -29,6 +29,7 @@
 import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_PREVIEW_TAPPED
 import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_SHARE_TAPPED
 import com.android.systemui.screenshot.ui.viewmodel.ActionButtonAppearance
+import com.android.systemui.screenshot.ui.viewmodel.PreviewAction
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
@@ -40,7 +41,9 @@
  */
 interface ScreenshotActionsProvider {
     fun onScrollChipReady(onClick: Runnable)
+
     fun onScrollChipInvalidated()
+
     fun setCompletedScreenshot(result: ScreenshotSavedResult)
 
     /**
@@ -75,17 +78,19 @@
     private var result: ScreenshotSavedResult? = null
 
     init {
-        actionsCallback.providePreviewAction {
-            debugLog(LogConfig.DEBUG_ACTIONS) { "Preview tapped" }
-            uiEventLogger.log(SCREENSHOT_PREVIEW_TAPPED, 0, request.packageNameString)
-            onDeferrableActionTapped { result ->
-                actionExecutor.startSharedTransition(
-                    createEdit(result.uri, context),
-                    result.user,
-                    true
-                )
+        actionsCallback.providePreviewAction(
+            PreviewAction(context.resources.getString(R.string.screenshot_edit_description)) {
+                debugLog(LogConfig.DEBUG_ACTIONS) { "Preview tapped" }
+                uiEventLogger.log(SCREENSHOT_PREVIEW_TAPPED, 0, request.packageNameString)
+                onDeferrableActionTapped { result ->
+                    actionExecutor.startSharedTransition(
+                        createEdit(result.uri, context),
+                        result.user,
+                        true
+                    )
+                }
             }
-        }
+        )
 
         actionsCallback.provideActionButton(
             ActionButtonAppearance(
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index e8dfac8..95ee2e0 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -20,7 +20,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
 
 import static com.android.systemui.Flags.screenshotPrivateProfileAccessibilityAnnouncementFix;
-import static com.android.systemui.Flags.screenshotShelfUi2;
 import static com.android.systemui.screenshot.LogConfig.DEBUG_ANIM;
 import static com.android.systemui.screenshot.LogConfig.DEBUG_CALLBACK;
 import static com.android.systemui.screenshot.LogConfig.DEBUG_INPUT;
@@ -101,7 +100,7 @@
 /**
  * Controls the state and flow for screenshots.
  */
-public class ScreenshotController {
+public class ScreenshotController implements ScreenshotHandler {
     private static final String TAG = logTag(ScreenshotController.class);
 
     /**
@@ -351,7 +350,8 @@
         mShowUIOnExternalDisplay = showUIOnExternalDisplay;
     }
 
-    void handleScreenshot(ScreenshotData screenshot, Consumer<Uri> finisher,
+    @Override
+    public void handleScreenshot(ScreenshotData screenshot, Consumer<Uri> finisher,
             RequestCallback requestCallback) {
         Assert.isMainThread();
 
@@ -406,22 +406,16 @@
         }
 
         final UUID requestId;
-        if (screenshotShelfUi2()) {
-            requestId = mActionsController.setCurrentScreenshot(screenshot);
-            saveScreenshotInBackground(screenshot, requestId, finisher);
+        requestId = mActionsController.setCurrentScreenshot(screenshot);
+        saveScreenshotInBackground(screenshot, requestId, finisher);
 
-            if (screenshot.getTaskId() >= 0) {
-                mAssistContentRequester.requestAssistContent(
-                        screenshot.getTaskId(),
-                        assistContent ->
-                                mActionsController.onAssistContent(requestId, assistContent));
-            } else {
-                mActionsController.onAssistContent(requestId, null);
-            }
+        if (screenshot.getTaskId() >= 0) {
+            mAssistContentRequester.requestAssistContent(
+                    screenshot.getTaskId(),
+                    assistContent ->
+                            mActionsController.onAssistContent(requestId, assistContent));
         } else {
-            requestId = UUID.randomUUID(); // passed through but unused for legacy UI
-            saveScreenshotInWorkerThread(screenshot.getUserHandle(), finisher,
-                    this::showUiOnActionsReady, this::showUiOnQuickShareActionReady);
+            mActionsController.onAssistContent(requestId, null);
         }
 
         // The window is focusable by default
@@ -457,9 +451,6 @@
         // ignore system bar insets for the purpose of window layout
         mWindow.getDecorView().setOnApplyWindowInsetsListener(
                 (v, insets) -> WindowInsets.CONSUMED);
-        if (!screenshotShelfUi2()) {
-            mScreenshotHandler.cancelTimeout(); // restarted after animation
-        }
     }
 
     private boolean shouldShowUi() {
@@ -514,11 +505,7 @@
     }
 
     boolean isPendingSharedTransition() {
-        if (screenshotShelfUi2()) {
-            return mActionExecutor.isPendingSharedTransition();
-        } else {
-            return mViewProxy.isPendingSharedTransition();
-        }
+        return mActionExecutor.isPendingSharedTransition();
     }
 
     // Any cleanup needed when the service is being destroyed.
@@ -602,11 +589,7 @@
                             if (mConfigChanges.applyNewConfig(mContext.getResources())) {
                                 // Hide the scroll chip until we know it's available in this
                                 // orientation
-                                if (screenshotShelfUi2()) {
-                                    mActionsController.onScrollChipInvalidated();
-                                } else {
-                                    mViewProxy.hideScrollChip();
-                                }
+                                mActionsController.onScrollChipInvalidated();
                                 // Delay scroll capture eval a bit to allow the underlying activity
                                 // to set up in the new orientation.
                                 mScreenshotHandler.postDelayed(
@@ -639,13 +622,8 @@
                 (response) -> {
                     mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_LONG_SCREENSHOT_IMPRESSION,
                             0, response.getPackageName());
-                    if (screenshotShelfUi2()) {
-                        mActionsController.onScrollChipReady(requestId,
-                                () -> onScrollButtonClicked(owner, response));
-                    } else {
-                        mViewProxy.showScrollChip(response.getPackageName(),
-                                () -> onScrollButtonClicked(owner, response));
-                    }
+                    mActionsController.onScrollChipReady(requestId,
+                            () -> onScrollButtonClicked(owner, response));
                     return Unit.INSTANCE;
                 }
         );
@@ -714,11 +692,9 @@
         mWindowManager.addView(decorView, mWindowLayoutParams);
         decorView.requestApplyInsets();
 
-        if (screenshotShelfUi2()) {
-            ViewGroup layout = decorView.requireViewById(android.R.id.content);
-            layout.setClipChildren(false);
-            layout.setClipToPadding(false);
-        }
+        ViewGroup layout = decorView.requireViewById(android.R.id.content);
+        layout.setClipChildren(false);
+        layout.setClipToPadding(false);
     }
 
     void removeWindow() {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt
index 40d709d..2699657 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.screenshot
 
 import android.net.Uri
@@ -12,6 +28,7 @@
 import com.android.systemui.display.data.repository.DisplayRepository
 import com.android.systemui.res.R
 import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_CAPTURE_FAILED
+import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_DISMISSED_OTHER
 import com.android.systemui.screenshot.TakeScreenshotService.RequestCallback
 import java.util.function.Consumer
 import javax.inject.Inject
@@ -25,9 +42,13 @@
         onSaved: (Uri?) -> Unit,
         requestCallback: RequestCallback
     )
+
     fun onCloseSystemDialogsReceived()
+
     fun removeWindows()
+
     fun onDestroy()
+
     fun executeScreenshotsAsync(
         screenshotRequest: ScreenshotRequest,
         onSaved: Consumer<Uri?>,
@@ -35,6 +56,14 @@
     )
 }
 
+interface ScreenshotHandler {
+    fun handleScreenshot(
+        screenshot: ScreenshotData,
+        finisher: Consumer<Uri?>,
+        requestCallback: RequestCallback
+    )
+}
+
 /**
  * Receives the signal to take a screenshot from [TakeScreenshotService], and calls back with the
  * result.
@@ -51,10 +80,10 @@
     private val screenshotRequestProcessor: ScreenshotRequestProcessor,
     private val uiEventLogger: UiEventLogger,
     private val screenshotNotificationControllerFactory: ScreenshotNotificationsController.Factory,
+    private val headlessScreenshotHandler: HeadlessScreenshotHandler,
 ) : TakeScreenshotExecutor {
-
     private val displays = displayRepository.displays
-    private val screenshotControllers = mutableMapOf<Int, ScreenshotController>()
+    private var screenshotController: ScreenshotController? = null
     private val notificationControllers = mutableMapOf<Int, ScreenshotNotificationsController>()
 
     /**
@@ -72,9 +101,15 @@
         val resultCallbackWrapper = MultiResultCallbackWrapper(requestCallback)
         displays.forEach { display ->
             val displayId = display.displayId
+            var screenshotHandler: ScreenshotHandler =
+                if (displayId == Display.DEFAULT_DISPLAY) {
+                    getScreenshotController(display)
+                } else {
+                    headlessScreenshotHandler
+                }
             Log.d(TAG, "Executing screenshot for display $displayId")
             dispatchToController(
-                display = display,
+                screenshotHandler,
                 rawScreenshotData = ScreenshotData.fromRequest(screenshotRequest, displayId),
                 onSaved =
                     if (displayId == Display.DEFAULT_DISPLAY) {
@@ -87,7 +122,7 @@
 
     /** All logging should be triggered only by this method. */
     private suspend fun dispatchToController(
-        display: Display,
+        screenshotHandler: ScreenshotHandler,
         rawScreenshotData: ScreenshotData,
         onSaved: (Uri?) -> Unit,
         callback: RequestCallback
@@ -101,13 +136,12 @@
                     logScreenshotRequested(rawScreenshotData)
                     onFailedScreenshotRequest(rawScreenshotData, callback)
                 }
-                .getOrNull()
-                ?: return
+                .getOrNull() ?: return
 
         logScreenshotRequested(screenshotData)
         Log.d(TAG, "Screenshot request: $screenshotData")
         try {
-            getScreenshotController(display).handleScreenshot(screenshotData, onSaved, callback)
+            screenshotHandler.handleScreenshot(screenshotData, onSaved, callback)
         } catch (e: IllegalStateException) {
             Log.e(TAG, "Error while ScreenshotController was handling ScreenshotData!", e)
             onFailedScreenshotRequest(screenshotData, callback)
@@ -140,43 +174,31 @@
     private suspend fun getDisplaysToScreenshot(requestType: Int): List<Display> {
         val allDisplays = displays.first()
         return if (requestType == TAKE_SCREENSHOT_PROVIDED_IMAGE) {
-            // If this is a provided image, let's show the UI on the default display only.
+            // If this is a provided image just screenshot th default display
             allDisplays.filter { it.displayId == Display.DEFAULT_DISPLAY }
         } else {
             allDisplays.filter { it.type in ALLOWED_DISPLAY_TYPES }
         }
     }
 
-    /** Propagates the close system dialog signal to all controllers. */
+    /** Propagates the close system dialog signal to the ScreenshotController. */
     override fun onCloseSystemDialogsReceived() {
-        screenshotControllers.forEach { (_, screenshotController) ->
-            if (!screenshotController.isPendingSharedTransition) {
-                screenshotController.requestDismissal(ScreenshotEvent.SCREENSHOT_DISMISSED_OTHER)
-            }
+        if (screenshotController?.isPendingSharedTransition == false) {
+            screenshotController?.requestDismissal(SCREENSHOT_DISMISSED_OTHER)
         }
     }
 
     /** Removes all screenshot related windows. */
     override fun removeWindows() {
-        screenshotControllers.forEach { (_, screenshotController) ->
-            screenshotController.removeWindow()
-        }
+        screenshotController?.removeWindow()
     }
 
     /**
      * Destroys the executor. Afterwards, this class is not expected to work as intended anymore.
      */
     override fun onDestroy() {
-        screenshotControllers.forEach { (_, screenshotController) ->
-            screenshotController.onDestroy()
-        }
-        screenshotControllers.clear()
-    }
-
-    private fun getScreenshotController(display: Display): ScreenshotController {
-        return screenshotControllers.computeIfAbsent(display.displayId) {
-            screenshotControllerFactory.create(display, /* showUIOnExternalDisplay= */ false)
-        }
+        screenshotController?.onDestroy()
+        screenshotController = null
     }
 
     private fun getNotificationController(id: Int): ScreenshotNotificationsController {
@@ -196,6 +218,12 @@
         }
     }
 
+    private fun getScreenshotController(display: Display): ScreenshotController {
+        val controller = screenshotController ?: screenshotControllerFactory.create(display, false)
+        screenshotController = controller
+        return controller
+    }
+
     /**
      * Returns a [RequestCallback] that wraps [originalCallback].
      *
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
index d87d85b..8feefa4 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
@@ -16,16 +16,21 @@
 
 package com.android.systemui.screenshot.appclips;
 
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+
 import static com.android.systemui.screenshot.appclips.AppClipsEvent.SCREENSHOT_FOR_NOTE_ACCEPTED;
 import static com.android.systemui.screenshot.appclips.AppClipsEvent.SCREENSHOT_FOR_NOTE_CANCELLED;
 import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.ACTION_FINISH_FROM_TRAMPOLINE;
 import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_CALLING_PACKAGE_NAME;
+import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_CALLING_PACKAGE_TASK_ID;
+import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_CLIP_DATA;
 import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_RESULT_RECEIVER;
 import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_SCREENSHOT_URI;
 import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.PERMISSION_SELF;
 
 import android.app.Activity;
 import android.content.BroadcastReceiver;
+import android.content.ClipData;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -42,19 +47,28 @@
 import android.util.Log;
 import android.view.View;
 import android.widget.Button;
+import android.widget.CheckBox;
 import android.widget.ImageView;
+import android.widget.TextView;
 
 import androidx.activity.ComponentActivity;
 import androidx.annotation.Nullable;
+import androidx.core.graphics.Insets;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsCompat;
 import androidx.lifecycle.ViewModelProvider;
 
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.UiEventLogger.UiEventEnum;
 import com.android.settingslib.Utils;
+import com.android.systemui.Flags;
+import com.android.systemui.log.DebugLogger;
 import com.android.systemui.res.R;
 import com.android.systemui.screenshot.scroll.CropView;
 import com.android.systemui.settings.UserTracker;
 
+import java.util.Set;
+
 import javax.inject.Inject;
 
 /**
@@ -73,8 +87,6 @@
  *
  * <p>This {@link Activity} runs in its own separate process to isolate memory intensive image
  * editing from SysUI process.
- *
- * TODO(b/267309532): Polish UI and animations.
  */
 public class AppClipsActivity extends ComponentActivity {
 
@@ -94,6 +106,8 @@
     private CropView mCropView;
     private Button mSave;
     private Button mCancel;
+    private CheckBox mBacklinksIncludeDataCheckBox;
+    private TextView mBacklinksDataTextView;
     private AppClipsViewModel mViewModel;
 
     private ResultReceiver mResultReceiver;
@@ -149,26 +163,47 @@
         mLayout = getLayoutInflater().inflate(R.layout.app_clips_screenshot, null);
         mRoot = mLayout.findViewById(R.id.root);
 
+        // Manually handle window insets post Android V to support edge-to-edge display.
+        ViewCompat.setOnApplyWindowInsetsListener(mRoot, (v, windowInsets) -> {
+            Insets insets = windowInsets.getInsets(
+                    WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout());
+            v.setPadding(insets.left, insets.top, insets.right, insets.bottom);
+            return WindowInsetsCompat.CONSUMED;
+        });
+
         mSave = mLayout.findViewById(R.id.save);
         mCancel = mLayout.findViewById(R.id.cancel);
         mSave.setOnClickListener(this::onClick);
         mCancel.setOnClickListener(this::onClick);
-
-
         mCropView = mLayout.findViewById(R.id.crop_view);
-
         mPreview = mLayout.findViewById(R.id.preview);
         mPreview.addOnLayoutChangeListener(
                 (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
                         updateImageDimensions());
 
+        mBacklinksDataTextView = mLayout.findViewById(R.id.backlinks_data);
+        mBacklinksIncludeDataCheckBox = mLayout.findViewById(R.id.backlinks_include_data);
+        mBacklinksIncludeDataCheckBox.setOnCheckedChangeListener(
+                (buttonView, isChecked) ->
+                        mBacklinksDataTextView.setVisibility(isChecked ? View.VISIBLE : View.GONE));
+
         mViewModel = new ViewModelProvider(this, mViewModelFactory).get(AppClipsViewModel.class);
         mViewModel.getScreenshot().observe(this, this::setScreenshot);
         mViewModel.getResultLiveData().observe(this, this::setResultThenFinish);
         mViewModel.getErrorLiveData().observe(this, this::setErrorThenFinish);
+        mViewModel.getBacklinksLiveData().observe(this, this::setBacklinksData);
 
         if (savedInstanceState == null) {
-            mViewModel.performScreenshot();
+            int displayId = getDisplayId();
+            mViewModel.performScreenshot(displayId);
+
+            if (Flags.appClipsBacklinks()) {
+                int appClipsTaskId = getTaskId();
+                int callingPackageTaskId = intent.getIntExtra(EXTRA_CALLING_PACKAGE_TASK_ID,
+                        INVALID_TASK_ID);
+                Set<Integer> taskIdsToIgnore = Set.of(appClipsTaskId, callingPackageTaskId);
+                mViewModel.triggerBacklinks(taskIdsToIgnore, displayId);
+            }
         }
     }
 
@@ -217,6 +252,9 @@
 
         // Screenshot is now available so set content view.
         setContentView(mLayout);
+
+        // Request view to apply insets as it is added late and not when activity was first created.
+        mRoot.requestApplyInsets();
     }
 
     private void onClick(View view) {
@@ -264,11 +302,22 @@
         data.putInt(Intent.EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE,
                 Intent.CAPTURE_CONTENT_FOR_NOTE_SUCCESS);
         data.putParcelable(EXTRA_SCREENSHOT_URI, uri);
+
+        if (mBacklinksIncludeDataCheckBox.getVisibility() == View.VISIBLE
+                && mBacklinksIncludeDataCheckBox.isChecked()
+                && mViewModel.getBacklinksLiveData().getValue() != null) {
+            ClipData backlinksData = mViewModel.getBacklinksLiveData().getValue().getClipData();
+            data.putParcelable(EXTRA_CLIP_DATA, backlinksData);
+
+            DebugLogger.INSTANCE.logcatMessage(this,
+                    () -> "setResultThenFinish: sending notes app ClipData");
+        }
+
         try {
             mResultReceiver.send(Activity.RESULT_OK, data);
             logUiEvent(SCREENSHOT_FOR_NOTE_ACCEPTED);
         } catch (Exception e) {
-            // Do nothing.
+            Log.e(TAG, "Error while sending data to trampoline activity", e);
         }
 
         // Nullify the ResultReceiver before finishing to avoid resending the result.
@@ -281,6 +330,20 @@
         finish();
     }
 
+    private void setBacklinksData(InternalBacklinksData backlinksData) {
+        mBacklinksIncludeDataCheckBox.setVisibility(View.VISIBLE);
+        mBacklinksDataTextView.setVisibility(
+                mBacklinksIncludeDataCheckBox.isChecked() ? View.VISIBLE : View.GONE);
+
+        mBacklinksDataTextView.setText(backlinksData.getClipData().getDescription().getLabel());
+
+        Drawable appIcon = backlinksData.getAppIcon();
+        int size = getResources().getDimensionPixelSize(R.dimen.appclips_backlinks_icon_size);
+        appIcon.setBounds(/* left= */ 0, /* top= */ 0, /* right= */ size, /* bottom= */ size);
+        mBacklinksDataTextView.setCompoundDrawablesRelative(/* start= */ appIcon, /* top= */
+                null, /* end= */ null, /* bottom= */ null);
+    }
+
     private void setError(int errorCode) {
         if (mResultReceiver == null) {
             return;
@@ -295,6 +358,7 @@
             }
         } catch (Exception e) {
             // Do nothing.
+            Log.e(TAG, "Error while sending trampoline activity error code: " + errorCode, e);
         }
 
         // Nullify the ResultReceiver to avoid resending the result.
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsCrossProcessHelper.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsCrossProcessHelper.java
index 7de22b1..aaa5dfc 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsCrossProcessHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsCrossProcessHelper.java
@@ -20,6 +20,7 @@
 import android.content.Intent;
 import android.graphics.Bitmap;
 import android.os.UserHandle;
+import android.util.Log;
 
 import androidx.annotation.Nullable;
 
@@ -27,19 +28,18 @@
 import com.android.internal.infra.ServiceConnector;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Application;
-import com.android.systemui.settings.DisplayTracker;
 
 import javax.inject.Inject;
 
 /** An intermediary singleton object to help communicating with the cross process service. */
 @SysUISingleton
 class AppClipsCrossProcessHelper {
+    private static final String TAG = AppClipsCrossProcessHelper.class.getSimpleName();
 
     private final ServiceConnector<IAppClipsScreenshotHelperService> mProxyConnector;
-    private final DisplayTracker mDisplayTracker;
 
     @Inject
-    AppClipsCrossProcessHelper(@Application Context context, DisplayTracker displayTracker) {
+    AppClipsCrossProcessHelper(@Application Context context) {
         // Start a service as main user so that even if the app clips activity is running as work
         // profile user the service is able to use correct instance of Bubbles to grab a screenshot
         // excluding the bubble layer.
@@ -48,7 +48,6 @@
                 Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY
                         | Context.BIND_NOT_VISIBLE, UserHandle.USER_SYSTEM,
                 IAppClipsScreenshotHelperService.Stub::asInterface);
-        mDisplayTracker = displayTracker;
     }
 
     /**
@@ -58,15 +57,16 @@
      * pass around but not a {@link Bitmap}.
      */
     @Nullable
-    Bitmap takeScreenshot() {
+    Bitmap takeScreenshot(int displayId) {
         try {
             AndroidFuture<ScreenshotHardwareBufferInternal> future =
                     mProxyConnector.postForResult(
-                            service ->
-                                    // Take a screenshot of the default display of the user.
-                                    service.takeScreenshot(mDisplayTracker.getDefaultDisplayId()));
+                            service -> service.takeScreenshot(displayId));
             return future.get().createBitmapThenCloseBuffer();
         } catch (Exception e) {
+            Log.e(TAG,
+                    String.format("Error while capturing a screenshot of displayId %d", displayId),
+                    e);
             return null;
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java
index 48449b3..ef18fbe 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java
@@ -26,6 +26,7 @@
 
 import android.app.Activity;
 import android.content.ActivityNotFoundException;
+import android.content.ClipData;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -52,6 +53,7 @@
 import com.android.systemui.dagger.qualifiers.Application;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.log.DebugLogger;
 import com.android.systemui.notetask.NoteTaskController;
 import com.android.systemui.notetask.NoteTaskEntryPoint;
 import com.android.systemui.res.R;
@@ -82,9 +84,11 @@
     private static final String TAG = AppClipsTrampolineActivity.class.getSimpleName();
     static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
     static final String EXTRA_SCREENSHOT_URI = TAG + "SCREENSHOT_URI";
+    static final String EXTRA_CLIP_DATA = TAG + "CLIP_DATA";
     static final String ACTION_FINISH_FROM_TRAMPOLINE = TAG + "FINISH_FROM_TRAMPOLINE";
     static final String EXTRA_RESULT_RECEIVER = TAG + "RESULT_RECEIVER";
     static final String EXTRA_CALLING_PACKAGE_NAME = TAG + "CALLING_PACKAGE_NAME";
+    static final String EXTRA_CALLING_PACKAGE_TASK_ID = TAG + "CALLING_PACKAGE_TASK_ID";
     private static final ApplicationInfoFlags APPLICATION_INFO_FLAGS = ApplicationInfoFlags.of(0);
 
     private final NoteTaskController mNoteTaskController;
@@ -193,12 +197,14 @@
         ComponentName componentName = ComponentName.unflattenFromString(
                     getString(R.string.config_screenshotAppClipsActivityComponent));
         String callingPackageName = getCallingPackage();
+        int callingPackageTaskId = getTaskId();
 
         Intent intent = new Intent()
                 .setComponent(componentName)
                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                 .putExtra(EXTRA_RESULT_RECEIVER, mResultReceiver)
-                .putExtra(EXTRA_CALLING_PACKAGE_NAME, callingPackageName);
+                .putExtra(EXTRA_CALLING_PACKAGE_NAME, callingPackageName)
+                .putExtra(EXTRA_CALLING_PACKAGE_TASK_ID, callingPackageTaskId);
         try {
             startActivity(intent);
 
@@ -260,6 +266,15 @@
             if (statusCode == CAPTURE_CONTENT_FOR_NOTE_SUCCESS) {
                 Uri uri = resultData.getParcelable(EXTRA_SCREENSHOT_URI, Uri.class);
                 convertedData.setData(uri);
+
+                if (resultData.containsKey(EXTRA_CLIP_DATA)) {
+                    ClipData backlinksData = resultData.getParcelable(EXTRA_CLIP_DATA,
+                            ClipData.class);
+                    convertedData.setClipData(backlinksData);
+
+                    DebugLogger.INSTANCE.logcatMessage(this,
+                            () -> "onReceiveResult: sending notes app ClipData");
+                }
             }
 
             // Broadcast no longer required, setting it to null.
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java
index 630d338..8c833ec 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java
@@ -16,9 +16,23 @@
 
 package com.android.systemui.screenshot.appclips;
 
+import static android.content.Intent.ACTION_MAIN;
+import static android.content.Intent.ACTION_VIEW;
 import static android.content.Intent.CAPTURE_CONTENT_FOR_NOTE_FAILED;
+import static android.content.Intent.CATEGORY_LAUNCHER;
 
+import static com.google.common.util.concurrent.Futures.withTimeout;
+
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+
+import android.app.ActivityTaskManager.RootTaskInfo;
+import android.app.IActivityTaskManager;
+import android.app.WindowConfiguration;
+import android.app.assist.AssistContent;
+import android.content.ClipData;
+import android.content.ComponentName;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
 import android.graphics.HardwareRenderer;
 import android.graphics.RecordingCanvas;
@@ -26,10 +40,13 @@
 import android.graphics.RenderNode;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.RemoteException;
 import android.os.UserHandle;
+import android.util.Log;
 import android.view.Display;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.lifecycle.LiveData;
 import androidx.lifecycle.MutableLiveData;
 import androidx.lifecycle.ViewModel;
@@ -37,22 +54,37 @@
 
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.log.DebugLogger;
+import com.android.systemui.screenshot.AssistContentRequester;
 import com.android.systemui.screenshot.ImageExporter;
 
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
 
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
 
 import javax.inject.Inject;
 
 /** A {@link ViewModel} to help with the App Clips screenshot flow. */
 final class AppClipsViewModel extends ViewModel {
 
+    private static final String TAG = AppClipsViewModel.class.getSimpleName();
+
     private final AppClipsCrossProcessHelper mAppClipsCrossProcessHelper;
     private final ImageExporter mImageExporter;
+    private final IActivityTaskManager mAtmService;
+    private final AssistContentRequester mAssistContentRequester;
+    private final PackageManager mPackageManager;
+
     @Main
     private final Executor mMainExecutor;
     @Background
@@ -61,24 +93,34 @@
     private final MutableLiveData<Bitmap> mScreenshotLiveData;
     private final MutableLiveData<Uri> mResultLiveData;
     private final MutableLiveData<Integer> mErrorLiveData;
+    private final MutableLiveData<InternalBacklinksData> mBacklinksLiveData;
 
-    AppClipsViewModel(AppClipsCrossProcessHelper appClipsCrossProcessHelper,
-            ImageExporter imageExporter, @Main Executor mainExecutor,
-            @Background Executor bgExecutor) {
+    private AppClipsViewModel(AppClipsCrossProcessHelper appClipsCrossProcessHelper,
+            ImageExporter imageExporter, IActivityTaskManager atmService,
+            AssistContentRequester assistContentRequester, PackageManager packageManager,
+            @Main Executor mainExecutor, @Background Executor bgExecutor) {
         mAppClipsCrossProcessHelper = appClipsCrossProcessHelper;
         mImageExporter = imageExporter;
+        mAtmService = atmService;
+        mAssistContentRequester = assistContentRequester;
+        mPackageManager = packageManager;
         mMainExecutor = mainExecutor;
         mBgExecutor = bgExecutor;
 
         mScreenshotLiveData = new MutableLiveData<>();
         mResultLiveData = new MutableLiveData<>();
         mErrorLiveData = new MutableLiveData<>();
+        mBacklinksLiveData = new MutableLiveData<>();
     }
 
-    /** Grabs a screenshot and updates the {@link Bitmap} set in screenshot {@link LiveData}. */
-    void performScreenshot() {
+    /**
+     * Grabs a screenshot and updates the {@link Bitmap} set in screenshot {@link #getScreenshot()}.
+     *
+     * @param displayId id of the {@link Display} to capture screenshot.
+     */
+    void performScreenshot(int displayId) {
         mBgExecutor.execute(() -> {
-            Bitmap screenshot = mAppClipsCrossProcessHelper.takeScreenshot();
+            Bitmap screenshot = mAppClipsCrossProcessHelper.takeScreenshot(displayId);
             mMainExecutor.execute(() -> {
                 if (screenshot == null) {
                     mErrorLiveData.setValue(CAPTURE_CONTENT_FOR_NOTE_FAILED);
@@ -89,6 +131,40 @@
         });
     }
 
+    /**
+     * Triggers the Backlinks flow which:
+     * <ul>
+     *     <li>Evaluates the task to query.
+     *     <li>Requests {@link AssistContent} from that task.
+     *     <li>Transforms the {@link AssistContent} into {@link ClipData} for Backlinks.
+     *     <li>The {@link ClipData} is reported to activity via {@link #getBacklinksLiveData()}.
+     * </ul>
+     *
+     * @param taskIdsToIgnore id of the tasks to ignore when querying for {@link AssistContent}
+     * @param displayId       id of the display to query tasks for Backlinks data
+     */
+    void triggerBacklinks(Set<Integer> taskIdsToIgnore, int displayId) {
+        DebugLogger.INSTANCE.logcatMessage(this, () -> "Backlinks triggered");
+        mBgExecutor.execute(() -> {
+            ListenableFuture<InternalBacklinksData> backlinksData = getBacklinksData(
+                    taskIdsToIgnore, displayId);
+            Futures.addCallback(backlinksData, new FutureCallback<>() {
+                @Override
+                public void onSuccess(@Nullable InternalBacklinksData result) {
+                    if (result != null) {
+                        mBacklinksLiveData.setValue(result);
+                    }
+                }
+
+                @Override
+                public void onFailure(Throwable t) {
+                    Log.e(TAG, "Error querying for Backlinks data", t);
+                }
+            }, mMainExecutor);
+
+        });
+    }
+
     /** Returns a {@link LiveData} that holds the captured screenshot. */
     LiveData<Bitmap> getScreenshot() {
         return mScreenshotLiveData;
@@ -107,6 +183,11 @@
         return mErrorLiveData;
     }
 
+    /** Returns a {@link LiveData} that holds Backlinks data in {@link InternalBacklinksData}. */
+    LiveData<InternalBacklinksData> getBacklinksLiveData() {
+        return mBacklinksLiveData;
+    }
+
     /**
      * Saves the provided {@link Drawable} to storage then informs the result {@link Uri} to
      * {@link LiveData}.
@@ -148,21 +229,172 @@
         return HardwareRenderer.createHardwareBitmap(output, bounds.width(), bounds.height());
     }
 
+    private ListenableFuture<InternalBacklinksData> getBacklinksData(Set<Integer> taskIdsToIgnore,
+            int displayId) {
+        return getAllRootTaskInfosOnDisplay(displayId)
+                .stream()
+                .filter(taskInfo -> shouldIncludeTask(taskInfo, taskIdsToIgnore))
+                .findFirst()
+                .map(this::getBacklinksDataForTaskId)
+                .orElse(Futures.immediateFuture(null));
+    }
+
+    private List<RootTaskInfo> getAllRootTaskInfosOnDisplay(int displayId) {
+        try {
+            return mAtmService.getAllRootTaskInfosOnDisplay(displayId);
+        } catch (RemoteException e) {
+            Log.e(TAG, String.format("Error while querying for tasks on display %d", displayId), e);
+            return Collections.emptyList();
+        }
+    }
+
+    private boolean shouldIncludeTask(RootTaskInfo taskInfo, Set<Integer> taskIdsToIgnore) {
+        DebugLogger.INSTANCE.logcatMessage(this,
+                () -> String.format("shouldIncludeTask taskId %d; topActivity %s", taskInfo.taskId,
+                        taskInfo.topActivity));
+
+        // Only consider tasks that shouldn't be ignored, are visible, running, and have a launcher
+        // icon. Furthermore, types such as launcher/home/dock/assistant are ignored.
+        return !taskIdsToIgnore.contains(taskInfo.taskId)
+                && taskInfo.isVisible
+                && taskInfo.isRunning
+                && taskInfo.numActivities > 0
+                && taskInfo.topActivity != null
+                && taskInfo.topActivityInfo != null
+                && taskInfo.childTaskIds.length > 0
+                && taskInfo.getActivityType() == WindowConfiguration.ACTIVITY_TYPE_STANDARD
+                && canAppStartThroughLauncher(taskInfo.topActivity.getPackageName());
+    }
+
+    private boolean canAppStartThroughLauncher(String packageName) {
+        return getMainLauncherIntentForPackage(packageName).resolveActivity(mPackageManager)
+                != null;
+    }
+
+    private ListenableFuture<InternalBacklinksData> getBacklinksDataForTaskId(
+            RootTaskInfo taskInfo) {
+        DebugLogger.INSTANCE.logcatMessage(this,
+                () -> String.format("getBacklinksDataForTaskId for taskId %d; topActivity %s",
+                        taskInfo.taskId, taskInfo.topActivity));
+
+        SettableFuture<InternalBacklinksData> backlinksData = SettableFuture.create();
+        int taskId = taskInfo.taskId;
+        mAssistContentRequester.requestAssistContent(taskId, assistContent ->
+                backlinksData.set(getBacklinksDataFromAssistContent(taskInfo, assistContent)));
+        return withTimeout(backlinksData, 5L, TimeUnit.SECONDS, newSingleThreadScheduledExecutor());
+    }
+
+    /**
+     * A utility method to get {@link InternalBacklinksData} to use for Backlinks functionality from
+     * {@link AssistContent} received from the app whose screenshot is taken.
+     *
+     * <p>There are multiple ways an app can provide deep-linkable data via {@link AssistContent}
+     * but Backlinks restricts to using only one way. The following is the ordered list based on
+     * preference:
+     * <ul>
+     *     <li>{@link AssistContent#getWebUri()} is the most preferred way.
+     *     <li>Second preference is given to {@link AssistContent#getIntent()} when the app provides
+     *     the intent, see {@link AssistContent#isAppProvidedIntent()}.
+     *     <li>The last preference is given to an {@link Intent} that is built using
+     *     {@link Intent#ACTION_MAIN} and {@link Intent#CATEGORY_LAUNCHER}.
+     * </ul>
+     *
+     * @param taskInfo {@link RootTaskInfo} of the task which provided the {@link AssistContent}.
+     * @param content the {@link AssistContent} to map into Backlinks {@link ClipData}.
+     * @return {@link InternalBacklinksData} that represents the Backlinks data along with app icon.
+     */
+    private InternalBacklinksData getBacklinksDataFromAssistContent(RootTaskInfo taskInfo,
+            @Nullable AssistContent content) {
+        DebugLogger.INSTANCE.logcatMessage(this,
+                () -> String.format("getBacklinksDataFromAssistContent taskId %d; topActivity %s",
+                        taskInfo.taskId, taskInfo.topActivity));
+
+        String appName = getAppNameOfTask(taskInfo);
+        String packageName = taskInfo.topActivity.getPackageName();
+        Drawable appIcon = taskInfo.topActivityInfo.loadIcon(mPackageManager);
+        ClipData mainLauncherIntent = ClipData.newIntent(appName,
+                getMainLauncherIntentForPackage(packageName));
+        InternalBacklinksData fallback = new InternalBacklinksData(mainLauncherIntent, appIcon);
+        if (content == null) {
+            return fallback;
+        }
+
+        // First preference is given to app provided uri.
+        if (content.isAppProvidedWebUri()) {
+            DebugLogger.INSTANCE.logcatMessage(this,
+                    () -> "getBacklinksDataFromAssistContent: app has provided a uri");
+
+            Uri uri = content.getWebUri();
+            Intent backlinksIntent = new Intent(ACTION_VIEW).setData(uri);
+            if (doesIntentResolveToSamePackage(backlinksIntent, packageName)) {
+                DebugLogger.INSTANCE.logcatMessage(this,
+                        () -> "getBacklinksDataFromAssistContent: using app provided uri");
+                return new InternalBacklinksData(ClipData.newRawUri(appName, uri), appIcon);
+            }
+        }
+
+        // Second preference is given to app provided, hopefully deep-linking, intent.
+        if (content.isAppProvidedIntent()) {
+            DebugLogger.INSTANCE.logcatMessage(this,
+                    () -> "getBacklinksDataFromAssistContent: app has provided an intent");
+
+            Intent backlinksIntent = content.getIntent();
+            if (doesIntentResolveToSamePackage(backlinksIntent, packageName)) {
+                DebugLogger.INSTANCE.logcatMessage(this,
+                        () -> "getBacklinksDataFromAssistContent: using app provided intent");
+                return new InternalBacklinksData(ClipData.newIntent(appName, backlinksIntent),
+                        appIcon);
+            }
+        }
+
+        DebugLogger.INSTANCE.logcatMessage(this,
+                () -> "getBacklinksDataFromAssistContent: using fallback");
+        return fallback;
+    }
+
+    private boolean doesIntentResolveToSamePackage(Intent intentToResolve,
+            String requiredPackageName) {
+        ComponentName resolvedComponent = intentToResolve.resolveActivity(mPackageManager);
+        if (resolvedComponent == null) {
+            return false;
+        }
+
+        return resolvedComponent.getPackageName().equals(requiredPackageName);
+    }
+
+    private String getAppNameOfTask(RootTaskInfo taskInfo) {
+        return taskInfo.topActivityInfo.loadLabel(mPackageManager).toString();
+    }
+
+    private Intent getMainLauncherIntentForPackage(String packageName) {
+        return new Intent(ACTION_MAIN)
+                .addCategory(CATEGORY_LAUNCHER)
+                .setPackage(packageName);
+    }
+
     /** Helper factory to help with injecting {@link AppClipsViewModel}. */
     static final class Factory implements ViewModelProvider.Factory {
 
         private final AppClipsCrossProcessHelper mAppClipsCrossProcessHelper;
         private final ImageExporter mImageExporter;
+        private final IActivityTaskManager mAtmService;
+        private final AssistContentRequester mAssistContentRequester;
+        private final PackageManager mPackageManager;
         @Main
         private final Executor mMainExecutor;
         @Background
         private final Executor mBgExecutor;
 
         @Inject
-        Factory(AppClipsCrossProcessHelper appClipsCrossProcessHelper,  ImageExporter imageExporter,
-                @Main Executor mainExecutor, @Background Executor bgExecutor) {
+        Factory(AppClipsCrossProcessHelper appClipsCrossProcessHelper, ImageExporter imageExporter,
+                IActivityTaskManager atmService, AssistContentRequester assistContentRequester,
+                PackageManager packageManager, @Main Executor mainExecutor,
+                @Background Executor bgExecutor) {
             mAppClipsCrossProcessHelper = appClipsCrossProcessHelper;
             mImageExporter = imageExporter;
+            mAtmService = atmService;
+            mAssistContentRequester = assistContentRequester;
+            mPackageManager = packageManager;
             mMainExecutor = mainExecutor;
             mBgExecutor = bgExecutor;
         }
@@ -176,7 +408,8 @@
 
             //noinspection unchecked
             return (T) new AppClipsViewModel(mAppClipsCrossProcessHelper, mImageExporter,
-                    mMainExecutor, mBgExecutor);
+                    mAtmService, mAssistContentRequester, mPackageManager, mMainExecutor,
+                    mBgExecutor);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/InternalBacklinksData.kt b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/InternalBacklinksData.kt
new file mode 100644
index 0000000..0e312f9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/InternalBacklinksData.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.screenshot.appclips
+
+import android.content.ClipData
+import android.graphics.drawable.Drawable
+
+/** A class to hold the [ClipData] for backlinks and the corresponding app's [Drawable] icon. */
+internal data class InternalBacklinksData(val clipData: ClipData, val appIcon: Drawable)
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/dagger/ScreenshotModule.java b/packages/SystemUI/src/com/android/systemui/screenshot/dagger/ScreenshotModule.java
index 8235325..56ba1af4 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/dagger/ScreenshotModule.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/dagger/ScreenshotModule.java
@@ -16,15 +16,12 @@
 
 package com.android.systemui.screenshot.dagger;
 
-import static com.android.systemui.Flags.screenshotShelfUi2;
-
 import android.app.Service;
 import android.view.accessibility.AccessibilityManager;
 
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.screenshot.ImageCapture;
 import com.android.systemui.screenshot.ImageCaptureImpl;
-import com.android.systemui.screenshot.LegacyScreenshotViewProxy;
 import com.android.systemui.screenshot.ScreenshotPolicy;
 import com.android.systemui.screenshot.ScreenshotPolicyImpl;
 import com.android.systemui.screenshot.ScreenshotShelfViewProxy;
@@ -96,14 +93,7 @@
         return new ScreenshotViewModel(accessibilityManager);
     }
 
-    @Provides
-    static ScreenshotViewProxy.Factory providesScreenshotViewProxyFactory(
-            ScreenshotShelfViewProxy.Factory shelfScreenshotViewProxyFactory,
-            LegacyScreenshotViewProxy.Factory legacyScreenshotViewProxyFactory) {
-        if (screenshotShelfUi2()) {
-            return shelfScreenshotViewProxyFactory;
-        } else {
-            return legacyScreenshotViewProxyFactory;
-        }
-    }
+    @Binds
+    abstract ScreenshotViewProxy.Factory bindScreenshotViewProxyFactory(
+            ScreenshotShelfViewProxy.Factory shelfScreenshotViewProxyFactory);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ScreenshotShelfViewBinder.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ScreenshotShelfViewBinder.kt
index 442b387..0fefa0b 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ScreenshotShelfViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ScreenshotShelfViewBinder.kt
@@ -128,8 +128,9 @@
                         }
                     }
                     launch {
-                        viewModel.previewAction.collect { onClick ->
-                            previewView.setOnClickListener { onClick?.invoke() }
+                        viewModel.previewAction.collect { action ->
+                            previewView.setOnClickListener { action?.onClick?.invoke() }
+                            previewView.contentDescription = action?.contentDescription
                         }
                     }
                     launch {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModel.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModel.kt
index 3f99bc4..25420d4 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModel.kt
@@ -31,8 +31,8 @@
     val scrollingScrim: StateFlow<Bitmap?> = _scrollingScrim
     private val _badge = MutableStateFlow<Drawable?>(null)
     val badge: StateFlow<Drawable?> = _badge
-    private val _previewAction = MutableStateFlow<(() -> Unit)?>(null)
-    val previewAction: StateFlow<(() -> Unit)?> = _previewAction
+    private val _previewAction = MutableStateFlow<PreviewAction?>(null)
+    val previewAction: StateFlow<PreviewAction?> = _previewAction
     private val _actions = MutableStateFlow(emptyList<ActionButtonViewModel>())
     val actions: StateFlow<List<ActionButtonViewModel>> = _actions
     private val _animationState = MutableStateFlow(AnimationState.NOT_STARTED)
@@ -57,8 +57,8 @@
         _badge.value = badge
     }
 
-    fun setPreviewAction(onClick: () -> Unit) {
-        _previewAction.value = onClick
+    fun setPreviewAction(previewAction: PreviewAction) {
+        _previewAction.value = previewAction
     }
 
     fun addAction(
@@ -149,6 +149,11 @@
     }
 }
 
+data class PreviewAction(
+    val contentDescription: CharSequence,
+    val onClick: () -> Unit,
+)
+
 enum class AnimationState {
     NOT_STARTED,
     ENTRANCE_STARTED, // The first 200ms of the entrance animation
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
index d382b7a..a62edcb 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessDialog.java
@@ -25,6 +25,7 @@
 
 import android.app.Activity;
 import android.content.res.Configuration;
+import android.graphics.Insets;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.view.Gravity;
@@ -32,7 +33,9 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
+import android.view.WindowInsets;
 import android.view.WindowManager;
+import android.view.WindowMetrics;
 import android.view.accessibility.AccessibilityManager;
 import android.widget.FrameLayout;
 
@@ -152,18 +155,27 @@
 
         Configuration configuration = getResources().getConfiguration();
         int orientation = configuration.orientation;
-        int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
+        int windowWidth = getWindowAvailableWidth();
 
         if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
             boolean shouldBeFullWidth = getIntent()
                     .getBooleanExtra(EXTRA_BRIGHTNESS_DIALOG_IS_FULL_WIDTH, false);
-            lp.width = (shouldBeFullWidth ? screenWidth : screenWidth / 2) - horizontalMargin * 2;
+            lp.width = (shouldBeFullWidth ? windowWidth : windowWidth / 2) - horizontalMargin * 2;
         } else if (orientation == Configuration.ORIENTATION_PORTRAIT) {
-            lp.width = screenWidth - horizontalMargin * 2;
+            lp.width = windowWidth - horizontalMargin * 2;
         }
 
         frame.setLayoutParams(lp);
+    }
 
+    private int getWindowAvailableWidth() {
+        final WindowMetrics metrics = getWindowManager().getCurrentWindowMetrics();
+        // Gets all excluding insets
+        final WindowInsets windowInsets = metrics.getWindowInsets();
+        Insets insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()
+                | WindowInsets.Type.displayCutout());
+        int insetsWidth = insets.right + insets.left;
+        return metrics.getBounds().width() - insetsWidth;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflater.kt b/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflater.kt
index 468a873..cebc59b 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflater.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/binder/BrightnessMirrorInflater.kt
@@ -21,6 +21,7 @@
 import android.view.View
 import android.view.ViewGroup
 import androidx.core.view.isVisible
+import androidx.core.view.setPadding
 import com.android.systemui.res.R
 import com.android.systemui.settings.brightness.BrightnessSliderController
 
@@ -33,7 +34,15 @@
         val frame =
             (LayoutInflater.from(context).inflate(R.layout.brightness_mirror_container, null)
                     as ViewGroup)
-                .apply { isVisible = true }
+                .apply {
+                    isVisible = true
+                    // Match BrightnessMirrorController padding
+                    setPadding(
+                        context.resources.getDimensionPixelSize(
+                            R.dimen.rounded_slider_background_padding
+                        )
+                    )
+                }
         val sliderController = sliderControllerFactory.create(context, frame)
         sliderController.init()
         frame.addView(
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/viewModel/BrightnessMirrorViewModel.kt b/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/viewModel/BrightnessMirrorViewModel.kt
index 2651a994..79e8b87 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/viewModel/BrightnessMirrorViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/ui/viewModel/BrightnessMirrorViewModel.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.settings.brightness.ui.viewModel
 
 import android.content.res.Resources
+import android.util.Log
 import android.view.View
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
@@ -67,25 +68,45 @@
     override fun setLocationAndSize(view: View) {
         view.getLocationInWindow(tempPosition)
         val padding = resources.getDimensionPixelSize(R.dimen.rounded_slider_background_padding)
-        _toggleSlider?.rootView?.setPadding(padding, padding, padding, padding)
         // Account for desired padding
         _locationAndSize.value =
             LocationAndSize(
-                yOffset = tempPosition[1] - padding,
+                yOffsetFromContainer = view.findTopFromContainer() - padding,
+                yOffsetFromWindow = tempPosition[1] - padding,
                 width = view.measuredWidth + 2 * padding,
                 height = view.measuredHeight + 2 * padding,
             )
     }
 
+    private fun View.findTopFromContainer(): Int {
+        var out = 0
+        var view = this
+        while (view.id != R.id.quick_settings_container) {
+            out += view.top
+            val parent = view.parent as? View
+            if (parent == null) {
+                Log.wtf(TAG, "Couldn't find container in parents of $this")
+                break
+            }
+            view = parent
+        }
+        return out
+    }
+
     // Callbacks are used for indicating reinflation when the config changes in some ways (like
     // density). However, we don't need that as we recompose the view anyway
     override fun addCallback(listener: MirrorController.BrightnessMirrorListener) {}
 
     override fun removeCallback(listener: MirrorController.BrightnessMirrorListener) {}
+
+    companion object {
+        private const val TAG = "BrightnessMirrorViewModel"
+    }
 }
 
 data class LocationAndSize(
-    val yOffset: Int = 0,
+    val yOffsetFromContainer: Int = 0,
+    val yOffsetFromWindow: Int = 0,
     val width: Int = 0,
     val height: Int = 0,
 )
diff --git a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
index 2def6c7..d870fe6 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.shade
 
 import android.content.Context
+import android.graphics.Insets
 import android.graphics.Rect
 import android.os.PowerManager
 import android.os.SystemClock
@@ -25,6 +26,7 @@
 import android.view.MotionEvent
 import android.view.View
 import android.view.ViewGroup
+import android.view.WindowInsets
 import android.widget.FrameLayout
 import androidx.activity.OnBackPressedDispatcher
 import androidx.activity.OnBackPressedDispatcherOwner
@@ -37,7 +39,7 @@
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.compose.theme.PlatformTheme
 import com.android.internal.annotations.VisibleForTesting
-import com.android.systemui.Flags.glanceableHubFullscreenSwipe
+import com.android.systemui.Flags.glanceableHubBackGesture
 import com.android.systemui.ambient.touch.TouchMonitor
 import com.android.systemui.ambient.touch.dagger.AmbientTouchComponent
 import com.android.systemui.communal.dagger.Communal
@@ -48,8 +50,6 @@
 import com.android.systemui.communal.util.CommunalColors
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
-import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.res.R
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
@@ -151,8 +151,6 @@
     /**
      * True if either the primary or alternate bouncer are open, meaning the hub should not receive
      * any touch input.
-     *
-     * Tracks [KeyguardTransitionInteractor.isFinishedInState] for [KeyguardState.isBouncerState].
      */
     private var anyBouncerShowing = false
 
@@ -264,15 +262,33 @@
             // Run when the touch handling lifecycle is RESUMED, meaning the hub is visible and not
             // occluded.
             lifecycleRegistry.repeatOnLifecycle(Lifecycle.State.RESUMED) {
-                val exclusionRect =
-                    Rect(
-                        0,
-                        topEdgeSwipeRegionWidth,
-                        containerView.right,
-                        containerView.bottom - bottomEdgeSwipeRegionWidth
-                    )
+                // Avoid adding exclusion to right/left edges to allow back gestures.
+                val insets =
+                    if (glanceableHubBackGesture()) {
+                        containerView.rootWindowInsets.getInsets(WindowInsets.Type.systemGestures())
+                    } else {
+                        Insets.NONE
+                    }
 
-                containerView.systemGestureExclusionRects = listOf(exclusionRect)
+                containerView.systemGestureExclusionRects =
+                    listOf(
+                        // Only allow swipe up to bouncer and swipe down to shade in the very
+                        // top/bottom to avoid conflicting with widgets in the hub grid.
+                        Rect(
+                            insets.left,
+                            topEdgeSwipeRegionWidth,
+                            containerView.right - insets.right,
+                            containerView.bottom - bottomEdgeSwipeRegionWidth
+                        ),
+                        // Disable back gestures on the left side of the screen, to avoid
+                        // conflicting with scene transitions.
+                        Rect(
+                            0,
+                            0,
+                            insets.right,
+                            containerView.bottom,
+                        )
+                    )
             }
         }
 
@@ -309,13 +325,9 @@
         )
         collectFlow(containerView, keyguardInteractor.isDreaming, { isDreaming = it })
 
-        if (glanceableHubFullscreenSwipe()) {
-            communalContainerWrapper = CommunalWrapper(containerView.context)
-            communalContainerWrapper?.addView(communalContainerView)
-            return communalContainerWrapper!!
-        } else {
-            return containerView
-        }
+        communalContainerWrapper = CommunalWrapper(containerView.context)
+        communalContainerWrapper?.addView(communalContainerView)
+        return communalContainerWrapper!!
     }
 
     /**
@@ -371,8 +383,7 @@
         // and the touch is within the horizontal notification band on the screen, do not process
         // the touch.
         if (
-            glanceableHubFullscreenSwipe() &&
-                !hubShowing &&
+            !hubShowing &&
                 !notificationStackScrollLayoutController.isBelowLastNotification(ev.x, ev.y)
         ) {
             return false
@@ -389,17 +400,7 @@
         val hubOccluded = anyBouncerShowing || shadeShowing
 
         if (isDown && !hubOccluded) {
-            if (glanceableHubFullscreenSwipe()) {
-                isTrackingHubTouch = true
-            } else {
-                val x = ev.rawX
-                val inOpeningSwipeRegion: Boolean = x >= view.width - rightEdgeSwipeRegionWidth
-                if (inOpeningSwipeRegion || hubShowing) {
-                    // Steal touch events when the hub is open, or if the touch started in the
-                    // opening gesture region.
-                    isTrackingHubTouch = true
-                }
-            }
+            isTrackingHubTouch = true
         }
 
         if (isTrackingHubTouch) {
@@ -419,20 +420,12 @@
     private fun dispatchTouchEvent(view: View, ev: MotionEvent): Boolean {
         try {
             var handled = false
-            if (glanceableHubFullscreenSwipe()) {
-                communalContainerWrapper?.dispatchTouchEvent(ev) {
-                    if (it) {
-                        handled = true
-                    }
+            communalContainerWrapper?.dispatchTouchEvent(ev) {
+                if (it) {
+                    handled = true
                 }
-                return handled || hubShowing
-            } else {
-                view.dispatchTouchEvent(ev)
-                // Return true regardless of dispatch result as some touches at the start of a
-                // gesture
-                // may return false from dispatchTouchEvent.
-                return true
             }
+            return handled || hubShowing
         } finally {
             powerManager.userActivity(
                 SystemClock.uptimeMillis(),
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 262befc..04de2c2 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -25,7 +25,6 @@
 import static com.android.keyguard.KeyguardClockSwitch.LARGE;
 import static com.android.keyguard.KeyguardClockSwitch.SMALL;
 import static com.android.systemui.Flags.predictiveBackAnimateShade;
-import static com.android.systemui.Flags.shadeCollapseActivityLaunchFix;
 import static com.android.systemui.Flags.smartspaceRelocateToBottom;
 import static com.android.systemui.classifier.Classifier.BOUNCER_UNLOCK;
 import static com.android.systemui.classifier.Classifier.GENERIC;
@@ -149,7 +148,7 @@
 import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingLockscreenHostedTransitionViewModel;
 import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingTransitionViewModel;
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardTouchHandlingViewModel;
 import com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel;
 import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel;
 import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel;
@@ -159,8 +158,8 @@
 import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager;
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarView;
 import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.navigationbar.views.NavigationBarView;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.FalsingManager.FalsingTapListener;
@@ -484,7 +483,9 @@
     private float mBottomAreaShadeAlpha;
     final ValueAnimator mBottomAreaShadeAlphaAnimator;
     private final AnimatableProperty mPanelAlphaAnimator = AnimatableProperty.from("panelAlpha",
-            NotificationPanelView::setPanelAlphaInternal,
+            (view, alpha) -> {
+                setAlphaInternal(alpha);
+            },
             NotificationPanelView::getCurrentPanelAlpha,
             R.id.panel_alpha_animator_tag, R.id.panel_alpha_animator_start_tag,
             R.id.panel_alpha_animator_end_tag);
@@ -774,7 +775,7 @@
             @Main CoroutineDispatcher mainDispatcher,
             KeyguardTransitionInteractor keyguardTransitionInteractor,
             DumpManager dumpManager,
-            KeyguardLongPressViewModel keyguardLongPressViewModel,
+            KeyguardTouchHandlingViewModel keyguardTouchHandlingViewModel,
             KeyguardInteractor keyguardInteractor,
             ActivityStarter activityStarter,
             SharedNotificationContainerInteractor sharedNotificationContainerInteractor,
@@ -969,7 +970,7 @@
         mKeyguardClockInteractor = keyguardClockInteractor;
         KeyguardLongPressViewBinder.bind(
                 mView.requireViewById(R.id.keyguard_long_press),
-                keyguardLongPressViewModel,
+                keyguardTouchHandlingViewModel,
                 () -> {
                     onEmptySpaceClick();
                     return Unit.INSTANCE;
@@ -1043,6 +1044,10 @@
                                 mView.setTranslationY(0f);
                             })
                             .start();
+                } else {
+                    mView.postDelayed(() -> {
+                        instantCollapse();
+                    }, unlockAnimationStartDelay);
                 }
             }
         }
@@ -1090,7 +1095,6 @@
         initBottomArea();
 
         mWakeUpCoordinator.setStackScroller(mNotificationStackScrollLayoutController);
-        mPulseExpansionHandler.setUp(mNotificationStackScrollLayoutController);
         mWakeUpCoordinator.addListener(new NotificationWakeUpCoordinator.WakeUpListener() {
             @Override
             public void onFullyHiddenChanged(boolean isFullyHidden) {
@@ -3046,7 +3050,7 @@
 
                     if (mDeviceEntryFaceAuthInteractor.canFaceAuthRun()) {
                         mUpdateMonitor.requestActiveUnlock(
-                                ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT,
+                                ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY,
                                 "lockScreenEmptySpaceTap");
                     } else {
                         mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_HINT,
@@ -3075,6 +3079,11 @@
         }
     }
 
+    private void setAlphaInternal(float alpha) {
+        mKeyguardInteractor.setPanelAlpha(alpha / 255f);
+        mView.setPanelAlphaInternal(alpha);
+    }
+
     @Override
     public void setAlphaChangeAnimationEndAction(Runnable r) {
         mPanelAlphaEndAction = r;
@@ -3384,7 +3393,9 @@
         /** Updates the views to the initial state for the fold to AOD animation. */
         @Override
         public void prepareFoldToAodAnimation() {
-            if (!MigrateClocksToBlueprint.isEnabled()) {
+            if (MigrateClocksToBlueprint.isEnabled()) {
+                setDozing(true /* dozing */, false /* animate */);
+            } else {
                 // Force show AOD UI even if we are not locked
                 showAodUi();
             }
@@ -4118,11 +4129,7 @@
 
     @Override
     public boolean canBeCollapsed() {
-        return !isFullyCollapsed() && !isTracking() && !isClosing()
-                // Don't try to collapse if on keyguard, as the expansion fraction is 1 in this
-                // case.
-                && !(shadeCollapseActivityLaunchFix() && mExpandedFraction == 1f
-                && mBarState == KEYGUARD);
+        return !isFullyCollapsed() && !isTracking() && !isClosing();
     }
 
     public void instantCollapse() {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
index f67d0c1..bc5cf2a 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
@@ -644,7 +644,8 @@
                     mCurrentState.bouncerShowing,
                     mCurrentState.dozing,
                     mCurrentState.shadeOrQsExpanded,
-                    mCurrentState.dreaming);
+                    mCurrentState.dreaming,
+                    mCurrentState.communalVisible);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index e41f99b..1c223db 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -369,7 +369,9 @@
                 }
 
                 mFalsingCollector.onTouchEvent(ev);
-                mPulsingWakeupGestureHandler.onTouchEvent(ev);
+                if (!SceneContainerFlag.isEnabled()) {
+                    mPulsingWakeupGestureHandler.onTouchEvent(ev);
+                }
 
                 if (!SceneContainerFlag.isEnabled()
                         && mGlanceableHubContainerController.onTouchEvent(ev)) {
@@ -427,7 +429,11 @@
                             } else {
                                 return logDownDispatch(ev, "hidden or hiding", true);
                             }
+                        } else {
+                            mShadeLogger.d("NSWVC: bouncer not showing");
                         }
+                    } else {
+                        mShadeLogger.d("NSWVC: touch not within view");
                     }
                 } else if (mIsTrackingBarGesture) {
                     final boolean sendToStatusBar = mStatusBarViewController.sendTouchToView(ev);
@@ -437,6 +443,9 @@
                     return logDownDispatch(ev, "sending bar gesture to status bar",
                             sendToStatusBar);
                 }
+                if (isDown) {
+                    mShadeLogger.logNoTouchDispatch(mIsTrackingBarGesture, mExpandAnimationRunning);
+                }
                 return logDownDispatch(ev, "no custom touch dispatch of down event", null);
             }
 
@@ -698,12 +707,22 @@
 
     @Override
     public void dump(PrintWriter pw, String[] args) {
+        pw.print("  mExpandingBelowNotch=");
+        pw.println(mExpandingBelowNotch);
         pw.print("  mExpandAnimationRunning=");
         pw.println(mExpandAnimationRunning);
-        pw.print("  mTouchCancelled=");
-        pw.println(mTouchCancelled);
+        pw.print("  mExternalTouchIntercepted=");
+        pw.println(mExternalTouchIntercepted);
+        pw.print("  mIsOcclusionTransitionRunning=");
+        pw.println(mIsOcclusionTransitionRunning);
+        pw.print("  mIsTrackingBarGesture=");
+        pw.println(mIsTrackingBarGesture);
+        pw.print("  mLaunchAnimationTimeout=");
+        pw.println(mLaunchAnimationTimeout);
         pw.print("  mTouchActive=");
         pw.println(mTouchActive);
+        pw.print("  mTouchCancelled=");
+        pw.println(mTouchCancelled);
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt b/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
index fe4832f0..062327d 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
@@ -47,17 +47,19 @@
  * display state, wake-ups are handled by [com.android.systemui.doze.DozeSensors].
  */
 @SysUISingleton
-class PulsingGestureListener @Inject constructor(
-        private val falsingManager: FalsingManager,
-        private val dockManager: DockManager,
-        private val powerInteractor: PowerInteractor,
-        private val ambientDisplayConfiguration: AmbientDisplayConfiguration,
-        private val statusBarStateController: StatusBarStateController,
-        private val shadeLogger: ShadeLogger,
-        private val dozeInteractor: DozeInteractor,
-        userTracker: UserTracker,
-        tunerService: TunerService,
-        dumpManager: DumpManager
+class PulsingGestureListener
+@Inject
+constructor(
+    private val falsingManager: FalsingManager,
+    private val dockManager: DockManager,
+    private val powerInteractor: PowerInteractor,
+    private val ambientDisplayConfiguration: AmbientDisplayConfiguration,
+    private val statusBarStateController: StatusBarStateController,
+    private val shadeLogger: ShadeLogger,
+    private val dozeInteractor: DozeInteractor,
+    userTracker: UserTracker,
+    tunerService: TunerService,
+    dumpManager: DumpManager
 ) : GestureDetector.SimpleOnGestureListener(), Dumpable {
     private var doubleTapEnabled = false
     private var singleTapEnabled = false
@@ -66,21 +68,27 @@
         val tunable = Tunable { key: String?, _: String? ->
             when (key) {
                 Settings.Secure.DOZE_DOUBLE_TAP_GESTURE ->
-                    doubleTapEnabled = ambientDisplayConfiguration.doubleTapGestureEnabled(
-                            userTracker.userId)
+                    doubleTapEnabled =
+                        ambientDisplayConfiguration.doubleTapGestureEnabled(userTracker.userId)
                 Settings.Secure.DOZE_TAP_SCREEN_GESTURE ->
-                    singleTapEnabled = ambientDisplayConfiguration.tapGestureEnabled(
-                            userTracker.userId)
+                    singleTapEnabled =
+                        ambientDisplayConfiguration.tapGestureEnabled(userTracker.userId)
             }
         }
-        tunerService.addTunable(tunable,
-                Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
-                Settings.Secure.DOZE_TAP_SCREEN_GESTURE)
+        tunerService.addTunable(
+            tunable,
+            Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
+            Settings.Secure.DOZE_TAP_SCREEN_GESTURE
+        )
 
         dumpManager.registerDumpable(this)
     }
 
     override fun onSingleTapUp(e: MotionEvent): Boolean {
+        return onSingleTapUp(e.x, e.y)
+    }
+
+    fun onSingleTapUp(x: Float, y: Float): Boolean {
         val isNotDocked = !dockManager.isDocked
         shadeLogger.logSingleTapUp(statusBarStateController.isDozing, singleTapEnabled, isNotDocked)
         if (statusBarStateController.isDozing && singleTapEnabled && isNotDocked) {
@@ -89,11 +97,13 @@
             shadeLogger.logSingleTapUpFalsingState(proximityIsNotNear, isNotAFalseTap)
             if (proximityIsNotNear && isNotAFalseTap) {
                 shadeLogger.d("Single tap handled, requesting centralSurfaces.wakeUpIfDozing")
-                dozeInteractor.setLastTapToWakePosition(Point(e.x.toInt(), e.y.toInt()))
+                dozeInteractor.setLastTapToWakePosition(Point(x.toInt(), y.toInt()))
                 powerInteractor.wakeUpIfDozing("PULSING_SINGLE_TAP", PowerManager.WAKE_REASON_TAP)
             }
+
             return true
         }
+
         shadeLogger.d("onSingleTapUp event ignored")
         return false
     }
@@ -103,10 +113,18 @@
      * motion events for a double tap.
      */
     override fun onDoubleTapEvent(e: MotionEvent): Boolean {
+        if (e.actionMasked != MotionEvent.ACTION_UP) {
+            return false
+        }
+
+        return onDoubleTapEvent()
+    }
+
+    fun onDoubleTapEvent(): Boolean {
         // React to the [MotionEvent.ACTION_UP] event after double tap is detected. Falsing
         // checks MUST be on the ACTION_UP event.
-        if (e.actionMasked == MotionEvent.ACTION_UP &&
-                statusBarStateController.isDozing &&
+        if (
+            statusBarStateController.isDozing &&
                 (doubleTapEnabled || singleTapEnabled) &&
                 !falsingManager.isProximityNear &&
                 !falsingManager.isFalseDoubleTap
@@ -114,6 +132,7 @@
             powerInteractor.wakeUpIfDozing("PULSING_DOUBLE_TAP", PowerManager.WAKE_REASON_TAP)
             return true
         }
+
         return false
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt
index 004db16..5065baa 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.shade
 
 import android.view.MotionEvent
+import androidx.compose.ui.Alignment
 import com.android.systemui.assist.AssistManager
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
@@ -24,6 +25,7 @@
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.shared.model.SceneFamilies
 import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.scene.shared.model.TransitionKeys.OpenBottomShade
 import com.android.systemui.scene.shared.model.TransitionKeys.SlightlyFasterShadeCollapse
 import com.android.systemui.shade.ShadeController.ShadeVisibilityListener
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
@@ -117,7 +119,7 @@
             if (delayed) {
                 scope.launch {
                     delay(125)
-                    animateCollapseShadeInternal()
+                    withContext(mainDispatcher) { animateCollapseShadeInternal() }
                 }
             } else {
                 animateCollapseShadeInternal()
@@ -175,11 +177,16 @@
         sceneInteractor.changeScene(
             SceneFamilies.NotifShade,
             "ShadeController.animateExpandShade",
+            OpenBottomShade.takeIf { shadeInteractor.shadeAlignment == Alignment.BottomEnd }
         )
     }
 
     override fun expandToQs() {
-        sceneInteractor.changeScene(SceneFamilies.QuickSettings, "ShadeController.animateExpandQs")
+        sceneInteractor.changeScene(
+            SceneFamilies.QuickSettings,
+            "ShadeController.animateExpandQs",
+            OpenBottomShade.takeIf { shadeInteractor.shadeAlignment == Alignment.BottomEnd }
+        )
     }
 
     override fun setVisibilityListener(listener: ShadeVisibilityListener) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
index b5b46f1..66a310c 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
@@ -72,79 +72,78 @@
             },
             {
                 "QsTrackingNotStarted: downTime=$str1,initTouchY=$int1,y=$int2,h=$long1," +
-                        "slop=$double1,qsExpanded=$bool1,keyguardShowing=$bool2,qsExpansion=$bool3"
+                    "slop=$double1,qsExpanded=$bool1,keyguardShowing=$bool2,qsExpansion=$bool3"
             }
         )
     }
 
     fun logMotionEvent(event: MotionEvent, message: String) {
         buffer.log(
-                TAG,
-                LogLevel.VERBOSE,
-                {
-                    str1 = message
-                    long1 = event.eventTime
-                    long2 = event.downTime
-                    int1 = event.action
-                    int2 = event.classification
-                },
-                {
-                    "$str1: eventTime=$long1,downTime=$long2,action=$int1,class=$int2"
-                }
+            TAG,
+            LogLevel.VERBOSE,
+            {
+                str1 = message
+                long1 = event.eventTime
+                long2 = event.downTime
+                int1 = event.action
+                int2 = event.classification
+            },
+            { "$str1: eventTime=$long1,downTime=$long2,action=$int1,class=$int2" }
         )
     }
 
     /** Logs motion event dispatch results from NotificationShadeWindowViewController. */
     fun logShadeWindowDispatch(event: MotionEvent, message: String, result: Boolean?) {
         buffer.log(
-                TAG,
-                LogLevel.VERBOSE,
-                {
-                    str1 = message
-                    long1 = event.eventTime
-                    long2 = event.downTime
-                },
-                {
-                    val prefix = when (result) {
+            TAG,
+            LogLevel.VERBOSE,
+            {
+                str1 = message
+                long1 = event.eventTime
+                long2 = event.downTime
+            },
+            {
+                val prefix =
+                    when (result) {
                         true -> "SHADE TOUCH REROUTED"
                         false -> "SHADE TOUCH BLOCKED"
                         null -> "SHADE TOUCH DISPATCHED"
                     }
-                    "$prefix: eventTime=$long1,downTime=$long2, reason=$str1"
-                }
+                "$prefix: eventTime=$long1,downTime=$long2, reason=$str1"
+            }
         )
     }
 
     fun logMotionEventStatusBarState(event: MotionEvent, statusBarState: Int, message: String) {
         buffer.log(
-                TAG,
-                LogLevel.VERBOSE,
-                {
-                    str1 = message
-                    long1 = event.eventTime
-                    long2 = event.downTime
-                    int1 = event.action
-                    int2 = statusBarState
-                    double1 = event.y.toDouble()
-                },
-                {
-                    "$str1\neventTime=$long1,downTime=$long2,y=$double1,action=$int1," +
-                            "statusBarState=${when (int2) {
+            TAG,
+            LogLevel.VERBOSE,
+            {
+                str1 = message
+                long1 = event.eventTime
+                long2 = event.downTime
+                int1 = event.action
+                int2 = statusBarState
+                double1 = event.y.toDouble()
+            },
+            {
+                "$str1\neventTime=$long1,downTime=$long2,y=$double1,action=$int1," +
+                    "statusBarState=${when (int2) {
                                 0 -> "SHADE"
                                 1 -> "KEYGUARD"
                                 2 -> "SHADE_LOCKED"
                                 else -> "UNKNOWN:$int2"
                             }}"
-                }
+            }
         )
     }
 
     fun logExpansionChanged(
-            message: String,
-            fraction: Float,
-            expanded: Boolean,
-            tracking: Boolean,
-            dragDownPxAmount: Float,
+        message: String,
+        fraction: Float,
+        expanded: Boolean,
+        tracking: Boolean,
+        dragDownPxAmount: Float,
     ) {
         buffer.log(
             TAG,
@@ -158,7 +157,8 @@
             },
             {
                 "$str1 fraction=$double1,expanded=$bool1," +
-                    "tracking=$bool2," + "dragDownPxAmount=$dragDownPxAmount"
+                    "tracking=$bool2," +
+                    "dragDownPxAmount=$dragDownPxAmount"
             }
         )
     }
@@ -176,24 +176,17 @@
     }
 
     fun logQsExpandImmediateChanged(newValue: Boolean) {
-        buffer.log(
-            TAG,
-            LogLevel.VERBOSE,
-            {
-                bool1 = newValue
-            },
-            { "qsExpandImmediate=$bool1" }
-        )
+        buffer.log(TAG, LogLevel.VERBOSE, { bool1 = newValue }, { "qsExpandImmediate=$bool1" })
     }
 
     fun logQsExpansionChanged(
-            message: String,
-            qsExpanded: Boolean,
-            qsMinExpansionHeight: Int,
-            qsMaxExpansionHeight: Int,
-            stackScrollerOverscrolling: Boolean,
-            qsAnimatorExpand: Boolean,
-            animatingQs: Boolean
+        message: String,
+        qsExpanded: Boolean,
+        qsMinExpansionHeight: Int,
+        qsMaxExpansionHeight: Int,
+        stackScrollerOverscrolling: Boolean,
+        qsAnimatorExpand: Boolean,
+        animatingQs: Boolean
     ) {
         buffer.log(
             TAG,
@@ -227,8 +220,10 @@
             },
             {
                 "PulsingGestureListener#onSingleTapUp all of this must true for single " +
-               "tap to be detected: isDozing: $bool1, singleTapEnabled: $bool2, isNotDocked: $bool3"
-        })
+                    "tap to be detected: isDozing: $bool1, singleTapEnabled: $bool2," +
+                    " isNotDocked: $bool3"
+            }
+        )
     }
 
     fun logSingleTapUpFalsingState(proximityIsNotNear: Boolean, isNotFalseTap: Boolean) {
@@ -247,9 +242,9 @@
     }
 
     fun logNotInterceptingTouchInstantExpanding(
-            instantExpanding: Boolean,
-            notificationsDragEnabled: Boolean,
-            touchDisabled: Boolean
+        instantExpanding: Boolean,
+        notificationsDragEnabled: Boolean,
+        touchDisabled: Boolean
     ) {
         buffer.log(
             TAG,
@@ -276,12 +271,12 @@
     }
 
     fun logFlingExpands(
-            vel: Float,
-            vectorVel: Float,
-            interactionType: Int,
-            minVelocityPxPerSecond: Float,
-            expansionOverHalf: Boolean,
-            allowExpandForSmallExpansion: Boolean
+        vel: Float,
+        vectorVel: Float,
+        interactionType: Int,
+        minVelocityPxPerSecond: Float,
+        expansionOverHalf: Boolean,
+        allowExpandForSmallExpansion: Boolean
     ) {
         buffer.log(
             TAG,
@@ -294,9 +289,11 @@
                 bool1 = expansionOverHalf
                 bool2 = allowExpandForSmallExpansion
             },
-            { "NPVC flingExpands called with vel: $long1, vectorVel: $long2, " +
+            {
+                "NPVC flingExpands called with vel: $long1, vectorVel: $long2, " +
                     "interactionType: $int1, minVelocityPxPerSecond: $double1 " +
-                    "expansionOverHalf: $bool1, allowExpandForSmallExpansion: $bool2" }
+                    "expansionOverHalf: $bool1, allowExpandForSmallExpansion: $bool2"
+            }
         )
     }
 
@@ -338,9 +335,7 @@
         buffer.log(
             TAG,
             LogLevel.VERBOSE,
-            {
-                str1 = panelState.panelStateToString()
-            },
+            { str1 = panelState.panelStateToString() },
             { "New panel State: $str1" }
         )
     }
@@ -357,12 +352,13 @@
         )
     }
 
-    private fun flingTypeToString(flingType: Int) = when (flingType) {
-        FLING_EXPAND -> "FLING_EXPAND"
-        FLING_COLLAPSE -> "FLING_COLLAPSE"
-        FLING_HIDE -> "FLING_HIDE"
-        else -> "UNKNOWN"
-    }
+    private fun flingTypeToString(flingType: Int) =
+        when (flingType) {
+            FLING_EXPAND -> "FLING_EXPAND"
+            FLING_COLLAPSE -> "FLING_COLLAPSE"
+            FLING_HIDE -> "FLING_HIDE"
+            else -> "UNKNOWN"
+        }
 
     fun logSplitShadeChanged(splitShadeEnabled: Boolean) {
         buffer.log(
@@ -392,8 +388,26 @@
             },
             {
                 "CentralSurfaces updateNotificationPanelTouchState set disabled to: $bool1\n" +
-                        "isGoingToSleep: $bool2, !shouldControlScreenOff: $bool3," +
-                        "!mDeviceInteractive: $bool4, !isPulsing: $str1"
+                    "isGoingToSleep: $bool2, !shouldControlScreenOff: $bool3," +
+                    "!mDeviceInteractive: $bool4, !isPulsing: $str1"
+            }
+        )
+    }
+
+    fun logNoTouchDispatch(
+        isTrackingBarGesture: Boolean,
+        isExpandAnimationRunning: Boolean,
+    ) {
+        buffer.log(
+            TAG,
+            LogLevel.VERBOSE,
+            {
+                bool1 = isTrackingBarGesture
+                bool2 = isExpandAnimationRunning
+            },
+            {
+                "NSWVC: touch not dispatched: isTrackingBarGesture: $bool1, " +
+                    "isExpandAnimationRunning: $bool2"
             }
         )
     }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
index 7e1a310..4d43ad5 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/data/repository/ShadeRepository.kt
@@ -15,7 +15,10 @@
  */
 package com.android.systemui.shade.data.repository
 
+import android.content.Context
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.res.R
 import com.android.systemui.shade.shared.flag.DualShade
 import com.android.systemui.shade.shared.model.ShadeMode
 import javax.inject.Inject
@@ -104,6 +107,9 @@
 
     val shadeMode: StateFlow<ShadeMode>
 
+    /** Whether dual shade should be aligned to the bottom (true) or to the top (false). */
+    val isDualShadeAlignedToBottom: Boolean
+
     /** True when QS is taking up the entire screen, i.e. fully expanded on a non-unfolded phone. */
     @Deprecated("Use ShadeInteractor instead") val legacyQsFullscreen: StateFlow<Boolean>
 
@@ -174,7 +180,8 @@
 
 /** Business logic for shade interactions */
 @SysUISingleton
-class ShadeRepositoryImpl @Inject constructor() : ShadeRepository {
+class ShadeRepositoryImpl @Inject constructor(@Application applicationContext: Context) :
+    ShadeRepository {
     private val _qsExpansion = MutableStateFlow(0f)
     override val qsExpansion: StateFlow<Float> = _qsExpansion.asStateFlow()
 
@@ -223,6 +230,9 @@
     val _shadeMode = MutableStateFlow(if (DualShade.isEnabled) ShadeMode.Dual else ShadeMode.Single)
     override val shadeMode: StateFlow<ShadeMode> = _shadeMode.asStateFlow()
 
+    override val isDualShadeAlignedToBottom =
+        applicationContext.resources.getBoolean(R.bool.config_dualShadeAlignedToBottom)
+
     override fun setShadeMode(shadeMode: ShadeMode) {
         _shadeMode.value = shadeMode
     }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
index 18407cc..ef0a842 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.shade.domain.interactor
 
+import com.android.systemui.shade.shared.model.ShadeAlignment
 import com.android.systemui.shade.shared.model.ShadeMode
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
@@ -53,6 +54,9 @@
 
     /** Emits true if the shade can be expanded from QQS to QS and false otherwise. */
     val isExpandToQsEnabled: Flow<Boolean>
+
+    /** How to align the shade content. */
+    val shadeAlignment: ShadeAlignment
 }
 
 /** ShadeInteractor methods with implementations that differ between non-empty impls. */
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt
index bb4baa3..6226d07 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.shade.domain.interactor
 
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.shade.shared.model.ShadeAlignment
 import com.android.systemui.shade.shared.model.ShadeMode
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
@@ -46,4 +47,5 @@
     override val isShadeTouchable: Flow<Boolean> = inactiveFlowBoolean
     override val isExpandToQsEnabled: Flow<Boolean> = inactiveFlowBoolean
     override val shadeMode: StateFlow<ShadeMode> = MutableStateFlow(ShadeMode.Single)
+    override val shadeAlignment: ShadeAlignment = ShadeAlignment.Top
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImpl.kt
index 4014512..55f019b 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorImpl.kt
@@ -24,6 +24,8 @@
 import com.android.systemui.keyguard.shared.model.Edge
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.shade.data.repository.ShadeRepository
+import com.android.systemui.shade.shared.model.ShadeAlignment
 import com.android.systemui.statusbar.disableflags.data.repository.DisableFlagsRepository
 import com.android.systemui.statusbar.phone.DozeParameters
 import com.android.systemui.statusbar.policy.data.repository.UserSetupRepository
@@ -51,6 +53,7 @@
     keyguardRepository: KeyguardRepository,
     keyguardTransitionInteractor: KeyguardTransitionInteractor,
     powerInteractor: PowerInteractor,
+    shadeRepository: ShadeRepository,
     userSetupRepository: UserSetupRepository,
     userSwitcherInteractor: UserSwitcherInteractor,
     private val baseShadeInteractor: BaseShadeInteractor,
@@ -99,6 +102,13 @@
             }
         }
 
+    override val shadeAlignment: ShadeAlignment =
+        if (shadeRepository.isDualShadeAlignedToBottom) {
+            ShadeAlignment.Bottom
+        } else {
+            ShadeAlignment.Top
+        }
+
     override val isExpandToQsEnabled: Flow<Boolean> =
         combine(
             disableFlagsRepository.disableFlags,
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeLockscreenInteractorImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeLockscreenInteractorImpl.kt
index d5953ca..e525b86 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeLockscreenInteractorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeLockscreenInteractorImpl.kt
@@ -19,6 +19,7 @@
 import com.android.keyguard.LockIconViewController
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.shared.model.SceneFamilies
 import com.android.systemui.scene.shared.model.Scenes
@@ -96,7 +97,7 @@
     }
 
     override fun showAodUi() {
-        sceneInteractor.changeScene(Scenes.Lockscreen, "showAodUi")
+        sceneInteractor.changeScene(Scenes.Lockscreen, "showAodUi", sceneState = KeyguardState.AOD)
         // TODO(b/330311871) implement transition to AOD
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt
index 3f4bcba..354d379 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/startable/ShadeStartable.kt
@@ -32,6 +32,8 @@
 import com.android.systemui.shade.shared.flag.DualShade
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.shade.transition.ScrimShadeTransitionController
+import com.android.systemui.statusbar.PulseExpansionHandler
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
 import com.android.systemui.statusbar.policy.SplitShadeStateController
 import javax.inject.Inject
 import javax.inject.Provider
@@ -56,6 +58,8 @@
     private val sceneInteractorProvider: Provider<SceneInteractor>,
     private val panelExpansionInteractorProvider: Provider<PanelExpansionInteractor>,
     private val shadeExpansionStateManager: ShadeExpansionStateManager,
+    private val pulseExpansionHandler: PulseExpansionHandler,
+    private val nsslc: NotificationStackScrollLayoutController,
 ) : CoreStartable {
 
     override fun start() {
@@ -63,6 +67,7 @@
         hydrateShadeExpansionStateManager()
         logTouchesTo(touchLog)
         scrimShadeTransitionController.init()
+        pulseExpansionHandler.setUp(nsslc)
     }
 
     private fun hydrateShadeExpansionStateManager() {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/shared/model/ShadeAlignment.kt b/packages/SystemUI/src/com/android/systemui/shade/shared/model/ShadeAlignment.kt
new file mode 100644
index 0000000..06905379
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/shade/shared/model/ShadeAlignment.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.shared.model
+
+/** Enumerates all supported alignments of the shade. */
+sealed interface ShadeAlignment {
+
+    /** Aligns the shade to the top. */
+    data object Top : ShadeAlignment
+
+    /** Aligns the shade to the bottom. */
+    data object Bottom : ShadeAlignment
+}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/OverlayShadeViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/OverlayShadeViewModel.kt
index 0314091..6551854 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/OverlayShadeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/OverlayShadeViewModel.kt
@@ -22,6 +22,7 @@
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.shared.model.SceneFamilies
 import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.SharingStarted
@@ -38,6 +39,7 @@
 constructor(
     @Application applicationScope: CoroutineScope,
     private val sceneInteractor: SceneInteractor,
+    shadeInteractor: ShadeInteractor
 ) {
     /** The scene to show in the background when the overlay shade is open. */
     val backgroundScene: StateFlow<SceneKey> =
@@ -49,6 +51,9 @@
                 initialValue = Scenes.Lockscreen,
             )
 
+    /** Dictates the alignment of the overlay shade panel on the screen. */
+    val panelAlignment = shadeInteractor.shadeAlignment
+
     /** Notifies that the user has clicked the semi-transparent background scrim. */
     fun onScrimClicked() {
         sceneInteractor.changeScene(
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
index b0100b9..2b2aac64 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
@@ -37,7 +37,6 @@
 import com.android.systemui.settings.brightness.ui.viewModel.BrightnessMirrorViewModel
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
-import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
 import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor
 import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
 import java.util.concurrent.atomic.AtomicBoolean
@@ -60,7 +59,6 @@
     @Application private val applicationScope: CoroutineScope,
     val qsSceneAdapter: QSSceneAdapter,
     val shadeHeaderViewModel: ShadeHeaderViewModel,
-    val notifications: NotificationsPlaceholderViewModel,
     val brightnessMirrorViewModel: BrightnessMirrorViewModel,
     val mediaCarouselInteractor: MediaCarouselInteractor,
     shadeInteractor: ShadeInteractor,
diff --git a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
index 6d951bf..abffd3c 100644
--- a/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
@@ -18,8 +18,10 @@
 import android.app.ActivityOptions
 import android.app.PendingIntent
 import android.content.Intent
+import android.os.Handler
 import android.view.View
 import android.view.ViewGroup
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.BcSmartspaceDataPlugin
 import com.android.systemui.plugins.BcSmartspaceDataPlugin.UI_SURFACE_DREAM
@@ -51,19 +53,20 @@
 
         @Provides
         fun providesSmartspaceView(
-            activityStarter: ActivityStarter,
-            falsingManager: FalsingManager,
-            parent: ViewGroup,
-            @Named(PLUGIN) plugin: BcSmartspaceDataPlugin,
-            viewWithCustomLayout: View?,
-            onAttachListener: View.OnAttachStateChangeListener
-        ):
-                BcSmartspaceDataPlugin.SmartspaceView {
+                activityStarter: ActivityStarter,
+                falsingManager: FalsingManager,
+                parent: ViewGroup,
+                @Named(PLUGIN) plugin: BcSmartspaceDataPlugin,
+                viewWithCustomLayout: View?,
+                onAttachListener: View.OnAttachStateChangeListener,
+                @Background bgHandler: Handler,
+        ): BcSmartspaceDataPlugin.SmartspaceView {
             val ssView = viewWithCustomLayout
                     as? BcSmartspaceDataPlugin.SmartspaceView
                     ?: plugin.getView(parent)
             // Currently, this is only used to provide SmartspaceView on Dream surface.
             ssView.setUiSurface(UI_SURFACE_DREAM)
+            ssView.setBgHandler(bgHandler)
             ssView.registerDataProvider(plugin)
 
             ssView.setIntentStarter(object : BcSmartspaceDataPlugin.IntentStarter {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 95cabfb..c1eb8bc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -386,6 +386,11 @@
         mStatusBarStateListener.onDozingChanged(mStatusBarStateController.isDozing());
     }
 
+    @Nullable
+    public ViewGroup getIndicationArea() {
+        return mIndicationArea;
+    }
+
     public void setIndicationArea(ViewGroup indicationArea) {
         mIndicationArea = indicationArea;
         mTopIndicationView = indicationArea.findViewById(R.id.keyguard_indication_text);
@@ -1271,7 +1276,7 @@
             mPowerPluggedInWired = status.isPluggedInWired() && isChargingOrFull;
             mPowerPluggedInWireless = status.isPluggedInWireless() && isChargingOrFull;
             mPowerPluggedInDock = status.isPluggedInDock() && isChargingOrFull;
-            mPowerPluggedIn = status.isPluggedIn() && isChargingOrFull;
+            mPowerPluggedIn = isPowerPluggedIn(status, isChargingOrFull);
             mPowerCharged = status.isCharged();
             mChargingWattage = status.maxChargingWattage;
             mChargingSpeed = status.getChargingSpeed(mContext);
@@ -1557,6 +1562,11 @@
         return status.isBatteryDefender();
     }
 
+    /** Return true if the device has power plugged in. */
+    protected boolean isPowerPluggedIn(BatteryStatus status, boolean isChargingOrFull) {
+        return status.isPluggedIn() && isChargingOrFull;
+    }
+
     private boolean isCurrentUser(int userId) {
         return getCurrentUser() == userId;
     }
@@ -1665,11 +1675,6 @@
     private final StatusBarStateController.StateListener mStatusBarStateListener =
             new StatusBarStateController.StateListener() {
         @Override
-        public void onStateChanged(int newState) {
-            setVisible(newState == StatusBarState.KEYGUARD);
-        }
-
-        @Override
         public void onDozingChanged(boolean dozing) {
             if (mDozing == dozing) {
                 return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index 04a413a..240953d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -291,8 +291,9 @@
     }
 
     private void updateMediaMetaData(MediaListener callback) {
-        callback.onPrimaryMetadataOrStateChanged(mMediaMetadata,
-                getMediaControllerPlaybackState(mMediaController));
+        int playbackState = getMediaControllerPlaybackState(mMediaController);
+        mHandler.post(
+                () -> callback.onPrimaryMetadataOrStateChanged(mMediaMetadata, playbackState));
     }
 
     public void removeCallback(MediaListener callback) {
@@ -437,9 +438,11 @@
 
     private void updateMediaMetaData(List<MediaListener> callbacks) {
         @PlaybackState.State int state = getMediaControllerPlaybackState(mMediaController);
-        for (int i = 0; i < callbacks.size(); i++) {
-            callbacks.get(i).onPrimaryMetadataOrStateChanged(mMediaMetadata, state);
-        }
+        mHandler.post(() -> {
+            for (int i = 0; i < callbacks.size(); i++) {
+                callbacks.get(i).onPrimaryMetadataOrStateChanged(mMediaMetadata, state);
+            }
+        });
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 307e702..9b1e782 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -62,6 +62,7 @@
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.phone.ExpandHeadsUpOnInlineReply;
 import com.android.systemui.statusbar.policy.RemoteInputUriController;
 import com.android.systemui.statusbar.policy.RemoteInputView;
 import com.android.systemui.util.DumpUtilsKt;
@@ -399,7 +400,7 @@
     public boolean activateRemoteInput(View view, RemoteInput[] inputs, RemoteInput input,
             PendingIntent pendingIntent, @Nullable EditedSuggestionInfo editedSuggestionInfo) {
         return activateRemoteInput(view, inputs, input, pendingIntent, editedSuggestionInfo,
-                null /* userMessageContent */, null /* authBypassCheck */);
+                    null /* userMessageContent */, null /* authBypassCheck */);
     }
 
     /**
@@ -420,6 +421,12 @@
             PendingIntent pendingIntent, @Nullable EditedSuggestionInfo editedSuggestionInfo,
             @Nullable String userMessageContent,
             @Nullable AuthBypassPredicate authBypassCheck) {
+        if (ExpandHeadsUpOnInlineReply.isEnabled()) {
+            return activateRemoteInputOnExpanded(view, inputs, input, pendingIntent,
+                    editedSuggestionInfo, userMessageContent,
+                    authBypassCheck);
+        }
+
         ViewParent p = view.getParent();
         RemoteInputView riv = null;
         ExpandableNotificationRow row = null;
@@ -491,6 +498,86 @@
         return true;
     }
 
+    /**
+     * Activates a given {@link RemoteInput} on the expanded notification.
+     * If the given notification is not expanded, this method will expand the notification
+     * first and after that activate remote input on the expanded.
+     * @param view The view of the action button or suggestion chip that was tapped.
+     * @param inputs The remote inputs that need to be sent to the app.
+     * @param input The remote input that needs to be activated.
+     * @param pendingIntent The pending intent to be sent to the app.
+     * @param editedSuggestionInfo The smart reply that should be inserted in the remote input, or
+     *         {@code null} if the user is not editing a smart reply.
+     * @param userMessageContent User-entered text with which to initialize the remote input view.
+     * @param authBypassCheck Optional auth bypass check associated with this remote input
+     *         activation. If {@code null}, we never bypass.
+     * @return Whether the {@link RemoteInput} was activated.
+     */
+    public boolean activateRemoteInputOnExpanded(View view, RemoteInput[] inputs, RemoteInput input,
+            PendingIntent pendingIntent, @Nullable EditedSuggestionInfo editedSuggestionInfo,
+            @Nullable String userMessageContent,
+            @Nullable AuthBypassPredicate authBypassCheck) {
+        ViewParent p = view.getParent();
+        RemoteInputView riv = null;
+        ExpandableNotificationRow row = null;
+        while (p != null) {
+            if (p instanceof View) {
+                View pv = (View) p;
+                if (pv.getId() == com.android.internal.R.id.status_bar_latest_event_content) {
+                    row = (ExpandableNotificationRow) pv.getTag(R.id.row_tag_for_content_view);
+                    break;
+                }
+            }
+            p = p.getParent();
+        }
+
+        if (row == null) {
+            return false;
+        }
+
+        final boolean deferBouncer = authBypassCheck != null;
+        if (!deferBouncer && showBouncerForRemoteInput(view, pendingIntent, row)) {
+            return true;
+        }
+
+        if (!row.getPrivateLayout().getExpandedChild().isShown()) {
+            // The expanded layout is selected, but it's not shown yet, let's wait on it to
+            // show before we do the animation.
+            mCallback.onMakeExpandedVisibleForRemoteInput(row, view, deferBouncer, () -> {
+                activateRemoteInputOnExpanded(view, inputs, input, pendingIntent,
+                        editedSuggestionInfo, userMessageContent, authBypassCheck);
+            });
+            return true;
+        }
+
+        riv = findRemoteInputView(row.getPrivateLayout().getExpandedChild());
+        if (riv == null) {
+            return false;
+        }
+
+        if (!riv.isAttachedToWindow()) {
+            // if we still didn't find a view that is attached, let's abort.
+            return false;
+        }
+
+        riv.getController().setPendingIntent(pendingIntent);
+        riv.getController().setRemoteInput(input);
+        riv.getController().setRemoteInputs(inputs);
+        riv.getController().setEditedSuggestionInfo(editedSuggestionInfo);
+        riv.focusAnimated();
+        if (userMessageContent != null) {
+            riv.setEditTextContent(userMessageContent);
+        }
+        if (deferBouncer) {
+            final ExpandableNotificationRow finalRow = row;
+            riv.getController().setBouncerChecker(() ->
+                    !authBypassCheck.canSendRemoteInputWithoutBouncer()
+                            && showBouncerForRemoteInput(view, pendingIntent, finalRow));
+        }
+
+        return true;
+    }
+
     private boolean showBouncerForRemoteInput(View view, PendingIntent pendingIntent,
             ExpandableNotificationRow row) {
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 9a82ecf..28e3a83 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -40,6 +40,7 @@
 import com.android.internal.policy.SystemBarUtils;
 import com.android.systemui.animation.ShadeInterpolation;
 import com.android.systemui.res.R;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
 import com.android.systemui.statusbar.notification.ColorUpdateLogger;
 import com.android.systemui.statusbar.notification.NotificationUtils;
@@ -261,14 +262,17 @@
             viewState.hasItemsInStableShelf = false;
         }
 
-        final float stackEnd = ambientState.getStackY() + ambientState.getStackHeight();
+        final float stackBottom = SceneContainerFlag.isEnabled()
+                ? ambientState.getStackTop() + ambientState.getStackHeight()
+                : ambientState.getStackY() + ambientState.getStackHeight();
+
         if (viewState.hidden) {
             // if the shelf is hidden, position it at the end of the stack (plus the clip
             // padding), such that when it appears animated, it will smoothly move in from the
             // bottom, without jump cutting any notifications
-            viewState.setYTranslation(stackEnd + mPaddingBetweenElements);
+            viewState.setYTranslation(stackBottom + mPaddingBetweenElements);
         } else {
-            viewState.setYTranslation(stackEnd - viewState.height);
+            viewState.setYTranslation(stackBottom - viewState.height);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index d0702fc..bbf0ae1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -69,7 +69,6 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.text.NumberFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 
@@ -148,11 +147,6 @@
     @VisibleForTesting float mScaleToFitNewIconSize = 1;
     private StatusBarIcon mIcon;
     @ViewDebug.ExportedProperty private String mSlot;
-    private Drawable mNumberBackground;
-    private Paint mNumberPain;
-    private int mNumberX;
-    private int mNumberY;
-    private String mNumberText;
     private StatusBarNotification mNotification;
     private final boolean mBlocked;
     private Configuration mConfiguration;
@@ -201,10 +195,6 @@
         mDozer = new NotificationDozeHelper();
         mBlocked = blocked;
         mSlot = slot;
-        mNumberPain = new Paint();
-        mNumberPain.setTextAlign(Paint.Align.CENTER);
-        mNumberPain.setColor(context.getColor(R.drawable.notification_number_text_color));
-        mNumberPain.setAntiAlias(true);
         setNotification(sbn);
         setScaleType(ScaleType.CENTER);
         mConfiguration = new Configuration(context.getResources().getConfiguration());
@@ -410,8 +400,6 @@
                 && mIcon.iconLevel == icon.iconLevel;
         final boolean visibilityEquals = mIcon != null
                 && mIcon.visible == icon.visible;
-        final boolean numberEquals = mIcon != null
-                && mIcon.number == icon.number;
         mIcon = icon.clone();
         setContentDescription(icon.contentDescription);
         if (!iconEquals) {
@@ -425,20 +413,6 @@
             setImageLevel(icon.iconLevel);
         }
 
-        if (!numberEquals) {
-            if (icon.number > 0 && getContext().getResources().getBoolean(
-                        R.bool.config_statusBarShowNumber)) {
-                if (mNumberBackground == null) {
-                    mNumberBackground = getContext().getResources().getDrawable(
-                            R.drawable.ic_notification_overlay);
-                }
-                placeNumber();
-            } else {
-                mNumberBackground = null;
-                mNumberText = null;
-            }
-            invalidate();
-        }
         if (!visibilityEquals) {
             setVisibility(icon.visible && !mBlocked ? VISIBLE : GONE);
         }
@@ -568,14 +542,6 @@
     }
 
     @Override
-    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        super.onSizeChanged(w, h, oldw, oldh);
-        if (mNumberBackground != null) {
-            placeNumber();
-        }
-    }
-
-    @Override
     public void onRtlPropertiesChanged(int layoutDirection) {
         super.onRtlPropertiesChanged(layoutDirection);
         updateDrawable();
@@ -609,10 +575,6 @@
             canvas.restore();
         }
 
-        if (mNumberBackground != null) {
-            mNumberBackground.draw(canvas);
-            canvas.drawText(mNumberText, mNumberX, mNumberY, mNumberPain);
-        }
         if (mDotAppearAmount != 0.0f) {
             float radius;
             float alpha = Color.alpha(mDecorColor) / 255.f;
@@ -640,39 +602,6 @@
         Log.d("View", debugIndent(depth) + "icon=" + mIcon);
     }
 
-    void placeNumber() {
-        final String str;
-        final int tooBig = getContext().getResources().getInteger(
-                android.R.integer.status_bar_notification_info_maxnum);
-        if (mIcon.number > tooBig) {
-            str = getContext().getResources().getString(
-                        android.R.string.status_bar_notification_info_overflow);
-        } else {
-            NumberFormat f = NumberFormat.getIntegerInstance();
-            str = f.format(mIcon.number);
-        }
-        mNumberText = str;
-
-        final int w = getWidth();
-        final int h = getHeight();
-        final Rect r = new Rect();
-        mNumberPain.getTextBounds(str, 0, str.length(), r);
-        final int tw = r.right - r.left;
-        final int th = r.bottom - r.top;
-        mNumberBackground.getPadding(r);
-        int dw = r.left + tw + r.right;
-        if (dw < mNumberBackground.getMinimumWidth()) {
-            dw = mNumberBackground.getMinimumWidth();
-        }
-        mNumberX = w-r.right-((dw-r.right-r.left)/2);
-        int dh = r.top + th + r.bottom;
-        if (dh < mNumberBackground.getMinimumWidth()) {
-            dh = mNumberBackground.getMinimumWidth();
-        }
-        mNumberY = h-r.bottom-((dh-r.top-th-r.bottom)/2);
-        mNumberBackground.setBounds(w-dw, h-dh, w, h);
-    }
-
     @Override
     public String toString() {
         return "StatusBarIconView("
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index 79218ae..e505ef7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -53,6 +53,7 @@
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.res.R;
+import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor;
 import com.android.systemui.scene.domain.interactor.SceneInteractor;
 import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.scene.shared.model.Scenes;
@@ -114,6 +115,7 @@
     private final Lazy<ShadeInteractor> mShadeInteractorLazy;
     private final Lazy<DeviceUnlockedInteractor> mDeviceUnlockedInteractorLazy;
     private final Lazy<SceneInteractor> mSceneInteractorLazy;
+    private final Lazy<SceneContainerOcclusionInteractor> mSceneContainerOcclusionInteractorLazy;
     private final Lazy<KeyguardClockInteractor> mKeyguardClockInteractorLazy;
     private int mState;
     private int mLastState;
@@ -182,6 +184,7 @@
             Lazy<ShadeInteractor> shadeInteractorLazy,
             Lazy<DeviceUnlockedInteractor> deviceUnlockedInteractorLazy,
             Lazy<SceneInteractor> sceneInteractorLazy,
+            Lazy<SceneContainerOcclusionInteractor> sceneContainerOcclusionInteractor,
             Lazy<KeyguardClockInteractor> keyguardClockInteractorLazy) {
         mUiEventLogger = uiEventLogger;
         mInteractionJankMonitorLazy = interactionJankMonitorLazy;
@@ -190,6 +193,7 @@
         mShadeInteractorLazy = shadeInteractorLazy;
         mDeviceUnlockedInteractorLazy = deviceUnlockedInteractorLazy;
         mSceneInteractorLazy = sceneInteractorLazy;
+        mSceneContainerOcclusionInteractorLazy = sceneContainerOcclusionInteractor;
         mKeyguardClockInteractorLazy = keyguardClockInteractorLazy;
         for (int i = 0; i < HISTORY_SIZE; i++) {
             mHistoricalRecords[i] = new HistoricalState();
@@ -199,7 +203,9 @@
     @Override
     public void start() {
         mJavaAdapter.alwaysCollectFlow(
-                mKeyguardTransitionInteractorLazy.get().isFinishedInState(GONE),
+                mKeyguardTransitionInteractorLazy.get().isFinishedIn(
+                        /* scene */ Scenes.Gone,
+                        /* stateWithoutSceneContainer */ GONE),
                 (Boolean isFinishedInState) -> {
                     if (isFinishedInState) {
                         setLeaveOpenOnKeyguardHide(false);
@@ -214,6 +220,7 @@
                     combineFlows(
                         mDeviceUnlockedInteractorLazy.get().getDeviceUnlockStatus(),
                         mSceneInteractorLazy.get().getCurrentScene(),
+                        mSceneContainerOcclusionInteractorLazy.get().getInvisibleDueToOcclusion(),
                         this::calculateStateFromSceneFramework),
                     this::onStatusBarStateChanged);
         }
@@ -664,10 +671,11 @@
 
     private int calculateStateFromSceneFramework(
             DeviceUnlockStatus deviceUnlockStatus,
-            SceneKey currentScene) {
+            SceneKey currentScene,
+            boolean isOccluded) {
         SceneContainerFlag.isUnexpectedlyInLegacyMode();
 
-        if (deviceUnlockStatus.isUnlocked()) {
+        if (deviceUnlockStatus.isUnlocked() || isOccluded) {
             return StatusBarState.SHADE;
         } else {
             return Preconditions.checkNotNull(sStatusBarStateByLockedSceneKey.get(currentScene));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipsLog.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipsLog.kt
new file mode 100644
index 0000000..ecb6286
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipsLog.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.chips
+
+import javax.inject.Qualifier
+
+/** Logs for events related to the status bar chips. */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class StatusBarChipsLog
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipsModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipsModule.kt
new file mode 100644
index 0000000..173ff37
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/StatusBarChipsModule.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.chips
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogBufferFactory
+import dagger.Module
+import dagger.Provides
+
+@Module
+abstract class StatusBarChipsModule {
+    companion object {
+        @Provides
+        @SysUISingleton
+        @StatusBarChipsLog
+        fun provideChipsLogBuffer(factory: LogBufferFactory): LogBuffer {
+            return factory.create("StatusBarChips", 200)
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt
index 7e9acaf..eaefc11 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt
@@ -17,15 +17,36 @@
 package com.android.systemui.statusbar.chips.call.domain.interactor
 
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.statusbar.chips.StatusBarChipsLog
 import com.android.systemui.statusbar.phone.ongoingcall.data.repository.OngoingCallRepository
+import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.flow.stateIn
 
 /** Interactor for the ongoing phone call chip shown in the status bar. */
 @SysUISingleton
 class CallChipInteractor
 @Inject
 constructor(
+    @Application private val scope: CoroutineScope,
     repository: OngoingCallRepository,
+    @StatusBarChipsLog private val logger: LogBuffer,
 ) {
-    val ongoingCallState = repository.ongoingCallState
+    val ongoingCallState: StateFlow<OngoingCallModel> =
+        repository.ongoingCallState
+            .onEach {
+                logger.log(TAG, LogLevel.INFO, { str1 = it::class.simpleName }, { "State: $str1" })
+            }
+            .stateIn(scope, SharingStarted.Lazily, OngoingCallModel.NoCall)
+
+    companion object {
+        private const val TAG = "OngoingCall"
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
index ad09aa3..ed1756a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
@@ -16,14 +16,17 @@
 
 package com.android.systemui.statusbar.chips.call.ui.viewmodel
 
+import android.view.View
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.systemui.animation.ActivityTransitionAnimator
+import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.chips.call.domain.interactor.CallChipInteractor
+import com.android.systemui.statusbar.chips.ui.model.ColorsModel
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
 import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
 import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel
@@ -52,40 +55,58 @@
                 when (state) {
                     is OngoingCallModel.NoCall -> OngoingActivityChipModel.Hidden
                     is OngoingCallModel.InCall -> {
-                        // This mimics OngoingCallController#updateChip.
-                        // TODO(b/332662551): Handle `state.startTimeMs = 0` correctly (see
-                        // b/192379214 and
-                        // OngoingCallController.CallNotificationInfo.hasValidStartTime).
-                        val startTimeInElapsedRealtime =
-                            state.startTimeMs - systemClock.currentTimeMillis() +
-                                systemClock.elapsedRealtime()
-                        OngoingActivityChipModel.Shown(
-                            icon =
-                                Icon.Resource(
-                                    com.android.internal.R.drawable.ic_phone,
-                                    contentDescription = null,
-                                ),
-                            startTimeMs = startTimeInElapsedRealtime,
-                        ) {
-                            if (state.intent != null) {
-                                val backgroundView =
-                                    it.requireViewById<ChipBackgroundContainer>(
-                                        R.id.ongoing_activity_chip_background
-                                    )
-                                // TODO(b/332662551): Log the click event.
-                                // This mimics OngoingCallController#updateChipClickListener.
-                                activityStarter.postStartActivityDismissingKeyguard(
-                                    state.intent,
-                                    ActivityTransitionAnimator.Controller.fromView(
-                                        backgroundView,
-                                        InteractionJankMonitor
-                                            .CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP,
-                                    )
-                                )
-                            }
+                        // This block mimics OngoingCallController#updateChip.
+                        if (state.startTimeMs <= 0L) {
+                            // If the start time is invalid, don't show a timer and show just an
+                            // icon. See b/192379214.
+                            OngoingActivityChipModel.Shown.IconOnly(
+                                icon = phoneIcon,
+                                colors = ColorsModel.Themed,
+                                getOnClickListener(state),
+                            )
+                        } else {
+                            val startTimeInElapsedRealtime =
+                                state.startTimeMs - systemClock.currentTimeMillis() +
+                                    systemClock.elapsedRealtime()
+                            OngoingActivityChipModel.Shown.Timer(
+                                icon = phoneIcon,
+                                colors = ColorsModel.Themed,
+                                startTimeMs = startTimeInElapsedRealtime,
+                                getOnClickListener(state),
+                            )
                         }
                     }
                 }
             }
             .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingActivityChipModel.Hidden)
+
+    private fun getOnClickListener(state: OngoingCallModel.InCall): View.OnClickListener? {
+        if (state.intent == null) {
+            return null
+        }
+
+        return View.OnClickListener { view ->
+            val backgroundView =
+                view.requireViewById<ChipBackgroundContainer>(R.id.ongoing_activity_chip_background)
+            // TODO(b/332662551): Log the click event.
+            // This mimics OngoingCallController#updateChipClickListener.
+            activityStarter.postStartActivityDismissingKeyguard(
+                state.intent,
+                ActivityTransitionAnimator.Controller.fromView(
+                    backgroundView,
+                    InteractionJankMonitor.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP,
+                )
+            )
+        }
+    }
+
+    companion object {
+        private val phoneIcon =
+            Icon.Resource(
+                com.android.internal.R.drawable.ic_phone,
+                ContentDescription.Resource(
+                    R.string.ongoing_phone_call_content_description,
+                ),
+            )
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractor.kt
new file mode 100644
index 0000000..6917f46
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractor.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.chips.casttootherdevice.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.mediarouter.data.repository.MediaRouterRepository
+import com.android.systemui.statusbar.chips.casttootherdevice.domain.model.MediaRouterCastModel
+import com.android.systemui.statusbar.policy.CastDevice
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+
+/**
+ * Interactor for MediaRouter events, used to show the cast-audio-to-other-device chip in the status
+ * bar.
+ */
+@SysUISingleton
+class MediaRouterChipInteractor
+@Inject
+constructor(
+    @Application private val scope: CoroutineScope,
+    private val mediaRouterRepository: MediaRouterRepository,
+) {
+    private val activeCastDevice: StateFlow<CastDevice?> =
+        mediaRouterRepository.castDevices
+            .map { allDevices -> allDevices.firstOrNull { it.isCasting } }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), null)
+
+    /** The current casting state, according to MediaRouter APIs. */
+    val mediaRouterCastingState: StateFlow<MediaRouterCastModel> =
+        activeCastDevice
+            .map {
+                if (it != null) {
+                    MediaRouterCastModel.Casting(deviceName = it.name)
+                } else {
+                    MediaRouterCastModel.DoingNothing
+                }
+            }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), MediaRouterCastModel.DoingNothing)
+
+    /** Stops the currently active MediaRouter cast. */
+    fun stopCasting() {
+        activeCastDevice.value?.let { mediaRouterRepository.stopCasting(it) }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/model/MediaRouterCastModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/model/MediaRouterCastModel.kt
new file mode 100644
index 0000000..1f84d7c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/model/MediaRouterCastModel.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.chips.casttootherdevice.domain.model
+
+/** Represents the current casting state, according to MediaRouter APIs. */
+sealed interface MediaRouterCastModel {
+    /** MediaRouter isn't aware of any active cast. */
+    data object DoingNothing : MediaRouterCastModel
+
+    /**
+     * MediaRouter has an active cast.
+     *
+     * @property deviceName the name of the device receiving the cast.
+     */
+    data class Casting(val deviceName: String?) : MediaRouterCastModel
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegate.kt
new file mode 100644
index 0000000..cac3f25
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegate.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.chips.casttootherdevice.ui.view
+
+import android.content.Context
+import android.os.Bundle
+import com.android.systemui.mediaprojection.data.model.MediaProjectionState
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel.CastToOtherDeviceChipViewModel.Companion.CAST_TO_OTHER_DEVICE_ICON
+import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
+import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
+import com.android.systemui.statusbar.phone.SystemUIDialog
+
+/** A dialog that lets the user stop an ongoing cast-screen-to-other-device event. */
+class EndCastScreenToOtherDeviceDialogDelegate(
+    private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
+    private val context: Context,
+    private val stopAction: () -> Unit,
+    private val state: ProjectionChipModel.Projecting,
+) : SystemUIDialog.Delegate {
+    override fun createDialog(): SystemUIDialog {
+        return endMediaProjectionDialogHelper.createDialog(this)
+    }
+
+    override fun beforeCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
+        with(dialog) {
+            setIcon(CAST_TO_OTHER_DEVICE_ICON)
+            setTitle(R.string.cast_to_other_device_stop_dialog_title)
+            setMessage(getMessage())
+            // No custom on-click, because the dialog will automatically be dismissed when the
+            // button is clicked anyway.
+            setNegativeButton(R.string.close_dialog_button, /* onClick= */ null)
+            setPositiveButton(R.string.cast_to_other_device_stop_dialog_button) { _, _ ->
+                stopAction.invoke()
+            }
+        }
+    }
+
+    private fun getMessage(): String {
+        return if (state.projectionState is MediaProjectionState.Projecting.SingleTask) {
+            val appBeingSharedName =
+                endMediaProjectionDialogHelper.getAppName(state.projectionState)
+            if (appBeingSharedName != null && state.deviceName != null) {
+                context.getString(
+                    R.string.cast_to_other_device_stop_dialog_message_specific_app_with_device,
+                    appBeingSharedName,
+                    state.deviceName,
+                )
+            } else if (appBeingSharedName != null) {
+                context.getString(
+                    R.string.cast_to_other_device_stop_dialog_message_specific_app,
+                    appBeingSharedName,
+                )
+            } else if (state.deviceName != null) {
+                context.getString(
+                    R.string.cast_to_other_device_stop_dialog_message_generic_with_device,
+                    state.deviceName
+                )
+            } else {
+                context.getString(R.string.cast_to_other_device_stop_dialog_message_generic)
+            }
+        } else {
+            if (state.deviceName != null) {
+                context.getString(
+                    R.string.cast_to_other_device_stop_dialog_message_entire_screen_with_device,
+                    state.deviceName
+                )
+            } else {
+                context.getString(
+                    R.string.cast_to_other_device_stop_dialog_message_entire_screen,
+                )
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastToOtherDeviceDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastToOtherDeviceDialogDelegate.kt
deleted file mode 100644
index bc0f492..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastToOtherDeviceDialogDelegate.kt
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.chips.casttootherdevice.ui.view
-
-import android.os.Bundle
-import com.android.systemui.res.R
-import com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel.CastToOtherDeviceChipViewModel.Companion.CAST_TO_OTHER_DEVICE_ICON
-import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
-import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
-import com.android.systemui.statusbar.phone.SystemUIDialog
-
-/** A dialog that lets the user stop an ongoing cast-screen-to-other-device event. */
-class EndCastToOtherDeviceDialogDelegate(
-    private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
-    private val stopAction: () -> Unit,
-    private val state: ProjectionChipModel.Projecting,
-) : SystemUIDialog.Delegate {
-    override fun createDialog(): SystemUIDialog {
-        return endMediaProjectionDialogHelper.createDialog(this)
-    }
-
-    override fun beforeCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
-        with(dialog) {
-            setIcon(CAST_TO_OTHER_DEVICE_ICON)
-            setTitle(R.string.cast_to_other_device_stop_dialog_title)
-            setMessage(
-                endMediaProjectionDialogHelper.getDialogMessage(
-                    state.projectionState,
-                    genericMessageResId = R.string.cast_to_other_device_stop_dialog_message,
-                    specificAppMessageResId =
-                        R.string.cast_to_other_device_stop_dialog_message_specific_app,
-                )
-            )
-            // No custom on-click, because the dialog will automatically be dismissed when the
-            // button is clicked anyway.
-            setNegativeButton(R.string.close_dialog_button, /* onClick= */ null)
-            setPositiveButton(R.string.cast_to_other_device_stop_dialog_button) { _, _ ->
-                stopAction.invoke()
-            }
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegate.kt
new file mode 100644
index 0000000..7dc9b25
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegate.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.chips.casttootherdevice.ui.view
+
+import android.content.Context
+import android.os.Bundle
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel.CastToOtherDeviceChipViewModel.Companion.CAST_TO_OTHER_DEVICE_ICON
+import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
+import com.android.systemui.statusbar.phone.SystemUIDialog
+
+/**
+ * A dialog that lets the user stop an ongoing cast-to-other-device event. The user could be casting
+ * their screen, or just casting their audio. This dialog uses generic strings to handle both cases
+ * well.
+ */
+class EndGenericCastToOtherDeviceDialogDelegate(
+    private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
+    private val context: Context,
+    private val deviceName: String?,
+    private val stopAction: () -> Unit,
+) : SystemUIDialog.Delegate {
+    override fun createDialog(): SystemUIDialog {
+        return endMediaProjectionDialogHelper.createDialog(this)
+    }
+
+    override fun beforeCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
+        val message =
+            if (deviceName != null) {
+                context.getString(
+                    R.string.cast_to_other_device_stop_dialog_message_generic_with_device,
+                    deviceName,
+                )
+            } else {
+                context.getString(R.string.cast_to_other_device_stop_dialog_message_generic)
+            }
+        with(dialog) {
+            setIcon(CAST_TO_OTHER_DEVICE_ICON)
+            setTitle(R.string.cast_to_other_device_stop_dialog_title)
+            setMessage(message)
+            // No custom on-click, because the dialog will automatically be dismissed when the
+            // button is clicked anyway.
+            setNegativeButton(R.string.close_dialog_button, /* onClick= */ null)
+            setPositiveButton(R.string.cast_to_other_device_stop_dialog_button) { _, _ ->
+                stopAction.invoke()
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
index a1678bf..4183cdd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModel.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel
 
+import android.content.Context
 import androidx.annotation.DrawableRes
 import com.android.systemui.animation.DialogTransitionAnimator
 import com.android.systemui.common.shared.model.ContentDescription
@@ -23,10 +24,14 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.res.R
-import com.android.systemui.statusbar.chips.casttootherdevice.ui.view.EndCastToOtherDeviceDialogDelegate
+import com.android.systemui.statusbar.chips.casttootherdevice.domain.interactor.MediaRouterChipInteractor
+import com.android.systemui.statusbar.chips.casttootherdevice.domain.model.MediaRouterCastModel
+import com.android.systemui.statusbar.chips.casttootherdevice.ui.view.EndCastScreenToOtherDeviceDialogDelegate
+import com.android.systemui.statusbar.chips.casttootherdevice.ui.view.EndGenericCastToOtherDeviceDialogDelegate
 import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractor
 import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
 import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
+import com.android.systemui.statusbar.chips.ui.model.ColorsModel
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
 import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel
 import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel.Companion.createDialogLaunchOnClickListener
@@ -35,27 +40,35 @@
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
 
 /**
- * View model for the cast-to-other-device chip, shown when sharing your phone screen content to a
- * different device. (Triggered from the Quick Settings Cast tile or from the Settings app.)
+ * View model for the cast-to-other-device chip, shown when a user is sharing content to a different
+ * device. (Triggered from the Quick Settings Cast tile or from the Settings app.) The content could
+ * either be the user's screen, or just the user's audio.
  */
 @SysUISingleton
 class CastToOtherDeviceChipViewModel
 @Inject
 constructor(
     @Application private val scope: CoroutineScope,
+    private val context: Context,
     private val mediaProjectionChipInteractor: MediaProjectionChipInteractor,
+    private val mediaRouterChipInteractor: MediaRouterChipInteractor,
     private val systemClock: SystemClock,
     private val dialogTransitionAnimator: DialogTransitionAnimator,
     private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
 ) : OngoingActivityChipViewModel {
-    override val chip: StateFlow<OngoingActivityChipModel> =
-        // TODO(b/342169876): The MediaProjection APIs are not invoked for certain
-        // cast-to-other-device events, like audio-only casting. We should also listen to
-        // MediaRouter APIs to cover all cast events.
+    /**
+     * The cast chip to show, based only on MediaProjection API events.
+     *
+     * This chip will only be [OngoingActivityChipModel.Shown] when the user is casting their
+     * *screen*. If the user is only casting audio, this chip will be
+     * [OngoingActivityChipModel.Hidden].
+     */
+    private val projectionChip: StateFlow<OngoingActivityChipModel> =
         mediaProjectionChipInteractor.projection
             .map { projectionModel ->
                 when (projectionModel) {
@@ -64,11 +77,76 @@
                         if (projectionModel.type != ProjectionChipModel.Type.CAST_TO_OTHER_DEVICE) {
                             OngoingActivityChipModel.Hidden
                         } else {
-                            createCastToOtherDeviceChip(projectionModel)
+                            createCastScreenToOtherDeviceChip(projectionModel)
                         }
                     }
                 }
             }
+            // See b/347726238.
+            .stateIn(scope, SharingStarted.Lazily, OngoingActivityChipModel.Hidden)
+
+    /**
+     * The cast chip to show, based only on MediaRouter API events.
+     *
+     * This chip will be [OngoingActivityChipModel.Shown] when the user is casting their screen *or*
+     * their audio.
+     *
+     * The MediaProjection APIs are not invoked for casting *only audio* to another device because
+     * MediaProjection is only concerned with *screen* sharing (see b/342169876). We listen to
+     * MediaRouter APIs here to cover audio-only casting.
+     *
+     * Note that this means we will start showing the cast chip before the casting actually starts,
+     * for **both** audio-only casting and screen casting. MediaRouter is aware of all
+     * cast-to-other-device events, and MediaRouter immediately marks a device as "connecting" once
+     * a user selects what device they'd like to cast to, even if they haven't hit "Start casting"
+     * yet. All of SysUI considers "connecting" devices to be casting (see
+     * [com.android.systemui.statusbar.policy.CastDevice.isCasting]), so the chip will follow the
+     * same convention and start showing once a device is selected. See b/269975671.
+     */
+    private val routerChip =
+        mediaRouterChipInteractor.mediaRouterCastingState
+            .map { routerModel ->
+                when (routerModel) {
+                    is MediaRouterCastModel.DoingNothing -> OngoingActivityChipModel.Hidden
+                    is MediaRouterCastModel.Casting -> {
+                        // A consequence of b/269975671 is that MediaRouter will mark a device as
+                        // casting before casting has actually started. To alleviate this bug a bit,
+                        // we won't show a timer for MediaRouter events. That way, we won't show a
+                        // timer if cast hasn't actually started.
+                        //
+                        // This does mean that the audio-only casting chip will *never* show a
+                        // timer, because audio-only casting never activates the MediaProjection
+                        // APIs and those are the only cast APIs that show a timer.
+                        createIconOnlyCastChip(routerModel.deviceName)
+                    }
+                }
+            }
+            .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingActivityChipModel.Hidden)
+
+    override val chip: StateFlow<OngoingActivityChipModel> =
+        combine(projectionChip, routerChip) { projection, router ->
+                // A consequence of b/269975671 is that MediaRouter and MediaProjection APIs fire at
+                // different times when *screen* casting:
+                //
+                // 1. When the user chooses what device to cast to, the MediaRouter APIs mark the
+                // device as casting (even though casting hasn't actually started yet). At this
+                // point, `routerChip` is [OngoingActivityChipModel.Shown] but `projectionChip` is
+                // [OngoingActivityChipModel.Hidden], and we'll show the router chip.
+                //
+                // 2. Once casting has actually started, the MediaProjection APIs become aware of
+                // the device. At this point, both `routerChip` and `projectionChip` are
+                // [OngoingActivityChipModel.Shown].
+                //
+                // Because the MediaProjection APIs have activated, we know that the user is screen
+                // casting (not audio casting). We need to switch to using `projectionChip` because
+                // that chip will show information specific to screen casting. The `projectionChip`
+                // will also show a timer, as opposed to `routerChip`'s icon-only display.
+                if (projection is OngoingActivityChipModel.Shown) {
+                    projection
+                } else {
+                    router
+                }
+            }
             .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingActivityChipModel.Hidden)
 
     /** Stops the currently active projection. */
@@ -76,31 +154,66 @@
         mediaProjectionChipInteractor.stopProjecting()
     }
 
-    private fun createCastToOtherDeviceChip(
+    private fun stopMediaRouterCasting() {
+        mediaRouterChipInteractor.stopCasting()
+    }
+
+    private fun createCastScreenToOtherDeviceChip(
         state: ProjectionChipModel.Projecting,
     ): OngoingActivityChipModel.Shown {
-        return OngoingActivityChipModel.Shown(
+        return OngoingActivityChipModel.Shown.Timer(
             icon =
                 Icon.Resource(
                     CAST_TO_OTHER_DEVICE_ICON,
-                    ContentDescription.Resource(R.string.accessibility_casting),
+                    // This string is "Casting screen"
+                    ContentDescription.Resource(
+                        R.string.cast_screen_to_other_device_chip_accessibility_label,
+                    ),
                 ),
+            colors = ColorsModel.Red,
             // TODO(b/332662551): Maybe use a MediaProjection API to fetch this time.
             startTimeMs = systemClock.elapsedRealtime(),
             createDialogLaunchOnClickListener(
-                createCastToOtherDeviceDialogDelegate(state),
+                createCastScreenToOtherDeviceDialogDelegate(state),
                 dialogTransitionAnimator,
             ),
         )
     }
 
-    private fun createCastToOtherDeviceDialogDelegate(state: ProjectionChipModel.Projecting) =
-        EndCastToOtherDeviceDialogDelegate(
+    private fun createIconOnlyCastChip(deviceName: String?): OngoingActivityChipModel.Shown {
+        return OngoingActivityChipModel.Shown.IconOnly(
+            icon =
+                Icon.Resource(
+                    CAST_TO_OTHER_DEVICE_ICON,
+                    // This string is just "Casting"
+                    ContentDescription.Resource(R.string.accessibility_casting),
+                ),
+            colors = ColorsModel.Red,
+            createDialogLaunchOnClickListener(
+                createGenericCastToOtherDeviceDialogDelegate(deviceName),
+                dialogTransitionAnimator,
+            ),
+        )
+    }
+
+    private fun createCastScreenToOtherDeviceDialogDelegate(
+        state: ProjectionChipModel.Projecting,
+    ) =
+        EndCastScreenToOtherDeviceDialogDelegate(
             endMediaProjectionDialogHelper,
+            context,
             stopAction = this::stopProjecting,
             state,
         )
 
+    private fun createGenericCastToOtherDeviceDialogDelegate(deviceName: String?) =
+        EndGenericCastToOtherDeviceDialogDelegate(
+            endMediaProjectionDialogHelper,
+            context,
+            deviceName,
+            stopAction = this::stopMediaRouterCasting,
+        )
+
     companion object {
         @DrawableRes val CAST_TO_OTHER_DEVICE_ICON = R.drawable.ic_cast_connected
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt
index 20ebae7..ce60fab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractor.kt
@@ -19,8 +19,11 @@
 import android.content.pm.PackageManager
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
 import com.android.systemui.mediaprojection.data.model.MediaProjectionState
 import com.android.systemui.mediaprojection.data.repository.MediaProjectionRepository
+import com.android.systemui.statusbar.chips.StatusBarChipsLog
 import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
 import com.android.systemui.util.Utils
 import javax.inject.Inject
@@ -45,12 +48,16 @@
     @Application private val scope: CoroutineScope,
     private val mediaProjectionRepository: MediaProjectionRepository,
     private val packageManager: PackageManager,
+    @StatusBarChipsLog private val logger: LogBuffer,
 ) {
     val projection: StateFlow<ProjectionChipModel> =
         mediaProjectionRepository.mediaProjectionState
             .map { state ->
                 when (state) {
-                    is MediaProjectionState.NotProjecting -> ProjectionChipModel.NotProjecting
+                    is MediaProjectionState.NotProjecting -> {
+                        logger.log(TAG, LogLevel.INFO, {}, { "State: NotProjecting" })
+                        ProjectionChipModel.NotProjecting
+                    }
                     is MediaProjectionState.Projecting -> {
                         val type =
                             if (isProjectionToOtherDevice(state.hostPackage)) {
@@ -58,7 +65,17 @@
                             } else {
                                 ProjectionChipModel.Type.SHARE_TO_APP
                             }
-                        ProjectionChipModel.Projecting(type, state)
+                        logger.log(
+                            TAG,
+                            LogLevel.INFO,
+                            {
+                                str1 = type.name
+                                str2 = state.hostPackage
+                            },
+                            { "State: Projecting(type=$str1 hostPackage=$str2)" }
+                        )
+                        // TODO(b/351851835): Get the device name.
+                        ProjectionChipModel.Projecting(type, state, deviceName = null)
                     }
                 }
             }
@@ -81,4 +98,8 @@
         // marked as going to a different device, even if that isn't always true. See b/321078669.
         return Utils.isHeadlessRemoteDisplayProvider(packageManager, packageName)
     }
+
+    companion object {
+        private const val TAG = "MediaProjection"
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/model/ProjectionChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/model/ProjectionChipModel.kt
index 85682f5..a1a5e82 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/model/ProjectionChipModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/domain/model/ProjectionChipModel.kt
@@ -26,10 +26,16 @@
     /** There is no media being projected. */
     data object NotProjecting : ProjectionChipModel()
 
-    /** Media is currently being projected. */
+    /**
+     * Media is currently being projected.
+     *
+     * @property deviceName the name of the device receiving the projection, or null if the
+     *   projection is to this device (as opposed to a different device).
+     */
     data class Projecting(
         val type: Type,
         val projectionState: MediaProjectionState.Projecting,
+        val deviceName: String?,
     ) : ProjectionChipModel()
 
     enum class Type {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelper.kt
index 402306a..6004365 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelper.kt
@@ -16,13 +16,8 @@
 
 package com.android.systemui.statusbar.chips.mediaprojection.ui.view
 
-import android.annotation.StringRes
 import android.app.ActivityManager
-import android.content.Context
 import android.content.pm.PackageManager
-import android.text.Html
-import android.text.Html.FROM_HTML_MODE_LEGACY
-import android.text.TextUtils
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.mediaprojection.data.model.MediaProjectionState
 import com.android.systemui.statusbar.phone.SystemUIDialog
@@ -35,63 +30,38 @@
 constructor(
     private val dialogFactory: SystemUIDialog.Factory,
     private val packageManager: PackageManager,
-    private val context: Context
 ) {
     /** Creates a new [SystemUIDialog] using the given delegate. */
     fun createDialog(delegate: SystemUIDialog.Delegate): SystemUIDialog {
         return dialogFactory.create(delegate)
     }
 
-    /** See other [getDialogMessage]. */
-    fun getDialogMessage(
-        state: MediaProjectionState.Projecting,
-        @StringRes genericMessageResId: Int,
-        @StringRes specificAppMessageResId: Int,
-    ): CharSequence {
+    fun getAppName(state: MediaProjectionState.Projecting): CharSequence? {
         val specificTaskInfo =
             if (state is MediaProjectionState.Projecting.SingleTask) {
                 state.task
             } else {
                 null
             }
-        return getDialogMessage(specificTaskInfo, genericMessageResId, specificAppMessageResId)
+        return getAppName(specificTaskInfo)
+    }
+
+    fun getAppName(specificTaskInfo: ActivityManager.RunningTaskInfo?): CharSequence? {
+        val packageName = specificTaskInfo?.baseIntent?.component?.packageName ?: return null
+        return getAppName(packageName)
     }
 
     /**
-     * Returns the message to show in the dialog based on the specific media projection state.
-     *
-     * @param genericMessageResId a res ID for a more generic "end projection" message
-     * @param specificAppMessageResId a res ID for an "end projection" message that also lets us
-     *   specify which app is currently being projected.
+     * Returns the human-readable application name for the given package, or null if it couldn't be
+     * found for any reason.
      */
-    fun getDialogMessage(
-        specificTaskInfo: ActivityManager.RunningTaskInfo?,
-        @StringRes genericMessageResId: Int,
-        @StringRes specificAppMessageResId: Int,
-    ): CharSequence {
-        if (specificTaskInfo == null) {
-            return context.getString(genericMessageResId)
-        }
-        val packageName =
-            specificTaskInfo.baseIntent.component?.packageName
-                ?: return context.getString(genericMessageResId)
+    fun getAppName(packageName: String): CharSequence? {
         return try {
             val appInfo = packageManager.getApplicationInfo(packageName, 0)
-            val appName = appInfo.loadLabel(packageManager)
-            getSpecificAppMessageText(specificAppMessageResId, appName)
+            appInfo.loadLabel(packageManager)
         } catch (e: PackageManager.NameNotFoundException) {
             // TODO(b/332662551): Log this error.
-            context.getString(genericMessageResId)
+            null
         }
     }
-
-    private fun getSpecificAppMessageText(
-        @StringRes specificAppMessageResId: Int,
-        appName: CharSequence,
-    ): CharSequence {
-        // https://developer.android.com/guide/topics/resources/string-resource#StylingWithHTML
-        val escapedAppName = TextUtils.htmlEncode(appName.toString())
-        val text = context.getString(specificAppMessageResId, escapedAppName)
-        return Html.fromHtml(text, FROM_HTML_MODE_LEGACY)
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt
index 1e9f0a1..28a8385 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt
@@ -18,10 +18,13 @@
 
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
 import com.android.systemui.mediaprojection.data.model.MediaProjectionState
 import com.android.systemui.mediaprojection.data.repository.MediaProjectionRepository
 import com.android.systemui.screenrecord.data.model.ScreenRecordModel
 import com.android.systemui.screenrecord.data.repository.ScreenRecordRepository
+import com.android.systemui.statusbar.chips.StatusBarChipsLog
 import com.android.systemui.statusbar.chips.screenrecord.domain.model.ScreenRecordChipModel
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
@@ -39,6 +42,7 @@
     @Application private val scope: CoroutineScope,
     private val screenRecordRepository: ScreenRecordRepository,
     private val mediaProjectionRepository: MediaProjectionRepository,
+    @StatusBarChipsLog private val logger: LogBuffer,
 ) {
     val screenRecordState: StateFlow<ScreenRecordChipModel> =
         // ScreenRecordRepository has the main "is the screen being recorded?" state, and
@@ -49,10 +53,19 @@
                 mediaProjectionRepository.mediaProjectionState,
             ) { screenRecordState, mediaProjectionState ->
                 when (screenRecordState) {
-                    is ScreenRecordModel.DoingNothing -> ScreenRecordChipModel.DoingNothing
-                    // TODO(b/332662551): Implement the 3-2-1 countdown chip.
-                    is ScreenRecordModel.Starting ->
+                    is ScreenRecordModel.DoingNothing -> {
+                        logger.log(TAG, LogLevel.INFO, {}, { "State: DoingNothing" })
+                        ScreenRecordChipModel.DoingNothing
+                    }
+                    is ScreenRecordModel.Starting -> {
+                        logger.log(
+                            TAG,
+                            LogLevel.INFO,
+                            { long1 = screenRecordState.millisUntilStarted },
+                            { "State: Starting($long1)" }
+                        )
                         ScreenRecordChipModel.Starting(screenRecordState.millisUntilStarted)
+                    }
                     is ScreenRecordModel.Recording -> {
                         val recordedTask =
                             if (
@@ -62,6 +75,12 @@
                             } else {
                                 null
                             }
+                        logger.log(
+                            TAG,
+                            LogLevel.INFO,
+                            { str1 = recordedTask?.baseIntent?.component?.packageName },
+                            { "State: Recording(taskPackage=$str1)" }
+                        )
                         ScreenRecordChipModel.Recording(recordedTask)
                     }
                 }
@@ -72,4 +91,8 @@
     fun stopRecording() {
         scope.launch { screenRecordRepository.stopRecording() }
     }
+
+    companion object {
+        private const val TAG = "ScreenRecord"
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegate.kt
index 9adbff9..1eca827 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegate.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.chips.screenrecord.ui.view
 
 import android.app.ActivityManager
+import android.content.Context
 import android.os.Bundle
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
@@ -26,6 +27,7 @@
 /** A dialog that lets the user stop an ongoing screen recording. */
 class EndScreenRecordingDialogDelegate(
     private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
+    val context: Context,
     private val stopAction: () -> Unit,
     private val recordedTask: ActivityManager.RunningTaskInfo?,
 ) : SystemUIDialog.Delegate {
@@ -35,16 +37,18 @@
     }
 
     override fun beforeCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
+        val appName = endMediaProjectionDialogHelper.getAppName(recordedTask)
+        val message =
+            if (appName != null) {
+                context.getString(R.string.screenrecord_stop_dialog_message_specific_app, appName)
+            } else {
+                context.getString(R.string.screenrecord_stop_dialog_message)
+            }
+
         with(dialog) {
             setIcon(ScreenRecordChipViewModel.ICON)
             setTitle(R.string.screenrecord_stop_dialog_title)
-            setMessage(
-                endMediaProjectionDialogHelper.getDialogMessage(
-                    recordedTask,
-                    genericMessageResId = R.string.screenrecord_stop_dialog_message,
-                    specificAppMessageResId = R.string.screenrecord_stop_dialog_message_specific_app
-                )
-            )
+            setMessage(message)
             // No custom on-click, because the dialog will automatically be dismissed when the
             // button is clicked anyway.
             setNegativeButton(R.string.close_dialog_button, /* onClick= */ null)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
index d190cfd..df25d57 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModel.kt
@@ -17,16 +17,20 @@
 package com.android.systemui.statusbar.chips.screenrecord.ui.viewmodel
 
 import android.app.ActivityManager
+import android.content.Context
 import androidx.annotation.DrawableRes
 import com.android.systemui.animation.DialogTransitionAnimator
+import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.res.R
+import com.android.systemui.screenrecord.data.model.ScreenRecordModel.Starting.Companion.toCountdownSeconds
 import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
 import com.android.systemui.statusbar.chips.screenrecord.domain.interactor.ScreenRecordChipInteractor
 import com.android.systemui.statusbar.chips.screenrecord.domain.model.ScreenRecordChipModel
 import com.android.systemui.statusbar.chips.screenrecord.ui.view.EndScreenRecordingDialogDelegate
+import com.android.systemui.statusbar.chips.ui.model.ColorsModel
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
 import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel
 import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel.Companion.createDialogLaunchOnClickListener
@@ -44,6 +48,7 @@
 @Inject
 constructor(
     @Application private val scope: CoroutineScope,
+    private val context: Context,
     private val interactor: ScreenRecordChipInteractor,
     private val systemClock: SystemClock,
     private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
@@ -54,12 +59,22 @@
             .map { state ->
                 when (state) {
                     is ScreenRecordChipModel.DoingNothing -> OngoingActivityChipModel.Hidden
-                    // TODO(b/332662551): Implement the 3-2-1 countdown chip.
-                    is ScreenRecordChipModel.Starting -> OngoingActivityChipModel.Hidden
+                    is ScreenRecordChipModel.Starting -> {
+                        OngoingActivityChipModel.Shown.Countdown(
+                            colors = ColorsModel.Red,
+                            secondsUntilStarted = state.millisUntilStarted.toCountdownSeconds(),
+                        )
+                    }
                     is ScreenRecordChipModel.Recording -> {
-                        OngoingActivityChipModel.Shown(
-                            // TODO(b/332662551): Also provide a content description.
-                            icon = Icon.Resource(ICON, contentDescription = null),
+                        OngoingActivityChipModel.Shown.Timer(
+                            icon =
+                                Icon.Resource(
+                                    ICON,
+                                    ContentDescription.Resource(
+                                        R.string.screenrecord_ongoing_screen_only,
+                                    ),
+                                ),
+                            colors = ColorsModel.Red,
                             startTimeMs = systemClock.elapsedRealtime(),
                             createDialogLaunchOnClickListener(
                                 createDelegate(state.recordedTask),
@@ -69,13 +84,15 @@
                     }
                 }
             }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingActivityChipModel.Hidden)
+            // See b/347726238.
+            .stateIn(scope, SharingStarted.Lazily, OngoingActivityChipModel.Hidden)
 
     private fun createDelegate(
         recordedTask: ActivityManager.RunningTaskInfo?
     ): EndScreenRecordingDialogDelegate {
         return EndScreenRecordingDialogDelegate(
             endMediaProjectionDialogHelper,
+            context,
             stopAction = interactor::stopRecording,
             recordedTask,
         )
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegate.kt
index 7e7ef40..564f20e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegate.kt
@@ -16,7 +16,9 @@
 
 package com.android.systemui.statusbar.chips.sharetoapp.ui.view
 
+import android.content.Context
 import android.os.Bundle
+import com.android.systemui.mediaprojection.data.model.MediaProjectionState
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
 import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
@@ -26,6 +28,7 @@
 /** A dialog that lets the user stop an ongoing share-screen-to-app event. */
 class EndShareToAppDialogDelegate(
     private val endMediaProjectionDialogHelper: EndMediaProjectionDialogHelper,
+    private val context: Context,
     private val stopAction: () -> Unit,
     private val state: ProjectionChipModel.Projecting,
 ) : SystemUIDialog.Delegate {
@@ -37,13 +40,7 @@
         with(dialog) {
             setIcon(SHARE_TO_APP_ICON)
             setTitle(R.string.share_to_app_stop_dialog_title)
-            setMessage(
-                endMediaProjectionDialogHelper.getDialogMessage(
-                    state.projectionState,
-                    genericMessageResId = R.string.share_to_app_stop_dialog_message,
-                    specificAppMessageResId = R.string.share_to_app_stop_dialog_message_specific_app
-                )
-            )
+            setMessage(getMessage())
             // No custom on-click, because the dialog will automatically be dismissed when the
             // button is clicked anyway.
             setNegativeButton(R.string.close_dialog_button, /* onClick= */ null)
@@ -52,4 +49,32 @@
             }
         }
     }
+
+    private fun getMessage(): String {
+        return if (state.projectionState is MediaProjectionState.Projecting.SingleTask) {
+            // If a single app is being shared, use the name of the app being shared in the dialog
+            val appBeingSharedName =
+                endMediaProjectionDialogHelper.getAppName(state.projectionState)
+            if (appBeingSharedName != null) {
+                context.getString(
+                    R.string.share_to_app_stop_dialog_message_single_app_specific,
+                    appBeingSharedName,
+                )
+            } else {
+                context.getString(R.string.share_to_app_stop_dialog_message_single_app_generic)
+            }
+        } else {
+            // Otherwise, use the name of the app *receiving* the share
+            val hostAppName =
+                endMediaProjectionDialogHelper.getAppName(state.projectionState.hostPackage)
+            if (hostAppName != null) {
+                context.getString(
+                    R.string.share_to_app_stop_dialog_message_entire_screen_with_host_app,
+                    hostAppName
+                )
+            } else {
+                context.getString(R.string.share_to_app_stop_dialog_message_entire_screen)
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
index dc41002..c097720 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModel.kt
@@ -16,8 +16,10 @@
 
 package com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel
 
+import android.content.Context
 import androidx.annotation.DrawableRes
 import com.android.systemui.animation.DialogTransitionAnimator
+import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
@@ -26,6 +28,7 @@
 import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
 import com.android.systemui.statusbar.chips.mediaprojection.ui.view.EndMediaProjectionDialogHelper
 import com.android.systemui.statusbar.chips.sharetoapp.ui.view.EndShareToAppDialogDelegate
+import com.android.systemui.statusbar.chips.ui.model.ColorsModel
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
 import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel
 import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipViewModel.Companion.createDialogLaunchOnClickListener
@@ -46,6 +49,7 @@
 @Inject
 constructor(
     @Application private val scope: CoroutineScope,
+    private val context: Context,
     private val mediaProjectionChipInteractor: MediaProjectionChipInteractor,
     private val systemClock: SystemClock,
     private val dialogTransitionAnimator: DialogTransitionAnimator,
@@ -65,7 +69,8 @@
                     }
                 }
             }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingActivityChipModel.Hidden)
+            // See b/347726238.
+            .stateIn(scope, SharingStarted.Lazily, OngoingActivityChipModel.Hidden)
 
     /** Stops the currently active projection. */
     private fun stopProjecting() {
@@ -75,9 +80,13 @@
     private fun createShareToAppChip(
         state: ProjectionChipModel.Projecting,
     ): OngoingActivityChipModel.Shown {
-        return OngoingActivityChipModel.Shown(
-            // TODO(b/332662551): Use the right content description.
-            icon = Icon.Resource(SHARE_TO_APP_ICON, contentDescription = null),
+        return OngoingActivityChipModel.Shown.Timer(
+            icon =
+                Icon.Resource(
+                    SHARE_TO_APP_ICON,
+                    ContentDescription.Resource(R.string.share_to_app_chip_accessibility_label),
+                ),
+            colors = ColorsModel.Red,
             // TODO(b/332662551): Maybe use a MediaProjection API to fetch this time.
             startTimeMs = systemClock.elapsedRealtime(),
             createDialogLaunchOnClickListener(
@@ -90,12 +99,12 @@
     private fun createShareToAppDialogDelegate(state: ProjectionChipModel.Projecting) =
         EndShareToAppDialogDelegate(
             endMediaProjectionDialogHelper,
+            context,
             stopAction = this::stopProjecting,
             state,
         )
 
     companion object {
-        // TODO(b/332662551): Use the right icon.
-        @DrawableRes val SHARE_TO_APP_ICON = R.drawable.ic_screenshot_share
+        @DrawableRes val SHARE_TO_APP_ICON = R.drawable.ic_present_to_all
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt
new file mode 100644
index 0000000..b2140f7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/ColorsModel.kt
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.chips.ui.model
+
+import android.content.Context
+import android.content.res.ColorStateList
+import androidx.annotation.ColorInt
+import com.android.settingslib.Utils
+import com.android.systemui.res.R
+
+/** Model representing how the chip in the status bar should be colored. */
+sealed interface ColorsModel {
+    /** The color for the background of the chip. */
+    fun background(context: Context): ColorStateList
+
+    /** The color for the text (and icon) on the chip. */
+    @ColorInt fun text(context: Context): Int
+
+    /** The chip should match the theme's primary color. */
+    data object Themed : ColorsModel {
+        override fun background(context: Context): ColorStateList =
+            Utils.getColorAttr(context, com.android.internal.R.attr.colorAccent)
+
+        override fun text(context: Context) =
+            Utils.getColorAttrDefaultColor(context, com.android.internal.R.attr.colorPrimary)
+    }
+
+    /** The chip should have a red background with white text. */
+    data object Red : ColorsModel {
+        override fun background(context: Context): ColorStateList =
+            ColorStateList.valueOf(context.getColor(R.color.GM2_red_600))
+
+        override fun text(context: Context) = context.getColor(android.R.color.white)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
index e63713b..40f86f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
@@ -21,24 +21,65 @@
 
 /** Model representing the display of an ongoing activity as a chip in the status bar. */
 sealed class OngoingActivityChipModel {
+    /** Condensed name representing the model, used for logs. */
+    abstract val logName: String
+
     /** This chip shouldn't be shown. */
-    data object Hidden : OngoingActivityChipModel()
+    data object Hidden : OngoingActivityChipModel() {
+        override val logName = "Hidden"
+    }
 
     /** This chip should be shown with the given information. */
-    data class Shown(
-        /** The icon to show on the chip. */
-        val icon: Icon,
+    abstract class Shown(
+        /** The icon to show on the chip. If null, no icon will be shown. */
+        open val icon: Icon?,
+        /** What colors to use for the chip. */
+        open val colors: ColorsModel,
         /**
-         * The time this event started, used to show the timer.
-         *
-         * This time should be relative to
-         * [com.android.systemui.util.time.SystemClock.elapsedRealtime], *not*
-         * [com.android.systemui.util.time.SystemClock.currentTimeMillis] because the
-         * [ChipChronometer] is based off of elapsed realtime. See
-         * [android.widget.Chronometer.setBase].
+         * Listener method to invoke when this chip is clicked. If null, the chip won't be
+         * clickable.
          */
-        val startTimeMs: Long,
-        /** Listener method to invoke when this chip is clicked. */
-        val onClickListener: View.OnClickListener,
-    ) : OngoingActivityChipModel()
+        open val onClickListener: View.OnClickListener?,
+    ) : OngoingActivityChipModel() {
+
+        /** This chip shows only an icon and nothing else. */
+        data class IconOnly(
+            override val icon: Icon,
+            override val colors: ColorsModel,
+            override val onClickListener: View.OnClickListener?,
+        ) : Shown(icon, colors, onClickListener) {
+            override val logName = "Shown.Icon"
+        }
+
+        /** The chip shows a timer, counting up from [startTimeMs]. */
+        data class Timer(
+            override val icon: Icon,
+            override val colors: ColorsModel,
+            /**
+             * The time this event started, used to show the timer.
+             *
+             * This time should be relative to
+             * [com.android.systemui.util.time.SystemClock.elapsedRealtime], *not*
+             * [com.android.systemui.util.time.SystemClock.currentTimeMillis] because the
+             * [ChipChronometer] is based off of elapsed realtime. See
+             * [android.widget.Chronometer.setBase].
+             */
+            val startTimeMs: Long,
+            override val onClickListener: View.OnClickListener?,
+        ) : Shown(icon, colors, onClickListener) {
+            override val logName = "Shown.Timer"
+        }
+
+        /**
+         * This chip shows a countdown using [secondsUntilStarted]. Used to inform users that an
+         * event is about to start. Typically, a [Countdown] chip will turn into a [Timer] chip.
+         */
+        data class Countdown(
+            override val colors: ColorsModel,
+            /** The number of seconds until an event is started. */
+            val secondsUntilStarted: Long,
+        ) : Shown(icon = null, colors, onClickListener = null) {
+            override val logName = "Shown.Countdown"
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt
index 1b79ce4..15c348e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt
@@ -18,6 +18,9 @@
 
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.statusbar.chips.StatusBarChipsLog
 import com.android.systemui.statusbar.chips.call.ui.viewmodel.CallChipViewModel
 import com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel.CastToOtherDeviceChipViewModel
 import com.android.systemui.statusbar.chips.screenrecord.ui.viewmodel.ScreenRecordChipViewModel
@@ -45,6 +48,7 @@
     shareToAppChipViewModel: ShareToAppChipViewModel,
     castToOtherDeviceChipViewModel: CastToOtherDeviceChipViewModel,
     callChipViewModel: CallChipViewModel,
+    @StatusBarChipsLog private val logger: LogBuffer,
 ) {
     /**
      * A flow modeling the chip that should be shown in the status bar after accounting for possibly
@@ -60,6 +64,17 @@
                 castToOtherDeviceChipViewModel.chip,
                 callChipViewModel.chip,
             ) { screenRecord, shareToApp, castToOtherDevice, call ->
+                logger.log(
+                    TAG,
+                    LogLevel.INFO,
+                    {
+                        str1 = screenRecord.logName
+                        str2 = shareToApp.logName
+                        str3 = castToOtherDevice.logName
+                    },
+                    { "Chips: ScreenRecord=$str1 > ShareToApp=$str2 > CastToOther=$str3..." },
+                )
+                logger.log(TAG, LogLevel.INFO, { str1 = call.logName }, { "... > Call=$str1" })
                 // This `when` statement shows the priority order of the chips
                 when {
                     // Screen recording also activates the media projection APIs, so whenever the
@@ -72,5 +87,12 @@
                     else -> call
                 }
             }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingActivityChipModel.Hidden)
+            // Some of the chips could have timers in them and we don't want the start time
+            // for those timers to get reset for any reason. So, as soon as any subscriber has
+            // requested the chip information, we need to maintain it forever. See b/347726238.
+            .stateIn(scope, SharingStarted.Lazily, OngoingActivityChipModel.Hidden)
+
+    companion object {
+        private const val TAG = "ChipsViewModel"
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/model/StatusBarMode.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/model/StatusBarMode.kt
index 933d0ab..b467032 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/model/StatusBarMode.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/model/StatusBarMode.kt
@@ -16,13 +16,13 @@
 
 package com.android.systemui.statusbar.data.model
 
-import com.android.systemui.statusbar.phone.BarTransitions
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT
-import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode
+import com.android.systemui.shared.statusbar.phone.BarTransitions
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_OPAQUE
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_TRANSPARENT
+import com.android.systemui.shared.statusbar.phone.BarTransitions.TransitionMode
 
 /**
  * The possible status bar modes.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractor.kt
index ca73081..9ca110e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/domain/interactor/StatusBarKeyguardViewManagerInteractor.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.keyguard.domain.interactor.WindowManagerLockscreenVisibilityInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
@@ -90,17 +91,22 @@
 
     /** Occlusion state to apply whenever a keyguard transition is FINISHED. */
     private val occlusionStateFromFinishedStep =
-        keyguardTransitionInteractor.finishedKeyguardTransitionStep
-            .sample(keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop, ::Pair)
-            .map { (finishedStep, showWhenLockedOnTop) ->
+        combine(
+                keyguardTransitionInteractor.isFinishedIn(
+                    scene = Scenes.Gone,
+                    stateWithoutSceneContainer = KeyguardState.GONE,
+                ),
+                keyguardTransitionInteractor.isFinishedIn(KeyguardState.OCCLUDED),
+                keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop,
+                ::Triple
+            )
+            .map { (isOnGone, isOnOccluded, showWhenLockedOnTop) ->
                 // If we're FINISHED in OCCLUDED, we want to render as occluded. We also need to
                 // remain occluded if a SHOW_WHEN_LOCKED activity is on the top of the task stack,
                 // and we're in any state other than GONE. This is necessary, for example, when we
                 // transition from OCCLUDED to a bouncer state. Otherwise, we should not be
                 // occluded.
-                val occluded =
-                    finishedStep.to == KeyguardState.OCCLUDED ||
-                        (showWhenLockedOnTop && finishedStep.to != KeyguardState.GONE)
+                val occluded = isOnOccluded || (showWhenLockedOnTop && !isOnGone)
                 OccludedState(occluded = occluded, animate = false)
             }
 
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 ee2c9cc..ef4dffad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
@@ -109,6 +109,7 @@
         @Main private val uiExecutor: Executor,
         @Background private val bgExecutor: Executor,
         @Main private val handler: Handler,
+        @Background private val bgHandler: Handler,
         @Named(DATE_SMARTSPACE_DATA_PLUGIN)
         optionalDatePlugin: Optional<BcSmartspaceDataPlugin>,
         @Named(WEATHER_SMARTSPACE_DATA_PLUGIN)
@@ -304,26 +305,20 @@
         dumpManager.registerDumpable(this)
     }
 
-    fun isEnabled(): Boolean {
-        execution.assertIsMainThread()
+    val isEnabled: Boolean = plugin != null
 
-        return plugin != null
-    }
+    val isDateWeatherDecoupled: Boolean = datePlugin != null && weatherPlugin != null
 
-    fun isDateWeatherDecoupled(): Boolean {
-        execution.assertIsMainThread()
-
-        return datePlugin != null && weatherPlugin != null
-    }
-
-    fun isWeatherEnabled(): Boolean {
-       execution.assertIsMainThread()
-       val showWeather = secureSettings.getIntForUser(
-           LOCK_SCREEN_WEATHER_ENABLED,
-           1,
-           userTracker.userId) == 1
-       return showWeather
-    }
+    val isWeatherEnabled: Boolean
+        get() {
+            val showWeather =
+                secureSettings.getIntForUser(
+                    LOCK_SCREEN_WEATHER_ENABLED,
+                    1,
+                    userTracker.userId,
+                ) == 1
+            return showWeather
+        }
 
     private fun updateBypassEnabled() {
         val bypassEnabled = bypassController.bypassEnabled
@@ -336,10 +331,10 @@
     fun buildAndConnectDateView(parent: ViewGroup): View? {
         execution.assertIsMainThread()
 
-        if (!isEnabled()) {
+        if (!isEnabled) {
             throw RuntimeException("Cannot build view when not enabled")
         }
-        if (!isDateWeatherDecoupled()) {
+        if (!isDateWeatherDecoupled) {
             throw RuntimeException("Cannot build date view when not decoupled")
         }
 
@@ -360,10 +355,10 @@
     fun buildAndConnectWeatherView(parent: ViewGroup): View? {
         execution.assertIsMainThread()
 
-        if (!isEnabled()) {
+        if (!isEnabled) {
             throw RuntimeException("Cannot build view when not enabled")
         }
-        if (!isDateWeatherDecoupled()) {
+        if (!isDateWeatherDecoupled) {
             throw RuntimeException("Cannot build weather view when not decoupled")
         }
 
@@ -384,7 +379,7 @@
     fun buildAndConnectView(parent: ViewGroup): View? {
         execution.assertIsMainThread()
 
-        if (!isEnabled()) {
+        if (!isEnabled) {
             throw RuntimeException("Cannot build view when not enabled")
         }
 
@@ -412,6 +407,7 @@
 
         val ssView = plugin.getView(parent)
         configPlugin?.let { ssView.registerConfigProvider(it) }
+        ssView.setBgHandler(bgHandler)
         ssView.setUiSurface(BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD)
         ssView.setTimeChangedDelegate(SmartspaceTimeChangedDelegate(keyguardUpdateMonitor))
         ssView.registerDataProvider(plugin)
@@ -575,7 +571,7 @@
     }
 
     private fun filterSmartspaceTarget(t: SmartspaceTarget): Boolean {
-        if (isDateWeatherDecoupled() && t.featureType == SmartspaceTarget.FEATURE_WEATHER) {
+        if (isDateWeatherDecoupled && t.featureType == SmartspaceTarget.FEATURE_WEATHER) {
             return false
         }
         if (!showNotifications) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
index f62b24a..3dcaff3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
@@ -21,6 +21,7 @@
 import com.android.internal.annotations.VisibleForTesting
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.NOTIFICATIONS_USE_PEOPLE_FILTERING
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.notification.collection.NotificationClassificationFlag
 import com.android.systemui.statusbar.notification.shared.NotificationMinimalismPrototype
 import com.android.systemui.statusbar.notification.shared.PriorityPeopleSection
 import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
@@ -51,7 +52,8 @@
     }
 
     fun getNotificationBuckets(): IntArray {
-        if (PriorityPeopleSection.isEnabled || NotificationMinimalismPrototype.V2.isEnabled) {
+        if (PriorityPeopleSection.isEnabled || NotificationMinimalismPrototype.V2.isEnabled
+            || NotificationClassificationFlag.isEnabled) {
             // We don't need this list to be adaptive, it can be the superset of all features.
             return PriorityBucket.getAllInOrder()
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
index 4c66f66..9240c1c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -58,7 +58,7 @@
 constructor(
     @Application applicationScope: CoroutineScope,
     dumpManager: DumpManager,
-    private val mHeadsUpManager: HeadsUpManager,
+    private val headsUpManager: HeadsUpManager,
     private val statusBarStateController: StatusBarStateController,
     private val bypassController: KeyguardBypassController,
     private val dozeParameters: DozeParameters,
@@ -71,8 +71,8 @@
     StatusBarStateController.StateListener,
     ShadeExpansionListener,
     Dumpable {
-    private lateinit var mStackScrollerController: NotificationStackScrollLayoutController
-    private var mVisibilityInterpolator = Interpolators.FAST_OUT_SLOW_IN_REVERSE
+    private lateinit var stackScrollerController: NotificationStackScrollLayoutController
+    private var visibilityInterpolator = Interpolators.FAST_OUT_SLOW_IN_REVERSE
 
     private var inputLinearDozeAmount: Float = 0.0f
     private var inputEasedDozeAmount: Float = 0.0f
@@ -85,13 +85,13 @@
     private var outputEasedDozeAmount: Float = 0.0f
     @VisibleForTesting val dozeAmountInterpolator: Interpolator = Interpolators.FAST_OUT_SLOW_IN
 
-    private var mNotificationVisibleAmount = 0.0f
-    private var mNotificationsVisible = false
-    private var mNotificationsVisibleForExpansion = false
-    private var mVisibilityAnimator: ObjectAnimator? = null
-    private var mVisibilityAmount = 0.0f
-    private var mLinearVisibilityAmount = 0.0f
-    private val mEntrySetToClearWhenFinished = mutableSetOf<NotificationEntry>()
+    private var notificationVisibleAmount = 0.0f
+    private var notificationsVisible = false
+    private var notificationsVisibleForExpansion = false
+    private var visibilityAnimator: ObjectAnimator? = null
+    private var visibilityAmount = 0.0f
+    private var linearVisibilityAmount = 0.0f
+    private val entrySetToClearWhenFinished = mutableSetOf<NotificationEntry>()
     private var pulseExpanding: Boolean = false
     private val wakeUpListeners = arrayListOf<WakeUpListener>()
     private var state: Int = StatusBarState.KEYGUARD
@@ -104,14 +104,14 @@
             willWakeUp = false
             if (value) {
                 if (
-                    mNotificationsVisible &&
-                        !mNotificationsVisibleForExpansion &&
+                    notificationsVisible &&
+                        !notificationsVisibleForExpansion &&
                         !bypassController.bypassEnabled
                 ) {
                     // We're waking up while pulsing, let's make sure the animation looks nice
-                    mStackScrollerController.wakeUpFromPulse()
+                    stackScrollerController.wakeUpFromPulse()
                 }
-                if (bypassController.bypassEnabled && !mNotificationsVisible) {
+                if (bypassController.bypassEnabled && !notificationsVisible) {
                     // Let's make sure our huns become visible once we are waking up in case
                     // they were blocked by the proximity sensor
                     updateNotificationVisibility(
@@ -186,13 +186,13 @@
 
     init {
         dumpManager.registerDumpable(this)
-        mHeadsUpManager.addListener(this)
+        headsUpManager.addListener(this)
         statusBarStateController.addCallback(this)
         bypassController.registerOnBypassStateChangedListener(bypassStateChangedListener)
         addListener(
             object : WakeUpListener {
                 override fun onFullyHiddenChanged(isFullyHidden: Boolean) {
-                    if (isFullyHidden && mNotificationsVisibleForExpansion) {
+                    if (isFullyHidden && notificationsVisibleForExpansion) {
                         // When the notification becomes fully invisible, let's make sure our
                         // expansion
                         // flag also changes. This can happen if the bouncer shows when dragging
@@ -217,7 +217,7 @@
     }
 
     fun setStackScroller(stackScrollerController: NotificationStackScrollLayoutController) {
-        mStackScrollerController = stackScrollerController
+        this.stackScrollerController = stackScrollerController
         pulseExpanding = stackScrollerController.isPulseExpanding
         stackScrollerController.setOnPulseHeightChangedListener {
             val nowExpanding = isPulseExpanding()
@@ -237,7 +237,7 @@
         }
     }
 
-    fun isPulseExpanding(): Boolean = mStackScrollerController.isPulseExpanding
+    fun isPulseExpanding(): Boolean = stackScrollerController.isPulseExpanding
 
     /**
      * @param visible should notifications be visible
@@ -249,13 +249,13 @@
         animate: Boolean,
         increaseSpeed: Boolean
     ) {
-        mNotificationsVisibleForExpansion = visible
+        notificationsVisibleForExpansion = visible
         updateNotificationVisibility(animate, increaseSpeed)
-        if (!visible && mNotificationsVisible) {
+        if (!visible && notificationsVisible) {
             // If we stopped expanding and we're still visible because we had a pulse that hasn't
             // times out, let's release them all to make sure were not stuck in a state where
             // notifications are visible
-            mHeadsUpManager.releaseAllImmediately()
+            headsUpManager.releaseAllImmediately()
         }
     }
 
@@ -269,12 +269,12 @@
 
     private fun updateNotificationVisibility(animate: Boolean, increaseSpeed: Boolean) {
         // TODO: handle Lockscreen wakeup for bypass when we're not pulsing anymore
-        var visible = mNotificationsVisibleForExpansion || mHeadsUpManager.hasNotifications()
+        var visible = notificationsVisibleForExpansion || headsUpManager.hasNotifications()
         visible = visible && canShowPulsingHuns
 
         if (
             !visible &&
-                mNotificationsVisible &&
+                notificationsVisible &&
                 (wakingUp || willWakeUp) &&
                 outputLinearDozeAmount != 0.0f
         ) {
@@ -290,11 +290,11 @@
         animate: Boolean,
         increaseSpeed: Boolean
     ) {
-        if (mNotificationsVisible == visible) {
+        if (notificationsVisible == visible) {
             return
         }
-        mNotificationsVisible = visible
-        mVisibilityAnimator?.cancel()
+        notificationsVisible = visible
+        visibilityAnimator?.cancel()
         if (animate) {
             notifyAnimationStart(visible)
             startVisibilityAnimation(increaseSpeed)
@@ -371,7 +371,7 @@
             state = statusBarStateController.state,
             changed = changed
         )
-        mStackScrollerController.setDozeAmount(outputEasedDozeAmount)
+        stackScrollerController.setDozeAmount(outputEasedDozeAmount)
         updateHideAmount()
         if (changed && outputLinearDozeAmount == 0.0f) {
             setNotificationsVisible(visible = false, animate = false, increaseSpeed = false)
@@ -469,13 +469,27 @@
         get() = state
 
     override fun onPanelExpansionChanged(event: ShadeExpansionChangeEvent) {
-        val collapsedEnough = event.fraction <= 0.9f
-        if (collapsedEnough != this.collapsedEnoughToHide) {
-            val couldShowPulsingHuns = canShowPulsingHuns
-            this.collapsedEnoughToHide = collapsedEnough
+        val fraction = event.fraction
+
+        val wasCollapsedEnoughToHide = collapsedEnoughToHide
+        val isCollapsedEnoughToHide = fraction <= 0.9f
+
+        if (isCollapsedEnoughToHide != wasCollapsedEnoughToHide) {
+            val couldShowPulsingHuns = this.canShowPulsingHuns
+            this.collapsedEnoughToHide = isCollapsedEnoughToHide
+            val canShowPulsingHuns = this.canShowPulsingHuns
+
+            logger.logOnPanelExpansionChanged(
+                fraction,
+                wasCollapsedEnoughToHide,
+                isCollapsedEnoughToHide,
+                couldShowPulsingHuns,
+                canShowPulsingHuns
+            )
+
             if (couldShowPulsingHuns && !canShowPulsingHuns) {
                 updateNotificationVisibility(animate = true, increaseSpeed = true)
-                mHeadsUpManager.releaseAllImmediately()
+                headsUpManager.releaseAllImmediately()
             }
         }
     }
@@ -562,12 +576,12 @@
     }
 
     private fun startVisibilityAnimation(increaseSpeed: Boolean) {
-        if (mNotificationVisibleAmount == 0f || mNotificationVisibleAmount == 1f) {
-            mVisibilityInterpolator =
-                if (mNotificationsVisible) Interpolators.TOUCH_RESPONSE
+        if (notificationVisibleAmount == 0f || notificationVisibleAmount == 1f) {
+            visibilityInterpolator =
+                if (notificationsVisible) Interpolators.TOUCH_RESPONSE
                 else Interpolators.FAST_OUT_SLOW_IN_REVERSE
         }
-        val target = if (mNotificationsVisible) 1.0f else 0.0f
+        val target = if (notificationsVisible) 1.0f else 0.0f
         val visibilityAnimator = ObjectAnimator.ofFloat(this, notificationVisibility, target)
         visibilityAnimator.interpolator = InterpolatorsAndroidX.LINEAR
         var duration = StackStateAnimator.ANIMATION_DURATION_WAKEUP.toLong()
@@ -576,34 +590,34 @@
         }
         visibilityAnimator.duration = duration
         visibilityAnimator.start()
-        mVisibilityAnimator = visibilityAnimator
+        this.visibilityAnimator = visibilityAnimator
     }
 
     private fun setVisibilityAmount(visibilityAmount: Float) {
         logger.logSetVisibilityAmount(visibilityAmount)
-        mLinearVisibilityAmount = visibilityAmount
-        mVisibilityAmount = mVisibilityInterpolator.getInterpolation(visibilityAmount)
+        linearVisibilityAmount = visibilityAmount
+        this.visibilityAmount = visibilityInterpolator.getInterpolation(visibilityAmount)
         handleAnimationFinished()
         updateHideAmount()
     }
 
     private fun handleAnimationFinished() {
-        if (outputLinearDozeAmount == 0.0f || mLinearVisibilityAmount == 0.0f) {
-            mEntrySetToClearWhenFinished.forEach { it.setHeadsUpAnimatingAway(false) }
-            mEntrySetToClearWhenFinished.clear()
+        if (outputLinearDozeAmount == 0.0f || linearVisibilityAmount == 0.0f) {
+            entrySetToClearWhenFinished.forEach { it.setHeadsUpAnimatingAway(false) }
+            entrySetToClearWhenFinished.clear()
         }
     }
 
     private fun updateHideAmount() {
-        val linearAmount = min(1.0f - mLinearVisibilityAmount, outputLinearDozeAmount)
-        val amount = min(1.0f - mVisibilityAmount, outputEasedDozeAmount)
+        val linearAmount = min(1.0f - linearVisibilityAmount, outputLinearDozeAmount)
+        val amount = min(1.0f - visibilityAmount, outputEasedDozeAmount)
         logger.logSetHideAmount(linearAmount)
-        mStackScrollerController.setHideAmount(linearAmount, amount)
+        stackScrollerController.setHideAmount(linearAmount, amount)
         notificationsFullyHidden = linearAmount == 1.0f
     }
 
     private fun notifyAnimationStart(awake: Boolean) {
-        mStackScrollerController.notifyHideAnimationStart(!awake)
+        stackScrollerController.notifyHideAnimationStart(!awake)
     }
 
     override fun onDozingChanged(isDozing: Boolean) {
@@ -615,7 +629,7 @@
     override fun onHeadsUpStateChanged(entry: NotificationEntry, isHeadsUp: Boolean) {
         var animate = shouldAnimateVisibility()
         if (!isHeadsUp) {
-            if (outputLinearDozeAmount != 0.0f && mLinearVisibilityAmount != 0.0f) {
+            if (outputLinearDozeAmount != 0.0f && linearVisibilityAmount != 0.0f) {
                 if (entry.isRowDismissed) {
                     // if we animate, we see the shelf briefly visible. Instead we fully animate
                     // the notification and its background out
@@ -623,11 +637,11 @@
                 } else if (!wakingUp && !willWakeUp) {
                     // TODO: look that this is done properly and not by anyone else
                     entry.setHeadsUpAnimatingAway(true)
-                    mEntrySetToClearWhenFinished.add(entry)
+                    entrySetToClearWhenFinished.add(entry)
                 }
             }
-        } else if (mEntrySetToClearWhenFinished.contains(entry)) {
-            mEntrySetToClearWhenFinished.remove(entry)
+        } else if (entrySetToClearWhenFinished.contains(entry)) {
+            entrySetToClearWhenFinished.remove(entry)
             entry.setHeadsUpAnimatingAway(false)
         }
         updateNotificationVisibility(animate, increaseSpeed = false)
@@ -644,11 +658,11 @@
         pw.println("hardDozeAmountOverrideSource: $hardDozeAmountOverrideSource")
         pw.println("outputLinearDozeAmount: $outputLinearDozeAmount")
         pw.println("outputEasedDozeAmount: $outputEasedDozeAmount")
-        pw.println("mNotificationVisibleAmount: $mNotificationVisibleAmount")
-        pw.println("mNotificationsVisible: $mNotificationsVisible")
-        pw.println("mNotificationsVisibleForExpansion: $mNotificationsVisibleForExpansion")
-        pw.println("mVisibilityAmount: $mVisibilityAmount")
-        pw.println("mLinearVisibilityAmount: $mLinearVisibilityAmount")
+        pw.println("notificationVisibleAmount: $notificationVisibleAmount")
+        pw.println("notificationsVisible: $notificationsVisible")
+        pw.println("notificationsVisibleForExpansion: $notificationsVisibleForExpansion")
+        pw.println("visibilityAmount: $visibilityAmount")
+        pw.println("linearVisibilityAmount: $linearVisibilityAmount")
         pw.println("pulseExpanding: $pulseExpanding")
         pw.println("state: ${StatusBarState.toString(state)}")
         pw.println("fullyAwake: $fullyAwake")
@@ -698,7 +712,7 @@
                 }
 
                 override fun get(coordinator: NotificationWakeUpCoordinator): Float {
-                    return coordinator.mLinearVisibilityAmount
+                    return coordinator.linearVisibilityAmount
                 }
             }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt
index 9619bea..752ec2d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt
@@ -182,6 +182,31 @@
         )
     }
 
+    fun logOnPanelExpansionChanged(
+        fraction: Float,
+        wasCollapsedEnoughToHide: Boolean,
+        isCollapsedEnoughToHide: Boolean,
+        couldShowPulsingHuns: Boolean,
+        canShowPulsingHuns: Boolean
+    ) {
+        buffer.log(
+            TAG,
+            DEBUG,
+            {
+                double1 = fraction.toDouble()
+                bool1 = wasCollapsedEnoughToHide
+                bool2 = isCollapsedEnoughToHide
+                bool3 = couldShowPulsingHuns
+                bool4 = canShowPulsingHuns
+            },
+            {
+                "onPanelExpansionChanged($double1):" +
+                    " collapsedEnoughToHide: $bool1 -> $bool2," +
+                    " canShowPulsingHuns: $bool3 -> $bool4"
+            }
+        )
+    }
+
     fun logSetWakingUp(wakingUp: Boolean, requestDelayedAnimation: Boolean) {
         buffer.log(
             TAG,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationClassificationFlag.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationClassificationFlag.kt
new file mode 100644
index 0000000..139347c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationClassificationFlag.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+
+import android.service.notification.Flags
+import com.android.systemui.flags.FlagToken
+import com.android.systemui.flags.RefactorFlagUtils
+
+/**
+ * Helper for android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION
+ */
+@Suppress("NOTHING_TO_INLINE")
+object NotificationClassificationFlag {
+    const val FLAG_NAME = Flags.FLAG_NOTIFICATION_CLASSIFICATION
+
+    /** A token used for dependency declaration */
+    val token: FlagToken
+        get() = FlagToken(FLAG_NAME, isEnabled)
+
+    /** Are sections sorted by time? */
+    @JvmStatic
+    inline val isEnabled
+        get() = Flags.notificationClassification()
+
+    /**
+     * Called to ensure code is only run when the flag is enabled. This protects users from the
+     * unintended behaviors caused by accidentally running new logic, while also crashing on an eng
+     * build to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun isUnexpectedlyInLegacyMode() =
+            RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+    /**
+     * Called to ensure code is only run when the flag is disabled. This will throw an exception if
+     * the flag is enabled to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_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 1adfef0..f98a88f 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
@@ -68,9 +68,11 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController;
 import com.android.systemui.statusbar.notification.row.NotificationGuts;
+import com.android.systemui.statusbar.notification.row.data.repository.NotificationRowRepository;
 import com.android.systemui.statusbar.notification.row.shared.HeadsUpStatusBarModel;
 import com.android.systemui.statusbar.notification.row.shared.NotificationContentModel;
 import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor;
+import com.android.systemui.statusbar.notification.row.shared.RichOngoingContentModel;
 import com.android.systemui.statusbar.notification.stack.PriorityBucket;
 import com.android.systemui.util.ListenerSet;
 
@@ -97,7 +99,7 @@
  * At the moment, there are many things here that shouldn't be and vice-versa. Hopefully we can
  * clean this up in the future.
  */
-public final class NotificationEntry extends ListEntry {
+public final class NotificationEntry extends ListEntry implements NotificationRowRepository {
 
     private final String mKey;
     private StatusBarNotification mSbn;
@@ -159,6 +161,8 @@
             StateFlowKt.MutableStateFlow(null);
     private final MutableStateFlow<CharSequence> mHeadsUpStatusBarTextPublic =
             StateFlowKt.MutableStateFlow(null);
+    private final MutableStateFlow<RichOngoingContentModel> mRichOngoingContentModel =
+            StateFlowKt.MutableStateFlow(null);
 
     // indicates when this entry's view was first attached to a window
     // this value will reset when the view is completely removed from the shade (ie: filtered out)
@@ -945,6 +949,7 @@
     }
 
     /** @see #setHeadsUpStatusBarText(CharSequence) */
+    @NonNull
     public StateFlow<CharSequence> getHeadsUpStatusBarText() {
         return mHeadsUpStatusBarText;
     }
@@ -959,10 +964,17 @@
     }
 
     /** @see #setHeadsUpStatusBarTextPublic(CharSequence) */
+    @NonNull
     public StateFlow<CharSequence> getHeadsUpStatusBarTextPublic() {
         return mHeadsUpStatusBarTextPublic;
     }
 
+    /** Gets the current RON content model, which may be null */
+    @NonNull
+    public StateFlow<RichOngoingContentModel> getRichOngoingContentModel() {
+        return mRichOngoingContentModel;
+    }
+
     /**
      * Sets the text to be displayed on the StatusBar, when this notification is the top pinned
      * heads up, and its content is sensitive right now.
@@ -1047,6 +1059,7 @@
         HeadsUpStatusBarModel headsUpStatusBarModel = contentModel.getHeadsUpStatusBarModel();
         this.mHeadsUpStatusBarText.setValue(headsUpStatusBarModel.getPrivateText());
         this.mHeadsUpStatusBarTextPublic.setValue(headsUpStatusBarModel.getPublicText());
+        this.mRichOngoingContentModel.setValue(contentModel.getRichOngoingContentModel());
     }
 
     /** Information about a suggestion that is being edited. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BundleCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BundleCoordinator.kt
new file mode 100644
index 0000000..244c594
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BundleCoordinator.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 android.app.NotificationChannel.NEWS_ID
+import android.app.NotificationChannel.PROMOTIONS_ID
+import android.app.NotificationChannel.RECS_ID
+import android.app.NotificationChannel.SOCIAL_MEDIA_ID
+import com.android.systemui.statusbar.notification.collection.ListEntry
+import com.android.systemui.statusbar.notification.collection.NotifPipeline
+import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
+import com.android.systemui.statusbar.notification.collection.render.NodeController
+import com.android.systemui.statusbar.notification.dagger.NewsHeader
+import com.android.systemui.statusbar.notification.dagger.PromoHeader
+import com.android.systemui.statusbar.notification.dagger.RecsHeader
+import com.android.systemui.statusbar.notification.dagger.SocialHeader
+import com.android.systemui.statusbar.notification.stack.BUCKET_NEWS
+import com.android.systemui.statusbar.notification.stack.BUCKET_PROMO
+import com.android.systemui.statusbar.notification.stack.BUCKET_RECS
+import com.android.systemui.statusbar.notification.stack.BUCKET_SOCIAL
+import javax.inject.Inject
+
+/**
+ * Coordinator for sections derived from NotificationAssistantService classification.
+ */
+@CoordinatorScope
+class BundleCoordinator @Inject constructor(
+    @NewsHeader private val newsHeaderController: NodeController,
+    @SocialHeader private val socialHeaderController: NodeController,
+    @RecsHeader private val recsHeaderController: NodeController,
+    @PromoHeader private val promoHeaderController: NodeController,
+) : Coordinator {
+
+    val newsSectioner =
+            object : NotifSectioner("News", BUCKET_NEWS) {
+                override fun isInSection(entry: ListEntry): Boolean {
+                    return entry.representativeEntry?.channel?.id == NEWS_ID
+                }
+
+                override fun getHeaderNodeController(): NodeController? {
+                    return newsHeaderController
+                }
+            }
+
+    val socialSectioner =
+        object : NotifSectioner("Social", BUCKET_SOCIAL) {
+            override fun isInSection(entry: ListEntry): Boolean {
+                return entry.representativeEntry?.channel?.id == SOCIAL_MEDIA_ID
+            }
+
+            override fun getHeaderNodeController(): NodeController? {
+                return socialHeaderController
+            }
+        }
+
+    val recsSectioner =
+        object : NotifSectioner("Recommendations", BUCKET_RECS) {
+            override fun isInSection(entry: ListEntry): Boolean {
+                return entry.representativeEntry?.channel?.id == RECS_ID
+            }
+
+            override fun getHeaderNodeController(): NodeController? {
+                return recsHeaderController
+            }
+        }
+
+    val promoSectioner =
+        object : NotifSectioner("Promotions", BUCKET_PROMO) {
+            override fun isInSection(entry: ListEntry): Boolean {
+                return entry.representativeEntry?.channel?.id == PROMOTIONS_ID
+            }
+
+            override fun getHeaderNodeController(): NodeController? {
+                return promoHeaderController
+            }
+        }
+
+    override fun attach(pipeline: NotifPipeline) {
+    }
+}
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 f98f77e..aff57bd 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
@@ -40,6 +40,7 @@
 import com.android.systemui.statusbar.notification.interruption.HeadsUpViewBinder
 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider
 import com.android.systemui.statusbar.notification.logKey
+import com.android.systemui.statusbar.notification.shared.GroupHunAnimationFix
 import com.android.systemui.statusbar.notification.stack.BUCKET_HEADS_UP
 import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
@@ -726,6 +727,12 @@
      */
     private fun isAttemptingToShowHun(entry: ListEntry) =
         mHeadsUpManager.isHeadsUpEntry(entry.key) || isEntryBinding(entry)
+                || isHeadsUpAnimatingAway(entry)
+
+    private fun isHeadsUpAnimatingAway(entry: ListEntry): Boolean {
+        if (!GroupHunAnimationFix.isEnabled) return false
+        return entry.representativeEntry?.row?.isHeadsUpAnimatingAway ?: false
+    }
 
     /**
      * Whether the notification is already heads up/binding per [isAttemptingToShowHun] OR if it
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
index 5a1146d..55c6790 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
 package com.android.systemui.statusbar.notification.collection.coordinator
 
 import android.app.NotificationManager
@@ -27,9 +25,10 @@
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.keyguard.data.repository.KeyguardRepository
-import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.expansionChanges
 import com.android.systemui.statusbar.notification.collection.GroupEntry
@@ -58,7 +57,6 @@
 import kotlin.time.Duration.Companion.seconds
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.delay
@@ -89,7 +87,7 @@
     private val headsUpManager: HeadsUpManager,
     private val keyguardNotificationVisibilityProvider: KeyguardNotificationVisibilityProvider,
     private val keyguardRepository: KeyguardRepository,
-    private val keyguardTransitionRepository: KeyguardTransitionRepository,
+    private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
     private val logger: KeyguardCoordinatorLogger,
     @Application private val scope: CoroutineScope,
     private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider,
@@ -126,8 +124,12 @@
     private suspend fun trackSeenNotifications() {
         // Whether or not keyguard is visible (or occluded).
         val isKeyguardPresent: Flow<Boolean> =
-            keyguardTransitionRepository.transitions
-                .map { step -> step.to != KeyguardState.GONE }
+            keyguardTransitionInteractor
+                .transitionValue(
+                    scene = Scenes.Gone,
+                    stateWithoutSceneContainer = KeyguardState.GONE,
+                )
+                .map { it == 0f }
                 .distinctUntilChanged()
                 .onEach { trackingUnseen -> logger.logTrackingUnseen(trackingUnseen) }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
index e413522..e038982 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
@@ -17,10 +17,7 @@
 
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED
-import com.android.systemui.statusbar.notification.collection.NotifPipeline
-import com.android.systemui.statusbar.notification.collection.PipelineDumpable
-import com.android.systemui.statusbar.notification.collection.PipelineDumper
-import com.android.systemui.statusbar.notification.collection.SortBySectionTimeFlag
+import com.android.systemui.statusbar.notification.collection.*
 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
 import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
@@ -69,6 +66,7 @@
     dismissibilityCoordinator: DismissibilityCoordinator,
     dreamCoordinator: DreamCoordinator,
     statsLoggerCoordinator: NotificationStatsLoggerCoordinator,
+    bundleCoordinator: BundleCoordinator,
 ) : NotifCoordinators {
 
     private val mCoreCoordinators: MutableList<CoreCoordinator> = ArrayList()
@@ -132,6 +130,12 @@
             mOrderedSections.add(conversationCoordinator.peopleSilentSectioner) // People Silent
         }
         mOrderedSections.add(rankingCoordinator.alertingSectioner) // Alerting
+        if (NotificationClassificationFlag.isEnabled) {
+            mOrderedSections.add(bundleCoordinator.newsSectioner);
+            mOrderedSections.add(bundleCoordinator.socialSectioner);
+            mOrderedSections.add(bundleCoordinator.recsSectioner);
+            mOrderedSections.add(bundleCoordinator.promoSectioner);
+        }
         mOrderedSections.add(rankingCoordinator.silentSectioner) // Silent
         mOrderedSections.add(rankingCoordinator.minimizedSectioner) // Minimized
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProvider.kt
index 5adf31b..f166d32 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProvider.kt
@@ -13,12 +13,18 @@
     /** The subset of active listeners which are temporary (will be removed after called) */
     private val temporaryListeners = ArraySet<OnReorderingAllowedListener>()
 
+    private val banListeners = ListenerSet<OnReorderingBannedListener>()
+
     var isReorderingAllowed = true
         set(value) {
             if (field != value) {
                 field = value
                 if (value) {
                     notifyReorderingAllowed()
+                } else {
+                    banListeners.forEach { listener ->
+                        listener.onReorderingBanned()
+                    }
                 }
             }
         }
@@ -38,6 +44,10 @@
         allListeners.addIfAbsent(listener)
     }
 
+    fun addPersistentReorderingBannedListener(listener: OnReorderingBannedListener) {
+        banListeners.addIfAbsent(listener)
+    }
+
     /** Add a listener which will be removed when it is called. */
     fun addTemporaryReorderingAllowedListener(listener: OnReorderingAllowedListener) {
         // Only add to the temporary set if it was added to the global set
@@ -57,3 +67,8 @@
 fun interface OnReorderingAllowedListener {
     fun onReorderingAllowed()
 }
+
+fun interface OnReorderingBannedListener {
+    fun onReorderingBanned()
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt
index ca43591..e661090 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt
@@ -80,6 +80,50 @@
             .build()
 
     @Provides
+    @NewsHeader
+    @SysUISingleton
+    @JvmStatic fun providesNewsHeaderSubcomponent(
+        builder: Provider<SectionHeaderControllerSubcomponent.Builder>
+    ) = builder.get()
+        .nodeLabel("news header")
+        .headerText(com.android.internal.R.string.news_notification_channel_label)
+        .clickIntentAction(Settings.ACTION_NOTIFICATION_SETTINGS)
+        .build()
+
+    @Provides
+    @SocialHeader
+    @SysUISingleton
+    @JvmStatic fun providesSocialHeaderSubcomponent(
+        builder: Provider<SectionHeaderControllerSubcomponent.Builder>
+    ) = builder.get()
+        .nodeLabel("social header")
+        .headerText(com.android.internal.R.string.social_notification_channel_label)
+        .clickIntentAction(Settings.ACTION_NOTIFICATION_SETTINGS)
+        .build()
+
+    @Provides
+    @RecsHeader
+    @SysUISingleton
+    @JvmStatic fun providesRecsHeaderSubcomponent(
+        builder: Provider<SectionHeaderControllerSubcomponent.Builder>
+    ) = builder.get()
+        .nodeLabel("recs header")
+        .headerText(com.android.internal.R.string.recs_notification_channel_label)
+        .clickIntentAction(Settings.ACTION_NOTIFICATION_SETTINGS)
+        .build()
+
+    @Provides
+    @PromoHeader
+    @SysUISingleton
+    @JvmStatic fun providesPromoHeaderSubcomponent(
+        builder: Provider<SectionHeaderControllerSubcomponent.Builder>
+    ) = builder.get()
+        .nodeLabel("promo header")
+        .headerText(com.android.internal.R.string.promotional_notification_channel_label)
+        .clickIntentAction(Settings.ACTION_NOTIFICATION_SETTINGS)
+        .build()
+
+    @Provides
     @SilentHeader
     @JvmStatic fun providesSilentHeaderNodeController(
         @SilentHeader subcomponent: SectionHeaderControllerSubcomponent
@@ -126,6 +170,54 @@
     @JvmStatic fun providesIncomingHeaderController(
         @IncomingHeader subcomponent: SectionHeaderControllerSubcomponent
     ) = subcomponent.headerController
+
+    @Provides
+    @NewsHeader
+    @JvmStatic fun providesNewsHeaderNodeController(
+        @NewsHeader subcomponent: SectionHeaderControllerSubcomponent
+    ) = subcomponent.nodeController
+
+    @Provides
+    @NewsHeader
+    @JvmStatic fun providesNewsHeaderController(
+        @NewsHeader subcomponent: SectionHeaderControllerSubcomponent
+    ) = subcomponent.headerController
+
+    @Provides
+    @SocialHeader
+    @JvmStatic fun providesSocialHeaderNodeController(
+        @SocialHeader subcomponent: SectionHeaderControllerSubcomponent
+    ) = subcomponent.nodeController
+
+    @Provides
+    @SocialHeader
+    @JvmStatic fun providesSocialHeaderController(
+        @SocialHeader subcomponent: SectionHeaderControllerSubcomponent
+    ) = subcomponent.headerController
+
+    @Provides
+    @RecsHeader
+    @JvmStatic fun providesRecsHeaderNodeController(
+        @RecsHeader subcomponent: SectionHeaderControllerSubcomponent
+    ) = subcomponent.nodeController
+
+    @Provides
+    @RecsHeader
+    @JvmStatic fun providesRecsHeaderController(
+        @RecsHeader subcomponent: SectionHeaderControllerSubcomponent
+    ) = subcomponent.headerController
+
+    @Provides
+    @PromoHeader
+    @JvmStatic fun providesPromoHeaderNodeController(
+        @PromoHeader subcomponent: SectionHeaderControllerSubcomponent
+    ) = subcomponent.nodeController
+
+    @Provides
+    @PromoHeader
+    @JvmStatic fun providesPromoHeaderController(
+        @PromoHeader subcomponent: SectionHeaderControllerSubcomponent
+    ) = subcomponent.headerController
 }
 
 @Subcomponent(modules = [ SectionHeaderBindingModule::class ])
@@ -183,3 +275,19 @@
 @Scope
 @Retention(AnnotationRetention.BINARY)
 annotation class SectionHeaderScope
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+annotation class NewsHeader
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+annotation class SocialHeader
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+annotation class RecsHeader
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+annotation class PromoHeader
\ No newline at end of file
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 91bb28e..b63ee4c 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
@@ -18,12 +18,13 @@
 
 import android.app.NotificationManager;
 import android.content.Context;
+import android.os.Handler;
 import android.service.notification.NotificationListenerService;
 
 import com.android.internal.jank.InteractionJankMonitor;
-import com.android.settingslib.statusbar.notification.data.repository.NotificationsSoundPolicyRepository;
-import com.android.settingslib.statusbar.notification.data.repository.NotificationsSoundPolicyRepositoryImpl;
-import com.android.settingslib.statusbar.notification.domain.interactor.NotificationsSoundPolicyInteractor;
+import com.android.settingslib.notification.data.repository.ZenModeRepository;
+import com.android.settingslib.notification.data.repository.ZenModeRepositoryImpl;
+import com.android.settingslib.notification.domain.interactor.NotificationsSoundPolicyInteractor;
 import com.android.systemui.CoreStartable;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Application;
@@ -279,19 +280,21 @@
 
     @Provides
     @SysUISingleton
-    public static NotificationsSoundPolicyRepository provideNotificationsSoundPolicyRepository(
+    static ZenModeRepository provideZenModeRepository(
             Context context,
             NotificationManager notificationManager,
             @Application CoroutineScope coroutineScope,
-            @Background CoroutineContext coroutineContext) {
-        return new NotificationsSoundPolicyRepositoryImpl(context, notificationManager,
-                coroutineScope, coroutineContext);
+            @Background CoroutineContext coroutineContext,
+            @Background Handler handler
+    ) {
+        return new ZenModeRepositoryImpl(context, notificationManager,
+                coroutineScope, coroutineContext, handler);
     }
 
     @Provides
     @SysUISingleton
-    public static NotificationsSoundPolicyInteractor provideNotificationsSoundPolicyInteractror(
-            NotificationsSoundPolicyRepository repository) {
+    static NotificationsSoundPolicyInteractor provideNotificationsSoundPolicyInteractor(
+            ZenModeRepository repository) {
         return new NotificationsSoundPolicyInteractor(repository);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRepository.kt
index e9306a5..069ae93 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/data/repository/HeadsUpRepository.kt
@@ -41,4 +41,7 @@
     val activeHeadsUpRows: Flow<Set<HeadsUpRowRepository>>
 
     fun setHeadsUpAnimatingAway(animatingAway: Boolean)
+
+    /** Snooze the currently pinned HUN. */
+    fun snooze()
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
index 4a6553f..eebbb13 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-@file:OptIn(ExperimentalCoroutinesApi::class)
+@file:OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class)
 
 package com.android.systemui.statusbar.notification.domain.interactor
 
@@ -27,11 +27,15 @@
 import com.android.systemui.statusbar.notification.shared.HeadsUpRowKey
 import javax.inject.Inject
 import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.FlowPreview
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.debounce
+import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onStart
 
 class HeadsUpNotificationInteractor
 @Inject
@@ -73,10 +77,21 @@
 
     val isHeadsUpOrAnimatingAway: Flow<Boolean> =
         combine(hasPinnedRows, headsUpRepository.isHeadsUpAnimatingAway) {
-            hasPinnedRows,
-            animatingAway ->
-            hasPinnedRows || animatingAway
-        }
+                hasPinnedRows,
+                animatingAway ->
+                hasPinnedRows || animatingAway
+            }
+            .debounce { isHeadsUpOrAnimatingAway ->
+                if (isHeadsUpOrAnimatingAway) {
+                    0
+                } else {
+                    // When the last pinned entry is removed from the [HeadsUpRepository],
+                    // there might be a delay before the View starts animating.
+                    50L
+                }
+            }
+            .onStart { emit(false) } // emit false, so we don't wait for the initial update
+            .distinctUntilChanged()
 
     private val canShowHeadsUp: Flow<Boolean> =
         combine(
@@ -101,10 +116,17 @@
 
     fun headsUpRow(key: HeadsUpRowKey): HeadsUpRowInteractor =
         HeadsUpRowInteractor(key as HeadsUpRowRepository)
+
     fun elementKeyFor(key: HeadsUpRowKey) = (key as HeadsUpRowRepository).elementKey
+
     fun setHeadsUpAnimatingAway(animatingAway: Boolean) {
         headsUpRepository.setHeadsUpAnimatingAway(animatingAway)
     }
+
+    /** Snooze the currently pinned HUN. */
+    fun snooze() {
+        headsUpRepository.snooze()
+    }
 }
 
 class HeadsUpRowInteractor(repository: HeadsUpRowRepository)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt
index 367aaad..e04e0fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/CommonVisualInterruptionSuppressors.kt
@@ -22,19 +22,27 @@
 import android.app.Notification.CATEGORY_EVENT
 import android.app.Notification.CATEGORY_REMINDER
 import android.app.Notification.VISIBILITY_PRIVATE
+import android.app.NotificationManager
 import android.app.NotificationManager.IMPORTANCE_DEFAULT
 import android.app.NotificationManager.IMPORTANCE_HIGH
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
 import android.content.pm.PackageManager
 import android.content.pm.PackageManager.PERMISSION_GRANTED
 import android.database.ContentObserver
 import android.hardware.display.AmbientDisplayConfiguration
+import android.os.Bundle
 import android.os.Handler
 import android.os.PowerManager
+import android.os.SystemProperties
 import android.provider.Settings
 import android.provider.Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED
 import android.provider.Settings.Global.HEADS_UP_OFF
+import android.service.notification.Flags
 import com.android.internal.logging.UiEvent
 import com.android.internal.logging.UiEventLogger
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.settings.UserTracker
@@ -47,6 +55,7 @@
 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PULSE
 import com.android.systemui.statusbar.policy.BatteryController
 import com.android.systemui.statusbar.policy.HeadsUpManager
+import com.android.systemui.util.NotificationChannels
 import com.android.systemui.util.settings.GlobalSettings
 import com.android.systemui.util.settings.SystemSettings
 import com.android.systemui.util.time.SystemClock
@@ -213,6 +222,15 @@
         entry.sbn.let { it.isGroup && it.notification.suppressAlertingDueToGrouping() }
 }
 
+class HunSilentNotificationSuppressor() :
+    VisualInterruptionFilter(
+        types = setOf(PEEK, PULSE),
+        reason = "notification isSilent"
+    ) {
+    override fun shouldSuppress(entry: NotificationEntry) =
+        entry.sbn.let { Flags.notificationSilentFlag() && it.notification.isSilent }
+}
+
 class HunJustLaunchedFsiSuppressor() :
     VisualInterruptionFilter(types = setOf(PEEK, PULSE), reason = "just launched FSI") {
     override fun shouldSuppress(entry: NotificationEntry) = entry.hasJustLaunchedFullScreenIntent()
@@ -244,12 +262,22 @@
         keyguardNotificationVisibilityProvider.shouldHideNotification(entry)
 }
 
+/**
+ * Set with:
+ * adb shell setprop persist.force_show_avalanche_edu_once 1 && adb shell stop; adb shell start
+ */
+private const val FORCE_SHOW_AVALANCHE_EDU_ONCE = "persist.force_show_avalanche_edu_once"
+
+private const val PREF_HAS_SEEN_AVALANCHE_EDU = "has_seen_avalanche_edu"
+
 class AvalancheSuppressor(
     private val avalancheProvider: AvalancheProvider,
     private val systemClock: SystemClock,
     private val systemSettings: SystemSettings,
     private val packageManager: PackageManager,
     private val uiEventLogger: UiEventLogger,
+    private val context: Context,
+    private val notificationManager: NotificationManager
 ) :
     VisualInterruptionFilter(
         types = setOf(PEEK, PULSE),
@@ -257,6 +285,24 @@
     ) {
     val TAG = "AvalancheSuppressor"
 
+    private val prefs = context.getSharedPreferences(context.packageName, Context.MODE_PRIVATE)
+
+    // SharedPreferences are persisted across reboots
+    var hasSeenEdu: Boolean
+        get() = prefs.getBoolean(PREF_HAS_SEEN_AVALANCHE_EDU, false)
+        set(value) = prefs.edit().putBoolean(PREF_HAS_SEEN_AVALANCHE_EDU, value).apply()
+
+    // Reset on reboot.
+    // The pipeline runs these suppressors many times very fast, so we must use a separate bool
+    // to force show for debug so that phone does not get stuck sending out infinite number of
+    // education HUNs.
+    private var hasShownOnceForDebug = false
+
+    private fun shouldShowEdu() : Boolean {
+        val forceShowOnce = SystemProperties.get(FORCE_SHOW_AVALANCHE_EDU_ONCE, "").equals("1")
+        return !hasSeenEdu || (forceShowOnce && !hasShownOnceForDebug)
+    }
+
     enum class State {
         ALLOW_CONVERSATION_AFTER_AVALANCHE,
         ALLOW_HIGH_PRIORITY_CONVERSATION_ANY_TIME,
@@ -309,9 +355,53 @@
         if (state != State.SUPPRESS) {
             return false
         }
+        if (shouldShowEdu()) {
+            showEdu()
+        }
         return true
     }
 
+    /**
+     * Show avalanche education HUN from SystemUI.
+     */
+    private fun showEdu() {
+        val res = context.resources
+        val titleStr = res.getString(
+            com.android.systemui.res.R.string.adaptive_notification_edu_hun_title)
+        val textStr = res.getString(
+            com.android.systemui.res.R.string.adaptive_notification_edu_hun_text)
+        val actionStr = res.getString(
+            com.android.systemui.res.R.string.go_to_adaptive_notification_settings)
+
+        val intent = Intent(Settings.ACTION_MANAGE_ADAPTIVE_NOTIFICATIONS)
+        val pendingIntent = PendingIntent.getActivity(
+            context, 0, intent,
+            PendingIntent.FLAG_IMMUTABLE
+        )
+
+        // Replace "System UI" app name with "Android System"
+        val bundle = Bundle()
+        bundle.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
+                context.getString(com.android.internal.R.string.android_system_label))
+
+        val builder =
+            Notification.Builder(context, NotificationChannels.ALERTS)
+                .setTicker(titleStr)
+                .setContentTitle(titleStr)
+                .setContentText(textStr)
+                .setSmallIcon(com.android.systemui.res.R.drawable.ic_settings)
+                .setCategory(Notification.CATEGORY_SYSTEM)
+                .setTimeoutAfter(/* one day in ms */ 24 * 60 * 60 * 1000L)
+                .setAutoCancel(true)
+                .addAction(android.R.drawable.button_onoff_indicator_off, actionStr, pendingIntent)
+                .setContentIntent(pendingIntent)
+                .addExtras(bundle)
+
+        notificationManager.notify(SystemMessage.NOTE_ADAPTIVE_NOTIFICATIONS, builder.build())
+        hasSeenEdu = true
+        hasShownOnceForDebug = true;
+    }
+
     private fun calculateState(entry: NotificationEntry): State {
         if (
             entry.ranking.isConversation &&
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/FullScreenIntentDecisionProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/FullScreenIntentDecisionProvider.kt
index b77748e..576c7ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/FullScreenIntentDecisionProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/FullScreenIntentDecisionProvider.kt
@@ -39,6 +39,7 @@
 import com.android.systemui.statusbar.notification.interruption.FullScreenIntentDecisionProvider.DecisionImpl.NO_FSI_SUPPRESSED_ONLY_BY_DND
 import com.android.systemui.statusbar.notification.interruption.FullScreenIntentDecisionProvider.DecisionImpl.NO_FSI_SUPPRESSIVE_BUBBLE_METADATA
 import com.android.systemui.statusbar.notification.interruption.FullScreenIntentDecisionProvider.DecisionImpl.NO_FSI_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR
+import com.android.systemui.statusbar.notification.interruption.FullScreenIntentDecisionProvider.DecisionImpl.NO_FSI_SUPPRESSIVE_SILENT_NOTIFICATION
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.FSI_SUPPRESSED_NO_HUN_OR_KEYGUARD
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.FSI_SUPPRESSED_SUPPRESSIVE_BUBBLE_METADATA
 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl.NotificationInterruptEvent.FSI_SUPPRESSED_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR
@@ -94,6 +95,7 @@
             uiEventId = FSI_SUPPRESSED_SUPPRESSIVE_BUBBLE_METADATA,
             eventLogData = EventLogData("274759612", "bubbleMetadata")
         ),
+        NO_FSI_SUPPRESSIVE_SILENT_NOTIFICATION(false, "suppressive setSilent notification"),
         NO_FSI_PACKAGE_SUSPENDED(false, "package suspended"),
         FSI_DEVICE_NOT_INTERACTIVE(true, "device is not interactive"),
         FSI_DEVICE_DREAMING(true, "device is dreaming"),
@@ -154,6 +156,12 @@
             return NO_FSI_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR
         }
 
+        if (android.service.notification.Flags.notificationSilentFlag()) {
+            if (sbn.notification.isSilent) {
+                return NO_FSI_SUPPRESSIVE_SILENT_NOTIFICATION
+            }
+        }
+
         val bubbleMetadata = notification.bubbleMetadata
         if (bubbleMetadata != null && bubbleMetadata.isNotificationSuppressed) {
             return NO_FSI_SUPPRESSIVE_BUBBLE_METADATA
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 a2f97bd..e9efa56 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
@@ -193,6 +193,14 @@
         })
     }
 
+    fun logNoAlertingSilentNotification(entry: NotificationEntry) {
+        buffer.log(TAG, DEBUG, {
+            str1 = entry.logKey
+        }, {
+            "No alerting: suppressed due to silent notification: $str1"
+        })
+    }
+
     fun logNoAlertingSuppressedBy(
         entry: NotificationEntry,
         suppressor: NotificationInterruptSuppressor,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java
index c084482..2b02790 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java
@@ -67,6 +67,11 @@
          */
         NO_FSI_SUPPRESSIVE_BUBBLE_METADATA(false),
         /**
+         * Notification should not FSI due to being explicitly silent.
+         * see {@link android.app.Notification#isSilent}
+         */
+        NO_FSI_SUPPRESSIVE_SILENT_NOTIFICATION(false),
+        /**
          * Device screen is off, so the FSI should launch.
          */
         FSI_DEVICE_NOT_INTERACTIVE(true),
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 fea360d..450067a 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
@@ -295,8 +295,17 @@
             // 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.
             return getDecisionGivenSuppression(
-                    FullScreenIntentDecision.NO_FSI_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR,
+                FullScreenIntentDecision.NO_FSI_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR,
+                suppressedByDND);
+        }
+
+        // If the notification is explicitly silent, block FSI and warn.
+        if (android.service.notification.Flags.notificationSilentFlag()) {
+            if (sbn.getNotification().isSilent()) {
+                return getDecisionGivenSuppression(
+                    FullScreenIntentDecision.NO_FSI_SUPPRESSIVE_SILENT_NOTIFICATION,
                     suppressedByDND);
+            }
         }
 
         // If the notification has suppressive BubbleMetadata, block FSI and warn.
@@ -587,8 +596,18 @@
         StatusBarNotification sbn = entry.getSbn();
 
         // Don't alert notifications that are suppressed due to group alert behavior
+        if (android.service.notification.Flags.notificationSilentFlag()) {
+            if (sbn.getNotification().isSilent()) {
+                if (log) {
+                    mLogger.logNoAlertingSilentNotification(entry);
+                }
+                return false;
+            }
+        }
+
         if (sbn.isGroup() && sbn.getNotification().suppressAlertingDueToGrouping()) {
-            if (log) mLogger.logNoAlertingGroupAlertBehavior(entry);
+            if (log)
+                mLogger.logNoAlertingGroupAlertBehavior(entry);
             return false;
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt
index 84f8662..1c476ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImpl.kt
@@ -15,6 +15,8 @@
  */
 package com.android.systemui.statusbar.notification.interruption
 
+import android.app.NotificationManager
+import android.content.Context
 import android.content.pm.PackageManager
 import android.hardware.display.AmbientDisplayConfiguration
 import android.os.Handler
@@ -68,7 +70,9 @@
     private val avalancheProvider: AvalancheProvider,
     private val systemSettings: SystemSettings,
     private val packageManager: PackageManager,
-    private val bubbles: Optional<Bubbles>
+    private val bubbles: Optional<Bubbles>,
+    private val context: Context,
+    private val notificationManager: NotificationManager
 ) : VisualInterruptionDecisionProvider {
 
     init {
@@ -172,6 +176,7 @@
         addFilter(BubbleNotAllowedSuppressor())
         addFilter(BubbleNoMetadataSuppressor())
         addFilter(HunGroupAlertBehaviorSuppressor())
+        addFilter(HunSilentNotificationSuppressor())
         addFilter(HunJustLaunchedFsiSuppressor())
         addFilter(AlertAppSuspendedSuppressor())
         addFilter(AlertKeyguardVisibilitySuppressor(keyguardNotificationVisibilityProvider))
@@ -179,7 +184,7 @@
         if (NotificationAvalancheSuppression.isEnabled) {
             addFilter(
                 AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
-                        uiEventLogger)
+                        uiEventLogger, context, notificationManager)
             )
             avalancheProvider.register()
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLogger.java
index 9e0dd8fc..1755123 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationPanelLogger.java
@@ -20,9 +20,13 @@
 import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_FOREGROUND_SERVICE;
 import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_HEADS_UP;
 import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_MEDIA_CONTROLS;
+import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_NEWS;
 import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_PEOPLE;
 import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_PRIORITY_PEOPLE;
+import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_PROMO;
+import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_RECS;
 import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_SILENT;
+import static com.android.systemui.statusbar.notification.stack.NotificationPriorityBucketKt.BUCKET_SOCIAL;
 
 import android.annotation.Nullable;
 import android.service.notification.StatusBarNotification;
@@ -135,6 +139,10 @@
                 return Notifications.Notification.SECTION_PEOPLE;
             case BUCKET_ALERTING: return Notifications.Notification.SECTION_ALERTING;
             case BUCKET_SILENT: return Notifications.Notification.SECTION_SILENT;
+            case BUCKET_NEWS: return Notifications.Notification.SECTION_NEWS;
+            case BUCKET_SOCIAL: return Notifications.Notification.SECTION_SOCIAL;
+            case BUCKET_RECS: return Notifications.Notification.SECTION_RECS;
+            case BUCKET_PROMO: return Notifications.Notification.SECTION_PROMO;
         }
         return Notifications.Notification.SECTION_UNKNOWN;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/Notifications.proto b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/Notifications.proto
index c2ab275..ce4356a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/Notifications.proto
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/Notifications.proto
@@ -43,6 +43,13 @@
         SECTION_ALERTING = 4;
         SECTION_SILENT = 5;
         SECTION_FOREGROUND_SERVICE = 6;
+        SECTION_PRIORITY_PEOPLE = 7;
+        SECTION_TOP_ONGOING = 8;
+        SECTION_TOP_UNSEEN = 9;
+        SECTION_NEWS = 10;
+        SECTION_SOCIAL = 11;
+        SECTION_RECS = 12;
+        SECTION_PROMO = 13;
     }
     optional NotificationSection section = 6;
 }
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 190a2cd..9e943ee 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
@@ -104,6 +104,7 @@
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationCompactMessagingTemplateViewWrapper;
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
 import com.android.systemui.statusbar.notification.shared.NotificationContentAlphaOptimization;
+import com.android.systemui.statusbar.notification.shared.TransparentHeaderFix;
 import com.android.systemui.statusbar.notification.stack.AmbientState;
 import com.android.systemui.statusbar.notification.stack.AnimationProperties;
 import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
@@ -111,6 +112,7 @@
 import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.SwipeableView;
+import com.android.systemui.statusbar.phone.ExpandHeadsUpOnInlineReply;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.InflatedSmartReplyState;
@@ -328,38 +330,61 @@
     private OnClickListener mExpandClickListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
-            if (!shouldShowPublic() && (!mIsMinimized || isExpanded())
-                    && mGroupMembershipManager.isGroupSummary(mEntry)) {
-                mGroupExpansionChanging = true;
-                final boolean wasExpanded = mGroupExpansionManager.isGroupExpanded(mEntry);
-                boolean nowExpanded = mGroupExpansionManager.toggleGroupExpansion(mEntry);
-                mOnExpandClickListener.onExpandClicked(mEntry, v, nowExpanded);
+            toggleExpansionState(v, /* shouldLogExpandClickMetric = */true);
+        }
+    };
+
+    /**
+     * Toggles expansion state.
+     */
+    public void toggleExpansionState() {
+        toggleExpansionState(this, /*shouldLogExpandClickMetric*/ false);
+    }
+
+    private void toggleExpansionState(View v, boolean shouldLogExpandClickMetric) {
+        if (!shouldShowPublic() && (!mIsMinimized || isExpanded())
+                && mGroupMembershipManager.isGroupSummary(mEntry)) {
+            mGroupExpansionChanging = true;
+            final boolean wasExpanded = mGroupExpansionManager.isGroupExpanded(mEntry);
+            boolean nowExpanded = mGroupExpansionManager.toggleGroupExpansion(mEntry);
+            mOnExpandClickListener.onExpandClicked(mEntry, v, nowExpanded);
+            if (shouldLogExpandClickMetric) {
                 mMetricsLogger.action(MetricsEvent.ACTION_NOTIFICATION_GROUP_EXPANDER, nowExpanded);
-                onExpansionChanged(true /* userAction */, wasExpanded);
-            } else if (mEnableNonGroupedNotificationExpand) {
-                if (v.isAccessibilityFocused()) {
-                    mPrivateLayout.setFocusOnVisibilityChange();
+            }
+            onExpansionChanged(true /* userAction */, wasExpanded);
+        } else if (mEnableNonGroupedNotificationExpand) {
+            if (v.isAccessibilityFocused()) {
+                mPrivateLayout.setFocusOnVisibilityChange();
+            }
+            boolean nowExpanded;
+            if (isPinned()) {
+                nowExpanded = !mExpandedWhenPinned;
+                mExpandedWhenPinned = nowExpanded;
+                // Also notify any expansion changed listeners. This is necessary since the
+                // expansion doesn't actually change (it's already system expanded) but it
+                // changes visually
+                if (mExpansionChangedListener != null) {
+                    mExpansionChangedListener.onExpansionChanged(nowExpanded);
                 }
-                boolean nowExpanded;
-                if (isPinned()) {
-                    nowExpanded = !mExpandedWhenPinned;
-                    mExpandedWhenPinned = nowExpanded;
-                    // Also notify any expansion changed listeners. This is necessary since the
-                    // expansion doesn't actually change (it's already system expanded) but it
-                    // changes visually
-                    if (mExpansionChangedListener != null) {
-                        mExpansionChangedListener.onExpansionChanged(nowExpanded);
-                    }
-                } else {
-                    nowExpanded = !isExpanded();
-                    setUserExpanded(nowExpanded);
-                }
-                notifyHeightChanged(/* needsAnimation= */ true);
-                mOnExpandClickListener.onExpandClicked(mEntry, v, nowExpanded);
+            } else {
+                nowExpanded = !isExpanded();
+                setUserExpanded(nowExpanded);
+            }
+
+            if (ExpandHeadsUpOnInlineReply.isEnabled() && mExpandable) {
+                // it is triggered by the user.
+                // So, mHasUserChangedExpansion should be marked true.
+                mHasUserChangedExpansion = true;
+            }
+
+            notifyHeightChanged(/* needsAnimation= */ true);
+            mOnExpandClickListener.onExpandClicked(mEntry, v, nowExpanded);
+            if (shouldLogExpandClickMetric) {
                 mMetricsLogger.action(MetricsEvent.ACTION_NOTIFICATION_EXPANDER, nowExpanded);
             }
         }
-    };
+    }
+
     private boolean mKeepInParentForDismissAnimation;
     private boolean mRemoved;
     public static final FloatProperty<ExpandableNotificationRow> TRANSLATE_CONTENT =
@@ -1560,6 +1585,9 @@
                 /* headerView= */ headerView,
                 /* onClickListener= */ mExpandClickListener
         );
+        if (TransparentHeaderFix.isEnabled()) {
+            updateBackgroundForGroupState();
+        }
     }
 
     /**
@@ -2011,6 +2039,21 @@
         };
     }
 
+    /**
+     * Retrieves an OnClickListener for the close button of a notification, which when invoked,
+     * dismisses the notificationc represented by the given ExpandableNotificationRow.
+     *
+     * @param row The ExpandableNotificationRow representing the notification to be dismissed.
+     * @return An OnClickListener instance that dismisses the notification(s) when invoked.
+     */
+    public View.OnClickListener getCloseButtonOnClickListener(ExpandableNotificationRow row) {
+        return v -> {
+            if (row != null) {
+                row.performDismiss(false);
+            }
+        };
+    }
+
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         Trace.beginSection(appendTraceStyleTag("ExpNotRow#onMeasure"));
@@ -2830,9 +2873,18 @@
     }
 
     public boolean isExpanded(boolean allowOnKeyguard) {
+        final boolean isHeadsUpState = ExpandHeadsUpOnInlineReply.isEnabled()
+                && canShowHeadsUp() && isHeadsUpState();
+        // System expanded should be ignored in pinned heads up state
+        final boolean isPinned = isHeadsUpState && isPinned();
+        // Heads Up Notification can be expanded when it is pinned.
+        final boolean isPinnedAndExpanded =
+                isHeadsUpState && isPinnedAndExpanded();
+
         return (!shouldShowPublic()) && (!mOnKeyguard || allowOnKeyguard)
-                && (!hasUserChangedExpansion() && (isSystemExpanded() || isSystemChildExpanded())
-                || isUserExpanded());
+                && (!hasUserChangedExpansion() && !isPinned
+                && (isSystemExpanded() || isSystemChildExpanded())
+                || isUserExpanded() || isPinnedAndExpanded);
     }
 
     private boolean isSystemChildExpanded() {
@@ -2935,24 +2987,21 @@
         if (mShowingPublicInitialized && mShowingPublic == oldShowingPublic) {
             return;
         }
-        float oldAlpha = getContentView().getAlpha();
 
         if (!animated) {
-            mPublicLayout.animate().cancel();
-            mPrivateLayout.animate().cancel();
-            if (mChildrenContainer != null) {
-                mChildrenContainer.animate().cancel();
+            if (!NotificationContentAlphaOptimization.isEnabled()
+                    || mShowingPublic != oldShowingPublic) {
+                // Don't reset the alpha or cancel the animation if the showing layout doesn't
+                // change
+                mPublicLayout.animate().cancel();
+                mPrivateLayout.animate().cancel();
+                if (mChildrenContainer != null) {
+                    mChildrenContainer.animate().cancel();
+                }
+                resetAllContentAlphas();
             }
-            resetAllContentAlphas();
             mPublicLayout.setVisibility(mShowingPublic ? View.VISIBLE : View.INVISIBLE);
             updateChildrenVisibility();
-            if (NotificationContentAlphaOptimization.isEnabled()) {
-                // We want to set the old alpha to the now-showing layout to avoid breaking an
-                // on-going animation
-                if (oldAlpha != 1f) {
-                    setAlphaAndLayerType(mShowingPublic ? mPublicLayout : mPrivateLayout, oldAlpha);
-                }
-            }
         } else {
             animateShowingPublic(delay, duration, mShowingPublic);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 6f00d96..646d0b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -61,6 +61,7 @@
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationCustomViewWrapper;
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationHeaderViewWrapper;
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
+import com.android.systemui.statusbar.phone.ExpandHeadsUpOnInlineReply;
 import com.android.systemui.statusbar.policy.InflatedSmartReplyState;
 import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder;
 import com.android.systemui.statusbar.policy.RemoteInputView;
@@ -72,6 +73,8 @@
 import com.android.systemui.util.Compile;
 import com.android.systemui.util.DumpUtilsKt;
 
+import kotlinx.coroutines.DisposableHandle;
+
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -109,6 +112,8 @@
     private View mHeadsUpChild;
     private HybridNotificationView mSingleLineView;
 
+    @Nullable public DisposableHandle mContractedBinderHandle;
+
     private RemoteInputView mExpandedRemoteInput;
     private RemoteInputView mHeadsUpRemoteInput;
 
@@ -909,7 +914,9 @@
                 View visibleView = getViewForVisibleType(visibleType);
                 if (visibleView != null) {
                     visibleView.setVisibility(VISIBLE);
-                    transferRemoteInputFocus(visibleType);
+                    if (!ExpandHeadsUpOnInlineReply.isEnabled()) {
+                        transferRemoteInputFocus(visibleType);
+                    }
                 }
 
                 if (animate && ((visibleType == VISIBLE_TYPE_EXPANDED && mExpandedChild != null)
@@ -1393,30 +1400,39 @@
         mCachedExpandedRemoteInput = null;
         mCachedExpandedRemoteInputViewController = null;
 
-        if (mHeadsUpChild != null) {
-            RemoteInputViewData headsUpData = applyRemoteInput(mHeadsUpChild, mNotificationEntry,
-                    hasFreeformRemoteInput, mPreviousHeadsUpRemoteInputIntent,
-                    mCachedHeadsUpRemoteInput, mCachedHeadsUpRemoteInputViewController,
-                    mHeadsUpWrapper);
-            mHeadsUpRemoteInput = headsUpData.mView;
-            mHeadsUpRemoteInputController = headsUpData.mController;
-            if (mHeadsUpRemoteInputController != null) {
-                mHeadsUpRemoteInputController.bind();
-            }
-        } else {
+        if (ExpandHeadsUpOnInlineReply.isEnabled()) {
             mHeadsUpRemoteInput = null;
-            if (mHeadsUpRemoteInputController != null) {
-                mHeadsUpRemoteInputController.unbind();
-            }
             mHeadsUpRemoteInputController = null;
+            mCachedHeadsUpRemoteInput = null;
+            mCachedHeadsUpRemoteInputViewController = null;
+        } else {
+            ExpandHeadsUpOnInlineReply.assertInLegacyMode();
+            if (mHeadsUpChild != null) {
+                RemoteInputViewData headsUpData = applyRemoteInput(mHeadsUpChild,
+                        mNotificationEntry,
+                        hasFreeformRemoteInput, mPreviousHeadsUpRemoteInputIntent,
+                        mCachedHeadsUpRemoteInput, mCachedHeadsUpRemoteInputViewController,
+                        mHeadsUpWrapper);
+                mHeadsUpRemoteInput = headsUpData.mView;
+                mHeadsUpRemoteInputController = headsUpData.mController;
+                if (mHeadsUpRemoteInputController != null) {
+                    mHeadsUpRemoteInputController.bind();
+                }
+            } else {
+                mHeadsUpRemoteInput = null;
+                if (mHeadsUpRemoteInputController != null) {
+                    mHeadsUpRemoteInputController.unbind();
+                }
+                mHeadsUpRemoteInputController = null;
+            }
+            if (mCachedHeadsUpRemoteInput != null
+                    && mCachedHeadsUpRemoteInput != mHeadsUpRemoteInput) {
+                // We had a cached remote input but didn't reuse it. Clean up required.
+                mCachedHeadsUpRemoteInput.dispatchFinishTemporaryDetach();
+            }
+            mCachedHeadsUpRemoteInput = null;
+            mCachedHeadsUpRemoteInputViewController = null;
         }
-        if (mCachedHeadsUpRemoteInput != null
-                && mCachedHeadsUpRemoteInput != mHeadsUpRemoteInput) {
-            // We had a cached remote input but didn't reuse it. Clean up required.
-            mCachedHeadsUpRemoteInput.dispatchFinishTemporaryDetach();
-        }
-        mCachedHeadsUpRemoteInput = null;
-        mCachedHeadsUpRemoteInputViewController = null;
     }
 
     private RemoteInputViewData applyRemoteInput(View view, NotificationEntry entry,
@@ -1461,7 +1477,7 @@
             }
             if (hasRemoteInput) {
                 result.mView.setWrapper(wrapper);
-                result.mView.addOnVisibilityChangedListener(this::setRemoteInputVisible);
+                result.mView.setOnVisibilityChangedListener(this::setRemoteInputVisible);
 
                 if (existingPendingIntent != null || result.mView.isActive()) {
                     // The current action could be gone, or the pending intent no longer valid.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
index e704140..492d802 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
@@ -46,6 +46,10 @@
 import com.android.systemui.statusbar.notification.ConversationNotificationProcessor
 import com.android.systemui.statusbar.notification.InflationException
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_CONTRACTED
+import com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_EXPANDED
+import com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_HEADSUP
+import com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_SINGLELINE
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.BindParams
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED
@@ -62,6 +66,7 @@
 import com.android.systemui.statusbar.notification.row.shared.NewRemoteViews
 import com.android.systemui.statusbar.notification.row.shared.NotificationContentModel
 import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor
+import com.android.systemui.statusbar.notification.row.shared.RichOngoingContentModel
 import com.android.systemui.statusbar.notification.row.ui.viewbinder.SingleLineConversationViewBinder
 import com.android.systemui.statusbar.notification.row.ui.viewbinder.SingleLineViewBinder
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper
@@ -86,6 +91,8 @@
     private val remoteViewCache: NotifRemoteViewCache,
     private val remoteInputManager: NotificationRemoteInputManager,
     private val conversationProcessor: ConversationNotificationProcessor,
+    private val ronExtractor: RichOngoingNotificationContentExtractor,
+    private val ronInflater: RichOngoingNotificationViewInflater,
     @NotifInflation private val inflationExecutor: Executor,
     private val smartReplyStateInflater: SmartReplyStateInflater,
     private val notifLayoutInflaterFactoryProvider: NotifLayoutInflaterFactory.Provider,
@@ -133,6 +140,8 @@
                 remoteViewCache,
                 entry,
                 conversationProcessor,
+                ronExtractor,
+                ronInflater,
                 row,
                 bindParams.isMinimized,
                 bindParams.usesIncreasedHeight,
@@ -177,6 +186,7 @@
                 notifLayoutInflaterFactoryProvider = notifLayoutInflaterFactoryProvider,
                 headsUpStyleProvider = headsUpStyleProvider,
                 conversationProcessor = conversationProcessor,
+                ronExtractor = ronExtractor,
                 logger = logger,
             )
         inflateSmartReplyViews(
@@ -255,39 +265,31 @@
     ) {
         when (inflateFlag) {
             FLAG_CONTENT_VIEW_CONTRACTED ->
-                row.privateLayout.performWhenContentInactive(
-                    NotificationContentView.VISIBLE_TYPE_CONTRACTED
-                ) {
+                row.privateLayout.performWhenContentInactive(VISIBLE_TYPE_CONTRACTED) {
+                    row.privateLayout.mContractedBinderHandle?.dispose()
+                    row.privateLayout.mContractedBinderHandle = null
                     row.privateLayout.setContractedChild(null)
                     remoteViewCache.removeCachedView(entry, FLAG_CONTENT_VIEW_CONTRACTED)
                 }
             FLAG_CONTENT_VIEW_EXPANDED ->
-                row.privateLayout.performWhenContentInactive(
-                    NotificationContentView.VISIBLE_TYPE_EXPANDED
-                ) {
+                row.privateLayout.performWhenContentInactive(VISIBLE_TYPE_EXPANDED) {
                     row.privateLayout.setExpandedChild(null)
                     remoteViewCache.removeCachedView(entry, FLAG_CONTENT_VIEW_EXPANDED)
                 }
             FLAG_CONTENT_VIEW_HEADS_UP ->
-                row.privateLayout.performWhenContentInactive(
-                    NotificationContentView.VISIBLE_TYPE_HEADSUP
-                ) {
+                row.privateLayout.performWhenContentInactive(VISIBLE_TYPE_HEADSUP) {
                     row.privateLayout.setHeadsUpChild(null)
                     remoteViewCache.removeCachedView(entry, FLAG_CONTENT_VIEW_HEADS_UP)
                     row.privateLayout.setHeadsUpInflatedSmartReplies(null)
                 }
             FLAG_CONTENT_VIEW_PUBLIC ->
-                row.publicLayout.performWhenContentInactive(
-                    NotificationContentView.VISIBLE_TYPE_CONTRACTED
-                ) {
+                row.publicLayout.performWhenContentInactive(VISIBLE_TYPE_CONTRACTED) {
                     row.publicLayout.setContractedChild(null)
                     remoteViewCache.removeCachedView(entry, FLAG_CONTENT_VIEW_PUBLIC)
                 }
             FLAG_CONTENT_VIEW_SINGLE_LINE -> {
                 if (AsyncHybridViewInflation.isEnabled) {
-                    row.privateLayout.performWhenContentInactive(
-                        NotificationContentView.VISIBLE_TYPE_SINGLELINE
-                    ) {
+                    row.privateLayout.performWhenContentInactive(VISIBLE_TYPE_SINGLELINE) {
                         row.privateLayout.setSingleLineView(null)
                     }
                 }
@@ -308,32 +310,22 @@
         @InflationFlag contentViews: Int
     ) {
         if (contentViews and FLAG_CONTENT_VIEW_CONTRACTED != 0) {
-            row.privateLayout.removeContentInactiveRunnable(
-                NotificationContentView.VISIBLE_TYPE_CONTRACTED
-            )
+            row.privateLayout.removeContentInactiveRunnable(VISIBLE_TYPE_CONTRACTED)
         }
         if (contentViews and FLAG_CONTENT_VIEW_EXPANDED != 0) {
-            row.privateLayout.removeContentInactiveRunnable(
-                NotificationContentView.VISIBLE_TYPE_EXPANDED
-            )
+            row.privateLayout.removeContentInactiveRunnable(VISIBLE_TYPE_EXPANDED)
         }
         if (contentViews and FLAG_CONTENT_VIEW_HEADS_UP != 0) {
-            row.privateLayout.removeContentInactiveRunnable(
-                NotificationContentView.VISIBLE_TYPE_HEADSUP
-            )
+            row.privateLayout.removeContentInactiveRunnable(VISIBLE_TYPE_HEADSUP)
         }
         if (contentViews and FLAG_CONTENT_VIEW_PUBLIC != 0) {
-            row.publicLayout.removeContentInactiveRunnable(
-                NotificationContentView.VISIBLE_TYPE_CONTRACTED
-            )
+            row.publicLayout.removeContentInactiveRunnable(VISIBLE_TYPE_CONTRACTED)
         }
         if (
             AsyncHybridViewInflation.isEnabled &&
                 contentViews and FLAG_CONTENT_VIEW_SINGLE_LINE != 0
         ) {
-            row.privateLayout.removeContentInactiveRunnable(
-                NotificationContentView.VISIBLE_TYPE_SINGLELINE
-            )
+            row.privateLayout.removeContentInactiveRunnable(VISIBLE_TYPE_SINGLELINE)
         }
     }
 
@@ -353,6 +345,8 @@
         private val remoteViewCache: NotifRemoteViewCache,
         private val entry: NotificationEntry,
         private val conversationProcessor: ConversationNotificationProcessor,
+        private val ronExtractor: RichOngoingNotificationContentExtractor,
+        private val ronInflater: RichOngoingNotificationViewInflater,
         private val row: ExpandableNotificationRow,
         private val isMinimized: Boolean,
         private val usesIncreasedHeight: Boolean,
@@ -432,6 +426,7 @@
                     notifLayoutInflaterFactoryProvider = notifLayoutInflaterFactoryProvider,
                     headsUpStyleProvider = headsUpStyleProvider,
                     conversationProcessor = conversationProcessor,
+                    ronExtractor = ronExtractor,
                     logger = logger
                 )
             logger.logAsyncTaskProgress(
@@ -463,6 +458,21 @@
                         )
                     }
             }
+
+            if (reInflateFlags and CONTENT_VIEWS_TO_CREATE_RICH_ONGOING != 0) {
+                logger.logAsyncTaskProgress(entry, "inflating RON view")
+                inflationProgress.richOngoingNotificationViewHolder =
+                    inflationProgress.contentModel.richOngoingContentModel?.let {
+                        ronInflater.inflateView(
+                            contentModel = it,
+                            existingView = row.privateLayout.contractedChild,
+                            entry = entry,
+                            systemUiContext = context,
+                            parentView = row.privateLayout
+                        )
+                    }
+            }
+
             logger.logAsyncTaskProgress(entry, "getting row image resolver (on wrong thread!)")
             val imageResolver = row.imageResolver
             // wait for image resolver to finish preloading
@@ -568,6 +578,7 @@
         var inflatedSmartReplyState: InflatedSmartReplyState? = null
         var expandedInflatedSmartReplies: InflatedSmartReplyViewHolder? = null
         var headsUpInflatedSmartReplies: InflatedSmartReplyViewHolder? = null
+        var richOngoingNotificationViewHolder: InflatedContentViewHolder? = null
 
         // Inflated SingleLineView that lacks the UI State
         var inflatedSingleLineView: HybridNotificationView? = null
@@ -602,6 +613,7 @@
             val inflateHeadsUp =
                 (reInflateFlags and FLAG_CONTENT_VIEW_HEADS_UP != 0 &&
                     result.remoteViews.headsUp != null)
+
             if (inflateContracted || inflateExpanded || inflateHeadsUp) {
                 logger.logAsyncTaskProgress(entry, "inflating contracted smart reply state")
                 result.inflatedSmartReplyState = inflater.inflateSmartReplyState(entry)
@@ -643,6 +655,7 @@
             notifLayoutInflaterFactoryProvider: NotifLayoutInflaterFactory.Provider,
             headsUpStyleProvider: HeadsUpStyleProvider,
             conversationProcessor: ConversationNotificationProcessor,
+            ronExtractor: RichOngoingNotificationContentExtractor,
             logger: NotificationRowContentBinderLogger
         ): InflationProgress {
             // process conversations and extract the messaging style
@@ -651,9 +664,24 @@
                     conversationProcessor.processNotification(entry, builder, logger)
                 } else null
 
+            val richOngoingContentModel =
+                if (reInflateFlags and CONTENT_VIEWS_TO_CREATE_RICH_ONGOING != 0) {
+                    ronExtractor.extractContentModel(
+                        entry = entry,
+                        builder = builder,
+                        systemUIContext = systemUIContext,
+                        packageContext = packageContext
+                    )
+                } else {
+                    // if we're not re-inflating any RON views, make sure the model doesn't change
+                    entry.richOngoingContentModel.value
+                }
+
+            val remoteViewsFlags = getRemoteViewsFlags(reInflateFlags, richOngoingContentModel)
+
             val remoteViews =
                 createRemoteViews(
-                    reInflateFlags = reInflateFlags,
+                    reInflateFlags = remoteViewsFlags,
                     builder = builder,
                     isMinimized = isMinimized,
                     usesIncreasedHeight = usesIncreasedHeight,
@@ -688,6 +716,7 @@
                 NotificationContentModel(
                     headsUpStatusBarModel = headsUpStatusBarModel,
                     singleLineViewModel = singleLineViewModel,
+                    richOngoingContentModel = richOngoingContentModel,
                 )
 
             return InflationProgress(
@@ -815,7 +844,7 @@
             val publicLayout = row.publicLayout
             val runningInflations = HashMap<Int, CancellationSignal>()
             var flag = FLAG_CONTENT_VIEW_CONTRACTED
-            if (reInflateFlags and flag != 0) {
+            if (reInflateFlags and flag != 0 && result.remoteViews.contracted != null) {
                 val isNewView =
                     !canReapplyRemoteView(
                         newView = result.remoteViews.contracted,
@@ -829,7 +858,7 @@
                         }
 
                         override val remoteView: RemoteViews
-                            get() = result.remoteViews.contracted!!
+                            get() = result.remoteViews.contracted
                     }
                 logger.logAsyncTaskProgress(entry, "applying contracted view")
                 applyRemoteView(
@@ -847,104 +876,89 @@
                     callback = callback,
                     parentLayout = privateLayout,
                     existingView = privateLayout.contractedChild,
-                    existingWrapper =
-                        privateLayout.getVisibleWrapper(
-                            NotificationContentView.VISIBLE_TYPE_CONTRACTED
-                        ),
+                    existingWrapper = privateLayout.getVisibleWrapper(VISIBLE_TYPE_CONTRACTED),
                     runningInflations = runningInflations,
                     applyCallback = applyCallback,
                     logger = logger
                 )
             }
             flag = FLAG_CONTENT_VIEW_EXPANDED
-            if (reInflateFlags and flag != 0) {
-                if (result.remoteViews.expanded != null) {
-                    val isNewView =
-                        !canReapplyRemoteView(
-                            newView = result.remoteViews.expanded,
-                            oldView =
-                                remoteViewCache.getCachedView(entry, FLAG_CONTENT_VIEW_EXPANDED)
-                        )
-                    val applyCallback: ApplyCallback =
-                        object : ApplyCallback() {
-                            override fun setResultView(v: View) {
-                                logger.logAsyncTaskProgress(entry, "expanded view applied")
-                                result.inflatedExpandedView = v
-                            }
-
-                            override val remoteView: RemoteViews
-                                get() = result.remoteViews.expanded
-                        }
-                    logger.logAsyncTaskProgress(entry, "applying expanded view")
-                    applyRemoteView(
-                        inflationExecutor = inflationExecutor,
-                        inflateSynchronously = inflateSynchronously,
-                        isMinimized = isMinimized,
-                        result = result,
-                        reInflateFlags = reInflateFlags,
-                        inflationId = flag,
-                        remoteViewCache = remoteViewCache,
-                        entry = entry,
-                        row = row,
-                        isNewView = isNewView,
-                        remoteViewClickHandler = remoteViewClickHandler,
-                        callback = callback,
-                        parentLayout = privateLayout,
-                        existingView = privateLayout.expandedChild,
-                        existingWrapper =
-                            privateLayout.getVisibleWrapper(
-                                NotificationContentView.VISIBLE_TYPE_EXPANDED
-                            ),
-                        runningInflations = runningInflations,
-                        applyCallback = applyCallback,
-                        logger = logger
+            if (reInflateFlags and flag != 0 && result.remoteViews.expanded != null) {
+                val isNewView =
+                    !canReapplyRemoteView(
+                        newView = result.remoteViews.expanded,
+                        oldView = remoteViewCache.getCachedView(entry, FLAG_CONTENT_VIEW_EXPANDED)
                     )
-                }
+                val applyCallback: ApplyCallback =
+                    object : ApplyCallback() {
+                        override fun setResultView(v: View) {
+                            logger.logAsyncTaskProgress(entry, "expanded view applied")
+                            result.inflatedExpandedView = v
+                        }
+
+                        override val remoteView: RemoteViews
+                            get() = result.remoteViews.expanded
+                    }
+                logger.logAsyncTaskProgress(entry, "applying expanded view")
+                applyRemoteView(
+                    inflationExecutor = inflationExecutor,
+                    inflateSynchronously = inflateSynchronously,
+                    isMinimized = isMinimized,
+                    result = result,
+                    reInflateFlags = reInflateFlags,
+                    inflationId = flag,
+                    remoteViewCache = remoteViewCache,
+                    entry = entry,
+                    row = row,
+                    isNewView = isNewView,
+                    remoteViewClickHandler = remoteViewClickHandler,
+                    callback = callback,
+                    parentLayout = privateLayout,
+                    existingView = privateLayout.expandedChild,
+                    existingWrapper = privateLayout.getVisibleWrapper(VISIBLE_TYPE_EXPANDED),
+                    runningInflations = runningInflations,
+                    applyCallback = applyCallback,
+                    logger = logger
+                )
             }
             flag = FLAG_CONTENT_VIEW_HEADS_UP
-            if (reInflateFlags and flag != 0) {
-                if (result.remoteViews.headsUp != null) {
-                    val isNewView =
-                        !canReapplyRemoteView(
-                            newView = result.remoteViews.headsUp,
-                            oldView =
-                                remoteViewCache.getCachedView(entry, FLAG_CONTENT_VIEW_HEADS_UP)
-                        )
-                    val applyCallback: ApplyCallback =
-                        object : ApplyCallback() {
-                            override fun setResultView(v: View) {
-                                logger.logAsyncTaskProgress(entry, "heads up view applied")
-                                result.inflatedHeadsUpView = v
-                            }
-
-                            override val remoteView: RemoteViews
-                                get() = result.remoteViews.headsUp
-                        }
-                    logger.logAsyncTaskProgress(entry, "applying heads up view")
-                    applyRemoteView(
-                        inflationExecutor = inflationExecutor,
-                        inflateSynchronously = inflateSynchronously,
-                        isMinimized = isMinimized,
-                        result = result,
-                        reInflateFlags = reInflateFlags,
-                        inflationId = flag,
-                        remoteViewCache = remoteViewCache,
-                        entry = entry,
-                        row = row,
-                        isNewView = isNewView,
-                        remoteViewClickHandler = remoteViewClickHandler,
-                        callback = callback,
-                        parentLayout = privateLayout,
-                        existingView = privateLayout.headsUpChild,
-                        existingWrapper =
-                            privateLayout.getVisibleWrapper(
-                                NotificationContentView.VISIBLE_TYPE_HEADSUP
-                            ),
-                        runningInflations = runningInflations,
-                        applyCallback = applyCallback,
-                        logger = logger
+            if (reInflateFlags and flag != 0 && result.remoteViews.headsUp != null) {
+                val isNewView =
+                    !canReapplyRemoteView(
+                        newView = result.remoteViews.headsUp,
+                        oldView = remoteViewCache.getCachedView(entry, FLAG_CONTENT_VIEW_HEADS_UP)
                     )
-                }
+                val applyCallback: ApplyCallback =
+                    object : ApplyCallback() {
+                        override fun setResultView(v: View) {
+                            logger.logAsyncTaskProgress(entry, "heads up view applied")
+                            result.inflatedHeadsUpView = v
+                        }
+
+                        override val remoteView: RemoteViews
+                            get() = result.remoteViews.headsUp
+                    }
+                logger.logAsyncTaskProgress(entry, "applying heads up view")
+                applyRemoteView(
+                    inflationExecutor = inflationExecutor,
+                    inflateSynchronously = inflateSynchronously,
+                    isMinimized = isMinimized,
+                    result = result,
+                    reInflateFlags = reInflateFlags,
+                    inflationId = flag,
+                    remoteViewCache = remoteViewCache,
+                    entry = entry,
+                    row = row,
+                    isNewView = isNewView,
+                    remoteViewClickHandler = remoteViewClickHandler,
+                    callback = callback,
+                    parentLayout = privateLayout,
+                    existingView = privateLayout.headsUpChild,
+                    existingWrapper = privateLayout.getVisibleWrapper(VISIBLE_TYPE_HEADSUP),
+                    runningInflations = runningInflations,
+                    applyCallback = applyCallback,
+                    logger = logger
+                )
             }
             flag = FLAG_CONTENT_VIEW_PUBLIC
             if (reInflateFlags and flag != 0) {
@@ -979,10 +993,7 @@
                     callback = callback,
                     parentLayout = publicLayout,
                     existingView = publicLayout.contractedChild,
-                    existingWrapper =
-                        publicLayout.getVisibleWrapper(
-                            NotificationContentView.VISIBLE_TYPE_CONTRACTED
-                        ),
+                    existingWrapper = publicLayout.getVisibleWrapper(VISIBLE_TYPE_CONTRACTED),
                     runningInflations = runningInflations,
                     applyCallback = applyCallback,
                     logger = logger
@@ -1359,79 +1370,34 @@
             if (runningInflations.isNotEmpty()) {
                 return false
             }
-            val privateLayout = row.privateLayout
-            val publicLayout = row.publicLayout
             logger.logAsyncTaskProgress(entry, "finishing")
-            if (reInflateFlags and FLAG_CONTENT_VIEW_CONTRACTED != 0) {
-                if (result.inflatedContentView != null) {
-                    // New view case
-                    privateLayout.setContractedChild(result.inflatedContentView)
-                    remoteViewCache.putCachedView(
-                        entry,
-                        FLAG_CONTENT_VIEW_CONTRACTED,
-                        result.remoteViews.contracted
-                    )
-                } else if (remoteViewCache.hasCachedView(entry, FLAG_CONTENT_VIEW_CONTRACTED)) {
-                    // Reinflation case. Only update if it's still cached (i.e. view has not been
-                    // freed while inflating).
-                    remoteViewCache.putCachedView(
-                        entry,
-                        FLAG_CONTENT_VIEW_CONTRACTED,
-                        result.remoteViews.contracted
-                    )
-                }
+
+            // before updating the content model, stop existing binding if necessary
+            val hasRichOngoingContentModel = result.contentModel.richOngoingContentModel != null
+            val requestedRichOngoing = reInflateFlags and CONTENT_VIEWS_TO_CREATE_RICH_ONGOING != 0
+            val rejectedRichOngoing = requestedRichOngoing && !hasRichOngoingContentModel
+            if (result.richOngoingNotificationViewHolder != null || rejectedRichOngoing) {
+                row.privateLayout.mContractedBinderHandle?.dispose()
+                row.privateLayout.mContractedBinderHandle = null
             }
-            if (reInflateFlags and FLAG_CONTENT_VIEW_EXPANDED != 0) {
-                if (result.inflatedExpandedView != null) {
-                    privateLayout.setExpandedChild(result.inflatedExpandedView)
-                    remoteViewCache.putCachedView(
-                        entry,
-                        FLAG_CONTENT_VIEW_EXPANDED,
-                        result.remoteViews.expanded
-                    )
-                } else if (result.remoteViews.expanded == null) {
-                    privateLayout.setExpandedChild(null)
-                    remoteViewCache.removeCachedView(entry, FLAG_CONTENT_VIEW_EXPANDED)
-                } else if (remoteViewCache.hasCachedView(entry, FLAG_CONTENT_VIEW_EXPANDED)) {
-                    remoteViewCache.putCachedView(
-                        entry,
-                        FLAG_CONTENT_VIEW_EXPANDED,
-                        result.remoteViews.expanded
-                    )
-                }
-                if (result.remoteViews.expanded != null) {
-                    privateLayout.setExpandedInflatedSmartReplies(
-                        result.expandedInflatedSmartReplies
-                    )
-                } else {
-                    privateLayout.setExpandedInflatedSmartReplies(null)
-                }
-                row.setExpandable(result.remoteViews.expanded != null)
-            }
-            if (reInflateFlags and FLAG_CONTENT_VIEW_HEADS_UP != 0) {
-                if (result.inflatedHeadsUpView != null) {
-                    privateLayout.setHeadsUpChild(result.inflatedHeadsUpView)
-                    remoteViewCache.putCachedView(
-                        entry,
-                        FLAG_CONTENT_VIEW_HEADS_UP,
-                        result.remoteViews.headsUp
-                    )
-                } else if (result.remoteViews.headsUp == null) {
-                    privateLayout.setHeadsUpChild(null)
-                    remoteViewCache.removeCachedView(entry, FLAG_CONTENT_VIEW_HEADS_UP)
-                } else if (remoteViewCache.hasCachedView(entry, FLAG_CONTENT_VIEW_HEADS_UP)) {
-                    remoteViewCache.putCachedView(
-                        entry,
-                        FLAG_CONTENT_VIEW_HEADS_UP,
-                        result.remoteViews.headsUp
-                    )
-                }
-                if (result.remoteViews.headsUp != null) {
-                    privateLayout.setHeadsUpInflatedSmartReplies(result.headsUpInflatedSmartReplies)
-                } else {
-                    privateLayout.setHeadsUpInflatedSmartReplies(null)
-                }
-            }
+
+            // set the content model after disposal and before setting new rich ongoing view
+            entry.setContentModel(result.contentModel)
+            result.inflatedSmartReplyState?.let { row.privateLayout.setInflatedSmartReplyState(it) }
+
+            // set normal remote views (skipping rich ongoing states when that model exists)
+            val remoteViewsFlags =
+                getRemoteViewsFlags(reInflateFlags, result.contentModel.richOngoingContentModel)
+            setContentViewsFromRemoteViews(
+                remoteViewsFlags,
+                entry,
+                remoteViewCache,
+                result,
+                row,
+                isMinimized,
+            )
+
+            // set single line view
             if (
                 AsyncHybridViewInflation.isEnabled &&
                     reInflateFlags and FLAG_CONTENT_VIEW_SINGLE_LINE != 0
@@ -1444,80 +1410,144 @@
                     } else {
                         SingleLineViewBinder.bind(viewModel, singleLineView)
                     }
-                    privateLayout.setSingleLineView(result.inflatedSingleLineView)
+                    row.privateLayout.setSingleLineView(result.inflatedSingleLineView)
                 }
             }
-            result.inflatedSmartReplyState?.let { privateLayout.setInflatedSmartReplyState(it) }
-            if (reInflateFlags and FLAG_CONTENT_VIEW_PUBLIC != 0) {
-                if (result.inflatedPublicView != null) {
-                    publicLayout.setContractedChild(result.inflatedPublicView)
-                    remoteViewCache.putCachedView(
-                        entry,
-                        FLAG_CONTENT_VIEW_PUBLIC,
-                        result.remoteViews.public
-                    )
-                } else if (remoteViewCache.hasCachedView(entry, FLAG_CONTENT_VIEW_PUBLIC)) {
-                    remoteViewCache.putCachedView(
-                        entry,
-                        FLAG_CONTENT_VIEW_PUBLIC,
-                        result.remoteViews.public
-                    )
-                }
+
+            // after updating the content model, set the view, then start the new binder
+            result.richOngoingNotificationViewHolder?.let { viewHolder ->
+                row.privateLayout.contractedChild = viewHolder.view
+                row.privateLayout.expandedChild = null
+                row.privateLayout.headsUpChild = null
+                row.privateLayout.setExpandedInflatedSmartReplies(null)
+                row.privateLayout.setHeadsUpInflatedSmartReplies(null)
+                row.privateLayout.mContractedBinderHandle =
+                    viewHolder.binder.setupContentViewBinder()
+                row.setExpandable(false)
+                remoteViewCache.removeCachedView(entry, FLAG_CONTENT_VIEW_CONTRACTED)
+                remoteViewCache.removeCachedView(entry, FLAG_CONTENT_VIEW_EXPANDED)
+                remoteViewCache.removeCachedView(entry, FLAG_CONTENT_VIEW_HEADS_UP)
             }
-            if (AsyncGroupHeaderViewInflation.isEnabled) {
-                if (reInflateFlags and FLAG_GROUP_SUMMARY_HEADER != 0) {
-                    if (result.inflatedGroupHeaderView != null) {
-                        // We need to set if the row is minimized before setting the group header to
-                        // make sure the setting of header view works correctly
-                        row.setIsMinimized(isMinimized)
-                        row.setGroupHeader(/* headerView= */ result.inflatedGroupHeaderView)
-                        remoteViewCache.putCachedView(
-                            entry,
-                            FLAG_GROUP_SUMMARY_HEADER,
-                            result.remoteViews.normalGroupHeader
-                        )
-                    } else if (remoteViewCache.hasCachedView(entry, FLAG_GROUP_SUMMARY_HEADER)) {
-                        // Re-inflation case. Only update if it's still cached (i.e. view has not
-                        // been freed while inflating).
-                        remoteViewCache.putCachedView(
-                            entry,
-                            FLAG_GROUP_SUMMARY_HEADER,
-                            result.remoteViews.normalGroupHeader
-                        )
-                    }
-                }
-                if (reInflateFlags and FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER != 0) {
-                    if (result.inflatedMinimizedGroupHeaderView != null) {
-                        // We need to set if the row is minimized before setting the group header to
-                        // make sure the setting of header view works correctly
-                        row.setIsMinimized(isMinimized)
-                        row.setMinimizedGroupHeader(
-                            /* headerView= */ result.inflatedMinimizedGroupHeaderView
-                        )
-                        remoteViewCache.putCachedView(
-                            entry,
-                            FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER,
-                            result.remoteViews.minimizedGroupHeader
-                        )
-                    } else if (
-                        remoteViewCache.hasCachedView(entry, FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER)
-                    ) {
-                        // Re-inflation case. Only update if it's still cached (i.e. view has not
-                        // been freed while inflating).
-                        remoteViewCache.putCachedView(
-                            entry,
-                            FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER,
-                            result.remoteViews.normalGroupHeader
-                        )
-                    }
-                }
-            }
-            entry.setContentModel(result.contentModel)
+
             Trace.endAsyncSection(APPLY_TRACE_METHOD, System.identityHashCode(row))
             endListener?.onAsyncInflationFinished(entry)
             return true
         }
 
+        private fun setContentViewsFromRemoteViews(
+            @InflationFlag reInflateFlags: Int,
+            entry: NotificationEntry,
+            remoteViewCache: NotifRemoteViewCache,
+            result: InflationProgress,
+            row: ExpandableNotificationRow,
+            isMinimized: Boolean,
+        ) {
+            val privateLayout = row.privateLayout
+            val publicLayout = row.publicLayout
+            val remoteViewsUpdater = RemoteViewsUpdater(reInflateFlags, entry, remoteViewCache)
+            remoteViewsUpdater.setContentView(
+                FLAG_CONTENT_VIEW_CONTRACTED,
+                result.remoteViews.contracted,
+                result.inflatedContentView,
+                privateLayout::setContractedChild
+            )
+            remoteViewsUpdater.setContentView(
+                FLAG_CONTENT_VIEW_EXPANDED,
+                result.remoteViews.expanded,
+                result.inflatedExpandedView,
+                privateLayout::setExpandedChild
+            )
+            remoteViewsUpdater.setSmartReplies(
+                FLAG_CONTENT_VIEW_EXPANDED,
+                result.remoteViews.expanded,
+                result.expandedInflatedSmartReplies,
+                privateLayout::setExpandedInflatedSmartReplies
+            )
+            if (reInflateFlags and FLAG_CONTENT_VIEW_EXPANDED != 0) {
+                row.setExpandable(result.remoteViews.expanded != null)
+            }
+            remoteViewsUpdater.setContentView(
+                FLAG_CONTENT_VIEW_HEADS_UP,
+                result.remoteViews.headsUp,
+                result.inflatedHeadsUpView,
+                privateLayout::setHeadsUpChild
+            )
+            remoteViewsUpdater.setSmartReplies(
+                FLAG_CONTENT_VIEW_HEADS_UP,
+                result.remoteViews.headsUp,
+                result.headsUpInflatedSmartReplies,
+                privateLayout::setHeadsUpInflatedSmartReplies
+            )
+            remoteViewsUpdater.setContentView(
+                FLAG_CONTENT_VIEW_PUBLIC,
+                result.remoteViews.public,
+                result.inflatedPublicView,
+                publicLayout::setContractedChild
+            )
+            if (AsyncGroupHeaderViewInflation.isEnabled) {
+                remoteViewsUpdater.setContentView(
+                    FLAG_GROUP_SUMMARY_HEADER,
+                    result.remoteViews.normalGroupHeader,
+                    result.inflatedGroupHeaderView,
+                ) { views ->
+                    row.setIsMinimized(isMinimized)
+                    row.setGroupHeader(views)
+                }
+                remoteViewsUpdater.setContentView(
+                    FLAG_LOW_PRIORITY_GROUP_SUMMARY_HEADER,
+                    result.remoteViews.minimizedGroupHeader,
+                    result.inflatedMinimizedGroupHeaderView,
+                ) { views ->
+                    row.setIsMinimized(isMinimized)
+                    row.setMinimizedGroupHeader(views)
+                }
+            }
+        }
+
+        private class RemoteViewsUpdater(
+            @InflationFlag private val reInflateFlags: Int,
+            private val entry: NotificationEntry,
+            private val remoteViewCache: NotifRemoteViewCache,
+        ) {
+            fun <V : View> setContentView(
+                @InflationFlag flagState: Int,
+                remoteViews: RemoteViews?,
+                view: V?,
+                setView: (V?) -> Unit,
+            ) {
+                val clearViewFlags = FLAG_CONTENT_VIEW_HEADS_UP or FLAG_CONTENT_VIEW_EXPANDED
+                val shouldClearView = flagState and clearViewFlags != 0
+                if (reInflateFlags and flagState != 0) {
+                    if (view != null) {
+                        setView(view)
+                        remoteViewCache.putCachedView(entry, flagState, remoteViews)
+                    } else if (shouldClearView && remoteViews == null) {
+                        setView(null)
+                        remoteViewCache.removeCachedView(entry, flagState)
+                    } else if (remoteViewCache.hasCachedView(entry, flagState)) {
+                        // Re-inflation case. Only update if it's still cached (i.e. view has not
+                        // been freed while inflating).
+                        remoteViewCache.putCachedView(entry, flagState, remoteViews)
+                    }
+                }
+            }
+
+            fun setSmartReplies(
+                @InflationFlag flagState: Int,
+                remoteViews: RemoteViews?,
+                smartReplies: InflatedSmartReplyViewHolder?,
+                setSmartReplies: (InflatedSmartReplyViewHolder?) -> Unit,
+            ) {
+                if (reInflateFlags and flagState != 0) {
+                    if (remoteViews != null) {
+                        setSmartReplies(smartReplies)
+                    } else {
+                        setSmartReplies(null)
+                    }
+                }
+            }
+        }
+
         private fun createExpandedView(
             builder: Notification.Builder,
             isMinimized: Boolean
@@ -1562,6 +1592,21 @@
                     !oldView.hasFlags(RemoteViews.FLAG_REAPPLY_DISALLOWED)
         }
 
+        @InflationFlag
+        private fun getRemoteViewsFlags(
+            @InflationFlag reInflateFlags: Int,
+            richOngoingContentModel: RichOngoingContentModel?
+        ): Int =
+            if (richOngoingContentModel != null) {
+                reInflateFlags and CONTENT_VIEWS_TO_CREATE_RICH_ONGOING.inv()
+            } else {
+                reInflateFlags
+            }
+
+        @InflationFlag
+        private const val CONTENT_VIEWS_TO_CREATE_RICH_ONGOING =
+            FLAG_CONTENT_VIEW_CONTRACTED or FLAG_CONTENT_VIEW_EXPANDED or FLAG_CONTENT_VIEW_HEADS_UP
+
         private const val ASYNC_TASK_TRACE_METHOD =
             "NotificationRowContentBinderImpl.AsyncInflationTask"
         private const val APPLY_TRACE_METHOD = "NotificationRowContentBinderImpl#apply"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java
index 84f2f66..c630c4d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowModule.java
@@ -18,6 +18,8 @@
 
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor;
+import com.android.systemui.statusbar.notification.row.shared.RichOngoingNotificationFlag;
+import com.android.systemui.statusbar.notification.row.ui.viewmodel.RichOngoingViewModelComponent;
 
 import dagger.Binds;
 import dagger.Module;
@@ -28,7 +30,7 @@
 /**
  * Dagger Module containing notification row and view inflation implementations.
  */
-@Module
+@Module(subcomponents = {RichOngoingViewModelComponent.class})
 public abstract class NotificationRowModule {
 
     /**
@@ -47,6 +49,25 @@
         }
     }
 
+    /** Provides ron content model extractor. */
+    @Provides
+    @SysUISingleton
+    public static RichOngoingNotificationContentExtractor provideRonContentExtractor(
+            Provider<RichOngoingNotificationContentExtractorImpl> realImpl
+    ) {
+        if (RichOngoingNotificationFlag.isEnabled()) {
+            return realImpl.get();
+        } else {
+            return new NoOpRichOngoingNotificationContentExtractor();
+        }
+    }
+
+    /** Provides ron view inflater. */
+    @Binds
+    @SysUISingleton
+    public abstract RichOngoingNotificationViewInflater provideRonViewInflater(
+            RichOngoingNotificationViewInflaterImpl impl);
+
     /**
      * Provides notification remote view cache instance.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RichOngoingNotificationContentExtractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RichOngoingNotificationContentExtractor.kt
new file mode 100644
index 0000000..b5ea861
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RichOngoingNotificationContentExtractor.kt
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.row
+
+import android.app.Notification
+import android.app.PendingIntent
+import android.content.Context
+import android.util.Log
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.row.shared.IconModel
+import com.android.systemui.statusbar.notification.row.shared.RichOngoingContentModel
+import com.android.systemui.statusbar.notification.row.shared.RichOngoingNotificationFlag
+import com.android.systemui.statusbar.notification.row.shared.TimerContentModel
+import java.time.Duration
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.LocalTime
+import java.time.ZoneId
+import javax.inject.Inject
+
+/**
+ * Interface which provides a [RichOngoingContentModel] for a given [Notification] when one is
+ * applicable to the given style.
+ */
+interface RichOngoingNotificationContentExtractor {
+    fun extractContentModel(
+        entry: NotificationEntry,
+        builder: Notification.Builder,
+        systemUIContext: Context,
+        packageContext: Context
+    ): RichOngoingContentModel?
+}
+
+class NoOpRichOngoingNotificationContentExtractor : RichOngoingNotificationContentExtractor {
+    override fun extractContentModel(
+        entry: NotificationEntry,
+        builder: Notification.Builder,
+        systemUIContext: Context,
+        packageContext: Context
+    ): RichOngoingContentModel? = null
+}
+
+@SysUISingleton
+class RichOngoingNotificationContentExtractorImpl @Inject constructor() :
+    RichOngoingNotificationContentExtractor {
+
+    init {
+        /* check if */ RichOngoingNotificationFlag.isUnexpectedlyInLegacyMode()
+    }
+
+    override fun extractContentModel(
+        entry: NotificationEntry,
+        builder: Notification.Builder,
+        systemUIContext: Context,
+        packageContext: Context
+    ): RichOngoingContentModel? =
+        try {
+            val sbn = entry.sbn
+            val notification = sbn.notification
+            val icon = IconModel(notification.smallIcon)
+            if (sbn.packageName == "com.google.android.deskclock") {
+                when (notification.channelId) {
+                    "Timers v2" -> {
+                        parseTimerNotification(notification, icon)
+                    }
+                    "Stopwatch v2" -> {
+                        Log.i("RONs", "Can't process stopwatch yet")
+                        null
+                    }
+                    else -> {
+                        Log.i("RONs", "Can't process channel '${notification.channelId}'")
+                        null
+                    }
+                }
+            } else null
+        } catch (e: Exception) {
+            Log.e("RONs", "Error parsing RON", e)
+            null
+        }
+
+    /**
+     * FOR PROTOTYPING ONLY: create a RON TimerContentModel using the time information available
+     * inside the sortKey of the clock app's timer notifications.
+     */
+    private fun parseTimerNotification(
+        notification: Notification,
+        icon: IconModel
+    ): TimerContentModel {
+        // sortKey=1 0|↺7|RUNNING|▶16:21:58.523|Σ0:05:00|Δ0:00:03|⏳0:04:57
+        // sortKey=1 0|↺7|PAUSED|Σ0:05:00|Δ0:04:54|⏳0:00:06
+        // sortKey=1 1|↺7|RUNNING|▶16:30:28.433|Σ0:04:05|Δ0:00:06|⏳0:03:59
+        // sortKey=1 0|↺7|RUNNING|▶16:36:18.350|Σ0:05:00|Δ0:01:42|⏳0:03:18
+        // sortKey=1 2|↺7|RUNNING|▶16:38:37.816|Σ0:02:00|Δ0:01:09|⏳0:00:51
+        // ▶ = "current" time (when updated)
+        // Σ = total time
+        // Δ = time elapsed
+        // ⏳ = time remaining
+        val sortKey = notification.sortKey
+        val (_, _, state, extra) = sortKey.split("|", limit = 4)
+        return when (state) {
+            "PAUSED" -> {
+                val (total, _, remaining) = extra.split("|")
+                val timeRemaining = parseTimeDelta(remaining)
+                TimerContentModel(
+                    icon = icon,
+                    name = total,
+                    state =
+                        TimerContentModel.TimerState.Paused(
+                            timeRemaining = timeRemaining,
+                            resumeIntent = notification.findActionWithName("Resume"),
+                            resetIntent = notification.findActionWithName("Reset"),
+                        )
+                )
+            }
+            "RUNNING" -> {
+                val (current, total, _, remaining) = extra.split("|")
+                val finishTime = parseCurrentTime(current) + parseTimeDelta(remaining).toMillis()
+                TimerContentModel(
+                    icon = icon,
+                    name = total,
+                    state =
+                        TimerContentModel.TimerState.Running(
+                            finishTime = finishTime,
+                            pauseIntent = notification.findActionWithName("Pause"),
+                            addOneMinuteIntent = notification.findActionWithName("Add 1 min"),
+                        )
+                )
+            }
+            else -> error("unknown state ($state) in sortKey=$sortKey")
+        }
+    }
+
+    private fun Notification.findActionWithName(name: String): PendingIntent? {
+        return actions.firstOrNull { name == it.title?.toString() }?.actionIntent
+    }
+
+    private fun parseCurrentTime(current: String): Long {
+        val (hour, minute, second, millis) = current.replace("▶", "").split(":", ".")
+        // NOTE: this won't work correctly at/around midnight.  It's just for prototyping.
+        val localDateTime =
+            LocalDateTime.of(
+                LocalDate.now(),
+                LocalTime.of(hour.toInt(), minute.toInt(), second.toInt(), millis.toInt() * 1000000)
+            )
+        val offset = ZoneId.systemDefault().rules.getOffset(localDateTime)
+        return localDateTime.toInstant(offset).toEpochMilli()
+    }
+
+    private fun parseTimeDelta(delta: String): Duration {
+        val (hour, minute, second) = delta.replace("Σ", "").replace("⏳", "").split(":")
+        return Duration.ofHours(hour.toLong())
+            .plusMinutes(minute.toLong())
+            .plusSeconds(second.toLong())
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RichOngoingNotificationViewInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RichOngoingNotificationViewInflater.kt
new file mode 100644
index 0000000..e9c4960
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RichOngoingNotificationViewInflater.kt
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.row
+
+import android.app.Notification
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.row.shared.RichOngoingContentModel
+import com.android.systemui.statusbar.notification.row.shared.RichOngoingNotificationFlag
+import com.android.systemui.statusbar.notification.row.shared.StopwatchContentModel
+import com.android.systemui.statusbar.notification.row.shared.TimerContentModel
+import com.android.systemui.statusbar.notification.row.ui.view.TimerView
+import com.android.systemui.statusbar.notification.row.ui.viewbinder.TimerViewBinder
+import com.android.systemui.statusbar.notification.row.ui.viewmodel.RichOngoingViewModelComponent
+import com.android.systemui.statusbar.notification.row.ui.viewmodel.TimerViewModel
+import javax.inject.Inject
+import kotlinx.coroutines.DisposableHandle
+
+fun interface DeferredContentViewBinder {
+    fun setupContentViewBinder(): DisposableHandle
+}
+
+class InflatedContentViewHolder(val view: View, val binder: DeferredContentViewBinder)
+
+/**
+ * Interface which provides a [RichOngoingContentModel] for a given [Notification] when one is
+ * applicable to the given style.
+ */
+interface RichOngoingNotificationViewInflater {
+    fun inflateView(
+        contentModel: RichOngoingContentModel,
+        existingView: View?,
+        entry: NotificationEntry,
+        systemUiContext: Context,
+        parentView: ViewGroup,
+    ): InflatedContentViewHolder?
+}
+
+@SysUISingleton
+class RichOngoingNotificationViewInflaterImpl
+@Inject
+constructor(
+    private val viewModelComponentFactory: RichOngoingViewModelComponent.Factory,
+) : RichOngoingNotificationViewInflater {
+
+    override fun inflateView(
+        contentModel: RichOngoingContentModel,
+        existingView: View?,
+        entry: NotificationEntry,
+        systemUiContext: Context,
+        parentView: ViewGroup,
+    ): InflatedContentViewHolder? {
+        if (RichOngoingNotificationFlag.isUnexpectedlyInLegacyMode()) return null
+        val component = viewModelComponentFactory.create(entry)
+        return when (contentModel) {
+            is TimerContentModel ->
+                inflateTimerView(
+                    existingView,
+                    component::createTimerViewModel,
+                    systemUiContext,
+                    parentView
+                )
+            is StopwatchContentModel -> TODO("Not yet implemented")
+        }
+    }
+
+    private fun inflateTimerView(
+        existingView: View?,
+        createViewModel: () -> TimerViewModel,
+        systemUiContext: Context,
+        parentView: ViewGroup,
+    ): InflatedContentViewHolder? {
+        if (existingView is TimerView && !existingView.isReinflateNeeded()) return null
+        val newView =
+            LayoutInflater.from(systemUiContext)
+                .inflate(
+                    R.layout.rich_ongoing_timer_notification,
+                    parentView,
+                    /* attachToRoot= */ false
+                ) as TimerView
+        return InflatedContentViewHolder(newView) {
+            TimerViewBinder.bindWhileAttached(newView, createViewModel())
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt
index 6fc82c9..463192c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/SingleLineViewInflater.kt
@@ -244,7 +244,7 @@
             return SingleIcon(null)
         }
         val userKey = user.getKeyOrName()
-        var conversationIcon: Icon? = null
+        var conversationIcon: Icon? = shortcutIcon
         var conversationText: CharSequence? = conversationTitle
 
         val groups = groupMessages(messages, historicMessages)
@@ -253,10 +253,6 @@
         if (!isGroupConversation) {
             // Conversation is one-to-one, load the single icon
             // Let's resolve the icon / text from the last sender
-            if (shortcutIcon != null) {
-                conversationIcon = shortcutIcon
-            }
-
             for (i in messages.lastIndex downTo 0) {
                 val message = messages[i]
                 val sender = message.senderPerson
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/data/repository/NotificationRowRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/data/repository/NotificationRowRepository.kt
new file mode 100644
index 0000000..bac887b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/data/repository/NotificationRowRepository.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.row.data.repository
+
+import com.android.systemui.statusbar.notification.row.shared.RichOngoingContentModel
+import kotlinx.coroutines.flow.StateFlow
+
+/** A repository of states relating to a specific notification row. */
+interface NotificationRowRepository {
+    /**
+     * A flow of an immutable data class with the current state of the Rich Ongoing Notification
+     * content, if applicable.
+     */
+    val richOngoingContentModel: StateFlow<RichOngoingContentModel?>
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/domain/interactor/NotificationRowInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/domain/interactor/NotificationRowInteractor.kt
new file mode 100644
index 0000000..4705ace
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/domain/interactor/NotificationRowInteractor.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 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.row.domain.interactor
+
+import com.android.systemui.statusbar.notification.row.data.repository.NotificationRowRepository
+import com.android.systemui.statusbar.notification.row.shared.TimerContentModel
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.filterIsInstance
+
+/** Interactor specific to a particular notification row. */
+class NotificationRowInteractor @Inject constructor(repository: NotificationRowRepository) {
+    /** Content of a rich ongoing timer notification. */
+    val timerContentModel: Flow<TimerContentModel> =
+        repository.richOngoingContentModel.filterIsInstance<TimerContentModel>()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/IconModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/IconModel.kt
new file mode 100644
index 0000000..e611938
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/IconModel.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.row.shared
+
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.Icon
+
+// TODO: figure out how to support lazy resolution of the drawable, e.g. on unrelated text change
+class IconModel(val icon: Icon) {
+    var drawable: Drawable? = null
+
+    override fun equals(other: Any?): Boolean =
+        when (other) {
+            null -> false
+            (other === this) -> true
+            !is IconModel -> false
+            else -> other.icon.sameAs(icon)
+        }
+
+    override fun toString(): String = "IconModel(icon=$icon, drawable=$drawable)"
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/NotificationContentModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/NotificationContentModel.kt
index b2421bc..46010a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/NotificationContentModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/NotificationContentModel.kt
@@ -21,4 +21,7 @@
 data class NotificationContentModel(
     val headsUpStatusBarModel: HeadsUpStatusBarModel,
     val singleLineViewModel: SingleLineViewModel? = null,
+    val richOngoingContentModel: RichOngoingContentModel? = null,
 )
+
+sealed interface RichOngoingContentModel
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/RichOngoingClock.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/RichOngoingClock.kt
new file mode 100644
index 0000000..5584701
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/RichOngoingClock.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.row.shared
+
+import android.app.PendingIntent
+import java.time.Duration
+
+/**
+ * Represents a simple timer that counts down to a time.
+ *
+ * @param name the label for the timer
+ * @param state state of the timer, including time and whether it is paused or running
+ */
+data class TimerContentModel(
+    val icon: IconModel,
+    val name: String,
+    val state: TimerState,
+) : RichOngoingContentModel {
+    /** The state (paused or running) of the timer, and relevant time */
+    sealed interface TimerState {
+        /**
+         * Indicates a running timer
+         *
+         * @param finishTime the time in ms since epoch that the timer will finish
+         * @param pauseIntent the action for pausing the timer
+         */
+        data class Running(
+            val finishTime: Long,
+            val pauseIntent: PendingIntent?,
+            val addOneMinuteIntent: PendingIntent?,
+        ) : TimerState
+
+        /**
+         * Indicates a paused timer
+         *
+         * @param timeRemaining the time in ms remaining on the paused timer
+         * @param resumeIntent the action for resuming the timer
+         */
+        data class Paused(
+            val timeRemaining: Duration,
+            val resumeIntent: PendingIntent?,
+            val resetIntent: PendingIntent?,
+        ) : TimerState
+    }
+}
+
+/**
+ * Represents a simple stopwatch that counts up and allows tracking laps.
+ *
+ * @param state state of the stopwatch, including time and whether it is paused or running
+ * @param lapDurations a list of durations of each completed lap
+ */
+data class StopwatchContentModel(
+    val icon: IconModel,
+    val state: StopwatchState,
+    val lapDurations: List<Long>,
+) : RichOngoingContentModel {
+    /** The state (paused or running) of the stopwatch, and relevant time */
+    sealed interface StopwatchState {
+        /**
+         * Indicates a running stopwatch
+         *
+         * @param startTime the time in ms since epoch that the stopwatch started, plus any
+         *   accumulated pause time
+         * @param pauseIntent the action for pausing the stopwatch
+         */
+        data class Running(
+            val startTime: Long,
+            val pauseIntent: PendingIntent,
+        ) : StopwatchState
+
+        /**
+         * Indicates a paused stopwatch
+         *
+         * @param timeElapsed the time in ms elapsed on the stopwatch
+         * @param resumeIntent the action for resuming the stopwatch
+         */
+        data class Paused(
+            val timeElapsed: Duration,
+            val resumeIntent: PendingIntent,
+        ) : StopwatchState
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/RichOngoingNotificationFlag.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/RichOngoingNotificationFlag.kt
new file mode 100644
index 0000000..4a7f7cd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/shared/RichOngoingNotificationFlag.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.row.shared
+
+import android.app.Flags
+import com.android.systemui.flags.FlagToken
+import com.android.systemui.flags.RefactorFlagUtils
+
+/** Helper for reading or using the api rich ongoing flag state. */
+@Suppress("NOTHING_TO_INLINE")
+object RichOngoingNotificationFlag {
+    /** The aconfig flag name */
+    const val FLAG_NAME = Flags.FLAG_API_RICH_ONGOING
+
+    /** A token used for dependency declaration */
+    val token: FlagToken
+        get() = FlagToken(FLAG_NAME, isEnabled)
+
+    /** Is the refactor enabled */
+    @JvmStatic
+    inline val isEnabled
+        get() = Flags.apiRichOngoing()
+
+    /**
+     * Called to ensure code is only run when the flag is enabled. This protects users from the
+     * unintended behaviors caused by accidentally running new logic, while also crashing on an eng
+     * build to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun isUnexpectedlyInLegacyMode() =
+        RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+    /**
+     * Called to ensure code is only run when the flag is disabled. This will throw an exception if
+     * the flag is enabled to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/view/ConfigurationTracker.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/view/ConfigurationTracker.kt
new file mode 100644
index 0000000..95c507c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/view/ConfigurationTracker.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.row.ui.view
+
+import android.content.pm.ActivityInfo.CONFIG_ASSETS_PATHS
+import android.content.pm.ActivityInfo.CONFIG_DENSITY
+import android.content.pm.ActivityInfo.CONFIG_FONT_SCALE
+import android.content.pm.ActivityInfo.CONFIG_LAYOUT_DIRECTION
+import android.content.pm.ActivityInfo.CONFIG_LOCALE
+import android.content.pm.ActivityInfo.CONFIG_UI_MODE
+import android.content.res.Configuration
+import android.content.res.Resources
+
+/**
+ * Tracks the active configuration when constructed and returns (when queried) whether the
+ * configuration has unhandled changes.
+ */
+class ConfigurationTracker(
+    private val resources: Resources,
+    private val unhandledConfigChanges: Int
+) {
+    private val initialConfig = Configuration(resources.configuration)
+
+    constructor(
+        resources: Resources,
+        handlesDensityFontScale: Boolean = false,
+        handlesTheme: Boolean = false,
+        handlesLocaleAndLayout: Boolean = true,
+    ) : this(
+        resources,
+        unhandledConfigChanges =
+            (if (handlesDensityFontScale) 0 else CONFIG_DENSITY or CONFIG_FONT_SCALE) or
+                (if (handlesTheme) 0 else CONFIG_ASSETS_PATHS or CONFIG_UI_MODE) or
+                (if (handlesLocaleAndLayout) 0 else CONFIG_LOCALE or CONFIG_LAYOUT_DIRECTION)
+    )
+
+    /**
+     * Whether the current configuration has unhandled changes relative to the initial configuration
+     */
+    fun hasUnhandledConfigChange(): Boolean =
+        initialConfig.diff(resources.configuration) and unhandledConfigChanges != 0
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/view/TimerButtonView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/view/TimerButtonView.kt
new file mode 100644
index 0000000..0d83ace
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/view/TimerButtonView.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.row.ui.view
+
+import android.annotation.DrawableRes
+import android.content.Context
+import android.util.AttributeSet
+import android.widget.Button
+
+class TimerButtonView
+@JvmOverloads
+constructor(
+    context: Context,
+    attrs: AttributeSet? = null,
+    defStyleAttr: Int = 0,
+    defStyleRes: Int = 0,
+) : Button(context, attrs, defStyleAttr, defStyleRes) {
+
+    private val Int.dp: Int
+        get() = (this * context.resources.displayMetrics.density).toInt()
+
+    fun setIcon(@DrawableRes icon: Int) {
+        val drawable = context.getDrawable(icon)
+        drawable?.setBounds(0, 0, 24.dp, 24.dp)
+        setCompoundDrawablesRelative(drawable, null, null, null)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/view/TimerView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/view/TimerView.kt
new file mode 100644
index 0000000..2e164d6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/view/TimerView.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.row.ui.view
+
+import android.content.Context
+import android.graphics.drawable.Drawable
+import android.os.SystemClock
+import android.util.AttributeSet
+import android.widget.Chronometer
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.view.isVisible
+import com.android.systemui.res.R
+
+class TimerView
+@JvmOverloads
+constructor(
+    context: Context,
+    attrs: AttributeSet? = null,
+    defStyleAttr: Int = 0,
+    defStyleRes: Int = 0,
+) : ConstraintLayout(context, attrs, defStyleAttr, defStyleRes) {
+
+    private val configTracker = ConfigurationTracker(resources)
+
+    private lateinit var icon: ImageView
+    private lateinit var label: TextView
+    private lateinit var chronometer: Chronometer
+    private lateinit var pausedTimeRemaining: TextView
+    lateinit var mainButton: TimerButtonView
+        private set
+
+    lateinit var altButton: TimerButtonView
+        private set
+
+    override fun onFinishInflate() {
+        super.onFinishInflate()
+        icon = requireViewById(R.id.icon)
+        label = requireViewById(R.id.label)
+        chronometer = requireViewById(R.id.chronoRemaining)
+        pausedTimeRemaining = requireViewById(R.id.pausedTimeRemaining)
+        mainButton = requireViewById(R.id.mainButton)
+        altButton = requireViewById(R.id.altButton)
+    }
+
+    /** the resources configuration has changed such that the view needs to be reinflated */
+    fun isReinflateNeeded(): Boolean = configTracker.hasUnhandledConfigChange()
+
+    fun setIcon(iconDrawable: Drawable?) {
+        this.icon.setImageDrawable(iconDrawable)
+    }
+
+    fun setLabel(label: String) {
+        this.label.text = label
+    }
+
+    fun setPausedTime(pausedTime: String?) {
+        if (pausedTime != null) {
+            pausedTimeRemaining.text = pausedTime
+            pausedTimeRemaining.isVisible = true
+        } else {
+            pausedTimeRemaining.isVisible = false
+        }
+    }
+
+    fun setCountdownTime(countdownTimeMs: Long?) {
+        if (countdownTimeMs != null) {
+            chronometer.base =
+                countdownTimeMs - System.currentTimeMillis() + SystemClock.elapsedRealtime()
+            chronometer.isVisible = true
+            chronometer.start()
+        } else {
+            chronometer.isVisible = false
+            chronometer.stop()
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/TimerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/TimerViewBinder.kt
new file mode 100644
index 0000000..c9ff589
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/TimerViewBinder.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.row.ui.viewbinder
+
+import android.view.View
+import androidx.core.view.isGone
+import androidx.lifecycle.lifecycleScope
+import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.statusbar.notification.row.ui.view.TimerButtonView
+import com.android.systemui.statusbar.notification.row.ui.view.TimerView
+import com.android.systemui.statusbar.notification.row.ui.viewmodel.TimerViewModel
+import kotlinx.coroutines.DisposableHandle
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.launch
+
+/** Binds a [TimerView] to its [view model][TimerViewModel]. */
+object TimerViewBinder {
+    fun bindWhileAttached(
+        view: TimerView,
+        viewModel: TimerViewModel,
+    ): DisposableHandle {
+        return view.repeatWhenAttached { lifecycleScope.launch { bind(view, viewModel) } }
+    }
+
+    suspend fun bind(
+        view: TimerView,
+        viewModel: TimerViewModel,
+    ) = coroutineScope {
+        launch { viewModel.icon.collect { view.setIcon(it) } }
+        launch { viewModel.label.collect { view.setLabel(it) } }
+        launch { viewModel.pausedTime.collect { view.setPausedTime(it) } }
+        launch { viewModel.countdownTime.collect { view.setCountdownTime(it) } }
+        launch { viewModel.mainButtonModel.collect { bind(view.mainButton, it) } }
+        launch { viewModel.altButtonModel.collect { bind(view.altButton, it) } }
+    }
+
+    fun bind(buttonView: TimerButtonView, model: TimerViewModel.ButtonViewModel?) {
+        if (model != null) {
+            buttonView.setIcon(model.iconRes)
+            buttonView.setText(model.labelRes)
+            buttonView.setOnClickListener(
+                model.pendingIntent?.let { pendingIntent ->
+                    View.OnClickListener { pendingIntent.send() }
+                }
+            )
+            buttonView.isEnabled = model.pendingIntent != null
+        }
+        buttonView.isGone = model == null
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/RichOngoingViewModelComponent.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/RichOngoingViewModelComponent.kt
new file mode 100644
index 0000000..dad52a3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/RichOngoingViewModelComponent.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.row.ui.viewmodel
+
+// noinspection CleanArchitectureDependencyViolation
+import com.android.systemui.statusbar.notification.row.data.repository.NotificationRowRepository
+import dagger.BindsInstance
+import dagger.Subcomponent
+
+@Subcomponent
+interface RichOngoingViewModelComponent {
+
+    @Subcomponent.Factory
+    interface Factory {
+        /** Creates an instance of [RichOngoingViewModelComponent]. */
+        fun create(
+            @BindsInstance repository: NotificationRowRepository
+        ): RichOngoingViewModelComponent
+    }
+
+    fun createTimerViewModel(): TimerViewModel
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/TimerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/TimerViewModel.kt
new file mode 100644
index 0000000..a85c87f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/TimerViewModel.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.row.ui.viewmodel
+
+import android.annotation.DrawableRes
+import android.annotation.StringRes
+import android.app.PendingIntent
+import android.graphics.drawable.Drawable
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.statusbar.notification.row.domain.interactor.NotificationRowInteractor
+import com.android.systemui.statusbar.notification.row.shared.RichOngoingNotificationFlag
+import com.android.systemui.statusbar.notification.row.shared.TimerContentModel.TimerState
+import com.android.systemui.util.kotlin.FlowDumperImpl
+import java.time.Duration
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.mapNotNull
+
+/** A view model for Timer notifications. */
+class TimerViewModel
+@Inject
+constructor(
+    dumpManager: DumpManager,
+    rowInteractor: NotificationRowInteractor,
+) : FlowDumperImpl(dumpManager) {
+    init {
+        /* check if */ RichOngoingNotificationFlag.isUnexpectedlyInLegacyMode()
+    }
+
+    private val state: Flow<TimerState> = rowInteractor.timerContentModel.mapNotNull { it.state }
+
+    val icon: Flow<Drawable?> = rowInteractor.timerContentModel.mapNotNull { it.icon.drawable }
+
+    val label: Flow<String> = rowInteractor.timerContentModel.mapNotNull { it.name }
+
+    val countdownTime: Flow<Long?> = state.map { (it as? TimerState.Running)?.finishTime }
+
+    val pausedTime: Flow<String?> =
+        state.map { (it as? TimerState.Paused)?.timeRemaining?.format() }
+
+    val mainButtonModel: Flow<ButtonViewModel> =
+        state.map {
+            when (it) {
+                is TimerState.Paused ->
+                    ButtonViewModel(
+                        it.resumeIntent,
+                        com.android.systemui.res.R.string.controls_media_resume, // "Resume",
+                        com.android.systemui.res.R.drawable.ic_media_play
+                    )
+                is TimerState.Running ->
+                    ButtonViewModel(
+                        it.pauseIntent,
+                        com.android.systemui.res.R.string.controls_media_button_pause, // "Pause",
+                        com.android.systemui.res.R.drawable.ic_media_pause
+                    )
+            }
+        }
+
+    val altButtonModel: Flow<ButtonViewModel?> =
+        state.map {
+            when (it) {
+                is TimerState.Paused ->
+                    it.resetIntent?.let { resetIntent ->
+                        ButtonViewModel(
+                            resetIntent,
+                            com.android.systemui.res.R.string.reset, // "Reset",
+                            com.android.systemui.res.R.drawable.ic_close_white_rounded
+                        )
+                    }
+                is TimerState.Running ->
+                    it.addOneMinuteIntent?.let { addOneMinuteIntent ->
+                        ButtonViewModel(
+                            addOneMinuteIntent,
+                            com.android.systemui.res.R.string.add, // "Add 1 minute",
+                            com.android.systemui.res.R.drawable.ic_add
+                        )
+                    }
+            }
+        }
+
+    data class ButtonViewModel(
+        val pendingIntent: PendingIntent?,
+        @StringRes val labelRes: Int,
+        @DrawableRes val iconRes: Int,
+    )
+}
+
+private fun Duration.format(): String {
+    val hours = this.toHours()
+    return if (hours > 0) {
+        String.format("%d:%02d:%02d", hours, toMinutesPart(), toSecondsPart())
+    } else {
+        String.format("%d:%02d", toMinutes(), toSecondsPart())
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
index 9394249..f352123 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
@@ -36,6 +36,7 @@
 
 import com.android.app.animation.Interpolators;
 import com.android.internal.widget.CachingIconView;
+import com.android.internal.widget.NotificationCloseButton;
 import com.android.internal.widget.NotificationExpandButton;
 import com.android.systemui.res.R;
 import com.android.systemui.statusbar.TransformableView;
@@ -60,6 +61,7 @@
             = new PathInterpolator(0.4f, 0f, 0.7f, 1f);
     protected final ViewTransformationHelper mTransformationHelper;
     private CachingIconView mIcon;
+    private NotificationCloseButton mCloseButton;
     private NotificationExpandButton mExpandButton;
     private View mAltExpandTarget;
     private View mIconContainer;
@@ -112,6 +114,7 @@
                 TRANSFORMING_VIEW_TITLE);
         resolveHeaderViews();
         addFeedbackOnClickListener(row);
+        addCloseButtonOnClickListener(row);
     }
 
     @Override
@@ -150,6 +153,7 @@
         mNotificationTopLine = mView.findViewById(com.android.internal.R.id.notification_top_line);
         mAudiblyAlertedIcon = mView.findViewById(com.android.internal.R.id.alerted_icon);
         mFeedbackIcon = mView.findViewById(com.android.internal.R.id.feedback);
+        mCloseButton = mView.findViewById(com.android.internal.R.id.close_button);
     }
 
     private void addFeedbackOnClickListener(ExpandableNotificationRow row) {
@@ -179,6 +183,13 @@
         }
     }
 
+    private void addCloseButtonOnClickListener(ExpandableNotificationRow row) {
+        View.OnClickListener listener = row.getCloseButtonOnClickListener(row);
+        if (mCloseButton != null && listener != null) {
+            mCloseButton.setOnClickListener(listener);
+        }
+    }
+
     @Override
     public void onContentUpdated(ExpandableNotificationRow row) {
         super.onContentUpdated(row);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/GroupHunAnimationFix.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/GroupHunAnimationFix.kt
new file mode 100644
index 0000000..5867612
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/GroupHunAnimationFix.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.shared
+
+import com.android.systemui.Flags
+import com.android.systemui.flags.FlagToken
+import com.android.systemui.flags.RefactorFlagUtils
+
+/** Helper for com.android.systemui.Flags.FLAG_NOTIFICATION_GROUP_HUN_REMOVAL_ANIMATION_FIX */
+@Suppress("NOTHING_TO_INLINE")
+object GroupHunAnimationFix {
+    const val FLAG_NAME = Flags.FLAG_NOTIFICATION_GROUP_HUN_REMOVAL_ANIMATION_FIX
+
+    /** A token used for dependency declaration */
+    val token: FlagToken
+        get() = FlagToken(FLAG_NAME, isEnabled)
+
+    /** Are sections sorted by time? */
+    @JvmStatic
+    inline val isEnabled
+        get() = Flags.notificationGroupHunRemovalAnimationFix()
+
+    /**
+     * Called to ensure code is only run when the flag is enabled. This protects users from the
+     * unintended behaviors caused by accidentally running new logic, while also crashing on an eng
+     * build to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun isUnexpectedlyInLegacyMode() =
+        RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+    /**
+     * Called to ensure code is only run when the flag is disabled. This will throw an exception if
+     * the flag is enabled to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/TransparentHeaderFix.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/TransparentHeaderFix.kt
new file mode 100644
index 0000000..0b01510
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/TransparentHeaderFix.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.shared
+
+import com.android.systemui.Flags
+import com.android.systemui.flags.FlagToken
+import com.android.systemui.flags.RefactorFlagUtils
+
+/** Helper for reading or using the notification transparent header fix flag state. */
+@Suppress("NOTHING_TO_INLINE")
+object TransparentHeaderFix {
+    /** The aconfig flag name */
+    const val FLAG_NAME = Flags.FLAG_NOTIFICATION_TRANSPARENT_HEADER_FIX
+
+    /** A token used for dependency declaration */
+    val token: FlagToken
+        get() = FlagToken(FLAG_NAME, isEnabled)
+
+    /** Is the flag enabled */
+    @JvmStatic
+    inline val isEnabled
+        get() = Flags.notificationTransparentHeaderFix()
+
+    /**
+     * Called to ensure code is only run when the flag is enabled. This protects users from the
+     * unintended behaviors caused by accidentally running new logic, while also crashing on an eng
+     * build to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun isUnexpectedlyInLegacyMode() =
+        RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+    /**
+     * Called to ensure code is only run when the flag is disabled. This will throw an exception if
+     * the flag is enabled to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index 5f4e832..fbddc06 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -29,6 +29,7 @@
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.res.R;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.StatusBarState;
@@ -63,6 +64,8 @@
      *  Used to read bouncer states.
      */
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    private float mStackTop;
+    private float mStackCutoff;
     private int mScrollY;
     private float mOverScrollTopAmount;
     private float mOverScrollBottomAmount;
@@ -128,13 +131,13 @@
     /** Distance of top of notifications panel from top of screen. */
     private float mStackY = 0;
 
-    /** Height of notifications panel. */
+    /** Height of notifications panel interpolated by the expansion fraction. */
     private float mStackHeight = 0;
 
     /** Fraction of shade expansion. */
     private float mExpansionFraction;
 
-    /** Height of the notifications panel without top padding when expansion completes. */
+    /** Height of the notifications panel when expansion completes. */
     private float mStackEndHeight;
 
     /** Whether we are swiping up. */
@@ -173,8 +176,7 @@
     }
 
     /**
-     * @param stackEndHeight Height of the notifications panel without top padding
-     *                       when expansion completes.
+     * @see #getStackEndHeight()
      */
     public void setStackEndHeight(float stackEndHeight) {
         mStackEndHeight = stackEndHeight;
@@ -184,6 +186,7 @@
      * @param stackY Distance of top of notifications panel from top of screen.
      */
     public void setStackY(float stackY) {
+        SceneContainerFlag.assertInLegacyMode();
         mStackY = stackY;
     }
 
@@ -191,6 +194,7 @@
      * @return Distance of top of notifications panel from top of screen.
      */
     public float getStackY() {
+        SceneContainerFlag.assertInLegacyMode();
         return mStackY;
     }
 
@@ -252,14 +256,14 @@
     }
 
     /**
-     * @param stackHeight Height of notifications panel.
+     * @see #getStackHeight()
      */
     public void setStackHeight(float stackHeight) {
         mStackHeight = stackHeight;
     }
 
     /**
-     * @return Height of notifications panel.
+     * @return Height of notifications panel interpolated by the expansion fraction.
      */
     public float getStackHeight() {
         return mStackHeight;
@@ -346,6 +350,33 @@
         return mZDistanceBetweenElements;
     }
 
+    /** Y coordinate in view pixels of the top of the notification stack */
+    public float getStackTop() {
+        if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return 0f;
+        return mStackTop;
+    }
+
+    /** @see #getStackTop() */
+    public void setStackTop(float mStackTop) {
+        if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return;
+        this.mStackTop = mStackTop;
+    }
+
+    /**
+     * Y coordinate in view pixels above which the bottom of the notification stack / shelf / footer
+     * must be.
+     */
+    public float getStackCutoff() {
+        if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return 0f;
+        return mStackCutoff;
+    }
+
+    /** @see #getStackCutoff() */
+    public void setStackCutoff(float stackCutoff) {
+        if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return;
+        this.mStackCutoff = stackCutoff;
+    }
+
     public int getScrollY() {
         return mScrollY;
     }
@@ -752,6 +783,8 @@
 
     @Override
     public void dump(PrintWriter pw, String[] args) {
+        pw.println("mStackTop=" + mStackTop);
+        pw.println("mStackCutoff" + mStackCutoff);
         pw.println("mTopPadding=" + mTopPadding);
         pw.println("mStackTopMargin=" + mStackTopMargin);
         pw.println("mStackTranslation=" + mStackTranslation);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationPriorityBucket.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationPriorityBucket.kt
index fabb696..f4a4527 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationPriorityBucket.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationPriorityBucket.kt
@@ -20,6 +20,10 @@
             BUCKET_PRIORITY_PEOPLE,
             BUCKET_PEOPLE,
             BUCKET_ALERTING,
+            BUCKET_NEWS,
+            BUCKET_SOCIAL,
+            BUCKET_RECS,
+            BUCKET_PROMO,
             BUCKET_SILENT
         ]
 )
@@ -35,6 +39,10 @@
                 BUCKET_PRIORITY_PEOPLE,
                 BUCKET_PEOPLE,
                 BUCKET_ALERTING,
+                BUCKET_NEWS,
+                BUCKET_SOCIAL,
+                BUCKET_RECS,
+                BUCKET_PROMO,
                 BUCKET_SILENT,
             )
     }
@@ -49,4 +57,9 @@
 const val BUCKET_PRIORITY_PEOPLE = 7
 const val BUCKET_PEOPLE = 4
 const val BUCKET_ALERTING = 5
+const val BUCKET_NEWS = 10
+const val BUCKET_SOCIAL = 11
+const val BUCKET_RECS = 12
+const val BUCKET_PROMO = 13
 const val BUCKET_SILENT = 6
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
index 3400ad1..7441c70 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
@@ -22,12 +22,10 @@
 import com.android.systemui.media.controls.ui.controller.KeyguardMediaController
 import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
 import com.android.systemui.statusbar.notification.SourceType
+import com.android.systemui.statusbar.notification.collection.NotificationClassificationFlag
 import com.android.systemui.statusbar.notification.collection.render.MediaContainerController
 import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController
-import com.android.systemui.statusbar.notification.dagger.AlertingHeader
-import com.android.systemui.statusbar.notification.dagger.IncomingHeader
-import com.android.systemui.statusbar.notification.dagger.PeopleHeader
-import com.android.systemui.statusbar.notification.dagger.SilentHeader
+import com.android.systemui.statusbar.notification.dagger.*
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.ExpandableView
 import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider
@@ -51,7 +49,11 @@
     @IncomingHeader private val incomingHeaderController: SectionHeaderController,
     @PeopleHeader private val peopleHeaderController: SectionHeaderController,
     @AlertingHeader private val alertingHeaderController: SectionHeaderController,
-    @SilentHeader private val silentHeaderController: SectionHeaderController
+    @SilentHeader private val silentHeaderController: SectionHeaderController,
+    @NewsHeader private val newsHeaderController: SectionHeaderController,
+    @SocialHeader private val socialHeaderController: SectionHeaderController,
+    @RecsHeader private val recsHeaderController: SectionHeaderController,
+    @PromoHeader private val promoHeaderController: SectionHeaderController
 ) : SectionProvider {
 
     private val configurationListener =
@@ -84,6 +86,22 @@
     val mediaControlsView: MediaContainerView?
         get() = mediaContainerController.mediaContainerView
 
+    @VisibleForTesting
+    val newsHeaderView: SectionHeaderView?
+        get() = newsHeaderController.headerView
+
+    @VisibleForTesting
+    val socialHeaderView: SectionHeaderView?
+        get() = socialHeaderController.headerView
+
+    @VisibleForTesting
+    val recsHeaderView: SectionHeaderView?
+        get() = recsHeaderController.headerView
+
+    @VisibleForTesting
+    val promoHeaderView: SectionHeaderView?
+        get() = promoHeaderController.headerView
+
     /** Must be called before use. */
     fun initialize(parent: NotificationStackScrollLayout) {
         check(!initialized) { "NotificationSectionsManager already initialized" }
@@ -107,15 +125,24 @@
         incomingHeaderController.reinflateView(parent)
         mediaContainerController.reinflateView(parent)
         keyguardMediaController.attachSinglePaneContainer(mediaControlsView)
+        if (NotificationClassificationFlag.isEnabled) {
+            newsHeaderController.reinflateView(parent)
+            socialHeaderController.reinflateView(parent)
+            recsHeaderController.reinflateView(parent)
+            promoHeaderController.reinflateView(parent)
+        }
     }
 
     override fun beginsSection(view: View, previous: View?): Boolean =
         view === silentHeaderView ||
-            view === mediaControlsView ||
-            view === peopleHeaderView ||
-            view === alertingHeaderView ||
-            view === incomingHeaderView ||
-            getBucket(view) != getBucket(previous)
+                view === mediaControlsView ||
+                view === peopleHeaderView ||
+                view === alertingHeaderView ||
+                view === incomingHeaderView ||
+                (NotificationClassificationFlag.isEnabled && (view === newsHeaderView
+                        || view === socialHeaderView || view === recsHeaderView
+                        || view === promoHeaderView)) ||
+                getBucket(view) != getBucket(previous)
 
     private fun getBucket(view: View?): Int? =
         when {
@@ -124,6 +151,10 @@
             view === mediaControlsView -> BUCKET_MEDIA_CONTROLS
             view === peopleHeaderView -> BUCKET_PEOPLE
             view === alertingHeaderView -> BUCKET_ALERTING
+            view === newsHeaderView -> BUCKET_NEWS
+            view === socialHeaderView -> BUCKET_SOCIAL
+            view === recsHeaderView -> BUCKET_RECS
+            view === promoHeaderView -> BUCKET_PROMO
             view is ExpandableNotificationRow -> view.entry.bucket
             else -> null
         }
@@ -255,6 +286,12 @@
         peopleHeaderView?.setForegroundColors(onSurface, onSurfaceVariant)
         silentHeaderView?.setForegroundColors(onSurface, onSurfaceVariant)
         alertingHeaderView?.setForegroundColors(onSurface, onSurfaceVariant)
+        if (NotificationClassificationFlag.isEnabled) {
+            newsHeaderView?.setForegroundColors(onSurface, onSurfaceVariant)
+            socialHeaderView?.setForegroundColors(onSurface, onSurfaceVariant)
+            recsHeaderView?.setForegroundColors(onSurface, onSurfaceVariant)
+            promoHeaderView?.setForegroundColors(onSurface, onSurfaceVariant)
+        }
     }
 
     companion object {
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 71a0b94..dab3799 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
@@ -89,7 +89,6 @@
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.res.R;
 import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.shade.TouchLogger;
@@ -620,8 +619,6 @@
 
     @Nullable
     private OnClickListener mManageButtonClickListener;
-    @Nullable
-    private OnNotificationRemovedListener mOnNotificationRemovedListener;
 
     public NotificationStackScrollLayout(Context context, AttributeSet attrs) {
         super(context, attrs, 0, 0);
@@ -773,10 +770,6 @@
                 && !mIsRemoteInputActive;
     }
 
-    public NotificationSwipeActionHelper getSwipeActionHelper() {
-        return mSwipeHelper;
-    }
-
     void updateBgColor() {
         for (int i = 0; i < getChildCount(); i++) {
             View child = getChildAt(i);
@@ -834,11 +827,11 @@
         drawDebugInfo(canvas, y, Color.RED, /* label= */ "y = " + y);
 
         if (SceneContainerFlag.isEnabled()) {
-            y = (int) mScrollViewFields.getStackTop();
+            y = (int) mAmbientState.getStackTop();
             drawDebugInfo(canvas, y, Color.RED, /* label= */ "getStackTop() = " + y);
 
-            y = (int) mScrollViewFields.getStackBottom();
-            drawDebugInfo(canvas, y, Color.MAGENTA, /* label= */ "getStackBottom() = " + y);
+            y = (int) mAmbientState.getStackCutoff();
+            drawDebugInfo(canvas, y, Color.MAGENTA, /* label= */ "getStackCutoff() = " + y);
 
             y = (int) mScrollViewFields.getHeadsUpTop();
             drawDebugInfo(canvas, y, Color.GREEN, /* label= */ "getHeadsUpTop() = " + y);
@@ -1181,9 +1174,11 @@
         updateAlgorithmLayoutMinHeight();
         updateOwnTranslationZ();
 
-        // Give The Algorithm information regarding the QS height so it can layout notifications
-        // properly. Needed for some devices that grows notifications down-to-top
-        mStackScrollAlgorithm.updateQSFrameTop(mQsHeader == null ? 0 : mQsHeader.getHeight());
+        if (!SceneContainerFlag.isEnabled()) {
+            // Give The Algorithm information regarding the QS height so it can layout notifications
+            // properly. Needed for some devices that grows notifications down-to-top
+            mStackScrollAlgorithm.updateQSFrameTop(mQsHeader == null ? 0 : mQsHeader.getHeight());
+        }
 
         // Once the layout has finished, we don't need to animate any scrolling clampings anymore.
         mAnimateStackYForContentHeightChange = false;
@@ -1214,14 +1209,14 @@
 
     @Override
     public void setStackTop(float stackTop) {
-        mScrollViewFields.setStackTop(stackTop);
+        mAmbientState.setStackTop(stackTop);
         // TODO(b/332574413): replace the following with using stackTop
         updateTopPadding(stackTop, isAddOrRemoveAnimationPending());
     }
 
     @Override
-    public void setStackBottom(float stackBottom) {
-        mScrollViewFields.setStackBottom(stackBottom);
+    public void setStackCutoff(float stackCutoff) {
+        mAmbientState.setStackCutoff(stackCutoff);
     }
 
     @Override
@@ -1424,11 +1419,7 @@
         if (mAmbientState.isBouncerInTransit() && mQsExpansionFraction > 0f) {
             fraction = BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(fraction);
         }
-        // TODO(b/322228881): Clean up scene container vs legacy behavior in NSSL
-        if (SceneContainerFlag.isEnabled()) {
-            // stackY should be driven by scene container, not NSSL
-            mAmbientState.setStackY(getTopPadding());
-        } else {
+        if (!SceneContainerFlag.isEnabled()) {
             final float stackY = MathUtils.lerp(0, endTopPosition, fraction);
             mAmbientState.setStackY(stackY);
         }
@@ -1442,22 +1433,40 @@
     @VisibleForTesting
     public void updateStackEndHeightAndStackHeight(float fraction) {
         final float oldStackHeight = mAmbientState.getStackHeight();
-        if (mQsExpansionFraction <= 0 && !shouldSkipHeightUpdate()) {
-            final float endHeight = updateStackEndHeight(
-                    getHeight(), getEmptyBottomMargin(), getTopPadding());
+        if (SceneContainerFlag.isEnabled()) {
+            final float endHeight;
+            if (!shouldSkipHeightUpdate()) {
+                endHeight = updateStackEndHeight();
+            } else {
+                endHeight = mAmbientState.getStackEndHeight();
+            }
             updateStackHeight(endHeight, fraction);
         } else {
-            // Always updateStackHeight to prevent jumps in the stack height when this fraction
-            // suddenly reapplies after a freeze.
-            final float endHeight = mAmbientState.getStackEndHeight();
-            updateStackHeight(endHeight, fraction);
+            if (mQsExpansionFraction <= 0 && !shouldSkipHeightUpdate()) {
+                final float endHeight = updateStackEndHeight(
+                        getHeight(), getEmptyBottomMargin(), getTopPadding());
+                updateStackHeight(endHeight, fraction);
+            } else {
+                // Always updateStackHeight to prevent jumps in the stack height when this fraction
+                // suddenly reapplies after a freeze.
+                final float endHeight = mAmbientState.getStackEndHeight();
+                updateStackHeight(endHeight, fraction);
+            }
         }
         if (oldStackHeight != mAmbientState.getStackHeight()) {
             requestChildrenUpdate();
         }
     }
 
+    private float updateStackEndHeight() {
+        if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return 0f;
+        float height = Math.max(0f, mAmbientState.getStackCutoff() - mAmbientState.getStackTop());
+        mAmbientState.setStackEndHeight(height);
+        return height;
+    }
+
     private float updateStackEndHeight(float height, float bottomMargin, float topPadding) {
+        SceneContainerFlag.assertInLegacyMode();
         final float stackEndHeight;
         if (mMaxDisplayedNotifications != -1) {
             // The stack intrinsic height already contains the correct value when there is a limit
@@ -1491,6 +1500,7 @@
      * needed.
      */
     void setOnStackYChanged(Consumer<Boolean> onStackYChanged) {
+        SceneContainerFlag.assertInLegacyMode();
         mOnStackYChanged = onStackYChanged;
     }
 
@@ -1811,6 +1821,7 @@
     }
 
     public void setQsHeader(ViewGroup qsHeader) {
+        SceneContainerFlag.assertInLegacyMode();
         mQsHeader = qsHeader;
     }
 
@@ -1963,17 +1974,6 @@
         return insets;
     }
 
-    private final Runnable mReclamp = new Runnable() {
-        @Override
-        public void run() {
-            int range = getScrollRange();
-            mScroller.startScroll(mScrollX, mOwnScrollY, 0, range - mOwnScrollY);
-            mDontReportNextOverScroll = true;
-            mDontClampNextScroll = true;
-            animateScroll();
-        }
-    };
-
     public void setExpandingEnabled(boolean enable) {
         mExpandHelper.setEnabled(enable);
     }
@@ -2271,6 +2271,7 @@
 
     public void setOverscrollTopChangedListener(
             OnOverscrollTopChangedListener overscrollTopChangedListener) {
+        SceneContainerFlag.assertInLegacyMode();
         mOverscrollTopChangedListener = overscrollTopChangedListener;
     }
 
@@ -2427,17 +2428,6 @@
         return null;
     }
 
-    private ExpandableNotificationRow getLastRowNotGone() {
-        int childCount = getChildCount();
-        for (int i = childCount - 1; i >= 0; i--) {
-            View child = getChildAt(i);
-            if (child instanceof ExpandableNotificationRow && child.getVisibility() != View.GONE) {
-                return (ExpandableNotificationRow) child;
-            }
-        }
-        return null;
-    }
-
     /**
      * @return the number of children which have visibility unequal to GONE
      */
@@ -2453,8 +2443,9 @@
         return count;
     }
 
-    private void updateContentHeight() {
-        final float scrimTopPadding = mAmbientState.isOnKeyguard() ? 0 : mMinimumPaddings;
+    @VisibleForTesting
+    void updateContentHeight() {
+        final float scrimTopPadding = getScrimTopPaddingOrZero();
         final int shelfIntrinsicHeight = mShelf != null ? mShelf.getIntrinsicHeight() : 0;
         final int footerIntrinsicHeight = mFooterView != null ? mFooterView.getIntrinsicHeight() : 0;
         final float height =
@@ -2662,6 +2653,7 @@
     }
 
     public void setMaxTopPadding(int maxTopPadding) {
+        SceneContainerFlag.assertInLegacyMode();
         mMaxTopPadding = maxTopPadding;
     }
 
@@ -2682,13 +2674,10 @@
     }
 
     public float getTopPaddingOverflow() {
+        SceneContainerFlag.assertInLegacyMode();
         return mTopPaddingOverflow;
     }
 
-    private int clampPadding(int desiredPadding) {
-        return Math.max(desiredPadding, mIntrinsicPadding);
-    }
-
     private float getRubberBandFactor(boolean onTop) {
         if (!onTop) {
             return RUBBER_BAND_FACTOR_NORMAL;
@@ -2961,7 +2950,7 @@
         return view.getHeight();
     }
 
-    public int getPositionInLinearLayout(View requestedView) {
+    private int getPositionInLinearLayout(View requestedView) {
         ExpandableNotificationRow childInGroup = null;
         ExpandableNotificationRow requestedRow = null;
         if (isChildInGroup(requestedView)) {
@@ -2970,7 +2959,7 @@
             childInGroup = (ExpandableNotificationRow) requestedView;
             requestedView = requestedRow = childInGroup.getNotificationParent();
         }
-        final float scrimTopPadding = mAmbientState.isOnKeyguard() ? 0 : mMinimumPaddings;
+        final float scrimTopPadding = getScrimTopPaddingOrZero();
         int position = (int) scrimTopPadding;
         int visibleIndex = -1;
         ExpandableView lastVisibleChild = null;
@@ -3000,6 +2989,17 @@
         return 0;
     }
 
+    /**
+     * Returns the top scrim padding, or zero if the SceneContainer flag is enabled.
+     */
+    private int getScrimTopPaddingOrZero() {
+        if (SceneContainerFlag.isEnabled()) {
+            // the scrim padding is set on the notification placeholder
+            return 0;
+        }
+        return mAmbientState.isOnKeyguard() ? 0 : mMinimumPaddings;
+    }
+
     @Override
     public void onViewAdded(View child) {
         super.onViewAdded(child);
@@ -3511,6 +3511,13 @@
         setIsBeingDragged(true);
     }
 
+    // Only when scene container is enabled, mark that we are being dragged so that we start
+    // dispatching the rest of the gesture to scene container.
+    void startDraggingOnHun() {
+        SceneContainerFlag.isUnexpectedlyInLegacyMode();
+        setIsBeingDragged(true);
+    }
+
     @Override
     public boolean onGenericMotionEvent(MotionEvent event) {
         if (!isScrollingEnabled()
@@ -3721,7 +3728,7 @@
 
     protected boolean isInsideQsHeader(MotionEvent ev) {
         if (SceneContainerFlag.isEnabled()) {
-            return ev.getY() < mScrollViewFields.getStackTop();
+            return ev.getY() < mAmbientState.getStackTop();
         }
 
         mQsHeader.getBoundsOnScreen(mQsHeaderBound);
@@ -4455,6 +4462,7 @@
     }
 
     void goToFullShade(long delay) {
+        SceneContainerFlag.assertInLegacyMode();
         mGoToFullShadeNeedsAnimation = true;
         mGoToFullShadeDelay = delay;
         mNeedsAnimation = true;
@@ -4641,6 +4649,7 @@
     }
 
     public boolean isEmptyShadeViewVisible() {
+        SceneContainerFlag.assertInLegacyMode();
         return mEmptyShadeView.isVisible();
     }
 
@@ -4919,6 +4928,7 @@
     }
 
     public void setQsFullScreen(boolean qsFullScreen) {
+        SceneContainerFlag.assertInLegacyMode();
         if (FooterViewRefactor.isEnabled()) {
             if (qsFullScreen == mQsFullScreen) {
                 return;  // no change
@@ -5095,6 +5105,7 @@
     }
 
     public void setExpandingVelocity(float expandingVelocity) {
+        SceneContainerFlag.assertInLegacyMode();
         mAmbientState.setExpandingVelocity(expandingVelocity);
     }
 
@@ -5715,6 +5726,7 @@
      * Set a listener to when scrolling changes.
      */
     public void setOnScrollListener(Consumer<Integer> listener) {
+        SceneContainerFlag.assertInLegacyMode();
         mScrollListener = listener;
     }
 
@@ -6560,16 +6572,4 @@
         void onAnimationEnd(
                 List<ExpandableNotificationRow> viewsToRemove, @SelectedRows int selectedRows);
     }
-
-    /**
-     *
-     */
-    public interface OnNotificationRemovedListener {
-        /**
-         *
-         * @param child
-         * @param isTransferInProgress
-         */
-        void onNotificationRemoved(ExpandableView child, boolean isTransferInProgress);
-    }
 }
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 6a3055f..36930bf 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
@@ -59,6 +59,7 @@
 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.internal.view.OneShotPreDrawListener;
 import com.android.systemui.Dumpable;
 import com.android.systemui.ExpandHelper;
@@ -68,7 +69,6 @@
 import com.android.systemui.classifier.FalsingCollector;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.keyguard.MigrateClocksToBlueprint;
 import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository;
 import com.android.systemui.keyguard.shared.model.KeyguardState;
 import com.android.systemui.keyguard.shared.model.TransitionStep;
@@ -127,6 +127,7 @@
 import com.android.systemui.statusbar.notification.shared.NotificationsHeadsUpRefactor;
 import com.android.systemui.statusbar.notification.stack.ui.viewbinder.NotificationListViewBinder;
 import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
+import com.android.systemui.statusbar.phone.HeadsUpNotificationViewControllerEmptyImpl;
 import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -169,6 +170,7 @@
     private final NotificationVisibilityProvider mVisibilityProvider;
     private final NotificationWakeUpCoordinator mWakeUpCoordinator;
     private final HeadsUpManager mHeadsUpManager;
+    private HeadsUpTouchHelper mHeadsUpTouchHelper;
     private final NotificationRoundnessManager mNotificationRoundnessManager;
     private final TunerService mTunerService;
     private final DeviceProvisionedController mDeviceProvisionedController;
@@ -707,6 +709,7 @@
             NotificationVisibilityProvider visibilityProvider,
             NotificationWakeUpCoordinator wakeUpCoordinator,
             HeadsUpManager headsUpManager,
+            Provider<IStatusBarService> statusBarService,
             NotificationRoundnessManager notificationRoundnessManager,
             TunerService tunerService,
             DeviceProvisionedController deviceProvisionedController,
@@ -759,6 +762,14 @@
         mVisibilityProvider = visibilityProvider;
         mWakeUpCoordinator = wakeUpCoordinator;
         mHeadsUpManager = headsUpManager;
+        if (SceneContainerFlag.isEnabled()) {
+            mHeadsUpTouchHelper = new HeadsUpTouchHelper(
+                    mHeadsUpManager,
+                    statusBarService.get(),
+                    getHeadsUpCallback(),
+                    new HeadsUpNotificationViewControllerEmptyImpl()
+            );
+        }
         mNotificationRoundnessManager = notificationRoundnessManager;
         mTunerService = tunerService;
         mDeviceProvisionedController = deviceProvisionedController;
@@ -1053,6 +1064,7 @@
 
     public void setOverscrollTopChangedListener(
             OnOverscrollTopChangedListener listener) {
+        SceneContainerFlag.assertInLegacyMode();
         mView.setOverscrollTopChangedListener(listener);
     }
 
@@ -1178,6 +1190,7 @@
     }
 
     public void goToFullShade(long delay) {
+        SceneContainerFlag.assertInLegacyMode();
         mView.goToFullShade(delay);
     }
 
@@ -1248,6 +1261,7 @@
     }
 
     public void setOnStackYChanged(Consumer<Boolean> onStackYChanged) {
+        SceneContainerFlag.assertInLegacyMode();
         mView.setOnStackYChanged(onStackYChanged);
     }
 
@@ -1320,7 +1334,10 @@
         updateAlpha();
     }
 
-    void setMaxAlphaFromView(float alpha) {
+    /**
+     * Max alpha from the containing view. Used by brightness slider as an example.
+     */
+    public void setMaxAlphaFromView(float alpha) {
         mMaxAlphaFromView = alpha;
         updateAlpha();
     }
@@ -1604,10 +1621,6 @@
         return mView.getTransientView(i);
     }
 
-    public int getPositionInLinearLayout(ExpandableView row) {
-        return mView.getPositionInLinearLayout(row);
-    }
-
     public NotificationStackScrollLayout getView() {
         return mView;
     }
@@ -1747,6 +1760,7 @@
      * Set a listener to when scrolling changes.
      */
     public void setOnScrollListener(Consumer<Integer> listener) {
+        SceneContainerFlag.assertInLegacyMode();
         mView.setOnScrollListener(listener);
     }
 
@@ -1994,6 +2008,13 @@
                     && !mView.isExpandingNotification()) {
                 scrollWantsIt = mView.onInterceptTouchEventScroll(ev);
             }
+            boolean hunWantsIt = false;
+            if (shouldHeadsUpHandleTouch()) {
+                hunWantsIt = mHeadsUpTouchHelper.onInterceptTouchEvent(ev);
+                if (hunWantsIt) {
+                    mView.startDraggingOnHun();
+                }
+            }
             boolean swipeWantsIt = false;
             if (mLongPressedView == null && !mView.isBeingDragged()
                     && !mView.isExpandingNotification()
@@ -2023,7 +2044,7 @@
                     && ev.getActionMasked() != MotionEvent.ACTION_DOWN) {
                 mJankMonitor.begin(mView, CUJ_NOTIFICATION_SHADE_SCROLL_FLING);
             }
-            return swipeWantsIt || scrollWantsIt || expandWantsIt || longPressWantsIt;
+            return swipeWantsIt || scrollWantsIt || expandWantsIt || longPressWantsIt || hunWantsIt;
         }
 
         @Override
@@ -2075,6 +2096,10 @@
                     && !expandingNotification && !mView.getDisallowScrollingInThisMotion()) {
                 scrollerWantsIt = mView.onScrollTouch(ev);
             }
+            boolean hunWantsIt = false;
+            if (shouldHeadsUpHandleTouch()) {
+                hunWantsIt = mHeadsUpTouchHelper.onTouchEvent(ev);
+            }
 
             // Check if we need to clear any snooze leavebehinds
             if (guts != null && !NotificationSwipeHelper.isTouchInView(ev, guts)
@@ -2095,7 +2120,8 @@
                 mView.setCheckForLeaveBehind(true);
             }
             traceJankOnTouchEvent(ev.getActionMasked(), scrollerWantsIt);
-            return horizontalSwipeWantsIt || scrollerWantsIt || expandWantsIt || longPressWantsIt;
+            return horizontalSwipeWantsIt || scrollerWantsIt || expandWantsIt || longPressWantsIt
+                    || hunWantsIt;
         }
 
         private void traceJankOnTouchEvent(int action, boolean scrollerWantsIt) {
@@ -2122,6 +2148,11 @@
                     break;
             }
         }
+
+        private boolean shouldHeadsUpHandleTouch() {
+            return SceneContainerFlag.isEnabled() && mLongPressedView == null
+                    && !mSwipeHelper.isSwiping();
+        }
     }
 
     private class NotifStackControllerImpl implements NotifStackController {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt
index 6afcf37..97ec391 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt
@@ -32,13 +32,6 @@
 class ScrollViewFields {
     /** Used to produce the clipping path */
     var scrimClippingShape: ShadeScrimShape? = null
-    /** Y coordinate in view pixels of the top of the notification stack */
-    var stackTop: Float = 0f
-    /**
-     * Y coordinate in view pixels above which the bottom of the notification stack / shelf / footer
-     * must be.
-     */
-    var stackBottom: Float = 0f
     /** Y coordinate in view pixels of the top of the HUN */
     var headsUpTop: Float = 0f
     /** Whether the notifications are scrolled all the way to the top (i.e. when freshly opened) */
@@ -70,17 +63,17 @@
     /** send the [syntheticScroll] to the [syntheticScrollConsumer], if present. */
     fun sendSyntheticScroll(syntheticScroll: Float) =
         syntheticScrollConsumer?.accept(syntheticScroll)
+
     /** send [isCurrentGestureOverscroll] to the [currentGestureOverscrollConsumer], if present. */
     fun sendCurrentGestureOverscroll(isCurrentGestureOverscroll: Boolean) =
         currentGestureOverscrollConsumer?.accept(isCurrentGestureOverscroll)
+
     /** send the [headsUpHeight] to the [headsUpHeightConsumer], if present. */
     fun sendHeadsUpHeight(headsUpHeight: Float) = headsUpHeightConsumer?.accept(headsUpHeight)
 
     fun dump(pw: IndentingPrintWriter) {
         pw.printSection("StackViewStates") {
             pw.println("scrimClippingShape", scrimClippingShape)
-            pw.println("stackTop", stackTop)
-            pw.println("stackBottom", stackBottom)
             pw.println("headsUpTop", headsUpTop)
             pw.println("isScrolledToTop", isScrolledToTop)
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index f9efc07..4282fa2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -29,6 +29,7 @@
 import com.android.keyguard.BouncerPanelExpansionCalculator;
 import com.android.systemui.animation.ShadeInterpolation;
 import com.android.systemui.res.R;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.NotificationShelf;
@@ -332,8 +333,10 @@
 
     private void updateClipping(StackScrollAlgorithmState algorithmState,
             AmbientState ambientState) {
-        float drawStart = ambientState.isOnKeyguard() ? 0
+        float stackTop = SceneContainerFlag.isEnabled() ? ambientState.getStackTop()
                 : ambientState.getStackY() - ambientState.getScrollY();
+        float drawStart = ambientState.isOnKeyguard() ? 0
+                : stackTop;
         float clipStart = 0;
         int childCount = algorithmState.visibleChildren.size();
         boolean firstHeadsUp = true;
@@ -442,12 +445,26 @@
         state.visibleChildren.clear();
         state.visibleChildren.ensureCapacity(childCount);
         int notGoneIndex = 0;
+        boolean emptyShadeVisible = false;
         for (int i = 0; i < childCount; i++) {
             ExpandableView v = (ExpandableView) mHostView.getChildAt(i);
             if (v.getVisibility() != View.GONE) {
                 if (v == ambientState.getShelf()) {
                     continue;
                 }
+                if (FooterViewRefactor.isEnabled()) {
+                    if (v instanceof EmptyShadeView) {
+                        emptyShadeVisible = true;
+                    }
+                    if (v instanceof FooterView) {
+                        if (emptyShadeVisible || notGoneIndex == 0) {
+                            // if the empty shade is visible or the footer is the first visible
+                            // view, we're in a transitory state so let's leave the footer alone.
+                            continue;
+                        }
+                    }
+                }
+
                 notGoneIndex = updateNotGoneIndex(state, notGoneIndex, v);
                 if (v instanceof ExpandableNotificationRow row) {
 
@@ -470,11 +487,8 @@
         // expanded. Consider updating these states in updateContentView instead so that we don't
         // have to recalculate in every frame.
         float currentY = -ambientState.getScrollY();
-        if (!ambientState.isOnKeyguard()
-                || (ambientState.isBypassEnabled() && ambientState.isPulseExpanding())) {
-            // add top padding at the start as long as we're not on the lock screen
-            currentY += mNotificationScrimPadding;
-        }
+        // add top padding at the start as long as we're not on the lock screen
+        currentY += getScrimTopPaddingOrZero(ambientState);
         state.firstViewInShelf = null;
         for (int i = 0; i < state.visibleChildren.size(); i++) {
             final ExpandableView view = state.visibleChildren.get(i);
@@ -531,11 +545,9 @@
      */
     protected void updatePositionsForState(StackScrollAlgorithmState algorithmState,
             AmbientState ambientState) {
-        if (!ambientState.isOnKeyguard()
-                || (ambientState.isBypassEnabled() && ambientState.isPulseExpanding())) {
-            algorithmState.mCurrentYPosition += mNotificationScrimPadding;
-            algorithmState.mCurrentExpandedYPosition += mNotificationScrimPadding;
-        }
+        float scrimTopPadding = getScrimTopPaddingOrZero(ambientState);
+        algorithmState.mCurrentYPosition += scrimTopPadding;
+        algorithmState.mCurrentExpandedYPosition += scrimTopPadding;
 
         int childCount = algorithmState.visibleChildren.size();
         for (int i = 0; i < childCount; i++) {
@@ -563,9 +575,7 @@
                 && algorithmState.firstViewInShelf != null;
 
         final float shelfHeight = showingShelf ? ambientState.getShelf().getIntrinsicHeight() : 0f;
-        final float scrimPadding = ambientState.isOnKeyguard()
-                && (!ambientState.isBypassEnabled() || !ambientState.isPulseExpanding())
-                ? 0 : mNotificationScrimPadding;
+        final float scrimPadding = getScrimTopPaddingOrZero(ambientState);
 
         final float stackHeight = ambientState.getStackHeight() - shelfHeight - scrimPadding;
         final float stackEndHeight = ambientState.getStackEndHeight() - shelfHeight - scrimPadding;
@@ -577,6 +587,21 @@
         return stackHeight / stackEndHeight;
     }
 
+    /**
+     * Returns the top scrim padding, or zero if the SceneContainer flag is enabled.
+     */
+    private float getScrimTopPaddingOrZero(AmbientState ambientState) {
+        if (SceneContainerFlag.isEnabled()) {
+            // the scrim padding is set on the notification placeholder
+            return 0f;
+        }
+
+        boolean shouldUsePadding =
+                !ambientState.isOnKeyguard()
+                        || (ambientState.isBypassEnabled() && ambientState.isPulseExpanding());
+        return shouldUsePadding ? mNotificationScrimPadding : 0f;
+    }
+
     private boolean hasNonClearableNotifs(StackScrollAlgorithmState algorithmState) {
         for (int i = 0; i < algorithmState.visibleChildren.size(); i++) {
             View child = algorithmState.visibleChildren.get(i);
@@ -641,9 +666,13 @@
         // Incoming views have yTranslation=0 by default.
         viewState.setYTranslation(algorithmState.mCurrentYPosition);
 
-        float viewEnd = viewState.getYTranslation() + viewState.height + ambientState.getStackY();
+        float stackTop = SceneContainerFlag.isEnabled()
+                ? ambientState.getStackTop()
+                : ambientState.getStackY();
+        float viewEnd = stackTop + viewState.getYTranslation() + viewState.height;
         maybeUpdateHeadsUpIsVisible(viewState, ambientState.isShadeExpanded(),
                 view.mustStayOnScreen(),
+                // TODO(b/332574413) use the position from the HeadsUpNotificationPlaceholder
                 /* topVisible= */ viewState.getYTranslation() >= mNotificationScrimPadding,
                 viewEnd, /* hunMax */ ambientState.getMaxHeadsUpTranslation()
         );
@@ -681,7 +710,9 @@
             }
         } else {
             if (view instanceof EmptyShadeView) {
-                float fullHeight = ambientState.getLayoutMaxHeight() + mMarginBottom
+                float fullHeight = SceneContainerFlag.isEnabled()
+                        ? ambientState.getStackCutoff() - ambientState.getStackTop()
+                        : ambientState.getLayoutMaxHeight() + mMarginBottom
                         - ambientState.getStackY();
                 viewState.setYTranslation((fullHeight - getMaxAllowedChildHeight(view)) / 2f);
             } else if (view != ambientState.getTrackedHeadsUpRow()) {
@@ -726,7 +757,7 @@
                 + mPaddingBetweenElements;
 
         setLocation(view.getViewState(), algorithmState.mCurrentYPosition, i);
-        viewState.setYTranslation(viewState.getYTranslation() + ambientState.getStackY());
+        viewState.setYTranslation(viewState.getYTranslation() + stackTop);
     }
 
     @VisibleForTesting
@@ -869,6 +900,7 @@
                     // Ensure that the heads up is always visible even when scrolled off.
                     // NSSL y starts at top of screen in non-split-shade, but below the qs offset
                     // in split shade, so we only need to inset by the scrim padding in split shade.
+                    // TODO(b/332574413) get the clamp inset from HeadsUpNotificationPlaceholder
                     final float clampInset = ambientState.getUseSplitShade()
                             ? mNotificationScrimPadding : mQuickQsOffsetHeight;
                     clampHunToTop(clampInset, ambientState.getStackTranslation(),
@@ -1002,8 +1034,11 @@
         // Animate pinned HUN bottom corners to and from original roundness.
         final float originalCornerRadius =
                 row.isLastInSection() ? 1f : (mSmallCornerRadius / mLargeCornerRadius);
+        final float stackTop = SceneContainerFlag.isEnabled()
+                ? ambientState.getStackTop()
+                : ambientState.getStackY();
         final float bottomValue = computeCornerRoundnessForPinnedHun(mHostView.getHeight(),
-                ambientState.getStackY(), getMaxAllowedChildHeight(row), originalCornerRadius);
+                stackTop, getMaxAllowedChildHeight(row), originalCornerRadius);
         row.requestBottomRoundness(bottomValue, STACK_SCROLL_ALGO);
         row.addOnDetachResetRoundness(STACK_SCROLL_ALGO);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt
index eaaa9a1..762c507 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt
@@ -50,8 +50,11 @@
     /** set the y position in px of the top of the stack in this view's coordinates */
     fun setStackTop(stackTop: Float)
 
-    /** set the y position in px of the bottom of the stack in this view's coordinates */
-    fun setStackBottom(stackBottom: Float)
+    /**
+     * set the bottom-most acceptable y-position of the bottom of the notification stack/ shelf /
+     * footer.
+     */
+    fun setStackCutoff(stackBottom: Float)
 
     /** set the y position in px of the top of the HUN in this view's coordinates */
     fun setHeadsUpTop(headsUpTop: Float)
@@ -61,8 +64,10 @@
 
     /** Set a consumer for synthetic scroll events */
     fun setSyntheticScrollConsumer(consumer: Consumer<Float>?)
+
     /** Set a consumer for current gesture overscroll events */
     fun setCurrentGestureOverscrollConsumer(consumer: Consumer<Boolean>?)
+
     /** Set a consumer for heads up height changed events */
     fun setHeadsUpHeightConsumer(consumer: Consumer<Float>?)
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
index cf5366b..497ffca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
@@ -154,6 +154,14 @@
                         }
                     }
 
+                    if (!SceneContainerFlag.isEnabled) {
+                        launch {
+                            // For when the entire view should fade, such as with the brightness
+                            // slider
+                            viewModel.panelAlpha.collect { controller.setMaxAlphaFromView(it) }
+                        }
+                    }
+
                     if (communalHub()) {
                         launch {
                             viewModel.glanceableHubAlpha.collect {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
index a21db12..57e52b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
@@ -70,10 +70,10 @@
             ) { shadeExpansion, shadeMode, qsExpansion, transitionState, quickSettingsScene ->
                 when (transitionState) {
                     is ObservableTransitionState.Idle -> {
-                        if (transitionState.currentScene == Scenes.Lockscreen) {
-                            1f
-                        } else {
-                            shadeExpansion
+                        when (transitionState.currentScene) {
+                            Scenes.Lockscreen,
+                            Scenes.QuickSettings -> 1f
+                            else -> shadeExpansion
                         }
                     }
                     is ObservableTransitionState.Transition -> {
@@ -90,8 +90,10 @@
                             1f
                         } else if (
                             shadeMode != ShadeMode.Split &&
-                                transitionState.fromScene in SceneFamilies.Home &&
-                                transitionState.toScene in quickSettingsScene
+                                (transitionState.fromScene in SceneFamilies.Home &&
+                                    transitionState.toScene == quickSettingsScene) ||
+                                (transitionState.fromScene == quickSettingsScene &&
+                                    transitionState.toScene in SceneFamilies.Home)
                         ) {
                             // during QS expansion, increase fraction at same rate as scrim alpha,
                             // but start when scrim alpha is at EXPANSION_FOR_DELAYED_STACK_FADE_IN.
@@ -160,9 +162,13 @@
         stackAppearanceInteractor::setCurrentGestureOverscroll
 
     /** Whether the notification stack is scrollable or not. */
-    val isScrollable: Flow<Boolean> = sceneInteractor.currentScene.map {
-        sceneInteractor.isSceneInFamily(it, SceneFamilies.NotifShade) || it == Scenes.Lockscreen
-    }.dumpWhileCollecting("isScrollable")
+    val isScrollable: Flow<Boolean> =
+        sceneInteractor.currentScene
+            .map {
+                sceneInteractor.isSceneInFamily(it, SceneFamilies.NotifShade) ||
+                    it == Scenes.Lockscreen
+            }
+            .dumpWhileCollecting("isScrollable")
 
     /** Whether the notification stack is displayed in doze mode. */
     val isDozing: Flow<Boolean> by lazy {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
index 634bd7e..eb1f778 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
@@ -20,15 +20,17 @@
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.flags.FeatureFlagsClassic
 import com.android.systemui.flags.Flags
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.ui.viewmodel.ShadeSceneViewModel
+import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
 import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
 import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimRounding
 import com.android.systemui.util.kotlin.FlowDumperImpl
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
 
 /**
  * ViewModel used by the Notification placeholders inside the scene container to update the
@@ -41,8 +43,9 @@
     dumpManager: DumpManager,
     private val interactor: NotificationStackAppearanceInteractor,
     shadeInteractor: ShadeInteractor,
+    private val shadeSceneViewModel: ShadeSceneViewModel,
+    private val headsUpNotificationInteractor: HeadsUpNotificationInteractor,
     featureFlags: FeatureFlagsClassic,
-    private val keyguardInteractor: KeyguardInteractor,
 ) : FlowDumperImpl(dumpManager) {
     /** DEBUG: whether the placeholder should be made slightly visible for positional debugging. */
     val isVisualDebuggingEnabled: Boolean = featureFlags.isEnabled(Flags.NSSL_DEBUG_LINES)
@@ -60,11 +63,23 @@
         interactor.setConstrainedAvailableSpace(height)
     }
 
+    /** Notifies that empty space on the notification scrim has been clicked. */
+    fun onEmptySpaceClicked() {
+        shadeSceneViewModel.onContentClicked()
+    }
+
     /** Sets the content alpha for the current state of the brightness mirror */
     fun setAlphaForBrightnessMirror(alpha: Float) {
         interactor.setAlphaForBrightnessMirror(alpha)
     }
 
+    /** Whether or not the notification scrim should be clickable. */
+    val isClickable: StateFlow<Boolean> = shadeSceneViewModel.isClickable
+
+    /** True when a HUN is pinned or animating away. */
+    val isHeadsUpOrAnimatingAway: Flow<Boolean> =
+        headsUpNotificationInteractor.isHeadsUpOrAnimatingAway
+
     /** Corner rounding of the stack */
     val shadeScrimRounding: Flow<ShadeScrimRounding> =
         interactor.shadeScrimRounding.dumpWhileCollecting("shadeScrimRounding")
@@ -94,6 +109,11 @@
     fun setScrolledToTop(scrolledToTop: Boolean) {
         interactor.setScrolledToTop(scrolledToTop)
     }
+
+    /** Snooze the currently pinned HUN. */
+    fun snoozeHun() {
+        headsUpNotificationInteractor.snooze()
+    }
 }
 
 // Expansion fraction thresholds (between 0-1f) at which the corresponding value should be
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index 1fc2821..d1d5d30 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -21,6 +21,7 @@
 
 import androidx.annotation.VisibleForTesting
 import com.android.systemui.common.shared.model.NotificationContainerBounds
+import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dump.DumpManager
@@ -75,6 +76,7 @@
 import com.android.systemui.util.kotlin.BooleanFlowOperators.anyOf
 import com.android.systemui.util.kotlin.FlowDumperImpl
 import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine
+import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -136,8 +138,10 @@
     private val primaryBouncerToLockscreenTransitionViewModel:
         PrimaryBouncerToLockscreenTransitionViewModel,
     private val aodBurnInViewModel: AodBurnInViewModel,
+    private val communalSceneInteractor: CommunalSceneInteractor,
     unfoldTransitionInteractor: UnfoldTransitionInteractor,
 ) : FlowDumperImpl(dumpManager) {
+    // TODO(b/349784682): Transform deprecated states for Flexiglass
     private val statesForConstrainedNotifications: Set<KeyguardState> =
         setOf(AOD, LOCKSCREEN, DOZING, ALTERNATE_BOUNCER, PRIMARY_BOUNCER)
     private val statesForHiddenKeyguard: Set<KeyguardState> = setOf(GONE, OCCLUDED)
@@ -284,7 +288,7 @@
     /** Are we on the dream without the shade/qs? */
     private val isDreamingWithoutShade: Flow<Boolean> =
         combine(
-                keyguardTransitionInteractor.isFinishedInState(DREAMING),
+                keyguardTransitionInteractor.isFinishedIn(DREAMING),
                 isAnyExpanded,
             ) { isDreaming, isAnyExpanded ->
                 isDreaming && !isAnyExpanded
@@ -369,7 +373,7 @@
                 paddingTopDimen,
                 interactor.topPosition
                     .sampleCombine(
-                        keyguardTransitionInteractor.isInTransitionToAnyState,
+                        keyguardTransitionInteractor.isInTransition,
                         shadeInteractor.qsExpansion,
                     )
                     .onStart { emit(Triple(0f, false, 0f)) }
@@ -470,6 +474,19 @@
             }
             .dumpWhileCollecting("isTransitioningToHiddenKeyguard")
 
+    val panelAlpha = keyguardInteractor.panelAlpha
+
+    private fun bouncerToGoneNotificationAlpha(viewState: ViewStateAccessor): Flow<Float> =
+        merge(
+                primaryBouncerToGoneTransitionViewModel.notificationAlpha,
+                alternateBouncerToGoneTransitionViewModel.notificationAlpha(viewState),
+            )
+            .sample(communalSceneInteractor.isCommunalVisible) { alpha, isCommunalVisible ->
+                // when glanceable hub is visible, hide notifications during the transition to GONE
+                if (isCommunalVisible) 0f else alpha
+            }
+            .dumpWhileCollecting("bouncerToGoneNotificationAlpha")
+
     fun keyguardAlpha(viewState: ViewStateAccessor): Flow<Float> {
         // All transition view models are mututally exclusive, and safe to merge
         val alphaTransitions =
@@ -477,7 +494,7 @@
                 keyguardInteractor.dismissAlpha.dumpWhileCollecting(
                     "keyguardInteractor.dismissAlpha"
                 ),
-                alternateBouncerToGoneTransitionViewModel.notificationAlpha(viewState),
+                bouncerToGoneNotificationAlpha(viewState),
                 aodToGoneTransitionViewModel.notificationAlpha(viewState),
                 aodToLockscreenTransitionViewModel.notificationAlpha,
                 aodToOccludedTransitionViewModel.lockscreenAlpha(viewState),
@@ -495,8 +512,9 @@
                 occludedToAodTransitionViewModel.lockscreenAlpha,
                 occludedToGoneTransitionViewModel.notificationAlpha(viewState),
                 occludedToLockscreenTransitionViewModel.lockscreenAlpha,
-                primaryBouncerToGoneTransitionViewModel.notificationAlpha,
                 primaryBouncerToLockscreenTransitionViewModel.lockscreenAlpha,
+                glanceableHubToLockscreenTransitionViewModel.keyguardAlpha,
+                lockscreenToGlanceableHubTransitionViewModel.keyguardAlpha,
             )
 
         return merge(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
index fae0a46..97266c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterImpl.kt
@@ -126,6 +126,7 @@
         animationController: ActivityTransitionAnimator.Controller?,
         fillInIntent: Intent?,
         extraOptions: Bundle?,
+        customMessage: String?,
     ) {
         activityStarterInternal.startPendingIntentDismissingKeyguard(
             intent = intent,
@@ -135,6 +136,7 @@
             dismissShade = dismissShade,
             fillInIntent = fillInIntent,
             extraOptions = extraOptions,
+            customMessage = customMessage,
         )
     }
 
@@ -319,11 +321,13 @@
         intent: Intent,
         onlyProvisioned: Boolean,
         dismissShade: Boolean,
+        customMessage: String?,
     ) {
         activityStarterInternal.startActivityDismissingKeyguard(
             intent = intent,
             onlyProvisioned = onlyProvisioned,
             dismissShade = dismissShade,
+            customMessage = customMessage,
         )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternal.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternal.kt
index cff9f5e..93ce6e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternal.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternal.kt
@@ -42,6 +42,7 @@
         skipLockscreenChecks: Boolean = false,
         fillInIntent: Intent? = null,
         extraOptions: Bundle? = null,
+        customMessage: String? = null,
     )
 
     /** Starts an activity after dismissing keyguard. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt
index dbb95e6..ae98e1d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarterInternalImpl.kt
@@ -42,7 +42,8 @@
         showOverLockscreen: Boolean,
         skipLockscreenChecks: Boolean,
         fillInIntent: Intent?,
-        extraOptions: Bundle?
+        extraOptions: Bundle?,
+        customMessage: String?,
     ) {
         TODO("Not yet implemented b/308819693")
     }
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 2011332..91b5d0b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -39,7 +39,7 @@
 import com.android.systemui.qs.pipeline.shared.QSPipelineFlagsRepository;
 import com.android.systemui.res.R;
 import com.android.systemui.statusbar.policy.CastController;
-import com.android.systemui.statusbar.policy.CastController.CastDevice;
+import com.android.systemui.statusbar.policy.CastDevice;
 import com.android.systemui.statusbar.policy.DataSaverController;
 import com.android.systemui.statusbar.policy.DataSaverController.Listener;
 import com.android.systemui.statusbar.policy.DeviceControlsController;
@@ -430,8 +430,7 @@
 
             boolean isCasting = false;
             for (CastDevice device : mCastController.getCastDevices()) {
-                if (device.state == CastDevice.STATE_CONNECTED
-                        || device.state == CastDevice.STATE_CONNECTING) {
+                if (device.isCasting()) {
                     isCasting = true;
                     break;
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
deleted file mode 100644
index f62a79f..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.IntDef;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.Paint;
-import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffColorFilter;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.os.SystemClock;
-import android.util.Log;
-import android.view.View;
-
-import com.android.app.animation.Interpolators;
-import com.android.settingslib.Utils;
-import com.android.systemui.res.R;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-public class BarTransitions {
-    private static final boolean DEBUG = false;
-    private static final boolean DEBUG_COLORS = false;
-
-    public static final int MODE_TRANSPARENT = 0;
-    public static final int MODE_SEMI_TRANSPARENT = 1;
-    public static final int MODE_TRANSLUCENT = 2;
-    public static final int MODE_LIGHTS_OUT = 3;
-    public static final int MODE_OPAQUE = 4;
-    public static final int MODE_WARNING = 5;
-    public static final int MODE_LIGHTS_OUT_TRANSPARENT = 6;
-
-    @IntDef(flag = true, prefix = { "MODE_" }, value = {
-            MODE_OPAQUE,
-            MODE_SEMI_TRANSPARENT,
-            MODE_TRANSLUCENT,
-            MODE_LIGHTS_OUT,
-            MODE_TRANSPARENT,
-            MODE_WARNING,
-            MODE_LIGHTS_OUT_TRANSPARENT
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface TransitionMode {}
-
-    public static final int LIGHTS_IN_DURATION = 250;
-    public static final int LIGHTS_OUT_DURATION = 1500;
-    public static final int BACKGROUND_DURATION = 200;
-
-    private final String mTag;
-    private final View mView;
-    protected final BarBackgroundDrawable mBarBackground;
-
-    private @TransitionMode int mMode;
-    private boolean mAlwaysOpaque = false;
-
-    public BarTransitions(View view, int gradientResourceId) {
-        mTag = "BarTransitions." + view.getClass().getSimpleName();
-        mView = view;
-        mBarBackground = new BarBackgroundDrawable(mView.getContext(), gradientResourceId);
-        mView.setBackground(mBarBackground);
-    }
-
-    public void destroy() {
-        // To be overridden
-    }
-
-    public int getMode() {
-        return mMode;
-    }
-
-    public void setAutoDim(boolean autoDim) {
-        // Default is don't care.
-    }
-
-    /**
-     * @param alwaysOpaque if {@code true}, the bar's background will always be opaque, regardless
-     *         of what mode it is currently set to.
-     */
-    public void setAlwaysOpaque(boolean alwaysOpaque) {
-        mAlwaysOpaque = alwaysOpaque;
-    }
-
-    public boolean isAlwaysOpaque() {
-        // Low-end devices do not support translucent modes, fallback to opaque
-        return mAlwaysOpaque;
-    }
-
-    public void transitionTo(int mode, boolean animate) {
-        if (isAlwaysOpaque() && (mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSLUCENT
-                || mode == MODE_TRANSPARENT)) {
-            mode = MODE_OPAQUE;
-        }
-        if (isAlwaysOpaque() && (mode == MODE_LIGHTS_OUT_TRANSPARENT)) {
-            mode = MODE_LIGHTS_OUT;
-        }
-        if (mMode == mode) return;
-        int oldMode = mMode;
-        mMode = mode;
-        if (DEBUG) Log.d(mTag, String.format("%s -> %s animate=%s",
-                modeToString(oldMode), modeToString(mode),  animate));
-        onTransition(oldMode, mMode, animate);
-    }
-
-    protected void onTransition(int oldMode, int newMode, boolean animate) {
-        applyModeBackground(oldMode, newMode, animate);
-    }
-
-    protected void applyModeBackground(int oldMode, int newMode, boolean animate) {
-        if (DEBUG) Log.d(mTag, String.format("applyModeBackground oldMode=%s newMode=%s animate=%s",
-                modeToString(oldMode), modeToString(newMode), animate));
-        mBarBackground.applyModeBackground(oldMode, newMode, animate);
-    }
-
-    public static String modeToString(int mode) {
-        if (mode == MODE_OPAQUE) return "MODE_OPAQUE";
-        if (mode == MODE_SEMI_TRANSPARENT) return "MODE_SEMI_TRANSPARENT";
-        if (mode == MODE_TRANSLUCENT) return "MODE_TRANSLUCENT";
-        if (mode == MODE_LIGHTS_OUT) return "MODE_LIGHTS_OUT";
-        if (mode == MODE_TRANSPARENT) return "MODE_TRANSPARENT";
-        if (mode == MODE_WARNING) return "MODE_WARNING";
-        if (mode == MODE_LIGHTS_OUT_TRANSPARENT) return "MODE_LIGHTS_OUT_TRANSPARENT";
-        throw new IllegalArgumentException("Unknown mode " + mode);
-    }
-
-    public void finishAnimations() {
-        mBarBackground.finishAnimation();
-    }
-
-    protected boolean isLightsOut(int mode) {
-        return mode == MODE_LIGHTS_OUT || mode == MODE_LIGHTS_OUT_TRANSPARENT;
-    }
-
-    protected static class BarBackgroundDrawable extends Drawable {
-        private final int mOpaque;
-        private final int mSemiTransparent;
-        private final int mTransparent;
-        private final int mWarning;
-        private final Drawable mGradient;
-
-        private int mMode = -1;
-        private boolean mAnimating;
-        private long mStartTime;
-        private long mEndTime;
-
-        private int mGradientAlpha;
-        private int mColor;
-        private float mOverrideAlpha = 1f;
-        private PorterDuffColorFilter mTintFilter;
-        private Paint mPaint = new Paint();
-
-        private int mGradientAlphaStart;
-        private int mColorStart;
-        private Rect mFrame;
-
-
-        public BarBackgroundDrawable(Context context, int gradientResourceId) {
-            final Resources res = context.getResources();
-            if (DEBUG_COLORS) {
-                mOpaque = 0xff0000ff;
-                mSemiTransparent = 0x7f0000ff;
-                mTransparent = 0x2f0000ff;
-                mWarning = 0xffff0000;
-            } else {
-                mOpaque = context.getColor(R.color.system_bar_background_opaque);
-                mSemiTransparent = context.getColor(
-                        com.android.internal.R.color.system_bar_background_semi_transparent);
-                mTransparent = context.getColor(R.color.system_bar_background_transparent);
-                mWarning = Utils.getColorAttrDefaultColor(context, android.R.attr.colorError);
-            }
-            mGradient = context.getDrawable(gradientResourceId);
-        }
-
-        public void setFrame(Rect frame) {
-            mFrame = frame;
-        }
-
-        public void setOverrideAlpha(float overrideAlpha) {
-            mOverrideAlpha = overrideAlpha;
-            invalidateSelf();
-        }
-
-        public float getOverrideAlpha() {
-            return mOverrideAlpha;
-        }
-
-        public int getColor() {
-            return mColor;
-        }
-
-        public Rect getFrame() {
-            return mFrame;
-        }
-
-        @Override
-        public void setAlpha(int alpha) {
-            // noop
-        }
-
-        @Override
-        public void setColorFilter(ColorFilter colorFilter) {
-            // noop
-        }
-
-        @Override
-        public void setTint(int color) {
-            PorterDuff.Mode targetMode = mTintFilter == null ? Mode.SRC_IN :
-                mTintFilter.getMode();
-            if (mTintFilter == null || mTintFilter.getColor() != color) {
-                mTintFilter = new PorterDuffColorFilter(color, targetMode);
-            }
-            invalidateSelf();
-        }
-
-        @Override
-        public void setTintMode(Mode tintMode) {
-            int targetColor = mTintFilter == null ? 0 : mTintFilter.getColor();
-            if (mTintFilter == null || mTintFilter.getMode() != tintMode) {
-                mTintFilter = new PorterDuffColorFilter(targetColor, tintMode);
-            }
-            invalidateSelf();
-        }
-
-        @Override
-        protected void onBoundsChange(Rect bounds) {
-            super.onBoundsChange(bounds);
-            mGradient.setBounds(bounds);
-        }
-
-        public void applyModeBackground(int oldMode, int newMode, boolean animate) {
-            if (mMode == newMode) return;
-            mMode = newMode;
-            mAnimating = animate;
-            if (animate) {
-                long now = SystemClock.elapsedRealtime();
-                mStartTime = now;
-                mEndTime = now + BACKGROUND_DURATION;
-                mGradientAlphaStart = mGradientAlpha;
-                mColorStart = mColor;
-            }
-            invalidateSelf();
-        }
-
-        @Override
-        public int getOpacity() {
-            return PixelFormat.TRANSLUCENT;
-        }
-
-        public void finishAnimation() {
-            if (mAnimating) {
-                mAnimating = false;
-                invalidateSelf();
-            }
-        }
-
-        @Override
-        public void draw(Canvas canvas) {
-            int targetGradientAlpha = 0, targetColor = 0;
-            if (mMode == MODE_WARNING) {
-                targetColor = mWarning;
-            } else if (mMode == MODE_TRANSLUCENT) {
-                targetColor = mSemiTransparent;
-            } else if (mMode == MODE_SEMI_TRANSPARENT) {
-                targetColor = mSemiTransparent;
-            } else if (mMode == MODE_TRANSPARENT || mMode == MODE_LIGHTS_OUT_TRANSPARENT) {
-                targetColor = mTransparent;
-            } else {
-                targetColor = mOpaque;
-            }
-
-            if (!mAnimating) {
-                mColor = targetColor;
-                mGradientAlpha = targetGradientAlpha;
-            } else {
-                final long now = SystemClock.elapsedRealtime();
-                if (now >= mEndTime) {
-                    mAnimating = false;
-                    mColor = targetColor;
-                    mGradientAlpha = targetGradientAlpha;
-                } else {
-                    final float t = (now - mStartTime) / (float)(mEndTime - mStartTime);
-                    final float v = Math.max(0, Math.min(
-                            Interpolators.LINEAR.getInterpolation(t), 1));
-                    mGradientAlpha = (int)(v * targetGradientAlpha + mGradientAlphaStart * (1 - v));
-                    mColor = Color.argb(
-                          (int)(v * Color.alpha(targetColor) + Color.alpha(mColorStart) * (1 - v)),
-                          (int)(v * Color.red(targetColor) + Color.red(mColorStart) * (1 - v)),
-                          (int)(v * Color.green(targetColor) + Color.green(mColorStart) * (1 - v)),
-                          (int)(v * Color.blue(targetColor) + Color.blue(mColorStart) * (1 - v)));
-                }
-            }
-            if (mGradientAlpha > 0) {
-                mGradient.setAlpha(mGradientAlpha);
-                mGradient.draw(canvas);
-            }
-
-            if (Color.alpha(mColor) > 0) {
-                mPaint.setColor(mColor);
-                if (mTintFilter != null) {
-                    mPaint.setColorFilter(mTintFilter);
-                }
-                mPaint.setAlpha((int) (Color.alpha(mColor) * mOverrideAlpha));
-                if (mFrame != null) {
-                    canvas.drawRect(mFrame, mPaint);
-                } else {
-                    canvas.drawPaint(mPaint);
-                }
-            }
-            if (mAnimating) {
-                invalidateSelf();  // keep going
-            }
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index 97b6f95..6d76200 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -53,11 +53,14 @@
 import com.android.systemui.keyguard.domain.interactor.BiometricUnlockInteractor;
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
 import com.android.systemui.keyguard.shared.model.BiometricUnlockSource;
+import com.android.systemui.keyguard.shared.model.Edge;
 import com.android.systemui.keyguard.shared.model.KeyguardState;
+import com.android.systemui.keyguard.shared.model.TransitionState;
 import com.android.systemui.keyguard.shared.model.TransitionStep;
 import com.android.systemui.log.SessionTracker;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.res.R;
+import com.android.systemui.scene.shared.model.Scenes;
 import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.VibratorHelper;
@@ -327,14 +330,17 @@
         mSelectedUserInteractor = selectedUserInteractor;
         mKeyguardTransitionInteractor = keyguardTransitionInteractor;
         javaAdapter.alwaysCollectFlow(
-                keyguardTransitionInteractor.getStartedKeyguardTransitionStep(),
-                this::consumeTransitionStepOnStartedKeyguardState);
+                keyguardTransitionInteractor.transition(
+                        /* edge */ Edge.create(Scenes.Gone, null),
+                        /* edgeWithoutSceneContainer */ Edge.create(
+                                KeyguardState.GONE, (KeyguardState) null)),
+                this::consumeFromGoneTransitions);
         dumpManager.registerDumpable(this);
     }
 
     @VisibleForTesting
-    protected void consumeTransitionStepOnStartedKeyguardState(TransitionStep transitionStep) {
-        if (transitionStep.getFrom() == KeyguardState.GONE) {
+    protected void consumeFromGoneTransitions(TransitionStep transitionStep) {
+        if (transitionStep.getTransitionState() == TransitionState.STARTED) {
             mBiometricUnlockInteractor.setBiometricUnlockState(MODE_NONE, null);
         }
     }
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 d75a738..a0d4ca2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -41,9 +41,10 @@
 import com.android.systemui.animation.ActivityTransitionAnimator;
 import com.android.systemui.animation.RemoteAnimationRunnerCompat;
 import com.android.systemui.display.data.repository.DisplayMetricsRepository;
-import com.android.systemui.navigationbar.NavigationBarView;
+import com.android.systemui.navigationbar.views.NavigationBarView;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.qs.QSPanelController;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.util.Compile;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt
index 3bc8e27..88d3e07 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesEmptyImpl.kt
@@ -20,7 +20,7 @@
 import androidx.lifecycle.LifecycleRegistry
 import com.android.keyguard.AuthKeyguardMessageArea
 import com.android.systemui.animation.ActivityTransitionAnimator
-import com.android.systemui.navigationbar.NavigationBarView
+import com.android.systemui.navigationbar.views.NavigationBarView
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction
 import com.android.systemui.qs.QSPanelController
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
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 62c139b..462ae7a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -146,7 +146,7 @@
 import com.android.systemui.keyguard.ui.binder.LightRevealScrimViewBinder;
 import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel;
 import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.navigationbar.NavigationBarView;
+import com.android.systemui.navigationbar.views.NavigationBarView;
 import com.android.systemui.notetask.NoteTaskController;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
@@ -181,6 +181,7 @@
 import com.android.systemui.shade.ShadeSurface;
 import com.android.systemui.shade.ShadeViewController;
 import com.android.systemui.shared.recents.utilities.Utilities;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
 import com.android.systemui.statusbar.AutoHideUiElement;
 import com.android.systemui.statusbar.CircleReveal;
 import com.android.systemui.statusbar.CommandQueue;
@@ -1328,7 +1329,9 @@
                                                 .putExtra(Intent.EXTRA_TEXT, message.toString()),
                                         "Share rejected touch report")
                                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
-                        true /* onlyProvisioned */, true /* dismissShade */);
+                        true /* onlyProvisioned */,
+                        true /* dismissShade */,
+                        null /* customMessage */);
             });
         }
 
@@ -1481,7 +1484,9 @@
         return (v, event) -> {
             mAutoHideController.checkUserAutoHide(event);
             mRemoteInputManager.checkRemoteInputOutside(event);
-            if (!MigrateClocksToBlueprint.isEnabled()) {
+            if (!MigrateClocksToBlueprint.isEnabled() || mQsController.isCustomizing()) {
+                // For migrate clocks flag, when the user is editing QS tiles they need to be able
+                // to touch outside the customizer to close it, such as on the status or nav bar.
                 mShadeController.onStatusBarTouch(event);
             }
             return getNotificationShadeWindowView().onTouchEvent(event);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java
index 398c1d4..bd0097e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java
@@ -74,9 +74,9 @@
             mLightModeIconColorSingleTone = Color.WHITE;
         } else {
             mDarkModeIconColorSingleTone = context.getColor(
-                    com.android.settingslib.R.color.dark_mode_icon_color_single_tone);
+                    com.android.settingslib.R.color.black);
             mLightModeIconColorSingleTone = context.getColor(
-                    com.android.settingslib.R.color.light_mode_icon_color_single_tone);
+                    com.android.settingslib.R.color.white);
         }
 
         mTransitionsController = lightBarTransitionsControllerFactory.create(this);
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 330383f..a32d5fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
@@ -29,8 +29,10 @@
 import android.view.MotionEvent;
 import android.view.View;
 
+import androidx.annotation.MainThread;
 import androidx.annotation.Nullable;
 
+import com.android.app.tracing.TraceUtils;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.assist.AssistManager;
@@ -61,6 +63,8 @@
 
 import dagger.Lazy;
 
+import kotlin.Unit;
+
 import kotlinx.coroutines.ExperimentalCoroutinesApi;
 
 import javax.inject.Inject;
@@ -109,7 +113,7 @@
     private CentralSurfaces mCentralSurfaces;
     private boolean mAlwaysOnSuppressed;
     private boolean mPulsePending;
-    private DozeInteractor mDozeInteractor;
+    private final DozeInteractor mDozeInteractor;
 
     @Inject
     public DozeServiceHost(DozeLog dozeLog, PowerManager powerManager,
@@ -337,13 +341,17 @@
     }
 
     @Override
+    @MainThread
     public void dozeTimeTick() {
-        mDozeInteractor.dozeTimeTick();
-        mShadeLockscreenInteractor.dozeTimeTick();
-        mAuthController.dozeTimeTick();
-        if (mAmbientIndicationContainer instanceof DozeReceiver) {
-            ((DozeReceiver) mAmbientIndicationContainer).dozeTimeTick();
-        }
+        TraceUtils.trace("DozeServiceHost#dozeTimeTick", () -> {
+            mDozeInteractor.dozeTimeTick();
+            mShadeLockscreenInteractor.dozeTimeTick();
+            mAuthController.dozeTimeTick();
+            if (mAmbientIndicationContainer instanceof DozeReceiver) {
+                ((DozeReceiver) mAmbientIndicationContainer).dozeTimeTick();
+            }
+            return Unit.INSTANCE;
+        });
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandHeadsUpOnInlineReply.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandHeadsUpOnInlineReply.kt
new file mode 100644
index 0000000..d4e2688
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ExpandHeadsUpOnInlineReply.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 com.android.systemui.Flags
+import com.android.systemui.flags.FlagToken
+import com.android.systemui.flags.RefactorFlagUtils
+
+/** Helper for reading or using the expand heads up on inline reply flag state. */
+@Suppress("NOTHING_TO_INLINE")
+object ExpandHeadsUpOnInlineReply {
+    /** The aconfig flag name */
+    const val FLAG_NAME = Flags.FLAG_EXPAND_HEADS_UP_ON_INLINE_REPLY
+
+    /** A token used for dependency declaration */
+    val token: FlagToken
+        get() = FlagToken(FLAG_NAME, isEnabled)
+
+    /** Is the refactor enabled */
+    @JvmStatic
+    inline val isEnabled
+        get() = Flags.expandHeadsUpOnInlineReply()
+
+    /**
+     * Called to ensure code is only run when the flag is enabled. This protects users from the
+     * unintended behaviors caused by accidentally running new logic, while also crashing on an eng
+     * build to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun isUnexpectedlyInLegacyMode() =
+        RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+    /**
+     * Called to ensure code is only run when the flag is disabled. This will throw an exception if
+     * the flag is enabled to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
+}
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 3925beb..0623bb2c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -31,6 +31,7 @@
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.policy.SystemBarUtils;
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
@@ -39,6 +40,7 @@
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.provider.OnReorderingAllowedListener;
+import com.android.systemui.statusbar.notification.collection.provider.OnReorderingBannedListener;
 import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
 import com.android.systemui.statusbar.notification.data.repository.HeadsUpRepository;
@@ -86,7 +88,7 @@
     private final List<OnHeadsUpPhoneListenerChange> mHeadsUpPhoneListeners = new ArrayList<>();
     private final VisualStabilityProvider mVisualStabilityProvider;
 
-    private final AvalancheController mAvalancheController;
+    private AvalancheController mAvalancheController;
 
     // TODO(b/328393698) move the topHeadsUpRow logic to an interactor
     private final MutableStateFlow<HeadsUpRowRepository> mTopHeadsUpRow =
@@ -104,6 +106,7 @@
     private boolean mIsExpanded;
     private int mStatusBarState;
     private AnimationStateHandler mAnimationStateHandler;
+
     private int mHeadsUpInset;
 
     // Used for determining the region for touch interaction
@@ -158,7 +161,6 @@
         mGroupMembershipManager = groupMembershipManager;
         mVisualStabilityProvider = visualStabilityProvider;
         mAvalancheController = avalancheController;
-
         updateResources();
         configurationController.addCallback(new ConfigurationController.ConfigurationListener() {
             @Override
@@ -175,6 +177,7 @@
             javaAdapter.alwaysCollectFlow(shadeInteractor.isAnyExpanded(),
                     this::onShadeOrQsExpanded);
         }
+        mVisualStabilityProvider.addPersistentReorderingBannedListener(mOnReorderingBannedListener);
     }
 
     public void setAnimationStateHandler(AnimationStateHandler handler) {
@@ -382,6 +385,8 @@
 
     private final OnReorderingAllowedListener mOnReorderingAllowedListener = () -> {
         mAnimationStateHandler.setHeadsUpGoingAwayAnimationsAllowed(false);
+        mAvalancheController.setEnableAtRuntime(true);
+
         for (NotificationEntry entry : mEntriesToRemoveWhenReorderingAllowed) {
             if (isHeadsUpEntry(entry.getKey())) {
                 // Maybe the heads-up was removed already
@@ -392,6 +397,29 @@
         mAnimationStateHandler.setHeadsUpGoingAwayAnimationsAllowed(true);
     };
 
+    private final OnReorderingBannedListener mOnReorderingBannedListener = () -> {
+        if (mAvalancheController != null) {
+            // Waiting HUNs in AvalancheController are still promoted to the HUN section and thus
+            // seen in open shade; clear them so we don't show them again when the shade closes and
+            // reordering is allowed again.
+            final int numDropped = mAvalancheController.getWaitingKeys().size();
+            mAvalancheController.logDroppedHunsInBackground(numDropped);
+            mAvalancheController.clearNext();
+
+            // In open shade the first HUN is pinned, and visual stability logic prevents us from
+            // unpinning this first HUN as long as the shade remains open. AvalancheController only
+            // shows the next HUN when the currently showing HUN is unpinned, so we must disable
+            // throttling here so that the incoming HUN stream is not forever paused. This is reset
+            // when reorder becomes allowed.
+            mAvalancheController.setEnableAtRuntime(false);
+
+            // Note that we cannot do the above when
+            // 1) the remove runnable runs because its delay means it may not run before shade close
+            // 2) reordering is allowed again (when shade closes) because the HUN appear animation
+            // will have started by then
+        }
+    };
+
     ///////////////////////////////////////////////////////////////////////////////////////////////
     //  HeadsUpManager utility (protected) methods overrides:
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpNotificationViewControllerEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpNotificationViewControllerEmptyImpl.kt
new file mode 100644
index 0000000..9f76429
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpNotificationViewControllerEmptyImpl.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.phone.HeadsUpTouchHelper.HeadsUpNotificationViewController
+
+/** Empty impl of [HeadsUpNotificationViewController] for use with Scene Container */
+class HeadsUpNotificationViewControllerEmptyImpl : HeadsUpNotificationViewController {
+    override fun setHeadsUpDraggingStartingHeight(startHeight: Int) {}
+
+    override fun setTrackedHeadsUp(expandableNotificationRow: ExpandableNotificationRow?) {}
+
+    override fun startExpand(
+        newX: Float,
+        newY: Float,
+        startTracking: Boolean,
+        expandedHeight: Float
+    ) {}
+}
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 198272e..7f16e18 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -23,6 +23,7 @@
 
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.Gefingerpoken;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
@@ -122,9 +123,14 @@
                                                 + mPickedChild.getTranslationY());
                     mPanel.setHeadsUpDraggingStartingHeight(startHeight);
                     mPanel.startExpand(x, y, true /* startTracking */, startHeight);
-                    // This call needs to be after the expansion start otherwise we will get a
-                    // flicker of one frame as it's not expanded yet.
-                    mHeadsUpManager.unpinAll(true);
+
+                    // TODO(b/340514839): Figure out where to move this side effect in flexiglass
+                    if (!SceneContainerFlag.isEnabled()) {
+                        // This call needs to be after the expansion start otherwise we will get a
+                        // flicker of one frame as it's not expanded yet.
+                        mHeadsUpManager.unpinAll(true);
+                    }
+
                     clearNotificationEffects();
                     endMotion();
                     return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaViewController.kt
index 8a45ec1..4aece3d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaViewController.kt
@@ -42,7 +42,7 @@
     }
 
     override fun onViewAttached() {
-        if (!smartspaceRelocateToBottom() || !smartspaceController.isEnabled()) {
+        if (!smartspaceRelocateToBottom() || !smartspaceController.isEnabled) {
             return
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index 84e6018..d0a62e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -455,8 +455,8 @@
         float luminance = Color.luminance(textColor);
         @ColorInt int iconColor = Utils.getColorStateListDefaultColor(mContext,
                     luminance < 0.5
-                        ? com.android.settingslib.R.color.dark_mode_icon_color_single_tone
-                        : com.android.settingslib.R.color.light_mode_icon_color_single_tone);
+                        ? com.android.settingslib.R.color.black
+                        : com.android.settingslib.R.color.white);
         @ColorInt int contrastColor = luminance < 0.5
                 ? DarkIconDispatcherImpl.DEFAULT_ICON_TINT
                 : DarkIconDispatcherImpl.DEFAULT_INVERSE_ICON_TINT;
@@ -467,7 +467,7 @@
         if (userSwitcherName != null) {
             userSwitcherName.setTextColor(Utils.getColorStateListDefaultColor(
                     mContext,
-                    com.android.settingslib.R.color.light_mode_icon_color_single_tone));
+                    com.android.settingslib.R.color.white));
         }
 
         if (iconManager != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
index e400ab6..bcb613f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LegacyActivityStarterInternalImpl.kt
@@ -34,6 +34,7 @@
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.ActivityIntentHelper
 import com.android.systemui.Flags.communalHub
+import com.android.systemui.Flags.mediaLockscreenLaunchAnimation
 import com.android.systemui.animation.ActivityTransitionAnimator
 import com.android.systemui.animation.DelegateTransitionAnimatorController
 import com.android.systemui.assist.AssistManager
@@ -231,6 +232,7 @@
         skipLockscreenChecks: Boolean,
         fillInIntent: Intent?,
         extraOptions: Bundle?,
+        customMessage: String?,
     ) {
         val animationController =
             if (associatedView is ExpandableNotificationRow) {
@@ -247,9 +249,10 @@
         val actuallyShowOverLockscreen =
             showOverLockscreen &&
                 intent.isActivity &&
-                    (skipLockscreenChecks || activityIntentHelper.wouldPendingShowOverLockscreen(
-                    intent,
-                    lockScreenUserManager.currentUserId
+                (skipLockscreenChecks ||
+                    activityIntentHelper.wouldPendingShowOverLockscreen(
+                        intent,
+                        lockScreenUserManager.currentUserId
                     ))
 
         val animate =
@@ -338,6 +341,7 @@
                     afterKeyguardGone = willLaunchResolverActivity,
                     dismissShade = collapse,
                     willAnimateOnKeyguard = animate,
+                    customMessage = customMessage,
                 )
             }
         } else {
@@ -470,12 +474,16 @@
                         shadeControllerLazy.get().collapseShadeForActivityStart()
                     }
                     if (communalHub()) {
-                        communalSceneInteractor.snapToSceneForActivityStart(CommunalScenes.Blank)
+                        communalSceneInteractor.changeSceneForActivityStartOnDismissKeyguard()
                     }
                     return deferred
                 }
 
                 override fun willRunAnimationOnKeyguard(): Boolean {
+                    if (communalHub() && communalSceneInteractor.isIdleOnCommunal.value) {
+                        // Override to false when launching activity over the hub that requires auth
+                        return false
+                    }
                     return willAnimateOnKeyguard
                 }
             }
@@ -557,7 +565,7 @@
                 override fun onTransitionAnimationStart(isExpandingFullyAbove: Boolean) {
                     super.onTransitionAnimationStart(isExpandingFullyAbove)
                     if (communalHub()) {
-                        communalSceneInteractor.snapToSceneForActivityStart(
+                        communalSceneInteractor.snapToScene(
                             CommunalScenes.Blank,
                             ActivityTransitionAnimator.TIMINGS.totalDuration
                         )
@@ -630,8 +638,9 @@
         isActivityIntent: Boolean,
         showOverLockscreen: Boolean,
     ): Boolean {
-        // TODO(b/294418322): Support launch animations when occluded.
-        if (keyguardStateController.isOccluded) {
+        // TODO(b/294418322): always support launch animations when occluded.
+        val ignoreOcclusion = showOverLockscreen && mediaLockscreenLaunchAnimation()
+        if (keyguardStateController.isOccluded && !ignoreOcclusion) {
             return false
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt
index 231a8c6..824415e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt
@@ -39,7 +39,7 @@
 ) {
     override fun toString(): String {
         val appearanceString =
-                ViewDebug.flagsToString(InsetsFlags::class.java, "appearance", appearance)
+            ViewDebug.flagsToString(InsetsFlags::class.java, "appearance", appearance)
         return "LetterboxAppearance{$appearanceString, $appearanceRegions}"
     }
 }
@@ -57,14 +57,16 @@
     private val letterboxBackgroundProvider: LetterboxBackgroundProvider,
 ) : Dumpable {
 
-    private val darkAppearanceIconColor = context.getColor(
-        // For a dark background status bar, use a *light* icon color.
-        com.android.settingslib.R.color.light_mode_icon_color_single_tone
-    )
-    private val lightAppearanceIconColor = context.getColor(
-        // For a light background status bar, use a *dark* icon color.
-        com.android.settingslib.R.color.dark_mode_icon_color_single_tone
-    )
+    private val darkAppearanceIconColor =
+        context.getColor(
+            // For a dark background status bar, use a *light* icon color.
+            com.android.settingslib.R.color.white
+        )
+    private val lightAppearanceIconColor =
+        context.getColor(
+            // For a light background status bar, use a *dark* icon color.
+            com.android.settingslib.R.color.black
+        )
 
     init {
         dumpManager.registerCriticalDumpable(this)
@@ -85,7 +87,11 @@
         lastAppearanceRegions = originalAppearanceRegions
         lastLetterboxes = letterboxes
         return getLetterboxAppearanceInternal(
-                letterboxes, originalAppearance, originalAppearanceRegions, statusBarBounds)
+                letterboxes,
+                originalAppearance,
+                originalAppearanceRegions,
+                statusBarBounds
+            )
             .also { lastLetterboxAppearance = it }
     }
 
@@ -138,7 +144,9 @@
                 // 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)
+                    appearanceRegion.appearance,
+                    matchingLetterbox.letterboxInnerBounds
+                )
             }
         }
 
@@ -148,7 +156,8 @@
     ): LetterboxAppearance {
         return LetterboxAppearance(
             originalAppearance or APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS,
-            originalAppearanceRegions)
+            originalAppearanceRegions
+        )
     }
 
     @Appearance
@@ -215,7 +224,9 @@
            lastAppearanceRegion: $lastAppearanceRegions,
            lastLetterboxes: $lastLetterboxes,
            lastLetterboxAppearance: $lastLetterboxAppearance
-       """.trimIndent())
+       """
+                .trimIndent()
+        )
     }
 }
 
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 eec617b..a33996b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
@@ -19,8 +19,8 @@
 import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
 import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
 
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
 
 import android.content.Context;
 import android.graphics.Rect;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 3784132..3ba62b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -44,6 +44,7 @@
 
 import androidx.lifecycle.Observer;
 
+import com.android.systemui.Flags;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.qualifiers.DisplayId;
 import com.android.systemui.dagger.qualifiers.Main;
@@ -57,12 +58,13 @@
 import com.android.systemui.qs.tiles.RotationLockTile;
 import com.android.systemui.res.R;
 import com.android.systemui.screenrecord.RecordingController;
+import com.android.systemui.screenrecord.data.model.ScreenRecordModel;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.ui.StatusBarIconController;
 import com.android.systemui.statusbar.policy.BluetoothController;
 import com.android.systemui.statusbar.policy.CastController;
-import com.android.systemui.statusbar.policy.CastController.CastDevice;
+import com.android.systemui.statusbar.policy.CastDevice;
 import com.android.systemui.statusbar.policy.DataSaverController;
 import com.android.systemui.statusbar.policy.DataSaverController.Listener;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -354,7 +356,11 @@
         mProvisionedController.addCallback(this);
         mCurrentUserSetup = mProvisionedController.isCurrentUserSetup();
         mZenController.addCallback(this);
-        mCast.addCallback(mCastCallback);
+        if (!Flags.statusBarScreenSharingChips()) {
+            // If the flag is enabled, the cast icon is handled in the new screen sharing chips
+            // instead of here so we don't need to listen for events here.
+            mCast.addCallback(mCastCallback);
+        }
         mHotspot.addCallback(mHotspotCallback);
         mNextAlarmController.addCallback(mNextAlarmCallback);
         mDataSaver.addCallback(this);
@@ -362,7 +368,11 @@
         mPrivacyItemController.addCallback(this);
         mSensorPrivacyController.addCallback(mSensorPrivacyListener);
         mLocationController.addCallback(this);
-        mRecordingController.addCallback(this);
+        if (!Flags.statusBarScreenSharingChips()) {
+            // If the flag is enabled, the screen record icon is handled in the new screen sharing
+            // chips instead of here so we don't need to listen for events here.
+            mRecordingController.addCallback(this);
+        }
         mJavaAdapter.alwaysCollectFlow(mConnectedDisplayInteractor.getConnectedDisplayState(),
                 this::onConnectedDisplayAvailabilityChanged);
 
@@ -519,10 +529,14 @@
     }
 
     private void updateCast() {
+        if (Flags.statusBarScreenSharingChips()) {
+            // The cast icon is handled in the new screen sharing chips instead of here.
+            return;
+        }
+
         boolean isCasting = false;
         for (CastDevice device : mCast.getCastDevices()) {
-            if (device.state == CastDevice.STATE_CONNECTING
-                    || device.state == CastDevice.STATE_CONNECTED) {
+            if (device.isCasting()) {
                 isCasting = true;
                 break;
             }
@@ -789,6 +803,10 @@
     private Runnable mRemoveCastIconRunnable = new Runnable() {
         @Override
         public void run() {
+            if (Flags.statusBarScreenSharingChips()) {
+                // The cast icon is handled in the new screen sharing chips instead of here.
+                return;
+            }
             if (DEBUG) Log.v(TAG, "updateCast: hiding icon NOW");
             mIconController.setIconVisibility(mSlotCast, false);
         }
@@ -797,8 +815,13 @@
     // Screen Recording
     @Override
     public void onCountdown(long millisUntilFinished) {
+        if (Flags.statusBarScreenSharingChips()) {
+            // The screen record icon is handled in the new screen sharing chips instead of here.
+            return;
+        }
         if (DEBUG) Log.d(TAG, "screenrecord: countdown " + millisUntilFinished);
-        int countdown = (int) Math.floorDiv(millisUntilFinished + 500, 1000);
+        int countdown =
+                (int) ScreenRecordModel.Starting.Companion.toCountdownSeconds(millisUntilFinished);
         int resourceId = R.drawable.stat_sys_screen_record;
         String description = Integer.toString(countdown);
         switch (countdown) {
@@ -821,6 +844,10 @@
 
     @Override
     public void onCountdownEnd() {
+        if (Flags.statusBarScreenSharingChips()) {
+            // The screen record icon is handled in the new screen sharing chips instead of here.
+            return;
+        }
         if (DEBUG) Log.d(TAG, "screenrecord: hiding icon during countdown");
         mHandler.post(() -> mIconController.setIconVisibility(mSlotScreenRecord, false));
         // Reset talkback priority
@@ -830,6 +857,10 @@
 
     @Override
     public void onRecordingStart() {
+        if (Flags.statusBarScreenSharingChips()) {
+            // The screen record icon is handled in the new screen sharing chips instead of here.
+            return;
+        }
         if (DEBUG) Log.d(TAG, "screenrecord: showing icon");
         mIconController.setIcon(mSlotScreenRecord,
                 R.drawable.stat_sys_screen_record,
@@ -839,6 +870,10 @@
 
     @Override
     public void onRecordingEnd() {
+        if (Flags.statusBarScreenSharingChips()) {
+            // The screen record icon is handled in the new screen sharing chips instead of here.
+            return;
+        }
         // Ensure this is on the main thread
         if (DEBUG) Log.d(TAG, "screenrecord: hiding icon");
         mHandler.post(() -> mIconController.setIconVisibility(mSlotScreenRecord, false));
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 ae3f923..6676a7f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitions.java
@@ -23,6 +23,7 @@
 import android.view.View;
 
 import com.android.systemui.res.R;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
 
 public final class PhoneStatusBarTransitions extends BarTransitions {
     private static final float ICON_ALPHA_WHEN_NOT_OPAQUE = 1;
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 9cece76..e4edfa4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -76,6 +76,7 @@
 import com.android.systemui.scene.shared.model.Scenes;
 import com.android.systemui.scrim.ScrimView;
 import com.android.systemui.shade.ShadeViewController;
+import com.android.systemui.shade.shared.flag.DualShade;
 import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
 import com.android.systemui.statusbar.notification.stack.ViewState;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -87,6 +88,7 @@
 import com.android.systemui.wallpapers.data.repository.WallpaperRepository;
 
 import kotlinx.coroutines.CoroutineDispatcher;
+import kotlinx.coroutines.ExperimentalCoroutinesApi;
 
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
@@ -101,6 +103,7 @@
  * security method gets shown).
  */
 @SysUISingleton
+@ExperimentalCoroutinesApi
 public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dumpable,
         CoreStartable {
 
@@ -999,7 +1002,7 @@
             if (!mScreenOffAnimationController.shouldExpandNotifications()
                     && !mAnimatingPanelExpansionOnUnlock
                     && !occluding) {
-                if (mTransparentScrimBackground) {
+                if (mTransparentScrimBackground || DualShade.isEnabled()) {
                     mBehindAlpha = 0;
                     mNotificationsAlpha = 0;
                 } else if (mClipsQsScrim) {
@@ -1051,7 +1054,12 @@
                 behindAlpha = 0f;
             }
             mInFrontAlpha = mState.getFrontAlpha();
-            if (mClipsQsScrim) {
+            if (DualShade.isEnabled() && mState == ScrimState.SHADE_LOCKED) {
+                mBehindAlpha = 0;
+                mNotificationsTint = Color.TRANSPARENT;
+                mNotificationsAlpha = 0;
+                mBehindTint = Color.TRANSPARENT;
+            } else if (mClipsQsScrim) {
                 mNotificationsAlpha = behindAlpha;
                 mNotificationsTint = behindTint;
                 mBehindAlpha = 1;
@@ -1105,8 +1113,7 @@
     }
 
     private Pair<Integer, Float> calculateBackStateForState(ScrimState state) {
-        // Either darken of make the scrim transparent when you
-        // pull down the shade
+        // Either darken or make the scrim transparent when pulling down the shade.
         float interpolatedFract = getInterpolatedFraction();
 
         float stateBehind = mClipsQsScrim ? state.getNotifAlpha() : state.getBehindAlpha();
@@ -1201,11 +1208,7 @@
             return true;
         }
 
-        if (mState == ScrimState.PULSING) {
-            return true;
-        }
-
-        return false;
+        return mState == ScrimState.PULSING;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarDemoMode.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarDemoMode.java
index 29c1372..25b8bfe0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarDemoMode.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarDemoMode.java
@@ -16,11 +16,11 @@
 
 package com.android.systemui.statusbar.phone;
 
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_OPAQUE;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_TRANSLUCENT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_WARNING;
 import static com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentModule.OPERATOR_NAME_VIEW;
 
 import android.annotation.NonNull;
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 b40bf56..96127b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -63,6 +63,7 @@
 import com.android.systemui.bouncer.ui.BouncerView;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor;
 import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.dreams.DreamOverlayStateController;
@@ -77,9 +78,9 @@
 import com.android.systemui.keyguard.shared.model.KeyguardDone;
 import com.android.systemui.keyguard.shared.model.KeyguardState;
 import com.android.systemui.keyguard.shared.model.TransitionStep;
-import com.android.systemui.navigationbar.NavigationBarView;
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.navigationbar.TaskbarDelegate;
+import com.android.systemui.navigationbar.views.NavigationBarView;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.scene.domain.interactor.SceneInteractor;
@@ -167,6 +168,7 @@
     private final BouncerView mPrimaryBouncerView;
     private final Lazy<ShadeController> mShadeController;
     private final Lazy<SceneInteractor> mSceneInteractorLazy;
+    private final Lazy<DeviceEntryInteractor> mDeviceEntryInteractorLazy;
 
     private Job mListenForAlternateBouncerTransitionSteps = null;
     private Job mListenForKeyguardAuthenticatedBiometricsHandled = null;
@@ -395,7 +397,8 @@
             Lazy<KeyguardSurfaceBehindInteractor> surfaceBehindInteractor,
             JavaAdapter javaAdapter,
             Lazy<SceneInteractor> sceneInteractorLazy,
-            StatusBarKeyguardViewManagerInteractor statusBarKeyguardViewManagerInteractor
+            StatusBarKeyguardViewManagerInteractor statusBarKeyguardViewManagerInteractor,
+            Lazy<DeviceEntryInteractor> deviceEntryInteractorLazy
     ) {
         mContext = context;
         mViewMediatorCallback = callback;
@@ -430,6 +433,7 @@
         mJavaAdapter = javaAdapter;
         mSceneInteractorLazy = sceneInteractorLazy;
         mStatusBarKeyguardViewManagerInteractor = statusBarKeyguardViewManagerInteractor;
+        mDeviceEntryInteractorLazy = deviceEntryInteractorLazy;
     }
 
     KeyguardTransitionInteractor mKeyguardTransitionInteractor;
@@ -735,6 +739,11 @@
      *                 {@see KeyguardBouncer#show(boolean, boolean)}
      */
     public void showBouncer(boolean scrimmed) {
+        if (SceneContainerFlag.isEnabled()) {
+            mDeviceEntryInteractorLazy.get().attemptDeviceEntry();
+            return;
+        }
+
         if (DeviceEntryUdfpsRefactor.isEnabled()) {
             if (mAlternateBouncerInteractor.canShowAlternateBouncerForFingerprint()) {
                 Log.d(TAG, "showBouncer:alternateBouncer.forceShow()");
@@ -777,8 +786,7 @@
         hideAlternateBouncer(false);
         if (mKeyguardStateController.isShowing() && !isBouncerShowing()) {
             if (SceneContainerFlag.isEnabled()) {
-                mSceneInteractorLazy.get().changeScene(
-                        Scenes.Bouncer, "StatusBarKeyguardViewManager.showPrimaryBouncer");
+                mDeviceEntryInteractorLazy.get().attemptDeviceEntry();
             } else {
                 mPrimaryBouncerInteractor.show(scrimmed);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
index 4505a1d..b1754fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
@@ -192,27 +192,42 @@
         if (!deferBouncer && mKeyguardStateController.isShowing()) {
             onLockedRemoteInput(row, clickedView);
         } else {
-            if (row.isChildInGroup() && !row.areChildrenExpanded()) {
-                // The group isn't expanded, let's make sure it's visible!
-                mGroupExpansionManager.toggleGroupExpansion(row.getEntry());
-            }
-
-            if (android.app.Flags.compactHeadsUpNotificationReply()
-                    && row.isCompactConversationHeadsUpOnScreen()) {
-                // Notification can be system expanded true and it is set user expanded in
-                // activateRemoteInput. notifyHeightChanged also doesn't work as visibleType doesn't
-                // change. To expand huning notification properly, we need set userExpanded false.
-                if (!row.isPinned() && row.isExpanded()) {
-                    row.setUserExpanded(false);
+            if (ExpandHeadsUpOnInlineReply.isEnabled()) {
+                if (row.isChildInGroup() && !row.areChildrenExpanded()) {
+                    // The group isn't expanded, let's make sure it's visible!
+                    mGroupExpansionManager.toggleGroupExpansion(row.getEntry());
+                } else if (!row.isChildInGroup() && !row.isExpanded()) {
+                    // notification isn't expanded, let's make sure it's visible!
+                    row.toggleExpansionState();
+                    row.getPrivateLayout().setOnExpandedVisibleListener(runnable);
                 }
-                // expand notification emits expanded information to HUN listener.
-                row.expandNotification();
             } else {
-                // Note: Since Normal HUN has remote input view in it, we don't expect to hit
-                // onMakeExpandedVisibleForRemoteInput from activateRemoteInput for Normal HUN.
-                row.setUserExpanded(true);
+                if (row.isChildInGroup() && !row.areChildrenExpanded()) {
+                    // The group isn't expanded, let's make sure it's visible!
+                    mGroupExpansionManager.toggleGroupExpansion(row.getEntry());
+                }
+
+                if (android.app.Flags.compactHeadsUpNotificationReply()
+                        && row.isCompactConversationHeadsUpOnScreen()) {
+                    // Notification can be system expanded true and it is set user expanded in
+                    // activateRemoteInput. notifyHeightChanged also doesn't work as visibleType
+                    // doesn't change. To expand huning notification properly,
+                    // we need set userExpanded false.
+                    if (!row.isPinned() && row.isExpanded()) {
+                        row.setUserExpanded(false);
+                    }
+                    // expand notification emits expanded information to HUN listener.
+                    row.expandNotification();
+                } else {
+                    // TODO(b/346976443) Group and normal notification expansions are two different
+                    // concepts. We should never call setUserExpanded for expanding groups.
+
+                    // Note: Since Normal HUN has remote input view in it, we don't expect to hit
+                    // onMakeExpandedVisibleForRemoteInput from activateRemoteInput for Normal HUN.
+                    row.setUserExpanded(true);
+                }
+                row.getPrivateLayout().setOnExpandedVisibleListener(runnable);
             }
-            row.getPrivateLayout().setOnExpandedVisibleListener(runnable);
         }
     }
 
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 4b1ee58..45aee5b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
@@ -29,6 +29,7 @@
 import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
 import android.view.WindowInsets;
 
+import androidx.annotation.VisibleForTesting;
 import com.android.compose.animation.scene.ObservableTransitionState;
 import com.android.internal.policy.SystemBarUtils;
 import com.android.systemui.Dumpable;
@@ -68,7 +69,8 @@
     private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
 
     private boolean mIsStatusBarExpanded = false;
-    private boolean mIsIdleOnGone = false;
+    private boolean mIsIdleOnGone = true;
+    private boolean mIsRemoteUserInteractionOngoing = false;
     private boolean mShouldAdjustInsets = false;
     private View mNotificationShadeWindowView;
     private View mNotificationPanelView;
@@ -133,6 +135,9 @@
             javaAdapter.alwaysCollectFlow(
                     sceneInteractor.get().getTransitionState(),
                     this::onSceneChanged);
+            javaAdapter.alwaysCollectFlow(
+                    sceneInteractor.get().isRemoteUserInteractionOngoing(),
+                    this::onRemoteUserInteractionOngoingChanged);
         } else {
             javaAdapter.alwaysCollectFlow(
                     shadeInteractor.isAnyExpanded(),
@@ -179,6 +184,13 @@
         }
     }
 
+    private void onRemoteUserInteractionOngoingChanged(Boolean ongoing) {
+        if (ongoing != mIsRemoteUserInteractionOngoing) {
+            mIsRemoteUserInteractionOngoing = ongoing;
+            updateTouchableRegion();
+        }
+    }
+
     /**
      * Calculates the touch region needed for heads up notifications, taking into consideration
      * any existing display cutouts (notch)
@@ -276,13 +288,15 @@
      * Helper to let us know when calculating the region is not needed because we know the entire
      * screen needs to be touchable.
      */
-    private boolean shouldMakeEntireScreenTouchable() {
+    @VisibleForTesting
+    boolean shouldMakeEntireScreenTouchable() {
         // The touchable region is always the full area when expanded, whether we're showing the
         // shade or the bouncer. It's also fully touchable when the screen off animation is playing
         // since we don't want stray touches to go through the light reveal scrim to whatever is
         // underneath.
         return mIsStatusBarExpanded
-                || !mIsIdleOnGone
+                || (SceneContainerFlag.isEnabled()
+                && (!mIsIdleOnGone || mIsRemoteUserInteractionOngoing))
                 || mPrimaryBouncerInteractor.isShowing().getValue()
                 || mAlternateBouncerInteractor.isVisibleState()
                 || mUnlockedScreenOffAnimationController.isAnimationPlaying();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java
index da91d6a..6ac7f11 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowCallback.java
@@ -26,5 +26,5 @@
      */
     void onStateChanged(boolean keyguardShowing, boolean keyguardOccluded,
             boolean keyguardGoingAway, boolean bouncerShowing, boolean isDozing,
-            boolean panelExpanded, boolean isDreaming);
+            boolean panelExpanded, boolean isDreaming, boolean communalShowing);
 }
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 3d8090d..aced0be 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
@@ -14,6 +14,8 @@
 
 package com.android.systemui.statusbar.phone.fragment;
 
+import static com.android.systemui.statusbar.phone.fragment.StatusBarVisibilityModel.createHiddenModel;
+
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.app.Fragment;
@@ -46,6 +48,7 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.res.R;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.shade.ShadeExpansionStateManager;
 import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor;
 import com.android.systemui.statusbar.CommandQueue;
@@ -205,6 +208,13 @@
     private boolean mTransitionFromLockscreenToDreamStarted = false;
 
     /**
+     * True if the current scene allows the home status bar (aka this status bar) to be shown, and
+     * false if the current scene should never show the home status bar. Only used if the scene
+     * container is enabled.
+     */
+    private boolean mHomeStatusBarAllowedByScene = true;
+
+    /**
      * True if there's an active ongoing activity that should be showing a chip and false otherwise.
      */
     private boolean mHasOngoingActivity;
@@ -522,6 +532,13 @@
                     mHasOngoingActivity = hasOngoingActivity;
                     updateStatusBarVisibilities(/* animate= */ true);
                 }
+
+                @Override
+                public void onIsHomeStatusBarAllowedBySceneChanged(
+                        boolean isHomeStatusBarAllowedByScene) {
+                    mHomeStatusBarAllowedByScene = isHomeStatusBarAllowedByScene;
+                    updateStatusBarVisibilities(/* animate= */ true);
+                }
     };
 
     @Override
@@ -580,17 +597,22 @@
         boolean headsUpVisible =
                 mStatusBarFragmentComponent.getHeadsUpAppearanceController().shouldBeVisible();
 
-        if (!mKeyguardStateController.isLaunchTransitionFadingAway()
-                && !mKeyguardStateController.isKeyguardFadingAway()
-                && shouldHideStatusBar()
-                && !(mStatusBarStateController.getState() == StatusBarState.KEYGUARD
-                        && headsUpVisible)) {
-            // Hide everything
-            return new StatusBarVisibilityModel(
-                    /* showClock= */ false,
-                    /* showNotificationIcons= */ false,
-                    /* showOngoingActivityChip= */ false,
-                    /* showSystemInfo= */ false);
+        if (SceneContainerFlag.isEnabled()) {
+            // With the scene container, only use the value calculated by the view model to
+            // determine if the status bar needs hiding.
+            if (!mHomeStatusBarAllowedByScene) {
+                return createHiddenModel();
+            }
+        } else {
+            // Without the scene container, use our old, mildly-hacky logic to determine if the
+            // status bar needs hiding.
+            if (!mKeyguardStateController.isLaunchTransitionFadingAway()
+                    && !mKeyguardStateController.isKeyguardFadingAway()
+                    && shouldHideStatusBar()
+                    && !(mStatusBarStateController.getState() == StatusBarState.KEYGUARD
+                    && headsUpVisible)) {
+                return createHiddenModel();
+            }
         }
 
         boolean showClock = externalModel.getShowClock() && !headsUpVisible;
@@ -698,7 +720,7 @@
     }
 
     private void hideEndSideContent(boolean animate) {
-        if (!animate) {
+        if (!animate || !mAnimationsEnabled) {
             mEndSideAlphaController.setAlpha(/*alpha*/ 0f, SOURCE_OTHER);
         } else {
             mEndSideAlphaController.animateToAlpha(/*alpha*/ 0f, SOURCE_OTHER, FADE_OUT_DURATION,
@@ -707,7 +729,7 @@
     }
 
     private void showEndSideContent(boolean animate) {
-        if (!animate) {
+        if (!animate || !mAnimationsEnabled) {
             mEndSideAlphaController.setAlpha(1f, SOURCE_OTHER);
             return;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModel.kt
index fe24fae..9255e63 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModel.kt
@@ -36,6 +36,17 @@
             return createModelFromFlags(DISABLE_NONE, DISABLE2_NONE)
         }
 
+        /** Creates a model that hides every piece of the status bar. */
+        @JvmStatic
+        fun createHiddenModel(): StatusBarVisibilityModel {
+            return StatusBarVisibilityModel(
+                showClock = false,
+                showNotificationIcons = false,
+                showOngoingActivityChip = false,
+                showSystemInfo = false,
+            )
+        }
+
         /**
          * Given a set of disabled flags, converts them into the correct visibility statuses.
          *
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
index 50649a8..f81b952 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/shared/model/OngoingCallModel.kt
@@ -18,7 +18,13 @@
 
 import android.app.PendingIntent
 
-/** Represents the state of any ongoing calls. */
+/**
+ * Represents the state of any ongoing calls.
+ *
+ * TODO(b/332662551): If there's an ongoing call but the user has the call app open, then we use the
+ *   NoCall model, *not* the InCall model, which is confusing when looking at the logs. We may want
+ *   to make that more clear, either with better logging or different models.
+ */
 sealed interface OngoingCallModel {
     /** There is no ongoing call. */
     data object NoCall : OngoingCallModel
@@ -29,7 +35,8 @@
      * @property startTimeMs the time that the phone call started, based on the notification's
      *   `when` field. Importantly, this time is relative to
      *   [com.android.systemui.util.time.SystemClock.currentTimeMillis], **not**
-     *   [com.android.systemui.util.time.SystemClock.elapsedRealtime].
+     *   [com.android.systemui.util.time.SystemClock.elapsedRealtime]. This value can be 0 if the
+     *   user has started an outgoing call that hasn't been answered yet - see b/192379214.
      * @property intent the intent associated with the call notification.
      */
     data class InCall(val startTimeMs: Long, val intent: PendingIntent?) : OngoingCallModel
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
index 9449659..62bd8ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
@@ -349,6 +349,7 @@
                     false
                 }
             }
+            .flowOn(bgDispatcher)
             .stateIn(scope, SharingStarted.WhileSubscribed(), false)
 
     override val carrierId =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt
index ec3af87..a7c5f78 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt
@@ -345,32 +345,67 @@
                 orElse = flowOf(false),
                 retrySignal = telephonyProcessCrashedEvent,
             )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+            .stateIn(scope, SharingStarted.Eagerly, false)
 
     private fun satelliteProvisioned(sm: SupportedSatelliteManager): Flow<Boolean> =
         conflatedCallbackFlow {
-            val callback = SatelliteProvisionStateCallback { provisioned ->
-                logBuffer.i {
-                    "onSatelliteProvisionStateChanged: " +
-                        if (provisioned) "provisioned" else "not provisioned"
+                // TODO(b/347992038): SatelliteManager should be sending the current provisioned
+                // status when we register a callback. Until then, we have to manually query here.
+
+                // First, check to see what the current status is, and send the result to the output
+                trySend(queryIsSatelliteProvisioned(sm))
+
+                val callback = SatelliteProvisionStateCallback { provisioned ->
+                    logBuffer.i {
+                        "onSatelliteProvisionStateChanged: " +
+                            if (provisioned) "provisioned" else "not provisioned"
+                    }
+                    trySend(provisioned)
                 }
-                trySend(provisioned)
-            }
 
-            var registered = false
-            try {
-                sm.registerForProvisionStateChanged(
-                    bgDispatcher.asExecutor(),
-                    callback,
-                )
-                registered = true
-            } catch (e: Exception) {
-                logBuffer.e("error registering for provisioning state callback", e)
-            }
+                var registered = false
+                try {
+                    logBuffer.i { "registerForProvisionStateChanged" }
+                    sm.registerForProvisionStateChanged(
+                        bgDispatcher.asExecutor(),
+                        callback,
+                    )
+                    registered = true
+                } catch (e: Exception) {
+                    logBuffer.e("error registering for provisioning state callback", e)
+                }
 
-            awaitClose {
-                if (registered) {
-                    sm.unregisterForProvisionStateChanged(callback)
+                awaitClose {
+                    if (registered) {
+                        sm.unregisterForProvisionStateChanged(callback)
+                    }
+                }
+            }
+            .flowOn(bgDispatcher)
+
+    /** Check the current satellite provisioning status. */
+    private suspend fun queryIsSatelliteProvisioned(sm: SupportedSatelliteManager): Boolean =
+        withContext(bgDispatcher) {
+            suspendCancellableCoroutine { continuation ->
+                val receiver =
+                    object : OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> {
+                        override fun onResult(result: Boolean) {
+                            logBuffer.i { "requestIsProvisioned.onResult: $result" }
+                            continuation.resume(result)
+                        }
+
+                        override fun onError(exception: SatelliteManager.SatelliteException) {
+                            logBuffer.e("requestIsProvisioned.onError:", exception)
+                            continuation.resume(false)
+                        }
+                    }
+
+                logBuffer.i { "Query for current satellite provisioned state." }
+                try {
+                    sm.requestIsProvisioned(bgDispatcher.asExecutor(), receiver)
+                } catch (e: Exception) {
+                    logBuffer.e("Exception while calling SatelliteManager.requestIsProvisioned:", e)
+                    continuation.resume(false)
                 }
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
index 7644653..ae1898b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/binder/CollapsedStatusBarViewBinder.kt
@@ -18,8 +18,11 @@
 
 import android.animation.Animator
 import android.animation.AnimatorListenerAdapter
+import android.content.res.ColorStateList
+import android.graphics.drawable.GradientDrawable
 import android.view.View
 import android.widget.ImageView
+import android.widget.TextView
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.systemui.Flags
@@ -27,8 +30,10 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.res.R
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.statusbar.chips.ui.binder.ChipChronometerBinder
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
+import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
 import com.android.systemui.statusbar.chips.ui.view.ChipChronometer
 import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor
 import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModel
@@ -84,23 +89,45 @@
 
                 if (Flags.statusBarScreenSharingChips()) {
                     val chipView: View = view.requireViewById(R.id.ongoing_activity_chip)
+                    val chipContext = chipView.context
                     val chipIconView: ImageView =
                         chipView.requireViewById(R.id.ongoing_activity_chip_icon)
                     val chipTimeView: ChipChronometer =
                         chipView.requireViewById(R.id.ongoing_activity_chip_time)
+                    val chipTextView: TextView =
+                        chipView.requireViewById(R.id.ongoing_activity_chip_text)
+                    val chipBackgroundView =
+                        chipView.requireViewById<ChipBackgroundContainer>(
+                            R.id.ongoing_activity_chip_background
+                        )
                     launch {
                         viewModel.ongoingActivityChip.collect { chipModel ->
                             when (chipModel) {
                                 is OngoingActivityChipModel.Shown -> {
-                                    IconViewBinder.bind(chipModel.icon, chipIconView)
-                                    ChipChronometerBinder.bind(chipModel.startTimeMs, chipTimeView)
+                                    // Data
+                                    IconViewBinder.bindNullable(chipModel.icon, chipIconView)
+                                    setChipMainContent(chipModel, chipTextView, chipTimeView)
                                     chipView.setOnClickListener(chipModel.onClickListener)
 
+                                    // Accessibility
+                                    setChipAccessibility(chipModel, chipView)
+
+                                    // Colors
+                                    val textColor = chipModel.colors.text(chipContext)
+                                    chipIconView.imageTintList = ColorStateList.valueOf(textColor)
+                                    chipTimeView.setTextColor(textColor)
+                                    chipTextView.setTextColor(textColor)
+                                    (chipBackgroundView.background as GradientDrawable).color =
+                                        chipModel.colors.background(chipContext)
+
+                                    // Notify listeners
                                     listener.onOngoingActivityStatusChanged(
                                         hasOngoingActivity = true
                                     )
                                 }
                                 is OngoingActivityChipModel.Hidden -> {
+                                    // The Chronometer should be stopped to prevent leaks -- see
+                                    // b/192243808 and [Chronometer.start].
                                     chipTimeView.stop()
                                     listener.onOngoingActivityStatusChanged(
                                         hasOngoingActivity = false
@@ -110,6 +137,89 @@
                         }
                     }
                 }
+
+                if (SceneContainerFlag.isEnabled) {
+                    launch {
+                        viewModel.isHomeStatusBarAllowedByScene.collect {
+                            listener.onIsHomeStatusBarAllowedBySceneChanged(it)
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private fun setChipMainContent(
+        chipModel: OngoingActivityChipModel.Shown,
+        chipTextView: TextView,
+        chipTimeView: ChipChronometer,
+    ) {
+        when (chipModel) {
+            is OngoingActivityChipModel.Shown.Countdown -> {
+                chipTextView.text = chipModel.secondsUntilStarted.toString()
+                chipTextView.visibility = View.VISIBLE
+
+                // The Chronometer should be stopped to prevent leaks -- see b/192243808 and
+                // [Chronometer.start].
+                chipTimeView.stop()
+                chipTimeView.visibility = View.GONE
+            }
+            is OngoingActivityChipModel.Shown.Timer -> {
+                ChipChronometerBinder.bind(chipModel.startTimeMs, chipTimeView)
+                chipTimeView.visibility = View.VISIBLE
+
+                chipTextView.visibility = View.GONE
+            }
+            is OngoingActivityChipModel.Shown.IconOnly -> {
+                chipTextView.visibility = View.GONE
+                // The Chronometer should be stopped to prevent leaks -- see b/192243808 and
+                // [Chronometer.start].
+                chipTimeView.stop()
+                chipTimeView.visibility = View.GONE
+            }
+        }
+        updateChipTextPadding(chipModel, chipTextView, chipTimeView)
+    }
+
+    private fun updateChipTextPadding(
+        chipModel: OngoingActivityChipModel.Shown,
+        chipTextView: TextView,
+        chipTimeView: ChipChronometer,
+    ) {
+        val requiresPadding = chipModel.icon != null
+        if (requiresPadding) {
+            chipTextView.addChipTextPaddingStart()
+            chipTimeView.addChipTextPaddingStart()
+        } else {
+            chipTextView.removeChipTextPaddingStart()
+            chipTimeView.removeChipTextPaddingStart()
+        }
+    }
+
+    private fun View.addChipTextPaddingStart() {
+        this.setPaddingRelative(
+            this.context.resources.getDimensionPixelSize(
+                R.dimen.ongoing_activity_chip_icon_text_padding
+            ),
+            paddingTop,
+            paddingEnd,
+            paddingBottom,
+        )
+    }
+
+    private fun View.removeChipTextPaddingStart() {
+        this.setPaddingRelative(/* start= */ 0, paddingTop, paddingEnd, paddingBottom)
+    }
+
+    private fun setChipAccessibility(chipModel: OngoingActivityChipModel.Shown, chipView: View) {
+        when (chipModel) {
+            is OngoingActivityChipModel.Shown.Countdown -> {
+                // Set as assertive so talkback will announce the countdown
+                chipView.accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_ASSERTIVE
+            }
+            is OngoingActivityChipModel.Shown.Timer,
+            is OngoingActivityChipModel.Shown.IconOnly -> {
+                chipView.accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_NONE
             }
         }
     }
@@ -158,4 +268,10 @@
 
     /** Called when the status of the ongoing activity chip (active or not active) has changed. */
     fun onOngoingActivityStatusChanged(hasOngoingActivity: Boolean)
+
+    /**
+     * Called when the scene state has changed such that the home status bar is newly allowed or no
+     * longer allowed. See [CollapsedStatusBarViewModel.isHomeStatusBarAllowedByScene].
+     */
+    fun onIsHomeStatusBarAllowedBySceneChanged(isHomeStatusBarAllowedByScene: Boolean)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt
index 95d9248..d6c3834 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModel.kt
@@ -24,6 +24,9 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
 import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
 import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
 import com.android.systemui.statusbar.chips.ui.viewmodel.OngoingActivityChipsViewModel
 import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor
@@ -65,6 +68,12 @@
     val ongoingActivityChip: StateFlow<OngoingActivityChipModel>
 
     /**
+     * True if the current scene can show the home status bar (aka this status bar), and false if
+     * the current scene should never show the home status bar.
+     */
+    val isHomeStatusBarAllowedByScene: StateFlow<Boolean>
+
+    /**
      * Apps can request a low profile mode [android.view.View.SYSTEM_UI_FLAG_LOW_PROFILE] where
      * status bar and navigation icons dim. In this mode, a notification dot appears where the
      * notification icons would appear if they would be shown outside of this mode.
@@ -83,6 +92,8 @@
     private val lightsOutInteractor: LightsOutInteractor,
     private val notificationsInteractor: ActiveNotificationsInteractor,
     keyguardTransitionInteractor: KeyguardTransitionInteractor,
+    sceneInteractor: SceneInteractor,
+    sceneContainerOcclusionInteractor: SceneContainerOcclusionInteractor,
     ongoingActivityChipsViewModel: OngoingActivityChipsViewModel,
     @Application coroutineScope: CoroutineScope,
 ) : CollapsedStatusBarViewModel {
@@ -99,6 +110,20 @@
 
     override val ongoingActivityChip = ongoingActivityChipsViewModel.chip
 
+    override val isHomeStatusBarAllowedByScene: StateFlow<Boolean> =
+        combine(
+                sceneInteractor.currentScene,
+                sceneContainerOcclusionInteractor.invisibleDueToOcclusion,
+            ) { currentScene, isOccluded ->
+                // All scenes have their own status bars, so we should only show the home status bar
+                // if we're not in a scene. The one exception: If the scene is occluded, then the
+                // occluding app needs to show the status bar. (Fullscreen apps actually won't show
+                // the status bar but that's handled with the rest of our fullscreen app logic,
+                // which lives elsewhere.)
+                currentScene == Scenes.Gone || isOccluded
+            }
+            .stateIn(coroutineScope, SharingStarted.WhileSubscribed(), initialValue = false)
+
     override fun areNotificationsLightsOut(displayId: Int): Flow<Boolean> =
         if (NotificationsLiveDataStoreRefactor.isUnexpectedlyInLegacyMode()) {
             emptyFlow()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
index 32774e0..8aabdf2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
@@ -15,12 +15,14 @@
  */
 package com.android.systemui.statusbar.policy
 
+import android.os.Handler
 import android.util.Log
 import androidx.annotation.VisibleForTesting
 import com.android.internal.logging.UiEvent
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.Dumpable
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun
 import com.android.systemui.statusbar.policy.BaseHeadsUpManager.HeadsUpEntry
@@ -35,10 +37,14 @@
 @SysUISingleton
 class AvalancheController
 @Inject
-constructor(dumpManager: DumpManager, private val uiEventLogger: UiEventLogger) : Dumpable {
+constructor(dumpManager: DumpManager,
+            private val uiEventLogger: UiEventLogger,
+            @Background private val bgHandler: Handler
+) : Dumpable {
 
     private val tag = "AvalancheController"
     private val debug = Compile.IS_DEBUG && Log.isLoggable(tag, Log.DEBUG)
+    var enableAtRuntime = true
 
     // HUN showing right now, in the floating state where full shade is hidden, on launcher or AOD
     @VisibleForTesting var headsUpEntryShowing: HeadsUpEntry? = null
@@ -81,13 +87,17 @@
         dumpManager.registerNormalDumpable(tag, /* module */ this)
     }
 
+    fun isEnabled() : Boolean {
+        return NotificationThrottleHun.isEnabled && enableAtRuntime
+    }
+
     fun getShowingHunKey(): String {
         return getKey(headsUpEntryShowing)
     }
 
     /** Run or delay Runnable for given HeadsUpEntry */
     fun update(entry: HeadsUpEntry?, runnable: Runnable, label: String) {
-        if (!NotificationThrottleHun.isEnabled) {
+        if (!isEnabled()) {
             runnable.run()
             return
         }
@@ -143,7 +153,7 @@
      * all Runnables associated with that entry.
      */
     fun delete(entry: HeadsUpEntry?, runnable: Runnable, label: String) {
-        if (!NotificationThrottleHun.isEnabled) {
+        if (!isEnabled()) {
             runnable.run()
             return
         }
@@ -184,7 +194,7 @@
      *    BaseHeadsUpManager.HeadsUpEntry.calculateFinishTime to shorten display duration.
      */
     fun getDurationMs(entry: HeadsUpEntry, autoDismissMs: Int): Int {
-        if (!NotificationThrottleHun.isEnabled) {
+        if (!isEnabled()) {
             // Use default duration, like we did before AvalancheController existed
             return autoDismissMs
         }
@@ -233,7 +243,7 @@
 
     /** Return true if entry is waiting to show. */
     fun isWaiting(key: String): Boolean {
-        if (!NotificationThrottleHun.isEnabled) {
+        if (!isEnabled()) {
             return false
         }
         for (entry in nextMap.keys) {
@@ -246,7 +256,7 @@
 
     /** Return list of keys for huns waiting */
     fun getWaitingKeys(): MutableList<String> {
-        if (!NotificationThrottleHun.isEnabled) {
+        if (!isEnabled()) {
             return mutableListOf()
         }
         val keyList = mutableListOf<String>()
@@ -257,7 +267,7 @@
     }
 
     fun getWaitingEntry(key: String): HeadsUpEntry? {
-        if (!NotificationThrottleHun.isEnabled) {
+        if (!isEnabled()) {
             return null
         }
         for (headsUpEntry in nextMap.keys) {
@@ -269,7 +279,7 @@
     }
 
     fun getWaitingEntryList(): List<HeadsUpEntry> {
-        if (!NotificationThrottleHun.isEnabled) {
+        if (!isEnabled()) {
             return mutableListOf()
         }
         return nextMap.keys.toList()
@@ -310,11 +320,7 @@
 
         // Remove runnable labels for dropped huns
         val listToDrop = nextList.subList(1, nextList.size)
-
-        // Log dropped HUNs
-        for (e in listToDrop) {
-            uiEventLogger.log(ThrottleEvent.AVALANCHE_THROTTLING_HUN_DROPPED)
-        }
+        logDroppedHunsInBackground(listToDrop.size)
 
         if (debug) {
             // Clear runnable labels
@@ -331,6 +337,15 @@
         showNow(headsUpEntryShowing!!, headsUpEntryShowingRunnableList)
     }
 
+    fun logDroppedHunsInBackground(numDropped: Int) {
+        bgHandler.post(Runnable {
+            // Do this in the background to avoid missing frames when closing the shade
+            for (n in 1..numDropped) {
+                uiEventLogger.log(ThrottleEvent.AVALANCHE_THROTTLING_HUN_DROPPED)
+            }
+        })
+    }
+
     fun clearNext() {
         nextList.clear()
         nextMap.clear()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
index fad5df8..220e729 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
@@ -834,6 +834,7 @@
          * @return true if the notification is sticky
          */
         public boolean isSticky() {
+            if (mEntry == null) return false;
             return (mEntry.isRowPinned() && mExpanded)
                     || mRemoteInputActive
                     || hasFullScreenIntent(mEntry);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index 6012ecd..775f34d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -250,6 +250,7 @@
             mLevel = (int) (100f
                     * intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
                     / intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100));
+            int previousPluggedChargingSource = mPluggedChargingSource;
             mPluggedChargingSource = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
             mPluggedIn = mPluggedChargingSource != 0;
             final int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
@@ -276,7 +277,9 @@
                 mIsBatteryDefender = isBatteryDefender;
                 fireIsBatteryDefenderChanged();
             }
-
+            if (mPluggedChargingSource != previousPluggedChargingSource) {
+                updatePowerSave();
+            }
             fireBatteryLevelChanged();
         } else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)) {
             updatePowerSave();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java
index abedd3220..a3dcc3b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastController.java
@@ -37,15 +37,4 @@
         void onCastDevicesChanged();
     }
 
-    public static final class CastDevice {
-        public static final int STATE_DISCONNECTED = 0;
-        public static final int STATE_CONNECTING = 1;
-        public static final int STATE_CONNECTED = 2;
-
-        public String id;
-        public String name;
-        public String description;
-        public int state = STATE_DISCONNECTED;
-        public Object tag;
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
index 64bdf60..45cb52a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
@@ -19,15 +19,12 @@
 import static android.media.MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY;
 
 import android.content.Context;
-import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.media.MediaRouter;
 import android.media.MediaRouter.RouteInfo;
 import android.media.projection.MediaProjectionInfo;
 import android.media.projection.MediaProjectionManager;
 import android.os.Handler;
-import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
 
@@ -37,8 +34,6 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.res.R;
-import com.android.systemui.util.Utils;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -51,10 +46,11 @@
 /** Platform implementation of the cast controller. **/
 @SysUISingleton
 public class CastControllerImpl implements CastController {
-    private static final String TAG = "CastController";
+    public static final String TAG = "CastController";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private final Context mContext;
+    private final PackageManager mPackageManager;
     @GuardedBy("mCallbacks")
     private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
     private final MediaRouter mMediaRouter;
@@ -68,8 +64,12 @@
     private MediaProjectionInfo mProjection;
 
     @Inject
-    public CastControllerImpl(Context context, DumpManager dumpManager) {
+    public CastControllerImpl(
+            Context context,
+            PackageManager packageManager,
+            DumpManager dumpManager) {
         mContext = context;
+        mPackageManager = packageManager;
         mMediaRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
         mMediaRouter.setRouterGroupId(MediaRouter.MIRRORING_GROUP_ID);
         mProjectionManager = (MediaProjectionManager)
@@ -156,36 +156,17 @@
         final ArrayList<CastDevice> devices = new ArrayList<>();
         synchronized(mRoutes) {
             for (RouteInfo route : mRoutes.values()) {
-                final CastDevice device = new CastDevice();
-                device.id = route.getTag().toString();
-                final CharSequence name = route.getName(mContext);
-                device.name = name != null ? name.toString() : null;
-                final CharSequence description = route.getDescription();
-                device.description = description != null ? description.toString() : null;
-
-                int statusCode = route.getStatusCode();
-                if (statusCode == RouteInfo.STATUS_CONNECTING) {
-                    device.state = CastDevice.STATE_CONNECTING;
-                } else if (route.isSelected() || statusCode == RouteInfo.STATUS_CONNECTED) {
-                    device.state = CastDevice.STATE_CONNECTED;
-                } else {
-                    device.state = CastDevice.STATE_DISCONNECTED;
-                }
-
-                device.tag = route;
-                devices.add(device);
+                devices.add(CastDevice.Companion.toCastDevice(route, mContext));
             }
         }
 
         synchronized (mProjectionLock) {
             if (mProjection != null) {
-                final CastDevice device = new CastDevice();
-                device.id = mProjection.getPackageName();
-                device.name = getAppName(mProjection.getPackageName());
-                device.description = mContext.getString(R.string.quick_settings_casting);
-                device.state = CastDevice.STATE_CONNECTED;
-                device.tag = mProjection;
-                devices.add(device);
+                devices.add(
+                        CastDevice.Companion.toCastDevice(
+                                mProjection,
+                                mContext,
+                                mPackageManager));
             }
         }
 
@@ -194,18 +175,18 @@
 
     @Override
     public void startCasting(CastDevice device) {
-        if (device == null || device.tag == null) return;
-        final RouteInfo route = (RouteInfo) device.tag;
+        if (device == null || device.getTag() == null) return;
+        final RouteInfo route = (RouteInfo) device.getTag();
         if (DEBUG) Log.d(TAG, "startCasting: " + routeToString(route));
         mMediaRouter.selectRoute(ROUTE_TYPE_REMOTE_DISPLAY, route);
     }
 
     @Override
     public void stopCasting(CastDevice device) {
-        final boolean isProjection = device.tag instanceof MediaProjectionInfo;
+        final boolean isProjection = device.getTag() instanceof MediaProjectionInfo;
         if (DEBUG) Log.d(TAG, "stopCasting isProjection=" + isProjection);
         if (isProjection) {
-            final MediaProjectionInfo projection = (MediaProjectionInfo) device.tag;
+            final MediaProjectionInfo projection = (MediaProjectionInfo) device.getTag();
             if (Objects.equals(mProjectionManager.getActiveProjectionInfo(), projection)) {
                 mProjectionManager.stopActiveProjection();
             } else {
@@ -219,7 +200,7 @@
     @Override
     public boolean hasConnectedCastDevice() {
         return getCastDevices().stream().anyMatch(
-                castDevice -> castDevice.state == CastDevice.STATE_CONNECTED);
+                castDevice -> castDevice.getState() == CastDevice.CastState.Connected);
     }
 
     private void setProjection(MediaProjectionInfo projection, boolean started) {
@@ -241,27 +222,6 @@
         }
     }
 
-    private String getAppName(String packageName) {
-        final PackageManager pm = mContext.getPackageManager();
-        if (Utils.isHeadlessRemoteDisplayProvider(pm, packageName)) {
-            return "";
-        }
-
-        try {
-            final ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0);
-            if (appInfo != null) {
-                final CharSequence label = appInfo.loadLabel(pm);
-                if (!TextUtils.isEmpty(label)) {
-                    return label.toString();
-                }
-            }
-            Log.w(TAG, "No label found for package: " + packageName);
-        } catch (NameNotFoundException e) {
-            Log.w(TAG, "Error getting appName for package: " + packageName, e);
-        }
-        return packageName;
-    }
-
     private void updateRemoteDisplays() {
         synchronized(mRoutes) {
             mRoutes.clear();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastDevice.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastDevice.kt
new file mode 100644
index 0000000..5fc160b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastDevice.kt
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.policy
+
+import android.content.Context
+import android.content.pm.PackageManager
+import android.media.MediaRouter
+import android.media.projection.MediaProjectionInfo
+import android.text.TextUtils
+import android.util.Log
+import com.android.systemui.res.R
+import com.android.systemui.util.Utils
+
+/** Represents a specific cast session. */
+data class CastDevice(
+    val id: String,
+    /** A human-readable name of what is receiving the cast (e.g. "Home Speaker", "Abc App"). */
+    val name: String?,
+    /** An optional description with more information about the cast. */
+    val description: String? = null,
+    val state: CastState,
+    val origin: CastOrigin,
+    /** Optional tag to use as a comparison value between cast sessions. */
+    val tag: Any? = null,
+) {
+    val isCasting = state == CastState.Connecting || state == CastState.Connected
+
+    companion object {
+        /** Creates a [CastDevice] based on the provided information from MediaRouter. */
+        fun MediaRouter.RouteInfo.toCastDevice(context: Context): CastDevice {
+            val state =
+                when {
+                    statusCode == MediaRouter.RouteInfo.STATUS_CONNECTING -> CastState.Connecting
+                    this.isSelected || statusCode == MediaRouter.RouteInfo.STATUS_CONNECTED ->
+                        CastState.Connected
+                    else -> CastState.Disconnected
+                }
+            return CastDevice(
+                id = this.tag.toString(),
+                name = this.getName(context)?.toString(),
+                description = this.description?.toString(),
+                state = state,
+                tag = this,
+                origin = CastOrigin.MediaRouter,
+            )
+        }
+
+        /** Creates a [CastDevice] based on the provided information from MediaProjection. */
+        fun MediaProjectionInfo.toCastDevice(
+            context: Context,
+            packageManager: PackageManager
+        ): CastDevice {
+            return CastDevice(
+                id = this.packageName,
+                name = getAppName(this.packageName, packageManager),
+                description = context.getString(R.string.quick_settings_casting),
+                state = CastState.Connected,
+                tag = this,
+                origin = CastOrigin.MediaProjection,
+            )
+        }
+
+        private fun getAppName(packageName: String, packageManager: PackageManager): String {
+            if (Utils.isHeadlessRemoteDisplayProvider(packageManager, packageName)) {
+                return ""
+            }
+            try {
+                val appInfo = packageManager.getApplicationInfo(packageName, 0)
+                val label = appInfo.loadLabel(packageManager)
+                if (!TextUtils.isEmpty(label)) {
+                    return label.toString()
+                }
+                Log.w(CastControllerImpl.TAG, "No label found for package: $packageName")
+            } catch (e: PackageManager.NameNotFoundException) {
+                Log.w(CastControllerImpl.TAG, "Error getting appName for package: $packageName", e)
+            }
+            return packageName
+        }
+    }
+
+    enum class CastState {
+        Disconnected,
+        Connecting,
+        Connected,
+    }
+
+    enum class CastOrigin {
+        /** SysUI found out about this cast device from MediaRouter APIs. */
+        MediaRouter,
+        /** SysUI found out about this cast device from MediaProjection APIs. */
+        MediaProjection,
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureControllerImpl.java
index de0eb49..528ef49 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DevicePostureControllerImpl.java
@@ -31,8 +31,8 @@
 
 import kotlin.Unit;
 
-import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.Executor;
 
 import javax.inject.Inject;
@@ -42,7 +42,13 @@
 public class DevicePostureControllerImpl implements DevicePostureController {
     /** From androidx.window.common.COMMON_STATE_USE_BASE_STATE */
     private static final int COMMON_STATE_USE_BASE_STATE = 1000;
-    private final List<Callback> mListeners = new ArrayList<>();
+    /**
+     * Despite this is always used only from the main thread, it might be that some listener
+     * unregisters itself while we're sending the update, ending up modifying this while we're
+     * iterating it.
+     * Keeping a threadsafe list of listeners helps preventing ConcurrentModificationExceptions.
+     */
+    private final List<Callback> mListeners = new CopyOnWriteArrayList<>();
     private final List<DeviceState> mSupportedStates;
     private DeviceState mCurrentDeviceState;
     private int mCurrentDevicePosture = DEVICE_POSTURE_UNKNOWN;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 1fc7bf4..31776cf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -115,7 +115,7 @@
     private final SendButtonTextWatcher mTextWatcher;
     private final TextView.OnEditorActionListener mEditorActionHandler;
     private final ArrayList<Runnable> mOnSendListeners = new ArrayList<>();
-    private final ArrayList<Consumer<Boolean>> mOnVisibilityChangedListeners = new ArrayList<>();
+    private Consumer<Boolean> mOnVisibilityChangedListener = null;
     private final ArrayList<OnFocusChangeListener> mEditTextFocusChangeListeners =
             new ArrayList<>();
 
@@ -733,24 +733,17 @@
      * {@link #getVisibility()} would return {@link View#VISIBLE}, and {@code false} it would return
      * any other value.
      */
-    public void addOnVisibilityChangedListener(Consumer<Boolean> listener) {
-        mOnVisibilityChangedListeners.add(listener);
-    }
-
-    /**
-     * Unregister a listener previously registered via
-     * {@link #addOnVisibilityChangedListener(Consumer)}.
-     */
-    public void removeOnVisibilityChangedListener(Consumer<Boolean> listener) {
-        mOnVisibilityChangedListeners.remove(listener);
+    public void setOnVisibilityChangedListener(Consumer<Boolean> listener) {
+        mOnVisibilityChangedListener = listener;
     }
 
     @Override
     protected void onVisibilityChanged(View changedView, int visibility) {
         super.onVisibilityChanged(changedView, visibility);
         if (changedView == this) {
-            for (Consumer<Boolean> listener : new ArrayList<>(mOnVisibilityChangedListeners)) {
-                listener.accept(visibility == VISIBLE);
+            final Consumer<Boolean> visibilityChangedListener = mOnVisibilityChangedListener;
+            if (visibilityChangedListener != null) {
+                visibilityChangedListener.accept(visibility == VISIBLE);
             }
             // Hide soft-keyboard when the input view became invisible
             // (i.e. The notification shade collapsed by pressing the home key)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
index ad19729..23e40b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeController.java
@@ -24,7 +24,14 @@
 import android.service.notification.ZenModeConfig.ZenRule;
 
 import com.android.systemui.statusbar.policy.ZenModeController.Callback;
+import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor;
 
+/**
+ * Callback-based controller for listening to (or making) zen mode changes. Please prefer using the
+ * Flow-based {@link ZenModeInteractor} for new code instead of this.
+ *
+ * TODO(b/308591859): This should eventually be replaced by ZenModeInteractor/ZenModeRepository.
+ */
 public interface ZenModeController extends CallbackController<Callback> {
     void setZen(int zen, Uri conditionId, String reason);
     int getZen();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
index 15200bd..e08e4d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
@@ -73,7 +73,6 @@
 import com.android.systemui.statusbar.policy.bluetooth.BluetoothRepository;
 import com.android.systemui.statusbar.policy.bluetooth.BluetoothRepositoryImpl;
 import com.android.systemui.statusbar.policy.data.repository.DeviceProvisioningRepositoryModule;
-import com.android.systemui.statusbar.policy.data.repository.ZenModeRepositoryModule;
 
 import dagger.Binds;
 import dagger.Module;
@@ -84,7 +83,7 @@
 import javax.inject.Named;
 
 /** Dagger Module for code in the statusbar.policy package. */
-@Module(includes = { DeviceProvisioningRepositoryModule.class, ZenModeRepositoryModule.class })
+@Module(includes = {DeviceProvisioningRepositoryModule.class})
 public interface StatusBarPolicyModule {
 
     String DEVICE_STATE_ROTATION_LOCK_DEFAULTS = "DEVICE_STATE_ROTATION_LOCK_DEFAULTS";
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/data/repository/ZenModeRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/data/repository/ZenModeRepository.kt
deleted file mode 100644
index 94ab58a..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/data/repository/ZenModeRepository.kt
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.policy.data.repository
-
-import android.app.NotificationManager
-import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
-import com.android.systemui.statusbar.policy.ZenModeController
-import dagger.Binds
-import dagger.Module
-import javax.inject.Inject
-import kotlinx.coroutines.channels.awaitClose
-import kotlinx.coroutines.flow.Flow
-
-/**
- * A repository that holds information about the status and configuration of Zen Mode (or Do Not
- * Disturb/DND Mode).
- */
-interface ZenModeRepository {
-    val zenMode: Flow<Int>
-    val consolidatedNotificationPolicy: Flow<NotificationManager.Policy?>
-}
-
-class ZenModeRepositoryImpl
-@Inject
-constructor(
-    private val zenModeController: ZenModeController,
-) : ZenModeRepository {
-    // TODO(b/308591859): ZenModeController should use flows instead of callbacks. The
-    // conflatedCallbackFlows here should be replaced eventually, see:
-    // https://docs.google.com/document/d/1gAiuYupwUAFdbxkDXa29A4aFNu7XoCd7sCIk31WTnHU/edit?resourcekey=0-J4ZBiUhLhhQnNobAcI2vIw
-
-    override val zenMode: Flow<Int> = conflatedCallbackFlow {
-        val callback =
-            object : ZenModeController.Callback {
-                override fun onZenChanged(zen: Int) {
-                    trySend(zen)
-                }
-            }
-        zenModeController.addCallback(callback)
-        trySend(zenModeController.zen)
-
-        awaitClose { zenModeController.removeCallback(callback) }
-    }
-
-    override val consolidatedNotificationPolicy: Flow<NotificationManager.Policy?> =
-        conflatedCallbackFlow {
-            val callback =
-                object : ZenModeController.Callback {
-                    override fun onConsolidatedPolicyChanged(policy: NotificationManager.Policy?) {
-                        trySend(policy)
-                    }
-                }
-            zenModeController.addCallback(callback)
-            trySend(zenModeController.consolidatedPolicy)
-
-            awaitClose { zenModeController.removeCallback(callback) }
-        }
-}
-
-@Module
-interface ZenModeRepositoryModule {
-    @Binds fun bindImpl(impl: ZenModeRepositoryImpl): ZenModeRepository
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt
index ae31851..e4d0668 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractor.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.statusbar.policy.domain.interactor
 
 import android.provider.Settings
-import com.android.systemui.statusbar.policy.data.repository.ZenModeRepository
+import com.android.settingslib.notification.data.repository.ZenModeRepository
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.combine
@@ -30,9 +30,9 @@
  */
 class ZenModeInteractor @Inject constructor(repository: ZenModeRepository) {
     val isZenModeEnabled: Flow<Boolean> =
-        repository.zenMode
+        repository.globalZenMode
             .map {
-                when (it) {
+                when (it ?: Settings.Global.ZEN_MODE_OFF) {
                     Settings.Global.ZEN_MODE_ALARMS -> true
                     Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS -> true
                     Settings.Global.ZEN_MODE_NO_INTERRUPTIONS -> true
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt
index 3e01180..4869114 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModel.kt
@@ -20,7 +20,8 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
-import com.android.systemui.keyguard.shared.model.StatusBarState
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.statusbar.domain.interactor.KeyguardStatusBarInteractor
 import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationInteractor
 import com.android.systemui.statusbar.policy.BatteryController
@@ -48,6 +49,7 @@
 constructor(
     @Application scope: CoroutineScope,
     headsUpNotificationInteractor: HeadsUpNotificationInteractor,
+    sceneInteractor: SceneInteractor,
     keyguardInteractor: KeyguardInteractor,
     keyguardStatusBarInteractor: KeyguardStatusBarInteractor,
     batteryController: BatteryController,
@@ -55,11 +57,11 @@
     /** True if this view should be visible and false otherwise. */
     val isVisible: StateFlow<Boolean> =
         combine(
+                sceneInteractor.currentScene,
                 keyguardInteractor.isDozing,
-                keyguardInteractor.statusBarState,
                 headsUpNotificationInteractor.showHeadsUpStatusBar,
-            ) { isDozing, statusBarState, showHeadsUpStatusBar ->
-                !isDozing && statusBarState == StatusBarState.KEYGUARD && !showHeadsUpStatusBar
+            ) { currentScene, isDozing, showHeadsUpStatusBar ->
+                currentScene == Scenes.Lockscreen && !isDozing && !showHeadsUpStatusBar
             }
             .stateIn(scope, SharingStarted.WhileSubscribed(), false)
 
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
index 2797b8d..e9f4374 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusUsiPowerUI.kt
@@ -36,10 +36,10 @@
 import com.android.internal.logging.InstanceId
 import com.android.internal.logging.InstanceIdSequence
 import com.android.internal.logging.UiEventLogger
-import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.log.DebugLogger.debugLog
+import com.android.systemui.res.R
 import com.android.systemui.shared.hardware.hasInputDevice
 import com.android.systemui.shared.hardware.isAnyStylusSource
 import com.android.systemui.util.NotificationChannels
@@ -65,8 +65,10 @@
     private var batteryCapacity = 1.0f
     private var suppressed = false
     private var instanceId: InstanceId? = null
-    @VisibleForTesting var inputDeviceId: Int? = null
-      private set
+    @VisibleForTesting
+    var inputDeviceId: Int? = null
+        private set
+
     @VisibleForTesting var instanceIdSequence = InstanceIdSequence(1 shl 13)
 
     fun init() {
@@ -113,7 +115,7 @@
             inputDeviceId = deviceId
             if (batteryState.capacity == batteryCapacity || batteryState.capacity <= 0f)
                 return@updateBattery
-
+            // Note that batteryState.capacity == NaN will fall through to here
             batteryCapacity = batteryState.capacity
             debugLog {
                 "Updating notification battery state to $batteryCapacity " +
@@ -172,7 +174,7 @@
     }
 
     private fun isBatteryBelowThreshold(): Boolean {
-        return batteryCapacity <= LOW_BATTERY_THRESHOLD
+        return !batteryCapacity.isNaN() && batteryCapacity <= LOW_BATTERY_THRESHOLD
     }
 
     private fun hasConnectedBluetoothStylus(): Boolean {
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index 4963aae..c7fc445 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -202,8 +202,8 @@
             }
             boolean currentUser = userId == mUserTracker.getUserId();
             boolean isAsleep = themeOverlayControllerWakefulnessDeprecation()
-                    ? mKeyguardTransitionInteractor.isFinishedInStateWhereValue(
-                    KeyguardState.Companion::deviceIsAsleepInState)
+                    ? KeyguardState.Companion.deviceIsAsleepInState(
+                            mKeyguardTransitionInteractor.getFinishedState())
                     : mWakefulnessLifecycle.getWakefulness() != WAKEFULNESS_ASLEEP;
 
             if (currentUser && !mAcceptColorEvents && isAsleep) {
@@ -525,7 +525,7 @@
 
         if (themeOverlayControllerWakefulnessDeprecation()) {
             mJavaAdapter.alwaysCollectFlow(
-                    mKeyguardTransitionInteractor.isFinishedInState(KeyguardState.DOZING),
+                    mKeyguardTransitionInteractor.isFinishedIn(KeyguardState.DOZING),
                     isFinishedInDozing -> {
                         if (isFinishedInDozing) whenAsleepHandler.run();
                     });
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/domain/interactor/TouchpadGesturesInteractor.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/domain/interactor/TouchpadGesturesInteractor.kt
new file mode 100644
index 0000000..b6c2ae7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/domain/interactor/TouchpadGesturesInteractor.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.touchpad.tutorial.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.model.SysUiState
+import com.android.systemui.settings.DisplayTracker
+import com.android.systemui.shared.system.QuickStepContract
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+
+@SysUISingleton
+class TouchpadGesturesInteractor
+@Inject
+constructor(
+    private val sysUiState: SysUiState,
+    private val displayTracker: DisplayTracker,
+    @Background private val backgroundScope: CoroutineScope
+) {
+    fun disableGestures() {
+        setGesturesState(disabled = true)
+    }
+
+    fun enableGestures() {
+        setGesturesState(disabled = false)
+    }
+
+    private fun setGesturesState(disabled: Boolean) {
+        backgroundScope.launch {
+            sysUiState
+                .setFlag(QuickStepContract.SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED, disabled)
+                .commitUpdate(displayTracker.defaultDisplayId)
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/GestureViewModelFactory.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/GestureViewModelFactory.kt
deleted file mode 100644
index 504bd5f..0000000
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/GestureViewModelFactory.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.touchpad.tutorial.ui
-
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.ViewModelProvider
-
-sealed class GestureTutorialViewModel : ViewModel()
-
-class BackGestureTutorialViewModel : GestureTutorialViewModel()
-
-class HomeGestureTutorialViewModel : GestureTutorialViewModel()
-
-class GestureViewModelFactory : ViewModelProvider.Factory {
-
-    @Suppress("UNCHECKED_CAST")
-    override fun <T : ViewModel> create(modelClass: Class<T>): T {
-        return when (modelClass) {
-            BackGestureTutorialViewModel::class.java -> BackGestureTutorialViewModel()
-            HomeGestureTutorialViewModel::class.java -> HomeGestureTutorialViewModel()
-            else -> error("Unknown ViewModel class: ${modelClass.name}")
-        }
-            as T
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/TouchpadTutorialViewModel.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/TouchpadTutorialViewModel.kt
index 11740a8..9e6553a 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/TouchpadTutorialViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/TouchpadTutorialViewModel.kt
@@ -18,11 +18,13 @@
 
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.ViewModelProvider
+import com.android.systemui.touchpad.tutorial.domain.interactor.TouchpadGesturesInteractor
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
 import javax.inject.Inject
 
-class TouchpadTutorialViewModel : ViewModel() {
+class TouchpadTutorialViewModel(private val gesturesInteractor: TouchpadGesturesInteractor) :
+    ViewModel() {
 
     private val _screen = MutableStateFlow(Screen.TUTORIAL_SELECTION)
     val screen: StateFlow<Screen> = _screen
@@ -31,11 +33,20 @@
         _screen.value = screen
     }
 
-    class Factory @Inject constructor() : ViewModelProvider.Factory {
+    fun onOpened() {
+        gesturesInteractor.disableGestures()
+    }
+
+    fun onClosed() {
+        gesturesInteractor.enableGestures()
+    }
+
+    class Factory @Inject constructor(private val gesturesInteractor: TouchpadGesturesInteractor) :
+        ViewModelProvider.Factory {
 
         @Suppress("UNCHECKED_CAST")
         override fun <T : ViewModel> create(modelClass: Class<T>): T {
-            return TouchpadTutorialViewModel() as T
+            return TouchpadTutorialViewModel(gesturesInteractor) as T
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitor.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitor.kt
new file mode 100644
index 0000000..1fa7a0c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitor.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.touchpad.tutorial.ui.gesture
+
+import android.view.MotionEvent
+import kotlin.math.abs
+
+/**
+ * Monitor for touchpad gestures that calls [gestureDoneCallback] when gesture was successfully
+ * done. All tracked motion events should be passed to [processTouchpadEvent]
+ */
+interface TouchpadGestureMonitor {
+
+    val gestureDistanceThresholdPx: Int
+    val gestureDoneCallback: () -> Unit
+
+    fun processTouchpadEvent(event: MotionEvent)
+}
+
+class BackGestureMonitor(
+    override val gestureDistanceThresholdPx: Int,
+    override val gestureDoneCallback: () -> Unit
+) : TouchpadGestureMonitor {
+
+    private var xStart = 0f
+
+    override fun processTouchpadEvent(event: MotionEvent) {
+        val action = event.actionMasked
+        when (action) {
+            MotionEvent.ACTION_DOWN -> {
+                if (isThreeFingerTouchpadSwipe(event)) {
+                    xStart = event.x
+                }
+            }
+            MotionEvent.ACTION_UP -> {
+                if (isThreeFingerTouchpadSwipe(event)) {
+                    val distance = abs(event.x - xStart)
+                    if (distance >= gestureDistanceThresholdPx) {
+                        gestureDoneCallback()
+                    }
+                }
+            }
+        }
+    }
+
+    private fun isThreeFingerTouchpadSwipe(event: MotionEvent): Boolean {
+        return event.classification == MotionEvent.CLASSIFICATION_MULTI_FINGER_SWIPE &&
+            event.getAxisValue(MotionEvent.AXIS_GESTURE_SWIPE_FINGER_COUNT) == 3f
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGesture.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGesture.kt
new file mode 100644
index 0000000..4ae9c7b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGesture.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.touchpad.tutorial.ui.gesture
+
+enum class TouchpadGesture {
+    BACK,
+    HOME;
+
+    fun toMonitor(
+        swipeDistanceThresholdPx: Int,
+        gestureDoneCallback: () -> Unit
+    ): TouchpadGestureMonitor {
+        return when (this) {
+            BACK -> BackGestureMonitor(swipeDistanceThresholdPx, gestureDoneCallback)
+            else -> throw IllegalArgumentException("Not implemented yet")
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandler.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandler.kt
new file mode 100644
index 0000000..dc8471c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandler.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.touchpad.tutorial.ui.gesture
+
+import android.view.InputDevice
+import android.view.MotionEvent
+
+/**
+ * Allows listening to touchpadGesture and calling onDone when gesture was triggered. Can have all
+ * motion events passed to [onMotionEvent] and will filter touchpad events accordingly
+ */
+class TouchpadGestureHandler(
+    touchpadGesture: TouchpadGesture,
+    swipeDistanceThresholdPx: Int,
+    onDone: () -> Unit
+) {
+
+    private val gestureRecognition =
+        touchpadGesture.toMonitor(swipeDistanceThresholdPx, gestureDoneCallback = onDone)
+
+    fun onMotionEvent(event: MotionEvent): Boolean {
+        // events from touchpad have SOURCE_MOUSE and not SOURCE_TOUCHPAD because of legacy reasons
+        val isFromTouchpad =
+            event.isFromSource(InputDevice.SOURCE_MOUSE) &&
+                event.getToolType(0) == MotionEvent.TOOL_TYPE_FINGER
+        val buttonClick =
+            event.actionMasked == MotionEvent.ACTION_DOWN &&
+                event.isButtonPressed(MotionEvent.BUTTON_PRIMARY)
+        return if (isFromTouchpad && !buttonClick) {
+            gestureRecognition.processTouchpadEvent(event)
+            true
+        } else {
+            false
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/BackGestureTutorialScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/BackGestureTutorialScreen.kt
new file mode 100644
index 0000000..04a4798
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/BackGestureTutorialScreen.kt
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.touchpad.tutorial.ui.view
+
+import androidx.activity.compose.BackHandler
+import androidx.annotation.StringRes
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.input.pointer.pointerInteropFilter
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import com.android.systemui.res.R
+import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGesture.BACK
+import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGestureHandler
+
+@OptIn(ExperimentalComposeUiApi::class)
+@Composable
+fun BackGestureTutorialScreen(
+    onDoneButtonClicked: () -> Unit,
+    onBack: () -> Unit,
+) {
+    BackHandler(onBack = onBack)
+    var gestureDone by remember { mutableStateOf(false) }
+    val swipeDistanceThresholdPx =
+        with(LocalContext.current) {
+            resources.getDimensionPixelSize(
+                com.android.internal.R.dimen.system_gestures_distance_threshold
+            )
+        }
+    val gestureHandler =
+        remember(swipeDistanceThresholdPx) {
+            TouchpadGestureHandler(BACK, swipeDistanceThresholdPx, onDone = { gestureDone = true })
+        }
+    Box(
+        modifier =
+            Modifier.fillMaxSize()
+                // we need to use pointerInteropFilter because some info about touchpad gestures is
+                // only available in MotionEvent
+                .pointerInteropFilter(onTouchEvent = gestureHandler::onMotionEvent)
+    ) {
+        GestureTutorialContent(gestureDone, onDoneButtonClicked)
+    }
+}
+
+@Composable
+private fun GestureTutorialContent(gestureDone: Boolean, onDoneButtonClicked: () -> Unit) {
+    Column(
+        verticalArrangement = Arrangement.Center,
+        modifier =
+            Modifier.fillMaxSize()
+                .background(color = MaterialTheme.colorScheme.surfaceContainer)
+                .padding(start = 48.dp, top = 124.dp, end = 48.dp, bottom = 48.dp)
+    ) {
+        Row(modifier = Modifier.fillMaxWidth().weight(1f)) {
+            TutorialDescription(
+                titleTextId =
+                    if (gestureDone) R.string.touchpad_tutorial_gesture_done
+                    else R.string.touchpad_back_gesture_action_title,
+                bodyTextId = R.string.touchpad_back_gesture_guidance,
+                modifier = Modifier.weight(1f)
+            )
+            Spacer(modifier = Modifier.width(76.dp))
+            TutorialAnimation(modifier = Modifier.weight(1f).padding(top = 24.dp))
+        }
+        DoneButton(onDoneButtonClicked = onDoneButtonClicked)
+    }
+}
+
+@Composable
+fun TutorialDescription(
+    @StringRes titleTextId: Int,
+    @StringRes bodyTextId: Int,
+    modifier: Modifier = Modifier
+) {
+    Column(verticalArrangement = Arrangement.Top, modifier = modifier) {
+        Text(text = stringResource(id = titleTextId), style = MaterialTheme.typography.displayLarge)
+        Spacer(modifier = Modifier.height(16.dp))
+        Text(text = stringResource(id = bodyTextId), style = MaterialTheme.typography.bodyLarge)
+    }
+}
+
+@Composable
+fun TutorialAnimation(modifier: Modifier = Modifier) {
+    // below are just placeholder images, will be substituted by animations soon
+    Column(modifier = modifier.fillMaxWidth()) {
+        Image(
+            painter = painterResource(id = R.drawable.placeholder_touchpad_tablet_back_gesture),
+            contentDescription =
+                stringResource(
+                    id = R.string.touchpad_back_gesture_screen_animation_content_description
+                ),
+            modifier = Modifier.fillMaxWidth()
+        )
+        Spacer(modifier = Modifier.height(24.dp))
+        Image(
+            painter = painterResource(id = R.drawable.placeholder_touchpad_back_gesture),
+            contentDescription =
+                stringResource(id = R.string.touchpad_back_gesture_animation_content_description),
+            modifier = Modifier.fillMaxWidth()
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt
index b7629c7..93c2658 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TouchpadTutorialActivity.kt
@@ -17,19 +17,16 @@
 package com.android.systemui.touchpad.tutorial.ui.view
 
 import android.os.Bundle
+import android.view.WindowManager
 import androidx.activity.ComponentActivity
 import androidx.activity.compose.setContent
 import androidx.activity.enableEdgeToEdge
+import androidx.activity.viewModels
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.lifecycle.Lifecycle.State.STARTED
-import androidx.lifecycle.ViewModelProvider
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import androidx.lifecycle.viewmodel.compose.viewModel
 import com.android.compose.theme.PlatformTheme
-import com.android.systemui.touchpad.tutorial.ui.BackGestureTutorialViewModel
-import com.android.systemui.touchpad.tutorial.ui.GestureViewModelFactory
-import com.android.systemui.touchpad.tutorial.ui.HomeGestureTutorialViewModel
 import com.android.systemui.touchpad.tutorial.ui.Screen.BACK_GESTURE
 import com.android.systemui.touchpad.tutorial.ui.Screen.HOME_GESTURE
 import com.android.systemui.touchpad.tutorial.ui.Screen.TUTORIAL_SELECTION
@@ -42,18 +39,29 @@
     private val viewModelFactory: TouchpadTutorialViewModel.Factory,
 ) : ComponentActivity() {
 
+    private val vm by viewModels<TouchpadTutorialViewModel>(factoryProducer = { viewModelFactory })
+
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         enableEdgeToEdge()
-        setContent {
-            PlatformTheme { TouchpadTutorialScreen(viewModelFactory, closeTutorial = { finish() }) }
-        }
+        setContent { PlatformTheme { TouchpadTutorialScreen(vm) { finish() } } }
+        // required to handle 3+ fingers on touchpad
+        window.addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY)
+    }
+
+    override fun onResume() {
+        super.onResume()
+        vm.onOpened()
+    }
+
+    override fun onPause() {
+        super.onPause()
+        vm.onClosed()
     }
 }
 
 @Composable
-fun TouchpadTutorialScreen(viewModelFactory: ViewModelProvider.Factory, closeTutorial: () -> Unit) {
-    val vm = viewModel<TouchpadTutorialViewModel>(factory = viewModelFactory)
+fun TouchpadTutorialScreen(vm: TouchpadTutorialViewModel, closeTutorial: () -> Unit) {
     val activeScreen by vm.screen.collectAsStateWithLifecycle(STARTED)
     when (activeScreen) {
         TUTORIAL_SELECTION ->
@@ -63,17 +71,11 @@
                 onActionKeyTutorialClicked = {},
                 onDoneButtonClicked = closeTutorial
             )
-        BACK_GESTURE -> BackGestureTutorialScreen()
-        HOME_GESTURE -> HomeGestureTutorialScreen()
+        BACK_GESTURE ->
+            BackGestureTutorialScreen(
+                onDoneButtonClicked = { vm.goTo(TUTORIAL_SELECTION) },
+                onBack = { vm.goTo(TUTORIAL_SELECTION) },
+            )
+        HOME_GESTURE -> {}
     }
 }
-
-@Composable
-fun BackGestureTutorialScreen() {
-    val vm = viewModel<BackGestureTutorialViewModel>(factory = GestureViewModelFactory())
-}
-
-@Composable
-fun HomeGestureTutorialScreen() {
-    val vm = viewModel<HomeGestureTutorialViewModel>(factory = GestureViewModelFactory())
-}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TutorialComponents.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TutorialComponents.kt
new file mode 100644
index 0000000..16fa91d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TutorialComponents.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.touchpad.tutorial.ui.view
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.material3.Button
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import com.android.systemui.res.R
+
+@Composable
+fun DoneButton(onDoneButtonClicked: () -> Unit, modifier: Modifier = Modifier) {
+    Row(
+        horizontalArrangement = Arrangement.End,
+        verticalAlignment = Alignment.CenterVertically,
+        modifier = modifier.fillMaxWidth()
+    ) {
+        Button(onClick = onDoneButtonClicked) {
+            Text(stringResource(R.string.touchpad_tutorial_done_button))
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TutorialSelectionScreen.kt b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TutorialSelectionScreen.kt
index 532eb1b..877bbe1 100644
--- a/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TutorialSelectionScreen.kt
+++ b/packages/SystemUI/src/com/android/systemui/touchpad/tutorial/ui/view/TutorialSelectionScreen.kt
@@ -22,7 +22,6 @@
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.aspectRatio
 import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material3.Button
@@ -114,16 +113,3 @@
         Text(text = text, style = MaterialTheme.typography.headlineLarge)
     }
 }
-
-@Composable
-private fun DoneButton(onDoneButtonClicked: () -> Unit, modifier: Modifier = Modifier) {
-    Row(
-        horizontalArrangement = Arrangement.End,
-        verticalAlignment = Alignment.CenterVertically,
-        modifier = modifier.fillMaxWidth()
-    ) {
-        Button(onClick = onDoneButtonClicked) {
-            Text(stringResource(R.string.touchpad_tutorial_done_button))
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
index ec6f862..fb40235 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
@@ -14,18 +14,18 @@
 
 package com.android.systemui.tuner;
 
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.KEY;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.KEY_CODE_END;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.KEY_CODE_START;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.KEY_IMAGE_DELIM;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.MENU_IME_ROTATE;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.NAVSPACE;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.NAV_BAR_LEFT;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.NAV_BAR_RIGHT;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.NAV_BAR_VIEWS;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.extractButton;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.extractImage;
-import static com.android.systemui.navigationbar.NavigationBarInflaterView.extractKeycode;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.KEY;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.KEY_CODE_END;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.KEY_CODE_START;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.KEY_IMAGE_DELIM;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.MENU_IME_ROTATE;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.NAVSPACE;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.NAV_BAR_LEFT;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.NAV_BAR_RIGHT;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.NAV_BAR_VIEWS;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.extractButton;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.extractImage;
+import static com.android.systemui.navigationbar.views.NavigationBarInflaterView.extractKeycode;
 
 import android.annotation.Nullable;
 import android.app.AlertDialog;
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimation.kt
index aea739d..c5e98a1 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimation.kt
@@ -22,9 +22,12 @@
 import android.annotation.BinderThread
 import android.os.SystemProperties
 import android.util.Log
+import android.view.View
 import android.view.animation.DecelerateInterpolator
 import com.android.app.tracing.TraceUtils.traceAsync
 import com.android.internal.foldables.FoldLockSettingAvailabilityProvider
+import com.android.internal.jank.Cuj.CUJ_FOLD_ANIM
+import com.android.internal.jank.InteractionJankMonitor
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.display.data.repository.DeviceStateRepository
 import com.android.systemui.power.domain.interactor.PowerInteractor
@@ -65,7 +68,8 @@
     @Background private val applicationScope: CoroutineScope,
     private val animationStatusRepository: AnimationStatusRepository,
     private val controllerFactory: FullscreenLightRevealAnimationController.Factory,
-    private val foldLockSettingAvailabilityProvider: FoldLockSettingAvailabilityProvider
+    private val foldLockSettingAvailabilityProvider: FoldLockSettingAvailabilityProvider,
+    private val interactionJankMonitor: InteractionJankMonitor
 ) : FullscreenLightRevealAnimation {
 
     private val revealProgressValueAnimator: ValueAnimator =
@@ -87,7 +91,7 @@
             controllerFactory.create(
                 displaySelector = { minByOrNull { it.naturalWidth } },
                 effectFactory = { LinearSideLightRevealEffect(it.isVerticalRotation()) },
-                overlayContainerName = SURFACE_CONTAINER_NAME
+                overlayContainerName = OVERLAY_TITLE
             )
         controller.init()
 
@@ -149,13 +153,23 @@
     private suspend fun waitForGoToSleep() =
         traceAsync(TAG, "waitForGoToSleep()") { powerInteractor.isAsleep.filter { it }.first() }
 
-    private suspend fun playFoldLightRevealOverlayAnimation() {
-        revealProgressValueAnimator.duration = ANIMATION_DURATION
-        revealProgressValueAnimator.interpolator = DecelerateInterpolator()
-        revealProgressValueAnimator.addUpdateListener { animation ->
-            controller.updateRevealAmount(animation.animatedFraction)
+    private suspend fun playFoldLightRevealOverlayAnimation() =
+        trackCuj(CUJ_FOLD_ANIM, controller.scrimView) {
+            revealProgressValueAnimator.duration = ANIMATION_DURATION
+            revealProgressValueAnimator.interpolator = DecelerateInterpolator()
+            revealProgressValueAnimator.addUpdateListener { animation ->
+                controller.updateRevealAmount(animation.animatedFraction)
+            }
+            revealProgressValueAnimator.startAndAwaitCompletion()
         }
-        revealProgressValueAnimator.startAndAwaitCompletion()
+
+    private suspend fun trackCuj(cuj: Int, view: View?, block: suspend () -> Unit) {
+        view?.let { interactionJankMonitor.begin(it, cuj) }
+        try {
+            block()
+        } finally {
+            if (view != null) interactionJankMonitor.end(cuj)
+        }
     }
 
     private suspend fun ValueAnimator.startAndAwaitCompletion(): Unit =
@@ -182,7 +196,7 @@
     private companion object {
         const val TAG = "FoldLightRevealOverlayAnimation"
         const val WAIT_FOR_ANIMATION_TIMEOUT_MS = 2000L
-        const val SURFACE_CONTAINER_NAME = "fold-overlay-container"
+        const val OVERLAY_TITLE = "fold-animation-overlay"
         val ANIMATION_DURATION: Long
             get() = SystemProperties.getLong("persist.fold_animation_duration", 200L)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/FullscreenLightRevealAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/FullscreenLightRevealAnimation.kt
index 135edfc..a921377 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/FullscreenLightRevealAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/FullscreenLightRevealAnimation.kt
@@ -73,7 +73,7 @@
     @Main private val executor: Executor,
     @Assisted private val displaySelector: List<DisplayInfo>.() -> DisplayInfo?,
     @Assisted private val lightRevealEffectFactory: (rotation: Int) -> LightRevealEffect,
-    @Assisted private val overlayContainerName: String
+    @Assisted private val overlayTitle: String
 ) {
 
     private lateinit var bgExecutor: Executor
@@ -81,7 +81,10 @@
 
     private var currentRotation: Int = context.display.rotation
     private var root: SurfaceControlViewHost? = null
-    private var scrimView: LightRevealScrim? = null
+
+    /** The scrim view that is used to reveal the screen. */
+    var scrimView: LightRevealScrim? = null
+        private set
 
     private val rotationWatcher = RotationWatcher()
     private val internalDisplayInfos: List<DisplayInfo> =
@@ -153,7 +156,7 @@
         val containerBuilder =
             SurfaceControl.Builder(SurfaceSession())
                 .setContainerLayer()
-                .setName(overlayContainerName)
+                .setName("FoldUnfoldAnimationContainer")
 
         displayAreaHelper
             .get()
@@ -221,7 +224,7 @@
             }
             format = PixelFormat.TRANSLUCENT
             type = WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY
-            title = javaClass.simpleName
+            title = overlayTitle
             layoutInDisplayCutoutMode =
                 WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
             fitInsetsTypes = 0
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
index f355dd8..666e75f 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
@@ -71,7 +71,7 @@
             fullscreenLightRevealAnimationControllerFactory.create(
                 displaySelector = { maxByOrNull { it.naturalWidth } },
                 effectFactory = { LinearLightRevealEffect(it.isVerticalRotation()) },
-                overlayContainerName = SURFACE_CONTAINER_NAME,
+                overlayContainerName = OVERLAY_TITLE,
             )
         controller.init()
         bgExecutor = threadFactory.buildDelayableExecutorOnHandler(unfoldProgressHandler)
@@ -194,7 +194,7 @@
 
     private companion object {
         const val TAG = "UnfoldLightRevealOverlayAnimation"
-        const val SURFACE_CONTAINER_NAME = "unfold-overlay-container"
+        const val OVERLAY_TITLE = "unfold-animation-overlay"
         const val UNFOLD_BLOCK_TOUCHES_UNTIL_PROGRESS = 0.8f
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/util/dagger/UtilModule.java b/packages/SystemUI/src/com/android/systemui/util/dagger/UtilModule.java
index 9c8a481..501fee6 100644
--- a/packages/SystemUI/src/com/android/systemui/util/dagger/UtilModule.java
+++ b/packages/SystemUI/src/com/android/systemui/util/dagger/UtilModule.java
@@ -20,15 +20,15 @@
 import com.android.systemui.util.RingerModeTrackerImpl;
 import com.android.systemui.util.animation.data.repository.AnimationStatusRepository;
 import com.android.systemui.util.animation.data.repository.AnimationStatusRepositoryImpl;
+import com.android.systemui.util.icons.AppCategoryIconProvider;
+import com.android.systemui.util.icons.AppCategoryIconProviderImpl;
 import com.android.systemui.util.wrapper.UtilWrapperModule;
 
 import dagger.Binds;
 import dagger.Module;
 
 /** Dagger Module for code in the util package. */
-@Module(includes = {
-                UtilWrapperModule.class
-        })
+@Module(includes = {UtilWrapperModule.class})
 public interface UtilModule {
     /** */
     @Binds
@@ -37,4 +37,8 @@
     @Binds
     AnimationStatusRepository provideAnimationStatus(
             AnimationStatusRepositoryImpl ringerModeTrackerImpl);
+
+    /** */
+    @Binds
+    AppCategoryIconProvider appCategoryIconProvider(AppCategoryIconProviderImpl impl);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/util/icons/AppCategoryIconProvider.kt b/packages/SystemUI/src/com/android/systemui/util/icons/AppCategoryIconProvider.kt
new file mode 100644
index 0000000..6e3f8f1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/icons/AppCategoryIconProvider.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.icons
+
+import android.content.Intent
+import android.content.pm.PackageInfo
+import android.content.pm.PackageManager
+import android.graphics.drawable.Icon
+import android.os.RemoteException
+import android.util.Log
+import com.android.systemui.assist.AssistManager
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.shared.system.PackageManagerWrapper
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.withContext
+
+interface AppCategoryIconProvider {
+    /** Returns the [Icon] of the default assistant app, if it exists. */
+    suspend fun assistantAppIcon(): Icon?
+
+    /**
+     * Returns the [Icon] of the default app of [category], if it exists. Category can be for
+     * example [Intent.CATEGORY_APP_EMAIL] or [Intent.CATEGORY_APP_CALCULATOR].
+     */
+    suspend fun categoryAppIcon(category: String): Icon?
+}
+
+class AppCategoryIconProviderImpl
+@Inject
+constructor(
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
+    private val assistManager: AssistManager,
+    private val packageManager: PackageManager,
+    private val packageManagerWrapper: PackageManagerWrapper,
+) : AppCategoryIconProvider {
+
+    override suspend fun assistantAppIcon(): Icon? {
+        val assistInfo = assistManager.assistInfo ?: return null
+        return getPackageIcon(assistInfo.packageName)
+    }
+
+    override suspend fun categoryAppIcon(category: String): Icon? {
+        val intent = Intent(Intent.ACTION_MAIN).apply { addCategory(category) }
+        val packageInfo = getPackageInfo(intent) ?: return null
+        return getPackageIcon(packageInfo.packageName)
+    }
+
+    private suspend fun getPackageInfo(intent: Intent): PackageInfo? =
+        withContext(backgroundDispatcher) {
+            val packageName =
+                packageManagerWrapper
+                    .resolveActivity(/* intent= */ intent, /* flags= */ 0)
+                    ?.activityInfo
+                    ?.packageName ?: return@withContext null
+            return@withContext getPackageInfo(packageName)
+        }
+
+    private suspend fun getPackageIcon(packageName: String): Icon? {
+        val appInfo = getPackageInfo(packageName)?.applicationInfo ?: return null
+        return if (appInfo.icon != 0) {
+            Icon.createWithResource(appInfo.packageName, appInfo.icon)
+        } else {
+            null
+        }
+    }
+
+    private suspend fun getPackageInfo(packageName: String): PackageInfo? =
+        withContext(backgroundDispatcher) {
+            try {
+                return@withContext packageManager.getPackageInfo(packageName, /* flags= */ 0)
+            } catch (e: RemoteException) {
+                Log.e(TAG, "Failed to retrieve package info for $packageName")
+                return@withContext null
+            }
+        }
+
+    companion object {
+        private const val TAG = "DefaultAppsIconProvider"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt
index 8c46f9a..28ac2c0 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/JavaAdapter.kt
@@ -106,3 +106,13 @@
 ): Flow<R> {
     return combine(flow1, flow2, flow3, trifunction)
 }
+
+fun <T1, T2, T3, T4, R> combineFlows(
+    flow: Flow<T1>,
+    flow2: Flow<T2>,
+    flow3: Flow<T3>,
+    flow4: Flow<T4>,
+    transform: (T1, T2, T3, T4) -> R
+): Flow<R> {
+    return combine(flow, flow2, flow3, flow4, transform)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/SettingsSingleThreadBackground.java b/packages/SystemUI/src/com/android/systemui/util/kotlin/SettingsSingleThreadBackground.java
new file mode 100644
index 0000000..e13981d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/SettingsSingleThreadBackground.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.kotlin;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+/**
+ * This is a background executor/dispatcher which guarantees that **within that instance**,
+ * operations will execute in the same order as they were dispatched.
+ * This is useful for background operations like register/unregister where ordering is important.
+ */
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface SettingsSingleThreadBackground { }
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt
index d10554f..a03221e 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/SysUICoroutinesModule.kt
@@ -16,19 +16,24 @@
 
 package com.android.systemui.util.kotlin
 
+import android.os.Handler
 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.Tracing
+import com.android.systemui.dagger.qualifiers.UiBackground
 import dagger.Module
 import dagger.Provides
-import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.DelicateCoroutinesApi
 import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.android.asCoroutineDispatcher
+import kotlinx.coroutines.asCoroutineDispatcher
 import kotlinx.coroutines.newFixedThreadPoolContext
 import kotlinx.coroutines.plus
+import java.util.concurrent.Executor
+import kotlin.coroutines.CoroutineContext
 
 private const val LIMIT_BACKGROUND_DISPATCHER_THREADS = true
 
@@ -75,6 +80,14 @@
     }
 
     @Provides
+    @SysUISingleton
+    @SettingsSingleThreadBackground
+    fun settingsBgDispatcher(@Background bgHandler: Handler): CoroutineDispatcher {
+        // Handlers are guaranteed to be sequential so we use that one for now.
+        return bgHandler.asCoroutineDispatcher("SettingsBg")
+    }
+
+    @Provides
     @Background
     @SysUISingleton
     fun bgCoroutineContext(
@@ -83,4 +96,25 @@
     ): CoroutineContext {
         return bgCoroutineDispatcher + tracingCoroutineContext
     }
+
+    /** Coroutine dispatcher for background operations on for UI. */
+    @Provides
+    @SysUISingleton
+    @UiBackground
+    @Deprecated(
+        "Use @UiBackground CoroutineContext instead",
+        ReplaceWith("uiBgCoroutineContext()", "kotlin.coroutines.CoroutineContext")
+    )
+    fun uiBgDispatcher(@UiBackground uiBgExecutor: Executor): CoroutineDispatcher =
+        uiBgExecutor.asCoroutineDispatcher()
+
+    @Provides
+    @UiBackground
+    @SysUISingleton
+    fun uiBgCoroutineContext(
+        @Tracing tracingCoroutineContext: CoroutineContext,
+        @UiBackground uiBgCoroutineDispatcher: CoroutineDispatcher,
+    ): CoroutineContext {
+        return uiBgCoroutineDispatcher + tracingCoroutineContext
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/util/service/PersistentConnectionManager.java b/packages/SystemUI/src/com/android/systemui/util/service/PersistentConnectionManager.java
index 64f8246..a58a264 100644
--- a/packages/SystemUI/src/com/android/systemui/util/service/PersistentConnectionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/util/service/PersistentConnectionManager.java
@@ -27,6 +27,7 @@
 
 import androidx.annotation.NonNull;
 
+import com.android.app.tracing.TraceStateLogger;
 import com.android.systemui.Dumpable;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dump.DumpManager;
@@ -41,11 +42,11 @@
 /**
  * The {@link PersistentConnectionManager} is responsible for maintaining a connection to a
  * {@link ObservableServiceConnection}.
+ *
  * @param <T> The transformed connection type handled by the service.
  */
 public class PersistentConnectionManager<T> implements Dumpable {
     private static final String TAG = "PersistentConnManager";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private final SystemClock mSystemClock;
     private final DelayableExecutor mBgExecutor;
@@ -55,6 +56,7 @@
     private final Observer mObserver;
     private final DumpManager mDumpManager;
     private final String mDumpsysName;
+    private final TraceStateLogger mConnectionReasonLogger;
 
     private int mReconnectAttempts = 0;
     private Runnable mCurrentReconnectCancelable;
@@ -64,36 +66,52 @@
     private final Runnable mConnectRunnable = new Runnable() {
         @Override
         public void run() {
+            mConnectionReasonLogger.log("ConnectionReasonRetry");
             mCurrentReconnectCancelable = null;
             mConnection.bind();
         }
     };
 
-    private final Observer.Callback mObserverCallback = () -> initiateConnectionAttempt();
+    private final Observer.Callback mObserverCallback = () -> initiateConnectionAttempt(
+            "ConnectionReasonObserver");
 
     private final ObservableServiceConnection.Callback<T> mConnectionCallback =
             new ObservableServiceConnection.Callback<>() {
-        private long mStartTime;
+                private long mStartTime = -1;
 
-        @Override
-        public void onConnected(ObservableServiceConnection connection, Object proxy) {
-            mStartTime = mSystemClock.currentTimeMillis();
-        }
+                @Override
+                public void onConnected(ObservableServiceConnection connection, Object proxy) {
+                    mStartTime = mSystemClock.currentTimeMillis();
+                }
 
-        @Override
-        public void onDisconnected(ObservableServiceConnection connection, int reason) {
-            // Do not attempt to reconnect if we were manually unbound
-            if (reason == ObservableServiceConnection.DISCONNECT_REASON_UNBIND) {
-                return;
-            }
+                @Override
+                public void onDisconnected(ObservableServiceConnection connection, int reason) {
+                    // Do not attempt to reconnect if we were manually unbound
+                    if (reason == ObservableServiceConnection.DISCONNECT_REASON_UNBIND) {
+                        return;
+                    }
 
-            if (mSystemClock.currentTimeMillis() - mStartTime > mMinConnectionDuration) {
-                initiateConnectionAttempt();
-            } else {
-                scheduleConnectionAttempt();
-            }
-        }
-    };
+                    if (mStartTime <= 0) {
+                        Log.e(TAG, "onDisconnected called with invalid connection start time: "
+                                + mStartTime);
+                        return;
+                    }
+
+                    final float connectionDuration = mSystemClock.currentTimeMillis() - mStartTime;
+                    // Reset the start time.
+                    mStartTime = -1;
+
+                    if (connectionDuration > mMinConnectionDuration) {
+                        Log.i(TAG, "immediately reconnecting since service was connected for "
+                                + connectionDuration
+                                + "ms which is longer than the min duration of "
+                                + mMinConnectionDuration + "ms");
+                        initiateConnectionAttempt("ConnectionReasonMinDurationMet");
+                    } else {
+                        scheduleConnectionAttempt();
+                    }
+                }
+            };
 
     @Inject
     public PersistentConnectionManager(
@@ -112,6 +130,7 @@
         mObserver = observer;
         mDumpManager = dumpManager;
         mDumpsysName = TAG + "#" + dumpsysName;
+        mConnectionReasonLogger = new TraceStateLogger(mDumpsysName);
 
         mMaxReconnectAttempts = maxReconnectAttempts;
         mBaseReconnectDelayMs = baseReconnectDelayMs;
@@ -125,7 +144,7 @@
         mDumpManager.registerCriticalDumpable(mDumpsysName, this);
         mConnection.addCallback(mConnectionCallback);
         mObserver.addCallback(mObserverCallback);
-        initiateConnectionAttempt();
+        initiateConnectionAttempt("ConnectionReasonStart");
     }
 
     /**
@@ -140,6 +159,7 @@
 
     /**
      * Add a callback to the {@link ObservableServiceConnection}.
+     *
      * @param callback The callback to add.
      */
     public void addConnectionCallback(ObservableServiceConnection.Callback<T> callback) {
@@ -148,6 +168,7 @@
 
     /**
      * Remove a callback from the {@link ObservableServiceConnection}.
+     *
      * @param callback The callback to remove.
      */
     public void removeConnectionCallback(ObservableServiceConnection.Callback<T> callback) {
@@ -163,10 +184,10 @@
         mConnection.dump(pw);
     }
 
-    private void initiateConnectionAttempt() {
+    private void initiateConnectionAttempt(String reason) {
+        mConnectionReasonLogger.log(reason);
         // Reset attempts
         mReconnectAttempts = 0;
-
         // The first attempt is always a direct invocation rather than delayed.
         mConnection.bind();
     }
@@ -179,20 +200,15 @@
         }
 
         if (mReconnectAttempts >= mMaxReconnectAttempts) {
-            if (DEBUG) {
-                Log.d(TAG, "exceeded max connection attempts.");
-            }
+            Log.d(TAG, "exceeded max connection attempts.");
             return;
         }
 
         final long reconnectDelayMs =
                 (long) Math.scalb(mBaseReconnectDelayMs, mReconnectAttempts);
 
-        if (DEBUG) {
-            Log.d(TAG,
-                    "scheduling connection attempt in " + reconnectDelayMs + "milliseconds");
-        }
-
+        Log.d(TAG,
+                "scheduling connection attempt in " + reconnectDelayMs + "milliseconds");
         mCurrentReconnectCancelable = mBgExecutor.executeDelayed(mConnectRunnable,
                 reconnectDelayMs);
 
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java b/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java
index 42389f0..816f55d 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/GlobalSettingsImpl.java
@@ -23,16 +23,23 @@
 import android.net.Uri;
 import android.provider.Settings;
 
+import com.android.systemui.util.kotlin.SettingsSingleThreadBackground;
+
+import kotlinx.coroutines.CoroutineDispatcher;
+
 import javax.inject.Inject;
 
 // use UserHandle.USER_SYSTEM everywhere
 @SuppressLint("StaticSettingsProvider")
 class GlobalSettingsImpl implements GlobalSettings {
     private final ContentResolver mContentResolver;
+    private final CoroutineDispatcher mBgDispatcher;
 
     @Inject
-    GlobalSettingsImpl(ContentResolver contentResolver) {
+    GlobalSettingsImpl(ContentResolver contentResolver,
+            @SettingsSingleThreadBackground CoroutineDispatcher bgDispatcher) {
         mContentResolver = contentResolver;
+        mBgDispatcher = bgDispatcher;
     }
 
     @Override
@@ -46,6 +53,11 @@
     }
 
     @Override
+    public CoroutineDispatcher getBackgroundDispatcher() {
+        return mBgDispatcher;
+    }
+
+    @Override
     public String getString(String name) {
         return Settings.Global.getString(mContentResolver, name);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java b/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java
index 6532ce8..9c98f43 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/SecureSettingsImpl.java
@@ -23,17 +23,23 @@
 import androidx.annotation.NonNull;
 
 import com.android.systemui.settings.UserTracker;
+import com.android.systemui.util.kotlin.SettingsSingleThreadBackground;
 
 import javax.inject.Inject;
 
+import kotlinx.coroutines.CoroutineDispatcher;
+
 class SecureSettingsImpl implements SecureSettings {
     private final ContentResolver mContentResolver;
     private final UserTracker mUserTracker;
+    private final CoroutineDispatcher mBgDispatcher;
 
     @Inject
-    SecureSettingsImpl(ContentResolver contentResolver, UserTracker userTracker) {
+    SecureSettingsImpl(ContentResolver contentResolver, UserTracker userTracker,
+            @SettingsSingleThreadBackground CoroutineDispatcher bgDispatcher) {
         mContentResolver = contentResolver;
         mUserTracker = userTracker;
+        mBgDispatcher = bgDispatcher;
     }
 
     @Override
@@ -52,6 +58,11 @@
     }
 
     @Override
+    public CoroutineDispatcher getBackgroundDispatcher() {
+        return mBgDispatcher;
+    }
+
+    @Override
     public String getStringForUser(String name, int userHandle) {
         return Settings.Secure.getStringForUser(mContentResolver, name,
                 getRealUserHandle(userHandle));
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt b/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt
index d92127c..fe54044 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/SettingsProxy.kt
@@ -19,7 +19,12 @@
 import android.database.ContentObserver
 import android.net.Uri
 import android.provider.Settings.SettingNotFoundException
+import androidx.annotation.WorkerThread
 import com.android.app.tracing.TraceUtils.trace
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
 
 /**
  * Used to interact with mainly with Settings.Global, but can also be used for Settings.System and
@@ -40,6 +45,12 @@
     fun getContentResolver(): ContentResolver
 
     /**
+     * Returns the background [CoroutineDispatcher] that the async APIs will use for a specific
+     * implementation.
+     */
+    val backgroundDispatcher: CoroutineDispatcher
+
+    /**
      * Construct the content URI for a particular name/value pair, useful for monitoring changes
      * with a ContentObserver.
      *
@@ -49,21 +60,74 @@
     fun getUriFor(name: String): Uri
 
     /**
-     * Convenience wrapper around [ContentResolver.registerContentObserver].'
-     *
+     * Registers listener for a given content observer <b>while blocking the current thread</b>.
      * Implicitly calls [getUriFor] on the passed in name.
+     *
+     * This should not be called from the main thread, use [registerContentObserver] or
+     * [registerContentObserverAsync] instead.
      */
+    @WorkerThread
     fun registerContentObserverSync(name: String, settingsObserver: ContentObserver) {
         registerContentObserverSync(getUriFor(name), settingsObserver)
     }
 
-    /** Convenience wrapper around [ContentResolver.registerContentObserver].' */
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
+     * registration happens on a worker thread. Caller may wrap the API in an async block if they
+     * wish to synchronize execution.
+     */
+    suspend fun registerContentObserver(name: String, settingsObserver: ContentObserver) {
+        withContext(backgroundDispatcher) {
+            registerContentObserverSync(getUriFor(name), settingsObserver)
+        }
+    }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * API corresponding to [registerContentObserver] for Java usage.
+     */
+    fun registerContentObserverAsync(name: String, settingsObserver: ContentObserver) =
+        CoroutineScope(backgroundDispatcher).launch {
+            registerContentObserverSync(getUriFor(name), settingsObserver)
+        }
+
+    /**
+     * Registers listener for a given content observer <b>while blocking the current thread</b>.
+     *
+     * This should not be called from the main thread, use [registerContentObserver] or
+     * [registerContentObserverAsync] instead.
+     */
+    @WorkerThread
     fun registerContentObserverSync(uri: Uri, settingsObserver: ContentObserver) =
         registerContentObserverSync(uri, false, settingsObserver)
 
     /**
      * Convenience wrapper around [ContentResolver.registerContentObserver].'
      *
+     * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
+     * registration happens on a worker thread. Caller may wrap the API in an async block if they
+     * wish to synchronize execution.
+     */
+    suspend fun registerContentObserver(uri: Uri, settingsObserver: ContentObserver) {
+        withContext(backgroundDispatcher) { registerContentObserverSync(uri, settingsObserver) }
+    }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * API corresponding to [registerContentObserver] for Java usage.
+     */
+    fun registerContentObserverAsync(uri: Uri, settingsObserver: ContentObserver) =
+        CoroutineScope(backgroundDispatcher).launch {
+            registerContentObserverSync(uri, settingsObserver)
+        }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
      * Implicitly calls [getUriFor] on the passed in name.
      */
     fun registerContentObserverSync(
@@ -72,7 +136,44 @@
         settingsObserver: ContentObserver
     ) = registerContentObserverSync(getUriFor(name), notifyForDescendants, settingsObserver)
 
-    /** Convenience wrapper around [ContentResolver.registerContentObserver].' */
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
+     * registration happens on a worker thread. Caller may wrap the API in an async block if they
+     * wish to synchronize execution.
+     */
+    suspend fun registerContentObserver(
+        name: String,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver
+    ) {
+        withContext(backgroundDispatcher) {
+            registerContentObserverSync(getUriFor(name), notifyForDescendants, settingsObserver)
+        }
+    }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * API corresponding to [registerContentObserver] for Java usage.
+     */
+    fun registerContentObserverAsync(
+        name: String,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver
+    ) =
+        CoroutineScope(backgroundDispatcher).launch {
+            registerContentObserverSync(getUriFor(name), notifyForDescendants, settingsObserver)
+        }
+
+    /**
+     * Registers listener for a given content observer <b>while blocking the current thread</b>.
+     *
+     * This should not be called from the main thread, use [registerContentObserver] or
+     * [registerContentObserverAsync] instead.
+     */
+    @WorkerThread
     fun registerContentObserverSync(
         uri: Uri,
         notifyForDescendants: Boolean,
@@ -84,7 +185,44 @@
         }
     }
 
-    /** See [ContentResolver.unregisterContentObserver]. */
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * suspend API corresponding to [registerContentObserver] to ensure that [ContentObserver]
+     * registration happens on a worker thread. Caller may wrap the API in an async block if they
+     * wish to synchronize execution.
+     */
+    suspend fun registerContentObserver(
+        uri: Uri,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver
+    ) {
+        withContext(backgroundDispatcher) {
+            registerContentObserverSync(uri, notifyForDescendants, settingsObserver)
+        }
+    }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * API corresponding to [registerContentObserver] for Java usage.
+     */
+    fun registerContentObserverAsync(
+        uri: Uri,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver
+    ) =
+        CoroutineScope(backgroundDispatcher).launch {
+            registerContentObserverSync(uri, notifyForDescendants, settingsObserver)
+        }
+
+    /**
+     * Unregisters the given content observer <b>while blocking the current thread</b>.
+     *
+     * This should not be called from the main thread, use [unregisterContentObserver] or
+     * [unregisterContentObserverAsync] instead.
+     */
+    @WorkerThread
     fun unregisterContentObserverSync(settingsObserver: ContentObserver) {
         trace({ "SP#unregisterObserver" }) {
             getContentResolver().unregisterContentObserver(settingsObserver)
@@ -92,6 +230,26 @@
     }
 
     /**
+     * Convenience wrapper around [ContentResolver.unregisterContentObserver].'
+     *
+     * API corresponding to [unregisterContentObserver] for Java usage to ensure that
+     * [ContentObserver] un-registration happens on a worker thread. Caller may wrap the API in an
+     * async block if they wish to synchronize execution.
+     */
+    suspend fun unregisterContentObserver(settingsObserver: ContentObserver) {
+        withContext(backgroundDispatcher) { unregisterContentObserverSync(settingsObserver) }
+    }
+
+    /**
+     * Convenience wrapper around [ContentResolver.unregisterContentObserver].'
+     *
+     * API corresponding to [unregisterContentObserver] for Java usage to ensure that
+     * [ContentObserver] registration happens on a worker thread.
+     */
+    fun unregisterContentObserverAsync(settingsObserver: ContentObserver) =
+        CoroutineScope(backgroundDispatcher).launch { unregisterContentObserver(settingsObserver) }
+
+    /**
      * Look up a name in the database.
      *
      * @param name to look up in the table
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java b/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java
index 658b299..406d95b 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/SystemSettingsImpl.java
@@ -23,17 +23,23 @@
 import androidx.annotation.NonNull;
 
 import com.android.systemui.settings.UserTracker;
+import com.android.systemui.util.kotlin.SettingsSingleThreadBackground;
 
 import javax.inject.Inject;
 
+import kotlinx.coroutines.CoroutineDispatcher;
+
 class SystemSettingsImpl implements SystemSettings {
     private final ContentResolver mContentResolver;
     private final UserTracker mUserTracker;
+    private final CoroutineDispatcher mBgCoroutineDispatcher;
 
     @Inject
-    SystemSettingsImpl(ContentResolver contentResolver, UserTracker userTracker) {
+    SystemSettingsImpl(ContentResolver contentResolver, UserTracker userTracker,
+            @SettingsSingleThreadBackground CoroutineDispatcher bgDispatcher) {
         mContentResolver = contentResolver;
         mUserTracker = userTracker;
+        mBgCoroutineDispatcher = bgDispatcher;
     }
 
     @Override
@@ -52,6 +58,11 @@
     }
 
     @Override
+    public CoroutineDispatcher getBackgroundDispatcher() {
+        return mBgCoroutineDispatcher;
+    }
+
+    @Override
     public String getStringForUser(String name, int userHandle) {
         return Settings.System.getStringForUser(mContentResolver, name,
                 getRealUserHandle(userHandle));
diff --git a/packages/SystemUI/src/com/android/systemui/util/settings/UserSettingsProxy.kt b/packages/SystemUI/src/com/android/systemui/util/settings/UserSettingsProxy.kt
index ed65f1a..3bf5b65 100644
--- a/packages/SystemUI/src/com/android/systemui/util/settings/UserSettingsProxy.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/settings/UserSettingsProxy.kt
@@ -16,6 +16,7 @@
 package com.android.systemui.util.settings
 
 import android.annotation.UserIdInt
+import android.content.ContentResolver
 import android.database.ContentObserver
 import android.net.Uri
 import android.os.UserHandle
@@ -26,6 +27,9 @@
 import com.android.systemui.util.settings.SettingsProxy.Companion.parseFloatOrThrow
 import com.android.systemui.util.settings.SettingsProxy.Companion.parseLongOrThrow
 import com.android.systemui.util.settings.SettingsProxy.Companion.parseLongOrUseDefault
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
 
 /**
  * Used to interact with per-user Settings.Secure and Settings.System settings (but not
@@ -66,6 +70,17 @@
         registerContentObserverForUserSync(uri, settingsObserver, userId)
     }
 
+    override suspend fun registerContentObserver(uri: Uri, settingsObserver: ContentObserver) {
+        withContext(backgroundDispatcher) {
+            registerContentObserverForUserSync(uri, settingsObserver, userId)
+        }
+    }
+
+    override fun registerContentObserverAsync(uri: Uri, settingsObserver: ContentObserver) =
+        CoroutineScope(backgroundDispatcher).launch {
+            registerContentObserverForUserSync(uri, settingsObserver, userId)
+        }
+
     /** Convenience wrapper around [ContentResolver.registerContentObserver].' */
     override fun registerContentObserverSync(
         uri: Uri,
@@ -75,6 +90,30 @@
         registerContentObserverForUserSync(uri, notifyForDescendants, settingsObserver, userId)
     }
 
+    override suspend fun registerContentObserver(
+        uri: Uri,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver
+    ) {
+        withContext(backgroundDispatcher) {
+            registerContentObserverForUserSync(uri, notifyForDescendants, settingsObserver, userId)
+        }
+    }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * API corresponding to [registerContentObserverForUser] for Java usage.
+     */
+    override fun registerContentObserverAsync(
+        uri: Uri,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver
+    ) =
+        CoroutineScope(backgroundDispatcher).launch {
+            registerContentObserverForUserSync(uri, notifyForDescendants, settingsObserver, userId)
+        }
+
     /**
      * Convenience wrapper around [ContentResolver.registerContentObserver]
      *
@@ -88,6 +127,37 @@
         registerContentObserverForUserSync(getUriFor(name), settingsObserver, userHandle)
     }
 
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * suspend API corresponding to [registerContentObserverForUser] to ensure that
+     * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
+     * async block if they wish to synchronize execution.
+     */
+    suspend fun registerContentObserverForUser(
+        name: String,
+        settingsObserver: ContentObserver,
+        userHandle: Int
+    ) {
+        withContext(backgroundDispatcher) {
+            registerContentObserverForUserSync(name, settingsObserver, userHandle)
+        }
+    }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * API corresponding to [registerContentObserverForUser] for Java usage.
+     */
+    fun registerContentObserverForUserAsync(
+        name: String,
+        settingsObserver: ContentObserver,
+        userHandle: Int
+    ) =
+        CoroutineScope(backgroundDispatcher).launch {
+            registerContentObserverForUserSync(getUriFor(name), settingsObserver, userHandle)
+        }
+
     /** Convenience wrapper around [ContentResolver.registerContentObserver] */
     fun registerContentObserverForUserSync(
         uri: Uri,
@@ -98,6 +168,37 @@
     }
 
     /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * suspend API corresponding to [registerContentObserverForUser] to ensure that
+     * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
+     * async block if they wish to synchronize execution.
+     */
+    suspend fun registerContentObserverForUser(
+        uri: Uri,
+        settingsObserver: ContentObserver,
+        userHandle: Int
+    ) {
+        withContext(backgroundDispatcher) {
+            registerContentObserverForUserSync(uri, settingsObserver, userHandle)
+        }
+    }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * API corresponding to [registerContentObserverForUser] for Java usage.
+     */
+    fun registerContentObserverForUserAsync(
+        uri: Uri,
+        settingsObserver: ContentObserver,
+        userHandle: Int
+    ) =
+        CoroutineScope(backgroundDispatcher).launch {
+            registerContentObserverForUserSync(uri, settingsObserver, userHandle)
+        }
+
+    /**
      * Convenience wrapper around [ContentResolver.registerContentObserver]
      *
      * Implicitly calls [getUriFor] on the passed in name.
@@ -116,6 +217,50 @@
         )
     }
 
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * suspend API corresponding to [registerContentObserverForUser] to ensure that
+     * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
+     * async block if they wish to synchronize execution.
+     */
+    suspend fun registerContentObserverForUser(
+        name: String,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver,
+        userHandle: Int
+    ) {
+        withContext(backgroundDispatcher) {
+            registerContentObserverForUserSync(
+                name,
+                notifyForDescendants,
+                settingsObserver,
+                userHandle
+            )
+        }
+    }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * API corresponding to [registerContentObserverForUser] for Java usage.
+     */
+    fun registerContentObserverForUserAsync(
+        name: String,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver,
+        userHandle: Int
+    ) {
+        CoroutineScope(backgroundDispatcher).launch {
+            registerContentObserverForUserSync(
+                getUriFor(name),
+                notifyForDescendants,
+                settingsObserver,
+                userHandle
+            )
+        }
+    }
+
     /** Convenience wrapper around [ContentResolver.registerContentObserver] */
     fun registerContentObserverForUserSync(
         uri: Uri,
@@ -136,6 +281,49 @@
     }
 
     /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * suspend API corresponding to [registerContentObserverForUser] to ensure that
+     * [ContentObserver] registration happens on a worker thread. Caller may wrap the API in an
+     * async block if they wish to synchronize execution.
+     */
+    suspend fun registerContentObserverForUser(
+        uri: Uri,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver,
+        userHandle: Int
+    ) {
+        withContext(backgroundDispatcher) {
+            registerContentObserverForUserSync(
+                uri,
+                notifyForDescendants,
+                settingsObserver,
+                getRealUserHandle(userHandle)
+            )
+        }
+    }
+
+    /**
+     * Convenience wrapper around [ContentResolver.registerContentObserver].'
+     *
+     * API corresponding to [registerContentObserverForUser] for Java usage.
+     */
+    fun registerContentObserverForUserAsync(
+        uri: Uri,
+        notifyForDescendants: Boolean,
+        settingsObserver: ContentObserver,
+        userHandle: Int
+    ) =
+        CoroutineScope(backgroundDispatcher).launch {
+            registerContentObserverForUserSync(
+                uri,
+                notifyForDescendants,
+                settingsObserver,
+                userHandle
+            )
+        }
+
+    /**
      * Look up a name in the database.
      *
      * @param name to look up in the table
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeControllerCollector.kt b/packages/SystemUI/src/com/android/systemui/volume/VolumeControllerCollector.kt
new file mode 100644
index 0000000..6859191
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeControllerCollector.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.volume
+
+import android.media.IVolumeController
+import com.android.settingslib.media.data.repository.VolumeControllerEvent
+import com.android.systemui.dagger.qualifiers.Application
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.launch
+
+/**
+ * This class is a bridge between
+ * [com.android.settingslib.volume.data.repository.AudioRepository.volumeControllerEvents] and the
+ * old code that uses [IVolumeController] interface directly.
+ */
+class VolumeControllerCollector
+@Inject
+constructor(@Application private val coroutineScope: CoroutineScope) {
+
+    /** Collects [Flow] of [VolumeControllerEvent] into [IVolumeController]. */
+    fun collectToController(
+        eventsFlow: Flow<VolumeControllerEvent>,
+        controller: IVolumeController
+    ) =
+        coroutineScope.launch {
+            eventsFlow.collect { event ->
+                when (event) {
+                    is VolumeControllerEvent.VolumeChanged ->
+                        controller.volumeChanged(event.streamType, event.flags)
+                    VolumeControllerEvent.Dismiss -> controller.dismiss()
+                    is VolumeControllerEvent.DisplayCsdWarning ->
+                        controller.displayCsdWarning(event.csdWarning, event.displayDurationMs)
+                    is VolumeControllerEvent.DisplaySafeVolumeWarning ->
+                        controller.displaySafeVolumeWarning(event.flags)
+                    is VolumeControllerEvent.MasterMuteChanged ->
+                        controller.masterMuteChanged(event.flags)
+                    is VolumeControllerEvent.SetA11yMode -> controller.setA11yMode(event.mode)
+                    is VolumeControllerEvent.SetLayoutDirection ->
+                        controller.setLayoutDirection(event.layoutDirection)
+                }
+            }
+        }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index aee441a..c45f98e 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -567,7 +567,7 @@
             streamStateW(stream).levelMax = Math.max(1, getAudioManagerStreamMaxVolume(stream));
             updateStreamMuteW(stream, mAudio.isStreamMute(stream));
             final StreamState ss = streamStateW(stream);
-            ss.muteSupported = mAudio.isStreamAffectedByMute(stream);
+            ss.muteSupported = mAudio.isStreamMutableByUi(stream);
             ss.name = STREAMS.get(stream);
             checkRoutedToBluetoothW(stream);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt b/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt
index 1ae5614..de8b9b1 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/AudioModule.kt
@@ -20,7 +20,7 @@
 import android.content.Context
 import android.media.AudioManager
 import com.android.settingslib.bluetooth.LocalBluetoothManager
-import com.android.settingslib.statusbar.notification.domain.interactor.NotificationsSoundPolicyInteractor
+import com.android.settingslib.notification.domain.interactor.NotificationsSoundPolicyInteractor
 import com.android.settingslib.volume.data.repository.AudioRepository
 import com.android.settingslib.volume.data.repository.AudioRepositoryImpl
 import com.android.settingslib.volume.data.repository.AudioSharingRepository
@@ -32,6 +32,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.volume.shared.VolumeLogger
 import dagger.Module
 import dagger.Provides
 import kotlin.coroutines.CoroutineContext
@@ -58,6 +59,7 @@
             contentResolver: ContentResolver,
             @Background coroutineContext: CoroutineContext,
             @Application coroutineScope: CoroutineScope,
+            volumeLogger: VolumeLogger,
         ): AudioRepository =
             AudioRepositoryImpl(
                 intentsReceiver,
@@ -65,6 +67,7 @@
                 contentResolver,
                 coroutineContext,
                 coroutineScope,
+                volumeLogger,
             )
 
         @Provides
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractor.kt
index 7f1faee..cfcd6b1 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractor.kt
@@ -16,15 +16,23 @@
 
 package com.android.systemui.volume.panel.component.spatial.domain.interactor
 
+import android.bluetooth.BluetoothProfile
 import android.media.AudioDeviceAttributes
 import android.media.AudioDeviceInfo
+import android.media.AudioManager
+import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.settingslib.bluetooth.LocalBluetoothProfile
+import com.android.settingslib.flags.Flags
 import com.android.settingslib.media.domain.interactor.SpatializerInteractor
+import com.android.settingslib.volume.data.repository.AudioRepository
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.volume.domain.interactor.AudioOutputInteractor
 import com.android.systemui.volume.domain.model.AudioOutputDevice
 import com.android.systemui.volume.panel.component.spatial.domain.model.SpatialAudioAvailabilityModel
 import com.android.systemui.volume.panel.component.spatial.domain.model.SpatialAudioEnabledModel
 import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope
 import javax.inject.Inject
+import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.SharingStarted
@@ -33,6 +41,7 @@
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.withContext
 
 /**
  * Provides an ability to access and update spatial audio and head tracking state.
@@ -46,6 +55,8 @@
 constructor(
     audioOutputInteractor: AudioOutputInteractor,
     private val spatializerInteractor: SpatializerInteractor,
+    private val audioRepository: AudioRepository,
+    @Background private val backgroundCoroutineContext: CoroutineContext,
     @VolumePanelScope private val coroutineScope: CoroutineScope,
 ) {
 
@@ -138,42 +149,85 @@
     }
 
     private suspend fun AudioOutputDevice.getAudioDeviceAttributes(): AudioDeviceAttributes? {
-        when (this) {
-            is AudioOutputDevice.BuiltIn -> return builtinSpeaker
+        return when (this) {
+            is AudioOutputDevice.BuiltIn -> builtinSpeaker
             is AudioOutputDevice.Bluetooth -> {
-                return listOf(
-                        AudioDeviceAttributes(
-                            AudioDeviceAttributes.ROLE_OUTPUT,
-                            AudioDeviceInfo.TYPE_BLE_HEADSET,
-                            cachedBluetoothDevice.address,
-                        ),
-                        AudioDeviceAttributes(
-                            AudioDeviceAttributes.ROLE_OUTPUT,
-                            AudioDeviceInfo.TYPE_BLE_SPEAKER,
-                            cachedBluetoothDevice.address,
-                        ),
-                        AudioDeviceAttributes(
-                            AudioDeviceAttributes.ROLE_OUTPUT,
-                            AudioDeviceInfo.TYPE_BLE_BROADCAST,
-                            cachedBluetoothDevice.address,
-                        ),
-                        AudioDeviceAttributes(
-                            AudioDeviceAttributes.ROLE_OUTPUT,
-                            AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
-                            cachedBluetoothDevice.address,
-                        ),
-                        AudioDeviceAttributes(
-                            AudioDeviceAttributes.ROLE_OUTPUT,
-                            AudioDeviceInfo.TYPE_HEARING_AID,
-                            cachedBluetoothDevice.address,
+                if (Flags.enableDeterminingSpatialAudioAttributesByProfile()) {
+                    getAudioDeviceAttributesByBluetoothProfile(cachedBluetoothDevice)
+                } else {
+                    listOf(
+                            AudioDeviceAttributes(
+                                AudioDeviceAttributes.ROLE_OUTPUT,
+                                AudioDeviceInfo.TYPE_BLE_HEADSET,
+                                cachedBluetoothDevice.address,
+                            ),
+                            AudioDeviceAttributes(
+                                AudioDeviceAttributes.ROLE_OUTPUT,
+                                AudioDeviceInfo.TYPE_BLE_SPEAKER,
+                                cachedBluetoothDevice.address,
+                            ),
+                            AudioDeviceAttributes(
+                                AudioDeviceAttributes.ROLE_OUTPUT,
+                                AudioDeviceInfo.TYPE_BLE_BROADCAST,
+                                cachedBluetoothDevice.address,
+                            ),
+                            AudioDeviceAttributes(
+                                AudioDeviceAttributes.ROLE_OUTPUT,
+                                AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
+                                cachedBluetoothDevice.address,
+                            ),
+                            AudioDeviceAttributes(
+                                AudioDeviceAttributes.ROLE_OUTPUT,
+                                AudioDeviceInfo.TYPE_HEARING_AID,
+                                cachedBluetoothDevice.address,
+                            )
                         )
-                    )
-                    .firstOrNull { spatializerInteractor.isSpatialAudioAvailable(it) }
+                        .firstOrNull { spatializerInteractor.isSpatialAudioAvailable(it) }
+                }
             }
-            else -> return null
+            else -> null
         }
     }
 
+    private suspend fun getAudioDeviceAttributesByBluetoothProfile(
+        cachedBluetoothDevice: CachedBluetoothDevice
+    ): AudioDeviceAttributes? =
+        withContext(backgroundCoroutineContext) {
+            cachedBluetoothDevice.profiles
+                .firstOrNull {
+                    it.profileId in audioProfiles && it.isEnabled(cachedBluetoothDevice.device)
+                }
+                ?.let { profile: LocalBluetoothProfile ->
+                    when (profile.profileId) {
+                        BluetoothProfile.A2DP -> {
+                            AudioDeviceInfo.TYPE_BLUETOOTH_A2DP
+                        }
+                        BluetoothProfile.LE_AUDIO -> {
+                            when (
+                                audioRepository.getBluetoothAudioDeviceCategory(
+                                    cachedBluetoothDevice.address
+                                )
+                            ) {
+                                AudioManager.AUDIO_DEVICE_CATEGORY_SPEAKER ->
+                                    AudioDeviceInfo.TYPE_BLE_SPEAKER
+                                else -> AudioDeviceInfo.TYPE_BLE_HEADSET
+                            }
+                        }
+                        BluetoothProfile.HEARING_AID -> {
+                            AudioDeviceInfo.TYPE_HEARING_AID
+                        }
+                        else -> null
+                    }
+                }
+                ?.let {
+                    AudioDeviceAttributes(
+                        AudioDeviceAttributes.ROLE_OUTPUT,
+                        it,
+                        cachedBluetoothDevice.address,
+                    )
+                }
+        }
+
     private companion object {
         val builtinSpeaker =
             AudioDeviceAttributes(
@@ -181,5 +235,7 @@
                 AudioDeviceInfo.TYPE_BUILTIN_SPEAKER,
                 ""
             )
+        val audioProfiles =
+            setOf(BluetoothProfile.A2DP, BluetoothProfile.LE_AUDIO, BluetoothProfile.HEARING_AID)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt
index c18573e..521f608 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt
@@ -26,6 +26,7 @@
 import com.android.settingslib.volume.shared.model.RingerMode
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.res.R
+import com.android.systemui.volume.panel.shared.VolumePanelLogger
 import com.android.systemui.volume.panel.ui.VolumePanelUiEvent
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
@@ -51,6 +52,7 @@
     private val context: Context,
     private val audioVolumeInteractor: AudioVolumeInteractor,
     private val uiEventLogger: UiEventLogger,
+    private val volumePanelLogger: VolumePanelLogger,
 ) : SliderViewModel {
 
     private val volumeChanges = MutableStateFlow<Int?>(null)
@@ -105,6 +107,7 @@
                 audioVolumeInteractor.canChangeVolume(audioStream),
                 audioVolumeInteractor.ringerMode,
             ) { model, isEnabled, ringerMode ->
+                volumePanelLogger.onVolumeUpdateReceived(audioStream, model.volume)
                 model.toState(isEnabled, ringerMode)
             }
             .stateIn(coroutineScope, SharingStarted.Eagerly, SliderState.Empty)
@@ -112,7 +115,10 @@
     init {
         volumeChanges
             .filterNotNull()
-            .onEach { audioVolumeInteractor.setVolume(audioStream, it) }
+            .onEach {
+                volumePanelLogger.onSetVolumeRequested(audioStream, it)
+                audioVolumeInteractor.setVolume(audioStream, it)
+            }
             .launchIn(coroutineScope)
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/shared/VolumePanelLogger.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/shared/VolumePanelLogger.kt
new file mode 100644
index 0000000..cc513b5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/shared/VolumePanelLogger.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.volume.panel.shared
+
+import com.android.settingslib.volume.shared.model.AudioStream
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.log.dagger.VolumeLog
+import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope
+import javax.inject.Inject
+
+private const val TAG = "SysUI_VolumePanel"
+
+/** Logs events related to the Volume Panel. */
+@VolumePanelScope
+class VolumePanelLogger @Inject constructor(@VolumeLog private val logBuffer: LogBuffer) {
+
+    fun onSetVolumeRequested(audioStream: AudioStream, volume: Int) {
+        logBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = audioStream.toString()
+                int1 = volume
+            },
+            { "Set volume: stream=$str1 volume=$int1" }
+        )
+    }
+
+    fun onVolumeUpdateReceived(audioStream: AudioStream, volume: Int) {
+        logBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = audioStream.toString()
+                int1 = volume
+            },
+            { "Volume update received: stream=$str1 volume=$int1" }
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/shared/VolumeLogger.kt b/packages/SystemUI/src/com/android/systemui/volume/shared/VolumeLogger.kt
new file mode 100644
index 0000000..869a82a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/shared/VolumeLogger.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.volume.shared
+
+import com.android.settingslib.volume.data.repository.AudioRepositoryImpl
+import com.android.settingslib.volume.shared.model.AudioStream
+import com.android.settingslib.volume.shared.model.AudioStreamModel
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.core.LogLevel
+import com.android.systemui.log.dagger.VolumeLog
+import javax.inject.Inject
+
+private const val TAG = "SysUI_Volume"
+
+/** Logs general System UI volume events. */
+@SysUISingleton
+class VolumeLogger @Inject constructor(@VolumeLog private val logBuffer: LogBuffer) :
+    AudioRepositoryImpl.Logger {
+
+    override fun onSetVolumeRequested(audioStream: AudioStream, volume: Int) {
+        logBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = audioStream.toString()
+                int1 = volume
+            },
+            { "Set volume: stream=$str1 volume=$int1" }
+        )
+    }
+
+    override fun onVolumeUpdateReceived(audioStream: AudioStream, model: AudioStreamModel) {
+        logBuffer.log(
+            TAG,
+            LogLevel.DEBUG,
+            {
+                str1 = audioStream.toString()
+                int1 = model.volume
+            },
+            { "Volume update received: stream=$str1 volume=$int1" }
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
index cb61534..45799b2 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
@@ -51,7 +51,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.flags.FeatureFlags;
@@ -261,7 +261,7 @@
         // Store callback in a field so it won't get GC'd
         mStatusBarWindowCallback =
                 (keyguardShowing, keyguardOccluded, keyguardGoingAway, bouncerShowing, isDozing,
-                        panelExpanded, isDreaming) -> {
+                        panelExpanded, isDreaming, communalShowing) -> {
                     if (panelExpanded != mPanelExpanded) {
                         mPanelExpanded = panelExpanded;
                         mBubbles.onNotificationPanelExpandedChanged(panelExpanded);
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index ec9b5cf..3f1ec85 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -20,8 +20,9 @@
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DIALOG_SHOWING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ONE_HANDED_ACTIVE;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
@@ -66,6 +67,7 @@
 import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
 import com.android.wm.shell.onehanded.OneHandedUiEventLogger;
 import com.android.wm.shell.pip.Pip;
+import com.android.wm.shell.pip.PipTransitionController;
 import com.android.wm.shell.recents.RecentTasks;
 import com.android.wm.shell.splitscreen.SplitScreen;
 import com.android.wm.shell.sysui.ShellInterface;
@@ -249,7 +251,25 @@
                 pip.showPictureInPictureMenu();
             }
         });
+        pip.registerPipTransitionCallback(
+                new PipTransitionController.PipTransitionCallback() {
+                    @Override
+                    public void onPipTransitionStarted(int direction, Rect pipBounds) {
+                        mSysUiState.setFlag(SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING, true)
+                                .commitUpdate(mDisplayTracker.getDefaultDisplayId());
+                    }
 
+                    @Override
+                    public void onPipTransitionFinished(int direction) {
+                        mSysUiState.setFlag(SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING, false)
+                                .commitUpdate(mDisplayTracker.getDefaultDisplayId());
+                    }
+
+                    @Override
+                    public void onPipTransitionCanceled(int direction) {
+                        // No op.
+                    }
+                }, mSysUiMainExecutor);
         mSysUiState.addCallback(sysUiStateFlag -> {
             mIsSysUiStateValid = (sysUiStateFlag & INVALID_SYSUI_STATE_MASK) == 0;
             pip.onSystemUiStateChanged(mIsSysUiStateValid, sysUiStateFlag);
diff --git a/packages/SystemUI/tests/src/android/animation/AnimatorTestRuleIsolationTest.kt b/packages/SystemUI/tests/src/android/animation/AnimatorTestRuleIsolationTest.kt
deleted file mode 100644
index f23fbee..0000000
--- a/packages/SystemUI/tests/src/android/animation/AnimatorTestRuleIsolationTest.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.animation
-
-import android.testing.AndroidTestingRunner
-import android.testing.TestableLooper.RunWithLooper
-import androidx.core.animation.doOnEnd
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.google.common.truth.Truth.assertThat
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-
-/**
- * This test class validates that two tests' animators are isolated from each other when using the
- * same animator test rule. This is a test to prevent future instances of b/275602127.
- */
-@RunWith(AndroidTestingRunner::class)
-@SmallTest
-@RunWithLooper
-class AnimatorTestRuleIsolationTest : SysuiTestCase() {
-
-    @get:Rule val animatorTestRule = AnimatorTestRule(this)
-
-    @Test
-    fun testA() {
-        // GIVEN global state is reset at the start of the test
-        didTouchA = false
-        didTouchB = false
-        // WHEN starting 2 animations of different durations, and setting didTouchA at the end
-        ObjectAnimator.ofFloat(0f, 1f).apply {
-            duration = 100
-            doOnEnd { didTouchA = true }
-            start()
-        }
-        ObjectAnimator.ofFloat(0f, 1f).apply {
-            duration = 150
-            doOnEnd { didTouchA = true }
-            start()
-        }
-        // WHEN when you advance time so that only one of the animations has ended
-        animatorTestRule.advanceTimeBy(100)
-        // VERIFY we did indeed end the current animation
-        assertThat(didTouchA).isTrue()
-        // VERIFY advancing the animator did NOT cause testB's animator to end
-        assertThat(didTouchB).isFalse()
-    }
-
-    @Test
-    fun testB() {
-        // GIVEN global state is reset at the start of the test
-        didTouchA = false
-        didTouchB = false
-        // WHEN starting 2 animations of different durations, and setting didTouchB at the end
-        ObjectAnimator.ofFloat(0f, 1f).apply {
-            duration = 100
-            doOnEnd { didTouchB = true }
-            start()
-        }
-        ObjectAnimator.ofFloat(0f, 1f).apply {
-            duration = 150
-            doOnEnd { didTouchB = true }
-            start()
-        }
-        animatorTestRule.advanceTimeBy(100)
-        // VERIFY advancing the animator did NOT cause testA's animator to end
-        assertThat(didTouchA).isFalse()
-        // VERIFY we did indeed end the current animation
-        assertThat(didTouchB).isTrue()
-    }
-
-    companion object {
-        var didTouchA = false
-        var didTouchB = false
-    }
-}
diff --git a/packages/SystemUI/tests/src/android/animation/AnimatorTestRulePrecisionTest.kt b/packages/SystemUI/tests/src/android/animation/AnimatorTestRulePrecisionTest.kt
deleted file mode 100644
index fd5f157..0000000
--- a/packages/SystemUI/tests/src/android/animation/AnimatorTestRulePrecisionTest.kt
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.animation
-
-import android.testing.AndroidTestingRunner
-import android.testing.TestableLooper.RunWithLooper
-import androidx.core.animation.doOnEnd
-import androidx.test.filters.SmallTest
-import com.android.app.animation.Interpolators
-import com.android.systemui.SysuiTestCase
-import com.google.common.truth.Truth.assertThat
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@RunWith(AndroidTestingRunner::class)
-@SmallTest
-@RunWithLooper
-class AnimatorTestRulePrecisionTest : SysuiTestCase() {
-
-    @get:Rule val animatorTestRule = AnimatorTestRule(this)
-
-    var value1: Float = -1f
-    var value2: Float = -1f
-
-    private inline fun animateThis(
-        propertyName: String,
-        duration: Long,
-        startDelay: Long = 0,
-        crossinline onEndAction: (animator: Animator) -> Unit,
-    ) {
-        ObjectAnimator.ofFloat(this, propertyName, 0f, 1f).also {
-            it.interpolator = Interpolators.LINEAR
-            it.duration = duration
-            it.startDelay = startDelay
-            it.doOnEnd(onEndAction)
-            it.start()
-        }
-    }
-
-    @Test
-    fun testSingleAnimator() {
-        var ended = false
-        animateThis("value1", duration = 100) { ended = true }
-
-        assertThat(value1).isEqualTo(0f)
-        assertThat(ended).isFalse()
-        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
-
-        animatorTestRule.advanceTimeBy(50)
-        assertThat(value1).isEqualTo(0.5f)
-        assertThat(ended).isFalse()
-        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
-
-        animatorTestRule.advanceTimeBy(49)
-        assertThat(value1).isEqualTo(0.99f)
-        assertThat(ended).isFalse()
-        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
-
-        animatorTestRule.advanceTimeBy(1)
-        assertThat(value1).isEqualTo(1f)
-        assertThat(ended).isTrue()
-        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(0)
-    }
-
-    @Test
-    fun testDelayedAnimator() {
-        var ended = false
-        animateThis("value1", duration = 100, startDelay = 50) { ended = true }
-
-        assertThat(value1).isEqualTo(-1f)
-        assertThat(ended).isFalse()
-        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
-
-        animatorTestRule.advanceTimeBy(49)
-        assertThat(value1).isEqualTo(-1f)
-        assertThat(ended).isFalse()
-        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
-
-        animatorTestRule.advanceTimeBy(1)
-        assertThat(value1).isEqualTo(0f)
-        assertThat(ended).isFalse()
-        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
-
-        animatorTestRule.advanceTimeBy(99)
-        assertThat(value1).isEqualTo(0.99f)
-        assertThat(ended).isFalse()
-        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
-
-        animatorTestRule.advanceTimeBy(1)
-        assertThat(value1).isEqualTo(1f)
-        assertThat(ended).isTrue()
-        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(0)
-    }
-
-    @Test
-    fun testTwoAnimators() {
-        var ended1 = false
-        var ended2 = false
-        animateThis("value1", duration = 100) { ended1 = true }
-        animateThis("value2", duration = 200) { ended2 = true }
-        assertThat(value1).isEqualTo(0f)
-        assertThat(value2).isEqualTo(0f)
-        assertThat(ended1).isFalse()
-        assertThat(ended2).isFalse()
-        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(2)
-
-        animatorTestRule.advanceTimeBy(99)
-        assertThat(value1).isEqualTo(0.99f)
-        assertThat(value2).isEqualTo(0.495f)
-        assertThat(ended1).isFalse()
-        assertThat(ended2).isFalse()
-        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(2)
-
-        animatorTestRule.advanceTimeBy(1)
-        assertThat(value1).isEqualTo(1f)
-        assertThat(value2).isEqualTo(0.5f)
-        assertThat(ended1).isTrue()
-        assertThat(ended2).isFalse()
-        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
-
-        animatorTestRule.advanceTimeBy(99)
-        assertThat(value1).isEqualTo(1f)
-        assertThat(value2).isEqualTo(0.995f)
-        assertThat(ended1).isTrue()
-        assertThat(ended2).isFalse()
-        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
-
-        animatorTestRule.advanceTimeBy(1)
-        assertThat(value1).isEqualTo(1f)
-        assertThat(value2).isEqualTo(1f)
-        assertThat(ended1).isTrue()
-        assertThat(ended2).isTrue()
-        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(0)
-    }
-
-    @Test
-    fun testChainedAnimators() {
-        var ended1 = false
-        var ended2 = false
-        animateThis("value1", duration = 100) {
-            ended1 = true
-            animateThis("value2", duration = 100) { ended2 = true }
-        }
-
-        assertThat(value1).isEqualTo(0f)
-        assertThat(value2).isEqualTo(-1f)
-        assertThat(ended1).isFalse()
-        assertThat(ended2).isFalse()
-        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
-
-        animatorTestRule.advanceTimeBy(99)
-        assertThat(value1).isEqualTo(0.99f)
-        assertThat(value2).isEqualTo(-1f)
-        assertThat(ended1).isFalse()
-        assertThat(ended2).isFalse()
-        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
-
-        animatorTestRule.advanceTimeBy(1)
-        assertThat(value1).isEqualTo(1f)
-        assertThat(value2).isEqualTo(0f)
-        assertThat(ended1).isTrue()
-        assertThat(ended2).isFalse()
-        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
-
-        animatorTestRule.advanceTimeBy(99)
-        assertThat(value1).isEqualTo(1f)
-        assertThat(value2).isEqualTo(0.99f)
-        assertThat(ended1).isTrue()
-        assertThat(ended2).isFalse()
-        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
-
-        animatorTestRule.advanceTimeBy(1)
-        assertThat(value1).isEqualTo(1f)
-        assertThat(value2).isEqualTo(1f)
-        assertThat(ended1).isTrue()
-        assertThat(ended2).isTrue()
-        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(0)
-    }
-}
diff --git a/packages/SystemUI/tests/src/androidx/core/animation/AnimatorTestRuleIsolationTest.kt b/packages/SystemUI/tests/src/androidx/core/animation/AnimatorTestRuleIsolationTest.kt
index 2d84fba..5b3f08f 100644
--- a/packages/SystemUI/tests/src/androidx/core/animation/AnimatorTestRuleIsolationTest.kt
+++ b/packages/SystemUI/tests/src/androidx/core/animation/AnimatorTestRuleIsolationTest.kt
@@ -15,8 +15,8 @@
  */
 package androidx.core.animation
 
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.doOnEnd
@@ -29,7 +29,7 @@
  * This test class validates that two tests' animators are isolated from each other when using the
  * same animator test rule. This is a test to prevent future instances of b/275602127.
  */
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 @RunWithLooper
 class AnimatorTestRuleIsolationTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
index 8858d13..48f6cc4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
@@ -28,6 +28,7 @@
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_FACE_ERRORS
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT
+import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_ON_WAKE
 import android.provider.Settings.Secure.ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS
@@ -40,6 +41,7 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.settings.FakeSettings
+import dagger.Lazy
 import java.io.PrintWriter
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
@@ -51,7 +53,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
-import dagger.Lazy
 
 @SmallTest
 class ActiveUnlockConfigTest : SysuiTestCase() {
@@ -111,6 +112,48 @@
                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE
             )
         )
+        assertFalse(
+                activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+                        ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY
+                )
+        )
+        assertTrue(
+            activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
+            )
+        )
+        assertTrue(
+            activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.BIOMETRIC_FAIL
+            )
+        )
+    }
+
+    @Test
+    fun onUnlockIntentLegacySettingChanged() {
+        // GIVEN no active unlock settings enabled
+        assertFalse(
+            activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY
+            )
+        )
+
+        // WHEN unlock on unlock intent legacy is allowed
+        secureSettings.putIntForUser(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY, 1, currentUser)
+        updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_LEGACY))
+
+        // THEN active unlock triggers allowed on unlock_intent_legacy, unlock_intent,
+        // AND biometric fail
+        assertFalse(
+            activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE
+            )
+        )
+        assertTrue(
+            activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY
+            )
+        )
         assertTrue(
             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
@@ -132,16 +175,21 @@
             )
         )
 
-        // WHEN unlock on biometric failed is allowed
+        // WHEN unlock on unlock intent is allowed
         secureSettings.putIntForUser(ACTIVE_UNLOCK_ON_UNLOCK_INTENT, 1, currentUser)
         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT))
 
-        // THEN active unlock triggers allowed on: biometric failure ONLY
+        // THEN active unlock triggers allowed on: unlock intent AND biometric failure
         assertFalse(
             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE
             )
         )
+        assertFalse(
+            activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY
+            )
+        )
         assertTrue(
             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
@@ -184,6 +232,11 @@
         )
         assertFalse(
             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY
+            )
+        )
+        assertFalse(
+            activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
                 ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
             )
         )
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/AuthKeyguardMessageAreaTest.java b/packages/SystemUI/tests/src/com/android/keyguard/AuthKeyguardMessageAreaTest.java
index 52af8fb..6ee8ffd 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/AuthKeyguardMessageAreaTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/AuthKeyguardMessageAreaTest.java
@@ -18,10 +18,10 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
 import android.view.View;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -32,7 +32,7 @@
 import org.mockito.MockitoAnnotations;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @RunWithLooper
 public class AuthKeyguardMessageAreaTest extends SysuiTestCase {
     private KeyguardMessageArea mKeyguardMessageArea;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/BouncerKeyguardMessageAreaTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/BouncerKeyguardMessageAreaTest.kt
index ba46a87..049d77a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/BouncerKeyguardMessageAreaTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/BouncerKeyguardMessageAreaTest.kt
@@ -17,9 +17,9 @@
 package com.android.keyguard
 
 import android.content.Context
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
 import android.util.AttributeSet
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
@@ -31,7 +31,7 @@
 import org.mockito.Mockito.verify
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @RunWithLooper
 class BouncerKeyguardMessageAreaTest : SysuiTestCase() {
     class FakeBouncerKeyguardMessageArea(context: Context, attrs: AttributeSet?) :
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/BouncerPanelExpansionCalculatorTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/BouncerPanelExpansionCalculatorTest.kt
index 6512e70..bb2340a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/BouncerPanelExpansionCalculatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/BouncerPanelExpansionCalculatorTest.kt
@@ -16,15 +16,15 @@
 
 package com.android.keyguard
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import android.testing.AndroidTestingRunner
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class BouncerPanelExpansionCalculatorTest : SysuiTestCase() {
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
index 0a3225e..a8ab922 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java
@@ -50,9 +50,9 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
-import android.testing.AndroidTestingRunner;
 import android.text.TextUtils;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.keyguard.logging.CarrierTextManagerLogger;
@@ -84,7 +84,7 @@
 import java.util.List;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 public class CarrierTextManagerTest extends SysuiTestCase {
 
     private static final CharSequence SEPARATOR = " \u2014 ";
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
index 69a6f2a..79933ee 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
@@ -16,10 +16,10 @@
 package com.android.keyguard
 
 import android.content.BroadcastReceiver
-import android.testing.AndroidTestingRunner
 import android.view.View
 import android.view.ViewTreeObserver
 import android.widget.FrameLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.broadcast.BroadcastDispatcher
@@ -76,7 +76,7 @@
 import com.android.systemui.Flags as AConfigFlags
 import org.mockito.Mockito.`when` as whenever
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class ClockEventControllerTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/EmergencyButtonControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/EmergencyButtonControllerTest.kt
index 9a95b17..347605d 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/EmergencyButtonControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/EmergencyButtonControllerTest.kt
@@ -21,8 +21,8 @@
 import android.os.PowerManager
 import android.telecom.TelecomManager
 import android.telephony.TelephonyManager
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.internal.widget.LockPatternUtils
@@ -45,7 +45,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
 class EmergencyButtonControllerTest : SysuiTestCase() {
     @Mock lateinit var emergencyButton: EmergencyButton
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java
index f9fe5e7..e724c60 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java
@@ -28,10 +28,10 @@
 
 import android.os.SystemClock;
 import android.platform.test.annotations.EnableFlags;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
 import android.view.KeyEvent;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.util.LatencyTracker;
@@ -54,7 +54,7 @@
 import org.mockito.MockitoAnnotations;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @RunWithLooper
 public class KeyguardAbsKeyInputViewControllerTest extends SysuiTestCase {
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardBiometricLockoutLoggerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardBiometricLockoutLoggerTest.kt
index 634dac1..d170e48 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardBiometricLockoutLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardBiometricLockoutLoggerTest.kt
@@ -17,7 +17,7 @@
 package com.android.keyguard
 
 import android.hardware.biometrics.BiometricSourceType
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
 import com.android.internal.logging.UiEventLogger
@@ -38,7 +38,7 @@
 import org.mockito.MockitoAnnotations
 import org.mockito.Mockito.`when` as whenever
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class KeyguardBiometricLockoutLoggerTest : SysuiTestCase() {
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
index cfa74f0..1d78168 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
@@ -30,9 +30,9 @@
 import android.database.ContentObserver;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
 import android.view.View;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.Flags;
@@ -47,7 +47,7 @@
 import org.mockito.verification.VerificationMode;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchControllerBaseTest {
     @Test
     public void testInit_viewAlreadyAttached() {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerWithCoroutinesTest.kt
index 9a1a4e2..c2c0f57 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerWithCoroutinesTest.kt
@@ -16,8 +16,8 @@
 
 package com.android.keyguard
 
-import android.testing.AndroidTestingRunner
 import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED
 import kotlinx.coroutines.Dispatchers
@@ -26,7 +26,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class KeyguardClockSwitchControllerWithCoroutinesTest : KeyguardClockSwitchControllerBaseTest() {
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
index e2063d2..83443be 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -30,7 +30,6 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
@@ -39,6 +38,7 @@
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.Flags;
@@ -55,7 +55,7 @@
 import org.mockito.MockitoAnnotations;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 // Need to run on the main thread because KeyguardSliceView$Row init checks for
 // the main thread before acquiring a wake lock. This class is constructed when
 // the keyguard_clock_switch layout is inflated.
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java
index cc36cfa..dd58ea7 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java
@@ -28,11 +28,11 @@
 import static org.mockito.Mockito.when;
 
 import android.hardware.display.DisplayManagerGlobal;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.Display;
 import android.view.DisplayInfo;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -49,7 +49,7 @@
 import java.util.concurrent.Executor;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @TestableLooper.RunWithLooper
 public class KeyguardDisplayManagerTest extends SysuiTestCase {
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java
index 6228ff8..bd81181 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardMessageAreaControllerTest.java
@@ -27,11 +27,11 @@
 import static org.mockito.Mockito.when;
 
 import android.hardware.biometrics.BiometricSourceType;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.text.Editable;
 import android.text.TextWatcher;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -47,7 +47,7 @@
 
 @SmallTest
 @TestableLooper.RunWithLooper
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 public class KeyguardMessageAreaControllerTest extends SysuiTestCase {
     @Mock
     private ConfigurationController mConfigurationController;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java
index c566826..8b5372a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewControllerTest.java
@@ -23,11 +23,11 @@
 
 import android.content.pm.PackageManager;
 import android.os.Handler;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
 import android.view.View;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -47,7 +47,7 @@
 import org.mockito.MockitoAnnotations;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @RunWithLooper(setAsMainLooper = true)
 public class KeyguardSliceViewControllerTest extends SysuiTestCase {
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
index a0e8065..d96518a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
@@ -17,7 +17,6 @@
 
 import android.graphics.Color;
 import android.net.Uri;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
 import android.view.LayoutInflater;
 
@@ -26,6 +25,7 @@
 import androidx.slice.SliceSpecs;
 import androidx.slice.builders.ListBuilder;
 import androidx.slice.widget.RowContent;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -44,7 +44,7 @@
 
 @SmallTest
 @RunWithLooper(setAsMainLooper = true)
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 public class KeyguardSliceViewTest extends SysuiTestCase {
     private KeyguardSliceView mKeyguardSliceView;
     private Uri mSliceUri;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusAreaViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusAreaViewTest.kt
index ed61ee12..64e4996 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusAreaViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusAreaViewTest.kt
@@ -1,7 +1,7 @@
 package com.android.keyguard
 
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import org.junit.Assert.assertEquals
@@ -10,7 +10,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @RunWithLooper(setAsMainLooper = true)
 class KeyguardStatusAreaViewTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerWithCoroutinesTest.kt
index 3b57d8f..c29439d 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerWithCoroutinesTest.kt
@@ -16,8 +16,8 @@
 
 package com.android.keyguard
 
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.power.shared.model.ScreenPowerState
 import kotlinx.coroutines.cancelChildren
@@ -29,7 +29,7 @@
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
 class KeyguardStatusViewControllerWithCoroutinesTest : KeyguardStatusViewControllerBaseTest() {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
index afd2034..16d2f02 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
@@ -1,7 +1,7 @@
 package com.android.keyguard
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
 import android.view.LayoutInflater
 import android.view.View
@@ -15,7 +15,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @RunWithLooper(setAsMainLooper = true)
 class KeyguardStatusViewTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt
index 336183d..2e41246 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt
@@ -16,8 +16,9 @@
 
 package com.android.keyguard
 
-import android.testing.AndroidTestingRunner
 import android.view.View
+import android.view.ViewGroup
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.ui.view.KeyguardRootView
@@ -43,7 +44,7 @@
  * the set of ids, which also dictact which direction to move and when, via a filter fn.
  */
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class KeyguardUnfoldTransitionTest : SysuiTestCase() {
 
     private val kosmos = Kosmos()
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index ee0cefb..075d8ae 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -108,10 +108,10 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.text.TextUtils;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.dx.mockito.inline.extended.ExtendedMockito;
@@ -176,7 +176,7 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @TestableLooper.RunWithLooper
 public class KeyguardUpdateMonitorTest extends SysuiTestCase {
     private static final String PKG_ALLOWING_FP_LISTEN_ON_OCCLUDING_ACTIVITY =
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUserSwitcherAnchorTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUserSwitcherAnchorTest.kt
index c674053..e7b42624 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUserSwitcherAnchorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUserSwitcherAnchorTest.kt
@@ -15,8 +15,8 @@
  */
 package com.android.keyguard
 
-import android.testing.AndroidTestingRunner
 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
@@ -25,7 +25,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class KeyguardUserSwitcherAnchorTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerTest.java
index 255c7d9..c1ba39e 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerTest.java
@@ -32,12 +32,12 @@
 
 import android.graphics.Point;
 import android.hardware.biometrics.BiometricSourceType;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.util.Pair;
 import android.view.HapticFeedbackConstants;
 import android.view.View;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.biometrics.UdfpsController;
@@ -50,7 +50,7 @@
 import org.junit.runner.RunWith;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @TestableLooper.RunWithLooper
 public class LegacyLockIconViewControllerTest extends LegacyLockIconViewControllerBaseTest {
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerWithCoroutinesTest.kt
index 9580139..2fd3cb0 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerWithCoroutinesTest.kt
@@ -16,8 +16,8 @@
 
 package com.android.keyguard
 
-import android.testing.AndroidTestingRunner
 import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.keyguard.LockIconView.ICON_LOCK
 import com.android.systemui.doze.util.getBurnInOffset
@@ -33,7 +33,7 @@
 import org.mockito.Mockito.reset
 import org.mockito.Mockito.verify
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class LegacyLockIconViewControllerWithCoroutinesTest : LegacyLockIconViewControllerBaseTest() {
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/NumPadAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/NumPadAnimatorTest.kt
index 7c2550f..18976e1 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/NumPadAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/NumPadAnimatorTest.kt
@@ -17,8 +17,8 @@
 
 import android.graphics.drawable.Drawable
 import android.graphics.drawable.GradientDrawable
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import org.junit.Before
@@ -32,7 +32,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
 class NumPadAnimatorTest : SysuiTestCase() {
     @Mock lateinit var background: GradientDrawable
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/PinShapeHintingViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeHintingViewTest.kt
index 835c9ff5..d8f2b10 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/PinShapeHintingViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeHintingViewTest.kt
@@ -16,9 +16,9 @@
 
 package com.android.keyguard
 
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.LayoutInflater
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
@@ -28,7 +28,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
 class PinShapeHintingViewTest : SysuiTestCase() {
     lateinit var underTest: PinShapeHintingView
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/PinShapeNonHintingViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeNonHintingViewTest.kt
index d431731..447cf65 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/PinShapeNonHintingViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/PinShapeNonHintingViewTest.kt
@@ -16,9 +16,9 @@
 
 package com.android.keyguard
 
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.LayoutInflater
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
@@ -28,7 +28,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
 class PinShapeNonHintingViewTest : SysuiTestCase() {
     lateinit var underTest: PinShapeNonHintingView
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/SplitShadeTransitionAdapterTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/SplitShadeTransitionAdapterTest.kt
index 9f9b9a4..c7d11ef 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/SplitShadeTransitionAdapterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/SplitShadeTransitionAdapterTest.kt
@@ -16,10 +16,10 @@
 package com.android.keyguard
 
 import android.animation.Animator
-import android.testing.AndroidTestingRunner
 import android.transition.TransitionValues
 import android.view.View
 import android.view.ViewGroup
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardStatusViewController.SplitShadeTransitionAdapter
 import com.android.systemui.SysuiTestCase
@@ -32,7 +32,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class SplitShadeTransitionAdapterTest : SysuiTestCase() {
 
     @Mock private lateinit var KeyguardClockSwitchController: KeyguardClockSwitchController
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt
index fb649c8..5247a89 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt
@@ -19,7 +19,7 @@
 import android.os.Looper
 import android.platform.test.flag.junit.SetFlagsRule
 import android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
@@ -43,7 +43,7 @@
 import java.util.Optional
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class ScreenOnCoordinatorTest : SysuiTestCase() {
 
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/BootCompleteCacheTest.kt b/packages/SystemUI/tests/src/com/android/systemui/BootCompleteCacheTest.kt
index 2551650..0a9ce68 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/BootCompleteCacheTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/BootCompleteCacheTest.kt
@@ -16,7 +16,7 @@
 
 package com.android.systemui
 
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.dump.DumpManager
 import org.junit.Assert.assertFalse
@@ -30,7 +30,7 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class BootCompleteCacheTest : SysuiTestCase() {
 
@@ -116,4 +116,4 @@
 
         verify(bootCompleteListener, never()).onBootComplete()
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/CameraAvailabilityListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/CameraAvailabilityListenerTest.kt
index f776a63..a23e829 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/CameraAvailabilityListenerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/CameraAvailabilityListenerTest.kt
@@ -4,8 +4,8 @@
 import android.graphics.Rect
 import android.graphics.RectF
 import android.hardware.camera2.CameraManager
-import android.testing.AndroidTestingRunner
 import android.util.PathParser
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.res.R
 import com.android.systemui.util.mockito.any
@@ -19,7 +19,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class CameraAvailabilityListenerTest : SysuiTestCase() {
     companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java b/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java
index 2e04007..0068644 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java
@@ -18,14 +18,17 @@
 
 import android.os.Looper;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Assert;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.util.concurrent.ExecutionException;
 
 @SmallTest
+@RunWith(AndroidJUnit4.class)
 public class DependencyTest extends SysuiTestCase {
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/DisplayCutoutBaseViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/DisplayCutoutBaseViewTest.kt
index 5886206..091072f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/DisplayCutoutBaseViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/DisplayCutoutBaseViewTest.kt
@@ -23,11 +23,11 @@
 import android.graphics.Rect
 import android.graphics.RectF
 import android.graphics.Region
-import android.testing.AndroidTestingRunner
 import android.view.Display
 import android.view.DisplayCutout
 import android.view.DisplayInfo
 import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.dx.mockito.inline.extended.ExtendedMockito.never
 import com.android.internal.R
@@ -42,7 +42,7 @@
 import org.mockito.MockitoAnnotations
 import org.mockito.Mockito.`when` as whenever
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class DisplayCutoutBaseViewTest : SysuiTestCase() {
 
@@ -183,4 +183,4 @@
             return@then true
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/FaceScanningProviderFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/FaceScanningProviderFactoryTest.kt
index 46936d6..bc12aaa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/FaceScanningProviderFactoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/FaceScanningProviderFactoryTest.kt
@@ -16,11 +16,11 @@
 
 import android.graphics.Point
 import android.hardware.display.DisplayManagerGlobal
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
 import android.view.Display
 import android.view.DisplayAdjustments
 import android.view.DisplayInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.R
 import com.android.keyguard.KeyguardUpdateMonitor
@@ -42,7 +42,7 @@
 import org.mockito.MockitoAnnotations
 
 @RunWithLooper
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class FaceScanningProviderFactoryTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorHwcLayerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorHwcLayerTest.kt
index d500b5a..fb60ba3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorHwcLayerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorHwcLayerTest.kt
@@ -22,11 +22,11 @@
 import android.graphics.Rect
 import android.graphics.RectF
 import android.hardware.graphics.common.DisplayDecorationSupport
-import android.testing.AndroidTestingRunner
 import android.view.Display
 import android.view.DisplayCutout
 import android.view.DisplayInfo
 import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.R
 import com.android.systemui.util.mockito.eq
@@ -39,7 +39,7 @@
 import org.mockito.MockitoAnnotations
 import org.mockito.Mockito.`when` as whenever
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class ScreenDecorHwcLayerTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
index 54a14a2..997f8a8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
@@ -61,7 +61,6 @@
 import android.hardware.display.DisplayManager;
 import android.hardware.graphics.common.DisplayDecorationSupport;
 import android.os.Handler;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
 import android.util.PathParser;
@@ -78,6 +77,7 @@
 import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.keyguard.KeyguardUpdateMonitor;
@@ -121,7 +121,7 @@
 import java.util.List;
 
 @RunWithLooper
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class ScreenDecorationsTest extends SysuiTestCase {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java
index 361a945..16b9ab5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IMagnificationConnectionTest.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.accessibility;
 
-import static com.android.systemui.accessibility.Magnification.DELAY_SHOW_MAGNIFICATION_TIMEOUT_MS;
+import static com.android.systemui.accessibility.MagnificationImpl.DELAY_SHOW_MAGNIFICATION_TIMEOUT_MS;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -65,7 +65,7 @@
 
 /**
  * Tests for {@link android.view.accessibility.IMagnificationConnection} retrieved from
- * {@link Magnification}
+ * {@link MagnificationImpl}
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -104,7 +104,7 @@
     private IWindowManager mIWindowManager;
 
     private IMagnificationConnection mIMagnificationConnection;
-    private Magnification mMagnification;
+    private MagnificationImpl mMagnification;
     private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
     private TestableLooper mTestableLooper;
 
@@ -119,11 +119,11 @@
                 any(IMagnificationConnection.class));
         mTestableLooper = TestableLooper.get(this);
         assertNotNull(mTestableLooper);
-        mMagnification = new Magnification(getContext(),
+        mMagnification = new MagnificationImpl(getContext(),
                 mTestableLooper.getLooper(), mContext.getMainExecutor(), mCommandQueue,
                 mModeSwitchesController, mSysUiState, mOverviewProxyService, mSecureSettings,
                 mDisplayTracker, getContext().getSystemService(DisplayManager.class),
-                mA11yLogger, mIWindowManager);
+                mA11yLogger, mIWindowManager, mAccessibilityManager);
         mMagnification.mWindowMagnificationControllerSupplier =
                 new FakeWindowMagnificationControllerSupplier(
                         mContext.getSystemService(DisplayManager.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationTest.java
index 17b7e21..41a4116 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationTest.java
@@ -84,7 +84,7 @@
     private SecureSettings mSecureSettings;
 
     private CommandQueue mCommandQueue;
-    private Magnification mMagnification;
+    private MagnificationImpl mMagnification;
     private OverviewProxyListener mOverviewProxyListener;
     private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
 
@@ -124,11 +124,12 @@
         when(mWindowMagnificationController.isActivated()).thenReturn(true);
 
         mCommandQueue = new CommandQueue(getContext(), mDisplayTracker);
-        mMagnification = new Magnification(getContext(),
+        mMagnification = new MagnificationImpl(getContext(),
                 getContext().getMainThreadHandler(), mContext.getMainExecutor(),
                 mCommandQueue, mModeSwitchesController,
                 mSysUiState, mOverviewProxyService, mSecureSettings, mDisplayTracker,
-                getContext().getSystemService(DisplayManager.class), mA11yLogger, mIWindowManager);
+                getContext().getSystemService(DisplayManager.class), mA11yLogger, mIWindowManager,
+                getContext().getSystemService(AccessibilityManager.class));
         mMagnification.mWindowMagnificationControllerSupplier = new FakeControllerSupplier(
                 mContext.getSystemService(DisplayManager.class), mWindowMagnificationController);
         mMagnification.mMagnificationSettingsSupplier = new FakeSettingsSupplier(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
index 38095c8..c30bedd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
@@ -258,8 +258,9 @@
         setupEnabledAccessibilityServiceList();
 
         mMenuViewLayer.mDismissMenuAction.run();
-        final String value = Settings.Secure.getString(mSpyContext.getContentResolver(),
-                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+        final String value = Settings.Secure.getStringForUser(mSpyContext.getContentResolver(),
+                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+                mSecureSettings.getRealUserHandle(UserHandle.USER_CURRENT));
 
         assertThat(value).isEqualTo("");
     }
@@ -274,8 +275,9 @@
                 ShortcutConstants.UserShortcutType.HARDWARE)).thenReturn(stubShortcutTargets);
 
         mMenuViewLayer.mDismissMenuAction.run();
-        final String value = Settings.Secure.getString(mSpyContext.getContentResolver(),
-                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+        final String value = Settings.Secure.getStringForUser(mSpyContext.getContentResolver(),
+                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+                mSecureSettings.getRealUserHandle(UserHandle.USER_CURRENT));
 
         assertThat(value).isEqualTo(TEST_SELECT_TO_SPEAK_COMPONENT_NAME.flattenToString());
     }
@@ -445,9 +447,11 @@
     }
 
     private void setupEnabledAccessibilityServiceList() {
-        Settings.Secure.putString(mSpyContext.getContentResolver(),
+        Settings.Secure.putStringForUser(mSpyContext.getContentResolver(),
                 Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
-                TEST_SELECT_TO_SPEAK_COMPONENT_NAME.flattenToString());
+                TEST_SELECT_TO_SPEAK_COMPONENT_NAME.flattenToString(),
+                mSecureSettings.getRealUserHandle(UserHandle.USER_CURRENT)
+        );
 
         final ResolveInfo resolveInfo = new ResolveInfo();
         final ServiceInfo serviceInfo = new ServiceInfo();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesCheckerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesCheckerTest.java
index 51f6cdb..7320bbf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesCheckerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesCheckerTest.java
@@ -22,9 +22,9 @@
 
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -44,7 +44,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
 public class HearingDevicesCheckerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java
index 4118c90..639b53b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ambient/touch/TouchMonitorTest.java
@@ -46,6 +46,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleCoroutineScope;
 import androidx.lifecycle.LifecycleObserver;
 import androidx.lifecycle.LifecycleOwner;
 import androidx.lifecycle.LifecycleRegistry;
@@ -159,7 +160,9 @@
             ArgumentCaptor<LifecycleObserver> observerCaptor =
                     ArgumentCaptor.forClass(LifecycleObserver.class);
             verify(mLifecycleRegistry, atLeast(1)).addObserver(observerCaptor.capture());
-            mLifecycleObservers.addAll(observerCaptor.getAllValues());
+            mLifecycleObservers.addAll(observerCaptor.getAllValues().stream().filter(
+                    lifecycleObserver -> !(lifecycleObserver instanceof LifecycleCoroutineScope))
+                    .toList());
 
             updateLifecycle(Lifecycle.State.RESUMED);
 
@@ -212,6 +215,40 @@
     }
 
     @Test
+    public void testSessionResetOnLifecycle() {
+        final TouchHandler touchHandler = createTouchHandler();
+        final Rect touchArea = new Rect(4, 4, 8 , 8);
+
+        doAnswer(invocation -> {
+            final Region region = (Region) invocation.getArguments()[1];
+            region.set(touchArea);
+            return null;
+        }).when(touchHandler).getTouchInitiationRegion(any(), any(), any());
+
+        final Environment environment = new Environment(Stream.of(touchHandler)
+                .collect(Collectors.toCollection(HashSet::new)), mKosmos);
+
+        // Ensure touch outside specified region is not delivered.
+        final MotionEvent initialEvent = Mockito.mock(MotionEvent.class);
+
+        // Make sure touch inside region causes session start.
+        when(initialEvent.getX()).thenReturn(5.0f);
+        when(initialEvent.getY()).thenReturn(5.0f);
+        environment.publishInputEvent(initialEvent);
+        verify(touchHandler).onSessionStart(any());
+
+        Mockito.clearInvocations(touchHandler);
+
+        // Reset lifecycle, forcing monitoring to be reset
+        environment.updateLifecycle(Lifecycle.State.STARTED);
+        environment.updateLifecycle(Lifecycle.State.RESUMED);
+        environment.executeAll();
+
+        environment.publishInputEvent(initialEvent);
+        verify(touchHandler).onSessionStart(any());
+    }
+
+    @Test
     @EnableFlags(Flags.FLAG_AMBIENT_TOUCH_MONITOR_LISTEN_TO_DISPLAY_CHANGES)
     public void testConfigurationListenerUpdatesBounds() {
         final TouchHandler touchHandler = createTouchHandler();
@@ -332,7 +369,6 @@
         }
     }
 
-
     @Test
     public void testNoActiveSessionWhenHandlerDisabled() {
         final TouchHandler touchHandler = Mockito.mock(TouchHandler.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/battery/AccessorizedBatteryDrawableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/battery/AccessorizedBatteryDrawableTest.kt
index 982f033..99d3600 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/battery/AccessorizedBatteryDrawableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/battery/AccessorizedBatteryDrawableTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.battery
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.battery.BatterySpecs.BATTERY_HEIGHT
@@ -24,8 +25,10 @@
 import com.android.systemui.battery.BatterySpecs.BATTERY_WIDTH_WITH_SHIELD
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class AccessorizedBatteryDrawableTest : SysuiTestCase() {
     @Test
     fun intrinsicSize_shieldFalse_isBatterySize() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewControllerTest.java
index 14eff2f..d940fc9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewControllerTest.java
@@ -31,6 +31,7 @@
 import android.os.Handler;
 import android.provider.Settings;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -44,10 +45,12 @@
 
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
 @SmallTest
+@RunWith(AndroidJUnit4.class)
 public class BatteryMeterViewControllerTest extends SysuiTestCase {
     @Mock
     private BatteryMeterView mBatteryMeterView;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/battery/BatterySpecsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/battery/BatterySpecsTest.kt
index 39cb047..cac0b66 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/battery/BatterySpecsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/battery/BatterySpecsTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.battery
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.battery.BatterySpecs.BATTERY_HEIGHT
@@ -24,8 +25,10 @@
 import com.android.systemui.battery.BatterySpecs.BATTERY_WIDTH_WITH_SHIELD
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class BatterySpecsTest : SysuiTestCase() {
     @Test
     fun getFullBatteryHeight_shieldFalse_returnsMainHeight() {
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 9a99ed7..1e3ee28 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -27,6 +27,7 @@
 import android.hardware.biometrics.PromptInfo
 import android.hardware.biometrics.PromptVerticalListContentView
 import android.hardware.face.FaceSensorPropertiesInternal
+import android.hardware.fingerprint.FingerprintManager
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
 import android.os.Handler
 import android.os.IBinder
@@ -88,9 +89,8 @@
 import org.mockito.Mockito.never
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
-import org.mockito.junit.MockitoJUnit
 import org.mockito.Mockito.`when` as whenever
-
+import org.mockito.junit.MockitoJUnit
 
 private const val OP_PACKAGE_NAME = "biometric.testapp"
 
@@ -99,33 +99,21 @@
 @SmallTest
 open class AuthContainerViewTest : SysuiTestCase() {
 
-    @JvmField @Rule
-    var mockitoRule = MockitoJUnit.rule()
+    @JvmField @Rule var mockitoRule = MockitoJUnit.rule()
 
-    @Mock
-    lateinit var callback: AuthDialogCallback
-    @Mock
-    lateinit var userManager: UserManager
-    @Mock
-    lateinit var lockPatternUtils: LockPatternUtils
-    @Mock
-    lateinit var wakefulnessLifecycle: WakefulnessLifecycle
-    @Mock
-    lateinit var panelInteractionDetector: AuthDialogPanelInteractionDetector
-    @Mock
-    lateinit var windowToken: IBinder
-    @Mock
-    lateinit var interactionJankMonitor: InteractionJankMonitor
-    @Mock
-    lateinit var vibrator: VibratorHelper
-    @Mock
-    lateinit var udfpsUtils: UdfpsUtils
-    @Mock
-    lateinit var authController: AuthController
-    @Mock
-    lateinit var selectedUserInteractor: SelectedUserInteractor
-    @Mock
-    private lateinit var packageManager: PackageManager
+    @Mock lateinit var callback: AuthDialogCallback
+    @Mock lateinit var userManager: UserManager
+    @Mock lateinit var fingerprintManager: FingerprintManager
+    @Mock lateinit var lockPatternUtils: LockPatternUtils
+    @Mock lateinit var wakefulnessLifecycle: WakefulnessLifecycle
+    @Mock lateinit var panelInteractionDetector: AuthDialogPanelInteractionDetector
+    @Mock lateinit var windowToken: IBinder
+    @Mock lateinit var interactionJankMonitor: InteractionJankMonitor
+    @Mock lateinit var vibrator: VibratorHelper
+    @Mock lateinit var udfpsUtils: UdfpsUtils
+    @Mock lateinit var authController: AuthController
+    @Mock lateinit var selectedUserInteractor: SelectedUserInteractor
+    @Mock private lateinit var packageManager: PackageManager
     @Mock private lateinit var activityTaskManager: ActivityTaskManager
 
     private lateinit var displayRepository: FakeDisplayRepository
@@ -141,11 +129,12 @@
     private val fingerprintRepository = FakeFingerprintPropertyRepository()
     private val displayStateRepository = FakeDisplayStateRepository()
     private val credentialInteractor = FakeCredentialInteractor()
-    private val bpCredentialInteractor = PromptCredentialInteractor(
-        Dispatchers.Main.immediate,
-        biometricPromptRepository,
-        credentialInteractor,
-    )
+    private val bpCredentialInteractor =
+        PromptCredentialInteractor(
+            Dispatchers.Main.immediate,
+            biometricPromptRepository,
+            credentialInteractor,
+        )
     private val promptSelectorInteractor by lazy {
         PromptSelectorInteractorImpl(
             fingerprintRepository,
@@ -166,22 +155,26 @@
 
         displayStateInteractor =
             DisplayStateInteractorImpl(
-                    testScope.backgroundScope,
-                    mContext,
-                    fakeExecutor,
-                    displayStateRepository,
-                    displayRepository,
+                testScope.backgroundScope,
+                mContext,
+                fakeExecutor,
+                displayStateRepository,
+                displayRepository,
             )
         udfpsOverlayInteractor =
-                UdfpsOverlayInteractor(
-                        context,
-                        authController,
-                        selectedUserInteractor,
-                        testScope.backgroundScope,
-                )
+            UdfpsOverlayInteractor(
+                context,
+                authController,
+                selectedUserInteractor,
+                fingerprintManager,
+                testScope.backgroundScope,
+            )
         biometricStatusInteractor =
-                BiometricStatusInteractorImpl(activityTaskManager, biometricStatusRepository,
-                    fingerprintRepository)
+            BiometricStatusInteractorImpl(
+                activityTaskManager,
+                biometricStatusRepository,
+                fingerprintRepository
+            )
         iconProvider = IconProvider(context)
         // Set up default logo icon
         whenever(packageManager.getApplicationIcon(OP_PACKAGE_NAME)).thenReturn(defaultLogoIcon)
@@ -198,10 +191,8 @@
     @Test
     fun testNotifiesAnimatedIn() {
         initializeFingerprintContainer()
-        verify(callback).onDialogAnimatedIn(
-            authContainer?.requestId ?: 0L,
-            true /* startFingerprintNow */
-        )
+        verify(callback)
+            .onDialogAnimatedIn(authContainer?.requestId ?: 0L, true /* startFingerprintNow */)
     }
 
     @Test
@@ -246,10 +237,8 @@
         waitForIdleSync()
 
         // attaching the view resets the state and allows this to happen again
-        verify(callback).onDialogAnimatedIn(
-            authContainer?.requestId ?: 0L,
-            true /* startFingerprintNow */
-        )
+        verify(callback)
+            .onDialogAnimatedIn(authContainer?.requestId ?: 0L, true /* startFingerprintNow */)
     }
 
     @Test
@@ -274,10 +263,8 @@
 
         // the first time is triggered by initializeFingerprintContainer()
         // the second time was triggered by dismissWithoutCallback()
-        verify(callback, times(2)).onDialogAnimatedIn(
-            authContainer?.requestId ?: 0L,
-            true /* startFingerprintNow */
-        )
+        verify(callback, times(2))
+            .onDialogAnimatedIn(authContainer?.requestId ?: 0L, true /* startFingerprintNow */)
     }
 
     @Test
@@ -288,18 +275,18 @@
         verify(panelInteractionDetector).disable()
     }
 
-
     @Test
     fun testActionAuthenticated_sendsDismissedAuthenticated() {
         val container = initializeFingerprintContainer()
         container.mBiometricCallback.onAuthenticated()
         waitForIdleSync()
 
-        verify(callback).onDismissed(
+        verify(callback)
+            .onDismissed(
                 eq(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED),
                 eq<ByteArray?>(null), /* credentialAttestation */
                 eq(authContainer?.requestId ?: 0L)
-        )
+            )
         assertThat(container.parent).isNull()
     }
 
@@ -309,15 +296,17 @@
         container.mBiometricCallback.onUserCanceled()
         waitForIdleSync()
 
-        verify(callback).onSystemEvent(
+        verify(callback)
+            .onSystemEvent(
                 eq(BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL),
                 eq(authContainer?.requestId ?: 0L)
-        )
-        verify(callback).onDismissed(
+            )
+        verify(callback)
+            .onDismissed(
                 eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
                 eq<ByteArray?>(null), /* credentialAttestation */
                 eq(authContainer?.requestId ?: 0L)
-        )
+            )
         assertThat(container.parent).isNull()
     }
 
@@ -327,19 +316,21 @@
         container.mBiometricCallback.onButtonNegative()
         waitForIdleSync()
 
-        verify(callback).onDismissed(
+        verify(callback)
+            .onDismissed(
                 eq(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE),
                 eq<ByteArray?>(null), /* credentialAttestation */
                 eq(authContainer?.requestId ?: 0L)
-        )
+            )
         assertThat(container.parent).isNull()
     }
 
     @Test
     fun testActionTryAgain_sendsTryAgain() {
-        val container = initializeFingerprintContainer(
-            authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK
-        )
+        val container =
+            initializeFingerprintContainer(
+                authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK
+            )
         container.mBiometricCallback.onButtonTryAgain()
         waitForIdleSync()
 
@@ -352,21 +343,24 @@
         container.mBiometricCallback.onError()
         waitForIdleSync()
 
-        verify(callback).onDismissed(
+        verify(callback)
+            .onDismissed(
                 eq(AuthDialogCallback.DISMISSED_ERROR),
                 eq<ByteArray?>(null), /* credentialAttestation */
                 eq(authContainer?.requestId ?: 0L)
-        )
+            )
         assertThat(authContainer!!.parent).isNull()
     }
 
     @Ignore("b/279650412")
     @Test
     fun testActionUseDeviceCredential_sendsOnDeviceCredentialPressed() {
-        val container = initializeFingerprintContainer(
-            authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK or
-                    BiometricManager.Authenticators.DEVICE_CREDENTIAL
-        )
+        val container =
+            initializeFingerprintContainer(
+                authenticators =
+                    BiometricManager.Authenticators.BIOMETRIC_WEAK or
+                        BiometricManager.Authenticators.DEVICE_CREDENTIAL
+            )
         container.mBiometricCallback.onUseDeviceCredential()
         waitForIdleSync()
 
@@ -376,10 +370,12 @@
 
     @Test
     fun testAnimateToCredentialUI_invokesStartTransitionToCredentialUI() {
-        val container = initializeFingerprintContainer(
-            authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK or
-                    BiometricManager.Authenticators.DEVICE_CREDENTIAL
-        )
+        val container =
+            initializeFingerprintContainer(
+                authenticators =
+                    BiometricManager.Authenticators.BIOMETRIC_WEAK or
+                        BiometricManager.Authenticators.DEVICE_CREDENTIAL
+            )
         container.animateToCredentialUI(false)
         waitForIdleSync()
 
@@ -395,10 +391,12 @@
 
     @Test
     fun testAnimateToCredentialUI_rotateCredentialUI() {
-        val container = initializeFingerprintContainer(
-            authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK or
-                    BiometricManager.Authenticators.DEVICE_CREDENTIAL
-        )
+        val container =
+            initializeFingerprintContainer(
+                authenticators =
+                    BiometricManager.Authenticators.BIOMETRIC_WEAK or
+                        BiometricManager.Authenticators.DEVICE_CREDENTIAL
+            )
         container.animateToCredentialUI(false)
         waitForIdleSync()
 
@@ -437,13 +435,12 @@
         mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT)
         var isButtonClicked = false
         val contentView =
-                PromptContentViewWithMoreOptionsButton.Builder()
-                        .setMoreOptionsButtonListener(
-                                fakeExecutor) { _, _ -> isButtonClicked = true }
-                        .build()
+            PromptContentViewWithMoreOptionsButton.Builder()
+                .setMoreOptionsButtonListener(fakeExecutor) { _, _ -> isButtonClicked = true }
+                .build()
 
         val container =
-                initializeFingerprintContainer(contentViewWithMoreOptionsButton = contentView)
+            initializeFingerprintContainer(contentViewWithMoreOptionsButton = contentView)
 
         waitForIdleSync()
 
@@ -461,9 +458,9 @@
     @Test
     fun testShowCredentialUI_withDescription() {
         val container =
-                initializeFingerprintContainer(
-                        authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL
-                )
+            initializeFingerprintContainer(
+                authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL
+            )
         waitForIdleSync()
 
         assertThat(container.hasCredentialView()).isTrue()
@@ -475,10 +472,10 @@
         mSetFlagsRule.enableFlags(FLAG_CONSTRAINT_BP)
         mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT)
         val container =
-                initializeFingerprintContainer(
-                        authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL,
-                        verticalListContentView = PromptVerticalListContentView.Builder().build()
-                )
+            initializeFingerprintContainer(
+                authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL,
+                verticalListContentView = PromptVerticalListContentView.Builder().build()
+            )
         // Two-step credential view should show -
         // 1. biometric prompt without sensor 2. credential view ui
         waitForIdleSync()
@@ -497,14 +494,14 @@
         mSetFlagsRule.enableFlags(FLAG_CONSTRAINT_BP)
         mSetFlagsRule.enableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT)
         val contentView =
-                PromptContentViewWithMoreOptionsButton.Builder()
-                        .setMoreOptionsButtonListener(fakeExecutor) { _, _ -> }
-                        .build()
+            PromptContentViewWithMoreOptionsButton.Builder()
+                .setMoreOptionsButtonListener(fakeExecutor) { _, _ -> }
+                .build()
         val container =
-                initializeFingerprintContainer(
-                        authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL,
-                        contentViewWithMoreOptionsButton = contentView
-                )
+            initializeFingerprintContainer(
+                authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL,
+                contentViewWithMoreOptionsButton = contentView
+            )
         waitForIdleSync()
 
         assertThat(container.hasCredentialView()).isTrue()
@@ -514,13 +511,13 @@
     @Test
     fun testCredentialViewUsesEffectiveUserId() {
         whenever(userManager.getCredentialOwnerProfile(anyInt())).thenReturn(200)
-        whenever(lockPatternUtils.getKeyguardStoredPasswordQuality(eq(200))).thenReturn(
-            DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
-        )
+        whenever(lockPatternUtils.getKeyguardStoredPasswordQuality(eq(200)))
+            .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING)
 
-        val container = initializeFingerprintContainer(
-            authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL
-        )
+        val container =
+            initializeFingerprintContainer(
+                authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL
+            )
         waitForIdleSync()
 
         assertThat(container.hasCredentialPatternView()).isTrue()
@@ -531,9 +528,8 @@
     fun testCredentialUI_disablesClickingOnBackground() {
         val container = initializeCredentialPasswordContainer()
         assertThat(container.hasBiometricPrompt()).isFalse()
-        assertThat(
-            container.findViewById<View>(R.id.background)?.isImportantForAccessibility
-        ).isFalse()
+        assertThat(container.findViewById<View>(R.id.background)?.isImportantForAccessibility)
+            .isFalse()
 
         container.findViewById<View>(R.id.background)?.performClick()
         waitForIdleSync()
@@ -552,7 +548,7 @@
     fun testLayoutParams_hasShowWhenLockedFlag() {
         val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
         assertThat((layoutParams.flags and WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED) != 0)
-                .isTrue()
+            .isTrue()
     }
 
     @Test
@@ -590,20 +586,20 @@
     }
 
     private fun initializeCredentialPasswordContainer(
-            addToView: Boolean = true,
+        addToView: Boolean = true,
     ): TestAuthContainerView {
         whenever(userManager.getCredentialOwnerProfile(anyInt())).thenReturn(20)
-        whenever(lockPatternUtils.getKeyguardStoredPasswordQuality(eq(20))).thenReturn(
-            DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
-        )
+        whenever(lockPatternUtils.getKeyguardStoredPasswordQuality(eq(20)))
+            .thenReturn(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC)
 
         // In the credential view, clicking on the background (to cancel authentication) is not
         // valid. Thus, the listener should be null, and it should not be in the accessibility
         // hierarchy.
-        val container = initializeFingerprintContainer(
+        val container =
+            initializeFingerprintContainer(
                 authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL,
                 addToView = addToView,
-        )
+            )
         waitForIdleSync()
 
         assertThat(container.hasCredentialPasswordView()).isTrue()
@@ -615,26 +611,28 @@
         addToView: Boolean = true,
         verticalListContentView: PromptVerticalListContentView? = null,
         contentViewWithMoreOptionsButton: PromptContentViewWithMoreOptionsButton? = null,
-    ) = initializeContainer(
-        TestAuthContainerView(
-            authenticators = authenticators,
-            fingerprintProps = fingerprintSensorPropertiesInternal(),
+    ) =
+        initializeContainer(
+            TestAuthContainerView(
+                authenticators = authenticators,
+                fingerprintProps = fingerprintSensorPropertiesInternal(),
                 verticalListContentView = verticalListContentView,
-        ),
-        addToView
-    )
+            ),
+            addToView
+        )
 
     private fun initializeCoexContainer(
         authenticators: Int = BiometricManager.Authenticators.BIOMETRIC_WEAK,
         addToView: Boolean = true
-    ) = initializeContainer(
-        TestAuthContainerView(
-            authenticators = authenticators,
-            fingerprintProps = fingerprintSensorPropertiesInternal(),
-            faceProps = faceSensorPropertiesInternal()
-        ),
-        addToView
-    )
+    ) =
+        initializeContainer(
+            TestAuthContainerView(
+                authenticators = authenticators,
+                fingerprintProps = fingerprintSensorPropertiesInternal(),
+                faceProps = faceSensorPropertiesInternal()
+            ),
+            addToView
+        )
 
     private fun initializeContainer(
         view: TestAuthContainerView,
@@ -655,47 +653,50 @@
         faceProps: List<FaceSensorPropertiesInternal> = listOf(),
         verticalListContentView: PromptVerticalListContentView? = null,
         contentViewWithMoreOptionsButton: PromptContentViewWithMoreOptionsButton? = null,
-    ) : AuthContainerView(
-        Config().apply {
-            mContext = this@AuthContainerViewTest.context
-            mCallback = callback
-            mSensorIds = (fingerprintProps.map { it.sensorId } +
-                faceProps.map { it.sensorId }).toIntArray()
-            mSkipAnimation = true
-            mPromptInfo = PromptInfo().apply {
-                this.authenticators = authenticators
-                if (verticalListContentView != null) {
-                    this.contentView = verticalListContentView
-                } else if (contentViewWithMoreOptionsButton != null) {
-                    this.contentView = contentViewWithMoreOptionsButton
-                }
-            }
-            mOpPackageName = OP_PACKAGE_NAME
-        },
-        testScope.backgroundScope,
-        fingerprintProps,
-        faceProps,
-        wakefulnessLifecycle,
-        panelInteractionDetector,
-        userManager,
-        lockPatternUtils,
-        interactionJankMonitor,
-        { promptSelectorInteractor },
-        PromptViewModel(
-            displayStateInteractor,
-            promptSelectorInteractor,
-            context,
-            udfpsOverlayInteractor,
-            biometricStatusInteractor,
-            udfpsUtils,
-            iconProvider,
-            activityTaskManager
-        ),
-        { credentialViewModel },
-        Handler(TestableLooper.get(this).looper),
-        fakeExecutor,
-        vibrator
-    ) {
+    ) :
+        AuthContainerView(
+            Config().apply {
+                mContext = this@AuthContainerViewTest.context
+                mCallback = callback
+                mSensorIds =
+                    (fingerprintProps.map { it.sensorId } + faceProps.map { it.sensorId })
+                        .toIntArray()
+                mSkipAnimation = true
+                mPromptInfo =
+                    PromptInfo().apply {
+                        this.authenticators = authenticators
+                        if (verticalListContentView != null) {
+                            this.contentView = verticalListContentView
+                        } else if (contentViewWithMoreOptionsButton != null) {
+                            this.contentView = contentViewWithMoreOptionsButton
+                        }
+                    }
+                mOpPackageName = OP_PACKAGE_NAME
+            },
+            testScope.backgroundScope,
+            fingerprintProps,
+            faceProps,
+            wakefulnessLifecycle,
+            panelInteractionDetector,
+            userManager,
+            lockPatternUtils,
+            interactionJankMonitor,
+            { promptSelectorInteractor },
+            PromptViewModel(
+                displayStateInteractor,
+                promptSelectorInteractor,
+                context,
+                udfpsOverlayInteractor,
+                biometricStatusInteractor,
+                udfpsUtils,
+                iconProvider,
+                activityTaskManager
+            ),
+            { credentialViewModel },
+            Handler(TestableLooper.get(this).looper),
+            fakeExecutor,
+            vibrator
+        ) {
         override fun postOnAnimation(runnable: Runnable) {
             runnable.run()
         }
@@ -717,8 +718,10 @@
         val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
         val lpFlags = layoutParams.flags
 
-        assertThat((lpFlags and WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS)
-                != 0).isTrue()
+        assertThat(
+                (lpFlags and WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) != 0
+            )
+            .isTrue()
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt
index a58efd3..30207bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/LogContextInteractorImplTest.kt
@@ -23,15 +23,22 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
 import com.android.systemui.display.data.repository.DeviceStateRepository
 import com.android.systemui.display.data.repository.fakeDeviceStateRepository
+import com.android.systemui.flags.DisableSceneContainer
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -61,10 +68,11 @@
     fun setup() {
         interactor =
             LogContextInteractorImpl(
-                testScope.backgroundScope,
-                deviceStateRepository,
-                kosmos.keyguardTransitionInteractor,
-                udfpsOverlayInteractor,
+                applicationScope = testScope.backgroundScope,
+                deviceStateRepository = deviceStateRepository,
+                keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor,
+                udfpsOverlayInteractor = udfpsOverlayInteractor,
+                deviceEntryInteractor = { kosmos.deviceEntryInteractor },
             )
     }
 
@@ -135,7 +143,57 @@
         }
 
     @Test
-    fun displayStateChanges() =
+    @EnableSceneContainer
+    fun displayStateChanges_withSceneContainer() =
+        testScope.runTest {
+            val displayState = collectLastValue(interactor.displayState)
+
+            keyguardTransitionRepository.startTransitionTo(KeyguardState.OFF)
+            assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_NO_UI)
+
+            keyguardTransitionRepository.startTransitionTo(KeyguardState.DOZING)
+            assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_NO_UI)
+
+            keyguardTransitionRepository.startTransitionTo(KeyguardState.DREAMING)
+            assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_SCREENSAVER)
+
+            keyguardTransitionRepository.startTransitionTo(KeyguardState.AOD)
+            assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_AOD)
+
+            keyguardTransitionRepository.startTransitionTo(KeyguardState.ALTERNATE_BOUNCER)
+            assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN)
+
+            keyguardTransitionRepository.startTransitionTo(KeyguardState.PRIMARY_BOUNCER)
+            assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN)
+
+            keyguardTransitionRepository.startTransitionTo(KeyguardState.LOCKSCREEN)
+            assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN)
+
+            keyguardTransitionRepository.startTransitionTo(KeyguardState.OCCLUDED)
+            assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_LOCKSCREEN)
+
+            // Unlock the device.
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
+            runCurrent()
+            kosmos.sceneInteractor.snapToScene(Scenes.Gone, "")
+
+            keyguardTransitionRepository.startTransitionTo(KeyguardState.GONE)
+            assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_UNKNOWN)
+
+            keyguardTransitionRepository.startTransitionTo(KeyguardState.UNDEFINED)
+            assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_UNKNOWN)
+
+            // Relock the device
+            kosmos.sceneInteractor.snapToScene(Scenes.Lockscreen, "")
+            keyguardTransitionRepository.startTransitionTo(KeyguardState.AOD)
+            assertThat(displayState()).isEqualTo(AuthenticateOptions.DISPLAY_STATE_AOD)
+        }
+
+    @Test
+    @DisableSceneContainer
+    fun displayStateChanges_withoutSceneContainer() =
         testScope.runTest {
             val displayState = collectLastValue(interactor.displayState)
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt
index 3d63c5b..13f2c72 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.biometrics.domain.interactor
 
 import android.graphics.Rect
+import android.hardware.fingerprint.FingerprintManager
 import android.view.MotionEvent
 import android.view.Surface
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -51,6 +52,7 @@
 
     private lateinit var testScope: TestScope
 
+    @Mock private lateinit var fingerprintManager: FingerprintManager
     @Mock private lateinit var authController: AuthController
     @Captor private lateinit var authControllerCallback: ArgumentCaptor<AuthController.Callback>
 
@@ -111,6 +113,7 @@
                 context,
                 authController,
                 selectedUserInteractor,
+                fingerprintManager,
                 testScope.backgroundScope
             )
         testScope.runCurrent()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
index 4238254..7fa165c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
@@ -73,6 +73,7 @@
 import org.mockito.Mockito.`when`
 import org.mockito.junit.MockitoJUnit
 import org.mockito.junit.MockitoRule
+import org.mockito.kotlin.argumentCaptor
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
@@ -218,6 +219,13 @@
 
             verify(kosmos.windowManager).addView(any(), any())
 
+            var viewCaptor = argumentCaptor<View>()
+            verify(kosmos.windowManager).addView(viewCaptor.capture(), any())
+            verify(viewCaptor.firstValue)
+                .announceForAccessibility(
+                    mContext.getText(R.string.accessibility_side_fingerprint_indicator_label)
+                )
+
             // Hide alternate bouncer
             kosmos.keyguardBouncerRepository.setAlternateVisible(false)
             runCurrent()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
index 93c6d9e..677d1fd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelTest.kt
@@ -17,11 +17,11 @@
 package com.android.systemui.biometrics.ui.viewmodel
 
 import android.app.ActivityManager.RunningTaskInfo
-import android.app.ActivityTaskManager
 import android.content.ComponentName
+import android.content.applicationContext
+import android.content.packageManager
 import android.content.pm.ActivityInfo
 import android.content.pm.ApplicationInfo
-import android.content.pm.PackageManager
 import android.content.pm.PackageManager.NameNotFoundException
 import android.content.res.Configuration
 import android.graphics.Bitmap
@@ -41,26 +41,20 @@
 import android.platform.test.annotations.EnableFlags
 import android.view.HapticFeedbackConstants
 import android.view.MotionEvent
+import android.view.Surface
 import androidx.test.filters.SmallTest
-import com.android.internal.widget.LockPatternUtils
-import com.android.launcher3.icons.IconProvider
+import com.android.app.activityTaskManager
 import com.android.systemui.Flags.FLAG_BP_TALKBACK
 import com.android.systemui.Flags.FLAG_CONSTRAINT_BP
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.AuthController
-import com.android.systemui.biometrics.UdfpsUtils
 import com.android.systemui.biometrics.Utils.toBitmap
-import com.android.systemui.biometrics.data.repository.FakeBiometricStatusRepository
-import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository
-import com.android.systemui.biometrics.data.repository.FakeFingerprintPropertyRepository
-import com.android.systemui.biometrics.data.repository.FakePromptRepository
-import com.android.systemui.biometrics.domain.interactor.BiometricStatusInteractor
-import com.android.systemui.biometrics.domain.interactor.BiometricStatusInteractorImpl
-import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
-import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractorImpl
+import com.android.systemui.biometrics.authController
+import com.android.systemui.biometrics.data.repository.biometricStatusRepository
+import com.android.systemui.biometrics.data.repository.fakeFingerprintPropertyRepository
 import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractor
-import com.android.systemui.biometrics.domain.interactor.PromptSelectorInteractorImpl
-import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor
+import com.android.systemui.biometrics.domain.interactor.promptSelectorInteractor
+import com.android.systemui.biometrics.domain.interactor.udfpsOverlayInteractor
 import com.android.systemui.biometrics.extractAuthenticatorTypes
 import com.android.systemui.biometrics.faceSensorPropertiesInternal
 import com.android.systemui.biometrics.fingerprintSensorPropertiesInternal
@@ -68,18 +62,20 @@
 import com.android.systemui.biometrics.shared.model.BiometricModalities
 import com.android.systemui.biometrics.shared.model.BiometricModality
 import com.android.systemui.biometrics.shared.model.DisplayRotation
+import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
 import com.android.systemui.biometrics.shared.model.toSensorStrength
 import com.android.systemui.biometrics.shared.model.toSensorType
+import com.android.systemui.biometrics.udfpsUtils
+import com.android.systemui.concurrency.fakeExecutor
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.display.data.repository.FakeDisplayRepository
+import com.android.systemui.display.data.repository.displayStateRepository
 import com.android.systemui.keyguard.shared.model.AcquiredFingerprintAuthenticationStatus
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
 import com.android.systemui.res.R
-import com.android.systemui.user.domain.interactor.SelectedUserInteractor
-import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.whenever
-import com.android.systemui.util.time.FakeSystemClock
+import com.android.systemui.util.mockito.withArgCaptor
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.first
@@ -94,7 +90,9 @@
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.ArgumentMatchers.eq
 import org.mockito.Mock
+import org.mockito.Mockito
 import org.mockito.junit.MockitoJUnit
+import org.mockito.kotlin.whenever
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
@@ -113,20 +111,12 @@
 
     @JvmField @Rule var mockitoRule = MockitoJUnit.rule()
 
-    @Mock private lateinit var lockPatternUtils: LockPatternUtils
     @Mock private lateinit var authController: AuthController
-    @Mock private lateinit var selectedUserInteractor: SelectedUserInteractor
-    @Mock private lateinit var udfpsUtils: UdfpsUtils
-    @Mock private lateinit var packageManager: PackageManager
-    @Mock private lateinit var iconProvider: IconProvider
     @Mock private lateinit var applicationInfoWithIcon: ApplicationInfo
     @Mock private lateinit var applicationInfoNoIcon: ApplicationInfo
-    @Mock private lateinit var activityTaskManager: ActivityTaskManager
     @Mock private lateinit var activityInfo: ActivityInfo
     @Mock private lateinit var runningTaskInfo: RunningTaskInfo
 
-    private val fakeExecutor = FakeExecutor(FakeSystemClock())
-    private val testScope = TestScope()
     private val defaultLogoIcon = context.getDrawable(R.drawable.ic_android)
     private val defaultLogoIconWithOverrides = context.getDrawable(R.drawable.ic_add)
     private val logoResFromApp = R.drawable.ic_cake
@@ -156,28 +146,81 @@
         context.resources.getDimensionPixelSize(
             R.dimen.biometric_prompt_two_pane_medium_horizontal_guideline_padding
         )
+    private val mockFaceIconSize = 200
+    private val mockFingerprintIconWidth = 300
+    private val mockFingerprintIconHeight = 300
 
-    private lateinit var fingerprintRepository: FakeFingerprintPropertyRepository
-    private lateinit var promptRepository: FakePromptRepository
-    private lateinit var displayStateRepository: FakeDisplayStateRepository
-    private lateinit var biometricStatusRepository: FakeBiometricStatusRepository
-    private lateinit var displayRepository: FakeDisplayRepository
-    private lateinit var displayStateInteractor: DisplayStateInteractor
-    private lateinit var udfpsOverlayInteractor: UdfpsOverlayInteractor
-    private lateinit var biometricStatusInteractor: BiometricStatusInteractor
+    /** Mock [UdfpsOverlayParams] for a test. */
+    private fun mockUdfpsOverlayParams(isLandscape: Boolean = false): UdfpsOverlayParams =
+        UdfpsOverlayParams(
+            sensorBounds = Rect(400, 1600, 600, 1800),
+            overlayBounds = Rect(0, 1200, 1000, 2400),
+            naturalDisplayWidth = 1000,
+            naturalDisplayHeight = 3000,
+            scaleFactor = 1f,
+            rotation = if (isLandscape) Surface.ROTATION_90 else Surface.ROTATION_0
+        )
 
-    private lateinit var selector: PromptSelectorInteractor
-    private lateinit var viewModel: PromptViewModel
-    private lateinit var iconViewModel: PromptIconViewModel
     private lateinit var promptContentView: PromptContentView
     private lateinit var promptContentViewWithMoreOptionsButton:
         PromptContentViewWithMoreOptionsButton
 
+    private val kosmos = Kosmos()
+
     @Before
     fun setup() {
-        fingerprintRepository = FakeFingerprintPropertyRepository()
+
+        // Set up default logo info and app customized info
+        whenever(kosmos.packageManager.getApplicationInfo(eq(OP_PACKAGE_NAME_NO_ICON), anyInt()))
+            .thenReturn(applicationInfoNoIcon)
+        whenever(kosmos.packageManager.getApplicationInfo(eq(OP_PACKAGE_NAME), anyInt()))
+            .thenReturn(applicationInfoWithIcon)
+        whenever(
+                kosmos.packageManager.getApplicationInfo(
+                    eq(packageNameForLogoWithOverrides),
+                    anyInt()
+                )
+            )
+            .thenReturn(applicationInfoWithIcon)
+        whenever(
+                kosmos.packageManager.getApplicationInfo(
+                    eq(OP_PACKAGE_NAME_CAN_NOT_BE_FOUND),
+                    anyInt()
+                )
+            )
+            .thenThrow(NameNotFoundException())
+
+        whenever(kosmos.packageManager.getActivityInfo(any(), anyInt())).thenReturn(activityInfo)
+        whenever(kosmos.iconProvider.getIcon(activityInfo)).thenReturn(defaultLogoIconWithOverrides)
+        whenever(kosmos.packageManager.getApplicationIcon(applicationInfoWithIcon))
+            .thenReturn(defaultLogoIcon)
+        whenever(kosmos.packageManager.getApplicationLabel(applicationInfoWithIcon))
+            .thenReturn(defaultLogoDescription)
+        whenever(kosmos.packageManager.getUserBadgedIcon(any(), any())).then { it.getArgument(0) }
+        whenever(kosmos.packageManager.getUserBadgedLabel(any(), any())).then { it.getArgument(0) }
+
+        context.setMockPackageManager(kosmos.packageManager)
+        overrideResource(logoResFromApp, logoDrawableFromAppRes)
+        overrideResource(
+            R.array.biometric_dialog_package_names_for_logo_with_overrides,
+            arrayOf(packageNameForLogoWithOverrides)
+        )
+
+        overrideResource(R.dimen.biometric_dialog_fingerprint_icon_width, mockFingerprintIconWidth)
+        overrideResource(
+            R.dimen.biometric_dialog_fingerprint_icon_height,
+            mockFingerprintIconHeight
+        )
+        overrideResource(R.dimen.biometric_dialog_face_icon_size, mockFaceIconSize)
+
+        kosmos.applicationContext = context
+
+        if (testCase.fingerprint?.isAnyUdfpsType == true) {
+            kosmos.authController = authController
+        }
+
         testCase.fingerprint?.let {
-            fingerprintRepository.setProperties(
+            kosmos.fakeFingerprintPropertyRepository.setProperties(
                 it.sensorId,
                 it.sensorStrength.toSensorStrength(),
                 it.sensorType.toSensorType(),
@@ -186,31 +229,20 @@
                 }
             )
         }
-        promptRepository = FakePromptRepository()
-        displayStateRepository = FakeDisplayStateRepository()
-        displayRepository = FakeDisplayRepository()
-        displayStateInteractor =
-            DisplayStateInteractorImpl(
-                testScope.backgroundScope,
-                mContext,
-                fakeExecutor,
-                displayStateRepository,
-                displayRepository,
-            )
-        udfpsOverlayInteractor =
-            UdfpsOverlayInteractor(
-                context,
-                authController,
-                selectedUserInteractor,
-                testScope.backgroundScope
-            )
-        biometricStatusRepository = FakeBiometricStatusRepository()
-        biometricStatusInteractor =
-            BiometricStatusInteractorImpl(
-                activityTaskManager,
-                biometricStatusRepository,
-                fingerprintRepository
-            )
+
+        kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_0)
+        testCase.fingerprint?.isAnySidefpsType.let {
+            kosmos.displayStateRepository.setIsInRearDisplayMode(testCase.isInRearDisplayMode)
+            if (testCase.isDeviceFolded) {
+                kosmos.promptViewModel.iconViewModel.onConfigurationChanged(
+                    getFoldedConfiguration()
+                )
+            } else {
+                kosmos.promptViewModel.iconViewModel.onConfigurationChanged(
+                    getUnfoldedConfiguration()
+                )
+            }
+        }
 
         promptContentView =
             PromptVerticalListContentView.Builder()
@@ -221,47 +253,29 @@
         promptContentViewWithMoreOptionsButton =
             PromptContentViewWithMoreOptionsButton.Builder()
                 .setDescription("test")
-                .setMoreOptionsButtonListener(fakeExecutor) { _, _ -> }
+                .setMoreOptionsButtonListener(kosmos.fakeExecutor) { _, _ -> }
                 .build()
-
-        // Set up default logo info and app customized info
-        whenever(packageManager.getApplicationInfo(eq(OP_PACKAGE_NAME_NO_ICON), anyInt()))
-            .thenReturn(applicationInfoNoIcon)
-        whenever(packageManager.getApplicationInfo(eq(OP_PACKAGE_NAME), anyInt()))
-            .thenReturn(applicationInfoWithIcon)
-        whenever(packageManager.getApplicationInfo(eq(packageNameForLogoWithOverrides), anyInt()))
-            .thenReturn(applicationInfoWithIcon)
-        whenever(packageManager.getApplicationInfo(eq(OP_PACKAGE_NAME_CAN_NOT_BE_FOUND), anyInt()))
-            .thenThrow(NameNotFoundException())
-
-        whenever(packageManager.getActivityInfo(any(), anyInt())).thenReturn(activityInfo)
-        whenever(iconProvider.getIcon(activityInfo)).thenReturn(defaultLogoIconWithOverrides)
-        whenever(packageManager.getApplicationIcon(applicationInfoWithIcon))
-            .thenReturn(defaultLogoIcon)
-        whenever(packageManager.getApplicationLabel(applicationInfoWithIcon))
-            .thenReturn(defaultLogoDescription)
-        whenever(packageManager.getUserBadgedIcon(any(), any())).then { it.getArgument(0) }
-        whenever(packageManager.getUserBadgedLabel(any(), any())).then { it.getArgument(0) }
-
-        context.setMockPackageManager(packageManager)
-        val resources = context.getOrCreateTestableResources()
-        resources.addOverride(logoResFromApp, logoDrawableFromAppRes)
-        resources.addOverride(
-            R.array.biometric_dialog_package_names_for_logo_with_overrides,
-            arrayOf(packageNameForLogoWithOverrides)
-        )
     }
 
     @Test
     fun start_idle_and_show_authenticating() =
         runGenericTest(doNotStart = true) {
-            val expectedSize =
+            var expectedPromptSize =
                 if (testCase.shouldStartAsImplicitFlow) PromptSize.SMALL else PromptSize.MEDIUM
-            val authenticating by collectLastValue(viewModel.isAuthenticating)
-            val authenticated by collectLastValue(viewModel.isAuthenticated)
-            val modalities by collectLastValue(viewModel.modalities)
-            val message by collectLastValue(viewModel.message)
-            val size by collectLastValue(viewModel.size)
+            val authenticating by collectLastValue(kosmos.promptViewModel.isAuthenticating)
+            val authenticated by collectLastValue(kosmos.promptViewModel.isAuthenticated)
+            val modalities by collectLastValue(kosmos.promptViewModel.modalities)
+            val iconAsset by collectLastValue(kosmos.promptViewModel.iconViewModel.iconAsset)
+            val iconOverlayAsset by
+                collectLastValue(kosmos.promptViewModel.iconViewModel.iconOverlayAsset)
+            val shouldAnimateIconView by
+                collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconView)
+            val shouldAnimateIconOverlay by
+                collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconOverlay)
+            val iconContentDescriptionId by
+                collectLastValue(kosmos.promptViewModel.iconViewModel.contentDescriptionId)
+            val message by collectLastValue(kosmos.promptViewModel.message)
+            val size by collectLastValue(kosmos.promptViewModel.size)
 
             assertThat(authenticating).isFalse()
             assertThat(authenticated?.isNotAuthenticated).isTrue()
@@ -269,131 +283,49 @@
                 assertThat(hasFace).isEqualTo(testCase.face != null)
                 assertThat(hasFingerprint).isEqualTo(testCase.fingerprint != null)
             }
+
             assertThat(message).isEqualTo(PromptMessage.Empty)
-            assertThat(size).isEqualTo(expectedSize)
+            assertThat(size).isEqualTo(expectedPromptSize)
 
-            val startMessage = "here we go"
-            viewModel.showAuthenticating(startMessage, isRetry = false)
+            val forceExplicitFlow =
+                testCase.isCoex && testCase.confirmationRequested ||
+                    testCase.authenticatedByFingerprint
 
-            assertThat(message).isEqualTo(PromptMessage.Help(startMessage))
-            assertThat(authenticating).isTrue()
-            assertThat(authenticated?.isNotAuthenticated).isTrue()
-            assertThat(size).isEqualTo(expectedSize)
-            assertButtonsVisible(negative = expectedSize != PromptSize.SMALL)
-        }
-
-    @Test
-    fun shows_authenticated_with_no_errors() = runGenericTest {
-        // this case can't happen until fingerprint is started
-        // trigger it now since no error has occurred in this test
-        val forceError = testCase.isCoex && testCase.authenticatedByFingerprint
-
-        if (forceError) {
-            assertThat(viewModel.fingerprintStartMode.first())
-                .isEqualTo(FingerprintStartMode.Pending)
-            viewModel.ensureFingerprintHasStarted(isDelayed = true)
-        }
-
-        showAuthenticated(
-            testCase.authenticatedModality,
-            testCase.expectConfirmation(atLeastOneFailure = forceError),
-        )
-    }
-
-    @Test
-    fun set_haptic_on_confirm_when_confirmation_required_otherwise_on_authenticated() =
-        runGenericTest {
-            val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false)
-
-            viewModel.showAuthenticated(testCase.authenticatedModality, 1_000L)
-
-            val confirmHaptics by collectLastValue(viewModel.hapticsToPlay)
-            assertThat(confirmHaptics?.hapticFeedbackConstant)
-                .isEqualTo(
-                    if (expectConfirmation) HapticFeedbackConstants.NO_HAPTICS
-                    else HapticFeedbackConstants.CONFIRM
-                )
-            assertThat(confirmHaptics?.flag)
-                .isEqualTo(
-                    if (expectConfirmation) null
-                    else HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING
-                )
-
-            if (expectConfirmation) {
-                viewModel.confirmAuthenticated()
+            if ((testCase.isCoex && !forceExplicitFlow) || testCase.isFaceOnly) {
+                // Face-only or implicit co-ex auth
+                assertThat(iconAsset).isEqualTo(R.raw.face_dialog_idle_static)
+                assertThat(iconOverlayAsset).isEqualTo(-1)
+                assertThat(shouldAnimateIconView).isEqualTo(false)
+                assertThat(shouldAnimateIconOverlay).isEqualTo(false)
             }
 
-            val confirmedHaptics by collectLastValue(viewModel.hapticsToPlay)
-            assertThat(confirmedHaptics?.hapticFeedbackConstant)
-                .isEqualTo(HapticFeedbackConstants.CONFIRM)
-            assertThat(confirmedHaptics?.flag)
-                .isEqualTo(HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING)
-        }
-
-    @Test
-    fun playSuccessHaptic_SetsConfirmConstant() = runGenericTest {
-        val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false)
-        viewModel.showAuthenticated(testCase.authenticatedModality, 1_000L)
-
-        if (expectConfirmation) {
-            viewModel.confirmAuthenticated()
-        }
-
-        val currentHaptics by collectLastValue(viewModel.hapticsToPlay)
-        assertThat(currentHaptics?.hapticFeedbackConstant)
-            .isEqualTo(HapticFeedbackConstants.CONFIRM)
-        assertThat(currentHaptics?.flag)
-            .isEqualTo(HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING)
-    }
-
-    @Test
-    fun playErrorHaptic_SetsRejectConstant() = runGenericTest {
-        viewModel.showTemporaryError("test", "messageAfterError", false)
-
-        val currentHaptics by collectLastValue(viewModel.hapticsToPlay)
-        assertThat(currentHaptics?.hapticFeedbackConstant).isEqualTo(HapticFeedbackConstants.REJECT)
-        assertThat(currentHaptics?.flag)
-            .isEqualTo(HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING)
-    }
-
-    @Test
-    fun start_idle_and_show_authenticating_iconUpdate() =
-        runGenericTest(doNotStart = true) {
-            val currentRotation by collectLastValue(displayStateInteractor.currentRotation)
-            val iconAsset by collectLastValue(iconViewModel.iconAsset)
-            val iconContentDescriptionId by collectLastValue(iconViewModel.contentDescriptionId)
-            val shouldAnimateIconView by collectLastValue(iconViewModel.shouldAnimateIconView)
-
-            val forceExplicitFlow = testCase.isCoex && testCase.authenticatedByFingerprint
             if (forceExplicitFlow) {
-                viewModel.ensureFingerprintHasStarted(isDelayed = true)
+                expectedPromptSize = PromptSize.MEDIUM
+                kosmos.promptViewModel.ensureFingerprintHasStarted(isDelayed = true)
             }
 
             val startMessage = "here we go"
-            viewModel.showAuthenticating(startMessage, isRetry = false)
+            kosmos.promptViewModel.showAuthenticating(startMessage, isRetry = false)
+            verifyIconSize(forceExplicitFlow)
 
-            if (testCase.isFingerprintOnly) {
-                val iconOverlayAsset by collectLastValue(iconViewModel.iconOverlayAsset)
-                val shouldAnimateIconOverlay by
-                    collectLastValue(iconViewModel.shouldAnimateIconOverlay)
-
+            // Icon asset assertions
+            if ((testCase.isCoex && !forceExplicitFlow) || testCase.isFaceOnly) {
+                // Face-only or implicit co-ex auth
+                assertThat(iconAsset).isEqualTo(R.raw.face_dialog_authenticating)
+                assertThat(iconOverlayAsset).isEqualTo(-1)
+                assertThat(iconContentDescriptionId)
+                    .isEqualTo(R.string.biometric_dialog_face_icon_description_authenticating)
+                assertThat(shouldAnimateIconView).isEqualTo(true)
+                assertThat(shouldAnimateIconOverlay).isEqualTo(false)
+            } else if ((testCase.isCoex && forceExplicitFlow) || testCase.isFingerprintOnly) {
+                // Fingerprint-only or explicit co-ex auth
                 if (testCase.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON) {
-                    val expectedOverlayAsset =
-                        when (currentRotation) {
-                            DisplayRotation.ROTATION_0 ->
-                                R.raw.biometricprompt_fingerprint_to_error_landscape
-                            DisplayRotation.ROTATION_90 ->
-                                R.raw.biometricprompt_symbol_fingerprint_to_error_portrait_topleft
-                            DisplayRotation.ROTATION_180 ->
-                                R.raw.biometricprompt_fingerprint_to_error_landscape
-                            DisplayRotation.ROTATION_270 ->
-                                R.raw
-                                    .biometricprompt_symbol_fingerprint_to_error_portrait_bottomright
-                            else -> throw Exception("invalid rotation")
-                        }
-                    assertThat(iconOverlayAsset).isEqualTo(expectedOverlayAsset)
+                    assertThat(iconAsset).isEqualTo(getSfpsBaseIconAsset())
+                    assertThat(iconOverlayAsset)
+                        .isEqualTo(R.raw.biometricprompt_fingerprint_to_error_landscape)
                     assertThat(iconContentDescriptionId)
                         .isEqualTo(R.string.security_settings_sfps_enroll_find_sensor_message)
+                    assertThat(shouldAnimateIconView).isEqualTo(true)
                     assertThat(shouldAnimateIconOverlay).isEqualTo(false)
                 } else {
                     assertThat(iconAsset)
@@ -406,85 +338,74 @@
                 }
             }
 
-            if (testCase.isFaceOnly) {
-                val expectedIconAsset = R.raw.face_dialog_authenticating
-                assertThat(iconAsset).isEqualTo(expectedIconAsset)
-                assertThat(iconContentDescriptionId)
-                    .isEqualTo(R.string.biometric_dialog_face_icon_description_authenticating)
-                assertThat(shouldAnimateIconView).isEqualTo(true)
-            }
-
-            if (testCase.isCoex) {
-                if (testCase.confirmationRequested || forceExplicitFlow) {
-                    // explicit flow
-                    val iconOverlayAsset by collectLastValue(iconViewModel.iconOverlayAsset)
-                    val shouldAnimateIconOverlay by
-                        collectLastValue(iconViewModel.shouldAnimateIconOverlay)
-
-                    // TODO: Update when SFPS co-ex is implemented
-                    if (testCase.sensorType != FingerprintSensorProperties.TYPE_POWER_BUTTON) {
-                        assertThat(iconAsset)
-                            .isEqualTo(R.raw.fingerprint_dialogue_fingerprint_to_error_lottie)
-                        assertThat(iconOverlayAsset).isEqualTo(-1)
-                        assertThat(iconContentDescriptionId)
-                            .isEqualTo(R.string.fingerprint_dialog_touch_sensor)
-                        assertThat(shouldAnimateIconView).isEqualTo(false)
-                        assertThat(shouldAnimateIconOverlay).isEqualTo(false)
-                    }
-                } else {
-                    // implicit flow
-                    val expectedIconAsset = R.raw.face_dialog_authenticating
-                    assertThat(iconAsset).isEqualTo(expectedIconAsset)
-                    assertThat(iconContentDescriptionId)
-                        .isEqualTo(R.string.biometric_dialog_face_icon_description_authenticating)
-                    assertThat(shouldAnimateIconView).isEqualTo(true)
-                }
-            }
+            assertThat(message).isEqualTo(PromptMessage.Help(startMessage))
+            assertThat(authenticating).isTrue()
+            assertThat(authenticated?.isNotAuthenticated).isTrue()
+            assertThat(size).isEqualTo(expectedPromptSize)
+            assertButtonsVisible(negative = expectedPromptSize != PromptSize.SMALL)
         }
 
     @Test
-    fun start_authenticating_show_and_clear_error_iconUpdate() = runGenericTest {
-        val currentRotation by collectLastValue(displayStateInteractor.currentRotation)
+    fun start_authenticating_show_and_clear_error() = runGenericTest {
+        val iconAsset by collectLastValue(kosmos.promptViewModel.iconViewModel.iconAsset)
+        val iconOverlayAsset by
+            collectLastValue(kosmos.promptViewModel.iconViewModel.iconOverlayAsset)
+        val iconContentDescriptionId by
+            collectLastValue(kosmos.promptViewModel.iconViewModel.contentDescriptionId)
+        val shouldAnimateIconView by
+            collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconView)
+        val shouldAnimateIconOverlay by
+            collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconOverlay)
+        val message by collectLastValue(kosmos.promptViewModel.message)
 
-        val iconAsset by collectLastValue(iconViewModel.iconAsset)
-        val iconContentDescriptionId by collectLastValue(iconViewModel.contentDescriptionId)
-        val shouldAnimateIconView by collectLastValue(iconViewModel.shouldAnimateIconView)
-
-        val forceExplicitFlow = testCase.isCoex && testCase.authenticatedByFingerprint
+        var forceExplicitFlow =
+            testCase.isCoex && testCase.confirmationRequested || testCase.authenticatedByFingerprint
         if (forceExplicitFlow) {
-            viewModel.ensureFingerprintHasStarted(isDelayed = true)
+            kosmos.promptViewModel.ensureFingerprintHasStarted(isDelayed = true)
         }
+        verifyIconSize(forceExplicitFlow)
 
         val errorJob = launch {
-            viewModel.showTemporaryError(
+            kosmos.promptViewModel.showTemporaryError(
                 "so sad",
                 messageAfterError = "",
                 authenticateAfterError = testCase.isFingerprintOnly || testCase.isCoex,
             )
+            forceExplicitFlow = true
             // Usually done by binder
-            iconViewModel.setPreviousIconWasError(true)
-            iconViewModel.setPreviousIconOverlayWasError(true)
+            kosmos.promptViewModel.iconViewModel.setPreviousIconWasError(true)
+            kosmos.promptViewModel.iconViewModel.setPreviousIconOverlayWasError(true)
         }
 
-        if (testCase.isFingerprintOnly) {
-            val iconOverlayAsset by collectLastValue(iconViewModel.iconOverlayAsset)
-            val shouldAnimateIconOverlay by collectLastValue(iconViewModel.shouldAnimateIconOverlay)
+        assertThat(message?.isError).isEqualTo(true)
+        assertThat(message?.message).isEqualTo("so sad")
 
+        // Icon asset assertions
+        if (testCase.isFaceOnly) {
+            // Face-only auth
+            assertThat(iconAsset).isEqualTo(R.raw.face_dialog_dark_to_error)
+            assertThat(iconOverlayAsset).isEqualTo(-1)
+            assertThat(iconContentDescriptionId).isEqualTo(R.string.keyguard_face_failed)
+            assertThat(shouldAnimateIconView).isEqualTo(true)
+            assertThat(shouldAnimateIconOverlay).isEqualTo(false)
+
+            // Clear error, go to idle
+            errorJob.join()
+
+            assertThat(iconAsset).isEqualTo(R.raw.face_dialog_error_to_idle)
+            assertThat(iconOverlayAsset).isEqualTo(-1)
+            assertThat(iconContentDescriptionId)
+                .isEqualTo(R.string.biometric_dialog_face_icon_description_idle)
+            assertThat(shouldAnimateIconView).isEqualTo(true)
+            assertThat(shouldAnimateIconOverlay).isEqualTo(false)
+        } else if ((testCase.isCoex && forceExplicitFlow) || testCase.isFingerprintOnly) {
+            // Fingerprint-only or explicit co-ex auth
             if (testCase.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON) {
-                val expectedOverlayAsset =
-                    when (currentRotation) {
-                        DisplayRotation.ROTATION_0 ->
-                            R.raw.biometricprompt_fingerprint_to_error_landscape
-                        DisplayRotation.ROTATION_90 ->
-                            R.raw.biometricprompt_symbol_fingerprint_to_error_portrait_topleft
-                        DisplayRotation.ROTATION_180 ->
-                            R.raw.biometricprompt_fingerprint_to_error_landscape
-                        DisplayRotation.ROTATION_270 ->
-                            R.raw.biometricprompt_symbol_fingerprint_to_error_portrait_bottomright
-                        else -> throw Exception("invalid rotation")
-                    }
-                assertThat(iconOverlayAsset).isEqualTo(expectedOverlayAsset)
+                assertThat(iconAsset).isEqualTo(getSfpsBaseIconAsset())
+                assertThat(iconOverlayAsset)
+                    .isEqualTo(R.raw.biometricprompt_fingerprint_to_error_landscape)
                 assertThat(iconContentDescriptionId).isEqualTo(R.string.biometric_dialog_try_again)
+                assertThat(shouldAnimateIconView).isEqualTo(true)
                 assertThat(shouldAnimateIconOverlay).isEqualTo(true)
             } else {
                 assertThat(iconAsset)
@@ -499,19 +420,9 @@
             errorJob.join()
 
             if (testCase.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON) {
-                val expectedOverlayAsset =
-                    when (currentRotation) {
-                        DisplayRotation.ROTATION_0 ->
-                            R.raw.biometricprompt_symbol_error_to_fingerprint_landscape
-                        DisplayRotation.ROTATION_90 ->
-                            R.raw.biometricprompt_symbol_error_to_fingerprint_portrait_topleft
-                        DisplayRotation.ROTATION_180 ->
-                            R.raw.biometricprompt_symbol_error_to_fingerprint_landscape
-                        DisplayRotation.ROTATION_270 ->
-                            R.raw.biometricprompt_symbol_error_to_fingerprint_portrait_bottomright
-                        else -> throw Exception("invalid rotation")
-                    }
-                assertThat(iconOverlayAsset).isEqualTo(expectedOverlayAsset)
+                assertThat(iconAsset).isEqualTo(getSfpsBaseIconAsset())
+                assertThat(iconOverlayAsset)
+                    .isEqualTo(R.raw.biometricprompt_symbol_error_to_fingerprint_landscape)
                 assertThat(iconContentDescriptionId)
                     .isEqualTo(R.string.security_settings_sfps_enroll_find_sensor_message)
                 assertThat(shouldAnimateIconOverlay).isEqualTo(true)
@@ -525,89 +436,48 @@
                 assertThat(shouldAnimateIconOverlay).isEqualTo(false)
             }
         }
+    }
 
-        if (testCase.isFaceOnly) {
-            assertThat(iconAsset).isEqualTo(R.drawable.face_dialog_dark_to_error)
-            assertThat(iconContentDescriptionId).isEqualTo(R.string.keyguard_face_failed)
-            assertThat(shouldAnimateIconView).isEqualTo(true)
-
-            // Clear error, go to idle
-            errorJob.join()
-
-            assertThat(iconAsset).isEqualTo(R.drawable.face_dialog_error_to_idle)
-            assertThat(iconContentDescriptionId)
-                .isEqualTo(R.string.biometric_dialog_face_icon_description_idle)
-            assertThat(shouldAnimateIconView).isEqualTo(true)
-        }
-
-        if (testCase.isCoex) {
-            val iconOverlayAsset by collectLastValue(iconViewModel.iconOverlayAsset)
-            val shouldAnimateIconOverlay by collectLastValue(iconViewModel.shouldAnimateIconOverlay)
-
-            // TODO: Update when SFPS co-ex is implemented
-            if (testCase.sensorType != FingerprintSensorProperties.TYPE_POWER_BUTTON) {
-                assertThat(iconAsset)
-                    .isEqualTo(R.raw.fingerprint_dialogue_fingerprint_to_error_lottie)
-                assertThat(iconOverlayAsset).isEqualTo(-1)
-                assertThat(iconContentDescriptionId).isEqualTo(R.string.biometric_dialog_try_again)
-                assertThat(shouldAnimateIconView).isEqualTo(true)
-                assertThat(shouldAnimateIconOverlay).isEqualTo(false)
-            }
-
-            // Clear error, restart authenticating
-            errorJob.join()
-
-            if (testCase.sensorType != FingerprintSensorProperties.TYPE_POWER_BUTTON) {
-                assertThat(iconAsset)
-                    .isEqualTo(R.raw.fingerprint_dialogue_error_to_fingerprint_lottie)
-                assertThat(iconOverlayAsset).isEqualTo(-1)
-                assertThat(iconContentDescriptionId)
-                    .isEqualTo(R.string.fingerprint_dialog_touch_sensor)
-                assertThat(shouldAnimateIconView).isEqualTo(true)
-                assertThat(shouldAnimateIconOverlay).isEqualTo(false)
-            }
+    private fun getSfpsBaseIconAsset(): Int {
+        return if (testCase.isInRearDisplayMode) {
+            R.raw.biometricprompt_rear_landscape_base
+        } else if (testCase.isDeviceFolded) {
+            R.raw.biometricprompt_folded_base_default
+        } else {
+            R.raw.biometricprompt_landscape_base
         }
     }
 
     @Test
-    fun shows_authenticated_no_errors_no_confirmation_required_iconUpdate() = runGenericTest {
+    fun shows_authenticated_no_errors_no_confirmation_required() = runGenericTest {
         if (!testCase.confirmationRequested) {
-            val currentRotation by collectLastValue(displayStateInteractor.currentRotation)
+            val iconAsset by collectLastValue(kosmos.promptViewModel.iconViewModel.iconAsset)
+            val iconOverlayAsset by
+                collectLastValue(kosmos.promptViewModel.iconViewModel.iconOverlayAsset)
+            val iconContentDescriptionId by
+                collectLastValue(kosmos.promptViewModel.iconViewModel.contentDescriptionId)
+            val shouldAnimateIconView by
+                collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconView)
+            val shouldAnimateIconOverlay by
+                collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconOverlay)
+            verifyIconSize()
 
-            val iconAsset by collectLastValue(iconViewModel.iconAsset)
-            val iconContentDescriptionId by collectLastValue(iconViewModel.contentDescriptionId)
-            val shouldAnimateIconView by collectLastValue(iconViewModel.shouldAnimateIconView)
-
-            viewModel.showAuthenticated(
+            kosmos.promptViewModel.showAuthenticated(
                 modality = testCase.authenticatedModality,
                 dismissAfterDelay = DELAY
             )
 
             if (testCase.isFingerprintOnly) {
-                val iconOverlayAsset by collectLastValue(iconViewModel.iconOverlayAsset)
-                val shouldAnimateIconOverlay by
-                    collectLastValue(iconViewModel.shouldAnimateIconOverlay)
-
+                // Fingerprint icon asset assertions
                 if (testCase.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON) {
-                    val expectedOverlayAsset =
-                        when (currentRotation) {
-                            DisplayRotation.ROTATION_0 ->
-                                R.raw.biometricprompt_symbol_fingerprint_to_success_landscape
-                            DisplayRotation.ROTATION_90 ->
-                                R.raw.biometricprompt_symbol_fingerprint_to_success_portrait_topleft
-                            DisplayRotation.ROTATION_180 ->
-                                R.raw.biometricprompt_symbol_fingerprint_to_success_landscape
-                            DisplayRotation.ROTATION_270 ->
-                                R.raw
-                                    .biometricprompt_symbol_fingerprint_to_success_portrait_bottomright
-                            else -> throw Exception("invalid rotation")
-                        }
-                    assertThat(iconOverlayAsset).isEqualTo(expectedOverlayAsset)
+                    assertThat(iconAsset).isEqualTo(getSfpsBaseIconAsset())
+                    assertThat(iconOverlayAsset)
+                        .isEqualTo(R.raw.biometricprompt_symbol_fingerprint_to_success_landscape)
                     assertThat(iconContentDescriptionId)
                         .isEqualTo(R.string.security_settings_sfps_enroll_find_sensor_message)
+                    assertThat(shouldAnimateIconView).isEqualTo(true)
                     assertThat(shouldAnimateIconOverlay).isEqualTo(true)
                 } else {
-                    val isAuthenticated by collectLastValue(viewModel.isAuthenticated)
                     assertThat(iconAsset)
                         .isEqualTo(R.raw.fingerprint_dialogue_fingerprint_to_success_lottie)
                     assertThat(iconOverlayAsset).isEqualTo(-1)
@@ -616,47 +486,52 @@
                     assertThat(shouldAnimateIconView).isEqualTo(true)
                     assertThat(shouldAnimateIconOverlay).isEqualTo(false)
                 }
-            }
-
-            // If co-ex, using implicit flow (explicit flow always requires confirmation)
-            if (testCase.isFaceOnly || testCase.isCoex) {
-                assertThat(iconAsset).isEqualTo(R.drawable.face_dialog_dark_to_checkmark)
+            } else if (testCase.isFaceOnly || testCase.isCoex) {
+                // Face icon asset assertions
+                // If co-ex, use implicit flow (explicit flow always requires confirmation)
+                assertThat(iconAsset).isEqualTo(R.raw.face_dialog_dark_to_checkmark)
+                assertThat(iconOverlayAsset).isEqualTo(-1)
                 assertThat(iconContentDescriptionId)
                     .isEqualTo(R.string.biometric_dialog_face_icon_description_authenticated)
                 assertThat(shouldAnimateIconView).isEqualTo(true)
+                assertThat(shouldAnimateIconOverlay).isEqualTo(false)
             }
         }
     }
 
     @Test
-    fun shows_pending_confirmation_iconUpdate() = runGenericTest {
+    fun shows_pending_confirmation() = runGenericTest {
         if (
             (testCase.isFaceOnly || testCase.isCoex) &&
                 testCase.authenticatedByFace &&
                 testCase.confirmationRequested
         ) {
-            val iconAsset by collectLastValue(iconViewModel.iconAsset)
-            val iconContentDescriptionId by collectLastValue(iconViewModel.contentDescriptionId)
-            val shouldAnimateIconView by collectLastValue(iconViewModel.shouldAnimateIconView)
+            val iconAsset by collectLastValue(kosmos.promptViewModel.iconViewModel.iconAsset)
+            val iconOverlayAsset by
+                collectLastValue(kosmos.promptViewModel.iconViewModel.iconOverlayAsset)
+            val iconContentDescriptionId by
+                collectLastValue(kosmos.promptViewModel.iconViewModel.contentDescriptionId)
+            val shouldAnimateIconView by
+                collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconView)
+            val shouldAnimateIconOverlay by
+                collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconOverlay)
 
-            viewModel.showAuthenticated(
+            val forceExplicitFlow = testCase.isCoex && testCase.confirmationRequested
+            verifyIconSize(forceExplicitFlow = forceExplicitFlow)
+
+            kosmos.promptViewModel.showAuthenticated(
                 modality = testCase.authenticatedModality,
                 dismissAfterDelay = DELAY
             )
 
             if (testCase.isFaceOnly) {
-                assertThat(iconAsset).isEqualTo(R.drawable.face_dialog_wink_from_dark)
+                assertThat(iconAsset).isEqualTo(R.raw.face_dialog_wink_from_dark)
+                assertThat(iconOverlayAsset).isEqualTo(-1)
                 assertThat(iconContentDescriptionId)
                     .isEqualTo(R.string.biometric_dialog_face_icon_description_authenticated)
                 assertThat(shouldAnimateIconView).isEqualTo(true)
-            }
-
-            // explicit flow because confirmation requested
-            if (testCase.isCoex) {
-                val iconOverlayAsset by collectLastValue(iconViewModel.iconOverlayAsset)
-                val shouldAnimateIconOverlay by
-                    collectLastValue(iconViewModel.shouldAnimateIconOverlay)
-
+                assertThat(shouldAnimateIconOverlay).isEqualTo(false)
+            } else if (testCase.isCoex) { // explicit flow, confirmation requested
                 // TODO: Update when SFPS co-ex is implemented
                 if (testCase.sensorType != FingerprintSensorProperties.TYPE_POWER_BUTTON) {
                     assertThat(iconAsset)
@@ -678,30 +553,36 @@
                 testCase.authenticatedByFace &&
                 testCase.confirmationRequested
         ) {
-            val iconAsset by collectLastValue(iconViewModel.iconAsset)
-            val iconContentDescriptionId by collectLastValue(iconViewModel.contentDescriptionId)
-            val shouldAnimateIconView by collectLastValue(iconViewModel.shouldAnimateIconView)
+            val iconAsset by collectLastValue(kosmos.promptViewModel.iconViewModel.iconAsset)
+            val iconOverlayAsset by
+                collectLastValue(kosmos.promptViewModel.iconViewModel.iconOverlayAsset)
+            val iconContentDescriptionId by
+                collectLastValue(kosmos.promptViewModel.iconViewModel.contentDescriptionId)
+            val shouldAnimateIconView by
+                collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconView)
+            val shouldAnimateIconOverlay by
+                collectLastValue(kosmos.promptViewModel.iconViewModel.shouldAnimateIconOverlay)
+            val forceExplicitFlow = testCase.isCoex && testCase.confirmationRequested
+            verifyIconSize(forceExplicitFlow = forceExplicitFlow)
 
-            viewModel.showAuthenticated(
+            kosmos.promptViewModel.showAuthenticated(
                 modality = testCase.authenticatedModality,
                 dismissAfterDelay = DELAY
             )
 
-            viewModel.confirmAuthenticated()
+            kosmos.promptViewModel.confirmAuthenticated()
 
             if (testCase.isFaceOnly) {
-                assertThat(iconAsset).isEqualTo(R.drawable.face_dialog_dark_to_checkmark)
+                assertThat(iconAsset).isEqualTo(R.raw.face_dialog_dark_to_checkmark)
+                assertThat(iconOverlayAsset).isEqualTo(-1)
                 assertThat(iconContentDescriptionId)
                     .isEqualTo(R.string.biometric_dialog_face_icon_description_confirmed)
                 assertThat(shouldAnimateIconView).isEqualTo(true)
+                assertThat(shouldAnimateIconOverlay).isEqualTo(false)
             }
 
             // explicit flow because confirmation requested
             if (testCase.isCoex) {
-                val iconOverlayAsset by collectLastValue(iconViewModel.iconOverlayAsset)
-                val shouldAnimateIconOverlay by
-                    collectLastValue(iconViewModel.shouldAnimateIconOverlay)
-
                 // TODO: Update when SFPS co-ex is implemented
                 if (testCase.sensorType != FingerprintSensorProperties.TYPE_POWER_BUTTON) {
                     assertThat(iconAsset)
@@ -717,19 +598,119 @@
     }
 
     @Test
-    fun sfpsIconUpdates_onConfigurationChanged() = runGenericTest {
-        if (testCase.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON) {
-            val testConfig = Configuration()
-            val folded = INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP - 1
-            val unfolded = INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP + 1
-            val currentIcon by collectLastValue(iconViewModel.iconAsset)
+    fun shows_authenticated_with_no_errors() = runGenericTest {
+        // this case can't happen until fingerprint is started
+        // trigger it now since no error has occurred in this test
+        val forceError = testCase.isCoex && testCase.authenticatedByFingerprint
 
-            testConfig.smallestScreenWidthDp = folded
-            iconViewModel.onConfigurationChanged(testConfig)
+        if (forceError) {
+            assertThat(kosmos.promptViewModel.fingerprintStartMode.first())
+                .isEqualTo(FingerprintStartMode.Pending)
+            kosmos.promptViewModel.ensureFingerprintHasStarted(isDelayed = true)
+        }
+
+        showAuthenticated(
+            testCase.authenticatedModality,
+            testCase.expectConfirmation(atLeastOneFailure = forceError),
+        )
+    }
+
+    // Verifies expected icon sizes for all modalities
+    private fun TestScope.verifyIconSize(forceExplicitFlow: Boolean = false) {
+        val iconSize by collectLastValue(kosmos.promptViewModel.iconSize)
+        if ((testCase.isCoex && !forceExplicitFlow) || testCase.isFaceOnly) {
+            // Face-only or implicit co-ex auth
+            assertThat(iconSize).isEqualTo(Pair(mockFaceIconSize, mockFaceIconSize))
+        } else if ((testCase.isCoex && forceExplicitFlow) || testCase.isFingerprintOnly) {
+            // Fingerprint-only or explicit co-ex auth
+            if (testCase.fingerprint?.isAnyUdfpsType == true) {
+                val udfpsOverlayParams by
+                    collectLastValue(kosmos.promptViewModel.udfpsOverlayParams)
+                val expectedUdfpsOverlayParams = mockUdfpsOverlayParams()
+                assertThat(udfpsOverlayParams).isEqualTo(expectedUdfpsOverlayParams)
+
+                assertThat(iconSize)
+                    .isEqualTo(
+                        Pair(
+                            expectedUdfpsOverlayParams.sensorBounds.width(),
+                            expectedUdfpsOverlayParams.sensorBounds.height()
+                        )
+                    )
+            } else {
+                assertThat(iconSize)
+                    .isEqualTo(Pair(mockFingerprintIconWidth, mockFingerprintIconHeight))
+            }
+        }
+    }
+
+    @Test
+    fun set_haptic_on_confirm_when_confirmation_required_otherwise_on_authenticated() =
+        runGenericTest {
+            val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false)
+
+            kosmos.promptViewModel.showAuthenticated(testCase.authenticatedModality, 1_000L)
+
+            val confirmHaptics by collectLastValue(kosmos.promptViewModel.hapticsToPlay)
+            assertThat(confirmHaptics?.hapticFeedbackConstant)
+                .isEqualTo(
+                    if (expectConfirmation) HapticFeedbackConstants.NO_HAPTICS
+                    else HapticFeedbackConstants.CONFIRM
+                )
+            assertThat(confirmHaptics?.flag)
+                .isEqualTo(
+                    if (expectConfirmation) null
+                    else HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING
+                )
+
+            if (expectConfirmation) {
+                kosmos.promptViewModel.confirmAuthenticated()
+            }
+
+            val confirmedHaptics by collectLastValue(kosmos.promptViewModel.hapticsToPlay)
+            assertThat(confirmedHaptics?.hapticFeedbackConstant)
+                .isEqualTo(HapticFeedbackConstants.CONFIRM)
+            assertThat(confirmedHaptics?.flag)
+                .isEqualTo(HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING)
+        }
+
+    @Test
+    fun playSuccessHaptic_SetsConfirmConstant() = runGenericTest {
+        val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false)
+        kosmos.promptViewModel.showAuthenticated(testCase.authenticatedModality, 1_000L)
+
+        if (expectConfirmation) {
+            kosmos.promptViewModel.confirmAuthenticated()
+        }
+
+        val currentHaptics by collectLastValue(kosmos.promptViewModel.hapticsToPlay)
+        assertThat(currentHaptics?.hapticFeedbackConstant)
+            .isEqualTo(HapticFeedbackConstants.CONFIRM)
+        assertThat(currentHaptics?.flag)
+            .isEqualTo(HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING)
+    }
+
+    @Test
+    fun playErrorHaptic_SetsRejectConstant() = runGenericTest {
+        kosmos.promptViewModel.showTemporaryError("test", "messageAfterError", false)
+
+        val currentHaptics by collectLastValue(kosmos.promptViewModel.hapticsToPlay)
+        assertThat(currentHaptics?.hapticFeedbackConstant).isEqualTo(HapticFeedbackConstants.REJECT)
+        assertThat(currentHaptics?.flag)
+            .isEqualTo(HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING)
+    }
+
+    @Test
+    fun sfpsIconUpdates_onFoldConfigurationChanged() = runGenericTest {
+        if (
+            testCase.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON &&
+                !testCase.isInRearDisplayMode
+        ) {
+            val currentIcon by collectLastValue(kosmos.promptViewModel.iconViewModel.iconAsset)
+
+            kosmos.promptViewModel.iconViewModel.onConfigurationChanged(getFoldedConfiguration())
             val foldedIcon = currentIcon
 
-            testConfig.smallestScreenWidthDp = unfolded
-            iconViewModel.onConfigurationChanged(testConfig)
+            kosmos.promptViewModel.iconViewModel.onConfigurationChanged(getUnfoldedConfiguration())
             val unfoldedIcon = currentIcon
 
             assertThat(foldedIcon).isNotEqualTo(unfoldedIcon)
@@ -739,18 +720,18 @@
     @Test
     fun sfpsIconUpdates_onRotation() = runGenericTest {
         if (testCase.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON) {
-            val currentIcon by collectLastValue(iconViewModel.iconAsset)
+            val currentIcon by collectLastValue(kosmos.promptViewModel.iconViewModel.iconAsset)
 
-            displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_0)
+            kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_0)
             val iconRotation0 = currentIcon
 
-            displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_90)
+            kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_90)
             val iconRotation90 = currentIcon
 
-            displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_180)
+            kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_180)
             val iconRotation180 = currentIcon
 
-            displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_270)
+            kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_270)
             val iconRotation270 = currentIcon
 
             assertThat(iconRotation0).isEqualTo(iconRotation180)
@@ -762,12 +743,12 @@
     @Test
     fun sfpsIconUpdates_onRearDisplayMode() = runGenericTest {
         if (testCase.sensorType == FingerprintSensorProperties.TYPE_POWER_BUTTON) {
-            val currentIcon by collectLastValue(iconViewModel.iconAsset)
+            val currentIcon by collectLastValue(kosmos.promptViewModel.iconViewModel.iconAsset)
 
-            displayStateRepository.setIsInRearDisplayMode(false)
+            kosmos.displayStateRepository.setIsInRearDisplayMode(false)
             val iconNotRearDisplayMode = currentIcon
 
-            displayStateRepository.setIsInRearDisplayMode(true)
+            kosmos.displayStateRepository.setIsInRearDisplayMode(true)
             val iconRearDisplayMode = currentIcon
 
             assertThat(iconNotRearDisplayMode).isNotEqualTo(iconRearDisplayMode)
@@ -778,10 +759,10 @@
         authenticatedModality: BiometricModality,
         expectConfirmation: Boolean,
     ) {
-        val authenticating by collectLastValue(viewModel.isAuthenticating)
-        val authenticated by collectLastValue(viewModel.isAuthenticated)
-        val fpStartMode by collectLastValue(viewModel.fingerprintStartMode)
-        val size by collectLastValue(viewModel.size)
+        val authenticating by collectLastValue(kosmos.promptViewModel.isAuthenticating)
+        val authenticated by collectLastValue(kosmos.promptViewModel.isAuthenticated)
+        val fpStartMode by collectLastValue(kosmos.promptViewModel.fingerprintStartMode)
+        val size by collectLastValue(kosmos.promptViewModel.size)
 
         val authWithSmallPrompt =
             testCase.shouldStartAsImplicitFlow &&
@@ -791,7 +772,7 @@
         assertThat(size).isEqualTo(if (authWithSmallPrompt) PromptSize.SMALL else PromptSize.MEDIUM)
         assertButtonsVisible(negative = !authWithSmallPrompt)
 
-        viewModel.showAuthenticated(authenticatedModality, DELAY)
+        kosmos.promptViewModel.showAuthenticated(authenticatedModality, DELAY)
 
         assertThat(authenticated?.isAuthenticated).isTrue()
         assertThat(authenticated?.delay).isEqualTo(DELAY)
@@ -822,50 +803,49 @@
 
     @Test
     fun set_haptic_on_errors() = runGenericTest {
-        viewModel.showTemporaryError(
+        kosmos.promptViewModel.showTemporaryError(
             "so sad",
             messageAfterError = "",
             authenticateAfterError = false,
             hapticFeedback = true,
         )
 
-        val haptics by collectLastValue(viewModel.hapticsToPlay)
+        val haptics by collectLastValue(kosmos.promptViewModel.hapticsToPlay)
         assertThat(haptics?.hapticFeedbackConstant).isEqualTo(HapticFeedbackConstants.REJECT)
         assertThat(haptics?.flag).isEqualTo(HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING)
     }
 
     @Test
     fun plays_haptic_on_errors_unless_skipped() = runGenericTest {
-        viewModel.showTemporaryError(
+        kosmos.promptViewModel.showTemporaryError(
             "still sad",
             messageAfterError = "",
             authenticateAfterError = false,
             hapticFeedback = false,
         )
 
-        val haptics by collectLastValue(viewModel.hapticsToPlay)
+        val haptics by collectLastValue(kosmos.promptViewModel.hapticsToPlay)
         assertThat(haptics?.hapticFeedbackConstant).isEqualTo(HapticFeedbackConstants.NO_HAPTICS)
     }
 
     @Test
     fun plays_haptic_on_error_after_auth_when_confirmation_needed() = runGenericTest {
         val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false)
-        viewModel.showAuthenticated(testCase.authenticatedModality, 0)
+        kosmos.promptViewModel.showAuthenticated(testCase.authenticatedModality, 0)
 
-        viewModel.showTemporaryError(
+        kosmos.promptViewModel.showTemporaryError(
             "still sad",
             messageAfterError = "",
             authenticateAfterError = false,
             hapticFeedback = true,
         )
 
-        val haptics by collectLastValue(viewModel.hapticsToPlay)
+        val haptics by collectLastValue(kosmos.promptViewModel.hapticsToPlay)
         if (expectConfirmation) {
             assertThat(haptics?.hapticFeedbackConstant).isEqualTo(HapticFeedbackConstants.REJECT)
             assertThat(haptics?.flag).isEqualTo(HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING)
         } else {
-            assertThat(haptics?.hapticFeedbackConstant)
-                .isEqualTo(HapticFeedbackConstants.CONFIRM)
+            assertThat(haptics?.hapticFeedbackConstant).isEqualTo(HapticFeedbackConstants.CONFIRM)
         }
     }
 
@@ -875,15 +855,15 @@
         block: suspend TestScope.() -> Unit = {},
     ) {
         val errorMessage = "oh no!"
-        val authenticating by collectLastValue(viewModel.isAuthenticating)
-        val authenticated by collectLastValue(viewModel.isAuthenticated)
-        val message by collectLastValue(viewModel.message)
-        val messageVisible by collectLastValue(viewModel.isIndicatorMessageVisible)
-        val size by collectLastValue(viewModel.size)
-        val canTryAgainNow by collectLastValue(viewModel.canTryAgainNow)
+        val authenticating by collectLastValue(kosmos.promptViewModel.isAuthenticating)
+        val authenticated by collectLastValue(kosmos.promptViewModel.isAuthenticated)
+        val message by collectLastValue(kosmos.promptViewModel.message)
+        val messageVisible by collectLastValue(kosmos.promptViewModel.isIndicatorMessageVisible)
+        val size by collectLastValue(kosmos.promptViewModel.size)
+        val canTryAgainNow by collectLastValue(kosmos.promptViewModel.canTryAgainNow)
 
         val errorJob = launch {
-            viewModel.showTemporaryError(
+            kosmos.promptViewModel.showTemporaryError(
                 errorMessage,
                 authenticateAfterError = restart,
                 messageAfterError = helpAfterError,
@@ -913,13 +893,13 @@
 
     @Test
     fun no_errors_or_temporary_help_after_authenticated() = runGenericTest {
-        val authenticating by collectLastValue(viewModel.isAuthenticating)
-        val authenticated by collectLastValue(viewModel.isAuthenticated)
-        val message by collectLastValue(viewModel.message)
-        val messageIsShowing by collectLastValue(viewModel.isIndicatorMessageVisible)
-        val canTryAgain by collectLastValue(viewModel.canTryAgainNow)
+        val authenticating by collectLastValue(kosmos.promptViewModel.isAuthenticating)
+        val authenticated by collectLastValue(kosmos.promptViewModel.isAuthenticated)
+        val message by collectLastValue(kosmos.promptViewModel.message)
+        val messageIsShowing by collectLastValue(kosmos.promptViewModel.isIndicatorMessageVisible)
+        val canTryAgain by collectLastValue(kosmos.promptViewModel.canTryAgainNow)
 
-        viewModel.showAuthenticated(testCase.authenticatedModality, 0)
+        kosmos.promptViewModel.showAuthenticated(testCase.authenticatedModality, 0)
 
         val verifyNoError = {
             assertThat(authenticating).isFalse()
@@ -929,7 +909,7 @@
         }
 
         val errorJob = launch {
-            viewModel.showTemporaryError(
+            kosmos.promptViewModel.showTemporaryError(
                 "error",
                 messageAfterError = "",
                 authenticateAfterError = false,
@@ -939,14 +919,14 @@
         errorJob.join()
         verifyNoError()
 
-        val helpJob = launch { viewModel.showTemporaryHelp("hi") }
+        val helpJob = launch { kosmos.promptViewModel.showTemporaryHelp("hi") }
         verifyNoError()
         helpJob.join()
         verifyNoError()
 
         // persistent help is allowed
         val stickyHelpMessage = "blah"
-        viewModel.showHelp(stickyHelpMessage)
+        kosmos.promptViewModel.showHelp(stickyHelpMessage)
         assertThat(authenticating).isFalse()
         assertThat(authenticated?.isAuthenticated).isTrue()
         assertThat(message).isEqualTo(PromptMessage.Help(stickyHelpMessage))
@@ -955,11 +935,11 @@
 
     @Test
     fun suppress_temporary_error() = runGenericTest {
-        val messages by collectValues(viewModel.message)
+        val messages by collectValues(kosmos.promptViewModel.message)
 
         for (error in listOf("never", "see", "me")) {
             launch {
-                viewModel.showTemporaryError(
+                kosmos.promptViewModel.showTemporaryError(
                     error,
                     messageAfterError = "or me",
                     authenticateAfterError = false,
@@ -984,11 +964,11 @@
         val errors = listOf("woot", "oh yeah", "nope")
         val afterSuffix = "(after)"
         val expectedErrorMessage = if (suppress) errors.first() else errors.last()
-        val messages by collectValues(viewModel.message)
+        val messages by collectValues(kosmos.promptViewModel.message)
 
         for (error in errors) {
             launch {
-                viewModel.showTemporaryError(
+                kosmos.promptViewModel.showTemporaryError(
                     error,
                     messageAfterError = "$error $afterSuffix",
                     authenticateAfterError = false,
@@ -1017,15 +997,15 @@
 
     @Test
     fun authenticated_at_most_once_same_modality() = runGenericTest {
-        val authenticating by collectLastValue(viewModel.isAuthenticating)
-        val authenticated by collectLastValue(viewModel.isAuthenticated)
+        val authenticating by collectLastValue(kosmos.promptViewModel.isAuthenticating)
+        val authenticated by collectLastValue(kosmos.promptViewModel.isAuthenticated)
 
-        viewModel.showAuthenticated(testCase.authenticatedModality, 0)
+        kosmos.promptViewModel.showAuthenticated(testCase.authenticatedModality, 0)
 
         assertThat(authenticating).isFalse()
         assertThat(authenticated?.isAuthenticated).isTrue()
 
-        viewModel.showAuthenticated(testCase.authenticatedModality, 0)
+        kosmos.promptViewModel.showAuthenticated(testCase.authenticatedModality, 0)
 
         assertThat(authenticating).isFalse()
         assertThat(authenticated?.isAuthenticated).isTrue()
@@ -1033,15 +1013,15 @@
 
     @Test
     fun authenticating_cannot_restart_after_authenticated() = runGenericTest {
-        val authenticating by collectLastValue(viewModel.isAuthenticating)
-        val authenticated by collectLastValue(viewModel.isAuthenticated)
+        val authenticating by collectLastValue(kosmos.promptViewModel.isAuthenticating)
+        val authenticated by collectLastValue(kosmos.promptViewModel.isAuthenticated)
 
-        viewModel.showAuthenticated(testCase.authenticatedModality, 0)
+        kosmos.promptViewModel.showAuthenticated(testCase.authenticatedModality, 0)
 
         assertThat(authenticating).isFalse()
         assertThat(authenticated?.isAuthenticated).isTrue()
 
-        viewModel.showAuthenticating("again!")
+        kosmos.promptViewModel.showAuthenticating("again!")
 
         assertThat(authenticating).isFalse()
         assertThat(authenticated?.isAuthenticated).isTrue()
@@ -1051,13 +1031,13 @@
     fun confirm_authentication() = runGenericTest {
         val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false)
 
-        viewModel.showAuthenticated(testCase.authenticatedModality, 0)
+        kosmos.promptViewModel.showAuthenticated(testCase.authenticatedModality, 0)
 
-        val authenticating by collectLastValue(viewModel.isAuthenticating)
-        val authenticated by collectLastValue(viewModel.isAuthenticated)
-        val message by collectLastValue(viewModel.message)
-        val size by collectLastValue(viewModel.size)
-        val canTryAgain by collectLastValue(viewModel.canTryAgainNow)
+        val authenticating by collectLastValue(kosmos.promptViewModel.isAuthenticating)
+        val authenticated by collectLastValue(kosmos.promptViewModel.isAuthenticated)
+        val message by collectLastValue(kosmos.promptViewModel.message)
+        val size by collectLastValue(kosmos.promptViewModel.size)
+        val canTryAgain by collectLastValue(kosmos.promptViewModel.canTryAgainNow)
 
         assertThat(authenticated?.needsUserConfirmation).isEqualTo(expectConfirmation)
         if (expectConfirmation) {
@@ -1067,7 +1047,7 @@
                 confirm = true,
             )
 
-            viewModel.confirmAuthenticated()
+            kosmos.promptViewModel.confirmAuthenticated()
             assertThat(message).isEqualTo(PromptMessage.Empty)
             assertButtonsVisible()
         }
@@ -1081,13 +1061,13 @@
     fun second_authentication_acts_as_confirmation() = runGenericTest {
         val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false)
 
-        viewModel.showAuthenticated(testCase.authenticatedModality, 0)
+        kosmos.promptViewModel.showAuthenticated(testCase.authenticatedModality, 0)
 
-        val authenticating by collectLastValue(viewModel.isAuthenticating)
-        val authenticated by collectLastValue(viewModel.isAuthenticated)
-        val message by collectLastValue(viewModel.message)
-        val size by collectLastValue(viewModel.size)
-        val canTryAgain by collectLastValue(viewModel.canTryAgainNow)
+        val authenticating by collectLastValue(kosmos.promptViewModel.isAuthenticating)
+        val authenticated by collectLastValue(kosmos.promptViewModel.isAuthenticated)
+        val message by collectLastValue(kosmos.promptViewModel.message)
+        val size by collectLastValue(kosmos.promptViewModel.size)
+        val canTryAgain by collectLastValue(kosmos.promptViewModel.canTryAgainNow)
 
         assertThat(authenticated?.needsUserConfirmation).isEqualTo(expectConfirmation)
         if (expectConfirmation) {
@@ -1098,7 +1078,7 @@
             )
 
             if (testCase.modalities.hasSfps) {
-                viewModel.showAuthenticated(BiometricModality.Fingerprint, 0)
+                kosmos.promptViewModel.showAuthenticated(BiometricModality.Fingerprint, 0)
                 assertThat(message).isEqualTo(PromptMessage.Empty)
                 assertButtonsVisible()
             }
@@ -1114,15 +1094,15 @@
         val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false)
 
         if (testCase.isCoex) {
-            viewModel.onOverlayTouch(obtainMotionEvent(MotionEvent.ACTION_DOWN))
+            kosmos.promptViewModel.onOverlayTouch(obtainMotionEvent(MotionEvent.ACTION_DOWN))
         }
-        viewModel.showAuthenticated(testCase.authenticatedModality, 0)
+        kosmos.promptViewModel.showAuthenticated(testCase.authenticatedModality, 0)
 
-        val authenticating by collectLastValue(viewModel.isAuthenticating)
-        val authenticated by collectLastValue(viewModel.isAuthenticated)
-        val message by collectLastValue(viewModel.message)
-        val size by collectLastValue(viewModel.size)
-        val canTryAgain by collectLastValue(viewModel.canTryAgainNow)
+        val authenticating by collectLastValue(kosmos.promptViewModel.isAuthenticating)
+        val authenticated by collectLastValue(kosmos.promptViewModel.isAuthenticated)
+        val message by collectLastValue(kosmos.promptViewModel.message)
+        val size by collectLastValue(kosmos.promptViewModel.size)
+        val canTryAgain by collectLastValue(kosmos.promptViewModel.canTryAgainNow)
 
         assertThat(authenticating).isFalse()
         assertThat(canTryAgain).isFalse()
@@ -1136,7 +1116,7 @@
                     confirm = true,
                 )
 
-                viewModel.confirmAuthenticated()
+                kosmos.promptViewModel.confirmAuthenticated()
             } else if (testCase.isCoex) {
                 assertThat(authenticated?.isAuthenticatedAndConfirmed).isTrue()
             }
@@ -1150,16 +1130,16 @@
         val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false)
 
         if (testCase.isCoex) {
-            viewModel.onOverlayTouch(obtainMotionEvent(MotionEvent.ACTION_DOWN))
-            viewModel.onOverlayTouch(obtainMotionEvent(MotionEvent.ACTION_UP))
+            kosmos.promptViewModel.onOverlayTouch(obtainMotionEvent(MotionEvent.ACTION_DOWN))
+            kosmos.promptViewModel.onOverlayTouch(obtainMotionEvent(MotionEvent.ACTION_UP))
         }
-        viewModel.showAuthenticated(testCase.authenticatedModality, 0)
+        kosmos.promptViewModel.showAuthenticated(testCase.authenticatedModality, 0)
 
-        val authenticating by collectLastValue(viewModel.isAuthenticating)
-        val authenticated by collectLastValue(viewModel.isAuthenticated)
-        val message by collectLastValue(viewModel.message)
-        val size by collectLastValue(viewModel.size)
-        val canTryAgain by collectLastValue(viewModel.canTryAgainNow)
+        val authenticating by collectLastValue(kosmos.promptViewModel.isAuthenticating)
+        val authenticated by collectLastValue(kosmos.promptViewModel.isAuthenticated)
+        val message by collectLastValue(kosmos.promptViewModel.message)
+        val size by collectLastValue(kosmos.promptViewModel.size)
+        val canTryAgain by collectLastValue(kosmos.promptViewModel.canTryAgainNow)
 
         assertThat(authenticated?.needsUserConfirmation).isEqualTo(expectConfirmation)
         if (expectConfirmation) {
@@ -1169,7 +1149,7 @@
                 confirm = true,
             )
 
-            viewModel.confirmAuthenticated()
+            kosmos.promptViewModel.confirmAuthenticated()
             assertThat(message).isEqualTo(PromptMessage.Empty)
             assertButtonsVisible()
         }
@@ -1181,18 +1161,18 @@
 
     @Test
     fun cannot_confirm_unless_authenticated() = runGenericTest {
-        val authenticating by collectLastValue(viewModel.isAuthenticating)
-        val authenticated by collectLastValue(viewModel.isAuthenticated)
+        val authenticating by collectLastValue(kosmos.promptViewModel.isAuthenticating)
+        val authenticated by collectLastValue(kosmos.promptViewModel.isAuthenticated)
 
-        viewModel.confirmAuthenticated()
+        kosmos.promptViewModel.confirmAuthenticated()
         assertThat(authenticating).isTrue()
         assertThat(authenticated?.isNotAuthenticated).isTrue()
 
-        viewModel.showAuthenticated(testCase.authenticatedModality, 0)
+        kosmos.promptViewModel.showAuthenticated(testCase.authenticatedModality, 0)
 
         // reconfirm should be a no-op
-        viewModel.confirmAuthenticated()
-        viewModel.confirmAuthenticated()
+        kosmos.promptViewModel.confirmAuthenticated()
+        kosmos.promptViewModel.confirmAuthenticated()
 
         assertThat(authenticating).isFalse()
         assertThat(authenticated?.isNotAuthenticated).isFalse()
@@ -1201,36 +1181,36 @@
     @Test
     fun shows_help_before_authenticated() = runGenericTest {
         val helpMessage = "please help yourself to some cookies"
-        val message by collectLastValue(viewModel.message)
-        val messageVisible by collectLastValue(viewModel.isIndicatorMessageVisible)
-        val size by collectLastValue(viewModel.size)
+        val message by collectLastValue(kosmos.promptViewModel.message)
+        val messageVisible by collectLastValue(kosmos.promptViewModel.isIndicatorMessageVisible)
+        val size by collectLastValue(kosmos.promptViewModel.size)
 
-        viewModel.showHelp(helpMessage)
+        kosmos.promptViewModel.showHelp(helpMessage)
 
         assertThat(size).isEqualTo(PromptSize.MEDIUM)
         assertThat(message).isEqualTo(PromptMessage.Help(helpMessage))
         assertThat(messageVisible).isTrue()
 
-        assertThat(viewModel.isAuthenticating.first()).isFalse()
-        assertThat(viewModel.isAuthenticated.first().isNotAuthenticated).isTrue()
+        assertThat(kosmos.promptViewModel.isAuthenticating.first()).isFalse()
+        assertThat(kosmos.promptViewModel.isAuthenticated.first().isNotAuthenticated).isTrue()
     }
 
     @Test
     fun shows_help_after_authenticated() = runGenericTest {
         val expectConfirmation = testCase.expectConfirmation(atLeastOneFailure = false)
         val helpMessage = "more cookies please"
-        val authenticating by collectLastValue(viewModel.isAuthenticating)
-        val authenticated by collectLastValue(viewModel.isAuthenticated)
-        val message by collectLastValue(viewModel.message)
-        val messageVisible by collectLastValue(viewModel.isIndicatorMessageVisible)
-        val size by collectLastValue(viewModel.size)
-        val confirmationRequired by collectLastValue(viewModel.isConfirmationRequired)
+        val authenticating by collectLastValue(kosmos.promptViewModel.isAuthenticating)
+        val authenticated by collectLastValue(kosmos.promptViewModel.isAuthenticated)
+        val message by collectLastValue(kosmos.promptViewModel.message)
+        val messageVisible by collectLastValue(kosmos.promptViewModel.isIndicatorMessageVisible)
+        val size by collectLastValue(kosmos.promptViewModel.size)
+        val confirmationRequired by collectLastValue(kosmos.promptViewModel.isConfirmationRequired)
 
         if (testCase.isCoex && testCase.authenticatedByFingerprint) {
-            viewModel.ensureFingerprintHasStarted(isDelayed = true)
+            kosmos.promptViewModel.ensureFingerprintHasStarted(isDelayed = true)
         }
-        viewModel.showAuthenticated(testCase.authenticatedModality, 0)
-        viewModel.showHelp(helpMessage)
+        kosmos.promptViewModel.showAuthenticated(testCase.authenticatedModality, 0)
+        kosmos.promptViewModel.showHelp(helpMessage)
 
         assertThat(size).isEqualTo(PromptSize.MEDIUM)
 
@@ -1250,15 +1230,15 @@
         val errorMessage = "bad"
         val helpMessage = "again?"
         val expectTryAgainButton = testCase.isFaceOnly
-        val authenticating by collectLastValue(viewModel.isAuthenticating)
-        val authenticated by collectLastValue(viewModel.isAuthenticated)
-        val message by collectLastValue(viewModel.message)
-        val messageVisible by collectLastValue(viewModel.isIndicatorMessageVisible)
-        val canTryAgain by collectLastValue(viewModel.canTryAgainNow)
+        val authenticating by collectLastValue(kosmos.promptViewModel.isAuthenticating)
+        val authenticated by collectLastValue(kosmos.promptViewModel.isAuthenticated)
+        val message by collectLastValue(kosmos.promptViewModel.message)
+        val messageVisible by collectLastValue(kosmos.promptViewModel.isIndicatorMessageVisible)
+        val canTryAgain by collectLastValue(kosmos.promptViewModel.canTryAgainNow)
 
-        viewModel.showAuthenticating("go")
+        kosmos.promptViewModel.showAuthenticating("go")
         val errorJob = launch {
-            viewModel.showTemporaryError(
+            kosmos.promptViewModel.showTemporaryError(
                 errorMessage,
                 messageAfterError = helpMessage,
                 authenticateAfterError = false,
@@ -1283,7 +1263,7 @@
         assertButtonsVisible(negative = true, tryAgain = expectTryAgainButton)
 
         val helpMessage2 = "foo"
-        viewModel.showAuthenticating(helpMessage2, isRetry = true)
+        kosmos.promptViewModel.showAuthenticating(helpMessage2, isRetry = true)
         assertThat(authenticating).isTrue()
         assertThat(authenticated?.isAuthenticated).isFalse()
         assertThat(message).isEqualTo(PromptMessage.Help(helpMessage2))
@@ -1293,10 +1273,10 @@
 
     @Test
     fun switch_to_credential_fallback() = runGenericTest {
-        val size by collectLastValue(viewModel.size)
+        val size by collectLastValue(kosmos.promptViewModel.size)
 
         // TODO(b/251476085): remove Spaghetti, migrate logic, and update this test
-        viewModel.onSwitchToCredential()
+        kosmos.promptViewModel.onSwitchToCredential()
 
         assertThat(size).isEqualTo(PromptSize.LARGE)
     }
@@ -1304,15 +1284,15 @@
     @Test
     @EnableFlags(FLAG_BP_TALKBACK)
     fun hint_for_talkback_guidance() = runGenericTest {
-        val hint by collectLastValue(viewModel.accessibilityHint)
+        val hint by collectLastValue(kosmos.promptViewModel.accessibilityHint)
 
         // Touches should fall outside of sensor area
-        whenever(udfpsUtils.getTouchInNativeCoordinates(any(), any(), any()))
+        whenever(kosmos.udfpsUtils.getTouchInNativeCoordinates(any(), any(), any()))
             .thenReturn(Point(0, 0))
-        whenever(udfpsUtils.onTouchOutsideOfSensorArea(any(), any(), any(), any(), any()))
+        whenever(kosmos.udfpsUtils.onTouchOutsideOfSensorArea(any(), any(), any(), any(), any()))
             .thenReturn("Direction")
 
-        viewModel.onAnnounceAccessibilityHint(
+        kosmos.promptViewModel.onAnnounceAccessibilityHint(
             obtainMotionEvent(MotionEvent.ACTION_HOVER_ENTER),
             true
         )
@@ -1328,8 +1308,8 @@
     @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP)
     fun descriptionOverriddenByVerticalListContentView() =
         runGenericTest(description = "test description", contentView = promptContentView) {
-            val contentView by collectLastValue(viewModel.contentView)
-            val description by collectLastValue(viewModel.description)
+            val contentView by collectLastValue(kosmos.promptViewModel.contentView)
+            val description by collectLastValue(kosmos.promptViewModel.description)
 
             assertThat(description).isEqualTo("")
             assertThat(contentView).isEqualTo(promptContentView)
@@ -1342,8 +1322,8 @@
             description = "test description",
             contentView = promptContentViewWithMoreOptionsButton
         ) {
-            val contentView by collectLastValue(viewModel.contentView)
-            val description by collectLastValue(viewModel.description)
+            val contentView by collectLastValue(kosmos.promptViewModel.contentView)
+            val description by collectLastValue(kosmos.promptViewModel.description)
 
             assertThat(description).isEqualTo("")
             assertThat(contentView).isEqualTo(promptContentViewWithMoreOptionsButton)
@@ -1353,8 +1333,8 @@
     @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP)
     fun descriptionWithoutContentView() =
         runGenericTest(description = "test description") {
-            val contentView by collectLastValue(viewModel.contentView)
-            val description by collectLastValue(viewModel.description)
+            val contentView by collectLastValue(kosmos.promptViewModel.contentView)
+            val description by collectLastValue(kosmos.promptViewModel.description)
 
             assertThat(description).isEqualTo("test description")
             assertThat(contentView).isNull()
@@ -1364,7 +1344,7 @@
     @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP)
     fun logo_nullIfPkgNameNotFound() =
         runGenericTest(packageName = OP_PACKAGE_NAME_CAN_NOT_BE_FOUND) {
-            val logo by collectLastValue(viewModel.logo)
+            val logo by collectLastValue(kosmos.promptViewModel.logo)
             assertThat(logo).isNull()
         }
 
@@ -1372,7 +1352,7 @@
     @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP)
     fun logo_defaultWithOverrides() =
         runGenericTest(packageName = packageNameForLogoWithOverrides) {
-            val logo by collectLastValue(viewModel.logo)
+            val logo by collectLastValue(kosmos.promptViewModel.logo)
 
             // 1. PM.getApplicationInfo(packageNameForLogoWithOverrides) is set to return
             // applicationInfoWithIcon with defaultLogoIcon,
@@ -1385,14 +1365,14 @@
     @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP)
     fun logo_defaultIsNull() =
         runGenericTest(packageName = OP_PACKAGE_NAME_NO_ICON) {
-            val logo by collectLastValue(viewModel.logo)
+            val logo by collectLastValue(kosmos.promptViewModel.logo)
             assertThat(logo).isNull()
         }
 
     @Test
     @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP)
     fun logo_default() = runGenericTest {
-        val logo by collectLastValue(viewModel.logo)
+        val logo by collectLastValue(kosmos.promptViewModel.logo)
         assertThat(logo).isEqualTo(defaultLogoIcon)
     }
 
@@ -1401,7 +1381,7 @@
     fun logo_resSetByApp() =
         runGenericTest(logoRes = logoResFromApp) {
             val expectedBitmap = context.getDrawable(logoResFromApp).toBitmap()
-            val logo by collectLastValue(viewModel.logo)
+            val logo by collectLastValue(kosmos.promptViewModel.logo)
             assertThat((logo as BitmapDrawable).bitmap.sameAs(expectedBitmap)).isTrue()
         }
 
@@ -1409,7 +1389,7 @@
     @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP)
     fun logo_bitmapSetByApp() =
         runGenericTest(logoBitmap = logoBitmapFromApp) {
-            val logo by collectLastValue(viewModel.logo)
+            val logo by collectLastValue(kosmos.promptViewModel.logo)
             assertThat((logo as BitmapDrawable).bitmap).isEqualTo(logoBitmapFromApp)
         }
 
@@ -1417,7 +1397,7 @@
     @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP)
     fun logoDescription_emptyIfPkgNameNotFound() =
         runGenericTest(packageName = OP_PACKAGE_NAME_CAN_NOT_BE_FOUND) {
-            val logoDescription by collectLastValue(viewModel.logoDescription)
+            val logoDescription by collectLastValue(kosmos.promptViewModel.logoDescription)
             assertThat(logoDescription).isEqualTo("")
         }
 
@@ -1425,14 +1405,14 @@
     @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP)
     fun logoDescription_defaultIsEmpty() =
         runGenericTest(packageName = OP_PACKAGE_NAME_NO_ICON) {
-            val logoDescription by collectLastValue(viewModel.logoDescription)
+            val logoDescription by collectLastValue(kosmos.promptViewModel.logoDescription)
             assertThat(logoDescription).isEqualTo("")
         }
 
     @Test
     @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP)
     fun logoDescription_default() = runGenericTest {
-        val logoDescription by collectLastValue(viewModel.logoDescription)
+        val logoDescription by collectLastValue(kosmos.promptViewModel.logoDescription)
         assertThat(logoDescription).isEqualTo(defaultLogoDescription)
     }
 
@@ -1440,57 +1420,57 @@
     @EnableFlags(FLAG_CUSTOM_BIOMETRIC_PROMPT, FLAG_CONSTRAINT_BP)
     fun logoDescription_setByApp() =
         runGenericTest(logoDescription = logoDescriptionFromApp) {
-            val logoDescription by collectLastValue(viewModel.logoDescription)
+            val logoDescription by collectLastValue(kosmos.promptViewModel.logoDescription)
             assertThat(logoDescription).isEqualTo(logoDescriptionFromApp)
         }
 
     @Test
     @EnableFlags(FLAG_CONSTRAINT_BP)
     fun position_bottom_rotation0() = runGenericTest {
-        displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_0)
-        val position by collectLastValue(viewModel.position)
+        kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_0)
+        val position by collectLastValue(kosmos.promptViewModel.position)
         assertThat(position).isEqualTo(PromptPosition.Bottom)
     } // TODO(b/335278136): Add test for no sensor landscape
 
     @Test
     @EnableFlags(FLAG_CONSTRAINT_BP)
     fun position_bottom_forceLarge() = runGenericTest {
-        displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_270)
-        viewModel.onSwitchToCredential()
-        val position by collectLastValue(viewModel.position)
+        kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_270)
+        kosmos.promptViewModel.onSwitchToCredential()
+        val position by collectLastValue(kosmos.promptViewModel.position)
         assertThat(position).isEqualTo(PromptPosition.Bottom)
     }
 
     @Test
     @EnableFlags(FLAG_CONSTRAINT_BP)
     fun position_bottom_largeScreen() = runGenericTest {
-        displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_270)
-        displayStateRepository.setIsLargeScreen(true)
-        val position by collectLastValue(viewModel.position)
+        kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_270)
+        kosmos.displayStateRepository.setIsLargeScreen(true)
+        val position by collectLastValue(kosmos.promptViewModel.position)
         assertThat(position).isEqualTo(PromptPosition.Bottom)
     }
 
     @Test
     @EnableFlags(FLAG_CONSTRAINT_BP)
     fun position_right_rotation90() = runGenericTest {
-        displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_90)
-        val position by collectLastValue(viewModel.position)
+        kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_90)
+        val position by collectLastValue(kosmos.promptViewModel.position)
         assertThat(position).isEqualTo(PromptPosition.Right)
     }
 
     @Test
     @EnableFlags(FLAG_CONSTRAINT_BP)
     fun position_left_rotation270() = runGenericTest {
-        displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_270)
-        val position by collectLastValue(viewModel.position)
+        kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_270)
+        val position by collectLastValue(kosmos.promptViewModel.position)
         assertThat(position).isEqualTo(PromptPosition.Left)
     }
 
     @Test
     @EnableFlags(FLAG_CONSTRAINT_BP)
     fun position_top_rotation180() = runGenericTest {
-        displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_180)
-        val position by collectLastValue(viewModel.position)
+        kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_180)
+        val position by collectLastValue(kosmos.promptViewModel.position)
         if (testCase.modalities.hasUdfps) {
             assertThat(position).isEqualTo(PromptPosition.Top)
         } else {
@@ -1501,18 +1481,18 @@
     @Test
     @EnableFlags(FLAG_CONSTRAINT_BP)
     fun guideline_bottom() = runGenericTest {
-        displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_0)
-        val guidelineBounds by collectLastValue(viewModel.guidelineBounds)
+        kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_0)
+        val guidelineBounds by collectLastValue(kosmos.promptViewModel.guidelineBounds)
         assertThat(guidelineBounds).isEqualTo(Rect(0, mediumTopGuidelinePadding, 0, 0))
     } // TODO(b/335278136): Add test for no sensor landscape
 
     @Test
     @EnableFlags(FLAG_CONSTRAINT_BP)
     fun guideline_right() = runGenericTest {
-        displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_90)
+        kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_90)
 
         val isSmall = testCase.shouldStartAsImplicitFlow
-        val guidelineBounds by collectLastValue(viewModel.guidelineBounds)
+        val guidelineBounds by collectLastValue(kosmos.promptViewModel.guidelineBounds)
 
         if (isSmall) {
             assertThat(guidelineBounds).isEqualTo(Rect(-smallHorizontalGuidelinePadding, 0, 0, 0))
@@ -1527,10 +1507,10 @@
     @EnableFlags(FLAG_CONSTRAINT_BP)
     fun guideline_right_onlyShortTitle() =
         runGenericTest(subtitle = "") {
-            displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_90)
+            kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_90)
 
             val isSmall = testCase.shouldStartAsImplicitFlow
-            val guidelineBounds by collectLastValue(viewModel.guidelineBounds)
+            val guidelineBounds by collectLastValue(kosmos.promptViewModel.guidelineBounds)
 
             if (!isSmall && testCase.modalities.hasUdfps) {
                 assertThat(guidelineBounds)
@@ -1541,10 +1521,10 @@
     @Test
     @EnableFlags(FLAG_CONSTRAINT_BP)
     fun guideline_left() = runGenericTest {
-        displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_270)
+        kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_270)
 
         val isSmall = testCase.shouldStartAsImplicitFlow
-        val guidelineBounds by collectLastValue(viewModel.guidelineBounds)
+        val guidelineBounds by collectLastValue(kosmos.promptViewModel.guidelineBounds)
 
         if (isSmall) {
             assertThat(guidelineBounds).isEqualTo(Rect(0, 0, -smallHorizontalGuidelinePadding, 0))
@@ -1559,10 +1539,10 @@
     @EnableFlags(FLAG_CONSTRAINT_BP)
     fun guideline_left_onlyShortTitle() =
         runGenericTest(subtitle = "") {
-            displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_270)
+            kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_270)
 
             val isSmall = testCase.shouldStartAsImplicitFlow
-            val guidelineBounds by collectLastValue(viewModel.guidelineBounds)
+            val guidelineBounds by collectLastValue(kosmos.promptViewModel.guidelineBounds)
 
             if (!isSmall && testCase.modalities.hasUdfps) {
                 assertThat(guidelineBounds)
@@ -1573,8 +1553,8 @@
     @Test
     @EnableFlags(FLAG_CONSTRAINT_BP)
     fun guideline_top() = runGenericTest {
-        displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_180)
-        val guidelineBounds by collectLastValue(viewModel.guidelineBounds)
+        kosmos.displayStateRepository.setCurrentRotation(DisplayRotation.ROTATION_180)
+        val guidelineBounds by collectLastValue(kosmos.promptViewModel.guidelineBounds)
         if (testCase.modalities.hasUdfps) {
             assertThat(guidelineBounds).isEqualTo(Rect(0, 0, 0, 0))
         }
@@ -1582,11 +1562,11 @@
 
     @Test
     fun iconViewLoaded() = runGenericTest {
-        val isIconViewLoaded by collectLastValue(viewModel.isIconViewLoaded)
+        val isIconViewLoaded by collectLastValue(kosmos.promptViewModel.isIconViewLoaded)
         // TODO(b/328677869): Add test for noIcon logic.
         assertThat(isIconViewLoaded).isFalse()
 
-        viewModel.setIsIconViewLoaded(true)
+        kosmos.promptViewModel.setIsIconViewLoaded(true)
 
         assertThat(isIconViewLoaded).isTrue()
     }
@@ -1600,11 +1580,11 @@
         credential: Boolean = false,
     ) {
         runCurrent()
-        assertThat(viewModel.isTryAgainButtonVisible.first()).isEqualTo(tryAgain)
-        assertThat(viewModel.isConfirmButtonVisible.first()).isEqualTo(confirm)
-        assertThat(viewModel.isCancelButtonVisible.first()).isEqualTo(cancel)
-        assertThat(viewModel.isNegativeButtonVisible.first()).isEqualTo(negative)
-        assertThat(viewModel.isCredentialButtonVisible.first()).isEqualTo(credential)
+        assertThat(kosmos.promptViewModel.isTryAgainButtonVisible.first()).isEqualTo(tryAgain)
+        assertThat(kosmos.promptViewModel.isConfirmButtonVisible.first()).isEqualTo(confirm)
+        assertThat(kosmos.promptViewModel.isCancelButtonVisible.first()).isEqualTo(cancel)
+        assertThat(kosmos.promptViewModel.isNegativeButtonVisible.first()).isEqualTo(negative)
+        assertThat(kosmos.promptViewModel.isCredentialButtonVisible.first()).isEqualTo(credential)
     }
 
     private fun runGenericTest(
@@ -1621,30 +1601,10 @@
     ) {
         val topActivity = ComponentName(packageName, "test app")
         runningTaskInfo.topActivity = topActivity
-        whenever(activityTaskManager.getTasks(1)).thenReturn(listOf(runningTaskInfo))
-        selector =
-            PromptSelectorInteractorImpl(
-                fingerprintRepository,
-                displayStateInteractor,
-                promptRepository,
-                lockPatternUtils
-            )
-        selector.resetPrompt(REQUEST_ID)
+        whenever(kosmos.activityTaskManager.getTasks(1)).thenReturn(listOf(runningTaskInfo))
+        kosmos.promptSelectorInteractor.resetPrompt(REQUEST_ID)
 
-        viewModel =
-            PromptViewModel(
-                displayStateInteractor,
-                selector,
-                mContext,
-                udfpsOverlayInteractor,
-                biometricStatusInteractor,
-                udfpsUtils,
-                iconProvider,
-                activityTaskManager
-            )
-        iconViewModel = viewModel.iconViewModel
-
-        selector.initializePrompt(
+        kosmos.promptSelectorInteractor.initializePrompt(
             requireConfirmation = testCase.confirmationRequested,
             allowCredentialFallback = allowCredentialFallback,
             fingerprint = testCase.fingerprint,
@@ -1658,12 +1618,13 @@
             packageName = packageName,
         )
 
-        biometricStatusRepository.setFingerprintAcquiredStatus(
+        kosmos.biometricStatusRepository.setFingerprintAcquiredStatus(
             AcquiredFingerprintAuthenticationStatus(
                 AuthenticationReason.BiometricPromptAuthentication,
                 BiometricFingerprintConstants.FINGERPRINT_ACQUIRED_UNKNOWN
             )
         )
+
         // put the view model in the initial authenticating state, unless explicitly skipped
         val startMode =
             when {
@@ -1673,18 +1634,31 @@
             }
         when (startMode) {
             FingerprintStartMode.Normal -> {
-                viewModel.ensureFingerprintHasStarted(isDelayed = false)
-                viewModel.showAuthenticating()
+                kosmos.promptViewModel.ensureFingerprintHasStarted(isDelayed = false)
+                kosmos.promptViewModel.showAuthenticating()
             }
             FingerprintStartMode.Delayed -> {
-                viewModel.showAuthenticating()
+                kosmos.promptViewModel.showAuthenticating()
             }
             else -> {
                 /* skip */
             }
         }
 
-        testScope.runTest { block() }
+        if (testCase.fingerprint?.isAnyUdfpsType == true) {
+            kosmos.testScope.collectLastValue(kosmos.udfpsOverlayInteractor.udfpsOverlayParams)
+            kosmos.testScope.runCurrent()
+            overrideUdfpsOverlayParams()
+        }
+
+        kosmos.testScope.runTest { block() }
+    }
+
+    private fun overrideUdfpsOverlayParams(isLandscape: Boolean = false) {
+        val authControllerCallback = authController.captureCallback()
+        authControllerCallback.onUdfpsLocationChanged(
+            mockUdfpsOverlayParams(isLandscape = isLandscape)
+        )
     }
 
     /** Obtain a MotionEvent with the specified MotionEvent action constant */
@@ -1705,11 +1679,43 @@
                 TestCase(
                     fingerprint =
                         fingerprintSensorPropertiesInternal(
+                                sensorType = FingerprintSensorProperties.TYPE_REAR
+                            )
+                            .first(),
+                    authenticatedModality = BiometricModality.Fingerprint,
+                ),
+                TestCase(
+                    fingerprint =
+                        fingerprintSensorPropertiesInternal(
                                 strong = true,
                                 sensorType = FingerprintSensorProperties.TYPE_POWER_BUTTON
                             )
                             .first(),
                     authenticatedModality = BiometricModality.Fingerprint,
+                    isInRearDisplayMode = false,
+                    isDeviceFolded = false
+                ),
+                TestCase(
+                    fingerprint =
+                        fingerprintSensorPropertiesInternal(
+                                strong = true,
+                                sensorType = FingerprintSensorProperties.TYPE_POWER_BUTTON
+                            )
+                            .first(),
+                    authenticatedModality = BiometricModality.Fingerprint,
+                    isInRearDisplayMode = false,
+                    isDeviceFolded = true
+                ),
+                TestCase(
+                    fingerprint =
+                        fingerprintSensorPropertiesInternal(
+                                strong = true,
+                                sensorType = FingerprintSensorProperties.TYPE_POWER_BUTTON
+                            )
+                            .first(),
+                    authenticatedModality = BiometricModality.Fingerprint,
+                    isInRearDisplayMode = true,
+                    isDeviceFolded = false
                 ),
                 TestCase(
                     fingerprint =
@@ -1783,6 +1789,8 @@
 internal data class TestCase(
     val fingerprint: FingerprintSensorPropertiesInternal? = null,
     val face: FaceSensorPropertiesInternal? = null,
+    val isInRearDisplayMode: Boolean = false,
+    val isDeviceFolded: Boolean = false,
     val authenticatedModality: BiometricModality,
     val confirmationRequested: Boolean = false,
 ) {
@@ -1791,12 +1799,16 @@
             when {
                 fingerprint != null && face != null -> "coex"
                 fingerprint != null && fingerprint.isAnySidefpsType -> "fingerprint only, sideFps"
-                fingerprint != null && !fingerprint.isAnySidefpsType ->
-                    "fingerprint only, non-sideFps"
+                fingerprint != null && fingerprint.isAnyUdfpsType -> "fingerprint only, udfps"
+                fingerprint != null &&
+                    fingerprint.sensorType == FingerprintSensorProperties.TYPE_REAR ->
+                    "fingerprint only, rearFps"
                 face != null -> "face only"
                 else -> "?"
             }
-        return "[$modality, by: $authenticatedModality, confirm: $confirmationRequested]"
+        return "[$modality, isInRearDisplayMode: $isInRearDisplayMode, " +
+            "isDeviceFolded: $isDeviceFolded, by: $authenticatedModality, " +
+            "confirm: $confirmationRequested]"
     }
 
     fun expectConfirmation(atLeastOneFailure: Boolean): Boolean =
@@ -1872,4 +1884,25 @@
     )
 }
 
+private fun AuthController.captureCallback() =
+    withArgCaptor<AuthController.Callback> {
+        Mockito.verify(this@captureCallback).addCallback(capture())
+    }
+
+/** Get folded device configuration */
+fun getFoldedConfiguration(): Configuration {
+    val testConfig = Configuration()
+    val folded = INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP - 1
+    testConfig.smallestScreenWidthDp = folded
+    return testConfig
+}
+
+/** Get unfolded device configuration */
+fun getUnfoldedConfiguration(): Configuration {
+    val testConfig = Configuration()
+    val unfolded = INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP + 1
+    testConfig.smallestScreenWidthDp = unfolded
+    return testConfig
+}
+
 internal const val INNER_SCREEN_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP = 600
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/composable/BouncerContentTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/composable/BouncerContentTest.kt
index d32d12c..a4936e6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/composable/BouncerContentTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/composable/BouncerContentTest.kt
@@ -37,7 +37,7 @@
 import com.android.systemui.flags.Flags
 import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.motion.createSysUiComposeMotionTestRule
-import com.android.systemui.scene.domain.interactor.sceneContainerStartable
+import com.android.systemui.scene.domain.startable.sceneContainerStartable
 import com.android.systemui.testKosmos
 import org.junit.Before
 import org.junit.Rule
diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardImageLoaderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardImageLoaderTest.kt
index 21516d49..791f1f2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardImageLoaderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardImageLoaderTest.kt
@@ -18,6 +18,7 @@
 import android.content.ContentResolver
 import android.content.Context
 import android.net.Uri
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.whenever
@@ -29,6 +30,7 @@
 import org.junit.Assert.assertNull
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.any
 import org.mockito.ArgumentMatchers.eq
 import org.mockito.Mock
@@ -37,6 +39,7 @@
 
 @SmallTest
 @OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
 class ClipboardImageLoaderTest : SysuiTestCase() {
     @Mock private lateinit var mockContext: Context
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/complication/DreamHomeControlsComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/complication/DreamHomeControlsComplicationTest.java
index ddf69b5..c2173c4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/complication/DreamHomeControlsComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/complication/DreamHomeControlsComplicationTest.java
@@ -132,7 +132,7 @@
     public void complicationAvailability_serviceNotAvailable_noFavorites_doNotAddComplication() {
         final DreamHomeControlsComplication.Registrant registrant =
                 new DreamHomeControlsComplication.Registrant(mComplication,
-                        mDreamOverlayStateController, mControlsComponent, mMonitor, false);
+                        mDreamOverlayStateController, mControlsComponent, mMonitor);
         registrant.start();
 
         setHaveFavorites(false);
@@ -145,7 +145,7 @@
     public void complicationAvailability_serviceAvailable_noFavorites_doNotAddComplication() {
         final DreamHomeControlsComplication.Registrant registrant =
                 new DreamHomeControlsComplication.Registrant(mComplication,
-                        mDreamOverlayStateController, mControlsComponent, mMonitor, false);
+                        mDreamOverlayStateController, mControlsComponent, mMonitor);
         registrant.start();
 
         setHaveFavorites(false);
@@ -158,7 +158,7 @@
     public void complicationAvailability_serviceAvailable_noFavorites_panel_addComplication() {
         final DreamHomeControlsComplication.Registrant registrant =
                 new DreamHomeControlsComplication.Registrant(mComplication,
-                        mDreamOverlayStateController, mControlsComponent, mMonitor, false);
+                        mDreamOverlayStateController, mControlsComponent, mMonitor);
         registrant.start();
 
         setHaveFavorites(false);
@@ -171,7 +171,7 @@
     public void complicationAvailability_serviceNotAvailable_haveFavorites_doNotAddComplication() {
         final DreamHomeControlsComplication.Registrant registrant =
                 new DreamHomeControlsComplication.Registrant(mComplication,
-                        mDreamOverlayStateController, mControlsComponent, mMonitor, false);
+                        mDreamOverlayStateController, mControlsComponent, mMonitor);
         registrant.start();
 
         setHaveFavorites(true);
@@ -184,7 +184,7 @@
     public void complicationAvailability_serviceAvailable_haveFavorites_addComplication() {
         final DreamHomeControlsComplication.Registrant registrant =
                 new DreamHomeControlsComplication.Registrant(mComplication,
-                        mDreamOverlayStateController, mControlsComponent, mMonitor, false);
+                        mDreamOverlayStateController, mControlsComponent, mMonitor);
         registrant.start();
 
         setHaveFavorites(true);
@@ -197,7 +197,7 @@
     public void complicationAvailability_checkAvailabilityWhenDreamOverlayBecomesActive() {
         final DreamHomeControlsComplication.Registrant registrant =
                 new DreamHomeControlsComplication.Registrant(mComplication,
-                        mDreamOverlayStateController, mControlsComponent, mMonitor, false);
+                        mDreamOverlayStateController, mControlsComponent, mMonitor);
         registrant.start();
 
         setServiceAvailable(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/TemperatureControlBehaviorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/TemperatureControlBehaviorTest.kt
index ac1f90c..b3f4588 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/TemperatureControlBehaviorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/TemperatureControlBehaviorTest.kt
@@ -10,6 +10,7 @@
 import android.service.controls.templates.ThumbnailTemplate
 import android.view.LayoutInflater
 import android.view.ViewGroup
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
@@ -20,10 +21,12 @@
 import com.android.systemui.util.time.FakeSystemClock
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class TemperatureControlBehaviorTest : SysuiTestCase() {
 
     @Mock lateinit var controlsMetricsLogger: ControlsMetricsLogger
diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/shared/FaceAuthReasonTest.kt b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/shared/FaceAuthReasonTest.kt
index ef89752..82ad30e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/shared/FaceAuthReasonTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/shared/FaceAuthReasonTest.kt
@@ -16,13 +16,16 @@
 
 package com.android.systemui.deviceentry.shared
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import junit.framework.Assert
 import kotlin.reflect.full.declaredMembers
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class FaceAuthReasonTest : SysuiTestCase() {
     @Test
     fun testApiReasonToUiEvent_forAllReasons_isNotNull() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayMetricsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayMetricsRepositoryTest.kt
index dd741b4..d79db5c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayMetricsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayMetricsRepositoryTest.kt
@@ -19,6 +19,7 @@
 import android.content.Context
 import android.util.DisplayMetrics
 import android.view.Display
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.LogBuffer
@@ -33,9 +34,11 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
 @OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
 class DisplayMetricsRepositoryTest : SysuiTestCase() {
     private lateinit var underTest: DisplayMetricsRepository
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
index 01868ae..f34058b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
@@ -20,6 +20,7 @@
 import android.os.Looper
 import android.testing.TestableLooper
 import android.view.Display
+import android.view.Display.DEFAULT_DISPLAY
 import android.view.Display.TYPE_EXTERNAL
 import android.view.Display.TYPE_INTERNAL
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -27,7 +28,6 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.FlowValue
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.kotlinArgumentCaptor
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
@@ -45,6 +45,7 @@
 import org.mockito.Mockito.never
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
+import org.mockito.kotlin.eq
 
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
@@ -63,8 +64,8 @@
 
     @Before
     fun setup() {
-        setDisplays(emptyList())
-        setAllDisplaysIncludingDisabled()
+        setDisplays(DEFAULT_DISPLAY)
+        setAllDisplaysIncludingDisabled(DEFAULT_DISPLAY)
         displayRepository =
             DisplayRepositoryImpl(
                 displayManager,
@@ -81,7 +82,7 @@
         testScope.runTest {
             val value by latestDisplayFlowValue()
 
-            assertThat(value).isEmpty()
+            assertThat(value?.ids()).containsExactly(DEFAULT_DISPLAY)
 
             verify(displayManager).registerDisplayListener(any(), eq(testHandler), anyLong())
         }
@@ -91,7 +92,7 @@
         testScope.runTest {
             val value by latestDisplayFlowValue()
 
-            assertThat(value).isEmpty()
+            assertThat(value?.ids()).containsExactly(DEFAULT_DISPLAY)
 
             verify(displayManager).registerDisplayListener(any(), eq(testHandler), anyLong())
         }
@@ -103,14 +104,14 @@
         testScope.runTest {
             val firstSubscriber by latestDisplayFlowValue()
 
-            assertThat(firstSubscriber).isEmpty()
+            assertThat(firstSubscriber).hasSize(1) // Default display only
             verify(displayManager, times(1))
                 .registerDisplayListener(displayListener.capture(), eq(testHandler), anyLong())
 
             val innerScope = TestScope()
             innerScope.runTest {
                 val secondSubscriber by latestDisplayFlowValue()
-                assertThat(secondSubscriber).isEmpty()
+                assertThat(secondSubscriber).hasSize(1)
 
                 // No new registration, just the precedent one.
                 verify(displayManager, times(1))
@@ -120,12 +121,13 @@
             // Let's make sure it has *NOT* been unregistered, as there is still a subscriber.
             setDisplays(1)
             sendOnDisplayAdded(1)
-            assertThat(firstSubscriber?.ids()).containsExactly(1)
+            assertThat(firstSubscriber?.ids()).contains(1)
         }
 
         // All subscribers are done, unregister should have been called.
         verify(displayManager).unregisterDisplayListener(any())
     }
+
     @Test
     fun onDisplayAdded_propagated() =
         testScope.runTest {
@@ -134,7 +136,7 @@
             setDisplays(1)
             sendOnDisplayAdded(1)
 
-            assertThat(value?.ids()).containsExactly(1)
+            assertThat(value?.ids()).contains(1)
         }
 
     @Test
@@ -151,7 +153,7 @@
             setDisplays(1, 2, 3)
             sendOnDisplayRemoved(4)
 
-            assertThat(value?.ids()).containsExactly(1, 2, 3)
+            assertThat(value?.ids()).containsExactly(DEFAULT_DISPLAY, 1, 2, 3)
         }
 
     @Test
@@ -167,7 +169,7 @@
 
             displayListener.value.onDisplayChanged(4)
 
-            assertThat(value?.ids()).containsExactly(1, 2, 3, 4)
+            assertThat(value?.ids()).containsExactly(DEFAULT_DISPLAY, 1, 2, 3, 4)
         }
 
     @Test
@@ -434,29 +436,31 @@
             val defaultDisplayOff by latestDefaultDisplayOffFlowValue()
             setDisplays(
                 listOf(
-                    display(
-                        type = TYPE_INTERNAL,
-                        id = Display.DEFAULT_DISPLAY,
-                        state = Display.STATE_OFF
-                    )
+                    display(type = TYPE_INTERNAL, id = DEFAULT_DISPLAY, state = Display.STATE_OFF)
                 )
             )
-            displayListener.value.onDisplayChanged(Display.DEFAULT_DISPLAY)
+            displayListener.value.onDisplayChanged(DEFAULT_DISPLAY)
             assertThat(defaultDisplayOff).isTrue()
 
             setDisplays(
                 listOf(
-                    display(
-                        type = TYPE_INTERNAL,
-                        id = Display.DEFAULT_DISPLAY,
-                        state = Display.STATE_ON
-                    )
+                    display(type = TYPE_INTERNAL, id = DEFAULT_DISPLAY, state = Display.STATE_ON)
                 )
             )
-            displayListener.value.onDisplayChanged(Display.DEFAULT_DISPLAY)
+            displayListener.value.onDisplayChanged(DEFAULT_DISPLAY)
             assertThat(defaultDisplayOff).isFalse()
         }
 
+    @Test
+    fun displayFlow_startsWithDefaultDisplayBeforeAnyEvent() =
+        testScope.runTest {
+            setDisplays(DEFAULT_DISPLAY)
+
+            val value by latestDisplayFlowValue()
+
+            assertThat(value?.ids()).containsExactly(DEFAULT_DISPLAY)
+        }
+
     private fun Iterable<Display>.ids(): List<Int> = map { it.displayId }
 
     // Wrapper to capture the displayListener.
@@ -554,6 +558,8 @@
     }
 
     private fun setDisplays(vararg ids: Int) {
-        setDisplays(ids.map { display(type = TYPE_EXTERNAL, id = it) })
+        // DEFAULT_DISPLAY always there
+        val idsToSet = ids.toSet() + DEFAULT_DISPLAY
+        setDisplays(idsToSet.map { display(type = TYPE_EXTERNAL, id = it) })
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStatePreventingAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStatePreventingAdapterTest.java
index a7d7b93..419f7ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStatePreventingAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStatePreventingAdapterTest.java
@@ -24,6 +24,7 @@
 
 import android.view.Display;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -33,10 +34,12 @@
 
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.util.concurrent.Executor;
 
 @SmallTest
+@RunWith(AndroidJUnit4.class)
 public class DozeScreenStatePreventingAdapterTest extends SysuiTestCase {
 
     private Executor mExecutor;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java
index 240d2d7..5a89710 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuspendScreenStatePreventingAdapterTest.java
@@ -24,6 +24,7 @@
 
 import android.view.Display;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -33,10 +34,12 @@
 
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.util.concurrent.Executor;
 
 @SmallTest
+@RunWith(AndroidJUnit4.class)
 public class DozeSuspendScreenStatePreventingAdapterTest extends SysuiTestCase {
 
     private Executor mExecutor;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt
index 840eb46..5976292 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.dump
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.CoreStartable
 import com.android.systemui.Dumpable
@@ -28,6 +29,7 @@
 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.anyInt
 import org.mockito.Mockito.never
@@ -39,6 +41,7 @@
 import javax.inject.Provider
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class DumpHandlerTest : SysuiTestCase() {
 
     private lateinit var dumpHandler: DumpHandler
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dump/DumpManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dump/DumpManagerTest.kt
index 6d5226f..f331060 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dump/DumpManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/dump/DumpManagerTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.dump
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.Dumpable
 import com.android.systemui.SysuiTestCase
@@ -25,10 +26,12 @@
 import org.junit.Assert.assertThrows
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class DumpManagerTest : SysuiTestCase() {
 
     @Mock private lateinit var dumpable1: Dumpable
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dump/DumpsysTableLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dump/DumpsysTableLoggerTest.kt
index 1d2afe4..d09928b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dump/DumpsysTableLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/dump/DumpsysTableLoggerTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.dump
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 
 import com.android.systemui.SysuiTestCase
@@ -24,11 +25,13 @@
 import org.junit.Assert.assertEquals
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 
 import java.io.PrintWriter
 import java.io.StringWriter
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class DumpsysTableLoggerTest : SysuiTestCase() {
     private val logger = DumpsysTableLogger(
             TEST_SECTION_NAME,
@@ -143,4 +146,4 @@
     List(TEST_COLUMNS.size) { col ->
         "data$col$row"
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferFreezerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferFreezerTest.kt
index 3b4888f..0cd2b9f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferFreezerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferFreezerTest.kt
@@ -19,6 +19,7 @@
 import android.content.BroadcastReceiver
 import android.content.IntentFilter
 import android.os.UserHandle
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.broadcast.BroadcastDispatcher
@@ -30,6 +31,7 @@
 import com.android.systemui.util.time.FakeSystemClock
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
 import org.mockito.Captor
 import org.mockito.Mock
@@ -40,6 +42,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class LogBufferFreezerTest : SysuiTestCase() {
 
     lateinit var freezer: LogBufferFreezer
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dump/LogEulogizerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dump/LogEulogizerTest.kt
index 3ff7202..ae6b337 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dump/LogEulogizerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/dump/LogEulogizerTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.dump
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpHandler.Companion.dump
@@ -40,6 +41,7 @@
 import org.junit.Assert.assertTrue
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
 import org.mockito.Mockito
@@ -48,6 +50,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class LogEulogizerTest : SysuiTestCase() {
 
     lateinit var eulogizer: LogBufferEulogizer
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/ConditionalRestarterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/ConditionalRestarterTest.kt
index 52c6e22..9f238e6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/ConditionalRestarterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/ConditionalRestarterTest.kt
@@ -15,6 +15,7 @@
  */
 package com.android.systemui.flags
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.any
@@ -26,6 +27,7 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
@@ -35,6 +37,7 @@
  * Be careful with the {FeatureFlagsReleaseRestarter} in this test. It has a call to System.exit()!
  */
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class ConditionalRestarterTest : SysuiTestCase() {
     private lateinit var restarter: ConditionalRestarter
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsClassicDebugTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsClassicDebugTest.kt
index dbe59e6..a1fe0f0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsClassicDebugTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsClassicDebugTest.kt
@@ -23,6 +23,7 @@
 import android.content.res.Resources.NotFoundException
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.Flags.FLAG_SYSUI_TEAMFOOD
 import com.android.systemui.SysuiTestCase
@@ -39,6 +40,7 @@
 import org.junit.Assert
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.anyBoolean
 import org.mockito.Mockito.anyString
@@ -55,6 +57,7 @@
  * the default.
  */
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class FeatureFlagsClassicDebugTest : SysuiTestCase() {
     private lateinit var mFeatureFlagsClassicDebug: FeatureFlagsClassicDebug
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsClassicReleaseTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsClassicReleaseTest.kt
index 943e212..ad8bedb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsClassicReleaseTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsClassicReleaseTest.kt
@@ -17,12 +17,14 @@
 
 import android.content.pm.PackageManager.NameNotFoundException
 import android.content.res.Resources
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import org.junit.Assert.assertThrows
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito
 import org.mockito.Mockito.never
@@ -34,6 +36,7 @@
  * overriding, and should never return any value other than the one provided as the default.
  */
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class FeatureFlagsClassicReleaseTest : SysuiTestCase() {
     private lateinit var mFeatureFlagsClassicRelease: FeatureFlagsClassicRelease
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FlagCommandTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FlagCommandTest.kt
index d500dd2..dd56fa6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FlagCommandTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FlagCommandTest.kt
@@ -16,18 +16,21 @@
 
 package com.android.systemui.flags
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.any
 import java.io.PrintWriter
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class FlagCommandTest : SysuiTestCase() {
 
     @Mock private lateinit var featureFlags: FeatureFlagsClassicDebug
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FlagManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FlagManagerTest.kt
index 5e87a6f..593de37 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FlagManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FlagManagerTest.kt
@@ -19,6 +19,7 @@
 import android.database.ContentObserver
 import android.net.Uri
 import android.os.Handler
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.any
@@ -30,6 +31,7 @@
 import org.junit.Assert.assertThrows
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
@@ -42,6 +44,7 @@
  * overriding, and should never return any value other than the one provided as the default.
  */
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class FlagManagerTest : SysuiTestCase() {
     private lateinit var mFlagManager: FlagManager
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/NotOccludedConditionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/NotOccludedConditionTest.kt
index 755cc46..46b4c4b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/NotOccludedConditionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/NotOccludedConditionTest.kt
@@ -15,6 +15,7 @@
  */
 package com.android.systemui.flags
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
@@ -30,6 +31,7 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
@@ -39,6 +41,7 @@
  */
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class NotOccludedConditionTest : SysuiTestCase() {
     private lateinit var condition: NotOccludedCondition
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/PluggedInConditionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/PluggedInConditionTest.kt
index 0fdda08..0f727cb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/PluggedInConditionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/PluggedInConditionTest.kt
@@ -15,6 +15,7 @@
  */
 package com.android.systemui.flags
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
@@ -26,6 +27,7 @@
 import kotlinx.coroutines.test.runTest
 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.verify
@@ -36,6 +38,7 @@
  * Be careful with the {FeatureFlagsReleaseRestarter} in this test. It has a call to System.exit()!
  */
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class PluggedInConditionTest : SysuiTestCase() {
     private lateinit var condition: PluggedInCondition
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt
index 3c965ce..1ab945a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.flags
 
 import android.os.PowerManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.plugins.statusbar.StatusBarStateController
@@ -27,6 +28,7 @@
 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.anyInt
 import org.mockito.ArgumentMatchers.anyString
@@ -37,6 +39,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class RestartDozeListenerTest : SysuiTestCase() {
 
     lateinit var restartDozeListener: RestartDozeListener
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/ScreenIdleConditionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/ScreenIdleConditionTest.kt
index 0116e53..df03882 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/ScreenIdleConditionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/ScreenIdleConditionTest.kt
@@ -15,6 +15,7 @@
  */
 package com.android.systemui.flags
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
@@ -27,6 +28,7 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
@@ -35,6 +37,7 @@
  * Be careful with the {FeatureFlagsReleaseRestarter} in this test. It has a call to System.exit()!
  */
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class ScreenIdleConditionTest : SysuiTestCase() {
     private lateinit var condition: ScreenIdleCondition
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/fragments/FragmentServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/fragments/FragmentServiceTest.kt
index 8a29217..008c68d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/fragments/FragmentServiceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/fragments/FragmentServiceTest.kt
@@ -2,6 +2,7 @@
 
 import android.app.Fragment
 import android.os.Looper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
@@ -9,8 +10,10 @@
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class FragmentServiceTest : SysuiTestCase() {
     private val fragmentHostManagerFactory: FragmentHostManager.Factory = mock()
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsImeTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsImeTest.java
index 7f55d38..dc019b6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsImeTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsImeTest.java
@@ -37,6 +37,7 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.FlakyTest;
 import androidx.test.filters.LargeTest;
 import androidx.test.platform.app.InstrumentationRegistry;
@@ -48,6 +49,7 @@
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
@@ -55,6 +57,7 @@
 
 @LargeTest
 @FlakyTest(bugId = 176891566)
+@RunWith(AndroidJUnit4.class)
 public class GlobalActionsImeTest extends SysuiTestCase {
 
     @Rule
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt
index 53bcf86..361e768 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/data/repository/KeyboardRepositoryTest.kt
@@ -20,6 +20,7 @@
 import android.hardware.input.InputManager
 import android.hardware.input.InputManager.KeyboardBacklightListener
 import android.hardware.input.KeyboardBacklightState
+import android.testing.TestableLooper
 import android.view.InputDevice
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
@@ -27,11 +28,13 @@
 import com.android.systemui.coroutines.FlowValue
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
+import com.android.systemui.inputdevice.data.repository.InputDeviceRepository
 import com.android.systemui.keyboard.data.model.Keyboard
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.nullable
 import com.android.systemui.util.mockito.whenever
+import com.android.systemui.utils.os.FakeHandler
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -53,6 +56,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@TestableLooper.RunWithLooper
 @RunWith(AndroidJUnit4::class)
 class KeyboardRepositoryTest : SysuiTestCase() {
 
@@ -63,6 +67,7 @@
 
     private lateinit var underTest: KeyboardRepository
     private lateinit var dispatcher: CoroutineDispatcher
+    private lateinit var inputDeviceRepo: InputDeviceRepository
     private lateinit var testScope: TestScope
 
     @Before
@@ -75,7 +80,9 @@
         }
         dispatcher = StandardTestDispatcher()
         testScope = TestScope(dispatcher)
-        underTest = KeyboardRepositoryImpl(testScope.backgroundScope, dispatcher, inputManager)
+        val handler = FakeHandler(TestableLooper.get(this).looper)
+        inputDeviceRepo = InputDeviceRepository(handler, testScope.backgroundScope, inputManager)
+        underTest = KeyboardRepositoryImpl(dispatcher, inputManager, inputDeviceRepo)
     }
 
     @Test
@@ -363,6 +370,7 @@
         private val maxBrightnessLevel: Int
     ) : KeyboardBacklightState() {
         override fun getBrightnessLevel() = brightnessLevel
+
         override fun getMaxBrightnessLevel() = maxBrightnessLevel
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/docking/ui/viewmodel/KeyboardDockingIndicationViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/docking/ui/viewmodel/KeyboardDockingIndicationViewModelTest.kt
index 3a86868..2735d2f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/docking/ui/viewmodel/KeyboardDockingIndicationViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/docking/ui/viewmodel/KeyboardDockingIndicationViewModelTest.kt
@@ -20,6 +20,7 @@
 import android.view.WindowInsets
 import android.view.WindowManager
 import android.view.WindowMetrics
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
@@ -33,14 +34,13 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.Mockito.spy
 import org.mockito.MockitoAnnotations
 import org.mockito.kotlin.doReturn
 import org.mockito.kotlin.whenever
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class KeyboardDockingIndicationViewModelTest : SysuiTestCase() {
     private val testScope = TestScope(StandardTestDispatcher())
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperStateRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperStateRepositoryTest.kt
new file mode 100644
index 0000000..0b4e6a2
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperStateRepositoryTest.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.data.repository
+
+import android.hardware.input.fakeInputManager
+import android.view.KeyCharacterMap.VIRTUAL_KEYBOARD
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState
+import com.android.systemui.keyboard.shortcut.shortcutHelperStateRepository
+import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ShortcutHelperStateRepositoryTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos()
+
+    private val repo = kosmos.shortcutHelperStateRepository
+    private val helper = kosmos.shortcutHelperTestHelper
+    private val testScope = kosmos.testScope
+    private val fakeInputManager = kosmos.fakeInputManager
+
+    @Test
+    fun state_activeThroughToggle_emitsActiveWithDeviceIdFromEvent() =
+        testScope.runTest {
+            val deviceId = 123
+            val state by collectLastValue(repo.state)
+
+            helper.toggle(deviceId)
+
+            assertThat(state).isEqualTo(ShortcutHelperState.Active(deviceId))
+        }
+
+    @Test
+    fun state_activeThroughActivity_noKeyboardActive_emitsActiveWithVirtualDeviceId() =
+        testScope.runTest {
+            val state by collectLastValue(repo.state)
+
+            helper.showFromActivity()
+
+            assertThat(state).isEqualTo(ShortcutHelperState.Active(VIRTUAL_KEYBOARD))
+        }
+
+    @Test
+    fun state_activeThroughActivity_physicalKeyboardActive_emitsActiveWithDeviceId() =
+        testScope.runTest {
+            val deviceId = 456
+            val state by collectLastValue(repo.state)
+
+            fakeInputManager.addPhysicalKeyboard(deviceId)
+            helper.showFromActivity()
+
+            assertThat(state).isEqualTo(ShortcutHelperState.Active(deviceId))
+        }
+
+    @Test
+    fun state_activeThroughActivity_physicalKeyboardDisabled_emitsActiveWithVirtualDeviceId() =
+        testScope.runTest {
+            val deviceId = 456
+            val state by collectLastValue(repo.state)
+
+            fakeInputManager.addPhysicalKeyboard(deviceId)
+            fakeInputManager.inputManager.disableInputDevice(deviceId)
+            helper.showFromActivity()
+
+            assertThat(state).isEqualTo(ShortcutHelperState.Active(VIRTUAL_KEYBOARD))
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/AppCategoriesShortcutsSourceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/AppCategoriesShortcutsSourceTest.kt
new file mode 100644
index 0000000..e49e2b49
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/AppCategoriesShortcutsSourceTest.kt
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.data.source
+
+import android.content.Intent.CATEGORY_APP_BROWSER
+import android.content.Intent.CATEGORY_APP_CALCULATOR
+import android.content.Intent.CATEGORY_APP_CALENDAR
+import android.content.Intent.CATEGORY_APP_CONTACTS
+import android.content.Intent.CATEGORY_APP_EMAIL
+import android.content.Intent.CATEGORY_APP_MAPS
+import android.content.Intent.CATEGORY_APP_MESSAGING
+import android.content.Intent.CATEGORY_APP_MUSIC
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.keyboard.shortcut.shortcutHelperAppCategoriesShortcutsSource
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.android.systemui.util.icons.fakeAppCategoryIconProvider
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class AppCategoriesShortcutsSourceTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val defaultAppIconsProvider = kosmos.fakeAppCategoryIconProvider
+    private val source = kosmos.shortcutHelperAppCategoriesShortcutsSource
+
+    @Before
+    fun setUp() {
+        categoryApps.forEach { categoryAppIcon ->
+            defaultAppIconsProvider.installCategoryApp(
+                categoryAppIcon.category,
+                categoryAppIcon.packageName,
+                categoryAppIcon.iconResId
+            )
+        }
+    }
+
+    @Test
+    fun shortcutGroups_returnsSingleGroup() =
+        testScope.runTest { assertThat(source.shortcutGroups(TEST_DEVICE_ID)).hasSize(1) }
+
+    @Test
+    fun shortcutGroups_hasAssistantIcon() =
+        testScope.runTest {
+            defaultAppIconsProvider.installAssistantApp(ASSISTANT_PACKAGE, ASSISTANT_ICON_RES_ID)
+
+            val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items
+
+            val shortcutInfo = shortcuts.first { it.label == "Assistant" }
+
+            assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(ASSISTANT_PACKAGE)
+            assertThat(shortcutInfo.icon!!.resId).isEqualTo(ASSISTANT_ICON_RES_ID)
+        }
+
+    @Test
+    fun shortcutGroups_hasBrowserIcon() =
+        testScope.runTest {
+            val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items
+
+            val shortcutInfo = shortcuts.first { it.label == "Browser" }
+
+            assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(BROWSER_PACKAGE)
+            assertThat(shortcutInfo.icon!!.resId).isEqualTo(BROWSER_ICON_RES_ID)
+        }
+
+    @Test
+    fun shortcutGroups_hasContactsIcon() =
+        testScope.runTest {
+            val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items
+
+            val shortcutInfo = shortcuts.first { it.label == "Contacts" }
+
+            assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(CONTACTS_PACKAGE)
+            assertThat(shortcutInfo.icon!!.resId).isEqualTo(CONTACTS_ICON_RES_ID)
+        }
+
+    @Test
+    fun shortcutGroups_hasEmailIcon() =
+        testScope.runTest {
+            val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items
+
+            val shortcutInfo = shortcuts.first { it.label == "Email" }
+
+            assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(EMAIL_PACKAGE)
+            assertThat(shortcutInfo.icon!!.resId).isEqualTo(EMAIL_ICON_RES_ID)
+        }
+
+    @Test
+    fun shortcutGroups_hasCalendarIcon() =
+        testScope.runTest {
+            val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items
+
+            val shortcutInfo = shortcuts.first { it.label == "Calendar" }
+
+            assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(CALENDAR_PACKAGE)
+            assertThat(shortcutInfo.icon!!.resId).isEqualTo(CALENDAR_ICON_RES_ID)
+        }
+
+    @Test
+    fun shortcutGroups_hasMapsIcon() =
+        testScope.runTest {
+            val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items
+
+            val shortcutInfo = shortcuts.first { it.label == "Maps" }
+
+            assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(MAPS_PACKAGE)
+            assertThat(shortcutInfo.icon!!.resId).isEqualTo(MAPS_ICON_RES_ID)
+        }
+
+    @Test
+    fun shortcutGroups_hasMessagingIcon() =
+        testScope.runTest {
+            val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items
+
+            val shortcutInfo = shortcuts.first { it.label == "SMS" }
+
+            assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(MESSAGING_PACKAGE)
+            assertThat(shortcutInfo.icon!!.resId).isEqualTo(MESSAGING_ICON_RES_ID)
+        }
+
+    @Test
+    fun shortcutGroups_hasMusicIcon() =
+        testScope.runTest {
+            val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items
+
+            val shortcutInfo = shortcuts.first { it.label == "Music" }
+
+            assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(MUSIC_PACKAGE)
+            assertThat(shortcutInfo.icon!!.resId).isEqualTo(MUSIC_ICON_RES_ID)
+        }
+
+    @Test
+    fun shortcutGroups_hasCalculatorIcon() =
+        testScope.runTest {
+            val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items
+
+            val shortcutInfo = shortcuts.first { it.label == "Calculator" }
+
+            assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(CALCULATOR_PACKAGE)
+            assertThat(shortcutInfo.icon!!.resId).isEqualTo(CALCULATOR_ICON_RES_ID)
+        }
+
+    @Test
+    fun shortcutGroups_shortcutsSortedByLabelIgnoringCase() =
+        testScope.runTest {
+            val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items
+
+            val shortcutLabels = shortcuts.map { it.label!!.toString() }
+            assertThat(shortcutLabels).isEqualTo(shortcutLabels.sortedBy { it.lowercase() })
+        }
+
+    @Test
+    fun shortcutGroups_noAssistantApp_excludesAssistantFromShortcuts() =
+        testScope.runTest {
+            val shortcutLabels =
+                source.shortcutGroups(TEST_DEVICE_ID).first().items.map { it.label!!.toString() }
+
+            assertThat(shortcutLabels).doesNotContain("Assistant")
+        }
+
+    private companion object {
+        private const val ASSISTANT_PACKAGE = "the.assistant.app"
+        private const val ASSISTANT_ICON_RES_ID = 123
+
+        private const val BROWSER_PACKAGE = "com.test.browser"
+        private const val BROWSER_ICON_RES_ID = 1
+
+        private const val CONTACTS_PACKAGE = "app.test.contacts"
+        private const val CONTACTS_ICON_RES_ID = 234
+
+        private const val EMAIL_PACKAGE = "email.app.test"
+        private const val EMAIL_ICON_RES_ID = 351
+
+        private const val CALENDAR_PACKAGE = "app.test.calendar"
+        private const val CALENDAR_ICON_RES_ID = 411
+
+        private const val MAPS_PACKAGE = "maps.app.package"
+        private const val MAPS_ICON_RES_ID = 999
+
+        private const val MUSIC_PACKAGE = "com.android.music"
+        private const val MUSIC_ICON_RES_ID = 101
+
+        private const val MESSAGING_PACKAGE = "my.sms.app"
+        private const val MESSAGING_ICON_RES_ID = 9191
+
+        private const val CALCULATOR_PACKAGE = "that.calculator.app"
+        private const val CALCULATOR_ICON_RES_ID = 314
+
+        private val categoryApps =
+            listOf(
+                CategoryApp(CATEGORY_APP_BROWSER, BROWSER_PACKAGE, BROWSER_ICON_RES_ID),
+                CategoryApp(CATEGORY_APP_CONTACTS, CONTACTS_PACKAGE, CONTACTS_ICON_RES_ID),
+                CategoryApp(CATEGORY_APP_EMAIL, EMAIL_PACKAGE, EMAIL_ICON_RES_ID),
+                CategoryApp(CATEGORY_APP_CALENDAR, CALENDAR_PACKAGE, CALENDAR_ICON_RES_ID),
+                CategoryApp(CATEGORY_APP_MAPS, MAPS_PACKAGE, MAPS_ICON_RES_ID),
+                CategoryApp(CATEGORY_APP_MUSIC, MUSIC_PACKAGE, MUSIC_ICON_RES_ID),
+                CategoryApp(CATEGORY_APP_MESSAGING, MESSAGING_PACKAGE, MESSAGING_ICON_RES_ID),
+                CategoryApp(CATEGORY_APP_CALCULATOR, CALCULATOR_PACKAGE, CALCULATOR_ICON_RES_ID),
+            )
+
+        private const val TEST_DEVICE_ID = 123
+    }
+
+    private class CategoryApp(val category: String, val packageName: String, val iconResId: Int)
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
new file mode 100644
index 0000000..765cd01
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/TestShortcuts.kt
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.data.source
+
+import android.view.KeyEvent
+import android.view.KeyboardShortcutGroup
+import android.view.KeyboardShortcutInfo
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
+import com.android.systemui.keyboard.shortcut.shared.model.shortcut
+import com.android.systemui.res.R
+
+object TestShortcuts {
+
+    private val shortcutInfoWithRepeatedLabel =
+        KeyboardShortcutInfo(
+            /* label = */ "Shortcut with repeated label",
+            /* keycode = */ KeyEvent.KEYCODE_H,
+            /* modifiers = */ KeyEvent.META_META_ON,
+        )
+
+    private val shortcutInfoWithRepeatedLabelAlternate =
+        KeyboardShortcutInfo(
+            /* label = */ shortcutInfoWithRepeatedLabel.label,
+            /* keycode = */ KeyEvent.KEYCODE_L,
+            /* modifiers = */ KeyEvent.META_META_ON,
+        )
+
+    private val shortcutInfoWithRepeatedLabelSecondAlternate =
+        KeyboardShortcutInfo(
+            /* label = */ shortcutInfoWithRepeatedLabel.label,
+            /* keycode = */ KeyEvent.KEYCODE_M,
+            /* modifiers = */ KeyEvent.META_SHIFT_ON,
+        )
+
+    private val shortcutWithGroupedRepeatedLabel =
+        shortcut(shortcutInfoWithRepeatedLabel.label!!.toString()) {
+            command {
+                key(R.drawable.ic_ksh_key_meta)
+                key("H")
+            }
+            command {
+                key(R.drawable.ic_ksh_key_meta)
+                key("L")
+            }
+            command {
+                key("Shift")
+                key("M")
+            }
+        }
+
+    private val standardShortcutInfo1 =
+        KeyboardShortcutInfo(
+            /* label = */ "Standard shortcut 1",
+            /* keycode = */ KeyEvent.KEYCODE_N,
+            /* modifiers = */ KeyEvent.META_META_ON,
+        )
+
+    private val standardShortcut1 =
+        shortcut(standardShortcutInfo1.label!!.toString()) {
+            command {
+                key(R.drawable.ic_ksh_key_meta)
+                key("N")
+            }
+        }
+
+    private val standardShortcutInfo2 =
+        KeyboardShortcutInfo(
+            /* label = */ "Standard shortcut 2",
+            /* keycode = */ KeyEvent.KEYCODE_Z,
+            /* modifiers = */ KeyEvent.META_ALT_ON or KeyEvent.META_SHIFT_ON,
+        )
+
+    private val standardShortcut2 =
+        shortcut(standardShortcutInfo2.label!!.toString()) {
+            command {
+                key("Alt")
+                key("Shift")
+                key("Z")
+            }
+        }
+
+    private val standardShortcutInfo3 =
+        KeyboardShortcutInfo(
+            /* label = */ "Standard shortcut 3",
+            /* keycode = */ KeyEvent.KEYCODE_J,
+            /* modifiers = */ KeyEvent.META_CTRL_ON,
+        )
+
+    private val standardShortcut3 =
+        shortcut(standardShortcutInfo3.label!!.toString()) {
+            command {
+                key("Ctrl")
+                key("J")
+            }
+        }
+
+    private val shortcutInfoWithUnsupportedModifiers =
+        KeyboardShortcutInfo(
+            /* label = */ "Shortcut with unsupported modifiers",
+            /* keycode = */ KeyEvent.KEYCODE_A,
+            /* modifiers = */ KeyEvent.META_META_ON or KeyEvent.KEYCODE_SPACE,
+        )
+
+    private val groupWithRepeatedShortcutLabels =
+        KeyboardShortcutGroup(
+            "Group with duplicate labels",
+            listOf(
+                shortcutInfoWithRepeatedLabel,
+                shortcutInfoWithRepeatedLabelAlternate,
+                shortcutInfoWithRepeatedLabelSecondAlternate
+            )
+        )
+
+    private val subCategoryWithGroupedRepeatedShortcutLabels =
+        ShortcutSubCategory(
+            label = groupWithRepeatedShortcutLabels.label!!.toString(),
+            shortcuts = listOf(shortcutWithGroupedRepeatedLabel)
+        )
+
+    private val groupWithStandardShortcutInfo =
+        KeyboardShortcutGroup("Standard group", listOf(standardShortcutInfo1))
+
+    private val subCategoryWithStandardShortcut =
+        ShortcutSubCategory(
+            label = groupWithStandardShortcutInfo.label!!.toString(),
+            shortcuts = listOf(standardShortcut1)
+        )
+
+    private val groupWithOnlyUnsupportedModifierShortcut =
+        KeyboardShortcutGroup(
+            "Group with unsupported modifiers",
+            listOf(shortcutInfoWithUnsupportedModifiers)
+        )
+
+    private val groupWithSupportedAndUnsupportedModifierShortcut =
+        KeyboardShortcutGroup(
+            "Group with mix of supported and not supported modifiers",
+            listOf(standardShortcutInfo3, shortcutInfoWithUnsupportedModifiers)
+        )
+
+    private val switchToNextLanguageShortcut =
+        shortcut("Switch to next language") {
+            command {
+                key("Ctrl")
+                key("Space")
+            }
+        }
+
+    private val switchToPreviousLanguageShortcut =
+        shortcut("Switch to previous language") {
+            command {
+                key("Ctrl")
+                key("Shift")
+                key("Space")
+            }
+        }
+
+    private val subCategoryForInputLanguageSwitchShortcuts =
+        ShortcutSubCategory(
+            "Input",
+            listOf(switchToNextLanguageShortcut, switchToPreviousLanguageShortcut)
+        )
+
+    private val subCategoryWithUnsupportedShortcutsRemoved =
+        ShortcutSubCategory(
+            groupWithSupportedAndUnsupportedModifierShortcut.label!!.toString(),
+            listOf(standardShortcut3)
+        )
+
+    private val standardGroup1 =
+        KeyboardShortcutGroup(
+            "Standard group 1",
+            listOf(standardShortcutInfo1, standardShortcutInfo2, standardShortcutInfo3)
+        )
+
+    private val standardSubCategory1 =
+        ShortcutSubCategory(
+            standardGroup1.label!!.toString(),
+            listOf(standardShortcut1, standardShortcut2, standardShortcut3)
+        )
+
+    private val standardGroup2 =
+        KeyboardShortcutGroup(
+            "Standard group 2",
+            listOf(standardShortcutInfo3, standardShortcutInfo2, standardShortcutInfo1)
+        )
+
+    private val standardSubCategory2 =
+        ShortcutSubCategory(
+            standardGroup2.label!!.toString(),
+            listOf(standardShortcut3, standardShortcut2, standardShortcut1)
+        )
+    private val standardGroup3 =
+        KeyboardShortcutGroup(
+            "Standard group 3",
+            listOf(standardShortcutInfo2, standardShortcutInfo1)
+        )
+
+    private val standardSubCategory3 =
+        ShortcutSubCategory(
+            standardGroup3.label!!.toString(),
+            listOf(standardShortcut2, standardShortcut1)
+        )
+    val imeGroups = listOf(standardGroup1, standardGroup2, standardGroup3)
+    val imeCategory =
+        ShortcutCategory(
+            type = ShortcutCategoryType.IME,
+            subCategories =
+                listOf(
+                    subCategoryForInputLanguageSwitchShortcuts,
+                    standardSubCategory1,
+                    standardSubCategory2,
+                    standardSubCategory3
+                )
+        )
+
+    val systemGroups = listOf(standardGroup3, standardGroup2, standardGroup1)
+    val systemCategory =
+        ShortcutCategory(
+            type = ShortcutCategoryType.SYSTEM,
+            subCategories = listOf(standardSubCategory3, standardSubCategory2, standardSubCategory1)
+        )
+
+    val multitaskingGroups = listOf(standardGroup2, standardGroup1)
+    val multitaskingCategory =
+        ShortcutCategory(
+            type = ShortcutCategoryType.MULTI_TASKING,
+            subCategories = listOf(standardSubCategory2, standardSubCategory1)
+        )
+
+    val groupsWithDuplicateShortcutLabels =
+        listOf(groupWithRepeatedShortcutLabels, groupWithStandardShortcutInfo)
+
+    val subCategoriesWithGroupedDuplicatedShortcutLabels =
+        listOf(subCategoryWithGroupedRepeatedShortcutLabels, subCategoryWithStandardShortcut)
+
+    val imeSubCategoriesWithGroupedDuplicatedShortcutLabels =
+        listOf(
+            subCategoryForInputLanguageSwitchShortcuts,
+            subCategoryWithGroupedRepeatedShortcutLabels,
+            subCategoryWithStandardShortcut
+        )
+
+    val groupsWithUnsupportedModifier =
+        listOf(
+            groupWithStandardShortcutInfo,
+            groupWithOnlyUnsupportedModifierShortcut,
+            groupWithSupportedAndUnsupportedModifierShortcut
+        )
+
+    val subCategoriesWithUnsupportedModifiersRemoved =
+        listOf(subCategoryWithStandardShortcut, subCategoryWithUnsupportedShortcutsRemoved)
+
+    val imeSubCategoriesWithUnsupportedModifiersRemoved =
+        listOf(
+            subCategoryForInputLanguageSwitchShortcuts,
+            subCategoryWithStandardShortcut,
+            subCategoryWithUnsupportedShortcutsRemoved
+        )
+
+    val groupsWithOnlyUnsupportedModifiers = listOf(groupWithOnlyUnsupportedModifierShortcut)
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt
new file mode 100644
index 0000000..4c1e869
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperCategoriesInteractorTest.kt
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.domain.interactor
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyboard.shortcut.data.source.FakeKeyboardShortcutGroupsSource
+import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategory
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.IME
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MULTI_TASKING
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.SYSTEM
+import com.android.systemui.keyboard.shortcut.shortcutHelperAppCategoriesShortcutsSource
+import com.android.systemui.keyboard.shortcut.shortcutHelperCategoriesInteractor
+import com.android.systemui.keyboard.shortcut.shortcutHelperMultiTaskingShortcutsSource
+import com.android.systemui.keyboard.shortcut.shortcutHelperSystemShortcutsSource
+import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ShortcutHelperCategoriesInteractorTest : SysuiTestCase() {
+
+    private val systemShortcutsSource = FakeKeyboardShortcutGroupsSource()
+    private val multitaskingShortcutsSource = FakeKeyboardShortcutGroupsSource()
+    private val defaultAppsShortcutsSource = FakeKeyboardShortcutGroupsSource()
+    @OptIn(ExperimentalCoroutinesApi::class)
+    private val kosmos =
+        testKosmos().also {
+            it.testDispatcher = UnconfinedTestDispatcher()
+            it.shortcutHelperSystemShortcutsSource = systemShortcutsSource
+            it.shortcutHelperMultiTaskingShortcutsSource = multitaskingShortcutsSource
+            it.shortcutHelperAppCategoriesShortcutsSource = defaultAppsShortcutsSource
+        }
+
+    private val testScope = kosmos.testScope
+    private val interactor = kosmos.shortcutHelperCategoriesInteractor
+    private val helper = kosmos.shortcutHelperTestHelper
+
+    @Before
+    fun setShortcuts() {
+        helper.setImeShortcuts(TestShortcuts.imeGroups)
+        systemShortcutsSource.setGroups(TestShortcuts.systemGroups)
+        multitaskingShortcutsSource.setGroups(TestShortcuts.multitaskingGroups)
+    }
+
+    @Test
+    fun categories_emptyByDefault() =
+        testScope.runTest {
+            val categories by collectLastValue(interactor.shortcutCategories)
+
+            assertThat(categories).isEmpty()
+        }
+
+    @Test
+    fun categories_stateActive_emitsAllCategoriesInOrder() =
+        testScope.runTest {
+            val categories by collectLastValue(interactor.shortcutCategories)
+
+            helper.showFromActivity()
+
+            assertThat(categories)
+                .containsExactly(
+                    TestShortcuts.systemCategory,
+                    TestShortcuts.multitaskingCategory,
+                    TestShortcuts.imeCategory,
+                )
+                .inOrder()
+        }
+
+    @Test
+    fun categories_stateInactiveAfterActive_emitsEmpty() =
+        testScope.runTest {
+            val categories by collectLastValue(interactor.shortcutCategories)
+            helper.showFromActivity()
+            helper.hideFromActivity()
+
+            assertThat(categories).isEmpty()
+        }
+
+    @Test
+    fun categories_stateActive_imeShortcutsWithDuplicateLabels_emitsGroupedShortcuts() =
+        testScope.runTest {
+            helper.setImeShortcuts(TestShortcuts.groupsWithDuplicateShortcutLabels)
+
+            val categories by collectLastValue(interactor.shortcutCategories)
+
+            helper.showFromActivity()
+
+            assertThat(categories)
+                .containsExactly(
+                    TestShortcuts.systemCategory,
+                    TestShortcuts.multitaskingCategory,
+                    ShortcutCategory(
+                        type = IME,
+                        subCategories =
+                            TestShortcuts.imeSubCategoriesWithGroupedDuplicatedShortcutLabels
+                    ),
+                )
+                .inOrder()
+        }
+
+    @Test
+    fun categories_stateActive_systemShortcutsWithDuplicateLabels_emitsGroupedShortcuts() =
+        testScope.runTest {
+            systemShortcutsSource.setGroups(TestShortcuts.groupsWithDuplicateShortcutLabels)
+
+            val categories by collectLastValue(interactor.shortcutCategories)
+
+            helper.showFromActivity()
+
+            assertThat(categories)
+                .containsExactly(
+                    ShortcutCategory(
+                        type = SYSTEM,
+                        subCategories =
+                            TestShortcuts.subCategoriesWithGroupedDuplicatedShortcutLabels
+                    ),
+                    TestShortcuts.multitaskingCategory,
+                    TestShortcuts.imeCategory,
+                )
+                .inOrder()
+        }
+
+    @Test
+    fun categories_stateActive_multiTaskingShortcutsWithDuplicateLabels_emitsGroupedShortcuts() =
+        testScope.runTest {
+            multitaskingShortcutsSource.setGroups(TestShortcuts.groupsWithDuplicateShortcutLabels)
+
+            val categories by collectLastValue(interactor.shortcutCategories)
+
+            helper.showFromActivity()
+
+            assertThat(categories)
+                .containsExactly(
+                    TestShortcuts.systemCategory,
+                    ShortcutCategory(
+                        type = MULTI_TASKING,
+                        subCategories =
+                            TestShortcuts.subCategoriesWithGroupedDuplicatedShortcutLabels
+                    ),
+                    TestShortcuts.imeCategory,
+                )
+                .inOrder()
+        }
+
+    @Test
+    fun categories_stateActive_imeShortcutsWithUnsupportedModifiers_discardUnsupported() =
+        testScope.runTest {
+            helper.setImeShortcuts(TestShortcuts.groupsWithUnsupportedModifier)
+            val categories by collectLastValue(interactor.shortcutCategories)
+
+            helper.showFromActivity()
+
+            assertThat(categories)
+                .containsExactly(
+                    TestShortcuts.systemCategory,
+                    TestShortcuts.multitaskingCategory,
+                    ShortcutCategory(
+                        type = IME,
+                        subCategories =
+                            TestShortcuts.imeSubCategoriesWithUnsupportedModifiersRemoved
+                    ),
+                )
+                .inOrder()
+        }
+
+    @Test
+    fun categories_stateActive_systemShortcutsWithUnsupportedModifiers_discardUnsupported() =
+        testScope.runTest {
+            systemShortcutsSource.setGroups(TestShortcuts.groupsWithUnsupportedModifier)
+            val categories by collectLastValue(interactor.shortcutCategories)
+
+            helper.showFromActivity()
+
+            assertThat(categories)
+                .containsExactly(
+                    ShortcutCategory(
+                        type = SYSTEM,
+                        subCategories = TestShortcuts.subCategoriesWithUnsupportedModifiersRemoved
+                    ),
+                    TestShortcuts.multitaskingCategory,
+                    TestShortcuts.imeCategory,
+                )
+                .inOrder()
+        }
+
+    @Test
+    fun categories_stateActive_multitaskingShortcutsWithUnsupportedModifiers_discardUnsupported() =
+        testScope.runTest {
+            multitaskingShortcutsSource.setGroups(TestShortcuts.groupsWithUnsupportedModifier)
+            val categories by collectLastValue(interactor.shortcutCategories)
+
+            helper.showFromActivity()
+
+            assertThat(categories)
+                .containsExactly(
+                    TestShortcuts.systemCategory,
+                    ShortcutCategory(
+                        type = MULTI_TASKING,
+                        subCategories = TestShortcuts.subCategoriesWithUnsupportedModifiersRemoved
+                    ),
+                    TestShortcuts.imeCategory,
+                )
+                .inOrder()
+        }
+
+    @Test
+    fun categories_stateActive_systemShortcutsWithOnlyUnsupportedModifiers_discardsCategory() =
+        testScope.runTest {
+            systemShortcutsSource.setGroups(TestShortcuts.groupsWithOnlyUnsupportedModifiers)
+            val categories by collectLastValue(interactor.shortcutCategories)
+
+            helper.showFromActivity()
+
+            assertThat(categories)
+                .containsExactly(
+                    TestShortcuts.multitaskingCategory,
+                    TestShortcuts.imeCategory,
+                )
+                .inOrder()
+        }
+
+    @Test
+    fun categories_stateActive_multitaskingShortcutsWitOnlyUnsupportedModifiers_discardsCategory() =
+        testScope.runTest {
+            multitaskingShortcutsSource.setGroups(TestShortcuts.groupsWithOnlyUnsupportedModifiers)
+            val categories by collectLastValue(interactor.shortcutCategories)
+
+            helper.showFromActivity()
+
+            assertThat(categories)
+                .containsExactly(
+                    TestShortcuts.systemCategory,
+                    TestShortcuts.imeCategory,
+                )
+                .inOrder()
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt
index c985199..80d487c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.coroutines.collectValues
 import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
 import com.android.systemui.keyboard.shortcut.shortcutHelperViewModel
+import com.android.systemui.keyboard.shortcut.ui.model.ShortcutsUiState
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testCase
 import com.android.systemui.kosmos.testDispatcher
@@ -163,4 +164,34 @@
 
             assertThat(sysUiState.isFlagEnabled(SYSUI_STATE_SHORTCUT_HELPER_SHOWING)).isFalse()
         }
+
+    @Test
+    fun shortcutsUiState_inactiveByDefault() =
+        testScope.runTest {
+            val uiState by collectLastValue(viewModel.shortcutsUiState)
+
+            assertThat(uiState).isEqualTo(ShortcutsUiState.Inactive)
+        }
+
+    @Test
+    fun shortcutsUiState_featureActive_emitsActive() =
+        testScope.runTest {
+            val uiState by collectLastValue(viewModel.shortcutsUiState)
+
+            testHelper.showFromActivity()
+
+            assertThat(uiState).isInstanceOf(ShortcutsUiState.Active::class.java)
+        }
+
+    @Test
+    fun shortcutsUiState_featureActive_emitsActiveWithFirstCategorySelectedByDefault() =
+        testScope.runTest {
+            val uiState by collectLastValue(viewModel.shortcutsUiState)
+
+            testHelper.showFromActivity()
+
+            val activeUiState = uiState as ShortcutsUiState.Active
+            assertThat(activeUiState.defaultSelectedCategory)
+                .isEqualTo(activeUiState.shortcutCategories.first().type)
+        }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
index 90ac05f..506c5ae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/CustomizationProviderTest.kt
@@ -135,7 +135,6 @@
                             .thenReturn(FakeSharedPreferences())
                     },
                 userTracker = userTracker,
-                systemSettings = FakeSettings(),
                 broadcastDispatcher = fakeBroadcastDispatcher,
             )
         val remoteUserSelectionManager =
@@ -481,8 +480,7 @@
                         )
                     }
                 }
-            }
-            ?: emptyList()
+            } ?: emptyList()
     }
 
     private fun querySlots(): List<Slot> {
@@ -517,8 +515,7 @@
                         )
                     }
                 }
-            }
-            ?: emptyList()
+            } ?: emptyList()
     }
 
     private fun queryAffordances(): List<Affordance> {
@@ -558,8 +555,7 @@
                         )
                     }
                 }
-            }
-            ?: emptyList()
+            } ?: emptyList()
     }
 
     data class Slot(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
index 27b9863..f726aae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
@@ -7,6 +7,7 @@
 import android.graphics.Rect
 import android.os.PowerManager
 import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
 import android.testing.TestableLooper.RunWithLooper
 import android.view.RemoteAnimationTarget
 import android.view.SurfaceControl
@@ -99,6 +100,13 @@
             mock(ActivityManager.RunningTaskInfo::class.java), false)
     private lateinit var wallpaperTargets: Array<RemoteAnimationTarget>
 
+    private var surfaceControlLockWp = mock(SurfaceControl::class.java)
+    private var lockWallpaperTarget = RemoteAnimationTarget(
+            3 /* taskId */, 0, surfaceControlLockWp, false, Rect(), Rect(), 0, Point(), Rect(),
+            Rect(), mock(WindowConfiguration::class.java), false, surfaceControlLockWp,
+            Rect(), mock(ActivityManager.RunningTaskInfo::class.java), false)
+    private lateinit var lockWallpaperTargets: Array<RemoteAnimationTarget>
+
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
@@ -118,6 +126,7 @@
         // appear amount setter doesn't short circuit.
         remoteAnimationTargets = arrayOf(remoteTarget1)
         wallpaperTargets = arrayOf(wallpaperTarget)
+        lockWallpaperTargets = arrayOf(lockWallpaperTarget)
 
         // Set the surface applier to our mock so that we can verify the arguments passed to it.
         // This applier does not have any side effects within the unlock animation controller, so
@@ -144,6 +153,7 @@
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
             remoteAnimationTargets,
             arrayOf(),
+            arrayOf(),
             0 /* startTime */,
             false /* requestedShowSurfaceBehindKeyguard */
         )
@@ -177,6 +187,7 @@
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
             remoteAnimationTargets,
             wallpaperTargets,
+            arrayOf(),
             0 /* startTime */,
             false /* requestedShowSurfaceBehindKeyguard */
         )
@@ -199,6 +210,7 @@
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
             remoteAnimationTargets,
             wallpaperTargets,
+            arrayOf(),
             0 /* startTime */,
             false /* requestedShowSurfaceBehindKeyguard */
         )
@@ -219,6 +231,7 @@
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
             remoteAnimationTargets,
             wallpaperTargets,
+            arrayOf(),
             0 /* startTime */,
             false /* requestedShowSurfaceBehindKeyguard */
         )
@@ -242,6 +255,7 @@
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
             remoteAnimationTargets,
             wallpaperTargets,
+            arrayOf(),
             0 /* startTime */,
             true /* requestedShowSurfaceBehindKeyguard */
         )
@@ -265,6 +279,7 @@
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
             remoteAnimationTargets,
             wallpaperTargets,
+            arrayOf(),
             0 /* startTime */,
             true /* requestedShowSurfaceBehindKeyguard */
         )
@@ -286,6 +301,7 @@
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
             remoteAnimationTargets,
             wallpaperTargets,
+            arrayOf(),
             0 /* startTime */,
             false /* requestedShowSurfaceBehindKeyguard */
         )
@@ -301,6 +317,7 @@
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
             remoteAnimationTargets,
             wallpaperTargets,
+            arrayOf(),
             0 /* startTime */,
             true /* requestedShowSurfaceBehindKeyguard */
         )
@@ -317,6 +334,7 @@
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
                 remoteAnimationTargets,
                 wallpaperTargets,
+                arrayOf(),
                 0 /* startTime */,
                 false /* requestedShowSurfaceBehindKeyguard */
         )
@@ -325,6 +343,53 @@
     }
 
     /**
+     * The canned animation should launch a cross fade when there are different wallpapers on lock
+     * and home screen.
+     */
+    @Test
+    @EnableFlags(Flags.FLAG_FASTER_UNLOCK_TRANSITION)
+    fun manualUnlock_multipleWallpapers() {
+        var lastFadeInAlpha = -1f
+        var lastFadeOutAlpha = -1f
+
+        keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
+                arrayOf(remoteTarget1, remoteTarget2),
+                wallpaperTargets,
+                lockWallpaperTargets,
+                0 /* startTime */,
+                false /* requestedShowSurfaceBehindKeyguard */
+        )
+
+        for (i in 0..10) {
+            clearInvocations(surfaceTransactionApplier)
+            val amount = i / 10f
+
+            keyguardUnlockAnimationController.setSurfaceBehindAppearAmount(amount)
+
+            val captorSb = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>()
+            verify(surfaceTransactionApplier, times(2)).scheduleApply(
+                    captorSb.capture { sp ->
+                        sp.surface == surfaceControlWp || sp.surface == surfaceControlLockWp })
+
+            val fadeInAlpha = captorSb.getLastValue { it.surface == surfaceControlWp }.alpha
+            val fadeOutAlpha = captorSb.getLastValue { it.surface == surfaceControlLockWp }.alpha
+
+            if (amount == 0f) {
+                assertTrue (fadeInAlpha == 0f)
+                assertTrue (fadeOutAlpha == 1f)
+            } else if (amount == 1f) {
+                assertTrue (fadeInAlpha == 1f)
+                assertTrue (fadeOutAlpha == 0f)
+            } else {
+                assertTrue(fadeInAlpha >= lastFadeInAlpha)
+                assertTrue(fadeOutAlpha <= lastFadeOutAlpha)
+            }
+            lastFadeInAlpha = fadeInAlpha
+            lastFadeOutAlpha = fadeOutAlpha
+        }
+    }
+
+    /**
      * If we are not wake and unlocking, we expect the unlock animation to play normally.
      */
     @Test
@@ -333,6 +398,7 @@
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
                 arrayOf(remoteTarget1, remoteTarget2),
                 wallpaperTargets,
+                arrayOf(),
                 0 /* startTime */,
                 false /* requestedShowSurfaceBehindKeyguard */
         )
@@ -378,6 +444,7 @@
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
                 remoteAnimationTargets,
                 wallpaperTargets,
+                arrayOf(),
                 0 /* startTime */,
                 false /* requestedShowSurfaceBehindKeyguard */
         )
@@ -387,7 +454,7 @@
         clearInvocations(surfaceTransactionApplier)
 
         keyguardUnlockAnimationController.setSurfaceBehindAppearAmount(1f)
-        keyguardUnlockAnimationController.setWallpaperAppearAmount(1f)
+        keyguardUnlockAnimationController.setWallpaperAppearAmount(1f, wallpaperTargets)
 
         val captorSb = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>()
         verify(surfaceTransactionApplier, times(1)).scheduleApply(
@@ -414,6 +481,7 @@
         keyguardUnlockAnimationController.notifyStartSurfaceBehindRemoteAnimation(
                 remoteAnimationTargets,
                 wallpaperTargets,
+                arrayOf(),
                 0 /* startTime */,
                 false /* requestedShowSurfaceBehindKeyguard */
         )
@@ -423,7 +491,7 @@
         clearInvocations(surfaceTransactionApplier)
 
         keyguardUnlockAnimationController.setSurfaceBehindAppearAmount(1f)
-        keyguardUnlockAnimationController.setWallpaperAppearAmount(1f)
+        keyguardUnlockAnimationController.setWallpaperAppearAmount(1f, wallpaperTargets)
 
         val captorSb = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>()
         verify(surfaceTransactionApplier, times(1)).scheduleApply(
@@ -532,8 +600,8 @@
             }
         }
 
-        fun getLastValue(): T {
-            return allArgs.last()
+        fun getLastValue(predicate: Predicate<T>? = null): T {
+            return if (predicate != null) allArgs.last(predicate::test) else allArgs.last()
         }
 
         fun getAllValues(): List<T> {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
index 144e634..23fd997 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ResourceTrimmerTest.kt
@@ -18,7 +18,6 @@
 import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.scene.data.repository.Idle
 import com.android.systemui.scene.data.repository.setSceneTransition
-import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.testKosmos
 import com.android.systemui.utils.GlobalWindowManager
@@ -64,7 +63,6 @@
                 globalWindowManager = globalWindowManager,
                 applicationScope = testScope.backgroundScope,
                 bgDispatcher = kosmos.testDispatcher,
-                sceneInteractor = kosmos.sceneInteractor,
             )
         resourceTrimmer.start()
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt
index 42ab25f..032794c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorTest.kt
@@ -56,6 +56,7 @@
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
+import org.junit.Ignore
 import org.junit.runner.RunWith
 import org.mockito.Mockito.reset
 import org.mockito.Mockito.spy
@@ -97,6 +98,7 @@
 
     @Test
     @EnableFlags(Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
+    @Ignore("Until b/349837588 is fixed")
     fun testTransitionToOccluded_ifDreamEnds_occludingActivityOnTop() =
         testScope.runTest {
             kosmos.fakeKeyguardRepository.setDreaming(true)
@@ -156,6 +158,7 @@
             reset(transitionRepository)
 
             kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(onTop = false)
+            kosmos.fakeKeyguardRepository.setDreaming(false)
             runCurrent()
 
             assertThat(transitionRepository)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/InWindowLauncherUnlockAnimationInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/InWindowLauncherUnlockAnimationInteractorTest.kt
index 459e41d..ea5a41f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/InWindowLauncherUnlockAnimationInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/InWindowLauncherUnlockAnimationInteractorTest.kt
@@ -18,25 +18,22 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.SysUITestModule
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.TestMocksModule
-import com.android.systemui.biometrics.domain.BiometricsDomainLayerModule
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.keyguard.data.repository.FakeKeyguardSurfaceBehindRepository
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.data.repository.InWindowLauncherUnlockAnimationRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.data.repository.inWindowLauncherUnlockAnimationRepository
+import com.android.systemui.keyguard.data.repository.keyguardSurfaceBehindRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.keyguard.util.mockTopActivityClassName
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testScope
 import com.android.systemui.shared.system.ActivityManagerWrapper
-import com.android.systemui.user.domain.UserDomainLayerModule
-import dagger.BindsInstance
-import dagger.Component
+import com.android.systemui.shared.system.activityManagerWrapper
+import com.android.systemui.testKosmos
 import junit.framework.Assert.assertEquals
-import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -49,10 +46,16 @@
 @RunWith(AndroidJUnit4::class)
 @kotlinx.coroutines.ExperimentalCoroutinesApi
 class InWindowLauncherUnlockAnimationInteractorTest : SysuiTestCase() {
-    private lateinit var underTest: InWindowLauncherUnlockAnimationInteractor
-
-    private lateinit var testComponent: TestComponent
-    private lateinit var testScope: TestScope
+    private val kosmos = testKosmos()
+    private val underTest =
+        InWindowLauncherUnlockAnimationInteractor(
+            kosmos.inWindowLauncherUnlockAnimationRepository,
+            kosmos.applicationCoroutineScope,
+            kosmos.keyguardTransitionInteractor,
+            { kosmos.keyguardSurfaceBehindRepository },
+            kosmos.activityManagerWrapper,
+        )
+    private val testScope = kosmos.testScope
     private lateinit var transitionRepository: FakeKeyguardTransitionRepository
     @Mock private lateinit var activityManagerWrapper: ActivityManagerWrapper
 
@@ -62,19 +65,9 @@
     fun setUp() {
         MockitoAnnotations.initMocks(this)
 
-        testComponent =
-            DaggerInWindowLauncherUnlockAnimationInteractorTest_TestComponent.factory()
-                .create(
-                    test = this,
-                    mocks =
-                        TestMocksModule(
-                            activityManagerWrapper = activityManagerWrapper,
-                        ),
-                )
-        underTest = testComponent.underTest
-        testScope = testComponent.testScope
-        transitionRepository = testComponent.transitionRepository
+        transitionRepository = kosmos.fakeKeyguardTransitionRepository
 
+        activityManagerWrapper = kosmos.activityManagerWrapper
         activityManagerWrapper.mockTopActivityClassName(launcherClassName)
     }
 
@@ -92,7 +85,7 @@
             )
 
             // Put launcher on top
-            testComponent.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
+            kosmos.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
                 launcherClassName
             )
             activityManagerWrapper.mockTopActivityClassName(launcherClassName)
@@ -175,7 +168,7 @@
             )
 
             // Put not launcher on top
-            testComponent.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
+            kosmos.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
                 launcherClassName
             )
             activityManagerWrapper.mockTopActivityClassName("not_launcher")
@@ -252,7 +245,7 @@
             )
 
             // Put launcher on top
-            testComponent.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
+            kosmos.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
                 launcherClassName
             )
             activityManagerWrapper.mockTopActivityClassName(launcherClassName)
@@ -296,7 +289,7 @@
             )
 
             // Put Launcher on top and begin transitioning to GONE.
-            testComponent.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
+            kosmos.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
                 launcherClassName
             )
             activityManagerWrapper.mockTopActivityClassName(launcherClassName)
@@ -316,7 +309,7 @@
                 values
             )
 
-            testComponent.surfaceBehindRepository.setSurfaceRemoteAnimationTargetAvailable(true)
+            kosmos.keyguardSurfaceBehindRepository.setSurfaceRemoteAnimationTargetAvailable(true)
             runCurrent()
 
             assertEquals(
@@ -360,7 +353,7 @@
             )
 
             // Put Launcher on top and begin transitioning to GONE.
-            testComponent.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
+            kosmos.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
                 launcherClassName
             )
             activityManagerWrapper.mockTopActivityClassName(launcherClassName)
@@ -402,7 +395,7 @@
             )
 
             // Put Launcher on top and begin transitioning to GONE.
-            testComponent.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
+            kosmos.inWindowLauncherUnlockAnimationRepository.setLauncherActivityClass(
                 launcherClassName
             )
             activityManagerWrapper.mockTopActivityClassName(launcherClassName)
@@ -427,7 +420,7 @@
                     to = KeyguardState.AOD,
                 )
             )
-            testComponent.surfaceBehindRepository.setSurfaceRemoteAnimationTargetAvailable(true)
+            kosmos.keyguardSurfaceBehindRepository.setSurfaceRemoteAnimationTargetAvailable(true)
             runCurrent()
 
             assertEquals(
@@ -437,29 +430,4 @@
                 values
             )
         }
-
-    @SysUISingleton
-    @Component(
-        modules =
-            [
-                SysUITestModule::class,
-                BiometricsDomainLayerModule::class,
-                UserDomainLayerModule::class,
-            ]
-    )
-    interface TestComponent {
-        val underTest: InWindowLauncherUnlockAnimationInteractor
-        val testScope: TestScope
-        val transitionRepository: FakeKeyguardTransitionRepository
-        val surfaceBehindRepository: FakeKeyguardSurfaceBehindRepository
-        val inWindowLauncherUnlockAnimationRepository: InWindowLauncherUnlockAnimationRepository
-
-        @Component.Factory
-        interface Factory {
-            fun create(
-                @BindsInstance test: SysuiTestCase,
-                mocks: TestMocksModule,
-            ): TestComponent
-        }
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
index d2a9c58..7560a97 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorParameterizedTest.kt
@@ -63,9 +63,6 @@
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
-import platform.test.runner.parameterized.ParameterizedAndroidJunit4
-import platform.test.runner.parameterized.Parameters
-import platform.test.runner.parameterized.Parameter
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.anyInt
@@ -76,6 +73,9 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyZeroInteractions
 import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.Parameter
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @FlakyTest(
@@ -281,7 +281,6 @@
                             .thenReturn(FakeSharedPreferences())
                     },
                 userTracker = userTracker,
-                systemSettings = FakeSettings(),
                 broadcastDispatcher = fakeBroadcastDispatcher,
             )
         val remoteUserSelectionManager =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorSceneContainerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorSceneContainerTest.kt
index 9d06031..fd1bf54 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorSceneContainerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorSceneContainerTest.kt
@@ -63,9 +63,6 @@
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
-import platform.test.runner.parameterized.ParameterizedAndroidJunit4
-import platform.test.runner.parameterized.Parameters
-import platform.test.runner.parameterized.Parameter
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.anyInt
@@ -76,6 +73,9 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyZeroInteractions
 import org.mockito.MockitoAnnotations
+import platform.test.runner.parameterized.Parameter
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @FlakyTest(
@@ -281,7 +281,6 @@
                             .thenReturn(FakeSharedPreferences())
                     },
                 userTracker = userTracker,
-                systemSettings = FakeSettings(),
                 broadcastDispatcher = fakeBroadcastDispatcher,
             )
         val remoteUserSelectionManager =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt
index f32e775..c9871f1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt
@@ -21,6 +21,9 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
+import com.android.systemui.flags.DisableSceneContainer
+import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.KeyguardSurfaceBehindModel
@@ -28,12 +31,18 @@
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.keyguard.util.mockTopActivityClassName
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.data.repository.Idle
+import com.android.systemui.scene.data.repository.Transition
+import com.android.systemui.scene.data.repository.setSceneTransition
+import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.shared.system.ActivityManagerWrapper
 import com.android.systemui.shared.system.activityManagerWrapper
 import com.android.systemui.statusbar.notification.domain.interactor.notificationLaunchAnimationInteractor
 import com.android.systemui.testKosmos
 import com.android.systemui.util.assertValuesMatch
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
+import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -44,16 +53,22 @@
 @kotlinx.coroutines.ExperimentalCoroutinesApi
 class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
     private val kosmos = testKosmos()
-    private val testScope = kosmos.testScope
-    private val underTest = kosmos.keyguardSurfaceBehindInteractor
-    private val transitionRepository = kosmos.fakeKeyguardTransitionRepository
-    private val inWindowUnlockInteractor = kosmos.inWindowLauncherUnlockAnimationInteractor
-    private val activityManagerWrapper = kosmos.activityManagerWrapper
+    private lateinit var testScope: TestScope
+    private lateinit var underTest: KeyguardSurfaceBehindInteractor
+    private lateinit var transitionRepository: FakeKeyguardTransitionRepository
+    private lateinit var inWindowUnlockInteractor: InWindowLauncherUnlockAnimationInteractor
+    private lateinit var activityManagerWrapper: ActivityManagerWrapper
 
     private val LAUNCHER_ACTIVITY_NAME = "launcher"
 
     @Before
     fun setUp() {
+        testScope = kosmos.testScope
+        underTest = kosmos.keyguardSurfaceBehindInteractor
+        transitionRepository = kosmos.fakeKeyguardTransitionRepository
+        inWindowUnlockInteractor = kosmos.inWindowLauncherUnlockAnimationInteractor
+        activityManagerWrapper = kosmos.activityManagerWrapper
+
         inWindowUnlockInteractor.setLauncherActivityClass(LAUNCHER_ACTIVITY_NAME)
 
         // Default to having something other than Launcher on top.
@@ -61,6 +76,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     fun testSurfaceBehindModel_toAppSurface() =
         testScope.runTest {
             val values by collectValues(underTest.viewParams)
@@ -136,6 +152,7 @@
         }
 
     @Test
+    @DisableSceneContainer
     fun testSurfaceBehindModel_toLauncher() =
         testScope.runTest {
             val values by collectValues(underTest.viewParams)
@@ -196,6 +213,7 @@
         }
 
     @Test
+    @DisableSceneContainer
     fun testSurfaceBehindModel_fromNotificationLaunch() =
         testScope.runTest {
             val values by collectValues(underTest.viewParams)
@@ -230,6 +248,105 @@
         }
 
     @Test
+    @EnableSceneContainer
+    fun testSurfaceBehindModel_toAppSurface_scene_container() =
+        testScope.runTest {
+            val values by collectValues(underTest.viewParams)
+            runCurrent()
+
+            assertThat(values)
+                .containsExactly(
+                    // We're initialized in LOCKSCREEN.
+                    KeyguardSurfaceBehindModel(alpha = 0f),
+                )
+
+            kosmos.setSceneTransition(Transition(Scenes.Lockscreen, Scenes.Gone))
+
+            values.assertValuesMatch(
+                { it == KeyguardSurfaceBehindModel(alpha = 0f) },
+                // Once we start a transition to GONE, we should fade in and translate up. The exact
+                // start value depends on screen density, so just look for != 0.
+                {
+                    it.animateFromAlpha == 0f &&
+                        it.alpha == 1f &&
+                        it.animateFromTranslationY != 0f &&
+                        it.translationY == 0f
+                }
+            )
+
+            kosmos.setSceneTransition(Idle(Scenes.Gone))
+
+            values.assertValuesMatch(
+                { it == KeyguardSurfaceBehindModel(alpha = 0f) },
+                {
+                    it.animateFromAlpha == 0f &&
+                        it.alpha == 1f &&
+                        it.animateFromTranslationY != 0f &&
+                        it.translationY == 0f
+                },
+                // Once the current state is GONE, we should default to alpha = 1f.
+                { it == KeyguardSurfaceBehindModel(alpha = 1f) }
+            )
+        }
+
+    @Test
+    @EnableSceneContainer
+    fun testSurfaceBehindModel_toLauncher_scene_container() =
+        testScope.runTest {
+            val values by collectValues(underTest.viewParams)
+            activityManagerWrapper.mockTopActivityClassName(LAUNCHER_ACTIVITY_NAME)
+            runCurrent()
+
+            assertThat(values)
+                .containsExactly(
+                    // We're initialized in LOCKSCREEN.
+                    KeyguardSurfaceBehindModel(alpha = 0f),
+                )
+                .inOrder()
+
+            kosmos.setSceneTransition(Transition(Scenes.Lockscreen, Scenes.Gone))
+
+            assertThat(values)
+                .containsExactly(
+                    KeyguardSurfaceBehindModel(alpha = 0f),
+                    // We should instantly set alpha = 1, with no animations, when Launcher is
+                    // behind
+                    // the keyguard since we're playing in-window animations.
+                    KeyguardSurfaceBehindModel(alpha = 1f),
+                )
+                .inOrder()
+
+            kosmos.setSceneTransition(Idle(Scenes.Gone))
+
+            assertThat(values)
+                .containsExactly(
+                    KeyguardSurfaceBehindModel(alpha = 0f),
+                    // Should have remained at alpha = 1f through the entire animation.
+                    KeyguardSurfaceBehindModel(alpha = 1f),
+                )
+                .inOrder()
+        }
+
+    @Test
+    @EnableSceneContainer
+    fun testSurfaceBehindModel_fromNotificationLaunch_scene_container() =
+        testScope.runTest {
+            val values by collectValues(underTest.viewParams)
+            runCurrent()
+
+            kosmos.notificationLaunchAnimationInteractor.setIsLaunchAnimationRunning(true)
+            runCurrent()
+
+            kosmos.setSceneTransition(Transition(Scenes.Lockscreen, Scenes.Gone))
+
+            values.assertValuesMatch(
+                // We should be at alpha = 0f during the animation.
+                { it == KeyguardSurfaceBehindModel(alpha = 0f) },
+            )
+        }
+
+    @Test
+    @DisableSceneContainer
     fun notificationLaunchFromLockscreen_isAnimatingSurfaceTrue() =
         testScope.runTest {
             val isAnimatingSurface by collectLastValue(underTest.isAnimatingSurface)
@@ -253,6 +370,7 @@
         }
 
     @Test
+    @DisableSceneContainer
     fun notificationLaunchFromGone_isAnimatingSurfaceFalse() =
         testScope.runTest {
             val isAnimatingSurface by collectLastValue(underTest.isAnimatingSurface)
@@ -276,6 +394,7 @@
         }
 
     @Test
+    @DisableSceneContainer
     fun notificationLaunchFalse_isAnimatingSurfaceFalse() =
         testScope.runTest {
             val isAnimatingSurface by collectLastValue(underTest.isAnimatingSurface)
@@ -297,4 +416,44 @@
             runCurrent()
             assertThat(isAnimatingSurface).isFalse()
         }
+
+    @Test
+    @EnableSceneContainer
+    fun notificationLaunchFromLockscreen_isAnimatingSurfaceTrue_scene_container() =
+        testScope.runTest {
+            val isAnimatingSurface by collectLastValue(underTest.isAnimatingSurface)
+
+            kosmos.setSceneTransition(Idle(Scenes.Lockscreen))
+            kosmos.notificationLaunchAnimationInteractor.setIsLaunchAnimationRunning(true)
+            runCurrent()
+
+            assertThat(isAnimatingSurface).isTrue()
+        }
+
+    @Test
+    @EnableSceneContainer
+    fun notificationLaunchFromGone_isAnimatingSurfaceFalse_scene_container() =
+        testScope.runTest {
+            val isAnimatingSurface by collectLastValue(underTest.isAnimatingSurface)
+
+            kosmos.setSceneTransition(Idle(Scenes.Gone))
+            kosmos.notificationLaunchAnimationInteractor.setIsLaunchAnimationRunning(true)
+            runCurrent()
+            assertThat(isAnimatingSurface).isFalse()
+
+            kosmos.setSceneTransition(Transition(from = Scenes.Gone, to = Scenes.Lockscreen))
+            assertThat(isAnimatingSurface).isFalse()
+        }
+
+    @Test
+    @EnableSceneContainer
+    fun notificationLaunchFalse_isAnimatingSurfaceFalse_scene_container() =
+        testScope.runTest {
+            val isAnimatingSurface by collectLastValue(underTest.isAnimatingSurface)
+
+            kosmos.setSceneTransition(Idle(Scenes.Lockscreen))
+            kosmos.notificationLaunchAnimationInteractor.setIsLaunchAnimationRunning(false)
+            runCurrent()
+            assertThat(isAnimatingSurface).isFalse()
+        }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
index 246cfbf..3b0f623 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.communal.domain.interactor.communalInteractor
 import com.android.systemui.communal.domain.interactor.setCommunalAvailable
 import com.android.systemui.communal.shared.model.CommunalScenes
-import com.android.systemui.dock.fakeDockManager
 import com.android.systemui.flags.BrokenWithSceneContainer
 import com.android.systemui.flags.DisableSceneContainer
 import com.android.systemui.flags.FakeFeatureFlags
@@ -124,7 +123,6 @@
 
     private val powerInteractor by lazy { kosmos.powerInteractor }
     private val communalInteractor by lazy { kosmos.communalInteractor }
-    private val dockManager by lazy { kosmos.fakeDockManager }
 
     companion object {
         @JvmStatic
@@ -583,6 +581,7 @@
         }
 
     @Test
+    @DisableSceneContainer
     fun dozingToPrimaryBouncer() =
         testScope.runTest {
             // GIVEN a prior transition has run to DOZING
@@ -597,8 +596,8 @@
 
             assertThat(transitionRepository)
                 .startedTransition(
-                    to = KeyguardState.PRIMARY_BOUNCER,
                     from = KeyguardState.DOZING,
+                    to = KeyguardState.PRIMARY_BOUNCER,
                     animatorAssertion = { it.isNotNull() }
                 )
 
@@ -633,6 +632,7 @@
         }
 
     @Test
+    @DisableSceneContainer
     fun dozingToGlanceableHub() =
         testScope.runTest {
             // GIVEN a prior transition has run to DOZING
@@ -654,8 +654,8 @@
 
             assertThat(transitionRepository)
                 .startedTransition(
-                    to = KeyguardState.GLANCEABLE_HUB,
                     from = KeyguardState.DOZING,
+                    to = KeyguardState.GLANCEABLE_HUB,
                     animatorAssertion = { it.isNotNull() }
                 )
 
@@ -1314,6 +1314,7 @@
         }
 
     @Test
+    @DisableSceneContainer
     fun occludedToPrimaryBouncer() =
         testScope.runTest {
             // GIVEN a prior transition has run to OCCLUDED
@@ -1452,6 +1453,7 @@
         }
 
     @Test
+    @DisableSceneContainer
     fun dreamingToPrimaryBouncer() =
         testScope.runTest {
             // GIVEN a prior transition has run to DREAMING
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorTest.kt
new file mode 100644
index 0000000..22181f8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorTest.kt
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyguard.domain.interactor
+
+import android.app.AlarmManager
+import android.app.admin.alarmManager
+import android.app.admin.devicePolicyManager
+import android.content.BroadcastReceiver
+import android.content.Intent
+import android.content.mockedContext
+import android.os.PowerManager
+import android.os.UserHandle
+import android.provider.Settings
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.internal.widget.lockPatternUtils
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.BiometricUnlockMode
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
+import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
+import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.testKosmos
+import com.android.systemui.util.settings.fakeSettings
+import junit.framework.Assert.assertEquals
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.anyLong
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doAnswer
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class KeyguardWakeDirectlyToGoneInteractorTest : SysuiTestCase() {
+
+    private var lastRegisteredBroadcastReceiver: BroadcastReceiver? = null
+    private val kosmos =
+        testKosmos().apply {
+            whenever(mockedContext.user).thenReturn(mock<UserHandle>())
+            doAnswer { invocation ->
+                    lastRegisteredBroadcastReceiver = invocation.arguments[0] as BroadcastReceiver
+                }
+                .whenever(mockedContext)
+                .registerReceiver(any(), any(), any(), any(), any())
+        }
+
+    private val testScope = kosmos.testScope
+    private val underTest = kosmos.keyguardWakeDirectlyToGoneInteractor
+    private val lockPatternUtils = kosmos.lockPatternUtils
+    private val repository = kosmos.fakeKeyguardRepository
+    private val transitionRepository = kosmos.fakeKeyguardTransitionRepository
+
+    @Test
+    fun testCanWakeDirectlyToGone_keyguardServiceEnabledThenDisabled() =
+        testScope.runTest {
+            val canWake by collectValues(underTest.canWakeDirectlyToGone)
+
+            assertEquals(
+                listOf(
+                    false, // Defaults to false.
+                ),
+                canWake
+            )
+
+            repository.setKeyguardEnabled(false)
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    false, // Default to false.
+                    true, // True now that keyguard service is disabled
+                ),
+                canWake
+            )
+
+            repository.setKeyguardEnabled(true)
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    false,
+                    true,
+                    false,
+                ),
+                canWake
+            )
+        }
+
+    @Test
+    fun testCanWakeDirectlyToGone_lockscreenDisabledThenEnabled() =
+        testScope.runTest {
+            val canWake by collectValues(underTest.canWakeDirectlyToGone)
+
+            assertEquals(
+                listOf(
+                    false, // Defaults to false.
+                ),
+                canWake
+            )
+
+            whenever(lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(true)
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    // Still false - isLockScreenDisabled only causes canWakeDirectlyToGone to
+                    // update on the next wake/sleep event.
+                    false,
+                ),
+                canWake
+            )
+
+            kosmos.powerInteractor.setAsleepForTest()
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    false,
+                    // True since we slept after setting isLockScreenDisabled=true
+                    true,
+                ),
+                canWake
+            )
+
+            kosmos.powerInteractor.setAwakeForTest()
+            runCurrent()
+
+            kosmos.powerInteractor.setAsleepForTest()
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    false,
+                    true,
+                ),
+                canWake
+            )
+
+            whenever(lockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false)
+            kosmos.powerInteractor.setAwakeForTest()
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    false,
+                    true,
+                    false,
+                ),
+                canWake
+            )
+        }
+
+    @Test
+    fun testCanWakeDirectlyToGone_wakeAndUnlock() =
+        testScope.runTest {
+            val canWake by collectValues(underTest.canWakeDirectlyToGone)
+
+            assertEquals(
+                listOf(
+                    false, // Defaults to false.
+                ),
+                canWake
+            )
+
+            repository.setBiometricUnlockState(BiometricUnlockMode.WAKE_AND_UNLOCK)
+            runCurrent()
+
+            assertEquals(listOf(false, true), canWake)
+
+            repository.setBiometricUnlockState(BiometricUnlockMode.NONE)
+            runCurrent()
+
+            assertEquals(listOf(false, true, false), canWake)
+        }
+
+    @Test
+    fun testCanWakeDirectlyToGone_andSetsAlarm_ifPowerButtonDoesNotLockImmediately() =
+        testScope.runTest {
+            val canWake by collectValues(underTest.canWakeDirectlyToGone)
+
+            assertEquals(
+                listOf(
+                    false, // Defaults to false.
+                ),
+                canWake
+            )
+
+            repository.setCanIgnoreAuthAndReturnToGone(true)
+            runCurrent()
+
+            assertEquals(listOf(false, true), canWake)
+
+            repository.setCanIgnoreAuthAndReturnToGone(false)
+            runCurrent()
+
+            assertEquals(listOf(false, true, false), canWake)
+        }
+
+    @Test
+    fun testSetsCanIgnoreAuth_andSetsAlarm_whenTimingOut() =
+        testScope.runTest {
+            val canWake by collectValues(underTest.canWakeDirectlyToGone)
+
+            assertEquals(
+                listOf(
+                    false, // Defaults to false.
+                ),
+                canWake
+            )
+
+            whenever(kosmos.devicePolicyManager.getMaximumTimeToLock(eq(null), anyInt()))
+                .thenReturn(-1)
+            kosmos.fakeSettings.putInt(Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 500)
+
+            transitionRepository.sendTransitionSteps(
+                from = KeyguardState.LOCKSCREEN,
+                to = KeyguardState.GONE,
+                testScope,
+            )
+
+            kosmos.powerInteractor.setAsleepForTest(
+                sleepReason = PowerManager.GO_TO_SLEEP_REASON_TIMEOUT
+            )
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    false,
+                    true,
+                ),
+                canWake
+            )
+
+            verify(kosmos.alarmManager)
+                .setExactAndAllowWhileIdle(
+                    eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
+                    anyLong(),
+                    any(),
+                )
+        }
+
+    @Test
+    fun testCancelsFirstAlarm_onWake_withSecondAlarmSet() =
+        testScope.runTest {
+            val canWake by collectValues(underTest.canWakeDirectlyToGone)
+
+            assertEquals(
+                listOf(
+                    false, // Defaults to false.
+                ),
+                canWake
+            )
+
+            whenever(kosmos.devicePolicyManager.getMaximumTimeToLock(eq(null), anyInt()))
+                .thenReturn(-1)
+            kosmos.fakeSettings.putInt(Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT, 500)
+
+            transitionRepository.sendTransitionSteps(
+                from = KeyguardState.LOCKSCREEN,
+                to = KeyguardState.GONE,
+                testScope,
+            )
+
+            kosmos.powerInteractor.setAsleepForTest(
+                sleepReason = PowerManager.GO_TO_SLEEP_REASON_TIMEOUT
+            )
+            transitionRepository.sendTransitionSteps(
+                from = KeyguardState.LOCKSCREEN,
+                to = KeyguardState.AOD,
+                testScope = testScope,
+            )
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    false,
+                    // Timed out, so we can ignore auth/return to GONE.
+                    true,
+                ),
+                canWake
+            )
+
+            verify(kosmos.alarmManager)
+                .setExactAndAllowWhileIdle(
+                    eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
+                    anyLong(),
+                    any(),
+                )
+
+            kosmos.powerInteractor.setAwakeForTest()
+            transitionRepository.sendTransitionSteps(
+                from = KeyguardState.AOD,
+                to = KeyguardState.GONE,
+                testScope = testScope,
+            )
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    false,
+                    true,
+                    // Should be canceled by the wakeup, but there would still be an
+                    // alarm in flight that should be canceled.
+                    false,
+                ),
+                canWake
+            )
+
+            kosmos.powerInteractor.setAsleepForTest(
+                sleepReason = PowerManager.GO_TO_SLEEP_REASON_TIMEOUT
+            )
+            runCurrent()
+
+            assertEquals(
+                listOf(
+                    false,
+                    true,
+                    false,
+                    // Back to sleep.
+                    true,
+                ),
+                canWake
+            )
+
+            // Simulate the first sleep's alarm coming in.
+            lastRegisteredBroadcastReceiver?.onReceive(
+                kosmos.mockedContext,
+                Intent("com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD")
+            )
+            runCurrent()
+
+            // It should not have any effect.
+            assertEquals(
+                listOf(
+                    false,
+                    true,
+                    false,
+                    true,
+                ),
+                canWake
+            )
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinderTest.kt
new file mode 100644
index 0000000..c4eabd8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinderTest.kt
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyguard.ui.binder
+
+import android.platform.test.annotations.EnableFlags
+import android.testing.TestableLooper
+import android.view.View
+import android.view.layoutInflater
+import android.view.mockedLayoutInflater
+import android.view.windowManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.bouncer.domain.interactor.givenCanShowAlternateBouncer
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.res.R
+import com.android.systemui.testKosmos
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.whenever
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Mockito.any
+import org.mockito.Mockito.anyBoolean
+import org.mockito.Mockito.atLeastOnce
+import org.mockito.Mockito.never
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.verify
+import org.mockito.kotlin.isNull
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+class AlternateBouncerViewBinderTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+
+    private val mockedAltBouncerView =
+        spy(kosmos.layoutInflater.inflate(R.layout.alternate_bouncer, null, false))
+
+    @Before
+    fun setup() {
+        whenever(
+                kosmos.mockedLayoutInflater.inflate(
+                    eq(R.layout.alternate_bouncer),
+                    isNull(),
+                    anyBoolean()
+                )
+            )
+            .thenReturn(mockedAltBouncerView)
+        kosmos.alternateBouncerViewBinder.start()
+    }
+
+    @Test
+    @EnableFlags(FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
+    fun addViewToWindowManager() {
+        testScope.runTest {
+            kosmos.givenCanShowAlternateBouncer()
+            kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
+                from = KeyguardState.LOCKSCREEN,
+                to = KeyguardState.ALTERNATE_BOUNCER,
+                testScope,
+            )
+            verify(kosmos.windowManager).addView(any(), any())
+        }
+    }
+
+    @Test
+    @EnableFlags(FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
+    fun viewRemovedImmediatelyIfAlreadyAttachedToWindow() {
+        testScope.runTest {
+            kosmos.givenCanShowAlternateBouncer()
+            kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
+                from = KeyguardState.LOCKSCREEN,
+                to = KeyguardState.ALTERNATE_BOUNCER,
+                testScope,
+            )
+            verify(kosmos.windowManager).addView(any(), any())
+            whenever(mockedAltBouncerView.isAttachedToWindow).thenReturn(true)
+
+            kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
+                from = KeyguardState.ALTERNATE_BOUNCER,
+                to = KeyguardState.LOCKSCREEN,
+                testScope,
+            )
+            verify(kosmos.windowManager).removeView(any())
+        }
+    }
+
+    @Test
+    @EnableFlags(FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
+    fun viewNotRemovedUntilAttachedToWindow() {
+        testScope.runTest {
+            kosmos.givenCanShowAlternateBouncer()
+            kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
+                from = KeyguardState.LOCKSCREEN,
+                to = KeyguardState.ALTERNATE_BOUNCER,
+                testScope,
+            )
+            verify(kosmos.windowManager).addView(any(), any())
+
+            kosmos.fakeKeyguardTransitionRepository.sendTransitionSteps(
+                from = KeyguardState.ALTERNATE_BOUNCER,
+                to = KeyguardState.LOCKSCREEN,
+                testScope,
+            )
+
+            verify(kosmos.windowManager, never()).removeView(any())
+            givenAltBouncerViewAttachedToWindow()
+            verify(kosmos.windowManager).removeView(any())
+        }
+    }
+
+    private fun givenAltBouncerViewAttachedToWindow() {
+        val attachStateChangeListenerCaptor =
+            ArgumentCaptor.forClass(View.OnAttachStateChangeListener::class.java)
+        verify(mockedAltBouncerView, atLeastOnce())
+            .addOnAttachStateChangeListener(attachStateChangeListenerCaptor.capture())
+        attachStateChangeListenerCaptor.allValues.onEach {
+            it.onViewAttachedToWindow(mockedAltBouncerView)
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/InWindowLauncherUnlockAnimationManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/InWindowLauncherUnlockAnimationManagerTest.kt
index c7f4416..0cfc20d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/InWindowLauncherUnlockAnimationManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/InWindowLauncherUnlockAnimationManagerTest.kt
@@ -18,17 +18,15 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.SysUITestModule
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.domain.BiometricsDomainLayerModule
-import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.domain.interactor.inWindowLauncherUnlockAnimationInteractor
 import com.android.systemui.keyguard.ui.view.InWindowLauncherUnlockAnimationManager
+import com.android.systemui.keyguard.ui.viewmodel.InWindowLauncherAnimationViewModel
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testScope
 import com.android.systemui.shared.system.smartspace.ILauncherUnlockAnimationController
-import com.android.systemui.user.domain.UserDomainLayerModule
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.any
-import dagger.BindsInstance
-import dagger.Component
-import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
@@ -45,10 +43,9 @@
 @RunWith(AndroidJUnit4::class)
 @kotlinx.coroutines.ExperimentalCoroutinesApi
 class InWindowLauncherUnlockAnimationManagerTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
     private lateinit var underTest: InWindowLauncherUnlockAnimationManager
-
-    private lateinit var testComponent: TestComponent
-    private lateinit var testScope: TestScope
+    private val testScope = kosmos.testScope
 
     @Mock private lateinit var launcherUnlockAnimationController: ILauncherUnlockAnimationController
 
@@ -56,14 +53,14 @@
     fun setUp() {
         MockitoAnnotations.initMocks(this)
 
-        testComponent =
-            DaggerInWindowLauncherUnlockAnimationManagerTest_TestComponent.factory()
-                .create(
-                    test = this,
-                )
-        underTest = testComponent.underTest
-        testScope = testComponent.testScope
-
+        underTest =
+            InWindowLauncherUnlockAnimationManager(
+                kosmos.inWindowLauncherUnlockAnimationInteractor,
+                InWindowLauncherAnimationViewModel(
+                    kosmos.inWindowLauncherUnlockAnimationInteractor
+                ),
+                kosmos.applicationCoroutineScope
+            )
         underTest.setLauncherUnlockController("launcherClass", launcherUnlockAnimationController)
     }
 
@@ -114,25 +111,4 @@
 
             verifyNoMoreInteractions(launcherUnlockAnimationController)
         }
-
-    @SysUISingleton
-    @Component(
-        modules =
-            [
-                SysUITestModule::class,
-                BiometricsDomainLayerModule::class,
-                UserDomainLayerModule::class,
-            ]
-    )
-    interface TestComponent {
-        val underTest: InWindowLauncherUnlockAnimationManager
-        val testScope: TestScope
-
-        @Component.Factory
-        interface Factory {
-            fun create(
-                @BindsInstance test: SysuiTestCase,
-            ): TestComponent
-        }
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindParamsApplierTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindParamsApplierTest.kt
index 7787a7f..9055495 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindParamsApplierTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindParamsApplierTest.kt
@@ -18,6 +18,7 @@
 
 import android.testing.TestableLooper.RunWithLooper
 import android.view.RemoteAnimationTarget
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardViewController
 import com.android.systemui.SysuiTestCase
@@ -34,6 +35,7 @@
 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.anyBoolean
 import org.mockito.Mockito.doAnswer
@@ -42,6 +44,7 @@
 @SmallTest
 @RunWithLooper(setAsMainLooper = true)
 @kotlinx.coroutines.ExperimentalCoroutinesApi
+@RunWith(AndroidJUnit4::class)
 class KeyguardSurfaceBehindParamsApplierTest : SysuiTestCase() {
     @get:Rule val animatorTestRule = AnimatorTestRule(this)
 
@@ -155,4 +158,4 @@
         // Releasing the surface should immediately cancel animators.
         assertFalse(checkNotNull(isAnimatingSurface))
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelTest.kt
index 6398a5a..c1bd378 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerWindowViewModelTest.kt
@@ -19,26 +19,22 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.keyguard.keyguardUpdateMonitor
 import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.data.repository.fakeFingerprintPropertyRepository
-import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.statusbar.policy.keyguardStateController
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.kotlin.whenever
+import org.junit.runners.JUnit4
 
 @ExperimentalCoroutinesApi
 @RunWith(AndroidJUnit4::class)
@@ -54,35 +50,13 @@
     fun alternateBouncerTransition_alternateBouncerWindowRequiredTrue() =
         testScope.runTest {
             mSetFlagsRule.enableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
-            val canShowAlternateBouncer by collectLastValue(underTest.canShowAlternateBouncer)
             val alternateBouncerWindowRequired by
                 collectLastValue(underTest.alternateBouncerWindowRequired)
-            givenCanShowAlternateBouncer()
             fingerprintPropertyRepository.supportsUdfps()
             transitionRepository.sendTransitionSteps(
                 listOf(
-                    stepToLockscreen(0f, TransitionState.STARTED),
-                    stepToLockscreen(.4f),
-                    stepToLockscreen(1f, TransitionState.FINISHED),
-                ),
-                testScope,
-            )
-            assertThat(canShowAlternateBouncer).isTrue()
-            transitionRepository.sendTransitionSteps(
-                listOf(
-                    stepFromLockscreenToAlternateBouncer(0f, TransitionState.STARTED),
-                    stepFromLockscreenToAlternateBouncer(.4f),
-                    stepFromLockscreenToAlternateBouncer(.6f),
-                ),
-                testScope,
-            )
-            assertThat(canShowAlternateBouncer).isTrue()
-            assertThat(alternateBouncerWindowRequired).isTrue()
-
-            transitionRepository.sendTransitionSteps(
-                listOf(
                     stepFromAlternateBouncer(0f, TransitionState.STARTED),
-                    stepFromAlternateBouncer(.2f),
+                    stepFromAlternateBouncer(.4f),
                     stepFromAlternateBouncer(.6f),
                 ),
                 testScope,
@@ -104,21 +78,13 @@
             mSetFlagsRule.disableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
             val alternateBouncerWindowRequired by
                 collectLastValue(underTest.alternateBouncerWindowRequired)
-            givenCanShowAlternateBouncer()
             fingerprintPropertyRepository.supportsUdfps()
             transitionRepository.sendTransitionSteps(
                 listOf(
-                    stepToLockscreen(0f, TransitionState.STARTED),
-                    stepToLockscreen(.4f),
-                    stepToLockscreen(1f, TransitionState.FINISHED),
-                ),
-                testScope,
-            )
-            transitionRepository.sendTransitionSteps(
-                listOf(
-                    stepFromLockscreenToAlternateBouncer(0f, TransitionState.STARTED),
-                    stepFromLockscreenToAlternateBouncer(.4f),
-                    stepFromLockscreenToAlternateBouncer(.6f),
+                    stepFromAlternateBouncer(0f, TransitionState.STARTED),
+                    stepFromAlternateBouncer(.4f),
+                    stepFromAlternateBouncer(.6f),
+                    stepFromAlternateBouncer(1f),
                 ),
                 testScope,
             )
@@ -131,23 +97,13 @@
             mSetFlagsRule.enableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
             val alternateBouncerWindowRequired by
                 collectLastValue(underTest.alternateBouncerWindowRequired)
-            givenCanShowAlternateBouncer()
             fingerprintPropertyRepository.supportsUdfps()
             transitionRepository.sendTransitionSteps(
                 listOf(
-                    stepFromLockscreenToDozing(0f, TransitionState.STARTED),
-                    stepFromLockscreenToDozing(.4f),
-                    stepFromLockscreenToDozing(.6f),
-                    stepFromLockscreenToDozing(1f, TransitionState.FINISHED),
-                ),
-                testScope,
-            )
-            assertThat(alternateBouncerWindowRequired).isFalse()
-            transitionRepository.sendTransitionSteps(
-                listOf(
                     stepFromDozingToLockscreen(0f, TransitionState.STARTED),
                     stepFromDozingToLockscreen(.4f),
                     stepFromDozingToLockscreen(.6f),
+                    stepFromDozingToLockscreen(1f),
                 ),
                 testScope,
             )
@@ -160,39 +116,19 @@
             mSetFlagsRule.enableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
             val alternateBouncerWindowRequired by
                 collectLastValue(underTest.alternateBouncerWindowRequired)
-            givenCanShowAlternateBouncer()
             fingerprintPropertyRepository.supportsRearFps()
             transitionRepository.sendTransitionSteps(
                 listOf(
-                    stepToLockscreen(0f, TransitionState.STARTED),
-                    stepToLockscreen(.4f),
-                    stepToLockscreen(1f, TransitionState.FINISHED),
-                ),
-                testScope,
-            )
-            transitionRepository.sendTransitionSteps(
-                listOf(
-                    stepFromLockscreenToAlternateBouncer(0f, TransitionState.STARTED),
-                    stepFromLockscreenToAlternateBouncer(.4f),
-                    stepFromLockscreenToAlternateBouncer(.6f),
+                    stepFromAlternateBouncer(0f, TransitionState.STARTED),
+                    stepFromAlternateBouncer(.4f),
+                    stepFromAlternateBouncer(.6f),
+                    stepFromAlternateBouncer(1f),
                 ),
                 testScope,
             )
             assertThat(alternateBouncerWindowRequired).isFalse()
         }
 
-    private fun stepToLockscreen(
-        value: Float,
-        state: TransitionState = TransitionState.RUNNING
-    ): TransitionStep {
-        return step(
-            from = KeyguardState.GONE,
-            to = KeyguardState.LOCKSCREEN,
-            value = value,
-            transitionState = state,
-        )
-    }
-
     private fun stepFromAlternateBouncer(
         value: Float,
         state: TransitionState = TransitionState.RUNNING
@@ -205,18 +141,6 @@
         )
     }
 
-    private fun stepFromLockscreenToAlternateBouncer(
-        value: Float,
-        state: TransitionState = TransitionState.RUNNING
-    ): TransitionStep {
-        return step(
-            from = KeyguardState.LOCKSCREEN,
-            to = KeyguardState.ALTERNATE_BOUNCER,
-            value = value,
-            transitionState = state,
-        )
-    }
-
     private fun stepFromDozingToLockscreen(
         value: Float,
         state: TransitionState = TransitionState.RUNNING
@@ -229,18 +153,6 @@
         )
     }
 
-    private fun stepFromLockscreenToDozing(
-        value: Float,
-        state: TransitionState = TransitionState.RUNNING
-    ): TransitionStep {
-        return step(
-            from = KeyguardState.LOCKSCREEN,
-            to = KeyguardState.DOZING,
-            value = value,
-            transitionState = state,
-        )
-    }
-
     private fun step(
         from: KeyguardState,
         to: KeyguardState,
@@ -255,16 +167,4 @@
             ownerName = "AlternateBouncerViewModelTest"
         )
     }
-
-    /**
-     * Given the alternate bouncer parameters are set so that the alternate bouncer can show, aside
-     * from the fingerprint modality.
-     */
-    private fun givenCanShowAlternateBouncer() {
-        kosmos.fakeKeyguardBouncerRepository.setPrimaryShow(false)
-        kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
-        kosmos.fakeBiometricSettingsRepository.setIsFingerprintAuthCurrentlyAllowed(true)
-        whenever(kosmos.keyguardUpdateMonitor.isFingerprintLockedOut).thenReturn(false)
-        whenever(kosmos.keyguardStateController.isUnlocked).thenReturn(false)
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelTest.kt
deleted file mode 100644
index 716c40d..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelTest.kt
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.keyguard.ui.viewmodel
-
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
-import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
-import com.android.systemui.keyguard.shared.model.KeyguardState
-import com.android.systemui.keyguard.shared.model.TransitionState
-import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.keyguard.ui.StateToValue
-import com.android.systemui.kosmos.testScope
-import com.android.systemui.testKosmos
-import com.google.common.collect.Range
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.runCurrent
-import kotlinx.coroutines.test.runTest
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@ExperimentalCoroutinesApi
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class GoneToAodTransitionViewModelTest : SysuiTestCase() {
-    private val kosmos = testKosmos()
-    private val testScope = kosmos.testScope
-    private val repository = kosmos.fakeKeyguardTransitionRepository
-    private val underTest = kosmos.goneToAodTransitionViewModel
-    private val fingerprintPropertyRepository = kosmos.fingerprintPropertyRepository
-    private val biometricSettingsRepository = kosmos.biometricSettingsRepository
-
-    @Test
-    fun enterFromTopTranslationY() =
-        testScope.runTest {
-            val pixels = -100f
-            val enterFromTopTranslationY by
-                collectLastValue(underTest.enterFromTopTranslationY(pixels.toInt()))
-            runCurrent()
-
-            // The animation should only start > .4f way through
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            assertThat(enterFromTopTranslationY)
-                .isEqualTo(
-                    StateToValue(
-                        from = KeyguardState.GONE,
-                        to = KeyguardState.AOD,
-                        transitionState = TransitionState.STARTED,
-                        value = pixels
-                    )
-                )
-
-            repository.sendTransitionStep(step(.55f))
-            assertThat(enterFromTopTranslationY!!.value ?: -1f).isIn(Range.closed(pixels, 0f))
-
-            repository.sendTransitionStep(step(.85f))
-            assertThat(enterFromTopTranslationY!!.value ?: -1f).isIn(Range.closed(pixels, 0f))
-
-            // At the end, the translation should be complete and set to zero
-            repository.sendTransitionStep(step(1f))
-            assertThat(enterFromTopTranslationY)
-                .isEqualTo(
-                    StateToValue(
-                        from = KeyguardState.GONE,
-                        to = KeyguardState.AOD,
-                        transitionState = TransitionState.RUNNING,
-                        value = 0f
-                    )
-                )
-        }
-
-    @Test
-    fun enterFromTopAnimationAlpha() =
-        testScope.runTest {
-            val enterFromTopAnimationAlpha by collectLastValue(underTest.enterFromTopAnimationAlpha)
-            runCurrent()
-
-            // The animation should only start > .4f way through
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            assertThat(enterFromTopAnimationAlpha).isEqualTo(0f)
-
-            repository.sendTransitionStep(step(0.4f))
-            assertThat(enterFromTopAnimationAlpha).isEqualTo(0f)
-
-            repository.sendTransitionStep(step(.85f))
-            assertThat(enterFromTopAnimationAlpha).isIn(Range.closed(0f, 1f))
-
-            repository.sendTransitionStep(step(1f))
-            assertThat(enterFromTopAnimationAlpha).isEqualTo(1f)
-        }
-
-    @Test
-    fun deviceEntryBackgroundViewAlpha() =
-        testScope.runTest {
-            val deviceEntryBackgroundViewAlpha by
-                collectLastValue(underTest.deviceEntryBackgroundViewAlpha)
-            runCurrent()
-
-            // immediately 0f
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
-
-            repository.sendTransitionStep(step(0.4f))
-            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
-
-            repository.sendTransitionStep(step(.85f))
-            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
-
-            repository.sendTransitionStep(step(1f))
-            assertThat(deviceEntryBackgroundViewAlpha).isEqualTo(0f)
-        }
-
-    @Test
-    fun deviceEntryParentViewAlpha_udfpsEnrolled() =
-        testScope.runTest {
-            fingerprintPropertyRepository.supportsUdfps()
-            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
-            val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
-            runCurrent()
-
-            // animation doesn't start until the end
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            assertThat(deviceEntryParentViewAlpha).isEqualTo(0f)
-
-            repository.sendTransitionStep(step(0.5f))
-            assertThat(deviceEntryParentViewAlpha).isEqualTo(0f)
-
-            repository.sendTransitionStep(step(.95f))
-            assertThat(deviceEntryParentViewAlpha).isIn(Range.closed(.01f, 1f))
-
-            repository.sendTransitionStep(step(1f))
-            assertThat(deviceEntryParentViewAlpha).isIn(Range.closed(.99f, 1f))
-
-            repository.sendTransitionStep(step(1f, TransitionState.FINISHED))
-            assertThat(deviceEntryParentViewAlpha).isEqualTo(1f)
-        }
-
-    @Test
-    fun deviceEntryParentViewAlpha_rearFpEnrolled() =
-        testScope.runTest {
-            fingerprintPropertyRepository.supportsRearFps()
-            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
-            val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
-            runCurrent()
-
-            // animation doesn't start until the end
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            assertThat(deviceEntryParentViewAlpha).isNull()
-
-            repository.sendTransitionStep(step(0.5f))
-            assertThat(deviceEntryParentViewAlpha).isNull()
-
-            repository.sendTransitionStep(step(.95f))
-            assertThat(deviceEntryParentViewAlpha).isNull()
-
-            repository.sendTransitionStep(step(1f))
-            assertThat(deviceEntryParentViewAlpha).isNull()
-
-            repository.sendTransitionStep(step(1f, TransitionState.FINISHED))
-            assertThat(deviceEntryParentViewAlpha).isNull()
-        }
-
-    @Test
-    fun deviceEntryParentViewAlpha_udfpsNotEnrolled_noUpdates() =
-        testScope.runTest {
-            fingerprintPropertyRepository.supportsUdfps()
-            biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
-            val deviceEntryParentViewAlpha by collectLastValue(underTest.deviceEntryParentViewAlpha)
-            runCurrent()
-
-            // animation doesn't start until the end
-            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
-            assertThat(deviceEntryParentViewAlpha).isNull()
-
-            repository.sendTransitionStep(step(0.5f))
-            assertThat(deviceEntryParentViewAlpha).isNull()
-
-            repository.sendTransitionStep(step(.95f))
-            assertThat(deviceEntryParentViewAlpha).isNull()
-
-            repository.sendTransitionStep(step(1f))
-            assertThat(deviceEntryParentViewAlpha).isNull()
-
-            repository.sendTransitionStep(step(1f, TransitionState.FINISHED))
-            assertThat(deviceEntryParentViewAlpha).isNull()
-        }
-
-    private fun step(
-        value: Float,
-        state: TransitionState = TransitionState.RUNNING
-    ): TransitionStep {
-        return TransitionStep(
-            from = KeyguardState.GONE,
-            to = KeyguardState.AOD,
-            value = value,
-            transitionState = state,
-            ownerName = "GoneToAodTransitionViewModelTest"
-        )
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
index bdc5fc3..4f4aac4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardBottomAreaViewModelTest.kt
@@ -46,8 +46,8 @@
 import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
 import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
-import com.android.systemui.keyguard.domain.interactor.KeyguardLongPressInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTouchHandlingInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
 import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
@@ -58,6 +58,7 @@
 import com.android.systemui.settings.UserFileManager
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.pulsingGestureListener
 import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
 import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
 import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -178,7 +179,6 @@
                             .thenReturn(FakeSharedPreferences())
                     },
                 userTracker = userTracker,
-                systemSettings = FakeSettings(),
                 broadcastDispatcher = fakeBroadcastDispatcher,
             )
         val remoteUserSelectionManager =
@@ -211,8 +211,8 @@
                 dumpManager = mock(),
                 userHandle = UserHandle.SYSTEM,
             )
-        val keyguardLongPressInteractor =
-            KeyguardLongPressInteractor(
+        val keyguardTouchHandlingInteractor =
+            KeyguardTouchHandlingInteractor(
                 appContext = mContext,
                 scope = testScope.backgroundScope,
                 transitionInteractor = kosmos.keyguardTransitionInteractor,
@@ -221,6 +221,7 @@
                 featureFlags = featureFlags,
                 broadcastDispatcher = broadcastDispatcher,
                 accessibilityManager = accessibilityManager,
+                pulsingGestureListener = kosmos.pulsingGestureListener,
             )
         underTest =
             KeyguardBottomAreaViewModel(
@@ -246,13 +247,13 @@
                     ),
                 bottomAreaInteractor = KeyguardBottomAreaInteractor(repository = repository),
                 burnInHelperWrapper = burnInHelperWrapper,
-                longPressViewModel =
-                    KeyguardLongPressViewModel(
-                        interactor = keyguardLongPressInteractor,
+                keyguardTouchHandlingViewModel =
+                    KeyguardTouchHandlingViewModel(
+                        interactor = keyguardTouchHandlingInteractor,
                     ),
                 settingsMenuViewModel =
                     KeyguardSettingsMenuViewModel(
-                        interactor = keyguardLongPressInteractor,
+                        interactor = keyguardTouchHandlingInteractor,
                     ),
             )
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
index e33d75c..9fb1aa7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardQuickAffordancesCombinedViewModelTest.kt
@@ -221,7 +221,6 @@
                             .thenReturn(FakeSharedPreferences())
                     },
                 userTracker = userTracker,
-                systemSettings = FakeSettings(),
                 broadcastDispatcher = fakeBroadcastDispatcher,
             )
         val remoteUserSelectionManager =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/echo/LogcatEchoSettingsFormatTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/echo/LogcatEchoSettingsFormatTest.kt
index 02c9deb..aa4a6d1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/log/echo/LogcatEchoSettingsFormatTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/echo/LogcatEchoSettingsFormatTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.log.echo
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.core.LogLevel
@@ -24,8 +25,10 @@
 import com.android.systemui.log.echo.EchoOverrideType.TAG
 import kotlin.test.assertEquals
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class LogcatEchoSettingsFormatTest : SysuiTestCase() {
 
     private val format = LogcatEchoSettingFormat()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/echo/LogcatEchoTrackerDebugTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/echo/LogcatEchoTrackerDebugTest.kt
index 7967134..a5f50af 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/log/echo/LogcatEchoTrackerDebugTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/echo/LogcatEchoTrackerDebugTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.log.echo
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.core.LogLevel.DEBUG
@@ -39,11 +40,13 @@
 import org.junit.Assert.assertTrue
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class LogcatEchoTrackerDebugTest : SysuiTestCase() {
 
     private val dispatcher = StandardTestDispatcher()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt
index 1d182cf..e55cb12 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/LogDiffsForTableTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.log.table
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.table.TableChange.Companion.IS_INITIAL_PREFIX
@@ -35,9 +36,11 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
 @OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
 class LogDiffsForTableTest : SysuiTestCase() {
 
     private val testDispatcher = UnconfinedTestDispatcher()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableChangeTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableChangeTest.kt
index 43e430f..8d60811 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableChangeTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableChangeTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.log.table
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.table.TableChange.Companion.IS_INITIAL_PREFIX
@@ -23,8 +24,10 @@
 import com.google.common.truth.Truth.assertThat
 import junit.framework.Assert.assertTrue
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class TableChangeTest : SysuiTestCase() {
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferFactoryTest.kt
index 8ba7643..8c62bc2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferFactoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferFactoryTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.log.table
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
@@ -26,9 +27,11 @@
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class TableLogBufferFactoryTest : SysuiTestCase() {
     private val dumpManager: DumpManager = mock()
     private val systemClock = FakeSystemClock()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferTest.kt b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferTest.kt
index 5c9a003..ace562b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/log/table/TableLogBufferTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.log.table
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.LogcatEchoTracker
@@ -35,9 +36,11 @@
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class TableLogBufferTest : SysuiTestCase() {
     private lateinit var underTest: TableLogBuffer
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataCombineLatestTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataCombineLatestTest.java
index 544350c..1d4b090 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataCombineLatestTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataCombineLatestTest.java
@@ -79,7 +79,7 @@
                 USER_ID, true, APP, null, ARTIST, TITLE, null,
                 new ArrayList<>(), new ArrayList<>(), null, PACKAGE, null, null, null, true, null,
                 MediaData.PLAYBACK_LOCAL, false, KEY, false, false, false, 0L, 0L,
-                InstanceId.fakeInstanceId(-1), -1, false, null);
+                InstanceId.fakeInstanceId(-1), -1, false, null, -1, false);
         mDeviceData = new MediaDeviceData(true, null, DEVICE_NAME, null, false);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
index 4da56b5..3705909 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
@@ -16,8 +16,11 @@
 
 package com.android.systemui.media.controls.domain.pipeline
 
+import android.R
 import android.app.smartspace.SmartspaceAction
+import android.graphics.drawable.Icon
 import android.os.Bundle
+import android.os.Process
 import android.testing.TestableLooper
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
@@ -28,6 +31,7 @@
 import com.android.systemui.media.controls.MediaTestUtils
 import com.android.systemui.media.controls.data.repository.MediaFilterRepository
 import com.android.systemui.media.controls.data.repository.mediaFilterRepository
+import com.android.systemui.media.controls.shared.mockMediaLogger
 import com.android.systemui.media.controls.shared.model.EXTRA_KEY_TRIGGER_RESUME
 import com.android.systemui.media.controls.shared.model.MediaCommonModel
 import com.android.systemui.media.controls.shared.model.MediaData
@@ -36,7 +40,11 @@
 import com.android.systemui.media.controls.shared.model.SmartspaceMediaLoadingModel
 import com.android.systemui.media.controls.ui.controller.MediaPlayerData
 import com.android.systemui.media.controls.util.MediaFlags
+import com.android.systemui.media.controls.util.MediaSmartspaceLogger
 import com.android.systemui.media.controls.util.MediaUiEventLogger
+import com.android.systemui.media.controls.util.SmallHash
+import com.android.systemui.media.controls.util.mediaSmartspaceLogger
+import com.android.systemui.media.controls.util.mockMediaSmartspaceLogger
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.statusbar.NotificationLockscreenUserManager
 import com.android.systemui.testKosmos
@@ -101,8 +109,13 @@
     private lateinit var dataGuest: MediaData
     private lateinit var dataPrivateProfile: MediaData
     private val clock = FakeSystemClock()
-    private val repository: MediaFilterRepository = kosmos.mediaFilterRepository
-    private val mediaLoadingLogger = kosmos.mockMediaLoadingLogger
+    private val smartspaceLogger = kosmos.mockMediaSmartspaceLogger
+    private val repository: MediaFilterRepository =
+        with(kosmos) {
+            mediaSmartspaceLogger = mockMediaSmartspaceLogger
+            mediaFilterRepository
+        }
+    private val mediaLogger = kosmos.mockMediaLogger
 
     @Before
     fun setup() {
@@ -121,7 +134,7 @@
                 logger,
                 mediaFlags,
                 repository,
-                mediaLoadingLogger,
+                mediaLogger,
             )
         mediaDataFilter.mediaDataProcessor = mediaDataProcessor
         mediaDataFilter.addListener(listener)
@@ -146,6 +159,8 @@
         whenever(smartspaceData.packageName).thenReturn(SMARTSPACE_PACKAGE)
         whenever(smartspaceData.recommendations)
             .thenReturn(listOf(smartspaceMediaRecommendationItem))
+        whenever(smartspaceMediaRecommendationItem.icon)
+            .thenReturn(Icon.createWithResource(context, R.drawable.ic_media_play))
         whenever(smartspaceData.headphoneConnectionTimeMillis)
             .thenReturn(clock.currentTimeMillis() - 100)
         whenever(smartspaceData.instanceId).thenReturn(SMARTSPACE_INSTANCE_ID)
@@ -180,7 +195,7 @@
 
             verify(listener)
                 .onMediaDataLoaded(eq(KEY), eq(null), eq(dataMain), eq(true), eq(0), eq(false))
-            verify(mediaLoadingLogger)
+            verify(mediaLogger)
                 .logMediaLoaded(eq(dataMain.instanceId), eq(dataMain.active), anyString())
             assertThat(currentMedia).containsExactly(mediaCommonModel)
         }
@@ -196,7 +211,7 @@
 
             verify(listener, never())
                 .onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyInt(), anyBoolean())
-            verify(mediaLoadingLogger, never()).logMediaLoaded(any(), anyBoolean(), anyString())
+            verify(mediaLogger, never()).logMediaLoaded(any(), anyBoolean(), anyString())
             assertThat(currentMedia).doesNotContain(mediaCommonModel)
         }
 
@@ -210,14 +225,14 @@
             // GIVEN a media was removed for main user
             mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain)
 
-            verify(mediaLoadingLogger)
+            verify(mediaLogger)
                 .logMediaLoaded(eq(dataMain.instanceId), eq(dataMain.active), anyString())
             assertThat(currentMedia).containsExactly(mediaCommonModel)
 
             mediaDataFilter.onMediaDataRemoved(KEY, false)
 
             verify(listener).onMediaDataRemoved(eq(KEY), eq(false))
-            verify(mediaLoadingLogger).logMediaRemoved(eq(dataMain.instanceId), anyString())
+            verify(mediaLogger).logMediaRemoved(eq(dataMain.instanceId), anyString())
             assertThat(currentMedia).doesNotContain(mediaCommonModel)
         }
 
@@ -231,8 +246,7 @@
             mediaDataFilter.onMediaDataRemoved(KEY, false)
 
             verify(listener, never()).onMediaDataRemoved(eq(KEY), eq(false))
-            verify(mediaLoadingLogger, never())
-                .logMediaRemoved(eq(dataGuest.instanceId), anyString())
+            verify(mediaLogger, never()).logMediaRemoved(eq(dataGuest.instanceId), anyString())
             assertThat(currentMedia).isEmpty()
         }
 
@@ -245,7 +259,7 @@
             // GIVEN that we have a media loaded for main user
             mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain)
 
-            verify(mediaLoadingLogger)
+            verify(mediaLogger)
                 .logMediaLoaded(eq(dataMain.instanceId), eq(dataMain.active), anyString())
             assertThat(currentMedia).containsExactly(MediaCommonModel.MediaControl(mediaLoaded))
 
@@ -254,7 +268,7 @@
 
             // THEN we should remove the main user's media
             verify(listener).onMediaDataRemoved(eq(KEY), eq(false))
-            verify(mediaLoadingLogger).logMediaRemoved(eq(dataMain.instanceId), anyString())
+            verify(mediaLogger).logMediaRemoved(eq(dataMain.instanceId), anyString())
             assertThat(currentMedia).isEmpty()
         }
 
@@ -275,10 +289,10 @@
             // THEN we should add back the guest user media
             verify(listener)
                 .onMediaDataLoaded(eq(KEY_ALT), eq(null), eq(dataGuest), eq(true), eq(0), eq(false))
-            verify(mediaLoadingLogger)
+            verify(mediaLogger)
                 .logMediaLoaded(eq(dataGuest.instanceId), eq(dataGuest.active), anyString())
 
-            reset(mediaLoadingLogger)
+            reset(mediaLogger)
 
             // but not the main user's
             verify(listener, never())
@@ -290,7 +304,7 @@
                     anyInt(),
                     anyBoolean()
                 )
-            verify(mediaLoadingLogger, never())
+            verify(mediaLogger, never())
                 .logMediaLoaded(eq(dataMain.instanceId), anyBoolean(), anyString())
             assertThat(currentMedia)
                 .containsExactly(MediaCommonModel.MediaControl(guestLoadedStatesModel))
@@ -313,7 +327,7 @@
             val mediaLoadedStatesModel = MediaDataLoadingModel.Loaded(dataMain.instanceId)
             // THEN we should remove the private profile media
             verify(listener).onMediaDataRemoved(eq(KEY_ALT), eq(false))
-            verify(mediaLoadingLogger).logMediaRemoved(eq(dataGuest.instanceId), anyString())
+            verify(mediaLogger).logMediaRemoved(eq(dataGuest.instanceId), anyString())
             assertThat(currentMedia)
                 .containsExactly(MediaCommonModel.MediaControl(mediaLoadedStatesModel))
         }
@@ -533,8 +547,22 @@
     @Test
     fun onSwipeToDismiss_setsTimedOut() {
         mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain)
-        mediaDataFilter.onSwipeToDismiss()
+        mediaDataFilter.onSwipeToDismiss(1)
 
+        verify(smartspaceLogger, never())
+            .logSmartspaceCardUIEvent(
+                eq(MediaSmartspaceLogger.SMARTSPACE_CARD_DISMISS_EVENT),
+                anyInt(),
+                anyInt(),
+                anyInt(),
+                anyInt(),
+                anyBoolean(),
+                anyBoolean(),
+                anyInt(),
+                anyInt(),
+                anyInt(),
+                eq(true)
+            )
         verify(mediaDataProcessor).setInactive(eq(KEY), eq(true), eq(true))
     }
 
@@ -563,8 +591,7 @@
             assertThat(hasActiveMedia(selectedUserEntries)).isFalse()
             verify(listener)
                 .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(true))
-            verify(mediaLoadingLogger)
-                .logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
+            verify(mediaLogger).logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
             verify(logger).logRecommendationAdded(SMARTSPACE_PACKAGE, SMARTSPACE_INSTANCE_ID)
             verify(logger, never()).logRecommendationActivated(any(), any(), any())
         }
@@ -594,9 +621,8 @@
             verify(listener, never())
                 .onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyInt(), anyBoolean())
             verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
-            verify(mediaLoadingLogger, never()).logMediaLoaded(any(), anyBoolean(), anyString())
-            verify(mediaLoadingLogger, never())
-                .logRecommendationLoaded(any(), anyBoolean(), anyString())
+            verify(mediaLogger, never()).logMediaLoaded(any(), anyBoolean(), anyString())
+            verify(mediaLogger, never()).logRecommendationLoaded(any(), anyBoolean(), anyString())
             verify(logger, never()).logRecommendationAdded(any(), any())
             verify(logger, never()).logRecommendationActivated(any(), any(), any())
         }
@@ -634,8 +660,7 @@
             assertThat(hasActiveMedia(selectedUserEntries)).isFalse()
             verify(listener)
                 .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(true))
-            verify(mediaLoadingLogger)
-                .logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
+            verify(mediaLogger).logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
             verify(logger).logRecommendationAdded(SMARTSPACE_PACKAGE, SMARTSPACE_INSTANCE_ID)
             verify(logger, never()).logRecommendationActivated(any(), any(), any())
         }
@@ -670,8 +695,7 @@
                 .isFalse()
             assertThat(hasActiveMedia(selectedUserEntries)).isFalse()
             verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
-            verify(mediaLoadingLogger, never())
-                .logRecommendationLoaded(any(), anyBoolean(), anyString())
+            verify(mediaLogger, never()).logRecommendationLoaded(any(), anyBoolean(), anyString())
             verify(logger, never()).logRecommendationAdded(any(), any())
             verify(logger, never()).logRecommendationActivated(any(), any(), any())
         }
@@ -699,10 +723,10 @@
             assertThat(currentMedia).containsExactly(controlCommonModel)
             verify(listener)
                 .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
-            verify(mediaLoadingLogger)
+            verify(mediaLogger)
                 .logMediaLoaded(eq(dataCurrent.instanceId), eq(dataCurrent.active), anyString())
 
-            reset(mediaLoadingLogger)
+            reset(mediaLogger)
 
             // AND we get a smartspace signal
             mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
@@ -721,10 +745,9 @@
             verify(listener, never())
                 .onMediaDataLoaded(eq(KEY), eq(KEY), any(), anyBoolean(), anyInt(), anyBoolean())
             verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
-            verify(mediaLoadingLogger, never())
+            verify(mediaLogger, never())
                 .logMediaLoaded(eq(dataCurrent.instanceId), anyBoolean(), anyString())
-            verify(mediaLoadingLogger, never())
-                .logRecommendationLoaded(any(), anyBoolean(), anyString())
+            verify(mediaLogger, never()).logRecommendationLoaded(any(), anyBoolean(), anyString())
             verify(logger, never()).logRecommendationAdded(any(), any())
             verify(logger, never()).logRecommendationActivated(any(), any(), any())
         }
@@ -740,17 +763,14 @@
 
             // WHEN we have media that was recently played, but not currently active
             val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
-            val controlCommonModel =
-                MediaCommonModel.MediaControl(
-                    MediaDataLoadingModel.Loaded(dataMain.instanceId),
-                    true
-                )
+            val mediaLoadingModel = MediaDataLoadingModel.Loaded(dataMain.instanceId)
+            var controlCommonModel = MediaCommonModel.MediaControl(mediaLoadingModel, true)
             mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
             repository.setOrderedMedia()
             assertThat(currentMedia).containsExactly(controlCommonModel)
             verify(listener)
                 .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
-            verify(mediaLoadingLogger)
+            verify(mediaLogger)
                 .logMediaLoaded(eq(dataCurrent.instanceId), eq(dataCurrent.active), anyString())
 
             // AND we get a smartspace signal
@@ -758,7 +778,15 @@
             mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
 
             // THEN we should treat the media as active instead
-            val dataCurrentAndActive = dataCurrent.copy(active = true)
+            val dataCurrentAndActive =
+                dataMain.copy(active = true, lastActive = clock.elapsedRealtime())
+            controlCommonModel =
+                controlCommonModel.copy(
+                    mediaLoadingModel.copy(
+                        receivedSmartspaceCardLatency = 100,
+                        isSsReactivated = true
+                    )
+                )
             assertThat(currentMedia).containsExactly(controlCommonModel)
             assertThat(
                     hasActiveMediaOrRecommendation(
@@ -777,7 +805,7 @@
                     eq(100),
                     eq(true)
                 )
-            verify(mediaLoadingLogger)
+            verify(mediaLogger)
                 .logMediaLoaded(
                     eq(dataCurrentAndActive.instanceId),
                     eq(dataCurrentAndActive.active),
@@ -785,8 +813,7 @@
                 )
             // Smartspace update shouldn't be propagated for the empty rec list.
             verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
-            verify(mediaLoadingLogger, never())
-                .logRecommendationLoaded(any(), anyBoolean(), anyString())
+            verify(mediaLogger, never()).logRecommendationLoaded(any(), anyBoolean(), anyString())
             verify(logger, never()).logRecommendationAdded(any(), any())
             verify(logger).logRecommendationActivated(eq(APP_UID), eq(PACKAGE), eq(INSTANCE_ID))
         }
@@ -800,11 +827,8 @@
             val currentMedia by collectLastValue(repository.currentMedia)
             // WHEN we have media that was recently played, but not currently active
             val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
-            val controlCommonModel =
-                MediaCommonModel.MediaControl(
-                    MediaDataLoadingModel.Loaded(dataMain.instanceId),
-                    true
-                )
+            val mediaLoadingModel = MediaDataLoadingModel.Loaded(dataMain.instanceId)
+            var controlCommonModel = MediaCommonModel.MediaControl(mediaLoadingModel, true)
             val recsCommonModel =
                 MediaCommonModel.MediaRecommendations(
                     SmartspaceMediaLoadingModel.Loaded(SMARTSPACE_KEY)
@@ -816,7 +840,7 @@
             assertThat(currentMedia).containsExactly(controlCommonModel)
             verify(listener)
                 .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
-            verify(mediaLoadingLogger)
+            verify(mediaLogger)
                 .logMediaLoaded(eq(dataCurrent.instanceId), eq(dataCurrent.active), anyString())
 
             // AND we get a smartspace signal
@@ -824,7 +848,8 @@
             mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
 
             // THEN we should treat the media as active instead
-            val dataCurrentAndActive = dataCurrent.copy(active = true)
+            val dataCurrentAndActive =
+                dataMain.copy(active = true, lastActive = clock.elapsedRealtime())
             verify(listener)
                 .onMediaDataLoaded(
                     eq(KEY),
@@ -834,7 +859,7 @@
                     eq(100),
                     eq(true)
                 )
-            verify(mediaLoadingLogger)
+            verify(mediaLogger)
                 .logMediaLoaded(
                     eq(dataCurrentAndActive.instanceId),
                     eq(dataCurrentAndActive.active),
@@ -849,11 +874,17 @@
                 )
                 .isTrue()
             // Smartspace update should also be propagated but not prioritized.
+            controlCommonModel =
+                controlCommonModel.copy(
+                    mediaLoadingModel.copy(
+                        receivedSmartspaceCardLatency = 100,
+                        isSsReactivated = true
+                    )
+                )
             assertThat(currentMedia).containsExactly(controlCommonModel, recsCommonModel)
             verify(listener)
                 .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
-            verify(mediaLoadingLogger)
-                .logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
+            verify(mediaLogger).logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
             verify(logger).logRecommendationAdded(SMARTSPACE_PACKAGE, SMARTSPACE_INSTANCE_ID)
             verify(logger).logRecommendationActivated(eq(APP_UID), eq(PACKAGE), eq(INSTANCE_ID))
         }
@@ -870,8 +901,7 @@
             mediaDataFilter.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
 
             verify(listener).onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
-            verify(mediaLoadingLogger)
-                .logRecommendationRemoved(eq(SMARTSPACE_KEY), eq(true), anyString())
+            verify(mediaLogger).logRecommendationRemoved(eq(SMARTSPACE_KEY), eq(true), anyString())
             assertThat(currentMedia).isEmpty()
             assertThat(
                     hasActiveMediaOrRecommendation(
@@ -903,13 +933,14 @@
             assertThat(currentMedia).containsExactly(controlCommonModel)
             verify(listener)
                 .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
-            verify(mediaLoadingLogger)
+            verify(mediaLogger)
                 .logMediaLoaded(eq(dataCurrent.instanceId), eq(dataCurrent.active), anyString())
 
             runCurrent()
             mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
 
-            val dataCurrentAndActive = dataCurrent.copy(active = true)
+            val dataCurrentAndActive =
+                dataMain.copy(active = true, lastActive = clock.elapsedRealtime())
             verify(listener)
                 .onMediaDataLoaded(
                     eq(KEY),
@@ -919,7 +950,7 @@
                     eq(100),
                     eq(true)
                 )
-            verify(mediaLoadingLogger)
+            verify(mediaLogger)
                 .logMediaLoaded(
                     eq(dataCurrentAndActive.instanceId),
                     eq(dataCurrentAndActive.active),
@@ -929,8 +960,7 @@
             mediaDataFilter.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
 
             verify(listener).onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
-            verify(mediaLoadingLogger)
-                .logRecommendationRemoved(eq(SMARTSPACE_KEY), eq(true), anyString())
+            verify(mediaLogger).logRecommendationRemoved(eq(SMARTSPACE_KEY), eq(true), anyString())
             assertThat(currentMedia).containsExactly(controlCommonModel)
             assertThat(
                     hasActiveMediaOrRecommendation(
@@ -961,8 +991,7 @@
 
             verify(listener)
                 .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
-            verify(mediaLoadingLogger)
-                .logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(false), anyString())
+            verify(mediaLogger).logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(false), anyString())
             assertThat(currentMedia).containsExactly(recsCommonModel)
             assertThat(
                     hasActiveMediaOrRecommendation(
@@ -1003,11 +1032,11 @@
 
             verify(listener)
                 .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
-            verify(mediaLoadingLogger)
+            verify(mediaLogger)
                 .logMediaLoaded(eq(dataCurrent.instanceId), eq(dataCurrent.active), anyString())
             assertThat(currentMedia).containsExactly(controlCommonModel)
 
-            reset(mediaLoadingLogger)
+            reset(mediaLogger)
 
             // And an inactive recommendation is loaded
             mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
@@ -1015,11 +1044,10 @@
             // Smartspace is loaded but the media stays inactive
             verify(listener)
                 .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
-            verify(mediaLoadingLogger)
-                .logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(false), anyString())
+            verify(mediaLogger).logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(false), anyString())
             verify(listener, never())
                 .onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyInt(), anyBoolean())
-            verify(mediaLoadingLogger, never()).logMediaLoaded(any(), anyBoolean(), anyString())
+            verify(mediaLogger, never()).logMediaLoaded(any(), anyBoolean(), anyString())
             assertThat(currentMedia).containsExactly(controlCommonModel, recsCommonModel)
             assertThat(
                     hasActiveMediaOrRecommendation(
@@ -1042,11 +1070,27 @@
                 targetId = SMARTSPACE_KEY,
                 isActive = true,
                 packageName = SMARTSPACE_PACKAGE,
-                recommendations = listOf(smartspaceMediaRecommendationItem),
+                recommendations =
+                    listOf(
+                        smartspaceMediaRecommendationItem,
+                        smartspaceMediaRecommendationItem,
+                        smartspaceMediaRecommendationItem
+                    ),
             )
         mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, data)
-        mediaDataFilter.onSwipeToDismiss()
 
+        mediaDataFilter.onSwipeToDismiss(1)
+
+        verify(smartspaceLogger)
+            .logSmartspaceCardUIEvent(
+                MediaSmartspaceLogger.SMARTSPACE_CARD_DISMISS_EVENT,
+                SmallHash.hash(data.targetId),
+                Process.INVALID_UID,
+                surface = 1,
+                cardinality = 1,
+                isRecommendationCard = true,
+                isSwipeToDismiss = true
+            )
         verify(mediaDataProcessor).setRecommendationInactive(eq(SMARTSPACE_KEY))
         verify(mediaDataProcessor, never())
             .dismissSmartspaceRecommendation(eq(SMARTSPACE_KEY), anyLong())
@@ -1063,11 +1107,8 @@
                 MediaCommonModel.MediaRecommendations(
                     SmartspaceMediaLoadingModel.Loaded(SMARTSPACE_KEY)
                 )
-            val controlCommonModel =
-                MediaCommonModel.MediaControl(
-                    MediaDataLoadingModel.Loaded(dataMain.instanceId),
-                    true
-                )
+            val mediaLoadingModel = MediaDataLoadingModel.Loaded(dataMain.instanceId)
+            var controlCommonModel = MediaCommonModel.MediaControl(mediaLoadingModel, true)
             // WHEN we have media that was recently played, but not currently active
             val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
             mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
@@ -1075,7 +1116,7 @@
 
             verify(listener)
                 .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
-            verify(mediaLoadingLogger)
+            verify(mediaLogger)
                 .logMediaLoaded(eq(dataCurrent.instanceId), eq(dataCurrent.active), anyString())
             assertThat(currentMedia).containsExactly(controlCommonModel)
 
@@ -1086,7 +1127,15 @@
             mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
 
             // THEN we should treat the media as active instead
-            val dataCurrentAndActive = dataCurrent.copy(active = true)
+            val dataCurrentAndActive =
+                dataMain.copy(active = true, lastActive = clock.elapsedRealtime())
+            controlCommonModel =
+                controlCommonModel.copy(
+                    mediaLoadingModel.copy(
+                        receivedSmartspaceCardLatency = 100,
+                        isSsReactivated = true
+                    )
+                )
             verify(listener)
                 .onMediaDataLoaded(
                     eq(KEY),
@@ -1096,7 +1145,7 @@
                     eq(100),
                     eq(true)
                 )
-            verify(mediaLoadingLogger)
+            verify(mediaLogger)
                 .logMediaLoaded(
                     eq(dataCurrentAndActive.instanceId),
                     eq(dataCurrentAndActive.active),
@@ -1114,8 +1163,7 @@
             // And update the smartspace data state, but not prioritized
             verify(listener)
                 .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
-            verify(mediaLoadingLogger)
-                .logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
+            verify(mediaLogger).logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
         }
 
     @Test
@@ -1139,11 +1187,11 @@
 
             verify(listener)
                 .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
-            verify(mediaLoadingLogger)
+            verify(mediaLogger)
                 .logMediaLoaded(eq(dataCurrent.instanceId), eq(dataCurrent.active), anyString())
             assertThat(currentMedia).containsExactly(controlCommonModel)
 
-            reset(mediaLoadingLogger)
+            reset(mediaLogger)
 
             // AND we get a smartspace signal with extra to not trigger resume
             val extras = Bundle().apply { putBoolean(EXTRA_KEY_TRIGGER_RESUME, false) }
@@ -1153,13 +1201,12 @@
             // THEN listeners are not updated to show media
             verify(listener, never())
                 .onMediaDataLoaded(eq(KEY), eq(KEY), any(), eq(true), eq(100), eq(true))
-            verify(mediaLoadingLogger, never())
+            verify(mediaLogger, never())
                 .logMediaLoaded(eq(dataCurrent.instanceId), anyBoolean(), anyString())
             // But the smartspace update is still propagated
             verify(listener)
                 .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
-            verify(mediaLoadingLogger)
-                .logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
+            verify(mediaLogger).logRecommendationLoaded(eq(SMARTSPACE_KEY), eq(true), anyString())
             assertThat(currentMedia).containsExactly(controlCommonModel, recsCommonModel)
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/shared/SmartspaceMediaDataTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/shared/SmartspaceMediaDataTest.kt
index 473dc47..868145d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/shared/SmartspaceMediaDataTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/shared/SmartspaceMediaDataTest.kt
@@ -18,6 +18,7 @@
 
 import android.app.smartspace.SmartspaceAction
 import android.graphics.drawable.Icon
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
 import com.android.systemui.SysuiTestCase
@@ -26,8 +27,10 @@
 import com.android.systemui.res.R
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class SmartspaceMediaDataTest : SysuiTestCase() {
 
     private val icon: Icon = Icon.createWithResource(context, R.drawable.ic_media_play)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
index ccf926a..f8358c5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaCarouselControllerTest.kt
@@ -40,6 +40,7 @@
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.media.controls.MediaTestUtils
@@ -158,6 +159,7 @@
         testDispatcher = UnconfinedTestDispatcher()
         mediaCarouselController =
             MediaCarouselController(
+                applicationScope = kosmos.applicationCoroutineScope,
                 context = context,
                 mediaControlPanelFactory = mediaControlPanelFactory,
                 visualStabilityProvider = visualStabilityProvider,
@@ -195,10 +197,10 @@
         MediaPlayerData.clear()
         FakeExecutor.exhaustExecutors(bgExecutor)
         verify(globalSettings)
-                .registerContentObserverSync(
-                        eq(Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE)),
-                        capture(settingsObserverCaptor)
-                )
+            .registerContentObserverSync(
+                eq(Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE)),
+                capture(settingsObserverCaptor)
+            )
     }
 
     @After
@@ -894,7 +896,10 @@
             mediaCarouselController.updateHostVisibility = { updatedVisibility = true }
             mediaCarouselController.mediaCarousel = mediaCarousel
 
-            val settingsJob = mediaCarouselController.listenForLockscreenSettingChanges(this)
+            val settingsJob =
+                mediaCarouselController.listenForLockscreenSettingChanges(
+                    kosmos.applicationCoroutineScope
+                )
             secureSettings.putBool(Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN, false)
 
             val keyguardJob = mediaCarouselController.listenForAnyStateToLockscreenTransition(this)
@@ -921,7 +926,10 @@
             mediaCarouselController.updateHostVisibility = { updatedVisibility = true }
             mediaCarouselController.mediaCarousel = mediaCarousel
 
-            val settingsJob = mediaCarouselController.listenForLockscreenSettingChanges(this)
+            val settingsJob =
+                mediaCarouselController.listenForLockscreenSettingChanges(
+                    kosmos.applicationCoroutineScope
+                )
             secureSettings.putBool(Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN, true)
 
             val keyguardJob = mediaCarouselController.listenForAnyStateToLockscreenTransition(this)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaControlPanelTest.kt
index ecc456c..fbfe41f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaControlPanelTest.kt
@@ -40,6 +40,7 @@
 import android.media.session.MediaSession
 import android.media.session.PlaybackState
 import android.os.Bundle
+import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
 import android.platform.test.annotations.RequiresFlagsEnabled
 import android.platform.test.flag.junit.DeviceFlagsValueProvider
@@ -1771,8 +1772,41 @@
         verify(logger).logSeek(anyInt(), eq(PACKAGE), eq(instanceId))
     }
 
+    @EnableFlags(Flags.FLAG_MEDIA_LOCKSCREEN_LAUNCH_ANIMATION)
     @Test
-    fun tapContentView_showOverLockscreen_openActivity() {
+    fun tapContentView_showOverLockscreen_openActivity_withOriginAnimation() {
+        // WHEN we are on lockscreen and this activity can show over lockscreen
+        whenever(keyguardStateController.isShowing).thenReturn(true)
+        whenever(activityIntentHelper.wouldPendingShowOverLockscreen(any(), any())).thenReturn(true)
+
+        val clickIntent = mock(Intent::class.java)
+        val pendingIntent = mock(PendingIntent::class.java)
+        whenever(pendingIntent.intent).thenReturn(clickIntent)
+        val captor = ArgumentCaptor.forClass(View.OnClickListener::class.java)
+        val data = mediaData.copy(clickIntent = pendingIntent)
+        player.attachPlayer(viewHolder)
+        player.bindPlayer(data, KEY)
+        verify(viewHolder.player).setOnClickListener(captor.capture())
+
+        // THEN it sends the PendingIntent without dismissing keyguard first,
+        // and does not use the Intent directly (see b/271845008)
+        captor.value.onClick(viewHolder.player)
+        verify(activityStarter)
+            .startPendingIntentMaybeDismissingKeyguard(
+                eq(pendingIntent),
+                eq(true),
+                eq(null),
+                any(),
+                eq(null),
+                eq(null),
+                eq(null),
+            )
+        verify(activityStarter, never()).postStartActivityDismissingKeyguard(eq(clickIntent), any())
+    }
+
+    @DisableFlags(Flags.FLAG_MEDIA_LOCKSCREEN_LAUNCH_ANIMATION)
+    @Test
+    fun tapContentView_showOverLockscreen_openActivity_withoutOriginAnimation() {
         // WHEN we are on lockscreen and this activity can show over lockscreen
         whenever(keyguardStateController.isShowing).thenReturn(true)
         whenever(activityIntentHelper.wouldPendingShowOverLockscreen(any(), any())).thenReturn(true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt
index 2a8967e..64acc59 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt
@@ -24,6 +24,7 @@
 import android.media.AudioDeviceInfo
 import android.media.AudioManager
 import android.media.AudioManager.MuteAwaitConnectionCallback.EVENT_CONNECTION
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.settingslib.media.DeviceIconUtil
 import com.android.settingslib.media.LocalMediaManager
@@ -35,6 +36,7 @@
 import com.android.systemui.util.time.FakeSystemClock
 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.never
@@ -45,6 +47,7 @@
 
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class MediaMuteAwaitConnectionManagerTest : SysuiTestCase() {
     private lateinit var muteAwaitConnectionManager: MediaMuteAwaitConnectionManager
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/nearby/NearbyMediaDevicesManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/nearby/NearbyMediaDevicesManagerTest.kt
index d9453d6..b9aa029 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/nearby/NearbyMediaDevicesManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/nearby/NearbyMediaDevicesManagerTest.kt
@@ -2,6 +2,7 @@
 
 import android.media.INearbyMediaDevicesProvider
 import android.media.INearbyMediaDevicesUpdateCallback
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import android.media.NearbyDevice
@@ -10,6 +11,7 @@
 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.anyInt
@@ -20,6 +22,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class NearbyMediaDevicesManagerTest : SysuiTestCase() {
 
     private lateinit var manager: NearbyMediaDevicesManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt
index d828193..77807bf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt
@@ -19,6 +19,7 @@
 import android.app.StatusBarManager
 import android.content.Context
 import android.media.MediaRoute2Info
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.media.taptotransfer.receiver.ChipStateReceiver
@@ -35,6 +36,7 @@
 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.verify
 import org.mockito.MockitoAnnotations
@@ -43,6 +45,7 @@
 import java.util.concurrent.Executor
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class MediaTttCommandLineHelperTest : SysuiTestCase() {
 
     private val inlineExecutor = Executor { command -> command.run() }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttLoggerUtilsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttLoggerUtilsTest.kt
index b322bb7..ab5c893 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttLoggerUtilsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttLoggerUtilsTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.media.taptotransfer.common
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
@@ -27,9 +28,11 @@
 import java.io.StringWriter
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mockito.mock
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class MediaTttLoggerUtilsTest : SysuiTestCase() {
 
     private lateinit var buffer: LogBuffer
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt
index 5c6d913..02123ba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt
@@ -19,6 +19,7 @@
 import android.content.pm.ApplicationInfo
 import android.content.pm.PackageManager
 import android.graphics.drawable.Drawable
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
@@ -30,12 +31,14 @@
 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
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class MediaTttUtilsTest : SysuiTestCase() {
 
     private lateinit var appIconFromPackageName: Drawable
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverLoggerTest.kt
index 64f3fd3..cee71b5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverLoggerTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.media.taptotransfer.receiver
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
@@ -27,9 +28,11 @@
 import java.io.StringWriter
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mockito.mock
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class MediaTttReceiverLoggerTest : SysuiTestCase() {
 
     private lateinit var buffer: LogBuffer
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt
index f557713..352443a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverUiEventLoggerTest.kt
@@ -1,5 +1,6 @@
 package com.android.systemui.media.taptotransfer.receiver
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
 import com.android.internal.logging.testing.UiEventLoggerFake
@@ -7,8 +8,10 @@
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class MediaTttReceiverUiEventLoggerTest : SysuiTestCase() {
     private lateinit var uiEventLoggerFake: UiEventLoggerFake
     private lateinit var logger: MediaTttReceiverUiEventLogger
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLoggerTest.kt
index ee3704c..af8b3ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLoggerTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.media.taptotransfer.sender
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
 import com.android.systemui.SysuiTestCase
@@ -28,9 +29,11 @@
 import java.io.StringWriter
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mockito.mock
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class MediaTttSenderLoggerTest : SysuiTestCase() {
 
     private lateinit var buffer: LogBuffer
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt
index bf26a2f..30b578a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt
@@ -1,5 +1,6 @@
 package com.android.systemui.media.taptotransfer.sender
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
 import com.android.internal.logging.testing.UiEventLoggerFake
@@ -7,8 +8,10 @@
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class MediaTttSenderUiEventLoggerTest : SysuiTestCase() {
     private lateinit var uiEventLoggerFake: UiEventLoggerFake
     private lateinit var logger: MediaTttSenderUiEventLogger
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewControllerTest.kt
index f4c5ccf..b337ccf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewControllerTest.kt
@@ -22,6 +22,7 @@
 import android.os.Bundle
 import android.view.View
 import android.view.ViewGroup
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.Flags.FLAG_PSS_APP_SELECTOR_ABRUPT_EXIT_FIX
 import com.android.systemui.Flags.FLAG_PSS_APP_SELECTOR_RECENTS_SPLIT_SCREEN
@@ -36,6 +37,7 @@
 import java.util.Optional
 import org.junit.Rule
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
 import org.mockito.ArgumentMatchers.eq
 import org.mockito.Mockito.any
@@ -43,6 +45,7 @@
 import org.mockito.Mockito.verify
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class MediaProjectionRecentsViewControllerTest : SysuiTestCase() {
 
     @get:Rule val expect: Expect = Expect.create()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProviderTest.kt
index 9630ee3..55e52b7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/TaskPreviewSizeProviderTest.kt
@@ -27,6 +27,7 @@
 import android.view.WindowMetrics
 import androidx.core.view.WindowInsetsCompat.Type
 import androidx.lifecycle.LifecycleOwner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.mediaprojection.appselector.view.TaskPreviewSizeProvider.TaskPreviewSizeListener
@@ -38,8 +39,10 @@
 import kotlin.math.min
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class TaskPreviewSizeProviderTest : SysuiTestCase() {
 
     private val lifecycleOwner = mock<LifecycleOwner>()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/WindowMetricsProviderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/WindowMetricsProviderImplTest.kt
index fe18454..cc722aa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/WindowMetricsProviderImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/WindowMetricsProviderImplTest.kt
@@ -5,14 +5,17 @@
 import android.view.WindowManager
 import android.view.WindowMetrics
 import androidx.core.view.WindowInsetsCompat
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class WindowMetricsProviderImplTest : SysuiTestCase() {
 
     private val windowManager = mock<WindowManager>()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegateTest.kt
index 548366e..d183c73 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionDialogDelegateTest.kt
@@ -79,7 +79,7 @@
         val overrideDisableSingleAppOption = false
         setUpAndShowDialog(overrideDisableSingleAppOption)
 
-        val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_spinner)
+        val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_options)
         val secondOptionText =
             spinner.adapter
                 .getDropDownView(1, null, spinner)
@@ -100,7 +100,7 @@
         val overrideDisableSingleAppOption = true
         setUpAndShowDialog(overrideDisableSingleAppOption)
 
-        val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_spinner)
+        val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_options)
         val secondOptionText =
             spinner.adapter
                 .getDropDownView(1, null, spinner)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt
new file mode 100644
index 0000000..84ec1a5
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.mediarouter.data.repository
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.statusbar.policy.CastDevice
+import com.android.systemui.statusbar.policy.fakeCastController
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+class MediaRouterRepositoryTest : SysuiTestCase() {
+    val kosmos = Kosmos()
+    val testScope = kosmos.testScope
+    val castController = kosmos.fakeCastController
+
+    val underTest = kosmos.realMediaRouterRepository
+
+    @Test
+    fun castDevices_empty_isEmpty() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.castDevices)
+            // Required to let the listener attach before the devices get set
+            runCurrent()
+
+            castController.castDevices = emptyList()
+
+            assertThat(latest).isEmpty()
+        }
+
+    @Test
+    fun castDevices_onlyIncludesMediaRouterOriginDevices() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.castDevices)
+            // Required to let the listener attach before the devices get set
+            runCurrent()
+
+            val projectionDevice =
+                CastDevice(
+                    id = "idProjection",
+                    name = "name",
+                    description = "desc",
+                    state = CastDevice.CastState.Connected,
+                    origin = CastDevice.CastOrigin.MediaProjection,
+                )
+            val routerDevice1 =
+                CastDevice(
+                    id = "idRouter1",
+                    name = "name",
+                    description = "desc",
+                    state = CastDevice.CastState.Connected,
+                    origin = CastDevice.CastOrigin.MediaRouter,
+                )
+
+            val routerDevice2 =
+                CastDevice(
+                    id = "idRouter2",
+                    name = "name",
+                    description = "desc",
+                    state = CastDevice.CastState.Connected,
+                    origin = CastDevice.CastOrigin.MediaRouter,
+                )
+            castController.setCastDevices(listOf(projectionDevice, routerDevice1, routerDevice2))
+
+            assertThat(latest).containsExactly(routerDevice1, routerDevice2).inOrder()
+        }
+
+    @Test
+    fun stopCasting_notifiesCastController() {
+        val device =
+            CastDevice(
+                id = "id",
+                name = "name",
+                description = "desc",
+                state = CastDevice.CastState.Connected,
+                origin = CastDevice.CastOrigin.MediaRouter,
+            )
+
+        underTest.stopCasting(device)
+
+        assertThat(castController.lastStoppedDevice).isEqualTo(device)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java
index 2ff660f..bfbb7ce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java
@@ -36,6 +36,7 @@
 
 import android.content.ComponentName;
 import android.content.res.Configuration;
+import android.os.Handler;
 import android.view.IWindowManager;
 import android.view.accessibility.AccessibilityManager;
 
@@ -65,6 +66,8 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
@@ -120,6 +123,10 @@
     EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory;
     @Mock
     NotificationShadeWindowController mNotificationShadeWindowController;
+    @Mock
+    Handler mBgHandler;
+
+    @Captor ArgumentCaptor<Runnable> mRunnableArgumentCaptor;
     ConfigurationController mConfigurationController = new FakeConfigurationController();
 
     private AccessibilityManager.AccessibilityServicesStateChangeListener
@@ -149,7 +156,7 @@
                 () -> Optional.of(mock(CentralSurfaces.class)), mock(KeyguardStateController.class),
                 mNavigationModeController, mEdgeBackGestureHandlerFactory, mWm, mUserTracker,
                 mDisplayTracker, mNotificationShadeWindowController, mConfigurationController,
-                mDumpManager, mCommandQueue, mSynchronousExecutor);
+                mDumpManager, mCommandQueue, mSynchronousExecutor, mBgHandler);
     }
 
     @Test
@@ -203,8 +210,10 @@
                 .updateAccessibilityServicesState();
         verify(mNavbarTaskbarStateUpdater, times(1))
                 .updateAssistantAvailable(anyBoolean(), anyBoolean());
+        verify(mBgHandler).post(mRunnableArgumentCaptor.capture());
+        mRunnableArgumentCaptor.getValue().run();
         verify(mNavbarTaskbarStateUpdater, times(1))
-                .updateRotationWatcherState(anyInt());
+                .updateRotationWatcherState(anyInt(), anyBoolean());
         verify(mNavbarTaskbarStateUpdater, times(1))
                 .updateWallpaperVisibility(anyBoolean(), anyInt());
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarButtonTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarButtonTest.java
deleted file mode 100644
index 85244fd..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarButtonTest.java
+++ /dev/null
@@ -1,152 +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.navigationbar;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.graphics.PixelFormat;
-import android.hardware.display.DisplayManager;
-import android.hardware.display.VirtualDisplay;
-import android.media.ImageReader;
-import android.os.SystemClock;
-import android.testing.TestableLooper.RunWithLooper;
-import android.util.Log;
-import android.view.Display;
-import android.view.DisplayInfo;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.SysuiTestableContext;
-import com.android.systemui.assist.AssistManager;
-import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
-import com.android.systemui.recents.OverviewProxyService;
-import com.android.systemui.settings.FakeDisplayTracker;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-
-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.function.Predicate;
-
-/** atest NavigationBarButtonTest */
-@RunWith(AndroidJUnit4.class)
-@RunWithLooper
-@SmallTest
-public class NavigationBarButtonTest extends SysuiTestCase {
-
-    @Mock
-    EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory;
-    @Mock
-    EdgeBackGestureHandler mEdgeBackGestureHandler;
-    private static final String TAG = "NavigationBarButtonTest";
-    private ImageReader mReader;
-    private NavigationBarView mNavBar;
-    private VirtualDisplay mVirtualDisplay;
-    private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        final Display display = createVirtualDisplay();
-        final SysuiTestableContext context =
-                (SysuiTestableContext) mContext.createDisplayContext(display);
-
-        when(mEdgeBackGestureHandlerFactory.create(any(Context.class)))
-                .thenReturn(mEdgeBackGestureHandler);
-
-        mDependency.injectMockDependency(AssistManager.class);
-        mDependency.injectMockDependency(OverviewProxyService.class);
-        mDependency.injectMockDependency(KeyguardStateController.class);
-        mDependency.injectMockDependency(NavigationBarController.class);
-        mDependency.injectTestDependency(EdgeBackGestureHandler.Factory.class,
-                mEdgeBackGestureHandlerFactory);
-        mNavBar = new NavigationBarView(context, null);
-        mNavBar.setDisplayTracker(mDisplayTracker);
-    }
-
-    private Display createVirtualDisplay() {
-        final String displayName = "NavVirtualDisplay";
-        final DisplayInfo displayInfo = new DisplayInfo();
-        mContext.getDisplay().getDisplayInfo(displayInfo);
-
-        final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
-
-        mReader = ImageReader.newInstance(displayInfo.logicalWidth,
-                displayInfo.logicalHeight, PixelFormat.RGBA_8888, 2);
-
-        assertNotNull("ImageReader must not be null", mReader);
-
-        mVirtualDisplay = displayManager.createVirtualDisplay(displayName, displayInfo.logicalWidth,
-                displayInfo.logicalHeight, displayInfo.logicalDensityDpi, mReader.getSurface(),
-                0 /*flags*/);
-
-        assertNotNull("virtual display must not be null", mVirtualDisplay);
-
-        waitForDisplayReady(mVirtualDisplay.getDisplay().getDisplayId());
-
-        return mVirtualDisplay.getDisplay();
-    }
-
-    private void waitForDisplayReady(int displayId) {
-        waitForDisplayCondition(displayId, state -> state);
-    }
-
-    private void waitForDisplayCondition(int displayId, Predicate<Boolean> condition) {
-        for (int retry = 1; retry <= 10; retry++) {
-            if (condition.test(isDisplayOn(displayId))) {
-                return;
-            }
-            Log.i(TAG, "Waiting for virtual display ready ... retry = " + retry);
-            SystemClock.sleep(500);
-        }
-    }
-
-    private boolean isDisplayOn(int displayId) {
-        DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
-        Display display = displayManager.getDisplay(displayId);
-        return display != null && display.getState() == Display.STATE_ON;
-    }
-
-    @After
-    public void tearDown() {
-        releaseDisplay();
-    }
-
-    private void releaseDisplay() {
-        mVirtualDisplay.release();
-        mReader.close();
-    }
-
-    @Test
-    public void testRecentsButtonDisabledOnSecondaryDisplay() {
-        assertTrue("The recents button must be disabled",
-                mNavBar.isRecentsButtonDisabled());
-    }
-}
-
-
-
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java
index d5361ac..196bbb9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerImplTest.java
@@ -21,6 +21,7 @@
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
 import static com.android.wm.shell.Flags.enableTaskbarNavbarUnification;
+import static com.android.wm.shell.Flags.enableTaskbarOnPhones;
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -48,6 +49,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.model.SysUiState;
+import com.android.systemui.navigationbar.views.NavigationBar;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.settings.FakeDisplayTracker;
 import com.android.systemui.shared.recents.utilities.Utilities;
@@ -142,10 +144,11 @@
 
     @Test
     public void testCreateNavigationBarsIncludeDefaultTrue() {
-        assumeFalse(enableTaskbarNavbarUnification());
+        assumeFalse(enableTaskbarNavbarUnification() && enableTaskbarOnPhones());
 
         // Large screens may be using taskbar and the logic is different
         mNavigationBarController.mIsLargeScreen = false;
+        mNavigationBarController.mIsPhone = true;
         doNothing().when(mNavigationBarController).createNavigationBar(any(), any(), any());
 
         mNavigationBarController.createNavigationBars(true, null);
@@ -291,6 +294,17 @@
 
     @Test
     public void testShouldRenderTaskbar_taskbarNotRenderedOnPhone() {
+        assumeFalse(enableTaskbarOnPhones());
+
+        mNavigationBarController.mIsLargeScreen = false;
+        mNavigationBarController.mIsPhone = true;
+        assertFalse(mNavigationBarController.supportsTaskbar());
+    }
+
+    @Test
+    public void testShouldRenderTaskbar_taskbarRenderedOnPhone() {
+        assumeTrue(enableTaskbarNavbarUnification() && enableTaskbarOnPhones());
+
         mNavigationBarController.mIsLargeScreen = false;
         mNavigationBarController.mIsPhone = true;
         assertFalse(mNavigationBarController.supportsTaskbar());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarInflaterViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarInflaterViewTest.java
deleted file mode 100644
index a358c18..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarInflaterViewTest.java
+++ /dev/null
@@ -1,111 +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.navigationbar;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-
-import android.testing.TestableLooper.RunWithLooper;
-import android.util.SparseArray;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.assist.AssistManager;
-import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
-import com.android.systemui.recents.OverviewProxyService;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/** atest NavigationBarInflaterViewTest */
-@RunWith(AndroidJUnit4.class)
-@RunWithLooper
-@SmallTest
-public class NavigationBarInflaterViewTest extends SysuiTestCase {
-
-    private NavigationBarInflaterView mNavBarInflaterView;
-
-    private static final int BUTTON_ID = 0;
-
-    @Before
-    public void setUp() {
-        mDependency.injectMockDependency(AssistManager.class);
-        mDependency.injectMockDependency(OverviewProxyService.class);
-        mDependency.injectMockDependency(NavigationModeController.class);
-        mDependency.injectMockDependency(NavigationBarController.class);
-
-        mNavBarInflaterView = spy(new NavigationBarInflaterView(mContext, null));
-        doNothing().when(mNavBarInflaterView).createInflaters();
-
-        mNavBarInflaterView.mButtonDispatchers = new SparseArray<>(1);
-        mNavBarInflaterView.mButtonDispatchers.put(BUTTON_ID, new ButtonDispatcher(BUTTON_ID));
-
-        initializeViews();
-    }
-
-    private void initializeViews() {
-        mNavBarInflaterView.mVertical = mock(FrameLayout.class);
-        mNavBarInflaterView.mHorizontal = mock(FrameLayout.class);
-        initializeLayout(mNavBarInflaterView.mVertical);
-        initializeLayout(mNavBarInflaterView.mHorizontal);
-    }
-
-    private void initializeLayout(FrameLayout layout) {
-        View verticalChildView = mock(View.class);
-        verticalChildView.setId(BUTTON_ID);
-        doReturn(layout).when(verticalChildView).getParent();
-        doReturn(verticalChildView).when(layout).findViewById(BUTTON_ID);
-    }
-
-    @After
-    public void tearDown() {
-        mNavBarInflaterView = null;
-    }
-
-    @Test
-    public void testUpdateButtonDispatchersCurrentView_isVerticalTrue() {
-        mNavBarInflaterView.setVertical(true);
-
-        mNavBarInflaterView.updateButtonDispatchersCurrentView();
-
-        ButtonDispatcher button = mNavBarInflaterView.mButtonDispatchers.get(BUTTON_ID);
-        assertEquals("Buttons need to be set to vertical layout",
-                mNavBarInflaterView.mVertical.getId(),
-                ((View) button.getCurrentView().getParent()).getId());
-    }
-
-    @Test
-    public void testUpdateButtonDispatchersCurrentView_isVerticalFalse() {
-        mNavBarInflaterView.setVertical(false);
-
-        mNavBarInflaterView.updateButtonDispatchersCurrentView();
-
-        ButtonDispatcher button = mNavBarInflaterView.mButtonDispatchers.get(BUTTON_ID);
-        assertEquals("Buttons need to be set to horizon layout",
-                mNavBarInflaterView.mHorizontal.getId(),
-                ((View) button.getCurrentView().getParent()).getId());
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
deleted file mode 100644
index 2b60f65..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
+++ /dev/null
@@ -1,614 +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.navigationbar;
-
-import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
-import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
-import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN;
-import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT;
-import static android.inputmethodservice.InputMethodService.IME_INVISIBLE;
-import static android.inputmethodservice.InputMethodService.IME_VISIBLE;
-import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
-import static android.view.WindowInsets.Type.ime;
-
-import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.HOME_BUTTON_LONG_PRESS_DURATION_MS;
-import static com.android.systemui.assist.AssistManager.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS;
-import static com.android.systemui.navigationbar.NavigationBar.NavBarActionEvent.NAVBAR_ASSIST_LONGPRESS;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-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;
-
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.res.Resources;
-import android.hardware.display.DisplayManagerGlobal;
-import android.os.Handler;
-import android.os.SystemClock;
-import android.provider.DeviceConfig;
-import android.telecom.TelecomManager;
-import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
-import android.view.Display;
-import android.view.DisplayInfo;
-import android.view.IWindowManager;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewRootImpl;
-import android.view.ViewTreeObserver;
-import android.view.WindowInsets;
-import android.view.WindowManager;
-import android.view.WindowMetrics;
-import android.view.accessibility.AccessibilityManager;
-import android.view.inputmethod.InputMethodManager;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.SysuiTestableContext;
-import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
-import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver;
-import com.android.systemui.accessibility.SystemActions;
-import com.android.systemui.assist.AssistManager;
-import com.android.systemui.dump.DumpManager;
-import com.android.systemui.keyguard.WakefulnessLifecycle;
-import com.android.systemui.model.SysUiState;
-import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
-import com.android.systemui.navigationbar.buttons.DeadZone;
-import com.android.systemui.navigationbar.buttons.KeyButtonView;
-import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.recents.OverviewProxyService;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.settings.DisplayTracker;
-import com.android.systemui.settings.FakeDisplayTracker;
-import com.android.systemui.settings.UserContextProvider;
-import com.android.systemui.settings.UserTracker;
-import com.android.systemui.shade.NotificationShadeWindowView;
-import com.android.systemui.shade.ShadeViewController;
-import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor;
-import com.android.systemui.shared.rotation.RotationButtonController;
-import com.android.systemui.shared.system.TaskStackChangeListeners;
-import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.NotificationRemoteInputManager;
-import com.android.systemui.statusbar.NotificationShadeDepthController;
-import com.android.systemui.statusbar.NotificationShadeWindowController;
-import com.android.systemui.statusbar.phone.AutoHideController;
-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.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.util.DeviceConfigProxyFake;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.time.FakeSystemClock;
-import com.android.systemui.utils.leaks.LeakCheckedTest;
-import com.android.wm.shell.back.BackAnimation;
-import com.android.wm.shell.pip.Pip;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Optional;
-import java.util.concurrent.Executor;
-
-@RunWith(AndroidJUnit4.class)
-@RunWithLooper(setAsMainLooper = true)
-@SmallTest
-public class NavigationBarTest extends SysuiTestCase {
-    private static final int EXTERNAL_DISPLAY_ID = 2;
-
-    private NavigationBar mNavigationBar;
-    private NavigationBar mExternalDisplayNavigationBar;
-
-    private SysuiTestableContext mSysuiTestableContextExternal;
-    @Mock
-    NavigationBarView mNavigationBarView;
-    @Mock
-    NavigationBarFrame mNavigationBarFrame;
-    @Mock
-    ButtonDispatcher mHomeButton;
-    @Mock
-    KeyButtonView mHomeButtonView;
-    @Mock
-    ButtonDispatcher mRecentsButton;
-    @Mock
-    ButtonDispatcher mAccessibilityButton;
-    @Mock
-    ButtonDispatcher mImeSwitchButton;
-    @Mock
-    ButtonDispatcher mBackButton;
-    @Mock
-    NavigationBarTransitions mNavigationBarTransitions;
-    @Mock
-    RotationButtonController mRotationButtonController;
-    @Mock
-    LightBarTransitionsController mLightBarTransitionsController;
-    @Mock
-    private SystemActions mSystemActions;
-    @Mock
-    private OverviewProxyService mOverviewProxyService;
-    @Mock
-    private StatusBarStateController mStatusBarStateController;
-    @Mock
-    private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
-    @Mock
-    private NavigationModeController mNavigationModeController;
-    @Mock
-    private CommandQueue mCommandQueue;
-    private SysUiState mMockSysUiState;
-    @Mock
-    private Handler mHandler;
-    @Mock
-    private UserTracker mUserTracker;
-    @Mock
-    private UiEventLogger mUiEventLogger;
-    @Mock
-    private NavBarButtonClickLogger mNavBarButtonClickLogger;
-    @Mock
-    private NavbarOrientationTrackingLogger mNavbarOrientationTrackingLogger;
-    @Mock
-    private ViewTreeObserver mViewTreeObserver;
-    NavBarHelper mNavBarHelper;
-    @Mock
-    private LightBarController mLightBarController;
-    @Mock
-    private LightBarController.Factory mLightBarcontrollerFactory;
-    @Mock
-    private AutoHideController mAutoHideController;
-    @Mock
-    private AutoHideController.Factory mAutoHideControllerFactory;
-    @Mock
-    private WindowManager mWindowManager;
-    @Mock
-    private TelecomManager mTelecomManager;
-    @Mock
-    private InputMethodManager mInputMethodManager;
-    @Mock
-    private AssistManager mAssistManager;
-    @Mock
-    private DeadZone mDeadZone;
-    @Mock
-    private CentralSurfaces mCentralSurfaces;
-    @Mock
-    private KeyguardStateController mKeyguardStateController;
-    @Mock
-    private UserContextProvider mUserContextProvider;
-    @Mock
-    private WakefulnessLifecycle mWakefulnessLifecycle;
-    @Mock
-    private Resources mResources;
-    @Mock
-    private ViewRootImpl mViewRootImpl;
-    @Mock
-    private EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory;
-    @Mock
-    private EdgeBackGestureHandler mEdgeBackGestureHandler;
-    @Mock
-    private NotificationShadeWindowController mNotificationShadeWindowController;
-    private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
-    private DeviceConfigProxyFake mDeviceConfigProxyFake = new DeviceConfigProxyFake();
-    private TaskStackChangeListeners mTaskStackChangeListeners =
-            TaskStackChangeListeners.getTestInstance();
-
-    @Rule
-    public final LeakCheckedTest.SysuiLeakCheck mLeakCheck = new LeakCheckedTest.SysuiLeakCheck();
-
-    private final Executor mSynchronousExecutor = runnable -> runnable.run();
-
-    @Before
-    public void setup() throws Exception {
-        MockitoAnnotations.initMocks(this);
-
-        when(mLightBarcontrollerFactory.create(any(Context.class))).thenReturn(mLightBarController);
-        when(mAutoHideControllerFactory.create(any(Context.class))).thenReturn(mAutoHideController);
-        when(mNavigationBarView.getHomeButton()).thenReturn(mHomeButton);
-        when(mNavigationBarView.getRecentsButton()).thenReturn(mRecentsButton);
-        when(mNavigationBarView.getAccessibilityButton()).thenReturn(mAccessibilityButton);
-        when(mNavigationBarView.getImeSwitchButton()).thenReturn(mImeSwitchButton);
-        when(mNavigationBarView.getBackButton()).thenReturn(mBackButton);
-        when(mNavigationBarView.getRotationButtonController())
-                .thenReturn(mRotationButtonController);
-        when(mNavigationBarTransitions.getLightTransitionsController())
-                .thenReturn(mLightBarTransitionsController);
-        when(mStatusBarKeyguardViewManager.isNavBarVisible()).thenReturn(true);
-        when(mNavigationBarView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
-        when(mUserContextProvider.createCurrentUserContext(any(Context.class)))
-                .thenReturn(mContext);
-        when(mNavigationBarView.getResources()).thenReturn(mResources);
-        when(mNavigationBarView.getViewRootImpl()).thenReturn(mViewRootImpl);
-        when(mEdgeBackGestureHandlerFactory.create(any())).thenReturn(mEdgeBackGestureHandler);
-        setupSysuiDependency();
-        // This class inflates views that call Dependency.get, thus these injections are still
-        // necessary.
-        mDependency.injectTestDependency(AssistManager.class, mAssistManager);
-        mDependency.injectMockDependency(KeyguardStateController.class);
-        mDependency.injectTestDependency(StatusBarStateController.class, mStatusBarStateController);
-        mDependency.injectMockDependency(NavigationBarController.class);
-        mDependency.injectTestDependency(OverviewProxyService.class, mOverviewProxyService);
-        mDependency.injectTestDependency(NavigationModeController.class, mNavigationModeController);
-        TestableLooper.get(this).runWithLooper(() -> {
-            mNavBarHelper = spy(new NavBarHelper(mContext, mock(AccessibilityManager.class),
-                    mock(AccessibilityButtonModeObserver.class),
-                    mock(AccessibilityButtonTargetsObserver.class),
-                    mSystemActions, mOverviewProxyService,
-                    () -> mock(AssistManager.class), () -> Optional.of(mCentralSurfaces),
-                    mKeyguardStateController, mock(NavigationModeController.class),
-                    mEdgeBackGestureHandlerFactory, mock(IWindowManager.class),
-                    mock(UserTracker.class), mock(DisplayTracker.class),
-                    mNotificationShadeWindowController, mock(ConfigurationController.class),
-                    mock(DumpManager.class), mock(CommandQueue.class), mSynchronousExecutor));
-            mNavigationBar = createNavBar(mContext);
-            mExternalDisplayNavigationBar = createNavBar(mSysuiTestableContextExternal);
-        });
-    }
-
-    private void setupSysuiDependency() {
-        Display display = new Display(DisplayManagerGlobal.getInstance(), EXTERNAL_DISPLAY_ID,
-                new DisplayInfo(), DEFAULT_DISPLAY_ADJUSTMENTS);
-        mSysuiTestableContextExternal = (SysuiTestableContext) getContext().createDisplayContext(
-                display);
-
-        Display defaultDisplay = mContext.getDisplay();
-        when(mWindowManager.getDefaultDisplay()).thenReturn(defaultDisplay);
-        WindowMetrics metrics = mContext.getSystemService(WindowManager.class)
-                .getMaximumWindowMetrics();
-        when(mWindowManager.getMaximumWindowMetrics()).thenReturn(metrics);
-        WindowMetrics currentWindowMetrics = mContext.getSystemService(WindowManager.class)
-                .getCurrentWindowMetrics();
-        when(mWindowManager.getCurrentWindowMetrics()).thenReturn(currentWindowMetrics);
-        doNothing().when(mWindowManager).addView(any(), any());
-        doNothing().when(mWindowManager).removeViewImmediate(any());
-        mMockSysUiState = mock(SysUiState.class);
-        when(mMockSysUiState.setFlag(anyLong(), anyBoolean())).thenReturn(mMockSysUiState);
-
-        mContext.addMockSystemService(WindowManager.class, mWindowManager);
-        mSysuiTestableContextExternal.addMockSystemService(WindowManager.class, mWindowManager);
-    }
-
-    @Test
-    public void testHomeLongPress() {
-        when(mAssistManager.shouldOverrideAssist(INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS))
-                .thenReturn(false);
-
-        mNavigationBar.init();
-        mNavigationBar.onViewAttached();
-        mNavigationBar.onHomeLongClick(mHomeButtonView);
-
-        verify(mUiEventLogger, times(1)).log(NAVBAR_ASSIST_LONGPRESS);
-        verify(mAssistManager).startAssist(any());
-    }
-
-    @Test
-    public void testHomeLongPressOverride() {
-        when(mAssistManager.shouldOverrideAssist(INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS))
-                .thenReturn(true);
-
-        mNavigationBar.init();
-        mNavigationBar.onViewAttached();
-        mNavigationBar.onHomeLongClick(mHomeButtonView);
-
-        verify(mUiEventLogger, times(1)).log(NAVBAR_ASSIST_LONGPRESS);
-
-        ArgumentCaptor<Runnable> onRippleInvisibleRunnableCaptor = ArgumentCaptor.forClass(
-                Runnable.class);
-        // startAssist is not called initially
-        verify(mAssistManager, never()).startAssist(any());
-        // but a Runnable is added for when the ripple is invisible
-        verify(mHomeButtonView).setOnRippleInvisibleRunnable(
-                onRippleInvisibleRunnableCaptor.capture());
-        // and when that runs, startAssist is called
-        onRippleInvisibleRunnableCaptor.getValue().run();
-        verify(mAssistManager).startAssist(any());
-    }
-
-    @Test
-    public void testHomeLongPressWithCustomDuration() throws Exception {
-        mDeviceConfigProxyFake.setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                HOME_BUTTON_LONG_PRESS_DURATION_MS,
-                "100",
-                false);
-        when(mNavBarHelper.getLongPressHomeEnabled()).thenReturn(true);
-        mNavigationBar.init();
-        mNavigationBar.onViewAttached();
-
-        mNavigationBar.onHomeTouch(mNavigationBar.getView(), MotionEvent.obtain(
-                /*downTime=*/SystemClock.uptimeMillis(),
-                /*eventTime=*/SystemClock.uptimeMillis(),
-                /*action=*/MotionEvent.ACTION_DOWN,
-                0, 0, 0
-        ));
-        verify(mHandler, times(1)).postDelayed(any(), eq(100L));
-
-        mNavigationBar.onHomeTouch(mNavigationBar.getView(), MotionEvent.obtain(
-                /*downTime=*/SystemClock.uptimeMillis(),
-                /*eventTime=*/SystemClock.uptimeMillis(),
-                /*action=*/MotionEvent.ACTION_UP,
-                0, 0, 0
-        ));
-
-        verify(mHandler, times(1)).removeCallbacks(any());
-    }
-
-    @Test
-    public void onHomeTouch_isRinging_keyguardShowing_touchBlocked() {
-        when(mTelecomManager.isRinging()).thenReturn(true);
-        when(mKeyguardStateController.isShowing()).thenReturn(true);
-
-        boolean result = mNavigationBar.onHomeTouch(
-                mNavigationBar.getView(),
-                    MotionEvent.obtain(
-                    /*downTime=*/SystemClock.uptimeMillis(),
-                    /*eventTime=*/SystemClock.uptimeMillis(),
-                    /*action=*/MotionEvent.ACTION_DOWN,
-                    0, 0, 0));
-
-        assertThat(result).isTrue();
-
-        // Verify subsequent touches are also blocked
-        boolean nextTouchEvent = mNavigationBar.onHomeTouch(
-                mNavigationBar.getView(),
-                MotionEvent.obtain(
-                        /*downTime=*/SystemClock.uptimeMillis(),
-                        /*eventTime=*/SystemClock.uptimeMillis(),
-                        /*action=*/MotionEvent.ACTION_MOVE,
-                        0, 0, 0));
-        assertThat(nextTouchEvent).isTrue();
-    }
-
-    @Test
-    public void onHomeTouch_isRinging_keyguardNotShowing_touchNotBlocked() {
-        when(mTelecomManager.isRinging()).thenReturn(true);
-        when(mKeyguardStateController.isShowing()).thenReturn(false);
-
-        boolean result = mNavigationBar.onHomeTouch(
-                mNavigationBar.getView(),
-                MotionEvent.obtain(
-                        /*downTime=*/SystemClock.uptimeMillis(),
-                        /*eventTime=*/SystemClock.uptimeMillis(),
-                        /*action=*/MotionEvent.ACTION_DOWN,
-                        0, 0, 0));
-
-        assertThat(result).isFalse();
-
-        // Verify subsequent touches are also not blocked
-        boolean nextTouchEvent = mNavigationBar.onHomeTouch(
-                mNavigationBar.getView(),
-                MotionEvent.obtain(
-                        /*downTime=*/SystemClock.uptimeMillis(),
-                        /*eventTime=*/SystemClock.uptimeMillis(),
-                        /*action=*/MotionEvent.ACTION_MOVE,
-                        0, 0, 0));
-        assertThat(nextTouchEvent).isFalse();
-    }
-
-    @Test
-    public void testRegisteredWithUserTracker() {
-        mNavigationBar.init();
-        mNavigationBar.onViewAttached();
-        verify(mUserTracker).addCallback(any(UserTracker.Callback.class), any(Executor.class));
-    }
-
-    @Test
-    public void testSetImeWindowStatusWhenImeSwitchOnDisplay() {
-        // Create default & external NavBar fragment.
-        NavigationBar defaultNavBar = mNavigationBar;
-        NavigationBar externalNavBar = mExternalDisplayNavigationBar;
-        NotificationShadeWindowView mockShadeWindowView = mock(NotificationShadeWindowView.class);
-        WindowInsets windowInsets = new WindowInsets.Builder().setVisible(ime(), false).build();
-        doReturn(windowInsets).when(mockShadeWindowView).getRootWindowInsets();
-        doReturn(true).when(mockShadeWindowView).isAttachedToWindow();
-        doNothing().when(defaultNavBar).checkNavBarModes();
-        doNothing().when(externalNavBar).checkNavBarModes();
-        defaultNavBar.init();
-        externalNavBar.init();
-
-        defaultNavBar.setImeWindowStatus(DEFAULT_DISPLAY, null, IME_VISIBLE,
-                BACK_DISPOSITION_DEFAULT, true);
-
-        // Verify IME window state will be updated in default NavBar & external NavBar state reset.
-        assertEquals(NAVIGATION_HINT_BACK_ALT | NAVIGATION_HINT_IME_SHOWN
-                        | NAVIGATION_HINT_IME_SWITCHER_SHOWN,
-                defaultNavBar.getNavigationIconHints());
-        assertFalse((externalNavBar.getNavigationIconHints() & NAVIGATION_HINT_BACK_ALT) != 0);
-        assertFalse((externalNavBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SHOWN) != 0);
-        assertFalse((externalNavBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SWITCHER_SHOWN)
-                != 0);
-
-        externalNavBar.setImeWindowStatus(EXTERNAL_DISPLAY_ID, null, IME_VISIBLE,
-                BACK_DISPOSITION_DEFAULT, true);
-        defaultNavBar.setImeWindowStatus(
-                DEFAULT_DISPLAY, null, IME_INVISIBLE, BACK_DISPOSITION_DEFAULT, false);
-        // Verify IME window state will be updated in external NavBar & default NavBar state reset.
-        assertEquals(NAVIGATION_HINT_BACK_ALT | NAVIGATION_HINT_IME_SHOWN
-                        | NAVIGATION_HINT_IME_SWITCHER_SHOWN,
-                externalNavBar.getNavigationIconHints());
-        assertFalse((defaultNavBar.getNavigationIconHints() & NAVIGATION_HINT_BACK_ALT) != 0);
-        assertFalse((defaultNavBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SHOWN) != 0);
-        assertFalse((defaultNavBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SWITCHER_SHOWN)
-                != 0);
-    }
-
-    @Test
-    public void testSetImeWindowStatusWhenKeyguardLockingAndImeInsetsChange() {
-        NotificationShadeWindowView mockShadeWindowView = mock(NotificationShadeWindowView.class);
-        doReturn(mockShadeWindowView).when(mNotificationShadeWindowController).getWindowRootView();
-        doReturn(true).when(mockShadeWindowView).isAttachedToWindow();
-        doNothing().when(mNavigationBar).checkNavBarModes();
-        mNavigationBar.init();
-        WindowInsets windowInsets = new WindowInsets.Builder().setVisible(ime(), false).build();
-        doReturn(windowInsets).when(mockShadeWindowView).getRootWindowInsets();
-
-        // Verify navbar altered back icon when an app is showing IME
-        mNavigationBar.setImeWindowStatus(DEFAULT_DISPLAY, null, IME_VISIBLE,
-                BACK_DISPOSITION_DEFAULT, true);
-        assertTrue((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_BACK_ALT) != 0);
-        assertTrue((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SHOWN) != 0);
-        assertTrue((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SWITCHER_SHOWN)
-                != 0);
-
-        // Verify navbar didn't alter and showing back icon when the keyguard is showing without
-        // requesting IME insets visible.
-        doReturn(true).when(mKeyguardStateController).isShowing();
-        mNavigationBar.setImeWindowStatus(DEFAULT_DISPLAY, null, IME_VISIBLE,
-                BACK_DISPOSITION_DEFAULT, true);
-        assertFalse((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_BACK_ALT) != 0);
-        assertFalse((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SHOWN) != 0);
-        assertFalse((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SWITCHER_SHOWN)
-                != 0);
-
-        // Verify navbar altered and showing back icon when the keyguard is showing and
-        // requesting IME insets visible.
-        windowInsets = new WindowInsets.Builder().setVisible(ime(), true).build();
-        doReturn(windowInsets).when(mockShadeWindowView).getRootWindowInsets();
-        mNavigationBar.setImeWindowStatus(DEFAULT_DISPLAY, null, IME_VISIBLE,
-                BACK_DISPOSITION_DEFAULT, true);
-        assertTrue((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_BACK_ALT) != 0);
-        assertTrue((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SHOWN) != 0);
-        assertTrue((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SWITCHER_SHOWN)
-                != 0);
-    }
-
-    @Test
-    public void testA11yEventAfterDetach() {
-        mNavigationBar.init();
-        mNavigationBar.onViewAttached();
-        verify(mNavBarHelper).registerNavTaskStateUpdater(any(
-                NavBarHelper.NavbarTaskbarStateUpdater.class));
-        mNavigationBar.onViewDetached();
-        verify(mNavBarHelper).removeNavTaskStateUpdater(any(
-                NavBarHelper.NavbarTaskbarStateUpdater.class));
-
-        // Should be safe even though the internal view is now null.
-        mNavigationBar.updateAccessibilityStateFlags();
-    }
-
-    @Test
-    public void testCreateView_initiallyVisible_viewIsVisible() {
-        when(mStatusBarKeyguardViewManager.isNavBarVisible()).thenReturn(true);
-        mNavigationBar.init();
-        mNavigationBar.onViewAttached();
-
-        verify(mNavigationBarView).setVisibility(View.VISIBLE);
-    }
-
-    @Test
-    public void testCreateView_initiallyNotVisible_viewIsNotVisible() {
-        when(mStatusBarKeyguardViewManager.isNavBarVisible()).thenReturn(false);
-        mNavigationBar.init();
-        mNavigationBar.onViewAttached();
-
-        verify(mNavigationBarView).setVisibility(View.INVISIBLE);
-    }
-
-    @Test
-    public void testOnInit_readCurrentSysuiState() {
-        mNavigationBar.init();
-        verify(mNavBarHelper, times(1)).getCurrentSysuiState();
-    }
-
-    @Test
-    public void testScreenPinningEnabled_updatesSysuiState() {
-        mNavigationBar.init();
-        mTaskStackChangeListeners.getListenerImpl().onLockTaskModeChanged(
-                ActivityManager.LOCK_TASK_MODE_PINNED);
-        verify(mMockSysUiState).setFlag(eq(SYSUI_STATE_SCREEN_PINNING), eq(true));
-    }
-
-    private NavigationBar createNavBar(Context context) {
-        DeviceProvisionedController deviceProvisionedController =
-                mock(DeviceProvisionedController.class);
-        when(deviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
-        return spy(new NavigationBar(
-                mNavigationBarView,
-                mNavigationBarFrame,
-                null,
-                context,
-                mWindowManager,
-                () -> mAssistManager,
-                mock(AccessibilityManager.class),
-                deviceProvisionedController,
-                new MetricsLogger(),
-                mOverviewProxyService,
-                mNavigationModeController,
-                mStatusBarStateController,
-                mStatusBarKeyguardViewManager,
-                mMockSysUiState,
-                mUserTracker,
-                mCommandQueue,
-                Optional.of(mock(Pip.class)),
-                Optional.of(mock(Recents.class)),
-                () -> Optional.of(mCentralSurfaces),
-                mKeyguardStateController,
-                mock(ShadeViewController.class),
-                mock(PanelExpansionInteractor.class),
-                mock(NotificationRemoteInputManager.class),
-                mock(NotificationShadeDepthController.class),
-                mHandler,
-                mFakeExecutor,
-                mFakeExecutor,
-                mUiEventLogger,
-                mNavBarHelper,
-                mLightBarController,
-                mLightBarcontrollerFactory,
-                mAutoHideController,
-                mAutoHideControllerFactory,
-                Optional.of(mTelecomManager),
-                mInputMethodManager,
-                mDeadZone,
-                mDeviceConfigProxyFake,
-                mNavigationBarTransitions,
-                Optional.of(mock(BackAnimation.class)),
-                mUserContextProvider,
-                mWakefulnessLifecycle,
-                mTaskStackChangeListeners,
-                new FakeDisplayTracker(mContext),
-                mNavBarButtonClickLogger,
-                mNavbarOrientationTrackingLogger));
-    }
-
-    private void processAllMessages() {
-        TestableLooper.get(this).processAllMessages();
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java
deleted file mode 100644
index fbfd35f..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTransitionsTest.java
+++ /dev/null
@@ -1,108 +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.navigationbar;
-
-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.when;
-
-import android.content.Context;
-import android.testing.TestableLooper.RunWithLooper;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.assist.AssistManager;
-import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.recents.OverviewProxyService;
-import com.android.systemui.settings.FakeDisplayTracker;
-import com.android.systemui.statusbar.phone.BarTransitions;
-import com.android.systemui.statusbar.phone.LightBarTransitionsController;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidJUnit4.class)
-@RunWithLooper
-@SmallTest
-public class NavigationBarTransitionsTest extends SysuiTestCase {
-
-    @Mock
-    LightBarTransitionsController.Factory mLightBarTransitionsFactory;
-    @Mock
-    LightBarTransitionsController mLightBarTransitions;
-    @Mock
-    EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory;
-    @Mock
-    EdgeBackGestureHandler mEdgeBackGestureHandler;
-
-    private NavigationBarTransitions mTransitions;
-    private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-
-        when(mEdgeBackGestureHandlerFactory.create(any(Context.class)))
-                .thenReturn(mEdgeBackGestureHandler);
-        mDependency.injectMockDependency(AssistManager.class);
-        mDependency.injectMockDependency(OverviewProxyService.class);
-        mDependency.injectMockDependency(StatusBarStateController.class);
-        mDependency.injectMockDependency(KeyguardStateController.class);
-        mDependency.injectMockDependency(NavigationBarController.class);
-        mDependency.injectTestDependency(EdgeBackGestureHandler.Factory.class,
-                mEdgeBackGestureHandlerFactory);
-        doReturn(mContext)
-                .when(mDependency.injectMockDependency(NavigationModeController.class))
-                .getCurrentUserContext();
-
-        when(mLightBarTransitionsFactory.create(any())).thenReturn(mLightBarTransitions);
-        NavigationBarView navBar = spy(new NavigationBarView(mContext, null));
-        when(navBar.getCurrentView()).thenReturn(navBar);
-        when(navBar.findViewById(anyInt())).thenReturn(navBar);
-        mTransitions = new NavigationBarTransitions(
-                navBar, mLightBarTransitionsFactory, mDisplayTracker);
-    }
-
-    @Test
-    public void setIsLightsOut_NoAutoDim() {
-        mTransitions.setAutoDim(false);
-
-        assertFalse(mTransitions.isLightsOut(BarTransitions.MODE_OPAQUE));
-
-        assertTrue(mTransitions.isLightsOut(BarTransitions.MODE_LIGHTS_OUT));
-    }
-
-    @Test
-    public void setIsLightsOut_AutoDim() {
-        mTransitions.setAutoDim(true);
-
-        assertTrue(mTransitions.isLightsOut(BarTransitions.MODE_OPAQUE));
-
-        assertTrue(mTransitions.isLightsOut(BarTransitions.MODE_LIGHTS_OUT));
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt
index bba275e..eae6cdb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/TaskbarDelegateTest.kt
@@ -1,11 +1,13 @@
 package com.android.systemui.navigationbar
 
 import android.app.ActivityManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.model.SysUiState
 import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler
+import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.recents.OverviewProxyService
 import com.android.systemui.shared.system.QuickStepContract
 import com.android.systemui.shared.system.TaskStackChangeListeners
@@ -19,6 +21,7 @@
 import java.util.Optional
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers
 import org.mockito.Mock
 import org.mockito.Mockito.any
@@ -30,6 +33,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class TaskbarDelegateTest : SysuiTestCase() {
     val DISPLAY_ID = 0;
     val MODE_GESTURE = 0;
@@ -67,6 +71,8 @@
     lateinit var mCurrentSysUiState: NavBarHelper.CurrentSysuiState
     @Mock
     lateinit var mStatusBarKeyguardViewManager: StatusBarKeyguardViewManager
+    @Mock
+    lateinit var mStatusBarStateController: StatusBarStateController
 
     @Before
     fun setup() {
@@ -77,7 +83,7 @@
         `when`(mSysUiState.setFlag(anyLong(), anyBoolean())).thenReturn(mSysUiState)
         mTaskStackChangeListeners = TaskStackChangeListeners.getTestInstance()
         mTaskbarDelegate = TaskbarDelegate(context, mLightBarControllerFactory,
-            mStatusBarKeyguardViewManager)
+            mStatusBarKeyguardViewManager, mStatusBarStateController)
         mTaskbarDelegate.setDependencies(mCommandQueue, mOverviewProxyService, mNavBarHelper,
         mNavigationModeController, mSysUiState, mDumpManager, mAutoHideController,
                 mLightBarController, mOptionalPip, mBackAnimation, mTaskStackChangeListeners)
@@ -108,4 +114,4 @@
             ArgumentMatchers.eq(true)
         )
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/KeyButtonViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/KeyButtonViewTest.java
deleted file mode 100644
index 841f620..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/KeyButtonViewTest.java
+++ /dev/null
@@ -1,167 +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.navigationbar.buttons;
-
-import static android.view.KeyEvent.ACTION_DOWN;
-import static android.view.KeyEvent.ACTION_UP;
-import static android.view.KeyEvent.FLAG_CANCELED;
-import static android.view.KeyEvent.FLAG_LONG_PRESS;
-import static android.view.KeyEvent.KEYCODE_0;
-import static android.view.KeyEvent.KEYCODE_APP_SWITCH;
-import static android.view.KeyEvent.KEYCODE_BACK;
-import static android.view.KeyEvent.KEYCODE_HOME;
-import static android.view.KeyEvent.KEYCODE_UNKNOWN;
-
-import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_BACK_BUTTON_LONGPRESS;
-import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_BACK_BUTTON_TAP;
-import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_HOME_BUTTON_LONGPRESS;
-import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_HOME_BUTTON_TAP;
-import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_LONGPRESS;
-import static com.android.systemui.navigationbar.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_TAP;
-
-import static org.mockito.ArgumentMatchers.any;
-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 android.hardware.input.InputManagerGlobal;
-import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
-import android.view.KeyEvent;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.assist.AssistManager;
-import com.android.systemui.recents.OverviewProxyService;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidJUnit4.class)
-@RunWithLooper
-@SmallTest
-public class KeyButtonViewTest extends SysuiTestCase {
-
-    private KeyButtonView mKeyButtonView;
-    private MetricsLogger mMetricsLogger;
-    private UiEventLogger mUiEventLogger;
-    private InputManagerGlobal mInputManagerGlobal = mock(InputManagerGlobal.class);
-    @Captor
-    private ArgumentCaptor<KeyEvent> mInputEventCaptor;
-
-    @Before
-    public void setup() throws Exception {
-        MockitoAnnotations.initMocks(this);
-        mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
-        mDependency.injectMockDependency(OverviewProxyService.class);
-        mDependency.injectMockDependency(AssistManager.class);
-        mUiEventLogger = mDependency.injectMockDependency(UiEventLogger.class);
-
-        TestableLooper.get(this).runWithLooper(() -> {
-            mKeyButtonView = new KeyButtonView(mContext, null, 0,
-                    mInputManagerGlobal, mUiEventLogger);
-        });
-    }
-
-    @Test
-    public void testLogBackPress() {
-        checkmetrics(KEYCODE_BACK, ACTION_UP, 0, NAVBAR_BACK_BUTTON_TAP);
-    }
-
-    @Test
-    public void testLogOverviewPress() {
-        checkmetrics(KEYCODE_APP_SWITCH, ACTION_UP, 0, NAVBAR_OVERVIEW_BUTTON_TAP);
-    }
-
-    @Test
-    public void testLogHomePress() {
-        checkmetrics(KEYCODE_HOME, ACTION_UP, 0, NAVBAR_HOME_BUTTON_TAP);
-    }
-
-    @Test
-    public void testLogBackLongPressLog() {
-        checkmetrics(KEYCODE_BACK, ACTION_DOWN, FLAG_LONG_PRESS, NAVBAR_BACK_BUTTON_LONGPRESS);
-    }
-
-    @Test
-    public void testLogOverviewLongPress() {
-        checkmetrics(KEYCODE_APP_SWITCH, ACTION_DOWN, FLAG_LONG_PRESS,
-                NAVBAR_OVERVIEW_BUTTON_LONGPRESS);
-    }
-
-    @Test
-    public void testLogHomeLongPress() {
-        checkmetrics(KEYCODE_HOME, ACTION_DOWN, FLAG_LONG_PRESS, NAVBAR_HOME_BUTTON_LONGPRESS);
-    }
-
-    @Test
-    public void testNoLogKeyDown() {
-        checkmetrics(KEYCODE_BACK, ACTION_DOWN, 0, null);
-    }
-
-    @Test
-    public void testNoLogTapAfterLong() {
-        mKeyButtonView.mLongClicked = true;
-        checkmetrics(KEYCODE_BACK, ACTION_UP, 0, null);
-    }
-
-    @Test
-    public void testNoLogCanceled() {
-        checkmetrics(KEYCODE_HOME, ACTION_UP, FLAG_CANCELED, null);
-    }
-
-    @Test
-    public void testNoLogArbitraryKeys() {
-        checkmetrics(KEYCODE_0, ACTION_UP, 0, null);
-    }
-
-    @Test
-    public void testEventInjectedOnAbortGesture() {
-        mKeyButtonView.setCode(KEYCODE_HOME);
-        mKeyButtonView.abortCurrentGesture();
-        verify(mInputManagerGlobal, times(1))
-                .injectInputEvent(any(KeyEvent.class), any(Integer.class));
-    }
-
-    @Test
-    public void testNoEventInjectedOnAbortUnknownGesture() {
-        mKeyButtonView.setCode(KEYCODE_UNKNOWN);
-        mKeyButtonView.abortCurrentGesture();
-        verify(mInputManagerGlobal, never())
-                .injectInputEvent(any(KeyEvent.class), any(Integer.class));
-    }
-
-    private void checkmetrics(int code, int action, int flag,
-            KeyButtonView.NavBarButtonEvent expected) {
-        mKeyButtonView.setCode(code);
-        mKeyButtonView.sendEvent(action, flag);
-        if (expected == null) {
-            verify(mUiEventLogger, never()).log(any(KeyButtonView.NavBarButtonEvent.class));
-        } else {
-            verify(mUiEventLogger, times(1)).log(expected);
-        }
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NavigationBarContextTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NavigationBarContextTest.java
deleted file mode 100644
index 7eb7c8e..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NavigationBarContextTest.java
+++ /dev/null
@@ -1,226 +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.navigationbar.buttons;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.view.View;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.assist.AssistManager;
-import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/** atest NavigationBarContextTest */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class NavigationBarContextTest extends SysuiTestCase {
-    private static final int GROUP_ID = 1;
-    private static final int BUTTON_0_ID = GROUP_ID + 1;
-    private static final int BUTTON_1_ID = GROUP_ID + 2;
-    private static final int BUTTON_2_ID = GROUP_ID + 3;
-
-    private static final float TEST_DARK_INTENSITY = 0.6f;
-    private static final float DARK_INTENSITY_ERR = 0.0002f;
-    private static final int ICON_RES_ID = 1;
-
-    @Mock
-    EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory;
-    @Mock
-    EdgeBackGestureHandler mEdgeBackGestureHandler;
-
-    private ContextualButtonGroup mGroup;
-    private ContextualButton mBtn0;
-    private ContextualButton mBtn1;
-    private ContextualButton mBtn2;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-
-        when(mEdgeBackGestureHandlerFactory.create(any(Context.class)))
-                .thenReturn(mEdgeBackGestureHandler);
-
-        mDependency.injectMockDependency(AssistManager.class);
-        mDependency.injectTestDependency(EdgeBackGestureHandler.Factory.class,
-                mEdgeBackGestureHandlerFactory);
-
-        mGroup = new ContextualButtonGroup(GROUP_ID);
-        mBtn0 = new ContextualButton(BUTTON_0_ID, mContext, ICON_RES_ID);
-        mBtn1 = new ContextualButton(BUTTON_1_ID, mContext, ICON_RES_ID);
-        mBtn2 = new ContextualButton(BUTTON_2_ID, mContext, ICON_RES_ID);
-
-        // Order of adding buttons to group determines the priority, ascending priority order
-        mGroup.addButton(mBtn0);
-        mGroup.addButton(mBtn1);
-        mGroup.addButton(mBtn2);
-    }
-
-    @Test
-    public void testAddGetContextButtons() throws Exception {
-        assertEquals(mBtn0, mGroup.getContextButton(BUTTON_0_ID));
-        assertEquals(mBtn1, mGroup.getContextButton(BUTTON_1_ID));
-        assertEquals(mBtn2, mGroup.getContextButton(BUTTON_2_ID));
-    }
-
-    @Test
-    public void testSetButtonVisibility() throws Exception {
-        assertTrue("By default the group should be visible.", mGroup.isVisible());
-
-        // Set button 1 to be visible, make sure it is the only visible button
-        showButton(mBtn1);
-        assertFalse(mBtn0.isVisible());
-        assertTrue(mBtn1.isVisible());
-        assertFalse(mBtn2.isVisible());
-
-        // Hide button 1 and make sure the group is also invisible
-        assertNotEquals(mGroup.setButtonVisibility(BUTTON_1_ID, false /* visible */), View.VISIBLE);
-        assertFalse("No buttons are visible, group should also be hidden", mGroup.isVisible());
-        assertNull("No buttons should be visible", mGroup.getVisibleContextButton());
-    }
-
-    @Test(expected = RuntimeException.class)
-    public void testSetButtonVisibilityUnaddedButton() throws Exception {
-        int id = mBtn2.getId() + 1;
-        mGroup.setButtonVisibility(id, true /* visible */);
-        fail("Did not throw when setting a button with an invalid id");
-    }
-
-    @Test
-    public void testSetHigherPriorityButton() throws Exception {
-        // Show button 0
-        showButton(mBtn0);
-
-        // Show button 1
-        showButton(mBtn1);
-        assertTrue("Button 0 should be visible behind",
-                mGroup.isButtonVisibleWithinGroup(mBtn0.getId()));
-
-        // Show button 2
-        showButton(mBtn2);
-        assertTrue("Button 1 should be visible behind",
-                mGroup.isButtonVisibleWithinGroup(mBtn1.getId()));
-        assertTrue(mGroup.isButtonVisibleWithinGroup(mBtn0.getId()));
-        assertTrue(mGroup.isButtonVisibleWithinGroup(mBtn1.getId()));
-        assertTrue(mGroup.isButtonVisibleWithinGroup(mBtn2.getId()));
-
-        // Hide button 2
-        assertNotEquals(mGroup.setButtonVisibility(BUTTON_2_ID, false /* visible */), View.VISIBLE);
-        assertEquals("Hiding button 2 should show button 1", mBtn1,
-                mGroup.getVisibleContextButton());
-
-        // Hide button 1
-        assertNotEquals(mGroup.setButtonVisibility(BUTTON_1_ID, false /* visible */), View.VISIBLE);
-        assertEquals("Hiding button 1 should show button 0", mBtn0,
-                mGroup.getVisibleContextButton());
-
-        // Hide button 0, all buttons are now invisible
-        assertNotEquals(mGroup.setButtonVisibility(BUTTON_0_ID, false /* visible */), View.VISIBLE);
-        assertFalse("No buttons are visible, group should also be invisible", mGroup.isVisible());
-        assertNull(mGroup.getVisibleContextButton());
-        assertFalse(mGroup.isButtonVisibleWithinGroup(mBtn0.getId()));
-        assertFalse(mGroup.isButtonVisibleWithinGroup(mBtn1.getId()));
-        assertFalse(mGroup.isButtonVisibleWithinGroup(mBtn2.getId()));
-    }
-
-    @Test
-    public void testSetLowerPriorityButton() throws Exception {
-        // Show button 2
-        showButton(mBtn2);
-
-        // Show button 1
-        assertNotEquals(mGroup.setButtonVisibility(BUTTON_1_ID, true /* visible */), View.VISIBLE);
-        assertTrue("Showing button 1 lower priority should be hidden but visible underneath",
-                mGroup.isButtonVisibleWithinGroup(BUTTON_1_ID));
-        assertFalse(mBtn0.isVisible());
-        assertFalse(mBtn1.isVisible());
-        assertTrue(mBtn2.isVisible());
-
-        // Hide button 1
-        assertNotEquals(mGroup.setButtonVisibility(BUTTON_1_ID, false /* visible */), View.VISIBLE);
-        assertFalse("Hiding button 1 with lower priority hides itself underneath",
-                mGroup.isButtonVisibleWithinGroup(BUTTON_1_ID));
-        assertTrue("A button still visible, group should also be visible", mGroup.isVisible());
-        assertEquals(mBtn2, mGroup.getVisibleContextButton());
-    }
-
-    @Test
-    public void testSetSamePriorityButton() throws Exception {
-        // Show button 1
-        showButton(mBtn1);
-
-        // Show button 1 again
-        showButton(mBtn1);
-
-        // The original button should still be visible
-        assertEquals(mBtn1, mGroup.getVisibleContextButton());
-        assertFalse(mGroup.isButtonVisibleWithinGroup(mBtn0.getId()));
-        assertFalse(mGroup.isButtonVisibleWithinGroup(mBtn2.getId()));
-    }
-
-    @Test
-    @Ignore("b/112934365")
-    public void testUpdateIconsDarkIntensity() throws Exception {
-        final int unusedColor = 0;
-        final Drawable d = mock(Drawable.class);
-        final ContextualButton button = spy(mBtn0);
-        final KeyButtonDrawable kbd1 = spy(new KeyButtonDrawable(d, unusedColor, unusedColor,
-                false /* horizontalFlip */, null /* ovalBackgroundColor */));
-        final KeyButtonDrawable kbd2 = spy(new KeyButtonDrawable(d, unusedColor, unusedColor,
-                false /* horizontalFlip */, null /* ovalBackgroundColor */));
-        kbd1.setDarkIntensity(TEST_DARK_INTENSITY);
-        kbd2.setDarkIntensity(0f);
-
-        // Update icon returns the drawable intensity to half
-        doReturn(kbd1).when(button).getNewDrawable(anyInt(), anyInt());
-        button.updateIcon(0, 0);
-        assertEquals(TEST_DARK_INTENSITY, kbd1.getDarkIntensity(), DARK_INTENSITY_ERR);
-
-        // Return old dark intensity on new drawable after update icon
-        doReturn(kbd2).when(button).getNewDrawable(anyInt(), anyInt());
-        button.updateIcon(0, 0);
-        assertEquals(TEST_DARK_INTENSITY, kbd2.getDarkIntensity(), DARK_INTENSITY_ERR);
-    }
-
-    private void showButton(ContextualButton button) {
-        assertEquals(View.VISIBLE, mGroup.setButtonVisibility(button.getId(), true /* visible */));
-        assertTrue("After set a button visible, group should also be visible", mGroup.isVisible());
-        assertEquals(button, mGroup.getVisibleContextButton());
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java
deleted file mode 100644
index 6a3c615..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/buttons/NearestTouchFrameTest.java
+++ /dev/null
@@ -1,279 +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.navigationbar.buttons;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
-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.content.Context;
-import android.content.res.Configuration;
-import android.graphics.Rect;
-import android.testing.TestableLooper.RunWithLooper;
-import android.view.MotionEvent;
-import android.view.View;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Map;
-
-@RunWith(AndroidJUnit4.class)
-@RunWithLooper
-@SmallTest
-public class NearestTouchFrameTest extends SysuiTestCase {
-
-    @Mock
-    EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory;
-    @Mock
-    EdgeBackGestureHandler mEdgeBackGestureHandler;
-    private NearestTouchFrame mNearestTouchFrame;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-
-        when(mEdgeBackGestureHandlerFactory.create(any(Context.class)))
-                .thenReturn(mEdgeBackGestureHandler);
-
-        mDependency.injectTestDependency(EdgeBackGestureHandler.Factory.class,
-                mEdgeBackGestureHandlerFactory);
-        Configuration c = new Configuration(mContext.getResources().getConfiguration());
-        c.smallestScreenWidthDp = 500;
-        mNearestTouchFrame = new NearestTouchFrame(mContext, null, c);
-        mNearestTouchFrame.layout(0, 0, 100, 100);
-    }
-
-    @Test
-    public void testNoActionOnLargeDevices() {
-        Configuration c = new Configuration(mContext.getResources().getConfiguration());
-        c.smallestScreenWidthDp = 700;
-        mNearestTouchFrame = new NearestTouchFrame(mContext, null, c);
-
-        View left = mockViewAt(0, 0, 10, 10);
-        View right = mockViewAt(20, 0, 10, 10);
-
-        mNearestTouchFrame.addView(left);
-        mNearestTouchFrame.addView(right);
-        mNearestTouchFrame.layout(0, 0, 30, 30);
-
-        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
-                12 /* x */, 5 /* y */, 0);
-        mNearestTouchFrame.onTouchEvent(ev);
-        verify(left, never()).onTouchEvent(eq(ev));
-        ev.recycle();
-    }
-
-    @Test
-    public void testInvisibleViews() {
-        View left = mockViewAt(0, 0, 10, 10);
-        View right = mockViewAt(20, 0, 10, 10);
-        when(left.getVisibility()).thenReturn(View.INVISIBLE);
-
-        mNearestTouchFrame.addView(left);
-        mNearestTouchFrame.addView(right);
-        mNearestTouchFrame.layout(0, 0, 30, 30);
-
-        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
-                12 /* x */, 5 /* y */, 0);
-        mNearestTouchFrame.onTouchEvent(ev);
-        verify(left, never()).onTouchEvent(eq(ev));
-        verify(right, never()).onTouchEvent(eq(ev));
-        ev.recycle();
-    }
-
-
-    @Test
-    public void testNearestView_DetachedViewsExcluded() {
-        View left = mockViewAt(0, 0, 10, 10);
-        when(left.isAttachedToWindow()).thenReturn(false);
-        View right = mockViewAt(20, 0, 10, 10);
-
-        mNearestTouchFrame.addView(left);
-        mNearestTouchFrame.addView(right);
-        mNearestTouchFrame.layout(0, 0, 30, 30);
-
-        // Would go to left view if attached, but goes to right instead as left should be detached.
-        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
-                12 /* x */, 5 /* y */, 0);
-        mNearestTouchFrame.onTouchEvent(ev);
-        verify(right).onTouchEvent(eq(ev));
-        ev.recycle();
-    }
-
-    @Test
-    public void testHorizontalSelection_Left() {
-        View left = mockViewAt(0, 0, 10, 10);
-        View right = mockViewAt(20, 0, 10, 10);
-
-        mNearestTouchFrame.addView(left);
-        mNearestTouchFrame.addView(right);
-        mNearestTouchFrame.layout(0, 0, 30, 30);
-
-        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
-                12 /* x */, 5 /* y */, 0);
-        mNearestTouchFrame.onTouchEvent(ev);
-        verify(left).onTouchEvent(eq(ev));
-        ev.recycle();
-    }
-
-    @Test
-    public void testHorizontalSelection_Right() {
-        View left = mockViewAt(0, 0, 10, 10);
-        View right = mockViewAt(20, 0, 10, 10);
-
-        mNearestTouchFrame.addView(left);
-        mNearestTouchFrame.addView(right);
-        mNearestTouchFrame.layout(0, 0, 30, 30);
-
-        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
-                18 /* x */, 5 /* y */, 0);
-        mNearestTouchFrame.onTouchEvent(ev);
-        verify(right).onTouchEvent(eq(ev));
-        ev.recycle();
-    }
-
-    @Test
-    public void testVerticalSelection_Top() {
-        View top = mockViewAt(0, 0, 10, 10);
-        View bottom = mockViewAt(0, 20, 10, 10);
-        mNearestTouchFrame.setIsVertical(true);
-        mNearestTouchFrame.addView(top);
-        mNearestTouchFrame.addView(bottom);
-        mNearestTouchFrame.layout(0, 0, 30, 30);
-
-        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
-                5 /* x */, 12 /* y */, 0);
-        mNearestTouchFrame.onTouchEvent(ev);
-        verify(top).onTouchEvent(eq(ev));
-        ev.recycle();
-    }
-
-    @Test
-    public void testVerticalSelection_Bottom() {
-        View top = mockViewAt(0, 0, 10, 10);
-        View bottom = mockViewAt(0, 20, 10, 10);
-        mNearestTouchFrame.setIsVertical(true);
-        mNearestTouchFrame.addView(top);
-        mNearestTouchFrame.addView(bottom);
-        mNearestTouchFrame.layout(0, 0, 30, 30);
-
-        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
-                5 /* x */, 18 /* y */, 0);
-        mNearestTouchFrame.onTouchEvent(ev);
-        verify(bottom).onTouchEvent(eq(ev));
-        ev.recycle();
-    }
-
-    @Test
-    public void testViewNotAttachedNoCrash() {
-        View view = mockViewAt(0, 20, 10, 10);
-        when(view.isAttachedToWindow()).thenReturn(false);
-        mNearestTouchFrame.addView(view);
-        mNearestTouchFrame.layout(0, 0, 30, 30);
-
-        MotionEvent ev = MotionEvent.obtain(0, 0, 0, 5 /* x */, 18 /* y */, 0);
-        mNearestTouchFrame.onTouchEvent(ev);
-        verify(view, never()).onTouchEvent(eq(ev));
-        ev.recycle();
-    }
-
-    @Test
-    public void testViewMiddleChildNotAttachedCrash() {
-        View view1 = mockViewAt(0, 20, 10, 10);
-        View view2 = mockViewAt(11, 20, 10, 10);
-        View view3 = mockViewAt(21, 20, 10, 10);
-        when(view2.isAttachedToWindow()).thenReturn(false);
-        mNearestTouchFrame.addView(view1);
-        mNearestTouchFrame.addView(view2);
-        mNearestTouchFrame.addView(view3);
-        mNearestTouchFrame.layout(0, 0, 30, 30);
-
-        MotionEvent ev = MotionEvent.obtain(0, 0, 0, 5 /* x */, 18 /* y */, 0);
-        mNearestTouchFrame.onTouchEvent(ev);
-        verify(view2, never()).onTouchEvent(eq(ev));
-        ev.recycle();
-    }
-
-    @Test
-    public void testCachedRegionsSplit_horizontal() {
-        View left = mockViewAt(0, 0, 5, 20);
-        View right = mockViewAt(15, 0, 5, 20);
-        mNearestTouchFrame.addView(left);
-        mNearestTouchFrame.addView(right);
-        mNearestTouchFrame.layout(0, 0, 20, 20);
-
-        Map<View, Rect> childRegions = mNearestTouchFrame.getFullTouchableChildRegions();
-        assertEquals(2, childRegions.size());
-        Rect leftRegion = childRegions.get(left);
-        Rect rightRegion = childRegions.get(right);
-        assertEquals(new Rect(0, 0, 9, 20), leftRegion);
-        assertEquals(new Rect(10, 0, 20, 20), rightRegion);
-    }
-
-    @Test
-    public void testCachedRegionsSplit_vertical() {
-        View top = mockViewAt(0, 0, 20, 5);
-        View bottom = mockViewAt(0, 15, 20, 5);
-        mNearestTouchFrame.addView(top);
-        mNearestTouchFrame.addView(bottom);
-        mNearestTouchFrame.setIsVertical(true);
-        mNearestTouchFrame.layout(0, 0, 20, 20);
-
-        Map<View, Rect> childRegions = mNearestTouchFrame.getFullTouchableChildRegions();
-        assertEquals(2, childRegions.size());
-        Rect topRegion = childRegions.get(top);
-        Rect bottomRegion = childRegions.get(bottom);
-        assertEquals(new Rect(0, 0, 20, 9), topRegion);
-        assertEquals(new Rect(0, 10, 20, 20), bottomRegion);
-    }
-
-    private View mockViewAt(int x, int y, int width, int height) {
-        View v = spy(new View(mContext));
-        doAnswer(invocation -> {
-            int[] pos = (int[]) invocation.getArguments()[0];
-            pos[0] = x;
-            pos[1] = y;
-            return null;
-        }).when(v).getLocationInWindow(any());
-        when(v.isClickable()).thenReturn(true);
-        when(v.isAttachedToWindow()).thenReturn(true);
-        when(v.getWidth()).thenReturn(width);
-        when(v.getHeight()).thenReturn(height);
-
-        // Stupid final methods.
-        v.setLeft(0);
-        v.setRight(width);
-        v.setTop(0);
-        v.setBottom(height);
-        return v;
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarButtonTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarButtonTest.java
new file mode 100644
index 0000000..00e79f5
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarButtonTest.java
@@ -0,0 +1,153 @@
+/*
+ * 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.navigationbar.views;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.VirtualDisplay;
+import android.media.ImageReader;
+import android.os.SystemClock;
+import android.testing.TestableLooper.RunWithLooper;
+import android.util.Log;
+import android.view.Display;
+import android.view.DisplayInfo;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.SysuiTestableContext;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.navigationbar.NavigationBarController;
+import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
+import com.android.systemui.recents.OverviewProxyService;
+import com.android.systemui.settings.FakeDisplayTracker;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+
+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.function.Predicate;
+
+/** atest NavigationBarButtonTest */
+@RunWith(AndroidJUnit4.class)
+@RunWithLooper
+@SmallTest
+public class NavigationBarButtonTest extends SysuiTestCase {
+
+    @Mock
+    EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory;
+    @Mock
+    EdgeBackGestureHandler mEdgeBackGestureHandler;
+    private static final String TAG = "NavigationBarButtonTest";
+    private ImageReader mReader;
+    private NavigationBarView mNavBar;
+    private VirtualDisplay mVirtualDisplay;
+    private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        final Display display = createVirtualDisplay();
+        final SysuiTestableContext context =
+                (SysuiTestableContext) mContext.createDisplayContext(display);
+
+        when(mEdgeBackGestureHandlerFactory.create(any(Context.class)))
+                .thenReturn(mEdgeBackGestureHandler);
+
+        mDependency.injectMockDependency(AssistManager.class);
+        mDependency.injectMockDependency(OverviewProxyService.class);
+        mDependency.injectMockDependency(KeyguardStateController.class);
+        mDependency.injectMockDependency(NavigationBarController.class);
+        mDependency.injectTestDependency(EdgeBackGestureHandler.Factory.class,
+                mEdgeBackGestureHandlerFactory);
+        mNavBar = new NavigationBarView(context, null);
+        mNavBar.setDisplayTracker(mDisplayTracker);
+    }
+
+    private Display createVirtualDisplay() {
+        final String displayName = "NavVirtualDisplay";
+        final DisplayInfo displayInfo = new DisplayInfo();
+        mContext.getDisplay().getDisplayInfo(displayInfo);
+
+        final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
+
+        mReader = ImageReader.newInstance(displayInfo.logicalWidth,
+                displayInfo.logicalHeight, PixelFormat.RGBA_8888, 2);
+
+        assertNotNull("ImageReader must not be null", mReader);
+
+        mVirtualDisplay = displayManager.createVirtualDisplay(displayName, displayInfo.logicalWidth,
+                displayInfo.logicalHeight, displayInfo.logicalDensityDpi, mReader.getSurface(),
+                0 /*flags*/);
+
+        assertNotNull("virtual display must not be null", mVirtualDisplay);
+
+        waitForDisplayReady(mVirtualDisplay.getDisplay().getDisplayId());
+
+        return mVirtualDisplay.getDisplay();
+    }
+
+    private void waitForDisplayReady(int displayId) {
+        waitForDisplayCondition(displayId, state -> state);
+    }
+
+    private void waitForDisplayCondition(int displayId, Predicate<Boolean> condition) {
+        for (int retry = 1; retry <= 10; retry++) {
+            if (condition.test(isDisplayOn(displayId))) {
+                return;
+            }
+            Log.i(TAG, "Waiting for virtual display ready ... retry = " + retry);
+            SystemClock.sleep(500);
+        }
+    }
+
+    private boolean isDisplayOn(int displayId) {
+        DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
+        Display display = displayManager.getDisplay(displayId);
+        return display != null && display.getState() == Display.STATE_ON;
+    }
+
+    @After
+    public void tearDown() {
+        releaseDisplay();
+    }
+
+    private void releaseDisplay() {
+        mVirtualDisplay.release();
+        mReader.close();
+    }
+
+    @Test
+    public void testRecentsButtonDisabledOnSecondaryDisplay() {
+        assertTrue("The recents button must be disabled",
+                mNavBar.isRecentsButtonDisabled());
+    }
+}
+
+
+
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarInflaterViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarInflaterViewTest.java
new file mode 100644
index 0000000..e58c8f2
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarInflaterViewTest.java
@@ -0,0 +1,113 @@
+/*
+ * 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.navigationbar.views;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+
+import android.testing.TestableLooper.RunWithLooper;
+import android.util.SparseArray;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.navigationbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.navigationbar.views.buttons.ButtonDispatcher;
+import com.android.systemui.recents.OverviewProxyService;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** atest NavigationBarInflaterViewTest */
+@RunWith(AndroidJUnit4.class)
+@RunWithLooper
+@SmallTest
+public class NavigationBarInflaterViewTest extends SysuiTestCase {
+
+    private NavigationBarInflaterView mNavBarInflaterView;
+
+    private static final int BUTTON_ID = 0;
+
+    @Before
+    public void setUp() {
+        mDependency.injectMockDependency(AssistManager.class);
+        mDependency.injectMockDependency(OverviewProxyService.class);
+        mDependency.injectMockDependency(NavigationModeController.class);
+        mDependency.injectMockDependency(NavigationBarController.class);
+
+        mNavBarInflaterView = spy(new NavigationBarInflaterView(mContext, null));
+        doNothing().when(mNavBarInflaterView).createInflaters();
+
+        mNavBarInflaterView.mButtonDispatchers = new SparseArray<>(1);
+        mNavBarInflaterView.mButtonDispatchers.put(BUTTON_ID, new ButtonDispatcher(BUTTON_ID));
+
+        initializeViews();
+    }
+
+    private void initializeViews() {
+        mNavBarInflaterView.mVertical = mock(FrameLayout.class);
+        mNavBarInflaterView.mHorizontal = mock(FrameLayout.class);
+        initializeLayout(mNavBarInflaterView.mVertical);
+        initializeLayout(mNavBarInflaterView.mHorizontal);
+    }
+
+    private void initializeLayout(FrameLayout layout) {
+        View verticalChildView = mock(View.class);
+        verticalChildView.setId(BUTTON_ID);
+        doReturn(layout).when(verticalChildView).getParent();
+        doReturn(verticalChildView).when(layout).findViewById(BUTTON_ID);
+    }
+
+    @After
+    public void tearDown() {
+        mNavBarInflaterView = null;
+    }
+
+    @Test
+    public void testUpdateButtonDispatchersCurrentView_isVerticalTrue() {
+        mNavBarInflaterView.setVertical(true);
+
+        mNavBarInflaterView.updateButtonDispatchersCurrentView();
+
+        ButtonDispatcher button = mNavBarInflaterView.mButtonDispatchers.get(BUTTON_ID);
+        assertEquals("Buttons need to be set to vertical layout",
+                mNavBarInflaterView.mVertical.getId(),
+                ((View) button.getCurrentView().getParent()).getId());
+    }
+
+    @Test
+    public void testUpdateButtonDispatchersCurrentView_isVerticalFalse() {
+        mNavBarInflaterView.setVertical(false);
+
+        mNavBarInflaterView.updateButtonDispatchersCurrentView();
+
+        ButtonDispatcher button = mNavBarInflaterView.mButtonDispatchers.get(BUTTON_ID);
+        assertEquals("Buttons need to be set to horizon layout",
+                mNavBarInflaterView.mHorizontal.getId(),
+                ((View) button.getCurrentView().getParent()).getId());
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java
new file mode 100644
index 0000000..98ff6c9
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarTest.java
@@ -0,0 +1,623 @@
+/*
+ * 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.navigationbar.views;
+
+import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
+import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
+import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SWITCHER_SHOWN;
+import static android.inputmethodservice.InputMethodService.BACK_DISPOSITION_DEFAULT;
+import static android.inputmethodservice.InputMethodService.IME_INVISIBLE;
+import static android.inputmethodservice.InputMethodService.IME_VISIBLE;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
+import static android.view.WindowInsets.Type.ime;
+
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.HOME_BUTTON_LONG_PRESS_DURATION_MS;
+import static com.android.systemui.assist.AssistManager.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS;
+import static com.android.systemui.navigationbar.views.NavigationBar.NavBarActionEvent.NAVBAR_ASSIST_LONGPRESS;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+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;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.res.Resources;
+import android.hardware.display.DisplayManagerGlobal;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.provider.DeviceConfig;
+import android.telecom.TelecomManager;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.Display;
+import android.view.DisplayInfo;
+import android.view.IWindowManager;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewRootImpl;
+import android.view.ViewTreeObserver;
+import android.view.WindowInsets;
+import android.view.WindowManager;
+import android.view.WindowMetrics;
+import android.view.accessibility.AccessibilityManager;
+import android.view.inputmethod.InputMethodManager;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.SysuiTestableContext;
+import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
+import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver;
+import com.android.systemui.accessibility.SystemActions;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.dump.DumpManager;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.model.SysUiState;
+import com.android.systemui.navigationbar.NavBarHelper;
+import com.android.systemui.navigationbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
+import com.android.systemui.navigationbar.views.buttons.ButtonDispatcher;
+import com.android.systemui.navigationbar.views.buttons.DeadZone;
+import com.android.systemui.navigationbar.views.buttons.KeyButtonView;
+import com.android.systemui.navigationbar.views.buttons.NavBarButtonClickLogger;
+import com.android.systemui.navigationbar.views.buttons.NavbarOrientationTrackingLogger;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.recents.OverviewProxyService;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.settings.DisplayTracker;
+import com.android.systemui.settings.FakeDisplayTracker;
+import com.android.systemui.settings.UserContextProvider;
+import com.android.systemui.settings.UserTracker;
+import com.android.systemui.shade.NotificationShadeWindowView;
+import com.android.systemui.shade.ShadeViewController;
+import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor;
+import com.android.systemui.shared.rotation.RotationButtonController;
+import com.android.systemui.shared.system.TaskStackChangeListeners;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationShadeDepthController;
+import com.android.systemui.statusbar.NotificationShadeWindowController;
+import com.android.systemui.statusbar.phone.AutoHideController;
+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.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.DeviceConfigProxyFake;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
+import com.android.systemui.utils.leaks.LeakCheckedTest;
+import com.android.wm.shell.back.BackAnimation;
+import com.android.wm.shell.pip.Pip;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Optional;
+import java.util.concurrent.Executor;
+
+@RunWith(AndroidJUnit4.class)
+@RunWithLooper(setAsMainLooper = true)
+@SmallTest
+public class NavigationBarTest extends SysuiTestCase {
+    private static final int EXTERNAL_DISPLAY_ID = 2;
+
+    private NavigationBar mNavigationBar;
+    private NavigationBar mExternalDisplayNavigationBar;
+
+    private SysuiTestableContext mSysuiTestableContextExternal;
+    @Mock
+    NavigationBarView mNavigationBarView;
+    @Mock
+    NavigationBarFrame mNavigationBarFrame;
+    @Mock
+    ButtonDispatcher mHomeButton;
+    @Mock
+    KeyButtonView mHomeButtonView;
+    @Mock
+    ButtonDispatcher mRecentsButton;
+    @Mock
+    ButtonDispatcher mAccessibilityButton;
+    @Mock
+    ButtonDispatcher mImeSwitchButton;
+    @Mock
+    ButtonDispatcher mBackButton;
+    @Mock
+    NavigationBarTransitions mNavigationBarTransitions;
+    @Mock
+    RotationButtonController mRotationButtonController;
+    @Mock
+    LightBarTransitionsController mLightBarTransitionsController;
+    @Mock
+    private SystemActions mSystemActions;
+    @Mock
+    private OverviewProxyService mOverviewProxyService;
+    @Mock
+    private StatusBarStateController mStatusBarStateController;
+    @Mock
+    private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    @Mock
+    private NavigationModeController mNavigationModeController;
+    @Mock
+    private CommandQueue mCommandQueue;
+    private SysUiState mMockSysUiState;
+    @Mock
+    private Handler mHandler;
+
+    @Mock
+    private Handler mBgHandler;
+    @Mock
+    private UserTracker mUserTracker;
+    @Mock
+    private UiEventLogger mUiEventLogger;
+    @Mock
+    private NavBarButtonClickLogger mNavBarButtonClickLogger;
+    @Mock
+    private NavbarOrientationTrackingLogger mNavbarOrientationTrackingLogger;
+    @Mock
+    private ViewTreeObserver mViewTreeObserver;
+    NavBarHelper mNavBarHelper;
+    @Mock
+    private LightBarController mLightBarController;
+    @Mock
+    private LightBarController.Factory mLightBarcontrollerFactory;
+    @Mock
+    private AutoHideController mAutoHideController;
+    @Mock
+    private AutoHideController.Factory mAutoHideControllerFactory;
+    @Mock
+    private WindowManager mWindowManager;
+    @Mock
+    private TelecomManager mTelecomManager;
+    @Mock
+    private InputMethodManager mInputMethodManager;
+    @Mock
+    private AssistManager mAssistManager;
+    @Mock
+    private DeadZone mDeadZone;
+    @Mock
+    private CentralSurfaces mCentralSurfaces;
+    @Mock
+    private KeyguardStateController mKeyguardStateController;
+    @Mock
+    private UserContextProvider mUserContextProvider;
+    @Mock
+    private WakefulnessLifecycle mWakefulnessLifecycle;
+    @Mock
+    private Resources mResources;
+    @Mock
+    private ViewRootImpl mViewRootImpl;
+    @Mock
+    private EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory;
+    @Mock
+    private EdgeBackGestureHandler mEdgeBackGestureHandler;
+    @Mock
+    private NotificationShadeWindowController mNotificationShadeWindowController;
+    private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
+    private DeviceConfigProxyFake mDeviceConfigProxyFake = new DeviceConfigProxyFake();
+    private TaskStackChangeListeners mTaskStackChangeListeners =
+            TaskStackChangeListeners.getTestInstance();
+
+    @Rule
+    public final LeakCheckedTest.SysuiLeakCheck mLeakCheck = new LeakCheckedTest.SysuiLeakCheck();
+
+    private final Executor mSynchronousExecutor = runnable -> runnable.run();
+
+    @Before
+    public void setup() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        when(mLightBarcontrollerFactory.create(any(Context.class))).thenReturn(mLightBarController);
+        when(mAutoHideControllerFactory.create(any(Context.class))).thenReturn(mAutoHideController);
+        when(mNavigationBarView.getHomeButton()).thenReturn(mHomeButton);
+        when(mNavigationBarView.getRecentsButton()).thenReturn(mRecentsButton);
+        when(mNavigationBarView.getAccessibilityButton()).thenReturn(mAccessibilityButton);
+        when(mNavigationBarView.getImeSwitchButton()).thenReturn(mImeSwitchButton);
+        when(mNavigationBarView.getBackButton()).thenReturn(mBackButton);
+        when(mNavigationBarView.getRotationButtonController())
+                .thenReturn(mRotationButtonController);
+        when(mNavigationBarTransitions.getLightTransitionsController())
+                .thenReturn(mLightBarTransitionsController);
+        when(mStatusBarKeyguardViewManager.isNavBarVisible()).thenReturn(true);
+        when(mNavigationBarView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
+        when(mUserContextProvider.createCurrentUserContext(any(Context.class)))
+                .thenReturn(mContext);
+        when(mNavigationBarView.getResources()).thenReturn(mResources);
+        when(mNavigationBarView.getViewRootImpl()).thenReturn(mViewRootImpl);
+        when(mEdgeBackGestureHandlerFactory.create(any())).thenReturn(mEdgeBackGestureHandler);
+        setupSysuiDependency();
+        // This class inflates views that call Dependency.get, thus these injections are still
+        // necessary.
+        mDependency.injectTestDependency(AssistManager.class, mAssistManager);
+        mDependency.injectMockDependency(KeyguardStateController.class);
+        mDependency.injectTestDependency(StatusBarStateController.class, mStatusBarStateController);
+        mDependency.injectMockDependency(NavigationBarController.class);
+        mDependency.injectTestDependency(OverviewProxyService.class, mOverviewProxyService);
+        mDependency.injectTestDependency(NavigationModeController.class, mNavigationModeController);
+        TestableLooper.get(this).runWithLooper(() -> {
+            mNavBarHelper = spy(new NavBarHelper(mContext, mock(AccessibilityManager.class),
+                    mock(AccessibilityButtonModeObserver.class),
+                    mock(AccessibilityButtonTargetsObserver.class),
+                    mSystemActions, mOverviewProxyService,
+                    () -> mock(AssistManager.class), () -> Optional.of(mCentralSurfaces),
+                    mKeyguardStateController, mock(NavigationModeController.class),
+                    mEdgeBackGestureHandlerFactory, mock(IWindowManager.class),
+                    mock(UserTracker.class), mock(DisplayTracker.class),
+                    mNotificationShadeWindowController, mock(ConfigurationController.class),
+                    mock(DumpManager.class), mock(CommandQueue.class), mSynchronousExecutor,
+                    mBgHandler));
+            mNavigationBar = createNavBar(mContext);
+            mExternalDisplayNavigationBar = createNavBar(mSysuiTestableContextExternal);
+        });
+    }
+
+    private void setupSysuiDependency() {
+        Display display = new Display(DisplayManagerGlobal.getInstance(), EXTERNAL_DISPLAY_ID,
+                new DisplayInfo(), DEFAULT_DISPLAY_ADJUSTMENTS);
+        mSysuiTestableContextExternal = (SysuiTestableContext) getContext().createDisplayContext(
+                display);
+
+        Display defaultDisplay = mContext.getDisplay();
+        when(mWindowManager.getDefaultDisplay()).thenReturn(defaultDisplay);
+        WindowMetrics metrics = mContext.getSystemService(WindowManager.class)
+                .getMaximumWindowMetrics();
+        when(mWindowManager.getMaximumWindowMetrics()).thenReturn(metrics);
+        WindowMetrics currentWindowMetrics = mContext.getSystemService(WindowManager.class)
+                .getCurrentWindowMetrics();
+        when(mWindowManager.getCurrentWindowMetrics()).thenReturn(currentWindowMetrics);
+        doNothing().when(mWindowManager).addView(any(), any());
+        doNothing().when(mWindowManager).removeViewImmediate(any());
+        mMockSysUiState = mock(SysUiState.class);
+        when(mMockSysUiState.setFlag(anyLong(), anyBoolean())).thenReturn(mMockSysUiState);
+
+        mContext.addMockSystemService(WindowManager.class, mWindowManager);
+        mSysuiTestableContextExternal.addMockSystemService(WindowManager.class, mWindowManager);
+    }
+
+    @Test
+    public void testHomeLongPress() {
+        when(mAssistManager.shouldOverrideAssist(INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS))
+                .thenReturn(false);
+
+        mNavigationBar.init();
+        mNavigationBar.onViewAttached();
+        mNavigationBar.onHomeLongClick(mHomeButtonView);
+
+        verify(mUiEventLogger, times(1)).log(NAVBAR_ASSIST_LONGPRESS);
+        verify(mAssistManager).startAssist(any());
+    }
+
+    @Test
+    public void testHomeLongPressOverride() {
+        when(mAssistManager.shouldOverrideAssist(INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS))
+                .thenReturn(true);
+
+        mNavigationBar.init();
+        mNavigationBar.onViewAttached();
+        mNavigationBar.onHomeLongClick(mHomeButtonView);
+
+        verify(mUiEventLogger, times(1)).log(NAVBAR_ASSIST_LONGPRESS);
+
+        ArgumentCaptor<Runnable> onRippleInvisibleRunnableCaptor = ArgumentCaptor.forClass(
+                Runnable.class);
+        // startAssist is not called initially
+        verify(mAssistManager, never()).startAssist(any());
+        // but a Runnable is added for when the ripple is invisible
+        verify(mHomeButtonView).setOnRippleInvisibleRunnable(
+                onRippleInvisibleRunnableCaptor.capture());
+        // and when that runs, startAssist is called
+        onRippleInvisibleRunnableCaptor.getValue().run();
+        verify(mAssistManager).startAssist(any());
+    }
+
+    @Test
+    public void testHomeLongPressWithCustomDuration() throws Exception {
+        mDeviceConfigProxyFake.setProperty(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                HOME_BUTTON_LONG_PRESS_DURATION_MS,
+                "100",
+                false);
+        when(mNavBarHelper.getLongPressHomeEnabled()).thenReturn(true);
+        mNavigationBar.init();
+        mNavigationBar.onViewAttached();
+
+        mNavigationBar.onHomeTouch(mNavigationBar.getView(), MotionEvent.obtain(
+                /*downTime=*/SystemClock.uptimeMillis(),
+                /*eventTime=*/SystemClock.uptimeMillis(),
+                /*action=*/MotionEvent.ACTION_DOWN,
+                0, 0, 0
+        ));
+        verify(mHandler, times(1)).postDelayed(any(), eq(100L));
+
+        mNavigationBar.onHomeTouch(mNavigationBar.getView(), MotionEvent.obtain(
+                /*downTime=*/SystemClock.uptimeMillis(),
+                /*eventTime=*/SystemClock.uptimeMillis(),
+                /*action=*/MotionEvent.ACTION_UP,
+                0, 0, 0
+        ));
+
+        verify(mHandler, times(1)).removeCallbacks(any());
+    }
+
+    @Test
+    public void onHomeTouch_isRinging_keyguardShowing_touchBlocked() {
+        when(mTelecomManager.isRinging()).thenReturn(true);
+        when(mKeyguardStateController.isShowing()).thenReturn(true);
+
+        boolean result = mNavigationBar.onHomeTouch(
+                mNavigationBar.getView(),
+                    MotionEvent.obtain(
+                    /*downTime=*/SystemClock.uptimeMillis(),
+                    /*eventTime=*/SystemClock.uptimeMillis(),
+                    /*action=*/MotionEvent.ACTION_DOWN,
+                    0, 0, 0));
+
+        assertThat(result).isTrue();
+
+        // Verify subsequent touches are also blocked
+        boolean nextTouchEvent = mNavigationBar.onHomeTouch(
+                mNavigationBar.getView(),
+                MotionEvent.obtain(
+                        /*downTime=*/SystemClock.uptimeMillis(),
+                        /*eventTime=*/SystemClock.uptimeMillis(),
+                        /*action=*/MotionEvent.ACTION_MOVE,
+                        0, 0, 0));
+        assertThat(nextTouchEvent).isTrue();
+    }
+
+    @Test
+    public void onHomeTouch_isRinging_keyguardNotShowing_touchNotBlocked() {
+        when(mTelecomManager.isRinging()).thenReturn(true);
+        when(mKeyguardStateController.isShowing()).thenReturn(false);
+
+        boolean result = mNavigationBar.onHomeTouch(
+                mNavigationBar.getView(),
+                MotionEvent.obtain(
+                        /*downTime=*/SystemClock.uptimeMillis(),
+                        /*eventTime=*/SystemClock.uptimeMillis(),
+                        /*action=*/MotionEvent.ACTION_DOWN,
+                        0, 0, 0));
+
+        assertThat(result).isFalse();
+
+        // Verify subsequent touches are also not blocked
+        boolean nextTouchEvent = mNavigationBar.onHomeTouch(
+                mNavigationBar.getView(),
+                MotionEvent.obtain(
+                        /*downTime=*/SystemClock.uptimeMillis(),
+                        /*eventTime=*/SystemClock.uptimeMillis(),
+                        /*action=*/MotionEvent.ACTION_MOVE,
+                        0, 0, 0));
+        assertThat(nextTouchEvent).isFalse();
+    }
+
+    @Test
+    public void testRegisteredWithUserTracker() {
+        mNavigationBar.init();
+        mNavigationBar.onViewAttached();
+        verify(mUserTracker).addCallback(any(UserTracker.Callback.class), any(Executor.class));
+    }
+
+    @Test
+    public void testSetImeWindowStatusWhenImeSwitchOnDisplay() {
+        // Create default & external NavBar fragment.
+        NavigationBar defaultNavBar = mNavigationBar;
+        NavigationBar externalNavBar = mExternalDisplayNavigationBar;
+        NotificationShadeWindowView mockShadeWindowView = mock(NotificationShadeWindowView.class);
+        WindowInsets windowInsets = new WindowInsets.Builder().setVisible(ime(), false).build();
+        doReturn(windowInsets).when(mockShadeWindowView).getRootWindowInsets();
+        doReturn(true).when(mockShadeWindowView).isAttachedToWindow();
+        doNothing().when(defaultNavBar).checkNavBarModes();
+        doNothing().when(externalNavBar).checkNavBarModes();
+        defaultNavBar.init();
+        externalNavBar.init();
+
+        defaultNavBar.setImeWindowStatus(DEFAULT_DISPLAY, null, IME_VISIBLE,
+                BACK_DISPOSITION_DEFAULT, true);
+
+        // Verify IME window state will be updated in default NavBar & external NavBar state reset.
+        assertEquals(NAVIGATION_HINT_BACK_ALT | NAVIGATION_HINT_IME_SHOWN
+                        | NAVIGATION_HINT_IME_SWITCHER_SHOWN,
+                defaultNavBar.getNavigationIconHints());
+        assertFalse((externalNavBar.getNavigationIconHints() & NAVIGATION_HINT_BACK_ALT) != 0);
+        assertFalse((externalNavBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SHOWN) != 0);
+        assertFalse((externalNavBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SWITCHER_SHOWN)
+                != 0);
+
+        externalNavBar.setImeWindowStatus(EXTERNAL_DISPLAY_ID, null, IME_VISIBLE,
+                BACK_DISPOSITION_DEFAULT, true);
+        defaultNavBar.setImeWindowStatus(
+                DEFAULT_DISPLAY, null, IME_INVISIBLE, BACK_DISPOSITION_DEFAULT, false);
+        // Verify IME window state will be updated in external NavBar & default NavBar state reset.
+        assertEquals(NAVIGATION_HINT_BACK_ALT | NAVIGATION_HINT_IME_SHOWN
+                        | NAVIGATION_HINT_IME_SWITCHER_SHOWN,
+                externalNavBar.getNavigationIconHints());
+        assertFalse((defaultNavBar.getNavigationIconHints() & NAVIGATION_HINT_BACK_ALT) != 0);
+        assertFalse((defaultNavBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SHOWN) != 0);
+        assertFalse((defaultNavBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SWITCHER_SHOWN)
+                != 0);
+    }
+
+    @Test
+    public void testSetImeWindowStatusWhenKeyguardLockingAndImeInsetsChange() {
+        NotificationShadeWindowView mockShadeWindowView = mock(NotificationShadeWindowView.class);
+        doReturn(mockShadeWindowView).when(mNotificationShadeWindowController).getWindowRootView();
+        doReturn(true).when(mockShadeWindowView).isAttachedToWindow();
+        doNothing().when(mNavigationBar).checkNavBarModes();
+        mNavigationBar.init();
+        WindowInsets windowInsets = new WindowInsets.Builder().setVisible(ime(), false).build();
+        doReturn(windowInsets).when(mockShadeWindowView).getRootWindowInsets();
+
+        // Verify navbar altered back icon when an app is showing IME
+        mNavigationBar.setImeWindowStatus(DEFAULT_DISPLAY, null, IME_VISIBLE,
+                BACK_DISPOSITION_DEFAULT, true);
+        assertTrue((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_BACK_ALT) != 0);
+        assertTrue((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SHOWN) != 0);
+        assertTrue((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SWITCHER_SHOWN)
+                != 0);
+
+        // Verify navbar didn't alter and showing back icon when the keyguard is showing without
+        // requesting IME insets visible.
+        doReturn(true).when(mKeyguardStateController).isShowing();
+        mNavigationBar.setImeWindowStatus(DEFAULT_DISPLAY, null, IME_VISIBLE,
+                BACK_DISPOSITION_DEFAULT, true);
+        assertFalse((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_BACK_ALT) != 0);
+        assertFalse((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SHOWN) != 0);
+        assertFalse((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SWITCHER_SHOWN)
+                != 0);
+
+        // Verify navbar altered and showing back icon when the keyguard is showing and
+        // requesting IME insets visible.
+        windowInsets = new WindowInsets.Builder().setVisible(ime(), true).build();
+        doReturn(windowInsets).when(mockShadeWindowView).getRootWindowInsets();
+        mNavigationBar.setImeWindowStatus(DEFAULT_DISPLAY, null, IME_VISIBLE,
+                BACK_DISPOSITION_DEFAULT, true);
+        assertTrue((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_BACK_ALT) != 0);
+        assertTrue((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SHOWN) != 0);
+        assertTrue((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_IME_SWITCHER_SHOWN)
+                != 0);
+    }
+
+    @Test
+    public void testA11yEventAfterDetach() {
+        mNavigationBar.init();
+        mNavigationBar.onViewAttached();
+        verify(mNavBarHelper).registerNavTaskStateUpdater(any(
+                NavBarHelper.NavbarTaskbarStateUpdater.class));
+        mNavigationBar.onViewDetached();
+        verify(mNavBarHelper).removeNavTaskStateUpdater(any(
+                NavBarHelper.NavbarTaskbarStateUpdater.class));
+
+        // Should be safe even though the internal view is now null.
+        mNavigationBar.updateAccessibilityStateFlags();
+    }
+
+    @Test
+    public void testCreateView_initiallyVisible_viewIsVisible() {
+        when(mStatusBarKeyguardViewManager.isNavBarVisible()).thenReturn(true);
+        mNavigationBar.init();
+        mNavigationBar.onViewAttached();
+
+        verify(mNavigationBarView).setVisibility(View.VISIBLE);
+    }
+
+    @Test
+    public void testCreateView_initiallyNotVisible_viewIsNotVisible() {
+        when(mStatusBarKeyguardViewManager.isNavBarVisible()).thenReturn(false);
+        mNavigationBar.init();
+        mNavigationBar.onViewAttached();
+
+        verify(mNavigationBarView).setVisibility(View.INVISIBLE);
+    }
+
+    @Test
+    public void testOnInit_readCurrentSysuiState() {
+        mNavigationBar.init();
+        verify(mNavBarHelper, times(1)).getCurrentSysuiState();
+    }
+
+    @Test
+    public void testScreenPinningEnabled_updatesSysuiState() {
+        mNavigationBar.init();
+        mTaskStackChangeListeners.getListenerImpl().onLockTaskModeChanged(
+                ActivityManager.LOCK_TASK_MODE_PINNED);
+        verify(mMockSysUiState).setFlag(eq(SYSUI_STATE_SCREEN_PINNING), eq(true));
+    }
+
+    private NavigationBar createNavBar(Context context) {
+        DeviceProvisionedController deviceProvisionedController =
+                mock(DeviceProvisionedController.class);
+        when(deviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
+        return spy(new NavigationBar(
+                mNavigationBarView,
+                mNavigationBarFrame,
+                null,
+                context,
+                mWindowManager,
+                () -> mAssistManager,
+                mock(AccessibilityManager.class),
+                deviceProvisionedController,
+                new MetricsLogger(),
+                mOverviewProxyService,
+                mNavigationModeController,
+                mStatusBarStateController,
+                mStatusBarKeyguardViewManager,
+                mMockSysUiState,
+                mUserTracker,
+                mCommandQueue,
+                Optional.of(mock(Pip.class)),
+                Optional.of(mock(Recents.class)),
+                () -> Optional.of(mCentralSurfaces),
+                mKeyguardStateController,
+                mock(ShadeViewController.class),
+                mock(PanelExpansionInteractor.class),
+                mock(NotificationRemoteInputManager.class),
+                mock(NotificationShadeDepthController.class),
+                mHandler,
+                mFakeExecutor,
+                mFakeExecutor,
+                mUiEventLogger,
+                mNavBarHelper,
+                mLightBarController,
+                mLightBarcontrollerFactory,
+                mAutoHideController,
+                mAutoHideControllerFactory,
+                Optional.of(mTelecomManager),
+                mInputMethodManager,
+                mDeadZone,
+                mDeviceConfigProxyFake,
+                mNavigationBarTransitions,
+                Optional.of(mock(BackAnimation.class)),
+                mUserContextProvider,
+                mWakefulnessLifecycle,
+                mTaskStackChangeListeners,
+                new FakeDisplayTracker(mContext),
+                mNavBarButtonClickLogger,
+                mNavbarOrientationTrackingLogger));
+    }
+
+    private void processAllMessages() {
+        TestableLooper.get(this).processAllMessages();
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarTransitionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarTransitionsTest.java
new file mode 100644
index 0000000..b0265c0
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/NavigationBarTransitionsTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.navigationbar.views;
+
+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.when;
+
+import android.content.Context;
+import android.testing.TestableLooper.RunWithLooper;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.navigationbar.NavigationBarController;
+import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.recents.OverviewProxyService;
+import com.android.systemui.settings.FakeDisplayTracker;
+import com.android.systemui.shared.statusbar.phone.BarTransitions;
+import com.android.systemui.statusbar.phone.LightBarTransitionsController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+@RunWithLooper
+@SmallTest
+public class NavigationBarTransitionsTest extends SysuiTestCase {
+
+    @Mock
+    LightBarTransitionsController.Factory mLightBarTransitionsFactory;
+    @Mock
+    LightBarTransitionsController mLightBarTransitions;
+    @Mock
+    EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory;
+    @Mock
+    EdgeBackGestureHandler mEdgeBackGestureHandler;
+
+    private NavigationBarTransitions mTransitions;
+    private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+
+        when(mEdgeBackGestureHandlerFactory.create(any(Context.class)))
+                .thenReturn(mEdgeBackGestureHandler);
+        mDependency.injectMockDependency(AssistManager.class);
+        mDependency.injectMockDependency(OverviewProxyService.class);
+        mDependency.injectMockDependency(StatusBarStateController.class);
+        mDependency.injectMockDependency(KeyguardStateController.class);
+        mDependency.injectMockDependency(NavigationBarController.class);
+        mDependency.injectTestDependency(EdgeBackGestureHandler.Factory.class,
+                mEdgeBackGestureHandlerFactory);
+        doReturn(mContext)
+                .when(mDependency.injectMockDependency(NavigationModeController.class))
+                .getCurrentUserContext();
+
+        when(mLightBarTransitionsFactory.create(any())).thenReturn(mLightBarTransitions);
+        NavigationBarView navBar = spy(new NavigationBarView(mContext, null));
+        when(navBar.getCurrentView()).thenReturn(navBar);
+        when(navBar.findViewById(anyInt())).thenReturn(navBar);
+        mTransitions = new NavigationBarTransitions(
+                navBar, mLightBarTransitionsFactory, mDisplayTracker);
+    }
+
+    @Test
+    public void setIsLightsOut_NoAutoDim() {
+        mTransitions.setAutoDim(false);
+
+        assertFalse(mTransitions.isLightsOut(BarTransitions.MODE_OPAQUE));
+
+        assertTrue(mTransitions.isLightsOut(BarTransitions.MODE_LIGHTS_OUT));
+    }
+
+    @Test
+    public void setIsLightsOut_AutoDim() {
+        mTransitions.setAutoDim(true);
+
+        assertTrue(mTransitions.isLightsOut(BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT));
+
+        assertTrue(mTransitions.isLightsOut(BarTransitions.MODE_LIGHTS_OUT));
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/KeyButtonViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/KeyButtonViewTest.java
new file mode 100644
index 0000000..403a883
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/KeyButtonViewTest.java
@@ -0,0 +1,167 @@
+/*
+ * 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.navigationbar.views.buttons;
+
+import static android.view.KeyEvent.ACTION_DOWN;
+import static android.view.KeyEvent.ACTION_UP;
+import static android.view.KeyEvent.FLAG_CANCELED;
+import static android.view.KeyEvent.FLAG_LONG_PRESS;
+import static android.view.KeyEvent.KEYCODE_0;
+import static android.view.KeyEvent.KEYCODE_APP_SWITCH;
+import static android.view.KeyEvent.KEYCODE_BACK;
+import static android.view.KeyEvent.KEYCODE_HOME;
+import static android.view.KeyEvent.KEYCODE_UNKNOWN;
+
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_BACK_BUTTON_LONGPRESS;
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_BACK_BUTTON_TAP;
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_HOME_BUTTON_LONGPRESS;
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_HOME_BUTTON_TAP;
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_LONGPRESS;
+import static com.android.systemui.navigationbar.views.buttons.KeyButtonView.NavBarButtonEvent.NAVBAR_OVERVIEW_BUTTON_TAP;
+
+import static org.mockito.ArgumentMatchers.any;
+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 android.hardware.input.InputManagerGlobal;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.KeyEvent;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.recents.OverviewProxyService;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidJUnit4.class)
+@RunWithLooper
+@SmallTest
+public class KeyButtonViewTest extends SysuiTestCase {
+
+    private KeyButtonView mKeyButtonView;
+    private MetricsLogger mMetricsLogger;
+    private UiEventLogger mUiEventLogger;
+    private InputManagerGlobal mInputManagerGlobal = mock(InputManagerGlobal.class);
+    @Captor
+    private ArgumentCaptor<KeyEvent> mInputEventCaptor;
+
+    @Before
+    public void setup() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
+        mDependency.injectMockDependency(OverviewProxyService.class);
+        mDependency.injectMockDependency(AssistManager.class);
+        mUiEventLogger = mDependency.injectMockDependency(UiEventLogger.class);
+
+        TestableLooper.get(this).runWithLooper(() -> {
+            mKeyButtonView = new KeyButtonView(mContext, null, 0,
+                    mInputManagerGlobal, mUiEventLogger);
+        });
+    }
+
+    @Test
+    public void testLogBackPress() {
+        checkmetrics(KEYCODE_BACK, ACTION_UP, 0, NAVBAR_BACK_BUTTON_TAP);
+    }
+
+    @Test
+    public void testLogOverviewPress() {
+        checkmetrics(KEYCODE_APP_SWITCH, ACTION_UP, 0, NAVBAR_OVERVIEW_BUTTON_TAP);
+    }
+
+    @Test
+    public void testLogHomePress() {
+        checkmetrics(KEYCODE_HOME, ACTION_UP, 0, NAVBAR_HOME_BUTTON_TAP);
+    }
+
+    @Test
+    public void testLogBackLongPressLog() {
+        checkmetrics(KEYCODE_BACK, ACTION_DOWN, FLAG_LONG_PRESS, NAVBAR_BACK_BUTTON_LONGPRESS);
+    }
+
+    @Test
+    public void testLogOverviewLongPress() {
+        checkmetrics(KEYCODE_APP_SWITCH, ACTION_DOWN, FLAG_LONG_PRESS,
+                NAVBAR_OVERVIEW_BUTTON_LONGPRESS);
+    }
+
+    @Test
+    public void testLogHomeLongPress() {
+        checkmetrics(KEYCODE_HOME, ACTION_DOWN, FLAG_LONG_PRESS, NAVBAR_HOME_BUTTON_LONGPRESS);
+    }
+
+    @Test
+    public void testNoLogKeyDown() {
+        checkmetrics(KEYCODE_BACK, ACTION_DOWN, 0, null);
+    }
+
+    @Test
+    public void testNoLogTapAfterLong() {
+        mKeyButtonView.mLongClicked = true;
+        checkmetrics(KEYCODE_BACK, ACTION_UP, 0, null);
+    }
+
+    @Test
+    public void testNoLogCanceled() {
+        checkmetrics(KEYCODE_HOME, ACTION_UP, FLAG_CANCELED, null);
+    }
+
+    @Test
+    public void testNoLogArbitraryKeys() {
+        checkmetrics(KEYCODE_0, ACTION_UP, 0, null);
+    }
+
+    @Test
+    public void testEventInjectedOnAbortGesture() {
+        mKeyButtonView.setCode(KEYCODE_HOME);
+        mKeyButtonView.abortCurrentGesture();
+        verify(mInputManagerGlobal, times(1))
+                .injectInputEvent(any(KeyEvent.class), any(Integer.class));
+    }
+
+    @Test
+    public void testNoEventInjectedOnAbortUnknownGesture() {
+        mKeyButtonView.setCode(KEYCODE_UNKNOWN);
+        mKeyButtonView.abortCurrentGesture();
+        verify(mInputManagerGlobal, never())
+                .injectInputEvent(any(KeyEvent.class), any(Integer.class));
+    }
+
+    private void checkmetrics(int code, int action, int flag,
+            KeyButtonView.NavBarButtonEvent expected) {
+        mKeyButtonView.setCode(code);
+        mKeyButtonView.sendEvent(action, flag);
+        if (expected == null) {
+            verify(mUiEventLogger, never()).log(any(KeyButtonView.NavBarButtonEvent.class));
+        } else {
+            verify(mUiEventLogger, times(1)).log(expected);
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/NavigationBarContextTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/NavigationBarContextTest.java
new file mode 100644
index 0000000..79c4a96
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/NavigationBarContextTest.java
@@ -0,0 +1,226 @@
+/*
+ * 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.navigationbar.views.buttons;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/** atest NavigationBarContextTest */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NavigationBarContextTest extends SysuiTestCase {
+    private static final int GROUP_ID = 1;
+    private static final int BUTTON_0_ID = GROUP_ID + 1;
+    private static final int BUTTON_1_ID = GROUP_ID + 2;
+    private static final int BUTTON_2_ID = GROUP_ID + 3;
+
+    private static final float TEST_DARK_INTENSITY = 0.6f;
+    private static final float DARK_INTENSITY_ERR = 0.0002f;
+    private static final int ICON_RES_ID = 1;
+
+    @Mock
+    EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory;
+    @Mock
+    EdgeBackGestureHandler mEdgeBackGestureHandler;
+
+    private ContextualButtonGroup mGroup;
+    private ContextualButton mBtn0;
+    private ContextualButton mBtn1;
+    private ContextualButton mBtn2;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+
+        when(mEdgeBackGestureHandlerFactory.create(any(Context.class)))
+                .thenReturn(mEdgeBackGestureHandler);
+
+        mDependency.injectMockDependency(AssistManager.class);
+        mDependency.injectTestDependency(EdgeBackGestureHandler.Factory.class,
+                mEdgeBackGestureHandlerFactory);
+
+        mGroup = new ContextualButtonGroup(GROUP_ID);
+        mBtn0 = new ContextualButton(BUTTON_0_ID, mContext, ICON_RES_ID);
+        mBtn1 = new ContextualButton(BUTTON_1_ID, mContext, ICON_RES_ID);
+        mBtn2 = new ContextualButton(BUTTON_2_ID, mContext, ICON_RES_ID);
+
+        // Order of adding buttons to group determines the priority, ascending priority order
+        mGroup.addButton(mBtn0);
+        mGroup.addButton(mBtn1);
+        mGroup.addButton(mBtn2);
+    }
+
+    @Test
+    public void testAddGetContextButtons() throws Exception {
+        assertEquals(mBtn0, mGroup.getContextButton(BUTTON_0_ID));
+        assertEquals(mBtn1, mGroup.getContextButton(BUTTON_1_ID));
+        assertEquals(mBtn2, mGroup.getContextButton(BUTTON_2_ID));
+    }
+
+    @Test
+    public void testSetButtonVisibility() throws Exception {
+        assertTrue("By default the group should be visible.", mGroup.isVisible());
+
+        // Set button 1 to be visible, make sure it is the only visible button
+        showButton(mBtn1);
+        assertFalse(mBtn0.isVisible());
+        assertTrue(mBtn1.isVisible());
+        assertFalse(mBtn2.isVisible());
+
+        // Hide button 1 and make sure the group is also invisible
+        assertNotEquals(mGroup.setButtonVisibility(BUTTON_1_ID, false /* visible */), View.VISIBLE);
+        assertFalse("No buttons are visible, group should also be hidden", mGroup.isVisible());
+        assertNull("No buttons should be visible", mGroup.getVisibleContextButton());
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void testSetButtonVisibilityUnaddedButton() throws Exception {
+        int id = mBtn2.getId() + 1;
+        mGroup.setButtonVisibility(id, true /* visible */);
+        fail("Did not throw when setting a button with an invalid id");
+    }
+
+    @Test
+    public void testSetHigherPriorityButton() throws Exception {
+        // Show button 0
+        showButton(mBtn0);
+
+        // Show button 1
+        showButton(mBtn1);
+        assertTrue("Button 0 should be visible behind",
+                mGroup.isButtonVisibleWithinGroup(mBtn0.getId()));
+
+        // Show button 2
+        showButton(mBtn2);
+        assertTrue("Button 1 should be visible behind",
+                mGroup.isButtonVisibleWithinGroup(mBtn1.getId()));
+        assertTrue(mGroup.isButtonVisibleWithinGroup(mBtn0.getId()));
+        assertTrue(mGroup.isButtonVisibleWithinGroup(mBtn1.getId()));
+        assertTrue(mGroup.isButtonVisibleWithinGroup(mBtn2.getId()));
+
+        // Hide button 2
+        assertNotEquals(mGroup.setButtonVisibility(BUTTON_2_ID, false /* visible */), View.VISIBLE);
+        assertEquals("Hiding button 2 should show button 1", mBtn1,
+                mGroup.getVisibleContextButton());
+
+        // Hide button 1
+        assertNotEquals(mGroup.setButtonVisibility(BUTTON_1_ID, false /* visible */), View.VISIBLE);
+        assertEquals("Hiding button 1 should show button 0", mBtn0,
+                mGroup.getVisibleContextButton());
+
+        // Hide button 0, all buttons are now invisible
+        assertNotEquals(mGroup.setButtonVisibility(BUTTON_0_ID, false /* visible */), View.VISIBLE);
+        assertFalse("No buttons are visible, group should also be invisible", mGroup.isVisible());
+        assertNull(mGroup.getVisibleContextButton());
+        assertFalse(mGroup.isButtonVisibleWithinGroup(mBtn0.getId()));
+        assertFalse(mGroup.isButtonVisibleWithinGroup(mBtn1.getId()));
+        assertFalse(mGroup.isButtonVisibleWithinGroup(mBtn2.getId()));
+    }
+
+    @Test
+    public void testSetLowerPriorityButton() throws Exception {
+        // Show button 2
+        showButton(mBtn2);
+
+        // Show button 1
+        assertNotEquals(mGroup.setButtonVisibility(BUTTON_1_ID, true /* visible */), View.VISIBLE);
+        assertTrue("Showing button 1 lower priority should be hidden but visible underneath",
+                mGroup.isButtonVisibleWithinGroup(BUTTON_1_ID));
+        assertFalse(mBtn0.isVisible());
+        assertFalse(mBtn1.isVisible());
+        assertTrue(mBtn2.isVisible());
+
+        // Hide button 1
+        assertNotEquals(mGroup.setButtonVisibility(BUTTON_1_ID, false /* visible */), View.VISIBLE);
+        assertFalse("Hiding button 1 with lower priority hides itself underneath",
+                mGroup.isButtonVisibleWithinGroup(BUTTON_1_ID));
+        assertTrue("A button still visible, group should also be visible", mGroup.isVisible());
+        assertEquals(mBtn2, mGroup.getVisibleContextButton());
+    }
+
+    @Test
+    public void testSetSamePriorityButton() throws Exception {
+        // Show button 1
+        showButton(mBtn1);
+
+        // Show button 1 again
+        showButton(mBtn1);
+
+        // The original button should still be visible
+        assertEquals(mBtn1, mGroup.getVisibleContextButton());
+        assertFalse(mGroup.isButtonVisibleWithinGroup(mBtn0.getId()));
+        assertFalse(mGroup.isButtonVisibleWithinGroup(mBtn2.getId()));
+    }
+
+    @Test
+    @Ignore("b/112934365")
+    public void testUpdateIconsDarkIntensity() throws Exception {
+        final int unusedColor = 0;
+        final Drawable d = mock(Drawable.class);
+        final ContextualButton button = spy(mBtn0);
+        final KeyButtonDrawable kbd1 = spy(new KeyButtonDrawable(d, unusedColor, unusedColor,
+                false /* horizontalFlip */, null /* ovalBackgroundColor */));
+        final KeyButtonDrawable kbd2 = spy(new KeyButtonDrawable(d, unusedColor, unusedColor,
+                false /* horizontalFlip */, null /* ovalBackgroundColor */));
+        kbd1.setDarkIntensity(TEST_DARK_INTENSITY);
+        kbd2.setDarkIntensity(0f);
+
+        // Update icon returns the drawable intensity to half
+        doReturn(kbd1).when(button).getNewDrawable(anyInt(), anyInt());
+        button.updateIcon(0, 0);
+        assertEquals(TEST_DARK_INTENSITY, kbd1.getDarkIntensity(), DARK_INTENSITY_ERR);
+
+        // Return old dark intensity on new drawable after update icon
+        doReturn(kbd2).when(button).getNewDrawable(anyInt(), anyInt());
+        button.updateIcon(0, 0);
+        assertEquals(TEST_DARK_INTENSITY, kbd2.getDarkIntensity(), DARK_INTENSITY_ERR);
+    }
+
+    private void showButton(ContextualButton button) {
+        assertEquals(View.VISIBLE, mGroup.setButtonVisibility(button.getId(), true /* visible */));
+        assertTrue("After set a button visible, group should also be visible", mGroup.isVisible());
+        assertEquals(button, mGroup.getVisibleContextButton());
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrameTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrameTest.java
new file mode 100644
index 0000000..7941a68
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/views/buttons/NearestTouchFrameTest.java
@@ -0,0 +1,279 @@
+/*
+ * 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.navigationbar.views.buttons;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+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.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.MotionEvent;
+import android.view.View;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Map;
+
+@RunWith(AndroidJUnit4.class)
+@RunWithLooper
+@SmallTest
+public class NearestTouchFrameTest extends SysuiTestCase {
+
+    @Mock
+    EdgeBackGestureHandler.Factory mEdgeBackGestureHandlerFactory;
+    @Mock
+    EdgeBackGestureHandler mEdgeBackGestureHandler;
+    private NearestTouchFrame mNearestTouchFrame;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+
+        when(mEdgeBackGestureHandlerFactory.create(any(Context.class)))
+                .thenReturn(mEdgeBackGestureHandler);
+
+        mDependency.injectTestDependency(EdgeBackGestureHandler.Factory.class,
+                mEdgeBackGestureHandlerFactory);
+        Configuration c = new Configuration(mContext.getResources().getConfiguration());
+        c.smallestScreenWidthDp = 500;
+        mNearestTouchFrame = new NearestTouchFrame(mContext, null, c);
+        mNearestTouchFrame.layout(0, 0, 100, 100);
+    }
+
+    @Test
+    public void testNoActionOnLargeDevices() {
+        Configuration c = new Configuration(mContext.getResources().getConfiguration());
+        c.smallestScreenWidthDp = 700;
+        mNearestTouchFrame = new NearestTouchFrame(mContext, null, c);
+
+        View left = mockViewAt(0, 0, 10, 10);
+        View right = mockViewAt(20, 0, 10, 10);
+
+        mNearestTouchFrame.addView(left);
+        mNearestTouchFrame.addView(right);
+        mNearestTouchFrame.layout(0, 0, 30, 30);
+
+        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+                12 /* x */, 5 /* y */, 0);
+        mNearestTouchFrame.onTouchEvent(ev);
+        verify(left, never()).onTouchEvent(eq(ev));
+        ev.recycle();
+    }
+
+    @Test
+    public void testInvisibleViews() {
+        View left = mockViewAt(0, 0, 10, 10);
+        View right = mockViewAt(20, 0, 10, 10);
+        when(left.getVisibility()).thenReturn(View.INVISIBLE);
+
+        mNearestTouchFrame.addView(left);
+        mNearestTouchFrame.addView(right);
+        mNearestTouchFrame.layout(0, 0, 30, 30);
+
+        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+                12 /* x */, 5 /* y */, 0);
+        mNearestTouchFrame.onTouchEvent(ev);
+        verify(left, never()).onTouchEvent(eq(ev));
+        verify(right, never()).onTouchEvent(eq(ev));
+        ev.recycle();
+    }
+
+
+    @Test
+    public void testNearestView_DetachedViewsExcluded() {
+        View left = mockViewAt(0, 0, 10, 10);
+        when(left.isAttachedToWindow()).thenReturn(false);
+        View right = mockViewAt(20, 0, 10, 10);
+
+        mNearestTouchFrame.addView(left);
+        mNearestTouchFrame.addView(right);
+        mNearestTouchFrame.layout(0, 0, 30, 30);
+
+        // Would go to left view if attached, but goes to right instead as left should be detached.
+        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+                12 /* x */, 5 /* y */, 0);
+        mNearestTouchFrame.onTouchEvent(ev);
+        verify(right).onTouchEvent(eq(ev));
+        ev.recycle();
+    }
+
+    @Test
+    public void testHorizontalSelection_Left() {
+        View left = mockViewAt(0, 0, 10, 10);
+        View right = mockViewAt(20, 0, 10, 10);
+
+        mNearestTouchFrame.addView(left);
+        mNearestTouchFrame.addView(right);
+        mNearestTouchFrame.layout(0, 0, 30, 30);
+
+        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+                12 /* x */, 5 /* y */, 0);
+        mNearestTouchFrame.onTouchEvent(ev);
+        verify(left).onTouchEvent(eq(ev));
+        ev.recycle();
+    }
+
+    @Test
+    public void testHorizontalSelection_Right() {
+        View left = mockViewAt(0, 0, 10, 10);
+        View right = mockViewAt(20, 0, 10, 10);
+
+        mNearestTouchFrame.addView(left);
+        mNearestTouchFrame.addView(right);
+        mNearestTouchFrame.layout(0, 0, 30, 30);
+
+        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+                18 /* x */, 5 /* y */, 0);
+        mNearestTouchFrame.onTouchEvent(ev);
+        verify(right).onTouchEvent(eq(ev));
+        ev.recycle();
+    }
+
+    @Test
+    public void testVerticalSelection_Top() {
+        View top = mockViewAt(0, 0, 10, 10);
+        View bottom = mockViewAt(0, 20, 10, 10);
+        mNearestTouchFrame.setIsVertical(true);
+        mNearestTouchFrame.addView(top);
+        mNearestTouchFrame.addView(bottom);
+        mNearestTouchFrame.layout(0, 0, 30, 30);
+
+        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+                5 /* x */, 12 /* y */, 0);
+        mNearestTouchFrame.onTouchEvent(ev);
+        verify(top).onTouchEvent(eq(ev));
+        ev.recycle();
+    }
+
+    @Test
+    public void testVerticalSelection_Bottom() {
+        View top = mockViewAt(0, 0, 10, 10);
+        View bottom = mockViewAt(0, 20, 10, 10);
+        mNearestTouchFrame.setIsVertical(true);
+        mNearestTouchFrame.addView(top);
+        mNearestTouchFrame.addView(bottom);
+        mNearestTouchFrame.layout(0, 0, 30, 30);
+
+        MotionEvent ev = MotionEvent.obtain(0, 0, 0,
+                5 /* x */, 18 /* y */, 0);
+        mNearestTouchFrame.onTouchEvent(ev);
+        verify(bottom).onTouchEvent(eq(ev));
+        ev.recycle();
+    }
+
+    @Test
+    public void testViewNotAttachedNoCrash() {
+        View view = mockViewAt(0, 20, 10, 10);
+        when(view.isAttachedToWindow()).thenReturn(false);
+        mNearestTouchFrame.addView(view);
+        mNearestTouchFrame.layout(0, 0, 30, 30);
+
+        MotionEvent ev = MotionEvent.obtain(0, 0, 0, 5 /* x */, 18 /* y */, 0);
+        mNearestTouchFrame.onTouchEvent(ev);
+        verify(view, never()).onTouchEvent(eq(ev));
+        ev.recycle();
+    }
+
+    @Test
+    public void testViewMiddleChildNotAttachedCrash() {
+        View view1 = mockViewAt(0, 20, 10, 10);
+        View view2 = mockViewAt(11, 20, 10, 10);
+        View view3 = mockViewAt(21, 20, 10, 10);
+        when(view2.isAttachedToWindow()).thenReturn(false);
+        mNearestTouchFrame.addView(view1);
+        mNearestTouchFrame.addView(view2);
+        mNearestTouchFrame.addView(view3);
+        mNearestTouchFrame.layout(0, 0, 30, 30);
+
+        MotionEvent ev = MotionEvent.obtain(0, 0, 0, 5 /* x */, 18 /* y */, 0);
+        mNearestTouchFrame.onTouchEvent(ev);
+        verify(view2, never()).onTouchEvent(eq(ev));
+        ev.recycle();
+    }
+
+    @Test
+    public void testCachedRegionsSplit_horizontal() {
+        View left = mockViewAt(0, 0, 5, 20);
+        View right = mockViewAt(15, 0, 5, 20);
+        mNearestTouchFrame.addView(left);
+        mNearestTouchFrame.addView(right);
+        mNearestTouchFrame.layout(0, 0, 20, 20);
+
+        Map<View, Rect> childRegions = mNearestTouchFrame.getFullTouchableChildRegions();
+        assertEquals(2, childRegions.size());
+        Rect leftRegion = childRegions.get(left);
+        Rect rightRegion = childRegions.get(right);
+        assertEquals(new Rect(0, 0, 9, 20), leftRegion);
+        assertEquals(new Rect(10, 0, 20, 20), rightRegion);
+    }
+
+    @Test
+    public void testCachedRegionsSplit_vertical() {
+        View top = mockViewAt(0, 0, 20, 5);
+        View bottom = mockViewAt(0, 15, 20, 5);
+        mNearestTouchFrame.addView(top);
+        mNearestTouchFrame.addView(bottom);
+        mNearestTouchFrame.setIsVertical(true);
+        mNearestTouchFrame.layout(0, 0, 20, 20);
+
+        Map<View, Rect> childRegions = mNearestTouchFrame.getFullTouchableChildRegions();
+        assertEquals(2, childRegions.size());
+        Rect topRegion = childRegions.get(top);
+        Rect bottomRegion = childRegions.get(bottom);
+        assertEquals(new Rect(0, 0, 20, 9), topRegion);
+        assertEquals(new Rect(0, 10, 20, 20), bottomRegion);
+    }
+
+    private View mockViewAt(int x, int y, int width, int height) {
+        View v = spy(new View(mContext));
+        doAnswer(invocation -> {
+            int[] pos = (int[]) invocation.getArguments()[0];
+            pos[0] = x;
+            pos[1] = y;
+            return null;
+        }).when(v).getLocationInWindow(any());
+        when(v.isClickable()).thenReturn(true);
+        when(v.isAttachedToWindow()).thenReturn(true);
+        when(v.getWidth()).thenReturn(width);
+        when(v.getHeight()).thenReturn(height);
+
+        // Stupid final methods.
+        v.setLeft(0);
+        v.setRight(width);
+        v.setTop(0);
+        v.setBottom(height);
+        return v;
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt
index f624f20..b7fb759 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/quickaffordance/NoteTaskQuickAffordanceConfigTest.kt
@@ -57,7 +57,9 @@
 import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.anyString
+import org.mockito.Mockito.spy
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
 import org.mockito.MockitoSession
 import org.mockito.quality.Strictness
 
@@ -75,6 +77,9 @@
 
     private lateinit var mockitoSession: MockitoSession
 
+    private val spiedContext = spy(context)
+    private val spiedResources = spy(spiedContext.resources)
+
     @Before
     fun setUp() {
         mockitoSession =
@@ -100,6 +105,8 @@
                 )
             )
             .thenReturn(listOf("com.google.test.notes"))
+
+        `when`(spiedContext.resources).thenReturn(spiedResources)
     }
 
     @After
@@ -109,7 +116,7 @@
 
     private fun createUnderTest(isEnabled: Boolean = true): KeyguardQuickAffordanceConfig =
         NoteTaskQuickAffordanceConfig(
-            context = context,
+            context = spiedContext,
             controller = controller,
             stylusManager = stylusManager,
             userManager = userManager,
@@ -132,126 +139,262 @@
         )
 
     // region lockScreenState
+    @Suppress("ktlint:standard:max-line-length")
     @Test
-    fun lockScreenState_stylusUsed_userUnlocked_isSelected_shouldEmitVisible() = runTest {
-        val underTest = createUnderTest()
-        TestConfig().setStylusEverUsed(true).setUserUnlocked(true).setConfigSelections(underTest)
-
-        val actual by collectLastValue(underTest.lockScreenState)
-
-        assertThat(actual).isEqualTo(createLockScreenStateVisible())
-    }
-
-    @Test
-    fun lockScreenState_stylusUsed_userUnlocked_isSelected_noDefaultNotesAppSet_shouldEmitHidden() =
+    fun lockScreenState_stylusUnused_userLocked_customizationDisabled_notesLockScreenShortcutNotSelected_shouldEmitHidden() =
         runTest {
             val underTest = createUnderTest()
             TestConfig()
-                .setStylusEverUsed(true)
-                .setUserUnlocked(true)
-                .setConfigSelections(underTest)
-            whenever(
-                    roleManager.getRoleHoldersAsUser(
-                        eq(RoleManager.ROLE_NOTES),
-                        any(UserHandle::class.java)
-                    )
-                )
-                .thenReturn(emptyList())
+                .setStylusEverUsed(false)
+                .setUserUnlocked(false)
+                .setLockScreenCustomizationEnabled(false)
+                .setConfigSelections()
 
             val actual by collectLastValue(underTest.lockScreenState)
 
             assertThat(actual).isEqualTo(LockScreenState.Hidden)
         }
 
+    @Suppress("ktlint:standard:max-line-length")
     @Test
-    fun lockScreenState_stylusUnused_userUnlocked_isSelected_shouldEmitHidden() = runTest {
-        val underTest = createUnderTest()
-        TestConfig().setStylusEverUsed(false).setUserUnlocked(true).setConfigSelections(underTest)
+    fun lockScreenState_stylusUnused_userLocked_customizationDisabled_notesLockScreenShortcutSelected_shouldEmitHidden() =
+        runTest {
+            val underTest = createUnderTest()
+            TestConfig()
+                .setStylusEverUsed(false)
+                .setUserUnlocked(false)
+                .setLockScreenCustomizationEnabled(false)
+                .setConfigSelections(underTest)
 
-        val actual by collectLastValue(underTest.lockScreenState)
+            val actual by collectLastValue(underTest.lockScreenState)
 
-        assertThat(actual).isEqualTo(LockScreenState.Hidden)
-    }
+            assertThat(actual).isEqualTo(LockScreenState.Hidden)
+        }
 
+    @Suppress("ktlint:standard:max-line-length")
     @Test
-    fun lockScreenState_stylusUsed_userLocked_isSelected_shouldEmitHidden() = runTest {
-        val underTest = createUnderTest()
-        TestConfig().setStylusEverUsed(true).setUserUnlocked(false).setConfigSelections(underTest)
+    fun lockScreenState_stylusUnused_userLocked_customizationEnabled_notesLockScreenShortcutNotSelected_shouldEmitHidden() =
+        runTest {
+            val underTest = createUnderTest()
+            TestConfig()
+                .setStylusEverUsed(false)
+                .setUserUnlocked(false)
+                .setLockScreenCustomizationEnabled(true)
+                .setConfigSelections()
 
-        val actual by collectLastValue(underTest.lockScreenState)
+            val actual by collectLastValue(underTest.lockScreenState)
 
-        assertThat(actual).isEqualTo(LockScreenState.Hidden)
-    }
+            assertThat(actual).isEqualTo(LockScreenState.Hidden)
+        }
 
+    @Suppress("ktlint:standard:max-line-length")
     @Test
-    fun lockScreenState_stylusUsed_userUnlocked_noSelected_shouldEmitHidden() = runTest {
-        TestConfig().setStylusEverUsed(true).setUserUnlocked(true).setConfigSelections()
+    fun lockScreenState_stylusUnused_userLocked_customizationEnabled_notesLockScreenShortcutSelected_shouldEmitHidden() =
+        runTest {
+            val underTest = createUnderTest()
+            TestConfig()
+                .setStylusEverUsed(false)
+                .setUserUnlocked(false)
+                .setLockScreenCustomizationEnabled(true)
+                .setConfigSelections(underTest)
 
-        val underTest = createUnderTest()
-        val actual by collectLastValue(underTest.lockScreenState)
+            val actual by collectLastValue(underTest.lockScreenState)
 
-        assertThat(actual).isEqualTo(LockScreenState.Hidden)
-    }
+            assertThat(actual).isEqualTo(LockScreenState.Hidden)
+        }
 
+    @Suppress("ktlint:standard:max-line-length")
     @Test
-    fun lockScreenState_stylusUnused_userUnlocked_noSelected_shouldEmitHidden() = runTest {
-        TestConfig().setStylusEverUsed(false).setUserUnlocked(true).setConfigSelections()
+    fun lockScreenState_stylusUnused_userUnlocked_customizationDisabled_notesLockScreenShortcutNotSelected_shouldEmitHidden() =
+        runTest {
+            val underTest = createUnderTest()
+            TestConfig()
+                .setStylusEverUsed(false)
+                .setUserUnlocked(true)
+                .setLockScreenCustomizationEnabled(false)
+                .setConfigSelections()
 
-        val underTest = createUnderTest()
-        val actual by collectLastValue(underTest.lockScreenState)
+            val actual by collectLastValue(underTest.lockScreenState)
 
-        assertThat(actual).isEqualTo(LockScreenState.Hidden)
-    }
+            assertThat(actual).isEqualTo(LockScreenState.Hidden)
+        }
 
+    @Suppress("ktlint:standard:max-line-length")
     @Test
-    fun lockScreenState_stylusUsed_userLocked_noSelected_shouldEmitHidden() = runTest {
-        TestConfig().setStylusEverUsed(true).setUserUnlocked(false).setConfigSelections()
+    fun lockScreenState_stylusUnused_userUnlocked_customizationDisabled_notesLockScreenShortcutSelected_shouldEmitHidden() =
+        runTest {
+            val underTest = createUnderTest()
+            TestConfig()
+                .setStylusEverUsed(false)
+                .setUserUnlocked(true)
+                .setLockScreenCustomizationEnabled(false)
+                .setConfigSelections(underTest)
 
-        val underTest = createUnderTest()
-        val actual by collectLastValue(underTest.lockScreenState)
+            val actual by collectLastValue(underTest.lockScreenState)
 
-        assertThat(actual).isEqualTo(LockScreenState.Hidden)
-    }
+            assertThat(actual).isEqualTo(LockScreenState.Hidden)
+        }
 
+    @Suppress("ktlint:standard:max-line-length")
     @Test
-    fun lockScreenState_stylusUsed_userUnlocked_customSelections_shouldEmitHidden() = runTest {
-        TestConfig().setStylusEverUsed(true).setUserUnlocked(true).setConfigSelections(mock())
+    fun lockScreenState_stylusUnused_userUnlocked_customizationEnabled_notesLockScreenShortcutNotSelected_shouldEmitHidden() =
+        runTest {
+            val underTest = createUnderTest()
+            TestConfig()
+                .setStylusEverUsed(false)
+                .setUserUnlocked(true)
+                .setLockScreenCustomizationEnabled(true)
+                .setConfigSelections()
 
-        val underTest = createUnderTest()
-        val actual by collectLastValue(underTest.lockScreenState)
+            val actual by collectLastValue(underTest.lockScreenState)
 
-        assertThat(actual).isEqualTo(LockScreenState.Hidden)
-    }
+            assertThat(actual).isEqualTo(LockScreenState.Hidden)
+        }
 
+    @Suppress("ktlint:standard:max-line-length")
     @Test
-    fun lockScreenState_stylusUnused_userUnlocked_customSelections_shouldEmitHidden() = runTest {
-        TestConfig().setStylusEverUsed(false).setUserUnlocked(true).setConfigSelections(mock())
+    fun lockScreenState_stylusUnused_userUnlocked_customizationEnabled_notesLockScreenShortcutSelected_shouldEmitVisible() =
+        runTest {
+            val underTest = createUnderTest()
+            TestConfig()
+                .setStylusEverUsed(false)
+                .setUserUnlocked(true)
+                .setLockScreenCustomizationEnabled(true)
+                .setConfigSelections(underTest)
 
-        val underTest = createUnderTest()
-        val actual by collectLastValue(underTest.lockScreenState)
+            val actual by collectLastValue(underTest.lockScreenState)
 
-        assertThat(actual).isEqualTo(LockScreenState.Hidden)
-    }
+            assertThat(actual).isEqualTo(createLockScreenStateVisible())
+        }
 
+    @Suppress("ktlint:standard:max-line-length")
     @Test
-    fun lockScreenState_stylusUsed_userLocked_customSelections_shouldEmitHidden() = runTest {
-        TestConfig().setStylusEverUsed(true).setUserUnlocked(false).setConfigSelections(mock())
+    fun lockScreenState_stylusUsed_userLocked_customizationDisabled_notesLockScreenShortcutNotSelected_shouldEmitHidden() =
+        runTest {
+            val underTest = createUnderTest()
+            TestConfig()
+                .setStylusEverUsed(true)
+                .setUserUnlocked(false)
+                .setLockScreenCustomizationEnabled(false)
+                .setConfigSelections()
 
-        val underTest = createUnderTest()
-        val actual by collectLastValue(underTest.lockScreenState)
+            val actual by collectLastValue(underTest.lockScreenState)
 
-        assertThat(actual).isEqualTo(LockScreenState.Hidden)
-    }
+            assertThat(actual).isEqualTo(LockScreenState.Hidden)
+        }
 
+    @Suppress("ktlint:standard:max-line-length")
     @Test
-    fun lockScreenState_isNotEnabled_shouldEmitHidden() = runTest {
-        TestConfig().setStylusEverUsed(true).setUserUnlocked(true).setConfigSelections()
+    fun lockScreenState_stylusUsed_userLocked_customizationDisabled_notesLockScreenShortcutSelected_shouldEmitHidden() =
+        runTest {
+            val underTest = createUnderTest()
+            TestConfig()
+                .setStylusEverUsed(true)
+                .setUserUnlocked(false)
+                .setLockScreenCustomizationEnabled(false)
+                .setConfigSelections(underTest)
 
-        val underTest = createUnderTest(isEnabled = false)
-        val actual by collectLastValue(underTest.lockScreenState)
+            val actual by collectLastValue(underTest.lockScreenState)
 
-        assertThat(actual).isEqualTo(LockScreenState.Hidden)
-    }
+            assertThat(actual).isEqualTo(LockScreenState.Hidden)
+        }
+
+    @Suppress("ktlint:standard:max-line-length")
+    @Test
+    fun lockScreenState_stylusUsed_userLocked_customizationEnabled_notesLockScreenShortcutNotSelected_shouldEmitHidden() =
+        runTest {
+            val underTest = createUnderTest()
+            TestConfig()
+                .setStylusEverUsed(true)
+                .setUserUnlocked(false)
+                .setLockScreenCustomizationEnabled(true)
+                .setConfigSelections()
+
+            val actual by collectLastValue(underTest.lockScreenState)
+
+            assertThat(actual).isEqualTo(LockScreenState.Hidden)
+        }
+
+    @Suppress("ktlint:standard:max-line-length")
+    @Test
+    fun lockScreenState_stylusUsed_userLocked_customizationEnabled_notesLockScreenShortcutSelected_shouldEmitHidden() =
+        runTest {
+            val underTest = createUnderTest()
+            TestConfig()
+                .setStylusEverUsed(true)
+                .setUserUnlocked(false)
+                .setLockScreenCustomizationEnabled(true)
+                .setConfigSelections(underTest)
+
+            val actual by collectLastValue(underTest.lockScreenState)
+
+            assertThat(actual).isEqualTo(LockScreenState.Hidden)
+        }
+
+    @Suppress("ktlint:standard:max-line-length")
+    @Test
+    fun lockScreenState_stylusUsed_userUnlocked_customizationDisabled_notesLockScreenShortcutNotSelected_shouldEmitVisible() =
+        runTest {
+            val underTest = createUnderTest()
+            TestConfig()
+                .setStylusEverUsed(true)
+                .setUserUnlocked(true)
+                .setLockScreenCustomizationEnabled(false)
+                .setConfigSelections()
+
+            val actual by collectLastValue(underTest.lockScreenState)
+
+            assertThat(actual).isEqualTo(createLockScreenStateVisible())
+        }
+
+    @Suppress("ktlint:standard:max-line-length")
+    @Test
+    fun lockScreenState_stylusUsed_userUnlocked_customizationDisabled_notesLockScreenShortcutSelected_shouldEmitVisible() =
+        runTest {
+            val underTest = createUnderTest()
+            TestConfig()
+                .setStylusEverUsed(true)
+                .setUserUnlocked(true)
+                .setLockScreenCustomizationEnabled(false)
+                .setConfigSelections(underTest)
+
+            val actual by collectLastValue(underTest.lockScreenState)
+
+            assertThat(actual).isEqualTo(createLockScreenStateVisible())
+        }
+
+    @Suppress("ktlint:standard:max-line-length")
+    @Test
+    fun lockScreenState_stylusUsed_userUnlocked_customizationEnabled_notesLockScreenShortcutNotSelected_shouldEmitHidden() =
+        runTest {
+            val underTest = createUnderTest()
+            TestConfig()
+                .setStylusEverUsed(true)
+                .setUserUnlocked(true)
+                .setLockScreenCustomizationEnabled(true)
+                .setConfigSelections()
+
+            val actual by collectLastValue(underTest.lockScreenState)
+
+            assertThat(actual).isEqualTo(LockScreenState.Hidden)
+        }
+
+    @Suppress("ktlint:standard:max-line-length")
+    @Test
+    fun lockScreenState_stylusUsed_userUnlocked_customizationEnabled_notesLockScreenShortcutSelected_shouldEmitVisible() =
+        runTest {
+            val underTest = createUnderTest()
+            TestConfig()
+                .setStylusEverUsed(true)
+                .setUserUnlocked(true)
+                .setLockScreenCustomizationEnabled(true)
+                .setConfigSelections(underTest)
+
+            val actual by collectLastValue(underTest.lockScreenState)
+
+            assertThat(actual).isEqualTo(createLockScreenStateVisible())
+        }
+
     // endregion
 
     @Test
@@ -294,18 +437,24 @@
             .isEqualTo(ACTION_MANAGE_NOTES_ROLE_FROM_QUICK_AFFORDANCE)
         assertThat(disabled.actionIntent?.`package`).isEqualTo(context.packageName)
     }
+
     // endregion
 
     private inner class TestConfig {
 
         fun setStylusEverUsed(value: Boolean) = also {
-            whenever(InputSettings.isStylusEverUsed(mContext)).thenReturn(value)
+            whenever(InputSettings.isStylusEverUsed(spiedContext)).thenReturn(value)
         }
 
         fun setUserUnlocked(value: Boolean) = also {
             whenever(userManager.isUserUnlocked).thenReturn(value)
         }
 
+        fun setLockScreenCustomizationEnabled(value: Boolean) = also {
+            `when`(spiedResources.getBoolean(R.bool.custom_lockscreen_shortcuts_enabled))
+                .thenReturn(value)
+        }
+
         fun setConfigSelections(vararg values: KeyguardQuickAffordanceConfig) = also {
             val slotKey = "bottom-right"
             val configSnapshots = values.toList()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDisableFlagsLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDisableFlagsLoggerTest.kt
index 9e5d3bd..cc3e27c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDisableFlagsLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDisableFlagsLoggerTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.qs
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
@@ -26,9 +27,11 @@
 import java.io.PrintWriter
 import java.io.StringWriter
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mockito.mock
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class QSDisableFlagsLoggerTest : SysuiTestCase() {
 
     private val buffer =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTest.java
index 1c86638..03483c9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceManagerTest.java
@@ -20,6 +20,8 @@
 import static com.android.systemui.Flags.FLAG_QS_CUSTOM_TILE_CLICK_GUARANTEED_BUG_FIX;
 import static com.android.systemui.util.concurrency.MockExecutorHandlerKt.mockExecutorHandler;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
@@ -279,4 +281,23 @@
         verify(mTileLifecycle, never()).onStopListening();
         verify(mTileLifecycle, never()).executeSetBindService(false);
     }
+
+    @Test
+    public void testNoExtraPendingBindIfAlreadyBound() {
+        mTileServiceManager.startLifecycleManagerAndAddTile();
+
+        // As part of adding the tile, it will be bound and it will send a start successful to
+        // TileServices. startSuccessful will clear pending bind
+        mTileServiceManager.clearPendingBind();
+
+        // Assume we are still bound
+        when(mTileLifecycle.isBound()).thenReturn(true);
+
+        // And we want to bind again
+        mTileServiceManager.setBindAllowed(true);
+        mTileServiceManager.setBindRequested(true);
+
+        // Then the tile doesn't have pending bind
+        assertThat(mTileServiceManager.hasPendingBind()).isFalse();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/data/QSPreferencesRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/data/QSPreferencesRepositoryTest.kt
deleted file mode 100644
index b0aa6dd..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/data/QSPreferencesRepositoryTest.kt
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.panels.data
-
-import android.content.Context
-import android.content.SharedPreferences
-import android.content.pm.UserInfo
-import android.testing.AndroidTestingRunner
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.testScope
-import com.android.systemui.qs.panels.data.repository.QSPreferencesRepository
-import com.android.systemui.qs.panels.data.repository.qsPreferencesRepository
-import com.android.systemui.settings.userFileManager
-import com.android.systemui.testKosmos
-import com.android.systemui.user.data.repository.fakeUserRepository
-import com.android.systemui.user.data.repository.userRepository
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.test.runTest
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@SmallTest
-@RunWith(AndroidTestingRunner::class)
-class QSPreferencesRepositoryTest : SysuiTestCase() {
-    private val kosmos = testKosmos()
-    private val underTest = with(kosmos) { qsPreferencesRepository }
-
-    @Test
-    fun showLabels_updatesFromSharedPreferences() =
-        with(kosmos) {
-            testScope.runTest {
-                val latest by collectLastValue(underTest.showLabels)
-                assertThat(latest).isFalse()
-
-                setShowLabelsInSharedPreferences(true)
-                assertThat(latest).isTrue()
-
-                setShowLabelsInSharedPreferences(false)
-                assertThat(latest).isFalse()
-            }
-        }
-
-    @Test
-    fun showLabels_updatesFromUserChange() =
-        with(kosmos) {
-            testScope.runTest {
-                fakeUserRepository.setUserInfos(USERS)
-                val latest by collectLastValue(underTest.showLabels)
-
-                fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)
-                setShowLabelsInSharedPreferences(false)
-
-                fakeUserRepository.setSelectedUserInfo(ANOTHER_USER)
-                setShowLabelsInSharedPreferences(true)
-
-                fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)
-                assertThat(latest).isFalse()
-            }
-        }
-
-    @Test
-    fun setShowLabels_inSharedPreferences() {
-        underTest.setShowLabels(false)
-        assertThat(getShowLabelsFromSharedPreferences(true)).isFalse()
-
-        underTest.setShowLabels(true)
-        assertThat(getShowLabelsFromSharedPreferences(false)).isTrue()
-    }
-
-    @Test
-    fun setShowLabels_forDifferentUser() =
-        with(kosmos) {
-            testScope.runTest {
-                fakeUserRepository.setUserInfos(USERS)
-
-                fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)
-                underTest.setShowLabels(false)
-                assertThat(getShowLabelsFromSharedPreferences(true)).isFalse()
-
-                fakeUserRepository.setSelectedUserInfo(ANOTHER_USER)
-                underTest.setShowLabels(true)
-                assertThat(getShowLabelsFromSharedPreferences(false)).isTrue()
-
-                fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)
-                assertThat(getShowLabelsFromSharedPreferences(true)).isFalse()
-            }
-        }
-
-    private fun getSharedPreferences(): SharedPreferences =
-        with(kosmos) {
-            return userFileManager.getSharedPreferences(
-                QSPreferencesRepository.FILE_NAME,
-                Context.MODE_PRIVATE,
-                userRepository.getSelectedUserInfo().id,
-            )
-        }
-
-    private fun setShowLabelsInSharedPreferences(value: Boolean) {
-        getSharedPreferences().edit().putBoolean(ICON_LABELS_KEY, value).apply()
-    }
-
-    private fun getShowLabelsFromSharedPreferences(defaultValue: Boolean): Boolean {
-        return getSharedPreferences().getBoolean(ICON_LABELS_KEY, defaultValue)
-    }
-
-    companion object {
-        private const val ICON_LABELS_KEY = "show_icon_labels"
-        private const val PRIMARY_USER_ID = 0
-        private val PRIMARY_USER = UserInfo(PRIMARY_USER_ID, "user 0", UserInfo.FLAG_MAIN)
-        private const val ANOTHER_USER_ID = 1
-        private val ANOTHER_USER = UserInfo(ANOTHER_USER_ID, "user 1", UserInfo.FLAG_FULL)
-        private val USERS = listOf(PRIMARY_USER, ANOTHER_USER)
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractorTest.kt
deleted file mode 100644
index 9b08432e..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/domain/interactor/IconLabelVisibilityInteractorTest.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.panels.domain.interactor
-
-import android.content.pm.UserInfo
-import android.testing.AndroidTestingRunner
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.testScope
-import com.android.systemui.testKosmos
-import com.android.systemui.user.data.repository.fakeUserRepository
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.runCurrent
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@OptIn(ExperimentalCoroutinesApi::class)
-@SmallTest
-@RunWith(AndroidTestingRunner::class)
-class IconLabelVisibilityInteractorTest : SysuiTestCase() {
-    private val kosmos = testKosmos()
-    private val underTest = with(kosmos) { iconLabelVisibilityInteractor }
-
-    @Before
-    fun setUp() {
-        with(kosmos) { fakeUserRepository.setUserInfos(USERS) }
-    }
-
-    @Test
-    fun changingShowLabels_receivesCorrectShowLabels() =
-        with(kosmos) {
-            testScope.runTest {
-                val showLabels by collectLastValue(underTest.showLabels)
-
-                underTest.setShowLabels(false)
-                runCurrent()
-                assertThat(showLabels).isFalse()
-
-                underTest.setShowLabels(true)
-                runCurrent()
-                assertThat(showLabels).isTrue()
-            }
-        }
-
-    @Test
-    fun changingUser_receivesCorrectShowLabels() =
-        with(kosmos) {
-            testScope.runTest {
-                val showLabels by collectLastValue(underTest.showLabels)
-
-                fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)
-                underTest.setShowLabels(false)
-                runCurrent()
-                assertThat(showLabels).isFalse()
-
-                fakeUserRepository.setSelectedUserInfo(ANOTHER_USER)
-                underTest.setShowLabels(true)
-                runCurrent()
-                assertThat(showLabels).isTrue()
-
-                fakeUserRepository.setSelectedUserInfo(PRIMARY_USER)
-                runCurrent()
-                assertThat(showLabels).isFalse()
-            }
-        }
-
-    companion object {
-        private val PRIMARY_USER = UserInfo(0, "user 0", UserInfo.FLAG_MAIN)
-        private val ANOTHER_USER = UserInfo(1, "user 1", UserInfo.FLAG_FULL)
-        private val USERS = listOf(PRIMARY_USER, ANOTHER_USER)
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
index 50cf5cc5..9f12b18 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
@@ -39,7 +39,6 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.MetricsLogger;
-import com.android.keyguard.TestScopeProvider;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.DialogTransitionAnimator;
 import com.android.systemui.classifier.FalsingManagerFake;
@@ -54,14 +53,11 @@
 import com.android.systemui.statusbar.connectivity.SignalCallback;
 import com.android.systemui.statusbar.connectivity.WifiIndicators;
 import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository;
-import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor;
 import com.android.systemui.statusbar.policy.CastController;
-import com.android.systemui.statusbar.policy.CastController.CastDevice;
+import com.android.systemui.statusbar.policy.CastDevice;
 import com.android.systemui.statusbar.policy.HotspotController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
-import kotlinx.coroutines.test.TestScope;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -105,12 +101,10 @@
     @Mock
     private QsEventLogger mUiEventLogger;
 
-    private WifiInteractor mWifiInteractor;
     private final TileJavaAdapter mJavaAdapter = new TileJavaAdapter();
     private final FakeConnectivityRepository mConnectivityRepository =
             new FakeConnectivityRepository();
     private final FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
-    private final TestScope mTestScope = TestScopeProvider.getTestScope();
 
     private TestableLooper mTestableLooper;
     private CastTile mCastTile;
@@ -172,8 +166,7 @@
     @Test
     public void testStateActive_wifiEnabledAndCasting() {
         createAndStartTileOldImpl();
-        CastController.CastDevice device = new CastController.CastDevice();
-        device.state = CastController.CastDevice.STATE_CONNECTED;
+        CastDevice device = createConnectedCastDevice();
         List<CastDevice> devices = new ArrayList<>();
         devices.add(device);
         when(mController.getCastDevices()).thenReturn(devices);
@@ -232,8 +225,7 @@
     @Test
     public void stateActive_wifiConnectedAndCasting_newPipeline() {
         createAndStartTileNewImpl();
-        CastController.CastDevice device = new CastController.CastDevice();
-        device.state = CastDevice.STATE_CONNECTED;
+        CastDevice device = createConnectedCastDevice();
         List<CastDevice> devices = new ArrayList<>();
         devices.add(device);
         when(mController.getCastDevices()).thenReturn(devices);
@@ -248,8 +240,7 @@
     @Test
     public void stateActive_ethernetConnectedAndCasting_newPipeline() {
         createAndStartTileNewImpl();
-        CastController.CastDevice device = new CastController.CastDevice();
-        device.state = CastDevice.STATE_CONNECTED;
+        CastDevice device = createConnectedCastDevice();
         List<CastDevice> devices = new ArrayList<>();
         devices.add(device);
         when(mController.getCastDevices()).thenReturn(devices);
@@ -286,8 +277,7 @@
     @Test
     public void testStateActive_hotspotEnabledAndConnectedAndCasting() {
         createAndStartTileOldImpl();
-        CastController.CastDevice device = new CastController.CastDevice();
-        device.state = CastController.CastDevice.STATE_CONNECTED;
+        CastDevice device = createConnectedCastDevice();
         List<CastDevice> devices = new ArrayList<>();
         devices.add(device);
         when(mController.getCastDevices()).thenReturn(devices);
@@ -309,9 +299,13 @@
     @Test
     public void testHandleClick_castDevicePresent() {
         createAndStartTileOldImpl();
-        CastController.CastDevice device = new CastController.CastDevice();
-        device.state = CastDevice.STATE_CONNECTED;
-        device.tag = mock(MediaRouter.RouteInfo.class);
+        CastDevice device = new CastDevice(
+                "id",
+                /* name= */ null,
+                /* description= */ null,
+                /* state= */ CastDevice.CastState.Connected,
+                /* origin= */ CastDevice.CastOrigin.MediaRouter,
+                /* tag= */ mock(MediaRouter.RouteInfo.class));
         List<CastDevice> devices = new ArrayList<>();
         devices.add(device);
         when(mController.getCastDevices()).thenReturn(devices);
@@ -327,9 +321,13 @@
     @Test
     public void testHandleClick_projectionOnly() {
         createAndStartTileOldImpl();
-        CastController.CastDevice device = new CastController.CastDevice();
-        device.state = CastDevice.STATE_CONNECTED;
-        device.tag = mock(MediaProjectionInfo.class);
+        CastDevice device = new CastDevice(
+                "id",
+                /* name= */ null,
+                /* description= */ null,
+                /* state= */ CastDevice.CastState.Connected,
+                /* origin= */ CastDevice.CastOrigin.MediaProjection,
+                /* tag= */ mock(MediaProjectionInfo.class));
         List<CastDevice> devices = new ArrayList<>();
         devices.add(device);
         when(mController.getCastDevices()).thenReturn(devices);
@@ -344,31 +342,40 @@
     @Test
     public void testUpdateState_projectionOnly() {
         createAndStartTileOldImpl();
-        CastController.CastDevice device = new CastController.CastDevice();
-        device.state = CastDevice.STATE_CONNECTED;
-        device.tag = mock(MediaProjectionInfo.class);
-        device.name = "Test Projection Device";
+        CastDevice device = new CastDevice(
+                "id",
+                /* name= */ "Test Projection Device",
+                /* description= */ null,
+                /* state= */ CastDevice.CastState.Connected,
+                /* origin= */ CastDevice.CastOrigin.MediaProjection,
+                /* tag= */ mock(MediaProjectionInfo.class));
         List<CastDevice> devices = new ArrayList<>();
         devices.add(device);
         when(mController.getCastDevices()).thenReturn(devices);
 
         enableWifiAndProcessMessages();
         assertEquals(Tile.STATE_ACTIVE, mCastTile.getState().state);
-        assertTrue(mCastTile.getState().secondaryLabel.toString().startsWith(device.name));
+        assertTrue(mCastTile.getState().secondaryLabel.toString()
+                .startsWith("Test Projection Device"));
     }
 
     @Test
     public void testUpdateState_castingAndProjection() {
         createAndStartTileOldImpl();
-        CastController.CastDevice casting = new CastController.CastDevice();
-        casting.state = CastDevice.STATE_CONNECTED;
-        casting.tag = mock(RouteInfo.class);
-        casting.name = "Test Casting Device";
-
-        CastController.CastDevice projection = new CastController.CastDevice();
-        projection.state = CastDevice.STATE_CONNECTED;
-        projection.tag = mock(MediaProjectionInfo.class);
-        projection.name = "Test Projection Device";
+        CastDevice casting = new CastDevice(
+                "id1",
+                /* name= */ "Test Casting Device",
+                /* description= */ null,
+                /* state= */ CastDevice.CastState.Connected,
+                /* origin= */ CastDevice.CastOrigin.MediaRouter,
+                /* tag= */ mock(RouteInfo.class));
+        CastDevice projection = new CastDevice(
+                "id2",
+                /* name= */ "Test Projection Device",
+                /* description= */ null,
+                /* state= */ CastDevice.CastState.Connected,
+                /* origin= */ CastDevice.CastOrigin.MediaProjection,
+                /* tag= */ mock(MediaProjectionInfo.class));
 
         List<CastDevice> devices = new ArrayList<>();
         devices.add(casting);
@@ -379,22 +386,27 @@
 
         // Note here that the tile should be active, and should choose casting over projection.
         assertEquals(Tile.STATE_ACTIVE, mCastTile.getState().state);
-        assertTrue(mCastTile.getState().secondaryLabel.toString().startsWith(casting.name));
+        assertTrue(mCastTile.getState().secondaryLabel.toString()
+                .startsWith("Test Casting Device"));
     }
 
     @Test
     public void testUpdateState_connectedAndConnecting() {
         createAndStartTileOldImpl();
-        CastController.CastDevice connecting = new CastController.CastDevice();
-        connecting.state = CastDevice.STATE_CONNECTING;
-        connecting.tag = mock(RouteInfo.class);
-        connecting.name = "Test Casting Device";
-
-        CastController.CastDevice connected = new CastController.CastDevice();
-        connected.state = CastDevice.STATE_CONNECTED;
-        connected.tag = mock(RouteInfo.class);
-        connected.name = "Test Casting Device";
-
+        CastDevice connecting = new CastDevice(
+                "id",
+                /* name= */ "Test Connecting Device",
+                /* description= */ null,
+                /* state= */ CastDevice.CastState.Connecting,
+                /* origin= */ CastDevice.CastOrigin.MediaRouter,
+                /* tag= */ mock(RouteInfo.class));
+        CastDevice connected = new CastDevice(
+                "id",
+                /* name= */ "Test Connected Device",
+                /* description= */ null,
+                /* state= */ CastDevice.CastState.Connected,
+                /* origin= */ CastDevice.CastOrigin.MediaRouter,
+                /* tag= */ mock(RouteInfo.class));
         List<CastDevice> devices = new ArrayList<>();
         devices.add(connecting);
         devices.add(connected);
@@ -404,7 +416,8 @@
 
         // Tile should be connected and always prefer the connected device.
         assertEquals(Tile.STATE_ACTIVE, mCastTile.getState().state);
-        assertTrue(mCastTile.getState().secondaryLabel.toString().startsWith(connected.name));
+        assertTrue(mCastTile.getState().secondaryLabel.toString()
+                .startsWith("Test Connected Device"));
     }
 
     @Test
@@ -427,8 +440,7 @@
     @Test
     public void testExpandView_casting_projection() {
         createAndStartTileOldImpl();
-        CastController.CastDevice device = new CastController.CastDevice();
-        device.state = CastController.CastDevice.STATE_CONNECTED;
+        CastDevice device = createConnectedCastDevice();
         List<CastDevice> devices = new ArrayList<>();
         devices.add(device);
         when(mController.getCastDevices()).thenReturn(devices);
@@ -441,9 +453,14 @@
     @Test
     public void testExpandView_connecting_projection() {
         createAndStartTileOldImpl();
-        CastController.CastDevice connecting = new CastController.CastDevice();
-        connecting.state = CastDevice.STATE_CONNECTING;
-        connecting.name = "Test Casting Device";
+        CastDevice connecting = new CastDevice(
+                "id",
+                /* name= */
+                "Test Projection Device",
+                /* description= */ null,
+                /* state= */ CastDevice.CastState.Connected,
+                /* origin= */ CastDevice.CastOrigin.MediaProjection,
+                /* tag= */ mock(MediaProjectionInfo.class));
 
         List<CastDevice> devices = new ArrayList<>();
         devices.add(connecting);
@@ -457,9 +474,14 @@
     @Test
     public void testExpandView_casting_mediaRoute() {
         createAndStartTileOldImpl();
-        CastController.CastDevice device = new CastController.CastDevice();
-        device.state = CastDevice.STATE_CONNECTED;
-        device.tag = mock(MediaRouter.RouteInfo.class);
+        CastDevice device = new CastDevice(
+                "id",
+                /* name= */ "Test Router Device",
+                /* description= */ null,
+                /* state= */ CastDevice.CastState.Connected,
+                /* origin= */ CastDevice.CastOrigin.MediaRouter,
+                /* tag= */ mock(RouteInfo.class));
+
         List<CastDevice> devices = new ArrayList<>();
         devices.add(device);
         when(mController.getCastDevices()).thenReturn(devices);
@@ -472,11 +494,13 @@
     @Test
     public void testExpandView_connecting_mediaRoute() {
         createAndStartTileOldImpl();
-        CastController.CastDevice connecting = new CastController.CastDevice();
-        connecting.state = CastDevice.STATE_CONNECTING;
-        connecting.tag = mock(RouteInfo.class);
-        connecting.name = "Test Casting Device";
-
+        CastDevice connecting = new CastDevice(
+                "id",
+                /* name= */ "Test Router Device",
+                /* description= */ null,
+                /* state= */ CastDevice.CastState.Connecting,
+                /* origin= */ CastDevice.CastOrigin.MediaRouter,
+                /* tag= */ mock(RouteInfo.class));
         List<CastDevice> devices = new ArrayList<>();
         devices.add(connecting);
         when(mController.getCastDevices()).thenReturn(devices);
@@ -567,4 +591,14 @@
                 hotspotCallbackArgumentCaptor.capture());
         mHotspotCallback = hotspotCallbackArgumentCaptor.getValue();
     }
+
+    private CastDevice createConnectedCastDevice() {
+        return new CastDevice(
+                "id",
+                /* name= */ null,
+                /* description= */ null,
+                /* state= */ CastDevice.CastState.Connected,
+                /* origin= */ CastDevice.CastOrigin.MediaProjection,
+                /* tag= */ null);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
index 0683321..79cb51a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/InternetTileNewImplTest.kt
@@ -20,6 +20,7 @@
 import android.service.quicksettings.Tile
 import android.testing.TestableLooper
 import android.testing.TestableLooper.RunWithLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
 import com.android.systemui.res.R
@@ -54,12 +55,14 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWithLooper(setAsMainLooper = true)
+@RunWith(AndroidJUnit4::class)
 class InternetTileNewImplTest : SysuiTestCase() {
     lateinit var underTest: InternetTileNewImpl
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt
index 42b81de..c918ed8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt
@@ -97,6 +97,7 @@
                 qsTileLogger,
                 FakeSystemClock(),
                 testCoroutineDispatcher,
+                testCoroutineDispatcher,
                 testScope.backgroundScope,
             )
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt
index 6e6e311..e1c3911 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/recents/OverviewProxyServiceTest.kt
@@ -23,6 +23,7 @@
 import android.os.PowerManager
 import android.os.Process
 import android.os.UserHandle
+import android.os.UserManager
 import android.testing.TestableContext
 import android.testing.TestableLooper
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -108,6 +109,7 @@
     @Mock private lateinit var navModeController: NavigationModeController
     @Mock private lateinit var statusBarWinController: NotificationShadeWindowController
     @Mock private lateinit var userTracker: UserTracker
+    @Mock private lateinit var userManager: UserManager
     @Mock private lateinit var uiEventLogger: UiEventLogger
     @Mock private lateinit var sysuiUnlockAnimationController: KeyguardUnlockAnimationController
     @Mock
@@ -199,11 +201,12 @@
     }
 
     @Test
-    fun connectToOverviewService_primaryUser_expectBindService() {
+    fun connectToOverviewService_primaryUserNoVisibleBgUsersSupported_expectBindService() {
         val mockitoSession =
             ExtendedMockito.mockitoSession().spyStatic(Process::class.java).startMocking()
         try {
             `when`(Process.myUserHandle()).thenReturn(UserHandle.SYSTEM)
+            `when`(userManager.isVisibleBackgroundUsersSupported()).thenReturn(false)
             val spyContext = spy(context)
             val ops = createOverviewProxyService(spyContext)
             ops.startConnectionToCurrentUser()
@@ -214,11 +217,46 @@
     }
 
     @Test
-    fun connectToOverviewService_nonPrimaryUser_expectNoBindService() {
+    fun connectToOverviewService_nonPrimaryUserNoVisibleBgUsersSupported_expectNoBindService() {
         val mockitoSession =
             ExtendedMockito.mockitoSession().spyStatic(Process::class.java).startMocking()
         try {
             `when`(Process.myUserHandle()).thenReturn(UserHandle.of(12345))
+            `when`(userManager.isVisibleBackgroundUsersSupported()).thenReturn(false)
+            val spyContext = spy(context)
+            val ops = createOverviewProxyService(spyContext)
+            ops.startConnectionToCurrentUser()
+            verify(spyContext, times(0)).bindServiceAsUser(any(), any(), anyInt(), any())
+        } finally {
+            mockitoSession.finishMocking()
+        }
+    }
+
+    @Test
+    fun connectToOverviewService_nonPrimaryBgUserVisibleBgUsersSupported_expectBindService() {
+        val mockitoSession =
+            ExtendedMockito.mockitoSession().spyStatic(Process::class.java).startMocking()
+        try {
+            `when`(Process.myUserHandle()).thenReturn(UserHandle.of(12345))
+            `when`(userManager.isVisibleBackgroundUsersSupported()).thenReturn(true)
+            `when`(userManager.isUserForeground()).thenReturn(false)
+            val spyContext = spy(context)
+            val ops = createOverviewProxyService(spyContext)
+            ops.startConnectionToCurrentUser()
+            verify(spyContext, atLeast(1)).bindServiceAsUser(any(), any(), anyInt(), any())
+        } finally {
+            mockitoSession.finishMocking()
+        }
+    }
+
+    @Test
+    fun connectToOverviewService_nonPrimaryFgUserVisibleBgUsersSupported_expectNoBindService() {
+        val mockitoSession =
+            ExtendedMockito.mockitoSession().spyStatic(Process::class.java).startMocking()
+        try {
+            `when`(Process.myUserHandle()).thenReturn(UserHandle.of(12345))
+            `when`(userManager.isVisibleBackgroundUsersSupported()).thenReturn(true)
+            `when`(userManager.isUserForeground()).thenReturn(true)
             val spyContext = spy(context)
             val ops = createOverviewProxyService(spyContext)
             ops.startConnectionToCurrentUser()
@@ -242,6 +280,7 @@
             sysUiState,
             mock(),
             userTracker,
+            userManager,
             wakefulnessLifecycle,
             uiEventLogger,
             displayTracker,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt
index 503c52f..ce1a885 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt
@@ -17,7 +17,6 @@
 package com.android.systemui.recordissue
 
 import android.app.Dialog
-import android.content.SharedPreferences
 import android.os.UserHandle
 import android.testing.TestableLooper
 import android.widget.Button
@@ -57,6 +56,7 @@
 import org.mockito.Mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.spy
+import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
@@ -71,7 +71,6 @@
     @Mock private lateinit var mediaProjectionMetricsLogger: MediaProjectionMetricsLogger
     @Mock private lateinit var userTracker: UserTracker
     @Mock private lateinit var state: IssueRecordingState
-    @Mock private lateinit var sharedPreferences: SharedPreferences
     @Mock
     private lateinit var screenCaptureDisabledDialogDelegate: ScreenCaptureDisabledDialogDelegate
     @Mock private lateinit var screenCaptureDisabledDialog: SystemUIDialog
@@ -192,7 +191,7 @@
                 anyInt(),
                 eq(SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER)
             )
-        verify(factory).create(any<ScreenCapturePermissionDialogDelegate>())
+        verify(factory, times(2)).create(any(SystemUIDialog.Delegate::class.java))
     }
 
     @Test
@@ -213,7 +212,7 @@
                 anyInt(),
                 eq(SessionCreationSource.SYSTEM_UI_SCREEN_RECORDER)
             )
-        verify(factory, never()).create(any<ScreenCapturePermissionDialogDelegate>())
+        verify(factory, never()).create()
     }
 
     @Test
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 0d7a9e4..f866f74 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingServiceTest.java
@@ -35,8 +35,8 @@
 import android.os.Handler;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.testing.AndroidTestingRunner;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.UiEventLogger;
@@ -60,7 +60,7 @@
 import java.io.IOException;
 import java.util.concurrent.Executor;
 
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class RecordingServiceTest extends SysuiTestCase {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegateTest.kt
index 9432451..cc8d7d5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegateTest.kt
@@ -18,10 +18,10 @@
 
 import android.content.Intent
 import android.os.UserHandle
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.View
 import android.widget.Spinner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.Dependency
 import com.android.systemui.SysuiTestCase
@@ -55,7 +55,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 class ScreenRecordPermissionDialogDelegateTest : SysuiTestCase() {
 
@@ -109,7 +109,7 @@
     fun testShowDialog_partialScreenSharingEnabled_optionsSpinnerIsVisible() {
         showDialog()
 
-        val visibility = dialog.requireViewById<Spinner>(R.id.screen_share_mode_spinner).visibility
+        val visibility = dialog.requireViewById<Spinner>(R.id.screen_share_mode_options).visibility
         assertThat(visibility).isEqualTo(View.VISIBLE)
     }
 
@@ -155,7 +155,7 @@
     fun showDialog_singleAppIsDefault() {
         showDialog()
 
-        val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_spinner)
+        val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_options)
         val singleApp = context.getString(R.string.screen_share_permission_dialog_option_single_app)
         assertEquals(spinner.adapter.getItem(0), singleApp)
     }
@@ -217,7 +217,7 @@
     }
 
     private fun onSpinnerItemSelected(position: Int) {
-        val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_spinner)
+        val spinner = dialog.requireViewById<Spinner>(R.id.screen_share_mode_options)
         checkNotNull(spinner.onItemSelectedListener)
             .onItemSelected(spinner, mock(), position, /* id= */ 0)
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/data/model/ScreenRecordModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/data/model/ScreenRecordModelTest.kt
new file mode 100644
index 0000000..9331c8d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/data/model/ScreenRecordModelTest.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.screenrecord.data.model
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.screenrecord.data.model.ScreenRecordModel.Starting.Companion.toCountdownSeconds
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+
+@SmallTest
+class ScreenRecordModelTest : SysuiTestCase() {
+    @Test
+    fun countdownSeconds_millis0_is0() {
+        assertThat(0L.toCountdownSeconds()).isEqualTo(0)
+        assertThat(ScreenRecordModel.Starting(0L).countdownSeconds).isEqualTo(0)
+    }
+
+    @Test
+    fun countdownSeconds_millis500_isOne() {
+        assertThat(500L.toCountdownSeconds()).isEqualTo(1)
+        assertThat(ScreenRecordModel.Starting(500L).countdownSeconds).isEqualTo(1)
+    }
+
+    @Test
+    fun countdownSeconds_millis999_isOne() {
+        assertThat(999L.toCountdownSeconds()).isEqualTo(1)
+        assertThat(ScreenRecordModel.Starting(999L).countdownSeconds).isEqualTo(1)
+    }
+
+    @Test
+    fun countdownSeconds_millis1000_isOne() {
+        assertThat(1000L.toCountdownSeconds()).isEqualTo(1)
+        assertThat(ScreenRecordModel.Starting(1000L).countdownSeconds).isEqualTo(1)
+    }
+
+    @Test
+    fun countdownSeconds_millis1499_isOne() {
+        assertThat(1499L.toCountdownSeconds()).isEqualTo(1)
+        assertThat(ScreenRecordModel.Starting(1499L).countdownSeconds).isEqualTo(1)
+    }
+
+    @Test
+    fun countdownSeconds_millis1500_isTwo() {
+        assertThat(1500L.toCountdownSeconds()).isEqualTo(2)
+        assertThat(ScreenRecordModel.Starting(1500L).countdownSeconds).isEqualTo(2)
+    }
+
+    @Test
+    fun countdownSeconds_millis1999_isTwo() {
+        assertThat(1599L.toCountdownSeconds()).isEqualTo(2)
+        assertThat(ScreenRecordModel.Starting(1599L).countdownSeconds).isEqualTo(2)
+    }
+
+    @Test
+    fun countdownSeconds_millis2000_isTwo() {
+        assertThat(2000L.toCountdownSeconds()).isEqualTo(2)
+        assertThat(ScreenRecordModel.Starting(2000L).countdownSeconds).isEqualTo(2)
+    }
+
+    @Test
+    fun countdownSeconds_millis2500_isThree() {
+        assertThat(2500L.toCountdownSeconds()).isEqualTo(3)
+        assertThat(ScreenRecordModel.Starting(2500L).countdownSeconds).isEqualTo(3)
+    }
+
+    @Test
+    fun countdownSeconds_millis2999_isThree() {
+        assertThat(2999L.toCountdownSeconds()).isEqualTo(3)
+        assertThat(ScreenRecordModel.Starting(2999L).countdownSeconds).isEqualTo(3)
+    }
+
+    @Test
+    fun countdownSeconds_millis3000_isThree() {
+        assertThat(3000L.toCountdownSeconds()).isEqualTo(3)
+        assertThat(ScreenRecordModel.Starting(3000L).countdownSeconds).isEqualTo(3)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt
index 61ea437..aceea90 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.screenrecord.data.repository
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
@@ -28,6 +29,7 @@
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.kotlin.argumentCaptor
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.verify
@@ -35,6 +37,7 @@
 
 @SmallTest
 @OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
 class ScreenRecordRepositoryTest : SysuiTestCase() {
     private val kosmos = Kosmos()
     private val testScope = kosmos.testScope
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentCreatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentCreatorTest.kt
index 36639d4..67eaf7b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentCreatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentCreatorTest.kt
@@ -20,6 +20,7 @@
 import android.content.Context
 import android.content.Intent
 import android.net.Uri
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.ext.truth.content.IntentSubject.assertThat as assertThatIntent
 import androidx.test.filters.SmallTest
 import com.android.systemui.res.R
@@ -29,9 +30,11 @@
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mockito.`when` as whenever
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class ActionIntentCreatorTest : SysuiTestCase() {
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentExecutorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentExecutorTest.kt
index 5cd3f66..612d646 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentExecutorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionIntentExecutorTest.kt
@@ -17,9 +17,9 @@
 package com.android.systemui.screenshot
 
 import android.content.Intent
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import android.os.Process.myUserHandle
 import android.platform.test.annotations.EnableFlags
-import android.testing.AndroidTestingRunner
 import android.testing.TestableContext
 import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
@@ -36,7 +36,7 @@
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.verify
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class ActionIntentExecutorTest : SysuiTestCase() {
 
     private val scheduler = TestCoroutineScheduler()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/DefaultScreenshotActionsProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/DefaultScreenshotActionsProviderTest.kt
index 6f5c56e..148a2e5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/DefaultScreenshotActionsProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/DefaultScreenshotActionsProviderTest.kt
@@ -24,6 +24,7 @@
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.screenshot.ui.viewmodel.PreviewAction
 import com.google.common.truth.Truth.assertThat
 import java.util.UUID
 import kotlin.test.Test
@@ -60,9 +61,9 @@
     fun previewActionAccessed_beforeScreenshotCompleted_doesNothing() {
         actionsProvider = createActionsProvider()
 
-        val previewActionCaptor = argumentCaptor<() -> Unit>()
+        val previewActionCaptor = argumentCaptor<PreviewAction>()
         verify(actionsCallback).providePreviewAction(previewActionCaptor.capture())
-        previewActionCaptor.firstValue.invoke()
+        previewActionCaptor.firstValue.onClick.invoke()
         verifyNoMoreInteractions(actionExecutor)
     }
 
@@ -102,14 +103,14 @@
     fun actionAccessed_whilePending_launchesMostRecentAction() = runTest {
         actionsProvider = createActionsProvider()
 
-        val previewActionCaptor = argumentCaptor<() -> Unit>()
+        val previewActionCaptor = argumentCaptor<PreviewAction>()
         verify(actionsCallback).providePreviewAction(previewActionCaptor.capture())
         val actionButtonCaptor = argumentCaptor<() -> Unit>()
         verify(actionsCallback, times(2))
             .provideActionButton(any(), any(), actionButtonCaptor.capture())
 
         actionButtonCaptor.firstValue.invoke()
-        previewActionCaptor.firstValue.invoke()
+        previewActionCaptor.firstValue.onClick.invoke()
         actionButtonCaptor.secondValue.invoke()
         actionsProvider.setCompletedScreenshot(validResult)
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/DraggableConstraintLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/DraggableConstraintLayoutTest.java
index c6ce51a..ba330f7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/DraggableConstraintLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/DraggableConstraintLayoutTest.java
@@ -20,10 +20,10 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.MotionEvent;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -35,7 +35,7 @@
 import org.mockito.MockitoAnnotations;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 public class DraggableConstraintLayoutTest extends SysuiTestCase {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt
index 924b872..b31d21e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt
@@ -4,12 +4,12 @@
 import android.os.UserHandle
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
-import android.testing.AndroidTestingRunner
 import android.view.View
 import android.view.ViewGroup
 import android.widget.FrameLayout
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.constraintlayout.widget.Guideline
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.screenshot.message.LabeledIcon
@@ -31,7 +31,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class MessageContainerControllerTest : SysuiTestCase() {
     lateinit var messageContainer: MessageContainerController
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotActionsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotActionsControllerTest.kt
index 2a3c31a..29e7a8a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotActionsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotActionsControllerTest.kt
@@ -16,9 +16,10 @@
 
 package com.android.systemui.screenshot
 
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.screenshot.ui.viewmodel.PreviewAction
 import com.android.systemui.screenshot.ui.viewmodel.ScreenshotViewModel
 import java.util.UUID
 import kotlin.test.Test
@@ -29,13 +30,13 @@
 import org.mockito.kotlin.never
 import org.mockito.kotlin.verify
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class ScreenshotActionsControllerTest : SysuiTestCase() {
     private val screenshotData = mock<ScreenshotData>()
     private val actionExecutor = mock<ActionExecutor>()
     private val viewModel = mock<ScreenshotViewModel>()
-    private val onClick = mock<() -> Unit>()
+    private val previewAction = PreviewAction("description", onClick = {})
 
     private lateinit var actionsController: ScreenshotActionsController
     private lateinit var fakeActionsProvider1: FakeActionsProvider
@@ -43,6 +44,7 @@
     private val actionsProviderFactory =
         object : ScreenshotActionsProvider.Factory {
             var isFirstCall = true
+
             override fun create(
                 requestId: UUID,
                 request: ScreenshotData,
@@ -69,16 +71,16 @@
     @Test
     fun setPreview_onCurrentScreenshot_updatesViewModel() {
         actionsController.setCurrentScreenshot(screenshotData)
-        fakeActionsProvider1.callPreview(onClick)
+        fakeActionsProvider1.callPreview(previewAction)
 
-        verify(viewModel).setPreviewAction(onClick)
+        verify(viewModel).setPreviewAction(previewAction)
     }
 
     @Test
     fun setPreview_onNonCurrentScreenshot_doesNotUpdateViewModel() {
         actionsController.setCurrentScreenshot(screenshotData)
         actionsController.setCurrentScreenshot(screenshotData)
-        fakeActionsProvider1.callPreview(onClick)
+        fakeActionsProvider1.callPreview(previewAction)
 
         verify(viewModel, never()).setPreviewAction(any())
     }
@@ -87,8 +89,8 @@
         private val actionsCallback: ScreenshotActionsController.ActionsCallback
     ) : ScreenshotActionsProvider {
 
-        fun callPreview(onClick: () -> Unit) {
-            actionsCallback.providePreviewAction(onClick)
+        fun callPreview(previewAction: PreviewAction) {
+            actionsCallback.providePreviewAction(previewAction)
         }
 
         override fun onScrollChipReady(onClick: Runnable) {}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDataTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDataTest.kt
index f8a8a68..3ed0977 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDataTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDataTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.screenshot
 
 import android.content.ComponentName
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import android.graphics.Insets
 import android.graphics.Rect
 import android.os.UserHandle
@@ -25,7 +26,9 @@
 import com.android.internal.util.ScreenshotRequest
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
+import org.junit.runner.RunWith
 
+@RunWith(AndroidJUnit4::class)
 class ScreenshotDataTest {
     private val type = WindowManager.TAKE_SCREENSHOT_FULLSCREEN
     private val source = WindowManager.ScreenshotSource.SCREENSHOT_KEY_OTHER
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
index 2a9aca7..89c13b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotNotificationSmartActionsTest.java
@@ -34,8 +34,8 @@
 import android.net.Uri;
 import android.os.Handler;
 import android.os.UserHandle;
-import android.testing.AndroidTestingRunner;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -50,7 +50,7 @@
 import java.util.concurrent.TimeUnit;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 /**
  * Tests for exception handling and  bitmap configuration in adding smart actions to Screenshot
  * Notification.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotSoundControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotSoundControllerTest.kt
index 92c2404..5987e74 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotSoundControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotSoundControllerTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.screenshot
 
 import android.media.MediaPlayer
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.mock
@@ -29,11 +30,13 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 
 @SmallTest
 @OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
 class ScreenshotSoundControllerTest : SysuiTestCase() {
 
     private val soundProvider = mock<ScreenshotSoundProvider>()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/SmartActionsReceiverTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/SmartActionsReceiverTest.java
index 83c9497..471fdc0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/SmartActionsReceiverTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/SmartActionsReceiverTest.java
@@ -28,8 +28,8 @@
 import android.app.PendingIntent;
 import android.content.Intent;
 import android.os.Bundle;
-import android.testing.AndroidTestingRunner;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -40,7 +40,7 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class SmartActionsReceiverTest extends SysuiTestCase {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt
index bf7d909..0b81b5e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt
@@ -3,7 +3,6 @@
 import android.content.ComponentName
 import android.graphics.Bitmap
 import android.net.Uri
-import android.testing.AndroidTestingRunner
 import android.view.Display
 import android.view.Display.TYPE_EXTERNAL
 import android.view.Display.TYPE_INTERNAL
@@ -12,6 +11,7 @@
 import android.view.Display.TYPE_WIFI
 import android.view.WindowManager
 import android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.internal.util.ScreenshotRequest
@@ -22,7 +22,6 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.kotlinArgumentCaptor as ArgumentCaptor
 import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.nullable
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import java.lang.IllegalStateException
@@ -39,12 +38,11 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyNoMoreInteractions
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class TakeScreenshotExecutorTest : SysuiTestCase() {
 
-    private val controller0 = mock<ScreenshotController>()
-    private val controller1 = mock<ScreenshotController>()
+    private val controller = mock<ScreenshotController>()
     private val notificationsController0 = mock<ScreenshotNotificationsController>()
     private val notificationsController1 = mock<ScreenshotNotificationsController>()
     private val controllerFactory = mock<ScreenshotController.Factory>()
@@ -56,6 +54,7 @@
     private val topComponent = ComponentName(mContext, TakeScreenshotExecutorTest::class.java)
     private val testScope = TestScope(UnconfinedTestDispatcher())
     private val eventLogger = UiEventLoggerFake()
+    private val headlessHandler = mock<HeadlessScreenshotHandler>()
 
     private val screenshotExecutor =
         TakeScreenshotExecutorImpl(
@@ -64,14 +63,13 @@
             testScope,
             requestProcessor,
             eventLogger,
-            notificationControllerFactory
+            notificationControllerFactory,
+            headlessHandler,
         )
 
     @Before
     fun setUp() {
-        whenever(controllerFactory.create(any(), any())).thenAnswer {
-            if (it.getArgument<Display>(0).displayId == 0) controller0 else controller1
-        }
+        whenever(controllerFactory.create(any(), any())).thenReturn(controller)
         whenever(notificationControllerFactory.create(eq(0))).thenReturn(notificationsController0)
         whenever(notificationControllerFactory.create(eq(1))).thenReturn(notificationsController1)
     }
@@ -86,14 +84,14 @@
             screenshotExecutor.executeScreenshots(createScreenshotRequest(), onSaved, callback)
 
             verify(controllerFactory).create(eq(internalDisplay), any())
-            verify(controllerFactory).create(eq(externalDisplay), any())
+            verify(controllerFactory, never()).create(eq(externalDisplay), any())
 
             val capturer = ArgumentCaptor<ScreenshotData>()
 
-            verify(controller0).handleScreenshot(capturer.capture(), any(), any())
+            verify(controller).handleScreenshot(capturer.capture(), any(), any())
             assertThat(capturer.value.displayId).isEqualTo(0)
             // OnSaved callback should be different.
-            verify(controller1).handleScreenshot(capturer.capture(), any(), any())
+            verify(headlessHandler).handleScreenshot(capturer.capture(), any(), any())
             assertThat(capturer.value.displayId).isEqualTo(1)
 
             assertThat(eventLogger.numLogs()).isEqualTo(2)
@@ -125,10 +123,10 @@
 
             val capturer = ArgumentCaptor<ScreenshotData>()
 
-            verify(controller0).handleScreenshot(capturer.capture(), any(), any())
+            verify(controller).handleScreenshot(capturer.capture(), any(), any())
             assertThat(capturer.value.displayId).isEqualTo(0)
             // OnSaved callback should be different.
-            verify(controller1, never()).handleScreenshot(any(), any(), any())
+            verify(headlessHandler, never()).handleScreenshot(any(), any(), any())
 
             assertThat(eventLogger.numLogs()).isEqualTo(1)
             assertThat(eventLogger.get(0).eventId)
@@ -146,13 +144,14 @@
             screenshotExecutor.executeScreenshots(createScreenshotRequest(), onSaved, callback)
 
             verifyNoMoreInteractions(controllerFactory)
+            verify(headlessHandler, never()).handleScreenshot(any(), any(), any())
             screenshotExecutor.onDestroy()
         }
 
     @Test
     fun executeScreenshots_allowedTypes_allCaptured() =
         testScope.runTest {
-            whenever(controllerFactory.create(any(), any())).thenReturn(controller0)
+            whenever(controllerFactory.create(any(), any())).thenReturn(controller)
 
             setDisplays(
                 display(TYPE_INTERNAL, id = 0),
@@ -163,7 +162,8 @@
             val onSaved = { _: Uri? -> }
             screenshotExecutor.executeScreenshots(createScreenshotRequest(), onSaved, callback)
 
-            verify(controller0, times(4)).handleScreenshot(any(), any(), any())
+            verify(controller, times(1)).handleScreenshot(any(), any(), any())
+            verify(headlessHandler, times(3)).handleScreenshot(any(), any(), any())
             screenshotExecutor.onDestroy()
         }
 
@@ -177,8 +177,8 @@
             val capturer0 = ArgumentCaptor<TakeScreenshotService.RequestCallback>()
             val capturer1 = ArgumentCaptor<TakeScreenshotService.RequestCallback>()
 
-            verify(controller0).handleScreenshot(any(), any(), capturer0.capture())
-            verify(controller1).handleScreenshot(any(), any(), capturer1.capture())
+            verify(controller).handleScreenshot(any(), any(), capturer0.capture())
+            verify(headlessHandler).handleScreenshot(any(), any(), capturer1.capture())
 
             verify(callback, never()).onFinish()
 
@@ -202,8 +202,8 @@
             val capturer0 = ArgumentCaptor<TakeScreenshotService.RequestCallback>()
             val capturer1 = ArgumentCaptor<TakeScreenshotService.RequestCallback>()
 
-            verify(controller0).handleScreenshot(any(), any(), capturer0.capture())
-            verify(controller1).handleScreenshot(any(), nullable(), capturer1.capture())
+            verify(controller).handleScreenshot(any(), any(), capturer0.capture())
+            verify(headlessHandler).handleScreenshot(any(), any(), capturer1.capture())
 
             verify(callback, never()).onFinish()
 
@@ -229,8 +229,8 @@
             val capturer0 = ArgumentCaptor<TakeScreenshotService.RequestCallback>()
             val capturer1 = ArgumentCaptor<TakeScreenshotService.RequestCallback>()
 
-            verify(controller0).handleScreenshot(any(), any(), capturer0.capture())
-            verify(controller1).handleScreenshot(any(), any(), capturer1.capture())
+            verify(controller).handleScreenshot(any(), any(), capturer0.capture())
+            verify(headlessHandler).handleScreenshot(any(), any(), capturer1.capture())
 
             verify(callback, never()).onFinish()
 
@@ -254,50 +254,45 @@
             screenshotExecutor.executeScreenshots(createScreenshotRequest(), onSaved, callback)
 
             screenshotExecutor.onDestroy()
-            verify(controller0).onDestroy()
-            verify(controller1).onDestroy()
+            verify(controller).onDestroy()
         }
 
     @Test
-    fun removeWindows_propagatedToControllers() =
+    fun removeWindows_propagatedToController() =
         testScope.runTest {
             setDisplays(display(TYPE_INTERNAL, id = 0), display(TYPE_EXTERNAL, id = 1))
             val onSaved = { _: Uri? -> }
             screenshotExecutor.executeScreenshots(createScreenshotRequest(), onSaved, callback)
 
             screenshotExecutor.removeWindows()
-            verify(controller0).removeWindow()
-            verify(controller1).removeWindow()
+            verify(controller).removeWindow()
 
             screenshotExecutor.onDestroy()
         }
 
     @Test
-    fun onCloseSystemDialogsReceived_propagatedToControllers() =
+    fun onCloseSystemDialogsReceived_propagatedToController() =
         testScope.runTest {
             setDisplays(display(TYPE_INTERNAL, id = 0), display(TYPE_EXTERNAL, id = 1))
             val onSaved = { _: Uri? -> }
             screenshotExecutor.executeScreenshots(createScreenshotRequest(), onSaved, callback)
 
             screenshotExecutor.onCloseSystemDialogsReceived()
-            verify(controller0).requestDismissal(any())
-            verify(controller1).requestDismissal(any())
+            verify(controller).requestDismissal(any())
 
             screenshotExecutor.onDestroy()
         }
 
     @Test
-    fun onCloseSystemDialogsReceived_someControllerHavePendingTransitions() =
+    fun onCloseSystemDialogsReceived_controllerHasPendingTransitions() =
         testScope.runTest {
             setDisplays(display(TYPE_INTERNAL, id = 0), display(TYPE_EXTERNAL, id = 1))
-            whenever(controller0.isPendingSharedTransition).thenReturn(true)
-            whenever(controller1.isPendingSharedTransition).thenReturn(false)
+            whenever(controller.isPendingSharedTransition).thenReturn(true)
             val onSaved = { _: Uri? -> }
             screenshotExecutor.executeScreenshots(createScreenshotRequest(), onSaved, callback)
 
             screenshotExecutor.onCloseSystemDialogsReceived()
-            verify(controller0, never()).requestDismissal(any())
-            verify(controller1).requestDismissal(any())
+            verify(controller, never()).requestDismissal(any())
 
             screenshotExecutor.onDestroy()
         }
@@ -317,7 +312,7 @@
                 .isEqualTo(ScreenshotData.fromRequest(screenshotRequest))
 
             val capturer = ArgumentCaptor<ScreenshotData>()
-            verify(controller0).handleScreenshot(capturer.capture(), any(), any())
+            verify(controller).handleScreenshot(capturer.capture(), any(), any())
             assertThat(capturer.value).isEqualTo(toBeReturnedByProcessor)
 
             screenshotExecutor.onDestroy()
@@ -388,9 +383,9 @@
         testScope.runTest {
             setDisplays(display(TYPE_INTERNAL, id = 0), display(TYPE_EXTERNAL, id = 1))
             val onSaved = { _: Uri? -> }
-            whenever(controller0.handleScreenshot(any(), any(), any()))
+            whenever(controller.handleScreenshot(any(), any(), any()))
                 .thenThrow(IllegalStateException::class.java)
-            whenever(controller1.handleScreenshot(any(), any(), any()))
+            whenever(headlessHandler.handleScreenshot(any(), any(), any()))
                 .thenThrow(IllegalStateException::class.java)
 
             screenshotExecutor.executeScreenshots(createScreenshotRequest(), onSaved, callback)
@@ -408,9 +403,9 @@
         testScope.runTest {
             setDisplays(display(TYPE_INTERNAL, id = 0), display(TYPE_EXTERNAL, id = 1))
             val onSaved = { _: Uri? -> }
-            whenever(controller0.handleScreenshot(any(), any(), any()))
+            whenever(controller.handleScreenshot(any(), any(), any()))
                 .thenThrow(IllegalStateException::class.java)
-            whenever(controller1.handleScreenshot(any(), any(), any()))
+            whenever(headlessHandler.handleScreenshot(any(), any(), any()))
                 .thenThrow(IllegalStateException::class.java)
 
             screenshotExecutor.executeScreenshots(createScreenshotRequest(), onSaved, callback)
@@ -428,9 +423,9 @@
         testScope.runTest {
             setDisplays(display(TYPE_INTERNAL, id = 0), display(TYPE_EXTERNAL, id = 1))
             val onSaved = { _: Uri? -> }
-            whenever(controller0.handleScreenshot(any(), any(), any()))
+            whenever(controller.handleScreenshot(any(), any(), any()))
                 .thenThrow(IllegalStateException::class.java)
-            whenever(controller1.handleScreenshot(any(), any(), any()))
+            whenever(headlessHandler.handleScreenshot(any(), any(), any()))
                 .thenThrow(IllegalStateException::class.java)
 
             screenshotExecutor.executeScreenshots(createScreenshotRequest(), onSaved, callback)
@@ -449,7 +444,7 @@
                 assertThat(it).isNull()
                 onSavedCallCount += 1
             }
-            whenever(controller0.handleScreenshot(any(), any(), any())).thenAnswer {
+            whenever(controller.handleScreenshot(any(), any(), any())).thenAnswer {
                 (it.getArgument(1) as Consumer<Uri?>).accept(null)
             }
 
@@ -478,6 +473,7 @@
         var processed: ScreenshotData? = null
         var toReturn: ScreenshotData? = null
         var shouldThrowException = false
+
         override suspend fun process(screenshot: ScreenshotData): ScreenshotData {
             if (shouldThrowException) throw RequestProcessorException("")
             processed = screenshot
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java
index ebdc49f..7d2d7c45 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java
@@ -30,12 +30,12 @@
 import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.testing.AndroidTestingRunner;
 import android.view.LayoutInflater;
 import android.view.ViewGroup;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -54,7 +54,7 @@
 import java.util.concurrent.TimeUnit;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 public class WorkProfileMessageControllerTest extends SysuiTestCase {
     private static final String FILES_APP_COMPONENT = "com.android.test/.FilesComponent";
     private static final String FILES_APP_LABEL = "Custom Files App";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java
index 68a6893..9986205 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java
@@ -17,6 +17,7 @@
 package com.android.systemui.screenshot.appclips;
 
 import static android.app.Activity.RESULT_OK;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 
 import static com.android.systemui.screenshot.appclips.AppClipsEvent.SCREENSHOT_FOR_NOTE_ACCEPTED;
 import static com.android.systemui.screenshot.appclips.AppClipsEvent.SCREENSHOT_FOR_NOTE_CANCELLED;
@@ -25,30 +26,48 @@
 import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityTaskManager.RootTaskInfo;
+import android.app.IActivityTaskManager;
+import android.app.assist.AssistContent;
+import android.content.ComponentName;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.ApplicationInfoFlags;
+import android.content.pm.ResolveInfo;
 import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.ShapeDrawable;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Process;
+import android.os.RemoteException;
 import android.os.ResultReceiver;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
 import android.testing.AndroidTestingRunner;
 import android.view.Display;
+import android.view.View;
+import android.widget.CheckBox;
 import android.widget.ImageView;
+import android.widget.TextView;
 
 import androidx.test.rule.ActivityTestRule;
 import androidx.test.runner.intercepting.SingleActivityFactory;
 
 import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.res.R;
+import com.android.systemui.screenshot.AssistContentRequester;
 import com.android.systemui.screenshot.ImageExporter;
 import com.android.systemui.settings.UserTracker;
 
@@ -60,9 +79,11 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.List;
 import java.util.UUID;
 import java.util.concurrent.Executor;
 import java.util.function.BiConsumer;
@@ -75,14 +96,30 @@
     private static final Bitmap TEST_BITMAP = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);
     private static final String TEST_URI_STRING = "www.test-uri.com";
     private static final Uri TEST_URI = Uri.parse(TEST_URI_STRING);
-    private static final BiConsumer<Integer, Bundle> FAKE_CONSUMER = (unUsed1, unUsed2) -> {};
+    private static final BiConsumer<Integer, Bundle> FAKE_CONSUMER = (unUsed1, unUsed2) -> {
+    };
     private static final String TEST_CALLING_PACKAGE = "test-calling-package";
+    private static final int BACKLINKS_TASK_ID = 42;
+    private static final String BACKLINKS_TASK_APP_NAME = "Backlinks app";
+    private static final String BACKLINKS_TASK_PACKAGE_NAME = "backlinksTaskPackageName";
+
+    private static final RootTaskInfo TASK_THAT_SUPPORTS_BACKLINKS =
+            createTaskInfoForBacklinksTask();
+    private static final AssistContent ASSIST_CONTENT_FOR_BACKLINKS_TASK =
+            createAssistContentForBacklinksTask();
+    private static final Drawable FAKE_DRAWABLE = new ShapeDrawable();
+
+    private ArgumentCaptor<Integer> mDisplayIdCaptor = ArgumentCaptor.forClass(Integer.class);
 
     @Mock
     private AppClipsCrossProcessHelper mAppClipsCrossProcessHelper;
     @Mock
     private ImageExporter mImageExporter;
     @Mock
+    private IActivityTaskManager mAtmService;
+    @Mock
+    private AssistContentRequester mAssistContentRequester;
+    @Mock
     private PackageManager mPackageManager;
     @Mock
     private UserTracker mUserTracker;
@@ -98,9 +135,10 @@
                 protected AppClipsActivityTestable create(Intent unUsed) {
                     return new AppClipsActivityTestable(
                             new AppClipsViewModel.Factory(mAppClipsCrossProcessHelper,
-                                    mImageExporter, getContext().getMainExecutor(),
-                                    directExecutor()), mPackageManager, mUserTracker,
-                            mUiEventLogger);
+                                    mImageExporter, mAtmService, mAssistContentRequester,
+                                    mPackageManager, getContext().getMainExecutor(),
+                                    directExecutor()),
+                            mPackageManager, mUserTracker, mUiEventLogger);
                 }
             };
 
@@ -118,7 +156,7 @@
         when(mPackageManager.getApplicationInfoAsUser(eq(TEST_CALLING_PACKAGE),
                 any(ApplicationInfoFlags.class), eq(TEST_USER_ID))).thenReturn(applicationInfo);
 
-        when(mAppClipsCrossProcessHelper.takeScreenshot()).thenReturn(TEST_BITMAP);
+        when(mAppClipsCrossProcessHelper.takeScreenshot(anyInt())).thenReturn(TEST_BITMAP);
         ImageExporter.Result result = new ImageExporter.Result();
         result.uri = TEST_URI;
         when(mImageExporter.export(any(Executor.class), any(UUID.class), any(Bitmap.class),
@@ -132,10 +170,15 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_APP_CLIPS_BACKLINKS)
     public void appClipsLaunched_screenshotDisplayed() {
         launchActivity();
 
         assertThat(((ImageView) mActivity.findViewById(R.id.preview)).getDrawable()).isNotNull();
+        assertThat(mActivity.findViewById(R.id.backlinks_data).getVisibility())
+                .isEqualTo(View.GONE);
+        assertThat(mActivity.findViewById(R.id.backlinks_include_data).getVisibility())
+                .isEqualTo(View.GONE);
     }
 
     @Test
@@ -176,6 +219,59 @@
         verify(mUiEventLogger).log(SCREENSHOT_FOR_NOTE_CANCELLED, TEST_UID, TEST_CALLING_PACKAGE);
     }
 
+    @Test
+    @EnableFlags(Flags.FLAG_APP_CLIPS_BACKLINKS)
+    public void appClipsLaunched_backlinks_displayed() throws RemoteException {
+        setUpMocksForBacklinks();
+
+        launchActivity();
+        waitForIdleSync();
+
+        assertThat(mDisplayIdCaptor.getValue()).isEqualTo(mActivity.getDisplayId());
+        TextView backlinksData = mActivity.findViewById(R.id.backlinks_data);
+        assertThat(backlinksData.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(backlinksData.getText().toString()).isEqualTo(BACKLINKS_TASK_APP_NAME);
+        assertThat(backlinksData.getCompoundDrawablesRelative()[0]).isEqualTo(FAKE_DRAWABLE);
+
+        CheckBox backlinksIncludeData = mActivity.findViewById(R.id.backlinks_include_data);
+        assertThat(backlinksIncludeData.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(backlinksIncludeData.getText().toString())
+                .isEqualTo(mActivity.getString(R.string.backlinks_include_link));
+        assertThat(backlinksIncludeData.isChecked()).isTrue();
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_APP_CLIPS_BACKLINKS)
+    public void appClipsLaunched_backlinks_doNotIncludeLink() throws RemoteException {
+        setUpMocksForBacklinks();
+
+        launchActivity();
+        waitForIdleSync();
+        CheckBox backlinksIncludeData = mActivity.findViewById(R.id.backlinks_include_data);
+        runOnMainThread(() -> backlinksIncludeData.performClick());
+        waitForIdleSync();
+
+        assertThat(backlinksIncludeData.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(backlinksIncludeData.isChecked()).isFalse();
+
+        TextView backlinksData = mActivity.findViewById(R.id.backlinks_data);
+        assertThat(backlinksData.getVisibility()).isEqualTo(View.GONE);
+    }
+
+    private void setUpMocksForBacklinks() throws RemoteException {
+        when(mAtmService.getAllRootTaskInfosOnDisplay(mDisplayIdCaptor.capture()))
+                .thenReturn(List.of(TASK_THAT_SUPPORTS_BACKLINKS));
+        doAnswer(invocation -> {
+            AssistContentRequester.Callback callback = invocation.getArgument(1);
+            callback.onAssistContentAvailable(ASSIST_CONTENT_FOR_BACKLINKS_TASK);
+            return null;
+        }).when(mAssistContentRequester).requestAssistContent(eq(BACKLINKS_TASK_ID), any());
+        when(mPackageManager
+                .resolveActivity(any(Intent.class), anyInt()))
+                .thenReturn(createBacklinksTaskResolveInfo());
+        when(mPackageManager.loadItemIcon(any(), any())).thenReturn(FAKE_DRAWABLE);
+    }
+
     private void launchActivity() {
         launchActivity(createResultReceiver(FAKE_CONSUMER));
     }
@@ -203,7 +299,7 @@
         testReceiver.writeToParcel(parcel, 0);
         parcel.setDataPosition(0);
 
-        testReceiver  = ResultReceiver.CREATOR.createFromParcel(parcel);
+        testReceiver = ResultReceiver.CREATOR.createFromParcel(parcel);
         parcel.recycle();
         return testReceiver;
     }
@@ -212,6 +308,37 @@
         mContext.getMainExecutor().execute(runnable);
     }
 
+    private static ResolveInfo createBacklinksTaskResolveInfo() {
+        ActivityInfo activityInfo = new ActivityInfo();
+        activityInfo.applicationInfo = new ApplicationInfo();
+        activityInfo.name = BACKLINKS_TASK_APP_NAME;
+        activityInfo.packageName = BACKLINKS_TASK_PACKAGE_NAME;
+        activityInfo.applicationInfo.packageName = BACKLINKS_TASK_PACKAGE_NAME;
+        ResolveInfo resolveInfo = new ResolveInfo();
+        resolveInfo.activityInfo = activityInfo;
+        return resolveInfo;
+    }
+
+    private static RootTaskInfo createTaskInfoForBacklinksTask() {
+        RootTaskInfo taskInfo = new RootTaskInfo();
+        taskInfo.taskId = BACKLINKS_TASK_ID;
+        taskInfo.isVisible = true;
+        taskInfo.isRunning = true;
+        taskInfo.numActivities = 1;
+        taskInfo.topActivity = new ComponentName(BACKLINKS_TASK_PACKAGE_NAME, "backlinksClass");
+        taskInfo.topActivityInfo = createBacklinksTaskResolveInfo().activityInfo;
+        taskInfo.baseIntent = new Intent().setComponent(taskInfo.topActivity);
+        taskInfo.childTaskIds = new int[]{BACKLINKS_TASK_ID + 1};
+        taskInfo.configuration.windowConfiguration.setActivityType(ACTIVITY_TYPE_STANDARD);
+        return taskInfo;
+    }
+
+    private static AssistContent createAssistContentForBacklinksTask() {
+        AssistContent content = new AssistContent();
+        content.setWebUri(Uri.parse("https://developers.android.com"));
+        return content;
+    }
+
     public static class AppClipsActivityTestable extends AppClipsActivity {
 
         public AppClipsActivityTestable(AppClipsViewModel.Factory viewModelFactory,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java
index 6733ead..809fb3f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java
@@ -26,6 +26,7 @@
 
 import static com.android.internal.infra.AndroidFuture.completedFuture;
 import static com.android.systemui.screenshot.appclips.AppClipsEvent.SCREENSHOT_FOR_NOTE_TRIGGERED;
+import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_CLIP_DATA;
 import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_SCREENSHOT_URI;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -37,6 +38,7 @@
 import static org.mockito.Mockito.when;
 
 import android.app.Activity;
+import android.content.ClipData;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -81,6 +83,7 @@
 
     private static final String TEST_URI_STRING = "www.test-uri.com";
     private static final Uri TEST_URI = Uri.parse(TEST_URI_STRING);
+    private static final ClipData TEST_CLIP_DATA = ClipData.newRawUri("Test backlinks", TEST_URI);
     private static final int TEST_UID = 42;
     private static final String TEST_CALLING_PACKAGE = "test-calling-package";
 
@@ -238,6 +241,7 @@
         Bundle bundle = new Bundle();
         bundle.putParcelable(EXTRA_SCREENSHOT_URI, TEST_URI);
         bundle.putInt(EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE, CAPTURE_CONTENT_FOR_NOTE_SUCCESS);
+        bundle.putParcelable(EXTRA_CLIP_DATA, TEST_CLIP_DATA);
         activity.getResultReceiverForTest().send(Activity.RESULT_OK, bundle);
         waitForIdleSync();
 
@@ -245,7 +249,10 @@
         assertThat(actualResult.getResultCode()).isEqualTo(Activity.RESULT_OK);
         assertThat(getStatusCodeExtra(actualResult.getResultData()))
                 .isEqualTo(CAPTURE_CONTENT_FOR_NOTE_SUCCESS);
-        assertThat(actualResult.getResultData().getData()).isEqualTo(TEST_URI);
+
+        Intent resultData = actualResult.getResultData();
+        assertThat(resultData.getData()).isEqualTo(TEST_URI);
+        assertThat(resultData.getClipData()).isEqualTo(TEST_CLIP_DATA);
         assertThat(mActivityRule.getActivity().isFinishing()).isTrue();
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java
index ad0797c..baf1357 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java
@@ -16,28 +16,51 @@
 
 package com.android.systemui.screenshot.appclips;
 
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.content.ClipDescription.MIMETYPE_TEXT_INTENT;
+import static android.content.ClipDescription.MIMETYPE_TEXT_URILIST;
+import static android.content.Intent.ACTION_MAIN;
+import static android.content.Intent.ACTION_VIEW;
 import static android.content.Intent.CAPTURE_CONTENT_FOR_NOTE_FAILED;
+import static android.content.Intent.CATEGORY_LAUNCHER;
+import static android.view.Display.DEFAULT_DISPLAY;
 
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityTaskManager.RootTaskInfo;
+import android.app.IActivityTaskManager;
+import android.app.assist.AssistContent;
+import android.content.ClipData;
+import android.content.ClipDescription;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.graphics.Bitmap;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.ShapeDrawable;
 import android.net.Uri;
 import android.os.Process;
+import android.os.RemoteException;
 import android.os.UserHandle;
-import android.view.Display;
 
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.screenshot.AssistContentRequester;
 import com.android.systemui.screenshot.ImageExporter;
 
 import com.google.common.util.concurrent.Futures;
@@ -45,9 +68,13 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
@@ -60,27 +87,45 @@
     private static final Rect FAKE_RECT = new Rect();
     private static final Uri FAKE_URI = Uri.parse("www.test-uri.com");
     private static final UserHandle USER_HANDLE = Process.myUserHandle();
+    private static final int BACKLINKS_TASK_ID = 42;
+    private static final String BACKLINKS_TASK_APP_NAME = "Ultimate question app";
+    private static final String BACKLINKS_TASK_PACKAGE_NAME = "backlinksTaskPackageName";
+    private static final AssistContent EMPTY_ASSIST_CONTENT = new AssistContent();
 
     @Mock private AppClipsCrossProcessHelper mAppClipsCrossProcessHelper;
     @Mock private ImageExporter mImageExporter;
+    @Mock private IActivityTaskManager mAtmService;
+    @Mock private AssistContentRequester mAssistContentRequester;
+    @Mock
+    private PackageManager mPackageManager;
+    private ArgumentCaptor<Intent> mPackageManagerIntentCaptor;
     private AppClipsViewModel mViewModel;
 
     @Before
-    public void setUp() {
+    public void setUp() throws RemoteException {
         MockitoAnnotations.initMocks(this);
+        mPackageManagerIntentCaptor = ArgumentCaptor.forClass(Intent.class);
+
+        // Set up mocking for backlinks.
+        when(mAtmService.getAllRootTaskInfosOnDisplay(DEFAULT_DISPLAY))
+                .thenReturn(List.of(createTaskInfoForBacklinksTask()));
+        when(mPackageManager.resolveActivity(mPackageManagerIntentCaptor.capture(), anyInt()))
+                .thenReturn(createBacklinksTaskResolveInfo());
+        when(mPackageManager.loadItemIcon(any(), any())).thenReturn(FAKE_DRAWABLE);
 
         mViewModel = new AppClipsViewModel.Factory(mAppClipsCrossProcessHelper, mImageExporter,
+                mAtmService, mAssistContentRequester, mPackageManager,
                 getContext().getMainExecutor(), directExecutor()).create(AppClipsViewModel.class);
     }
 
     @Test
     public void performScreenshot_fails_shouldUpdateErrorWithFailed() {
-        when(mAppClipsCrossProcessHelper.takeScreenshot()).thenReturn(null);
+        when(mAppClipsCrossProcessHelper.takeScreenshot(anyInt())).thenReturn(null);
 
-        mViewModel.performScreenshot();
+        mViewModel.performScreenshot(DEFAULT_DISPLAY);
         waitForIdleSync();
 
-        verify(mAppClipsCrossProcessHelper).takeScreenshot();
+        verify(mAppClipsCrossProcessHelper).takeScreenshot(DEFAULT_DISPLAY);
         assertThat(mViewModel.getErrorLiveData().getValue())
                 .isEqualTo(CAPTURE_CONTENT_FOR_NOTE_FAILED);
         assertThat(mViewModel.getResultLiveData().getValue()).isNull();
@@ -88,12 +133,12 @@
 
     @Test
     public void performScreenshot_succeeds_shouldUpdateScreenshotWithBitmap() {
-        when(mAppClipsCrossProcessHelper.takeScreenshot()).thenReturn(FAKE_BITMAP);
+        when(mAppClipsCrossProcessHelper.takeScreenshot(DEFAULT_DISPLAY)).thenReturn(FAKE_BITMAP);
 
-        mViewModel.performScreenshot();
+        mViewModel.performScreenshot(DEFAULT_DISPLAY);
         waitForIdleSync();
 
-        verify(mAppClipsCrossProcessHelper).takeScreenshot();
+        verify(mAppClipsCrossProcessHelper).takeScreenshot(DEFAULT_DISPLAY);
         assertThat(mViewModel.getErrorLiveData().getValue()).isNull();
         assertThat(mViewModel.getScreenshot().getValue()).isEqualTo(FAKE_BITMAP);
     }
@@ -101,7 +146,7 @@
     @Test
     public void saveScreenshot_throwsError_shouldUpdateErrorWithFailed() {
         when(mImageExporter.export(any(Executor.class), any(UUID.class), eq(null), eq(USER_HANDLE),
-                eq(Display.DEFAULT_DISPLAY))).thenReturn(
+                eq(DEFAULT_DISPLAY))).thenReturn(
                 Futures.immediateFailedFuture(new ExecutionException(new Throwable())));
 
         mViewModel.saveScreenshotThenFinish(FAKE_DRAWABLE, FAKE_RECT, USER_HANDLE);
@@ -115,7 +160,7 @@
     @Test
     public void saveScreenshot_failsSilently_shouldUpdateErrorWithFailed() {
         when(mImageExporter.export(any(Executor.class), any(UUID.class), eq(null), eq(USER_HANDLE),
-                eq(Display.DEFAULT_DISPLAY))).thenReturn(
+                eq(DEFAULT_DISPLAY))).thenReturn(
                 Futures.immediateFuture(new ImageExporter.Result()));
 
         mViewModel.saveScreenshotThenFinish(FAKE_DRAWABLE, FAKE_RECT, USER_HANDLE);
@@ -131,7 +176,7 @@
         ImageExporter.Result result = new ImageExporter.Result();
         result.uri = FAKE_URI;
         when(mImageExporter.export(any(Executor.class), any(UUID.class), eq(null), eq(USER_HANDLE),
-                eq(Display.DEFAULT_DISPLAY))).thenReturn(Futures.immediateFuture(result));
+                eq(DEFAULT_DISPLAY))).thenReturn(Futures.immediateFuture(result));
 
         mViewModel.saveScreenshotThenFinish(FAKE_DRAWABLE, FAKE_RECT, USER_HANDLE);
         waitForIdleSync();
@@ -139,4 +184,206 @@
         assertThat(mViewModel.getErrorLiveData().getValue()).isNull();
         assertThat(mViewModel.getResultLiveData().getValue()).isEqualTo(FAKE_URI);
     }
+
+    @Test
+    public void triggerBacklinks_shouldUpdateBacklinks_withUri() {
+        Uri expectedUri = Uri.parse("https://developers.android.com");
+        AssistContent contentWithUri = new AssistContent();
+        contentWithUri.setWebUri(expectedUri);
+        doAnswer(invocation -> {
+            AssistContentRequester.Callback callback = invocation.getArgument(1);
+            callback.onAssistContentAvailable(contentWithUri);
+            return null;
+        }).when(mAssistContentRequester).requestAssistContent(eq(BACKLINKS_TASK_ID), any());
+
+        mViewModel.triggerBacklinks(Collections.emptySet(), DEFAULT_DISPLAY);
+        waitForIdleSync();
+
+        Intent queriedIntent = mPackageManagerIntentCaptor.getValue();
+        assertThat(queriedIntent.getData()).isEqualTo(expectedUri);
+        assertThat(queriedIntent.getAction()).isEqualTo(ACTION_VIEW);
+
+        InternalBacklinksData result = mViewModel.getBacklinksLiveData().getValue();
+        assertThat(result.getAppIcon()).isEqualTo(FAKE_DRAWABLE);
+        ClipData clipData = result.getClipData();
+        ClipDescription resultDescription = clipData.getDescription();
+        assertThat(resultDescription.getLabel().toString()).isEqualTo(BACKLINKS_TASK_APP_NAME);
+        assertThat(resultDescription.getMimeType(0)).isEqualTo(MIMETYPE_TEXT_URILIST);
+        assertThat(clipData.getItemCount()).isEqualTo(1);
+        assertThat(clipData.getItemAt(0).getUri()).isEqualTo(expectedUri);
+    }
+
+    @Test
+    public void triggerBacklinks_withNonResolvableUri_usesMainLauncherIntent() {
+        Uri expectedUri = Uri.parse("https://developers.android.com");
+        AssistContent contentWithUri = new AssistContent();
+        contentWithUri.setWebUri(expectedUri);
+        resetPackageManagerMockingForUsingFallbackBacklinks();
+        doAnswer(invocation -> {
+            AssistContentRequester.Callback callback = invocation.getArgument(1);
+            callback.onAssistContentAvailable(contentWithUri);
+            return null;
+        }).when(mAssistContentRequester).requestAssistContent(eq(BACKLINKS_TASK_ID), any());
+
+        mViewModel.triggerBacklinks(Collections.emptySet(), DEFAULT_DISPLAY);
+        waitForIdleSync();
+
+        verifyMainLauncherBacklinksIntent();
+    }
+
+    @Test
+    public void triggerBacklinks_shouldUpdateBacklinks_withAppProvidedIntent() {
+        Intent expectedIntent = new Intent().setPackage(BACKLINKS_TASK_PACKAGE_NAME);
+        AssistContent contentWithAppProvidedIntent = new AssistContent();
+        contentWithAppProvidedIntent.setIntent(expectedIntent);
+        doAnswer(invocation -> {
+            AssistContentRequester.Callback callback = invocation.getArgument(1);
+            callback.onAssistContentAvailable(contentWithAppProvidedIntent);
+            return null;
+        }).when(mAssistContentRequester).requestAssistContent(eq(BACKLINKS_TASK_ID), any());
+
+        mViewModel.triggerBacklinks(Collections.emptySet(), DEFAULT_DISPLAY);
+        waitForIdleSync();
+
+        Intent queriedIntent = mPackageManagerIntentCaptor.getValue();
+        assertThat(queriedIntent.getPackage()).isEqualTo(expectedIntent.getPackage());
+
+        InternalBacklinksData result = mViewModel.getBacklinksLiveData().getValue();
+        assertThat(result.getAppIcon()).isEqualTo(FAKE_DRAWABLE);
+        ClipData clipData = result.getClipData();
+        ClipDescription resultDescription = clipData.getDescription();
+        assertThat(resultDescription.getLabel().toString()).isEqualTo(BACKLINKS_TASK_APP_NAME);
+        assertThat(resultDescription.getMimeType(0)).isEqualTo(MIMETYPE_TEXT_INTENT);
+        assertThat(clipData.getItemCount()).isEqualTo(1);
+        assertThat(clipData.getItemAt(0).getIntent()).isEqualTo(expectedIntent);
+    }
+
+    @Test
+    public void triggerBacklinks_withNonResolvableAppProvidedIntent_usesMainLauncherIntent() {
+        Intent expectedIntent = new Intent().setPackage(BACKLINKS_TASK_PACKAGE_NAME);
+        AssistContent contentWithAppProvidedIntent = new AssistContent();
+        contentWithAppProvidedIntent.setIntent(expectedIntent);
+        resetPackageManagerMockingForUsingFallbackBacklinks();
+        doAnswer(invocation -> {
+            AssistContentRequester.Callback callback = invocation.getArgument(1);
+            callback.onAssistContentAvailable(contentWithAppProvidedIntent);
+            return null;
+        }).when(mAssistContentRequester).requestAssistContent(eq(BACKLINKS_TASK_ID), any());
+
+        mViewModel.triggerBacklinks(Collections.emptySet(), DEFAULT_DISPLAY);
+        waitForIdleSync();
+
+        verifyMainLauncherBacklinksIntent();
+    }
+
+    @Test
+    public void triggerBacklinks_shouldUpdateBacklinks_withMainLauncherIntent() {
+        doAnswer(invocation -> {
+            AssistContentRequester.Callback callback = invocation.getArgument(1);
+            callback.onAssistContentAvailable(EMPTY_ASSIST_CONTENT);
+            return null;
+        }).when(mAssistContentRequester).requestAssistContent(eq(BACKLINKS_TASK_ID), any());
+
+        mViewModel.triggerBacklinks(Collections.emptySet(), DEFAULT_DISPLAY);
+        waitForIdleSync();
+
+        Intent queriedIntent = mPackageManagerIntentCaptor.getValue();
+        assertThat(queriedIntent.getPackage()).isEqualTo(BACKLINKS_TASK_PACKAGE_NAME);
+        assertThat(queriedIntent.getAction()).isEqualTo(ACTION_MAIN);
+        assertThat(queriedIntent.getCategories()).containsExactly(CATEGORY_LAUNCHER);
+
+        verifyMainLauncherBacklinksIntent();
+    }
+
+    @Test
+    public void triggerBacklinks_withNonResolvableMainLauncherIntent_noBacklinksAvailable() {
+        reset(mPackageManager);
+        doAnswer(invocation -> {
+            AssistContentRequester.Callback callback = invocation.getArgument(1);
+            callback.onAssistContentAvailable(EMPTY_ASSIST_CONTENT);
+            return null;
+        }).when(mAssistContentRequester).requestAssistContent(eq(BACKLINKS_TASK_ID), any());
+
+        mViewModel.triggerBacklinks(Collections.emptySet(), DEFAULT_DISPLAY);
+        waitForIdleSync();
+
+        assertThat(mViewModel.getBacklinksLiveData().getValue()).isNull();
+    }
+
+    @Test
+    public void triggerBacklinks_nonStandardActivityIgnored_noBacklinkAvailable()
+            throws RemoteException {
+        reset(mAtmService);
+        RootTaskInfo taskInfo = createTaskInfoForBacklinksTask();
+        taskInfo.configuration.windowConfiguration.setActivityType(ACTIVITY_TYPE_HOME);
+        when(mAtmService.getAllRootTaskInfosOnDisplay(DEFAULT_DISPLAY))
+                .thenReturn(List.of(taskInfo));
+
+        mViewModel.triggerBacklinks(Collections.emptySet(), DEFAULT_DISPLAY);
+        waitForIdleSync();
+
+        assertThat(mViewModel.getBacklinksLiveData().getValue()).isNull();
+    }
+
+    @Test
+    public void triggerBacklinks_taskIdsToIgnoreConsidered_noBacklinkAvailable() {
+        mViewModel.triggerBacklinks(Set.of(BACKLINKS_TASK_ID), DEFAULT_DISPLAY);
+        waitForIdleSync();
+
+        assertThat(mViewModel.getBacklinksLiveData().getValue()).isNull();
+    }
+
+    private void resetPackageManagerMockingForUsingFallbackBacklinks() {
+        reset(mPackageManager);
+        when(mPackageManager.loadItemIcon(any(), any())).thenReturn(FAKE_DRAWABLE);
+        when(mPackageManager.resolveActivity(any(Intent.class), anyInt()))
+                // First the logic queries whether a package has a launcher activity, this should
+                // resolve otherwise the logic filters out the task.
+                .thenReturn(createBacklinksTaskResolveInfo())
+                // Then logic queries with the backlinks intent, this should not resolve for the
+                // logic to use the fallback intent.
+                .thenReturn(null);
+    }
+
+    private void verifyMainLauncherBacklinksIntent() {
+        InternalBacklinksData result = mViewModel.getBacklinksLiveData().getValue();
+        assertThat(result.getAppIcon()).isEqualTo(FAKE_DRAWABLE);
+
+        ClipData clipData = result.getClipData();
+        assertThat(clipData.getItemCount()).isEqualTo(1);
+
+        ClipDescription resultDescription = clipData.getDescription();
+        assertThat(resultDescription.getLabel().toString()).isEqualTo(BACKLINKS_TASK_APP_NAME);
+        assertThat(resultDescription.getMimeType(0)).isEqualTo(MIMETYPE_TEXT_INTENT);
+
+        Intent actualBacklinksIntent = clipData.getItemAt(0).getIntent();
+        assertThat(actualBacklinksIntent.getPackage()).isEqualTo(BACKLINKS_TASK_PACKAGE_NAME);
+        assertThat(actualBacklinksIntent.getAction()).isEqualTo(ACTION_MAIN);
+        assertThat(actualBacklinksIntent.getCategories()).containsExactly(CATEGORY_LAUNCHER);
+    }
+
+    private static ResolveInfo createBacklinksTaskResolveInfo() {
+        ActivityInfo activityInfo = new ActivityInfo();
+        activityInfo.applicationInfo = new ApplicationInfo();
+        activityInfo.name = BACKLINKS_TASK_APP_NAME;
+        activityInfo.packageName = BACKLINKS_TASK_PACKAGE_NAME;
+        activityInfo.applicationInfo.packageName = BACKLINKS_TASK_PACKAGE_NAME;
+        ResolveInfo resolveInfo = new ResolveInfo();
+        resolveInfo.activityInfo = activityInfo;
+        return resolveInfo;
+    }
+
+    private static RootTaskInfo createTaskInfoForBacklinksTask() {
+        RootTaskInfo taskInfo = new RootTaskInfo();
+        taskInfo.taskId = BACKLINKS_TASK_ID;
+        taskInfo.isVisible = true;
+        taskInfo.isRunning = true;
+        taskInfo.numActivities = 1;
+        taskInfo.topActivity = new ComponentName(BACKLINKS_TASK_PACKAGE_NAME, "backlinksClass");
+        taskInfo.topActivityInfo = createBacklinksTaskResolveInfo().activityInfo;
+        taskInfo.baseIntent = new Intent().setComponent(taskInfo.topActivity);
+        taskInfo.childTaskIds = new int[]{BACKLINKS_TASK_ID + 1};
+        taskInfo.configuration.windowConfiguration.setActivityType(ACTIVITY_TYPE_STANDARD);
+        return taskInfo;
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/message/ProfileMessageControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/message/ProfileMessageControllerTest.kt
index ce2facd..6b9865f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/message/ProfileMessageControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/message/ProfileMessageControllerTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.screenshot.message
 
 import android.content.ComponentName
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import android.content.pm.PackageManager
 import android.graphics.Canvas
 import android.graphics.ColorFilter
@@ -27,7 +28,9 @@
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
+import org.junit.runner.RunWith
 
+@RunWith(AndroidJUnit4::class)
 class ProfileMessageControllerTest {
     @Test
     fun personalScreenshot() = runTest {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PolicyRequestProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PolicyRequestProcessorTest.kt
index 4945ace..3b0e194 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PolicyRequestProcessorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PolicyRequestProcessorTest.kt
@@ -16,6 +16,7 @@
 package com.android.systemui.screenshot.policy
 
 import android.content.ComponentName
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import android.graphics.Insets
 import android.graphics.Rect
 import android.os.UserHandle
@@ -34,7 +35,9 @@
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.runBlocking
 import org.junit.Test
+import org.junit.runner.RunWith
 
+@RunWith(AndroidJUnit4::class)
 class PolicyRequestProcessorTest {
 
     val imageCapture = object : ImageCapture {
@@ -78,4 +81,4 @@
         assertWithMessage("The topComponent of the screenshot").that(result.topComponent)
                 .isEqualTo(ComponentName.unflattenFromString(FILES))
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PrivateProfilePolicyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PrivateProfilePolicyTest.kt
index 9e3ae05..6e57761 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PrivateProfilePolicyTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/PrivateProfilePolicyTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.screenshot.policy
 
 import android.content.ComponentName
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import android.os.UserHandle
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.screenshot.data.model.DisplayContentModel
@@ -40,7 +41,9 @@
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
+import org.junit.runner.RunWith
 
+@RunWith(AndroidJUnit4::class)
 class PrivateProfilePolicyTest {
     private val kosmos = Kosmos()
     private val policy = PrivateProfilePolicy(kosmos.profileTypeRepository)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/WorkProfilePolicyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/WorkProfilePolicyTest.kt
index 5d35528..8d217fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/WorkProfilePolicyTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/policy/WorkProfilePolicyTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.screenshot.policy
 
 import android.content.ComponentName
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import android.os.UserHandle
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
@@ -50,7 +51,9 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Rule
 import org.junit.Test
+import org.junit.runner.RunWith
 
+@RunWith(AndroidJUnit4::class)
 class WorkProfilePolicyTest {
     @JvmField @Rule val setFlagsRule = SetFlagsRule()
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/scroll/FakeSessionTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/scroll/FakeSessionTest.java
index aad46139..88cb00c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/scroll/FakeSessionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/scroll/FakeSessionTest.java
@@ -23,8 +23,8 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
-import android.testing.AndroidTestingRunner;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -39,7 +39,7 @@
  * client/connection.
  */
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 public class FakeSessionTest extends SysuiTestCase {
     @Test
     public void testNonEmptyResult_hasImage() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/scroll/ScrollCaptureControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/scroll/ScrollCaptureControllerTest.java
index f39f543..f8de714 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/scroll/ScrollCaptureControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/scroll/ScrollCaptureControllerTest.java
@@ -29,9 +29,9 @@
 import static java.lang.Math.abs;
 
 import android.content.Context;
-import android.testing.AndroidTestingRunner;
 import android.view.ScrollCaptureResponse;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.testing.UiEventLoggerFake;
@@ -46,7 +46,7 @@
  * screenshots.
  */
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 public class ScrollCaptureControllerTest extends SysuiTestCase {
 
     private static final ScrollCaptureResponse EMPTY_RESPONSE =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModelTest.kt
index e32086b..e39e0fb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModelTest.kt
@@ -17,12 +17,15 @@
 package com.android.systemui.screenshot.ui.viewmodel
 
 import android.view.accessibility.AccessibilityManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mockito.mock
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class ScreenshotViewModelTest {
     private val accessibilityManager: AccessibilityManager = mock(AccessibilityManager::class.java)
     private val appearance = ActionButtonAppearance(null, "Label", "Description")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scrim/ScrimViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/scrim/ScrimViewTest.java
index a345f78..ca8da63 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scrim/ScrimViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/scrim/ScrimViewTest.java
@@ -22,12 +22,12 @@
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
 import android.testing.ViewUtils;
 import android.view.View;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.colorextraction.ColorExtractor;
@@ -38,7 +38,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class ScrimViewTest extends LeakCheckedTest {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/sensorprivacy/SensorUseStartedActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/sensorprivacy/SensorUseStartedActivityTest.kt
index 333e634..1a4749c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/sensorprivacy/SensorUseStartedActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/sensorprivacy/SensorUseStartedActivityTest.kt
@@ -1,8 +1,8 @@
 package com.android.systemui.sensorprivacy
 
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import androidx.test.ext.junit.rules.ActivityScenarioRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.mock
@@ -11,7 +11,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 @TestableLooper.RunWithLooper
 class SensorUseStartedActivityTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessControllerTest.kt
index 2b78405..98260d8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessControllerTest.kt
@@ -19,9 +19,9 @@
 import android.hardware.display.DisplayManager
 import android.os.Handler
 import android.service.vr.IVrManager
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.testing.TestableLooper.RunWithLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.settings.DisplayTracker
@@ -40,7 +40,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @RunWithLooper
 class BrightnessControllerTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt
index 31acd86..a06784e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessDialogTest.kt
@@ -18,11 +18,11 @@
 
 import android.content.Intent
 import android.graphics.Rect
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.View
 import android.view.ViewGroup
 import android.view.WindowManagerPolicyConstants.EXTRA_FROM_BRIGHTNESS_KEY
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.FlakyTest
 import androidx.test.filters.SmallTest
 import androidx.test.rule.ActivityTestRule
@@ -55,7 +55,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
 class BrightnessDialogTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
index 2b3588a..c7bea59 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
@@ -16,11 +16,11 @@
 
 package com.android.systemui.shade
 
-import android.testing.AndroidTestingRunner
 import android.view.ViewGroup
 import androidx.constraintlayout.widget.ConstraintSet
 import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
 import androidx.constraintlayout.widget.ConstraintSet.START
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
@@ -33,7 +33,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class CombinedShadeHeaderConstraintsTest : SysuiTestCase() {
 
     private lateinit var qqsConstraint: ConstraintSet
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangeTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangeTest.kt
index 9b2e085..8c80835 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangeTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangeTest.kt
@@ -15,8 +15,8 @@
  */
 package com.android.systemui.shade
 
-import android.testing.AndroidTestingRunner
 import androidx.constraintlayout.widget.ConstraintSet
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.mock
@@ -27,7 +27,7 @@
 import org.mockito.Mockito.verify
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class ConstraintChangeTest : SysuiTestCase() {
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangesTest.kt
index 0abb084..05c1706 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ConstraintChangesTest.kt
@@ -15,8 +15,8 @@
  */
 package com.android.systemui.shade
 
-import android.testing.AndroidTestingRunner
 import androidx.constraintlayout.widget.ConstraintSet
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.mock
@@ -26,7 +26,7 @@
 import org.mockito.Mockito.inOrder
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class ConstraintChangesTest : SysuiTestCase() {
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
index b8267a0..169511f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.shade
 
+import android.graphics.Insets
 import android.graphics.Rect
 import android.os.PowerManager
 import android.platform.test.annotations.DisableFlags
@@ -25,14 +26,14 @@
 import android.testing.ViewUtils
 import android.view.MotionEvent
 import android.view.View
+import android.view.WindowInsets
 import android.widget.FrameLayout
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleOwner
 import androidx.test.filters.SmallTest
-import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.compose.animation.scene.SceneKey
 import com.android.systemui.Flags
-import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE
+import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_BACK_GESTURE
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.ambient.touch.TouchHandler
 import com.android.systemui.ambient.touch.TouchMonitor
@@ -56,10 +57,8 @@
 import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.statusbar.notification.stack.notificationStackScrollLayoutController
 import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.any
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
@@ -70,10 +69,11 @@
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.anyFloat
 import org.mockito.Mock
-import org.mockito.Mockito.times
-import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
 
 @ExperimentalCoroutinesApi
 @RunWith(AndroidTestingRunner::class)
@@ -184,133 +184,6 @@
             }
         }
 
-    @DisableFlags(FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE)
-    @Test
-    fun onTouchEvent_communalClosed_doesNotIntercept() =
-        with(kosmos) {
-            testScope.runTest {
-                // Communal is closed.
-                goToScene(CommunalScenes.Blank)
-
-                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
-            }
-        }
-
-    @DisableFlags(FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE)
-    @Test
-    fun onTouchEvent_openGesture_interceptsTouches() =
-        with(kosmos) {
-            testScope.runTest {
-                // Communal is closed.
-                goToScene(CommunalScenes.Blank)
-
-                // Initial touch down is intercepted, and so are touches outside of the region,
-                // until an
-                // up event is received.
-                assertThat(underTest.onTouchEvent(DOWN_IN_RIGHT_SWIPE_REGION_EVENT)).isTrue()
-                assertThat(underTest.onTouchEvent(MOVE_EVENT)).isTrue()
-                assertThat(underTest.onTouchEvent(UP_EVENT)).isTrue()
-                assertThat(underTest.onTouchEvent(MOVE_EVENT)).isFalse()
-            }
-        }
-
-    @DisableFlags(FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE)
-    @Test
-    fun onTouchEvent_communalTransitioning_interceptsTouches() =
-        with(kosmos) {
-            testScope.runTest {
-                // Communal is opening.
-                communalRepository.setTransitionState(
-                    flowOf(
-                        ObservableTransitionState.Transition(
-                            fromScene = CommunalScenes.Blank,
-                            toScene = CommunalScenes.Communal,
-                            currentScene = flowOf(CommunalScenes.Blank),
-                            progress = flowOf(0.5f),
-                            isInitiatedByUserInput = true,
-                            isUserInputOngoing = flowOf(true)
-                        )
-                    )
-                )
-                testableLooper.processAllMessages()
-
-                // Touch events are intercepted.
-                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isTrue()
-                // User activity sent to PowerManager.
-                verify(powerManager).userActivity(any(), any(), any())
-            }
-        }
-
-    @DisableFlags(FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE)
-    @Test
-    fun onTouchEvent_communalOpen_interceptsTouches() =
-        with(kosmos) {
-            testScope.runTest {
-                // Communal is open.
-                goToScene(CommunalScenes.Communal)
-
-                // Touch events are intercepted.
-                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isTrue()
-                // User activity sent to PowerManager.
-                verify(powerManager).userActivity(any(), any(), any())
-            }
-        }
-
-    @DisableFlags(FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE)
-    @Test
-    fun onTouchEvent_communalAndBouncerShowing_doesNotIntercept() =
-        with(kosmos) {
-            testScope.runTest {
-                // Communal is open.
-                goToScene(CommunalScenes.Communal)
-
-                // Bouncer is visible.
-                fakeKeyguardBouncerRepository.setPrimaryShow(true)
-                testableLooper.processAllMessages()
-
-                // Touch events are not intercepted.
-                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
-                // User activity is not sent to PowerManager.
-                verify(powerManager, times(0)).userActivity(any(), any(), any())
-            }
-        }
-
-    @DisableFlags(FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE)
-    @Test
-    fun onTouchEvent_communalAndShadeShowing_doesNotIntercept() =
-        with(kosmos) {
-            testScope.runTest {
-                // Communal is open.
-                goToScene(CommunalScenes.Communal)
-
-                // Shade shows up.
-                shadeTestUtil.setQsExpansion(1.0f)
-                testableLooper.processAllMessages()
-
-                // Touch events are not intercepted.
-                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
-            }
-        }
-
-    @DisableFlags(FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE)
-    @Test
-    fun onTouchEvent_containerViewDisposed_doesNotIntercept() =
-        with(kosmos) {
-            testScope.runTest {
-                // Communal is open.
-                goToScene(CommunalScenes.Communal)
-
-                // Touch events are intercepted.
-                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isTrue()
-
-                // Container view disposed.
-                underTest.disposeView()
-
-                // Touch events are not intercepted.
-                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
-            }
-        }
-
     @Test
     fun lifecycle_initializedAfterConstruction() =
         with(kosmos) {
@@ -452,6 +325,7 @@
         }
 
     @Test
+    @DisableFlags(FLAG_GLANCEABLE_HUB_BACK_GESTURE)
     fun gestureExclusionZone_setAfterInit() =
         with(kosmos) {
             testScope.runTest {
@@ -460,10 +334,41 @@
                 assertThat(containerView.systemGestureExclusionRects)
                     .containsExactly(
                         Rect(
-                            /* left */ 0,
-                            /* top */ TOP_SWIPE_REGION_WIDTH,
-                            /* right */ CONTAINER_WIDTH,
-                            /* bottom */ CONTAINER_HEIGHT - BOTTOM_SWIPE_REGION_WIDTH
+                            /* left= */ 0,
+                            /* top= */ TOP_SWIPE_REGION_WIDTH,
+                            /* right= */ CONTAINER_WIDTH,
+                            /* bottom= */ CONTAINER_HEIGHT - BOTTOM_SWIPE_REGION_WIDTH
+                        ),
+                        Rect(
+                            /* left= */ 0,
+                            /* top= */ 0,
+                            /* right= */ 0,
+                            /* bottom= */ CONTAINER_HEIGHT
+                        )
+                    )
+            }
+        }
+
+    @Test
+    @EnableFlags(FLAG_GLANCEABLE_HUB_BACK_GESTURE)
+    fun gestureExclusionZone_setAfterInit_backGestureEnabled() =
+        with(kosmos) {
+            testScope.runTest {
+                goToScene(CommunalScenes.Communal)
+
+                assertThat(containerView.systemGestureExclusionRects)
+                    .containsExactly(
+                        Rect(
+                            /* left= */ FAKE_INSETS.left,
+                            /* top= */ TOP_SWIPE_REGION_WIDTH,
+                            /* right= */ CONTAINER_WIDTH - FAKE_INSETS.right,
+                            /* bottom= */ CONTAINER_HEIGHT - BOTTOM_SWIPE_REGION_WIDTH
+                        ),
+                        Rect(
+                            /* left= */ 0,
+                            /* top= */ 0,
+                            /* right= */ FAKE_INSETS.right,
+                            /* bottom= */ CONTAINER_HEIGHT
                         )
                     )
             }
@@ -475,6 +380,9 @@
             testScope.runTest {
                 goToScene(CommunalScenes.Communal)
 
+                // Exclusion rect is set.
+                assertThat(containerView.systemGestureExclusionRects).isNotEmpty()
+
                 // Shade shows up.
                 shadeTestUtil.setQsExpansion(1.0f)
                 testableLooper.processAllMessages()
@@ -490,6 +398,9 @@
             testScope.runTest {
                 goToScene(CommunalScenes.Communal)
 
+                // Exclusion rect is set.
+                assertThat(containerView.systemGestureExclusionRects).isNotEmpty()
+
                 // Bouncer is visible.
                 fakeKeyguardBouncerRepository.setPrimaryShow(true)
                 testableLooper.processAllMessages()
@@ -506,7 +417,7 @@
                 goToScene(CommunalScenes.Communal)
 
                 // Exclusion rect is set.
-                assertThat(containerView.systemGestureExclusionRects).hasSize(1)
+                assertThat(containerView.systemGestureExclusionRects).isNotEmpty()
 
                 // Leave the hub.
                 goToScene(CommunalScenes.Blank)
@@ -517,7 +428,6 @@
         }
 
     @Test
-    @EnableFlags(FLAG_GLANCEABLE_HUB_FULLSCREEN_SWIPE)
     fun fullScreenSwipeGesture_doNotProcessTouchesInNotificationStack() =
         with(kosmos) {
             testScope.runTest {
@@ -535,7 +445,12 @@
         }
 
     private fun initAndAttachContainerView() {
-        containerView = View(context)
+        val mockInsets =
+            mock<WindowInsets> {
+                on { getInsets(WindowInsets.Type.systemGestures()) } doReturn FAKE_INSETS
+            }
+
+        containerView = spy(View(context)) { on { rootWindowInsets } doReturn mockInsets }
 
         parentView = FrameLayout(context)
 
@@ -558,6 +473,7 @@
         private const val RIGHT_SWIPE_REGION_WIDTH = 20
         private const val TOP_SWIPE_REGION_WIDTH = 12
         private const val BOTTOM_SWIPE_REGION_WIDTH = 14
+        private val FAKE_INSETS = Insets.of(10, 20, 30, 50)
 
         /**
          * A touch down event right in the middle of the screen, to avoid being in any of the swipe
@@ -572,9 +488,5 @@
                 CONTAINER_HEIGHT.toFloat() / 2,
                 0
             )
-        private val DOWN_IN_RIGHT_SWIPE_REGION_EVENT =
-            MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, CONTAINER_WIDTH.toFloat(), 0f, 0)
-        private val MOVE_EVENT = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)
-        private val UP_EVENT = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_UP, 0f, 0f, 0)
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LockscreenHostedDreamGestureListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LockscreenHostedDreamGestureListenerTest.kt
index b4f890b..2ac0ed0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/LockscreenHostedDreamGestureListenerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LockscreenHostedDreamGestureListenerTest.kt
@@ -17,8 +17,8 @@
 package com.android.systemui.shade
 
 import android.os.PowerManager
-import android.testing.AndroidTestingRunner
 import android.view.MotionEvent
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
@@ -47,7 +47,7 @@
 
 @SmallTest
 @OptIn(ExperimentalCoroutinesApi::class)
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class LockscreenHostedDreamGestureListenerTest : SysuiTestCase() {
     @Mock private lateinit var falsingManager: FalsingManager
     @Mock private lateinit var falsingCollector: FalsingCollector
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt
index bff408a..abc96ee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationControllerTest.kt
@@ -16,9 +16,9 @@
 
 package com.android.systemui.shade
 
-import android.testing.AndroidTestingRunner
 import android.view.View
 import android.view.ViewGroup
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
@@ -46,7 +46,7 @@
  * the set of ids, which also dictact which direction to move and when, via a filter fn.
  */
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class NotificationPanelUnfoldAnimationControllerTest : SysuiTestCase() {
 
     @Mock private lateinit var progressProvider: NaturalRotationUnfoldProgressProvider
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index c3cedf8..b80d1a4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -111,7 +111,7 @@
 import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingLockscreenHostedTransitionViewModel;
 import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingTransitionViewModel;
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardTouchHandlingViewModel;
 import com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel;
 import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel;
 import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel;
@@ -334,7 +334,7 @@
     @Mock protected PrimaryBouncerToGoneTransitionViewModel
             mPrimaryBouncerToGoneTransitionViewModel;
     @Mock protected KeyguardTransitionInteractor mKeyguardTransitionInteractor;
-    @Mock protected KeyguardLongPressViewModel mKeyuardLongPressViewModel;
+    @Mock protected KeyguardTouchHandlingViewModel mKeyuardTouchHandlingViewModel;
     @Mock protected AlternateBouncerInteractor mAlternateBouncerInteractor;
     @Mock protected MotionEvent mDownMotionEvent;
     @Mock protected CoroutineDispatcher mMainDispatcher;
@@ -419,7 +419,7 @@
         mShadeAnimationInteractor = new ShadeAnimationInteractorLegacyImpl(
                 new ShadeAnimationRepository(), mShadeRepository);
         mPowerInteractor = keyguardInteractorDeps.getPowerInteractor();
-        when(mKeyguardTransitionInteractor.isInTransitionToStateWhere(any())).thenReturn(
+        when(mKeyguardTransitionInteractor.isInTransitionWhere(any(), any())).thenReturn(
                 MutableStateFlow(false));
         when(mKeyguardTransitionInteractor.isInTransition(any(), any()))
                 .thenReturn(emptyFlow());
@@ -438,6 +438,7 @@
                 mFakeKeyguardRepository,
                 mKeyguardTransitionInteractor,
                 mPowerInteractor,
+                mShadeRepository,
                 new FakeUserSetupRepository(),
                 mock(UserSwitcherInteractor.class),
                 new ShadeInteractorLegacyImpl(
@@ -463,6 +464,7 @@
                 () -> mShadeInteractor,
                 () -> mKosmos.getDeviceUnlockedInteractor(),
                 () -> mKosmos.getSceneInteractor(),
+                () -> mKosmos.getSceneContainerOcclusionInteractor(),
                 () -> mKosmos.getKeyguardClockInteractor());
 
         KeyguardStatusView keyguardStatusView = new KeyguardStatusView(mContext);
@@ -620,6 +622,7 @@
                                 () -> mShadeInteractor,
                                 () -> mKosmos.getDeviceUnlockedInteractor(),
                                 () -> mKosmos.getSceneInteractor(),
+                                () -> mKosmos.getSceneContainerOcclusionInteractor(),
                                 () -> mKosmos.getKeyguardClockInteractor()),
                         mKeyguardBypassController,
                         mDozeParameters,
@@ -752,7 +755,7 @@
                 mMainDispatcher,
                 mKeyguardTransitionInteractor,
                 mDumpManager,
-                mKeyuardLongPressViewModel,
+                mKeyuardTouchHandlingViewModel,
                 mKeyguardInteractor,
                 mActivityStarter,
                 mSharedNotificationContainerInteractor,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index 6536405..90e8ea5f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -18,7 +18,6 @@
 
 import static com.android.keyguard.KeyguardClockSwitch.LARGE;
 import static com.android.keyguard.KeyguardClockSwitch.SMALL;
-import static com.android.systemui.Flags.FLAG_SHADE_COLLAPSE_ACTIVITY_LAUNCH_FIX;
 import static com.android.systemui.shade.ShadeExpansionStateManagerKt.STATE_CLOSED;
 import static com.android.systemui.shade.ShadeExpansionStateManagerKt.STATE_OPEN;
 import static com.android.systemui.shade.ShadeExpansionStateManagerKt.STATE_OPENING;
@@ -49,13 +48,13 @@
 import android.os.PowerManager;
 import android.platform.test.annotations.DisableFlags;
 import android.platform.test.annotations.EnableFlags;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.accessibility.AccessibilityNodeInfo;
 
 import androidx.constraintlayout.widget.ConstraintSet;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.DejankUtils;
@@ -80,7 +79,7 @@
 import java.util.List;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 public class NotificationPanelViewControllerTest extends NotificationPanelViewControllerBaseTest {
 
@@ -679,32 +678,6 @@
     }
 
     @Test
-    @EnableFlags(FLAG_SHADE_COLLAPSE_ACTIVITY_LAUNCH_FIX)
-    public void testCanBeCollapsed_expandedInKeyguard() {
-        mStatusBarStateController.setState(KEYGUARD);
-        mNotificationPanelViewController.setExpandedFraction(1f);
-
-        assertThat(mNotificationPanelViewController.canBeCollapsed()).isFalse();
-    }
-
-    @Test
-    @EnableFlags(FLAG_SHADE_COLLAPSE_ACTIVITY_LAUNCH_FIX)
-    public void testCanBeCollapsed_expandedInShade() {
-        mStatusBarStateController.setState(SHADE);
-        mNotificationPanelViewController.setExpandedFraction(1f);
-        assertThat(mNotificationPanelViewController.canBeCollapsed()).isTrue();
-    }
-
-    @Test
-    @DisableFlags(FLAG_SHADE_COLLAPSE_ACTIVITY_LAUNCH_FIX)
-    public void testCanBeCollapsed_expandedInKeyguard_flagDisabled() {
-        mStatusBarStateController.setState(KEYGUARD);
-        mNotificationPanelViewController.setExpandedFraction(1f);
-
-        assertThat(mNotificationPanelViewController.canBeCollapsed()).isTrue();
-    }
-
-    @Test
     @Ignore("b/341163515 - fails to clean up animators correctly")
     public void testSwipeWhileLocked_notifiesKeyguardState() {
         mStatusBarStateController.setState(KEYGUARD);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt
index d47bd47..e1d92e7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerWithCoroutinesTest.kt
@@ -19,11 +19,11 @@
 package com.android.systemui.shade
 
 import android.platform.test.annotations.EnableFlags
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.HapticFeedbackConstants
 import android.view.View
 import android.view.ViewStub
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.util.CollectionUtils
 import com.android.keyguard.KeyguardClockSwitch.LARGE
@@ -55,7 +55,7 @@
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 @SmallTest
 class NotificationPanelViewControllerWithCoroutinesTest :
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
index 31bd12f..fec7424 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
@@ -16,10 +16,10 @@
 package com.android.systemui.shade
 
 import android.os.SystemClock
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
 import android.view.MotionEvent
 import android.widget.FrameLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardSecurityContainerController
 import com.android.keyguard.LegacyLockIconViewController
@@ -82,7 +82,7 @@
 import org.mockito.MockitoAnnotations
 
 @ExperimentalCoroutinesApi
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @RunWithLooper(setAsMainLooper = true)
 @SmallTest
 class NotificationShadeWindowViewTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt
index 0c3af03..97ce37c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationsQuickSettingsContainerTest.kt
@@ -16,11 +16,11 @@
 
 package com.android.systemui.shade
 
-import android.testing.AndroidTestingRunner
 import android.view.View
 import android.view.ViewGroup
 import android.widget.FrameLayout
 import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.qs.QSFragmentLegacy
@@ -34,7 +34,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class NotificationsQuickSettingsContainerTest : SysuiTestCase() {
 
     @Mock private lateinit var qsFrame: View
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt
index 3900def..effd28ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt
@@ -20,9 +20,9 @@
 import android.os.PowerManager
 import android.provider.Settings.Secure.DOZE_DOUBLE_TAP_GESTURE
 import android.provider.Settings.Secure.DOZE_TAP_SCREEN_GESTURE
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
 import android.view.MotionEvent
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dock.DockManager
@@ -49,7 +49,7 @@
 import org.mockito.MockitoAnnotations
 import org.mockito.Mockito.`when` as whenever
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @RunWithLooper(setAsMainLooper = true)
 @SmallTest
 class PulsingGestureListenerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt
index 2cd740d..f38bf13 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QsBatteryModeControllerTest.kt
@@ -3,8 +3,8 @@
 import android.content.Context
 import android.content.res.Resources
 import android.graphics.Rect
-import android.testing.AndroidTestingRunner
 import android.view.DisplayCutout
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
@@ -21,7 +21,7 @@
 import org.mockito.junit.MockitoJUnit
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class QsBatteryModeControllerTest : SysuiTestCase() {
 
     private companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
index 85541aa..06a883c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplBaseTest.java
@@ -218,6 +218,7 @@
                 mKeyguardRepository,
                 keyguardTransitionInteractor,
                 powerInteractor,
+                mShadeRepository,
                 new FakeUserSetupRepository(),
                 mUserSwitcherInteractor,
                 new ShadeInteractorLegacyImpl(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplTest.java
index ad4b4fd..9a6423d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplTest.java
@@ -36,10 +36,10 @@
 import static org.mockito.Mockito.when;
 
 import android.platform.test.annotations.EnableFlags;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.MotionEvent;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.plugins.qs.QS;
@@ -53,7 +53,7 @@
 import java.util.List;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 public class QuickSettingsControllerImplTest extends QuickSettingsControllerImplBaseTest {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplWithCoroutinesTest.kt
index dfd7a71..46961d4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerImplWithCoroutinesTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.shade
 
 import android.app.StatusBarManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.statusbar.disableflags.data.model.DisableFlagsModel
 import com.google.common.truth.Truth.assertThat
@@ -25,9 +26,11 @@
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
 @OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
 class QuickSettingsControllerImplWithCoroutinesTest : QuickSettingsControllerImplBaseTest() {
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
index 6bdd3ef..0217238 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
@@ -16,10 +16,10 @@
 
 package com.android.systemui.shade
 
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
 import android.view.Display
 import android.view.WindowManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.statusbar.IStatusBarService
 import com.android.systemui.SysuiTestCase
@@ -59,7 +59,7 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @RunWithLooper(setAsMainLooper = true)
 @SmallTest
 class ShadeControllerImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeExpansionStateManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeExpansionStateManagerTest.kt
index 89ae42f..4734ede 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeExpansionStateManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeExpansionStateManagerTest.kt
@@ -16,13 +16,16 @@
 
 package com.android.systemui.shade
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 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(AndroidJUnit4::class)
 class ShadeExpansionStateManagerTest : SysuiTestCase() {
 
     private lateinit var shadeExpansionStateManager: ShadeExpansionStateManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/CellSignalStateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/CellSignalStateTest.kt
index 7a9ef62..c669959 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/CellSignalStateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/CellSignalStateTest.kt
@@ -16,7 +16,7 @@
 
 package com.android.systemui.shade.carrier
 
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import org.junit.Assert.assertNotSame
@@ -24,7 +24,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class CellSignalStateTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java
index a42121a..1a2531a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java
@@ -21,13 +21,13 @@
 import static org.junit.Assert.assertTrue;
 
 import android.content.Context;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.TextView;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.settingslib.mobile.TelephonyIcons;
@@ -38,7 +38,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @TestableLooper.RunWithLooper
 @SmallTest
 public class ShadeCarrierTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
index 750693c..97acc6e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
@@ -40,7 +40,7 @@
 
     @Before
     fun setUp() {
-        underTest = ShadeRepositoryImpl()
+        underTest = ShadeRepositoryImpl(getContext())
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt
index 7c33648..10c017b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt
@@ -1,6 +1,6 @@
 package com.android.systemui.shade.transition
 
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepository
@@ -30,7 +30,7 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class ScrimShadeTransitionControllerTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shadow/DoubleShadowTextClockTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shadow/DoubleShadowTextClockTest.kt
index 4679a58..89a3d5b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shadow/DoubleShadowTextClockTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shadow/DoubleShadowTextClockTest.kt
@@ -20,8 +20,8 @@
 import android.content.res.Resources
 import android.content.res.TypedArray
 import android.platform.test.annotations.PlatinumTest
-import android.testing.AndroidTestingRunner
 import android.util.AttributeSet
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.shared.R
@@ -39,7 +39,7 @@
 
 @PlatinumTest(focusArea = "sysui")
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class DoubleShadowTextClockTest : SysuiTestCase() {
     @get:Rule val mockito: MockitoRule = MockitoJUnit.rule()
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/animation/DisableSubpixelTextTransitionListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/animation/DisableSubpixelTextTransitionListenerTest.kt
index fc230e3..5d8f868 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/animation/DisableSubpixelTextTransitionListenerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/animation/DisableSubpixelTextTransitionListenerTest.kt
@@ -17,9 +17,9 @@
 package com.android.systemui.shared.animation
 
 import android.graphics.Paint
-import android.testing.AndroidTestingRunner
 import android.widget.FrameLayout
 import android.widget.TextView
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
@@ -28,7 +28,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class DisableSubpixelTextTransitionListenerTest : SysuiTestCase() {
 
     private lateinit var disableSubpixelTextTransitionListener:
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt
index 293dc04..3a53a5a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt
@@ -14,9 +14,9 @@
  */
 package com.android.systemui.shared.animation
 
-import android.testing.AndroidTestingRunner
 import android.view.View
 import android.view.ViewGroup
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.shared.animation.UnfoldConstantTranslateAnimator.Direction
@@ -34,7 +34,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class UnfoldConstantTranslateAnimatorTest : SysuiTestCase() {
 
     private val progressProvider = FakeUnfoldTransitionProvider()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimatorTest.kt
index 3cb48d9..fbaddfa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimatorTest.kt
@@ -15,8 +15,8 @@
 package com.android.systemui.shared.animation
 
 import android.graphics.Point
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import android.testing.AndroidTestingRunner
 import android.view.Display
 import android.view.Surface.ROTATION_0
 import android.view.Surface.ROTATION_90
@@ -36,7 +36,7 @@
 import org.mockito.junit.MockitoJUnit
 import org.mockito.Mockito.`when` as whenever
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class UnfoldMoveFromCenterAnimatorTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt
index 7b0cd19..e076418 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/AnimatableClockViewTest.kt
@@ -16,8 +16,8 @@
 
 package com.android.systemui.shared.clocks
 
-import android.testing.AndroidTestingRunner
 import android.view.LayoutInflater
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.app.animation.Interpolators
 import com.android.systemui.customization.R
@@ -34,7 +34,7 @@
 import org.mockito.Mockito.verifyNoMoreInteractions
 import org.mockito.junit.MockitoJUnit
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class AnimatableClockViewTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
index 74d0173..2f52248 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
@@ -19,7 +19,7 @@
 import android.content.ContentResolver
 import android.content.Context
 import android.graphics.drawable.Drawable
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.flags.FakeFeatureFlags
@@ -55,7 +55,7 @@
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.junit.MockitoJUnit
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class ClockRegistryTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt
index e0e8d1f..2522ed7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/DefaultClockProviderTest.kt
@@ -19,10 +19,10 @@
 import android.content.res.Resources
 import android.graphics.Color
 import android.graphics.drawable.Drawable
-import android.testing.AndroidTestingRunner
 import android.util.TypedValue
 import android.view.LayoutInflater
 import android.widget.FrameLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.customization.R
@@ -53,7 +53,7 @@
 private fun DefaultClockProvider.createClock(id: ClockId): DefaultClockController =
     createClock(ClockSettings(id, null)) as DefaultClockController
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class DefaultClockProviderTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt
index 1a0e932..8418598 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt
@@ -16,7 +16,7 @@
 
 package com.android.systemui.shared.condition
 
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.shared.condition.Condition.START_EAGERLY
@@ -32,7 +32,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class CombinedConditionTest : SysuiTestCase() {
 
     class FakeCondition
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt
index 0a8210d..83fb14a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt
@@ -1,6 +1,6 @@
 package com.android.systemui.shared.condition
 
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
@@ -19,7 +19,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class ConditionExtensionsTest : SysuiTestCase() {
     private lateinit var testScope: TestScope
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java
index 65ca0a2..267f22b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java
@@ -27,8 +27,8 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.testing.AndroidTestingRunner;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -51,7 +51,7 @@
 import java.util.HashSet;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 public class ConditionMonitorTest extends SysuiTestCase {
     private FakeCondition mCondition1;
     private FakeCondition mCondition2;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionTest.java
index cec5d0a..a224843 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/ConditionTest.java
@@ -25,8 +25,8 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import android.testing.AndroidTestingRunner;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -40,7 +40,7 @@
 import org.mockito.MockitoAnnotations;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 public class ConditionTest extends SysuiTestCase {
     @Mock
     CoroutineScope mScope;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/navigationbar/RegionSamplingHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/navigationbar/RegionSamplingHelperTest.kt
index 5fc09c7..2a6754c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/navigationbar/RegionSamplingHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/navigationbar/RegionSamplingHelperTest.kt
@@ -17,12 +17,12 @@
 package com.android.systemui.shared.navigationbar
 
 import android.graphics.Rect
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
 import android.view.SurfaceControl
 import android.view.View
 import android.view.ViewRootImpl
 import androidx.concurrent.futures.DirectExecutor
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.concurrency.FakeExecutor
@@ -43,7 +43,7 @@
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.junit.MockitoJUnit
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 @RunWithLooper
 class RegionSamplingHelperTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/notifications/data/repository/NotificationSettingsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/notifications/data/repository/NotificationSettingsRepositoryTest.kt
index 0dd988d..69cc9d5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/notifications/data/repository/NotificationSettingsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/notifications/data/repository/NotificationSettingsRepositoryTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.shared.notifications.data.repository
 
 import android.provider.Settings
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
@@ -28,10 +29,9 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class NotificationSettingsRepositoryTest : SysuiTestCase() {
 
     private lateinit var underTest: NotificationSettingsRepository
@@ -56,7 +56,7 @@
     @Test
     fun testGetIsShowNotificationsOnLockscreenEnabled() =
         testScope.runTest {
-            val showNotifs by collectLastValue(underTest.isShowNotificationsOnLockScreenEnabled)
+            val showNotifs by collectLastValue(underTest.isShowNotificationsOnLockScreenEnabled())
 
             secureSettingsRepository.setInt(
                 name = Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
@@ -74,7 +74,7 @@
     @Test
     fun testSetIsShowNotificationsOnLockscreenEnabled() =
         testScope.runTest {
-            val showNotifs by collectLastValue(underTest.isShowNotificationsOnLockScreenEnabled)
+            val showNotifs by collectLastValue(underTest.isShowNotificationsOnLockScreenEnabled())
 
             underTest.setShowNotificationsOnLockscreenEnabled(true)
             assertThat(showNotifs).isEqualTo(true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginManagerTest.java
index 40c84d6..c721ceb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginManagerTest.java
@@ -28,9 +28,9 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.net.Uri;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
@@ -55,7 +55,7 @@
 import java.util.List;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @RunWithLooper
 public class PluginManagerTest extends SysuiTestCase {
     private static final String PRIVILEGED_PACKAGE = "com.android.systemui";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/VersionInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/VersionInfoTest.java
index 711187b..15fdc7c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/VersionInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/VersionInfoTest.java
@@ -17,6 +17,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -29,8 +30,10 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
 
 @SmallTest
+@RunWith(AndroidJUnit4.class)
 public class VersionInfoTest extends SysuiTestCase {
 
     @Rule
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/regionsampling/RegionSamplerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/regionsampling/RegionSamplerTest.kt
index 1031621..7fc845c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/regionsampling/RegionSamplerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/regionsampling/RegionSamplerTest.kt
@@ -4,8 +4,8 @@
 import android.app.WallpaperManager
 import android.graphics.Color
 import android.graphics.RectF
-import android.testing.AndroidTestingRunner
 import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.any
@@ -28,7 +28,7 @@
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.junit.MockitoJUnit
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class RegionSamplerTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/rotation/RotationButtonControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/rotation/RotationButtonControllerTest.kt
index ee3d870..5a4ef05 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/rotation/RotationButtonControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/rotation/RotationButtonControllerTest.kt
@@ -15,11 +15,11 @@
  */
 package com.android.systemui.shared.rotation
 
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
 import android.view.Display
 import android.view.WindowInsetsController
 import android.view.WindowManagerPolicyConstants
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
@@ -27,7 +27,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 @RunWithLooper
 class RotationButtonControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/system/UncaughtExceptionPreHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/system/UncaughtExceptionPreHandlerTest.kt
index b761647..d67ce30 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/system/UncaughtExceptionPreHandlerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/system/UncaughtExceptionPreHandlerTest.kt
@@ -1,5 +1,6 @@
 package com.android.systemui.shared.system
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
@@ -8,6 +9,7 @@
 import org.junit.Before
 import org.junit.Ignore
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.any
 import org.mockito.Mockito.only
@@ -16,6 +18,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class UncaughtExceptionPreHandlerTest : SysuiTestCase() {
     private lateinit var preHandlerManager: UncaughtExceptionPreHandlerManager
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt
index e9676c8..d0ba629 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt
@@ -20,11 +20,13 @@
 import android.view.CrossWindowBlurListeners
 import android.view.SurfaceControl
 import android.view.ViewRootImpl
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 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.Mockito.any
@@ -37,6 +39,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class BlurUtilsTest : SysuiTestCase() {
 
     @Mock lateinit var resources: Resources
@@ -117,4 +120,4 @@
             return transaction
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
index 5da3a56..9df46e5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
@@ -42,6 +42,7 @@
 import android.view.WindowInsetsController.Behavior;
 import android.view.accessibility.Flags;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.statusbar.LetterboxDetails;
@@ -54,8 +55,10 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @SmallTest
+@RunWith(AndroidJUnit4.class)
 public class CommandQueueTest extends SysuiTestCase {
 
     private static final LetterboxDetails[] TEST_LETTERBOX_DETAILS = new LetterboxDetails[] {
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 69e8f47..9e6a498 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
@@ -6,26 +6,23 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.ExpandHelper
-import com.android.systemui.SysUITestModule
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.TestMocksModule
-import com.android.systemui.biometrics.domain.BiometricsDomainLayerModule
 import com.android.systemui.classifier.FalsingCollectorFake
 import com.android.systemui.classifier.FalsingManagerFake
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.flags.FakeFeatureFlagsClassicModule
 import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.keyguard.domain.interactor.NaturalScrollingSettingObserver
+import com.android.systemui.kosmos.testScope
 import com.android.systemui.media.controls.ui.controller.MediaHierarchyManager
 import com.android.systemui.plugins.qs.QS
-import com.android.systemui.power.domain.interactor.PowerInteractor
 import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter
 import com.android.systemui.res.R
+import com.android.systemui.shade.data.repository.shadeRepository
 import com.android.systemui.shade.domain.interactor.ShadeLockscreenInteractor
-import com.android.systemui.shade.data.repository.FakeShadeRepository
-import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.statusbar.disableflags.data.model.DisableFlagsModel
-import com.android.systemui.statusbar.disableflags.data.repository.FakeDisableFlagsRepository
+import com.android.systemui.statusbar.disableflags.data.repository.disableFlagsRepository
+import com.android.systemui.statusbar.disableflags.data.repository.fakeDisableFlagsRepository
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
@@ -33,17 +30,16 @@
 import com.android.systemui.statusbar.phone.CentralSurfaces
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.phone.ScrimController
-import com.android.systemui.statusbar.policy.FakeConfigurationController
 import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
-import com.android.systemui.user.domain.UserDomainLayerModule
+import com.android.systemui.statusbar.policy.configurationController
+import com.android.systemui.statusbar.policy.fakeConfigurationController
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.mock
-import dagger.BindsInstance
-import dagger.Component
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
 import org.junit.After
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertNotNull
@@ -65,8 +61,8 @@
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyZeroInteractions
-import org.mockito.junit.MockitoJUnit
 import org.mockito.Mockito.`when` as whenever
+import org.mockito.junit.MockitoJUnit
 
 private fun <T> anyObject(): T {
     return Mockito.anyObject<T>()
@@ -77,15 +73,14 @@
 @RunWith(AndroidJUnit4::class)
 @OptIn(ExperimentalCoroutinesApi::class)
 class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
-
+    private val kosmos =
+        testKosmos().apply {
+            fakeFeatureFlagsClassic.apply { set(Flags.FULL_SCREEN_USER_SWITCHER, false) }
+        }
     private lateinit var transitionController: LockscreenShadeTransitionController
-    private lateinit var testComponent: TestComponent
-    private val configurationController
-        get() = testComponent.configurationController
-    private val disableFlagsRepository
-        get() = testComponent.disableFlagsRepository
-    private val testScope
-        get() = testComponent.testScope
+    private val configurationController = kosmos.fakeConfigurationController
+    private val disableFlagsRepository = kosmos.fakeDisableFlagsRepository
+    private val testScope = kosmos.testScope
 
     private val qsSceneAdapter = FakeQSSceneAdapter({ mock() })
 
@@ -134,26 +129,6 @@
         whenever(keyguardBypassController.bypassEnabled).thenReturn(false)
         whenever(naturalScrollingSettingObserver.isNaturalScrollingEnabled).thenReturn(true)
 
-        testComponent =
-            DaggerLockscreenShadeTransitionControllerTest_TestComponent.factory()
-                .create(
-                    test = this,
-                    featureFlags =
-                        FakeFeatureFlagsClassicModule {
-                            set(Flags.FULL_SCREEN_USER_SWITCHER, false)
-                        },
-                    mocks =
-                        TestMocksModule(
-                            notificationShadeDepthController = depthController,
-                            keyguardBypassController = keyguardBypassController,
-                            mediaHierarchyManager = mediaHierarchyManager,
-                            notificationLockscreenUserManager = lockScreenUserManager,
-                            notificationStackScrollLayoutController = nsslController,
-                            scrimController = scrimController,
-                            statusBarStateController = statusbarStateController,
-                        )
-                )
-
         transitionController =
             LockscreenShadeTransitionController(
                 statusBarStateController = statusbarStateController,
@@ -191,10 +166,10 @@
                 falsingManager = FalsingManagerFake(),
                 dumpManager = mock(),
                 qsTransitionControllerFactory = { qsTransitionController },
-                shadeRepository = testComponent.shadeRepository,
-                shadeInteractor = testComponent.shadeInteractor,
+                shadeRepository = kosmos.shadeRepository,
+                shadeInteractor = kosmos.shadeInteractor,
                 splitShadeStateController = ResourcesSplitShadeStateController(),
-                shadeLockscreenInteractorLazy = {shadeLockscreenInteractor},
+                shadeLockscreenInteractorLazy = { shadeLockscreenInteractor },
                 naturalScrollingSettingObserver = naturalScrollingSettingObserver,
                 lazyQSSceneAdapter = { qsSceneAdapter }
             )
@@ -214,387 +189,424 @@
     }
 
     @Test
-    fun testCantDragDownWhenQSExpanded() {
-        assertTrue("Can't drag down on keyguard", transitionController.canDragDown())
-        whenever(qS.isFullyCollapsed).thenReturn(false)
-        assertFalse("Can drag down when QS is expanded", transitionController.canDragDown())
-    }
+    fun testCantDragDownWhenQSExpanded() =
+        testScope.runTest {
+            assertTrue("Can't drag down on keyguard", transitionController.canDragDown())
+            whenever(qS.isFullyCollapsed).thenReturn(false)
+            assertFalse("Can drag down when QS is expanded", transitionController.canDragDown())
+        }
 
     @Test
-    fun testCanDragDownInLockedDownShade() {
-        whenever(statusbarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)
-        assertFalse("Can drag down in shade locked", transitionController.canDragDown())
-        whenever(nsslController.isInLockedDownShade).thenReturn(true)
-        assertTrue("Can't drag down in locked down shade", transitionController.canDragDown())
-    }
+    fun testCanDragDownInLockedDownShade() =
+        testScope.runTest {
+            whenever(statusbarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)
+            assertFalse("Can drag down in shade locked", transitionController.canDragDown())
+            whenever(nsslController.isInLockedDownShade).thenReturn(true)
+            assertTrue("Can't drag down in locked down shade", transitionController.canDragDown())
+        }
 
     @Test
-    fun testGoingToLockedShade() {
-        transitionController.goToLockedShade(null)
-        verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
-    }
+    fun testGoingToLockedShade() =
+        testScope.runTest {
+            transitionController.goToLockedShade(null)
+            verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
+        }
 
     @Test
-    fun testWakingToShadeLockedWhenDozing() {
-        whenever(statusbarStateController.isDozing).thenReturn(true)
-        transitionController.goToLockedShade(null)
-        verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
-        assertTrue("Not waking to shade locked", transitionController.isWakingToShadeLocked)
-    }
+    fun testWakingToShadeLockedWhenDozing() =
+        testScope.runTest {
+            whenever(statusbarStateController.isDozing).thenReturn(true)
+            transitionController.goToLockedShade(null)
+            verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
+            assertTrue("Not waking to shade locked", transitionController.isWakingToShadeLocked)
+        }
 
     @Test
-    fun testNotWakingToShadeLockedWhenNotDozing() {
-        whenever(statusbarStateController.isDozing).thenReturn(false)
-        transitionController.goToLockedShade(null)
-        verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
-        assertFalse(
-            "Waking to shade locked when not dozing",
-            transitionController.isWakingToShadeLocked
-        )
-    }
-
-    @Test
-    fun testGoToLockedShadeOnlyOnKeyguard() {
-        whenever(statusbarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)
-        transitionController.goToLockedShade(null)
-        whenever(statusbarStateController.state).thenReturn(StatusBarState.SHADE)
-        transitionController.goToLockedShade(null)
-        verify(statusbarStateController, never()).setState(anyInt())
-    }
-
-    @Test
-    fun testDontGoWhenShadeDisabled() {
-        disableFlagsRepository.disableFlags.value =
-            DisableFlagsModel(
-                disable2 = DISABLE2_NOTIFICATION_SHADE,
+    fun testNotWakingToShadeLockedWhenNotDozing() =
+        testScope.runTest {
+            whenever(statusbarStateController.isDozing).thenReturn(false)
+            transitionController.goToLockedShade(null)
+            verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
+            assertFalse(
+                "Waking to shade locked when not dozing",
+                transitionController.isWakingToShadeLocked
             )
-        testScope.runCurrent()
-        transitionController.goToLockedShade(null)
-        verify(statusbarStateController, never()).setState(anyInt())
-    }
+        }
 
     @Test
-    fun testUserExpandsViewOnGoingToFullShade() {
-        assertFalse("Row shouldn't be user expanded yet", row.isUserExpanded)
-        transitionController.goToLockedShade(row)
-        assertTrue("Row wasn't user expanded on drag down", row.isUserExpanded)
-    }
+    fun testGoToLockedShadeOnlyOnKeyguard() =
+        testScope.runTest {
+            whenever(statusbarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)
+            transitionController.goToLockedShade(null)
+            whenever(statusbarStateController.state).thenReturn(StatusBarState.SHADE)
+            transitionController.goToLockedShade(null)
+            verify(statusbarStateController, never()).setState(anyInt())
+        }
 
     @Test
-    fun testTriggeringBouncerNoNotificationsOnLockscreen() {
-        whenever(lockScreenUserManager.shouldShowLockscreenNotifications()).thenReturn(false)
-        transitionController.goToLockedShade(null)
-        verify(statusbarStateController, never()).setState(anyInt())
-        verify(statusbarStateController).setLeaveOpenOnKeyguardHide(true)
-        verify(centralSurfaces).showBouncerWithDimissAndCancelIfKeyguard(anyObject(), anyObject())
-    }
+    fun testDontGoWhenShadeDisabled() =
+        testScope.runTest {
+            disableFlagsRepository.disableFlags.value =
+                DisableFlagsModel(
+                    disable2 = DISABLE2_NOTIFICATION_SHADE,
+                )
+            testScope.runCurrent()
+            transitionController.goToLockedShade(null)
+            verify(statusbarStateController, never()).setState(anyInt())
+        }
 
     @Test
-    fun testGoToLockedShadeCreatesQSAnimation() {
-        transitionController.goToLockedShade(null)
-        verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
-        verify(shadeLockscreenInteractor).transitionToExpandedShade(anyLong())
-        assertNotNull(transitionController.dragDownAnimator)
-    }
+    fun testUserExpandsViewOnGoingToFullShade() =
+        testScope.runTest {
+            assertFalse("Row shouldn't be user expanded yet", row.isUserExpanded)
+            transitionController.goToLockedShade(row)
+            assertTrue("Row wasn't user expanded on drag down", row.isUserExpanded)
+        }
 
     @Test
-    fun testGoToLockedShadeDoesntCreateQSAnimation() {
-        transitionController.goToLockedShade(null, needsQSAnimation = false)
-        verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
-        verify(shadeLockscreenInteractor).transitionToExpandedShade(anyLong())
-        assertNull(transitionController.dragDownAnimator)
-    }
+    fun testTriggeringBouncerNoNotificationsOnLockscreen() =
+        testScope.runTest {
+            whenever(lockScreenUserManager.shouldShowLockscreenNotifications()).thenReturn(false)
+            transitionController.goToLockedShade(null)
+            verify(statusbarStateController, never()).setState(anyInt())
+            verify(statusbarStateController).setLeaveOpenOnKeyguardHide(true)
+            verify(centralSurfaces)
+                .showBouncerWithDimissAndCancelIfKeyguard(anyObject(), anyObject())
+        }
 
     @Test
-    fun testGoToLockedShadeAlwaysCreatesQSAnimationInSplitShade() {
-        enableSplitShade()
-        transitionController.goToLockedShade(null, needsQSAnimation = true)
-        verify(shadeLockscreenInteractor).transitionToExpandedShade(anyLong())
-        assertNotNull(transitionController.dragDownAnimator)
-    }
+    fun testGoToLockedShadeCreatesQSAnimation() =
+        testScope.runTest {
+            transitionController.goToLockedShade(null)
+            verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
+            verify(shadeLockscreenInteractor).transitionToExpandedShade(anyLong())
+            assertNotNull(transitionController.dragDownAnimator)
+        }
 
     @Test
-    fun testGoToLockedShadeCancelDoesntLeaveShadeOpenOnKeyguardHide() {
-        whenever(lockScreenUserManager.shouldShowLockscreenNotifications()).thenReturn(false)
-        whenever(lockScreenUserManager.isLockscreenPublicMode(any())).thenReturn(true)
-        transitionController.goToLockedShade(null)
-        val captor = argumentCaptor<Runnable>()
-        verify(centralSurfaces).showBouncerWithDimissAndCancelIfKeyguard(isNull(), captor.capture())
-        captor.value.run()
-        verify(statusbarStateController).setLeaveOpenOnKeyguardHide(false)
-    }
+    fun testGoToLockedShadeDoesntCreateQSAnimation() =
+        testScope.runTest {
+            transitionController.goToLockedShade(null, needsQSAnimation = false)
+            verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
+            verify(shadeLockscreenInteractor).transitionToExpandedShade(anyLong())
+            assertNull(transitionController.dragDownAnimator)
+        }
 
     @Test
-    fun testDragDownAmountDoesntCallOutInLockedDownShade() {
-        whenever(nsslController.isInLockedDownShade).thenReturn(true)
-        transitionController.dragDownAmount = 10f
-        verify(nsslController, never()).setTransitionToFullShadeAmount(anyFloat())
-        verify(mediaHierarchyManager, never()).setTransitionToFullShadeAmount(anyFloat())
-        verify(scrimController, never()).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
-        verify(transitionControllerCallback, never())
-            .setTransitionToFullShadeAmount(anyFloat(), anyBoolean(), anyLong())
-        verify(qsTransitionController, never()).dragDownAmount = anyFloat()
-    }
+    fun testGoToLockedShadeAlwaysCreatesQSAnimationInSplitShade() =
+        testScope.runTest {
+            enableSplitShade()
+            transitionController.goToLockedShade(null, needsQSAnimation = true)
+            verify(shadeLockscreenInteractor).transitionToExpandedShade(anyLong())
+            assertNotNull(transitionController.dragDownAnimator)
+        }
 
     @Test
-    fun testDragDownAmountCallsOut() {
-        transitionController.dragDownAmount = 10f
-        verify(nsslController).setTransitionToFullShadeAmount(anyFloat())
-        verify(mediaHierarchyManager).setTransitionToFullShadeAmount(anyFloat())
-        verify(scrimController).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
-        verify(transitionControllerCallback)
-            .setTransitionToFullShadeAmount(anyFloat(), anyBoolean(), anyLong())
-        verify(qsTransitionController).dragDownAmount = 10f
-        verify(depthController).transitionToFullShadeProgress = anyFloat()
-    }
+    fun testGoToLockedShadeCancelDoesntLeaveShadeOpenOnKeyguardHide() =
+        testScope.runTest {
+            whenever(lockScreenUserManager.shouldShowLockscreenNotifications()).thenReturn(false)
+            whenever(lockScreenUserManager.isLockscreenPublicMode(any())).thenReturn(true)
+            transitionController.goToLockedShade(null)
+            val captor = argumentCaptor<Runnable>()
+            verify(centralSurfaces)
+                .showBouncerWithDimissAndCancelIfKeyguard(isNull(), captor.capture())
+            captor.value.run()
+            verify(statusbarStateController).setLeaveOpenOnKeyguardHide(false)
+        }
 
     @Test
-    fun testDragDownAmount_depthDistanceIsZero_setsProgressToZero() {
-        context
-            .getOrCreateTestableResources()
-            .addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 0)
-        configurationController.notifyConfigurationChanged()
-
-        transitionController.dragDownAmount = 10f
-
-        verify(depthController).transitionToFullShadeProgress = 0f
-    }
+    fun testDragDownAmountDoesntCallOutInLockedDownShade() =
+        testScope.runTest {
+            whenever(nsslController.isInLockedDownShade).thenReturn(true)
+            transitionController.dragDownAmount = 10f
+            verify(nsslController, never()).setTransitionToFullShadeAmount(anyFloat())
+            verify(mediaHierarchyManager, never()).setTransitionToFullShadeAmount(anyFloat())
+            verify(scrimController, never())
+                .setTransitionToFullShadeProgress(anyFloat(), anyFloat())
+            verify(transitionControllerCallback, never())
+                .setTransitionToFullShadeAmount(anyFloat(), anyBoolean(), anyLong())
+            verify(qsTransitionController, never()).dragDownAmount = anyFloat()
+        }
 
     @Test
-    fun testDragDownAmount_depthDistanceNonZero_setsProgressBasedOnDistance() {
-        context
-            .getOrCreateTestableResources()
-            .addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 100)
-        configurationController.notifyConfigurationChanged()
-
-        transitionController.dragDownAmount = 10f
-
-        verify(depthController).transitionToFullShadeProgress = 0.1f
-    }
+    fun testDragDownAmountCallsOut() =
+        testScope.runTest {
+            transitionController.dragDownAmount = 10f
+            verify(nsslController).setTransitionToFullShadeAmount(anyFloat())
+            verify(mediaHierarchyManager).setTransitionToFullShadeAmount(anyFloat())
+            verify(scrimController).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
+            verify(transitionControllerCallback)
+                .setTransitionToFullShadeAmount(anyFloat(), anyBoolean(), anyLong())
+            verify(qsTransitionController).dragDownAmount = 10f
+            verify(depthController).transitionToFullShadeProgress = anyFloat()
+        }
 
     @Test
-    fun setDragAmount_setsKeyguardTransitionProgress() {
-        transitionController.dragDownAmount = 10f
+    fun testDragDownAmount_depthDistanceIsZero_setsProgressToZero() =
+        testScope.runTest {
+            context
+                .getOrCreateTestableResources()
+                .addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 0)
+            configurationController.notifyConfigurationChanged()
 
-        verify(shadeLockscreenInteractor).setKeyguardTransitionProgress(anyFloat(), anyInt())
-    }
+            transitionController.dragDownAmount = 10f
+
+            verify(depthController).transitionToFullShadeProgress = 0f
+        }
 
     @Test
-    fun setDragAmount_setsKeyguardAlphaBasedOnDistance() {
-        val alphaDistance =
-            context.resources.getDimensionPixelSize(
-                R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance
-            )
-        transitionController.dragDownAmount = 10f
+    fun testDragDownAmount_depthDistanceNonZero_setsProgressBasedOnDistance() =
+        testScope.runTest {
+            context
+                .getOrCreateTestableResources()
+                .addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 100)
+            configurationController.notifyConfigurationChanged()
 
-        val expectedAlpha = 1 - 10f / alphaDistance
-        verify(shadeLockscreenInteractor).setKeyguardTransitionProgress(eq(expectedAlpha), anyInt())
-    }
+            transitionController.dragDownAmount = 10f
+
+            verify(depthController).transitionToFullShadeProgress = 0.1f
+        }
 
     @Test
-    fun setDragAmount_notInSplitShade_setsKeyguardTranslationToZero() {
-        val mediaTranslationY = 123
-        disableSplitShade()
-        whenever(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).thenReturn(true)
-        whenever(mediaHierarchyManager.getGuidedTransformationTranslationY())
-            .thenReturn(mediaTranslationY)
+    fun setDragAmount_setsKeyguardTransitionProgress() =
+        testScope.runTest {
+            transitionController.dragDownAmount = 10f
 
-        transitionController.dragDownAmount = 10f
-
-        verify(shadeLockscreenInteractor).setKeyguardTransitionProgress(anyFloat(), eq(0))
-    }
+            verify(shadeLockscreenInteractor).setKeyguardTransitionProgress(anyFloat(), anyInt())
+        }
 
     @Test
-    fun setDragAmount_inSplitShade_setsKeyguardTranslationBasedOnMediaTranslation() {
-        val mediaTranslationY = 123
-        enableSplitShade()
-        whenever(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).thenReturn(true)
-        whenever(mediaHierarchyManager.getGuidedTransformationTranslationY())
-            .thenReturn(mediaTranslationY)
+    fun setDragAmount_setsKeyguardAlphaBasedOnDistance() =
+        testScope.runTest {
+            val alphaDistance =
+                context.resources.getDimensionPixelSize(
+                    R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance
+                )
+            transitionController.dragDownAmount = 10f
 
-        transitionController.dragDownAmount = 10f
+            val expectedAlpha = 1 - 10f / alphaDistance
+            verify(shadeLockscreenInteractor)
+                .setKeyguardTransitionProgress(eq(expectedAlpha), anyInt())
+        }
 
-        verify(shadeLockscreenInteractor)
+    @Test
+    fun setDragAmount_notInSplitShade_setsKeyguardTranslationToZero() =
+        testScope.runTest {
+            val mediaTranslationY = 123
+            disableSplitShade()
+            whenever(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).thenReturn(true)
+            whenever(mediaHierarchyManager.getGuidedTransformationTranslationY())
+                .thenReturn(mediaTranslationY)
+
+            transitionController.dragDownAmount = 10f
+
+            verify(shadeLockscreenInteractor).setKeyguardTransitionProgress(anyFloat(), eq(0))
+        }
+
+    @Test
+    fun setDragAmount_inSplitShade_setsKeyguardTranslationBasedOnMediaTranslation() =
+        testScope.runTest {
+            val mediaTranslationY = 123
+            enableSplitShade()
+            whenever(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).thenReturn(true)
+            whenever(mediaHierarchyManager.getGuidedTransformationTranslationY())
+                .thenReturn(mediaTranslationY)
+
+            transitionController.dragDownAmount = 10f
+
+            verify(shadeLockscreenInteractor)
                 .setKeyguardTransitionProgress(anyFloat(), eq(mediaTranslationY))
-    }
+        }
 
     @Test
-    fun setDragAmount_inSplitShade_mediaNotShowing_setsKeyguardTranslationBasedOnDistance() {
-        enableSplitShade()
-        whenever(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).thenReturn(false)
-        whenever(mediaHierarchyManager.getGuidedTransformationTranslationY()).thenReturn(123)
+    fun setDragAmount_inSplitShade_mediaNotShowing_setsKeyguardTranslationBasedOnDistance() =
+        testScope.runTest {
+            enableSplitShade()
+            whenever(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).thenReturn(false)
+            whenever(mediaHierarchyManager.getGuidedTransformationTranslationY()).thenReturn(123)
 
-        transitionController.dragDownAmount = 10f
+            transitionController.dragDownAmount = 10f
 
-        val distance =
-            context.resources.getDimensionPixelSize(
-                R.dimen.lockscreen_shade_keyguard_transition_distance
+            val distance =
+                context.resources.getDimensionPixelSize(
+                    R.dimen.lockscreen_shade_keyguard_transition_distance
+                )
+            val offset =
+                context.resources.getDimensionPixelSize(
+                    R.dimen.lockscreen_shade_keyguard_transition_vertical_offset
+                )
+            val expectedTranslation = 10f / distance * offset
+            verify(shadeLockscreenInteractor)
+                .setKeyguardTransitionProgress(anyFloat(), eq(expectedTranslation.toInt()))
+        }
+
+    @Test
+    fun setDragDownAmount_setsValueOnMediaHierarchyManager() =
+        testScope.runTest {
+            transitionController.dragDownAmount = 10f
+
+            verify(mediaHierarchyManager).setTransitionToFullShadeAmount(10f)
+        }
+
+    @Test
+    fun setDragAmount_setsScrimProgressBasedOnScrimDistance() =
+        testScope.runTest {
+            val distance = 10
+            context.orCreateTestableResources.addOverride(
+                R.dimen.lockscreen_shade_scrim_transition_distance,
+                distance
             )
-        val offset =
-            context.resources.getDimensionPixelSize(
-                R.dimen.lockscreen_shade_keyguard_transition_vertical_offset
+            configurationController.notifyConfigurationChanged()
+
+            transitionController.dragDownAmount = 5f
+
+            verify(scrimController)
+                .transitionToFullShadeProgress(
+                    progress = eq(0.5f),
+                    lockScreenNotificationsProgress = anyFloat()
+                )
+        }
+
+    @Test
+    fun setDragAmount_setsNotificationsScrimProgressBasedOnNotificationsScrimDistanceAndDelay() =
+        testScope.runTest {
+            val distance = 100
+            val delay = 10
+            context.orCreateTestableResources.addOverride(
+                R.dimen.lockscreen_shade_notifications_scrim_transition_distance,
+                distance
             )
-        val expectedTranslation = 10f / distance * offset
-        verify(shadeLockscreenInteractor)
-            .setKeyguardTransitionProgress(anyFloat(), eq(expectedTranslation.toInt()))
-    }
-
-    @Test
-    fun setDragDownAmount_setsValueOnMediaHierarchyManager() {
-        transitionController.dragDownAmount = 10f
-
-        verify(mediaHierarchyManager).setTransitionToFullShadeAmount(10f)
-    }
-
-    @Test
-    fun setDragAmount_setsScrimProgressBasedOnScrimDistance() {
-        val distance = 10
-        context.orCreateTestableResources.addOverride(
-            R.dimen.lockscreen_shade_scrim_transition_distance,
-            distance
-        )
-        configurationController.notifyConfigurationChanged()
-
-        transitionController.dragDownAmount = 5f
-
-        verify(scrimController)
-            .transitionToFullShadeProgress(
-                progress = eq(0.5f),
-                lockScreenNotificationsProgress = anyFloat()
+            context.orCreateTestableResources.addOverride(
+                R.dimen.lockscreen_shade_notifications_scrim_transition_delay,
+                delay
             )
-    }
+            configurationController.notifyConfigurationChanged()
+
+            transitionController.dragDownAmount = 20f
+
+            verify(scrimController)
+                .transitionToFullShadeProgress(
+                    progress = anyFloat(),
+                    lockScreenNotificationsProgress = eq(0.1f)
+                )
+        }
 
     @Test
-    fun setDragAmount_setsNotificationsScrimProgressBasedOnNotificationsScrimDistanceAndDelay() {
-        val distance = 100
-        val delay = 10
-        context.orCreateTestableResources.addOverride(
-            R.dimen.lockscreen_shade_notifications_scrim_transition_distance,
-            distance
-        )
-        context.orCreateTestableResources.addOverride(
-            R.dimen.lockscreen_shade_notifications_scrim_transition_delay,
-            delay
-        )
-        configurationController.notifyConfigurationChanged()
-
-        transitionController.dragDownAmount = 20f
-
-        verify(scrimController)
-            .transitionToFullShadeProgress(
-                progress = anyFloat(),
-                lockScreenNotificationsProgress = eq(0.1f)
+    fun setDragAmount_dragAmountLessThanNotifDelayDistance_setsNotificationsScrimProgressToZero() =
+        testScope.runTest {
+            val distance = 100
+            val delay = 50
+            context.orCreateTestableResources.addOverride(
+                R.dimen.lockscreen_shade_notifications_scrim_transition_distance,
+                distance
             )
-    }
-
-    @Test
-    fun setDragAmount_dragAmountLessThanNotifDelayDistance_setsNotificationsScrimProgressToZero() {
-        val distance = 100
-        val delay = 50
-        context.orCreateTestableResources.addOverride(
-            R.dimen.lockscreen_shade_notifications_scrim_transition_distance,
-            distance
-        )
-        context.orCreateTestableResources.addOverride(
-            R.dimen.lockscreen_shade_notifications_scrim_transition_delay,
-            delay
-        )
-        configurationController.notifyConfigurationChanged()
-
-        transitionController.dragDownAmount = 20f
-
-        verify(scrimController)
-            .transitionToFullShadeProgress(
-                progress = anyFloat(),
-                lockScreenNotificationsProgress = eq(0f)
+            context.orCreateTestableResources.addOverride(
+                R.dimen.lockscreen_shade_notifications_scrim_transition_delay,
+                delay
             )
-    }
+            configurationController.notifyConfigurationChanged()
+
+            transitionController.dragDownAmount = 20f
+
+            verify(scrimController)
+                .transitionToFullShadeProgress(
+                    progress = anyFloat(),
+                    lockScreenNotificationsProgress = eq(0f)
+                )
+        }
 
     @Test
-    fun setDragAmount_dragAmountMoreThanTotalDistance_setsNotificationsScrimProgressToOne() {
-        val distance = 100
-        val delay = 50
-        context.orCreateTestableResources.addOverride(
-            R.dimen.lockscreen_shade_notifications_scrim_transition_distance,
-            distance
-        )
-        context.orCreateTestableResources.addOverride(
-            R.dimen.lockscreen_shade_notifications_scrim_transition_delay,
-            delay
-        )
-        configurationController.notifyConfigurationChanged()
-
-        transitionController.dragDownAmount = 999999f
-
-        verify(scrimController)
-            .transitionToFullShadeProgress(
-                progress = anyFloat(),
-                lockScreenNotificationsProgress = eq(1f)
+    fun setDragAmount_dragAmountMoreThanTotalDistance_setsNotificationsScrimProgressToOne() =
+        testScope.runTest {
+            val distance = 100
+            val delay = 50
+            context.orCreateTestableResources.addOverride(
+                R.dimen.lockscreen_shade_notifications_scrim_transition_distance,
+                distance
             )
-    }
-
-    @Test
-    fun setDragDownAmount_inSplitShade_setsValueOnMediaHierarchyManager() {
-        enableSplitShade()
-
-        transitionController.dragDownAmount = 10f
-
-        verify(mediaHierarchyManager).setTransitionToFullShadeAmount(10f)
-    }
-
-    @Test
-    fun setDragAmount_notInSplitShade_forwardsToSingleShadeOverScroller() {
-        disableSplitShade()
-
-        transitionController.dragDownAmount = 10f
-
-        verify(singleShadeOverScroller).expansionDragDownAmount = 10f
-        verifyZeroInteractions(splitShadeOverScroller)
-    }
-
-    @Test
-    fun setDragAmount_inSplitShade_forwardsToSplitShadeOverScroller() {
-        enableSplitShade()
-
-        transitionController.dragDownAmount = 10f
-
-        verify(splitShadeOverScroller).expansionDragDownAmount = 10f
-        verifyZeroInteractions(singleShadeOverScroller)
-    }
-
-    @Test
-    fun setDragDownAmount_inSplitShade_setsKeyguardStatusBarAlphaBasedOnDistance() {
-        val alphaDistance =
-            context.resources.getDimensionPixelSize(
-                R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance
+            context.orCreateTestableResources.addOverride(
+                R.dimen.lockscreen_shade_notifications_scrim_transition_delay,
+                delay
             )
-        val dragDownAmount = 10f
-        enableSplitShade()
+            configurationController.notifyConfigurationChanged()
 
-        transitionController.dragDownAmount = dragDownAmount
+            transitionController.dragDownAmount = 999999f
 
-        val expectedAlpha = 1 - dragDownAmount / alphaDistance
-        verify(shadeLockscreenInteractor).setKeyguardStatusBarAlpha(expectedAlpha)
-    }
+            verify(scrimController)
+                .transitionToFullShadeProgress(
+                    progress = anyFloat(),
+                    lockScreenNotificationsProgress = eq(1f)
+                )
+        }
 
     @Test
-    fun setDragDownAmount_notInSplitShade_setsKeyguardStatusBarAlphaToMinusOne() {
-        disableSplitShade()
+    fun setDragDownAmount_inSplitShade_setsValueOnMediaHierarchyManager() =
+        testScope.runTest {
+            enableSplitShade()
 
-        transitionController.dragDownAmount = 10f
+            transitionController.dragDownAmount = 10f
 
-        verify(shadeLockscreenInteractor).setKeyguardStatusBarAlpha(-1f)
-    }
+            verify(mediaHierarchyManager).setTransitionToFullShadeAmount(10f)
+        }
 
     @Test
-    fun nullQs_canDragDownFromAdapter() {
-        transitionController.qS = null
+    fun setDragAmount_notInSplitShade_forwardsToSingleShadeOverScroller() =
+        testScope.runTest {
+            disableSplitShade()
 
-        qsSceneAdapter.isQsFullyCollapsed = true
-        assertTrue("Can't drag down on keyguard", transitionController.canDragDown())
-        qsSceneAdapter.isQsFullyCollapsed = false
-        assertFalse("Can drag down when QS is expanded", transitionController.canDragDown())
-    }
+            transitionController.dragDownAmount = 10f
+
+            verify(singleShadeOverScroller).expansionDragDownAmount = 10f
+            verifyZeroInteractions(splitShadeOverScroller)
+        }
+
+    @Test
+    fun setDragAmount_inSplitShade_forwardsToSplitShadeOverScroller() =
+        testScope.runTest {
+            enableSplitShade()
+
+            transitionController.dragDownAmount = 10f
+
+            verify(splitShadeOverScroller).expansionDragDownAmount = 10f
+            verifyZeroInteractions(singleShadeOverScroller)
+        }
+
+    @Test
+    fun setDragDownAmount_inSplitShade_setsKeyguardStatusBarAlphaBasedOnDistance() =
+        testScope.runTest {
+            val alphaDistance =
+                context.resources.getDimensionPixelSize(
+                    R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance
+                )
+            val dragDownAmount = 10f
+            enableSplitShade()
+
+            transitionController.dragDownAmount = dragDownAmount
+
+            val expectedAlpha = 1 - dragDownAmount / alphaDistance
+            verify(shadeLockscreenInteractor).setKeyguardStatusBarAlpha(expectedAlpha)
+        }
+
+    @Test
+    fun setDragDownAmount_notInSplitShade_setsKeyguardStatusBarAlphaToMinusOne() =
+        testScope.runTest {
+            disableSplitShade()
+
+            transitionController.dragDownAmount = 10f
+
+            verify(shadeLockscreenInteractor).setKeyguardStatusBarAlpha(-1f)
+        }
+
+    @Test
+    fun nullQs_canDragDownFromAdapter() =
+        testScope.runTest {
+            transitionController.qS = null
+
+            qsSceneAdapter.isQsFullyCollapsed = true
+            assertTrue("Can't drag down on keyguard", transitionController.canDragDown())
+            qsSceneAdapter.isQsFullyCollapsed = false
+            assertFalse("Can drag down when QS is expanded", transitionController.canDragDown())
+        }
 
     private fun enableSplitShade() {
         setSplitShadeEnabled(true)
@@ -619,32 +631,4 @@
     ) {
         setTransitionToFullShadeProgress(progress, lockScreenNotificationsProgress)
     }
-
-    @SysUISingleton
-    @Component(
-        modules =
-            [
-                SysUITestModule::class,
-                UserDomainLayerModule::class,
-                BiometricsDomainLayerModule::class,
-            ]
-    )
-    interface TestComponent {
-
-        val configurationController: FakeConfigurationController
-        val disableFlagsRepository: FakeDisableFlagsRepository
-        val powerInteractor: PowerInteractor
-        val shadeInteractor: ShadeInteractor
-        val shadeRepository: FakeShadeRepository
-        val testScope: TestScope
-
-        @Component.Factory
-        interface Factory {
-            fun create(
-                    @BindsInstance test: SysuiTestCase,
-                    featureFlags: FakeFeatureFlagsClassicModule,
-                    mocks: TestMocksModule,
-            ): TestComponent
-        }
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
index 3b85dba..5f9c9df 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
@@ -23,18 +23,21 @@
 import android.content.Intent;
 import android.graphics.drawable.Icon;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
 @SmallTest
+@RunWith(AndroidJUnit4.class)
 public class NotificationUiAdjustmentTest extends SysuiTestCase {
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt
index 9c59f9b..396d017 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt
@@ -20,6 +20,7 @@
 import android.telephony.SubscriptionInfo
 import android.telephony.TelephonyManager
 import android.telephony.telephonyManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.keyguard.keyguardUpdateMonitor
 import com.android.systemui.SysuiTestCase
@@ -44,11 +45,13 @@
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class OperatorNameViewControllerTest : SysuiTestCase() {
     private lateinit var underTest: OperatorNameViewController
     private lateinit var airplaneModeInteractor: AirplaneModeInteractor
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
index 6cac30a..1a6b420 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
@@ -26,6 +26,7 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.plugins.activityStarter
 import com.android.systemui.res.R
+import com.android.systemui.statusbar.chips.ui.model.ColorsModel
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
 import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
 import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
@@ -68,13 +69,33 @@
         }
 
     @Test
-    fun chip_inCall_isShown() =
+    fun chip_inCall_zeroStartTime_isShownAsIconOnly() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.chip)
+
+            repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = null))
+
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
+        }
+
+    @Test
+    fun chip_inCall_negativeStartTime_isShownAsIconOnly() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.chip)
+
+            repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = -2, intent = null))
+
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
+        }
+
+    @Test
+    fun chip_inCall_positiveStartTime_isShownAsTimer() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
 
             repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 345, intent = null))
 
-            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
         }
 
     @Test
@@ -91,11 +112,12 @@
             // started 2000ms ago (1000 - 3000). The OngoingActivityChipModel start time needs to be
             // relative to elapsedRealtime, so it should be 2000ms before the elapsed realtime set
             // on the clock.
-            assertThat((latest as OngoingActivityChipModel.Shown).startTimeMs).isEqualTo(398_000)
+            assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs)
+                .isEqualTo(398_000)
         }
 
     @Test
-    fun chip_inCall_iconIsPhone() =
+    fun chip_positiveStartTime_iconIsPhone() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
 
@@ -103,6 +125,43 @@
 
             assertThat(((latest as OngoingActivityChipModel.Shown).icon as Icon.Resource).res)
                 .isEqualTo(com.android.internal.R.drawable.ic_phone)
+            assertThat((latest as OngoingActivityChipModel.Shown).icon!!.contentDescription)
+                .isNotNull()
+        }
+
+    @Test
+    fun chip_zeroStartTime_iconIsPhone() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.chip)
+
+            repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = null))
+
+            assertThat(((latest as OngoingActivityChipModel.Shown).icon as Icon.Resource).res)
+                .isEqualTo(com.android.internal.R.drawable.ic_phone)
+            assertThat((latest as OngoingActivityChipModel.Shown).icon!!.contentDescription)
+                .isNotNull()
+        }
+
+    @Test
+    fun chip_positiveStartTime_colorsAreThemed() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.chip)
+
+            repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 1000, intent = null))
+
+            assertThat((latest as OngoingActivityChipModel.Shown).colors)
+                .isEqualTo(ColorsModel.Themed)
+        }
+
+    @Test
+    fun chip_zeroStartTime_colorsAreThemed() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.chip)
+
+            repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = null))
+
+            assertThat((latest as OngoingActivityChipModel.Shown).colors)
+                .isEqualTo(ColorsModel.Themed)
         }
 
     @Test
@@ -115,7 +174,8 @@
             // Start a call
             repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 1000, intent = null))
             assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
-            assertThat((latest as OngoingActivityChipModel.Shown).startTimeMs).isEqualTo(398_000)
+            assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs)
+                .isEqualTo(398_000)
 
             // End the call
             repo.setOngoingCallState(OngoingCallModel.NoCall)
@@ -128,32 +188,46 @@
             // Start a new call, which started 1000ms ago
             repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 102_000, intent = null))
             assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
-            assertThat((latest as OngoingActivityChipModel.Shown).startTimeMs).isEqualTo(499_000)
+            assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs)
+                .isEqualTo(499_000)
         }
 
     @Test
-    fun chip_inCall_nullIntent_clickListenerDoesNothing() =
+    fun chip_inCall_nullIntent_nullClickListener() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
 
             repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 1000, intent = null))
 
-            val clickListener = (latest as OngoingActivityChipModel.Shown).onClickListener
-
-            clickListener.onClick(chipView)
-            // Just verify nothing crashes
+            assertThat((latest as OngoingActivityChipModel.Shown).onClickListener).isNull()
         }
 
     @Test
-    fun chip_inCall_validIntent_clickListenerLaunchesIntent() =
+    fun chip_inCall_positiveStartTime_validIntent_clickListenerLaunchesIntent() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
 
             val intent = mock<PendingIntent>()
             repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 1000, intent = intent))
             val clickListener = (latest as OngoingActivityChipModel.Shown).onClickListener
+            assertThat(clickListener).isNotNull()
 
-            clickListener.onClick(chipView)
+            clickListener!!.onClick(chipView)
+
+            verify(kosmos.activityStarter).postStartActivityDismissingKeyguard(intent, null)
+        }
+
+    @Test
+    fun chip_inCall_zeroStartTime_validIntent_clickListenerLaunchesIntent() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.chip)
+
+            val intent = mock<PendingIntent>()
+            repo.setOngoingCallState(OngoingCallModel.InCall(startTimeMs = 0, intent = intent))
+            val clickListener = (latest as OngoingActivityChipModel.Shown).onClickListener
+            assertThat(clickListener).isNotNull()
+
+            clickListener!!.onClick(chipView)
 
             verify(kosmos.activityStarter).postStartActivityDismissingKeyguard(intent, null)
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/domian/interactor/MediaRouterChipInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/domian/interactor/MediaRouterChipInteractorTest.kt
new file mode 100644
index 0000000..ecb1a6d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/domian/interactor/MediaRouterChipInteractorTest.kt
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.chips.casttootherdevice.domian.interactor
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.mediarouter.data.repository.fakeMediaRouterRepository
+import com.android.systemui.statusbar.chips.casttootherdevice.domain.interactor.mediaRouterChipInteractor
+import com.android.systemui.statusbar.chips.casttootherdevice.domain.model.MediaRouterCastModel
+import com.android.systemui.statusbar.policy.CastDevice
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+class MediaRouterChipInteractorTest : SysuiTestCase() {
+    val kosmos = Kosmos()
+    val testScope = kosmos.testScope
+    val mediaRouterRepository = kosmos.fakeMediaRouterRepository
+
+    val underTest = kosmos.mediaRouterChipInteractor
+
+    @Test
+    fun mediaRouterCastingState_noDevices_doingNothing() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.mediaRouterCastingState)
+
+            mediaRouterRepository.castDevices.value = emptyList()
+
+            assertThat(latest).isEqualTo(MediaRouterCastModel.DoingNothing)
+        }
+
+    @Test
+    fun mediaRouterCastingState_disconnectedDevice_doingNothing() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.mediaRouterCastingState)
+
+            mediaRouterRepository.castDevices.value =
+                listOf(
+                    CastDevice(
+                        state = CastDevice.CastState.Disconnected,
+                        id = "id",
+                        name = "name",
+                        description = "desc",
+                        origin = CastDevice.CastOrigin.MediaRouter,
+                    )
+                )
+
+            assertThat(latest).isEqualTo(MediaRouterCastModel.DoingNothing)
+        }
+
+    @Test
+    fun mediaRouterCastingState_connectingDevice_casting_withName() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.mediaRouterCastingState)
+
+            mediaRouterRepository.castDevices.value =
+                listOf(
+                    CastDevice(
+                        state = CastDevice.CastState.Connecting,
+                        id = "id",
+                        name = "My Favorite Device",
+                        description = "desc",
+                        origin = CastDevice.CastOrigin.MediaRouter,
+                    )
+                )
+
+            assertThat(latest)
+                .isEqualTo(MediaRouterCastModel.Casting(deviceName = "My Favorite Device"))
+        }
+
+    @Test
+    fun mediaRouterCastingState_connectedDevice_casting_withName() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.mediaRouterCastingState)
+
+            mediaRouterRepository.castDevices.value =
+                listOf(
+                    CastDevice(
+                        state = CastDevice.CastState.Connected,
+                        id = "id",
+                        name = "My Second Favorite Device",
+                        description = "desc",
+                        origin = CastDevice.CastOrigin.MediaRouter,
+                    )
+                )
+
+            assertThat(latest)
+                .isEqualTo(MediaRouterCastModel.Casting(deviceName = "My Second Favorite Device"))
+        }
+
+    @Test
+    fun stopCasting_noDevices_doesNothing() =
+        testScope.runTest {
+            collectLastValue(underTest.mediaRouterCastingState)
+
+            mediaRouterRepository.castDevices.value = emptyList()
+            // Let the interactor catch up to the repo value
+            runCurrent()
+
+            underTest.stopCasting()
+
+            assertThat(mediaRouterRepository.lastStoppedDevice).isNull()
+        }
+
+    @Test
+    fun stopCasting_disconnectedDevice_doesNothing() =
+        testScope.runTest {
+            collectLastValue(underTest.mediaRouterCastingState)
+
+            mediaRouterRepository.castDevices.value =
+                listOf(
+                    CastDevice(
+                        state = CastDevice.CastState.Disconnected,
+                        id = "id",
+                        name = "name",
+                        description = "desc",
+                        origin = CastDevice.CastOrigin.MediaRouter,
+                    )
+                )
+            // Let the interactor catch up to the repo value
+            runCurrent()
+
+            underTest.stopCasting()
+
+            assertThat(mediaRouterRepository.lastStoppedDevice).isNull()
+        }
+
+    @Test
+    fun stopCasting_connectingDevice_notifiesRepo() =
+        testScope.runTest {
+            collectLastValue(underTest.mediaRouterCastingState)
+
+            val device =
+                CastDevice(
+                    state = CastDevice.CastState.Connecting,
+                    id = "id",
+                    name = "name",
+                    description = "desc",
+                    origin = CastDevice.CastOrigin.MediaRouter,
+                )
+            mediaRouterRepository.castDevices.value = listOf(device)
+            // Let the interactor catch up to the repo value
+            runCurrent()
+
+            underTest.stopCasting()
+
+            assertThat(mediaRouterRepository.lastStoppedDevice).isEqualTo(device)
+        }
+
+    @Test
+    fun stopCasting_connectedDevice_notifiesRepo() =
+        testScope.runTest {
+            collectLastValue(underTest.mediaRouterCastingState)
+
+            val device =
+                CastDevice(
+                    state = CastDevice.CastState.Connected,
+                    id = "id",
+                    name = "name",
+                    description = "desc",
+                    origin = CastDevice.CastOrigin.MediaRouter,
+                )
+            mediaRouterRepository.castDevices.value = listOf(device)
+            // Let the interactor catch up to the repo value
+            runCurrent()
+
+            underTest.stopCasting()
+
+            assertThat(mediaRouterRepository.lastStoppedDevice).isEqualTo(device)
+        }
+
+    @Test
+    fun stopCasting_multipleConnectedDevices_notifiesRepoOfFirst() =
+        testScope.runTest {
+            collectLastValue(underTest.mediaRouterCastingState)
+
+            val device1 =
+                CastDevice(
+                    state = CastDevice.CastState.Connected,
+                    id = "id1",
+                    name = "name",
+                    description = "desc",
+                    origin = CastDevice.CastOrigin.MediaRouter,
+                )
+            val device2 =
+                CastDevice(
+                    state = CastDevice.CastState.Connected,
+                    id = "id2",
+                    name = "name",
+                    description = "desc",
+                    origin = CastDevice.CastOrigin.MediaRouter,
+                )
+            mediaRouterRepository.castDevices.value = listOf(device1, device2)
+            // Let the interactor catch up to the repo value
+            runCurrent()
+
+            underTest.stopCasting()
+
+            assertThat(mediaRouterRepository.lastStoppedDevice).isEqualTo(device1)
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegateTest.kt
new file mode 100644
index 0000000..c8397bd
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegateTest.kt
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.chips.casttootherdevice.ui.view
+
+import android.content.ComponentName
+import android.content.DialogInterface
+import android.content.Intent
+import android.content.applicationContext
+import android.content.packageManager
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.mediaprojection.data.model.MediaProjectionState
+import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
+import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.mediaProjectionChipInteractor
+import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
+import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper
+import com.android.systemui.statusbar.phone.SystemUIDialog
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+class EndCastScreenToOtherDeviceDialogDelegateTest : SysuiTestCase() {
+    private val kosmos = Kosmos().also { it.testCase = this }
+    private val sysuiDialog = mock<SystemUIDialog>()
+    private lateinit var underTest: EndCastScreenToOtherDeviceDialogDelegate
+
+    @Test
+    fun icon() {
+        createAndSetDelegate(ENTIRE_SCREEN)
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(sysuiDialog).setIcon(R.drawable.ic_cast_connected)
+    }
+
+    @Test
+    fun title() {
+        createAndSetDelegate(SINGLE_TASK)
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(sysuiDialog).setTitle(R.string.cast_to_other_device_stop_dialog_title)
+    }
+
+    @Test
+    fun message_entireScreen_unknownDevice() {
+        createAndSetDelegate(ENTIRE_SCREEN, deviceName = null)
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(sysuiDialog)
+            .setMessage(
+                context.getString(R.string.cast_to_other_device_stop_dialog_message_entire_screen)
+            )
+    }
+
+    @Test
+    fun message_entireScreen_hasDevice() {
+        createAndSetDelegate(ENTIRE_SCREEN, deviceName = "My Favorite Device")
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(sysuiDialog)
+            .setMessage(
+                context.getString(
+                    R.string.cast_to_other_device_stop_dialog_message_entire_screen_with_device,
+                    "My Favorite Device",
+                )
+            )
+    }
+
+    @Test
+    fun message_singleTask_unknownAppName_unknownDevice() {
+        val baseIntent =
+            Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
+        whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
+            .thenThrow(PackageManager.NameNotFoundException())
+
+        createAndSetDelegate(
+            MediaProjectionState.Projecting.SingleTask(
+                HOST_PACKAGE,
+                createTask(taskId = 1, baseIntent = baseIntent)
+            ),
+            deviceName = null,
+        )
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(sysuiDialog)
+            .setMessage(
+                context.getString(R.string.cast_to_other_device_stop_dialog_message_generic)
+            )
+    }
+
+    @Test
+    fun message_singleTask_unknownAppName_hasDevice() {
+        val baseIntent =
+            Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
+        whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
+            .thenThrow(PackageManager.NameNotFoundException())
+
+        createAndSetDelegate(
+            MediaProjectionState.Projecting.SingleTask(
+                HOST_PACKAGE,
+                createTask(taskId = 1, baseIntent = baseIntent)
+            ),
+            deviceName = "My Favorite Device",
+        )
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(sysuiDialog)
+            .setMessage(
+                context.getString(
+                    R.string.cast_to_other_device_stop_dialog_message_generic_with_device,
+                    "My Favorite Device",
+                )
+            )
+    }
+
+    @Test
+    fun message_singleTask_hasAppName_unknownDevice() {
+        val baseIntent =
+            Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
+        val appInfo = mock<ApplicationInfo>()
+        whenever(appInfo.loadLabel(kosmos.packageManager)).thenReturn("Fake Package")
+        whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
+            .thenReturn(appInfo)
+
+        createAndSetDelegate(
+            MediaProjectionState.Projecting.SingleTask(
+                HOST_PACKAGE,
+                createTask(taskId = 1, baseIntent = baseIntent)
+            ),
+            deviceName = null,
+        )
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(sysuiDialog)
+            .setMessage(
+                context.getString(
+                    R.string.cast_to_other_device_stop_dialog_message_specific_app,
+                    "Fake Package",
+                )
+            )
+    }
+
+    @Test
+    fun message_singleTask_hasAppName_hasDevice() {
+        val baseIntent =
+            Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
+        val appInfo = mock<ApplicationInfo>()
+        whenever(appInfo.loadLabel(kosmos.packageManager)).thenReturn("Fake Package")
+        whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
+            .thenReturn(appInfo)
+
+        createAndSetDelegate(
+            MediaProjectionState.Projecting.SingleTask(
+                HOST_PACKAGE,
+                createTask(taskId = 1, baseIntent = baseIntent)
+            ),
+            deviceName = "My Favorite Device",
+        )
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(sysuiDialog)
+            .setMessage(
+                context.getString(
+                    R.string.cast_to_other_device_stop_dialog_message_specific_app_with_device,
+                    "Fake Package",
+                    "My Favorite Device",
+                )
+            )
+    }
+
+    @Test
+    fun negativeButton() {
+        createAndSetDelegate(ENTIRE_SCREEN)
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(sysuiDialog).setNegativeButton(R.string.close_dialog_button, null)
+    }
+
+    @Test
+    fun positiveButton() =
+        kosmos.testScope.runTest {
+            createAndSetDelegate(SINGLE_TASK)
+
+            underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+            val clickListener = argumentCaptor<DialogInterface.OnClickListener>()
+
+            // Verify the button has the right text
+            verify(sysuiDialog)
+                .setPositiveButton(
+                    eq(R.string.cast_to_other_device_stop_dialog_button),
+                    clickListener.capture()
+                )
+
+            // Verify that clicking the button stops the recording
+            assertThat(kosmos.fakeMediaProjectionRepository.stopProjectingInvoked).isFalse()
+
+            clickListener.firstValue.onClick(mock<DialogInterface>(), 0)
+            runCurrent()
+
+            assertThat(kosmos.fakeMediaProjectionRepository.stopProjectingInvoked).isTrue()
+        }
+
+    private fun createAndSetDelegate(
+        state: MediaProjectionState.Projecting,
+        deviceName: String? = null,
+    ) {
+        underTest =
+            EndCastScreenToOtherDeviceDialogDelegate(
+                kosmos.endMediaProjectionDialogHelper,
+                kosmos.applicationContext,
+                stopAction = kosmos.mediaProjectionChipInteractor::stopProjecting,
+                ProjectionChipModel.Projecting(
+                    ProjectionChipModel.Type.CAST_TO_OTHER_DEVICE,
+                    state,
+                    deviceName,
+                ),
+            )
+    }
+
+    companion object {
+        private const val HOST_PACKAGE = "fake.host.package"
+        private val ENTIRE_SCREEN = MediaProjectionState.Projecting.EntireScreen(HOST_PACKAGE)
+        private val SINGLE_TASK =
+            MediaProjectionState.Projecting.SingleTask(HOST_PACKAGE, createTask(taskId = 1))
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastToOtherDeviceDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastToOtherDeviceDialogDelegateTest.kt
deleted file mode 100644
index c6fb481..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastToOtherDeviceDialogDelegateTest.kt
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.chips.casttootherdevice.ui.view
-
-import android.content.ComponentName
-import android.content.DialogInterface
-import android.content.Intent
-import android.content.packageManager
-import android.content.pm.ApplicationInfo
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.testCase
-import com.android.systemui.kosmos.testScope
-import com.android.systemui.mediaprojection.data.model.MediaProjectionState
-import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
-import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask
-import com.android.systemui.res.R
-import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.mediaProjectionChipInteractor
-import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
-import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper
-import com.android.systemui.statusbar.phone.SystemUIDialog
-import com.google.common.truth.Truth.assertThat
-import kotlin.test.Test
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.runCurrent
-import kotlinx.coroutines.test.runTest
-import org.mockito.kotlin.any
-import org.mockito.kotlin.argumentCaptor
-import org.mockito.kotlin.eq
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.verify
-import org.mockito.kotlin.whenever
-
-@SmallTest
-@OptIn(ExperimentalCoroutinesApi::class)
-class EndCastToOtherDeviceDialogDelegateTest : SysuiTestCase() {
-    private val kosmos = Kosmos().also { it.testCase = this }
-    private val sysuiDialog = mock<SystemUIDialog>()
-    private lateinit var underTest: EndCastToOtherDeviceDialogDelegate
-
-    @Test
-    fun icon() {
-        createAndSetDelegate(ENTIRE_SCREEN)
-
-        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
-
-        verify(sysuiDialog).setIcon(R.drawable.ic_cast_connected)
-    }
-
-    @Test
-    fun title() {
-        createAndSetDelegate(SINGLE_TASK)
-
-        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
-
-        verify(sysuiDialog).setTitle(R.string.cast_to_other_device_stop_dialog_title)
-    }
-
-    @Test
-    fun message_entireScreen() {
-        createAndSetDelegate(ENTIRE_SCREEN)
-
-        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
-
-        verify(sysuiDialog)
-            .setMessage(context.getString(R.string.cast_to_other_device_stop_dialog_message))
-    }
-
-    @Test
-    fun message_singleTask() {
-        val baseIntent =
-            Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
-        val appInfo = mock<ApplicationInfo>()
-        whenever(appInfo.loadLabel(kosmos.packageManager)).thenReturn("Fake Package")
-        whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
-            .thenReturn(appInfo)
-
-        createAndSetDelegate(
-            MediaProjectionState.Projecting.SingleTask(
-                HOST_PACKAGE,
-                createTask(taskId = 1, baseIntent = baseIntent)
-            )
-        )
-
-        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
-
-        // It'd be nice to use R.string.cast_to_other_device_stop_dialog_message_specific_app
-        // directly, but it includes the <b> tags which aren't in the returned string.
-        val result = argumentCaptor<CharSequence>()
-        verify(sysuiDialog).setMessage(result.capture())
-        assertThat(result.firstValue.toString()).isEqualTo("You will stop casting Fake Package")
-    }
-
-    @Test
-    fun negativeButton() {
-        createAndSetDelegate(ENTIRE_SCREEN)
-
-        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
-
-        verify(sysuiDialog).setNegativeButton(R.string.close_dialog_button, null)
-    }
-
-    @Test
-    fun positiveButton() =
-        kosmos.testScope.runTest {
-            createAndSetDelegate(SINGLE_TASK)
-
-            underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
-
-            val clickListener = argumentCaptor<DialogInterface.OnClickListener>()
-
-            // Verify the button has the right text
-            verify(sysuiDialog)
-                .setPositiveButton(
-                    eq(R.string.cast_to_other_device_stop_dialog_button),
-                    clickListener.capture()
-                )
-
-            // Verify that clicking the button stops the recording
-            assertThat(kosmos.fakeMediaProjectionRepository.stopProjectingInvoked).isFalse()
-
-            clickListener.firstValue.onClick(mock<DialogInterface>(), 0)
-            runCurrent()
-
-            assertThat(kosmos.fakeMediaProjectionRepository.stopProjectingInvoked).isTrue()
-        }
-
-    private fun createAndSetDelegate(state: MediaProjectionState.Projecting) {
-        underTest =
-            EndCastToOtherDeviceDialogDelegate(
-                kosmos.endMediaProjectionDialogHelper,
-                stopAction = kosmos.mediaProjectionChipInteractor::stopProjecting,
-                ProjectionChipModel.Projecting(
-                    ProjectionChipModel.Type.CAST_TO_OTHER_DEVICE,
-                    state,
-                ),
-            )
-    }
-
-    companion object {
-        private const val HOST_PACKAGE = "fake.host.package"
-        private val ENTIRE_SCREEN = MediaProjectionState.Projecting.EntireScreen(HOST_PACKAGE)
-        private val SINGLE_TASK =
-            MediaProjectionState.Projecting.SingleTask(HOST_PACKAGE, createTask(taskId = 1))
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegateTest.kt
new file mode 100644
index 0000000..e6101f5
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegateTest.kt
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.chips.casttootherdevice.ui.view
+
+import android.content.DialogInterface
+import android.content.applicationContext
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testCase
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.mediarouter.data.repository.fakeMediaRouterRepository
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.chips.casttootherdevice.domain.interactor.mediaRouterChipInteractor
+import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper
+import com.android.systemui.statusbar.phone.SystemUIDialog
+import com.android.systemui.statusbar.policy.CastDevice
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+
+@SmallTest
+@OptIn(ExperimentalCoroutinesApi::class)
+class EndGenericCastToOtherDeviceDialogDelegateTest : SysuiTestCase() {
+    private val kosmos = Kosmos().also { it.testCase = this }
+    private val sysuiDialog = mock<SystemUIDialog>()
+    private lateinit var underTest: EndGenericCastToOtherDeviceDialogDelegate
+
+    @Test
+    fun icon() {
+        createAndSetDelegate()
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(sysuiDialog).setIcon(R.drawable.ic_cast_connected)
+    }
+
+    @Test
+    fun title() {
+        createAndSetDelegate()
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(sysuiDialog).setTitle(R.string.cast_to_other_device_stop_dialog_title)
+    }
+
+    @Test
+    fun message_unknownDevice() {
+        createAndSetDelegate(deviceName = null)
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(sysuiDialog)
+            .setMessage(
+                context.getString(R.string.cast_to_other_device_stop_dialog_message_generic)
+            )
+    }
+
+    @Test
+    fun message_hasDevice() {
+        createAndSetDelegate(deviceName = "My Favorite Device")
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(sysuiDialog)
+            .setMessage(
+                context.getString(
+                    R.string.cast_to_other_device_stop_dialog_message_generic_with_device,
+                    "My Favorite Device",
+                )
+            )
+    }
+
+    @Test
+    fun negativeButton() {
+        createAndSetDelegate()
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(sysuiDialog).setNegativeButton(R.string.close_dialog_button, null)
+    }
+
+    @Test
+    fun positiveButton() =
+        kosmos.testScope.runTest {
+            createAndSetDelegate()
+
+            // Set up a real device so the stop works correctly
+            collectLastValue(kosmos.mediaRouterChipInteractor.mediaRouterCastingState)
+            val device =
+                CastDevice(
+                    state = CastDevice.CastState.Connected,
+                    id = "id",
+                    name = "name",
+                    description = "desc",
+                    origin = CastDevice.CastOrigin.MediaRouter,
+                )
+            kosmos.fakeMediaRouterRepository.castDevices.value = listOf(device)
+            // Let everything catch up to the repo value
+            runCurrent()
+            runCurrent()
+
+            underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+            val clickListener = argumentCaptor<DialogInterface.OnClickListener>()
+
+            // Verify the button has the right text
+            verify(sysuiDialog)
+                .setPositiveButton(
+                    eq(R.string.cast_to_other_device_stop_dialog_button),
+                    clickListener.capture()
+                )
+
+            // Verify that clicking the button stops the recording
+            assertThat(kosmos.fakeMediaRouterRepository.lastStoppedDevice).isNull()
+
+            clickListener.firstValue.onClick(mock<DialogInterface>(), 0)
+            runCurrent()
+
+            assertThat(kosmos.fakeMediaRouterRepository.lastStoppedDevice).isEqualTo(device)
+        }
+
+    private fun createAndSetDelegate(deviceName: String? = null) {
+        underTest =
+            EndGenericCastToOtherDeviceDialogDelegate(
+                kosmos.endMediaProjectionDialogHelper,
+                kosmos.applicationContext,
+                deviceName,
+                stopAction = kosmos.mediaRouterChipInteractor::stopCasting,
+            )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
index 93d781f..fe29140 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
@@ -20,6 +20,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.mockDialogTransitionAnimator
+import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.kosmos.Kosmos
@@ -28,15 +29,19 @@
 import com.android.systemui.mediaprojection.data.model.MediaProjectionState
 import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
 import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask
+import com.android.systemui.mediarouter.data.repository.fakeMediaRouterRepository
 import com.android.systemui.res.R
-import com.android.systemui.statusbar.chips.casttootherdevice.ui.view.EndCastToOtherDeviceDialogDelegate
+import com.android.systemui.statusbar.chips.casttootherdevice.ui.view.EndCastScreenToOtherDeviceDialogDelegate
+import com.android.systemui.statusbar.chips.casttootherdevice.ui.view.EndGenericCastToOtherDeviceDialogDelegate
 import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.CAST_TO_OTHER_DEVICES_PACKAGE
 import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.NORMAL_PACKAGE
 import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.setUpPackageManagerForMediaProjection
+import com.android.systemui.statusbar.chips.ui.model.ColorsModel
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
 import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory
+import com.android.systemui.statusbar.policy.CastDevice
 import com.android.systemui.util.time.fakeSystemClock
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
@@ -54,9 +59,11 @@
     private val kosmos = Kosmos().also { it.testCase = this }
     private val testScope = kosmos.testScope
     private val mediaProjectionRepo = kosmos.fakeMediaProjectionRepository
+    private val mediaRouterRepo = kosmos.fakeMediaRouterRepository
     private val systemClock = kosmos.fakeSystemClock
 
-    private val mockCastDialog = mock<SystemUIDialog>()
+    private val mockScreenCastDialog = mock<SystemUIDialog>()
+    private val mockGenericCastDialog = mock<SystemUIDialog>()
 
     private val chipBackgroundView = mock<ChipBackgroundContainer>()
     private val chipView =
@@ -75,14 +82,25 @@
     fun setUp() {
         setUpPackageManagerForMediaProjection(kosmos)
 
-        whenever(kosmos.mockSystemUIDialogFactory.create(any<EndCastToOtherDeviceDialogDelegate>()))
-            .thenReturn(mockCastDialog)
+        whenever(
+                kosmos.mockSystemUIDialogFactory.create(
+                    any<EndCastScreenToOtherDeviceDialogDelegate>()
+                )
+            )
+            .thenReturn(mockScreenCastDialog)
+        whenever(
+                kosmos.mockSystemUIDialogFactory.create(
+                    any<EndGenericCastToOtherDeviceDialogDelegate>()
+                )
+            )
+            .thenReturn(mockGenericCastDialog)
     }
 
     @Test
     fun chip_notProjectingState_isHidden() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
+            mediaRouterRepo.castDevices.value = emptyList()
 
             mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
 
@@ -90,9 +108,10 @@
         }
 
     @Test
-    fun chip_singleTaskState_otherDevicesPackage_isShown() =
+    fun chip_projectionIsSingleTaskState_otherDevicesPackage_isShownAsTimer_forScreen() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
+            mediaRouterRepo.castDevices.value = emptyList()
 
             mediaProjectionRepo.mediaProjectionState.value =
                 MediaProjectionState.Projecting.SingleTask(
@@ -100,26 +119,106 @@
                     createTask(taskId = 1),
                 )
 
-            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
             val icon = (latest as OngoingActivityChipModel.Shown).icon
             assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
+            assertThat((icon.contentDescription as ContentDescription.Resource).res)
+                .isEqualTo(R.string.cast_screen_to_other_device_chip_accessibility_label)
         }
 
     @Test
-    fun chip_entireScreenState_otherDevicesPackage_isShown() =
+    fun chip_projectionIsEntireScreenState_otherDevicesPackage_isShownAsTimer_forScreen() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.chip)
+            mediaRouterRepo.castDevices.value = emptyList()
+
+            mediaProjectionRepo.mediaProjectionState.value =
+                MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)
+
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
+            val icon = (latest as OngoingActivityChipModel.Shown).icon
+            assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
+            assertThat((icon.contentDescription as ContentDescription.Resource).res)
+                .isEqualTo(R.string.cast_screen_to_other_device_chip_accessibility_label)
+        }
+
+    @Test
+    fun chip_routerStateDoingNothing_isHidden() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.chip)
+            mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
+
+            mediaRouterRepo.castDevices.value = emptyList()
+
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
+        }
+
+    @Test
+    fun chip_routerStateCasting_isShownAsGenericIconOnly() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.chip)
+            mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
+
+            mediaRouterRepo.castDevices.value =
+                listOf(
+                    CastDevice(
+                        state = CastDevice.CastState.Connected,
+                        id = "id",
+                        name = "name",
+                        description = "desc",
+                        origin = CastDevice.CastOrigin.MediaRouter,
+                    )
+                )
+
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
+            val icon = (latest as OngoingActivityChipModel.Shown).icon
+            assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
+            // This content description is just generic "Casting", not "Casting screen"
+            assertThat((icon.contentDescription as ContentDescription.Resource).res)
+                .isEqualTo(R.string.accessibility_casting)
+        }
+
+    @Test
+    fun chip_projectingAndRouterCasting_projectionInfoShown() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.chip)
+
+            mediaProjectionRepo.mediaProjectionState.value =
+                MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)
+            mediaRouterRepo.castDevices.value =
+                listOf(
+                    CastDevice(
+                        state = CastDevice.CastState.Connected,
+                        id = "id",
+                        name = "name",
+                        description = "desc",
+                        origin = CastDevice.CastOrigin.MediaRouter,
+                    )
+                )
+
+            // Only the projection info will show a timer
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
+            val icon = (latest as OngoingActivityChipModel.Shown).icon
+            assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
+            // MediaProjection == screen casting, so this content description reflects that we're
+            // using the MediaProjection information.
+            assertThat((icon.contentDescription as ContentDescription.Resource).res)
+                .isEqualTo(R.string.cast_screen_to_other_device_chip_accessibility_label)
+        }
+
+    @Test
+    fun chip_colorsAreRed() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
 
             mediaProjectionRepo.mediaProjectionState.value =
                 MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)
 
-            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
-            val icon = (latest as OngoingActivityChipModel.Shown).icon
-            assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_cast_connected)
+            assertThat((latest as OngoingActivityChipModel.Shown).colors).isEqualTo(ColorsModel.Red)
         }
 
     @Test
-    fun chip_singleTaskState_normalPackage_isHidden() =
+    fun chip_projectionIsSingleTaskState_normalPackage_isHidden() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
 
@@ -130,7 +229,7 @@
         }
 
     @Test
-    fun chip_entireScreenState_normalPackage_isHidden() =
+    fun chip_projectionIsEntireScreenState_normalPackage_isHidden() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
 
@@ -141,7 +240,7 @@
         }
 
     @Test
-    fun chip_timeResetsOnEachNewShare() =
+    fun chip_projectionOnly_timeResetsOnEachNewShare() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
 
@@ -150,7 +249,7 @@
                 MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)
 
             assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
-            assertThat((latest as OngoingActivityChipModel.Shown).startTimeMs).isEqualTo(1234)
+            assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs).isEqualTo(1234)
 
             mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
             assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
@@ -163,22 +262,54 @@
                 )
 
             assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
-            assertThat((latest as OngoingActivityChipModel.Shown).startTimeMs).isEqualTo(5678)
+            assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs).isEqualTo(5678)
         }
 
     @Test
-    fun chip_entireScreen_clickListenerShowsCastDialog() =
+    fun chip_routerInfoThenProjectionInfo_switchesToTimer() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.chip)
+
+            // First, set only MediaRouter to have information and verify we just show the icon
+            systemClock.setElapsedRealtime(1234)
+            mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
+            mediaRouterRepo.castDevices.value =
+                listOf(
+                    CastDevice(
+                        state = CastDevice.CastState.Connected,
+                        id = "id",
+                        name = "name",
+                        description = "desc",
+                        origin = CastDevice.CastOrigin.MediaRouter,
+                    )
+                )
+
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.IconOnly::class.java)
+
+            // Later, set MediaProjection to also have information
+            systemClock.setElapsedRealtime(5678)
+            mediaProjectionRepo.mediaProjectionState.value =
+                MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)
+
+            // Verify the new time is used
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
+            assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs).isEqualTo(5678)
+        }
+
+    @Test
+    fun chip_projectionStateEntireScreen_clickListenerShowsScreenCastDialog() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
             mediaProjectionRepo.mediaProjectionState.value =
                 MediaProjectionState.Projecting.EntireScreen(CAST_TO_OTHER_DEVICES_PACKAGE)
 
             val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
+            assertThat(clickListener).isNotNull()
 
-            clickListener.onClick(chipView)
+            clickListener!!.onClick(chipView)
             verify(kosmos.mockDialogTransitionAnimator)
                 .showFromView(
-                    eq(mockCastDialog),
+                    eq(mockScreenCastDialog),
                     eq(chipBackgroundView),
                     eq(null),
                     ArgumentMatchers.anyBoolean(),
@@ -186,7 +317,7 @@
         }
 
     @Test
-    fun chip_singleTask_clickListenerShowsCastDialog() =
+    fun chip_projectionStateSingleTask_clickListenerShowsScreenCastDialog() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
 
@@ -197,11 +328,41 @@
                 )
 
             val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
+            assertThat(clickListener).isNotNull()
 
-            clickListener.onClick(chipView)
+            clickListener!!.onClick(chipView)
             verify(kosmos.mockDialogTransitionAnimator)
                 .showFromView(
-                    eq(mockCastDialog),
+                    eq(mockScreenCastDialog),
+                    eq(chipBackgroundView),
+                    eq(null),
+                    ArgumentMatchers.anyBoolean(),
+                )
+        }
+
+    @Test
+    fun chip_routerStateCasting_clickListenerShowsGenericCastDialog() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.chip)
+
+            mediaRouterRepo.castDevices.value =
+                listOf(
+                    CastDevice(
+                        state = CastDevice.CastState.Connected,
+                        id = "id",
+                        name = "name",
+                        description = "desc",
+                        origin = CastDevice.CastOrigin.MediaRouter,
+                    )
+                )
+
+            val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
+            assertThat(clickListener).isNotNull()
+
+            clickListener!!.onClick(chipView)
+            verify(kosmos.mockDialogTransitionAnimator)
+                .showFromView(
+                    eq(mockGenericCastDialog),
                     eq(chipBackgroundView),
                     eq(null),
                     ArgumentMatchers.anyBoolean(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperTest.kt
index ee929ae..ab935fe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperTest.kt
@@ -27,7 +27,6 @@
 import com.android.systemui.kosmos.testCase
 import com.android.systemui.mediaprojection.data.model.MediaProjectionState
 import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask
-import com.android.systemui.res.R
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory
 import com.google.common.truth.Truth.assertThat
@@ -56,19 +55,15 @@
     }
 
     @Test
-    fun getDialogMessage_entireScreen_isGenericMessage() {
+    fun getAppName_stateVersion_entireScreen_returnsNull() {
         val result =
-            underTest.getDialogMessage(
-                MediaProjectionState.Projecting.EntireScreen("host.package"),
-                R.string.accessibility_home,
-                R.string.cast_to_other_device_stop_dialog_message_specific_app
-            )
+            underTest.getAppName(MediaProjectionState.Projecting.EntireScreen("host.package"))
 
-        assertThat(result).isEqualTo(context.getString(R.string.accessibility_home))
+        assertThat(result).isNull()
     }
 
     @Test
-    fun getDialogMessage_singleTask_cannotFindPackage_isGenericMessage() {
+    fun getAppName_stateVersion_singleTask_cannotFindPackage_returnsNull() {
         val baseIntent =
             Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
         whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
@@ -77,21 +72,16 @@
         val projectionState =
             MediaProjectionState.Projecting.SingleTask(
                 "host.package",
-                createTask(taskId = 1, baseIntent = baseIntent)
+                createTask(taskId = 1, baseIntent = baseIntent),
             )
 
-        val result =
-            underTest.getDialogMessage(
-                projectionState,
-                R.string.accessibility_home,
-                R.string.cast_to_other_device_stop_dialog_message_specific_app
-            )
+        val result = underTest.getAppName(projectionState)
 
-        assertThat(result).isEqualTo(context.getString(R.string.accessibility_home))
+        assertThat(result).isNull()
     }
 
     @Test
-    fun getDialogMessage_singleTask_findsPackage_isSpecificMessageWithAppLabel() {
+    fun getAppName_stateVersion_singleTask_findsPackage_returnsName() {
         val baseIntent =
             Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
         val appInfo = mock<ApplicationInfo>()
@@ -102,93 +92,66 @@
         val projectionState =
             MediaProjectionState.Projecting.SingleTask(
                 "host.package",
-                createTask(taskId = 1, baseIntent = baseIntent)
+                createTask(taskId = 1, baseIntent = baseIntent),
             )
 
-        val result =
-            underTest.getDialogMessage(
-                projectionState,
-                R.string.accessibility_home,
-                R.string.cast_to_other_device_stop_dialog_message_specific_app
-            )
+        val result = underTest.getAppName(projectionState)
 
-        // It'd be nice to use the R.string resources directly, but they include the <b> tags which
-        // aren't in the returned string.
-        assertThat(result.toString()).isEqualTo("You will stop casting Fake Package")
+        assertThat(result).isEqualTo("Fake Package")
     }
 
     @Test
-    fun getDialogMessage_nullTask_isGenericMessage() {
-        val result =
-            underTest.getDialogMessage(
-                specificTaskInfo = null,
-                R.string.accessibility_home,
-                R.string.cast_to_other_device_stop_dialog_message_specific_app,
-            )
+    fun getAppName_taskInfoVersion_null_returnsNull() {
+        val result = underTest.getAppName(specificTaskInfo = null)
 
-        assertThat(result).isEqualTo(context.getString(R.string.accessibility_home))
+        assertThat(result).isNull()
     }
 
     @Test
-    fun getDialogMessage_withTask_cannotFindPackage_isGenericMessage() {
+    fun getAppName_taskInfoVersion_cannotFindPackage_returnsNull() {
         val baseIntent =
             Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
         whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
             .thenThrow(PackageManager.NameNotFoundException())
-        val task = createTask(taskId = 1, baseIntent = baseIntent)
 
-        val result =
-            underTest.getDialogMessage(
-                task,
-                R.string.accessibility_home,
-                R.string.cast_to_other_device_stop_dialog_message_specific_app
-            )
+        val result = underTest.getAppName(createTask(taskId = 1, baseIntent = baseIntent))
 
-        assertThat(result).isEqualTo(context.getString(R.string.accessibility_home))
+        assertThat(result).isNull()
     }
 
     @Test
-    fun getDialogMessage_withTask_findsPackage_isSpecificMessageWithAppLabel() {
+    fun getAppName_taskInfoVersion_findsPackage_returnsName() {
         val baseIntent =
             Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
         val appInfo = mock<ApplicationInfo>()
         whenever(appInfo.loadLabel(kosmos.packageManager)).thenReturn("Fake Package")
         whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
             .thenReturn(appInfo)
-        val task = createTask(taskId = 1, baseIntent = baseIntent)
 
-        val result =
-            underTest.getDialogMessage(
-                task,
-                R.string.accessibility_home,
-                R.string.cast_to_other_device_stop_dialog_message_specific_app
-            )
+        val result = underTest.getAppName(createTask(taskId = 1, baseIntent = baseIntent))
 
-        assertThat(result.toString()).isEqualTo("You will stop casting Fake Package")
+        assertThat(result).isEqualTo("Fake Package")
     }
 
     @Test
-    fun getDialogMessage_appLabelHasSpecialCharacters_isEscaped() {
-        val baseIntent =
-            Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
+    fun getAppName_packageNameVersion_cannotFindPackage_returnsNull() {
+        whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
+            .thenThrow(PackageManager.NameNotFoundException())
+
+        val result = underTest.getAppName("fake.task.package")
+
+        assertThat(result).isNull()
+    }
+
+    @Test
+    fun getAppName_packageNameVersion_findsPackage_returnsName() {
         val appInfo = mock<ApplicationInfo>()
-        whenever(appInfo.loadLabel(kosmos.packageManager)).thenReturn("Fake & Package <Here>")
+        whenever(appInfo.loadLabel(kosmos.packageManager)).thenReturn("Fake Package")
         whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
             .thenReturn(appInfo)
 
-        val projectionState =
-            MediaProjectionState.Projecting.SingleTask(
-                "host.package",
-                createTask(taskId = 1, baseIntent = baseIntent)
-            )
+        val result = underTest.getAppName("fake.task.package")
 
-        val result =
-            underTest.getDialogMessage(
-                projectionState,
-                R.string.accessibility_home,
-                R.string.cast_to_other_device_stop_dialog_message_specific_app
-            )
-
-        assertThat(result.toString()).isEqualTo("You will stop casting Fake & Package <Here>")
+        assertThat(result).isEqualTo("Fake Package")
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt
index 7e667de..bfb63ac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt
@@ -20,6 +20,7 @@
 import android.content.ComponentName
 import android.content.DialogInterface
 import android.content.Intent
+import android.content.applicationContext
 import android.content.packageManager
 import android.content.pm.ApplicationInfo
 import androidx.test.filters.SmallTest
@@ -95,11 +96,13 @@
 
         underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
 
-        // It'd be nice to use R.string.screenrecord_stop_dialog_message_specific_app directly, but
-        // it includes the <b> tags which aren't in the returned string.
-        val result = argumentCaptor<CharSequence>()
-        verify(sysuiDialog).setMessage(result.capture())
-        assertThat(result.firstValue.toString()).isEqualTo("You will stop recording Fake Package")
+        verify(sysuiDialog)
+            .setMessage(
+                context.getString(
+                    R.string.screenrecord_stop_dialog_message_specific_app,
+                    "Fake Package",
+                )
+            )
     }
 
     @Test
@@ -140,6 +143,7 @@
         underTest =
             EndScreenRecordingDialogDelegate(
                 kosmos.endMediaProjectionDialogHelper,
+                kosmos.applicationContext,
                 stopAction = kosmos.screenRecordChipInteractor::stopRecording,
                 recordedTask,
             )
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
index 45044f7..0a06cc7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelTest.kt
@@ -32,6 +32,7 @@
 import com.android.systemui.screenrecord.data.model.ScreenRecordModel
 import com.android.systemui.screenrecord.data.repository.screenRecordRepository
 import com.android.systemui.statusbar.chips.screenrecord.ui.view.EndScreenRecordingDialogDelegate
+import com.android.systemui.statusbar.chips.ui.model.ColorsModel
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
 import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
 import com.android.systemui.statusbar.phone.SystemUIDialog
@@ -87,25 +88,82 @@
         }
 
     @Test
-    fun chip_startingState_isHidden() =
+    fun chip_startingState_isShownAsCountdownWithoutIconOrClickListener() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
 
             screenRecordRepo.screenRecordState.value = ScreenRecordModel.Starting(400)
 
-            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Countdown::class.java)
+            assertThat((latest as OngoingActivityChipModel.Shown).icon).isNull()
+            assertThat((latest as OngoingActivityChipModel.Shown).onClickListener).isNull()
+        }
+
+    // The millis we typically get from [ScreenRecordRepository] are around 2995, 1995, and 995.
+    @Test
+    fun chip_startingState_millis2995_is3() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.chip)
+
+            screenRecordRepo.screenRecordState.value = ScreenRecordModel.Starting(2995)
+
+            assertThat((latest as OngoingActivityChipModel.Shown.Countdown).secondsUntilStarted)
+                .isEqualTo(3)
         }
 
     @Test
-    fun chip_recordingState_isShownWithIcon() =
+    fun chip_startingState_millis1995_is2() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.chip)
+
+            screenRecordRepo.screenRecordState.value = ScreenRecordModel.Starting(1995)
+
+            assertThat((latest as OngoingActivityChipModel.Shown.Countdown).secondsUntilStarted)
+                .isEqualTo(2)
+        }
+
+    @Test
+    fun chip_startingState_millis995_is1() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.chip)
+
+            screenRecordRepo.screenRecordState.value = ScreenRecordModel.Starting(995)
+
+            assertThat((latest as OngoingActivityChipModel.Shown.Countdown).secondsUntilStarted)
+                .isEqualTo(1)
+        }
+
+    @Test
+    fun chip_recordingState_isShownAsTimerWithIcon() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
 
             screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
 
-            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
             val icon = (latest as OngoingActivityChipModel.Shown).icon
             assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_screenrecord)
+            assertThat(icon.contentDescription).isNotNull()
+        }
+
+    @Test
+    fun chip_startingState_colorsAreRed() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.chip)
+
+            screenRecordRepo.screenRecordState.value = ScreenRecordModel.Starting(2000L)
+
+            assertThat((latest as OngoingActivityChipModel.Shown).colors).isEqualTo(ColorsModel.Red)
+        }
+
+    @Test
+    fun chip_recordingState_colorsAreRed() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.chip)
+
+            screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
+
+            assertThat((latest as OngoingActivityChipModel.Shown).colors).isEqualTo(ColorsModel.Red)
         }
 
     @Test
@@ -117,7 +175,7 @@
             screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
 
             assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
-            assertThat((latest as OngoingActivityChipModel.Shown).startTimeMs).isEqualTo(1234)
+            assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs).isEqualTo(1234)
 
             screenRecordRepo.screenRecordState.value = ScreenRecordModel.DoingNothing
             assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
@@ -126,7 +184,7 @@
             screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording
 
             assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
-            assertThat((latest as OngoingActivityChipModel.Shown).startTimeMs).isEqualTo(5678)
+            assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs).isEqualTo(5678)
         }
 
     @Test
@@ -137,8 +195,9 @@
             mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
 
             val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
+            assertThat(clickListener).isNotNull()
 
-            clickListener.onClick(chipView)
+            clickListener!!.onClick(chipView)
             // EndScreenRecordingDialogDelegate will test that the dialog has the right message
             verify(kosmos.mockDialogTransitionAnimator)
                 .showFromView(
@@ -158,8 +217,9 @@
                 MediaProjectionState.Projecting.EntireScreen("host.package")
 
             val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
+            assertThat(clickListener).isNotNull()
 
-            clickListener.onClick(chipView)
+            clickListener!!.onClick(chipView)
             // EndScreenRecordingDialogDelegate will test that the dialog has the right message
             verify(kosmos.mockDialogTransitionAnimator)
                 .showFromView(
@@ -182,8 +242,9 @@
                 )
 
             val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
+            assertThat(clickListener).isNotNull()
 
-            clickListener.onClick(chipView)
+            clickListener!!.onClick(chipView)
             // EndScreenRecordingDialogDelegate will test that the dialog has the right message
             verify(kosmos.mockDialogTransitionAnimator)
                 .showFromView(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegateTest.kt
index 4c2546e..bfb57c5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareToAppDialogDelegateTest.kt
@@ -19,8 +19,10 @@
 import android.content.ComponentName
 import android.content.DialogInterface
 import android.content.Intent
+import android.content.applicationContext
 import android.content.packageManager
 import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.kosmos.Kosmos
@@ -59,12 +61,14 @@
 
         underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
 
-        verify(sysuiDialog).setIcon(R.drawable.ic_screenshot_share)
+        verify(sysuiDialog).setIcon(R.drawable.ic_present_to_all)
     }
 
     @Test
     fun title() {
         createAndSetDelegate(ENTIRE_SCREEN)
+        whenever(kosmos.packageManager.getApplicationInfo(eq(HOST_PACKAGE), any<Int>()))
+            .thenThrow(PackageManager.NameNotFoundException())
 
         underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
 
@@ -72,16 +76,60 @@
     }
 
     @Test
-    fun message_entireScreen() {
+    fun message_entireScreen_unknownHostPackage() {
         createAndSetDelegate(ENTIRE_SCREEN)
+        whenever(kosmos.packageManager.getApplicationInfo(eq(HOST_PACKAGE), any<Int>()))
+            .thenThrow(PackageManager.NameNotFoundException())
 
         underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
 
-        verify(sysuiDialog).setMessage(context.getString(R.string.share_to_app_stop_dialog_message))
+        verify(sysuiDialog)
+            .setMessage(context.getString(R.string.share_to_app_stop_dialog_message_entire_screen))
     }
 
     @Test
-    fun message_singleTask() {
+    fun message_entireScreen_hasHostPackage() {
+        createAndSetDelegate(ENTIRE_SCREEN)
+        val hostAppInfo = mock<ApplicationInfo>()
+        whenever(hostAppInfo.loadLabel(kosmos.packageManager)).thenReturn("Host Package")
+        whenever(kosmos.packageManager.getApplicationInfo(eq(HOST_PACKAGE), any<Int>()))
+            .thenReturn(hostAppInfo)
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(sysuiDialog)
+            .setMessage(
+                context.getString(
+                    R.string.share_to_app_stop_dialog_message_entire_screen_with_host_app,
+                    "Host Package",
+                )
+            )
+    }
+
+    @Test
+    fun message_singleTask_unknownAppName() {
+        val baseIntent =
+            Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
+        whenever(kosmos.packageManager.getApplicationInfo(eq("fake.task.package"), any<Int>()))
+            .thenThrow(PackageManager.NameNotFoundException())
+
+        createAndSetDelegate(
+            MediaProjectionState.Projecting.SingleTask(
+                HOST_PACKAGE,
+                createTask(taskId = 1, baseIntent = baseIntent)
+            )
+        )
+
+        underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
+
+        verify(sysuiDialog)
+            .setMessage(
+                context.getString(R.string.share_to_app_stop_dialog_message_single_app_generic)
+            )
+    }
+
+    @Test
+    fun message_singleTask_hasAppName() {
         val baseIntent =
             Intent().apply { this.component = ComponentName("fake.task.package", "cls") }
         val appInfo = mock<ApplicationInfo>()
@@ -98,11 +146,13 @@
 
         underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
 
-        // It'd be nice to use R.string.share_to_app_stop_dialog_message_specific_app directly, but
-        // it includes the <b> tags which aren't in the returned string.
-        val result = argumentCaptor<CharSequence>()
-        verify(sysuiDialog).setMessage(result.capture())
-        assertThat(result.firstValue.toString()).isEqualTo("You will stop sharing Fake Package")
+        verify(sysuiDialog)
+            .setMessage(
+                context.getString(
+                    R.string.share_to_app_stop_dialog_message_single_app_specific,
+                    "Fake Package",
+                )
+            )
     }
 
     @Test
@@ -118,6 +168,8 @@
     fun positiveButton() =
         kosmos.testScope.runTest {
             createAndSetDelegate(ENTIRE_SCREEN)
+            whenever(kosmos.packageManager.getApplicationInfo(eq(HOST_PACKAGE), any<Int>()))
+                .thenThrow(PackageManager.NameNotFoundException())
 
             underTest.beforeCreate(sysuiDialog, /* savedInstanceState= */ null)
 
@@ -143,8 +195,13 @@
         underTest =
             EndShareToAppDialogDelegate(
                 kosmos.endMediaProjectionDialogHelper,
+                kosmos.applicationContext,
                 stopAction = kosmos.mediaProjectionChipInteractor::stopProjecting,
-                ProjectionChipModel.Projecting(ProjectionChipModel.Type.SHARE_TO_APP, state),
+                ProjectionChipModel.Projecting(
+                    ProjectionChipModel.Type.SHARE_TO_APP,
+                    state,
+                    deviceName = null,
+                ),
             )
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
index 9aef526..3028d00 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelTest.kt
@@ -33,6 +33,7 @@
 import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.NORMAL_PACKAGE
 import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.setUpPackageManagerForMediaProjection
 import com.android.systemui.statusbar.chips.sharetoapp.ui.view.EndShareToAppDialogDelegate
+import com.android.systemui.statusbar.chips.ui.model.ColorsModel
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
 import com.android.systemui.statusbar.chips.ui.view.ChipBackgroundContainer
 import com.android.systemui.statusbar.phone.SystemUIDialog
@@ -115,7 +116,7 @@
         }
 
     @Test
-    fun chip_singleTaskState_normalPackage_isShown() =
+    fun chip_singleTaskState_normalPackage_isShownAsTimer() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
 
@@ -125,22 +126,35 @@
                     createTask(taskId = 1),
                 )
 
-            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
             val icon = (latest as OngoingActivityChipModel.Shown).icon
-            assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_screenshot_share)
+            assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_present_to_all)
+            assertThat(icon.contentDescription).isNotNull()
         }
 
     @Test
-    fun chip_entireScreenState_normalPackage_isShown() =
+    fun chip_entireScreenState_normalPackage_isShownAsTimer() =
         testScope.runTest {
             val latest by collectLastValue(underTest.chip)
 
             mediaProjectionRepo.mediaProjectionState.value =
                 MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
 
-            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown.Timer::class.java)
             val icon = (latest as OngoingActivityChipModel.Shown).icon
-            assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_screenshot_share)
+            assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_present_to_all)
+            assertThat(icon.contentDescription).isNotNull()
+        }
+
+    @Test
+    fun chip_colorsAreRed() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.chip)
+
+            mediaProjectionRepo.mediaProjectionState.value =
+                MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
+
+            assertThat((latest as OngoingActivityChipModel.Shown).colors).isEqualTo(ColorsModel.Red)
         }
 
     @Test
@@ -153,7 +167,7 @@
                 MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
 
             assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
-            assertThat((latest as OngoingActivityChipModel.Shown).startTimeMs).isEqualTo(1234)
+            assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs).isEqualTo(1234)
 
             mediaProjectionRepo.mediaProjectionState.value = MediaProjectionState.NotProjecting
             assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java)
@@ -166,7 +180,7 @@
                 )
 
             assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
-            assertThat((latest as OngoingActivityChipModel.Shown).startTimeMs).isEqualTo(5678)
+            assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs).isEqualTo(5678)
         }
 
     @Test
@@ -177,8 +191,9 @@
                 MediaProjectionState.Projecting.EntireScreen(NORMAL_PACKAGE)
 
             val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
+            assertThat(clickListener).isNotNull()
 
-            clickListener.onClick(chipView)
+            clickListener!!.onClick(chipView)
             verify(kosmos.mockDialogTransitionAnimator)
                 .showFromView(
                     eq(mockShareDialog),
@@ -199,8 +214,9 @@
                 )
 
             val clickListener = ((latest as OngoingActivityChipModel.Shown).onClickListener)
+            assertThat(clickListener).isNotNull()
 
-            clickListener.onClick(chipView)
+            clickListener!!.onClick(chipView)
             verify(kosmos.mockDialogTransitionAnimator)
                 .showFromView(
                     eq(mockShareDialog),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/view/ChipBackgroundContainerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/view/ChipBackgroundContainerTest.kt
index 7d2b463..5fbdfbf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/view/ChipBackgroundContainerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/view/ChipBackgroundContainerTest.kt
@@ -16,10 +16,10 @@
 
 package com.android.systemui.statusbar.chips.ui.view
 
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.LayoutInflater
 import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.res.R
@@ -29,7 +29,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
 class ChipBackgroundContainerTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/view/ChipChronometerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/view/ChipChronometerTest.kt
index b8d4e47..6f771175 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/view/ChipChronometerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/view/ChipChronometerTest.kt
@@ -16,10 +16,10 @@
 
 package com.android.systemui.statusbar.chips.ui.view
 
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.LayoutInflater
 import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.res.R
@@ -36,7 +36,7 @@
 private const val XL_TEXT = "00:0000"
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
 class ChipChronometerTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
index a7b1411f..8bc83cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.chips.ui.viewmodel
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
@@ -34,15 +35,22 @@
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
 import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
+import com.android.systemui.util.time.fakeSystemClock
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class OngoingActivityChipsViewModelTest : SysuiTestCase() {
     private val kosmos = Kosmos().also { it.testCase = this }
     private val testScope = kosmos.testScope
+    private val systemClock = kosmos.fakeSystemClock
 
     private val screenRecordState = kosmos.screenRecordRepository.screenRecordState
     private val mediaProjectionState = kosmos.fakeMediaProjectionRepository.mediaProjectionState
@@ -188,6 +196,39 @@
             assertIsCallChip(latest)
         }
 
+    /** Regression test for b/347726238. */
+    @Test
+    fun chip_timerDoesNotResetAfterSubscribersRestart() =
+        testScope.runTest {
+            var latest: OngoingActivityChipModel? = null
+
+            val job1 = underTest.chip.onEach { latest = it }.launchIn(this)
+
+            // Start a chip with a timer
+            systemClock.setElapsedRealtime(1234)
+            screenRecordState.value = ScreenRecordModel.Recording
+
+            runCurrent()
+
+            assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs).isEqualTo(1234)
+
+            // Stop subscribing to the chip flow
+            job1.cancel()
+
+            // Let time pass
+            systemClock.setElapsedRealtime(5678)
+
+            // WHEN we re-subscribe to the chip flow
+            val job2 = underTest.chip.onEach { latest = it }.launchIn(this)
+
+            runCurrent()
+
+            // THEN the old start time is still used
+            assertThat((latest as OngoingActivityChipModel.Shown.Timer).startTimeMs).isEqualTo(1234)
+
+            job2.cancel()
+        }
+
     companion object {
         fun assertIsScreenRecordChip(latest: OngoingActivityChipModel?) {
             assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
@@ -198,7 +239,7 @@
         fun assertIsShareToAppChip(latest: OngoingActivityChipModel?) {
             assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java)
             val icon = (latest as OngoingActivityChipModel.Shown).icon
-            assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_screenshot_share)
+            assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.ic_present_to_all)
         }
 
         fun assertIsCallChip(latest: OngoingActivityChipModel?) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/CommandParserTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/CommandParserTest.kt
index cfbe8e3..673cf59 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/CommandParserTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/CommandParserTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.commandline
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
@@ -24,8 +25,10 @@
 import org.junit.Assert.assertThrows
 import org.junit.Assert.assertTrue
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class CommandParserTest : SysuiTestCase() {
     private val parser = CommandParser()
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ParametersTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ParametersTest.kt
index e391d6b..83811cd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ParametersTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ParametersTest.kt
@@ -1,5 +1,6 @@
 package com.android.systemui.statusbar.commandline
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
@@ -7,8 +8,10 @@
 import org.junit.Assert.assertThrows
 import org.junit.Assert.assertTrue
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class ParametersTest : SysuiTestCase() {
     @Test
     fun singleArgOptional_returnsNullBeforeParse() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ParseableCommandTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ParseableCommandTest.kt
index 86548d0..1a7c8a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ParseableCommandTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ParseableCommandTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.commandline
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
@@ -24,10 +25,12 @@
 import org.junit.Assert.assertTrue
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class ParseableCommandTest : SysuiTestCase() {
     @Mock private lateinit var pw: PrintWriter
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ValueParserTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ValueParserTest.kt
index 759f0bc..8cf7473 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ValueParserTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/ValueParserTest.kt
@@ -1,13 +1,16 @@
 package com.android.systemui.statusbar.commandline
 
 import android.graphics.Rect
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import org.junit.Assert.assertTrue
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class ValueParserTest : SysuiTestCase() {
     @Test
     fun parseString() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProviderTest.kt
index 0fdda62..ca90f74 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/ui/MobileContextProviderTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.connectivity.ui
 
 import android.telephony.SubscriptionInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.demomode.DemoModeController
@@ -28,12 +29,14 @@
 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.verify
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class MobileContextProviderTest : SysuiTestCase() {
     @Mock private lateinit var networkController: NetworkController
     @Mock private lateinit var dumpManager: DumpManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/KeyguardStatusBarRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/KeyguardStatusBarRepositoryImplTest.kt
index b1c994c..7c98037 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/KeyguardStatusBarRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/KeyguardStatusBarRepositoryImplTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.data.repository
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.R
 import com.android.systemui.SysuiTestCase
@@ -29,9 +30,11 @@
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mockito.verify
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class KeyguardStatusBarRepositoryImplTest : SysuiTestCase() {
     private val testScope = TestScope()
     private val configurationController = mock<ConfigurationController>()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt
index 4b250b2..7f981ee 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt
@@ -23,6 +23,7 @@
 import android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS
 import android.view.WindowInsetsController.APPEARANCE_OPAQUE_STATUS_BARS
 import android.view.WindowInsetsController.APPEARANCE_SEMI_TRANSPARENT_STATUS_BARS
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.statusbar.LetterboxDetails
 import com.android.internal.view.AppearanceRegion
@@ -48,9 +49,11 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mockito.verify
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class StatusBarModeRepositoryImplTest : SysuiTestCase() {
     private val testScope = TestScope()
     private val commandQueue = mock<CommandQueue>()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/DisableFlagsLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/DisableFlagsLoggerTest.kt
index f1c7956..fffcbb6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/DisableFlagsLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/DisableFlagsLoggerTest.kt
@@ -16,13 +16,16 @@
 
 package com.android.systemui.statusbar.disableflags
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import org.junit.Assert.assertThrows
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class DisableFlagsLoggerTest : SysuiTestCase() {
     private val disable1Flags = listOf(
             DisableFlagsLogger.DisableFlag(0b100, 'A', 'a'),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/DisableStateTrackerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/DisableStateTrackerTest.kt
index 215afb2..cf78c71 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/DisableStateTrackerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/DisableStateTrackerTest.kt
@@ -24,17 +24,20 @@
 import android.app.StatusBarManager.DISABLE_NAVIGATION
 import android.app.StatusBarManager.DISABLE_NOTIFICATION_ICONS
 import android.app.StatusBarManager.DISABLE_NOTIFICATION_TICKER
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.CommandQueue
 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.verify
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class DisableStateTrackerTest : SysuiTestCase() {
 
     private lateinit var underTest: DisableStateTracker
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt
index 31e1fef..d2dfc92 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/disableflags/data/repository/DisableFlagsRepositoryTest.kt
@@ -21,6 +21,7 @@
 import android.app.StatusBarManager.DISABLE_NONE
 import android.app.StatusBarManager.DISABLE_NOTIFICATION_ALERTS
 import android.content.res.Configuration
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
@@ -42,10 +43,12 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mockito.verify
 
 @SmallTest
 @OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
 class DisableFlagsRepositoryTest : SysuiTestCase() {
 
     private lateinit var underTest: DisableFlagsRepository
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 066ca1c..7a8533e 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
@@ -35,6 +35,7 @@
 import android.testing.TestableLooper.RunWithLooper
 import android.view.View
 import android.widget.FrameLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.SysuiTestCase
@@ -69,6 +70,7 @@
 import com.android.systemui.util.time.FakeSystemClock
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
 import org.mockito.Captor
 import org.mockito.Mock
@@ -86,6 +88,7 @@
 
 @SmallTest
 @RunWithLooper(setAsMainLooper = true)
+@RunWith(AndroidJUnit4::class)
 class LockscreenSmartspaceControllerTest : SysuiTestCase() {
     companion object {
         const val SMARTSPACE_TIME_TOO_EARLY = 1000L
@@ -136,6 +139,9 @@
     private lateinit var handler: Handler
 
     @Mock
+    private lateinit var bgHandler: Handler
+
+    @Mock
     private lateinit var datePlugin: BcSmartspaceDataPlugin
 
     @Mock
@@ -265,6 +271,7 @@
                 executor,
                 bgExecutor,
                 handler,
+                bgHandler,
                 Optional.of(datePlugin),
                 Optional.of(weatherPlugin),
                 Optional.of(plugin),
@@ -762,6 +769,7 @@
         // THEN the existing session is reused and views are registered
         verify(smartspaceManager, never()).createSmartspaceSession(any())
         verify(smartspaceView2).setUiSurface(BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD)
+        verify(smartspaceView2).setBgHandler(bgHandler)
         verify(smartspaceView2).setTimeChangedDelegate(any())
         verify(smartspaceView2).registerDataProvider(plugin)
         verify(smartspaceView2).registerConfigProvider(configPlugin)
@@ -838,6 +846,7 @@
         verify(dateSmartspaceView).setUiSurface(
                 BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD)
         verify(dateSmartspaceView).setTimeChangedDelegate(any())
+        verify(dateSmartspaceView).setBgHandler(bgHandler)
         verify(dateSmartspaceView).registerDataProvider(datePlugin)
 
         verify(dateSmartspaceView).setPrimaryTextColor(anyInt())
@@ -851,6 +860,7 @@
         verify(weatherSmartspaceView).setUiSurface(
                 BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD)
         verify(weatherSmartspaceView).setTimeChangedDelegate(any())
+        verify(weatherSmartspaceView).setBgHandler(bgHandler)
         verify(weatherSmartspaceView).registerDataProvider(weatherPlugin)
 
         verify(weatherSmartspaceView).setPrimaryTextColor(anyInt())
@@ -863,6 +873,7 @@
 
         verify(smartspaceView).setUiSurface(BcSmartspaceDataPlugin.UI_SURFACE_LOCK_SCREEN_AOD)
         verify(smartspaceView).setTimeChangedDelegate(any())
+        verify(smartspaceView).setBgHandler(bgHandler)
         verify(smartspaceView).registerDataProvider(plugin)
         verify(smartspaceView).registerConfigProvider(configPlugin)
         verify(smartspaceSession)
@@ -988,6 +999,9 @@
             override fun setUiSurface(uiSurface: String) {
             }
 
+            override fun setBgHandler(bgHandler: Handler?) {
+            }
+
             override fun setTimeChangedDelegate(
                 delegate: BcSmartspaceDataPlugin.TimeChangedDelegate?
             ) {}
@@ -1020,6 +1034,9 @@
             override fun setUiSurface(uiSurface: String) {
             }
 
+            override fun setBgHandler(bgHandler: Handler?) {
+            }
+
             override fun setTimeChangedDelegate(
                 delegate: BcSmartspaceDataPlugin.TimeChangedDelegate?
             ) {}
@@ -1048,6 +1065,9 @@
             override fun setUiSurface(uiSurface: String) {
             }
 
+            override fun setBgHandler(bgHandler: Handler?) {
+            }
+
             override fun setTimeChangedDelegate(
                 delegate: BcSmartspaceDataPlugin.TimeChangedDelegate?
             ) {}
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 25533d8..d87b3e2 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
@@ -19,16 +19,23 @@
 
 import android.app.Notification
 import android.os.UserHandle
+import android.platform.test.flag.junit.FlagsParameterization
 import android.provider.Settings
-import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
-import com.android.systemui.log.logcatLogBuffer
+import com.android.systemui.flags.andSceneContainer
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.log.logcatLogBuffer
 import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.scene.data.repository.Idle
+import com.android.systemui.scene.data.repository.setTransition
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
@@ -49,6 +56,8 @@
 import com.android.systemui.util.mockito.withArgCaptor
 import com.android.systemui.util.settings.FakeSettings
 import com.google.common.truth.Truth.assertThat
+import java.util.function.Consumer
+import kotlin.time.Duration.Companion.seconds
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestCoroutineScheduler
@@ -62,22 +71,28 @@
 import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
-import java.util.function.Consumer
-import kotlin.time.Duration.Companion.seconds
 import org.mockito.Mockito.`when` as whenever
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
 
 @SmallTest
-@RunWith(AndroidJUnit4::class)
-class KeyguardCoordinatorTest : SysuiTestCase() {
+@RunWith(ParameterizedAndroidJunit4::class)
+class KeyguardCoordinatorTest(flags: FlagsParameterization) : SysuiTestCase() {
+
+    private val kosmos = Kosmos()
 
     private val headsUpManager: HeadsUpManager = mock()
     private val keyguardNotifVisibilityProvider: KeyguardNotificationVisibilityProvider = mock()
     private val keyguardRepository = FakeKeyguardRepository()
-    private val keyguardTransitionRepository = FakeKeyguardTransitionRepository()
+    private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
     private val notifPipeline: NotifPipeline = mock()
     private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider = mock()
     private val statusBarStateController: StatusBarStateController = mock()
 
+    init {
+        mSetFlagsRule.setFlagsParameterization(flags)
+    }
+
     @Test
     fun testSetSectionHeadersVisibleInShade() = runKeyguardCoordinatorTest {
         clearInvocations(sectionHeaderVisibilityProvider)
@@ -147,10 +162,9 @@
         keyguardRepository.setKeyguardShowing(false)
         whenever(statusBarStateController.isExpanded).thenReturn(false)
         runKeyguardCoordinatorTest {
-            keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.LOCKSCREEN,
-                    to = KeyguardState.GONE,
-                    this.testScheduler,
+            kosmos.setTransition(
+                sceneTransition = Idle(Scenes.Gone),
+                stateTransition = TransitionStep(KeyguardState.LOCKSCREEN, KeyguardState.GONE)
             )
 
             // WHEN: A notification is posted
@@ -163,24 +177,20 @@
 
             // WHEN: The keyguard is now showing
             keyguardRepository.setKeyguardShowing(true)
-            keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.GONE,
-                    to = KeyguardState.AOD,
-                    this.testScheduler,
+            kosmos.setTransition(
+                sceneTransition = Idle(Scenes.Lockscreen),
+                stateTransition = TransitionStep(KeyguardState.GONE, KeyguardState.AOD)
             )
-            testScheduler.runCurrent()
 
             // THEN: The notification is recognized as "seen" and is filtered out.
             assertThat(unseenFilter.shouldFilterOut(fakeEntry, 0L)).isTrue()
 
             // WHEN: The keyguard goes away
             keyguardRepository.setKeyguardShowing(false)
-            keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.AOD,
-                    to = KeyguardState.GONE,
-                    this.testScheduler,
+            kosmos.setTransition(
+                sceneTransition = Idle(Scenes.Gone),
+                stateTransition = TransitionStep(KeyguardState.AOD, KeyguardState.GONE)
             )
-            testScheduler.runCurrent()
 
             // THEN: The notification is shown regardless
             assertThat(unseenFilter.shouldFilterOut(fakeEntry, 0L)).isFalse()
@@ -344,9 +354,9 @@
             val fakeEntry = NotificationEntryBuilder().build()
             collectionListener.onEntryAdded(fakeEntry)
             keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.AOD,
-                    to = KeyguardState.LOCKSCREEN,
-                    this.testScheduler,
+                from = KeyguardState.AOD,
+                to = KeyguardState.LOCKSCREEN,
+                this.testScheduler,
             )
             testScheduler.runCurrent()
 
@@ -356,21 +366,17 @@
 
             // WHEN: Keyguard is no longer showing
             keyguardRepository.setKeyguardShowing(false)
-            keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.LOCKSCREEN,
-                    to = KeyguardState.GONE,
-                    this.testScheduler,
+            kosmos.setTransition(
+                sceneTransition = Idle(Scenes.Gone),
+                stateTransition = TransitionStep(KeyguardState.LOCKSCREEN, KeyguardState.GONE)
             )
-            testScheduler.runCurrent()
 
             // WHEN: Keyguard is shown again
             keyguardRepository.setKeyguardShowing(true)
-            keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.GONE,
-                    to = KeyguardState.AOD,
-                    this.testScheduler,
+            kosmos.setTransition(
+                sceneTransition = Idle(Scenes.Lockscreen),
+                stateTransition = TransitionStep(KeyguardState.GONE, KeyguardState.AOD)
             )
-            testScheduler.runCurrent()
 
             // THEN: The notification is now recognized as "seen" and is filtered out.
             assertThat(unseenFilter.shouldFilterOut(fakeEntry, 0L)).isTrue()
@@ -383,9 +389,9 @@
         keyguardRepository.setKeyguardShowing(true)
         runKeyguardCoordinatorTest {
             keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.GONE,
-                    to = KeyguardState.LOCKSCREEN,
-                    this.testScheduler,
+                from = KeyguardState.GONE,
+                to = KeyguardState.LOCKSCREEN,
+                this.testScheduler,
             )
             val fakeEntry = NotificationEntryBuilder().build()
             collectionListener.onEntryAdded(fakeEntry)
@@ -393,9 +399,9 @@
             // WHEN: Keyguard is no longer showing
             keyguardRepository.setKeyguardShowing(false)
             keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.LOCKSCREEN,
-                    to = KeyguardState.GONE,
-                    this.testScheduler,
+                from = KeyguardState.LOCKSCREEN,
+                to = KeyguardState.GONE,
+                this.testScheduler,
             )
 
             // WHEN: Keyguard is shown again
@@ -413,10 +419,9 @@
         keyguardRepository.setKeyguardShowing(true)
         keyguardRepository.setIsDozing(false)
         runKeyguardCoordinatorTest {
-            keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.GONE,
-                    to = KeyguardState.LOCKSCREEN,
-                    this.testScheduler,
+            kosmos.setTransition(
+                sceneTransition = Idle(Scenes.Lockscreen),
+                stateTransition = TransitionStep(KeyguardState.GONE, KeyguardState.LOCKSCREEN)
             )
             val firstEntry = NotificationEntryBuilder().setId(1).build()
             collectionListener.onEntryAdded(firstEntry)
@@ -437,21 +442,17 @@
 
             // WHEN: the keyguard is no longer showing
             keyguardRepository.setKeyguardShowing(false)
-            keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.LOCKSCREEN,
-                    to = KeyguardState.GONE,
-                    this.testScheduler,
+            kosmos.setTransition(
+                sceneTransition = Idle(Scenes.Gone),
+                stateTransition = TransitionStep(KeyguardState.LOCKSCREEN, KeyguardState.GONE)
             )
-            testScheduler.runCurrent()
 
             // WHEN: Keyguard is shown again
             keyguardRepository.setKeyguardShowing(true)
-            keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.GONE,
-                    to = KeyguardState.LOCKSCREEN,
-                    this.testScheduler,
+            kosmos.setTransition(
+                sceneTransition = Idle(Scenes.Lockscreen),
+                stateTransition = TransitionStep(KeyguardState.GONE, KeyguardState.LOCKSCREEN)
             )
-            testScheduler.runCurrent()
 
             // THEN: The first notification is considered seen and is filtered out.
             assertThat(unseenFilter.shouldFilterOut(firstEntry, 0L)).isTrue()
@@ -468,9 +469,9 @@
         keyguardRepository.setIsDozing(false)
         runKeyguardCoordinatorTest {
             keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.GONE,
-                    to = KeyguardState.LOCKSCREEN,
-                    this.testScheduler,
+                from = KeyguardState.GONE,
+                to = KeyguardState.LOCKSCREEN,
+                this.testScheduler,
             )
             testScheduler.runCurrent()
 
@@ -498,18 +499,18 @@
             // WHEN: the keyguard is no longer showing
             keyguardRepository.setKeyguardShowing(false)
             keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.LOCKSCREEN,
-                    to = KeyguardState.GONE,
-                    this.testScheduler,
+                from = KeyguardState.LOCKSCREEN,
+                to = KeyguardState.GONE,
+                this.testScheduler,
             )
             testScheduler.runCurrent()
 
             // WHEN: Keyguard is shown again
             keyguardRepository.setKeyguardShowing(true)
             keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.GONE,
-                    to = KeyguardState.LOCKSCREEN,
-                    this.testScheduler,
+                from = KeyguardState.GONE,
+                to = KeyguardState.LOCKSCREEN,
+                this.testScheduler,
             )
             testScheduler.runCurrent()
 
@@ -525,9 +526,9 @@
         keyguardRepository.setIsDozing(false)
         runKeyguardCoordinatorTest {
             keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.GONE,
-                    to = KeyguardState.LOCKSCREEN,
-                    this.testScheduler,
+                from = KeyguardState.GONE,
+                to = KeyguardState.LOCKSCREEN,
+                this.testScheduler,
             )
             testScheduler.runCurrent()
 
@@ -555,18 +556,18 @@
             // WHEN: the keyguard is no longer showing
             keyguardRepository.setKeyguardShowing(false)
             keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.LOCKSCREEN,
-                    to = KeyguardState.GONE,
-                    this.testScheduler,
+                from = KeyguardState.LOCKSCREEN,
+                to = KeyguardState.GONE,
+                this.testScheduler,
             )
             testScheduler.runCurrent()
 
             // WHEN: Keyguard is shown again
             keyguardRepository.setKeyguardShowing(true)
             keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.GONE,
-                    to = KeyguardState.LOCKSCREEN,
-                    this.testScheduler,
+                from = KeyguardState.GONE,
+                to = KeyguardState.LOCKSCREEN,
+                this.testScheduler,
             )
             testScheduler.runCurrent()
 
@@ -582,9 +583,9 @@
         keyguardRepository.setIsDozing(false)
         runKeyguardCoordinatorTest {
             keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.GONE,
-                    to = KeyguardState.LOCKSCREEN,
-                    this.testScheduler,
+                from = KeyguardState.GONE,
+                to = KeyguardState.LOCKSCREEN,
+                this.testScheduler,
             )
             testScheduler.runCurrent()
 
@@ -608,18 +609,18 @@
             // WHEN: the keyguard is no longer showing
             keyguardRepository.setKeyguardShowing(false)
             keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.LOCKSCREEN,
-                    to = KeyguardState.GONE,
-                    this.testScheduler,
+                from = KeyguardState.LOCKSCREEN,
+                to = KeyguardState.GONE,
+                this.testScheduler,
             )
             testScheduler.runCurrent()
 
             // WHEN: Keyguard is shown again
             keyguardRepository.setKeyguardShowing(true)
             keyguardTransitionRepository.sendTransitionSteps(
-                    from = KeyguardState.GONE,
-                    to = KeyguardState.LOCKSCREEN,
-                    this.testScheduler,
+                from = KeyguardState.GONE,
+                to = KeyguardState.LOCKSCREEN,
+                this.testScheduler,
             )
             testScheduler.runCurrent()
 
@@ -646,7 +647,7 @@
                 headsUpManager,
                 keyguardNotifVisibilityProvider,
                 keyguardRepository,
-                keyguardTransitionRepository,
+                kosmos.keyguardTransitionInteractor,
                 KeyguardCoordinatorLogger(logcatLogBuffer()),
                 testScope.backgroundScope,
                 sectionHeaderVisibilityProvider,
@@ -706,4 +707,12 @@
                 )
             }
     }
+
+    companion object {
+        @JvmStatic
+        @Parameters(name = "{0}")
+        fun getParams(): List<FlagsParameterization> {
+            return FlagsParameterization.allCombinationsOf().andSceneContainer()
+        }
+    }
 }
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 b161f84..0505727 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
@@ -23,6 +23,7 @@
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
 import android.service.notification.StatusBarNotification
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.server.notification.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING
@@ -54,11 +55,13 @@
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when` as whenever
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class SensitiveContentCoordinatorTest : SysuiTestCase() {
 
     val dynamicPrivacyController: DynamicPrivacyController = mock()
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 8272f5a..ef2a2aa 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
@@ -19,6 +19,7 @@
 import android.app.smartspace.SmartspaceTarget
 import android.content.ComponentName
 import android.os.UserHandle
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener
@@ -43,6 +44,7 @@
 import org.junit.Assert.assertTrue
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.never
@@ -51,6 +53,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class SmartspaceDedupingCoordinatorTest : SysuiTestCase() {
 
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
index 11996fe..99bd4fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.notification.collection.render
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.logcatLogBuffer
@@ -37,10 +38,12 @@
 import com.android.systemui.util.mockito.mock
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mockito
 import org.mockito.Mockito.`when` as whenever
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class NodeSpecBuilderTest : SysuiTestCase() {
 
     private val mediaContainerController: MediaContainerController = mock()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt
index 70d309b..ca75ca6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.notification.collection.render
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.notification.collection.GroupEntry
@@ -32,6 +33,7 @@
 import com.android.systemui.util.mockito.withArgCaptor
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.inOrder
 import org.mockito.Mockito.never
@@ -42,6 +44,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class RenderStageManagerTest : SysuiTestCase() {
 
     @Mock private lateinit var shadeListBuilder: ShadeListBuilder
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorTest.kt
index b775079..79ff4be 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationAlertsInteractorTest.kt
@@ -15,6 +15,7 @@
 package com.android.systemui.statusbar.notification.domain.interactor
 
 import android.app.StatusBarManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysUITestComponent
 import com.android.systemui.SysUITestModule
@@ -26,8 +27,10 @@
 import dagger.BindsInstance
 import dagger.Component
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class NotificationAlertsInteractorTest : SysuiTestCase() {
 
     @Component(modules = [SysUITestModule::class])
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractorTest.kt
index a0faab5..982b7b1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationLaunchAnimationInteractorTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.notification.domain.interactor
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
@@ -23,8 +24,10 @@
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class NotificationLaunchAnimationInteractorTest : SysuiTestCase() {
     private val repository = NotificationLaunchAnimationRepository()
     private val underTest = NotificationLaunchAnimationInteractor(repository)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractorTest.kt
index 3593f5b..133a114 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsKeyguardInteractorTest.kt
@@ -13,6 +13,7 @@
  */
 package com.android.systemui.statusbar.notification.domain.interactor
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysUITestComponent
 import com.android.systemui.SysUITestModule
@@ -25,8 +26,10 @@
 import dagger.BindsInstance
 import dagger.Component
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class NotificationsKeyguardInteractorTest : SysuiTestCase() {
 
     @SysUISingleton
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt
index 334776c..277b887 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/domain/interactor/RenderNotificationsListInteractorTest.kt
@@ -16,6 +16,7 @@
 package com.android.systemui.statusbar.notification.domain.interactor
 
 import android.service.notification.StatusBarNotification
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
@@ -31,8 +32,10 @@
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class RenderNotificationsListInteractorTest : SysuiTestCase() {
     private val backgroundDispatcher = StandardTestDispatcher()
     private val testScope = TestScope(backgroundDispatcher)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt
index 26f5370..f07303e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/domain/interactor/NotificationIconsInteractorTest.kt
@@ -17,21 +17,19 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.SysUITestComponent
-import com.android.systemui.SysUITestModule
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.TestMocksModule
-import com.android.systemui.biometrics.domain.BiometricsDomainLayerModule
-import com.android.systemui.collectLastValue
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.deviceentry.data.repository.FakeDeviceEntryRepository
-import com.android.systemui.runTest
-import com.android.systemui.statusbar.data.repository.NotificationListenerSettingsRepository
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.statusbar.data.repository.notificationListenerSettingsRepository
 import com.android.systemui.statusbar.notification.data.model.activeNotificationModel
-import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository
 import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationsStore
-import com.android.systemui.statusbar.notification.domain.interactor.HeadsUpNotificationIconInteractor
-import com.android.systemui.statusbar.notification.domain.interactor.NotificationsKeyguardInteractor
+import com.android.systemui.statusbar.notification.data.repository.activeNotificationListRepository
+import com.android.systemui.statusbar.notification.data.repository.notificationsKeyguardViewStateRepository
+import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
+import com.android.systemui.statusbar.notification.domain.interactor.headsUpNotificationIconInteractor
 import com.android.systemui.statusbar.notification.shared.byIsAmbient
 import com.android.systemui.statusbar.notification.shared.byIsLastMessageFromReply
 import com.android.systemui.statusbar.notification.shared.byIsPulsing
@@ -39,15 +37,15 @@
 import com.android.systemui.statusbar.notification.shared.byIsSilent
 import com.android.systemui.statusbar.notification.shared.byIsSuppressedFromStatusBar
 import com.android.systemui.statusbar.notification.shared.byKey
-import com.android.systemui.user.domain.UserDomainLayerModule
+import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationsKeyguardInteractor
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.eq
-import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
-import com.android.wm.shell.bubbles.Bubbles
+import com.android.wm.shell.bubbles.bubbles
+import com.android.wm.shell.bubbles.bubblesOptional
 import com.google.common.truth.Truth.assertThat
-import dagger.BindsInstance
-import dagger.Component
-import java.util.Optional
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -55,29 +53,22 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class NotificationIconsInteractorTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val activeNotificationListRepository = kosmos.activeNotificationListRepository
+    private val notificationsKeyguardInteractor = kosmos.notificationsKeyguardInteractor
 
-    private val bubbles: Bubbles = mock()
-
-    @Component(modules = [SysUITestModule::class])
-    @SysUISingleton
-    interface TestComponent : SysUITestComponent<NotificationIconsInteractor> {
-
-        val activeNotificationListRepository: ActiveNotificationListRepository
-        val notificationsKeyguardInteractor: NotificationsKeyguardInteractor
-
-        @Component.Factory
-        interface Factory {
-            fun create(@BindsInstance test: SysuiTestCase, mocks: TestMocksModule): TestComponent
-        }
-    }
-
-    val testComponent: TestComponent =
-        DaggerNotificationIconsInteractorTest_TestComponent.factory()
-            .create(test = this, mocks = TestMocksModule(bubbles = Optional.of(bubbles)))
+    private val underTest =
+        NotificationIconsInteractor(
+            kosmos.activeNotificationsInteractor,
+            kosmos.bubblesOptional,
+            kosmos.headsUpNotificationIconInteractor,
+            kosmos.notificationsKeyguardViewStateRepository
+        )
 
     @Before
     fun setup() {
-        testComponent.apply {
+        testScope.apply {
             activeNotificationListRepository.activeNotifications.value =
                 ActiveNotificationsStore.Builder()
                     .apply { testIcons.forEach(::addIndividualNotif) }
@@ -87,22 +78,22 @@
 
     @Test
     fun filteredEntrySet() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by collectLastValue(underTest.filteredNotifSet())
             assertThat(filteredSet).containsExactlyElementsIn(testIcons)
         }
 
     @Test
     fun filteredEntrySet_noExpandedBubbles() =
-        testComponent.runTest {
-            whenever(bubbles.isBubbleExpanded(eq("notif1"))).thenReturn(true)
+        testScope.runTest {
+            whenever(kosmos.bubbles.isBubbleExpanded(eq("notif1"))).thenReturn(true)
             val filteredSet by collectLastValue(underTest.filteredNotifSet())
             assertThat(filteredSet).comparingElementsUsing(byKey).doesNotContain("notif1")
         }
 
     @Test
     fun filteredEntrySet_noAmbient() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by collectLastValue(underTest.filteredNotifSet(showAmbient = false))
             assertThat(filteredSet).comparingElementsUsing(byIsAmbient).doesNotContain(true)
             assertThat(filteredSet)
@@ -112,21 +103,21 @@
 
     @Test
     fun filteredEntrySet_noLowPriority() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by collectLastValue(underTest.filteredNotifSet(showLowPriority = false))
             assertThat(filteredSet).comparingElementsUsing(byIsSilent).doesNotContain(true)
         }
 
     @Test
     fun filteredEntrySet_noDismissed() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by collectLastValue(underTest.filteredNotifSet(showDismissed = false))
             assertThat(filteredSet).comparingElementsUsing(byIsRowDismissed).doesNotContain(true)
         }
 
     @Test
     fun filteredEntrySet_noRepliedMessages() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by
                 collectLastValue(underTest.filteredNotifSet(showRepliedMessages = false))
             assertThat(filteredSet)
@@ -136,7 +127,7 @@
 
     @Test
     fun filteredEntrySet_noPulsing_notifsNotFullyHidden() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by collectLastValue(underTest.filteredNotifSet(showPulsing = false))
             notificationsKeyguardInteractor.setNotificationsFullyHidden(false)
             assertThat(filteredSet).comparingElementsUsing(byIsPulsing).doesNotContain(true)
@@ -144,65 +135,46 @@
 
     @Test
     fun filteredEntrySet_noPulsing_notifsFullyHidden() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by collectLastValue(underTest.filteredNotifSet(showPulsing = false))
             notificationsKeyguardInteractor.setNotificationsFullyHidden(true)
             assertThat(filteredSet).comparingElementsUsing(byIsPulsing).contains(true)
         }
 }
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class AlwaysOnDisplayNotificationIconsInteractorTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
 
-    private val bubbles: Bubbles = mock()
-
-    @Component(
-        modules =
-            [
-                SysUITestModule::class,
-                BiometricsDomainLayerModule::class,
-                UserDomainLayerModule::class,
-            ]
-    )
-    @SysUISingleton
-    interface TestComponent : SysUITestComponent<AlwaysOnDisplayNotificationIconsInteractor> {
-
-        val activeNotificationListRepository: ActiveNotificationListRepository
-        val deviceEntryRepository: FakeDeviceEntryRepository
-        val notificationsKeyguardInteractor: NotificationsKeyguardInteractor
-
-        @Component.Factory
-        interface Factory {
-            fun create(@BindsInstance test: SysuiTestCase, mocks: TestMocksModule): TestComponent
-        }
-    }
-
-    private val testComponent: TestComponent =
-        DaggerAlwaysOnDisplayNotificationIconsInteractorTest_TestComponent.factory()
-            .create(test = this, mocks = TestMocksModule(bubbles = Optional.of(bubbles)))
+    private val underTest =
+        AlwaysOnDisplayNotificationIconsInteractor(
+            kosmos.testDispatcher,
+            kosmos.deviceEntryInteractor,
+            kosmos.notificationIconsInteractor,
+        )
 
     @Before
     fun setup() {
-        testComponent.apply {
-            activeNotificationListRepository.activeNotifications.value =
-                ActiveNotificationsStore.Builder()
-                    .apply { testIcons.forEach(::addIndividualNotif) }
-                    .build()
-        }
+        kosmos.activeNotificationListRepository.activeNotifications.value =
+            ActiveNotificationsStore.Builder()
+                .apply { testIcons.forEach(::addIndividualNotif) }
+                .build()
     }
 
     @Test
     fun filteredEntrySet_noExpandedBubbles() =
-        testComponent.runTest {
-            whenever(bubbles.isBubbleExpanded(eq("notif1"))).thenReturn(true)
+        testScope.runTest {
+            whenever(kosmos.bubbles.isBubbleExpanded(eq("notif1"))).thenReturn(true)
             val filteredSet by collectLastValue(underTest.aodNotifs)
             assertThat(filteredSet).comparingElementsUsing(byKey).doesNotContain("notif1")
         }
 
     @Test
     fun filteredEntrySet_noAmbient() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by collectLastValue(underTest.aodNotifs)
             assertThat(filteredSet).comparingElementsUsing(byIsAmbient).doesNotContain(true)
             assertThat(filteredSet)
@@ -212,14 +184,14 @@
 
     @Test
     fun filteredEntrySet_noDismissed() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by collectLastValue(underTest.aodNotifs)
             assertThat(filteredSet).comparingElementsUsing(byIsRowDismissed).doesNotContain(true)
         }
 
     @Test
     fun filteredEntrySet_noRepliedMessages() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by collectLastValue(underTest.aodNotifs)
             assertThat(filteredSet)
                 .comparingElementsUsing(byIsLastMessageFromReply)
@@ -228,37 +200,37 @@
 
     @Test
     fun filteredEntrySet_showPulsing_notifsNotFullyHidden_bypassDisabled() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by collectLastValue(underTest.aodNotifs)
-            deviceEntryRepository.setBypassEnabled(false)
-            notificationsKeyguardInteractor.setNotificationsFullyHidden(false)
+            kosmos.fakeDeviceEntryRepository.setBypassEnabled(false)
+            kosmos.notificationsKeyguardInteractor.setNotificationsFullyHidden(false)
             assertThat(filteredSet).comparingElementsUsing(byIsPulsing).contains(true)
         }
 
     @Test
     fun filteredEntrySet_showPulsing_notifsFullyHidden_bypassDisabled() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by collectLastValue(underTest.aodNotifs)
-            deviceEntryRepository.setBypassEnabled(false)
-            notificationsKeyguardInteractor.setNotificationsFullyHidden(true)
+            kosmos.fakeDeviceEntryRepository.setBypassEnabled(false)
+            kosmos.notificationsKeyguardInteractor.setNotificationsFullyHidden(true)
             assertThat(filteredSet).comparingElementsUsing(byIsPulsing).contains(true)
         }
 
     @Test
     fun filteredEntrySet_noPulsing_notifsNotFullyHidden_bypassEnabled() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by collectLastValue(underTest.aodNotifs)
-            deviceEntryRepository.setBypassEnabled(true)
-            notificationsKeyguardInteractor.setNotificationsFullyHidden(false)
+            kosmos.fakeDeviceEntryRepository.setBypassEnabled(true)
+            kosmos.notificationsKeyguardInteractor.setNotificationsFullyHidden(false)
             assertThat(filteredSet).comparingElementsUsing(byIsPulsing).doesNotContain(true)
         }
 
     @Test
     fun filteredEntrySet_showPulsing_notifsFullyHidden_bypassEnabled() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by collectLastValue(underTest.aodNotifs)
-            deviceEntryRepository.setBypassEnabled(true)
-            notificationsKeyguardInteractor.setNotificationsFullyHidden(true)
+            kosmos.fakeDeviceEntryRepository.setBypassEnabled(true)
+            kosmos.notificationsKeyguardInteractor.setNotificationsFullyHidden(true)
             assertThat(filteredSet).comparingElementsUsing(byIsPulsing).contains(true)
         }
 }
@@ -266,32 +238,19 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class StatusBarNotificationIconsInteractorTest : SysuiTestCase() {
-
-    private val bubbles: Bubbles = mock()
-
-    @Component(modules = [SysUITestModule::class])
-    @SysUISingleton
-    interface TestComponent : SysUITestComponent<StatusBarNotificationIconsInteractor> {
-
-        val activeNotificationListRepository: ActiveNotificationListRepository
-        val headsUpIconsInteractor: HeadsUpNotificationIconInteractor
-        val notificationsKeyguardInteractor: NotificationsKeyguardInteractor
-        val notificationListenerSettingsRepository: NotificationListenerSettingsRepository
-
-        @Component.Factory
-        interface Factory {
-            fun create(@BindsInstance test: SysuiTestCase, mocks: TestMocksModule): TestComponent
-        }
-    }
-
-    val testComponent: TestComponent =
-        DaggerStatusBarNotificationIconsInteractorTest_TestComponent.factory()
-            .create(test = this, mocks = TestMocksModule(bubbles = Optional.of(bubbles)))
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val underTest =
+        StatusBarNotificationIconsInteractor(
+            kosmos.testDispatcher,
+            kosmos.notificationIconsInteractor,
+            kosmos.notificationListenerSettingsRepository,
+        )
 
     @Before
     fun setup() {
-        testComponent.apply {
-            activeNotificationListRepository.activeNotifications.value =
+        testScope.apply {
+            kosmos.activeNotificationListRepository.activeNotifications.value =
                 ActiveNotificationsStore.Builder()
                     .apply { testIcons.forEach(::addIndividualNotif) }
                     .build()
@@ -300,15 +259,15 @@
 
     @Test
     fun filteredEntrySet_noExpandedBubbles() =
-        testComponent.runTest {
-            whenever(bubbles.isBubbleExpanded(eq("notif1"))).thenReturn(true)
+        testScope.runTest {
+            whenever(kosmos.bubbles.isBubbleExpanded(eq("notif1"))).thenReturn(true)
             val filteredSet by collectLastValue(underTest.statusBarNotifs)
             assertThat(filteredSet).comparingElementsUsing(byKey).doesNotContain("notif1")
         }
 
     @Test
     fun filteredEntrySet_noAmbient() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by collectLastValue(underTest.statusBarNotifs)
             assertThat(filteredSet).comparingElementsUsing(byIsAmbient).doesNotContain(true)
             assertThat(filteredSet)
@@ -318,30 +277,30 @@
 
     @Test
     fun filteredEntrySet_noLowPriority_whenDontShowSilentIcons() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by collectLastValue(underTest.statusBarNotifs)
-            notificationListenerSettingsRepository.showSilentStatusIcons.value = false
+            kosmos.notificationListenerSettingsRepository.showSilentStatusIcons.value = false
             assertThat(filteredSet).comparingElementsUsing(byIsSilent).doesNotContain(true)
         }
 
     @Test
     fun filteredEntrySet_showLowPriority_whenShowSilentIcons() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by collectLastValue(underTest.statusBarNotifs)
-            notificationListenerSettingsRepository.showSilentStatusIcons.value = true
+            kosmos.notificationListenerSettingsRepository.showSilentStatusIcons.value = true
             assertThat(filteredSet).comparingElementsUsing(byIsSilent).contains(true)
         }
 
     @Test
     fun filteredEntrySet_noDismissed() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by collectLastValue(underTest.statusBarNotifs)
             assertThat(filteredSet).comparingElementsUsing(byIsRowDismissed).doesNotContain(true)
         }
 
     @Test
     fun filteredEntrySet_noRepliedMessages() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by collectLastValue(underTest.statusBarNotifs)
             assertThat(filteredSet)
                 .comparingElementsUsing(byIsLastMessageFromReply)
@@ -350,9 +309,9 @@
 
     @Test
     fun filteredEntrySet_includesIsolatedIcon() =
-        testComponent.runTest {
+        testScope.runTest {
             val filteredSet by collectLastValue(underTest.statusBarNotifs)
-            headsUpIconsInteractor.setIsolatedIconNotificationKey("notif5")
+            kosmos.headsUpNotificationIconInteractor.setIsolatedIconNotificationKey("notif5")
             assertThat(filteredSet).comparingElementsUsing(byKey).contains("notif5")
         }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
index 894e02e..1f4e80e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/ui/viewmodel/NotificationIconContainerAlwaysOnDisplayViewModelTest.kt
@@ -16,111 +16,81 @@
 
 package com.android.systemui.statusbar.notification.icon.ui.viewmodel
 
+import android.content.res.mainResources
 import android.platform.test.annotations.DisableFlags
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR
 import com.android.systemui.Flags.FLAG_NEW_AOD_TRANSITION
-import com.android.systemui.SysUITestComponent
-import com.android.systemui.SysUITestModule
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.TestMocksModule
-import com.android.systemui.biometrics.domain.BiometricsDomainLayerModule
-import com.android.systemui.collectLastValue
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.flags.FakeFeatureFlagsClassicModule
+import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.flags.Flags
-import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
-import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.flags.fakeFeatureFlagsClassic
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.DozeStateModel
 import com.android.systemui.keyguard.shared.model.DozeTransitionModel
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
-import com.android.systemui.power.data.repository.FakePowerRepository
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.power.data.repository.fakePowerRepository
 import com.android.systemui.power.shared.model.WakeSleepReason
 import com.android.systemui.power.shared.model.WakefulnessState
-import com.android.systemui.runCurrent
-import com.android.systemui.runTest
-import com.android.systemui.statusbar.phone.DozeParameters
-import com.android.systemui.statusbar.phone.ScreenOffAnimationController
-import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepository
-import com.android.systemui.user.domain.UserDomainLayerModule
-import com.android.systemui.util.mockito.mock
+import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.statusbar.notification.icon.domain.interactor.alwaysOnDisplayNotificationIconsInteractor
+import com.android.systemui.statusbar.phone.dozeParameters
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
-import dagger.BindsInstance
-import dagger.Component
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class NotificationIconContainerAlwaysOnDisplayViewModelTest : SysuiTestCase() {
-
-    @SysUISingleton
-    @Component(
-        modules =
-            [
-                SysUITestModule::class,
-                BiometricsDomainLayerModule::class,
-                UserDomainLayerModule::class,
-            ]
-    )
-    interface TestComponent :
-        SysUITestComponent<NotificationIconContainerAlwaysOnDisplayViewModel> {
-
-        val deviceProvisioningRepository: FakeDeviceProvisioningRepository
-        val keyguardRepository: FakeKeyguardRepository
-        val keyguardTransitionRepository: FakeKeyguardTransitionRepository
-        val powerRepository: FakePowerRepository
-
-        @Component.Factory
-        interface Factory {
-            fun create(
-                @BindsInstance test: SysuiTestCase,
-                mocks: TestMocksModule,
-                featureFlags: FakeFeatureFlagsClassicModule,
-            ): TestComponent
+    private val kosmos =
+        testKosmos().apply {
+            fakeFeatureFlagsClassic.apply { set(Flags.FULL_SCREEN_USER_SWITCHER, value = false) }
         }
-    }
 
-    private val dozeParams: DozeParameters = mock()
-    private val screenOffAnimController: ScreenOffAnimationController = mock()
-
-    private val testComponent: TestComponent =
-        DaggerNotificationIconContainerAlwaysOnDisplayViewModelTest_TestComponent.factory()
-            .create(
-                test = this,
-                featureFlags =
-                    FakeFeatureFlagsClassicModule {
-                        set(Flags.FULL_SCREEN_USER_SWITCHER, value = false)
-                    },
-                mocks =
-                    TestMocksModule(
-                        dozeParameters = dozeParams,
-                        screenOffAnimationController = screenOffAnimController,
-                    ),
-            )
+    val underTest =
+        NotificationIconContainerAlwaysOnDisplayViewModel(
+            kosmos.testDispatcher,
+            kosmos.alwaysOnDisplayNotificationIconsInteractor,
+            kosmos.keyguardInteractor,
+            kosmos.keyguardTransitionInteractor,
+            kosmos.mainResources,
+            kosmos.shadeInteractor,
+        )
+    val testScope = kosmos.testScope
+    val keyguardRepository = kosmos.fakeKeyguardRepository
+    val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
+    val powerRepository = kosmos.fakePowerRepository
 
     @Before
     fun setup() {
-        testComponent.apply {
-            keyguardRepository.setKeyguardShowing(true)
-            keyguardRepository.setKeyguardOccluded(false)
-            powerRepository.updateWakefulness(
-                rawState = WakefulnessState.AWAKE,
-                lastWakeReason = WakeSleepReason.OTHER,
-                lastSleepReason = WakeSleepReason.OTHER,
-            )
-        }
+        keyguardRepository.setKeyguardShowing(true)
+        keyguardRepository.setKeyguardOccluded(false)
+        kosmos.fakePowerRepository.updateWakefulness(
+            rawState = WakefulnessState.AWAKE,
+            lastWakeReason = WakeSleepReason.OTHER,
+            lastSleepReason = WakeSleepReason.OTHER,
+        )
         mSetFlagsRule.enableFlags(FLAG_NEW_AOD_TRANSITION)
     }
 
     @Test
     fun animationsEnabled_isFalse_whenDeviceAsleepAndNotPulsing() =
-        testComponent.runTest {
+        testScope.runTest {
             powerRepository.updateWakefulness(
                 rawState = WakefulnessState.ASLEEP,
                 lastWakeReason = WakeSleepReason.POWER_BUTTON,
@@ -143,7 +113,7 @@
 
     @Test
     fun animationsEnabled_isTrue_whenDeviceAsleepAndPulsing() =
-        testComponent.runTest {
+        testScope.runTest {
             powerRepository.updateWakefulness(
                 rawState = WakefulnessState.ASLEEP,
                 lastWakeReason = WakeSleepReason.POWER_BUTTON,
@@ -166,7 +136,7 @@
 
     @Test
     fun animationsEnabled_isFalse_whenStartingToSleepAndNotControlScreenOff() =
-        testComponent.runTest {
+        testScope.runTest {
             powerRepository.updateWakefulness(
                 rawState = WakefulnessState.STARTING_TO_SLEEP,
                 lastWakeReason = WakeSleepReason.POWER_BUTTON,
@@ -179,7 +149,7 @@
                     transitionState = TransitionState.STARTED,
                 )
             )
-            whenever(dozeParams.shouldControlScreenOff()).thenReturn(false)
+            whenever(kosmos.dozeParameters.shouldControlScreenOff()).thenReturn(false)
             val animationsEnabled by collectLastValue(underTest.areContainerChangesAnimated)
             runCurrent()
             assertThat(animationsEnabled).isFalse()
@@ -187,7 +157,7 @@
 
     @Test
     fun animationsEnabled_isTrue_whenStartingToSleepAndControlScreenOff() =
-        testComponent.runTest {
+        testScope.runTest {
             val animationsEnabled by collectLastValue(underTest.areContainerChangesAnimated)
             assertThat(animationsEnabled).isTrue()
 
@@ -203,13 +173,13 @@
                     transitionState = TransitionState.STARTED,
                 )
             )
-            whenever(dozeParams.shouldControlScreenOff()).thenReturn(true)
+            whenever(kosmos.dozeParameters.shouldControlScreenOff()).thenReturn(true)
             assertThat(animationsEnabled).isTrue()
         }
 
     @Test
     fun animationsEnabled_isTrue_whenNotAsleep() =
-        testComponent.runTest {
+        testScope.runTest {
             powerRepository.updateWakefulness(
                 rawState = WakefulnessState.AWAKE,
                 lastWakeReason = WakeSleepReason.POWER_BUTTON,
@@ -228,7 +198,7 @@
     @Test
     @DisableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR)
     fun animationsEnabled_isTrue_whenKeyguardIsShowing() =
-        testComponent.runTest {
+        testScope.runTest {
             keyguardTransitionRepository.sendTransitionStep(
                 TransitionStep(
                     transitionState = TransitionState.STARTED,
@@ -257,7 +227,7 @@
 
     @Test
     fun tintAlpha_isZero_whenNotOnAodOrDozing() =
-        testComponent.runTest {
+        testScope.runTest {
             val tintAlpha by collectLastValue(underTest.tintAlpha)
             runCurrent()
             keyguardTransitionRepository.sendTransitionSteps(
@@ -271,7 +241,7 @@
 
     @Test
     fun tintAlpha_isOne_whenOnAod() =
-        testComponent.runTest {
+        testScope.runTest {
             val tintAlpha by collectLastValue(underTest.tintAlpha)
             runCurrent()
             keyguardTransitionRepository.sendTransitionSteps(
@@ -285,7 +255,7 @@
 
     @Test
     fun tintAlpha_isOne_whenDozing() =
-        testComponent.runTest {
+        testScope.runTest {
             val tintAlpha by collectLastValue(underTest.tintAlpha)
             runCurrent()
             keyguardTransitionRepository.sendTransitionSteps(
@@ -298,7 +268,7 @@
 
     @Test
     fun tintAlpha_isOne_whenTransitionFromAodToDoze() =
-        testComponent.runTest {
+        testScope.runTest {
             keyguardTransitionRepository.sendTransitionSteps(
                 from = KeyguardState.GONE,
                 to = KeyguardState.AOD,
@@ -332,7 +302,7 @@
 
     @Test
     fun tintAlpha_isFraction_midTransitionToAod() =
-        testComponent.runTest {
+        testScope.runTest {
             val tintAlpha by collectLastValue(underTest.tintAlpha)
             runCurrent()
 
@@ -361,7 +331,7 @@
 
     @Test
     fun iconAnimationsEnabled_whenOnLockScreen() =
-        testComponent.runTest {
+        testScope.runTest {
             val iconAnimationsEnabled by collectLastValue(underTest.areIconAnimationsEnabled)
             runCurrent()
 
@@ -376,7 +346,7 @@
 
     @Test
     fun iconAnimationsDisabled_whenOnAod() =
-        testComponent.runTest {
+        testScope.runTest {
             val iconAnimationsEnabled by collectLastValue(underTest.areIconAnimationsEnabled)
             runCurrent()
 
@@ -391,7 +361,7 @@
 
     @Test
     fun iconAnimationsDisabled_whenDozing() =
-        testComponent.runTest {
+        testScope.runTest {
             val iconAnimationsEnabled by collectLastValue(underTest.areIconAnimationsEnabled)
             runCurrent()
 
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 bfe5c6e..61d14b7 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
@@ -60,6 +60,7 @@
 import android.os.PowerManager;
 import android.platform.test.annotations.DisableFlags;
 
+import android.platform.test.annotations.EnableFlags;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
@@ -244,6 +245,50 @@
     }
 
     @Test
+    @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
+    public void testShouldNotHeadsUp_silentNotification() {
+        // GIVEN state for "heads up when awake" is true
+        ensureStateForHeadsUpWhenAwake();
+
+        // WHEN the alert for a grouped notification is suppressed
+        // see {@link android.app.Notification#GROUP_ALERT_CHILDREN}
+        NotificationEntry entry = new NotificationEntryBuilder()
+            .setPkg("a")
+            .setOpPkg("a")
+            .setTag("a")
+            .setNotification(new Notification.Builder(getContext(), "a")
+                .setSilent(true)
+                .build())
+            .setImportance(IMPORTANCE_DEFAULT)
+            .build();
+
+        // THEN this entry shouldn't HUN
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
+    }
+
+    @Test
+    @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
+    public void testShouldNotHeadsUp_silentNotificationFalse() {
+        // GIVEN state for "heads up when awake" is true
+        ensureStateForHeadsUpWhenAwake();
+
+        // WHEN the alert for a grouped notification is suppressed
+        // see {@link android.app.Notification#GROUP_ALERT_CHILDREN}
+        NotificationEntry entry = new NotificationEntryBuilder()
+            .setPkg("a")
+            .setOpPkg("a")
+            .setTag("a")
+            .setNotification(new Notification.Builder(getContext(), "a")
+                .setSilent(false)
+                .build())
+            .setImportance(IMPORTANCE_HIGH)
+            .build();
+
+        // THEN this entry shouldn't HUN
+        assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isTrue();
+    }
+
+    @Test
     public void testShouldHeadsUpWhenDozing() {
         ensureStateForHeadsUpWhenDozing();
 
@@ -685,6 +730,26 @@
     }
 
     @Test
+    @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
+    public void testShouldNotFullScreen_silentNotification() {
+        Notification n = new Notification.Builder(getContext(), "a")
+            .setContentTitle("title")
+            .setContentText("content text")
+            .setFullScreenIntent(mPendingIntent, true)
+            .setSilent(true)
+            .build();
+        NotificationEntry entry = createNotification(IMPORTANCE_HIGH, n);
+
+        assertThat(mNotifInterruptionStateProvider.getFullScreenIntentDecision(entry))
+            .isEqualTo(FullScreenIntentDecision.NO_FSI_SUPPRESSIVE_SILENT_NOTIFICATION);
+        assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
+            .isFalse();
+        verify(mLogger).logNoFullscreen(entry, "NO_FSI_SUPPRESSIVE_SILENT_NOTIFICATION");
+        verify(mLogger, never()).logFullscreen(any(), any());
+        verify(mLogger, never()).logNoFullscreenWarning(any(), any());
+    }
+
+    @Test
     public void testShouldFullScreen_notInteractive() {
         NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
         Notification.BubbleMetadata bubbleMetadata = new Notification.BubbleMetadata.Builder("foo")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt
index e984200..a7f36c3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderImplTest.kt
@@ -20,6 +20,7 @@
 import android.app.Notification.CATEGORY_EVENT
 import android.app.Notification.CATEGORY_REMINDER
 import android.app.NotificationManager
+import android.content.pm.PackageManager.PERMISSION_DENIED
 import android.content.pm.PackageManager.PERMISSION_GRANTED
 import android.platform.test.annotations.EnableFlags
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -28,11 +29,16 @@
 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.BUBBLE
 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PEEK
 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionType.PULSE
-import java.util.Optional
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mockito.anyString
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when`
+import org.mockito.kotlin.whenever
+import java.util.Optional
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
@@ -58,7 +64,9 @@
             avalancheProvider,
             systemSettings,
             packageManager,
-            Optional.of(bubbles)
+            Optional.of(bubbles),
+            context,
+            notificationManager
         )
     }
 
@@ -87,12 +95,60 @@
     // because avalanche code is based on the suppression refactor.
 
     @Test
+    fun testAvalancheFilter_suppress_hasNotSeenEdu_showEduHun() {
+        setAllowedEmergencyPkg(false)
+        whenever(avalancheProvider.timeoutMs).thenReturn(20)
+        whenever(avalancheProvider.startTime).thenReturn(whenAgo(10))
+
+        val avalancheSuppressor = AvalancheSuppressor(
+            avalancheProvider, systemClock, systemSettings, packageManager,
+            uiEventLogger, context, notificationManager
+        )
+        avalancheSuppressor.hasSeenEdu = false
+
+        withFilter(avalancheSuppressor) {
+            ensurePeekState()
+            assertShouldNotHeadsUp(
+                buildEntry {
+                    importance = NotificationManager.IMPORTANCE_HIGH
+                    whenMs = whenAgo(5)
+                }
+            )
+        }
+        verify(notificationManager, times(1)).notify(anyInt(), any())
+    }
+
+    @Test
+    fun testAvalancheFilter_suppress_hasSeenEduHun_doNotShowEduHun() {
+        setAllowedEmergencyPkg(false)
+        whenever(avalancheProvider.timeoutMs).thenReturn(20)
+        whenever(avalancheProvider.startTime).thenReturn(whenAgo(10))
+
+        val avalancheSuppressor = AvalancheSuppressor(
+            avalancheProvider, systemClock, systemSettings, packageManager,
+            uiEventLogger, context, notificationManager
+        )
+        avalancheSuppressor.hasSeenEdu = true
+
+        withFilter(avalancheSuppressor) {
+            ensurePeekState()
+            assertShouldNotHeadsUp(
+                buildEntry {
+                    importance = NotificationManager.IMPORTANCE_HIGH
+                    whenMs = whenAgo(5)
+                }
+            )
+        }
+        verify(notificationManager, times(0)).notify(anyInt(), any())
+    }
+
+    @Test
     fun testAvalancheFilter_duringAvalanche_allowConversationFromAfterEvent() {
         avalancheProvider.startTime = whenAgo(10)
 
         withFilter(
             AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
-                    uiEventLogger)
+                    uiEventLogger, context, notificationManager)
         ) {
             ensurePeekState()
             assertShouldHeadsUp(
@@ -112,7 +168,7 @@
 
         withFilter(
             AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
-                    uiEventLogger)
+                    uiEventLogger, context, notificationManager)
         ) {
             ensurePeekState()
             assertShouldNotHeadsUp(
@@ -132,7 +188,7 @@
 
         withFilter(
             AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
-                    uiEventLogger)
+                    uiEventLogger, context, notificationManager)
         ) {
             ensurePeekState()
             assertShouldHeadsUp(
@@ -150,7 +206,7 @@
 
         withFilter(
             AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
-                    uiEventLogger)
+                    uiEventLogger, context, notificationManager)
         ) {
             ensurePeekState()
             assertShouldHeadsUp(
@@ -168,7 +224,7 @@
 
         withFilter(
             AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
-                    uiEventLogger)
+                    uiEventLogger, context, notificationManager)
         ) {
             ensurePeekState()
             assertShouldHeadsUp(
@@ -186,7 +242,7 @@
 
         withFilter(
             AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
-                    uiEventLogger)
+                    uiEventLogger, context, notificationManager)
         ) {
             ensurePeekState()
             assertShouldHeadsUp(
@@ -204,7 +260,7 @@
 
         withFilter(
             AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
-                    uiEventLogger)
+                    uiEventLogger, context, notificationManager)
         ) {
             assertFsiNotSuppressed()
         }
@@ -216,7 +272,7 @@
 
         withFilter(
             AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
-                    uiEventLogger)
+                    uiEventLogger, context, notificationManager)
         ) {
             ensurePeekState()
             assertShouldHeadsUp(
@@ -228,20 +284,24 @@
         }
     }
 
-    @Test
-    fun testAvalancheFilter_duringAvalanche_allowEmergency() {
-        avalancheProvider.startTime = whenAgo(10)
-
+    private fun setAllowedEmergencyPkg(allow: Boolean) {
         `when`(
             packageManager.checkPermission(
                 org.mockito.Mockito.eq(permission.RECEIVE_EMERGENCY_BROADCAST),
                 anyString()
             )
-        ).thenReturn(PERMISSION_GRANTED)
+        ).thenReturn(if (allow) PERMISSION_GRANTED else PERMISSION_DENIED)
+    }
+
+    @Test
+    fun testAvalancheFilter_duringAvalanche_allowEmergency() {
+        avalancheProvider.startTime = whenAgo(10)
+
+        setAllowedEmergencyPkg(true)
 
         withFilter(
             AvalancheSuppressor(avalancheProvider, systemClock, systemSettings, packageManager,
-                    uiEventLogger)
+                    uiEventLogger, context, notificationManager)
         ) {
             ensurePeekState()
             assertShouldHeadsUp(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
index a457405..d5ab62b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestBase.kt
@@ -31,6 +31,7 @@
 import android.app.Notification.GROUP_ALERT_SUMMARY
 import android.app.Notification.VISIBILITY_PRIVATE
 import android.app.NotificationChannel
+import android.app.NotificationManager
 import android.app.NotificationManager.IMPORTANCE_DEFAULT
 import android.app.NotificationManager.IMPORTANCE_HIGH
 import android.app.NotificationManager.IMPORTANCE_LOW
@@ -48,6 +49,7 @@
 import android.hardware.display.FakeAmbientDisplayConfiguration
 import android.os.Looper
 import android.os.PowerManager
+import android.platform.test.annotations.EnableFlags
 import android.provider.Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED
 import android.provider.Settings.Global.HEADS_UP_OFF
 import android.provider.Settings.Global.HEADS_UP_ON
@@ -133,7 +135,7 @@
     protected val bubbles: Bubbles = mock()
     lateinit var systemSettings: SystemSettings
     protected val packageManager: PackageManager = mock()
-
+    protected val notificationManager: NotificationManager = mock()
     protected abstract val provider: VisualInterruptionDecisionProvider
 
     private val neverSuppresses = object : NotificationInterruptSuppressor {}
@@ -531,6 +533,32 @@
     }
 
     @Test
+    @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
+    fun testShouldNotHeadsUp_silentNotification() {
+        withPeekAndPulseEntry({
+                                  isGrouped = false
+                                  isGroupSummary = false
+                                  isSilent = true
+                              }) {
+            assertShouldNotHeadsUp(it)
+            assertNoEventsLogged()
+        }
+    }
+
+    @Test
+    @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
+    fun testShouldHeadsUp_silentNotificationFalse() {
+        withPeekAndPulseEntry({
+                                  isGrouped = false
+                                  isGroupSummary = false
+                                  isSilent = false
+                              }) {
+            assertShouldHeadsUp(it)
+            assertNoEventsLogged()
+        }
+    }
+
+    @Test
     fun testShouldNotHeadsUp_justLaunchedFsi() {
         withPeekAndPulseEntry({ hasJustLaunchedFsi = true }) {
             assertShouldNotHeadsUp(it)
@@ -1162,6 +1190,7 @@
         var groupAlertBehavior: Int? = null
         var hasBubbleMetadata = false
         var hasFsi = false
+        var isSilent = false
 
         // Set on Notification:
         var isForegroundService = false
@@ -1232,6 +1261,8 @@
                     }
                     groupAlertBehavior?.let { nb.setGroupAlertBehavior(it) }
 
+                    nb.setSilent(isSilent)
+
                     if (hasBubbleMetadata) {
                         nb.setBubbleMetadata(buildBubbleMetadata())
                     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt
index 01e638b..f4cebd7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProviderTestUtil.kt
@@ -15,6 +15,8 @@
  */
 package com.android.systemui.statusbar.notification.interruption
 
+import android.app.NotificationManager
+import android.content.Context
 import android.content.pm.PackageManager
 import android.hardware.display.AmbientDisplayConfiguration
 import android.os.Handler
@@ -58,6 +60,8 @@
         systemSettings: SystemSettings,
         packageManager: PackageManager,
         bubbles: Optional<Bubbles>,
+        context: Context,
+        notificationManager: NotificationManager
     ): VisualInterruptionDecisionProvider {
         return if (VisualInterruptionRefactor.isEnabled) {
             VisualInterruptionDecisionProviderImpl(
@@ -79,7 +83,9 @@
                 avalancheProvider,
                 systemSettings,
                 packageManager,
-                bubbles
+                bubbles,
+                context,
+                notificationManager
             )
         } else {
             NotificationInterruptStateProviderWrapper(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index 7304bd6..e8349b0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -71,6 +71,7 @@
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
 import com.android.systemui.statusbar.notification.shared.NotificationContentAlphaOptimization;
 import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
+import com.android.systemui.statusbar.phone.ExpandHeadsUpOnInlineReply;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 
 import org.junit.Assert;
@@ -328,7 +329,7 @@
 
     @Test
     @EnableFlags(NotificationContentAlphaOptimization.FLAG_NAME)
-    public void setHideSensitive_changeContent_shouldNotDisturbAnimation() throws Exception {
+    public void setHideSensitive_changeContent_shouldResetAlpha() throws Exception {
 
         // Given: A sensitive row that has public version but is not hiding sensitive,
         // and is during an animation that sets its alpha value to be 0.5f
@@ -351,12 +352,12 @@
 
         // Then: The alpha value of private layout should be reset to 1, private layout be
         // INVISIBLE;
-        // The alpha value of public layout should be 0.5 to preserve the animation state, public
-        // layout should be VISIBLE
+        // The alpha value of public layout should be reset to 1 to avoid remaining transparent,
+        // public layout should be VISIBLE
         assertEquals(View.INVISIBLE, row.getPrivateLayout().getVisibility());
         assertEquals(1f, row.getPrivateLayout().getAlpha(), 0);
         assertEquals(View.VISIBLE, row.getPublicLayout().getVisibility());
-        assertEquals(0.5f, row.getPublicLayout().getAlpha(), 0);
+        assertEquals(1f, row.getPublicLayout().getAlpha(), 0);
     }
 
     @Test
@@ -793,6 +794,231 @@
     }
 
     @Test
+    public void isExpanded_onKeyguard_allowOnKeyguardExpanded() throws Exception {
+        // GIVEN
+        final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setOnKeyguard(true);
+        row.setUserExpanded(true);
+
+        // THEN
+        assertThat(row.isExpanded(/*allowOnKeyguard =*/ true)).isTrue();
+    }
+    @Test
+    public void isExpanded_onKeyguard_notAllowOnKeyguardNotExpanded() throws Exception {
+        // GIVEN
+        final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setOnKeyguard(true);
+        row.setUserExpanded(true);
+
+        // THEN
+        assertThat(row.isExpanded(/*allowOnKeyguard =*/ false)).isFalse();
+    }
+
+    @Test
+    public void isExpanded_systemExpanded_expanded() throws Exception {
+        // GIVEN
+        final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setOnKeyguard(false);
+        row.setSystemExpanded(true);
+
+        // THEN
+        assertThat(row.isExpanded()).isTrue();
+    }
+
+    @Test
+    public void isExpanded_systemChildExpanded_expanded() throws Exception {
+        // GIVEN
+        final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setOnKeyguard(false);
+        row.setSystemChildExpanded(true);
+
+        // THEN
+        assertThat(row.isExpanded()).isTrue();
+    }
+
+    @Test
+    public void isExpanded_userExpanded_expanded() throws Exception {
+        // GIVEN
+        final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setOnKeyguard(false);
+        row.setSystemExpanded(true);
+        row.setUserExpanded(true);
+
+        // THEN
+        assertThat(row.isExpanded()).isTrue();
+    }
+
+    @Test
+    public void isExpanded_userExpandedFalse_notExpanded() throws Exception {
+        // GIVEN
+        final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setOnKeyguard(false);
+        row.setSystemExpanded(true);
+        row.setUserExpanded(false);
+
+        // THEN
+        assertThat(row.isExpanded()).isFalse();
+    }
+
+    @Test
+    @EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
+    public void isExpanded_HUNsystemExpandedTrueForPinned_notExpanded() throws Exception {
+        // GIVEN
+        final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setOnKeyguard(false);
+        row.setSystemExpanded(true);
+        row.setPinned(true);
+        row.setHeadsUp(true);
+
+        // THEN
+        assertThat(row.isExpanded()).isFalse();
+    }
+
+    @Test
+    @EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
+    public void isExpanded_HUNsystemExpandedTrueForNotPinned_expanded() throws Exception {
+        // GIVEN
+        final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setOnKeyguard(false);
+        row.setSystemExpanded(true);
+        row.setPinned(false);
+        row.setHeadsUp(true);
+
+        // THEN
+        assertThat(row.isExpanded()).isTrue();
+    }
+
+    @Test
+    @EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
+    public void isExpanded_HUNDisappearingsystemExpandedTrueForPinned_notExpanded()
+            throws Exception {
+        // GIVEN
+        final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setOnKeyguard(false);
+        row.setSystemExpanded(true);
+        row.setPinned(true);
+        row.setHeadsUpAnimatingAway(true);
+
+        // THEN
+        assertThat(row.isExpanded()).isFalse();
+    }
+
+    @Test
+    @EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
+    public void isExpanded_HUNDisappearingsystemExpandedTrueForNotPinned_expanded()
+            throws Exception {
+        // GIVEN
+        final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setOnKeyguard(false);
+        row.setSystemExpanded(true);
+        row.setPinned(false);
+        row.setHeadsUpAnimatingAway(true);
+
+        // THEN
+        assertThat(row.isExpanded()).isTrue();
+    }
+
+    @Test
+    @EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
+    public void isExpanded_userExpandedTrueForHeadsUp_expanded() throws Exception {
+        // GIVEN
+        final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setOnKeyguard(false);
+        row.setSystemExpanded(true);
+        row.setHeadsUpAnimatingAway(true);
+        row.setUserExpanded(true);
+
+        // THEN
+        assertThat(row.isExpanded()).isTrue();
+    }
+    @Test
+    @EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
+    public void isExpanded_userExpandedTrueForHeadsUpDisappearRunning_expanded() throws Exception {
+        // GIVEN
+        final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setOnKeyguard(false);
+        row.setSystemExpanded(true);
+        row.setHeadsUpAnimatingAway(true);
+        row.setUserExpanded(true);
+
+        // THEN
+        assertThat(row.isExpanded()).isTrue();
+    }
+
+    @Test
+    @EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
+    public void isExpanded_userExpandedFalseForHeadsUp_notExpanded() throws Exception {
+        // GIVEN
+        final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setOnKeyguard(false);
+        row.setSystemExpanded(true);
+        row.setHeadsUpAnimatingAway(true);
+        row.setUserExpanded(false);
+
+        // THEN
+        assertThat(row.isExpanded()).isFalse();
+    }
+    @Test
+    @EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
+    public void isExpanded_userExpandedFalseForHeadsUpDisappearRunning_notExpanded()
+            throws Exception {
+        // GIVEN
+        final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setOnKeyguard(false);
+        row.setSystemExpanded(true);
+        row.setHeadsUpAnimatingAway(true);
+        row.setUserExpanded(false);
+
+        // THEN
+        assertThat(row.isExpanded()).isFalse();
+    }
+
+    @Test
+    @EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
+    public void isExpanded_HUNexpandedWhenPinningTrue_expanded() throws Exception {
+        // GIVEN
+        final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setOnKeyguard(false);
+        row.setSystemExpanded(true);
+        row.setHeadsUp(true);
+        row.setPinned(true);
+
+        // WHEN
+        row.expandNotification();
+
+        // THEN
+        assertThat(row.isExpanded()).isTrue();
+    }
+
+    @Test
+    @EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
+    public void isExpanded_HUNexpandedWhenPinningFalse_notExpanded() throws Exception {
+        // GIVEN
+        final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setOnKeyguard(false);
+        row.setSystemExpanded(false);
+        row.setHeadsUp(true);
+        row.setPinned(true);
+
+        // THEN
+        assertThat(row.isExpanded()).isFalse();
+    }
+
+    @Test
+    @EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
+    public void hasUserChangedExpansion_expandPinned_returnTrue() throws Exception {
+        // GIVEN
+        final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+        row.setPinned(true);
+
+        // WHEN
+        row.expandNotification();
+
+        // THEN
+        assertThat(row.hasUserChangedExpansion()).isTrue();
+    }
+
+    @Test
     public void onDisappearAnimationFinished_shouldSetFalse_headsUpAnimatingAway()
             throws Exception {
         final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
index e6cba1c..54a26f7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImplTest.kt
@@ -23,6 +23,7 @@
 import android.platform.test.annotations.EnableFlags
 import android.testing.TestableLooper.RunWithLooper
 import android.util.TypedValue
+import android.util.TypedValue.COMPLEX_UNIT_SP
 import android.view.View
 import android.view.ViewGroup
 import android.widget.RemoteViews
@@ -34,27 +35,39 @@
 import com.android.systemui.statusbar.notification.ConversationNotificationProcessor
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.BindParams
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_ALL
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationCallback
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag
 import com.android.systemui.statusbar.notification.row.shared.HeadsUpStatusBarModel
 import com.android.systemui.statusbar.notification.row.shared.NewRemoteViews
 import com.android.systemui.statusbar.notification.row.shared.NotificationContentModel
 import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor
+import com.android.systemui.statusbar.notification.row.shared.RichOngoingContentModel
+import com.android.systemui.statusbar.notification.row.shared.TimerContentModel
 import com.android.systemui.statusbar.policy.InflatedSmartReplyState
 import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder
 import com.android.systemui.statusbar.policy.SmartReplyStateInflater
-import com.android.systemui.util.concurrency.mockExecutorHandler
+import com.google.common.truth.Truth.assertThat
 import java.util.concurrent.CountDownLatch
 import java.util.concurrent.Executor
 import java.util.concurrent.TimeUnit
+import kotlinx.coroutines.DisposableHandle
 import org.junit.Assert
 import org.junit.Before
 import org.junit.Ignore
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.kotlin.any
+import org.mockito.kotlin.argThat
+import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.doReturn
 import org.mockito.kotlin.eq
+import org.mockito.kotlin.inOrder
 import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
 import org.mockito.kotlin.spy
 import org.mockito.kotlin.times
 import org.mockito.kotlin.verify
@@ -65,20 +78,24 @@
 @RunWithLooper
 @EnableFlags(NotificationRowContentBinderRefactor.FLAG_NAME)
 class NotificationRowContentBinderImplTest : SysuiTestCase() {
-    private lateinit var mNotificationInflater: NotificationRowContentBinderImpl
-    private lateinit var mBuilder: Notification.Builder
-    private lateinit var mRow: ExpandableNotificationRow
-    private lateinit var mHelper: NotificationTestHelper
+    private lateinit var notificationInflater: NotificationRowContentBinderImpl
+    private lateinit var builder: Notification.Builder
+    private lateinit var row: ExpandableNotificationRow
+    private lateinit var testHelper: NotificationTestHelper
 
-    private var mCache: NotifRemoteViewCache = mock()
-    private var mConversationNotificationProcessor: ConversationNotificationProcessor = mock()
-    private var mInflatedSmartReplyState: InflatedSmartReplyState = mock()
-    private var mInflatedSmartReplies: InflatedSmartReplyViewHolder = mock()
-    private var mNotifLayoutInflaterFactoryProvider: NotifLayoutInflaterFactory.Provider = mock()
-    private var mHeadsUpStyleProvider: HeadsUpStyleProvider = mock()
-    private var mNotifLayoutInflaterFactory: NotifLayoutInflaterFactory = mock()
-    private val mSmartReplyStateInflater: SmartReplyStateInflater =
+    private val cache: NotifRemoteViewCache = mock()
+    private val layoutInflaterFactoryProvider =
+        object : NotifLayoutInflaterFactory.Provider {
+            override fun provide(
+                row: ExpandableNotificationRow,
+                layoutType: Int
+            ): NotifLayoutInflaterFactory = mock()
+        }
+    private val smartReplyStateInflater: SmartReplyStateInflater =
         object : SmartReplyStateInflater {
+            private val inflatedSmartReplyState: InflatedSmartReplyState = mock()
+            private val inflatedSmartReplies: InflatedSmartReplyViewHolder = mock()
+
             override fun inflateSmartReplyViewHolder(
                 sysuiContext: Context,
                 notifPackageContext: Context,
@@ -86,37 +103,61 @@
                 existingSmartReplyState: InflatedSmartReplyState?,
                 newSmartReplyState: InflatedSmartReplyState
             ): InflatedSmartReplyViewHolder {
-                return mInflatedSmartReplies
+                return inflatedSmartReplies
             }
 
             override fun inflateSmartReplyState(entry: NotificationEntry): InflatedSmartReplyState {
-                return mInflatedSmartReplyState
+                return inflatedSmartReplyState
             }
         }
 
+    private var fakeRonContentModel: RichOngoingContentModel? = null
+    private val fakeRonExtractor =
+        object : RichOngoingNotificationContentExtractor {
+            override fun extractContentModel(
+                entry: NotificationEntry,
+                builder: Notification.Builder,
+                systemUIContext: Context,
+                packageContext: Context
+            ): RichOngoingContentModel? = fakeRonContentModel
+        }
+
+    private var fakeRonViewHolder: InflatedContentViewHolder? = null
+    private val fakeRonViewInflater =
+        spy(
+            object : RichOngoingNotificationViewInflater {
+                override fun inflateView(
+                    contentModel: RichOngoingContentModel,
+                    existingView: View?,
+                    entry: NotificationEntry,
+                    systemUiContext: Context,
+                    parentView: ViewGroup
+                ): InflatedContentViewHolder? = fakeRonViewHolder
+            }
+        )
+
     @Before
     fun setUp() {
         allowTestableLooperAsMainThread()
-        mBuilder =
+        builder =
             Notification.Builder(mContext, "no-id")
                 .setSmallIcon(R.drawable.ic_person)
                 .setContentTitle("Title")
                 .setContentText("Text")
                 .setStyle(Notification.BigTextStyle().bigText("big text"))
-        mHelper = NotificationTestHelper(mContext, mDependency)
-        val row = mHelper.createRow(mBuilder.build())
-        mRow = spy(row)
-        whenever(mNotifLayoutInflaterFactoryProvider.provide(any(), any()))
-            .thenReturn(mNotifLayoutInflaterFactory)
-        mNotificationInflater =
+        testHelper = NotificationTestHelper(mContext, mDependency)
+        row = spy(testHelper.createRow(builder.build()))
+        notificationInflater =
             NotificationRowContentBinderImpl(
-                mCache,
+                cache,
                 mock(),
-                mConversationNotificationProcessor,
+                mock<ConversationNotificationProcessor>(),
+                fakeRonExtractor,
+                fakeRonViewInflater,
                 mock(),
-                mSmartReplyStateInflater,
-                mNotifLayoutInflaterFactoryProvider,
-                mHeadsUpStyleProvider,
+                smartReplyStateInflater,
+                layoutInflaterFactoryProvider,
+                mock<HeadsUpStyleProvider>(),
                 mock()
             )
     }
@@ -125,16 +166,16 @@
     fun testIncreasedHeadsUpBeingUsed() {
         val params = BindParams()
         params.usesIncreasedHeadsUpHeight = true
-        val builder = spy(mBuilder)
-        mNotificationInflater.inflateNotificationViews(
-            mRow.entry,
-            mRow,
+        val builder = spy(builder)
+        notificationInflater.inflateNotificationViews(
+            row.entry,
+            row,
             params,
             true /* inflateSynchronously */,
-            NotificationRowContentBinder.FLAG_CONTENT_VIEW_ALL,
+            FLAG_CONTENT_VIEW_ALL,
             builder,
             mContext,
-            mSmartReplyStateInflater
+            smartReplyStateInflater
         )
         verify(builder).createHeadsUpContentView(true)
     }
@@ -143,80 +184,68 @@
     fun testIncreasedHeightBeingUsed() {
         val params = BindParams()
         params.usesIncreasedHeight = true
-        val builder = spy(mBuilder)
-        mNotificationInflater.inflateNotificationViews(
-            mRow.entry,
-            mRow,
+        val builder = spy(builder)
+        notificationInflater.inflateNotificationViews(
+            row.entry,
+            row,
             params,
             true /* inflateSynchronously */,
-            NotificationRowContentBinder.FLAG_CONTENT_VIEW_ALL,
+            FLAG_CONTENT_VIEW_ALL,
             builder,
             mContext,
-            mSmartReplyStateInflater
+            smartReplyStateInflater
         )
         verify(builder).createContentView(true)
     }
 
     @Test
     fun testInflationCallsUpdated() {
-        inflateAndWait(
-            mNotificationInflater,
-            NotificationRowContentBinder.FLAG_CONTENT_VIEW_ALL,
-            mRow
-        )
-        verify(mRow).onNotificationUpdated()
+        inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_ALL, row)
+        verify(row).onNotificationUpdated()
     }
 
     @Test
     fun testInflationOnlyInflatesSetFlags() {
-        inflateAndWait(
-            mNotificationInflater,
-            NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP,
-            mRow
-        )
-        Assert.assertNotNull(mRow.privateLayout.headsUpChild)
-        verify(mRow).onNotificationUpdated()
+        inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_HEADS_UP, row)
+        Assert.assertNotNull(row.privateLayout.headsUpChild)
+        verify(row).onNotificationUpdated()
     }
 
     @Test
     fun testInflationThrowsErrorDoesntCallUpdated() {
-        mRow.privateLayout.removeAllViews()
-        mRow.entry.sbn.notification.contentView =
+        row.privateLayout.removeAllViews()
+        row.entry.sbn.notification.contentView =
             RemoteViews(mContext.packageName, R.layout.status_bar)
         inflateAndWait(
             true /* expectingException */,
-            mNotificationInflater,
-            NotificationRowContentBinder.FLAG_CONTENT_VIEW_ALL,
-            mRow
+            notificationInflater,
+            FLAG_CONTENT_VIEW_ALL,
+            row
         )
-        Assert.assertTrue(mRow.privateLayout.childCount == 0)
-        verify(mRow, times(0)).onNotificationUpdated()
+        Assert.assertTrue(row.privateLayout.childCount == 0)
+        verify(row, times(0)).onNotificationUpdated()
     }
 
     @Test
     fun testAsyncTaskRemoved() {
-        mRow.entry.abortTask()
-        inflateAndWait(
-            mNotificationInflater,
-            NotificationRowContentBinder.FLAG_CONTENT_VIEW_ALL,
-            mRow
-        )
-        verify(mRow).onNotificationUpdated()
+        row.entry.abortTask()
+        inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_ALL, row)
+        verify(row).onNotificationUpdated()
     }
 
     @Test
     fun testRemovedNotInflated() {
-        mRow.setRemoved()
-        mNotificationInflater.setInflateSynchronously(true)
-        mNotificationInflater.bindContent(
-            mRow.entry,
-            mRow,
-            NotificationRowContentBinder.FLAG_CONTENT_VIEW_ALL,
+        row.setRemoved()
+        notificationInflater.setInflateSynchronously(true)
+        notificationInflater.bindContent(
+            row.entry,
+            row,
+            FLAG_CONTENT_VIEW_ALL,
             BindParams(),
             false /* forceInflate */,
             null /* callback */
         )
-        Assert.assertNull(mRow.entry.runningTask)
+        Assert.assertNull(row.entry.runningTask)
     }
 
     @Test
@@ -235,11 +264,11 @@
             inflateSynchronously = false,
             isMinimized = false,
             result = result,
-            reInflateFlags = NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED,
+            reInflateFlags = FLAG_CONTENT_VIEW_EXPANDED,
             inflationId = 0,
             remoteViewCache = mock(),
-            entry = mRow.entry,
-            row = mRow,
+            entry = row.entry,
+            row = row,
             isNewView = true, /* isNewView */
             remoteViewClickHandler = { _, _, _ -> true },
             callback =
@@ -253,7 +282,7 @@
                         countDownLatch.countDown()
                     }
                 },
-            parentLayout = mRow.privateLayout,
+            parentLayout = row.privateLayout,
             existingView = null,
             existingWrapper = null,
             runningInflations = HashMap(),
@@ -275,13 +304,13 @@
 
     @Test
     fun doesntReapplyDisallowedRemoteView() {
-        mBuilder.setStyle(Notification.MediaStyle())
-        val mediaView = mBuilder.createContentView()
-        mBuilder.setStyle(Notification.DecoratedCustomViewStyle())
-        mBuilder.setCustomContentView(
+        builder.setStyle(Notification.MediaStyle())
+        val mediaView = builder.createContentView()
+        builder.setStyle(Notification.DecoratedCustomViewStyle())
+        builder.setCustomContentView(
             RemoteViews(context.packageName, com.android.systemui.tests.R.layout.custom_view_dark)
         )
-        val decoratedMediaView = mBuilder.createContentView()
+        val decoratedMediaView = builder.createContentView()
         Assert.assertFalse(
             "The decorated media style doesn't allow a view to be reapplied!",
             NotificationRowContentBinderImpl.canReapplyRemoteView(mediaView, decoratedMediaView)
@@ -292,112 +321,167 @@
     @Ignore("b/345418902")
     fun testUsesSameViewWhenCachedPossibleToReuse() {
         // GIVEN a cached view.
-        val contractedRemoteView = mBuilder.createContentView()
-        whenever(
-                mCache.hasCachedView(
-                    mRow.entry,
-                    NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED
-                )
-            )
-            .thenReturn(true)
-        whenever(
-                mCache.getCachedView(
-                    mRow.entry,
-                    NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED
-                )
-            )
+        val contractedRemoteView = builder.createContentView()
+        whenever(cache.hasCachedView(row.entry, FLAG_CONTENT_VIEW_CONTRACTED)).thenReturn(true)
+        whenever(cache.getCachedView(row.entry, FLAG_CONTENT_VIEW_CONTRACTED))
             .thenReturn(contractedRemoteView)
 
         // GIVEN existing bound view with same layout id.
         val view = contractedRemoteView.apply(mContext, null /* parent */)
-        mRow.privateLayout.setContractedChild(view)
+        row.privateLayout.setContractedChild(view)
 
         // WHEN inflater inflates
-        inflateAndWait(
-            mNotificationInflater,
-            NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED,
-            mRow
-        )
+        inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_CONTRACTED, row)
 
         // THEN the view should be re-used
         Assert.assertEquals(
             "Binder inflated a new view even though the old one was cached and usable.",
             view,
-            mRow.privateLayout.contractedChild
+            row.privateLayout.contractedChild
         )
     }
 
     @Test
     fun testInflatesNewViewWhenCachedNotPossibleToReuse() {
         // GIVEN a cached remote view.
-        val contractedRemoteView = mBuilder.createHeadsUpContentView()
-        whenever(
-                mCache.hasCachedView(
-                    mRow.entry,
-                    NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED
-                )
-            )
-            .thenReturn(true)
-        whenever(
-                mCache.getCachedView(
-                    mRow.entry,
-                    NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED
-                )
-            )
+        val contractedRemoteView = builder.createHeadsUpContentView()
+        whenever(cache.hasCachedView(row.entry, FLAG_CONTENT_VIEW_CONTRACTED)).thenReturn(true)
+        whenever(cache.getCachedView(row.entry, FLAG_CONTENT_VIEW_CONTRACTED))
             .thenReturn(contractedRemoteView)
 
         // GIVEN existing bound view with different layout id.
         val view: View = TextView(mContext)
-        mRow.privateLayout.setContractedChild(view)
+        row.privateLayout.setContractedChild(view)
 
         // WHEN inflater inflates
-        inflateAndWait(
-            mNotificationInflater,
-            NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED,
-            mRow
-        )
+        inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_CONTRACTED, row)
 
         // THEN the view should be a new view
         Assert.assertNotEquals(
             "Binder (somehow) used the same view when inflating.",
             view,
-            mRow.privateLayout.contractedChild
+            row.privateLayout.contractedChild
         )
     }
 
     @Test
     fun testInflationCachesCreatedRemoteView() {
         // WHEN inflater inflates
-        inflateAndWait(
-            mNotificationInflater,
-            NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED,
-            mRow
-        )
+        inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_CONTRACTED, row)
 
         // THEN inflater informs cache of the new remote view
-        verify(mCache)
-            .putCachedView(
-                eq(mRow.entry),
-                eq(NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED),
-                any()
-            )
+        verify(cache).putCachedView(eq(row.entry), eq(FLAG_CONTENT_VIEW_CONTRACTED), any())
     }
 
     @Test
     fun testUnbindRemovesCachedRemoteView() {
         // WHEN inflated unbinds content
-        mNotificationInflater.unbindContent(
-            mRow.entry,
-            mRow,
-            NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP
-        )
+        notificationInflater.unbindContent(row.entry, row, FLAG_CONTENT_VIEW_HEADS_UP)
 
         // THEN inflated informs cache to remove remote view
-        verify(mCache)
-            .removeCachedView(
-                eq(mRow.entry),
-                eq(NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP)
-            )
+        verify(cache).removeCachedView(eq(row.entry), eq(FLAG_CONTENT_VIEW_HEADS_UP))
+    }
+
+    @Test
+    fun testRonModelRequiredForRonView() {
+        fakeRonContentModel = null
+        val ronView = View(context)
+        fakeRonViewHolder = InflatedContentViewHolder(view = ronView, binder = mock())
+        // WHEN inflater inflates
+        inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_CONTRACTED, row)
+        verify(fakeRonViewInflater, never()).inflateView(any(), any(), any(), any(), any())
+    }
+
+    @Test
+    fun testRonModelTriggersInflationOfRonView() {
+        val mockRonModel = mock<TimerContentModel>()
+        val ronView = View(context)
+        val mockBinder = mock<DeferredContentViewBinder>()
+
+        val entry = row.entry
+        val privateLayout = row.privateLayout
+
+        fakeRonContentModel = mockRonModel
+        fakeRonViewHolder = InflatedContentViewHolder(view = ronView, binder = mockBinder)
+        // WHEN inflater inflates
+        inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_CONTRACTED, row)
+        // VERIFY that the inflater is invoked
+        verify(fakeRonViewInflater)
+            .inflateView(eq(mockRonModel), any(), eq(entry), any(), eq(privateLayout))
+        assertThat(row.privateLayout.contractedChild).isSameInstanceAs(ronView)
+        verify(mockBinder).setupContentViewBinder()
+    }
+
+    @Test
+    fun ronViewAppliesElementsInOrder() {
+        val oldHandle = mock<DisposableHandle>()
+        val mockRonModel = mock<TimerContentModel>()
+        val ronView = View(context)
+        val mockBinder = mock<DeferredContentViewBinder>()
+
+        row.privateLayout.mContractedBinderHandle = oldHandle
+        val entry = spy(row.entry)
+        row.entry = entry
+        val privateLayout = spy(row.privateLayout)
+        row.privateLayout = privateLayout
+
+        fakeRonContentModel = mockRonModel
+        fakeRonViewHolder = InflatedContentViewHolder(view = ronView, binder = mockBinder)
+        // WHEN inflater inflates
+        inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_CONTRACTED, row)
+
+        // Validate that these 4 steps happen in this precise order
+        inOrder(oldHandle, entry, privateLayout, mockBinder) {
+            verify(oldHandle).dispose()
+            verify(entry).setContentModel(argThat { richOngoingContentModel === mockRonModel })
+            verify(privateLayout).setContractedChild(eq(ronView))
+            verify(mockBinder).setupContentViewBinder()
+        }
+    }
+
+    @Test
+    fun testRonNotReinflating() {
+        val handle0 = mock<DisposableHandle>()
+        val handle1 = mock<DisposableHandle>()
+        val ronView = View(context)
+        val mockRonModel1 = mock<TimerContentModel>()
+        val mockRonModel2 = mock<TimerContentModel>()
+        val mockBinder1 = mock<DeferredContentViewBinder>()
+        doReturn(handle1).whenever(mockBinder1).setupContentViewBinder()
+
+        row.privateLayout.mContractedBinderHandle = handle0
+        val entry = spy(row.entry)
+        row.entry = entry
+        val privateLayout = spy(row.privateLayout)
+        row.privateLayout = privateLayout
+
+        // WHEN inflater inflates both a model and a view
+        fakeRonContentModel = mockRonModel1
+        fakeRonViewHolder = InflatedContentViewHolder(view = ronView, binder = mockBinder1)
+        inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_CONTRACTED, row)
+
+        // Validate that these 4 steps happen in this precise order
+        inOrder(handle0, entry, privateLayout, mockBinder1, handle1) {
+            verify(handle0).dispose()
+            verify(entry).setContentModel(argThat { richOngoingContentModel === mockRonModel1 })
+            verify(privateLayout).setContractedChild(eq(ronView))
+            verify(mockBinder1).setupContentViewBinder()
+            verify(handle1, never()).dispose()
+        }
+
+        clearInvocations(handle0, entry, privateLayout, mockBinder1, handle1)
+
+        // THEN when the inflater inflates just a model
+        fakeRonContentModel = mockRonModel2
+        fakeRonViewHolder = null
+        inflateAndWait(notificationInflater, FLAG_CONTENT_VIEW_CONTRACTED, row)
+
+        // Validate that for reinflation, the only thing we do us update the model
+        verify(handle1, never()).dispose()
+        verify(entry).setContentModel(argThat { richOngoingContentModel === mockRonModel2 })
+        verify(privateLayout, never()).setContractedChild(any())
+        verify(mockBinder1, never()).setupContentViewBinder()
+        verify(handle1, never()).dispose()
     }
 
     @Test
@@ -453,46 +537,36 @@
         whenever(view.measuredHeight)
             .thenReturn(
                 TypedValue.applyDimension(
-                        TypedValue.COMPLEX_UNIT_SP,
+                        COMPLEX_UNIT_SP,
                         measuredHeightDp,
                         mContext.resources.displayMetrics
                     )
                     .toInt()
             )
-        mRow.entry.targetSdk = targetSdk
-        mRow.entry.sbn.notification.contentView = contentView
-        return NotificationRowContentBinderImpl.isValidView(view, mRow.entry, mContext.resources)
+        row.entry.targetSdk = targetSdk
+        row.entry.sbn.notification.contentView = contentView
+        return NotificationRowContentBinderImpl.isValidView(view, row.entry, mContext.resources)
     }
 
     @Test
     fun testInvalidNotificationDoesNotInvokeCallback() {
-        mRow.privateLayout.removeAllViews()
-        mRow.entry.sbn.notification.contentView =
+        row.privateLayout.removeAllViews()
+        row.entry.sbn.notification.contentView =
             RemoteViews(
                 mContext.packageName,
                 com.android.systemui.tests.R.layout.invalid_notification_height
             )
-        inflateAndWait(
-            true,
-            mNotificationInflater,
-            NotificationRowContentBinder.FLAG_CONTENT_VIEW_ALL,
-            mRow
-        )
-        Assert.assertEquals(0, mRow.privateLayout.childCount.toLong())
-        verify(mRow, times(0)).onNotificationUpdated()
+        inflateAndWait(true, notificationInflater, FLAG_CONTENT_VIEW_ALL, row)
+        Assert.assertEquals(0, row.privateLayout.childCount.toLong())
+        verify(row, times(0)).onNotificationUpdated()
     }
 
     private class ExceptionHolder {
-        var mException: Exception? = null
-
-        fun setException(exception: Exception?) {
-            mException = exception
-        }
+        var exception: Exception? = null
     }
 
     private class AsyncFailRemoteView(packageName: String?, layoutId: Int) :
         RemoteViews(packageName, layoutId) {
-        var mHandler = mockExecutorHandler { p0 -> p0.run() }
 
         override fun apply(context: Context, parent: ViewGroup): View {
             return super.apply(context, parent)
@@ -505,7 +579,7 @@
             listener: OnViewAppliedListener,
             handler: InteractionHandler?
         ): CancellationSignal {
-            mHandler.post { listener.onError(RuntimeException("Failed to inflate async")) }
+            executor.execute { listener.onError(RuntimeException("Failed to inflate async")) }
             return CancellationSignal()
         }
 
@@ -541,18 +615,17 @@
                 object : InflationCallback {
                     override fun handleInflationException(entry: NotificationEntry, e: Exception) {
                         if (!expectingException) {
-                            exceptionHolder.setException(e)
+                            exceptionHolder.exception = e
                         }
                         countDownLatch.countDown()
                     }
 
                     override fun onAsyncInflationFinished(entry: NotificationEntry) {
                         if (expectingException) {
-                            exceptionHolder.setException(
+                            exceptionHolder.exception =
                                 RuntimeException(
                                     "Inflation finished even though there should be an error"
                                 )
-                            )
                         }
                         countDownLatch.countDown()
                     }
@@ -566,7 +639,7 @@
                 callback /* callback */
             )
             Assert.assertTrue(countDownLatch.await(500, TimeUnit.MILLISECONDS))
-            exceptionHolder.mException?.let { throw it }
+            exceptionHolder.exception?.let { throw it }
         }
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index 21d586b..c74a04f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -199,6 +199,8 @@
                                 mock(NotifRemoteViewCache.class),
                                 mock(NotificationRemoteInputManager.class),
                                 mock(ConversationNotificationProcessor.class),
+                                mock(RichOngoingNotificationContentExtractor.class),
+                                mock(RichOngoingNotificationViewInflater.class),
                                 mock(Executor.class),
                                 new MockSmartReplyInflater(),
                                 mock(NotifLayoutInflaterFactory.Provider.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/DisplaySwitchNotificationsHiderTrackerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/DisplaySwitchNotificationsHiderTrackerTest.kt
index 1dfcb38..578950f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/DisplaySwitchNotificationsHiderTrackerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/DisplaySwitchNotificationsHiderTrackerTest.kt
@@ -15,6 +15,7 @@
  */
 package com.android.systemui.statusbar.notification.stack
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.util.LatencyTracker
 import com.android.internal.util.LatencyTracker.ACTION_NOTIFICATIONS_HIDDEN_FOR_MEASURE
@@ -31,12 +32,14 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 
 @SmallTest
 @OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
 class DisplaySwitchNotificationsHiderTrackerTest : SysuiTestCase() {
 
     private val testScope = TestScope()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
index 5c45b2e..3669e3d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
@@ -64,6 +64,10 @@
     @Mock private SectionHeaderController mPeopleHeaderController;
     @Mock private SectionHeaderController mAlertingHeaderController;
     @Mock private SectionHeaderController mSilentHeaderController;
+    @Mock private SectionHeaderController mNewsHeaderController;
+    @Mock private SectionHeaderController mSocialHeaderController;
+    @Mock private SectionHeaderController mRecsHeaderController;
+    @Mock private SectionHeaderController mPromoHeaderController;
 
     private NotificationSectionsManager mSectionsManager;
 
@@ -94,7 +98,11 @@
                         mIncomingHeaderController,
                         mPeopleHeaderController,
                         mAlertingHeaderController,
-                        mSilentHeaderController
+                        mSilentHeaderController,
+                        mNewsHeaderController,
+                        mSocialHeaderController,
+                        mRecsHeaderController,
+                        mPromoHeaderController
                 );
         // Required in order for the header inflation to work properly
         when(mNssl.generateLayoutParams(any(AttributeSet.class)))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
index 48e8f88..c1f2cb77 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
@@ -10,6 +10,8 @@
 import com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerProgress
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ShadeInterpolation
+import com.android.systemui.flags.DisableSceneContainer
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.flags.FakeFeatureFlags
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.res.R
@@ -30,8 +32,8 @@
 import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.mock
-import org.mockito.MockitoAnnotations
 import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
 
 /** Tests for {@link NotificationShelf}. */
 @SmallTest
@@ -332,6 +334,101 @@
     }
 
     @Test
+    fun updateState_lastViewAlmostBelowShelf_completelyInShelf() {
+        val viewStart = 0f
+        val shelfClipStart = 0.001f
+
+        val expandableView = mock(ExpandableView::class.java)
+        whenever(expandableView.shelfIcon).thenReturn(mock(StatusBarIconView::class.java))
+        whenever(expandableView.translationY).thenReturn(viewStart)
+        whenever(expandableView.actualHeight).thenReturn(20)
+
+        whenever(expandableView.minHeight).thenReturn(20)
+        whenever(expandableView.shelfTransformationTarget).thenReturn(null) // use translationY
+        whenever(expandableView.isInShelf).thenReturn(true)
+
+        whenever(ambientState.isOnKeyguard).thenReturn(true)
+        whenever(ambientState.isExpansionChanging).thenReturn(false)
+        whenever(ambientState.isShadeExpanded).thenReturn(true)
+
+        val amountInShelf =
+            shelf.getAmountInShelf(
+                /* i= */ 0,
+                /* view= */ expandableView,
+                /* scrollingFast= */ false,
+                /* expandingAnimated= */ false,
+                /* isLastChild= */ true,
+                shelfClipStart
+            )
+        assertEquals(1f, amountInShelf)
+    }
+
+    @Test
+    @EnableSceneContainer
+    fun updateState_withViewInShelf_showShelf() {
+        // GIVEN a view is scrolled into the shelf
+        val stackTop = 200f
+        val stackHeight = 800f
+        whenever(ambientState.stackTop).thenReturn(stackTop)
+        whenever(ambientState.stackHeight).thenReturn(stackHeight)
+        val shelfTop = stackTop + stackHeight - shelf.height
+        val stackScrollAlgorithmState = StackScrollAlgorithmState()
+        val viewInShelf = mock(ExpandableView::class.java)
+
+        whenever(ambientState.isShadeExpanded).thenReturn(true)
+        whenever(ambientState.lastVisibleBackgroundChild).thenReturn(viewInShelf)
+        whenever(viewInShelf.viewState).thenReturn(ExpandableViewState())
+        whenever(viewInShelf.shelfIcon).thenReturn(mock(StatusBarIconView::class.java))
+        whenever(viewInShelf.translationY).thenReturn(shelfTop)
+        whenever(viewInShelf.actualHeight).thenReturn(10)
+        whenever(viewInShelf.isInShelf).thenReturn(true)
+        whenever(viewInShelf.minHeight).thenReturn(10)
+        whenever(viewInShelf.shelfTransformationTarget).thenReturn(null) // use translationY
+        whenever(viewInShelf.isInShelf).thenReturn(true)
+
+        stackScrollAlgorithmState.visibleChildren.add(viewInShelf)
+        stackScrollAlgorithmState.firstViewInShelf = viewInShelf
+
+        // WHEN Shelf's ViewState is updated
+        shelf.updateState(stackScrollAlgorithmState, ambientState)
+
+        // THEN the shelf is visible, and positioned correctly
+        val shelfState = shelf.viewState as NotificationShelf.ShelfState
+        assertEquals(false, shelfState.hidden)
+        assertEquals(shelf.height, shelfState.height)
+        assertEquals(shelfTop, shelfState.yTranslation)
+    }
+
+    @Test
+    @EnableSceneContainer
+    fun updateState_withNullLastVisibleBackgroundChild_hideShelf_withSceneContainer() {
+        // GIVEN
+        val stackTop = 200f
+        val stackHeight = 800f
+        whenever(ambientState.stackTop).thenReturn(stackTop)
+        whenever(ambientState.stackHeight).thenReturn(stackHeight)
+        val paddingBetweenElements =
+            context.resources.getDimensionPixelSize(R.dimen.notification_divider_height)
+        whenever(ambientState.isShadeExpanded).thenReturn(true)
+        val lastVisibleBackgroundChild = mock<ExpandableView>()
+        val expandableViewState = ExpandableViewState()
+        whenever(lastVisibleBackgroundChild.viewState).thenReturn(expandableViewState)
+        val stackScrollAlgorithmState = StackScrollAlgorithmState()
+        stackScrollAlgorithmState.firstViewInShelf = mock()
+
+        whenever(ambientState.lastVisibleBackgroundChild).thenReturn(null)
+
+        // WHEN
+        shelf.updateState(stackScrollAlgorithmState, ambientState)
+
+        // THEN
+        val shelfState = shelf.viewState as NotificationShelf.ShelfState
+        assertEquals(true, shelfState.hidden)
+        assertEquals(stackTop + stackHeight + paddingBetweenElements, shelfState.yTranslation)
+    }
+
+    @Test
+    @DisableSceneContainer
     fun updateState_withNullLastVisibleBackgroundChild_hideShelf() {
         // GIVEN
         whenever(ambientState.stackY).thenReturn(100f)
@@ -358,6 +455,35 @@
     }
 
     @Test
+    @EnableSceneContainer
+    fun updateState_withNullFirstViewInShelf_hideShelf_withSceneContainer() {
+        // GIVEN
+        val stackTop = 200f
+        val stackHeight = 800f
+        whenever(ambientState.stackTop).thenReturn(stackTop)
+        whenever(ambientState.stackHeight).thenReturn(stackHeight)
+        val paddingBetweenElements =
+            context.resources.getDimensionPixelSize(R.dimen.notification_divider_height)
+        whenever(ambientState.isShadeExpanded).thenReturn(true)
+        val lastVisibleBackgroundChild = mock<ExpandableView>()
+        val expandableViewState = ExpandableViewState()
+        whenever(lastVisibleBackgroundChild.viewState).thenReturn(expandableViewState)
+        whenever(ambientState.lastVisibleBackgroundChild).thenReturn(lastVisibleBackgroundChild)
+        val stackScrollAlgorithmState = StackScrollAlgorithmState()
+
+        stackScrollAlgorithmState.firstViewInShelf = null
+
+        // WHEN
+        shelf.updateState(stackScrollAlgorithmState, ambientState)
+
+        // THEN
+        val shelfState = shelf.viewState as NotificationShelf.ShelfState
+        assertEquals(true, shelfState.hidden)
+        assertEquals(stackTop + stackHeight + paddingBetweenElements, shelfState.yTranslation)
+    }
+
+    @Test
+    @DisableSceneContainer
     fun updateState_withNullFirstViewInShelf_hideShelf() {
         // GIVEN
         whenever(ambientState.stackY).thenReturn(100f)
@@ -384,6 +510,35 @@
     }
 
     @Test
+    @EnableSceneContainer
+    fun updateState_withCollapsedShade_hideShelf_withSceneContainer() {
+        // GIVEN
+        val stackTop = 200f
+        val stackHeight = 800f
+        whenever(ambientState.stackTop).thenReturn(stackTop)
+        whenever(ambientState.stackHeight).thenReturn(stackHeight)
+        val paddingBetweenElements =
+            context.resources.getDimensionPixelSize(R.dimen.notification_divider_height)
+        val lastVisibleBackgroundChild = mock<ExpandableView>()
+        val expandableViewState = ExpandableViewState()
+        whenever(lastVisibleBackgroundChild.viewState).thenReturn(expandableViewState)
+        whenever(ambientState.lastVisibleBackgroundChild).thenReturn(lastVisibleBackgroundChild)
+        val stackScrollAlgorithmState = StackScrollAlgorithmState()
+        stackScrollAlgorithmState.firstViewInShelf = mock()
+
+        whenever(ambientState.isShadeExpanded).thenReturn(false)
+
+        // WHEN
+        shelf.updateState(stackScrollAlgorithmState, ambientState)
+
+        // THEN
+        val shelfState = shelf.viewState as NotificationShelf.ShelfState
+        assertEquals(true, shelfState.hidden)
+        assertEquals(stackTop + stackHeight + paddingBetweenElements, shelfState.yTranslation)
+    }
+
+    @Test
+    @DisableSceneContainer
     fun updateState_withCollapsedShade_hideShelf() {
         // GIVEN
         whenever(ambientState.stackY).thenReturn(100f)
@@ -410,6 +565,49 @@
     }
 
     @Test
+    @EnableSceneContainer
+    fun updateState_withHiddenSectionBeforeShelf_hideShelf_withSceneContainer() {
+        // GIVEN
+        val stackTop = 200f
+        val stackHeight = 800f
+        whenever(ambientState.stackTop).thenReturn(stackTop)
+        whenever(ambientState.stackHeight).thenReturn(stackHeight)
+        val paddingBetweenElements =
+            context.resources.getDimensionPixelSize(R.dimen.notification_divider_height)
+        whenever(ambientState.isShadeExpanded).thenReturn(true)
+        val lastVisibleBackgroundChild = mock<ExpandableView>()
+        val expandableViewState = ExpandableViewState()
+        whenever(lastVisibleBackgroundChild.viewState).thenReturn(expandableViewState)
+        val stackScrollAlgorithmState = StackScrollAlgorithmState()
+        whenever(ambientState.lastVisibleBackgroundChild).thenReturn(lastVisibleBackgroundChild)
+
+        val ssaVisibleChild = mock<ExpandableView>()
+        val ssaVisibleChildState = ExpandableViewState()
+        ssaVisibleChildState.hidden = true
+        whenever(ssaVisibleChild.viewState).thenReturn(ssaVisibleChildState)
+
+        val ssaVisibleChild1 = mock<ExpandableView>()
+        val ssaVisibleChildState1 = ExpandableViewState()
+        ssaVisibleChildState1.hidden = true
+        whenever(ssaVisibleChild1.viewState).thenReturn(ssaVisibleChildState1)
+
+        stackScrollAlgorithmState.visibleChildren.add(ssaVisibleChild)
+        stackScrollAlgorithmState.visibleChildren.add(ssaVisibleChild1)
+        whenever(ambientState.isExpansionChanging).thenReturn(true)
+        whenever(ambientState.expansionFraction).thenReturn(1f)
+        stackScrollAlgorithmState.firstViewInShelf = ssaVisibleChild1
+
+        // WHEN
+        shelf.updateState(stackScrollAlgorithmState, ambientState)
+
+        // THEN
+        val shelfState = shelf.viewState as NotificationShelf.ShelfState
+        assertEquals(true, shelfState.hidden)
+        assertEquals(stackTop + stackHeight + paddingBetweenElements, shelfState.yTranslation)
+    }
+
+    @Test
+    @DisableSceneContainer
     fun updateState_withHiddenSectionBeforeShelf_hideShelf() {
         // GIVEN
         whenever(ambientState.stackY).thenReturn(100f)
@@ -461,12 +659,9 @@
         expectedAlpha: Float
     ) {
         val sbnMock: StatusBarNotification = mock()
-        val mockEntry = mock<NotificationEntry>().apply {
-            whenever(this.sbn).thenReturn(sbnMock)
-        }
+        val mockEntry = mock<NotificationEntry>().apply { whenever(this.sbn).thenReturn(sbnMock) }
         val row = ExpandableNotificationRow(mContext, null, mockEntry)
-        whenever(ambientState.lastVisibleBackgroundChild)
-            .thenReturn(row)
+        whenever(ambientState.lastVisibleBackgroundChild).thenReturn(row)
         whenever(ambientState.isExpansionChanging).thenReturn(true)
         whenever(ambientState.expansionFraction).thenReturn(expansionFraction)
         whenever(hostLayoutController.speedBumpIndex).thenReturn(0)
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 ce2491b..1060b62 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
@@ -53,6 +53,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.nano.MetricsProto;
+import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.ExpandHelper;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;
@@ -99,6 +100,7 @@
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController.NotificationPanelEvent;
 import com.android.systemui.statusbar.notification.stack.NotificationSwipeHelper.NotificationCallback;
 import com.android.systemui.statusbar.notification.stack.ui.viewbinder.NotificationListViewBinder;
+import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -135,6 +137,8 @@
     @Mock private NotificationVisibilityProvider mVisibilityProvider;
     @Mock private NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
     @Mock private HeadsUpManager mHeadsUpManager;
+    @Mock private HeadsUpTouchHelper.Callback mHeadsUpCallback;
+    @Mock private Provider<IStatusBarService> mStatusBarService;
     @Mock private NotificationRoundnessManager mNotificationRoundnessManager;
     @Mock private TunerService mTunerService;
     @Mock private DeviceProvisionedController mDeviceProvisionedController;
@@ -973,6 +977,8 @@
         when(mNotificationStackScrollLayout.getViewTreeObserver())
                 .thenReturn(viewTreeObserver);
         when(mNotificationStackScrollLayout.getContext()).thenReturn(getContext());
+        when(mNotificationStackScrollLayout.getHeadsUpCallback()).thenReturn(mHeadsUpCallback);
+        when(mHeadsUpCallback.getContext()).thenReturn(getContext());
         mController = new NotificationStackScrollLayoutController(
                 mNotificationStackScrollLayout,
                 true,
@@ -981,6 +987,7 @@
                 mVisibilityProvider,
                 mNotificationWakeUpCoordinator,
                 mHeadsUpManager,
+                mStatusBarService,
                 mNotificationRoundnessManager,
                 mTunerService,
                 mDeviceProvisionedController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 12f3ef3..a925ccf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -49,6 +49,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.annotation.DimenRes;
 import android.graphics.Insets;
 import android.graphics.Rect;
 import android.os.SystemClock;
@@ -138,7 +139,7 @@
     @Mock private NotificationStackScrollLayoutController mStackScrollLayoutController;
     @Mock private ScreenOffAnimationController mScreenOffAnimationController;
     @Mock private NotificationShelf mNotificationShelf;
-    @Mock private NotificationStackSizeCalculator mNotificationStackSizeCalculator;
+    @Mock private NotificationStackSizeCalculator mStackSizeCalculator;
     @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     @Mock private LargeScreenShadeInterpolator mLargeScreenShadeInterpolator;
     @Mock private AvalancheController mAvalancheController;
@@ -197,7 +198,7 @@
         // refer to the CUT's member variables, not the spy's member variables.
         mStackScrollerInternal = new NotificationStackScrollLayout(getContext(), null);
         mStackScrollerInternal.initView(getContext(), mNotificationSwipeHelper,
-                mNotificationStackSizeCalculator);
+                mStackSizeCalculator);
         mStackScroller = spy(mStackScrollerInternal);
         mStackScroller.setResetUserExpandedStatesRunnable(() -> {});
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
@@ -214,6 +215,7 @@
     }
 
     @Test
+    @DisableSceneContainer // TODO(b/332574413) cover stack bounds integration with tests
     public void testUpdateStackHeight_qsExpansionGreaterThanZero() {
         final float expansionFraction = 0.2f;
         final float overExpansion = 50f;
@@ -232,6 +234,32 @@
     }
 
     @Test
+    @EnableSceneContainer
+    public void testIntrinsicStackHeight() {
+        int stackHeight = 300;
+        when(mStackSizeCalculator.computeHeight(eq(mStackScroller), anyInt(), anyFloat()))
+                .thenReturn((float) stackHeight);
+
+        mStackScroller.updateContentHeight();
+
+        assertThat(mStackScroller.getIntrinsicStackHeight()).isEqualTo(stackHeight);
+    }
+
+    @Test
+    @DisableSceneContainer
+    public void testIntrinsicStackHeight_includesTopScrimPadding() {
+        int stackHeight = 300;
+        int topScrimPadding = px(R.dimen.notification_side_paddings);
+        when(mStackSizeCalculator.computeHeight(eq(mStackScroller), anyInt(), anyFloat()))
+                .thenReturn((float) stackHeight);
+
+        mStackScroller.updateContentHeight();
+
+        assertThat(mStackScroller.getIntrinsicStackHeight())
+                .isEqualTo(stackHeight + topScrimPadding);
+    }
+
+    @Test
     @DisableSceneContainer // TODO(b/312473478): address disabled test
     public void testUpdateStackHeight_qsExpansionZero() {
         final float expansionFraction = 0.2f;
@@ -261,15 +289,62 @@
     }
 
     @Test
-    public void updateStackEndHeightAndStackHeight_normallyUpdatesBoth() {
-        final float expansionFraction = 0.5f;
+    @EnableSceneContainer
+    public void updateStackEndHeightAndStackHeight_shadeFullyExpanded_withSceneContainer() {
+        final float stackTop = 200f;
+        final float stackCutoff = 1000f;
+        final float stackEndHeight = stackCutoff - stackTop;
+        mAmbientState.setStackTop(stackTop);
+        mAmbientState.setStackCutoff(stackCutoff);
         mAmbientState.setStatusBarState(StatusBarState.KEYGUARD);
-
-        // Validate that by default we update everything
         clearInvocations(mAmbientState);
+
+        // WHEN shade is fully expanded
+        mStackScroller.updateStackEndHeightAndStackHeight(/* fraction = */ 1.0f);
+
+        // THEN stackHeight and stackEndHeight are the same
+        verify(mAmbientState).setStackEndHeight(stackEndHeight);
+        verify(mAmbientState).setStackHeight(stackEndHeight);
+    }
+
+    @Test
+    @EnableSceneContainer
+    public void updateStackEndHeightAndStackHeight_shadeExpanding_withSceneContainer() {
+        final float stackTop = 200f;
+        final float stackCutoff = 1000f;
+        final float stackEndHeight = stackCutoff - stackTop;
+        mAmbientState.setStackTop(stackTop);
+        mAmbientState.setStackCutoff(stackCutoff);
+        mAmbientState.setStatusBarState(StatusBarState.KEYGUARD);
+        clearInvocations(mAmbientState);
+
+        // WHEN shade is expanding
+        final float expansionFraction = 0.5f;
         mStackScroller.updateStackEndHeightAndStackHeight(expansionFraction);
-        verify(mAmbientState).setStackEndHeight(anyFloat());
-        verify(mAmbientState).setStackHeight(anyFloat());
+
+        // THEN stackHeight is changed by the expansion frac
+        verify(mAmbientState).setStackEndHeight(stackEndHeight);
+        verify(mAmbientState).setStackHeight(stackEndHeight * 0.75f);
+    }
+
+    @Test
+    @EnableSceneContainer
+    public void updateStackEndHeightAndStackHeight_shadeOverscrolledToTop_withSceneContainer() {
+        // GIVEN stack scrolled over the top, stack top is negative
+        final float stackTop = -2000f;
+        final float stackCutoff = 1000f;
+        final float stackEndHeight = stackCutoff - stackTop;
+        mAmbientState.setStackTop(stackTop);
+        mAmbientState.setStackCutoff(stackCutoff);
+        mAmbientState.setStatusBarState(StatusBarState.KEYGUARD);
+        clearInvocations(mAmbientState);
+
+        // WHEN stack is updated
+        mStackScroller.updateStackEndHeightAndStackHeight(/* fraction = */ 1.0f);
+
+        // THEN stackHeight is measured from the stack top
+        verify(mAmbientState).setStackEndHeight(stackEndHeight);
+        verify(mAmbientState).setStackHeight(stackEndHeight);
     }
 
     @Test
@@ -771,7 +846,7 @@
     @DisableSceneContainer // TODO(b/312473478): address disabled test
     public void setFractionToShade_recomputesStackHeight() {
         mStackScroller.setFractionToShade(1f);
-        verify(mNotificationStackSizeCalculator).computeHeight(any(), anyInt(), anyFloat());
+        verify(mStackSizeCalculator).computeHeight(any(), anyInt(), anyFloat());
     }
 
     @Test
@@ -891,6 +966,7 @@
     }
 
     @Test
+    @DisableSceneContainer // NSSL has no more scroll logic when SceneContainer is on
     public void testNormalShade_hasNoTopOverscroll() {
         mTestableResources
                 .addOverride(R.bool.config_use_split_notification_shade, /* value= */ false);
@@ -1182,6 +1258,10 @@
         assertEquals(expected, mAmbientState.isClearAllInProgress());
     }
 
+    private int px(@DimenRes int id) {
+        return mTestableResources.getResources().getDimensionPixelSize(id);
+    }
+
     private static void mockBoundsOnScreen(View view, Rect bounds) {
         doAnswer(invocation -> {
             Rect out = invocation.getArgument(0);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
index a6fb718..c2a7b52 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
@@ -5,11 +5,15 @@
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
 import android.widget.FrameLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerProgress
+import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.ShadeInterpolation.getContentAlpha
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.flags.DisableSceneContainer
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.FeatureFlagsClassic
 import com.android.systemui.res.R
@@ -37,6 +41,7 @@
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mockito.any
 import org.mockito.Mockito.eq
 import org.mockito.Mockito.mock
@@ -44,6 +49,7 @@
 import org.mockito.Mockito.`when` as whenever
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class StackScrollAlgorithmTest : SysuiTestCase() {
 
     @JvmField @Rule var expect: Expect = Expect.create()
@@ -63,7 +69,7 @@
         EmptyShadeView(context, /* attrs= */ null).apply {
             layout(/* l= */ 0, /* t= */ 0, /* r= */ 100, /* b= */ 100)
         }
-    private val footerView = FooterView(context, /*attrs=*/ null)
+    private val footerView = FooterView(context, /* attrs= */ null)
     @OptIn(ExperimentalCoroutinesApi::class)
     private val ambientState =
         AmbientState(
@@ -109,6 +115,17 @@
     }
 
     @Test
+    @EnableSceneContainer
+    fun resetViewStates_childPositionedAtStackTop() {
+        val stackTop = 100f
+        ambientState.stackTop = stackTop
+
+        stackScrollAlgorithm.resetViewStates(ambientState, 0)
+
+        assertThat(notificationRow.viewState.yTranslation).isEqualTo(stackTop)
+    }
+
+    @Test
     fun resetViewStates_defaultHun_yTranslationIsInset() {
         whenever(notificationRow.isPinned).thenReturn(true)
         whenever(notificationRow.isHeadsUp).thenReturn(true)
@@ -123,6 +140,7 @@
     }
 
     @Test
+    @DisableSceneContainer // TODO(b/332574413) cover hun bounds integration with tests
     fun resetViewStates_defaultHunWhenShadeIsOpening_yTranslationIsInset() {
         whenever(notificationRow.isPinned).thenReturn(true)
         whenever(notificationRow.isHeadsUp).thenReturn(true)
@@ -165,6 +183,7 @@
     }
 
     @Test
+    @DisableSceneContainer // TODO(b/332574413) cover hun bounds integration with tests
     @EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
     fun resetViewStates_defaultHun_showingQS_newHeadsUpAnim_hunTranslatedToMax() {
         // Given: the shade is open and scrolled to the bottom to show the QuickSettings
@@ -181,6 +200,7 @@
     }
 
     @Test
+    @DisableSceneContainer // TODO(b/332574413) cover hun bounds integration with tests
     @EnableFlags(NotificationsImprovedHunAnimation.FLAG_NAME)
     fun resetViewStates_hunAnimatingAway_showingQS_newHeadsUpAnim_hunTranslatedToBottomOfScreen() {
         // Given: the shade is open and scrolled to the bottom to show the QuickSettings
@@ -269,6 +289,27 @@
     }
 
     @Test
+    @EnableSceneContainer
+    fun resetViewStates_emptyShadeView_isCenteredVertically_withSceneContainer() {
+        stackScrollAlgorithm.initView(context)
+        hostView.removeAllViews()
+        hostView.addView(emptyShadeView)
+        ambientState.layoutMaxHeight = maxPanelHeight.toInt()
+
+        val stackTop = 200f
+        val stackBottom = 2000f
+        val stackHeight = stackBottom - stackTop
+        ambientState.stackTop = stackTop
+        ambientState.stackCutoff = stackBottom
+
+        stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+        val centeredY = stackTop + stackHeight / 2f - emptyShadeView.height / 2f
+        assertThat(emptyShadeView.viewState.yTranslation).isEqualTo(centeredY)
+    }
+
+    @Test
+    @DisableSceneContainer
     fun resetViewStates_emptyShadeView_isCenteredVertically() {
         stackScrollAlgorithm.initView(context)
         hostView.removeAllViews()
@@ -520,6 +561,7 @@
         assertThat((footerView.viewState as FooterViewState).hideContent).isTrue()
     }
 
+    @DisableFlags(Flags.FLAG_NOTIFICATIONS_FOOTER_VIEW_REFACTOR)
     @Test
     fun resetViewStates_clearAllInProgress_allRowsRemoved_emptyShade_footerHidden() {
         ambientState.isClearAllInProgress = true
@@ -1154,6 +1196,7 @@
 
         assertFalse(stackScrollAlgorithm.shouldHunAppearFromBottom(ambientState, viewState))
     }
+
     // endregion
 
     private fun createHunViewMock(
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 f0bc655..665544d 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
@@ -61,7 +61,7 @@
 import com.android.systemui.qs.external.CustomTile;
 import com.android.systemui.res.R;
 import com.android.systemui.statusbar.policy.CastController;
-import com.android.systemui.statusbar.policy.CastController.CastDevice;
+import com.android.systemui.statusbar.policy.CastDevice;
 import com.android.systemui.statusbar.policy.DataSaverController;
 import com.android.systemui.statusbar.policy.DeviceControlsController;
 import com.android.systemui.statusbar.policy.HotspotController;
@@ -422,9 +422,17 @@
     }
 
     private static List<CastDevice> buildFakeCastDevice(boolean isCasting) {
-        CastDevice cd = new CastDevice();
-        cd.state = isCasting ? CastDevice.STATE_CONNECTED : CastDevice.STATE_DISCONNECTED;
-        return Collections.singletonList(cd);
+        CastDevice.CastState state = isCasting
+                ? CastDevice.CastState.Connected
+                : CastDevice.CastState.Disconnected;
+        return Collections.singletonList(
+                new CastDevice(
+                        "id",
+                        /* name= */ null,
+                        /* description= */ null,
+                        /* state= */ state,
+                        /* origin= */ CastDevice.CastOrigin.MediaProjection,
+                        /* tag= */ null));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
index 285949a..9eafcdb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
@@ -495,18 +495,18 @@
     }
 
     @Test
-    public void biometricUnlockStateResetOnTransitionFromGone() {
-        mBiometricUnlockController.consumeTransitionStepOnStartedKeyguardState(
+    public void biometricUnlockStateResetOnStartedTransition() {
+        mBiometricUnlockController.consumeFromGoneTransitions(
                 new TransitionStep(
-                        KeyguardState.AOD,
                         KeyguardState.GONE,
+                        KeyguardState.AOD,
                         .1f /* value */,
-                        TransitionState.STARTED
+                        TransitionState.RUNNING
                 )
         );
         verify(mBiometricUnlockInteractor, never()).setBiometricUnlockState(anyInt(), any());
 
-        mBiometricUnlockController.consumeTransitionStepOnStartedKeyguardState(
+        mBiometricUnlockController.consumeFromGoneTransitions(
                 new TransitionStep(
                         KeyguardState.GONE,
                         KeyguardState.AOD,
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 1eb33ce..d2540a6 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
@@ -53,6 +53,7 @@
 
 import android.app.ActivityManager;
 import android.app.IWallpaperManager;
+import android.app.NotificationManager;
 import android.app.WallpaperManager;
 import android.app.trust.TrustManager;
 import android.content.BroadcastReceiver;
@@ -339,6 +340,7 @@
     @Mock private KeyboardShortcuts mKeyboardShortcuts;
     @Mock private KeyboardShortcutListSearch mKeyboardShortcutListSearch;
     @Mock private PackageManager mPackageManager;
+    @Mock private NotificationManager mNotificationManager;
     @Mock private GlanceableHubContainerController mGlanceableHubContainerController;
     @Mock private EmergencyGestureIntentFactory mEmergencyGestureIntentFactory;
 
@@ -399,7 +401,9 @@
                         mAvalancheProvider,
                         mSystemSettings,
                         mPackageManager,
-                        Optional.of(mBubbles));
+                        Optional.of(mBubbles),
+                        mContext,
+                        mNotificationManager);
         mVisualInterruptionDecisionProvider.start();
 
         mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
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 53e643e..68e17c1 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
@@ -52,28 +52,17 @@
 import com.android.keyguard.CarrierTextController;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.keyguard.TestScopeProvider;
 import com.android.keyguard.logging.KeyguardLogger;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.battery.BatteryMeterViewController;
-import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository;
-import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository;
-import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor;
 import com.android.systemui.flags.DisableSceneContainer;
 import com.android.systemui.flags.EnableSceneContainer;
-import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
 import com.android.systemui.kosmos.KosmosJavaAdapter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.power.domain.interactor.PowerInteractorFactory;
 import com.android.systemui.res.R;
 import com.android.systemui.shade.ShadeViewStateProvider;
-import com.android.systemui.shade.data.repository.FakeShadeRepository;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
-import com.android.systemui.statusbar.data.repository.FakeKeyguardStatusBarRepository;
-import com.android.systemui.statusbar.domain.interactor.KeyguardStatusBarInteractor;
 import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
 import com.android.systemui.statusbar.phone.ui.StatusBarIconController;
 import com.android.systemui.statusbar.phone.ui.TintedIconManager;
@@ -82,14 +71,11 @@
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.UserInfoController;
-import com.android.systemui.statusbar.ui.viewmodel.KeyguardStatusBarViewModel;
 import com.android.systemui.user.ui.viewmodel.StatusBarUserChipViewModel;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.settings.SecureSettings;
 import com.android.systemui.util.time.FakeSystemClock;
 
-import kotlinx.coroutines.test.TestScope;
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -150,11 +136,7 @@
     private KeyguardStatusBarViewController mController;
     private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
     private final FakeExecutor mBackgroundExecutor = new FakeExecutor(new FakeSystemClock());
-    private final TestScope mTestScope = TestScopeProvider.getTestScope();
-    private final FakeKeyguardRepository mKeyguardRepository = new FakeKeyguardRepository();
     private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
-    private KeyguardInteractor mKeyguardInteractor;
-    private KeyguardStatusBarViewModel mViewModel;
 
     @Before
     public void setup() throws Exception {
@@ -163,28 +145,6 @@
         MockitoAnnotations.initMocks(this);
 
         when(mIconManagerFactory.create(any(), any())).thenReturn(mIconManager);
-        KeyguardTransitionInteractor keyguardTransitionInteractor =
-                mKosmos.getKeyguardTransitionInteractor();
-        mKeyguardInteractor = new KeyguardInteractor(
-                mKeyguardRepository,
-                mCommandQueue,
-                PowerInteractorFactory.create().getPowerInteractor(),
-                new FakeKeyguardBouncerRepository(),
-                new ConfigurationInteractor(new FakeConfigurationRepository()),
-                new FakeShadeRepository(),
-                keyguardTransitionInteractor,
-                () -> mKosmos.getSceneInteractor(),
-                () -> mKosmos.getFromGoneTransitionInteractor(),
-                () -> mKosmos.getFromLockscreenTransitionInteractor(),
-                () -> mKosmos.getSharedNotificationContainerInteractor(),
-                mTestScope);
-        mViewModel =
-                new KeyguardStatusBarViewModel(
-                        mTestScope.getBackgroundScope(),
-                        mKosmos.getHeadsUpNotificationInteractor(),
-                        mKeyguardInteractor,
-                        new KeyguardStatusBarInteractor(new FakeKeyguardStatusBarRepository()),
-                        mBatteryController);
 
         allowTestableLooperAsMainThread();
         TestableLooper.get(this).runWithLooper(() -> {
@@ -212,7 +172,7 @@
                 mKeyguardStateController,
                 mKeyguardBypassController,
                 mKeyguardUpdateMonitor,
-                mViewModel,
+                mKosmos.getKeyguardStatusBarViewModel(),
                 mBiometricUnlockController,
                 mStatusBarStateController,
                 mStatusBarContentInsetsProvider,
@@ -356,6 +316,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void setBatteryListening_true_callbackAdded() {
         mController.setBatteryListening(true);
 
@@ -363,6 +324,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void setBatteryListening_false_callbackRemoved() {
         // First set to true so that we know setting to false is a change in state.
         mController.setBatteryListening(true);
@@ -373,6 +335,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void setBatteryListening_trueThenTrue_callbackAddedOnce() {
         mController.setBatteryListening(true);
         mController.setBatteryListening(true);
@@ -412,6 +375,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void updateViewState_alphaAndVisibilityGiven_viewUpdated() {
         // Verify the initial values so we know the method triggers changes.
         assertThat(mKeyguardStatusBarView.getAlpha()).isEqualTo(1f);
@@ -426,6 +390,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void updateViewState_paramVisibleButIsDisabled_viewIsInvisible() {
         mController.onViewAttached();
         setDisableSystemIcons(true);
@@ -437,6 +402,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void updateViewState_notKeyguardState_nothingUpdated() {
         mController.onViewAttached();
         updateStateToNotKeyguard();
@@ -449,6 +415,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void updateViewState_bypassEnabledAndShouldListenForFace_viewHidden() {
         mController.onViewAttached();
         updateStateToKeyguard();
@@ -464,6 +431,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void updateViewState_bypassNotEnabled_viewShown() {
         mController.onViewAttached();
         updateStateToKeyguard();
@@ -478,6 +446,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void updateViewState_shouldNotListenForFace_viewShown() {
         mController.onViewAttached();
         updateStateToKeyguard();
@@ -492,6 +461,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void updateViewState_panelExpandedHeightZero_viewHidden() {
         mController.onViewAttached();
         updateStateToKeyguard();
@@ -504,6 +474,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void updateViewState_dragProgressOne_viewHidden() {
         mController.onViewAttached();
         updateStateToKeyguard();
@@ -516,6 +487,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void updateViewState_disableSystemInfoFalse_viewShown() {
         mController.onViewAttached();
         updateStateToKeyguard();
@@ -527,6 +499,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void updateViewState_disableSystemInfoTrue_viewHidden() {
         mController.onViewAttached();
         updateStateToKeyguard();
@@ -538,6 +511,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void updateViewState_disableSystemIconsFalse_viewShown() {
         mController.onViewAttached();
         updateStateToKeyguard();
@@ -549,6 +523,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void updateViewState_disableSystemIconsTrue_viewHidden() {
         mController.onViewAttached();
         updateStateToKeyguard();
@@ -648,6 +623,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void setAlpha_explicitAlpha_setsExplicitAlpha() {
         mController.onViewAttached();
         updateStateToKeyguard();
@@ -658,6 +634,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void setAlpha_explicitAlpha_thenMinusOneAlpha_setsAlphaBasedOnDefaultCriteria() {
         mController.onViewAttached();
         updateStateToKeyguard();
@@ -672,6 +649,7 @@
     // TODO(b/195442899): Add more tests for #updateViewState once CLs are finalized.
 
     @Test
+    @DisableSceneContainer
     public void updateForHeadsUp_headsUpShouldBeVisible_viewHidden() {
         mController.onViewAttached();
         updateStateToKeyguard();
@@ -684,6 +662,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void updateForHeadsUp_headsUpShouldNotBeVisible_viewShown() {
         mController.onViewAttached();
         updateStateToKeyguard();
@@ -773,6 +752,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void animateKeyguardStatusBarIn_isDisabled_viewStillHidden() {
         mController.onViewAttached();
         updateStateToKeyguard();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
index a27073c..88ec18d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java
@@ -18,7 +18,7 @@
 
 import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
 
-import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
+import static com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
 
 import static junit.framework.Assert.assertTrue;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImplTest.kt
index c44c178..2f81027 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ManagedProfileControllerImplTest.kt
@@ -18,6 +18,7 @@
 
 import android.content.pm.UserInfo
 import android.os.UserManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.settings.UserTracker
@@ -29,12 +30,14 @@
 import junit.framework.Assert
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class ManagedProfileControllerImplTest : SysuiTestCase() {
 
     private val mainExecutor: FakeExecutor = FakeExecutor(FakeSystemClock())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt
index f2f336c..dfee2ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt
@@ -21,11 +21,14 @@
 import android.app.admin.DevicePolicyResourcesManager
 import android.content.SharedPreferences
 import android.os.UserManager
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
 import android.telecom.TelecomManager
 import android.testing.TestableLooper
 import android.testing.TestableLooper.RunWithLooper
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor
@@ -39,6 +42,7 @@
 import com.android.systemui.statusbar.phone.ui.StatusBarIconController
 import com.android.systemui.statusbar.policy.BluetoothController
 import com.android.systemui.statusbar.policy.CastController
+import com.android.systemui.statusbar.policy.CastDevice
 import com.android.systemui.statusbar.policy.DataSaverController
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
 import com.android.systemui.statusbar.policy.HotspotController
@@ -54,6 +58,7 @@
 import com.android.systemui.util.kotlin.JavaAdapter
 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.time.DateFormatUtil
 import com.android.systemui.util.time.FakeSystemClock
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -78,6 +83,7 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.argumentCaptor
 
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper
@@ -87,6 +93,8 @@
 
     companion object {
         private const val ALARM_SLOT = "alarm"
+        private const val CAST_SLOT = "cast"
+        private const val SCREEN_RECORD_SLOT = "screen_record"
         private const val CONNECTED_DISPLAY_SLOT = "connected_display"
         private const val MANAGED_PROFILE_SLOT = "managed_profile"
     }
@@ -271,6 +279,101 @@
             verify(iconController).setIconVisibility(CONNECTED_DISPLAY_SLOT, true)
         }
 
+    @Test
+    @DisableFlags(Flags.FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
+    fun cast_chipsFlagOff_iconShown() {
+        statusBarPolicy.init()
+        clearInvocations(iconController)
+
+        val callbackCaptor = argumentCaptor<CastController.Callback>()
+        verify(castController).addCallback(callbackCaptor.capture())
+
+        whenever(castController.castDevices)
+            .thenReturn(
+                listOf(
+                    CastDevice(
+                        "id",
+                        "name",
+                        "description",
+                        CastDevice.CastState.Connected,
+                        CastDevice.CastOrigin.MediaProjection,
+                    )
+                )
+            )
+        callbackCaptor.firstValue.onCastDevicesChanged()
+
+        verify(iconController).setIconVisibility(CAST_SLOT, true)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
+    fun cast_chipsFlagOn_noCallbackRegistered() {
+        statusBarPolicy.init()
+
+        verify(castController, never()).addCallback(any())
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
+    fun screenRecord_chipsFlagOff_iconShown_forAllStates() {
+        statusBarPolicy.init()
+        clearInvocations(iconController)
+
+        val callbackCaptor = argumentCaptor<RecordingController.RecordingStateChangeCallback>()
+        verify(recordingController).addCallback(callbackCaptor.capture())
+
+        callbackCaptor.firstValue.onCountdown(3000)
+        testableLooper.processAllMessages()
+        verify(iconController).setIconVisibility(SCREEN_RECORD_SLOT, true)
+        clearInvocations(iconController)
+
+        callbackCaptor.firstValue.onCountdownEnd()
+        testableLooper.processAllMessages()
+        verify(iconController).setIconVisibility(SCREEN_RECORD_SLOT, false)
+        clearInvocations(iconController)
+
+        callbackCaptor.firstValue.onRecordingStart()
+        testableLooper.processAllMessages()
+        verify(iconController).setIconVisibility(SCREEN_RECORD_SLOT, true)
+        clearInvocations(iconController)
+
+        callbackCaptor.firstValue.onRecordingEnd()
+        testableLooper.processAllMessages()
+        verify(iconController).setIconVisibility(SCREEN_RECORD_SLOT, false)
+        clearInvocations(iconController)
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
+    fun screenRecord_chipsFlagOn_noCallbackRegistered() {
+        statusBarPolicy.init()
+
+        verify(recordingController, never()).addCallback(any())
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS)
+    fun screenRecord_chipsFlagOn_methodsDoNothing() {
+        statusBarPolicy.init()
+        clearInvocations(iconController)
+
+        statusBarPolicy.onCountdown(3000)
+        testableLooper.processAllMessages()
+        verify(iconController, never()).setIconVisibility(eq(SCREEN_RECORD_SLOT), any())
+
+        statusBarPolicy.onCountdownEnd()
+        testableLooper.processAllMessages()
+        verify(iconController, never()).setIconVisibility(eq(SCREEN_RECORD_SLOT), any())
+
+        statusBarPolicy.onRecordingStart()
+        testableLooper.processAllMessages()
+        verify(iconController, never()).setIconVisibility(eq(SCREEN_RECORD_SLOT), any())
+
+        statusBarPolicy.onRecordingEnd()
+        testableLooper.processAllMessages()
+        verify(iconController, never()).setIconVisibility(eq(SCREEN_RECORD_SLOT), any())
+    }
+
     private fun createAlarmInfo(): AlarmManager.AlarmClockInfo {
         return AlarmManager.AlarmClockInfo(10L, null)
     }
@@ -315,13 +418,18 @@
 
     private class FakeConnectedDisplayStateProvider : ConnectedDisplayInteractor {
         private val flow = MutableSharedFlow<State>()
+
         suspend fun emit(value: State) = flow.emit(value)
+
         override val connectedDisplayState: Flow<State>
             get() = flow
+
         override val connectedDisplayAddition: Flow<Unit>
             get() = TODO("Not yet implemented")
+
         override val pendingDisplay: Flow<PendingDisplay?>
             get() = TODO("Not yet implemented")
+
         override val concurrentDisplaysInProgress: Flow<Boolean>
             get() = TODO("Not yet implemented")
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitionsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitionsTest.kt
index c4568a9..318656b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitionsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarTransitionsTest.kt
@@ -21,12 +21,12 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSLUCENT
-import com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_OPAQUE
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_TRANSLUCENT
+import com.android.systemui.shared.statusbar.phone.BarTransitions.MODE_TRANSPARENT
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
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 ba38f87..25314f3 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
@@ -27,6 +27,7 @@
 import android.view.ViewTreeObserver
 import android.view.ViewTreeObserver.OnPreDrawListener
 import android.widget.FrameLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.systemui.SysuiTestCase
@@ -54,6 +55,7 @@
 import javax.inject.Provider
 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
@@ -64,6 +66,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class PhoneStatusBarViewControllerTest : SysuiTestCase() {
 
     @Mock private lateinit var shadeViewController: ShadeViewController
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 4590071..73e3bf4 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
@@ -49,6 +49,8 @@
 import android.content.res.ColorStateList;
 import android.content.res.TypedArray;
 import android.graphics.Color;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
 import android.testing.TestableLooper;
 import android.testing.ViewUtils;
 import android.util.MathUtils;
@@ -65,6 +67,7 @@
 import com.android.systemui.animation.ShadeInterpolation;
 import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants;
 import com.android.systemui.dock.DockManager;
+import com.android.systemui.flags.EnableSceneContainer;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository;
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
@@ -75,7 +78,9 @@
 import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerToGoneTransitionViewModel;
 import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel;
 import com.android.systemui.kosmos.KosmosJavaAdapter;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.scrim.ScrimView;
+import com.android.systemui.shade.shared.flag.DualShade;
 import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
 import com.android.systemui.shade.transition.LinearLargeScreenShadeInterpolator;
 import com.android.systemui.statusbar.policy.FakeConfigurationController;
@@ -309,7 +314,11 @@
         mWallpaperRepository.getWallpaperSupportsAmbientMode().setValue(false);
         mTestScope.getTestScheduler().runCurrent();
 
-        mScrimController.legacyTransitionTo(ScrimState.KEYGUARD);
+        if (SceneContainerFlag.isEnabled()) {
+            mScrimController.transitionTo(ScrimState.KEYGUARD);
+        } else {
+            mScrimController.legacyTransitionTo(ScrimState.KEYGUARD);
+        }
         finishAnimationsImmediately();
     }
 
@@ -358,6 +367,47 @@
     }
 
     @Test
+    @EnableSceneContainer
+    @DisableFlags(DualShade.FLAG_NAME)
+    public void transitionToShadeLocked_sceneContainer_dualShadeOff() {
+        mScrimController.transitionTo(SHADE_LOCKED);
+        mScrimController.setQsPosition(1f, 0);
+        finishAnimationsImmediately();
+
+        assertScrimAlpha(Map.of(
+                mNotificationsScrim, OPAQUE,
+                mScrimInFront, TRANSPARENT,
+                mScrimBehind, OPAQUE
+        ));
+
+        assertScrimTinted(Map.of(
+                mScrimInFront, false,
+                mScrimBehind, true
+        ));
+    }
+
+    @Test
+    @EnableSceneContainer
+    @EnableFlags(DualShade.FLAG_NAME)
+    public void transitionToShadeLocked_sceneContainer_dualShadeOn() {
+        mScrimController.transitionTo(SHADE_LOCKED);
+        mScrimController.setQsPosition(1f, 0);
+        finishAnimationsImmediately();
+
+        assertScrimAlpha(Map.of(
+                mNotificationsScrim, TRANSPARENT,
+                mScrimInFront, TRANSPARENT,
+                mScrimBehind, TRANSPARENT
+        ));
+
+        assertScrimTinted(Map.of(
+                mScrimInFront, false,
+                mNotificationsScrim, false,
+                mScrimBehind, false
+        ));
+    }
+
+    @Test
     public void transitionToShadeLocked_clippingQs() {
         mScrimController.setClipsQsScrim(true);
         mScrimController.legacyTransitionTo(SHADE_LOCKED);
@@ -997,6 +1047,64 @@
     }
 
     @Test
+    @EnableSceneContainer
+    @DisableFlags(DualShade.FLAG_NAME)
+    public void transitionToUnlocked_sceneContainer_dualShadeOff() {
+        mScrimController.setRawPanelExpansionFraction(0f);
+        mScrimController.transitionTo(ScrimState.UNLOCKED);
+        finishAnimationsImmediately();
+
+        assertScrimAlpha(Map.of(
+                mScrimInFront, TRANSPARENT,
+                mNotificationsScrim, TRANSPARENT,
+                mScrimBehind, TRANSPARENT
+        ));
+
+        mScrimController.setRawPanelExpansionFraction(0.5f);
+        assertScrimAlpha(Map.of(
+                mScrimInFront, TRANSPARENT,
+                mNotificationsScrim, SEMI_TRANSPARENT,
+                mScrimBehind, SEMI_TRANSPARENT
+        ));
+
+        mScrimController.setRawPanelExpansionFraction(1f);
+        assertScrimAlpha(Map.of(
+                mScrimInFront, TRANSPARENT,
+                mNotificationsScrim, OPAQUE,
+                mScrimBehind, OPAQUE
+        ));
+    }
+
+    @Test
+    @EnableSceneContainer
+    @EnableFlags(DualShade.FLAG_NAME)
+    public void transitionToUnlocked_sceneContainer_dualShadeOn() {
+        mScrimController.setRawPanelExpansionFraction(0f);
+        mScrimController.transitionTo(ScrimState.UNLOCKED);
+        finishAnimationsImmediately();
+
+        assertScrimAlpha(Map.of(
+                mScrimInFront, TRANSPARENT,
+                mNotificationsScrim, TRANSPARENT,
+                mScrimBehind, TRANSPARENT
+        ));
+
+        mScrimController.setRawPanelExpansionFraction(0.5f);
+        assertScrimAlpha(Map.of(
+                mScrimInFront, TRANSPARENT,
+                mNotificationsScrim, TRANSPARENT,
+                mScrimBehind, TRANSPARENT
+        ));
+
+        mScrimController.setRawPanelExpansionFraction(1f);
+        assertScrimAlpha(Map.of(
+                mScrimInFront, TRANSPARENT,
+                mNotificationsScrim, TRANSPARENT,
+                mScrimBehind, TRANSPARENT
+        ));
+    }
+
+    @Test
     public void transitionToUnlocked_nonClippedQs_followsLargeScreensInterpolator() {
         mScrimController.setClipsQsScrim(false);
         mScrimController.setRawPanelExpansionFraction(0f);
@@ -2086,7 +2194,7 @@
     }
 
     private void assertScrimTinted(Map<ScrimView, Boolean> scrimToTint) {
-        scrimToTint.forEach((scrim, hasTint) -> assertScrimTint(scrim, hasTint));
+        scrimToTint.forEach(this::assertScrimTint);
     }
 
     private void assertScrimTint(ScrimView scrim, boolean hasTint) {
@@ -2123,7 +2231,7 @@
         if (!scrimToAlpha.containsKey(mNotificationsScrim)) {
             assertScrimAlpha(mNotificationsScrim, TRANSPARENT);
         }
-        scrimToAlpha.forEach((scrimView, alpha) -> assertScrimAlpha(scrimView, alpha));
+        scrimToAlpha.forEach(this::assertScrimAlpha);
 
         // When clipping, QS scrim should not affect combined visibility.
         if (mScrimController.getClipQsScrim() && scrimToAlpha.get(mScrimBehind) == OPAQUE) {
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 3ca4c59..0e4d892 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
@@ -37,6 +37,8 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
@@ -66,6 +68,7 @@
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.TrustGrantFlags;
 import com.android.keyguard.ViewMediatorCallback;
+import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor;
 import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
@@ -74,8 +77,11 @@
 import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;
 import com.android.systemui.bouncer.ui.BouncerView;
 import com.android.systemui.bouncer.ui.BouncerViewDelegate;
+import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.dreams.DreamOverlayStateController;
+import com.android.systemui.flags.DisableSceneContainer;
+import com.android.systemui.flags.EnableSceneContainer;
 import com.android.systemui.keyguard.domain.interactor.KeyguardDismissActionInteractor;
 import com.android.systemui.keyguard.domain.interactor.KeyguardSurfaceBehindInteractor;
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
@@ -158,6 +164,7 @@
     @Mock private TaskbarDelegate mTaskbarDelegate;
     @Mock private StatusBarKeyguardViewManager.KeyguardViewManagerCallback mCallback;
     @Mock private SelectedUserInteractor mSelectedUserInteractor;
+    @Mock private DeviceEntryInteractor mDeviceEntryInteractor;
 
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback
@@ -178,6 +185,7 @@
     public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
 
     @Before
+    @DisableFlags(com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR)
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         when(mContainer.findViewById(anyInt())).thenReturn(mKeyguardMessageArea);
@@ -185,10 +193,6 @@
                 .thenReturn(mKeyguardMessageAreaController);
         when(mBouncerView.getDelegate()).thenReturn(mBouncerViewDelegate);
         when(mBouncerViewDelegate.getBackCallback()).thenReturn(mBouncerViewDelegateBackCallback);
-        mSetFlagsRule.disableFlags(
-                com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR,
-                com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR
-        );
 
         when(mNotificationShadeWindowController.getWindowRootView())
                 .thenReturn(mNotificationShadeWindowView);
@@ -227,7 +231,8 @@
                         () -> mock(KeyguardSurfaceBehindInteractor.class),
                         mock(JavaAdapter.class),
                         () -> mock(SceneInteractor.class),
-                        mock(StatusBarKeyguardViewManagerInteractor.class)) {
+                        mock(StatusBarKeyguardViewManagerInteractor.class),
+                        () -> mDeviceEntryInteractor) {
                     @Override
                     public ViewRootImpl getViewRootImpl() {
                         return mViewRootImpl;
@@ -250,6 +255,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void dismissWithAction_AfterKeyguardGoneSetToFalse() {
         OnDismissAction action = () -> false;
         Runnable cancelAction = () -> {
@@ -265,6 +271,7 @@
         mStatusBarKeyguardViewManager.hide(0 /* startTime */, 0 /* fadeoutDuration */);
         mStatusBarKeyguardViewManager.showPrimaryBouncer(true /* scrimmed */);
         verify(mPrimaryBouncerInteractor, never()).show(anyBoolean());
+        verify(mDeviceEntryInteractor, never()).attemptDeviceEntry();
     }
 
     @Test
@@ -274,9 +281,11 @@
                 KeyguardSecurityModel.SecurityMode.Password);
         mStatusBarKeyguardViewManager.showPrimaryBouncer(true /* scrimmed */);
         verify(mPrimaryBouncerInteractor, never()).show(anyBoolean());
+        verify(mDeviceEntryInteractor, never()).attemptDeviceEntry();
     }
 
     @Test
+    @DisableSceneContainer
     public void showBouncer_showsTheBouncer() {
         mStatusBarKeyguardViewManager.showPrimaryBouncer(true /* scrimmed */);
         verify(mPrimaryBouncerInteractor).show(eq(true));
@@ -320,6 +329,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void onPanelExpansionChanged_showsBouncerWhenSwiping() {
         mKeyguardStateController.setCanDismissLockScreen(false);
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
@@ -456,6 +466,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void testHiding_cancelsGoneRunnable() {
         OnDismissAction action = mock(OnDismissAction.class);
         Runnable cancelAction = mock(Runnable.class);
@@ -470,6 +481,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void testHidingBouncer_cancelsGoneRunnable() {
         OnDismissAction action = mock(OnDismissAction.class);
         Runnable cancelAction = mock(Runnable.class);
@@ -484,6 +496,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void testHiding_doesntCancelWhenShowing() {
         OnDismissAction action = mock(OnDismissAction.class);
         Runnable cancelAction = mock(Runnable.class);
@@ -539,6 +552,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void testShowAltAuth_unlockingWithBiometricNotAllowed() {
         // GIVEN cannot use alternate bouncer
         when(mPrimaryBouncerInteractor.isFullyShowing()).thenReturn(false);
@@ -553,6 +567,8 @@
     }
 
     @Test
+    @DisableSceneContainer
+    @DisableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
     public void testShowAlternateBouncer_unlockingWithBiometricAllowed() {
         // GIVEN will show alternate bouncer
         when(mPrimaryBouncerInteractor.isFullyShowing()).thenReturn(false);
@@ -735,7 +751,8 @@
                         () -> mock(KeyguardSurfaceBehindInteractor.class),
                         mock(JavaAdapter.class),
                         () -> mock(SceneInteractor.class),
-                        mock(StatusBarKeyguardViewManagerInteractor.class)) {
+                        mock(StatusBarKeyguardViewManagerInteractor.class),
+                        () -> mDeviceEntryInteractor) {
                     @Override
                     public ViewRootImpl getViewRootImpl() {
                         return mViewRootImpl;
@@ -783,11 +800,11 @@
     }
 
     @Test
+    @EnableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
     public void handleDispatchTouchEvent_alternateBouncerViewFlagEnabled() {
         mStatusBarKeyguardViewManager.addCallback(mCallback);
 
         // GIVEN alternate bouncer view flag enabled & the alternate bouncer is visible
-        mSetFlagsRule.enableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR);
         when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
 
         // THEN the touch is not acted upon
@@ -795,9 +812,9 @@
     }
 
     @Test
+    @EnableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
     public void onInterceptTouch_alternateBouncerViewFlagEnabled() {
         // GIVEN alternate bouncer view flag enabled & the alternate bouncer is visible
-        mSetFlagsRule.enableFlags(com.android.systemui.Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR);
         when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
 
         // THEN the touch is not intercepted
@@ -829,6 +846,8 @@
     }
 
     @Test
+    @DisableSceneContainer
+    @DisableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
     public void handleDispatchTouchEvent_shouldInterceptTouchAndHandleTouch() {
         mStatusBarKeyguardViewManager.addCallback(mCallback);
 
@@ -855,6 +874,8 @@
     }
 
     @Test
+    @DisableSceneContainer
+    @DisableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
     public void handleDispatchTouchEvent_shouldInterceptTouchButNotHandleTouch() {
         mStatusBarKeyguardViewManager.addCallback(mCallback);
 
@@ -881,6 +902,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void shouldInterceptTouch_alternateBouncerNotVisible() {
         // GIVEN the alternate bouncer is not visible
         when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(false);
@@ -898,6 +920,8 @@
     }
 
     @Test
+    @DisableSceneContainer
+    @DisableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
     public void shouldInterceptTouch_alternateBouncerVisible() {
         // GIVEN the alternate bouncer is visible
         when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
@@ -931,6 +955,8 @@
     }
 
     @Test
+    @DisableSceneContainer
+    @DisableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
     public void alternateBouncerOnTouch_actionDownThenUp_noMinTimeShown_noHideAltBouncer() {
         reset(mAlternateBouncerInteractor);
 
@@ -955,6 +981,8 @@
     }
 
     @Test
+    @DisableSceneContainer
+    @DisableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
     public void alternateBouncerOnTouch_actionDownThenUp_handlesTouch_hidesAltBouncer() {
         reset(mAlternateBouncerInteractor);
 
@@ -979,6 +1007,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void alternateBouncerOnTouch_actionUp_doesNotHideAlternateBouncer() {
         reset(mAlternateBouncerInteractor);
 
@@ -996,6 +1025,8 @@
     }
 
     @Test
+    @DisableSceneContainer
+    @DisableFlags(Flags.FLAG_DEVICE_ENTRY_UDFPS_REFACTOR)
     public void onTrustChanged_hideAlternateBouncerAndClearMessageArea() {
         // GIVEN keyguard update monitor callback is registered
         verify(mKeyguardUpdateMonitor).registerCallback(mKeyguardUpdateMonitorCallback.capture());
@@ -1024,6 +1055,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void testShowBouncerOrKeyguard_needsFullScreen() {
         when(mKeyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(
                 KeyguardSecurityModel.SecurityMode.SimPin);
@@ -1033,6 +1065,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void testShowBouncerOrKeyguard_needsFullScreen_bouncerAlreadyShowing() {
         when(mKeyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(
                 KeyguardSecurityModel.SecurityMode.SimPin);
@@ -1043,6 +1076,20 @@
     }
 
     @Test
+    @EnableSceneContainer
+    public void showBouncer_attemptDeviceEntry() {
+        mStatusBarKeyguardViewManager.showBouncer(false);
+        verify(mDeviceEntryInteractor).attemptDeviceEntry();
+    }
+
+    @Test
+    @EnableSceneContainer
+    public void showPrimaryBouncer_attemptDeviceEntry() {
+        mStatusBarKeyguardViewManager.showPrimaryBouncer(false);
+        verify(mDeviceEntryInteractor).attemptDeviceEntry();
+    }
+
+    @Test
     public void altBouncerNotVisible_keyguardAuthenticatedBiometricsHandled() {
         clearInvocations(mAlternateBouncerInteractor);
         when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
index 35888a5..80b9e80 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
@@ -16,14 +16,18 @@
 
 import static android.content.Intent.ACTION_DEVICE_LOCKED_CHANGED;
 
+import static org.mockito.ArgumentMatchers.any;
+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 static org.mockito.internal.verification.VerificationModeFactory.times;
 
 import android.content.Intent;
+import android.platform.test.annotations.EnableFlags;
 import android.testing.TestableLooper;
 import android.view.View;
 
@@ -38,8 +42,10 @@
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.notification.row.NotificationContentView;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.concurrency.FakeExecutor;
@@ -55,6 +61,8 @@
 @RunWith(AndroidJUnit4.class)
 @TestableLooper.RunWithLooper
 public class StatusBarRemoteInputCallbackTest extends SysuiTestCase {
+
+    @Mock private GroupExpansionManager mGroupExpansionManager;
     @Mock private DeviceProvisionedController mDeviceProvisionedController;
     @Mock private com.android.systemui.shade.ShadeController mShadeController;
     @Mock private NotificationLockscreenUserManager mNotificationLockscreenUserManager;
@@ -77,7 +85,7 @@
                 mNotificationLockscreenUserManager);
 
         mRemoteInputCallback = spy(new StatusBarRemoteInputCallback(mContext,
-                mock(GroupExpansionManager.class), mNotificationLockscreenUserManager,
+                mGroupExpansionManager, mNotificationLockscreenUserManager,
                 mKeyguardStateController, mStatusBarStateController, mStatusBarKeyguardViewManager,
                 mActivityStarter, mShadeController,
                 new CommandQueue(mContext, new FakeDisplayTracker(mContext)),
@@ -103,4 +111,177 @@
 
         verify(mStatusBarKeyguardViewManager).showBouncer(true);
     }
+
+    @Test
+    public void onMakeExpandedVisibleForRemoteInput_collapsedGroup_expandGroupExpansion() {
+        // GIVEN
+        final Runnable onExpandedVisibleRunner = mock(Runnable.class);
+
+        final ExpandableNotificationRow enr = mock(ExpandableNotificationRow.class);
+        final NotificationContentView privateLayout = mock(NotificationContentView.class);
+        final NotificationEntry enrEntry = mock(NotificationEntry.class);
+
+        when(enr.getPrivateLayout()).thenReturn(privateLayout);
+        when(enr.getEntry()).thenReturn(enrEntry);
+        when(enr.isChildInGroup()).thenReturn(true);
+        when(enr.areChildrenExpanded()).thenReturn(false);
+
+        // WHEN
+        mRemoteInputCallback.onMakeExpandedVisibleForRemoteInput(
+                enr, mock(View.class), false, onExpandedVisibleRunner);
+
+        // THEN
+        verify(mGroupExpansionManager).toggleGroupExpansion(enrEntry);
+        verify(enr).setUserExpanded(true);
+        verify(privateLayout).setOnExpandedVisibleListener(onExpandedVisibleRunner);
+    }
+
+    @Test
+    public void onMakeExpandedVisibleForRemoteInput_expandedGroup_setUserExpandedTrue() {
+        // GIVEN
+        final Runnable onExpandedVisibleRunner = mock(Runnable.class);
+
+        final ExpandableNotificationRow enr = mock(ExpandableNotificationRow.class);
+        final NotificationContentView privateLayout = mock(NotificationContentView.class);
+        final NotificationEntry enrEntry = mock(NotificationEntry.class);
+
+        when(enr.getPrivateLayout()).thenReturn(privateLayout);
+        when(enr.getEntry()).thenReturn(enrEntry);
+        when(enr.isChildInGroup()).thenReturn(true);
+        when(enr.areChildrenExpanded()).thenReturn(true);
+
+        // WHEN
+        mRemoteInputCallback.onMakeExpandedVisibleForRemoteInput(
+                enr, mock(View.class), false, onExpandedVisibleRunner);
+
+        // THEN
+        verify(mGroupExpansionManager, never()).toggleGroupExpansion(any());
+        verify(enr).setUserExpanded(true);
+        verify(privateLayout).setOnExpandedVisibleListener(onExpandedVisibleRunner);
+    }
+
+    @Test
+    public void onMakeExpandedVisibleForRemoteInput_nonGroupNotifications_setUserExpandedTrue() {
+        // GIVEN
+        final Runnable onExpandedVisibleRunner = mock(Runnable.class);
+
+        final ExpandableNotificationRow enr = mock(ExpandableNotificationRow.class);
+        final NotificationContentView privateLayout = mock(NotificationContentView.class);
+        final NotificationEntry enrEntry = mock(NotificationEntry.class);
+
+        when(enr.getPrivateLayout()).thenReturn(privateLayout);
+        when(enr.getEntry()).thenReturn(enrEntry);
+        when(enr.isChildInGroup()).thenReturn(false);
+
+        // WHEN
+        mRemoteInputCallback.onMakeExpandedVisibleForRemoteInput(
+                enr, mock(View.class), false, onExpandedVisibleRunner);
+
+        // THEN
+        verify(mGroupExpansionManager, never()).toggleGroupExpansion(any());
+        verify(enr).setUserExpanded(true);
+        verify(privateLayout).setOnExpandedVisibleListener(onExpandedVisibleRunner);
+    }
+
+    @Test
+    @EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
+    public void onMakeExpandedVisibleForRemoteInput_notExpandedGroup_toggleExpansion() {
+        // GIVEN
+        final Runnable onExpandedVisibleRunner = mock(Runnable.class);
+
+        final ExpandableNotificationRow enr = mock(ExpandableNotificationRow.class);
+        final NotificationContentView privateLayout = mock(NotificationContentView.class);
+        final NotificationEntry enrEntry = mock(NotificationEntry.class);
+
+        when(enr.getPrivateLayout()).thenReturn(privateLayout);
+        when(enr.getEntry()).thenReturn(enrEntry);
+        when(enr.isChildInGroup()).thenReturn(true);
+        when(enr.areChildrenExpanded()).thenReturn(false);
+
+        // WHEN
+        mRemoteInputCallback.onMakeExpandedVisibleForRemoteInput(
+                enr, mock(View.class), false, onExpandedVisibleRunner);
+
+        // THEN
+        verify(mGroupExpansionManager).toggleGroupExpansion(enrEntry);
+        verify(enr, never()).setUserExpanded(anyBoolean());
+        verify(privateLayout, never()).setOnExpandedVisibleListener(any());
+    }
+
+    @Test
+    @EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
+    public void onMakeExpandedVisibleForRemoteInput_expandedGroup_notToggleExpansion() {
+        // GIVEN
+        final Runnable onExpandedVisibleRunner = mock(Runnable.class);
+
+        final ExpandableNotificationRow enr = mock(ExpandableNotificationRow.class);
+        final NotificationContentView privateLayout = mock(NotificationContentView.class);
+        final NotificationEntry enrEntry = mock(NotificationEntry.class);
+
+        when(enr.getPrivateLayout()).thenReturn(privateLayout);
+        when(enr.getEntry()).thenReturn(enrEntry);
+        when(enr.isChildInGroup()).thenReturn(true);
+        when(enr.areChildrenExpanded()).thenReturn(true);
+
+        // WHEN
+        mRemoteInputCallback.onMakeExpandedVisibleForRemoteInput(
+                enr, mock(View.class), false, onExpandedVisibleRunner);
+
+        // THEN
+        verify(mGroupExpansionManager, never()).toggleGroupExpansion(enrEntry);
+        verify(enr, never()).setUserExpanded(anyBoolean());
+        verify(privateLayout, never()).setOnExpandedVisibleListener(any());
+    }
+
+    @Test
+    @EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
+    public void onMakeExpandedVisibleForRemoteInput_notExpandedNotification_toggleExpansion() {
+        // GIVEN
+        final Runnable onExpandedVisibleRunner = mock(Runnable.class);
+
+        final ExpandableNotificationRow enr = mock(ExpandableNotificationRow.class);
+        final NotificationContentView privateLayout = mock(NotificationContentView.class);
+        final NotificationEntry enrEntry = mock(NotificationEntry.class);
+
+        when(enr.getPrivateLayout()).thenReturn(privateLayout);
+        when(enr.getEntry()).thenReturn(enrEntry);
+        when(enr.isChildInGroup()).thenReturn(false);
+        when(enr.isExpanded()).thenReturn(false);
+
+        // WHEN
+        mRemoteInputCallback.onMakeExpandedVisibleForRemoteInput(
+                enr, mock(View.class), false, onExpandedVisibleRunner);
+
+        // THEN
+        verify(enr).toggleExpansionState();
+        verify(privateLayout).setOnExpandedVisibleListener(onExpandedVisibleRunner);
+        verify(enr, never()).setUserExpanded(anyBoolean());
+        verify(mGroupExpansionManager, never()).toggleGroupExpansion(any());
+    }
+
+    @Test
+    @EnableFlags(ExpandHeadsUpOnInlineReply.FLAG_NAME)
+    public void onMakeExpandedVisibleForRemoteInput_expandedNotification_notToggleExpansion() {
+        // GIVEN
+        final Runnable onExpandedVisibleRunner = mock(Runnable.class);
+
+        final ExpandableNotificationRow enr = mock(ExpandableNotificationRow.class);
+        final NotificationContentView privateLayout = mock(NotificationContentView.class);
+        final NotificationEntry enrEntry = mock(NotificationEntry.class);
+
+        when(enr.getPrivateLayout()).thenReturn(privateLayout);
+        when(enr.getEntry()).thenReturn(enrEntry);
+        when(enr.isChildInGroup()).thenReturn(false);
+        when(enr.isExpanded()).thenReturn(true);
+
+        // WHEN
+        mRemoteInputCallback.onMakeExpandedVisibleForRemoteInput(
+                enr, mock(View.class), false, onExpandedVisibleRunner);
+
+        // THEN
+        verify(enr, never()).toggleExpansionState();
+        verify(privateLayout, never()).setOnExpandedVisibleListener(onExpandedVisibleRunner);
+        verify(enr, never()).setUserExpanded(anyBoolean());
+        verify(mGroupExpansionManager, never()).toggleGroupExpansion(any());
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt
new file mode 100644
index 0000000..230ddf9
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerTest.kt
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.compose.animation.scene.ObservableTransitionState
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.DisableSceneContainer
+import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.data.repository.sceneContainerRepository
+import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.testKosmos
+import com.android.systemui.util.kotlin.getValue
+import com.google.common.truth.Truth.assertThat
+import dagger.Lazy
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@OptIn(ExperimentalCoroutinesApi::class)
+class StatusBarTouchableRegionManagerTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val sceneRepository = kosmos.sceneContainerRepository
+
+    private val underTest by Lazy { kosmos.statusBarTouchableRegionManager }
+
+    @Test
+    @EnableSceneContainer
+    fun entireScreenTouchable_sceneContainerEnabled_isRemoteUserInteractionOngoing() =
+        testScope.runTest {
+            sceneRepository.setTransitionState(
+                flowOf(ObservableTransitionState.Idle(currentScene = Scenes.Gone))
+            )
+            runCurrent()
+            assertThat(underTest.shouldMakeEntireScreenTouchable()).isFalse()
+
+            sceneRepository.isRemoteUserInteractionOngoing.value = true
+            runCurrent()
+            assertThat(underTest.shouldMakeEntireScreenTouchable()).isTrue()
+
+            sceneRepository.isRemoteUserInteractionOngoing.value = false
+            runCurrent()
+            assertThat(underTest.shouldMakeEntireScreenTouchable()).isFalse()
+        }
+
+    @Test
+    @DisableSceneContainer
+    fun entireScreenTouchable_sceneContainerDisabled_isRemoteUserInteractionOngoing() =
+        testScope.runTest {
+            assertThat(underTest.shouldMakeEntireScreenTouchable()).isFalse()
+
+            sceneRepository.isRemoteUserInteractionOngoing.value = true
+            runCurrent()
+
+            assertThat(underTest.shouldMakeEntireScreenTouchable()).isFalse()
+        }
+
+    @Test
+    @EnableSceneContainer
+    fun entireScreenTouchable_sceneContainerEnabled_isIdleOnGone() =
+        testScope.runTest {
+            sceneRepository.setTransitionState(
+                flowOf(ObservableTransitionState.Idle(currentScene = Scenes.Gone))
+            )
+            runCurrent()
+            assertThat(underTest.shouldMakeEntireScreenTouchable()).isFalse()
+
+            sceneRepository.setTransitionState(
+                flowOf(ObservableTransitionState.Idle(currentScene = Scenes.Shade))
+            )
+            runCurrent()
+            assertThat(underTest.shouldMakeEntireScreenTouchable()).isTrue()
+
+            sceneRepository.setTransitionState(
+                flowOf(ObservableTransitionState.Idle(currentScene = Scenes.Gone))
+            )
+            runCurrent()
+            assertThat(underTest.shouldMakeEntireScreenTouchable()).isFalse()
+        }
+
+    @Test
+    @DisableSceneContainer
+    fun entireScreenTouchable_sceneContainerDisabled_isIdleOnGone() =
+        testScope.runTest {
+            assertThat(underTest.shouldMakeEntireScreenTouchable()).isFalse()
+
+            sceneRepository.setTransitionState(
+                flowOf(ObservableTransitionState.Idle(currentScene = Scenes.Shade))
+            )
+            runCurrent()
+
+            assertThat(underTest.shouldMakeEntireScreenTouchable()).isFalse()
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt
index 5a0e13d..2d9880a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/domain/interactor/LightsOutInteractorTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.phone.domain.interactor
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
@@ -25,8 +26,10 @@
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class LightsOutInteractorTest : SysuiTestCase() {
 
     private val statusBarModeRepository = FakeStatusBarModeRepository()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt
index e0f1e1a..219b16f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.phone.fragment
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
@@ -26,9 +27,11 @@
 import java.io.PrintWriter
 import java.io.StringWriter
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mockito.mock
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class CollapsedStatusBarFragmentLoggerTest : SysuiTestCase() {
 
     private val buffer = LogBufferFactory(DumpManager(), mock(LogcatEchoTracker::class.java))
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 ee27cea..01540e7 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
@@ -49,6 +49,8 @@
 import com.android.systemui.animation.AnimatorTestRule;
 import com.android.systemui.demomode.DemoModeController;
 import com.android.systemui.dump.DumpManager;
+import com.android.systemui.flags.DisableSceneContainer;
+import com.android.systemui.flags.EnableSceneContainer;
 import com.android.systemui.log.LogBuffer;
 import com.android.systemui.log.LogcatEchoTracker;
 import com.android.systemui.plugins.DarkIconDispatcher;
@@ -302,6 +304,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void disable_shadeOpenAndShouldHide_everythingHidden() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
@@ -318,6 +321,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void disable_shadeOpenButNotShouldHide_everythingShown() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
@@ -335,6 +339,7 @@
 
     /** Regression test for b/279790651. */
     @Test
+    @DisableSceneContainer
     public void disable_shadeOpenAndShouldHide_thenShadeNotOpenAndDozingUpdate_everythingShown() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
@@ -376,6 +381,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void disable_isTransitioningToOccluded_everythingHidden() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
@@ -390,6 +396,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void disable_wasTransitioningToOccluded_transitionFinished_everythingShown() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
@@ -674,6 +681,80 @@
     }
 
     @Test
+    @EnableSceneContainer
+    public void isHomeStatusBarAllowedByScene_false_everythingHidden() {
+        resumeAndGetFragment();
+
+        mCollapsedStatusBarViewBinder.getListener().onIsHomeStatusBarAllowedBySceneChanged(false);
+
+        // THEN all views are hidden
+        assertEquals(View.GONE, getClockView().getVisibility());
+        assertEquals(View.INVISIBLE, getNotificationAreaView().getVisibility());
+        assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility());
+    }
+
+    @Test
+    @EnableSceneContainer
+    public void isHomeStatusBarAllowedByScene_true_everythingShown() {
+        resumeAndGetFragment();
+
+        mCollapsedStatusBarViewBinder.getListener().onIsHomeStatusBarAllowedBySceneChanged(true);
+
+        // THEN all views are shown
+        assertEquals(View.VISIBLE, getClockView().getVisibility());
+        assertEquals(View.VISIBLE, getNotificationAreaView().getVisibility());
+        assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
+    }
+
+    @Test
+    @EnableSceneContainer
+    public void disable_isHomeStatusBarAllowedBySceneFalse_disableValuesIgnored() {
+        CollapsedStatusBarFragment fragment = resumeAndGetFragment();
+
+        // WHEN the scene doesn't allow the status bar
+        mCollapsedStatusBarViewBinder.getListener().onIsHomeStatusBarAllowedBySceneChanged(false);
+
+        // BUT the disable flags want to show the status bar
+        fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
+
+        // THEN all views are hidden (the disable flags aren't respected)
+        assertEquals(View.GONE, getClockView().getVisibility());
+        assertEquals(View.INVISIBLE, getNotificationAreaView().getVisibility());
+        assertEquals(View.INVISIBLE, getEndSideContentView().getVisibility());
+    }
+
+    @Test
+    @EnableSceneContainer
+    public void disable_isHomeStatusBarAllowedBySceneTrue_disableValuesUsed() {
+        CollapsedStatusBarFragment fragment = resumeAndGetFragment();
+
+        // WHEN the scene does allow the status bar
+        mCollapsedStatusBarViewBinder.getListener().onIsHomeStatusBarAllowedBySceneChanged(true);
+
+        // AND the disable flags want to hide the clock
+        fragment.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_CLOCK, 0, false);
+
+        // THEN all views are shown except the clock (the disable flags are used)
+        assertEquals(View.GONE, getClockView().getVisibility());
+        assertEquals(View.VISIBLE, getNotificationAreaView().getVisibility());
+        assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
+    }
+
+    @Test
+    @DisableSceneContainer
+    public void isHomeStatusBarAllowedByScene_sceneContainerDisabled_valueNotUsed() {
+        resumeAndGetFragment();
+
+        // Even if the scene says to hide the home status bar
+        mCollapsedStatusBarViewBinder.getListener().onIsHomeStatusBarAllowedBySceneChanged(false);
+
+        // The value isn't used because the scene container flag is disabled, so all views are shown
+        assertEquals(View.VISIBLE, getClockView().getVisibility());
+        assertEquals(View.VISIBLE, getNotificationAreaView().getVisibility());
+        assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
+    }
+
+    @Test
     public void disable_isDozing_clockAndSystemInfoVisible() {
         CollapsedStatusBarFragment fragment = resumeAndGetFragment();
         when(mStatusBarStateController.isDozing()).thenReturn(true);
@@ -758,6 +839,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void testStatusBarIcons_hiddenThroughoutCameraLaunch() {
         final CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
@@ -779,6 +861,7 @@
     }
 
     @Test
+    @DisableSceneContainer
     public void testStatusBarIcons_hiddenThroughoutLockscreenToDreamTransition() {
         final CollapsedStatusBarFragment fragment = resumeAndGetFragment();
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModelTest.kt
index 022b5d2..9f6f51a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/StatusBarVisibilityModelTest.kt
@@ -19,14 +19,17 @@
 import android.app.StatusBarManager.DISABLE_NOTIFICATION_ICONS
 import android.app.StatusBarManager.DISABLE_ONGOING_CALL_CHIP
 import android.app.StatusBarManager.DISABLE_SYSTEM_INFO
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.phone.fragment.StatusBarVisibilityModel.Companion.createDefaultModel
 import com.android.systemui.statusbar.phone.fragment.StatusBarVisibilityModel.Companion.createModelFromFlags
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class StatusBarVisibilityModelTest : SysuiTestCase() {
     @Test
     fun createDefaultModel_everythingEnabled() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
index 7273d9f..5174ec7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
@@ -25,11 +25,11 @@
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
 import android.service.notification.NotificationListenerService.REASON_USER_STOPPED
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.LayoutInflater
 import android.view.View
 import android.widget.LinearLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.systemui.Flags.FLAG_STATUS_BAR_SCREEN_SHARING_CHIPS
@@ -80,7 +80,7 @@
 private const val PROC_STATE_INVISIBLE = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
 @OptIn(ExperimentalCoroutinesApi::class)
 class OngoingCallControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLoggerTest.kt
index ecec124..5ce936d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLoggerTest.kt
@@ -16,13 +16,16 @@
 
 package com.android.systemui.statusbar.phone.ongoingcall
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class OngoingCallLoggerTest : SysuiTestCase() {
     private val uiEventLoggerFake = UiEventLoggerFake()
     private val ongoingCallLogger = OngoingCallLogger(uiEventLoggerFake)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt
index d6624ca..27c2366 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt
@@ -16,13 +16,16 @@
 
 package com.android.systemui.statusbar.phone.ongoingcall.data.repository
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class OngoingCallRepositoryTest : SysuiTestCase() {
     private val underTest = OngoingCallRepository()
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImplTest.kt
index 7e523fb..19abbd5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerImplTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.phone.ui
 
 import android.os.UserHandle
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.statusbar.StatusBarIcon
 import com.android.systemui.SysuiTestCase
@@ -32,11 +33,13 @@
 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.verify
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class StatusBarIconControllerImplTest : SysuiTestCase() {
 
     private lateinit var underTest: StatusBarIconControllerImpl
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerTest.java
index 14bce9c..891ff38 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ui/StatusBarIconControllerTest.java
@@ -25,11 +25,11 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
 import android.view.ViewGroup;
 import android.widget.LinearLayout;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.statusbar.StatusBarIcon;
@@ -55,7 +55,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @RunWithLooper(setAsMainLooper = true)
 @SmallTest
 public class StatusBarIconControllerTest extends LeakCheckedTest {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModelImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModelImplTest.kt
index 1c9f523..b823333 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModelImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/airplane/ui/viewmodel/AirplaneModeViewModelImplTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.pipeline.airplane.ui.viewmodel
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.table.TableLogBuffer
@@ -33,12 +34,14 @@
 import kotlinx.coroutines.runBlocking
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
 @SmallTest
 @OptIn(ExperimentalCoroutinesApi::class)
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
+@RunWith(AndroidJUnit4::class)
 class AirplaneModeViewModelImplTest : SysuiTestCase() {
 
     private lateinit var underTest: AirplaneModeViewModelImpl
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt
index 6028712..f9ae5ff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ethernet/domain/EthernetInteractorTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.pipeline.ethernet.domain
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.settingslib.AccessibilityContentDescriptions
 import com.android.systemui.res.R
@@ -28,8 +29,10 @@
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class EthernetInteractorTest : SysuiTestCase() {
     private val connectivityRepository = FakeConnectivityRepository()
     private val underTest = EthernetInteractor(connectivityRepository)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfigTest.kt
index 3de50c9..4a2f6f2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/model/SystemUiCarrierConfigTest.kt
@@ -21,15 +21,18 @@
 import android.telephony.CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL
 import android.telephony.CarrierConfigManager.KEY_SHOW_5G_SLICE_ICON_BOOL
 import android.telephony.CarrierConfigManager.KEY_SHOW_OPERATOR_NAME_IN_STATUSBAR_BOOL
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class SystemUiCarrierConfigTest : SysuiTestCase() {
 
     lateinit var underTest: SystemUiCarrierConfig
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt
index 932c4a1..320c148 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/CarrierConfigRepositoryTest.kt
@@ -20,6 +20,7 @@
 import android.os.PersistableBundle
 import android.telephony.CarrierConfigManager
 import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
 import com.android.systemui.SysuiTestCase
@@ -37,6 +38,7 @@
 import org.junit.After
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
@@ -45,6 +47,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class CarrierConfigRepositoryTest : SysuiTestCase() {
     private val testDispatcher = UnconfinedTestDispatcher()
     private val testScope = TestScope(testDispatcher)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
index 6785de93..db6f5927 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionParameterizedTest.kt
@@ -43,11 +43,12 @@
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
 import org.junit.After
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+import platform.test.runner.parameterized.Parameter
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-import org.junit.runners.Parameterized.Parameters
 
 /**
  * Parameterized test for all of the common values of [FakeNetworkEventModel]. This test simply
@@ -56,7 +57,7 @@
  */
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(Parameterized::class)
+@RunWith(ParameterizedAndroidJunit4::class)
 internal class DemoMobileConnectionParameterizedTest(private val testCase: TestCase) :
     SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
index a41bc0d..5e0d2fb0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/demo/DemoMobileConnectionsRepositoryTest.kt
@@ -19,6 +19,7 @@
 import android.telephony.TelephonyManager.DATA_ACTIVITY_INOUT
 import android.telephony.TelephonyManager.DATA_ACTIVITY_NONE
 import android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.settingslib.SignalIcon
 import com.android.settingslib.mobile.TelephonyIcons.THREE_G
@@ -49,9 +50,11 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class DemoMobileConnectionsRepositoryTest : SysuiTestCase() {
     private val dumpManager: DumpManager = mock()
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt
index 3c13906..fd4c370 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryTest.kt
@@ -23,6 +23,7 @@
 import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET
 import android.telephony.TelephonyCallback
 import android.telephony.TelephonyManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
@@ -58,6 +59,7 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 
@@ -69,6 +71,7 @@
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class FullMobileConnectionRepositoryTest : SysuiTestCase() {
     private lateinit var underTest: FullMobileConnectionRepository
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
index 6d8bf55..8fd0b31 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
@@ -66,6 +66,7 @@
 import android.telephony.TelephonyManager.EXTRA_SUBSCRIPTION_ID
 import android.telephony.TelephonyManager.NETWORK_TYPE_LTE
 import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.settingslib.mobile.MobileMappings
 import com.android.systemui.SysuiTestCase
@@ -107,6 +108,7 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
@@ -114,6 +116,7 @@
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class MobileConnectionRepositoryTest : SysuiTestCase() {
     private lateinit var underTest: MobileConnectionRepositoryImpl
     private lateinit var connectionsRepo: FakeMobileConnectionsRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
index 1488418..30e96f1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorTest.kt
@@ -20,6 +20,7 @@
 import android.telephony.CellSignalStrength
 import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET
 import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.settingslib.mobile.MobileIconCarrierIdOverrides
 import com.android.settingslib.mobile.MobileIconCarrierIdOverridesImpl
@@ -52,11 +53,13 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.ArgumentMatchers.anyString
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class MobileIconInteractorTest : SysuiTestCase() {
     private lateinit var underTest: MobileIconInteractor
     private val mobileMappingsProxy = FakeMobileMappingsProxy()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
index 58d9ee3..cc0eae7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorTest.kt
@@ -21,6 +21,7 @@
 import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
 import android.telephony.SubscriptionManager.PROFILE_CLASS_PROVISIONING
 import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.settingslib.mobile.MobileMappings
 import com.android.systemui.SysuiTestCase
@@ -50,11 +51,13 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class MobileIconsInteractorTest : SysuiTestCase() {
     private lateinit var underTest: MobileIconsInteractor
     private lateinit var connectivityRepository: FakeConnectivityRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerTest.kt
index 755aaa6..4511be9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/ui/MobileViewLoggerTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.pipeline.mobile.ui
 
 import android.widget.TextView
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
@@ -32,10 +33,12 @@
 import java.io.StringWriter
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class MobileViewLoggerTest : SysuiTestCase() {
     private val buffer = LogBufferFactory(DumpManager(), mock()).create("buffer", 10)
     private val stringWriter = StringWriter()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt
index cdc4733..fc1ea22 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcherTest.kt
@@ -18,6 +18,7 @@
 
 import android.telephony.TelephonyManager
 import android.telephony.satellite.SatelliteManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
@@ -41,9 +42,11 @@
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mockito.verify
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class DeviceBasedSatelliteRepositorySwitcherTest : SysuiTestCase() {
     private val testDispatcher = StandardTestDispatcher()
     private val testScope = TestScope(testDispatcher)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/demo/DemoDeviceBasedSatelliteRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/demo/DemoDeviceBasedSatelliteRepositoryTest.kt
index f77fd19..8769389 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/demo/DemoDeviceBasedSatelliteRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/demo/DemoDeviceBasedSatelliteRepositoryTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.pipeline.satellite.data.demo
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
@@ -29,8 +30,10 @@
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class DemoDeviceBasedSatelliteRepositoryTest : SysuiTestCase() {
 
     private val testDispatcher = StandardTestDispatcher()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImplTest.kt
index 890a2e4..73ac6e3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImplTest.kt
@@ -32,10 +32,12 @@
 import android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_OFF
 import android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE
 import android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN
+import android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_ERROR
 import android.telephony.satellite.SatelliteManager.SatelliteException
 import android.telephony.satellite.SatelliteModemStateCallback
 import android.telephony.satellite.SatelliteProvisionStateCallback
 import android.telephony.satellite.SatelliteSupportedStateCallback
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
@@ -60,8 +62,10 @@
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito
+import org.mockito.Mockito.atLeastOnce
 import org.mockito.Mockito.doAnswer
 import org.mockito.Mockito.never
 import org.mockito.Mockito.times
@@ -71,6 +75,7 @@
 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class DeviceBasedSatelliteRepositoryImplTest : SysuiTestCase() {
     private lateinit var underTest: DeviceBasedSatelliteRepositoryImpl
 
@@ -354,13 +359,142 @@
         }
 
     @Test
-    fun satelliteProvisioned_supported_tracksCallback() =
+    fun satelliteProvisioned_returnsException_defaultsToFalse() =
+        testScope.runTest {
+            // GIVEN satellite is supported on device
+            doAnswer {
+                val callback: OutcomeReceiver<Boolean, SatelliteException> =
+                    it.getArgument(1) as OutcomeReceiver<Boolean, SatelliteException>
+                callback.onResult(true)
+            }
+                .whenever(satelliteManager)
+                .requestIsSupported(any(), any())
+
+            // GIVEN satellite returns an error when asked if provisioned
+            doAnswer {
+                val receiver = it.arguments[1] as OutcomeReceiver<Boolean, SatelliteException>
+                receiver.onError(SatelliteException(SATELLITE_RESULT_ERROR))
+                null
+            }
+                .whenever(satelliteManager)
+                .requestIsProvisioned(
+                    any(),
+                    any<OutcomeReceiver<Boolean, SatelliteException>>()
+                )
+
+            // GIVEN we've been up long enough to start querying
+            systemClock.setUptimeMillis(Process.getStartUptimeMillis() + MIN_UPTIME)
+
+            underTest =
+                DeviceBasedSatelliteRepositoryImpl(
+                    Optional.of(satelliteManager),
+                    telephonyManager,
+                    dispatcher,
+                    testScope.backgroundScope,
+                    logBuffer = FakeLogBuffer.Factory.create(),
+                    verboseLogBuffer = FakeLogBuffer.Factory.create(),
+                    systemClock,
+                )
+
+            // WHEN we try to check for provisioned status
+            val provisioned by collectLastValue(underTest.isSatelliteProvisioned)
+
+            // THEN well, first we don't throw...
+            // AND THEN we assume that it's not provisioned
+            assertThat(provisioned).isFalse()
+        }
+
+    @Test
+    fun satelliteProvisioned_throwsWhenQuerying_defaultsToFalse() =
+        testScope.runTest {
+            // GIVEN satellite is supported on device
+            doAnswer {
+                val callback: OutcomeReceiver<Boolean, SatelliteException> =
+                    it.getArgument(1) as OutcomeReceiver<Boolean, SatelliteException>
+                callback.onResult(true)
+            }
+                .whenever(satelliteManager)
+                .requestIsSupported(any(), any())
+
+            // GIVEN satellite throws when asked if provisioned
+            whenever(satelliteManager.requestIsProvisioned(any(), any()))
+                .thenThrow(SecurityException())
+
+            // GIVEN we've been up long enough to start querying
+            systemClock.setUptimeMillis(Process.getStartUptimeMillis() + MIN_UPTIME)
+
+            underTest =
+                DeviceBasedSatelliteRepositoryImpl(
+                    Optional.of(satelliteManager),
+                    telephonyManager,
+                    dispatcher,
+                    testScope.backgroundScope,
+                    logBuffer = FakeLogBuffer.Factory.create(),
+                    verboseLogBuffer = FakeLogBuffer.Factory.create(),
+                    systemClock,
+                )
+
+            // WHEN we try to check for provisioned status
+            val provisioned by collectLastValue(underTest.isSatelliteProvisioned)
+
+            // THEN well, first we don't throw...
+            // AND THEN we assume that it's not provisioned
+            assertThat(provisioned).isFalse()
+        }
+
+    @Test
+    fun satelliteProvisioned_supported_provisioned_queriesInitialStateBeforeCallbacks() =
+        testScope.runTest {
+            // GIVEN satellite is supported, and provisioned
+            setUpRepo(
+                uptime = MIN_UPTIME,
+                satMan = satelliteManager,
+                satelliteSupported = true,
+                initialSatelliteIsProvisioned = true,
+            )
+
+            val provisioned by collectLastValue(underTest.isSatelliteProvisioned)
+
+            runCurrent()
+
+            // THEN the current state is requested
+            verify(satelliteManager, atLeastOnce()).requestIsProvisioned(any(), any())
+
+            // AND the state is correct
+            assertThat(provisioned).isTrue()
+        }
+
+    @Test
+    fun satelliteProvisioned_supported_notProvisioned_queriesInitialStateBeforeCallbacks() =
+        testScope.runTest {
+            // GIVEN satellite is supported, and provisioned
+            setUpRepo(
+                uptime = MIN_UPTIME,
+                satMan = satelliteManager,
+                satelliteSupported = true,
+                initialSatelliteIsProvisioned = false,
+            )
+
+            val provisioned by collectLastValue(underTest.isSatelliteProvisioned)
+
+            runCurrent()
+
+            // THEN the current state is requested
+            verify(satelliteManager, atLeastOnce()).requestIsProvisioned(any(), any())
+
+            // AND the state is correct
+            assertThat(provisioned).isFalse()
+        }
+
+    @Test
+    fun satelliteProvisioned_supported_notInitiallyProvisioned_tracksCallback() =
         testScope.runTest {
             // GIVEN satellite is not supported
             setUpRepo(
                 uptime = MIN_UPTIME,
                 satMan = satelliteManager,
                 satelliteSupported = true,
+                initialSatelliteIsProvisioned = false,
             )
 
             val provisioned by collectLastValue(underTest.isSatelliteProvisioned)
@@ -416,6 +550,8 @@
 
             // THEN listeners are re-registered
             verify(satelliteManager, times(2)).registerForProvisionStateChanged(any(), any())
+            // AND the state is queried again
+            verify(satelliteManager, times(2)).requestIsProvisioned(any(), any())
         }
 
     @Test
@@ -632,6 +768,7 @@
         uptime: Long = MIN_UPTIME,
         satMan: SatelliteManager? = satelliteManager,
         satelliteSupported: Boolean = true,
+        initialSatelliteIsProvisioned: Boolean = true,
     ) {
         doAnswer {
                 val callback: OutcomeReceiver<Boolean, SatelliteException> =
@@ -641,6 +778,14 @@
             .whenever(satelliteManager)
             .requestIsSupported(any(), any())
 
+        doAnswer {
+            val callback: OutcomeReceiver<Boolean, SatelliteException> =
+                it.getArgument(1) as OutcomeReceiver<Boolean, SatelliteException>
+            callback.onResult(initialSatelliteIsProvisioned)
+        }
+            .whenever(satelliteManager)
+            .requestIsProvisioned(any(), any())
+
         systemClock.setUptimeMillis(Process.getStartUptimeMillis() + uptime)
 
         underTest =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
index 2e5ebb3..cd0390e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
@@ -18,6 +18,7 @@
 
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.telephony.flags.Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG
 import com.android.systemui.SysuiTestCase
@@ -38,8 +39,10 @@
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class DeviceBasedSatelliteInteractorTest : SysuiTestCase() {
     private lateinit var underTest: DeviceBasedSatelliteInteractor
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
index c39e301..64b07fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.pipeline.satellite.ui.viewmodel
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
@@ -41,9 +42,11 @@
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
+import org.junit.runner.RunWith
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class DeviceBasedSatelliteViewModelTest : SysuiTestCase() {
     private lateinit var underTest: DeviceBasedSatelliteViewModel
     private lateinit var interactor: DeviceBasedSatelliteInteractor
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/model/DefaultConnectionModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/model/DefaultConnectionModelTest.kt
index c43778a..4c2bb7f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/model/DefaultConnectionModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/model/DefaultConnectionModelTest.kt
@@ -16,13 +16,16 @@
 
 package com.android.systemui.statusbar.pipeline.shared.data.model
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.LogMessageImpl
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class DefaultConnectionModelTest : SysuiTestCase() {
     @Test
     fun messageInitializerAndPrinter_isValidatedFalse_hasCorrectInfo() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryImplTest.kt
index fa4e91b..f486787 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/data/repository/ConnectivityRepositoryImplTest.kt
@@ -25,6 +25,7 @@
 import android.net.vcn.VcnTransportInfo
 import android.net.wifi.WifiInfo
 import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
@@ -50,6 +51,7 @@
 import kotlinx.coroutines.yield
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when` as whenever
@@ -57,6 +59,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class ConnectivityRepositoryImplTest : SysuiTestCase() {
 
     private lateinit var underTest: ConnectivityRepositoryImpl
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt
index 028a58c..c3ad0f9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/ModernStatusBarViewTest.kt
@@ -17,8 +17,8 @@
 package com.android.systemui.statusbar.pipeline.shared.ui.view
 
 import android.graphics.Rect
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT
@@ -30,7 +30,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @RunWithLooper(setAsMainLooper = true)
 class ModernStatusBarViewTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/SingleBindableStatusBarIconViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/SingleBindableStatusBarIconViewTest.kt
index ca9df57..a6cdfe2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/SingleBindableStatusBarIconViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/view/SingleBindableStatusBarIconViewTest.kt
@@ -17,8 +17,8 @@
 package com.android.systemui.statusbar.pipeline.shared.ui.view
 
 import android.graphics.Rect
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.StatusBarIconView
@@ -32,7 +32,7 @@
  * method.
  */
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 class SingleBindableStatusBarIconViewTest : SysuiTestCase() {
     private lateinit var binding: SingleBindableStatusBarIconViewBinding
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt
index 92de866..94159bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/CollapsedStatusBarViewModelImplTest.kt
@@ -18,11 +18,13 @@
 
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
@@ -35,6 +37,10 @@
 import com.android.systemui.log.assertLogsWtf
 import com.android.systemui.mediaprojection.data.model.MediaProjectionState
 import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
+import com.android.systemui.scene.data.repository.sceneContainerRepository
+import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.screenrecord.data.model.ScreenRecordModel
 import com.android.systemui.screenrecord.data.repository.screenRecordRepository
 import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.MediaProjectionChipInteractorTest.Companion.NORMAL_PACKAGE
@@ -60,9 +66,11 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
 @OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
 class CollapsedStatusBarViewModelImplTest : SysuiTestCase() {
     private val kosmos =
         Kosmos().also {
@@ -81,6 +89,8 @@
             kosmos.lightsOutInteractor,
             kosmos.activeNotificationsInteractor,
             kosmos.keyguardTransitionInteractor,
+            kosmos.sceneInteractor,
+            kosmos.sceneContainerOcclusionInteractor,
             kosmos.ongoingActivityChipsViewModel,
             kosmos.applicationCoroutineScope,
         )
@@ -423,6 +433,68 @@
             assertIsShareToAppChip(latest)
         }
 
+    @Test
+    fun isHomeStatusBarAllowedByScene_sceneLockscreen_notOccluded_false() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+
+            kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
+            kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(false, taskInfo = null)
+
+            assertThat(latest).isFalse()
+        }
+
+    @Test
+    fun isHomeStatusBarAllowedByScene_sceneLockscreen_occluded_true() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+
+            kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
+            kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(true, taskInfo = null)
+
+            assertThat(latest).isTrue()
+        }
+
+    @Test
+    fun isHomeStatusBarAllowedByScene_sceneBouncer_false() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+
+            kosmos.sceneContainerRepository.snapToScene(Scenes.Bouncer)
+
+            assertThat(latest).isFalse()
+        }
+
+    @Test
+    fun isHomeStatusBarAllowedByScene_sceneCommunal_false() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+
+            kosmos.sceneContainerRepository.snapToScene(Scenes.Communal)
+
+            assertThat(latest).isFalse()
+        }
+
+    @Test
+    fun isHomeStatusBarAllowedByScene_sceneShade_false() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+
+            kosmos.sceneContainerRepository.snapToScene(Scenes.Shade)
+
+            assertThat(latest).isFalse()
+        }
+
+    @Test
+    fun isHomeStatusBarAllowedByScene_sceneGone_true() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.isHomeStatusBarAllowedByScene)
+
+            kosmos.sceneContainerRepository.snapToScene(Scenes.Gone)
+
+            assertThat(latest).isTrue()
+        }
+
     private fun activeNotificationsStore(notifications: List<ActiveNotificationModel>) =
         ActiveNotificationsStore.Builder()
             .apply { notifications.forEach(::addIndividualNotif) }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt
index b66eed0..d3f1125 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeCollapsedStatusBarViewModel.kt
@@ -31,6 +31,8 @@
     override val ongoingActivityChip: MutableStateFlow<OngoingActivityChipModel> =
         MutableStateFlow(OngoingActivityChipModel.Hidden)
 
+    override val isHomeStatusBarAllowedByScene = MutableStateFlow(false)
+
     override fun areNotificationsLightsOut(displayId: Int): Flow<Boolean> = areNotificationLightsOut
 
     fun setNotificationLightsOut(lightsOut: Boolean) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt
index 0cb3329..2238bff 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/InternetTileViewModelTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.pipeline.shared.ui.viewmodel
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.settingslib.AccessibilityContentDescriptions.WIFI_OTHER_DEVICE_CONNECTION
 import com.android.systemui.SysuiTestCase
@@ -55,8 +56,10 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class InternetTileViewModelTest : SysuiTestCase() {
     private lateinit var underTest: InternetTileViewModel
     private lateinit var mobileIconsInteractor: MobileIconsInteractor
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModelTest.kt
index ba035be..eb6b068 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/shared/model/WifiNetworkModelTest.kt
@@ -18,6 +18,7 @@
 
 import android.net.wifi.WifiManager.UNKNOWN_SSID
 import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.table.TableRowLogger
@@ -25,8 +26,10 @@
 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel.Companion.MIN_VALID_LEVEL
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class WifiNetworkModelTest : SysuiTestCase() {
     @Test
     fun active_levelsInValidRange_noException() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
index ed8843b..db829a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryControllerTest.java
@@ -23,6 +23,8 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.staticMockMarker;
 import static com.android.settingslib.fuelgauge.BatterySaverLogging.SAVER_ENABLED_QS;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -308,6 +310,52 @@
         mBatteryController.fireBatteryLevelChanged();
     }
 
+    @Test
+    public void plugAndUnplugWhenInBatterySaver_stateUpdatedWithoutBatterySaverBroadcast() {
+        PowerSaveState state = new PowerSaveState.Builder()
+                .setBatterySaverEnabled(false)
+                .build();
+        when(mPowerManager.getPowerSaveState(PowerManager.ServiceType.AOD)).thenReturn(state);
+
+        // Set up on power save and not charging
+        when(mPowerManager.isPowerSaveMode()).thenReturn(true);
+        mBatteryController.onReceive(
+                getContext(), new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
+        mBatteryController.onReceive(getContext(), createChargingIntent(false));
+
+        TestCallback callback = new TestCallback();
+        mBatteryController.addCallback(callback);
+
+        assertThat(callback.pluggedIn).isFalse();
+        assertThat(callback.powerSaverOn).isTrue();
+
+        // Plug in (battery saver turns off)
+        when(mPowerManager.isPowerSaveMode()).thenReturn(false);
+        mBatteryController.onReceive(getContext(), createChargingIntent(true));
+
+        assertThat(callback.pluggedIn).isTrue();
+        assertThat(callback.powerSaverOn).isFalse();
+
+        // Unplug (battery saver turns back on)
+        when(mPowerManager.isPowerSaveMode()).thenReturn(true);
+        mBatteryController.onReceive(getContext(), createChargingIntent(false));
+
+        assertThat(callback.pluggedIn).isFalse();
+        assertThat(callback.powerSaverOn).isTrue();
+    }
+
+    private Intent createChargingIntent(boolean charging) {
+        Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
+        if (charging) {
+            return intent
+                .putExtra(BatteryManager.EXTRA_STATUS, BatteryManager.BATTERY_STATUS_CHARGING)
+                .putExtra(BatteryManager.EXTRA_PLUGGED, BatteryManager.BATTERY_PLUGGED_AC);
+        } else {
+            return intent
+                .putExtra(BatteryManager.EXTRA_STATUS, BatteryManager.BATTERY_STATUS_DISCHARGING);
+        }
+    }
+
     private void setupIncompatibleCharging() {
         final List<UsbPort> usbPorts = new ArrayList<>();
         usbPorts.add(mUsbPort);
@@ -318,4 +366,19 @@
         when(mUsbPortStatus.getComplianceWarnings())
                 .thenReturn(new int[]{UsbPortStatus.COMPLIANCE_WARNING_DEBUG_ACCESSORY});
     }
+
+    private static class TestCallback
+        implements BatteryController.BatteryStateChangeCallback {
+        boolean pluggedIn = false;
+        boolean powerSaverOn = false;
+        @Override
+        public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
+            this.pluggedIn = pluggedIn;
+        }
+
+        @Override
+        public void onPowerSaveChanged(boolean isPowerSave) {
+            this.powerSaverOn = isPowerSave;
+        }
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
index 9ab64d65..93071bd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
@@ -43,6 +43,7 @@
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.settingslib.bluetooth.BluetoothEventManager;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java
index 68c1b8d..59b20c8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastControllerImplTest.java
@@ -9,12 +9,13 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.content.pm.PackageManager;
 import android.media.MediaRouter;
 import android.media.projection.MediaProjectionInfo;
 import android.media.projection.MediaProjectionManager;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -33,7 +34,7 @@
 import java.util.concurrent.atomic.AtomicBoolean;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @TestableLooper.RunWithLooper
 public class CastControllerImplTest extends SysuiTestCase {
 
@@ -52,8 +53,12 @@
         mContext.addMockSystemService(MediaRouter.class, mMediaRouter);
         mContext.addMockSystemService(MediaProjectionManager.class, mMediaProjectionManager);
         when(mMediaProjectionManager.getActiveProjectionInfo()).thenReturn(mProjection);
+        when(mProjection.getPackageName()).thenReturn("fake.package");
 
-        mController = new CastControllerImpl(mContext, mock(DumpManager.class));
+        mController = new CastControllerImpl(
+                mContext,
+                mock(PackageManager.class),
+                mock(DumpManager.class));
     }
 
     @Test
@@ -148,16 +153,26 @@
 
     @Test
     public void hasConnectedCastDevice_connected() {
-        CastController.CastDevice castDevice = new CastController.CastDevice();
-        castDevice.state = CastController.CastDevice.STATE_CONNECTED;
+        CastDevice castDevice = new CastDevice(
+                "id",
+                /* name= */ null,
+                /* description= */ null,
+                /* state= */ CastDevice.CastState.Connected,
+                /* origin= */ CastDevice.CastOrigin.MediaProjection,
+                /* tag= */ null);
         mController.startCasting(castDevice);
         assertTrue(mController.hasConnectedCastDevice());
     }
 
     @Test
     public void hasConnectedCastDevice_notConnected() {
-        CastController.CastDevice castDevice = new CastController.CastDevice();
-        castDevice.state = CastController.CastDevice.STATE_CONNECTING;
+        CastDevice castDevice = new CastDevice(
+                "id",
+                /* name= */ null,
+                /* description= */ null,
+                /* state= */ CastDevice.CastState.Connecting,
+                /* origin= */ CastDevice.CastOrigin.MediaProjection,
+                /* tag= */ null);
         mController.startCasting(castDevice);
         assertTrue(mController.hasConnectedCastDevice());
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt
new file mode 100644
index 0000000..03ad66c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CastDeviceTest.kt
@@ -0,0 +1,441 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.policy
+
+import android.Manifest
+import android.content.Intent
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
+import android.content.pm.ResolveInfo
+import android.media.MediaRouter
+import android.media.projection.MediaProjectionInfo
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.policy.CastDevice.Companion.toCastDevice
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Test
+import org.mockito.ArgumentMatchers
+import org.mockito.Mockito.doAnswer
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
+
+@SmallTest
+class CastDeviceTest : SysuiTestCase() {
+    private val mockAppInfo =
+        mock<ApplicationInfo>().apply { whenever(this.loadLabel(any())).thenReturn("") }
+
+    private val packageManager =
+        mock<PackageManager>().apply {
+            whenever(
+                    this.checkPermission(
+                        Manifest.permission.REMOTE_DISPLAY_PROVIDER,
+                        HEADLESS_REMOTE_PACKAGE,
+                    )
+                )
+                .thenReturn(PackageManager.PERMISSION_GRANTED)
+            whenever(
+                    this.checkPermission(
+                        Manifest.permission.REMOTE_DISPLAY_PROVIDER,
+                        NORMAL_PACKAGE,
+                    )
+                )
+                .thenReturn(PackageManager.PERMISSION_DENIED)
+
+            doAnswer {
+                    // See Utils.isHeadlessRemoteDisplayProvider
+                    if ((it.arguments[0] as Intent).`package` == HEADLESS_REMOTE_PACKAGE) {
+                        emptyList()
+                    } else {
+                        listOf(mock<ResolveInfo>())
+                    }
+                }
+                .whenever(this)
+                .queryIntentActivities(any(), ArgumentMatchers.anyInt())
+
+            whenever(this.getApplicationInfo(any<String>(), any<Int>())).thenReturn(mockAppInfo)
+        }
+
+    @Test
+    fun isCasting_disconnected_false() {
+        val device =
+            CastDevice(
+                id = "id",
+                name = "name",
+                state = CastDevice.CastState.Disconnected,
+                origin = CastDevice.CastOrigin.MediaRouter,
+            )
+
+        assertThat(device.isCasting).isFalse()
+    }
+
+    @Test
+    fun isCasting_connecting_true() {
+        val device =
+            CastDevice(
+                id = "id",
+                name = "name",
+                state = CastDevice.CastState.Connecting,
+                origin = CastDevice.CastOrigin.MediaRouter,
+            )
+
+        assertThat(device.isCasting).isTrue()
+    }
+
+    @Test
+    fun isCasting_connected_true() {
+        val device =
+            CastDevice(
+                id = "id",
+                name = "name",
+                state = CastDevice.CastState.Connected,
+                origin = CastDevice.CastOrigin.MediaRouter,
+            )
+
+        assertThat(device.isCasting).isTrue()
+    }
+
+    @Test
+    fun routeToCastDevice_statusNone_stateDisconnected() {
+        val route =
+            mockRouteInfo().apply {
+                whenever(this.statusCode).thenReturn(MediaRouter.RouteInfo.STATUS_NONE)
+            }
+
+        val device = route.toCastDevice(context)
+
+        assertThat(device.state).isEqualTo(CastDevice.CastState.Disconnected)
+    }
+
+    @Test
+    fun routeToCastDevice_statusNotAvailable_stateDisconnected() {
+        val route =
+            mockRouteInfo().apply {
+                whenever(this.statusCode).thenReturn(MediaRouter.RouteInfo.STATUS_NOT_AVAILABLE)
+            }
+
+        val device = route.toCastDevice(context)
+
+        assertThat(device.state).isEqualTo(CastDevice.CastState.Disconnected)
+    }
+
+    @Test
+    fun routeToCastDevice_statusScanning_stateDisconnected() {
+        val route =
+            mockRouteInfo().apply {
+                whenever(this.statusCode).thenReturn(MediaRouter.RouteInfo.STATUS_SCANNING)
+            }
+
+        val device = route.toCastDevice(context)
+
+        assertThat(device.state).isEqualTo(CastDevice.CastState.Disconnected)
+    }
+
+    @Test
+    fun routeToCastDevice_statusAvailable_isSelectedFalse_stateDisconnected() {
+        val route =
+            mockRouteInfo().apply {
+                whenever(this.statusCode).thenReturn(MediaRouter.RouteInfo.STATUS_AVAILABLE)
+                whenever(this.isSelected).thenReturn(false)
+            }
+
+        val device = route.toCastDevice(context)
+
+        assertThat(device.state).isEqualTo(CastDevice.CastState.Disconnected)
+    }
+
+    @Test
+    fun routeToCastDevice_statusAvailable_isSelectedTrue_stateConnected() {
+        val route =
+            mockRouteInfo().apply {
+                whenever(this.statusCode).thenReturn(MediaRouter.RouteInfo.STATUS_AVAILABLE)
+                whenever(this.isSelected).thenReturn(true)
+            }
+
+        val device = route.toCastDevice(context)
+
+        assertThat(device.state).isEqualTo(CastDevice.CastState.Connected)
+    }
+
+    @Test
+    fun routeToCastDevice_statusInUse_isSelectedFalse_stateDisconnected() {
+        val route =
+            mockRouteInfo().apply {
+                whenever(this.statusCode).thenReturn(MediaRouter.RouteInfo.STATUS_IN_USE)
+                whenever(this.isSelected).thenReturn(false)
+            }
+
+        val device = route.toCastDevice(context)
+
+        assertThat(device.state).isEqualTo(CastDevice.CastState.Disconnected)
+    }
+
+    @Test
+    fun routeToCastDevice_statusInUse_isSelectedTrue_stateConnected() {
+        val route =
+            mockRouteInfo().apply {
+                whenever(this.statusCode).thenReturn(MediaRouter.RouteInfo.STATUS_IN_USE)
+                whenever(this.isSelected).thenReturn(true)
+            }
+
+        val device = route.toCastDevice(context)
+
+        assertThat(device.state).isEqualTo(CastDevice.CastState.Connected)
+    }
+
+    @Test
+    fun routeToCastDevice_statusConnecting_isSelectedFalse_stateConnecting() {
+        val route =
+            mockRouteInfo().apply {
+                whenever(this.statusCode).thenReturn(MediaRouter.RouteInfo.STATUS_CONNECTING)
+                whenever(this.isSelected).thenReturn(false)
+            }
+
+        val device = route.toCastDevice(context)
+
+        assertThat(device.state).isEqualTo(CastDevice.CastState.Connecting)
+    }
+
+    @Test
+    fun routeToCastDevice_statusConnecting_isSelectedTrue_stateConnecting() {
+        val route =
+            mockRouteInfo().apply {
+                whenever(this.statusCode).thenReturn(MediaRouter.RouteInfo.STATUS_CONNECTING)
+                whenever(this.isSelected).thenReturn(true)
+            }
+
+        val device = route.toCastDevice(context)
+
+        assertThat(device.state).isEqualTo(CastDevice.CastState.Connecting)
+    }
+
+    @Test
+    fun routeToCastDevice_statusConnected_isSelectedFalse_stateConnected() {
+        val route =
+            mockRouteInfo().apply {
+                whenever(this.statusCode).thenReturn(MediaRouter.RouteInfo.STATUS_CONNECTED)
+                whenever(this.isSelected).thenReturn(false)
+            }
+
+        val device = route.toCastDevice(context)
+
+        assertThat(device.state).isEqualTo(CastDevice.CastState.Connected)
+    }
+
+    @Test
+    fun routeToCastDevice_statusConnected_isSelectedTrue_stateConnected() {
+        val route =
+            mockRouteInfo().apply {
+                whenever(this.statusCode).thenReturn(MediaRouter.RouteInfo.STATUS_CONNECTED)
+                whenever(this.isSelected).thenReturn(true)
+            }
+
+        val device = route.toCastDevice(context)
+
+        assertThat(device.state).isEqualTo(CastDevice.CastState.Connected)
+    }
+
+    @Test
+    fun routeToCastDevice_tagIsStringType_idMatchesTag() {
+        val route = mock<MediaRouter.RouteInfo>().apply { whenever(this.tag).thenReturn("FakeTag") }
+
+        val device = route.toCastDevice(context)
+
+        assertThat(device.id).isEqualTo("FakeTag")
+    }
+
+    @Test
+    fun routeToCastDevice_tagIsOtherType_idMatchesTag() {
+        val tag = listOf("tag1", "tag2")
+        val route = mock<MediaRouter.RouteInfo>().apply { whenever(this.tag).thenReturn(tag) }
+
+        val device = route.toCastDevice(context)
+
+        assertThat(device.id).isEqualTo(tag.toString())
+    }
+
+    @Test
+    fun routeToCastDevice_nameMatchesName() {
+        val route = mockRouteInfo().apply { whenever(this.getName(context)).thenReturn("FakeName") }
+
+        val device = route.toCastDevice(context)
+
+        assertThat(device.name).isEqualTo("FakeName")
+    }
+
+    @Test
+    fun routeToCastDevice_descriptionMatchesDescription() {
+        val route =
+            mockRouteInfo().apply { whenever(this.description).thenReturn("FakeDescription") }
+
+        val device = route.toCastDevice(context)
+
+        assertThat(device.description).isEqualTo("FakeDescription")
+    }
+
+    @Test
+    fun routeToCastDevice_tagIsRoute() {
+        val route = mockRouteInfo()
+
+        val device = route.toCastDevice(context)
+
+        assertThat(device.tag).isEqualTo(route)
+    }
+
+    @Test
+    fun routeToCastDevice_originIsMediaRouter() {
+        val route = mockRouteInfo()
+
+        val device = route.toCastDevice(context)
+
+        assertThat(device.origin).isEqualTo(CastDevice.CastOrigin.MediaRouter)
+    }
+
+    @Test
+    fun routeToCastDevice_nullValues_ok() {
+        val device = mockRouteInfo().toCastDevice(context)
+
+        assertThat(device.name).isNull()
+        assertThat(device.description).isNull()
+    }
+
+    @Test
+    fun projectionToCastDevice_idMatchesPackage() {
+        val projection =
+            mock<MediaProjectionInfo>().apply {
+                whenever(this.packageName).thenReturn("fake.package")
+            }
+
+        val device = projection.toCastDevice(context, packageManager)
+
+        assertThat(device.id).isEqualTo("fake.package")
+    }
+
+    @Test
+    fun projectionToCastDevice_name_packageIsHeadlessRemote_isEmpty() {
+        val projection =
+            mock<MediaProjectionInfo>().apply {
+                whenever(this.packageName).thenReturn(HEADLESS_REMOTE_PACKAGE)
+            }
+
+        val device = projection.toCastDevice(context, packageManager)
+
+        assertThat(device.name).isEmpty()
+    }
+
+    @Test
+    fun projectionToCastDevice_name_packageMissingFromPackageManager_isPackageName() {
+        val projection =
+            mock<MediaProjectionInfo>().apply {
+                whenever(this.packageName).thenReturn(NORMAL_PACKAGE)
+            }
+
+        whenever(packageManager.getApplicationInfo(eq(NORMAL_PACKAGE), any<Int>()))
+            .thenThrow(PackageManager.NameNotFoundException())
+
+        val device = projection.toCastDevice(context, packageManager)
+
+        assertThat(device.name).isEqualTo(NORMAL_PACKAGE)
+    }
+
+    @Test
+    fun projectionToCastDevice_name_nameFromPackageManagerEmpty_isPackageName() {
+        val projection =
+            mock<MediaProjectionInfo>().apply {
+                whenever(this.packageName).thenReturn(NORMAL_PACKAGE)
+            }
+
+        val appInfo = mock<ApplicationInfo>()
+        whenever(appInfo.loadLabel(packageManager)).thenReturn("")
+        whenever(packageManager.getApplicationInfo(eq(NORMAL_PACKAGE), any<Int>()))
+            .thenReturn(appInfo)
+
+        val device = projection.toCastDevice(context, packageManager)
+
+        assertThat(device.name).isEqualTo(NORMAL_PACKAGE)
+    }
+
+    @Test
+    fun projectionToCastDevice_name_packageManagerHasName_isName() {
+        val projection =
+            mock<MediaProjectionInfo>().apply {
+                whenever(this.packageName).thenReturn(NORMAL_PACKAGE)
+            }
+
+        val appInfo = mock<ApplicationInfo>()
+        whenever(appInfo.loadLabel(packageManager)).thenReturn("Valid App Name")
+        whenever(packageManager.getApplicationInfo(eq(NORMAL_PACKAGE), any<Int>()))
+            .thenReturn(appInfo)
+
+        val device = projection.toCastDevice(context, packageManager)
+
+        assertThat(device.name).isEqualTo("Valid App Name")
+    }
+
+    @Test
+    fun projectionToCastDevice_descriptionIsCasting() {
+        val projection = mockProjectionInfo()
+
+        val device = projection.toCastDevice(context, packageManager)
+
+        assertThat(device.description).isEqualTo(context.getString(R.string.quick_settings_casting))
+    }
+
+    @Test
+    fun projectionToCastDevice_stateIsConnected() {
+        val projection = mockProjectionInfo()
+
+        val device = projection.toCastDevice(context, packageManager)
+
+        assertThat(device.state).isEqualTo(CastDevice.CastState.Connected)
+    }
+
+    @Test
+    fun projectionToCastDevice_tagIsProjection() {
+        val projection = mockProjectionInfo()
+
+        val device = projection.toCastDevice(context, packageManager)
+
+        assertThat(device.tag).isEqualTo(projection)
+    }
+
+    @Test
+    fun projectionToCastDevice_originIsMediaProjection() {
+        val projection = mockProjectionInfo()
+
+        val device = projection.toCastDevice(context, packageManager)
+
+        assertThat(device.origin).isEqualTo(CastDevice.CastOrigin.MediaProjection)
+    }
+
+    private fun mockRouteInfo(): MediaRouter.RouteInfo {
+        return mock<MediaRouter.RouteInfo>().apply { whenever(this.tag).thenReturn(Any()) }
+    }
+
+    private fun mockProjectionInfo(): MediaProjectionInfo {
+        return mock<MediaProjectionInfo>().apply {
+            whenever(this.packageName).thenReturn("fake.package")
+        }
+    }
+
+    private companion object {
+        const val HEADLESS_REMOTE_PACKAGE = "headless.remote.package"
+        const val NORMAL_PACKAGE = "normal.package"
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ClockTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ClockTest.kt
index 22c72cc..7549a7f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ClockTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ClockTest.kt
@@ -16,12 +16,12 @@
 
 package com.android.systemui.statusbar.policy
 
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.View.MeasureSpec.UNSPECIFIED
 import android.view.View.MeasureSpec.makeMeasureSpec
 import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
 import android.widget.LinearLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import org.junit.Before
@@ -31,7 +31,7 @@
 import org.junit.Test
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
 class ClockTest : SysuiTestCase() {
     private lateinit var clockView: Clock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt
index c606511..f871d27 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DevicePostureControllerImplTest.kt
@@ -18,9 +18,9 @@
 
 import android.hardware.devicestate.DeviceState
 import android.hardware.devicestate.DeviceStateManager
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.testing.TestableResources
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_CLOSED
@@ -44,7 +44,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 class DevicePostureControllerImplTest : SysuiTestCase() {
     private val useBaseStateDeviceState = SUPPORTED_POSTURES_SIZE
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImplTest.kt
index 31bd57e..649a4ab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImplTest.kt
@@ -18,8 +18,8 @@
 
 import android.os.Handler
 import android.provider.Settings
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
@@ -45,7 +45,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
 class DeviceProvisionedControllerImplTest : SysuiTestCase() {
 
@@ -246,4 +246,4 @@
         `when`(userTracker.userId).thenReturn(toUser)
         userTrackerCallbackCaptor.value.onUserChanged(toUser, mContext)
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java
index 683136d..f5efd6d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ExtensionControllerImplTest.java
@@ -23,10 +23,10 @@
 import static org.mockito.Mockito.when;
 
 import android.content.res.Configuration;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -51,7 +51,7 @@
 import java.util.Map;
 import java.util.function.Consumer;
 
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class ExtensionControllerImplTest extends SysuiTestCase {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java
index 784fb71..3721b0e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HotspotControllerImplTest.java
@@ -33,9 +33,9 @@
 import android.net.wifi.WifiManager;
 import android.os.Handler;
 import android.os.UserManager;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -57,7 +57,7 @@
 import java.util.concurrent.Executor;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @TestableLooper.RunWithLooper
 public class HotspotControllerImplTest extends SysuiTestCase {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt
index 1250228..b7a3515 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt
@@ -16,12 +16,12 @@
 
 package com.android.systemui.statusbar.policy
 
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.testing.ViewUtils
 import android.view.LayoutInflater
 import android.view.View
 import android.widget.FrameLayout
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.res.R
@@ -45,7 +45,7 @@
 
 @SmallTest
 @TestableLooper.RunWithLooper
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class KeyguardQsUserSwitchControllerTest : SysuiTestCase() {
     @Mock
     private lateinit var userSwitcherController: UserSwitcherController
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java
index 3a086ae..aed9af6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java
@@ -25,9 +25,9 @@
 import static org.mockito.Mockito.when;
 
 import android.hardware.biometrics.BiometricSourceType;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.widget.LockPatternUtils;
@@ -54,7 +54,7 @@
 
 @SmallTest
 @TestableLooper.RunWithLooper
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 public class KeyguardStateControllerTest extends SysuiTestCase {
 
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt
index 635d63e..750f0c6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt
@@ -15,8 +15,8 @@
 
 import android.app.StatusBarManager
 import android.content.res.Configuration
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 
 import com.android.systemui.res.R
@@ -35,7 +35,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @RunWithLooper
 class RemoteInputQuickSettingsDisablerTest : SysuiTestCase() {
 
@@ -134,4 +134,4 @@
     private fun shouldDisableQs(state: Int): Boolean {
         return state and StatusBarManager.DISABLE2_QUICK_SETTINGS != 0
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
index 70afbd8..ffe7750 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
@@ -247,7 +247,7 @@
         ExpandableNotificationRow row = helper.createRow();
         RemoteInputView view = RemoteInputView.inflate(mContext, null, row.getEntry(), mController);
 
-        view.addOnVisibilityChangedListener(null);
+        view.setOnVisibilityChangedListener(null);
         view.setVisibility(View.INVISIBLE);
         view.setVisibility(View.VISIBLE);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
index a9681e0..36e3052 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyConstantsTest.java
@@ -22,10 +22,10 @@
 
 import android.app.RemoteInput;
 import android.provider.DeviceConfig;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableResources;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
@@ -39,7 +39,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @TestableLooper.RunWithLooper
 @SmallTest
 public class SmartReplyConstantsTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java
index ddd29c3..637a0f1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java
@@ -27,10 +27,10 @@
 import android.os.Handler;
 import android.provider.Settings;
 import android.service.notification.ZenModeConfig;
-import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -51,7 +51,7 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 @RunWithLooper
 public class ZenModeControllerImplTest extends SysuiTestCase {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt
index 6f40f15..94f0d19 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/bluetooth/BluetoothRepositoryImplTest.kt
@@ -15,6 +15,7 @@
 package com.android.systemui.statusbar.policy.bluetooth
 
 import android.bluetooth.BluetoothProfile
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.settingslib.bluetooth.CachedBluetoothDevice
 import com.android.settingslib.bluetooth.LocalBluetoothAdapter
@@ -30,11 +31,13 @@
 import kotlinx.coroutines.test.TestScope
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.MockitoAnnotations
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class BluetoothRepositoryImplTest : SysuiTestCase() {
 
     private lateinit var underTest: BluetoothRepositoryImpl
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/data/repository/ZenModeRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/data/repository/ZenModeRepositoryImplTest.kt
deleted file mode 100644
index 004f679..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/data/repository/ZenModeRepositoryImplTest.kt
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
-package com.android.systemui.statusbar.policy.data.repository
-
-import android.app.NotificationManager
-import android.provider.Settings
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.statusbar.policy.ZenModeController
-import com.android.systemui.util.mockito.whenever
-import com.android.systemui.util.mockito.withArgCaptor
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.runCurrent
-import kotlinx.coroutines.test.runTest
-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
-
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class ZenModeRepositoryImplTest : SysuiTestCase() {
-    @Mock lateinit var zenModeController: ZenModeController
-
-    lateinit var underTest: ZenModeRepositoryImpl
-
-    private val testPolicy = NotificationManager.Policy(0, 1, 0)
-
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-        underTest = ZenModeRepositoryImpl(zenModeController)
-    }
-
-    @Test
-    fun zenMode_reflectsCurrentControllerState() = runTest {
-        whenever(zenModeController.zen).thenReturn(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS)
-        val zenMode by collectLastValue(underTest.zenMode)
-        assertThat(zenMode).isEqualTo(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS)
-    }
-
-    @Test
-    fun zenMode_updatesWhenControllerStateChanges() = runTest {
-        val zenMode by collectLastValue(underTest.zenMode)
-        runCurrent()
-        whenever(zenModeController.zen).thenReturn(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
-        withArgCaptor { Mockito.verify(zenModeController).addCallback(capture()) }
-            .onZenChanged(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
-        assertThat(zenMode).isEqualTo(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
-    }
-
-    @Test
-    fun policy_reflectsCurrentControllerState() {
-        runTest {
-            whenever(zenModeController.consolidatedPolicy).thenReturn(testPolicy)
-            val policy by collectLastValue(underTest.consolidatedNotificationPolicy)
-            assertThat(policy).isEqualTo(testPolicy)
-        }
-    }
-
-    @Test
-    fun policy_updatesWhenControllerStateChanges() = runTest {
-        val policy by collectLastValue(underTest.consolidatedNotificationPolicy)
-        runCurrent()
-        whenever(zenModeController.consolidatedPolicy).thenReturn(testPolicy)
-        withArgCaptor { Mockito.verify(zenModeController).addCallback(capture()) }
-            .onConsolidatedPolicyChanged(testPolicy)
-        assertThat(policy).isEqualTo(testPolicy)
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorTest.kt
deleted file mode 100644
index dbb1062..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/domain/interactor/ZenModeInteractorTest.kt
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.policy.domain.interactor
-
-import android.app.NotificationManager.Policy
-import android.provider.Settings
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysUITestComponent
-import com.android.systemui.SysUITestModule
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.collectLastValue
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.runCurrent
-import com.android.systemui.runTest
-import com.android.systemui.statusbar.policy.data.repository.FakeZenModeRepository
-import com.android.systemui.user.domain.UserDomainLayerModule
-import com.google.common.truth.Truth.assertThat
-import dagger.BindsInstance
-import dagger.Component
-import org.junit.Test
-
-@SmallTest
-class ZenModeInteractorTest : SysuiTestCase() {
-    @SysUISingleton
-    @Component(
-        modules =
-            [
-                SysUITestModule::class,
-                UserDomainLayerModule::class,
-            ]
-    )
-    interface TestComponent : SysUITestComponent<ZenModeInteractor> {
-
-        val repository: FakeZenModeRepository
-
-        @Component.Factory
-        interface Factory {
-            fun create(@BindsInstance test: SysuiTestCase): TestComponent
-        }
-    }
-
-    private val testComponent: TestComponent =
-        DaggerZenModeInteractorTest_TestComponent.factory().create(test = this)
-
-    @Test
-    fun testIsZenModeEnabled_off() =
-        testComponent.runTest {
-            val enabled by collectLastValue(underTest.isZenModeEnabled)
-
-            repository.zenMode.value = Settings.Global.ZEN_MODE_OFF
-            runCurrent()
-
-            assertThat(enabled).isFalse()
-        }
-
-    @Test
-    fun testIsZenModeEnabled_alarms() =
-        testComponent.runTest {
-            val enabled by collectLastValue(underTest.isZenModeEnabled)
-
-            repository.zenMode.value = Settings.Global.ZEN_MODE_ALARMS
-            runCurrent()
-
-            assertThat(enabled).isTrue()
-        }
-
-    @Test
-    fun testIsZenModeEnabled_importantInterruptions() =
-        testComponent.runTest {
-            val enabled by collectLastValue(underTest.isZenModeEnabled)
-
-            repository.zenMode.value = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
-            runCurrent()
-
-            assertThat(enabled).isTrue()
-        }
-
-    @Test
-    fun testIsZenModeEnabled_noInterruptions() =
-        testComponent.runTest {
-            val enabled by collectLastValue(underTest.isZenModeEnabled)
-
-            repository.zenMode.value = Settings.Global.ZEN_MODE_NO_INTERRUPTIONS
-            runCurrent()
-
-            assertThat(enabled).isTrue()
-        }
-
-    @Test
-    fun testIsZenModeEnabled_unknown() =
-        testComponent.runTest {
-            val enabled by collectLastValue(underTest.isZenModeEnabled)
-
-            repository.zenMode.value = 4 // this should fail if we ever add another zen mode type
-            runCurrent()
-
-            assertThat(enabled).isFalse()
-        }
-
-    @Test
-    fun testAreNotificationsHiddenInShade_noPolicy() =
-        testComponent.runTest {
-            val hidden by collectLastValue(underTest.areNotificationsHiddenInShade)
-
-            repository.consolidatedNotificationPolicy.value = null
-            repository.zenMode.value = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
-            runCurrent()
-
-            assertThat(hidden).isFalse()
-        }
-
-    @Test
-    fun testAreNotificationsHiddenInShade_zenOffShadeSuppressed() =
-        testComponent.runTest {
-            val hidden by collectLastValue(underTest.areNotificationsHiddenInShade)
-
-            repository.setSuppressedVisualEffects(Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST)
-            repository.zenMode.value = Settings.Global.ZEN_MODE_OFF
-            runCurrent()
-
-            assertThat(hidden).isFalse()
-        }
-
-    @Test
-    fun testAreNotificationsHiddenInShade_zenOnShadeNotSuppressed() =
-        testComponent.runTest {
-            val hidden by collectLastValue(underTest.areNotificationsHiddenInShade)
-
-            repository.setSuppressedVisualEffects(Policy.SUPPRESSED_EFFECT_STATUS_BAR)
-            repository.zenMode.value = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
-            runCurrent()
-
-            assertThat(hidden).isFalse()
-        }
-
-    @Test
-    fun testAreNotificationsHiddenInShade_zenOnShadeSuppressed() =
-        testComponent.runTest {
-            val hidden by collectLastValue(underTest.areNotificationsHiddenInShade)
-
-            repository.setSuppressedVisualEffects(Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST)
-            repository.zenMode.value = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
-            runCurrent()
-
-            assertThat(hidden).isTrue()
-        }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
index d88289d..ef4e734 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelTest.kt
@@ -26,8 +26,10 @@
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
-import com.android.systemui.keyguard.shared.model.StatusBarState
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.data.repository.sceneContainerRepository
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.statusbar.domain.interactor.keyguardStatusBarInteractor
 import com.android.systemui.statusbar.notification.data.repository.FakeHeadsUpRowRepository
 import com.android.systemui.statusbar.notification.stack.data.repository.headsUpNotificationRepository
@@ -85,6 +87,7 @@
             KeyguardStatusBarViewModel(
                 testScope.backgroundScope,
                 headsUpNotificationInteractor,
+                kosmos.sceneInteractor,
                 keyguardInteractor,
                 keyguardStatusBarInteractor,
                 batteryController,
@@ -95,7 +98,7 @@
     fun isVisible_dozing_false() =
         testScope.runTest {
             val latest by collectLastValue(underTest.isVisible)
-            keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
+            kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
 
             keyguardRepository.setIsDozing(true)
 
@@ -103,21 +106,21 @@
         }
 
     @Test
-    fun isVisible_statusBarStateShade_false() =
+    fun isVisible_sceneShade_false() =
         testScope.runTest {
             val latest by collectLastValue(underTest.isVisible)
 
-            keyguardRepository.setStatusBarState(StatusBarState.SHADE)
+            kosmos.sceneContainerRepository.snapToScene(Scenes.Shade)
 
             assertThat(latest).isFalse()
         }
 
     @Test
-    fun isVisible_statusBarStateShadeLocked_false() =
+    fun isVisible_sceneBouncer_false() =
         testScope.runTest {
             val latest by collectLastValue(underTest.isVisible)
 
-            keyguardRepository.setStatusBarState(StatusBarState.SHADE_LOCKED)
+            kosmos.sceneContainerRepository.snapToScene(Scenes.Bouncer)
 
             assertThat(latest).isFalse()
         }
@@ -130,7 +133,7 @@
             // WHEN HUN displayed on the bypass lock screen
             headsUpRepository.setNotifications(FakeHeadsUpRowRepository("key 0", isPinned = true))
             keyguardTransitionRepository.emitInitialStepsFromOff(KeyguardState.LOCKSCREEN)
-            keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
+            kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
             faceAuthRepository.isBypassEnabled.value = true
 
             // THEN KeyguardStatusBar is NOT visible to make space for HeadsUpStatusBar
@@ -138,11 +141,11 @@
         }
 
     @Test
-    fun isVisible_statusBarStateKeyguard_andNotDozing_andNotShowingHeadsUpStatusBar_true() =
+    fun isVisible_sceneLockscreen_andNotDozing_andNotShowingHeadsUpStatusBar_true() =
         testScope.runTest {
             val latest by collectLastValue(underTest.isVisible)
 
-            keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
+            kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
             keyguardRepository.setIsDozing(false)
 
             assertThat(latest).isTrue()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt
index 8576d4f..03a25e3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt
@@ -21,18 +21,21 @@
 import android.app.StatusBarManager.WINDOW_STATE_HIDDEN
 import android.app.StatusBarManager.WINDOW_STATE_SHOWING
 import android.app.StatusBarManager.WINDOW_STATUS_BAR
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.CommandQueue
 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.verify
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class StatusBarWindowStateControllerTest : SysuiTestCase() {
     private lateinit var controller: StatusBarWindowStateController
     private lateinit var callback: CommandQueue.Callbacks
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
index 5b9db4b..5603ff0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusUsiPowerUiTest.kt
@@ -31,8 +31,8 @@
 import com.android.internal.logging.InstanceId
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.InstanceIdSequenceFake
-import com.android.systemui.res.R
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.res.R
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.eq
@@ -109,6 +109,14 @@
     }
 
     @Test
+    fun updateBatteryState_capacityNaN_cancelsNotification() {
+        stylusUsiPowerUi.updateBatteryState(0, FixedCapacityBatteryState(Float.NaN))
+
+        verify(notificationManager, times(1)).cancel(R.string.stylus_battery_low_percentage)
+        verifyNoMoreInteractions(notificationManager)
+    }
+
+    @Test
     fun updateBatteryState_capacityBelowThreshold_notifies() {
         stylusUsiPowerUi.updateBatteryState(0, FixedCapacityBatteryState(0.1f))
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/glowboxeffect/GlowBoxEffectTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/glowboxeffect/GlowBoxEffectTest.kt
index 16132ba..32ef501 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/glowboxeffect/GlowBoxEffectTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/glowboxeffect/GlowBoxEffectTest.kt
@@ -18,8 +18,8 @@
 
 import android.graphics.Color
 import android.graphics.Paint
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.AnimatorTestRule
@@ -31,7 +31,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 class GlowBoxEffectTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/loadingeffect/LoadingEffectTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/loadingeffect/LoadingEffectTest.kt
index 41d7fd5..67a4219 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/loadingeffect/LoadingEffectTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/loadingeffect/LoadingEffectTest.kt
@@ -18,8 +18,8 @@
 
 import android.graphics.Paint
 import android.graphics.RenderEffect
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.AnimatorTestRule
@@ -33,7 +33,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 class LoadingEffectTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/MultiRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/MultiRippleControllerTest.kt
index 0d19ab1..a5afe1e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/MultiRippleControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/MultiRippleControllerTest.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.surfaceeffects.ripple
 
 import android.graphics.Color
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.surfaceeffects.ripple.MultiRippleController.Companion.MAX_RIPPLE_NUMBER
@@ -29,7 +29,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class MultiRippleControllerTest : SysuiTestCase() {
     private lateinit var multiRippleController: MultiRippleController
     private lateinit var multiRippleView: MultiRippleView
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationTest.kt
index 74ed7fb..8dafa82 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationTest.kt
@@ -17,8 +17,8 @@
 package com.android.systemui.surfaceeffects.ripple
 
 import android.graphics.Color
-import android.testing.AndroidTestingRunner
 import androidx.core.graphics.ColorUtils
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.concurrency.FakeExecutor
@@ -28,7 +28,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class RippleAnimationTest : SysuiTestCase() {
 
     private val fakeSystemClock = FakeSystemClock()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleShaderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleShaderTest.kt
index 89cc18cc..2fee2a4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleShaderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleShaderTest.kt
@@ -15,7 +15,7 @@
  */
 package com.android.systemui.surfaceeffects.ripple
 
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
@@ -24,7 +24,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class RippleShaderTest : SysuiTestCase() {
 
     private lateinit var rippleShader: RippleShader
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleViewTest.kt
index 1e5ab7e..18644ab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/ripple/RippleViewTest.kt
@@ -15,7 +15,7 @@
  */
 package com.android.systemui.surfaceeffects.ripple
 
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import org.junit.Before
@@ -23,7 +23,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class RippleViewTest : SysuiTestCase() {
     private lateinit var rippleView: RippleView
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SolidColorShaderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SolidColorShaderTest.kt
index f1fadf6..fbd3eae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SolidColorShaderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SolidColorShaderTest.kt
@@ -16,14 +16,14 @@
 package com.android.systemui.surfaceeffects.shaders
 
 import android.graphics.Color
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class SolidColorShaderTest : SysuiTestCase() {
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SparkleShaderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SparkleShaderTest.kt
index 64ea6a6..d32bffb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SparkleShaderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/shaders/SparkleShaderTest.kt
@@ -16,14 +16,14 @@
 package com.android.systemui.surfaceeffects.shaders
 
 import android.graphics.Color
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class SparkleShaderTest : SysuiTestCase() {
 
     private lateinit var sparkleShader: SparkleShader
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseControllerTest.kt
index 08b49f0..4ba6438 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseControllerTest.kt
@@ -16,9 +16,9 @@
 package com.android.systemui.surfaceeffects.turbulencenoise
 
 import android.graphics.Color
-import android.testing.AndroidTestingRunner
 import android.view.View.INVISIBLE
 import android.view.View.VISIBLE
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseController.Companion.AnimationState.EASE_IN
@@ -33,7 +33,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class TurbulenceNoiseControllerTest : SysuiTestCase() {
     private val fakeSystemClock = FakeSystemClock()
     // FakeExecutor is needed to run animator.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShaderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShaderTest.kt
index e62ca64..286f017 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShaderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShaderTest.kt
@@ -15,7 +15,7 @@
  */
 package com.android.systemui.surfaceeffects.turbulencenoise
 
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseShader.Companion.Type.SIMPLEX_NOISE
@@ -25,7 +25,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class TurbulenceNoiseShaderTest : SysuiTestCase() {
 
     private lateinit var turbulenceNoiseShader: TurbulenceNoiseShader
diff --git a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseViewTest.kt
index 953071c..e09d4ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseViewTest.kt
@@ -16,7 +16,7 @@
 package com.android.systemui.surfaceeffects.turbulencenoise
 
 import android.graphics.Color
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseShader.Companion.Type.SIMPLEX_NOISE
@@ -28,7 +28,7 @@
 import org.junit.runner.RunWith
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 class TurbulenceNoiseViewTest : SysuiTestCase() {
 
     private val fakeSystemClock = FakeSystemClock()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
index ae4dfbd..bb6ba46 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewDisplayControllerTest.kt
@@ -23,6 +23,7 @@
 import android.view.ViewGroup
 import android.view.WindowManager
 import android.view.accessibility.AccessibilityManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
 import com.android.internal.logging.testing.UiEventLoggerFake
@@ -44,6 +45,7 @@
 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.never
 import org.mockito.Mockito.reset
@@ -53,6 +55,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class TemporaryViewDisplayControllerTest : SysuiTestCase() {
     private lateinit var underTest: TestController
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt
index 38c1a78..1dfd934 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewLoggerTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.temporarydisplay
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
 import com.android.systemui.SysuiTestCase
@@ -28,9 +29,11 @@
 import java.io.StringWriter
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 import org.mockito.Mockito
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class TemporaryViewLoggerTest : SysuiTestCase() {
     private lateinit var buffer: LogBuffer
     private lateinit var logger: TemporaryViewLogger<TemporaryViewInfo>
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewUiEventLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewUiEventLoggerTest.kt
index f707a8da..281ecfb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewUiEventLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TemporaryViewUiEventLoggerTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.temporarydisplay
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.InstanceId
 import com.android.internal.logging.testing.UiEventLoggerFake
@@ -23,8 +24,10 @@
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class TemporaryViewUiEventLoggerTest : SysuiTestCase() {
     private lateinit var uiEventLoggerFake: UiEventLoggerFake
     private lateinit var logger: TemporaryViewUiEventLogger
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TouchableRegionViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TouchableRegionViewControllerTest.kt
index 7586fe4..a230f06 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TouchableRegionViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/TouchableRegionViewControllerTest.kt
@@ -19,12 +19,14 @@
 import android.graphics.Rect
 import android.view.View
 import android.view.ViewTreeObserver
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.any
 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.verify
@@ -32,6 +34,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class TouchableRegionViewControllerTest : SysuiTestCase() {
 
     @Mock private lateinit var view: View
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandlerTest.kt
index c539246..75d031d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandlerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/SwipeChipbarAwayGestureHandlerTest.kt
@@ -19,6 +19,7 @@
 import android.graphics.Rect
 import android.view.MotionEvent
 import android.view.View
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer
 import com.android.systemui.SysuiTestCase
@@ -29,8 +30,10 @@
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
+@RunWith(AndroidJUnit4::class)
 class SwipeChipbarAwayGestureHandlerTest : SysuiTestCase() {
 
     private lateinit var underTest: SwipeChipbarAwayGestureHandler
diff --git a/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/TouchpadTutorialViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/TouchpadTutorialViewModelTest.kt
new file mode 100644
index 0000000..2300a1f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/TouchpadTutorialViewModelTest.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.touchpad.tutorial.ui
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.model.sysUiState
+import com.android.systemui.settings.displayTracker
+import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED
+import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags
+import com.android.systemui.testKosmos
+import com.android.systemui.touchpad.tutorial.domain.interactor.TouchpadGesturesInteractor
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class TouchpadTutorialViewModelTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos()
+    private val testScope = TestScope()
+    private val sysUiState = kosmos.sysUiState
+    private val viewModel =
+        TouchpadTutorialViewModel(
+            TouchpadGesturesInteractor(sysUiState, kosmos.displayTracker, testScope.backgroundScope)
+        )
+
+    @Test
+    fun sysUiStateFlag_disabledByDefault() =
+        testScope.runTest {
+            assertThat(isFlagEnabled(SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED)).isFalse()
+        }
+
+    @Test
+    fun sysUiStateFlag_enabledAfterTutorialOpened() =
+        testScope.runTest {
+            viewModel.onOpened()
+
+            assertThat(isFlagEnabled(SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED)).isTrue()
+        }
+
+    @Test
+    fun sysUiStateFlag_disabledAfterTutorialClosed() =
+        testScope.runTest {
+            viewModel.onOpened()
+            viewModel.onClosed()
+
+            assertThat(isFlagEnabled(SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED)).isFalse()
+        }
+
+    private fun TestScope.isFlagEnabled(@SystemUiStateFlags flag: Long): Boolean {
+        // sysui state is changed on background scope so let's make sure it's executed
+        runCurrent()
+        return sysUiState.isFlagEnabled(flag)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitorTest.kt
new file mode 100644
index 0000000..cf0db7b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/BackGestureMonitorTest.kt
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.touchpad.tutorial.ui.gesture
+
+import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_DOWN
+import android.view.MotionEvent.ACTION_MOVE
+import android.view.MotionEvent.ACTION_POINTER_DOWN
+import android.view.MotionEvent.ACTION_POINTER_UP
+import android.view.MotionEvent.ACTION_UP
+import android.view.MotionEvent.AXIS_GESTURE_SWIPE_FINGER_COUNT
+import android.view.MotionEvent.CLASSIFICATION_MULTI_FINGER_SWIPE
+import android.view.MotionEvent.CLASSIFICATION_TWO_FINGER_SWIPE
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class BackGestureMonitorTest : SysuiTestCase() {
+
+    private var gestureDoneWasCalled = false
+    private val gestureDoneCallback = { gestureDoneWasCalled = true }
+    private val gestureMonitor = BackGestureMonitor(SWIPE_DISTANCE.toInt(), gestureDoneCallback)
+
+    companion object {
+        const val SWIPE_DISTANCE = 100f
+    }
+
+    @Test
+    fun triggersGestureDoneForThreeFingerGestureRight() {
+        val events =
+            listOf(
+                threeFingerEvent(ACTION_DOWN, x = 0f, y = 0f),
+                threeFingerEvent(ACTION_POINTER_DOWN, x = 0f, y = 0f),
+                threeFingerEvent(ACTION_POINTER_DOWN, x = 0f, y = 0f),
+                threeFingerEvent(ACTION_MOVE, x = SWIPE_DISTANCE / 2, y = 0f),
+                threeFingerEvent(ACTION_POINTER_UP, x = SWIPE_DISTANCE, y = 0f),
+                threeFingerEvent(ACTION_POINTER_UP, x = SWIPE_DISTANCE, y = 0f),
+                threeFingerEvent(ACTION_UP, x = SWIPE_DISTANCE, y = 0f),
+            )
+
+        events.forEach { gestureMonitor.processTouchpadEvent(it) }
+
+        assertThat(gestureDoneWasCalled).isTrue()
+    }
+
+    @Test
+    fun triggersGestureDoneForThreeFingerGestureLeft() {
+        val events =
+            listOf(
+                threeFingerEvent(ACTION_DOWN, x = SWIPE_DISTANCE, y = 0f),
+                threeFingerEvent(ACTION_POINTER_DOWN, x = SWIPE_DISTANCE, y = 0f),
+                threeFingerEvent(ACTION_POINTER_DOWN, x = SWIPE_DISTANCE, y = 0f),
+                threeFingerEvent(ACTION_MOVE, x = SWIPE_DISTANCE / 2, y = 0f),
+                threeFingerEvent(ACTION_POINTER_UP, x = 0f, y = 0f),
+                threeFingerEvent(ACTION_POINTER_UP, x = 0f, y = 0f),
+                threeFingerEvent(ACTION_UP, x = 0f, y = 0f),
+            )
+
+        events.forEach { gestureMonitor.processTouchpadEvent(it) }
+
+        assertThat(gestureDoneWasCalled).isTrue()
+    }
+
+    private fun threeFingerEvent(action: Int, x: Float, y: Float): MotionEvent {
+        return motionEvent(
+            action = action,
+            x = x,
+            y = y,
+            classification = CLASSIFICATION_MULTI_FINGER_SWIPE,
+            axisValues = mapOf(AXIS_GESTURE_SWIPE_FINGER_COUNT to 3f)
+        )
+    }
+
+    @Test
+    fun doesntTriggerGestureDone_onThreeFingersSwipeUp() {
+        val events =
+            listOf(
+                threeFingerEvent(ACTION_DOWN, x = 0f, y = 0f),
+                threeFingerEvent(ACTION_POINTER_DOWN, x = 0f, y = 0f),
+                threeFingerEvent(ACTION_POINTER_DOWN, x = 0f, y = 0f),
+                threeFingerEvent(ACTION_MOVE, x = 0f, y = SWIPE_DISTANCE / 2),
+                threeFingerEvent(ACTION_POINTER_UP, x = 0f, y = SWIPE_DISTANCE),
+                threeFingerEvent(ACTION_POINTER_UP, x = 0f, y = SWIPE_DISTANCE),
+                threeFingerEvent(ACTION_UP, x = 0f, y = SWIPE_DISTANCE),
+            )
+
+        events.forEach { gestureMonitor.processTouchpadEvent(it) }
+
+        assertThat(gestureDoneWasCalled).isFalse()
+    }
+
+    @Test
+    fun doesntTriggerGestureDone_onTwoFingersSwipe() {
+        fun twoFingerEvent(action: Int, x: Float, y: Float) =
+            motionEvent(
+                action = action,
+                x = x,
+                y = y,
+                classification = CLASSIFICATION_TWO_FINGER_SWIPE,
+                axisValues = mapOf(AXIS_GESTURE_SWIPE_FINGER_COUNT to 2f)
+            )
+        val events =
+            listOf(
+                twoFingerEvent(ACTION_DOWN, x = 0f, y = 0f),
+                twoFingerEvent(ACTION_MOVE, x = SWIPE_DISTANCE / 2, y = 0f),
+                twoFingerEvent(ACTION_UP, x = SWIPE_DISTANCE, y = 0f),
+            )
+
+        events.forEach { gestureMonitor.processTouchpadEvent(it) }
+
+        assertThat(gestureDoneWasCalled).isFalse()
+    }
+
+    @Test
+    fun doesntTriggerGestureDone_onFourFingersSwipe() {
+        fun fourFingerEvent(action: Int, x: Float, y: Float) =
+            motionEvent(
+                action = action,
+                x = x,
+                y = y,
+                classification = CLASSIFICATION_MULTI_FINGER_SWIPE,
+                axisValues = mapOf(AXIS_GESTURE_SWIPE_FINGER_COUNT to 4f)
+            )
+        val events =
+            listOf(
+                fourFingerEvent(ACTION_DOWN, x = 0f, y = 0f),
+                fourFingerEvent(ACTION_POINTER_DOWN, x = 0f, y = 0f),
+                fourFingerEvent(ACTION_POINTER_DOWN, x = 0f, y = 0f),
+                fourFingerEvent(ACTION_POINTER_DOWN, x = 0f, y = 0f),
+                fourFingerEvent(ACTION_MOVE, x = SWIPE_DISTANCE / 2, y = 0f),
+                fourFingerEvent(ACTION_POINTER_UP, x = SWIPE_DISTANCE, y = 0f),
+                fourFingerEvent(ACTION_POINTER_UP, x = SWIPE_DISTANCE, y = 0f),
+                fourFingerEvent(ACTION_POINTER_UP, x = SWIPE_DISTANCE, y = 0f),
+                fourFingerEvent(ACTION_UP, x = SWIPE_DISTANCE, y = 0f),
+            )
+
+        events.forEach { gestureMonitor.processTouchpadEvent(it) }
+
+        assertThat(gestureDoneWasCalled).isFalse()
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/FakeMotionEvent.kt b/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/FakeMotionEvent.kt
new file mode 100644
index 0000000..e632e34
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/FakeMotionEvent.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.touchpad.tutorial.ui.gesture
+
+import android.view.InputDevice.SOURCE_CLASS_POINTER
+import android.view.InputDevice.SOURCE_MOUSE
+import android.view.MotionEvent
+import android.view.MotionEvent.CLASSIFICATION_NONE
+import android.view.MotionEvent.TOOL_TYPE_FINGER
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.spy
+
+fun motionEvent(
+    action: Int,
+    x: Float,
+    y: Float,
+    source: Int = 0,
+    toolType: Int = TOOL_TYPE_FINGER,
+    pointerCount: Int = 1,
+    axisValues: Map<Int, Float> = emptyMap(),
+    classification: Int = CLASSIFICATION_NONE,
+): MotionEvent {
+    val event =
+        MotionEvent.obtain(/* downTime= */ 0, /* eventTime= */ 0, action, x, y, /* metaState= */ 0)
+    event.source = source
+    return spy<MotionEvent>(event) {
+        on { getToolType(0) } doReturn toolType
+        on { getPointerCount() } doReturn pointerCount
+        axisValues.forEach { (key, value) -> on { getAxisValue(key) } doReturn value }
+        on { getClassification() } doReturn classification
+    }
+}
+
+fun touchpadEvent(
+    action: Int,
+    x: Float,
+    y: Float,
+    pointerCount: Int = 1,
+    classification: Int = CLASSIFICATION_NONE,
+    axisValues: Map<Int, Float> = emptyMap()
+): MotionEvent {
+    return motionEvent(
+        action = action,
+        x = x,
+        y = y,
+        source = SOURCE_MOUSE or SOURCE_CLASS_POINTER,
+        toolType = TOOL_TYPE_FINGER,
+        pointerCount = pointerCount,
+        classification = classification,
+        axisValues = axisValues
+    )
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandlerTest.kt
new file mode 100644
index 0000000..769f264
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/touchpad/tutorial/ui/gesture/TouchpadGestureHandlerTest.kt
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.touchpad.tutorial.ui.gesture
+
+import android.view.InputDevice.SOURCE_MOUSE
+import android.view.InputDevice.SOURCE_TOUCHSCREEN
+import android.view.MotionEvent
+import android.view.MotionEvent.ACTION_DOWN
+import android.view.MotionEvent.ACTION_HOVER_ENTER
+import android.view.MotionEvent.ACTION_MOVE
+import android.view.MotionEvent.ACTION_POINTER_DOWN
+import android.view.MotionEvent.ACTION_POINTER_UP
+import android.view.MotionEvent.ACTION_UP
+import android.view.MotionEvent.AXIS_GESTURE_SWIPE_FINGER_COUNT
+import android.view.MotionEvent.CLASSIFICATION_MULTI_FINGER_SWIPE
+import android.view.MotionEvent.TOOL_TYPE_FINGER
+import android.view.MotionEvent.TOOL_TYPE_MOUSE
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGesture.BACK
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class TouchpadGestureHandlerTest : SysuiTestCase() {
+
+    private var gestureDone = false
+    private val handler = TouchpadGestureHandler(BACK, SWIPE_DISTANCE) { gestureDone = true }
+
+    companion object {
+        const val SWIPE_DISTANCE = 100
+    }
+
+    @Test
+    fun handlesEventsFromTouchpad() {
+        val event = downEvent(source = SOURCE_MOUSE, toolType = TOOL_TYPE_FINGER)
+        val eventHandled = handler.onMotionEvent(event)
+        assertThat(eventHandled).isTrue()
+    }
+
+    @Test
+    fun ignoresEventsFromMouse() {
+        val event = downEvent(source = SOURCE_MOUSE, toolType = TOOL_TYPE_MOUSE)
+        val eventHandled = handler.onMotionEvent(event)
+        assertThat(eventHandled).isFalse()
+    }
+
+    @Test
+    fun ignoresEventsFromTouch() {
+        val event = downEvent(source = SOURCE_TOUCHSCREEN, toolType = TOOL_TYPE_FINGER)
+        val eventHandled = handler.onMotionEvent(event)
+        assertThat(eventHandled).isFalse()
+    }
+
+    @Test
+    fun ignoresButtonClicksFromTouchpad() {
+        val event = downEvent(source = SOURCE_MOUSE, toolType = TOOL_TYPE_FINGER)
+        event.buttonState = MotionEvent.BUTTON_PRIMARY
+        val eventHandled = handler.onMotionEvent(event)
+        assertThat(eventHandled).isFalse()
+    }
+
+    private fun downEvent(source: Int, toolType: Int) =
+        motionEvent(action = ACTION_DOWN, x = 0f, y = 0f, source = source, toolType = toolType)
+
+    @Test
+    fun triggersGestureDoneForThreeFingerGesture() {
+        backGestureEvents().forEach { handler.onMotionEvent(it) }
+
+        assertThat(gestureDone).isTrue()
+    }
+
+    private fun backGestureEvents(): List<MotionEvent> {
+        // list of motion events read from device while doing back gesture
+        val y = 100f
+        return listOf(
+            touchpadEvent(ACTION_HOVER_ENTER, x = 759f, y = y, pointerCount = 1),
+            threeFingerTouchpadEvent(ACTION_DOWN, x = 759f, y = y, pointerCount = 1),
+            threeFingerTouchpadEvent(ACTION_POINTER_DOWN, x = 759f, y = y, pointerCount = 2),
+            threeFingerTouchpadEvent(ACTION_POINTER_DOWN, x = 759f, y = y, pointerCount = 3),
+            threeFingerTouchpadEvent(ACTION_MOVE, x = 767f, y = y, pointerCount = 3),
+            threeFingerTouchpadEvent(ACTION_MOVE, x = 785f, y = y, pointerCount = 3),
+            threeFingerTouchpadEvent(ACTION_MOVE, x = 814f, y = y, pointerCount = 3),
+            threeFingerTouchpadEvent(ACTION_MOVE, x = 848f, y = y, pointerCount = 3),
+            threeFingerTouchpadEvent(ACTION_MOVE, x = 943f, y = y, pointerCount = 3),
+            threeFingerTouchpadEvent(ACTION_POINTER_UP, x = 943f, y = y, pointerCount = 3),
+            threeFingerTouchpadEvent(ACTION_POINTER_UP, x = 943f, y = y, pointerCount = 2),
+            threeFingerTouchpadEvent(ACTION_UP, x = 943f, y = y, pointerCount = 1)
+        )
+    }
+
+    private fun threeFingerTouchpadEvent(
+        action: Int,
+        x: Float,
+        y: Float,
+        pointerCount: Int
+    ): MotionEvent {
+        return touchpadEvent(
+            action = action,
+            x = x,
+            y = y,
+            pointerCount = pointerCount,
+            classification = CLASSIFICATION_MULTI_FINGER_SWIPE,
+            axisValues = mapOf(AXIS_GESTURE_SWIPE_FINGER_COUNT to 3f)
+        )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java b/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java
index 683397e..bb7b31b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/tuner/TunablePaddingTest.java
@@ -26,14 +26,17 @@
 import android.view.View;
 import android.view.WindowManager;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.utils.leaks.LeakCheckedTest;
 
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 @SmallTest
+@RunWith(AndroidJUnit4.class)
 public class TunablePaddingTest extends LeakCheckedTest {
 
     private static final String KEY = "KEY";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt
index 2cdc8d8..5d850d8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt
@@ -18,7 +18,7 @@
 
 import android.content.Context
 import android.content.res.Resources
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.R
 import com.android.systemui.SysuiTestCase
@@ -65,7 +65,7 @@
 import org.mockito.MockitoAnnotations
 
 @OptIn(ExperimentalCoroutinesApi::class)
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class DisplaySwitchLatencyTrackerTest : SysuiTestCase() {
     private lateinit var displaySwitchLatencyTracker: DisplaySwitchLatencyTracker
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
index e1797c4..c29b86c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
@@ -19,9 +19,9 @@
 import android.hardware.devicestate.DeviceStateManager
 import android.hardware.devicestate.DeviceStateManager.FoldStateListener
 import android.os.PowerManager
-import android.testing.AndroidTestingRunner
 import android.view.ViewGroup
 import android.view.ViewTreeObserver
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.util.LatencyTracker
 import com.android.systemui.SysuiTestCase
@@ -56,7 +56,7 @@
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class FoldAodAnimationControllerTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimationTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimationTest.kt
index dddc712..266a60d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimationTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimationTest.kt
@@ -18,11 +18,14 @@
 
 import android.os.PowerManager
 import android.os.SystemProperties
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.foldables.FoldLockSettingAvailabilityProvider
+import com.android.internal.jank.Cuj.CUJ_FOLD_ANIM
+import com.android.internal.jank.InteractionJankMonitor
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.AnimatorTestRule
 import com.android.systemui.display.data.repository.DeviceStateRepository.DeviceState
 import com.android.systemui.display.data.repository.fakeDeviceStateRepository
 import com.android.systemui.kosmos.Kosmos
@@ -32,27 +35,34 @@
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setScreenPowerState
 import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.power.shared.model.ScreenPowerState
+import com.android.systemui.statusbar.LightRevealScrim
 import com.android.systemui.util.animation.data.repository.fakeAnimationStatusRepository
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.whenever
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceTimeBy
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mockito.atLeast
 import org.mockito.Mockito.never
+import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
 
 @SmallTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @OptIn(ExperimentalCoroutinesApi::class)
 class FoldLightRevealOverlayAnimationTest : SysuiTestCase() {
+    @get:Rule val animatorTestRule = AnimatorTestRule(this)
+
     private val kosmos = Kosmos()
     private val testScope: TestScope = kosmos.testScope
     private val fakeDeviceStateRepository = kosmos.fakeDeviceStateRepository
@@ -63,6 +73,8 @@
     private val mockFoldLockSettingAvailabilityProvider =
         mock<FoldLockSettingAvailabilityProvider>()
     private val onOverlayReady = mock<Runnable>()
+    private val mockJankMonitor = mock<InteractionJankMonitor>()
+    private val mockScrimView = mock<LightRevealScrim>()
     private lateinit var foldLightRevealAnimation: FoldLightRevealOverlayAnimation
 
     @Before
@@ -71,6 +83,8 @@
         whenever(mockFoldLockSettingAvailabilityProvider.isFoldLockBehaviorAvailable)
             .thenReturn(true)
         fakeAnimationStatusRepository.onAnimationStatusChanged(true)
+        whenever(mockFullScreenController.scrimView).thenReturn(mockScrimView)
+        whenever(mockJankMonitor.begin(any(), eq(CUJ_FOLD_ANIM))).thenReturn(true)
 
         foldLightRevealAnimation =
             FoldLightRevealOverlayAnimation(
@@ -80,7 +94,8 @@
                 testScope.backgroundScope,
                 fakeAnimationStatusRepository,
                 mockControllerFactory,
-                mockFoldLockSettingAvailabilityProvider
+                mockFoldLockSettingAvailabilityProvider,
+                mockJankMonitor
             )
         foldLightRevealAnimation.init()
     }
@@ -99,9 +114,9 @@
         testScope.runTest {
             foldDeviceToScreenOff()
             emitLastWakefulnessEventStartingToSleep()
-            advanceTimeBy(SHORT_DELAY_MS)
+            advanceTime(SHORT_DELAY_MS)
             turnScreenOn()
-            advanceTimeBy(ANIMATION_DURATION)
+            advanceTime(ANIMATION_DURATION)
 
             verifyFoldAnimationDidNotPlay()
         }
@@ -111,8 +126,8 @@
         testScope.runTest {
             foldDeviceToScreenOff()
             emitLastWakefulnessEventStartingToSleep()
-            advanceTimeBy(SHORT_DELAY_MS)
-            advanceTimeBy(ANIMATION_DURATION)
+            advanceTime(SHORT_DELAY_MS)
+            advanceTime(ANIMATION_DURATION)
 
             verifyFoldAnimationDidNotPlay()
         }
@@ -122,10 +137,10 @@
         testScope.runTest {
             foldDeviceToScreenOff()
             foldLightRevealAnimation.onScreenTurningOn {}
-            advanceTimeBy(WAIT_FOR_ANIMATION_TIMEOUT_MS)
+            advanceTime(WAIT_FOR_ANIMATION_TIMEOUT_MS)
             powerInteractor.setScreenPowerState(ScreenPowerState.SCREEN_ON)
-            advanceTimeBy(SHORT_DELAY_MS)
-            advanceTimeBy(ANIMATION_DURATION)
+            advanceTime(SHORT_DELAY_MS)
+            advanceTime(ANIMATION_DURATION)
 
             verifyFoldAnimationDidNotPlay()
         }
@@ -135,10 +150,12 @@
         testScope.runTest {
             foldDeviceToScreenOff()
             foldLightRevealAnimation.onScreenTurningOn {}
-            advanceTimeBy(SHORT_DELAY_MS)
-            advanceTimeBy(ANIMATION_DURATION)
+            advanceTime(SHORT_DELAY_MS)
+            clearInvocations(mockFullScreenController)
+
+            // Unfold the device
             fakeDeviceStateRepository.emit(DeviceState.HALF_FOLDED)
-            advanceTimeBy(SHORT_DELAY_MS)
+            advanceTime(SHORT_DELAY_MS)
             powerInteractor.setScreenPowerState(ScreenPowerState.SCREEN_ON)
 
             verifyOverlayWasRemoved()
@@ -149,12 +166,38 @@
         testScope.runTest {
             foldDeviceToScreenOff()
             turnScreenOn()
-            advanceTimeBy(ANIMATION_DURATION)
+            clearInvocations(mockFullScreenController)
+            advanceTime(ANIMATION_DURATION)
 
             verifyOverlayWasRemoved()
         }
 
     @Test
+    fun foldToScreenOn_jankCujIsStarted() =
+        testScope.runTest {
+            foldDeviceToScreenOff()
+            turnScreenOn()
+            // Cuj has started but not ended
+            verify(mockJankMonitor, times(1)).begin(any(), eq(CUJ_FOLD_ANIM))
+            verify(mockJankMonitor, never()).end(eq(CUJ_FOLD_ANIM))
+        }
+
+    @Test
+    fun foldToScreenOn_animationFinished_jankCujIsFinished() =
+        testScope.runTest {
+            foldDeviceToScreenOff()
+            turnScreenOn()
+
+            advanceTime(ANIMATION_DURATION)
+            verify(mockJankMonitor, times(1)).end(eq(CUJ_FOLD_ANIM))
+        }
+
+    private fun TestScope.advanceTime(timeMs: Long) {
+        animatorTestRule.advanceTimeBy(timeMs)
+        advanceTimeBy(timeMs)
+    }
+
+    @Test
     fun unfold_immediatelyRunRunnable() =
         testScope.runTest {
             foldLightRevealAnimation.onScreenTurningOn(onOverlayReady)
@@ -165,18 +208,18 @@
     private suspend fun TestScope.foldDeviceToScreenOff() {
         fakeDeviceStateRepository.emit(DeviceState.HALF_FOLDED)
         powerInteractor.setScreenPowerState(ScreenPowerState.SCREEN_ON)
-        advanceTimeBy(SHORT_DELAY_MS)
+        advanceTime(SHORT_DELAY_MS)
         fakeDeviceStateRepository.emit(DeviceState.FOLDED)
-        advanceTimeBy(SHORT_DELAY_MS)
+        advanceTime(SHORT_DELAY_MS)
         powerInteractor.setScreenPowerState(ScreenPowerState.SCREEN_OFF)
-        advanceTimeBy(SHORT_DELAY_MS)
+        advanceTime(SHORT_DELAY_MS)
     }
 
     private fun TestScope.turnScreenOn() {
         foldLightRevealAnimation.onScreenTurningOn {}
-        advanceTimeBy(SHORT_DELAY_MS)
+        advanceTime(SHORT_DELAY_MS)
         powerInteractor.setScreenPowerState(ScreenPowerState.SCREEN_ON)
-        advanceTimeBy(SHORT_DELAY_MS)
+        advanceTime(SHORT_DELAY_MS)
     }
 
     private fun emitLastWakefulnessEventStartingToSleep() =
@@ -195,6 +238,7 @@
         const val WAIT_FOR_ANIMATION_TIMEOUT_MS = 2000L
         val ANIMATION_DURATION: Long
             get() = SystemProperties.getLong("persist.fold_animation_duration", 200L)
+
         const val SHORT_DELAY_MS = 50L
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldStateLoggingProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldStateLoggingProviderTest.kt
index 39e4e64..459b3e0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldStateLoggingProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldStateLoggingProviderTest.kt
@@ -16,7 +16,7 @@
 
 package com.android.systemui.unfold
 
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.unfold.FoldStateLoggingProvider.FoldStateLoggingListener
@@ -34,7 +34,7 @@
 import org.junit.runner.RunWith
 import org.mockito.MockitoAnnotations
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class FoldStateLoggingProviderTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldStateRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldStateRepositoryTest.kt
index ab779a7..448b63e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldStateRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldStateRepositoryTest.kt
@@ -15,7 +15,7 @@
  */
 package com.android.systemui.unfold
 
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
@@ -38,7 +38,7 @@
 import org.junit.runner.RunWith
 import org.mockito.Mockito.verify
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class FoldStateRepositoryTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt
index 06f1a88..208e39c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt
@@ -18,7 +18,7 @@
 import android.os.VibrationAttributes
 import android.os.VibrationEffect
 import android.os.vibrator
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.testKosmos
@@ -30,7 +30,7 @@
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class UnfoldHapticsPlayerTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt
index 2955384..1e5929d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt
@@ -19,7 +19,7 @@
 import android.hardware.devicestate.DeviceStateManager
 import android.hardware.devicestate.DeviceStateManager.FoldStateListener
 import android.provider.Settings
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.util.LatencyTracker
 import com.android.systemui.SysuiTestCase
@@ -39,7 +39,7 @@
 import org.mockito.Mockito.verifyNoMoreInteractions
 import org.mockito.MockitoAnnotations
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class UnfoldLatencyTrackerTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldTransitionWallpaperControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldTransitionWallpaperControllerTest.kt
index 0c452eb..b5282eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldTransitionWallpaperControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldTransitionWallpaperControllerTest.kt
@@ -1,6 +1,6 @@
 package com.android.systemui.unfold
 
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.WallpaperController
@@ -13,7 +13,7 @@
 import org.mockito.Mockito.verify
 import org.mockito.junit.MockitoJUnit
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class UnfoldTransitionWallpaperControllerTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfigTest.kt
index 3c53997..b48a6da3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfigTest.kt
@@ -14,7 +14,7 @@
  */
 package com.android.systemui.unfold.config
 
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
@@ -28,7 +28,7 @@
  * Internal Android resource constants are not available in public APIs,
  * so we can't use them there directly.
  */
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class ResourceUnfoldTransitionConfigTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProviderTest.kt
index e5f619b..61f0abb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/MainThreadUnfoldTransitionProgressProviderTest.kt
@@ -19,8 +19,8 @@
 import android.os.Handler
 import android.os.HandlerThread
 import android.os.Looper
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.unfold.FakeUnfoldTransitionProvider
@@ -29,7 +29,7 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.runner.RunWith
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 @RunWithLooper(setAsMainLooper = true)
 class MainThreadUnfoldTransitionProgressProviderTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
index 14fb054..ef2d4ce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
@@ -17,7 +17,7 @@
 
 import android.os.Handler
 import android.os.HandlerThread
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.unfold.UnfoldTransitionProgressProvider
@@ -29,11 +29,17 @@
 import com.android.systemui.unfold.util.TestFoldStateProvider
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
+import org.junit.After
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@RunWith(AndroidTestingRunner::class)
+/**
+ * This test class tests [PhysicsBasedUnfoldTransitionProgressProvider] in a more E2E
+ * fashion, it uses real handler thread and timings, so it might be perceptible to more flakiness
+ * compared to the other unit tests that do not perform real multithreaded interactions.
+ */
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class PhysicsBasedUnfoldTransitionProgressProviderTest : SysuiTestCase() {
 
@@ -44,8 +50,8 @@
         mock<UnfoldFrameCallbackScheduler.Factory>().apply {
             whenever(create()).then { UnfoldFrameCallbackScheduler() }
         }
-    private val mockBgHandler = mock<Handler>()
-    private val fakeHandler = Handler(HandlerThread("UnfoldBg").apply { start() }.looper)
+    private val handlerThread = HandlerThread("UnfoldBg").apply { start() }
+    private val bgHandler = Handler(handlerThread.looper)
 
     @Before
     fun setUp() {
@@ -54,20 +60,26 @@
                 context,
                 schedulerFactory,
                 foldStateProvider = foldStateProvider,
-                progressHandler = fakeHandler
+                progressHandler = bgHandler
             )
         progressProvider.addCallback(listener)
     }
 
+    @After
+    fun after() {
+        handlerThread.quit()
+    }
+
     @Test
     fun testUnfold_emitsIncreasingTransitionEvents() {
         runOnProgressThreadWithInterval(
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_OPENING) },
             { foldStateProvider.sendHingeAngleUpdate(10f) },
-            { foldStateProvider.sendUnfoldedScreenAvailable() },
-            { foldStateProvider.sendHingeAngleUpdate(90f) },
-            { foldStateProvider.sendHingeAngleUpdate(180f) },
-            { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN) },
+            { foldStateProvider.sendUnfoldedScreenAvailable() }
+        )
+        sendHingeAngleAndEnsureAnimationUpdate(90f, 120f, 180f)
+        runOnProgressThreadWithInterval(
+            { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN) }
         )
 
         with(listener.ensureTransitionFinished()) {
@@ -91,7 +103,7 @@
     }
 
     @Test
-    fun testUnfold_screenAvailableOnlyAfterFullUnfold_emitsIncreasingTransitionEvents() {
+    fun testUnfold_screenAvailableOnlyAfterFullUnfold_finishesWithUnfoldEvent() {
         runOnProgressThreadWithInterval(
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_OPENING) },
             { foldStateProvider.sendHingeAngleUpdate(10f) },
@@ -102,7 +114,6 @@
         )
 
         with(listener.ensureTransitionFinished()) {
-            assertIncreasingProgress()
             assertFinishedWithUnfold()
         }
     }
@@ -111,9 +122,9 @@
     fun testFold_emitsDecreasingTransitionEvents() {
         runOnProgressThreadWithInterval(
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_CLOSING) },
-            { foldStateProvider.sendHingeAngleUpdate(170f) },
-            { foldStateProvider.sendHingeAngleUpdate(90f) },
-            { foldStateProvider.sendHingeAngleUpdate(10f) },
+        )
+        sendHingeAngleAndEnsureAnimationUpdate(170f, 90f, 10f)
+        runOnProgressThreadWithInterval(
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_CLOSED) },
         )
 
@@ -127,9 +138,9 @@
     fun testUnfoldAndStopUnfolding_finishesTheUnfoldTransition() {
         runOnProgressThreadWithInterval(
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_START_OPENING) },
-            { foldStateProvider.sendUnfoldedScreenAvailable() },
-            { foldStateProvider.sendHingeAngleUpdate(10f) },
-            { foldStateProvider.sendHingeAngleUpdate(90f) },
+            { foldStateProvider.sendUnfoldedScreenAvailable() })
+        sendHingeAngleAndEnsureAnimationUpdate(10f, 50f, 90f)
+        runOnProgressThreadWithInterval(
             { foldStateProvider.sendFoldUpdate(FOLD_UPDATE_FINISH_HALF_OPEN) },
         )
 
@@ -159,12 +170,22 @@
         with(listener.ensureTransitionFinished()) { assertHasFoldAnimationAtTheEnd() }
     }
 
+    private fun sendHingeAngleAndEnsureAnimationUpdate(vararg angles: Float) {
+        angles.forEach { angle ->
+            listener.waitForProgressChangeAfter {
+                bgHandler.post {
+                    foldStateProvider.sendHingeAngleUpdate(angle)
+                }
+            }
+        }
+    }
+
     private fun runOnProgressThreadWithInterval(
         vararg blocks: () -> Unit,
         intervalMillis: Long = 60,
     ) {
         blocks.forEach {
-            fakeHandler.post(it)
+            bgHandler.post(it)
             Thread.sleep(intervalMillis)
         }
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/RemoteUnfoldTransitionReceiverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/RemoteUnfoldTransitionReceiverTest.kt
index 4989a21..a7b67e2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/RemoteUnfoldTransitionReceiverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/RemoteUnfoldTransitionReceiverTest.kt
@@ -16,7 +16,7 @@
 
 package com.android.systemui.unfold.progress
 
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.systemui.SysuiTestCase
@@ -24,7 +24,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class RemoteUnfoldTransitionReceiverTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt
index bbc96f70..6e8bf85 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/TestUnfoldProgressListener.kt
@@ -68,6 +68,24 @@
         return recordings.first()
     }
 
+    /**
+     * Number of progress event for the currently running transition
+     * Returns null if there is no currently running transition
+     */
+    val currentTransitionProgressEventCount: Int?
+        get() = currentRecording?.progressHistory?.size
+
+    /**
+     * Runs [block] and ensures that there was at least once onTransitionProgress event after that
+     */
+    fun waitForProgressChangeAfter(block: () -> Unit) {
+        val eventCount = currentTransitionProgressEventCount
+        block()
+        waitForCondition {
+            currentTransitionProgressEventCount != eventCount
+        }
+    }
+
     fun assertStarted() {
         assertWithMessage("Transition didn't start").that(currentRecording).isNotNull()
     }
@@ -86,7 +104,7 @@
     }
 
     class UnfoldTransitionRecording {
-        private val progressHistory: MutableList<Float> = arrayListOf()
+        val progressHistory: MutableList<Float> = arrayListOf()
         private var finishingInvocations: Int = 0
 
         fun addProgress(progress: Float) {
@@ -142,6 +160,6 @@
     }
 
     private companion object {
-        private const val MIN_ANIMATION_EVENTS = 5
+        private const val MIN_ANIMATION_EVENTS = 3
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/UnfoldRemoteFilterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/UnfoldRemoteFilterTest.kt
index 70eadce..b93c161 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/UnfoldRemoteFilterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/UnfoldRemoteFilterTest.kt
@@ -16,7 +16,7 @@
 
 package com.android.systemui.unfold.progress
 
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.systemui.SysuiTestCase
@@ -25,7 +25,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class UnfoldRemoteFilterTest : SysuiTestCase() {
     private val listener = TestUnfoldProgressListener()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
index 552b60c..21a45ec 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
@@ -21,8 +21,8 @@
 import android.content.res.Resources
 import android.os.Handler
 import android.os.Looper
-import android.testing.AndroidTestingRunner
 import androidx.core.util.Consumer
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.unfold.config.ResourceUnfoldTransitionConfig
@@ -50,7 +50,7 @@
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class DeviceFoldStateProviderTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceStateRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceStateRepositoryTest.kt
index 4eb1591..4d9c80f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceStateRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceStateRepositoryTest.kt
@@ -15,7 +15,7 @@
  */
 package com.android.systemui.unfold.updates
 
-import android.testing.AndroidTestingRunner
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
@@ -32,7 +32,7 @@
 import org.junit.runner.RunWith
 import org.mockito.Mockito.verify
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 class DeviceStateRepositoryTest : SysuiTestCase() {
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/RotationChangeProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/RotationChangeProviderTest.kt
index eaef007..f5bcc21 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/RotationChangeProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/RotationChangeProviderTest.kt
@@ -21,9 +21,9 @@
 import android.os.HandlerThread
 import android.os.Looper
 import android.os.Process
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
 import android.view.Display
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.unfold.updates.RotationChangeProvider.RotationListener
@@ -41,7 +41,7 @@
 import org.mockito.Mockito.verifyNoMoreInteractions
 import org.mockito.MockitoAnnotations
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 @RunWithLooper
 class RotationChangeProviderTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProviderTest.kt
index 70ec050..8d892ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProviderTest.kt
@@ -15,9 +15,9 @@
  */
 package com.android.systemui.unfold.util
 
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.Surface
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.unfold.FakeUnfoldTransitionProvider
@@ -36,7 +36,7 @@
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 @TestableLooper.RunWithLooper
 class NaturalRotationUnfoldProgressProviderTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScaleAwareUnfoldProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScaleAwareUnfoldProgressProviderTest.kt
index 451bd24..39977c7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScaleAwareUnfoldProgressProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScaleAwareUnfoldProgressProviderTest.kt
@@ -18,8 +18,8 @@
 import android.content.ContentResolver
 import android.database.ContentObserver
 import android.provider.Settings
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.unfold.FakeUnfoldTransitionProvider
@@ -35,7 +35,7 @@
 import org.mockito.Mockito.verifyNoMoreInteractions
 import org.mockito.MockitoAnnotations
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 @TestableLooper.RunWithLooper
 class ScaleAwareUnfoldProgressProviderTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProviderTest.kt
index 4486402..6e0bff2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProviderTest.kt
@@ -19,8 +19,8 @@
 import android.os.Handler
 import android.os.HandlerThread
 import android.os.Process
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.unfold.FakeUnfoldTransitionProvider
@@ -38,7 +38,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 @RunWithLooper
 class ScopedUnfoldTransitionProgressProviderTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProviderTest.kt
index cd4d7b5..0cbe1ba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/UnfoldOnlyProgressProviderTest.kt
@@ -15,8 +15,8 @@
  */
 package com.android.systemui.unfold.util
 
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.unfold.FakeUnfoldTransitionProvider
@@ -26,7 +26,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 @TestableLooper.RunWithLooper
 class UnfoldOnlyProgressProviderTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt
index b04eb01..32c5986 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt
@@ -20,9 +20,9 @@
 import android.hardware.usb.IUsbSerialReader
 import android.hardware.usb.UsbAccessory
 import android.hardware.usb.UsbManager
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import androidx.test.rule.ActivityTestRule
 import com.android.systemui.SysuiTestCase
@@ -40,7 +40,7 @@
 /**
  * UsbPermissionActivityTest
  */
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 @TestableLooper.RunWithLooper
 class UsbPermissionActivityTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/CreateUserActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/CreateUserActivityTest.kt
index 6db35ae..84cd79d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/CreateUserActivityTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/CreateUserActivityTest.kt
@@ -1,9 +1,9 @@
 package com.android.systemui.user
 
 import android.app.Dialog
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import androidx.test.ext.junit.rules.ActivityScenarioRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.any
@@ -15,7 +15,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 @TestableLooper.RunWithLooper
 class CreateUserActivityTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/UserCreatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/UserCreatorTest.kt
index 35f9c41..a291140 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/UserCreatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/UserCreatorTest.kt
@@ -3,8 +3,8 @@
 import android.content.pm.UserInfo
 import android.graphics.Bitmap
 import android.os.UserManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.concurrency.FakeExecutor
@@ -22,7 +22,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 class UserCreatorTest : SysuiTestCase() {
     companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt
index 0669cb8..37a73cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt
@@ -21,6 +21,7 @@
 import android.os.UserHandle
 import android.os.UserManager
 import android.provider.Settings
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.settings.FakeUserTracker
@@ -41,7 +42,6 @@
 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.mock
 import org.mockito.Mockito.`when` as whenever
@@ -49,7 +49,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class UserRepositoryImplTest : SysuiTestCase() {
 
     @Mock private lateinit var manager: UserManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt
index 01795e9..20b273a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/GuestUserInteractorTest.kt
@@ -22,6 +22,7 @@
 import android.content.pm.UserInfo
 import android.os.UserHandle
 import android.os.UserManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.GuestResetOrExitSessionReceiver
@@ -39,7 +40,6 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
 import org.mockito.Mockito.never
@@ -47,7 +47,7 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class GuestUserInteractorTest : SysuiTestCase() {
 
     @Mock private lateinit var manager: UserManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/RefreshUsersSchedulerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/RefreshUsersSchedulerTest.kt
index b30f77a..59ad38a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/RefreshUsersSchedulerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/RefreshUsersSchedulerTest.kt
@@ -17,6 +17,7 @@
 
 package com.android.systemui.user.domain.interactor
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.user.data.repository.FakeUserRepository
@@ -26,11 +27,10 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.MockitoAnnotations
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class RefreshUsersSchedulerTest : SysuiTestCase() {
 
     private lateinit var underTest: RefreshUsersScheduler
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/SelectedUserInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/SelectedUserInteractorTest.kt
index 140e919..78028f8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/SelectedUserInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/SelectedUserInteractorTest.kt
@@ -1,6 +1,7 @@
 package com.android.systemui.user.domain.interactor
 
 import android.content.pm.UserInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.Flags.FLAG_REFACTOR_GET_CURRENT_USER
 import com.android.systemui.SysuiTestCase
@@ -10,10 +11,9 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class SelectedUserInteractorTest : SysuiTestCase() {
 
     private lateinit var underTest: SelectedUserInteractor
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractorTest.kt
index 96c6eb8..ccbdffa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserSwitcherInteractorTest.kt
@@ -28,6 +28,7 @@
 import android.os.UserHandle
 import android.os.UserManager
 import android.provider.Settings
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.UiEventLogger
 import com.android.keyguard.KeyguardUpdateMonitor
@@ -75,7 +76,6 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.ArgumentCaptor
 import org.mockito.ArgumentMatchers.anyBoolean
 import org.mockito.ArgumentMatchers.anyInt
@@ -89,7 +89,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class UserSwitcherInteractorTest : SysuiTestCase() {
 
     @Mock private lateinit var activityStarter: ActivityStarter
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
index 661837b..99cdf73 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/StatusBarUserChipViewModelTest.kt
@@ -23,6 +23,7 @@
 import android.graphics.Bitmap
 import android.graphics.drawable.BitmapDrawable
 import android.os.UserManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.UiEventLogger
 import com.android.keyguard.KeyguardUpdateMonitor
@@ -60,7 +61,6 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
 import org.mockito.Mockito.doAnswer
@@ -68,7 +68,7 @@
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class StatusBarUserChipViewModelTest : SysuiTestCase() {
     @Mock private lateinit var activityStarter: ActivityStarter
     @Mock private lateinit var activityManager: ActivityManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
index 5661e20..917df61 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
@@ -21,6 +21,7 @@
 import android.app.admin.DevicePolicyManager
 import android.content.pm.UserInfo
 import android.os.UserManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.UiEventLogger
 import com.android.keyguard.KeyguardUpdateMonitor
@@ -62,13 +63,12 @@
 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.MockitoAnnotations
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
-@RunWith(JUnit4::class)
+@RunWith(AndroidJUnit4::class)
 class UserSwitcherViewModelTest : SysuiTestCase() {
 
     @Mock private lateinit var activityStarter: ActivityStarter
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/icons/AppCategoryIconProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/icons/AppCategoryIconProviderTest.kt
new file mode 100644
index 0000000..ef41b6ee
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/icons/AppCategoryIconProviderTest.kt
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.icons
+
+import android.app.role.RoleManager.ROLE_ASSISTANT
+import android.content.ComponentName
+import android.content.Intent
+import android.content.Intent.CATEGORY_APP_BROWSER
+import android.content.Intent.CATEGORY_APP_CONTACTS
+import android.content.Intent.CATEGORY_APP_EMAIL
+import android.content.mockPackageManager
+import android.content.mockPackageManagerWrapper
+import android.content.pm.ActivityInfo
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageInfo
+import android.content.pm.ResolveInfo
+import android.graphics.drawable.Icon
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.assist.mockAssistManager
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class AppCategoryIconProviderTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+    private val packageManagerWrapper = kosmos.mockPackageManagerWrapper
+    private val packageManager = kosmos.mockPackageManager
+    private val assistManager = kosmos.mockAssistManager
+    private val provider = kosmos.appCategoryIconProvider
+
+    @Before
+    fun setUp() {
+        whenever(packageManagerWrapper.resolveActivity(any<Intent>(), any<Int>())).thenAnswer {
+            invocation ->
+            val category = (invocation.arguments[0] as Intent).categories.first()
+            val categoryAppIcon =
+                categoryAppIcons.firstOrNull { it.category == category } ?: return@thenAnswer null
+            val activityInfo = ActivityInfo().also { it.packageName = categoryAppIcon.packageName }
+            return@thenAnswer ResolveInfo().also { it.activityInfo = activityInfo }
+        }
+        whenever(packageManager.getPackageInfo(any<String>(), any<Int>())).thenAnswer { invocation
+            ->
+            val packageName = invocation.arguments[0] as String
+            val categoryAppIcon =
+                categoryAppIcons.firstOrNull { it.packageName == packageName }
+                    ?: return@thenAnswer null
+            val applicationInfo =
+                ApplicationInfo().also {
+                    it.packageName = packageName
+                    it.icon = categoryAppIcon.iconResId
+                }
+            return@thenAnswer PackageInfo().also {
+                it.packageName = packageName
+                it.applicationInfo = applicationInfo
+            }
+        }
+    }
+
+    @Test
+    fun assistantAppIcon_defaultAssistantSet_returnsIcon() =
+        testScope.runTest {
+            whenever(assistManager.assistInfo)
+                .thenReturn(ComponentName(ASSISTANT_PACKAGE, ASSISTANT_CLASS))
+
+            val icon = provider.assistantAppIcon() as Icon
+
+            assertThat(icon.resPackage).isEqualTo(ASSISTANT_PACKAGE)
+            assertThat(icon.resId).isEqualTo(ASSISTANT_ICON_RES_ID)
+        }
+
+    @Test
+    fun assistantAppIcon_defaultAssistantNotSet_returnsNull() =
+        testScope.runTest {
+            whenever(assistManager.assistInfo).thenReturn(null)
+
+            assertThat(provider.assistantAppIcon()).isNull()
+        }
+
+    @Test
+    fun categoryAppIcon_returnsIconOfKnownBrowserApp() {
+        testScope.runTest {
+            val icon = provider.categoryAppIcon(CATEGORY_APP_BROWSER) as Icon
+
+            assertThat(icon.resPackage).isEqualTo(BROWSER_PACKAGE)
+            assertThat(icon.resId).isEqualTo(BROWSER_ICON_RES_ID)
+        }
+    }
+
+    @Test
+    fun categoryAppIcon_returnsIconOfKnownContactsApp() {
+        testScope.runTest {
+            val icon = provider.categoryAppIcon(CATEGORY_APP_CONTACTS) as Icon
+
+            assertThat(icon.resPackage).isEqualTo(CONTACTS_PACKAGE)
+            assertThat(icon.resId).isEqualTo(CONTACTS_ICON_RES_ID)
+        }
+    }
+
+    @Test
+    fun categoryAppIcon_noDefaultAppForCategoryEmail_returnsNull() {
+        testScope.runTest {
+            val icon = provider.categoryAppIcon(CATEGORY_APP_EMAIL)
+
+            assertThat(icon).isNull()
+        }
+    }
+
+    private companion object {
+        private const val ASSISTANT_PACKAGE = "the.assistant.app"
+        private const val ASSISTANT_CLASS = "the.assistant.app.class"
+        private const val ASSISTANT_ICON_RES_ID = 123
+
+        private const val BROWSER_PACKAGE = "com.test.browser"
+        private const val BROWSER_ICON_RES_ID = 1
+
+        private const val CONTACTS_PACKAGE = "app.test.contacts"
+        private const val CONTACTS_ICON_RES_ID = 234
+
+        private val categoryAppIcons =
+            listOf(
+                App(ROLE_ASSISTANT, ASSISTANT_PACKAGE, ASSISTANT_ICON_RES_ID),
+                App(CATEGORY_APP_BROWSER, BROWSER_PACKAGE, BROWSER_ICON_RES_ID),
+                App(CATEGORY_APP_CONTACTS, CONTACTS_PACKAGE, CONTACTS_ICON_RES_ID),
+            )
+    }
+
+    private class App(val category: String, val packageName: String, val iconResId: Int)
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/PackageManagerExtComponentEnabledTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/PackageManagerExtComponentEnabledTest.kt
index 8bfff9c2..b3f2113 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/PackageManagerExtComponentEnabledTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/PackageManagerExtComponentEnabledTest.kt
@@ -19,6 +19,7 @@
 import android.content.ComponentName
 import android.content.pm.ComponentInfo
 import android.content.pm.PackageManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/AsyncSensorManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/AsyncSensorManagerTest.java
index df08efa..c896fc0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/AsyncSensorManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/AsyncSensorManagerTest.java
@@ -23,8 +23,8 @@
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import android.hardware.SensorEventListener;
-import android.testing.AndroidTestingRunner;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
@@ -39,7 +39,7 @@
 import org.junit.runner.RunWith;
 
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(AndroidJUnit4.class)
 public class AsyncSensorManagerTest extends SysuiTestCase {
 
     private AsyncSensorManager mAsyncSensorManager;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.java
deleted file mode 100644
index ef10fdf..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/util/service/PersistentConnectionManagerTest.java
+++ /dev/null
@@ -1,178 +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.util.service;
-
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.dump.DumpManager;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.time.FakeSystemClock;
-
-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;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class PersistentConnectionManagerTest extends SysuiTestCase {
-    private static final int MAX_RETRIES = 5;
-    private static final int RETRY_DELAY_MS = 1000;
-    private static final int CONNECTION_MIN_DURATION_MS = 5000;
-    private static final String DUMPSYS_NAME = "dumpsys_name";
-
-    private FakeSystemClock mFakeClock = new FakeSystemClock();
-    private FakeExecutor mFakeExecutor = new FakeExecutor(mFakeClock);
-
-    @Mock
-    private ObservableServiceConnection<Proxy> mConnection;
-
-    @Mock
-    private ObservableServiceConnection.Callback<Proxy> mConnectionCallback;
-
-    @Mock
-    private Observer mObserver;
-
-    @Mock
-    private DumpManager mDumpManager;
-
-    private static class Proxy {
-    }
-
-    private PersistentConnectionManager<Proxy> mConnectionManager;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-
-        mConnectionManager = new PersistentConnectionManager<>(
-                mFakeClock,
-                mFakeExecutor,
-                mDumpManager,
-                DUMPSYS_NAME,
-                mConnection,
-                MAX_RETRIES,
-                RETRY_DELAY_MS,
-                CONNECTION_MIN_DURATION_MS,
-                mObserver);
-    }
-
-    private ObservableServiceConnection.Callback<Proxy> captureCallbackAndSend(
-            ObservableServiceConnection<Proxy> mConnection, Proxy proxy) {
-        ArgumentCaptor<ObservableServiceConnection.Callback<Proxy>> connectionCallbackCaptor =
-                ArgumentCaptor.forClass(ObservableServiceConnection.Callback.class);
-
-        verify(mConnection).addCallback(connectionCallbackCaptor.capture());
-        verify(mConnection).bind();
-        Mockito.clearInvocations(mConnection);
-
-        final ObservableServiceConnection.Callback callback = connectionCallbackCaptor.getValue();
-        if (proxy != null) {
-            callback.onConnected(mConnection, proxy);
-        } else {
-            callback.onDisconnected(mConnection, 0);
-        }
-
-        return callback;
-    }
-
-    /**
-     * Validates initial connection.
-     */
-    @Test
-    public void testConnect() {
-        mConnectionManager.start();
-        captureCallbackAndSend(mConnection, Mockito.mock(Proxy.class));
-    }
-
-    /**
-     * Ensures reconnection on disconnect.
-     */
-    @Test
-    public void testRetryOnBindFailure() {
-        mConnectionManager.start();
-        ArgumentCaptor<ObservableServiceConnection.Callback<Proxy>> connectionCallbackCaptor =
-                ArgumentCaptor.forClass(ObservableServiceConnection.Callback.class);
-
-        verify(mConnection).addCallback(connectionCallbackCaptor.capture());
-
-        // Verify attempts happen. Note that we account for the retries plus initial attempt, which
-        // is not scheduled.
-        for (int attemptCount = 0; attemptCount < MAX_RETRIES + 1; attemptCount++) {
-            verify(mConnection).bind();
-            Mockito.clearInvocations(mConnection);
-            connectionCallbackCaptor.getValue().onDisconnected(mConnection, 0);
-            mFakeExecutor.advanceClockToNext();
-            mFakeExecutor.runAllReady();
-        }
-    }
-
-    /**
-     * Ensures manual unbind does not reconnect.
-     */
-    @Test
-    public void testStopDoesNotReconnect() {
-        mConnectionManager.start();
-        ArgumentCaptor<ObservableServiceConnection.Callback<Proxy>> connectionCallbackCaptor =
-                ArgumentCaptor.forClass(ObservableServiceConnection.Callback.class);
-
-        verify(mConnection).addCallback(connectionCallbackCaptor.capture());
-        verify(mConnection).bind();
-        Mockito.clearInvocations(mConnection);
-        mConnectionManager.stop();
-        mFakeExecutor.advanceClockToNext();
-        mFakeExecutor.runAllReady();
-        verify(mConnection, never()).bind();
-    }
-
-    /**
-     * Ensures rebind on package change.
-     */
-    @Test
-    public void testAttemptOnPackageChange() {
-        mConnectionManager.start();
-        verify(mConnection).bind();
-        ArgumentCaptor<Observer.Callback> callbackCaptor =
-                ArgumentCaptor.forClass(Observer.Callback.class);
-        captureCallbackAndSend(mConnection, Mockito.mock(Proxy.class));
-
-        verify(mObserver).addCallback(callbackCaptor.capture());
-
-        callbackCaptor.getValue().onSourceChanged();
-        verify(mConnection).bind();
-    }
-
-    @Test
-    public void testAddConnectionCallback() {
-        mConnectionManager.addConnectionCallback(mConnectionCallback);
-        verify(mConnection).addCallback(mConnectionCallback);
-    }
-
-    @Test
-    public void testRemoveConnectionCallback() {
-        mConnectionManager.removeConnectionCallback(mConnectionCallback);
-        verify(mConnection).removeCallback(mConnectionCallback);
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/settings/SettingsProxyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/settings/SettingsProxyTest.kt
index eb11e38..dd791e7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/settings/SettingsProxyTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/settings/SettingsProxyTest.kt
@@ -22,11 +22,16 @@
 import android.os.Handler
 import android.os.Looper
 import android.provider.Settings.SettingNotFoundException
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
 import org.junit.Assert.assertThrows
 import org.junit.Before
 import org.junit.Test
@@ -36,17 +41,21 @@
 import org.mockito.kotlin.eq
 
 /** Tests for [SettingsProxy]. */
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 @TestableLooper.RunWithLooper
 class SettingsProxyTest : SysuiTestCase() {
 
+    private val testDispatcher = StandardTestDispatcher()
+
     private lateinit var mSettings: SettingsProxy
     private lateinit var mContentObserver: ContentObserver
+    private lateinit var testScope: TestScope
 
     @Before
     fun setUp() {
-        mSettings = FakeSettingsProxy()
+        testScope = TestScope(testDispatcher)
+        mSettings = FakeSettingsProxy(testDispatcher)
         mContentObserver = object : ContentObserver(Handler(Looper.getMainLooper())) {}
     }
 
@@ -58,6 +67,23 @@
     }
 
     @Test
+    fun registerContentObserverSuspend_inputString_success() =
+        testScope.runTest {
+            mSettings.registerContentObserver(TEST_SETTING, mContentObserver)
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
+        }
+
+    @Test
+    fun registerContentObserverAsync_inputString_success() {
+        mSettings.registerContentObserverAsync(TEST_SETTING, mContentObserver)
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
+        }
+    }
+
+    @Test
     fun registerContentObserver_inputString_notifyForDescendants_true() {
         mSettings.registerContentObserverSync(
             TEST_SETTING,
@@ -69,6 +95,31 @@
     }
 
     @Test
+    fun registerContentObserverSuspend_inputString_notifyForDescendants_true() =
+        testScope.runTest {
+            mSettings.registerContentObserver(
+                TEST_SETTING,
+                notifyForDescendants = true,
+                mContentObserver
+            )
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
+        }
+
+    @Test
+    fun registerContentObserverAsync_inputString_notifyForDescendants_true() {
+        mSettings.registerContentObserverAsync(
+            TEST_SETTING,
+            notifyForDescendants = true,
+            mContentObserver
+        )
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
+        }
+    }
+
+    @Test
     fun registerContentObserver_inputUri_success() {
         mSettings.registerContentObserverSync(TEST_SETTING_URI, mContentObserver)
         verify(mSettings.getContentResolver())
@@ -76,6 +127,23 @@
     }
 
     @Test
+    fun registerContentObserverSuspend_inputUri_success() =
+        testScope.runTest {
+            mSettings.registerContentObserver(TEST_SETTING_URI, mContentObserver)
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
+        }
+
+    @Test
+    fun registerContentObserverAsync_inputUri_success() {
+        mSettings.registerContentObserverAsync(TEST_SETTING_URI, mContentObserver)
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(eq(TEST_SETTING_URI), eq(false), eq(mContentObserver))
+        }
+    }
+
+    @Test
     fun registerContentObserver_inputUri_notifyForDescendants_true() {
         mSettings.registerContentObserverSync(
             TEST_SETTING_URI,
@@ -87,12 +155,52 @@
     }
 
     @Test
-    fun unregisterContentObserver() {
+    fun registerContentObserverSuspend_inputUri_notifyForDescendants_true() =
+        testScope.runTest {
+            mSettings.registerContentObserver(
+                TEST_SETTING_URI,
+                notifyForDescendants = true,
+                mContentObserver
+            )
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
+        }
+
+    @Test
+    fun registerContentObserverAsync_inputUri_notifyForDescendants_true() {
+        mSettings.registerContentObserverAsync(
+            TEST_SETTING_URI,
+            notifyForDescendants = true,
+            mContentObserver
+        )
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(eq(TEST_SETTING_URI), eq(true), eq(mContentObserver))
+        }
+    }
+
+    @Test
+    fun unregisterContentObserverSync() {
         mSettings.unregisterContentObserverSync(mContentObserver)
         verify(mSettings.getContentResolver()).unregisterContentObserver(eq(mContentObserver))
     }
 
     @Test
+    fun unregisterContentObserverSuspend_inputString_success() =
+        testScope.runTest {
+            mSettings.unregisterContentObserver(mContentObserver)
+            verify(mSettings.getContentResolver()).unregisterContentObserver(eq(mContentObserver))
+        }
+
+    @Test
+    fun unregisterContentObserverAsync_inputString_success() {
+        mSettings.unregisterContentObserverAsync(mContentObserver)
+        testScope.launch {
+            verify(mSettings.getContentResolver()).unregisterContentObserver(eq(mContentObserver))
+        }
+    }
+
+    @Test
     fun getString_keyPresent_returnValidValue() {
         mSettings.putString(TEST_SETTING, "test")
         assertThat(mSettings.getString(TEST_SETTING)).isEqualTo("test")
@@ -199,13 +307,16 @@
         assertThat(mSettings.getFloat(TEST_SETTING, 2.5F)).isEqualTo(2.5F)
     }
 
-    private class FakeSettingsProxy : SettingsProxy {
+    private class FakeSettingsProxy(val testDispatcher: CoroutineDispatcher) : SettingsProxy {
 
         private val mContentResolver = mock(ContentResolver::class.java)
         private val settingToValueMap: MutableMap<String, String> = mutableMapOf()
 
         override fun getContentResolver() = mContentResolver
 
+        override val backgroundDispatcher: CoroutineDispatcher
+            get() = testDispatcher
+
         override fun getUriFor(name: String) =
             Uri.parse(StringBuilder().append("content://settings/").append(name).toString())
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt
index 38469ee..e3e20c8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/settings/UserSettingsProxyTest.kt
@@ -23,13 +23,18 @@
 import android.os.Handler
 import android.os.Looper
 import android.provider.Settings
-import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.settings.FakeUserTracker
 import com.android.systemui.settings.UserTracker
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
 import org.junit.Assert.assertThrows
 import org.junit.Before
 import org.junit.Test
@@ -39,14 +44,16 @@
 import org.mockito.kotlin.eq
 
 /** Tests for [UserSettingsProxy]. */
-@RunWith(AndroidTestingRunner::class)
+@RunWith(AndroidJUnit4::class)
 @SmallTest
 @TestableLooper.RunWithLooper
 class UserSettingsProxyTest : SysuiTestCase() {
 
     private var mUserTracker = FakeUserTracker()
-    private var mSettings: UserSettingsProxy = FakeUserSettingsProxy(mUserTracker)
+    private val testDispatcher = StandardTestDispatcher()
+    private var mSettings: UserSettingsProxy = FakeUserSettingsProxy(mUserTracker, testDispatcher)
     private var mContentObserver = object : ContentObserver(Handler(Looper.getMainLooper())) {}
+    private lateinit var testScope: TestScope
 
     @Before
     fun setUp() {
@@ -54,6 +61,7 @@
             listOf(UserInfo(MAIN_USER_ID, "main", UserInfo.FLAG_MAIN)),
             selectedUserIndex = 0
         )
+        testScope = TestScope(testDispatcher)
     }
 
     @Test
@@ -73,6 +81,41 @@
     }
 
     @Test
+    fun registerContentObserverForUserSuspend_inputString_success() =
+        testScope.runTest {
+            mSettings.registerContentObserverForUser(
+                TEST_SETTING,
+                mContentObserver,
+                mUserTracker.userId
+            )
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(false),
+                    eq(mContentObserver),
+                    eq(MAIN_USER_ID)
+                )
+        }
+
+    @Test
+    fun registerContentObserverForUserAsync_inputString_success() {
+        mSettings.registerContentObserverForUserAsync(
+            TEST_SETTING,
+            mContentObserver,
+            mUserTracker.userId
+        )
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(false),
+                    eq(mContentObserver),
+                    eq(MAIN_USER_ID)
+                )
+        }
+    }
+
+    @Test
     fun registerContentObserverForUser_inputString_notifyForDescendants_true() {
         mSettings.registerContentObserverForUserSync(
             TEST_SETTING,
@@ -90,6 +133,45 @@
     }
 
     @Test
+    fun registerContentObserverForUserSuspend_inputString_notifyForDescendants_true() =
+        testScope.runTest {
+            mSettings.registerContentObserverForUser(
+                TEST_SETTING,
+                notifyForDescendants = true,
+                mContentObserver,
+                mUserTracker.userId
+            )
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(
+                        true,
+                    ),
+                    eq(mContentObserver),
+                    eq(MAIN_USER_ID)
+                )
+        }
+
+    @Test
+    fun registerContentObserverForUserAsync_inputString_notifyForDescendants_true() {
+        mSettings.registerContentObserverForUserAsync(
+            TEST_SETTING,
+            notifyForDescendants = true,
+            mContentObserver,
+            mUserTracker.userId
+        )
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(true),
+                    eq(mContentObserver),
+                    eq(MAIN_USER_ID)
+                )
+        }
+    }
+
+    @Test
     fun registerContentObserverForUser_inputUri_success() {
         mSettings.registerContentObserverForUserSync(
             TEST_SETTING_URI,
@@ -106,6 +188,41 @@
     }
 
     @Test
+    fun registerContentObserverForUserSuspend_inputUri_success() =
+        testScope.runTest {
+            mSettings.registerContentObserverForUser(
+                TEST_SETTING_URI,
+                mContentObserver,
+                mUserTracker.userId
+            )
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(false),
+                    eq(mContentObserver),
+                    eq(MAIN_USER_ID)
+                )
+        }
+
+    @Test
+    fun registerContentObserverForUserAsync_inputUri_success() {
+        mSettings.registerContentObserverForUserAsync(
+            TEST_SETTING_URI,
+            mContentObserver,
+            mUserTracker.userId
+        )
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(false),
+                    eq(mContentObserver),
+                    eq(MAIN_USER_ID)
+                )
+        }
+    }
+
+    @Test
     fun registerContentObserverForUser_inputUri_notifyForDescendants_true() {
         mSettings.registerContentObserverForUserSync(
             TEST_SETTING_URI,
@@ -123,6 +240,45 @@
     }
 
     @Test
+    fun registerContentObserverForUserSuspend_inputUri_notifyForDescendants_true() =
+        testScope.runTest {
+            mSettings.registerContentObserverForUser(
+                TEST_SETTING_URI,
+                notifyForDescendants = true,
+                mContentObserver,
+                mUserTracker.userId
+            )
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(
+                        true,
+                    ),
+                    eq(mContentObserver),
+                    eq(MAIN_USER_ID)
+                )
+        }
+
+    @Test
+    fun registerContentObserverForUserAsync_inputUri_notifyForDescendants_true() {
+        mSettings.registerContentObserverForUserAsync(
+            TEST_SETTING_URI,
+            notifyForDescendants = true,
+            mContentObserver,
+            mUserTracker.userId
+        )
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(true),
+                    eq(mContentObserver),
+                    eq(MAIN_USER_ID)
+                )
+        }
+    }
+
+    @Test
     fun registerContentObserver_inputUri_success() {
         mSettings.registerContentObserverSync(TEST_SETTING_URI, mContentObserver)
         verify(mSettings.getContentResolver())
@@ -130,6 +286,33 @@
     }
 
     @Test
+    fun registerContentObserverSuspend_inputUri_success() =
+        testScope.runTest {
+            mSettings.registerContentObserver(TEST_SETTING_URI, mContentObserver)
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(false),
+                    eq(mContentObserver),
+                    eq(0)
+                )
+        }
+
+    @Test
+    fun registerContentObserverAsync_inputUri_success() {
+        mSettings.registerContentObserverAsync(TEST_SETTING_URI, mContentObserver)
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(false),
+                    eq(mContentObserver),
+                    eq(0)
+                )
+        }
+    }
+
+    @Test
     fun registerContentObserver_inputUri_notifyForDescendants_true() {
         mSettings.registerContentObserverSync(
             TEST_SETTING_URI,
@@ -141,6 +324,33 @@
     }
 
     @Test
+    fun registerContentObserverSuspend_inputUri_notifyForDescendants_true() =
+        testScope.runTest {
+            mSettings.registerContentObserver(TEST_SETTING_URI, mContentObserver)
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(false),
+                    eq(mContentObserver),
+                    eq(0)
+                )
+        }
+
+    @Test
+    fun registerContentObserverAsync_inputUri_notifyForDescendants_true() {
+        mSettings.registerContentObserverAsync(TEST_SETTING_URI, mContentObserver)
+        testScope.launch {
+            verify(mSettings.getContentResolver())
+                .registerContentObserver(
+                    eq(TEST_SETTING_URI),
+                    eq(false),
+                    eq(mContentObserver),
+                    eq(0)
+                )
+        }
+    }
+
+    @Test
     fun getString_keyPresent_returnValidValue() {
         mSettings.putString(TEST_SETTING, "test")
         assertThat(mSettings.getString(TEST_SETTING)).isEqualTo("test")
@@ -300,7 +510,10 @@
      *
      * This class uses a mock of [ContentResolver] to test the [ContentObserver] registration APIs.
      */
-    private class FakeUserSettingsProxy(override val userTracker: UserTracker) : UserSettingsProxy {
+    private class FakeUserSettingsProxy(
+        override val userTracker: UserTracker,
+        val testDispatcher: CoroutineDispatcher
+    ) : UserSettingsProxy {
 
         private val mContentResolver = mock(ContentResolver::class.java)
         private val userIdToSettingsValueMap: MutableMap<Int, MutableMap<String, String>> =
@@ -311,6 +524,9 @@
         override fun getUriFor(name: String) =
             Uri.parse(StringBuilder().append(URI_PREFIX).append(name).toString())
 
+        override val backgroundDispatcher: CoroutineDispatcher
+            get() = testDispatcher
+
         override fun getStringForUser(name: String, userHandle: Int) =
             userIdToSettingsValueMap[userHandle]?.get(name) ?: ""
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeControllerCollectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeControllerCollectorTest.kt
new file mode 100644
index 0000000..dd78e4a
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeControllerCollectorTest.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.volume
+
+import android.media.IVolumeController
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.settingslib.media.data.repository.VolumeControllerEvent
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class VolumeControllerCollectorTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos()
+    private val eventsFlow = MutableStateFlow<VolumeControllerEvent?>(null)
+    private val underTest = VolumeControllerCollector(kosmos.applicationCoroutineScope)
+
+    private val volumeController = mock<IVolumeController> {}
+
+    @Test
+    fun volumeControllerEvent_volumeChanged_callsMethod() =
+        testEvent(VolumeControllerEvent.VolumeChanged(3, 0)) {
+            verify(volumeController) { 1 * { volumeController.volumeChanged(eq(3), eq(0)) } }
+        }
+
+    @Test
+    fun volumeControllerEvent_dismiss_callsMethod() =
+        testEvent(VolumeControllerEvent.Dismiss) {
+            verify(volumeController) { 1 * { volumeController.dismiss() } }
+        }
+
+    @Test
+    fun volumeControllerEvent_displayCsdWarning_callsMethod() =
+        testEvent(VolumeControllerEvent.DisplayCsdWarning(0, 1)) {
+            verify(volumeController) { 1 * { volumeController.displayCsdWarning(eq(0), eq(1)) } }
+        }
+
+    @Test
+    fun volumeControllerEvent_displaySafeVolumeWarning_callsMethod() =
+        testEvent(VolumeControllerEvent.DisplaySafeVolumeWarning(1)) {
+            verify(volumeController) { 1 * { volumeController.displaySafeVolumeWarning(eq(1)) } }
+        }
+
+    @Test
+    fun volumeControllerEvent_masterMuteChanged_callsMethod() =
+        testEvent(VolumeControllerEvent.MasterMuteChanged(1)) {
+            verify(volumeController) { 1 * { volumeController.masterMuteChanged(1) } }
+        }
+
+    @Test
+    fun volumeControllerEvent_setA11yMode_callsMethod() =
+        testEvent(VolumeControllerEvent.SetA11yMode(1)) {
+            verify(volumeController) { 1 * { volumeController.setA11yMode(1) } }
+        }
+
+    @Test
+    fun volumeControllerEvent_SetLayoutDirection_callsMethod() =
+        testEvent(VolumeControllerEvent.SetLayoutDirection(1)) {
+            verify(volumeController) { 1 * { volumeController.setLayoutDirection(eq(1)) } }
+        }
+
+    private fun testEvent(event: VolumeControllerEvent, verify: () -> Unit) =
+        kosmos.testScope.runTest {
+            underTest.collectToController(eventsFlow.filterNotNull(), volumeController)
+
+            eventsFlow.value = event
+            runCurrent()
+
+            verify()
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index 4654a4d..6efb7d8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -35,6 +35,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
@@ -783,8 +784,8 @@
         mDialog.show(SHOW_REASON_UNKNOWN);
         mTestableLooper.processAllMessages();
 
-        verify(mVolumeDialogInteractor).onDialogShown();
-        verify(mVolumeDialogInteractor).onDialogDismissed(); // dismiss by timeout
+        verify(mVolumeDialogInteractor, atLeastOnce()).onDialogShown();
+        verify(mVolumeDialogInteractor, atLeastOnce()).onDialogDismissed(); // dismiss by timeout
     }
 
     /**
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryImplTest.kt
index 7d89a55..bdecf2b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/data/repository/WallpaperRepositoryImplTest.kt
@@ -20,6 +20,7 @@
 import android.app.WallpaperManager
 import android.content.Intent
 import android.content.pm.UserInfo
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
@@ -37,9 +38,11 @@
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
+import org.junit.runner.RunWith
 
 @SmallTest
 @OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidJUnit4::class)
 class WallpaperRepositoryImplTest : SysuiTestCase() {
 
     private val testDispatcher = StandardTestDispatcher()
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 fabb9b7..6c4608d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -25,6 +25,8 @@
 import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
 import static android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED;
 
+import static androidx.test.ext.truth.content.IntentSubject.assertThat;
+
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.server.notification.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING;
 import static com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_BAR;
@@ -57,6 +59,7 @@
 import android.app.IActivityManager;
 import android.app.INotificationManager;
 import android.app.Notification;
+import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -189,6 +192,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -471,7 +475,9 @@
                         mock(AvalancheProvider.class),
                         mock(SystemSettings.class),
                         mock(PackageManager.class),
-                        Optional.of(mock(Bubbles.class))
+                        Optional.of(mock(Bubbles.class)),
+                        mContext,
+                        mock(NotificationManager.class)
                         );
         interruptionDecisionProvider.start();
 
@@ -1847,6 +1853,7 @@
                 any(Bubble.class), anyBoolean(), anyBoolean());
     }
 
+    @Ignore("reason = b/351977103")
     @Test
     public void testShowStackEdu_isNotConversationBubble() {
         // Setup
@@ -2017,6 +2024,31 @@
     }
 
     @Test
+    public void testShowOrHideAppBubble_updateExistedBubbleInOverflow_updateIntentInBubble() {
+        String appBubbleKey = Bubble.getAppBubbleKeyForApp(mAppBubbleIntent.getPackage(), mUser0);
+        mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
+        // Collapse the stack so we don't need to wait for the dismiss animation in the test
+        mBubbleController.collapseStack();
+        // Dismiss the app bubble so it's in the overflow
+        mBubbleController.dismissBubble(appBubbleKey, Bubbles.DISMISS_USER_GESTURE);
+        assertThat(mBubbleData.getOverflowBubbleWithKey(appBubbleKey)).isNotNull();
+
+        // Modify the intent to include new extras.
+        Intent newAppBubbleIntent = new Intent(mContext, BubblesTestActivity.class)
+                .setPackage(mContext.getPackageName())
+                .putExtra("hello", "world");
+
+        // Calling this while collapsed will re-add and expand the app bubble
+        mBubbleController.showOrHideAppBubble(newAppBubbleIntent, mUser0, mAppBubbleIcon);
+        assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(appBubbleKey);
+        assertThat(mBubbleController.isStackExpanded()).isTrue();
+        assertThat(mBubbleData.getBubbles().size()).isEqualTo(1);
+        assertThat(mBubbleData.getBubbles().get(0).getAppBubbleIntent()).extras().string(
+                "hello").isEqualTo("world");
+        assertThat(mBubbleData.getOverflowBubbleWithKey(appBubbleKey)).isNull();
+    }
+
+    @Test
     public void testCreateBubbleFromOngoingNotification() {
         NotificationEntry notif = new NotificationEntryBuilder()
                 .setFlag(mContext, Notification.FLAG_ONGOING_EVENT, true)
diff --git a/packages/SystemUI/tests/utils/src/android/app/admin/AlarmManagerKosmos.kt b/packages/SystemUI/tests/utils/src/android/app/admin/AlarmManagerKosmos.kt
new file mode 100644
index 0000000..a7b5873
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/android/app/admin/AlarmManagerKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.admin
+
+import android.app.AlarmManager
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.util.mockito.mock
+
+var Kosmos.alarmManager by Kosmos.Fixture { mock<AlarmManager>() }
diff --git a/packages/SystemUI/tests/utils/src/android/content/PackageManagerKosmos.kt b/packages/SystemUI/tests/utils/src/android/content/PackageManagerKosmos.kt
index 8901314..9d7d916 100644
--- a/packages/SystemUI/tests/utils/src/android/content/PackageManagerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/android/content/PackageManagerKosmos.kt
@@ -17,6 +17,13 @@
 
 import android.content.pm.PackageManager
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.shared.system.PackageManagerWrapper
 import com.android.systemui.util.mockito.mock
 
-val Kosmos.packageManager by Kosmos.Fixture { mock<PackageManager>() }
+val Kosmos.mockPackageManager by Kosmos.Fixture { mock<PackageManager>() }
+
+var Kosmos.packageManager by Kosmos.Fixture { mockPackageManager }
+
+val Kosmos.mockPackageManagerWrapper by Kosmos.Fixture { mock<PackageManagerWrapper>() }
+
+var Kosmos.packageManagerWrapper by Kosmos.Fixture { mockPackageManagerWrapper }
diff --git a/packages/SystemUI/tests/utils/src/android/hardware/display/AmbientDisplayConfigurationKosmos.kt b/packages/SystemUI/tests/utils/src/android/hardware/display/AmbientDisplayConfigurationKosmos.kt
new file mode 100644
index 0000000..3f3c30f
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/android/hardware/display/AmbientDisplayConfigurationKosmos.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.display
+
+import android.content.applicationContext
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+
+val Kosmos.ambientDisplayConfiguration by Fixture {
+    FakeAmbientDisplayConfiguration(applicationContext)
+}
diff --git a/packages/SystemUI/tests/utils/src/android/hardware/input/FakeInputManager.kt b/packages/SystemUI/tests/utils/src/android/hardware/input/FakeInputManager.kt
new file mode 100644
index 0000000..c4f93d1
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/android/hardware/input/FakeInputManager.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.input
+
+import android.view.InputDevice
+import android.view.KeyCharacterMap
+import android.view.KeyCharacterMap.VIRTUAL_KEYBOARD
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.invocation.InvocationOnMock
+
+class FakeInputManager {
+
+    private val keyCharacterMap = KeyCharacterMap.load(VIRTUAL_KEYBOARD)
+
+    private val virtualKeyboard =
+        InputDevice.Builder()
+            .setId(VIRTUAL_KEYBOARD)
+            .setKeyboardType(InputDevice.KEYBOARD_TYPE_ALPHABETIC)
+            .setSources(InputDevice.SOURCE_KEYBOARD)
+            .setEnabled(true)
+            .setKeyCharacterMap(keyCharacterMap)
+            .build()
+
+    private val devices = mutableMapOf<Int, InputDevice>(VIRTUAL_KEYBOARD to virtualKeyboard)
+
+    val inputManager =
+        mock<InputManager> {
+            whenever(getInputDevice(anyInt())).thenAnswer { invocation ->
+                val deviceId = invocation.arguments[0] as Int
+                return@thenAnswer devices[deviceId]
+            }
+            whenever(inputDeviceIds).thenAnswer {
+                return@thenAnswer devices.keys.toIntArray()
+            }
+
+            fun setDeviceEnabled(invocation: InvocationOnMock, enabled: Boolean) {
+                val deviceId = invocation.arguments[0] as Int
+                val device = devices[deviceId] ?: return
+                devices[deviceId] = device.copy(enabled = enabled)
+            }
+
+            whenever(disableInputDevice(anyInt())).thenAnswer { invocation ->
+                setDeviceEnabled(invocation, enabled = false)
+            }
+            whenever(enableInputDevice(anyInt())).thenAnswer { invocation ->
+                setDeviceEnabled(invocation, enabled = true)
+            }
+        }
+
+    fun addPhysicalKeyboard(id: Int, enabled: Boolean = true) {
+        check(id > 0) { "Physical keyboard ids have to be > 0" }
+        addKeyboard(id, enabled)
+    }
+
+    private fun addKeyboard(id: Int, enabled: Boolean = true) {
+        devices[id] =
+            InputDevice.Builder()
+                .setId(id)
+                .setKeyboardType(InputDevice.KEYBOARD_TYPE_ALPHABETIC)
+                .setSources(InputDevice.SOURCE_KEYBOARD)
+                .setEnabled(enabled)
+                .setKeyCharacterMap(keyCharacterMap)
+                .build()
+    }
+
+    private fun InputDevice.copy(
+        id: Int = getId(),
+        type: Int = keyboardType,
+        sources: Int = getSources(),
+        enabled: Boolean = isEnabled
+    ) =
+        InputDevice.Builder()
+            .setId(id)
+            .setKeyboardType(type)
+            .setSources(sources)
+            .setEnabled(enabled)
+            .build()
+}
diff --git a/packages/SystemUI/tests/utils/src/android/hardware/input/InputManagerKosmos.kt b/packages/SystemUI/tests/utils/src/android/hardware/input/InputManagerKosmos.kt
new file mode 100644
index 0000000..bf68eab
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/android/hardware/input/InputManagerKosmos.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.input
+
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.fakeInputManager by Kosmos.Fixture { FakeInputManager() }
diff --git a/packages/SystemUI/tests/utils/src/android/view/LayoutInflaterKosmos.kt b/packages/SystemUI/tests/utils/src/android/view/LayoutInflaterKosmos.kt
index 21dea6b..2ee289b 100644
--- a/packages/SystemUI/tests/utils/src/android/view/LayoutInflaterKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/android/view/LayoutInflaterKosmos.kt
@@ -18,6 +18,8 @@
 
 import android.content.applicationContext
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.util.mockito.mock
 
 var Kosmos.layoutInflater: LayoutInflater by
     Kosmos.Fixture { LayoutInflater.from(applicationContext) }
+var Kosmos.mockedLayoutInflater: LayoutInflater by Kosmos.Fixture { mock<LayoutInflater>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/app/admin/DevicePolicyManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/app/admin/DevicePolicyManagerKosmos.kt
new file mode 100644
index 0000000..f51e122
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/app/admin/DevicePolicyManagerKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.admin
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.util.mockito.mock
+
+val Kosmos.devicePolicyManager by Kosmos.Fixture { mock<android.app.admin.DevicePolicyManager>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/internal/widget/LockPatternUtilsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/internal/widget/LockPatternUtilsKosmos.kt
index d9ea5e9..b511270 100644
--- a/packages/SystemUI/tests/utils/src/com/android/internal/widget/LockPatternUtilsKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/internal/widget/LockPatternUtilsKosmos.kt
@@ -16,7 +16,14 @@
 
 package com.android.internal.widget
 
+import android.app.admin.devicePolicyManager
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
 
-var Kosmos.lockPatternUtils by Kosmos.Fixture { mock<LockPatternUtils>() }
+var Kosmos.lockPatternUtils by
+    Kosmos.Fixture {
+        mock<LockPatternUtils>().apply {
+            whenever(this.devicePolicyManager).thenReturn(this@Fixture.devicePolicyManager)
+        }
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
index 8eef930..a124b34 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
@@ -21,7 +21,6 @@
 import android.app.Instrumentation;
 import android.content.Context;
 import android.content.res.Resources;
-import android.os.Build;
 import android.os.Handler;
 import android.os.HandlerExecutor;
 import android.os.Looper;
@@ -44,7 +43,7 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.uiautomator.UiDevice;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.systemui.broadcast.FakeBroadcastDispatcher;
 import com.android.systemui.flags.SceneContainerRule;
 
@@ -297,7 +296,7 @@
     }
 
     public static boolean isRobolectricTest() {
-        return !isRavenwoodTest() && Build.FINGERPRINT.contains("robolectric");
+        return !isRavenwoodTest() && !System.getProperty("java.vm.name").equals("Dalvik");
     }
 
     protected boolean isScreenshotTest() {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
index 9dae44d..7c53639 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
@@ -18,6 +18,7 @@
 import android.app.ActivityManager
 import android.app.admin.DevicePolicyManager
 import android.app.trust.TrustManager
+import android.hardware.fingerprint.FingerprintManager
 import android.os.UserManager
 import android.service.notification.NotificationListenerService
 import android.util.DisplayMetrics
@@ -94,6 +95,7 @@
     @get:Provides val deviceProvisionedController: DeviceProvisionedController = mock(),
     @get:Provides val dozeParameters: DozeParameters = mock(),
     @get:Provides val dumpManager: DumpManager = mock(),
+    @get:Provides val fingerprintManager: FingerprintManager = mock(),
     @get:Provides val headsUpManager: HeadsUpManager = mock(),
     @get:Provides val guestResumeSessionReceiver: GuestResumeSessionReceiver = mock(),
     @get:Provides val keyguardBypassController: KeyguardBypassController = mock(),
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/assist/AssistManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/assist/AssistManagerKosmos.kt
index b7d6f3a..22eb646 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/assist/AssistManagerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/assist/AssistManagerKosmos.kt
@@ -19,4 +19,6 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.util.mockito.mock
 
-var Kosmos.assistManager by Kosmos.Fixture { mock<AssistManager>() }
+val Kosmos.mockAssistManager by Kosmos.Fixture { mock<AssistManager>() }
+
+var Kosmos.assistManager by Kosmos.Fixture { mockAssistManager }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorKosmos.kt
index cbfc768..ae592b9 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorKosmos.kt
@@ -17,17 +17,20 @@
 package com.android.systemui.biometrics.domain.interactor
 
 import android.content.applicationContext
+import android.hardware.fingerprint.FingerprintManager
 import com.android.systemui.biometrics.authController
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.user.domain.interactor.selectedUserInteractor
+import com.android.systemui.util.mockito.mock
 
 val Kosmos.udfpsOverlayInteractor by Fixture {
     UdfpsOverlayInteractor(
         context = applicationContext,
         authController = authController,
         selectedUserInteractor = selectedUserInteractor,
+        fingerprintManager = mock<FingerprintManager>(),
         scope = applicationCoroutineScope,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelKosmos.kt
index 4999a5a..43b57de 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModelKosmos.kt
@@ -26,6 +26,8 @@
 import com.android.systemui.biometrics.udfpsUtils
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.util.mockito.mock
+import org.mockito.Mockito.mock
 
 val Kosmos.promptViewModel by Fixture {
     PromptViewModel(
@@ -35,7 +37,9 @@
         udfpsOverlayInteractor = udfpsOverlayInteractor,
         biometricStatusInteractor = biometricStatusInteractor,
         udfpsUtils = udfpsUtils,
-        iconProvider = IconProvider(applicationContext),
+        iconProvider = iconProvider,
         activityTaskManager = activityTaskManager,
     )
 }
+
+val Kosmos.iconProvider by Fixture { mock<IconProvider>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorKosmos.kt
index f75cdd4..9236bd2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorKosmos.kt
@@ -20,6 +20,7 @@
 import com.android.systemui.biometrics.data.repository.fingerprintPropertyRepository
 import com.android.systemui.bouncer.data.repository.keyguardBouncerRepository
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryFingerprintAuthInteractor
+import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor
 import com.android.systemui.keyguard.data.repository.biometricSettingsRepository
 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
@@ -28,6 +29,7 @@
 import com.android.systemui.plugins.statusbar.statusBarStateController
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.statusbar.policy.keyguardStateController
+import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.systemClock
 
 val Kosmos.alternateBouncerInteractor: AlternateBouncerInteractor by
@@ -47,3 +49,24 @@
             sceneInteractor = { sceneInteractor },
         )
     }
+
+fun Kosmos.givenCanShowAlternateBouncer() {
+    this.givenAlternateBouncerSupported()
+    this.keyguardBouncerRepository.setPrimaryShow(false)
+    this.biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
+    this.biometricSettingsRepository.setIsFingerprintAuthCurrentlyAllowed(true)
+    whenever(this.keyguardUpdateMonitor.isFingerprintLockedOut).thenReturn(false)
+    whenever(this.keyguardStateController.isUnlocked).thenReturn(false)
+}
+
+fun Kosmos.givenAlternateBouncerSupported() {
+    if (DeviceEntryUdfpsRefactor.isEnabled) {
+        this.fingerprintPropertyRepository.supportsUdfps()
+    } else {
+        this.keyguardBouncerRepository.setAlternateBouncerUIAvailable(true)
+    }
+}
+
+fun Kosmos.givenCannotShowAlternateBouncer() {
+    this.biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(false)
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalPrefsRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalPrefsRepository.kt
index d3ed58b..1da1fb2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalPrefsRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/data/repository/FakeCommunalPrefsRepository.kt
@@ -17,16 +17,28 @@
 
 package com.android.systemui.communal.data.repository
 
+import android.content.pm.UserInfo
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.map
 
 /** Fake implementation of [CommunalPrefsRepository] */
 class FakeCommunalPrefsRepository : CommunalPrefsRepository {
-    private val _isCtaDismissed = MutableStateFlow(false)
-    override val isCtaDismissed: Flow<Boolean> = _isCtaDismissed.asStateFlow()
+    private val _isCtaDismissed = MutableStateFlow<Set<UserInfo>>(emptySet())
+    private val _isDisclaimerDismissed = MutableStateFlow<Set<UserInfo>>(emptySet())
 
-    override suspend fun setCtaDismissedForCurrentUser() {
-        _isCtaDismissed.value = true
+    override fun isCtaDismissed(user: UserInfo): Flow<Boolean> =
+        _isCtaDismissed.map { it.contains(user) }
+
+    override fun isDisclaimerDismissed(user: UserInfo): Flow<Boolean> =
+        _isDisclaimerDismissed.map { it.contains(user) }
+
+    override suspend fun setCtaDismissed(user: UserInfo) {
+        _isCtaDismissed.value = _isCtaDismissed.value.toMutableSet().apply { add(user) }
+    }
+
+    override suspend fun setDisclaimerDismissed(user: UserInfo) {
+        _isDisclaimerDismissed.value =
+            _isDisclaimerDismissed.value.toMutableSet().apply { add(user) }
     }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
index 1583d1c..b58861b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalInteractorKosmos.kt
@@ -19,7 +19,6 @@
 import android.os.userManager
 import com.android.systemui.broadcast.broadcastDispatcher
 import com.android.systemui.communal.data.repository.communalMediaRepository
-import com.android.systemui.communal.data.repository.communalPrefsRepository
 import com.android.systemui.communal.data.repository.communalWidgetRepository
 import com.android.systemui.communal.widgets.EditWidgetsActivityStarter
 import com.android.systemui.flags.Flags
@@ -46,7 +45,7 @@
         broadcastDispatcher = broadcastDispatcher,
         communalSceneInteractor = communalSceneInteractor,
         widgetRepository = communalWidgetRepository,
-        communalPrefsRepository = communalPrefsRepository,
+        communalPrefsInteractor = communalPrefsInteractor,
         mediaRepository = communalMediaRepository,
         smartspaceRepository = smartspaceRepository,
         keyguardInteractor = keyguardInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalPrefsInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalPrefsInteractorKosmos.kt
new file mode 100644
index 0000000..37563c4
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/communal/domain/interactor/CommunalPrefsInteractorKosmos.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.communal.domain.interactor
+
+import com.android.systemui.communal.data.repository.communalPrefsRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.settings.userTracker
+import com.android.systemui.user.domain.interactor.selectedUserInteractor
+import com.android.systemui.util.mockito.mock
+
+var Kosmos.communalPrefsInteractor: CommunalPrefsInteractor by
+    Kosmos.Fixture {
+        CommunalPrefsInteractor(
+            applicationCoroutineScope,
+            communalPrefsRepository,
+            selectedUserInteractor,
+            userTracker,
+            tableLogBuffer = mock()
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceconfig/data/repository/DeviceConfigRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceconfig/data/repository/DeviceConfigRepositoryKosmos.kt
new file mode 100644
index 0000000..e4efadbd
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceconfig/data/repository/DeviceConfigRepositoryKosmos.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.deviceconfig.data.repository
+
+import com.android.systemui.concurrency.fakeExecutor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.util.deviceConfigProxy
+
+val Kosmos.deviceConfigRepository by Fixture {
+    DeviceConfigRepository(
+        backgroundExecutor = fakeExecutor,
+        backgroundDispatcher = testDispatcher,
+        dataSource = deviceConfigProxy,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceconfig/domain/interactor/DeviceConfigInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceconfig/domain/interactor/DeviceConfigInteractorKosmos.kt
new file mode 100644
index 0000000..d538497
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceconfig/domain/interactor/DeviceConfigInteractorKosmos.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.deviceconfig.domain.interactor
+
+import com.android.systemui.deviceconfig.data.repository.deviceConfigRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+
+val Kosmos.deviceConfigInteractor by Fixture {
+    DeviceConfigInteractor(
+        repository = deviceConfigRepository,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt
index 045bd5d..25e7729 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt
@@ -30,10 +30,16 @@
     private val _isBypassEnabled = MutableStateFlow(false)
     override val isBypassEnabled: StateFlow<Boolean> = _isBypassEnabled
 
+    var userPresentCount = 0
+
     override suspend fun isLockscreenEnabled(): Boolean {
         return isLockscreenEnabled
     }
 
+    override suspend fun reportUserPresent() {
+        userPresentCount++
+    }
+
     fun setLockscreenEnabled(isLockscreenEnabled: Boolean) {
         this.isLockscreenEnabled = isLockscreenEnabled
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
index 3401cc4..f436a68 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
@@ -17,10 +17,20 @@
 package com.android.systemui.keyboard.shortcut
 
 import android.content.applicationContext
+import android.content.res.mainResources
+import android.hardware.input.fakeInputManager
+import android.view.windowManager
 import com.android.systemui.broadcast.broadcastDispatcher
-import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperRepository
+import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperCategoriesRepository
+import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperStateRepository
 import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperTestHelper
-import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutHelperInteractor
+import com.android.systemui.keyboard.shortcut.data.source.AppCategoriesShortcutsSource
+import com.android.systemui.keyboard.shortcut.data.source.InputShortcutsSource
+import com.android.systemui.keyboard.shortcut.data.source.KeyboardShortcutGroupsSource
+import com.android.systemui.keyboard.shortcut.data.source.MultitaskingShortcutsSource
+import com.android.systemui.keyboard.shortcut.data.source.SystemShortcutsSource
+import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutHelperCategoriesInteractor
+import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutHelperStateInteractor
 import com.android.systemui.keyboard.shortcut.ui.ShortcutHelperActivityStarter
 import com.android.systemui.keyboard.shortcut.ui.viewmodel.ShortcutHelperViewModel
 import com.android.systemui.keyguard.data.repository.fakeCommandQueue
@@ -30,27 +40,83 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.model.sysUiState
 import com.android.systemui.settings.displayTracker
+import com.android.systemui.util.icons.fakeAppCategoryIconProvider
 
-val Kosmos.shortcutHelperRepository by
-    Kosmos.Fixture { ShortcutHelperRepository(fakeCommandQueue, broadcastDispatcher) }
+var Kosmos.shortcutHelperAppCategoriesShortcutsSource: KeyboardShortcutGroupsSource by
+    Kosmos.Fixture {
+        AppCategoriesShortcutsSource(
+            fakeAppCategoryIconProvider,
+            mainResources,
+        )
+    }
+
+var Kosmos.shortcutHelperSystemShortcutsSource: KeyboardShortcutGroupsSource by
+    Kosmos.Fixture { SystemShortcutsSource(mainResources) }
+
+var Kosmos.shortcutHelperMultiTaskingShortcutsSource: KeyboardShortcutGroupsSource by
+    Kosmos.Fixture { MultitaskingShortcutsSource(mainResources) }
+
+val Kosmos.shortcutHelperStateRepository by
+    Kosmos.Fixture {
+        ShortcutHelperStateRepository(
+            fakeCommandQueue,
+            broadcastDispatcher,
+            fakeInputManager.inputManager,
+            testScope,
+            testDispatcher
+        )
+    }
+
+val Kosmos.shortcutHelperInputShortcutsSource by
+    Kosmos.Fixture { InputShortcutsSource(mainResources, windowManager) }
+
+val Kosmos.shortcutHelperCategoriesRepository by
+    Kosmos.Fixture {
+        ShortcutHelperCategoriesRepository(
+            applicationContext,
+            testDispatcher,
+            shortcutHelperSystemShortcutsSource,
+            shortcutHelperMultiTaskingShortcutsSource,
+            shortcutHelperAppCategoriesShortcutsSource,
+            shortcutHelperInputShortcutsSource,
+            fakeInputManager.inputManager,
+            shortcutHelperStateRepository,
+        )
+    }
 
 val Kosmos.shortcutHelperTestHelper by
     Kosmos.Fixture {
         ShortcutHelperTestHelper(
-            shortcutHelperRepository,
+            shortcutHelperStateRepository,
             applicationContext,
             broadcastDispatcher,
-            fakeCommandQueue
+            fakeCommandQueue,
+            windowManager
         )
     }
 
-val Kosmos.shortcutHelperInteractor by
+val Kosmos.shortcutHelperStateInteractor by
     Kosmos.Fixture {
-        ShortcutHelperInteractor(displayTracker, testScope, sysUiState, shortcutHelperRepository)
+        ShortcutHelperStateInteractor(
+            displayTracker,
+            testScope,
+            sysUiState,
+            shortcutHelperStateRepository
+        )
     }
 
+val Kosmos.shortcutHelperCategoriesInteractor by
+    Kosmos.Fixture { ShortcutHelperCategoriesInteractor(shortcutHelperCategoriesRepository) }
+
 val Kosmos.shortcutHelperViewModel by
-    Kosmos.Fixture { ShortcutHelperViewModel(testDispatcher, shortcutHelperInteractor) }
+    Kosmos.Fixture {
+        ShortcutHelperViewModel(
+            applicationCoroutineScope,
+            testDispatcher,
+            shortcutHelperStateInteractor,
+            shortcutHelperCategoriesInteractor
+        )
+    }
 
 val Kosmos.fakeShortcutHelperStartActivity by Kosmos.Fixture { FakeShortcutHelperStartActivity() }
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperTestHelper.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperTestHelper.kt
index e6e7b87..40510db 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperTestHelper.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperTestHelper.kt
@@ -18,20 +18,45 @@
 
 import android.content.Context
 import android.content.Intent
+import android.view.KeyboardShortcutGroup
+import android.view.WindowManager
+import android.view.WindowManager.KeyboardShortcutsReceiver
 import com.android.systemui.broadcast.FakeBroadcastDispatcher
 import com.android.systemui.keyguard.data.repository.FakeCommandQueue
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.whenever
 
 class ShortcutHelperTestHelper(
-    repo: ShortcutHelperRepository,
+    repo: ShortcutHelperStateRepository,
     private val context: Context,
     private val fakeBroadcastDispatcher: FakeBroadcastDispatcher,
     private val fakeCommandQueue: FakeCommandQueue,
+    windowManager: WindowManager
 ) {
 
+    companion object {
+        const val DEFAULT_DEVICE_ID = 123
+    }
+
+    private var imeShortcuts: List<KeyboardShortcutGroup> = emptyList()
+
     init {
+        whenever(windowManager.requestImeKeyboardShortcuts(any(), any())).thenAnswer {
+            val keyboardShortcutReceiver = it.getArgument<KeyboardShortcutsReceiver>(0)
+            keyboardShortcutReceiver.onKeyboardShortcutsReceived(imeShortcuts)
+            return@thenAnswer Unit
+        }
         repo.start()
     }
 
+    /**
+     * Use this method to set what ime shortcuts should be returned from windowManager in tests. By
+     * default windowManager.requestImeKeyboardShortcuts will return emptyList. See init block.
+     */
+    fun setImeShortcuts(imeShortcuts: List<KeyboardShortcutGroup>) {
+        this.imeShortcuts = imeShortcuts
+    }
+
     fun hideThroughCloseSystemDialogs() {
         fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
             context,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/source/FakeKeyboardShortcutGroupsSource.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/source/FakeKeyboardShortcutGroupsSource.kt
new file mode 100644
index 0000000..2bab1a4
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/source/FakeKeyboardShortcutGroupsSource.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyboard.shortcut.data.source
+
+import android.view.KeyboardShortcutGroup
+
+class FakeKeyboardShortcutGroupsSource : KeyboardShortcutGroupsSource {
+
+    private var groups = listOf<KeyboardShortcutGroup>()
+
+    override suspend fun shortcutGroups(deviceId: Int): List<KeyboardShortcutGroup> = groups
+
+    fun setGroups(groups: List<KeyboardShortcutGroup>) {
+        this.groups = groups
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/DismissCallbackRegistryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/DismissCallbackRegistryKosmos.kt
new file mode 100644
index 0000000..b12f947
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/DismissCallbackRegistryKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyguard
+
+import com.android.systemui.concurrency.fakeExecutor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+
+val Kosmos.dismissCallbackRegistry by Fixture { DismissCallbackRegistry(fakeExecutor) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
index 2d100f0..87143ef 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardRepository.kt
@@ -119,6 +119,8 @@
     private val _keyguardAlpha = MutableStateFlow(1f)
     override val keyguardAlpha: StateFlow<Float> = _keyguardAlpha
 
+    override val panelAlpha: MutableStateFlow<Float> = MutableStateFlow(1f)
+
     override val lastRootViewTapPosition: MutableStateFlow<Point?> = MutableStateFlow(null)
 
     override val ambientIndicationVisible: MutableStateFlow<Boolean> = MutableStateFlow(false)
@@ -131,6 +133,11 @@
 
     override val topClippingBounds = MutableStateFlow<Int?>(null)
 
+    private var isShowKeyguardWhenReenabled: Boolean = false
+
+    private val _canIgnoreAuthAndReturnToGone = MutableStateFlow(false)
+    override val canIgnoreAuthAndReturnToGone = _canIgnoreAuthAndReturnToGone.asStateFlow()
+
     override fun setQuickSettingsVisible(isVisible: Boolean) {
         _isQuickSettingsVisible.value = isVisible
     }
@@ -259,9 +266,25 @@
         _keyguardAlpha.value = alpha
     }
 
+    override fun setPanelAlpha(alpha: Float) {
+        panelAlpha.value = alpha
+    }
+
     fun setIsEncryptedOrLockdown(value: Boolean) {
         _isEncryptedOrLockdown.value = value
     }
+
+    override fun setShowKeyguardWhenReenabled(isShowKeyguardWhenReenabled: Boolean) {
+        this.isShowKeyguardWhenReenabled = isShowKeyguardWhenReenabled
+    }
+
+    override fun isShowKeyguardWhenReenabled(): Boolean {
+        return isShowKeyguardWhenReenabled
+    }
+
+    override fun setCanIgnoreAuthAndReturnToGone(canWake: Boolean) {
+        _canIgnoreAuthAndReturnToGone.value = canWake
+    }
 }
 
 @Module
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeTrustRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeTrustRepository.kt
index cd83c2f..39a1a63 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeTrustRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeTrustRepository.kt
@@ -33,9 +33,10 @@
     private val _isTrustUsuallyManaged = MutableStateFlow(false)
     override val isCurrentUserTrustUsuallyManaged: StateFlow<Boolean>
         get() = _isTrustUsuallyManaged
+
     private val _isCurrentUserTrusted = MutableStateFlow(false)
-    override val isCurrentUserTrusted: Flow<Boolean>
-        get() = _isCurrentUserTrusted
+    override val isCurrentUserTrusted: StateFlow<Boolean>
+        get() = _isCurrentUserTrusted.asStateFlow()
 
     private val _isCurrentUserActiveUnlockAvailable = MutableStateFlow(false)
     override val isCurrentUserActiveUnlockRunning: StateFlow<Boolean> =
@@ -48,6 +49,13 @@
     private val _requestDismissKeyguard = MutableStateFlow(TrustModel(false, 0, TrustGrantFlags(0)))
     override val trustAgentRequestingToDismissKeyguard: Flow<TrustModel> = _requestDismissKeyguard
 
+    var keyguardShowingChangeEventCount: Int = 0
+        private set
+
+    override suspend fun reportKeyguardShowingChanged() {
+        keyguardShowingChangeEventCount++
+    }
+
     fun setCurrentUserTrusted(trust: Boolean) {
         _isCurrentUserTrusted.value = trust
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorKosmos.kt
index 78a419f..ce317d4 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractorKosmos.kt
@@ -32,6 +32,7 @@
         FromAlternateBouncerTransitionInteractor(
             transitionRepository = keyguardTransitionRepository,
             transitionInteractor = keyguardTransitionInteractor,
+            internalTransitionInteractor = internalKeyguardTransitionInteractor,
             scope = applicationCoroutineScope,
             bgDispatcher = testDispatcher,
             mainDispatcher = testDispatcher,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt
index 42af25e..ef789d1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorKosmos.kt
@@ -29,6 +29,7 @@
         FromAodTransitionInteractor(
             transitionRepository = fakeKeyguardTransitionRepository,
             transitionInteractor = keyguardTransitionInteractor,
+            internalTransitionInteractor = internalKeyguardTransitionInteractor,
             scope = applicationCoroutineScope,
             bgDispatcher = testDispatcher,
             mainDispatcher = testDispatcher,
@@ -36,5 +37,6 @@
             powerInteractor = powerInteractor,
             keyguardOcclusionInteractor = keyguardOcclusionInteractor,
             deviceEntryRepository = deviceEntryRepository,
+            wakeToGoneInteractor = keyguardWakeDirectlyToGoneInteractor,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt
index edf77a0..446652c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractorKosmos.kt
@@ -30,6 +30,7 @@
         FromDozingTransitionInteractor(
             transitionRepository = keyguardTransitionRepository,
             transitionInteractor = keyguardTransitionInteractor,
+            internalTransitionInteractor = internalKeyguardTransitionInteractor,
             scope = applicationCoroutineScope,
             bgDispatcher = testDispatcher,
             mainDispatcher = testDispatcher,
@@ -38,5 +39,6 @@
             powerInteractor = powerInteractor,
             keyguardOcclusionInteractor = keyguardOcclusionInteractor,
             deviceEntryRepository = deviceEntryRepository,
+            wakeToGoneInteractor = keyguardWakeDirectlyToGoneInteractor,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractorKosmos.kt
index f7a9d59..7ebef10 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractorKosmos.kt
@@ -28,6 +28,7 @@
         FromDreamingLockscreenHostedTransitionInteractor(
             transitionRepository = keyguardTransitionRepository,
             transitionInteractor = keyguardTransitionInteractor,
+            internalTransitionInteractor = internalKeyguardTransitionInteractor,
             scope = applicationCoroutineScope,
             bgDispatcher = testDispatcher,
             mainDispatcher = testDispatcher,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorKosmos.kt
index 135644c..6c3de44 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractorKosmos.kt
@@ -16,18 +16,22 @@
 
 package com.android.systemui.keyguard.domain.interactor
 
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
 import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 
+@OptIn(ExperimentalCoroutinesApi::class)
 var Kosmos.fromDreamingTransitionInteractor by
     Kosmos.Fixture {
         FromDreamingTransitionInteractor(
             transitionRepository = keyguardTransitionRepository,
             transitionInteractor = keyguardTransitionInteractor,
+            internalTransitionInteractor = internalKeyguardTransitionInteractor,
             scope = applicationCoroutineScope,
             bgDispatcher = testDispatcher,
             mainDispatcher = testDispatcher,
@@ -35,5 +39,6 @@
             glanceableHubTransitions = glanceableHubTransitions,
             powerInteractor = powerInteractor,
             keyguardOcclusionInteractor = keyguardOcclusionInteractor,
+            deviceEntryInteractor = deviceEntryInteractor,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractorKosmos.kt
index 1695327..6784658 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractorKosmos.kt
@@ -28,6 +28,7 @@
         FromGlanceableHubTransitionInteractor(
             transitionRepository = keyguardTransitionRepository,
             transitionInteractor = keyguardTransitionInteractor,
+            internalTransitionInteractor = internalKeyguardTransitionInteractor,
             scope = applicationCoroutineScope,
             bgDispatcher = testDispatcher,
             mainDispatcher = testDispatcher,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorKosmos.kt
index 4039ee6..317294f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractorKosmos.kt
@@ -31,6 +31,7 @@
         FromGoneTransitionInteractor(
             transitionRepository = fakeKeyguardTransitionRepository,
             transitionInteractor = keyguardTransitionInteractor,
+            internalTransitionInteractor = internalKeyguardTransitionInteractor,
             scope = applicationCoroutineScope,
             bgDispatcher = testDispatcher,
             mainDispatcher = testDispatcher,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorKosmos.kt
index 28bd439..4131145 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorKosmos.kt
@@ -29,6 +29,7 @@
         FromLockscreenTransitionInteractor(
             transitionRepository = keyguardTransitionRepository,
             transitionInteractor = keyguardTransitionInteractor,
+            internalTransitionInteractor = internalKeyguardTransitionInteractor,
             scope = applicationCoroutineScope,
             bgDispatcher = testDispatcher,
             mainDispatcher = testDispatcher,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorKosmos.kt
index fc740a1..c216945 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractorKosmos.kt
@@ -29,6 +29,7 @@
         FromOccludedTransitionInteractor(
             transitionRepository = keyguardTransitionRepository,
             transitionInteractor = keyguardTransitionInteractor,
+            internalTransitionInteractor = internalKeyguardTransitionInteractor,
             scope = applicationCoroutineScope,
             bgDispatcher = testDispatcher,
             mainDispatcher = testDispatcher,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorKosmos.kt
index d72b9c1..42ee152 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractorKosmos.kt
@@ -31,6 +31,7 @@
         FromPrimaryBouncerTransitionInteractor(
             transitionRepository = keyguardTransitionRepository,
             transitionInteractor = keyguardTransitionInteractor,
+            internalTransitionInteractor = internalKeyguardTransitionInteractor,
             scope = applicationCoroutineScope,
             bgDispatcher = testDispatcher,
             mainDispatcher = testDispatcher,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/InternalKeyguardTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/InternalKeyguardTransitionInteractorKosmos.kt
new file mode 100644
index 0000000..017a9ec
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/InternalKeyguardTransitionInteractorKosmos.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyguard.domain.interactor
+
+import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.internalKeyguardTransitionInteractor by
+    Kosmos.Fixture {
+        InternalKeyguardTransitionInteractor(
+            repository = keyguardTransitionRepository,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractorKosmos.kt
index 0667a6b..c6b5ed0 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardEnabledInteractorKosmos.kt
@@ -28,5 +28,6 @@
             keyguardRepository,
             biometricSettingsRepository,
             keyguardTransitionInteractor,
+            internalTransitionInteractor = internalKeyguardTransitionInteractor,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt
index c06f833..73799b6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorKosmos.kt
@@ -24,10 +24,11 @@
 import com.android.systemui.keyguard.data.repository.keyguardRepository
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.shade.pulsingGestureListener
 
-val Kosmos.keyguardLongPressInteractor by
+val Kosmos.keyguardTouchHandlingInteractor by
     Kosmos.Fixture {
-        KeyguardLongPressInteractor(
+        KeyguardTouchHandlingInteractor(
             appContext = applicationContext,
             scope = applicationCoroutineScope,
             transitionInteractor = keyguardTransitionInteractor,
@@ -36,5 +37,6 @@
             featureFlags = featureFlagsClassic,
             broadcastDispatcher = broadcastDispatcher,
             accessibilityManager = accessibilityManagerWrapper,
+            pulsingGestureListener = pulsingGestureListener,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractorKosmos.kt
index 7d8d33f..5836902 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionBootInteractorKosmos.kt
@@ -30,5 +30,6 @@
             deviceProvisioningInteractor = deviceProvisioningInteractor,
             keyguardTransitionInteractor = keyguardTransitionInteractor,
             repository = keyguardTransitionRepository,
+            internalTransitionInteractor = internalKeyguardTransitionInteractor,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorKosmos.kt
index c90642d..c5da10e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorKosmos.kt
@@ -33,6 +33,6 @@
             fromAodTransitionInteractor = { fromAodTransitionInteractor },
             fromAlternateBouncerTransitionInteractor = { fromAlternateBouncerTransitionInteractor },
             fromDozingTransitionInteractor = { fromDozingTransitionInteractor },
-            sceneInteractor = { sceneInteractor }
+            sceneInteractor = sceneInteractor
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorKosmos.kt
new file mode 100644
index 0000000..63e168d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardWakeDirectlyToGoneInteractorKosmos.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyguard.domain.interactor
+
+import android.app.admin.alarmManager
+import android.content.mockedContext
+import com.android.internal.widget.lockPatternUtils
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.user.domain.interactor.selectedUserInteractor
+import com.android.systemui.util.settings.fakeSettings
+import com.android.systemui.util.time.systemClock
+
+val Kosmos.keyguardWakeDirectlyToGoneInteractor by
+    Kosmos.Fixture {
+        KeyguardWakeDirectlyToGoneInteractor(
+            applicationCoroutineScope,
+            mockedContext,
+            fakeKeyguardRepository,
+            systemClock,
+            alarmManager,
+            keyguardTransitionInteractor,
+            powerInteractor,
+            fakeSettings,
+            lockPatternUtils,
+            fakeSettings,
+            selectedUserInteractor,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/TrustInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/TrustInteractorKosmos.kt
index 0ebf164..d60326c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/TrustInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/TrustInteractorKosmos.kt
@@ -19,5 +19,11 @@
 import com.android.systemui.keyguard.data.repository.trustRepository
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.applicationCoroutineScope
 
-val Kosmos.trustInteractor by Fixture { TrustInteractor(repository = trustRepository) }
+val Kosmos.trustInteractor by Fixture {
+    TrustInteractor(
+        applicationScope = applicationCoroutineScope,
+        repository = trustRepository,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt
index bd9c0be..8bb2fce 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorKosmos.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.keyguard.domain.interactor
 
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.statusbar.notification.domain.interactor.notificationLaunchAnimationInteractor
@@ -25,6 +26,7 @@
     Kosmos.Fixture {
         WindowManagerLockscreenVisibilityInteractor(
             keyguardInteractor = keyguardInteractor,
+            transitionRepository = keyguardTransitionRepository,
             transitionInteractor = keyguardTransitionInteractor,
             surfaceBehindInteractor = keyguardSurfaceBehindInteractor,
             fromLockscreenInteractor = fromLockscreenTransitionInteractor,
@@ -33,5 +35,6 @@
             notificationLaunchAnimationInteractor = notificationLaunchAnimationInteractor,
             sceneInteractor = { sceneInteractor },
             deviceEntryInteractor = { deviceEntryInteractor },
+            wakeToGoneInteractor = keyguardWakeDirectlyToGoneInteractor,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
index 3c1f7b1..e50e044 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/scenetransition/LockscreenSceneTransitionInteractor.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.keyguard.domain.interactor.scenetransition
 
 import com.android.systemui.keyguard.data.repository.lockscreenSceneTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.internalKeyguardTransitionInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
@@ -29,5 +30,6 @@
             applicationScope = applicationCoroutineScope,
             sceneInteractor = sceneInteractor,
             repository = lockscreenSceneTransitionRepository,
+            internalTransitionInteractor = internalKeyguardTransitionInteractor,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinderKosmos.kt
new file mode 100644
index 0000000..6eb8a49
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinderKosmos.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.keyguard.ui.binder
+
+import android.content.applicationContext
+import android.view.layoutInflater
+import android.view.mockedLayoutInflater
+import android.view.windowManager
+import com.android.systemui.biometrics.domain.interactor.fingerprintPropertyInteractor
+import com.android.systemui.biometrics.domain.interactor.udfpsOverlayInteractor
+import com.android.systemui.common.ui.domain.interactor.configurationInteractor
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
+import com.android.systemui.deviceentry.ui.viewmodel.AlternateBouncerUdfpsAccessibilityOverlayViewModel
+import com.android.systemui.keyguard.ui.SwipeUpAnywhereGestureHandler
+import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerDependencies
+import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerMessageAreaViewModel
+import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerUdfpsIconViewModel
+import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerViewModel
+import com.android.systemui.keyguard.ui.viewmodel.DeviceEntryBackgroundViewModel
+import com.android.systemui.keyguard.ui.viewmodel.alternateBouncerViewModel
+import com.android.systemui.keyguard.ui.viewmodel.alternateBouncerWindowViewModel
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.statusbar.gesture.TapGestureDetector
+import com.android.systemui.util.mockito.mock
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+@OptIn(ExperimentalCoroutinesApi::class)
+val Kosmos.alternateBouncerViewBinder by
+    Kosmos.Fixture {
+        AlternateBouncerViewBinder(
+            applicationScope = applicationCoroutineScope,
+            alternateBouncerWindowViewModel = { alternateBouncerWindowViewModel },
+            alternateBouncerDependencies = { alternateBouncerDependencies },
+            windowManager = { windowManager },
+            layoutInflater = { mockedLayoutInflater },
+        )
+    }
+
+private val Kosmos.alternateBouncerDependencies by
+    Kosmos.Fixture {
+        AlternateBouncerDependencies(
+            viewModel = mock<AlternateBouncerViewModel>(),
+            swipeUpAnywhereGestureHandler = mock<SwipeUpAnywhereGestureHandler>(),
+            tapGestureDetector = mock<TapGestureDetector>(),
+            udfpsIconViewModel = alternateBouncerUdfpsIconViewModel,
+            udfpsAccessibilityOverlayViewModel = {
+                mock<AlternateBouncerUdfpsAccessibilityOverlayViewModel>()
+            },
+            messageAreaViewModel = mock<AlternateBouncerMessageAreaViewModel>(),
+            powerInteractor = powerInteractor,
+        )
+    }
+
+private val Kosmos.alternateBouncerUdfpsIconViewModel by
+    Kosmos.Fixture {
+        AlternateBouncerUdfpsIconViewModel(
+            context = applicationContext,
+            configurationInteractor = configurationInteractor,
+            deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
+            deviceEntryBackgroundViewModel = mock<DeviceEntryBackgroundViewModel>(),
+            fingerprintPropertyInteractor = fingerprintPropertyInteractor,
+            udfpsOverlayInteractor = udfpsOverlayInteractor,
+            alternateBouncerViewModel = alternateBouncerViewModel,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelKosmos.kt
index 6f168d4..6cf668c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelKosmos.kt
@@ -33,6 +33,7 @@
         keyguardInteractor = keyguardInteractor,
         keyguardTransitionInteractor = keyguardTransitionInteractor,
         goneToAodTransitionViewModel = goneToAodTransitionViewModel,
+        lockscreenToAodTransitionViewModel = lockscreenToAodTransitionViewModel,
         aodToLockscreenTransitionViewModel = aodToLockscreenTransitionViewModel,
         occludedToLockscreenTransitionViewModel = occludedToLockscreenTransitionViewModel,
         keyguardClockViewModel = keyguardClockViewModel,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelKosmos.kt
index 19e4241..8549a30 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelKosmos.kt
@@ -22,11 +22,13 @@
 import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.power.domain.interactor.powerInteractor
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 
 var Kosmos.goneToAodTransitionViewModel by Fixture {
     GoneToAodTransitionViewModel(
         deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
+        powerInteractor = powerInteractor,
         animationFlow = keyguardTransitionAnimationFlow,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt
index 3c62b44..b5e6f75 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelKosmos.kt
@@ -23,7 +23,6 @@
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.statusbar.notification.icon.ui.viewmodel.notificationIconContainerAlwaysOnDisplayViewModel
-import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationsKeyguardInteractor
 import com.android.systemui.statusbar.ui.systemBarUtilsProxy
 
 val Kosmos.keyguardClockViewModel by
@@ -32,7 +31,6 @@
             keyguardClockInteractor = keyguardClockInteractor,
             applicationScope = applicationCoroutineScope,
             aodNotificationIconViewModel = notificationIconContainerAlwaysOnDisplayViewModel,
-            notifsKeyguardInteractor = notificationsKeyguardInteractor,
             shadeInteractor = shadeInteractor,
             systemBarUtils = systemBarUtilsProxy,
             configurationInteractor = configurationInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardLongPressViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardLongPressViewModelKosmos.kt
index 3c9846a..281d7b0 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardLongPressViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardLongPressViewModelKosmos.kt
@@ -16,12 +16,12 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
-import com.android.systemui.keyguard.domain.interactor.keyguardLongPressInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTouchHandlingInteractor
 import com.android.systemui.kosmos.Kosmos
 
-val Kosmos.keyguardLongPressViewModel by
+val Kosmos.keyguardTouchHandlingViewModel by
     Kosmos.Fixture {
-        KeyguardLongPressViewModel(
-            interactor = keyguardLongPressInteractor,
+        KeyguardTouchHandlingViewModel(
+            interactor = keyguardTouchHandlingInteractor,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt
index 30a4f21..550ecb3 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModelKosmos.kt
@@ -21,6 +21,7 @@
 import com.android.systemui.keyguard.domain.interactor.keyguardClockInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
 import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor
 
@@ -30,9 +31,10 @@
             clockInteractor = keyguardClockInteractor,
             interactor = keyguardBlueprintInteractor,
             authController = authController,
-            longPress = keyguardLongPressViewModel,
+            touchHandling = keyguardTouchHandlingViewModel,
             shadeInteractor = shadeInteractor,
             applicationScope = applicationCoroutineScope,
             unfoldTransitionInteractor = unfoldTransitionInteractor,
+            occlusionInteractor = sceneContainerOcclusionInteractor,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelKosmos.kt
index 07b4cd4..f45e33b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToAodTransitionViewModelKosmos.kt
@@ -22,11 +22,13 @@
 import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.power.domain.interactor.powerInteractor
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 
-val Kosmos.lockscreenToAodTransitionViewModel by Fixture {
+var Kosmos.lockscreenToAodTransitionViewModel by Fixture {
     LockscreenToAodTransitionViewModel(
         deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
+        powerInteractor = powerInteractor,
         shadeDependentFlows = shadeDependentFlows,
         animationFlow = keyguardTransitionAnimationFlow,
     )
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
index 31cdbc7..0666820 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
@@ -50,6 +50,7 @@
 import com.android.systemui.plugins.statusbar.statusBarStateController
 import com.android.systemui.power.data.repository.fakePowerRepository
 import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.domain.startable.scrimStartable
 import com.android.systemui.scene.sceneContainerConfig
@@ -67,6 +68,7 @@
 import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.wifiInteractor
 import com.android.systemui.statusbar.policy.data.repository.fakeDeviceProvisioningRepository
 import com.android.systemui.statusbar.policy.domain.interactor.deviceProvisioningInteractor
+import com.android.systemui.statusbar.ui.viewmodel.keyguardStatusBarViewModel
 import com.android.systemui.util.time.systemClock
 import com.android.systemui.volume.domain.interactor.volumeDialogInteractor
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -101,6 +103,7 @@
     val keyguardInteractor by lazy { kosmos.keyguardInteractor }
     val keyguardTransitionRepository by lazy { kosmos.fakeKeyguardTransitionRepository }
     val keyguardTransitionInteractor by lazy { kosmos.keyguardTransitionInteractor }
+    val keyguardStatusBarViewModel by lazy { kosmos.keyguardStatusBarViewModel }
     val powerRepository by lazy { kosmos.fakePowerRepository }
     val clock by lazy { kosmos.systemClock }
     val mobileConnectionsRepository by lazy { kosmos.fakeMobileConnectionsRepository }
@@ -142,4 +145,5 @@
     val ongoingActivityChipsViewModel by lazy { kosmos.ongoingActivityChipsViewModel }
     val scrimController by lazy { kosmos.scrimController }
     val scrimStartable by lazy { kosmos.scrimStartable }
+    val sceneContainerOcclusionInteractor by lazy { kosmos.sceneContainerOcclusionInteractor }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryKosmos.kt
index 690bde7..7a04aa2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryKosmos.kt
@@ -18,6 +18,7 @@
 
 import android.content.applicationContext
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.media.controls.util.mediaSmartspaceLogger
 import com.android.systemui.statusbar.policy.configurationController
 import com.android.systemui.util.time.systemClock
 
@@ -26,6 +27,7 @@
         MediaFilterRepository(
             applicationContext = applicationContext,
             systemClock = systemClock,
-            configurationController = configurationController
+            configurationController = configurationController,
+            smartspaceLogger = mediaSmartspaceLogger,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterKosmos.kt
index b8b0060..1473184 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterKosmos.kt
@@ -21,6 +21,7 @@
 import com.android.systemui.concurrency.fakeExecutor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.media.controls.data.repository.mediaFilterRepository
+import com.android.systemui.media.controls.shared.mediaLogger
 import com.android.systemui.media.controls.util.mediaFlags
 import com.android.systemui.media.controls.util.mediaUiEventLogger
 import com.android.systemui.settings.userTracker
@@ -45,6 +46,6 @@
             logger = mediaUiEventLogger,
             mediaFlags = mediaFlags,
             mediaFilterRepository = mediaFilterRepository,
-            mediaLoadingLogger = mediaLoadingLogger,
+            mediaLogger = mediaLogger,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaLoadingLoggerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaLoadingLoggerKosmos.kt
deleted file mode 100644
index 96886f7..0000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/MediaLoadingLoggerKosmos.kt
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.controls.domain.pipeline
-
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.log.logcatLogBuffer
-import org.mockito.Mockito.mock
-
-val Kosmos.mediaLoadingLogger by
-    Kosmos.Fixture { MediaLoadingLogger(logcatLogBuffer("MediaLoadingLogBuffer")) }
-val Kosmos.mockMediaLoadingLogger by Kosmos.Fixture { mock(MediaLoadingLogger::class.java) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractorKosmos.kt
index 81adefa..6e650a3 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractorKosmos.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.media.controls.domain.pipeline.interactor
 
-import android.content.applicationContext
 import com.android.systemui.activityIntentHelper
 import com.android.systemui.bluetooth.mockBroadcastDialogController
 import com.android.systemui.kosmos.Kosmos
@@ -31,7 +30,6 @@
 val Kosmos.mediaControlInteractor by
     Kosmos.Fixture {
         MediaControlInteractor(
-            applicationContext = applicationContext,
             instanceId = mediaInstanceId,
             repository = mediaFilterRepository,
             mediaDataProcessor = mediaDataProcessor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/interactor/factory/MediaControlInteractorFactoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/interactor/factory/MediaControlInteractorFactoryKosmos.kt
index 461eaa2..e490b75 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/interactor/factory/MediaControlInteractorFactoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/interactor/factory/MediaControlInteractorFactoryKosmos.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.media.controls.domain.pipeline.interactor.factory
 
-import android.content.applicationContext
 import com.android.internal.logging.InstanceId
 import com.android.systemui.activityIntentHelper
 import com.android.systemui.bluetooth.mockBroadcastDialogController
@@ -34,7 +33,6 @@
         object : MediaControlInteractorFactory {
             override fun create(instanceId: InstanceId): MediaControlInteractor {
                 return MediaControlInteractor(
-                    applicationContext = applicationContext,
                     instanceId = instanceId,
                     repository = mediaFilterRepository,
                     mediaDataProcessor = mediaDataProcessor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/shared/MediaLoggerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/shared/MediaLoggerKosmos.kt
new file mode 100644
index 0000000..55c419e
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/shared/MediaLoggerKosmos.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.controls.shared
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.log.logcatLogBuffer
+import org.mockito.Mockito.mock
+
+var Kosmos.mediaLogger by Kosmos.Fixture { MediaLogger(logcatLogBuffer("MediaLogBuffer")) }
+val Kosmos.mockMediaLogger by Kosmos.Fixture { mock(MediaLogger::class.java) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelKosmos.kt
index 069995a..054ac2e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaCarouselViewModelKosmos.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.media.controls.domain.pipeline.interactor.factory.mediaControlInteractorFactory
 import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
+import com.android.systemui.media.controls.shared.mediaLogger
 import com.android.systemui.media.controls.util.mediaFlags
 import com.android.systemui.media.controls.util.mediaUiEventLogger
 import com.android.systemui.statusbar.notification.collection.provider.visualStabilityProvider
@@ -40,5 +41,6 @@
             recommendationsViewModel = mediaRecommendationsViewModel,
             logger = mediaUiEventLogger,
             mediaFlags = mediaFlags,
+            mediaLogger = mediaLogger,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/util/MediaSmartspaceLoggerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/util/MediaSmartspaceLoggerKosmos.kt
new file mode 100644
index 0000000..c63dec5
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/util/MediaSmartspaceLoggerKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.controls.util
+
+import com.android.systemui.kosmos.Kosmos
+import org.mockito.Mockito.mock
+
+var Kosmos.mediaSmartspaceLogger by Kosmos.Fixture { MediaSmartspaceLogger() }
+val Kosmos.mockMediaSmartspaceLogger by Kosmos.Fixture { mock(MediaSmartspaceLogger::class.java) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/mediarouter/data/repository/FakeMediaRouterRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/mediarouter/data/repository/FakeMediaRouterRepository.kt
new file mode 100644
index 0000000..8aa7a03
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/mediarouter/data/repository/FakeMediaRouterRepository.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.mediarouter.data.repository
+
+import com.android.systemui.statusbar.policy.CastDevice
+import kotlinx.coroutines.flow.MutableStateFlow
+
+class FakeMediaRouterRepository : MediaRouterRepository {
+    override val castDevices: MutableStateFlow<List<CastDevice>> = MutableStateFlow(emptyList())
+
+    var lastStoppedDevice: CastDevice? = null
+        private set
+
+    override fun stopCasting(device: CastDevice) {
+        lastStoppedDevice = device
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryKosmos.kt
new file mode 100644
index 0000000..eec9920
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryKosmos.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.mediarouter.data.repository
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.statusbar.policy.fakeCastController
+
+val Kosmos.realMediaRouterRepository by
+    Kosmos.Fixture {
+        MediaRouterRepositoryImpl(
+            scope = applicationCoroutineScope,
+            castController = fakeCastController,
+        )
+    }
+
+val Kosmos.fakeMediaRouterRepository by Kosmos.Fixture { FakeMediaRouterRepository() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/navigation/data/repository/NavigationRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/navigation/data/repository/NavigationRepositoryKosmos.kt
new file mode 100644
index 0000000..717a300
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/navigation/data/repository/NavigationRepositoryKosmos.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.navigation.data.repository
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.navigationbar.navigationModeController
+
+val Kosmos.navigationRepository by Fixture {
+    NavigationRepository(
+        controller = navigationModeController,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/navigation/domain/interactor/NavigationInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/navigation/domain/interactor/NavigationInteractorKosmos.kt
new file mode 100644
index 0000000..80fe3b9
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/navigation/domain/interactor/NavigationInteractorKosmos.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.navigation.domain.interactor
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.navigation.data.repository.navigationRepository
+
+val Kosmos.navigationInteractor by Fixture {
+    NavigationInteractor(
+        repository = navigationRepository,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/navigationbar/NavigationModeControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/navigationbar/NavigationModeControllerKosmos.kt
new file mode 100644
index 0000000..f2fb1a8
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/navigationbar/NavigationModeControllerKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.navigationbar
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.util.mockito.mock
+
+val Kosmos.navigationModeController by Fixture { mock<NavigationModeController>() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt
index ec56327..f9f8d23 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt
@@ -22,6 +22,7 @@
 import com.android.systemui.keyguard.domain.interactor.keyguardClockInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.statusbar.StatusBarStateControllerImpl
@@ -38,6 +39,7 @@
             { shadeInteractor },
             { deviceUnlockedInteractor },
             { sceneInteractor },
+            { sceneContainerOcclusionInteractor },
             { keyguardClockInteractor },
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/FixedColumnsRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/FixedColumnsRepositoryKosmos.kt
new file mode 100644
index 0000000..2f5daaa
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/FixedColumnsRepositoryKosmos.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.data.repository
+
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.fixedColumnsRepository by Kosmos.Fixture { FixedColumnsRepository() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/InfiniteGridSizeRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/InfiniteGridSizeRepositoryKosmos.kt
deleted file mode 100644
index d8af3fa..0000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/InfiniteGridSizeRepositoryKosmos.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.panels.data.repository
-
-import com.android.systemui.kosmos.Kosmos
-
-val Kosmos.infiniteGridSizeRepository by Kosmos.Fixture { InfiniteGridSizeRepository() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/PaginatedGridRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/PaginatedGridRepositoryKosmos.kt
new file mode 100644
index 0000000..696c4bf
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/PaginatedGridRepositoryKosmos.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.data.repository
+
+import com.android.systemui.common.ui.data.repository.configurationRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testCase
+
+val Kosmos.paginatedGridRepository by
+    Kosmos.Fixture {
+        testCase.context.orCreateTestableResources
+        PaginatedGridRepository(testCase.context.resources, configurationRepository)
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryKosmos.kt
new file mode 100644
index 0000000..da55e21
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/data/repository/QuickQuickSettingsRowRepositoryKosmos.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.data.repository
+
+import com.android.systemui.common.ui.data.repository.configurationRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testCase
+
+val Kosmos.quickQuickSettingsRowRepository by
+    Kosmos.Fixture {
+        testCase.context.orCreateTestableResources
+        QuickQuickSettingsRowRepository(testCase.context.resources, configurationRepository)
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/FixedColumnsSizeInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/FixedColumnsSizeInteractorKosmos.kt
new file mode 100644
index 0000000..f4d281d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/FixedColumnsSizeInteractorKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.domain.interactor
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.panels.data.repository.fixedColumnsRepository
+
+val Kosmos.fixedColumnsSizeInteractor by
+    Kosmos.Fixture { FixedColumnsSizeInteractor(fixedColumnsRepository) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorKosmos.kt
index 7f387d7..320c2ec 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridConsistencyInteractorKosmos.kt
@@ -20,5 +20,5 @@
 
 val Kosmos.infiniteGridConsistencyInteractor by
     Kosmos.Fixture {
-        InfiniteGridConsistencyInteractor(iconTilesInteractor, infiniteGridSizeInteractor)
+        InfiniteGridConsistencyInteractor(iconTilesInteractor, fixedColumnsSizeInteractor)
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridLayoutKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridLayoutKosmos.kt
index 82cfaf5..be00152 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridLayoutKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridLayoutKosmos.kt
@@ -18,8 +18,8 @@
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.qs.panels.ui.compose.InfiniteGridLayout
+import com.android.systemui.qs.panels.ui.viewmodel.fixedColumnsSizeViewModel
 import com.android.systemui.qs.panels.ui.viewmodel.iconTilesViewModel
-import com.android.systemui.qs.panels.ui.viewmodel.infiniteGridSizeViewModel
 
 val Kosmos.infiniteGridLayout by
-    Kosmos.Fixture { InfiniteGridLayout(iconTilesViewModel, infiniteGridSizeViewModel) }
+    Kosmos.Fixture { InfiniteGridLayout(iconTilesViewModel, fixedColumnsSizeViewModel) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridSizeInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridSizeInteractorKosmos.kt
deleted file mode 100644
index 6e11977..0000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/InfiniteGridSizeInteractorKosmos.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.panels.domain.interactor
-
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.panels.data.repository.infiniteGridSizeRepository
-
-val Kosmos.infiniteGridSizeInteractor by
-    Kosmos.Fixture { InfiniteGridSizeInteractor(infiniteGridSizeRepository) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/PaginatedGridInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/PaginatedGridInteractorKosmos.kt
new file mode 100644
index 0000000..a922e5d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/PaginatedGridInteractorKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.domain.interactor
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.panels.data.repository.paginatedGridRepository
+
+val Kosmos.paginatedGridInteractor by
+    Kosmos.Fixture { PaginatedGridInteractor(paginatedGridRepository) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractorKosmos.kt
new file mode 100644
index 0000000..3fcbc8d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/QuickQuickSettingsRowInteractorKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.domain.interactor
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.panels.data.repository.quickQuickSettingsRowRepository
+
+val Kosmos.quickQuickSettingsRowInteractor by
+    Kosmos.Fixture { QuickQuickSettingsRowInteractor(quickQuickSettingsRowRepository) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/FixedColumnsSizeViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/FixedColumnsSizeViewModelKosmos.kt
new file mode 100644
index 0000000..feadc91
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/FixedColumnsSizeViewModelKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.ui.viewmodel
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.panels.domain.interactor.fixedColumnsSizeInteractor
+
+val Kosmos.fixedColumnsSizeViewModel by
+    Kosmos.Fixture { FixedColumnsSizeViewModelImpl(fixedColumnsSizeInteractor) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridSizeViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridSizeViewModelKosmos.kt
deleted file mode 100644
index f6dfb8b..0000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/InfiniteGridSizeViewModelKosmos.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.panels.ui.viewmodel
-
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.panels.domain.interactor.infiniteGridSizeInteractor
-
-val Kosmos.infiniteGridSizeViewModel by
-    Kosmos.Fixture { InfiniteGridSizeViewModelImpl(infiniteGridSizeInteractor) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/MockTileViewModel.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/MockTileViewModel.kt
new file mode 100644
index 0000000..5386ece
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/MockTileViewModel.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.ui.viewmodel
+
+import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+
+fun MockTileViewModel(
+    spec: TileSpec,
+    state: StateFlow<QSTile.State> = MutableStateFlow(QSTile.State())
+): TileViewModel = mock {
+    whenever(this.spec).thenReturn(spec)
+    whenever(this.state).thenReturn(state)
+    whenever(this.currentState).thenReturn(state.value)
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
new file mode 100644
index 0000000..85e9265
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PaginatedGridViewModelKosmos.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.ui.viewmodel
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.qs.panels.domain.interactor.paginatedGridInteractor
+
+val Kosmos.paginatedGridViewModel by
+    Kosmos.Fixture {
+        PaginatedGridViewModel(
+            iconTilesViewModel,
+            fixedColumnsSizeViewModel,
+            iconLabelVisibilityViewModel,
+            paginatedGridInteractor,
+            applicationCoroutineScope,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PartitionedGridViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PartitionedGridViewModelKosmos.kt
index b07cc7d..fde174d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PartitionedGridViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/PartitionedGridViewModelKosmos.kt
@@ -22,7 +22,7 @@
     Kosmos.Fixture {
         PartitionedGridViewModel(
             iconTilesViewModel,
-            infiniteGridSizeViewModel,
+            fixedColumnsSizeViewModel,
             iconLabelVisibilityViewModel,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelKosmos.kt
new file mode 100644
index 0000000..40d2624
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/QuickQuickSettingsViewModelKosmos.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.panels.ui.viewmodel
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.qs.panels.domain.interactor.quickQuickSettingsRowInteractor
+import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
+
+val Kosmos.quickQuickSettingsViewModel by
+    Kosmos.Fixture {
+        QuickQuickSettingsViewModel(
+            currentTilesInteractor,
+            fixedColumnsSizeViewModel,
+            quickQuickSettingsRowInteractor,
+            iconTilesViewModel,
+            applicationCoroutineScope,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt
index 419e781..dceb8bf 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt
@@ -33,7 +33,6 @@
 import com.android.systemui.util.mockito.whenever
 import javax.inject.Provider
 import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.SharedFlow
 import kotlinx.coroutines.flow.StateFlow
 
 var Kosmos.newFactoryTileMap by Kosmos.Fixture { emptyMap<String, Provider<QSTileViewModel>>() }
@@ -50,7 +49,7 @@
                         instanceIdSequenceFake.newInstanceId(),
                     )
                 object : QSTileViewModel {
-                    override val state: SharedFlow<QSTileState> =
+                    override val state: StateFlow<QSTileState?> =
                         MutableStateFlow(QSTileState.build({ null }, tileSpec.spec) {})
                     override val config: QSTileConfig = config
                     override val isAvailable: StateFlow<Boolean> = MutableStateFlow(true)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/qr/QRCodeScannerTileKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/qr/QRCodeScannerTileKosmos.kt
index dcfcce7..537be4f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/qr/QRCodeScannerTileKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/qr/QRCodeScannerTileKosmos.kt
@@ -69,6 +69,7 @@
             qsTileLogger,
             systemClock,
             testDispatcher,
+            testDispatcher,
             testScope.backgroundScope,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt
new file mode 100644
index 0000000..779634d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModelKosmos.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.ui.viewmodel
+
+import com.android.systemui.brightness.ui.viewmodel.brightnessSliderViewModel
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.panels.ui.viewmodel.editModeViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.quickQuickSettingsViewModel
+import com.android.systemui.qs.panels.ui.viewmodel.tileGridViewModel
+
+val Kosmos.quickSettingsContainerViewModel by
+    Kosmos.Fixture {
+        QuickSettingsContainerViewModel(
+            brightnessSliderViewModel,
+            tileGridViewModel,
+            editModeViewModel,
+            quickQuickSettingsViewModel,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt
new file mode 100644
index 0000000..c56c56c
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.ui.viewmodel
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.ui.viewmodel.overlayShadeViewModel
+
+val Kosmos.quickSettingsShadeSceneViewModel: QuickSettingsShadeSceneViewModel by
+    Kosmos.Fixture {
+        QuickSettingsShadeSceneViewModel(
+            shadeInteractor = shadeInteractor,
+            overlayShadeViewModel = overlayShadeViewModel,
+            quickSettingsContainerViewModel = quickSettingsContainerViewModel,
+            applicationScope = applicationCoroutineScope,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryUtil.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryUtil.kt
index 641a757..2f17ca8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryUtil.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryUtil.kt
@@ -18,8 +18,11 @@
 
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.compose.animation.scene.SceneKey
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.model.Scenes
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -30,6 +33,25 @@
 private val mutableTransitionState =
     MutableStateFlow<ObservableTransitionState>(ObservableTransitionState.Idle(Scenes.Lockscreen))
 
+suspend fun Kosmos.setTransition(
+    sceneTransition: ObservableTransitionState,
+    stateTransition: TransitionStep? = null,
+    scope: TestScope = testScope,
+    repository: SceneContainerRepository = sceneContainerRepository
+) {
+    if (SceneContainerFlag.isEnabled) {
+        setSceneTransition(sceneTransition, scope, repository)
+    } else {
+        if (stateTransition == null) throw IllegalArgumentException("No transitionStep provided")
+        fakeKeyguardTransitionRepository.sendTransitionSteps(
+            from = stateTransition.from,
+            to = stateTransition.to,
+            testScope = scope,
+            throughTransitionState = stateTransition.transitionState
+        )
+    }
+}
+
 fun Kosmos.setSceneTransition(
     transition: ObservableTransitionState,
     scope: TestScope = testScope,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneContainerStartableKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneContainerStartableKosmos.kt
deleted file mode 100644
index cf18c0e..0000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneContainerStartableKosmos.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.scene.domain.interactor
-
-import com.android.internal.logging.uiEventLogger
-import com.android.systemui.authentication.domain.interactor.authenticationInteractor
-import com.android.systemui.bouncer.domain.interactor.bouncerInteractor
-import com.android.systemui.bouncer.domain.interactor.simBouncerInteractor
-import com.android.systemui.classifier.falsingCollector
-import com.android.systemui.classifier.falsingManager
-import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor
-import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
-import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
-import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
-import com.android.systemui.keyguard.domain.interactor.windowManagerLockscreenVisibilityInteractor
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.kosmos.testScope
-import com.android.systemui.model.sysUiState
-import com.android.systemui.power.domain.interactor.powerInteractor
-import com.android.systemui.scene.domain.startable.SceneContainerStartable
-import com.android.systemui.scene.session.shared.shadeSessionStorage
-import com.android.systemui.scene.shared.logger.sceneLogger
-import com.android.systemui.settings.displayTracker
-import com.android.systemui.shade.domain.interactor.shadeInteractor
-import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
-import com.android.systemui.statusbar.notificationShadeWindowController
-import com.android.systemui.statusbar.phone.centralSurfacesOptional
-import com.android.systemui.statusbar.policy.domain.interactor.deviceProvisioningInteractor
-
-val Kosmos.sceneContainerStartable by Fixture {
-    SceneContainerStartable(
-        applicationScope = testScope.backgroundScope,
-        sceneInteractor = sceneInteractor,
-        deviceEntryInteractor = deviceEntryInteractor,
-        deviceUnlockedInteractor = deviceUnlockedInteractor,
-        bouncerInteractor = bouncerInteractor,
-        keyguardInteractor = keyguardInteractor,
-        sysUiState = sysUiState,
-        displayId = displayTracker.defaultDisplayId,
-        sceneLogger = sceneLogger,
-        falsingCollector = falsingCollector,
-        falsingManager = falsingManager,
-        powerInteractor = powerInteractor,
-        simBouncerInteractor = { simBouncerInteractor },
-        authenticationInteractor = { authenticationInteractor },
-        windowController = notificationShadeWindowController,
-        deviceProvisioningInteractor = deviceProvisioningInteractor,
-        centralSurfacesOptLazy = { centralSurfacesOptional },
-        headsUpInteractor = headsUpNotificationInteractor,
-        occlusionInteractor = sceneContainerOcclusionInteractor,
-        faceUnlockInteractor = deviceEntryFaceAuthInteractor,
-        shadeInteractor = shadeInteractor,
-        uiEventLogger = uiEventLogger,
-        sceneBackInteractor = sceneBackInteractor,
-        shadeSessionStorage = shadeSessionStorage,
-        windowMgrLockscreenVisInteractor = windowManagerLockscreenVisibilityInteractor,
-    )
-}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt
index 066736c..ae8b411 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneInteractorKosmos.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.scene.domain.interactor
 
 import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.scene.data.repository.sceneContainerRepository
@@ -30,6 +31,7 @@
             repository = sceneContainerRepository,
             logger = sceneLogger,
             sceneFamilyResolvers = { sceneFamilyResolvers },
-            deviceUnlockedInteractor = deviceUnlockedInteractor,
+            deviceUnlockedInteractor = { deviceUnlockedInteractor },
+            keyguardEnabledInteractor = { keyguardEnabledInteractor },
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/resolver/SceneResolverKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/resolver/SceneResolverKosmos.kt
index 6be1939..ae33aea 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/resolver/SceneResolverKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/resolver/SceneResolverKosmos.kt
@@ -20,6 +20,7 @@
 
 import com.android.compose.animation.scene.SceneKey
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.scene.shared.model.SceneFamilies
@@ -39,6 +40,7 @@
         HomeSceneFamilyResolver(
             applicationScope = applicationCoroutineScope,
             deviceEntryInteractor = deviceEntryInteractor,
+            keyguardEnabledInteractor = keyguardEnabledInteractor,
         )
     }
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/KeyguardStateCallbackStartableKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/KeyguardStateCallbackStartableKosmos.kt
new file mode 100644
index 0000000..f9111bf
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/KeyguardStateCallbackStartableKosmos.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.scene.domain.startable
+
+import com.android.systemui.bouncer.domain.interactor.simBouncerInteractor
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.keyguard.domain.interactor.trustInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.user.domain.interactor.selectedUserInteractor
+
+val Kosmos.keyguardStateCallbackStartable by Fixture {
+    KeyguardStateCallbackStartable(
+        applicationScope = applicationCoroutineScope,
+        backgroundDispatcher = testDispatcher,
+        sceneInteractor = sceneInteractor,
+        selectedUserInteractor = selectedUserInteractor,
+        deviceEntryInteractor = deviceEntryInteractor,
+        simBouncerInteractor = simBouncerInteractor,
+        trustInteractor = trustInteractor,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt
new file mode 100644
index 0000000..03a42bc
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/SceneContainerStartableKosmos.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.scene.domain.startable
+
+import com.android.internal.logging.uiEventLogger
+import com.android.systemui.authentication.domain.interactor.authenticationInteractor
+import com.android.systemui.bouncer.domain.interactor.bouncerInteractor
+import com.android.systemui.bouncer.domain.interactor.simBouncerInteractor
+import com.android.systemui.classifier.falsingCollector
+import com.android.systemui.classifier.falsingManager
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
+import com.android.systemui.keyguard.dismissCallbackRegistry
+import com.android.systemui.keyguard.domain.interactor.keyguardEnabledInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.domain.interactor.windowManagerLockscreenVisibilityInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.model.sysUiState
+import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.scene.domain.interactor.sceneBackInteractor
+import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.session.shared.shadeSessionStorage
+import com.android.systemui.scene.shared.logger.sceneLogger
+import com.android.systemui.settings.displayTracker
+import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
+import com.android.systemui.statusbar.notificationShadeWindowController
+import com.android.systemui.statusbar.phone.centralSurfacesOptional
+import com.android.systemui.statusbar.policy.domain.interactor.deviceProvisioningInteractor
+
+val Kosmos.sceneContainerStartable by Fixture {
+    SceneContainerStartable(
+        applicationScope = testScope.backgroundScope,
+        sceneInteractor = sceneInteractor,
+        deviceEntryInteractor = deviceEntryInteractor,
+        deviceUnlockedInteractor = deviceUnlockedInteractor,
+        bouncerInteractor = bouncerInteractor,
+        keyguardInteractor = keyguardInteractor,
+        keyguardTransitionInteractor = keyguardTransitionInteractor,
+        sysUiState = sysUiState,
+        displayId = displayTracker.defaultDisplayId,
+        sceneLogger = sceneLogger,
+        falsingCollector = falsingCollector,
+        falsingManager = falsingManager,
+        powerInteractor = powerInteractor,
+        simBouncerInteractor = { simBouncerInteractor },
+        authenticationInteractor = { authenticationInteractor },
+        windowController = notificationShadeWindowController,
+        deviceProvisioningInteractor = deviceProvisioningInteractor,
+        centralSurfacesOptLazy = { centralSurfacesOptional },
+        headsUpInteractor = headsUpNotificationInteractor,
+        occlusionInteractor = sceneContainerOcclusionInteractor,
+        faceUnlockInteractor = deviceEntryFaceAuthInteractor,
+        shadeInteractor = shadeInteractor,
+        uiEventLogger = uiEventLogger,
+        sceneBackInteractor = sceneBackInteractor,
+        shadeSessionStorage = shadeSessionStorage,
+        windowMgrLockscreenVisInteractor = windowManagerLockscreenVisibilityInteractor,
+        keyguardEnabledInteractor = keyguardEnabledInteractor,
+        dismissCallbackRegistry = dismissCallbackRegistry,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/StatusBarStartableKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/StatusBarStartableKosmos.kt
new file mode 100644
index 0000000..ee69c30
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/startable/StatusBarStartableKosmos.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.systemui.scene.domain.startable
+
+import android.content.applicationContext
+import com.android.internal.statusbar.statusBarService
+import com.android.systemui.authentication.domain.interactor.authenticationInteractor
+import com.android.systemui.deviceconfig.domain.interactor.deviceConfigInteractor
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.navigation.domain.interactor.navigationInteractor
+import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.user.domain.interactor.selectedUserInteractor
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+
+val Kosmos.statusBarStartable by Fixture {
+    StatusBarStartable(
+        applicationScope = applicationCoroutineScope,
+        backgroundDispatcher = testDispatcher,
+        applicationContext = applicationContext,
+        selectedUserInteractor = selectedUserInteractor,
+        sceneInteractor = sceneInteractor,
+        deviceEntryInteractor = deviceEntryInteractor,
+        sceneContainerOcclusionInteractor = sceneContainerOcclusionInteractor,
+        deviceConfigInteractor = deviceConfigInteractor,
+        navigationInteractor = navigationInteractor,
+        authenticationInteractor = authenticationInteractor,
+        powerInteractor = powerInteractor,
+        deviceEntryFaceAuthInteractor = deviceEntryFaceAuthInteractor,
+        statusBarService = statusBarService,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/PulsingGestureListenerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/PulsingGestureListenerKosmos.kt
new file mode 100644
index 0000000..4fc2228
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/PulsingGestureListenerKosmos.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.hardware.display.ambientDisplayConfiguration
+import com.android.systemui.classifier.falsingManager
+import com.android.systemui.dock.dockManager
+import com.android.systemui.dump.dumpManager
+import com.android.systemui.keyguard.domain.interactor.dozeInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.plugins.statusbar.statusBarStateController
+import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.settings.userTracker
+import com.android.systemui.util.mockito.mock
+
+val Kosmos.pulsingGestureListener by Fixture {
+    PulsingGestureListener(
+        falsingManager = falsingManager,
+        dockManager = dockManager,
+        powerInteractor = powerInteractor,
+        ambientDisplayConfiguration = ambientDisplayConfiguration,
+        statusBarStateController = statusBarStateController,
+        shadeLogger = mock(),
+        dozeInteractor = dozeInteractor,
+        userTracker = userTracker,
+        tunerService = mock(),
+        dumpManager = dumpManager,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt
index 728c67a..b9918f1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/data/repository/FakeShadeRepository.kt
@@ -30,7 +30,7 @@
 @SysUISingleton
 class FakeShadeRepository @Inject constructor() : ShadeRepository {
     private val _qsExpansion = MutableStateFlow(0f)
-    override val qsExpansion = _qsExpansion
+    @Deprecated("Use ShadeInteractor.qsExpansion instead") override val qsExpansion = _qsExpansion
 
     private val _udfpsTransitionToFullShadeProgress = MutableStateFlow(0f)
     override val udfpsTransitionToFullShadeProgress = _udfpsTransitionToFullShadeProgress
@@ -59,11 +59,16 @@
     private val _legacyIsQsExpanded = MutableStateFlow(false)
     @Deprecated("Use ShadeInteractor instead") override val legacyIsQsExpanded = _legacyIsQsExpanded
 
+    @Deprecated("Use ShadeInteractor.isUserInteractingWithShade instead")
     override val legacyLockscreenShadeTracking = MutableStateFlow(false)
 
     private val _shadeMode = MutableStateFlow<ShadeMode>(ShadeMode.Single)
     override val shadeMode: StateFlow<ShadeMode> = _shadeMode.asStateFlow()
 
+    private var _isDualShadeAlignedToBottom = false
+    override val isDualShadeAlignedToBottom
+        get() = _isDualShadeAlignedToBottom
+
     @Deprecated("Use ShadeInteractor instead")
     override fun setLegacyIsQsExpanded(legacyIsQsExpanded: Boolean) {
         _legacyIsQsExpanded.value = legacyIsQsExpanded
@@ -137,8 +142,12 @@
         _legacyShadeExpansion.value = expandedFraction
     }
 
-    override fun setShadeMode(shadeMode: ShadeMode) {
-        _shadeMode.value = shadeMode
+    override fun setShadeMode(mode: ShadeMode) {
+        _shadeMode.value = mode
+    }
+
+    fun setDualShadeAlignedToBottom(isAlignedToBottom: Boolean) {
+        _isDualShadeAlignedToBottom = isAlignedToBottom
     }
 }
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt
index 543d5b6..a00d2f4 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/interactor/ShadeInteractorKosmos.kt
@@ -71,5 +71,6 @@
             userSetupRepository = userSetupRepository,
             userSwitcherInteractor = userSwitcherInteractor,
             baseShadeInteractor = baseShadeInteractor,
+            shadeRepository = shadeRepository,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/startable/ShadeStartableKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/startable/ShadeStartableKosmos.kt
index b85858d..79b80bc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/startable/ShadeStartableKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/domain/startable/ShadeStartableKosmos.kt
@@ -27,7 +27,9 @@
 import com.android.systemui.shade.data.repository.shadeRepository
 import com.android.systemui.shade.domain.interactor.panelExpansionInteractor
 import com.android.systemui.shade.transition.ScrimShadeTransitionController
+import com.android.systemui.statusbar.notification.stack.notificationStackScrollLayoutController
 import com.android.systemui.statusbar.policy.splitShadeStateController
+import com.android.systemui.statusbar.pulseExpansionHandler
 import com.android.systemui.util.mockito.mock
 
 @Deprecated("ShadeExpansionStateManager is deprecated. Remove your dependency on it instead.")
@@ -45,5 +47,7 @@
         sceneInteractorProvider = { sceneInteractor },
         panelExpansionInteractorProvider = { panelExpansionInteractor },
         shadeExpansionStateManager = shadeExpansionStateManager,
+        pulseExpansionHandler = pulseExpansionHandler,
+        nsslc = notificationStackScrollLayoutController,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeSceneViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeSceneViewModelKosmos.kt
index 1ca3509..72a80d4 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeSceneViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeSceneViewModelKosmos.kt
@@ -18,6 +18,7 @@
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.notifications.ui.viewmodel.NotificationsShadeSceneViewModel
+import com.android.systemui.shade.domain.interactor.shadeInteractor
 
 val Kosmos.notificationsShadeSceneViewModel: NotificationsShadeSceneViewModel by
-    Kosmos.Fixture { NotificationsShadeSceneViewModel() }
+    Kosmos.Fixture { NotificationsShadeSceneViewModel(shadeInteractor) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/OverlayShadeViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/OverlayShadeViewModelKosmos.kt
index fec1028..8d4d547 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/OverlayShadeViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/OverlayShadeViewModelKosmos.kt
@@ -19,11 +19,13 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.shade.domain.interactor.shadeInteractor
 
 val Kosmos.overlayShadeViewModel: OverlayShadeViewModel by
     Kosmos.Fixture {
         OverlayShadeViewModel(
             applicationScope = applicationCoroutineScope,
             sceneInteractor = sceneInteractor,
+            shadeInteractor = shadeInteractor,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt
deleted file mode 100644
index 4d81ea1..0000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/QuickSettingsShadeSceneViewModelKosmos.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.ui.viewmodel
-
-import com.android.systemui.brightness.ui.viewmodel.brightnessSliderViewModel
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.panels.ui.viewmodel.editModeViewModel
-import com.android.systemui.qs.panels.ui.viewmodel.tileGridViewModel
-import com.android.systemui.qs.ui.adapter.qsSceneAdapter
-import com.android.systemui.qs.ui.viewmodel.QuickSettingsShadeSceneViewModel
-
-val Kosmos.quickSettingsShadeSceneViewModel: QuickSettingsShadeSceneViewModel by
-    Kosmos.Fixture {
-        QuickSettingsShadeSceneViewModel(
-            overlayShadeViewModel = overlayShadeViewModel,
-            brightnessSliderViewModel = brightnessSliderViewModel,
-            tileGridViewModel = tileGridViewModel,
-            editModeViewModel = editModeViewModel,
-            qsSceneAdapter = qsSceneAdapter,
-        )
-    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelKosmos.kt
new file mode 100644
index 0000000..989c3a5
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelKosmos.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.ui.viewmodel
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
+import com.android.systemui.qs.footerActionsController
+import com.android.systemui.qs.footerActionsViewModelFactory
+import com.android.systemui.qs.ui.adapter.qsSceneAdapter
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModel
+import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.unfold.domain.interactor.unfoldTransitionInteractor
+
+val Kosmos.shadeSceneViewModel: ShadeSceneViewModel by
+    Kosmos.Fixture {
+        ShadeSceneViewModel(
+            applicationScope = applicationCoroutineScope,
+            shadeHeaderViewModel = shadeHeaderViewModel,
+            qsSceneAdapter = qsSceneAdapter,
+            brightnessMirrorViewModel = brightnessMirrorViewModel,
+            mediaCarouselInteractor = mediaCarouselInteractor,
+            shadeInteractor = shadeInteractor,
+            footerActionsViewModelFactory = footerActionsViewModelFactory,
+            footerActionsController = footerActionsController,
+            sceneInteractor = sceneInteractor,
+            unfoldTransitionInteractor = unfoldTransitionInteractor,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/StatusBarChipsLogKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/StatusBarChipsLogKosmos.kt
new file mode 100644
index 0000000..e904cd2
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/StatusBarChipsLogKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.chips
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.log.logcatLogBuffer
+
+val Kosmos.statusBarChipsLogger by Kosmos.Fixture { logcatLogBuffer("StatusBarChips") }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorKosmos.kt
index 064e57b..fcd14d8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractorKosmos.kt
@@ -17,7 +17,15 @@
 package com.android.systemui.statusbar.chips.call.domain.interactor
 
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.statusbar.chips.statusBarChipsLogger
 import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
 
 val Kosmos.callChipInteractor: CallChipInteractor by
-    Kosmos.Fixture { CallChipInteractor(repository = ongoingCallRepository) }
+    Kosmos.Fixture {
+        CallChipInteractor(
+            scope = applicationCoroutineScope,
+            repository = ongoingCallRepository,
+            logger = statusBarChipsLogger,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractorKosmos.kt
new file mode 100644
index 0000000..cb18b68
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/domain/interactor/MediaRouterChipInteractorKosmos.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.chips.casttootherdevice.domain.interactor
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.mediarouter.data.repository.fakeMediaRouterRepository
+
+val Kosmos.mediaRouterChipInteractor by
+    Kosmos.Fixture {
+        MediaRouterChipInteractor(
+            scope = applicationCoroutineScope,
+            mediaRouterRepository = fakeMediaRouterRepository,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelKosmos.kt
index 4baa8d0..144fe26 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelKosmos.kt
@@ -16,9 +16,11 @@
 
 package com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel
 
+import android.content.applicationContext
 import com.android.systemui.animation.mockDialogTransitionAnimator
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.statusbar.chips.casttootherdevice.domain.interactor.mediaRouterChipInteractor
 import com.android.systemui.statusbar.chips.mediaprojection.domain.interactor.mediaProjectionChipInteractor
 import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper
 import com.android.systemui.util.time.fakeSystemClock
@@ -27,7 +29,9 @@
     Kosmos.Fixture {
         CastToOtherDeviceChipViewModel(
             scope = applicationCoroutineScope,
+            context = applicationContext,
             mediaProjectionChipInteractor = mediaProjectionChipInteractor,
+            mediaRouterChipInteractor = mediaRouterChipInteractor,
             systemClock = fakeSystemClock,
             endMediaProjectionDialogHelper = endMediaProjectionDialogHelper,
             dialogTransitionAnimator = mockDialogTransitionAnimator,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorKosmos.kt
index 6812a9d..0bfd88fc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/domain/interactor/MediaProjectionChipInteractorKosmos.kt
@@ -20,6 +20,7 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
+import com.android.systemui.statusbar.chips.statusBarChipsLogger
 
 val Kosmos.mediaProjectionChipInteractor: MediaProjectionChipInteractor by
     Kosmos.Fixture {
@@ -27,5 +28,6 @@
             scope = applicationCoroutineScope,
             mediaProjectionRepository = fakeMediaProjectionRepository,
             packageManager = packageManager,
+            logger = statusBarChipsLogger,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperKosmos.kt
index 4f82662..1ed7a47 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperKosmos.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.statusbar.chips.mediaprojection.ui.view
 
-import android.content.applicationContext
 import android.content.packageManager
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory
@@ -26,6 +25,5 @@
         EndMediaProjectionDialogHelper(
             dialogFactory = mockSystemUIDialogFactory,
             packageManager = packageManager,
-            context = applicationContext,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorKosmos.kt
index b4e9c14..557d3e2 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorKosmos.kt
@@ -20,6 +20,7 @@
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
 import com.android.systemui.screenrecord.data.repository.screenRecordRepository
+import com.android.systemui.statusbar.chips.statusBarChipsLogger
 
 val Kosmos.screenRecordChipInteractor: ScreenRecordChipInteractor by
     Kosmos.Fixture {
@@ -27,5 +28,6 @@
             scope = applicationCoroutineScope,
             screenRecordRepository = screenRecordRepository,
             mediaProjectionRepository = fakeMediaProjectionRepository,
+            logger = statusBarChipsLogger,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelKosmos.kt
index 99b7ec9..1d06947 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/screenrecord/ui/viewmodel/ScreenRecordChipViewModelKosmos.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.chips.screenrecord.ui.viewmodel
 
+import android.content.applicationContext
 import com.android.systemui.animation.mockDialogTransitionAnimator
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
@@ -27,6 +28,7 @@
     Kosmos.Fixture {
         ScreenRecordChipViewModel(
             scope = applicationCoroutineScope,
+            context = applicationContext,
             interactor = screenRecordChipInteractor,
             endMediaProjectionDialogHelper = endMediaProjectionDialogHelper,
             dialogTransitionAnimator = mockDialogTransitionAnimator,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelKosmos.kt
index 535f81a..2e475a3 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/sharetoapp/ui/viewmodel/ShareToAppChipViewModelKosmos.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel
 
+import android.content.applicationContext
 import com.android.systemui.animation.mockDialogTransitionAnimator
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
@@ -27,6 +28,7 @@
     Kosmos.Fixture {
         ShareToAppChipViewModel(
             scope = applicationCoroutineScope,
+            context = applicationContext,
             mediaProjectionChipInteractor = mediaProjectionChipInteractor,
             systemClock = fakeSystemClock,
             endMediaProjectionDialogHelper = endMediaProjectionDialogHelper,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelKosmos.kt
index 078e845..16e288f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelKosmos.kt
@@ -22,6 +22,7 @@
 import com.android.systemui.statusbar.chips.casttootherdevice.ui.viewmodel.castToOtherDeviceChipViewModel
 import com.android.systemui.statusbar.chips.screenrecord.ui.viewmodel.screenRecordChipViewModel
 import com.android.systemui.statusbar.chips.sharetoapp.ui.viewmodel.shareToAppChipViewModel
+import com.android.systemui.statusbar.chips.statusBarChipsLogger
 
 val Kosmos.ongoingActivityChipsViewModel: OngoingActivityChipsViewModel by
     Kosmos.Fixture {
@@ -31,5 +32,6 @@
             shareToAppChipViewModel = shareToAppChipViewModel,
             castToOtherDeviceChipViewModel = castToOtherDeviceChipViewModel,
             callChipViewModel = callChipViewModel,
+            logger = statusBarChipsLogger,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/domain/interactor/KeyguardOcclusionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/domain/interactor/KeyguardOcclusionInteractorKosmos.kt
index a90a9ff..65016c3 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/domain/interactor/KeyguardOcclusionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/domain/interactor/KeyguardOcclusionInteractorKosmos.kt
@@ -19,6 +19,7 @@
 import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
 import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository
 import com.android.systemui.keyguard.domain.interactor.KeyguardOcclusionInteractor
+import com.android.systemui.keyguard.domain.interactor.internalKeyguardTransitionInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.kosmos.Kosmos
@@ -34,5 +35,6 @@
             transitionInteractor = keyguardTransitionInteractor,
             keyguardInteractor = keyguardInteractor,
             deviceUnlockedInteractor = { deviceUnlockedInteractor },
+            internalTransitionInteractor = internalKeyguardTransitionInteractor,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/NotificationsDataKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/NotificationsDataKosmos.kt
deleted file mode 100644
index a61f7ec..0000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/data/NotificationsDataKosmos.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.data
-
-import com.android.settingslib.statusbar.notification.data.repository.FakeNotificationsSoundPolicyRepository
-import com.android.systemui.kosmos.Kosmos
-
-val Kosmos.notificationsSoundPolicyRepository by
-    Kosmos.Fixture { FakeNotificationsSoundPolicyRepository() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractorKosmos.kt
index 0614309..aee90d5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/domain/interactor/NotificationsSoundPolicyInteractorKosmos.kt
@@ -16,12 +16,9 @@
 
 package com.android.systemui.statusbar.notification.domain.interactor
 
-import com.android.settingslib.statusbar.notification.data.repository.FakeNotificationsSoundPolicyRepository
-import com.android.settingslib.statusbar.notification.domain.interactor.NotificationsSoundPolicyInteractor
+import com.android.settingslib.notification.domain.interactor.NotificationsSoundPolicyInteractor
 import com.android.systemui.kosmos.Kosmos
-
-var Kosmos.notificationsSoundPolicyRepository by
-    Kosmos.Fixture { FakeNotificationsSoundPolicyRepository() }
+import com.android.systemui.statusbar.policy.data.repository.zenModeRepository
 
 val Kosmos.notificationsSoundPolicyInteractor: NotificationsSoundPolicyInteractor by
-    Kosmos.Fixture { NotificationsSoundPolicyInteractor(notificationsSoundPolicyRepository) }
+    Kosmos.Fixture { NotificationsSoundPolicyInteractor(zenModeRepository) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt
new file mode 100644
index 0000000..16dc50f
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowBuilder.kt
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.row
+
+import android.app.ActivityManager
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.content.Context
+import android.content.pm.LauncherApps
+import android.os.UserHandle
+import android.provider.DeviceConfig
+import androidx.core.os.bundleOf
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
+import com.android.internal.logging.MetricsLogger
+import com.android.internal.statusbar.IStatusBarService
+import com.android.systemui.TestableDependency
+import com.android.systemui.classifier.FalsingManagerFake
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.flags.FakeFeatureFlagsClassic
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.media.dialog.MediaOutputDialogManager
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.shared.system.ActivityManagerWrapper
+import com.android.systemui.shared.system.DevicePolicyManagerWrapper
+import com.android.systemui.shared.system.PackageManagerWrapper
+import com.android.systemui.statusbar.NotificationMediaManager
+import com.android.systemui.statusbar.NotificationRemoteInputManager
+import com.android.systemui.statusbar.NotificationShadeWindowController
+import com.android.systemui.statusbar.RankingBuilder
+import com.android.systemui.statusbar.SmartReplyController
+import com.android.systemui.statusbar.notification.ColorUpdateLogger
+import com.android.systemui.statusbar.notification.ConversationNotificationProcessor
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
+import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider
+import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager
+import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManagerImpl
+import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager
+import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManagerImpl
+import com.android.systemui.statusbar.notification.icon.IconBuilder
+import com.android.systemui.statusbar.notification.icon.IconManager
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.CoordinateOnClickListener
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.ExpandableNotificationRowLogger
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.OnExpandClickListener
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_ALL
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag
+import com.android.systemui.statusbar.notification.row.shared.NotificationRowContentBinderRefactor
+import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger
+import com.android.systemui.statusbar.phone.KeyguardBypassController
+import com.android.systemui.statusbar.policy.HeadsUpManager
+import com.android.systemui.statusbar.policy.SmartActionInflaterImpl
+import com.android.systemui.statusbar.policy.SmartReplyConstants
+import com.android.systemui.statusbar.policy.SmartReplyInflaterImpl
+import com.android.systemui.statusbar.policy.SmartReplyStateInflaterImpl
+import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent
+import com.android.systemui.util.Assert.runWithCurrentThreadAsMainThread
+import com.android.systemui.util.DeviceConfigProxyFake
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.time.FakeSystemClock
+import com.android.systemui.wmshell.BubblesManager
+import com.google.common.util.concurrent.MoreExecutors
+import com.google.common.util.concurrent.SettableFuture
+import java.util.Optional
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlinx.coroutines.test.TestScope
+import org.junit.Assert.assertTrue
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers
+import org.mockito.Mockito
+
+class ExpandableNotificationRowBuilder(
+    private val context: Context,
+    dependency: TestableDependency,
+    private val featureFlags: FakeFeatureFlagsClassic = FakeFeatureFlagsClassic()
+) {
+
+    private val mMockLogger: ExpandableNotificationRowLogger
+    private val mStatusBarStateController: StatusBarStateController
+    private val mKeyguardBypassController: KeyguardBypassController
+    private val mGroupMembershipManager: GroupMembershipManager
+    private val mGroupExpansionManager: GroupExpansionManager
+    private val mHeadsUpManager: HeadsUpManager
+    private val mIconManager: IconManager
+    private val mContentBinder: NotificationRowContentBinder
+    private val mBindStage: RowContentBindStage
+    private val mBindPipeline: NotifBindPipeline
+    private val mBindPipelineEntryListener: NotifCollectionListener
+    private val mPeopleNotificationIdentifier: PeopleNotificationIdentifier
+    private val mOnUserInteractionCallback: OnUserInteractionCallback
+    private val mDismissibilityProvider: NotificationDismissibilityProvider
+    private val mSmartReplyController: SmartReplyController
+    private val mSmartReplyConstants: SmartReplyConstants
+    private val mTestScope: TestScope = TestScope()
+    private val mBgCoroutineContext = mTestScope.backgroundScope.coroutineContext
+    private val mMainCoroutineContext = mTestScope.coroutineContext
+    private val mFakeSystemClock = FakeSystemClock()
+    private val mMainExecutor = FakeExecutor(mFakeSystemClock)
+
+    init {
+        featureFlags.setDefault(Flags.ENABLE_NOTIFICATIONS_SIMULATE_SLOW_MEASURE)
+        featureFlags.setDefault(Flags.BIGPICTURE_NOTIFICATION_LAZY_LOADING)
+
+        dependency.injectTestDependency(FeatureFlags::class.java, featureFlags)
+        dependency.injectMockDependency(NotificationMediaManager::class.java)
+        dependency.injectMockDependency(NotificationShadeWindowController::class.java)
+        dependency.injectMockDependency(MediaOutputDialogManager::class.java)
+
+        mMockLogger = Mockito.mock(ExpandableNotificationRowLogger::class.java)
+        mStatusBarStateController = Mockito.mock(StatusBarStateController::class.java)
+        mKeyguardBypassController = Mockito.mock(KeyguardBypassController::class.java)
+        mGroupMembershipManager = GroupMembershipManagerImpl()
+        mSmartReplyController = Mockito.mock(SmartReplyController::class.java)
+
+        val dumpManager = DumpManager()
+        mGroupExpansionManager = GroupExpansionManagerImpl(dumpManager, mGroupMembershipManager)
+        mHeadsUpManager = Mockito.mock(HeadsUpManager::class.java)
+        mIconManager =
+            IconManager(
+                Mockito.mock(CommonNotifCollection::class.java),
+                Mockito.mock(LauncherApps::class.java),
+                IconBuilder(context),
+                mTestScope,
+                mBgCoroutineContext,
+                mMainCoroutineContext,
+            )
+
+        mSmartReplyConstants =
+            SmartReplyConstants(
+                /* mainExecutor = */ mMainExecutor,
+                /* context = */ context,
+                /* deviceConfig = */ DeviceConfigProxyFake().apply {
+                    setProperty(
+                        DeviceConfig.NAMESPACE_SYSTEMUI,
+                        SystemUiDeviceConfigFlags.SSIN_SHOW_IN_HEADS_UP,
+                        "true",
+                        true
+                    )
+                    setProperty(
+                        DeviceConfig.NAMESPACE_SYSTEMUI,
+                        SystemUiDeviceConfigFlags.SSIN_ENABLED,
+                        "true",
+                        true
+                    )
+                    setProperty(
+                        DeviceConfig.NAMESPACE_SYSTEMUI,
+                        SystemUiDeviceConfigFlags.SSIN_REQUIRES_TARGETING_P,
+                        "false",
+                        true
+                    )
+                }
+            )
+        val remoteViewsFactories = getNotifRemoteViewsFactoryContainer(featureFlags)
+        val remoteInputManager = Mockito.mock(NotificationRemoteInputManager::class.java)
+        val smartReplyStateInflater =
+            SmartReplyStateInflaterImpl(
+                constants = mSmartReplyConstants,
+                activityManagerWrapper = ActivityManagerWrapper.getInstance(),
+                packageManagerWrapper = PackageManagerWrapper.getInstance(),
+                devicePolicyManagerWrapper = DevicePolicyManagerWrapper.getInstance(),
+                smartRepliesInflater =
+                    SmartReplyInflaterImpl(
+                        constants = mSmartReplyConstants,
+                        keyguardDismissUtil = mock(),
+                        remoteInputManager = remoteInputManager,
+                        smartReplyController = mSmartReplyController,
+                        context = context
+                    ),
+                smartActionsInflater =
+                    SmartActionInflaterImpl(
+                        constants = mSmartReplyConstants,
+                        activityStarter = mock(),
+                        smartReplyController = mSmartReplyController,
+                        headsUpManager = mHeadsUpManager
+                    )
+            )
+        val notifLayoutInflaterFactoryProvider =
+            object : NotifLayoutInflaterFactory.Provider {
+                override fun provide(
+                    row: ExpandableNotificationRow,
+                    layoutType: Int
+                ): NotifLayoutInflaterFactory =
+                    NotifLayoutInflaterFactory(row, layoutType, remoteViewsFactories)
+            }
+        val conversationProcessor =
+            ConversationNotificationProcessor(
+                mock(),
+                mock(),
+            )
+        mContentBinder =
+            if (NotificationRowContentBinderRefactor.isEnabled)
+                NotificationRowContentBinderImpl(
+                    mock(),
+                    remoteInputManager,
+                    conversationProcessor,
+                    mock(),
+                    mock(),
+                    mock(),
+                    smartReplyStateInflater,
+                    notifLayoutInflaterFactoryProvider,
+                    mock(),
+                    mock(),
+                )
+            else
+                NotificationContentInflater(
+                    mock(),
+                    remoteInputManager,
+                    conversationProcessor,
+                    mock(),
+                    mock(),
+                    smartReplyStateInflater,
+                    notifLayoutInflaterFactoryProvider,
+                    mock(),
+                    mock(),
+                )
+        mContentBinder.setInflateSynchronously(true)
+        mBindStage =
+            RowContentBindStage(
+                mContentBinder,
+                mock(),
+                mock(),
+            )
+
+        val collection = Mockito.mock(CommonNotifCollection::class.java)
+
+        mBindPipeline =
+            NotifBindPipeline(
+                collection,
+                Mockito.mock(NotifBindPipelineLogger::class.java),
+                NotificationEntryProcessorFactoryExecutorImpl(mMainExecutor),
+            )
+        mBindPipeline.setStage(mBindStage)
+
+        val collectionListenerCaptor = ArgumentCaptor.forClass(NotifCollectionListener::class.java)
+        Mockito.verify(collection).addCollectionListener(collectionListenerCaptor.capture())
+        mBindPipelineEntryListener = collectionListenerCaptor.value
+        mPeopleNotificationIdentifier = Mockito.mock(PeopleNotificationIdentifier::class.java)
+        mOnUserInteractionCallback = Mockito.mock(OnUserInteractionCallback::class.java)
+        mDismissibilityProvider = Mockito.mock(NotificationDismissibilityProvider::class.java)
+        val mFutureDismissalRunnable = Mockito.mock(Runnable::class.java)
+        whenever(
+                mOnUserInteractionCallback.registerFutureDismissal(
+                    ArgumentMatchers.any(),
+                    ArgumentMatchers.anyInt()
+                )
+            )
+            .thenReturn(mFutureDismissalRunnable)
+    }
+
+    private fun getNotifRemoteViewsFactoryContainer(
+        featureFlags: FeatureFlags,
+    ): NotifRemoteViewsFactoryContainer {
+        return NotifRemoteViewsFactoryContainerImpl(
+            featureFlags,
+            PrecomputedTextViewFactory(),
+            BigPictureLayoutInflaterFactory(),
+            NotificationOptimizedLinearLayoutFactory(),
+            { Mockito.mock(NotificationViewFlipperFactory::class.java) },
+        )
+    }
+
+    fun createRow(notification: Notification): ExpandableNotificationRow {
+        val channel =
+            NotificationChannel(
+                notification.channelId,
+                notification.channelId,
+                NotificationManager.IMPORTANCE_DEFAULT
+            )
+        channel.isBlockable = true
+        val entry =
+            NotificationEntryBuilder()
+                .setPkg(PKG)
+                .setOpPkg(PKG)
+                .setId(123321)
+                .setUid(UID)
+                .setInitialPid(2000)
+                .setNotification(notification)
+                .setUser(USER_HANDLE)
+                .setPostTime(System.currentTimeMillis())
+                .setChannel(channel)
+                .build()
+
+        // it is for mitigating Rank building process.
+        if (notification.isConversationStyleNotification) {
+            val rb = RankingBuilder(entry.ranking)
+            rb.setIsConversation(true)
+            entry.ranking = rb.build()
+        }
+
+        return generateRow(entry, FLAG_CONTENT_VIEW_ALL)
+    }
+
+    private fun generateRow(
+        entry: NotificationEntry,
+        @InflationFlag extraInflationFlags: Int
+    ): ExpandableNotificationRow {
+        // NOTE: This flag is read when the ExpandableNotificationRow is inflated, so it needs to be
+        //  set, but we do not want to override an existing value that is needed by a specific test.
+
+        val rowFuture: SettableFuture<ExpandableNotificationRow> = SettableFuture.create()
+        val rowInflaterTask =
+            RowInflaterTask(mFakeSystemClock, Mockito.mock(RowInflaterTaskLogger::class.java))
+        rowInflaterTask.inflate(context, null, entry, MoreExecutors.directExecutor()) { inflatedRow
+            ->
+            rowFuture.set(inflatedRow)
+        }
+        val row = rowFuture.get(1, TimeUnit.SECONDS)
+
+        entry.row = row
+        mIconManager.createIcons(entry)
+        mBindPipelineEntryListener.onEntryInit(entry)
+        mBindPipeline.manageRow(entry, row)
+        row.initialize(
+            entry,
+            Mockito.mock(RemoteInputViewSubcomponent.Factory::class.java),
+            APP_NAME,
+            entry.key,
+            mMockLogger,
+            mKeyguardBypassController,
+            mGroupMembershipManager,
+            mGroupExpansionManager,
+            mHeadsUpManager,
+            mBindStage,
+            Mockito.mock(OnExpandClickListener::class.java),
+            Mockito.mock(CoordinateOnClickListener::class.java),
+            FalsingManagerFake(),
+            mStatusBarStateController,
+            mPeopleNotificationIdentifier,
+            mOnUserInteractionCallback,
+            Optional.of(Mockito.mock(BubblesManager::class.java)),
+            Mockito.mock(NotificationGutsManager::class.java),
+            mDismissibilityProvider,
+            Mockito.mock(MetricsLogger::class.java),
+            Mockito.mock(NotificationChildrenContainerLogger::class.java),
+            Mockito.mock(ColorUpdateLogger::class.java),
+            mSmartReplyConstants,
+            mSmartReplyController,
+            featureFlags,
+            Mockito.mock(IStatusBarService::class.java)
+        )
+        row.setAboveShelfChangedListener { aboveShelf: Boolean -> }
+        mBindStage.getStageParams(entry).requireContentViews(extraInflationFlags)
+        inflateAndWait(entry)
+        return row
+    }
+
+    private fun inflateAndWait(entry: NotificationEntry) {
+        val countDownLatch = CountDownLatch(1)
+        mBindStage.requestRebind(entry) { en: NotificationEntry? -> countDownLatch.countDown() }
+        runWithCurrentThreadAsMainThread(mMainExecutor::runAllReady)
+        assertTrue(countDownLatch.await(500, TimeUnit.MILLISECONDS))
+    }
+
+    companion object {
+        private const val APP_NAME = "appName"
+        private const val PKG = "com.android.systemui"
+        private const val UID = 1000
+        private val USER_HANDLE = UserHandle.of(ActivityManager.getCurrentUser())
+
+        private const val IS_CONVERSATION_FLAG = "test.isConversation"
+
+        private val Notification.isConversationStyleNotification
+            get() = extras.getBoolean(IS_CONVERSATION_FLAG, false)
+
+        fun markAsConversation(builder: Notification.Builder) {
+            builder.addExtras(bundleOf(IS_CONVERSATION_FLAG to true))
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/data/repository/NotificationRowRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/data/repository/NotificationRowRepositoryKosmos.kt
new file mode 100644
index 0000000..84ef4b5
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/data/repository/NotificationRowRepositoryKosmos.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.row.data.repository
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.statusbar.notification.row.shared.RichOngoingContentModel
+import kotlinx.coroutines.flow.MutableStateFlow
+
+val Kosmos.fakeNotificationRowRepository by Fixture { FakeNotificationRowRepository() }
+
+class FakeNotificationRowRepository : NotificationRowRepository {
+    override val richOngoingContentModel = MutableStateFlow<RichOngoingContentModel?>(null)
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/domain/interactor/NotificationRowInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/domain/interactor/NotificationRowInteractorKosmos.kt
new file mode 100644
index 0000000..3a7d7ba
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/domain/interactor/NotificationRowInteractorKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.row.domain.interactor
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.statusbar.notification.row.data.repository.NotificationRowRepository
+
+fun Kosmos.getNotificationRowInteractor(repository: NotificationRowRepository) =
+    NotificationRowInteractor(repository = repository)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/TimerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/TimerViewModelKosmos.kt
new file mode 100644
index 0000000..00f45b2
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/TimerViewModelKosmos.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.row.ui.viewmodel
+
+import com.android.systemui.dump.dumpManager
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.statusbar.notification.row.data.repository.NotificationRowRepository
+import com.android.systemui.statusbar.notification.row.domain.interactor.getNotificationRowInteractor
+
+fun Kosmos.getTimerViewModel(repository: NotificationRowRepository) =
+    TimerViewModel(
+        dumpManager = dumpManager,
+        rowInteractor = getNotificationRowInteractor(repository),
+    )
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/HeadsUpNotificationRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/HeadsUpNotificationRepositoryKosmos.kt
index 7bf77e5..492e87b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/HeadsUpNotificationRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/HeadsUpNotificationRepositoryKosmos.kt
@@ -30,7 +30,12 @@
     override val topHeadsUpRow: Flow<HeadsUpRowRepository?> = MutableStateFlow(null)
     override val activeHeadsUpRows: MutableStateFlow<Set<HeadsUpRowRepository>> =
         MutableStateFlow(emptySet())
+
     override fun setHeadsUpAnimatingAway(animatingAway: Boolean) {
         isHeadsUpAnimatingAway.value = animatingAway
     }
+
+    override fun snooze() {
+        // do nothing
+    }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt
index f0eea38..afb8acb 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt
@@ -18,10 +18,11 @@
 
 import com.android.systemui.dump.dumpManager
 import com.android.systemui.flags.featureFlagsClassic
-import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.shade.ui.viewmodel.shadeSceneViewModel
+import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackAppearanceInteractor
 
 val Kosmos.notificationsPlaceholderViewModel by Fixture {
@@ -29,7 +30,8 @@
         dumpManager = dumpManager,
         interactor = notificationStackAppearanceInteractor,
         shadeInteractor = shadeInteractor,
+        shadeSceneViewModel = shadeSceneViewModel,
+        headsUpNotificationInteractor = headsUpNotificationInteractor,
         featureFlags = featureFlagsClassic,
-        keyguardInteractor = keyguardInteractor,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
index 299486f..ffd8aab 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.notification.stack.ui.viewmodel
 
+import com.android.systemui.communal.domain.interactor.communalSceneInteractor
 import com.android.systemui.dump.dumpManager
 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
@@ -86,6 +87,7 @@
         primaryBouncerToLockscreenTransitionViewModel =
             primaryBouncerToLockscreenTransitionViewModel,
         aodBurnInViewModel = aodBurnInViewModel,
+        communalSceneInteractor = communalSceneInteractor,
         unfoldTransitionInteractor = unfoldTransitionInteractor,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerKosmos.kt
new file mode 100644
index 0000000..8785256
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManagerKosmos.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.content.applicationContext
+import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor
+import com.android.systemui.bouncer.domain.interactor.primaryBouncerInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.statusbar.notificationShadeWindowController
+import com.android.systemui.statusbar.policy.configurationController
+import com.android.systemui.statusbar.policy.headsUpManager
+import com.android.systemui.util.kotlin.JavaAdapter
+import com.android.systemui.util.mockito.mock
+import org.mockito.Mockito.mock
+
+var Kosmos.statusBarTouchableRegionManager by
+    Kosmos.Fixture {
+        StatusBarTouchableRegionManager(
+            applicationContext,
+            notificationShadeWindowController,
+            configurationController,
+            headsUpManager,
+            shadeInteractor,
+            { sceneInteractor },
+            JavaAdapter(testScope.backgroundScope),
+            mock<UnlockedScreenOffAnimationController>(),
+            primaryBouncerInteractor,
+            alternateBouncerInteractor,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/SystemUIDialogFactoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/SystemUIDialogFactoryKosmos.kt
index 1851c89..6574946 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/SystemUIDialogFactoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/phone/SystemUIDialogFactoryKosmos.kt
@@ -36,3 +36,14 @@
 
 val Kosmos.mockSystemUIDialogFactory: SystemUIDialog.Factory by
     Kosmos.Fixture { mock<SystemUIDialog.Factory>() }
+
+val Kosmos.systemUIDialogDotFactory by
+    Kosmos.Fixture {
+        SystemUIDialog.Factory(
+            applicationContext,
+            systemUIDialogManager,
+            sysUiState,
+            broadcastDispatcher,
+            dialogTransitionAnimator,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/CastControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/CastControllerKosmos.kt
new file mode 100644
index 0000000..8e77437
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/CastControllerKosmos.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.policy
+
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.fakeCastController: FakeCastController by Kosmos.Fixture { FakeCastController() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeCastController.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeCastController.kt
new file mode 100644
index 0000000..2df0c7a5
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeCastController.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.policy
+
+import java.io.PrintWriter
+
+class FakeCastController : CastController {
+    private var listeners = mutableListOf<CastController.Callback>()
+
+    private var castDevices = emptyList<CastDevice>()
+
+    var lastStoppedDevice: CastDevice? = null
+        private set
+
+    override fun addCallback(listener: CastController.Callback) {
+        listeners += listener
+    }
+
+    override fun removeCallback(listener: CastController.Callback) {
+        listeners -= listener
+    }
+
+    override fun getCastDevices(): List<CastDevice> {
+        return castDevices
+    }
+
+    fun setCastDevices(devices: List<CastDevice>) {
+        castDevices = devices
+        listeners.forEach { it.onCastDevicesChanged() }
+    }
+
+    override fun startCasting(device: CastDevice?) {}
+
+    override fun stopCasting(device: CastDevice?) {
+        lastStoppedDevice = device
+    }
+
+    override fun hasConnectedCastDevice(): Boolean {
+        return castDevices.any { it.state == CastDevice.CastState.Connected }
+    }
+
+    override fun dump(pw: PrintWriter, args: Array<out String>) {}
+
+    override fun setDiscovering(request: Boolean) {}
+
+    override fun setCurrentUserId(currentUserId: Int) {}
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/FakeStatusBarPolicyDataLayerModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/FakeStatusBarPolicyDataLayerModule.kt
index 16dab40..5aece1b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/FakeStatusBarPolicyDataLayerModule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/FakeStatusBarPolicyDataLayerModule.kt
@@ -16,14 +16,7 @@
 package com.android.systemui.statusbar.policy.data
 
 import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepositoryModule
-import com.android.systemui.statusbar.policy.data.repository.FakeZenModeRepositoryModule
 import dagger.Module
 
-@Module(
-    includes =
-        [
-            FakeDeviceProvisioningRepositoryModule::class,
-            FakeZenModeRepositoryModule::class,
-        ]
-)
+@Module(includes = [FakeDeviceProvisioningRepositoryModule::class])
 object FakeStatusBarPolicyDataLayerModule
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/repository/FakeZenModeRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/repository/FakeZenModeRepository.kt
deleted file mode 100644
index c4d7867..0000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/repository/FakeZenModeRepository.kt
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.policy.data.repository
-
-import android.app.NotificationManager.Policy
-import android.provider.Settings
-import com.android.systemui.dagger.SysUISingleton
-import dagger.Binds
-import dagger.Module
-import javax.inject.Inject
-import kotlinx.coroutines.flow.MutableStateFlow
-
-@SysUISingleton
-class FakeZenModeRepository @Inject constructor() : ZenModeRepository {
-    override val zenMode: MutableStateFlow<Int> = MutableStateFlow(Settings.Global.ZEN_MODE_OFF)
-    override val consolidatedNotificationPolicy: MutableStateFlow<Policy?> =
-        MutableStateFlow(
-            Policy(
-                /* priorityCategories = */ 0,
-                /* priorityCallSenders = */ 0,
-                /* priorityMessageSenders = */ 0,
-            )
-        )
-
-    fun setSuppressedVisualEffects(suppressedVisualEffects: Int) {
-        consolidatedNotificationPolicy.value =
-            Policy(
-                /* priorityCategories = */ 0,
-                /* priorityCallSenders = */ 0,
-                /* priorityMessageSenders = */ 0,
-                /* suppressedVisualEffects = */ suppressedVisualEffects,
-            )
-    }
-}
-
-@Module
-interface FakeZenModeRepositoryModule {
-    @Binds fun bindFake(fake: FakeZenModeRepository): ZenModeRepository
-}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/repository/ZenModeRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/repository/ZenModeRepositoryKosmos.kt
index 1ec7511..1ba5ddb 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/repository/ZenModeRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/data/repository/ZenModeRepositoryKosmos.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.policy.data.repository
 
+import com.android.settingslib.notification.data.repository.FakeZenModeRepository
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelKosmos.kt
new file mode 100644
index 0000000..ea79edc
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/ui/viewmodel/KeyguardStatusBarViewModelKosmos.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.ui.viewmodel
+
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.statusbar.domain.interactor.keyguardStatusBarInteractor
+import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
+import com.android.systemui.statusbar.policy.batteryController
+
+val Kosmos.keyguardStatusBarViewModel: KeyguardStatusBarViewModel by
+    Kosmos.Fixture {
+        KeyguardStatusBarViewModel(
+            applicationCoroutineScope,
+            headsUpNotificationInteractor,
+            sceneInteractor,
+            keyguardInteractor,
+            keyguardStatusBarInteractor,
+            batteryController,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/FakeUserRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/FakeUserRepository.kt
index 1f2ecb7..ed335f9 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/FakeUserRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/FakeUserRepository.kt
@@ -39,7 +39,7 @@
         // User id to represent a non system (human) user id. We presume this is the main user.
         const val MAIN_USER_ID = 10
 
-        private const val DEFAULT_SELECTED_USER = 0
+        const val DEFAULT_SELECTED_USER = 0
         private val DEFAULT_SELECTED_USER_INFO =
             UserInfo(
                 /* id= */ DEFAULT_SELECTED_USER,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/DeviceConfigProxyKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/util/DeviceConfigProxyKosmos.kt
new file mode 100644
index 0000000..cf902ef
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/DeviceConfigProxyKosmos.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+
+val Kosmos.fakeDeviceConfigProxy by Fixture { DeviceConfigProxyFake() }
+
+val Kosmos.deviceConfigProxy by Fixture<DeviceConfigProxy> { fakeDeviceConfigProxy }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/icons/AppCategoryIconProviderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/util/icons/AppCategoryIconProviderKosmos.kt
new file mode 100644
index 0000000..7987185
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/icons/AppCategoryIconProviderKosmos.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.icons
+
+import android.content.mockPackageManager
+import android.content.mockPackageManagerWrapper
+import com.android.systemui.assist.mockAssistManager
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testDispatcher
+
+var Kosmos.fakeAppCategoryIconProvider by Kosmos.Fixture { FakeAppCategoryIconProvider() }
+
+var Kosmos.appCategoryIconProvider: AppCategoryIconProvider by
+    Kosmos.Fixture {
+        AppCategoryIconProviderImpl(
+            testDispatcher,
+            mockAssistManager,
+            mockPackageManager,
+            mockPackageManagerWrapper
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/icons/FakeAppCategoryIconProvider.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/util/icons/FakeAppCategoryIconProvider.kt
new file mode 100644
index 0000000..3e7bf21
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/icons/FakeAppCategoryIconProvider.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.icons
+
+import android.app.role.RoleManager.ROLE_ASSISTANT
+import android.graphics.drawable.Icon
+
+class FakeAppCategoryIconProvider : AppCategoryIconProvider {
+
+    private val installedApps = mutableMapOf<String, App>()
+
+    fun installCategoryApp(category: String, packageName: String, iconResId: Int) {
+        installedApps[category] = App(packageName, iconResId)
+    }
+
+    fun installAssistantApp(packageName: String, iconResId: Int) {
+        installedApps[ROLE_ASSISTANT] = App(packageName, iconResId)
+    }
+
+    override suspend fun assistantAppIcon() = categoryAppIcon(ROLE_ASSISTANT)
+
+    override suspend fun categoryAppIcon(category: String): Icon? {
+        val app = installedApps[category] ?: return null
+        return Icon.createWithResource(app.packageName, app.iconResId)
+    }
+
+    private class App(val packageName: String, val iconResId: Int)
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java
index 3a70cdf..476b7d8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeGlobalSettings.java
@@ -16,12 +16,16 @@
 
 package com.android.systemui.util.settings;
 
+import static kotlinx.coroutines.test.TestCoroutineDispatchersKt.StandardTestDispatcher;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ContentResolver;
 import android.database.ContentObserver;
 import android.net.Uri;
 
+import kotlinx.coroutines.CoroutineDispatcher;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -30,10 +34,16 @@
 public class FakeGlobalSettings implements GlobalSettings {
     private final Map<String, String> mValues = new HashMap<>();
     private final Map<String, List<ContentObserver>> mContentObserversAllUsers = new HashMap<>();
+    private final CoroutineDispatcher mDispatcher;
 
     public static final Uri CONTENT_URI = Uri.parse("content://settings/fake_global");
 
     public FakeGlobalSettings() {
+        mDispatcher = StandardTestDispatcher(/* scheduler = */ null, /* name = */ null);
+    }
+
+    public FakeGlobalSettings(CoroutineDispatcher dispatcher) {
+        mDispatcher = dispatcher;
     }
 
     @Override
@@ -44,6 +54,11 @@
     }
 
     @Override
+    public CoroutineDispatcher getBackgroundDispatcher() {
+        return mDispatcher;
+    }
+
+    @Override
     public void registerContentObserverSync(Uri uri, boolean notifyDescendants,
             ContentObserver settingsObserver) {
         List<ContentObserver> observers;
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java
index cd219ec..e35da11 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.util.settings;
 
+import static kotlinx.coroutines.test.TestCoroutineDispatchersKt.StandardTestDispatcher;
+
 import android.annotation.UserIdInt;
 import android.content.ContentResolver;
 import android.database.ContentObserver;
@@ -27,6 +29,8 @@
 
 import com.android.systemui.settings.UserTracker;
 
+import kotlinx.coroutines.CoroutineDispatcher;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -37,19 +41,27 @@
     private final Map<SettingsKey, List<ContentObserver>> mContentObservers =
             new HashMap<>();
     private final Map<String, List<ContentObserver>> mContentObserversAllUsers = new HashMap<>();
+    private final CoroutineDispatcher mDispatcher;
 
     public static final Uri CONTENT_URI = Uri.parse("content://settings/fake");
     @UserIdInt
     private int mUserId = UserHandle.USER_CURRENT;
 
     public FakeSettings() {
+        mDispatcher = StandardTestDispatcher(/* scheduler = */ null, /* name = */ null);
+    }
+
+    public FakeSettings(CoroutineDispatcher dispatcher) {
+        mDispatcher = dispatcher;
     }
 
     public FakeSettings(String initialKey, String initialValue) {
+        mDispatcher = StandardTestDispatcher(/* scheduler = */ null, /* name = */ null);
         putString(initialKey, initialValue);
     }
 
     public FakeSettings(Map<String, String> initialValues) {
+        mDispatcher = StandardTestDispatcher(/* scheduler = */ null, /* name = */ null);
         for (Map.Entry<String, String> kv : initialValues.entrySet()) {
             putString(kv.getKey(), kv.getValue());
         }
@@ -66,6 +78,11 @@
     }
 
     @Override
+    public CoroutineDispatcher getBackgroundDispatcher() {
+        return mDispatcher;
+    }
+
+    @Override
     public void registerContentObserverForUserSync(Uri uri, boolean notifyDescendants,
             ContentObserver settingsObserver, int userHandle) {
         List<ContentObserver> observers;
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeCastController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeCastController.java
deleted file mode 100644
index 84ace7c..0000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeCastController.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.android.systemui.utils.leaks;
-
-import android.testing.LeakCheck;
-
-import com.android.systemui.statusbar.policy.CastController;
-import com.android.systemui.statusbar.policy.CastController.Callback;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class FakeCastController extends BaseLeakChecker<Callback> implements CastController {
-    public FakeCastController(LeakCheck test) {
-        super(test, "cast");
-    }
-
-    @Override
-    public void setDiscovering(boolean request) {
-
-    }
-
-    @Override
-    public void setCurrentUserId(int currentUserId) {
-
-    }
-
-    @Override
-    public List<CastDevice> getCastDevices() {
-        return new ArrayList<>();
-    }
-
-    @Override
-    public void startCasting(CastDevice device) {
-
-    }
-
-    @Override
-    public void stopCasting(CastDevice device) {
-
-    }
-
-    @Override
-    public boolean hasConnectedCastDevice() {
-        return false;
-    }
-}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckedTest.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
index 5d21ddd..372a7c7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
@@ -109,7 +109,7 @@
                 } else if (cls == ZenModeController.class) {
                     obj = new FakeZenModeController(this);
                 } else if (cls == CastController.class) {
-                    obj = new FakeCastController(this);
+                    obj = new LeakCheckerCastController(this);
                 } else if (cls == HotspotController.class) {
                     obj = new FakeHotspotController(this);
                 } else if (cls == FlashlightController.class) {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckerCastController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckerCastController.java
new file mode 100644
index 0000000..2249bc0
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/LeakCheckerCastController.java
@@ -0,0 +1,62 @@
+/*
+ * 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 com.android.systemui.utils.leaks;
+
+import android.testing.LeakCheck;
+
+import com.android.systemui.statusbar.policy.CastController;
+import com.android.systemui.statusbar.policy.CastController.Callback;
+import com.android.systemui.statusbar.policy.CastDevice;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LeakCheckerCastController extends BaseLeakChecker<Callback> implements CastController {
+    public LeakCheckerCastController(LeakCheck test) {
+        super(test, "cast");
+    }
+
+    @Override
+    public void setDiscovering(boolean request) {
+
+    }
+
+    @Override
+    public void setCurrentUserId(int currentUserId) {
+
+    }
+
+    @Override
+    public List<CastDevice> getCastDevices() {
+        return new ArrayList<>();
+    }
+
+    @Override
+    public void startCasting(CastDevice device) {
+
+    }
+
+    @Override
+    public void stopCasting(CastDevice device) {
+
+    }
+
+    @Override
+    public boolean hasConnectedCastDevice() {
+        return false;
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/VolumeControllerCollectorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/VolumeControllerCollectorKosmos.kt
new file mode 100644
index 0000000..d60f14c
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/VolumeControllerCollectorKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.volume
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+
+val Kosmos.volumeControllerCollector by
+    Kosmos.Fixture { VolumeControllerCollector(applicationCoroutineScope) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt
index 21d59f0..135cb14 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/data/repository/FakeAudioRepository.kt
@@ -22,7 +22,6 @@
 import com.android.settingslib.volume.shared.model.AudioStream
 import com.android.settingslib.volume.shared.model.AudioStreamModel
 import com.android.settingslib.volume.shared.model.RingerMode
-import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
@@ -42,6 +41,7 @@
 
     private val models: MutableMap<AudioStream, MutableStateFlow<AudioStreamModel>> = mutableMapOf()
     private val lastAudibleVolumes: MutableMap<AudioStream, Int> = mutableMapOf()
+    private val deviceCategories: MutableMap<String, Int> = mutableMapOf()
 
     private fun getAudioStreamModelState(
         audioStream: AudioStream
@@ -60,7 +60,7 @@
             )
         }
 
-    override fun getAudioStream(audioStream: AudioStream): Flow<AudioStreamModel> =
+    override fun getAudioStream(audioStream: AudioStream): StateFlow<AudioStreamModel> =
         getAudioStreamModelState(audioStream).asStateFlow()
 
     override suspend fun setVolume(audioStream: AudioStream, volume: Int) {
@@ -103,4 +103,12 @@
     override suspend fun setRingerMode(audioStream: AudioStream, mode: RingerMode) {
         mutableRingerMode.value = mode
     }
+
+    fun setBluetoothAudioDeviceCategory(bluetoothAddress: String, category: Int) {
+        deviceCategories[bluetoothAddress] = category
+    }
+
+    override suspend fun getBluetoothAudioDeviceCategory(bluetoothAddress: String): Int {
+        return deviceCategories[bluetoothAddress] ?: AudioManager.AUDIO_DEVICE_CATEGORY_UNKNOWN
+    }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/TestMediaDevicesFactory.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/TestMediaDevicesFactory.kt
index 141f242..83adc79 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/TestMediaDevicesFactory.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/TestMediaDevicesFactory.kt
@@ -18,9 +18,11 @@
 
 import android.annotation.SuppressLint
 import android.bluetooth.BluetoothDevice
+import android.bluetooth.BluetoothProfile
 import android.graphics.drawable.Drawable
 import android.graphics.drawable.TestStubDrawable
 import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.settingslib.bluetooth.LeAudioProfile
 import com.android.settingslib.media.BluetoothMediaDevice
 import com.android.settingslib.media.MediaDevice
 import com.android.settingslib.media.PhoneMediaDevice
@@ -59,11 +61,17 @@
                 whenever(name).thenReturn(deviceName)
                 whenever(address).thenReturn(deviceAddress)
             }
+        val leAudioProfile =
+            mock<LeAudioProfile> {
+                whenever(profileId).thenReturn(BluetoothProfile.LE_AUDIO)
+                whenever(isEnabled(bluetoothDevice)).thenReturn(true)
+            }
         val cachedBluetoothDevice: CachedBluetoothDevice = mock {
             whenever(isHearingAidDevice).thenReturn(true)
             whenever(address).thenReturn(deviceAddress)
             whenever(device).thenReturn(bluetoothDevice)
             whenever(name).thenReturn(deviceName)
+            whenever(profiles).thenReturn(listOf(leAudioProfile))
         }
         return mock<BluetoothMediaDevice> {
             whenever(name).thenReturn(deviceName)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractorKosmos.kt
index 95a7b9b..6a46d56 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/spatial/domain/interactor/SpatialAudioComponentInteractorKosmos.kt
@@ -17,8 +17,10 @@
 package com.android.systemui.volume.panel.component.spatial.domain.interactor
 
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.backgroundCoroutineContext
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.media.spatializerInteractor
+import com.android.systemui.volume.data.repository.audioRepository
 import com.android.systemui.volume.domain.interactor.audioOutputInteractor
 
 val Kosmos.spatialAudioComponentInteractor by
@@ -26,6 +28,8 @@
         SpatialAudioComponentInteractor(
             audioOutputInteractor,
             spatializerInteractor,
+            audioRepository,
+            backgroundCoroutineContext,
             testScope.backgroundScope,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelKosmos.kt
index b2b19de..e6b52f0 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelKosmos.kt
@@ -20,6 +20,7 @@
 import com.android.internal.logging.uiEventLogger
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.volume.domain.interactor.audioVolumeInteractor
+import com.android.systemui.volume.shared.volumePanelLogger
 import kotlinx.coroutines.CoroutineScope
 
 val Kosmos.audioStreamSliderViewModelFactory by
@@ -36,6 +37,7 @@
                     applicationContext,
                     audioVolumeInteractor,
                     uiEventLogger,
+                    volumePanelLogger,
                 )
             }
         }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/shared/VolumePanelLoggerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/shared/VolumePanelLoggerKosmos.kt
new file mode 100644
index 0000000..3a7574d
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/shared/VolumePanelLoggerKosmos.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.volume.shared
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.log.logcatLogBuffer
+import com.android.systemui.volume.panel.shared.VolumePanelLogger
+
+val Kosmos.volumePanelLogger by Kosmos.Fixture { VolumePanelLogger(logcatLogBuffer()) }
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt
index fec6ff1..0458f53 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/RotationChangeProvider.kt
@@ -28,6 +28,9 @@
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import java.util.concurrent.CopyOnWriteArrayList
+import java.util.concurrent.atomic.AtomicInteger
+
+private const val INVALID_ROTATION = -1
 
 /**
  * Allows to subscribe to rotation changes. Updates are provided for the display associated to
@@ -45,7 +48,7 @@
     private val listeners = CopyOnWriteArrayList<RotationListener>()
 
     private val displayListener = RotationDisplayListener()
-    private var lastRotation: Int? = null
+    private val lastRotation = AtomicInteger(INVALID_ROTATION)
 
     override fun addCallback(listener: RotationListener) {
         bgHandler.post {
@@ -61,7 +64,7 @@
             listeners -= listener
             if (listeners.isEmpty()) {
                 unsubscribeToRotation()
-                lastRotation = null
+                lastRotation.set(INVALID_ROTATION)
             }
         }
     }
@@ -100,9 +103,8 @@
 
                 if (displayId == display.displayId) {
                     val currentRotation = display.rotation
-                    if (lastRotation == null || lastRotation != currentRotation) {
+                    if (lastRotation.compareAndSet(lastRotation.get(), currentRotation)) {
                         listeners.forEach { it.onRotationChanged(currentRotation) }
-                        lastRotation = currentRotation
                     }
                 }
             } finally {
diff --git a/packages/VpnDialogs/res/values-fr-rCA/strings.xml b/packages/VpnDialogs/res/values-fr-rCA/strings.xml
index ad450b4..9ae0cb2 100644
--- a/packages/VpnDialogs/res/values-fr-rCA/strings.xml
+++ b/packages/VpnDialogs/res/values-fr-rCA/strings.xml
@@ -32,7 +32,7 @@
     <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Modifier les paramètres RPV"</string>
     <string name="configure" msgid="4905518375574791375">"Configurer"</string>
     <string name="disconnect" msgid="971412338304200056">"Déconnecter"</string>
-    <string name="open_app" msgid="3717639178595958667">"Ouvrir l\'application"</string>
+    <string name="open_app" msgid="3717639178595958667">"Ouvrir l\'appli"</string>
     <string name="dismiss" msgid="6192859333764711227">"Ignorer"</string>
     <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g>… ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string>
     <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string>
diff --git a/packages/overlays/AvoidAppsInCutoutOverlay/res/values-fr-rCA/strings.xml b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-fr-rCA/strings.xml
index ea0a27b..4f922a5 100644
--- a/packages/overlays/AvoidAppsInCutoutOverlay/res/values-fr-rCA/strings.xml
+++ b/packages/overlays/AvoidAppsInCutoutOverlay/res/values-fr-rCA/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="3814493834951357513">"Rendre les applications sous la zone de découpe"</string>
+    <string name="display_cutout_emulation_overlay" msgid="3814493834951357513">"Rendre les applis sous la zone de découpe"</string>
 </resources>
diff --git a/proto/src/system_messages.proto b/proto/src/system_messages.proto
index 7f542d1..994bdb5 100644
--- a/proto/src/system_messages.proto
+++ b/proto/src/system_messages.proto
@@ -310,6 +310,14 @@
     // Package: android
     NOTE_USB_UVC = 75;
 
+    // Inform the user about adaptive notifications
+    // Package: com.android.systemui
+    NOTE_ADAPTIVE_NOTIFICATIONS = 76;
+
+    // Warn the user that the device's Headless System User Mode status doesn't match the build's.
+    // Package: android
+    NOTE_WRONG_HSUM_STATUS = 77;
+
     // ADD_NEW_IDS_ABOVE_THIS_LINE
     // Legacy IDs with arbitrary values appear below
     // Legacy IDs existed as stable non-conflicting constants prior to the O release
diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp
index 48bc803..e2eb09f 100644
--- a/ravenwood/Android.bp
+++ b/ravenwood/Android.bp
@@ -231,6 +231,12 @@
 }
 
 filegroup {
+    name: "ravenwood-framework-jarjar-rules",
+    srcs: ["texts/ravenwood-framework-jarjar-rules.txt"],
+    visibility: ["//frameworks/base"],
+}
+
+filegroup {
     name: "ravenwood-services-jarjar-rules",
     srcs: ["texts/ravenwood-services-jarjar-rules.txt"],
     visibility: ["//frameworks/base"],
@@ -268,11 +274,87 @@
     src: "scripts/ravenwood-stats-checker.sh",
     test_suites: ["general-tests"],
     data: [
-        ":framework-minus-apex.ravenwood.stats",
-        ":framework-minus-apex.ravenwood.apis",
-        ":framework-minus-apex.ravenwood.keep_all",
-        ":services.core.ravenwood.stats",
-        ":services.core.ravenwood.apis",
-        ":services.core.ravenwood.keep_all",
+        ":framework-minus-apex.ravenwood-base{hoststubgen_framework-minus-apex_stats.csv}",
+        ":framework-minus-apex.ravenwood-base{hoststubgen_framework-minus-apex_apis.csv}",
+        ":framework-minus-apex.ravenwood-base{hoststubgen_framework-minus-apex_keep_all.txt}",
+        ":framework-minus-apex.ravenwood-base{hoststubgen_framework-minus-apex_dump.txt}",
+        ":services.core.ravenwood-base{hoststubgen_services.core_stats.csv}",
+        ":services.core.ravenwood-base{hoststubgen_services.core_apis.csv}",
+        ":services.core.ravenwood-base{hoststubgen_services.core_keep_all.txt}",
+        ":services.core.ravenwood-base{hoststubgen_services.core_dump.txt}",
+    ],
+}
+
+java_library {
+    name: "services.fakes.ravenwood-jarjar",
+    installable: false,
+    srcs: [":services.fakes-sources"],
+    libs: [
+        "ravenwood-framework",
+        "services.core.ravenwood",
+    ],
+    jarjar_rules: ":ravenwood-services-jarjar-rules",
+    visibility: ["//visibility:private"],
+}
+
+java_library {
+    name: "mockito-ravenwood-prebuilt",
+    installable: false,
+    static_libs: [
+        "mockito-robolectric-prebuilt",
+    ],
+}
+
+java_library {
+    name: "inline-mockito-ravenwood-prebuilt",
+    installable: false,
+    static_libs: [
+        "inline-mockito-robolectric-prebuilt",
+    ],
+}
+
+android_ravenwood_libgroup {
+    name: "ravenwood-runtime",
+    libs: [
+        "100-framework-minus-apex.ravenwood",
+        "200-kxml2-android",
+
+        "ravenwood-runtime-common-ravenwood",
+
+        "android.test.mock.ravenwood",
+        "ravenwood-helper-runtime",
+        "hoststubgen-helper-runtime.ravenwood",
+        "services.core.ravenwood-jarjar",
+        "services.fakes.ravenwood-jarjar",
+
+        // Provide runtime versions of utils linked in below
+        "junit",
+        "truth",
+        "flag-junit",
+        "ravenwood-framework",
+        "ravenwood-junit-impl",
+        "ravenwood-junit-impl-flag",
+        "mockito-ravenwood-prebuilt",
+        "inline-mockito-ravenwood-prebuilt",
+
+        // It's a stub, so it should be towards the end.
+        "z00-all-updatable-modules-system-stubs",
+    ],
+    jni_libs: [
+        "libandroid_runtime",
+        "libravenwood_runtime",
+    ],
+}
+
+android_ravenwood_libgroup {
+    name: "ravenwood-utils",
+    libs: [
+        "junit",
+        "truth",
+        "flag-junit",
+        "ravenwood-framework",
+        "ravenwood-junit",
+        "mockito-ravenwood-prebuilt",
+        "inline-mockito-ravenwood-prebuilt",
     ],
 }
diff --git a/ravenwood/bivalenttest/Android.bp b/ravenwood/bivalenttest/Android.bp
index 2d94894..06cf08e6 100644
--- a/ravenwood/bivalenttest/Android.bp
+++ b/ravenwood/bivalenttest/Android.bp
@@ -38,6 +38,9 @@
         "androidx.annotation_annotation",
         "androidx.test.ext.junit",
         "androidx.test.rules",
+
+        // To make sure it won't cause VerifyError (b/324063814)
+        "platformprotosnano",
     ],
     srcs: [
         "test/**/*.java",
diff --git a/ravenwood/scripts/ravenwood-stats-collector.sh b/ravenwood/scripts/ravenwood-stats-collector.sh
index 43b61a4..36601bd 100755
--- a/ravenwood/scripts/ravenwood-stats-collector.sh
+++ b/ravenwood/scripts/ravenwood-stats-collector.sh
@@ -22,10 +22,12 @@
 stats=$out_dir/ravenwood-stats-all.csv
 apis=$out_dir/ravenwood-apis-all.csv
 keep_all_dir=$out_dir/ravenwood-keep-all/
+dump_dir=$out_dir/ravenwood-dump/
 
 rm -fr $out_dir
 mkdir -p $out_dir
 mkdir -p $keep_all_dir
+mkdir -p $dump_dir
 
 # Where the input files are.
 path=$ANDROID_BUILD_TOP/out/host/linux-x86/testcases/ravenwood-stats-checker/x86_64/
@@ -85,4 +87,8 @@
 
 cp *keep_all.txt $keep_all_dir
 echo "Keep all files created at:"
-find $keep_all_dir -type f
\ No newline at end of file
+find $keep_all_dir -type f
+
+cp *dump.txt $dump_dir
+echo "Dump files created at:"
+find $dump_dir -type f
\ No newline at end of file
diff --git a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
index f3172ae..bdc3577 100644
--- a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
+++ b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
@@ -274,7 +274,9 @@
 android.telephony.ModemActivityInfo
 android.telephony.ServiceState
 
+android.os.connectivity.CellularBatteryStats
 android.os.connectivity.WifiActivityEnergyInfo
+android.os.connectivity.WifiBatteryStats
 
 com.android.server.LocalServices
 
diff --git a/ravenwood/texts/ravenwood-framework-jarjar-rules.txt b/ravenwood/texts/ravenwood-framework-jarjar-rules.txt
new file mode 100644
index 0000000..2eeb904
--- /dev/null
+++ b/ravenwood/texts/ravenwood-framework-jarjar-rules.txt
@@ -0,0 +1,2 @@
+# To avoid VerifyError on nano proto files (b/324063814)
+rule com.**.nano.**   devicenano.@0
diff --git a/services/accessibility/accessibility.aconfig b/services/accessibility/accessibility.aconfig
index 9353150..b4efae3 100644
--- a/services/accessibility/accessibility.aconfig
+++ b/services/accessibility/accessibility.aconfig
@@ -11,6 +11,16 @@
 }
 
 flag {
+    name: "always_allow_observing_touch_events"
+    namespace: "accessibility"
+    description: "Always allows InputFilter observing SOURCE_TOUCHSCREEN events, even if touch exploration is enabled."
+    bug: "344604959"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
     name: "resettable_dynamic_properties"
     namespace: "accessibility"
     description: "Maintains initial copies of a11yServiceInfo dynamic properties so they can reset on disconnect."
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 5fb60e7..9fc64a9 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -26,6 +26,8 @@
 import android.annotation.NonNull;
 import android.content.Context;
 import android.graphics.Region;
+import android.hardware.input.InputManager;
+import android.os.Looper;
 import android.os.PowerManager;
 import android.os.SystemClock;
 import android.provider.Settings;
@@ -54,6 +56,7 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Objects;
 import java.util.StringJoiner;
 
 /**
@@ -158,6 +161,13 @@
      */
     static final int FLAG_FEATURE_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP = 0x00001000;
 
+    /**
+     * Flag for enabling the Accessibility mouse key events feature.
+     *
+     * @see #setUserAndEnabledFeatures(int, int)
+     */
+    static final int FLAG_FEATURE_MOUSE_KEYS = 0x00002000;
+
     static final int FEATURES_AFFECTING_MOTION_EVENTS =
             FLAG_FEATURE_INJECT_MOTION_EVENTS
                     | FLAG_FEATURE_AUTOCLICK
@@ -189,6 +199,8 @@
 
     private KeyboardInterceptor mKeyboardInterceptor;
 
+    private MouseKeysInterceptor mMouseKeysInterceptor;
+
     private boolean mInstalled;
 
     private int mUserId;
@@ -610,7 +622,7 @@
         }
     }
 
-    void notifyAccessibilityButtonClicked(int displayId) {
+    void notifyMagnificationShortcutTriggered(int displayId) {
         if (mMagnificationGestureHandler.size() != 0) {
             final MagnificationGestureHandler handler = mMagnificationGestureHandler.get(displayId);
             if (handler != null) {
@@ -733,6 +745,15 @@
             // default display.
             addFirstEventHandler(Display.DEFAULT_DISPLAY, mKeyboardInterceptor);
         }
+
+        if ((mEnabledFeatures & FLAG_FEATURE_MOUSE_KEYS) != 0) {
+            mMouseKeysInterceptor = new MouseKeysInterceptor(mAms,
+                    Objects.requireNonNull(mContext.getSystemService(
+                            InputManager.class)),
+                    Looper.myLooper(),
+                    Display.DEFAULT_DISPLAY);
+            addFirstEventHandler(Display.DEFAULT_DISPLAY, mMouseKeysInterceptor);
+        }
     }
 
     /**
@@ -816,6 +837,11 @@
             mKeyboardInterceptor.onDestroy();
             mKeyboardInterceptor = null;
         }
+
+        if (mMouseKeysInterceptor != null) {
+            mMouseKeysInterceptor.onDestroy();
+            mMouseKeysInterceptor = null;
+        }
     }
 
     private MagnificationGestureHandler createMagnificationGestureHandler(
@@ -1087,21 +1113,15 @@
         }
     }
 
-    private boolean anyServiceWantsToObserveMotionEvent(MotionEvent event) {
-        // Disable SOURCE_TOUCHSCREEN generic event interception if any service is performing
-        // touch exploration.
-        if (event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN)
-                && (mEnabledFeatures & FLAG_FEATURE_TOUCH_EXPLORATION) != 0) {
-            return false;
-        }
-        final int eventSourceWithoutClass = event.getSource() & ~InputDevice.SOURCE_CLASS_MASK;
-        return (mCombinedGenericMotionEventSources
-                        & mCombinedMotionEventObservedSources
-                        & eventSourceWithoutClass)
-                != 0;
-    }
-
     private boolean anyServiceWantsGenericMotionEvent(MotionEvent event) {
+        if (Flags.alwaysAllowObservingTouchEvents()) {
+            final boolean isTouchEvent = event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN);
+            if (isTouchEvent && !canShareGenericTouchEvent()) {
+                return false;
+            }
+            final int eventSourceWithoutClass = event.getSource() & ~InputDevice.SOURCE_CLASS_MASK;
+            return (mCombinedGenericMotionEventSources & eventSourceWithoutClass) != 0;
+        }
         // Disable SOURCE_TOUCHSCREEN generic event interception if any service is performing
         // touch exploration.
         if (event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN)
@@ -1112,6 +1132,36 @@
         return (mCombinedGenericMotionEventSources & eventSourceWithoutClass) != 0;
     }
 
+    private boolean anyServiceWantsToObserveMotionEvent(MotionEvent event) {
+        if (Flags.alwaysAllowObservingTouchEvents()) {
+            final int eventSourceWithoutClass = event.getSource() & ~InputDevice.SOURCE_CLASS_MASK;
+            return (mCombinedMotionEventObservedSources & eventSourceWithoutClass) != 0;
+        }
+        // Disable SOURCE_TOUCHSCREEN generic event interception if any service is performing
+        // touch exploration.
+        if (event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN)
+                && (mEnabledFeatures & FLAG_FEATURE_TOUCH_EXPLORATION) != 0) {
+            return false;
+        }
+        final int eventSourceWithoutClass = event.getSource() & ~InputDevice.SOURCE_CLASS_MASK;
+        return (mCombinedGenericMotionEventSources
+                & mCombinedMotionEventObservedSources
+                & eventSourceWithoutClass)
+                != 0;
+    }
+
+    private boolean canShareGenericTouchEvent() {
+        if ((mCombinedMotionEventObservedSources & InputDevice.SOURCE_TOUCHSCREEN) != 0) {
+            // Share touch events if a MotionEvent-observing service wants them.
+            return true;
+        }
+        if ((mEnabledFeatures & FLAG_FEATURE_TOUCH_EXPLORATION) == 0) {
+            // Share touch events if touch exploration is not enabled.
+            return true;
+        }
+        return false;
+    }
+
     public void setCombinedGenericMotionEventSources(int sources) {
         mCombinedGenericMotionEventSources = sources;
     }
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 4f9db8b..b918d80 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -47,10 +47,17 @@
 import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
 import static com.android.internal.accessibility.common.ShortcutConstants.USER_SHORTCUT_TYPES;
 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.QUICK_SETTINGS;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.TRIPLETAP;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.TWOFINGER_DOUBLETAP;
 import static com.android.internal.accessibility.util.AccessibilityStatsLogUtils.logAccessibilityShortcutActivated;
 import static com.android.internal.util.FunctionalUtils.ignoreRemoteException;
 import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 import static com.android.server.accessibility.AccessibilityUserState.doesShortcutTargetsStringContain;
+import static com.android.hardware.input.Flags.keyboardA11yMouseKeys;
 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 
 import android.accessibilityservice.AccessibilityGestureEvent;
@@ -844,14 +851,17 @@
                     userState.mEnabledServices, userState.mUserId);
         }
 
-        boolean buttonTargetsChanged = userState.mAccessibilityButtonTargets.removeIf(
+        // Remove any button targets that match any stopped continuous services
+        Set<String> buttonTargets = userState.getShortcutTargetsLocked(SOFTWARE);
+        boolean buttonTargetsChanged = buttonTargets.removeIf(
                 target -> continuousServicePackages.stream().anyMatch(
                         pkg -> Objects.equals(target, pkg)));
         if (buttonTargetsChanged) {
+            userState.updateShortcutTargetsLocked(buttonTargets, SOFTWARE);
             persistColonDelimitedSetToSettingLocked(
-                    Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
+                    ShortcutUtils.convertToKey(SOFTWARE),
                     userState.mUserId,
-                    userState.mAccessibilityButtonTargets, str -> str);
+                    buttonTargets, str -> str);
         }
 
         return enabledServicesChanged || buttonTargetsChanged;
@@ -923,25 +933,11 @@
                                         newValue, restoredFromSdk);
                             }
                         }
-                        case Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS -> {
-                            synchronized (mLock) {
-                                restoreAccessibilityButtonTargetsLocked(
-                                        previousValue, newValue);
-                            }
-                        }
-                        case Settings.Secure.ACCESSIBILITY_QS_TARGETS -> {
-                            if (!android.view.accessibility.Flags.a11yQsShortcut()) {
-                                return;
-                            }
-                            restoreAccessibilityQsTargets(newValue);
-                        }
-                        case Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE -> {
-                            if (!android.view.accessibility.Flags
-                                    .restoreA11yShortcutTargetService()) {
-                                return;
-                            }
-                            restoreAccessibilityShortcutTargetService(previousValue, newValue);
-                        }
+                        case Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
+                                Settings.Secure.ACCESSIBILITY_QS_TARGETS,
+                                Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE ->
+                                restoreShortcutTargets(newValue,
+                                        ShortcutUtils.convertToType(which));
                     }
                 }
             }
@@ -1040,7 +1036,7 @@
         }
         persistColonDelimitedSetToSettingLocked(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
                 userState.mUserId, targetsFromSetting, str -> str);
-        readAccessibilityButtonTargetsLocked(userState);
+        readAccessibilityShortcutTargetsLocked(userState, SOFTWARE);
         onUserStateChangedLocked(userState);
     }
 
@@ -1615,7 +1611,7 @@
         }
         mMainHandler.sendMessage(obtainMessage(
                 AccessibilityManagerService::performAccessibilityShortcutInternal, this,
-                displayId, UserShortcutType.SOFTWARE, targetName));
+                displayId, SOFTWARE, targetName));
     }
 
     /**
@@ -1720,12 +1716,12 @@
         }
         // Turn on/off a11y qs shortcut for the a11y features based on the change in QS Panel
         if (!a11yFeaturesToEnable.isEmpty()) {
-            enableShortcutForTargets(/* enable= */ true, UserShortcutType.QUICK_SETTINGS,
+            enableShortcutForTargets(/* enable= */ true, QUICK_SETTINGS,
                     a11yFeaturesToEnable, userId);
         }
 
         if (!a11yFeaturesToRemove.isEmpty()) {
-            enableShortcutForTargets(/* enable= */ false, UserShortcutType.QUICK_SETTINGS,
+            enableShortcutForTargets(/* enable= */ false, QUICK_SETTINGS,
                     a11yFeaturesToRemove, userId);
         }
     }
@@ -2057,100 +2053,74 @@
     }
 
     /**
-     * User could enable accessibility services and configure accessibility button during the SUW.
-     * Merges current value of accessibility button settings into the restored one to make sure
-     * user's preferences of accessibility button updated in SUW are not lost.
-     *
-     * Called only during settings restore; currently supports only the owner user
-     * TODO: http://b/22388012
-     */
-    void restoreAccessibilityButtonTargetsLocked(String oldSetting, String newSetting) {
-        final Set<String> targetsFromSetting = new ArraySet<>();
-        readColonDelimitedStringToSet(oldSetting, str -> str, targetsFromSetting,
-                /* doMerge = */false);
-        readColonDelimitedStringToSet(newSetting, str -> str, targetsFromSetting,
-                /* doMerge = */true);
-
-        final AccessibilityUserState userState = getUserStateLocked(UserHandle.USER_SYSTEM);
-        userState.mAccessibilityButtonTargets.clear();
-        userState.mAccessibilityButtonTargets.addAll(targetsFromSetting);
-        persistColonDelimitedSetToSettingLocked(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
-                UserHandle.USER_SYSTEM, userState.mAccessibilityButtonTargets, str -> str);
-
-        scheduleNotifyClientsOfServicesStateChangeLocked(userState);
-        onUserStateChangedLocked(userState);
-    }
-
-    /**
      * User could configure accessibility shortcut during the SUW before restoring user data.
      * Merges the current value and the new value to make sure we don't lost the setting the user's
-     * preferences of accessibility qs shortcut updated in SUW are not lost.
-     *
-     * Called only during settings restore; currently supports only the owner user
+     * preferences of accessibility shortcut updated in SUW are not lost.
+     * Called only during settings restore; currently supports only the owner user.
+     * <P>
+     * Throws an exception if used with {@code TRIPLETAP} or {@code TWOFINGER_DOUBLETAP}.
+     * </P>
      * TODO: http://b/22388012
      */
-    private void restoreAccessibilityQsTargets(String newValue) {
+    private void restoreShortcutTargets(String newValue,
+            @UserShortcutType int shortcutType) {
+        assertNoTapShortcut(shortcutType);
+        if (shortcutType == QUICK_SETTINGS && !android.view.accessibility.Flags.a11yQsShortcut()) {
+            return;
+        }
+        if (shortcutType == HARDWARE
+                && !android.view.accessibility.Flags.restoreA11yShortcutTargetService()) {
+            return;
+        }
+
         synchronized (mLock) {
             final AccessibilityUserState userState = getUserStateLocked(UserHandle.USER_SYSTEM);
-            final Set<String> mergedTargets = userState.getA11yQsTargets();
-            readColonDelimitedStringToSet(newValue, str -> str, mergedTargets,
-                    /* doMerge = */ true);
+            final Set<String> mergedTargets = (shortcutType == HARDWARE)
+                    ? new ArraySet<>(ShortcutUtils.getShortcutTargetsFromSettings(
+                            mContext, shortcutType, userState.mUserId))
+                    : userState.getShortcutTargetsLocked(shortcutType);
 
-            userState.updateA11yQsTargetLocked(mergedTargets);
-            persistColonDelimitedSetToSettingLocked(Settings.Secure.ACCESSIBILITY_QS_TARGETS,
+            if (Flags.clearDefaultFromA11yShortcutTargetServiceRestore()
+                    && shortcutType == HARDWARE) {
+                final String defaultService =
+                        mContext.getString(R.string.config_defaultAccessibilityService);
+                final ComponentName defaultServiceComponent = TextUtils.isEmpty(defaultService)
+                        ? null : ComponentName.unflattenFromString(defaultService);
+                boolean shouldClearDefaultService = defaultServiceComponent != null
+                        && !stringSetContainsComponentName(mergedTargets, defaultServiceComponent);
+                readColonDelimitedStringToSet(newValue, str -> str, mergedTargets,
+                        /* doMerge = */ true);
+
+                if (shouldClearDefaultService && stringSetContainsComponentName(
+                        mergedTargets, defaultServiceComponent)) {
+                    Slog.i(LOG_TAG, "Removing default service " + defaultService
+                            + " from restore of "
+                            + Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
+                    mergedTargets.removeIf(str ->
+                            defaultServiceComponent.equals(ComponentName.unflattenFromString(str)));
+                }
+                if (mergedTargets.isEmpty()) {
+                    return;
+                }
+            } else {
+                readColonDelimitedStringToSet(newValue, str -> str, mergedTargets,
+                        /* doMerge = */ true);
+            }
+
+            userState.updateShortcutTargetsLocked(mergedTargets, shortcutType);
+            persistColonDelimitedSetToSettingLocked(ShortcutUtils.convertToKey(shortcutType),
                     UserHandle.USER_SYSTEM, mergedTargets, str -> str);
             scheduleNotifyClientsOfServicesStateChangeLocked(userState);
             onUserStateChangedLocked(userState);
         }
     }
 
-    /**
-     * Merges the old and restored value of
-     * {@link Settings.Secure#ACCESSIBILITY_SHORTCUT_TARGET_SERVICE}.
-     *
-     * <p>Also clears out {@link R.string#config_defaultAccessibilityService} from
-     * the merged set if it was not present before restoring.
-     */
-    private void restoreAccessibilityShortcutTargetService(
-            String oldValue, String restoredValue) {
-        final Set<String> targetsFromSetting = new ArraySet<>();
-        readColonDelimitedStringToSet(oldValue, str -> str,
-                targetsFromSetting, /*doMerge=*/false);
-        final String defaultService =
-                mContext.getString(R.string.config_defaultAccessibilityService);
-        final ComponentName defaultServiceComponent = TextUtils.isEmpty(defaultService)
-                ? null : ComponentName.unflattenFromString(defaultService);
-        boolean shouldClearDefaultService = defaultServiceComponent != null
-                && !stringSetContainsComponentName(targetsFromSetting, defaultServiceComponent);
-        readColonDelimitedStringToSet(restoredValue, str -> str,
-                targetsFromSetting, /*doMerge=*/true);
-        if (Flags.clearDefaultFromA11yShortcutTargetServiceRestore()) {
-            if (shouldClearDefaultService && stringSetContainsComponentName(
-                    targetsFromSetting, defaultServiceComponent)) {
-                Slog.i(LOG_TAG, "Removing default service " + defaultService
-                        + " from restore of "
-                        + Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
-                targetsFromSetting.removeIf(str ->
-                        defaultServiceComponent.equals(ComponentName.unflattenFromString(str)));
-            }
-            if (targetsFromSetting.isEmpty()) {
-                return;
-            }
-        }
-        synchronized (mLock) {
-            final AccessibilityUserState userState = getUserStateLocked(UserHandle.USER_SYSTEM);
-            final Set<String> shortcutTargets =
-                    userState.getShortcutTargetsLocked(UserShortcutType.HARDWARE);
-            shortcutTargets.clear();
-            shortcutTargets.addAll(targetsFromSetting);
-            persistColonDelimitedSetToSettingLocked(
-                    Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
-                    UserHandle.USER_SYSTEM, targetsFromSetting, str -> str);
-            scheduleNotifyClientsOfServicesStateChangeLocked(userState);
-            onUserStateChangedLocked(userState);
-        }
+    private String getRawShortcutSetting(int userId, @UserShortcutType int shortcutType) {
+        return Settings.Secure.getStringForUser(mContext.getContentResolver(),
+                ShortcutUtils.convertToKey(shortcutType), userId);
     }
 
+
     /**
      * Returns {@code true} if the set contains the provided non-null {@link ComponentName}.
      *
@@ -2252,10 +2222,10 @@
         }
     }
 
-    private void sendAccessibilityButtonToInputFilter(int displayId) {
+    private void notifyMagnificationShortcutTriggered(int displayId) {
         synchronized (mLock) {
             if (mHasInputFilter && mInputFilter != null) {
-                mInputFilter.notifyAccessibilityButtonClicked(displayId);
+                mInputFilter.notifyMagnificationShortcutTriggered(displayId);
             }
         }
     }
@@ -2263,7 +2233,7 @@
     private void showAccessibilityTargetsSelection(int displayId,
             @UserShortcutType int shortcutType) {
         final Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON);
-        final String chooserClassName = (shortcutType == UserShortcutType.HARDWARE)
+        final String chooserClassName = (shortcutType == HARDWARE)
                 ? AccessibilityShortcutChooserActivity.class.getName()
                 : AccessibilityButtonChooserActivity.class.getName();
         intent.setClassName(CHOOSER_PACKAGE_NAME, chooserClassName);
@@ -2967,6 +2937,9 @@
             if (combinedGenericMotionEventSources != 0) {
                 flags |= AccessibilityInputFilter.FLAG_FEATURE_INTERCEPT_GENERIC_MOTION_EVENTS;
             }
+            if (userState.isMouseKeysEnabled()) {
+                flags |= AccessibilityInputFilter.FLAG_FEATURE_MOUSE_KEYS;
+            }
             if (flags != 0) {
                 if (!mHasInputFilter) {
                     mHasInputFilter = true;
@@ -3116,9 +3089,10 @@
         scheduleUpdateInputFilter(userState);
         updateRelevantEventsLocked(userState);
         scheduleUpdateClientsIfNeededLocked(userState, forceUpdate);
-        updateAccessibilityShortcutKeyTargetsLocked(userState);
-        updateAccessibilityButtonTargetsLocked(userState);
-        updateAccessibilityQsTargetsLocked(userState);
+        updateAccessibilityShortcutTargetsLocked(userState, HARDWARE);
+        updateAccessibilityShortcutTargetsLocked(userState, SOFTWARE);
+        updateAccessibilityShortcutTargetsLocked(userState, GESTURE);
+        updateAccessibilityShortcutTargetsLocked(userState, QUICK_SETTINGS);
         // Update the capabilities before the mode because we will check the current mode is
         // invalid or not..
         updateMagnificationCapabilitiesSettingsChangeLocked(userState);
@@ -3236,15 +3210,17 @@
         somethingChanged |= readAudioDescriptionEnabledSettingLocked(userState);
         somethingChanged |= readMagnificationEnabledSettingsLocked(userState);
         somethingChanged |= readAutoclickEnabledSettingLocked(userState);
-        somethingChanged |= readAccessibilityShortcutKeySettingLocked(userState);
-        somethingChanged |= readAccessibilityQsTargetsLocked(userState);
-        somethingChanged |= readAccessibilityButtonTargetsLocked(userState);
+        somethingChanged |= readAccessibilityShortcutTargetsLocked(userState, HARDWARE);
+        somethingChanged |= readAccessibilityShortcutTargetsLocked(userState, QUICK_SETTINGS);
+        somethingChanged |= readAccessibilityShortcutTargetsLocked(userState, SOFTWARE);
+        somethingChanged |= readAccessibilityShortcutTargetsLocked(userState, GESTURE);
         somethingChanged |= readAccessibilityButtonTargetComponentLocked(userState);
         somethingChanged |= readUserRecommendedUiTimeoutSettingsLocked(userState);
         somethingChanged |= readMagnificationModeForDefaultDisplayLocked(userState);
         somethingChanged |= readMagnificationCapabilitiesLocked(userState);
         somethingChanged |= readMagnificationFollowTypingLocked(userState);
         somethingChanged |= readAlwaysOnMagnificationLocked(userState);
+        somethingChanged |= readMouseKeysEnabledLocked(userState);
         return somethingChanged;
     }
 
@@ -3386,60 +3362,34 @@
         userState.setSendMotionEventsEnabled(sendMotionEvents);
     }
 
-    private boolean readAccessibilityShortcutKeySettingLocked(AccessibilityUserState userState) {
-        final String settingValue = Settings.Secure.getStringForUser(mContext.getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, userState.mUserId);
+    /**
+     * Throws an exception for {@code TRIPLETAP} or {@code TWOFINGER_DOUBLETAP} types.
+     */
+    private boolean readAccessibilityShortcutTargetsLocked(AccessibilityUserState userState,
+            @UserShortcutType int shortcutType) {
+        assertNoTapShortcut(shortcutType);
+        final String settingValue = getRawShortcutSetting(userState.mUserId, shortcutType);
         final Set<String> targetsFromSetting = new ArraySet<>();
-        readColonDelimitedStringToSet(settingValue, str -> str, targetsFromSetting, false);
-        // Fall back to device's default a11y service, only when setting is never updated.
-        if (settingValue == null) {
+        // If dealing with an empty hardware shortcut, fall back to the default value.
+        if (shortcutType == HARDWARE && settingValue == null) {
             final String defaultService = mContext.getString(
                     R.string.config_defaultAccessibilityService);
             if (!TextUtils.isEmpty(defaultService)) {
-                targetsFromSetting.add(defaultService);
+                // Convert to component name to reformat the target if it has a relative path.
+                ComponentName name = ComponentName.unflattenFromString(defaultService);
+                if (name != null) {
+                    targetsFromSetting.add(name.flattenToString());
+                }
             }
+        } else {
+            readColonDelimitedStringToSet(settingValue, str -> str, targetsFromSetting, false);
         }
 
-        final Set<String> currentTargets =
-                userState.getShortcutTargetsLocked(UserShortcutType.HARDWARE);
-        if (targetsFromSetting.equals(currentTargets)) {
-            return false;
+        if (userState.updateShortcutTargetsLocked(targetsFromSetting, shortcutType)) {
+            scheduleNotifyClientsOfServicesStateChangeLocked(userState);
+            return true;
         }
-        currentTargets.clear();
-        currentTargets.addAll(targetsFromSetting);
-        scheduleNotifyClientsOfServicesStateChangeLocked(userState);
-        return true;
-    }
-
-    private boolean readAccessibilityQsTargetsLocked(AccessibilityUserState userState) {
-        final Set<String> targetsFromSetting = new ArraySet<>();
-        readColonDelimitedSettingToSet(Settings.Secure.ACCESSIBILITY_QS_TARGETS,
-                userState.mUserId, str -> str, targetsFromSetting);
-
-        final Set<String> currentTargets =
-                userState.getShortcutTargetsLocked(UserShortcutType.QUICK_SETTINGS);
-        if (targetsFromSetting.equals(currentTargets)) {
-            return false;
-        }
-        userState.updateA11yQsTargetLocked(targetsFromSetting);
-        scheduleNotifyClientsOfServicesStateChangeLocked(userState);
-        return true;
-    }
-
-    private boolean readAccessibilityButtonTargetsLocked(AccessibilityUserState userState) {
-        final Set<String> targetsFromSetting = new ArraySet<>();
-        readColonDelimitedSettingToSet(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
-                userState.mUserId, str -> str, targetsFromSetting);
-
-        final Set<String> currentTargets =
-                userState.getShortcutTargetsLocked(UserShortcutType.SOFTWARE);
-        if (targetsFromSetting.equals(currentTargets)) {
-            return false;
-        }
-        currentTargets.clear();
-        currentTargets.addAll(targetsFromSetting);
-        scheduleNotifyClientsOfServicesStateChangeLocked(userState);
-        return true;
+        return false;
     }
 
     private boolean readAccessibilityButtonTargetComponentLocked(AccessibilityUserState userState) {
@@ -3480,31 +3430,6 @@
         return false;
     }
 
-    /**
-     * Check if the target that will be enabled by the accessibility shortcut key is installed.
-     * If it isn't, remove it from the list and associated setting so a side loaded service can't
-     * spoof the package name of the default service.
-     */
-    private void updateAccessibilityShortcutKeyTargetsLocked(AccessibilityUserState userState) {
-        final Set<String> currentTargets =
-                userState.getShortcutTargetsLocked(UserShortcutType.HARDWARE);
-        final int lastSize = currentTargets.size();
-        if (lastSize == 0) {
-            return;
-        }
-        currentTargets.removeIf(
-                name -> !userState.isShortcutTargetInstalledLocked(name));
-        if (lastSize == currentTargets.size()) {
-            return;
-        }
-
-        // Update setting key with new value.
-        persistColonDelimitedSetToSettingLocked(
-                Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
-                userState.mUserId, currentTargets, str -> str);
-        scheduleNotifyClientsOfServicesStateChangeLocked(userState);
-    }
-
     private boolean canRequestAndRequestsTouchExplorationLocked(
             AccessibilityServiceConnection service, AccessibilityUserState userState) {
         // Service not ready or cannot request the feature - well nothing to do.
@@ -3663,35 +3588,56 @@
     }
 
     /**
-     * 1) Update accessibility button availability to accessibility services.
-     * 2) Check if the target that will be enabled by the accessibility button is installed.
-     *    If it isn't, remove it from the list and associated setting so a side loaded service can't
-     *    spoof the package name of the default service.
+     * Adds or removes shortcut targets based on other attributes in the UserState.
+     * <P></P>
+     * Any target is removed if it is no longer installed on device.
+     * For software shortcuts,
+     * the function also updates the availability of the a11y button for services that request it.
+     * For quick settings shortcuts,
+     * targets are added if their service is enabled and has a corresponding QS panel.
      */
-    private void updateAccessibilityButtonTargetsLocked(AccessibilityUserState userState) {
-        // Update accessibility button availability.
-        for (int i = userState.mBoundServices.size() - 1; i >= 0; i--) {
-            final AccessibilityServiceConnection service = userState.mBoundServices.get(i);
-            if (service.mRequestAccessibilityButton) {
-                service.notifyAccessibilityButtonAvailabilityChangedLocked(
-                        service.isAccessibilityButtonAvailableLocked(userState));
+    private void updateAccessibilityShortcutTargetsLocked(
+            AccessibilityUserState userState, @UserShortcutType int shortcutType) {
+        if (shortcutType == QUICK_SETTINGS && !android.view.accessibility.Flags.a11yQsShortcut()) {
+            return;
+        }
+        if (shortcutType == SOFTWARE) {
+            // Update accessibility button availability.
+            for (int i = userState.mBoundServices.size() - 1; i >= 0; i--) {
+                final AccessibilityServiceConnection service = userState.mBoundServices.get(i);
+                if (service.mRequestAccessibilityButton) {
+                    service.notifyAccessibilityButtonAvailabilityChangedLocked(
+                            service.isAccessibilityButtonAvailableLocked(userState));
+                }
             }
         }
 
+        // Remove targets that are no longer installed on device.
         final Set<String> currentTargets =
-                userState.getShortcutTargetsLocked(UserShortcutType.SOFTWARE);
-        final int lastSize = currentTargets.size();
-        if (lastSize == 0) {
-            return;
-        }
+                userState.getShortcutTargetsLocked(shortcutType);
         currentTargets.removeIf(
                 name -> !userState.isShortcutTargetInstalledLocked(name));
-        if (lastSize == currentTargets.size()) {
+
+        if (shortcutType == QUICK_SETTINGS) {
+            // Add the target if the a11y service is enabled and the tile exist in QS panel
+            Set<ComponentName> enabledServices = userState.getEnabledServicesLocked();
+            Map<ComponentName, ComponentName> a11yFeatureToTileService =
+                    userState.getA11yFeatureToTileService();
+            Set<ComponentName> currentA11yTilesInQsPanel = userState.getA11yQsTilesInQsPanel();
+            for (ComponentName enabledService : enabledServices) {
+                ComponentName tileService =
+                        a11yFeatureToTileService.getOrDefault(enabledService, null);
+                if (tileService != null && currentA11yTilesInQsPanel.contains(tileService)) {
+                    currentTargets.add(enabledService.flattenToString());
+                }
+            }
+        }
+        // Update targets in userState
+        if (!userState.updateShortcutTargetsLocked(currentTargets, shortcutType)) {
             return;
         }
-
-        // Update setting key with new value.
-        persistColonDelimitedSetToSettingLocked(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
+        // If there was a change to the targets in userState, save the new targets to Settings.
+        persistColonDelimitedSetToSettingLocked(ShortcutUtils.convertToKey(shortcutType),
                 userState.mUserId, currentTargets, str -> str);
         scheduleNotifyClientsOfServicesStateChangeLocked(userState);
     }
@@ -3719,8 +3665,7 @@
             return;
         }
         final Set<String> buttonTargets =
-                userState.getShortcutTargetsLocked(UserShortcutType.SOFTWARE);
-        int lastSize = buttonTargets.size();
+                userState.getShortcutTargetsLocked(SOFTWARE);
         buttonTargets.removeIf(name -> {
             if (packageName != null && name != null && !name.contains(packageName)) {
                 return false;
@@ -3752,13 +3697,11 @@
             }
             return false;
         });
-        boolean changed = (lastSize != buttonTargets.size());
-        lastSize = buttonTargets.size();
 
         final Set<String> shortcutKeyTargets =
-                userState.getShortcutTargetsLocked(UserShortcutType.HARDWARE);
+                userState.getShortcutTargetsLocked(HARDWARE);
         final Set<String> qsShortcutTargets =
-                userState.getShortcutTargetsLocked(UserShortcutType.QUICK_SETTINGS);
+                userState.getShortcutTargetsLocked(QUICK_SETTINGS);
         userState.mEnabledServices.forEach(componentName -> {
             if (packageName != null && componentName != null
                     && !packageName.equals(componentName.getPackageName())) {
@@ -3790,8 +3733,7 @@
                     + " should be assign to the button or shortcut.");
             buttonTargets.add(serviceName);
         });
-        changed |= (lastSize != buttonTargets.size());
-        if (!changed) {
+        if (!userState.updateShortcutTargetsLocked(buttonTargets, SOFTWARE)) {
             return;
         }
 
@@ -3802,50 +3744,6 @@
     }
 
     /**
-     * Update the Settings.Secure.ACCESSIBILITY_QS_TARGETS so that it only contains valid content,
-     * and a side loaded service can't spoof the package name of the default service.
-     * <p>
-     * 1. Remove the target if the target is no longer installed on the device <br/>
-     * 2. Add the target if the target is enabled and the target's tile is in the QS Panel <br/>
-     * </p>
-     */
-    private void updateAccessibilityQsTargetsLocked(AccessibilityUserState userState) {
-        if (!android.view.accessibility.Flags.a11yQsShortcut()) {
-            return;
-        }
-
-        final Set<String> targets =
-                userState.getShortcutTargetsLocked(UserShortcutType.QUICK_SETTINGS);
-
-        // Removes the targets that are no longer installed on the device.
-        boolean somethingChanged = targets.removeIf(
-                name -> !userState.isShortcutTargetInstalledLocked(name));
-        // Add the target if the a11y service is enabled and the tile exist in QS panel
-        Set<ComponentName> enabledServices = userState.getEnabledServicesLocked();
-        Map<ComponentName, ComponentName> a11yFeatureToTileService =
-                userState.getA11yFeatureToTileService();
-        Set<ComponentName> currentA11yTilesInQsPanel = userState.getA11yQsTilesInQsPanel();
-        for (ComponentName enabledService : enabledServices) {
-            ComponentName tileService =
-                    a11yFeatureToTileService.getOrDefault(enabledService, null);
-            if (tileService != null && currentA11yTilesInQsPanel.contains(tileService)) {
-                somethingChanged |= targets.add(enabledService.flattenToString());
-            }
-        }
-
-        if (!somethingChanged) {
-            return;
-        }
-        userState.updateA11yQsTargetLocked(targets);
-
-        // Update setting key with new value.
-        persistColonDelimitedSetToSettingLocked(
-                Settings.Secure.ACCESSIBILITY_QS_TARGETS,
-                userState.mUserId, targets, str -> str);
-        scheduleNotifyClientsOfServicesStateChangeLocked(userState);
-    }
-
-    /**
      * Remove the shortcut target for the unbound service which is requesting accessibility button
      * and targeting sdk > Q from the accessibility button and shortcut.
      *
@@ -3860,30 +3758,26 @@
             return;
         }
 
-        final List<Pair<Integer, String>> shortcutTypeAndShortcutSetting = new ArrayList<>(3);
-        shortcutTypeAndShortcutSetting.add(
-                new Pair<>(UserShortcutType.HARDWARE,
-                        Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE));
-        shortcutTypeAndShortcutSetting.add(
-                new Pair<>(UserShortcutType.SOFTWARE,
-                        Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS));
+        final List<Integer> shortcutTypes = new ArrayList<>(4);
+        shortcutTypes.add(HARDWARE);
+        shortcutTypes.add(SOFTWARE);
         if (android.view.accessibility.Flags.a11yQsShortcut()) {
-            shortcutTypeAndShortcutSetting.add(
-                    new Pair<>(UserShortcutType.QUICK_SETTINGS,
-                            Settings.Secure.ACCESSIBILITY_QS_TARGETS));
+            shortcutTypes.add(QUICK_SETTINGS);
+        }
+        if (android.provider.Flags.a11yStandaloneGestureEnabled()) {
+            shortcutTypes.add(GESTURE);
         }
 
         final ComponentName serviceName = service.getComponentName();
-        for (Pair<Integer, String> shortcutTypePair : shortcutTypeAndShortcutSetting) {
-            int shortcutType = shortcutTypePair.first;
-            String shortcutSettingName = shortcutTypePair.second;
+        for (Integer shortcutType: shortcutTypes) {
+            String shortcutSettingName = ShortcutUtils.convertToKey(shortcutType);
             if (userState.removeShortcutTargetLocked(shortcutType, serviceName)) {
                 final Set<String> currentTargets = userState.getShortcutTargetsLocked(shortcutType);
                 persistColonDelimitedSetToSettingLocked(
                         shortcutSettingName,
                         userState.mUserId, currentTargets, str -> str);
 
-                if (shortcutType != UserShortcutType.QUICK_SETTINGS) {
+                if (shortcutType != QUICK_SETTINGS) {
                     continue;
                 }
 
@@ -3959,7 +3853,8 @@
      */
     @EnforcePermission(MANAGE_ACCESSIBILITY)
     @Override
-    public void performAccessibilityShortcut(String targetName) {
+    public void performAccessibilityShortcut(
+            int displayId, @UserShortcutType int shortcutType, String targetName) {
         performAccessibilityShortcut_enforcePermission();
         if (mTraceManager.isA11yTracingEnabledForTypes(FLAGS_ACCESSIBILITY_MANAGER)) {
             mTraceManager.logTrace(LOG_TAG + ".performAccessibilityShortcut",
@@ -3968,7 +3863,7 @@
 
         mMainHandler.sendMessage(obtainMessage(
                 AccessibilityManagerService::performAccessibilityShortcutInternal, this,
-                Display.DEFAULT_DISPLAY, UserShortcutType.HARDWARE, targetName));
+                displayId, shortcutType, targetName));
     }
 
     /**
@@ -4007,7 +3902,7 @@
                             .isActivated(displayId);
             logAccessibilityShortcutActivated(mContext, MAGNIFICATION_COMPONENT_NAME, shortcutType,
                     enabled);
-            sendAccessibilityButtonToInputFilter(displayId);
+            notifyMagnificationShortcutTriggered(displayId);
             return;
         }
         final ComponentName targetComponentName = ComponentName.unflattenFromString(targetName);
@@ -4115,7 +4010,7 @@
             final boolean requestA11yButton = (installedServiceInfo.flags
                     & FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0;
             // Turns on / off the accessibility service
-            if ((targetSdk <= Build.VERSION_CODES.Q && shortcutType == UserShortcutType.HARDWARE)
+            if ((targetSdk <= Build.VERSION_CODES.Q && shortcutType == HARDWARE)
                     || (targetSdk > Build.VERSION_CODES.Q && !requestA11yButton)) {
                 if (serviceConnection == null) {
                     logAccessibilityShortcutActivated(mContext, assignedTarget, shortcutType,
@@ -4129,7 +4024,7 @@
                 }
                 return true;
             }
-            if (shortcutType == UserShortcutType.HARDWARE && targetSdk > Build.VERSION_CODES.Q
+            if (shortcutType == HARDWARE && targetSdk > Build.VERSION_CODES.Q
                     && requestA11yButton) {
                 if (!userState.getEnabledServicesLocked().contains(assignedTarget)) {
                     enableAccessibilityServiceLocked(assignedTarget, mCurrentUserId);
@@ -4177,6 +4072,11 @@
             boolean enable, @UserShortcutType int shortcutTypes,
             @NonNull List<String> shortcutTargets, @UserIdInt int userId) {
         enableShortcutsForTargets_enforcePermission();
+        if ((shortcutTypes & GESTURE) == GESTURE
+                && !android.provider.Flags.a11yStandaloneGestureEnabled()) {
+            throw new IllegalArgumentException(
+                    "GESTURE type shortcuts are disabled by feature flag");
+        }
         for (int shortcutType : USER_SHORTCUT_TYPES) {
             if ((shortcutTypes & shortcutType) == shortcutType) {
                 enableShortcutForTargets(enable, shortcutType, shortcutTargets, userId);
@@ -4222,7 +4122,7 @@
             validNewTargets = newTargets;
 
             // filter out targets that doesn't have qs shortcut
-            if (shortcutType == UserShortcutType.QUICK_SETTINGS) {
+            if (shortcutType == QUICK_SETTINGS) {
                 validNewTargets = newTargets.stream().filter(target -> {
                     ComponentName targetComponent = ComponentName.unflattenFromString(target);
                     return featureToTileMap.containsKey(targetComponent);
@@ -4240,10 +4140,10 @@
                     /* defaultEmptyString= */ ""
             );
 
-            if (shortcutType == UserShortcutType.QUICK_SETTINGS) {
+            if (shortcutType == QUICK_SETTINGS) {
                 int numOfFeatureChanged = Math.abs(currentTargets.size() - validNewTargets.size());
                 logMetricForQsShortcutConfiguration(enable, numOfFeatureChanged);
-                userState.updateA11yQsTargetLocked(validNewTargets);
+                userState.updateShortcutTargetsLocked(validNewTargets, QUICK_SETTINGS);
                 scheduleNotifyClientsOfServicesStateChangeLocked(userState);
                 onUserStateChangedLocked(userState);
             }
@@ -4257,7 +4157,7 @@
         }
 
         // Add or Remove tile in QS Panel
-        if (shortcutType == UserShortcutType.QUICK_SETTINGS) {
+        if (shortcutType == QUICK_SETTINGS) {
             mMainHandler.sendMessage(obtainMessage(
                     AccessibilityManagerService::updateA11yTileServicesInQuickSettingsPanel,
                     this, validNewTargets, currentTargets, userId));
@@ -4266,7 +4166,7 @@
         if (!enable) {
             return;
         }
-        if (shortcutType == UserShortcutType.HARDWARE) {
+        if (shortcutType == HARDWARE) {
             skipVolumeShortcutDialogTimeoutRestriction(userId);
             if (com.android.server.accessibility.Flags.enableHardwareShortcutDisablesWarning()) {
                 persistIntToSetting(
@@ -4275,7 +4175,7 @@
                         AccessibilityShortcutController.DialogStatus.SHOWN
                 );
             }
-        } else if (shortcutType == UserShortcutType.SOFTWARE) {
+        } else if (shortcutType == SOFTWARE) {
             // Update the A11y FAB size to large when the Magnification shortcut is
             // enabled and the user hasn't changed the floating button size
             if (shortcutTargets.contains(MAGNIFICATION_CONTROLLER_NAME)
@@ -4445,7 +4345,7 @@
             final AccessibilityUserState userState = getCurrentUserStateLocked();
             final ArrayList<String> shortcutTargets = new ArrayList<>(
                     userState.getShortcutTargetsLocked(shortcutType));
-            if (shortcutType != UserShortcutType.SOFTWARE) {
+            if (shortcutType != SOFTWARE) {
                 return shortcutTargets;
             }
             // Adds legacy a11y services requesting a11y button into the list.
@@ -4461,6 +4361,7 @@
                     shortcutTargets.add(serviceName);
                 }
             }
+            userState.updateShortcutTargetsLocked(Set.copyOf(shortcutTargets), shortcutType);
             return shortcutTargets;
         }
     }
@@ -5559,6 +5460,9 @@
         private final Uri mAccessibilityButtonTargetsUri = Settings.Secure.getUriFor(
                 Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
 
+        private final Uri mAccessibilityGestureTargetsUri = Settings.Secure.getUriFor(
+                Settings.Secure.ACCESSIBILITY_GESTURE_TARGETS);
+
         private final Uri mUserNonInteractiveUiTimeoutUri = Settings.Secure.getUriFor(
                 Settings.Secure.ACCESSIBILITY_NON_INTERACTIVE_UI_TIMEOUT_MS);
 
@@ -5577,6 +5481,9 @@
         private final Uri mAlwaysOnMagnificationUri = Settings.Secure.getUriFor(
                 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED);
 
+        private final Uri mMouseKeysUri = Settings.Secure.getUriFor(
+                Settings.Secure.ACCESSIBILITY_MOUSE_KEYS_ENABLED);
+
         public AccessibilityContentObserver(Handler handler) {
             super(handler);
         }
@@ -5612,6 +5519,8 @@
             contentResolver.registerContentObserver(
                     mAccessibilityButtonTargetsUri, false, this, UserHandle.USER_ALL);
             contentResolver.registerContentObserver(
+                    mAccessibilityGestureTargetsUri, false, this, UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(
                     mUserNonInteractiveUiTimeoutUri, false, this, UserHandle.USER_ALL);
             contentResolver.registerContentObserver(
                     mUserInteractiveUiTimeoutUri, false, this, UserHandle.USER_ALL);
@@ -5623,6 +5532,8 @@
                     mMagnificationFollowTypingUri, false, this, UserHandle.USER_ALL);
             contentResolver.registerContentObserver(
                     mAlwaysOnMagnificationUri, false, this, UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(
+                    mMouseKeysUri, false, this, UserHandle.USER_ALL);
         }
 
         @Override
@@ -5672,7 +5583,7 @@
                         || mShowImeWithHardKeyboardUri.equals(uri)) {
                     userState.reconcileSoftKeyboardModeWithSettingsLocked();
                 } else if (mAccessibilityShortcutServiceIdUri.equals(uri)) {
-                    if (readAccessibilityShortcutKeySettingLocked(userState)) {
+                    if (readAccessibilityShortcutTargetsLocked(userState, HARDWARE)) {
                         onUserStateChangedLocked(userState);
                     }
                 } else if (mAccessibilityButtonComponentIdUri.equals(uri)) {
@@ -5680,7 +5591,11 @@
                         onUserStateChangedLocked(userState);
                     }
                 } else if (mAccessibilityButtonTargetsUri.equals(uri)) {
-                    if (readAccessibilityButtonTargetsLocked(userState)) {
+                    if (readAccessibilityShortcutTargetsLocked(userState, SOFTWARE)) {
+                        onUserStateChangedLocked(userState);
+                    }
+                } else if (mAccessibilityGestureTargetsUri.equals(uri)) {
+                    if (readAccessibilityShortcutTargetsLocked(userState, GESTURE)) {
                         onUserStateChangedLocked(userState);
                     }
                 } else if (mUserNonInteractiveUiTimeoutUri.equals(uri)
@@ -5699,6 +5614,10 @@
                     readMagnificationFollowTypingLocked(userState);
                 } else if (mAlwaysOnMagnificationUri.equals(uri)) {
                     readAlwaysOnMagnificationLocked(userState);
+                } else if (mMouseKeysUri.equals(uri)) {
+                    if (readMouseKeysEnabledLocked(userState)) {
+                        onUserStateChangedLocked(userState);
+                    }
                 }
             }
         }
@@ -5837,6 +5756,20 @@
         return false;
     }
 
+    boolean readMouseKeysEnabledLocked(AccessibilityUserState userState) {
+        if (!keyboardA11yMouseKeys()) {
+            return false;
+        }
+        final boolean isMouseKeysEnabled =
+                Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_MOUSE_KEYS_ENABLED, 0, userState.mUserId) == 1;
+        if (isMouseKeysEnabled != userState.isMouseKeysEnabled()) {
+            userState.setMouseKeysEnabled(isMouseKeysEnabled);
+            return true;
+        }
+        return false;
+    }
+
     @Override
     public void setGestureDetectionPassthroughRegion(int displayId, Region region) {
         mMainHandler.sendMessage(
@@ -6505,4 +6438,10 @@
         String metricId = enable ? METRIC_ID_QS_SHORTCUT_ADD : METRIC_ID_QS_SHORTCUT_REMOVE;
         Counter.logIncrementWithUid(metricId, Binder.getCallingUid(), numOfFeatures);
     }
+
+    private void assertNoTapShortcut(@UserShortcutType int shortcutType) {
+        if ((shortcutType & (TRIPLETAP | TWOFINGER_DOUBLETAP)) != 0) {
+            throw new IllegalArgumentException("Tap shortcuts are not supported.");
+        }
+    }
 }
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
index a37a184..b061065 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
@@ -27,6 +27,12 @@
 
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.QUICK_SETTINGS;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.TRIPLETAP;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.TWOFINGER_DOUBLETAP;
 
 import android.accessibilityservice.AccessibilityService.SoftKeyboardShowMode;
 import android.accessibilityservice.AccessibilityServiceInfo;
@@ -98,9 +104,10 @@
 
     final Set<ComponentName> mTouchExplorationGrantedServices = new HashSet<>();
 
-    final ArraySet<String> mAccessibilityShortcutKeyTargets = new ArraySet<>();
+    private final ArraySet<String> mAccessibilityShortcutKeyTargets = new ArraySet<>();
 
-    final ArraySet<String> mAccessibilityButtonTargets = new ArraySet<>();
+    private final ArraySet<String> mAccessibilityButtonTargets = new ArraySet<>();
+    private final ArraySet<String> mAccessibilityGestureTargets = new ArraySet<>();
     private final ArraySet<String> mAccessibilityQsTargets = new ArraySet<>();
 
     /**
@@ -162,6 +169,8 @@
     private final int mFocusStrokeWidthDefaultValue;
     // The default value of the focus color.
     private final int mFocusColorDefaultValue;
+    /** Whether mouse keys feature is enabled. */
+    private boolean mMouseKeysEnabled = false;
     private final Map<ComponentName, ComponentName> mA11yServiceToTileService = new ArrayMap<>();
     private final Map<ComponentName, ComponentName> mA11yActivityToTileService = new ArrayMap<>();
 
@@ -224,6 +233,7 @@
         mTouchExplorationGrantedServices.clear();
         mAccessibilityShortcutKeyTargets.clear();
         mAccessibilityButtonTargets.clear();
+        mAccessibilityGestureTargets.clear();
         mTargetAssignedToAccessibilityButton = null;
         mIsTouchExplorationEnabled = false;
         mServiceHandlesDoubleTap = false;
@@ -524,6 +534,20 @@
         }
     }
 
+    private void dumpShortcutTargets(
+            PrintWriter pw, @UserShortcutType int shortcutType, String name) {
+        pw.append("     ").append(name).append(":{");
+        ArraySet<String> targets = getShortcutTargetsInternalLocked(shortcutType);
+        int size = targets.size();
+        for (int i = 0; i < size; i++) {
+            if (i > 0) {
+                pw.append(", ");
+            }
+            pw.append(targets.valueAt(i));
+        }
+        pw.println("}");
+    }
+
     void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.append("User state[");
         pw.println();
@@ -553,30 +577,12 @@
                 .append(String.valueOf(mAlwaysOnMagnificationEnabled));
         pw.append("}");
         pw.println();
-        pw.append("     shortcut key:{");
-        int size = mAccessibilityShortcutKeyTargets.size();
-        for (int i = 0; i < size; i++) {
-            final String componentId = mAccessibilityShortcutKeyTargets.valueAt(i);
-            pw.append(componentId);
-            if (i + 1 < size) {
-                pw.append(", ");
-            }
-        }
-        pw.println("}");
-        pw.append("     button:{");
-        size = mAccessibilityButtonTargets.size();
-        for (int i = 0; i < size; i++) {
-            final String componentId = mAccessibilityButtonTargets.valueAt(i);
-            pw.append(componentId);
-            if (i + 1 < size) {
-                pw.append(", ");
-            }
-        }
-        pw.println("}");
+        dumpShortcutTargets(pw, HARDWARE, "shortcut key");
+        dumpShortcutTargets(pw, SOFTWARE, "button");
         pw.append("     button target:{").append(mTargetAssignedToAccessibilityButton);
         pw.println("}");
-        pw.append("     qs shortcut targets:").append(mAccessibilityQsTargets.toString());
-        pw.println();
+        dumpShortcutTargets(pw, GESTURE, "gesture");
+        dumpShortcutTargets(pw, QUICK_SETTINGS, "qs shortcut targets");
         pw.append("     a11y tiles in QS panel:").append(mA11yTilesInQsPanel.toString());
         pw.println();
         pw.append("     Bound services:{");
@@ -670,6 +676,14 @@
         mIsFilterKeyEventsEnabled = enabled;
     }
 
+    public void setMouseKeysEnabled(boolean enabled) {
+        mMouseKeysEnabled = enabled;
+    }
+
+    public boolean isMouseKeysEnabled() {
+        return mMouseKeysEnabled;
+    }
+
     public int getInteractiveUiTimeoutLocked() {
         return mInteractiveUiTimeout;
     }
@@ -771,21 +785,28 @@
 
     /**
      * Returns a set which contains the flattened component names and the system class names
-     * assigned to the given shortcut.
+     * assigned to the given shortcut. The set is a defensive copy. To apply any changes to the set,
+     * use {@link #updateShortcutTargetsLocked(Set, int)}
      *
      * @param shortcutType The shortcut type.
      * @return The array set of the strings
      */
     public ArraySet<String> getShortcutTargetsLocked(@UserShortcutType int shortcutType) {
-        if (shortcutType == UserShortcutType.HARDWARE) {
+        return new ArraySet<>(getShortcutTargetsInternalLocked(shortcutType));
+    }
+
+    private ArraySet<String> getShortcutTargetsInternalLocked(@UserShortcutType int shortcutType) {
+        if (shortcutType == HARDWARE) {
             return mAccessibilityShortcutKeyTargets;
-        } else if (shortcutType == UserShortcutType.SOFTWARE) {
+        } else if (shortcutType == SOFTWARE) {
             return mAccessibilityButtonTargets;
-        } else if (shortcutType == UserShortcutType.QUICK_SETTINGS) {
-            return getA11yQsTargets();
-        } else if ((shortcutType == UserShortcutType.TRIPLETAP
+        } else if (shortcutType == GESTURE) {
+            return mAccessibilityGestureTargets;
+        } else if (shortcutType == QUICK_SETTINGS) {
+            return mAccessibilityQsTargets;
+        } else if ((shortcutType == TRIPLETAP
                 && isMagnificationSingleFingerTripleTapEnabledLocked()) || (
-                shortcutType == UserShortcutType.TWOFINGER_DOUBLETAP
+                shortcutType == TWOFINGER_DOUBLETAP
                         && isMagnificationTwoFingerTripleTapEnabledLocked())) {
             ArraySet<String> targets = new ArraySet<>();
             targets.add(MAGNIFICATION_CONTROLLER_NAME);
@@ -795,6 +816,32 @@
     }
 
     /**
+     * Updates the corresponding shortcut targets with the provided set.
+     * Tap shortcuts don't operate using sets of targets,
+     * so trying to update {@code TRIPLETAP} or {@code TWOFINGER_DOUBLETAP}
+     * will instead throw an {@code IllegalArgumentException}
+     * @param newTargets set of targets to replace the existing set.
+     * @param shortcutType type to be replaced.
+     * @return {@code true} if the set was changed, or {@code false} if the elements are the same.
+     * @throws IllegalArgumentException if {@code TRIPLETAP} or {@code TWOFINGER_DOUBLETAP} is used.
+     */
+    boolean updateShortcutTargetsLocked(
+            Set<String> newTargets, @UserShortcutType int shortcutType) {
+        final int mask = TRIPLETAP | TWOFINGER_DOUBLETAP;
+        if ((shortcutType & mask) != 0) {
+            throw new IllegalArgumentException("Tap shortcuts cannot be updated with target sets.");
+        }
+
+        final Set<String> currentTargets = getShortcutTargetsInternalLocked(shortcutType);
+        if (newTargets.equals(currentTargets)) {
+            return false;
+        }
+        currentTargets.clear();
+        currentTargets.addAll(newTargets);
+        return true;
+    }
+
+    /**
      * Whether or not the given shortcut target is installed in device.
      *
      * @param name The shortcut target name
@@ -828,7 +875,7 @@
     }
 
     /**
-     * Removes given shortcut target in the list.
+     * Removes given shortcut target in the set.
      *
      * @param shortcutType The shortcut type.
      * @param target The component name of the shortcut target.
@@ -836,16 +883,17 @@
      */
     public boolean removeShortcutTargetLocked(
             @UserShortcutType int shortcutType, ComponentName target) {
-        if (shortcutType == UserShortcutType.TRIPLETAP
-                || shortcutType == UserShortcutType.TWOFINGER_DOUBLETAP) {
+        if (shortcutType == TRIPLETAP
+                || shortcutType == TWOFINGER_DOUBLETAP) {
             throw new UnsupportedOperationException(
                     "removeShortcutTargetLocked only support shortcut type: "
                             + "software and hardware and quick settings for now"
             );
         }
 
-        Set<String> targets = getShortcutTargetsLocked(shortcutType);
-        boolean result = targets.removeIf(name -> {
+        // getting internal set lets us directly modify targets, as it's not a copy.
+        Set<String> targets = getShortcutTargetsInternalLocked(shortcutType);
+        return targets.removeIf(name -> {
             ComponentName componentName;
             if (name == null
                     || (componentName = ComponentName.unflattenFromString(name)) == null) {
@@ -853,11 +901,6 @@
             }
             return componentName.equals(target);
         });
-        if (shortcutType == UserShortcutType.QUICK_SETTINGS) {
-            updateA11yQsTargetLocked(targets);
-        }
-
-        return result;
     }
 
     /**
@@ -1114,11 +1157,6 @@
         );
     }
 
-    public void updateA11yQsTargetLocked(Set<String> targets) {
-        mAccessibilityQsTargets.clear();
-        mAccessibilityQsTargets.addAll(targets);
-    }
-
     /**
      * Returns a copy of the targets which has qs shortcut turned on
      */
diff --git a/services/accessibility/java/com/android/server/accessibility/MouseKeysInterceptor.java b/services/accessibility/java/com/android/server/accessibility/MouseKeysInterceptor.java
new file mode 100644
index 0000000..3f0f23f
--- /dev/null
+++ b/services/accessibility/java/com/android/server/accessibility/MouseKeysInterceptor.java
@@ -0,0 +1,498 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.accessibility;
+
+import static android.accessibilityservice.AccessibilityTrace.FLAGS_INPUT_FILTER;
+import static android.util.MathUtils.sqrt;
+
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.companion.virtual.VirtualDeviceManager;
+import android.companion.virtual.VirtualDeviceParams;
+import android.hardware.input.InputManager;
+import android.hardware.input.VirtualMouse;
+import android.hardware.input.VirtualMouseButtonEvent;
+import android.hardware.input.VirtualMouseConfig;
+import android.hardware.input.VirtualMouseRelativeEvent;
+import android.hardware.input.VirtualMouseScrollEvent;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.view.KeyEvent;
+
+import com.android.server.LocalServices;
+import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
+
+/**
+ * Implements the "mouse keys" accessibility feature for physical keyboards.
+ *
+ * If enabled, mouse keys will allow users to use a physical keyboard to
+ * control the mouse on the display.
+ * The following mouse functionality is supported by the mouse keys:
+ * <ul>
+ *   <li> Move the mouse pointer in different directions (up, down, left, right and diagonally).
+ *   <li> Click the mouse button (left, right and middle click).
+ *   <li> Press and hold the mouse button.
+ *   <li> Release the mouse button.
+ *   <li> Scroll (up and down).
+ * </ul>
+ *
+ * The keys that are mapped to mouse keys are consumed by {@link AccessibilityInputFilter}.
+ * Non-mouse key {@link KeyEvent} will be passed to the parent handler to be handled as usual.
+ * A new {@link VirtualMouse} is created whenever the mouse keys feature is turned on in Settings.
+ * In case multiple physical keyboard are connected to a device,
+ * mouse keys of each physical keyboard will control a single (global) mouse pointer.
+ */
+public class MouseKeysInterceptor extends BaseEventStreamTransformation implements Handler.Callback,
+        InputManager.InputDeviceListener {
+    private static final String LOG_TAG = "MouseKeysInterceptor";
+
+    // To enable these logs, run: 'adb shell setprop log.tag.MouseKeysInterceptor DEBUG'
+    // (requires restart)
+    private static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG);
+
+    private static final int MESSAGE_MOVE_MOUSE_POINTER = 1;
+    private static final int MESSAGE_SCROLL_MOUSE_POINTER = 2;
+    private static final float MOUSE_POINTER_MOVEMENT_STEP = 1.8f;
+    private static final int KEY_NOT_SET = -1;
+
+    /** Time interval after which mouse action will be repeated */
+    private static final int INTERVAL_MILLIS = 10;
+
+    private final AccessibilityManagerService mAms;
+    private final InputManager mInputManager;
+    private final Handler mHandler;
+
+    private final int mDisplayId;
+
+    VirtualDeviceManager.VirtualDevice mVirtualDevice = null;
+
+    private VirtualMouse mVirtualMouse = null;
+
+    /**
+     * State of the active directional mouse key.
+     * Multiple mouse keys will not be allowed to be used simultaneously i.e.,
+     * once a mouse key is pressed, other mouse key presses will be disregarded
+     * (except for when the "HOLD" key is pressed).
+     */
+    private int mActiveMoveKey = KEY_NOT_SET;
+
+    /** State of the active scroll mouse key. */
+    private int mActiveScrollKey = KEY_NOT_SET;
+
+    /** Last time the key action was performed */
+    private long mLastTimeKeyActionPerformed = 0;
+
+    // TODO (b/346706749): This is currently using the numpad key bindings for mouse keys.
+    //  Decide the final mouse key bindings with UX input.
+    public enum MouseKeyEvent {
+        DIAGONAL_DOWN_LEFT_MOVE(KeyEvent.KEYCODE_NUMPAD_1),
+        DOWN_MOVE(KeyEvent.KEYCODE_NUMPAD_2),
+        DIAGONAL_DOWN_RIGHT_MOVE(KeyEvent.KEYCODE_NUMPAD_3),
+        LEFT_MOVE(KeyEvent.KEYCODE_NUMPAD_4),
+        RIGHT_MOVE(KeyEvent.KEYCODE_NUMPAD_6),
+        DIAGONAL_UP_LEFT_MOVE(KeyEvent.KEYCODE_NUMPAD_7),
+        UP_MOVE(KeyEvent.KEYCODE_NUMPAD_8),
+        DIAGONAL_UP_RIGHT_MOVE(KeyEvent.KEYCODE_NUMPAD_9),
+        LEFT_CLICK(KeyEvent.KEYCODE_NUMPAD_5),
+        RIGHT_CLICK(KeyEvent.KEYCODE_NUMPAD_DOT),
+        HOLD(KeyEvent.KEYCODE_NUMPAD_MULTIPLY),
+        RELEASE(KeyEvent.KEYCODE_NUMPAD_SUBTRACT),
+        SCROLL_UP(KeyEvent.KEYCODE_A),
+        SCROLL_DOWN(KeyEvent.KEYCODE_S);
+
+        private final int mKeyCode;
+        MouseKeyEvent(int enumValue) {
+            mKeyCode = enumValue;
+        }
+
+        private static final SparseArray<MouseKeyEvent> VALUE_TO_ENUM_MAP = new SparseArray<>();
+
+        static {
+            for (MouseKeyEvent type : MouseKeyEvent.values()) {
+                VALUE_TO_ENUM_MAP.put(type.mKeyCode, type);
+            }
+        }
+
+        public final int getKeyCodeValue() {
+            return mKeyCode;
+        }
+
+        /**
+         * Convert int value of the key code to corresponding MouseEvent enum. If no matching
+         * value is found, this will return {@code null}.
+         */
+        @Nullable
+        public static MouseKeyEvent from(int value) {
+            return VALUE_TO_ENUM_MAP.get(value);
+        }
+    }
+
+    /**
+     * Construct a new MouseKeysInterceptor.
+     *
+     * @param service The service to notify of key events
+     * @param inputManager InputManager to track changes to connected input devices
+     * @param looper Looper to use for callbacks and messages
+     * @param displayId Display ID to send mouse events to
+     */
+    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    public MouseKeysInterceptor(AccessibilityManagerService service, InputManager inputManager,
+            Looper looper, int displayId) {
+        mAms = service;
+        mInputManager = inputManager;
+        mHandler = new Handler(looper, this);
+        mInputManager.registerInputDeviceListener(this, mHandler);
+        mDisplayId = displayId;
+        // Create the virtual mouse on a separate thread since virtual device creation
+        // should happen on an auxiliary thread, and not from the handler's thread.
+        new Thread(() -> {
+            mVirtualMouse = createVirtualMouse();
+        }).start();
+
+    }
+
+    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    private void sendVirtualMouseRelativeEvent(float x, float y) {
+        if (mVirtualMouse != null) {
+            mVirtualMouse.sendRelativeEvent(new VirtualMouseRelativeEvent.Builder()
+                    .setRelativeX(x)
+                    .setRelativeY(y)
+                    .build()
+            );
+        }
+    }
+
+    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    private void sendVirtualMouseButtonEvent(int buttonCode, int actionCode) {
+        if (mVirtualMouse != null) {
+            mVirtualMouse.sendButtonEvent(new VirtualMouseButtonEvent.Builder()
+                    .setAction(actionCode)
+                    .setButtonCode(buttonCode)
+                    .build()
+            );
+        }
+    }
+
+    /**
+     * Performs a mouse scroll action based on the provided key code.
+     * This method interprets the key code as a mouse scroll and sends
+     * the corresponding {@code VirtualMouseScrollEvent#mYAxisMovement}.
+
+     * @param keyCode The key code representing the mouse scroll action.
+     *                Supported keys are:
+     *                <ul>
+     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent SCROLL_UP}
+     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent SCROLL_DOWN}
+     *                </ul>
+     */
+    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    private void performMouseScrollAction(int keyCode) {
+        MouseKeyEvent mouseKeyEvent = MouseKeyEvent.from(keyCode);
+        float y = switch (mouseKeyEvent) {
+            case SCROLL_UP -> 1.0f;
+            case SCROLL_DOWN -> -1.0f;
+            default -> 0.0f;
+        };
+        if (mVirtualMouse != null) {
+            mVirtualMouse.sendScrollEvent(new VirtualMouseScrollEvent.Builder()
+                    .setYAxisMovement(y)
+                    .build()
+            );
+        }
+        if (DEBUG) {
+            Slog.d(LOG_TAG, "Performed mouse key event: " + mouseKeyEvent.name()
+                    + " for scroll action with axis movement (y=" + y + ")");
+        }
+    }
+
+    /**
+     * Performs a mouse button action based on the provided key code.
+     * This method interprets the key code as a mouse button press and sends
+     * the corresponding press and release events to the virtual mouse.
+
+     * @param keyCode The key code representing the mouse button action.
+     *                Supported keys are:
+     *                <ul>
+     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent LEFT_CLICK} (Primary Button)
+     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent RIGHT_CLICK} (Secondary
+     *                  Button)
+     *                </ul>
+     */
+    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    private void performMouseButtonAction(int keyCode) {
+        MouseKeyEvent mouseKeyEvent = MouseKeyEvent.from(keyCode);
+        int buttonCode = switch (mouseKeyEvent) {
+            case LEFT_CLICK -> VirtualMouseButtonEvent.BUTTON_PRIMARY;
+            case RIGHT_CLICK -> VirtualMouseButtonEvent.BUTTON_SECONDARY;
+            default -> VirtualMouseButtonEvent.BUTTON_UNKNOWN;
+        };
+        if (buttonCode != VirtualMouseButtonEvent.BUTTON_UNKNOWN) {
+            sendVirtualMouseButtonEvent(buttonCode, VirtualMouseButtonEvent.ACTION_BUTTON_PRESS);
+            sendVirtualMouseButtonEvent(buttonCode, VirtualMouseButtonEvent.ACTION_BUTTON_RELEASE);
+        }
+        if (DEBUG) {
+            if (buttonCode == VirtualMouseButtonEvent.BUTTON_UNKNOWN) {
+                Slog.d(LOG_TAG, "Button code is unknown for mouse key event: "
+                        + mouseKeyEvent.name());
+            } else {
+                Slog.d(LOG_TAG, "Performed mouse key event: " + mouseKeyEvent.name()
+                        + " for button action");
+            }
+        }
+    }
+
+    /**
+     * Performs a mouse pointer action based on the provided key code.
+     * The method calculates the relative movement of the mouse pointer
+     * and sends the corresponding event to the virtual mouse.
+     *
+     * @param keyCode The key code representing the direction or button press.
+     *                Supported keys are:
+     *                <ul>
+     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent DIAGONAL_DOWN_LEFT}
+     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent DOWN}
+     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent DIAGONAL_DOWN_RIGHT}
+     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent LEFT}
+     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent RIGHT}
+     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent DIAGONAL_UP_LEFT}
+     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent UP}
+     *                  <li>{@link MouseKeysInterceptor.MouseKeyEvent DIAGONAL_UP_RIGHT}
+     *                </ul>
+     */
+    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    private void performMousePointerAction(int keyCode) {
+        float x = 0f;
+        float y = 0f;
+        MouseKeyEvent mouseKeyEvent = MouseKeyEvent.from(keyCode);
+        switch (mouseKeyEvent) {
+            case DIAGONAL_DOWN_LEFT_MOVE -> {
+                x = -MOUSE_POINTER_MOVEMENT_STEP / sqrt(2);
+                y = MOUSE_POINTER_MOVEMENT_STEP / sqrt(2);
+            }
+            case DOWN_MOVE -> {
+                y = MOUSE_POINTER_MOVEMENT_STEP;
+            }
+            case DIAGONAL_DOWN_RIGHT_MOVE -> {
+                x = MOUSE_POINTER_MOVEMENT_STEP / sqrt(2);
+                y = MOUSE_POINTER_MOVEMENT_STEP / sqrt(2);
+            }
+            case LEFT_MOVE -> {
+                x = -MOUSE_POINTER_MOVEMENT_STEP;
+            }
+            case RIGHT_MOVE -> {
+                x = MOUSE_POINTER_MOVEMENT_STEP;
+            }
+            case DIAGONAL_UP_LEFT_MOVE -> {
+                x = -MOUSE_POINTER_MOVEMENT_STEP / sqrt(2);
+                y = -MOUSE_POINTER_MOVEMENT_STEP / sqrt(2);
+            }
+            case UP_MOVE -> {
+                y = -MOUSE_POINTER_MOVEMENT_STEP;
+            }
+            case DIAGONAL_UP_RIGHT_MOVE -> {
+                x = MOUSE_POINTER_MOVEMENT_STEP / sqrt(2);
+                y = -MOUSE_POINTER_MOVEMENT_STEP / sqrt(2);
+            }
+            default -> {
+                x = 0.0f;
+                y = 0.0f;
+            }
+        }
+        sendVirtualMouseRelativeEvent(x, y);
+        if (DEBUG) {
+            Slog.d(LOG_TAG, "Performed mouse key event: " + mouseKeyEvent.name()
+                    + " for relative pointer movement (x=" + x + ", y=" + y + ")");
+        }
+    }
+
+    private boolean isMouseKey(int keyCode) {
+        return MouseKeyEvent.VALUE_TO_ENUM_MAP.contains(keyCode);
+    }
+
+    private boolean isMouseButtonKey(int keyCode) {
+        return keyCode == MouseKeyEvent.LEFT_CLICK.getKeyCodeValue()
+                || keyCode == MouseKeyEvent.RIGHT_CLICK.getKeyCodeValue();
+    }
+
+    private boolean isMouseScrollKey(int keyCode) {
+        return keyCode == MouseKeyEvent.SCROLL_UP.getKeyCodeValue()
+                || keyCode == MouseKeyEvent.SCROLL_DOWN.getKeyCodeValue();
+    }
+
+    /**
+     * Create a virtual mouse using the VirtualDeviceManagerInternal.
+     *
+     * @return The created VirtualMouse.
+     */
+    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    private VirtualMouse createVirtualMouse() {
+        final VirtualDeviceManagerInternal localVdm =
+                LocalServices.getService(VirtualDeviceManagerInternal.class);
+        mVirtualDevice = localVdm.createVirtualDevice(
+                new VirtualDeviceParams.Builder().setName("Mouse Keys Virtual Device").build());
+        VirtualMouse virtualMouse = mVirtualDevice.createVirtualMouse(
+                new VirtualMouseConfig.Builder()
+                .setInputDeviceName("Mouse Keys Virtual Mouse")
+                .setAssociatedDisplayId(mDisplayId)
+                .build());
+        return virtualMouse;
+    }
+
+    /**
+     * Handles key events and forwards mouse key events to the virtual mouse.
+     *
+     * @param event The key event to handle.
+     * @param policyFlags The policy flags associated with the key event.
+     */
+    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    @Override
+    public void onKeyEvent(KeyEvent event, int policyFlags) {
+        if (mAms.getTraceManager().isA11yTracingEnabledForTypes(FLAGS_INPUT_FILTER)) {
+            mAms.getTraceManager().logTrace(LOG_TAG + ".onKeyEvent",
+                    FLAGS_INPUT_FILTER, "event=" + event + ";policyFlags=" + policyFlags);
+        }
+        boolean isDown = event.getAction() == KeyEvent.ACTION_DOWN;
+        int keyCode = event.getKeyCode();
+
+        if (!isMouseKey(keyCode)) {
+            // Pass non-mouse key events to the next handler
+            super.onKeyEvent(event, policyFlags);
+        } else if (keyCode == MouseKeyEvent.HOLD.getKeyCodeValue()) {
+            sendVirtualMouseButtonEvent(VirtualMouseButtonEvent.BUTTON_PRIMARY,
+                    VirtualMouseButtonEvent.ACTION_BUTTON_PRESS);
+        } else if (keyCode == MouseKeyEvent.RELEASE.getKeyCodeValue()) {
+            sendVirtualMouseButtonEvent(VirtualMouseButtonEvent.BUTTON_PRIMARY,
+                    VirtualMouseButtonEvent.ACTION_BUTTON_RELEASE);
+        } else if (isDown && isMouseButtonKey(keyCode)) {
+            performMouseButtonAction(keyCode);
+        } else if (isDown && isMouseScrollKey(keyCode)) {
+            // If the scroll key is pressed down and no other key is active,
+            // set it as the active key and send a message to scroll the pointer
+            if (mActiveScrollKey == KEY_NOT_SET) {
+                mActiveScrollKey = keyCode;
+                mLastTimeKeyActionPerformed = event.getDownTime();
+                mHandler.sendEmptyMessage(MESSAGE_SCROLL_MOUSE_POINTER);
+            }
+        } else if (isDown) {
+            // This is a directional key.
+            // If the key is pressed down and no other key is active,
+            // set it as the active key and send a message to move the pointer
+            if (mActiveMoveKey == KEY_NOT_SET) {
+                mActiveMoveKey = keyCode;
+                mLastTimeKeyActionPerformed = event.getDownTime();
+                mHandler.sendEmptyMessage(MESSAGE_MOVE_MOUSE_POINTER);
+            }
+        } else if (mActiveMoveKey == keyCode) {
+            // If the key is released, and it is the active key, stop moving the pointer
+            mActiveMoveKey = KEY_NOT_SET;
+            mHandler.removeMessages(MESSAGE_MOVE_MOUSE_POINTER);
+        } else if (mActiveScrollKey == keyCode) {
+            // If the key is released, and it is the active key, stop scrolling the pointer
+            mActiveScrollKey = KEY_NOT_SET;
+            mHandler.removeMessages(MESSAGE_SCROLL_MOUSE_POINTER);
+        } else {
+            Slog.i(LOG_TAG, "Dropping event with key code: '" + keyCode
+                    + "', with no matching down event from deviceId = " + event.getDeviceId());
+        }
+    }
+
+    /**
+     * Handle messages for moving or scrolling the mouse pointer.
+     *
+     * @param msg The message to handle.
+     * @return True if the message was handled, false otherwise.
+     */
+    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    @Override
+    public boolean handleMessage(Message msg) {
+        switch (msg.what) {
+            case MESSAGE_MOVE_MOUSE_POINTER ->
+                    handleMouseMessage(msg.getWhen(), mActiveMoveKey, MESSAGE_MOVE_MOUSE_POINTER);
+            case MESSAGE_SCROLL_MOUSE_POINTER ->
+                    handleMouseMessage(msg.getWhen(), mActiveScrollKey,
+                            MESSAGE_SCROLL_MOUSE_POINTER);
+            default -> {
+                Slog.e(LOG_TAG, "Unexpected message type");
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Handles mouse-related messages for moving or scrolling the mouse pointer.
+     * This method checks if the specified time interval {@code INTERVAL_MILLIS} has passed since
+     * the last movement or scroll action and performs the corresponding action if necessary.
+     * If there is an active key, the message is rescheduled to be handled again
+     * after the specified {@code INTERVAL_MILLIS}.
+     *
+     * @param currentTime The current time when the message is being handled.
+     * @param activeKey The key code representing the active key. This determines
+     *                  the direction or type of action to be performed.
+     * @param messageType The type of message to be handled. It can be one of the
+     *                    following:
+     *                    <ul>
+     *                      <li>{@link #MESSAGE_MOVE_MOUSE_POINTER} - for moving the mouse pointer.
+     *                      <li>{@link #MESSAGE_SCROLL_MOUSE_POINTER} - for scrolling mouse pointer.
+     *                    </ul>
+     */
+    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    public void handleMouseMessage(long currentTime, int activeKey, int messageType) {
+        if (currentTime - mLastTimeKeyActionPerformed >= INTERVAL_MILLIS) {
+            if (messageType == MESSAGE_MOVE_MOUSE_POINTER) {
+                performMousePointerAction(activeKey);
+            } else if (messageType == MESSAGE_SCROLL_MOUSE_POINTER) {
+                performMouseScrollAction(activeKey);
+            }
+            mLastTimeKeyActionPerformed = currentTime;
+        }
+        if (activeKey != KEY_NOT_SET) {
+            // Reschedule the message if the key is still active
+            mHandler.sendEmptyMessageDelayed(messageType, INTERVAL_MILLIS);
+        }
+    }
+
+    @Override
+    public void onInputDeviceAdded(int deviceId) {
+    }
+
+    @Override
+    public void onInputDeviceRemoved(int deviceId) {
+    }
+
+    @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    @Override
+    public void onDestroy() {
+        // Clear mouse state
+        mActiveMoveKey = KEY_NOT_SET;
+        mActiveScrollKey = KEY_NOT_SET;
+        mLastTimeKeyActionPerformed = 0;
+        mHandler.removeCallbacksAndMessages(null);
+
+        mVirtualDevice.close();
+        mInputManager.unregisterInputDeviceListener(this);
+    }
+
+    @Override
+    public void onInputDeviceChanged(int deviceId) {
+    }
+
+}
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 5567707..76f6d17 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -17,6 +17,7 @@
 package com.android.server.appwidget;
 
 import static android.appwidget.flags.Flags.removeAppWidgetServiceIoFromCriticalPath;
+import static android.appwidget.flags.Flags.supportResumeRestoreAfterReboot;
 import static android.content.Context.KEYGUARD_SERVICE;
 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
@@ -166,6 +167,8 @@
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
 import java.util.function.LongSupplier;
 
 class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBackupProvider,
@@ -342,6 +345,11 @@
         LocalServices.addService(AppWidgetManagerInternal.class, new AppWidgetManagerLocal());
     }
 
+    @Override
+    public int getMaxBitmapMemory() {
+        return mMaxWidgetBitmapMemory;
+    }
+
     void systemServicesReady() {
         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
         mAppOpsManagerInternal = LocalServices.getService(AppOpsManagerInternal.class);
@@ -457,7 +465,7 @@
                 break;
             case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
                 added = true;
-                // Follow through
+                // fall through
             case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
                 pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
                 break;
@@ -3571,6 +3579,13 @@
             }
 
             out.endTag(null, "gs");
+
+            if (supportResumeRestoreAfterReboot()
+                    && mBackupRestoreController.requiresPersistenceLocked()) {
+                AppWidgetXmlUtil.writeBackupRestoreControllerState(
+                        out, mBackupRestoreController.getStateLocked(userId));
+            }
+
             out.endDocument();
             return true;
         } catch (IOException e) {
@@ -3717,6 +3732,32 @@
                         LoadedWidgetState loadedWidgets = new LoadedWidgetState(widget,
                                 hostTag, providerTag);
                         outLoadedWidgets.add(loadedWidgets);
+                    } else if (supportResumeRestoreAfterReboot()
+                            && AppWidgetXmlUtil.TAG_BACKUP_RESTORE_CONTROLLER_STATE.equals(tag)) {
+                        final BackupRestoreController.State s =
+                                AppWidgetXmlUtil.readBackupRestoreControllerState(parser);
+                        if (s == null) {
+                            continue;
+                        }
+                        final Set<String> prunedAppsInFile = s.getPrunedApps();
+                        if (prunedAppsInFile != null) {
+                            final Set<String> prunedAppsInMemory = mBackupRestoreController
+                                    .mPrunedAppsPerUser.get(userId);
+                            if (prunedAppsInMemory == null) {
+                                mBackupRestoreController.mPrunedAppsPerUser.put(
+                                        userId, prunedAppsInFile);
+                            } else {
+                                prunedAppsInMemory.addAll(prunedAppsInFile);
+                            }
+                        }
+                        loadUpdateRecords(s.getUpdatesByProvider(),
+                                this::findProviderByTag,
+                                mBackupRestoreController.mUpdatesByProvider::get,
+                                mBackupRestoreController.mUpdatesByProvider::put);
+                        loadUpdateRecords(s.getUpdatesByHost(),
+                                this::findHostByTag,
+                                mBackupRestoreController.mUpdatesByHost::get,
+                                mBackupRestoreController.mUpdatesByHost::put);
                     }
                 }
             } while (type != XmlPullParser.END_DOCUMENT);
@@ -3732,6 +3773,36 @@
         return version;
     }
 
+    private <T> void loadUpdateRecords(
+            @Nullable final SparseArray<
+                    List<BackupRestoreController.RestoreUpdateRecord>> updatesOnFile,
+            @NonNull final Function<Integer, T> findKeyByTagCb,
+            @NonNull final Function<T, List<
+                    BackupRestoreController.RestoreUpdateRecord>> findRecordsCb,
+            @NonNull final BiConsumer<T, List<
+                    BackupRestoreController.RestoreUpdateRecord>> newRecordsCb) {
+        if (updatesOnFile == null) {
+            return;
+        }
+        for (int i = 0; i < updatesOnFile.size(); i++) {
+            final int tag = updatesOnFile.keyAt(i);
+            final List<
+                    BackupRestoreController.RestoreUpdateRecord
+                    > recordsOnFile = updatesOnFile.get(tag);
+            if (recordsOnFile == null || recordsOnFile.isEmpty()) {
+                continue;
+            }
+            final T key = findKeyByTagCb.apply(tag);
+            final List<BackupRestoreController.RestoreUpdateRecord> recordsInMemory =
+                    findRecordsCb.apply(key);
+            if (recordsInMemory != null) {
+                recordsInMemory.addAll(recordsOnFile);
+            } else  {
+                newRecordsCb.accept(key, recordsOnFile);
+            }
+        }
+    }
+
     private void performUpgradeLocked(int fromVersion) {
         if (fromVersion < CURRENT_VERSION) {
             Slog.v(TAG, "Upgrading widget database from " + fromVersion + " to "
@@ -4674,7 +4745,7 @@
         }
     }
 
-    private static final class Provider {
+    static final class Provider {
 
         ProviderId id;
         AppWidgetProviderInfo info;
@@ -4931,7 +5002,7 @@
         }
     }
 
-    private static final class Host {
+    static final class Host {
         HostId id;
         ArrayList<Widget> widgets = new ArrayList<>();
         IAppWidgetHost callbacks;
@@ -5250,10 +5321,10 @@
     /**
      * This class encapsulates the backup and restore logic for a user group state.
      */
-    private final class BackupRestoreController {
+    final class BackupRestoreController {
         private static final String TAG = "BackupRestoreController";
 
-        private static final boolean DEBUG = true;
+        private static final boolean DEBUG = AppWidgetServiceImpl.DEBUG;
 
         // Version of backed-up widget state.
         private static final int WIDGET_STATE_VERSION = 2;
@@ -5262,16 +5333,31 @@
         // a given package.  Keep track of what we've done so far here; the list is
         // cleared at the start of every system restore pass, but preserved through
         // any install-time restore operations.
+        @GuardedBy("AppWidgetServiceImpl.this.mLock")
         private final SparseArray<Set<String>> mPrunedAppsPerUser = new SparseArray<>();
 
-        private final HashMap<Provider, ArrayList<RestoreUpdateRecord>> mUpdatesByProvider =
-                new HashMap<>();
-        private final HashMap<Host, ArrayList<RestoreUpdateRecord>> mUpdatesByHost =
-                new HashMap<>();
+        @GuardedBy("AppWidgetServiceImpl.this.mLock")
+        final Map<Provider, List<RestoreUpdateRecord>> mUpdatesByProvider =
+                new ArrayMap<>();
 
-        @GuardedBy("mLock")
+        @GuardedBy("AppWidgetServiceImpl.this.mLock")
+        private final Map<Host, List<RestoreUpdateRecord>> mUpdatesByHost =
+                new ArrayMap<>();
+
+        @GuardedBy("AppWidgetServiceImpl.this.mLock")
         private boolean mHasSystemRestoreFinished;
 
+        @GuardedBy("AppWidgetServiceImpl.this.mLock")
+        public boolean requiresPersistenceLocked() {
+            if (mHasSystemRestoreFinished) {
+                // No need to persist intermediate states if system restore is already finished.
+                return false;
+            }
+            // If either of the internal states is non-empty, then we need to persist that
+            return !(mPrunedAppsPerUser.size() == 0 && mUpdatesByProvider.isEmpty()
+                    && mUpdatesByHost.isEmpty());
+        }
+
         public List<String> getWidgetParticipants(int userId) {
             if (DEBUG) {
                 Slog.i(TAG, "Getting widget participants for user: " + userId);
@@ -5436,7 +5522,7 @@
                                 // If there's no live entry for this provider, add an inactive one
                                 // so that widget IDs referring to them can be properly allocated
 
-                                // Backup and resotre only for the parent profile.
+                                // Backup and restore only for the parent profile.
                                 ComponentName componentName = new ComponentName(pkg, cl);
 
                                 Provider p = findProviderLocked(componentName, userId);
@@ -5579,9 +5665,9 @@
 
             final UserHandle userHandle = new UserHandle(userId);
             // Build the providers' broadcasts and send them off
-            Set<Map.Entry<Provider, ArrayList<RestoreUpdateRecord>>> providerEntries
+            Set<Map.Entry<Provider, List<RestoreUpdateRecord>>> providerEntries
                     = mUpdatesByProvider.entrySet();
-            for (Map.Entry<Provider, ArrayList<RestoreUpdateRecord>> e : providerEntries) {
+            for (Map.Entry<Provider, List<RestoreUpdateRecord>> e : providerEntries) {
                 // For each provider there's a list of affected IDs
                 Provider provider = e.getKey();
                 if (provider.zombie) {
@@ -5589,7 +5675,7 @@
                     // We'll be called again when the provider is installed.
                     continue;
                 }
-                ArrayList<RestoreUpdateRecord> updates = e.getValue();
+                List<RestoreUpdateRecord> updates = e.getValue();
                 final int pending = countPendingUpdates(updates);
                 if (DEBUG) {
                     Slog.i(TAG, "Provider " + provider + " pending: " + pending);
@@ -5618,12 +5704,12 @@
             }
 
             // same thing per host
-            Set<Map.Entry<Host, ArrayList<RestoreUpdateRecord>>> hostEntries
+            Set<Map.Entry<Host, List<RestoreUpdateRecord>>> hostEntries
                     = mUpdatesByHost.entrySet();
-            for (Map.Entry<Host, ArrayList<RestoreUpdateRecord>> e : hostEntries) {
+            for (Map.Entry<Host, List<RestoreUpdateRecord>> e : hostEntries) {
                 Host host = e.getKey();
                 if (host.id.uid != UNKNOWN_UID) {
-                    ArrayList<RestoreUpdateRecord> updates = e.getValue();
+                    List<RestoreUpdateRecord> updates = e.getValue();
                     final int pending = countPendingUpdates(updates);
                     if (DEBUG) {
                         Slog.i(TAG, "Host " + host + " pending: " + pending);
@@ -5714,8 +5800,9 @@
             return false;
         }
 
+        @GuardedBy("mLock")
         private void stashProviderRestoreUpdateLocked(Provider provider, int oldId, int newId) {
-            ArrayList<RestoreUpdateRecord> r = mUpdatesByProvider.get(provider);
+            List<RestoreUpdateRecord> r = mUpdatesByProvider.get(provider);
             if (r == null) {
                 r = new ArrayList<>();
                 mUpdatesByProvider.put(provider, r);
@@ -5732,7 +5819,7 @@
             r.add(new RestoreUpdateRecord(oldId, newId));
         }
 
-        private boolean alreadyStashed(ArrayList<RestoreUpdateRecord> stash,
+        private boolean alreadyStashed(List<RestoreUpdateRecord> stash,
                 final int oldId, final int newId) {
             final int N = stash.size();
             for (int i = 0; i < N; i++) {
@@ -5744,8 +5831,9 @@
             return false;
         }
 
+        @GuardedBy("mLock")
         private void stashHostRestoreUpdateLocked(Host host, int oldId, int newId) {
-            ArrayList<RestoreUpdateRecord> r = mUpdatesByHost.get(host);
+            List<RestoreUpdateRecord> r = mUpdatesByHost.get(host);
             if (r == null) {
                 r = new ArrayList<>();
                 mUpdatesByHost.put(host, r);
@@ -5835,7 +5923,7 @@
                     || widget.provider.getUserId() == userId);
         }
 
-        private int countPendingUpdates(ArrayList<RestoreUpdateRecord> updates) {
+        private int countPendingUpdates(List<RestoreUpdateRecord> updates) {
             int pending = 0;
             final int N = updates.size();
             for (int i = 0; i < N; i++) {
@@ -5847,9 +5935,28 @@
             return pending;
         }
 
+        @GuardedBy("mLock")
+        @NonNull
+        private State getStateLocked(final int userId) {
+            final Set<String> prunedApps = mPrunedAppsPerUser.get(userId);
+            final SparseArray<List<RestoreUpdateRecord>> updatesByProvider = new SparseArray<>();
+            final SparseArray<List<RestoreUpdateRecord>> updatesByHost = new SparseArray<>();
+            mUpdatesByProvider.forEach((p, updates) -> {
+                if (p.getUserId() == userId) {
+                    updatesByProvider.put(p.tag, new ArrayList<>(updates));
+                }
+            });
+            mUpdatesByHost.forEach((h, updates) -> {
+                if (h.getUserId() == userId) {
+                    updatesByHost.put(h.tag, new ArrayList<>(updates));
+                }
+            });
+            return new State(prunedApps, updatesByProvider, updatesByHost);
+        }
+
         // Accumulate a list of updates that affect the given provider for a final
         // coalesced notification broadcast once restore is over.
-        private class RestoreUpdateRecord {
+        static class RestoreUpdateRecord {
             public int oldId;
             public int newId;
             public boolean notified;
@@ -5860,6 +5967,45 @@
                 notified = false;
             }
         }
+
+        static final class State {
+            // We need to make sure to wipe the pre-restore widget state only once for
+            // a given package.  Keep track of what we've done so far here; the list is
+            // cleared at the start of every system restore pass, but preserved through
+            // any install-time restore operations.
+            @Nullable
+            private final Set<String> mPrunedApps;
+
+            @Nullable
+            private final SparseArray<List<RestoreUpdateRecord>> mUpdatesByProvider;
+
+            @Nullable
+            private final SparseArray<List<RestoreUpdateRecord>> mUpdatesByHost;
+
+            State(
+                    @Nullable final Set<String> prunedApps,
+                    @Nullable final SparseArray<List<RestoreUpdateRecord>> updatesByProvider,
+                    @Nullable final SparseArray<List<RestoreUpdateRecord>> updatesByHost) {
+                mPrunedApps = prunedApps;
+                mUpdatesByProvider = updatesByProvider;
+                mUpdatesByHost = updatesByHost;
+            }
+
+            @Nullable
+            Set<String> getPrunedApps() {
+                return mPrunedApps;
+            }
+
+            @Nullable
+            SparseArray<List<BackupRestoreController.RestoreUpdateRecord>> getUpdatesByProvider() {
+                return mUpdatesByProvider;
+            }
+
+            @Nullable
+            SparseArray<List<BackupRestoreController.RestoreUpdateRecord>> getUpdatesByHost() {
+                return mUpdatesByHost;
+            }
+        }
     }
 
     private class AppWidgetManagerLocal extends AppWidgetManagerInternal {
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetXmlUtil.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetXmlUtil.java
index d781cd8..ce9130a 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetXmlUtil.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetXmlUtil.java
@@ -22,17 +22,24 @@
 import android.content.ComponentName;
 import android.os.Build;
 import android.text.TextUtils;
+import android.util.ArraySet;
+import android.util.Log;
 import android.util.SizeF;
 import android.util.Slog;
+import android.util.SparseArray;
 
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 /**
@@ -65,6 +72,16 @@
     private static final String ATTR_DESCRIPTION_RES = "description_res";
     private static final String ATTR_PROVIDER_INHERITANCE = "provider_inheritance";
     private static final String ATTR_OS_FINGERPRINT = "os_fingerprint";
+    static final String TAG_BACKUP_RESTORE_CONTROLLER_STATE = "br";
+    private static final String TAG_PRUNED_APPS = "pruned_apps";
+    private static final String ATTR_TAG = "tag";
+    private static final String ATTR_PACKAGE_NAMES = "pkgs";
+    private static final String TAG_PROVIDER_UPDATES = "provider_updates";
+    private static final String TAG_HOST_UPDATES = "host_updates";
+    private static final String TAG_RECORD = "record";
+    private static final String ATTR_OLD_ID = "old_id";
+    private static final String ATTR_NEW_ID = "new_id";
+    private static final String ATTR_NOTIFIED = "notified";
     private static final String SIZE_SEPARATOR = ",";
 
     /**
@@ -165,4 +182,168 @@
             return null;
         }
     }
+
+    /**
+     * Persists {@link AppWidgetServiceImpl.BackupRestoreController.State} to disk as XML.
+     * See {@link #readBackupRestoreControllerState(TypedXmlPullParser)} for example XML.
+     *
+     * @param out XML serializer
+     * @param state {@link AppWidgetServiceImpl.BackupRestoreController.State} of
+     *      intermediate states to be persisted as xml to resume restore after reboot.
+     */
+    static void writeBackupRestoreControllerState(
+            @NonNull final TypedXmlSerializer out,
+            @NonNull final AppWidgetServiceImpl.BackupRestoreController.State state)
+            throws IOException {
+        Objects.requireNonNull(out);
+        Objects.requireNonNull(state);
+        out.startTag(null, TAG_BACKUP_RESTORE_CONTROLLER_STATE);
+        final Set<String> prunedApps = state.getPrunedApps();
+        if (prunedApps != null && !prunedApps.isEmpty()) {
+            out.startTag(null, TAG_PRUNED_APPS);
+            out.attribute(null, ATTR_PACKAGE_NAMES, String.join(",", prunedApps));
+            out.endTag(null, TAG_PRUNED_APPS);
+        }
+        final SparseArray<List<AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord>>
+                updatesByProvider = state.getUpdatesByProvider();
+        if (updatesByProvider != null) {
+            writeUpdateRecords(out, TAG_PROVIDER_UPDATES, updatesByProvider);
+        }
+        final SparseArray<List<AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord>>
+                updatesByHost = state.getUpdatesByHost();
+        if (updatesByHost != null) {
+            writeUpdateRecords(out, TAG_HOST_UPDATES, updatesByHost);
+        }
+        out.endTag(null, TAG_BACKUP_RESTORE_CONTROLLER_STATE);
+    }
+
+    private static void writeUpdateRecords(@NonNull final TypedXmlSerializer out,
+            @NonNull final String outerTag, @NonNull final SparseArray<List<
+                    AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord>> records)
+            throws IOException {
+        for (int i = 0; i < records.size(); i++) {
+            final int tag = records.keyAt(i);
+            out.startTag(null, outerTag);
+            out.attributeInt(null, ATTR_TAG, tag);
+            final List<AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord> entries =
+                    records.get(tag);
+            for (AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord entry : entries) {
+                out.startTag(null, TAG_RECORD);
+                out.attributeInt(null, ATTR_OLD_ID, entry.oldId);
+                out.attributeInt(null, ATTR_NEW_ID, entry.newId);
+                out.attributeBoolean(null, ATTR_NOTIFIED, entry.notified);
+                out.endTag(null, TAG_RECORD);
+            }
+            out.endTag(null, outerTag);
+        }
+    }
+
+    /**
+     * Parses {@link AppWidgetServiceImpl.BackupRestoreController.State} from xml.
+     *
+     * <pre>
+     * {@code
+     *     <?xml version="1.0"?>
+     *     <br>
+     *         <pruned_apps pkgs="com.example.app1,com.example.app2,com.example.app3" />
+     *         <provider_updates tag="0">
+     *             <record old_id="10" new_id="0" notified="false" />
+     *         </provider_updates>
+     *         <provider_updates tag="1">
+     *             <record old_id="9" new_id="1" notified="true" />
+     *         </provider_updates>
+     *         <provider_updates tag="2">
+     *             <record old_id="8" new_id="2" notified="false" />
+     *         </provider_updates>
+     *         <host_updates tag="0">
+     *             <record old_id="10" new_id="0" notified="false" />
+     *         </host_updates>
+     *         <host_updates tag="1">
+     *             <record old_id="9" new_id="1" notified="true" />
+     *         </host_updates>
+     *         <host_updates tag="2">
+     *             <record old_id="8" new_id="2" notified="false" />
+     *         </host_updates>
+     *     </br>
+     * }
+     * </pre>
+     *
+     * @param parser XML parser
+     * @return {@link AppWidgetServiceImpl.BackupRestoreController.State} of intermediate states
+     * in {@link AppWidgetServiceImpl.BackupRestoreController}, so that backup & restore can be
+     * resumed after reboot.
+     */
+    @Nullable
+    static AppWidgetServiceImpl.BackupRestoreController.State
+            readBackupRestoreControllerState(@NonNull final TypedXmlPullParser parser) {
+        Objects.requireNonNull(parser);
+        int type;
+        String tag = null;
+        final Set<String> prunedApps = new ArraySet<>(1);
+        final SparseArray<List<AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord>>
+                updatesByProviders = new SparseArray<>();
+        final SparseArray<List<AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord>>
+                updatesByHosts = new SparseArray<>();
+
+        try {
+            do {
+                type = parser.next();
+                if (type != XmlPullParser.START_TAG) {
+                    continue;
+                }
+                tag = parser.getName();
+                switch (tag) {
+                    case TAG_PRUNED_APPS:
+                        final String packages =
+                                parser.getAttributeValue(null, ATTR_PACKAGE_NAMES);
+                        prunedApps.addAll(Arrays.asList(packages.split(",")));
+                        break;
+                    case TAG_PROVIDER_UPDATES:
+                        updatesByProviders.put(parser.getAttributeInt(null, ATTR_TAG),
+                                parseRestoreUpdateRecords(parser));
+                        break;
+                    case TAG_HOST_UPDATES:
+                        updatesByHosts.put(parser.getAttributeInt(null, ATTR_TAG),
+                                parseRestoreUpdateRecords(parser));
+                        break;
+                    default:
+                        break;
+                }
+            } while (type != XmlPullParser.END_DOCUMENT
+                    && (!TAG_BACKUP_RESTORE_CONTROLLER_STATE.equals(tag)
+                            || type != XmlPullParser.END_TAG));
+        } catch (IOException | XmlPullParserException e) {
+            Log.e(TAG, "error parsing state", e);
+            return null;
+        }
+        return new AppWidgetServiceImpl.BackupRestoreController.State(
+                prunedApps, updatesByProviders, updatesByHosts);
+    }
+
+    @NonNull
+    private static List<
+            AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord
+            > parseRestoreUpdateRecords(@NonNull final TypedXmlPullParser parser)
+            throws XmlPullParserException, IOException {
+        int type;
+        String tag;
+        final List<AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord> ret =
+                new ArrayList<>();
+        do {
+            type = parser.next();
+            tag = parser.getName();
+            if (tag.equals(TAG_RECORD) && type == XmlPullParser.START_TAG) {
+                final int oldId = parser.getAttributeInt(null, ATTR_OLD_ID);
+                final int newId = parser.getAttributeInt(null, ATTR_NEW_ID);
+                final boolean notified = parser.getAttributeBoolean(
+                        null, ATTR_NOTIFIED);
+                final AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord record =
+                        new AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord(
+                                oldId, newId);
+                record.notified = notified;
+                ret.add(record);
+            }
+        } while (tag.equals(TAG_RECORD));
+        return ret;
+    }
 }
diff --git a/services/autofill/java/com/android/server/autofill/RequestId.java b/services/autofill/java/com/android/server/autofill/RequestId.java
index 29ad786..d8069a8 100644
--- a/services/autofill/java/com/android/server/autofill/RequestId.java
+++ b/services/autofill/java/com/android/server/autofill/RequestId.java
@@ -16,8 +16,14 @@
 
 package com.android.server.autofill;
 
-import java.util.List;
+import static com.android.server.autofill.Helper.sDebug;
+
+import android.util.Slog;
+import android.util.SparseArray;
+
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.List;
+import java.util.Random;
 
 // Helper class containing various methods to deal with FillRequest Ids.
 // For authentication flows, there needs to be a way to know whether to retrieve the Fill
@@ -25,56 +31,97 @@
 // way to achieve this is by assigning odd number request ids to secondary provider and
 // even numbers to primary provider.
 public class RequestId {
+    private AtomicInteger sIdCounter;
 
-  private AtomicInteger sIdCounter;
+    // The minimum request id is 2 to avoid possible authentication issues.
+    static final int MIN_REQUEST_ID = 2;
+    // The maximum request id is 0x7FFF to make sure the 16th bit is 0.
+    // This is to make sure the authentication id is always positive.
+    static final int MAX_REQUEST_ID = 0x7FFF; // 32767
 
-  // Mainly used for tests
-  RequestId(int start) {
-    sIdCounter = new AtomicInteger(start);
-  }
+    // The maximum start id is made small to best avoid wrapping around.
+    static final int MAX_START_ID = 1000;
+    // The magic number is used to determine if a wrap has happened.
+    // The underlying assumption of MAGIC_NUMBER is that there can't be as many as MAGIC_NUMBER
+    // of fill requests in one session. so there can't be as many as MAGIC_NUMBER of fill requests
+    // getting dropped.
+    static final int MAGIC_NUMBER = 5000;
 
-  public RequestId() {
-    this((int) (Math.floor(Math.random() * 0xFFFF)));
-  }
+    static final int MIN_PRIMARY_REQUEST_ID = 2;
+    static final int MAX_PRIMARY_REQUEST_ID = 0x7FFE; // 32766
 
-  public static int getLastRequestIdIndex(List<Integer> requestIds) {
-    int lastId = -1;
-    int indexOfBiggest = -1;
-    // Biggest number is usually the latest request, since IDs only increase
-    // The only exception is when the request ID wraps around back to 0
-      for (int i = requestIds.size() - 1; i >= 0; i--) {
-        if (requestIds.get(i) > lastId) {
-        lastId = requestIds.get(i);
-        indexOfBiggest = i;
-      }
-    }
+    static final int MIN_SECONDARY_REQUEST_ID = 3;
+    static final int MAX_SECONDARY_REQUEST_ID = 0x7FFF; // 32767
 
-    // 0xFFFE + 2 == 0x1 (for secondary)
-    // 0xFFFD + 2 == 0x0 (for primary)
-    // Wrap has occurred
-    if (lastId >= 0xFFFD) {
-      // Calculate the biggest size possible
-      // If list only has one kind of request ids - we need to multiple by 2
-      // (since they skip odd ints)
-      // Also subtract one from size because at least one integer exists pre-wrap
-      int calcSize = (requestIds.size()) * 2;
-      //Biggest possible id after wrapping
-      int biggestPossible = (lastId + calcSize) % 0xFFFF;
-      lastId = -1;
-      indexOfBiggest = -1;
-      for (int i = 0; i < requestIds.size(); i++) {
-        int currentId = requestIds.get(i);
-        if (currentId <= biggestPossible && currentId > lastId) {
-          lastId = currentId;
-          indexOfBiggest = i;
+    private static final String TAG = "RequestId";
+
+    // WARNING: This constructor should only be used for testing
+    RequestId(int startId) {
+        if (startId < MIN_REQUEST_ID || startId > MAX_REQUEST_ID) {
+            throw new IllegalArgumentException("startId must be between " + MIN_REQUEST_ID +
+                                                   " and " + MAX_REQUEST_ID);
         }
-      }
+        if (sDebug) {
+            Slog.d(TAG, "RequestId(int): startId= " + startId);
+        }
+        sIdCounter = new AtomicInteger(startId);
     }
 
-    return indexOfBiggest;
-  }
+    // WARNING: This get method should only be used for testing
+    int getRequestId() {
+        return sIdCounter.get();
+    }
 
-  public int nextId(boolean isSecondary) {
+    public RequestId() {
+        Random random = new Random();
+        int low = MIN_REQUEST_ID;
+        int high = MAX_START_ID + 1; // nextInt is exclusive on upper limit
+
+        // Generate a random start request id that >= MIN_REQUEST_ID and <= MAX_START_ID
+        int startId = random.nextInt(high - low) + low;
+        if (sDebug) {
+            Slog.d(TAG, "RequestId(): startId= " + startId);
+        }
+        sIdCounter = new AtomicInteger(startId);
+    }
+
+    // Given a list of request ids, find the index of the last request id.
+    // Note: Since the request id wraps around, the largest request id may not be
+    // the latest request id.
+    //
+    // @param requestIds List of request ids in ascending order with at least one element.
+    // @return Index of the last request id.
+    public static int getLastRequestIdIndex(List<Integer> requestIds) {
+        // If there is only one request id, return index as 0.
+        if (requestIds.size() == 1) {
+            return 0;
+        }
+
+        // We have to use a magical number to determine if a wrap has happened because
+        // the request id could be lost. The underlying assumption of MAGIC_NUMBER is that
+        // there can't be as many as MAGIC_NUMBER of fill requests in one session.
+        boolean wrapHasHappened = false;
+        int latestRequestIdIndex = -1;
+
+        for (int i = 0; i < requestIds.size() - 1; i++) {
+            if (requestIds.get(i+1) - requestIds.get(i) > MAGIC_NUMBER) {
+                wrapHasHappened = true;
+                latestRequestIdIndex = i;
+                break;
+            }
+        }
+
+        // If there was no wrap, the last request index is the last index.
+        if (!wrapHasHappened) {
+            latestRequestIdIndex = requestIds.size() - 1;
+        }
+        if (sDebug) {
+            Slog.d(TAG, "getLastRequestIdIndex(): latestRequestIdIndex = " + latestRequestIdIndex);
+        }
+        return latestRequestIdIndex;
+    }
+
+    public int nextId(boolean isSecondary) {
         // For authentication flows, there needs to be a way to know whether to retrieve the Fill
         // Response from the primary provider or the secondary provider from the requestId. A simple
         // way to achieve this is by assigning odd number request ids to secondary provider and
@@ -82,13 +129,20 @@
         int requestId;
 
         do {
-            requestId = sIdCounter.incrementAndGet() % 0xFFFF;
+            requestId = sIdCounter.incrementAndGet() % (MAX_REQUEST_ID + 1);
+            // Skip numbers smaller than MIN_REQUEST_ID to avoid possible authentication issue
+            if (requestId < MIN_REQUEST_ID) {
+                requestId = MIN_REQUEST_ID;
+            }
             sIdCounter.set(requestId);
         } while (isSecondaryProvider(requestId) != isSecondary);
+        if (sDebug) {
+            Slog.d(TAG, "nextId(): requestId = " + requestId);
+        }
         return requestId;
-  }
+    }
 
-  public static boolean isSecondaryProvider(int requestId) {
-      return requestId % 2 == 1;
-  }
+    public static boolean isSecondaryProvider(int requestId) {
+        return requestId % 2 == 1;
+    }
 }
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 494e956..c6ddc16 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -6902,17 +6902,18 @@
         return mPendingSaveUi != null && mPendingSaveUi.getState() == PendingUi.STATE_PENDING;
     }
 
+    // Return latest response index in mResponses SparseArray.
     @GuardedBy("mLock")
     private int getLastResponseIndexLocked() {
-        if (mResponses != null) {
-            List<Integer> requestIdList = new ArrayList<>();
-            final int responseCount = mResponses.size();
-            for (int i = 0; i < responseCount; i++) {
-                requestIdList.add(mResponses.keyAt(i));
-            }
-            return mRequestId.getLastRequestIdIndex(requestIdList);
+        if (mResponses == null  || mResponses.size() == 0) {
+          return -1;
         }
-        return -1;
+        List<Integer> requestIdList = new ArrayList<>();
+        final int responseCount = mResponses.size();
+        for (int i = 0; i < responseCount; i++) {
+            requestIdList.add(mResponses.keyAt(i));
+        }
+        return mRequestId.getLastRequestIdIndex(requestIdList);
     }
 
     private LogMaker newLogMaker(int category) {
diff --git a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
index 4860a27..8abbe56 100644
--- a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
+++ b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java
@@ -792,10 +792,11 @@
     }
 
     private String getVToUAllowlist(Context context, int userId) {
-        return Settings.Secure.getStringForUser(
+         String allowlist = Settings.Secure.getStringForUser(
                 context.getContentResolver(),
                 Settings.Secure.V_TO_U_RESTORE_ALLOWLIST,
                 userId);
+         return (allowlist == null) ? "" : allowlist;
     }
 
     private static long extractRadix(byte[] data, int offset, int maxChars, int radix)
diff --git a/services/companion/java/com/android/server/companion/association/AssociationRequestsProcessor.java b/services/companion/java/com/android/server/companion/association/AssociationRequestsProcessor.java
index 3fbd856..b3a2da4 100644
--- a/services/companion/java/com/android/server/companion/association/AssociationRequestsProcessor.java
+++ b/services/companion/java/com/android/server/companion/association/AssociationRequestsProcessor.java
@@ -19,7 +19,6 @@
 import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
 import static android.app.PendingIntent.FLAG_IMMUTABLE;
 import static android.app.PendingIntent.FLAG_ONE_SHOT;
-import static android.companion.CompanionDeviceManager.REASON_INTERNAL_ERROR;
 import static android.companion.CompanionDeviceManager.RESULT_INTERNAL_ERROR;
 import static android.content.ComponentName.createRelative;
 import static android.content.pm.PackageManager.FEATURE_WATCH;
@@ -183,7 +182,7 @@
             String errorMessage = "3p apps are not allowed to create associations on watch.";
             Slog.e(TAG, errorMessage);
             try {
-                callback.onFailure(errorMessage);
+                callback.onFailure(RESULT_INTERNAL_ERROR);
             } catch (RemoteException e) {
                 // ignored
             }
@@ -252,8 +251,9 @@
         } catch (SecurityException e) {
             // Since, at this point the caller is our own UI, we need to catch the exception on
             // forward it back to the application via the callback.
+            Slog.e(TAG, e.getMessage());
             try {
-                callback.onFailure(e.getMessage());
+                callback.onFailure(RESULT_INTERNAL_ERROR);
             } catch (RemoteException ignore) {
             }
             return;
@@ -378,7 +378,7 @@
             // Send the association back via the app's callback
             if (callback != null) {
                 try {
-                    callback.onFailure(REASON_INTERNAL_ERROR);
+                    callback.onFailure(RESULT_INTERNAL_ERROR);
                 } catch (RemoteException ignore) {
                 }
             }
diff --git a/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java b/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java
index ce4067c..ef39846 100644
--- a/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java
+++ b/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java
@@ -192,7 +192,8 @@
             for (UserInfo user : aliveUsers) {
                 int userId = user.getUserHandle().getIdentifier();
                 int appUid = queryUidFromPackageName(userId, packageName);
-                if (mVirtualDeviceManagerInternal.isAppRunningOnAnyVirtualDevice(appUid)) {
+                if (mVirtualDeviceManagerInternal != null
+                        && mVirtualDeviceManagerInternal.isAppRunningOnAnyVirtualDevice(appUid)) {
                     if (data == null) {
                         data = new InjectionSessionData();
                         data.appUid = appUid;
diff --git a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
index afeafa4..988a213 100644
--- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
+++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
@@ -87,15 +87,6 @@
         void onSecureWindowShown(int displayId, int uid);
     }
 
-    /**
-     * For communicating when activities are blocked from entering PIP on the display by this
-     * policy controller.
-     */
-    public interface PipBlockedCallback {
-        /** Called when an activity is blocked from entering PIP. */
-        void onEnteringPipBlocked(int uid);
-    }
-
     /** Interface to listen for interception of intents. */
     public interface IntentListenerCallback {
         /** Returns true when an intent should be intercepted */
@@ -136,7 +127,6 @@
     @GuardedBy("mGenericWindowPolicyControllerLock")
     private final ArraySet<Integer> mRunningUids = new ArraySet<>();
     @Nullable private final ActivityListener mActivityListener;
-    @Nullable private final PipBlockedCallback mPipBlockedCallback;
     @Nullable private final IntentListenerCallback mIntentListenerCallback;
     private final Handler mHandler = new Handler(Looper.getMainLooper());
     @NonNull
@@ -190,7 +180,6 @@
             @NonNull Set<ComponentName> crossTaskNavigationExemptions,
             @Nullable ComponentName permissionDialogComponent,
             @Nullable ActivityListener activityListener,
-            @Nullable PipBlockedCallback pipBlockedCallback,
             @Nullable ActivityBlockedCallback activityBlockedCallback,
             @Nullable SecureWindowCallback secureWindowCallback,
             @Nullable IntentListenerCallback intentListenerCallback,
@@ -208,7 +197,6 @@
         mActivityBlockedCallback = activityBlockedCallback;
         setInterestedWindowFlags(windowFlags, systemWindowFlags);
         mActivityListener = activityListener;
-        mPipBlockedCallback = pipBlockedCallback;
         mSecureWindowCallback = secureWindowCallback;
         mIntentListenerCallback = intentListenerCallback;
         mDisplayCategories = displayCategories;
@@ -346,6 +334,10 @@
         }
         final UserHandle activityUser =
                 UserHandle.getUserHandleForUid(activityInfo.applicationInfo.uid);
+        if (!activityUser.isSystem() && !mAllowedUsers.contains(activityUser)) {
+            logActivityLaunchBlocked("Activity launch disallowed from user " + activityUser);
+            return false;
+        }
         final ComponentName activityComponent = activityInfo.getComponentName();
         if (BLOCKED_APP_STREAMING_COMPONENT.equals(activityComponent) && activityUser.isSystem()) {
             // The error dialog alerting users that streaming is blocked is always allowed.
@@ -464,18 +456,6 @@
             return mShowTasksInHostDeviceRecents;
         }
     }
-
-    @Override
-    public boolean isEnteringPipAllowed(int uid) {
-        if (super.isEnteringPipAllowed(uid)) {
-            return true;
-        }
-        if (mPipBlockedCallback != null) {
-            mHandler.post(() -> mPipBlockedCallback.onEnteringPipBlocked(uid));
-        }
-        return false;
-    }
-
     @Override
     public @Nullable ComponentName getCustomHomeComponent() {
         return mCustomHomeComponent;
@@ -512,7 +492,6 @@
                     "virtual_devices.value_activity_blocked_count",
                     mAttributionSource.getUid());
         }
-
     }
 
     private static boolean isAllowedByPolicy(boolean allowedByDefault,
diff --git a/services/companion/java/com/android/server/companion/virtual/InputController.java b/services/companion/java/com/android/server/companion/virtual/InputController.java
index 70af49c..d091ce8 100644
--- a/services/companion/java/com/android/server/companion/virtual/InputController.java
+++ b/services/companion/java/com/android/server/companion/virtual/InputController.java
@@ -31,6 +31,7 @@
 import android.hardware.input.VirtualMouseButtonEvent;
 import android.hardware.input.VirtualMouseRelativeEvent;
 import android.hardware.input.VirtualMouseScrollEvent;
+import android.hardware.input.VirtualRotaryEncoderScrollEvent;
 import android.hardware.input.VirtualStylusButtonEvent;
 import android.hardware.input.VirtualStylusMotionEvent;
 import android.hardware.input.VirtualTouchEvent;
@@ -76,6 +77,7 @@
     static final String PHYS_TYPE_TOUCHSCREEN = "Touchscreen";
     static final String PHYS_TYPE_NAVIGATION_TOUCHPAD = "NavigationTouchpad";
     static final String PHYS_TYPE_STYLUS = "Stylus";
+    static final String PHYS_TYPE_ROTARY_ENCODER = "RotaryEncoder";
     @StringDef(prefix = { "PHYS_TYPE_" }, value = {
             PHYS_TYPE_DPAD,
             PHYS_TYPE_KEYBOARD,
@@ -83,6 +85,7 @@
             PHYS_TYPE_TOUCHSCREEN,
             PHYS_TYPE_NAVIGATION_TOUCHPAD,
             PHYS_TYPE_STYLUS,
+            PHYS_TYPE_ROTARY_ENCODER,
     })
     @Retention(RetentionPolicy.SOURCE)
     @interface PhysType {
@@ -206,6 +209,15 @@
                         height, width));
     }
 
+    void createRotaryEncoder(@NonNull String deviceName, int vendorId, int productId,
+            @NonNull IBinder deviceToken, int displayId) throws DeviceCreationException {
+        final String phys = createPhys(PHYS_TYPE_ROTARY_ENCODER);
+        createDeviceInternal(InputDeviceDescriptor.TYPE_ROTARY_ENCODER, deviceName, vendorId,
+                productId, deviceToken, displayId, phys,
+                () -> mNativeWrapper.openUinputRotaryEncoder(deviceName, vendorId, productId,
+                        phys));
+    }
+
     void unregisterInputDevice(@NonNull IBinder token) {
         synchronized (mLock) {
             final InputDeviceDescriptor inputDeviceDescriptor = mInputDeviceDescriptors.remove(
@@ -403,6 +415,20 @@
         }
     }
 
+    boolean sendRotaryEncoderScrollEvent(@NonNull IBinder token,
+            @NonNull VirtualRotaryEncoderScrollEvent event) {
+        synchronized (mLock) {
+            final InputDeviceDescriptor inputDeviceDescriptor = mInputDeviceDescriptors.get(
+                    token);
+            if (inputDeviceDescriptor == null) {
+                return false;
+            }
+            return mNativeWrapper.writeRotaryEncoderScrollEvent(
+                    inputDeviceDescriptor.getNativePointer(), event.getScrollAmount(),
+                    event.getEventTimeNanos());
+        }
+    }
+
     public void dump(@NonNull PrintWriter fout) {
         fout.println("    InputController: ");
         synchronized (mLock) {
@@ -449,6 +475,9 @@
             int productId, String phys, int height, int width);
     private static native long nativeOpenUinputStylus(String deviceName, int vendorId,
             int productId, String phys, int height, int width);
+    private static native long nativeOpenUinputRotaryEncoder(String deviceName, int vendorId,
+            int productId, String phys);
+
     private static native void nativeCloseUinput(long ptr);
     private static native boolean nativeWriteDpadKeyEvent(long ptr, int androidKeyCode, int action,
             long eventTimeNanos);
@@ -467,6 +496,8 @@
             int locationX, int locationY, int pressure, int tiltX, int tiltY, long eventTimeNanos);
     private static native boolean nativeWriteStylusButtonEvent(long ptr, int buttonCode, int action,
             long eventTimeNanos);
+    private static native boolean nativeWriteRotaryEncoderScrollEvent(long ptr, float scrollAmount,
+            long eventTimeNanos);
 
     /** Wrapper around the static native methods for tests. */
     @VisibleForTesting
@@ -495,6 +526,11 @@
             return nativeOpenUinputStylus(deviceName, vendorId, productId, phys, height, width);
         }
 
+        public long openUinputRotaryEncoder(String deviceName, int vendorId, int productId,
+                String phys) {
+            return nativeOpenUinputRotaryEncoder(deviceName, vendorId, productId, phys);
+        }
+
         public void closeUinput(long ptr) {
             nativeCloseUinput(ptr);
         }
@@ -542,6 +578,11 @@
                 long eventTimeNanos) {
             return nativeWriteStylusButtonEvent(ptr, buttonCode, action, eventTimeNanos);
         }
+
+        public boolean writeRotaryEncoderScrollEvent(long ptr, float scrollAmount,
+                long eventTimeNanos) {
+            return nativeWriteRotaryEncoderScrollEvent(ptr, scrollAmount, eventTimeNanos);
+        }
     }
 
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
@@ -553,6 +594,7 @@
         static final int TYPE_DPAD = 4;
         static final int TYPE_NAVIGATION_TOUCHPAD = 5;
         static final int TYPE_STYLUS = 6;
+        static final int TYPE_ROTARY_ENCODER = 7;
         @IntDef(prefix = { "TYPE_" }, value = {
                 TYPE_KEYBOARD,
                 TYPE_MOUSE,
@@ -560,6 +602,7 @@
                 TYPE_DPAD,
                 TYPE_NAVIGATION_TOUCHPAD,
                 TYPE_STYLUS,
+                TYPE_ROTARY_ENCODER,
         })
         @Retention(RetentionPolicy.SOURCE)
         @interface Type {
@@ -821,6 +864,8 @@
                 return "virtual_devices.value_virtual_navigationtouchpad_created_count";
             case InputDeviceDescriptor.TYPE_STYLUS:
                 return "virtual_devices.value_virtual_stylus_created_count";
+            case InputDeviceDescriptor.TYPE_ROTARY_ENCODER:
+                return "virtual_devices.value_virtual_rotary_created_count";
             default:
                 Log.e(TAG, "No metric known for input type: " + type);
                 return null;
diff --git a/services/companion/java/com/android/server/companion/virtual/SensorController.java b/services/companion/java/com/android/server/companion/virtual/SensorController.java
index cf48180..0655685 100644
--- a/services/companion/java/com/android/server/companion/virtual/SensorController.java
+++ b/services/companion/java/com/android/server/companion/virtual/SensorController.java
@@ -229,6 +229,10 @@
                 Slog.e(TAG, "No sensor callback configured for sensor handle " + handle);
                 return BAD_VALUE;
             }
+            if (mVdmInternal == null) {
+                Slog.e(TAG, "Virtual Device Manager is not enabled.");
+                return BAD_VALUE;
+            }
             VirtualSensor sensor = mVdmInternal.getVirtualSensor(mVirtualDeviceId, handle);
             if (sensor == null) {
                 Slog.e(TAG, "No sensor found for deviceId=" + mVirtualDeviceId
@@ -285,6 +289,10 @@
                 Slog.e(TAG, "No runtime sensor callback configured.");
                 return BAD_VALUE;
             }
+            if (mVdmInternal == null) {
+                Slog.e(TAG, "Virtual Device Manager is not enabled.");
+                return BAD_VALUE;
+            }
             VirtualSensor sensor = mVdmInternal.getVirtualSensor(mVirtualDeviceId, sensorHandle);
             if (sensor == null) {
                 Slog.e(TAG, "No sensor found for deviceId=" + mVirtualDeviceId
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index 6704049..7d9d660 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -24,6 +24,7 @@
 import static android.companion.virtual.VirtualDeviceParams.NAVIGATION_POLICY_DEFAULT_ALLOWED;
 import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_ACTIVITY;
 import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_AUDIO;
+import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_BLOCKED_ACTIVITY_BEHAVIOR;
 import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CAMERA;
 import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CLIPBOARD;
 import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_RECENTS;
@@ -77,6 +78,8 @@
 import android.hardware.input.VirtualMouseRelativeEvent;
 import android.hardware.input.VirtualMouseScrollEvent;
 import android.hardware.input.VirtualNavigationTouchpadConfig;
+import android.hardware.input.VirtualRotaryEncoderConfig;
+import android.hardware.input.VirtualRotaryEncoderScrollEvent;
 import android.hardware.input.VirtualStylusButtonEvent;
 import android.hardware.input.VirtualStylusConfig;
 import android.hardware.input.VirtualStylusMotionEvent;
@@ -183,8 +186,9 @@
     private final SparseIntArray mDevicePolicies;
     @GuardedBy("mVirtualDeviceLock")
     private final SparseArray<VirtualDisplayWrapper> mVirtualDisplays = new SparseArray<>();
-    private final IVirtualDeviceActivityListener mActivityListener;
-    private final IVirtualDeviceSoundEffectListener mSoundEffectListener;
+    private IVirtualDeviceActivityListener mActivityListener;
+    private ActivityListener mActivityListenerAdapter = null;
+    private IVirtualDeviceSoundEffectListener mSoundEffectListener;
     private final DisplayManagerGlobal mDisplayManager;
     private final DisplayManagerInternal mDisplayManagerInternal;
     @GuardedBy("mVirtualDeviceLock")
@@ -237,6 +241,16 @@
                     Slog.w(TAG, "Unable to call mActivityListener for display: " + displayId, e);
                 }
             }
+
+            @Override
+            public void onActivityLaunchBlocked(int displayId,
+                    @NonNull ComponentName componentName, @UserIdInt int userId) {
+                try {
+                    mActivityListener.onActivityLaunchBlocked(displayId, componentName, userId);
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Unable to call mActivityListener for display: " + displayId, e);
+                }
+            }
         };
     }
 
@@ -301,7 +315,9 @@
         UserHandle ownerUserHandle = UserHandle.getUserHandleForUid(attributionSource.getUid());
         mContext = context.createContextAsUser(ownerUserHandle, 0);
         mAssociationInfo = associationInfo;
-        mPersistentDeviceId = createPersistentDeviceId(associationInfo.getId());
+        mPersistentDeviceId = associationInfo == null
+                ? null
+                : createPersistentDeviceId(associationInfo.getId());
         mService = service;
         mPendingTrampolineCallback = pendingTrampolineCallback;
         mActivityListener = activityListener;
@@ -403,7 +419,7 @@
 
     /** Returns the device display name. */
     CharSequence getDisplayName() {
-        return mAssociationInfo.getDisplayName();
+        return mAssociationInfo == null ? mParams.getName() : mAssociationInfo.getDisplayName();
     }
 
     /** Returns the public representation of the device. */
@@ -418,6 +434,22 @@
         }
     }
 
+    /**
+     * Setter for listeners that live in the client process, namely in
+     * {@link android.companion.virtual.VirtualDeviceInternal}.
+     *
+     * This is needed for virtual devices that are created by the system, as the VirtualDeviceImpl
+     * object is created before the returned VirtualDeviceInternal one.
+     */
+    @Override // Binder call
+    @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    public void setListeners(@NonNull IVirtualDeviceActivityListener activityListener,
+            @NonNull IVirtualDeviceSoundEffectListener soundEffectListener) {
+        super.setListeners_enforcePermission();
+        mActivityListener = Objects.requireNonNull(activityListener);
+        mSoundEffectListener = Objects.requireNonNull(soundEffectListener);
+    }
+
     @Override  // Binder call
     public @VirtualDeviceParams.DevicePolicy int getDevicePolicy(
             @VirtualDeviceParams.PolicyType int policyType) {
@@ -454,7 +486,9 @@
 
     @Override // Binder call
     public int getAssociationId() {
-        return mAssociationInfo.getId();
+        return mAssociationInfo == null
+                ? VirtualDeviceManagerService.CDM_ASSOCIATION_ID_NONE
+                : mAssociationInfo.getId();
     }
 
     @Override // Binder call
@@ -687,6 +721,13 @@
                     }
                 }
                 break;
+            case POLICY_TYPE_BLOCKED_ACTIVITY_BEHAVIOR:
+                if (android.companion.virtualdevice.flags.Flags.activityControlApi()) {
+                    synchronized (mVirtualDeviceLock) {
+                        mDevicePolicies.put(policyType, devicePolicy);
+                    }
+                }
+                break;
             default:
                 throw new IllegalArgumentException("Device policy " + policyType
                         + " cannot be changed at runtime. ");
@@ -812,6 +853,26 @@
 
     @Override // Binder call
     @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    public void createVirtualRotaryEncoder(@NonNull VirtualRotaryEncoderConfig config,
+            @NonNull IBinder deviceToken) {
+        super.createVirtualRotaryEncoder_enforcePermission();
+        Objects.requireNonNull(config);
+        Objects.requireNonNull(deviceToken);
+        checkVirtualInputDeviceDisplayIdAssociation(config.getAssociatedDisplayId());
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            mInputController.createRotaryEncoder(config.getInputDeviceName(), config.getVendorId(),
+                    config.getProductId(), deviceToken,
+                    getTargetDisplayIdForInput(config.getAssociatedDisplayId()));
+        } catch (InputController.DeviceCreationException e) {
+            throw new IllegalArgumentException(e);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    @Override // Binder call
+    @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
     public void unregisterInputDevice(IBinder token) {
         super.unregisterInputDevice_enforcePermission();
         final long ident = Binder.clearCallingIdentity();
@@ -947,6 +1008,19 @@
 
     @Override // Binder call
     @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
+    public boolean sendRotaryEncoderScrollEvent(@NonNull IBinder token,
+            @NonNull VirtualRotaryEncoderScrollEvent event) {
+        super.sendRotaryEncoderScrollEvent_enforcePermission();
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            return mInputController.sendRotaryEncoderScrollEvent(token, event);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    @Override // Binder call
+    @EnforcePermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
     public void setShowPointerIcon(boolean showPointerIcon) {
         super.setShowPointerIcon_enforcePermission();
         final long ident = Binder.clearCallingIdentity();
@@ -1105,7 +1179,7 @@
         String indent = "    ";
         fout.println("  VirtualDevice: ");
         fout.println(indent + "mDeviceId: " + mDeviceId);
-        fout.println(indent + "mAssociationId: " + mAssociationInfo.getId());
+        fout.println(indent + "mAssociationId: " + getAssociationId());
         fout.println(indent + "mOwnerPackageName: " + mOwnerPackageName);
         fout.println(indent + "mParams: ");
         mParams.dump(fout, indent + indent);
@@ -1154,6 +1228,10 @@
         final ComponentName homeComponent =
                 Flags.vdmCustomHome() ? mParams.getHomeComponent() : null;
 
+        if (mActivityListenerAdapter == null) {
+            mActivityListenerAdapter = createListenerAdapter();
+        }
+
         final GenericWindowPolicyController gwpc = new GenericWindowPolicyController(
                 WindowManager.LayoutParams.FLAG_SECURE,
                 WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
@@ -1166,8 +1244,7 @@
                         ? mParams.getBlockedCrossTaskNavigations()
                         : mParams.getAllowedCrossTaskNavigations(),
                 mPermissionDialogComponent,
-                createListenerAdapter(),
-                this::onEnteringPipBlocked,
+                mActivityListenerAdapter,
                 this::onActivityBlocked,
                 this::onSecureWindowShown,
                 this::shouldInterceptIntent,
@@ -1251,12 +1328,37 @@
 
     @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
     private void onActivityBlocked(int displayId, ActivityInfo activityInfo) {
-        Intent intent = BlockedAppStreamingActivity.createIntent(
-                activityInfo, mAssociationInfo.getDisplayName());
-        mContext.startActivityAsUser(
-                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK),
-                ActivityOptions.makeBasic().setLaunchDisplayId(displayId).toBundle(),
-                UserHandle.SYSTEM);
+        Intent intent = BlockedAppStreamingActivity.createIntent(activityInfo, getDisplayName());
+        if (shouldShowBlockedActivityDialog(
+                activityInfo.getComponentName(), intent.getComponent())) {
+            mContext.startActivityAsUser(
+                    intent.addFlags(
+                            Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK),
+                    ActivityOptions.makeBasic().setLaunchDisplayId(displayId).toBundle(),
+                    UserHandle.SYSTEM);
+        }
+
+        if (android.companion.virtualdevice.flags.Flags.activityControlApi()) {
+            mActivityListenerAdapter.onActivityLaunchBlocked(
+                    displayId,
+                    activityInfo.getComponentName(),
+                    UserHandle.getUserHandleForUid(
+                            activityInfo.applicationInfo.uid).getIdentifier());
+        }
+    }
+
+    private boolean shouldShowBlockedActivityDialog(ComponentName blockedComponent,
+            ComponentName blockedAppStreamingActivityComponent) {
+        if (Objects.equals(blockedComponent, blockedAppStreamingActivityComponent)) {
+            // Do not show the dialog if it was blocked for some reason already to avoid
+            // infinite blocking loop.
+            return false;
+        }
+        if (!android.companion.virtualdevice.flags.Flags.activityControlApi()) {
+            return true;
+        }
+        // Do not show the dialog if disabled by policy.
+        return getDevicePolicy(POLICY_TYPE_BLOCKED_ACTIVITY_BEHAVIOR) == DEVICE_POLICY_DEFAULT;
     }
 
     private void onSecureWindowShown(int displayId, int uid) {
@@ -1339,7 +1441,7 @@
 
     @SuppressWarnings("AndroidFrameworkRequiresPermission")
     private void checkVirtualInputDeviceDisplayIdAssociation(int displayId) {
-        if (mContext.checkCallingPermission(android.Manifest.permission.INJECT_EVENTS)
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.INJECT_EVENTS)
                     == PackageManager.PERMISSION_GRANTED) {
             // The INJECT_EVENTS permission allows for injecting input to any window / display.
             return;
@@ -1456,12 +1558,6 @@
         return mInputController.getInputDeviceDescriptors().values().stream().anyMatch(
                 inputDeviceDescriptor -> inputDeviceDescriptor.getInputDeviceId() == inputDeviceId);
     }
-
-    void onEnteringPipBlocked(int uid) {
-        // Do nothing. ActivityRecord#checkEnterPictureInPictureState logs that the display does not
-        // support PiP.
-    }
-
     void playSoundEffect(int effectType) {
         try {
             mSoundEffectListener.onPlaySoundEffect(effectType);
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceLog.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceLog.java
index c65aa5b..b0bacfd 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceLog.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceLog.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Binder;
+import android.os.Process;
 import android.util.SparseArray;
 
 import java.io.PrintWriter;
@@ -35,6 +36,8 @@
             "MM-dd HH:mm:ss.SSS").withZone(ZoneId.systemDefault());
     private static final int MAX_ENTRIES = 16;
 
+    private static final String VIRTUAL_DEVICE_OWNER_SYSTEM = "system";
+
     private final Context mContext;
     private final ArrayDeque<LogEntry> mLogEntries = new ArrayDeque<>();
 
@@ -132,6 +135,8 @@
             String[] packages;
             if (mUidToPackagesCache.contains(ownerUid)) {
                 return mUidToPackagesCache.get(ownerUid);
+            } else if (ownerUid == Process.SYSTEM_UID) {
+                return VIRTUAL_DEVICE_OWNER_SYSTEM;
             } else {
                 packages = mPackageManager.getPackagesForUid(ownerUid);
                 String packageName = "";
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
index 9ad73ca..1be1d2b 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
@@ -101,6 +101,11 @@
             AssociationRequest.DEVICE_PROFILE_APP_STREAMING,
             AssociationRequest.DEVICE_PROFILE_NEARBY_DEVICE_STREAMING);
 
+    /**
+     * A virtual device association id corresponding to no CDM association.
+     */
+    static final int CDM_ASSOCIATION_ID_NONE = 0;
+
     private final Object mVirtualDeviceManagerLock = new Object();
     private final VirtualDeviceManagerImpl mImpl;
     private final VirtualDeviceManagerNativeImpl mNativeImpl;
@@ -316,7 +321,9 @@
 
             for (int i = 0; i < mVirtualDevices.size(); i++) {
                 VirtualDeviceImpl virtualDevice = mVirtualDevices.valueAt(i);
-                if (!activeAssociationIds.contains(virtualDevice.getAssociationId())) {
+                int deviceAssociationId = virtualDevice.getAssociationId();
+                if (deviceAssociationId != CDM_ASSOCIATION_ID_NONE
+                        && !activeAssociationIds.contains(deviceAssociationId)) {
                     virtualDevicesToRemove.add(virtualDevice);
                 }
             }
@@ -422,28 +429,39 @@
                 @NonNull IVirtualDeviceActivityListener activityListener,
                 @NonNull IVirtualDeviceSoundEffectListener soundEffectListener) {
             createVirtualDevice_enforcePermission();
-            attributionSource.enforceCallingUid();
-
-            final int callingUid = getCallingUid();
+            Objects.requireNonNull(activityListener);
+            Objects.requireNonNull(soundEffectListener);
             final String packageName = attributionSource.getPackageName();
-            if (!PermissionUtils.validateCallingPackageName(getContext(), packageName)) {
-                throw new SecurityException(
-                        "Package name " + packageName + " does not belong to calling uid "
-                                + callingUid);
-            }
             AssociationInfo associationInfo = getAssociationInfo(packageName, associationId);
             if (associationInfo == null) {
                 throw new IllegalArgumentException("No association with ID " + associationId);
-            }
-            if (!VIRTUAL_DEVICE_COMPANION_DEVICE_PROFILES
+            } else if (!VIRTUAL_DEVICE_COMPANION_DEVICE_PROFILES
                     .contains(associationInfo.getDeviceProfile())
                     && Flags.persistentDeviceIdApi()) {
                 throw new IllegalArgumentException("Unsupported CDM Association device profile "
                         + associationInfo.getDeviceProfile() + " for virtual device creation.");
             }
+            return createVirtualDevice(token, attributionSource, associationInfo, params,
+                    activityListener, soundEffectListener);
+        }
+
+        private IVirtualDevice createVirtualDevice(
+                IBinder token,
+                AttributionSource attributionSource,
+                AssociationInfo associationInfo,
+                @NonNull VirtualDeviceParams params,
+                @Nullable IVirtualDeviceActivityListener activityListener,
+                @Nullable IVirtualDeviceSoundEffectListener soundEffectListener) {
+            createVirtualDevice_enforcePermission();
+            attributionSource.enforceCallingUid();
+
+            final String packageName = attributionSource.getPackageName();
+            if (!PermissionUtils.validateCallingPackageName(getContext(), packageName)) {
+                throw new SecurityException(
+                        "Package name " + packageName + " does not belong to calling uid "
+                                + getCallingUid());
+            }
             Objects.requireNonNull(params);
-            Objects.requireNonNull(activityListener);
-            Objects.requireNonNull(soundEffectListener);
 
             final UserHandle userHandle = getCallingUserHandle();
             final CameraAccessController cameraAccessController =
@@ -724,6 +742,21 @@
         private final ArraySet<Integer> mAllUidsOnVirtualDevice = new ArraySet<>();
 
         @Override
+        public @NonNull VirtualDeviceManager.VirtualDevice createVirtualDevice(
+                @NonNull VirtualDeviceParams params) {
+            Objects.requireNonNull(params, "params must not be null");
+            Objects.requireNonNull(params.getName(), "virtual device name must not be null");
+            IVirtualDevice virtualDevice = mImpl.createVirtualDevice(
+                    new Binder(),
+                    getContext().getAttributionSource(),
+                    /* associationInfo= */ null,
+                    params,
+                    /* activityListener= */ null,
+                    /* soundEffectListener= */ null);
+            return new VirtualDeviceManager.VirtualDevice(mImpl, getContext(), virtualDevice);
+        }
+
+        @Override
         public int getDeviceOwnerUid(int deviceId) {
             VirtualDeviceImpl virtualDevice;
             synchronized (mVirtualDeviceManagerLock) {
diff --git a/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
index b64aa8a..ea6351b 100644
--- a/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
+++ b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
@@ -364,7 +364,7 @@
     }
 
     @RequiresPermission(android.Manifest.permission.START_TASKS_FROM_RECENTS)
-    private int invokeContextualSearchIntent(Intent launchIntent) {
+    private int invokeContextualSearchIntent(Intent launchIntent, final int userId) {
         // Contextual search starts with a frozen screen - so we launch without
         // any system animations or starting window.
         final ActivityOptions opts = ActivityOptions.makeCustomTaskAnimation(mContext,
@@ -372,7 +372,7 @@
         opts.setDisableStartingWindow(true);
         return mAtmInternal.startActivityWithScreenshot(launchIntent,
                 mContext.getPackageName(), Binder.getCallingUid(), Binder.getCallingPid(), null,
-                opts.toBundle(), Binder.getCallingUserHandle().getIdentifier());
+                opts.toBundle(), userId);
     }
 
     private void enforcePermission(@NonNull final String func) {
@@ -446,6 +446,8 @@
             synchronized (this) {
                 if (DEBUG_USER) Log.d(TAG, "startContextualSearch");
                 enforcePermission("startContextualSearch");
+                final int callingUserId = Binder.getCallingUserHandle().getIdentifier();
+
                 mAssistDataRequester.cancel();
                 // Creates a new CallbackToken at mToken and an expiration handler.
                 issueToken();
@@ -455,7 +457,7 @@
                 Binder.withCleanCallingIdentity(() -> {
                     Intent launchIntent = getContextualSearchIntent(entrypoint, mToken);
                     if (launchIntent != null) {
-                        int result = invokeContextualSearchIntent(launchIntent);
+                        int result = invokeContextualSearchIntent(launchIntent, callingUserId);
                         if (DEBUG_USER) Log.d(TAG, "Launch result: " + result);
                     }
                 });
diff --git a/services/core/Android.bp b/services/core/Android.bp
index d9962c7..1cd20ed 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -47,7 +47,7 @@
     ],
     tools: ["protologtool"],
     cmd: "$(location protologtool) transform-protolog-calls " +
-        "--protolog-class com.android.internal.protolog.common.ProtoLog " +
+        "--protolog-class com.android.internal.protolog.ProtoLog " +
         "--loggroups-class com.android.internal.protolog.ProtoLogGroup " +
         "--loggroups-jar $(location :protolog-groups) " +
         "--viewer-config-file-path /etc/core.protolog.pb " +
@@ -66,7 +66,7 @@
     ],
     tools: ["protologtool"],
     cmd: "$(location protologtool) generate-viewer-config " +
-        "--protolog-class com.android.internal.protolog.common.ProtoLog " +
+        "--protolog-class com.android.internal.protolog.ProtoLog " +
         "--loggroups-class com.android.internal.protolog.ProtoLogGroup " +
         "--loggroups-jar $(location :protolog-groups) " +
         "--viewer-config-type json " +
@@ -83,7 +83,7 @@
     ],
     tools: ["protologtool"],
     cmd: "$(location protologtool) generate-viewer-config " +
-        "--protolog-class com.android.internal.protolog.common.ProtoLog " +
+        "--protolog-class com.android.internal.protolog.ProtoLog " +
         "--loggroups-class com.android.internal.protolog.ProtoLogGroup " +
         "--loggroups-jar $(location :protolog-groups) " +
         "--viewer-config-type proto " +
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 256f2b3..361b818 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -63,7 +63,7 @@
 # NotificationManagerService.java
 # ---------------------------
 # when a NotificationManager.notify is called. status: 0=post, 1=update, 2=ignored
-2750 notification_enqueue (uid|1|5),(pid|1|5),(pkg|3),(id|1|5),(tag|3),(userid|1|5),(notification|3),(status|1)
+2750 notification_enqueue (uid|1|5),(pid|1|5),(pkg|3),(id|1|5),(tag|3),(userid|1|5),(notification|3),(status|1),(app_provided|1)
 # when someone tries to cancel a notification, the notification manager sometimes
 # calls this with flags too
 2751 notification_cancel (uid|1|5),(pid|1|5),(pkg|3),(id|1|5),(tag|3),(userid|1|5),(required_flags|1),(forbidden_flags|1),(reason|1|5),(listener|3)
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index b35959f..19279a8 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -104,6 +104,7 @@
 import android.os.ServiceSpecificException;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.DiskInfo;
@@ -1180,6 +1181,7 @@
 
     private void onUserUnlocking(int userId) {
         Slog.d(TAG, "onUserUnlocking " + userId);
+        Trace.instant(Trace.TRACE_TAG_SYSTEM_SERVER, "SMS.onUserUnlocking: " + userId);
 
         if (userId != UserHandle.USER_SYSTEM) {
             // Check if this user shares media with another user
@@ -1466,6 +1468,8 @@
         @Override
         public void onVolumeCreated(String volId, int type, String diskId, String partGuid,
                 int userId) {
+            Trace.instant(Trace.TRACE_TAG_SYSTEM_SERVER,
+                    "SMS.onVolumeCreated: " + volId + ", " + userId);
             synchronized (mLock) {
                 final DiskInfo disk = mDisks.get(diskId);
                 final VolumeInfo vol = new VolumeInfo(volId, type, disk, partGuid);
@@ -2352,6 +2356,7 @@
 
     private void mount(VolumeInfo vol) {
         try {
+            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "SMS.mount: " + vol.id);
             // TODO(b/135341433): Remove cautious logging when FUSE is stable
             Slog.i(TAG, "Mounting volume " + vol);
             extendWatchdogTimeout("#mount might be slow");
@@ -2363,6 +2368,8 @@
                     vol.internalPath = internalPath;
                     ParcelFileDescriptor pfd = new ParcelFileDescriptor(fd);
                     try {
+                        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER,
+                                "SMS.startFuseFileSystem: " + vol.id);
                         mStorageSessionController.onVolumeMount(pfd, vol);
                         return true;
                     } catch (ExternalStorageServiceException e) {
@@ -2375,6 +2382,7 @@
                                 TimeUnit.SECONDS.toMillis(nextResetSeconds));
                         return false;
                     } finally {
+                        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
                         try {
                             pfd.close();
                         } catch (Exception e) {
@@ -2386,6 +2394,8 @@
             Slog.i(TAG, "Mounted volume " + vol);
         } catch (Exception e) {
             Slog.wtf(TAG, e);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
         }
     }
 
diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java
index 44aea15..e2ab0d9 100644
--- a/services/core/java/com/android/server/SystemConfig.java
+++ b/services/core/java/com/android/server/SystemConfig.java
@@ -1603,7 +1603,7 @@
                         } else {
                             mPackageToSharedUidAllowList.put(pkgName, sharedUid);
                         }
-                    }
+                    } break;
                     case "asl-file": {
                         String packageName = parser.getAttributeValue(null, "package");
                         String path = parser.getAttributeValue(null, "path");
diff --git a/services/core/java/com/android/server/SystemServerInitThreadPool.java b/services/core/java/com/android/server/SystemServerInitThreadPool.java
index 3d3535d..73d8384 100644
--- a/services/core/java/com/android/server/SystemServerInitThreadPool.java
+++ b/services/core/java/com/android/server/SystemServerInitThreadPool.java
@@ -197,8 +197,8 @@
                 /* processCpuTracker= */null, /* lastPids= */null,
                 CompletableFuture.completedFuture(Watchdog.getInterestingNativePids()),
                 /* logExceptionCreatingFile= */null, /* subject= */null,
-                /* criticalEventSection= */null, Runnable::run,
-                /* latencyTracker= */null);
+                /* criticalEventSection= */null, /* extraHeaders= */ null,
+                Runnable::run, /* latencyTracker= */null);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index bc83a0e..3633d0f 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -921,8 +921,7 @@
 
     //helper function to determine if limit on num listeners applies to callingUid
     private boolean doesLimitApplyForListeners(int callingUid, int exemptUid) {
-        return (callingUid != Process.SYSTEM_UID
-                && callingUid != Process.PHONE_UID
+        return (!TelephonyPermissions.isSystemOrPhone(callingUid)
                 && callingUid != exemptUid);
     }
 
@@ -2990,7 +2989,7 @@
         // Always redact location info from PhysicalChannelConfig if the registrant is from neither
         // PHONE nor SYSTEM process. There is no user case that the registrant needs the location
         // info (e.g. physicalCellId). This also remove the need for the location permissions check.
-        return record.callerUid != Process.PHONE_UID && record.callerUid != Process.SYSTEM_UID;
+        return !TelephonyPermissions.isSystemOrPhone(record.callerUid);
     }
 
     /**
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 72a55dbe..21947ba 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -74,6 +74,7 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Optional;
 import java.util.UUID;
@@ -991,6 +992,9 @@
             FrameworkStatsLog.write(FrameworkStatsLog.SYSTEM_SERVER_WATCHDOG_OCCURRED, subject);
         }
 
+        final LinkedHashMap headersMap =
+                com.android.server.am.Flags.enableDropboxWatchdogHeaders()
+                ? new LinkedHashMap<>(Collections.singletonMap("Watchdog-Type", dropboxTag)) : null;
         long anrTime = SystemClock.uptimeMillis();
         StringBuilder report = new StringBuilder();
         report.append(ResourcePressureUtil.currentPsiState());
@@ -998,8 +1002,9 @@
         StringWriter tracesFileException = new StringWriter();
         final File stack = StackTracesDumpHelper.dumpStackTraces(
                 pids, processCpuTracker, new SparseBooleanArray(),
-                CompletableFuture.completedFuture(getInterestingNativePids()), tracesFileException,
-                subject, criticalEvents, Runnable::run, /* latencyTracker= */null);
+                CompletableFuture.completedFuture(getInterestingNativePids()),
+                tracesFileException, subject, criticalEvents, headersMap,
+                Runnable::run, /* latencyTracker= */null);
         // Give some extra time to make sure the stack traces get written.
         // The system's been hanging for a whlie, another second or two won't hurt much.
         SystemClock.sleep(5000);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 6bd7445..0fa5260 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -127,6 +127,7 @@
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE_EXECUTING;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.am.ProcessList.UNKNOWN_ADJ;
 
 import android.Manifest;
 import android.annotation.IntDef;
@@ -4304,7 +4305,7 @@
                 // queued up in the app side as they're one way calls. And we'll also hold off
                 // the service timeout timer until the process is unfrozen.
                 mAm.mOomAdjuster.updateAppFreezeStateLSP(callerApp, OOM_ADJ_REASON_BIND_SERVICE,
-                        true);
+                        true, UNKNOWN_ADJ);
             }
 
             final boolean wasStopped = hostApp == null ? wasStopped(s) : false;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index affe298..614a097 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -429,7 +429,7 @@
 import com.android.internal.os.Zygote;
 import com.android.internal.pm.pkg.parsing.ParsingPackageUtils;
 import com.android.internal.policy.AttributeCache;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.FrameworkStatsLog;
@@ -730,7 +730,7 @@
     /** Whether some specified important processes are allowed to use FIFO priority. */
     boolean mAllowSpecifiedFifoScheduling = true;
 
-    @GuardedBy("this")
+    @GuardedBy("mStrictModeCallbacks")
     private final SparseArray<IUnsafeIntentStrictModeCallback>
             mStrictModeCallbacks = new SparseArray<>();
 
@@ -5481,8 +5481,13 @@
     private boolean isHomeLaunchDelayable() {
         // This feature is disabled on Auto since it seems to add an unacceptably long boot delay
         // without even solving the underlying issue (it merely hits the timeout).
-        return enableHomeDelay() &&
-                !mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+        // This feature is disabled on TV since the ThemeOverlayController is currently not present
+        // and therefore we do not want to wait unnecessarily.
+        // This feature is currently disabled in WearOS to avoid extreme boot regressions
+        return enableHomeDelay()
+                && !mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
+                && !mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)
+                && !mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
     }
 
     final void ensureBootCompleted() {
@@ -5550,9 +5555,7 @@
             for (int i=0; i<intents.length; i++) {
                 Intent intent = intents[i];
                 if (intent != null) {
-                    if (intent.hasFileDescriptors()) {
-                        throw new IllegalArgumentException("File descriptors passed in Intent");
-                    }
+                    intent.prepareToEnterSystemServer();
                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
                         throw new IllegalArgumentException(
@@ -5585,7 +5588,6 @@
                         }
                     }
                     intents[i] = new Intent(intent);
-                    intents[i].removeExtendedFlags(Intent.EXTENDED_FLAG_FILTER_MISMATCH);
                 }
             }
             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
@@ -9538,18 +9540,20 @@
      * @param callback The binder used to communicate the violations.
      */
     @Override
-    public synchronized void registerStrictModeCallback(IBinder callback) {
-        int callingPid = Binder.getCallingPid();
-        mStrictModeCallbacks.put(callingPid,
-                IUnsafeIntentStrictModeCallback.Stub.asInterface(callback));
-        try {
-            callback.linkToDeath(() -> {
-                synchronized (ActivityManagerService.this) {
-                    mStrictModeCallbacks.remove(callingPid);
-                }
-            }, 0);
-        } catch (RemoteException e) {
-            mStrictModeCallbacks.remove(callingPid);
+    public void registerStrictModeCallback(IBinder callback) {
+        final int callingPid = Binder.getCallingPid();
+        synchronized (mStrictModeCallbacks) {
+            mStrictModeCallbacks.put(callingPid,
+                    IUnsafeIntentStrictModeCallback.Stub.asInterface(callback));
+            try {
+                callback.linkToDeath(() -> {
+                    synchronized (mStrictModeCallbacks) {
+                        mStrictModeCallbacks.remove(callingPid);
+                    }
+                }, 0);
+            } catch (RemoteException e) {
+                mStrictModeCallbacks.remove(callingPid);
+            }
         }
     }
 
@@ -10016,8 +10020,9 @@
                 if (crashInfo != null && crashInfo.stackTrace != null) {
                     sb.append(crashInfo.stackTrace);
                 }
-                boolean shouldAddLogs = logcatLines > 0 || kernelLogLines > 0;
-                if (!runSynchronously && shouldAddLogs) {
+                boolean shouldAddLogs = (logcatLines > 0 || kernelLogLines > 0)
+                        && (Flags.collectLogcatOnRunSynchronously() || !runSynchronously);
+                if (shouldAddLogs) {
                     sb.append("\n");
                     if (logcatLines > 0) {
                         fetchLogcatBuffers(sb, logcatLines, LOGCAT_TIMEOUT_SEC,
@@ -13961,12 +13966,7 @@
         enforceNotIsolatedCaller("startService");
         enforceAllowedToStartOrBindServiceIfSdkSandbox(service);
         if (service != null) {
-            // Refuse possible leaked file descriptors
-            if (service.hasFileDescriptors()) {
-                throw new IllegalArgumentException("File descriptors passed in Intent");
-            }
-            // Remove existing mismatch flag so it can be properly updated later
-            service.removeExtendedFlags(Intent.EXTENDED_FLAG_FILTER_MISMATCH);
+            service.prepareToEnterSystemServer();
         }
 
         if (callingPackage == null) {
@@ -14203,12 +14203,7 @@
         enforceAllowedToStartOrBindServiceIfSdkSandbox(service);
 
         if (service != null) {
-            // Refuse possible leaked file descriptors
-            if (service.hasFileDescriptors()) {
-                throw new IllegalArgumentException("File descriptors passed in Intent");
-            }
-            // Remove existing mismatch flag so it can be properly updated later
-            service.removeExtendedFlags(Intent.EXTENDED_FLAG_FILTER_MISMATCH);
+            service.prepareToEnterSystemServer();
         }
 
         if (callingPackage == null) {
@@ -16242,12 +16237,7 @@
 
     final Intent verifyBroadcastLocked(Intent intent) {
         if (intent != null) {
-            // Refuse possible leaked file descriptors
-            if (intent.hasFileDescriptors()) {
-                throw new IllegalArgumentException("File descriptors passed in Intent");
-            }
-            // Remove existing mismatch flag so it can be properly updated later
-            intent.removeExtendedFlags(Intent.EXTENDED_FLAG_FILTER_MISMATCH);
+            intent.prepareToEnterSystemServer();
         }
 
         int flags = intent.getFlags();
@@ -18378,43 +18368,55 @@
 
         boolean closeFd = true;
         try {
-            synchronized (mProcLock) {
-                if (fd == null) {
-                    throw new IllegalArgumentException("null fd");
-                }
-                mBinderTransactionTrackingEnabled = false;
+            Objects.requireNonNull(fd);
 
-                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
-                pw.println("Binder transaction traces for all processes.\n");
-                mProcessList.forEachLruProcessesLOSP(true, process -> {
+            record ProcessToDump(String processName, IApplicationThread thread) { }
+
+            PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
+            pw.println("Binder transaction traces for all processes.\n");
+            final ArrayList<ProcessToDump> processes = new ArrayList<>();
+            synchronized (mProcLock) {
+                // Since dumping binder transactions is a long-running operation, we can't do it
+                // with mProcLock held. Do the initial verification here, and save the processes
+                // to dump later outside the lock.
+                final ArrayList<ProcessRecord> unverifiedProcesses =
+                        new ArrayList<>(mProcessList.getLruProcessesLOSP());
+                for (int i = 0, size = unverifiedProcesses.size(); i < size; i++) {
+                    ProcessRecord process = unverifiedProcesses.get(i);
                     final IApplicationThread thread = process.getThread();
                     if (!processSanityChecksLPr(process, thread)) {
-                        return;
+                        continue;
                     }
-
-                    pw.println("Traces for process: " + process.processName);
-                    pw.flush();
-                    try {
-                        TransferPipe tp = new TransferPipe();
-                        try {
-                            thread.stopBinderTrackingAndDump(tp.getWriteFd());
-                            tp.go(fd.getFileDescriptor());
-                        } finally {
-                            tp.kill();
-                        }
-                    } catch (IOException e) {
-                        pw.println("Failure while dumping IPC traces from " + process +
-                                ".  Exception: " + e);
-                        pw.flush();
-                    } catch (RemoteException e) {
-                        pw.println("Got a RemoteException while dumping IPC traces from " +
-                                process + ".  Exception: " + e);
-                        pw.flush();
-                    }
-                });
-                closeFd = false;
-                return true;
+                    processes.add(new ProcessToDump(process.processName, process.getThread()));
+                }
+                mBinderTransactionTrackingEnabled = false;
             }
+            for (int i = 0, size = processes.size(); i < size; i++) {
+                final String processName = processes.get(i).processName();
+                final IApplicationThread thread = processes.get(i).thread();
+
+                pw.println("Traces for process: " + processName);
+                pw.flush();
+                try {
+                    TransferPipe tp = new TransferPipe();
+                    try {
+                        thread.stopBinderTrackingAndDump(tp.getWriteFd());
+                        tp.go(fd.getFileDescriptor());
+                    } finally {
+                        tp.kill();
+                    }
+                } catch (IOException e) {
+                    pw.println("Failure while dumping IPC traces from " + processName +
+                            ".  Exception: " + e);
+                    pw.flush();
+                } catch (RemoteException e) {
+                    pw.println("Got a RemoteException while dumping IPC traces from " +
+                            processName + ".  Exception: " + e);
+                    pw.flush();
+                }
+            }
+            closeFd = false;
+            return true;
         } finally {
             if (fd != null && closeFd) {
                 try {
@@ -19938,7 +19940,7 @@
         public void triggerUnsafeIntentStrictMode(int callingPid, int type, Intent intent) {
             final IUnsafeIntentStrictModeCallback callback;
             final Intent i = intent.cloneFilter();
-            synchronized (ActivityManagerService.this) {
+            synchronized (mStrictModeCallbacks) {
                 callback = mStrictModeCallbacks.get(callingPid);
             }
             if (callback != null) {
@@ -19946,7 +19948,7 @@
                     try {
                         callback.onUnsafeIntent(type, i);
                     } catch (RemoteException e) {
-                        synchronized (ActivityManagerService.this) {
+                        synchronized (mStrictModeCallbacks) {
                             mStrictModeCallbacks.remove(callingPid);
                         }
                     }
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 1ac37ad..00183ac 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -130,6 +130,7 @@
 import com.android.server.power.stats.BluetoothPowerStatsProcessor;
 import com.android.server.power.stats.CameraPowerStatsProcessor;
 import com.android.server.power.stats.CpuPowerStatsProcessor;
+import com.android.server.power.stats.CustomEnergyConsumerPowerStatsProcessor;
 import com.android.server.power.stats.FlashlightPowerStatsProcessor;
 import com.android.server.power.stats.GnssPowerStatsProcessor;
 import com.android.server.power.stats.MobileRadioPowerStatsProcessor;
@@ -574,6 +575,15 @@
                         AggregatedPowerStatsConfig.STATE_PROCESS_STATE)
                 .setProcessor(
                         new GnssPowerStatsProcessor(mPowerProfile, mPowerStatsUidResolver));
+
+        config.trackCustomPowerComponents(CustomEnergyConsumerPowerStatsProcessor::new)
+                .trackDeviceStates(
+                        AggregatedPowerStatsConfig.STATE_POWER,
+                        AggregatedPowerStatsConfig.STATE_SCREEN)
+                .trackUidStates(
+                        AggregatedPowerStatsConfig.STATE_POWER,
+                        AggregatedPowerStatsConfig.STATE_SCREEN,
+                        AggregatedPowerStatsConfig.STATE_PROCESS_STATE);
         return config;
     }
 
@@ -665,6 +675,10 @@
                 BatteryConsumer.POWER_COMPONENT_CAMERA,
                 Flags.streamlinedMiscBatteryStats());
 
+        // By convention POWER_COMPONENT_ANY represents custom Energy Consumers
+        mStats.setPowerStatsCollectorEnabled(BatteryConsumer.POWER_COMPONENT_ANY,
+                Flags.streamlinedMiscBatteryStats());
+
         mWorker.systemServicesReady();
         mStats.systemServicesReady(mContext);
         mCpuWakeupStats.systemServicesReady();
@@ -834,6 +848,7 @@
     }
 
     private void syncStats(String reason, int flags) {
+        mStats.collectPowerStatsSamples();
         awaitUninterruptibly(mWorker.scheduleSync(reason, flags));
     }
 
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index 211f952..6433f2c 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -83,6 +83,8 @@
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.ServiceThread;
 
+import dalvik.annotation.optimization.NeverCompile;
+
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.PrintWriter;
@@ -98,8 +100,6 @@
 import java.util.Random;
 import java.util.Set;
 
-import dalvik.annotation.optimization.NeverCompile;
-
 public final class CachedAppOptimizer {
 
     // Flags stored in the DeviceConfig API.
@@ -248,7 +248,7 @@
     private static final int COMPACT_ACTION_ANON_FLAG = 2;
 
     private static final String ATRACE_COMPACTION_TRACK = "Compaction";
-    private static final String ATRACE_FREEZER_TRACK = "Freezer";
+    public static final String ATRACE_FREEZER_TRACK = "Freezer";
 
     private static final int FREEZE_BINDER_TIMEOUT_MS = 0;
     private static final int FREEZE_DEADLOCK_TIMEOUT_MS = 1000;
diff --git a/services/core/java/com/android/server/am/ContentProviderHelper.java b/services/core/java/com/android/server/am/ContentProviderHelper.java
index a8b9e43..4ff1367 100644
--- a/services/core/java/com/android/server/am/ContentProviderHelper.java
+++ b/services/core/java/com/android/server/am/ContentProviderHelper.java
@@ -674,7 +674,9 @@
                     if (conn != null) {
                         conn.waiting = true;
                     }
-                    cpr.wait(wait);
+                    if (wait > 0) {
+                        cpr.wait(wait);
+                    }
                     if (cpr.provider == null) {
                         timedOut = true;
                         break;
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index c9e0666..b058bd8 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -1653,8 +1653,7 @@
             new ComputeOomAdjWindowCallback();
 
     /** These methods are called inline during computeOomAdjLSP(), on the same thread */
-    final class ComputeOomAdjWindowCallback
-            implements WindowProcessController.ComputeOomAdjCallback {
+    final class ComputeOomAdjWindowCallback {
 
         ProcessRecord app;
         int adj;
@@ -1684,8 +1683,7 @@
             this.mState = app.mState;
         }
 
-        @Override
-        public void onVisibleActivity() {
+        void onVisibleActivity(int flags) {
             // App has a visible activity; only upgrade adjustment.
             if (adj > VISIBLE_APP_ADJ) {
                 adj = VISIBLE_APP_ADJ;
@@ -1705,12 +1703,17 @@
             if (schedGroup < SCHED_GROUP_DEFAULT) {
                 schedGroup = SCHED_GROUP_DEFAULT;
             }
+            if ((flags & WindowProcessController.ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN) != 0) {
+                // Another side of split should be the current global top. Use the same top
+                // priority for this non-top split.
+                schedGroup = SCHED_GROUP_TOP_APP;
+                mAdjType = "resumed-split-screen-activity";
+            }
             foregroundActivities = true;
             mHasVisibleActivities = true;
         }
 
-        @Override
-        public void onPausedActivity() {
+        void onPausedActivity() {
             if (adj > PERCEPTIBLE_APP_ADJ) {
                 adj = PERCEPTIBLE_APP_ADJ;
                 mAdjType = "pause-activity";
@@ -1733,8 +1736,7 @@
             mHasVisibleActivities = false;
         }
 
-        @Override
-        public void onStoppingActivity(boolean finishing) {
+        void onStoppingActivity(boolean finishing) {
             if (adj > PERCEPTIBLE_APP_ADJ) {
                 adj = PERCEPTIBLE_APP_ADJ;
                 mAdjType = "stop-activity";
@@ -1764,8 +1766,7 @@
             mHasVisibleActivities = false;
         }
 
-        @Override
-        public void onOtherActivity() {
+        void onOtherActivity() {
             if (procState > PROCESS_STATE_CACHED_ACTIVITY) {
                 procState = PROCESS_STATE_CACHED_ACTIVITY;
                 mAdjType = "cch-act";
@@ -1832,7 +1833,8 @@
             state.setNoKillOnBgRestrictedAndIdle(false);
             // If this UID is currently allowlisted, it should not be frozen.
             final UidRecord uidRec = app.getUidRecord();
-            app.mOptRecord.setShouldNotFreeze(uidRec != null && uidRec.isCurAllowListed());
+            app.mOptRecord.setShouldNotFreeze(uidRec != null && uidRec.isCurAllowListed(),
+                    ProcessCachedOptimizerRecord.SHOULD_NOT_FREEZE_REASON_UID_ALLOWLISTED, mAdjSeq);
         }
 
         final int appUid = app.info.uid;
@@ -2672,7 +2674,9 @@
 
         if (client.mOptRecord.shouldNotFreeze()) {
             // Propagate the shouldNotFreeze flag down the bindings.
-            if (app.mOptRecord.setShouldNotFreeze(true, dryRun)) {
+            if (app.mOptRecord.setShouldNotFreeze(true, dryRun,
+                    app.mOptRecord.shouldNotFreezeReason()
+                    | client.mOptRecord.shouldNotFreezeReason(), mAdjSeq)) {
                 // Bail out early, as we only care about the return value for a dryrun.
                 return true;
             }
@@ -2739,7 +2743,10 @@
             if (cr.hasFlag(Context.BIND_ALLOW_OOM_MANAGEMENT)) {
                 // Similar to BIND_WAIVE_PRIORITY, keep it unfrozen.
                 if (clientAdj < CACHED_APP_MIN_ADJ) {
-                    if (app.mOptRecord.setShouldNotFreeze(true, dryRun)) {
+                    if (app.mOptRecord.setShouldNotFreeze(true, dryRun,
+                            app.mOptRecord.shouldNotFreezeReason()
+                            | ProcessCachedOptimizerRecord
+                            .SHOULD_NOT_FREEZE_REASON_BINDER_ALLOW_OOM_MANAGEMENT, mAdjSeq)) {
                         // Bail out early, as we only care about the return value for a dryrun.
                         return true;
                     }
@@ -2976,7 +2983,10 @@
             // bound by an unfrozen app via a WPRI binding has to remain
             // unfrozen.
             if (clientAdj < CACHED_APP_MIN_ADJ) {
-                if (app.mOptRecord.setShouldNotFreeze(true, dryRun)) {
+                if (app.mOptRecord.setShouldNotFreeze(true, dryRun,
+                        app.mOptRecord.shouldNotFreezeReason()
+                        | ProcessCachedOptimizerRecord
+                        .SHOULD_NOT_FREEZE_REASON_BIND_WAIVE_PRIORITY, mAdjSeq)) {
                     // Bail out early, as we only care about the return value for a dryrun.
                     return true;
                 }
@@ -3117,7 +3127,9 @@
         }
         if (client.mOptRecord.shouldNotFreeze()) {
             // Propagate the shouldNotFreeze flag down the bindings.
-            if (app.mOptRecord.setShouldNotFreeze(true, dryRun)) {
+            if (app.mOptRecord.setShouldNotFreeze(true, dryRun,
+                    app.mOptRecord.shouldNotFreezeReason()
+                    | client.mOptRecord.shouldNotFreezeReason(), mAdjSeq)) {
                 // Bail out early, as we only care about the return value for a dryrun.
                 return true;
             }
@@ -3476,7 +3488,7 @@
             changes |= ActivityManagerService.ProcessChangeItem.CHANGE_ACTIVITIES;
         }
 
-        updateAppFreezeStateLSP(app, oomAdjReson, false);
+        updateAppFreezeStateLSP(app, oomAdjReson, false, oldOomAdj);
 
         if (state.getReportedProcState() != state.getCurProcState()) {
             state.setReportedProcState(state.getCurProcState());
@@ -3873,16 +3885,37 @@
 
     @GuardedBy({"mService", "mProcLock"})
     void updateAppFreezeStateLSP(ProcessRecord app, @OomAdjReason int oomAdjReason,
-            boolean immediate) {
+            boolean immediate, int oldOomAdj) {
         if (!mCachedAppOptimizer.useFreezer()) {
             return;
         }
 
+        final ProcessCachedOptimizerRecord opt = app.mOptRecord;
+        final ProcessStateRecord state = app.mState;
+        if (Flags.traceUpdateAppFreezeStateLsp()) {
+            final boolean oomAdjChanged =
+                    (state.getCurAdj() >= FREEZER_CUTOFF_ADJ ^ oldOomAdj >= FREEZER_CUTOFF_ADJ)
+                    || oldOomAdj == UNKNOWN_ADJ;
+            final boolean shouldNotFreezeChanged = opt.shouldNotFreezeAdjSeq() == mAdjSeq;
+            if ((oomAdjChanged || shouldNotFreezeChanged)
+                    && Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                Trace.instantForTrack(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                        CachedAppOptimizer.ATRACE_FREEZER_TRACK,
+                        "updateAppFreezeStateLSP " + app.processName
+                        + " isFreezeExempt: " + opt.isFreezeExempt()
+                        + " isFrozen: " + opt.isFrozen()
+                        + " shouldNotFreeze: " + opt.shouldNotFreeze()
+                        + " shouldNotFreezeReason: " + opt.shouldNotFreezeReason()
+                        + " curAdj: " + state.getCurAdj()
+                        + " oldOomAdj: " + oldOomAdj
+                        + " immediate: " + immediate);
+            }
+        }
+
         if (app.mOptRecord.isFreezeExempt()) {
             return;
         }
 
-        final ProcessCachedOptimizerRecord opt = app.mOptRecord;
         // if an app is already frozen and shouldNotFreeze becomes true, immediately unfreeze
         if (opt.isFrozen() && opt.shouldNotFreeze()) {
             mCachedAppOptimizer.unfreezeAppLSP(app,
@@ -3890,7 +3923,6 @@
             return;
         }
 
-        final ProcessStateRecord state = app.mState;
         // Use current adjustment when freezing, set adjustment when unfreezing.
         if (state.getCurAdj() >= FREEZER_CUTOFF_ADJ && !opt.isFrozen()
                 && !opt.shouldNotFreeze()) {
diff --git a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
index ea92571..53643b8 100644
--- a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
+++ b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
@@ -16,6 +16,7 @@
 
 package com.android.server.am;
 
+import android.annotation.IntDef;
 import android.annotation.UptimeMillisLong;
 import android.app.ActivityManagerInternal.OomAdjReason;
 import android.util.TimeUtils;
@@ -23,14 +24,31 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
-import java.io.PrintWriter;
-
 import dalvik.annotation.optimization.NeverCompile;
 
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * The state info of app when it's cached, used by the optimizer.
  */
 final class ProcessCachedOptimizerRecord {
+
+    static final int SHOULD_NOT_FREEZE_REASON_NONE = 1;
+    static final int SHOULD_NOT_FREEZE_REASON_UID_ALLOWLISTED = 1 << 1;
+    static final int SHOULD_NOT_FREEZE_REASON_BINDER_ALLOW_OOM_MANAGEMENT = 1 << 2;
+    static final int SHOULD_NOT_FREEZE_REASON_BIND_WAIVE_PRIORITY = 1 << 3;
+
+    @IntDef(flag = true, prefix = {"SHOULD_NOT_FREEZE_REASON_"}, value = {
+        SHOULD_NOT_FREEZE_REASON_NONE,
+        SHOULD_NOT_FREEZE_REASON_UID_ALLOWLISTED,
+        SHOULD_NOT_FREEZE_REASON_BINDER_ALLOW_OOM_MANAGEMENT,
+        SHOULD_NOT_FREEZE_REASON_BIND_WAIVE_PRIORITY,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ShouldNotFreezeReason {}
+
     private final ProcessRecord mApp;
 
     private final ActivityManagerGlobalLock mProcLock;
@@ -112,6 +130,18 @@
     private boolean mShouldNotFreeze;
 
     /**
+     * Reason for mShouldNotFreeze being set to a particular value.
+     */
+    @GuardedBy("mProcLock")
+    private @ShouldNotFreezeReason int mShouldNotFreezeReason;
+
+    /**
+     * The value of adjSeq when last time mShouldNotFreeze was set.
+     */
+    @GuardedBy("mProcLock")
+    private int mShouldNotFreezeAdjSeq;
+
+    /**
      * Exempt from freezer (now for system apps with INSTALL_PACKAGES permission)
      */
     @GuardedBy("mProcLock")
@@ -275,8 +305,19 @@
     }
 
     @GuardedBy("mProcLock")
-    void setShouldNotFreeze(boolean shouldNotFreeze) {
-        setShouldNotFreeze(shouldNotFreeze, false);
+    @ShouldNotFreezeReason int shouldNotFreezeReason() {
+        return mShouldNotFreezeReason;
+    }
+
+    @GuardedBy("mProcLock")
+    int shouldNotFreezeAdjSeq() {
+        return mShouldNotFreezeAdjSeq;
+    }
+
+    @GuardedBy("mProcLock")
+    void setShouldNotFreeze(boolean shouldNotFreeze, @ShouldNotFreezeReason int reason,
+            int adjSeq) {
+        setShouldNotFreeze(shouldNotFreeze, false, reason, adjSeq);
     }
 
     /**
@@ -284,10 +325,23 @@
      * if it was a real run.
      */
     @GuardedBy("mProcLock")
-    boolean setShouldNotFreeze(boolean shouldNotFreeze, boolean dryRun) {
+    boolean setShouldNotFreeze(boolean shouldNotFreeze, boolean dryRun,
+            @ShouldNotFreezeReason int reason, int adjSeq) {
         if (dryRun) {
             return mFrozen && !shouldNotFreeze;
         }
+        if (Flags.traceUpdateAppFreezeStateLsp()) {
+            if (shouldNotFreeze) {
+                reason &= ~SHOULD_NOT_FREEZE_REASON_NONE;
+            } else {
+                reason = SHOULD_NOT_FREEZE_REASON_NONE;
+            }
+
+            if (reason != mShouldNotFreezeReason || shouldNotFreeze != mShouldNotFreeze) {
+                mShouldNotFreezeAdjSeq = adjSeq;
+            }
+            mShouldNotFreezeReason = reason;
+        }
         mShouldNotFreeze = shouldNotFreeze;
         return false;
     }
diff --git a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
index d4d4965..ba4b71c 100644
--- a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
+++ b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
@@ -60,7 +60,6 @@
 import com.android.server.criticalevents.CriticalEventLog;
 import com.android.server.stats.pull.ProcfsMemoryUtil.MemorySnapshot;
 import com.android.server.wm.WindowProcessController;
-import com.android.server.utils.AnrTimer;
 
 import java.io.File;
 import java.io.PrintWriter;
@@ -69,6 +68,7 @@
 import java.time.ZoneId;
 import java.time.ZonedDateTime;
 import java.util.ArrayList;
+import java.util.LinkedHashMap;
 import java.util.UUID;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
@@ -429,7 +429,7 @@
             }
         }
         // Build memory headers for the ANRing process.
-        String memoryHeaders = buildMemoryHeadersFor(pid);
+        LinkedHashMap<String, String> memoryHeaders = buildMemoryHeadersFor(pid);
 
         // Get critical event log before logging the ANR so that it doesn't occur in the log.
         latencyTracker.criticalEventLogStarted();
@@ -753,7 +753,7 @@
             resolver.getUserId()) != 0;
     }
 
-    private @Nullable String buildMemoryHeadersFor(int pid) {
+    private @Nullable LinkedHashMap<String, String> buildMemoryHeadersFor(int pid) {
         if (pid <= 0) {
             Slog.i(TAG, "Memory header requested with invalid pid: " + pid);
             return null;
@@ -764,15 +764,13 @@
             return null;
         }
 
-        StringBuilder memoryHeaders = new StringBuilder();
-        memoryHeaders.append("RssHwmKb: ")
-            .append(snapshot.rssHighWaterMarkInKilobytes)
-            .append("\n");
-        memoryHeaders.append("RssKb: ").append(snapshot.rssInKilobytes).append("\n");
-        memoryHeaders.append("RssAnonKb: ").append(snapshot.anonRssInKilobytes).append("\n");
-        memoryHeaders.append("RssShmemKb: ").append(snapshot.rssShmemKilobytes).append("\n");
-        memoryHeaders.append("VmSwapKb: ").append(snapshot.swapInKilobytes).append("\n");
-        return memoryHeaders.toString();
+        LinkedHashMap<String, String> memoryHeaders = new LinkedHashMap<>();
+        memoryHeaders.put("RssHwmKb", Integer.toString(snapshot.rssHighWaterMarkInKilobytes));
+        memoryHeaders.put("RssKb", Integer.toString(snapshot.rssInKilobytes));
+        memoryHeaders.put("RssAnonKb", Integer.toString(snapshot.anonRssInKilobytes));
+        memoryHeaders.put("RssShmemKb", Integer.toString(snapshot.rssShmemKilobytes));
+        memoryHeaders.put("VmSwapKb", Integer.toString(snapshot.swapInKilobytes));
+        return memoryHeaders;
     }
     /**
      * Unless configured otherwise, swallow ANRs in background processes & kill the process.
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index bea0e00..779aabe 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -855,8 +855,8 @@
                         Slog.i(TAG, "Failed to connect to lmkd, retry after " +
                                 LMKD_RECONNECT_DELAY_MS + " ms");
                         // retry after LMKD_RECONNECT_DELAY_MS
-                        sKillHandler.sendMessageDelayed(sKillHandler.obtainMessage(
-                                KillHandler.LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS);
+                        sendMessageDelayed(obtainMessage(
+                                LMKD_RECONNECT_MSG), LMKD_RECONNECT_DELAY_MS);
                     }
                     break;
                 default:
diff --git a/services/core/java/com/android/server/am/ProcessStateRecord.java b/services/core/java/com/android/server/am/ProcessStateRecord.java
index 7c64298..bc990d9 100644
--- a/services/core/java/com/android/server/am/ProcessStateRecord.java
+++ b/services/core/java/com/android/server/am/ProcessStateRecord.java
@@ -27,6 +27,11 @@
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
 import static com.android.server.am.ProcessList.CACHED_APP_MIN_ADJ;
 import static com.android.server.am.ProcessRecord.TAG;
+import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED;
+import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING;
+import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING;
+import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE;
+import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER;
 
 import android.annotation.ElapsedRealtimeLong;
 import android.app.ActivityManager;
@@ -1108,6 +1113,7 @@
         return mCachedCompatChanges[cachedCompatChangeId] == VALUE_TRUE;
     }
 
+    /** This is only called if the process contains activities and is not the global top. */
     @GuardedBy("mService")
     void computeOomAdjFromActivitiesIfNecessary(OomAdjuster.ComputeOomAdjWindowCallback callback,
             int adj, boolean foregroundActivities, boolean hasVisibleActivities, int procState,
@@ -1117,8 +1123,17 @@
         }
         callback.initialize(mApp, adj, foregroundActivities, hasVisibleActivities, procState,
                 schedGroup, appUid, logUid, processCurTop);
-        final int minLayer = Math.min(ProcessList.VISIBLE_APP_LAYER_MAX,
-                mApp.getWindowProcessController().computeOomAdjFromActivities(callback));
+        final int flags = mApp.getWindowProcessController().getActivityStateFlags();
+
+        if ((flags & ACTIVITY_STATE_FLAG_IS_VISIBLE) != 0) {
+            callback.onVisibleActivity(flags);
+        } else if ((flags & ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED) != 0) {
+            callback.onPausedActivity();
+        } else if ((flags & ACTIVITY_STATE_FLAG_IS_STOPPING) != 0) {
+            callback.onStoppingActivity((flags & ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING) != 0);
+        } else {
+            callback.onOtherActivity();
+        }
 
         mCachedAdj = callback.adj;
         mCachedForegroundActivities = callback.foregroundActivities;
@@ -1128,6 +1143,8 @@
         mCachedAdjType = callback.mAdjType;
 
         if (mCachedAdj == ProcessList.VISIBLE_APP_ADJ) {
+            final int taskLayer = flags & ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER;
+            final int minLayer = Math.min(ProcessList.VISIBLE_APP_LAYER_MAX, taskLayer);
             mCachedAdj += minLayer;
         }
     }
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index cbea7aa..932b9c0 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -136,6 +136,7 @@
     static final String[] sDeviceConfigAconfigScopes = new String[] {
         "accessibility",
         "android_core_networking",
+        "android_sdk",
         "android_stylus",
         "aoc",
         "app_widgets",
diff --git a/services/core/java/com/android/server/am/StackTracesDumpHelper.java b/services/core/java/com/android/server/am/StackTracesDumpHelper.java
index c1374e1..2021ba4 100644
--- a/services/core/java/com/android/server/am/StackTracesDumpHelper.java
+++ b/services/core/java/com/android/server/am/StackTracesDumpHelper.java
@@ -47,6 +47,8 @@
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.Map;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
@@ -100,15 +102,17 @@
     /**
      * @param subject the subject of the dumped traces
      * @param criticalEventSection the critical event log, passed as a string
+     * @param extraHeaders Optional, Extra headers added by the dumping method
      */
     public static File dumpStackTraces(ArrayList<Integer> firstPids,
             ProcessCpuTracker processCpuTracker, SparseBooleanArray lastPids,
             Future<ArrayList<Integer>> nativePidsFuture, StringWriter logExceptionCreatingFile,
-            String subject, String criticalEventSection, @NonNull Executor auxiliaryTaskExecutor,
+            String subject, String criticalEventSection,
+            LinkedHashMap<String, String> extraHeaders, @NonNull Executor auxiliaryTaskExecutor,
             AnrLatencyTracker latencyTracker) {
         return dumpStackTraces(firstPids, processCpuTracker, lastPids, nativePidsFuture,
                 logExceptionCreatingFile, null, subject, criticalEventSection,
-                /* memoryHeaders= */ null, auxiliaryTaskExecutor, null, latencyTracker);
+                extraHeaders, auxiliaryTaskExecutor, null, latencyTracker);
     }
 
     /**
@@ -119,7 +123,7 @@
             ProcessCpuTracker processCpuTracker, SparseBooleanArray lastPids,
             Future<ArrayList<Integer>> nativePidsFuture, StringWriter logExceptionCreatingFile,
             AtomicLong firstPidEndOffset, String subject, String criticalEventSection,
-            String memoryHeaders, @NonNull Executor auxiliaryTaskExecutor,
+            LinkedHashMap<String, String> extraHeaders, @NonNull Executor auxiliaryTaskExecutor,
            Future<File> firstPidFilePromise, AnrLatencyTracker latencyTracker) {
         try {
 
@@ -159,11 +163,12 @@
                 }
                 return null;
             }
+            boolean extraHeadersExist = extraHeaders != null && !extraHeaders.isEmpty();
 
-            if (subject != null || criticalEventSection != null || memoryHeaders != null) {
+            if (subject != null || criticalEventSection != null || extraHeadersExist) {
                 appendtoANRFile(tracesFile.getAbsolutePath(),
                         (subject != null ? "Subject: " + subject + "\n" : "")
-                        + (memoryHeaders != null ? memoryHeaders + "\n\n" : "")
+                        + (extraHeadersExist ? stringifyHeaders(extraHeaders) + "\n\n" : "")
                         + (criticalEventSection != null ? criticalEventSection : ""));
             }
 
@@ -614,4 +619,15 @@
         return pids;
     }
 
+    private static String stringifyHeaders(@NonNull LinkedHashMap<String, String> headers) {
+        StringBuilder headersString = new StringBuilder();
+        for (Map.Entry<String, String> entry : headers.entrySet()) {
+            headersString.append(entry.getKey())
+                    .append(": ")
+                    .append(entry.getValue())
+                    .append("\n");
+        }
+        return headersString.toString();
+    }
+
 }
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index fa0e2ca..30efa3e 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -2335,6 +2335,14 @@
             // Never stop system user
             return;
         }
+        synchronized(mLock) {
+            final UserState uss = mStartedUsers.get(oldUserId);
+            if (uss == null || uss.state == UserState.STATE_STOPPING
+                    || uss.state == UserState.STATE_SHUTDOWN) {
+                // We've stopped (or are stopping) the user anyway, so don't bother scheduling.
+                return;
+            }
+        }
         if (oldUserId == mInjector.getUserManagerInternal().getMainUserId()) {
             // MainUser is currently special for things like Docking, so we'll exempt it for now.
             Slogf.i(TAG, "Exempting user %d from being stopped due to inactivity by virtue "
@@ -2371,6 +2379,12 @@
                 // We'll soon want to switch to this user, so don't kill it now.
                 return;
             }
+            final UserInfo currentOrTargetUser = getCurrentUserLU();
+            if (currentOrTargetUser != null && currentOrTargetUser.isGuest()) {
+                // Don't kill any background users for the sake of a Guest. Just reschedule instead.
+                scheduleStopOfBackgroundUser(userId);
+                return;
+            }
             Slogf.i(TAG, "Stopping background user %d due to inactivity", userId);
             stopUsersLU(userId, /* allowDelayedLocking= */ true, null, null);
         }
diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig
index bb52857..9b380ff 100644
--- a/services/core/java/com/android/server/am/flags.aconfig
+++ b/services/core/java/com/android/server/am/flags.aconfig
@@ -125,6 +125,14 @@
 }
 
 flag {
+    name: "trace_update_app_freeze_state_lsp"
+    namespace: "backstage_power"
+    description: "Output process oom adj and other metadata to trace in updateAppFreezeStateLSP"
+    bug: "345547733"
+    is_fixed_read_only: true
+}
+
+flag {
     name: "simplify_process_traversal"
     namespace: "backstage_power"
     description: "Simplify the OomAdjuster's process traversal mechanism."
@@ -152,3 +160,19 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    name: "collect_logcat_on_run_synchronously"
+    namespace: "dropbox"
+    description: "Allow logcat collection on synchronous dropbox collection"
+    bug: "324222683"
+    is_fixed_read_only: true
+}
+
+flag {
+    name: "enable_dropbox_watchdog_headers"
+    namespace: "dropbox"
+    description: "Add watchdog-specific dropbox headers"
+    bug: "330682397"
+    is_fixed_read_only: true
+}
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 1bb7922..f61bd60 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -2790,8 +2790,9 @@
      * have information on them.
      */
     private static boolean isOpAllowedForUid(int uid) {
+        int appId = UserHandle.getAppId(uid);
         return Flags.runtimePermissionAppopsMappingEnabled()
-                && (uid == Process.ROOT_UID || uid == Process.SYSTEM_UID);
+                && (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/appop/DiscreteRegistry.java b/services/core/java/com/android/server/appop/DiscreteRegistry.java
index b1a12f7..5d83ad6 100644
--- a/services/core/java/com/android/server/appop/DiscreteRegistry.java
+++ b/services/core/java/com/android/server/appop/DiscreteRegistry.java
@@ -26,6 +26,7 @@
 import static android.app.AppOpsManager.FILTER_BY_UID;
 import static android.app.AppOpsManager.OP_CAMERA;
 import static android.app.AppOpsManager.OP_COARSE_LOCATION;
+import static android.app.AppOpsManager.OP_EMERGENCY_LOCATION;
 import static android.app.AppOpsManager.OP_FINE_LOCATION;
 import static android.app.AppOpsManager.OP_FLAGS_ALL;
 import static android.app.AppOpsManager.OP_FLAG_SELF;
@@ -135,9 +136,10 @@
     private static final String PROPERTY_DISCRETE_FLAGS = "discrete_history_op_flags";
     private static final String PROPERTY_DISCRETE_OPS_LIST = "discrete_history_ops_cslist";
     private static final String DEFAULT_DISCRETE_OPS = OP_FINE_LOCATION + "," + OP_COARSE_LOCATION
-            + "," + OP_CAMERA + "," + OP_RECORD_AUDIO + "," + OP_PHONE_CALL_MICROPHONE + ","
-            + OP_PHONE_CALL_CAMERA + "," + OP_RECEIVE_AMBIENT_TRIGGER_AUDIO + ","
-            + OP_RECEIVE_SANDBOX_TRIGGER_AUDIO + "," + OP_RESERVED_FOR_TESTING;
+            + "," + OP_EMERGENCY_LOCATION + "," + OP_CAMERA + "," + OP_RECORD_AUDIO + ","
+            + OP_PHONE_CALL_MICROPHONE + "," + OP_PHONE_CALL_CAMERA + ","
+            + OP_RECEIVE_AMBIENT_TRIGGER_AUDIO + "," + OP_RECEIVE_SANDBOX_TRIGGER_AUDIO
+            + "," + OP_RESERVED_FOR_TESTING;
     private static final long DEFAULT_DISCRETE_HISTORY_CUTOFF = Duration.ofDays(7).toMillis();
     private static final long MAXIMUM_DISCRETE_HISTORY_CUTOFF = Duration.ofDays(30).toMillis();
     private static final long DEFAULT_DISCRETE_HISTORY_QUANTIZATION =
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index bce1830..8de1552 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -51,6 +51,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
+import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.SystemClock;
@@ -374,6 +375,16 @@
                 deviceInfo.mScoAudioMode, deviceInfo.mIsPrivileged, deviceInfo.mEventSource);
     }
 
+    /**
+     * Indicates if a Bluetooth SCO activation request owner is controlling
+     * the SCO audio state itself or not.
+     * @param uid the UI of the SOC request owner app
+     * @return true if we should control SCO audio state, false otherwise
+     */
+    private boolean shouldStartScoForUid(int uid) {
+        return !(uid == Process.BLUETOOTH_UID || uid == Process.PHONE_UID);
+    }
+
     @GuardedBy("mDeviceStateLock")
     /*package*/ void setCommunicationRouteForClient(
                             IBinder cb, int uid, AudioDeviceAttributes device,
@@ -388,7 +399,7 @@
                                         + " device: " + device + " isPrivileged: " + isPrivileged
                                         + " from API: " + eventSource)).printLog(TAG));
 
-        final boolean wasBtScoRequested = isBluetoothScoRequested();
+        final int previousBtScoRequesterUid = bluetoothScoRequestOwnerUid();
         CommunicationRouteClient client;
 
         // Save previous client route in case of failure to start BT SCO audio
@@ -412,9 +423,42 @@
         if (client == null) {
             return;
         }
-        if (!mScoManagedByAudio) {
-            boolean isBtScoRequested = isBluetoothScoRequested();
-            if (isBtScoRequested && (!wasBtScoRequested || !isBluetoothScoActive())) {
+        final int btScoRequesterUid = bluetoothScoRequestOwnerUid();
+        final boolean isBtScoRequested = btScoRequesterUid != -1;
+        final boolean wasBtScoRequested = previousBtScoRequesterUid != -1;
+
+        if (mScoManagedByAudio) {
+            if (isBtScoRequested && (!wasBtScoRequested || !isBluetoothScoActive()
+                    || !mBtHelper.isBluetoothScoRequestedInternally())) {
+                boolean scoStarted = false;
+                if (shouldStartScoForUid(btScoRequesterUid)) {
+                    scoStarted = mBtHelper.startBluetoothSco(scoAudioMode, eventSource);
+                    if (!scoStarted) {
+                        Log.w(TAG, "setCommunicationRouteForClient: "
+                                + "failure to start BT SCO for uid: " + uid);
+                        // clean up or restore previous client selection
+                        if (prevClientDevice != null) {
+                            addCommunicationRouteClient(cb, uid, prevClientDevice, prevPrivileged);
+                        } else {
+                            removeCommunicationRouteClient(cb, true);
+                        }
+                        postBroadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
+                    }
+                } else {
+                    scoStarted = true;
+                }
+                if (scoStarted) {
+                    setBluetoothScoOn(true, "setCommunicationRouteForClient");
+                }
+            } else if (!isBtScoRequested && wasBtScoRequested) {
+                if (shouldStartScoForUid(previousBtScoRequesterUid)) {
+                    mBtHelper.stopBluetoothSco(eventSource);
+                }
+                setBluetoothScoOn(false, "setCommunicationRouteForClient");
+            }
+        } else {
+            if (isBtScoRequested && (!wasBtScoRequested || !isBluetoothScoActive()
+                    || !mBtHelper.isBluetoothScoRequestedInternally())) {
                 if (!mBtHelper.startBluetoothSco(scoAudioMode, eventSource)) {
                     Log.w(TAG, "setCommunicationRouteForClient: failure to start BT SCO for uid: "
                             + uid);
@@ -430,19 +474,10 @@
                 mBtHelper.stopBluetoothSco(eventSource);
             }
         }
-        // In BT classic for communication, the device changes from a2dp to sco device, but for
-        // LE Audio it stays the same and we must trigger the proper stream volume alignment, if
-        // LE Audio communication device is activated after the audio system has already switched to
-        // MODE_IN_CALL mode.
-        if (isBluetoothLeAudioRequested() && device != null) {
-            final int streamType = mAudioService.getBluetoothContextualVolumeStream();
-            final int leAudioVolIndex = getVssVolumeForDevice(streamType, device.getInternalType());
-            final int leAudioMaxVolIndex = getMaxVssVolumeForStream(streamType);
-            if (AudioService.DEBUG_COMM_RTE) {
-                Log.v(TAG, "setCommunicationRouteForClient restoring LE Audio device volume lvl.");
-            }
-            postSetLeAudioVolumeIndex(leAudioVolIndex, leAudioMaxVolIndex, streamType);
-        }
+        // In BT classic for communication, the device changes from a2dp to sco device,
+        // but for LE Audio or Hearing Aid it stays the same and we must trigger the proper
+        // stream volume alignment.
+        mAudioService.postUpdateContextualVolumes();
 
         updateCommunicationRoute(eventSource);
     }
@@ -574,12 +609,12 @@
     @GuardedBy("mDeviceStateLock")
     /*package*/ void updateCommunicationRouteClientState(
                             CommunicationRouteClient client, boolean wasActive) {
-        boolean wasBtScoRequested = isBluetoothScoRequested();
+        int btScoRequesterUid = bluetoothScoRequestOwnerUid();
         client.setPlaybackActive(mAudioService.isPlaybackActiveForUid(client.getUid()));
         client.setRecordingActive(mAudioService.isRecordingActiveForUid(client.getUid()));
         if (wasActive != client.isActive()) {
             postUpdateCommunicationRouteClient(
-                    wasBtScoRequested, "updateCommunicationRouteClientState");
+                    btScoRequesterUid, "updateCommunicationRouteClientState");
         }
     }
 
@@ -762,6 +797,22 @@
     }
 
     /**
+     * Helper method on top of isBluetoothScoRequested() returning the UID of the
+     * BT SCO route request owner of -1 if SCO is not requested.
+     * @return the UID of the BT SCO route request owner of -1 if SCO is not requested.
+     */
+    @GuardedBy("mDeviceStateLock")
+    /*package*/ int bluetoothScoRequestOwnerUid() {
+        if (!isBluetoothScoRequested()) {
+            return -1;
+        }
+        CommunicationRouteClient crc = topCommunicationRouteClient();
+        if (crc == null) {
+            return -1;
+        }
+        return crc.getUid();
+    }
+    /**
      * Helper method on top of isDeviceRequestedForCommunication() indicating if
      * Bluetooth LE Audio communication device is currently requested or not.
      * @return true if Bluetooth LE Audio device is requested, false otherwise.
@@ -1147,14 +1198,18 @@
         }
     }
 
+    @GuardedBy("mDeviceStateLock")
     /*package*/ void setBluetoothScoOn(boolean on, String eventSource) {
-        if (AudioService.DEBUG_COMM_RTE) {
-            Log.v(TAG, "setBluetoothScoOn: " + on + " " + eventSource);
-        }
         synchronized (mBluetoothAudioStateLock) {
+            int btScoRequesterUId = bluetoothScoRequestOwnerUid();
+            Log.i(TAG, "setBluetoothScoOn: " + on + ", mBluetoothScoOn: "
+                    + mBluetoothScoOn + ", btScoRequesterUId: " + btScoRequesterUId
+                    + ", from: " + eventSource);
             mBluetoothScoOn = on;
             updateAudioHalBluetoothState();
-            postUpdateCommunicationRouteClient(isBluetoothScoRequested(), eventSource);
+            if (!mScoManagedByAudio) {
+                postUpdateCommunicationRouteClient(btScoRequesterUId, eventSource);
+            }
         }
     }
 
@@ -1508,9 +1563,9 @@
     }
 
     /*package*/ void postUpdateCommunicationRouteClient(
-            boolean wasBtScoRequested, String eventSource) {
+            int btScoRequesterUid, String eventSource) {
         sendILMsgNoDelay(MSG_IL_UPDATE_COMMUNICATION_ROUTE_CLIENT, SENDMSG_QUEUE,
-                wasBtScoRequested ? 1 : 0, eventSource);
+                btScoRequesterUid, eventSource);
     }
 
     /*package*/ void postSetCommunicationDeviceForClient(CommunicationDeviceInfo info) {
@@ -1863,7 +1918,7 @@
                                         || btInfo.mProfile == BluetoothProfile.HEARING_AID
                                         || (mScoManagedByAudio
                                             && btInfo.mProfile == BluetoothProfile.HEADSET)) {
-                                    onUpdateCommunicationRouteClient(isBluetoothScoRequested(),
+                                    onUpdateCommunicationRouteClient(bluetoothScoRequestOwnerUid(),
                                             "setBluetoothActiveDevice");
                                 }
                             }
@@ -1925,11 +1980,11 @@
                 case MSG_I_SET_MODE_OWNER:
                     synchronized (mSetModeLock) {
                         synchronized (mDeviceStateLock) {
-                            boolean wasBtScoRequested = isBluetoothScoRequested();
+                            int btScoRequesterUid = bluetoothScoRequestOwnerUid();
                             mAudioModeOwner = (AudioModeInfo) msg.obj;
                             if (mAudioModeOwner.mMode != AudioSystem.MODE_RINGTONE) {
                                 onUpdateCommunicationRouteClient(
-                                        wasBtScoRequested, "setNewModeOwner");
+                                        btScoRequesterUid, "setNewModeOwner");
                             }
                         }
                     }
@@ -1956,7 +2011,7 @@
                 case MSG_IL_UPDATE_COMMUNICATION_ROUTE_CLIENT:
                     synchronized (mSetModeLock) {
                         synchronized (mDeviceStateLock) {
-                            onUpdateCommunicationRouteClient(msg.arg1 == 1, (String) msg.obj);
+                            onUpdateCommunicationRouteClient(msg.arg1, (String) msg.obj);
                         }
                     }
                     break;
@@ -2455,7 +2510,7 @@
     @Nullable private AudioDeviceAttributes preferredCommunicationDevice() {
         boolean btSCoOn = mBtHelper.isBluetoothScoOn();
         synchronized (mBluetoothAudioStateLock) {
-            btSCoOn = btSCoOn && mBluetoothScoOn;
+            btSCoOn = (btSCoOn || mScoManagedByAudio) && mBluetoothScoOn;
         }
 
         if (btSCoOn) {
@@ -2520,18 +2575,28 @@
      */
     // @GuardedBy("mSetModeLock")
     @GuardedBy("mDeviceStateLock")
-    private void onUpdateCommunicationRouteClient(boolean wasBtScoRequested, String eventSource) {
+    private void onUpdateCommunicationRouteClient(
+            int previousBtScoRequesterUid, String eventSource) {
         CommunicationRouteClient crc = topCommunicationRouteClient();
         if (AudioService.DEBUG_COMM_RTE) {
             Log.v(TAG, "onUpdateCommunicationRouteClient, crc: " + crc
-                    + " wasBtScoRequested: " + wasBtScoRequested + " eventSource: " + eventSource);
+                    + " previousBtScoRequesterUid: " + previousBtScoRequesterUid
+                    + " eventSource: " + eventSource);
         }
         if (crc != null) {
             setCommunicationRouteForClient(crc.getBinder(), crc.getUid(), crc.getDevice(),
                     BtHelper.SCO_MODE_UNDEFINED, crc.isPrivileged(), eventSource);
         } else {
-            if (!mScoManagedByAudio && !isBluetoothScoRequested() && wasBtScoRequested) {
-                mBtHelper.stopBluetoothSco(eventSource);
+            boolean wasScoRequested = previousBtScoRequesterUid != -1;
+            if (!isBluetoothScoRequested() && wasScoRequested) {
+                if (mScoManagedByAudio) {
+                    if (shouldStartScoForUid(previousBtScoRequesterUid)) {
+                        mBtHelper.stopBluetoothSco(eventSource);
+                    }
+                    setBluetoothScoOn(false, eventSource);
+                } else {
+                    mBtHelper.stopBluetoothSco(eventSource);
+                }
             }
             updateCommunicationRoute(eventSource);
         }
@@ -2791,12 +2856,13 @@
         return mDeviceInventory.getImmutableDeviceInventory();
     }
 
-    void addOrUpdateDeviceSAStateInInventory(AdiDeviceState deviceState) {
-        mDeviceInventory.addOrUpdateDeviceSAStateInInventory(deviceState);
+    void addOrUpdateDeviceSAStateInInventory(AdiDeviceState deviceState, boolean syncInventory) {
+        mDeviceInventory.addOrUpdateDeviceSAStateInInventory(deviceState, syncInventory);
     }
 
-    void addOrUpdateBtAudioDeviceCategoryInInventory(AdiDeviceState deviceState) {
-        mDeviceInventory.addOrUpdateAudioDeviceCategoryInInventory(deviceState);
+    void addOrUpdateBtAudioDeviceCategoryInInventory(
+            AdiDeviceState deviceState, boolean syncInventory) {
+        mDeviceInventory.addOrUpdateAudioDeviceCategoryInInventory(deviceState, syncInventory);
     }
 
     @Nullable
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index ba7aee0..02aa6f5 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -135,9 +135,10 @@
      * AdiDeviceState in the {@link AudioDeviceInventory#mDeviceInventory} list.
      * @param deviceState the device to update
      */
-    void addOrUpdateDeviceSAStateInInventory(AdiDeviceState deviceState) {
+    void addOrUpdateDeviceSAStateInInventory(AdiDeviceState deviceState, boolean syncInventory) {
         synchronized (mDeviceInventoryLock) {
-            mDeviceInventory.merge(deviceState.getDeviceId(), deviceState, (oldState, newState) -> {
+            mDeviceInventory.merge(deviceState.getDeviceId(), deviceState,
+                    (oldState, newState) -> {
                 oldState.setHasHeadTracker(newState.hasHeadTracker());
                 oldState.setHeadTrackerEnabled(newState.isHeadTrackerEnabled());
                 oldState.setSAEnabled(newState.isSAEnabled());
@@ -145,7 +146,9 @@
             });
             checkDeviceInventorySize_l();
         }
-        mDeviceBroker.postSynchronizeAdiDevicesInInventory(deviceState);
+        if (syncInventory) {
+            mDeviceBroker.postSynchronizeAdiDevicesInInventory(deviceState);
+        }
     }
 
     /**
@@ -196,7 +199,8 @@
      * AdiDeviceState in the {@link AudioDeviceInventory#mDeviceInventory} list.
      * @param deviceState the device to update
      */
-    void addOrUpdateAudioDeviceCategoryInInventory(AdiDeviceState deviceState) {
+    void addOrUpdateAudioDeviceCategoryInInventory(
+            AdiDeviceState deviceState, boolean syncInventory) {
         AtomicBoolean updatedCategory = new AtomicBoolean(false);
         synchronized (mDeviceInventoryLock) {
             if (automaticBtDeviceType()) {
@@ -218,7 +222,9 @@
         if (updatedCategory.get()) {
             mDeviceBroker.postUpdatedAdiDeviceState(deviceState, false /*initSA*/);
         }
-        mDeviceBroker.postSynchronizeAdiDevicesInInventory(deviceState);
+        if (syncInventory) {
+            mDeviceBroker.postSynchronizeAdiDevicesInInventory(deviceState);
+        }
     }
 
     void addAudioDeviceWithCategoryInInventoryIfNeeded(@NonNull String address,
@@ -235,14 +241,14 @@
         boolean bleCategoryFound = false;
         AdiDeviceState deviceState = findBtDeviceStateForAddress(address, DEVICE_OUT_BLE_HEADSET);
         if (deviceState != null) {
-            addOrUpdateAudioDeviceCategoryInInventory(deviceState);
+            addOrUpdateAudioDeviceCategoryInInventory(deviceState, true /*syncInventory*/);
             btCategory = deviceState.getAudioDeviceCategory();
             bleCategoryFound = true;
         }
 
         deviceState = findBtDeviceStateForAddress(address, DEVICE_OUT_BLUETOOTH_A2DP);
         if (deviceState != null) {
-            addOrUpdateAudioDeviceCategoryInInventory(deviceState);
+            addOrUpdateAudioDeviceCategoryInInventory(deviceState, true /*syncInventory*/);
             int a2dpCategory = deviceState.getAudioDeviceCategory();
             if (bleCategoryFound && a2dpCategory != btCategory) {
                 Log.w(TAG, "Found different audio device category for A2DP and BLE profiles with "
@@ -269,23 +275,43 @@
     }
 
     /**
-     * synchronize AdiDeviceState for LE devices in the same group
+     * Synchronize AdiDeviceState for LE devices in the same group
+     * or BT classic devices with the same address.
+     * @param updatedDevice the device state to synchronize or null.
+     * Called with null once after the device inventory and spatializer helper
+     * have been initialized to resync all devices.
      */
     void onSynchronizeAdiDevicesInInventory(AdiDeviceState updatedDevice) {
         synchronized (mDevicesLock) {
             synchronized (mDeviceInventoryLock) {
-                boolean found = false;
-                found |= synchronizeBleDeviceInInventory(updatedDevice);
-                if (automaticBtDeviceType()) {
-                    found |= synchronizeDeviceProfilesInInventory(updatedDevice);
-                }
-                if (found) {
-                    mDeviceBroker.postPersistAudioDeviceSettings();
+                if (updatedDevice != null) {
+                    onSynchronizeAdiDeviceInInventory_l(updatedDevice);
+                } else {
+                    for (AdiDeviceState ads : mDeviceInventory.values()) {
+                        onSynchronizeAdiDeviceInInventory_l(ads);
+                    }
                 }
             }
         }
     }
 
+    /**
+     * Synchronize AdiDeviceState for LE devices in the same group
+     * or BT classic devices with the same address.
+     * @param updatedDevice the device state to synchronize.
+     */
+    @GuardedBy({"mDevicesLock", "mDeviceInventoryLock"})
+    void onSynchronizeAdiDeviceInInventory_l(AdiDeviceState updatedDevice) {
+        boolean found = false;
+        found |= synchronizeBleDeviceInInventory(updatedDevice);
+        if (automaticBtDeviceType()) {
+            found |= synchronizeDeviceProfilesInInventory(updatedDevice);
+        }
+        if (found) {
+            mDeviceBroker.postPersistAudioDeviceSettings();
+        }
+    }
+
     @GuardedBy("mDeviceInventoryLock")
     private void checkDeviceInventorySize_l() {
         if (mDeviceInventory.size() > MAX_DEVICE_INVENTORY_ENTRIES) {
@@ -595,6 +621,9 @@
             mDeviceName = TextUtils.emptyIfNull(deviceName);
             mDeviceAddress = TextUtils.emptyIfNull(address);
             mDeviceIdentityAddress = TextUtils.emptyIfNull(identityAddress);
+            if (mDeviceIdentityAddress.isEmpty()) {
+                mDeviceIdentityAddress = mDeviceAddress;
+            }
             mDeviceCodecFormat = codecFormat;
             mGroupId = groupId;
             mPeerDeviceAddress = TextUtils.emptyIfNull(peerAddress);
@@ -2499,7 +2528,7 @@
             mDeviceBroker.setBluetoothA2dpOnInt(true, false /*fromA2dp*/, eventSource);
 
             AudioDeviceAttributes ada = new AudioDeviceAttributes(device, address, name);
-            final int res = AudioSystem.setDeviceConnectionState(ada,
+            final int res = mAudioSystem.setDeviceConnectionState(ada,
                     AudioSystem.DEVICE_STATE_AVAILABLE, codec);
             if (res != AudioSystem.AUDIO_STATUS_OK) {
                 AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
@@ -2519,23 +2548,27 @@
                     new DeviceInfo(device, name, address,
                             btInfo.mDevice.getIdentityAddress(), codec,
                             groupId, peerAddress, peerIdentityAddress));
-            mDeviceBroker.postAccessoryPlugMediaUnmute(device);
-            setCurrentAudioRouteNameIfPossible(name, /*fromA2dp=*/false);
+            if (btInfo.mIsLeOutput) {
+                mDeviceBroker.postAccessoryPlugMediaUnmute(device);
+                setCurrentAudioRouteNameIfPossible(name, /*fromA2dp=*/false);
+            }
             addAudioDeviceInInventoryIfNeeded(device, address, peerAddress,
                     BtHelper.getBtDeviceCategory(address), /*userDefined=*/false);
         }
 
-        if (streamType == AudioSystem.STREAM_DEFAULT) {
-            // No need to update volume for input devices
-            return;
-        }
+        if (btInfo.mIsLeOutput) {
+            if (streamType == AudioSystem.STREAM_DEFAULT) {
+                // No need to update volume for input devices
+                return;
+            }
 
-        final int leAudioVolIndex = (volumeIndex == -1)
-                ? mDeviceBroker.getVssVolumeForDevice(streamType, device)
-                : volumeIndex;
-        final int maxIndex = mDeviceBroker.getMaxVssVolumeForStream(streamType);
-        mDeviceBroker.postSetLeAudioVolumeIndex(leAudioVolIndex, maxIndex, streamType);
-        mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "makeLeAudioDeviceAvailable");
+            final int leAudioVolIndex = (volumeIndex == -1)
+                    ? mDeviceBroker.getVssVolumeForDevice(streamType, device)
+                    : volumeIndex;
+            final int maxIndex = mDeviceBroker.getMaxVssVolumeForStream(streamType);
+            mDeviceBroker.postSetLeAudioVolumeIndex(leAudioVolIndex, maxIndex, streamType);
+            mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "makeLeAudioDeviceAvailable");
+        }
 
         updateBluetoothPreferredModes_l(btInfo.mDevice /*connectedDevice*/);
     }
@@ -2546,7 +2579,7 @@
         AudioDeviceAttributes ada = null;
         if (device != AudioSystem.DEVICE_NONE) {
             ada = new AudioDeviceAttributes(device, address);
-            final int res = AudioSystem.setDeviceConnectionState(ada,
+            final int res = mAudioSystem.setDeviceConnectionState(ada,
                     AudioSystem.DEVICE_STATE_UNAVAILABLE,
                     codec);
 
@@ -2951,8 +2984,8 @@
             // Note if the device is not compatible with spatialization mode or the device
             // type is not canonical, it will be ignored in {@link SpatializerHelper}.
             if (devState != null) {
-                addOrUpdateDeviceSAStateInInventory(devState);
-                addOrUpdateAudioDeviceCategoryInInventory(devState);
+                addOrUpdateDeviceSAStateInInventory(devState, false /*syncInventory*/);
+                addOrUpdateAudioDeviceCategoryInInventory(devState, false /*syncInventory*/);
             }
         }
     }
diff --git a/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java b/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java
index 76191bb..c5180af 100644
--- a/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java
+++ b/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java
@@ -16,16 +16,27 @@
 
 package com.android.server.audio;
 
+import static android.Manifest.permission.ACCESS_ULTRASOUND;
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
 import static android.Manifest.permission.CALL_AUDIO_INTERCEPTION;
+import static android.Manifest.permission.CAPTURE_AUDIO_HOTWORD;
+import static android.Manifest.permission.CAPTURE_AUDIO_OUTPUT;
+import static android.Manifest.permission.CAPTURE_MEDIA_OUTPUT;
+import static android.Manifest.permission.CAPTURE_TUNER_AUDIO_INPUT;
+import static android.Manifest.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT;
 import static android.Manifest.permission.MODIFY_AUDIO_ROUTING;
+import static android.Manifest.permission.MODIFY_AUDIO_SETTINGS;
+import static android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS;
 import static android.Manifest.permission.MODIFY_PHONE_STATE;
 import static android.Manifest.permission.RECORD_AUDIO;
+import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
 
 import android.annotation.Nullable;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.ArraySet;
 import android.util.IntArray;
+import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.media.permission.INativePermissionController;
@@ -51,11 +62,25 @@
 
     static final String[] MONITORED_PERMS = new String[PermissionEnum.ENUM_SIZE];
 
+    static final byte[] HDS_PERMS = new byte[] {PermissionEnum.CAPTURE_AUDIO_HOTWORD,
+            PermissionEnum.CAPTURE_AUDIO_OUTPUT, PermissionEnum.RECORD_AUDIO};
+
     static {
-        MONITORED_PERMS[PermissionEnum.MODIFY_AUDIO_ROUTING] = MODIFY_AUDIO_ROUTING;
-        MONITORED_PERMS[PermissionEnum.MODIFY_PHONE_STATE] = MODIFY_PHONE_STATE;
         MONITORED_PERMS[PermissionEnum.RECORD_AUDIO] = RECORD_AUDIO;
+        MONITORED_PERMS[PermissionEnum.MODIFY_AUDIO_ROUTING] = MODIFY_AUDIO_ROUTING;
+        MONITORED_PERMS[PermissionEnum.MODIFY_AUDIO_SETTINGS] = MODIFY_AUDIO_SETTINGS;
+        MONITORED_PERMS[PermissionEnum.MODIFY_PHONE_STATE] = MODIFY_PHONE_STATE;
+        MONITORED_PERMS[PermissionEnum.MODIFY_DEFAULT_AUDIO_EFFECTS] = MODIFY_DEFAULT_AUDIO_EFFECTS;
+        MONITORED_PERMS[PermissionEnum.WRITE_SECURE_SETTINGS] = WRITE_SECURE_SETTINGS;
         MONITORED_PERMS[PermissionEnum.CALL_AUDIO_INTERCEPTION] = CALL_AUDIO_INTERCEPTION;
+        MONITORED_PERMS[PermissionEnum.ACCESS_ULTRASOUND] = ACCESS_ULTRASOUND;
+        MONITORED_PERMS[PermissionEnum.CAPTURE_AUDIO_OUTPUT] = CAPTURE_AUDIO_OUTPUT;
+        MONITORED_PERMS[PermissionEnum.CAPTURE_MEDIA_OUTPUT] = CAPTURE_MEDIA_OUTPUT;
+        MONITORED_PERMS[PermissionEnum.CAPTURE_AUDIO_HOTWORD] = CAPTURE_AUDIO_HOTWORD;
+        MONITORED_PERMS[PermissionEnum.CAPTURE_TUNER_AUDIO_INPUT] = CAPTURE_TUNER_AUDIO_INPUT;
+        MONITORED_PERMS[PermissionEnum.CAPTURE_VOICE_COMMUNICATION_OUTPUT] =
+                CAPTURE_VOICE_COMMUNICATION_OUTPUT;
+        MONITORED_PERMS[PermissionEnum.BLUETOOTH_CONNECT] = BLUETOOTH_CONNECT;
     }
 
     private final Object mLock = new Object();
@@ -67,6 +92,7 @@
 
     @GuardedBy("mLock")
     private final Map<Integer, Set<String>> mPackageMap;
+
     // Values are sorted
     @GuardedBy("mLock")
     private final int[][] mPermMap = new int[PermissionEnum.ENUM_SIZE][];
@@ -74,6 +100,9 @@
     @GuardedBy("mLock")
     private boolean mIsUpdateDeferred = true;
 
+    @GuardedBy("mLock")
+    private int mHdsUid = -1;
+
     /**
      * @param appInfos - PackageState for all apps on the device, used to populate init state
      */
@@ -103,7 +132,7 @@
             try {
                 for (byte i = 0; i < PermissionEnum.ENUM_SIZE; i++) {
                     if (mIsUpdateDeferred) {
-                        mPermMap[i] = getUidsHoldingPerm(MONITORED_PERMS[i]);
+                        mPermMap[i] = getUidsHoldingPerm(i);
                     }
                     mDest.populatePermissionState(i, mPermMap[i]);
                 }
@@ -163,7 +192,7 @@
             }
             try {
                 for (byte i = 0; i < PermissionEnum.ENUM_SIZE; i++) {
-                    var newPerms = getUidsHoldingPerm(MONITORED_PERMS[i]);
+                    var newPerms = getUidsHoldingPerm(i);
                     if (!Arrays.equals(newPerms, mPermMap[i])) {
                         mPermMap[i] = newPerms;
                         mDest.populatePermissionState(i, newPerms);
@@ -178,6 +207,77 @@
         }
     }
 
+    public void setIsolatedServiceUid(int uid, int owningUid) {
+        synchronized (mLock) {
+            if (mHdsUid == uid) return;
+            var packageNameSet = mPackageMap.get(owningUid);
+            if (packageNameSet == null) return;
+            var packageName = packageNameSet.iterator().next();
+            onModifyPackageState(uid, packageName, /* isRemove= */ false);
+            // permissions
+            mHdsUid = uid;
+            if (mDest == null) {
+                mIsUpdateDeferred = true;
+                return;
+            }
+            try {
+                for (byte perm : HDS_PERMS) {
+                    int[] newPerms = new int[mPermMap[perm].length + 1];
+                    System.arraycopy(mPermMap[perm], 0, newPerms, 0, mPermMap[perm].length);
+                    newPerms[newPerms.length - 1] = mHdsUid;
+                    Arrays.sort(newPerms);
+                    mPermMap[perm] = newPerms;
+                    mDest.populatePermissionState(perm, newPerms);
+                }
+            } catch (RemoteException e) {
+                // We will re-init the state when the service comes back up
+                mDest = null;
+                // We didn't necessarily finish
+                mIsUpdateDeferred = true;
+            }
+        }
+    }
+
+    public void clearIsolatedServiceUid(int uid) {
+        synchronized (mLock) {
+            if (mHdsUid != uid) return;
+            var packageNameSet = mPackageMap.get(uid);
+            if (packageNameSet == null) return;
+            var packageName = packageNameSet.iterator().next();
+            onModifyPackageState(uid, packageName, /* isRemove= */ true);
+            // permissions
+            if (mDest == null) {
+                mIsUpdateDeferred = true;
+                return;
+            }
+            try {
+                for (byte perm : HDS_PERMS) {
+                    int[] newPerms = new int[mPermMap[perm].length - 1];
+                    int ind = Arrays.binarySearch(mPermMap[perm], uid);
+                    if (ind < 0) continue;
+                    System.arraycopy(mPermMap[perm], 0, newPerms, 0, ind);
+                    System.arraycopy(mPermMap[perm], ind + 1, newPerms, ind,
+                            mPermMap[perm].length - ind - 1);
+                    mPermMap[perm] = newPerms;
+                    mDest.populatePermissionState(perm, newPerms);
+                }
+            } catch (RemoteException e) {
+                // We will re-init the state when the service comes back up
+                mDest = null;
+                // We didn't necessarily finish
+                mIsUpdateDeferred = true;
+            }
+            mHdsUid = -1;
+        }
+    }
+
+    private boolean isSpecialHdsPermission(int perm) {
+        for (var hdsPerm : HDS_PERMS) {
+            if (perm == hdsPerm) return true;
+        }
+        return false;
+    }
+
     /** Called when full syncing package state to audioserver. */
     @GuardedBy("mLock")
     private void resetNativePackageState() {
@@ -202,16 +302,19 @@
 
     @GuardedBy("mLock")
     /** Return all uids (not app-ids) which currently hold a given permission. Not app-op aware */
-    private int[] getUidsHoldingPerm(String perm) {
+    private int[] getUidsHoldingPerm(int perm) {
         IntArray acc = new IntArray();
         for (int userId : mUserIdSupplier.get()) {
             for (int appId : mPackageMap.keySet()) {
                 int uid = UserHandle.getUid(userId, appId);
-                if (mPermissionPredicate.test(uid, perm)) {
+                if (mPermissionPredicate.test(uid, MONITORED_PERMS[perm])) {
                     acc.add(uid);
                 }
             }
         }
+        if (isSpecialHdsPermission(perm) && mHdsUid != -1) {
+            acc.add(mHdsUid);
+        }
         var unwrapped = acc.toArray();
         Arrays.sort(unwrapped);
         return unwrapped;
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 684cb24..0d309eb 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -461,6 +461,7 @@
     private static final int MSG_DISPATCH_PREFERRED_MIXER_ATTRIBUTES = 52;
     private static final int MSG_CONFIGURATION_CHANGED = 54;
     private static final int MSG_BROADCAST_MASTER_MUTE = 55;
+    private static final int MSG_UPDATE_CONTEXTUAL_VOLUMES = 56;
 
     /**
      * Messages handled by the {@link SoundDoseHelper}, do not exceed
@@ -707,10 +708,14 @@
     // Streams currently muted by ringer mode and dnd
     protected static volatile int sRingerAndZenModeMutedStreams;
 
-    /** Streams that can be muted. Do not resolve to aliases when checking.
+    /** Streams that can be muted by system. Do not resolve to aliases when checking.
      * @see System#MUTE_STREAMS_AFFECTED */
     private int mMuteAffectedStreams;
 
+    /** Streams that can be muted by user. Do not resolve to aliases when checking.
+     * @see System#MUTE_STREAMS_AFFECTED */
+    private int mUserMutableStreams;
+
     @NonNull
     private SoundEffectsHelper mSfxHelper;
 
@@ -783,9 +788,11 @@
             AudioSystem.DEVICE_OUT_HDMI_EARC
     ));
 
+    private final Object mAbsoluteVolumeDeviceInfoMapLock = new Object();
     // Devices where the framework sends a full scale audio signal, and controls the volume of
     // the external audio system separately.
     // For possible volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}.
+    @GuardedBy("mAbsoluteVolumeDeviceInfoMapLock")
     Map<Integer, AbsoluteVolumeDeviceInfo> mAbsoluteVolumeDeviceInfoMap = new ArrayMap<>();
 
     /**
@@ -834,7 +841,9 @@
     // full scale, and volume control separately) and can be used for multiple use cases reflected
     // by the audio mode (e.g. media playback in MODE_NORMAL, and phone calls in MODE_IN_CALL).
     Set<Integer> mAbsVolumeMultiModeCaseDevices = new HashSet<>(
-            Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID));
+            Arrays.asList(AudioSystem.DEVICE_OUT_HEARING_AID,
+                          AudioSystem.DEVICE_OUT_BLE_HEADSET,
+                          AudioSystem.DEVICE_OUT_BLE_SPEAKER));
 
     private final boolean mMonitorRotation;
 
@@ -968,7 +977,7 @@
 
     private NotificationManager mNm;
     private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate;
-    private VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT;
+    private volatile VolumePolicy mVolumePolicy = VolumePolicy.DEFAULT;
     private long mLoweredFromNormalToVibrateTime;
 
     // Array of Uids of valid assistant services to check if caller is one of them
@@ -2343,6 +2352,7 @@
                 mMuteAffectedStreams &= ~(1 << vss.mStreamType);
             }
         }
+        updateUserMutableStreams();
     }
 
     private void createStreamStates() {
@@ -2412,6 +2422,8 @@
         }
         pw.print("\n- mute affected streams = 0x");
         pw.println(Integer.toHexString(mMuteAffectedStreams));
+        pw.print("\n- user mutable streams = 0x");
+        pw.println(Integer.toHexString(mUserMutableStreams));
     }
 
     private void updateStreamVolumeAlias(boolean updateVolumes, String caller) {
@@ -2906,6 +2918,7 @@
         mMuteAffectedStreams = mSettings.getSystemIntForUser(cr,
                 System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED,
                 UserHandle.USER_CURRENT);
+        updateUserMutableStreams();
 
         updateMasterMono(cr);
 
@@ -2925,6 +2938,12 @@
         mVolumeController.loadSettings(cr);
     }
 
+    private void updateUserMutableStreams() {
+        mUserMutableStreams = mMuteAffectedStreams;
+        mUserMutableStreams &= ~(1 << AudioSystem.STREAM_VOICE_CALL);
+        mUserMutableStreams &= ~(1 << AudioSystem.STREAM_BLUETOOTH_SCO);
+    }
+
     @GuardedBy("mSettingsLock")
     private void resetActiveAssistantUidsLocked() {
         mActiveAssistantServiceUids = NO_ACTIVE_ASSISTANT_SERVICE_UIDS;
@@ -3715,9 +3734,8 @@
         int oldIndex = mStreamStates[streamType].getIndex(device);
 
         // Check if the volume adjustment should be handled by an absolute volume controller instead
-        if (isAbsoluteVolumeDevice(device)
-                && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) {
-            AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device);
+        if (isAbsoluteVolumeDevice(device) && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) {
+            final AbsoluteVolumeDeviceInfo info = getAbsoluteVolumeDeviceInfo(device);
             if (info.mHandlesVolumeAdjustment) {
                 dispatchAbsoluteVolumeAdjusted(streamType, info, oldIndex, direction,
                         keyEventMode);
@@ -3784,7 +3802,7 @@
                 mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex / 10);
             } else if (isAbsoluteVolumeDevice(device)
                     && (flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0) {
-                AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device);
+                final AbsoluteVolumeDeviceInfo info = getAbsoluteVolumeDeviceInfo(device);
                 dispatchAbsoluteVolumeChanged(streamType, info, newIndex);
             }
 
@@ -3799,17 +3817,16 @@
                     mStreamStates[streamType].getMaxIndex(), streamType);
             }
 
-            // Check if volume update should be send to Hearing Aid
-            if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
-                // only modify the hearing aid attenuation when the stream to modify matches
-                // the one expected by the hearing aid
-                if (streamType == getBluetoothContextualVolumeStream()) {
-                    if (DEBUG_VOL) {
-                        Log.d(TAG, "adjustStreamVolume postSetHearingAidVolumeIndex index="
-                                + newIndex + " stream=" + streamType);
-                    }
-                    mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
+            // Check if volume update should be send to Hearing Aid.
+            // Only modify the hearing aid attenuation when the stream to modify matches
+            // the one expected by the hearing aid.
+            if (device == AudioSystem.DEVICE_OUT_HEARING_AID
+                    && streamType == getBluetoothContextualVolumeStream()) {
+                if (DEBUG_VOL) {
+                    Log.d(TAG, "adjustStreamVolume postSetHearingAidVolumeIndex index="
+                            + newIndex + " stream=" + streamType);
                 }
+                mDeviceBroker.postSetHearingAidVolumeIndex(newIndex, streamType);
             }
         }
 
@@ -4465,7 +4482,7 @@
             }
         }
         if (mVoicePlaybackActive.getAndSet(voiceActive) != voiceActive) {
-            updateHearingAidVolumeOnVoiceActivityUpdate();
+            postUpdateContextualVolumes();
         }
         if (mMediaPlaybackActive.getAndSet(mediaActive) != mediaActive && mediaActive) {
             mSoundDoseHelper.scheduleMusicActiveCheck();
@@ -4603,89 +4620,55 @@
         }
     }
 
-    private void updateHearingAidVolumeOnVoiceActivityUpdate() {
-        final int streamType = getBluetoothContextualVolumeStream();
-        final int index = getStreamVolume(streamType);
-        sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_HEARING_AID,
-                mVoicePlaybackActive.get(), streamType, index));
-        mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
 
+    // delay between audio playback configuration update and checking
+    // actual stream activity to take async playback stop into account
+    private static final int UPDATE_CONTEXTUAL_VOLUME_DELAY_MS = 500;
+
+    /*package*/ void postUpdateContextualVolumes() {
+        sendMsg(mAudioHandler, MSG_UPDATE_CONTEXTUAL_VOLUMES, SENDMSG_REPLACE,
+                /*arg1*/ 0, /*arg2*/ 0, TAG, UPDATE_CONTEXTUAL_VOLUME_DELAY_MS);
     }
 
-    /**
-     * Manage an audio mode change for audio devices that use an "absolute volume" model,
-     * i.e. the framework sends the full scale signal, and the actual volume for the use case
-     * is communicated separately.
-     */
-    void updateAbsVolumeMultiModeDevices(int oldMode, int newMode) {
-        if (oldMode == newMode) {
-            return;
-        }
-        switch (newMode) {
-            case AudioSystem.MODE_IN_COMMUNICATION:
-            case AudioSystem.MODE_IN_CALL:
-            case AudioSystem.MODE_NORMAL:
-            case AudioSystem.MODE_CALL_SCREENING:
-            case AudioSystem.MODE_CALL_REDIRECT:
-            case AudioSystem.MODE_COMMUNICATION_REDIRECT:
-                break;
-            default:
-                // no-op is enough for all other values
-                return;
-        }
-
-        int streamType = getBluetoothContextualVolumeStream(newMode);
+    private void onUpdateContextualVolumes() {
+        final int streamType = getBluetoothContextualVolumeStream();
 
         final Set<Integer> deviceTypes = getDeviceSetForStreamDirect(streamType);
-        final Set<Integer> absVolumeMultiModeCaseDevices = AudioSystem.intersectionAudioDeviceTypes(
-                mAbsVolumeMultiModeCaseDevices, deviceTypes);
+        final Set<Integer> absVolumeMultiModeCaseDevices =
+                AudioSystem.intersectionAudioDeviceTypes(
+                        mAbsVolumeMultiModeCaseDevices, deviceTypes);
         if (absVolumeMultiModeCaseDevices.isEmpty()) {
             return;
         }
-
-        // handling of specific interfaces goes here:
-        if (AudioSystem.isSingleAudioDeviceType(
-                absVolumeMultiModeCaseDevices, AudioSystem.DEVICE_OUT_HEARING_AID)) {
-            final int index = getStreamVolume(streamType);
-            sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_MODE_CHANGE_HEARING_AID,
-                    newMode, streamType, index));
-            mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
-        }
-    }
-
-    private void setLeAudioVolumeOnModeUpdate(int mode, int device, int streamType, int index,
-            int maxIndex) {
-        switch (mode) {
-            case AudioSystem.MODE_IN_COMMUNICATION:
-            case AudioSystem.MODE_IN_CALL:
-            case AudioSystem.MODE_NORMAL:
-            case AudioSystem.MODE_CALL_SCREENING:
-            case AudioSystem.MODE_CALL_REDIRECT:
-            case AudioSystem.MODE_COMMUNICATION_REDIRECT:
-            case AudioSystem.MODE_RINGTONE:
-                break;
-            default:
-                // no-op is enough for all other values
-                return;
-        }
-
-        // In some cases (like the outgoing or rejected call) the value of 'device' is not
-        // DEVICE_OUT_BLE_* even when BLE is connected. Changing the volume level in such case
-        // may cuase the other devices volume level leaking into the LeAudio device settings.
-        if (!AudioSystem.isLeAudioDeviceType(device)) {
-            Log.w(TAG, "setLeAudioVolumeOnModeUpdate ignoring invalid device="
-                    + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex
-                    + " streamType=" + streamType);
+        if (absVolumeMultiModeCaseDevices.size() > 1) {
+            Log.w(TAG, "onUpdateContextualVolumes too many active devices: "
+                    + absVolumeMultiModeCaseDevices.stream().map(AudioSystem::getOutputDeviceName)
+                        .collect(Collectors.joining(","))
+                    + ", for stream: " + streamType);
             return;
         }
 
+        final int device = absVolumeMultiModeCaseDevices.toArray(new Integer[0])[0].intValue();
+
+        final int index = getStreamVolume(streamType, device);
+
         if (DEBUG_VOL) {
-            Log.d(TAG, "setLeAudioVolumeOnModeUpdate postSetLeAudioVolumeIndex device="
-                    + device + ", mode=" + mode + ", index=" + index + " maxIndex=" + maxIndex
-                    + " streamType=" + streamType);
+            Log.i(TAG, "onUpdateContextualVolumes streamType: " + streamType
+                    + ", device: " + AudioSystem.getOutputDeviceName(device)
+                    + ", index: " + index);
         }
-        mDeviceBroker.postSetLeAudioVolumeIndex(index, maxIndex, streamType);
-        mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "setLeAudioVolumeOnModeUpdate");
+
+        if (AudioSystem.isLeAudioDeviceType(device)) {
+            mDeviceBroker.postSetLeAudioVolumeIndex(index * 10,
+                    mStreamStates[streamType].getMaxIndex(), streamType);
+        } else if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
+            mDeviceBroker.postSetHearingAidVolumeIndex(index * 10, streamType);
+        } else {
+            return;
+        }
+
+        sVolumeLogger.enqueue(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_CONTEXTUAL_VOLUME,
+                mVoicePlaybackActive.get(), streamType, index, device));
     }
 
     private void setStreamVolume(int streamType, int index, int flags,
@@ -4787,7 +4770,7 @@
             mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10);
         } else if (isAbsoluteVolumeDevice(device)
                 && ((flags & AudioManager.FLAG_ABSOLUTE_VOLUME) == 0)) {
-            AbsoluteVolumeDeviceInfo info = mAbsoluteVolumeDeviceInfoMap.get(device);
+            final AbsoluteVolumeDeviceInfo info = getAbsoluteVolumeDeviceInfo(device);
 
             dispatchAbsoluteVolumeChanged(streamType, info, index);
         }
@@ -6222,9 +6205,7 @@
                 updateStreamVolumeAlias(true /*updateVolumes*/, requesterPackage);
 
                 // change of mode may require volume to be re-applied on some devices
-                updateAbsVolumeMultiModeDevices(previousMode, mode);
-
-                setLeAudioVolumeOnModeUpdate(mode, device, streamAlias, index, maxIndex);
+                onUpdateContextualVolumes();
 
                 synchronized (mCachedAbsVolDrivingStreamsLock) {
                     mCachedAbsVolDrivingStreams.replaceAll((absDev, stream) -> {
@@ -7124,6 +7105,11 @@
         return (mMuteAffectedStreams & (1 << streamType)) != 0;
     }
 
+    @Override
+    public boolean isStreamMutableByUi(int streamType) {
+        return (mUserMutableStreams & (1 << streamType)) != 0;
+    }
+
     private void ensureValidDirection(int direction) {
         switch (direction) {
             case AudioManager.ADJUST_LOWER:
@@ -7575,7 +7561,8 @@
         if (register) {
             AbsoluteVolumeDeviceInfo info = new AbsoluteVolumeDeviceInfo(
                     device, volumes, cb, handlesVolumeAdjustment, deviceVolumeBehavior);
-            AbsoluteVolumeDeviceInfo oldInfo = mAbsoluteVolumeDeviceInfoMap.get(deviceOut);
+            final AbsoluteVolumeDeviceInfo oldInfo = getAbsoluteVolumeDeviceInfo(deviceOut);
+
             boolean volumeBehaviorChanged = (oldInfo == null)
                     || (oldInfo.mDeviceVolumeBehavior != deviceVolumeBehavior);
             if (volumeBehaviorChanged) {
@@ -7735,8 +7722,10 @@
         if (mAbsVolumeMultiModeCaseDevices.contains(audioSystemDeviceOut)) {
             return AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE;
         }
-        if (mAbsoluteVolumeDeviceInfoMap.containsKey(audioSystemDeviceOut)) {
-            return mAbsoluteVolumeDeviceInfoMap.get(audioSystemDeviceOut).mDeviceVolumeBehavior;
+        synchronized (mAbsoluteVolumeDeviceInfoMapLock) {
+            if (mAbsoluteVolumeDeviceInfoMap.containsKey(audioSystemDeviceOut)) {
+                return mAbsoluteVolumeDeviceInfoMap.get(audioSystemDeviceOut).mDeviceVolumeBehavior;
+            }
         }
 
         if (isA2dpAbsoluteVolumeDevice(audioSystemDeviceOut)
@@ -9635,6 +9624,9 @@
 
                 case MSG_INIT_SPATIALIZER:
                     onInitSpatializer();
+                    // the device inventory can only be synchronized after the
+                    // spatializer has been initialized
+                    mDeviceBroker.postSynchronizeAdiDevicesInInventory(null);
                     mAudioEventWakeLock.release();
                     break;
 
@@ -9805,6 +9797,10 @@
                     onConfigurationChanged();
                     break;
 
+                case MSG_UPDATE_CONTEXTUAL_VOLUMES:
+                    onUpdateContextualVolumes();
+                    break;
+
                 case MusicFxHelper.MSG_EFFECT_CLIENT_GONE:
                     mMusicFxHelper.handleMessage(msg);
                     break;
@@ -11390,7 +11386,8 @@
 
         deviceState.setAudioDeviceCategory(btAudioDeviceCategory);
 
-        mDeviceBroker.addOrUpdateBtAudioDeviceCategoryInInventory(deviceState);
+        mDeviceBroker.addOrUpdateBtAudioDeviceCategoryInInventory(
+                deviceState, true /*syncInventory*/);
         mDeviceBroker.postPersistAudioDeviceSettings();
 
         mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes(),
@@ -11694,7 +11691,7 @@
     static final int LOG_NB_EVENTS_VOLUME = 100;
     static final int LOG_NB_EVENTS_DYN_POLICY = 10;
     static final int LOG_NB_EVENTS_SPATIAL = 30;
-    static final int LOG_NB_EVENTS_SOUND_DOSE = 30;
+    static final int LOG_NB_EVENTS_SOUND_DOSE = 50;
 
     static final int LOG_NB_EVENTS_LOUDNESS_CODEC = 30;
 
@@ -11774,10 +11771,12 @@
     }
 
     private Set<Integer> getAbsoluteVolumeDevicesWithBehavior(int behavior) {
-        return mAbsoluteVolumeDeviceInfoMap.entrySet().stream()
-                .filter(entry -> entry.getValue().mDeviceVolumeBehavior == behavior)
-                .map(Map.Entry::getKey)
-                .collect(Collectors.toSet());
+        synchronized (mAbsoluteVolumeDeviceInfoMapLock) {
+            return mAbsoluteVolumeDeviceInfoMap.entrySet().stream()
+                    .filter(entry -> entry.getValue().mDeviceVolumeBehavior == behavior)
+                    .map(Map.Entry::getKey)
+                    .collect(Collectors.toSet());
+        }
     }
 
     private String dumpDeviceTypes(@NonNull Set<Integer> deviceTypes) {
@@ -11957,8 +11956,9 @@
         var umi = LocalServices.getService(UserManagerInternal.class);
         var pmsi = LocalServices.getService(PermissionManagerServiceInternal.class);
         var provider = new AudioServerPermissionProvider(packageStates,
-                (Integer uid, String perm) -> (pmsi.checkUidPermission(uid, perm,
-                        Context.DEVICE_ID_DEFAULT) == PackageManager.PERMISSION_GRANTED),
+                (Integer uid, String perm) -> ActivityManager.checkComponentPermission(perm, uid,
+                        /* owningUid = */ -1, /* exported */true)
+                    == PackageManager.PERMISSION_GRANTED,
                 () -> umi.getUserIds()
                 );
         audioPolicy.registerOnStartTask(() -> {
@@ -12101,6 +12101,11 @@
         }
     }
 
+    @Override
+    public VolumePolicy getVolumePolicy() {
+        return mVolumePolicy;
+    }
+
     /** Interface used for enforcing the safe hearing standard. */
     public interface ISafeHearingVolumeController {
         /** Displays an instructional safeguard as required by the safe hearing standard. */
@@ -12320,13 +12325,19 @@
         }
 
         @Override
-        public void addAssistantServiceUid(int uid) {
+        public void addAssistantServiceUid(int uid, int owningUid) {
+            if (audioserverPermissions()) {
+                mPermissionProvider.setIsolatedServiceUid(uid, owningUid);
+            }
             sendMsg(mAudioHandler, MSG_ADD_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE,
                     uid, 0, null, 0);
         }
 
         @Override
         public void removeAssistantServiceUid(int uid) {
+            if (audioserverPermissions()) {
+                mPermissionProvider.clearIsolatedServiceUid(uid);
+            }
             sendMsg(mAudioHandler, MSG_REMOVE_ASSISTANT_SERVICE_UID, SENDMSG_QUEUE,
                     uid, 0, null, 0);
         }
@@ -14270,14 +14281,26 @@
     }
 
     /**
+     * Returns the input device which uses absolute volume behavior, including its variants,
+     * or {@code null} if there is no mapping for the device type
+     */
+    @Nullable
+    private AbsoluteVolumeDeviceInfo getAbsoluteVolumeDeviceInfo(int deviceType) {
+        synchronized (mAbsoluteVolumeDeviceInfoMapLock) {
+            return mAbsoluteVolumeDeviceInfoMap.get(deviceType);
+        }
+    }
+
+    /**
      * Returns whether the input device uses absolute volume behavior, including its variants.
      * For included volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}.
-     *
-     * This is distinct from Bluetooth A2DP absolute volume behavior
+     * <p>This is distinct from Bluetooth A2DP absolute volume behavior
      * ({@link #isA2dpAbsoluteVolumeDevice}).
      */
     private boolean isAbsoluteVolumeDevice(int deviceType) {
-        return mAbsoluteVolumeDeviceInfoMap.containsKey(deviceType);
+        synchronized (mAbsoluteVolumeDeviceInfoMapLock) {
+            return mAbsoluteVolumeDeviceInfoMap.containsKey(deviceType);
+        }
     }
 
     /**
@@ -14389,7 +14412,9 @@
                     + AudioDeviceVolumeManager.volumeBehaviorName(info.mDeviceVolumeBehavior)
             );
         }
-        mAbsoluteVolumeDeviceInfoMap.put(audioSystemDeviceOut, info);
+        synchronized (mAbsoluteVolumeDeviceInfoMapLock) {
+            mAbsoluteVolumeDeviceInfoMap.put(audioSystemDeviceOut, info);
+        }
     }
 
     private AbsoluteVolumeDeviceInfo removeAudioSystemDeviceOutFromAbsVolumeDevices(
@@ -14398,7 +14423,10 @@
             Log.d(TAG, "Removing DeviceType: 0x" + Integer.toHexString(audioSystemDeviceOut)
                     + " from mAbsoluteVolumeDeviceInfoMap");
         }
-        return mAbsoluteVolumeDeviceInfoMap.remove(audioSystemDeviceOut);
+
+        synchronized (mAbsoluteVolumeDeviceInfoMapLock) {
+            return mAbsoluteVolumeDeviceInfoMap.remove(audioSystemDeviceOut);
+        }
     }
 
     //====================
diff --git a/services/core/java/com/android/server/audio/AudioServiceEvents.java b/services/core/java/com/android/server/audio/AudioServiceEvents.java
index 749044e..631d5d8 100644
--- a/services/core/java/com/android/server/audio/AudioServiceEvents.java
+++ b/services/core/java/com/android/server/audio/AudioServiceEvents.java
@@ -227,7 +227,7 @@
         static final int VOL_SET_HEARING_AID_VOL = 3;
         static final int VOL_SET_AVRCP_VOL = 4;
         static final int VOL_ADJUST_VOL_UID = 5;
-        static final int VOL_VOICE_ACTIVITY_HEARING_AID = 6;
+        static final int VOL_VOICE_ACTIVITY_CONTEXTUAL_VOLUME = 6;
         static final int VOL_MODE_CHANGE_HEARING_AID = 7;
         static final int VOL_SET_GROUP_VOL = 8;
         static final int VOL_MUTE_STREAM_INT = 9;
@@ -299,14 +299,14 @@
             logMetricEvent();
         }
 
-        /** used for VOL_VOICE_ACTIVITY_HEARING_AID */
-        VolumeEvent(int op, boolean voiceActive, int stream, int index) {
+        /** used for VOL_VOICE_ACTIVITY_CONTEXTUAL_VOLUME */
+        VolumeEvent(int op, boolean voiceActive, int stream, int index, int device) {
             mOp = op;
             mStream = stream;
             mVal1 = index;
             mVal2 = voiceActive ? 1 : 0;
             // unused
-            mVal3 = -1;
+            mVal3 = device;
             mCaller = null;
             mGroupName = null;
             logMetricEvent();
@@ -445,14 +445,16 @@
                             .set(MediaMetrics.Property.INDEX, mVal1)
                             .record();
                     return;
-                case VOL_VOICE_ACTIVITY_HEARING_AID:
+                case VOL_VOICE_ACTIVITY_CONTEXTUAL_VOLUME:
                     new MediaMetrics.Item(mMetricsId)
-                            .set(MediaMetrics.Property.EVENT, "voiceActivityHearingAid")
+                            .set(MediaMetrics.Property.EVENT, "voiceActivityContextualVolume")
                             .set(MediaMetrics.Property.INDEX, mVal1)
                             .set(MediaMetrics.Property.STATE,
                                     mVal2 == 1 ? "active" : "inactive")
                             .set(MediaMetrics.Property.STREAM_TYPE,
                                     AudioSystem.streamToString(mStream))
+                            .set(MediaMetrics.Property.DEVICE,
+                                    AudioSystem.getOutputDeviceName(mVal3))
                             .record();
                     return;
                 case VOL_MODE_CHANGE_HEARING_AID:
@@ -538,11 +540,12 @@
                             .append(" flags:0x").append(Integer.toHexString(mVal2))
                             .append(") from ").append(mCaller)
                             .toString();
-                case VOL_VOICE_ACTIVITY_HEARING_AID:
+                case VOL_VOICE_ACTIVITY_CONTEXTUAL_VOLUME:
                     return new StringBuilder("Voice activity change (")
                             .append(mVal2 == 1 ? "active" : "inactive")
-                            .append(") causes setting HEARING_AID volume to idx:").append(mVal1)
+                            .append(") causes setting volume to idx:").append(mVal1)
                             .append(" stream:").append(AudioSystem.streamToString(mStream))
+                            .append(" device:").append(AudioSystem.getOutputDeviceName(mVal3))
                             .toString();
                 case VOL_MODE_CHANGE_HEARING_AID:
                     return new StringBuilder("setMode(")
@@ -577,6 +580,7 @@
         static final int DOSE_REPEAT_5X = 2;
         static final int DOSE_ACCUMULATION_START = 3;
         static final int LOWER_VOLUME_TO_RS1 = 4;
+        static final int UPDATE_ABS_VOLUME_ATTENUATION = 5;
 
         final int mEventType;
         final float mFloatValue;
@@ -608,6 +612,10 @@
             return new SoundDoseEvent(LOWER_VOLUME_TO_RS1, 0 /*ignored*/, 0 /*ignored*/);
         }
 
+        static SoundDoseEvent getAbsVolumeAttenuationEvent(float attenuation, int device) {
+            return new SoundDoseEvent(UPDATE_ABS_VOLUME_ATTENUATION, attenuation, device);
+        }
+
         @Override
         public String eventToString() {
             switch (mEventType) {
@@ -623,6 +631,10 @@
                     return "CSD accumulating: RS2 entered";
                 case LOWER_VOLUME_TO_RS1:
                     return "CSD lowering volume to RS1";
+                case UPDATE_ABS_VOLUME_ATTENUATION:
+                    return String.format(java.util.Locale.US,
+                            "Updating CSD absolute volume attenuation on device %d with %.2f dB ",
+                            mLongValue, mFloatValue);
             }
             return new StringBuilder("FIXME invalid event type:").append(mEventType).toString();
         }
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index a346a9b..57bffa7 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -142,7 +142,6 @@
     private static final int SCO_MODE_MAX = 2;
 
     private static final int BT_HEARING_AID_GAIN_MIN = -128;
-    private static final int BT_LE_AUDIO_MIN_VOL = 0;
     private static final int BT_LE_AUDIO_MAX_VOL = 255;
 
     // BtDevice constants currently rolling out under flag protection. Use own
@@ -211,8 +210,7 @@
     //----------------------------------------------------------------------
     // Interface for AudioDeviceBroker
 
-    // @GuardedBy("mDeviceBroker.mSetModeLock")
-    @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+    // Called locked by ADeviceBroker.mSetModeLock -> AudioDeviceBroker.mDeviceStateLock
     /*package*/ synchronized void onSystemReady() {
         mScoConnectionState = android.media.AudioManager.SCO_AUDIO_STATE_ERROR;
         resetBluetoothSco();
@@ -373,12 +371,10 @@
         return codecAndChanged;
     }
 
-    // @GuardedBy("mDeviceBroker.mSetModeLock")
-    @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+    // Called locked by ADeviceBroker.mSetModeLock -> AudioDeviceBroker.mDeviceStateLock
     /*package*/ synchronized void onReceiveBtEvent(Intent intent) {
         final String action = intent.getAction();
 
-        Log.i(TAG, "onReceiveBtEvent action: " + action + " mScoAudioState: " + mScoAudioState);
         if (action.equals(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED)) {
             BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE,
                     android.bluetooth.BluetoothDevice.class);
@@ -397,77 +393,67 @@
     }
 
     /**
-     * Exclusively called from AudioDeviceBroker when handling MSG_L_RECEIVED_BT_EVENT
+     * Exclusively called from AudioDeviceBroker (with mSetModeLock held)
+     * when handling MSG_L_RECEIVED_BT_EVENT in {@link #onReceiveBtEvent(Intent)}
      * as part of the serialization of the communication route selection
      */
-    // @GuardedBy("mDeviceBroker.mSetModeLock")
-    @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+    @GuardedBy("BtHelper.this")
     private void onScoAudioStateChanged(int state) {
         boolean broadcast = false;
         int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR;
-        if (mDeviceBroker.isScoManagedByAudio()) {
-            switch (state) {
-                case BluetoothHeadset.STATE_AUDIO_CONNECTED:
-                    mDeviceBroker.setBluetoothScoOn(true, "BtHelper.onScoAudioStateChanged");
-                    scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTED;
+        Log.i(TAG, "onScoAudioStateChanged  state: " + state
+                + ", mScoAudioState: " + mScoAudioState);
+        switch (state) {
+            case BluetoothHeadset.STATE_AUDIO_CONNECTED:
+                scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTED;
+                if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL
+                        && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
+                    mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
+                } else if (mDeviceBroker.isBluetoothScoRequested()) {
+                    // broadcast intent if the connection was initated by AudioService
                     broadcast = true;
-                    break;
-                case BluetoothHeadset.STATE_AUDIO_DISCONNECTED:
-                    mDeviceBroker.setBluetoothScoOn(false, "BtHelper.onScoAudioStateChanged");
-                    scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED;
-                    broadcast = true;
-                    break;
-                default:
-                    break;
-            }
-        } else {
-            switch (state) {
-                case BluetoothHeadset.STATE_AUDIO_CONNECTED:
-                    scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTED;
-                    if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL
-                            && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
-                        mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
-                    } else if (mDeviceBroker.isBluetoothScoRequested()) {
-                        // broadcast intent if the connection was initated by AudioService
-                        broadcast = true;
-                    }
+                }
+                if (!mDeviceBroker.isScoManagedByAudio()) {
                     mDeviceBroker.setBluetoothScoOn(true, "BtHelper.onScoAudioStateChanged");
-                    break;
-                case BluetoothHeadset.STATE_AUDIO_DISCONNECTED:
+                }
+                break;
+            case BluetoothHeadset.STATE_AUDIO_DISCONNECTED:
+                if (!mDeviceBroker.isScoManagedByAudio()) {
                     mDeviceBroker.setBluetoothScoOn(false, "BtHelper.onScoAudioStateChanged");
-                    scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED;
-                    // There are two cases where we want to immediately reconnect audio:
-                    // 1) If a new start request was received while disconnecting: this was
-                    // notified by requestScoState() setting state to SCO_STATE_ACTIVATE_REQ.
-                    // 2) If audio was connected then disconnected via Bluetooth APIs and
-                    // we still have pending activation requests by apps: this is indicated by
-                    // state SCO_STATE_ACTIVE_EXTERNAL and BT SCO is requested.
-                    if (mScoAudioState == SCO_STATE_ACTIVATE_REQ) {
-                        if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null
-                                && connectBluetoothScoAudioHelper(mBluetoothHeadset,
-                                mBluetoothHeadsetDevice, mScoAudioMode)) {
-                            mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
-                            scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTING;
-                            broadcast = true;
-                            break;
-                        }
-                    }
-                    if (mScoAudioState != SCO_STATE_ACTIVE_EXTERNAL) {
+                }
+                scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED;
+                // There are two cases where we want to immediately reconnect audio:
+                // 1) If a new start request was received while disconnecting: this was
+                // notified by requestScoState() setting state to SCO_STATE_ACTIVATE_REQ.
+                // 2) If audio was connected then disconnected via Bluetooth APIs and
+                // we still have pending activation requests by apps: this is indicated by
+                // state SCO_STATE_ACTIVE_EXTERNAL and BT SCO is requested.
+                if (mScoAudioState == SCO_STATE_ACTIVATE_REQ) {
+                    if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null
+                            && connectBluetoothScoAudioHelper(mBluetoothHeadset,
+                            mBluetoothHeadsetDevice, mScoAudioMode)) {
+                        mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
+                        scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTING;
                         broadcast = true;
+                        break;
                     }
-                    mScoAudioState = SCO_STATE_INACTIVE;
-                    break;
-                case BluetoothHeadset.STATE_AUDIO_CONNECTING:
-                    if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL
-                            && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
-                        mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
-                    }
-                    break;
-                default:
-                    break;
-            }
+                }
+                if (mScoAudioState != SCO_STATE_ACTIVE_EXTERNAL) {
+                    broadcast = true;
+                }
+                mScoAudioState = SCO_STATE_INACTIVE;
+                break;
+            case BluetoothHeadset.STATE_AUDIO_CONNECTING:
+                if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL
+                        && mScoAudioState != SCO_STATE_DEACTIVATE_REQ) {
+                    mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL;
+                }
+                break;
+            default:
+                break;
         }
         if (broadcast) {
+            Log.i(TAG, "onScoAudioStateChanged  broadcasting state: " + scoAudioState);
             broadcastScoConnectionState(scoAudioState);
             //FIXME: this is to maintain compatibility with deprecated intent
             // AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED. Remove when appropriate.
@@ -493,16 +479,19 @@
         return false;
     }
 
-    // @GuardedBy("mDeviceBroker.mSetModeLock")
-    @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+    /*package*/ synchronized boolean isBluetoothScoRequestedInternally() {
+        return mScoAudioState == SCO_STATE_ACTIVE_INTERNAL
+              || mScoAudioState == SCO_STATE_ACTIVATE_REQ;
+    }
+
+    // Called locked by ADeviceBroker.mSetModeLock -> AudioDeviceBroker.mDeviceStateLock
     /*package*/ synchronized boolean startBluetoothSco(int scoAudioMode,
                 @NonNull String eventSource) {
         AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(eventSource));
         return requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, scoAudioMode);
     }
 
-    // @GuardedBy("mDeviceBroker.mSetModeLock")
-    @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+    // Called locked by ADeviceBroker.mSetModeLock -> AudioDeviceBroker.mDeviceStateLock
     /*package*/ synchronized boolean stopBluetoothSco(@NonNull String eventSource) {
         AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(eventSource));
         return requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, SCO_MODE_VIRTUAL_CALL);
@@ -574,8 +563,7 @@
         mScoConnectionState = state;
     }
 
-    // @GuardedBy("mDeviceBroker.mSetModeLock")
-    @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+    // Called locked by ADeviceBroker.mSetModeLock -> AudioDeviceBroker.mDeviceStateLock
     /*package*/ synchronized void resetBluetoothSco() {
         mScoAudioState = SCO_STATE_INACTIVE;
         broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
@@ -584,8 +572,7 @@
         mDeviceBroker.setBluetoothScoOn(false, "resetBluetoothSco");
     }
 
-    // @GuardedBy("mDeviceBroker.mSetModeLock")
-    @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+    // Called locked by ADeviceBroker.mSetModeLock -> AudioDeviceBroker.mDeviceStateLock
     /*package*/ synchronized void onBtProfileDisconnected(int profile) {
         AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
                 "BT profile " + BluetoothProfile.getProfileName(profile)
@@ -649,8 +636,7 @@
 
     MyLeAudioCallback mLeAudioCallback = null;
 
-    // @GuardedBy("mDeviceBroker.mSetModeLock")
-    @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+    // Called locked by ADeviceBroker.mSetModeLock -> AudioDeviceBroker.mDeviceStateLock
     /*package*/ synchronized void onBtProfileConnected(int profile, BluetoothProfile proxy) {
         AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
                 "BT profile " + BluetoothProfile.getProfileName(profile) + " connected to proxy "
@@ -787,8 +773,7 @@
         }
     }
 
-    // @GuardedBy("mDeviceBroker.mSetModeLock")
-    @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+    // Called locked by ADeviceBroker.mSetModeLock -> AudioDeviceBroker.mDeviceStateLock
     private void onHeadsetProfileConnected(@NonNull BluetoothHeadset headset) {
         // Discard timeout message
         mDeviceBroker.handleCancelFailureToConnectToBtHeadsetService();
@@ -931,8 +916,7 @@
         return btDevice == null ? "(null)" : btDevice.getAnonymizedAddress();
     }
 
-    // @GuardedBy("mDeviceBroker.mSetModeLock")
-    @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
+    // Called locked by ADeviceBroker.mSetModeLock -> AudioDeviceBroker.mDeviceStateLock
     /*package */ synchronized void onSetBtScoActiveDevice(BluetoothDevice btDevice) {
         Log.i(TAG, "onSetBtScoActiveDevice: " + getAnonymizedAddress(mBluetoothHeadsetDevice)
                 + " -> " + getAnonymizedAddress(btDevice));
@@ -1133,6 +1117,9 @@
 
     //-----------------------------------------------------
     // Utilities
+
+    // suppress warning due to generic Intent passed as param
+    @SuppressWarnings("AndroidFrameworkRequiresPermission")
     private void sendStickyBroadcastToAll(Intent intent) {
         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         final long ident = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index d26ba48..88268cd 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -662,8 +662,7 @@
         synchronized(mPlayerLock) {
             pw.println("\n  playback listeners:");
             for (PlayMonitorClient pmc : mClients) {
-                pw.print(" " + (pmc.isPrivileged() ? "(S)" : "(P)")
-                        + pmc.toString());
+                pw.println(" " + pmc);
             }
             pw.println("\n");
             // all players
@@ -1031,7 +1030,8 @@
         if (pcdb == null) {
             return;
         }
-        final PlayMonitorClient pmc = new PlayMonitorClient(pcdb, isPrivileged);
+        final PlayMonitorClient pmc = new PlayMonitorClient(pcdb, isPrivileged,
+                Binder.getCallingUid(), Binder.getCallingPid());
         if (pmc.init()) {
             mClients.add(pmc);
         }
@@ -1103,10 +1103,22 @@
         private boolean mIsReleased = false;
         @GuardedBy("this")
         private int mErrorCount = 0;
+        private final int mUid;
+        private final int mPid;
 
-        PlayMonitorClient(IPlaybackConfigDispatcher pcdb, boolean isPrivileged) {
+        PlayMonitorClient(IPlaybackConfigDispatcher pcdb, boolean isPrivileged,
+                int uid, int pid) {
             mDispatcherCb = pcdb;
             mIsPrivileged = isPrivileged;
+            mUid = uid;
+            mPid = pid;
+        }
+
+        @Override
+        public String toString() {
+            return "PlayMonitorClient:"
+                    + (isPrivileged() ? "S" : "P")
+                    + " uid:" + mUid + " pid:" + mPid;
         }
 
         @Override
diff --git a/services/core/java/com/android/server/audio/SoundDoseHelper.java b/services/core/java/com/android/server/audio/SoundDoseHelper.java
index e28ae95..ded93e6 100644
--- a/services/core/java/com/android/server/audio/SoundDoseHelper.java
+++ b/services/core/java/com/android/server/audio/SoundDoseHelper.java
@@ -39,6 +39,7 @@
 import android.media.ISoundDose;
 import android.media.ISoundDoseCallback;
 import android.media.SoundDoseRecord;
+import android.media.VolumeInfo;
 import android.os.Binder;
 import android.os.Message;
 import android.os.RemoteException;
@@ -642,9 +643,9 @@
             if (index > safeIndex) {
                 streamState.setIndex(safeIndex, deviceType, caller,
                         true /*hasModifyAudioSettings*/);
-                mAudioHandler.sendMessageAtTime(
+                mAudioHandler.sendMessage(
                         mAudioHandler.obtainMessage(MSG_SET_DEVICE_VOLUME, deviceType,
-                                /*arg2=*/0, streamState), /*delay=*/0);
+                                /*arg2=*/0, streamState));
             }
         }
     }
@@ -685,8 +686,11 @@
     /*package*/ void disableSafeMediaVolume(String callingPackage) {
         synchronized (mSafeMediaVolumeStateLock) {
             final long identity = Binder.clearCallingIdentity();
-            setSafeMediaVolumeEnabled(false, callingPackage);
-            Binder.restoreCallingIdentity(identity);
+            try {
+                setSafeMediaVolumeEnabled(false, callingPackage);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
 
             if (mPendingVolumeCommand != null) {
                 mAudioService.onSetStreamVolume(mPendingVolumeCommand.mStreamType,
@@ -700,6 +704,7 @@
         }
     }
 
+    @SuppressWarnings("AndroidFrameworkRequiresPermission")
     /*package*/ void scheduleMusicActiveCheck() {
         synchronized (mSafeMediaVolumeStateLock) {
             cancelMusicActiveCheck();
@@ -895,6 +900,8 @@
 
         try {
             if (!isAbsoluteVolume) {
+                mLogger.enqueue(
+                        SoundDoseEvent.getAbsVolumeAttenuationEvent(/*attenuation=*/0.f, device));
                 // remove any possible previous attenuation
                 soundDose.updateAttenuation(/* attenuationDB= */0.f, device);
 
@@ -903,10 +910,11 @@
 
             if (AudioService.mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC
                     && safeDevicesContains(device)) {
-                soundDose.updateAttenuation(
-                        -AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_MUSIC,
-                                (newIndex + 5) / 10,
-                                device), device);
+                float attenuationDb = -AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_MUSIC,
+                        (newIndex + 5) / 10, device);
+                mLogger.enqueue(
+                        SoundDoseEvent.getAbsVolumeAttenuationEvent(attenuationDb, device));
+                soundDose.updateAttenuation(attenuationDb, device);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Could not apply the attenuation for MEL calculation with volume index "
@@ -1031,10 +1039,9 @@
             mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_DISABLED;
         }
 
-        mAudioHandler.sendMessageAtTime(
+        mAudioHandler.sendMessage(
                 mAudioHandler.obtainMessage(MSG_PERSIST_SAFE_VOLUME_STATE,
-                        persistedState, /*arg2=*/0,
-                        /*obj=*/null), /*delay=*/0);
+                        persistedState, /*arg2=*/0, /*obj=*/null));
     }
 
     private void updateCsdEnabled(String caller) {
@@ -1195,8 +1202,8 @@
 
         sanitizeDoseRecords_l();
 
-        mAudioHandler.sendMessageAtTime(mAudioHandler.obtainMessage(MSG_PERSIST_CSD_VALUES,
-                /* arg1= */0, /* arg2= */0, /* obj= */null), /* delay= */0);
+        mAudioHandler.sendMessage(mAudioHandler.obtainMessage(MSG_PERSIST_CSD_VALUES,
+                /* arg1= */0, /* arg2= */0, /* obj= */null));
 
         mLogger.enqueue(SoundDoseEvent.getDoseUpdateEvent(currentCsd, totalDuration));
     }
@@ -1312,23 +1319,32 @@
     }
 
     /** Called when handling MSG_LOWER_VOLUME_TO_RS1 */
+    @SuppressWarnings("AndroidFrameworkRequiresPermission")
     private void onLowerVolumeToRs1() {
-        mLogger.enqueue(SoundDoseEvent.getLowerVolumeToRs1Event());
         final ArrayList<AudioDeviceAttributes> devices = mAudioService.getDevicesForAttributesInt(
-                new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build(), true);
-        final int nativeDeviceType;
-        final AudioDeviceAttributes ada;
-        if (!devices.isEmpty()) {
-            ada = devices.get(0);
-            nativeDeviceType = ada.getInternalType();
-        } else {
-            nativeDeviceType = AudioSystem.DEVICE_OUT_USB_HEADSET;
-            ada = new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_USB_HEADSET, "");
+                new AudioAttributes.Builder().setUsage(
+                        AudioAttributes.USAGE_MEDIA).build(), /*forVolume=*/true);
+        if (devices.isEmpty()) {
+            Log.e(TAG, "Cannot lower the volume to RS1, no devices registered for USAGE_MEDIA");
+            return;
         }
-        final int index = safeMediaVolumeIndex(nativeDeviceType);
-        mAudioService.setStreamVolumeWithAttributionInt(STREAM_MUSIC, index / 10, /*flags*/ 0, ada,
-                mContext.getOpPackageName(), /*attributionTag=*/null,
-                true /*canChangeMuteAndUpdateController*/);
+        final AudioDeviceAttributes ada = devices.get(0);
+        final int nativeDeviceType = ada.getInternalType();
+        final int index = safeMediaVolumeIndex(nativeDeviceType) / 10;
+        final VolumeInfo curVolume = mAudioService.getDeviceVolume(
+                new VolumeInfo.Builder(STREAM_MUSIC).build(), ada,
+                /*callingPackage=*/"sounddosehelper");
+
+        if (index < curVolume.getVolumeIndex()) {
+            mLogger.enqueue(SoundDoseEvent.getLowerVolumeToRs1Event());
+            mAudioService.setStreamVolumeWithAttributionInt(STREAM_MUSIC, index, /*flags*/ 0, ada,
+                    mContext.getOpPackageName(), /*attributionTag=*/null,
+                    /*canChangeMuteAndUpdateController=*/true);
+        } else {
+            Log.i(TAG, "The current volume " + curVolume.getVolumeIndex()
+                    + " for device type " + nativeDeviceType
+                    + " is already smaller or equal to the safe index volume " + index);
+        }
     }
 
     // StreamVolumeCommand contains the information needed to defer the process of
@@ -1348,9 +1364,9 @@
 
         @Override
         public String toString() {
-            return new StringBuilder().append("{streamType=").append(mStreamType).append(",index=")
-                    .append(mIndex).append(",flags=").append(mFlags).append(",device=")
-                    .append(mDevice).append('}').toString();
+            return "{streamType=" + mStreamType
+                    + ",index=" + mIndex + ",flags=" + mFlags
+                    + ",device=" + mDevice + "}";
         }
     }
 }
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index cae1695..9265ff2 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -568,7 +568,8 @@
             updatedDevice = new AdiDeviceState(canonicalDeviceType, ada.getInternalType(),
                     ada.getAddress());
             initSAState(updatedDevice);
-            mDeviceBroker.addOrUpdateDeviceSAStateInInventory(updatedDevice);
+            mDeviceBroker.addOrUpdateDeviceSAStateInInventory(
+                    updatedDevice, true /*syncInventory*/);
         }
         if (updatedDevice != null) {
             onRoutingUpdated();
@@ -723,7 +724,7 @@
                     new AdiDeviceState(canonicalDeviceType, ada.getInternalType(),
                             ada.getAddress());
             initSAState(deviceState);
-            mDeviceBroker.addOrUpdateDeviceSAStateInInventory(deviceState);
+            mDeviceBroker.addOrUpdateDeviceSAStateInInventory(deviceState, true /*syncInventory*/);
             mDeviceBroker.postPersistAudioDeviceSettings();
             logDeviceState(deviceState, "addWirelessDeviceIfNew"); // may be updated later.
         }
diff --git a/services/core/java/com/android/server/backup/AppSpecificLocalesBackupHelper.java b/services/core/java/com/android/server/backup/AppSpecificLocalesBackupHelper.java
index 1726da2..a83813f 100644
--- a/services/core/java/com/android/server/backup/AppSpecificLocalesBackupHelper.java
+++ b/services/core/java/com/android/server/backup/AppSpecificLocalesBackupHelper.java
@@ -18,6 +18,8 @@
 
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
+import android.app.backup.BackupRestoreEventLogger.BackupRestoreError;
+import android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType;
 import android.app.backup.BlobBackupHelper;
 import android.util.Slog;
 
@@ -33,6 +35,16 @@
     private static final String TAG = "AppLocalesBackupHelper";   // must be < 23 chars
     private static final boolean DEBUG = false;
 
+    @BackupRestoreDataType
+    private static final String DATA_TYPE_APP_LOCALES = "app_locales:locales";
+
+    @BackupRestoreError
+    private static final String ERROR_UNEXPECTED_KEY = "unexpected_key";
+    @BackupRestoreError
+    private static final String ERROR_BACKUP_FAILED = "backup_failed";
+    @BackupRestoreError
+    private static final String ERROR_RESTORE_FAILED = "restore_failed";
+
     // Current version of the blob schema
     private static final int BLOB_VERSION = 1;
 
@@ -59,13 +71,24 @@
         if (KEY_APP_LOCALES.equals(key)) {
             try {
                 newPayload = mLocaleManagerInternal.getBackupPayload(mUserId);
+                getLogger().logItemsBackedUp(
+                        DATA_TYPE_APP_LOCALES,
+                        /* count= */ 1);
             } catch (Exception e) {
                 // Treat as no data
                 Slog.e(TAG, "Couldn't communicate with locale manager", e);
+                getLogger().logItemsBackupFailed(
+                        DATA_TYPE_APP_LOCALES,
+                        /* count= */ 1,
+                        ERROR_BACKUP_FAILED);
                 newPayload = null;
             }
         } else {
             Slog.w(TAG, "Unexpected backup key " + key);
+            getLogger().logItemsBackupFailed(
+                    DATA_TYPE_APP_LOCALES,
+                    /* count= */ 1,
+                    ERROR_UNEXPECTED_KEY);
         }
         return newPayload;
     }
@@ -79,11 +102,22 @@
         if (KEY_APP_LOCALES.equals(key)) {
             try {
                 mLocaleManagerInternal.stageAndApplyRestoredPayload(payload, mUserId);
+                getLogger().logItemsRestored(
+                        DATA_TYPE_APP_LOCALES,
+                        /* count= */ 1);
             } catch (Exception e) {
                 Slog.e(TAG, "Couldn't communicate with locale manager", e);
+                getLogger().logItemsRestoreFailed(
+                        DATA_TYPE_APP_LOCALES,
+                        /* count= */ 1,
+                        ERROR_RESTORE_FAILED);
             }
         } else {
             Slog.w(TAG, "Unexpected restore key " + key);
+            getLogger().logItemsBackupFailed(
+                    DATA_TYPE_APP_LOCALES,
+                    /* count= */ 1,
+                    ERROR_UNEXPECTED_KEY);
         }
     }
 
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 0e81eb9..8e8a037 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -31,8 +31,8 @@
 import android.app.UserSwitchObserver;
 import android.app.admin.DevicePolicyManager;
 import android.app.trust.ITrustManager;
-import android.content.ContentResolver;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
@@ -233,6 +233,7 @@
         private static final boolean DEFAULT_KEYGUARD_ENABLED = true;
         private static final boolean DEFAULT_APP_ENABLED = true;
         private static final boolean DEFAULT_ALWAYS_REQUIRE_CONFIRMATION = false;
+        private static final boolean DEFAULT_MANDATORY_BIOMETRICS_STATUS = false;
 
         // Some devices that shipped before S already have face-specific settings. Instead of
         // migrating, which is complicated, let's just keep using the existing settings.
@@ -253,6 +254,8 @@
                 Settings.Secure.getUriFor(Settings.Secure.BIOMETRIC_KEYGUARD_ENABLED);
         private final Uri BIOMETRIC_APP_ENABLED =
                 Settings.Secure.getUriFor(Settings.Secure.BIOMETRIC_APP_ENABLED);
+        private final Uri MANDATORY_BIOMETRICS_ENABLED =
+                Settings.Secure.getUriFor(Settings.Secure.MANDATORY_BIOMETRICS);
 
         private final ContentResolver mContentResolver;
         private final List<BiometricService.EnabledOnKeyguardCallback> mCallbacks;
@@ -260,6 +263,7 @@
         private final Map<Integer, Boolean> mBiometricEnabledOnKeyguard = new HashMap<>();
         private final Map<Integer, Boolean> mBiometricEnabledForApps = new HashMap<>();
         private final Map<Integer, Boolean> mFaceAlwaysRequireConfirmation = new HashMap<>();
+        private final Map<Integer, Boolean> mMandatoryBiometricsEnabled = new HashMap<>();
 
         /**
          * Creates a content observer.
@@ -281,6 +285,9 @@
             mUseLegacyFaceOnlySettings =
                     Build.VERSION.DEVICE_INITIAL_SDK_INT <= Build.VERSION_CODES.Q
                     && hasFace && !hasFingerprint;
+            mMandatoryBiometricsEnabled.put(context.getUserId(), Settings.Secure.getIntForUser(
+                    mContentResolver, Settings.Secure.MANDATORY_BIOMETRICS,
+                    DEFAULT_MANDATORY_BIOMETRICS_STATUS ? 1 : 0, context.getUserId()) != 0);
 
             updateContentObserver();
         }
@@ -311,6 +318,10 @@
                     false /* notifyForDescendants */,
                     this /* observer */,
                     UserHandle.USER_ALL);
+            mContentResolver.registerContentObserver(MANDATORY_BIOMETRICS_ENABLED,
+                    false /* notifyForDescendants */,
+                    this /* observer */,
+                    UserHandle.USER_ALL);
         }
 
         @Override
@@ -353,6 +364,12 @@
                         Settings.Secure.BIOMETRIC_APP_ENABLED,
                         DEFAULT_APP_ENABLED ? 1 : 0 /* default */,
                         userId) != 0);
+            } else if (MANDATORY_BIOMETRICS_ENABLED.equals(uri)) {
+                mMandatoryBiometricsEnabled.put(userId, Settings.Secure.getIntForUser(
+                        mContentResolver,
+                        Settings.Secure.MANDATORY_BIOMETRICS,
+                        DEFAULT_MANDATORY_BIOMETRICS_STATUS ? 1 : 0 /* default */,
+                        userId) != 0);
             }
         }
 
@@ -394,6 +411,11 @@
             }
         }
 
+        public boolean getMandatoryBiometricsEnabledForUser(int userId) {
+            return mMandatoryBiometricsEnabled.getOrDefault(userId,
+                    DEFAULT_MANDATORY_BIOMETRICS_STATUS);
+        }
+
         void notifyEnabledOnKeyguardCallbacks(int userId) {
             List<EnabledOnKeyguardCallback> callbacks = mCallbacks;
             for (int i = 0; i < callbacks.size(); i++) {
diff --git a/services/core/java/com/android/server/biometrics/PreAuthInfo.java b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
index f085647..b9e6563 100644
--- a/services/core/java/com/android/server/biometrics/PreAuthInfo.java
+++ b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
@@ -29,11 +29,13 @@
 import android.content.Context;
 import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricManager;
+import android.hardware.biometrics.Flags;
 import android.hardware.biometrics.PromptInfo;
 import android.os.RemoteException;
 import android.util.Pair;
 import android.util.Slog;
 
+import com.android.internal.R;
 import com.android.server.biometrics.sensors.LockoutTracker;
 
 import java.lang.annotation.Retention;
@@ -59,6 +61,7 @@
     static final int BIOMETRIC_LOCKOUT_TIMED = 10;
     static final int BIOMETRIC_LOCKOUT_PERMANENT = 11;
     static final int BIOMETRIC_SENSOR_PRIVACY_ENABLED = 12;
+    static final int MANDATORY_BIOMETRIC_UNAVAILABLE_ERROR = 13;
     private static final String TAG = "BiometricService/PreAuthInfo";
     final boolean credentialRequested;
     // Sensors that can be used for this request (e.g. strong enough, enrolled, enabled).
@@ -73,12 +76,14 @@
     private final boolean mBiometricRequested;
     private final int mBiometricStrengthRequested;
     private final BiometricCameraManager mBiometricCameraManager;
+    private final boolean mOnlyMandatoryBiometricsRequested;
 
     private PreAuthInfo(boolean biometricRequested, int biometricStrengthRequested,
             boolean credentialRequested, List<BiometricSensor> eligibleSensors,
             List<Pair<BiometricSensor, Integer>> ineligibleSensors, boolean credentialAvailable,
-            boolean confirmationRequested, boolean ignoreEnrollmentState, int userId,
-            Context context, BiometricCameraManager biometricCameraManager) {
+            PromptInfo promptInfo, int userId, Context context,
+            BiometricCameraManager biometricCameraManager,
+            boolean isOnlyMandatoryBiometricsRequested) {
         mBiometricRequested = biometricRequested;
         mBiometricStrengthRequested = biometricStrengthRequested;
         mBiometricCameraManager = biometricCameraManager;
@@ -87,10 +92,11 @@
         this.eligibleSensors = eligibleSensors;
         this.ineligibleSensors = ineligibleSensors;
         this.credentialAvailable = credentialAvailable;
-        this.confirmationRequested = confirmationRequested;
-        this.ignoreEnrollmentState = ignoreEnrollmentState;
+        this.confirmationRequested = promptInfo.isConfirmationRequested();
+        this.ignoreEnrollmentState = promptInfo.isIgnoreEnrollmentState();
         this.userId = userId;
         this.context = context;
+        this.mOnlyMandatoryBiometricsRequested = isOnlyMandatoryBiometricsRequested;
     }
 
     static PreAuthInfo create(ITrustManager trustManager,
@@ -102,7 +108,16 @@
             BiometricCameraManager biometricCameraManager)
             throws RemoteException {
 
-        final boolean confirmationRequested = promptInfo.isConfirmationRequested();
+        final boolean isOnlyMandatoryBiometricsRequested = promptInfo.getAuthenticators()
+                == BiometricManager.Authenticators.MANDATORY_BIOMETRICS;
+
+        if (dropCredentialFallback(promptInfo.getAuthenticators(),
+                settingObserver.getMandatoryBiometricsEnabledForUser(userId),
+                trustManager)) {
+            promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG);
+            promptInfo.setNegativeButtonText(context.getString(R.string.cancel));
+        }
+
         final boolean biometricRequested = Utils.isBiometricRequested(promptInfo);
         final int requestedStrength = Utils.getPublicBiometricStrength(promptInfo);
         final boolean credentialRequested = Utils.isCredentialRequested(promptInfo);
@@ -150,8 +165,27 @@
         }
 
         return new PreAuthInfo(biometricRequested, requestedStrength, credentialRequested,
-                eligibleSensors, ineligibleSensors, credentialAvailable, confirmationRequested,
-                promptInfo.isIgnoreEnrollmentState(), userId, context, biometricCameraManager);
+                eligibleSensors, ineligibleSensors, credentialAvailable, promptInfo, userId,
+                context, biometricCameraManager, isOnlyMandatoryBiometricsRequested);
+    }
+
+    private static boolean dropCredentialFallback(int authenticators,
+            boolean isMandatoryBiometricsEnabled, ITrustManager trustManager) {
+        final boolean isMandatoryBiometricsRequested =
+                (authenticators & BiometricManager.Authenticators.MANDATORY_BIOMETRICS)
+                        == BiometricManager.Authenticators.MANDATORY_BIOMETRICS;
+        if (Flags.mandatoryBiometrics() && isMandatoryBiometricsEnabled
+                && isMandatoryBiometricsRequested) {
+            try {
+                final boolean isInSignificantPlace = trustManager.isInSignificantPlace();
+                return !isInSignificantPlace;
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote exception while trying to check "
+                        + "if user is in a trusted location.");
+            }
+        }
+
+        return false;
     }
 
     /**
@@ -353,6 +387,25 @@
                     status = CREDENTIAL_NOT_ENROLLED;
                 }
             }
+        } else if (Flags.mandatoryBiometrics() && mOnlyMandatoryBiometricsRequested) {
+            if (!eligibleSensors.isEmpty()) {
+                for (BiometricSensor sensor : eligibleSensors) {
+                    modality |= sensor.modality;
+                }
+
+                if (modality == TYPE_FACE && cameraPrivacyEnabled) {
+                    // If the only modality requested is face, credential is unavailable,
+                    // and the face sensor privacy is enabled then return
+                    // BIOMETRIC_SENSOR_PRIVACY_ENABLED.
+                    //
+                    // Note: This sensor will not be eligible for calls to authenticate.
+                    status = BIOMETRIC_SENSOR_PRIVACY_ENABLED;
+                } else {
+                    status = AUTHENTICATOR_OK;
+                }
+            } else {
+                status = MANDATORY_BIOMETRIC_UNAVAILABLE_ERROR;
+            }
         } else if (mBiometricRequested) {
             if (!eligibleSensors.isEmpty()) {
                 for (BiometricSensor sensor : eligibleSensors) {
@@ -509,7 +562,8 @@
             CREDENTIAL_NOT_ENROLLED,
             BIOMETRIC_LOCKOUT_TIMED,
             BIOMETRIC_LOCKOUT_PERMANENT,
-            BIOMETRIC_SENSOR_PRIVACY_ENABLED})
+            BIOMETRIC_SENSOR_PRIVACY_ENABLED,
+            MANDATORY_BIOMETRIC_UNAVAILABLE_ERROR})
     @Retention(RetentionPolicy.SOURCE)
     @interface AuthenticatorStatus {
     }
diff --git a/services/core/java/com/android/server/biometrics/Utils.java b/services/core/java/com/android/server/biometrics/Utils.java
index 4af30a9..df29ca4 100644
--- a/services/core/java/com/android/server/biometrics/Utils.java
+++ b/services/core/java/com/android/server/biometrics/Utils.java
@@ -140,6 +140,14 @@
     }
 
     /**
+     * @param authenticators composed of one or more values from {@link Authenticators}
+     * @return true if mandatory biometrics is requested
+     */
+    static boolean isMandatoryBiometricsRequested(@Authenticators.Types int authenticators) {
+        return (authenticators & Authenticators.MANDATORY_BIOMETRICS) != 0;
+    }
+
+    /**
      * @param promptInfo should be first processed by
      * {@link #combineAuthenticatorBundles(PromptInfo)}
      * @return true if device credential is allowed.
@@ -242,7 +250,8 @@
         // Check if any of the non-biometric and non-credential bits are set. If so, this is
         // invalid.
         final int testBits = ~(Authenticators.DEVICE_CREDENTIAL
-                | Authenticators.BIOMETRIC_MIN_STRENGTH);
+                | Authenticators.BIOMETRIC_MIN_STRENGTH
+                | Authenticators.MANDATORY_BIOMETRICS);
         if ((authenticators & testBits) != 0) {
             Slog.e(BiometricService.TAG, "Non-biometric, non-credential bits found."
                     + " Authenticators: " + authenticators);
@@ -259,6 +268,8 @@
             return true;
         } else if (biometricBits == Authenticators.BIOMETRIC_WEAK) {
             return true;
+        } else if (isMandatoryBiometricsRequested(authenticators)) {
+            return true;
         }
 
         Slog.e(BiometricService.TAG, "Unsupported biometric flags. Authenticators: "
diff --git a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
index d061e2d..fbd32a6 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
@@ -31,7 +31,6 @@
 
 import com.android.server.biometrics.log.BiometricContext;
 import com.android.server.biometrics.log.BiometricLogger;
-import com.android.server.biometrics.sensors.fingerprint.aidl.AidlSession;
 
 import java.util.function.Supplier;
 
@@ -203,16 +202,6 @@
         }
     }
 
-    // TODO(b/317414324): Deprecate setIgnoreDisplayTouches
-    protected final void resetIgnoreDisplayTouches() {
-        final AidlSession session = (AidlSession) getFreshDaemon();
-        try {
-            session.getSession().setIgnoreDisplayTouches(false);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Remote exception when resetting setIgnoreDisplayTouches");
-        }
-    }
-
     @Override
     public boolean isInterruptable() {
         return true;
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java b/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java
index eb78fe6..a118415 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java
@@ -20,7 +20,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.hardware.biometrics.BiometricConstants;
-import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -28,11 +27,12 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
+import com.android.modules.expresslog.Counter;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Arrays;
-import java.util.function.BooleanSupplier;
+
 
 /**
  * Contains all the necessary information for a HAL operation.
@@ -89,8 +89,6 @@
     private final BaseClientMonitor mClientMonitor;
     @Nullable
     private final ClientMonitorCallback mClientCallback;
-    @NonNull
-    private final BooleanSupplier mIsDebuggable;
     @Nullable
     private ClientMonitorCallback mOnStartCallback;
     @OperationState
@@ -99,6 +97,7 @@
     @NonNull
     final Runnable mCancelWatchdog;
 
+    @VisibleForTesting
     BiometricSchedulerOperation(
             @NonNull BaseClientMonitor clientMonitor,
             @Nullable ClientMonitorCallback callback
@@ -106,33 +105,14 @@
         this(clientMonitor, callback, STATE_WAITING_IN_QUEUE);
     }
 
-    @VisibleForTesting
-    BiometricSchedulerOperation(
-            @NonNull BaseClientMonitor clientMonitor,
-            @Nullable ClientMonitorCallback callback,
-            @NonNull BooleanSupplier isDebuggable
-    ) {
-        this(clientMonitor, callback, STATE_WAITING_IN_QUEUE, isDebuggable);
-    }
-
     protected BiometricSchedulerOperation(
             @NonNull BaseClientMonitor clientMonitor,
             @Nullable ClientMonitorCallback callback,
             @OperationState int state
     ) {
-        this(clientMonitor, callback, state, Build::isDebuggable);
-    }
-
-    private BiometricSchedulerOperation(
-            @NonNull BaseClientMonitor clientMonitor,
-            @Nullable ClientMonitorCallback callback,
-            @OperationState int state,
-            @NonNull BooleanSupplier isDebuggable
-    ) {
         mClientMonitor = clientMonitor;
         mClientCallback = callback;
         mState = state;
-        mIsDebuggable = isDebuggable;
         mCancelWatchdog = () -> {
             if (!isFinished()) {
                 Slog.e(TAG, "[Watchdog Triggered]: " + this);
@@ -187,9 +167,7 @@
 
         if (mClientMonitor.getCookie() != 0) {
             String err = "operation requires cookie";
-            if (mIsDebuggable.getAsBoolean()) {
-                throw new IllegalStateException(err);
-            }
+            Counter.logIncrement("biometric.value_biometric_scheduler_operation_state_error_count");
             Slog.e(TAG, err);
         }
 
@@ -456,10 +434,9 @@
     private boolean errorWhenOneOf(String op, @OperationState int... states) {
         final boolean isError = ArrayUtils.contains(states, mState);
         if (isError) {
-            String err = op + ": mState must not be " + mState;
-            if (mIsDebuggable.getAsBoolean()) {
-                throw new IllegalStateException(err);
-            }
+            Counter.logIncrement(
+                    "biometric.value_biometric_scheduler_operation_state_error_count");
+            final String err = op + ": mState must not be " + mState;
             Slog.e(TAG, err);
         }
         return isError;
@@ -468,10 +445,10 @@
     private boolean errorWhenNoneOf(String op, @OperationState int... states) {
         final boolean isError = !ArrayUtils.contains(states, mState);
         if (isError) {
-            String err = op + ": mState=" + mState + " must be one of " + Arrays.toString(states);
-            if (mIsDebuggable.getAsBoolean()) {
-                throw new IllegalStateException(err);
-            }
+            Counter.logIncrement(
+                    "biometric.value_biometric_scheduler_operation_state_error_count");
+            final String err = op + ": mState=" + mState + " must be one of "
+                    + Arrays.toString(states);
             Slog.e(TAG, err);
         }
         return isError;
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 4c86f57..60cfd5a 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
@@ -962,6 +962,19 @@
             provider.onUdfpsUiEvent(event, requestId, sensorId);
         }
 
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
+        @Override
+        public void setIgnoreDisplayTouches(long requestId, int sensorId, boolean ignoreTouches) {
+            super.setIgnoreDisplayTouches_enforcePermission();
+
+            final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
+            if (provider == null) {
+                Slog.w(TAG,
+                        "No matching provider for setIgnoreDisplayTouches, sensorId: " + sensorId);
+                return;
+            }
+            provider.setIgnoreDisplayTouches(requestId, sensorId, ignoreTouches);
+        }
 
         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
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 a6cf2f4..e4a99e6 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
@@ -134,6 +134,8 @@
 
     void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller);
 
+    void setIgnoreDisplayTouches(long requestId, int sensorId, boolean ignoreTouches);
+
     void onPowerPressed();
 
     @NonNull
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/Udfps.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/Udfps.java
index dce0175..15d7a47 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/Udfps.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/Udfps.java
@@ -31,4 +31,5 @@
     void onPointerUp(PointerContext pc);
     void onUdfpsUiEvent(@FingerprintManager.UdfpsUiEvent int event);
     boolean isPointerDown();
+    void setIgnoreDisplayTouches(boolean ignoreTouches);
 }
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 72d92b9..d04afdb 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
@@ -33,7 +33,6 @@
 import android.hardware.biometrics.BiometricManager.Authenticators;
 import android.hardware.biometrics.BiometricSourceType;
 import android.hardware.biometrics.common.ICancellationSignal;
-import android.hardware.biometrics.common.OperationState;
 import android.hardware.biometrics.events.AuthenticationAcquiredInfo;
 import android.hardware.biometrics.events.AuthenticationErrorInfo;
 import android.hardware.biometrics.events.AuthenticationFailedInfo;
@@ -182,7 +181,6 @@
         handleLockout(authenticated);
         if (authenticated) {
             mState = STATE_STOPPED;
-            resetIgnoreDisplayTouches();
             mSensorOverlays.hide(getSensorId());
             if (reportBiometricAuthAttempts()) {
                 mAuthenticationStateListeners.onAuthenticationSucceeded(
@@ -223,7 +221,6 @@
                 // Send the error, but do not invoke the FinishCallback yet. Since lockout is not
                 // controlled by the HAL, the framework must stop the sensor before finishing the
                 // client.
-                resetIgnoreDisplayTouches();
                 mSensorOverlays.hide(getSensorId());
                 mAuthenticationStateListeners.onAuthenticationError(
                         new AuthenticationErrorInfo.Builder(BiometricSourceType.FINGERPRINT,
@@ -275,7 +272,6 @@
             BiometricNotificationUtils.showBadCalibrationNotification(getContext());
         }
 
-        resetIgnoreDisplayTouches();
         mSensorOverlays.hide(getSensorId());
         mAuthenticationStateListeners.onAuthenticationStopped(new AuthenticationStoppedInfo
                 .Builder(BiometricSourceType.FINGERPRINT, getRequestReason()).build()
@@ -284,7 +280,6 @@
 
     @Override
     protected void startHalOperation() {
-        resetIgnoreDisplayTouches();
         mSensorOverlays.show(getSensorId(), getRequestReason(), this);
         mAuthenticationStateListeners.onAuthenticationStarted(new AuthenticationStartedInfo
                 .Builder(BiometricSourceType.FINGERPRINT, getRequestReason()).build()
@@ -331,12 +326,6 @@
             if (session.hasContextMethods()) {
                 try {
                     session.getSession().onContextChanged(ctx);
-                    // TODO(b/317414324): Deprecate setIgnoreDisplayTouches
-                    if (ctx.operationState != null && ctx.operationState.getTag()
-                            == OperationState.fingerprintOperationState) {
-                        session.getSession().setIgnoreDisplayTouches(ctx.operationState
-                                .getFingerprintOperationState().isHardwareIgnoringTouches);
-                    }
                 } catch (RemoteException e) {
                     Slog.e(TAG, "Unable to notify context changed", e);
                 }
@@ -353,7 +342,6 @@
 
     @Override
     protected void stopHalOperation() {
-        resetIgnoreDisplayTouches();
         mSensorOverlays.hide(getSensorId());
         mAuthenticationStateListeners.onAuthenticationStopped(new AuthenticationStoppedInfo
                 .Builder(BiometricSourceType.FINGERPRINT, getRequestReason()).build()
@@ -415,6 +403,15 @@
     }
 
     @Override
+    public void setIgnoreDisplayTouches(boolean ignoreTouches) {
+        try {
+            getFreshDaemon().getSession().setIgnoreDisplayTouches(ignoreTouches);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Remote exception", e);
+        }
+    }
+
+    @Override
     public boolean isPointerDown() {
         return mIsPointerDown;
     }
@@ -457,7 +454,6 @@
             Slog.e(TAG, "Remote exception", e);
         }
 
-        resetIgnoreDisplayTouches();
         mSensorOverlays.hide(getSensorId());
         mAuthenticationStateListeners.onAuthenticationStopped(new AuthenticationStoppedInfo
                 .Builder(BiometricSourceType.FINGERPRINT, getRequestReason()).build()
@@ -492,7 +488,6 @@
             Slog.e(TAG, "Remote exception", e);
         }
 
-        resetIgnoreDisplayTouches();
         mSensorOverlays.hide(getSensorId());
         mAuthenticationStateListeners.onAuthenticationStopped(new AuthenticationStoppedInfo
                 .Builder(BiometricSourceType.FINGERPRINT, getRequestReason()).build()
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
index 36af5db..fb48053 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
@@ -87,7 +87,6 @@
 
     @Override
     protected void stopHalOperation() {
-        resetIgnoreDisplayTouches();
         mSensorOverlays.hide(getSensorId());
         mAuthenticationStateListeners.onAuthenticationStopped(
                 new AuthenticationStoppedInfo.Builder(BiometricSourceType.FINGERPRINT,
@@ -107,7 +106,6 @@
 
     @Override
     protected void startHalOperation() {
-        resetIgnoreDisplayTouches();
         mSensorOverlays.show(getSensorId(), BiometricRequestConstants.REASON_AUTH_KEYGUARD,
                 this);
         mAuthenticationStateListeners.onAuthenticationStarted(
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 3a72d7e..993a68f 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
@@ -150,7 +150,6 @@
                 controller -> controller.onEnrollmentProgress(getSensorId(), remaining));
 
         if (remaining == 0) {
-            resetIgnoreDisplayTouches();
             mSensorOverlays.hide(getSensorId());
             mAuthenticationStateListeners.onAuthenticationStopped(
                     new AuthenticationStoppedInfo.Builder(
@@ -211,7 +210,6 @@
         );
         super.onError(errorCode, vendorCode);
 
-        resetIgnoreDisplayTouches();
         mSensorOverlays.hide(getSensorId());
         mAuthenticationStateListeners.onAuthenticationStopped(
                 new AuthenticationStoppedInfo.Builder(BiometricSourceType.FINGERPRINT,
@@ -227,7 +225,6 @@
 
     @Override
     protected void startHalOperation() {
-        resetIgnoreDisplayTouches();
         mSensorOverlays.show(getSensorId(),
                 getRequestReasonFromFingerprintEnrollReason(mEnrollReason), this);
         mAuthenticationStateListeners.onAuthenticationStarted(new AuthenticationStartedInfo
@@ -277,7 +274,6 @@
 
     @Override
     protected void stopHalOperation() {
-        resetIgnoreDisplayTouches();
         mSensorOverlays.hide(getSensorId());
         mAuthenticationStateListeners.onAuthenticationStopped(new AuthenticationStoppedInfo
                 .Builder(BiometricSourceType.FINGERPRINT,
@@ -359,5 +355,14 @@
     }
 
     @Override
+    public void setIgnoreDisplayTouches(boolean ignoreTouches) {
+        try {
+            getFreshDaemon().getSession().setIgnoreDisplayTouches(ignoreTouches);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Unable to send setIgnoreDisplayTouches", e);
+        }
+    }
+
+    @Override
     public void onPowerPressed() {}
 }
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 1bddb83b..12baf00 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
@@ -790,6 +790,19 @@
     }
 
     @Override
+    public void setIgnoreDisplayTouches(long requestId, int sensorId, boolean ignoreTouches) {
+        mFingerprintSensors.get(sensorId).getScheduler().getCurrentClientIfMatches(
+                requestId, (client) -> {
+                    if (!(client instanceof Udfps)) {
+                        Slog.e(getTag(),
+                                "setIgnoreDisplayTouches received during client: " + client);
+                        return;
+                    }
+                    ((Udfps) client).setIgnoreDisplayTouches(ignoreTouches);
+                });
+    }
+
+    @Override
     public void onPowerPressed() {
         for (int i = 0; i < mFingerprintSensors.size(); i++) {
             final Sensor sensor = mFingerprintSensors.valueAt(i);
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java b/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java
index 9467d6f..a3c68f9 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java
@@ -590,15 +590,9 @@
                 || isVendorIdentifierType(id.type);
     }
 
-    private static boolean isValidHalProgramInfo(ProgramInfo info) {
-        return isValidHalProgramSelector(info.selector)
-                && isValidLogicallyTunedTo(info.logicallyTunedTo)
-                && isValidPhysicallyTunedTo(info.physicallyTunedTo);
-    }
-
     @Nullable
     static RadioManager.ProgramInfo programInfoFromHalProgramInfo(ProgramInfo info) {
-        if (!isValidHalProgramInfo(info)) {
+        if (!isValidHalProgramSelector(info.selector)) {
             return null;
         }
         Collection<ProgramSelector.Identifier> relatedContent = new ArrayList<>();
@@ -624,6 +618,15 @@
         );
     }
 
+    @Nullable
+    static RadioManager.ProgramInfo tunedProgramInfoFromHalProgramInfo(ProgramInfo info) {
+        if (!isValidLogicallyTunedTo(info.logicallyTunedTo)
+                || !isValidPhysicallyTunedTo(info.physicallyTunedTo)) {
+            return null;
+        }
+        return programInfoFromHalProgramInfo(info);
+    }
+
     static ProgramFilter filterToHalProgramFilter(@Nullable ProgramList.Filter filter) {
         if (filter == null) {
             filter = new ProgramList.Filter();
@@ -686,8 +689,10 @@
         if (!programSelectorMeetsSdkVersionRequirement(info.getSelector(), uid)) {
             return false;
         }
-        if (!identifierMeetsSdkVersionRequirement(info.getLogicallyTunedTo(), uid)
-                || !identifierMeetsSdkVersionRequirement(info.getPhysicallyTunedTo(), uid)) {
+        if ((info.getLogicallyTunedTo() != null
+                && !identifierMeetsSdkVersionRequirement(info.getLogicallyTunedTo(), uid))
+                || (info.getPhysicallyTunedTo() != null
+                && !identifierMeetsSdkVersionRequirement(info.getPhysicallyTunedTo(), uid))) {
             return false;
         }
         Iterator<ProgramSelector.Identifier> relatedContentIt = info.getRelatedContent().iterator();
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
index 03e347a..4edd441 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
@@ -121,7 +121,7 @@
         public void onCurrentProgramInfoChanged(ProgramInfo halProgramInfo) {
             fireLater(() -> {
                 RadioManager.ProgramInfo currentProgramInfo =
-                        ConversionUtils.programInfoFromHalProgramInfo(halProgramInfo);
+                        ConversionUtils.tunedProgramInfoFromHalProgramInfo(halProgramInfo);
                 Objects.requireNonNull(currentProgramInfo,
                         "Program info from AIDL HAL is invalid");
                 synchronized (mLock) {
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index 0afca92..73aa14b 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -251,7 +251,7 @@
     }
 
     private void registerVirtualDeviceListener() {
-        if (mVirtualDeviceListener != null) {
+        if (mVdm == null || mVirtualDeviceListener != null) {
             return;
         }
         mVirtualDeviceListener = new VirtualDeviceManager.VirtualDeviceListener() {
@@ -891,7 +891,8 @@
                 Slog.e(TAG, "RemoteException calling UserManager: " + e);
                 return null;
             }
-            if (deviceId != DEVICE_ID_DEFAULT && !mVdm.isValidVirtualDeviceId(deviceId)) {
+            if (deviceId != DEVICE_ID_DEFAULT
+                    && mVdm != null && !mVdm.isValidVirtualDeviceId(deviceId)) {
                 Slog.w(TAG, "getClipboardLocked called with invalid (possibly released) deviceId "
                         + deviceId);
                 return null;
@@ -1467,8 +1468,8 @@
             return;
         }
         // Don't notify if this access is coming from the privileged app which owns the device.
-        if (clipboard.deviceId != DEVICE_ID_DEFAULT && mVdmInternal.getDeviceOwnerUid(
-                clipboard.deviceId) == uid) {
+        if (clipboard.deviceId != DEVICE_ID_DEFAULT && mVdmInternal != null
+                && mVdmInternal.getDeviceOwnerUid(clipboard.deviceId) == uid) {
             return;
         }
         // Don't notify if already notified for this uid and clip.
@@ -1519,7 +1520,7 @@
     private ArraySet<Context> getToastContexts(Clipboard clipboard) throws IllegalStateException {
         ArraySet<Context> contexts = new ArraySet<>();
 
-        if (clipboard.deviceId != DEVICE_ID_DEFAULT) {
+        if (mVdmInternal != null && clipboard.deviceId != DEVICE_ID_DEFAULT) {
             DisplayManager displayManager = getContext().getSystemService(DisplayManager.class);
 
             int topFocusedDisplayId = mWm.getTopFocusedDisplayId();
diff --git a/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java b/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
index b179783..6e38733 100644
--- a/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
+++ b/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
@@ -20,6 +20,8 @@
 import android.annotation.Nullable;
 import android.companion.virtual.IVirtualDevice;
 import android.companion.virtual.VirtualDevice;
+import android.companion.virtual.VirtualDeviceManager;
+import android.companion.virtual.VirtualDeviceParams;
 import android.companion.virtual.sensor.VirtualSensor;
 import android.content.Context;
 import android.os.LocaleList;
@@ -180,4 +182,14 @@
      * exists, as long as one may have existed or can be created.
      */
     public abstract @NonNull Set<String> getAllPersistentDeviceIds();
+
+    /**
+     * Creates a virtual device where applications can launch and receive input events injected by
+     * the creator.
+     *
+     * <p>A Companion Device Manager association is not required. Only the system may create such
+     * virtual devices.</p>
+     */
+    public abstract @NonNull VirtualDeviceManager.VirtualDevice createVirtualDevice(
+            @NonNull VirtualDeviceParams params);
 }
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index f8fd0a0..22b85d4 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -83,9 +83,10 @@
 
     @VisibleForTesting
     PlatformCompat(Context context, CompatConfig compatConfig,
-            AndroidBuildClassifier buildClassifier) {
+            AndroidBuildClassifier buildClassifier,
+            ChangeReporter changeReporter) {
         mContext = context;
-        mChangeReporter = new ChangeReporter(ChangeReporter.SOURCE_SYSTEM_SERVER);
+        mChangeReporter = changeReporter;
         mCompatConfig = compatConfig;
         mBuildClassifier = buildClassifier;
 
@@ -96,8 +97,11 @@
     @EnforcePermission(LOG_COMPAT_CHANGE)
     public void reportChange(long changeId, ApplicationInfo appInfo) {
         super.reportChange_enforcePermission();
-
-        reportChangeInternal(changeId, appInfo.uid, ChangeReporter.STATE_LOGGED);
+        reportChangeInternal(
+                changeId,
+                appInfo.uid,
+                appInfo.isSystemApp(),
+                ChangeReporter.STATE_LOGGED);
     }
 
     @Override
@@ -108,7 +112,11 @@
 
         ApplicationInfo appInfo = getApplicationInfo(packageName, userId);
         if (appInfo != null) {
-            reportChangeInternal(changeId, appInfo.uid, ChangeReporter.STATE_LOGGED);
+            reportChangeInternal(
+                    changeId,
+                    appInfo.uid,
+                    appInfo.isSystemApp(),
+                    ChangeReporter.STATE_LOGGED);
         }
     }
 
@@ -117,7 +125,7 @@
     public void reportChangeByUid(long changeId, int uid) {
         super.reportChangeByUid_enforcePermission();
 
-        reportChangeInternal(changeId, uid, ChangeReporter.STATE_LOGGED);
+        reportChangeInternal(changeId, uid, false, ChangeReporter.STATE_LOGGED);
     }
 
     /**
@@ -128,8 +136,8 @@
      * @param uid             of the user
      * @param state           of the change - enabled/disabled/logged
      */
-    private void reportChangeInternal(long changeId, int uid, int state) {
-        mChangeReporter.reportChange(uid, changeId, state, true);
+    private void reportChangeInternal(long changeId, int uid, boolean isKnownSystemApp, int state) {
+        mChangeReporter.reportChange(uid, changeId, state, isKnownSystemApp, true);
     }
 
     @Override
@@ -190,7 +198,11 @@
         if (appInfo != null) {
             boolean isTargetingLatestSdk =
                     mCompatConfig.isChangeTargetingLatestSdk(c, appInfo.targetSdkVersion);
-            mChangeReporter.reportChange(appInfo.uid, changeId, state, isTargetingLatestSdk);
+            mChangeReporter.reportChange(appInfo.uid,
+                    changeId,
+                    state,
+                    appInfo.isSystemApp(),
+                    isTargetingLatestSdk);
         }
         return enabled;
     }
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
index e8394d4..619aecf 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
@@ -19,6 +19,9 @@
 import static android.Manifest.permission.CONTROL_DEVICE_STATE;
 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_REAR_DISPLAY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST;
 import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS;
 import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP;
 import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER;
@@ -47,6 +50,8 @@
 import android.hardware.devicestate.DeviceStateManagerInternal;
 import android.hardware.devicestate.IDeviceStateManager;
 import android.hardware.devicestate.IDeviceStateManagerCallback;
+import android.hardware.devicestate.feature.flags.FeatureFlags;
+import android.hardware.devicestate.feature.flags.FeatureFlagsImpl;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
@@ -175,7 +180,7 @@
 
     private Set<Integer> mDeviceStatesAvailableForAppRequests = new HashSet<>();
 
-    private Set<Integer> mFoldedDeviceStates;
+    private Set<Integer> mFoldedDeviceStates = new HashSet<>();
 
     @Nullable
     private DeviceState mRearDisplayState;
@@ -185,6 +190,9 @@
     @Nullable
     private OverrideRequest mRearDisplayPendingOverrideRequest;
 
+    @NonNull
+    private final FeatureFlags mFlags;
+
     @VisibleForTesting
     interface SystemPropertySetter {
         void setDebugTracingDeviceStateProperty(String value);
@@ -245,6 +253,7 @@
             @NonNull SystemPropertySetter systemPropertySetter) {
         super(context);
         mSystemPropertySetter = systemPropertySetter;
+        mFlags = new FeatureFlagsImpl();
         // We use the DisplayThread because this service indirectly drives
         // display (on/off) and window (position) events through its callbacks.
         DisplayThread displayThread = DisplayThread.get();
@@ -270,9 +279,12 @@
         publishBinderService(Context.DEVICE_STATE_SERVICE, mBinderService);
         publishLocalService(DeviceStateManagerInternal.class, new LocalService());
 
-        synchronized (mLock) {
-            readStatesAvailableForRequestFromApps();
-            mFoldedDeviceStates = readFoldedStates();
+        if (!mFlags.deviceStatePropertyMigration()) {
+            synchronized (mLock) {
+                readStatesAvailableForRequestFromApps();
+                mFoldedDeviceStates = readFoldedStates();
+                setRearDisplayStateLocked();
+            }
         }
 
         mActivityTaskManagerInternal.registerScreenObserver(mOverrideRequestScreenObserver);
@@ -461,8 +473,6 @@
             mOverrideRequestController.handleNewSupportedStates(newStateIdentifiers, reason);
             updatePendingStateLocked();
 
-            setRearDisplayStateLocked();
-
             notifyDeviceStateInfoChangedAsync();
 
             mHandler.post(this::notifyPolicyIfNeeded);
@@ -838,12 +848,22 @@
             OverrideRequest request = new OverrideRequest(token, callingPid, callingUid,
                     deviceState.get(), flags, OVERRIDE_REQUEST_TYPE_EMULATED_STATE);
 
-            // If we don't have the CONTROL_DEVICE_STATE permission, we want to show the overlay
-            if (!hasControlDeviceStatePermission && mRearDisplayState != null
-                    && state == mRearDisplayState.getIdentifier()) {
-                showRearDisplayEducationalOverlayLocked(request);
+            if (mFlags.deviceStatePropertyMigration()) {
+                // If we don't have the CONTROL_DEVICE_STATE permission, we want to show the overlay
+                if (!hasControlDeviceStatePermission && deviceState.get().hasProperty(
+                        PROPERTY_FEATURE_REAR_DISPLAY)) {
+                    showRearDisplayEducationalOverlayLocked(request);
+                } else {
+                    mOverrideRequestController.addRequest(request);
+                }
             } else {
-                mOverrideRequestController.addRequest(request);
+                // If we don't have the CONTROL_DEVICE_STATE permission, we want to show the overlay
+                if (!hasControlDeviceStatePermission && mRearDisplayState != null
+                        && state == mRearDisplayState.getIdentifier()) {
+                    showRearDisplayEducationalOverlayLocked(request);
+                } else {
+                    mOverrideRequestController.addRequest(request);
+                }
             }
         }
     }
@@ -1034,7 +1054,13 @@
 
     private boolean isStateAvailableForAppRequests(int state) {
         synchronized (mLock) {
-            return mDeviceStatesAvailableForAppRequests.contains(state);
+            if (mFlags.deviceStatePropertyMigration()) {
+                Optional<DeviceState> deviceState =  getStateLocked(state);
+                return deviceState.isPresent() && deviceState.get().hasProperty(
+                        PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST);
+            } else {
+                return mDeviceStatesAvailableForAppRequests.contains(state);
+            }
         }
     }
 
@@ -1096,9 +1122,20 @@
      */
     @GuardedBy("mLock")
     private boolean isDeviceOpeningLocked(int newBaseState) {
-        return mBaseState.filter(
-                deviceState -> mFoldedDeviceStates.contains(deviceState.getIdentifier())
-                        && !mFoldedDeviceStates.contains(newBaseState)).isPresent();
+        if (mFlags.deviceStatePropertyMigration()) {
+            final DeviceState currentBaseState = mBaseState.orElse(INVALID_DEVICE_STATE);
+            final DeviceState newDeviceBaseState = getStateLocked(newBaseState).orElse(
+                    INVALID_DEVICE_STATE);
+
+            return currentBaseState.hasProperty(
+                    PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY)
+                    && !newDeviceBaseState.hasProperty(
+                    PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY);
+        } else {
+            return mBaseState.filter(
+                    deviceState -> mFoldedDeviceStates.contains(deviceState.getIdentifier())
+                            && !mFoldedDeviceStates.contains(newBaseState)).isPresent();
+        }
     }
 
     private final class DeviceStateProviderListener implements DeviceStateProvider.Listener {
diff --git a/services/core/java/com/android/server/display/BrightnessSetting.java b/services/core/java/com/android/server/display/BrightnessSetting.java
index 651828b..7d26004 100644
--- a/services/core/java/com/android/server/display/BrightnessSetting.java
+++ b/services/core/java/com/android/server/display/BrightnessSetting.java
@@ -131,6 +131,25 @@
     }
 
     /**
+     * Sets the brightness. Does not send update event to listeners.
+     * @param brightness The value to which the brightness is to be set.
+     */
+    public void setBrightnessNoNotify(float brightness) {
+        if (Float.isNaN(brightness)) {
+            Slog.w(TAG, "Attempting to init invalid brightness");
+            return;
+        }
+        synchronized (mSyncRoot) {
+            if (brightness != mBrightness) {
+                mPersistentDataStore.setBrightness(mLogicalDisplay.getPrimaryDisplayDeviceLocked(),
+                        brightness, mUserSerial
+                );
+            }
+            mBrightness = brightness;
+        }
+    }
+
+    /**
      * @return The brightness for the default display in nits. Used when the underlying display
      * device has changed but we want to persist the nit value.
      */
diff --git a/services/core/java/com/android/server/display/DisplayBrightnessState.java b/services/core/java/com/android/server/display/DisplayBrightnessState.java
index 184ae41..222c5a8 100644
--- a/services/core/java/com/android/server/display/DisplayBrightnessState.java
+++ b/services/core/java/com/android/server/display/DisplayBrightnessState.java
@@ -29,9 +29,10 @@
  */
 public final class DisplayBrightnessState {
     public static final float CUSTOM_ANIMATION_RATE_NOT_SET = -1f;
+    public static final float BRIGHTNESS_NOT_SET = -1f;
 
     private final float mBrightness;
-    private final float mSdrBrightness;
+    private final float mHdrBrightness;
 
     private final float mMaxBrightness;
     private final float mMinBrightness;
@@ -51,7 +52,7 @@
 
     private DisplayBrightnessState(Builder builder) {
         mBrightness = builder.getBrightness();
-        mSdrBrightness = builder.getSdrBrightness();
+        mHdrBrightness = builder.getHdrBrightness();
         mBrightnessReason = builder.getBrightnessReason();
         mDisplayBrightnessStrategyName = builder.getDisplayBrightnessStrategyName();
         mShouldUseAutoBrightness = builder.getShouldUseAutoBrightness();
@@ -73,10 +74,10 @@
     }
 
     /**
-     * Gets the sdr brightness
+     * Gets the hdr brightness
      */
-    public float getSdrBrightness() {
-        return mSdrBrightness;
+    public float getHdrBrightness() {
+        return mHdrBrightness;
     }
 
     /**
@@ -163,8 +164,8 @@
         StringBuilder stringBuilder = new StringBuilder("DisplayBrightnessState:");
         stringBuilder.append("\n    brightness:");
         stringBuilder.append(getBrightness());
-        stringBuilder.append("\n    sdrBrightness:");
-        stringBuilder.append(getSdrBrightness());
+        stringBuilder.append("\n    hdrBrightness:");
+        stringBuilder.append(getHdrBrightness());
         stringBuilder.append("\n    brightnessReason:");
         stringBuilder.append(getBrightnessReason());
         stringBuilder.append("\n    shouldUseAutoBrightness:");
@@ -198,7 +199,7 @@
         DisplayBrightnessState otherState = (DisplayBrightnessState) other;
 
         return mBrightness == otherState.getBrightness()
-                && mSdrBrightness == otherState.getSdrBrightness()
+                && mHdrBrightness == otherState.getHdrBrightness()
                 && mBrightnessReason.equals(otherState.getBrightnessReason())
                 && TextUtils.equals(mDisplayBrightnessStrategyName,
                         otherState.getDisplayBrightnessStrategyName())
@@ -216,7 +217,7 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(mBrightness, mSdrBrightness, mBrightnessReason,
+        return Objects.hash(mBrightness, mHdrBrightness, mBrightnessReason,
                 mShouldUseAutoBrightness, mIsSlowChange, mMaxBrightness, mMinBrightness,
                 mCustomAnimationRate,
                 mShouldUpdateScreenBrightnessSetting, mBrightnessEvent, mBrightnessAdjustmentFlag,
@@ -235,7 +236,7 @@
      */
     public static class Builder {
         private float mBrightness;
-        private float mSdrBrightness;
+        private float mHdrBrightness = BRIGHTNESS_NOT_SET;
         private BrightnessReason mBrightnessReason = new BrightnessReason();
         private String mDisplayBrightnessStrategyName;
         private boolean mShouldUseAutoBrightness;
@@ -260,7 +261,7 @@
         public static Builder from(DisplayBrightnessState state) {
             Builder builder = new Builder();
             builder.setBrightness(state.getBrightness());
-            builder.setSdrBrightness(state.getSdrBrightness());
+            builder.setHdrBrightness(state.getHdrBrightness());
             builder.setBrightnessReason(state.getBrightnessReason());
             builder.setDisplayBrightnessStrategyName(state.getDisplayBrightnessStrategyName());
             builder.setShouldUseAutoBrightness(state.getShouldUseAutoBrightness());
@@ -295,20 +296,20 @@
         }
 
         /**
-         * Gets the sdr brightness
+         * Gets the hdr brightness
          */
-        public float getSdrBrightness() {
-            return mSdrBrightness;
+        public float getHdrBrightness() {
+            return mHdrBrightness;
         }
 
         /**
-         * Sets the sdr brightness
+         * Sets the hdr brightness
          *
-         * @param sdrBrightness The sdr brightness to be associated with DisplayBrightnessState's
+         * @param hdrBrightness The hdr brightness to be associated with DisplayBrightnessState's
          *                      builder
          */
-        public Builder setSdrBrightness(float sdrBrightness) {
-            this.mSdrBrightness = sdrBrightness;
+        public Builder setHdrBrightness(float hdrBrightness) {
+            this.mHdrBrightness = hdrBrightness;
             return this;
         }
 
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 2d5f38e..3493381b 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -598,10 +598,11 @@
         FoldSettingProvider foldSettingProvider = new FoldSettingProvider(context,
                 new SettingsWrapper(),
                 new FoldLockSettingAvailabilityProvider(context.getResources()));
+        Looper displayThreadLooper = DisplayThread.get().getLooper();
         mInjector = injector;
         mContext = context;
         mFlags = injector.getFlags();
-        mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());
+        mHandler = new DisplayManagerHandler(displayThreadLooper);
         mUiHandler = UiThread.getHandler();
         mDisplayDeviceRepo = new DisplayDeviceRepository(mSyncRoot, mPersistentDataStore);
         mLogicalDisplayMapper = new LogicalDisplayMapper(mContext,
@@ -609,7 +610,7 @@
                 mDisplayDeviceRepo, new LogicalDisplayListener(), mSyncRoot, mHandler, mFlags);
         mDisplayModeDirector = new DisplayModeDirector(
                 context, mHandler, mFlags, mDisplayDeviceConfigProvider);
-        mBrightnessSynchronizer = new BrightnessSynchronizer(mContext,
+        mBrightnessSynchronizer = new BrightnessSynchronizer(mContext, displayThreadLooper,
                 mFlags.isBrightnessIntRangeUserPerceptionEnabled());
         Resources resources = mContext.getResources();
         mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger(
@@ -822,6 +823,13 @@
     }
 
     @VisibleForTesting
+    void setDisplayState(int displayId, int state) {
+        synchronized (mSyncRoot) {
+            mDisplayStates.setValueAt(displayId, state);
+        }
+    }
+
+    @VisibleForTesting
     Handler getDisplayHandler() {
         return mHandler;
     }
@@ -1548,16 +1556,20 @@
         int flags = virtualDisplayConfig.getFlags();
         if (virtualDevice != null) {
             final VirtualDeviceManager vdm = mContext.getSystemService(VirtualDeviceManager.class);
-            try {
-                if (!vdm.isValidVirtualDeviceId(virtualDevice.getDeviceId())) {
-                    throw new SecurityException("Invalid virtual device");
+            if (vdm != null) {
+                try {
+                    if (!vdm.isValidVirtualDeviceId(virtualDevice.getDeviceId())) {
+                        throw new SecurityException("Invalid virtual device");
+                    }
+                } catch (RemoteException ex) {
+                    throw new SecurityException("Unable to validate virtual device");
                 }
-            } catch (RemoteException ex) {
-                throw new SecurityException("Unable to validate virtual device");
+                final VirtualDeviceManagerInternal localVdm =
+                        getLocalService(VirtualDeviceManagerInternal.class);
+                if (localVdm != null) {
+                    flags |= localVdm.getBaseVirtualDisplayFlags(virtualDevice);
+                }
             }
-            final VirtualDeviceManagerInternal localVdm =
-                    getLocalService(VirtualDeviceManagerInternal.class);
-            flags |= localVdm.getBaseVirtualDisplayFlags(virtualDevice);
         }
 
         if (surface != null && surface.isSingleBuffered()) {
@@ -1935,6 +1947,27 @@
         }
     }
 
+    private void setVirtualDisplayRotationInternal(IBinder appToken,
+            @Surface.Rotation int rotation) {
+        int displayId;
+        synchronized (mSyncRoot) {
+            if (mVirtualDisplayAdapter == null) {
+                return;
+            }
+            DisplayDevice device = mVirtualDisplayAdapter.getDisplayDevice(appToken);
+            if (device == null) {
+                return;
+            }
+            LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
+            if (display == null) {
+                return;
+            }
+            displayId = display.getDisplayIdLocked();
+        }
+        mWindowManagerInternal.setNonDefaultDisplayRotation(
+                displayId, rotation, /* caller= */ "Virtual Display");
+    }
+
     private void registerDefaultDisplayAdapters() {
         // Register default display adapters.
         synchronized (mSyncRoot) {
@@ -3406,27 +3439,39 @@
         }
     }
 
-    boolean requestDisplayPower(int displayId, boolean on) {
+    boolean requestDisplayPower(int displayId, int requestedState) {
         synchronized (mSyncRoot) {
             final var display = mLogicalDisplayMapper.getDisplayLocked(displayId);
             if (display == null) {
-                Slog.w(TAG, "requestDisplayPower: Cannot find a display with displayId="
+                Slog.w(TAG, "requestDisplayPower: Cannot find the display with displayId="
                         + displayId);
                 return false;
             }
+            var state = requestedState;
+            if (state == Display.STATE_UNKNOWN) {
+                state = mDisplayStates.get(displayId);
+            }
+
             final BrightnessPair brightnessPair = mDisplayBrightnesses.get(displayId);
+            var brightnessState = brightnessPair.brightness;
+            if (state == Display.STATE_OFF) {
+                brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT;
+            }
+
             var runnable = display.getPrimaryDisplayDeviceLocked().requestDisplayStateLocked(
-                    on ? Display.STATE_ON : Display.STATE_OFF,
-                    on ? brightnessPair.brightness : PowerManager.BRIGHTNESS_OFF_FLOAT,
+                    state,
+                    brightnessState,
                     brightnessPair.sdrBrightness,
                     display.getDisplayOffloadSessionLocked());
             if (runnable == null) {
-                Slog.w(TAG, "requestDisplayPower: Cannot update the power state to ON=" + on
-                        + " for a display with displayId=" + displayId + ", runnable is null");
+                Slog.w(TAG, "requestDisplayPower: Cannot set power state = " + state
+                        + " for the display with displayId=" + displayId + ","
+                        + " requestedState=" + requestedState + ": runnable is null");
                 return false;
             }
             runnable.run();
-            Slog.i(TAG, "requestDisplayPower(displayId=" + displayId + ", on=" + on + ")");
+            Slog.i(TAG, "requestDisplayPower(displayId=" + displayId
+                    + ", requestedState=" + requestedState + "): state set to " + state);
         }
         return true;
     }
@@ -4175,6 +4220,20 @@
         }
 
         @Override // Binder call
+        public void setVirtualDisplayRotation(IVirtualDisplayCallback callback,
+                @Surface.Rotation int rotation) {
+            if (!android.companion.virtualdevice.flags.Flags.virtualDisplayRotationApi()) {
+                return;
+            }
+            final long token = Binder.clearCallingIdentity();
+            try {
+                setVirtualDisplayRotationInternal(callback.asBinder(), rotation);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override // Binder call
         public void dump(@NonNull FileDescriptor fd, @NonNull final PrintWriter pw, String[] args) {
             if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
@@ -4655,9 +4714,9 @@
         }
 
         @EnforcePermission(MANAGE_DISPLAYS)
-        public boolean requestDisplayPower(int displayId, boolean on) {
+        public boolean requestDisplayPower(int displayId, int state) {
             requestDisplayPower_enforcePermission();
-            return DisplayManagerService.this.requestDisplayPower(displayId, on);
+            return DisplayManagerService.this.requestDisplayPower(displayId, state);
         }
 
         @EnforcePermission(RESTRICT_DISPLAY_MODES)
@@ -4782,6 +4841,8 @@
                 }
                 final int[] supportedStates =
                         mDeviceStateManager.getSupportedStateIdentifiers();
+                // TODO(b/352019542): remove the log once b/345960547 is fixed.
+                Slog.d(TAG, "supportedStates=" + Arrays.toString(supportedStates));
                 DisplayInfo displayInfo;
                 for (int state : supportedStates) {
                     displayInfo = mLogicalDisplayMapper.getDisplayInfoForStateLocked(state,
@@ -4790,6 +4851,8 @@
                         possibleInfo.add(displayInfo);
                     }
                 }
+                // TODO(b/352019542): remove the log once b/345960547 is fixed.
+                Slog.d(TAG, "possibleInfos=" + possibleInfo);
                 return possibleInfo;
             }
         }
diff --git a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java
index d973b71..e46397b 100644
--- a/services/core/java/com/android/server/display/DisplayManagerShellCommand.java
+++ b/services/core/java/com/android/server/display/DisplayManagerShellCommand.java
@@ -62,6 +62,8 @@
                 return showNotification();
             case "cancel-notifications":
                 return cancelNotifications();
+            case "get-brightness":
+                return getBrightness();
             case "set-brightness":
                 return setBrightness();
             case "reset-brightness-configuration":
@@ -106,10 +108,10 @@
                 return setDisplayEnabled(true);
             case "disable-display":
                 return setDisplayEnabled(false);
-            case "power-on":
-                return requestDisplayPower(true);
+            case "power-reset":
+                return requestDisplayPower(Display.STATE_UNKNOWN);
             case "power-off":
-                return requestDisplayPower(false);
+                return requestDisplayPower(Display.STATE_OFF);
             default:
                 return handleDefaultCommands(cmd);
         }
@@ -183,6 +185,10 @@
             pw.println("  disable-display DISPLAY_ID");
             pw.println("    Disable the DISPLAY_ID. Only possible if this is a connected display.");
         }
+        pw.println("  power-reset DISPLAY_ID");
+        pw.println("    Turn the DISPLAY_ID power to a state the display supposed to have.");
+        pw.println("  power-off DISPLAY_ID");
+        pw.println("    Turn the display DISPLAY_ID power off.");
         pw.println();
         Intent.printIntentArgsHelp(pw , "");
     }
@@ -309,6 +315,25 @@
         return 0;
     }
 
+    private int getBrightness() {
+        String displayIdString = getNextArg();
+        if (displayIdString == null) {
+            getErrPrintWriter().println("Error: no display id specified");
+            return 1;
+        }
+        int displayId;
+        try {
+            displayId = Integer.parseInt(displayIdString);
+        } catch (NumberFormatException e) {
+            getErrPrintWriter().println("Error: invalid displayId=" + displayIdString + " not int");
+            return 1;
+        }
+        final Context context = mService.getContext();
+        final DisplayManager dm = context.getSystemService(DisplayManager.class);
+        getOutPrintWriter().println(dm.getBrightness(displayId));
+        return 0;
+    }
+
     private int setBrightness() {
         String brightnessText = getNextArg();
         if (brightnessText == null) {
@@ -597,7 +622,7 @@
         return 0;
     }
 
-    private int requestDisplayPower(boolean enable) {
+    private int requestDisplayPower(int state) {
         final String displayIdText = getNextArg();
         if (displayIdText == null) {
             getErrPrintWriter().println("Error: no displayId specified");
@@ -610,7 +635,7 @@
             getErrPrintWriter().println("Error: invalid displayId: '" + displayIdText + "'");
             return 1;
         }
-        mService.requestDisplayPower(displayId, enable);
+        mService.requestDisplayPower(displayId, state);
         return 0;
     }
 }
diff --git a/services/core/java/com/android/server/display/DisplayOffloadSessionImpl.java b/services/core/java/com/android/server/display/DisplayOffloadSessionImpl.java
index 0fef55d..a188e79 100644
--- a/services/core/java/com/android/server/display/DisplayOffloadSessionImpl.java
+++ b/services/core/java/com/android/server/display/DisplayOffloadSessionImpl.java
@@ -84,6 +84,14 @@
     }
 
     @Override
+    public void cancelBlockScreenOn() {
+        if (mDisplayOffloader == null) {
+            return;
+        }
+        mDisplayOffloader.cancelBlockScreenOn();
+    }
+
+    @Override
     public float[] getAutoBrightnessLevels(int mode) {
         if (mode < 0 || mode > AUTO_BRIGHTNESS_MODE_MAX) {
             throw new IllegalArgumentException("Unknown auto-brightness mode: " + mode);
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 65a729a..76a561b 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -587,7 +587,8 @@
                         mUniqueDisplayId,
                         mThermalBrightnessThrottlingDataId,
                         logicalDisplay.getPowerThrottlingDataIdLocked(),
-                        mDisplayDeviceConfig), mContext, flags, mSensorManager);
+                        mDisplayDeviceConfig,
+                        mDisplayId), mContext, flags, mSensorManager);
         // Seed the cached brightness
         saveBrightnessInfo(getScreenBrightnessSetting());
         mAutomaticBrightnessStrategy =
@@ -892,7 +893,8 @@
             // will call updatePowerState if needed.
             mBrightnessClamperController.onDisplayChanged(
                     new BrightnessClamperController.DisplayDeviceData(uniqueId,
-                        thermalBrightnessThrottlingDataId, powerThrottlingDataId, config));
+                            thermalBrightnessThrottlingDataId, powerThrottlingDataId,
+                            config, mDisplayId));
 
             if (changed) {
                 updatePowerState();
@@ -1483,6 +1485,7 @@
                     || !mAutomaticBrightnessStrategy.shouldUseAutoBrightness())) {
                 rawBrightnessState = getDozeBrightnessForOffload();
                 brightnessState = clampScreenBrightness(rawBrightnessState);
+                updateScreenBrightnessSetting = false;
                 mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_MANUAL);
                 mTempBrightnessEvent.setFlags(
                         mTempBrightnessEvent.getFlags() | BrightnessEvent.FLAG_DOZE_SCALE);
@@ -1565,7 +1568,9 @@
             // even if they range changes what it means in absolute terms.
             mDisplayBrightnessController.updateScreenBrightnessSetting(
                     MathUtils.constrain(unthrottledBrightnessState,
-                            clampedState.getMinBrightness(), clampedState.getMaxBrightness()));
+                            clampedState.getMinBrightness(), clampedState.getMaxBrightness()),
+                    Math.min(mBrightnessRangeController.getCurrentBrightnessMax(),
+                            clampedState.getMaxBrightness()));
         }
 
         // The current brightness to use has been calculated at this point, and HbmController should
@@ -1628,9 +1633,13 @@
             // use instead. We still preserve the calculated brightness for Standard Dynamic Range
             // (SDR) layers, but the main brightness value will be the one for HDR.
             float sdrAnimateValue = animateValue;
-            // TODO(b/216365040): The decision to prevent HBM for HDR in low power mode should be
-            // done in HighBrightnessModeController.
-            if (mBrightnessRangeController.getHighBrightnessMode()
+
+            if (clampedState.getHdrBrightness() != DisplayBrightnessState.BRIGHTNESS_NOT_SET) {
+                // TODO(b/343792639): The decision to prevent HBM for HDR in low power mode will be
+                // done in HdrBrightnessModifier.
+                // customAnimationRate and reason also handled by HdrBrightnessModifier
+                animateValue = clampedState.getHdrBrightness();
+            } else if (mBrightnessRangeController.getHighBrightnessMode()
                     == BrightnessInfo.HIGH_BRIGHTNESS_MODE_HDR
                     && (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_DIMMED) == 0
                     && (mBrightnessReasonTemp.getModifier() & BrightnessReason.MODIFIER_LOW_POWER)
@@ -2094,7 +2103,7 @@
     private void onDisplayOffloadUnblockScreenOn(DisplayOffloadSession displayOffloadSession) {
         Message msg = mHandler.obtainMessage(MSG_OFFLOADING_SCREEN_ON_UNBLOCKED,
                 displayOffloadSession);
-        mHandler.sendMessage(msg);
+        mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
     }
 
     private void unblockScreenOnByDisplayOffload() {
@@ -2108,6 +2117,17 @@
                 Trace.TRACE_TAG_POWER, SCREEN_ON_BLOCKED_BY_DISPLAYOFFLOAD_TRACE_NAME, 0);
     }
 
+    private void cancelUnblockScreenOnByDisplayOffload() {
+        if (mDisplayOffloadSession == null) {
+            return;
+        }
+        if (mPendingScreenOnUnblockerByDisplayOffload == null) {
+            // Already unblocked.
+            return;
+        }
+        mDisplayOffloadSession.cancelBlockScreenOn();
+    }
+
     private boolean setScreenState(int state, @Display.StateReason int reason) {
         return setScreenState(state, reason, false /*reportOnly*/);
     }
@@ -2119,11 +2139,13 @@
 
         // If the screen is turning on, give displayoffload a chance to do something before the
         // screen actually turns on.
-        // TODO(b/316941732): add tests for this displayoffload screen-on blocker.
         if (isOn && changed && !mScreenTurningOnWasBlockedByDisplayOffload) {
             blockScreenOnByDisplayOffload(mDisplayOffloadSession);
         } else if (!isOn && mScreenTurningOnWasBlockedByDisplayOffload) {
             // No longer turning screen on, so unblock previous screen on blocking immediately.
+            if (mFlags.isOffloadSessionCancelBlockScreenOnEnabled()) {
+                cancelUnblockScreenOnByDisplayOffload();
+            }
             unblockScreenOnByDisplayOffload();
             mScreenTurningOnWasBlockedByDisplayOffload = false;
         }
@@ -2455,12 +2477,20 @@
 
     @Override
     public void setBrightness(float brightness) {
-        mDisplayBrightnessController.setBrightness(clampScreenBrightness(brightness));
+        // After HBMController and NBMController migration to Clampers framework
+        // currentBrightnessMax should be taken from clampers controller
+        // TODO(b/263362199)
+        mDisplayBrightnessController.setBrightness(clampScreenBrightness(brightness),
+                mBrightnessRangeController.getCurrentBrightnessMax());
     }
 
     @Override
     public void setBrightness(float brightness, int userSerial) {
-        mDisplayBrightnessController.setBrightness(clampScreenBrightness(brightness), userSerial);
+        // After HBMController and NBMController migration to Clampers framework
+        // currentBrightnessMax should be taken from clampers controller
+        // TODO(b/263362199)
+        mDisplayBrightnessController.setBrightness(clampScreenBrightness(brightness), userSerial,
+                mBrightnessRangeController.getCurrentBrightnessMax());
     }
 
     @Override
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index e645e98..4791cd1 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -389,11 +389,15 @@
         // Retrieve the layout for this particular state.
         final Layout layout = mDeviceStateToLayoutMap.get(deviceState);
         if (layout == null) {
+            // TODO(b/352019542): remove the log once b/345960547 is fixed.
+            Slog.d(TAG, "Cannot get layout for given state:" + deviceState);
             return null;
         }
         // Retrieve the details of the given display within this layout.
         Layout.Display display = layout.getById(displayId);
         if (display == null) {
+            // TODO(b/352019542): remove the log once b/345960547 is fixed.
+            Slog.d(TAG, "Cannot get display for given layout:" + layout);
             return null;
         }
         // Retrieve the display info for the display that matches the display id.
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 1a5c79f..9b02f4b 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -56,6 +56,7 @@
 import android.util.ArrayMap;
 import android.util.Slog;
 import android.view.Display;
+import android.view.DisplayCutout;
 import android.view.DisplayShape;
 import android.view.Surface;
 import android.view.SurfaceControl;
@@ -213,6 +214,10 @@
         }
     }
 
+    DisplayDevice getDisplayDevice(IBinder appToken) {
+        return mVirtualDisplayDevices.get(appToken);
+    }
+
     /**
      * Generates a virtual display's unique identifier.
      *
@@ -271,6 +276,7 @@
         private boolean mIsDisplayOn;
         private int mDisplayIdToMirror;
         private boolean mIsWindowManagerMirroring;
+        private DisplayCutout mDisplayCutout;
 
         public VirtualDisplayDevice(IBinder displayToken, IBinder appToken,
                 int ownerUid, String ownerPackageName, Surface surface, int flags,
@@ -286,6 +292,7 @@
             mHeight = virtualDisplayConfig.getHeight();
             mDensityDpi = virtualDisplayConfig.getDensityDpi();
             mRequestedRefreshRate = virtualDisplayConfig.getRequestedRefreshRate();
+            mDisplayCutout = virtualDisplayConfig.getDisplayCutout();
             mMode = createMode(mWidth, mHeight, getRefreshRate());
             mSurface = surface;
             mFlags = flags;
@@ -567,6 +574,7 @@
 
                 mInfo.displayShape =
                         DisplayShape.createDefaultDisplayShape(mInfo.width, mInfo.height, false);
+                mInfo.displayCutout = mDisplayCutout;
             }
             return mInfo;
         }
diff --git a/services/core/java/com/android/server/display/brightness/BrightnessUtils.java b/services/core/java/com/android/server/display/brightness/BrightnessUtils.java
index 8bf675c..d009e614 100644
--- a/services/core/java/com/android/server/display/brightness/BrightnessUtils.java
+++ b/services/core/java/com/android/server/display/brightness/BrightnessUtils.java
@@ -52,9 +52,8 @@
      * A utility to construct the DisplayBrightnessState
      */
     public static DisplayBrightnessState constructDisplayBrightnessState(
-            int brightnessChangeReason, float brightness, float sdrBrightness,
-            String displayBrightnessStrategyName) {
-        return constructDisplayBrightnessState(brightnessChangeReason, brightness, sdrBrightness,
+            int brightnessChangeReason, float brightness, String displayBrightnessStrategyName) {
+        return constructDisplayBrightnessState(brightnessChangeReason, brightness,
                 displayBrightnessStrategyName, /* slowChange= */ false);
     }
 
@@ -62,13 +61,12 @@
      * A utility to construct the DisplayBrightnessState
      */
     public static DisplayBrightnessState constructDisplayBrightnessState(
-            int brightnessChangeReason, float brightness, float sdrBrightness,
+            int brightnessChangeReason, float brightness,
             String displayBrightnessStrategyName, boolean slowChange) {
         BrightnessReason brightnessReason = new BrightnessReason();
         brightnessReason.setReason(brightnessChangeReason);
         return new DisplayBrightnessState.Builder()
                 .setBrightness(brightness)
-                .setSdrBrightness(sdrBrightness)
                 .setBrightnessReason(brightnessReason)
                 .setDisplayBrightnessStrategyName(displayBrightnessStrategyName)
                 .setIsSlowChange(slowChange)
diff --git a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
index 4982a0b0..c632e77 100644
--- a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
+++ b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
@@ -313,13 +313,18 @@
     /**
      * Notifies the brightnessSetting to persist the supplied brightness value.
      */
-    public void setBrightness(float brightnessValue) {
+    public void setBrightness(float brightnessValue, float maxBrightness) {
         // Update the setting, which will eventually call back into DPC to have us actually
         // update the display with the new value.
         mBrightnessSetting.setBrightness(brightnessValue);
         if (mDisplayId == Display.DEFAULT_DISPLAY && mPersistBrightnessNitsForDefaultDisplay) {
             float nits = convertToNits(brightnessValue);
-            if (nits >= 0) {
+            float currentlyStoredNits = mBrightnessSetting.getBrightnessNitsForDefaultDisplay();
+            // Don't override settings if the brightness is set to max, but the currently
+            // stored value is greater. On multi-screen device, when switching between a
+            // screen with a wider brightness range and one with a narrower brightness range,
+            // the stored value shouldn't change.
+            if (nits >= 0 && !(brightnessValue == maxBrightness && currentlyStoredNits > nits)) {
                 mBrightnessSetting.setBrightnessNitsForDefaultDisplay(nits);
             }
         }
@@ -328,15 +333,15 @@
     /**
      * Notifies the brightnessSetting to persist the supplied brightness value for a user.
      */
-    public void setBrightness(float brightnessValue, int userSerial) {
+    public void setBrightness(float brightnessValue, int userSerial, float maxBrightness) {
         mBrightnessSetting.setUserSerial(userSerial);
-        setBrightness(brightnessValue);
+        setBrightness(brightnessValue, maxBrightness);
     }
 
     /**
      * Sets the current screen brightness, and notifies the BrightnessSetting about the change.
      */
-    public void updateScreenBrightnessSetting(float brightnessValue) {
+    public void updateScreenBrightnessSetting(float brightnessValue, float maxBrightness) {
         synchronized (mLock) {
             if (!BrightnessUtils.isValidBrightnessValue(brightnessValue)
                     || brightnessValue == mCurrentScreenBrightness) {
@@ -345,7 +350,7 @@
             setCurrentScreenBrightnessLocked(brightnessValue);
         }
         notifyCurrentScreenBrightness();
-        setBrightness(brightnessValue);
+        setBrightness(brightnessValue, maxBrightness);
     }
 
     /**
@@ -582,7 +587,7 @@
                 float brightnessForDefaultDisplay = getBrightnessFromNits(
                         brightnessNitsForDefaultDisplay);
                 if (BrightnessUtils.isValidBrightnessValue(brightnessForDefaultDisplay)) {
-                    mBrightnessSetting.setBrightness(brightnessForDefaultDisplay);
+                    mBrightnessSetting.setBrightnessNoNotify(brightnessForDefaultDisplay);
                     currentBrightnessSetting = brightnessForDefaultDisplay;
                 }
             }
diff --git a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java
index 101ad30..88d2c00 100644
--- a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java
+++ b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java
@@ -23,23 +23,17 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
-import android.content.res.Resources;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
 import android.hardware.display.BrightnessInfo;
 import android.hardware.display.DisplayManagerInternal;
 import android.os.Handler;
 import android.os.HandlerExecutor;
 import android.os.PowerManager;
-import android.os.SystemClock;
 import android.provider.DeviceConfig;
 import android.provider.DeviceConfigInterface;
 import android.util.IndentingPrintWriter;
 import android.util.Slog;
 
-import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.display.DisplayBrightnessState;
 import com.android.server.display.DisplayDeviceConfig;
@@ -50,30 +44,22 @@
 import com.android.server.display.config.SensorData;
 import com.android.server.display.feature.DeviceConfigParameterProvider;
 import com.android.server.display.feature.DisplayManagerFlags;
-import com.android.server.display.utils.AmbientFilter;
-import com.android.server.display.utils.AmbientFilterFactory;
-import com.android.server.display.utils.DebugUtils;
-import com.android.server.display.utils.SensorUtils;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
 
 /**
  * Clampers controller, all in DisplayControllerHandler
  */
 public class BrightnessClamperController {
     private static final String TAG = "BrightnessClamperController";
-    // To enable these logs, run:
-    // 'adb shell setprop persist.log.tag.BrightnessClamperController DEBUG && adb reboot'
-    private static final boolean DEBUG = DebugUtils.isDebuggable(TAG);
-    public static final float INVALID_LUX = -1f;
 
     private final DeviceConfigParameterProvider mDeviceConfigParameterProvider;
     private final Handler mHandler;
-    private final SensorManager mSensorManager;
+    private final LightSensorController mLightSensorController;
+
     private final ClamperChangeListener mClamperChangeListenerExternal;
     private final Executor mExecutor;
     private final List<BrightnessClamper<? super DisplayDeviceData>> mClampers;
@@ -85,70 +71,49 @@
     private float mCustomAnimationRate = DisplayBrightnessState.CUSTOM_ANIMATION_RATE_NOT_SET;
     @Nullable
     private Type mClamperType = null;
-    private final SensorEventListener mLightSensorListener;
-    private Sensor mRegisteredLightSensor = null;
-    private Sensor mLightSensor;
-    private String mLightSensorType;
-    private String mLightSensorName;
-    private AmbientFilter mAmbientFilter;
-    private final DisplayDeviceConfig mDisplayDeviceConfig;
-    private final Resources mResources;
-    private final int mLightSensorRate;
 
-    private final Injector mInjector;
     private boolean mClamperApplied = false;
 
+    private final LightSensorController.LightSensorListener mLightSensorListener =
+            new LightSensorController.LightSensorListener() {
+                @Override
+                public void onAmbientLuxChange(float lux) {
+                    mModifiers.forEach(mModifier -> mModifier.setAmbientLux(lux));
+                }
+            };
+
     public BrightnessClamperController(Handler handler,
             ClamperChangeListener clamperChangeListener, DisplayDeviceData data, Context context,
             DisplayManagerFlags flags, SensorManager sensorManager) {
-        this(null, handler, clamperChangeListener, data, context, flags, sensorManager);
+        this(new Injector(), handler, clamperChangeListener, data, context, flags, sensorManager);
     }
 
     @VisibleForTesting
     BrightnessClamperController(Injector injector, Handler handler,
             ClamperChangeListener clamperChangeListener, DisplayDeviceData data, Context context,
             DisplayManagerFlags flags, SensorManager sensorManager) {
-        mInjector = injector == null ? new Injector() : injector;
-        mDeviceConfigParameterProvider = mInjector.getDeviceConfigParameterProvider();
+        mDeviceConfigParameterProvider = injector.getDeviceConfigParameterProvider();
         mHandler = handler;
-        mSensorManager = sensorManager;
-        mDisplayDeviceConfig = data.mDisplayDeviceConfig;
-        mLightSensorListener = new SensorEventListener() {
-            @Override
-            public void onSensorChanged(SensorEvent event) {
-                long now = SystemClock.elapsedRealtime();
-                mAmbientFilter.addValue(TimeUnit.NANOSECONDS.toMillis(event.timestamp),
-                        event.values[0]);
-                final float lux = mAmbientFilter.getEstimate(now);
-                mModifiers.forEach(mModifier -> mModifier.setAmbientLux(lux));
-            }
-
-            @Override
-            public void onAccuracyChanged(Sensor sensor, int accuracy) {
-                // unused
-            }
-        };
+        mLightSensorController = injector.getLightSensorController(sensorManager, context,
+                mLightSensorListener, mHandler);
 
         mClamperChangeListenerExternal = clamperChangeListener;
         mExecutor = new HandlerExecutor(handler);
-        mResources = context.getResources();
-        mLightSensorRate = context.getResources().getInteger(
-                R.integer.config_autoBrightnessLightSensorRate);
 
         Runnable clamperChangeRunnableInternal = this::recalculateBrightnessCap;
-
         ClamperChangeListener clamperChangeListenerInternal = () -> {
             if (!mHandler.hasCallbacks(clamperChangeRunnableInternal)) {
                 mHandler.post(clamperChangeRunnableInternal);
             }
         };
 
-        mClampers = mInjector.getClampers(handler, clamperChangeListenerInternal, data, flags,
+        mClampers = injector.getClampers(handler, clamperChangeListenerInternal, data, flags,
                 context);
-        mModifiers = mInjector.getModifiers(flags, context, handler, clamperChangeListener,
-                data.mDisplayDeviceConfig, mSensorManager);
+        mModifiers = injector.getModifiers(flags, context, handler, clamperChangeListener,
+                data.mDisplayDeviceConfig);
         mOnPropertiesChangedListener =
                 properties -> mClampers.forEach(BrightnessClamper::onDeviceConfigChanged);
+        mLightSensorController.configure(data.getAmbientLightSensor(), data.getDisplayId());
         start();
     }
 
@@ -156,7 +121,9 @@
      * Should be called when display changed. Forwards the call to individual clampers
      */
     public void onDisplayChanged(DisplayDeviceData data) {
+        mLightSensorController.configure(data.getAmbientLightSensor(), data.getDisplayId());
         mClampers.forEach(clamper -> clamper.onDisplayChanged(data));
+        adjustLightSensorSubscription();
     }
 
     /**
@@ -184,9 +151,9 @@
         }
 
         if (displayState != STATE_ON) {
-            unregisterSensorListener();
+            mLightSensorController.stop();
         } else {
-            maybeRegisterLightSensor();
+            adjustLightSensorSubscription();
         }
 
         for (int i = 0; i < mModifiers.size(); i++) {
@@ -231,9 +198,8 @@
         writer.println("  mBrightnessCap: " + mBrightnessCap);
         writer.println("  mClamperType: " + mClamperType);
         writer.println("  mClamperApplied: " + mClamperApplied);
-        writer.println("  mLightSensor=" + mLightSensor);
-        writer.println("  mRegisteredLightSensor=" + mRegisteredLightSensor);
         IndentingPrintWriter ipw = new IndentingPrintWriter(writer, "    ");
+        mLightSensorController.dump(ipw);
         mClampers.forEach(clamper -> clamper.dump(ipw));
         mModifiers.forEach(modifier -> modifier.dump(ipw));
     }
@@ -245,6 +211,7 @@
     public void stop() {
         mDeviceConfigParameterProvider.removeOnPropertiesChangedListener(
                 mOnPropertiesChangedListener);
+        mLightSensorController.stop();
         mClampers.forEach(BrightnessClamper::stop);
         mModifiers.forEach(BrightnessStateModifier::stop);
     }
@@ -281,10 +248,15 @@
         if (!mClampers.isEmpty()) {
             mDeviceConfigParameterProvider.addOnPropertiesChangedListener(
                     mExecutor, mOnPropertiesChangedListener);
-            reloadLightSensorData(mDisplayDeviceConfig);
-            mLightSensor = mInjector.getLightSensor(
-                    mSensorManager, mLightSensorType, mLightSensorName);
-            maybeRegisterLightSensor();
+        }
+        adjustLightSensorSubscription();
+    }
+
+    private void adjustLightSensorSubscription() {
+        if (mModifiers.stream().anyMatch(BrightnessStateModifier::shouldListenToLightSensor)) {
+            mLightSensorController.restart();
+        } else {
+            mLightSensorController.stop();
         }
     }
 
@@ -323,7 +295,7 @@
 
         List<BrightnessStateModifier> getModifiers(DisplayManagerFlags flags, Context context,
                 Handler handler, ClamperChangeListener listener,
-                DisplayDeviceConfig displayDeviceConfig, SensorManager sensorManager) {
+                DisplayDeviceConfig displayDeviceConfig) {
             List<BrightnessStateModifier> modifiers = new ArrayList<>();
             modifiers.add(new DisplayDimModifier(context));
             modifiers.add(new BrightnessLowPowerModeModifier());
@@ -332,14 +304,18 @@
                 modifiers.add(new BrightnessLowLuxModifier(handler, listener, context,
                         displayDeviceConfig));
             }
+            if (flags.useNewHdrBrightnessModifier()) {
+                modifiers.add(new HdrBrightnessModifier());
+            }
             return modifiers;
         }
 
-        Sensor getLightSensor(SensorManager sensorManager, String type, String name) {
-            return SensorUtils.findSensor(sensorManager, type,
-                    name, Sensor.TYPE_LIGHT);
+        LightSensorController getLightSensorController(SensorManager sensorManager,
+                Context context, LightSensorController.LightSensorListener listener,
+                Handler handler) {
+            return new LightSensorController(sensorManager, context.getResources(),
+                    listener, handler);
         }
-
     }
 
     /**
@@ -354,17 +330,21 @@
         private final String mThermalThrottlingDataId;
         @NonNull
         private final String mPowerThrottlingDataId;
-
+        @NonNull
         private final DisplayDeviceConfig mDisplayDeviceConfig;
 
+        private final int mDisplayId;
+
         public DisplayDeviceData(@NonNull String uniqueDisplayId,
                 @NonNull String thermalThrottlingDataId,
                 @NonNull String powerThrottlingDataId,
-                @NonNull DisplayDeviceConfig displayDeviceConfig) {
+                @NonNull DisplayDeviceConfig displayDeviceConfig,
+                int displayId) {
             mUniqueDisplayId = uniqueDisplayId;
             mThermalThrottlingDataId = thermalThrottlingDataId;
             mPowerThrottlingDataId = powerThrottlingDataId;
             mDisplayDeviceConfig = displayDeviceConfig;
+            mDisplayId = displayId;
         }
 
 
@@ -412,55 +392,18 @@
         }
 
         @NonNull
+        @Override
         public SensorData getTempSensor() {
             return mDisplayDeviceConfig.getTempSensor();
         }
-    }
 
-    private void maybeRegisterLightSensor() {
-        if (mModifiers.stream().noneMatch(BrightnessStateModifier::shouldListenToLightSensor)) {
-            return;
+        @NonNull
+        SensorData getAmbientLightSensor() {
+            return mDisplayDeviceConfig.getAmbientLightSensor();
         }
 
-        if (mRegisteredLightSensor == mLightSensor) {
-            return;
-        }
-
-        if (mRegisteredLightSensor != null) {
-            unregisterSensorListener();
-        }
-
-        mAmbientFilter = AmbientFilterFactory.createBrightnessFilter(TAG, mResources);
-        mSensorManager.registerListener(mLightSensorListener,
-                mLightSensor, mLightSensorRate * 1000, mHandler);
-        mRegisteredLightSensor = mLightSensor;
-
-        if (DEBUG) {
-            Slog.d(TAG, "maybeRegisterLightSensor");
-        }
-    }
-
-    private void unregisterSensorListener() {
-        mSensorManager.unregisterListener(mLightSensorListener);
-        mRegisteredLightSensor = null;
-        mModifiers.forEach(mModifier -> mModifier.setAmbientLux(INVALID_LUX)); // set lux to invalid
-        if (DEBUG) {
-            Slog.d(TAG, "unregisterSensorListener");
-        }
-    }
-
-    private void reloadLightSensorData(DisplayDeviceConfig displayDeviceConfig) {
-        // The displayDeviceConfig (ddc) contains display specific preferences. When loaded,
-        // it naturally falls back to the global config.xml.
-        if (displayDeviceConfig != null
-                && displayDeviceConfig.getAmbientLightSensor() != null) {
-            // This covers both the ddc and the config.xml fallback
-            mLightSensorType = displayDeviceConfig.getAmbientLightSensor().type;
-            mLightSensorName = displayDeviceConfig.getAmbientLightSensor().name;
-        } else if (mLightSensorName == null && mLightSensorType == null) {
-            mLightSensorType = mResources.getString(
-                    com.android.internal.R.string.config_displayLightSensorType);
-            mLightSensorName = "";
+        int getDisplayId() {
+            return mDisplayId;
         }
     }
 }
diff --git a/services/core/java/com/android/server/display/brightness/clamper/HdrBrightnessModifier.java b/services/core/java/com/android/server/display/brightness/clamper/HdrBrightnessModifier.java
new file mode 100644
index 0000000..a829866
--- /dev/null
+++ b/services/core/java/com/android/server/display/brightness/clamper/HdrBrightnessModifier.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.clamper;
+
+import android.hardware.display.DisplayManagerInternal;
+
+import com.android.server.display.DisplayBrightnessState;
+
+import java.io.PrintWriter;
+
+public class HdrBrightnessModifier implements BrightnessStateModifier {
+    @Override
+    public void apply(DisplayManagerInternal.DisplayPowerRequest request,
+            DisplayBrightnessState.Builder stateBuilder) {
+        // noop
+    }
+
+    @Override
+    public void dump(PrintWriter printWriter) {
+        // noop
+    }
+
+    @Override
+    public void stop() {
+        // noop
+    }
+
+    @Override
+    public boolean shouldListenToLightSensor() {
+        return false;
+    }
+
+    @Override
+    public void setAmbientLux(float lux) {
+        // noop
+    }
+}
diff --git a/services/core/java/com/android/server/display/brightness/clamper/LightSensorController.java b/services/core/java/com/android/server/display/brightness/clamper/LightSensorController.java
new file mode 100644
index 0000000..d89dd28
--- /dev/null
+++ b/services/core/java/com/android/server/display/brightness/clamper/LightSensorController.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.clamper;
+
+import android.annotation.Nullable;
+import android.content.res.Resources;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.util.Slog;
+import android.view.Display;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.display.config.SensorData;
+import com.android.server.display.utils.AmbientFilter;
+import com.android.server.display.utils.AmbientFilterFactory;
+import com.android.server.display.utils.DebugUtils;
+import com.android.server.display.utils.SensorUtils;
+
+import java.io.PrintWriter;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Manages light sensor subscription and notifies its listener about ambient lux changes
+ */
+public class LightSensorController {
+    private static final String TAG = "LightSensorController";
+
+    // To enable these logs, run:
+    // 'adb shell setprop persist.log.tag.LightSensorController DEBUG && adb reboot'
+    private static final boolean DEBUG = DebugUtils.isDebuggable(TAG);
+    static final float INVALID_LUX = -1f;
+
+    private final SensorManager mSensorManager;
+    private final LightSensorListener mLightSensorListener;
+    private final Handler mHandler;
+    private final Injector mInjector;
+    private final AmbientFilter mAmbientFilter;
+
+    private Sensor mLightSensor;
+    private Sensor mRegisteredLightSensor = null;
+    private final int mLightSensorRate;
+
+    private final SensorEventListener mLightSensorEventListener = new SensorEventListener() {
+        @Override
+        public void onSensorChanged(SensorEvent event) {
+            long now = mInjector.getTime();
+            mAmbientFilter.addValue(TimeUnit.NANOSECONDS.toMillis(event.timestamp),
+                    event.values[0]);
+            final float lux = mAmbientFilter.getEstimate(now);
+            mLightSensorListener.onAmbientLuxChange(lux);
+        }
+
+        @Override
+        public void onAccuracyChanged(Sensor sensor, int accuracy) {
+            // unused
+        }
+    };
+
+    LightSensorController(SensorManager sensorManager, Resources resources,
+            LightSensorListener listener, Handler handler) {
+        this(sensorManager, resources, listener, handler, new Injector());
+    }
+
+    @VisibleForTesting
+    LightSensorController(SensorManager sensorManager, Resources resources,
+            LightSensorListener listener, Handler handler, Injector injector) {
+        mSensorManager = sensorManager;
+        mLightSensorRate = injector.getLightSensorRate(resources);
+        mAmbientFilter = injector.getAmbientFilter(resources);
+        mLightSensorListener = listener;
+        mHandler = handler;
+        mInjector = injector;
+    }
+
+    void restart() {
+        if (mRegisteredLightSensor == mLightSensor) {
+            return;
+        }
+        if (mRegisteredLightSensor != null) {
+            stop();
+        }
+        if (mLightSensor == null) {
+            return;
+        }
+
+        mSensorManager.registerListener(mLightSensorEventListener,
+                mLightSensor, mLightSensorRate * 1000, mHandler);
+        mRegisteredLightSensor = mLightSensor;
+
+        if (DEBUG) {
+            Slog.d(TAG, "restart");
+        }
+    }
+
+    void stop() {
+        if (mRegisteredLightSensor == null) {
+            return;
+        }
+        mSensorManager.unregisterListener(mLightSensorEventListener);
+        mRegisteredLightSensor = null;
+        mAmbientFilter.clear();
+        mLightSensorListener.onAmbientLuxChange(INVALID_LUX);
+        if (DEBUG) {
+            Slog.d(TAG, "stop");
+        }
+    }
+
+    void configure(SensorData sensorData, int displayId) {
+        final int fallbackType = displayId == Display.DEFAULT_DISPLAY
+                ? Sensor.TYPE_LIGHT : SensorUtils.NO_FALLBACK;
+        mLightSensor = mInjector.getLightSensor(mSensorManager, sensorData, fallbackType);
+    }
+
+    void dump(PrintWriter writer) {
+        writer.println("LightSensorController");
+        writer.println("  mLightSensor=" + mLightSensor);
+        writer.println("  mRegisteredLightSensor=" + mRegisteredLightSensor);
+    }
+
+    static class Injector {
+        @Nullable
+        Sensor getLightSensor(SensorManager sensorManager, SensorData sensorData,
+                int fallbackType) {
+            return SensorUtils.findSensor(sensorManager, sensorData, fallbackType);
+        }
+
+        AmbientFilter getAmbientFilter(Resources resources) {
+            return AmbientFilterFactory.createBrightnessFilter(TAG, resources);
+        }
+
+        int getLightSensorRate(Resources resources) {
+            return resources.getInteger(R.integer.config_autoBrightnessLightSensorRate);
+        }
+
+        // should be consistent with SensorEvent.timestamp
+        long getTime() {
+            return SystemClock.elapsedRealtime();
+        }
+    }
+
+    interface  LightSensorListener {
+        void onAmbientLuxChange(float ambientLux);
+    }
+}
diff --git a/services/core/java/com/android/server/display/brightness/strategy/AutoBrightnessFallbackStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/AutoBrightnessFallbackStrategy.java
index 16bf177f..d8b95ec 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/AutoBrightnessFallbackStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/AutoBrightnessFallbackStrategy.java
@@ -75,7 +75,6 @@
         brightnessReason.setReason(BrightnessReason.REASON_SCREEN_OFF_BRIGHTNESS_SENSOR);
         return new DisplayBrightnessState.Builder()
                 .setBrightness(brightness)
-                .setSdrBrightness(brightness)
                 .setBrightnessReason(brightnessReason)
                 .setDisplayBrightnessStrategyName(getName())
                 .setShouldUpdateScreenBrightnessSetting(brightness
diff --git a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
index b43b35b..706b4a6 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
@@ -15,6 +15,8 @@
  */
 package com.android.server.display.brightness.strategy;
 
+import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
+
 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT;
 import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DOZE;
 
@@ -133,14 +135,20 @@
         // We are still in the process of updating the power state, so there's no need to trigger
         // an update again
         switchMode(targetDisplayState, /* sendUpdate= */ false);
-        final boolean autoBrightnessEnabledInDoze =
-                allowAutoBrightnessWhileDozingConfig && Display.isDozeState(targetDisplayState);
+
+        // If the policy is POLICY_DOZE and the display state is STATE_ON, auto-brightness should
+        // only be enabled if the config allows it
+        final boolean autoBrightnessEnabledInDoze = allowAutoBrightnessWhileDozingConfig
+                && policy == POLICY_DOZE && targetDisplayState != Display.STATE_OFF;
+
         mIsAutoBrightnessEnabled = shouldUseAutoBrightness()
-                && (targetDisplayState == Display.STATE_ON || autoBrightnessEnabledInDoze)
+                && ((targetDisplayState == Display.STATE_ON && policy != POLICY_DOZE)
+                || autoBrightnessEnabledInDoze)
                 && brightnessReason != BrightnessReason.REASON_OVERRIDE
                 && mAutomaticBrightnessController != null;
         mAutoBrightnessDisabledDueToDisplayOff = shouldUseAutoBrightness()
-                && !(targetDisplayState == Display.STATE_ON || autoBrightnessEnabledInDoze);
+                && !((targetDisplayState == Display.STATE_ON && policy != POLICY_DOZE)
+                || autoBrightnessEnabledInDoze);
         final int autoBrightnessState = mIsAutoBrightnessEnabled
                 && brightnessReason != BrightnessReason.REASON_FOLLOWER
                 ? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
@@ -289,7 +297,6 @@
                 /* isAutomaticBrightnessAdjusted = */ true);
         return new DisplayBrightnessState.Builder()
                 .setBrightness(brightness)
-                .setSdrBrightness(brightness)
                 .setBrightnessReason(brightnessReason)
                 .setDisplayBrightnessStrategyName(getName())
                 .setIsSlowChange(mIsSlowChange)
diff --git a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2.java b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2.java
index 4d9c18a..c87872c 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2.java
@@ -15,6 +15,8 @@
  */
 package com.android.server.display.brightness.strategy;
 
+import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
+
 import android.annotation.Nullable;
 import android.content.Context;
 import android.hardware.display.BrightnessConfiguration;
@@ -107,14 +109,19 @@
     public void setAutoBrightnessState(int targetDisplayState,
             boolean allowAutoBrightnessWhileDozingConfig, int brightnessReason, int policy,
             float lastUserSetScreenBrightness, boolean userSetBrightnessChanged) {
-        final boolean autoBrightnessEnabledInDoze =
-                allowAutoBrightnessWhileDozingConfig && Display.isDozeState(targetDisplayState);
+        // If the policy is POLICY_DOZE and the display state is STATE_ON, auto-brightness should
+        // only be enabled if the config allows it
+        final boolean autoBrightnessEnabledInDoze = allowAutoBrightnessWhileDozingConfig
+                && policy == POLICY_DOZE && targetDisplayState != Display.STATE_OFF;
+
         mIsAutoBrightnessEnabled = shouldUseAutoBrightness()
-                && (targetDisplayState == Display.STATE_ON || autoBrightnessEnabledInDoze)
+                && ((targetDisplayState == Display.STATE_ON && policy != POLICY_DOZE)
+                || autoBrightnessEnabledInDoze)
                 && brightnessReason != BrightnessReason.REASON_OVERRIDE
                 && mAutomaticBrightnessController != null;
         mAutoBrightnessDisabledDueToDisplayOff = shouldUseAutoBrightness()
-                && !(targetDisplayState == Display.STATE_ON || autoBrightnessEnabledInDoze);
+                && !((targetDisplayState == Display.STATE_ON  && policy != POLICY_DOZE)
+                || autoBrightnessEnabledInDoze);
         final int autoBrightnessState = mIsAutoBrightnessEnabled
                 && brightnessReason != BrightnessReason.REASON_FOLLOWER
                 ? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
diff --git a/services/core/java/com/android/server/display/brightness/strategy/BoostBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/BoostBrightnessStrategy.java
index 009a47a..2ef7ea9 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/BoostBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/BoostBrightnessStrategy.java
@@ -42,7 +42,6 @@
         // the brightness
         DisplayBrightnessState displayBrightnessState =
                 BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_BOOST,
-                        PowerManager.BRIGHTNESS_MAX,
                         PowerManager.BRIGHTNESS_MAX, getName());
         return displayBrightnessState;
     }
diff --git a/services/core/java/com/android/server/display/brightness/strategy/DozeBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/DozeBrightnessStrategy.java
index 2b493f3..0855c9e 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/DozeBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/DozeBrightnessStrategy.java
@@ -36,7 +36,6 @@
         // the brightness
         return BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_DOZE,
                 strategyExecutionRequest.getDisplayPowerRequest().dozeScreenBrightness,
-                strategyExecutionRequest.getDisplayPowerRequest().dozeScreenBrightness,
                 getName());
     }
 
diff --git a/services/core/java/com/android/server/display/brightness/strategy/FallbackBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/FallbackBrightnessStrategy.java
index 0b92317..7c0c931 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/FallbackBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/FallbackBrightnessStrategy.java
@@ -39,7 +39,6 @@
         brightnessReason.setReason(BrightnessReason.REASON_MANUAL);
         return new DisplayBrightnessState.Builder()
                 .setBrightness(strategyExecutionRequest.getCurrentScreenBrightness())
-                .setSdrBrightness(strategyExecutionRequest.getCurrentScreenBrightness())
                 .setBrightnessReason(brightnessReason)
                 .setDisplayBrightnessStrategyName(getName())
                 // The fallback brightness might change due to clamping. Make sure we tell the rest
diff --git a/services/core/java/com/android/server/display/brightness/strategy/FollowerBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/FollowerBrightnessStrategy.java
index 5a07ce2..7ab92d1 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/FollowerBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/FollowerBrightnessStrategy.java
@@ -53,7 +53,7 @@
         // Todo(b/241308599): Introduce a validator class and add validations before setting
         // the brightness
         return BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_FOLLOWER,
-                mBrightnessToFollow, mBrightnessToFollow, getName(), mBrightnessToFollowSlowChange);
+                mBrightnessToFollow, getName(), mBrightnessToFollowSlowChange);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/display/brightness/strategy/InvalidBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/InvalidBrightnessStrategy.java
index 9dc6cff..f9e56bb 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/InvalidBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/InvalidBrightnessStrategy.java
@@ -34,8 +34,7 @@
     public DisplayBrightnessState updateBrightness(
             StrategyExecutionRequest strategyExecutionRequest) {
         return BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_UNKNOWN,
-                PowerManager.BRIGHTNESS_INVALID_FLOAT, PowerManager.BRIGHTNESS_INVALID_FLOAT,
-                getName());
+                PowerManager.BRIGHTNESS_INVALID_FLOAT, getName());
     }
 
     @Override
diff --git a/services/core/java/com/android/server/display/brightness/strategy/OffloadBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/OffloadBrightnessStrategy.java
index b46873a..1d7d3a6 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/OffloadBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/OffloadBrightnessStrategy.java
@@ -55,7 +55,6 @@
         brightnessReason.setReason(BrightnessReason.REASON_OFFLOAD);
         return new DisplayBrightnessState.Builder()
                 .setBrightness(offloadBrightness)
-                .setSdrBrightness(offloadBrightness)
                 .setBrightnessReason(brightnessReason)
                 .setDisplayBrightnessStrategyName(getName())
                 .setIsSlowChange(false)
diff --git a/services/core/java/com/android/server/display/brightness/strategy/OverrideBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/OverrideBrightnessStrategy.java
index a2982b1..40a495c 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/OverrideBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/OverrideBrightnessStrategy.java
@@ -35,8 +35,7 @@
         // the brightness
         return BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_OVERRIDE,
                 strategyExecutionRequest.getDisplayPowerRequest().screenBrightnessOverride,
-                strategyExecutionRequest.getDisplayPowerRequest()
-                        .screenBrightnessOverride, getName());
+                getName());
     }
 
     @Override
diff --git a/services/core/java/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategy.java
index 6a3162c..fe7a6b7 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategy.java
@@ -36,7 +36,6 @@
         // Todo(b/241308599): Introduce a validator class and add validations before setting
         // the brightness
         return BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_SCREEN_OFF,
-                PowerManager.BRIGHTNESS_OFF_FLOAT,
                 PowerManager.BRIGHTNESS_OFF_FLOAT, getName());
     }
 
diff --git a/services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java
index 6b8817a..ca0beef 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java
@@ -48,7 +48,6 @@
         // the brightness
         DisplayBrightnessState displayBrightnessState =
                 BrightnessUtils.constructDisplayBrightnessState(BrightnessReason.REASON_TEMPORARY,
-                        mTemporaryScreenBrightness,
                         mTemporaryScreenBrightness, getName());
         return displayBrightnessState;
     }
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 3883604..bd759f3 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -25,6 +25,9 @@
 import static android.hardware.display.ColorDisplayManager.COLOR_MODE_SATURATED;
 import static android.hardware.display.ColorDisplayManager.VENDOR_COLOR_MODE_RANGE_MAX;
 import static android.hardware.display.ColorDisplayManager.VENDOR_COLOR_MODE_RANGE_MIN;
+import static android.os.UserHandle.USER_SYSTEM;
+import static android.os.UserHandle.getCallingUserId;
+import static android.os.UserManager.isVisibleBackgroundUsersEnabled;
 
 import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY;
 
@@ -80,6 +83,7 @@
 import com.android.server.SystemService;
 import com.android.server.accessibility.Flags;
 import com.android.server.display.feature.DisplayManagerFlags;
+import com.android.server.pm.UserManagerService;
 import com.android.server.twilight.TwilightListener;
 import com.android.server.twilight.TwilightManager;
 import com.android.server.twilight.TwilightState;
@@ -186,9 +190,14 @@
 
     private final Object mCctTintApplierLock = new Object();
 
+    private final boolean mVisibleBackgroundUsersEnabled;
+    private final UserManagerService mUserManager;
+
     public ColorDisplayService(Context context) {
         super(context);
         mHandler = new TintHandler(DisplayThread.get().getLooper());
+        mVisibleBackgroundUsersEnabled = isVisibleBackgroundUsersEnabled();
+        mUserManager = UserManagerService.getInstance();
     }
 
     @Override
@@ -1745,6 +1754,9 @@
         @Override
         public void setColorMode(int colorMode) {
             setColorMode_enforcePermission();
+
+            enforceValidCallingUser("setColorMode");
+
             final long token = Binder.clearCallingIdentity();
             try {
                 setColorModeInternal(colorMode);
@@ -1784,6 +1796,9 @@
             if (!hasTransformsPermission && !hasLegacyPermission) {
                 throw new SecurityException("Permission required to set display saturation level");
             }
+
+            enforceValidCallingUser("setSaturationLevel");
+
             final long token = Binder.clearCallingIdentity();
             try {
                 setSaturationLevelInternal(level);
@@ -1812,6 +1827,8 @@
         public boolean setAppSaturationLevel(String packageName, int level) {
             super.setAppSaturationLevel_enforcePermission();
 
+            enforceValidCallingUser("setAppSaturationLevel");
+
             final String callingPackageName = LocalServices.getService(PackageManagerInternal.class)
                     .getNameForUid(Binder.getCallingUid());
             final long token = Binder.clearCallingIdentity();
@@ -1838,6 +1855,9 @@
         @Override
         public boolean setNightDisplayActivated(boolean activated) {
             setNightDisplayActivated_enforcePermission();
+
+            enforceValidCallingUser("setNightDisplayActivated");
+
             final long token = Binder.clearCallingIdentity();
             try {
                 mNightDisplayTintController.setActivated(activated);
@@ -1861,6 +1881,9 @@
         @Override
         public boolean setNightDisplayColorTemperature(int temperature) {
             setNightDisplayColorTemperature_enforcePermission();
+
+            enforceValidCallingUser("setNightDisplayColorTemperature");
+
             final long token = Binder.clearCallingIdentity();
             try {
                 return mNightDisplayTintController.setColorTemperature(temperature);
@@ -1883,6 +1906,9 @@
         @Override
         public boolean setNightDisplayAutoMode(int autoMode) {
             setNightDisplayAutoMode_enforcePermission();
+
+            enforceValidCallingUser("setNightDisplayAutoMode");
+
             final long token = Binder.clearCallingIdentity();
             try {
                 return setNightDisplayAutoModeInternal(autoMode);
@@ -1917,6 +1943,9 @@
         @Override
         public boolean setNightDisplayCustomStartTime(Time startTime) {
             setNightDisplayCustomStartTime_enforcePermission();
+
+            enforceValidCallingUser("setNightDisplayCustomStartTime");
+
             final long token = Binder.clearCallingIdentity();
             try {
                 return setNightDisplayCustomStartTimeInternal(startTime);
@@ -1939,6 +1968,9 @@
         @Override
         public boolean setNightDisplayCustomEndTime(Time endTime) {
             setNightDisplayCustomEndTime_enforcePermission();
+
+            enforceValidCallingUser("setNightDisplayCustomEndTime");
+
             final long token = Binder.clearCallingIdentity();
             try {
                 return setNightDisplayCustomEndTimeInternal(endTime);
@@ -1961,6 +1993,9 @@
         @Override
         public boolean setDisplayWhiteBalanceEnabled(boolean enabled) {
             setDisplayWhiteBalanceEnabled_enforcePermission();
+
+            enforceValidCallingUser("setDisplayWhiteBalanceEnabled");
+
             final long token = Binder.clearCallingIdentity();
             try {
                 return setDisplayWhiteBalanceSettingEnabled(enabled);
@@ -1993,6 +2028,9 @@
         @Override
         public boolean setReduceBrightColorsActivated(boolean activated) {
             setReduceBrightColorsActivated_enforcePermission();
+
+            enforceValidCallingUser("setReduceBrightColorsActivated");
+
             final long token = Binder.clearCallingIdentity();
             try {
                 return setReduceBrightColorsActivatedInternal(activated);
@@ -2025,6 +2063,9 @@
         @Override
         public boolean setReduceBrightColorsStrength(int strength) {
             setReduceBrightColorsStrength_enforcePermission();
+
+            enforceValidCallingUser("setReduceBrightColorsStrength");
+
             final long token = Binder.clearCallingIdentity();
             try {
                 return setReduceBrightColorsStrengthInternal(strength);
@@ -2064,4 +2105,32 @@
             }
         }
     }
+
+    /**
+     * This method validates whether the calling user is allowed to set display's color transform
+     * on a device that enables visible background users.
+     * Only system or current user or the user that belongs to the same profile group as the current
+     * user is permitted to set the color transform.
+     */
+    private void enforceValidCallingUser(String method) {
+        if (!mVisibleBackgroundUsersEnabled) {
+            return;
+        }
+
+        int callingUserId = getCallingUserId();
+        if (callingUserId == USER_SYSTEM || callingUserId == mCurrentUser) {
+            return;
+        }
+        long ident = Binder.clearCallingIdentity();
+        try {
+            if (mUserManager.isSameProfileGroup(callingUserId, mCurrentUser)) {
+                return;
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+
+        throw new SecurityException("Calling user id: " + callingUserId
+                + ", is not permitted to use Method " + method + "().");
+    }
 }
diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
index f56d803..3ce7d2a 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -179,6 +179,16 @@
             Flags::offloadDozeOverrideHoldsWakelock
     );
 
+    private final FlagState mOffloadSessionCancelBlockScreenOn =
+            new FlagState(
+                    Flags.FLAG_OFFLOAD_SESSION_CANCEL_BLOCK_SCREEN_ON,
+                    Flags::offloadSessionCancelBlockScreenOn);
+
+    private final FlagState mNewHdrBrightnessModifier =
+            new FlagState(
+                    Flags.FLAG_NEW_HDR_BRIGHTNESS_MODIFIER,
+                    Flags::newHdrBrightnessModifier);
+
     /**
      * @return {@code true} if 'port' is allowed in display layout configuration file.
      */
@@ -352,6 +362,10 @@
         return mOffloadDozeOverrideHoldsWakelock.isEnabled();
     }
 
+    public boolean isOffloadSessionCancelBlockScreenOnEnabled() {
+        return mOffloadSessionCancelBlockScreenOn.isEnabled();
+    }
+
     /**
      * @return Whether to ignore preferredRefreshRate app request conversion to display mode or not
      */
@@ -364,6 +378,13 @@
     }
 
     /**
+     * @return Whether to use new HDR brightness modifier or not
+     */
+    public boolean useNewHdrBrightnessModifier() {
+        return mNewHdrBrightnessModifier.isEnabled();
+    }
+
+    /**
      * dumps all flagstates
      * @param pw printWriter
      */
@@ -399,6 +420,8 @@
         pw.println(" " + mIgnoreAppPreferredRefreshRate);
         pw.println(" " + mSynthetic60hzModes);
         pw.println(" " + mOffloadDozeOverrideHoldsWakelock);
+        pw.println(" " + mOffloadSessionCancelBlockScreenOn);
+        pw.println(" " + mNewHdrBrightnessModifier);
     }
 
     private static class FlagState {
diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig
index 95d0ca3..fd3af23 100644
--- a/services/core/java/com/android/server/display/feature/display_flags.aconfig
+++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig
@@ -299,3 +299,19 @@
       purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    name: "offload_session_cancel_block_screen_on"
+    namespace: "wear_frameworks"
+    description: "Flag for DisplayPowerController to start notifying DisplayOffloadSession about cancelling screen on blocker."
+    bug: "331725519"
+    is_fixed_read_only: true
+}
+
+flag {
+    name: "new_hdr_brightness_modifier"
+    namespace: "display_manager"
+    description: "Flag for new HDR brightness clamper."
+    bug: "331275392"
+    is_fixed_read_only: true
+}
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index 18a9986..886857c 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -1079,6 +1079,21 @@
         }
 
         @Override // Binder call
+        public void finishSelfOneway(IBinder token, boolean immediate) {
+            // Requires no permission, called by Dream from an arbitrary process.
+            if (token == null) {
+                throw new IllegalArgumentException("token must not be null");
+            }
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                finishSelfInternal(token, immediate);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override // Binder call
         public void startDozing(
                 IBinder token, int screenState, @Display.StateReason int reason,
                 int screenBrightness) {
@@ -1096,6 +1111,23 @@
         }
 
         @Override // Binder call
+        public void startDozingOneway(
+                IBinder token, int screenState, @Display.StateReason int reason,
+                int screenBrightness) {
+            // Requires no permission, called by Dream from an arbitrary process.
+            if (token == null) {
+                throw new IllegalArgumentException("token must not be null");
+            }
+
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                startDozingInternal(token, screenState, reason, screenBrightness);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+
+        @Override // Binder call
         public void stopDozing(IBinder token) {
             // Requires no permission, called by Dream from an arbitrary process.
             if (token == null) {
diff --git a/services/core/java/com/android/server/flags/services.aconfig b/services/core/java/com/android/server/flags/services.aconfig
index 9bbcb0c..d387828 100644
--- a/services/core/java/com/android/server/flags/services.aconfig
+++ b/services/core/java/com/android/server/flags/services.aconfig
@@ -28,3 +28,10 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    namespace: "wear_frameworks"
+    name: "optional_background_install_control"
+    description: "Enable BackgroundInstallControl based on system feature to prevent it from starting on form factors."
+    bug: "340928990"
+}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java
index cd2c037..5696fba 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecController.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java
@@ -427,7 +427,7 @@
     @ServiceThreadOnly
     void setHpdSignalType(@Constants.HpdSignalType int signal, int portId) {
         assertRunOnServiceThread();
-        HdmiLogger.debug("setHpdSignalType: portId %b, signal %b", portId, signal);
+        HdmiLogger.debug("setHpdSignalType: portId %d, signal %d", portId, signal);
         mNativeWrapperImpl.nativeSetHpdSignalType(signal, portId);
     }
 
@@ -439,7 +439,7 @@
     @Constants.HpdSignalType
     int getHpdSignalType(int portId) {
         assertRunOnServiceThread();
-        HdmiLogger.debug("getHpdSignalType: portId %b ", portId);
+        HdmiLogger.debug("getHpdSignalType: portId %d ", portId);
         return mNativeWrapperImpl.nativeGetHpdSignalType(portId);
     }
 
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 275c930..49888db 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -67,7 +67,7 @@
 /**
  * Represent a logical device of type TV residing in Android system.
  */
-public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
+public class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
     private static final String TAG = "HdmiCecLocalDeviceTv";
 
     // Whether ARC is available or not. "true" means that ARC is established between TV and
@@ -113,6 +113,18 @@
     // handle.
     private final DelayedMessageBuffer mDelayedMessageBuffer = new DelayedMessageBuffer(this);
 
+    private boolean mWasActiveSourceSetToConnectedDevice = false;
+
+    @VisibleForTesting
+    protected boolean getWasActiveSourceSetToConnectedDevice() {
+        return mWasActiveSourceSetToConnectedDevice;
+    }
+
+    protected void setWasActiveSourceSetToConnectedDevice(
+            boolean wasActiveSourceSetToConnectedDevice) {
+        mWasActiveSourceSetToConnectedDevice = wasActiveSourceSetToConnectedDevice;
+    }
+
     // Defines the callback invoked when TV input framework is updated with input status.
     // We are interested in the notification for HDMI input addition event, in order to
     // process any CEC commands that arrived before the input is added.
@@ -474,6 +486,7 @@
                 || info.getDeviceType() == HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) {
             mService.getHdmiCecNetwork().updateDevicePowerStatus(logicalAddress,
                     HdmiControlManager.POWER_STATUS_ON);
+            setWasActiveSourceSetToConnectedDevice(true);
             ActiveSource activeSource = ActiveSource.of(logicalAddress, physicalAddress);
             ActiveSourceHandler.create(this, null).process(activeSource, info.getDeviceType());
         } else {
@@ -489,13 +502,16 @@
     protected int handleStandby(HdmiCecMessage message) {
         assertRunOnServiceThread();
 
-        // Ignore <Standby> from non-active source device.
-        if (getActiveSource().logicalAddress != message.getSource()) {
+        // If a device has previously asserted the active source status, ignore <Standby> from
+        // non-active source.
+        if (getWasActiveSourceSetToConnectedDevice()
+                && getActiveSource().logicalAddress != message.getSource()) {
             Slog.d(TAG, "<Standby> was not sent by the current active source, ignoring."
                     + " Current active source has logical address "
                     + getActiveSource().logicalAddress);
             return Constants.HANDLED;
         }
+        setWasActiveSourceSetToConnectedDevice(false);
         return super.handleStandby(message);
     }
 
@@ -581,6 +597,12 @@
     @Constants.HandleMessageResult
     protected int handleReportPhysicalAddress(HdmiCecMessage message) {
         super.handleReportPhysicalAddress(message);
+        // Ignore <Report Physical Address> while DeviceDiscoveryAction is in progress to avoid
+        // starting a NewDeviceAction which might interfere in creating the list of known devices.
+        if (hasAction(DeviceDiscoveryAction.class)) {
+            return Constants.HANDLED;
+        }
+
         int path = HdmiUtils.twoBytesToInt(message.getParams());
         int address = message.getSource();
         int type = message.getParams()[2];
@@ -1457,6 +1479,7 @@
             invokeStandbyCompletedCallback(callback);
             return;
         }
+        setWasActiveSourceSetToConnectedDevice(false);
         boolean sendStandbyOnSleep =
                 mService.getHdmiCecConfig().getIntValue(
                     HdmiControlManager.CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP)
diff --git a/services/core/java/com/android/server/health/HealthServiceWrapper.java b/services/core/java/com/android/server/health/HealthServiceWrapper.java
index 25d1a88..9c14b5b 100644
--- a/services/core/java/com/android/server/health/HealthServiceWrapper.java
+++ b/services/core/java/com/android/server/health/HealthServiceWrapper.java
@@ -71,6 +71,21 @@
     public abstract android.hardware.health.HealthInfo getHealthInfo() throws RemoteException;
 
     /**
+     * Calls into getBatteryHealthData() in the health HAL.
+     * This function does not have a corresponding HIDL implementation, so
+     * returns null by default, unless there is an AIDL class that overrides
+     * this one.
+     *
+     * @return battery health data. {@code null} if no health HAL service.
+     *     {@code null} if any service-specific error when calling {@code
+     *     getBatteryHealthData}, e.g. it is unsupported.
+     * @throws RemoteException for any transaction-level errors
+     */
+    public android.hardware.health.BatteryHealthData getBatteryHealthData() throws RemoteException {
+        return null;
+    }
+
+    /**
      * Create a new HealthServiceWrapper instance.
      *
      * @param healthInfoCallback the callback to call when health info changes
diff --git a/services/core/java/com/android/server/health/HealthServiceWrapperAidl.java b/services/core/java/com/android/server/health/HealthServiceWrapperAidl.java
index fd3a92e..2a3fbc3 100644
--- a/services/core/java/com/android/server/health/HealthServiceWrapperAidl.java
+++ b/services/core/java/com/android/server/health/HealthServiceWrapperAidl.java
@@ -212,6 +212,17 @@
         }
     }
 
+    @Override
+    public BatteryHealthData getBatteryHealthData() throws RemoteException {
+        IHealth service = mLastService.get();
+        if (service == null) return null;
+        try {
+            return service.getBatteryHealthData();
+        } catch (UnsupportedOperationException | ServiceSpecificException ex) {
+            return null;
+        }
+    }
+
     public void setChargingPolicy(int policy) throws RemoteException {
         IHealth service = mLastService.get();
         if (service == null) return;
diff --git a/services/core/java/com/android/server/input/BatteryController.java b/services/core/java/com/android/server/input/BatteryController.java
index 38a0d37..62c21bd 100644
--- a/services/core/java/com/android/server/input/BatteryController.java
+++ b/services/core/java/com/android/server/input/BatteryController.java
@@ -83,6 +83,7 @@
     private final Handler mHandler;
     private final UEventManager mUEventManager;
     private final BluetoothBatteryManager mBluetoothBatteryManager;
+    private final Runnable mHandlePollEventCallback = this::handlePollEvent;
 
     // Maps a pid to the registered listener record for that process. There can only be one battery
     // listener per process.
@@ -206,7 +207,7 @@
         if (!mIsInteractive || !anyOf(mDeviceMonitors, DeviceMonitor::requiresPolling)) {
             // Stop polling.
             mIsPolling = false;
-            mHandler.removeCallbacks(this::handlePollEvent);
+            mHandler.removeCallbacks(mHandlePollEventCallback);
             return;
         }
 
@@ -215,7 +216,7 @@
         }
         // Start polling.
         mIsPolling = true;
-        mHandler.postDelayed(this::handlePollEvent, delayStart ? POLLING_PERIOD_MILLIS : 0);
+        mHandler.postDelayed(mHandlePollEventCallback, delayStart ? POLLING_PERIOD_MILLIS : 0);
     }
 
     private <R> R processInputDevice(int deviceId, R defaultValue, Function<InputDevice, R> func) {
@@ -366,7 +367,7 @@
             }
             final long eventTime = SystemClock.uptimeMillis();
             mDeviceMonitors.forEach((deviceId, monitor) -> monitor.onPoll(eventTime));
-            mHandler.postDelayed(this::handlePollEvent, POLLING_PERIOD_MILLIS);
+            mHandler.postDelayed(mHandlePollEventCallback, POLLING_PERIOD_MILLIS);
         }
     }
 
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index e5dbce9..1f46af8 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -53,6 +53,7 @@
 import android.hardware.input.InputManager;
 import android.hardware.input.InputSensorInfo;
 import android.hardware.input.InputSettings;
+import android.hardware.input.KeyGlyphMap;
 import android.hardware.input.KeyboardLayout;
 import android.hardware.input.KeyboardLayoutSelectionResult;
 import android.hardware.input.TouchCalibration;
@@ -311,6 +312,9 @@
     // Manages Keyboard modifier keys remapping
     private final KeyRemapper mKeyRemapper;
 
+    // Manages Keyboard glyphs for specific keyboards
+    private final KeyboardGlyphManager mKeyboardGlyphManager;
+
     // Manages loading PointerIcons
     private final PointerIconCache mPointerIconCache;
 
@@ -460,6 +464,7 @@
         mKeyboardLedController = new KeyboardLedController(mContext, injector.getLooper(),
                 mNative);
         mKeyRemapper = new KeyRemapper(mContext, mNative, mDataStore, injector.getLooper());
+        mKeyboardGlyphManager = new KeyboardGlyphManager(mContext, injector.getLooper());
         mPointerIconCache = new PointerIconCache(mContext, mNative);
 
         mUseDevInputEventForAudioJack =
@@ -576,6 +581,7 @@
         mKeyboardLedController.systemRunning();
         mKeyRemapper.systemRunning();
         mPointerIconCache.systemRunning();
+        mKeyboardGlyphManager.systemRunning();
     }
 
     private void reloadDeviceAliases() {
@@ -1208,6 +1214,11 @@
                 imeInfo, imeSubtype);
     }
 
+    @Override // Binder call
+    public KeyGlyphMap getKeyGlyphMap(int deviceId) {
+        return mKeyboardGlyphManager.getKeyGlyphMap(deviceId);
+    }
+
     public void setFocusedApplication(int displayId, InputApplicationHandle application) {
         mNative.setFocusedApplication(displayId, application);
     }
@@ -2077,6 +2088,7 @@
         mBatteryController.dump(ipw);
         mKeyboardBacklightController.dump(ipw);
         mKeyboardLedController.dump(ipw);
+        mKeyboardGlyphManager.dump(ipw);
     }
 
     private void dumpAssociations(IndentingPrintWriter pw) {
@@ -3352,6 +3364,10 @@
         mPointerIconCache.setPointerFillStyle(fillStyle);
     }
 
+    void setPointerStrokeStyle(@PointerIcon.PointerIconVectorStyleStroke int strokeStyle) {
+        mPointerIconCache.setPointerStrokeStyle(strokeStyle);
+    }
+
     void setPointerScale(float scale) {
         mPointerIconCache.setPointerScale(scale);
     }
diff --git a/services/core/java/com/android/server/input/InputSettingsObserver.java b/services/core/java/com/android/server/input/InputSettingsObserver.java
index 593b091..000f312 100644
--- a/services/core/java/com/android/server/input/InputSettingsObserver.java
+++ b/services/core/java/com/android/server/input/InputSettingsObserver.java
@@ -18,6 +18,7 @@
 
 import static android.view.PointerIcon.DEFAULT_POINTER_SCALE;
 import static android.view.PointerIcon.POINTER_ICON_VECTOR_STYLE_FILL_BLACK;
+import static android.view.PointerIcon.POINTER_ICON_VECTOR_STYLE_STROKE_WHITE;
 import static android.view.flags.Flags.enableVectorCursorA11ySettings;
 
 import static com.android.input.flags.Flags.rateLimitUserActivityPokeInDispatcher;
@@ -103,6 +104,8 @@
                         (reason) -> updateStylusPointerIconEnabled()),
                 Map.entry(Settings.System.getUriFor(Settings.System.POINTER_FILL_STYLE),
                         (reason) -> updatePointerFillStyleFromSettings()),
+                Map.entry(Settings.System.getUriFor(Settings.System.POINTER_STROKE_STYLE),
+                        (reason) -> updatePointerStrokeStyleFromSettings()),
                 Map.entry(Settings.System.getUriFor(Settings.System.POINTER_SCALE),
                         (reason) -> updatePointerScaleFromSettings()));
     }
@@ -281,6 +284,17 @@
         mService.setPointerFillStyle(pointerFillStyle);
     }
 
+    private void updatePointerStrokeStyleFromSettings() {
+        if (!enableVectorCursorA11ySettings()) {
+            return;
+        }
+        final int pointerStrokeStyle = Settings.System.getIntForUser(
+                mContext.getContentResolver(), Settings.System.POINTER_STROKE_STYLE,
+                POINTER_ICON_VECTOR_STYLE_STROKE_WHITE,
+                UserHandle.USER_CURRENT);
+        mService.setPointerStrokeStyle(pointerStrokeStyle);
+    }
+
     private void updatePointerScaleFromSettings() {
         if (!enableVectorCursorA11ySettings()) {
             return;
diff --git a/services/core/java/com/android/server/input/KeyboardGlyphManager.java b/services/core/java/com/android/server/input/KeyboardGlyphManager.java
new file mode 100644
index 0000000..f59d72b
--- /dev/null
+++ b/services/core/java/com/android/server/input/KeyboardGlyphManager.java
@@ -0,0 +1,382 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.input;
+
+import static com.android.hardware.input.Flags.keyboardGlyphMap;
+
+import android.annotation.AnyRes;
+import android.annotation.MainThread;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.hardware.input.InputManager;
+import android.hardware.input.KeyGlyphMap;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.util.IndentingPrintWriter;
+import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
+import android.view.InputDevice;
+
+import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Provides information on custom glyphs configured for specific keyboard devices.
+ *
+ * @hide
+ */
+public final class KeyboardGlyphManager implements InputManager.InputDeviceListener {
+
+    private static final String TAG = "KeyboardGlyphManager";
+    // To enable these logs, run: 'adb shell setprop log.tag.KeyboardGlyphManager DEBUG'
+    // (requires restart)
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private static final String TAG_KEYBOARD_GLYPH_MAPS = "keyboard-glyph-maps";
+    private static final String TAG_KEYBOARD_GLYPH_MAP = "keyboard-glyph-map";
+    private static final String TAG_KEY_GLYPH = "key-glyph";
+    private static final String TAG_MODIFIER_GLYPH = "modifier-glyph";
+    private static final String TAG_FUNCTION_ROW_KEY = "function-row-key";
+    private static final String TAG_HARDWARE_DEFINED_SHORTCUT = "hardware-defined-shortcut";
+
+    private final Context mContext;
+    private final Handler mHandler;
+    private final Object mGlyphMapLock = new Object();
+    @GuardedBy("mGlyphMapLock")
+    private boolean mGlyphMapDataLoaded = false;
+    @GuardedBy("mGlyphMapLock")
+    private List<KeyGlyphMapData> mGlyphMapDataList = new ArrayList<>();
+    // Cache for already loaded glyph maps
+    @GuardedBy("mGlyphMapLock")
+    private final SparseArray<KeyGlyphMap> mGlyphMapCache = new SparseArray<>();
+
+    KeyboardGlyphManager(Context context, Looper looper) {
+        mContext = context;
+        mHandler = new Handler(looper);
+    }
+
+    void systemRunning() {
+        if (!keyboardGlyphMap()) {
+            return;
+        }
+        // Listen to new Package installations to fetch new Keyboard glyph maps
+        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
+        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
+        filter.addDataScheme("package");
+        mContext.registerReceiver(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                resetMaps();
+            }
+        }, filter, null, mHandler);
+    }
+
+    @Override
+    @MainThread
+    public void onInputDeviceAdded(int deviceId) {
+    }
+
+    @Override
+    @MainThread
+    public void onInputDeviceRemoved(int deviceId) {
+        synchronized (mGlyphMapLock) {
+            mGlyphMapCache.remove(deviceId);
+        }
+    }
+
+    @Override
+    @MainThread
+    public void onInputDeviceChanged(int deviceId) {
+    }
+
+    @MainThread
+    private void resetMaps() {
+        synchronized (mGlyphMapLock) {
+            mGlyphMapDataLoaded = false;
+            mGlyphMapDataList.clear();
+            mGlyphMapCache.clear();
+        }
+    }
+
+    @NonNull
+    private List<KeyGlyphMapData> loadGlyphMapDataList() {
+        final PackageManager pm = mContext.getPackageManager();
+        List<KeyGlyphMapData> glyphMaps = new ArrayList<>();
+        Intent intent = new Intent(InputManager.ACTION_QUERY_KEYBOARD_GLYPH_MAPS);
+        for (ResolveInfo resolveInfo : pm.queryBroadcastReceiversAsUser(intent,
+                PackageManager.GET_META_DATA | PackageManager.MATCH_DIRECT_BOOT_AWARE
+                        | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, UserHandle.USER_SYSTEM)) {
+            if (resolveInfo == null || resolveInfo.activityInfo == null) {
+                continue;
+            }
+            final ActivityInfo activityInfo = resolveInfo.activityInfo;
+            KeyGlyphMapData data = getKeyboardGlyphMapsInPackage(pm, activityInfo);
+            if (data == null) {
+                continue;
+            }
+            glyphMaps.add(data);
+        }
+        return glyphMaps;
+    }
+
+    @Nullable
+    private KeyGlyphMapData getKeyboardGlyphMapsInPackage(PackageManager pm,
+            @NonNull ActivityInfo receiver) {
+        Bundle metaData = receiver.metaData;
+        if (metaData == null) {
+            return null;
+        }
+
+        int configResId = metaData.getInt(InputManager.META_DATA_KEYBOARD_GLYPH_MAPS);
+        if (configResId == 0) {
+            Slog.w(TAG, "Missing meta-data '" + InputManager.META_DATA_KEYBOARD_GLYPH_MAPS
+                    + "' on receiver " + receiver.packageName + "/" + receiver.name);
+            return null;
+        }
+
+        try {
+            Resources resources = pm.getResourcesForApplication(receiver.applicationInfo);
+            try (XmlResourceParser parser = resources.getXml(configResId)) {
+                XmlUtils.beginDocument(parser, TAG_KEYBOARD_GLYPH_MAPS);
+
+                while (true) {
+                    XmlUtils.nextElement(parser);
+                    String element = parser.getName();
+                    if (element == null) {
+                        break;
+                    }
+                    if (!TAG_KEYBOARD_GLYPH_MAP.equals(element)) {
+                        continue;
+                    }
+                    TypedArray a = resources.obtainAttributes(parser, R.styleable.KeyboardGlyphMap);
+                    try {
+                        int glyphMapRes = a.getResourceId(R.styleable.KeyboardGlyphMap_glyphMap, 0);
+                        int vendor = a.getInt(R.styleable.KeyboardGlyphMap_vendorId, -1);
+                        int product = a.getInt(R.styleable.KeyboardGlyphMap_productId, -1);
+                        if (glyphMapRes != 0 && vendor != -1 && product != -1) {
+                            return new KeyGlyphMapData(receiver.packageName, receiver.name,
+                                    glyphMapRes, vendor, product);
+                        }
+                    } finally {
+                        a.recycle();
+                    }
+                }
+            }
+        } catch (Exception ex) {
+            Slog.w(TAG, "Could not parse keyboard glyph map resource from receiver "
+                    + receiver.packageName + "/" + receiver.name, ex);
+        }
+        return null;
+    }
+
+    @Nullable
+    private KeyGlyphMap loadGlyphMap(KeyGlyphMapData data) {
+        final PackageManager pm = mContext.getPackageManager();
+        try {
+            ComponentName componentName = new ComponentName(data.packageName, data.receiverName);
+            ActivityInfo receiver = pm.getReceiverInfo(componentName,
+                    PackageManager.GET_META_DATA
+                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
+                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
+            Resources resources = pm.getResourcesForApplication(receiver.applicationInfo);
+            return loadGlyphMapFromResource(resources, componentName, data.resourceId);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, "Package not found: " + e);
+        }
+        return null;
+    }
+
+    @NonNull
+    private KeyGlyphMap loadGlyphMapFromResource(Resources resources,
+            @NonNull ComponentName componentName, @AnyRes int glyphMapId) {
+        SparseIntArray keyGlyphs = new SparseIntArray();
+        SparseIntArray modifierGlyphs = new SparseIntArray();
+        List<Integer> functionRowKeys = new ArrayList<>();
+        HashMap<KeyGlyphMap.KeyCombination, Integer> hardwareShortcuts = new HashMap<>();
+        try {
+            XmlResourceParser parser = resources.getXml(glyphMapId);
+            XmlUtils.beginDocument(parser, TAG_KEYBOARD_GLYPH_MAP);
+
+            while (true) {
+                XmlUtils.nextElement(parser);
+                String element = parser.getName();
+                if (element == null) {
+                    break;
+                }
+                switch (element) {
+                    case TAG_KEY_GLYPH -> {
+                        final TypedArray a = resources.obtainAttributes(parser,
+                                R.styleable.KeyGlyph);
+                        try {
+                            int keycode = a.getInt(R.styleable.KeyGlyph_keycode, 0);
+                            int keyGlyph = a.getResourceId(R.styleable.KeyGlyph_glyphDrawable, 0);
+                            if (keycode != 0 && keyGlyph != 0) {
+                                keyGlyphs.put(keycode, keyGlyph);
+                            }
+                        } finally {
+                            a.recycle();
+                        }
+                    }
+                    case TAG_MODIFIER_GLYPH -> {
+                        final TypedArray a = resources.obtainAttributes(parser,
+                                R.styleable.ModifierGlyph);
+                        try {
+                            int modifier = a.getInt(R.styleable.ModifierGlyph_modifier, 0);
+                            int modifierGlyph = a.getResourceId(
+                                    R.styleable.ModifierGlyph_glyphDrawable,
+                                    0);
+                            if (modifier != 0 && modifierGlyph != 0) {
+                                modifierGlyphs.put(modifier, modifierGlyph);
+                            }
+                        } finally {
+                            a.recycle();
+                        }
+                    }
+                    case TAG_FUNCTION_ROW_KEY -> {
+                        final TypedArray a = resources.obtainAttributes(parser,
+                                R.styleable.FunctionRowKey);
+                        try {
+                            int keycode = a.getInt(R.styleable.FunctionRowKey_keycode, 0);
+                            if (keycode != 0) {
+                                functionRowKeys.add(keycode);
+                            }
+                        } finally {
+                            a.recycle();
+                        }
+                    }
+                    case TAG_HARDWARE_DEFINED_SHORTCUT -> {
+                        final TypedArray a = resources.obtainAttributes(parser,
+                                R.styleable.HardwareDefinedShortcut);
+                        try {
+                            int keycode = a.getInt(R.styleable.HardwareDefinedShortcut_keycode,
+                                    0);
+                            int modifierState = a.getInt(
+                                    R.styleable.HardwareDefinedShortcut_modifierState, 0);
+                            int outKeycode = a.getInt(
+                                    R.styleable.HardwareDefinedShortcut_outKeycode,
+                                    0);
+                            if (keycode != 0 && modifierState != 0 && outKeycode != 0) {
+                                hardwareShortcuts.put(
+                                        new KeyGlyphMap.KeyCombination(modifierState, keycode),
+                                        outKeycode);
+                            }
+                        } finally {
+                            a.recycle();
+                        }
+                    }
+                }
+            }
+        } catch (XmlPullParserException | IOException e) {
+            Log.e(TAG, "Unable to parse key glyph map : " + e);
+        }
+        return new KeyGlyphMap(componentName, keyGlyphs, modifierGlyphs,
+                functionRowKeys.stream().mapToInt(Integer::intValue).toArray(), hardwareShortcuts);
+    }
+
+    /**
+     * Returns keyboard glyph map corresponding to device ID
+     */
+    @Nullable
+    public KeyGlyphMap getKeyGlyphMap(int deviceId) {
+        if (!keyboardGlyphMap()) {
+            return null;
+        }
+        synchronized (mGlyphMapLock) {
+            if (mGlyphMapCache.indexOfKey(deviceId) >= 0) {
+                return mGlyphMapCache.get(deviceId);
+            }
+            KeyGlyphMap keyGlyphMap = getKeyGlyphMapInternal(deviceId);
+            mGlyphMapCache.put(deviceId, keyGlyphMap);
+            return keyGlyphMap;
+        }
+    }
+
+    @GuardedBy("mGlyphMapLock")
+    private KeyGlyphMap getKeyGlyphMapInternal(int deviceId) {
+        final InputDevice inputDevice = getInputDevice(deviceId);
+        if (inputDevice == null || inputDevice.isVirtual() || !inputDevice.isFullKeyboard()) {
+            return null;
+        }
+        if (!mGlyphMapDataLoaded) {
+            mGlyphMapDataList = loadGlyphMapDataList();
+            mGlyphMapDataLoaded = true;
+        }
+        for (KeyGlyphMapData data : mGlyphMapDataList) {
+            if (data.vendorId == inputDevice.getVendorId()
+                    && data.productId == inputDevice.getProductId()) {
+                return loadGlyphMap(data);
+            }
+        }
+        return null;
+    }
+
+    void dump(IndentingPrintWriter ipw) {
+        if (!keyboardGlyphMap()) {
+            return;
+        }
+        List<KeyGlyphMapData> glyphMapDataList = loadGlyphMapDataList();
+        ipw.println(TAG + ": " + glyphMapDataList.size() + " glyph maps");
+        ipw.increaseIndent();
+        for (KeyGlyphMapData data : glyphMapDataList) {
+            ipw.println(data);
+            if (DEBUG) {
+                KeyGlyphMap map = loadGlyphMap(data);
+                if (map != null) {
+                    ipw.increaseIndent();
+                    ipw.println(map);
+                    ipw.decreaseIndent();
+                }
+            }
+        }
+        ipw.decreaseIndent();
+    }
+
+    @Nullable
+    private InputDevice getInputDevice(int deviceId) {
+        InputManager inputManager = mContext.getSystemService(InputManager.class);
+        return inputManager != null ? inputManager.getInputDevice(deviceId) : null;
+    }
+
+    private record KeyGlyphMapData(@NonNull String packageName, @NonNull String receiverName,
+                                   @AnyRes int resourceId, int vendorId, int productId) {
+    }
+}
diff --git a/services/core/java/com/android/server/input/KeyboardLayoutManager.java b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
index 97c32b9..4993412 100644
--- a/services/core/java/com/android/server/input/KeyboardLayoutManager.java
+++ b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
@@ -255,17 +255,6 @@
         }
     }
 
-    private static boolean isCompatibleLocale(Locale systemLocale, Locale keyboardLocale) {
-        // Different languages are never compatible
-        if (!systemLocale.getLanguage().equals(keyboardLocale.getLanguage())) {
-            return false;
-        }
-        // If both the system and the keyboard layout have a country specifier, they must be equal.
-        return TextUtils.isEmpty(systemLocale.getCountry())
-                || TextUtils.isEmpty(keyboardLocale.getCountry())
-                || systemLocale.getCountry().equals(keyboardLocale.getCountry());
-    }
-
     @MainThread
     private void updateKeyboardLayouts() {
         // Scan all input devices state for keyboard layouts that have been uninstalled.
@@ -953,21 +942,33 @@
             return;
         }
 
+        List<String> layoutNames = new ArrayList<>();
+        for (String layoutDesc : config.getConfiguredLayouts()) {
+            KeyboardLayout kl = getKeyboardLayout(layoutDesc);
+            if (kl == null) {
+                // b/349033234: Weird state with stale keyboard layout configured.
+                // Possibly due to race condition between KCM providing package being removed and
+                // corresponding layouts being removed from Datastore and cache.
+                // {@see updateKeyboardLayouts()}
+                //
+                // Ideally notification will be correctly shown after the keyboard layouts are
+                // configured again with the new package state.
+                return;
+            }
+            layoutNames.add(kl.getLabel());
+        }
         showKeyboardLayoutNotification(
                 r.getString(
                         R.string.keyboard_layout_notification_selected_title,
                         inputDevice.getName()),
-                createConfiguredNotificationText(mContext, config.getConfiguredLayouts()),
+                createConfiguredNotificationText(mContext, layoutNames),
                 inputDevice);
     }
 
     @MainThread
     private String createConfiguredNotificationText(@NonNull Context context,
-            @NonNull Set<String> selectedLayouts) {
+            @NonNull List<String> layoutNames) {
         final Resources r = context.getResources();
-        List<String> layoutNames = new ArrayList<>();
-        selectedLayouts.forEach(
-                (layoutDesc) -> layoutNames.add(getKeyboardLayout(layoutDesc).getLabel()));
         Collections.sort(layoutNames);
         switch (layoutNames.size()) {
             case 1:
diff --git a/services/core/java/com/android/server/input/PointerIconCache.java b/services/core/java/com/android/server/input/PointerIconCache.java
index 44622d8..297cd68 100644
--- a/services/core/java/com/android/server/input/PointerIconCache.java
+++ b/services/core/java/com/android/server/input/PointerIconCache.java
@@ -18,6 +18,7 @@
 
 import static android.view.PointerIcon.DEFAULT_POINTER_SCALE;
 import static android.view.PointerIcon.POINTER_ICON_VECTOR_STYLE_FILL_BLACK;
+import static android.view.PointerIcon.POINTER_ICON_VECTOR_STYLE_STROKE_WHITE;
 
 import android.annotation.NonNull;
 import android.content.Context;
@@ -65,6 +66,9 @@
     private @PointerIcon.PointerIconVectorStyleFill int mPointerIconFillStyle =
             POINTER_ICON_VECTOR_STYLE_FILL_BLACK;
     @GuardedBy("mLoadedPointerIconsByDisplayAndType")
+    private @PointerIcon.PointerIconVectorStyleStroke int mPointerIconStrokeStyle =
+            POINTER_ICON_VECTOR_STYLE_STROKE_WHITE;
+    @GuardedBy("mLoadedPointerIconsByDisplayAndType")
     private float mPointerIconScale = DEFAULT_POINTER_SCALE;
 
     private final DisplayManager.DisplayListener mDisplayListener =
@@ -120,6 +124,11 @@
         mUiThreadHandler.post(() -> handleSetPointerFillStyle(fillStyle));
     }
 
+    /** Set the stroke style for vector pointer icons. */
+    public void setPointerStrokeStyle(@PointerIcon.PointerIconVectorStyleStroke int strokeStyle) {
+        mUiThreadHandler.post(() -> handleSetPointerStrokeStyle(strokeStyle));
+    }
+
     /** Set the scale for vector pointer icons. */
     public void setPointerScale(float scale) {
         mUiThreadHandler.post(() -> handleSetPointerScale(scale));
@@ -144,6 +153,8 @@
                 theme.setTo(context.getTheme());
                 theme.applyStyle(PointerIcon.vectorFillStyleToResource(mPointerIconFillStyle),
                         /* force= */ true);
+                theme.applyStyle(PointerIcon.vectorStrokeStyleToResource(mPointerIconStrokeStyle),
+                        /* force= */ true);
                 icon = PointerIcon.getLoadedSystemIcon(new ContextThemeWrapper(context, theme),
                         type, mUseLargePointerIcons, mPointerIconScale);
                 iconsByType.put(type, icon);
@@ -224,6 +235,20 @@
     }
 
     @android.annotation.UiThread
+    private void handleSetPointerStrokeStyle(
+            @PointerIcon.PointerIconVectorStyleStroke int strokeStyle) {
+        synchronized (mLoadedPointerIconsByDisplayAndType) {
+            if (mPointerIconStrokeStyle == strokeStyle) {
+                return;
+            }
+            mPointerIconStrokeStyle = strokeStyle;
+            // Clear all cached icons on all displays.
+            mLoadedPointerIconsByDisplayAndType.clear();
+        }
+        mNative.reloadPointerIcons();
+    }
+
+    @android.annotation.UiThread
     private void handleSetPointerScale(float scale) {
         synchronized (mLoadedPointerIconsByDisplayAndType) {
             if (mPointerIconScale == scale) {
diff --git a/services/core/java/com/android/server/inputmethod/AutofillSuggestionsController.java b/services/core/java/com/android/server/inputmethod/AutofillSuggestionsController.java
index 0749edc..aeace7a 100644
--- a/services/core/java/com/android/server/inputmethod/AutofillSuggestionsController.java
+++ b/services/core/java/com/android/server/inputmethod/AutofillSuggestionsController.java
@@ -103,8 +103,8 @@
 
         // Note that current user ID is guaranteed to be userId.
         final var imeId = mBindingController.getSelectedMethodId();
-        final InputMethodInfo imi = InputMethodSettingsRepository.get(mBindingController.mUserId)
-                .getMethodMap().get(imeId);
+        final InputMethodInfo imi = InputMethodSettingsRepository.get(
+                mBindingController.getUserId()).getMethodMap().get(imeId);
         if (imi == null || !isInlineSuggestionsEnabled(imi, touchExplorationEnabled)) {
             callback.onInlineSuggestionsUnsupported();
             return;
diff --git a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
index 7d48527..5ff421a 100644
--- a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
+++ b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
@@ -53,10 +53,10 @@
 import java.util.Objects;
 
 /**
- * The default implementation of {@link ImeVisibilityApplier} used in
- * {@link InputMethodManagerService}.
+ * A stateless helper class for IME visibility operations like show/hide and update Z-ordering
+ * relative to the IME targeted window.
  */
-final class DefaultImeVisibilityApplier implements ImeVisibilityApplier {
+final class DefaultImeVisibilityApplier {
 
     private static final String TAG = "DefaultImeVisibilityApplier";
 
@@ -69,19 +69,29 @@
     @NonNull
     private final ImeTargetVisibilityPolicy mImeTargetVisibilityPolicy;
 
-
     DefaultImeVisibilityApplier(InputMethodManagerService service) {
         mService = service;
         mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
         mImeTargetVisibilityPolicy = LocalServices.getService(ImeTargetVisibilityPolicy.class);
     }
 
+    /**
+     * Performs showing IME on top of the given window.
+     *
+     * @param showInputToken a token that represents the requester to show IME
+     * @param statsToken     the token tracking the current IME request
+     * @param resultReceiver if non-null, this will be called back to the caller when
+     *                       it has processed request to tell what it has done
+     * @param reason         yhe reason for requesting to show IME
+     * @param userId         the target user when performing show IME
+     */
     @GuardedBy("ImfLock.class")
-    @Override
-    public void performShowIme(IBinder showInputToken, @NonNull ImeTracker.Token statsToken,
+    void performShowIme(IBinder showInputToken, @NonNull ImeTracker.Token statsToken,
             @InputMethod.ShowFlags int showFlags, ResultReceiver resultReceiver,
-            @SoftInputShowHideReason int reason) {
-        final IInputMethodInvoker curMethod = mService.getCurMethodLocked();
+            @SoftInputShowHideReason int reason, @UserIdInt int userId) {
+        final var bindingController = mService.getInputMethodBindingController(userId);
+        final var userData = mService.getUserData(userId);
+        final IInputMethodInvoker curMethod = bindingController.getCurMethod();
         if (curMethod != null) {
             if (DEBUG) {
                 Slog.v(TAG, "Calling " + curMethod + ".showSoftInput(" + showInputToken
@@ -93,22 +103,34 @@
                 if (DEBUG_IME_VISIBILITY) {
                     EventLog.writeEvent(IMF_SHOW_IME,
                             statsToken != null ? statsToken.getTag() : ImeTracker.TOKEN_NONE,
-                            Objects.toString(mService.mImeBindingState.mFocusedWindow),
+                            Objects.toString(userData.mImeBindingState.mFocusedWindow),
                             InputMethodDebug.softInputDisplayReasonToString(reason),
                             InputMethodDebug.softInputModeToString(
-                                    mService.mImeBindingState.mFocusedWindowSoftInputMode));
+                                    userData.mImeBindingState.mFocusedWindowSoftInputMode));
                 }
                 mService.onShowHideSoftInputRequested(true /* show */, showInputToken, reason,
-                        statsToken);
+                        statsToken, userId);
             }
         }
     }
 
+    /**
+     * Performs hiding IME to the given window
+     *
+     * @param hideInputToken a token that represents the requester to hide IME
+     * @param statsToken     the token tracking the current IME request
+     * @param resultReceiver if non-null, this will be called back to the caller when
+     *                       it has processed request to tell what it has done
+     * @param reason         the reason for requesting to hide IME
+     * @param userId         the target user when performing hide IME
+     */
     @GuardedBy("ImfLock.class")
-    @Override
-    public void performHideIme(IBinder hideInputToken, @NonNull ImeTracker.Token statsToken,
-            ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {
-        final IInputMethodInvoker curMethod = mService.getCurMethodLocked();
+    void performHideIme(IBinder hideInputToken, @NonNull ImeTracker.Token statsToken,
+            ResultReceiver resultReceiver, @SoftInputShowHideReason int reason,
+            @UserIdInt int userId) {
+        final var bindingController = mService.getInputMethodBindingController(userId);
+        final IInputMethodInvoker curMethod = bindingController.getCurMethod();
+        final var userData = mService.getUserData(userId);
         if (curMethod != null) {
             // The IME will report its visible state again after the following message finally
             // delivered to the IME process as an IPC.  Hence the inconsistency between
@@ -124,30 +146,33 @@
                 if (DEBUG_IME_VISIBILITY) {
                     EventLog.writeEvent(IMF_HIDE_IME,
                             statsToken != null ? statsToken.getTag() : ImeTracker.TOKEN_NONE,
-                            Objects.toString(mService.mImeBindingState.mFocusedWindow),
+                            Objects.toString(userData.mImeBindingState.mFocusedWindow),
                             InputMethodDebug.softInputDisplayReasonToString(reason),
                             InputMethodDebug.softInputModeToString(
-                                    mService.mImeBindingState.mFocusedWindowSoftInputMode));
+                                    userData.mImeBindingState.mFocusedWindowSoftInputMode));
                 }
                 mService.onShowHideSoftInputRequested(false /* show */, hideInputToken, reason,
-                        statsToken);
+                        statsToken, userId);
             }
         }
     }
 
-    @GuardedBy("ImfLock.class")
-    @Override
-    public void applyImeVisibility(IBinder windowToken, @NonNull ImeTracker.Token statsToken,
-            @ImeVisibilityStateComputer.VisibilityState int state, @UserIdInt int userId) {
-        applyImeVisibility(windowToken, statsToken, state,
-                SoftInputShowHideReason.NOT_SET /* ignore reason */, userId);
-    }
-
+    /**
+     * Applies the IME visibility from {@link android.inputmethodservice.InputMethodService} with
+     * according to the given visibility state.
+     *
+     * @param windowToken the token of a window for applying the IME visibility
+     * @param statsToken  the token tracking the current IME request
+     * @param state       the new IME visibility state for the applier to handle
+     * @param reason      one of {@link SoftInputShowHideReason}
+     * @param userId      the target user when applying the IME visibility state
+     */
     @GuardedBy("ImfLock.class")
     void applyImeVisibility(IBinder windowToken, @Nullable ImeTracker.Token statsToken,
             @ImeVisibilityStateComputer.VisibilityState int state,
             @SoftInputShowHideReason int reason, @UserIdInt int userId) {
         final var bindingController = mService.getInputMethodBindingController(userId);
+        final var userData = mService.getUserData(userId);
         final int displayIdToShowIme = bindingController.getDisplayIdToShowIme();
         switch (state) {
             case STATE_SHOW_IME:
@@ -160,7 +185,7 @@
                 break;
             case STATE_HIDE_IME:
                 if (!Flags.refactorInsetsController()) {
-                    if (mService.hasAttachedClient()) {
+                    if (userData.mCurClient != null) {
                         ImeTracker.forLogging().onProgress(statsToken,
                                 ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
                         // IMMS only knows of focused window, not the actual IME target.
@@ -177,70 +202,88 @@
                 break;
             case STATE_HIDE_IME_EXPLICIT:
                 if (Flags.refactorInsetsController()) {
-                    setImeVisibilityOnFocusedWindowClient(false);
+                    setImeVisibilityOnFocusedWindowClient(false, userId);
                 } else {
                     mService.hideCurrentInputLocked(windowToken, statsToken,
-                        0 /* flags */, null /* resultReceiver */, reason);
+                            0 /* flags */, null /* resultReceiver */, reason, userId);
                 }
                 break;
             case STATE_HIDE_IME_NOT_ALWAYS:
                 if (Flags.refactorInsetsController()) {
-                    setImeVisibilityOnFocusedWindowClient(false);
+                    setImeVisibilityOnFocusedWindowClient(false, userId);
                 } else {
                     mService.hideCurrentInputLocked(windowToken, statsToken,
-                            InputMethodManager.HIDE_NOT_ALWAYS, null /* resultReceiver */, reason);
+                            InputMethodManager.HIDE_NOT_ALWAYS, null /* resultReceiver */, reason,
+                            userId);
                 }
                 break;
             case STATE_SHOW_IME_IMPLICIT:
                 if (Flags.refactorInsetsController()) {
                     // This can be triggered by IMMS#startInputOrWindowGainedFocus. We need to
                     // set the requestedVisibleTypes in InsetsController first, before applying it.
-                    setImeVisibilityOnFocusedWindowClient(true);
+                    setImeVisibilityOnFocusedWindowClient(true, userId);
                 } else {
                     mService.showCurrentInputLocked(windowToken, statsToken,
                             InputMethodManager.SHOW_IMPLICIT, MotionEvent.TOOL_TYPE_UNKNOWN,
-                        null /* resultReceiver */, reason);
+                            null /* resultReceiver */, reason, userId);
                 }
                 break;
             case STATE_SHOW_IME_SNAPSHOT:
-                showImeScreenshot(windowToken, displayIdToShowIme);
+                showImeScreenshot(windowToken, displayIdToShowIme, userId);
                 break;
             case STATE_REMOVE_IME_SNAPSHOT:
-                removeImeScreenshot(displayIdToShowIme);
+                removeImeScreenshot(displayIdToShowIme, userId);
                 break;
             default:
                 throw new IllegalArgumentException("Invalid IME visibility state: " + state);
         }
     }
 
+    /**
+     * Shows the IME screenshot and attach it to the given IME target window.
+     *
+     * @param imeTarget   the token of a window to show the IME screenshot
+     * @param displayId   the unique id to identify the display
+     * @param userId      the target user when when showing the IME screenshot
+     * @return {@code true} if success, {@code false} otherwise
+     */
     @GuardedBy("ImfLock.class")
-    @Override
-    public boolean showImeScreenshot(@NonNull IBinder imeTarget, int displayId) {
+    boolean showImeScreenshot(@NonNull IBinder imeTarget, int displayId,
+            @UserIdInt int userId) {
         if (mImeTargetVisibilityPolicy.showImeScreenshot(imeTarget, displayId)) {
             mService.onShowHideSoftInputRequested(false /* show */, imeTarget,
-                    SHOW_IME_SCREENSHOT_FROM_IMMS, null /* statsToken */);
+                    SHOW_IME_SCREENSHOT_FROM_IMMS, null /* statsToken */, userId);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Removes the IME screenshot on the given display.
+     *
+     * @param displayId the target display of showing IME screenshot
+     * @param userId    the target user of showing IME screenshot
+     * @return {@code true} if success, {@code false} otherwise
+     */
+    @GuardedBy("ImfLock.class")
+    boolean removeImeScreenshot(int displayId, @UserIdInt int userId) {
+        final var userData = mService.getUserData(userId);
+        if (mImeTargetVisibilityPolicy.removeImeScreenshot(displayId)) {
+            mService.onShowHideSoftInputRequested(false /* show */,
+                    userData.mImeBindingState.mFocusedWindow,
+                    REMOVE_IME_SCREENSHOT_FROM_IMMS, null /* statsToken */, userId);
             return true;
         }
         return false;
     }
 
     @GuardedBy("ImfLock.class")
-    @Override
-    public boolean removeImeScreenshot(int displayId) {
-        if (mImeTargetVisibilityPolicy.removeImeScreenshot(displayId)) {
-            mService.onShowHideSoftInputRequested(false /* show */,
-                    mService.mImeBindingState.mFocusedWindow,
-                    REMOVE_IME_SCREENSHOT_FROM_IMMS, null /* statsToken */);
-            return true;
-        }
-        return false;
-    }
-
-    private void setImeVisibilityOnFocusedWindowClient(boolean visibility) {
-        if (mService.mImeBindingState != null
-                && mService.mImeBindingState.mFocusedWindowClient != null
-                && mService.mImeBindingState.mFocusedWindowClient.mClient != null) {
-            mService.mImeBindingState.mFocusedWindowClient.mClient.setImeVisibility(visibility);
+    private void setImeVisibilityOnFocusedWindowClient(boolean visibility, @UserIdInt int userId) {
+        final var userData = mService.getUserData(userId);
+        if (userData.mImeBindingState != null
+                && userData.mImeBindingState.mFocusedWindowClient != null
+                && userData.mImeBindingState.mFocusedWindowClient.mClient != null) {
+            userData.mImeBindingState.mFocusedWindowClient.mClient.setImeVisibility(visibility);
         } else {
             // TODO(b/329229469): ImeTracker?
         }
diff --git a/services/core/java/com/android/server/inputmethod/HardwareKeyboardShortcutController.java b/services/core/java/com/android/server/inputmethod/HardwareKeyboardShortcutController.java
index 62adb25..41313fa 100644
--- a/services/core/java/com/android/server/inputmethod/HardwareKeyboardShortcutController.java
+++ b/services/core/java/com/android/server/inputmethod/HardwareKeyboardShortcutController.java
@@ -19,7 +19,6 @@
 import android.annotation.AnyThread;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.UserIdInt;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodSubtype;
 
@@ -34,24 +33,12 @@
     @GuardedBy("ImfLock.class")
     private final ArrayList<InputMethodSubtypeHandle> mSubtypeHandles = new ArrayList<>();
 
-    @UserIdInt
-    private final int mUserId;
-
-    @AnyThread
-    @UserIdInt
-    int getUserId() {
-        return mUserId;
-    }
-
-    HardwareKeyboardShortcutController(@NonNull InputMethodMap methodMap, @UserIdInt int userId) {
-        mUserId = userId;
-        reset(methodMap);
+    HardwareKeyboardShortcutController() {
     }
 
     @GuardedBy("ImfLock.class")
-    void reset(@NonNull InputMethodMap methodMap) {
+    void update(@NonNull InputMethodSettings settings) {
         mSubtypeHandles.clear();
-        final InputMethodSettings settings = InputMethodSettings.create(methodMap, mUserId);
         final List<InputMethodInfo> inputMethods = settings.getEnabledInputMethodList();
         for (int i = 0; i < inputMethods.size(); ++i) {
             final InputMethodInfo imi = inputMethods.get(i);
diff --git a/services/core/java/com/android/server/inputmethod/ImeTrackerService.java b/services/core/java/com/android/server/inputmethod/ImeTrackerService.java
index 56fa8c9..14551a1 100644
--- a/services/core/java/com/android/server/inputmethod/ImeTrackerService.java
+++ b/services/core/java/com/android/server/inputmethod/ImeTrackerService.java
@@ -23,7 +23,6 @@
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.util.Log;
 import android.view.inputmethod.ImeTracker;
 
@@ -70,8 +69,8 @@
 
     private final Object mLock = new Object();
 
-    ImeTrackerService(@NonNull Looper looper) {
-        mHandler = new Handler(looper, null /* callback */, true /* async */);
+    ImeTrackerService(@NonNull Handler handler) {
+        mHandler = handler;
     }
 
     @NonNull
diff --git a/services/core/java/com/android/server/inputmethod/ImeVisibilityApplier.java b/services/core/java/com/android/server/inputmethod/ImeVisibilityApplier.java
deleted file mode 100644
index a5f9b7a..0000000
--- a/services/core/java/com/android/server/inputmethod/ImeVisibilityApplier.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.inputmethod;
-
-import android.annotation.NonNull;
-import android.annotation.UserIdInt;
-import android.os.IBinder;
-import android.os.ResultReceiver;
-import android.view.inputmethod.ImeTracker;
-import android.view.inputmethod.InputMethod;
-
-import com.android.internal.inputmethod.SoftInputShowHideReason;
-
-/**
- * Interface for IME visibility operations like show/hide and update Z-ordering relative to the IME
- * targeted window.
- */
-interface ImeVisibilityApplier {
-    /**
-     * Performs showing IME on top of the given window.
-     *
-     * @param showInputToken A token that represents the requester to show IME.
-     * @param statsToken     The token tracking the current IME request.
-     * @param resultReceiver If non-null, this will be called back to the caller when
-     *                       it has processed request to tell what it has done.
-     * @param reason         The reason for requesting to show IME.
-     */
-    default void performShowIme(IBinder showInputToken, @NonNull ImeTracker.Token statsToken,
-            @InputMethod.ShowFlags int showFlags, ResultReceiver resultReceiver,
-            @SoftInputShowHideReason int reason) {}
-
-    /**
-     * Performs hiding IME to the given window
-     *
-     * @param hideInputToken A token that represents the requester to hide IME.
-     * @param statsToken     The token tracking the current IME request.
-     * @param resultReceiver If non-null, this will be called back to the caller when
-     *                       it has processed request to tell what it has done.
-     * @param reason         The reason for requesting to hide IME.
-     */
-    default void performHideIme(IBinder hideInputToken, @NonNull ImeTracker.Token statsToken,
-            ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {}
-
-    /**
-     * Applies the IME visibility from {@link android.inputmethodservice.InputMethodService} with
-     * according to the given visibility state.
-     *
-     * @param windowToken The token of a window for applying the IME visibility
-     * @param statsToken  The token tracking the current IME request.
-     * @param state       The new IME visibility state for the applier to handle
-     */
-    default void applyImeVisibility(IBinder windowToken, @NonNull ImeTracker.Token statsToken,
-            @ImeVisibilityStateComputer.VisibilityState int state, @UserIdInt int userId) {}
-
-    /**
-     * Updates the IME Z-ordering relative to the given window.
-     *
-     * This used to adjust the IME relative layer of the window during
-     * {@link InputMethodManagerService} is in switching IME clients.
-     *
-     * @param windowToken The token of a window to update the Z-ordering relative to the IME.
-     */
-    default void updateImeLayeringByTarget(IBinder windowToken) {
-        // TODO: add a method in WindowManagerInternal to call DC#updateImeInputAndControlTarget
-        //  here to end up updating IME layering after IMMS#attachNewInputLocked called.
-    }
-
-    /**
-     * Shows the IME screenshot and attach it to the given IME target window.
-     *
-     * @param windowToken The token of a window to show the IME screenshot.
-     * @param displayId The unique id to identify the display
-     * @return {@code true} if success, {@code false} otherwise.
-     */
-    default boolean showImeScreenshot(@NonNull IBinder windowToken, int displayId) {
-        return false;
-    }
-
-    /**
-     * Removes the IME screenshot on the given display.
-     *
-     * @param displayId The target display of showing IME screenshot.
-     * @return {@code true} if success, {@code false} otherwise.
-     */
-    default boolean removeImeScreenshot(int displayId) {
-        return false;
-    }
-}
diff --git a/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java b/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
index 9d80844..7ebf595 100644
--- a/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
+++ b/services/core/java/com/android/server/inputmethod/ImeVisibilityStateComputer.java
@@ -38,6 +38,7 @@
 import android.accessibilityservice.AccessibilityService;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.UserIdInt;
 import android.content.res.Configuration;
 import android.os.Binder;
 import android.os.IBinder;
@@ -52,6 +53,7 @@
 import android.view.inputmethod.InputMethod;
 import android.view.inputmethod.InputMethodManager;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.inputmethod.SoftInputShowHideReason;
 import com.android.server.LocalServices;
@@ -553,15 +555,17 @@
         return null;
     }
 
-    IBinder getWindowTokenFrom(IBinder requestImeToken) {
+    @GuardedBy("ImfLock.class")
+    IBinder getWindowTokenFrom(IBinder requestImeToken, @UserIdInt int userId) {
         for (IBinder windowToken : mRequestWindowStateMap.keySet()) {
             final ImeTargetWindowState state = mRequestWindowStateMap.get(windowToken);
             if (state.getRequestImeToken() == requestImeToken) {
                 return windowToken;
             }
         }
+        final var userData = mService.getUserData(userId);
         // Fallback to the focused window for some edge cases (e.g. relaunching the activity)
-        return mService.mImeBindingState.mFocusedWindow;
+        return userData.mImeBindingState.mFocusedWindow;
     }
 
     IBinder getWindowTokenFrom(ImeTargetWindowState windowState) {
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
index 60d647d..5ab493b 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodBindingController.java
@@ -70,7 +70,7 @@
     /** Time in milliseconds that the IME service has to bind before it is reconnected. */
     static final long TIME_TO_RECONNECT = 3 * 1000;
 
-    @UserIdInt final int mUserId;
+    @UserIdInt private final int mUserId;
     @NonNull private final InputMethodManagerService mService;
     @NonNull private final Context mContext;
     @NonNull private final AutofillSuggestionsController mAutofillController;
@@ -96,6 +96,32 @@
     @GuardedBy("ImfLock.class") private int mDisplayIdToShowIme = INVALID_DISPLAY;
     @GuardedBy("ImfLock.class") private int mDeviceIdToShowIme = DEVICE_ID_DEFAULT;
 
+    /**
+     * A set of status bits regarding the active IME.
+     *
+     * <p>This value is a combination of following two bits:</p>
+     * <dl>
+     * <dt>{@link InputMethodService#IME_ACTIVE}</dt>
+     * <dd>
+     *   If this bit is ON, connected IME is ready to accept touch/key events.
+     * </dd>
+     * <dt>{@link InputMethodService#IME_VISIBLE}</dt>
+     * <dd>
+     *   If this bit is ON, some of IME view, e.g. software input, candidate view, is visible.
+     * </dd>
+     * <dt>{@link InputMethodService#IME_INVISIBLE}</dt>
+     * <dd> If this bit is ON, IME is ready with views from last EditorInfo but is
+     *    currently invisible.
+     * </dd>
+     * </dl>
+     * <em>Do not update this value outside of {@link #setImeWindowStatus(IBinder, int, int)} and
+     * {@link InputMethodBindingController#unbindCurrentMethod()}.</em>
+     */
+    @GuardedBy("ImfLock.class") private int mImeWindowVis;
+
+    @GuardedBy("ImfLock.class")
+    private int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT;
+
     @Nullable private CountDownLatch mLatchForTesting;
 
     /**
@@ -382,9 +408,9 @@
                         InputMethodManager
                                 .invalidateLocalConnectionlessStylusHandwritingAvailabilityCaches();
                     }
-                    mService.initializeImeLocked(mCurMethod, mCurToken);
+                    mService.initializeImeLocked(mCurMethod, mCurToken, mUserId);
                     mService.scheduleNotifyImeUidToAudioService(mCurMethodUid);
-                    mService.reRequestCurrentClientSessionLocked();
+                    mService.reRequestCurrentClientSessionLocked(mUserId);
                     mAutofillController.performOnCreateInlineSuggestionsRequest();
                 }
 
@@ -437,7 +463,7 @@
                     mLastBindTime = SystemClock.uptimeMillis();
                     clearCurMethodAndSessions();
                     mService.clearInputShownLocked();
-                    mService.unbindCurrentClientLocked(UnbindReason.DISCONNECT_IME);
+                    mService.unbindCurrentClientLocked(UnbindReason.DISCONNECT_IME, mUserId);
                 }
             }
         }
@@ -473,7 +499,7 @@
 
         if (getCurToken() != null) {
             removeCurrentToken();
-            mService.resetSystemUiLocked();
+            mService.resetSystemUiLocked(this);
             mAutofillController.onResetSystemUi();
         }
 
@@ -483,7 +509,7 @@
 
     @GuardedBy("ImfLock.class")
     private void clearCurMethodAndSessions() {
-        mService.clearClientSessionsLocked();
+        mService.clearClientSessionsLocked(this);
         mCurMethod = null;
         mCurMethodUid = Process.INVALID_UID;
     }
@@ -638,6 +664,36 @@
         }
     }
 
+    /**
+     * Returns the current {@link InputMethodSubtype}.
+     *
+     * <p>Also this method has had questionable behaviors:</p>
+     * <ul>
+     *     <li>Calling this method can update {@link #mCurrentSubtype}.</li>
+     *     <li>This method may return {@link #mCurrentSubtype} as-is, even if it does not belong to
+     *     the current IME.</li>
+     * </ul>
+     * <p>TODO(b/347083680): Address above issues.</p>
+     */
+    @GuardedBy("ImfLock.class")
+    @Nullable
+    InputMethodSubtype getCurrentInputMethodSubtype() {
+        final var selectedMethodId = getSelectedMethodId();
+        if (selectedMethodId == null) {
+            return null;
+        }
+        final InputMethodSettings settings = InputMethodSettingsRepository.get(mUserId);
+        final InputMethodInfo imi = settings.getMethodMap().get(selectedMethodId);
+        if (imi == null || imi.getSubtypeCount() == 0) {
+            return null;
+        }
+        final var subtype = SubtypeUtils.getCurrentInputMethodSubtype(imi, settings,
+                mCurrentSubtype);
+        mCurrentSubtype = subtype;
+        return subtype;
+    }
+
+
     @GuardedBy("ImfLock.class")
     void setDisplayIdToShowIme(int displayId) {
         mDisplayIdToShowIme = displayId;
@@ -657,4 +713,29 @@
     int getDeviceIdToShowIme() {
         return mDeviceIdToShowIme;
     }
+
+    @UserIdInt
+    int getUserId() {
+        return mUserId;
+    }
+
+    @GuardedBy("ImfLock.class")
+    void setImeWindowVis(int imeWindowVis) {
+        mImeWindowVis = imeWindowVis;
+    }
+
+    @GuardedBy("ImfLock.class")
+    int getImeWindowVis() {
+        return mImeWindowVis;
+    }
+
+    @GuardedBy("ImfLock.class")
+    int getBackDisposition() {
+        return mBackDisposition;
+    }
+
+    @GuardedBy("ImfLock.class")
+    void setBackDisposition(int backDisposition) {
+        mBackDisposition = backDisposition;
+    }
 }
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 183b4b5..875380f 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -70,7 +70,6 @@
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentProvider;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -80,7 +79,6 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.res.Resources;
-import android.database.ContentObserver;
 import android.hardware.input.InputManager;
 import android.inputmethodservice.InputMethodService;
 import android.media.AudioManagerInternal;
@@ -299,32 +297,45 @@
     private final String[] mNonPreemptibleInputMethods;
 
     /**
-     * See {@link #shouldEnableExperimentalConcurrentMultiUserMode(Context)} about when set to be
-     * {@code true}.
+     * See {@link #shouldEnableConcurrentMultiUserMode(Context)} about when set to be {@code true}.
      */
     @SharedByAllUsersField
-    private final boolean mExperimentalConcurrentMultiUserModeEnabled;
+    private final boolean mConcurrentMultiUserModeEnabled;
 
     /**
-     * Returns {@code true} if experimental concurrent multi-user mode is enabled.
+     * Returns {@code true} if the concurrent multi-user mode is enabled.
      *
      * <p>Currently not compatible with profiles (e.g. work profile).</p>
      *
      * @param context {@link Context} to be used to query
      *                {@link PackageManager#FEATURE_AUTOMOTIVE}
-     * @return {@code true} if experimental concurrent multi-user mode is enabled.
+     * @return {@code true} if the concurrent multi-user mode is enabled.
      */
-    static boolean shouldEnableExperimentalConcurrentMultiUserMode(@NonNull Context context) {
+    static boolean shouldEnableConcurrentMultiUserMode(@NonNull Context context) {
         return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
                 && UserManager.isVisibleBackgroundUsersEnabled()
                 && context.getResources().getBoolean(android.R.bool.config_perDisplayFocusEnabled)
                 && Flags.concurrentInputMethods();
     }
 
+    /**
+     * Figures out the target IME user ID for a given {@link Binder} IPC.
+     *
+     * @param callingProcessUserId the user ID of the calling process
+     * @return User ID to be used for this {@link Binder} call.
+     */
+    @GuardedBy("ImfLock.class")
+    @UserIdInt
+    @BinderThread
+    private int resolveImeUserIdLocked(@UserIdInt int callingProcessUserId) {
+        return mConcurrentMultiUserModeEnabled ? callingProcessUserId : mCurrentUserId;
+    }
+
     final Context mContext;
     final Resources mRes;
     private final Handler mHandler;
 
+    private final InputMethodManagerInternal mInputMethodManagerInternal;
     @NonNull
     private final Handler mIoHandler;
 
@@ -337,8 +348,6 @@
     @GuardedBy("ImfLock.class")
     private UserDataRepository mUserDataRepository;
 
-    @MultiUserUnawareField
-    final SettingsObserver mSettingsObserver;
     final WindowManagerInternal mWindowManagerInternal;
     private final ActivityManagerInternal mActivityManagerInternal;
     final PackageManagerInternal mPackageManagerInternal;
@@ -377,15 +386,6 @@
     @SharedByAllUsersField
     private final SparseArray<String> mVirtualDeviceMethodMap = new SparseArray<>();
 
-    // TODO: Instantiate mSwitchingController for each user.
-    @NonNull
-    @MultiUserUnawareField
-    private InputMethodSubtypeSwitchingController mSwitchingController;
-    // TODO: Instantiate mHardwareKeyboardShortcutController for each user.
-    @NonNull
-    @MultiUserUnawareField
-    private HardwareKeyboardShortcutController mHardwareKeyboardShortcutController;
-
     @Nullable
     private StatusBarManagerInternal mStatusBarManagerInternal;
     @SharedByAllUsersField
@@ -477,12 +477,6 @@
     private final ClientController mClientController;
 
     /**
-     * Holds the current IME binding state info.
-     */
-    @MultiUserUnawareField
-    ImeBindingState mImeBindingState;
-
-    /**
      * Set once the system is ready to run third party code.
      */
     @SharedByAllUsersField
@@ -500,39 +494,6 @@
         return getUserData(userId).mBindingController;
     }
 
-
-    /**
-     * Id obtained with {@link InputMethodInfo#getId()} for the currently selected input method.
-     * This is to be synchronized with the secure settings keyed with
-     * {@link Settings.Secure#DEFAULT_INPUT_METHOD}.
-     *
-     * <p>This can be transiently {@code null} when the system is re-initializing input method
-     * settings, e.g., the system locale is just changed.</p>
-     *
-     * <p>Note that {@link InputMethodBindingController#getCurId()} is used to track which IME
-     * is being connected to {@link InputMethodManagerService}.</p>
-     *
-     * @see InputMethodBindingController#getCurId()
-     */
-    @GuardedBy("ImfLock.class")
-    @Nullable
-    String getSelectedMethodIdLocked() {
-        return getInputMethodBindingController(mCurrentUserId).getSelectedMethodId();
-    }
-
-    @GuardedBy("ImfLock.class")
-    @Nullable
-    InputMethodInfo queryInputMethodForCurrentUserLocked(@NonNull String imeId) {
-        return InputMethodSettingsRepository.get(mCurrentUserId).getMethodMap().get(imeId);
-    }
-
-    /**
-     * The client that is currently bound to an input method.
-     */
-    @MultiUserUnawareField
-    @Nullable
-    private ClientState mCurClient;
-
     /**
      * The last window token that we confirmed that IME started talking to.  This is always updated
      * upon reports from the input method.  If the window state is already changed before the report
@@ -542,33 +503,6 @@
     IBinder mLastImeTargetWindow;
 
     /**
-     * The {@link IRemoteInputConnection} last provided by the current client.
-     */
-    @MultiUserUnawareField
-    IRemoteInputConnection mCurInputConnection;
-
-    /**
-     * The {@link ImeOnBackInvokedDispatcher} last provided by the current client to
-     * receive {@link android.window.OnBackInvokedCallback}s forwarded from IME.
-     */
-    @MultiUserUnawareField
-    ImeOnBackInvokedDispatcher mCurImeDispatcher;
-
-    /**
-     * The {@link IRemoteAccessibilityInputConnection} last provided by the current client.
-     */
-    @MultiUserUnawareField
-    @Nullable
-    IRemoteAccessibilityInputConnection mCurRemoteAccessibilityInputConnection;
-
-    /**
-     * The {@link EditorInfo} last provided by the current client.
-     */
-    @MultiUserUnawareField
-    @Nullable
-    EditorInfo mCurEditorInfo;
-
-    /**
      * Map of window perceptible states indexed by their associated window tokens.
      *
      * The value {@code true} indicates that IME has not been mostly hidden via
@@ -579,38 +513,6 @@
     private final WeakHashMap<IBinder, Boolean> mFocusedWindowPerceptible = new WeakHashMap<>();
 
     /**
-     * The token tracking the current IME show request that is waiting for a connection to an IME,
-     * otherwise {@code null}.
-     */
-    @Nullable
-    @MultiUserUnawareField
-    private ImeTracker.Token mCurStatsToken;
-
-    /**
-     * {@code true} if the current input method is in fullscreen mode.
-     */
-    @MultiUserUnawareField
-    boolean mInFullscreenMode;
-
-    /**
-     * The token we have made for the currently active input method, to
-     * identify it in the future.
-     */
-    @GuardedBy("ImfLock.class")
-    @Nullable
-    IBinder getCurTokenLocked() {
-        return getInputMethodBindingController(mCurrentUserId).getCurToken();
-    }
-
-    /**
-     * The displayId of current active input method.
-     */
-    @GuardedBy("ImfLock.class")
-    int getCurTokenDisplayIdLocked() {
-        return getInputMethodBindingController(mCurrentUserId).getCurTokenDisplayId();
-    }
-
-    /**
      * The display ID of the input method indicates the fallback display which returned by
      * {@link #computeImeDisplayIdForTarget}.
      */
@@ -627,59 +529,11 @@
     }
 
     /**
-     * Have we called mCurMethod.bindInput()?
-     */
-    @MultiUserUnawareField
-    boolean mBoundToMethod;
-
-    /**
-     * Have we called bindInput() for accessibility services?
-     */
-    @MultiUserUnawareField
-    boolean mBoundToAccessibility;
-
-    /**
-     * Currently enabled session.
-     */
-    @GuardedBy("ImfLock.class")
-    @MultiUserUnawareField
-    SessionState mEnabledSession;
-    @MultiUserUnawareField
-    SparseArray<AccessibilitySessionState> mEnabledAccessibilitySessions = new SparseArray<>();
-
-    /**
      * True if the device is currently interactive with user.  The value is true initially.
      */
     @MultiUserUnawareField
     boolean mIsInteractive = true;
 
-    @MultiUserUnawareField
-    int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT;
-
-    /**
-     * A set of status bits regarding the active IME.
-     *
-     * <p>This value is a combination of following two bits:</p>
-     * <dl>
-     * <dt>{@link InputMethodService#IME_ACTIVE}</dt>
-     * <dd>
-     *   If this bit is ON, connected IME is ready to accept touch/key events.
-     * </dd>
-     * <dt>{@link InputMethodService#IME_VISIBLE}</dt>
-     * <dd>
-     *   If this bit is ON, some of IME view, e.g. software input, candidate view, is visible.
-     * </dd>
-     * <dt>{@link InputMethodService#IME_INVISIBLE}</dt>
-     * <dd> If this bit is ON, IME is ready with views from last EditorInfo but is
-     *    currently invisible.
-     * </dd>
-     * </dl>
-     * <em>Do not update this value outside of {@link #setImeWindowStatus(IBinder, int, int)} and
-     * {@link InputMethodBindingController#unbindCurrentMethod()}.</em>
-     */
-    @MultiUserUnawareField
-    int mImeWindowVis;
-
     @SharedByAllUsersField
     private final MyPackageMonitor mMyPackageMonitor = new MyPackageMonitor();
 
@@ -713,94 +567,53 @@
     @NonNull
     private final ImeTrackerService mImeTrackerService;
 
-    class SettingsObserver extends ContentObserver {
-        int mUserId;
-        boolean mRegistered = false;
-        @NonNull
-        String mLastEnabled = "";
-
-        /**
-         * <em>This constructor must be called within the lock.</em>
-         */
-        SettingsObserver(Handler handler) {
-            super(handler);
+    @GuardedBy("ImfLock.class")
+    private void onSecureSettingsChangedLocked(@NonNull String key, @UserIdInt int userId) {
+        if (!mConcurrentMultiUserModeEnabled && userId != mCurrentUserId) {
+            return;
         }
-
-        @GuardedBy("ImfLock.class")
-        public void registerContentObserverLocked(@UserIdInt int userId) {
-            if (mRegistered && mUserId == userId) {
-                return;
+        switch (key) {
+            case Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD: {
+                mMenuController.updateKeyboardFromSettingsLocked();
+                break;
             }
-            ContentResolver resolver = mContext.getContentResolver();
-            if (mRegistered) {
-                mContext.getContentResolver().unregisterContentObserver(this);
-                mRegistered = false;
-            }
-            if (mUserId != userId) {
-                mLastEnabled = "";
-                mUserId = userId;
-            }
-            resolver.registerContentObserver(Settings.Secure.getUriFor(
-                    Settings.Secure.DEFAULT_INPUT_METHOD), false, this, userId);
-            resolver.registerContentObserver(Settings.Secure.getUriFor(
-                    Settings.Secure.ENABLED_INPUT_METHODS), false, this, userId);
-            resolver.registerContentObserver(Settings.Secure.getUriFor(
-                    Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE), false, this, userId);
-            resolver.registerContentObserver(Settings.Secure.getUriFor(
-                    Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD), false, this, userId);
-            resolver.registerContentObserver(Settings.Secure.getUriFor(
-                    Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE), false, this, userId);
-            resolver.registerContentObserver(Settings.Secure.getUriFor(
-                    STYLUS_HANDWRITING_ENABLED), false, this);
-            mRegistered = true;
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            final Uri showImeUri = Settings.Secure.getUriFor(
-                    Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD);
-            final Uri accessibilityRequestingNoImeUri = Settings.Secure.getUriFor(
-                    Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE);
-            final Uri stylusHandwritingEnabledUri = Settings.Secure.getUriFor(
-                    STYLUS_HANDWRITING_ENABLED);
-            synchronized (ImfLock.class) {
-                if (showImeUri.equals(uri)) {
-                    mMenuController.updateKeyboardFromSettingsLocked();
-                } else if (accessibilityRequestingNoImeUri.equals(uri)) {
-                    final int accessibilitySoftKeyboardSetting = Settings.Secure.getIntForUser(
-                            mContext.getContentResolver(),
-                            Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0, mUserId);
-                    mVisibilityStateComputer.getImePolicy().setA11yRequestNoSoftKeyboard(
-                            accessibilitySoftKeyboardSetting);
-                    if (mVisibilityStateComputer.getImePolicy().isA11yRequestNoSoftKeyboard()) {
-                        hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
-                                SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE);
-                    } else if (isShowRequestedForCurrentWindow()) {
-                        showCurrentInputLocked(mImeBindingState.mFocusedWindow,
-                                InputMethodManager.SHOW_IMPLICIT,
-                                SoftInputShowHideReason.SHOW_SETTINGS_ON_CHANGE);
-                    }
-                } else if (stylusHandwritingEnabledUri.equals(uri)) {
-                    InputMethodManager.invalidateLocalStylusHandwritingAvailabilityCaches();
-                    InputMethodManager
-                            .invalidateLocalConnectionlessStylusHandwritingAvailabilityCaches();
-                } else {
-                    boolean enabledChanged = false;
-                    String newEnabled = InputMethodSettingsRepository.get(mCurrentUserId)
-                            .getEnabledInputMethodsStr();
-                    if (!mLastEnabled.equals(newEnabled)) {
-                        mLastEnabled = newEnabled;
-                        enabledChanged = true;
-                    }
-                    updateInputMethodsFromSettingsLocked(enabledChanged);
+            case Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE: {
+                final int accessibilitySoftKeyboardSetting = Settings.Secure.getIntForUser(
+                        mContext.getContentResolver(),
+                        Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0, userId);
+                mVisibilityStateComputer.getImePolicy().setA11yRequestNoSoftKeyboard(
+                        accessibilitySoftKeyboardSetting);
+                final var userData = getUserData(userId);
+                if (mVisibilityStateComputer.getImePolicy().isA11yRequestNoSoftKeyboard()) {
+                    hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow,
+                            0 /* flags */, SoftInputShowHideReason.HIDE_SETTINGS_ON_CHANGE, userId);
+                } else if (isShowRequestedForCurrentWindow(userId)) {
+                    showCurrentInputLocked(userData.mImeBindingState.mFocusedWindow,
+                            InputMethodManager.SHOW_IMPLICIT,
+                            SoftInputShowHideReason.SHOW_SETTINGS_ON_CHANGE, userId);
                 }
+                break;
             }
-        }
-
-        @Override
-        public String toString() {
-            return "SettingsObserver{mUserId=" + mUserId + " mRegistered=" + mRegistered
-                    + " mLastEnabled=" + mLastEnabled + "}";
+            case STYLUS_HANDWRITING_ENABLED: {
+                InputMethodManager.invalidateLocalStylusHandwritingAvailabilityCaches();
+                InputMethodManager
+                        .invalidateLocalConnectionlessStylusHandwritingAvailabilityCaches();
+                break;
+            }
+            case Settings.Secure.DEFAULT_INPUT_METHOD:
+            case Settings.Secure.ENABLED_INPUT_METHODS:
+            case Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE: {
+                boolean enabledChanged = false;
+                String newEnabled = InputMethodSettingsRepository.get(userId)
+                        .getEnabledInputMethodsStr();
+                final var userData = getUserData(userId);
+                if (!userData.mLastEnabledInputMethodsStr.equals(newEnabled)) {
+                    userData.mLastEnabledInputMethodsStr = newEnabled;
+                    enabledChanged = true;
+                }
+                updateInputMethodsFromSettingsLocked(enabledChanged, userId);
+                break;
+            }
         }
     }
 
@@ -837,7 +650,7 @@
      * Handles {@link Intent#ACTION_LOCALE_CHANGED}.
      *
      * <p>Note: For historical reasons, {@link Intent#ACTION_LOCALE_CHANGED} has been sent to all
-     * the users. We should ignore this event if this is about any background user's locale.</p>
+     * the users.</p>
      */
     void onActionLocaleChanged(@NonNull LocaleList prevLocales, @NonNull LocaleList newLocales) {
         if (DEBUG) {
@@ -854,11 +667,14 @@
                         AdditionalSubtypeMapRepository.get(userId),
                         DirectBootAwareness.AUTO);
                 InputMethodSettingsRepository.put(userId, settings);
+
+                if (mConcurrentMultiUserModeEnabled || userId == mCurrentUserId) {
+                    postInputMethodSettingUpdatedLocked(true /* resetDefaultEnabledIme */, userId);
+                    // If the locale is changed, needs to reset the default ime
+                    resetDefaultImeLocked(mContext, userId);
+                    updateFromSettingsLocked(true, userId);
+                }
             }
-            postInputMethodSettingUpdatedLocked(true /* resetDefaultEnabledIme */);
-            // If the locale is changed, needs to reset the default ime
-            resetDefaultImeLocked(mContext);
-            updateFromSettingsLocked(true);
         }
     }
 
@@ -893,8 +709,8 @@
                 if (!isChangingPackagesOfCurrentUserLocked()) {
                     return false;
                 }
-                final InputMethodSettings settings =
-                        InputMethodSettingsRepository.get(mCurrentUserId);
+                final int userId = getChangingUserId();
+                final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
                 String curInputMethodId = settings.getSelectedInputMethod();
                 final List<InputMethodInfo> methodList = settings.getMethodList();
                 final int numImes = methodList.size();
@@ -907,8 +723,8 @@
                                     if (!doit) {
                                         return true;
                                     }
-                                    resetSelectedInputMethodAndSubtypeLocked("");
-                                    chooseNewDefaultIMELocked();
+                                    resetSelectedInputMethodAndSubtypeLocked("", userId);
+                                    chooseNewDefaultIMELocked(userId);
                                     return true;
                                 }
                             }
@@ -975,7 +791,7 @@
                     if (change == PACKAGE_PERMANENT_CHANGE) {
                         Slog.i(TAG, "Input method uninstalled, disabling: " + imi.getComponent());
                         if (isCurrentUser) {
-                            setInputMethodEnabledLocked(imi.getId(), false);
+                            setInputMethodEnabledLocked(imi.getId(), false, userId);
                         } else {
                             settings.buildAndPutEnabledInputMethodsStrRemovingId(
                                     new StringBuilder(),
@@ -1013,7 +829,7 @@
                 if (!isCurrentUser) {
                     return;
                 }
-                postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */);
+                postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */, userId);
 
                 boolean changed = false;
 
@@ -1033,12 +849,14 @@
                             // Uh oh, current input method is no longer around!
                             // Pick another one...
                             Slog.i(TAG, "Current input method removed: " + curInputMethodId);
-                            updateSystemUiLocked(0 /* vis */, mBackDisposition);
-                            if (!chooseNewDefaultIMELocked()) {
+                            final var bindingController = getInputMethodBindingController(userId);
+                            updateSystemUiLocked(0 /* vis */,
+                                    bindingController.getBackDisposition(), userId);
+                            if (!chooseNewDefaultIMELocked(userId)) {
                                 changed = true;
                                 curIm = null;
                                 Slog.i(TAG, "Unsetting current input method");
-                                resetSelectedInputMethodAndSubtypeLocked("");
+                                resetSelectedInputMethodAndSubtypeLocked("", userId);
                             }
                         }
                     }
@@ -1047,7 +865,7 @@
                 if (curIm == null) {
                     // We currently don't have a default input method... is
                     // one now available?
-                    changed = chooseNewDefaultIMELocked();
+                    changed = chooseNewDefaultIMELocked(userId);
                 } else if (!changed && isPackageModified(curIm.getPackageName())) {
                     // Even if the current input method is still available, current subtype could
                     // be obsolete when the package is modified in practice.
@@ -1055,7 +873,7 @@
                 }
 
                 if (changed) {
-                    updateFromSettingsLocked(false);
+                    updateFromSettingsLocked(false, userId);
                 }
             }
         }
@@ -1107,18 +925,45 @@
     public static final class Lifecycle extends SystemService {
         private final InputMethodManagerService mService;
 
-
         public Lifecycle(Context context) {
-            this(context, new InputMethodManagerService(context,
-                            shouldEnableExperimentalConcurrentMultiUserMode(context)));
+            this(context, createServiceForProduction(context));
         }
 
-        public Lifecycle(
-                Context context, @NonNull InputMethodManagerService inputMethodManagerService) {
+        @VisibleForTesting
+        Lifecycle(Context context, @NonNull InputMethodManagerService inputMethodManagerService) {
             super(context);
             mService = inputMethodManagerService;
         }
 
+        /**
+         * Does initialization then instantiate {@link InputMethodManagerService} for production
+         * configurations.
+         *
+         * <p>We have this abstraction just because several unit tests directly initialize
+         * {@link InputMethodManagerService} with some mocked/emulated dependencies.</p>
+         *
+         * @param context {@link Context} to be used to set up
+         * @return {@link InputMethodManagerService} object to be used
+         */
+        @NonNull
+        private static InputMethodManagerService createServiceForProduction(
+                @NonNull Context context) {
+            // TODO(b/196206770): Disallow I/O on this thread. Currently it's needed for loading
+            // additional subtypes in switchUserOnHandlerLocked().
+            final ServiceThread thread = new ServiceThread(HANDLER_THREAD_NAME,
+                    Process.THREAD_PRIORITY_FOREGROUND, true /* allowIo */);
+            thread.start();
+
+            final ServiceThread ioThread = new ServiceThread(PACKAGE_MONITOR_THREAD_NAME,
+                    Process.THREAD_PRIORITY_FOREGROUND, true /* allowIo */);
+            ioThread.start();
+
+            return new InputMethodManagerService(context,
+                    shouldEnableConcurrentMultiUserMode(context), thread.getLooper(),
+                    Handler.createAsync(ioThread.getLooper()),
+                    null /* bindingControllerForTesting */);
+        }
+
         @Override
         public void onStart() {
             mService.publishLocalService();
@@ -1140,7 +985,7 @@
         public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
             // Called on ActivityManager thread.
             synchronized (ImfLock.class) {
-                if (mService.mExperimentalConcurrentMultiUserModeEnabled) {
+                if (mService.mConcurrentMultiUserModeEnabled) {
                     // In concurrent multi-user mode, we in general do not rely on the concept of
                     // current user.
                     return;
@@ -1173,10 +1018,9 @@
             final int userId = user.getUserIdentifier();
             SecureSettingsWrapper.onUserStarting(userId);
             synchronized (ImfLock.class) {
-                mService.getUserData(userId);
-                if (mService.mExperimentalConcurrentMultiUserModeEnabled) {
+                if (mService.mConcurrentMultiUserModeEnabled) {
                     if (mService.mCurrentUserId != userId && mService.mSystemReady) {
-                        mService.experimentalInitializeVisibleBackgroundUserLocked(userId);
+                        mService.initializeVisibleBackgroundUserLocked(userId);
                     }
                 }
             }
@@ -1197,10 +1041,10 @@
             InputMethodSettingsRepository.put(userId, newSettings);
             if (mCurrentUserId == userId) {
                 // We need to rebuild IMEs.
-                postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */);
-                updateInputMethodsFromSettingsLocked(true /* enabledChanged */);
-            } else if (mExperimentalConcurrentMultiUserModeEnabled) {
-                experimentalInitializeVisibleBackgroundUserLocked(userId);
+                postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */, userId);
+                updateInputMethodsFromSettingsLocked(true /* enabledChanged */, userId);
+            } else if (mConcurrentMultiUserModeEnabled) {
+                initializeVisibleBackgroundUserLocked(userId);
             }
         }
     }
@@ -1217,60 +1061,32 @@
         }
         // Hide soft input before user switch task since switch task may block main handler a while
         // and delayed the hideCurrentInputLocked().
-        hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
-                SoftInputShowHideReason.HIDE_SWITCH_USER);
+        final var userData = getUserData(userId);
+        hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow, 0 /* flags */,
+                SoftInputShowHideReason.HIDE_SWITCH_USER, userId);
         final UserSwitchHandlerTask task = new UserSwitchHandlerTask(this, userId,
                 clientToBeReset);
         mUserSwitchHandlerTask = task;
         mHandler.post(task);
     }
 
-    public InputMethodManagerService(Context context,
-            boolean experimentalConcurrentMultiUserModeEnabled) {
-        this(context, experimentalConcurrentMultiUserModeEnabled, null, null, null);
-    }
-
     @VisibleForTesting
     InputMethodManagerService(
             Context context,
-            boolean experimentalConcurrentMultiUserModeEnabled,
-            @Nullable ServiceThread serviceThreadForTesting,
-            @Nullable ServiceThread ioThreadForTesting,
+            boolean concurrentMultiUserModeEnabled,
+            @NonNull Looper uiLooper,
+            @NonNull Handler ioHandler,
             @Nullable IntFunction<InputMethodBindingController> bindingControllerForTesting) {
         synchronized (ImfLock.class) {
-            mExperimentalConcurrentMultiUserModeEnabled =
-                    experimentalConcurrentMultiUserModeEnabled;
+            mConcurrentMultiUserModeEnabled = concurrentMultiUserModeEnabled;
             mContext = context;
             mRes = context.getResources();
             SecureSettingsWrapper.onStart(mContext);
 
-            // TODO(b/196206770): Disallow I/O on this thread. Currently it's needed for loading
-            // additional subtypes in switchUserOnHandlerLocked().
-            final ServiceThread thread =
-                    serviceThreadForTesting != null
-                            ? serviceThreadForTesting
-                            : new ServiceThread(
-                                    HANDLER_THREAD_NAME,
-                                    Process.THREAD_PRIORITY_FOREGROUND,
-                                    true /* allowIo */);
-            thread.start();
-            mHandler = Handler.createAsync(thread.getLooper(), this);
-            {
-                final ServiceThread ioThread =
-                        ioThreadForTesting != null
-                                ? ioThreadForTesting
-                                : new ServiceThread(
-                                        PACKAGE_MONITOR_THREAD_NAME,
-                                        Process.THREAD_PRIORITY_FOREGROUND,
-                                        true /* allowIo */);
-                ioThread.start();
-                mIoHandler = Handler.createAsync(ioThread.getLooper());
-            }
+            mHandler = Handler.createAsync(uiLooper, this);
+            mIoHandler = ioHandler;
             SystemLocaleWrapper.onStart(context, this::onActionLocaleChanged, mHandler);
-            mImeTrackerService = new ImeTrackerService(serviceThreadForTesting != null
-                    ? serviceThreadForTesting.getLooper() : Looper.getMainLooper());
-            // Note: SettingsObserver doesn't register observers in its constructor.
-            mSettingsObserver = new SettingsObserver(mHandler);
+            mImeTrackerService = new ImeTrackerService(mHandler);
             mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
             mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
             mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
@@ -1283,7 +1099,13 @@
 
             mShowOngoingImeSwitcherForPhones = false;
 
-            // InputMethodSettingsRepository should be initialized before buildInputMethodListLocked
+            // Executing InputMethodSettingsRepository.initialize() does not mean that it
+            // immediately becomes ready to return the up-to-date InputMethodSettings for each
+            // running user, because we want to return from the constructor as early as possible so
+            // as not to delay the system boot process.
+            // Search for InputMethodSettingsRepository.put() to find where and when it's actually
+            // being updated. In general IMMS should refrain from exposing the existence of IMEs
+            // until systemReady().
             InputMethodSettingsRepository.initialize(mHandler, mContext);
             AdditionalSubtypeMapRepository.initialize(mHandler, mContext);
 
@@ -1294,34 +1116,23 @@
             mUserDataRepository = new UserDataRepository(mHandler, mUserManagerInternal,
                     bindingControllerForTesting != null ? bindingControllerForTesting
                             : bindingControllerFactory);
-            for (int id : mUserManagerInternal.getUserIds()) {
-                getUserData(id);
-            }
 
-            final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
-
-            mSwitchingController =
-                    InputMethodSubtypeSwitchingController.createInstanceLocked(context,
-                            settings.getMethodMap(), settings.getUserId());
-            mHardwareKeyboardShortcutController =
-                    new HardwareKeyboardShortcutController(settings.getMethodMap(),
-                            settings.getUserId());
             mMenuController = new InputMethodMenuController(this);
             mVisibilityStateComputer = new ImeVisibilityStateComputer(this);
             mVisibilityApplier = new DefaultImeVisibilityApplier(this);
 
             mClientController = new ClientController(mPackageManagerInternal);
             mClientController.addClientControllerCallback(c -> onClientRemoved(c));
-            mImeBindingState = ImeBindingState.newEmptyState();
 
             mPreventImeStartupUnlessTextEditor = mRes.getBoolean(
                     com.android.internal.R.bool.config_preventImeStartupUnlessTextEditor);
             mNonPreemptibleInputMethods = mRes.getStringArray(
                     com.android.internal.R.array.config_nonPreemptibleInputMethods);
             Runnable discardDelegationTextRunnable = () -> discardHandwritingDelegationText();
-            mHwController = new HandwritingModeController(mContext, thread.getLooper(),
+            mHwController = new HandwritingModeController(mContext, uiLooper,
                     new InkWindowInitializer(), discardDelegationTextRunnable);
             registerDeviceListenerAndCheckStylusSupport();
+            mInputMethodManagerInternal = new LocalServiceImpl();
         }
     }
 
@@ -1361,10 +1172,11 @@
     }
 
     @GuardedBy("ImfLock.class")
-    private void resetDefaultImeLocked(Context context) {
+    private void resetDefaultImeLocked(Context context, @UserIdInt int userId) {
+        final var bindingController = getInputMethodBindingController(userId);
         // Do not reset the default (current) IME when it is a 3rd-party IME
-        String selectedMethodId = getSelectedMethodIdLocked();
-        final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
+        String selectedMethodId = bindingController.getSelectedMethodId();
+        final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
         if (selectedMethodId != null
                 && !settings.getMethodMap().get(selectedMethodId).isSystem()) {
             return;
@@ -1379,7 +1191,7 @@
         if (DEBUG) {
             Slog.i(TAG, "Default found, using " + defIm.getId());
         }
-        setSelectedInputMethodAndSubtypeLocked(defIm, NOT_A_SUBTYPE_ID, false);
+        setSelectedInputMethodAndSubtypeLocked(defIm, NOT_A_SUBTYPE_ID, false, userId);
     }
 
     @GuardedBy("ImfLock.class")
@@ -1424,29 +1236,32 @@
     @GuardedBy("ImfLock.class")
     private void switchUserOnHandlerLocked(@UserIdInt int newUserId,
             IInputMethodClientInvoker clientToBeReset) {
+        final int prevUserId = mCurrentUserId;
         if (DEBUG) {
             Slog.d(TAG, "Switching user stage 1/3. newUserId=" + newUserId
-                    + " currentUserId=" + mCurrentUserId);
+                    + " prevUserId=" + prevUserId);
         }
 
         // Clean up stuff for mCurrentUserId, which soon becomes the previous user.
 
         // TODO(b/338461930): Check if this is still necessary or not.
-        onUnbindCurrentMethodByReset();
+        onUnbindCurrentMethodByReset(prevUserId);
 
         // Note that in b/197848765 we want to see if we can keep the binding alive for better
         // profile switching.
-        final var bindingController = getInputMethodBindingController(mCurrentUserId);
+        final var bindingController = getInputMethodBindingController(prevUserId);
         bindingController.unbindCurrentMethod();
 
-        unbindCurrentClientLocked(UnbindReason.SWITCH_USER);
+        unbindCurrentClientLocked(UnbindReason.SWITCH_USER, prevUserId);
 
         // Hereafter we start initializing things for "newUserId".
 
         maybeInitImeNavbarConfigLocked(newUserId);
 
-        // ContentObserver should be registered again when the user is changed
-        mSettingsObserver.registerContentObserverLocked(newUserId);
+        final var newUserData = getUserData(newUserId);
+
+        // TODO(b/342027196): Double check if we need to always reset upon user switching.
+        newUserData.mLastEnabledInputMethodsStr = "";
 
         mCurrentUserId = newUserId;
         final String defaultImiId = SecureSettingsWrapper.getString(
@@ -1465,13 +1280,14 @@
         final boolean initialUserSwitch = TextUtils.isEmpty(defaultImiId);
 
         final InputMethodSettings newSettings = InputMethodSettingsRepository.get(newUserId);
-        postInputMethodSettingUpdatedLocked(initialUserSwitch /* resetDefaultEnabledIme */);
+        postInputMethodSettingUpdatedLocked(initialUserSwitch /* resetDefaultEnabledIme */,
+                newUserId);
         if (TextUtils.isEmpty(newSettings.getSelectedInputMethod())) {
             // This is the first time of the user switch and
             // set the current ime to the proper one.
-            resetDefaultImeLocked(mContext);
+            resetDefaultImeLocked(mContext, newUserId);
         }
-        updateFromSettingsLocked(true);
+        updateFromSettingsLocked(true, newUserId);
 
         if (initialUserSwitch) {
             InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
@@ -1490,7 +1306,7 @@
                 // The client is already gone.
                 return;
             }
-            cs.mClient.scheduleStartInputIfNecessary(mInFullscreenMode);
+            cs.mClient.scheduleStartInputIfNecessary(newUserData.mInFullscreenMode);
         }
     }
 
@@ -1508,7 +1324,9 @@
                 mStatusBarManagerInternal =
                         LocalServices.getService(StatusBarManagerInternal.class);
                 hideStatusBarIconLocked();
-                updateSystemUiLocked(mImeWindowVis, mBackDisposition);
+                final var bindingController = getInputMethodBindingController(currentUserId);
+                updateSystemUiLocked(bindingController.getImeWindowVis(),
+                        bindingController.getBackDisposition(), currentUserId);
                 mShowOngoingImeSwitcherForPhones = mRes.getBoolean(
                         com.android.internal.R.bool.show_ongoing_ime_switcher);
                 if (mShowOngoingImeSwitcherForPhones) {
@@ -1536,7 +1354,19 @@
                 }, "Lazily initialize IMMS#mImeDrawsImeNavBarRes");
 
                 mMyPackageMonitor.register(mContext, UserHandle.ALL, mIoHandler);
-                mSettingsObserver.registerContentObserverLocked(currentUserId);
+                SecureSettingsChangeCallback.register(mHandler, mContext.getContentResolver(),
+                        new String[] {
+                                Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
+                                Settings.Secure.DEFAULT_INPUT_METHOD,
+                                Settings.Secure.ENABLED_INPUT_METHODS,
+                                Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE,
+                                Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD,
+                                Settings.Secure.STYLUS_HANDWRITING_ENABLED,
+                        }, (key, flags, userId) -> {
+                            synchronized (ImfLock.class) {
+                                onSecureSettingsChangedLocked(key, userId);
+                            }
+                        });
 
                 final IntentFilter broadcastFilterForAllUsers = new IntentFilter();
                 broadcastFilterForAllUsers.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
@@ -1552,8 +1382,8 @@
                         DirectBootAwareness.AUTO);
                 InputMethodSettingsRepository.put(currentUserId, newSettings);
                 postInputMethodSettingUpdatedLocked(
-                        !imeSelectedOnBoot /* resetDefaultEnabledIme */);
-                updateFromSettingsLocked(true);
+                        !imeSelectedOnBoot /* resetDefaultEnabledIme */, currentUserId);
+                updateFromSettingsLocked(true, currentUserId);
                 InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
                         getPackageManagerForUser(mContext, currentUserId),
                         newSettings.getEnabledInputMethodList());
@@ -1562,10 +1392,10 @@
                         AdditionalSubtypeMapRepository::startWriterThread,
                         "Start AdditionalSubtypeMapRepository's writer thread");
 
-                if (mExperimentalConcurrentMultiUserModeEnabled) {
+                if (mConcurrentMultiUserModeEnabled) {
                     for (int userId : mUserManagerInternal.getUserIds()) {
                         if (userId != mCurrentUserId) {
-                            experimentalInitializeVisibleBackgroundUserLocked(userId);
+                            initializeVisibleBackgroundUserLocked(userId);
                         }
                     }
                 }
@@ -1590,14 +1420,16 @@
      * Returns true iff the caller is identified to be the current input method with the token.
      *
      * @param token the window token given to the input method when it was started
+     * @param userId userId of the calling IME process
      * @return true if and only if non-null valid token is specified
      */
     @GuardedBy("ImfLock.class")
-    private boolean calledWithValidTokenLocked(@NonNull IBinder token) {
+    private boolean calledWithValidTokenLocked(@NonNull IBinder token, @UserIdInt int userId) {
         if (token == null) {
             throw new InvalidParameterException("token must not be null.");
         }
-        if (token != getCurTokenLocked()) {
+        final var bindingController = getInputMethodBindingController(userId);
+        if (token != bindingController.getCurToken()) {
             Slog.e(TAG, "Ignoring " + Debug.getCaller() + " due to an invalid token."
                     + " uid:" + Binder.getCallingUid() + " token:" + token);
             return false;
@@ -1870,20 +1702,31 @@
         }
     }
 
+    @GuardedBy("ImfLock.class")
+    private void onClientRemoved(ClientState client) {
+        clearClientSessionLocked(client);
+        clearClientSessionForAccessibilityLocked(client);
+        // TODO(b/324907325): Remove the suppress warnings once b/324907325 is fixed.
+        @SuppressWarnings("GuardedBy") Consumer<UserDataRepository.UserData> clientRemovedForUser =
+                userData -> onClientRemovedInternalLocked(client, userData);
+        mUserDataRepository.forAllUserData(clientRemovedForUser);
+    }
+
     /**
      * Hide the IME if the removed user is the current user.
      */
     // TODO(b/325515685): Move this method to InputMethodBindingController
     @GuardedBy("ImfLock.class")
-    private void onClientRemoved(ClientState client) {
-        clearClientSessionLocked(client);
-        clearClientSessionForAccessibilityLocked(client);
-        if (mCurClient == client) {
-            hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
-                    SoftInputShowHideReason.HIDE_REMOVE_CLIENT);
-            if (mBoundToMethod) {
-                mBoundToMethod = false;
-                IInputMethodInvoker curMethod = getCurMethodLocked();
+    private void onClientRemovedInternalLocked(ClientState client,
+            @NonNull UserDataRepository.UserData userData) {
+        final int userId = userData.mUserId;
+        if (userData.mCurClient == client) {
+            hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow, 0 /* flags */,
+                    SoftInputShowHideReason.HIDE_REMOVE_CLIENT, userId);
+            if (userData.mBoundToMethod) {
+                userData.mBoundToMethod = false;
+                final var userBindingController = getInputMethodBindingController(userId);
+                IInputMethodInvoker curMethod = userBindingController.getCurMethod();
                 if (curMethod != null) {
                     // When we unbind input, we are unbinding the client, so we always
                     // unbind ime and a11y together.
@@ -1891,10 +1734,10 @@
                     AccessibilityManagerInternal.get().unbindInput();
                 }
             }
-            mBoundToAccessibility = false;
-            mCurClient = null;
-            if (mImeBindingState.mFocusedWindowClient == client) {
-                mImeBindingState = ImeBindingState.newEmptyState();
+            userData.mBoundToAccessibility = false;
+            userData.mCurClient = null;
+            if (userData.mImeBindingState.mFocusedWindowClient == client) {
+                userData.mImeBindingState = ImeBindingState.newEmptyState();
             }
         }
     }
@@ -1907,49 +1750,51 @@
     }
 
     @GuardedBy("ImfLock.class")
-    void unbindCurrentClientLocked(@UnbindReason int unbindClientReason) {
-        if (mCurClient != null) {
+    void unbindCurrentClientLocked(@UnbindReason int unbindClientReason, @UserIdInt int userId) {
+        final var userData = getUserData(userId);
+        if (userData.mCurClient != null) {
             if (DEBUG) {
-                Slog.v(TAG, "unbindCurrentInputLocked: client=" + mCurClient.mClient.asBinder());
+                Slog.v(TAG, "unbindCurrentInputLocked: client="
+                        + userData.mCurClient.mClient.asBinder());
             }
-            if (mBoundToMethod) {
-                mBoundToMethod = false;
-                IInputMethodInvoker curMethod = getCurMethodLocked();
+            final var bindingController = getInputMethodBindingController(userId);
+            if (userData.mBoundToMethod) {
+                userData.mBoundToMethod = false;
+                IInputMethodInvoker curMethod = bindingController.getCurMethod();
                 if (curMethod != null) {
                     curMethod.unbindInput();
                 }
             }
-            mBoundToAccessibility = false;
+            userData.mBoundToAccessibility = false;
 
             // 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.mClient.setActive(false /* active */, false /* fullscreen */);
+            userData.mCurClient.mClient.setActive(false /* active */, false /* fullscreen */);
 
-            // TODO(b/325515685): make binding controller user independent. Before this change, the
-            //  following dependencies also need to be user independent: mCurClient, mBoundToMethod,
-            //  getCurMethodLocked(), and mMenuController.
-            final var bindingController = getInputMethodBindingController(mCurrentUserId);
-            mCurClient.mClient.onUnbindMethod(bindingController.getSequenceNumber(),
+            userData.mCurClient.mClient.onUnbindMethod(bindingController.getSequenceNumber(),
                     unbindClientReason);
-            mCurClient.mSessionRequested = false;
-            mCurClient.mSessionRequestedForAccessibility = false;
-            mCurClient = null;
-            ImeTracker.forLogging().onFailed(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
-            mCurStatsToken = null;
+            userData.mCurClient.mSessionRequested = false;
+            userData.mCurClient.mSessionRequestedForAccessibility = false;
+            userData.mCurClient = null;
+            ImeTracker.forLogging().onFailed(userData.mCurStatsToken,
+                    ImeTracker.PHASE_SERVER_WAIT_IME);
+            userData.mCurStatsToken = null;
+            // TODO: Make mMenuController multi-user aware
             mMenuController.hideInputMethodMenuLocked();
         }
     }
 
     /**
      * TODO(b/338404383) Remove
-     * Called when {@link #resetCurrentMethodAndClientLocked(int)} invoked for clean-up states
+     * Called when {@link #resetCurrentMethodAndClientLocked(int, int)} invoked for clean-up states
      * before unbinding the current method.
      */
     @GuardedBy("ImfLock.class")
-    void onUnbindCurrentMethodByReset() {
+    void onUnbindCurrentMethodByReset(@UserIdInt int userId) {
+        final var userData = getUserData(userId);
         final ImeTargetWindowState winState = mVisibilityStateComputer.getWindowStateOrNull(
-                mImeBindingState.mFocusedWindow);
+                userData.mImeBindingState.mFocusedWindow);
         if (winState != null && !winState.isRequestedImeVisible()
                 && !mVisibilityStateComputer.isInputShown()) {
             // Normally, the focus window will apply the IME visibility state to
@@ -1960,25 +1805,17 @@
             // As a result, we have to notify WM to apply IME visibility before clearing the
             // binding states in the first place.
             final var statsToken = createStatsTokenForFocusedClient(false /* show */,
-                    SoftInputShowHideReason.UNBIND_CURRENT_METHOD);
-            mVisibilityApplier.applyImeVisibility(mImeBindingState.mFocusedWindow, statsToken,
-                    STATE_HIDE_IME, mCurrentUserId);
+                    SoftInputShowHideReason.UNBIND_CURRENT_METHOD, userId);
+            mVisibilityApplier.applyImeVisibility(userData.mImeBindingState.mFocusedWindow,
+                    statsToken, STATE_HIDE_IME, SoftInputShowHideReason.NOT_SET /* ignore reason */,
+                    userId);
         }
     }
 
-    /**
-     * {@code true} when a {@link ClientState} has attached from starting the
-     * input connection.
-     */
-    @GuardedBy("ImfLock.class")
-    boolean hasAttachedClient() {
-        return mCurClient != null;
-    }
-
     @VisibleForTesting
     void setAttachedClientForTesting(@NonNull ClientState cs) {
         synchronized (ImfLock.class) {
-            mCurClient = cs;
+            getUserData(mCurrentUserId).mCurClient = cs;
         }
     }
 
@@ -1994,32 +1831,36 @@
     }
 
     @GuardedBy("ImfLock.class")
-    private boolean isShowRequestedForCurrentWindow() {
+    private boolean isShowRequestedForCurrentWindow(@UserIdInt int userId) {
+        final var userData = getUserData(userId);
+        // TODO(b/349904272): Make mVisibilityStateComputer multi-user aware
         final ImeTargetWindowState state = mVisibilityStateComputer.getWindowStateOrNull(
-                mImeBindingState.mFocusedWindow);
+                userData.mImeBindingState.mFocusedWindow);
         return state != null && state.isRequestedImeVisible();
     }
 
     @GuardedBy("ImfLock.class")
     @NonNull
-    InputBindResult attachNewInputLocked(@StartInputReason int startInputReason, boolean initial) {
-        final int userId = mCurrentUserId;
+    InputBindResult attachNewInputLocked(@StartInputReason int startInputReason, boolean initial,
+            @UserIdInt int userId) {
         final var bindingController = getInputMethodBindingController(userId);
-        if (!mBoundToMethod) {
-            bindingController.getCurMethod().bindInput(mCurClient.mBinding);
-            mBoundToMethod = true;
+        final var userData = getUserData(userId);
+        if (!userData.mBoundToMethod) {
+            bindingController.getCurMethod().bindInput(userData.mCurClient.mBinding);
+            userData.mBoundToMethod = true;
         }
 
         final boolean restarting = !initial;
         final Binder startInputToken = new Binder();
-        final StartInputInfo info = new StartInputInfo(mCurrentUserId,
+        final StartInputInfo info = new StartInputInfo(userId,
                 bindingController.getCurToken(), bindingController.getCurTokenDisplayId(),
                 bindingController.getCurId(), startInputReason,
-                restarting, UserHandle.getUserId(mCurClient.mUid),
-                mCurClient.mSelfReportedDisplayId, mImeBindingState.mFocusedWindow, mCurEditorInfo,
-                mImeBindingState.mFocusedWindowSoftInputMode,
+                restarting, UserHandle.getUserId(userData.mCurClient.mUid),
+                userData.mCurClient.mSelfReportedDisplayId,
+                userData.mImeBindingState.mFocusedWindow, userData.mCurEditorInfo,
+                userData.mImeBindingState.mFocusedWindowSoftInputMode,
                 bindingController.getSequenceNumber());
-        mImeTargetWindowMap.put(startInputToken, mImeBindingState.mFocusedWindow);
+        mImeTargetWindowMap.put(startInputToken, userData.mImeBindingState.mFocusedWindow);
         mStartInputHistory.addEntry(info);
 
         // Seems that PackageManagerInternal#grantImplicitAccess() doesn't handle cross-user
@@ -2027,33 +1868,34 @@
         // 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 (userId == UserHandle.getUserId(mCurClient.mUid)) {
+        if (userId == UserHandle.getUserId(userData.mCurClient.mUid)) {
             mPackageManagerInternal.grantImplicitAccess(userId, null /* intent */,
                     UserHandle.getAppId(bindingController.getCurMethodUid()),
-                    mCurClient.mUid, true /* direct */);
+                    userData.mCurClient.mUid, true /* direct */);
         }
 
         @InputMethodNavButtonFlags final int navButtonFlags = getInputMethodNavButtonFlagsLocked();
-        final SessionState session = mCurClient.mCurSession;
-        setEnabledSessionLocked(session);
-        session.mMethod.startInput(startInputToken, mCurInputConnection, mCurEditorInfo, restarting,
-                navButtonFlags, mCurImeDispatcher);
+        final SessionState session = userData.mCurClient.mCurSession;
+        setEnabledSessionLocked(session, userData);
+        session.mMethod.startInput(startInputToken, userData.mCurInputConnection,
+                userData.mCurEditorInfo, restarting, navButtonFlags, userData.mCurImeDispatcher);
         if (Flags.refactorInsetsController()) {
-            if (isShowRequestedForCurrentWindow() && mImeBindingState != null
-                    && mImeBindingState.mFocusedWindow != null) {
-                showSoftInputInternal(mImeBindingState.mFocusedWindow);
+            if (isShowRequestedForCurrentWindow(userId) && userData.mImeBindingState != null
+                    && userData.mImeBindingState.mFocusedWindow != null) {
+                showSoftInputInternal(userData.mImeBindingState.mFocusedWindow);
             }
         } else {
-            if (isShowRequestedForCurrentWindow()) {
+            if (isShowRequestedForCurrentWindow(userId)) {
                 if (DEBUG) Slog.v(TAG, "Attach new input asks to show input");
                 // Re-use current statsToken, if it exists.
-                final var statsToken = mCurStatsToken != null ? mCurStatsToken
+                final var statsToken = userData.mCurStatsToken != null ? userData.mCurStatsToken
                     : createStatsTokenForFocusedClient(true /* show */,
-                            SoftInputShowHideReason.ATTACH_NEW_INPUT);
-                mCurStatsToken = null;
-                showCurrentInputLocked(mImeBindingState.mFocusedWindow, statsToken,
+                            SoftInputShowHideReason.ATTACH_NEW_INPUT, userId);
+                userData.mCurStatsToken = null;
+                showCurrentInputLocked(userData.mImeBindingState.mFocusedWindow, statsToken,
                         mVisibilityStateComputer.getShowFlags(), MotionEvent.TOOL_TYPE_UNKNOWN,
-                        null /* resultReceiver */, SoftInputShowHideReason.ATTACH_NEW_INPUT);
+                        null /* resultReceiver */, SoftInputShowHideReason.ATTACH_NEW_INPUT,
+                        userId);
             }
         }
 
@@ -2063,7 +1905,8 @@
         final boolean suppressesSpellChecker =
                 curInputMethodInfo != null && curInputMethodInfo.suppressesSpellChecker();
         final SparseArray<IAccessibilityInputMethodSession> accessibilityInputMethodSessions =
-                createAccessibilityInputMethodSessions(mCurClient.mAccessibilitySessions);
+                createAccessibilityInputMethodSessions(
+                        userData.mCurClient.mAccessibilitySessions);
         if (bindingController.supportsStylusHandwriting() && hasSupportedStylusLocked()) {
             mHwController.setInkWindowInitializer(new InkWindowInitializer());
         }
@@ -2075,10 +1918,12 @@
 
     @GuardedBy("ImfLock.class")
     private void attachNewAccessibilityLocked(@StartInputReason int startInputReason,
-            boolean initial) {
-        if (!mBoundToAccessibility) {
+            boolean initial, @UserIdInt int userId) {
+        final var userData = getUserData(userId);
+
+        if (!userData.mBoundToAccessibility) {
             AccessibilityManagerInternal.get().bindInput();
-            mBoundToAccessibility = true;
+            userData.mBoundToAccessibility = true;
         }
 
         // TODO(b/187453053): grantImplicitAccess to accessibility services access? if so, need to
@@ -2087,9 +1932,11 @@
         // We don't start input when session for a11y is created. We start input when
         // input method start input, a11y manager service is always on.
         if (startInputReason != StartInputReason.SESSION_CREATED_BY_ACCESSIBILITY) {
-            setEnabledSessionForAccessibilityLocked(mCurClient.mAccessibilitySessions);
-            AccessibilityManagerInternal.get().startInput(mCurRemoteAccessibilityInputConnection,
-                    mCurEditorInfo, !initial /* restarting */);
+            setEnabledSessionForAccessibilityLocked(userData.mCurClient.mAccessibilitySessions,
+                    userData);
+            AccessibilityManagerInternal.get().startInput(
+                    userData.mCurRemoteAccessibilityInputConnection,
+                    userData.mCurEditorInfo, !initial /* restarting */);
         }
     }
 
@@ -2125,10 +1972,13 @@
             @NonNull ImeOnBackInvokedDispatcher imeDispatcher,
             @NonNull InputMethodBindingController bindingController) {
 
+        final int userId = bindingController.getUserId();
+        final var userData = getUserData(userId);
+
         // Compute the final shown display ID with validated cs.selfReportedDisplayId for this
         // session & other conditions.
         ImeTargetWindowState winState = mVisibilityStateComputer.getWindowStateOrNull(
-                mImeBindingState.mFocusedWindow);
+                userData.mImeBindingState.mFocusedWindow);
         if (winState == null) {
             return InputBindResult.NOT_IME_TARGET_WINDOW;
         }
@@ -2139,19 +1989,19 @@
         // Potentially override the selected input method if the new display belongs to a virtual
         // device with a custom IME.
         String selectedMethodId = bindingController.getSelectedMethodId();
-        final String deviceMethodId = computeCurrentDeviceMethodIdLocked(bindingController.mUserId,
-                selectedMethodId);
+        final String deviceMethodId = computeCurrentDeviceMethodIdLocked(
+                bindingController.getUserId(), selectedMethodId);
         if (deviceMethodId == null) {
             mVisibilityStateComputer.getImePolicy().setImeHiddenByDisplayPolicy(true);
         } else if (!Objects.equals(deviceMethodId, selectedMethodId)) {
             setInputMethodLocked(deviceMethodId, NOT_A_SUBTYPE_ID,
-                    bindingController.getDeviceIdToShowIme());
+                    bindingController.getDeviceIdToShowIme(), userId);
             selectedMethodId = deviceMethodId;
         }
 
         if (mVisibilityStateComputer.getImePolicy().isImeHiddenByDisplayPolicy()) {
-            hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
-                    SoftInputShowHideReason.HIDE_DISPLAY_IME_POLICY_HIDE);
+            hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow, 0 /* flags */,
+                    SoftInputShowHideReason.HIDE_DISPLAY_IME_POLICY_HIDE, userId);
             return InputBindResult.NO_IME;
         }
 
@@ -2160,19 +2010,19 @@
             return InputBindResult.NO_IME;
         }
 
-        if (mCurClient != cs) {
-            prepareClientSwitchLocked(cs);
+        if (userData.mCurClient != cs) {
+            prepareClientSwitchLocked(cs, userId);
         }
 
-        final boolean connectionWasActive = mCurInputConnection != null;
+        final boolean connectionWasActive = userData.mCurInputConnection != null;
 
         // Bump up the sequence for this client and attach it.
         bindingController.advanceSequenceNumber();
 
-        mCurClient = cs;
-        mCurInputConnection = inputConnection;
-        mCurRemoteAccessibilityInputConnection = remoteAccessibilityInputConnection;
-        mCurImeDispatcher = imeDispatcher;
+        userData.mCurClient = cs;
+        userData.mCurInputConnection = inputConnection;
+        userData.mCurRemoteAccessibilityInputConnection = remoteAccessibilityInputConnection;
+        userData.mCurImeDispatcher = imeDispatcher;
         // Override the locale hints if the app is running on a virtual device.
         if (mVdmInternal == null) {
             mVdmInternal = LocalServices.getService(VirtualDeviceManagerInternal.class);
@@ -2183,17 +2033,17 @@
                 editorInfo.hintLocales = hintsFromVirtualDevice;
             }
         }
-        mCurEditorInfo = editorInfo;
+        userData.mCurEditorInfo = editorInfo;
 
         // Notify input manager if the connection state changes.
-        final boolean connectionIsActive = mCurInputConnection != null;
+        final boolean connectionIsActive = userData.mCurInputConnection != null;
         if (connectionIsActive != connectionWasActive) {
             mInputManagerInternal.notifyInputMethodConnectionActive(connectionIsActive);
         }
 
         // If configured, we want to avoid starting up the IME if it is not supposed to be showing
         if (shouldPreventImeStartupLocked(selectedMethodId, startInputFlags,
-                unverifiedTargetSdkVersion)) {
+                unverifiedTargetSdkVersion, userId)) {
             if (DEBUG) {
                 Slog.d(TAG, "Avoiding IME startup and unbinding current input method.");
             }
@@ -2208,7 +2058,7 @@
         final String curId = bindingController.getCurId();
         final int displayIdToShowIme = bindingController.getDisplayIdToShowIme();
         if (curId != null && curId.equals(bindingController.getSelectedMethodId())
-                && displayIdToShowIme == getCurTokenDisplayIdLocked()) {
+                && displayIdToShowIme == bindingController.getCurTokenDisplayId()) {
             if (cs.mCurSession != null) {
                 // Fast case: if we are already connected to the input method,
                 // then just return it.
@@ -2222,12 +2072,12 @@
                 // we can always attach to accessibility because AccessibilityManagerService is
                 // always on.
                 attachNewAccessibilityLocked(startInputReason,
-                        (startInputFlags & StartInputFlags.INITIAL_CONNECTION) != 0);
+                        (startInputFlags & StartInputFlags.INITIAL_CONNECTION) != 0, userId);
                 return attachNewInputLocked(startInputReason,
-                        (startInputFlags & StartInputFlags.INITIAL_CONNECTION) != 0);
+                        (startInputFlags & StartInputFlags.INITIAL_CONNECTION) != 0, userId);
             }
 
-            InputBindResult bindResult = tryReuseConnectionLocked(bindingController, cs);
+            InputBindResult bindResult = tryReuseConnectionLocked(bindingController, cs, userId);
             if (bindResult != null) {
                 return bindResult;
             }
@@ -2304,18 +2154,19 @@
     private boolean shouldPreventImeStartupLocked(
             @NonNull String selectedMethodId,
             @StartInputFlags int startInputFlags,
-            int unverifiedTargetSdkVersion) {
+            int unverifiedTargetSdkVersion,
+            @UserIdInt int userId) {
         // Fast-path for the majority of cases
         if (!mPreventImeStartupUnlessTextEditor) {
             return false;
         }
-        if (isShowRequestedForCurrentWindow()) {
+        if (isShowRequestedForCurrentWindow(userId)) {
             return false;
         }
         if (isSoftInputModeStateVisibleAllowed(unverifiedTargetSdkVersion, startInputFlags)) {
             return false;
         }
-        final InputMethodInfo imi = InputMethodSettingsRepository.get(mCurrentUserId)
+        final InputMethodInfo imi = InputMethodSettingsRepository.get(userId)
                 .getMethodMap().get(selectedMethodId);
         if (imi == null) {
             return false;
@@ -2327,10 +2178,10 @@
     }
 
     @GuardedBy("ImfLock.class")
-    private void prepareClientSwitchLocked(ClientState cs) {
+    private void prepareClientSwitchLocked(ClientState cs, @UserIdInt int userId) {
         // If the client is changing, we need to switch over to the new
         // one.
-        unbindCurrentClientLocked(UnbindReason.SWITCH_CLIENT);
+        unbindCurrentClientLocked(UnbindReason.SWITCH_CLIENT, userId);
         // If the screen is on, inform the new client it is active
         if (mIsInteractive) {
             cs.mClient.setActive(true /* active */, false /* fullscreen */);
@@ -2340,13 +2191,14 @@
     @GuardedBy("ImfLock.class")
     @Nullable
     private InputBindResult tryReuseConnectionLocked(
-            @NonNull InputMethodBindingController bindingController, @NonNull ClientState cs) {
+            @NonNull InputMethodBindingController bindingController, @NonNull ClientState cs,
+            @UserIdInt int userId) {
         if (bindingController.hasMainConnection()) {
-            if (getCurMethodLocked() != null) {
+            if (bindingController.getCurMethod() != null) {
                 if (!Flags.useZeroJankProxy()) {
                     // Return to client, and we will get back with it when
                     // we have had a session made for it.
-                    requestClientSessionLocked(cs);
+                    requestClientSessionLocked(cs, userId);
                     requestClientSessionForAccessibilityLocked(cs);
                 }
                 return new InputBindResult(
@@ -2372,7 +2224,7 @@
                             bindingController.getSequenceNumber(), false);
                 } else {
                     EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME,
-                            getSelectedMethodIdLocked(), bindingDuration, 0);
+                            bindingController.getSelectedMethodId(), bindingDuration, 0);
                 }
             }
         }
@@ -2413,12 +2265,15 @@
     }
 
     @GuardedBy("ImfLock.class")
-    void initializeImeLocked(@NonNull IInputMethodInvoker inputMethod, @NonNull IBinder token) {
+    void initializeImeLocked(@NonNull IInputMethodInvoker inputMethod, @NonNull IBinder token,
+            @UserIdInt int userId) {
         if (DEBUG) {
             Slog.v(TAG, "Sending attach of token: " + token + " for display: "
-                    + getCurTokenDisplayIdLocked());
+                    + getInputMethodBindingController(userId).getCurTokenDisplayId());
         }
-        inputMethod.initializeInternal(token, new InputMethodPrivilegedOperationsImpl(this, token),
+        inputMethod.initializeInternal(token,
+                new InputMethodPrivilegedOperationsImpl(this, token, userId),
+                // TODO(b/345519864): Make getInputMethodNavButtonFlagsLocked() multi-user aware
                 getInputMethodNavButtonFlagsLocked());
     }
 
@@ -2449,7 +2304,7 @@
 
     @BinderThread
     void onSessionCreated(IInputMethodInvoker method, IInputMethodSession session,
-            InputChannel channel) {
+            InputChannel channel, @UserIdInt int userId) {
         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.onSessionCreated");
         try {
             synchronized (ImfLock.class) {
@@ -2459,18 +2314,21 @@
                     channel.dispose();
                     return;
                 }
-                IInputMethodInvoker curMethod = getCurMethodLocked();
+                final var bindingController = getInputMethodBindingController(userId);
+                final var userData = getUserData(userId);
+                IInputMethodInvoker curMethod = bindingController.getCurMethod();
                 if (curMethod != null && method != null
                         && curMethod.asBinder() == method.asBinder()) {
-                    if (mCurClient != null) {
-                        clearClientSessionLocked(mCurClient);
-                        mCurClient.mCurSession = new SessionState(
-                                mCurClient, method, session, channel);
+                    if (userData.mCurClient != null) {
+                        clearClientSessionLocked(userData.mCurClient);
+                        userData.mCurClient.mCurSession = new SessionState(
+                                userData.mCurClient, method, session, channel);
                         InputBindResult res = attachNewInputLocked(
-                                StartInputReason.SESSION_CREATED_BY_IME, true);
-                        attachNewAccessibilityLocked(StartInputReason.SESSION_CREATED_BY_IME, true);
+                                StartInputReason.SESSION_CREATED_BY_IME, true, userId);
+                        attachNewAccessibilityLocked(StartInputReason.SESSION_CREATED_BY_IME, true,
+                                userId);
                         if (res.method != null) {
-                            mCurClient.mClient.onBindMethod(res);
+                            userData.mCurClient.mClient.onBindMethod(res);
                         }
                         return;
                     }
@@ -2485,37 +2343,41 @@
     }
 
     @GuardedBy("ImfLock.class")
-    void resetSystemUiLocked() {
+    void resetSystemUiLocked(InputMethodBindingController bindingController) {
         // Set IME window status as invisible when unbinding current method.
-        mImeWindowVis = 0;
-        mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT;
-        updateSystemUiLocked(mImeWindowVis, mBackDisposition);
+        final int imeWindowVis = 0;
+        final int backDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT;
+        bindingController.setImeWindowVis(imeWindowVis);
+        bindingController.setBackDisposition(backDisposition);
+        updateSystemUiLocked(imeWindowVis, backDisposition, bindingController.getUserId());
     }
 
     @GuardedBy("ImfLock.class")
-    void resetCurrentMethodAndClientLocked(@UnbindReason int unbindClientReason) {
-        final var bindingController = getInputMethodBindingController(mCurrentUserId);
+    void resetCurrentMethodAndClientLocked(@UnbindReason int unbindClientReason,
+            @UserIdInt int userId) {
+        final var bindingController = getInputMethodBindingController(userId);
         bindingController.setSelectedMethodId(null);
 
         // Callback before clean-up binding states.
         // TODO(b/338461930): Check if this is still necessary or not.
-        onUnbindCurrentMethodByReset();
+        onUnbindCurrentMethodByReset(userId);
         bindingController.unbindCurrentMethod();
-        unbindCurrentClientLocked(unbindClientReason);
+        unbindCurrentClientLocked(unbindClientReason, userId);
     }
 
     @GuardedBy("ImfLock.class")
-    void reRequestCurrentClientSessionLocked() {
-        if (mCurClient != null) {
-            clearClientSessionLocked(mCurClient);
-            clearClientSessionForAccessibilityLocked(mCurClient);
-            requestClientSessionLocked(mCurClient);
-            requestClientSessionForAccessibilityLocked(mCurClient);
+    void reRequestCurrentClientSessionLocked(@UserIdInt int userId) {
+        final var userData = getUserData(userId);
+        if (userData.mCurClient != null) {
+            clearClientSessionLocked(userData.mCurClient);
+            clearClientSessionForAccessibilityLocked(userData.mCurClient);
+            requestClientSessionLocked(userData.mCurClient, userId);
+            requestClientSessionForAccessibilityLocked(userData.mCurClient);
         }
     }
 
     @GuardedBy("ImfLock.class")
-    void requestClientSessionLocked(ClientState cs) {
+    void requestClientSessionLocked(ClientState cs, @UserIdInt int userId) {
         if (!cs.mSessionRequested) {
             if (DEBUG) Slog.v(TAG, "Creating new session for client " + cs);
             final InputChannel serverChannel;
@@ -2528,14 +2390,15 @@
 
             cs.mSessionRequested = true;
 
-            final IInputMethodInvoker curMethod = getCurMethodLocked();
+            final var bindingController = getInputMethodBindingController(userId);
+            final IInputMethodInvoker curMethod = bindingController.getCurMethod();
             final IInputMethodSessionCallback.Stub callback =
                     new IInputMethodSessionCallback.Stub() {
                         @Override
                         public void sessionCreated(IInputMethodSession session) {
                             final long ident = Binder.clearCallingIdentity();
                             try {
-                                onSessionCreated(curMethod, session, serverChannel);
+                                onSessionCreated(curMethod, session, serverChannel, userId);
                             } finally {
                                 Binder.restoreCallingIdentity(ident);
                             }
@@ -2600,7 +2463,12 @@
                     sessionState.mSession.finishSession();
                 } catch (RemoteException e) {
                     Slog.w(TAG, "Session failed to close due to remote exception", e);
-                    updateSystemUiLocked(0 /* vis */, mBackDisposition);
+                    // TODO(b/350386877): Propagate userId from the caller or infer it from
+                    //  sessionState
+                    final int userId = mCurrentUserId;
+                    final var bindingController = getInputMethodBindingController(userId);
+                    updateSystemUiLocked(0 /* vis */, bindingController.getBackDisposition(),
+                            userId);
                 }
                 sessionState.mSession = null;
             }
@@ -2626,34 +2494,43 @@
     }
 
     @GuardedBy("ImfLock.class")
-    void clearClientSessionsLocked() {
-        if (getCurMethodLocked() != null) {
+    void clearClientSessionsLocked(@NonNull InputMethodBindingController bindingController) {
+        final int userId = bindingController.getUserId();
+        final var userData = getUserData(userId);
+        if (bindingController.getCurMethod() != null) {
             // TODO(b/324907325): Remove the suppress warnings once b/324907325 is fixed.
             @SuppressWarnings("GuardedBy") Consumer<ClientState> clearClientSession = c -> {
-                clearClientSessionLocked(c);
-                clearClientSessionForAccessibilityLocked(c);
+                // TODO(b/305849394): Figure out what we should do for single user IME mode.
+                final boolean shouldClearClientSession =
+                        !mConcurrentMultiUserModeEnabled
+                                || UserHandle.getUserId(c.mUid) == userId;
+                if (shouldClearClientSession) {
+                    clearClientSessionLocked(c);
+                    clearClientSessionForAccessibilityLocked(c);
+                }
             };
             mClientController.forAllClients(clearClientSession);
 
-            finishSessionLocked(mEnabledSession);
-            for (int i = 0; i < mEnabledAccessibilitySessions.size(); i++) {
-                finishSessionForAccessibilityLocked(mEnabledAccessibilitySessions.valueAt(i));
+            finishSessionLocked(userData.mEnabledSession);
+            for (int i = 0; i < userData.mEnabledAccessibilitySessions.size(); i++) {
+                finishSessionForAccessibilityLocked(
+                        userData.mEnabledAccessibilitySessions.valueAt(i));
             }
-            mEnabledSession = null;
-            mEnabledAccessibilitySessions.clear();
+            userData.mEnabledSession = null;
+            userData.mEnabledAccessibilitySessions.clear();
             scheduleNotifyImeUidToAudioService(Process.INVALID_UID);
         }
         hideStatusBarIconLocked();
-        mInFullscreenMode = false;
+        getUserData(userId).mInFullscreenMode = false;
         mWindowManagerInternal.setDismissImeOnBackKeyPressed(false);
         scheduleResetStylusHandwriting();
     }
 
     @BinderThread
     private void updateStatusIcon(@NonNull IBinder token, String packageName,
-            @DrawableRes int iconId) {
+            @DrawableRes int iconId, @UserIdInt int userId) {
         synchronized (ImfLock.class) {
-            if (!calledWithValidTokenLocked(token)) {
+            if (!calledWithValidTokenLocked(token, userId)) {
                 return;
             }
             final long ident = Binder.clearCallingIdentity();
@@ -2664,7 +2541,7 @@
                 } else if (packageName != null) {
                     if (DEBUG) Slog.d(TAG, "show a small icon for the input method");
                     final PackageManager userAwarePackageManager =
-                            getPackageManagerForUser(mContext, mCurrentUserId);
+                            getPackageManagerForUser(mContext, userId);
                     ApplicationInfo applicationInfo = null;
                     try {
                         applicationInfo = userAwarePackageManager.getApplicationInfo(packageName,
@@ -2697,6 +2574,9 @@
     @GuardedBy("ImfLock.class")
     @InputMethodNavButtonFlags
     private int getInputMethodNavButtonFlagsLocked() {
+        // TODO(b/345519864): Make mImeDrawsImeNavBarRes multi-user aware.
+        final int userId = mCurrentUserId;
+        final var bindingController = getInputMethodBindingController(userId);
         if (mImeDrawsImeNavBarResLazyInitFuture != null) {
             // TODO(b/225366708): Avoid Future.get(), which is internally used here.
             ConcurrentUtils.waitForFutureNoInterrupt(mImeDrawsImeNavBarResLazyInitFuture,
@@ -2704,15 +2584,14 @@
         }
         // Whether the current display has a navigation bar. When this is false (e.g. emulator),
         // the IME should not draw the IME navigation bar.
-        final int tokenDisplayId = getCurTokenDisplayIdLocked();
+        final int tokenDisplayId = bindingController.getCurTokenDisplayId();
         final boolean hasNavigationBar = mWindowManagerInternal
                 .hasNavigationBar(tokenDisplayId != INVALID_DISPLAY
                         ? tokenDisplayId : DEFAULT_DISPLAY);
         final boolean canImeDrawsImeNavBar =
                 mImeDrawsImeNavBarRes != null && mImeDrawsImeNavBarRes.get() && hasNavigationBar;
         final boolean shouldShowImeSwitcherWhenImeIsShown = shouldShowImeSwitcherLocked(
-                InputMethodService.IME_ACTIVE | InputMethodService.IME_VISIBLE,
-                mCurrentUserId);
+                InputMethodService.IME_ACTIVE | InputMethodService.IME_VISIBLE, userId);
         return (canImeDrawsImeNavBar ? InputMethodNavButtonFlags.IME_DRAWS_IME_NAV_BAR : 0)
                 | (shouldShowImeSwitcherWhenImeIsShown
                 ? InputMethodNavButtonFlags.SHOW_IME_SWITCHER_WHEN_IME_IS_SHOWN : 0);
@@ -2795,24 +2674,26 @@
 
     @BinderThread
     @SuppressWarnings("deprecation")
-    private void setImeWindowStatus(@NonNull IBinder token, int vis, int backDisposition) {
+    private void setImeWindowStatus(@NonNull IBinder token, int vis, int backDisposition,
+            @UserIdInt int userId) {
         final int topFocusedDisplayId = mWindowManagerInternal.getTopFocusedDisplayId();
 
         synchronized (ImfLock.class) {
-            if (!calledWithValidTokenLocked(token)) {
+            if (!calledWithValidTokenLocked(token, userId)) {
                 return;
             }
+            final var bindingController = getInputMethodBindingController(userId);
             // Skip update IME status when current token display is not same as focused display.
             // Note that we still need to update IME status when focusing external display
             // that does not support system decoration and fallback to show IME on default
             // display since it is intentional behavior.
-            final int tokenDisplayId = getCurTokenDisplayIdLocked();
+            final int tokenDisplayId = bindingController.getCurTokenDisplayId();
             if (tokenDisplayId != topFocusedDisplayId && tokenDisplayId != FALLBACK_DISPLAY_ID) {
                 return;
             }
-            mImeWindowVis = vis;
-            mBackDisposition = backDisposition;
-            updateSystemUiLocked(vis, backDisposition);
+            bindingController.setImeWindowVis(vis);
+            bindingController.setBackDisposition(backDisposition);
+            updateSystemUiLocked(vis, backDisposition, userId);
         }
 
         final boolean dismissImeOnBackKeyPressed;
@@ -2832,9 +2713,10 @@
     }
 
     @BinderThread
-    private void reportStartInput(@NonNull IBinder token, IBinder startInputToken) {
+    private void reportStartInput(@NonNull IBinder token, IBinder startInputToken,
+            @UserIdInt int userId) {
         synchronized (ImfLock.class) {
-            if (!calledWithValidTokenLocked(token)) {
+            if (!calledWithValidTokenLocked(token, userId)) {
                 return;
             }
             final IBinder targetWindow = mImeTargetWindowMap.get(startInputToken);
@@ -2847,28 +2729,29 @@
 
     private void updateImeWindowStatus(boolean disableImeIcon) {
         synchronized (ImfLock.class) {
+            // TODO(b/350386877): Propagate userId from the caller.
+            final int userId = mCurrentUserId;
             if (disableImeIcon) {
-                updateSystemUiLocked(0, mBackDisposition);
+                final var bindingController = getInputMethodBindingController(userId);
+                updateSystemUiLocked(0, bindingController.getBackDisposition(), userId);
             } else {
-                updateSystemUiLocked();
+                updateSystemUiLocked(userId);
             }
         }
     }
 
-    @GuardedBy("ImfLock.class")
-    void updateSystemUiLocked() {
-        updateSystemUiLocked(mImeWindowVis, mBackDisposition);
-    }
-
     // Caution! This method is called in this class. Handle multi-user carefully
     @GuardedBy("ImfLock.class")
-    private void updateSystemUiLocked(int vis, int backDisposition) {
-        updateSystemUiLocked(vis, backDisposition, mCurrentUserId);
+    void updateSystemUiLocked(@UserIdInt int userId) {
+        final var bindingController = getInputMethodBindingController(userId);
+        updateSystemUiLocked(bindingController.getImeWindowVis(),
+                bindingController.getBackDisposition(), userId);
     }
 
     @GuardedBy("ImfLock.class")
     private void updateSystemUiLocked(int vis, int backDisposition, @UserIdInt int userId) {
         final var bindingController = getInputMethodBindingController(userId);
+        final var userData = getUserData(userId);
         final var curToken = bindingController.getCurToken();
         if (curToken == null) {
             return;
@@ -2880,8 +2763,8 @@
                     + " inv: " + (vis & InputMethodService.IME_INVISIBLE)
                     + " displayId: " + curTokenDisplayId);
         }
-        final IBinder focusedWindowToken = mImeBindingState != null
-                ? mImeBindingState.mFocusedWindow : null;
+        final IBinder focusedWindowToken = userData.mImeBindingState != null
+                ? userData.mImeBindingState.mFocusedWindow : null;
         final Boolean windowPerceptible = focusedWindowToken != null
                 ? mFocusedWindowPerceptible.get(focusedWindowToken) : null;
 
@@ -2916,35 +2799,31 @@
     }
 
     @GuardedBy("ImfLock.class")
-    void updateFromSettingsLocked(boolean enabledMayChange) {
-        updateInputMethodsFromSettingsLocked(enabledMayChange);
+    void updateFromSettingsLocked(boolean enabledMayChange, @UserIdInt int userId) {
+        updateInputMethodsFromSettingsLocked(enabledMayChange, userId);
         mMenuController.updateKeyboardFromSettingsLocked();
     }
 
     /**
-     * This is an experimental implementation used when and only when
-     * {@link #mExperimentalConcurrentMultiUserModeEnabled}.
+     * This initialization logic is used when and only when {@link #mConcurrentMultiUserModeEnabled}
+     * is set to {@code true}.
      *
-     * <p>Never assume what this method is doing is officially supported. For the canonical and
-     * desired behaviors always refer to single-user code paths such as
-     * {@link #updateInputMethodsFromSettingsLocked(boolean)}.</p>
+     * <p>There remain several yet-to-be-implemented features. For the canonical and desired
+     * behaviors always refer to single-user code paths such as
+     * {@link #updateInputMethodsFromSettingsLocked(boolean, int)}.</p>
      *
      * <p>Here are examples of missing features.</p>
      * <ul>
-     *     <li>Subtypes are not supported at all!</li>
      *     <li>Profiles are not supported.</li>
      *     <li>
      *         {@link PackageManager#COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED} is not updated.
      *     </li>
      *     <li>{@link InputMethodBindingController#getDeviceIdToShowIme()} is ignored.</li>
-     *     <li>{@link #mSwitchingController} is ignored.</li>
-     *     <li>{@link #mHardwareKeyboardShortcutController} is ignored.</li>
-     *     <li>{@link #mPreventImeStartupUnlessTextEditor} is ignored.</li>
      *     <li>and so on.</li>
      * </ul>
      */
     @GuardedBy("ImfLock.class")
-    void experimentalInitializeVisibleBackgroundUserLocked(@UserIdInt int userId) {
+    void initializeVisibleBackgroundUserLocked(@UserIdInt int userId) {
         final var settings = InputMethodSettingsRepository.get(userId);
 
         // Until we figure out what makes most sense, we enable all the pre-installed IMEs in
@@ -2952,7 +2831,7 @@
         String enabledImeIdsStr = settings.getEnabledInputMethodsStr();
         for (var imi : settings.getMethodList()) {
             if (!imi.isSystem()) {
-                return;
+                continue;
             }
             enabledImeIdsStr = InputMethodUtils.concatEnabledImeIds(enabledImeIdsStr, imi.getId());
         }
@@ -2965,17 +2844,22 @@
         if (TextUtils.isEmpty(id)) {
             final InputMethodInfo imi = InputMethodInfoUtils.getMostApplicableDefaultIME(
                     settings.getEnabledInputMethodList());
-            if (imi == null) {
-                return;
+            if (imi != null) {
+                id = imi.getId();
+                settings.putSelectedInputMethod(id);
             }
-            id = imi.getId();
-            settings.putSelectedInputMethod(id);
         }
+        final var bindingController = getInputMethodBindingController(userId);
+        bindingController.setSelectedMethodId(id);
+
+        // Also re-initialize controllers.
+        final var userData = getUserData(userId);
+        userData.mSwitchingController.resetCircularListLocked(mContext, settings);
+        userData.mHardwareKeyboardShortcutController.update(settings);
     }
 
     @GuardedBy("ImfLock.class")
-    void updateInputMethodsFromSettingsLocked(boolean enabledMayChange) {
-        final int userId = mCurrentUserId;
+    void updateInputMethodsFromSettingsLocked(boolean enabledMayChange, @UserIdInt int userId) {
         final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
         if (enabledMayChange) {
             final PackageManager userAwarePackageManager = getPackageManagerForUser(mContext,
@@ -3006,7 +2890,7 @@
             }
         }
 
-        final var bindingController = getInputMethodBindingController(mCurrentUserId);
+        final var bindingController = getInputMethodBindingController(userId);
         if (bindingController.getDeviceIdToShowIme() == DEVICE_ID_DEFAULT) {
             String ime = SecureSettingsWrapper.getString(
                     Settings.Secure.DEFAULT_INPUT_METHOD, null, userId);
@@ -3031,35 +2915,24 @@
         // enabled.
         String id = settings.getSelectedInputMethod();
         // There is no input method selected, try to choose new applicable input method.
-        if (TextUtils.isEmpty(id) && chooseNewDefaultIMELocked()) {
+        if (TextUtils.isEmpty(id) && chooseNewDefaultIMELocked(userId)) {
             id = settings.getSelectedInputMethod();
         }
         if (!TextUtils.isEmpty(id)) {
             try {
-                setInputMethodLocked(id, settings.getSelectedInputMethodSubtypeId(id));
+                setInputMethodLocked(id, settings.getSelectedInputMethodSubtypeId(id), userId);
             } catch (IllegalArgumentException e) {
                 Slog.w(TAG, "Unknown input method from prefs: " + id, e);
-                resetCurrentMethodAndClientLocked(UnbindReason.SWITCH_IME_FAILED);
+                resetCurrentMethodAndClientLocked(UnbindReason.SWITCH_IME_FAILED, userId);
             }
         } else {
             // There is no longer an input method set, so stop any current one.
-            resetCurrentMethodAndClientLocked(UnbindReason.NO_IME);
+            resetCurrentMethodAndClientLocked(UnbindReason.NO_IME, userId);
         }
 
-        // TODO: Instantiate mSwitchingController for each user.
-        if (userId == mSwitchingController.getUserId()) {
-            mSwitchingController.resetCircularListLocked(settings.getMethodMap());
-        } else {
-            mSwitchingController = InputMethodSubtypeSwitchingController.createInstanceLocked(
-                    mContext, settings.getMethodMap(), userId);
-        }
-        // TODO: Instantiate mHardwareKeyboardShortcutController for each user.
-        if (userId == mHardwareKeyboardShortcutController.getUserId()) {
-            mHardwareKeyboardShortcutController.reset(settings.getMethodMap());
-        } else {
-            mHardwareKeyboardShortcutController = new HardwareKeyboardShortcutController(
-                    settings.getMethodMap(), userId);
-        }
+        final var userData = getUserData(userId);
+        userData.mSwitchingController.resetCircularListLocked(mContext, settings);
+        userData.mHardwareKeyboardShortcutController.update(settings);
         sendOnNavButtonFlagsChangedLocked();
     }
 
@@ -3076,13 +2949,12 @@
     }
 
     @GuardedBy("ImfLock.class")
-    void setInputMethodLocked(String id, int subtypeId) {
-        setInputMethodLocked(id, subtypeId, DEVICE_ID_DEFAULT);
+    void setInputMethodLocked(String id, int subtypeId, @UserIdInt int userId) {
+        setInputMethodLocked(id, subtypeId, DEVICE_ID_DEFAULT, userId);
     }
 
     @GuardedBy("ImfLock.class")
-    void setInputMethodLocked(String id, int subtypeId, int deviceId) {
-        final int userId = mCurrentUserId;
+    void setInputMethodLocked(String id, int subtypeId, int deviceId, @UserIdInt int userId) {
         final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
         InputMethodInfo info = settings.getMethodMap().get(id);
         if (info == null) {
@@ -3106,7 +2978,7 @@
                 // getCurrentInputMethodSubtype.
                 subtypeId = NOT_A_SUBTYPE_ID;
                 // TODO(b/347083680): The method below has questionable behaviors.
-                newSubtype = getCurrentInputMethodSubtypeLocked();
+                newSubtype = bindingController.getCurrentInputMethodSubtype();
                 if (newSubtype != null) {
                     for (int i = 0; i < subtypeCount; ++i) {
                         if (Objects.equals(newSubtype, info.getSubtypeAt(i))) {
@@ -3117,10 +2989,11 @@
                 }
             }
             if (!Objects.equals(newSubtype, oldSubtype)) {
-                setSelectedInputMethodAndSubtypeLocked(info, subtypeId, true);
-                IInputMethodInvoker curMethod = getCurMethodLocked();
+                setSelectedInputMethodAndSubtypeLocked(info, subtypeId, true, userId);
+                IInputMethodInvoker curMethod = bindingController.getCurMethod();
                 if (curMethod != null) {
-                    updateSystemUiLocked(mImeWindowVis, mBackDisposition);
+                    updateSystemUiLocked(bindingController.getImeWindowVis(),
+                            bindingController.getBackDisposition(), userId);
                     curMethod.changeInputMethodSubtype(newSubtype);
                 }
             }
@@ -3137,7 +3010,7 @@
             settings.putSelectedDefaultDeviceInputMethod(id);
             return;
         }
-        IInputMethodInvoker curMethod = getCurMethodLocked();
+        IInputMethodInvoker curMethod = bindingController.getCurMethod();
         if (curMethod != null) {
             curMethod.removeStylusHandwritingWindow();
         }
@@ -3145,7 +3018,7 @@
         try {
             // Set a subtype to this input method.
             // subtypeId the name of a subtype which will be set.
-            setSelectedInputMethodAndSubtypeLocked(info, subtypeId, false);
+            setSelectedInputMethodAndSubtypeLocked(info, subtypeId, false, userId);
             // mCurMethodId should be updated after setSelectedInputMethodAndSubtypeLocked()
             // because mCurMethodId is stored as a history in
             // setSelectedInputMethodAndSubtypeLocked().
@@ -3157,7 +3030,7 @@
                 intent.putExtra("input_method_id", id);
                 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
             }
-            unbindCurrentClientLocked(UnbindReason.SWITCH_IME);
+            unbindCurrentClientLocked(UnbindReason.SWITCH_IME, userId);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
@@ -3169,24 +3042,30 @@
             int lastClickToolType, ResultReceiver resultReceiver,
             @SoftInputShowHideReason int reason) {
         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.showSoftInput");
-        int uid = Binder.getCallingUid();
+        final int uid = Binder.getCallingUid();
+        final int callingUserId = UserHandle.getUserId(uid);
         ImeTracing.getInstance().triggerManagerServiceDump(
                 "InputMethodManagerService#showSoftInput", mDumper);
         synchronized (ImfLock.class) {
-            if (!canInteractWithImeLocked(uid, client, "showSoftInput", statsToken)) {
+            final int userId = resolveImeUserIdLocked(callingUserId);
+            if (!canInteractWithImeLocked(uid, client, "showSoftInput", statsToken,
+                    userId)) {
                 ImeTracker.forLogging().onFailed(
                         statsToken, ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
                 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
                 return false;
             }
             final long ident = Binder.clearCallingIdentity();
+            final var userData = getUserData(userId);
             try {
                 if (DEBUG) Slog.v(TAG, "Client requesting input be shown");
                 if (Flags.refactorInsetsController()) {
                     boolean wasVisible = isInputShownLocked();
-                    if (mImeBindingState != null && mImeBindingState.mFocusedWindowClient != null
-                            && mImeBindingState.mFocusedWindowClient.mClient != null) {
-                        mImeBindingState.mFocusedWindowClient.mClient.setImeVisibility(true);
+                    if (userData.mImeBindingState != null
+                            && userData.mImeBindingState.mFocusedWindowClient != null
+                            && userData.mImeBindingState.mFocusedWindowClient.mClient != null) {
+                        userData.mImeBindingState.mFocusedWindowClient.mClient
+                                .setImeVisibility(true);
                         if (resultReceiver != null) {
                             resultReceiver.send(
                                     wasVisible ? InputMethodManager.RESULT_UNCHANGED_SHOWN
@@ -3197,7 +3076,7 @@
                     return false;
                 } else {
                     return showCurrentInputLocked(windowToken, statsToken, flags, lastClickToolType,
-                            resultReceiver, reason);
+                            resultReceiver, reason, userId);
                 }
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -3211,12 +3090,14 @@
         ImeTracing.getInstance().triggerManagerServiceDump(
                 "InputMethodManagerService#showSoftInput", mDumper);
         synchronized (ImfLock.class) {
+            // TODO(b/305849394): Infer userId from windowToken
+            final int userId = mCurrentUserId;
             final long ident = Binder.clearCallingIdentity();
             try {
                 if (DEBUG) Slog.v(TAG, "Client requesting input be shown");
                 return showCurrentInputLocked(windowToken, null /* statsToken */, 0 /* flags */,
                         0 /* lastClickTooType */, null /* resultReceiver */,
-                        SoftInputShowHideReason.SHOW_SOFT_INPUT);
+                        SoftInputShowHideReason.SHOW_SOFT_INPUT, userId);
             } finally {
                 Binder.restoreCallingIdentity(ident);
                 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
@@ -3229,11 +3110,14 @@
         ImeTracing.getInstance().triggerManagerServiceDump(
                 "InputMethodManagerService#hideSoftInput", mDumper);
         synchronized (ImfLock.class) {
+            // TODO(b/305849394): Infer userId from windowToken
+            final int userId = mCurrentUserId;
             final long ident = Binder.clearCallingIdentity();
             try {
                 if (DEBUG) Slog.v(TAG, "Client requesting input be hidden");
                 return hideCurrentInputLocked(windowToken, null /* statsToken */, 0 /* flags */,
-                        null /* resultReceiver */, SoftInputShowHideReason.HIDE_SOFT_INPUT);
+                        null /* resultReceiver */, SoftInputShowHideReason.HIDE_SOFT_INPUT,
+                        userId);
             } finally {
                 Binder.restoreCallingIdentity(ident);
                 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
@@ -3322,13 +3206,15 @@
         try {
             ImeTracing.getInstance().triggerManagerServiceDump(
                     "InputMethodManagerService#startStylusHandwriting", mDumper);
-            int uid = Binder.getCallingUid();
+            final int uid = Binder.getCallingUid();
+            final int callingUserId = UserHandle.getUserId(uid);
             synchronized (ImfLock.class) {
+                final int userId = resolveImeUserIdLocked(callingUserId);
                 if (!acceptingDelegation) {
                     mHwController.clearPendingHandwritingDelegation();
                 }
                 if (!canInteractWithImeLocked(uid, client, "startStylusHandwriting",
-                        null /* statsToken */)) {
+                        null /* statsToken */, userId)) {
                     return false;
                 }
                 if (!hasSupportedStylusLocked()) {
@@ -3338,7 +3224,7 @@
                 }
                 final long ident = Binder.clearCallingIdentity();
                 try {
-                    final var bindingController = getInputMethodBindingController(mCurrentUserId);
+                    final var bindingController = getInputMethodBindingController(userId);
                     if (!bindingController.supportsStylusHandwriting()) {
                         Slog.w(TAG,
                                 "Stylus HW unsupported by IME. Ignoring startStylusHandwriting()");
@@ -3363,7 +3249,7 @@
                         return false;
                     }
                     if (DEBUG) Slog.v(TAG, "Client requesting Stylus Handwriting to be started");
-                    final IInputMethodInvoker curMethod = getCurMethodLocked();
+                    final IInputMethodInvoker curMethod = bindingController.getCurMethod();
                     if (curMethod != null) {
                         curMethod.canStartStylusHandwriting(requestId.getAsInt(),
                                 connectionlessCallback, cursorAnchorInfo,
@@ -3435,8 +3321,9 @@
             return false;
         }
         synchronized (ImfLock.class) {
+            final var bindingController = getInputMethodBindingController(userId);
             if (mHwController.isDelegationUsingConnectionlessFlow()) {
-                final IInputMethodInvoker curMethod = getCurMethodLocked();
+                final IInputMethodInvoker curMethod = bindingController.getCurMethod();
                 if (curMethod == null) {
                     return false;
                 }
@@ -3486,29 +3373,32 @@
             Objects.requireNonNull(windowToken, "windowToken must not be null");
             synchronized (ImfLock.class) {
                 Boolean windowPerceptible = mFocusedWindowPerceptible.get(windowToken);
-                if (mImeBindingState.mFocusedWindow != windowToken
+                final int userId = mCurrentUserId;
+                final var userData = getUserData(userId);
+                if (userData.mImeBindingState.mFocusedWindow != windowToken
                         || (windowPerceptible != null && windowPerceptible == perceptible)) {
                     return;
                 }
                 mFocusedWindowPerceptible.put(windowToken, windowPerceptible);
-                updateSystemUiLocked();
+                updateSystemUiLocked(mCurrentUserId);
             }
         });
     }
 
     @GuardedBy("ImfLock.class")
     private boolean showCurrentInputLocked(IBinder windowToken,
-            @InputMethodManager.ShowFlags int flags, @SoftInputShowHideReason int reason) {
-        final var statsToken = createStatsTokenForFocusedClient(true /* show */, reason);
+            @InputMethodManager.ShowFlags int flags, @SoftInputShowHideReason int reason,
+            @UserIdInt int userId) {
+        final var statsToken = createStatsTokenForFocusedClient(true /* show */, reason, userId);
         return showCurrentInputLocked(windowToken, statsToken, flags,
-                MotionEvent.TOOL_TYPE_UNKNOWN, null /* resultReceiver */, reason);
+                MotionEvent.TOOL_TYPE_UNKNOWN, null /* resultReceiver */, reason, userId);
     }
 
     @GuardedBy("ImfLock.class")
     boolean showCurrentInputLocked(IBinder windowToken,
             @NonNull ImeTracker.Token statsToken, @InputMethodManager.ShowFlags int flags,
             @MotionEvent.ToolType int lastClickToolType, @Nullable ResultReceiver resultReceiver,
-            @SoftInputShowHideReason int reason) {
+            @SoftInputShowHideReason int reason, @UserIdInt int userId) {
         if (!mVisibilityStateComputer.onImeShowFlags(statsToken, flags)) {
             return false;
         }
@@ -3522,20 +3412,23 @@
         mVisibilityStateComputer.requestImeVisibility(windowToken, true);
 
         // Ensure binding the connection when IME is going to show.
-        final var bindingController = getInputMethodBindingController(mCurrentUserId);
+        final var bindingController = getInputMethodBindingController(userId);
+        final var userData = getUserData(userId);
         bindingController.setCurrentMethodVisible();
-        final IInputMethodInvoker curMethod = getCurMethodLocked();
-        ImeTracker.forLogging().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
+        final IInputMethodInvoker curMethod = bindingController.getCurMethod();
+        ImeTracker.forLogging().onCancelled(userData.mCurStatsToken,
+                ImeTracker.PHASE_SERVER_WAIT_IME);
         final boolean readyToDispatchToIme;
         if (Flags.deferShowSoftInputUntilSessionCreation()) {
             readyToDispatchToIme =
-                    curMethod != null && mCurClient != null && mCurClient.mCurSession != null;
+                    curMethod != null && userData.mCurClient != null
+                            && userData.mCurClient.mCurSession != null;
         } else {
             readyToDispatchToIme = curMethod != null;
         }
         if (readyToDispatchToIme) {
             ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_HAS_IME);
-            mCurStatsToken = null;
+            userData.mCurStatsToken = null;
 
             if (Flags.useHandwritingListenerForTooltype()) {
                 maybeReportToolType();
@@ -3544,12 +3437,12 @@
             }
             mVisibilityApplier.performShowIme(windowToken, statsToken,
                     mVisibilityStateComputer.getShowFlagsForInputMethodServiceOnly(),
-                    resultReceiver, reason);
+                    resultReceiver, reason, userId);
             mVisibilityStateComputer.setInputShown(true);
             return true;
         } else {
             ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
-            mCurStatsToken = statsToken;
+            userData.mCurStatsToken = statsToken;
         }
         return false;
     }
@@ -3581,11 +3474,13 @@
     public boolean hideSoftInput(IInputMethodClient client, IBinder windowToken,
             @NonNull ImeTracker.Token statsToken, @InputMethodManager.HideFlags int flags,
             ResultReceiver resultReceiver, @SoftInputShowHideReason int reason) {
-        int uid = Binder.getCallingUid();
+        final int uid = Binder.getCallingUid();
+        final int callingUserId = UserHandle.getUserId(uid);
         ImeTracing.getInstance().triggerManagerServiceDump(
                 "InputMethodManagerService#hideSoftInput", mDumper);
         synchronized (ImfLock.class) {
-            if (!canInteractWithImeLocked(uid, client, "hideSoftInput", statsToken)) {
+            final int userId = resolveImeUserIdLocked(callingUserId);
+            if (!canInteractWithImeLocked(uid, client, "hideSoftInput", statsToken, userId)) {
                 if (isInputShownLocked()) {
                     ImeTracker.forLogging().onFailed(
                             statsToken, ImeTracker.PHASE_SERVER_CLIENT_FOCUSED);
@@ -3596,15 +3491,18 @@
                 return false;
             }
             final long ident = Binder.clearCallingIdentity();
+            final var userData = getUserData(userId);
             try {
                 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.hideSoftInput");
                 if (DEBUG) Slog.v(TAG, "Client requesting input be hidden");
                 if (Flags.refactorInsetsController()) {
-                    if (mImeBindingState != null && mImeBindingState.mFocusedWindowClient != null
-                            && mImeBindingState.mFocusedWindowClient.mClient != null) {
+                    if (userData.mImeBindingState != null
+                            && userData.mImeBindingState.mFocusedWindowClient != null
+                            && userData.mImeBindingState.mFocusedWindowClient.mClient != null) {
                         boolean wasVisible = isInputShownLocked();
                         // TODO add windowToken to interface
-                        mImeBindingState.mFocusedWindowClient.mClient.setImeVisibility(false);
+                        userData.mImeBindingState.mFocusedWindowClient.mClient
+                                .setImeVisibility(false);
                         if (resultReceiver != null) {
                             resultReceiver.send(wasVisible ? InputMethodManager.RESULT_HIDDEN
                                     : InputMethodManager.RESULT_UNCHANGED_HIDDEN, null);
@@ -3614,7 +3512,7 @@
                     return false;
                 } else {
                     return InputMethodManagerService.this.hideCurrentInputLocked(windowToken,
-                            statsToken, flags, resultReceiver, reason);
+                            statsToken, flags, resultReceiver, reason, userId);
                 }
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -3626,57 +3524,65 @@
     @Override
     @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.TEST_INPUT_METHOD)
     public void hideSoftInputFromServerForTest() {
+        final int callingUserId = UserHandle.getCallingUserId();
         synchronized (ImfLock.class) {
-            hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
-                    SoftInputShowHideReason.HIDE_SOFT_INPUT);
+            final int userId = resolveImeUserIdLocked(callingUserId);
+            final var userData = getUserData(userId);
+            hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow, 0 /* flags */,
+                    SoftInputShowHideReason.HIDE_SOFT_INPUT, userId);
         }
     }
 
     @GuardedBy("ImfLock.class")
     private boolean hideCurrentInputLocked(IBinder windowToken,
-            @InputMethodManager.HideFlags int flags, @SoftInputShowHideReason int reason) {
-        final var statsToken = createStatsTokenForFocusedClient(false /* show */, reason);
+            @InputMethodManager.HideFlags int flags, @SoftInputShowHideReason int reason,
+            @UserIdInt int userId) {
+        final var statsToken = createStatsTokenForFocusedClient(false /* show */, reason, userId);
         return hideCurrentInputLocked(windowToken, statsToken, flags, null /* resultReceiver */,
-                reason);
+                reason, userId);
     }
 
     @GuardedBy("ImfLock.class")
     boolean hideCurrentInputLocked(IBinder windowToken, @NonNull ImeTracker.Token statsToken,
             @InputMethodManager.HideFlags int flags, @Nullable ResultReceiver resultReceiver,
-            @SoftInputShowHideReason int reason) {
+            @SoftInputShowHideReason int reason, @UserIdInt int userId) {
+        final var bindingController = getInputMethodBindingController(userId);
         if (!mVisibilityStateComputer.canHideIme(statsToken, flags)) {
             return false;
         }
 
         // There is a chance that IMM#hideSoftInput() is called in a transient state where
-        // IMMS#InputShown is already updated to be true whereas IMMS#mImeWindowVis is still waiting
-        // to be updated with the new value sent from IME process.  Even in such a transient state
-        // historically we have accepted an incoming call of IMM#hideSoftInput() from the
+        // IMMS#InputShown is already updated to be true whereas the user's ImeWindowVis is still
+        // waiting to be updated with the new value sent from IME process.  Even in such a transient
+        // state historically we have accepted an incoming call of IMM#hideSoftInput() from the
         // application process as a valid request, and have even promised such a behavior with CTS
         // since Android Eclair.  That's why we need to accept IMM#hideSoftInput() even when only
         // IMMS#InputShown indicates that the software keyboard is shown.
         // TODO(b/246309664): Clean up IMMS#mImeWindowVis
-        IInputMethodInvoker curMethod = getCurMethodLocked();
+        final var userData = getUserData(userId);
+        IInputMethodInvoker curMethod = bindingController.getCurMethod();
         final boolean shouldHideSoftInput = curMethod != null
-                && (isInputShownLocked() || (mImeWindowVis & InputMethodService.IME_ACTIVE) != 0);
+                && (isInputShownLocked()
+                || (bindingController.getImeWindowVis() & InputMethodService.IME_ACTIVE) != 0);
 
         mVisibilityStateComputer.requestImeVisibility(windowToken, false);
         if (shouldHideSoftInput) {
             // The IME will report its visible state again after the following message finally
             // delivered to the IME process as an IPC.  Hence the inconsistency between
-            // IMMS#mInputShown and IMMS#mImeWindowVis should be resolved spontaneously in
+            // IMMS#mInputShown and the user's ImeWindowVis should be resolved spontaneously in
             // the final state.
             ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE);
-            mVisibilityApplier.performHideIme(windowToken, statsToken, resultReceiver, reason);
+            mVisibilityApplier.performHideIme(windowToken, statsToken, resultReceiver, reason,
+                    userId);
         } else {
             ImeTracker.forLogging().onCancelled(statsToken, ImeTracker.PHASE_SERVER_SHOULD_HIDE);
         }
-        final var bindingController = getInputMethodBindingController(mCurrentUserId);
         bindingController.setCurrentMethodNotVisible();
         mVisibilityStateComputer.clearImeShowFlags();
         // Cancel existing statsToken for show IME as we got a hide request.
-        ImeTracker.forLogging().onCancelled(mCurStatsToken, ImeTracker.PHASE_SERVER_WAIT_IME);
-        mCurStatsToken = null;
+        ImeTracker.forLogging().onCancelled(userData.mCurStatsToken,
+                ImeTracker.PHASE_SERVER_WAIT_IME);
+        userData.mCurStatsToken = null;
         return shouldHideSoftInput;
     }
 
@@ -3746,7 +3652,7 @@
                     return new InputBindResult(
                             InputBindResult.ResultCode.ERROR_SYSTEM_NOT_READY,
                             null /* method */, null /* accessibilitySessions */, null /* channel */,
-                            getSelectedMethodIdLocked(),
+                            bindingController.getSelectedMethodId(),
                             bindingController.getSequenceNumber(),
                             false /* isInputMethodSuppressingSpellChecker */);
                 }
@@ -3757,8 +3663,7 @@
                 final long ident = Binder.clearCallingIdentity();
                 try {
                     // Verify if IMMS is in the process of switching user.
-                    if (!mExperimentalConcurrentMultiUserModeEnabled
-                            && mUserSwitchHandlerTask != null) {
+                    if (!mConcurrentMultiUserModeEnabled && mUserSwitchHandlerTask != null) {
                         // There is already an on-going pending user switch task.
                         final int nextUserId = mUserSwitchHandlerTask.mToUserId;
                         if (userId == nextUserId) {
@@ -3806,13 +3711,14 @@
                     final boolean shouldClearFlag =
                             mImePlatformCompatUtils.shouldClearShowForcedFlag(cs.mUid);
                     final boolean showForced = mVisibilityStateComputer.mShowForced;
-                    if (mImeBindingState.mFocusedWindow != windowToken
+                    final var userData = getUserData(userId);
+                    if (userData.mImeBindingState.mFocusedWindow != windowToken
                             && showForced && shouldClearFlag) {
                         mVisibilityStateComputer.mShowForced = false;
                     }
 
                     // Verify if caller is a background user.
-                    if (!mExperimentalConcurrentMultiUserModeEnabled && userId != mCurrentUserId) {
+                    if (!mConcurrentMultiUserModeEnabled && userId != mCurrentUserId) {
                         if (ArrayUtils.contains(
                                 mUserManagerInternal.getProfileIds(mCurrentUserId, false),
                                 userId)) {
@@ -3825,8 +3731,8 @@
                         Slog.w(TAG, "If you need to impersonate a foreground user/profile from"
                                 + " a background user, use EditorInfo.targetInputMethodUser with"
                                 + " INTERACT_ACROSS_USERS_FULL permission.");
-                        hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
-                                SoftInputShowHideReason.HIDE_INVALID_USER);
+                        hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow,
+                                0 /* flags */, SoftInputShowHideReason.HIDE_INVALID_USER, userId);
                         return InputBindResult.INVALID_USER;
                     }
 
@@ -3886,7 +3792,9 @@
                     + " cs=" + cs);
         }
 
-        final boolean sameWindowFocused = mImeBindingState.mFocusedWindow == windowToken;
+        final int userId = bindingController.getUserId();
+        final var userData = getUserData(userId);
+        final boolean sameWindowFocused = userData.mImeBindingState.mFocusedWindow == windowToken;
         final boolean isTextEditor = (startInputFlags & StartInputFlags.IS_TEXT_EDITOR) != 0;
         final boolean startInputByWinGainedFocus =
                 (startInputFlags & StartInputFlags.WINDOW_GAINED_FOCUS) != 0;
@@ -3918,7 +3826,7 @@
                     null, null, null, null, -1, false);
         }
 
-        mImeBindingState = new ImeBindingState(bindingController.mUserId, windowToken,
+        userData.mImeBindingState = new ImeBindingState(bindingController.getUserId(), windowToken,
                 softInputMode, cs, editorInfo);
         mFocusedWindowPerceptible.put(windowToken, true);
 
@@ -3949,16 +3857,17 @@
                     }
                     break;
             }
-            final var statsToken = createStatsTokenForFocusedClient(isShow, imeVisRes.getReason());
-            mVisibilityApplier.applyImeVisibility(mImeBindingState.mFocusedWindow, statsToken,
-                    imeVisRes.getState(), imeVisRes.getReason());
+            final var statsToken = createStatsTokenForFocusedClient(isShow, imeVisRes.getReason(),
+                    userId);
+            mVisibilityApplier.applyImeVisibility(userData.mImeBindingState.mFocusedWindow,
+                    statsToken, imeVisRes.getState(), imeVisRes.getReason(), userId);
             if (imeVisRes.getReason() == SoftInputShowHideReason.HIDE_UNSPECIFIED_WINDOW) {
                 // If focused display changed, we should unbind current method
                 // to make app window in previous display relayout after Ime
                 // 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.mSelfReportedDisplayId != getCurTokenDisplayIdLocked()) {
+                if (cs.mSelfReportedDisplayId != bindingController.getCurTokenDisplayId()) {
                     bindingController.unbindCurrentMethod();
                 }
             }
@@ -3978,9 +3887,10 @@
 
     @GuardedBy("ImfLock.class")
     private boolean canInteractWithImeLocked(int uid, IInputMethodClient client, String methodName,
-            @Nullable ImeTracker.Token statsToken) {
-        if (mCurClient == null || client == null
-                || mCurClient.mClient.asBinder() != client.asBinder()) {
+            @Nullable ImeTracker.Token statsToken, @UserIdInt int userId) {
+        final var userData = getUserData(userId);
+        if (userData.mCurClient == null || client == null
+                || userData.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.
@@ -3990,7 +3900,7 @@
                 throw new IllegalArgumentException("unknown client " + client.asBinder());
             }
             ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_CLIENT_KNOWN);
-            if (!isImeClientFocused(mImeBindingState.mFocusedWindow, cs)) {
+            if (!isImeClientFocused(userData.mImeBindingState.mFocusedWindow, cs)) {
                 Slog.w(TAG, String.format("Ignoring %s of uid %d : %s", methodName, uid, client));
                 return false;
             }
@@ -4002,14 +3912,18 @@
     @GuardedBy("ImfLock.class")
     private boolean canShowInputMethodPickerLocked(IInputMethodClient client) {
         final int uid = Binder.getCallingUid();
-        if (mImeBindingState.mFocusedWindowClient != null && client != null
-                && mImeBindingState.mFocusedWindowClient.mClient.asBinder() == client.asBinder()) {
+        // TODO(b/305849394): Get userId from callers.
+        final int userId = mCurrentUserId;
+        final var userData = getUserData(userId);
+        if (userData.mImeBindingState.mFocusedWindowClient != null && client != null
+                && userData.mImeBindingState.mFocusedWindowClient.mClient.asBinder()
+                == client.asBinder()) {
             return true;
         }
-        if (mCurrentUserId != UserHandle.getUserId(uid)) {
+        if (userId != UserHandle.getUserId(uid)) {
             return false;
         }
-        final var curIntent = getInputMethodBindingController(mCurrentUserId).getCurIntent();
+        final var curIntent = getInputMethodBindingController(userId).getCurIntent();
         if (curIntent != null && InputMethodUtils.checkIfPackageBelongsToUid(
                 mPackageManagerInternal, uid, curIntent.getComponent().getPackageName())) {
             return true;
@@ -4020,17 +3934,19 @@
     @Override
     public void showInputMethodPickerFromClient(IInputMethodClient client,
             int auxiliarySubtypeMode) {
+        final int callingUserId = UserHandle.getCallingUserId();
         synchronized (ImfLock.class) {
             if (!canShowInputMethodPickerLocked(client)) {
                 Slog.w(TAG, "Ignoring showInputMethodPickerFromClient of uid "
                         + Binder.getCallingUid() + ": " + client);
                 return;
             }
-
+            final int userId = resolveImeUserIdLocked(callingUserId);
+            final var userData = getUserData(userId);
             // Always call subtype picker, because subtype picker is a superset of input method
             // picker.
-            final int displayId =
-                    (mCurClient != null) ? mCurClient.mSelfReportedDisplayId : DEFAULT_DISPLAY;
+            final int displayId = (userData.mCurClient != null)
+                    ? userData.mCurClient.mSelfReportedDisplayId : DEFAULT_DISPLAY;
             mHandler.obtainMessage(MSG_SHOW_IM_SUBTYPE_PICKER, auxiliarySubtypeMode, displayId)
                     .sendToTarget();
         }
@@ -4062,33 +3978,31 @@
     }
 
     @BinderThread
-    private void setInputMethod(@NonNull IBinder token, String id) {
+    private void setInputMethod(@NonNull IBinder token, String id, @UserIdInt int userId) {
         final int callingUid = Binder.getCallingUid();
-        final int userId = UserHandle.getUserId(callingUid);
         synchronized (ImfLock.class) {
-            if (!calledWithValidTokenLocked(token)) {
+            if (!calledWithValidTokenLocked(token, userId)) {
                 return;
             }
-            final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
+            final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
             final InputMethodInfo imi = settings.getMethodMap().get(id);
             if (imi == null || !canCallerAccessInputMethod(
                     imi.getPackageName(), callingUid, userId, settings)) {
                 throw getExceptionForUnknownImeId(id);
             }
-            setInputMethodWithSubtypeIdLocked(token, id, NOT_A_SUBTYPE_ID);
+            setInputMethodWithSubtypeIdLocked(token, id, NOT_A_SUBTYPE_ID, userId);
         }
     }
 
     @BinderThread
     private void setInputMethodAndSubtype(@NonNull IBinder token, String id,
-            InputMethodSubtype subtype) {
+            InputMethodSubtype subtype, @UserIdInt int userId) {
         final int callingUid = Binder.getCallingUid();
-        final int userId = UserHandle.getUserId(callingUid);
         synchronized (ImfLock.class) {
-            if (!calledWithValidTokenLocked(token)) {
+            if (!calledWithValidTokenLocked(token, userId)) {
                 return;
             }
-            final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
+            final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
             final InputMethodInfo imi = settings.getMethodMap().get(id);
             if (imi == null || !canCallerAccessInputMethod(
                     imi.getPackageName(), callingUid, userId, settings)) {
@@ -4096,20 +4010,19 @@
             }
             if (subtype != null) {
                 setInputMethodWithSubtypeIdLocked(token, id,
-                        SubtypeUtils.getSubtypeIdFromHashCode(imi, subtype.hashCode()));
+                        SubtypeUtils.getSubtypeIdFromHashCode(imi, subtype.hashCode()), userId);
             } else {
-                setInputMethod(token, id);
+                setInputMethod(token, id, userId);
             }
         }
     }
 
     @BinderThread
-    private boolean switchToPreviousInputMethod(@NonNull IBinder token) {
+    private boolean switchToPreviousInputMethod(@NonNull IBinder token, @UserIdInt int userId) {
         synchronized (ImfLock.class) {
-            if (!calledWithValidTokenLocked(token)) {
+            if (!calledWithValidTokenLocked(token, userId)) {
                 return false;
             }
-            final int userId = mCurrentUserId;
             final var bindingController = getInputMethodBindingController(userId);
             final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
             final Pair<String, String> lastIme = settings.getLastInputMethodAndSubtype();
@@ -4174,9 +4087,10 @@
             if (!TextUtils.isEmpty(targetLastImiId)) {
                 if (DEBUG) {
                     Slog.d(TAG, "Switch to: " + lastImi.getId() + ", " + lastIme.second
-                            + ", from: " + getSelectedMethodIdLocked() + ", " + subtypeId);
+                            + ", from: " + bindingController.getSelectedMethodId() + ", "
+                            + subtypeId);
                 }
-                setInputMethodWithSubtypeIdLocked(token, targetLastImiId, subtypeId);
+                setInputMethodWithSubtypeIdLocked(token, targetLastImiId, subtypeId, userId);
                 return true;
             } else {
                 return false;
@@ -4185,41 +4099,44 @@
     }
 
     @BinderThread
-    private boolean switchToNextInputMethod(@NonNull IBinder token, boolean onlyCurrentIme) {
+    private boolean switchToNextInputMethod(@NonNull IBinder token, boolean onlyCurrentIme,
+            @UserIdInt int userId) {
         synchronized (ImfLock.class) {
-            if (!calledWithValidTokenLocked(token)) {
+            if (!calledWithValidTokenLocked(token, userId)) {
                 return false;
             }
-            return switchToNextInputMethodLocked(token, onlyCurrentIme);
+            return switchToNextInputMethodLocked(token, onlyCurrentIme, userId);
         }
     }
 
     @GuardedBy("ImfLock.class")
-    private boolean switchToNextInputMethodLocked(@Nullable IBinder token, boolean onlyCurrentIme) {
-        final int userId = mCurrentUserId;
+    private boolean switchToNextInputMethodLocked(@Nullable IBinder token, boolean onlyCurrentIme,
+            @UserIdInt int userId) {
         final var bindingController = getInputMethodBindingController(userId);
         final var currentImi = bindingController.getSelectedMethod();
-        final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
-                onlyCurrentIme, currentImi, bindingController.getCurrentSubtype());
+        final ImeSubtypeListItem nextSubtype = getUserData(userId).mSwitchingController
+                .getNextInputMethodLocked(onlyCurrentIme, currentImi,
+                        bindingController.getCurrentSubtype());
         if (nextSubtype == null) {
             return false;
         }
         setInputMethodWithSubtypeIdLocked(token, nextSubtype.mImi.getId(),
-                nextSubtype.mSubtypeId);
+                nextSubtype.mSubtypeId, userId);
         return true;
     }
 
     @BinderThread
-    private boolean shouldOfferSwitchingToNextInputMethod(@NonNull IBinder token) {
+    private boolean shouldOfferSwitchingToNextInputMethod(@NonNull IBinder token,
+            @UserIdInt int userId) {
         synchronized (ImfLock.class) {
-            if (!calledWithValidTokenLocked(token)) {
+            if (!calledWithValidTokenLocked(token, userId)) {
                 return false;
             }
-            final int userId = mCurrentUserId;
             final var bindingController = getInputMethodBindingController(userId);
             final var currentImi = bindingController.getSelectedMethod();
-            final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
-                    false /* onlyCurrentIme */, currentImi, bindingController.getCurrentSubtype());
+            final ImeSubtypeListItem nextSubtype = getUserData(userId).mSwitchingController
+                    .getNextInputMethodLocked(false /* onlyCurrentIme */, currentImi,
+                            bindingController.getCurrentSubtype());
             return nextSubtype != null;
         }
     }
@@ -4276,7 +4193,8 @@
                             DirectBootAwareness.AUTO);
                     InputMethodSettingsRepository.put(userId, newSettings);
                     if (isCurrentUser) {
-                        postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */);
+                        postInputMethodSettingUpdatedLocked(false /* resetDefaultEnabledIme */,
+                                userId);
                     }
                 } finally {
                     Binder.restoreCallingIdentity(ident);
@@ -4312,10 +4230,9 @@
                 }
                 if (currentUser) {
                     // To avoid unnecessary "updateInputMethodsFromSettingsLocked" from happening.
-                    if (mSettingsObserver != null) {
-                        mSettingsObserver.mLastEnabled = settings.getEnabledInputMethodsStr();
-                    }
-                    updateInputMethodsFromSettingsLocked(false /* enabledChanged */);
+                    final var userData = getUserData(userId);
+                    userData.mLastEnabledInputMethodsStr = settings.getEnabledInputMethodsStr();
+                    updateInputMethodsFromSettingsLocked(false /* enabledChanged */, userId);
                 }
             }
         } finally {
@@ -4334,17 +4251,20 @@
     @Override
     @Deprecated
     public int getInputMethodWindowVisibleHeight(@NonNull IInputMethodClient client) {
-        int callingUid = Binder.getCallingUid();
+        final int callingUid = Binder.getCallingUid();
+        final int callingUserId = UserHandle.getCallingUserId();
         return Binder.withCleanCallingIdentity(() -> {
             final int curTokenDisplayId;
             synchronized (ImfLock.class) {
+                final int userId = resolveImeUserIdLocked(callingUserId);
                 if (!canInteractWithImeLocked(callingUid, client,
-                        "getInputMethodWindowVisibleHeight", null /* statsToken */)) {
+                        "getInputMethodWindowVisibleHeight", null /* statsToken */, userId)) {
                     return 0;
                 }
+                final var bindingController = getInputMethodBindingController(userId);
                 // This should probably use the caller's display id, but because this is unsupported
                 // and maintained only for compatibility, there's no point in fixing it.
-                curTokenDisplayId = getCurTokenDisplayIdLocked();
+                curTokenDisplayId = bindingController.getCurTokenDisplayId();
             }
             return mWindowManagerInternal.getInputMethodWindowVisibleHeight(curTokenDisplayId);
         });
@@ -4469,10 +4389,12 @@
     @IInputMethodManagerImpl.PermissionVerified(Manifest.permission.TEST_INPUT_METHOD)
     @Override
     public void addVirtualStylusIdForTestSession(IInputMethodClient client) {
-        int uid = Binder.getCallingUid();
+        final int uid = Binder.getCallingUid();
+        final int callingUserId = UserHandle.getUserId(uid);
         synchronized (ImfLock.class) {
+            final int userId = resolveImeUserIdLocked(callingUserId);
             if (!canInteractWithImeLocked(uid, client, "addVirtualStylusIdForTestSession",
-                    null /* statsToken */)) {
+                    null /* statsToken */, userId)) {
                 return;
             }
             final long ident = Binder.clearCallingIdentity();
@@ -4496,10 +4418,12 @@
     @Override
     public void setStylusWindowIdleTimeoutForTest(
             IInputMethodClient client, @DurationMillisLong long timeout) {
-        int uid = Binder.getCallingUid();
+        final int uid = Binder.getCallingUid();
+        final int callingUserId = UserHandle.getUserId(uid);
         synchronized (ImfLock.class) {
+            final int userId = resolveImeUserIdLocked(callingUserId);
             if (!canInteractWithImeLocked(uid, client, "setStylusWindowIdleTimeoutForTest",
-                    null /* statsToken */)) {
+                    null /* statsToken */, userId)) {
                 return;
             }
             final long ident = Binder.clearCallingIdentity();
@@ -4609,67 +4533,66 @@
 
     private void dumpDebug(ProtoOutputStream proto, long fieldId) {
         synchronized (ImfLock.class) {
-            final var bindingController = getInputMethodBindingController(mCurrentUserId);
+            final int userId = mCurrentUserId;
+            final var bindingController = getInputMethodBindingController(userId);
+            final var userData = getUserData(userId);
             final long token = proto.start(fieldId);
-            proto.write(CUR_METHOD_ID, getSelectedMethodIdLocked());
+            proto.write(CUR_METHOD_ID, bindingController.getSelectedMethodId());
             proto.write(CUR_SEQ, bindingController.getSequenceNumber());
-            proto.write(CUR_CLIENT, Objects.toString(mCurClient));
-            mImeBindingState.dumpDebug(proto, mWindowManagerInternal);
+            proto.write(CUR_CLIENT, Objects.toString(userData.mCurClient));
+            userData.mImeBindingState.dumpDebug(proto, mWindowManagerInternal);
             proto.write(LAST_IME_TARGET_WINDOW_NAME,
                     mWindowManagerInternal.getWindowName(mLastImeTargetWindow));
             proto.write(CUR_FOCUSED_WINDOW_SOFT_INPUT_MODE, InputMethodDebug.softInputModeToString(
-                    mImeBindingState.mFocusedWindowSoftInputMode));
-            if (mCurEditorInfo != null) {
-                mCurEditorInfo.dumpDebug(proto, CUR_ATTRIBUTE);
+                    userData.mImeBindingState.mFocusedWindowSoftInputMode));
+            if (userData.mCurEditorInfo != null) {
+                userData.mCurEditorInfo.dumpDebug(proto, CUR_ATTRIBUTE);
             }
             proto.write(CUR_ID, bindingController.getCurId());
             mVisibilityStateComputer.dumpDebug(proto, fieldId);
-            proto.write(IN_FULLSCREEN_MODE, mInFullscreenMode);
-            proto.write(CUR_TOKEN, Objects.toString(getCurTokenLocked()));
-            proto.write(CUR_TOKEN_DISPLAY_ID, getCurTokenDisplayIdLocked());
+            proto.write(IN_FULLSCREEN_MODE, userData.mInFullscreenMode);
+            proto.write(CUR_TOKEN, Objects.toString(bindingController.getCurToken()));
+            proto.write(CUR_TOKEN_DISPLAY_ID, bindingController.getCurTokenDisplayId());
             proto.write(SYSTEM_READY, mSystemReady);
             proto.write(HAVE_CONNECTION, bindingController.hasMainConnection());
-            proto.write(BOUND_TO_METHOD, mBoundToMethod);
+            proto.write(BOUND_TO_METHOD, userData.mBoundToMethod);
             proto.write(IS_INTERACTIVE, mIsInteractive);
-            proto.write(BACK_DISPOSITION, mBackDisposition);
-            proto.write(IME_WINDOW_VISIBILITY, mImeWindowVis);
+            proto.write(BACK_DISPOSITION, bindingController.getBackDisposition());
+            proto.write(IME_WINDOW_VISIBILITY, bindingController.getImeWindowVis());
             proto.write(SHOW_IME_WITH_HARD_KEYBOARD, mMenuController.getShowImeWithHardKeyboard());
             proto.end(token);
         }
     }
 
     @BinderThread
-    private void notifyUserAction(@NonNull IBinder token) {
+    private void notifyUserAction(@NonNull IBinder token, @UserIdInt int userId) {
         if (DEBUG) {
             Slog.d(TAG, "Got the notification of a user action.");
         }
         synchronized (ImfLock.class) {
-            if (getCurTokenLocked() != token) {
+            final var bindingController = getInputMethodBindingController(userId);
+            if (bindingController.getCurToken() != token) {
                 if (DEBUG) {
                     Slog.d(TAG, "Ignoring the user action notification from IMEs that are no longer"
                             + " active.");
                 }
                 return;
             }
-            final int userId = mCurrentUserId;
-            if (userId != mSwitchingController.getUserId()) {
-                return;
-            }
-            final var imi = getInputMethodBindingController(userId).getSelectedMethod();
+            final InputMethodInfo imi = bindingController.getSelectedMethod();
             if (imi != null) {
-                mSwitchingController.onUserActionLocked(imi,
-                        getInputMethodBindingController(userId).getCurrentSubtype());
+                getUserData(userId).mSwitchingController.onUserActionLocked(imi,
+                        bindingController.getCurrentSubtype());
             }
         }
     }
 
     @BinderThread
     private void applyImeVisibility(IBinder token, IBinder windowToken, boolean setVisible,
-            @NonNull ImeTracker.Token statsToken) {
+            @NonNull ImeTracker.Token statsToken, @UserIdInt int userId) {
         try {
             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.applyImeVisibility");
             synchronized (ImfLock.class) {
-                if (!calledWithValidTokenLocked(token)) {
+                if (!calledWithValidTokenLocked(token, userId)) {
                     ImeTracker.forLogging().onFailed(statsToken,
                             ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
                     return;
@@ -4677,10 +4600,11 @@
                 ImeTracker.forLogging().onProgress(statsToken,
                         ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
                 final IBinder requestToken = mVisibilityStateComputer.getWindowTokenFrom(
-                        windowToken);
+                        windowToken, userId);
                 mVisibilityApplier.applyImeVisibility(requestToken, statsToken,
                         setVisible ? ImeVisibilityStateComputer.STATE_SHOW_IME
-                                : ImeVisibilityStateComputer.STATE_HIDE_IME, mCurrentUserId);
+                                : ImeVisibilityStateComputer.STATE_HIDE_IME,
+                        SoftInputShowHideReason.NOT_SET /* ignore reason */, userId);
             }
         } finally {
             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
@@ -4701,7 +4625,9 @@
     }
 
     @GuardedBy("ImfLock.class")
-    private void setInputMethodWithSubtypeIdLocked(IBinder token, String id, int subtypeId) {
+    private void setInputMethodWithSubtypeIdLocked(IBinder token, String id, int subtypeId,
+            @UserIdInt int userId) {
+        final var bindingController = getInputMethodBindingController(userId);
         if (token == null) {
             if (mContext.checkCallingOrSelfPermission(
                     android.Manifest.permission.WRITE_SECURE_SETTINGS)
@@ -4710,13 +4636,13 @@
                         "Using null token requires permission "
                                 + android.Manifest.permission.WRITE_SECURE_SETTINGS);
             }
-        } else if (getCurTokenLocked() != token) {
+        } else if (bindingController.getCurToken() != token) {
             Slog.w(TAG, "Ignoring setInputMethod of uid " + Binder.getCallingUid()
                     + " token: " + token);
             return;
         } else {
             // Called with current IME's token.
-            final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
+            final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
             if (settings.getMethodMap().get(id) != null
                     && settings.getEnabledInputMethodListWithFilter(
                             (info) -> info.getId().equals(id)).isEmpty()) {
@@ -4726,7 +4652,7 @@
 
         final long ident = Binder.clearCallingIdentity();
         try {
-            setInputMethodLocked(id, subtypeId);
+            setInputMethodLocked(id, subtypeId, userId);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
@@ -4737,17 +4663,22 @@
      */
     @GuardedBy("ImfLock.class")
     void onShowHideSoftInputRequested(boolean show, IBinder requestImeToken,
-            @SoftInputShowHideReason int reason, @Nullable ImeTracker.Token statsToken) {
-        final IBinder requestToken = mVisibilityStateComputer.getWindowTokenFrom(requestImeToken);
+            @SoftInputShowHideReason int reason, @Nullable ImeTracker.Token statsToken,
+            @UserIdInt int userId) {
+        final IBinder requestToken = mVisibilityStateComputer.getWindowTokenFrom(requestImeToken,
+                userId);
+        final var bindingController = getInputMethodBindingController(userId);
+        final var userData = getUserData(userId);
         final WindowManagerInternal.ImeTargetInfo info =
                 mWindowManagerInternal.onToggleImeRequested(
-                        show, mImeBindingState.mFocusedWindow, requestToken,
-                        getCurTokenDisplayIdLocked());
+                        show, userData.mImeBindingState.mFocusedWindow, requestToken,
+                        bindingController.getCurTokenDisplayId());
         mSoftInputShowHideHistory.addEntry(new SoftInputShowHideHistory.Entry(
-                mImeBindingState.mFocusedWindowClient, mImeBindingState.mFocusedWindowEditorInfo,
-                info.focusedWindowName, mImeBindingState.mFocusedWindowSoftInputMode, reason,
-                mInFullscreenMode, info.requestWindowName, info.imeControlTargetName,
-                info.imeLayerTargetName, info.imeSurfaceParentName));
+                userData.mImeBindingState.mFocusedWindowClient,
+                userData.mImeBindingState.mFocusedWindowEditorInfo,
+                info.focusedWindowName, userData.mImeBindingState.mFocusedWindowSoftInputMode,
+                reason, userData.mInFullscreenMode, info.requestWindowName,
+                info.imeControlTargetName, info.imeLayerTargetName, info.imeSurfaceParentName));
 
         if (statsToken != null) {
             mImeTrackerService.onImmsUpdate(statsToken, info.requestWindowName);
@@ -4756,30 +4687,33 @@
 
     @BinderThread
     private void hideMySoftInput(@NonNull IBinder token, @NonNull ImeTracker.Token statsToken,
-            @InputMethodManager.HideFlags int flags, @SoftInputShowHideReason int reason) {
+            @InputMethodManager.HideFlags int flags, @SoftInputShowHideReason int reason,
+            @UserIdInt int userId) {
         try {
             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.hideMySoftInput");
             synchronized (ImfLock.class) {
-                if (!calledWithValidTokenLocked(token)) {
+                if (!calledWithValidTokenLocked(token, userId)) {
                     ImeTracker.forLogging().onFailed(statsToken,
                             ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
                     return;
                 }
+                final var userData = getUserData(userId);
                 ImeTracker.forLogging().onProgress(statsToken,
                         ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
                 final long ident = Binder.clearCallingIdentity();
                 try {
                     if (Flags.refactorInsetsController()) {
-                        mCurClient.mClient.setImeVisibility(false);
+                        userData.mCurClient.mClient.setImeVisibility(false);
                         // TODO we will loose the flags here
-                        if (mImeBindingState != null
-                                && mImeBindingState.mFocusedWindowClient != null
-                                && mImeBindingState.mFocusedWindowClient.mClient != null) {
-                            mImeBindingState.mFocusedWindowClient.mClient.setImeVisibility(false);
+                        if (userData.mImeBindingState != null
+                                && userData.mImeBindingState.mFocusedWindowClient != null
+                                && userData.mImeBindingState.mFocusedWindowClient.mClient != null) {
+                            userData.mImeBindingState.mFocusedWindowClient.mClient
+                                    .setImeVisibility(false);
                         }
                     } else {
                         hideCurrentInputLocked(mLastImeTargetWindow, statsToken, flags,
-                                null /* resultReceiver */, reason);
+                                null /* resultReceiver */, reason, userId);
                     }
                 } finally {
                     Binder.restoreCallingIdentity(ident);
@@ -4792,30 +4726,34 @@
 
     @BinderThread
     private void showMySoftInput(@NonNull IBinder token, @NonNull ImeTracker.Token statsToken,
-            @InputMethodManager.ShowFlags int flags, @SoftInputShowHideReason int reason) {
+            @InputMethodManager.ShowFlags int flags, @SoftInputShowHideReason int reason,
+            @UserIdInt int userId) {
         try {
             Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.showMySoftInput");
             synchronized (ImfLock.class) {
-                if (!calledWithValidTokenLocked(token)) {
+                if (!calledWithValidTokenLocked(token, userId)) {
                     ImeTracker.forLogging().onFailed(statsToken,
                             ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
                     return;
                 }
+                final var userData = getUserData(userId);
                 ImeTracker.forLogging().onProgress(statsToken,
                         ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
                 final long ident = Binder.clearCallingIdentity();
                 try {
                     if (Flags.refactorInsetsController()) {
-                        mCurClient.mClient.setImeVisibility(false);
+                        userData.mCurClient.mClient.setImeVisibility(false);
                         // TODO we will loose the flags here
-                        if (mImeBindingState != null
-                                && mImeBindingState.mFocusedWindowClient != null
-                                && mImeBindingState.mFocusedWindowClient.mClient != null) {
-                            mImeBindingState.mFocusedWindowClient.mClient.setImeVisibility(true);
+                        if (userData.mImeBindingState != null
+                                && userData.mImeBindingState.mFocusedWindowClient != null
+                                && userData.mImeBindingState.mFocusedWindowClient.mClient != null) {
+                            userData.mImeBindingState.mFocusedWindowClient.mClient
+                                    .setImeVisibility(true);
                         }
                     } else {
                         showCurrentInputLocked(mLastImeTargetWindow, statsToken, flags,
-                                MotionEvent.TOOL_TYPE_UNKNOWN, null /* resultReceiver */, reason);
+                                MotionEvent.TOOL_TYPE_UNKNOWN, null /* resultReceiver */, reason,
+                                userId);
                     }
                 } finally {
                     Binder.restoreCallingIdentity(ident);
@@ -4826,46 +4764,52 @@
         }
     }
 
+    @GuardedBy("ImfLock.class")
     @VisibleForTesting
-    ImeVisibilityApplier getVisibilityApplier() {
-        synchronized (ImfLock.class) {
-            return mVisibilityApplier;
-        }
+    DefaultImeVisibilityApplier getVisibilityApplierLocked() {
+        return mVisibilityApplier;
     }
 
     void onApplyImeVisibilityFromComputer(IBinder windowToken, @NonNull ImeTracker.Token statsToken,
             @NonNull ImeVisibilityResult result) {
         synchronized (ImfLock.class) {
+            // TODO(b/305849394): Infer userId from windowToken
+            final int userId = mCurrentUserId;
             mVisibilityApplier.applyImeVisibility(windowToken, statsToken, result.getState(),
-                    result.getReason());
+                    result.getReason(), userId);
         }
     }
 
     @GuardedBy("ImfLock.class")
-    void setEnabledSessionLocked(SessionState session) {
-        if (mEnabledSession != session) {
-            if (mEnabledSession != null && mEnabledSession.mSession != null) {
-                if (DEBUG) Slog.v(TAG, "Disabling: " + mEnabledSession);
-                mEnabledSession.mMethod.setSessionEnabled(mEnabledSession.mSession, false);
+    void setEnabledSessionLocked(SessionState session,
+            @NonNull UserDataRepository.UserData userData) {
+        if (userData.mEnabledSession != session) {
+            if (userData.mEnabledSession != null && userData.mEnabledSession.mSession != null) {
+                if (DEBUG) Slog.v(TAG, "Disabling: " + userData.mEnabledSession);
+                userData.mEnabledSession.mMethod.setSessionEnabled(
+                        userData.mEnabledSession.mSession, false);
             }
-            mEnabledSession = session;
-            if (mEnabledSession != null && mEnabledSession.mSession != null) {
-                if (DEBUG) Slog.v(TAG, "Enabling: " + mEnabledSession);
-                mEnabledSession.mMethod.setSessionEnabled(mEnabledSession.mSession, true);
+            userData.mEnabledSession = session;
+            if (userData.mEnabledSession != null && userData.mEnabledSession.mSession != null) {
+                if (DEBUG) Slog.v(TAG, "Enabling: " + userData.mEnabledSession);
+                userData.mEnabledSession.mMethod.setSessionEnabled(
+                        userData.mEnabledSession.mSession, true);
             }
         }
     }
 
     @GuardedBy("ImfLock.class")
     void setEnabledSessionForAccessibilityLocked(
-            SparseArray<AccessibilitySessionState> accessibilitySessions) {
+            SparseArray<AccessibilitySessionState> accessibilitySessions,
+            @NonNull UserDataRepository.UserData userData) {
         // mEnabledAccessibilitySessions could the same object as accessibilitySessions.
         SparseArray<IAccessibilityInputMethodSession> disabledSessions = new SparseArray<>();
-        for (int i = 0; i < mEnabledAccessibilitySessions.size(); i++) {
-            if (!accessibilitySessions.contains(mEnabledAccessibilitySessions.keyAt(i))) {
-                AccessibilitySessionState sessionState = mEnabledAccessibilitySessions.valueAt(i);
+        for (int i = 0; i < userData.mEnabledAccessibilitySessions.size(); i++) {
+            if (!accessibilitySessions.contains(userData.mEnabledAccessibilitySessions.keyAt(i))) {
+                AccessibilitySessionState sessionState =
+                        userData.mEnabledAccessibilitySessions.valueAt(i);
                 if (sessionState != null) {
-                    disabledSessions.append(mEnabledAccessibilitySessions.keyAt(i),
+                    disabledSessions.append(userData.mEnabledAccessibilitySessions.keyAt(i),
                             sessionState.mSession);
                 }
             }
@@ -4876,7 +4820,7 @@
         }
         SparseArray<IAccessibilityInputMethodSession> enabledSessions = new SparseArray<>();
         for (int i = 0; i < accessibilitySessions.size(); i++) {
-            if (!mEnabledAccessibilitySessions.contains(accessibilitySessions.keyAt(i))) {
+            if (!userData.mEnabledAccessibilitySessions.contains(accessibilitySessions.keyAt(i))) {
                 AccessibilitySessionState sessionState = accessibilitySessions.valueAt(i);
                 if (sessionState != null) {
                     enabledSessions.append(accessibilitySessions.keyAt(i), sessionState.mSession);
@@ -4887,7 +4831,7 @@
             AccessibilityManagerInternal.get().setImeSessionEnabled(enabledSessions,
                     true);
         }
-        mEnabledAccessibilitySessions = accessibilitySessions;
+        userData.mEnabledAccessibilitySessions = accessibilitySessions;
     }
 
     @SuppressWarnings("unchecked")
@@ -4929,7 +4873,7 @@
                     final List<ImeSubtypeListItem> imList = InputMethodSubtypeSwitchingController
                             .getSortedInputMethodAndSubtypeList(
                                     showAuxSubtypes, isScreenLocked, true /* forImeMenu */,
-                                    mContext, settings.getMethodMap(), settings.getUserId());
+                                    mContext, settings);
                     if (imList.isEmpty()) {
                         Slog.w(TAG, "Show switching menu failed, imList is empty,"
                                 + " showAuxSubtypes: " + showAuxSubtypes
@@ -4947,25 +4891,33 @@
 
             case MSG_HIDE_ALL_INPUT_METHODS:
                 synchronized (ImfLock.class) {
+                    // TODO(b/305849394): Needs to figure out what to do where for background users.
+                    final int userId = mCurrentUserId;
+                    final var userData = getUserData(userId);
                     if (Flags.refactorInsetsController()) {
-                        if (mImeBindingState != null
-                                && mImeBindingState.mFocusedWindowClient != null
-                                && mImeBindingState.mFocusedWindowClient.mClient != null) {
-                            mImeBindingState.mFocusedWindowClient.mClient.setImeVisibility(false);
+                        if (userData.mImeBindingState != null
+                                && userData.mImeBindingState.mFocusedWindowClient != null
+                                && userData.mImeBindingState.mFocusedWindowClient.mClient != null) {
+                            userData.mImeBindingState.mFocusedWindowClient.mClient
+                                    .setImeVisibility(false);
                         }
                     } else {
                         @SoftInputShowHideReason final int reason = (int) msg.obj;
-                        hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
-                                reason);
+                        hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow,
+                                0 /* flags */, reason, userId);
                     }
                 }
                 return true;
             case MSG_REMOVE_IME_SURFACE: {
                 synchronized (ImfLock.class) {
+                    // TODO(b/305849394): Needs to figure out what to do where for background users.
+                    final int userId = mCurrentUserId;
+                    final var userData = getUserData(userId);
                     try {
-                        if (mEnabledSession != null && mEnabledSession.mSession != null
-                                && !isShowRequestedForCurrentWindow()) {
-                            mEnabledSession.mSession.removeImeSurface();
+                        if (userData.mEnabledSession != null
+                                && userData.mEnabledSession.mSession != null
+                                && !isShowRequestedForCurrentWindow(userId)) {
+                            userData.mEnabledSession.mSession.removeImeSurface();
                         }
                     } catch (RemoteException e) {
                     }
@@ -4975,10 +4927,14 @@
             case MSG_REMOVE_IME_SURFACE_FROM_WINDOW: {
                 IBinder windowToken = (IBinder) msg.obj;
                 synchronized (ImfLock.class) {
+                    // TODO(b/305849394): Infer userId from windowToken.
+                    final int userId = mCurrentUserId;
+                    final var userData = getUserData(userId);
                     try {
-                        if (windowToken == mImeBindingState.mFocusedWindow
-                                && mEnabledSession != null && mEnabledSession.mSession != null) {
-                            mEnabledSession.mSession.removeImeSurface();
+                        if (windowToken == userData.mImeBindingState.mFocusedWindow
+                                && userData.mEnabledSession != null
+                                && userData.mEnabledSession.mSession != null) {
+                            userData.mEnabledSession.mSession.removeImeSurface();
                         }
                     } catch (RemoteException e) {
                     }
@@ -5031,9 +4987,11 @@
                 synchronized (ImfLock.class) {
                     final var bindingController = getInputMethodBindingController(mCurrentUserId);
                     if (bindingController.supportsStylusHandwriting()
-                            && getCurMethodLocked() != null && hasSupportedStylusLocked()) {
+                            && bindingController.getCurMethod() != null
+                            && hasSupportedStylusLocked()) {
                         Slog.d(TAG, "Initializing Handwriting Spy");
-                        mHwController.initializeHandwritingSpy(getCurTokenDisplayIdLocked());
+                        mHwController.initializeHandwritingSpy(
+                                bindingController.getCurTokenDisplayId());
                     } else {
                         mHwController.reset();
                     }
@@ -5050,18 +5008,21 @@
                 }
                 return true;
             case MSG_START_HANDWRITING:
+                final var handwritingRequest = (HandwritingRequest) msg.obj;
                 synchronized (ImfLock.class) {
-                    IInputMethodInvoker curMethod = getCurMethodLocked();
-                    if (curMethod == null || mImeBindingState.mFocusedWindow == null) {
+                    final int userId = handwritingRequest.userId;
+                    final var bindingController = getInputMethodBindingController(userId);
+                    final var userData = getUserData(userId);
+                    IInputMethodInvoker curMethod = bindingController.getCurMethod();
+                    if (curMethod == null || userData.mImeBindingState.mFocusedWindow == null) {
                         return true;
                     }
-                    final var bindingController = getInputMethodBindingController(mCurrentUserId);
                     final HandwritingModeController.HandwritingSession session =
                             mHwController.startHandwritingSession(
-                                    msg.arg1 /*requestId*/,
-                                    msg.arg2 /*pid*/,
+                                    handwritingRequest.requestId,
+                                    handwritingRequest.pid,
                                     bindingController.getCurMethodUid(),
-                                    mImeBindingState.mFocusedWindow);
+                                    userData.mImeBindingState.mFocusedWindow);
                     if (session == null) {
                         Slog.e(TAG,
                                 "Failed to start handwriting session for requestId: " + msg.arg1);
@@ -5096,52 +5057,60 @@
         return false;
     }
 
+    private record HandwritingRequest(int requestId, int pid, @UserIdInt int userId) { }
+
     @BinderThread
-    private void onStylusHandwritingReady(int requestId, int pid) {
-        mHandler.obtainMessage(MSG_START_HANDWRITING, requestId, pid).sendToTarget();
+    private void onStylusHandwritingReady(int requestId, int pid, @UserIdInt int userId) {
+        mHandler.obtainMessage(MSG_START_HANDWRITING,
+                new HandwritingRequest(requestId, pid, userId)).sendToTarget();
     }
 
     private void handleSetInteractive(final boolean interactive) {
         synchronized (ImfLock.class) {
+            // TODO(b/305849394): Support multiple IMEs.
+            final int userId = mCurrentUserId;
+            final var bindingController = getInputMethodBindingController(userId);
             mIsInteractive = interactive;
-            updateSystemUiLocked(interactive ? mImeWindowVis : 0, mBackDisposition);
-
+            updateSystemUiLocked(
+                    interactive ? bindingController.getImeWindowVis() : 0,
+                    bindingController.getBackDisposition(), userId);
+            final var userData = getUserData(userId);
             // Inform the current client of the change in active status
-            if (mCurClient == null || mCurClient.mClient == null) {
+            if (userData.mCurClient == null || userData.mCurClient.mClient == null) {
                 return;
             }
-            // TODO(b/325515685): user data must be retrieved by a userId parameter
-            final var bindingController = getInputMethodBindingController(mCurrentUserId);
             if (mImePlatformCompatUtils.shouldUseSetInteractiveProtocol(
                     bindingController.getCurMethodUid())) {
                 // Handle IME visibility when interactive changed before finishing the input to
                 // ensure we preserve the last state as possible.
                 final ImeVisibilityResult imeVisRes = mVisibilityStateComputer.onInteractiveChanged(
-                        mImeBindingState.mFocusedWindow, interactive);
+                        userData.mImeBindingState.mFocusedWindow, interactive);
                 if (imeVisRes != null) {
                     // Pass in a null statsToken as the IME snapshot is not tracked by ImeTracker.
-                    mVisibilityApplier.applyImeVisibility(mImeBindingState.mFocusedWindow,
-                            null /* statsToken */, imeVisRes.getState(), imeVisRes.getReason());
+                    mVisibilityApplier.applyImeVisibility(userData.mImeBindingState.mFocusedWindow,
+                            null /* statsToken */, imeVisRes.getState(), imeVisRes.getReason(),
+                            userId);
                 }
                 // Eligible IME processes use new "setInteractive" protocol.
-                mCurClient.mClient.setInteractive(mIsInteractive, mInFullscreenMode);
+                userData.mCurClient.mClient.setInteractive(mIsInteractive,
+                        userData.mInFullscreenMode);
             } else {
                 // Legacy IME processes continue using legacy "setActive" protocol.
-                mCurClient.mClient.setActive(mIsInteractive, mInFullscreenMode);
+                userData.mCurClient.mClient.setActive(mIsInteractive, userData.mInFullscreenMode);
             }
         }
     }
 
     @GuardedBy("ImfLock.class")
-    private boolean chooseNewDefaultIMELocked() {
-        final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
+    private boolean chooseNewDefaultIMELocked(@UserIdInt int userId) {
+        final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
         final InputMethodInfo imi = InputMethodInfoUtils.getMostApplicableDefaultIME(
                 settings.getEnabledInputMethodList());
         if (imi != null) {
             if (DEBUG) {
                 Slog.d(TAG, "New default IME was selected: " + imi.getId());
             }
-            resetSelectedInputMethodAndSubtypeLocked(imi.getId());
+            resetSelectedInputMethodAndSubtypeLocked(imi.getId(), userId);
             return true;
         }
 
@@ -5244,7 +5213,8 @@
     }
 
     @GuardedBy("ImfLock.class")
-    void postInputMethodSettingUpdatedLocked(boolean resetDefaultEnabledIme) {
+    void postInputMethodSettingUpdatedLocked(boolean resetDefaultEnabledIme,
+            @UserIdInt int userId) {
         if (DEBUG) {
             Slog.d(TAG, "--- re-buildInputMethodList reset = " + resetDefaultEnabledIme
                     + " \n ------ caller=" + Debug.getCallers(10));
@@ -5254,7 +5224,6 @@
             return;
         }
 
-        final int userId = mCurrentUserId;
         final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
 
         boolean reenableMinimumNonAuxSystemImes = false;
@@ -5279,7 +5248,7 @@
                     Slog.i(TAG, "All the enabled IMEs are gone. Reset default enabled IMEs.");
                 }
                 resetDefaultEnabledIme = true;
-                resetSelectedInputMethodAndSubtypeLocked("");
+                resetSelectedInputMethodAndSubtypeLocked("", userId);
             } else if (!enabledNonAuxImeFound) {
                 if (DEBUG) {
                     Slog.i(TAG, "All the enabled non-Aux IMEs are gone. Do partial reset.");
@@ -5298,7 +5267,7 @@
                 if (DEBUG) {
                     Slog.d(TAG, "--- enable ime = " + imi);
                 }
-                setInputMethodEnabledLocked(imi.getId(), true);
+                setInputMethodEnabledLocked(imi.getId(), true, userId);
             }
         }
 
@@ -5306,31 +5275,20 @@
         if (!TextUtils.isEmpty(defaultImiId)) {
             if (!settings.getMethodMap().containsKey(defaultImiId)) {
                 Slog.w(TAG, "Default IME is uninstalled. Choose new default IME.");
-                if (chooseNewDefaultIMELocked()) {
-                    updateInputMethodsFromSettingsLocked(true);
+                if (chooseNewDefaultIMELocked(userId)) {
+                    updateInputMethodsFromSettingsLocked(true, userId);
                 }
             } else {
                 // Double check that the default IME is certainly enabled.
-                setInputMethodEnabledLocked(defaultImiId, true);
+                setInputMethodEnabledLocked(defaultImiId, true, userId);
             }
         }
 
-        updateDefaultVoiceImeIfNeededLocked();
+        updateDefaultVoiceImeIfNeededLocked(userId);
 
-        // TODO: Instantiate mSwitchingController for each user.
-        if (userId == mSwitchingController.getUserId()) {
-            mSwitchingController.resetCircularListLocked(settings.getMethodMap());
-        } else {
-            mSwitchingController = InputMethodSubtypeSwitchingController.createInstanceLocked(
-                    mContext, settings.getMethodMap(), mCurrentUserId);
-        }
-        // TODO: Instantiate mHardwareKeyboardShortcutController for each user.
-        if (userId == mHardwareKeyboardShortcutController.getUserId()) {
-            mHardwareKeyboardShortcutController.reset(settings.getMethodMap());
-        } else {
-            mHardwareKeyboardShortcutController = new HardwareKeyboardShortcutController(
-                    settings.getMethodMap(), userId);
-        }
+        final var userData = getUserData(userId);
+        userData.mSwitchingController.resetCircularListLocked(mContext, settings);
+        userData.mHardwareKeyboardShortcutController.update(settings);
 
         sendOnNavButtonFlagsChangedLocked();
 
@@ -5352,8 +5310,8 @@
     }
 
     @GuardedBy("ImfLock.class")
-    private void updateDefaultVoiceImeIfNeededLocked() {
-        final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
+    private void updateDefaultVoiceImeIfNeededLocked(@UserIdInt int userId) {
+        final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
         final String systemSpeechRecognizer =
                 mContext.getString(com.android.internal.R.string.config_systemSpeechRecognizer);
         final String currentDefaultVoiceImeId = settings.getDefaultVoiceInputMethod();
@@ -5377,9 +5335,10 @@
             return;
         }
         if (DEBUG) {
-            Slog.i(TAG, "Enabling the default Voice IME:" + newSystemVoiceIme);
+            Slog.i(TAG, "Enabling the default Voice IME:" + newSystemVoiceIme
+                    + " userId:" + userId);
         }
-        setInputMethodEnabledLocked(newSystemVoiceIme.getId(), true);
+        setInputMethodEnabledLocked(newSystemVoiceIme.getId(), true, userId);
         settings.putDefaultVoiceInputMethod(newSystemVoiceIme.getId());
     }
 
@@ -5391,11 +5350,11 @@
      * @param id      ID of the IME is to be manipulated. It is OK to pass IME ID that is currently
      *                not recognized by the system
      * @param enabled {@code true} if {@code id} needs to be enabled
+     * @param userId  the user ID to be updated
      * @return {@code true} if the IME was previously enabled
      */
     @GuardedBy("ImfLock.class")
-    private boolean setInputMethodEnabledLocked(String id, boolean enabled) {
-        final int userId = mCurrentUserId;
+    private boolean setInputMethodEnabledLocked(String id, boolean enabled, @UserIdInt int userId) {
         final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
         if (enabled) {
             final String enabledImeIdsStr = settings.getEnabledInputMethodsStr();
@@ -5419,9 +5378,9 @@
                 if (bindingController.getDeviceIdToShowIme() == DEVICE_ID_DEFAULT) {
                     // Disabled input method is currently selected, switch to another one.
                     final String selId = settings.getSelectedInputMethod();
-                    if (id.equals(selId) && !chooseNewDefaultIMELocked()) {
+                    if (id.equals(selId) && !chooseNewDefaultIMELocked(userId)) {
                         Slog.i(TAG, "Can't find new IME, unsetting the current input method.");
-                        resetSelectedInputMethodAndSubtypeLocked("");
+                        resetSelectedInputMethodAndSubtypeLocked("", userId);
                     }
                 } else if (id.equals(settings.getSelectedDefaultDeviceInputMethod())) {
                     // Disabled default device IME while using a virtual device one, choose a
@@ -5444,11 +5403,10 @@
 
     @GuardedBy("ImfLock.class")
     private void setSelectedInputMethodAndSubtypeLocked(InputMethodInfo imi, int subtypeId,
-            boolean setSubtypeOnly) {
-        final int userId = mCurrentUserId;
+            boolean setSubtypeOnly, @UserIdInt int userId) {
         final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
         final var bindingController = getInputMethodBindingController(userId);
-        settings.saveCurrentInputMethodAndSubtypeToHistory(getSelectedMethodIdLocked(),
+        settings.saveCurrentInputMethodAndSubtypeToHistory(bindingController.getSelectedMethodId(),
                 bindingController.getCurrentSubtype());
 
         // Set Subtype here
@@ -5467,7 +5425,7 @@
                 newSubtypeHashcode = INVALID_SUBTYPE_HASHCODE;
                 // If the subtype is not specified, choose the most applicable one
                 // TODO(b/347083680): The method below has questionable behaviors.
-                newSubtype = getCurrentInputMethodSubtypeLocked();
+                newSubtype = bindingController.getCurrentInputMethodSubtype();
             }
         }
         settings.putSelectedSubtype(newSubtypeHashcode);
@@ -5481,12 +5439,13 @@
     }
 
     @GuardedBy("ImfLock.class")
-    private void resetSelectedInputMethodAndSubtypeLocked(String newDefaultIme) {
-        final var bindingController = getInputMethodBindingController(mCurrentUserId);
+    private void resetSelectedInputMethodAndSubtypeLocked(String newDefaultIme,
+            @UserIdInt int userId) {
+        final var bindingController = getInputMethodBindingController(userId);
         bindingController.setDisplayIdToShowIme(INVALID_DISPLAY);
         bindingController.setDeviceIdToShowIme(DEVICE_ID_DEFAULT);
 
-        final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
+        final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
         settings.putSelectedDefaultDeviceInputMethod(null);
 
         InputMethodInfo imi = settings.getMethodMap().get(newDefaultIme);
@@ -5503,7 +5462,7 @@
                 }
             }
         }
-        setSelectedInputMethodAndSubtypeLocked(imi, lastSubtypeId, false);
+        setSelectedInputMethodAndSubtypeLocked(imi, lastSubtypeId, false, userId);
     }
 
     /**
@@ -5520,54 +5479,13 @@
                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
         }
         synchronized (ImfLock.class) {
-            if (mCurrentUserId == userId) {
-                // TODO(b/347083680): The method below has questionable behaviors.
-                return getCurrentInputMethodSubtypeLocked();
-            }
-
-            return InputMethodSettingsRepository.get(userId)
-                    .getCurrentInputMethodSubtypeForNonCurrentUsers();
+            final var bindingController = getInputMethodBindingController(userId);
+            // TODO(b/347083680): The method below has questionable behaviors.
+            return bindingController.getCurrentInputMethodSubtype();
         }
     }
 
     /**
-     * Returns the current {@link InputMethodSubtype} for the current user.
-     *
-     * <p>CAVEATS: You must also update
-     * {@link InputMethodSettings#getCurrentInputMethodSubtypeForNonCurrentUsers()}
-     * when you update the algorithm of this method.</p>
-     *
-     * <p>TODO: Address code duplication between this and
-     * {@link InputMethodSettings#getCurrentInputMethodSubtypeForNonCurrentUsers()}.</p>
-     *
-     * <p>Also this method has had questionable behaviors:</p>
-     * <ul>
-     *     <li>Calling this method can update {@link #mCurrentSubtype}.</li>
-     *     <li>This method may return {@link #mCurrentSubtype} as-is, even if it does not belong
-     *         to the current IME.</li>
-     * </ul>
-     * <p>TODO(b/347083680): Address above issues.</p>
-     */
-    @GuardedBy("ImfLock.class")
-    InputMethodSubtype getCurrentInputMethodSubtypeLocked() {
-        final int userId = mCurrentUserId;
-        final var selectedMethodId = getInputMethodBindingController(userId).getSelectedMethodId();
-        if (selectedMethodId == null) {
-            return null;
-        }
-        final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
-        final InputMethodInfo imi = settings.getMethodMap().get(selectedMethodId);
-        if (imi == null || imi.getSubtypeCount() == 0) {
-            return null;
-        }
-        final var bindingController = getInputMethodBindingController(userId);
-        final var subtype = SubtypeUtils.getCurrentInputMethodSubtype(imi, settings,
-                bindingController.getCurrentSubtype());
-        bindingController.setCurrentSubtype(subtype);
-        return subtype;
-    }
-
-    /**
      * Returns the default {@link InputMethodInfo} for the specific userId.
      *
      * @param userId user ID to query
@@ -5581,13 +5499,13 @@
     @GuardedBy("ImfLock.class")
     private boolean switchToInputMethodLocked(String imeId, @UserIdInt int userId) {
         final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
-        if (userId == mCurrentUserId) {
+        if (mConcurrentMultiUserModeEnabled || userId == mCurrentUserId) {
             if (!settings.getMethodMap().containsKey(imeId)
                     || !settings.getEnabledInputMethodList()
                     .contains(settings.getMethodMap().get(imeId))) {
                 return false; // IME is not found or not enabled.
             }
-            setInputMethodLocked(imeId, NOT_A_SUBTYPE_ID);
+            setInputMethodLocked(imeId, NOT_A_SUBTYPE_ID, userId);
             return true;
         }
         if (!settings.getMethodMap().containsKey(imeId)
@@ -5629,20 +5547,20 @@
     }
 
     @GuardedBy("ImfLock.class")
-    private void switchKeyboardLayoutLocked(int direction) {
-        final int userId = mCurrentUserId;
+    private void switchKeyboardLayoutLocked(int direction, @UserIdInt int userId) {
         final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
 
-        final InputMethodInfo currentImi = settings.getMethodMap().get(getSelectedMethodIdLocked());
+        final var bindingController = getInputMethodBindingController(userId);
+        final InputMethodInfo currentImi = settings.getMethodMap().get(
+                bindingController.getSelectedMethodId());
         if (currentImi == null) {
             return;
         }
-        final var bindingController = getInputMethodBindingController(userId);
         final InputMethodSubtypeHandle currentSubtypeHandle =
                 InputMethodSubtypeHandle.of(currentImi, bindingController.getCurrentSubtype());
         final InputMethodSubtypeHandle nextSubtypeHandle =
-                mHardwareKeyboardShortcutController.onSubtypeSwitch(currentSubtypeHandle,
-                        direction > 0);
+                getUserData(userId).mHardwareKeyboardShortcutController.onSubtypeSwitch(
+                        currentSubtypeHandle, direction > 0);
         if (nextSubtypeHandle == null) {
             return;
         }
@@ -5654,7 +5572,7 @@
         final int subtypeCount = nextImi.getSubtypeCount();
         if (subtypeCount == 0) {
             if (nextSubtypeHandle.equals(InputMethodSubtypeHandle.of(nextImi, null))) {
-                setInputMethodLocked(nextImi.getId(), NOT_A_SUBTYPE_ID);
+                setInputMethodLocked(nextImi.getId(), NOT_A_SUBTYPE_ID, userId);
             }
             return;
         }
@@ -5662,14 +5580,19 @@
         for (int i = 0; i < subtypeCount; ++i) {
             if (nextSubtypeHandle.equals(
                     InputMethodSubtypeHandle.of(nextImi, nextImi.getSubtypeAt(i)))) {
-                setInputMethodLocked(nextImi.getId(), i);
+                setInputMethodLocked(nextImi.getId(), i, userId);
                 return;
             }
         }
     }
 
     private void publishLocalService() {
-        LocalServices.addService(InputMethodManagerInternal.class, new LocalServiceImpl());
+        LocalServices.addService(InputMethodManagerInternal.class, mInputMethodManagerInternal);
+    }
+
+    // TODO(b/352228316): Remove it once IMMIProxy is removed.
+    InputMethodManagerInternal getLocalService(){
+        return mInputMethodManagerInternal;
     }
 
     private final class LocalServiceImpl extends InputMethodManagerInternal {
@@ -5732,7 +5655,7 @@
                     return false; // IME is not found.
                 }
                 if (userId == mCurrentUserId) {
-                    setInputMethodEnabledLocked(imeId, enabled);
+                    setInputMethodEnabledLocked(imeId, enabled, userId);
                     return true;
                 }
                 if (enabled) {
@@ -5779,7 +5702,8 @@
             //TODO(b/150843766): Check if Input Token is valid.
             final IBinder curHostInputToken;
             synchronized (ImfLock.class) {
-                if (displayId != getCurTokenDisplayIdLocked()) {
+                final var bindingController = getInputMethodBindingController(userId);
+                if (displayId != bindingController.getCurTokenDisplayId()) {
                     return false;
                 }
                 curHostInputToken = getInputMethodBindingController(userId).getCurHostInputToken();
@@ -5793,7 +5717,10 @@
         @Override
         public void reportImeControl(@Nullable IBinder windowToken) {
             synchronized (ImfLock.class) {
-                if (mImeBindingState.mFocusedWindow != windowToken) {
+                // TODO(b/305849394): Need to infer userId or get userId from callers.
+                final int userId = mCurrentUserId;
+                final var userData = getUserData(userId);
+                if (userData.mImeBindingState.mFocusedWindow != windowToken) {
                     // A perceptible value was set for the focused window, but it is no longer in
                     // control, so we reset the perceptible for the window passed as argument.
                     // TODO(b/314149476): Investigate whether this logic is still relevant, if not
@@ -5806,10 +5733,13 @@
         @Override
         public void onImeParentChanged(int displayId) {
             synchronized (ImfLock.class) {
+                // TODO(b/305849394): Need to infer userId or get userId from callers.
+                final int userId = mCurrentUserId;
+                final var userData = getUserData(userId);
                 // 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 != mImeBindingState.mFocusedWindow) {
+                if (mLastImeTargetWindow != userData.mImeBindingState.mFocusedWindow) {
                     mMenuController.hideInputMethodMenuLocked();
                 }
             }
@@ -5832,33 +5762,36 @@
         public void onSessionForAccessibilityCreated(int accessibilityConnectionId,
                 IAccessibilityInputMethodSession session, @UserIdInt int userId) {
             synchronized (ImfLock.class) {
-                final var bindingController = getInputMethodBindingController(mCurrentUserId);
+                final var bindingController = getInputMethodBindingController(userId);
+                final var userData = getUserData(userId);
                 // TODO(b/305829876): Implement user ID verification
-                if (mCurClient != null) {
-                    clearClientSessionForAccessibilityLocked(mCurClient, accessibilityConnectionId);
-                    mCurClient.mAccessibilitySessions.put(
+                if (userData.mCurClient != null) {
+                    clearClientSessionForAccessibilityLocked(userData.mCurClient,
+                            accessibilityConnectionId);
+                    userData.mCurClient.mAccessibilitySessions.put(
                             accessibilityConnectionId,
-                            new AccessibilitySessionState(mCurClient,
+                            new AccessibilitySessionState(userData.mCurClient,
                                     accessibilityConnectionId,
                                     session));
 
                     attachNewAccessibilityLocked(StartInputReason.SESSION_CREATED_BY_ACCESSIBILITY,
-                            true);
+                            true, userId);
 
-                    final SessionState sessionState = mCurClient.mCurSession;
+                    final SessionState sessionState = userData.mCurClient.mCurSession;
                     final IInputMethodSession imeSession = sessionState == null
                             ? null : sessionState.mSession;
                     final SparseArray<IAccessibilityInputMethodSession>
                             accessibilityInputMethodSessions =
                             createAccessibilityInputMethodSessions(
-                                    mCurClient.mAccessibilitySessions);
+                                    userData.mCurClient.mAccessibilitySessions);
                     final InputBindResult res = new InputBindResult(
                             InputBindResult.ResultCode.SUCCESS_WITH_ACCESSIBILITY_SESSION,
                             imeSession, accessibilityInputMethodSessions, /* channel= */ null,
                             bindingController.getCurId(),
                             bindingController.getSequenceNumber(),
                             /* isInputMethodSuppressingSpellChecker= */ false);
-                    mCurClient.mClient.onBindAccessibilityService(res, accessibilityConnectionId);
+                    userData.mCurClient.mClient.onBindAccessibilityService(res,
+                            accessibilityConnectionId);
                 }
             }
         }
@@ -5867,33 +5800,34 @@
         public void unbindAccessibilityFromCurrentClient(int accessibilityConnectionId,
                 @UserIdInt int userId) {
             synchronized (ImfLock.class) {
-                final var bindingController = getInputMethodBindingController(mCurrentUserId);
+                final var bindingController = getInputMethodBindingController(userId);
+                final var userData = getUserData(userId);
                 // TODO(b/305829876): Implement user ID verification
-                if (mCurClient != null) {
+                if (userData.mCurClient != null) {
                     if (DEBUG) {
                         Slog.v(TAG, "unbindAccessibilityFromCurrentClientLocked: client="
-                                + mCurClient.mClient.asBinder());
+                                + userData.mCurClient.mClient.asBinder());
                     }
                     // A11yManagerService unbinds the disabled accessibility service. We don't need
                     // to do it here.
-                    mCurClient.mClient.onUnbindAccessibilityService(
+                    userData.mCurClient.mClient.onUnbindAccessibilityService(
                             bindingController.getSequenceNumber(),
                             accessibilityConnectionId);
                 }
                 // We only have sessions when we bound to an input method. Remove this session
                 // from all clients.
-                if (getCurMethodLocked() != null) {
+                if (bindingController.getCurMethod() != null) {
                     // TODO(b/324907325): Remove the suppress warnings once b/324907325 is fixed.
                     @SuppressWarnings("GuardedBy") Consumer<ClientState> clearClientSession =
                             c -> clearClientSessionForAccessibilityLocked(c,
                                     accessibilityConnectionId);
                     mClientController.forAllClients(clearClientSession);
 
-                    AccessibilitySessionState session = mEnabledAccessibilitySessions.get(
+                    AccessibilitySessionState session = userData.mEnabledAccessibilitySessions.get(
                             accessibilityConnectionId);
                     if (session != null) {
                         finishSessionForAccessibilityLocked(session);
-                        mEnabledAccessibilitySessions.remove(accessibilityConnectionId);
+                        userData.mEnabledAccessibilitySessions.remove(accessibilityConnectionId);
                     }
                 }
             }
@@ -5910,14 +5844,15 @@
         public void onSwitchKeyboardLayoutShortcut(int direction, int displayId,
                 IBinder targetWindowToken) {
             synchronized (ImfLock.class) {
-                switchKeyboardLayoutLocked(direction);
+                // TODO(b/305849394): Infer userId from displayId
+                switchKeyboardLayoutLocked(direction, mCurrentUserId);
             }
         }
     }
 
     @BinderThread
     private IInputContentUriToken createInputContentUriToken(@Nullable IBinder token,
-            @Nullable Uri contentUri, @Nullable String packageName) {
+            @Nullable Uri contentUri, @Nullable String packageName, @UserIdInt int imeUserId) {
         if (token == null) {
             throw new NullPointerException("token");
         }
@@ -5934,15 +5869,6 @@
 
         synchronized (ImfLock.class) {
             final int uid = Binder.getCallingUid();
-            final int imeUserId = UserHandle.getUserId(uid);
-            if (imeUserId != mCurrentUserId) {
-                // Currently concurrent multi-user is not supported here due to the remaining
-                // dependency on mCurEditorInfo and mCurClient.
-                // TODO(b/341558132): Remove this early-exit once it becomes multi-user ready.
-                Slog.i(TAG, "Ignoring createInputContentUriToken due to user ID mismatch."
-                        + " imeUserId=" + imeUserId + " mCurrentUserId=" + mCurrentUserId);
-                return null;
-            }
             final var bindingController = getInputMethodBindingController(imeUserId);
             if (bindingController.getSelectedMethodId() == null) {
                 return null;
@@ -5955,16 +5881,16 @@
             // We cannot simply distinguish a bad IME that reports an arbitrary package name from
             // an unfortunate IME whose internal state is already obsolete due to the asynchronous
             // nature of our system.  Let's compare it with our internal record.
-            // TODO(b/341558132): Use "imeUserId" to query per-user "curEditorInfo"
-            final var curPackageName = mCurEditorInfo != null ? mCurEditorInfo.packageName : null;
+            final var userData = getUserData(imeUserId);
+            final var curPackageName = userData.mCurEditorInfo != null
+                    ? userData.mCurEditorInfo.packageName : null;
             if (!TextUtils.equals(curPackageName, packageName)) {
                 Slog.e(TAG, "Ignoring createInputContentUriToken mCurEditorInfo.packageName="
                         + curPackageName + " packageName=" + packageName);
                 return null;
             }
             // This user ID can never be spoofed.
-            // TODO(b/341558132): Use "imeUserId" to query per-user "curClient"
-            final int appUserId = UserHandle.getUserId(mCurClient.mUid);
+            final int appUserId = UserHandle.getUserId(userData.mCurClient.mUid);
             // This user ID may be invalid if "contentUri" embedded an invalid user ID.
             final int contentUriOwnerUserId = ContentProvider.getUserIdFromUri(contentUri,
                     imeUserId);
@@ -5981,14 +5907,16 @@
     }
 
     @BinderThread
-    private void reportFullscreenMode(@NonNull IBinder token, boolean fullscreen) {
+    private void reportFullscreenMode(@NonNull IBinder token, boolean fullscreen,
+            @UserIdInt int userId) {
         synchronized (ImfLock.class) {
-            if (!calledWithValidTokenLocked(token)) {
+            if (!calledWithValidTokenLocked(token, userId)) {
                 return;
             }
-            if (mCurClient != null && mCurClient.mClient != null) {
-                mInFullscreenMode = fullscreen;
-                mCurClient.mClient.reportFullscreenMode(fullscreen);
+            final var userData = getUserData(userId);
+            if (userData.mCurClient != null && userData.mCurClient.mClient != null) {
+                userData.mInFullscreenMode = fullscreen;
+                userData.mCurClient.mClient.reportFullscreenMode(fullscreen);
             }
         }
     }
@@ -6081,7 +6009,9 @@
         final Printer p = new PrintWriterPrinter(pw);
 
         synchronized (ImfLock.class) {
-            final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
+            final int userId = mCurrentUserId;
+            final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
+            final var userData = getUserData(userId);
             p.println("Current Input Method Manager state:");
             final List<InputMethodInfo> methodList = settings.getMethodList();
             int numImes = methodList.size();
@@ -6111,16 +6041,16 @@
             mClientController.forAllClients(clientControllerDump);
             final var bindingController = getInputMethodBindingController(mCurrentUserId);
             p.println("  mCurrentUserId=" + mCurrentUserId);
-            p.println("  mCurMethodId=" + getSelectedMethodIdLocked());
-            client = mCurClient;
+            p.println("  mCurMethodId=" + bindingController.getSelectedMethodId());
+            client = userData.mCurClient;
             p.println("  mCurClient=" + client + " mCurSeq="
                     + bindingController.getSequenceNumber());
             p.println("  mFocusedWindowPerceptible=" + mFocusedWindowPerceptible);
-            mImeBindingState.dump(/* prefix= */ "  ", p);
+            userData.mImeBindingState.dump(/* prefix= */ "  ", p);
 
             p.println("  mCurId=" + bindingController.getCurId()
                     + " mHaveConnection=" + bindingController.hasMainConnection()
-                    + " mBoundToMethod=" + mBoundToMethod + " mVisibleBound="
+                    + " mBoundToMethod=" + userData.mBoundToMethod + " mVisibleBound="
                     + bindingController.isVisibleBound());
 
             p.println("  mUserDataRepository=");
@@ -6131,28 +6061,40 @@
                         p.println("      hasMainConnection="
                                 + u.mBindingController.hasMainConnection());
                         p.println("      isVisibleBound=" + u.mBindingController.isVisibleBound());
+                        p.println("      boundToMethod=" + u.mBoundToMethod);
+                        p.println("      curClient=" + u.mCurClient);
+                        if (u.mCurEditorInfo != null) {
+                            p.println("      curEditorInfo:");
+                            u.mCurEditorInfo.dump(p, "        ", false /* dumpExtras */);
+                        } else {
+                            p.println("      curEditorInfo: null");
+                        }
+                        p.println("      imeBindingState:");
+                        u.mImeBindingState.dump("        ", p);
+                        p.println("      enabledSession=" + u.mEnabledSession);
+                        p.println("      inFullscreenMode=" + u.mInFullscreenMode);
+                        p.println("      switchingController:");
+                        u.mSwitchingController.dump(p, "        ");
+                        p.println("      mLastEnabledInputMethodsStr="
+                                + u.mLastEnabledInputMethodsStr);
                     };
             mUserDataRepository.forAllUserData(userDataDump);
 
-            p.println("  mCurToken=" + getCurTokenLocked());
-            p.println("  mCurTokenDisplayId=" + getCurTokenDisplayIdLocked());
+            p.println("  mCurToken=" + bindingController.getCurToken());
+            p.println("  mCurTokenDisplayId=" + bindingController.getCurTokenDisplayId());
             p.println("  mCurHostInputToken=" + bindingController.getCurHostInputToken());
             p.println("  mCurIntent=" + bindingController.getCurIntent());
-            method = getCurMethodLocked();
-            p.println("  mCurMethod=" + getCurMethodLocked());
-            p.println("  mEnabledSession=" + mEnabledSession);
+            method = bindingController.getCurMethod();
+            p.println("  mCurMethod=" + method);
+            p.println("  mEnabledSession=" + userData.mEnabledSession);
             mVisibilityStateComputer.dump(pw, "  ");
-            p.println("  mInFullscreenMode=" + mInFullscreenMode);
+            p.println("  mInFullscreenMode=" + userData.mInFullscreenMode);
             p.println("  mSystemReady=" + mSystemReady + " mInteractive=" + mIsInteractive);
-            p.println("  mExperimentalConcurrentMultiUserModeEnabled="
-                    + mExperimentalConcurrentMultiUserModeEnabled);
+            p.println("  mConcurrentMultiUserModeEnabled=" + mConcurrentMultiUserModeEnabled);
             p.println("  ENABLE_HIDE_IME_CAPTION_BAR="
                     + InputMethodService.ENABLE_HIDE_IME_CAPTION_BAR);
-            p.println("  mSettingsObserver=" + mSettingsObserver);
             p.println("  mStylusIds=" + (mStylusIds != null
                     ? Arrays.toString(mStylusIds.toArray()) : ""));
-            p.println("  mSwitchingController:");
-            mSwitchingController.dump(p, "    ");
 
             p.println("  mStartInputHistory:");
             mStartInputHistory.dump(pw, "    ");
@@ -6180,20 +6122,24 @@
         } else {
             p.println("No input method client.");
         }
-
-        if (mImeBindingState.mFocusedWindowClient != null
-                && client != mImeBindingState.mFocusedWindowClient) {
-            p.println(" ");
-            p.println("Warning: Current input method client doesn't match the last focused. "
-                    + "window.");
-            p.println("Dumping input method client in the last focused window just in case.");
-            p.println(" ");
-            pw.flush();
-            try {
-                TransferPipe.dumpAsync(
-                        mImeBindingState.mFocusedWindowClient.mClient.asBinder(), fd, args);
-            } catch (IOException | RemoteException e) {
-                p.println("Failed to dump input method client in focused window: " + e);
+        synchronized (ImfLock.class) {
+            final int userId = mCurrentUserId;
+            final var userData = getUserData(userId);
+            if (userData.mImeBindingState.mFocusedWindowClient != null
+                    && client != userData.mImeBindingState.mFocusedWindowClient) {
+                p.println(" ");
+                p.println("Warning: Current input method client doesn't match the last focused. "
+                        + "window.");
+                p.println("Dumping input method client in the last focused window just in case.");
+                p.println(" ");
+                pw.flush();
+                try {
+                    TransferPipe.dumpAsync(
+                            userData.mImeBindingState.mFocusedWindowClient.mClient.asBinder(), fd,
+                            args);
+                } catch (IOException | RemoteException e) {
+                    p.println("Failed to dump input method client in focused window: " + e);
+                }
             }
         }
 
@@ -6517,7 +6463,7 @@
             if (enabled && !settings.getMethodMap().containsKey(imeId)) {
                 failedToEnableUnknownIme = true;
             } else {
-                previouslyEnabled = setInputMethodEnabledLocked(imeId, enabled);
+                previouslyEnabled = setInputMethodEnabledLocked(imeId, enabled, userId);
             }
         } else {
             if (enabled) {
@@ -6629,18 +6575,21 @@
                     final List<InputMethodInfo> nextEnabledImes;
                     final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
                     if (userId == mCurrentUserId) {
+                        final var userData = getUserData(userId);
                         if (Flags.refactorInsetsController()) {
-                            if (mImeBindingState != null
-                                    && mImeBindingState.mFocusedWindowClient != null
-                                    && mImeBindingState.mFocusedWindowClient.mClient != null) {
-                                mImeBindingState.mFocusedWindowClient.mClient.setImeVisibility(
-                                        false);
+                            if (userData.mImeBindingState != null
+                                    && userData.mImeBindingState.mFocusedWindowClient != null
+                                    && userData.mImeBindingState.mFocusedWindowClient.mClient
+                                    != null) {
+                                userData.mImeBindingState.mFocusedWindowClient.mClient
+                                        .setImeVisibility(false);
                             } else {
                                 // TODO(b329229469): ImeTracker?
                             }
                         } else {
-                            hideCurrentInputLocked(mImeBindingState.mFocusedWindow, 0 /* flags */,
-                                    SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND);
+                            hideCurrentInputLocked(userData.mImeBindingState.mFocusedWindow,
+                                    0 /* flags */,
+                                    SoftInputShowHideReason.HIDE_RESET_SHELL_COMMAND, userId);
                         }
                         final var bindingController = getInputMethodBindingController(userId);
                         bindingController.unbindCurrentMethod();
@@ -6651,16 +6600,16 @@
                                 mContext, settings.getMethodList());
                         toDisable.removeAll(defaultEnabled);
                         for (InputMethodInfo info : toDisable) {
-                            setInputMethodEnabledLocked(info.getId(), false);
+                            setInputMethodEnabledLocked(info.getId(), false, userId);
                         }
                         for (InputMethodInfo info : defaultEnabled) {
-                            setInputMethodEnabledLocked(info.getId(), true);
+                            setInputMethodEnabledLocked(info.getId(), true, userId);
                         }
                         // Choose new default IME, reset to none if no IME available.
-                        if (!chooseNewDefaultIMELocked()) {
-                            resetSelectedInputMethodAndSubtypeLocked(null);
+                        if (!chooseNewDefaultIMELocked(userId)) {
+                            resetSelectedInputMethodAndSubtypeLocked(null, userId);
                         }
-                        updateInputMethodsFromSettingsLocked(true /* enabledMayChange */);
+                        updateInputMethodsFromSettingsLocked(true /* enabledMayChange */, userId);
                         InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(
                                 getPackageManagerForUser(mContext, settings.getUserId()),
                                 settings.getEnabledInputMethodList());
@@ -6769,13 +6718,15 @@
      * @param reason the reason why the IME request was created
      */
     @NonNull
+    @GuardedBy("ImfLock.class")
     private ImeTracker.Token createStatsTokenForFocusedClient(boolean show,
-            @SoftInputShowHideReason int reason) {
-        final int uid = mImeBindingState.mFocusedWindowClient != null
-                ? mImeBindingState.mFocusedWindowClient.mUid
+            @SoftInputShowHideReason int reason, @UserIdInt int userId) {
+        final var userData = getUserData(userId);
+        final int uid = userData.mImeBindingState.mFocusedWindowClient != null
+                ? userData.mImeBindingState.mFocusedWindowClient.mUid
                 : -1;
-        final var packageName = mImeBindingState.mFocusedWindowEditorInfo != null
-                ? mImeBindingState.mFocusedWindowEditorInfo.packageName
+        final var packageName = userData.mImeBindingState.mFocusedWindowEditorInfo != null
+                ? userData.mImeBindingState.mFocusedWindowEditorInfo.packageName
                 : "uid(" + uid + ")";
 
         return ImeTracker.forLogging().onStart(packageName, uid,
@@ -6788,23 +6739,26 @@
         private final InputMethodManagerService mImms;
         @NonNull
         private final IBinder mToken;
+        @UserIdInt
+        private final int mUserId;
 
         InputMethodPrivilegedOperationsImpl(InputMethodManagerService imms,
-                @NonNull IBinder token) {
+                @NonNull IBinder token, @UserIdInt int userId) {
             mImms = imms;
             mToken = token;
+            mUserId = userId;
         }
 
         @BinderThread
         @Override
         public void setImeWindowStatusAsync(int vis, int backDisposition) {
-            mImms.setImeWindowStatus(mToken, vis, backDisposition);
+            mImms.setImeWindowStatus(mToken, vis, backDisposition, mUserId);
         }
 
         @BinderThread
         @Override
         public void reportStartInputAsync(IBinder startInputToken) {
-            mImms.reportStartInput(mToken, startInputToken);
+            mImms.reportStartInput(mToken, startInputToken, mUserId);
         }
 
         @BinderThread
@@ -6820,7 +6774,7 @@
             @SuppressWarnings("unchecked") final AndroidFuture<IBinder> typedFuture = future;
             try {
                 typedFuture.complete(mImms.createInputContentUriToken(
-                        mToken, contentUri, packageName).asBinder());
+                        mToken, contentUri, packageName, mUserId).asBinder());
             } catch (Throwable e) {
                 typedFuture.completeExceptionally(e);
             }
@@ -6829,7 +6783,7 @@
         @BinderThread
         @Override
         public void reportFullscreenModeAsync(boolean fullscreen) {
-            mImms.reportFullscreenMode(mToken, fullscreen);
+            mImms.reportFullscreenMode(mToken, fullscreen, mUserId);
         }
 
         @BinderThread
@@ -6837,7 +6791,7 @@
         public void setInputMethod(String id, AndroidFuture future /* T=Void */) {
             @SuppressWarnings("unchecked") final AndroidFuture<Void> typedFuture = future;
             try {
-                mImms.setInputMethod(mToken, id);
+                mImms.setInputMethod(mToken, id, mUserId);
                 typedFuture.complete(null);
             } catch (Throwable e) {
                 typedFuture.completeExceptionally(e);
@@ -6850,7 +6804,7 @@
                 AndroidFuture future /* T=Void */) {
             @SuppressWarnings("unchecked") final AndroidFuture<Void> typedFuture = future;
             try {
-                mImms.setInputMethodAndSubtype(mToken, id, subtype);
+                mImms.setInputMethodAndSubtype(mToken, id, subtype, mUserId);
                 typedFuture.complete(null);
             } catch (Throwable e) {
                 typedFuture.completeExceptionally(e);
@@ -6864,7 +6818,7 @@
                 AndroidFuture future /* T=Void */) {
             @SuppressWarnings("unchecked") final AndroidFuture<Void> typedFuture = future;
             try {
-                mImms.hideMySoftInput(mToken, statsToken, flags, reason);
+                mImms.hideMySoftInput(mToken, statsToken, flags, reason, mUserId);
                 typedFuture.complete(null);
             } catch (Throwable e) {
                 typedFuture.completeExceptionally(e);
@@ -6878,7 +6832,7 @@
                 AndroidFuture future /* T=Void */) {
             @SuppressWarnings("unchecked") final AndroidFuture<Void> typedFuture = future;
             try {
-                mImms.showMySoftInput(mToken, statsToken, flags, reason);
+                mImms.showMySoftInput(mToken, statsToken, flags, reason, mUserId);
                 typedFuture.complete(null);
             } catch (Throwable e) {
                 typedFuture.completeExceptionally(e);
@@ -6888,7 +6842,7 @@
         @BinderThread
         @Override
         public void updateStatusIconAsync(String packageName, @DrawableRes int iconId) {
-            mImms.updateStatusIcon(mToken, packageName, iconId);
+            mImms.updateStatusIcon(mToken, packageName, iconId, mUserId);
         }
 
         @BinderThread
@@ -6896,7 +6850,7 @@
         public void switchToPreviousInputMethod(AndroidFuture future /* T=Boolean */) {
             @SuppressWarnings("unchecked") final AndroidFuture<Boolean> typedFuture = future;
             try {
-                typedFuture.complete(mImms.switchToPreviousInputMethod(mToken));
+                typedFuture.complete(mImms.switchToPreviousInputMethod(mToken, mUserId));
             } catch (Throwable e) {
                 typedFuture.completeExceptionally(e);
             }
@@ -6908,7 +6862,8 @@
                 AndroidFuture future /* T=Boolean */) {
             @SuppressWarnings("unchecked") final AndroidFuture<Boolean> typedFuture = future;
             try {
-                typedFuture.complete(mImms.switchToNextInputMethod(mToken, onlyCurrentIme));
+                typedFuture.complete(mImms.switchToNextInputMethod(mToken, onlyCurrentIme,
+                        mUserId));
             } catch (Throwable e) {
                 typedFuture.completeExceptionally(e);
             }
@@ -6919,7 +6874,7 @@
         public void shouldOfferSwitchingToNextInputMethod(AndroidFuture future /* T=Boolean */) {
             @SuppressWarnings("unchecked") final AndroidFuture<Boolean> typedFuture = future;
             try {
-                typedFuture.complete(mImms.shouldOfferSwitchingToNextInputMethod(mToken));
+                typedFuture.complete(mImms.shouldOfferSwitchingToNextInputMethod(mToken, mUserId));
             } catch (Throwable e) {
                 typedFuture.completeExceptionally(e);
             }
@@ -6928,20 +6883,20 @@
         @BinderThread
         @Override
         public void notifyUserActionAsync() {
-            mImms.notifyUserAction(mToken);
+            mImms.notifyUserAction(mToken, mUserId);
         }
 
         @BinderThread
         @Override
         public void applyImeVisibilityAsync(IBinder windowToken, boolean setVisible,
                 @NonNull ImeTracker.Token statsToken) {
-            mImms.applyImeVisibility(mToken, windowToken, setVisible, statsToken);
+            mImms.applyImeVisibility(mToken, windowToken, setVisible, statsToken, mUserId);
         }
 
         @BinderThread
         @Override
         public void onStylusHandwritingReady(int requestId, int pid) {
-            mImms.onStylusHandwritingReady(requestId, pid);
+            mImms.onStylusHandwritingReady(requestId, pid, mUserId);
         }
 
         @BinderThread
@@ -6954,12 +6909,12 @@
         @Override
         public void switchKeyboardLayoutAsync(int direction) {
             synchronized (ImfLock.class) {
-                if (!mImms.calledWithValidTokenLocked(mToken)) {
+                if (!mImms.calledWithValidTokenLocked(mToken, mUserId)) {
                     return;
                 }
                 final long ident = Binder.clearCallingIdentity();
                 try {
-                    mImms.switchKeyboardLayoutLocked(direction);
+                    mImms.switchKeyboardLayoutLocked(direction, mUserId);
                 } finally {
                     Binder.restoreCallingIdentity(ident);
                 }
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
index 326ef7e..656c87d 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java
@@ -79,16 +79,17 @@
         if (DEBUG) Slog.v(TAG, "Show switching menu. showAuxSubtypes=" + showAuxSubtypes);
 
         final int userId = mService.getCurrentImeUserIdLocked();
+        final var bindingController = mService.getInputMethodBindingController(userId);
 
         hideInputMethodMenuLocked();
 
         if (preferredInputMethodSubtypeId == NOT_A_SUBTYPE_ID) {
             final InputMethodSubtype currentSubtype =
-                    mService.getCurrentInputMethodSubtypeLocked();
+                    bindingController.getCurrentInputMethodSubtype();
             if (currentSubtype != null) {
-                final String curMethodId = mService.getSelectedMethodIdLocked();
+                final String curMethodId = bindingController.getSelectedMethodId();
                 final InputMethodInfo currentImi =
-                        mService.queryInputMethodForCurrentUserLocked(curMethodId);
+                        InputMethodSettingsRepository.get(userId).getMethodMap().get(curMethodId);
                 preferredInputMethodSubtypeId = SubtypeUtils.getSubtypeIdFromHashCode(
                         currentImi, currentSubtype.hashCode());
             }
@@ -179,7 +180,7 @@
                     if (subtypeId < 0 || subtypeId >= im.getSubtypeCount()) {
                         subtypeId = NOT_A_SUBTYPE_ID;
                     }
-                    mService.setInputMethodLocked(im.getId(), subtypeId);
+                    mService.setInputMethodLocked(im.getId(), subtypeId, userId);
                 }
                 hideInputMethodMenuLocked();
             }
@@ -200,7 +201,7 @@
         attrs.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
         attrs.setTitle("Select input method");
         w.setAttributes(attrs);
-        mService.updateSystemUiLocked();
+        mService.updateSystemUiLocked(userId);
         mService.sendOnNavButtonFlagsChangedLocked();
         mSwitchingDialog.show();
     }
@@ -238,7 +239,9 @@
             mSwitchingDialog = null;
             mSwitchingDialogTitleView = null;
 
-            mService.updateSystemUiLocked();
+            // TODO(b/305849394): Make InputMethodMenuController multi-user aware
+            final int userId = mService.getCurrentImeUserIdLocked();
+            mService.updateSystemUiLocked(userId);
             mService.sendOnNavButtonFlagsChangedLocked();
             mDialogBuilder = null;
             mIms = null;
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodSettings.java b/services/core/java/com/android/server/inputmethod/InputMethodSettings.java
index 5569e1e..0152158 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodSettings.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodSettings.java
@@ -571,57 +571,6 @@
         }
     }
 
-    /**
-     * A variant of {@link InputMethodManagerService#getCurrentInputMethodSubtypeLocked()} for
-     * non-current users.
-     *
-     * <p>TODO: Address code duplication between this and
-     * {@link InputMethodManagerService#getCurrentInputMethodSubtypeLocked()}.</p>
-     *
-     * @return {@link InputMethodSubtype} if exists. {@code null} otherwise.
-     */
-    @Nullable
-    InputMethodSubtype getCurrentInputMethodSubtypeForNonCurrentUsers() {
-        final String selectedMethodId = getSelectedInputMethod();
-        if (selectedMethodId == null) {
-            return null;
-        }
-        final InputMethodInfo imi = mMethodMap.get(selectedMethodId);
-        if (imi == null || imi.getSubtypeCount() == 0) {
-            return null;
-        }
-
-        final int subtypeHashCode = getSelectedInputMethodSubtypeHashCode();
-        if (subtypeHashCode != INVALID_SUBTYPE_HASHCODE) {
-            final int subtypeIndex = SubtypeUtils.getSubtypeIdFromHashCode(imi,
-                    subtypeHashCode);
-            if (subtypeIndex >= 0) {
-                return imi.getSubtypeAt(subtypeIndex);
-            }
-        }
-
-        // If there are no selected subtypes, the framework will try to find the most applicable
-        // subtype from explicitly or implicitly enabled subtypes.
-        final List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypes =
-                getEnabledInputMethodSubtypeList(imi, true);
-        // If there is only one explicitly or implicitly enabled subtype, just returns it.
-        if (explicitlyOrImplicitlyEnabledSubtypes.isEmpty()) {
-            return null;
-        }
-        if (explicitlyOrImplicitlyEnabledSubtypes.size() == 1) {
-            return explicitlyOrImplicitlyEnabledSubtypes.get(0);
-        }
-        final String locale = SystemLocaleWrapper.get(mUserId).get(0).toString();
-        final InputMethodSubtype subtype = SubtypeUtils.findLastResortApplicableSubtype(
-                explicitlyOrImplicitlyEnabledSubtypes, SubtypeUtils.SUBTYPE_MODE_KEYBOARD,
-                locale, true);
-        if (subtype != null) {
-            return subtype;
-        }
-        return SubtypeUtils.findLastResortApplicableSubtype(
-                explicitlyOrImplicitlyEnabledSubtypes, null, locale, true);
-    }
-
     @NonNull
     AdditionalSubtypeMap getNewAdditionalSubtypeMap(@NonNull String imeId,
             @NonNull ArrayList<InputMethodSubtype> subtypes,
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java b/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
index 770e3b2..bb1b9df 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodSubtypeSwitchingController.java
@@ -16,10 +16,8 @@
 
 package com.android.server.inputmethod;
 
-import android.annotation.AnyThread;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.UserIdInt;
 import android.content.Context;
 import android.os.UserHandle;
 import android.text.TextUtils;
@@ -48,15 +46,20 @@
     private static final int NOT_A_SUBTYPE_ID = InputMethodUtils.NOT_A_SUBTYPE_ID;
 
     public static class ImeSubtypeListItem implements Comparable<ImeSubtypeListItem> {
+
+        @NonNull
         public final CharSequence mImeName;
+        @Nullable
         public final CharSequence mSubtypeName;
+        @NonNull
         public final InputMethodInfo mImi;
         public final int mSubtypeId;
         public final boolean mIsSystemLocale;
         public final boolean mIsSystemLanguage;
 
-        ImeSubtypeListItem(CharSequence imeName, CharSequence subtypeName,
-                InputMethodInfo imi, int subtypeId, String subtypeLocale, String systemLocale) {
+        ImeSubtypeListItem(@NonNull CharSequence imeName, @Nullable CharSequence subtypeName,
+                @NonNull InputMethodInfo imi, int subtypeId, @Nullable String subtypeLocale,
+                @NonNull String systemLocale) {
             mImeName = imeName;
             mSubtypeName = subtypeName;
             mImi = imi;
@@ -69,7 +72,6 @@
                 if (mIsSystemLocale) {
                     mIsSystemLanguage = true;
                 } else {
-                    // TODO: Use Locale#getLanguage or Locale#toLanguageTag
                     final String systemLanguage = LocaleUtils.getLanguageFromLocaleString(
                             systemLocale);
                     final String subtypeLanguage = LocaleUtils.getLanguageFromLocaleString(
@@ -101,8 +103,9 @@
          *   <li>{@link #mSubtypeName}</li>
          *   <li>{@link #mImi} with {@link InputMethodInfo#getId()}</li>
          * </ol>
-         * Note: this class has a natural ordering that is inconsistent with {@link #equals(Object).
-         * This method doesn't compare {@link #mSubtypeId} but {@link #equals(Object)} does.
+         * Note: this class has a natural ordering that is inconsistent with
+         * {@link #equals(Object)}. This method doesn't compare {@link #mSubtypeId} but
+         * {@link #equals(Object)} does.
          *
          * @param other the object to be compared.
          * @return a negative integer, zero, or positive integer as this object is less than, equal
@@ -155,15 +158,15 @@
         }
     }
 
+    @NonNull
     static List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList(
             boolean includeAuxiliarySubtypes, boolean isScreenLocked, boolean forImeMenu,
-            @NonNull Context context, @NonNull InputMethodMap methodMap,
-            @UserIdInt int userId) {
+            @NonNull Context context, @NonNull InputMethodSettings settings) {
+        final int userId = settings.getUserId();
         final Context userAwareContext = context.getUserId() == userId
                 ? context
                 : context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
         final String mSystemLocaleStr = SystemLocaleWrapper.get(userId).get(0).toLanguageTag();
-        final InputMethodSettings settings = InputMethodSettings.create(methodMap, userId);
 
         final ArrayList<InputMethodInfo> imis = settings.getEnabledInputMethodList();
         if (imis.isEmpty()) {
@@ -190,7 +193,7 @@
                 enabledSubtypeSet.add(String.valueOf(subtype.hashCode()));
             }
             final CharSequence imeLabel = imi.loadLabel(userAwareContext.getPackageManager());
-            if (enabledSubtypeSet.size() > 0) {
+            if (!enabledSubtypeSet.isEmpty()) {
                 final int subtypeCount = imi.getSubtypeCount();
                 if (DEBUG) {
                     Slog.v(TAG, "Add subtypes: " + subtypeCount + ", " + imi.getId());
@@ -223,14 +226,18 @@
         return imList;
     }
 
-    private static int calculateSubtypeId(InputMethodInfo imi, InputMethodSubtype subtype) {
+    private static int calculateSubtypeId(@NonNull InputMethodInfo imi,
+            @Nullable InputMethodSubtype subtype) {
         return subtype != null ? SubtypeUtils.getSubtypeIdFromHashCode(imi, subtype.hashCode())
                 : NOT_A_SUBTYPE_ID;
     }
 
     private static class StaticRotationList {
+
+        @NonNull
         private final List<ImeSubtypeListItem> mImeSubtypeList;
-        StaticRotationList(final List<ImeSubtypeListItem> imeSubtypeList) {
+
+        StaticRotationList(@NonNull List<ImeSubtypeListItem> imeSubtypeList) {
             mImeSubtypeList = imeSubtypeList;
         }
 
@@ -242,24 +249,22 @@
          *                does not have a subtype.
          * @return The index in the given list. -1 if not found.
          */
-        private int getIndex(InputMethodInfo imi, InputMethodSubtype subtype) {
+        private int getIndex(@NonNull InputMethodInfo imi, @Nullable InputMethodSubtype subtype) {
             final int currentSubtypeId = calculateSubtypeId(imi, subtype);
             final int numSubtypes = mImeSubtypeList.size();
             for (int i = 0; i < numSubtypes; ++i) {
-                final ImeSubtypeListItem isli = mImeSubtypeList.get(i);
+                final ImeSubtypeListItem item = mImeSubtypeList.get(i);
                 // Skip until the current IME/subtype is found.
-                if (imi.equals(isli.mImi) && isli.mSubtypeId == currentSubtypeId) {
+                if (imi.equals(item.mImi) && item.mSubtypeId == currentSubtypeId) {
                     return i;
                 }
             }
             return -1;
         }
 
+        @Nullable
         public ImeSubtypeListItem getNextInputMethodLocked(boolean onlyCurrentIme,
-                InputMethodInfo imi, InputMethodSubtype subtype) {
-            if (imi == null) {
-                return null;
-            }
+                @NonNull InputMethodInfo imi, @Nullable InputMethodSubtype subtype) {
             if (mImeSubtypeList.size() <= 1) {
                 return null;
             }
@@ -282,22 +287,24 @@
             return null;
         }
 
-        protected void dump(final Printer pw, final String prefix) {
+        protected void dump(@NonNull Printer pw, @NonNull String prefix) {
             final int numSubtypes = mImeSubtypeList.size();
-            for (int i = 0; i < numSubtypes; ++i) {
-                final int rank = i;
-                final ImeSubtypeListItem item = mImeSubtypeList.get(i);
+            for (int rank = 0; rank < numSubtypes; ++rank) {
+                final ImeSubtypeListItem item = mImeSubtypeList.get(rank);
                 pw.println(prefix + "rank=" + rank + " item=" + item);
             }
         }
     }
 
     private static class DynamicRotationList {
+
         private static final String TAG = DynamicRotationList.class.getSimpleName();
+        @NonNull
         private final List<ImeSubtypeListItem> mImeSubtypeList;
+        @NonNull
         private final int[] mUsageHistoryOfSubtypeListItemIndex;
 
-        private DynamicRotationList(final List<ImeSubtypeListItem> imeSubtypeListItems) {
+        private DynamicRotationList(@NonNull List<ImeSubtypeListItem> imeSubtypeListItems) {
             mImeSubtypeList = imeSubtypeListItems;
             mUsageHistoryOfSubtypeListItemIndex = new int[mImeSubtypeList.size()];
             final int numSubtypes = mImeSubtypeList.size();
@@ -314,7 +321,8 @@
          *
          * @return -1 when the specified item doesn't belong to {@link #mImeSubtypeList} actually.
          */
-        private int getUsageRank(final InputMethodInfo imi, InputMethodSubtype subtype) {
+        private int getUsageRank(@NonNull InputMethodInfo imi,
+                @Nullable InputMethodSubtype subtype) {
             final int currentSubtypeId = calculateSubtypeId(imi, subtype);
             final int numItems = mUsageHistoryOfSubtypeListItemIndex.length;
             for (int usageRank = 0; usageRank < numItems; usageRank++) {
@@ -330,7 +338,8 @@
             return -1;
         }
 
-        public void onUserAction(InputMethodInfo imi, InputMethodSubtype subtype) {
+        public void onUserAction(@NonNull InputMethodInfo imi,
+                @Nullable InputMethodSubtype subtype) {
             final int currentUsageRank = getUsageRank(imi, subtype);
             // Do nothing if currentUsageRank == -1 (not found), or currentUsageRank == 0
             if (currentUsageRank <= 0) {
@@ -342,8 +351,9 @@
             mUsageHistoryOfSubtypeListItemIndex[0] = currentItemIndex;
         }
 
+        @Nullable
         public ImeSubtypeListItem getNextInputMethodLocked(boolean onlyCurrentIme,
-                InputMethodInfo imi, InputMethodSubtype subtype) {
+                @NonNull InputMethodInfo imi, @Nullable InputMethodSubtype subtype) {
             int currentUsageRank = getUsageRank(imi, subtype);
             if (currentUsageRank < 0) {
                 if (DEBUG) {
@@ -366,7 +376,7 @@
             return null;
         }
 
-        protected void dump(final Printer pw, final String prefix) {
+        protected void dump(@NonNull Printer pw, @NonNull String prefix) {
             for (int rank = 0; rank < mUsageHistoryOfSubtypeListItemIndex.length; ++rank) {
                 final int index = mUsageHistoryOfSubtypeListItemIndex[rank];
                 final ImeSubtypeListItem item = mImeSubtypeList.get(index);
@@ -377,58 +387,52 @@
 
     @VisibleForTesting
     public static class ControllerImpl {
+
+        @NonNull
         private final DynamicRotationList mSwitchingAwareRotationList;
+        @NonNull
         private final StaticRotationList mSwitchingUnawareRotationList;
 
-        public static ControllerImpl createFrom(final ControllerImpl currentInstance,
-                final List<ImeSubtypeListItem> sortedEnabledItems) {
-            DynamicRotationList switchingAwareRotationList = null;
-            {
-                final List<ImeSubtypeListItem> switchingAwareImeSubtypes =
-                        filterImeSubtypeList(sortedEnabledItems,
-                                true /* supportsSwitchingToNextInputMethod */);
-                if (currentInstance != null
-                        && currentInstance.mSwitchingAwareRotationList != null
-                        && Objects.equals(
-                                currentInstance.mSwitchingAwareRotationList.mImeSubtypeList,
-                                switchingAwareImeSubtypes)) {
-                    // Can reuse the current instance.
-                    switchingAwareRotationList = currentInstance.mSwitchingAwareRotationList;
-                }
-                if (switchingAwareRotationList == null) {
-                    switchingAwareRotationList = new DynamicRotationList(switchingAwareImeSubtypes);
-                }
+        @NonNull
+        public static ControllerImpl createFrom(@Nullable ControllerImpl currentInstance,
+                @NonNull List<ImeSubtypeListItem> sortedEnabledItems) {
+            final var switchingAwareImeSubtypes = filterImeSubtypeList(sortedEnabledItems,
+                    true /* supportsSwitchingToNextInputMethod */);
+            final var switchingUnawareImeSubtypes = filterImeSubtypeList(sortedEnabledItems,
+                    false /* supportsSwitchingToNextInputMethod */);
+
+            final DynamicRotationList switchingAwareRotationList;
+            if (currentInstance != null && Objects.equals(
+                    currentInstance.mSwitchingAwareRotationList.mImeSubtypeList,
+                    switchingAwareImeSubtypes)) {
+                // Can reuse the current instance.
+                switchingAwareRotationList = currentInstance.mSwitchingAwareRotationList;
+            } else {
+                switchingAwareRotationList = new DynamicRotationList(switchingAwareImeSubtypes);
             }
 
-            StaticRotationList switchingUnawareRotationList = null;
-            {
-                final List<ImeSubtypeListItem> switchingUnawareImeSubtypes = filterImeSubtypeList(
-                        sortedEnabledItems, false /* supportsSwitchingToNextInputMethod */);
-                if (currentInstance != null
-                        && currentInstance.mSwitchingUnawareRotationList != null
-                        && Objects.equals(
-                                currentInstance.mSwitchingUnawareRotationList.mImeSubtypeList,
-                                switchingUnawareImeSubtypes)) {
-                    // Can reuse the current instance.
-                    switchingUnawareRotationList = currentInstance.mSwitchingUnawareRotationList;
-                }
-                if (switchingUnawareRotationList == null) {
-                    switchingUnawareRotationList =
-                            new StaticRotationList(switchingUnawareImeSubtypes);
-                }
+            final StaticRotationList switchingUnawareRotationList;
+            if (currentInstance != null && Objects.equals(
+                    currentInstance.mSwitchingUnawareRotationList.mImeSubtypeList,
+                    switchingUnawareImeSubtypes)) {
+                // Can reuse the current instance.
+                switchingUnawareRotationList = currentInstance.mSwitchingUnawareRotationList;
+            } else {
+                switchingUnawareRotationList = new StaticRotationList(switchingUnawareImeSubtypes);
             }
 
             return new ControllerImpl(switchingAwareRotationList, switchingUnawareRotationList);
         }
 
-        private ControllerImpl(final DynamicRotationList switchingAwareRotationList,
-                final StaticRotationList switchingUnawareRotationList) {
+        private ControllerImpl(@NonNull DynamicRotationList switchingAwareRotationList,
+                @NonNull StaticRotationList switchingUnawareRotationList) {
             mSwitchingAwareRotationList = switchingAwareRotationList;
             mSwitchingUnawareRotationList = switchingUnawareRotationList;
         }
 
-        public ImeSubtypeListItem getNextInputMethod(boolean onlyCurrentIme, InputMethodInfo imi,
-                InputMethodSubtype subtype) {
+        @Nullable
+        public ImeSubtypeListItem getNextInputMethod(boolean onlyCurrentIme,
+                @Nullable InputMethodInfo imi, @Nullable InputMethodSubtype subtype) {
             if (imi == null) {
                 return null;
             }
@@ -441,18 +445,17 @@
             }
         }
 
-        public void onUserActionLocked(InputMethodInfo imi, InputMethodSubtype subtype) {
-            if (imi == null) {
-                return;
-            }
+        public void onUserActionLocked(@NonNull InputMethodInfo imi,
+                @Nullable InputMethodSubtype subtype) {
             if (imi.supportsSwitchingToNextInputMethod()) {
                 mSwitchingAwareRotationList.onUserAction(imi, subtype);
             }
         }
 
+        @NonNull
         private static List<ImeSubtypeListItem> filterImeSubtypeList(
-                final List<ImeSubtypeListItem> items,
-                final boolean supportsSwitchingToNextInputMethod) {
+                @NonNull List<ImeSubtypeListItem> items,
+                boolean supportsSwitchingToNextInputMethod) {
             final ArrayList<ImeSubtypeListItem> result = new ArrayList<>();
             final int numItems = items.size();
             for (int i = 0; i < numItems; i++) {
@@ -473,67 +476,33 @@
         }
     }
 
-    private final Context mContext;
-    @UserIdInt
-    private final int mUserId;
+    @NonNull
     private ControllerImpl mController;
 
-    private InputMethodSubtypeSwitchingController(@NonNull Context context,
-            @NonNull InputMethodMap methodMap, @UserIdInt int userId) {
-        mContext = context;
-        mUserId = userId;
-        mController = ControllerImpl.createFrom(null,
-                getSortedInputMethodAndSubtypeList(
-                        false /* includeAuxiliarySubtypes */, false /* isScreenLocked */,
-                        false /* forImeMenu */, context, methodMap, userId));
+    InputMethodSubtypeSwitchingController() {
+        mController = ControllerImpl.createFrom(null, Collections.emptyList());
     }
 
-    @NonNull
-    public static InputMethodSubtypeSwitchingController createInstanceLocked(
-            @NonNull Context context,
-            @NonNull InputMethodMap methodMap, @UserIdInt int userId) {
-        return new InputMethodSubtypeSwitchingController(context, methodMap, userId);
-    }
-
-    @AnyThread
-    @UserIdInt
-    int getUserId() {
-        return mUserId;
-    }
-
-    public void onUserActionLocked(InputMethodInfo imi, InputMethodSubtype subtype) {
-        if (mController == null) {
-            if (DEBUG) {
-                Slog.e(TAG, "mController shouldn't be null.");
-            }
-            return;
-        }
+    public void onUserActionLocked(@NonNull InputMethodInfo imi,
+            @Nullable InputMethodSubtype subtype) {
         mController.onUserActionLocked(imi, subtype);
     }
 
-    public void resetCircularListLocked(@NonNull InputMethodMap methodMap) {
+    public void resetCircularListLocked(@NonNull Context context,
+            @NonNull InputMethodSettings settings) {
         mController = ControllerImpl.createFrom(mController,
                 getSortedInputMethodAndSubtypeList(
                         false /* includeAuxiliarySubtypes */, false /* isScreenLocked */,
-                        false /* forImeMenu */, mContext, methodMap, mUserId));
+                        false /* forImeMenu */, context, settings));
     }
 
-    public ImeSubtypeListItem getNextInputMethodLocked(boolean onlyCurrentIme, InputMethodInfo imi,
-            InputMethodSubtype subtype) {
-        if (mController == null) {
-            if (DEBUG) {
-                Slog.e(TAG, "mController shouldn't be null.");
-            }
-            return null;
-        }
+    @Nullable
+    public ImeSubtypeListItem getNextInputMethodLocked(boolean onlyCurrentIme,
+            @Nullable InputMethodInfo imi, @Nullable InputMethodSubtype subtype) {
         return mController.getNextInputMethod(onlyCurrentIme, imi, subtype);
     }
 
     public void dump(@NonNull Printer pw, @NonNull String prefix) {
-        if (mController != null) {
-            mController.dump(pw, prefix);
-        } else {
-            pw.println(prefix + "mController=null");
-        }
+        mController.dump(pw, prefix);
     }
 }
diff --git a/services/core/java/com/android/server/inputmethod/SecureSettingsChangeCallback.java b/services/core/java/com/android/server/inputmethod/SecureSettingsChangeCallback.java
new file mode 100644
index 0000000..328d7c6
--- /dev/null
+++ b/services/core/java/com/android/server/inputmethod/SecureSettingsChangeCallback.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+import android.content.ContentResolver;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.ArrayMap;
+
+import java.util.Collection;
+
+/**
+ * A wrapper interface to monitor the given set of {@link Settings.Secure}.
+ */
+@FunctionalInterface
+interface SecureSettingsChangeCallback {
+    /**
+     * Called back when the value associated with {@code key} is updated.
+     *
+     * @param key a key defined in {@link Settings.Secure}
+     * @param flags flags defined in {@link ContentResolver.NotifyFlags}
+     * @param userId the user ID with which the value is associated
+     */
+    void onChange(@NonNull String key, @ContentResolver.NotifyFlags int flags,
+            @UserIdInt int userId);
+
+    /**
+     * Registers {@link SecureSettingsChangeCallback} to the given set of {@link Settings.Secure}.
+     *
+     * @param handler  {@link Handler} to be used to call back {@link #onChange(String, int, int)}
+     * @param resolver {@link ContentResolver} with which {@link Settings.Secure} will be retrieved
+     * @param keys     A set of {@link Settings.Secure} to be monitored
+     * @param callback {@link SecureSettingsChangeCallback} to be called back
+     */
+    @NonNull
+    static void register(@NonNull Handler handler, @NonNull ContentResolver resolver,
+            @NonNull String[] keys, @NonNull SecureSettingsChangeCallback callback) {
+        final ArrayMap<Uri, String> uriMapper = new ArrayMap<>();
+        for (String key : keys) {
+            uriMapper.put(Settings.Secure.getUriFor(key), key);
+        }
+        final ContentObserver observer = new ContentObserver(handler) {
+            @Override
+            public void onChange(boolean selfChange, @NonNull Collection<Uri> uris, int flags,
+                    @UserIdInt int userId) {
+                uris.forEach(uri -> {
+                    final String key = uriMapper.get(uri);
+                    if (key != null) {
+                        callback.onChange(key, flags, userId);
+                    }
+                });
+            }
+        };
+        for (Uri uri : uriMapper.keySet()) {
+            resolver.registerContentObserverAsUser(uri, false /* notifyForDescendants */, observer,
+                    UserHandle.ALL);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java b/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java
index 559b625..4764e4f 100644
--- a/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java
+++ b/services/core/java/com/android/server/inputmethod/SecureSettingsWrapper.java
@@ -44,6 +44,32 @@
     @Nullable
     private static volatile ContentResolver sContentResolver = null;
 
+    private static volatile boolean sTestMode = false;
+
+    /**
+     * Can be called from unit tests to start the test mode, where a fake implementation will be
+     * used instead.
+     *
+     * <p>The fake implementation is just an {@link ArrayMap}. By default it is empty, and the data
+     * written can be read back later.</p>
+     */
+    @AnyThread
+    static void startTestMode() {
+        sTestMode = true;
+    }
+
+    /**
+     * Can be called from unit tests to end the test mode, where a fake implementation will be used
+     * instead.
+     */
+    @AnyThread
+    static void endTestMode() {
+        synchronized (sUserMap) {
+            sUserMap.clear();
+        }
+        sTestMode = false;
+    }
+
     /**
      * Not intended to be instantiated.
      */
@@ -78,6 +104,52 @@
         int getInt(String key, int defaultValue);
     }
 
+    private static class FakeReaderWriterImpl implements ReaderWriter {
+        @GuardedBy("mNonPersistentKeyValues")
+        private final ArrayMap<String, String> mNonPersistentKeyValues = new ArrayMap<>();
+
+        @AnyThread
+        @Override
+        public void putString(String key, String value) {
+            synchronized (mNonPersistentKeyValues) {
+                mNonPersistentKeyValues.put(key, value);
+            }
+        }
+
+        @AnyThread
+        @Nullable
+        @Override
+        public String getString(String key, String defaultValue) {
+            synchronized (mNonPersistentKeyValues) {
+                if (mNonPersistentKeyValues.containsKey(key)) {
+                    final String result = mNonPersistentKeyValues.get(key);
+                    return result != null ? result : defaultValue;
+                }
+                return defaultValue;
+            }
+        }
+
+        @AnyThread
+        @Override
+        public void putInt(String key, int value) {
+            synchronized (mNonPersistentKeyValues) {
+                mNonPersistentKeyValues.put(key, String.valueOf(value));
+            }
+        }
+
+        @AnyThread
+        @Override
+        public int getInt(String key, int defaultValue) {
+            synchronized (mNonPersistentKeyValues) {
+                if (mNonPersistentKeyValues.containsKey(key)) {
+                    final String result = mNonPersistentKeyValues.get(key);
+                    return result != null ? Integer.parseInt(result) : defaultValue;
+                }
+                return defaultValue;
+            }
+        }
+    }
+
     private static class UnlockedUserImpl implements ReaderWriter {
         @UserIdInt
         private final int mUserId;
@@ -200,6 +272,9 @@
 
     private static ReaderWriter createImpl(@NonNull UserManagerInternal userManagerInternal,
             @UserIdInt int userId) {
+        if (sTestMode) {
+            return new FakeReaderWriterImpl();
+        }
         return userManagerInternal.isUserUnlockingOrUnlocked(userId)
                 ? new UnlockedUserImpl(userId, sContentResolver)
                 : new LockedUserImpl(userId, sContentResolver);
@@ -234,6 +309,9 @@
                 return readerWriter;
             }
         }
+        if (sTestMode) {
+            return putOrGet(userId, new FakeReaderWriterImpl());
+        }
         final UserManagerInternal userManagerInternal =
                 LocalServices.getService(UserManagerInternal.class);
         if (!userManagerInternal.exists(userId)) {
@@ -276,6 +354,10 @@
      */
     @AnyThread
     static void onUserStarting(@UserIdInt int userId) {
+        if (sTestMode) {
+            putOrGet(userId, new FakeReaderWriterImpl());
+            return;
+        }
         putOrGet(userId, createImpl(LocalServices.getService(UserManagerInternal.class), userId));
     }
 
@@ -286,6 +368,10 @@
      */
     @AnyThread
     static void onUserUnlocking(@UserIdInt int userId) {
+        if (sTestMode) {
+            putOrGet(userId, new FakeReaderWriterImpl());
+            return;
+        }
         final ReaderWriter readerWriter = new UnlockedUserImpl(userId, sContentResolver);
         putOrGet(userId, readerWriter);
     }
diff --git a/services/core/java/com/android/server/inputmethod/UserDataRepository.java b/services/core/java/com/android/server/inputmethod/UserDataRepository.java
index 2b19d3e..5cd980f 100644
--- a/services/core/java/com/android/server/inputmethod/UserDataRepository.java
+++ b/services/core/java/com/android/server/inputmethod/UserDataRepository.java
@@ -17,12 +17,18 @@
 package com.android.server.inputmethod;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.content.pm.UserInfo;
 import android.os.Handler;
 import android.util.SparseArray;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.ImeTracker;
+import android.window.ImeOnBackInvokedDispatcher;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.inputmethod.IRemoteAccessibilityInputConnection;
+import com.android.internal.inputmethod.IRemoteInputConnection;
 import com.android.server.pm.UserManagerInternal;
 
 import java.util.function.Consumer;
@@ -53,7 +59,8 @@
         }
     }
 
-    UserDataRepository(@NonNull Handler handler, @NonNull UserManagerInternal userManagerInternal,
+    UserDataRepository(
+            @NonNull Handler handler, @NonNull UserManagerInternal userManagerInternal,
             @NonNull IntFunction<InputMethodBindingController> bindingControllerFactory) {
         mBindingControllerFactory = bindingControllerFactory;
         userManagerInternal.addUserLifecycleListener(
@@ -67,16 +74,6 @@
                             }
                         });
                     }
-
-                    @Override
-                    public void onUserCreated(UserInfo user, Object unusedToken) {
-                        final int userId = user.id;
-                        handler.post(() -> {
-                            synchronized (ImfLock.class) {
-                                getOrCreate(userId);
-                            }
-                        });
-                    }
                 });
     }
 
@@ -88,6 +85,91 @@
         @NonNull
         final InputMethodBindingController mBindingController;
 
+        @NonNull
+        final InputMethodSubtypeSwitchingController mSwitchingController;
+
+        @NonNull
+        final HardwareKeyboardShortcutController mHardwareKeyboardShortcutController;
+
+        /**
+         * Have we called mCurMethod.bindInput()?
+         */
+        @GuardedBy("ImfLock.class")
+        boolean mBoundToMethod = false;
+
+        /**
+         * Have we called bindInput() for accessibility services?
+         */
+        @GuardedBy("ImfLock.class")
+        boolean mBoundToAccessibility;
+
+        @GuardedBy("ImfLock.class")
+        @NonNull
+        ImeBindingState mImeBindingState = ImeBindingState.newEmptyState();
+
+        @GuardedBy("ImfLock.class")
+        @Nullable
+        ClientState mCurClient = null;
+
+        @GuardedBy("ImfLock.class")
+        boolean mInFullscreenMode;
+
+        /**
+         * The {@link IRemoteInputConnection} last provided by the current client.
+         */
+        @GuardedBy("ImfLock.class")
+        @Nullable
+        IRemoteInputConnection mCurInputConnection;
+
+        /**
+         * The {@link ImeOnBackInvokedDispatcher} last provided by the current client to
+         * receive {@link android.window.OnBackInvokedCallback}s forwarded from IME.
+         */
+        @GuardedBy("ImfLock.class")
+        @Nullable
+        ImeOnBackInvokedDispatcher mCurImeDispatcher;
+
+        /**
+         * The {@link IRemoteAccessibilityInputConnection} last provided by the current client.
+         */
+        @GuardedBy("ImfLock.class")
+        @Nullable
+        IRemoteAccessibilityInputConnection mCurRemoteAccessibilityInputConnection;
+
+        /**
+         * The {@link EditorInfo} last provided by the current client.
+         */
+        @GuardedBy("ImfLock.class")
+        @Nullable
+        EditorInfo mCurEditorInfo;
+
+        /**
+         * The token tracking the current IME show request that is waiting for a connection to an
+         * IME, otherwise {@code null}.
+         */
+        @GuardedBy("ImfLock.class")
+        @Nullable
+        ImeTracker.Token mCurStatsToken;
+
+        /**
+         * Currently enabled session.
+         */
+        @GuardedBy("ImfLock.class")
+        @Nullable
+        InputMethodManagerService.SessionState mEnabledSession;
+
+        @GuardedBy("ImfLock.class")
+        @Nullable
+        SparseArray<InputMethodManagerService.AccessibilitySessionState>
+                mEnabledAccessibilitySessions = new SparseArray<>();
+
+        /**
+         * A per-user cache of {@link InputMethodSettings#getEnabledInputMethodsStr()}.
+         */
+        @GuardedBy("ImfLock.class")
+        @NonNull
+        String mLastEnabledInputMethodsStr = "";
+
         /**
          * Intended to be instantiated only from this file.
          */
@@ -95,6 +177,8 @@
                 @NonNull InputMethodBindingController bindingController) {
             mUserId = userId;
             mBindingController = bindingController;
+            mSwitchingController = new InputMethodSubtypeSwitchingController();
+            mHardwareKeyboardShortcutController = new HardwareKeyboardShortcutController();
         }
 
         @Override
diff --git a/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java b/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java
index 757c07c..41aac32 100644
--- a/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java
+++ b/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java
@@ -254,7 +254,7 @@
                 synchronized (ImfLock.class) {
                     ClientState cs = imms.getClientStateLocked(client);
                     if (cs != null) {
-                        imms.requestClientSessionLocked(cs);
+                        imms.requestClientSessionLocked(cs, userId);
                         imms.requestClientSessionForAccessibilityLocked(cs);
                     }
                 }
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 363a4a7..91a4d6f 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubClientBroker.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubClientBroker.java
@@ -1126,7 +1126,7 @@
         }
     }
 
-    private void sendHostEndpointConnectedEvent() {
+    void sendHostEndpointConnectedEvent() {
         HostEndpointInfo info = new HostEndpointInfo();
         info.hostEndpointId = (char) mHostEndPointId;
         info.packageName = mPackage;
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 b3fb147..a0aad52 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -74,13 +74,13 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.PriorityQueue;
-import java.util.Random;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
@@ -158,13 +158,11 @@
 
     // A queue of reliable message records for duplicate detection
     private final PriorityQueue<ReliableMessageRecord> mReliableMessageRecordQueue =
-            new PriorityQueue<ReliableMessageRecord>(
-                    (ReliableMessageRecord left, ReliableMessageRecord right) -> {
-                        return Long.compare(left.getTimestamp(), right.getTimestamp());
-                    });
+            new PriorityQueue<>(
+                    Comparator.comparingLong(ReliableMessageRecord::getTimestamp));
 
-    // The test mode manager that manages behaviors during test mode.
-    private final TestModeManager mTestModeManager = new TestModeManager();
+    // The test mode manager that manages behaviors during test mode
+    private final ContextHubTestModeManager mTestModeManager = new ContextHubTestModeManager();
 
     // The period of the recurring time
     private static final int PERIOD_METRIC_QUERY_DAYS = 1;
@@ -179,10 +177,10 @@
     private boolean mIsBtMainEnabled = false;
 
     // True if test mode is enabled for the Context Hub
-    private AtomicBoolean mIsTestModeEnabled = new AtomicBoolean(false);
+    private final AtomicBoolean mIsTestModeEnabled = new AtomicBoolean(false);
 
     // A hashmap used to record if a contexthub is waiting for daily query
-    private Set<Integer> mMetricQueryPendingContextHubIds =
+    private final Set<Integer> mMetricQueryPendingContextHubIds =
             Collections.newSetFromMap(new ConcurrentHashMap<Integer, Boolean>());
 
     // Lock object for sendWifiSettingUpdate()
@@ -227,25 +225,32 @@
         @Override
         public void handleNanoappMessage(short hostEndpointId, NanoAppMessage message,
                 List<String> nanoappPermissions, List<String> messagePermissions) {
-            if (Flags.reliableMessageImplementation()
+            // Only process the message normally if not using test mode manager or if
+            // the test mode manager call returned false as this indicates it did not
+            // process the message.
+            boolean useTestModeManager = Flags.reliableMessageImplementation()
                     && Flags.reliableMessageTestModeBehavior()
-                    && mIsTestModeEnabled.get()
-                    && mTestModeManager.handleNanoappMessage(mContextHubId, hostEndpointId,
-                            message, nanoappPermissions, messagePermissions)) {
-                // The TestModeManager handled the nanoapp message, so return here.
-                return;
+                    && mIsTestModeEnabled.get();
+            if (!useTestModeManager
+                    || !mTestModeManager.handleNanoappMessage(() -> {
+                        handleClientMessageCallback(mContextHubId, hostEndpointId,
+                                message, nanoappPermissions, messagePermissions);
+                    }, message)) {
+                handleClientMessageCallback(mContextHubId, hostEndpointId,
+                        message, nanoappPermissions, messagePermissions);
             }
-
-            handleClientMessageCallback(mContextHubId, hostEndpointId, message,
-                    nanoappPermissions, messagePermissions);
         }
 
         @Override
         public void handleServiceRestart() {
-            Log.i(TAG, "Starting Context Hub Service restart");
+            Log.i(TAG, "Recovering from Context Hub HAL restart...");
             initExistingCallbacks();
             resetSettings();
-            Log.i(TAG, "Finished Context Hub Service restart");
+            if (Flags.reconnectHostEndpointsAfterHalRestart()) {
+                mClientManager.forEachClientOfHub(mContextHubId,
+                        ContextHubClientBroker::sendHostEndpointConnectedEvent);
+            }
+            Log.i(TAG, "Finished recovering from Context Hub HAL restart");
         }
 
         @Override
@@ -258,8 +263,6 @@
      * Records a reliable message from a nanoapp for duplicate detection.
      */
     private static class ReliableMessageRecord {
-        public static final int TIMEOUT_NS = 1000000000;
-
         public int mContextHubId;
         public long mTimestamp;
         public int mMessageSequenceNumber;
@@ -294,65 +297,8 @@
         }
 
         public boolean isExpired() {
-            return mTimestamp + TIMEOUT_NS < SystemClock.elapsedRealtimeNanos();
-        }
-    }
-
-    /**
-     * A class to manage behaviors during test mode. This is used for testing.
-     */
-    private class TestModeManager {
-        /**
-         * Probability (in percent) of duplicating a message.
-         */
-        private static final int MESSAGE_DUPLICATION_PROBABILITY_PERCENT = 50;
-
-        /**
-         * The number of total messages to send when the duplicate event happens.
-         */
-        private static final int NUM_MESSAGES_TO_DUPLICATE = 3;
-
-        /**
-         * A probability percent for a certain event.
-         */
-        private static final int MAX_PROBABILITY_PERCENT = 100;
-
-        private Random mRandom = new Random();
-
-        /**
-         * @see ContextHubServiceCallback.handleNanoappMessage
-         * @return whether the message was handled
-         */
-        public boolean handleNanoappMessage(int contextHubId,
-                short hostEndpointId, NanoAppMessage message,
-                List<String> nanoappPermissions, List<String> messagePermissions) {
-            if (!message.isReliable()) {
-                return false;
-            }
-
-            if (Flags.reliableMessageDuplicateDetectionService()
-                && didEventHappen(MESSAGE_DUPLICATION_PROBABILITY_PERCENT)) {
-                Log.i(TAG, "[TEST MODE] Duplicating message ("
-                        + NUM_MESSAGES_TO_DUPLICATE
-                        + " sends) with message sequence number: "
-                        + message.getMessageSequenceNumber());
-                for (int i = 0; i < NUM_MESSAGES_TO_DUPLICATE; ++i) {
-                    handleClientMessageCallback(contextHubId, hostEndpointId,
-                            message, nanoappPermissions, messagePermissions);
-                }
-                return true;
-            }
-            return false;
-        }
-
-        /**
-         * Returns true if the event with percentPercent did happen.
-         *
-         * @param probabilityPercent the percent probability of the event.
-         * @return true if the event happened, false otherwise.
-         */
-        private boolean didEventHappen(int probabilityPercent) {
-            return mRandom.nextInt(MAX_PROBABILITY_PERCENT) < probabilityPercent;
+            return mTimestamp + ContextHubTransactionManager.RELIABLE_MESSAGE_TIMEOUT.toNanos()
+                    < SystemClock.elapsedRealtimeNanos();
         }
     }
 
@@ -476,7 +422,7 @@
             hubInfo = mContextHubWrapper.getHubs();
         } catch (RemoteException e) {
             Log.e(TAG, "RemoteException while getting Context Hub info", e);
-            hubInfo = new Pair(Collections.emptyList(), Collections.emptyList());
+            hubInfo = new Pair<>(Collections.emptyList(), Collections.emptyList());
         }
 
         long bootTimeNs = SystemClock.elapsedRealtimeNanos() - startTimeNs;
@@ -536,6 +482,7 @@
         for (int contextHubId : mContextHubIdToInfoMap.keySet()) {
             try {
                 mContextHubWrapper.registerExistingCallback(contextHubId);
+                Log.i(TAG, "Re-registered callback to context hub " + contextHubId);
             } catch (RemoteException e) {
                 Log.e(TAG, "RemoteException while registering existing service callback for hub "
                         + "(ID = " + contextHubId + ")", e);
@@ -647,7 +594,7 @@
         mSensorPrivacyManagerInternal.addSensorPrivacyListenerForAllUsers(
                 SensorPrivacyManager.Sensors.MICROPHONE, (userId, enabled) -> {
                     // If we are in HSUM mode, any user can change the microphone setting
-                    if (mUserManager.isHeadlessSystemUserMode() || userId == getCurrentUserId()) {
+                    if (UserManager.isHeadlessSystemUserMode() || userId == getCurrentUserId()) {
                         Log.d(TAG, "User: " + userId + " mic privacy: " + enabled);
                         sendMicrophoneDisableSettingUpdate(enabled);
                     }
@@ -720,33 +667,30 @@
 
     @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
-    public int[] getContextHubHandles() throws RemoteException {
+    public int[] getContextHubHandles() {
         super.getContextHubHandles_enforcePermission();
-
         return ContextHubServiceUtil.createPrimitiveIntArray(mContextHubIdToInfoMap.keySet());
     }
 
     @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
-    public ContextHubInfo getContextHubInfo(int contextHubHandle) throws RemoteException {
+    public ContextHubInfo getContextHubInfo(int contextHubHandle) {
         super.getContextHubInfo_enforcePermission();
-
         if (!mContextHubIdToInfoMap.containsKey(contextHubHandle)) {
             Log.e(TAG, "Invalid Context Hub handle " + contextHubHandle + " in getContextHubInfo");
             return null;
         }
-
         return mContextHubIdToInfoMap.get(contextHubHandle);
     }
 
-    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     /**
      * Returns a List of ContextHubInfo object describing the available hubs.
      *
      * @return the List of ContextHubInfo objects
      */
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
-    public List<ContextHubInfo> getContextHubs() throws RemoteException {
+    public List<ContextHubInfo> getContextHubs() {
         super.getContextHubs_enforcePermission();
 
         return mContextHubInfoList;
@@ -814,7 +758,7 @@
 
     @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
-    public int loadNanoApp(int contextHubHandle, NanoApp nanoApp) throws RemoteException {
+    public int loadNanoApp(int contextHubHandle, NanoApp nanoApp) {
         super.loadNanoApp_enforcePermission();
 
         if (mContextHubWrapper == null) {
@@ -843,7 +787,7 @@
 
     @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
-    public int unloadNanoApp(int nanoAppHandle) throws RemoteException {
+    public int unloadNanoApp(int nanoAppHandle) {
         super.unloadNanoApp_enforcePermission();
 
         if (mContextHubWrapper == null) {
@@ -870,7 +814,7 @@
 
     @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
-    public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppHandle) throws RemoteException {
+    public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppHandle) {
 
         super.getNanoAppInstanceInfo_enforcePermission();
 
@@ -880,7 +824,7 @@
     @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
     public int[] findNanoAppOnHub(
-            int contextHubHandle, NanoAppFilter filter) throws RemoteException {
+            int contextHubHandle, NanoAppFilter filter) {
 
         super.findNanoAppOnHub_enforcePermission();
 
@@ -895,20 +839,19 @@
 
         int[] retArray = new int[foundInstances.size()];
         for (int i = 0; i < foundInstances.size(); i++) {
-            retArray[i] = foundInstances.get(i).intValue();
+            retArray[i] = foundInstances.get(i);
         }
         return retArray;
     }
 
     /**
      * Performs a query at the specified hub.
-     * <p>
-     * This method should only be invoked internally by the service, either to update the service
+     *
+     * <p>This method should only be invoked internally by the service, either to update the service
      * cache or as a result of an explicit query requested by a client through the sendMessage API.
      *
      * @param contextHubId the ID of the hub to do the query
      * @return true if the query succeeded
-     * @throws IllegalStateException if the transaction queue is full
      */
     private boolean queryNanoAppsInternal(int contextHubId) {
         if (mContextHubWrapper == null) {
@@ -1003,7 +946,7 @@
             return;
         }
 
-        byte errorCode = ErrorCode.OK;
+        byte errorCode;
         synchronized (mReliableMessageRecordQueue) {
             Optional<ReliableMessageRecord> record =
                     findReliableMessageRecord(contextHubId,
@@ -1219,7 +1162,6 @@
         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.
      *
@@ -1232,10 +1174,11 @@
      * @throws IllegalStateException    if max number of clients have already registered
      * @throws NullPointerException     if clientCallback is null
      */
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
     public IContextHubClient createClient(
             int contextHubId, IContextHubClientCallback clientCallback,
-            @Nullable String attributionTag, String packageName) throws RemoteException {
+            @Nullable String attributionTag, String packageName) {
         super.createClient_enforcePermission();
 
         if (!isValidContextHubId(contextHubId)) {
@@ -1250,7 +1193,6 @@
                 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.
      *
@@ -1262,10 +1204,11 @@
      * @throws IllegalArgumentException if hubInfo does not represent a valid hub
      * @throws IllegalStateException    if there were too many registered clients at the service
      */
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
     public IContextHubClient createPendingIntentClient(
             int contextHubId, PendingIntent pendingIntent, long nanoAppId,
-            @Nullable String attributionTag) throws RemoteException {
+            @Nullable String attributionTag) {
         super.createPendingIntentClient_enforcePermission();
 
         if (!isValidContextHubId(contextHubId)) {
@@ -1277,15 +1220,14 @@
                 contextHubInfo, pendingIntent, nanoAppId, attributionTag, mTransactionManager);
     }
 
-    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     /**
      * Loads a nanoapp binary at the specified Context hub.
      *
      * @param contextHubId        the ID of the hub to load the binary
      * @param transactionCallback the client-facing transaction callback interface
      * @param nanoAppBinary       the binary to load
-     * @throws IllegalStateException if the transaction queue is full
      */
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
     public void loadNanoAppOnHub(
             int contextHubId, IContextHubTransactionCallback transactionCallback,
@@ -1308,15 +1250,14 @@
         mTransactionManager.addTransaction(transaction);
     }
 
-    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     /**
      * Unloads a nanoapp from the specified Context Hub.
      *
      * @param contextHubId        the ID of the hub to unload the nanoapp
      * @param transactionCallback the client-facing transaction callback interface
      * @param nanoAppId           the ID of the nanoapp to unload
-     * @throws IllegalStateException if the transaction queue is full
      */
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
     public void unloadNanoAppFromHub(
             int contextHubId, IContextHubTransactionCallback transactionCallback, long nanoAppId)
@@ -1333,19 +1274,17 @@
         mTransactionManager.addTransaction(transaction);
     }
 
-    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     /**
      * Enables a nanoapp at the specified Context Hub.
      *
      * @param contextHubId        the ID of the hub to enable the nanoapp
      * @param transactionCallback the client-facing transaction callback interface
      * @param nanoAppId           the ID of the nanoapp to enable
-     * @throws IllegalStateException if the transaction queue is full
      */
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
     public void enableNanoApp(
-            int contextHubId, IContextHubTransactionCallback transactionCallback, long nanoAppId)
-            throws RemoteException {
+            int contextHubId, IContextHubTransactionCallback transactionCallback, long nanoAppId) {
         super.enableNanoApp_enforcePermission();
 
         if (!checkHalProxyAndContextHubId(
@@ -1358,19 +1297,17 @@
         mTransactionManager.addTransaction(transaction);
     }
 
-    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     /**
      * Disables a nanoapp at the specified Context Hub.
      *
      * @param contextHubId        the ID of the hub to disable the nanoapp
      * @param transactionCallback the client-facing transaction callback interface
      * @param nanoAppId           the ID of the nanoapp to disable
-     * @throws IllegalStateException if the transaction queue is full
      */
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
     public void disableNanoApp(
-            int contextHubId, IContextHubTransactionCallback transactionCallback, long nanoAppId)
-            throws RemoteException {
+            int contextHubId, IContextHubTransactionCallback transactionCallback, long nanoAppId) {
         super.disableNanoApp_enforcePermission();
 
         if (!checkHalProxyAndContextHubId(
@@ -1383,17 +1320,16 @@
         mTransactionManager.addTransaction(transaction);
     }
 
-    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     /**
      * Queries for a list of nanoapps from the specified Context hub.
      *
      * @param contextHubId        the ID of the hub to query
      * @param transactionCallback the client-facing transaction callback interface
-     * @throws IllegalStateException if the transaction queue is full
      */
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
-    public void queryNanoApps(int contextHubId, IContextHubTransactionCallback transactionCallback)
-            throws RemoteException {
+    public void queryNanoApps(int contextHubId,
+            IContextHubTransactionCallback transactionCallback) {
         super.queryNanoApps_enforcePermission();
 
         if (!checkHalProxyAndContextHubId(
@@ -1406,16 +1342,15 @@
         mTransactionManager.addTransaction(transaction);
     }
 
-    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     /**
      * Queries for a list of preloaded nanoapp IDs from the specified Context Hub.
      *
      * @param hubInfo The Context Hub to query a list of nanoapps from.
      * @return The list of 64-bit IDs of the preloaded nanoapps.
-     * @throws NullPointerException if hubInfo is null
      */
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
-    public long[] getPreloadedNanoAppIds(ContextHubInfo hubInfo) throws RemoteException {
+    public long[] getPreloadedNanoAppIds(ContextHubInfo hubInfo) {
         super.getPreloadedNanoAppIds_enforcePermission();
         Objects.requireNonNull(hubInfo, "hubInfo cannot be null");
 
@@ -1426,7 +1361,6 @@
         return nanoappIds;
     }
 
-    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     /**
      * Puts the context hub in and out of test mode. Test mode is a clean state
      * where tests can be executed in the same environment. If enable is true,
@@ -1442,6 +1376,7 @@
      *               test mode.
      * @return       If true, the operation was successful; false otherwise.
      */
+    @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_CONTEXT_HUB)
     @Override
     public boolean setTestMode(boolean enable) {
         super.setTestMode_enforcePermission();
@@ -1551,10 +1486,6 @@
         }
     }
 
-    private void checkPermissions() {
-        ContextHubServiceUtil.checkPermissions(mContext);
-    }
-
     private int onMessageReceiptOldApi(
             int msgType, int contextHubHandle, int appInstance, byte[] data) {
         if (data == null) {
@@ -1586,7 +1517,6 @@
                     callback.onMessageReceipt(contextHubHandle, appInstance, msg);
                 } catch (RemoteException e) {
                     Log.i(TAG, "Exception (" + e + ") calling remote callback (" + callback + ").");
-                    continue;
                 }
             }
             mCallbacksList.finishBroadcast();
@@ -1729,8 +1659,8 @@
      * Hub.
      */
     private void sendMicrophoneDisableSettingUpdateForCurrentUser() {
-        boolean isEnabled = mSensorPrivacyManagerInternal == null ? false :
-                mSensorPrivacyManagerInternal.isSensorPrivacyEnabled(
+        boolean isEnabled = mSensorPrivacyManagerInternal != null
+                && mSensorPrivacyManagerInternal.isSensorPrivacyEnabled(
                 getCurrentUserId(), SensorPrivacyManager.Sensors.MICROPHONE);
         sendMicrophoneDisableSettingUpdate(isEnabled);
     }
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubServiceTransaction.java b/services/core/java/com/android/server/location/contexthub/ContextHubServiceTransaction.java
index 6da7a65..3aea6d5 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubServiceTransaction.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubServiceTransaction.java
@@ -27,53 +27,65 @@
  *
  * @hide
  */
-/* package */ abstract class ContextHubServiceTransaction {
+abstract class ContextHubServiceTransaction {
     private final int mTransactionId;
+
     @ContextHubTransaction.Type
     private final int mTransactionType;
 
-    /** The ID of the nanoapp this transaction is targeted for, null if not applicable. */
-    private final Long mNanoAppId;
+    private final long mNanoAppId;
 
-    /**
-     * The host package associated with this transaction.
-     */
     private final String mPackage;
 
-    /**
-     * The message sequence number associated with this transaction, null if not applicable.
-     */
-    private final Integer mMessageSequenceNumber;
+    private final int mMessageSequenceNumber;
 
-    /**
-     * true if the transaction has already completed, false otherwise
-     */
+    private long mNextRetryTime;
+
+    private long mTimeoutTime;
+
+    /** The number of times the transaction has been started (start function called). */
+    private int mNumCompletedStartCalls;
+
+    private final short mHostEndpointId;
+
     private boolean mIsComplete = false;
 
-    /* package */ ContextHubServiceTransaction(int id, int type, String packageName) {
+    ContextHubServiceTransaction(int id, int type, String packageName) {
         mTransactionId = id;
         mTransactionType = type;
-        mNanoAppId = null;
+        mNanoAppId = Long.MAX_VALUE;
         mPackage = packageName;
-        mMessageSequenceNumber = null;
+        mMessageSequenceNumber = Integer.MAX_VALUE;
+        mNextRetryTime = Long.MAX_VALUE;
+        mTimeoutTime = Long.MAX_VALUE;
+        mNumCompletedStartCalls = 0;
+        mHostEndpointId = Short.MAX_VALUE;
     }
 
-    /* package */ ContextHubServiceTransaction(int id, int type, long nanoAppId,
+    ContextHubServiceTransaction(int id, int type, long nanoAppId,
             String packageName) {
         mTransactionId = id;
         mTransactionType = type;
         mNanoAppId = nanoAppId;
         mPackage = packageName;
-        mMessageSequenceNumber = null;
+        mMessageSequenceNumber = Integer.MAX_VALUE;
+        mNextRetryTime = Long.MAX_VALUE;
+        mTimeoutTime = Long.MAX_VALUE;
+        mNumCompletedStartCalls = 0;
+        mHostEndpointId = Short.MAX_VALUE;
     }
 
-    /* package */ ContextHubServiceTransaction(int id, int type, String packageName,
-            int messageSequenceNumber) {
+    ContextHubServiceTransaction(int id, int type, String packageName,
+            int messageSequenceNumber, short hostEndpointId) {
         mTransactionId = id;
         mTransactionType = type;
-        mNanoAppId = null;
+        mNanoAppId = Long.MAX_VALUE;
         mPackage = packageName;
         mMessageSequenceNumber = messageSequenceNumber;
+        mNextRetryTime = Long.MAX_VALUE;
+        mTimeoutTime = Long.MAX_VALUE;
+        mNumCompletedStartCalls = 0;
+        mHostEndpointId = hostEndpointId;
     }
 
     /**
@@ -95,7 +107,7 @@
      *
      * @param result the result of the transaction
      */
-    /* package */ void onTransactionComplete(@ContextHubTransaction.Result int result) {
+    void onTransactionComplete(@ContextHubTransaction.Result int result) {
     }
 
     /**
@@ -106,44 +118,51 @@
      * @param result           the result of the query
      * @param nanoAppStateList the list of nanoapps given by the query response
      */
-    /* package */ void onQueryResponse(
+    void onQueryResponse(
             @ContextHubTransaction.Result int result, List<NanoAppState> nanoAppStateList) {
     }
 
-    /**
-     * @return the ID of this transaction
-     */
-    /* package */ int getTransactionId() {
+    int getTransactionId() {
         return mTransactionId;
     }
 
-    /**
-     * @return the type of this transaction
-     * @see ContextHubTransaction.Type
-     */
     @ContextHubTransaction.Type
-    /* package */ int getTransactionType() {
+    int getTransactionType() {
         return mTransactionType;
     }
 
-    /**
-     * @return the message sequence number of this transaction
-     */
-    Integer getMessageSequenceNumber() {
+    int getMessageSequenceNumber() {
         return mMessageSequenceNumber;
     }
 
+    long getNextRetryTime() {
+        return mNextRetryTime;
+    }
+
+    long getTimeoutTime() {
+        return mTimeoutTime;
+    }
+
+    int getNumCompletedStartCalls() {
+        return mNumCompletedStartCalls;
+    }
+
+    short getHostEndpointId() {
+        return mHostEndpointId;
+    }
+
     /**
      * Gets the timeout period as defined in IContexthub.hal
      *
      * @return the timeout of this transaction in the specified time unit
      */
-    /* package */ long getTimeout(TimeUnit unit) {
+    long getTimeout(TimeUnit unit) {
         switch (mTransactionType) {
             case ContextHubTransaction.TYPE_LOAD_NANOAPP:
                 return unit.convert(30L, TimeUnit.SECONDS);
             case ContextHubTransaction.TYPE_RELIABLE_MESSAGE:
-                return unit.convert(1000L, TimeUnit.MILLISECONDS);
+                return unit.convert(ContextHubTransactionManager.RELIABLE_MESSAGE_TIMEOUT.toNanos(),
+                        TimeUnit.NANOSECONDS);
             case ContextHubTransaction.TYPE_UNLOAD_NANOAPP:
             case ContextHubTransaction.TYPE_ENABLE_NANOAPP:
             case ContextHubTransaction.TYPE_DISABLE_NANOAPP:
@@ -159,14 +178,23 @@
      *
      * Should only be called as a result of a response from a Context Hub callback
      */
-    /* package */ void setComplete() {
+    void setComplete() {
         mIsComplete = true;
     }
 
-    /**
-     * @return true if the transaction has already completed, false otherwise
-     */
-    /* package */ boolean isComplete() {
+    void setNextRetryTime(long nextRetryTime) {
+        mNextRetryTime = nextRetryTime;
+    }
+
+    void setTimeoutTime(long timeoutTime) {
+        mTimeoutTime = timeoutTime;
+    }
+
+    void setNumCompletedStartCalls(int numCompletedStartCalls) {
+        mNumCompletedStartCalls = numCompletedStartCalls;
+    }
+
+    boolean isComplete() {
         return mIsComplete;
     }
 
@@ -176,18 +204,29 @@
         out.append(ContextHubTransaction.typeToString(mTransactionType,
                 /* upperCase= */ true));
         out.append(" (");
-        if (mNanoAppId != null) {
+        if (mNanoAppId != Long.MAX_VALUE) {
             out.append("appId = 0x");
             out.append(Long.toHexString(mNanoAppId));
             out.append(", ");
         }
         out.append("package = ");
         out.append(mPackage);
-        if (mMessageSequenceNumber != null) {
+        if (mMessageSequenceNumber != Integer.MAX_VALUE) {
             out.append(", messageSequenceNumber = ");
             out.append(mMessageSequenceNumber);
         }
+        if (mTransactionType == ContextHubTransaction.TYPE_RELIABLE_MESSAGE) {
+            out.append(", nextRetryTime = ");
+            out.append(mNextRetryTime);
+            out.append(", timeoutTime = ");
+            out.append(mTimeoutTime);
+            out.append(", numCompletedStartCalls = ");
+            out.append(mNumCompletedStartCalls);
+            out.append(", hostEndpointId = ");
+            out.append(mHostEndpointId);
+        }
         out.append(")");
+
         return out.toString();
     }
 }
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubTestModeManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubTestModeManager.java
new file mode 100644
index 0000000..f2714db
--- /dev/null
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubTestModeManager.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.location.contexthub;
+
+import android.chre.flags.Flags;
+import android.hardware.location.NanoAppMessage;
+import android.util.Log;
+
+import java.util.Random;
+
+/**
+ * A class to manage behaviors during test mode. This is used for testing.
+ * @hide
+ */
+public class ContextHubTestModeManager {
+    private static final String TAG = "ContextHubTestModeManager";
+
+    /** Probability of duplicating a message. */
+    private static final double MESSAGE_DROP_PROBABILITY = 0.05;
+
+    /** Probability of duplicating a message. */
+    private static final double MESSAGE_DUPLICATION_PROBABILITY = 0.05;
+
+    /** The number of total messages to send when the duplication event happens. */
+    private static final int NUM_MESSAGES_TO_DUPLICATE = 3;
+
+    /**
+     * The seed for the random number generator. This is used to make the
+     * test more deterministic.
+     */
+    private static final long SEED = 0xDEADBEEF;
+
+    private final Random mRandom = new Random(SEED);
+
+    /**
+     * @return whether the message was handled
+     * @see ContextHubServiceCallback#handleNanoappMessage
+     */
+    public boolean handleNanoappMessage(Runnable handleMessage, NanoAppMessage message) {
+        if (Flags.reliableMessageDuplicateDetectionService()
+                && message.isReliable()
+                && mRandom.nextDouble() < MESSAGE_DUPLICATION_PROBABILITY) {
+            Log.i(TAG, "[TEST MODE] Duplicating message ("
+                    + NUM_MESSAGES_TO_DUPLICATE
+                    + " sends) with message sequence number: "
+                    + message.getMessageSequenceNumber());
+            for (int i = 0; i < NUM_MESSAGES_TO_DUPLICATE; ++i) {
+                handleMessage.run();
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * @return whether the message was handled
+     * @see IContextHubWrapper#sendMessageToContextHub
+     */
+    public boolean sendMessageToContextHub(NanoAppMessage message) {
+        if (Flags.reliableMessageRetrySupportService()
+                && message.isReliable()
+                && mRandom.nextDouble() < MESSAGE_DROP_PROBABILITY) {
+            Log.i(TAG, "[TEST MODE] Dropping message with message sequence number: "
+                    + message.getMessageSequenceNumber());
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java
index ec94e2b..e6d330f8 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubTransactionManager.java
@@ -16,19 +16,26 @@
 
 package com.android.server.location.contexthub;
 
+import android.chre.flags.Flags;
 import android.hardware.location.ContextHubTransaction;
 import android.hardware.location.IContextHubTransactionCallback;
 import android.hardware.location.NanoAppBinary;
 import android.hardware.location.NanoAppMessage;
 import android.hardware.location.NanoAppState;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.util.Log;
 
+import java.time.Duration;
 import java.util.ArrayDeque;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Random;
+import java.util.Set;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
@@ -47,34 +54,30 @@
 /* package */ class ContextHubTransactionManager {
     private static final String TAG = "ContextHubTransactionManager";
 
-    /*
-     * Maximum number of transaction requests that can be pending at a time
-     */
+    public static final Duration RELIABLE_MESSAGE_TIMEOUT = Duration.ofSeconds(1);
+
     private static final int MAX_PENDING_REQUESTS = 10000;
 
-    /*
-     * The proxy to talk to the Context Hub
-     */
+    private static final int RELIABLE_MESSAGE_MAX_NUM_RETRY = 3;
+
+    private static final Duration RELIABLE_MESSAGE_RETRY_WAIT_TIME = Duration.ofMillis(250);
+
+    private static final Duration RELIABLE_MESSAGE_MIN_WAIT_TIME = Duration.ofNanos(1000);
+
     private final IContextHubWrapper mContextHubProxy;
 
-    /*
-     * The manager for all clients for the service.
-     */
     private final ContextHubClientManager mClientManager;
 
-    /*
-     * The nanoapp state manager for the service
-     */
     private final NanoAppStateManager mNanoAppStateManager;
 
-    /*
-     * A queue containing the current transactions
-     */
     private final ArrayDeque<ContextHubServiceTransaction> mTransactionQueue = new ArrayDeque<>();
 
-    /*
-     * The next available transaction ID
-     */
+    private final Map<Integer, ContextHubServiceTransaction> mReliableMessageTransactionMap =
+            new HashMap<>();
+
+    /** A set of host endpoint IDs that have an active pending transaction. */
+    private final Set<Short> mReliableMessageHostEndpointIdActiveSet = new HashSet<>();
+
     private final AtomicInteger mNextAvailableId = new AtomicInteger();
 
     /**
@@ -86,10 +89,12 @@
             new AtomicInteger(new Random().nextInt(Integer.MAX_VALUE / 2));
 
     /*
-     * An executor and the future object for scheduling timeout timers
+     * An executor and the future object for scheduling timeout timers and
+     * for scheduling the processing of reliable message transactions.
      */
-    private final ScheduledThreadPoolExecutor mTimeoutExecutor = new ScheduledThreadPoolExecutor(1);
+    private final ScheduledThreadPoolExecutor mExecutor = new ScheduledThreadPoolExecutor(1);
     private ScheduledFuture<?> mTimeoutFuture = null;
+    private ScheduledFuture<?> mReliableMessageTransactionFuture = null;
 
     /*
      * The list of previous transaction records.
@@ -333,7 +338,7 @@
             IContextHubTransactionCallback transactionCallback, String packageName) {
         return new ContextHubServiceTransaction(mNextAvailableId.getAndIncrement(),
                 ContextHubTransaction.TYPE_RELIABLE_MESSAGE, packageName,
-                mNextAvailableMessageSequenceNumber.getAndIncrement()) {
+                mNextAvailableMessageSequenceNumber.getAndIncrement(), hostEndpointId) {
             @Override
             /* package */ int onTransact() {
                 try {
@@ -416,16 +421,23 @@
             return;
         }
 
-        if (mTransactionQueue.size() == MAX_PENDING_REQUESTS) {
+        if (mTransactionQueue.size() >= MAX_PENDING_REQUESTS
+                || mReliableMessageTransactionMap.size() >= MAX_PENDING_REQUESTS) {
             throw new IllegalStateException("Transaction queue is full (capacity = "
                     + MAX_PENDING_REQUESTS + ")");
         }
 
-        mTransactionQueue.add(transaction);
         mTransactionRecordDeque.add(new TransactionRecord(transaction.toString()));
-
-        if (mTransactionQueue.size() == 1) {
-            startNextTransaction();
+        if (Flags.reliableMessageRetrySupportService()
+                && transaction.getTransactionType()
+                        == ContextHubTransaction.TYPE_RELIABLE_MESSAGE) {
+            mReliableMessageTransactionMap.put(transaction.getMessageSequenceNumber(), transaction);
+            mExecutor.execute(() -> processMessageTransactions());
+        } else {
+            mTransactionQueue.add(transaction);
+            if (mTransactionQueue.size() == 1) {
+                startNextTransaction();
+            }
         }
     }
 
@@ -455,26 +467,42 @@
 
     /* package */
     synchronized void onMessageDeliveryResponse(int messageSequenceNumber, boolean success) {
-        ContextHubServiceTransaction transaction = mTransactionQueue.peek();
+        if (!Flags.reliableMessageRetrySupportService()) {
+            ContextHubServiceTransaction transaction = mTransactionQueue.peek();
+            if (transaction == null) {
+                Log.w(TAG, "Received unexpected transaction response (no transaction pending)");
+                return;
+            }
+
+            int transactionMessageSequenceNumber = transaction.getMessageSequenceNumber();
+            if (transaction.getTransactionType() != ContextHubTransaction.TYPE_RELIABLE_MESSAGE
+                    || transactionMessageSequenceNumber != messageSequenceNumber) {
+                Log.w(TAG, "Received unexpected message transaction response (expected message "
+                        + "sequence number = "
+                        + transaction.getMessageSequenceNumber()
+                        + ", received messageSequenceNumber = " + messageSequenceNumber + ")");
+                return;
+            }
+
+            transaction.onTransactionComplete(success ? ContextHubTransaction.RESULT_SUCCESS :
+                            ContextHubTransaction.RESULT_FAILED_AT_HUB);
+            removeTransactionAndStartNext();
+            return;
+        }
+
+        ContextHubServiceTransaction transaction =
+                mReliableMessageTransactionMap.get(messageSequenceNumber);
         if (transaction == null) {
-            Log.w(TAG, "Received unexpected transaction response (no transaction pending)");
+            Log.w(TAG, "Could not find reliable message transaction with "
+                    + "message sequence number = "
+                    + messageSequenceNumber);
             return;
         }
 
-        Integer transactionMessageSequenceNumber = transaction.getMessageSequenceNumber();
-        if (transaction.getTransactionType() != ContextHubTransaction.TYPE_RELIABLE_MESSAGE
-                || transactionMessageSequenceNumber == null
-                || transactionMessageSequenceNumber != messageSequenceNumber) {
-            Log.w(TAG, "Received unexpected message transaction response (expected message "
-                    + "sequence number = "
-                    + transaction.getMessageSequenceNumber()
-                    + ", received messageSequenceNumber = " + messageSequenceNumber + ")");
-            return;
-        }
-
-        transaction.onTransactionComplete(success ? ContextHubTransaction.RESULT_SUCCESS :
-                        ContextHubTransaction.RESULT_FAILED_AT_HUB);
-        removeTransactionAndStartNext();
+        completeMessageTransaction(transaction,
+                success ? ContextHubTransaction.RESULT_SUCCESS
+                        : ContextHubTransaction.RESULT_FAILED_AT_HUB);
+        mExecutor.execute(() -> processMessageTransactions());
     }
 
     /**
@@ -503,6 +531,15 @@
      */
     /* package */
     synchronized void onHubReset() {
+        if (Flags.reliableMessageRetrySupportService()) {
+            Iterator<Map.Entry<Integer, ContextHubServiceTransaction>> iter =
+                    mReliableMessageTransactionMap.entrySet().iterator();
+            while (iter.hasNext()) {
+                completeMessageTransaction(iter.next().getValue(),
+                        ContextHubTransaction.RESULT_FAILED_AT_HUB, iter);
+            }
+        }
+
         ContextHubServiceTransaction transaction = mTransactionQueue.peek();
         if (transaction == null) {
             return;
@@ -566,7 +603,7 @@
 
                 long timeoutMs = transaction.getTimeout(TimeUnit.MILLISECONDS);
                 try {
-                    mTimeoutFuture = mTimeoutExecutor.schedule(
+                    mTimeoutFuture = mExecutor.schedule(
                             onTimeoutFunc, timeoutMs, TimeUnit.MILLISECONDS);
                 } catch (Exception e) {
                     Log.e(TAG, "Error when schedule a timer", e);
@@ -579,6 +616,138 @@
         }
     }
 
+    /**
+     * Processes message transactions, starting and completing them as needed.
+     * <p>
+     * This function is called when adding a message transaction or when a timer
+     * expires for an existing message transaction's retry or timeout. The
+     * internal processing loop will iterate at most twice as if one iteration
+     * completes a transaction, the next iteration can only start new transactions.
+     * If the first iteration does not complete any transaction, the loop will
+     * only iterate once.
+     * <p>
+     */
+    private synchronized void processMessageTransactions() {
+        if (!Flags.reliableMessageRetrySupportService()) {
+            return;
+        }
+
+        if (mReliableMessageTransactionFuture != null) {
+            mReliableMessageTransactionFuture.cancel(/* mayInterruptIfRunning= */ false);
+            mReliableMessageTransactionFuture = null;
+        }
+
+        long now = SystemClock.elapsedRealtimeNanos();
+        long nextExecutionTime = Long.MAX_VALUE;
+        boolean continueProcessing;
+        do {
+            continueProcessing = false;
+            Iterator<Map.Entry<Integer, ContextHubServiceTransaction>> iter =
+                    mReliableMessageTransactionMap.entrySet().iterator();
+            while (iter.hasNext()) {
+                ContextHubServiceTransaction transaction = iter.next().getValue();
+                short hostEndpointId = transaction.getHostEndpointId();
+                int numCompletedStartCalls = transaction.getNumCompletedStartCalls();
+                if (numCompletedStartCalls == 0
+                        && mReliableMessageHostEndpointIdActiveSet.contains(hostEndpointId)) {
+                    continue;
+                }
+
+                long nextRetryTime = transaction.getNextRetryTime();
+                long timeoutTime = transaction.getTimeoutTime();
+                boolean transactionTimedOut = timeoutTime <= now;
+                boolean transactionHitMaxRetries = nextRetryTime <= now
+                        && numCompletedStartCalls > RELIABLE_MESSAGE_MAX_NUM_RETRY;
+                if (transactionTimedOut || transactionHitMaxRetries) {
+                    completeMessageTransaction(transaction,
+                            ContextHubTransaction.RESULT_FAILED_TIMEOUT, iter);
+                    continueProcessing = true;
+                } else {
+                    if (nextRetryTime <= now || numCompletedStartCalls <= 0) {
+                        startMessageTransaction(transaction, now);
+                    }
+
+                    nextExecutionTime = Math.min(nextExecutionTime,
+                            transaction.getNextRetryTime());
+                    nextExecutionTime = Math.min(nextExecutionTime,
+                            transaction.getTimeoutTime());
+                }
+            }
+        } while (continueProcessing);
+
+        if (nextExecutionTime < Long.MAX_VALUE) {
+            mReliableMessageTransactionFuture = mExecutor.schedule(
+                    () -> processMessageTransactions(),
+                    Math.max(nextExecutionTime - SystemClock.elapsedRealtimeNanos(),
+                            RELIABLE_MESSAGE_MIN_WAIT_TIME.toNanos()),
+                    TimeUnit.NANOSECONDS);
+        }
+    }
+
+    /**
+     * Completes a message transaction and removes it from the reliable message map.
+     *
+     * @param transaction The transaction to complete.
+     * @param result The result code.
+     */
+    private void completeMessageTransaction(ContextHubServiceTransaction transaction,
+            @ContextHubTransaction.Result int result) {
+        completeMessageTransaction(transaction, result, /* iter= */ null);
+    }
+
+    /**
+     * Completes a message transaction and removes it from the reliable message map using iter.
+     *
+     * @param transaction The transaction to complete.
+     * @param result The result code.
+     * @param iter The iterator for the reliable message map - used to remove the message directly.
+     */
+    private void completeMessageTransaction(ContextHubServiceTransaction transaction,
+            @ContextHubTransaction.Result int result,
+            Iterator<Map.Entry<Integer, ContextHubServiceTransaction>> iter) {
+        transaction.onTransactionComplete(result);
+
+        if (iter == null) {
+            mReliableMessageTransactionMap.remove(transaction.getMessageSequenceNumber());
+        } else {
+            iter.remove();
+        }
+        mReliableMessageHostEndpointIdActiveSet.remove(transaction.getHostEndpointId());
+
+        Log.d(TAG, "Successfully completed reliable message transaction with "
+                + "message sequence number: " + transaction.getMessageSequenceNumber()
+                + " and result: " + result);
+    }
+
+    /**
+     * Starts a message transaction.
+     *
+     * @param transaction The transaction to start.
+     * @param now The now time.
+     */
+    private void startMessageTransaction(ContextHubServiceTransaction transaction, long now) {
+        int numCompletedStartCalls = transaction.getNumCompletedStartCalls();
+        @ContextHubTransaction.Result int result = transaction.onTransact();
+        if (result == ContextHubTransaction.RESULT_SUCCESS) {
+            Log.d(TAG, "Successfully "
+                    + (numCompletedStartCalls == 0 ? "started" : "retried")
+                    + " reliable message transaction with message sequence number: "
+                    + transaction.getMessageSequenceNumber());
+        } else {
+            Log.w(TAG, "Could not start reliable message transaction with "
+                    + "message sequence number: "
+                    + transaction.getMessageSequenceNumber()
+                    + ", result: " + result);
+        }
+
+        transaction.setNextRetryTime(now + RELIABLE_MESSAGE_RETRY_WAIT_TIME.toNanos());
+        if (transaction.getTimeoutTime() == Long.MAX_VALUE) { // first time starting transaction
+            transaction.setTimeoutTime(now + RELIABLE_MESSAGE_TIMEOUT.toNanos());
+        }
+        transaction.setNumCompletedStartCalls(numCompletedStartCalls + 1);
+        mReliableMessageHostEndpointIdActiveSet.add(transaction.getHostEndpointId());
+    }
+
     private int toStatsTransactionResult(@ContextHubTransaction.Result int result) {
         switch (result) {
             case ContextHubTransaction.RESULT_SUCCESS:
@@ -605,19 +774,34 @@
 
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder(100);
-        ContextHubServiceTransaction[] arr;
+        StringBuilder sb = new StringBuilder();
+        int i = 0;
         synchronized (this) {
-            arr = mTransactionQueue.toArray(new ContextHubServiceTransaction[0]);
-        }
-        for (int i = 0; i < arr.length; i++) {
-            sb.append(i + ": " + arr[i] + "\n");
-        }
+            for (ContextHubServiceTransaction transaction: mTransactionQueue) {
+                sb.append(i);
+                sb.append(": ");
+                sb.append(transaction.toString());
+                sb.append("\n");
+                ++i;
+            }
 
-        sb.append("Transaction History:\n");
-        Iterator<TransactionRecord> iterator = mTransactionRecordDeque.descendingIterator();
-        while (iterator.hasNext()) {
-            sb.append(iterator.next() + "\n");
+            if (Flags.reliableMessageRetrySupportService()) {
+                for (ContextHubServiceTransaction transaction:
+                        mReliableMessageTransactionMap.values()) {
+                    sb.append(i);
+                    sb.append(": ");
+                    sb.append(transaction.toString());
+                    sb.append("\n");
+                    ++i;
+                }
+            }
+
+            sb.append("Transaction History:\n");
+            Iterator<TransactionRecord> iterator = mTransactionRecordDeque.descendingIterator();
+            while (iterator.hasNext()) {
+                sb.append(iterator.next());
+                sb.append("\n");
+            }
         }
         return sb.toString();
     }
diff --git a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
index 552809b..4fc3d87 100644
--- a/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
+++ b/services/core/java/com/android/server/location/contexthub/IContextHubWrapper.java
@@ -52,6 +52,7 @@
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * @hide
@@ -432,10 +433,16 @@
 
         // Use this thread in case where the execution requires to be on a service thread.
         // For instance, AppOpsManager.noteOp requires the UPDATE_APP_OPS_STATS permission.
-        private HandlerThread mHandlerThread =
+        private final HandlerThread mHandlerThread =
                 new HandlerThread("Context Hub AIDL callback", Process.THREAD_PRIORITY_BACKGROUND);
         private Handler mHandler;
 
+        // True if test mode is enabled for the Context Hub
+        private final AtomicBoolean mIsTestModeEnabled = new AtomicBoolean(false);
+
+        // The test mode manager that manages behaviors during test mode
+        private final ContextHubTestModeManager mTestModeManager = new ContextHubTestModeManager();
+
         private class ContextHubAidlCallback extends
                 android.hardware.contexthub.IContextHubCallback.Stub {
             private final int mContextHubId;
@@ -549,6 +556,8 @@
             } else {
                 Log.e(TAG, "mHandleServiceRestartCallback is not set");
             }
+
+            mIsTestModeEnabled.set(false);
         }
 
         public Pair<List<ContextHubInfo>, List<String>> getHubs() throws RemoteException {
@@ -659,7 +668,17 @@
             try {
                 var msg = ContextHubServiceUtil.createAidlContextHubMessage(
                         hostEndpointId, message);
-                hub.sendMessageToHub(contextHubId, msg);
+
+                // Only process the message normally if not using test mode manager or if
+                // the test mode manager call returned false as this indicates it did not
+                // process the message.
+                boolean useTestModeManager = Flags.reliableMessageImplementation()
+                        && Flags.reliableMessageTestModeBehavior()
+                        && mIsTestModeEnabled.get();
+                if (!useTestModeManager || !mTestModeManager.sendMessageToContextHub(message)) {
+                    hub.sendMessageToHub(contextHubId, msg);
+                }
+
                 return ContextHubTransaction.RESULT_SUCCESS;
             } catch (RemoteException | ServiceSpecificException e) {
                 return ContextHubTransaction.RESULT_FAILED_UNKNOWN;
@@ -828,6 +847,7 @@
                 return false;
             }
 
+            mIsTestModeEnabled.set(enable);
             try {
                 hub.setTestMode(enable);
                 return true;
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 286e789..1938150 100644
--- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java
@@ -68,7 +68,6 @@
 import android.location.LocationRequest;
 import android.location.LocationResult;
 import android.location.LocationResult.BadLocationException;
-import android.location.flags.Flags;
 import android.location.provider.ProviderProperties;
 import android.location.provider.ProviderRequest;
 import android.location.util.identity.CallerIdentity;
@@ -1050,22 +1049,10 @@
                 stopBatching();
 
                 if (mStarted && mGnssNative.getCapabilities().hasScheduling()) {
-                    if (Flags.gnssCallStopBeforeSetPositionMode()) {
-                        GnssPositionMode positionMode = new GnssPositionMode(mPositionMode,
-                                GNSS_POSITION_RECURRENCE_PERIODIC, mFixInterval,
-                                /* preferredAccuracy= */ 0,
-                                /* preferredTime= */ 0,
-                                mProviderRequest.isLowPower());
-                        if (!positionMode.equals(mLastPositionMode)) {
-                            stopNavigating();
-                            startNavigating();
-                        }
-                    } else {
-                        // change period and/or lowPowerMode
-                        if (!setPositionMode(mPositionMode, GNSS_POSITION_RECURRENCE_PERIODIC,
-                                mFixInterval, mProviderRequest.isLowPower())) {
-                            Log.e(TAG, "set_position_mode failed in updateRequirements");
-                        }
+                    // change period and/or lowPowerMode
+                    if (!setPositionMode(mPositionMode, GNSS_POSITION_RECURRENCE_PERIODIC,
+                            mFixInterval, mProviderRequest.isLowPower())) {
+                        Log.e(TAG, "set_position_mode failed in updateRequirements");
                     }
                 } else if (!mStarted) {
                     // start GPS
@@ -1248,32 +1235,11 @@
             }
 
             int interval = mGnssNative.getCapabilities().hasScheduling() ? mFixInterval : 1000;
-
-            if (Flags.gnssCallStopBeforeSetPositionMode()) {
-                boolean success = mGnssNative.setPositionMode(mPositionMode,
-                        GNSS_POSITION_RECURRENCE_PERIODIC, interval,
-                        /* preferredAccuracy= */ 0,
-                        /* preferredTime= */ 0,
-                        mProviderRequest.isLowPower());
-                if (success) {
-                    mLastPositionMode = new GnssPositionMode(mPositionMode,
-                            GNSS_POSITION_RECURRENCE_PERIODIC, interval,
-                            /* preferredAccuracy= */ 0,
-                            /* preferredTime= */ 0,
-                            mProviderRequest.isLowPower());
-                } else {
-                    mLastPositionMode = null;
-                    setStarted(false);
-                    Log.e(TAG, "set_position_mode failed in startNavigating()");
-                    return;
-                }
-            } else {
-                if (!setPositionMode(mPositionMode, GNSS_POSITION_RECURRENCE_PERIODIC,
-                        interval, mProviderRequest.isLowPower())) {
-                    setStarted(false);
-                    Log.e(TAG, "set_position_mode failed in startNavigating()");
-                    return;
-                }
+            if (!setPositionMode(mPositionMode, GNSS_POSITION_RECURRENCE_PERIODIC,
+                    interval, mProviderRequest.isLowPower())) {
+                setStarted(false);
+                Log.e(TAG, "set_position_mode failed in startNavigating()");
+                return;
             }
             if (!mGnssNative.start()) {
                 setStarted(false);
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
index 3673eb0..56b93e8 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
@@ -839,6 +839,13 @@
                                     + "Disallowed route: "
                                     + route);
                 }
+
+                if (route.isSystemRouteType()) {
+                    throw new SecurityException(
+                            "Only the system is allowed to publish routes with system route types. "
+                                    + "Disallowed route: "
+                                    + route);
+                }
             }
 
             Connection connection = mConnectionRef.get();
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java b/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
index 7c1a5e1..93ef6f0 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
@@ -56,6 +56,7 @@
     private final PackageManager mPackageManager;
 
     private final ArrayList<MediaRoute2ProviderServiceProxy> mProxies = new ArrayList<>();
+    private final Runnable mScanPackagesRunnable = this::scanPackages;
     private boolean mRunning;
 
     MediaRoute2ProviderWatcher(Context context,
@@ -106,7 +107,7 @@
             mRunning = false;
 
             mContext.unregisterReceiver(mScanPackagesReceiver);
-            mHandler.removeCallbacks(this::scanPackages);
+            mHandler.removeCallbacks(mScanPackagesRunnable);
 
             // Stop all providers.
             for (int i = mProxies.size() - 1; i >= 0; i--) {
@@ -189,8 +190,8 @@
     }
 
     private void postScanPackagesIfNeeded() {
-        if (!mHandler.hasCallbacks(this::scanPackages)) {
-            mHandler.post(this::scanPackages);
+        if (!mHandler.hasCallbacks(mScanPackagesRunnable)) {
+            mHandler.post(mScanPackagesRunnable);
         }
     }
 
diff --git a/services/core/java/com/android/server/notification/CountdownConditionProvider.java b/services/core/java/com/android/server/notification/CountdownConditionProvider.java
index efca598..c3ace15 100644
--- a/services/core/java/com/android/server/notification/CountdownConditionProvider.java
+++ b/services/core/java/com/android/server/notification/CountdownConditionProvider.java
@@ -19,13 +19,11 @@
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.Uri;
 import android.service.notification.Condition;
-import android.service.notification.IConditionProvider;
 import android.service.notification.ZenModeConfig;
 import android.text.format.DateUtils;
 import android.util.Log;
@@ -41,9 +39,6 @@
     private static final String TAG = "ConditionProviders.CCP";
     private static final boolean DEBUG = Log.isLoggable("ConditionProviders", Log.DEBUG);
 
-    public static final ComponentName COMPONENT =
-            new ComponentName("android", CountdownConditionProvider.class.getName());
-
     private static final String ACTION = CountdownConditionProvider.class.getName();
     private static final int REQUEST_CODE = 100;
     private static final String EXTRA_CONDITION_ID = "condition_id";
@@ -60,31 +55,16 @@
     }
 
     @Override
-    public ComponentName getComponent() {
-        return COMPONENT;
-    }
-
-    @Override
     public boolean isValidConditionId(Uri id) {
         return ZenModeConfig.isValidCountdownConditionId(id);
     }
 
     @Override
-    public void attachBase(Context base) {
-        attachBaseContext(base);
-    }
-
-    @Override
     public void onBootComplete() {
         // noop
     }
 
     @Override
-    public IConditionProvider asInterface() {
-        return (IConditionProvider) onBind(null);
-    }
-
-    @Override
     public void dump(PrintWriter pw, DumpFilter filter) {
         pw.println("    CountdownConditionProvider:");
         pw.print("      mConnected="); pw.println(mConnected);
diff --git a/services/core/java/com/android/server/notification/CustomManualConditionProvider.java b/services/core/java/com/android/server/notification/CustomManualConditionProvider.java
new file mode 100644
index 0000000..9531c5e
--- /dev/null
+++ b/services/core/java/com/android/server/notification/CustomManualConditionProvider.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 android.net.Uri;
+import android.service.notification.ZenModeConfig;
+
+import java.io.PrintWriter;
+
+/**
+ * Condition provider used for custom manual rules (i.e. user-created rules without an automatic
+ * trigger).
+ */
+public class CustomManualConditionProvider extends SystemConditionProviderService {
+
+    private static final String SIMPLE_NAME = CustomManualConditionProvider.class.getSimpleName();
+
+    @Override
+    public boolean isValidConditionId(Uri id) {
+        return ZenModeConfig.isValidCustomManualConditionId(id);
+    }
+
+    @Override
+    public void onBootComplete() {
+        // Nothing to do.
+    }
+
+    @Override
+    public void onConnected() {
+        // No need to keep subscriptions because we won't ever call notifyConditions
+    }
+
+    @Override
+    public void onSubscribe(Uri conditionId) {
+        // No need to keep subscriptions because we won't ever call notifyConditions
+    }
+
+    @Override
+    public void onUnsubscribe(Uri conditionId) {
+        // No need to keep subscriptions because we won't ever call notifyConditions
+    }
+
+    @Override
+    public void dump(PrintWriter pw, NotificationManagerService.DumpFilter filter) {
+        pw.print("    "); pw.print(SIMPLE_NAME); pw.println(": ENABLED");
+    }
+}
diff --git a/services/core/java/com/android/server/notification/EventConditionProvider.java b/services/core/java/com/android/server/notification/EventConditionProvider.java
index 4fe7a27..00dd547 100644
--- a/services/core/java/com/android/server/notification/EventConditionProvider.java
+++ b/services/core/java/com/android/server/notification/EventConditionProvider.java
@@ -19,7 +19,6 @@
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -31,7 +30,6 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.service.notification.Condition;
-import android.service.notification.IConditionProvider;
 import android.service.notification.ZenModeConfig;
 import android.service.notification.ZenModeConfig.EventInfo;
 import android.util.ArraySet;
@@ -54,8 +52,6 @@
     private static final String TAG = "ConditionProviders.ECP";
     private static final boolean DEBUG = Log.isLoggable("ConditionProviders", Log.DEBUG);
 
-    public static final ComponentName COMPONENT =
-            new ComponentName("android", EventConditionProvider.class.getName());
     private static final String NOT_SHOWN = "...";
     private static final String SIMPLE_NAME = EventConditionProvider.class.getSimpleName();
     private static final String ACTION_EVALUATE = SIMPLE_NAME + ".EVALUATE";
@@ -82,11 +78,6 @@
     }
 
     @Override
-    public ComponentName getComponent() {
-        return COMPONENT;
-    }
-
-    @Override
     public boolean isValidConditionId(Uri id) {
         return ZenModeConfig.isValidEventConditionId(id);
     }
@@ -166,16 +157,6 @@
         }
     }
 
-    @Override
-    public void attachBase(Context base) {
-        attachBaseContext(base);
-    }
-
-    @Override
-    public IConditionProvider asInterface() {
-        return (IConditionProvider) onBind(null);
-    }
-
     private void reloadTrackers() {
         if (DEBUG) Slog.d(TAG, "reloadTrackers");
         for (int i = 0; i < mTrackers.size(); i++) {
diff --git a/services/core/java/com/android/server/notification/GroupHelper.java b/services/core/java/com/android/server/notification/GroupHelper.java
index 13cc99c..1cdab44 100644
--- a/services/core/java/com/android/server/notification/GroupHelper.java
+++ b/services/core/java/com/android/server/notification/GroupHelper.java
@@ -24,9 +24,14 @@
 import static android.app.Notification.FLAG_ONGOING_EVENT;
 import static android.app.Notification.VISIBILITY_PRIVATE;
 import static android.app.Notification.VISIBILITY_PUBLIC;
+import static android.service.notification.Flags.notificationForceGrouping;
 
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -34,7 +39,9 @@
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
 import android.service.notification.StatusBarNotification;
+import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.R;
@@ -42,14 +49,20 @@
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
+import java.util.function.Predicate;
 
 /**
  * NotificationManagerService helper for auto-grouping notifications.
  */
 public class GroupHelper {
     private static final String TAG = "GroupHelper";
+    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     protected static final String AUTOGROUP_KEY = "ranker_group";
 
@@ -63,8 +76,16 @@
     // Flags that autogroup summaries inherits if any child has them
     private static final int ANY_CHILDREN_FLAGS = FLAG_ONGOING_EVENT | FLAG_NO_CLEAR;
 
+    protected static final String AGGREGATE_GROUP_KEY = "Aggregate_";
+
+    // If an app posts more than NotificationManagerService.AUTOGROUP_SPARSE_GROUPS_AT_COUNT groups
+    //  with less than this value, they will be forced grouped
+    private static final int MIN_CHILD_COUNT_TO_AVOID_FORCE_GROUPING = 3;
+
+
     private final Callback mCallback;
     private final int mAutoGroupAtCount;
+    private final int mAutogroupSparseGroupsAtCount;
     private final Context mContext;
     private final PackageManager mPackageManager;
 
@@ -75,12 +96,41 @@
     private final ArrayMap<String, ArrayMap<String, NotificationAttributes>> mUngroupedNotifications
             = new ArrayMap<>();
 
+    // Contains the list of notifications that should be aggregated (forced grouping)
+    // but there are less than mAutoGroupAtCount per section for a package.
+    // The primary map's key is the full aggregated group key: userId|pkgName|g:groupName
+    // The internal map's key is the notification record key
+    @GuardedBy("mAggregatedNotifications")
+    private final ArrayMap<FullyQualifiedGroupKey, ArrayMap<String, NotificationAttributes>>
+            mUngroupedAbuseNotifications = new ArrayMap<>();
+
+    // Contains the list of group summaries that were canceled when "singleton groups" were
+    // force grouped. Used to remove the original group's children when an app cancels the
+    // already removed summary. Key is userId|packageName|g:OriginalGroupName
+    @GuardedBy("mAggregatedNotifications")
+    private final ArrayMap<FullyQualifiedGroupKey, CachedSummary>
+            mCanceledSummaries = new ArrayMap<>();
+
+    // Represents the current state of the aggregated (forced grouped) notifications
+    // Key is the full aggregated group key: userId|pkgName|g:groupName
+    // And groupName is "Aggregate_"+sectionName
+    @GuardedBy("mAggregatedNotifications")
+    private final ArrayMap<FullyQualifiedGroupKey, ArrayMap<String, NotificationAttributes>>
+            mAggregatedNotifications = new ArrayMap<>();
+
+    private static final List<NotificationSectioner> NOTIFICATION_SHADE_SECTIONS = List.of(
+        new NotificationSectioner("AlertingSection", 0, (record) ->
+            record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT),
+        new NotificationSectioner("SilentSection", 1, (record) ->
+            record.getImportance() < NotificationManager.IMPORTANCE_DEFAULT));
+
     public GroupHelper(Context context, PackageManager packageManager, int autoGroupAtCount,
-            Callback callback) {
+            int autoGroupSparseGroupsAtCount, Callback callback) {
         mAutoGroupAtCount = autoGroupAtCount;
         mCallback =  callback;
         mContext = context;
         mPackageManager = packageManager;
+        mAutogroupSparseGroupsAtCount = autoGroupSparseGroupsAtCount;
     }
 
     private String generatePackageKey(int userId, String pkg) {
@@ -88,40 +138,50 @@
     }
 
     @VisibleForTesting
-    @GuardedBy("mUngroupedNotifications")
-    protected int getAutogroupSummaryFlags(
-            @NonNull final ArrayMap<String, NotificationAttributes> children) {
+    protected static int getAutogroupSummaryFlags(
+            @NonNull final ArrayMap<String, NotificationAttributes> childrenMap) {
+        final Collection<NotificationAttributes> children = childrenMap.values();
         boolean allChildrenHasFlag = children.size() > 0;
         int anyChildFlagSet = 0;
-        for (int i = 0; i < children.size(); i++) {
-            if (!hasAnyFlag(children.valueAt(i).flags, ALL_CHILDREN_FLAG)) {
+        for (NotificationAttributes childAttr: children) {
+            if (!hasAnyFlag(childAttr.flags, ALL_CHILDREN_FLAG)) {
                 allChildrenHasFlag = false;
             }
-            if (hasAnyFlag(children.valueAt(i).flags, ANY_CHILDREN_FLAGS)) {
-                anyChildFlagSet |= (children.valueAt(i).flags & ANY_CHILDREN_FLAGS);
+            if (hasAnyFlag(childAttr.flags, ANY_CHILDREN_FLAGS)) {
+                anyChildFlagSet |= (childAttr.flags & ANY_CHILDREN_FLAGS);
             }
         }
         return BASE_FLAGS | (allChildrenHasFlag ? ALL_CHILDREN_FLAG : 0) | anyChildFlagSet;
     }
 
-    private boolean hasAnyFlag(int flags, int mask) {
+    private static boolean hasAnyFlag(int flags, int mask) {
         return (flags & mask) != 0;
     }
 
     /**
      * Called when a notification is newly posted. Checks whether that notification, and all other
      * active notifications should be grouped or ungrouped atuomatically, and returns whether.
-     * @param sbn The posted notification.
+     * @param record The posted notification.
      * @param autogroupSummaryExists Whether a summary for this notification already exists.
      * @return Whether the provided notification should be autogrouped synchronously.
      */
-    public boolean onNotificationPosted(StatusBarNotification sbn, boolean autogroupSummaryExists) {
+    public boolean onNotificationPosted(NotificationRecord record, boolean autogroupSummaryExists) {
         boolean sbnToBeAutogrouped = false;
         try {
-            if (!sbn.isAppGroup()) {
-                sbnToBeAutogrouped = maybeGroup(sbn, autogroupSummaryExists);
+            if (notificationForceGrouping()) {
+                final StatusBarNotification sbn = record.getSbn();
+                if (!sbn.isAppGroup()) {
+                    sbnToBeAutogrouped = maybeGroupWithSections(record, autogroupSummaryExists);
+                } else {
+                    maybeUngroupWithSections(record);
+                }
             } else {
-                maybeUngroup(sbn, false, sbn.getUserId());
+                final StatusBarNotification sbn = record.getSbn();
+                if (!sbn.isAppGroup()) {
+                    sbnToBeAutogrouped = maybeGroup(sbn, autogroupSummaryExists);
+                } else {
+                    maybeUngroup(sbn, false, sbn.getUserId());
+                }
             }
         } catch (Exception e) {
             Slog.e(TAG, "Failure processing new notification", e);
@@ -129,9 +189,20 @@
         return sbnToBeAutogrouped;
     }
 
-    public void onNotificationRemoved(StatusBarNotification sbn) {
+    /**
+     * Called when a notification was removed. Checks if that notification was part of an autogroup
+     * and triggers any necessary cleanups: summary removal, clearing caches etc.
+     *
+     * @param record The removed notification.
+     */
+    public void onNotificationRemoved(NotificationRecord record) {
         try {
-            maybeUngroup(sbn, true, sbn.getUserId());
+            if (notificationForceGrouping()) {
+                onNotificationRemoved(record, new ArrayList<>());
+            } else {
+                final StatusBarNotification sbn = record.getSbn();
+                maybeUngroup(sbn, true, sbn.getUserId());
+            }
         } catch (Exception e) {
             Slog.e(TAG, "Error processing canceled notification", e);
         }
@@ -156,10 +227,10 @@
             String packageKey = generatePackageKey(sbn.getUserId(), sbn.getPackageName());
             final ArrayMap<String, NotificationAttributes> children =
                     mUngroupedNotifications.getOrDefault(packageKey, new ArrayMap<>());
-
             NotificationAttributes attr = new NotificationAttributes(sbn.getNotification().flags,
                     sbn.getNotification().getSmallIcon(), sbn.getNotification().color,
-                    sbn.getNotification().visibility);
+                    sbn.getNotification().visibility, Notification.GROUP_ALERT_CHILDREN,
+                    sbn.getNotification().getChannelId());
             children.put(sbn.getKey(), attr);
             mUngroupedNotifications.put(packageKey, children);
 
@@ -173,17 +244,20 @@
             if (autogroupSummaryExists) {
                 NotificationAttributes attr = new NotificationAttributes(flags,
                         sbn.getNotification().getSmallIcon(), sbn.getNotification().color,
-                        VISIBILITY_PRIVATE);
+                        VISIBILITY_PRIVATE, Notification.GROUP_ALERT_CHILDREN,
+                        sbn.getNotification().getChannelId());
                 if (Flags.autogroupSummaryIconUpdate()) {
                     attr = updateAutobundledSummaryAttributes(sbn.getPackageName(), childrenAttr,
                             attr);
                 }
 
-                mCallback.updateAutogroupSummary(sbn.getUserId(), sbn.getPackageName(), attr);
+                mCallback.updateAutogroupSummary(sbn.getUserId(), sbn.getPackageName(),
+                        AUTOGROUP_KEY, attr);
             } else {
                 Icon summaryIcon = sbn.getNotification().getSmallIcon();
                 int summaryIconColor = sbn.getNotification().color;
                 int summaryVisibility = VISIBILITY_PRIVATE;
+                String summaryChannelId = sbn.getNotification().getChannelId();
                 if (Flags.autogroupSummaryIconUpdate()) {
                     // Calculate the initial summary icon, icon color and visibility
                     NotificationAttributes iconAttr = getAutobundledSummaryAttributes(
@@ -191,12 +265,14 @@
                     summaryIcon = iconAttr.icon;
                     summaryIconColor = iconAttr.iconColor;
                     summaryVisibility = iconAttr.visibility;
+                    summaryChannelId = iconAttr.channelId;
                 }
 
                 NotificationAttributes attr = new NotificationAttributes(flags, summaryIcon,
-                        summaryIconColor, summaryVisibility);
+                        summaryIconColor, summaryVisibility, Notification.GROUP_ALERT_CHILDREN,
+                        summaryChannelId);
                 mCallback.addAutoGroupSummary(sbn.getUserId(), sbn.getPackageName(), sbn.getKey(),
-                        attr);
+                        AUTOGROUP_KEY, Integer.MAX_VALUE, attr);
             }
             for (String keyToGroup : notificationsToGroup) {
                 if (android.app.Flags.checkAutogroupBeforePost()) {
@@ -204,10 +280,10 @@
                         // Autogrouping for the provided notification is to be done synchronously.
                         sbnToBeAutogrouped = true;
                     } else {
-                        mCallback.addAutoGroup(keyToGroup, /*requestSort=*/true);
+                        mCallback.addAutoGroup(keyToGroup, AUTOGROUP_KEY, /*requestSort=*/true);
                     }
                 } else {
-                    mCallback.addAutoGroup(keyToGroup, /*requestSort=*/true);
+                    mCallback.addAutoGroup(keyToGroup, AUTOGROUP_KEY, /*requestSort=*/true);
                 }
             }
         }
@@ -263,11 +339,12 @@
         }
 
         if (removeSummary) {
-            mCallback.removeAutoGroupSummary(userId, sbn.getPackageName());
+            mCallback.removeAutoGroupSummary(userId, sbn.getPackageName(), AUTOGROUP_KEY);
         } else {
             NotificationAttributes attr = new NotificationAttributes(summaryFlags,
                     sbn.getNotification().getSmallIcon(), sbn.getNotification().color,
-                    VISIBILITY_PRIVATE);
+                    VISIBILITY_PRIVATE, Notification.GROUP_ALERT_CHILDREN,
+                    sbn.getNotification().getChannelId());
             boolean attributesUpdated = false;
             if (Flags.autogroupSummaryIconUpdate()) {
                 NotificationAttributes newAttr = updateAutobundledSummaryAttributes(
@@ -279,7 +356,7 @@
             }
 
             if (updateSummaryFlags || attributesUpdated) {
-                mCallback.updateAutogroupSummary(userId, sbn.getPackageName(), attr);
+                mCallback.updateAutogroupSummary(userId, sbn.getPackageName(), AUTOGROUP_KEY, attr);
             }
         }
         if (removeAutogroupOverlay) {
@@ -287,16 +364,6 @@
         }
     }
 
-    @VisibleForTesting
-    int getNotGroupedByAppCount(int userId, String pkg) {
-        synchronized (mUngroupedNotifications) {
-            String key = generatePackageKey(userId, pkg);
-            final ArrayMap<String, NotificationAttributes> children =
-                    mUngroupedNotifications.getOrDefault(key, new ArrayMap<>());
-            return children.size();
-        }
-    }
-
     NotificationAttributes getAutobundledSummaryAttributes(@NonNull String packageName,
             @NonNull List<NotificationAttributes> childrenAttr) {
         Icon newIcon = null;
@@ -338,7 +405,20 @@
             newColor = COLOR_DEFAULT;
         }
 
-        return new NotificationAttributes(0, newIcon, newColor, newVisibility);
+        // Use GROUP_ALERT_CHILDREN
+        // Unless all children have GROUP_ALERT_SUMMARY => avoid muting all notifications in group
+        int newGroupAlertBehavior = Notification.GROUP_ALERT_SUMMARY;
+        for (NotificationAttributes attr: childrenAttr) {
+            if (attr.groupAlertBehavior != Notification.GROUP_ALERT_SUMMARY) {
+                newGroupAlertBehavior = Notification.GROUP_ALERT_CHILDREN;
+                break;
+            }
+        }
+
+        String channelId = !childrenAttr.isEmpty() ? childrenAttr.get(0).channelId : null;
+
+        return new NotificationAttributes(0, newIcon, newColor, newVisibility,
+                newGroupAlertBehavior, channelId);
     }
 
     NotificationAttributes updateAutobundledSummaryAttributes(@NonNull String packageName,
@@ -348,14 +428,28 @@
                 childrenAttr);
         Icon newIcon = newAttr.icon;
         int newColor = newAttr.iconColor;
+        String newChannelId = newAttr.channelId;
         if (newAttr.icon == null) {
             newIcon = oldAttr.icon;
         }
         if (newAttr.iconColor == Notification.COLOR_INVALID) {
             newColor = oldAttr.iconColor;
         }
+        if (newAttr.channelId == null) {
+            newChannelId = oldAttr.channelId;
+        }
 
-        return new NotificationAttributes(oldAttr.flags, newIcon, newColor, newAttr.visibility);
+        return new NotificationAttributes(oldAttr.flags, newIcon, newColor, newAttr.visibility,
+                oldAttr.groupAlertBehavior, newChannelId);
+    }
+
+    private NotificationAttributes getSummaryAttributes(String pkgName,
+            ArrayMap<String, NotificationAttributes> childrenMap) {
+        int flags = getAutogroupSummaryFlags(childrenMap);
+        NotificationAttributes attr = getAutobundledSummaryAttributes(pkgName,
+                childrenMap.values().stream().toList());
+        return new NotificationAttributes(flags, attr.icon, attr.iconColor, attr.visibility,
+                attr.groupAlertBehavior, attr.channelId);
     }
 
     /**
@@ -388,17 +482,865 @@
         }
     }
 
+    /**
+     * A non-app grouped notification has been added or updated
+     * Evaluate if:
+     * (a) an existing autogroup summary needs updated attributes
+     * (b) a new autogroup summary needs to be added with correct attributes
+     * (c) other non-app grouped children need to be moved to the autogroup
+     *
+     * This method implements autogrouping with sections support.
+     *
+     * And stores the list of upgrouped notifications & their flags
+     */
+    private boolean maybeGroupWithSections(NotificationRecord record,
+            boolean autogroupSummaryExists) {
+        final StatusBarNotification sbn = record.getSbn();
+        boolean sbnToBeAutogrouped = false;
+
+        final NotificationSectioner sectioner = getSection(record);
+        if (sectioner == null) {
+            if (DEBUG) {
+                Log.i(TAG, "Skipping autogrouping for " + record + " no valid section found.");
+            }
+            return false;
+        }
+
+        final String pkgName = sbn.getPackageName();
+        final FullyQualifiedGroupKey fullAggregateGroupKey = new FullyQualifiedGroupKey(
+                record.getUserId(), pkgName, sectioner);
+
+        // This notification is already aggregated
+        if (record.getGroupKey().equals(fullAggregateGroupKey.toString())) {
+            return false;
+        }
+
+        synchronized (mAggregatedNotifications) {
+            ArrayMap<String, NotificationAttributes> ungrouped =
+                mUngroupedAbuseNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+            ungrouped.put(record.getKey(), new NotificationAttributes(
+                record.getFlags(),
+                record.getNotification().getSmallIcon(),
+                record.getNotification().color,
+                record.getNotification().visibility,
+                record.getNotification().getGroupAlertBehavior(),
+                record.getChannel().getId()));
+            mUngroupedAbuseNotifications.put(fullAggregateGroupKey, ungrouped);
+
+            // scenario 0: ungrouped notifications
+            if (ungrouped.size() >= mAutoGroupAtCount || autogroupSummaryExists) {
+                if (DEBUG) {
+                    if (ungrouped.size() >= mAutoGroupAtCount) {
+                        Log.i(TAG,
+                            "Found >=" + mAutoGroupAtCount
+                                + " ungrouped notifications => force grouping");
+                    } else {
+                        Log.i(TAG, "Found aggregate summary => force grouping");
+                    }
+                }
+
+                final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+                    mAggregatedNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+                aggregatedNotificationsAttrs.putAll(ungrouped);
+                mAggregatedNotifications.put(fullAggregateGroupKey, aggregatedNotificationsAttrs);
+
+                // add/update aggregate summary
+                updateAggregateAppGroup(fullAggregateGroupKey, record.getKey(),
+                        autogroupSummaryExists, sectioner.mSummaryId);
+
+                // add notification to aggregate group
+                for (String keyToGroup : ungrouped.keySet()) {
+                    if (android.app.Flags.checkAutogroupBeforePost()) {
+                        if (keyToGroup.equals(record.getKey())) {
+                            // Autogrouping for the posted notification is to be done synchronously.
+                            sbnToBeAutogrouped = true;
+                        } else {
+                            mCallback.addAutoGroup(keyToGroup, fullAggregateGroupKey.toString(),
+                                    true);
+                        }
+                    } else {
+                        mCallback.addAutoGroup(keyToGroup, fullAggregateGroupKey.toString(), true);
+                    }
+                }
+
+                //cleanup mUngroupedAbuseNotifications
+                mUngroupedAbuseNotifications.remove(fullAggregateGroupKey);
+            }
+        }
+
+        return sbnToBeAutogrouped;
+    }
+
+    /**
+     * A notification was added that's app grouped.
+     * Evaluate whether:
+     * (a) an existing autogroup summary needs updated attributes
+     * (b) if we need to remove our autogroup overlay for this notification
+     * (c) we need to remove the autogroup summary
+     *
+     * This method implements autogrouping with sections support.
+     *
+     * And updates the internal state of un-app-grouped notifications and their flags.
+     */
+    private void maybeUngroupWithSections(NotificationRecord record) {
+        final StatusBarNotification sbn = record.getSbn();
+        final String pkgName = sbn.getPackageName();
+        final int userId = record.getUserId();
+        final FullyQualifiedGroupKey fullAggregateGroupKey = new FullyQualifiedGroupKey(userId,
+                pkgName, getSection(record));
+
+        synchronized (mAggregatedNotifications) {
+            // if this notification still exists and has an autogroup overlay, but is now
+            // grouped by the app, clear the overlay
+            ArrayMap<String, NotificationAttributes> ungrouped =
+                mUngroupedAbuseNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+            ungrouped.remove(sbn.getKey());
+            mUngroupedAbuseNotifications.put(fullAggregateGroupKey, ungrouped);
+
+            final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+                mAggregatedNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+            // check if the removed notification was part of the aggregate group
+            if (aggregatedNotificationsAttrs.containsKey(record.getKey())) {
+                aggregatedNotificationsAttrs.remove(sbn.getKey());
+                mAggregatedNotifications.put(fullAggregateGroupKey, aggregatedNotificationsAttrs);
+
+                if (DEBUG) {
+                    Log.i(TAG, "maybeUngroup removeAutoGroup: " + record);
+                }
+
+                mCallback.removeAutoGroup(sbn.getKey());
+
+                if (aggregatedNotificationsAttrs.isEmpty()) {
+                    if (DEBUG) {
+                        Log.i(TAG, "Aggregate group is empty: " + fullAggregateGroupKey);
+                    }
+                    mCallback.removeAutoGroupSummary(userId, pkgName,
+                            fullAggregateGroupKey.toString());
+                    mAggregatedNotifications.remove(fullAggregateGroupKey);
+                } else {
+                    if (DEBUG) {
+                        Log.i(TAG, "Aggregate group not empty, updating: " + fullAggregateGroupKey);
+                    }
+                    updateAggregateAppGroup(fullAggregateGroupKey, sbn.getKey(), true, 0);
+                }
+            }
+        }
+    }
+
+    /**
+     * Called when a notification is newly posted, after some delay, so that the app
+     * has a chance to post a group summary or children (complete a group).
+     * Checks whether that notification and other active notifications should be forced grouped
+     * because their grouping is incorrect:
+     *  - missing summary
+     *  - only summaries
+     *  - sparse groups == multiple groups with very few notifications
+     *
+     * @param record the notification that was posted
+     * @param notificationList the full notification list from NotificationManagerService
+     * @param summaryByGroupKey the map of group summaries from NotificationManagerService
+     */
+    @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING)
+    protected void onNotificationPostedWithDelay(final NotificationRecord record,
+            final List<NotificationRecord> notificationList,
+            final Map<String, NotificationRecord> summaryByGroupKey) {
+        // Ungrouped notifications are handled separately in
+        // {@link #onNotificationPosted(StatusBarNotification, boolean)}
+        final StatusBarNotification sbn = record.getSbn();
+        if (!sbn.isAppGroup()) {
+            return;
+        }
+
+        if (record.isCanceled) {
+            return;
+        }
+
+        final NotificationSectioner sectioner = getSection(record);
+        if (sectioner == null) {
+            if (DEBUG) {
+                Log.i(TAG, "Skipping autogrouping for " + record + " no valid section found.");
+            }
+            return;
+        }
+
+        final String pkgName = sbn.getPackageName();
+        final FullyQualifiedGroupKey fullAggregateGroupKey = new FullyQualifiedGroupKey(
+                record.getUserId(), pkgName, sectioner);
+
+        // This notification is already aggregated
+        if (record.getGroupKey().equals(fullAggregateGroupKey.toString())) {
+            return;
+        }
+
+        synchronized (mAggregatedNotifications) {
+            // scenario 1: group w/o summary
+            // scenario 2: summary w/o children
+            if (isGroupChildWithoutSummary(record, summaryByGroupKey) ||
+                isGroupSummaryWithoutChildren(record, notificationList)) {
+                if (DEBUG) {
+                    Log.i(TAG, "isGroupChildWithoutSummary OR isGroupSummaryWithoutChild"
+                            + record);
+                }
+
+                ArrayMap<String, NotificationAttributes> ungrouped =
+                        mUngroupedAbuseNotifications.getOrDefault(fullAggregateGroupKey,
+                            new ArrayMap<>());
+                ungrouped.put(record.getKey(), new NotificationAttributes(
+                    record.getFlags(),
+                    record.getNotification().getSmallIcon(),
+                    record.getNotification().color,
+                    record.getNotification().visibility,
+                    record.getNotification().getGroupAlertBehavior(),
+                    record.getChannel().getId()));
+                mUngroupedAbuseNotifications.put(fullAggregateGroupKey, ungrouped);
+                // Create/update summary and group if >= mAutoGroupAtCount notifications
+                //  or if aggregate group exists
+                boolean hasSummary = !mAggregatedNotifications.getOrDefault(fullAggregateGroupKey,
+                    new ArrayMap<>()).isEmpty();
+                if (ungrouped.size() >= mAutoGroupAtCount || hasSummary) {
+                    if (DEBUG) {
+                        if (ungrouped.size() >= mAutoGroupAtCount) {
+                            Log.i(TAG,
+                                "Found >=" + mAutoGroupAtCount
+                                    + " ungrouped notifications => force grouping");
+                        } else {
+                            Log.i(TAG, "Found aggregate summary => force grouping");
+                        }
+                    }
+                    aggregateUngroupedNotifications(fullAggregateGroupKey, sbn.getKey(),
+                            ungrouped, hasSummary, sectioner.mSummaryId);
+                }
+
+                return;
+            }
+
+            // scenario 3: sparse/singleton groups
+            if (Flags.notificationForceGroupSingletons()) {
+                groupSparseGroups(record, notificationList, summaryByGroupKey, sectioner,
+                    fullAggregateGroupKey);
+            }
+        }
+    }
+
+    /**
+     * Called when a notification is removed, so that this helper can adjust the aggregate groups:
+     *  - Removes the autogroup summary of the notification's section
+     *      if the record was the last child.
+     *  - Recalculates the autogroup summary "attributes":
+     *      icon, icon color, visibility, groupAlertBehavior, flags - if the removed record was
+     *  part of an autogroup.
+     *  - Removes the saved summary of the original group, if the record was the last remaining
+     *      child of a sparse group that was forced auto-grouped.
+     *
+     * see also {@link #onNotificationPostedWithDelay(NotificationRecord, List, Map)}
+     *
+     * @param record the removed notification
+     * @param notificationList the full notification list from NotificationManagerService
+     */
+    @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING)
+    protected void onNotificationRemoved(final NotificationRecord record,
+                final List<NotificationRecord> notificationList) {
+        final StatusBarNotification sbn = record.getSbn();
+        final String pkgName = sbn.getPackageName();
+        final int userId = record.getUserId();
+        final FullyQualifiedGroupKey fullAggregateGroupKey = new FullyQualifiedGroupKey(userId,
+                pkgName, getSection(record));
+
+        synchronized (mAggregatedNotifications) {
+            ArrayMap<String, NotificationAttributes> ungrouped =
+                mUngroupedAbuseNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+            ungrouped.remove(record.getKey());
+            mUngroupedAbuseNotifications.put(fullAggregateGroupKey, ungrouped);
+
+            final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+                mAggregatedNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+            // check if the removed notification was part of the aggregate group
+            if (record.getGroupKey().equals(fullAggregateGroupKey.toString())
+                    || aggregatedNotificationsAttrs.containsKey(record.getKey())) {
+                aggregatedNotificationsAttrs.remove(record.getKey());
+                mAggregatedNotifications.put(fullAggregateGroupKey, aggregatedNotificationsAttrs);
+
+                if (aggregatedNotificationsAttrs.isEmpty()) {
+                    if (DEBUG) {
+                        Log.i(TAG, "Aggregate group is empty: " + fullAggregateGroupKey);
+                    }
+                    mCallback.removeAutoGroupSummary(userId, pkgName,
+                            fullAggregateGroupKey.toString());
+                    mAggregatedNotifications.remove(fullAggregateGroupKey);
+                } else {
+                    if (DEBUG) {
+                        Log.i(TAG, "Aggregate group not empty, updating: " + fullAggregateGroupKey);
+                    }
+                    updateAggregateAppGroup(fullAggregateGroupKey, sbn.getKey(), true, 0);
+                }
+
+                // Try to cleanup cached summaries if notification was canceled (not snoozed)
+                if (record.isCanceled) {
+                    maybeClearCanceledSummariesCache(pkgName, userId,
+                            record.getNotification().getGroup(), notificationList);
+                }
+            }
+        }
+    }
+
+    private record NotificationMoveOp(NotificationRecord record, FullyQualifiedGroupKey oldGroup,
+                                      FullyQualifiedGroupKey newGroup) { }
+
+    /**
+     * Called when a notification channel is updated, so that this helper can adjust
+     * the aggregate groups by moving children if their section has changed.
+     * see {@link #onNotificationPostedWithDelay(NotificationRecord, List, Map)}
+     * @param userId the userId of the channel
+     * @param pkgName the channel's package
+     * @param channel the channel that was updated
+     * @param notificationList the full notification list from NotificationManagerService
+     */
+    @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void onChannelUpdated(final int userId, final String pkgName,
+            final NotificationChannel channel, final List<NotificationRecord> notificationList) {
+        synchronized (mAggregatedNotifications) {
+            ArrayMap<String, NotificationRecord> notificationsToCheck = new ArrayMap<>();
+            for (NotificationRecord r : notificationList) {
+                if (r.getChannel().getId().equals(channel.getId())
+                    && r.getSbn().getPackageName().equals(pkgName)
+                    && r.getUserId() == userId) {
+                    notificationsToCheck.put(r.getKey(), r);
+                }
+            }
+
+            final ArrayList<NotificationMoveOp> notificationsToMove = new ArrayList<>();
+
+            final Set<FullyQualifiedGroupKey> oldGroups =
+                    new HashSet<>(mAggregatedNotifications.keySet());
+            for (FullyQualifiedGroupKey oldFullAggKey : oldGroups) {
+                // Only check aggregate groups that match the same userId & packageName
+                if (pkgName.equals(oldFullAggKey.pkg) && userId == oldFullAggKey.userId) {
+                    final ArrayMap<String, NotificationAttributes> notificationsInAggGroup =
+                            mAggregatedNotifications.get(oldFullAggKey);
+                    if (notificationsInAggGroup == null) {
+                        continue;
+                    }
+
+                    FullyQualifiedGroupKey newFullAggregateGroupKey = null;
+                    for (String key : notificationsInAggGroup.keySet()) {
+                        if (notificationsToCheck.get(key) != null) {
+                            // check if section changes
+                            NotificationSectioner sectioner = getSection(
+                                    notificationsToCheck.get(key));
+                            if (sectioner == null) {
+                                continue;
+                            }
+                            newFullAggregateGroupKey = new FullyQualifiedGroupKey(userId, pkgName,
+                                    sectioner);
+                            if (!oldFullAggKey.equals(newFullAggregateGroupKey)) {
+                                if (DEBUG) {
+                                    Log.i(TAG, "Change section on channel update: " + key);
+                                }
+                                notificationsToMove.add(
+                                        new NotificationMoveOp(notificationsToCheck.get(key),
+                                            oldFullAggKey, newFullAggregateGroupKey));
+                            }
+                        }
+                    }
+
+                    if (newFullAggregateGroupKey != null) {
+                        // Add any notifications left ungrouped to the new section
+                        ArrayMap<String, NotificationAttributes> ungrouped =
+                            mUngroupedAbuseNotifications.get(newFullAggregateGroupKey);
+                        if (ungrouped != null) {
+                            for (NotificationRecord r : notificationList) {
+                                if (ungrouped.containsKey(r.getKey())) {
+                                    if (DEBUG) {
+                                        Log.i(TAG, "Add previously ungrouped: " + r);
+                                    }
+                                    notificationsToMove.add(
+                                        new NotificationMoveOp(r, null, newFullAggregateGroupKey));
+                                }
+                            }
+                            //Cleanup mUngroupedAbuseNotifications
+                            mUngroupedAbuseNotifications.remove(newFullAggregateGroupKey);
+                        }
+                    }
+                }
+            }
+
+            // Batch move to new section
+            if (!notificationsToMove.isEmpty()) {
+                moveNotificationsToNewSection(userId, pkgName, notificationsToMove);
+            }
+        }
+    }
+
+    @GuardedBy("mAggregatedNotifications")
+    private void moveNotificationsToNewSection(final int userId, final String pkgName,
+            final List<NotificationMoveOp> notificationsToMove) {
+        record GroupUpdateOp(FullyQualifiedGroupKey groupKey, NotificationRecord record,
+                             boolean hasSummary) { }
+        ArrayMap<FullyQualifiedGroupKey, GroupUpdateOp> groupsToUpdate = new ArrayMap<>();
+
+        for (NotificationMoveOp moveOp: notificationsToMove) {
+            final NotificationRecord record = moveOp.record;
+            final FullyQualifiedGroupKey oldFullAggregateGroupKey = moveOp.oldGroup;
+            final FullyQualifiedGroupKey newFullAggregateGroupKey = moveOp.newGroup;
+
+            if (DEBUG) {
+                Log.i(TAG,
+                    "moveNotificationToNewSection: " + record + " " + newFullAggregateGroupKey
+                        + " from: " + oldFullAggregateGroupKey);
+            }
+
+            // Update/remove aggregate summary for old group
+            if (oldFullAggregateGroupKey != null) {
+                final ArrayMap<String, NotificationAttributes> oldAggregatedNotificationsAttrs =
+                        mAggregatedNotifications.getOrDefault(oldFullAggregateGroupKey,
+                            new ArrayMap<>());
+                oldAggregatedNotificationsAttrs.remove(record.getKey());
+                mAggregatedNotifications.put(oldFullAggregateGroupKey,
+                        oldAggregatedNotificationsAttrs);
+
+                // Only add once, for triggering notification
+                if (!groupsToUpdate.containsKey(oldFullAggregateGroupKey)) {
+                    groupsToUpdate.put(oldFullAggregateGroupKey,
+                            new GroupUpdateOp(oldFullAggregateGroupKey, record, true));
+                }
+            }
+
+            // Add/update aggregate summary for new group
+            if (newFullAggregateGroupKey != null) {
+                final ArrayMap<String, NotificationAttributes> newAggregatedNotificationsAttrs =
+                        mAggregatedNotifications.getOrDefault(newFullAggregateGroupKey,
+                            new ArrayMap<>());
+                boolean newGroupExists = !newAggregatedNotificationsAttrs.isEmpty();
+                newAggregatedNotificationsAttrs.put(record.getKey(),
+                        new NotificationAttributes(record.getFlags(),
+                            record.getNotification().getSmallIcon(),
+                            record.getNotification().color,
+                            record.getNotification().visibility,
+                            record.getNotification().getGroupAlertBehavior(),
+                            record.getChannel().getId()));
+                mAggregatedNotifications.put(newFullAggregateGroupKey,
+                        newAggregatedNotificationsAttrs);
+
+                // Only add once, for triggering notification
+                if (!groupsToUpdate.containsKey(newFullAggregateGroupKey)) {
+                    groupsToUpdate.put(newFullAggregateGroupKey,
+                            new GroupUpdateOp(newFullAggregateGroupKey, record, newGroupExists));
+                }
+
+                // Add notification to new group. do not request resort
+                record.setOverrideGroupKey(null);
+                mCallback.addAutoGroup(record.getKey(), newFullAggregateGroupKey.toString(), false);
+            }
+        }
+
+        // Update groups (sections)
+        for (FullyQualifiedGroupKey groupKey : groupsToUpdate.keySet()) {
+            final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+                    mAggregatedNotifications.getOrDefault(groupKey, new ArrayMap<>());
+            if (aggregatedNotificationsAttrs.isEmpty()) {
+                mCallback.removeAutoGroupSummary(userId, pkgName, groupKey.toString());
+                mAggregatedNotifications.remove(groupKey);
+            } else {
+                NotificationRecord triggeringNotification = groupsToUpdate.get(groupKey).record;
+                boolean hasSummary = groupsToUpdate.get(groupKey).hasSummary;
+                NotificationSectioner sectioner = getSection(triggeringNotification);
+                if (sectioner == null) {
+                    continue;
+                }
+                updateAggregateAppGroup(groupKey, triggeringNotification.getKey(), hasSummary,
+                        sectioner.mSummaryId);
+            }
+        }
+    }
+
+    static String getFullAggregateGroupKey(String pkgName,
+            String groupName, int userId) {
+        return new FullyQualifiedGroupKey(userId, pkgName, groupName).toString();
+    }
+
+    /**
+     * Returns the full aggregate group key, which contains the userId and package name
+     * in addition to the aggregate group key (name).
+     * Equivalent to {@link StatusBarNotification#groupKey()}
+     */
+    static String getFullAggregateGroupKey(NotificationRecord record) {
+        return new FullyQualifiedGroupKey(record.getUserId(), record.getSbn().getPackageName(),
+                getSection(record)).toString();
+    }
+
+    protected static boolean isAggregatedGroup(NotificationRecord record) {
+        return (record.mOriginalFlags & Notification.FLAG_AUTOGROUP_SUMMARY) != 0;
+    }
+
+    private static int getNumChildrenForGroup(@NonNull final String groupKey,
+            final List<NotificationRecord> notificationList) {
+        //TODO (b/349072751): track grouping state in GroupHelper -> do not use notificationList
+        int numChildren = 0;
+        // find children for this summary
+        for (NotificationRecord r : notificationList) {
+            if (!r.getNotification().isGroupSummary()
+                    && groupKey.equals(r.getSbn().getGroup())) {
+                numChildren++;
+            }
+        }
+
+        if (DEBUG) {
+            Log.i(TAG, "getNumChildrenForGroup " + groupKey + " numChild: " + numChildren);
+        }
+        return numChildren;
+    }
+
+    private static boolean isGroupSummaryWithoutChildren(final NotificationRecord record,
+            final List<NotificationRecord> notificationList) {
+        final StatusBarNotification sbn = record.getSbn();
+        final String groupKey = record.getSbn().getGroup();
+
+        // ignore non app groups and non summaries
+        if (!sbn.isAppGroup() || !record.getNotification().isGroupSummary()) {
+            return false;
+        }
+
+        return getNumChildrenForGroup(groupKey, notificationList) == 0;
+    }
+
+    private static boolean isGroupChildWithoutSummary(final NotificationRecord record,
+            final Map<String, NotificationRecord> summaryByGroupKey) {
+        final StatusBarNotification sbn = record.getSbn();
+        final String groupKey = record.getSbn().getGroupKey();
+
+        if (!sbn.isAppGroup()) {
+            return false;
+        }
+
+        if (record.getNotification().isGroupSummary()) {
+            return false;
+        }
+
+        if (summaryByGroupKey.containsKey(groupKey)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @GuardedBy("mAggregatedNotifications")
+    private void aggregateUngroupedNotifications(FullyQualifiedGroupKey fullAggregateGroupKey,
+            String triggeringNotifKey, Map<String, NotificationAttributes> ungrouped,
+            final boolean hasSummary, int summaryId) {
+        final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+                mAggregatedNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+        aggregatedNotificationsAttrs.putAll(ungrouped);
+        mAggregatedNotifications.put(fullAggregateGroupKey, aggregatedNotificationsAttrs);
+
+        // add/update aggregate summary
+        updateAggregateAppGroup(fullAggregateGroupKey, triggeringNotifKey, hasSummary, summaryId);
+
+        // add notification to aggregate group
+        for (String key: ungrouped.keySet()) {
+            mCallback.addAutoGroup(key, fullAggregateGroupKey.toString(), true);
+        }
+
+        //cleanup mUngroupedAbuseNotifications
+        mUngroupedAbuseNotifications.remove(fullAggregateGroupKey);
+    }
+
+    @GuardedBy("mAggregatedNotifications")
+    private void updateAggregateAppGroup(FullyQualifiedGroupKey fullAggregateGroupKey,
+            String triggeringNotifKey, boolean hasSummary, int summaryId) {
+        final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+                mAggregatedNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+        NotificationAttributes attr = getSummaryAttributes(fullAggregateGroupKey.pkg,
+                aggregatedNotificationsAttrs);
+        String channelId = hasSummary ? attr.channelId
+                : aggregatedNotificationsAttrs.get(triggeringNotifKey).channelId;
+        NotificationAttributes summaryAttr = new NotificationAttributes(attr.flags, attr.icon,
+                attr.iconColor, attr.visibility, attr.groupAlertBehavior, channelId);
+
+        if (!hasSummary) {
+            if (DEBUG) {
+                Log.i(TAG, "Create aggregate summary: " + fullAggregateGroupKey);
+            }
+            mCallback.addAutoGroupSummary(fullAggregateGroupKey.userId, fullAggregateGroupKey.pkg,
+                    triggeringNotifKey, fullAggregateGroupKey.toString(), summaryId, summaryAttr);
+        } else {
+            if (DEBUG) {
+                Log.i(TAG, "Update aggregate summary: " + fullAggregateGroupKey);
+            }
+            mCallback.updateAutogroupSummary(fullAggregateGroupKey.userId,
+                    fullAggregateGroupKey.pkg, fullAggregateGroupKey.toString(), summaryAttr);
+        }
+    }
+
+    @GuardedBy("mAggregatedNotifications")
+    private void groupSparseGroups(final NotificationRecord record,
+            final List<NotificationRecord> notificationList,
+            final Map<String, NotificationRecord> summaryByGroupKey,
+            final NotificationSectioner sectioner,
+            final FullyQualifiedGroupKey fullAggregateGroupKey) {
+        final ArrayMap<String, NotificationRecord> sparseGroupSummaries = getSparseGroups(
+                fullAggregateGroupKey, notificationList, summaryByGroupKey, sectioner);
+        if (sparseGroupSummaries.size() >= mAutogroupSparseGroupsAtCount) {
+            if (DEBUG) {
+                Log.i(TAG,
+                    "Aggregate sparse groups for: " + record.getSbn().getPackageName()
+                        + " Section: " + sectioner.mName);
+            }
+
+            ArrayMap<String, NotificationAttributes> ungrouped =
+                    mUngroupedAbuseNotifications.getOrDefault(
+                        fullAggregateGroupKey, new ArrayMap<>());
+            final ArrayMap<String, NotificationAttributes> aggregatedNotificationsAttrs =
+                    mAggregatedNotifications.getOrDefault(fullAggregateGroupKey, new ArrayMap<>());
+            final boolean hasSummary = !aggregatedNotificationsAttrs.isEmpty();
+            for (NotificationRecord r : notificationList) {
+                // Add notifications for detected sparse groups
+                if (sparseGroupSummaries.containsKey(r.getGroupKey())) {
+                    // Move child notifications to aggregate group
+                    if (!r.getNotification().isGroupSummary()) {
+                        if (DEBUG) {
+                            Log.i(TAG, "Aggregate notification (sparse group): " + r);
+                        }
+                        mCallback.addAutoGroup(r.getKey(), fullAggregateGroupKey.toString(), true);
+                        aggregatedNotificationsAttrs.put(r.getKey(),
+                            new NotificationAttributes(r.getFlags(),
+                                r.getNotification().getSmallIcon(), r.getNotification().color,
+                                r.getNotification().visibility,
+                                r.getNotification().getGroupAlertBehavior(),
+                                r.getChannel().getId()));
+
+                    } else if (r.getNotification().isGroupSummary()) {
+                        // Remove summary notifications
+                        if (DEBUG) {
+                            Log.i(TAG, "Remove app summary (sparse group): " + r);
+                        }
+                        mCallback.removeAppProvidedSummary(r.getKey());
+                        cacheCanceledSummary(r);
+                    }
+                } else {
+                    // Add any notifications left ungrouped
+                    if (ungrouped.containsKey(r.getKey())) {
+                        if (DEBUG) {
+                            Log.i(TAG, "Aggregate ungrouped (sparse group): " + r);
+                        }
+                        mCallback.addAutoGroup(r.getKey(), fullAggregateGroupKey.toString(), true);
+                        aggregatedNotificationsAttrs.put(r.getKey(),ungrouped.get(r.getKey()));
+                    }
+                }
+            }
+
+            mAggregatedNotifications.put(fullAggregateGroupKey, aggregatedNotificationsAttrs);
+            // add/update aggregate summary
+            updateAggregateAppGroup(fullAggregateGroupKey, record.getKey(), hasSummary,
+                    sectioner.mSummaryId);
+
+            //cleanup mUngroupedAbuseNotifications
+            mUngroupedAbuseNotifications.remove(fullAggregateGroupKey);
+        }
+    }
+
+    private ArrayMap<String, NotificationRecord> getSparseGroups(
+            final FullyQualifiedGroupKey fullAggregateGroupKey,
+            final List<NotificationRecord> notificationList,
+            final Map<String, NotificationRecord> summaryByGroupKey,
+            final NotificationSectioner sectioner) {
+        ArrayMap<String, NotificationRecord> sparseGroups = new ArrayMap<>();
+        for (NotificationRecord summary : summaryByGroupKey.values()) {
+            if (summary != null && sectioner.isInSection(summary)) {
+                if (summary.getSbn().getPackageName().equalsIgnoreCase(fullAggregateGroupKey.pkg)
+                        && summary.getUserId() == fullAggregateGroupKey.userId
+                        && summary.getSbn().isAppGroup()
+                        && !summary.getGroupKey().equals(fullAggregateGroupKey.toString())) {
+                    int numChildren = getNumChildrenForGroup(summary.getSbn().getGroup(),
+                            notificationList);
+                    if (numChildren > 0 && numChildren < MIN_CHILD_COUNT_TO_AVOID_FORCE_GROUPING) {
+                        sparseGroups.put(summary.getGroupKey(), summary);
+                    }
+                }
+            }
+        }
+        return sparseGroups;
+    }
+
+    @GuardedBy("mAggregatedNotifications")
+    private void cacheCanceledSummary(NotificationRecord record) {
+        final FullyQualifiedGroupKey groupKey = new FullyQualifiedGroupKey(record.getUserId(),
+                record.getSbn().getPackageName(), record.getNotification().getGroup());
+        mCanceledSummaries.put(groupKey, new CachedSummary(record.getSbn().getId(),
+                record.getSbn().getTag(), record.getNotification().getGroup(), record.getKey()));
+    }
+
+    @GuardedBy("mAggregatedNotifications")
+    private void maybeClearCanceledSummariesCache(String pkgName, int userId,
+            String groupName, List<NotificationRecord> notificationList) {
+        final FullyQualifiedGroupKey findKey = new FullyQualifiedGroupKey(userId, pkgName,
+                groupName);
+        CachedSummary summary = mCanceledSummaries.get(findKey);
+        // Check if any notifications from original group remain
+        if (summary != null) {
+            if (DEBUG) {
+                Log.i(TAG, "Try removing cached summary: " + summary);
+            }
+            boolean stillHasChildren = false;
+            //TODO (b/349072751): track grouping state in GroupHelper -> do not use notificationList
+            for (NotificationRecord r : notificationList) {
+                if (summary.originalGroupKey.equals(r.getNotification().getGroup())
+                    && r.getUser().getIdentifier() == userId
+                    && r.getSbn().getPackageName().equals(pkgName)) {
+                    stillHasChildren = true;
+                    break;
+                }
+            }
+            if (!stillHasChildren) {
+                removeCachedSummary(pkgName, userId, summary);
+            }
+        }
+    }
+
+    @VisibleForTesting
+    @GuardedBy("mAggregatedNotifications")
+    protected CachedSummary findCanceledSummary(String pkgName, String tag, int id, int userId) {
+        for (FullyQualifiedGroupKey key: mCanceledSummaries.keySet()) {
+            if (pkgName.equals(key.pkg) && userId == key.userId) {
+                CachedSummary summary = mCanceledSummaries.get(key);
+                if (summary != null && summary.id == id && TextUtils.equals(tag, summary.tag)) {
+                    return summary;
+                }
+            }
+        }
+        return null;
+    }
+
+    @VisibleForTesting
+    @GuardedBy("mAggregatedNotifications")
+    protected CachedSummary findCanceledSummary(String pkgName, String tag, int id, int userId,
+            String groupName) {
+        final FullyQualifiedGroupKey findKey = new FullyQualifiedGroupKey(userId, pkgName,
+                groupName);
+        CachedSummary summary = mCanceledSummaries.get(findKey);
+        if (summary != null && summary.id == id && TextUtils.equals(tag, summary.tag)) {
+            return summary;
+        } else {
+            return null;
+        }
+    }
+
+    @GuardedBy("mAggregatedNotifications")
+    private void removeCachedSummary(String pkgName, int userId, CachedSummary summary) {
+        final FullyQualifiedGroupKey key = new FullyQualifiedGroupKey(userId, pkgName,
+                summary.originalGroupKey);
+        mCanceledSummaries.remove(key);
+    }
+
+    protected boolean isUpdateForCanceledSummary(final NotificationRecord record) {
+        synchronized (mAggregatedNotifications) {
+            if (record.getSbn().isAppGroup() && record.getNotification().isGroupSummary()) {
+                CachedSummary cachedSummary = findCanceledSummary(record.getSbn().getPackageName(),
+                        record.getSbn().getTag(), record.getSbn().getId(), record.getUserId(),
+                        record.getNotification().getGroup());
+                return cachedSummary != null;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Cancels the original group's children when an app cancels a summary that was 'maybe'
+     * previously removed due to forced grouping of a "sparse group".
+     *
+     * @param pkgName packageName
+     * @param tag original summary notification tag
+     * @param id original summary notification id
+     * @param userId original summary userId
+     */
+    @FlaggedApi(Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS)
+    public void maybeCancelGroupChildrenForCanceledSummary(String pkgName, String tag, int id,
+            int userId, int cancelReason) {
+        synchronized (mAggregatedNotifications) {
+            final CachedSummary summary = findCanceledSummary(pkgName, tag, id, userId);
+            if (summary != null) {
+                if (DEBUG) {
+                    Log.i(TAG, "Found cached summary: " + summary.key);
+                }
+                mCallback.removeNotificationFromCanceledGroup(userId, pkgName,
+                        summary.originalGroupKey, cancelReason);
+                removeCachedSummary(pkgName, userId, summary);
+            }
+        }
+    }
+
+    static NotificationSectioner getSection(final NotificationRecord record) {
+        for (NotificationSectioner sectioner: NOTIFICATION_SHADE_SECTIONS) {
+            if (sectioner.isInSection(record)) {
+                return sectioner;
+            }
+        }
+        return null;
+    }
+
+    record FullyQualifiedGroupKey(int userId, String pkg, String groupName) {
+        FullyQualifiedGroupKey(int userId, String pkg, @Nullable NotificationSectioner sectioner) {
+            this(userId, pkg, AGGREGATE_GROUP_KEY + (sectioner != null ? sectioner.mName : ""));
+        }
+
+        @Override
+        public String toString() {
+            return userId + "|" + pkg + "|" + "g:" + groupName;
+        }
+    }
+
+    protected static class NotificationSectioner {
+        final String mName;
+        final int mSummaryId;
+        private final Predicate<NotificationRecord> mSectionChecker;
+
+        public NotificationSectioner(String name, int summaryId,
+                Predicate<NotificationRecord> sectionChecker) {
+            mName = name;
+            mSummaryId = summaryId;
+            mSectionChecker = sectionChecker;
+        }
+
+        boolean isInSection(final NotificationRecord record) {
+            return isNotificationGroupable(record) && mSectionChecker.test(record);
+        }
+
+        private boolean isNotificationGroupable(final NotificationRecord record) {
+            if (record.isConversation()) {
+                return false;
+            }
+
+            Notification notification = record.getSbn().getNotification();
+            boolean isColorizedFGS = notification.isForegroundService()
+                && notification.isColorized()
+                && record.getImportance() > NotificationManager.IMPORTANCE_MIN;
+            boolean isCall = record.getImportance() > NotificationManager.IMPORTANCE_MIN
+                && notification.isStyle(Notification.CallStyle.class);
+            if (isColorizedFGS || isCall) {
+                return false;
+            }
+
+            return true;
+        }
+    }
+
+    record CachedSummary(int id, String tag, String originalGroupKey, String key) {}
+
     protected static class NotificationAttributes {
         public final int flags;
         public final int iconColor;
         public final Icon icon;
         public final int visibility;
+        public final int groupAlertBehavior;
+        public final String channelId;
 
-        public NotificationAttributes(int flags, Icon icon, int iconColor, int visibility) {
+        public NotificationAttributes(int flags, Icon icon, int iconColor, int visibility,
+                int groupAlertBehavior, String channelId) {
             this.flags = flags;
             this.icon = icon;
             this.iconColor = iconColor;
             this.visibility = visibility;
+            this.groupAlertBehavior = groupAlertBehavior;
+            this.channelId = channelId;
         }
 
         public NotificationAttributes(@NonNull NotificationAttributes attr) {
@@ -406,6 +1348,8 @@
             this.icon = attr.icon;
             this.iconColor = attr.iconColor;
             this.visibility = attr.visibility;
+            this.groupAlertBehavior = attr.groupAlertBehavior;
+            this.channelId = attr.channelId;
         }
 
         @Override
@@ -417,22 +1361,39 @@
                 return false;
             }
             return flags == that.flags && iconColor == that.iconColor && icon.sameAs(that.icon)
-                    && visibility == that.visibility;
+                    && visibility == that.visibility
+                    && groupAlertBehavior == that.groupAlertBehavior
+                    && channelId.equals(that.channelId);
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(flags, iconColor, icon, visibility);
+            return Objects.hash(flags, iconColor, icon, visibility, groupAlertBehavior, channelId);
+        }
+
+        @Override
+        public String toString() {
+            return "NotificationAttributes: flags: " + flags + " icon: " + icon + " color: "
+                    + iconColor + " vis: " + visibility + " groupAlertBehavior: "
+                    + groupAlertBehavior + " channelId: " + channelId;
         }
     }
 
     protected interface Callback {
-        void addAutoGroup(String key, boolean requestSort);
+        void addAutoGroup(String key, String groupName, boolean requestSort);
         void removeAutoGroup(String key);
 
-        void addAutoGroupSummary(int userId, String pkg, String triggeringKey,
+        void addAutoGroupSummary(int userId, String pkg, String triggeringKey, String groupName,
+                int summaryId, NotificationAttributes summaryAttr);
+        void removeAutoGroupSummary(int user, String pkg, String groupKey);
+
+        void updateAutogroupSummary(int userId, String pkg, String groupKey,
                 NotificationAttributes summaryAttr);
-        void removeAutoGroupSummary(int user, String pkg);
-        void updateAutogroupSummary(int userId, String pkg, NotificationAttributes summaryAttr);
+
+        // New callbacks for API abuse grouping
+        void removeAppProvidedSummary(String key);
+
+        void removeNotificationFromCanceledGroup(int userId, String pkg, String groupKey,
+                int cancelReason);
     }
 }
diff --git a/services/core/java/com/android/server/notification/NotificationAttentionHelper.java b/services/core/java/com/android/server/notification/NotificationAttentionHelper.java
index a7e14d9..5a9cf03 100644
--- a/services/core/java/com/android/server/notification/NotificationAttentionHelper.java
+++ b/services/core/java/com/android/server/notification/NotificationAttentionHelper.java
@@ -138,6 +138,7 @@
 
     private final boolean mUseAttentionLight;
     boolean mHasLight;
+    private final boolean mEnableNotificationAccessibilityEvents;
 
     private final SettingsObserver mSettingsObserver;
 
@@ -190,6 +191,9 @@
         mUseAttentionLight = resources.getBoolean(R.bool.config_useAttentionLight);
         mHasLight =
                 resources.getBoolean(com.android.internal.R.bool.config_intrusiveNotificationLed);
+        mEnableNotificationAccessibilityEvents =
+                resources.getBoolean(
+                        com.android.internal.R.bool.config_enableNotificationAccessibilityEvents);
 
         // Don't start allowing notifications until the setup wizard has run once.
         // After that, including subsequent boots, init with notifications turned on.
@@ -604,6 +608,13 @@
             }
         }
 
+        // Suppressed because notification was explicitly flagged as silent
+        if (android.service.notification.Flags.notificationSilentFlag()) {
+            if (notification.isSilent()) {
+                return true;
+            }
+        }
+
         // Suppressed for being too recently noisy
         final String pkg = record.getSbn().getPackageName();
         if (mUsageStats.isAlertRateLimited(pkg)) {
@@ -1023,7 +1034,7 @@
     }
 
     void sendAccessibilityEvent(NotificationRecord record) {
-        if (!mAccessibilityManager.isEnabled()) {
+        if (!mAccessibilityManager.isEnabled() || !mEnableNotificationAccessibilityEvents) {
             return;
         }
 
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index b436c8b..9e53cc3 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -39,6 +39,7 @@
 import static android.app.Notification.FLAG_BUBBLE;
 import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
 import static android.app.Notification.FLAG_FSI_REQUESTED_BUT_DENIED;
+import static android.app.Notification.FLAG_GROUP_SUMMARY;
 import static android.app.Notification.FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
 import static android.app.Notification.FLAG_NO_CLEAR;
 import static android.app.Notification.FLAG_NO_DISMISS;
@@ -46,6 +47,10 @@
 import static android.app.Notification.FLAG_ONLY_ALERT_ONCE;
 import static android.app.Notification.FLAG_USER_INITIATED_JOB;
 import static android.app.NotificationChannel.CONVERSATION_CHANNEL_ID_FORMAT;
+import static android.app.NotificationChannel.NEWS_ID;
+import static android.app.NotificationChannel.PROMOTIONS_ID;
+import static android.app.NotificationChannel.RECS_ID;
+import static android.app.NotificationChannel.SOCIAL_MEDIA_ID;
 import static android.app.NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED;
 import static android.app.NotificationManager.ACTION_AUTOMATIC_ZEN_RULE_STATUS_CHANGED;
 import static android.app.NotificationManager.ACTION_CONSOLIDATED_NOTIFICATION_POLICY_CHANGED;
@@ -98,7 +103,13 @@
 import static android.os.UserHandle.USER_ALL;
 import static android.os.UserHandle.USER_NULL;
 import static android.os.UserHandle.USER_SYSTEM;
+import static android.service.notification.Adjustment.KEY_TYPE;
+import static android.service.notification.Adjustment.TYPE_CONTENT_RECOMMENDATION;
+import static android.service.notification.Adjustment.TYPE_NEWS;
+import static android.service.notification.Adjustment.TYPE_PROMOTION;
+import static android.service.notification.Adjustment.TYPE_SOCIAL_MEDIA;
 import static android.service.notification.Flags.callstyleCallbackApi;
+import static android.service.notification.Flags.notificationForceGrouping;
 import static android.service.notification.Flags.redactSensitiveNotificationsFromUntrustedListeners;
 import static android.service.notification.Flags.redactSensitiveNotificationsBigTextStyle;
 import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
@@ -362,6 +373,7 @@
 import com.android.server.wm.BackgroundActivityStartCallback;
 import com.android.server.wm.WindowManagerInternal;
 
+import java.util.function.BiPredicate;
 import libcore.io.IoUtils;
 
 import org.json.JSONException;
@@ -458,7 +470,8 @@
             Adjustment.KEY_IMPORTANCE_PROPOSAL,
             Adjustment.KEY_SENSITIVE_CONTENT,
             Adjustment.KEY_RANKING_SCORE,
-            Adjustment.KEY_NOT_CONVERSATION
+            Adjustment.KEY_NOT_CONVERSATION,
+            Adjustment.KEY_TYPE
     };
 
     static final String[] NON_BLOCKABLE_DEFAULT_ROLES = new String[] {
@@ -502,6 +515,8 @@
 
     private static final long DELAY_FOR_ASSISTANT_TIME = 200;
 
+    private static final long DELAY_FORCE_REGROUP_TIME = 3000;
+
     private static final String ACTION_NOTIFICATION_TIMEOUT =
             NotificationManagerService.class.getSimpleName() + ".TIMEOUT";
     private static final int REQUEST_CODE_TIMEOUT = 1;
@@ -598,6 +613,9 @@
 
     static final long NOTIFICATION_MAX_AGE_AT_POST = Duration.ofDays(14).toMillis();
 
+    // Minium number of sparse groups for a package before autogrouping them
+    private static final int AUTOGROUP_SPARSE_GROUPS_AT_COUNT = 3;
+
     private IActivityManager mAm;
     private ActivityTaskManagerInternal mAtm;
     private ActivityManager mActivityManager;
@@ -991,17 +1009,25 @@
      * icons are different.
      * @param userId user id of the autogroup summary
      * @param pkg package of the autogroup summary
+     * @param groupKey group key of the autogroup summary
      * @param summaryAttr the new flags and/or icon & color for this summary
      * @param isAppForeground true if the app is currently in the foreground.
      */
     @GuardedBy("mNotificationLock")
-    protected void updateAutobundledSummaryLocked(int userId, String pkg,
-            NotificationAttributes summaryAttr, boolean isAppForeground) {
+    protected void updateAutobundledSummaryLocked(int userId, String pkg, String groupKey,
+                NotificationAttributes summaryAttr, boolean isAppForeground) {
         ArrayMap<String, String> summaries = mAutobundledSummaries.get(userId);
         if (summaries == null) {
             return;
         }
-        String summaryKey = summaries.get(pkg);
+        final String autbundledGroupKey;
+        if (notificationForceGrouping()) {
+            autbundledGroupKey = groupKey;
+        } else {
+            autbundledGroupKey = pkg;
+        }
+
+        String summaryKey = summaries.get(autbundledGroupKey);
         if (summaryKey == null) {
             return;
         }
@@ -1009,12 +1035,26 @@
         if (summary == null) {
             return;
         }
+
         int oldFlags = summary.getSbn().getNotification().flags;
 
         boolean attributesUpdated =
                 !summaryAttr.icon.sameAs(summary.getSbn().getNotification().getSmallIcon())
                 || summaryAttr.iconColor != summary.getSbn().getNotification().color
-                || summaryAttr.visibility != summary.getSbn().getNotification().visibility;
+                || summaryAttr.visibility != summary.getSbn().getNotification().visibility
+                || summaryAttr.groupAlertBehavior !=
+                        summary.getSbn().getNotification().getGroupAlertBehavior();
+
+        if (notificationForceGrouping()) {
+            if (!summary.getChannel().getId().equals(summaryAttr.channelId)) {
+                NotificationChannel newChannel = mPreferencesHelper.getNotificationChannel(pkg,
+                        summary.getUid(), summaryAttr.channelId, false);
+                if (newChannel != null) {
+                    summary.updateNotificationChannel(newChannel);
+                    attributesUpdated = true;
+                }
+            }
+        }
 
         if (oldFlags != summaryAttr.flags || attributesUpdated) {
             summary.getSbn().getNotification().flags =
@@ -1022,8 +1062,10 @@
             summary.getSbn().getNotification().setSmallIcon(summaryAttr.icon);
             summary.getSbn().getNotification().color = summaryAttr.iconColor;
             summary.getSbn().getNotification().visibility = summaryAttr.visibility;
+            summary.getSbn().getNotification()
+                    .setGroupAlertBehavior(summaryAttr.groupAlertBehavior);
             mHandler.post(new EnqueueNotificationRunnable(userId, summary, isAppForeground,
-                    mPostNotificationTrackerFactory.newTracker(null)));
+                    /* isAppProvided= */ false, mPostNotificationTrackerFactory.newTracker(null)));
         }
     }
 
@@ -1650,7 +1692,7 @@
                         // Force isAppForeground true here, because for sysui's purposes we
                         // want to adjust the flag behaviour.
                         mHandler.post(new EnqueueNotificationRunnable(r.getUser().getIdentifier(),
-                                r, true /* isAppForeground*/,
+                                r, /* isAppForeground= */ true , /* isAppProvided= */ false,
                                 mPostNotificationTrackerFactory.newTracker(null)));
                     }
                 }
@@ -1681,7 +1723,7 @@
                         // want to be able to adjust the flag behaviour.
                         mHandler.post(
                                 new EnqueueNotificationRunnable(r.getUser().getIdentifier(), r,
-                                        /* foreground= */ true,
+                                        /* foreground= */ true, /* isAppProvided= */ false,
                                         mPostNotificationTrackerFactory.newTracker(null)));
                     }
                 }
@@ -2706,7 +2748,7 @@
                 enqueueNotificationInternal(r.getSbn().getPackageName(), r.getSbn().getOpPkg(),
                         r.getSbn().getUid(), r.getSbn().getInitialPid(), r.getSbn().getTag(),
                         r.getSbn().getId(),  r.getSbn().getNotification(), userId, muteOnReturn,
-                        false /* byForegroundService */);
+                        /* byForegroundService= */ false, /* isAppProvided= */ false);
             } catch (Exception e) {
                 Slog.e(TAG, "Cannot un-snooze notification", e);
             }
@@ -2826,12 +2868,17 @@
         mAutoGroupAtCount =
                 getContext().getResources().getInteger(R.integer.config_autoGroupAtCount);
         return new GroupHelper(getContext(), getContext().getPackageManager(),
-                mAutoGroupAtCount, new GroupHelper.Callback() {
+                mAutoGroupAtCount, AUTOGROUP_SPARSE_GROUPS_AT_COUNT, new GroupHelper.Callback() {
             @Override
-            public void addAutoGroup(String key, boolean requestSort) {
-                        synchronized (mNotificationLock) {
-                            addAutogroupKeyLocked(key, requestSort);
-                        }
+            public void addAutoGroup(String key, String groupName, boolean requestSort) {
+                synchronized (mNotificationLock) {
+                    if (notificationForceGrouping()) {
+                        convertSummaryToNotificationLocked(key);
+                        addAutogroupKeyLocked(key, groupName, requestSort);
+                    } else {
+                        addAutogroupKeyLocked(key, groupName, requestSort);
+                    }
+                }
             }
 
             @Override
@@ -2843,32 +2890,69 @@
 
             @Override
             public void addAutoGroupSummary(int userId, String pkg, String triggeringKey,
-                    NotificationAttributes summaryAttr) {
+                    String groupName, int summaryId, NotificationAttributes summaryAttr) {
                 NotificationRecord r = createAutoGroupSummary(userId, pkg, triggeringKey,
-                        summaryAttr.flags, summaryAttr.icon, summaryAttr.iconColor,
-                        summaryAttr.visibility);
+                        groupName, summaryId, summaryAttr);
                 if (r != null) {
                     final boolean isAppForeground =
                             mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
                     mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground,
+                            /* isAppProvided= */ false,
                             mPostNotificationTrackerFactory.newTracker(null)));
                 }
             }
 
             @Override
-            public void removeAutoGroupSummary(int userId, String pkg) {
+            public void removeAutoGroupSummary(int userId, String pkg, String groupKey) {
                 synchronized (mNotificationLock) {
-                    clearAutogroupSummaryLocked(userId, pkg);
+                    clearAutogroupSummaryLocked(userId, pkg, groupKey);
                 }
             }
 
             @Override
-            public void updateAutogroupSummary(int userId, String pkg,
+            public void updateAutogroupSummary(int userId, String pkg, String groupKey,
                     NotificationAttributes summaryAttr) {
                 boolean isAppForeground = pkg != null
                         && mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
                 synchronized (mNotificationLock) {
-                    updateAutobundledSummaryLocked(userId, pkg, summaryAttr, isAppForeground);
+                    updateAutobundledSummaryLocked(userId, pkg, groupKey, summaryAttr,
+                            isAppForeground);
+                }
+            }
+
+            @Override
+            public void removeAppProvidedSummary(String key) {
+                synchronized (mNotificationLock) {
+                    removeAppSummaryLocked(key);
+                }
+            }
+
+            @Override
+            public void removeNotificationFromCanceledGroup(int userId, String pkg,
+                    String groupKey, int cancelReason) {
+                synchronized (mNotificationLock) {
+                    final int mustNotHaveFlags;
+                    if (lifetimeExtensionRefactor()) {
+                        // Also don't allow client apps to cancel lifetime extended notifs.
+                        mustNotHaveFlags = (FLAG_FOREGROUND_SERVICE | FLAG_USER_INITIATED_JOB
+                                | FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY);
+                    } else {
+                        mustNotHaveFlags = (FLAG_FOREGROUND_SERVICE | FLAG_USER_INITIATED_JOB);
+                    }
+                    FlagChecker childrenFlagChecker = (flags) -> {
+                            if (cancelReason == REASON_CANCEL
+                                || cancelReason == REASON_CLICK
+                                || cancelReason == REASON_CANCEL_ALL) {
+                                if ((flags & FLAG_BUBBLE) != 0) {
+                                    return false;
+                                }
+                            }
+                            return (flags & mustNotHaveFlags) == 0;
+                    };
+                    cancelGroupChildrenLocked(userId, pkg, Binder.getCallingUid(),
+                            Binder.getCallingPid(), null,
+                            false, childrenFlagChecker, groupKey,
+                            REASON_APP_CANCEL, SystemClock.elapsedRealtime());
                 }
             }
         });
@@ -3096,6 +3180,18 @@
                     modifiedChannel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);
         }
 
+        if (notificationForceGrouping()) {
+            final NotificationChannel updatedChannel = mPreferencesHelper.getNotificationChannel(
+                    pkg, uid, channel.getId(), false);
+            mHandler.postDelayed(() -> {
+                synchronized (mNotificationLock) {
+                    mGroupHelper.onChannelUpdated(
+                            UserHandle.getUserHandleForUid(uid).getIdentifier(), pkg,
+                            updatedChannel, mNotificationList);
+                }
+            }, DELAY_FORCE_REGROUP_TIME);
+        }
+
         handleSavePolicyFile();
     }
 
@@ -3763,7 +3859,7 @@
                 Notification notification, int userId) throws RemoteException {
             enqueueNotificationInternal(pkg, opPkg, Binder.getCallingUid(),
                     Binder.getCallingPid(), tag, id, notification, userId,
-                    false /* byForegroundService */);
+                    /* byForegroundService= */ false, /* isAppProvided= */ true);
         }
 
         @Override
@@ -6608,6 +6704,30 @@
             for (String removeKey : toRemove) {
                 adjustments.remove(removeKey);
             }
+            if (android.service.notification.Flags.notificationClassification()
+                    && adjustments.containsKey(KEY_TYPE)) {
+                NotificationChannel newChannel = null;
+                int type = adjustments.getInt(KEY_TYPE);
+                if (TYPE_NEWS == type) {
+                    newChannel = mPreferencesHelper.getNotificationChannel(
+                            r.getSbn().getPackageName(), r.getUid(), NEWS_ID, false);
+                } else if (TYPE_PROMOTION == type) {
+                    newChannel = mPreferencesHelper.getNotificationChannel(
+                            r.getSbn().getPackageName(), r.getUid(), PROMOTIONS_ID, false);
+                } else if (TYPE_SOCIAL_MEDIA == type) {
+                    newChannel = mPreferencesHelper.getNotificationChannel(
+                            r.getSbn().getPackageName(), r.getUid(), SOCIAL_MEDIA_ID, false);
+                } else if (TYPE_CONTENT_RECOMMENDATION == type) {
+                    newChannel = mPreferencesHelper.getNotificationChannel(
+                            r.getSbn().getPackageName(), r.getUid(), RECS_ID, false);
+                }
+                if (newChannel == null) {
+                    adjustments.remove(KEY_TYPE);
+                } else {
+                    // swap app provided type with the real thing
+                    adjustments.putParcelable(KEY_TYPE, newChannel);
+                }
+            }
             r.addAdjustment(adjustment);
             if (adjustment.getSignals().containsKey(Adjustment.KEY_SENSITIVE_CONTENT)) {
                 logSensitiveAdjustmentReceived(isPosted,
@@ -6617,18 +6737,33 @@
         }
     }
 
+    @SuppressWarnings("GuardedBy")
     @GuardedBy("mNotificationLock")
-    void addAutogroupKeyLocked(String key, boolean requestSort) {
+    void addAutogroupKeyLocked(String key, String groupName, boolean requestSort) {
         NotificationRecord r = mNotificationsByKey.get(key);
         if (r == null) {
             return;
         }
         if (r.getSbn().getOverrideGroupKey() == null) {
-            addAutoGroupAdjustment(r, GroupHelper.AUTOGROUP_KEY);
+            if (notificationForceGrouping()) {
+                if (r.getSbn().isAppGroup()) {
+                    // Override group key early for forced grouped notifications
+                    r.setOverrideGroupKey(groupName);
+                }
+            }
+
+            addAutoGroupAdjustment(r, groupName);
             EventLogTags.writeNotificationAutogrouped(key);
+
             if (!android.app.Flags.checkAutogroupBeforePost() || requestSort) {
                 mRankingHandler.requestSort();
             }
+
+            if (notificationForceGrouping()) {
+                if (r.getSbn().isAppGroup()) {
+                    mListeners.notifyPostedLocked(r, r);
+                }
+            }
         }
     }
 
@@ -6657,27 +6792,57 @@
     // Clears the 'fake' auto-group summary.
     @VisibleForTesting
     @GuardedBy("mNotificationLock")
-    void clearAutogroupSummaryLocked(int userId, String pkg) {
+    void clearAutogroupSummaryLocked(int userId, String pkg, String groupKey) {
+        final String autbundledGroupKey;
+        if (notificationForceGrouping()) {
+            autbundledGroupKey = groupKey;
+        } else {
+            autbundledGroupKey = pkg;
+        }
         ArrayMap<String, String> summaries = mAutobundledSummaries.get(userId);
-        if (summaries != null && summaries.containsKey(pkg)) {
-            final NotificationRecord removed = findNotificationByKeyLocked(summaries.remove(pkg));
+        if (summaries != null && summaries.containsKey(autbundledGroupKey)) {
+            final NotificationRecord removed = findNotificationByKeyLocked(
+                    summaries.remove(autbundledGroupKey));
             if (removed != null) {
                 final StatusBarNotification sbn = removed.getSbn();
                 cancelNotification(MY_UID, MY_PID, pkg, sbn.getTag(), sbn.getId(), 0, 0, false,
-                        userId, REASON_UNAUTOBUNDLED, null);
+                    userId, REASON_UNAUTOBUNDLED, null);
             }
         }
     }
 
     @GuardedBy("mNotificationLock")
-    private boolean hasAutoGroupSummaryLocked(StatusBarNotification sbn) {
-        ArrayMap<String, String> summaries = mAutobundledSummaries.get(sbn.getUserId());
-        return summaries != null && summaries.containsKey(sbn.getPackageName());
+    void removeAppSummaryLocked(String key) {
+        NotificationRecord r = mNotificationsByKey.get(key);
+        if (r == null) {
+            return;
+        }
+        if (convertSummaryToNotificationLocked(key)) {
+            r.isCanceled = true;
+            cancelNotification(Binder.getCallingUid(),
+                    Binder.getCallingPid(), r.getSbn().getPackageName(),
+                    r.getSbn().getTag(), r.getSbn().getId(), 0, 0,
+                    false, r.getUserId(),
+                    NotificationListenerService.REASON_GROUP_OPTIMIZATION, null);
+        }
+    }
+
+    @GuardedBy("mNotificationLock")
+    private boolean hasAutoGroupSummaryLocked(NotificationRecord record) {
+        final String autbundledGroupKey;
+        if (notificationForceGrouping()) {
+            autbundledGroupKey = GroupHelper.getFullAggregateGroupKey(record);
+        } else {
+            autbundledGroupKey = record.getSbn().getPackageName();
+        }
+
+        ArrayMap<String, String> summaries = mAutobundledSummaries.get(record.getUserId());
+        return summaries != null && summaries.containsKey(autbundledGroupKey);
     }
 
     // Creates a 'fake' summary for a package that has exceeded the solo-notification limit.
     NotificationRecord createAutoGroupSummary(int userId, String pkg, String triggeringKey,
-            int flagsToSet, Icon summaryIcon, int summaryIconColor, int summaryVisibilty) {
+            String groupKey, int summaryId, NotificationAttributes summaryAttr) {
         NotificationRecord summaryRecord = null;
         boolean isPermissionFixed = mPermissionHelper.isPermissionFixed(pkg, userId);
         synchronized (mNotificationLock) {
@@ -6695,24 +6860,35 @@
                 summaries = new ArrayMap<>();
             }
             mAutobundledSummaries.put(userId, summaries);
-            if (!summaries.containsKey(pkg)) {
+
+            boolean hasSummary;
+            String channelId;
+            if (notificationForceGrouping()) {
+                hasSummary = summaries.containsKey(groupKey);
+                channelId = summaryAttr.channelId;
+            } else {
+                hasSummary = summaries.containsKey(pkg);
+                channelId = notificationRecord.getChannel().getId();
+            }
+
+            if (!hasSummary) {
                 // Add summary
                 final ApplicationInfo appInfo =
                         adjustedSbn.getNotification().extras.getParcelable(
                                 EXTRA_BUILDER_APPLICATION_INFO, ApplicationInfo.class);
                 final Bundle extras = new Bundle();
                 extras.putParcelable(EXTRA_BUILDER_APPLICATION_INFO, appInfo);
-                final String channelId = notificationRecord.getChannel().getId();
+
 
                 final Notification summaryNotification =
                                 new Notification.Builder(getContext(), channelId)
-                                .setSmallIcon(summaryIcon)
+                                .setSmallIcon(summaryAttr.icon)
                                 .setGroupSummary(true)
-                                .setGroupAlertBehavior(Notification.GROUP_ALERT_CHILDREN)
-                                .setGroup(GroupHelper.AUTOGROUP_KEY)
-                                .setFlag(flagsToSet, true)
-                                .setColor(summaryIconColor)
-                                .setVisibility(summaryVisibilty)
+                                .setGroupAlertBehavior(summaryAttr.groupAlertBehavior)
+                                .setGroup(groupKey)
+                                .setFlag(summaryAttr.flags, true)
+                                .setColor(summaryAttr.iconColor)
+                                .setVisibility(summaryAttr.visibility)
                                 .build();
                 summaryNotification.extras.putAll(extras);
                 Intent appIntent = getContext().getPackageManager().getLaunchIntentForPackage(pkg);
@@ -6724,17 +6900,22 @@
                 final StatusBarNotification summarySbn =
                         new StatusBarNotification(adjustedSbn.getPackageName(),
                                 adjustedSbn.getOpPkg(),
-                                Integer.MAX_VALUE,
-                                GroupHelper.AUTOGROUP_KEY, adjustedSbn.getUid(),
+                                summaryId,
+                                groupKey, adjustedSbn.getUid(),
                                 adjustedSbn.getInitialPid(), summaryNotification,
-                                adjustedSbn.getUser(), GroupHelper.AUTOGROUP_KEY,
+                                adjustedSbn.getUser(), groupKey,
                                 System.currentTimeMillis());
                 summaryRecord = new NotificationRecord(getContext(), summarySbn,
                         notificationRecord.getChannel());
                 summaryRecord.setImportanceFixed(isPermissionFixed);
                 summaryRecord.setIsAppImportanceLocked(
                         notificationRecord.getIsAppImportanceLocked());
-                summaries.put(pkg, summarySbn.getKey());
+
+                if (notificationForceGrouping()) {
+                    summaries.put(summarySbn.getGroupKey(), summarySbn.getKey());
+                } else {
+                    summaries.put(pkg, summarySbn.getKey());
+                }
             }
             if (summaryRecord != null && checkDisqualifyingFeatures(userId, uid,
                     summaryRecord.getSbn().getId(), summaryRecord.getSbn().getTag(), summaryRecord,
@@ -6745,6 +6926,27 @@
         return null;
     }
 
+    @GuardedBy("mNotificationLock")
+    boolean convertSummaryToNotificationLocked(final String key) {
+        NotificationRecord r = mNotificationsByKey.get(key);
+        if (r == null) {
+            return false;
+        }
+        // Convert summary to regular notification
+        if (r.getSbn().isAppGroup() && r.getNotification().isGroupSummary()) {
+            String oldGroupKey = r.getGroupKey();
+            NotificationRecord groupSummary = mSummaryByGroupKey.get(oldGroupKey);
+            if (groupSummary != null && groupSummary.getKey().equals(r.getKey())) {
+                mSummaryByGroupKey.remove(oldGroupKey);
+            }
+            // Clear summary flag
+            StatusBarNotification sbn = r.getSbn();
+            sbn.getNotification().flags = (r.mOriginalFlags & ~FLAG_GROUP_SUMMARY);
+            return true;
+        }
+        return false;
+    }
+
     // Gets packages that have requested notification permission, and whether that has been
     // allowed/denied, for all users on the device.
     // Returns a single map containing that info keyed by (uid, package name) for all users.
@@ -7025,7 +7227,7 @@
         public void enqueueNotification(String pkg, String opPkg, int callingUid, int callingPid,
                 String tag, int id, Notification notification, int userId) {
             enqueueNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id, notification,
-                    userId, false /* byForegroundService */);
+                    userId, /* byForegroundService= */ false , /* isAppProvided= */ true);
         }
 
         @Override
@@ -7033,7 +7235,7 @@
                 String tag, int id, Notification notification, int userId,
                 boolean byForegroundService) {
             enqueueNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id, notification,
-                    userId, byForegroundService);
+                    userId, byForegroundService, /* isAppProvided= */ true);
         }
 
         @Override
@@ -7245,7 +7447,8 @@
                 r.getSbn().getInitialPid(), r.getSbn().getTag(),
                 r.getSbn().getId(), r.getNotification(),
                 r.getSbn().getUserId(), /* postSilently= */ true,
-                /* byForegroundService= */ false);
+                /* byForegroundService= */ false,
+                /* isAppProvided= */ false);
     }
 
     int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted) {
@@ -7306,19 +7509,21 @@
 
     void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
             final int callingPid, final String tag, final int id, final Notification notification,
-            int incomingUserId, boolean byForegroundService) {
+            int incomingUserId, boolean byForegroundService, boolean isAppProvided) {
         enqueueNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id, notification,
-                incomingUserId, false /* postSilently */, byForegroundService);
+                incomingUserId, false /* postSilently */, byForegroundService, isAppProvided);
     }
 
     void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
             final int callingPid, final String tag, final int id, final Notification notification,
-            int incomingUserId, boolean postSilently, boolean byForegroundService) {
+            int incomingUserId, boolean postSilently, boolean byForegroundService,
+            boolean isAppProvided) {
         PostNotificationTracker tracker = acquireWakeLockForPost(pkg, callingUid);
         boolean enqueued = false;
         try {
             enqueued = enqueueNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id,
-                    notification, incomingUserId, postSilently, tracker, byForegroundService);
+                    notification, incomingUserId, postSilently, tracker, byForegroundService,
+                    isAppProvided);
         } finally {
             if (!enqueued) {
                 tracker.cancel();
@@ -7344,7 +7549,7 @@
     private boolean enqueueNotificationInternal(final String pkg, final String opPkg,  //HUI
             final int callingUid, final int callingPid, final String tag, final int id,
             final Notification notification, int incomingUserId, boolean postSilently,
-            PostNotificationTracker tracker, boolean byForegroundService) {
+            PostNotificationTracker tracker, boolean byForegroundService, boolean isAppProvided) {
         if (DBG) {
             Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id
                     + " notification=" + notification);
@@ -7545,7 +7750,8 @@
         // Need escalated privileges to get package importance.
         final int packageImportance = getPackageImportanceWithIdentity(pkg);
         boolean isAppForeground = packageImportance == IMPORTANCE_FOREGROUND;
-        mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground, tracker));
+        mHandler.post(new EnqueueNotificationRunnable(userId, r, isAppForeground,
+                /* isAppProvided= */ isAppProvided, tracker));
         return true;
     }
 
@@ -7755,6 +7961,10 @@
                 notification.setTimeoutAfter(NOTIFICATION_TTL);
             }
         }
+
+        if (notificationForceGrouping()) {
+            notification.fixSilentGroup();
+        }
     }
 
     /**
@@ -7925,6 +8135,7 @@
                             mHandler.post(
                                     new EnqueueNotificationRunnable(
                                             r.getUser().getIdentifier(), r, isAppForeground,
+                                            /* isAppProvided= */ false,
                                             mPostNotificationTrackerFactory.newTracker(null)));
                         }
                     }
@@ -8307,8 +8518,15 @@
          * They will be recreated as needed when the group children are unsnoozed
          */
         private boolean isSnoozable(NotificationRecord record) {
-            return !(record.getNotification().isGroupSummary() && GroupHelper.AUTOGROUP_KEY.equals(
-                    record.getNotification().getGroup()));
+            if (notificationForceGrouping()) {
+                boolean isExemptedSummary =
+                        ((record.getFlags() & FLAG_AUTOGROUP_SUMMARY) != 0
+                        || GroupHelper.isAggregatedGroup(record));
+                return !(record.getNotification().isGroupSummary() && isExemptedSummary);
+            } else {
+                return !(record.getNotification().isGroupSummary()
+                        && GroupHelper.AUTOGROUP_KEY.equals(record.getNotification().getGroup()));
+            }
         }
     }
 
@@ -8431,16 +8649,26 @@
                     cancelNotificationLocked(
                             r, mSendDelete, mReason, mRank, mCount, wasPosted, listenerName,
                             mCancellationElapsedTimeMs);
-                    cancelGroupChildrenLocked(r, mCallingUid, mCallingPid, listenerName,
-                            mSendDelete, childrenFlagChecker, mReason,
-                            mCancellationElapsedTimeMs);
+                    if (r.getNotification().isGroupSummary()) {
+                        cancelGroupChildrenLocked(mUserId, mPkg, mCallingUid, mCallingPid,
+                                listenerName, mSendDelete, childrenFlagChecker,
+                                r.getNotification().getGroup(), mReason,
+                                mCancellationElapsedTimeMs);
+                    }
                     mAttentionHelper.updateLightsLocked();
                     if (mShortcutHelper != null) {
                         mShortcutHelper.maybeListenForShortcutChangesForBubbles(r,
-                                true /* isRemoved */,
-                                mHandler);
+                                true /* isRemoved */);
                     }
                 } else {
+                    if (notificationForceGrouping()) {
+                        // No notification was found => maybe it was canceled by forced grouping
+                        if (Flags.notificationForceGroupSingletons()) {
+                            mGroupHelper.maybeCancelGroupChildrenForCanceledSummary(mPkg, mTag,
+                                mId, mUserId, mReason);
+                        }
+                    }
+
                     // No notification was found, assume that it is snoozed and cancel it.
                     if (mReason != REASON_SNOOZED) {
                         final boolean wasSnoozed = mSnoozeHelper.cancel(mUserId, mPkg, mTag, mId);
@@ -8495,13 +8723,15 @@
         private final NotificationRecord r;
         private final int userId;
         private final boolean isAppForeground;
+        private final boolean isAppProvided;
         private final PostNotificationTracker mTracker;
 
         EnqueueNotificationRunnable(int userId, NotificationRecord r, boolean foreground,
-                PostNotificationTracker tracker) {
+                boolean isAppProvided, PostNotificationTracker tracker) {
             this.userId = userId;
             this.r = r;
             this.isAppForeground = foreground;
+            this.isAppProvided = isAppProvided;
             this.mTracker = checkNotNull(tracker);
         }
 
@@ -8523,6 +8753,13 @@
          */
         private boolean enqueueNotification() {
             synchronized (mNotificationLock) {
+                if (android.app.Flags.secureAllowlistToken()) {
+                    // allowlistToken is populated by unparceling, so it will be absent if the
+                    // EnqueueNotificationRunnable is created directly by NMS (as we do for group
+                    // summaries) instead of via notify(). Fix that.
+                    r.getNotification().overrideAllowlistToken(ALLOWLIST_TOKEN);
+                }
+
                 final long snoozeAt =
                         mSnoozeHelper.getSnoozeTimeForUnpostedNotification(
                                 r.getUser().getIdentifier(),
@@ -8586,9 +8823,10 @@
                     if (old != null) {
                         enqueueStatus = EVENTLOG_ENQUEUE_STATUS_UPDATE;
                     }
+                    int appProvided = isAppProvided ? 1 : 0;
                     EventLogTags.writeNotificationEnqueue(callingUid, callingPid,
                             pkg, id, tag, userId, notification.toString(),
-                            enqueueStatus);
+                            enqueueStatus, appProvided);
                 }
 
                 // tell the assistant service about the notification
@@ -8658,7 +8896,7 @@
             boolean appBanned = !areNotificationsEnabledForPackageInt(pkg, uid);
             boolean isCallNotification = isCallNotification(pkg, uid);
             boolean posted = false;
-            synchronized (mNotificationLock) {
+            synchronized (NotificationManagerService.this.mNotificationLock) {
                 try {
                     NotificationRecord r = findNotificationByListLocked(mEnqueuedNotifications,
                             key);
@@ -8681,6 +8919,29 @@
                         return false;
                     }
 
+                    if (notificationForceGrouping()) {
+                        if (Flags.notificationForceGroupSingletons()) {
+                            // Check if this is an updated for a summary for an aggregated sparse
+                            // group and remove it because that summary has been canceled
+                            if (mGroupHelper.isUpdateForCanceledSummary(r)) {
+                                if (DBG) {
+                                    Log.w(TAG,
+                                        "Suppressing notification because summary was canceled: "
+                                            + r);
+                                }
+
+                                String groupKey = r.getGroupKey();
+                                NotificationRecord groupSummary = mSummaryByGroupKey.get(groupKey);
+                                if (groupSummary != null && groupSummary.getKey()
+                                        .equals(r.getKey())) {
+                                    mSummaryByGroupKey.remove(groupKey);
+                                }
+                                return false;
+                            }
+                        }
+                    }
+
+
                     final boolean isPackageSuspended =
                             isPackagePausedOrSuspended(r.getSbn().getPackageName(), r.getUid());
                     r.setHidden(isPackageSuspended);
@@ -8738,18 +8999,38 @@
                         if (notification.getSmallIcon() != null && !isCritical(r)) {
                             StatusBarNotification oldSbn = (old != null) ? old.getSbn() : null;
                             if (oldSbn == null || !Objects.equals(oldSbn.getGroup(), n.getGroup())
+                                    || !Objects.equals(oldSbn.getNotification().getGroup(),
+                                        n.getNotification().getGroup())
                                     || oldSbn.getNotification().flags
                                     != n.getNotification().flags) {
                                 synchronized (mNotificationLock) {
-                                    boolean willBeAutogrouped = mGroupHelper.onNotificationPosted(n,
-                                            hasAutoGroupSummaryLocked(n));
+                                    final String autogroupName =
+                                            notificationForceGrouping() ?
+                                                GroupHelper.getFullAggregateGroupKey(r)
+                                                : GroupHelper.AUTOGROUP_KEY;
+                                    boolean willBeAutogrouped =
+                                            mGroupHelper.onNotificationPosted(r,
+                                                hasAutoGroupSummaryLocked(r));
                                     if (willBeAutogrouped) {
                                         // The newly posted notification will be autogrouped, but
                                         // was not autogrouped onPost, to avoid an unnecessary sort.
                                         // We add the autogroup key to the notification without a
                                         // sort here, and it'll be sorted below with extractSignals.
-                                        addAutogroupKeyLocked(key, /*requestSort=*/false);
+                                        addAutogroupKeyLocked(key,
+                                                autogroupName, /*requestSort=*/false);
+                                    } else {
+                                        if (notificationForceGrouping()) {
+                                            // Wait 3 seconds so that the app has a chance to post
+                                            // a group summary or children (complete a group)
+                                            mHandler.postDelayed(() -> {
+                                                synchronized (mNotificationLock) {
+                                                    mGroupHelper.onNotificationPostedWithDelay(
+                                                        r, mNotificationList, mSummaryByGroupKey);
+                                                }
+                                            }, r.getKey(), DELAY_FORCE_REGROUP_TIME);
+                                        }
                                     }
+
                                 }
                             }
                         }
@@ -8785,9 +9066,18 @@
                                     mHandler.post(() -> {
                                         synchronized (mNotificationLock) {
                                             mGroupHelper.onNotificationPosted(
-                                                    n, hasAutoGroupSummaryLocked(n));
+                                                    r, hasAutoGroupSummaryLocked(r));
                                         }
                                     });
+
+                                    if (notificationForceGrouping()) {
+                                        mHandler.postDelayed(() -> {
+                                            synchronized (mNotificationLock) {
+                                                mGroupHelper.onNotificationPostedWithDelay(r,
+                                                        mNotificationList, mSummaryByGroupKey);
+                                            }
+                                        }, r.getKey(), DELAY_FORCE_REGROUP_TIME);
+                                    }
                                 }
                             }
                         }
@@ -8796,12 +9086,20 @@
                         if (old != null && !old.isCanceled) {
                             mListeners.notifyRemovedLocked(r,
                                     REASON_ERROR, r.getStats());
-                            mHandler.post(new Runnable() {
-                                @Override
-                                public void run() {
-                                    mGroupHelper.onNotificationRemoved(n);
-                                }
-                            });
+                            if (notificationForceGrouping()) {
+                                mHandler.post(() -> {
+                                    synchronized (mNotificationLock) {
+                                        mGroupHelper.onNotificationRemoved(r, mNotificationList);
+                                    }
+                                });
+                            } else {
+                                mHandler.post(new Runnable() {
+                                    @Override
+                                    public void run() {
+                                        mGroupHelper.onNotificationRemoved(r);
+                                    }
+                                });
+                            }
                         }
 
                         if (callstyleCallbackApi()) {
@@ -8817,8 +9115,7 @@
 
                     if (mShortcutHelper != null) {
                         mShortcutHelper.maybeListenForShortcutChangesForBubbles(r,
-                                false /* isRemoved */,
-                                mHandler);
+                                false /* isRemoved */);
                     }
 
                     maybeRecordInterruptionLocked(r);
@@ -9032,6 +9329,18 @@
             n.flags &= ~Notification.FLAG_GROUP_SUMMARY;
         }
 
+        if (notificationForceGrouping()) {
+            if (old != null) {
+                // If this is an update to a summary that was forced grouped => remove summary flag
+                boolean wasSummary = (old.mOriginalFlags & FLAG_GROUP_SUMMARY) != 0;
+                boolean wasForcedGrouped = (old.getFlags() & FLAG_GROUP_SUMMARY) == 0
+                        && old.getSbn().getOverrideGroupKey() != null;
+                if (n.isGroupSummary() && wasSummary && wasForcedGrouped) {
+                    n.flags &= ~FLAG_GROUP_SUMMARY;
+                }
+            }
+        }
+
         String group = sbn.getGroupKey();
         boolean isSummary = n.isGroupSummary();
 
@@ -9064,8 +9373,10 @@
         // notification was a summary and the new one isn't, or when the old
         // notification was a summary and its group key changed.
         if (oldIsSummary && (!isSummary || !oldGroup.equals(group))) {
-            cancelGroupChildrenLocked(old, callingUid, callingPid, null, false /* sendDelete */,
-                    childrenFlagChecker, REASON_APP_CANCEL, SystemClock.elapsedRealtime());
+            cancelGroupChildrenLocked(old.getUserId(), old.getSbn().getPackageName(), callingUid,
+                    callingPid, null, false /* sendDelete */, childrenFlagChecker,
+                    old.getNotification().getGroup(), REASON_APP_CANCEL,
+                    SystemClock.elapsedRealtime());
         }
     }
 
@@ -9727,12 +10038,21 @@
                     r.isCanceled = true;
                 }
                 mListeners.notifyRemovedLocked(r, reason, r.getStats());
-                mHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        mGroupHelper.onNotificationRemoved(r.getSbn());
-                    }
-                });
+                if (notificationForceGrouping()) {
+                    mHandler.removeCallbacksAndMessages(r.getKey());
+                    mHandler.post(() -> {
+                        synchronized (NotificationManagerService.this.mNotificationLock) {
+                            mGroupHelper.onNotificationRemoved(r, mNotificationList);
+                        }
+                    });
+                } else {
+                    mHandler.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            mGroupHelper.onNotificationRemoved(r);
+                        }
+                    });
+                }
                 if (callstyleCallbackApi()) {
                     notifyCallNotificationEventListenerOnRemoved(r);
                 }
@@ -9765,9 +10085,15 @@
         }
         final ArrayMap<String, String> summaries =
                 mAutobundledSummaries.get(r.getSbn().getUserId());
+        final String autbundledGroupKey;
+        if (notificationForceGrouping()) {
+            autbundledGroupKey = groupKey;
+        } else {
+            autbundledGroupKey = r.getSbn().getPackageName();
+        }
         if (summaries != null && r.getSbn().getKey().equals(
-                summaries.get(r.getSbn().getPackageName()))) {
-            summaries.remove(r.getSbn().getPackageName());
+                summaries.get(autbundledGroupKey))) {
+            summaries.remove(autbundledGroupKey);
         }
 
         // Save it for users of getHistoricalNotifications(), unless the whole channel was deleted
@@ -10031,6 +10357,15 @@
         public boolean apply(int flags);
     }
 
+    private static boolean isChildOfGroup(final NotificationRecord childRecord, int userId,
+            String pkg, String groupKey) {
+        return (childRecord.getUser().getIdentifier() == userId
+            && childRecord.getSbn().getPackageName().equals(pkg)
+            && childRecord.getSbn().isGroup()
+            && !childRecord.getNotification().isGroupSummary()
+            && TextUtils.equals(groupKey, childRecord.getNotification().getGroup()));
+    }
+
     @GuardedBy("mNotificationLock")
     private void cancelAllNotificationsByListLocked(ArrayList<NotificationRecord> notificationList,
             @Nullable String pkg, boolean nullPkgIndicatesUserSwitch, @Nullable String channelId,
@@ -10188,43 +10523,34 @@
 
     // Warning: The caller is responsible for invoking updateLightsLocked().
     @GuardedBy("mNotificationLock")
-    private void cancelGroupChildrenLocked(NotificationRecord r, int callingUid, int callingPid,
-            String listenerName, boolean sendDelete, FlagChecker flagChecker, int reason,
-            @ElapsedRealtimeLong long cancellationElapsedTimeMs) {
-        Notification n = r.getNotification();
-        if (!n.isGroupSummary()) {
-            return;
-        }
-
-        String pkg = r.getSbn().getPackageName();
-
+    private void cancelGroupChildrenLocked(int userId, String pkg, int callingUid, int callingPid,
+            String listenerName, boolean sendDelete, FlagChecker flagChecker, String groupKey,
+            int reason, @ElapsedRealtimeLong long cancellationElapsedTimeMs) {
         if (pkg == null) {
-            if (DBG) Slog.e(TAG, "No package for group summary: " + r.getKey());
+            if (DBG) Slog.e(TAG, "No package for group summary");
             return;
         }
 
-        cancelGroupChildrenByListLocked(mNotificationList, r, callingUid, callingPid, listenerName,
-                sendDelete, true, flagChecker, reason, cancellationElapsedTimeMs);
-        cancelGroupChildrenByListLocked(mEnqueuedNotifications, r, callingUid, callingPid,
-                listenerName, sendDelete, false, flagChecker, reason, cancellationElapsedTimeMs);
+        cancelGroupChildrenByListLocked(mNotificationList, userId, pkg, callingUid, callingPid,
+                listenerName, sendDelete, true, flagChecker, groupKey,
+                reason, cancellationElapsedTimeMs);
+        cancelGroupChildrenByListLocked(mEnqueuedNotifications, userId, pkg, callingUid, callingPid,
+                listenerName, sendDelete, false, flagChecker, groupKey,
+                reason, cancellationElapsedTimeMs);
     }
 
     @GuardedBy("mNotificationLock")
     private void cancelGroupChildrenByListLocked(ArrayList<NotificationRecord> notificationList,
-            NotificationRecord parentNotification, int callingUid, int callingPid,
+            int userId, String pkg, int callingUid, int callingPid,
             String listenerName, boolean sendDelete, boolean wasPosted, FlagChecker flagChecker,
-            int reason, @ElapsedRealtimeLong long cancellationElapsedTimeMs) {
-        final String pkg = parentNotification.getSbn().getPackageName();
-        final int userId = parentNotification.getUserId();
+            String groupKey, int reason, @ElapsedRealtimeLong long cancellationElapsedTimeMs) {
         final int childReason = REASON_GROUP_SUMMARY_CANCELED;
         for (int i = notificationList.size() - 1; i >= 0; i--) {
             final NotificationRecord childR = notificationList.get(i);
             final StatusBarNotification childSbn = childR.getSbn();
-            if ((childSbn.isGroup() && !childSbn.getNotification().isGroupSummary()) &&
-                    childR.getGroupKey().equals(parentNotification.getGroupKey())
-                    && (flagChecker == null || flagChecker.apply(childR.getFlags()))
-                    && (!childR.getChannel().isImportantConversation()
-                            || reason != REASON_CANCEL)) {
+            if (isChildOfGroup(childR, userId, pkg, groupKey)
+                && (flagChecker == null || flagChecker.apply(childR.getFlags()))
+                && (!childR.getChannel().isImportantConversation() || reason != REASON_CANCEL)) {
                 EventLogTags.writeNotificationCancel(callingUid, callingPid, pkg, childSbn.getId(),
                         childSbn.getTag(), userId, 0, 0, childReason, listenerName);
                 notificationList.remove(i);
@@ -10304,6 +10630,7 @@
                 != null) {
             return r;
         }
+
         return null;
     }
 
@@ -11373,7 +11700,7 @@
             record.getNotification().flags |= FLAG_ONLY_ALERT_ONCE;
 
             mHandler.post(new EnqueueNotificationRunnable(record.getUser().getIdentifier(),
-                    record, isAppForeground,
+                    record, isAppForeground, /* isAppProvided= */ false,
                     mPostNotificationTrackerFactory.newTracker(null)));
         }
     }
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 0c6a6c8..bd00901 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -449,9 +449,16 @@
         mRankingTimeMs = calculateRankingTimeMs(previous.getRankingTimeMs());
         mCreationTimeMs = previous.mCreationTimeMs;
         mVisibleSinceMs = previous.mVisibleSinceMs;
-        if (previous.getSbn().getOverrideGroupKey() != null && !getSbn().isAppGroup()) {
-            getSbn().setOverrideGroupKey(previous.getSbn().getOverrideGroupKey());
+        if (android.service.notification.Flags.notificationForceGrouping()) {
+            if (previous.getSbn().getOverrideGroupKey() != null) {
+                getSbn().setOverrideGroupKey(previous.getSbn().getOverrideGroupKey());
+            }
+        } else {
+            if (previous.getSbn().getOverrideGroupKey() != null && !getSbn().isAppGroup()) {
+                getSbn().setOverrideGroupKey(previous.getSbn().getOverrideGroupKey());
+            }
         }
+
         // Don't copy importance information or mGlobalSortKey, recompute them.
     }
 
@@ -710,7 +717,8 @@
                 if (signals.containsKey(Adjustment.KEY_SNOOZE_CRITERIA)) {
                     final ArrayList<SnoozeCriterion> snoozeCriterionList =
                             adjustment.getSignals().getParcelableArrayList(
-                                    Adjustment.KEY_SNOOZE_CRITERIA, android.service.notification.SnoozeCriterion.class);
+                                    Adjustment.KEY_SNOOZE_CRITERIA,
+                                    android.service.notification.SnoozeCriterion.class);
                     setSnoozeCriteria(snoozeCriterionList);
                     EventLogTags.writeNotificationAdjusted(getKey(), Adjustment.KEY_SNOOZE_CRITERIA,
                             snoozeCriterionList.toString());
@@ -736,7 +744,8 @@
                 }
                 if (signals.containsKey(Adjustment.KEY_CONTEXTUAL_ACTIONS)) {
                     setSystemGeneratedSmartActions(
-                            signals.getParcelableArrayList(Adjustment.KEY_CONTEXTUAL_ACTIONS, android.app.Notification.Action.class));
+                            signals.getParcelableArrayList(Adjustment.KEY_CONTEXTUAL_ACTIONS,
+                                    android.app.Notification.Action.class));
                     EventLogTags.writeNotificationAdjusted(getKey(),
                             Adjustment.KEY_CONTEXTUAL_ACTIONS,
                             getSystemGeneratedSmartActions().toString());
@@ -778,6 +787,14 @@
                             Adjustment.KEY_SENSITIVE_CONTENT,
                             Boolean.toString(mSensitiveContent));
                 }
+                if (android.service.notification.Flags.notificationClassification()
+                        && signals.containsKey(Adjustment.KEY_TYPE)) {
+                    updateNotificationChannel(signals.getParcelable(Adjustment.KEY_TYPE,
+                            NotificationChannel.class));
+                    EventLogTags.writeNotificationAdjusted(getKey(),
+                            Adjustment.KEY_TYPE,
+                            mChannel.getId());
+                }
                 if (!signals.isEmpty() && adjustment.getIssuer() != null) {
                     mAdjustmentIssuer = adjustment.getIssuer();
                 }
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 309e945..c09504f 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -17,16 +17,23 @@
 package com.android.server.notification;
 
 import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
+import static android.app.NotificationChannel.NEWS_ID;
 import static android.app.NotificationChannel.PLACEHOLDER_CONVERSATION_ID;
+import static android.app.NotificationChannel.PROMOTIONS_ID;
+import static android.app.NotificationChannel.RECS_ID;
+import static android.app.NotificationChannel.SOCIAL_MEDIA_ID;
 import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
 import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
 import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE;
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
 import static android.app.NotificationManager.IMPORTANCE_MAX;
 import static android.app.NotificationManager.IMPORTANCE_NONE;
 import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
 
 import static android.os.UserHandle.USER_SYSTEM;
+import static android.service.notification.Flags.notificationClassification;
+
 import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES;
 import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES;
 import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES;
@@ -189,9 +196,12 @@
         int USER_LOCKED_BUBBLE = 0x00000002;
     }
 
+    private final Object mLock = new Object();
     // pkg|uid => PackagePreferences
+    @GuardedBy("mLock")
     private final ArrayMap<String, PackagePreferences> mPackagePreferences = new ArrayMap<>();
     // pkg|userId => PackagePreferences
+    @GuardedBy("mLock")
     private final ArrayMap<String, PackagePreferences> mRestoredWithoutUids = new ArrayMap<>();
 
     private final Context mContext;
@@ -263,7 +273,7 @@
                     Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
                     NotificationManagerService.REVIEW_NOTIF_STATE_SHOULD_SHOW);
         }
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
                 tag = parser.getName();
                 if (type == XmlPullParser.END_TAG && TAG_RANKING.equals(tag)) {
@@ -485,6 +495,7 @@
                 DEFAULT_BUBBLE_PREFERENCE, mClock.millis());
     }
 
+    @GuardedBy("mLock")
     private PackagePreferences getOrCreatePackagePreferencesLocked(String pkg,
             @UserIdInt int userId, int uid, int importance, int priority, int visibility,
             boolean showBadge, int bubblePreference, long creationTime) {
@@ -514,6 +525,10 @@
                 Slog.e(TAG, "createDefaultChannelIfNeededLocked - Exception: " + e);
             }
 
+            if (notificationClassification()) {
+                addReservedChannelsLocked(r);
+            }
+
             if (r.uid == UNKNOWN_UID) {
                 if (Flags.persistIncompleteRestoreData()) {
                     r.userId = userId;
@@ -603,6 +618,40 @@
         return true;
     }
 
+    private void addReservedChannelsLocked(PackagePreferences p) {
+        if (!p.channels.containsKey(NotificationChannel.PROMOTIONS_ID)) {
+            NotificationChannel channel = new NotificationChannel(
+                    NotificationChannel.PROMOTIONS_ID,
+                    mContext.getString(R.string.promotional_notification_channel_label),
+                    IMPORTANCE_LOW);
+            p.channels.put(channel.getId(), channel);
+        }
+
+        if (!p.channels.containsKey(NotificationChannel.RECS_ID)) {
+            NotificationChannel channel = new NotificationChannel(
+                    NotificationChannel.RECS_ID,
+                    mContext.getString(R.string.recs_notification_channel_label),
+                    IMPORTANCE_LOW);
+            p.channels.put(channel.getId(), channel);
+        }
+
+        if (!p.channels.containsKey(NotificationChannel.NEWS_ID)) {
+            NotificationChannel channel = new NotificationChannel(
+                    NotificationChannel.NEWS_ID,
+                    mContext.getString(R.string.news_notification_channel_label),
+                    IMPORTANCE_LOW);
+            p.channels.put(channel.getId(), channel);
+        }
+
+        if (!p.channels.containsKey(NotificationChannel.SOCIAL_MEDIA_ID)) {
+            NotificationChannel channel = new NotificationChannel(
+                    NotificationChannel.SOCIAL_MEDIA_ID,
+                    mContext.getString(R.string.social_notification_channel_label),
+                    IMPORTANCE_LOW);
+            p.channels.put(channel.getId(), channel);
+        }
+    }
+
     public void writeXml(TypedXmlSerializer out, boolean forBackup, int userId) throws IOException {
         out.startTag(null, TAG_RANKING);
         out.attributeInt(null, ATT_VERSION, XML_VERSION);
@@ -616,7 +665,7 @@
             notifPermissions = mPermissionHelper.getNotificationPermissionValues(userId);
         }
 
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             final int N = mPackagePreferences.size();
             for (int i = 0; i < N; i++) {
                 final PackagePreferences r = mPackagePreferences.valueAt(i);
@@ -625,11 +674,10 @@
                 }
                 writePackageXml(r, out, notifPermissions, forBackup);
             }
-        }
-        if (Flags.persistIncompleteRestoreData() && !forBackup) {
-            synchronized (mRestoredWithoutUids) {
-                final int N = mRestoredWithoutUids.size();
-                for (int i = 0; i < N; i++) {
+
+            if (Flags.persistIncompleteRestoreData() && !forBackup) {
+                final int M = mRestoredWithoutUids.size();
+                for (int i = 0; i < M; i++) {
                     final PackagePreferences r = mRestoredWithoutUids.valueAt(i);
                     writePackageXml(r, out, notifPermissions, false);
                 }
@@ -732,7 +780,7 @@
      */
     public void setBubblesAllowed(String pkg, int uid, int bubblePreference) {
         boolean changed;
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences p = getOrCreatePackagePreferencesLocked(pkg, uid);
             changed = p.bubblePreference != bubblePreference;
             p.bubblePreference = bubblePreference;
@@ -752,20 +800,20 @@
      */
     @Override
     public int getBubblePreference(String pkg, int uid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             return getOrCreatePackagePreferencesLocked(pkg, uid).bubblePreference;
         }
     }
 
     public int getAppLockedFields(String pkg, int uid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             return getOrCreatePackagePreferencesLocked(pkg, uid).lockedAppFields;
         }
     }
 
     @Override
     public boolean canShowBadge(String packageName, int uid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             return getOrCreatePackagePreferencesLocked(packageName, uid).showBadge;
         }
     }
@@ -773,7 +821,7 @@
     @Override
     public void setShowBadge(String packageName, int uid, boolean showBadge) {
         boolean changed = false;
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences pkgPrefs = getOrCreatePackagePreferencesLocked(packageName, uid);
             if (pkgPrefs.showBadge != showBadge) {
                 pkgPrefs.showBadge = showBadge;
@@ -786,28 +834,28 @@
     }
 
     public boolean isInInvalidMsgState(String packageName, int uid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
             return r.hasSentInvalidMessage && !r.hasSentValidMessage;
         }
     }
 
     public boolean hasUserDemotedInvalidMsgApp(String packageName, int uid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
             return isInInvalidMsgState(packageName, uid) ? r.userDemotedMsgApp : false;
         }
     }
 
     public void setInvalidMsgAppDemoted(String packageName, int uid, boolean isDemoted) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
             r.userDemotedMsgApp = isDemoted;
         }
     }
 
     public boolean setInvalidMessageSent(String packageName, int uid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
             boolean valueChanged = r.hasSentInvalidMessage == false;
             r.hasSentInvalidMessage = true;
@@ -817,7 +865,7 @@
     }
 
     public boolean setValidMessageSent(String packageName, int uid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
             boolean valueChanged = r.hasSentValidMessage == false;
             r.hasSentValidMessage = true;
@@ -828,7 +876,7 @@
 
     @VisibleForTesting
     boolean hasSentInvalidMsg(String packageName, int uid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
             return r.hasSentInvalidMessage;
         }
@@ -836,7 +884,7 @@
 
     @VisibleForTesting
     boolean hasSentValidMsg(String packageName, int uid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
             return r.hasSentValidMessage;
         }
@@ -844,7 +892,7 @@
 
     @VisibleForTesting
     boolean didUserEverDemoteInvalidMsgApp(String packageName, int uid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
             return r.userDemotedMsgApp;
         }
@@ -852,7 +900,7 @@
 
     /** Sets whether this package has sent a notification with valid bubble metadata. */
     public boolean setValidBubbleSent(String packageName, int uid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
             boolean valueChanged = !r.hasSentValidBubble;
             r.hasSentValidBubble = true;
@@ -861,14 +909,14 @@
     }
 
     boolean hasSentValidBubble(String packageName, int uid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
             return r.hasSentValidBubble;
         }
     }
 
     boolean isImportanceLocked(String pkg, int uid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
             return r.fixedImportance || r.defaultAppLockedImportance;
         }
@@ -879,7 +927,7 @@
         if (groupId == null) {
             return false;
         }
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
             NotificationChannelGroup group = r.groups.get(groupId);
             if (group == null) {
@@ -890,13 +938,13 @@
     }
 
     int getPackagePriority(String pkg, int uid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             return getOrCreatePackagePreferencesLocked(pkg, uid).priority;
         }
     }
 
     int getPackageVisibility(String pkg, int uid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             return getOrCreatePackagePreferencesLocked(pkg, uid).visibility;
         }
     }
@@ -911,7 +959,7 @@
             throw new IllegalArgumentException("group.getName() can't be empty");
         }
         boolean needsDndChange = false;
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
             if (r == null) {
                 throw new IllegalArgumentException("Invalid package");
@@ -965,7 +1013,7 @@
                 && channel.getImportance() <= IMPORTANCE_MAX, "Invalid importance level");
 
         boolean needsPolicyFileChange = false, wasUndeleted = false, needsDndChange = false;
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
             if (r == null) {
                 throw new IllegalArgumentException("Invalid package");
@@ -1109,7 +1157,7 @@
 
     void unlockNotificationChannelImportance(String pkg, int uid, String updatedChannelId) {
         Objects.requireNonNull(updatedChannelId);
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
             if (r == null) {
                 throw new IllegalArgumentException("Invalid package");
@@ -1131,7 +1179,7 @@
         Objects.requireNonNull(updatedChannel.getId());
         boolean changed = false;
         boolean needsDndChange = false;
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
             if (r == null) {
                 throw new IllegalArgumentException("Invalid package");
@@ -1306,7 +1354,7 @@
             String channelId, String conversationId, boolean returnParentIfNoConversationChannel,
             boolean includeDeleted) {
         Preconditions.checkNotNull(pkg);
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
             if (r == null) {
                 return null;
@@ -1347,7 +1395,7 @@
         Preconditions.checkNotNull(pkg);
         Preconditions.checkNotNull(conversationId);
         List<NotificationChannel> channels = new ArrayList<>();
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
             if (r == null) {
                 return channels;
@@ -1367,7 +1415,7 @@
             int callingUid, boolean fromSystemOrSystemUi) {
         boolean deletedChannel = false;
         boolean channelBypassedDnd = false;
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
             if (r == null) {
                 return false;
@@ -1403,7 +1451,7 @@
     public void permanentlyDeleteNotificationChannel(String pkg, int uid, String channelId) {
         Objects.requireNonNull(pkg);
         Objects.requireNonNull(channelId);
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
             if (r == null) {
                 return;
@@ -1415,7 +1463,7 @@
     @Override
     public void permanentlyDeleteNotificationChannels(String pkg, int uid) {
         Objects.requireNonNull(pkg);
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
             if (r == null) {
                 return;
@@ -1446,7 +1494,7 @@
                 boolean fixed = mPermissionHelper.isPermissionFixed(
                         pi.packageName, user.getUserHandle().getIdentifier());
                 if (fixed) {
-                    synchronized (mPackagePreferences) {
+                    synchronized (mLock) {
                         PackagePreferences p = getOrCreatePackagePreferencesLocked(
                                 pi.packageName, pi.applicationInfo.uid);
                         p.fixedImportance = true;
@@ -1461,7 +1509,7 @@
 
     public void updateDefaultApps(int userId, ArraySet<String> toRemove,
             ArraySet<Pair<String, Integer>> toAdd) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             for (PackagePreferences p : mPackagePreferences.values()) {
                 if (userId == UserHandle.getUserId(p.uid)) {
                     if (toRemove != null && toRemove.contains(p.pkg)) {
@@ -1491,7 +1539,7 @@
     public NotificationChannelGroup getNotificationChannelGroupWithChannels(String pkg,
             int uid, String groupId, boolean includeDeleted) {
         Objects.requireNonNull(pkg);
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
             if (r == null || groupId == null || !r.groups.containsKey(groupId)) {
                 return null;
@@ -1514,7 +1562,7 @@
     public NotificationChannelGroup getNotificationChannelGroup(String groupId, String pkg,
             int uid) {
         Objects.requireNonNull(pkg);
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
             if (r == null) {
                 return null;
@@ -1528,7 +1576,7 @@
             boolean includeBlocked, Set<String> activeChannelFilter) {
         Objects.requireNonNull(pkg);
         Map<String, NotificationChannelGroup> groups = new ArrayMap<>();
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
             if (r == null) {
                 return ParceledListSlice.emptyList();
@@ -1540,7 +1588,11 @@
                 boolean includeChannel = (includeDeleted || !nc.isDeleted())
                         && (activeChannelFilter == null
                                 || (includeBlocked && nc.getImportance() == IMPORTANCE_NONE)
-                                || activeChannelFilter.contains(nc.getId()));
+                                || activeChannelFilter.contains(nc.getId()))
+                        && !PROMOTIONS_ID.equals(nc.getId())
+                        && !NEWS_ID.equals(nc.getId())
+                        && !SOCIAL_MEDIA_ID.equals(nc.getId())
+                        && !RECS_ID.equals(nc.getId());
                 if (includeChannel) {
                     if (nc.getGroup() != null) {
                         if (r.groups.get(nc.getGroup()) != null) {
@@ -1575,7 +1627,7 @@
             String groupId, int callingUid, boolean fromSystemOrSystemUi) {
         List<NotificationChannel> deletedChannels = new ArrayList<>();
         boolean groupBypassedDnd = false;
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
             if (r == null || TextUtils.isEmpty(groupId)) {
                 return deletedChannels;
@@ -1607,7 +1659,7 @@
     public Collection<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
             int uid) {
         List<NotificationChannelGroup> groups = new ArrayList<>();
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
             if (r == null) {
                 return groups;
@@ -1618,7 +1670,7 @@
     }
 
     public NotificationChannelGroup getGroupForChannel(String pkg, int uid, String channelId) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences p = getPackagePreferencesLocked(pkg, uid);
             if (p != null) {
                 NotificationChannel nc = p.channels.get(channelId);
@@ -1637,7 +1689,7 @@
 
     public ArrayList<ConversationChannelWrapper> getConversations(IntArray userIds,
             boolean onlyImportant) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             ArrayList<ConversationChannelWrapper> conversations = new ArrayList<>();
             for (PackagePreferences p : mPackagePreferences.values()) {
                 if (userIds.binarySearch(UserHandle.getUserId(p.uid)) >= 0) {
@@ -1681,7 +1733,7 @@
 
     public ArrayList<ConversationChannelWrapper> getConversations(String pkg, int uid) {
         Objects.requireNonNull(pkg);
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
             if (r == null) {
                 return new ArrayList<>();
@@ -1723,7 +1775,7 @@
     public @NonNull List<String> deleteConversations(String pkg, int uid,
             Set<String> conversationIds, int callingUid, boolean fromSystemOrSystemUi) {
         List<String> deletedChannelIds = new ArrayList<>();
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
             if (r == null) {
                 return deletedChannelIds;
@@ -1756,7 +1808,7 @@
             boolean includeDeleted) {
         Objects.requireNonNull(pkg);
         List<NotificationChannel> channels = new ArrayList<>();
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
             if (r == null) {
                 return ParceledListSlice.emptyList();
@@ -1778,7 +1830,7 @@
     public ParceledListSlice<NotificationChannel> getNotificationChannelsBypassingDnd(String pkg,
             int uid) {
         List<NotificationChannel> channels = new ArrayList<>();
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             final PackagePreferences r = mPackagePreferences.get(
                     packagePreferencesKey(pkg, uid));
             if (r != null) {
@@ -1799,9 +1851,9 @@
      * upgrades.
      */
     public boolean onlyHasDefaultChannel(String pkg, int uid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
-            if (r.channels.size() == 1
+            if (r.channels.size() == (notificationClassification() ? 5 : 1)
                     && r.channels.containsKey(NotificationChannel.DEFAULT_CHANNEL_ID)) {
                 return true;
             }
@@ -1812,7 +1864,7 @@
     public int getDeletedChannelCount(String pkg, int uid) {
         Objects.requireNonNull(pkg);
         int deletedCount = 0;
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
             if (r == null) {
                 return deletedCount;
@@ -1831,7 +1883,7 @@
     public int getBlockedChannelCount(String pkg, int uid) {
         Objects.requireNonNull(pkg);
         int blockedCount = 0;
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences r = getPackagePreferencesLocked(pkg, uid);
             if (r == null) {
                 return blockedCount;
@@ -1874,7 +1926,7 @@
         ArraySet<Pair<String, Integer>> candidatePkgs = new ArraySet<>();
 
         final IntArray currentUserIds = mUserProfiles.getCurrentProfileIds();
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             final int numPackagePreferences = mPackagePreferences.size();
             for (int i = 0; i < numPackagePreferences; i++) {
                 final PackagePreferences r = mPackagePreferences.valueAt(i);
@@ -1943,7 +1995,7 @@
      * considered for sentiment adjustments (and thus never show a blocking helper).
      */
     public void setAppImportanceLocked(String packageName, int uid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences prefs = getOrCreatePackagePreferencesLocked(packageName, uid);
             if ((prefs.lockedAppFields & LockableAppFields.USER_LOCKED_IMPORTANCE) != 0) {
                 return;
@@ -1959,7 +2011,7 @@
      * Returns the delegate for a given package, if it's allowed by the package and the user.
      */
     public @Nullable String getNotificationDelegate(String sourcePkg, int sourceUid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences prefs = getPackagePreferencesLocked(sourcePkg, sourceUid);
 
             if (prefs == null || prefs.delegate == null) {
@@ -1977,7 +2029,7 @@
      */
     public void setNotificationDelegate(String sourcePkg, int sourceUid,
             String delegatePkg, int delegateUid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences prefs = getOrCreatePackagePreferencesLocked(sourcePkg, sourceUid);
             prefs.delegate = new Delegate(delegatePkg, delegateUid, true);
         }
@@ -1987,7 +2039,7 @@
      * Used by an app to turn off its notification delegate.
      */
     public void revokeNotificationDelegate(String sourcePkg, int sourceUid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences prefs = getPackagePreferencesLocked(sourcePkg, sourceUid);
             if (prefs != null && prefs.delegate != null) {
                 prefs.delegate.mEnabled = false;
@@ -2001,7 +2053,7 @@
      */
     public boolean isDelegateAllowed(String sourcePkg, int sourceUid,
             String potentialDelegatePkg, int potentialDelegateUid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences prefs = getPackagePreferencesLocked(sourcePkg, sourceUid);
 
             return prefs != null && prefs.isValidDelegate(potentialDelegatePkg,
@@ -2047,24 +2099,25 @@
         pw.println("per-package config version: " + XML_VERSION);
 
         pw.println("PackagePreferences:");
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             dumpPackagePreferencesLocked(pw, prefix, filter, mPackagePreferences, pkgPermissions);
+            pw.println("Restored without uid:");
+            dumpPackagePreferencesLocked(pw, prefix, filter, mRestoredWithoutUids, null);
         }
-        pw.println("Restored without uid:");
-        dumpPackagePreferencesLocked(pw, prefix, filter, mRestoredWithoutUids, null);
     }
 
     public void dump(ProtoOutputStream proto,
             @NonNull NotificationManagerService.DumpFilter filter,
             ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             dumpPackagePreferencesLocked(proto, RankingHelperProto.RECORDS, filter,
                     mPackagePreferences, pkgPermissions);
+            dumpPackagePreferencesLocked(proto, RankingHelperProto.RECORDS_RESTORED_WITHOUT_UID,
+                    filter, mRestoredWithoutUids, null);
         }
-        dumpPackagePreferencesLocked(proto, RankingHelperProto.RECORDS_RESTORED_WITHOUT_UID, filter,
-                mRestoredWithoutUids, null);
     }
 
+    @GuardedBy("mLock")
     private void dumpPackagePreferencesLocked(PrintWriter pw, String prefix,
             @NonNull NotificationManagerService.DumpFilter filter,
             ArrayMap<String, PackagePreferences> packagePreferences,
@@ -2249,7 +2302,7 @@
             pkgsWithPermissionsToHandle = pkgPermissions.keySet();
         }
         int pulledEvents = 0;
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             for (int i = 0; i < mPackagePreferences.size(); i++) {
                 if (pulledEvents > NOTIFICATION_PREFERENCES_PULL_LIMIT) {
                     break;
@@ -2329,7 +2382,7 @@
      * {@link StatsEvent}.
      */
     public void pullPackageChannelPreferencesStats(List<StatsEvent> events) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             int totalChannelsPulled = 0;
             for (int i = 0; i < mPackagePreferences.size(); i++) {
                 if (totalChannelsPulled > NOTIFICATION_CHANNEL_PULL_LIMIT) {
@@ -2365,7 +2418,7 @@
      * {@link StatsEvent}.
      */
     public void pullPackageChannelGroupPreferencesStats(List<StatsEvent> events) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             int totalGroupsPulled = 0;
             for (int i = 0; i < mPackagePreferences.size(); i++) {
                 if (totalGroupsPulled > NOTIFICATION_CHANNEL_GROUP_PULL_LIMIT) {
@@ -2394,10 +2447,12 @@
             ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) {
         JSONObject ranking = new JSONObject();
         JSONArray PackagePreferencess = new JSONArray();
-        try {
-            ranking.put("noUid", mRestoredWithoutUids.size());
-        } catch (JSONException e) {
-            // pass
+        synchronized (mLock) {
+            try {
+                ranking.put("noUid", mRestoredWithoutUids.size());
+            } catch (JSONException e) {
+                // pass
+            }
         }
 
         // Track data that we've handled from the permissions-based list
@@ -2406,7 +2461,7 @@
             pkgsWithPermissionsToHandle = pkgPermissions.keySet();
         }
 
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             final int N = mPackagePreferences.size();
             for (int i = 0; i < N; i++) {
                 final PackagePreferences r = mPackagePreferences.valueAt(i);
@@ -2512,7 +2567,7 @@
     }
 
     public Map<Integer, String> getPackageBans() {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             final int N = mPackagePreferences.size();
             ArrayMap<Integer, String> packageBans = new ArrayMap<>(N);
             for (int i = 0; i < N; i++) {
@@ -2571,7 +2626,7 @@
 
     private Map<String, Integer> getPackageChannels() {
         ArrayMap<String, Integer> packageChannels = new ArrayMap<>();
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             for (int i = 0; i < mPackagePreferences.size(); i++) {
                 final PackagePreferences r = mPackagePreferences.valueAt(i);
                 int channelCount = 0;
@@ -2587,7 +2642,7 @@
     }
 
     public void onUserRemoved(int userId) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             int N = mPackagePreferences.size();
             for (int i = N - 1; i >= 0; i--) {
                 PackagePreferences PackagePreferences = mPackagePreferences.valueAt(i);
@@ -2599,7 +2654,7 @@
     }
 
     protected void onLocaleChanged(Context context, int userId) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             int N = mPackagePreferences.size();
             for (int i = 0; i < N; i++) {
                 PackagePreferences PackagePreferences = mPackagePreferences.valueAt(i);
@@ -2611,6 +2666,7 @@
                                 context.getResources().getString(
                                         R.string.default_notification_channel_label));
                     }
+                    // TODO (b/346396459): Localize all reserved channels
                 }
             }
         }
@@ -2628,22 +2684,24 @@
             for (int i = 0; i < size; i++) {
                 final String pkg = pkgList[i];
                 final int uid = uidList[i];
-                synchronized (mPackagePreferences) {
+                synchronized (mLock) {
                     mPackagePreferences.remove(packagePreferencesKey(pkg, uid));
+                    mRestoredWithoutUids.remove(unrestoredPackageKey(pkg, changeUserId));
                 }
-                mRestoredWithoutUids.remove(unrestoredPackageKey(pkg, changeUserId));
                 updated = true;
             }
         } else {
             for (String pkg : pkgList) {
-                // Package install
-                final PackagePreferences r =
-                        mRestoredWithoutUids.get(unrestoredPackageKey(pkg, changeUserId));
-                if (r != null) {
-                    try {
-                        r.uid = mPm.getPackageUidAsUser(r.pkg, changeUserId);
-                        mRestoredWithoutUids.remove(unrestoredPackageKey(pkg, changeUserId));
-                        synchronized (mPackagePreferences) {
+                try {
+                    // Package install
+                    int uid = mPm.getPackageUidAsUser(pkg, changeUserId);
+                    PackagePermission p = null;
+                    synchronized (mLock) {
+                        final PackagePreferences r =
+                                mRestoredWithoutUids.get(unrestoredPackageKey(pkg, changeUserId));
+                        if (r != null) {
+                            r.uid = uid;
+                            mRestoredWithoutUids.remove(unrestoredPackageKey(pkg, changeUserId));
                             mPackagePreferences.put(packagePreferencesKey(r.pkg, r.uid), r);
 
                             // Try to restore any unrestored sound resources
@@ -2665,32 +2723,29 @@
                                     channel.setSound(restoredUri, channel.getAudioAttributes());
                                 }
                             }
-                        }
-                        if (r.migrateToPm) {
-                            try {
-                                PackagePermission p = new PackagePermission(
+
+                            if (r.migrateToPm) {
+                                p = new PackagePermission(
                                         r.pkg, UserHandle.getUserId(r.uid),
                                         r.importance != IMPORTANCE_NONE,
                                         hasUserConfiguredSettings(r));
-                                mPermissionHelper.setNotificationPermission(p);
-                            } catch (Exception e) {
-                                Slog.e(TAG, "could not migrate setting for " + r.pkg, e);
                             }
+                            updated = true;
                         }
-                        updated = true;
-                    } catch (Exception e) {
-                        Slog.e(TAG, "could not restore " + r.pkg, e);
                     }
+                    if (p != null) {
+                        mPermissionHelper.setNotificationPermission(p);
+                    }
+                } catch (Exception e) {
+                    Slog.e(TAG, "could not restore " + pkg, e);
                 }
                 // Package upgrade
                 try {
-                    synchronized (mPackagePreferences) {
-                        PackagePreferences fullPackagePreferences = getPackagePreferencesLocked(pkg,
-                                mPm.getPackageUidAsUser(pkg, changeUserId));
-                        if (fullPackagePreferences != null) {
-                            updated |= createDefaultChannelIfNeededLocked(fullPackagePreferences);
-                            updated |= deleteDefaultChannelIfNeededLocked(fullPackagePreferences);
-                        }
+                    PackagePreferences fullPackagePreferences = getPackagePreferencesLocked(pkg,
+                            mPm.getPackageUidAsUser(pkg, changeUserId));
+                    if (fullPackagePreferences != null) {
+                        updated |= createDefaultChannelIfNeededLocked(fullPackagePreferences);
+                        updated |= deleteDefaultChannelIfNeededLocked(fullPackagePreferences);
                     }
                 } catch (PackageManager.NameNotFoundException e) {
                 }
@@ -2704,7 +2759,7 @@
     }
 
     public void clearData(String pkg, int uid) {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             PackagePreferences p = getPackagePreferencesLocked(pkg, uid);
             if (p != null) {
                 p.channels = new ArrayMap<>();
@@ -2891,7 +2946,7 @@
     }
 
     public void unlockAllNotificationChannels() {
-        synchronized (mPackagePreferences) {
+        synchronized (mLock) {
             final int numPackagePreferences = mPackagePreferences.size();
             for (int i = 0; i < numPackagePreferences; i++) {
                 final PackagePreferences r = mPackagePreferences.valueAt(i);
@@ -2908,7 +2963,7 @@
                     PackageManager.PackageInfoFlags.of(PackageManager.MATCH_ALL),
                     user.getUserHandle().getIdentifier());
             for (PackageInfo pi : packages) {
-                synchronized (mPackagePreferences) {
+                synchronized (mLock) {
                     PackagePreferences p = getOrCreatePackagePreferencesLocked(
                             pi.packageName, pi.applicationInfo.uid);
                     if (p.migrateToPm && p.uid != UNKNOWN_UID) {
diff --git a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
index 737353d..6efe88f 100644
--- a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
+++ b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
@@ -20,7 +20,6 @@
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -28,7 +27,6 @@
 import android.os.Binder;
 import android.provider.Settings;
 import android.service.notification.Condition;
-import android.service.notification.IConditionProvider;
 import android.service.notification.ScheduleCalendar;
 import android.service.notification.ZenModeConfig;
 import android.text.TextUtils;
@@ -54,8 +52,6 @@
     static final String TAG = "ConditionProviders.SCP";
     static final boolean DEBUG = true || Log.isLoggable("ConditionProviders", Log.DEBUG);
 
-    public static final ComponentName COMPONENT =
-            new ComponentName("android", ScheduleConditionProvider.class.getName());
     private static final String NOT_SHOWN = "...";
     private static final String SIMPLE_NAME = ScheduleConditionProvider.class.getSimpleName();
     private static final String ACTION_EVALUATE =  SIMPLE_NAME + ".EVALUATE";
@@ -66,7 +62,8 @@
 
     private final Context mContext = this;
     private final ArrayMap<Uri, ScheduleCalendar> mSubscriptions = new ArrayMap<>();
-    private ArraySet<Uri> mSnoozedForAlarm = new ArraySet<>();
+    @GuardedBy("mSnoozedForAlarm")
+    private final ArraySet<Uri> mSnoozedForAlarm = new ArraySet<>();
 
     private AlarmManager mAlarmManager;
     private boolean mConnected;
@@ -78,11 +75,6 @@
     }
 
     @Override
-    public ComponentName getComponent() {
-        return COMPONENT;
-    }
-
-    @Override
     public boolean isValidConditionId(Uri id) {
         return ZenModeConfig.isValidScheduleConditionId(id);
     }
@@ -103,7 +95,10 @@
                 pw.println(mSubscriptions.get(conditionId).toString());
             }
         }
-        pw.println("      snoozed due to alarm: " + TextUtils.join(SEPARATOR, mSnoozedForAlarm));
+        synchronized (mSnoozedForAlarm) {
+            pw.println(
+                    "      snoozed due to alarm: " + TextUtils.join(SEPARATOR, mSnoozedForAlarm));
+        }
         dumpUpcomingTime(pw, "mNextAlarmTime", mNextAlarmTime, now);
     }
 
@@ -149,16 +144,6 @@
         evaluateSubscriptions();
     }
 
-    @Override
-    public void attachBase(Context base) {
-        attachBaseContext(base);
-    }
-
-    @Override
-    public IConditionProvider asInterface() {
-        return (IConditionProvider) onBind(null);
-    }
-
     private void evaluateSubscriptions() {
         if (mAlarmManager == null) {
             mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
@@ -299,6 +284,7 @@
         }
     }
 
+    @GuardedBy("mSnoozedForAlarm")
     private void saveSnoozedLocked() {
         final String setting = TextUtils.join(SEPARATOR, mSnoozedForAlarm);
         final int currentUser = ActivityManager.getCurrentUser();
diff --git a/services/core/java/com/android/server/notification/ShortcutHelper.java b/services/core/java/com/android/server/notification/ShortcutHelper.java
index 86dcecf..857e319 100644
--- a/services/core/java/com/android/server/notification/ShortcutHelper.java
+++ b/services/core/java/com/android/server/notification/ShortcutHelper.java
@@ -27,7 +27,6 @@
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutServiceInternal;
 import android.os.Binder;
-import android.os.Handler;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.text.TextUtils;
@@ -65,85 +64,34 @@
         void onShortcutRemoved(String key);
     }
 
+    private final ShortcutListener mShortcutListener;
     private LauncherApps mLauncherAppsService;
-    private ShortcutListener mShortcutListener;
     private ShortcutServiceInternal mShortcutServiceInternal;
     private UserManager mUserManager;
 
-    // Key: packageName Value: <shortcutId, notifId>
-    private HashMap<String, HashMap<String, String>> mActiveShortcutBubbles = new HashMap<>();
-    private boolean mLauncherAppsCallbackRegistered;
+    // Key: packageName|userId Value: <shortcutId, notifId>
+    private final HashMap<String, HashMap<String, String>> mActiveShortcutBubbles = new HashMap<>();
+    private boolean mShortcutChangedCallbackRegistered;
 
     // Bubbles can be created based on a shortcut, we need to listen for changes to
     // that shortcut so that we may update the bubble appropriately.
-    private final LauncherApps.Callback mLauncherAppsCallback = new LauncherApps.Callback() {
-        @Override
-        public void onPackageRemoved(String packageName, UserHandle user) {
-        }
+    private final LauncherApps.ShortcutChangeCallback mShortcutChangeCallback =
+            new LauncherApps.ShortcutChangeCallback() {
 
-        @Override
-        public void onPackageAdded(String packageName, UserHandle user) {
-        }
+                @Override
+                public void onShortcutsAddedOrUpdated(@NonNull String packageName,
+                        @NonNull List<ShortcutInfo> shortcuts, @NonNull UserHandle user) {
+                }
 
-        @Override
-        public void onPackageChanged(String packageName, UserHandle user) {
-        }
-
-        @Override
-        public void onPackagesAvailable(String[] packageNames, UserHandle user,
-                boolean replacing) {
-        }
-
-        @Override
-        public void onPackagesUnavailable(String[] packageNames, UserHandle user,
-                boolean replacing) {
-        }
-
-        @Override
-        public void onShortcutsChanged(@NonNull String packageName,
-                @NonNull List<ShortcutInfo> shortcuts, @NonNull UserHandle user) {
-            HashMap<String, String> shortcutBubbles = mActiveShortcutBubbles.get(packageName);
-            ArrayList<String> bubbleKeysToRemove = new ArrayList<>();
-            if (shortcutBubbles != null) {
-                // Copy to avoid a concurrent modification exception when we remove bubbles from
-                // shortcutBubbles.
-                final Set<String> shortcutIds = new HashSet<>(shortcutBubbles.keySet());
-
-                // If we can't find one of our bubbles in the shortcut list, that bubble needs
-                // to be removed.
-                for (String shortcutId : shortcutIds) {
-                    boolean foundShortcut = false;
-                    for (int i = 0; i < shortcuts.size(); i++) {
-                        if (shortcuts.get(i).getId().equals(shortcutId)) {
-                            foundShortcut = true;
-                            break;
-                        }
-                    }
-                    if (!foundShortcut) {
-                        bubbleKeysToRemove.add(shortcutBubbles.get(shortcutId));
-                        shortcutBubbles.remove(shortcutId);
-                        if (shortcutBubbles.isEmpty()) {
-                            mActiveShortcutBubbles.remove(packageName);
-                            if (mLauncherAppsCallbackRegistered
-                                    && mActiveShortcutBubbles.isEmpty()) {
-                                mLauncherAppsService.unregisterCallback(mLauncherAppsCallback);
-                                mLauncherAppsCallbackRegistered = false;
-                            }
-                        }
+                public void onShortcutsRemoved(@NonNull String packageName,
+                        @NonNull List<ShortcutInfo> removedShortcuts, @NonNull UserHandle user) {
+                    final String packageUserKey = getPackageUserKey(packageName, user);
+                    if (mActiveShortcutBubbles.get(packageUserKey) == null) return;
+                    for (ShortcutInfo info : removedShortcuts) {
+                        onShortcutRemoved(packageUserKey, info.getId());
                     }
                 }
-            }
-
-            // Let NoMan know about the updates
-            for (int i = 0; i < bubbleKeysToRemove.size(); i++) {
-                // update flag bubble
-                String bubbleKey = bubbleKeysToRemove.get(i);
-                if (mShortcutListener != null) {
-                    mShortcutListener.onShortcutRemoved(bubbleKey);
-                }
-            }
-        }
-    };
+            };
 
     ShortcutHelper(LauncherApps launcherApps, ShortcutListener listener,
             ShortcutServiceInternal shortcutServiceInternal, UserManager userManager) {
@@ -172,14 +120,14 @@
      * Returns whether the given shortcut info is a conversation shortcut.
      */
     public static boolean isConversationShortcut(
-            ShortcutInfo shortcutInfo, ShortcutServiceInternal mShortcutServiceInternal,
+            ShortcutInfo shortcutInfo, ShortcutServiceInternal shortcutServiceInternal,
             int callingUserId) {
         if (shortcutInfo == null || !shortcutInfo.isLongLived() || !shortcutInfo.isEnabled()) {
             return false;
         }
         // TODO (b/155016294) uncomment when sharing shortcuts are required
         /*
-        mShortcutServiceInternal.isSharingShortcut(callingUserId, "android",
+        shortcutServiceInternal.isSharingShortcut(callingUserId, "android",
                 shortcutInfo.getPackage(), shortcutInfo.getId(), shortcutInfo.getUserId(),
                 SHARING_FILTER);
          */
@@ -233,34 +181,30 @@
      *
      * @param r the notification record to check
      * @param removedNotification true if this notification is being removed
-     * @param handler handler to register the callback with
      */
     void maybeListenForShortcutChangesForBubbles(NotificationRecord r,
-            boolean removedNotification,
-            Handler handler) {
+            boolean removedNotification) {
         final String shortcutId = r.getNotification().getBubbleMetadata() != null
                 ? r.getNotification().getBubbleMetadata().getShortcutId()
                 : null;
+        final String packageUserKey = getPackageUserKey(r.getSbn().getPackageName(), r.getUser());
         if (!removedNotification
                 && !TextUtils.isEmpty(shortcutId)
                 && r.getShortcutInfo() != null
                 && r.getShortcutInfo().getId().equals(shortcutId)) {
             // Must track shortcut based bubbles in case the shortcut is removed
             HashMap<String, String> packageBubbles = mActiveShortcutBubbles.get(
-                    r.getSbn().getPackageName());
+                    packageUserKey);
             if (packageBubbles == null) {
                 packageBubbles = new HashMap<>();
             }
             packageBubbles.put(shortcutId, r.getKey());
-            mActiveShortcutBubbles.put(r.getSbn().getPackageName(), packageBubbles);
-            if (!mLauncherAppsCallbackRegistered) {
-                mLauncherAppsService.registerCallback(mLauncherAppsCallback, handler);
-                mLauncherAppsCallbackRegistered = true;
-            }
+            mActiveShortcutBubbles.put(packageUserKey, packageBubbles);
+            registerCallbackIfNeeded();
         } else {
             // No longer track shortcut
             HashMap<String, String> packageBubbles = mActiveShortcutBubbles.get(
-                    r.getSbn().getPackageName());
+                    packageUserKey);
             if (packageBubbles != null) {
                 if (!TextUtils.isEmpty(shortcutId)) {
                     packageBubbles.remove(shortcutId);
@@ -278,20 +222,62 @@
                     }
                 }
                 if (packageBubbles.isEmpty()) {
-                    mActiveShortcutBubbles.remove(r.getSbn().getPackageName());
+                    mActiveShortcutBubbles.remove(packageUserKey);
                 }
             }
-            if (mLauncherAppsCallbackRegistered && mActiveShortcutBubbles.isEmpty()) {
-                mLauncherAppsService.unregisterCallback(mLauncherAppsCallback);
-                mLauncherAppsCallbackRegistered = false;
+            unregisterCallbackIfNeeded();
+        }
+    }
+
+    private String getPackageUserKey(String packageName, UserHandle user) {
+        return packageName + "|" + user.getIdentifier();
+    }
+
+    private void onShortcutRemoved(String packageUserKey, String shortcutId) {
+        HashMap<String, String> shortcutBubbles = mActiveShortcutBubbles.get(packageUserKey);
+        ArrayList<String> bubbleKeysToRemove = new ArrayList<>();
+        if (shortcutBubbles != null) {
+            if (shortcutBubbles.containsKey(shortcutId)) {
+                bubbleKeysToRemove.add(shortcutBubbles.get(shortcutId));
+                shortcutBubbles.remove(shortcutId);
+                if (shortcutBubbles.isEmpty()) {
+                    mActiveShortcutBubbles.remove(packageUserKey);
+                    unregisterCallbackIfNeeded();
+                }
             }
+            notifyNoMan(bubbleKeysToRemove);
+        }
+    }
+
+    private void registerCallbackIfNeeded() {
+        if (!mShortcutChangedCallbackRegistered) {
+            mShortcutChangedCallbackRegistered = true;
+            mShortcutServiceInternal.addShortcutChangeCallback(mShortcutChangeCallback);
+        }
+    }
+
+    private void unregisterCallbackIfNeeded() {
+        if (mShortcutChangedCallbackRegistered && mActiveShortcutBubbles.isEmpty()) {
+            mShortcutServiceInternal.removeShortcutChangeCallback(mShortcutChangeCallback);
+            mShortcutChangedCallbackRegistered = false;
         }
     }
 
     void destroy() {
-        if (mLauncherAppsCallbackRegistered) {
-            mLauncherAppsService.unregisterCallback(mLauncherAppsCallback);
-            mLauncherAppsCallbackRegistered = false;
+        if (mShortcutChangedCallbackRegistered) {
+            mShortcutServiceInternal.removeShortcutChangeCallback(mShortcutChangeCallback);
+            mShortcutChangedCallbackRegistered = false;
+        }
+    }
+
+    private void notifyNoMan(List<String> bubbleKeysToRemove) {
+        // Let NoMan know about the updates
+        for (int i = 0; i < bubbleKeysToRemove.size(); i++) {
+            // update flag bubble
+            String bubbleKey = bubbleKeysToRemove.get(i);
+            if (mShortcutListener != null) {
+                mShortcutListener.onShortcutRemoved(bubbleKey);
+            }
         }
     }
 }
diff --git a/services/core/java/com/android/server/notification/SystemConditionProviderService.java b/services/core/java/com/android/server/notification/SystemConditionProviderService.java
index 574f04c..97073b7 100644
--- a/services/core/java/com/android/server/notification/SystemConditionProviderService.java
+++ b/services/core/java/com/android/server/notification/SystemConditionProviderService.java
@@ -31,12 +31,21 @@
 public abstract class SystemConditionProviderService extends ConditionProviderService {
 
     abstract public void dump(PrintWriter pw, DumpFilter filter);
-    abstract public void attachBase(Context context);
-    abstract public IConditionProvider asInterface();
-    abstract public ComponentName getComponent();
     abstract public boolean isValidConditionId(Uri id);
     abstract public void onBootComplete();
 
+    final ComponentName getComponent() {
+        return new ComponentName("android", this.getClass().getName());
+    }
+
+    final IConditionProvider asInterface() {
+        return (IConditionProvider) onBind(null);
+    }
+
+    final void attachBase(Context context) {
+        attachBaseContext(context);
+    }
+
     protected static String ts(long time) {
         return new Date(time) + " (" + time + ")";
     }
diff --git a/services/core/java/com/android/server/notification/TimeToLiveHelper.java b/services/core/java/com/android/server/notification/TimeToLiveHelper.java
index 2facab7..a4460b2 100644
--- a/services/core/java/com/android/server/notification/TimeToLiveHelper.java
+++ b/services/core/java/com/android/server/notification/TimeToLiveHelper.java
@@ -54,13 +54,17 @@
     private final AlarmManager mAm;
 
     @VisibleForTesting
+    @GuardedBy("mLock")
     final TreeSet<Pair<Long, String>> mKeys;
+    final Object mLock = new Object();
 
     public TimeToLiveHelper(NotificationManagerPrivate nm, Context context) {
         mContext = context;
         mNm = nm;
         mAm = context.getSystemService(AlarmManager.class);
-        mKeys = new TreeSet<>((left, right) -> Long.compare(left.first, right.first));
+        synchronized (mLock) {
+            mKeys = new TreeSet<>((left, right) -> Long.compare(left.first, right.first));
+        }
 
         IntentFilter timeoutFilter = new IntentFilter(ACTION);
         timeoutFilter.addDataScheme(SCHEME_TIMEOUT);
@@ -73,7 +77,9 @@
     }
 
     void dump(PrintWriter pw, String indent) {
-        pw.println(indent + "mKeys " + mKeys);
+        synchronized (mLock) {
+            pw.println(indent + "mKeys " + mKeys);
+        }
     }
 
     private @NonNull PendingIntent getAlarmPendingIntent(String nextKey, int flags) {
@@ -93,30 +99,35 @@
 
     @VisibleForTesting
     void scheduleTimeoutLocked(NotificationRecord record, long currentTime) {
-        removeMatchingEntry(record.getKey());
+        synchronized (mLock) {
+            removeMatchingEntry(record.getKey());
 
-        final long timeoutAfter = currentTime + record.getNotification().getTimeoutAfter();
-        if (record.getNotification().getTimeoutAfter() > 0) {
-            final Long currentEarliestTime = mKeys.isEmpty() ? null : mKeys.first().first;
+            final long timeoutAfter = currentTime + record.getNotification().getTimeoutAfter();
+            if (record.getNotification().getTimeoutAfter() > 0) {
+                final Long currentEarliestTime = mKeys.isEmpty() ? null : mKeys.first().first;
 
-            // Maybe replace alarm with an earlier one
-            if (currentEarliestTime == null || timeoutAfter < currentEarliestTime) {
-                if (currentEarliestTime != null) {
-                    cancelFirstAlarm();
+                // Maybe replace alarm with an earlier one
+                if (currentEarliestTime == null || timeoutAfter < currentEarliestTime) {
+                    if (currentEarliestTime != null) {
+                        cancelFirstAlarm();
+                    }
+                    mKeys.add(Pair.create(timeoutAfter, record.getKey()));
+                    maybeScheduleFirstAlarm();
+                } else {
+                    mKeys.add(Pair.create(timeoutAfter, record.getKey()));
                 }
-                mKeys.add(Pair.create(timeoutAfter, record.getKey()));
-                maybeScheduleFirstAlarm();
-            } else {
-                mKeys.add(Pair.create(timeoutAfter, record.getKey()));
             }
         }
     }
 
     @VisibleForTesting
     void cancelScheduledTimeoutLocked(NotificationRecord record) {
-        removeMatchingEntry(record.getKey());
+        synchronized (mLock) {
+            removeMatchingEntry(record.getKey());
+        }
     }
 
+    @GuardedBy("mLock")
     private void removeMatchingEntry(String key) {
         if (!mKeys.isEmpty() && key.equals(mKeys.first().second)) {
             // cancel the first alarm, remove the first entry, maybe schedule the alarm for the new
@@ -139,11 +150,13 @@
         }
     }
 
+    @GuardedBy("mLock")
     private void cancelFirstAlarm() {
         final PendingIntent pi = getAlarmPendingIntent(mKeys.first().second, FLAG_CANCEL_CURRENT);
         mAm.cancel(pi);
     }
 
+    @GuardedBy("mLock")
     private void maybeScheduleFirstAlarm() {
         if (!mKeys.isEmpty()) {
             final PendingIntent piNewFirst = getAlarmPendingIntent(mKeys.first().second,
@@ -162,13 +175,17 @@
                 return;
             }
             if (ACTION.equals(action)) {
-                Pair<Long, String> earliest = mKeys.first();
-                String key = intent.getStringExtra(EXTRA_KEY);
-                if (!earliest.second.equals(key)) {
-                    Slog.wtf(TAG, "Alarm triggered but wasn't the earliest we were tracking");
+                String timeoutKey = null;
+                synchronized (mLock) {
+                    Pair<Long, String> earliest = mKeys.first();
+                    String key = intent.getStringExtra(EXTRA_KEY);
+                    if (!earliest.second.equals(key)) {
+                        Slog.wtf(TAG, "Alarm triggered but wasn't the earliest we were tracking");
+                    }
+                    removeMatchingEntry(key);
+                    timeoutKey = earliest.second;
                 }
-                removeMatchingEntry(key);
-                mNm.timeoutNotification(earliest.second);
+                mNm.timeoutNotification(timeoutKey);
             }
         }
     };
diff --git a/services/core/java/com/android/server/notification/ZenModeConditions.java b/services/core/java/com/android/server/notification/ZenModeConditions.java
index 02b5f97..3650536 100644
--- a/services/core/java/com/android/server/notification/ZenModeConditions.java
+++ b/services/core/java/com/android/server/notification/ZenModeConditions.java
@@ -58,6 +58,9 @@
         if (mConditionProviders.isSystemProviderEnabled(ZenModeConfig.EVENT_PATH)) {
             mConditionProviders.addSystemProvider(new EventConditionProvider());
         }
+        if (mConditionProviders.isSystemProviderEnabled(ZenModeConfig.CUSTOM_MANUAL_PATH)) {
+            mConditionProviders.addSystemProvider(new CustomManualConditionProvider());
+        }
         mConditionProviders.setCallback(this);
     }
 
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 267291c..c078409 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -34,6 +34,7 @@
 import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_INIT_USER;
 import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_RESTORE_BACKUP;
 import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI;
+import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_UNKNOWN;
 import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_USER;
 
 import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE;
@@ -1134,6 +1135,26 @@
                 modified = true;
             }
 
+            // Allow updating the CPS backing system rules (e.g. for custom manual -> schedule)
+            if (Flags.modesUi()
+                    && (origin == UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI || origin == UPDATE_ORIGIN_USER)
+                    && Objects.equals(rule.pkg, SystemZenRules.PACKAGE_ANDROID)
+                    && !Objects.equals(rule.component, azr.getOwner())) {
+                rule.component = azr.getOwner();
+                modified = true;
+            }
+
+            if (Flags.modesUi()) {
+                if (!azr.isEnabled() && (isNew || rule.enabled)) {
+                    // Creating a rule as disabled, or disabling a previously enabled rule.
+                    // Record whodunit.
+                    rule.disabledOrigin = origin;
+                } else if (azr.isEnabled()) {
+                    // Enabling or previously enabled. Clear disabler.
+                    rule.disabledOrigin = UPDATE_ORIGIN_UNKNOWN;
+                }
+            }
+
             if (!Objects.equals(rule.conditionId, azr.getConditionId())) {
                 rule.conditionId = azr.getConditionId();
                 modified = true;
diff --git a/services/core/java/com/android/server/notification/flags.aconfig b/services/core/java/com/android/server/notification/flags.aconfig
index bf6b652..7265cff 100644
--- a/services/core/java/com/android/server/notification/flags.aconfig
+++ b/services/core/java/com/android/server/notification/flags.aconfig
@@ -141,4 +141,11 @@
   namespace: "systemui"
   description: "This flag does not allow notifications older than 2 weeks old to be posted"
   bug: "339833083"
-}
\ No newline at end of file
+}
+
+flag {
+  name: "notification_force_group_singletons"
+  namespace: "systemui"
+  description: "This flag enables forced auto-grouping singleton groups"
+  bug: "336488844"
+}
diff --git a/services/core/java/com/android/server/pm/BackgroundUserSoundNotifier.java b/services/core/java/com/android/server/pm/BackgroundUserSoundNotifier.java
new file mode 100644
index 0000000..58b14b1
--- /dev/null
+++ b/services/core/java/com/android/server/pm/BackgroundUserSoundNotifier.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import static android.media.AudioAttributes.USAGE_ALARM;
+
+import android.annotation.SuppressLint;
+import android.app.ActivityManager;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.UserInfo;
+import android.media.AudioFocusInfo;
+import android.media.AudioManager;
+import android.media.AudioPlaybackConfiguration;
+import android.media.audiopolicy.AudioPolicy;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.Vibrator;
+import android.util.Log;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+
+public class BackgroundUserSoundNotifier {
+
+    private static final boolean DEBUG = false;
+    private static final String LOG_TAG = BackgroundUserSoundNotifier.class.getSimpleName();
+    public static final String BUSN_CHANNEL_ID = "bg_user_sound_channel";
+    public static final String BUSN_CHANNEL_NAME = "BackgroundUserSound";
+    private static final String ACTION_MUTE_SOUND = "com.android.server.ACTION_MUTE_BG_USER";
+    private static final String EXTRA_NOTIFICATION_ID = "com.android.server.EXTRA_CLIENT_UID";
+    private static final String EXTRA_CURRENT_USER_ID = "com.android.server.EXTRA_CURRENT_USER_ID";
+    private static final String ACTION_SWITCH_USER = "com.android.server.ACTION_SWITCH_TO_USER";
+    /** ID of user with notification displayed, -1 if notification is not showing*/
+    private int mUserWithNotification = -1;
+    private final Context mSystemUserContext;
+    @VisibleForTesting
+    final NotificationManager mNotificationManager;
+    private final UserManager mUserManager;
+
+    /**
+     * Facilitates the display of notifications to current user when there is an alarm or timer
+     * going off on background user and allows to manage the sound through actions.
+     */
+    public BackgroundUserSoundNotifier(Context context) {
+        mSystemUserContext = context;
+        mNotificationManager =  mSystemUserContext.getSystemService(NotificationManager.class);
+        mUserManager = mSystemUserContext.getSystemService(UserManager.class);
+        NotificationChannel channel = new NotificationChannel(BUSN_CHANNEL_ID, BUSN_CHANNEL_NAME,
+                NotificationManager.IMPORTANCE_HIGH);
+        mNotificationManager.createNotificationChannel(channel);
+        setupFocusControlAudioPolicy();
+    }
+
+    private void setupFocusControlAudioPolicy() {
+        // Used to configure our audio policy to handle focus events.
+        // This gives us the ability to decide which audio focus requests to accept and bypasses
+        // the framework ducking logic.
+        ActivityManager am = mSystemUserContext.getSystemService(ActivityManager.class);
+
+        registerReceiver(am);
+        BackgroundUserListener bgUserListener = new BackgroundUserListener(mSystemUserContext);
+        AudioPolicy.Builder focusControlPolicyBuilder = new AudioPolicy.Builder(mSystemUserContext);
+        focusControlPolicyBuilder.setLooper(Looper.getMainLooper());
+
+        focusControlPolicyBuilder.setAudioPolicyFocusListener(bgUserListener);
+
+        AudioPolicy mFocusControlAudioPolicy = focusControlPolicyBuilder.build();
+        int status = mSystemUserContext.getSystemService(AudioManager.class)
+                .registerAudioPolicy(mFocusControlAudioPolicy);
+        if (status != AudioManager.SUCCESS) {
+            Log.w(LOG_TAG , "Could not register the service's focus"
+                    + " control audio policy, error: " + status);
+        }
+    }
+
+    final class BackgroundUserListener extends AudioPolicy.AudioPolicyFocusListener {
+
+        Context mSystemContext;
+
+        BackgroundUserListener(Context systemContext) {
+            mSystemContext = systemContext;
+        }
+
+        @SuppressLint("MissingPermission")
+        public void onAudioFocusGrant(AudioFocusInfo afi, int requestResult) {
+            try {
+                BackgroundUserSoundNotifier.this.notifyForegroundUserAboutSoundIfNecessary(afi,
+                        mSystemContext.createContextAsUser(
+                                UserHandle.of(ActivityManager.getCurrentUser()), 0));
+            } catch (RemoteException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        @SuppressLint("MissingPermission")
+        public void onAudioFocusLoss(AudioFocusInfo afi, boolean wasNotified) {
+            BackgroundUserSoundNotifier.this.dismissNotificationIfNecessary(afi);
+        }
+    }
+
+    /**
+     * Registers a BroadcastReceiver for actions related to background user sound notifications.
+     *  When ACTION_MUTE_SOUND is received, it mutes a background user's alarm sound.
+     *  When ACTION_SWITCH_USER is received, a switch to the background user with alarm is started.
+     */
+    private void registerReceiver(ActivityManager service) {
+        BroadcastReceiver backgroundUserNotificationBroadcastReceiver = new BroadcastReceiver() {
+            @SuppressLint("MissingPermission")
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (!(intent.hasExtra(EXTRA_NOTIFICATION_ID)
+                        && intent.hasExtra(EXTRA_CURRENT_USER_ID)
+                        && intent.hasExtra(Intent.EXTRA_USER_ID))) {
+                    return;
+                }
+                final int notificationId = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1);
+
+                if (DEBUG) {
+                    Log.d(LOG_TAG,
+                            "User with alarm id   " + intent.getIntExtra(Intent.EXTRA_USER_ID,
+                                    -1) + "  current user id " + intent.getIntExtra(
+                                    EXTRA_CURRENT_USER_ID, -1));
+                }
+                mNotificationManager.cancelAsUser(LOG_TAG, notificationId,
+                        UserHandle.of(intent.getIntExtra(EXTRA_CURRENT_USER_ID, -1)));
+                if (ACTION_MUTE_SOUND.equals(intent.getAction())) {
+                    final AudioManager audioManager =
+                            mSystemUserContext.getSystemService(AudioManager.class);
+                    if (audioManager != null) {
+                        for (AudioPlaybackConfiguration apc :
+                                audioManager.getActivePlaybackConfigurations()) {
+                            if (apc.getAudioAttributes().getUsage() == USAGE_ALARM) {
+                                if (apc.getPlayerProxy() != null) {
+                                    apc.getPlayerProxy().stop();
+                                }
+                            }
+                        }
+                    }
+                    Vibrator vibrator = mSystemUserContext.getSystemService(Vibrator.class);
+                    if (vibrator != null && vibrator.isVibrating()) {
+                        vibrator.cancel();
+                    }
+                } else if (ACTION_SWITCH_USER.equals(intent.getAction())) {
+                    service.switchUser(intent.getIntExtra(Intent.EXTRA_USER_ID, -1));
+                }
+            }
+        };
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(ACTION_MUTE_SOUND);
+        filter.addAction(ACTION_SWITCH_USER);
+        mSystemUserContext.registerReceiver(backgroundUserNotificationBroadcastReceiver, filter,
+                Context.RECEIVER_NOT_EXPORTED);
+    }
+
+    /**
+     * Check if sound is coming from background user and show notification is required.
+     */
+    @VisibleForTesting
+    void notifyForegroundUserAboutSoundIfNecessary(AudioFocusInfo afi, Context
+            foregroundContext) throws RemoteException {
+        final int userId = UserHandle.getUserId(afi.getClientUid());
+        final int usage = afi.getAttributes().getUsage();
+        UserInfo userInfo = mUserManager.getUserInfo(userId);
+        if (userInfo != null && userId != foregroundContext.getUserId()) {
+            //TODO: b/349138482 - Add handling of cases when usage == USAGE_NOTIFICATION_RINGTONE
+            if (usage == USAGE_ALARM) {
+                Intent muteIntent = createIntent(ACTION_MUTE_SOUND, afi, foregroundContext, userId);
+                PendingIntent mutePI = PendingIntent.getBroadcast(mSystemUserContext, 0,
+                        muteIntent, PendingIntent.FLAG_UPDATE_CURRENT
+                                | PendingIntent.FLAG_IMMUTABLE);
+                Intent switchIntent = createIntent(ACTION_SWITCH_USER, afi, foregroundContext,
+                        userId);
+                PendingIntent switchPI = PendingIntent.getBroadcast(mSystemUserContext, 0,
+                        switchIntent, PendingIntent.FLAG_UPDATE_CURRENT
+                                | PendingIntent.FLAG_IMMUTABLE);
+
+                mUserWithNotification = foregroundContext.getUserId();
+                mNotificationManager.notifyAsUser(LOG_TAG, afi.getClientUid(),
+                        createNotification(userInfo.name, mutePI, switchPI, foregroundContext),
+                        foregroundContext.getUser());
+            }
+        }
+    }
+
+    /**
+     * If notification is present, dismisses it. To be called when the relevant sound loses focus.
+     */
+    private void dismissNotificationIfNecessary(AudioFocusInfo afi) {
+        if (mUserWithNotification >= 0) {
+            mNotificationManager.cancelAsUser(LOG_TAG, afi.getClientUid(),
+                    UserHandle.of(mUserWithNotification));
+        }
+        mUserWithNotification = -1;
+    }
+
+    private Intent createIntent(String intentAction, AudioFocusInfo afi, Context fgUserContext,
+            int userId) {
+        final Intent intent = new Intent(intentAction);
+        intent.putExtra(EXTRA_CURRENT_USER_ID, fgUserContext.getUserId());
+        intent.putExtra(EXTRA_NOTIFICATION_ID, afi.getClientUid());
+        intent.putExtra(Intent.EXTRA_USER_ID, userId);
+        return intent;
+    }
+
+    private Notification createNotification(String userName, PendingIntent muteIntent,
+            PendingIntent switchIntent, Context fgContext) {
+        final String title = fgContext.getString(R.string.bg_user_sound_notification_title_alarm,
+                userName);
+        final int icon = R.drawable.ic_audio_alarm;
+        final Notification.Action mute = new Notification.Action.Builder(null,
+                fgContext.getString(R.string.bg_user_sound_notification_button_mute),
+                muteIntent).build();
+        final Notification.Action switchUser = new Notification.Action.Builder(null,
+                fgContext.getString(R.string.bg_user_sound_notification_button_switch_user),
+                switchIntent).build();
+        return new Notification.Builder(mSystemUserContext, BUSN_CHANNEL_ID)
+                .setSmallIcon(icon)
+                .setTicker(title)
+                .setWhen(0)
+                .setOngoing(true)
+                .setColor(fgContext.getColor(R.color.system_notification_accent_color))
+                .setContentTitle(title)
+                .setContentIntent(muteIntent)
+                .setAutoCancel(true)
+                .setActions(mute, switchUser)
+                .setContentText(fgContext.getString(R.string.bg_user_sound_notification_message))
+                .setVisibility(Notification.VISIBILITY_PUBLIC)
+                .build();
+    }
+}
+
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index f59ae16..ee0159d 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -2207,11 +2207,17 @@
         if (PackageManagerServiceUtils.isSystemOrRoot(callingUid)) {
             return true;
         }
-        if (requireFullPermission) {
-            return hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+        boolean permissionGranted = requireFullPermission ? hasPermission(
+                Manifest.permission.INTERACT_ACROSS_USERS_FULL)
+                : (hasPermission(
+                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
+                        || hasPermission(Manifest.permission.INTERACT_ACROSS_USERS));
+        if (!permissionGranted) {
+            if (Process.isIsolatedUid(callingUid) && isKnownIsolatedComputeApp(callingUid)) {
+                return checkIsolatedOwnerHasPermission(callingUid, requireFullPermission);
+            }
         }
-        return hasPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
-                || hasPermission(Manifest.permission.INTERACT_ACROSS_USERS);
+        return permissionGranted;
     }
 
     /**
@@ -2227,6 +2233,24 @@
                 == PackageManager.PERMISSION_GRANTED;
     }
 
+    private boolean hasPermission(String permission, int uid) {
+        return mContext.checkPermission(permission, Process.INVALID_PID, uid)
+                == PackageManager.PERMISSION_GRANTED;
+    }
+
+    /**
+     * Since isolated process cannot hold permissions, we check the permissions on the owner app
+     * for known isolated_compute_app cases because they belong to the same package.
+     */
+    private boolean checkIsolatedOwnerHasPermission(int callingUid, boolean requireFullPermission) {
+        int ownerUid = getIsolatedOwner(callingUid);
+        if (requireFullPermission) {
+            return hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, ownerUid);
+        }
+        return hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, ownerUid)
+                || hasPermission(Manifest.permission.INTERACT_ACROSS_USERS, ownerUid);
+    }
+
     public final boolean isCallerSameApp(String packageName, int uid) {
         return isCallerSameApp(packageName, uid, false /* resolveIsolatedUid */);
     }
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 1bdc586..009e9b8 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -2504,13 +2504,13 @@
         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
     }
 
-    private void enableRestrictedSettings(String pkgName, int appId, int userId) {
+    private void setAccessRestrictedSettingsMode(String pkgName, int appId, int userId, int mode) {
         final AppOpsManager appOpsManager = mPm.mContext.getSystemService(AppOpsManager.class);
         final int uid = UserHandle.getUid(userId, appId);
         appOpsManager.setMode(AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS,
                 uid,
                 pkgName,
-                AppOpsManager.MODE_ERRORED);
+                mode);
     }
 
     /**
@@ -2888,8 +2888,21 @@
                 mPm.notifyPackageChanged(packageName, request.getAppId());
             }
 
-            if (!android.permission.flags.Flags.enhancedConfirmationModeApisEnabled()
-                    || !android.security.Flags.extendEcmToAllSettings()) {
+            // Set the OP_ACCESS_RESTRICTED_SETTINGS op, which is used by ECM (see {@link
+            // EnhancedConfirmationManager}) as a persistent state denoting whether an app is
+            // currently guarded by ECM, not guarded by ECM, or (in Android V+) that this should
+            // be decided later.
+            if (android.permission.flags.Flags.enhancedConfirmationModeApisEnabled()
+                    && android.security.Flags.extendEcmToAllSettings()) {
+                final int appId = request.getAppId();
+                mPm.mHandler.post(() -> {
+                    for (int userId : firstUserIds) {
+                        // MODE_DEFAULT means that the app's guardedness will be decided lazily
+                        setAccessRestrictedSettingsMode(packageName, appId, userId,
+                                AppOpsManager.MODE_DEFAULT);
+                    }
+                });
+            } else {
                 // Apply restricted settings on potentially dangerous packages. Needs to happen
                 // after appOpsManager is notified of the new package
                 if (request.getPackageSource() == PackageInstaller.PACKAGE_SOURCE_LOCAL_FILE
@@ -2898,7 +2911,9 @@
                     final int appId = request.getAppId();
                     mPm.mHandler.post(() -> {
                         for (int userId : firstUserIds) {
-                            enableRestrictedSettings(packageName, appId, userId);
+                            // MODE_ERRORED means that the app is explicitly guarded
+                            setAccessRestrictedSettingsMode(packageName, appId, userId,
+                                    AppOpsManager.MODE_ERRORED);
                         }
                     });
                 }
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 00e9d8d..47a79a3 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -1060,7 +1060,10 @@
         final boolean isInstallDpcPackagesPermissionGranted = (snapshot.checkUidPermission(
                 android.Manifest.permission.INSTALL_DPC_PACKAGES, mInstallerUid)
                 == PackageManager.PERMISSION_GRANTED);
-        final int targetPackageUid = snapshot.getPackageUid(packageName, 0, userId);
+        // Also query the package uid for archived packages, so that the user confirmation
+        // dialog can be displayed for updating archived apps.
+        final int targetPackageUid = snapshot.getPackageUid(packageName,
+                PackageManager.MATCH_ARCHIVED_PACKAGES, userId);
         final boolean isUpdate = targetPackageUid != -1 || isApexSession();
         final InstallSourceInfo existingInstallSourceInfo = isUpdate
                 ? snapshot.getInstallSourceInfo(packageName, userId)
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index c0b8034..2e63cdb 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -186,6 +186,7 @@
 import com.android.internal.pm.pkg.component.ParsedMainComponent;
 import com.android.internal.pm.pkg.parsing.ParsingPackageUtils;
 import com.android.internal.telephony.CarrierAppUtils;
+import com.android.internal.telephony.TelephonyPermissions;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.CollectionUtils;
 import com.android.internal.util.ConcurrentUtils;
@@ -4492,8 +4493,7 @@
     void setSystemAppHiddenUntilInstalled(@NonNull Computer snapshot, String packageName,
             boolean hidden) {
         final int callingUid = Binder.getCallingUid();
-        final boolean calledFromSystemOrPhone = callingUid == Process.PHONE_UID
-                || callingUid == Process.SYSTEM_UID;
+        final boolean calledFromSystemOrPhone = TelephonyPermissions.isSystemOrPhone(callingUid);
         if (!calledFromSystemOrPhone) {
             mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
                     "setSystemAppHiddenUntilInstalled");
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index ff8abf8..924b36c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -92,6 +92,7 @@
 
 import com.android.internal.content.InstallLocationUtils;
 import com.android.internal.content.NativeLibraryHelper;
+import com.android.internal.telephony.TelephonyPermissions;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.HexDump;
@@ -356,7 +357,7 @@
      * If not, throws a {@link SecurityException}.
      */
     public static void enforceSystemOrPhoneCaller(String methodName, int callingUid) {
-        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
+        if (!TelephonyPermissions.isSystemOrPhone(callingUid)) {
             throw new SecurityException(
                     "Cannot call " + methodName + " from UID " + callingUid);
         }
diff --git a/services/core/java/com/android/server/pm/ReconcilePackageUtils.java b/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
index 90d6adc..630fcb6 100644
--- a/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
+++ b/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
@@ -185,7 +185,8 @@
                         removeAppKeySetData = true;
                     }
 
-                    if (!installRequest.isInstallSystem() && !isSystemPackage && !isApex
+                    if ((installRequest.getScanFlags() & SCAN_BOOTING) == 0
+                            && !installRequest.isInstallSystem() && !isSystemPackage && !isApex
                             && signingDetails != null
                             && systemPackage != null && systemPackage.getSigningDetails() != null
                             && systemPackage.getSigningDetails().checkCapability(
diff --git a/services/core/java/com/android/server/pm/ResolveIntentHelper.java b/services/core/java/com/android/server/pm/ResolveIntentHelper.java
index 69490a8..5b4f310 100644
--- a/services/core/java/com/android/server/pm/ResolveIntentHelper.java
+++ b/services/core/java/com/android/server/pm/ResolveIntentHelper.java
@@ -126,10 +126,12 @@
                     userId, resolveForStart, /*allowDynamicSplits*/ true);
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
 
-            var args = new SaferIntentUtils.IntentArgs(intent, resolvedType,
-                    false /* isReceiver */, resolveForStart, filterCallingUid, callingPid);
-            args.platformCompat = mPlatformCompat;
-            SaferIntentUtils.filterNonExportedComponents(args, query);
+            if (resolveForStart) {
+                var args = new SaferIntentUtils.IntentArgs(intent, resolvedType,
+                        false /* isReceiver */, true, filterCallingUid, callingPid);
+                args.platformCompat = mPlatformCompat;
+                SaferIntentUtils.filterNonExportedComponents(args, query);
+            }
 
             final boolean queryMayBeFiltered =
                     UserHandle.getAppId(filterCallingUid) >= Process.FIRST_APPLICATION_UID
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 1cd77ff..4a60e45 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -3443,6 +3443,14 @@
         }
 
         @Override
+        public void removeShortcutChangeCallback(
+                @NonNull LauncherApps.ShortcutChangeCallback callback) {
+            synchronized (mServiceLock) {
+                mShortcutChangeCallbacks.remove(Objects.requireNonNull(callback));
+            }
+        }
+
+        @Override
         public int getShortcutIconResId(int launcherUserId, @NonNull String callingPackage,
                 @NonNull String packageName, @NonNull String shortcutId, int userId) {
             Objects.requireNonNull(callingPackage, "callingPackage");
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index db94d0e..b9a9d64f 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -58,10 +58,13 @@
 import android.app.ActivityManagerInternal;
 import android.app.ActivityManagerNative;
 import android.app.ActivityOptions;
+import android.app.AlarmManager;
 import android.app.BroadcastOptions;
 import android.app.IActivityManager;
 import android.app.IStopUserCallback;
 import android.app.KeyguardManager;
+import android.app.Notification;
+import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.StatsManager;
 import android.app.admin.DevicePolicyEventLogger;
@@ -147,6 +150,8 @@
 import com.android.internal.app.IAppOpsService;
 import com.android.internal.app.SetScreenLockDialogActivity;
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.os.RoSystemProperties;
 import com.android.internal.util.DumpUtils;
@@ -322,6 +327,12 @@
      */
     private static final long PRIVATE_SPACE_AUTO_LOCK_INACTIVITY_TIMEOUT_MS = 5 * 60 * 1000;
 
+    /**
+     * The time duration (in milliseconds) of the window length for the auto-lock message alarm
+     */
+    private static final long PRIVATE_SPACE_AUTO_LOCK_INACTIVITY_ALARM_WINDOW_MS =
+            TimeUnit.SECONDS.toMillis(55);
+
     // Tron counters
     private static final String TRON_GUEST_CREATED = "users_guest_created";
     private static final String TRON_USER_CREATED = "users_user_created";
@@ -330,6 +341,7 @@
     private final Context mContext;
     private final PackageManagerService mPm;
 
+
     /**
      * Lock for packages. If using with {@link #mUsersLock}, {@link #mPackagesLock} should be
      * acquired first.
@@ -552,8 +564,15 @@
 
     private KeyguardManager.KeyguardLockedStateListener mKeyguardLockedStateListener;
 
-    /** Token to identify and remove already scheduled private space auto-lock messages */
-    private static final Object PRIVATE_SPACE_AUTO_LOCK_MESSAGE_TOKEN = new Object();
+    /**
+     * {@link android.app.AlarmManager.OnAlarmListener} to schedule an alarm to enable
+     * auto-locking private space after screen timeout
+     */
+    private PrivateSpaceAutoLockTimer mPrivateSpaceAutoLockTimer;
+
+    /** Tag representing the alarm manager timer for auto-locking private space */
+    private static final String PRIVATE_SPACE_AUTO_LOCK_TIMER_TAG = "PrivateSpaceAutoLockTimer";
+
 
     /** Content observer to get callbacks for privte space autolock settings changes */
     private final SettingsObserver mPrivateSpaceAutoLockSettingsObserver;
@@ -604,22 +623,28 @@
         public void onReceive(Context context, Intent intent) {
             if (isAutoLockForPrivateSpaceEnabled()) {
                 if (ACTION_SCREEN_OFF.equals(intent.getAction())) {
-                    Slog.d(LOG_TAG, "SCREEN_OFF broadcast received");
-                    maybeScheduleMessageToAutoLockPrivateSpace();
+                    maybeScheduleAlarmToAutoLockPrivateSpace();
                 } else if (ACTION_SCREEN_ON.equals(intent.getAction())) {
                     Slog.d(LOG_TAG, "SCREEN_ON broadcast received, "
-                            + "removing queued message to auto-lock private space");
-                    // Remove any queued messages since the device is interactive again
-                    mHandler.removeCallbacksAndMessages(PRIVATE_SPACE_AUTO_LOCK_MESSAGE_TOKEN);
+                            + "removing pending alarms to auto-lock private space");
+                    // Remove any pending alarm since the device is interactive again
+                    cancelPendingAutoLockAlarms();
                 }
             }
         }
     };
 
+    private void cancelPendingAutoLockAlarms() {
+        final AlarmManager alarmManager = mContext.getSystemService(AlarmManager.class);
+        if (alarmManager != null && mPrivateSpaceAutoLockTimer != null) {
+            alarmManager.cancel(mPrivateSpaceAutoLockTimer);
+        }
+    }
+
     @VisibleForTesting
-    void maybeScheduleMessageToAutoLockPrivateSpace() {
+    void maybeScheduleAlarmToAutoLockPrivateSpace() {
         // No action needed if auto-lock on inactivity not selected
-        int privateSpaceAutoLockPreference =
+        final int privateSpaceAutoLockPreference =
                 Settings.Secure.getIntForUser(mContext.getContentResolver(),
                         Settings.Secure.PRIVATE_SPACE_AUTO_LOCK,
                         Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_AFTER_DEVICE_RESTART,
@@ -632,26 +657,65 @@
         }
         int privateProfileUserId = getPrivateProfileUserId();
         if (privateProfileUserId != UserHandle.USER_NULL) {
-            scheduleMessageToAutoLockPrivateSpace(privateProfileUserId,
-                    PRIVATE_SPACE_AUTO_LOCK_MESSAGE_TOKEN,
+            if (isQuietModeEnabled(privateProfileUserId)) {
+                Slogf.d(LOG_TAG, "Not scheduling auto-lock alarm for %d, "
+                        + "quiet mode already enabled", privateProfileUserId);
+                return;
+            }
+            scheduleAlarmToAutoLockPrivateSpace(privateProfileUserId,
                     PRIVATE_SPACE_AUTO_LOCK_INACTIVITY_TIMEOUT_MS);
         }
     }
 
     @VisibleForTesting
-    void scheduleMessageToAutoLockPrivateSpace(int userId, Object token,
-            long delayInMillis) {
-        Slog.i(LOG_TAG, "Scheduling auto-lock message");
-        mHandler.postDelayed(() -> {
+    void scheduleAlarmToAutoLockPrivateSpace(int userId, long delayInMillis) {
+        final AlarmManager alarmManager = mContext.getSystemService(AlarmManager.class);
+        if (alarmManager == null) {
+            Slog.e(LOG_TAG, "AlarmManager not available, cannot schedule auto-lock alarm");
+            return;
+        }
+        initPrivateSpaceAutoLockTimer(userId);
+        final long alarmWindowStartTime = SystemClock.elapsedRealtime() + delayInMillis;
+        alarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                alarmWindowStartTime,
+                PRIVATE_SPACE_AUTO_LOCK_INACTIVITY_ALARM_WINDOW_MS,
+                PRIVATE_SPACE_AUTO_LOCK_TIMER_TAG,
+                new HandlerExecutor(mHandler),
+                mPrivateSpaceAutoLockTimer);
+    }
+
+    private void initPrivateSpaceAutoLockTimer(int userId) {
+        cancelPendingAutoLockAlarms();
+        if (mPrivateSpaceAutoLockTimer == null
+                || mPrivateSpaceAutoLockTimer.getUserId() != userId) {
+            mPrivateSpaceAutoLockTimer = new PrivateSpaceAutoLockTimer(userId);
+        }
+    }
+
+    private class PrivateSpaceAutoLockTimer implements AlarmManager.OnAlarmListener {
+
+        private final int mUserId;
+
+        PrivateSpaceAutoLockTimer(int userId) {
+            mUserId = userId;
+        }
+
+        int getUserId() {
+            return mUserId;
+        }
+
+        @Override
+        public void onAlarm() {
             final PowerManager powerManager = mContext.getSystemService(PowerManager.class);
             if (powerManager != null && !powerManager.isInteractive()) {
-                Slog.i(LOG_TAG, "Auto-locking private space with user-id " + userId);
-                setQuietModeEnabledAsync(userId, true,
+                Slog.i(LOG_TAG, "Auto-locking private space with user-id " + mUserId);
+                setQuietModeEnabledAsync(mUserId, true,
                         /* target */ null, mContext.getPackageName());
             } else {
-                Slog.i(LOG_TAG, "Device is interactive, skipping auto-lock");
+                Slog.i(LOG_TAG, "Device is interactive, skipping auto-lock for profile user "
+                        + mUserId);
             }
-        }, token, delayInMillis);
+        }
     }
 
     @RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)
@@ -697,7 +761,7 @@
             // Unregister device inactivity broadcasts
             if (mIsDeviceInactivityBroadcastReceiverRegistered) {
                 Slog.i(LOG_TAG, "Removing device inactivity broadcast receivers");
-                mHandler.removeCallbacksAndMessages(PRIVATE_SPACE_AUTO_LOCK_MESSAGE_TOKEN);
+                cancelPendingAutoLockAlarms();
                 mContext.unregisterReceiver(mDeviceInactivityBroadcastReceiver);
                 mIsDeviceInactivityBroadcastReceiverRegistered = false;
             }
@@ -1070,6 +1134,12 @@
         if (isAutoLockingPrivateSpaceOnRestartsEnabled()) {
             autoLockPrivateSpace();
         }
+
+        showHsumNotificationIfNeeded();
+
+        if (Flags.addUiForSoundsFromBackgroundUsers()) {
+            new BackgroundUserSoundNotifier(mContext);
+        }
     }
 
     private boolean isAutoLockingPrivateSpaceOnRestartsEnabled() {
@@ -4163,6 +4233,48 @@
         mUpdatingSystemUserMode = true;
     }
 
+    /**
+     * If the device's actual HSUM status differs from that which is defined by its build
+     * configuration, warn the user. Ignores HSUM emulated status, since that isn't relevant.
+     *
+     * The goal is to inform dogfooders that they need to factory reset the device to align their
+     * device with its build configuration.
+     */
+    private void showHsumNotificationIfNeeded() {
+        if (RoSystemProperties.MULTIUSER_HEADLESS_SYSTEM_USER == isHeadlessSystemUserMode()) {
+            // Actual state does match the configuration. Great!
+            return;
+        }
+        if (Build.isDebuggable()
+                && !TextUtils.isEmpty(SystemProperties.get(SYSTEM_USER_MODE_EMULATION_PROPERTY))) {
+            // Ignore any device that has been playing around with HSUM emulation.
+            return;
+        }
+        Slogf.w(LOG_TAG, "Posting warning that device's HSUM status doesn't match the build's.");
+
+        final String title = mContext
+                .getString(R.string.wrong_hsum_configuration_notification_title);
+        final String message = mContext
+                .getString(R.string.wrong_hsum_configuration_notification_message);
+
+        final Notification notification =
+                new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
+                        .setSmallIcon(R.drawable.stat_sys_adb)
+                        .setWhen(0)
+                        .setOngoing(true)
+                        .setTicker(title)
+                        .setDefaults(0)
+                        .setColor(mContext.getColor(R.color.system_notification_accent_color))
+                        .setContentTitle(title)
+                        .setContentText(message)
+                        .setVisibility(Notification.VISIBILITY_PUBLIC)
+                        .build();
+
+        final NotificationManager notificationManager =
+                mContext.getSystemService(NotificationManager.class);
+        notificationManager.notifyAsUser(
+                null, SystemMessage.NOTE_WRONG_HSUM_STATUS, notification, UserHandle.ALL);
+    }
 
     private ResilientAtomicFile getUserListFile() {
         File tempBackup = new File(mUserListFile.getParent(), mUserListFile.getName() + ".backup");
@@ -5918,9 +6030,11 @@
         return userData;
     }
 
+    /** For testing only! Directly, unnaturally removes userId from list of users. */
     @VisibleForTesting
     void removeUserInfo(@UserIdInt int userId) {
         synchronized (mUsersLock) {
+            UserManager.invalidateUserSerialNumberCache();
             mUsers.remove(userId);
         }
     }
@@ -6346,6 +6460,7 @@
 
         // Remove this user from the list
         synchronized (mUsersLock) {
+            UserManager.invalidateUserSerialNumberCache();
             mUsers.remove(userId);
             mIsUserManaged.delete(userId);
         }
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 57ea233..8be20b0 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -807,7 +807,7 @@
                     getDefaultSystemHandlerActivityPackage(pm,
                             SearchManager.INTENT_ACTION_GLOBAL_SEARCH, userId),
                     userId, MICROPHONE_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS,
-                    NOTIFICATION_PERMISSIONS, PHONE_PERMISSIONS, CALENDAR_PERMISSIONS);
+                    NOTIFICATION_PERMISSIONS);
         }
 
         // Voice recognition
@@ -875,6 +875,12 @@
                     getDefaultSystemHandlerActivityPackage(pm, ACTION_TRACK, userId), userId,
                     SENSORS_PERMISSIONS);
             }
+
+            // Allow voice search on wear
+            grantPermissionsToSystemPackage(pm,
+                    getDefaultSystemHandlerActivityPackage(pm,
+                            SearchManager.INTENT_ACTION_GLOBAL_SEARCH, userId),
+                    userId, PHONE_PERMISSIONS, CALENDAR_PERMISSIONS);
         }
 
         // Print Spooler
@@ -1631,10 +1637,12 @@
     private boolean isSystemOrCertificateMatchingPackage(PackageInfo pi, String cert) {
         if (cert == null) {
             return pi.applicationInfo.isSystemApp();
+        } else if (Objects.equals(cert, "platform")) {
+            return mServiceInternal.isPlatformSigned(pi.packageName);
+        } else {
+            return mContext.getPackageManager().hasSigningCertificate(pi.packageName, HexEncoding.
+                    decode(cert.replace(":", "")), PackageManager.CERT_INPUT_SHA256);
         }
-
-        return mContext.getPackageManager().hasSigningCertificate(pi.packageName, HexEncoding.
-                decode(cert.replace(":", "")), PackageManager.CERT_INPUT_SHA256);
     }
 
     private static boolean doesPackageSupportRuntimePermissions(PackageInfo pkg) {
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 28254d0..46e6546 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -274,7 +274,9 @@
             mVirtualDeviceManagerInternal =
                     LocalServices.getService(VirtualDeviceManagerInternal.class);
         }
-        return mVirtualDeviceManagerInternal.getPersistentIdForDevice(deviceId);
+        return mVirtualDeviceManagerInternal == null
+                ? VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT
+                : mVirtualDeviceManagerInternal.getPersistentIdForDevice(deviceId);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index bf90a6c..9d0c0e9 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2090,8 +2090,13 @@
                     "Home - Long Press");
             switch (mLongPressOnHomeBehavior) {
                 case LONG_PRESS_HOME_ALL_APPS:
-                    logKeyboardSystemsEvent(event, KeyboardLogEvent.ALL_APPS);
-                    launchAllAppsAction();
+                    if (mHasFeatureLeanback) {
+                        launchAllAppsAction();
+                        logKeyboardSystemsEvent(event, KeyboardLogEvent.ALL_APPS);
+                    } else {
+                        launchAllAppsViaA11y();
+                        logKeyboardSystemsEvent(event, KeyboardLogEvent.ACCESSIBILITY_ALL_APPS);
+                    }
                     break;
                 case LONG_PRESS_HOME_ASSIST:
                     logKeyboardSystemsEvent(event, KeyboardLogEvent.LAUNCH_ASSISTANT);
@@ -3563,24 +3568,6 @@
                 Slog.wtf(TAG, "KEYCODE_VOICE_ASSIST should be handled in"
                         + " interceptKeyBeforeQueueing");
                 return true;
-            case KeyEvent.KEYCODE_VIDEO_APP_1:
-            case KeyEvent.KEYCODE_VIDEO_APP_2:
-            case KeyEvent.KEYCODE_VIDEO_APP_3:
-            case KeyEvent.KEYCODE_VIDEO_APP_4:
-            case KeyEvent.KEYCODE_VIDEO_APP_5:
-            case KeyEvent.KEYCODE_VIDEO_APP_6:
-            case KeyEvent.KEYCODE_VIDEO_APP_7:
-            case KeyEvent.KEYCODE_VIDEO_APP_8:
-            case KeyEvent.KEYCODE_FEATURED_APP_1:
-            case KeyEvent.KEYCODE_FEATURED_APP_2:
-            case KeyEvent.KEYCODE_FEATURED_APP_3:
-            case KeyEvent.KEYCODE_FEATURED_APP_4:
-            case KeyEvent.KEYCODE_DEMO_APP_1:
-            case KeyEvent.KEYCODE_DEMO_APP_2:
-            case KeyEvent.KEYCODE_DEMO_APP_3:
-            case KeyEvent.KEYCODE_DEMO_APP_4:
-                Slog.wtf(TAG, "KEYCODE_APP_X should be handled in interceptKeyBeforeQueueing");
-                return true;
             case KeyEvent.KEYCODE_BRIGHTNESS_UP:
             case KeyEvent.KEYCODE_BRIGHTNESS_DOWN:
                 if (down) {
@@ -3683,12 +3670,17 @@
                 }
                 break;
             case KeyEvent.KEYCODE_ALL_APPS:
-                if (!down) {
-                    mHandler.removeMessages(MSG_HANDLE_ALL_APPS);
-                    Message msg = mHandler.obtainMessage(MSG_HANDLE_ALL_APPS);
-                    msg.setAsynchronous(true);
-                    msg.sendToTarget();
-                    logKeyboardSystemsEvent(event, KeyboardLogEvent.ALL_APPS);
+                if (firstDown) {
+                    if (mHasFeatureLeanback) {
+                        mHandler.removeMessages(MSG_HANDLE_ALL_APPS);
+                        Message msg = mHandler.obtainMessage(MSG_HANDLE_ALL_APPS);
+                        msg.setAsynchronous(true);
+                        msg.sendToTarget();
+                        logKeyboardSystemsEvent(event, KeyboardLogEvent.ALL_APPS);
+                    } else {
+                        launchAllAppsViaA11y();
+                        logKeyboardSystemsEvent(event, KeyboardLogEvent.ACCESSIBILITY_ALL_APPS);
+                    }
                 }
                 return true;
             case KeyEvent.KEYCODE_NOTIFICATION:
@@ -5486,9 +5478,8 @@
         // In case startedGoingToSleep is called after screenTurnedOff (the source caller is in
         // order but the methods run on different threads) and updateScreenOffSleepToken was
         // skipped. Then acquire sleep token if screen was off.
-        if (!mDefaultDisplayPolicy.isScreenOnFully() && !mDefaultDisplayPolicy.isScreenOnEarly()
-                && com.android.window.flags.Flags.skipSleepingWhenSwitchingDisplay()) {
-            updateScreenOffSleepToken(true /* acquire */, false /* isSwappingDisplay */);
+        if (!mDefaultDisplayPolicy.isScreenOnFully() && !mDefaultDisplayPolicy.isScreenOnEarly()) {
+            updateScreenOffSleepToken(true /* acquire */);
         }
 
         if (mKeyguardDelegate != null) {
@@ -5651,9 +5642,8 @@
         if (DEBUG_WAKEUP) Slog.i(TAG, "Display" + displayId + " turned off...");
 
         if (displayId == DEFAULT_DISPLAY) {
-            if (!isSwappingDisplay || mIsGoingToSleepDefaultDisplay
-                    || !com.android.window.flags.Flags.skipSleepingWhenSwitchingDisplay()) {
-                updateScreenOffSleepToken(true /* acquire */, isSwappingDisplay);
+            if (!isSwappingDisplay || mIsGoingToSleepDefaultDisplay) {
+                updateScreenOffSleepToken(true /* acquire */);
             }
             mRequestedOrSleepingDefaultDisplay = false;
             mDefaultDisplayPolicy.screenTurnedOff();
@@ -5712,7 +5702,7 @@
         if (displayId == DEFAULT_DISPLAY) {
             Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "screenTurningOn",
                     0 /* cookie */);
-            updateScreenOffSleepToken(false /* acquire */, false /* isSwappingDisplay */);
+            updateScreenOffSleepToken(false /* acquire */);
             mDefaultDisplayPolicy.screenTurningOn(screenOnListener);
             mBootAnimationDismissable = false;
 
@@ -6218,9 +6208,9 @@
     }
 
     // TODO (multidisplay): Support multiple displays in WindowManagerPolicy.
-    private void updateScreenOffSleepToken(boolean acquire, boolean isSwappingDisplay) {
+    private void updateScreenOffSleepToken(boolean acquire) {
         if (acquire) {
-            mScreenOffSleepTokenAcquirer.acquire(DEFAULT_DISPLAY, isSwappingDisplay);
+            mScreenOffSleepTokenAcquirer.acquire(DEFAULT_DISPLAY);
         } else {
             mScreenOffSleepTokenAcquirer.release(DEFAULT_DISPLAY);
         }
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 11b9e77..f85b8cc 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -17,6 +17,7 @@
 package com.android.server.power;
 
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
 import android.annotation.UserIdInt;
 import android.app.ActivityManagerInternal;
 import android.app.AppOpsManager;
@@ -197,9 +198,10 @@
             FaceDownDetector faceDownDetector, ScreenUndimDetector screenUndimDetector,
             Executor backgroundExecutor, PowerManagerFlags powerManagerFlags, Injector injector) {
         mContext = context;
+        mInjector = (injector == null) ? new RealInjector() : injector;
         mFlags = powerManagerFlags;
         mBatteryStats = batteryStats;
-        mAppOps = mContext.getSystemService(AppOpsManager.class);
+        mAppOps = mInjector.getAppOpsManager(context);
         mSuspendBlocker = suspendBlocker;
         mPolicy = policy;
         mFaceDownDetector = faceDownDetector;
@@ -230,7 +232,6 @@
         mShowWirelessChargingAnimationConfig = context.getResources().getBoolean(
                 com.android.internal.R.bool.config_showBuiltinWirelessChargingAnim);
 
-        mInjector = (injector == null) ? new RealInjector() : injector;
         mWakeLockLog = mInjector.getWakeLockLog(context);
         // Initialize interactive state for battery stats.
         try {
@@ -264,6 +265,7 @@
     /**
      * Called when a wake lock is acquired.
      */
+    @SuppressLint("AndroidFrameworkRequiresPermission")
     public void onWakeLockAcquired(int flags, String tag, String packageName,
             int ownerUid, int ownerPid, WorkSource workSource, String historyTag,
             IWakeLockCallback callback) {
@@ -273,27 +275,28 @@
                     + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
                     + ", workSource=" + workSource);
         }
-        notifyWakeLockListener(callback, tag, true, ownerUid, flags);
-        final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
-        if (monitorType >= 0) {
-            try {
-                final boolean unimportantForLogging = ownerUid == Process.SYSTEM_UID
-                        && (flags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
-                if (workSource != null) {
-                    mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag,
-                            historyTag, monitorType, unimportantForLogging);
-                } else {
-                    mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag,
-                            monitorType, unimportantForLogging);
-                    // XXX need to deal with disabled operations.
-                    mAppOps.startOpNoThrow(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
-                }
-            } catch (RemoteException ex) {
-                // Ignore
-            }
-        }
-
+        notifyWakeLockListener(callback, tag, true, ownerUid, ownerPid, flags, workSource,
+                packageName, historyTag);
         if (!mFlags.improveWakelockLatency()) {
+            final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+            if (monitorType >= 0) {
+                try {
+                    final boolean unimportantForLogging = ownerUid == Process.SYSTEM_UID
+                            && (flags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
+                    if (workSource != null) {
+                        mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag,
+                                historyTag, monitorType, unimportantForLogging);
+                    } else {
+                        mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag,
+                                monitorType, unimportantForLogging);
+                        // XXX need to deal with disabled operations.
+                        mAppOps.startOpNoThrow(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName,
+                                false, null, null);
+                    }
+                } catch (RemoteException ex) {
+                    // Ignore
+                }
+            }
             mWakeLockLog.onWakeLockAcquired(tag, ownerUid, flags, /*eventTime=*/ -1);
         }
         mWakefulnessSessionObserver.onWakeLockAcquired(flags);
@@ -404,6 +407,7 @@
     /**
      * Called when a wake lock is released.
      */
+    @SuppressLint("AndroidFrameworkRequiresPermission")
     public void onWakeLockReleased(int flags, String tag, String packageName,
             int ownerUid, int ownerPid, WorkSource workSource, String historyTag,
             IWakeLockCallback callback, int releaseReason) {
@@ -413,23 +417,24 @@
                     + ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
                     + ", workSource=" + workSource);
         }
-        notifyWakeLockListener(callback, tag, false, ownerUid, flags);
-        final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
-        if (monitorType >= 0) {
-            try {
-                if (workSource != null) {
-                    mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag,
-                            historyTag, monitorType);
-                } else {
-                    mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag,
-                            historyTag, monitorType);
-                    mAppOps.finishOp(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
-                }
-            } catch (RemoteException ex) {
-                // Ignore
-            }
-        }
+        notifyWakeLockListener(callback, tag, false, ownerUid, ownerPid, flags, workSource,
+                packageName, historyTag);
         if (!mFlags.improveWakelockLatency()) {
+            final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+            if (monitorType >= 0) {
+                try {
+                    if (workSource != null) {
+                        mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag,
+                                historyTag, monitorType);
+                    } else {
+                        mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag,
+                                historyTag, monitorType);
+                        mAppOps.finishOp(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName, null);
+                    }
+                } catch (RemoteException ex) {
+                    // Ignore
+                }
+            }
             mWakeLockLog.onWakeLockReleased(tag, ownerUid, /*eventTime=*/ -1);
         }
         mWakefulnessSessionObserver.onWakeLockReleased(flags, releaseReason);
@@ -1049,24 +1054,75 @@
     }
 
     private void notifyWakeLockListener(IWakeLockCallback callback, String tag, boolean isEnabled,
-            int ownerUid, int flags) {
-        if (callback != null) {
-            long currentTime = mInjector.currentTimeMillis();
-            mHandler.post(() -> {
+            int ownerUid, int ownerPid, int flags, WorkSource workSource, String packageName,
+            String historyTag) {
+        mHandler.post(() -> {
+            if (mFlags.improveWakelockLatency()) {
+                long currentTime = mInjector.currentTimeMillis();
+                if (isEnabled) {
+                    notifyWakelockAcquisition(tag, ownerUid, ownerPid, flags,
+                            workSource, packageName, historyTag, currentTime);
+                } else {
+                    notifyWakelockRelease(tag, ownerUid, ownerPid, flags,
+                            workSource, packageName, historyTag, currentTime);
+                }
+            }
+
+            if (callback != null) {
                 try {
-                    if (mFlags.improveWakelockLatency()) {
-                        if (isEnabled) {
-                            mWakeLockLog.onWakeLockAcquired(tag, ownerUid, flags, currentTime);
-                        } else {
-                            mWakeLockLog.onWakeLockReleased(tag, ownerUid, currentTime);
-                        }
-                    }
                     callback.onStateChanged(isEnabled);
                 } catch (RemoteException e) {
                     Slog.e(TAG, "Wakelock.mCallback [" + tag + "] is already dead.", e);
                 }
-            });
+            }
+        });
+    }
+
+    @SuppressLint("AndroidFrameworkRequiresPermission")
+    private void notifyWakelockAcquisition(String tag, int ownerUid, int ownerPid, int flags,
+            WorkSource workSource, String packageName, String historyTag, long currentTime) {
+        final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+        if (monitorType >= 0) {
+            try {
+                final boolean unimportantForLogging = ownerUid == Process.SYSTEM_UID
+                        && (flags & PowerManager.UNIMPORTANT_FOR_LOGGING) != 0;
+                if (workSource != null) {
+                    mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag,
+                            historyTag, monitorType, unimportantForLogging);
+                } else {
+                    mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag,
+                            monitorType, unimportantForLogging);
+                    // XXX need to deal with disabled operations.
+                    mAppOps.startOpNoThrow(
+                            AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName,
+                            false, null, null);
+                }
+            } catch (RemoteException ex) {
+                // Do Nothing
+            }
         }
+        mWakeLockLog.onWakeLockAcquired(tag, ownerUid, flags, currentTime);
+    }
+
+    @SuppressLint("AndroidFrameworkRequiresPermission")
+    private void notifyWakelockRelease(String tag, int ownerUid, int ownerPid, int flags,
+            WorkSource workSource, String packageName, String historyTag, long currentTime) {
+        final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+        if (monitorType >= 0) {
+            try {
+                if (workSource != null) {
+                    mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag,
+                            historyTag, monitorType);
+                } else {
+                    mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag,
+                            historyTag, monitorType);
+                    mAppOps.finishOp(AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName, null);
+                }
+            } catch (RemoteException ex) {
+                // Ignore
+            }
+        }
+        mWakeLockLog.onWakeLockReleased(tag, ownerUid, currentTime);
     }
 
     private final class NotifierHandler extends Handler {
@@ -1114,6 +1170,11 @@
          * Gets the WakeLockLog object
          */
         WakeLockLog getWakeLockLog(Context context);
+
+        /**
+         * Gets the AppOpsManager system service
+         */
+        AppOpsManager getAppOpsManager(Context context);
     }
 
     static class RealInjector implements Injector {
@@ -1126,5 +1187,10 @@
         public WakeLockLog getWakeLockLog(Context context) {
             return new WakeLockLog(context);
         }
+
+        @Override
+        public AppOpsManager getAppOpsManager(Context context) {
+            return context.getSystemService(AppOpsManager.class);
+        }
     }
 }
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index 6b7f2fa..4b4e442 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -48,6 +48,7 @@
 import android.os.VibrationEffect;
 import android.os.Vibrator;
 import android.os.vibrator.persistence.VibrationXmlParser;
+import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -743,6 +744,11 @@
      */
     @VisibleForTesting // For testing vibrations without shutting down device
     void playShutdownVibration(Context context) {
+        if (mInjector.isShutdownVibrationDisabled(context)) {
+            Log.i(TAG, "Vibration disabled in config");
+            return;
+        }
+
         Vibrator vibrator = mInjector.getVibrator(context);
         if (!vibrator.hasVibrator()) {
             return;
@@ -920,5 +926,14 @@
             return context.getResources().getString(
                     com.android.internal.R.string.config_defaultShutdownVibrationFile);
         }
+
+        public boolean isShutdownVibrationDisabled(Context context) {
+            boolean disabledInConfig = context.getResources().getBoolean(
+                    com.android.internal.R.bool.config_disableShutdownVibrationInZen);
+            boolean isZenMode = Settings.Global.getInt(context.getContentResolver(),
+                    Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF)
+                    != Settings.Global.ZEN_MODE_OFF;
+            return disabledInConfig && isZenMode;
+        }
     }
 }
diff --git a/services/core/java/com/android/server/power/feature/PowerManagerFlags.java b/services/core/java/com/android/server/power/feature/PowerManagerFlags.java
index ff1d2e4..c6ef89d 100644
--- a/services/core/java/com/android/server/power/feature/PowerManagerFlags.java
+++ b/services/core/java/com/android/server/power/feature/PowerManagerFlags.java
@@ -16,6 +16,8 @@
 
 package com.android.server.power.feature;
 
+import android.os.Build;
+import android.os.SystemProperties;
 import android.text.TextUtils;
 import android.util.Slog;
 
@@ -82,7 +84,7 @@
                 }
                 return mEnabled;
             }
-            mEnabled = mFlagFunction.get();
+            mEnabled = flagOrSystemProperty(mFlagFunction, mName);
             if (DEBUG) {
                 Slog.d(TAG, mName + ": mEnabled. Flag value = " + mEnabled);
             }
@@ -90,6 +92,15 @@
             return mEnabled;
         }
 
+        private boolean flagOrSystemProperty(Supplier<Boolean> flagFunction, String flagName) {
+            boolean flagValue = flagFunction.get();
+            if (Build.IS_ENG || Build.IS_USERDEBUG) {
+                return SystemProperties.getBoolean("persist.sys." + flagName + "-override",
+                        flagValue);
+            }
+            return flagValue;
+        }
+
         @Override
         public String toString() {
             // remove com.android.server.power.feature.flags. from the beginning of the name.
diff --git a/services/core/java/com/android/server/power/stats/AggregatedPowerStats.java b/services/core/java/com/android/server/power/stats/AggregatedPowerStats.java
index fbdba4f..e27f3b2 100644
--- a/services/core/java/com/android/server/power/stats/AggregatedPowerStats.java
+++ b/services/core/java/com/android/server/power/stats/AggregatedPowerStats.java
@@ -19,16 +19,20 @@
 import android.annotation.CurrentTimeMillisLong;
 import android.annotation.DurationMillisLong;
 import android.annotation.NonNull;
+import android.os.BatteryConsumer;
 import android.os.BatteryStats;
+import android.os.PersistableBundle;
 import android.os.UserHandle;
 import android.text.format.DateFormat;
 import android.util.IndentingPrintWriter;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.util.TimeUtils;
 
 import com.android.internal.os.PowerStats;
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
+import com.android.server.power.stats.AggregatedPowerStatsConfig.PowerComponent;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -53,11 +57,14 @@
     private static final int MAX_CLOCK_UPDATES = 100;
     private static final String XML_TAG_AGGREGATED_POWER_STATS = "agg-power-stats";
 
-    private final PowerComponentAggregatedPowerStats[] mPowerComponentStats;
+    private final AggregatedPowerStatsConfig mConfig;
+    private final SparseArray<PowerComponentAggregatedPowerStats> mPowerComponentStats;
+    private final PowerComponentAggregatedPowerStats mGenericPowerComponent;
 
     static class ClockUpdate {
         public long monotonicTime;
-        @CurrentTimeMillisLong public long currentTime;
+        @CurrentTimeMillisLong
+        public long currentTime;
     }
 
     private final List<ClockUpdate> mClockUpdates = new ArrayList<>();
@@ -65,13 +72,35 @@
     @DurationMillisLong
     private long mDurationMs;
 
-    AggregatedPowerStats(AggregatedPowerStatsConfig aggregatedPowerStatsConfig) {
-        List<AggregatedPowerStatsConfig.PowerComponent> configs =
+    AggregatedPowerStats(@NonNull AggregatedPowerStatsConfig aggregatedPowerStatsConfig) {
+        mConfig = aggregatedPowerStatsConfig;
+        List<PowerComponent> configs =
                 aggregatedPowerStatsConfig.getPowerComponentsAggregatedStatsConfigs();
-        mPowerComponentStats = new PowerComponentAggregatedPowerStats[configs.size()];
+        mPowerComponentStats = new SparseArray<>(configs.size());
         for (int i = 0; i < configs.size(); i++) {
-            mPowerComponentStats[i] = new PowerComponentAggregatedPowerStats(this, configs.get(i));
+            PowerComponent powerComponent = configs.get(i);
+            mPowerComponentStats.put(powerComponent.getPowerComponentId(),
+                    new PowerComponentAggregatedPowerStats(this, powerComponent));
         }
+        mGenericPowerComponent = createGenericPowerComponent();
+        mPowerComponentStats.put(BatteryConsumer.POWER_COMPONENT_ANY, mGenericPowerComponent);
+    }
+
+    private PowerComponentAggregatedPowerStats createGenericPowerComponent() {
+        PowerComponent config = new PowerComponent(BatteryConsumer.POWER_COMPONENT_ANY);
+        config.trackDeviceStates(
+                        AggregatedPowerStatsConfig.STATE_POWER,
+                        AggregatedPowerStatsConfig.STATE_SCREEN)
+                .trackUidStates(
+                        AggregatedPowerStatsConfig.STATE_POWER,
+                        AggregatedPowerStatsConfig.STATE_SCREEN,
+                        AggregatedPowerStatsConfig.STATE_PROCESS_STATE);
+        PowerComponentAggregatedPowerStats stats =
+                new PowerComponentAggregatedPowerStats(this, config);
+        stats.setPowerStatsDescriptor(
+                new PowerStats.Descriptor(BatteryConsumer.POWER_COMPONENT_ANY, 0, null, 0, 0,
+                        new PersistableBundle()));
+        return stats;
     }
 
     /**
@@ -79,7 +108,7 @@
      * there may be multiple clock updates in one set of aggregated stats.
      *
      * @param monotonicTime monotonic time in milliseconds, see
-     * {@link com.android.internal.os.MonotonicClock}
+     *                      {@link com.android.internal.os.MonotonicClock}
      * @param currentTime   current time in milliseconds, see {@link System#currentTimeMillis()}
      */
     void addClockUpdate(long monotonicTime, @CurrentTimeMillisLong long currentTime) {
@@ -90,7 +119,7 @@
             mClockUpdates.add(clockUpdate);
         } else {
             Slog.i(TAG, "Too many clock updates. Replacing the previous update with "
-                        + DateFormat.format("yyyy-MM-dd-HH-mm-ss", currentTime));
+                    + DateFormat.format("yyyy-MM-dd-HH-mm-ss", currentTime));
             mClockUpdates.set(mClockUpdates.size() - 1, clockUpdate);
         }
     }
@@ -119,66 +148,97 @@
         return mDurationMs;
     }
 
-    PowerComponentAggregatedPowerStats getPowerComponentStats(int powerComponentId) {
-        for (PowerComponentAggregatedPowerStats stats : mPowerComponentStats) {
-            if (stats.powerComponentId == powerComponentId) {
-                return stats;
+    List<PowerComponentAggregatedPowerStats> getPowerComponentStats() {
+        List<PowerComponentAggregatedPowerStats> list = new ArrayList<>(
+                mPowerComponentStats.size());
+        for (int i = 0; i < mPowerComponentStats.size(); i++) {
+            PowerComponentAggregatedPowerStats stats = mPowerComponentStats.valueAt(i);
+            if (stats != mGenericPowerComponent) {
+                list.add(stats);
             }
         }
-        return null;
+        return list;
+    }
+
+    PowerComponentAggregatedPowerStats getPowerComponentStats(int powerComponentId) {
+        return mPowerComponentStats.get(powerComponentId);
+    }
+
+    void start(long timestampMs) {
+        for (int i = 0; i < mPowerComponentStats.size(); i++) {
+            PowerComponentAggregatedPowerStats component = mPowerComponentStats.valueAt(i);
+            component.getConfig().getProcessor().start(component, timestampMs);
+        }
     }
 
     void setDeviceState(@AggregatedPowerStatsConfig.TrackedState int stateId, int state,
             long time) {
-        for (PowerComponentAggregatedPowerStats stats : mPowerComponentStats) {
-            stats.setState(stateId, state, time);
+        for (int i = 0; i < mPowerComponentStats.size(); i++) {
+            mPowerComponentStats.valueAt(i).setState(stateId, state, time);
         }
     }
 
     void setUidState(int uid, @AggregatedPowerStatsConfig.TrackedState int stateId, int state,
             long time) {
-        for (PowerComponentAggregatedPowerStats stats : mPowerComponentStats) {
-            stats.setUidState(uid, stateId, state, time);
+        for (int i = 0; i < mPowerComponentStats.size(); i++) {
+            mPowerComponentStats.valueAt(i).setUidState(uid, stateId, state, time);
         }
     }
 
     boolean isCompatible(PowerStats powerStats) {
         int powerComponentId = powerStats.descriptor.powerComponentId;
-        for (PowerComponentAggregatedPowerStats stats : mPowerComponentStats) {
-            if (stats.powerComponentId == powerComponentId && !stats.isCompatible(powerStats)) {
-                return false;
-            }
-        }
-        return true;
+        PowerComponentAggregatedPowerStats stats = mPowerComponentStats.get(powerComponentId);
+        return stats != null && stats.isCompatible(powerStats);
     }
 
     void addPowerStats(PowerStats powerStats, long time) {
         int powerComponentId = powerStats.descriptor.powerComponentId;
-        for (PowerComponentAggregatedPowerStats stats : mPowerComponentStats) {
-            if (stats.powerComponentId == powerComponentId) {
-                stats.getConfig().getProcessor().addPowerStats(stats, powerStats, time);
+        PowerComponentAggregatedPowerStats stats = mPowerComponentStats.get(powerComponentId);
+        if (stats == null) {
+            PowerComponent powerComponent = mConfig.createPowerComponent(powerComponentId);
+            if (powerComponent == null) {
+                return;
             }
+
+            stats = new PowerComponentAggregatedPowerStats(this, powerComponent);
+            stats.setPowerStatsDescriptor(powerStats.descriptor);
+            stats.copyStatesFrom(mGenericPowerComponent);
+            mPowerComponentStats.put(powerComponentId, stats);
         }
+
+        PowerStatsProcessor processor = stats.getConfig().getProcessor();
+        processor.addPowerStats(stats, powerStats, time);
     }
 
     public void noteStateChange(BatteryStats.HistoryItem item) {
-        for (PowerComponentAggregatedPowerStats stats : mPowerComponentStats) {
+        for (int i = 0; i < mPowerComponentStats.size(); i++) {
+            PowerComponentAggregatedPowerStats stats = mPowerComponentStats.valueAt(i);
             stats.getConfig().getProcessor().noteStateChange(stats, item);
         }
     }
 
+    void finish(long timestampMs) {
+        for (int i = 0; i < mPowerComponentStats.size(); i++) {
+            PowerComponentAggregatedPowerStats component = mPowerComponentStats.valueAt(i);
+            component.getConfig().getProcessor().finish(component, timestampMs);
+        }
+    }
+
     void reset() {
         mClockUpdates.clear();
         mDurationMs = 0;
-        for (PowerComponentAggregatedPowerStats stats : mPowerComponentStats) {
-            stats.reset();
+        for (int i = 0; i < mPowerComponentStats.size(); i++) {
+            mPowerComponentStats.valueAt(i).reset();
         }
     }
 
     public void writeXml(TypedXmlSerializer serializer) throws IOException {
         serializer.startTag(null, XML_TAG_AGGREGATED_POWER_STATS);
-        for (PowerComponentAggregatedPowerStats stats : mPowerComponentStats) {
-            stats.writeXml(serializer);
+        for (int i = 0; i < mPowerComponentStats.size(); i++) {
+            PowerComponentAggregatedPowerStats stats = mPowerComponentStats.valueAt(i);
+            if (stats != mGenericPowerComponent) {
+                stats.writeXml(serializer);
+            }
         }
         serializer.endTag(null, XML_TAG_AGGREGATED_POWER_STATS);
         serializer.flush();
@@ -200,23 +260,34 @@
                     case XML_TAG_AGGREGATED_POWER_STATS:
                         inElement = true;
                         break;
-                    case PowerComponentAggregatedPowerStats.XML_TAG_POWER_COMPONENT:
+                    case PowerComponentAggregatedPowerStats.XML_TAG_POWER_COMPONENT: {
                         if (!inElement) {
                             break;
                         }
 
                         int powerComponentId = parser.getAttributeInt(null,
                                 PowerComponentAggregatedPowerStats.XML_ATTR_ID);
-                        for (PowerComponentAggregatedPowerStats powerComponent :
-                                stats.mPowerComponentStats) {
-                            if (powerComponent.powerComponentId == powerComponentId) {
-                                if (!powerComponent.readFromXml(parser)) {
-                                    skipToEnd = true;
-                                }
-                                break;
+
+                        PowerComponentAggregatedPowerStats powerComponentStats =
+                                stats.getPowerComponentStats(powerComponentId);
+                        if (powerComponentStats == null) {
+                            PowerComponent powerComponent =
+                                    aggregatedPowerStatsConfig.createPowerComponent(
+                                            powerComponentId);
+                            if (powerComponent != null) {
+                                powerComponentStats = new PowerComponentAggregatedPowerStats(stats,
+                                        powerComponent);
+                                stats.mPowerComponentStats.put(powerComponentId,
+                                        powerComponentStats);
+                            }
+                        }
+                        if (powerComponentStats != null) {
+                            if (!powerComponentStats.readFromXml(parser)) {
+                                skipToEnd = true;
                             }
                         }
                         break;
+                    }
                 }
             }
             eventType = parser.next();
@@ -254,14 +325,14 @@
 
         ipw.println("Device");
         ipw.increaseIndent();
-        for (PowerComponentAggregatedPowerStats stats : mPowerComponentStats) {
-            stats.dumpDevice(ipw);
+        for (int i = 0; i < mPowerComponentStats.size(); i++) {
+            mPowerComponentStats.valueAt(i).dumpDevice(ipw);
         }
         ipw.decreaseIndent();
 
         Set<Integer> uids = new HashSet<>();
-        for (PowerComponentAggregatedPowerStats stats : mPowerComponentStats) {
-            stats.collectUids(uids);
+        for (int i = 0; i < mPowerComponentStats.size(); i++) {
+            mPowerComponentStats.valueAt(i).collectUids(uids);
         }
 
         Integer[] allUids = uids.toArray(new Integer[uids.size()]);
@@ -269,8 +340,8 @@
         for (int uid : allUids) {
             ipw.println(UserHandle.formatUid(uid));
             ipw.increaseIndent();
-            for (PowerComponentAggregatedPowerStats stats : mPowerComponentStats) {
-                stats.dumpUid(ipw, uid);
+            for (int i = 0; i < mPowerComponentStats.size(); i++) {
+                mPowerComponentStats.valueAt(i).dumpUid(ipw, uid);
             }
             ipw.decreaseIndent();
         }
diff --git a/services/core/java/com/android/server/power/stats/AggregatedPowerStatsConfig.java b/services/core/java/com/android/server/power/stats/AggregatedPowerStatsConfig.java
index 1ff7cb7..1f4a391 100644
--- a/services/core/java/com/android/server/power/stats/AggregatedPowerStatsConfig.java
+++ b/services/core/java/com/android/server/power/stats/AggregatedPowerStatsConfig.java
@@ -17,12 +17,14 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.os.BatteryConsumer;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.function.Supplier;
 
 /**
  * Configuration that controls how power stats are aggregated.  It determines which state changes
@@ -140,7 +142,7 @@
         }
 
         @NonNull
-        public PowerStatsProcessor getProcessor() {
+        PowerStatsProcessor getProcessor() {
             return mProcessor;
         }
 
@@ -160,6 +162,8 @@
     }
 
     private final List<PowerComponent> mPowerComponents = new ArrayList<>();
+    private PowerComponent mCustomPowerComponent;
+    private Supplier<PowerStatsProcessor> mCustomPowerStatsProcessorFactory;
 
     /**
      * Creates a configuration for the specified power component, which may be one of the
@@ -199,10 +203,45 @@
         return powerComponent;
     }
 
+    /**
+     * Creates a configuration for custom power components, which are yet to be discovered
+     * dynamically through the integration with PowerStatsService.
+     */
+    public PowerComponent trackCustomPowerComponents(
+            Supplier<PowerStatsProcessor> processorFactory) {
+        mCustomPowerStatsProcessorFactory = processorFactory;
+        mCustomPowerComponent = new PowerComponent(BatteryConsumer.POWER_COMPONENT_ANY);
+        return mCustomPowerComponent;
+    }
+
+    /**
+     * Returns configurations for all registered or dynamically discovered power components.
+     */
     public List<PowerComponent> getPowerComponentsAggregatedStatsConfigs() {
         return mPowerComponents;
     }
 
+    /**
+     * Creates a configuration for a custom power component discovered dynamically through the
+     * integration with PowerStatsService.
+     */
+    @Nullable
+    public PowerComponent createPowerComponent(int powerComponentId) {
+        if (mCustomPowerComponent == null) {
+            return null;
+        }
+
+        PowerComponent powerComponent = new PowerComponent(powerComponentId);
+        powerComponent.trackDeviceStates(mCustomPowerComponent.mTrackedDeviceStates);
+        powerComponent.trackUidStates(mCustomPowerComponent.mTrackedUidStates);
+
+        if (mCustomPowerStatsProcessorFactory != null) {
+            powerComponent.setProcessor(mCustomPowerStatsProcessorFactory.get());
+        }
+
+        return powerComponent;
+    }
+
     private static final PowerStatsProcessor NO_OP_PROCESSOR = new PowerStatsProcessor() {
         @Override
         void finish(PowerComponentAggregatedPowerStats stats, long timestampMs) {
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 322ed86..1b7bf89 100644
--- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
+++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
@@ -28,6 +28,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
 import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.app.usage.NetworkStatsManager;
@@ -300,6 +301,7 @@
     private final BluetoothPowerStatsCollector mBluetoothPowerStatsCollector;
     private final CameraPowerStatsCollector mCameraPowerStatsCollector;
     private final GnssPowerStatsCollector mGnssPowerStatsCollector;
+    private final CustomEnergyConsumerPowerStatsCollector mCustomEnergyConsumerPowerStatsCollector;
     private final SparseBooleanArray mPowerStatsCollectorEnabled = new SparseBooleanArray();
     private final WifiPowerStatsCollector.WifiStatsRetriever mWifiStatsRetriever =
             new WifiPowerStatsCollector.WifiStatsRetriever() {
@@ -1973,13 +1975,15 @@
         private WifiManager mWifiManager;
         private BluetoothPowerStatsCollector.BluetoothStatsRetriever mBluetoothStatsRetriever;
 
+        @SuppressLint("WifiManagerPotentialLeak")
         void setContext(Context context) {
             mPackageManager = context.getPackageManager();
             mConsumedEnergyRetriever = new PowerStatsCollector.ConsumedEnergyRetrieverImpl(
                     LocalServices.getService(PowerStatsInternal.class));
             mNetworkStatsManager = context.getSystemService(NetworkStatsManager.class);
-            mTelephonyManager = context.getSystemService(TelephonyManager.class);
-            mWifiManager = context.getSystemService(WifiManager.class);
+            mTelephonyManager =
+                    (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+            mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
             mBluetoothStatsRetriever = new BluetoothStatsRetrieverImpl(
                     context.getSystemService(BluetoothManager.class));
         }
@@ -11287,10 +11291,11 @@
         mCpuPowerStatsCollector.addConsumer(this::recordPowerStats);
 
         mMobileRadioPowerStatsCollector = new MobileRadioPowerStatsCollector(
-                mPowerStatsCollectorInjector);
+                mPowerStatsCollectorInjector, this::onMobileRadioPowerStatsRetrieved);
         mMobileRadioPowerStatsCollector.addConsumer(this::recordPowerStats);
 
-        mWifiPowerStatsCollector = new WifiPowerStatsCollector(mPowerStatsCollectorInjector);
+        mWifiPowerStatsCollector = new WifiPowerStatsCollector(mPowerStatsCollectorInjector,
+                this::onWifiPowerStatsRetrieved);
         mWifiPowerStatsCollector.addConsumer(this::recordPowerStats);
 
         mBluetoothPowerStatsCollector = new BluetoothPowerStatsCollector(
@@ -11303,6 +11308,10 @@
         mGnssPowerStatsCollector = new GnssPowerStatsCollector(mPowerStatsCollectorInjector);
         mGnssPowerStatsCollector.addConsumer(this::recordPowerStats);
 
+        mCustomEnergyConsumerPowerStatsCollector =
+                new CustomEnergyConsumerPowerStatsCollector(mPowerStatsCollectorInjector);
+        mCustomEnergyConsumerPowerStatsCollector.addConsumer(this::recordPowerStats);
+
         mStartCount++;
         initTimersAndCounters();
         mOnBattery = mOnBatteryInternal = false;
@@ -12315,16 +12324,13 @@
 
     /**
      * Distribute WiFi energy info and network traffic to apps.
+     *
      * @param info The energy information from the WiFi controller.
      */
     @GuardedBy("this")
     public void updateWifiState(@Nullable final WifiActivityEnergyInfo info,
             final long consumedChargeUC, long elapsedRealtimeMs, long uptimeMs,
             @NonNull NetworkStatsManager networkStatsManager) {
-        if (mWifiPowerStatsCollector.isEnabled()) {
-            return;
-        }
-
         if (DEBUG_ENERGY) {
             synchronized (mWifiNetworkLock) {
                 Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces));
@@ -12342,7 +12348,20 @@
                 delta = null;
             }
         }
+        updateWifiBatteryStats(info, delta, consumedChargeUC, elapsedRealtimeMs, uptimeMs);
+    }
 
+    private void onWifiPowerStatsRetrieved(WifiActivityEnergyInfo wifiActivityEnergyInfo,
+            List<NetworkStatsDelta> networkStatsDeltas, long elapsedRealtimeMs, long uptimeMs) {
+        // Do not populate consumed energy, because energy attribution is done by
+        // WifiPowerStatsProcessor.
+        updateWifiBatteryStats(wifiActivityEnergyInfo, networkStatsDeltas, POWER_DATA_UNAVAILABLE,
+                elapsedRealtimeMs, uptimeMs);
+    }
+
+    private void updateWifiBatteryStats(WifiActivityEnergyInfo info,
+            List<NetworkStatsDelta> delta, long consumedChargeUC, long elapsedRealtimeMs,
+            long uptimeMs) {
         synchronized (this) {
             if (!mOnBatteryInternal || mIgnoreNextExternalStats) {
                 if (mIgnoreNextExternalStats) {
@@ -12706,9 +12725,6 @@
                 : mLastModemActivityInfo.getDelta(activityInfo);
         mLastModemActivityInfo = activityInfo;
 
-        // Add modem tx power to history.
-        addModemTxPowerToHistory(deltaInfo, elapsedRealtimeMs, uptimeMs);
-
         // Grab a separate lock to acquire the network stats, which may do I/O.
         List<NetworkStatsDelta> delta = null;
         synchronized (mModemNetworkLock) {
@@ -12719,6 +12735,23 @@
             }
         }
 
+        updateCellularBatteryStats(deltaInfo, delta, consumedChargeUC, elapsedRealtimeMs, uptimeMs);
+    }
+
+    private void onMobileRadioPowerStatsRetrieved(ModemActivityInfo modemActivityInfo,
+            List<NetworkStatsDelta> networkStatsDeltas, long elapsedRealtimeMs, long uptimeMs) {
+        // Do not populate consumed energy, because energy attribution is done by
+        // MobileRadioPowerStatsProcessor.
+        updateCellularBatteryStats(modemActivityInfo, networkStatsDeltas, POWER_DATA_UNAVAILABLE,
+                elapsedRealtimeMs, uptimeMs);
+    }
+
+    private void updateCellularBatteryStats(@Nullable ModemActivityInfo deltaInfo,
+            @Nullable List<NetworkStatsDelta> delta, long consumedChargeUC, long elapsedRealtimeMs,
+            long uptimeMs) {
+        // Add modem tx power to history.
+        addModemTxPowerToHistory(deltaInfo, elapsedRealtimeMs, uptimeMs);
+
         synchronized (this) {
             final long totalRadioDurationMs =
                     mMobileRadioActiveTimer.getTimeSinceMarkLocked(
@@ -13106,7 +13139,6 @@
 
                 final long rxTimeMs = deltaInfo.getReceiveTimeMillis(rat, freq);
                 final int[] txTimesMs = deltaInfo.getTransmitTimeMillis(rat, freq);
-
                 ratStats.incrementRxDuration(freq, rxTimeMs);
                 if (isMobileRadioEnergyConsumerSupportedLocked()) {
                     // Accumulate the power cost of time spent receiving in a particular state.
@@ -13922,6 +13954,11 @@
      * Read and record Rail Energy data.
      */
     public void updateRailStatsLocked() {
+        if (mCustomEnergyConsumerPowerStatsCollector.isEnabled()) {
+            mCustomEnergyConsumerPowerStatsCollector.schedule();
+            return;
+        }
+
         if (mEnergyConsumerRetriever == null || !mTmpRailStats.isRailStatsAvailable()) {
             return;
         }
@@ -14733,6 +14770,10 @@
                 mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_GNSS));
         mGnssPowerStatsCollector.schedule();
 
+        mCustomEnergyConsumerPowerStatsCollector.setEnabled(
+                mPowerStatsCollectorEnabled.get(BatteryConsumer.POWER_COMPONENT_ANY));
+        mCustomEnergyConsumerPowerStatsCollector.schedule();
+
         mSystemReady = true;
     }
 
@@ -15373,16 +15414,15 @@
     /*@hide */
     public WifiBatteryStats getWifiBatteryStats() {
         final int which = STATS_SINCE_CHARGED;
-        final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000;
+        final long rawRealTimeUs = mClock.elapsedRealtime() * 1000;
         final ControllerActivityCounter counter = getWifiControllerActivity();
         final long idleTimeMs = counter.getIdleTimeCounter().getCountLocked(which);
         final long scanTimeMs = counter.getScanTimeCounter().getCountLocked(which);
         final long rxTimeMs = counter.getRxTimeCounter().getCountLocked(which);
         final long txTimeMs = counter.getTxTimeCounters()[0].getCountLocked(which);
-        final long totalControllerActivityTimeMs
-                = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which) / 1000;
-        final long sleepTimeMs
-                = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + txTimeMs);
+        final long totalControllerActivityTimeMs =
+                computeBatteryRealtime(mClock.elapsedRealtime() * 1000, which) / 1000;
+        final long sleepTimeMs = totalControllerActivityTimeMs - (idleTimeMs + rxTimeMs + txTimeMs);
         final long energyConsumedMaMs = counter.getPowerCounter().getCountLocked(which);
         final long monitoredRailChargeConsumedMaMs =
                 counter.getMonitoredRailChargeConsumedMaMs().getCountLocked(which);
diff --git a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
index ce0ee39..8127b82 100644
--- a/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
+++ b/services/core/java/com/android/server/power/stats/BatteryUsageStatsProvider.java
@@ -113,7 +113,9 @@
                 mPowerCalculators.add(new ScreenPowerCalculator(mPowerProfile));
                 mPowerCalculators.add(new AmbientDisplayPowerCalculator(mPowerProfile));
                 mPowerCalculators.add(new IdlePowerCalculator(mPowerProfile));
-                mPowerCalculators.add(new CustomEnergyConsumerPowerCalculator(mPowerProfile));
+                if (!mPowerStatsExporterEnabled.get(BatteryConsumer.POWER_COMPONENT_ANY)) {
+                    mPowerCalculators.add(new CustomEnergyConsumerPowerCalculator(mPowerProfile));
+                }
                 mPowerCalculators.add(new UserPowerCalculator());
 
                 if (!com.android.server.power.optimization.Flags.disableSystemServicePowerAttr()) {
diff --git a/services/core/java/com/android/server/power/stats/BinaryStatePowerStatsLayout.java b/services/core/java/com/android/server/power/stats/BinaryStatePowerStatsLayout.java
index 64c3446..502337c 100644
--- a/services/core/java/com/android/server/power/stats/BinaryStatePowerStatsLayout.java
+++ b/services/core/java/com/android/server/power/stats/BinaryStatePowerStatsLayout.java
@@ -16,16 +16,9 @@
 
 package com.android.server.power.stats;
 
-class BinaryStatePowerStatsLayout extends PowerStatsLayout {
+class BinaryStatePowerStatsLayout extends EnergyConsumerPowerStatsLayout {
     BinaryStatePowerStatsLayout() {
         addDeviceSectionUsageDuration();
-        // Add a section for consumed energy, even if the specific device does not
-        // have support EnergyConsumers.  This is done to guarantee format compatibility between
-        // PowerStats created by a PowerStatsCollector and those produced by a PowerStatsProcessor.
-        addDeviceSectionEnergyConsumers(1);
-        addDeviceSectionPowerEstimate();
-
         addUidSectionUsageDuration();
-        addUidSectionPowerEstimate();
     }
 }
diff --git a/services/core/java/com/android/server/power/stats/CustomEnergyConsumerPowerStatsCollector.java b/services/core/java/com/android/server/power/stats/CustomEnergyConsumerPowerStatsCollector.java
new file mode 100644
index 0000000..1191901
--- /dev/null
+++ b/services/core/java/com/android/server/power/stats/CustomEnergyConsumerPowerStatsCollector.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power.stats;
+
+import android.hardware.power.stats.EnergyConsumerType;
+import android.os.BatteryConsumer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CustomEnergyConsumerPowerStatsCollector extends PowerStatsCollector {
+    private static final EnergyConsumerPowerStatsLayout sLayout =
+            new EnergyConsumerPowerStatsLayout();
+    private final EnergyConsumerPowerStatsCollector.Injector mInjector;
+    private List<EnergyConsumerPowerStatsCollector> mCollectors;
+
+    CustomEnergyConsumerPowerStatsCollector(EnergyConsumerPowerStatsCollector.Injector injector) {
+        super(injector.getHandler(), 0, injector.getUidResolver(), injector.getClock());
+        mInjector = injector;
+    }
+
+    protected void ensureInitialized() {
+        if (mCollectors != null) {
+            return;
+        }
+
+        ConsumedEnergyRetriever retriever = mInjector.getConsumedEnergyRetriever();
+        int[] energyConsumerIds = retriever.getEnergyConsumerIds(EnergyConsumerType.OTHER);
+        int powerComponentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID;
+        mCollectors = new ArrayList<>(energyConsumerIds.length);
+        for (int i = 0; i < energyConsumerIds.length; i++) {
+            String name = retriever.getEnergyConsumerName(energyConsumerIds[i]);
+            EnergyConsumerPowerStatsCollector collector = new EnergyConsumerPowerStatsCollector(
+                    mInjector, powerComponentId++, name, energyConsumerIds[i], sLayout);
+            collector.setEnabled(true);
+            collector.addConsumer(this::deliverStats);
+            mCollectors.add(collector);
+        }
+    }
+
+    @Override
+    public boolean schedule() {
+        if (!isEnabled()) {
+            return false;
+        }
+
+        ensureInitialized();
+        boolean success = false;
+        for (int i = 0; i < mCollectors.size(); i++) {
+            success |= mCollectors.get(i).schedule();
+        }
+        return success;
+    }
+}
diff --git a/services/core/java/com/android/server/power/stats/CustomEnergyConsumerPowerStatsProcessor.java b/services/core/java/com/android/server/power/stats/CustomEnergyConsumerPowerStatsProcessor.java
new file mode 100644
index 0000000..a86242a
--- /dev/null
+++ b/services/core/java/com/android/server/power/stats/CustomEnergyConsumerPowerStatsProcessor.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power.stats;
+
+import com.android.internal.os.PowerStats;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CustomEnergyConsumerPowerStatsProcessor extends PowerStatsProcessor {
+    private static final EnergyConsumerPowerStatsLayout sLayout =
+            new EnergyConsumerPowerStatsLayout();
+    private long[] mTmpDeviceStatsArray;
+    private long[] mTmpUidStatsArray;
+    private PowerEstimationPlan mPlan;
+
+    @Override
+    void finish(PowerComponentAggregatedPowerStats stats, long timestampMs) {
+        PowerStats.Descriptor descriptor = stats.getPowerStatsDescriptor();
+        mTmpDeviceStatsArray = new long[descriptor.statsArrayLength];
+        mTmpUidStatsArray = new long[descriptor.uidStatsArrayLength];
+        if (mPlan == null) {
+            mPlan = new PowerEstimationPlan(stats.getConfig());
+        }
+
+        computeDevicePowerEstimates(stats);
+
+        List<Integer> uids = new ArrayList<>();
+        stats.collectUids(uids);
+
+        if (!uids.isEmpty()) {
+            computeUidPowerEstimates(stats, uids);
+        }
+    }
+
+    private void computeDevicePowerEstimates(PowerComponentAggregatedPowerStats stats) {
+        for (int i = mPlan.deviceStateEstimations.size() - 1; i >= 0; i--) {
+            DeviceStateEstimation estimation = mPlan.deviceStateEstimations.get(i);
+            if (!stats.getDeviceStats(mTmpDeviceStatsArray, estimation.stateValues)) {
+                continue;
+            }
+
+            sLayout.setDevicePowerEstimate(mTmpDeviceStatsArray,
+                    uCtoMah(sLayout.getConsumedEnergy(mTmpDeviceStatsArray, 0)));
+            stats.setDeviceStats(estimation.stateValues, mTmpDeviceStatsArray);
+        }
+    }
+
+    private void computeUidPowerEstimates(PowerComponentAggregatedPowerStats stats,
+            List<Integer> uids) {
+        for (int i = mPlan.uidStateEstimates.size() - 1; i >= 0; i--) {
+            UidStateEstimate uidStateEstimate = mPlan.uidStateEstimates.get(i);
+            List<UidStateProportionalEstimate> proportionalEstimates =
+                    uidStateEstimate.proportionalEstimates;
+            for (int j = proportionalEstimates.size() - 1; j >= 0; j--) {
+                UidStateProportionalEstimate proportionalEstimate = proportionalEstimates.get(j);
+                for (int k = uids.size() - 1; k >= 0; k--) {
+                    int uid = uids.get(k);
+                    if (stats.getUidStats(mTmpUidStatsArray, uid,
+                            proportionalEstimate.stateValues)) {
+                        sLayout.setUidPowerEstimate(mTmpUidStatsArray,
+                                uCtoMah(sLayout.getUidConsumedEnergy(mTmpUidStatsArray, 0)));
+                        stats.setUidStats(uid, proportionalEstimate.stateValues, mTmpUidStatsArray);
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/power/stats/EnergyConsumerPowerStatsCollector.java b/services/core/java/com/android/server/power/stats/EnergyConsumerPowerStatsCollector.java
index 2021f85..cace941 100644
--- a/services/core/java/com/android/server/power/stats/EnergyConsumerPowerStatsCollector.java
+++ b/services/core/java/com/android/server/power/stats/EnergyConsumerPowerStatsCollector.java
@@ -16,10 +16,13 @@
 
 package com.android.server.power.stats;
 
+import android.hardware.power.stats.EnergyConsumerAttribution;
+import android.hardware.power.stats.EnergyConsumerResult;
 import android.hardware.power.stats.EnergyConsumerType;
 import android.os.Handler;
 import android.os.PersistableBundle;
 import android.util.Slog;
+import android.util.SparseLongArray;
 
 import com.android.internal.os.Clock;
 import com.android.internal.os.PowerStats;
@@ -27,9 +30,7 @@
 import java.util.function.IntSupplier;
 
 public class EnergyConsumerPowerStatsCollector extends PowerStatsCollector {
-    private static final String TAG = "CameraPowerStatsCollector";
-
-    private static final long CAMERA_ACTIVITY_REQUEST_TIMEOUT = 20000;
+    private static final String TAG = "EnergyConsumerPowerStatsCollector";
 
     private static final long ENERGY_UNSPECIFIED = -1;
 
@@ -48,21 +49,22 @@
     private final int mEnergyConsumerType;
     private final String mEnergyConsumerName;
 
-    private final BinaryStatePowerStatsLayout mLayout;
+    private final EnergyConsumerPowerStatsLayout mLayout;
     private boolean mIsInitialized;
 
     private PowerStats mPowerStats;
     private ConsumedEnergyRetriever mConsumedEnergyRetriever;
     private IntSupplier mVoltageSupplier;
-    private int[] mEnergyConsumerIds = new int[0];
+    private int[] mEnergyConsumerIds;
     private long mLastConsumedEnergyUws = ENERGY_UNSPECIFIED;
+    private SparseLongArray mLastConsumerEnergyPerUid = new SparseLongArray();
     private int mLastVoltageMv;
     private long mLastUpdateTimestamp;
     private boolean mFirstCollection = true;
 
     EnergyConsumerPowerStatsCollector(Injector injector, int powerComponentId,
             String powerComponentName, @EnergyConsumerType int energyConsumerType,
-            String energyConsumerName, BinaryStatePowerStatsLayout statsLayout) {
+            String energyConsumerName, EnergyConsumerPowerStatsLayout statsLayout) {
         super(injector.getHandler(),
                 injector.getPowerStatsCollectionThrottlePeriod(powerComponentName),
                 injector.getUidResolver(), injector.getClock());
@@ -74,6 +76,21 @@
         mLayout = statsLayout;
     }
 
+    EnergyConsumerPowerStatsCollector(Injector injector, int powerComponentId,
+            String powerComponentName, int energyConsumerId,
+            EnergyConsumerPowerStatsLayout statsLayout) {
+        super(injector.getHandler(),
+                injector.getPowerStatsCollectionThrottlePeriod(powerComponentName),
+                injector.getUidResolver(), injector.getClock());
+        mInjector = injector;
+        mPowerComponentId = powerComponentId;
+        mPowerComponentName = powerComponentName;
+        mEnergyConsumerIds = new int[]{energyConsumerId};
+        mEnergyConsumerType = EnergyConsumerType.OTHER;
+        mEnergyConsumerName = null;
+        mLayout = statsLayout;
+    }
+
     private boolean ensureInitialized() {
         if (mIsInitialized) {
             return true;
@@ -85,9 +102,10 @@
 
         mConsumedEnergyRetriever = mInjector.getConsumedEnergyRetriever();
         mVoltageSupplier = mInjector.getVoltageSupplier();
-        mEnergyConsumerIds = mConsumedEnergyRetriever.getEnergyConsumerIds(mEnergyConsumerType,
-                mEnergyConsumerName);
-
+        if (mEnergyConsumerIds == null) {
+            mEnergyConsumerIds = mConsumedEnergyRetriever.getEnergyConsumerIds(mEnergyConsumerType,
+                    mEnergyConsumerName);
+        }
         PersistableBundle extras = new PersistableBundle();
         mLayout.toExtras(extras);
         PowerStats.Descriptor powerStatsDescriptor = new PowerStats.Descriptor(
@@ -110,18 +128,23 @@
             return null;
         }
 
-        long consumedEnergy = 0;
         int voltageMv = mVoltageSupplier.getAsInt();
-        if (voltageMv <= 0) {
+        int averageVoltage = mLastVoltageMv != 0 ? (mLastVoltageMv + voltageMv) / 2 : voltageMv;
+        if (averageVoltage <= 0) {
             Slog.wtf(TAG, "Unexpected battery voltage (" + voltageMv
                     + " mV) when querying energy consumers");
-        } else {
-            long[] energyUws = mConsumedEnergyRetriever.getConsumedEnergyUws(mEnergyConsumerIds);
-            if (energyUws != null) {
-                for (int i = energyUws.length - 1; i >= 0; i--) {
-                    if (energyUws[i] != ENERGY_UNSPECIFIED) {
-                        consumedEnergy += energyUws[i];
-                    }
+            return null;
+        }
+
+        mLastVoltageMv = voltageMv;
+
+        EnergyConsumerResult[] energy =
+                    mConsumedEnergyRetriever.getConsumedEnergy(mEnergyConsumerIds);
+        long consumedEnergy = 0;
+        if (energy != null) {
+            for (int i = energy.length - 1; i >= 0; i--) {
+                if (energy[i].energyUWs != ENERGY_UNSPECIFIED) {
+                    consumedEnergy += energy[i].energyUWs;
                 }
             }
         }
@@ -138,13 +161,47 @@
             return null;
         }
 
-        int averageVoltage = mLastVoltageMv != 0 ? (mLastVoltageMv + voltageMv) / 2 : voltageMv;
-        mLastVoltageMv = voltageMv;
         mLayout.setConsumedEnergy(mPowerStats.stats, 0, uJtoUc(energyDelta, averageVoltage));
+
+        for (int i = mPowerStats.uidStats.size() - 1; i >= 0; i--) {
+            mLayout.setUidConsumedEnergy(mPowerStats.uidStats.valueAt(i), 0, 0);
+        }
+
+        if (energy != null) {
+            for (int i = energy.length - 1; i >= 0; i--) {
+                EnergyConsumerAttribution[] perUid = energy[i].attribution;
+                if (perUid == null) {
+                    continue;
+                }
+
+                for (EnergyConsumerAttribution attribution : perUid) {
+                    int uid = mUidResolver.mapUid(attribution.uid);
+                    long lastEnergy = mLastConsumerEnergyPerUid.get(uid);
+                    long deltaEnergy = attribution.energyUWs - lastEnergy;
+                    mLastConsumerEnergyPerUid.put(uid, attribution.energyUWs);
+                    if (deltaEnergy <= 0) {
+                        continue;
+                    }
+                    long[] uidStats = mPowerStats.uidStats.get(uid);
+                    if (uidStats == null) {
+                        uidStats = new long[mLayout.getUidStatsArrayLength()];
+                        mPowerStats.uidStats.put(uid, uidStats);
+                    }
+
+                    mLayout.setUidConsumedEnergy(uidStats, 0,
+                            mLayout.getUidConsumedEnergy(uidStats, 0) + deltaEnergy);
+                }
+            }
+        }
         long timestamp = mClock.elapsedRealtime();
         mPowerStats.durationMs = timestamp - mLastUpdateTimestamp;
         mLastUpdateTimestamp = timestamp;
         mFirstCollection = false;
         return mPowerStats;
     }
+
+    @Override
+    protected void onUidRemoved(int uid) {
+        mLastConsumerEnergyPerUid.delete(uid);
+    }
 }
diff --git a/services/core/java/com/android/server/power/stats/EnergyConsumerPowerStatsLayout.java b/services/core/java/com/android/server/power/stats/EnergyConsumerPowerStatsLayout.java
new file mode 100644
index 0000000..8430f56
--- /dev/null
+++ b/services/core/java/com/android/server/power/stats/EnergyConsumerPowerStatsLayout.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.power.stats;
+
+class EnergyConsumerPowerStatsLayout extends PowerStatsLayout {
+    EnergyConsumerPowerStatsLayout() {
+        // Add a section for consumed energy, even if the specific device does not
+        // have support EnergyConsumers.  This is done to guarantee format compatibility between
+        // PowerStats created by a PowerStatsCollector and those produced by a PowerStatsProcessor.
+        addDeviceSectionEnergyConsumers(1);
+        addDeviceSectionPowerEstimate();
+
+        // Allocate a cell for per-UID consumed energy attribution. We won't know whether the
+        // corresponding energy consumer does per-UID attribution until we get data from
+        // PowerStatsService.
+        addUidSectionEnergyConsumers(1);
+        addUidSectionPowerEstimate();
+    }
+}
diff --git a/services/core/java/com/android/server/power/stats/MobileRadioPowerStatsCollector.java b/services/core/java/com/android/server/power/stats/MobileRadioPowerStatsCollector.java
index 33ea563..c88e1b0 100644
--- a/services/core/java/com/android/server/power/stats/MobileRadioPowerStatsCollector.java
+++ b/services/core/java/com/android/server/power/stats/MobileRadioPowerStatsCollector.java
@@ -16,6 +16,7 @@
 
 package com.android.server.power.stats;
 
+import android.annotation.Nullable;
 import android.content.pm.PackageManager;
 import android.hardware.power.stats.EnergyConsumerType;
 import android.net.NetworkStats;
@@ -69,6 +70,13 @@
             AccessNetworkConstants.AccessNetworkType.NGRAN
     };
 
+    interface Observer {
+        void onMobileRadioPowerStatsRetrieved(
+                @Nullable ModemActivityInfo modemActivityDelta,
+                @Nullable List<BatteryStatsImpl.NetworkStatsDelta> networkStatsDeltas,
+                long elapsedRealtimeMs, long uptimeMs);
+    }
+
     interface Injector {
         Handler getHandler();
         Clock getClock();
@@ -84,6 +92,7 @@
     }
 
     private final Injector mInjector;
+    private final Observer mObserver;
 
     private MobileRadioPowerStatsLayout mLayout;
     private boolean mIsInitialized;
@@ -105,13 +114,14 @@
     private long mLastCallDuration;
     private long mLastScanDuration;
 
-    MobileRadioPowerStatsCollector(Injector injector) {
+    MobileRadioPowerStatsCollector(Injector injector, Observer observer) {
         super(injector.getHandler(), injector.getPowerStatsCollectionThrottlePeriod(
                         BatteryConsumer.powerComponentIdToString(
                                 BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)),
                 injector.getUidResolver(),
                 injector.getClock());
         mInjector = injector;
+        mObserver = observer;
     }
 
     @Override
@@ -198,10 +208,8 @@
         Arrays.fill(mPowerStats.stats, 0);
         mPowerStats.uidStats.clear();
 
-        collectModemActivityInfo();
-
-        collectNetworkStats();
-
+        ModemActivityInfo modemActivityDelta = collectModemActivityInfo();
+        List<BatteryStatsImpl.NetworkStatsDelta> networkStatsDeltas = collectNetworkStats();
         if (mEnergyConsumerIds.length != 0) {
             collectEnergyConsumers();
         }
@@ -210,12 +218,16 @@
             setTimestamp(mClock.elapsedRealtime());
         }
 
+        if (mObserver != null) {
+            mObserver.onMobileRadioPowerStatsRetrieved(modemActivityDelta,
+                    networkStatsDeltas, mClock.elapsedRealtime(), mClock.uptimeMillis());
+        }
         return mPowerStats;
     }
 
-    private void collectModemActivityInfo() {
+    private ModemActivityInfo collectModemActivityInfo() {
         if (mTelephonyManager == null) {
-            return;
+            return null;
         }
 
         CompletableFuture<ModemActivityInfo> immediateFuture = new CompletableFuture<>();
@@ -243,7 +255,7 @@
         }
 
         if (activityInfo == null) {
-            return;
+            return null;
         }
 
         ModemActivityInfo deltaInfo = mLastModemActivityInfo == null
@@ -293,12 +305,13 @@
                 }
             }
         }
+        return deltaInfo;
     }
 
-    private void collectNetworkStats() {
+    private List<BatteryStatsImpl.NetworkStatsDelta> collectNetworkStats() {
         NetworkStats networkStats = mNetworkStatsSupplier.get();
         if (networkStats == null) {
-            return;
+            return null;
         }
 
         List<BatteryStatsImpl.NetworkStatsDelta> delta =
@@ -330,6 +343,7 @@
                 mLayout.setUidTxPackets(stats, mLayout.getUidTxPackets(stats) + txPackets);
             }
         }
+        return delta;
     }
 
     private void collectEnergyConsumers() {
diff --git a/services/core/java/com/android/server/power/stats/PowerComponentAggregatedPowerStats.java b/services/core/java/com/android/server/power/stats/PowerComponentAggregatedPowerStats.java
index 85a2293..8384b2b 100644
--- a/services/core/java/com/android/server/power/stats/PowerComponentAggregatedPowerStats.java
+++ b/services/core/java/com/android/server/power/stats/PowerComponentAggregatedPowerStats.java
@@ -22,6 +22,7 @@
 import android.annotation.Nullable;
 import android.os.UserHandle;
 import android.util.IndentingPrintWriter;
+import android.util.Slog;
 import android.util.SparseArray;
 
 import com.android.internal.os.PowerStats;
@@ -44,6 +45,7 @@
  * as part of the {@link PowerStats.Descriptor}.
  */
 class PowerComponentAggregatedPowerStats {
+    private static final String TAG = "AggregatePowerStats";
     static final String XML_TAG_POWER_COMPONENT = "power_component";
     static final String XML_ATTR_ID = "id";
     private static final String XML_TAG_DEVICE_STATS = "device-stats";
@@ -372,6 +374,37 @@
         }
     }
 
+    void copyStatesFrom(PowerComponentAggregatedPowerStats source) {
+        if (source.mDeviceStates.length == mDeviceStates.length) {
+            System.arraycopy(source.mDeviceStates, 0, mDeviceStates, 0, mDeviceStates.length);
+            if (source.mDeviceStats != null) {
+                createDeviceStats(0);
+                if (mDeviceStats != null) {
+                    mDeviceStats.copyStatesFrom(source.mDeviceStats);
+                }
+            }
+        } else {
+            Slog.wtf(TAG, "State configurations have different lengths: "
+                    + source.mDeviceStates.length + " vs " + mDeviceStates.length);
+        }
+        for (int i = source.mUidStats.size() - 1; i >= 0; i--) {
+            int uid = source.mUidStats.keyAt(i);
+            UidStats sourceUidStats = source.mUidStats.valueAt(i);
+            if (sourceUidStats.states == null) {
+                continue;
+            }
+            UidStats uidStats = new UidStats();
+            uidStats.states = Arrays.copyOf(sourceUidStats.states, sourceUidStats.states.length);
+            if (sourceUidStats.stats != null) {
+                createUidStats(uidStats, 0);
+                if (uidStats.stats != null) {
+                    uidStats.stats.copyStatesFrom(sourceUidStats.stats);
+                }
+            }
+            mUidStats.put(uid, uidStats);
+        }
+    }
+
     public void writeXml(TypedXmlSerializer serializer) throws IOException {
         // No stats aggregated - can skip writing XML altogether
         if (mPowerStatsDescriptor == null) {
diff --git a/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java b/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java
index 6e7fdf1..86f515c 100644
--- a/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java
+++ b/services/core/java/com/android/server/power/stats/PowerStatsAggregator.java
@@ -15,8 +15,8 @@
  */
 package com.android.server.power.stats;
 
+import android.annotation.NonNull;
 import android.os.BatteryStats;
-import android.util.SparseArray;
 
 import com.android.internal.os.BatteryStatsHistory;
 import com.android.internal.os.BatteryStatsHistoryIterator;
@@ -32,20 +32,14 @@
     private static final long UNINITIALIZED = -1;
     private final AggregatedPowerStatsConfig mAggregatedPowerStatsConfig;
     private final BatteryStatsHistory mHistory;
-    private final SparseArray<PowerStatsProcessor> mProcessors = new SparseArray<>();
     private AggregatedPowerStats mStats;
     private int mCurrentBatteryState = AggregatedPowerStatsConfig.POWER_STATE_BATTERY;
     private int mCurrentScreenState = AggregatedPowerStatsConfig.SCREEN_STATE_OTHER;
 
-    public PowerStatsAggregator(AggregatedPowerStatsConfig aggregatedPowerStatsConfig,
-            BatteryStatsHistory history) {
+    public PowerStatsAggregator(@NonNull AggregatedPowerStatsConfig aggregatedPowerStatsConfig,
+            @NonNull BatteryStatsHistory history) {
         mAggregatedPowerStatsConfig = aggregatedPowerStatsConfig;
         mHistory = history;
-        for (AggregatedPowerStatsConfig.PowerComponent powerComponentsConfig :
-                aggregatedPowerStatsConfig.getPowerComponentsAggregatedStatsConfigs()) {
-            PowerStatsProcessor processor = powerComponentsConfig.getProcessor();
-            mProcessors.put(powerComponentsConfig.getPowerComponentId(), processor);
-        }
     }
 
     AggregatedPowerStatsConfig getConfig() {
@@ -71,7 +65,7 @@
                 mStats = new AggregatedPowerStats(mAggregatedPowerStatsConfig);
             }
 
-            start(mStats, startTimeMs);
+            mStats.start(startTimeMs);
 
             boolean clockUpdateAdded = false;
             long baseTime = startTimeMs > 0 ? startTimeMs : UNINITIALIZED;
@@ -138,7 +132,7 @@
                         if (!mStats.isCompatible(item.powerStats)) {
                             if (lastTime > baseTime) {
                                 mStats.setDuration(lastTime - baseTime);
-                                finish(mStats, lastTime);
+                                mStats.finish(lastTime);
                                 consumer.accept(mStats);
                             }
                             mStats.reset();
@@ -151,7 +145,7 @@
             }
             if (lastTime > baseTime) {
                 mStats.setDuration(lastTime - baseTime);
-                finish(mStats, lastTime);
+                mStats.finish(lastTime);
                 consumer.accept(mStats);
             }
 
@@ -159,26 +153,6 @@
         }
     }
 
-    private void start(AggregatedPowerStats stats, long timestampMs) {
-        for (int i = 0; i < mProcessors.size(); i++) {
-            PowerComponentAggregatedPowerStats component =
-                    stats.getPowerComponentStats(mProcessors.keyAt(i));
-            if (component != null) {
-                mProcessors.valueAt(i).start(component, timestampMs);
-            }
-        }
-    }
-
-    private void finish(AggregatedPowerStats stats, long timestampMs) {
-        for (int i = 0; i < mProcessors.size(); i++) {
-            PowerComponentAggregatedPowerStats component =
-                    stats.getPowerComponentStats(mProcessors.keyAt(i));
-            if (component != null) {
-                mProcessors.valueAt(i).finish(component, timestampMs);
-            }
-        }
-    }
-
     /**
      * Reset to prepare for a new aggregation session.
      */
diff --git a/services/core/java/com/android/server/power/stats/PowerStatsCollector.java b/services/core/java/com/android/server/power/stats/PowerStatsCollector.java
index d442c61..d9f6c1f 100644
--- a/services/core/java/com/android/server/power/stats/PowerStatsCollector.java
+++ b/services/core/java/com/android/server/power/stats/PowerStatsCollector.java
@@ -16,6 +16,7 @@
 
 package com.android.server.power.stats;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.hardware.power.stats.EnergyConsumer;
 import android.hardware.power.stats.EnergyConsumerResult;
@@ -61,7 +62,6 @@
     private long mLastScheduledUpdateMs = -1;
 
     @GuardedBy("this")
-    @SuppressWarnings("unchecked")
     private volatile List<Consumer<PowerStats>> mConsumerList = Collections.emptyList();
 
     public PowerStatsCollector(Handler handler, long throttlePeriodMs,
@@ -90,7 +90,6 @@
      * Adds a consumer that will receive a callback every time a snapshot of stats is collected.
      * The method is thread safe.
      */
-    @SuppressWarnings("unchecked")
     public void addConsumer(Consumer<PowerStats> consumer) {
         synchronized (this) {
             if (mConsumerList.contains(consumer)) {
@@ -107,7 +106,6 @@
      * Removes a consumer.
      * The method is thread safe.
      */
-    @SuppressWarnings("unchecked")
     public void removeConsumer(Consumer<PowerStats> consumer) {
         synchronized (this) {
             List<Consumer<PowerStats>> newList = new ArrayList<>(mConsumerList);
@@ -131,18 +129,6 @@
         return mEnabled;
     }
 
-    @SuppressWarnings("GuardedBy")  // Field is volatile
-    public void collectAndDeliverStats() {
-        PowerStats stats = collectStats();
-        if (stats == null) {
-            return;
-        }
-        List<Consumer<PowerStats>> consumerList = mConsumerList;
-        for (int i = consumerList.size() - 1; i >= 0; i--) {
-            consumerList.get(i).accept(stats);
-        }
-    }
-
     /**
      * Schedules a stats snapshot collection, throttled in accordance with the
      * {@link #mThrottlePeriodMs} parameter.
@@ -175,8 +161,30 @@
         return true;
     }
 
+    /**
+     * Performs a PowerStats collection pass and delivers the result to registered consumers.
+     */
+    @SuppressWarnings("GuardedBy")  // Field is volatile
+    public void collectAndDeliverStats() {
+        deliverStats(collectStats());
+    }
+
     @Nullable
-    protected abstract PowerStats collectStats();
+    protected PowerStats collectStats() {
+        return null;
+    }
+
+    @SuppressWarnings("GuardedBy")  // Field is volatile
+    protected void deliverStats(PowerStats stats) {
+        if (stats == null) {
+            return;
+        }
+
+        List<Consumer<PowerStats>> consumerList = mConsumerList;
+        for (int i = consumerList.size() - 1; i >= 0; i--) {
+            consumerList.get(i).accept(stats);
+        }
+    }
 
     /**
      * Collects a fresh stats snapshot and prints it to the supplied printer.
@@ -231,10 +239,33 @@
     }
 
     interface ConsumedEnergyRetriever {
+        @NonNull
         int[] getEnergyConsumerIds(@EnergyConsumerType int energyConsumerType, String name);
 
+        String getEnergyConsumerName(int energyConsumerId);
+
         @Nullable
-        long[] getConsumedEnergyUws(int[] energyConsumerIds);
+        EnergyConsumerResult[] getConsumedEnergy(int[] energyConsumerIds);
+
+        @Nullable
+        default long[] getConsumedEnergyUws(int[] energyConsumerIds) {
+            EnergyConsumerResult[] results = getConsumedEnergy(energyConsumerIds);
+            if (results == null) {
+                return null;
+            }
+
+            long[] energy = new long[energyConsumerIds.length];
+            for (int i = 0; i < energyConsumerIds.length; i++) {
+                int id = energyConsumerIds[i];
+                for (EnergyConsumerResult result : results) {
+                    if (result.id == id) {
+                        energy[i] = result.energyUWs;
+                        break;
+                    }
+                }
+            }
+            return energy;
+        }
 
         default int[] getEnergyConsumerIds(@EnergyConsumerType int energyConsumerType) {
             return getEnergyConsumerIds(energyConsumerType, null);
@@ -243,24 +274,38 @@
 
     static class ConsumedEnergyRetrieverImpl implements ConsumedEnergyRetriever {
         private final PowerStatsInternal mPowerStatsInternal;
+        private EnergyConsumer[] mEnergyConsumers;
 
         ConsumedEnergyRetrieverImpl(PowerStatsInternal powerStatsInternal) {
             mPowerStatsInternal = powerStatsInternal;
         }
 
-        @Override
-        public int[] getEnergyConsumerIds(int energyConsumerType, String name) {
-            if (mPowerStatsInternal == null) {
-                return new int[0];
+        private void ensureEnergyConsumers() {
+            if (mEnergyConsumers != null) {
+                return;
             }
 
-            EnergyConsumer[] energyConsumerInfo = mPowerStatsInternal.getEnergyConsumerInfo();
-            if (energyConsumerInfo == null) {
+            if (mPowerStatsInternal == null) {
+                mEnergyConsumers = new EnergyConsumer[0];
+                return;
+            }
+
+            mEnergyConsumers = mPowerStatsInternal.getEnergyConsumerInfo();
+            if (mEnergyConsumers == null) {
+                mEnergyConsumers = new EnergyConsumer[0];
+            }
+        }
+
+        @Override
+        public int[] getEnergyConsumerIds(int energyConsumerType, String name) {
+            ensureEnergyConsumers();
+
+            if (mEnergyConsumers.length == 0) {
                 return new int[0];
             }
 
             List<EnergyConsumer> energyConsumers = new ArrayList<>();
-            for (EnergyConsumer energyConsumer : energyConsumerInfo) {
+            for (EnergyConsumer energyConsumer : mEnergyConsumers) {
                 if (energyConsumer.type == energyConsumerType
                         && (name == null || name.equals(energyConsumer.name))) {
                     energyConsumers.add(energyConsumer);
@@ -280,32 +325,50 @@
         }
 
         @Override
-        public long[] getConsumedEnergyUws(int[] energyConsumerIds) {
+        public EnergyConsumerResult[] getConsumedEnergy(int[] energyConsumerIds) {
             CompletableFuture<EnergyConsumerResult[]> future =
                     mPowerStatsInternal.getEnergyConsumedAsync(energyConsumerIds);
-            EnergyConsumerResult[] results = null;
             try {
-                results = future.get(
-                        POWER_STATS_ENERGY_CONSUMERS_TIMEOUT, TimeUnit.MILLISECONDS);
+                return future.get(POWER_STATS_ENERGY_CONSUMERS_TIMEOUT, TimeUnit.MILLISECONDS);
             } catch (InterruptedException | ExecutionException | TimeoutException e) {
                 Slog.e(TAG, "Could not obtain energy consumers from PowerStatsService", e);
             }
 
-            if (results == null) {
-                return null;
-            }
+            return null;
+        }
 
-            long[] energy = new long[energyConsumerIds.length];
-            for (int i = 0; i < energyConsumerIds.length; i++) {
-                int id = energyConsumerIds[i];
-                for (EnergyConsumerResult result : results) {
-                    if (result.id == id) {
-                        energy[i] = result.energyUWs;
-                        break;
-                    }
+        @Override
+        public String getEnergyConsumerName(int energyConsumerId) {
+            ensureEnergyConsumers();
+
+            for (EnergyConsumer energyConsumer : mEnergyConsumers) {
+                if (energyConsumer.id == energyConsumerId) {
+                    return sanitizeCustomPowerComponentName(energyConsumer);
                 }
             }
-            return energy;
+
+            Slog.e(TAG, "Unsupported energy consumer ID " + energyConsumerId);
+            return "unsupported";
+        }
+
+        private String sanitizeCustomPowerComponentName(EnergyConsumer energyConsumer) {
+            String name = energyConsumer.name;
+            if (name == null || name.isBlank()) {
+                name = "CUSTOM_" + energyConsumer.id;
+            }
+            int length = name.length();
+            StringBuilder sb = new StringBuilder(length);
+            for (int i = 0; i < length; i++) {
+                char c = name.charAt(i);
+                if (Character.isWhitespace(c)) {
+                    sb.append(' ');
+                } else if (Character.isISOControl(c)) {
+                    sb.append('_');
+                } else {
+                    sb.append(c);
+                }
+            }
+            return sb.toString();
         }
     }
 }
diff --git a/services/core/java/com/android/server/power/stats/PowerStatsExporter.java b/services/core/java/com/android/server/power/stats/PowerStatsExporter.java
index f6b198a8..549a97e 100644
--- a/services/core/java/com/android/server/power/stats/PowerStatsExporter.java
+++ b/services/core/java/com/android/server/power/stats/PowerStatsExporter.java
@@ -115,25 +115,16 @@
 
     private void populateBatteryUsageStatsBuilder(
             BatteryUsageStats.Builder batteryUsageStatsBuilder, AggregatedPowerStats stats) {
-        AggregatedPowerStatsConfig config = mPowerStatsAggregator.getConfig();
-        List<AggregatedPowerStatsConfig.PowerComponent> powerComponents =
-                config.getPowerComponentsAggregatedStatsConfigs();
-        for (int i = powerComponents.size() - 1; i >= 0; i--) {
-            populateBatteryUsageStatsBuilder(batteryUsageStatsBuilder, stats,
-                    powerComponents.get(i));
+        List<PowerComponentAggregatedPowerStats> powerComponentStats =
+                stats.getPowerComponentStats();
+        for (int i = powerComponentStats.size() - 1; i >= 0; i--) {
+            populateBatteryUsageStatsBuilder(batteryUsageStatsBuilder, powerComponentStats.get(i));
         }
     }
 
-    private void populateBatteryUsageStatsBuilder(
-            BatteryUsageStats.Builder batteryUsageStatsBuilder, AggregatedPowerStats stats,
-            AggregatedPowerStatsConfig.PowerComponent powerComponent) {
-        int powerComponentId = powerComponent.getPowerComponentId();
-        PowerComponentAggregatedPowerStats powerComponentStats = stats.getPowerComponentStats(
-                powerComponentId);
-        if (powerComponentStats == null) {
-            return;
-        }
-
+    private static void populateBatteryUsageStatsBuilder(
+            BatteryUsageStats.Builder batteryUsageStatsBuilder,
+            PowerComponentAggregatedPowerStats powerComponentStats) {
         PowerStats.Descriptor descriptor = powerComponentStats.getPowerStatsDescriptor();
         if (descriptor == null) {
             return;
@@ -144,7 +135,8 @@
 
         long[] deviceStats = new long[descriptor.statsArrayLength];
         double[] totalPower = new double[1];
-        MultiStateStats.States.forEachTrackedStateCombination(powerComponent.getDeviceStateConfig(),
+        MultiStateStats.States.forEachTrackedStateCombination(
+                powerComponentStats.getConfig().getDeviceStateConfig(),
                 states -> {
                     if (states[AggregatedPowerStatsConfig.STATE_POWER]
                             != AggregatedPowerStatsConfig.POWER_STATE_BATTERY) {
@@ -161,29 +153,37 @@
         AggregateBatteryConsumer.Builder deviceScope =
                 batteryUsageStatsBuilder.getAggregateBatteryConsumerBuilder(
                         BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
-        deviceScope.addConsumedPower(powerComponentId,
-                totalPower[0], BatteryConsumer.POWER_MODEL_UNDEFINED);
+        if (descriptor.powerComponentId >= BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID) {
+            if (batteryUsageStatsBuilder.isSupportedCustomPowerComponent(
+                    descriptor.powerComponentId)) {
+                deviceScope.addConsumedPowerForCustomComponent(descriptor.powerComponentId,
+                        totalPower[0]);
+            }
+        } else {
+            deviceScope.addConsumedPower(descriptor.powerComponentId,
+                    totalPower[0], BatteryConsumer.POWER_MODEL_UNDEFINED);
+        }
 
         if (layout.isUidPowerAttributionSupported()) {
-            populateUidBatteryConsumers(batteryUsageStatsBuilder, powerComponent,
+            populateUidBatteryConsumers(batteryUsageStatsBuilder,
                     powerComponentStats, layout);
         }
     }
 
     private static void populateUidBatteryConsumers(
             BatteryUsageStats.Builder batteryUsageStatsBuilder,
-            AggregatedPowerStatsConfig.PowerComponent powerComponent,
             PowerComponentAggregatedPowerStats powerComponentStats,
             PowerStatsLayout layout) {
+        AggregatedPowerStatsConfig.PowerComponent powerComponent = powerComponentStats.getConfig();
         int powerComponentId = powerComponent.getPowerComponentId();
         PowerStats.Descriptor descriptor = powerComponentStats.getPowerStatsDescriptor();
         long[] uidStats = new long[descriptor.uidStatsArrayLength];
 
-        boolean breakDownByProcState =
-                batteryUsageStatsBuilder.isProcessStateDataNeeded()
+        // TODO(b/347101393): add support for per-procstate breakdown for custom energy consumers
+        boolean breakDownByProcState = batteryUsageStatsBuilder.isProcessStateDataNeeded()
                 && powerComponent
-                        .getUidStateConfig()[AggregatedPowerStatsConfig.STATE_PROCESS_STATE]
-                        .isTracked();
+                .getUidStateConfig()[AggregatedPowerStatsConfig.STATE_PROCESS_STATE].isTracked()
+                && powerComponentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID;
 
         double[] powerByProcState =
                 new double[breakDownByProcState ? BatteryConsumer.PROCESS_STATE_COUNT : 1];
@@ -224,19 +224,27 @@
                 powerAllProcStates += power;
                 if (breakDownByProcState
                         && procState != BatteryConsumer.PROCESS_STATE_UNSPECIFIED) {
-                    builder.addConsumedPower(builder.getKey(powerComponentId, procState),
-                            power, BatteryConsumer.POWER_MODEL_UNDEFINED);
+                    builder.addConsumedPower(builder.getKey(powerComponentId, procState), power,
+                            BatteryConsumer.POWER_MODEL_UNDEFINED);
                 }
             }
-            builder.addConsumedPower(powerComponentId, powerAllProcStates,
-                    BatteryConsumer.POWER_MODEL_UNDEFINED);
+            if (powerComponentId >= BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID) {
+                builder.addConsumedPowerForCustomComponent(powerComponentId, powerAllProcStates);
+            } else {
+                builder.addConsumedPower(powerComponentId, powerAllProcStates,
+                        BatteryConsumer.POWER_MODEL_UNDEFINED);
+            }
             powerAllApps += powerAllProcStates;
         }
 
         AggregateBatteryConsumer.Builder allAppsScope =
                 batteryUsageStatsBuilder.getAggregateBatteryConsumerBuilder(
                         BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS);
-        allAppsScope.addConsumedPower(powerComponentId, powerAllApps,
-                BatteryConsumer.POWER_MODEL_UNDEFINED);
+        if (powerComponentId >= BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID) {
+            allAppsScope.addConsumedPowerForCustomComponent(powerComponentId, powerAllApps);
+        } else {
+            allAppsScope.addConsumedPower(powerComponentId, powerAllApps,
+                    BatteryConsumer.POWER_MODEL_UNDEFINED);
+        }
     }
 }
diff --git a/services/core/java/com/android/server/power/stats/PowerStatsLayout.java b/services/core/java/com/android/server/power/stats/PowerStatsLayout.java
index 9624fd2..62abfc6 100644
--- a/services/core/java/com/android/server/power/stats/PowerStatsLayout.java
+++ b/services/core/java/com/android/server/power/stats/PowerStatsLayout.java
@@ -32,6 +32,8 @@
     private static final String EXTRA_DEVICE_ENERGY_CONSUMERS_POSITION = "de";
     private static final String EXTRA_DEVICE_ENERGY_CONSUMERS_COUNT = "dec";
     private static final String EXTRA_UID_DURATION_POSITION = "ud";
+    private static final String EXTRA_UID_ENERGY_CONSUMERS_POSITION = "ue";
+    private static final String EXTRA_UID_ENERGY_CONSUMERS_COUNT = "uec";
     private static final String EXTRA_UID_POWER_POSITION = "up";
 
     protected static final int UNSUPPORTED = -1;
@@ -53,6 +55,8 @@
     private int mDeviceEnergyConsumerCount;
     private int mDevicePowerEstimatePosition = UNSUPPORTED;
     private int mUidDurationPosition = UNSUPPORTED;
+    private int mUidEnergyConsumerPosition = UNSUPPORTED;
+    private int mUidEnergyConsumerCount;
     private int mUidPowerEstimatePosition = UNSUPPORTED;
 
     public PowerStatsLayout() {
@@ -244,6 +248,36 @@
     }
 
     /**
+     * Declares that the UID stats array has a section capturing EnergyConsumer data from
+     * PowerStatsService.
+     */
+    public void addUidSectionEnergyConsumers(int energyConsumerCount) {
+        mUidEnergyConsumerPosition = addUidSection(energyConsumerCount, "energy",
+                FLAG_OPTIONAL);
+        mUidEnergyConsumerCount = energyConsumerCount;
+    }
+
+    public int getUidEnergyConsumerCount() {
+        return mUidEnergyConsumerCount;
+    }
+
+    /**
+     * Saves the accumulated energy for the specified rail the corresponding
+     * <code>stats</code> element.
+     */
+    public void setUidConsumedEnergy(long[] stats, int index, long energy) {
+        stats[mUidEnergyConsumerPosition + index] = energy;
+    }
+
+    /**
+     * Extracts the EnergyConsumer data from a uid stats array for the specified
+     * EnergyConsumer.
+     */
+    public long getUidConsumedEnergy(long[] stats, int index) {
+        return stats[mUidEnergyConsumerPosition + index];
+    }
+
+    /**
      * Converts the supplied mAh power estimate to a long and saves it in the corresponding
      * element of <code>stats</code>.
      */
@@ -269,6 +303,8 @@
                 mDeviceEnergyConsumerCount);
         extras.putInt(EXTRA_DEVICE_POWER_POSITION, mDevicePowerEstimatePosition);
         extras.putInt(EXTRA_UID_DURATION_POSITION, mUidDurationPosition);
+        extras.putInt(EXTRA_UID_ENERGY_CONSUMERS_POSITION, mUidEnergyConsumerPosition);
+        extras.putInt(EXTRA_UID_ENERGY_CONSUMERS_COUNT, mUidEnergyConsumerCount);
         extras.putInt(EXTRA_UID_POWER_POSITION, mUidPowerEstimatePosition);
         extras.putString(PowerStats.Descriptor.EXTRA_DEVICE_STATS_FORMAT, mDeviceFormat.toString());
         extras.putString(PowerStats.Descriptor.EXTRA_STATE_STATS_FORMAT, mStateFormat.toString());
@@ -284,6 +320,8 @@
         mDeviceEnergyConsumerCount = extras.getInt(EXTRA_DEVICE_ENERGY_CONSUMERS_COUNT);
         mDevicePowerEstimatePosition = extras.getInt(EXTRA_DEVICE_POWER_POSITION);
         mUidDurationPosition = extras.getInt(EXTRA_UID_DURATION_POSITION);
+        mUidEnergyConsumerPosition = extras.getInt(EXTRA_UID_ENERGY_CONSUMERS_POSITION);
+        mUidEnergyConsumerCount = extras.getInt(EXTRA_UID_ENERGY_CONSUMERS_COUNT);
         mUidPowerEstimatePosition = extras.getInt(EXTRA_UID_POWER_POSITION);
     }
 
diff --git a/services/core/java/com/android/server/power/stats/PowerStatsProcessor.java b/services/core/java/com/android/server/power/stats/PowerStatsProcessor.java
index f257e1a..dfc8daa 100644
--- a/services/core/java/com/android/server/power/stats/PowerStatsProcessor.java
+++ b/services/core/java/com/android/server/power/stats/PowerStatsProcessor.java
@@ -43,7 +43,7 @@
  * 2. For each UID, compute the proportion of the combined estimates in each state
  * and attribute the corresponding portion of the total power estimate in that state to the UID.
  */
-abstract class PowerStatsProcessor {
+public abstract class PowerStatsProcessor {
     private static final String TAG = "PowerStatsProcessor";
 
     private static final double MILLIAMPHOUR_PER_MICROCOULOMB = 1.0 / 1000.0 / 60.0 / 60.0;
diff --git a/services/core/java/com/android/server/power/stats/WifiPowerStatsCollector.java b/services/core/java/com/android/server/power/stats/WifiPowerStatsCollector.java
index bd04199..6d519ee 100644
--- a/services/core/java/com/android/server/power/stats/WifiPowerStatsCollector.java
+++ b/services/core/java/com/android/server/power/stats/WifiPowerStatsCollector.java
@@ -43,6 +43,12 @@
 
     private static final long ENERGY_UNSPECIFIED = -1;
 
+    interface Observer {
+        void onWifiPowerStatsRetrieved(WifiActivityEnergyInfo info,
+                List<BatteryStatsImpl.NetworkStatsDelta> delta, long elapsedRealtimeMs,
+                long uptimeMs);
+    }
+
     interface WifiStatsRetriever {
         interface Callback {
             void onWifiScanTime(int uid, long scanTimeMs, long batchScanTimeMs);
@@ -66,6 +72,7 @@
     }
 
     private final Injector mInjector;
+    private final Observer mObserver;
 
     private WifiPowerStatsLayout mLayout;
     private boolean mIsInitialized;
@@ -93,12 +100,13 @@
     private final SparseArray<WifiScanTimes> mLastScanTimes = new SparseArray<>();
     private long mLastWifiActiveDuration;
 
-    WifiPowerStatsCollector(Injector injector) {
+    WifiPowerStatsCollector(Injector injector, Observer observer) {
         super(injector.getHandler(), injector.getPowerStatsCollectionThrottlePeriod(
                         BatteryConsumer.powerComponentIdToString(
                                 BatteryConsumer.POWER_COMPONENT_WIFI)),
                 injector.getUidResolver(), injector.getClock());
         mInjector = injector;
+        mObserver = observer;
     }
 
     @Override
@@ -160,22 +168,27 @@
             return null;
         }
 
+        WifiActivityEnergyInfo activityInfo = null;
         if (mPowerReportingSupported) {
-            collectWifiActivityInfo();
+            activityInfo = collectWifiActivityInfo();
         } else {
             collectWifiActivityStats();
         }
-        collectNetworkStats();
+        List<BatteryStatsImpl.NetworkStatsDelta> networkStatsDeltas = collectNetworkStats();
         collectWifiScanTime();
 
         if (mEnergyConsumerIds.length != 0) {
             collectEnergyConsumers();
         }
 
+        if (mObserver != null) {
+            mObserver.onWifiPowerStatsRetrieved(activityInfo, networkStatsDeltas,
+                    mClock.elapsedRealtime(), mClock.uptimeMillis());
+        }
         return mPowerStats;
     }
 
-    private void collectWifiActivityInfo() {
+    private WifiActivityEnergyInfo collectWifiActivityInfo() {
         CompletableFuture<WifiActivityEnergyInfo> immediateFuture = new CompletableFuture<>();
         mWifiManager.getWifiActivityEnergyInfoAsync(Runnable::run,
                 immediateFuture::complete);
@@ -190,7 +203,7 @@
         }
 
         if (activityInfo == null) {
-            return;
+            return null;
         }
 
         long rxDuration = activityInfo.getControllerRxDurationMillis()
@@ -210,6 +223,9 @@
         mPowerStats.durationMs = rxDuration + txDuration + scanDuration + idleDuration;
 
         mLastWifiActivityInfo = activityInfo;
+
+        return new WifiActivityEnergyInfo(activityInfo.getTimeSinceBootMillis(),
+                activityInfo.getStackState(), txDuration, rxDuration, scanDuration, idleDuration);
     }
 
     private void collectWifiActivityStats() {
@@ -219,12 +235,12 @@
         mPowerStats.durationMs = duration;
     }
 
-    private void collectNetworkStats() {
+    private List<BatteryStatsImpl.NetworkStatsDelta> collectNetworkStats() {
         mPowerStats.uidStats.clear();
 
         NetworkStats networkStats = mNetworkStatsSupplier.get();
         if (networkStats == null) {
-            return;
+            return null;
         }
 
         List<BatteryStatsImpl.NetworkStatsDelta> delta =
@@ -256,6 +272,7 @@
                 mLayout.setUidTxPackets(stats, mLayout.getUidTxPackets(stats) + txPackets);
             }
         }
+        return delta;
     }
 
     private void collectWifiScanTime() {
diff --git a/services/core/java/com/android/server/stats/pull/BatteryHealthUtility.java b/services/core/java/com/android/server/stats/pull/BatteryHealthUtility.java
new file mode 100644
index 0000000..e0768fe
--- /dev/null
+++ b/services/core/java/com/android/server/stats/pull/BatteryHealthUtility.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.stats.pull;
+
+import android.util.StatsEvent;
+
+import com.android.internal.util.FrameworkStatsLog;
+
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Locale;
+
+/**
+ * Utility class to redact Battery Health data from HealthServiceWrapper
+ *
+ * @hide
+ */
+public abstract class BatteryHealthUtility {
+    /**
+     * Create a StatsEvent corresponding to the Battery Health data, the fields
+     * of which are redacted to preserve users' privacy.
+     * The redaction consists in truncating the timestamps to the Monday of the
+     * corresponding week, and reducing the battery serial into the last byte
+     * of its MD5.
+     */
+    public static StatsEvent buildStatsEvent(int atomTag,
+            android.hardware.health.BatteryHealthData data, int chargeStatus, int chargePolicy)
+            throws NoSuchAlgorithmException {
+        int manufacturingDate = secondsToWeekYYYYMMDD(data.batteryManufacturingDateSeconds);
+        int firstUsageDate = secondsToWeekYYYYMMDD(data.batteryFirstUsageSeconds);
+        long stateOfHealth = data.batteryStateOfHealth;
+        int partStatus = data.batteryPartStatus;
+        int serialHashTruncated = stringToIntHash(data.batterySerialNumber) & 0xFF; // Last byte
+
+        return FrameworkStatsLog.buildStatsEvent(atomTag, manufacturingDate, firstUsageDate,
+                (int) stateOfHealth, serialHashTruncated, partStatus, chargeStatus, chargePolicy);
+    }
+
+    private static int secondsToWeekYYYYMMDD(long seconds) {
+        Calendar calendar = Calendar.getInstance();
+        long millis = seconds * 1000L;
+
+        calendar.setTimeInMillis(millis);
+
+        // Truncate all date information, up to week, which is rounded to
+        // MONDAY
+        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        calendar.set(Calendar.MILLISECOND, 0);
+
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd", Locale.US);
+
+        String formattedDate = sdf.format(calendar.getTime());
+
+        return Integer.parseInt(formattedDate);
+    }
+
+    private static int stringToIntHash(String data) throws NoSuchAlgorithmException {
+        if (data == null || data.isEmpty()) {
+            return 0;
+        }
+
+        MessageDigest digest = MessageDigest.getInstance("MD5");
+        byte[] hashBytes = digest.digest(data.getBytes());
+
+        // Convert to integer (simplest way, but potential for loss of information)
+        BigInteger bigInt = new BigInteger(1, hashBytes);
+        return bigInt.intValue();
+    }
+}
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index c1b825b..0041d39 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -119,6 +119,8 @@
 import android.net.NetworkTemplate;
 import android.net.wifi.WifiManager;
 import android.os.AsyncTask;
+import android.os.BatteryManager;
+import android.os.BatteryProperty;
 import android.os.BatteryStats;
 import android.os.BatteryStatsInternal;
 import android.os.BatteryStatsManager;
@@ -243,6 +245,7 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.security.NoSuchAlgorithmException;
 import java.time.Instant;
 import java.time.temporal.ChronoUnit;
 import java.util.ArrayList;
@@ -769,6 +772,7 @@
                     case FrameworkStatsLog.FULL_BATTERY_CAPACITY:
                     case FrameworkStatsLog.BATTERY_VOLTAGE:
                     case FrameworkStatsLog.BATTERY_CYCLE_COUNT:
+                    case FrameworkStatsLog.BATTERY_HEALTH:
                         synchronized (mHealthHalLock) {
                             return pullHealthHalLocked(atomTag, data);
                         }
@@ -999,6 +1003,7 @@
         registerFullBatteryCapacity();
         registerBatteryVoltage();
         registerBatteryCycleCount();
+        registerBatteryHealth();
         registerSettingsStats();
         registerInstalledIncrementalPackages();
         registerKeystoreStorageStats();
@@ -4365,7 +4370,15 @@
         );
     }
 
-    int pullHealthHalLocked(int atomTag, List<StatsEvent> pulledData) {
+    private void registerBatteryHealth() {
+        int tagId = FrameworkStatsLog.BATTERY_HEALTH;
+        mStatsManager.setPullAtomCallback(tagId,
+                null, // use default PullAtomMetadata values
+                DIRECT_EXECUTOR, mStatsCallbackImpl);
+    }
+
+    @GuardedBy("mHealthHalLock")
+    private int pullHealthHalLocked(int atomTag, List<StatsEvent> pulledData) {
         if (mHealthService == null) {
             return StatsManager.PULL_SKIP;
         }
@@ -4396,6 +4409,44 @@
             case FrameworkStatsLog.BATTERY_CYCLE_COUNT:
                 pulledValue = healthInfo.batteryCycleCount;
                 break;
+            case FrameworkStatsLog.BATTERY_HEALTH:
+                android.hardware.health.BatteryHealthData bhd;
+                try {
+                    bhd = mHealthService.getBatteryHealthData();
+                } catch (RemoteException | IllegalStateException e) {
+                    return StatsManager.PULL_SKIP;
+                }
+                if (bhd == null) {
+                    return StatsManager.PULL_SKIP;
+                }
+
+                StatsEvent batteryHealthEvent;
+                try {
+                    BatteryProperty chargeStatusProperty = new BatteryProperty();
+                    BatteryProperty chargePolicyProperty = new BatteryProperty();
+
+                    if (0 > mHealthService.getProperty(
+                                BatteryManager.BATTERY_PROPERTY_STATUS, chargeStatusProperty)) {
+                        return StatsManager.PULL_SKIP;
+                    }
+                    if (0 > mHealthService.getProperty(
+                                BatteryManager.BATTERY_PROPERTY_CHARGING_POLICY,
+                                chargePolicyProperty)) {
+                        return StatsManager.PULL_SKIP;
+                    }
+                    int chargeStatus = (int) chargeStatusProperty.getLong();
+                    int chargePolicy = (int) chargePolicyProperty.getLong();
+                    batteryHealthEvent = BatteryHealthUtility.buildStatsEvent(
+                            atomTag, bhd, chargeStatus, chargePolicy);
+                    pulledData.add(batteryHealthEvent);
+
+                    return StatsManager.PULL_SUCCESS;
+                } catch (RemoteException | IllegalStateException e) {
+                    Slog.e(TAG, "Failed to add pulled data", e);
+                } catch (NoSuchAlgorithmException e) {
+                    Slog.e(TAG, "Could not find message digest algorithm", e);
+                }
+                return StatsManager.PULL_SKIP;
             default:
                 return StatsManager.PULL_SKIP;
         }
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index e0a8226..6721893 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -341,10 +341,16 @@
         }, UserHandle.ALL, intentFilter, null, null);
     }
 
+    private static boolean hasAlwaysBoundPermission(PackageManager pm, ComponentName component) {
+        return pm.checkPermission(android.Manifest.permission.ALWAYS_BOUND_TV_INPUT,
+                component.getPackageName()) == PackageManager.PERMISSION_GRANTED;
+    }
+
     private static boolean hasHardwarePermission(PackageManager pm, ComponentName component) {
         return pm.checkPermission(android.Manifest.permission.TV_INPUT_HARDWARE,
                 component.getPackageName()) == PackageManager.PERMISSION_GRANTED;
     }
+
     @GuardedBy("mLock")
     private void buildTvInputListLocked(int userId, String[] updatedPackages) {
         UserState userState = getOrCreateUserStateLocked(userId);
@@ -3526,7 +3532,7 @@
                 continue;
             }
             ComponentName component = new ComponentName(si.packageName, si.name);
-            if (hasHardwarePermission(pm, component)) {
+            if (!hasAlwaysBoundPermission(pm, component) && hasHardwarePermission(pm, component)) {
                 updateServiceConnectionLocked(component, userId);
             }
         }
diff --git a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
index 34c90f1..edd2fa9 100644
--- a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
+++ b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
@@ -2124,7 +2124,7 @@
         @Override
         public void setTeletextAppEnabled(IBinder sessionToken, boolean enable, int userId) {
             if (DEBUG) {
-                Slogf.d(TAG, "setTeletextAppEnabled(enable=%d)", enable);
+                Slogf.d(TAG, "setTeletextAppEnabled(enable=%b)", enable);
             }
             final int callingUid = Binder.getCallingUid();
             final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
diff --git a/services/core/java/com/android/server/updates/CertificateTransparencyLogInstallReceiver.java b/services/core/java/com/android/server/updates/CertificateTransparencyLogInstallReceiver.java
index bf32045..5565b6f 100644
--- a/services/core/java/com/android/server/updates/CertificateTransparencyLogInstallReceiver.java
+++ b/services/core/java/com/android/server/updates/CertificateTransparencyLogInstallReceiver.java
@@ -47,7 +47,7 @@
     private static final String LOGDIR_PREFIX = "logs-";
 
     public CertificateTransparencyLogInstallReceiver() {
-        super("/data/misc/keychain/trusted_ct_logs/", "ct_logs", "metadata/", "version");
+        super("/data/misc/keychain/ct/", "ct_logs", "metadata/", "version");
     }
 
     @Override
@@ -85,7 +85,7 @@
             }
         }
         try {
-            // 3. Create /data/misc/keychain/trusted_ct_logs/<new_version>/ .
+            // 3. Create /data/misc/keychain/ct/<new_version>/ .
             newVersion.mkdir();
             if (!newVersion.isDirectory()) {
                 throw new IOException("Unable to make directory " + newVersion.getCanonicalPath());
diff --git a/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java b/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java
index 9756094..503a726 100644
--- a/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java
+++ b/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java
@@ -108,9 +108,9 @@
             throws CustomizationParserException, IOException {
         try {
             return loadVibrationsInternal(res, vibratorInfo);
-        } catch (VibrationXmlParser.VibrationXmlParserException
-                | XmlParserException
-                | XmlPullParserException e) {
+        } catch (VibrationXmlParser.ParseFailedException
+                 | XmlParserException
+                 | XmlPullParserException e) {
             throw new CustomizationParserException(
                     "Error parsing haptic feedback customization file.", e);
         }
@@ -121,7 +121,6 @@
             Resources res, VibratorInfo vibratorInfo) throws
                     CustomizationParserException,
                     IOException,
-                    VibrationXmlParser.VibrationXmlParserException,
                     XmlParserException,
                     XmlPullParserException {
         if (!Flags.hapticFeedbackVibrationOemCustomizationEnabled()) {
@@ -172,10 +171,6 @@
 
             ParsedVibration parsedVibration = VibrationXmlParser.parseElement(
                     parser, VibrationXmlParser.FLAG_ALLOW_HIDDEN_APIS);
-            if (parsedVibration == null) {
-                throw new CustomizationParserException(
-                        "Unable to parse vibration element for effect " + effectId);
-            }
             VibrationEffect effect = parsedVibration.resolve(vibratorInfo);
             if (effect != null) {
                 if (effect.getDuration() == Long.MAX_VALUE) {
diff --git a/services/core/java/com/android/server/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java
index 84c37180..6537228 100644
--- a/services/core/java/com/android/server/vibrator/Vibration.java
+++ b/services/core/java/com/android/server/vibrator/Vibration.java
@@ -69,6 +69,7 @@
         CANCELLED_BY_USER(VibrationProto.CANCELLED_BY_USER),
         CANCELLED_BY_UNKNOWN_REASON(VibrationProto.CANCELLED_BY_UNKNOWN_REASON),
         CANCELLED_SUPERSEDED(VibrationProto.CANCELLED_SUPERSEDED),
+        CANCELLED_BY_APP_OPS(VibrationProto.CANCELLED_BY_APP_OPS),
         IGNORED_ERROR_APP_OPS(VibrationProto.IGNORED_ERROR_APP_OPS),
         IGNORED_ERROR_CANCELLING(VibrationProto.IGNORED_ERROR_CANCELLING),
         IGNORED_ERROR_SCHEDULING(VibrationProto.IGNORED_ERROR_SCHEDULING),
diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java
index 2fc183d..0206155 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSettings.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java
@@ -532,7 +532,8 @@
             return false;
         }
 
-        if (Flags.keyboardCategoryEnabled() && mVibrationConfig.hasFixedKeyboardAmplitude()) {
+        if (Flags.keyboardCategoryEnabled()
+                && mVibrationConfig.isKeyboardVibrationSettingsSupported()) {
             int category = callerInfo.attrs.getCategory();
             if (usage == USAGE_TOUCH && category == CATEGORY_KEYBOARD) {
                 // Keyboard touch has a different user setting.
@@ -556,8 +557,8 @@
             mVibrateInputDevices =
                     loadSystemSetting(Settings.System.VIBRATE_INPUT_DEVICES, 0, userHandle) > 0;
             mVibrateOn = loadSystemSetting(Settings.System.VIBRATE_ON, 1, userHandle) > 0;
-            mKeyboardVibrationOn = loadSystemSetting(Settings.System.KEYBOARD_VIBRATION_ENABLED,
-                    mVibrationConfig.isDefaultKeyboardVibrationEnabled() ? 1 : 0, userHandle) > 0;
+            mKeyboardVibrationOn = loadSystemSetting(
+                    Settings.System.KEYBOARD_VIBRATION_ENABLED, 1, userHandle) > 0;
 
             int alarmIntensity = toIntensity(
                     loadSystemSetting(Settings.System.ALARM_VIBRATION_INTENSITY, -1, userHandle),
@@ -644,12 +645,10 @@
                         .append("), ");
             }
             vibrationIntensitiesString.append('}');
-            String keyboardVibrationOnString = mKeyboardVibrationOn
-                    + " (default: " + mVibrationConfig.isDefaultKeyboardVibrationEnabled() + ")";
             return "VibrationSettings{"
                     + "mVibratorConfig=" + mVibrationConfig
                     + ", mVibrateOn=" + mVibrateOn
-                    + ", mKeyboardVibrationOn=" + keyboardVibrationOnString
+                    + ", mKeyboardVibrationOn=" + mKeyboardVibrationOn
                     + ", mVibrateInputDevices=" + mVibrateInputDevices
                     + ", mBatterySaverMode=" + mBatterySaverMode
                     + ", mRingerMode=" + ringerModeToString(mRingerMode)
@@ -666,8 +665,7 @@
             pw.println("VibrationSettings:");
             pw.increaseIndent();
             pw.println("vibrateOn = " + mVibrateOn);
-            pw.println("keyboardVibrationOn = " + mKeyboardVibrationOn
-                    + ", default: " + mVibrationConfig.isDefaultKeyboardVibrationEnabled());
+            pw.println("keyboardVibrationOn = " + mKeyboardVibrationOn);
             pw.println("vibrateInputDevices = " + mVibrateInputDevices);
             pw.println("batterySaverMode = " + mBatterySaverMode);
             pw.println("ringerMode = " + ringerModeToString(mRingerMode));
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index 3dcc7a6..5c15ccb 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -193,6 +193,27 @@
         }
     };
 
+    @VisibleForTesting
+    final AppOpsManager.OnOpChangedInternalListener mAppOpsChangeListener =
+            new AppOpsManager.OnOpChangedInternalListener() {
+                @Override
+                public void onOpChanged(int op, String packageName) {
+                    if (op != AppOpsManager.OP_VIBRATE) {
+                        return;
+                    }
+                    synchronized (mLock) {
+                        if (shouldCancelAppOpModeChangedLocked(mNextVibration)) {
+                            clearNextVibrationLocked(
+                                    new Vibration.EndInfo(Vibration.Status.CANCELLED_BY_APP_OPS));
+                        }
+                        if (shouldCancelAppOpModeChangedLocked(mCurrentVibration)) {
+                            mCurrentVibration.notifyCancelled(new Vibration.EndInfo(
+                                    Vibration.Status.CANCELLED_BY_APP_OPS), /* immediate= */ false);
+                        }
+                    }
+                }
+            };
+
     static native long nativeInit(OnSyncedVibrationCompleteListener listener);
 
     static native long nativeGetFinalizer();
@@ -238,6 +259,9 @@
         mBatteryStatsService = injector.getBatteryStatsService();
 
         mAppOps = mContext.getSystemService(AppOpsManager.class);
+        if (Flags.cancelByAppops()) {
+            mAppOps.startWatchingMode(AppOpsManager.OP_VIBRATE, null, mAppOpsChangeListener);
+        }
 
         PowerManager pm = context.getSystemService(PowerManager.class);
         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*vibrator*");
@@ -1390,6 +1414,15 @@
     }
 
     @GuardedBy("mLock")
+    private boolean shouldCancelAppOpModeChangedLocked(@Nullable VibrationStepConductor conductor) {
+        if (conductor == null) {
+            return false;
+        }
+        return checkAppOpModeLocked(conductor.getVibration().callerInfo)
+                != AppOpsManager.MODE_ALLOWED;
+    }
+
+    @GuardedBy("mLock")
     private void onAllVibratorsLocked(Consumer<VibratorController> consumer) {
         for (int i = 0; i < mVibrators.size(); i++) {
             consumer.accept(mVibrators.valueAt(i));
@@ -2461,9 +2494,6 @@
             try {
                 ParsedVibration parsedVibration =
                         VibrationXmlParser.parseDocument(new StringReader(xml));
-                if (parsedVibration == null) {
-                    throw new IllegalArgumentException("Error parsing vibration XML " + xml);
-                }
                 VibratorInfo combinedVibratorInfo = getCombinedVibratorInfo();
                 if (combinedVibratorInfo == null) {
                     throw new IllegalStateException(
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 8fc6965..72c7be3 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -17,6 +17,7 @@
 package com.android.server.wallpaper;
 
 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+import static android.Manifest.permission.MANAGE_EXTERNAL_STORAGE;
 import static android.Manifest.permission.READ_WALLPAPER_INTERNAL;
 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
 import static android.app.WallpaperManager.COMMAND_REAPPLY;
@@ -2209,7 +2210,8 @@
     public ParcelFileDescriptor getWallpaperWithFeature(String callingPkg, String callingFeatureId,
             IWallpaperManagerCallback cb, final int which, Bundle outParams, int wallpaperUserId,
             boolean getCropped) {
-        final boolean hasPrivilege = hasPermission(READ_WALLPAPER_INTERNAL);
+        final boolean hasPrivilege = hasPermission(READ_WALLPAPER_INTERNAL)
+                || hasPermission(MANAGE_EXTERNAL_STORAGE);
         if (!hasPrivilege) {
             mContext.getSystemService(StorageManager.class).checkPermissionReadImages(true,
                     Binder.getCallingPid(), Binder.getCallingUid(), callingPkg, callingFeatureId);
diff --git a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
index 0e0b78f..2d8aa3f 100644
--- a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
+++ b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
@@ -382,12 +382,6 @@
             }
             return null;
         }
-        if (activity.hasCommittedReparentToAnimationLeash()) {
-            if (DEBUG_SCREENSHOT) {
-                Slog.w(TAG_WM, "Failed to take screenshot. App is animating " + activity);
-            }
-            return null;
-        }
         final WindowState mainWindow = activity.findMainWindow();
         if (mainWindow == null) {
             Slog.w(TAG_WM, "Failed to take screenshot. No main window for " + source);
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index 3e177c9..a8dcaa8 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -102,7 +102,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.AssistUtils;
 import com.android.internal.policy.IKeyguardDismissCallback;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.LocalServices;
 import com.android.server.Watchdog;
 import com.android.server.pm.KnownPackages;
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index d9dc7ba..129cee7 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -93,6 +93,7 @@
 import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_LARGE;
 import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM;
 import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY;
+import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_SMALL;
 import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN;
 import static android.content.pm.ActivityInfo.PERSIST_ACROSS_REBOOTS;
 import static android.content.pm.ActivityInfo.PERSIST_ROOT_ONLY;
@@ -158,7 +159,6 @@
 import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_SIZE_COMPAT_MODE;
 import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__NOT_LETTERBOXED;
 import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__STATE__NOT_VISIBLE;
-import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
 import static com.android.server.wm.ActivityRecord.State.DESTROYED;
@@ -386,7 +386,7 @@
 import com.android.internal.os.TimeoutRecord;
 import com.android.internal.os.TransferPipe;
 import com.android.internal.policy.AttributeCache;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.XmlUtils;
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
@@ -734,6 +734,9 @@
      */
     private boolean mOccludesParent;
 
+    /** Whether the activity have style floating */
+    private boolean mStyleFloating;
+
     /**
      * Unlike {@link #mOccludesParent} which can be changed at runtime. This is a static attribute
      * from the style of activity. Because we don't want {@link WindowContainer#getOrientation()}
@@ -807,9 +810,10 @@
     final LetterboxUiController mLetterboxUiController;
 
     /**
-     * The policy for transparent activities
+     * App Compat Facade
      */
-    final TransparentPolicy mTransparentPolicy;
+    @NonNull
+    final AppCompatController mAppCompatController;
 
     /**
      * The scale to fit at least one side of the activity to its parent. If the activity uses
@@ -1706,7 +1710,7 @@
             if (isState(RESUMED)) {
                 newParent.setResumedActivity(this, "onParentChanged");
             }
-            mTransparentPolicy.start();
+            mAppCompatController.getTransparentPolicy().start();
         }
 
         if (rootTask != null && rootTask.topRunningActivity() == this) {
@@ -1908,7 +1912,7 @@
     }
 
     void updateLetterboxSurfaceIfNeeded(WindowState winHint, Transaction t) {
-        mLetterboxUiController.updateLetterboxSurfaceIfNeeded(winHint, t);
+        mLetterboxUiController.updateLetterboxSurfaceIfNeeded(winHint, t, getPendingTransaction());
     }
 
     void updateLetterboxSurfaceIfNeeded(WindowState winHint) {
@@ -2144,8 +2148,8 @@
         // Don't move below setOrientation(info.screenOrientation) since it triggers
         // getOverrideOrientation that requires having mLetterboxUiController
         // initialised.
-        mTransparentPolicy = new TransparentPolicy(this, mWmService.mLetterboxConfiguration);
         mLetterboxUiController = new LetterboxUiController(mWmService, this);
+        mAppCompatController = new AppCompatController(mWmService, this);
         mCameraCompatControlEnabled = mWmService.mContext.getResources()
                 .getBoolean(R.bool.config_isCameraCompatControlForStretchedIssuesEnabled);
         mResolveConfigHint = new TaskFragment.ConfigOverrideHint();
@@ -2187,7 +2191,11 @@
                 realTheme, com.android.internal.R.styleable.Window, mUserId);
 
         if (ent != null) {
-            mOccludesParent = !ActivityInfo.isTranslucentOrFloating(ent.array)
+            final boolean styleTranslucent = ent.array.getBoolean(
+                    com.android.internal.R.styleable.Window_windowIsTranslucent, false);
+            mStyleFloating = ent.array.getBoolean(
+                    com.android.internal.R.styleable.Window_windowIsFloating, false);
+            mOccludesParent = !(styleTranslucent || mStyleFloating)
                     // This style is propagated to the main window attributes with
                     // FLAG_SHOW_WALLPAPER from PhoneWindow#generateLayout.
                     || ent.array.getBoolean(R.styleable.Window_windowShowWallpaper, false);
@@ -2196,6 +2204,7 @@
             mOptOutEdgeToEdge = ent.array.getBoolean(
                     R.styleable.Window_windowOptOutEdgeToEdgeEnforcement, false);
         } else {
+            mStyleFloating = false;
             mStyleFillsParent = mOccludesParent = true;
             noDisplay = false;
             mOptOutEdgeToEdge = false;
@@ -2916,14 +2925,10 @@
 
     /** Makes starting window always fill the associated task. */
     private void attachStartingSurfaceToAssociatedTask() {
-        if (mSyncState == SYNC_STATE_NONE && isEmbedded()) {
-            // Collect this activity since it's starting window will reparent to task. To ensure
-            // any starting window's transaction will occur in order.
-            mTransitionController.collect(this);
-        }
+        mTransitionController.collect(mStartingWindow);
         // Associate the configuration of starting window with the task.
         overrideConfigurationPropagation(mStartingWindow, mStartingData.mAssociatedTask);
-        getSyncTransaction().reparent(mStartingWindow.mSurfaceControl,
+        mStartingWindow.getSyncTransaction().reparent(mStartingWindow.mSurfaceControl,
                 mStartingData.mAssociatedTask.mSurfaceControl);
     }
 
@@ -3236,6 +3241,10 @@
         return occludesParent(true /* includingFinishing */);
     }
 
+    boolean isStyleFloating() {
+        return mStyleFloating;
+    }
+
     /** Returns true if this activity is not finishing, is opaque and fills the entire space of
      * this task. */
     boolean occludesParent() {
@@ -4505,6 +4514,7 @@
         mTaskSupervisor.getActivityMetricsLogger().notifyActivityRemoved(this);
         mTaskSupervisor.mStoppingActivities.remove(this);
         mLetterboxUiController.destroy();
+        mAppCompatController.getTransparentPolicy().stop();
 
         // Defer removal of this activity when either a child is animating, or app transition is on
         // going. App transition animation might be applied on the parent task not on the activity,
@@ -4576,9 +4586,6 @@
         if (!delayed) {
             updateReportedVisibilityLocked();
         }
-
-        // Reset the last saved PiP snap fraction on removal.
-        mDisplayContent.mPinnedTaskController.onActivityHidden(mActivityComponent);
         mDisplayContent.onRunningActivityChanged();
         mRemovingFromDisplay = false;
     }
@@ -6245,12 +6252,13 @@
             return false;
         }
 
-        // Check if there are any activities with different UID over the activity that is embedded
-        // in untrusted mode. Traverse bottom to top with boundary so that it will only check
-        // activities above this activity.
+        // Check if there are any activities with different UID occluding partially the activity
+        // that is embedded in untrusted mode. Traverse bottom to top with boundary so that it will
+        // only check activities above this activity.
         final ActivityRecord differentUidOverlayActivity = getTask().getActivity(
-                a -> !a.finishing && a.getUid() != getUid(), this /* boundary */,
-                false /* includeBoundary */, false /* traverseTopToBottom */);
+                a -> !a.finishing && a.getUid() != getUid() && Rect.intersects(a.getBounds(),
+                        getBounds()), this /* boundary */, false /* includeBoundary */,
+                false /* traverseTopToBottom */);
         return differentUidOverlayActivity != null;
     }
 
@@ -6527,9 +6535,7 @@
             // and the token could be null.
             return;
         }
-        if (r.mDisplayContent.mActivityRefresher != null) {
-            r.mDisplayContent.mActivityRefresher.onActivityRefreshed(r);
-        }
+        r.mDisplayContent.mAppCompatCameraPolicy.onActivityRefreshed(r);
     }
 
     static void splashScreenAttachedLocked(IBinder token) {
@@ -6563,7 +6569,12 @@
         // Schedule an idle timeout in case the app doesn't do it for us.
         mTaskSupervisor.scheduleIdleTimeout(this);
 
-        mTaskSupervisor.reportResumedActivityLocked(this);
+        mTaskSupervisor.mStoppingActivities.remove(this);
+        if (getDisplayArea().allResumedActivitiesComplete()) {
+            // Construct the compat environment at a relatively stable state if needed.
+            updateCompatDisplayInsets();
+            mRootWindowContainer.executeAppTransitionForAllDisplay();
+        }
 
         resumeKeyDispatchingLocked();
         final Task rootTask = getRootTask();
@@ -6736,8 +6747,6 @@
         if (task.mLastRecentsAnimationTransaction != null) {
             task.clearLastRecentsAnimationTransaction(true /* forceRemoveOverlay */);
         }
-        // Reset the last saved PiP snap fraction on app stop.
-        mDisplayContent.mPinnedTaskController.onActivityHidden(mActivityComponent);
         if (isClientVisible()) {
             // Though this is usually unlikely to happen, still make sure the client is invisible.
             setClientVisible(false);
@@ -6745,6 +6754,13 @@
         destroySurfaces();
         // Remove any starting window that was added for this app if they are still around.
         removeStartingWindow();
+        // This is unlikely to happen because the sequence of lifecycle should invoke
+        // finishRelaunching before being stopped. Reset the potential unpaired count in case
+        // the binder transaction of relaunch is failed, so the transition won't be blocked.
+        if (mPendingRelaunchCount > 0) {
+            Slog.i(TAG, "Clear pending relaunch count on stopped " + this);
+            clearRelaunching();
+        }
 
         if (finishing) {
             abortAndClearOptionsAnimation();
@@ -6968,14 +6984,11 @@
         updateReportedVisibilityLocked();
     }
 
-    /**
-     * Sets whether something has been visible in the task and returns {@code true} if the state
-     * is changed from invisible to visible.
-     */
-    private boolean setTaskHasBeenVisible() {
+    /** Sets whether something has been visible in the task. */
+    private void setTaskHasBeenVisible() {
         final boolean wasTaskVisible = task.getHasBeenVisible();
         if (wasTaskVisible) {
-            return false;
+            return;
         }
         if (inTransition()) {
             // The deferring will be canceled until transition is ready so it won't dispatch
@@ -6983,20 +6996,22 @@
             task.setDeferTaskAppear(true);
         }
         task.setHasBeenVisible(true);
-        return true;
     }
 
     void onStartingWindowDrawn() {
-        boolean wasTaskVisible = false;
         if (task != null) {
             mSplashScreenStyleSolidColor = true;
-            wasTaskVisible = !setTaskHasBeenVisible();
+            setTaskHasBeenVisible();
         }
+        if (mStartingData == null || mStartingData.mIsDisplayed) {
+            return;
+        }
+        mStartingData.mIsDisplayed = true;
 
         // The transition may not be executed if the starting process hasn't attached. But if the
         // starting window is drawn, the transition can start earlier. Exclude finishing and bubble
         // because it may be a trampoline.
-        if (!wasTaskVisible && mStartingData != null && !finishing && !mLaunchedFromBubble
+        if (app == null && !finishing && !mLaunchedFromBubble
                 && mVisibleRequested && !mDisplayContent.mAppTransition.isReady()
                 && !mDisplayContent.mAppTransition.isRunning()
                 && mDisplayContent.isNextTransitionForward()) {
@@ -7233,9 +7248,6 @@
                         isInterestingAndDrawn = true;
                     }
                 }
-            } else if (mStartingData != null && w.isDrawn()) {
-                // The starting window for this container is drawn.
-                mStartingData.mIsDisplayed = true;
             }
         }
 
@@ -7519,7 +7531,8 @@
      *               use an icon or solid color splash screen will be made by WmShell.
      */
     private boolean shouldUseSolidColorSplashScreen(ActivityRecord sourceRecord,
-            boolean startActivity, ActivityOptions options, int resolvedTheme) {
+            boolean startActivity, ActivityOptions options, int resolvedTheme,
+            boolean newTask) {
         if (sourceRecord == null && !startActivity) {
             // Use simple style if this activity is not top activity. This could happen when adding
             // a splash screen window to the warm start activity which is re-create because top is
@@ -7542,21 +7555,19 @@
 
         // Choose the default behavior when neither the ActivityRecord nor the activity theme have
         // specified a splash screen style.
-
-        if (mLaunchSourceType == LAUNCH_SOURCE_TYPE_HOME || launchedFromUid == Process.SHELL_UID) {
-            return false;
-        } else if (mLaunchSourceType == LAUNCH_SOURCE_TYPE_SYSTEMUI) {
+        if (mLaunchSourceType == LAUNCH_SOURCE_TYPE_SYSTEMUI) {
             return true;
         } else {
             // Need to check sourceRecord in case this activity is launched from a service.
             if (sourceRecord == null) {
                 sourceRecord = searchCandidateLaunchingActivity();
             }
-
             if (sourceRecord != null) {
-                return sourceRecord.mSplashScreenStyleSolidColor;
+                return sourceRecord.mSplashScreenStyleSolidColor; // follow previous activity
+            } else if (mLaunchSourceType == LAUNCH_SOURCE_TYPE_HOME
+                    || launchedFromUid == Process.SHELL_UID) {
+                return !newTask; // only show icon for new task
             }
-
             // Use an icon if the activity was launched from System for the first start.
             // Otherwise, must use solid color splash screen.
             return mLaunchSourceType != LAUNCH_SOURCE_TYPE_SYSTEM || !startActivity;
@@ -7624,7 +7635,7 @@
                 splashScreenTheme);
 
         mSplashScreenStyleSolidColor = shouldUseSolidColorSplashScreen(sourceRecord, startActivity,
-                startOptions, resolvedTheme);
+                startOptions, resolvedTheme, newTask);
 
         final boolean activityCreated =
                 mState.ordinal() >= STARTED.ordinal() && mState.ordinal() <= STOPPED.ordinal();
@@ -8102,13 +8113,13 @@
     @Configuration.Orientation
     int getRequestedConfigurationOrientation(boolean forDisplay,
             @ActivityInfo.ScreenOrientation int requestedOrientation) {
-        if (mTransparentPolicy.hasInheritedOrientation()) {
+        if (mAppCompatController.getTransparentPolicy().hasInheritedOrientation()) {
             final RootDisplayArea root = getRootDisplayArea();
             if (forDisplay && root != null && root.isOrientationDifferentFromDisplay()) {
                 return reverseConfigurationOrientation(
-                        mTransparentPolicy.getInheritedOrientation());
+                        mAppCompatController.getTransparentPolicy().getInheritedOrientation());
             } else {
-                return mTransparentPolicy.getInheritedOrientation();
+                return mAppCompatController.getTransparentPolicy().getInheritedOrientation();
             }
         }
         if (task != null && requestedOrientation == SCREEN_ORIENTATION_BEHIND) {
@@ -8181,7 +8192,8 @@
     }
 
     void setRequestedOrientation(@ActivityInfo.ScreenOrientation int requestedOrientation) {
-        if (mLetterboxUiController.shouldIgnoreRequestedOrientation(requestedOrientation)) {
+        if (mAppCompatController.getOrientationPolicy()
+                .shouldIgnoreRequestedOrientation(requestedOrientation)) {
             return;
         }
         final int originalRelaunchingCount = mPendingRelaunchCount;
@@ -8284,7 +8296,8 @@
      */
     @Override
     protected int getOverrideOrientation() {
-        return mLetterboxUiController.overrideOrientationIfNeeded(super.getOverrideOrientation());
+        return mAppCompatController.getOrientationPolicy()
+                .overrideOrientationIfNeeded(super.getOverrideOrientation());
     }
 
     /**
@@ -8324,8 +8337,8 @@
 
     @Nullable
     CompatDisplayInsets getCompatDisplayInsets() {
-        if (mTransparentPolicy.isRunning()) {
-            return mTransparentPolicy.getInheritedCompatDisplayInsets();
+        if (mAppCompatController.getTransparentPolicy().isRunning()) {
+            return mAppCompatController.getTransparentPolicy().getInheritedCompatDisplayInsets();
         }
         return mCompatDisplayInsets;
     }
@@ -8488,7 +8501,7 @@
         }
         mSizeCompatBounds = null;
         mCompatDisplayInsets = null;
-        mTransparentPolicy.clearInheritedCompatDisplayInsets();
+        mAppCompatController.getTransparentPolicy().clearInheritedCompatDisplayInsets();
     }
 
     @VisibleForTesting
@@ -8558,7 +8571,7 @@
         final int parentWindowingMode =
                 newParentConfiguration.windowConfiguration.getWindowingMode();
         final boolean isInCameraCompatFreeform = parentWindowingMode == WINDOWING_MODE_FREEFORM
-                && mLetterboxUiController.getFreeformCameraCompatMode()
+                && mAppCompatController.getAppCompatCameraOverrides().getFreeformCameraCompatMode()
                         != CAMERA_COMPAT_FREEFORM_NONE;
 
         // Bubble activities should always fill their parent and should not be letterboxed.
@@ -8675,7 +8688,7 @@
     }
 
     @Nullable Rect getParentAppBoundsOverride() {
-        return Rect.copyOrNull(mResolveConfigHint.mTmpParentAppBoundsOverride);
+        return Rect.copyOrNull(mResolveConfigHint.mParentAppBoundsOverride);
     }
 
     /**
@@ -8821,8 +8834,8 @@
             return APP_COMPAT_STATE_CHANGED__STATE__NOT_VISIBLE;
         }
         // TODO(b/256564921): Investigate if we need new metrics for translucent activities
-        if (mTransparentPolicy.isRunning()) {
-            return mTransparentPolicy.getInheritedAppCompatState();
+        if (mAppCompatController.getTransparentPolicy().isRunning()) {
+            return mAppCompatController.getTransparentPolicy().getInheritedAppCompatState();
         }
         if (mInSizeCompatModeForBounds) {
             return APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_SIZE_COMPAT_MODE;
@@ -8860,7 +8873,7 @@
         }
         final Rect screenResolvedBounds =
                 mSizeCompatBounds != null ? mSizeCompatBounds : resolvedBounds;
-        final Rect parentAppBounds = mResolveConfigHint.mTmpParentAppBoundsOverride;
+        final Rect parentAppBounds = mResolveConfigHint.mParentAppBoundsOverride;
         final Rect parentBounds = newParentConfiguration.windowConfiguration.getBounds();
         final float screenResolvedBoundsWidth = screenResolvedBounds.width();
         final float parentAppBoundsWidth = parentAppBounds.width();
@@ -8975,7 +8988,7 @@
         // We check if the current activity is transparent. In that case we need to
         // recomputeConfiguration of the first opaque activity beneath, to allow a
         // proper computation of the new bounds.
-        if (!mTransparentPolicy.applyOnOpaqueActivityBelow(
+        if (!mAppCompatController.getTransparentPolicy().applyOnOpaqueActivityBelow(
                 ActivityRecord::recomputeConfiguration)) {
             onRequestedOverrideConfigurationChanged(getRequestedOverrideConfiguration());
         }
@@ -8985,16 +8998,6 @@
         return inTransitionSelfOrParent();
     }
 
-    boolean isDisplaySleepingAndSwapping() {
-        for (int i = mDisplayContent.mAllSleepTokens.size() - 1; i >= 0; i--) {
-            RootWindowContainer.SleepToken sleepToken = mDisplayContent.mAllSleepTokens.get(i);
-            if (sleepToken.isDisplaySwapping()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     /**
      * Whether this activity is letterboxed for fixed orientation. If letterboxed due to fixed
      * orientation then aspect ratio restrictions are also already respected.
@@ -9269,7 +9272,7 @@
      */
     private void resolveAspectRatioRestriction(Configuration newParentConfiguration) {
         final Configuration resolvedConfig = getResolvedOverrideConfiguration();
-        final Rect parentAppBounds = mResolveConfigHint.mTmpParentAppBoundsOverride;
+        final Rect parentAppBounds = mResolveConfigHint.mParentAppBoundsOverride;
         final Rect parentBounds = newParentConfiguration.windowConfiguration.getBounds();
         final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds();
         // Use tmp bounds to calculate aspect ratio so we can know whether the activity should use
@@ -9310,7 +9313,7 @@
                 : newParentConfiguration.windowConfiguration.getBounds();
         final Rect containerAppBounds = useResolvedBounds
                 ? new Rect(resolvedConfig.windowConfiguration.getAppBounds())
-                : mResolveConfigHint.mTmpParentAppBoundsOverride;
+                : mResolveConfigHint.mParentAppBoundsOverride;
 
         final int requestedOrientation = getRequestedConfigurationOrientation();
         final boolean orientationRequested = requestedOrientation != ORIENTATION_UNDEFINED;
@@ -9435,7 +9438,8 @@
 
     void updateSizeCompatScale(Rect resolvedAppBounds, Rect containerAppBounds) {
         // Only allow to scale down.
-        mSizeCompatScale = mTransparentPolicy.findOpaqueNotFinishingActivityBelow()
+        mSizeCompatScale = mAppCompatController.getTransparentPolicy()
+                .findOpaqueNotFinishingActivityBelow()
                 .map(activityRecord -> activityRecord.mSizeCompatScale)
                 .orElseGet(() -> {
                     final int contentW = resolvedAppBounds.width();
@@ -9448,7 +9452,7 @@
     }
 
     private boolean isInSizeCompatModeForBounds(final Rect appBounds, final Rect containerBounds) {
-        if (mTransparentPolicy.isRunning()) {
+        if (mAppCompatController.getTransparentPolicy().isRunning()) {
             // To avoid wrong app behaviour, we decided to disable SCM when a translucent activity
             // is letterboxed.
             return false;
@@ -9511,7 +9515,7 @@
     public Rect getBounds() {
         // TODO(b/268458693): Refactor configuration inheritance in case of translucent activities
         final Rect superBounds = super.getBounds();
-        return mTransparentPolicy.findOpaqueNotFinishingActivityBelow()
+        return mAppCompatController.getTransparentPolicy().findOpaqueNotFinishingActivityBelow()
                 .map(ActivityRecord::getBounds)
                 .orElseGet(() -> {
                     if (mSizeCompatBounds != null) {
@@ -9875,8 +9879,8 @@
      * Returns the min aspect ratio of this activity.
      */
     float getMinAspectRatio() {
-        if (mTransparentPolicy.isRunning()) {
-            return mTransparentPolicy.getInheritedMinAspectRatio();
+        if (mAppCompatController.getTransparentPolicy().isRunning()) {
+            return mAppCompatController.getTransparentPolicy().getInheritedMinAspectRatio();
         }
         if (info.applicationInfo == null) {
             return info.getMinAspectRatio();
@@ -9885,7 +9889,8 @@
             return mLetterboxUiController.getUserMinAspectRatio();
         }
         if (!mLetterboxUiController.shouldOverrideMinAspectRatio()
-                && !mLetterboxUiController.shouldOverrideMinAspectRatioForCamera()) {
+                && !mAppCompatController.getAppCompatCameraOverrides()
+                    .shouldOverrideMinAspectRatioForCamera()) {
             return info.getMinAspectRatio();
         }
         if (info.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_PORTRAIT_ONLY)
@@ -9915,6 +9920,11 @@
             return Math.max(ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM_VALUE,
                     info.getMinAspectRatio());
         }
+
+        if (info.isChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_SMALL)) {
+            return Math.max(ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_SMALL_VALUE,
+                    info.getMinAspectRatio());
+        }
         return info.getMinAspectRatio();
     }
 
@@ -9926,8 +9936,8 @@
     }
 
     float getMaxAspectRatio() {
-        if (mTransparentPolicy.isRunning()) {
-            return mTransparentPolicy.getInheritedMaxAspectRatio();
+        if (mAppCompatController.getTransparentPolicy().isRunning()) {
+            return mAppCompatController.getTransparentPolicy().getInheritedMaxAspectRatio();
         }
         return info.getMaxAspectRatio();
     }
@@ -10008,16 +10018,6 @@
         return updateReportedConfigurationAndSend();
     }
 
-    /**
-     * @return {@code true} if the Camera is active for the current activity
-     */
-    boolean isCameraActive() {
-        return mDisplayContent != null
-                && mDisplayContent.getDisplayRotationCompatPolicy() != null
-                && mDisplayContent.getDisplayRotationCompatPolicy()
-                    .isCameraActive(this, /* mustBeFullscreen */ true);
-    }
-
     boolean updateReportedConfigurationAndSend() {
         if (isConfigurationDispatchPaused()) {
             Slog.wtf(TAG, "trying to update reported(client) config while dispatch is paused");
@@ -10165,11 +10165,10 @@
 
     private void notifyActivityRefresherAboutConfigurationChange(
             Configuration newConfig, Configuration lastReportedConfig) {
-        if (mDisplayContent.mActivityRefresher == null
-                || !shouldBeResumed(/* activeActivity */ null)) {
+        if (!shouldBeResumed(/* activeActivity */ null)) {
             return;
         }
-        mDisplayContent.mActivityRefresher.onActivityConfigurationChanging(
+        mDisplayContent.mAppCompatCameraPolicy.onActivityConfigurationChanging(
                 this, newConfig, lastReportedConfig);
     }
 
@@ -10302,7 +10301,7 @@
         if (rootTask != null && rootTask.mTranslucentActivityWaiting == this) {
             rootTask.checkTranslucentActivityWaiting(null);
         }
-        final boolean andResume = shouldBeResumed(null /*activeActivity*/);
+        final boolean andResume = isState(RESUMED) || shouldBeResumed(null /*activeActivity*/);
         List<ResultInfo> pendingResults = null;
         List<ReferrerIntent> pendingNewIntents = null;
         if (andResume) {
@@ -10807,15 +10806,19 @@
         proto.write(OVERRIDE_ORIENTATION, getOverrideOrientation());
         proto.write(SHOULD_SEND_COMPAT_FAKE_FOCUS, shouldSendCompatFakeFocus());
         proto.write(SHOULD_FORCE_ROTATE_FOR_CAMERA_COMPAT,
-                mLetterboxUiController.shouldForceRotateForCameraCompat());
+                mAppCompatController.getAppCompatCameraOverrides()
+                        .shouldForceRotateForCameraCompat());
         proto.write(SHOULD_REFRESH_ACTIVITY_FOR_CAMERA_COMPAT,
-                mLetterboxUiController.shouldRefreshActivityForCameraCompat());
+                mAppCompatController.getAppCompatCameraOverrides()
+                        .shouldRefreshActivityForCameraCompat());
         proto.write(SHOULD_REFRESH_ACTIVITY_VIA_PAUSE_FOR_CAMERA_COMPAT,
-                mLetterboxUiController.shouldRefreshActivityViaPauseForCameraCompat());
+                mAppCompatController.getAppCompatCameraOverrides()
+                        .shouldRefreshActivityViaPauseForCameraCompat());
         proto.write(SHOULD_OVERRIDE_MIN_ASPECT_RATIO,
                 mLetterboxUiController.shouldOverrideMinAspectRatio());
         proto.write(SHOULD_IGNORE_ORIENTATION_REQUEST_LOOP,
-                mLetterboxUiController.shouldIgnoreOrientationRequestLoop());
+                mAppCompatController.getAppCompatOrientationOverrides()
+                        .shouldIgnoreOrientationRequestLoop());
         proto.write(SHOULD_OVERRIDE_FORCE_RESIZE_APP,
                 mLetterboxUiController.shouldOverrideForceResizeApp());
         proto.write(SHOULD_ENABLE_USER_ASPECT_RATIO_SETTINGS,
@@ -11147,8 +11150,7 @@
             boolean cancel) {
         // This override is just for getting metrics. allFinished needs to be checked before
         // finish because finish resets all the states.
-        final BLASTSyncEngine.SyncGroup syncGroup = getSyncGroup();
-        if (syncGroup != null && group != getSyncGroup()) return;
+        if (isDifferentSyncGroup(group)) return;
         mLastAllReadyAtSync = allSyncFinished();
         super.finishSync(outMergedTransaction, group, cancel);
     }
diff --git a/services/core/java/com/android/server/wm/ActivityRefresher.java b/services/core/java/com/android/server/wm/ActivityRefresher.java
index 23a9708..0c32dfc 100644
--- a/services/core/java/com/android/server/wm/ActivityRefresher.java
+++ b/services/core/java/com/android/server/wm/ActivityRefresher.java
@@ -27,7 +27,7 @@
 import android.os.Handler;
 import android.os.RemoteException;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.ArrayUtils;
 
 import java.util.ArrayList;
@@ -77,10 +77,10 @@
         final boolean cycleThroughStop =
                 mWmService.mLetterboxConfiguration
                         .isCameraCompatRefreshCycleThroughStopEnabled()
-                        && !activity.mLetterboxUiController
-                        .shouldRefreshActivityViaPauseForCameraCompat();
+                        && !activity.mAppCompatController.getAppCompatCameraOverrides()
+                            .shouldRefreshActivityViaPauseForCameraCompat();
 
-        activity.mLetterboxUiController.setIsRefreshRequested(true);
+        activity.mAppCompatController.getAppCompatCameraOverrides().setIsRefreshRequested(true);
         ProtoLog.v(WM_DEBUG_STATES,
                 "Refreshing activity for freeform camera compatibility treatment, "
                         + "activityRecord=%s", activity);
@@ -97,24 +97,26 @@
                 }
             }, REFRESH_CALLBACK_TIMEOUT_MS);
         } catch (RemoteException e) {
-            activity.mLetterboxUiController.setIsRefreshRequested(false);
+            activity.mAppCompatController.getAppCompatCameraOverrides()
+                    .setIsRefreshRequested(false);
         }
     }
 
     boolean isActivityRefreshing(@NonNull ActivityRecord activity) {
-        return activity.mLetterboxUiController.isRefreshRequested();
+        return activity.mAppCompatController.getAppCompatCameraOverrides().isRefreshRequested();
     }
 
     void onActivityRefreshed(@NonNull ActivityRecord activity) {
         // TODO(b/333060789): can we tell that refresh did not happen by observing the activity
         //  state?
-        activity.mLetterboxUiController.setIsRefreshRequested(false);
+        activity.mAppCompatController.getAppCompatCameraOverrides().setIsRefreshRequested(false);
     }
 
     private boolean shouldRefreshActivity(@NonNull ActivityRecord activity,
             @NonNull Configuration newConfig, @NonNull Configuration lastReportedConfig) {
         return mWmService.mLetterboxConfiguration.isCameraCompatRefreshEnabled()
-                && activity.mLetterboxUiController.shouldRefreshActivityForCameraCompat()
+                && activity.mAppCompatController.getAppCompatOverrides()
+                    .getAppCompatCameraOverrides().shouldRefreshActivityForCameraCompat()
                 && ArrayUtils.find(mEvaluators.toArray(), evaluator ->
                 ((Evaluator) evaluator)
                         .shouldRefreshActivity(activity, newConfig, lastReportedConfig)) != null;
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index 0e401eb..a0ef030 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -424,19 +424,13 @@
                 Intent intent = intents[i];
                 NeededUriGrants intentGrants = null;
 
-                // Refuse possible leaked file descriptors.
-                if (intent.hasFileDescriptors()) {
-                    throw new IllegalArgumentException("File descriptors passed in Intent");
-                }
+                intent.prepareToEnterSystemServer();
 
                 // Get the flag earlier because the intent may be modified in resolveActivity below.
                 final boolean componentSpecified = intent.getComponent() != null;
                 // Don't modify the client's object!
                 intent = new Intent(intent);
 
-                // Remove existing mismatch flag so it can be properly updated later
-                intent.removeExtendedFlags(Intent.EXTENDED_FLAG_FILTER_MISMATCH);
-
                 // Collect information about the target of the Intent.
                 ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i],
                         0 /* startFlags */, null /* profilerInfo */, userId, filterCallingUid,
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index e6d8132..5bfe9d7 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -127,7 +127,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.HeavyWeightSwitcherActivity;
 import com.android.internal.app.IVoiceInteractor;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.am.PendingIntentRecord;
 import com.android.server.pm.InstantAppResolver;
 import com.android.server.pm.PackageArchiver;
@@ -718,13 +718,7 @@
             onExecutionStarted();
 
             if (mRequest.intent != null) {
-                // Refuse possible leaked file descriptors
-                if (mRequest.intent.hasFileDescriptors()) {
-                    throw new IllegalArgumentException("File descriptors passed in Intent");
-                }
-
-                // Remove existing mismatch flag so it can be properly updated later
-                mRequest.intent.removeExtendedFlags(Intent.EXTENDED_FLAG_FILTER_MISMATCH);
+                mRequest.intent.prepareToEnterSystemServer();
             }
 
             final LaunchingState launchingState;
@@ -1655,7 +1649,8 @@
                 // activity, so this isn't just deliver-to-top
                 && mMovedToTopActivity == null
                 && !transitionController.hasOrderChanges()
-                && !transitionController.isTransientHide(startedActivityRootTask)) {
+                && !transitionController.isTransientHide(startedActivityRootTask)
+                && !newTransition.hasChanged(mLastStartActivityRecord)) {
             // We just delivered to top, so there isn't an actual transition here.
             if (!forceTransientTransition) {
                 newTransition.abort();
@@ -1798,6 +1793,7 @@
                     activity.destroyIfPossible("Removes redundant singleInstance");
                 }
             }
+            targetTaskTop.mTransitionController.collect(targetTaskTop);
             recordTransientLaunchIfNeeded(targetTaskTop);
             // Recycle the target task for this launch.
             startResult =
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index c088118..3b0b727 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -145,13 +145,6 @@
         void acquire(int displayId);
 
         /**
-         * Acquires a sleep token.
-         * @param displayId The display to apply to.
-         * @param isSwappingDisplay Whether the display is swapping to another physical display.
-         */
-        void acquire(int displayId, boolean isSwappingDisplay);
-
-        /**
          * Releases the sleep token.
          * @param displayId The display to apply to.
          */
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index cfd5300..5b17875 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -260,7 +260,7 @@
 import com.android.internal.os.TransferPipe;
 import com.android.internal.policy.AttributeCache;
 import com.android.internal.policy.KeyguardDismissCallback;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.FrameworkStatsLog;
@@ -1318,12 +1318,7 @@
             String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
         enforceNotIsolatedCaller("startActivityIntentSender");
         if (fillInIntent != null) {
-            // Refuse possible leaked file descriptors
-            if (fillInIntent.hasFileDescriptors()) {
-                throw new IllegalArgumentException("File descriptors passed in Intent");
-            }
-            // Remove existing mismatch flag so it can be properly updated later
-            fillInIntent.removeExtendedFlags(Intent.EXTENDED_FLAG_FILTER_MISMATCH);
+            fillInIntent.prepareToEnterSystemServer();
         }
 
         if (!(target instanceof PendingIntentRecord)) {
@@ -1349,10 +1344,10 @@
     @Override
     public boolean startNextMatchingActivity(IBinder callingActivity, Intent intent,
             Bundle bOptions) {
-        // Refuse possible leaked file descriptors
-        if (intent != null && intent.hasFileDescriptors()) {
-            throw new IllegalArgumentException("File descriptors passed in Intent");
+        if (intent != null) {
+            intent.prepareToEnterSystemServer();
         }
+
         SafeActivityOptions options = SafeActivityOptions.fromBundle(bOptions);
 
         synchronized (mGlobalLock) {
@@ -1367,8 +1362,6 @@
                 return false;
             }
             intent = new Intent(intent);
-            // Remove existing mismatch flag so it can be properly updated later
-            intent.removeExtendedFlags(Intent.EXTENDED_FLAG_FILTER_MISMATCH);
             // The caller is not allowed to change the data.
             intent.setDataAndType(r.intent.getData(), r.intent.getType());
             // And we are resetting to find the next component...
@@ -5063,16 +5056,10 @@
 
         @Override
         public void acquire(int displayId) {
-            acquire(displayId, false /* isSwappingDisplay */);
-        }
-
-        @Override
-        public void acquire(int displayId, boolean isSwappingDisplay) {
             synchronized (mGlobalLock) {
                 if (!mSleepTokens.contains(displayId)) {
                     mSleepTokens.append(displayId,
-                            mRootWindowContainer.createSleepToken(mTag, displayId,
-                                    isSwappingDisplay));
+                            mRootWindowContainer.createSleepToken(mTag, displayId));
                     updateSleepIfNeededLocked();
                 }
             }
@@ -6199,11 +6186,14 @@
             synchronized (mGlobalLockWithoutBoost) {
                 final WindowProcessController proc = mProcessNames.remove(name, uid);
                 if (proc != null && !mStartingProcessActivities.isEmpty()) {
-                    for (int i = mStartingProcessActivities.size() - 1; i >= 0; i--) {
-                        final ActivityRecord r = mStartingProcessActivities.get(i);
+                    // Use a copy in case finishIfPossible changes the list indirectly.
+                    final ArrayList<ActivityRecord> activities =
+                            new ArrayList<>(mStartingProcessActivities);
+                    for (int i = activities.size() - 1; i >= 0; i--) {
+                        final ActivityRecord r = activities.get(i);
                         if (uid == r.info.applicationInfo.uid && name.equals(r.processName)) {
                             Slog.w(TAG, proc + " is removed with pending start " + r);
-                            mStartingProcessActivities.remove(i);
+                            mStartingProcessActivities.remove(r);
                             // If visible, finish it to avoid getting stuck on screen.
                             if (r.isVisibleRequested()) {
                                 r.finishIfPossible("starting-proc-removed", false /* oomAdj */);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 3867d2d..e81b440 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -38,6 +38,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.Intent.ACTION_VIEW;
 import static android.content.pm.PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY;
 import static android.content.pm.PackageManager.PERMISSION_DENIED;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -121,6 +122,7 @@
 import android.graphics.Rect;
 import android.hardware.SensorPrivacyManager;
 import android.hardware.SensorPrivacyManagerInternal;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -142,13 +144,14 @@
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.view.Display;
+import android.webkit.URLUtil;
 import android.window.ActivityWindowInfo;
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.ReferrerIntent;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.LocalServices;
@@ -158,6 +161,7 @@
 import com.android.server.pm.SaferIntentUtils;
 import com.android.server.utils.Slogf;
 import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
+import com.android.window.flags.Flags;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -189,9 +193,6 @@
     // How long we can hold the launch wake lock before giving up.
     private static final int LAUNCH_TIMEOUT = 10 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
 
-    // How long we delay processing the stopping and finishing activities.
-    private static final int SCHEDULE_FINISHING_STOPPING_ACTIVITY_MS = 200;
-
     /** How long we wait until giving up on the activity telling us it released the top state. */
     private static final int TOP_RESUMED_STATE_LOSS_TIMEOUT = 500;
 
@@ -952,7 +953,7 @@
                 // Schedule transaction.
                 if (shouldDispatchLaunchActivityItemIndependently(r.info.packageName, r.getUid())) {
                     // LaunchActivityItem has @UnsupportedAppUsage usages.
-                    // Guard the bundleClientTransactionFlag feature with targetSDK on Android 15+.
+                    // Guard with targetSDK on Android 15+.
                     // To not bundle the transaction, dispatch the pending before schedule new
                     // transaction.
                     mService.getLifecycleManager().dispatchPendingTransaction(proc.getThread());
@@ -2064,21 +2065,6 @@
         }
     }
 
-    boolean reportResumedActivityLocked(ActivityRecord r) {
-        // A resumed activity cannot be stopping. remove from list
-        mStoppingActivities.remove(r);
-
-        final Task rootTask = r.getRootTask();
-        if (rootTask.getDisplayArea().allResumedActivitiesComplete()) {
-            mRootWindowContainer.ensureActivitiesVisible();
-            // Make sure activity & window visibility should be identical
-            // for all displays in this stage.
-            mRootWindowContainer.executeAppTransitionForAllDisplay();
-            return true;
-        }
-        return false;
-    }
-
     // Called when WindowManager has finished animating the launchingBehind activity to the back.
     private void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) {
         final Task task = r.getTask();
@@ -2108,7 +2094,6 @@
             boolean processPausingActivities, String reason) {
         // Stop any activities that are scheduled to do so but have been waiting for the transition
         // animation to finish.
-        boolean displaySwapping = false;
         ArrayList<ActivityRecord> readyToStopActivities = null;
         for (int i = 0; i < mStoppingActivities.size(); i++) {
             final ActivityRecord s = mStoppingActivities.get(i);
@@ -2116,10 +2101,9 @@
             // send onStop before any configuration change when removing pip transition is ongoing.
             final boolean animating = s.isInTransition()
                     && s.getTask() != null && !s.getTask().isForceHidden();
-            displaySwapping |= s.isDisplaySleepingAndSwapping();
             ProtoLog.v(WM_DEBUG_STATES, "Stopping %s: nowVisible=%b animating=%b "
                     + "finishing=%s", s, s.nowVisible, animating, s.finishing);
-            if ((!animating && !displaySwapping) || mService.mShuttingDown
+            if (!animating || mService.mShuttingDown
                     || s.getRootTask().isForceHiddenForPinnedTask()) {
                 if (!processPausingActivities && s.isState(PAUSING)) {
                     // Defer processing pausing activities in this iteration and reschedule
@@ -2140,16 +2124,6 @@
             }
         }
 
-        // Stopping activities are deferred processing if the display is swapping. Check again
-        // later to ensure the stopping activities can be stopped after display swapped.
-        if (displaySwapping) {
-            mHandler.postDelayed(() -> {
-                synchronized (mService.mGlobalLock) {
-                    scheduleProcessStoppingAndFinishingActivitiesIfNeeded();
-                }
-            }, SCHEDULE_FINISHING_STOPPING_ACTIVITY_MS);
-        }
-
         final int numReadyStops = readyToStopActivities == null ? 0 : readyToStopActivities.size();
         for (int i = 0; i < numReadyStops; i++) {
             final ActivityRecord r = readyToStopActivities.get(i);
@@ -2752,9 +2726,9 @@
         final ActivityOptions activityOptions = options != null
                 ? options.getOptions(this)
                 : null;
-        boolean moveHomeTaskForward = true;
         synchronized (mService.mGlobalLock) {
             final boolean isCallerRecents = mRecentTasks.isCallerRecents(callingUid);
+            boolean moveHomeTaskForward = isCallerRecents;
             int activityType = ACTIVITY_TYPE_UNDEFINED;
             if (activityOptions != null) {
                 activityType = activityOptions.getLaunchActivityType();
@@ -2930,6 +2904,9 @@
 
         @Override
         public void accept(ActivityRecord r) {
+            if (Flags.enableDesktopWindowingAppToWeb() && mInfo.capturedLink == null) {
+                setCapturedLink(r);
+            }
             if (r.mLaunchCookie != null) {
                 mInfo.addLaunchCookie(r.mLaunchCookie);
             }
@@ -2942,6 +2919,16 @@
                 mTopRunning = r;
             }
         }
+
+        private void setCapturedLink(ActivityRecord r) {
+            final Uri uri = r.intent.getData();
+            if (uri == null || !ACTION_VIEW.equals(r.intent.getAction())
+                    || !URLUtil.isNetworkUrl(uri.toString())) {
+                return;
+            }
+            mInfo.capturedLink = uri;
+            mInfo.capturedLinkTimestamp = r.lastLaunchTime;
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/AnrController.java b/services/core/java/com/android/server/wm/AnrController.java
index 0013c5c..80671ef 100644
--- a/services/core/java/com/android/server/wm/AnrController.java
+++ b/services/core/java/com/android/server/wm/AnrController.java
@@ -345,7 +345,7 @@
                     null /* processCpuTracker */, null /* lastPids */,
                     CompletableFuture.completedFuture(nativePids),
                     null /* logExceptionCreatingFile */, "Pre-dump", criticalEvents,
-                    Runnable::run, null/* AnrLatencyTracker */);
+                    null /* extraHeaders */, Runnable::run, null/* AnrLatencyTracker */);
             if (tracesFile != null) {
                 tracesFile.renameTo(
                         new File(tracesFile.getParent(), tracesFile.getName() + "_pre"));
diff --git a/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java b/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java
new file mode 100644
index 0000000..0d108e1
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AppCompatCameraOverrides.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
+import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA;
+import static android.content.pm.ActivityInfo.OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE;
+
+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.app.CameraCompatTaskInfo.FreeformCameraCompatMode;
+
+import com.android.server.wm.utils.OptPropFactory;
+import com.android.window.flags.Flags;
+
+import java.util.function.BooleanSupplier;
+
+/**
+ * Encapsulates app compat configurations and overrides related to camera.
+ */
+class AppCompatCameraOverrides {
+
+    private static final String TAG = TAG_WITH_CLASS_NAME
+            ? "AppCompatCameraOverrides" : TAG_ATM;
+
+    @NonNull
+    private final ActivityRecord mActivityRecord;
+    @NonNull
+    private final AppCompatCameraOverridesState mAppCompatCameraOverridesState;
+    @NonNull
+    private final LetterboxConfiguration mLetterboxConfiguration;
+    @NonNull
+    private final OptPropFactory.OptProp mAllowMinAspectRatioOverrideOptProp;
+    @NonNull
+    private final OptPropFactory.OptProp mCameraCompatAllowRefreshOptProp;
+    @NonNull
+    private final OptPropFactory.OptProp mCameraCompatEnableRefreshViaPauseOptProp;
+    @NonNull
+    private final OptPropFactory.OptProp mCameraCompatAllowForceRotationOptProp;
+
+    AppCompatCameraOverrides(@NonNull ActivityRecord activityRecord,
+            @NonNull LetterboxConfiguration letterboxConfiguration,
+            @NonNull OptPropFactory optPropBuilder) {
+        mActivityRecord = activityRecord;
+        mLetterboxConfiguration = letterboxConfiguration;
+        mAppCompatCameraOverridesState = new AppCompatCameraOverridesState();
+        mAllowMinAspectRatioOverrideOptProp = optPropBuilder.create(
+                PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE);
+        final BooleanSupplier isCameraCompatTreatmentEnabled = AppCompatUtils.asLazy(
+                mLetterboxConfiguration::isCameraCompatTreatmentEnabled);
+        mCameraCompatAllowRefreshOptProp = optPropBuilder.create(
+                PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH,
+                isCameraCompatTreatmentEnabled);
+        mCameraCompatEnableRefreshViaPauseOptProp = optPropBuilder.create(
+                PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE,
+                isCameraCompatTreatmentEnabled);
+        mCameraCompatAllowForceRotationOptProp = optPropBuilder.create(
+                PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION,
+                isCameraCompatTreatmentEnabled);
+    }
+
+    /**
+     * Whether we should apply the min aspect ratio per-app override only when an app is connected
+     * to the camera.
+     * When this override is applied the min aspect ratio given in the app's manifest will be
+     * overridden to the largest enabled aspect ratio treatment unless the app's manifest value
+     * is higher. The treatment will also apply if no value is provided in the manifest.
+     *
+     * <p>This method returns {@code true} when the following conditions are met:
+     * <ul>
+     *     <li>Opt-out component property isn't enabled
+     *     <li>Per-app override is enabled
+     * </ul>
+     */
+    boolean shouldOverrideMinAspectRatioForCamera() {
+        return isCameraActive() && mAllowMinAspectRatioOverrideOptProp
+                .shouldEnableWithOptInOverrideAndOptOutProperty(
+                        isCompatChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA));
+    }
+
+    /**
+     * Whether activity is eligible for activity "refresh" after camera compat force rotation
+     * treatment. See {@link DisplayRotationCompatPolicy} for context.
+     *
+     * <p>This treatment is enabled when the following conditions are met:
+     * <ul>
+     *     <li>Flag gating the camera compat treatment is enabled.
+     *     <li>Activity isn't opted out by the device manufacturer with override or by the app
+     *     developers with the component property.
+     * </ul>
+     */
+    boolean shouldRefreshActivityForCameraCompat() {
+        return mCameraCompatAllowRefreshOptProp.shouldEnableWithOptOutOverrideAndProperty(
+                isCompatChangeEnabled(OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH));
+    }
+
+    /**
+     * Whether activity should be "refreshed" after the camera compat force rotation treatment
+     * using the "resumed -> paused -> resumed" cycle rather than the "resumed -> ... -> stopped
+     * -> ... -> resumed" cycle. See {@link DisplayRotationCompatPolicy} for context.
+     *
+     * <p>This treatment is enabled when the following conditions are met:
+     * <ul>
+     *     <li>Flag gating the camera compat treatment is enabled.
+     *     <li>Activity "refresh" via "resumed -> paused -> resumed" cycle isn't disabled with the
+     *     component property by the app developers.
+     *     <li>Activity "refresh" via "resumed -> paused -> resumed" cycle is enabled by the device
+     *     manufacturer with override / by the app developers with the component property.
+     * </ul>
+     */
+    boolean shouldRefreshActivityViaPauseForCameraCompat() {
+        return mCameraCompatEnableRefreshViaPauseOptProp.shouldEnableWithOverrideAndProperty(
+                isCompatChangeEnabled(OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE));
+    }
+
+    /**
+     * Whether activity is eligible for camera compat force rotation treatment. See {@link
+     * DisplayRotationCompatPolicy} for context.
+     *
+     * <p>This treatment is enabled when the following conditions are met:
+     * <ul>
+     *     <li>Flag gating the camera compat treatment is enabled.
+     *     <li>Activity isn't opted out by the device manufacturer with override or by the app
+     *     developers with the component property.
+     * </ul>
+     */
+    boolean shouldForceRotateForCameraCompat() {
+        return mCameraCompatAllowForceRotationOptProp.shouldEnableWithOptOutOverrideAndProperty(
+                isCompatChangeEnabled(OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION));
+    }
+
+    /**
+     * Whether activity is eligible for camera compatibility free-form treatment.
+     *
+     * <p>The treatment is applied to a fixed-orientation camera activity in free-form windowing
+     * mode. The treatment letterboxes or pillarboxes the activity to the expected orientation and
+     * provides changes to the camera and display orientation signals to match those expected on a
+     * portrait device in that orientation (for example, on a standard phone).
+     *
+     * <p>The treatment is enabled when the following conditions are met:
+     * <ul>
+     * <li>Property gating the camera compatibility free-form treatment is enabled.
+     * <li>Activity isn't opted out by the device manufacturer with override.
+     * </ul>
+     */
+    boolean shouldApplyFreeformTreatmentForCameraCompat() {
+        return Flags.cameraCompatForFreeform() && !isCompatChangeEnabled(
+                OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT);
+    }
+
+    /**
+     * @return {@code true} if the Camera is active for the current activity
+     */
+    boolean isCameraActive() {
+        return mActivityRecord.mDisplayContent != null
+                && mActivityRecord.mDisplayContent.mAppCompatCameraPolicy
+                    .isCameraActive(mActivityRecord, /* mustBeFullscreen */ true);
+    }
+
+    /**
+     * @return {@code true} if the configuration needs to be recomputed after a camera state update.
+     */
+    boolean shouldRecomputeConfigurationForCameraCompat() {
+        return isOverrideOrientationOnlyForCameraEnabled()
+                || isCameraCompatSplitScreenAspectRatioAllowed()
+                || shouldOverrideMinAspectRatioForCamera();
+    }
+
+    boolean isOverrideOrientationOnlyForCameraEnabled() {
+        return isCompatChangeEnabled(OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA);
+    }
+
+    /**
+     * Whether activity "refresh" was requested but not finished in {@link #activityResumedLocked}.
+     */
+    boolean isRefreshRequested() {
+        return mAppCompatCameraOverridesState.mIsRefreshRequested;
+    }
+
+    /**
+     * @param isRequested Whether activity "refresh" was requested but not finished
+     *                    in {@link #activityResumedLocked}.
+     */
+    void setIsRefreshRequested(boolean isRequested) {
+        mAppCompatCameraOverridesState.mIsRefreshRequested = isRequested;
+    }
+
+    /**
+     * Whether we use split screen aspect ratio for the activity when camera compat treatment
+     * is active because the corresponding config is enabled and activity supports resizing.
+     */
+    boolean isCameraCompatSplitScreenAspectRatioAllowed() {
+        return mLetterboxConfiguration.isCameraCompatSplitScreenAspectRatioEnabled()
+                && !mActivityRecord.shouldCreateCompatDisplayInsets();
+    }
+
+    @FreeformCameraCompatMode
+    int getFreeformCameraCompatMode() {
+        return mAppCompatCameraOverridesState.mFreeformCameraCompatMode;
+    }
+
+    void setFreeformCameraCompatMode(@FreeformCameraCompatMode int freeformCameraCompatMode) {
+        mAppCompatCameraOverridesState.mFreeformCameraCompatMode = freeformCameraCompatMode;
+    }
+
+    private boolean isCompatChangeEnabled(long overrideChangeId) {
+        return mActivityRecord.info.isChangeEnabled(overrideChangeId);
+    }
+
+    static class AppCompatCameraOverridesState {
+        // Whether activity "refresh" was requested but not finished in
+        // ActivityRecord#activityResumedLocked following the camera compat force rotation in
+        // DisplayRotationCompatPolicy.
+        private boolean mIsRefreshRequested;
+
+        @FreeformCameraCompatMode
+        private int mFreeformCameraCompatMode = CAMERA_COMPAT_FREEFORM_NONE;
+    }
+}
diff --git a/services/core/java/com/android/server/wm/AppCompatCameraPolicy.java b/services/core/java/com/android/server/wm/AppCompatCameraPolicy.java
new file mode 100644
index 0000000..53729a2
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AppCompatCameraPolicy.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_UNSPECIFIED;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.pm.ActivityInfo.ScreenOrientation;
+import android.content.res.Configuration;
+import android.widget.Toast;
+
+import com.android.window.flags.Flags;
+
+/**
+ * Encapsulate policy logic related to app compat display rotation.
+ */
+class AppCompatCameraPolicy {
+
+    @Nullable
+    private final CameraStateMonitor mCameraStateMonitor;
+    @Nullable
+    private final ActivityRefresher mActivityRefresher;
+    @Nullable
+    final DisplayRotationCompatPolicy mDisplayRotationCompatPolicy;
+    @Nullable
+    final CameraCompatFreeformPolicy mCameraCompatFreeformPolicy;
+
+    AppCompatCameraPolicy(@NonNull WindowManagerService wmService,
+            @NonNull DisplayContent displayContent) {
+        // Not checking DeviceConfig value here to allow enabling via DeviceConfig
+        // without the need to restart the device.
+        final boolean needsDisplayRotationCompatPolicy =
+                wmService.mLetterboxConfiguration.isCameraCompatTreatmentEnabledAtBuildTime();
+        final boolean needsCameraCompatFreeformPolicy = Flags.cameraCompatForFreeform()
+                && DesktopModeLaunchParamsModifier.canEnterDesktopMode(wmService.mContext);
+        if (needsDisplayRotationCompatPolicy || needsCameraCompatFreeformPolicy) {
+            mCameraStateMonitor = new CameraStateMonitor(displayContent, wmService.mH);
+            mActivityRefresher = new ActivityRefresher(wmService, wmService.mH);
+            mDisplayRotationCompatPolicy =
+                    needsDisplayRotationCompatPolicy ? new DisplayRotationCompatPolicy(
+                            displayContent, mCameraStateMonitor, mActivityRefresher) : null;
+            mCameraCompatFreeformPolicy =
+                    needsCameraCompatFreeformPolicy ? new CameraCompatFreeformPolicy(displayContent,
+                            mCameraStateMonitor, mActivityRefresher) : null;
+        } else {
+            mDisplayRotationCompatPolicy = null;
+            mCameraCompatFreeformPolicy = null;
+            mCameraStateMonitor = null;
+            mActivityRefresher = null;
+        }
+    }
+
+    void onActivityRefreshed(@NonNull ActivityRecord activity) {
+        if (mActivityRefresher != null) {
+            mActivityRefresher.onActivityRefreshed(activity);
+        }
+    }
+
+    /**
+     * "Refreshes" activity by going through "stopped -> resumed" or "paused -> resumed" cycle.
+     * This allows to clear cached values in apps (e.g. display or camera rotation) that influence
+     * camera preview and can lead to sideways or stretching issues persisting even after force
+     * rotation.
+     */
+    void onActivityConfigurationChanging(@NonNull ActivityRecord activity,
+            @NonNull Configuration newConfig, @NonNull Configuration lastReportedConfig) {
+        if (mActivityRefresher != null) {
+            mActivityRefresher.onActivityConfigurationChanging(activity, newConfig,
+                    lastReportedConfig);
+        }
+    }
+
+    /**
+     * Notifies that animation in {@link ScreenRotationAnimation} has finished.
+     *
+     * <p>This class uses this signal as a trigger for notifying the user about forced rotation
+     * reason with the {@link Toast}.
+     */
+    void onScreenRotationAnimationFinished() {
+        if (mDisplayRotationCompatPolicy != null) {
+            mDisplayRotationCompatPolicy.onScreenRotationAnimationFinished();
+        }
+    }
+
+    boolean isActivityEligibleForOrientationOverride(@NonNull ActivityRecord activity) {
+        if (mDisplayRotationCompatPolicy != null) {
+            return mDisplayRotationCompatPolicy.isActivityEligibleForOrientationOverride(activity);
+        }
+        return false;
+    }
+
+    /**
+     * Whether camera compat treatment is applicable for the given activity.
+     *
+     * <p>Conditions that need to be met:
+     * <ul>
+     *     <li>Camera is active for the package.
+     *     <li>The activity is in fullscreen
+     *     <li>The activity has fixed orientation but not "locked" or "nosensor" one.
+     * </ul>
+     */
+    boolean isTreatmentEnabledForActivity(@Nullable ActivityRecord activity) {
+        if (mDisplayRotationCompatPolicy != null) {
+            return mDisplayRotationCompatPolicy.isTreatmentEnabledForActivity(activity);
+        }
+        return false;
+    }
+
+    void start() {
+        if (mCameraCompatFreeformPolicy != null) {
+            mCameraCompatFreeformPolicy.start();
+        }
+        if (mCameraStateMonitor != null) {
+            mCameraStateMonitor.startListeningToCameraState();
+        }
+    }
+
+    void dispose() {
+        if (mDisplayRotationCompatPolicy != null) {
+            mDisplayRotationCompatPolicy.dispose();
+        }
+        if (mCameraCompatFreeformPolicy != null) {
+            mCameraCompatFreeformPolicy.dispose();
+        }
+        if (mCameraStateMonitor != null) {
+            mCameraStateMonitor.dispose();
+        }
+    }
+
+    boolean hasDisplayRotationCompatPolicy() {
+        return mDisplayRotationCompatPolicy != null;
+    }
+
+    boolean hasCameraCompatFreeformPolicy() {
+        return mCameraCompatFreeformPolicy != null;
+    }
+
+    @ScreenOrientation
+    int getOrientation() {
+        return mDisplayRotationCompatPolicy != null
+                ? mDisplayRotationCompatPolicy.getOrientation()
+                : SCREEN_ORIENTATION_UNSPECIFIED;
+    }
+
+    boolean isCameraActive(@NonNull ActivityRecord activity, boolean mustBeFullscreen) {
+        return mDisplayRotationCompatPolicy != null
+                && mDisplayRotationCompatPolicy.isCameraActive(activity, mustBeFullscreen);
+    }
+
+    @Nullable
+    String getSummaryForDisplayRotationHistoryRecord() {
+        if (mDisplayRotationCompatPolicy != null) {
+            return mDisplayRotationCompatPolicy.getSummaryForDisplayRotationHistoryRecord();
+        }
+        return null;
+    }
+
+}
diff --git a/services/core/java/com/android/server/wm/AppCompatController.java b/services/core/java/com/android/server/wm/AppCompatController.java
new file mode 100644
index 0000000..16d3787
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AppCompatController.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.pm.PackageManager;
+
+import com.android.server.wm.utils.OptPropFactory;
+
+/**
+ * Allows the interaction with all the app compat policies and configurations
+ */
+class AppCompatController {
+
+    @NonNull
+    private final ActivityRecord mActivityRecord;
+    @NonNull
+    private final TransparentPolicy mTransparentPolicy;
+    @NonNull
+    private final AppCompatOrientationPolicy mOrientationPolicy;
+    @NonNull
+    private final AppCompatOverrides mAppCompatOverrides;
+
+    AppCompatController(@NonNull WindowManagerService wmService,
+                        @NonNull ActivityRecord activityRecord) {
+        mActivityRecord = activityRecord;
+        final PackageManager packageManager = wmService.mContext.getPackageManager();
+        final OptPropFactory optPropBuilder = new OptPropFactory(packageManager,
+                activityRecord.packageName);
+        mTransparentPolicy = new TransparentPolicy(activityRecord,
+                wmService.mLetterboxConfiguration);
+        mAppCompatOverrides = new AppCompatOverrides(activityRecord,
+                wmService.mLetterboxConfiguration, optPropBuilder);
+        // TODO(b/341903757) Remove BooleanSuppliers after fixing dependency with aspectRatio.
+        final LetterboxUiController tmpController = activityRecord.mLetterboxUiController;
+        mOrientationPolicy = new AppCompatOrientationPolicy(activityRecord,
+                mAppCompatOverrides, tmpController::shouldApplyUserFullscreenOverride,
+                tmpController::shouldApplyUserMinAspectRatioOverride,
+                tmpController::isSystemOverrideToFullscreenEnabled);
+    }
+
+    @NonNull
+    TransparentPolicy getTransparentPolicy() {
+        return mTransparentPolicy;
+    }
+
+    @NonNull
+    AppCompatOrientationPolicy getOrientationPolicy() {
+        return mOrientationPolicy;
+    }
+
+    @NonNull
+    AppCompatOverrides getAppCompatOverrides() {
+        return mAppCompatOverrides;
+    }
+
+    @NonNull
+    AppCompatOrientationOverrides getAppCompatOrientationOverrides() {
+        return mAppCompatOverrides.getAppCompatOrientationOverrides();
+    }
+
+    @NonNull
+    AppCompatCameraOverrides getAppCompatCameraOverrides() {
+        return mAppCompatOverrides.getAppCompatCameraOverrides();
+    }
+
+    @Nullable
+    AppCompatCameraPolicy getAppCompatCameraPolicy() {
+        if (mActivityRecord.mDisplayContent != null) {
+            return mActivityRecord.mDisplayContent.mAppCompatCameraPolicy;
+        }
+        return null;
+    }
+}
diff --git a/services/core/java/com/android/server/wm/AppCompatOrientationOverrides.java b/services/core/java/com/android/server/wm/AppCompatOrientationOverrides.java
new file mode 100644
index 0000000..155e246
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AppCompatOrientationOverrides.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.OVERRIDE_ANY_ORIENTATION;
+import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
+import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION;
+import static android.content.pm.ActivityInfo.OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE;
+import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR;
+import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
+import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
+
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.AppCompatUtils.asLazy;
+
+import android.annotation.NonNull;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wm.utils.OptPropFactory;
+
+import java.util.function.BooleanSupplier;
+import java.util.function.LongSupplier;
+
+/**
+ * Encapsulates all the configurations and overrides about orientation used by
+ * {@link AppCompatOrientationPolicy}.
+ */
+class AppCompatOrientationOverrides {
+
+    private static final String TAG = TAG_WITH_CLASS_NAME
+            ? "AppCompatOrientationOverrides" : TAG_ATM;
+
+    @NonNull
+    private final ActivityRecord mActivityRecord;
+    @NonNull
+    private final AppCompatCameraOverrides mAppCompatCameraOverrides;
+
+    @NonNull
+    private final OptPropFactory.OptProp mIgnoreRequestedOrientationOptProp;
+    @NonNull
+    private final OptPropFactory.OptProp mAllowIgnoringOrientationRequestWhenLoopDetectedOptProp;
+
+    @NonNull
+    final OrientationOverridesState mOrientationOverridesState;
+
+    AppCompatOrientationOverrides(@NonNull ActivityRecord activityRecord,
+            @NonNull LetterboxConfiguration letterboxConfiguration,
+            @NonNull OptPropFactory optPropBuilder,
+            @NonNull AppCompatCameraOverrides appCompatCameraOverrides) {
+        mActivityRecord = activityRecord;
+        mAppCompatCameraOverrides = appCompatCameraOverrides;
+        mOrientationOverridesState = new OrientationOverridesState(mActivityRecord,
+                System::currentTimeMillis);
+        final BooleanSupplier isPolicyForIgnoringRequestedOrientationEnabled = asLazy(
+                letterboxConfiguration::isPolicyForIgnoringRequestedOrientationEnabled);
+        mIgnoreRequestedOrientationOptProp = optPropBuilder.create(
+                PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION,
+                isPolicyForIgnoringRequestedOrientationEnabled);
+        mAllowIgnoringOrientationRequestWhenLoopDetectedOptProp = optPropBuilder.create(
+                PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED,
+                isPolicyForIgnoringRequestedOrientationEnabled);
+    }
+
+    boolean shouldEnableIgnoreOrientationRequest() {
+        return mIgnoreRequestedOrientationOptProp.shouldEnableWithOverrideAndProperty(
+                isCompatChangeEnabled(OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION));
+    }
+
+    /**
+     * Whether an app is calling {@link android.app.Activity#setRequestedOrientation}
+     * in a loop and orientation request should be ignored.
+     *
+     * <p>This should only be called once in response to
+     * {@link android.app.Activity#setRequestedOrientation}. See
+     * {@link #shouldIgnoreRequestedOrientation} for more details.
+     *
+     * <p>This treatment is enabled when the following conditions are met:
+     * <ul>
+     *     <li>Flag gating the treatment is enabled
+     *     <li>Opt-out component property isn't enabled
+     *     <li>Per-app override is enabled
+     *     <li>App has requested orientation more than 2 times within 1-second
+     *     timer and activity is not letterboxed for fixed orientation
+     * </ul>
+     */
+    boolean shouldIgnoreOrientationRequestLoop() {
+        final boolean loopDetectionEnabled = isCompatChangeEnabled(
+                OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED);
+        if (!mAllowIgnoringOrientationRequestWhenLoopDetectedOptProp
+                .shouldEnableWithOptInOverrideAndOptOutProperty(loopDetectionEnabled)) {
+            return false;
+        }
+        mOrientationOverridesState.updateOrientationRequestLoopState();
+
+        return mOrientationOverridesState.shouldIgnoreRequestInLoop()
+                && !mActivityRecord.isLetterboxedForFixedOrientationAndAspectRatio();
+    }
+
+    /**
+     * Sets whether an activity is relaunching after the app has called {@link
+     * android.app.Activity#setRequestedOrientation}.
+     */
+    void setRelaunchingAfterRequestedOrientationChanged(boolean isRelaunching) {
+        mOrientationOverridesState
+                .mIsRelaunchingAfterRequestedOrientationChanged = isRelaunching;
+    }
+
+    boolean getIsRelaunchingAfterRequestedOrientationChanged() {
+        return mOrientationOverridesState.mIsRelaunchingAfterRequestedOrientationChanged;
+    }
+
+    @VisibleForTesting
+    int getSetOrientationRequestCounter() {
+        return mOrientationOverridesState.mSetOrientationRequestCounter;
+    }
+
+    private boolean isCompatChangeEnabled(long overrideChangeId) {
+        return mActivityRecord.info.isChangeEnabled(overrideChangeId);
+    }
+
+    static class OrientationOverridesState {
+        // Corresponds to OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR
+        final boolean mIsOverrideToNosensorOrientationEnabled;
+        // Corresponds to OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT
+        final boolean mIsOverrideToPortraitOrientationEnabled;
+        // Corresponds to OVERRIDE_ANY_ORIENTATION
+        final boolean mIsOverrideAnyOrientationEnabled;
+        // Corresponds to OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE
+        final boolean mIsOverrideToReverseLandscapeOrientationEnabled;
+
+        private boolean mIsRelaunchingAfterRequestedOrientationChanged;
+
+        // Used to determine reset of mSetOrientationRequestCounter if next app requested
+        // orientation is after timeout value
+        @VisibleForTesting
+        static final int SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS = 1000;
+        // Minimum value of mSetOrientationRequestCounter before qualifying as orientation request
+        // loop
+        @VisibleForTesting
+        static final int MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP = 2;
+        // Updated when ActivityRecord#setRequestedOrientation is called
+        private long mTimeMsLastSetOrientationRequest = 0;
+        // Counter for ActivityRecord#setRequestedOrientation
+        private int mSetOrientationRequestCounter = 0;
+        @VisibleForTesting
+        LongSupplier mCurrentTimeMillisSupplier;
+
+        OrientationOverridesState(@NonNull ActivityRecord activityRecord,
+                @NonNull LongSupplier currentTimeMillisSupplier) {
+            mCurrentTimeMillisSupplier = currentTimeMillisSupplier;
+            mIsOverrideToNosensorOrientationEnabled =
+                    activityRecord.info.isChangeEnabled(OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR);
+            mIsOverrideToPortraitOrientationEnabled =
+                    activityRecord.info.isChangeEnabled(OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT);
+            mIsOverrideAnyOrientationEnabled =
+                    activityRecord.info.isChangeEnabled(OVERRIDE_ANY_ORIENTATION);
+            mIsOverrideToReverseLandscapeOrientationEnabled = activityRecord.info
+                    .isChangeEnabled(OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE);
+        }
+
+        /**
+         * @return {@code true} if we should start ignoring orientation in a orientation request
+         * loop.
+         */
+        boolean shouldIgnoreRequestInLoop() {
+            return mSetOrientationRequestCounter >= MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP;
+        }
+
+        /**
+         * Updates the orientation request counter using a specific timeout.
+         */
+        void updateOrientationRequestLoopState() {
+            final long currTimeMs = mCurrentTimeMillisSupplier.getAsLong();
+            final long elapsedTime = currTimeMs - mTimeMsLastSetOrientationRequest;
+            if (elapsedTime < SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS) {
+                mSetOrientationRequestCounter++;
+            } else {
+                mSetOrientationRequestCounter = 0;
+            }
+            mTimeMsLastSetOrientationRequest = currTimeMs;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java b/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java
new file mode 100644
index 0000000..69ba59b
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AppCompatOrientationPolicy.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_LOCKED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER;
+import static android.content.pm.ActivityInfo.isFixedOrientation;
+import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
+import static android.content.pm.ActivityInfo.screenOrientationToString;
+
+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.util.Slog;
+
+import java.util.function.BooleanSupplier;
+
+/**
+ * Contains all the logic related to orientation in the context of app compatibility
+ */
+class AppCompatOrientationPolicy {
+
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "AppCompatOrientationPolicy" : TAG_ATM;
+
+    @NonNull
+    private final ActivityRecord mActivityRecord;
+
+    @NonNull
+    private final AppCompatOverrides mAppCompatOverrides;
+    @NonNull
+    private final BooleanSupplier mShouldApplyUserFullscreenOverride;
+    @NonNull
+    private final BooleanSupplier mShouldApplyUserMinAspectRatioOverride;
+    @NonNull
+    private final BooleanSupplier mIsSystemOverrideToFullscreenEnabled;
+
+    // TODO(b/341903757) Remove BooleanSuppliers after fixing dependency with spectRatio component
+    AppCompatOrientationPolicy(@NonNull ActivityRecord activityRecord,
+                               @NonNull AppCompatOverrides appCompatOverrides,
+                               @NonNull BooleanSupplier shouldApplyUserFullscreenOverride,
+                               @NonNull BooleanSupplier shouldApplyUserMinAspectRatioOverride,
+                               @NonNull BooleanSupplier isSystemOverrideToFullscreenEnabled) {
+        mActivityRecord = activityRecord;
+        mAppCompatOverrides = appCompatOverrides;
+        mShouldApplyUserFullscreenOverride = shouldApplyUserFullscreenOverride;
+        mShouldApplyUserMinAspectRatioOverride = shouldApplyUserMinAspectRatioOverride;
+        mIsSystemOverrideToFullscreenEnabled = isSystemOverrideToFullscreenEnabled;
+    }
+
+    @ActivityInfo.ScreenOrientation
+    int overrideOrientationIfNeeded(@ActivityInfo.ScreenOrientation int candidate) {
+        final DisplayContent displayContent = mActivityRecord.mDisplayContent;
+        final boolean isIgnoreOrientationRequestEnabled = displayContent != null
+                && displayContent.getIgnoreOrientationRequest();
+        if (mShouldApplyUserFullscreenOverride.getAsBoolean() && isIgnoreOrientationRequestEnabled
+                // Do not override orientation to fullscreen for camera activities.
+                // Fixed-orientation activities are rarely tested in other orientations, and it
+                // often results in sideways or stretched previews. As the camera compat treatment
+                // targets fixed-orientation activities, overriding the orientation disables the
+                // treatment.
+                && !mAppCompatOverrides.getAppCompatCameraOverrides().isCameraActive()) {
+            Slog.v(TAG, "Requested orientation " + screenOrientationToString(candidate)
+                    + " for " + mActivityRecord + " is overridden to "
+                    + screenOrientationToString(SCREEN_ORIENTATION_USER)
+                    + " by user aspect ratio settings.");
+            return SCREEN_ORIENTATION_USER;
+        }
+
+        // In some cases (e.g. Kids app) we need to map the candidate orientation to some other
+        // orientation.
+        candidate = mActivityRecord.mWmService.mapOrientationRequest(candidate);
+
+        if (mShouldApplyUserMinAspectRatioOverride.getAsBoolean() && (!isFixedOrientation(candidate)
+                || candidate == SCREEN_ORIENTATION_LOCKED)) {
+            Slog.v(TAG, "Requested orientation " + screenOrientationToString(candidate)
+                    + " for " + mActivityRecord + " is overridden to "
+                    + screenOrientationToString(SCREEN_ORIENTATION_PORTRAIT)
+                    + " by user aspect ratio settings.");
+            return SCREEN_ORIENTATION_PORTRAIT;
+        }
+
+        if (mAppCompatOverrides.isAllowOrientationOverrideOptOut()) {
+            return candidate;
+        }
+
+        if (displayContent != null
+                && mAppCompatOverrides.getAppCompatCameraOverrides()
+                    .isOverrideOrientationOnlyForCameraEnabled()
+                && !displayContent.mAppCompatCameraPolicy
+                    .isActivityEligibleForOrientationOverride(mActivityRecord)) {
+            return candidate;
+        }
+
+        // mUserAspectRatio is always initialized first in shouldApplyUserFullscreenOverride(),
+        // which will always come first before this check as user override > device
+        // manufacturer override.
+        if (mIsSystemOverrideToFullscreenEnabled.getAsBoolean() && isIgnoreOrientationRequestEnabled
+                // Do not override orientation to fullscreen for camera activities.
+                // Fixed-orientation activities are rarely tested in other orientations, and it
+                // often results in sideways or stretched previews. As the camera compat treatment
+                // targets fixed-orientation activities, overriding the orientation disables the
+                // treatment.
+                && !mAppCompatOverrides.getAppCompatCameraOverrides().isCameraActive()) {
+            Slog.v(TAG, "Requested orientation  " + screenOrientationToString(candidate)
+                    + " for " + mActivityRecord + " is overridden to "
+                    + screenOrientationToString(SCREEN_ORIENTATION_USER));
+            return SCREEN_ORIENTATION_USER;
+        }
+
+        final AppCompatOrientationOverrides.OrientationOverridesState capabilityState =
+                mAppCompatOverrides.getAppCompatOrientationOverrides()
+                        .mOrientationOverridesState;
+
+        if (capabilityState.mIsOverrideToReverseLandscapeOrientationEnabled
+                && (isFixedOrientationLandscape(candidate)
+                || capabilityState.mIsOverrideAnyOrientationEnabled)) {
+            Slog.w(TAG, "Requested orientation  " + screenOrientationToString(candidate) + " for "
+                    + mActivityRecord + " is overridden to "
+                    + screenOrientationToString(SCREEN_ORIENTATION_REVERSE_LANDSCAPE));
+            return SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
+        }
+
+        if (!capabilityState.mIsOverrideAnyOrientationEnabled && isFixedOrientation(candidate)) {
+            return candidate;
+        }
+
+        if (capabilityState.mIsOverrideToPortraitOrientationEnabled) {
+            Slog.w(TAG, "Requested orientation  " + screenOrientationToString(candidate) + " for "
+                    + mActivityRecord + " is overridden to "
+                    + screenOrientationToString(SCREEN_ORIENTATION_PORTRAIT));
+            return SCREEN_ORIENTATION_PORTRAIT;
+        }
+
+        if (capabilityState.mIsOverrideToNosensorOrientationEnabled) {
+            Slog.w(TAG, "Requested orientation  " + screenOrientationToString(candidate) + " for "
+                    + mActivityRecord + " is overridden to "
+                    + screenOrientationToString(SCREEN_ORIENTATION_NOSENSOR));
+            return SCREEN_ORIENTATION_NOSENSOR;
+        }
+
+        return candidate;
+    }
+
+    /**
+     * Whether should ignore app requested orientation in response to an app
+     * calling {@link android.app.Activity#setRequestedOrientation}.
+     *
+     * <p>This is needed to avoid getting into {@link android.app.Activity#setRequestedOrientation}
+     * loop when {@link DisplayContent#getIgnoreOrientationRequest} is enabled or device has
+     * landscape natural orientation which app developers don't expect. For example, the loop can
+     * look like this:
+     * <ol>
+     *     <li>App sets default orientation to "unspecified" at runtime
+     *     <li>App requests to "portrait" after checking some condition (e.g. display rotation).
+     *     <li>(2) leads to fullscreen -> letterboxed bounds change and activity relaunch because
+     *     app can't handle the corresponding config changes.
+     *     <li>Loop goes back to (1)
+     * </ol>
+     *
+     * <p>This treatment is enabled when the following conditions are met:
+     * <ul>
+     *     <li>Flag gating the treatment is enabled
+     *     <li>Opt-out component property isn't enabled
+     *     <li>Opt-in component property or per-app override are enabled
+     *     <li>Activity is relaunched after {@link android.app.Activity#setRequestedOrientation}
+     *     call from an app or camera compat force rotation treatment is active for the activity.
+     *     <li>Orientation request loop detected and is not letterboxed for fixed orientation
+     * </ul>
+     */
+    boolean shouldIgnoreRequestedOrientation(
+            @ActivityInfo.ScreenOrientation int requestedOrientation) {
+        final AppCompatOrientationOverrides orientationOverrides =
+                mAppCompatOverrides.getAppCompatOrientationOverrides();
+        if (orientationOverrides.shouldEnableIgnoreOrientationRequest()) {
+            if (orientationOverrides.getIsRelaunchingAfterRequestedOrientationChanged()) {
+                Slog.w(TAG, "Ignoring orientation update to "
+                        + screenOrientationToString(requestedOrientation)
+                        + " due to relaunching after setRequestedOrientation for "
+                        + mActivityRecord);
+                return true;
+            }
+            final AppCompatCameraPolicy cameraPolicy = mActivityRecord.mAppCompatController
+                    .getAppCompatCameraPolicy();
+            if (cameraPolicy != null
+                    && cameraPolicy.isTreatmentEnabledForActivity(mActivityRecord)) {
+                Slog.w(TAG, "Ignoring orientation update to "
+                        + screenOrientationToString(requestedOrientation)
+                        + " due to camera compat treatment for " + mActivityRecord);
+                return true;
+            }
+        }
+        if (orientationOverrides.shouldIgnoreOrientationRequestLoop()) {
+            Slog.w(TAG, "Ignoring orientation update to "
+                    + screenOrientationToString(requestedOrientation)
+                    + " as orientation request loop was detected for "
+                    + mActivityRecord);
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/services/core/java/com/android/server/wm/AppCompatOverrides.java b/services/core/java/com/android/server/wm/AppCompatOverrides.java
new file mode 100644
index 0000000..94c6ba9
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AppCompatOverrides.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.FORCE_NON_RESIZE_APP;
+import static android.content.pm.ActivityInfo.FORCE_RESIZE_APP;
+import static android.content.pm.ActivityInfo.OVERRIDE_ANY_ORIENTATION_TO_USER;
+import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS;
+import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO;
+import static android.content.pm.ActivityInfo.OVERRIDE_RESPECT_REQUESTED_ORIENTATION;
+import static android.content.pm.ActivityInfo.OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET;
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS;
+
+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 com.android.server.wm.utils.OptPropFactory;
+
+/**
+ * Encapsulate logic related to operations guarded by an app override.
+ */
+public class AppCompatOverrides {
+
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "AppCompatOverrides" : TAG_ATM;
+
+    @NonNull
+    private final LetterboxConfiguration mLetterboxConfiguration;
+
+    @NonNull
+    private final ActivityRecord mActivityRecord;
+
+    @NonNull
+    private final OptPropFactory.OptProp mFakeFocusOptProp;
+    @NonNull
+    private final OptPropFactory.OptProp mAllowOrientationOverrideOptProp;
+    @NonNull
+    private final OptPropFactory.OptProp mAllowDisplayOrientationOverrideOptProp;
+    @NonNull
+    private final OptPropFactory.OptProp mAllowMinAspectRatioOverrideOptProp;
+    @NonNull
+    private final OptPropFactory.OptProp mAllowForceResizeOverrideOptProp;
+    @NonNull
+    private final OptPropFactory.OptProp mAllowUserAspectRatioOverrideOptProp;
+    @NonNull
+    private final OptPropFactory.OptProp mAllowUserAspectRatioFullscreenOverrideOptProp;
+    @NonNull
+    private final AppCompatOrientationOverrides mAppCompatOrientationOverrides;
+    @NonNull
+    private final AppCompatCameraOverrides mAppCompatCameraOverrides;
+
+    AppCompatOverrides(@NonNull ActivityRecord activityRecord,
+            @NonNull LetterboxConfiguration letterboxConfiguration,
+            @NonNull OptPropFactory optPropBuilder) {
+        mLetterboxConfiguration = letterboxConfiguration;
+        mActivityRecord = activityRecord;
+
+        mAppCompatCameraOverrides = new AppCompatCameraOverrides(mActivityRecord,
+                mLetterboxConfiguration, optPropBuilder);
+        mAppCompatOrientationOverrides = new AppCompatOrientationOverrides(mActivityRecord,
+                mLetterboxConfiguration, optPropBuilder, mAppCompatCameraOverrides);
+
+        mFakeFocusOptProp = optPropBuilder.create(PROPERTY_COMPAT_ENABLE_FAKE_FOCUS,
+                mLetterboxConfiguration::isCompatFakeFocusEnabled);
+
+
+        mAllowOrientationOverrideOptProp = optPropBuilder.create(
+                PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE);
+
+        mAllowDisplayOrientationOverrideOptProp = optPropBuilder.create(
+                PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE,
+                () -> mActivityRecord.mDisplayContent != null
+                        && mActivityRecord.getTask() != null
+                        && mActivityRecord.mDisplayContent.getIgnoreOrientationRequest()
+                        && !mActivityRecord.getTask().inMultiWindowMode()
+                        && mActivityRecord.mDisplayContent.getNaturalOrientation()
+                            == ORIENTATION_LANDSCAPE
+        );
+
+        mAllowMinAspectRatioOverrideOptProp = optPropBuilder.create(
+                PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE);
+        mAllowForceResizeOverrideOptProp = optPropBuilder.create(
+                PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES);
+        mAllowUserAspectRatioOverrideOptProp = optPropBuilder.create(
+                PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE,
+                mLetterboxConfiguration::isUserAppAspectRatioSettingsEnabled);
+        mAllowUserAspectRatioFullscreenOverrideOptProp = optPropBuilder.create(
+                PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE,
+                mLetterboxConfiguration::isUserAppAspectRatioFullscreenEnabled);
+    }
+
+    @NonNull
+    AppCompatOrientationOverrides getAppCompatOrientationOverrides() {
+        return mAppCompatOrientationOverrides;
+    }
+
+    @NonNull
+    AppCompatCameraOverrides getAppCompatCameraOverrides() {
+        return mAppCompatCameraOverrides;
+    }
+
+    /**
+     * Whether sending compat fake focus for split screen resumed activities is enabled. Needed
+     * because some game engines wait to get focus before drawing the content of the app which isn't
+     * guaranteed by default in multi-window modes.
+     *
+     * <p>This treatment is enabled when the following conditions are met:
+     * <ul>
+     *     <li>Flag gating the treatment is enabled
+     *     <li>Component property is NOT set to false
+     *     <li>Component property is set to true or per-app override is enabled
+     * </ul>
+     */
+    boolean shouldSendFakeFocus() {
+        return mFakeFocusOptProp.shouldEnableWithOverrideAndProperty(
+                isCompatChangeEnabled(OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS));
+    }
+
+    boolean isSystemOverrideToFullscreenEnabled(int userAspectRatio) {
+        return isCompatChangeEnabled(OVERRIDE_ANY_ORIENTATION_TO_USER)
+                && !mAllowOrientationOverrideOptProp.isFalse()
+                && (userAspectRatio == USER_MIN_ASPECT_RATIO_UNSET
+                    || userAspectRatio == USER_MIN_ASPECT_RATIO_FULLSCREEN);
+    }
+
+    boolean isAllowOrientationOverrideOptOut() {
+        return mAllowOrientationOverrideOptProp.isFalse();
+    }
+
+    /**
+     * Whether we should apply the min aspect ratio per-app override. When this override is applied
+     * the min aspect ratio given in the app's manifest will be overridden to the largest enabled
+     * aspect ratio treatment unless the app's manifest value is higher. The treatment will also
+     * apply if no value is provided in the manifest.
+     *
+     * <p>This method returns {@code true} when the following conditions are met:
+     * <ul>
+     *     <li>Opt-out component property isn't enabled
+     *     <li>Per-app override is enabled
+     * </ul>
+     */
+    boolean shouldOverrideMinAspectRatio() {
+        return mAllowMinAspectRatioOverrideOptProp.shouldEnableWithOptInOverrideAndOptOutProperty(
+                isCompatChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO));
+    }
+
+    boolean isOverrideRespectRequestedOrientationEnabled() {
+        return isCompatChangeEnabled(OVERRIDE_RESPECT_REQUESTED_ORIENTATION);
+    }
+
+    /**
+     * Whether should fix display orientation to landscape natural orientation when a task is
+     * fullscreen and the display is ignoring orientation requests.
+     *
+     * <p>This treatment is enabled when the following conditions are met:
+     * <ul>
+     *     <li>Opt-out component property isn't enabled
+     *     <li>Opt-in per-app override is enabled
+     *     <li>Task is in fullscreen.
+     *     <li>{@link DisplayContent#getIgnoreOrientationRequest} is enabled
+     *     <li>Natural orientation of the display is landscape.
+     * </ul>
+     */
+    boolean shouldUseDisplayLandscapeNaturalOrientation() {
+        return mAllowDisplayOrientationOverrideOptProp
+                .shouldEnableWithOptInOverrideAndOptOutProperty(
+                        isCompatChangeEnabled(OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION));
+    }
+
+    /**
+     * Whether we should apply the force resize per-app override. When this override is applied it
+     * forces the packages it is applied to to be resizable. It won't change whether the app can be
+     * put into multi-windowing mode, but allow the app to resize without going into size-compat
+     * mode when the window container resizes, such as display size change or screen rotation.
+     *
+     * <p>This method returns {@code true} when the following conditions are met:
+     * <ul>
+     *     <li>Opt-out component property isn't enabled
+     *     <li>Per-app override is enabled
+     * </ul>
+     */
+    boolean shouldOverrideForceResizeApp() {
+        return mAllowForceResizeOverrideOptProp.shouldEnableWithOptInOverrideAndOptOutProperty(
+                isCompatChangeEnabled(FORCE_RESIZE_APP));
+    }
+
+    /**
+     * Whether we should enable users to resize the current app.
+     */
+    boolean shouldEnableUserAspectRatioSettings() {
+        // We use mBooleanPropertyAllowUserAspectRatioOverride to allow apps to opt-out which has
+        // effect only if explicitly false. If mBooleanPropertyAllowUserAspectRatioOverride is null,
+        // the current app doesn't opt-out so the first part of the predicate is true.
+        return !mAllowUserAspectRatioOverrideOptProp.isFalse()
+                && mLetterboxConfiguration.isUserAppAspectRatioSettingsEnabled()
+                && mActivityRecord.mDisplayContent != null
+                && mActivityRecord.mDisplayContent.getIgnoreOrientationRequest();
+    }
+
+    boolean isUserFullscreenOverrideEnabled() {
+        if (mAllowUserAspectRatioOverrideOptProp.isFalse()
+                || mAllowUserAspectRatioFullscreenOverrideOptProp.isFalse()
+                || !mLetterboxConfiguration.isUserAppAspectRatioFullscreenEnabled()) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Whether we should apply the force non resize per-app override. When this override is applied
+     * it forces the packages it is applied to to be non-resizable.
+     *
+     * <p>This method returns {@code true} when the following conditions are met:
+     * <ul>
+     *     <li>Opt-out component property isn't enabled
+     *     <li>Per-app override is enabled
+     * </ul>
+     */
+    boolean shouldOverrideForceNonResizeApp() {
+        return mAllowForceResizeOverrideOptProp.shouldEnableWithOptInOverrideAndOptOutProperty(
+                isCompatChangeEnabled(FORCE_NON_RESIZE_APP));
+    }
+
+    private boolean isCompatChangeEnabled(long overrideChangeId) {
+        return mActivityRecord.info.isChangeEnabled(overrideChangeId);
+    }
+}
diff --git a/services/core/java/com/android/server/wm/AppCompatUtils.java b/services/core/java/com/android/server/wm/AppCompatUtils.java
new file mode 100644
index 0000000..be51dd3b
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AppCompatUtils.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 android.annotation.NonNull;
+
+import java.util.function.BooleanSupplier;
+
+/**
+ * Utilities for App Compat policies and overrides.
+ */
+class AppCompatUtils {
+
+    /**
+     * Lazy version of a {@link BooleanSupplier} which access an existing BooleanSupplier and
+     * caches the value.
+     *
+     * @param supplier The BooleanSupplier to decorate.
+     * @return A lazy implementation of a BooleanSupplier
+     */
+    @NonNull
+    static BooleanSupplier asLazy(@NonNull BooleanSupplier supplier) {
+        return new BooleanSupplier() {
+            private boolean mRead;
+            private boolean mValue;
+
+            @Override
+            public boolean getAsBoolean() {
+                if (!mRead) {
+                    mRead = true;
+                    mValue = supplier.getAsBoolean();
+                }
+                return mValue;
+            }
+        };
+    }
+}
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index c2b9128..bc7e84a 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -135,7 +135,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.policy.TransitionAnimation;
 import com.android.internal.protolog.common.LogLevel;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.DumpUtils.Dump;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.internal.util.function.pooled.PooledPredicate;
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 939babc..44b414f 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -92,7 +92,7 @@
 import android.window.ITaskFragmentOrganizer;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -256,7 +256,8 @@
             tmpCloseApps = new ArraySet<>(mDisplayContent.mClosingApps);
             if (mDisplayContent.mAtmService.mBackNavigationController
                     .removeIfContainsBackAnimationTargets(tmpOpenApps, tmpCloseApps)) {
-                mDisplayContent.mAtmService.mBackNavigationController.clearBackAnimations();
+                mDisplayContent.mAtmService.mBackNavigationController
+                        .clearBackAnimations(false /* cancel */);
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/BLASTSyncEngine.java b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
index e8faff6..4554b21 100644
--- a/services/core/java/com/android/server/wm/BLASTSyncEngine.java
+++ b/services/core/java/com/android/server/wm/BLASTSyncEngine.java
@@ -30,7 +30,7 @@
 import android.view.SurfaceControl;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 import java.util.ArrayList;
 
@@ -348,6 +348,11 @@
                 wc.setSyncGroup(this);
             }
             wc.prepareSync();
+            if (wc.mSyncState == WindowContainer.SYNC_STATE_NONE && wc.mSyncGroup != null) {
+                Slog.w(TAG, "addToSync: unset SyncGroup " + wc.mSyncGroup.mSyncId
+                        + " for non-sync " + wc);
+                wc.mSyncGroup = null;
+            }
             if (mReady) {
                 mWm.mWindowPlacerLocked.requestTraversal();
             }
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 1ce324f..8421765 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -61,7 +61,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.policy.TransitionAnimation;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.window.flags.Flags;
 
 import java.io.PrintWriter;
@@ -210,6 +210,9 @@
                             + "topRunningActivity=%s, callbackInfo=%s, currentFocus=%s",
                     currentTask, currentActivity, callbackInfo, window);
 
+            // Clear the pointer down outside focus if any.
+            mWindowManagerService.clearPointerDownOutsideFocusRunnable();
+
             // If we don't need to set up the animation, we return early. This is the case when
             // - We have an application callback.
             // - We don't have any ActivityRecord or Task to animate.
@@ -252,7 +255,8 @@
                 // skip if one of participant activity is translucent
                 backType = BackNavigationInfo.TYPE_CALLBACK;
             } else if (prevActivities.size() > 0) {
-                if (!isOccluded || isAllActivitiesCanShowWhenLocked(prevActivities)) {
+                if ((!isOccluded || isAllActivitiesCanShowWhenLocked(prevActivities))
+                        && isAllActivitiesCreated(prevActivities)) {
                     // We have another Activity in the same currentTask to go to
                     final WindowContainer parent = currentActivity.getParent();
                     final boolean canCustomize = parent != null
@@ -356,8 +360,7 @@
                                 removedWindowContainer);
                 mBackAnimationInProgress = builder != null;
                 if (mBackAnimationInProgress) {
-                    if (removedWindowContainer.hasCommittedReparentToAnimationLeash()
-                            || removedWindowContainer.mTransitionController.inTransition()
+                    if (removedWindowContainer.mTransitionController.inTransition()
                             || mWindowManagerService.mSyncEngine.hasPendingSyncSets()) {
                         ProtoLog.w(WM_DEBUG_BACK_PREVIEW,
                                 "Pending back animation due to another animation is running");
@@ -549,6 +552,17 @@
         return !prevActivities.isEmpty();
     }
 
+    private static boolean isAllActivitiesCreated(
+            @NonNull ArrayList<ActivityRecord> prevActivities) {
+        for (int i = prevActivities.size() - 1; i >= 0; --i) {
+            final ActivityRecord check = prevActivities.get(i);
+            if (check.isState(ActivityRecord.State.INITIALIZING)) {
+                return false;
+            }
+        }
+        return !prevActivities.isEmpty();
+    }
+
     boolean isMonitoringTransition() {
         return mAnimationHandler.mComposed || mNavigationMonitor.isMonitorForRemote();
     }
@@ -739,7 +753,7 @@
                 mObserver.sendResult(null /* result */);
             }
             if (isMonitorAnimationOrTransition()) {
-                clearBackAnimations();
+                clearBackAnimations(true /* cancel */);
             }
             cancelPendingAnimation();
         }
@@ -831,24 +845,23 @@
      * Cleanup animation, this can either happen when legacy transition ready, or when the Shell
      * transition finish.
      */
-    void clearBackAnimations() {
-        mAnimationHandler.clearBackAnimateTarget();
+    void clearBackAnimations(boolean cancel) {
+        mAnimationHandler.clearBackAnimateTarget(cancel);
         mNavigationMonitor.stopMonitorTransition();
         mWaitTransitionFinish = null;
     }
 
     /**
-     * Called when a transition finished.
-     * Handle the pending animation when the running transition finished.
+     * Handle the pending animation when the running transition finished, all the visibility change
+     * has applied so ready to start pending predictive back animation.
      * @param targets The final animation targets derived in transition.
      * @param finishedTransition The finished transition target.
     */
     void onTransitionFinish(ArrayList<Transition.ChangeInfo> targets,
             @NonNull Transition finishedTransition) {
         if (finishedTransition == mWaitTransitionFinish) {
-            clearBackAnimations();
+            clearBackAnimations(false /* cancel */);
         }
-
         if (!mBackAnimationInProgress || mPendingAnimationBuilder == null) {
             return;
         }
@@ -982,7 +995,7 @@
             mCloseAdaptor = createAdaptor(close, false, mSwitchType);
             if (mCloseAdaptor.mAnimationTarget == null) {
                 Slog.w(TAG, "composeNewAnimations fail, skip");
-                clearBackAnimateTarget();
+                clearBackAnimateTarget(true /* cancel */);
                 return;
             }
 
@@ -1001,7 +1014,7 @@
             mOpenAnimAdaptor = new BackWindowAnimationAdaptorWrapper(true, mSwitchType, open);
             if (!mOpenAnimAdaptor.isValid()) {
                 Slog.w(TAG, "compose animations fail, skip");
-                clearBackAnimateTarget();
+                clearBackAnimateTarget(true /* cancel */);
                 return;
             }
             mOpenActivities = openingActivities;
@@ -1013,7 +1026,7 @@
                 Slog.e(TAG, "Previous animation is running " + this);
                 return false;
             }
-            clearBackAnimateTarget();
+            clearBackAnimateTarget(true /* cancel */);
             if (close == null || open == null || open.length == 0 || open.length > 2) {
                 Slog.e(TAG, "reset animation with null target close: "
                         + close + " open: " + Arrays.toString(open));
@@ -1102,7 +1115,19 @@
             return false;
         }
 
-        void finishPresentAnimations() {
+        void finishPresentAnimations(boolean cancel) {
+            if (mOpenActivities != null) {
+                for (int i = mOpenActivities.length - 1; i >= 0; --i) {
+                    final ActivityRecord resetActivity = mOpenActivities[i];
+                    if (resetActivity.mDisplayContent.isFixedRotationLaunchingApp(resetActivity)) {
+                        resetActivity.mDisplayContent
+                                .continueUpdateOrientationForDiffOrienLaunchingApp();
+                    }
+                    if (resetActivity.mLaunchTaskBehind) {
+                        restoreLaunchBehind(resetActivity, cancel);
+                    }
+                }
+            }
             if (mCloseAdaptor != null) {
                 mCloseAdaptor.mTarget.cancelAnimation();
                 mCloseAdaptor = null;
@@ -1111,15 +1136,6 @@
                 mOpenAnimAdaptor.cleanUp(mStartingSurfaceTargetMatch);
                 mOpenAnimAdaptor = null;
             }
-
-            if (mOpenActivities != null) {
-                for (int i = mOpenActivities.length - 1; i >= 0; --i) {
-                    final ActivityRecord resetActivity = mOpenActivities[i];
-                    if (resetActivity.mLaunchTaskBehind) {
-                        restoreLaunchBehind(resetActivity);
-                    }
-                }
-            }
         }
 
         void markStartingSurfaceMatch(SurfaceControl.Transaction reparentTransaction) {
@@ -1130,10 +1146,10 @@
             mOpenAnimAdaptor.reparentWindowlessSurfaceToTarget(reparentTransaction);
         }
 
-        void clearBackAnimateTarget() {
+        void clearBackAnimateTarget(boolean cancel) {
             if (mComposed) {
                 mComposed = false;
-                finishPresentAnimations();
+                finishPresentAnimations(cancel);
             }
             mWaitTransition = false;
             mStartingSurfaceTargetMatch = false;
@@ -1322,12 +1338,16 @@
                 }
                 // If there is only one adaptor, attach the windowless window to top activity,
                 // because fixed rotation only applies on activity.
-                // Note that embedded activity won't use fixed rotation.
-                final Configuration openConfig = mAdaptors.length == 1
+                // Note that embedded activity won't use fixed rotation. Also, there is only one
+                // animation target for closing task.
+                final boolean chooseActivity = mAdaptors.length == 1
+                        && (switchType == ACTIVITY_SWITCH || mainActivity.mDisplayContent
+                                .isFixedRotationLaunchingApp(mainActivity));
+                final Configuration openConfig = chooseActivity
                         ? mainActivity.getConfiguration() : openTask.getConfiguration();
                 mRequestedStartingSurfaceId = openTask.mAtmService.mTaskOrganizerController
                         .addWindowlessStartingSurface(openTask, mainActivity,
-                                mAdaptors.length == 1 ? mainActivity.getSurfaceControl()
+                                chooseActivity ? mainActivity.getSurfaceControl()
                                         : mRemoteAnimationTarget.leash, snapshot, openConfig,
                             new IWindowlessStartingSurfaceCallback.Stub() {
                             // Once the starting surface has been created in shell, it will call
@@ -1344,6 +1364,8 @@
                                     synchronized (openTask.mWmService.mGlobalLock) {
                                         if (mRequestedStartingSurfaceId != INVALID_TASK_ID) {
                                             mStartingSurface = sc;
+                                        } else {
+                                            sc.release();
                                         }
                                     }
                                 }
@@ -1582,12 +1604,20 @@
                     @NonNull ActivityRecord[] visibleOpenActivities) {
                 boolean needsLaunchBehind = true;
                 if (isSupportWindowlessSurface() && mShowWindowlessSurface && !mIsLaunchBehind) {
+                    boolean activitiesAreDrawn = false;
+                    for (int i = visibleOpenActivities.length - 1; i >= 0; --i) {
+                        // If the activity hasn't stopped, it's window should remain drawn.
+                        activitiesAreDrawn |= visibleOpenActivities[i].firstWindowDrawn;
+                    }
                     final WindowContainer mainOpen = openAnimationAdaptor.mAdaptors[0].mTarget;
                     final TaskSnapshot snapshot = getSnapshot(mainOpen, visibleOpenActivities);
-                    openAnimationAdaptor.createStartingSurface(snapshot);
-                    // set LaunchBehind if we are creating splash screen surface.
-                    needsLaunchBehind = snapshot == null
-                            && openAnimationAdaptor.mRequestedStartingSurfaceId != INVALID_TASK_ID;
+                    // Don't create starting surface if previous activities haven't stopped or
+                    // the snapshot does not exist.
+                    if (snapshot != null || !activitiesAreDrawn) {
+                        openAnimationAdaptor.createStartingSurface(snapshot);
+                    }
+                    // Only use LaunchBehind if snapshot does not exist.
+                    needsLaunchBehind = snapshot == null;
                 }
                 if (needsLaunchBehind) {
                     for (int i = visibleOpenActivities.length - 1; i >= 0; --i) {
@@ -1649,7 +1679,7 @@
                                 return;
                             }
                             if (!triggerBack) {
-                                clearBackAnimateTarget();
+                                clearBackAnimateTarget(true /* cancel */);
                             } else {
                                 mWaitTransition = true;
                             }
@@ -1732,25 +1762,23 @@
                 true /* notifyClients */);
     }
 
-    private static void restoreLaunchBehind(@NonNull ActivityRecord activity) {
+    private static void restoreLaunchBehind(@NonNull ActivityRecord activity, boolean cancel) {
         if (!activity.isAttached()) {
             // The activity was detached from hierarchy.
             return;
         }
-
-        if (activity.mDisplayContent.isFixedRotationLaunchingApp(activity)) {
-            activity.mDisplayContent.continueUpdateOrientationForDiffOrienLaunchingApp();
-        }
-
-        // Restore the launch-behind state.
-        activity.mTaskSupervisor.scheduleLaunchTaskBehindComplete(activity.token);
         activity.mLaunchTaskBehind = false;
-        // Ignore all change
-        activity.mTransitionController.mSnapshotController
-                .mActivitySnapshotController.clearOnBackPressedActivities();
         ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
                 "Setting Activity.mLauncherTaskBehind to false. Activity=%s",
                 activity);
+        if (cancel) {
+            // Restore the launch-behind state
+            // TODO b/347168362 Change status directly during collecting for a transition.
+            activity.mTaskSupervisor.scheduleLaunchTaskBehindComplete(activity.token);
+            // Ignore all change
+            activity.mTransitionController.mSnapshotController
+                    .mActivitySnapshotController.clearOnBackPressedActivities();
+        }
     }
 
     void checkAnimationReady(WallpaperController wallpaperController) {
@@ -1770,7 +1798,7 @@
         if (!mBackAnimationInProgress) {
             // gesture is already finished, do not start animation
             if (mPendingAnimation != null) {
-                clearBackAnimations();
+                clearBackAnimations(true /* cancel */);
                 mPendingAnimation = null;
             }
             return;
diff --git a/services/core/java/com/android/server/wm/BlackFrame.java b/services/core/java/com/android/server/wm/BlackFrame.java
index 0b2c851..ba4ab7d 100644
--- a/services/core/java/com/android/server/wm/BlackFrame.java
+++ b/services/core/java/com/android/server/wm/BlackFrame.java
@@ -22,7 +22,7 @@
 import android.view.Surface.OutOfResourcesException;
 import android.view.SurfaceControl;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 import java.io.PrintWriter;
 import java.util.function.Supplier;
diff --git a/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java b/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java
index 0c751cf..68a4172 100644
--- a/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java
+++ b/services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java
@@ -32,7 +32,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.protolog.ProtoLogGroup;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.window.flags.Flags;
 
 /**
@@ -110,12 +110,14 @@
         if (!isTreatmentEnabledForActivity(cameraActivity)) {
             return false;
         }
-        final int existingCameraCompatMode =
-                cameraActivity.mLetterboxUiController.getFreeformCameraCompatMode();
+        final int existingCameraCompatMode = cameraActivity.mAppCompatController
+                .getAppCompatCameraOverrides()
+                        .getFreeformCameraCompatMode();
         final int newCameraCompatMode = getCameraCompatMode(cameraActivity);
         if (newCameraCompatMode != existingCameraCompatMode) {
             mIsCameraCompatTreatmentPending = true;
-            cameraActivity.mLetterboxUiController.setFreeformCameraCompatMode(newCameraCompatMode);
+            cameraActivity.mAppCompatController.getAppCompatCameraOverrides()
+                    .setFreeformCameraCompatMode(newCameraCompatMode);
             forceUpdateActivityAndTask(cameraActivity);
             return true;
         } else {
@@ -134,8 +136,8 @@
                     mDisplayContent.mDisplayId, cameraId);
             return false;
         }
-        cameraActivity.mLetterboxUiController.setFreeformCameraCompatMode(
-                CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE);
+        cameraActivity.mAppCompatController.getAppCompatCameraOverrides()
+                .setFreeformCameraCompatMode(CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE);
         forceUpdateActivityAndTask(cameraActivity);
         mIsCameraCompatTreatmentPending = false;
         return true;
@@ -191,6 +193,6 @@
                 || mCameraStateMonitor.isCameraWithIdRunningForActivity(topActivity, cameraId)) {
             return false;
         }
-        return topActivity.mLetterboxUiController.isRefreshRequested();
+        return topActivity.mAppCompatController.getAppCompatCameraOverrides().isRefreshRequested();
     }
 }
diff --git a/services/core/java/com/android/server/wm/CameraStateMonitor.java b/services/core/java/com/android/server/wm/CameraStateMonitor.java
index ea7edea..a54141c 100644
--- a/services/core/java/com/android/server/wm/CameraStateMonitor.java
+++ b/services/core/java/com/android/server/wm/CameraStateMonitor.java
@@ -26,7 +26,7 @@
 import android.util.ArraySet;
 import android.util.Slog;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/services/core/java/com/android/server/wm/ClientLifecycleManager.java b/services/core/java/com/android/server/wm/ClientLifecycleManager.java
index e396f2b..bf34759 100644
--- a/services/core/java/com/android/server/wm/ClientLifecycleManager.java
+++ b/services/core/java/com/android/server/wm/ClientLifecycleManager.java
@@ -35,7 +35,6 @@
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.window.flags.Flags;
 
 /**
  * Class that is able to combine multiple client lifecycle transition requests and/or callbacks,
@@ -72,9 +71,8 @@
      * @throws RemoteException
      *
      * @see ClientTransaction
-     * @deprecated use {@link #scheduleTransactionItem(IApplicationThread, ClientTransactionItem)}.
      */
-    @Deprecated
+    @VisibleForTesting
     void scheduleTransaction(@NonNull ClientTransaction transaction) throws RemoteException {
         final IApplicationThread client = transaction.getClient();
         try {
@@ -114,22 +112,13 @@
      */
     void scheduleTransactionItem(@NonNull IApplicationThread client,
             @NonNull ClientTransactionItem transactionItem) throws RemoteException {
-        // The behavior is different depending on the flag.
-        // When flag is on, we wait until RootWindowContainer#performSurfacePlacementNoTrace to
-        // dispatch all pending transactions at once.
-        if (Flags.bundleClientTransactionFlag()) {
-            final ClientTransaction clientTransaction = getOrCreatePendingTransaction(client);
-            clientTransaction.addTransactionItem(transactionItem);
+        // Wait until RootWindowContainer#performSurfacePlacementNoTrace to dispatch all pending
+        // transactions at once.
+        final ClientTransaction clientTransaction = getOrCreatePendingTransaction(client);
+        clientTransaction.addTransactionItem(transactionItem);
 
-            onClientTransactionItemScheduled(clientTransaction,
-                    false /* shouldDispatchImmediately */);
-        } else {
-            // TODO(b/260873529): cleanup after launch.
-            final ClientTransaction clientTransaction = ClientTransaction.obtain(client);
-            clientTransaction.addTransactionItem(transactionItem);
-
-            scheduleTransaction(clientTransaction);
-        }
+        onClientTransactionItemScheduled(clientTransaction,
+                false /* shouldDispatchImmediately */);
     }
 
     void scheduleTransactionAndLifecycleItems(@NonNull IApplicationThread client,
@@ -156,27 +145,18 @@
             @NonNull ClientTransactionItem transactionItem,
             @NonNull ActivityLifecycleItem lifecycleItem,
             boolean shouldDispatchImmediately) throws RemoteException {
-        // The behavior is different depending on the flag.
-        // When flag is on, we wait until RootWindowContainer#performSurfacePlacementNoTrace to
-        // dispatch all pending transactions at once.
-        if (Flags.bundleClientTransactionFlag()) {
-            final ClientTransaction clientTransaction = getOrCreatePendingTransaction(client);
-            clientTransaction.addTransactionItem(transactionItem);
-            clientTransaction.addTransactionItem(lifecycleItem);
+        // Wait until RootWindowContainer#performSurfacePlacementNoTrace to dispatch all pending
+        // transactions at once.
+        final ClientTransaction clientTransaction = getOrCreatePendingTransaction(client);
+        clientTransaction.addTransactionItem(transactionItem);
+        clientTransaction.addTransactionItem(lifecycleItem);
 
-            onClientTransactionItemScheduled(clientTransaction, shouldDispatchImmediately);
-        } else {
-            // TODO(b/260873529): cleanup after launch.
-            final ClientTransaction clientTransaction = ClientTransaction.obtain(client);
-            clientTransaction.addTransactionItem(transactionItem);
-            clientTransaction.addTransactionItem(lifecycleItem);
-            scheduleTransaction(clientTransaction);
-        }
+        onClientTransactionItemScheduled(clientTransaction, shouldDispatchImmediately);
     }
 
     /** Executes all the pending transactions. */
     void dispatchPendingTransactions() {
-        if (!Flags.bundleClientTransactionFlag() || mPendingTransactions.isEmpty()) {
+        if (mPendingTransactions.isEmpty()) {
             return;
         }
         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "clientTransactionsDispatched");
@@ -196,9 +176,6 @@
 
     /** Executes the pending transaction for the given client process. */
     void dispatchPendingTransaction(@NonNull IApplicationThread client) {
-        if (!Flags.bundleClientTransactionFlag()) {
-            return;
-        }
         final ClientTransaction pendingTransaction = mPendingTransactions.remove(client.asBinder());
         if (pendingTransaction != null) {
             try {
diff --git a/services/core/java/com/android/server/wm/CompatModePackages.java b/services/core/java/com/android/server/wm/CompatModePackages.java
index b795987f..44202a2 100644
--- a/services/core/java/com/android/server/wm/CompatModePackages.java
+++ b/services/core/java/com/android/server/wm/CompatModePackages.java
@@ -48,7 +48,7 @@
 import android.util.SparseBooleanArray;
 import android.util.Xml;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
 
diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java
index d70a880..7e7073c 100644
--- a/services/core/java/com/android/server/wm/ContentRecorder.java
+++ b/services/core/java/com/android/server/wm/ContentRecorder.java
@@ -42,7 +42,7 @@
 import android.view.SurfaceControl;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.display.feature.DisplayManagerFlags;
 
 /**
diff --git a/services/core/java/com/android/server/wm/ContentRecordingController.java b/services/core/java/com/android/server/wm/ContentRecordingController.java
index b589085..283f819 100644
--- a/services/core/java/com/android/server/wm/ContentRecordingController.java
+++ b/services/core/java/com/android/server/wm/ContentRecordingController.java
@@ -23,7 +23,7 @@
 import android.view.ContentRecordingSession;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 /**
  * Orchestrates the handoff between displays if the recording session changes, and keeps track of
diff --git a/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java b/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java
index be44629..3b99954 100644
--- a/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java
+++ b/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java
@@ -36,7 +36,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.display.BrightnessSynchronizer;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.wm.utils.DisplayInfoOverrides.DisplayInfoFieldsUpdater;
 import com.android.window.flags.Flags;
 
diff --git a/services/core/java/com/android/server/wm/DeviceStateController.java b/services/core/java/com/android/server/wm/DeviceStateController.java
index 857e03d..475a504 100644
--- a/services/core/java/com/android/server/wm/DeviceStateController.java
+++ b/services/core/java/com/android/server/wm/DeviceStateController.java
@@ -16,9 +16,19 @@
 
 package com.android.server.wm;
 
+import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_REAR_DISPLAY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN;
+
 import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
+import android.hardware.devicestate.DeviceStateManager;
+import android.hardware.devicestate.feature.flags.FeatureFlags;
+import android.hardware.devicestate.feature.flags.FeatureFlagsImpl;
 import android.util.ArrayMap;
 import android.util.Pair;
 
@@ -28,6 +38,7 @@
 import com.android.internal.util.ArrayUtils;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Executor;
@@ -43,16 +54,16 @@
     @NonNull
     private final WindowManagerGlobalLock mWmLock;
     @NonNull
-    private final int[] mOpenDeviceStates;
+    private final List<Integer> mOpenDeviceStates;
     @NonNull
-    private final int[] mHalfFoldedDeviceStates;
+    private final List<Integer> mHalfFoldedDeviceStates;
     @NonNull
-    private final int[] mFoldedDeviceStates;
+    private final List<Integer> mFoldedDeviceStates;
     @NonNull
-    private final int[] mRearDisplayDeviceStates;
-    private final int mConcurrentDisplayDeviceState;
+    private final List<Integer> mRearDisplayDeviceStates;
+    private final List<Integer> mConcurrentDisplayDeviceStates;
     @NonNull
-    private final int[] mReverseRotationAroundZAxisStates;
+    private final List<Integer> mReverseRotationAroundZAxisStates;
     @GuardedBy("mWmLock")
     @NonNull
     @VisibleForTesting
@@ -76,18 +87,55 @@
     DeviceStateController(@NonNull Context context, @NonNull WindowManagerGlobalLock wmLock) {
         mWmLock = wmLock;
 
-        mOpenDeviceStates = context.getResources()
-                .getIntArray(R.array.config_openDeviceStates);
-        mHalfFoldedDeviceStates = context.getResources()
-                .getIntArray(R.array.config_halfFoldedDeviceStates);
-        mFoldedDeviceStates = context.getResources()
-                .getIntArray(R.array.config_foldedDeviceStates);
-        mRearDisplayDeviceStates = context.getResources()
-                .getIntArray(R.array.config_rearDisplayDeviceStates);
-        mConcurrentDisplayDeviceState = context.getResources()
-                .getInteger(R.integer.config_deviceStateConcurrentRearDisplay);
-        mReverseRotationAroundZAxisStates = context.getResources()
-                .getIntArray(R.array.config_deviceStatesToReverseDefaultDisplayRotationAroundZAxis);
+        final FeatureFlags deviceStateManagerFlags = new FeatureFlagsImpl();
+        if (deviceStateManagerFlags.deviceStatePropertyMigration()) {
+            mOpenDeviceStates = new ArrayList<>();
+            mHalfFoldedDeviceStates = new ArrayList<>();
+            mFoldedDeviceStates = new ArrayList<>();
+            mRearDisplayDeviceStates = new ArrayList<>();
+            mConcurrentDisplayDeviceStates = new ArrayList<>();
+
+            final DeviceStateManager deviceStateManager =
+                    context.getSystemService(DeviceStateManager.class);
+            final List<android.hardware.devicestate.DeviceState> deviceStates =
+                    deviceStateManager.getSupportedDeviceStates();
+
+            for (int i = 0; i < deviceStates.size(); i++) {
+                final android.hardware.devicestate.DeviceState state = deviceStates.get(i);
+                if (state.hasProperty(
+                        PROPERTY_FEATURE_REAR_DISPLAY)) {
+                    mRearDisplayDeviceStates.add(state.getIdentifier());
+                } else if (state.hasProperty(
+                        PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT)) {
+                    mConcurrentDisplayDeviceStates.add(state.getIdentifier());
+                } else if (state.hasProperty(
+                        PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY)) {
+                    mFoldedDeviceStates.add(state.getIdentifier());
+                } else if (state.hasProperty(
+                        PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY)) {
+                    if (state.hasProperty(
+                            PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN)) {
+                        mHalfFoldedDeviceStates.add(state.getIdentifier());
+                    } else {
+                        mOpenDeviceStates.add(state.getIdentifier());
+                    }
+                }
+            }
+        } else {
+            mOpenDeviceStates = copyIntArrayToList(context.getResources()
+                    .getIntArray(R.array.config_openDeviceStates));
+            mHalfFoldedDeviceStates = copyIntArrayToList(context.getResources()
+                    .getIntArray(R.array.config_halfFoldedDeviceStates));
+            mFoldedDeviceStates = copyIntArrayToList(context.getResources()
+                    .getIntArray(R.array.config_foldedDeviceStates));
+            mRearDisplayDeviceStates = copyIntArrayToList(context.getResources()
+                    .getIntArray(R.array.config_rearDisplayDeviceStates));
+            mConcurrentDisplayDeviceStates = new ArrayList<>(List.of(context.getResources()
+                    .getInteger(R.integer.config_deviceStateConcurrentRearDisplay)));
+        }
+
+        mReverseRotationAroundZAxisStates = copyIntArrayToList(context.getResources().getIntArray(
+                R.array.config_deviceStatesToReverseDefaultDisplayRotationAroundZAxis));
         mMatchBuiltInDisplayOrientationToDefaultDisplay = context.getResources()
                 .getBoolean(R.bool
                         .config_matchSecondaryInternalDisplaysOrientationToReverseDefaultDisplay);
@@ -145,7 +193,6 @@
      */
     public void onDeviceStateReceivedByDisplayManager(int state) {
         mCurrentState = state;
-
         final DeviceState deviceState;
         if (ArrayUtils.contains(mHalfFoldedDeviceStates, state)) {
             deviceState = DeviceState.HALF_FOLDED;
@@ -155,9 +202,10 @@
             deviceState = DeviceState.REAR;
         } else if (ArrayUtils.contains(mOpenDeviceStates, state)) {
             deviceState = DeviceState.OPEN;
-        } else if (state == mConcurrentDisplayDeviceState) {
+        } else if (ArrayUtils.contains(mConcurrentDisplayDeviceStates, state)) {
             deviceState = DeviceState.CONCURRENT;
         } else {
+
             deviceState = DeviceState.UNKNOWN;
         }
 
@@ -190,4 +238,16 @@
         }
         return entries;
     }
+
+    @NonNull
+    private List<Integer> copyIntArrayToList(@Nullable int[] values) {
+        if (values == null) {
+            return Collections.emptyList();
+        }
+        final List<Integer> valueList = new ArrayList<>();
+        for (int i = 0; i < values.length; i++) {
+            valueList.add(values[i]);
+        }
+        return valueList;
+    }
 }
diff --git a/services/core/java/com/android/server/wm/DimmerAnimationHelper.java b/services/core/java/com/android/server/wm/DimmerAnimationHelper.java
index 735c73a..22fa88f 100644
--- a/services/core/java/com/android/server/wm/DimmerAnimationHelper.java
+++ b/services/core/java/com/android/server/wm/DimmerAnimationHelper.java
@@ -29,7 +29,7 @@
 import android.util.proto.ProtoOutputStream;
 import android.view.SurfaceControl;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 import java.io.PrintWriter;
 
diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java
index 0006bd2..def495f 100644
--- a/services/core/java/com/android/server/wm/DisplayArea.java
+++ b/services/core/java/com/android/server/wm/DisplayArea.java
@@ -45,7 +45,7 @@
 import android.window.IDisplayAreaOrganizer;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.policy.WindowManagerPolicy;
 
 import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java
index 3dc3be9..8f471d7 100644
--- a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java
+++ b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java
@@ -33,7 +33,7 @@
 import android.window.IDisplayAreaOrganizerController;
 import android.window.WindowContainerToken;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 import java.util.ArrayList;
 import java.util.HashMap;
diff --git a/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java b/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
index 8c52288..bb596cc 100644
--- a/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
+++ b/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
@@ -42,7 +42,7 @@
 
 import com.android.internal.annotations.Keep;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.policy.WindowManagerPolicy;
 
 import java.util.ArrayList;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index ad711cb..3652c4d 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -254,7 +254,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.ToBooleanFunction;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.internal.util.function.pooled.PooledPredicate;
@@ -263,7 +263,6 @@
 import com.android.server.wm.utils.RegionUtils;
 import com.android.server.wm.utils.RotationCache;
 import com.android.server.wm.utils.WmDisplayCutout;
-import com.android.window.flags.Flags;
 
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
@@ -475,14 +474,8 @@
     private final DisplayPolicy mDisplayPolicy;
     private final DisplayRotation mDisplayRotation;
 
-    @Nullable
-    final DisplayRotationCompatPolicy mDisplayRotationCompatPolicy;
-    @Nullable
-    final CameraCompatFreeformPolicy mCameraCompatFreeformPolicy;
-    @Nullable
-    final CameraStateMonitor mCameraStateMonitor;
-    @Nullable
-    final ActivityRefresher mActivityRefresher;
+    @NonNull
+    AppCompatCameraPolicy mAppCompatCameraPolicy;
 
     DisplayFrames mDisplayFrames;
     final DisplayUpdater mDisplayUpdater;
@@ -1191,6 +1184,7 @@
 
         mDeviceStateController = deviceStateController;
 
+        mAppCompatCameraPolicy = new AppCompatCameraPolicy(mWmService, this);
         mDisplayPolicy = new DisplayPolicy(mWmService, this);
         mDisplayRotation = new DisplayRotation(mWmService, this, mDisplayInfo.address,
                 mDeviceStateController, root.getDisplayRotationCoordinator());
@@ -1231,40 +1225,6 @@
         onDisplayChanged(this);
         updateDisplayAreaOrganizers();
 
-        // Not checking DeviceConfig value here to allow enabling via DeviceConfig
-        // without the need to restart the device.
-        final boolean shouldCreateDisplayRotationCompatPolicy =
-                mWmService.mLetterboxConfiguration.isCameraCompatTreatmentEnabledAtBuildTime();
-        final boolean shouldCreateCameraCompatFreeformPolicy = Flags.cameraCompatForFreeform()
-                && DesktopModeLaunchParamsModifier.canEnterDesktopMode(mWmService.mContext);
-        if (shouldCreateDisplayRotationCompatPolicy || shouldCreateCameraCompatFreeformPolicy) {
-            mCameraStateMonitor = new CameraStateMonitor(this, mWmService.mH);
-            mActivityRefresher = new ActivityRefresher(mWmService, mWmService.mH);
-            if (shouldCreateDisplayRotationCompatPolicy) {
-                mDisplayRotationCompatPolicy = new DisplayRotationCompatPolicy(this,
-                        mCameraStateMonitor, mActivityRefresher);
-                mDisplayRotationCompatPolicy.start();
-            } else {
-                mDisplayRotationCompatPolicy = null;
-            }
-
-            if (shouldCreateCameraCompatFreeformPolicy) {
-                mCameraCompatFreeformPolicy = new CameraCompatFreeformPolicy(this,
-                        mCameraStateMonitor, mActivityRefresher);
-                mCameraCompatFreeformPolicy.start();
-            } else {
-                mCameraCompatFreeformPolicy = null;
-            }
-
-            mCameraStateMonitor.startListeningToCameraState();
-        } else {
-            // These are to satisfy the `final` check.
-            mCameraStateMonitor = null;
-            mActivityRefresher = null;
-            mDisplayRotationCompatPolicy = null;
-            mCameraCompatFreeformPolicy = null;
-        }
-
         mRotationReversionController = new DisplayRotationReversionController(this);
 
         mInputMonitor = new InputMonitor(mWmService, this);
@@ -1280,6 +1240,7 @@
                 R.bool.config_defaultInTouchMode);
         mWmService.mInputManager.setInTouchMode(mInTouchMode, mWmService.MY_PID, mWmService.MY_UID,
                 /* hasPermission= */ true, mDisplayId);
+        mAppCompatCameraPolicy.start();
     }
 
     private void beginHoldScreenUpdate() {
@@ -1314,15 +1275,6 @@
         }
     }
 
-    /**
-     * @return The {@link DisplayRotationCompatPolicy} for this DisplayContent
-     */
-    // TODO(b/335387481) Allow access to DisplayRotationCompatPolicy only with getters
-    @Nullable
-    DisplayRotationCompatPolicy getDisplayRotationCompatPolicy() {
-        return mDisplayRotationCompatPolicy;
-    }
-
     @Override
     void migrateToNewSurfaceControl(Transaction t) {
         t.remove(mSurfaceControl);
@@ -1802,6 +1754,82 @@
         return mDisplayRotation.updateOrientation(orientation, forceUpdate);
     }
 
+    @Nullable
+    private ActivityRecord getLastOrientationSourceApp() {
+        final WindowContainer<?> orientationSrc = getLastOrientationSource();
+        return orientationSrc != null ? orientationSrc.asActivityRecord() : null;
+    }
+
+    /**
+     * This is called when the display rotation is changed. If the current top activity which
+     * decides the display orientation is not opaque, all non-top visible activities with
+     * different fixed orientations will still keep their original appearances.
+     */
+    void applyFixedRotationForNonTopVisibleActivityIfNeeded() {
+        if (!mWmService.mFlags.mRespectNonTopVisibleFixedOrientation) {
+            return;
+        }
+        final ActivityRecord orientationSrcApp = getLastOrientationSourceApp();
+        if (orientationSrcApp == null || orientationSrcApp.fillsParent()) {
+            return;
+        }
+        final int topOrientation = orientationSrcApp.getRequestedOrientation();
+        if (topOrientation == SCREEN_ORIENTATION_UNSPECIFIED) {
+            return;
+        }
+        forAllActivities(ar -> {
+            if (!ar.isVisibleRequested()) {
+                return true;
+            }
+            applyFixedRotationForNonTopVisibleActivityIfNeeded(ar, topOrientation);
+            return false;
+        }, true /* traverseTopToBottom */);
+    }
+
+    /**
+     * This is called when a non-top activity becomes visible. Such when moving a task which
+     * contains 2 activities with different fixed orientations, and if the top one is translucent,
+     * then the bottom one will apply the fixed rotation transform for its orientation.
+     */
+    void applyFixedRotationForNonTopVisibleActivityIfNeeded(@NonNull ActivityRecord ar) {
+        if (!mWmService.mFlags.mRespectNonTopVisibleFixedOrientation) {
+            return;
+        }
+        final ActivityRecord orientationSrcApp = getLastOrientationSourceApp();
+        if (orientationSrcApp != null) {
+            applyFixedRotationForNonTopVisibleActivityIfNeeded(ar,
+                    orientationSrcApp.getRequestedOrientation());
+        }
+    }
+
+    /**
+     * If the given visible activity uses a different fixed orientation than the current top, the
+     * fixed rotation transform will be applied to respect its requested appearance.
+     */
+    private void applyFixedRotationForNonTopVisibleActivityIfNeeded(@NonNull ActivityRecord ar,
+            @ActivityInfo.ScreenOrientation int topOrientation) {
+        final int orientation = ar.getRequestedOrientation();
+        if (orientation == topOrientation || ar.inMultiWindowMode()
+                || ar.getRequestedConfigurationOrientation() == ORIENTATION_UNDEFINED) {
+            return;
+        }
+        final int displayRotation = getRotation();
+        final int rotation = ar.isVisible()
+                ? ar.getWindowConfiguration().getDisplayRotation()
+                : mDisplayRotation.rotationForOrientation(orientation, displayRotation);
+        if (rotation == displayRotation) {
+            return;
+        }
+        startFixedRotationTransform(ar, rotation);
+        final WindowState wallpaperTarget = mWallpaperController.getWallpaperTarget();
+        if (wallpaperTarget != null && wallpaperTarget.mActivityRecord == ar) {
+            final WindowState wp = mWallpaperController.getTopVisibleWallpaper();
+            if (wp != null) {
+                wp.mToken.linkFixedRotationTransform(ar);
+            }
+        }
+    }
+
     @Override
     boolean isSyncFinished(BLASTSyncEngine.SyncGroup group) {
         // Do not consider children because if they are requested to be synced, they should be
@@ -1870,10 +1898,23 @@
             return false;
         }
         if (r.hasFixedRotationTransform()) {
+            if (mWmService.mFlags.mRespectNonTopVisibleFixedOrientation
+                    && mFixedRotationLaunchingApp == null) {
+                // It could be finishing the previous top translucent activity, and the next fixed
+                // orientation activity becomes the current top.
+                setFixedRotationLaunchingAppUnchecked(r,
+                        r.getWindowConfiguration().getDisplayRotation());
+            }
             // It has been set and not yet finished.
             return true;
         }
-        if (!r.occludesParent() || r.isReportedDrawn()) {
+        if (mWmService.mFlags.mRespectNonTopVisibleFixedOrientation) {
+            if (r.isReportedDrawn()) {
+                // It is late for a drawn app. Either this is already a stable state or it needs
+                // a rotation animation to handle the change.
+                return false;
+            }
+        } else if (!r.occludesParent() || r.isReportedDrawn()) {
             // While entering or leaving a translucent or floating activity (e.g. dialog style),
             // there is a visible activity in the background. Then it still needs rotation animation
             // to cover the activity configuration change.
@@ -2889,12 +2930,10 @@
             }
         }
 
-        if (mDisplayRotationCompatPolicy != null) {
-            int compatOrientation = mDisplayRotationCompatPolicy.getOrientation();
-            if (compatOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
-                mLastOrientationSource = null;
-                return compatOrientation;
-            }
+        final int compatOrientation = mAppCompatCameraPolicy.getOrientation();
+        if (compatOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
+            mLastOrientationSource = null;
+            return compatOrientation;
         }
 
         final int orientation = super.getOrientation();
@@ -3364,17 +3403,7 @@
         getPendingTransaction().apply();
         mWmService.mWindowPlacerLocked.requestTraversal();
 
-        if (mDisplayRotationCompatPolicy != null) {
-            mDisplayRotationCompatPolicy.dispose();
-        }
-
-        if (mCameraCompatFreeformPolicy != null) {
-            mCameraCompatFreeformPolicy.dispose();
-        }
-
-        if (mCameraStateMonitor != null) {
-            mCameraStateMonitor.dispose();
-        }
+        mAppCompatCameraPolicy.dispose();
     }
 
     /** Returns true if a removal action is still being deferred. */
@@ -5047,9 +5076,6 @@
         } finally {
             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
-        if (!com.android.window.flags.Flags.removePrepareSurfaceInPlacement()) {
-            prepareSurfaces();
-        }
 
         // This should be called after the insets have been dispatched to clients and we have
         // committed finish drawing windows.
@@ -6986,7 +7012,11 @@
                 // In most cases this is a no-op if the activity doesn't have fixed rotation.
                 // Otherwise it could be from finishing recents animation while the display has
                 // different orientation.
-                r.finishFixedRotationTransform();
+                if (!mWmService.mFlags.mRespectNonTopVisibleFixedOrientation) {
+                    r.finishFixedRotationTransform();
+                } else if (!r.isVisible()) {
+                    r.finishFixedRotationTransform();
+                }
                 return;
             }
             if (mFixedRotationLaunchingApp.hasFixedRotationTransform(r)) {
@@ -7001,7 +7031,12 @@
                 // E.g. activity A transferred starting window to B, only A will receive transition
                 // finished event. A doesn't have fixed rotation but B is the rotated launching app.
                 final Task task = r.getTask();
-                if (task == null || task != mFixedRotationLaunchingApp.getTask()) {
+                if (task != mFixedRotationLaunchingApp.getTask()
+                        // When closing a translucent task A (r.fillsParent() is false) to a
+                        // visible task B, because only A has visibility change, there is only A's
+                        // transition callback. Then it still needs to update orientation for B.
+                        && (!mWmService.mFlags.mRespectNonTopVisibleFixedOrientation
+                                || r.fillsParent())) {
                     // Different tasks won't be in one activity transition animation.
                     return;
                 }
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 4a59fc2..80362a4 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -132,7 +132,7 @@
 import com.android.internal.policy.ForceShowNavBarSettingsObserver;
 import com.android.internal.policy.GestureNavigationSettingsObserver;
 import com.android.internal.policy.ScreenDecorationsUtils;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.statusbar.LetterboxDetails;
 import com.android.internal.util.ScreenshotHelper;
 import com.android.internal.util.ScreenshotRequest;
@@ -782,7 +782,6 @@
     }
 
     private void onDisplaySwitchFinished() {
-        mDisplayContent.mWallpaperController.onDisplaySwitchFinished();
         mDisplayContent.mDisplayUpdater.onDisplaySwitching(false);
     }
 
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index afcf364..d2976b0 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -80,7 +80,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.LocalServices;
 import com.android.server.UiThread;
 import com.android.server.policy.WindowManagerPolicy;
@@ -627,6 +627,7 @@
 
         mRotation = rotation;
 
+        mDisplayContent.applyFixedRotationForNonTopVisibleActivityIfNeeded();
         mDisplayContent.setLayoutNeeded();
         mDisplayContent.mWaitingForConfig = true;
 
@@ -2294,10 +2295,8 @@
                     mInHalfFoldTransition = false;
                     mDeviceState = DeviceStateController.DeviceState.UNKNOWN;
                 }
-                mDisplayRotationCompatPolicySummary = dc.mDisplayRotationCompatPolicy == null
-                        ? null
-                        : dc.mDisplayRotationCompatPolicy
-                                .getSummaryForDisplayRotationHistoryRecord();
+                mDisplayRotationCompatPolicySummary = dc.mAppCompatCameraPolicy
+                        .getSummaryForDisplayRotationHistoryRecord();
                 mRotationReversionSlots =
                         dr.mDisplayContent.getRotationReversionController().getSlotsCopy();
             }
diff --git a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
index 6ecafdb..9998e1a 100644
--- a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java
@@ -42,7 +42,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.UiThread;
 
 /**
@@ -228,9 +228,11 @@
                 != lastReportedConfig.windowConfiguration.getDisplayRotation());
         return isTreatmentEnabledForDisplay()
                 && isTreatmentEnabledForActivity(activity)
-                && activity.mLetterboxUiController.shouldRefreshActivityForCameraCompat()
+                && activity.mAppCompatController.getAppCompatCameraOverrides()
+                    .shouldRefreshActivityForCameraCompat()
                 && (displayRotationChanged
-                || activity.mLetterboxUiController.isCameraCompatSplitScreenAspectRatioAllowed());
+                || activity.mAppCompatController.getAppCompatCameraOverrides()
+                        .isCameraCompatSplitScreenAspectRatioAllowed());
     }
 
     /**
@@ -254,7 +256,8 @@
     boolean isActivityEligibleForOrientationOverride(@NonNull ActivityRecord activity) {
         return isTreatmentEnabledForDisplay()
                 && isCameraActive(activity, /* mustBeFullscreen */ true)
-                && activity.mLetterboxUiController.shouldForceRotateForCameraCompat();
+                && activity.mAppCompatController.getAppCompatCameraOverrides()
+                    .shouldForceRotateForCameraCompat();
     }
 
     /**
@@ -286,7 +289,8 @@
                 // handle dynamic changes so we shouldn't force rotate them.
                 && activity.getOverrideOrientation() != SCREEN_ORIENTATION_NOSENSOR
                 && activity.getOverrideOrientation() != SCREEN_ORIENTATION_LOCKED
-                && activity.mLetterboxUiController.shouldForceRotateForCameraCompat();
+                && activity.mAppCompatController.getAppCompatCameraOverrides()
+                    .shouldForceRotateForCameraCompat();
     }
 
     @Override
@@ -295,7 +299,7 @@
         // Checking whether an activity in fullscreen rather than the task as this camera
         // compat treatment doesn't cover activity embedding.
         if (cameraActivity.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
-            cameraActivity.mLetterboxUiController.recomputeConfigurationForCameraCompatIfNeeded();
+            recomputeConfigurationForCameraCompatIfNeeded(cameraActivity);
             mDisplayContent.updateOrientation();
             return true;
         }
@@ -362,7 +366,7 @@
                 || topActivity.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
             return true;
         }
-        topActivity.mLetterboxUiController.recomputeConfigurationForCameraCompatIfNeeded();
+        recomputeConfigurationForCameraCompatIfNeeded(topActivity);
         mDisplayContent.updateOrientation();
         return true;
     }
@@ -377,4 +381,12 @@
         }
         return mActivityRefresher.isActivityRefreshing(topActivity);
     }
+
+    private void recomputeConfigurationForCameraCompatIfNeeded(
+            @NonNull ActivityRecord activityRecord) {
+        if (activityRecord.mAppCompatController.getAppCompatCameraOverrides()
+                .shouldRecomputeConfigurationForCameraCompat()) {
+            activityRecord.recomputeConfiguration();
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/DisplayRotationReversionController.java b/services/core/java/com/android/server/wm/DisplayRotationReversionController.java
index 50b29ec..b955738 100644
--- a/services/core/java/com/android/server/wm/DisplayRotationReversionController.java
+++ b/services/core/java/com/android/server/wm/DisplayRotationReversionController.java
@@ -26,7 +26,7 @@
 import android.content.ActivityInfoProto;
 import android.view.Surface;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 /**
  * Defines the behavior of reversion from device rotation overrides.
@@ -61,7 +61,7 @@
     }
 
     boolean isRotationReversionEnabled() {
-        return mDisplayContent.mDisplayRotationCompatPolicy != null
+        return mDisplayContent.mAppCompatCameraPolicy.hasDisplayRotationCompatPolicy()
                 || mDisplayContent.getDisplayRotation().mFoldController != null
                 || mDisplayContent.getIgnoreOrientationRequest();
     }
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java b/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
index c79565a..8bd8098 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettingsProvider.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.os.UserHandle.USER_SYSTEM;
 import static android.view.Display.TYPE_VIRTUAL;
 import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
 import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
@@ -27,6 +28,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.WindowConfiguration;
 import android.os.Environment;
 import android.util.ArrayMap;
@@ -42,6 +44,7 @@
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
 import com.android.server.wm.DisplayWindowSettings.SettingsProvider;
+import com.android.window.flags.Flags;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -53,6 +56,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * Implementation of {@link SettingsProvider} that reads the base settings provided in a display
@@ -91,11 +95,11 @@
     @NonNull
     private ReadableSettings mBaseSettings;
     @NonNull
-    private final WritableSettings mOverrideSettings;
+    private WritableSettings mOverrideSettings;
 
     DisplayWindowSettingsProvider() {
         this(new AtomicFileStorage(getVendorSettingsFile()),
-                new AtomicFileStorage(getOverrideSettingsFile()));
+                new AtomicFileStorage(getOverrideSettingsFileForUser(USER_SYSTEM)));
     }
 
     @VisibleForTesting
@@ -133,6 +137,48 @@
         mBaseSettings = new ReadableSettings(baseSettingsStorage);
     }
 
+    /**
+     * Overrides the storage that should be used to save override settings for a user.
+     *
+     * @see #DATA_DISPLAY_SETTINGS_FILE_PATH
+     */
+    void setOverrideSettingsForUser(@UserIdInt int userId) {
+        if (!Flags.perUserDisplayWindowSettings()) {
+            return;
+        }
+        final AtomicFile settingsFile = getOverrideSettingsFileForUser(userId);
+        setOverrideSettingsStorage(new AtomicFileStorage(settingsFile));
+    }
+
+    /**
+     * Removes display override settings that are no longer associated with active displays.
+     * This is necessary because displays can be dynamically added or removed during
+     * the system's lifecycle (e.g., user switch, system server restart).
+     *
+     * @param root The root window container used to obtain the currently active displays.
+     */
+    void removeStaleDisplaySettings(@NonNull RootWindowContainer root) {
+        if (!Flags.perUserDisplayWindowSettings()) {
+            return;
+        }
+        final Set<String> displayIdentifiers = new ArraySet<>();
+        root.forAllDisplays(dc -> {
+            final String identifier = mOverrideSettings.getIdentifier(dc.getDisplayInfo());
+            displayIdentifiers.add(identifier);
+        });
+        mOverrideSettings.removeStaleDisplaySettings(displayIdentifiers);
+    }
+
+    /**
+     * Overrides the storage that should be used to save override settings.
+     *
+     * @see #setOverrideSettingsForUser(int)
+     */
+    @VisibleForTesting
+    void setOverrideSettingsStorage(@NonNull WritableSettingsStorage overrideSettingsStorage) {
+        mOverrideSettings = new WritableSettings(overrideSettingsStorage);
+    }
+
     @Override
     @NonNull
     public SettingsEntry getSettings(@NonNull DisplayInfo info) {
@@ -302,6 +348,12 @@
             mVirtualDisplayIdentifiers.remove(identifier);
         }
 
+        void removeStaleDisplaySettings(@NonNull Set<String> currentDisplayIdentifiers) {
+            if (mSettings.retainAll(currentDisplayIdentifiers)) {
+                writeSettings();
+            }
+        }
+
         private void writeSettings() {
             final FileData fileData = new FileData();
             fileData.mIdentifierType = mIdentifierType;
@@ -332,9 +384,14 @@
     }
 
     @NonNull
-    private static AtomicFile getOverrideSettingsFile() {
-        final File overrideSettingsFile = new File(Environment.getDataDirectory(),
-                DATA_DISPLAY_SETTINGS_FILE_PATH);
+    private static AtomicFile getOverrideSettingsFileForUser(@UserIdInt int userId) {
+        final File directory;
+        if (userId == USER_SYSTEM || !Flags.perUserDisplayWindowSettings()) {
+            directory = Environment.getDataDirectory();
+        } else {
+            directory = Environment.getDataSystemCeDirectory(userId);
+        }
+        final File overrideSettingsFile = new File(directory, DATA_DISPLAY_SETTINGS_FILE_PATH);
         return new AtomicFile(overrideSettingsFile, WM_DISPLAY_COMMIT_TAG);
     }
 
diff --git a/services/core/java/com/android/server/wm/DragDropController.java b/services/core/java/com/android/server/wm/DragDropController.java
index 30f2d0d..6abef8b 100644
--- a/services/core/java/com/android/server/wm/DragDropController.java
+++ b/services/core/java/com/android/server/wm/DragDropController.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.content.ClipDescription.EXTRA_HIDE_DRAG_SOURCE_TASK_ID;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.View.DRAG_FLAG_GLOBAL;
 import static android.view.View.DRAG_FLAG_GLOBAL_SAME_APPLICATION;
@@ -217,6 +218,11 @@
                     mDragState.mToken = dragToken;
                     mDragState.mDisplayContent = displayContent;
                     mDragState.mData = data;
+                    mDragState.mCallingTaskIdToHide = shouldMoveCallingTaskToBack(callingWin,
+                            flags);
+                    if (DEBUG_DRAG) {
+                        Slog.d(TAG_WM, "Calling task to hide=" + mDragState.mCallingTaskIdToHide);
+                    }
 
                     if ((flags & View.DRAG_FLAG_ACCESSIBILITY_ACTION) == 0) {
                         final Display display = displayContent.getDisplay();
@@ -364,6 +370,23 @@
     }
 
     /**
+     * If the calling window's task should be hidden for the duration of the drag, this returns the
+     * task id of the task (or -1 otherwise).
+     */
+    private int shouldMoveCallingTaskToBack(WindowState callingWin, int flags) {
+        if ((flags & View.DRAG_FLAG_HIDE_CALLING_TASK_ON_DRAG_START) == 0) {
+            // Not requested by the app
+            return -1;
+        }
+        final ActivityRecord callingActivity = callingWin.getActivityRecord();
+        if (callingActivity == null || callingActivity.getTask() == null) {
+            // Not an activity
+            return -1;
+        }
+        return callingActivity.getTask().mTaskId;
+    }
+
+    /**
      * Notifies the unhandled drag listener if needed.
      * @return whether the listener was notified and subsequent drag completion should be deferred
      *         until the listener calls back
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index e3827aa..ba74f50 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.content.ClipDescription.EXTRA_HIDE_DRAG_SOURCE_TASK_ID;
 import static android.content.ClipDescription.MIMETYPE_APPLICATION_ACTIVITY;
 import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
 import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
@@ -48,6 +49,7 @@
 import android.os.Binder;
 import android.os.Build;
 import android.os.IBinder;
+import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.Trace;
 import android.os.UserHandle;
@@ -64,7 +66,7 @@
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.Interpolator;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.view.IDragAndDropPermissions;
 import com.android.server.LocalServices;
 import com.android.server.pm.UserManagerInternal;
@@ -117,6 +119,8 @@
     InputInterceptor mInputInterceptor;
     ArrayList<WindowState> mNotifiedWindows;
     boolean mDragInProgress;
+    // Set to non -1 value if a valid app requests DRAG_FLAG_HIDE_CALLING_TASK_ON_DRAG_START
+    int mCallingTaskIdToHide;
     /**
      * Whether if animation is completed. Needs to be volatile to update from the animation thread
      * without having a WM lock.
@@ -320,12 +324,12 @@
                 }
             }
             final boolean targetInterceptsGlobalDrag = targetInterceptsGlobalDrag(touchedWin);
-            return obtainDragEvent(DragEvent.ACTION_DROP, x, y, mData,
+            return obtainDragEvent(DragEvent.ACTION_DROP, x, y, mDataDescription, mData,
                     /* includeDragSurface= */ targetInterceptsGlobalDrag,
                     /* includeDragFlags= */ targetInterceptsGlobalDrag,
                     dragAndDropPermissions);
         } else {
-            return obtainDragEvent(DragEvent.ACTION_DROP, x, y, mData,
+            return obtainDragEvent(DragEvent.ACTION_DROP, x, y, mDataDescription, mData,
                     /* includeDragSurface= */ includePrivateInfo,
                     /* includeDragFlags= */ includePrivateInfo,
                     null /* dragAndDropPermissions */);
@@ -527,11 +531,24 @@
                 Slog.d(TAG_WM, "Sending DRAG_STARTED to new window " + newWin);
             }
             // Only allow the extras to be dispatched to a global-intercepting drag target
-            ClipData data = interceptsGlobalDrag ? mData.copyForTransferWithActivityInfo() : null;
+            ClipData data = null;
+            if (interceptsGlobalDrag) {
+                data = mData.copyForTransferWithActivityInfo();
+                PersistableBundle extras = data.getDescription().getExtras() != null
+                        ? data.getDescription().getExtras()
+                        : new PersistableBundle();
+                extras.putInt(EXTRA_HIDE_DRAG_SOURCE_TASK_ID, mCallingTaskIdToHide);
+                // Note that setting extras always copies the bundle
+                data.getDescription().setExtras(extras);
+                if (DEBUG_DRAG) {
+                    Slog.d(TAG_WM, "Adding EXTRA_HIDE_DRAG_SOURCE_TASK_ID=" + mCallingTaskIdToHide);
+                }
+            }
+            ClipDescription description = data != null ? data.getDescription() : mDataDescription;
             DragEvent event = obtainDragEvent(DragEvent.ACTION_DRAG_STARTED,
                     newWin.translateToWindowX(touchX), newWin.translateToWindowY(touchY),
-                    data, false /* includeDragSurface */, true /* includeDragFlags */,
-                    null /* dragAndDropPermission */);
+                    description, data, false /* includeDragSurface */,
+                    true /* includeDragFlags */, null /* dragAndDropPermission */);
             try {
                 newWin.mClient.dispatchDragEvent(event);
                 // track each window that we've notified that the drag is starting
@@ -700,37 +717,51 @@
         return mDragInProgress;
     }
 
-    private DragEvent obtainDragEvent(int action, float x, float y, ClipData data,
-            boolean includeDragSurface, boolean includeDragFlags,
+    private DragEvent obtainDragEvent(int action, float x, float y, ClipDescription description,
+            ClipData data, boolean includeDragSurface, boolean includeDragFlags,
             IDragAndDropPermissions dragAndDropPermissions) {
         return DragEvent.obtain(action, x, y, mThumbOffsetX, mThumbOffsetY,
                 includeDragFlags ? mFlags : 0,
-                null  /* localState */, mDataDescription, data,
+                null  /* localState */, description, data,
                 includeDragSurface ? mSurfaceControl : null,
                 dragAndDropPermissions, false /* result */);
     }
 
     private ValueAnimator createReturnAnimationLocked() {
-        final ValueAnimator animator = ValueAnimator.ofPropertyValuesHolder(
-                PropertyValuesHolder.ofFloat(
-                        ANIMATED_PROPERTY_X, mCurrentX - mThumbOffsetX,
-                        mOriginalX - mThumbOffsetX),
-                PropertyValuesHolder.ofFloat(
-                        ANIMATED_PROPERTY_Y, mCurrentY - mThumbOffsetY,
-                        mOriginalY - mThumbOffsetY),
-                PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_SCALE, mAnimatedScale,
-                        mAnimatedScale),
-                PropertyValuesHolder.ofFloat(
-                        ANIMATED_PROPERTY_ALPHA, mOriginalAlpha, mOriginalAlpha / 2));
+        final ValueAnimator animator;
+        final long duration;
+        if (mCallingTaskIdToHide != -1) {
+            animator = ValueAnimator.ofPropertyValuesHolder(
+                    PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_X, mCurrentX, mCurrentX),
+                    PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_Y, mCurrentY, mCurrentY),
+                    PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_SCALE, mAnimatedScale,
+                            mAnimatedScale),
+                    PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_ALPHA, mOriginalAlpha, 0f));
+            duration = MIN_ANIMATION_DURATION_MS;
+        } else {
+            animator = ValueAnimator.ofPropertyValuesHolder(
+                    PropertyValuesHolder.ofFloat(
+                            ANIMATED_PROPERTY_X, mCurrentX - mThumbOffsetX,
+                            mOriginalX - mThumbOffsetX),
+                    PropertyValuesHolder.ofFloat(
+                            ANIMATED_PROPERTY_Y, mCurrentY - mThumbOffsetY,
+                            mOriginalY - mThumbOffsetY),
+                    PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_SCALE, mAnimatedScale,
+                            mAnimatedScale),
+                    PropertyValuesHolder.ofFloat(
+                            ANIMATED_PROPERTY_ALPHA, mOriginalAlpha, mOriginalAlpha / 2));
 
-        final float translateX = mOriginalX - mCurrentX;
-        final float translateY = mOriginalY - mCurrentY;
-        // Adjust the duration to the travel distance.
-        final double travelDistance = Math.sqrt(translateX * translateX + translateY * translateY);
-        final double displayDiagonal =
-                Math.sqrt(mDisplaySize.x * mDisplaySize.x + mDisplaySize.y * mDisplaySize.y);
-        final long duration = MIN_ANIMATION_DURATION_MS + (long) (travelDistance / displayDiagonal
-                * (MAX_ANIMATION_DURATION_MS - MIN_ANIMATION_DURATION_MS));
+            final float translateX = mOriginalX - mCurrentX;
+            final float translateY = mOriginalY - mCurrentY;
+            // Adjust the duration to the travel distance.
+            final double travelDistance = Math.sqrt(
+                    translateX * translateX + translateY * translateY);
+            final double displayDiagonal =
+                    Math.sqrt(mDisplaySize.x * mDisplaySize.x + mDisplaySize.y * mDisplaySize.y);
+            duration = MIN_ANIMATION_DURATION_MS + (long) (travelDistance / displayDiagonal
+                    * (MAX_ANIMATION_DURATION_MS - MIN_ANIMATION_DURATION_MS));
+        }
+
         final AnimationListener listener = new AnimationListener();
         animator.setDuration(duration);
         animator.setInterpolator(mCubicEaseOutInterpolator);
@@ -742,13 +773,24 @@
     }
 
     private ValueAnimator createCancelAnimationLocked() {
-        final ValueAnimator animator = ValueAnimator.ofPropertyValuesHolder(
-                PropertyValuesHolder.ofFloat(
-                        ANIMATED_PROPERTY_X, mCurrentX - mThumbOffsetX, mCurrentX),
-                PropertyValuesHolder.ofFloat(
-                        ANIMATED_PROPERTY_Y, mCurrentY - mThumbOffsetY, mCurrentY),
-                PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_SCALE, mAnimatedScale, 0),
-                PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_ALPHA, mOriginalAlpha, 0));
+        final ValueAnimator animator;
+        if (mCallingTaskIdToHide != -1) {
+             animator = ValueAnimator.ofPropertyValuesHolder(
+                    PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_X, mCurrentX, mCurrentX),
+                    PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_Y, mCurrentY, mCurrentY),
+                    PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_SCALE, mAnimatedScale,
+                            mAnimatedScale),
+                    PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_ALPHA, mOriginalAlpha, 0f));
+        } else {
+            animator = ValueAnimator.ofPropertyValuesHolder(
+                    PropertyValuesHolder.ofFloat(
+                            ANIMATED_PROPERTY_X, mCurrentX - mThumbOffsetX, mCurrentX),
+                    PropertyValuesHolder.ofFloat(
+                            ANIMATED_PROPERTY_Y, mCurrentY - mThumbOffsetY, mCurrentY),
+                    PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_SCALE, mAnimatedScale, 0),
+                    PropertyValuesHolder.ofFloat(ANIMATED_PROPERTY_ALPHA, mOriginalAlpha, 0));
+        }
+
         final AnimationListener listener = new AnimationListener();
         animator.setDuration(MIN_ANIMATION_DURATION_MS);
         animator.setInterpolator(mCubicEaseOutInterpolator);
diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
index a21ba26..c66d659 100644
--- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java
+++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
@@ -35,7 +35,7 @@
 import android.view.InputChannel;
 import android.window.InputTransferToken;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.input.InputManagerService;
 
 /**
diff --git a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
index f40eb24..3123018 100644
--- a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
+++ b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
@@ -174,6 +174,9 @@
             // First: if this is not the current activity being started, make
             // sure it matches the current configuration.
             if (r != mStarting && mNotifyClients) {
+                if (!isTop) {
+                    r.mDisplayContent.applyFixedRotationForNonTopVisibleActivityIfNeeded(r);
+                }
                 r.ensureActivityConfiguration(true /* ignoreVisibility */);
             }
 
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 156e9f9..91c61b1 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -40,7 +40,7 @@
 import android.view.inputmethod.ImeTracker;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 import java.io.PrintWriter;
 
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 8035a29..74dbd15 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -66,7 +66,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.inputmethod.SoftInputShowHideReason;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.LocalServices;
 import com.android.server.inputmethod.InputMethodManagerInternal;
 
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index f68b67f6..33dea54 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -48,7 +48,7 @@
 import android.view.WindowInsets;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.function.TriFunction;
 import com.android.server.wm.SurfaceAnimator.AnimationType;
 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index a967f7a..3483842 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -41,7 +41,7 @@
 import android.view.WindowInsets;
 import android.view.WindowInsets.Type.InsetsType;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.inputmethod.InputMethodManagerInternal;
 
 import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index f70d2a5..872b4e1 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -16,7 +16,6 @@
 
 package com.android.server.wm;
 
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_APPEARING;
@@ -657,7 +656,6 @@
             final boolean lastKeyguardGoingAway = mKeyguardGoingAway;
 
             final ActivityRecord lastDismissKeyguardActivity = mDismissingKeyguardActivity;
-            final ActivityRecord lastTurnScreenOnActivity = mTopTurnScreenOnActivity;
 
             mRequestDismissKeyguard = false;
             mOccluded = false;
@@ -666,7 +664,6 @@
             mDismissingKeyguardActivity = null;
             mTopTurnScreenOnActivity = null;
 
-            boolean occludedByActivity = false;
             final Task task = getRootTaskForControllingOccluding(display);
             final ActivityRecord top = task != null ? task.getTopNonFinishingActivity() : null;
             if (top != null) {
@@ -712,7 +709,7 @@
 
             if (mTopTurnScreenOnActivity != null
                     && !mService.mWindowManager.mPowerManager.isInteractive()
-                    && (mRequestDismissKeyguard || occludedByActivity)) {
+                    && (mRequestDismissKeyguard || mOccluded)) {
                 controller.mTaskSupervisor.wakeUp("handleTurnScreenOn");
                 mTopTurnScreenOnActivity.setCurrentLaunchCanTurnScreenOn(false);
             }
diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java
index 362d4ef..2aa7c0c 100644
--- a/services/core/java/com/android/server/wm/Letterbox.java
+++ b/services/core/java/com/android/server/wm/Letterbox.java
@@ -20,6 +20,7 @@
 import static android.view.SurfaceControl.HIDDEN;
 import static android.window.TaskConstants.TASK_CHILD_LAYER_LETTERBOX_BACKGROUND;
 
+import android.annotation.NonNull;
 import android.graphics.Color;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -209,16 +210,18 @@
         return false;
     }
 
-    public void applySurfaceChanges(SurfaceControl.Transaction t) {
+    /** Applies surface changes such as colour, window crop, position and input info. */
+    public void applySurfaceChanges(@NonNull SurfaceControl.Transaction t,
+            @NonNull SurfaceControl.Transaction inputT) {
         if (useFullWindowSurface()) {
-            mFullWindowSurface.applySurfaceChanges(t);
+            mFullWindowSurface.applySurfaceChanges(t, inputT);
 
             for (LetterboxSurface surface : mSurfaces) {
                 surface.remove();
             }
         } else {
             for (LetterboxSurface surface : mSurfaces) {
-                surface.applySurfaceChanges(t);
+                surface.applySurfaceChanges(t, inputT);
             }
 
             mFullWindowSurface.remove();
@@ -418,7 +421,8 @@
             return Math.max(0, mLayoutFrameGlobal.height());
         }
 
-        public void applySurfaceChanges(SurfaceControl.Transaction t) {
+        public void applySurfaceChanges(@NonNull SurfaceControl.Transaction t,
+                @NonNull SurfaceControl.Transaction inputT) {
             if (!needsApplySurfaceChanges()) {
                 // Nothing changed.
                 return;
@@ -446,7 +450,7 @@
             }
             if (mSurface != null && mInputInterceptor != null) {
                 mInputInterceptor.updateTouchableRegion(mSurfaceFrameRelative);
-                t.setInputWindowInfo(mSurface, mInputInterceptor.mWindowHandle);
+                inputT.setInputWindowInfo(mSurface, mInputInterceptor.mWindowHandle);
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index 14a0467..a3550bc 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -16,35 +16,8 @@
 
 package com.android.server.wm;
 
-import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.content.pm.ActivityInfo.FORCE_NON_RESIZE_APP;
-import static android.content.pm.ActivityInfo.FORCE_RESIZE_APP;
-import static android.content.pm.ActivityInfo.OVERRIDE_ANY_ORIENTATION;
-import static android.content.pm.ActivityInfo.OVERRIDE_ANY_ORIENTATION_TO_USER;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
-import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS;
-import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
-import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION;
-import static android.content.pm.ActivityInfo.OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE;
-import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO;
-import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA;
-import static android.content.pm.ActivityInfo.OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA;
-import static android.content.pm.ActivityInfo.OVERRIDE_RESPECT_REQUESTED_ORIENTATION;
-import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR;
-import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT;
-import static android.content.pm.ActivityInfo.OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER;
-import static android.content.pm.ActivityInfo.isFixedOrientation;
 import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
-import static android.content.pm.ActivityInfo.screenOrientationToString;
 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_16_9;
 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2;
 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_4_3;
@@ -53,22 +26,9 @@
 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN;
 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_SPLIT_SCREEN;
 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_UNSET;
-import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
-import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION;
-import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH;
-import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE;
-import static android.view.WindowManager.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS;
-import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
 
 import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__BOTTOM;
 import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__CENTER;
@@ -104,8 +64,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager.TaskDescription;
-import android.app.CameraCompatTaskInfo.FreeformCameraCompatMode;
-import android.content.pm.ActivityInfo.ScreenOrientation;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -126,76 +84,25 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.statusbar.LetterboxDetails;
 import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType;
-import com.android.server.wm.utils.OptPropFactory;
-import com.android.server.wm.utils.OptPropFactory.OptProp;
 import com.android.window.flags.Flags;
 
 import java.io.PrintWriter;
-import java.util.function.BooleanSupplier;
 
 /** Controls behaviour of the letterbox UI for {@link mActivityRecord}. */
 // TODO(b/185262487): Improve test coverage of this class. Parts of it are tested in
 // SizeCompatTests and LetterboxTests but not all.
-// TODO(b/185264020): Consider making LetterboxUiController applicable to any level of the
-// hierarchy in addition to ActivityRecord (Task, DisplayArea, ...).
-// TODO(b/263021211): Consider renaming to more generic CompatUIController.
 final class LetterboxUiController {
 
     private static final String TAG = TAG_WITH_CLASS_NAME ? "LetterboxUiController" : TAG_ATM;
 
-    // Minimum value of mSetOrientationRequestCounter before qualifying as orientation request loop
-    @VisibleForTesting
-    static final int MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP = 2;
-    // Used to determine reset of mSetOrientationRequestCounter if next app requested
-    // orientation is after timeout value
-    @VisibleForTesting
-    static final int SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS = 1000;
-
     private final Point mTmpPoint = new Point();
 
     private final LetterboxConfiguration mLetterboxConfiguration;
 
     private final ActivityRecord mActivityRecord;
 
-    // TODO(b/265576778): Cache other overrides as well.
-
-    // Corresponds to OVERRIDE_ANY_ORIENTATION
-    private final boolean mIsOverrideAnyOrientationEnabled;
-    // Corresponds to OVERRIDE_ANY_ORIENTATION_TO_USER
-    private final boolean mIsSystemOverrideToFullscreenEnabled;
-    // Corresponds to OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT
-    private final boolean mIsOverrideToPortraitOrientationEnabled;
-    // Corresponds to OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR
-    private final boolean mIsOverrideToNosensorOrientationEnabled;
-    // Corresponds to OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE
-    private final boolean mIsOverrideToReverseLandscapeOrientationEnabled;
-    // Corresponds to OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA
-    private final boolean mIsOverrideOrientationOnlyForCameraEnabled;
-    // Corresponds to OVERRIDE_RESPECT_REQUESTED_ORIENTATION
-    private final boolean mIsOverrideRespectRequestedOrientationEnabled;
-
-    @NonNull
-    private final OptProp mAllowOrientationOverrideOptProp;
-    @NonNull
-    private final OptProp mAllowDisplayOrientationOverrideOptProp;
-    @NonNull
-    private final OptProp mAllowMinAspectRatioOverrideOptProp;
-    @NonNull
-    private final OptProp mAllowForceResizeOverrideOptProp;
-
-    @NonNull
-    private final OptProp mAllowUserAspectRatioOverrideOptProp;
-    @NonNull
-    private final OptProp mAllowUserAspectRatioFullscreenOverrideOptProp;
-
     private boolean mShowWallpaperForLetterboxBackground;
 
-    // Updated when ActivityRecord#setRequestedOrientation is called
-    private long mTimeMsLastSetOrientationRequest = 0;
-
-    // Counter for ActivityRecord#setRequestedOrientation
-    private int mSetOrientationRequestCounter = 0;
-
     // TODO(b/315140179): Make mUserAspectRatio final
     // The min aspect ratio override set by user
     @PackageManager.UserMinAspectRatio
@@ -204,114 +111,16 @@
     @Nullable
     private Letterbox mLetterbox;
 
-    @NonNull
-    private final OptProp mCameraCompatAllowForceRotationOptProp;
-
-    @NonNull
-    private final OptProp mCameraCompatAllowRefreshOptProp;
-
-    @NonNull
-    private final OptProp mCameraCompatEnableRefreshViaPauseOptProp;
-
-    // Whether activity "refresh" was requested but not finished in
-    // ActivityRecord#activityResumedLocked following the camera compat force rotation in
-    // DisplayRotationCompatPolicy.
-    private boolean mIsRefreshRequested;
-
-    @NonNull
-    private final OptProp mIgnoreRequestedOrientationOptProp;
-
-    @NonNull
-    private final OptProp mAllowIgnoringOrientationRequestWhenLoopDetectedOptProp;
-
-    @NonNull
-    private final OptProp mFakeFocusOptProp;
-
-    private boolean mIsRelaunchingAfterRequestedOrientationChanged;
-
     private boolean mLastShouldShowLetterboxUi;
 
     private boolean mDoubleTapEvent;
 
-    @FreeformCameraCompatMode
-    private int mFreeformCameraCompatMode = CAMERA_COMPAT_FREEFORM_NONE;
-
     LetterboxUiController(WindowManagerService wmService, ActivityRecord activityRecord) {
         mLetterboxConfiguration = wmService.mLetterboxConfiguration;
         // Given activityRecord may not be fully constructed since LetterboxUiController
         // is created in its constructor. It shouldn't be used in this constructor but it's safe
         // to use it after since controller is only used in ActivityRecord.
         mActivityRecord = activityRecord;
-
-        PackageManager packageManager = wmService.mContext.getPackageManager();
-
-        final OptPropFactory optPropBuilder = new OptPropFactory(packageManager,
-                activityRecord.packageName);
-
-        final BooleanSupplier isPolicyForIgnoringRequestedOrientationEnabled = asLazy(
-                mLetterboxConfiguration::isPolicyForIgnoringRequestedOrientationEnabled);
-        mIgnoreRequestedOrientationOptProp = optPropBuilder.create(
-                PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION,
-                isPolicyForIgnoringRequestedOrientationEnabled);
-        mAllowIgnoringOrientationRequestWhenLoopDetectedOptProp = optPropBuilder.create(
-                PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED,
-                isPolicyForIgnoringRequestedOrientationEnabled);
-
-        mFakeFocusOptProp = optPropBuilder.create(PROPERTY_COMPAT_ENABLE_FAKE_FOCUS,
-                mLetterboxConfiguration::isCompatFakeFocusEnabled);
-
-        final BooleanSupplier isCameraCompatTreatmentEnabled = asLazy(
-                mLetterboxConfiguration::isCameraCompatTreatmentEnabled);
-        mCameraCompatAllowForceRotationOptProp = optPropBuilder.create(
-                PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION,
-                isCameraCompatTreatmentEnabled);
-        mCameraCompatAllowRefreshOptProp = optPropBuilder.create(
-                PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH,
-                isCameraCompatTreatmentEnabled);
-        mCameraCompatEnableRefreshViaPauseOptProp = optPropBuilder.create(
-                PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE,
-                isCameraCompatTreatmentEnabled);
-
-        mAllowOrientationOverrideOptProp = optPropBuilder.create(
-                PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE);
-
-        mAllowDisplayOrientationOverrideOptProp = optPropBuilder.create(
-                PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE,
-                () -> mActivityRecord.mDisplayContent != null
-                        && mActivityRecord.getTask() != null
-                        && mActivityRecord.mDisplayContent.getIgnoreOrientationRequest()
-                        && !mActivityRecord.getTask().inMultiWindowMode()
-                        && mActivityRecord.mDisplayContent.getNaturalOrientation()
-                            == ORIENTATION_LANDSCAPE
-        );
-
-        mAllowMinAspectRatioOverrideOptProp = optPropBuilder.create(
-                PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE);
-
-        mAllowForceResizeOverrideOptProp = optPropBuilder.create(
-                PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES);
-
-        mAllowUserAspectRatioOverrideOptProp = optPropBuilder.create(
-                PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE,
-                mLetterboxConfiguration::isUserAppAspectRatioSettingsEnabled);
-
-        mAllowUserAspectRatioFullscreenOverrideOptProp = optPropBuilder.create(
-                PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE,
-                mLetterboxConfiguration::isUserAppAspectRatioFullscreenEnabled);
-
-        mIsOverrideAnyOrientationEnabled = isCompatChangeEnabled(OVERRIDE_ANY_ORIENTATION);
-        mIsSystemOverrideToFullscreenEnabled =
-                isCompatChangeEnabled(OVERRIDE_ANY_ORIENTATION_TO_USER);
-        mIsOverrideToPortraitOrientationEnabled =
-                isCompatChangeEnabled(OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT);
-        mIsOverrideToReverseLandscapeOrientationEnabled =
-                isCompatChangeEnabled(OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE);
-        mIsOverrideToNosensorOrientationEnabled =
-                isCompatChangeEnabled(OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR);
-        mIsOverrideOrientationOnlyForCameraEnabled =
-                isCompatChangeEnabled(OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA);
-        mIsOverrideRespectRequestedOrientationEnabled =
-                isCompatChangeEnabled(OVERRIDE_RESPECT_REQUESTED_ORIENTATION);
     }
 
     /** Cleans up {@link Letterbox} if it exists.*/
@@ -320,7 +129,6 @@
             mLetterbox.destroy();
             mLetterbox = null;
         }
-        mActivityRecord.mTransparentPolicy.stop();
     }
 
     void onMovedToDisplay(int displayId) {
@@ -330,105 +138,6 @@
     }
 
     /**
-     * Whether should ignore app requested orientation in response to an app
-     * calling {@link android.app.Activity#setRequestedOrientation}.
-     *
-     * <p>This is needed to avoid getting into {@link android.app.Activity#setRequestedOrientation}
-     * loop when {@link DisplayContent#getIgnoreOrientationRequest} is enabled or device has
-     * landscape natural orientation which app developers don't expect. For example, the loop can
-     * look like this:
-     * <ol>
-     *     <li>App sets default orientation to "unspecified" at runtime
-     *     <li>App requests to "portrait" after checking some condition (e.g. display rotation).
-     *     <li>(2) leads to fullscreen -> letterboxed bounds change and activity relaunch because
-     *     app can't handle the corresponding config changes.
-     *     <li>Loop goes back to (1)
-     * </ol>
-     *
-     * <p>This treatment is enabled when the following conditions are met:
-     * <ul>
-     *     <li>Flag gating the treatment is enabled
-     *     <li>Opt-out component property isn't enabled
-     *     <li>Opt-in component property or per-app override are enabled
-     *     <li>Activity is relaunched after {@link android.app.Activity#setRequestedOrientation}
-     *     call from an app or camera compat force rotation treatment is active for the activity.
-     *     <li>Orientation request loop detected and is not letterboxed for fixed orientation
-     * </ul>
-     */
-    boolean shouldIgnoreRequestedOrientation(@ScreenOrientation int requestedOrientation) {
-        if (mIgnoreRequestedOrientationOptProp.shouldEnableWithOverrideAndProperty(
-                isCompatChangeEnabled(OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION))) {
-            if (mIsRelaunchingAfterRequestedOrientationChanged) {
-                Slog.w(TAG, "Ignoring orientation update to "
-                        + screenOrientationToString(requestedOrientation)
-                        + " due to relaunching after setRequestedOrientation for "
-                        + mActivityRecord);
-                return true;
-            }
-            if (isCameraCompatTreatmentActive()) {
-                Slog.w(TAG, "Ignoring orientation update to "
-                        + screenOrientationToString(requestedOrientation)
-                        + " due to camera compat treatment for " + mActivityRecord);
-                return true;
-            }
-        }
-
-        if (shouldIgnoreOrientationRequestLoop()) {
-            Slog.w(TAG, "Ignoring orientation update to "
-                    + screenOrientationToString(requestedOrientation)
-                    + " as orientation request loop was detected for "
-                    + mActivityRecord);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Whether an app is calling {@link android.app.Activity#setRequestedOrientation}
-     * in a loop and orientation request should be ignored.
-     *
-     * <p>This should only be called once in response to
-     * {@link android.app.Activity#setRequestedOrientation}. See
-     * {@link #shouldIgnoreRequestedOrientation} for more details.
-     *
-     * <p>This treatment is enabled when the following conditions are met:
-     * <ul>
-     *     <li>Flag gating the treatment is enabled
-     *     <li>Opt-out component property isn't enabled
-     *     <li>Per-app override is enabled
-     *     <li>App has requested orientation more than 2 times within 1-second
-     *     timer and activity is not letterboxed for fixed orientation
-     * </ul>
-     */
-    boolean shouldIgnoreOrientationRequestLoop() {
-        final boolean loopDetectionEnabled = isCompatChangeEnabled(
-                OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED);
-        if (!mAllowIgnoringOrientationRequestWhenLoopDetectedOptProp
-                .shouldEnableWithOptInOverrideAndOptOutProperty(loopDetectionEnabled)) {
-            return false;
-        }
-
-        final long currTimeMs = System.currentTimeMillis();
-        if (currTimeMs - mTimeMsLastSetOrientationRequest
-                < SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS) {
-            mSetOrientationRequestCounter += 1;
-        } else {
-            // Resets app setOrientationRequest counter if timed out
-            mSetOrientationRequestCounter = 0;
-        }
-        // Update time last called
-        mTimeMsLastSetOrientationRequest = currTimeMs;
-
-        return mSetOrientationRequestCounter >= MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP
-                && !mActivityRecord.isLetterboxedForFixedOrientationAndAspectRatio();
-    }
-
-    @VisibleForTesting
-    int getSetOrientationRequestCounter() {
-        return mSetOrientationRequestCounter;
-    }
-
-    /**
      * Whether sending compat fake focus for split screen resumed activities is enabled. Needed
      * because some game engines wait to get focus before drawing the content of the app which isn't
      * guaranteed by default in multi-window modes.
@@ -441,8 +150,7 @@
      * </ul>
      */
     boolean shouldSendFakeFocus() {
-        return mFakeFocusOptProp.shouldEnableWithOverrideAndProperty(
-                isCompatChangeEnabled(OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS));
+        return getAppCompatOverrides().shouldSendFakeFocus();
     }
 
     /**
@@ -458,28 +166,7 @@
      * </ul>
      */
     boolean shouldOverrideMinAspectRatio() {
-        return mAllowMinAspectRatioOverrideOptProp.shouldEnableWithOptInOverrideAndOptOutProperty(
-                isCompatChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO));
-    }
-
-    /**
-     * Whether we should apply the min aspect ratio per-app override only when an app is connected
-     * to the camera.
-     * When this override is applied the min aspect ratio given in the app's manifest will be
-     * overridden to the largest enabled aspect ratio treatment unless the app's manifest value
-     * is higher. The treatment will also apply if no value is provided in the manifest.
-     *
-     * <p>This method returns {@code true} when the following conditions are met:
-     * <ul>
-     *     <li>Opt-out component property isn't enabled
-     *     <li>Per-app override is enabled
-     * </ul>
-     */
-    boolean shouldOverrideMinAspectRatioForCamera() {
-        return mActivityRecord.isCameraActive()
-                && mAllowMinAspectRatioOverrideOptProp
-                .shouldEnableWithOptInOverrideAndOptOutProperty(
-                        isCompatChangeEnabled(OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA));
+        return getAppCompatOverrides().shouldOverrideMinAspectRatio();
     }
 
     /**
@@ -495,8 +182,7 @@
      * </ul>
      */
     boolean shouldOverrideForceResizeApp() {
-        return mAllowForceResizeOverrideOptProp.shouldEnableWithOptInOverrideAndOptOutProperty(
-                isCompatChangeEnabled(FORCE_RESIZE_APP));
+        return getAppCompatOverrides().shouldOverrideForceResizeApp();
     }
 
     /**
@@ -510,8 +196,7 @@
      * </ul>
      */
     boolean shouldOverrideForceNonResizeApp() {
-        return mAllowForceResizeOverrideOptProp.shouldEnableWithOptInOverrideAndOptOutProperty(
-                isCompatChangeEnabled(FORCE_NON_RESIZE_APP));
+        return getAppCompatOverrides().shouldOverrideForceNonResizeApp();
     }
 
     /**
@@ -519,22 +204,13 @@
      * android.app.Activity#setRequestedOrientation}.
      */
     void setRelaunchingAfterRequestedOrientationChanged(boolean isRelaunching) {
-        mIsRelaunchingAfterRequestedOrientationChanged = isRelaunching;
+        getAppCompatOverrides().getAppCompatOrientationOverrides()
+                .setRelaunchingAfterRequestedOrientationChanged(isRelaunching);
     }
 
-    /**
-     * Whether activity "refresh" was requested but not finished in {@link #activityResumedLocked}.
-     */
-    boolean isRefreshRequested() {
-        return mIsRefreshRequested;
-    }
-
-    void setIsRefreshRequested(boolean isRequested) {
-        mIsRefreshRequested = isRequested;
-    }
 
     boolean isOverrideRespectRequestedOrientationEnabled() {
-        return mIsOverrideRespectRequestedOrientationEnabled;
+        return getAppCompatOverrides().isOverrideRespectRequestedOrientationEnabled();
     }
 
     /**
@@ -551,190 +227,7 @@
      * </ul>
      */
     boolean shouldUseDisplayLandscapeNaturalOrientation() {
-        return mAllowDisplayOrientationOverrideOptProp
-                .shouldEnableWithOptInOverrideAndOptOutProperty(
-                        isCompatChangeEnabled(OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION));
-    }
-
-    @ScreenOrientation
-    int overrideOrientationIfNeeded(@ScreenOrientation int candidate) {
-        final DisplayContent displayContent = mActivityRecord.mDisplayContent;
-        final boolean isIgnoreOrientationRequestEnabled = displayContent != null
-                && displayContent.getIgnoreOrientationRequest();
-        if (shouldApplyUserFullscreenOverride() && isIgnoreOrientationRequestEnabled
-                // Do not override orientation to fullscreen for camera activities.
-                // Fixed-orientation activities are rarely tested in other orientations, and it
-                // often results in sideways or stretched previews. As the camera compat treatment
-                // targets fixed-orientation activities, overriding the orientation disables the
-                // treatment.
-                && !mActivityRecord.isCameraActive()) {
-            Slog.v(TAG, "Requested orientation " + screenOrientationToString(candidate) + " for "
-                    + mActivityRecord + " is overridden to "
-                    + screenOrientationToString(SCREEN_ORIENTATION_USER)
-                    + " by user aspect ratio settings.");
-            return SCREEN_ORIENTATION_USER;
-        }
-
-        // In some cases (e.g. Kids app) we need to map the candidate orientation to some other
-        // orientation.
-        candidate = mActivityRecord.mWmService.mapOrientationRequest(candidate);
-
-        if (shouldApplyUserMinAspectRatioOverride() && (!isFixedOrientation(candidate)
-                || candidate == SCREEN_ORIENTATION_LOCKED)) {
-            Slog.v(TAG, "Requested orientation " + screenOrientationToString(candidate) + " for "
-                    + mActivityRecord + " is overridden to "
-                    + screenOrientationToString(SCREEN_ORIENTATION_PORTRAIT)
-                    + " by user aspect ratio settings.");
-            return SCREEN_ORIENTATION_PORTRAIT;
-        }
-
-        if (mAllowOrientationOverrideOptProp.isFalse()) {
-            return candidate;
-        }
-
-        if (mIsOverrideOrientationOnlyForCameraEnabled && displayContent != null
-                && (displayContent.mDisplayRotationCompatPolicy == null
-                        || !displayContent.mDisplayRotationCompatPolicy
-                                .isActivityEligibleForOrientationOverride(mActivityRecord))) {
-            return candidate;
-        }
-
-        // mUserAspectRatio is always initialized first in shouldApplyUserFullscreenOverride(),
-        // which will always come first before this check as user override > device
-        // manufacturer override.
-        if (isSystemOverrideToFullscreenEnabled() && isIgnoreOrientationRequestEnabled
-                // Do not override orientation to fullscreen for camera activities.
-                // Fixed-orientation activities are rarely tested in other orientations, and it
-                // often results in sideways or stretched previews. As the camera compat treatment
-                // targets fixed-orientation activities, overriding the orientation disables the
-                // treatment.
-                && !mActivityRecord.isCameraActive()) {
-            Slog.v(TAG, "Requested orientation  " + screenOrientationToString(candidate) + " for "
-                    + mActivityRecord + " is overridden to "
-                    + screenOrientationToString(SCREEN_ORIENTATION_USER));
-            return SCREEN_ORIENTATION_USER;
-        }
-
-        if (mIsOverrideToReverseLandscapeOrientationEnabled
-                && (isFixedOrientationLandscape(candidate) || mIsOverrideAnyOrientationEnabled)) {
-            Slog.w(TAG, "Requested orientation  " + screenOrientationToString(candidate) + " for "
-                    + mActivityRecord + " is overridden to "
-                    + screenOrientationToString(SCREEN_ORIENTATION_REVERSE_LANDSCAPE));
-            return SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
-        }
-
-        if (!mIsOverrideAnyOrientationEnabled && isFixedOrientation(candidate)) {
-            return candidate;
-        }
-
-        if (mIsOverrideToPortraitOrientationEnabled) {
-            Slog.w(TAG, "Requested orientation  " + screenOrientationToString(candidate) + " for "
-                    + mActivityRecord + " is overridden to "
-                    + screenOrientationToString(SCREEN_ORIENTATION_PORTRAIT));
-            return SCREEN_ORIENTATION_PORTRAIT;
-        }
-
-        if (mIsOverrideToNosensorOrientationEnabled) {
-            Slog.w(TAG, "Requested orientation  " + screenOrientationToString(candidate) + " for "
-                    + mActivityRecord + " is overridden to "
-                    + screenOrientationToString(SCREEN_ORIENTATION_NOSENSOR));
-            return SCREEN_ORIENTATION_NOSENSOR;
-        }
-
-        return candidate;
-    }
-
-    boolean isOverrideOrientationOnlyForCameraEnabled() {
-        return mIsOverrideOrientationOnlyForCameraEnabled;
-    }
-
-    /**
-     * Whether activity is eligible for activity "refresh" after camera compat force rotation
-     * treatment. See {@link DisplayRotationCompatPolicy} for context.
-     *
-     * <p>This treatment is enabled when the following conditions are met:
-     * <ul>
-     *     <li>Flag gating the camera compat treatment is enabled.
-     *     <li>Activity isn't opted out by the device manufacturer with override or by the app
-     *     developers with the component property.
-     * </ul>
-     */
-    boolean shouldRefreshActivityForCameraCompat() {
-        return mCameraCompatAllowRefreshOptProp.shouldEnableWithOptOutOverrideAndProperty(
-                isCompatChangeEnabled(OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH));
-    }
-
-    /**
-     * Whether activity should be "refreshed" after the camera compat force rotation treatment
-     * using the "resumed -> paused -> resumed" cycle rather than the "resumed -> ... -> stopped
-     * -> ... -> resumed" cycle. See {@link DisplayRotationCompatPolicy} for context.
-     *
-     * <p>This treatment is enabled when the following conditions are met:
-     * <ul>
-     *     <li>Flag gating the camera compat treatment is enabled.
-     *     <li>Activity "refresh" via "resumed -> paused -> resumed" cycle isn't disabled with the
-     *     component property by the app developers.
-     *     <li>Activity "refresh" via "resumed -> paused -> resumed" cycle is enabled by the device
-     *     manufacturer with override / by the app developers with the component property.
-     * </ul>
-     */
-    boolean shouldRefreshActivityViaPauseForCameraCompat() {
-        return mCameraCompatEnableRefreshViaPauseOptProp.shouldEnableWithOverrideAndProperty(
-                isCompatChangeEnabled(OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE));
-    }
-
-    /**
-     * Whether activity is eligible for camera compat force rotation treatment. See {@link
-     * DisplayRotationCompatPolicy} for context.
-     *
-     * <p>This treatment is enabled when the following conditions are met:
-     * <ul>
-     *     <li>Flag gating the camera compat treatment is enabled.
-     *     <li>Activity isn't opted out by the device manufacturer with override or by the app
-     *     developers with the component property.
-     * </ul>
-     */
-    boolean shouldForceRotateForCameraCompat() {
-        return mCameraCompatAllowForceRotationOptProp.shouldEnableWithOptOutOverrideAndProperty(
-                isCompatChangeEnabled(OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION));
-    }
-
-    /**
-     * Whether activity is eligible for camera compatibility free-form treatment.
-     *
-     * <p>The treatment is applied to a fixed-orientation camera activity in free-form windowing
-     * mode. The treatment letterboxes or pillarboxes the activity to the expected orientation and
-     * provides changes to the camera and display orientation signals to match those expected on a
-     * portrait device in that orientation (for example, on a standard phone).
-     *
-     * <p>The treatment is enabled when the following conditions are met:
-     * <ul>
-     * <li>Property gating the camera compatibility free-form treatment is enabled.
-     * <li>Activity isn't opted out by the device manufacturer with override.
-     * </ul>
-     */
-    boolean shouldApplyFreeformTreatmentForCameraCompat() {
-        return Flags.cameraCompatForFreeform() && !isCompatChangeEnabled(
-                        OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT);
-    }
-
-    private boolean isCameraCompatTreatmentActive() {
-        DisplayContent displayContent = mActivityRecord.mDisplayContent;
-        if (displayContent == null) {
-            return false;
-        }
-        return displayContent.mDisplayRotationCompatPolicy != null
-                && displayContent.mDisplayRotationCompatPolicy
-                        .isTreatmentEnabledForActivity(mActivityRecord);
-    }
-
-    @FreeformCameraCompatMode
-    int getFreeformCameraCompatMode() {
-        return mFreeformCameraCompatMode;
-    }
-
-    void setFreeformCameraCompatMode(@FreeformCameraCompatMode int freeformCameraCompatMode) {
-        mFreeformCameraCompatMode = freeformCameraCompatMode;
+        return getAppCompatOverrides().shouldUseDisplayLandscapeNaturalOrientation();
     }
 
     private boolean isCompatChangeEnabled(long overrideChangeId) {
@@ -785,16 +278,18 @@
     }
 
     void updateLetterboxSurfaceIfNeeded(WindowState winHint) {
-        updateLetterboxSurfaceIfNeeded(winHint, mActivityRecord.getSyncTransaction());
+        updateLetterboxSurfaceIfNeeded(winHint, mActivityRecord.getSyncTransaction(),
+                mActivityRecord.getPendingTransaction());
     }
 
-    void updateLetterboxSurfaceIfNeeded(WindowState winHint, Transaction t) {
+    void updateLetterboxSurfaceIfNeeded(WindowState winHint, @NonNull Transaction t,
+            @NonNull Transaction inputT) {
         if (shouldNotLayoutLetterbox(winHint)) {
             return;
         }
         layoutLetterboxIfNeeded(winHint);
         if (mLetterbox != null && mLetterbox.needsApplySurfaceChanges()) {
-            mLetterbox.applySurfaceChanges(t);
+            mLetterbox.applySurfaceChanges(t, inputT);
         }
     }
 
@@ -850,7 +345,8 @@
             // For this reason we use ActivityRecord#getBounds() that the translucent activity
             // inherits from the first opaque activity beneath and also takes care of the scaling
             // in case of activities in size compat mode.
-            final Rect innerFrame = mActivityRecord.mTransparentPolicy.isRunning()
+            final Rect innerFrame = mActivityRecord.mAppCompatController
+                    .getTransparentPolicy().isRunning()
                     ? mActivityRecord.getBounds() : w.getFrame();
             mLetterbox.layout(spaceToFill, innerFrame, mTmpPoint);
             if (mDoubleTapEvent) {
@@ -955,27 +451,10 @@
                         : getDefaultMinAspectRatio();
     }
 
-    void recomputeConfigurationForCameraCompatIfNeeded() {
-        if (isOverrideOrientationOnlyForCameraEnabled()
-                || isCameraCompatSplitScreenAspectRatioAllowed()
-                || shouldOverrideMinAspectRatioForCamera()) {
-            mActivityRecord.recomputeConfiguration();
-        }
-    }
-
     boolean isLetterboxEducationEnabled() {
         return mLetterboxConfiguration.getIsEducationEnabled();
     }
 
-    /**
-     * Whether we use split screen aspect ratio for the activity when camera compat treatment
-     * is active because the corresponding config is enabled and activity supports resizing.
-     */
-    boolean isCameraCompatSplitScreenAspectRatioAllowed() {
-        return mLetterboxConfiguration.isCameraCompatSplitScreenAspectRatioEnabled()
-                && !mActivityRecord.shouldCreateCompatDisplayInsets();
-    }
-
     private boolean shouldUseSplitScreenAspectRatio(@NonNull Configuration parentConfiguration) {
         final boolean isBookMode = isDisplayFullScreenAndInPosture(/* isTabletop */ false);
         final boolean isNotCenteredHorizontally = getHorizontalPositionMultiplier(
@@ -983,11 +462,16 @@
         final boolean isTabletopMode = isDisplayFullScreenAndInPosture(/* isTabletop */ true);
         final boolean isLandscape = isFixedOrientationLandscape(
                 mActivityRecord.getOverrideOrientation());
-
+        final AppCompatCameraOverrides appCompatCameraOverrides =
+                mActivityRecord.mAppCompatController.getAppCompatCameraOverrides();
+        final AppCompatCameraPolicy cameraPolicy =
+                mActivityRecord.mAppCompatController.getAppCompatCameraPolicy();
+        final boolean isCameraCompatTreatmentActive = cameraPolicy != null
+                && cameraPolicy.isTreatmentEnabledForActivity(mActivityRecord);
         // Don't resize to split screen size when in book mode if letterbox position is centered
         return (isBookMode && isNotCenteredHorizontally || isTabletopMode && isLandscape)
-                    || isCameraCompatSplitScreenAspectRatioAllowed()
-                        && isCameraCompatTreatmentActive();
+                    || (appCompatCameraOverrides.isCameraCompatSplitScreenAspectRatioAllowed()
+                    && isCameraCompatTreatmentActive);
     }
 
     private float getDefaultMinAspectRatioForUnresizableApps() {
@@ -1089,13 +573,7 @@
      * Whether we should enable users to resize the current app.
      */
     boolean shouldEnableUserAspectRatioSettings() {
-        // We use mBooleanPropertyAllowUserAspectRatioOverride to allow apps to opt-out which has
-        // effect only if explicitly false. If mBooleanPropertyAllowUserAspectRatioOverride is null,
-        // the current app doesn't opt-out so the first part of the predicate is true.
-        return !mAllowUserAspectRatioOverrideOptProp.isFalse()
-                && mLetterboxConfiguration.isUserAppAspectRatioSettingsEnabled()
-                && mActivityRecord.mDisplayContent != null
-                && mActivityRecord.mDisplayContent.getIgnoreOrientationRequest();
+        return getAppCompatOverrides().shouldEnableUserAspectRatioSettings();
     }
 
     /**
@@ -1114,15 +592,6 @@
                 && mUserAspectRatio != USER_MIN_ASPECT_RATIO_FULLSCREEN;
     }
 
-    boolean isUserFullscreenOverrideEnabled() {
-        if (mAllowUserAspectRatioOverrideOptProp.isFalse()
-                || mAllowUserAspectRatioFullscreenOverrideOptProp.isFalse()
-                || !mLetterboxConfiguration.isUserAppAspectRatioFullscreenEnabled()) {
-            return false;
-        }
-        return true;
-    }
-
     boolean shouldApplyUserFullscreenOverride() {
         if (isUserFullscreenOverrideEnabled()) {
             mUserAspectRatio = getUserMinAspectRatioOverrideCode();
@@ -1133,11 +602,12 @@
         return false;
     }
 
+    boolean isUserFullscreenOverrideEnabled() {
+        return getAppCompatOverrides().isUserFullscreenOverrideEnabled();
+    }
+
     boolean isSystemOverrideToFullscreenEnabled() {
-        return mIsSystemOverrideToFullscreenEnabled
-                && !mAllowOrientationOverrideOptProp.isFalse()
-                && (mUserAspectRatio == USER_MIN_ASPECT_RATIO_UNSET
-                    || mUserAspectRatio == USER_MIN_ASPECT_RATIO_FULLSCREEN);
+        return getAppCompatOverrides().isSystemOverrideToFullscreenEnabled(mUserAspectRatio);
     }
 
     boolean hasFullscreenOverride() {
@@ -1311,8 +781,9 @@
                 ? parentAppBoundsOverride : parentConfiguration.windowConfiguration.getAppBounds();
         // Use screen resolved bounds which uses resolved bounds or size compat bounds
         // as activity bounds can sometimes be empty
-        final Rect opaqueActivityBounds = mActivityRecord.mTransparentPolicy
-                .getFirstOpaqueActivity().map(ActivityRecord::getScreenResolvedBounds)
+        final Rect opaqueActivityBounds = mActivityRecord.mAppCompatController
+                .getTransparentPolicy().getFirstOpaqueActivity()
+                .map(ActivityRecord::getScreenResolvedBounds)
                 .orElse(mActivityRecord.getScreenResolvedBounds());
         return mLetterboxConfiguration.getIsHorizontalReachabilityEnabled()
                 && parentConfiguration.windowConfiguration.getWindowingMode()
@@ -1331,6 +802,11 @@
         return isHorizontalReachabilityEnabled() || isVerticalReachabilityEnabled();
     }
 
+    // TODO(b/346264992): Remove after AppCompatController refactoring
+    private AppCompatOverrides getAppCompatOverrides() {
+        return mActivityRecord.mAppCompatController.getAppCompatOverrides();
+    }
+
     /**
      * Whether vertical reachability is enabled for an activity in the current configuration.
      *
@@ -1350,8 +826,9 @@
                 ? parentAppBoundsOverride : parentConfiguration.windowConfiguration.getAppBounds();
         // Use screen resolved bounds which uses resolved bounds or size compat bounds
         // as activity bounds can sometimes be empty.
-        final Rect opaqueActivityBounds = mActivityRecord.mTransparentPolicy
-                .getFirstOpaqueActivity().map(ActivityRecord::getScreenResolvedBounds)
+        final Rect opaqueActivityBounds = mActivityRecord.mAppCompatController
+                .getTransparentPolicy().getFirstOpaqueActivity()
+                .map(ActivityRecord::getScreenResolvedBounds)
                 .orElse(mActivityRecord.getScreenResolvedBounds());
         return mLetterboxConfiguration.getIsVerticalReachabilityEnabled()
                 && parentConfiguration.windowConfiguration.getWindowingMode()
@@ -1368,7 +845,8 @@
 
     @VisibleForTesting
     boolean shouldShowLetterboxUi(WindowState mainWindow) {
-        if (mIsRelaunchingAfterRequestedOrientationChanged) {
+        if (getAppCompatOverrides().getAppCompatOrientationOverrides()
+                .getIsRelaunchingAfterRequestedOrientationChanged()) {
             return mLastShouldShowLetterboxUi;
         }
 
@@ -1457,7 +935,7 @@
         // corners because we assume the specific layout would. This is the case when the layout
         // of the translucent activity uses only a part of all the bounds because of the use of
         // LayoutParams.WRAP_CONTENT.
-        if (mActivityRecord.mTransparentPolicy.isRunning()
+        if (mActivityRecord.mAppCompatController.getTransparentPolicy().isRunning()
                 && (cropBounds.width() != mainWindow.mRequestedWidth
                 || cropBounds.height() != mainWindow.mRequestedHeight)) {
             return null;
@@ -1528,7 +1006,8 @@
     }
 
     boolean getIsRelaunchingAfterRequestedOrientationChanged() {
-        return mIsRelaunchingAfterRequestedOrientationChanged;
+        return getAppCompatOverrides().getAppCompatOrientationOverrides()
+                .getIsRelaunchingAfterRequestedOrientationChanged();
     }
 
     private void adjustBoundsForTaskbar(final WindowState mainWindow, final Rect bounds) {
@@ -1713,13 +1192,13 @@
     int getLetterboxPositionForLogging() {
         int positionToLog = APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__UNKNOWN_POSITION;
         if (isHorizontalReachabilityEnabled()) {
-            int letterboxPositionForHorizontalReachability = getLetterboxConfiguration()
+            int letterboxPositionForHorizontalReachability = mLetterboxConfiguration
                     .getLetterboxPositionForHorizontalReachability(
                             isDisplayFullScreenAndInPosture(/* isTabletop */ false));
             positionToLog = letterboxHorizontalReachabilityPositionToLetterboxPosition(
                     letterboxPositionForHorizontalReachability);
         } else if (isVerticalReachabilityEnabled()) {
-            int letterboxPositionForVerticalReachability = getLetterboxConfiguration()
+            int letterboxPositionForVerticalReachability = mLetterboxConfiguration
                     .getLetterboxPositionForVerticalReachability(
                             isDisplayFullScreenAndInPosture(/* isTabletop */ true));
             positionToLog = letterboxVerticalReachabilityPositionToLetterboxPosition(
@@ -1728,10 +1207,6 @@
         return positionToLog;
     }
 
-    private LetterboxConfiguration getLetterboxConfiguration() {
-        return mLetterboxConfiguration;
-    }
-
     /**
      * Logs letterbox position changes via {@link ActivityMetricsLogger#logLetterboxPositionChange}.
      */
@@ -1761,21 +1236,4 @@
                 w.mAttrs.insetsFlags.appearance
         );
     }
-
-    @NonNull
-    private static BooleanSupplier asLazy(@NonNull BooleanSupplier supplier) {
-        return new BooleanSupplier() {
-            private boolean mRead;
-            private boolean mValue;
-
-            @Override
-            public boolean getAsBoolean() {
-                if (!mRead) {
-                    mRead = true;
-                    mValue = supplier.getAsBoolean();
-                }
-                return mValue;
-            }
-        };
-    }
 }
diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index 0f9998c..0dadade 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -63,7 +63,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.policy.IKeyguardDismissCallback;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.telephony.CellBroadcastUtils;
 import com.android.internal.widget.LockPatternUtils;
diff --git a/services/core/java/com/android/server/wm/NonAppWindowAnimationAdapter.java b/services/core/java/com/android/server/wm/NonAppWindowAnimationAdapter.java
index 36c092b..1a895ea 100644
--- a/services/core/java/com/android/server/wm/NonAppWindowAnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/NonAppWindowAnimationAdapter.java
@@ -35,7 +35,7 @@
 import android.view.SurfaceControl;
 import android.view.WindowManager;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.policy.WindowManagerPolicy;
 
 import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
index 4c797f8..3cf301c 100644
--- a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
+++ b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java
@@ -36,7 +36,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.protolog.ProtoLogGroup;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.wm.DeviceStateController.DeviceState;
 
 public class PhysicalDisplaySwitchTransitionLauncher {
diff --git a/services/core/java/com/android/server/wm/PinnedTaskController.java b/services/core/java/com/android/server/wm/PinnedTaskController.java
index 4378b4f..755d4c8 100644
--- a/services/core/java/com/android/server/wm/PinnedTaskController.java
+++ b/services/core/java/com/android/server/wm/PinnedTaskController.java
@@ -22,7 +22,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 import android.app.PictureInPictureParams;
-import android.content.ComponentName;
 import android.content.res.Resources;
 import android.graphics.Insets;
 import android.graphics.Matrix;
@@ -326,19 +325,6 @@
     }
 
     /**
-     * Activity is hidden (either stopped or removed), resets the last saved snap fraction
-     * so that the default bounds will be returned for the next session.
-     */
-    void onActivityHidden(ComponentName componentName) {
-        if (mPinnedTaskListener == null) return;
-        try {
-            mPinnedTaskListener.onActivityHidden(componentName);
-        } catch (RemoteException e) {
-            Slog.e(TAG_WM, "Error delivering reset reentry fraction event.", e);
-        }
-    }
-
-    /**
      * Sets the Ime state and height.
      */
     void setAdjustedForIme(boolean adjustedForIme, int imeHeight) {
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index e07b72a..7aede8b 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -61,7 +61,6 @@
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
-import android.graphics.Insets;
 import android.graphics.Rect;
 import android.os.Environment;
 import android.os.IBinder;
@@ -76,11 +75,10 @@
 import android.util.SparseBooleanArray;
 import android.view.InsetsState;
 import android.view.MotionEvent;
-import android.view.WindowInsets;
 import android.view.WindowManagerPolicyConstants.PointerEventListener;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.am.ActivityManagerService;
 
@@ -1536,6 +1534,11 @@
             return true;
         }
 
+        // The task is marked as non-trimmable. Don't trim the task.
+        if (!task.mIsTrimmableFromRecents) {
+            return false;
+        }
+
         // Ignore tasks from different displays
         // TODO (b/115289124): No Recents on non-default displays.
         if (!task.isOnHomeDisplay()) {
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index 469cc64..c592caf 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -42,7 +42,7 @@
 import android.util.Slog;
 import android.view.IRecentsAnimationRunner;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.internal.util.function.pooled.PooledPredicate;
 import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 312c4be..6f94713 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -64,7 +64,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.IResultReceiver;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.LocalServices;
 import com.android.server.inputmethod.InputMethodManagerInternal;
 import com.android.server.statusbar.StatusBarManagerInternal;
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index 63bbb31..a8edaeb 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -45,7 +45,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.protolog.common.LogLevel;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.FastPrintWriter;
 import com.android.server.wm.SurfaceAnimator.AnimationType;
 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
diff --git a/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java b/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java
index 4d3b95b..e4962bf 100644
--- a/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java
+++ b/services/core/java/com/android/server/wm/RemoteDisplayChangeController.java
@@ -28,7 +28,7 @@
 import android.window.WindowContainerTransaction;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -104,10 +104,9 @@
 
         final IDisplayChangeWindowCallback remoteCallback = createCallback(callback);
         try {
-            mService.mH.removeCallbacks(mTimeoutRunnable);
-            mService.mH.postDelayed(mTimeoutRunnable, REMOTE_DISPLAY_CHANGE_TIMEOUT_MS);
             mService.mDisplayChangeController.onDisplayChange(mDisplayContent.mDisplayId,
                     fromRotation, toRotation, newDisplayAreaInfo, remoteCallback);
+            mService.mH.postDelayed(mTimeoutRunnable, callback, REMOTE_DISPLAY_CHANGE_TIMEOUT_MS);
             return true;
         } catch (RemoteException e) {
             Slog.e(TAG, "Exception while dispatching remote display-change", e);
@@ -118,6 +117,7 @@
 
     private void onContinueTimedOut() {
         Slog.e(TAG, "RemoteDisplayChange timed-out, UI might get messed-up after this.");
+        mService.mH.removeCallbacks(mTimeoutRunnable);
         // timed-out, so run all continue callbacks and clear the list
         synchronized (mService.mGlobalLock) {
             for (int i = 0; i < mCallbacks.size(); ++i) {
@@ -172,9 +172,6 @@
             // The "toIndex" is exclusive, so it needs +1 to clear the current calling callback.
             mCallbacks.subList(0, idx + 1).clear();
             final boolean completed = mCallbacks.isEmpty();
-            if (completed) {
-                mService.mH.removeCallbacks(mTimeoutRunnable);
-            }
             callback.onContinueRemoteDisplayChange(transaction);
             if (completed) {
                 onCompleted();
@@ -198,6 +195,7 @@
                             }
                             mService.mH.post(() -> RemoteDisplayChangeController.this
                                     .continueDisplayChange(callback, t));
+                            mService.mH.removeCallbacks(mTimeoutRunnable, callback);
                         }
                     }
                 };
diff --git a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
index d497d8c..243dbc7 100644
--- a/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
+++ b/services/core/java/com/android/server/wm/ResetTargetTaskHelper.java
@@ -24,7 +24,7 @@
 import android.content.pm.ActivityInfo;
 import android.os.Debug;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 import java.util.ArrayList;
 import java.util.function.Consumer;
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index f5ab38f..99697de 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -141,7 +141,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.ResolverActivity;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.internal.util.function.pooled.PooledPredicate;
 import com.android.server.LocalServices;
@@ -152,7 +152,6 @@
 import com.android.server.policy.PermissionPolicyInternal;
 import com.android.server.policy.WindowManagerPolicy;
 import com.android.server.utils.Slogf;
-import com.android.window.flags.Flags;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -789,13 +788,12 @@
             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
 
-        if (Flags.bundleClientTransactionFlag()) {
-            // mWmService.mResizingWindows is populated in #applySurfaceChangesTransaction()
-            handleResizingWindows();
+        // mWmService.mResizingWindows is populated in #applySurfaceChangesTransaction()
+        handleResizingWindows();
+        clearFrameChangingWindows();
 
-            // Called after #handleResizingWindows to include WindowStateResizeItem if any.
-            mWmService.mAtmService.getLifecycleManager().dispatchPendingTransactions();
-        }
+        // Called after #handleResizingWindows to include WindowStateResizeItem if any.
+        mWmService.mAtmService.getLifecycleManager().dispatchPendingTransactions();
 
         // Send any pending task-info changes that were queued-up during a layout deferment
         mWmService.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
@@ -839,11 +837,6 @@
             }
         }
 
-        if (!Flags.bundleClientTransactionFlag()) {
-            handleResizingWindows();
-        }
-        clearFrameChangingWindows();
-
         if (mWmService.mDisplayFrozen) {
             ProtoLog.v(WM_DEBUG_ORIENTATION,
                     "With display frozen, orientationChangeComplete=%b",
@@ -1905,6 +1898,7 @@
             // Don't do recursive work.
             return;
         }
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "RWC_ensureActivitiesVisible");
         mTaskSupervisor.beginActivityVisibilityUpdate();
         try {
             // First the front root tasks. In case any are not fullscreen and are in front of home.
@@ -1914,6 +1908,7 @@
             }
         } finally {
             mTaskSupervisor.endActivityVisibilityUpdate();
+            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
     }
 
@@ -2163,6 +2158,12 @@
                 // Use Task#setBoundsUnchecked to skip checking windowing mode as the windowing mode
                 // will be updated later after this is collected in transition.
                 rootTask.setBoundsUnchecked(taskFragment.getBounds());
+                // The exit-PIP activity resumes early for seamless transition. In certain
+                // scenarios, this introduces unintended addition to recents. To address this,
+                // we mark the root task for automatic removal from recents. This ensures that
+                // after the pinned activity reparents to its original task, the root task is
+                // automatically removed from the recents list.
+                rootTask.autoRemoveRecents = true;
 
                 // Move the last recents animation transaction from original task to the new one.
                 if (task.mLastRecentsAnimationTransaction != null) {
@@ -2846,10 +2847,6 @@
     }
 
     SleepToken createSleepToken(String tag, int displayId) {
-        return createSleepToken(tag, displayId, false /* isSwappingDisplay */);
-    }
-
-    SleepToken createSleepToken(String tag, int displayId, boolean isSwappingDisplay) {
         final DisplayContent display = getDisplayContent(displayId);
         if (display == null) {
             throw new IllegalArgumentException("Invalid display: " + displayId);
@@ -2858,16 +2855,13 @@
         final int tokenKey = makeSleepTokenKey(tag, displayId);
         SleepToken token = mSleepTokens.get(tokenKey);
         if (token == null) {
-            token = new SleepToken(tag, displayId, isSwappingDisplay);
+            token = new SleepToken(tag, displayId);
             mSleepTokens.put(tokenKey, token);
             display.mAllSleepTokens.add(token);
             ProtoLog.d(WM_DEBUG_STATES, "Create sleep token: tag=%s, displayId=%d", tag, displayId);
         } else {
             throw new RuntimeException("Create the same sleep token twice: " + token);
         }
-        if (isSwappingDisplay) {
-            display.mWallpaperController.onDisplaySwitchStarted();
-        }
         return token;
     }
 
@@ -3801,34 +3795,18 @@
         private final String mTag;
         private final long mAcquireTime;
         private final int mDisplayId;
-        private final boolean mIsSwappingDisplay;
         final int mHashKey;
 
-        // The display could remain in sleep after the physical display swapped, adding a 1
-        // seconds display swap timeout to prevent activities staying in PAUSED state.
-        // Otherwise, the sleep token should be removed once display turns back on after swapped.
-        private static final long DISPLAY_SWAP_TIMEOUT = 1000;
-
-        SleepToken(String tag, int displayId, boolean isSwappingDisplay) {
+        SleepToken(String tag, int displayId) {
             mTag = tag;
             mDisplayId = displayId;
             mAcquireTime = SystemClock.uptimeMillis();
-            mIsSwappingDisplay = isSwappingDisplay;
             mHashKey = makeSleepTokenKey(mTag, mDisplayId);
         }
 
-        public boolean isDisplaySwapping() {
-            long now = SystemClock.uptimeMillis();
-            if (now - mAcquireTime > DISPLAY_SWAP_TIMEOUT) {
-                return false;
-            }
-            return mIsSwappingDisplay;
-        }
-
         @Override
         public String toString() {
             return "{\"" + mTag + "\", display " + mDisplayId
-                    + (mIsSwappingDisplay ? " is swapping " : "")
                     + ", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
         }
 
diff --git a/services/core/java/com/android/server/wm/SafeActivityOptions.java b/services/core/java/com/android/server/wm/SafeActivityOptions.java
index b452131..8c7b637 100644
--- a/services/core/java/com/android/server/wm/SafeActivityOptions.java
+++ b/services/core/java/com/android/server/wm/SafeActivityOptions.java
@@ -442,7 +442,10 @@
         return taskDisplayArea;
     }
 
-    private boolean isAssistant(ActivityTaskManagerService atmService, int callingUid) {
+    /**
+     * Returns whether the given UID caller is the assistant.
+     */
+    public static boolean isAssistant(ActivityTaskManagerService atmService, int callingUid) {
         if (atmService.mActiveVoiceInteractionServiceComponent == null) {
             return false;
         }
diff --git a/services/core/java/com/android/server/wm/ScreenRecordingCallbackController.java b/services/core/java/com/android/server/wm/ScreenRecordingCallbackController.java
index 967f415..ad4faab 100644
--- a/services/core/java/com/android/server/wm/ScreenRecordingCallbackController.java
+++ b/services/core/java/com/android/server/wm/ScreenRecordingCallbackController.java
@@ -33,7 +33,7 @@
 import android.window.IScreenRecordingCallback;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index e7bffdf..31fda77 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -57,7 +57,7 @@
 
 import com.android.internal.R;
 import com.android.internal.policy.TransitionAnimation;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.display.DisplayControl;
 import com.android.server.wm.SurfaceAnimator.AnimationType;
 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
@@ -815,10 +815,8 @@
                 if (mDisplayContent.getRotationAnimation() == ScreenRotationAnimation.this) {
                     // It also invokes kill().
                     mDisplayContent.setRotationAnimation(null);
-                    if (mDisplayContent.mDisplayRotationCompatPolicy != null) {
-                        mDisplayContent.mDisplayRotationCompatPolicy
-                                .onScreenRotationAnimationFinished();
-                    }
+                    mDisplayContent.mAppCompatCameraPolicy
+                            .onScreenRotationAnimationFinished();
                 } else {
                     kill();
                 }
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 3b3eeb4..75e3e65 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -41,7 +41,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-import static com.android.window.flags.Flags.windowSessionRelayoutInfo;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -64,7 +63,6 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.ArraySet;
-import android.util.MergedConfiguration;
 import android.util.Slog;
 import android.view.IWindow;
 import android.view.IWindowId;
@@ -81,13 +79,12 @@
 import android.view.WindowInsets.Type.InsetsType;
 import android.view.WindowManager;
 import android.view.WindowRelayoutResult;
-import android.window.ClientWindowFrames;
 import android.window.InputTransferToken;
 import android.window.OnBackInvokedCallbackInfo;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.logging.MetricsLoggerWrapper;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.LocalServices;
 import com.android.server.wm.WindowManagerService.H;
 import com.android.window.flags.Flags;
@@ -290,37 +287,12 @@
         return res;
     }
 
-    /** @deprecated */
-    @Deprecated
-    @Override
-    public int relayoutLegacy(IWindow window, WindowManager.LayoutParams attrs,
-            int requestedWidth, int requestedHeight, int viewFlags, int flags, int seq,
-            int lastSyncSeqId, ClientWindowFrames outFrames,
-            MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl,
-            InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls,
-            Bundle outBundle) {
-        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, mRelayoutTag);
-        int res = mService.relayoutWindow(this, window, attrs,
-                requestedWidth, requestedHeight, viewFlags, flags, seq,
-                lastSyncSeqId, outFrames, mergedConfiguration, outSurfaceControl, outInsetsState,
-                outActiveControls, outBundle);
-        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-        return res;
-    }
-
     @Override
     public void relayoutAsync(IWindow window, WindowManager.LayoutParams attrs,
             int requestedWidth, int requestedHeight, int viewFlags, int flags, int seq,
             int lastSyncSeqId) {
-        if (windowSessionRelayoutInfo()) {
-            relayout(window, attrs, requestedWidth, requestedHeight, viewFlags, flags, seq,
-                    lastSyncSeqId, null /* outRelayoutResult */);
-        } else {
-            relayoutLegacy(window, attrs, requestedWidth, requestedHeight, viewFlags, flags, seq,
-                    lastSyncSeqId, null /* outFrames */, null /* mergedConfiguration */,
-                    null /* outSurfaceControl */, null /* outInsetsState */,
-                    null /* outActiveControls */, null /* outSyncIdBundle */);
-        }
+        relayout(window, attrs, requestedWidth, requestedHeight, viewFlags, flags, seq,
+                lastSyncSeqId, null /* outRelayoutResult */);
     }
 
     @Override
@@ -377,7 +349,7 @@
         final int callingPid = Binder.getCallingPid();
         // Validate and resolve ClipDescription data before clearing the calling identity
         validateAndResolveDragMimeTypeExtras(data, callingUid, callingPid, mPackageName);
-        validateDragFlags(flags);
+        validateDragFlags(flags, callingUid);
         final long ident = Binder.clearCallingIdentity();
         try {
             return mDragDropController.performDrag(mPid, mUid, window, flags, surface, touchSource,
@@ -403,12 +375,17 @@
      * Validates the given drag flags.
      */
     @VisibleForTesting
-    void validateDragFlags(int flags) {
+    void validateDragFlags(int flags, int callingUid) {
         if ((flags & View.DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION) != 0) {
             if (!mCanStartTasksFromRecents) {
                 throw new SecurityException("Requires START_TASKS_FROM_RECENTS permission");
             }
         }
+        if ((flags & View.DRAG_FLAG_HIDE_CALLING_TASK_ON_DRAG_START) != 0) {
+            if (!SafeActivityOptions.isAssistant(mService.mAtmService, callingUid)) {
+                throw new SecurityException("Caller is not the assistant");
+            }
+        }
     }
 
     /**
@@ -827,7 +804,7 @@
         if (changed && noSystemOverlayPermission) {
             if (mAlertWindowSurfaces.isEmpty()) {
                 cancelAlertWindowNotification();
-            } else if (mAlertWindowNotification == null) {
+            } else if (mAlertWindowNotification == null && !isSatellitePointingUiPackage()) {
                 mAlertWindowNotification = new AlertWindowNotification(mService, mPackageName);
                 if (mShowingAlertWindowNotificationAllowed) {
                     mAlertWindowNotification.post();
@@ -842,6 +819,16 @@
         }
     }
 
+    // TODO b/349195999 - short term solution to not show the satellite pointing ui notification.
+    private boolean isSatellitePointingUiPackage() {
+        if (mPackageName == null || !mPackageName.equals(mService.mContext.getString(
+            com.android.internal.R.string.config_pointing_ui_package))) {
+            return false;
+        }
+        return ActivityTaskManagerService.checkPermission(
+            android.Manifest.permission.SATELLITE_COMMUNICATION, mPid, mUid) == PERMISSION_GRANTED;
+    }
+
     void setShowingAlertWindowNotificationAllowed(boolean allowed) {
         mShowingAlertWindowNotificationAllowed = allowed;
         if (mAlertWindowNotification != null) {
@@ -897,6 +884,9 @@
                 pw.print(" mClientDead="); pw.print(mClientDead);
                 pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
         pw.print(prefix); pw.print("mPackageName="); pw.println(mPackageName);
+        if (isSatellitePointingUiPackage()) {
+            pw.print(prefix); pw.println("mIsSatellitePointingUiPackage=true");
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/SmoothDimmer.java b/services/core/java/com/android/server/wm/SmoothDimmer.java
index b5d94a2..2b4d901 100644
--- a/services/core/java/com/android/server/wm/SmoothDimmer.java
+++ b/services/core/java/com/android/server/wm/SmoothDimmer.java
@@ -26,7 +26,7 @@
 import android.view.SurfaceControl;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 class SmoothDimmer extends Dimmer {
 
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index c632714..9cfd396 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -33,7 +33,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.protolog.common.LogLevel;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
diff --git a/services/core/java/com/android/server/wm/SurfaceFreezer.java b/services/core/java/com/android/server/wm/SurfaceFreezer.java
index 0c36d27..34abf23 100644
--- a/services/core/java/com/android/server/wm/SurfaceFreezer.java
+++ b/services/core/java/com/android/server/wm/SurfaceFreezer.java
@@ -31,7 +31,7 @@
 import android.window.ScreenCapture;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 /**
  * This class handles "freezing" of an Animatable. The Animatable in question should implement
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 787c5d6..79fec23 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -47,8 +47,6 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.SurfaceControl.METADATA_TASK_ID;
-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.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.TRANSIT_CHANGE;
@@ -183,7 +181,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IVoiceInteractor;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.XmlUtils;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.internal.util.function.pooled.PooledPredicate;
@@ -406,8 +404,6 @@
     String mCallingPackage;
     String mCallingFeatureId;
 
-    private static final Rect sTmpBounds = new Rect();
-
     // Last non-fullscreen bounds the task was launched in or resized to.
     // The information is persisted and used to determine the appropriate root task to launch the
     // task into on restore.
@@ -499,6 +495,12 @@
      */
     boolean mReparentLeafTaskIfRelaunch;
 
+    /**
+     * Set to affect whether recents should be able to trim this task or not. It's set to true by
+     * default.
+     */
+    boolean mIsTrimmableFromRecents;
+
     private final AnimatingActivityRegistry mAnimatingActivityRegistry =
             new AnimatingActivityRegistry();
 
@@ -670,6 +672,7 @@
         mLaunchCookie = _launchCookie;
         mDeferTaskAppear = _deferTaskAppear;
         mRemoveWithTaskOrganizer = _removeWithTaskOrganizer;
+        mIsTrimmableFromRecents = true;
         EventLogTags.writeWmTaskCreated(mTaskId);
     }
 
@@ -1994,6 +1997,12 @@
         final boolean wasInMultiWindowMode = inMultiWindowMode();
         final boolean wasInPictureInPicture = inPinnedWindowingMode();
         super.onConfigurationChanged(newParentConfig);
+        if (mDisplayContent == null) {
+            // This should be initializing from Task.Builder. The onConfigurationChanged will be
+            // called again when this task is attached to hierarchy. Early return here because the
+            // following operations are no-op for a non-attached task.
+            return;
+        }
         // Only need to update surface size here since the super method will handle updating
         // surface position.
         updateSurfaceSize(getSyncTransaction());
@@ -2860,69 +2869,6 @@
         }
     }
 
-    /**
-     * Calculate the maximum visible area of this task. If the task has only one app,
-     * the result will be visible frame of that app. If the task has more than one apps,
-     * we search from top down if the next app got different visible area.
-     *
-     * This effort is to handle the case where some task (eg. GMail composer) might pop up
-     * a dialog that's different in size from the activity below, in which case we should
-     * be dimming the entire task area behind the dialog.
-     *
-     * @param out the union of visible bounds.
-     */
-    private static void getMaxVisibleBounds(ActivityRecord token, Rect out, boolean[] foundTop) {
-        // skip hidden (or about to hide) apps
-        if (token.mIsExiting || !token.isClientVisible() || !token.isVisibleRequested()) {
-            return;
-        }
-        final WindowState win = token.findMainWindow();
-        if (win == null) {
-            return;
-        }
-        if (!foundTop[0]) {
-            foundTop[0] = true;
-            out.setEmpty();
-        }
-
-        final Rect visibleFrame = sTmpBounds;
-        final WindowManager.LayoutParams attrs = win.mAttrs;
-        visibleFrame.set(win.getFrame());
-        visibleFrame.inset(win.getInsetsStateWithVisibilityOverride().calculateVisibleInsets(
-                visibleFrame, attrs.type, win.getActivityType(), attrs.softInputMode,
-                attrs.flags));
-        out.union(visibleFrame);
-    }
-
-    /** Bounds of the task to be used for dimming, as well as touch related tests. */
-    @Override
-    void getDimBounds(@NonNull Rect out) {
-        if (isRootTask()) {
-            getBounds(out);
-            return;
-        }
-
-        final Task rootTask = getRootTask();
-        if (inFreeformWindowingMode()) {
-            boolean[] foundTop = { false };
-            forAllActivities(a -> { getMaxVisibleBounds(a, out, foundTop); });
-            if (foundTop[0]) {
-                return;
-            }
-        }
-
-        if (!matchParentBounds()) {
-            // When minimizing the root docked task when going home, we don't adjust the task bounds
-            // so we need to intersect the task bounds with the root task bounds here..
-            rootTask.getBounds(mTmpRect);
-            mTmpRect.intersect(getBounds());
-            out.set(mTmpRect);
-        } else {
-            out.set(getBounds());
-        }
-        return;
-    }
-
     void setDragResizing(boolean dragResizing) {
         if (mDragResizing != dragResizing) {
             // No need to check if allowed if it's leaving dragResize
@@ -3472,6 +3418,7 @@
         info.isVisibleRequested = isVisibleRequested();
         info.isSleeping = shouldSleepActivities();
         info.isTopActivityTransparent = top != null && !top.fillsParent();
+        info.isTopActivityStyleFloating = top != null && top.isStyleFloating();
         appCompatTaskInfo.topActivityLetterboxVerticalPosition = TaskInfo.PROPERTY_VALUE_UNSET;
         appCompatTaskInfo.topActivityLetterboxHorizontalPosition = TaskInfo.PROPERTY_VALUE_UNSET;
         appCompatTaskInfo.topActivityLetterboxWidth = TaskInfo.PROPERTY_VALUE_UNSET;
@@ -3518,7 +3465,8 @@
         appCompatTaskInfo.topActivityBoundsLetterboxed = top != null && top.areBoundsLetterboxed();
         appCompatTaskInfo.cameraCompatTaskInfo.freeformCameraCompatMode = top == null
                 ? CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE
-                : top.mLetterboxUiController.getFreeformCameraCompatMode();
+                : top.mAppCompatController.getAppCompatCameraOverrides()
+                        .getFreeformCameraCompatMode();
     }
 
     /**
@@ -3580,15 +3528,29 @@
                 ? null : new PictureInPictureParams(top.pictureInPictureArgs);
     }
 
-    Rect getDisplayCutoutInsets() {
-        if (mDisplayContent == null || getDisplayInfo().displayCutout == null) return null;
+    /** @return The display cutout insets where the main window is not allowed to extend to. */
+    @NonNull Rect getDisplayCutoutInsets() {
+        final Rect displayCutoutInsets = new Rect();
+        if (mDisplayContent == null || getDisplayInfo().displayCutout == null) {
+            return displayCutoutInsets;
+        }
         final WindowState w = getTopVisibleAppMainWindow();
-        final int displayCutoutMode = w == null
-                ? WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
-                : w.getAttrs().layoutInDisplayCutoutMode;
-        return (displayCutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
-                || displayCutoutMode == LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES)
-                ? null : getDisplayInfo().displayCutout.getSafeInsets();
+        final Rect displayFrame;
+        if (w != null && w.mHaveFrame) {
+            displayFrame = w.getDisplayFrame();
+        } else {
+            displayFrame = mDisplayContent.getBounds();
+            displayFrame.inset(getDisplayInfo().displayCutout.getSafeInsets());
+        }
+        final Rect taskBounds = getBounds();
+        if (displayCutoutInsets.setIntersect(taskBounds, displayFrame)) {
+            displayCutoutInsets.set(
+                    displayCutoutInsets.left - taskBounds.left,
+                    displayCutoutInsets.top - taskBounds.top,
+                    taskBounds.right - displayCutoutInsets.right,
+                    taskBounds.bottom - displayCutoutInsets.bottom);
+        }
+        return displayCutoutInsets;
     }
 
     /**
@@ -3901,6 +3863,7 @@
         pw.print(" isResizeable="); pw.println(isResizeable());
         pw.print(prefix); pw.print("lastActiveTime="); pw.print(lastActiveTime);
         pw.println(" (inactive for " + (getInactiveDuration() / 1000) + "s)");
+        pw.print(prefix); pw.println(" isTrimmable=" + mIsTrimmableFromRecents);
     }
 
     @Override
@@ -4786,8 +4749,7 @@
                     // task is still updated by core. Otherwise if the task is collected (e.g.
                     // rotation change) after leaving this scope, the visibility operation will be
                     // put in sync transaction, then it is not synced with reparent.
-                    if (com.android.window.flags.Flags.removePrepareSurfaceInPlacement()
-                            && lastParentBeforePip.mSyncState == SYNC_STATE_NONE) {
+                    if (lastParentBeforePip.mSyncState == SYNC_STATE_NONE) {
                         lastParentBeforePip.prepareSurfaces();
                         // If the moveToFront is a part of finishing transition, then make sure
                         // the z-order of tasks are up-to-date.
@@ -6136,11 +6098,6 @@
         return setBoundsUnchecked(!inMultiWindowMode() ? null : bounds);
     }
 
-    @Override
-    public void getBounds(Rect bounds) {
-        bounds.set(getBounds());
-    }
-
     /**
      * Put a Task in this root task. Used for adding only.
      * When task is added to top of the root task, the entire branch of the hierarchy (including
@@ -6347,6 +6304,10 @@
         }
     }
 
+    void setTrimmableFromRecents(boolean isTrimmable) {
+        mIsTrimmableFromRecents = isTrimmable;
+    }
+
     /**
      * Return true if the activityInfo has the same requiredDisplayCategory as this task.
      */
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index eff8315..eaf3012 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -52,7 +52,7 @@
 import android.view.WindowManager;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.internal.util.function.pooled.PooledPredicate;
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index ab72e3c..9b2c022 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -29,6 +29,7 @@
 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 android.app.WindowConfiguration.isFloating;
 import static android.content.pm.ActivityInfo.FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING;
 import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
@@ -81,7 +82,6 @@
 import android.app.ResultInfo;
 import android.app.WindowConfiguration;
 import android.app.servertransaction.ActivityResultItem;
-import android.app.servertransaction.ClientTransaction;
 import android.app.servertransaction.NewIntentItem;
 import android.app.servertransaction.PauseActivityItem;
 import android.app.servertransaction.ResumeActivityItem;
@@ -106,7 +106,7 @@
 import android.window.TaskFragmentOrganizerToken;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.ToBooleanFunction;
 import com.android.server.am.HostingRecord;
 import com.android.server.pm.pkg.AndroidPackage;
@@ -1603,9 +1603,6 @@
 
             try {
                 final IApplicationThread appThread = next.app.getThread();
-                final ClientTransaction transaction = Flags.bundleClientTransactionFlag()
-                        ? null
-                        : ClientTransaction.obtain(appThread);
                 // Deliver all pending results.
                 final ArrayList<ResultInfo> a = next.results;
                 if (a != null) {
@@ -1616,24 +1613,16 @@
                         }
                         final ActivityResultItem activityResultItem = ActivityResultItem.obtain(
                                 next.token, a);
-                        if (transaction == null) {
-                            mAtmService.getLifecycleManager().scheduleTransactionItem(
-                                    appThread, activityResultItem);
-                        } else {
-                            transaction.addTransactionItem(activityResultItem);
-                        }
+                        mAtmService.getLifecycleManager().scheduleTransactionItem(
+                                appThread, activityResultItem);
                     }
                 }
 
                 if (next.newIntents != null) {
                     final NewIntentItem newIntentItem = NewIntentItem.obtain(
                             next.token, next.newIntents, true /* resume */);
-                    if (transaction == null) {
-                        mAtmService.getLifecycleManager().scheduleTransactionItem(
-                                appThread, newIntentItem);
-                    } else {
-                        transaction.addTransactionItem(newIntentItem);
-                    }
+                    mAtmService.getLifecycleManager().scheduleTransactionItem(
+                            appThread, newIntentItem);
                 }
 
                 // Well the app will no longer be stopped.
@@ -1650,13 +1639,8 @@
                 final ResumeActivityItem resumeActivityItem = ResumeActivityItem.obtain(
                         next.token, topProcessState, dc.isNextTransitionForward(),
                         next.shouldSendCompatFakeFocus());
-                if (transaction == null) {
-                    mAtmService.getLifecycleManager().scheduleTransactionItem(
-                            appThread, resumeActivityItem);
-                } else {
-                    transaction.addTransactionItem(resumeActivityItem);
-                    mAtmService.getLifecycleManager().scheduleTransaction(transaction);
-                }
+                mAtmService.getLifecycleManager().scheduleTransactionItem(
+                        appThread, resumeActivityItem);
 
                 ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Resumed %s", next);
             } catch (Exception e) {
@@ -2241,15 +2225,17 @@
     static class ConfigOverrideHint {
         @Nullable DisplayInfo mTmpOverrideDisplayInfo;
         @Nullable ActivityRecord.CompatDisplayInsets mTmpCompatInsets;
-        @Nullable Rect mTmpParentAppBoundsOverride;
+        @Nullable Rect mParentAppBoundsOverride;
         int mTmpOverrideConfigOrientation;
         boolean mUseOverrideInsetsForConfig;
 
         void resolveTmpOverrides(DisplayContent dc, Configuration parentConfig,
                 boolean isFixedRotationTransforming) {
-            mTmpParentAppBoundsOverride = new Rect(parentConfig.windowConfiguration.getAppBounds());
+            mParentAppBoundsOverride = new Rect(parentConfig.windowConfiguration.getAppBounds());
+            mTmpOverrideConfigOrientation = parentConfig.orientation;
             final Insets insets;
-            if (mUseOverrideInsetsForConfig && dc != null) {
+            if (mUseOverrideInsetsForConfig && dc != null
+                    && !isFloating(parentConfig.windowConfiguration.getWindowingMode())) {
                 // Insets are decoupled from configuration by default from V+, use legacy
                 // compatibility behaviour for apps targeting SDK earlier than 35
                 // (see applySizeOverrideIfNeeded).
@@ -2269,13 +2255,12 @@
             } else {
                 insets = Insets.NONE;
             }
-            mTmpParentAppBoundsOverride.inset(insets);
+            mParentAppBoundsOverride.inset(insets);
         }
 
         void resetTmpOverrides() {
             mTmpOverrideDisplayInfo = null;
             mTmpCompatInsets = null;
-            mTmpParentAppBoundsOverride = null;
             mTmpOverrideConfigOrientation = ORIENTATION_UNDEFINED;
         }
     }
@@ -2364,7 +2349,7 @@
                 final Rect containingAppBounds;
                 if (insideParentBounds) {
                     containingAppBounds = useOverrideInsetsForConfig
-                            ? overrideHint.mTmpParentAppBoundsOverride
+                            ? overrideHint.mParentAppBoundsOverride
                             : parentConfig.windowConfiguration.getAppBounds();
                 } else {
                     // Restrict appBounds to display non-decor rather than parent because the
diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
index c4e932a..b6b6cf2 100644
--- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java
@@ -59,7 +59,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.protolog.ProtoLogGroup;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.window.flags.Flags;
 
 import java.lang.annotation.Retention;
@@ -171,11 +171,7 @@
 
         TaskFragmentOrganizerState(@NonNull ITaskFragmentOrganizer organizer, int pid, int uid,
                 boolean isSystemOrganizer) {
-            if (Flags.bundleClientTransactionFlag()) {
-                mAppThread = getAppThread(pid, uid);
-            } else {
-                mAppThread = null;
-            }
+            mAppThread = getAppThread(pid, uid);
             mOrganizer = organizer;
             mOrganizerPid = pid;
             mOrganizerUid = uid;
@@ -431,13 +427,9 @@
                 return;
             }
             try {
-                if (Flags.bundleClientTransactionFlag()) {
-                    // Dispatch through IApplicationThread to ensure the binder call is in order
-                    // with ClientTransaction.
-                    mAppThread.scheduleTaskFragmentTransaction(mOrganizer, transaction);
-                } else {
-                    mOrganizer.onTransactionReady(transaction);
-                }
+                // Dispatch through IApplicationThread to ensure the binder call is in order
+                // with ClientTransaction.
+                mAppThread.scheduleTaskFragmentTransaction(mOrganizer, transaction);
             } catch (RemoteException e) {
                 Slog.d(TAG, "Exception sending TaskFragmentTransaction", e);
                 return;
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index b24d53b..6e36d427 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -57,7 +57,7 @@
 import android.window.WindowContainerToken;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.ArrayUtils;
 
 import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 9b3fb6b..972dd2e 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -59,7 +59,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.policy.TaskResizingAlgorithm;
 import com.android.internal.policy.TaskResizingAlgorithm.CtrlType;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 import java.util.concurrent.CompletableFuture;
 
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 63ca469..47af6fc 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -68,6 +68,8 @@
 import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM;
 import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_SPLASH_SCREEN;
 import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_PREDICT_BACK;
+import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
 import static com.android.server.wm.WindowState.BLAST_TIMEOUT_DURATION;
 
 import android.annotation.IntDef;
@@ -103,8 +105,8 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.graphics.ColorUtils;
 import com.android.internal.policy.TransitionAnimation;
+import com.android.internal.protolog.ProtoLog;
 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.inputmethod.InputMethodManagerInternal;
 import com.android.server.statusbar.StatusBarManagerInternal;
@@ -1195,7 +1197,6 @@
             throw new IllegalStateException("Can't finish a non-playing transition " + mSyncId);
         }
         mController.mFinishingTransition = this;
-
         if (mTransientHideTasks != null && !mTransientHideTasks.isEmpty()) {
             // The transient hide tasks could be occluded now, e.g. returning to home. So trigger
             // the update to make the activities in the tasks invisible-requested, then the next
@@ -1380,7 +1381,10 @@
             // If the activity was just inserted to an invisible task, it will keep INITIALIZING
             // state. Then no need to notify the callback to avoid clearing some states
             // unexpectedly, e.g. launch-task-behind.
-            if (ar.isVisibleRequested() || !ar.isState(ActivityRecord.State.INITIALIZING)) {
+            // However, skip dispatch to predictive back animation target, because it only set
+            // launch-task-behind to make the activity become visible.
+            if ((ar.isVisibleRequested() || !ar.isState(ActivityRecord.State.INITIALIZING))
+                    && !ar.isAnimating(PARENTS, ANIMATION_TYPE_PREDICT_BACK)) {
                 mController.dispatchLegacyAppTransitionFinished(ar);
             }
 
@@ -1439,11 +1443,11 @@
                 asyncRotationController.onTransitionFinished();
             }
             dc.onTransitionFinished();
-            if (hasParticipatedDisplay && dc.mDisplayRotationCompatPolicy != null) {
+            if (hasParticipatedDisplay) {
                 final ChangeInfo changeInfo = mChanges.get(dc);
                 if (changeInfo != null
                         && changeInfo.mRotation != dc.getWindowConfiguration().getRotation()) {
-                    dc.mDisplayRotationCompatPolicy.onScreenRotationAnimationFinished();
+                    dc.mAppCompatCameraPolicy.onScreenRotationAnimationFinished();
                 }
             }
             if (mTransientLaunches != null) {
@@ -1690,7 +1694,7 @@
         // ActivityRecord#canShowWindows() may reject to show its window. The visibility also
         // needs to be updated for STATE_ABORT.
         commitVisibleActivities(transaction);
-        commitVisibleWallpapers();
+        commitVisibleWallpapers(transaction);
 
         if (mTransactionCompletedListeners != null) {
             for (int i = 0; i < mTransactionCompletedListeners.size(); i++) {
@@ -1903,7 +1907,10 @@
         } else {
             final List<TransitionInfo.Change> changes = info.getChanges();
             for (int i = changes.size() - 1; i >= 0; --i) {
-                if (mTargets.get(i).mContainer.asActivityRecord() != null) {
+                final WindowContainer<?> container = mTargets.get(i).mContainer;
+                if (container.asActivityRecord() != null
+                        || (container.asTask() != null
+                                && mOverrideOptions.getOverrideTaskTransition())) {
                     changes.get(i).setAnimationOptions(mOverrideOptions);
                     // TODO(b/295805497): Extract mBackgroundColor from AnimationOptions.
                     changes.get(i).setBackgroundColor(mOverrideOptions.getBackgroundColor());
@@ -2121,7 +2128,7 @@
     /**
      * Reset waitingToshow for all wallpapers, and commit the visibility of the visible ones
      */
-    private void commitVisibleWallpapers() {
+    private void commitVisibleWallpapers(SurfaceControl.Transaction t) {
         boolean showWallpaper = shouldWallpaperBeVisible();
         for (int i = mParticipants.size() - 1; i >= 0; --i) {
             final WallpaperWindowToken wallpaper = mParticipants.valueAt(i).asWallpaperToken();
@@ -2129,6 +2136,14 @@
                 if (!wallpaper.isVisible() && wallpaper.isVisibleRequested()) {
                     wallpaper.commitVisibility(showWallpaper);
                 }
+                if (showWallpaper && Flags.ensureWallpaperInTransitions()
+                        && wallpaper.isVisibleRequested()
+                        && getLeashSurface(wallpaper, t) != wallpaper.getSurfaceControl()) {
+                    // If on a rotation leash, we need to explicitly show the wallpaper surface
+                    // because shell only gets the leash and we don't allow non-transition logic
+                    // to touch the surfaces until the transition is over.
+                    t.show(wallpaper.getSurfaceControl());
+                }
             }
         }
     }
@@ -2541,9 +2556,9 @@
             if (wc.asWindowState() != null) continue;
 
             final ChangeInfo changeInfo = changes.get(wc);
-
-            // Reject no-ops
-            if (!changeInfo.hasChanged()) {
+            // Reject no-ops, unless wallpaper
+            if (!changeInfo.hasChanged()
+                    && (!Flags.ensureWallpaperInTransitions() || wc.asWallpaperToken() == null)) {
                 ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
                         "  Rejecting as no-op: %s", wc);
                 continue;
@@ -2816,6 +2831,9 @@
             final Rect parentBounds = parent.getBounds();
             change.setEndRelOffset(bounds.left - parentBounds.left,
                     bounds.top - parentBounds.top);
+            if (Flags.activityEmbeddingOverlayPresentationFlag()) {
+                change.setEndParentSize(parentBounds.width(), parentBounds.height());
+            }
             int endRotation = target.getWindowConfiguration().getRotation();
             if (activityRecord != null) {
                 // TODO(b/227427984): Shell needs to aware letterbox.
@@ -2827,6 +2845,13 @@
                     // Use parent rotation because shell doesn't know the surface is rotated.
                     endRotation = parent.getWindowConfiguration().getRotation();
                 }
+            } else if (isWallpaper(target) && Flags.ensureWallpaperInTransitions()
+                    && target.getRelativeDisplayRotation() != 0
+                    && !target.mTransitionController.useShellTransitionsRotation()) {
+                // If the wallpaper is "fixed-rotated", shell is unaware of this, so use the
+                // "as-if-not-rotating" bounds and rotation
+                change.setEndAbsBounds(parent.getBounds());
+                endRotation = parent.getWindowConfiguration().getRotation();
             } else {
                 change.setEndAbsBounds(bounds);
             }
@@ -3225,6 +3250,12 @@
         Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_WINDOW_MANAGER, TAG, cookie);
     }
 
+    boolean hasChanged(WindowContainer wc) {
+        final ChangeInfo chg = mChanges.get(wc);
+        if (chg == null) return false;
+        return chg.hasChanged();
+    }
+
     @VisibleForTesting
     static class ChangeInfo {
         private static final int FLAG_NONE = 0;
@@ -3507,10 +3538,15 @@
             Slog.e(TAG, "#" + mSyncId + " readiness timeout, used=" + mReadyTrackerOld.mUsed
                     + " deferReadyDepth=" + mReadyTrackerOld.mDeferReadyDepth
                     + " group=" + mReadyTrackerOld.mReadyGroups);
-            return;
+        } else {
+            Slog.e(TAG, "#" + mSyncId + " met conditions: " + mReadyTracker.mMet);
+            Slog.e(TAG, "#" + mSyncId + " unmet conditions: " + mReadyTracker.mConditions);
         }
-        Slog.e(TAG, "#" + mSyncId + " met conditions: " + mReadyTracker.mMet);
-        Slog.e(TAG, "#" + mSyncId + " unmet conditions: " + mReadyTracker.mConditions);
+        // Make sure the pending display change can be applied (especially DC#mWaitingForConfig)
+        // in case shell hasn't called WindowOrganizerController#startTransition yet.
+        if (mState < STATE_STARTED && this == mController.getCollectingTransition()) {
+            applyDisplayChangeIfNeeded(new ArraySet<>());
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index 0812323..f4ff404 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -53,7 +53,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.protolog.ProtoLogGroup;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.FgThread;
 import com.android.window.flags.Flags;
 
diff --git a/services/core/java/com/android/server/wm/TransparentPolicy.java b/services/core/java/com/android/server/wm/TransparentPolicy.java
index b408397..3044abd 100644
--- a/services/core/java/com/android/server/wm/TransparentPolicy.java
+++ b/services/core/java/com/android/server/wm/TransparentPolicy.java
@@ -260,8 +260,9 @@
 
         private void start(@NonNull ActivityRecord firstOpaqueActivity) {
             mFirstOpaqueActivity = firstOpaqueActivity;
-            mFirstOpaqueActivity.mTransparentPolicy
-                    .mDestroyListeners.add(mActivityRecord.mTransparentPolicy);
+            mFirstOpaqueActivity.mAppCompatController.getTransparentPolicy()
+                    .mDestroyListeners.add(mActivityRecord.mAppCompatController
+                            .getTransparentPolicy());
             inheritFromOpaque(firstOpaqueActivity);
             final WindowContainer<?> parent = mActivityRecord.getParent();
             mLetterboxConfigListener = WindowContainer.overrideConfigurationPropagation(
@@ -312,8 +313,9 @@
             mInheritedAppCompatState = APP_COMPAT_STATE_CHANGED__STATE__UNKNOWN;
             mInheritedCompatDisplayInsets = null;
             if (mFirstOpaqueActivity != null) {
-                mFirstOpaqueActivity.mTransparentPolicy
-                        .mDestroyListeners.remove(mActivityRecord.mTransparentPolicy);
+                mFirstOpaqueActivity.mAppCompatController.getTransparentPolicy()
+                        .mDestroyListeners.remove(mActivityRecord.mAppCompatController
+                                .getTransparentPolicy());
             }
             mFirstOpaqueActivity = null;
         }
diff --git a/services/core/java/com/android/server/wm/TrustedPresentationListenerController.java b/services/core/java/com/android/server/wm/TrustedPresentationListenerController.java
index fa2d9bf..c0dc424 100644
--- a/services/core/java/com/android/server/wm/TrustedPresentationListenerController.java
+++ b/services/core/java/com/android/server/wm/TrustedPresentationListenerController.java
@@ -40,7 +40,7 @@
 import android.window.TrustedPresentationThresholds;
 import android.window.WindowInfosListener;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.wm.utils.RegionUtils;
 
 import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
index c071396..3947d02 100644
--- a/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
+++ b/services/core/java/com/android/server/wm/UnknownAppVisibilityController.java
@@ -153,6 +153,10 @@
             mUnknownApps.put(activity, UNKNOWN_STATE_WAITING_VISIBILITY_UPDATE);
             mDisplayContent.notifyKeyguardFlagsChanged();
             notifyVisibilitiesUpdated();
+        } else if (state == UNKNOWN_STATE_WAITING_RESUME
+                && !activity.isState(ActivityRecord.State.RESUMED)) {
+            Slog.d(TAG, "UAVC: skip waiting for non-resumed relayouted " + activity);
+            mUnknownApps.remove(activity);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java b/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java
index 4a5a20e..fffe692 100644
--- a/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/WallpaperAnimationAdapter.java
@@ -27,7 +27,7 @@
 import android.view.RemoteAnimationTarget;
 import android.view.SurfaceControl;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.wm.SurfaceAnimator.AnimationType;
 
 import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 3e43f5a..2652670 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -16,7 +16,6 @@
 
 package com.android.server.wm;
 
-import static android.app.WallpaperManager.COMMAND_DISPLAY_SWITCH;
 import static android.app.WallpaperManager.COMMAND_FREEZE;
 import static android.app.WallpaperManager.COMMAND_UNFREEZE;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
@@ -57,9 +56,10 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.ToBooleanFunction;
 import com.android.server.wallpaper.WallpaperCropper.WallpaperCropUtils;
+import com.android.window.flags.Flags;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -118,11 +118,6 @@
 
     private boolean mShouldOffsetWallpaperCenter;
 
-    /**
-     * Whether the wallpaper has been notified about a physical display switch event is started.
-     */
-    private volatile boolean mIsWallpaperNotifiedOnDisplaySwitch;
-
     private final ToBooleanFunction<WindowState> mFindWallpaperTargetFunction = w -> {
         final boolean useShellTransition = w.mTransitionController.isShellTransitionsEnabled();
         if (!useShellTransition) {
@@ -334,13 +329,13 @@
         }
         for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) {
             final WallpaperWindowToken token = mWallpaperTokens.get(i);
-            token.setVisibility(false);
             if (token.isVisible()) {
                 ProtoLog.d(WM_DEBUG_WALLPAPER,
                         "Hiding wallpaper %s from %s target=%s prev=%s callers=%s",
                         token, winGoingAway, mWallpaperTarget, mPrevWallpaperTarget,
                         Debug.getCallers(5));
             }
+            token.setVisibility(false);
         }
     }
 
@@ -764,10 +759,19 @@
 
     void collectTopWallpapers(Transition transition) {
         if (mFindResults.hasTopShowWhenLockedWallpaper()) {
-            transition.collect(mFindResults.mTopWallpaper.mTopShowWhenLockedWallpaper);
+            if (Flags.ensureWallpaperInTransitions()) {
+                transition.collect(mFindResults.mTopWallpaper.mTopShowWhenLockedWallpaper.mToken);
+            } else {
+                transition.collect(mFindResults.mTopWallpaper.mTopShowWhenLockedWallpaper);
+            }
+
         }
         if (mFindResults.hasTopHideWhenLockedWallpaper()) {
-            transition.collect(mFindResults.mTopWallpaper.mTopHideWhenLockedWallpaper);
+            if (Flags.ensureWallpaperInTransitions()) {
+                transition.collect(mFindResults.mTopWallpaper.mTopHideWhenLockedWallpaper.mToken);
+            } else {
+                transition.collect(mFindResults.mTopWallpaper.mTopHideWhenLockedWallpaper);
+            }
         }
     }
 
@@ -1084,52 +1088,6 @@
     }
 
     /**
-     * Notifies the wallpaper that the display turns off when switching physical device. If the
-     * wallpaper is currently visible, its client visibility will be preserved until the display is
-     * confirmed to be off or on.
-     */
-    void onDisplaySwitchStarted() {
-        mIsWallpaperNotifiedOnDisplaySwitch = notifyDisplaySwitch(true /* start */);
-    }
-
-    /**
-     * Called when the screen has finished turning on or the device goes to sleep. This is no-op if
-     * the operation is not part of a display switch.
-     */
-    void onDisplaySwitchFinished() {
-        // The method can be called outside WM lock (turned on), so only acquire lock if needed.
-        // This is to optimize the common cases that regular devices don't have display switch.
-        if (mIsWallpaperNotifiedOnDisplaySwitch) {
-            synchronized (mService.mGlobalLock) {
-                mIsWallpaperNotifiedOnDisplaySwitch = false;
-                notifyDisplaySwitch(false /* start */);
-            }
-        }
-    }
-
-    private boolean notifyDisplaySwitch(boolean start) {
-        boolean notified = false;
-        for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
-            final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
-            for (int i = token.getChildCount() - 1; i >= 0; i--) {
-                final WindowState w = token.getChildAt(i);
-                if (start && !w.mWinAnimator.getShown()) {
-                    continue;
-                }
-                try {
-                    w.mClient.dispatchWallpaperCommand(COMMAND_DISPLAY_SWITCH, 0 /* x */, 0 /* y */,
-                            start ? 1 : 0 /* use z as start or finish */,
-                            null /* bundle */, false /* sync */);
-                } catch (RemoteException e) {
-                    Slog.w(TAG, "Failed to dispatch COMMAND_DISPLAY_SWITCH " + e);
-                }
-                notified = true;
-            }
-        }
-        return notified;
-    }
-
-    /**
      * Each window can request a zoom, example:
      * - User is in overview, zoomed out.
      * - User also pulls down the shade.
diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
index 9d1551c..31156de 100644
--- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java
+++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
@@ -31,7 +31,8 @@
 import android.os.RemoteException;
 import android.util.SparseArray;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
+import com.android.window.flags.Flags;
 
 import java.util.function.Consumer;
 
@@ -80,6 +81,20 @@
         mDisplayContent.mWallpaperController.removeWallpaperToken(this);
     }
 
+    @Override
+    public void prepareSurfaces() {
+        super.prepareSurfaces();
+
+        if (Flags.ensureWallpaperInTransitions()) {
+            // Similar to Task.prepareSurfaces, outside of transitions we need to apply visibility
+            // changes directly. In transitions the transition player will take care of applying the
+            // visibility change.
+            if (!mTransitionController.inTransition(this)) {
+                getSyncTransaction().setVisibility(mSurfaceControl, isVisible());
+            }
+        }
+    }
+
     /**
      * Controls whether this wallpaper shows underneath the keyguard or is hidden and only
      * revealed once keyguard is dismissed.
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 8afcf0e..03342d3 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -34,7 +34,7 @@
 import android.view.Choreographer;
 import android.view.SurfaceControl;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.policy.WindowManagerPolicy;
 
 import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 70143ba..1d02f1c 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -111,7 +111,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.graphics.ColorUtils;
 import com.android.internal.protolog.common.LogLevel;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.ToBooleanFunction;
 import com.android.server.wm.SurfaceAnimator.Animatable;
 import com.android.server.wm.SurfaceAnimator.AnimationType;
@@ -179,7 +179,7 @@
 
     // List of children for this window container. List is in z-order as the children appear on
     // screen with the top-most window container at the tail of the list.
-    protected final WindowList<E> mChildren = new WindowList<E>();
+    protected final ArrayList<E> mChildren = new ArrayList<E>();
 
     // The specified orientation for this window container.
     // Shouldn't be accessed directly since subclasses can override getOverrideOrientation.
@@ -202,8 +202,7 @@
     private int mLastLayer = 0;
     private SurfaceControl mLastRelativeToLayer = null;
 
-    // TODO(b/132320879): Remove this from WindowContainers except DisplayContent.
-    private final Transaction mPendingTransaction;
+    private Transaction mPendingTransaction;
 
     /**
      * Windows that clients are waiting to have drawn.
@@ -238,12 +237,6 @@
     /** Total number of elements in this subtree, including our own hierarchy element. */
     private int mTreeWeight = 1;
 
-    /**
-     * Indicates whether we are animating and have committed the transaction to reparent our
-     * surface to the animation leash
-     */
-    private boolean mCommittedReparentToAnimationLeash;
-
     private int mSyncTransactionCommitCallbackDepth = 0;
 
     /** Interface for {@link #isAnimating} to check which cases for the container is animating. */
@@ -358,7 +351,6 @@
     WindowContainer(WindowManagerService wms) {
         mWmService = wms;
         mTransitionController = mWmService.mAtmService.getTransitionController();
-        mPendingTransaction = wms.mTransactionFactory.get();
         mSyncTransaction = wms.mTransactionFactory.get();
         mSurfaceAnimator = new SurfaceAnimator(this, this::onAnimationFinished, wms);
         mSurfaceFreezer = new SurfaceFreezer(this, wms);
@@ -580,6 +572,10 @@
     @Override
     public void onConfigurationChanged(Configuration newParentConfig) {
         super.onConfigurationChanged(newParentConfig);
+        if (mParent == null) {
+            // Avoid unnecessary surface operation before attaching to a parent.
+            return;
+        }
         updateSurfacePositionNonOrganized();
         scheduleAnimation();
         if (mOverlayHost != null) {
@@ -859,7 +855,7 @@
             mSurfaceFreezer.unfreeze(getSyncTransaction());
         }
         while (!mChildren.isEmpty()) {
-            final E child = mChildren.peekLast();
+            final E child = mChildren.getLast();
             child.removeImmediately();
             // Need to do this after calling remove on the child because the child might try to
             // remove/detach itself from its parent which will cause an exception if we remove
@@ -983,7 +979,7 @@
 
         switch (position) {
             case POSITION_TOP:
-                if (mChildren.peekLast() != child) {
+                if (getTopChild() != child) {
                     mChildren.remove(child);
                     mChildren.add(child);
                     onChildPositionChanged(child);
@@ -994,7 +990,7 @@
                 }
                 break;
             case POSITION_BOTTOM:
-                if (mChildren.peekFirst() != child) {
+                if (getBottomChild() != child) {
                     mChildren.remove(child);
                     mChildren.addFirst(child);
                     onChildPositionChanged(child);
@@ -1074,8 +1070,9 @@
             }
         }
         mDisplayContent = dc;
-        if (dc != null && dc != this) {
+        if (dc != null && dc != this && mPendingTransaction != null) {
             dc.getPendingTransaction().merge(mPendingTransaction);
+            mPendingTransaction = null;
         }
         for (int i = mChildren.size() - 1; i >= 0; --i) {
             final WindowContainer child = mChildren.get(i);
@@ -1448,7 +1445,13 @@
 
     /** Returns the top child container. */
     E getTopChild() {
-        return mChildren.peekLast();
+        final int n = mChildren.size();
+        return n == 0 ? null : mChildren.get(n - 1);
+    }
+
+    E getBottomChild() {
+        final int n = mChildren.size();
+        return n == 0 ? null : mChildren.get(0);
     }
 
     /**
@@ -2553,7 +2556,7 @@
         }
 
         if (mParent != null && mParent == other.mParent) {
-            final WindowList<WindowContainer> list = mParent.mChildren;
+            final ArrayList<WindowContainer> list = mParent.mChildren;
             return list.indexOf(this) > list.indexOf(other) ? 1 : -1;
         }
 
@@ -2590,7 +2593,7 @@
 
             // The position of the first non-common ancestor in the common ancestor list determines
             // which is greater the which.
-            final WindowList<WindowContainer> list = commonAncestor.mChildren;
+            final ArrayList<WindowContainer> list = commonAncestor.mChildren;
             return list.indexOf(thisParentChain.peekLast()) > list.indexOf(otherParentChain.peekLast())
                     ? 1 : -1;
         } finally {
@@ -2868,23 +2871,12 @@
     }
 
     void prepareSurfaces() {
-        // If a leash has been set when the transaction was committed, then the leash reparent has
-        // been committed.
-        mCommittedReparentToAnimationLeash = mSurfaceAnimator.hasLeash();
         for (int i = 0; i < mChildren.size(); i++) {
             mChildren.get(i).prepareSurfaces();
         }
     }
 
     /**
-     * @return true if the reparent to animation leash transaction has been committed, false
-     * otherwise.
-     */
-    boolean hasCommittedReparentToAnimationLeash() {
-        return mCommittedReparentToAnimationLeash;
-    }
-
-    /**
      * Trigger a call to prepareSurfaces from the animation thread, such that pending transactions
      * will be applied.
      */
@@ -2922,14 +2914,17 @@
 
     @Override
     public Transaction getPendingTransaction() {
-        final DisplayContent displayContent = getDisplayContent();
-        if (displayContent != null && displayContent != this) {
-            return displayContent.getPendingTransaction();
+        final WindowContainer<?> dc = mDisplayContent;
+        if (dc != null && dc.mPendingTransaction != null) {
+            return dc.mPendingTransaction;
         }
         // This WindowContainer has not attached to a display yet or this is a DisplayContent, so we
         // let the caller to save the surface operations within the local mPendingTransaction.
         // If this is not a DisplayContent, we will merge it to the pending transaction of its
         // display once it attaches to it.
+        if (mPendingTransaction == null) {
+            mPendingTransaction = mWmService.mTransactionFactory.get();
+        }
         return mPendingTransaction;
     }
 
@@ -3980,6 +3975,19 @@
     }
 
     /**
+     * Returns {@code true} if this window container belongs to a different sync group than the
+     * given group.
+     */
+    boolean isDifferentSyncGroup(@Nullable BLASTSyncEngine.SyncGroup group) {
+        if (group == null) return false;
+        final BLASTSyncEngine.SyncGroup thisGroup = getSyncGroup();
+        if (thisGroup == null || group == thisGroup) return false;
+        Slog.d(TAG, this + " uses a different SyncGroup, current=" + thisGroup.mSyncId
+                + " given=" + group.mSyncId);
+        return true;
+    }
+
+    /**
      * Recursively finishes/cleans-up sync state of this subtree and collects all the sync
      * transactions into `outMergedTransaction`.
      * @param outMergedTransaction A transaction to merge all the recorded sync operations into.
@@ -3988,10 +3996,14 @@
      */
     void finishSync(Transaction outMergedTransaction, @Nullable BLASTSyncEngine.SyncGroup group,
             boolean cancel) {
-        if (mSyncState == SYNC_STATE_NONE) return;
-        final BLASTSyncEngine.SyncGroup syncGroup = getSyncGroup();
-        // If it's null, then we need to clean-up anyways.
-        if (syncGroup != null && group != syncGroup) return;
+        if (mSyncState == SYNC_STATE_NONE) {
+            if (mSyncGroup != null) {
+                Slog.e(TAG, "finishSync: stale group " + mSyncGroup.mSyncId + " of " + this);
+                mSyncGroup = null;
+            }
+            return;
+        }
+        if (isDifferentSyncGroup(group)) return;
         ProtoLog.v(WM_DEBUG_SYNC_ENGINE, "finishSync cancel=%b for %s", cancel, this);
         outMergedTransaction.merge(mSyncTransaction);
         for (int i = mChildren.size() - 1; i >= 0; --i) {
diff --git a/services/core/java/com/android/server/wm/WindowContainerThumbnail.java b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
index b000a98..57fc4c7 100644
--- a/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
+++ b/services/core/java/com/android/server/wm/WindowContainerThumbnail.java
@@ -39,7 +39,7 @@
 import android.view.SurfaceControl.Transaction;
 import android.view.animation.Animation;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.wm.SurfaceAnimator.Animatable;
 import com.android.server.wm.SurfaceAnimator.AnimationType;
 
diff --git a/services/core/java/com/android/server/wm/WindowContextListenerController.java b/services/core/java/com/android/server/wm/WindowContextListenerController.java
index 21f251f..cd785e5 100644
--- a/services/core/java/com/android/server/wm/WindowContextListenerController.java
+++ b/services/core/java/com/android/server/wm/WindowContextListenerController.java
@@ -39,7 +39,7 @@
 import android.window.WindowContext;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 import java.util.Objects;
 
diff --git a/services/core/java/com/android/server/wm/WindowList.java b/services/core/java/com/android/server/wm/WindowList.java
deleted file mode 100644
index 1e888f5..0000000
--- a/services/core/java/com/android/server/wm/WindowList.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.server.wm;
-
-import java.util.ArrayList;
-
-/**
- * An {@link ArrayList} with extended functionality to be used as the children data structure in
- * {@link WindowContainer}.
- */
-class WindowList<E> extends ArrayList<E> {
-
-    public void addFirst(E e) {
-        add(0, e);
-    }
-
-    E peekLast() {
-        return size() > 0 ? get(size() - 1) : null;
-    }
-
-    E peekFirst() {
-        return size() > 0 ? get(0) : null;
-    }
-}
diff --git a/services/core/java/com/android/server/wm/WindowManagerFlags.java b/services/core/java/com/android/server/wm/WindowManagerFlags.java
index 294733e..f3e6a18 100644
--- a/services/core/java/com/android/server/wm/WindowManagerFlags.java
+++ b/services/core/java/com/android/server/wm/WindowManagerFlags.java
@@ -50,5 +50,8 @@
 
     final boolean mInsetsDecoupledConfiguration = Flags.insetsDecoupledConfiguration();
 
+    final boolean mRespectNonTopVisibleFixedOrientation =
+            Flags.respectNonTopVisibleFixedOrientation();
+
     /* End Available Flags */
 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index a42cb09..2ea1cf8 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -44,6 +44,7 @@
 import android.view.InputChannel;
 import android.view.MagnificationSpec;
 import android.view.RemoteAnimationTarget;
+import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.SurfaceControlViewHost;
 import android.view.WindowInfo;
@@ -817,6 +818,16 @@
     public abstract Context getTopFocusedDisplayUiContext();
 
     /**
+     * Sets the rotation of a non-default display.
+     *
+     * @param displayId The id of the display
+     * @param rotation The new rotation value.
+     * @param caller The requester of the rotation change, used for bookkeeping.
+     */
+    public abstract void setNonDefaultDisplayRotation(int displayId, @Surface.Rotation int rotation,
+            @NonNull String caller);
+
+    /**
      * Sets whether the relevant display content can host the relevant home activity and wallpaper.
      *
      * @param displayUniqueId The unique ID of the display. Note that the display may not yet be
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index aaa7f12..8033122 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -335,7 +335,7 @@
 import com.android.internal.policy.KeyInterceptionInfo;
 import com.android.internal.protolog.LegacyProtoLogImpl;
 import com.android.internal.protolog.ProtoLogGroup;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.FrameworkStatsLog;
@@ -732,6 +732,13 @@
     final DisplayWindowListenerController mDisplayNotificationController;
     final TaskSystemBarsListenerController mTaskSystemBarsListenerController;
 
+    /** Amount of time (in milliseconds) to delay the pointer down outside focus handling */
+    private static final int POINTER_DOWN_OUTSIDE_FOCUS_TIMEOUT_MS = 50;
+
+    /** A runnable to handle pointer down outside focus event. */
+    @Nullable
+    private Runnable mPointerDownOutsideFocusRunnable;
+
     boolean mDisplayFrozen = false;
     long mDisplayFreezeTime = 0;
     int mLastDisplayFreezeDuration = 0;
@@ -2027,7 +2034,9 @@
             // Otherwise, look at the package
             final ApplicationInfo appInfo = mPmInternal.getApplicationInfo(
                     packageName, 0 /* flags */, SYSTEM_UID, UserHandle.getUserId(callingUid));
-            if (appInfo == null || appInfo.uid != callingUid) {
+            if (appInfo == null
+                    || !mPmInternal.isSameApp(
+                            packageName, callingUid, UserHandle.getUserId(callingUid))) {
                 throw new SecurityException("Package " + packageName + " not in UID "
                         + callingUid);
             }
@@ -2290,32 +2299,7 @@
             outInsetsState = null;
             outActiveControls = null;
         }
-        return relayoutWindowInner(session, client, attrs, requestedWidth, requestedHeight,
-                viewVisibility, flags, seq, lastSyncSeqId, outFrames, outMergedConfiguration,
-                outSurfaceControl, outInsetsState, outActiveControls, null /* outBundle */,
-                outRelayoutResult);
-    }
 
-    /** @deprecated */
-    @Deprecated
-    public int relayoutWindow(Session session, IWindow client, LayoutParams attrs,
-            int requestedWidth, int requestedHeight, int viewVisibility, int flags, int seq,
-            int lastSyncSeqId, ClientWindowFrames outFrames,
-            MergedConfiguration outMergedConfiguration, SurfaceControl outSurfaceControl,
-            InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls,
-            Bundle outBundle) {
-        return relayoutWindowInner(session, client, attrs, requestedWidth, requestedHeight,
-                viewVisibility, flags, seq, lastSyncSeqId, outFrames, outMergedConfiguration,
-                outSurfaceControl, outInsetsState, outActiveControls, outBundle,
-                null /* outRelayoutResult */);
-    }
-
-    private int relayoutWindowInner(Session session, IWindow client, LayoutParams attrs,
-            int requestedWidth, int requestedHeight, int viewVisibility, int flags, int seq,
-            int lastSyncSeqId, ClientWindowFrames outFrames,
-            MergedConfiguration outMergedConfiguration, SurfaceControl outSurfaceControl,
-            InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls,
-            Bundle outBundle, WindowRelayoutResult outRelayoutResult) {
         if (outActiveControls != null) {
             outActiveControls.set(null, false /* copyControls */);
         }
@@ -2647,14 +2631,8 @@
             }
 
             if (outFrames != null && outMergedConfiguration != null) {
-                final boolean shouldReportActivityWindowInfo;
-                if (Flags.windowSessionRelayoutInfo()) {
-                    shouldReportActivityWindowInfo = outRelayoutResult != null
+                final boolean shouldReportActivityWindowInfo = outRelayoutResult != null
                             && win.mLastReportedActivityWindowInfo != null;
-                } else {
-                    shouldReportActivityWindowInfo = outBundle != null
-                            && win.mLastReportedActivityWindowInfo != null;
-                }
                 final ActivityWindowInfo outActivityWindowInfo = shouldReportActivityWindowInfo
                         ? new ActivityWindowInfo()
                         : null;
@@ -2663,13 +2641,7 @@
                         outActivityWindowInfo, false /* useLatestConfig */, shouldRelayout);
 
                 if (shouldReportActivityWindowInfo) {
-                    if (Flags.windowSessionRelayoutInfo()) {
-                        outRelayoutResult.activityWindowInfo = outActivityWindowInfo;
-                    } else {
-                        outBundle.putParcelable(
-                                IWindowSession.KEY_RELAYOUT_BUNDLE_ACTIVITY_WINDOW_INFO,
-                                outActivityWindowInfo);
-                    }
+                    outRelayoutResult.activityWindowInfo = outActivityWindowInfo;
                 }
 
                 // Set resize-handled here because the values are sent back to the client.
@@ -2700,28 +2672,16 @@
                         win.isVisible() /* visible */, false /* removed */);
             }
 
-            if (Flags.windowSessionRelayoutInfo()) {
-                if (outRelayoutResult != null) {
-                    if (win.syncNextBuffer() && viewVisibility == View.VISIBLE
-                            && win.mSyncSeqId > lastSyncSeqId) {
-                        outRelayoutResult.syncSeqId = win.shouldSyncWithBuffers()
-                                ? win.mSyncSeqId
-                                : -1;
-                        win.markRedrawForSyncReported();
-                    } else {
-                        outRelayoutResult.syncSeqId = -1;
-                    }
-                }
-            } else if (outBundle != null) {
-                final int maybeSyncSeqId;
+            if (outRelayoutResult != null) {
                 if (win.syncNextBuffer() && viewVisibility == View.VISIBLE
                         && win.mSyncSeqId > lastSyncSeqId) {
-                    maybeSyncSeqId = win.shouldSyncWithBuffers() ? win.mSyncSeqId : -1;
+                    outRelayoutResult.syncSeqId = win.shouldSyncWithBuffers()
+                            ? win.mSyncSeqId
+                            : -1;
                     win.markRedrawForSyncReported();
                 } else {
-                    maybeSyncSeqId = -1;
+                    outRelayoutResult.syncSeqId = -1;
                 }
-                outBundle.putInt(IWindowSession.KEY_RELAYOUT_BUNDLE_SEQID, maybeSyncSeqId);
             }
 
             if (configChanged) {
@@ -3790,6 +3750,8 @@
                         null /* trigger */, null /* remote */, null /* disp */);
             }
             mCurrentUserId = newUserId;
+            mDisplayWindowSettingsProvider.setOverrideSettingsForUser(newUserId);
+            mDisplayWindowSettingsProvider.removeStaleDisplaySettings(mRoot);
             mPolicy.setCurrentUserLw(newUserId);
             mKeyguardDisableHandler.setCurrentUser(newUserId);
 
@@ -5526,6 +5488,9 @@
             // DisplayWindowSettings are applied. In addition, wide-color/hdr/isTouchDevice also
             // affect the Configuration.
             mRoot.forAllDisplays(DisplayContent::reconfigureDisplayLocked);
+            // Per-user display settings may leave outdated settings after user switches, especially
+            // during reboots starting with the default user without setCurrentUser called.
+            mDisplayWindowSettingsProvider.removeStaleDisplaySettings(mRoot);
         }
     }
 
@@ -5938,7 +5903,8 @@
                 case ON_POINTER_DOWN_OUTSIDE_FOCUS: {
                     synchronized (mGlobalLock) {
                         final IBinder touchedToken = (IBinder) msg.obj;
-                        onPointerDownOutsideFocusLocked(getInputTargetFromToken(touchedToken));
+                        onPointerDownOutsideFocusLocked(getInputTargetFromToken(touchedToken),
+                                true /* fromHandler */);
                     }
                     break;
                 }
@@ -7964,7 +7930,8 @@
             synchronized (mGlobalLock) {
                 final InputTarget inputTarget =
                         WindowManagerService.this.getInputTargetFromWindowTokenLocked(windowToken);
-                WindowManagerService.this.onPointerDownOutsideFocusLocked(inputTarget);
+                WindowManagerService.this.onPointerDownOutsideFocusLocked(inputTarget,
+                        false /* fromHandler */);
             }
         }
 
@@ -8404,6 +8371,26 @@
         }
 
         @Override
+        public void setNonDefaultDisplayRotation(int displayId, @Surface.Rotation int rotation,
+                @NonNull String caller) {
+            if (displayId == Display.DEFAULT_DISPLAY || displayId == Display.INVALID_DISPLAY) {
+                Slog.w(TAG, "Cannot set rotation for display with id: " + displayId);
+                return;
+            }
+            synchronized (mGlobalLock) {
+                final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+                if (displayContent == null) {
+                    Slog.w(TAG, "Cannot set rotation for display " + displayId
+                            + " due to missing DisplayContent");
+                    return;
+                }
+                displayContent.getDisplayRotation().setUserRotation(
+                        displayContent.getDisplayRotation().getUserRotationMode(), rotation,
+                        caller);
+            }
+        }
+
+        @Override
         public void setHomeSupportedOnDisplay(String displayUniqueId, int displayType,
                 boolean supported) {
             final long origId = Binder.clearCallingIdentity();
@@ -9019,39 +9006,78 @@
         }
     }
 
-    private void onPointerDownOutsideFocusLocked(InputTarget t) {
+    void clearPointerDownOutsideFocusRunnable() {
+        if (mPointerDownOutsideFocusRunnable == null) return;
+
+        mH.removeCallbacks(mPointerDownOutsideFocusRunnable);
+        mPointerDownOutsideFocusRunnable = null;
+    }
+
+    private void onPointerDownOutsideFocusLocked(InputTarget t, boolean fromHandler) {
         if (t == null || !t.receiveFocusFromTapOutside()) {
             // If the window that received the input event cannot receive keys, don't move the
             // display it's on to the top since that window won't be able to get focus anyway.
             return;
         }
-        if (mRecentsAnimationController != null
-            && mRecentsAnimationController.getTargetAppMainWindow() == t) {
-            // If there is an active recents animation and touched window is the target, then ignore
-            // the touch. The target already handles touches using its own input monitor and we
-            // don't want to trigger any lifecycle changes from focusing another window.
-            // TODO(b/186770026): We should remove this once we support multiple resumed activities
-            //                    while in overview
-            return;
-        }
+        clearPointerDownOutsideFocusRunnable();
+
+        // For embedded activity that is showing side-by-side with another activity, delay
+        // handling the touch-outside event to prevent focus rapid changes back-n-forth.
+        // Otherwise, handle the touch-outside event directly.
         final WindowState w = t.getWindowState();
-        if (w != null) {
-            final Task task = w.getTask();
-            if (task != null && w.mTransitionController.isTransientHide(task)) {
-                // Don't disturb transient animation by accident touch.
+        final ActivityRecord activity = w != null ? w.getActivityRecord() : null;
+        if (activity != null && activity.isEmbedded()
+                && activity.getTaskFragment().getAdjacentTaskFragment() != null) {
+            mPointerDownOutsideFocusRunnable = () -> handlePointerDownOutsideFocus(t);
+            mH.postDelayed(mPointerDownOutsideFocusRunnable, POINTER_DOWN_OUTSIDE_FOCUS_TIMEOUT_MS);
+        } else if (!fromHandler) {
+            // Still post the runnable to handler thread in case there is already a runnable
+            // in execution, but still waiting to hold the wm lock.
+            mPointerDownOutsideFocusRunnable = () -> handlePointerDownOutsideFocus(t);
+            mH.post(mPointerDownOutsideFocusRunnable);
+        } else {
+            handlePointerDownOutsideFocus(t);
+        }
+    }
+
+    private void handlePointerDownOutsideFocus(InputTarget t) {
+        synchronized (mGlobalLock) {
+            if (mPointerDownOutsideFocusRunnable != null
+                    && mH.hasCallbacks(mPointerDownOutsideFocusRunnable)) {
+                // Skip if there's another pending pointer-down-outside-focus event.
                 return;
             }
-        }
+            clearPointerDownOutsideFocusRunnable();
 
-        ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "onPointerDownOutsideFocusLocked called on %s",
-                t);
-        if (mFocusedInputTarget != t && mFocusedInputTarget != null) {
-            mFocusedInputTarget.handleTapOutsideFocusOutsideSelf();
+            if (mRecentsAnimationController != null
+                    && mRecentsAnimationController.getTargetAppMainWindow() == t) {
+                // If there is an active recents animation and touched window is the target,
+                // then ignore the touch. The target already handles touches using its own
+                // input monitor and we don't want to trigger any lifecycle changes from
+                // focusing another window.
+                // TODO(b/186770026): We should remove this once we support multiple resumed
+                //  activities while in overview
+                return;
+            }
+
+            final WindowState w = t.getWindowState();
+            if (w != null) {
+                final Task task = w.getTask();
+                if (task != null && w.mTransitionController.isTransientHide(task)) {
+                    // Don't disturb transient animation by accident touch.
+                    return;
+                }
+            }
+
+            ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "onPointerDownOutsideFocusLocked called on %s", t);
+            if (mFocusedInputTarget != t && mFocusedInputTarget != null) {
+                mFocusedInputTarget.handleTapOutsideFocusOutsideSelf();
+            }
+            // Trigger Activity#onUserLeaveHint() if the order change of task pauses any activities.
+            mAtmService.mTaskSupervisor.mUserLeaving = true;
+            t.handleTapOutsideFocusInsideSelf();
+            mAtmService.mTaskSupervisor.mUserLeaving = false;
         }
-        // Trigger Activity#onUserLeaveHint() if the order change of task pauses any activities.
-        mAtmService.mTaskSupervisor.mUserLeaving = true;
-        t.handleTapOutsideFocusInsideSelf();
-        mAtmService.mTaskSupervisor.mUserLeaving = false;
     }
 
     @VisibleForTesting
@@ -9273,7 +9299,8 @@
                 isTrustedOverlay);
 
         final int sanitizedLpFlags =
-                (flags & (FLAG_NOT_TOUCHABLE | FLAG_SLIPPERY | LayoutParams.FLAG_NOT_FOCUSABLE))
+                (flags & (FLAG_NOT_TOUCHABLE | FLAG_SLIPPERY | LayoutParams.FLAG_NOT_FOCUSABLE
+                    | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH))
                 | LayoutParams.FLAG_NOT_TOUCH_MODAL;
         h.layoutParamsType = type;
         h.layoutParamsFlags = sanitizedLpFlags;
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 1f06bfa..6febe80 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -51,7 +51,7 @@
 import com.android.internal.protolog.LegacyProtoLogImpl;
 import com.android.internal.protolog.PerfettoProtoLogImpl;
 import com.android.internal.protolog.common.IProtoLog;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.IoThread;
 import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType;
 import com.android.server.wm.LetterboxConfiguration.LetterboxHorizontalReachabilityPosition;
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 72109d34..bc32b91 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -62,6 +62,7 @@
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_RESTORE_TRANSIENT_ORDER;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ALWAYS_ON_TOP;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_IS_TRIMMABLE;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_REPARENT_LEAF_TASK_IF_RELAUNCH;
@@ -123,8 +124,8 @@
 import android.window.WindowContainerTransaction;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.protolog.ProtoLogGroup;
-import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.util.ArrayUtils;
 import com.android.server.LocalServices;
 import com.android.server.pm.LauncherAppsService.LauncherAppsServiceInternal;
@@ -609,11 +610,19 @@
         int effects = TRANSACT_EFFECTS_NONE;
         ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Apply window transaction, syncId=%d", syncId);
         mService.deferWindowLayout();
+        mService.mTaskSupervisor.beginDeferResume();
+        boolean deferResume = true;
         mService.mTaskSupervisor.setDeferRootVisibilityUpdate(true /* deferUpdate */);
-        final boolean shouldDeferTransitionReady = transition != null && !t.isEmpty()
-                && (transition.isCollecting() || Flags.alwaysDeferTransitionWhenApplyWct());
-        if (shouldDeferTransitionReady) {
-            transition.deferTransitionReady();
+        boolean deferTransitionReady = false;
+        if (transition != null && !t.isEmpty()) {
+            if (transition.isCollecting()) {
+                deferTransitionReady = true;
+                transition.deferTransitionReady();
+            } else {
+                Slog.w(TAG, "Transition is not collecting when applyTransaction."
+                        + " transition=" + transition + " state=" + transition.getState());
+                transition = null;
+            }
         }
         try {
             final ArraySet<WindowContainer<?>> haveConfigChanges = new ArraySet<>();
@@ -750,6 +759,8 @@
             }
             if ((effects & TRANSACT_EFFECTS_LIFECYCLE) != 0) {
                 mService.mTaskSupervisor.setDeferRootVisibilityUpdate(false /* deferUpdate */);
+                mService.mTaskSupervisor.endDeferResume();
+                deferResume = false;
                 // Already calls ensureActivityConfig
                 mService.mRootWindowContainer.ensureActivitiesVisible();
                 mService.mRootWindowContainer.resumeFocusedTasksTopActivities();
@@ -767,10 +778,13 @@
                 mService.mWindowManager.mWindowPlacerLocked.requestTraversal();
             }
         } finally {
-            if (shouldDeferTransitionReady) {
+            if (deferTransitionReady) {
                 transition.continueTransitionReady();
             }
             mService.mTaskSupervisor.setDeferRootVisibilityUpdate(false /* deferUpdate */);
+            if (deferResume) {
+                mService.mTaskSupervisor.endDeferResume();
+            }
             mService.continueWindowLayout();
         }
         return effects;
@@ -865,15 +879,20 @@
 
         final int childWindowingMode = c.getActivityWindowingMode();
         if (!ActivityTaskManagerService.isPip2ExperimentEnabled()
-                && tr.getWindowingMode() == WINDOWING_MODE_PINNED
-                && (childWindowingMode == WINDOWING_MODE_PINNED
-                || childWindowingMode == WINDOWING_MODE_UNDEFINED)) {
-            // If setActivityWindowingMode requested to match its pinned task's windowing mode,
-            // remove any inconsistency checking timeout callbacks for PiP.
-            Slog.d(TAG, "Task and activity windowing modes match, so remove any timeout "
-                    + "abort PiP callbacks scheduled if needed; task_win_mode="
-                    + tr.getWindowingMode() + ", activity_win_mode=" + childWindowingMode);
-            mService.mRootWindowContainer.removeAllMaybeAbortPipEnterRunnable();
+                && tr.getWindowingMode() == WINDOWING_MODE_PINNED) {
+            if (childWindowingMode == WINDOWING_MODE_PINNED
+                    || childWindowingMode == WINDOWING_MODE_UNDEFINED) {
+                // If setActivityWindowingMode requested to match its pinned task's windowing mode,
+                // remove any inconsistency checking timeout callbacks for PiP.
+                Slog.d(TAG, "Task and activity windowing modes match, so remove any timeout "
+                        + "abort PiP callbacks scheduled if needed; task_win_mode="
+                        + tr.getWindowingMode() + ", activity_win_mode=" + childWindowingMode);
+                mService.mRootWindowContainer.removeAllMaybeAbortPipEnterRunnable();
+            } else if (shouldApplyLifecycleEffectOnPipChange()) {
+                // This is leaving PiP: task is pinned mode and activity changes to non-pip mode.
+                // Then the activity can be resumed because it becomes focusable.
+                effects |= TRANSACT_EFFECTS_LIFECYCLE;
+            }
         }
         if (childWindowingMode > -1) {
             tr.forAllActivities(a -> { a.setWindowingMode(childWindowingMode); });
@@ -898,6 +917,9 @@
                 if (canEnterPip) {
                     canEnterPip = mService.mActivityClientController
                             .requestPictureInPictureMode(activity);
+                    if (canEnterPip && shouldApplyLifecycleEffectOnPipChange()) {
+                        effects |= TRANSACT_EFFECTS_LIFECYCLE;
+                    }
                 }
                 if (!canEnterPip) {
                     // Restore the flag to its previous state when the activity cannot enter PIP.
@@ -909,6 +931,14 @@
         return effects;
     }
 
+    // TODO(b/333452456): For testing on local easier. Remove after the use case is gone.
+    @VisibleForTesting
+    static boolean shouldApplyLifecycleEffectOnPipChange() {
+        return android.os.SystemProperties.getBoolean(
+                "persist.wm.debug.apply_lifecycle_on_pip_change", false)
+                || com.android.window.flags.Flags.applyLifecycleOnPipChange();
+    }
+
     private int applyDisplayAreaChanges(DisplayArea displayArea,
             WindowContainerTransaction.Change c) {
         final int[] effects = new int[1];
@@ -1092,6 +1122,7 @@
                     break;
                 }
                 if (activity.isVisible() || activity.isVisibleRequested()) {
+                    effects |= TRANSACT_EFFECTS_LIFECYCLE;
                     // Prevent the transition from being executed too early if the activity is
                     // visible.
                     activity.finishIfPossible("finish-activity-op", false /* oomAdj */);
@@ -1109,6 +1140,7 @@
                 launchOpts.remove(WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_TASK_ID);
                 final SafeActivityOptions safeOptions =
                         SafeActivityOptions.fromBundle(launchOpts, caller.mPid, caller.mUid);
+                effects |= TRANSACT_EFFECTS_LIFECYCLE;
                 waitAsyncStart(() -> mService.mTaskSupervisor.startActivityFromRecents(
                         caller.mPid, caller.mUid, taskId, safeOptions));
                 break;
@@ -1340,6 +1372,17 @@
                 task.setReparentLeafTaskIfRelaunch(hop.isReparentLeafTaskIfRelaunch());
                 break;
             }
+            case HIERARCHY_OP_TYPE_SET_IS_TRIMMABLE: {
+                final WindowContainer container = WindowContainer.fromBinder(hop.getContainer());
+                final Task task = container != null ? container.asTask() : null;
+                if (task == null || !task.isAttached()) {
+                    Slog.e(TAG, "Attempt to operate on unknown or detached container: "
+                            + container);
+                    break;
+                }
+                task.setTrimmableFromRecents(hop.isTrimmableFromRecents());
+                break;
+            }
         }
         return effects;
     }
@@ -1565,7 +1608,7 @@
             case OP_TYPE_REORDER_TO_BOTTOM_OF_TASK: {
                 final Task task = taskFragment.getTask();
                 if (task != null) {
-                    if (task.mChildren.peekFirst() != taskFragment) {
+                    if (task.getBottomChild() != taskFragment) {
                         task.mChildren.remove(taskFragment);
                         task.mChildren.add(0, taskFragment);
                         if (!taskFragment.hasChild()) {
@@ -1581,7 +1624,7 @@
             case OP_TYPE_REORDER_TO_TOP_OF_TASK: {
                 final Task task = taskFragment.getTask();
                 if (task != null) {
-                    if (task.mChildren.peekLast() != taskFragment) {
+                    if (task.getTopChild() != taskFragment) {
                         task.mChildren.remove(taskFragment);
                         task.mChildren.add(taskFragment);
                         if (!taskFragment.hasChild()) {
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 1c00fbb..60d3e78 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -19,6 +19,7 @@
 import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.content.res.Configuration.ASSETS_SEQ_UNDEFINED;
 import static android.os.Build.VERSION_CODES.Q;
 import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
@@ -81,7 +82,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.HeavyWeightSwitcherActivity;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.Watchdog;
 import com.android.server.grammaticalinflection.GrammaticalInflectionManagerInternal;
@@ -309,14 +310,15 @@
     private volatile boolean mWasStoppedLogged;
 
     // The bits used for mActivityStateFlags.
-    private static final int ACTIVITY_STATE_FLAG_IS_VISIBLE = 1 << 16;
-    private static final int ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED = 1 << 17;
-    private static final int ACTIVITY_STATE_FLAG_IS_STOPPING = 1 << 18;
-    private static final int ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING = 1 << 19;
-    private static final int ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE = 1 << 20;
-    private static final int ACTIVITY_STATE_FLAG_HAS_RESUMED = 1 << 21;
-    private static final int ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK = 1 << 22;
-    private static final int ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER = 0x0000ffff;
+    public static final int ACTIVITY_STATE_FLAG_IS_VISIBLE = 1 << 16;
+    public static final int ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED = 1 << 17;
+    public static final int ACTIVITY_STATE_FLAG_IS_STOPPING = 1 << 18;
+    public static final int ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING = 1 << 19;
+    public static final int ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE = 1 << 20;
+    public static final int ACTIVITY_STATE_FLAG_HAS_RESUMED = 1 << 21;
+    public static final int ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK = 1 << 22;
+    public static final int ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN = 1 << 23;
+    public static final int ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER = 0x0000ffff;
 
     /**
      * The state for oom-adjustment calculation. The higher 16 bits are the activity states, and the
@@ -1211,31 +1213,13 @@
         }
     }
 
-    public interface ComputeOomAdjCallback {
-        void onVisibleActivity();
-        void onPausedActivity();
-        void onStoppingActivity(boolean finishing);
-        void onOtherActivity();
-    }
-
     /**
-     * Returns the minimum task layer rank. It should only be called if {@link #hasActivities}
-     * returns {@code true}.
+     * Returns the current ACTIVITY_STATE_FLAG_* of this process. It should only be called if
+     * {@link #hasActivities} returns {@code true}.
      */
     @HotPath(caller = HotPath.OOM_ADJUSTMENT)
-    public int computeOomAdjFromActivities(ComputeOomAdjCallback callback) {
-        final int flags = mActivityStateFlags;
-        if ((flags & ACTIVITY_STATE_FLAG_IS_VISIBLE) != 0) {
-            callback.onVisibleActivity();
-        } else if ((flags & ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED) != 0) {
-            callback.onPausedActivity();
-        } else if ((flags & ACTIVITY_STATE_FLAG_IS_STOPPING) != 0) {
-            callback.onStoppingActivity(
-                    (flags & ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING) != 0);
-        } else {
-            callback.onOtherActivity();
-        }
-        return flags & ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER;
+    public int getActivityStateFlags() {
+        return mActivityStateFlags;
     }
 
     void computeProcessActivityState() {
@@ -1256,14 +1240,25 @@
                 stateFlags |= ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE;
             }
             final Task task = r.getTask();
-            if (task != null && task.mLayerRank != Task.LAYER_RANK_INVISIBLE) {
+            if (task == null) {
+                Slog.e(TAG, "Unexpected detached " + r + " in " + this);
+                continue;
+            }
+            if (task.mLayerRank != Task.LAYER_RANK_INVISIBLE) {
                 stateFlags |= ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK;
             }
             if (r.isVisibleRequested()) {
                 if (r.isState(RESUMED)) {
                     stateFlags |= ACTIVITY_STATE_FLAG_HAS_RESUMED;
+                    final int windowingMode = r.getWindowingMode();
+                    if (windowingMode == WINDOWING_MODE_MULTI_WINDOW
+                            && com.android.window.flags.Flags
+                                    .processPriorityPolicyForMultiWindowMode()
+                            && task.getAdjacentTask() != null) {
+                        stateFlags |= ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN;
+                    }
                 }
-                if (task != null && minTaskLayer > 0) {
+                if (minTaskLayer > 0) {
                     final int layer = task.mLayerRank;
                     if (layer >= 0 && minTaskLayer > layer) {
                         minTaskLayer = layer;
@@ -2107,6 +2102,9 @@
                 pw.print("V|");
                 if ((stateFlags & ACTIVITY_STATE_FLAG_HAS_RESUMED) != 0) {
                     pw.print("R|");
+                    if ((stateFlags & ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN) != 0) {
+                        pw.print("RS|");
+                    }
                 }
             } else if ((stateFlags & ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED) != 0) {
                 pw.print("P|");
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index dcd4bd6..de73e6c 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -28,6 +28,7 @@
 import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
 import static android.os.PowerManager.DRAW_WAKE_LOCK;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.util.SequenceUtils.getNextSeq;
 import static android.view.SurfaceControl.Transaction;
 import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;
 import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
@@ -248,8 +249,8 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.policy.KeyInterceptionInfo;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.protolog.common.LogLevel;
-import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.internal.util.ToBooleanFunction;
 import com.android.server.policy.WindowManagerPolicy;
@@ -1975,8 +1976,8 @@
      */
     boolean isReadyForDisplay() {
         final boolean parentAndClientVisible = !isParentWindowHidden()
-                && mViewVisibility == View.VISIBLE && mToken.isVisible();
-        return mHasSurface && isVisibleByPolicy() && !mDestroying
+                && mViewVisibility == View.VISIBLE;
+        return mHasSurface && isVisibleByPolicy() && !mDestroying && mToken.isVisible()
                 && (parentAndClientVisible || isAnimating(TRANSITION | PARENTS));
     }
 
@@ -3652,6 +3653,7 @@
             }
         }
         outFrames.compatScale = getCompatScaleForClient();
+        outFrames.seq = getNextSeq(mLastReportedFrames.seq);
         if (mLastReportedFrames != outFrames) {
             mLastReportedFrames.setTo(outFrames);
         }
@@ -3682,7 +3684,9 @@
     }
 
     void fillInsetsState(@NonNull InsetsState outInsetsState, boolean copySources) {
+        final int lastSeq = mLastReportedInsetsState.getSeq();
         outInsetsState.set(getCompatInsetsState(), copySources);
+        outInsetsState.setSeq(getNextSeq(lastSeq));
         if (outInsetsState != mLastReportedInsetsState) {
             // No need to copy for the recorded.
             mLastReportedInsetsState.set(outInsetsState, false /* copySources */);
@@ -3691,9 +3695,11 @@
 
     void fillInsetsSourceControls(@NonNull InsetsSourceControl.Array outArray,
             boolean copyControls) {
+        final int lastSeq = mLastReportedActiveControls.getSeq();
         final InsetsSourceControl[] controls =
                 getDisplayContent().getInsetsStateController().getControlsForDispatch(this);
         outArray.set(controls, copyControls);
+        outArray.setSeq(getNextSeq(lastSeq));
         if (outArray != mLastReportedActiveControls) {
             // No need to copy for the recorded.
             mLastReportedActiveControls.setTo(outArray, false /* copyControls */);
@@ -3754,31 +3760,13 @@
         final boolean isDragResizing = isDragResizing();
 
         markRedrawForSyncReported();
-
-        if (Flags.bundleClientTransactionFlag()) {
-            getProcess().scheduleClientTransactionItem(
-                    WindowStateResizeItem.obtain(mClient, mLastReportedFrames, reportDraw,
-                            mLastReportedConfiguration, mLastReportedInsetsState, forceRelayout,
-                            alwaysConsumeSystemBars, displayId,
-                            syncWithBuffers ? mSyncSeqId : -1, isDragResizing,
-                            mLastReportedActivityWindowInfo));
-            onResizePostDispatched(drawPending, prevRotation, displayId);
-        } else {
-            // TODO(b/301870955): cleanup after launch
-            try {
-                mClient.resized(mLastReportedFrames, reportDraw, mLastReportedConfiguration,
-                        mLastReportedInsetsState, forceRelayout, alwaysConsumeSystemBars, displayId,
+        getProcess().scheduleClientTransactionItem(
+                WindowStateResizeItem.obtain(mClient, mLastReportedFrames, reportDraw,
+                        mLastReportedConfiguration, mLastReportedInsetsState, forceRelayout,
+                        alwaysConsumeSystemBars, displayId,
                         syncWithBuffers ? mSyncSeqId : -1, isDragResizing,
-                        mLastReportedActivityWindowInfo);
-                onResizePostDispatched(drawPending, prevRotation, displayId);
-            } catch (RemoteException e) {
-                // Cancel orientation change of this window to avoid blocking unfreeze display.
-                setOrientationChanging(false);
-                mLastFreezeDuration = (int) (SystemClock.elapsedRealtime()
-                        - mWmService.mDisplayFreezeTime);
-                Slog.w(TAG, "Failed to report 'resized' to " + this + " due to " + e);
-            }
-        }
+                        mLastReportedActivityWindowInfo));
+        onResizePostDispatched(drawPending, prevRotation, displayId);
         Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
     }
 
@@ -5008,12 +4996,8 @@
         anim.restrictDuration(MAX_ANIMATION_DURATION);
         anim.scaleCurrentDuration(mWmService.getWindowAnimationScaleLocked());
         final Point position = new Point();
-        if (com.android.window.flags.Flags.removePrepareSurfaceInPlacement()) {
-            transformFrameToSurfacePosition(mWindowFrames.mFrame.left, mWindowFrames.mFrame.top,
-                    position);
-        } else {
-            position.set(mSurfacePosition);
-        }
+        transformFrameToSurfacePosition(mWindowFrames.mFrame.left, mWindowFrames.mFrame.top,
+                position);
         final AnimationAdapter adapter = new LocalAnimationAdapter(
                 new WindowAnimationSpec(anim, position, false /* canSkipFirstFrame */,
                         0 /* windowCornerRadius */),
@@ -5791,8 +5775,7 @@
     @Override
     void finishSync(Transaction outMergedTransaction, BLASTSyncEngine.SyncGroup group,
             boolean cancel) {
-        final BLASTSyncEngine.SyncGroup syncGroup = getSyncGroup();
-        if (syncGroup != null && group != syncGroup) return;
+        if (isDifferentSyncGroup(group)) return;
         mPrepareSyncSeqId = 0;
         if (cancel) {
             // This is leaving sync so any buffers left in the sync have a chance of
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 6fd7aa0..397a6357 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -62,7 +62,8 @@
 import android.view.animation.AnimationUtils;
 
 import com.android.internal.protolog.common.LogLevel;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
+import com.android.window.flags.Flags;
 import com.android.server.policy.WindowManagerPolicy;
 
 import java.io.PrintWriter;
@@ -374,9 +375,13 @@
             ProtoLog.i(WM_SHOW_SURFACE_ALLOC, "SURFACE DESTROY: %s. %s",
                     mWin, new RuntimeException().fillInStackTrace());
             destroySurface(t);
-            // Don't hide wallpaper if we're deferring the surface destroy
-            // because of a surface change.
-            mWallpaperControllerLocked.hideWallpapers(mWin);
+            if (Flags.ensureWallpaperInTransitions()) {
+                if (mWallpaperControllerLocked.isWallpaperTarget(mWin)) {
+                    mWin.requestUpdateWallpaperIfNeeded();
+                }
+            } else {
+                mWallpaperControllerLocked.hideWallpapers(mWin);
+            }
         } catch (RuntimeException e) {
             Slog.w(TAG, "Exception thrown when destroying Window " + this
                     + " surface " + mSurfaceController + " session " + mSession + ": "
@@ -431,7 +436,9 @@
 
         if (!w.isOnScreen()) {
             hide(t, "prepareSurfaceLocked");
-            mWallpaperControllerLocked.hideWallpapers(w);
+            if (!w.mIsWallpaper || !Flags.ensureWallpaperInTransitions()) {
+                mWallpaperControllerLocked.hideWallpapers(w);
+            }
 
             // If we are waiting for this window to handle an orientation change. If this window is
             // really hidden (gone for layout), there is no point in still waiting for it.
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 4456a94..d9766e0 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -36,7 +36,7 @@
 import android.view.SurfaceControl;
 import android.view.WindowContentFrameStats;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 
 import java.io.PrintWriter;
 
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 4dca23b..11ef2cd 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -47,7 +47,7 @@
 import android.view.WindowManager.LayoutParams.WindowType;
 import android.window.WindowContext;
 
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.server.policy.WindowManagerPolicy;
 
 import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/wm/WindowTracing.java b/services/core/java/com/android/server/wm/WindowTracing.java
index b0e71bd..ba5323e 100644
--- a/services/core/java/com/android/server/wm/WindowTracing.java
+++ b/services/core/java/com/android/server/wm/WindowTracing.java
@@ -37,7 +37,7 @@
 
 import com.android.internal.protolog.LegacyProtoLogImpl;
 import com.android.internal.protolog.common.IProtoLog;
-import com.android.internal.protolog.common.ProtoLog;
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.util.TraceBuffer;
 
 import java.io.File;
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 7a710dc..3cd5f76 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -193,7 +193,7 @@
         "android.hardware.thermal-V2-ndk",
         "android.hardware.tv.input@1.0",
         "android.hardware.tv.input-V2-ndk",
-        "android.hardware.vibrator-V2-cpp",
+        "android.hardware.vibrator-V2-ndk",
         "android.hardware.vibrator@1.0",
         "android.hardware.vibrator@1.1",
         "android.hardware.vibrator@1.2",
@@ -210,6 +210,7 @@
         "android.system.suspend-V1-ndk",
         "server_configurable_flags",
         "service.incremental",
+        "android.companion.virtualdevice.flags-aconfig-cc",
     ],
 
     static_libs: [
diff --git a/services/core/jni/com_android_server_companion_virtual_InputController.cpp b/services/core/jni/com_android_server_companion_virtual_InputController.cpp
index 50d48b7..a32b0f1 100644
--- a/services/core/jni/com_android_server_companion_virtual_InputController.cpp
+++ b/services/core/jni/com_android_server_companion_virtual_InputController.cpp
@@ -19,6 +19,7 @@
 #include <android-base/unique_fd.h>
 #include <android/input.h>
 #include <android/keycodes.h>
+#include <android_companion_virtualdevice_flags.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <input/Input.h>
@@ -37,6 +38,8 @@
 
 namespace android {
 
+namespace vd_flags = android::companion::virtualdevice::flags;
+
 static constexpr jlong INVALID_PTR = 0;
 
 enum class DeviceType {
@@ -45,6 +48,7 @@
     TOUCHSCREEN,
     DPAD,
     STYLUS,
+    ROTARY_ENCODER,
 };
 
 static unique_fd invalidFd() {
@@ -87,6 +91,10 @@
             ioctl(fd, UI_SET_RELBIT, REL_Y);
             ioctl(fd, UI_SET_RELBIT, REL_WHEEL);
             ioctl(fd, UI_SET_RELBIT, REL_HWHEEL);
+            if (vd_flags::high_resolution_scroll()) {
+                ioctl(fd, UI_SET_RELBIT, REL_WHEEL_HI_RES);
+                ioctl(fd, UI_SET_RELBIT, REL_HWHEEL_HI_RES);
+            }
             break;
         case DeviceType::TOUCHSCREEN:
             ioctl(fd, UI_SET_EVBIT, EV_ABS);
@@ -114,6 +122,10 @@
             ioctl(fd, UI_SET_ABSBIT, ABS_PRESSURE);
             ioctl(fd, UI_SET_PROPBIT, INPUT_PROP_DIRECT);
             break;
+        case DeviceType::ROTARY_ENCODER:
+            ioctl(fd, UI_SET_EVBIT, EV_REL);
+            ioctl(fd, UI_SET_RELBIT, REL_WHEEL);
+            break;
         default:
             ALOGE("Invalid input device type %d", static_cast<int32_t>(deviceType));
             return invalidFd();
@@ -312,6 +324,13 @@
     return fd.ok() ? reinterpret_cast<jlong>(new VirtualStylus(std::move(fd))) : INVALID_PTR;
 }
 
+static jlong nativeOpenUinputRotaryEncoder(JNIEnv* env, jobject thiz, jstring name, jint vendorId,
+                                           jint productId, jstring phys, jint height, jint width) {
+    auto fd = openUinputJni(env, name, vendorId, productId, phys, DeviceType::ROTARY_ENCODER,
+                            /* screenHeight= */ 0, /* screenWidth= */ 0);
+    return fd.ok() ? reinterpret_cast<jlong>(new VirtualRotaryEncoder(std::move(fd))) : INVALID_PTR;
+}
+
 static void nativeCloseUinput(JNIEnv* env, jobject thiz, jlong ptr) {
     VirtualInputDevice* virtualInputDevice = reinterpret_cast<VirtualInputDevice*>(ptr);
     delete virtualInputDevice;
@@ -381,6 +400,13 @@
                                            std::chrono::nanoseconds(eventTimeNanos));
 }
 
+static bool nativeWriteRotaryEncoderScrollEvent(JNIEnv* env, jobject thiz, jlong ptr,
+                                                jfloat scrollAmount, jlong eventTimeNanos) {
+    VirtualRotaryEncoder* virtualRotaryEncoder = reinterpret_cast<VirtualRotaryEncoder*>(ptr);
+    return virtualRotaryEncoder->writeScrollEvent(scrollAmount,
+                                                  std::chrono::nanoseconds(eventTimeNanos));
+}
+
 static JNINativeMethod methods[] = {
         {"nativeOpenUinputDpad", "(Ljava/lang/String;IILjava/lang/String;)J",
          (void*)nativeOpenUinputDpad},
@@ -392,6 +418,8 @@
          (void*)nativeOpenUinputTouchscreen},
         {"nativeOpenUinputStylus", "(Ljava/lang/String;IILjava/lang/String;II)J",
          (void*)nativeOpenUinputStylus},
+        {"nativeOpenUinputRotaryEncoder", "(Ljava/lang/String;IILjava/lang/String;)J",
+         (void*)nativeOpenUinputRotaryEncoder},
         {"nativeCloseUinput", "(J)V", (void*)nativeCloseUinput},
         {"nativeWriteDpadKeyEvent", "(JIIJ)Z", (void*)nativeWriteDpadKeyEvent},
         {"nativeWriteKeyEvent", "(JIIJ)Z", (void*)nativeWriteKeyEvent},
@@ -401,6 +429,8 @@
         {"nativeWriteScrollEvent", "(JFFJ)Z", (void*)nativeWriteScrollEvent},
         {"nativeWriteStylusMotionEvent", "(JIIIIIIIJ)Z", (void*)nativeWriteStylusMotionEvent},
         {"nativeWriteStylusButtonEvent", "(JIIJ)Z", (void*)nativeWriteStylusButtonEvent},
+        {"nativeWriteRotaryEncoderScrollEvent", "(JFJ)Z",
+         (void*)nativeWriteRotaryEncoderScrollEvent},
 };
 
 int register_android_server_companion_virtual_InputController(JNIEnv* env) {
diff --git a/services/core/jni/com_android_server_vibrator_VibratorController.cpp b/services/core/jni/com_android_server_vibrator_VibratorController.cpp
index 4be21d8..2804a10 100644
--- a/services/core/jni/com_android_server_vibrator_VibratorController.cpp
+++ b/services/core/jni/com_android_server_vibrator_VibratorController.cpp
@@ -16,24 +16,21 @@
 
 #define LOG_TAG "VibratorController"
 
+#include <aidl/android/hardware/vibrator/IVibrator.h>
 #include <android/hardware/vibrator/1.3/IVibrator.h>
-#include <android/hardware/vibrator/IVibrator.h>
-
 #include <nativehelper/JNIHelp.h>
+#include <utils/Log.h>
+#include <utils/misc.h>
+#include <vibratorservice/VibratorHalController.h>
+
 #include "android_runtime/AndroidRuntime.h"
+#include "com_android_server_vibrator_VibratorManagerService.h"
 #include "core_jni_helpers.h"
 #include "jni.h"
 
-#include <utils/Log.h>
-#include <utils/misc.h>
-
-#include <vibratorservice/VibratorHalController.h>
-
-#include "com_android_server_vibrator_VibratorManagerService.h"
-
 namespace V1_0 = android::hardware::vibrator::V1_0;
 namespace V1_3 = android::hardware::vibrator::V1_3;
-namespace aidl = android::hardware::vibrator;
+namespace Aidl = aidl::android::hardware::vibrator;
 
 namespace android {
 
@@ -67,29 +64,29 @@
 } sRampClassInfo;
 
 static_assert(static_cast<uint8_t>(V1_0::EffectStrength::LIGHT) ==
-              static_cast<uint8_t>(aidl::EffectStrength::LIGHT));
+              static_cast<uint8_t>(Aidl::EffectStrength::LIGHT));
 static_assert(static_cast<uint8_t>(V1_0::EffectStrength::MEDIUM) ==
-              static_cast<uint8_t>(aidl::EffectStrength::MEDIUM));
+              static_cast<uint8_t>(Aidl::EffectStrength::MEDIUM));
 static_assert(static_cast<uint8_t>(V1_0::EffectStrength::STRONG) ==
-              static_cast<uint8_t>(aidl::EffectStrength::STRONG));
+              static_cast<uint8_t>(Aidl::EffectStrength::STRONG));
 
 static_assert(static_cast<uint8_t>(V1_3::Effect::CLICK) ==
-              static_cast<uint8_t>(aidl::Effect::CLICK));
+              static_cast<uint8_t>(Aidl::Effect::CLICK));
 static_assert(static_cast<uint8_t>(V1_3::Effect::DOUBLE_CLICK) ==
-              static_cast<uint8_t>(aidl::Effect::DOUBLE_CLICK));
-static_assert(static_cast<uint8_t>(V1_3::Effect::TICK) == static_cast<uint8_t>(aidl::Effect::TICK));
-static_assert(static_cast<uint8_t>(V1_3::Effect::THUD) == static_cast<uint8_t>(aidl::Effect::THUD));
-static_assert(static_cast<uint8_t>(V1_3::Effect::POP) == static_cast<uint8_t>(aidl::Effect::POP));
+              static_cast<uint8_t>(Aidl::Effect::DOUBLE_CLICK));
+static_assert(static_cast<uint8_t>(V1_3::Effect::TICK) == static_cast<uint8_t>(Aidl::Effect::TICK));
+static_assert(static_cast<uint8_t>(V1_3::Effect::THUD) == static_cast<uint8_t>(Aidl::Effect::THUD));
+static_assert(static_cast<uint8_t>(V1_3::Effect::POP) == static_cast<uint8_t>(Aidl::Effect::POP));
 static_assert(static_cast<uint8_t>(V1_3::Effect::HEAVY_CLICK) ==
-              static_cast<uint8_t>(aidl::Effect::HEAVY_CLICK));
+              static_cast<uint8_t>(Aidl::Effect::HEAVY_CLICK));
 static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_1) ==
-              static_cast<uint8_t>(aidl::Effect::RINGTONE_1));
+              static_cast<uint8_t>(Aidl::Effect::RINGTONE_1));
 static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_2) ==
-              static_cast<uint8_t>(aidl::Effect::RINGTONE_2));
+              static_cast<uint8_t>(Aidl::Effect::RINGTONE_2));
 static_assert(static_cast<uint8_t>(V1_3::Effect::RINGTONE_15) ==
-              static_cast<uint8_t>(aidl::Effect::RINGTONE_15));
+              static_cast<uint8_t>(Aidl::Effect::RINGTONE_15));
 static_assert(static_cast<uint8_t>(V1_3::Effect::TEXTURE_TICK) ==
-              static_cast<uint8_t>(aidl::Effect::TEXTURE_TICK));
+              static_cast<uint8_t>(Aidl::Effect::TEXTURE_TICK));
 
 static std::shared_ptr<vibrator::HalController> findVibrator(int32_t vibratorId) {
     vibrator::ManagerHalController* manager =
@@ -155,15 +152,15 @@
     std::atomic<int64_t> mCallbackId;
 };
 
-static aidl::BrakingPwle brakingPwle(aidl::Braking braking, int32_t duration) {
-    aidl::BrakingPwle pwle;
+static Aidl::BrakingPwle brakingPwle(Aidl::Braking braking, int32_t duration) {
+    Aidl::BrakingPwle pwle;
     pwle.braking = braking;
     pwle.duration = duration;
     return pwle;
 }
 
-static aidl::ActivePwle activePwleFromJavaPrimitive(JNIEnv* env, jobject ramp) {
-    aidl::ActivePwle pwle;
+static Aidl::ActivePwle activePwleFromJavaPrimitive(JNIEnv* env, jobject ramp) {
+    Aidl::ActivePwle pwle;
     pwle.startAmplitude =
             static_cast<float>(env->GetFloatField(ramp, sRampClassInfo.startAmplitude));
     pwle.endAmplitude = static_cast<float>(env->GetFloatField(ramp, sRampClassInfo.endAmplitude));
@@ -175,20 +172,20 @@
 }
 
 /* Return true if braking is not NONE and the active PWLE starts and ends with zero amplitude. */
-static bool shouldBeReplacedWithBraking(aidl::ActivePwle activePwle, aidl::Braking braking) {
-    return (braking != aidl::Braking::NONE) && (activePwle.startAmplitude == 0) &&
+static bool shouldBeReplacedWithBraking(Aidl::ActivePwle activePwle, Aidl::Braking braking) {
+    return (braking != Aidl::Braking::NONE) && (activePwle.startAmplitude == 0) &&
             (activePwle.endAmplitude == 0);
 }
 
 /* Return true if braking is not NONE and the active PWLE only ends with zero amplitude. */
-static bool shouldAddLastBraking(aidl::ActivePwle lastActivePwle, aidl::Braking braking) {
-    return (braking != aidl::Braking::NONE) && (lastActivePwle.startAmplitude > 0) &&
+static bool shouldAddLastBraking(Aidl::ActivePwle lastActivePwle, Aidl::Braking braking) {
+    return (braking != Aidl::Braking::NONE) && (lastActivePwle.startAmplitude > 0) &&
             (lastActivePwle.endAmplitude == 0);
 }
 
-static aidl::CompositeEffect effectFromJavaPrimitive(JNIEnv* env, jobject primitive) {
-    aidl::CompositeEffect effect;
-    effect.primitive = static_cast<aidl::CompositePrimitive>(
+static Aidl::CompositeEffect effectFromJavaPrimitive(JNIEnv* env, jobject primitive) {
+    Aidl::CompositeEffect effect;
+    effect.primitive = static_cast<Aidl::CompositePrimitive>(
             env->GetIntField(primitive, sPrimitiveClassInfo.id));
     effect.scale = static_cast<float>(env->GetFloatField(primitive, sPrimitiveClassInfo.scale));
     effect.delayMs = static_cast<int32_t>(env->GetIntField(primitive, sPrimitiveClassInfo.delay));
@@ -282,8 +279,8 @@
         ALOGE("vibratorPerformEffect failed because native wrapper was not initialized");
         return -1;
     }
-    aidl::Effect effectType = static_cast<aidl::Effect>(effect);
-    aidl::EffectStrength effectStrength = static_cast<aidl::EffectStrength>(strength);
+    Aidl::Effect effectType = static_cast<Aidl::Effect>(effect);
+    Aidl::EffectStrength effectStrength = static_cast<Aidl::EffectStrength>(strength);
     auto callback = wrapper->createCallback(vibrationId);
     auto performEffectFn = [effectType, effectStrength, &callback](vibrator::HalWrapper* hal) {
         return hal->performEffect(effectType, effectStrength, callback);
@@ -300,7 +297,7 @@
         return -1;
     }
     size_t size = env->GetArrayLength(composition);
-    std::vector<aidl::CompositeEffect> effects;
+    std::vector<Aidl::CompositeEffect> effects;
     for (size_t i = 0; i < size; i++) {
         jobject element = env->GetObjectArrayElement(composition, i);
         effects.push_back(effectFromJavaPrimitive(env, element));
@@ -321,13 +318,13 @@
         ALOGE("vibratorPerformPwleEffect failed because native wrapper was not initialized");
         return -1;
     }
-    aidl::Braking braking = static_cast<aidl::Braking>(brakingId);
+    Aidl::Braking braking = static_cast<Aidl::Braking>(brakingId);
     size_t size = env->GetArrayLength(waveform);
-    std::vector<aidl::PrimitivePwle> primitives;
+    std::vector<Aidl::PrimitivePwle> primitives;
     std::chrono::milliseconds totalDuration(0);
     for (size_t i = 0; i < size; i++) {
         jobject element = env->GetObjectArrayElement(waveform, i);
-        aidl::ActivePwle activePwle = activePwleFromJavaPrimitive(env, element);
+        Aidl::ActivePwle activePwle = activePwleFromJavaPrimitive(env, element);
         if ((i > 0) && shouldBeReplacedWithBraking(activePwle, braking)) {
             primitives.push_back(brakingPwle(braking, activePwle.duration));
         } else {
@@ -356,8 +353,8 @@
         return;
     }
     auto alwaysOnEnableFn = [id, effect, strength](vibrator::HalWrapper* hal) {
-        return hal->alwaysOnEnable(static_cast<int32_t>(id), static_cast<aidl::Effect>(effect),
-                                   static_cast<aidl::EffectStrength>(strength));
+        return hal->alwaysOnEnable(static_cast<int32_t>(id), static_cast<Aidl::Effect>(effect),
+                                   static_cast<Aidl::EffectStrength>(strength));
     };
     wrapper->halCall<void>(alwaysOnEnableFn, "alwaysOnEnable");
 }
@@ -389,7 +386,7 @@
                               static_cast<jlong>(info.capabilities.value()));
     }
     if (info.supportedEffects.isOk()) {
-        std::vector<aidl::Effect> effects = info.supportedEffects.value();
+        std::vector<Aidl::Effect> effects = info.supportedEffects.value();
         jintArray supportedEffects = env->NewIntArray(effects.size());
         env->SetIntArrayRegion(supportedEffects, 0, effects.size(),
                                reinterpret_cast<jint*>(effects.data()));
@@ -397,7 +394,7 @@
                               sVibratorInfoBuilderClassInfo.setSupportedEffects, supportedEffects);
     }
     if (info.supportedBraking.isOk()) {
-        std::vector<aidl::Braking> braking = info.supportedBraking.value();
+        std::vector<Aidl::Braking> braking = info.supportedBraking.value();
         jintArray supportedBraking = env->NewIntArray(braking.size());
         env->SetIntArrayRegion(supportedBraking, 0, braking.size(),
                                reinterpret_cast<jint*>(braking.data()));
diff --git a/services/core/lint-baseline.xml b/services/core/lint-baseline.xml
index 2ccd1e4..3b81f0a 100644
--- a/services/core/lint-baseline.xml
+++ b/services/core/lint-baseline.xml
@@ -145,4 +145,37 @@
             line="7158"/>
     </issue>
 
+    <issue
+        id="FlaggedApi"
+        message="Method `recordSmartReplied()` is a flagged API and should be inside an `if (Flags.lifetimeExtensionRefactor())` check (or annotate the surrounding method `onNotificationSmartReplySent` with `@FlaggedApi(Flags.FLAG_LIFETIME_EXTENSION_REFACTOR) to transfer requirement to caller`)"
+        errorLine1="                    r.recordSmartReplied();"
+        errorLine2="                    ~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java"
+            line="1591"
+            column="21"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getPackageImportanceWithIdentity()` is a flagged API and should be inside an `if (Flags.lifetimeExtensionRefactor())` check (or annotate the surrounding method `enqueueNotificationInternal` with `@FlaggedApi(Flags.FLAG_LIFETIME_EXTENSION_REFACTOR) to transfer requirement to caller`)"
+        errorLine1="        final int packageImportance = getPackageImportanceWithIdentity(pkg);"
+        errorLine2="                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java"
+            line="7546"
+            column="39"/>
+    </issue>
+
+    <issue
+        id="FlaggedApi"
+        message="Method `getPackageImportanceWithIdentity()` is a flagged API and should be inside an `if (Flags.lifetimeExtensionRefactor())` check (or annotate the surrounding method `onShortcutRemoved` with `@FlaggedApi(Flags.FLAG_LIFETIME_EXTENSION_REFACTOR) to transfer requirement to caller`)"
+        errorLine1="                    final int packageImportance = getPackageImportanceWithIdentity(packageName);"
+        errorLine2="                                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+        <location
+            file="frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java"
+            line="7916"
+            column="51"/>
+    </issue>
+
 </issues>
\ No newline at end of file
diff --git a/services/devicepolicy/Android.bp b/services/devicepolicy/Android.bp
index da965bb..32b571a 100644
--- a/services/devicepolicy/Android.bp
+++ b/services/devicepolicy/Android.bp
@@ -17,8 +17,10 @@
 java_library_static {
     name: "services.devicepolicy",
     defaults: ["platform_service_defaults"],
-    srcs: [":services.devicepolicy-sources"],
-
+    srcs: [
+        ":services.devicepolicy-sources",
+        ":statslog-devicepolicy-java-gen",
+    ],
     libs: [
         "services.core",
         "app-compat-annotations",
@@ -27,3 +29,11 @@
         "androidx.annotation_annotation",
     ],
 }
+
+genrule {
+    name: "statslog-devicepolicy-java-gen",
+    tools: ["stats-log-api-gen"],
+    cmd: "$(location stats-log-api-gen) --java $(out) --module devicepolicy" +
+        " --javaPackage com.android.server.devicepolicy --javaClass DevicePolicyStatsLog",
+    out: ["com/android/server/devicepolicy/DevicePolicyStatsLog.java"],
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index e8204e0..e122fe0 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -109,6 +109,7 @@
 import static android.app.AppOpsManager.OPSTR_SYSTEM_EXEMPT_FROM_SUSPENSION;
 import static android.app.AppOpsManager.OP_RUN_ANY_IN_BACKGROUND;
 import static android.app.AppOpsManager.OP_RUN_IN_BACKGROUND;
+import static android.app.StatsManager.PULL_SUCCESS;
 import static android.app.admin.DeviceAdminInfo.HEADLESS_DEVICE_OWNER_MODE_AFFILIATED;
 import static android.app.admin.DeviceAdminInfo.HEADLESS_DEVICE_OWNER_MODE_SINGLE_USER;
 import static android.app.admin.DeviceAdminInfo.HEADLESS_DEVICE_OWNER_MODE_UNSUPPORTED;
@@ -265,12 +266,26 @@
 import static android.security.keystore.AttestationUtils.USE_INDIVIDUAL_ATTESTATION;
 
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PROVISIONING_ENTRY_POINT_ADB;
+import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST;
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
 import static com.android.server.SystemTimeZone.TIME_ZONE_CONFIDENCE_HIGH;
 import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
 import static com.android.server.devicepolicy.DevicePolicyEngine.DEFAULT_POLICY_SIZE_LIMIT;
+import static com.android.server.devicepolicy.DevicePolicyStatsLog.DEVICE_POLICY_MANAGEMENT_MODE;
+import static com.android.server.devicepolicy.DevicePolicyStatsLog.DEVICE_POLICY_MANAGEMENT_MODE__MANAGEMENT_MODE__COPE;
+import static com.android.server.devicepolicy.DevicePolicyStatsLog.DEVICE_POLICY_MANAGEMENT_MODE__MANAGEMENT_MODE__DEVICE_OWNER;
+import static com.android.server.devicepolicy.DevicePolicyStatsLog.DEVICE_POLICY_MANAGEMENT_MODE__MANAGEMENT_MODE__DEVICE_OWNER_FINANCED;
+import static com.android.server.devicepolicy.DevicePolicyStatsLog.DEVICE_POLICY_MANAGEMENT_MODE__MANAGEMENT_MODE__MANAGEMENT_MODE_UNSPECIFIED;
+import static com.android.server.devicepolicy.DevicePolicyStatsLog.DEVICE_POLICY_MANAGEMENT_MODE__MANAGEMENT_MODE__PROFILE_OWNER;
+import static com.android.server.devicepolicy.DevicePolicyStatsLog.DEVICE_POLICY_STATE;
+import static com.android.server.devicepolicy.DevicePolicyStatsLog.DEVICE_POLICY_STATE__PASSWORD_COMPLEXITY__COMPLEXITY_HIGH;
+import static com.android.server.devicepolicy.DevicePolicyStatsLog.DEVICE_POLICY_STATE__PASSWORD_COMPLEXITY__COMPLEXITY_LEGACY;
+import static com.android.server.devicepolicy.DevicePolicyStatsLog.DEVICE_POLICY_STATE__PASSWORD_COMPLEXITY__COMPLEXITY_LOW;
+import static com.android.server.devicepolicy.DevicePolicyStatsLog.DEVICE_POLICY_STATE__PASSWORD_COMPLEXITY__COMPLEXITY_MEDIUM;
+import static com.android.server.devicepolicy.DevicePolicyStatsLog.DEVICE_POLICY_STATE__PASSWORD_COMPLEXITY__COMPLEXITY_NONE;
+import static com.android.server.devicepolicy.DevicePolicyStatsLog.DEVICE_POLICY_STATE__PASSWORD_COMPLEXITY__COMPLEXITY_UNSPECIFIED;
 import static com.android.server.devicepolicy.TransferOwnershipMetadataManager.ADMIN_TYPE_DEVICE_OWNER;
 import static com.android.server.devicepolicy.TransferOwnershipMetadataManager.ADMIN_TYPE_PROFILE_OWNER;
 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
@@ -305,6 +320,7 @@
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
+import android.app.StatsManager;
 import android.app.StatusBarManager;
 import android.app.admin.AccountTypePolicyKey;
 import android.app.admin.BooleanPolicyValue;
@@ -477,6 +493,7 @@
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.StatsEvent;
 import android.util.Xml;
 import android.view.IWindowManager;
 import android.view.accessibility.AccessibilityManager;
@@ -3348,6 +3365,9 @@
                 synchronized (getLockObject()) {
                     mDevicePolicyEngine.reapplyAllPoliciesOnBootLocked();
                 }
+                if (Flags.managementModePolicyMetrics()) {
+                    registerStatsCallbacks();
+                }
                 break;
             case SystemService.PHASE_ACTIVITY_MANAGER_READY:
                 synchronized (getLockObject()) {
@@ -3487,6 +3507,121 @@
         return true;
     }
 
+    /** Register callbacks for statsd pulled atoms. */
+    private void registerStatsCallbacks() {
+        final StatsManager statsManager = mContext.getSystemService(StatsManager.class);
+        if (statsManager == null) {
+            Slog.wtf(LOG_TAG, "StatsManager system service not found.");
+            return;
+        }
+        statsManager.setPullAtomCallback(
+                DEVICE_POLICY_MANAGEMENT_MODE,
+                null, // use defaultPullAtomMetadata values
+                DIRECT_EXECUTOR,
+                this::onPullManagementModeAtom);
+        statsManager.setPullAtomCallback(
+                DEVICE_POLICY_STATE,
+                null, // use defaultPullAtomMetadata values
+                DIRECT_EXECUTOR,
+                this::onPullPolicyStateAtom);
+    }
+
+    /** Writes the pulled atoms. */
+    private int onPullManagementModeAtom(int atomTag, List<StatsEvent> statsEvents) {
+        synchronized (getLockObject()) {
+            statsEvents.add(DevicePolicyStatsLog.buildStatsEvent(
+                    DEVICE_POLICY_MANAGEMENT_MODE,
+                    getStatsManagementModeLocked().managementMode()));
+            return PULL_SUCCESS;
+        }
+    }
+
+    /** Writes the pulled atoms. */
+    private int onPullPolicyStateAtom(int atomTag, List<StatsEvent> statsEvents) {
+        synchronized (getLockObject()) {
+            StatsManagementMode statsManagementMode = getStatsManagementModeLocked();
+            if (statsManagementMode.admin() != null) {
+                statsEvents.add(DevicePolicyStatsLog.buildStatsEvent(DEVICE_POLICY_STATE,
+                        getRequiredPasswordComplexityStatsLocked(statsManagementMode.admin()),
+                        statsManagementMode.managementMode()
+                        ));
+            } else {
+                statsEvents.add(DevicePolicyStatsLog.buildStatsEvent(DEVICE_POLICY_STATE,
+                        DEVICE_POLICY_STATE__PASSWORD_COMPLEXITY__COMPLEXITY_NONE,
+                        DEVICE_POLICY_MANAGEMENT_MODE__MANAGEMENT_MODE__MANAGEMENT_MODE_UNSPECIFIED
+                ));
+            }
+            return PULL_SUCCESS;
+        }
+    }
+
+    private StatsManagementMode getStatsManagementModeLocked() {
+        int managementMode =
+                DEVICE_POLICY_MANAGEMENT_MODE__MANAGEMENT_MODE__MANAGEMENT_MODE_UNSPECIFIED;
+        ActiveAdmin admin = getDeviceOwnerAdminLocked();
+        if (admin != null) {
+            managementMode = getDeviceOwnerTypeLocked(
+                    getDeviceOwnerComponent(false).getPackageName())
+                    != DEVICE_OWNER_TYPE_FINANCED
+                    ? DEVICE_POLICY_MANAGEMENT_MODE__MANAGEMENT_MODE__DEVICE_OWNER
+                    : DEVICE_POLICY_MANAGEMENT_MODE__MANAGEMENT_MODE__DEVICE_OWNER_FINANCED;
+        } else {
+            // Find the first user with managing_app.
+            for (Integer profileUserId : mOwners.getProfileOwnerKeys()) {
+                if (isManagedProfile(profileUserId)) {
+                    admin = getProfileOwnerAdminLocked(profileUserId);
+                    managementMode = mOwners.isProfileOwnerOfOrganizationOwnedDevice(
+                            profileUserId)
+                            ? DEVICE_POLICY_MANAGEMENT_MODE__MANAGEMENT_MODE__COPE
+                            : DEVICE_POLICY_MANAGEMENT_MODE__MANAGEMENT_MODE__PROFILE_OWNER;
+                    break;
+                }
+            }
+        }
+        return new StatsManagementMode(managementMode, admin);
+    }
+
+    private record StatsManagementMode(int managementMode, ActiveAdmin admin) {
+    }
+
+    @GuardedBy("getLockObject()")
+    private int getRequiredPasswordComplexityStatsLocked(ActiveAdmin admin) {
+        int userId = admin.getUserHandle().getIdentifier();
+        EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin(
+                admin.info.getComponent(),
+                userId,
+                admin);
+
+        Integer passwordComplexity = mDevicePolicyEngine.getLocalPolicySetByAdmin(
+                PolicyDefinition.PASSWORD_COMPLEXITY,
+                enforcingAdmin,
+                userId);
+        if (passwordComplexity == null) {
+            return admin.mPasswordPolicy.quality != PASSWORD_QUALITY_UNSPECIFIED
+                    ? DEVICE_POLICY_STATE__PASSWORD_COMPLEXITY__COMPLEXITY_LEGACY
+                    : DEVICE_POLICY_STATE__PASSWORD_COMPLEXITY__COMPLEXITY_UNSPECIFIED;
+        }
+        switch (passwordComplexity) {
+            case PASSWORD_COMPLEXITY_NONE -> {
+                return DEVICE_POLICY_STATE__PASSWORD_COMPLEXITY__COMPLEXITY_NONE;
+            }
+            case PASSWORD_COMPLEXITY_LOW -> {
+                return DEVICE_POLICY_STATE__PASSWORD_COMPLEXITY__COMPLEXITY_LOW;
+            }
+            case PASSWORD_COMPLEXITY_MEDIUM -> {
+                return DEVICE_POLICY_STATE__PASSWORD_COMPLEXITY__COMPLEXITY_MEDIUM;
+            }
+            case PASSWORD_COMPLEXITY_HIGH -> {
+                return DEVICE_POLICY_STATE__PASSWORD_COMPLEXITY__COMPLEXITY_HIGH;
+            }
+            default -> {
+                Slogf.wtf(LOG_TAG, "Unhandled password complexity: " + passwordComplexity);
+                // The following line is unreachable as Slogf.wtf crashes the process.
+                // But we need this to avoid compilation error missing return statement.
+                return DEVICE_POLICY_STATE__PASSWORD_COMPLEXITY__COMPLEXITY_UNSPECIFIED;
+            }
+        }
+    }
 
     private void applyManagedSubscriptionsPolicyIfRequired() {
         int copeProfileUserId = getOrganizationOwnedProfileUserId();
@@ -4115,6 +4250,10 @@
     private void clearOrgOwnedProfileOwnerUserRestrictions(UserHandle parentUserHandle) {
         mUserManager.setUserRestriction(
                 UserManager.DISALLOW_REMOVE_MANAGED_PROFILE, false, parentUserHandle);
+        if (mInjector.userManagerIsHeadlessSystemUserMode()) {
+            mUserManager.setUserRestriction(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,
+                    false, UserHandle.SYSTEM);
+        }
         mUserManager.setUserRestriction(
                 UserManager.DISALLOW_ADD_USER, false, parentUserHandle);
     }
@@ -17874,6 +18013,12 @@
             mUserManager.setUserRestriction(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,
                     isProfileOwnerOnOrganizationOwnedDevice,
                     parentUser);
+            if (mInjector.userManagerIsHeadlessSystemUserMode()) {
+                // For HSUM, additionally set this on user 0 to block ADB from removing the profile.
+                mUserManager.setUserRestriction(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,
+                        isProfileOwnerOnOrganizationOwnedDevice,
+                        UserHandle.SYSTEM);
+            }
             mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_USER,
                     isProfileOwnerOnOrganizationOwnedDevice,
                     parentUser);
diff --git a/services/fakes/Android.bp b/services/fakes/Android.bp
index 148054b..d44bb5a 100644
--- a/services/fakes/Android.bp
+++ b/services/fakes/Android.bp
@@ -16,5 +16,5 @@
         "java/**/*.java",
     ],
     path: "java",
-    visibility: ["//frameworks/base"],
+    visibility: ["//frameworks/base/ravenwood:__subpackages__"],
 }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index cdca948..e5a1ebf 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1924,7 +1924,11 @@
             startRotationResolverService(context, t);
             startSystemCaptionsManagerService(context, t);
             startTextToSpeechManagerService(context, t);
-            startWearableSensingService(t);
+            if (!isWatch || !android.server.Flags.removeWearableSensingServiceFromWear()) {
+                startWearableSensingService(t);
+            } else {
+                Slog.d(TAG, "Not starting WearableSensingService");
+            }
             startOnDeviceIntelligenceService(t);
 
             if (deviceHasConfigString(
@@ -2130,14 +2134,20 @@
             }
             t.traceEnd();
 
-            t.traceBegin("StartVpnManagerService");
-            try {
-                vpnManager = VpnManagerService.create(context);
-                ServiceManager.addService(Context.VPN_MANAGEMENT_SERVICE, vpnManager);
-            } catch (Throwable e) {
-                reportWtf("starting VPN Manager Service", e);
+            if (!isWatch || !android.server.Flags.allowRemovingVpnService()) {
+                t.traceBegin("StartVpnManagerService");
+                try {
+                    vpnManager = VpnManagerService.create(context);
+                    ServiceManager.addService(Context.VPN_MANAGEMENT_SERVICE, vpnManager);
+                } catch (Throwable e) {
+                    reportWtf("starting VPN Manager Service", e);
+                }
+                t.traceEnd();
+            } else {
+                // VPN management currently does not work in Wear, so skip starting the
+                // VPN manager SystemService.
+                Slog.i(TAG, "Not starting VpnManagerService");
             }
-            t.traceEnd();
 
             t.traceBegin("StartVcnManagementService");
             try {
@@ -2640,9 +2650,13 @@
             mSystemServiceManager.startService(MediaMetricsManagerService.class);
             t.traceEnd();
 
-            t.traceBegin("StartBackgroundInstallControlService");
-            mSystemServiceManager.startService(BackgroundInstallControlService.class);
-            t.traceEnd();
+            if (!com.android.server.flags.Flags.optionalBackgroundInstallControl()
+                    || SystemProperties.getBoolean(
+                            "ro.system_settings.service.backgound_install_control_enabled", true)) {
+                t.traceBegin("StartBackgroundInstallControlService");
+                mSystemServiceManager.startService(BackgroundInstallControlService.class);
+                t.traceEnd();
+            }
         }
 
         t.traceBegin("StartMediaProjectionManager");
diff --git a/services/java/com/android/server/flags.aconfig b/services/java/com/android/server/flags.aconfig
index 38354e8..29f3871 100644
--- a/services/java/com/android/server/flags.aconfig
+++ b/services/java/com/android/server/flags.aconfig
@@ -14,4 +14,18 @@
      namespace: "wear_frameworks"
      description: "Remove TextServiceManagerService on Wear"
      bug: "323720705"
+}
+
+flag {
+     name: "remove_wearable_sensing_service_from_wear"
+     namespace: "wear_frameworks"
+     description: "Remove WearableSensingManagerService on Wear"
+     bug: "340929916"
+}
+
+flag {
+     name: "allow_removing_vpn_service"
+     namespace: "wear_frameworks"
+     description: "Allow removing VpnManagerService"
+     bug: "340928692"
 }
\ No newline at end of file
diff --git a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
index bb0838d..7ed23cd 100644
--- a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
@@ -230,18 +230,7 @@
         }
         val isSoftRestricted =
             if (permission.isSoftRestricted && !isExempt) {
-                val targetSdkVersion =
-                    reducePackageInAppId(appId, Build.VERSION_CODES.CUR_DEVELOPMENT) {
-                        targetSdkVersion,
-                        packageState ->
-                        if (permissionName in packageState.androidPackage!!.requestedPermissions) {
-                            targetSdkVersion.coerceAtMost(
-                                packageState.androidPackage!!.targetSdkVersion
-                            )
-                        } else {
-                            targetSdkVersion
-                        }
-                    }
+                val targetSdkVersion = getAppIdTargetSdkVersion(appId, permissionName)
                 !anyPackageInAppId(appId) {
                     permissionName in it.androidPackage!!.requestedPermissions &&
                         isSoftRestrictedPermissionExemptForPackage(
@@ -718,18 +707,8 @@
 
         // If the app is updated, and has scoped storage permissions, then it is possible that the
         // app updated in an attempt to get unscoped storage. If so, revoke all storage permissions.
-        val oldTargetSdkVersion =
-            reducePackageInAppId(appId, Build.VERSION_CODES.CUR_DEVELOPMENT, oldState) {
-                targetSdkVersion,
-                packageState ->
-                targetSdkVersion.coerceAtMost(packageState.androidPackage!!.targetSdkVersion)
-            }
-        val newTargetSdkVersion =
-            reducePackageInAppId(appId, Build.VERSION_CODES.CUR_DEVELOPMENT, newState) {
-                targetSdkVersion,
-                packageState ->
-                targetSdkVersion.coerceAtMost(packageState.androidPackage!!.targetSdkVersion)
-            }
+        val oldTargetSdkVersion = getAppIdTargetSdkVersion(appId, null, oldState)
+        val newTargetSdkVersion = getAppIdTargetSdkVersion(appId, null, newState)
         @Suppress("ConvertTwoComparisonsToRangeCheck")
         val isTargetSdkVersionDowngraded =
             oldTargetSdkVersion >= Build.VERSION_CODES.Q &&
@@ -1115,6 +1094,7 @@
     }
 
     private fun MutateStateScope.inheritImplicitPermissionStates(appId: Int, userId: Int) {
+        val targetSdkVersion = getAppIdTargetSdkVersion(appId, null)
         val implicitPermissions = MutableIndexedSet<String>()
         forEachPackageInAppId(appId) {
             implicitPermissions += it.androidPackage!!.implicitPermissions
@@ -1153,7 +1133,10 @@
                     newFlags = newFlags or (sourceFlags and PermissionFlags.MASK_RUNTIME)
                 }
             }
-            if (implicitPermissionName in RETAIN_IMPLICIT_FLAGS_PERMISSIONS) {
+            if (
+                targetSdkVersion >= Build.VERSION_CODES.M &&
+                    implicitPermissionName in NO_IMPLICIT_FLAG_PERMISSIONS
+            ) {
                 newFlags = newFlags andInv PermissionFlags.IMPLICIT
             } else {
                 newFlags = newFlags or PermissionFlags.IMPLICIT
@@ -1413,6 +1396,22 @@
             else -> false
         }
 
+    private fun MutateStateScope.getAppIdTargetSdkVersion(
+        appId: Int,
+        permissionName: String?,
+        state: AccessState = newState
+    ): Int =
+        reducePackageInAppId(appId, Build.VERSION_CODES.CUR_DEVELOPMENT, state) {
+            targetSdkVersion,
+            packageState ->
+            val androidPackage = packageState.androidPackage!!
+            if (permissionName == null || permissionName in androidPackage.requestedPermissions) {
+                targetSdkVersion.coerceAtMost(androidPackage.targetSdkVersion)
+            } else {
+                targetSdkVersion
+            }
+        }
+
     private inline fun MutateStateScope.anyPackageInAppId(
         appId: Int,
         state: AccessState = newState,
@@ -1782,7 +1781,7 @@
         private const val PLATFORM_PACKAGE_NAME = "android"
 
         // A set of permissions that we don't want to revoke when they are no longer implicit.
-        private val RETAIN_IMPLICIT_FLAGS_PERMISSIONS =
+        private val NO_IMPLICIT_FLAG_PERMISSIONS =
             indexedSetOf(
                 Manifest.permission.ACCESS_MEDIA_LOCATION,
                 Manifest.permission.ACTIVITY_RECOGNITION,
diff --git a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
index 78dbc60..0b7438c 100644
--- a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
@@ -2687,7 +2687,7 @@
                 runtimePermissionChangedUidDevices.getOrPut(uid) { mutableSetOf() } += deviceId
             }
 
-            if (permission.hasGids && !wasPermissionGranted && isPermissionGranted) {
+            if (permission.hasGids && (wasPermissionGranted != isPermissionGranted)) {
                 gidsChangedUids += uid
             }
         }
diff --git a/services/tests/InputMethodSystemServerTests/Android.bp b/services/tests/InputMethodSystemServerTests/Android.bp
index 0da17e1..3bce9b5 100644
--- a/services/tests/InputMethodSystemServerTests/Android.bp
+++ b/services/tests/InputMethodSystemServerTests/Android.bp
@@ -84,7 +84,6 @@
     ],
     srcs: [
         "src/com/android/server/inputmethod/**/ClientControllerTest.java",
-        "src/com/android/server/inputmethod/**/UserDataRepositoryTest.java",
     ],
     auto_gen_config: true,
 }
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java
index a4ca317..9e46f2f 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java
@@ -37,6 +37,7 @@
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import static java.util.Objects.requireNonNull;
 
@@ -50,6 +51,7 @@
 
 import com.android.dx.mockito.inline.extended.ExtendedMockito;
 import com.android.internal.inputmethod.InputBindResult;
+import com.android.internal.inputmethod.SoftInputShowHideReason;
 import com.android.internal.inputmethod.StartInputFlags;
 import com.android.internal.inputmethod.StartInputReason;
 
@@ -73,9 +75,8 @@
     @Before
     public void setUp() throws RemoteException {
         super.setUp();
-        mVisibilityApplier =
-                (DefaultImeVisibilityApplier) mInputMethodManagerService.getVisibilityApplier();
         synchronized (ImfLock.class) {
+            mVisibilityApplier = mInputMethodManagerService.getVisibilityApplierLocked();
             mUserId = mInputMethodManagerService.getCurrentImeUserIdLocked();
             mInputMethodManagerService.setAttachedClientForTesting(requireNonNull(
                     mInputMethodManagerService.getClientStateLocked(mMockInputMethodClient)));
@@ -87,7 +88,7 @@
         synchronized (ImfLock.class) {
             mVisibilityApplier.performShowIme(new Binder() /* showInputToken */,
                     ImeTracker.Token.empty(), 0 /* showFlags */, null /* resultReceiver */,
-                    SHOW_SOFT_INPUT);
+                    SHOW_SOFT_INPUT, mUserId);
         }
         verifyShowSoftInput(false, true, 0 /* showFlags */);
     }
@@ -96,7 +97,7 @@
     public void testPerformHideIme() throws Exception {
         synchronized (ImfLock.class) {
             mVisibilityApplier.performHideIme(new Binder() /* hideInputToken */,
-                    ImeTracker.Token.empty(), null /* resultReceiver */, HIDE_SOFT_INPUT);
+                    ImeTracker.Token.empty(), null /* resultReceiver */, HIDE_SOFT_INPUT, mUserId);
         }
         verifyHideSoftInput(false, true);
     }
@@ -106,7 +107,7 @@
         assertThrows(IllegalArgumentException.class, () -> {
             synchronized (ImfLock.class) {
                 mVisibilityApplier.applyImeVisibility(mWindowToken, ImeTracker.Token.empty(),
-                        STATE_INVALID, mUserId);
+                        STATE_INVALID, eq(SoftInputShowHideReason.NOT_SET), mUserId);
             }
         });
     }
@@ -116,7 +117,7 @@
         final var statsToken = ImeTracker.Token.empty();
         synchronized (ImfLock.class) {
             mVisibilityApplier.applyImeVisibility(mWindowToken, statsToken, STATE_SHOW_IME,
-                    mUserId);
+                    eq(SoftInputShowHideReason.NOT_SET), mUserId);
         }
         verify(mMockWindowManagerInternal).showImePostLayout(eq(mWindowToken), eq(statsToken));
     }
@@ -126,7 +127,7 @@
         final var statsToken = ImeTracker.Token.empty();
         synchronized (ImfLock.class) {
             mVisibilityApplier.applyImeVisibility(mWindowToken, statsToken, STATE_HIDE_IME,
-                    mUserId);
+                    eq(SoftInputShowHideReason.NOT_SET), mUserId);
         }
         verify(mMockWindowManagerInternal).hideIme(eq(mWindowToken), anyInt() /* displayId */,
                 eq(statsToken));
@@ -134,20 +135,24 @@
 
     @Test
     public void testApplyImeVisibility_hideImeExplicit() throws Exception {
-        mInputMethodManagerService.mImeWindowVis = IME_ACTIVE;
         synchronized (ImfLock.class) {
+            final var bindingController =
+                    mInputMethodManagerService.getInputMethodBindingController(mUserId);
+            when(bindingController.getImeWindowVis()).thenReturn(IME_ACTIVE);
             mVisibilityApplier.applyImeVisibility(mWindowToken, ImeTracker.Token.empty(),
-                    STATE_HIDE_IME_EXPLICIT, mUserId);
+                    STATE_HIDE_IME_EXPLICIT, eq(SoftInputShowHideReason.NOT_SET), mUserId);
         }
         verifyHideSoftInput(true, true);
     }
 
     @Test
     public void testApplyImeVisibility_hideNotAlways() throws Exception {
-        mInputMethodManagerService.mImeWindowVis = IME_ACTIVE;
         synchronized (ImfLock.class) {
+            final var bindingController =
+                    mInputMethodManagerService.getInputMethodBindingController(mUserId);
+            when(bindingController.getImeWindowVis()).thenReturn(IME_ACTIVE);
             mVisibilityApplier.applyImeVisibility(mWindowToken, ImeTracker.Token.empty(),
-                    STATE_HIDE_IME_NOT_ALWAYS, mUserId);
+                    STATE_HIDE_IME_NOT_ALWAYS, eq(SoftInputShowHideReason.NOT_SET), mUserId);
         }
         verifyHideSoftInput(true, true);
     }
@@ -156,7 +161,7 @@
     public void testApplyImeVisibility_showImeImplicit() throws Exception {
         synchronized (ImfLock.class) {
             mVisibilityApplier.applyImeVisibility(mWindowToken, ImeTracker.Token.empty(),
-                    STATE_SHOW_IME_IMPLICIT, mUserId);
+                    STATE_SHOW_IME_IMPLICIT, eq(SoftInputShowHideReason.NOT_SET), mUserId);
         }
         verifyShowSoftInput(true, true, 0 /* showFlags */);
     }
@@ -177,7 +182,7 @@
             // Verify hideIme will apply the expected displayId when the default IME
             // visibility applier app STATE_HIDE_IME.
             mVisibilityApplier.applyImeVisibility(mWindowToken, statsToken, STATE_HIDE_IME,
-                    mUserId);
+                    eq(SoftInputShowHideReason.NOT_SET), mUserId);
             verify(mInputMethodManagerService.mWindowManagerInternal).hideIme(
                     eq(mWindowToken), eq(displayIdToShowIme), eq(statsToken));
         }
@@ -186,7 +191,7 @@
     @Test
     public void testShowImeScreenshot() {
         synchronized (ImfLock.class) {
-            mVisibilityApplier.showImeScreenshot(mWindowToken, Display.DEFAULT_DISPLAY);
+            mVisibilityApplier.showImeScreenshot(mWindowToken, Display.DEFAULT_DISPLAY, mUserId);
         }
 
         verify(mMockImeTargetVisibilityPolicy).showImeScreenshot(eq(mWindowToken),
@@ -196,7 +201,7 @@
     @Test
     public void testRemoveImeScreenshot() {
         synchronized (ImfLock.class) {
-            mVisibilityApplier.removeImeScreenshot(Display.DEFAULT_DISPLAY);
+            mVisibilityApplier.removeImeScreenshot(Display.DEFAULT_DISPLAY, mUserId);
         }
 
         verify(mMockImeTargetVisibilityPolicy).removeImeScreenshot(eq(Display.DEFAULT_DISPLAY));
@@ -217,14 +222,15 @@
             final int displayIdToShowIme = bindingController.getDisplayIdToShowIme();
             mInputMethodManagerService.hideCurrentInputLocked(mWindowToken,
                     statsToken, 0 /* flags */, null /* resultReceiver */,
-                    HIDE_SWITCH_USER);
-            mInputMethodManagerService.onUnbindCurrentMethodByReset();
+                    HIDE_SWITCH_USER, mUserId);
+            mInputMethodManagerService.onUnbindCurrentMethodByReset(mUserId);
 
             // Expects applyImeVisibility() -> hideIme() will be called to notify WM for syncing
             // the IME hidden state.
             // The unbind will cancel the previous stats token, and create a new one internally.
             verify(mVisibilityApplier).applyImeVisibility(
-                    eq(mWindowToken), any(), eq(STATE_HIDE_IME), eq(mUserId) /* userId */);
+                    eq(mWindowToken), any(), eq(STATE_HIDE_IME),
+                    eq(SoftInputShowHideReason.NOT_SET), eq(mUserId) /* userId */);
             verify(mInputMethodManagerService.mWindowManagerInternal).hideIme(
                     eq(mWindowToken), eq(displayIdToShowIme), and(not(eq(statsToken)), notNull()));
         }
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java
index a22cacb..337d5c1 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/ImeVisibilityStateComputerTest.java
@@ -58,8 +58,8 @@
 import org.mockito.ArgumentCaptor;
 
 /**
- * Test the behavior of {@link ImeVisibilityStateComputer} and {@link ImeVisibilityApplier} when
- * requesting the IME visibility.
+ * Test the behavior of {@link ImeVisibilityStateComputer} and {@link DefaultImeVisibilityApplier}
+ * when requesting the IME visibility.
  *
  * <p> Build/Install/Run:
  * atest FrameworksInputMethodSystemServerTests:ImeVisibilityStateComputerTest
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodBindingControllerTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodBindingControllerTest.java
index 70903cb..4d28b3c 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodBindingControllerTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodBindingControllerTest.java
@@ -140,7 +140,8 @@
         final InputMethodInfo info;
         synchronized (ImfLock.class) {
             mBindingController.setSelectedMethodId(TEST_IME_ID);
-            info = mInputMethodManagerService.queryInputMethodForCurrentUserLocked(TEST_IME_ID);
+            info = InputMethodSettingsRepository.get(mCallingUserId).getMethodMap()
+                    .get(TEST_IME_ID);
         }
         assertThat(info).isNotNull();
         assertThat(info.getId()).isEqualTo(TEST_IME_ID);
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
index 42bd75a..6a86379 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceTestBase.java
@@ -35,17 +35,21 @@
 import static org.mockito.Mockito.when;
 
 import android.app.ActivityManagerInternal;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.IntentFilter;
 import android.content.pm.PackageManagerInternal;
 import android.content.res.Configuration;
 import android.hardware.input.IInputManager;
 import android.hardware.input.InputManagerGlobal;
 import android.os.Binder;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.util.ArraySet;
 import android.view.InputChannel;
 import android.view.inputmethod.EditorInfo;
 import android.window.ImeOnBackInvokedDispatcher;
@@ -131,6 +135,14 @@
     protected boolean mIsLargeScreen;
     private InputManagerGlobal.TestSession mInputManagerGlobalSession;
 
+    private final ArraySet<Class<?>> mRegisteredLocalServices = new ArraySet<>();
+
+    protected <T> void addLocalServiceMock(Class<T> type, T service) {
+        mRegisteredLocalServices.add(type);
+        LocalServices.removeServiceForTest(type);
+        LocalServices.addService(type, service);
+    }
+
     @BeforeClass
     public static void setupClass() {
         // Make sure DeviceConfig's lazy-initialized ContentProvider gets
@@ -145,7 +157,6 @@
                 mockitoSession()
                         .initMocks(this)
                         .strictness(Strictness.LENIENT)
-                        .spyStatic(LocalServices.class)
                         .mockStatic(ServiceManager.class)
                         .mockStatic(SystemServerInitThreadPool.class)
                         .startMocking();
@@ -160,18 +171,13 @@
         mEditorInfo.packageName = TEST_EDITOR_PKG_NAME;
 
         // Injecting and mocking local services.
-        doReturn(mMockWindowManagerInternal)
-                .when(() -> LocalServices.getService(WindowManagerInternal.class));
-        doReturn(mMockActivityManagerInternal)
-                .when(() -> LocalServices.getService(ActivityManagerInternal.class));
-        doReturn(mMockPackageManagerInternal)
-                .when(() -> LocalServices.getService(PackageManagerInternal.class));
-        doReturn(mMockInputManagerInternal)
-                .when(() -> LocalServices.getService(InputManagerInternal.class));
-        doReturn(mMockUserManagerInternal)
-                .when(() -> LocalServices.getService(UserManagerInternal.class));
-        doReturn(mMockImeTargetVisibilityPolicy)
-                .when(() -> LocalServices.getService(ImeTargetVisibilityPolicy.class));
+        addLocalServiceMock(WindowManagerInternal.class, mMockWindowManagerInternal);
+        addLocalServiceMock(ActivityManagerInternal.class, mMockActivityManagerInternal);
+        addLocalServiceMock(PackageManagerInternal.class, mMockPackageManagerInternal);
+        addLocalServiceMock(InputManagerInternal.class, mMockInputManagerInternal);
+        addLocalServiceMock(UserManagerInternal.class, mMockUserManagerInternal);
+        addLocalServiceMock(ImeTargetVisibilityPolicy.class, mMockImeTargetVisibilityPolicy);
+
         doReturn(mMockIInputMethodManager)
                 .when(() -> ServiceManager.getServiceOrThrow(Context.INPUT_METHOD_SERVICE));
         doReturn(mMockIPlatformCompat)
@@ -182,6 +188,9 @@
         doNothing().when(mContext).enforceCallingPermission(anyString(), anyString());
         doNothing().when(mContext).sendBroadcastAsUser(any(), any());
         doReturn(null).when(mContext).registerReceiver(any(), any());
+        doReturn(null).when(mContext).registerReceiver(
+                any(BroadcastReceiver.class),
+                any(IntentFilter.class), anyString(), any(Handler.class));
         doReturn(null)
                 .when(mContext)
                 .registerReceiverAsUser(any(), any(), any(), anyString(), any(), anyInt());
@@ -189,6 +198,7 @@
         // Injecting and mocked InputMethodBindingController and InputMethod.
         mMockInputMethodInvoker = IInputMethodInvoker.create(mMockInputMethod);
         mInputManagerGlobalSession = InputManagerGlobal.createTestSession(mMockIInputManager);
+        when(mMockInputMethodBindingController.getUserId()).thenReturn(mCallingUserId);
         synchronized (ImfLock.class) {
             when(mMockInputMethodBindingController.getCurMethod())
                     .thenReturn(mMockInputMethodInvoker);
@@ -226,14 +236,16 @@
                         "immstest1",
                         Process.THREAD_PRIORITY_FOREGROUND,
                         true /* allowIo */);
+        mServiceThread.start();
         mIoThread =
                 new ServiceThread(
                         "immstest2",
                         Process.THREAD_PRIORITY_FOREGROUND,
                         true /* allowIo */);
+        mIoThread.start();
         mInputMethodManagerService = new InputMethodManagerService(mContext,
-                InputMethodManagerService.shouldEnableExperimentalConcurrentMultiUserMode(mContext),
-                mServiceThread, mIoThread,
+                InputMethodManagerService.shouldEnableConcurrentMultiUserMode(mContext),
+                mServiceThread.getLooper(), Handler.createAsync(mIoThread.getLooper()),
                 unusedUserId -> mMockInputMethodBindingController);
         spyOn(mInputMethodManagerService);
 
@@ -282,7 +294,7 @@
         if (mInputManagerGlobalSession != null) {
             mInputManagerGlobalSession.close();
         }
-        LocalServices.removeServiceForTest(InputMethodManagerInternal.class);
+        mRegisteredLocalServices.forEach(LocalServices::removeServiceForTest);
     }
 
     protected void verifyShowSoftInput(boolean setVisible, boolean showSoftInput)
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceWindowGainedFocusTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceWindowGainedFocusTest.java
index 9f46d0ba..ffc4df8 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceWindowGainedFocusTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodManagerServiceWindowGainedFocusTest.java
@@ -50,7 +50,6 @@
 import com.android.internal.inputmethod.InputMethodDebug;
 import com.android.internal.inputmethod.StartInputFlags;
 import com.android.internal.inputmethod.StartInputReason;
-import com.android.server.LocalServices;
 import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
 import com.android.server.wm.WindowManagerInternal;
 
@@ -270,8 +269,7 @@
 
     @Test
     public void startInputOrWindowGainedFocus_localeHintsOverride() throws RemoteException {
-        doReturn(mMockVdmInternal).when(
-                () -> LocalServices.getService(VirtualDeviceManagerInternal.class));
+        addLocalServiceMock(VirtualDeviceManagerInternal.class, mMockVdmInternal);
         LocaleList overrideLocale = LocaleList.forLanguageTags("zh-CN");
         doReturn(overrideLocale).when(mMockVdmInternal).getPreferredLocaleListForUid(anyInt());
         mockHasImeFocusAndRestoreImeVisibility(false /* restoreImeVisibility */);
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
index fbe384a..e81cf9d 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/InputMethodSubtypeSwitchingControllerTest.java
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 
 import android.content.ComponentName;
@@ -28,60 +29,63 @@
 import android.view.inputmethod.InputMethodSubtype;
 import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 import com.android.server.inputmethod.InputMethodSubtypeSwitchingController.ControllerImpl;
 import com.android.server.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem;
 
 import org.junit.Test;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 public final class InputMethodSubtypeSwitchingControllerTest {
-    private static final String DUMMY_PACKAGE_NAME = "dummy package name";
-    private static final String DUMMY_IME_LABEL = "dummy ime label";
-    private static final String DUMMY_SETTING_ACTIVITY_NAME = "";
-    private static final boolean DUMMY_IS_AUX_IME = false;
-    private static final boolean DUMMY_FORCE_DEFAULT = false;
-    private static final boolean DUMMY_IS_VR_IME = false;
-    private static final int DUMMY_IS_DEFAULT_RES_ID = 0;
+    private static final String TEST_PACKAGE_NAME = "test package name";
+    private static final String TEST_IME_LABEL = "test ime label";
+    private static final String TEST_SETTING_ACTIVITY_NAME = "";
+    private static final boolean TEST_IS_AUX_IME = false;
+    private static final boolean TEST_FORCE_DEFAULT = false;
+    private static final boolean TEST_IS_VR_IME = false;
+    private static final int TEST_IS_DEFAULT_RES_ID = 0;
     private static final String SYSTEM_LOCALE = "en_US";
     private static final int NOT_A_SUBTYPE_ID = InputMethodUtils.NOT_A_SUBTYPE_ID;
 
-    private static InputMethodSubtype createDummySubtype(final String locale) {
-        final InputMethodSubtypeBuilder builder = new InputMethodSubtypeBuilder();
-        return builder.setSubtypeNameResId(0)
+    @NonNull
+    private static InputMethodSubtype createTestSubtype(@NonNull String locale) {
+        return new InputMethodSubtypeBuilder()
+                .setSubtypeNameResId(0)
                 .setSubtypeIconResId(0)
                 .setSubtypeLocale(locale)
                 .setIsAsciiCapable(true)
                 .build();
     }
 
-    private static void addDummyImeSubtypeListItems(List<ImeSubtypeListItem> items,
-            String imeName, String imeLabel, List<String> subtypeLocales,
-            boolean supportsSwitchingToNextInputMethod) {
-        final ResolveInfo ri = new ResolveInfo();
-        final ServiceInfo si = new ServiceInfo();
+    private static void addTestImeSubtypeListItems(@NonNull List<ImeSubtypeListItem> items,
+            @NonNull String imeName, @NonNull String imeLabel,
+            @Nullable List<String> subtypeLocales, boolean supportsSwitchingToNextInputMethod) {
         final ApplicationInfo ai = new ApplicationInfo();
-        ai.packageName = DUMMY_PACKAGE_NAME;
+        ai.packageName = TEST_PACKAGE_NAME;
         ai.enabled = true;
+        final ServiceInfo si = new ServiceInfo();
         si.applicationInfo = ai;
         si.enabled = true;
-        si.packageName = DUMMY_PACKAGE_NAME;
+        si.packageName = TEST_PACKAGE_NAME;
         si.name = imeName;
         si.exported = true;
         si.nonLocalizedLabel = imeLabel;
+        final ResolveInfo ri = new ResolveInfo();
         ri.serviceInfo = si;
         List<InputMethodSubtype> subtypes = null;
         if (subtypeLocales != null) {
-            subtypes = new ArrayList<InputMethodSubtype>();
+            subtypes = new ArrayList<>();
             for (String subtypeLocale : subtypeLocales) {
-                subtypes.add(createDummySubtype(subtypeLocale));
+                subtypes.add(createTestSubtype(subtypeLocale));
             }
         }
-        final InputMethodInfo imi = new InputMethodInfo(ri, DUMMY_IS_AUX_IME,
-                DUMMY_SETTING_ACTIVITY_NAME, subtypes, DUMMY_IS_DEFAULT_RES_ID,
-                DUMMY_FORCE_DEFAULT, supportsSwitchingToNextInputMethod, DUMMY_IS_VR_IME);
+        final InputMethodInfo imi = new InputMethodInfo(ri, TEST_IS_AUX_IME,
+                TEST_SETTING_ACTIVITY_NAME, subtypes, TEST_IS_DEFAULT_RES_ID,
+                TEST_FORCE_DEFAULT, supportsSwitchingToNextInputMethod, TEST_IS_VR_IME);
         if (subtypes == null) {
             items.add(new ImeSubtypeListItem(imeName, null /* variableName */, imi,
                     NOT_A_SUBTYPE_ID, null, SYSTEM_LOCALE));
@@ -94,105 +98,104 @@
         }
     }
 
-    private static ImeSubtypeListItem createDummyItem(ComponentName imeComponentName,
-            String imeName, String subtypeName, String subtypeLocale, int subtypeIndex,
-            String systemLocale) {
-        final ResolveInfo ri = new ResolveInfo();
-        final ServiceInfo si = new ServiceInfo();
-        final ApplicationInfo ai = new ApplicationInfo();
+    @NonNull
+    private static ImeSubtypeListItem createTestItem(@NonNull ComponentName imeComponentName,
+            @NonNull String imeName, @NonNull String subtypeName,
+            @NonNull String subtypeLocale, int subtypeIndex) {
+        final var ai = new ApplicationInfo();
         ai.packageName = imeComponentName.getPackageName();
         ai.enabled = true;
+        final var si = new ServiceInfo();
         si.applicationInfo = ai;
         si.enabled = true;
         si.packageName = imeComponentName.getPackageName();
         si.name = imeComponentName.getClassName();
         si.exported = true;
-        si.nonLocalizedLabel = DUMMY_IME_LABEL;
+        si.nonLocalizedLabel = TEST_IME_LABEL;
+        final var ri = new ResolveInfo();
         ri.serviceInfo = si;
-        ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
+        final var subtypes = new ArrayList<InputMethodSubtype>();
         subtypes.add(new InputMethodSubtypeBuilder()
                 .setSubtypeNameResId(0)
                 .setSubtypeIconResId(0)
                 .setSubtypeLocale(subtypeLocale)
                 .setIsAsciiCapable(true)
                 .build());
-        final InputMethodInfo imi = new InputMethodInfo(ri, DUMMY_IS_AUX_IME,
-                DUMMY_SETTING_ACTIVITY_NAME, subtypes, DUMMY_IS_DEFAULT_RES_ID,
-                DUMMY_FORCE_DEFAULT, true /* supportsSwitchingToNextInputMethod */,
-                DUMMY_IS_VR_IME);
+        final InputMethodInfo imi = new InputMethodInfo(ri, TEST_IS_AUX_IME,
+                TEST_SETTING_ACTIVITY_NAME, subtypes, TEST_IS_DEFAULT_RES_ID,
+                TEST_FORCE_DEFAULT, true /* supportsSwitchingToNextInputMethod */, TEST_IS_VR_IME);
         return new ImeSubtypeListItem(imeName, subtypeName, imi, subtypeIndex, subtypeLocale,
-                systemLocale);
+                SYSTEM_LOCALE);
     }
 
+    @NonNull
     private static List<ImeSubtypeListItem> createEnabledImeSubtypes() {
-        final List<ImeSubtypeListItem> items = new ArrayList<ImeSubtypeListItem>();
-        addDummyImeSubtypeListItems(items, "LatinIme", "LatinIme", Arrays.asList("en_US", "fr"),
+        final var items = new ArrayList<ImeSubtypeListItem>();
+        addTestImeSubtypeListItems(items, "LatinIme", "LatinIme", List.of("en_US", "fr"),
                 true /* supportsSwitchingToNextInputMethod*/);
-        addDummyImeSubtypeListItems(items, "switchUnawareLatinIme", "switchUnawareLatinIme",
-                Arrays.asList("en_UK", "hi"),
+        addTestImeSubtypeListItems(items, "switchUnawareLatinIme", "switchUnawareLatinIme",
+                List.of("en_UK", "hi"), false /* supportsSwitchingToNextInputMethod*/);
+        addTestImeSubtypeListItems(items, "subtypeAwareIme", "subtypeAwareIme", null,
+                true /* supportsSwitchingToNextInputMethod */);
+        addTestImeSubtypeListItems(items, "subtypeUnawareIme", "subtypeUnawareIme", null,
                 false /* supportsSwitchingToNextInputMethod*/);
-        addDummyImeSubtypeListItems(items, "subtypeUnawareIme", "subtypeUnawareIme", null,
-                false /* supportsSwitchingToNextInputMethod*/);
-        addDummyImeSubtypeListItems(items, "JapaneseIme", "JapaneseIme", Arrays.asList("ja_JP"),
+        addTestImeSubtypeListItems(items, "JapaneseIme", "JapaneseIme", List.of("ja_JP"),
                 true /* supportsSwitchingToNextInputMethod*/);
-        addDummyImeSubtypeListItems(items, "switchUnawareJapaneseIme", "switchUnawareJapaneseIme",
-                Arrays.asList("ja_JP"), false /* supportsSwitchingToNextInputMethod*/);
+        addTestImeSubtypeListItems(items, "switchUnawareJapaneseIme", "switchUnawareJapaneseIme",
+                List.of("ja_JP"), false /* supportsSwitchingToNextInputMethod*/);
         return items;
     }
 
+    @NonNull
     private static List<ImeSubtypeListItem> createDisabledImeSubtypes() {
-        final List<ImeSubtypeListItem> items = new ArrayList<ImeSubtypeListItem>();
-        addDummyImeSubtypeListItems(items,
+        final var items = new ArrayList<ImeSubtypeListItem>();
+        addTestImeSubtypeListItems(items,
                 "UnknownIme", "UnknownIme",
-                Arrays.asList("en_US", "hi"),
+                List.of("en_US", "hi"),
                 true /* supportsSwitchingToNextInputMethod*/);
-        addDummyImeSubtypeListItems(items,
+        addTestImeSubtypeListItems(items,
                 "UnknownSwitchingUnawareIme", "UnknownSwitchingUnawareIme",
-                Arrays.asList("en_US"),
+                List.of("en_US"),
                 false /* supportsSwitchingToNextInputMethod*/);
-        addDummyImeSubtypeListItems(items, "UnknownSubtypeUnawareIme",
+        addTestImeSubtypeListItems(items, "UnknownSubtypeUnawareIme",
                 "UnknownSubtypeUnawareIme", null,
                 false /* supportsSwitchingToNextInputMethod*/);
         return items;
     }
 
-    private void assertNextInputMethod(final ControllerImpl controller,
-            final boolean onlyCurrentIme,
-            final ImeSubtypeListItem currentItem, final ImeSubtypeListItem nextItem) {
+    private void assertNextInputMethod(@NonNull ControllerImpl controller, boolean onlyCurrentIme,
+            @NonNull ImeSubtypeListItem currentItem, @Nullable ImeSubtypeListItem nextItem) {
         InputMethodSubtype subtype = null;
         if (currentItem.mSubtypeName != null) {
-            subtype = createDummySubtype(currentItem.mSubtypeName.toString());
+            subtype = createTestSubtype(currentItem.mSubtypeName.toString());
         }
         final ImeSubtypeListItem nextIme = controller.getNextInputMethod(onlyCurrentIme,
                 currentItem.mImi, subtype);
         assertEquals(nextItem, nextIme);
     }
 
-    private void assertRotationOrder(final ControllerImpl controller,
-            final boolean onlyCurrentIme,
-            final ImeSubtypeListItem... expectedRotationOrderOfImeSubtypeList) {
+    private void assertRotationOrder(@NonNull ControllerImpl controller, boolean onlyCurrentIme,
+            ImeSubtypeListItem... expectedRotationOrderOfImeSubtypeList) {
         final int numItems = expectedRotationOrderOfImeSubtypeList.length;
         for (int i = 0; i < numItems; i++) {
-            final int currentIndex = i;
-            final int nextIndex = (currentIndex + 1) % numItems;
-            final ImeSubtypeListItem currentItem =
-                    expectedRotationOrderOfImeSubtypeList[currentIndex];
+            final int nextIndex = (i + 1) % numItems;
+            final ImeSubtypeListItem currentItem = expectedRotationOrderOfImeSubtypeList[i];
             final ImeSubtypeListItem nextItem = expectedRotationOrderOfImeSubtypeList[nextIndex];
             assertNextInputMethod(controller, onlyCurrentIme, currentItem, nextItem);
         }
     }
 
-    private void onUserAction(final ControllerImpl controller,
-            final ImeSubtypeListItem subtypeListItem) {
+    private void onUserAction(@NonNull ControllerImpl controller,
+            @NonNull ImeSubtypeListItem subtypeListItem) {
         InputMethodSubtype subtype = null;
         if (subtypeListItem.mSubtypeName != null) {
-            subtype = createDummySubtype(subtypeListItem.mSubtypeName.toString());
+            subtype = createTestSubtype(subtypeListItem.mSubtypeName.toString());
         }
         controller.onUserActionLocked(subtypeListItem.mImi, subtype);
     }
 
     @Test
-    public void testControllerImpl() throws Exception {
+    public void testControllerImpl() {
         final List<ImeSubtypeListItem> disabledItems = createDisabledImeSubtypes();
         final ImeSubtypeListItem disabledIme_en_us = disabledItems.get(0);
         final ImeSubtypeListItem disabledIme_hi = disabledItems.get(1);
@@ -204,16 +207,17 @@
         final ImeSubtypeListItem latinIme_fr = enabledItems.get(1);
         final ImeSubtypeListItem switchingUnawareLatinIme_en_uk = enabledItems.get(2);
         final ImeSubtypeListItem switchingUnawareLatinIme_hi = enabledItems.get(3);
-        final ImeSubtypeListItem subtypeUnawareIme = enabledItems.get(4);
-        final ImeSubtypeListItem japaneseIme_ja_jp = enabledItems.get(5);
-        final ImeSubtypeListItem switchUnawareJapaneseIme_ja_jp = enabledItems.get(6);
+        final ImeSubtypeListItem subtypeAwareIme = enabledItems.get(4);
+        final ImeSubtypeListItem subtypeUnawareIme = enabledItems.get(5);
+        final ImeSubtypeListItem japaneseIme_ja_jp = enabledItems.get(6);
+        final ImeSubtypeListItem switchUnawareJapaneseIme_ja_jp = enabledItems.get(7);
 
         final ControllerImpl controller = ControllerImpl.createFrom(
                 null /* currentInstance */, enabledItems);
 
         // switching-aware loop
         assertRotationOrder(controller, false /* onlyCurrentIme */,
-                latinIme_en_us, latinIme_fr, japaneseIme_ja_jp);
+                latinIme_en_us, latinIme_fr, subtypeAwareIme, japaneseIme_ja_jp);
 
         // switching-unaware loop
         assertRotationOrder(controller, false /* onlyCurrentIme */,
@@ -226,6 +230,8 @@
         assertRotationOrder(controller, true /* onlyCurrentIme */,
                 switchingUnawareLatinIme_en_uk, switchingUnawareLatinIme_hi);
         assertNextInputMethod(controller, true /* onlyCurrentIme */,
+                subtypeAwareIme, null);
+        assertNextInputMethod(controller, true /* onlyCurrentIme */,
                 subtypeUnawareIme, null);
         assertNextInputMethod(controller, true /* onlyCurrentIme */,
                 japaneseIme_ja_jp, null);
@@ -252,59 +258,60 @@
     }
 
     @Test
-    public void testControllerImplWithUserAction() throws Exception {
+    public void testControllerImplWithUserAction() {
         final List<ImeSubtypeListItem> enabledItems = createEnabledImeSubtypes();
         final ImeSubtypeListItem latinIme_en_us = enabledItems.get(0);
         final ImeSubtypeListItem latinIme_fr = enabledItems.get(1);
-        final ImeSubtypeListItem switchingUnawarelatinIme_en_uk = enabledItems.get(2);
-        final ImeSubtypeListItem switchingUnawarelatinIme_hi = enabledItems.get(3);
-        final ImeSubtypeListItem subtypeUnawareIme = enabledItems.get(4);
-        final ImeSubtypeListItem japaneseIme_ja_jp = enabledItems.get(5);
-        final ImeSubtypeListItem switchUnawareJapaneseIme_ja_jp = enabledItems.get(6);
+        final ImeSubtypeListItem switchingUnawareLatinIme_en_uk = enabledItems.get(2);
+        final ImeSubtypeListItem switchingUnawareLatinIme_hi = enabledItems.get(3);
+        final ImeSubtypeListItem subtypeAwareIme = enabledItems.get(4);
+        final ImeSubtypeListItem subtypeUnawareIme = enabledItems.get(5);
+        final ImeSubtypeListItem japaneseIme_ja_jp = enabledItems.get(6);
+        final ImeSubtypeListItem switchUnawareJapaneseIme_ja_jp = enabledItems.get(7);
 
         final ControllerImpl controller = ControllerImpl.createFrom(
                 null /* currentInstance */, enabledItems);
 
         // === switching-aware loop ===
         assertRotationOrder(controller, false /* onlyCurrentIme */,
-                latinIme_en_us, latinIme_fr, japaneseIme_ja_jp);
+                latinIme_en_us, latinIme_fr, subtypeAwareIme, japaneseIme_ja_jp);
         // Then notify that a user did something for latinIme_fr.
         onUserAction(controller, latinIme_fr);
         assertRotationOrder(controller, false /* onlyCurrentIme */,
-                latinIme_fr, latinIme_en_us, japaneseIme_ja_jp);
+                latinIme_fr, latinIme_en_us, subtypeAwareIme, japaneseIme_ja_jp);
         // Then notify that a user did something for latinIme_fr again.
         onUserAction(controller, latinIme_fr);
         assertRotationOrder(controller, false /* onlyCurrentIme */,
-                latinIme_fr, latinIme_en_us, japaneseIme_ja_jp);
-        // Then notify that a user did something for japaneseIme_ja_JP.
-        onUserAction(controller, latinIme_fr);
+                latinIme_fr, latinIme_en_us, subtypeAwareIme, japaneseIme_ja_jp);
+        // Then notify that a user did something for subtypeAwareIme.
+        onUserAction(controller, subtypeAwareIme);
         assertRotationOrder(controller, false /* onlyCurrentIme */,
-                japaneseIme_ja_jp, latinIme_fr, latinIme_en_us);
+                subtypeAwareIme, latinIme_fr, latinIme_en_us, japaneseIme_ja_jp);
         // Check onlyCurrentIme == true.
-        assertNextInputMethod(controller, true /* onlyCurrentIme */,
-                japaneseIme_ja_jp, null);
         assertRotationOrder(controller, true /* onlyCurrentIme */,
                 latinIme_fr, latinIme_en_us);
-        assertRotationOrder(controller, true /* onlyCurrentIme */,
-                latinIme_en_us, latinIme_fr);
+        assertNextInputMethod(controller, true /* onlyCurrentIme */,
+                subtypeAwareIme, null);
+        assertNextInputMethod(controller, true /* onlyCurrentIme */,
+                japaneseIme_ja_jp, null);
 
         // === switching-unaware loop ===
         assertRotationOrder(controller, false /* onlyCurrentIme */,
-                switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi, subtypeUnawareIme,
+                switchingUnawareLatinIme_en_uk, switchingUnawareLatinIme_hi, subtypeUnawareIme,
                 switchUnawareJapaneseIme_ja_jp);
         // User action should be ignored for switching unaware IMEs.
-        onUserAction(controller, switchingUnawarelatinIme_hi);
+        onUserAction(controller, switchingUnawareLatinIme_hi);
         assertRotationOrder(controller, false /* onlyCurrentIme */,
-                switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi, subtypeUnawareIme,
+                switchingUnawareLatinIme_en_uk, switchingUnawareLatinIme_hi, subtypeUnawareIme,
                 switchUnawareJapaneseIme_ja_jp);
         // User action should be ignored for switching unaware IMEs.
-        onUserAction(controller, switchUnawareJapaneseIme_ja_jp);
+        onUserAction(controller, subtypeUnawareIme);
         assertRotationOrder(controller, false /* onlyCurrentIme */,
-                switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi, subtypeUnawareIme,
+                switchingUnawareLatinIme_en_uk, switchingUnawareLatinIme_hi, subtypeUnawareIme,
                 switchUnawareJapaneseIme_ja_jp);
         // Check onlyCurrentIme == true.
         assertRotationOrder(controller, true /* onlyCurrentIme */,
-                switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi);
+                switchingUnawareLatinIme_en_uk, switchingUnawareLatinIme_hi);
         assertNextInputMethod(controller, true /* onlyCurrentIme */,
                 subtypeUnawareIme, null);
         assertNextInputMethod(controller, true /* onlyCurrentIme */,
@@ -315,40 +322,41 @@
         final ControllerImpl newController = ControllerImpl.createFrom(controller,
                 sameEnabledItems);
         assertRotationOrder(newController, false /* onlyCurrentIme */,
-                japaneseIme_ja_jp, latinIme_fr, latinIme_en_us);
+                subtypeAwareIme, latinIme_fr, latinIme_en_us, japaneseIme_ja_jp);
         assertRotationOrder(newController, false /* onlyCurrentIme */,
-                switchingUnawarelatinIme_en_uk, switchingUnawarelatinIme_hi, subtypeUnawareIme,
+                switchingUnawareLatinIme_en_uk, switchingUnawareLatinIme_hi, subtypeUnawareIme,
                 switchUnawareJapaneseIme_ja_jp);
 
         // Rotation order should be initialized when created with a different subtype list.
-        final List<ImeSubtypeListItem> differentEnabledItems = Arrays.asList(
-                latinIme_en_us, latinIme_fr, switchingUnawarelatinIme_en_uk,
-                switchUnawareJapaneseIme_ja_jp);
+        final List<ImeSubtypeListItem> differentEnabledItems = List.of(
+                latinIme_en_us, latinIme_fr, subtypeAwareIme, switchingUnawareLatinIme_en_uk,
+                switchUnawareJapaneseIme_ja_jp, subtypeUnawareIme);
         final ControllerImpl anotherController = ControllerImpl.createFrom(controller,
                 differentEnabledItems);
         assertRotationOrder(anotherController, false /* onlyCurrentIme */,
-                latinIme_en_us, latinIme_fr);
+                latinIme_en_us, latinIme_fr, subtypeAwareIme);
         assertRotationOrder(anotherController, false /* onlyCurrentIme */,
-                switchingUnawarelatinIme_en_uk, switchUnawareJapaneseIme_ja_jp);
+                switchingUnawareLatinIme_en_uk, switchUnawareJapaneseIme_ja_jp, subtypeUnawareIme);
     }
 
     @Test
-    public void testImeSubtypeListItem() throws Exception {
-        final List<ImeSubtypeListItem> items = new ArrayList<ImeSubtypeListItem>();
-        addDummyImeSubtypeListItems(items, "LatinIme", "LatinIme",
-                Arrays.asList("en_US", "fr", "en", "en_uk", "enn", "e", "EN_US"),
+    public void testImeSubtypeListItem() {
+        final var items = new ArrayList<ImeSubtypeListItem>();
+        addTestImeSubtypeListItems(items, "LatinIme", "LatinIme",
+                List.of("en_US", "fr", "en", "en_uk", "enn", "e", "EN_US"),
                 true /* supportsSwitchingToNextInputMethod*/);
         final ImeSubtypeListItem item_en_us = items.get(0);
         final ImeSubtypeListItem item_fr = items.get(1);
         final ImeSubtypeListItem item_en = items.get(2);
-        final ImeSubtypeListItem item_enn = items.get(3);
-        final ImeSubtypeListItem item_e = items.get(4);
-        final ImeSubtypeListItem item_en_us_allcaps = items.get(5);
+        final ImeSubtypeListItem item_en_uk = items.get(3);
+        final ImeSubtypeListItem item_enn = items.get(4);
+        final ImeSubtypeListItem item_e = items.get(5);
+        final ImeSubtypeListItem item_en_us_allcaps = items.get(6);
 
         assertTrue(item_en_us.mIsSystemLocale);
         assertFalse(item_fr.mIsSystemLocale);
         assertFalse(item_en.mIsSystemLocale);
-        assertFalse(item_en.mIsSystemLocale);
+        assertFalse(item_en_uk.mIsSystemLocale);
         assertFalse(item_enn.mIsSystemLocale);
         assertFalse(item_e.mIsSystemLocale);
         assertFalse(item_en_us_allcaps.mIsSystemLocale);
@@ -356,80 +364,81 @@
         assertTrue(item_en_us.mIsSystemLanguage);
         assertFalse(item_fr.mIsSystemLanguage);
         assertTrue(item_en.mIsSystemLanguage);
-        assertFalse(item_enn.mIsSystemLocale);
-        assertFalse(item_e.mIsSystemLocale);
-        assertFalse(item_en_us_allcaps.mIsSystemLocale);
+        assertTrue(item_en_uk.mIsSystemLanguage);
+        assertFalse(item_enn.mIsSystemLanguage);
+        assertFalse(item_e.mIsSystemLanguage);
+        assertFalse(item_en_us_allcaps.mIsSystemLanguage);
     }
 
     @SuppressWarnings("SelfComparison")
     @Test
-    public void testImeSubtypeListComparator() throws Exception {
+    public void testImeSubtypeListComparator() {
         final ComponentName imeX1 = new ComponentName("com.example.imeX", "Ime1");
         final ComponentName imeX2 = new ComponentName("com.example.imeX", "Ime2");
         final ComponentName imeY1 = new ComponentName("com.example.imeY", "Ime1");
         final ComponentName imeZ1 = new ComponentName("com.example.imeZ", "Ime1");
         {
-            final List<ImeSubtypeListItem> items = Arrays.asList(
+            final List<ImeSubtypeListItem> items = List.of(
                     // Subtypes of two IMEs that have the same display name "X".
                     // Subtypes that has the same locale of the system's.
-                    createDummyItem(imeX1, "X", "E", "en_US", 0, "en_US"),
-                    createDummyItem(imeX2, "X", "E", "en_US", 0, "en_US"),
-                    createDummyItem(imeX1, "X", "Z", "en_US", 3, "en_US"),
-                    createDummyItem(imeX2, "X", "Z", "en_US", 3, "en_US"),
-                    createDummyItem(imeX1, "X", "", "en_US", 6, "en_US"),
-                    createDummyItem(imeX2, "X", "", "en_US", 6, "en_US"),
+                    createTestItem(imeX1, "X", "E", "en_US", 0),
+                    createTestItem(imeX2, "X", "E", "en_US", 0),
+                    createTestItem(imeX1, "X", "Z", "en_US", 3),
+                    createTestItem(imeX2, "X", "Z", "en_US", 3),
+                    createTestItem(imeX1, "X", "", "en_US", 6),
+                    createTestItem(imeX2, "X", "", "en_US", 6),
                     // Subtypes that has the same language of the system's.
-                    createDummyItem(imeX1, "X", "E", "en", 1, "en_US"),
-                    createDummyItem(imeX2, "X", "E", "en", 1, "en_US"),
-                    createDummyItem(imeX1, "X", "Z", "en", 4, "en_US"),
-                    createDummyItem(imeX2, "X", "Z", "en", 4, "en_US"),
-                    createDummyItem(imeX1, "X", "", "en", 7, "en_US"),
-                    createDummyItem(imeX2, "X", "", "en", 7, "en_US"),
+                    createTestItem(imeX1, "X", "E", "en", 1),
+                    createTestItem(imeX2, "X", "E", "en", 1),
+                    createTestItem(imeX1, "X", "Z", "en", 4),
+                    createTestItem(imeX2, "X", "Z", "en", 4),
+                    createTestItem(imeX1, "X", "", "en", 7),
+                    createTestItem(imeX2, "X", "", "en", 7),
                     // Subtypes that has different language than the system's.
-                    createDummyItem(imeX1, "X", "A", "hi_IN", 27, "en_US"),
-                    createDummyItem(imeX2, "X", "A", "hi_IN", 27, "en_US"),
-                    createDummyItem(imeX1, "X", "E", "ja", 2, "en_US"),
-                    createDummyItem(imeX2, "X", "E", "ja", 2, "en_US"),
-                    createDummyItem(imeX1, "X", "Z", "ja", 5, "en_US"),
-                    createDummyItem(imeX2, "X", "Z", "ja", 5, "en_US"),
-                    createDummyItem(imeX1, "X", "", "ja", 8, "en_US"),
-                    createDummyItem(imeX2, "X", "", "ja", 8, "en_US"),
+                    createTestItem(imeX1, "X", "A", "hi_IN", 27),
+                    createTestItem(imeX2, "X", "A", "hi_IN", 27),
+                    createTestItem(imeX1, "X", "E", "ja", 2),
+                    createTestItem(imeX2, "X", "E", "ja", 2),
+                    createTestItem(imeX1, "X", "Z", "ja", 5),
+                    createTestItem(imeX2, "X", "Z", "ja", 5),
+                    createTestItem(imeX1, "X", "", "ja", 8),
+                    createTestItem(imeX2, "X", "", "ja", 8),
 
                     // Subtypes of IME "Y".
                     // Subtypes that has the same locale of the system's.
-                    createDummyItem(imeY1, "Y", "E", "en_US", 9, "en_US"),
-                    createDummyItem(imeY1, "Y", "Z", "en_US", 12, "en_US"),
-                    createDummyItem(imeY1, "Y", "", "en_US", 15, "en_US"),
+                    createTestItem(imeY1, "Y", "E", "en_US", 9),
+                    createTestItem(imeY1, "Y", "Z", "en_US", 12),
+                    createTestItem(imeY1, "Y", "", "en_US", 15),
                     // Subtypes that has the same language of the system's.
-                    createDummyItem(imeY1, "Y", "E", "en", 10, "en_US"),
-                    createDummyItem(imeY1, "Y", "Z", "en", 13, "en_US"),
-                    createDummyItem(imeY1, "Y", "", "en", 16, "en_US"),
+                    createTestItem(imeY1, "Y", "E", "en", 10),
+                    createTestItem(imeY1, "Y", "Z", "en", 13),
+                    createTestItem(imeY1, "Y", "", "en", 16),
                     // Subtypes that has different language than the system's.
-                    createDummyItem(imeY1, "Y", "A", "hi_IN", 28, "en_US"),
-                    createDummyItem(imeY1, "Y", "E", "ja", 11, "en_US"),
-                    createDummyItem(imeY1, "Y", "Z", "ja", 14, "en_US"),
-                    createDummyItem(imeY1, "Y", "", "ja", 17, "en_US"),
+                    createTestItem(imeY1, "Y", "A", "hi_IN", 28),
+                    createTestItem(imeY1, "Y", "E", "ja", 11),
+                    createTestItem(imeY1, "Y", "Z", "ja", 14),
+                    createTestItem(imeY1, "Y", "", "ja", 17),
 
                     // Subtypes of IME Z.
                     // Subtypes that has the same locale of the system's.
-                    createDummyItem(imeZ1, "", "E", "en_US", 18, "en_US"),
-                    createDummyItem(imeZ1, "", "Z", "en_US", 21, "en_US"),
-                    createDummyItem(imeZ1, "", "", "en_US", 24, "en_US"),
+                    createTestItem(imeZ1, "", "E", "en_US", 18),
+                    createTestItem(imeZ1, "", "Z", "en_US", 21),
+                    createTestItem(imeZ1, "", "", "en_US", 24),
                     // Subtypes that has the same language of the system's.
-                    createDummyItem(imeZ1, "", "E", "en", 19, "en_US"),
-                    createDummyItem(imeZ1, "", "Z", "en", 22, "en_US"),
-                    createDummyItem(imeZ1, "", "", "en", 25, "en_US"),
+                    createTestItem(imeZ1, "", "E", "en", 19),
+                    createTestItem(imeZ1, "", "Z", "en", 22),
+                    createTestItem(imeZ1, "", "", "en", 25),
                     // Subtypes that has different language than the system's.
-                    createDummyItem(imeZ1, "", "A", "hi_IN", 29, "en_US"),
-                    createDummyItem(imeZ1, "", "E", "ja", 20, "en_US"),
-                    createDummyItem(imeZ1, "", "Z", "ja", 23, "en_US"),
-                    createDummyItem(imeZ1, "", "", "ja", 26, "en_US"));
+                    createTestItem(imeZ1, "", "A", "hi_IN", 29),
+                    createTestItem(imeZ1, "", "E", "ja", 20),
+                    createTestItem(imeZ1, "", "Z", "ja", 23),
+                    createTestItem(imeZ1, "", "", "ja", 26));
 
             // Ensure {@link java.lang.Comparable#compareTo} contracts are satisfied.
             for (int i = 0; i < items.size(); ++i) {
                 final ImeSubtypeListItem item1 = items.get(i);
                 // Ensures sgn(x.compareTo(y)) == -sgn(y.compareTo(x)).
-                assertTrue(item1 + " has the same order of itself", item1.compareTo(item1) == 0);
+                assertEquals(item1 + " has the same order of itself", 0, item1.compareTo(item1));
                 // Ensures (x.compareTo(y) > 0 && y.compareTo(z) > 0) implies x.compareTo(z) > 0.
                 for (int j = i + 1; j < items.size(); ++j) {
                     final ImeSubtypeListItem item2 = items.get(j);
@@ -442,26 +451,24 @@
 
         {
             // Following two items have the same priority.
-            final ImeSubtypeListItem nonSystemLocale1 =
-                    createDummyItem(imeX1, "X", "A", "ja_JP", 0, "en_US");
-            final ImeSubtypeListItem nonSystemLocale2 =
-                    createDummyItem(imeX1, "X", "A", "hi_IN", 1, "en_US");
-            assertTrue(nonSystemLocale1.compareTo(nonSystemLocale2) == 0);
-            assertTrue(nonSystemLocale2.compareTo(nonSystemLocale1) == 0);
+            final ImeSubtypeListItem nonSystemLocale1 = createTestItem(imeX1, "X", "A", "ja_JP", 0);
+            final ImeSubtypeListItem nonSystemLocale2 = createTestItem(imeX1, "X", "A", "hi_IN", 1);
+            assertEquals(0, nonSystemLocale1.compareTo(nonSystemLocale2));
+            assertEquals(0, nonSystemLocale2.compareTo(nonSystemLocale1));
             // But those aren't equal to each other.
-            assertFalse(nonSystemLocale1.equals(nonSystemLocale2));
-            assertFalse(nonSystemLocale2.equals(nonSystemLocale1));
+            assertNotEquals(nonSystemLocale1, nonSystemLocale2);
+            assertNotEquals(nonSystemLocale2, nonSystemLocale1);
         }
 
         {
             // Check if ComponentName is also taken into account when comparing two items.
-            final ImeSubtypeListItem ime1 = createDummyItem(imeX1, "X", "A", "ja_JP", 0, "en_US");
-            final ImeSubtypeListItem ime2 = createDummyItem(imeX2, "X", "A", "ja_JP", 0, "en_US");
+            final ImeSubtypeListItem ime1 = createTestItem(imeX1, "X", "A", "ja_JP", 0);
+            final ImeSubtypeListItem ime2 = createTestItem(imeX2, "X", "A", "ja_JP", 0);
             assertTrue(ime1.compareTo(ime2) < 0);
             assertTrue(ime2.compareTo(ime1) > 0);
             // But those aren't equal to each other.
-            assertFalse(ime1.equals(ime2));
-            assertFalse(ime2.equals(ime1));
+            assertNotEquals(ime1, ime2);
+            assertNotEquals(ime2, ime1);
         }
     }
 }
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java
index c3a87da..9ca4f1d 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java
@@ -30,6 +30,7 @@
 
 import com.android.server.pm.UserManagerInternal;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -63,6 +64,8 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        SecureSettingsWrapper.startTestMode();
+
         mHandler = new Handler(Looper.getMainLooper());
         mBindingControllerFactory = new IntFunction<InputMethodBindingController>() {
 
@@ -73,13 +76,18 @@
         };
     }
 
+    @After
+    public void tearDown() {
+        SecureSettingsWrapper.endTestMode();
+    }
+
     @Test
     public void testUserDataRepository_addsNewUserInfoOnUserCreatedEvent() {
         // Create UserDataRepository and capture the user lifecycle listener
         final var captor = ArgumentCaptor.forClass(UserManagerInternal.UserLifecycleListener.class);
         final var bindingControllerFactorySpy = spy(mBindingControllerFactory);
-        final var repository = new UserDataRepository(mHandler, mMockUserManagerInternal,
-                bindingControllerFactorySpy);
+        final var repository = new UserDataRepository(mHandler,
+                mMockUserManagerInternal, bindingControllerFactorySpy);
 
         verify(mMockUserManagerInternal, times(1)).addUserLifecycleListener(captor.capture());
         final var listener = captor.getValue();
@@ -91,33 +99,31 @@
         listener.onUserCreated(userInfo, /* unused token */ new Object());
         waitForIdle();
 
-        // Assert UserDataRepository contains the expected UserData
-        final var allUserData = collectUserData(repository);
-        assertThat(allUserData).hasSize(1);
-        assertThat(allUserData.get(0).mUserId).isEqualTo(ANY_USER_ID);
-
-        // Assert UserDataRepository called the InputMethodBindingController creator function.
-        verify(bindingControllerFactorySpy).apply(ANY_USER_ID);
-        assertThat(allUserData.get(0).mBindingController.mUserId).isEqualTo(ANY_USER_ID);
+        // Assert UserDataRepository remains to be empty.
+        assertThat(collectUserData(repository)).isEmpty();
     }
 
     @Test
     public void testUserDataRepository_removesUserInfoOnUserRemovedEvent() {
         // Create UserDataRepository and capture the user lifecycle listener
         final var captor = ArgumentCaptor.forClass(UserManagerInternal.UserLifecycleListener.class);
-        final var repository = new UserDataRepository(mHandler, mMockUserManagerInternal,
+        final var repository = new UserDataRepository(mHandler,
+                mMockUserManagerInternal,
                 userId -> new InputMethodBindingController(userId, mMockInputMethodManagerService));
 
         verify(mMockUserManagerInternal, times(1)).addUserLifecycleListener(captor.capture());
         final var listener = captor.getValue();
 
         // Add one UserData ...
-        final var userInfo = new UserInfo();
-        userInfo.id = ANY_USER_ID;
-        listener.onUserCreated(userInfo, /* unused token */ new Object());
-        waitForIdle();
+        synchronized (ImfLock.class) {
+            final var userData = repository.getOrCreate(ANY_USER_ID);
+            assertThat(userData.mUserId).isEqualTo(ANY_USER_ID);
+        }
+
         // ... and then call onUserRemoved
         assertThat(collectUserData(repository)).hasSize(1);
+        final var userInfo = new UserInfo();
+        userInfo.id = ANY_USER_ID;
         listener.onUserRemoved(userInfo);
         waitForIdle();
 
@@ -127,8 +133,8 @@
 
     @Test
     public void testGetOrCreate() {
-        final var repository = new UserDataRepository(mHandler, mMockUserManagerInternal,
-                mBindingControllerFactory);
+        final var repository = new UserDataRepository(mHandler,
+                mMockUserManagerInternal, mBindingControllerFactory);
 
         synchronized (ImfLock.class) {
             final var userData = repository.getOrCreate(ANY_USER_ID);
@@ -140,7 +146,7 @@
         assertThat(allUserData.get(0).mUserId).isEqualTo(ANY_USER_ID);
 
         // Assert UserDataRepository called the InputMethodBindingController creator function.
-        assertThat(allUserData.get(0).mBindingController.mUserId).isEqualTo(ANY_USER_ID);
+        assertThat(allUserData.get(0).mBindingController.getUserId()).isEqualTo(ANY_USER_ID);
     }
 
     private List<UserDataRepository.UserData> collectUserData(UserDataRepository repository) {
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayBrightnessStateTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayBrightnessStateTest.java
index bba4c8d..f690b1b 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayBrightnessStateTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayBrightnessStateTest.java
@@ -44,7 +44,7 @@
     @Test
     public void validateAllDisplayBrightnessStateFieldsAreSetAsExpected() {
         float brightness = 0.3f;
-        float sdrBrightness = 0.2f;
+        float hdrBrightness = 0.4f;
         boolean shouldUseAutoBrightness = true;
         boolean shouldUpdateScreenBrightnessSetting = true;
         int brightnessAdjustmentFlag = 2;
@@ -53,7 +53,7 @@
         brightnessReason.setModifier(BrightnessReason.MODIFIER_DIMMED);
         DisplayBrightnessState displayBrightnessState = mDisplayBrightnessStateBuilder
                 .setBrightness(brightness)
-                .setSdrBrightness(sdrBrightness)
+                .setHdrBrightness(hdrBrightness)
                 .setBrightnessReason(brightnessReason)
                 .setShouldUseAutoBrightness(shouldUseAutoBrightness)
                 .setShouldUpdateScreenBrightnessSetting(shouldUpdateScreenBrightnessSetting)
@@ -62,7 +62,7 @@
                 .build();
 
         assertEquals(displayBrightnessState.getBrightness(), brightness, FLOAT_DELTA);
-        assertEquals(displayBrightnessState.getSdrBrightness(), sdrBrightness, FLOAT_DELTA);
+        assertEquals(displayBrightnessState.getHdrBrightness(), hdrBrightness, FLOAT_DELTA);
         assertEquals(displayBrightnessState.getBrightnessReason(), brightnessReason);
         assertEquals(displayBrightnessState.getShouldUseAutoBrightness(), shouldUseAutoBrightness);
         assertEquals(shouldUpdateScreenBrightnessSetting,
@@ -78,7 +78,7 @@
         DisplayBrightnessState state1 = new DisplayBrightnessState.Builder()
                 .setBrightnessReason(reason)
                 .setBrightness(0.26f)
-                .setSdrBrightness(0.23f)
+                .setHdrBrightness(0.29f)
                 .setShouldUseAutoBrightness(false)
                 .setShouldUpdateScreenBrightnessSetting(true)
                 .build();
@@ -91,8 +91,8 @@
         sb.append("DisplayBrightnessState:")
                 .append("\n    brightness:")
                 .append(displayBrightnessState.getBrightness())
-                .append("\n    sdrBrightness:")
-                .append(displayBrightnessState.getSdrBrightness())
+                .append("\n    hdrBrightness:")
+                .append(displayBrightnessState.getHdrBrightness())
                 .append("\n    brightnessReason:")
                 .append(displayBrightnessState.getBrightnessReason())
                 .append("\n    shouldUseAutoBrightness:")
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
index 211ab03..d268637 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -2584,18 +2584,19 @@
 
         LogicalDisplay display =
                 logicalDisplayMapper.getDisplayLocked(displayDevice, /* includeDisabled= */ true);
+        displayManager.setDisplayState(display.getDisplayIdLocked(), Display.STATE_ON);
 
         assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
                 .isEqualTo(Display.STATE_ON);
 
-        assertThat(displayManager.requestDisplayPower(display.getDisplayIdLocked(), false))
-                .isTrue();
+        assertThat(displayManager.requestDisplayPower(display.getDisplayIdLocked(),
+                Display.STATE_OFF)).isTrue();
 
         assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
                 .isEqualTo(Display.STATE_OFF);
 
-        assertThat(displayManager.requestDisplayPower(display.getDisplayIdLocked(), true))
-                .isTrue();
+        assertThat(displayManager.requestDisplayPower(display.getDisplayIdLocked(),
+                Display.STATE_UNKNOWN)).isTrue();
 
         assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
                 .isEqualTo(Display.STATE_ON);
@@ -2621,8 +2622,10 @@
         assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState)
                 .isEqualTo(Display.STATE_ON);
 
-        assertThrows(SecurityException.class, () -> bs.requestDisplayPower(displayId, true));
-        assertThrows(SecurityException.class, () -> bs.requestDisplayPower(displayId, false));
+        assertThrows(SecurityException.class,
+                () -> bs.requestDisplayPower(displayId, Display.STATE_UNKNOWN));
+        assertThrows(SecurityException.class,
+                () -> bs.requestDisplayPower(displayId, Display.STATE_OFF));
     }
 
     @Test
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayOffloadSessionImplTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayOffloadSessionImplTest.java
index 4409051..30c384a 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayOffloadSessionImplTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayOffloadSessionImplTest.java
@@ -94,4 +94,11 @@
 
         verify(mDisplayOffloader).onBlockingScreenOn(eq(unblocker));
     }
+
+    @Test
+    public void testUnblockScreenOn() {
+        mSession.cancelBlockScreenOn();
+
+        verify(mDisplayOffloader).cancelBlockScreenOn();
+    }
 }
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
index 95f0b65..2018e1a 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -105,7 +105,6 @@
 
 import java.util.List;
 
-
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public final class DisplayPowerControllerTest {
@@ -1660,6 +1659,8 @@
         int initState = Display.STATE_OFF;
         mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
         mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
+        when(mDisplayOffloadSession.blockScreenOn(any())).thenReturn(true);
+
         // start with OFF.
         when(mHolder.displayPowerState.getScreenState()).thenReturn(initState);
         DisplayPowerRequest dpr = new DisplayPowerRequest();
@@ -1673,6 +1674,7 @@
         advanceTime(1); // Run updatePowerState
 
         verify(mDisplayOffloadSession).blockScreenOn(any(Runnable.class));
+        verify(mDisplayOffloadSession, never()).cancelBlockScreenOn();
     }
 
     @Test
@@ -1680,6 +1682,8 @@
         // set up.
         int initState = Display.STATE_ON;
         mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
+        when(mDisplayOffloadSession.blockScreenOn(any())).thenReturn(true);
+
         // start with ON.
         when(mHolder.displayPowerState.getScreenState()).thenReturn(initState);
         DisplayPowerRequest dpr = new DisplayPowerRequest();
@@ -1692,7 +1696,82 @@
         mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
         advanceTime(1); // Run updatePowerState
 
-        verify(mDisplayOffloadSession, never()).blockScreenOn(any(Runnable.class));
+        // No cancelBlockScreenOn call because we didn't block.
+        verify(mDisplayOffloadSession, never()).cancelBlockScreenOn();
+    }
+
+    @Test
+    public void testOffloadBlocker_turnON_thenOFF_cancelBlockScreenOnNotCalledIfUnblocked() {
+        // Set up.
+        when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
+        when(mDisplayManagerFlagsMock.isOffloadSessionCancelBlockScreenOnEnabled())
+                .thenReturn(true);
+        int initState = Display.STATE_OFF;
+        mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
+        mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
+        ArgumentCaptor<Runnable> argumentCaptor = ArgumentCaptor.forClass(Runnable.class);
+        when(mDisplayOffloadSession.blockScreenOn(argumentCaptor.capture())).thenReturn(true);
+
+        // Start with OFF.
+        when(mHolder.displayPowerState.getScreenState()).thenReturn(initState);
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        dpr.policy = DisplayPowerRequest.POLICY_OFF;
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState
+
+        // Go to ON.
+        dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState
+
+        verify(mDisplayOffloadSession).blockScreenOn(any());
+
+        // Unblocked
+        argumentCaptor.getValue().run();
+        advanceTime(1); // Run updatePowerState
+
+        // Go to OFF immediately
+        dpr.policy = DisplayPowerRequest.POLICY_OFF;
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState
+
+        // No cancelBlockScreenOn call because we already unblocked
+        verify(mDisplayOffloadSession, never()).cancelBlockScreenOn();
+    }
+
+    @Test
+    public void testOffloadBlocker_turnON_thenOFF_cancelBlockScreenOn() {
+        // Set up.
+        when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
+        when(mDisplayManagerFlagsMock.isOffloadSessionCancelBlockScreenOnEnabled())
+                .thenReturn(true);
+        int initState = Display.STATE_OFF;
+        mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
+        mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
+        when(mDisplayOffloadSession.blockScreenOn(any())).thenReturn(true);
+
+        // Start with OFF.
+        when(mHolder.displayPowerState.getScreenState()).thenReturn(initState);
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        dpr.policy = DisplayPowerRequest.POLICY_OFF;
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState
+
+        // Go to ON.
+        dpr.policy = DisplayPowerRequest.POLICY_BRIGHT;
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState
+
+        // We should call blockScreenOn
+        verify(mDisplayOffloadSession).blockScreenOn(any(Runnable.class));
+
+        // Go to OFF immediately
+        dpr.policy = DisplayPowerRequest.POLICY_OFF;
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState
+
+        // We should call cancelBlockScreenOn
+        verify(mDisplayOffloadSession).cancelBlockScreenOn();
     }
 
     @Test
@@ -1863,7 +1942,7 @@
     }
 
     @Test
-    public void testDozeManualBrightness() {
+    public void testDozeManualBrightness_DpcRefactorDisabled() {
         when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
         mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
         Settings.System.putInt(mContext.getContentResolver(),
@@ -1893,6 +1972,45 @@
                 /* ignoreAnimationLimits= */ anyBoolean());
         assertEquals(brightness * DOZE_SCALE_FACTOR, mHolder.dpc.getDozeBrightnessForOffload(),
                 /* delta= */ 0);
+        // This brightness shouldn't be stored in the setting
+        verify(mHolder.brightnessSetting, never()).setBrightness(brightness * DOZE_SCALE_FACTOR);
+    }
+
+    @Test
+    public void testDozeManualBrightness_DpcRefactorEnabled() {
+        when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
+        when(mDisplayManagerFlagsMock.isRefactorDisplayPowerControllerEnabled()).thenReturn(true);
+        mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
+        mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
+        Settings.System.putInt(mContext.getContentResolver(),
+                Settings.System.SCREEN_BRIGHTNESS_MODE,
+                Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
+        float brightness = 0.277f;
+        when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
+        when(mHolder.brightnessSetting.getBrightness()).thenReturn(brightness);
+        when(mHolder.hbmController.getCurrentBrightnessMax())
+                .thenReturn(PowerManager.BRIGHTNESS_MAX);
+        when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_DOZE);
+
+        DisplayPowerRequest dpr = new DisplayPowerRequest();
+        dpr.policy = DisplayPowerRequest.POLICY_DOZE;
+        mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+        advanceTime(1); // Run updatePowerState, initialize
+
+        ArgumentCaptor<BrightnessSetting.BrightnessSettingListener> listenerCaptor =
+                ArgumentCaptor.forClass(BrightnessSetting.BrightnessSettingListener.class);
+        verify(mHolder.brightnessSetting).registerListener(listenerCaptor.capture());
+        BrightnessSetting.BrightnessSettingListener listener = listenerCaptor.getValue();
+        listener.onBrightnessChanged(brightness);
+        advanceTime(1); // Send messages, run updatePowerState
+
+        verify(mHolder.animator).animateTo(eq(brightness * DOZE_SCALE_FACTOR),
+                /* linearSecondTarget= */ anyFloat(), /* rate= */ anyFloat(),
+                /* ignoreAnimationLimits= */ anyBoolean());
+        assertEquals(brightness * DOZE_SCALE_FACTOR, mHolder.dpc.getDozeBrightnessForOffload(),
+                /* delta= */ 0);
+        // This brightness shouldn't be stored in the setting
+        verify(mHolder.brightnessSetting, never()).setBrightness(brightness * DOZE_SCALE_FACTOR);
     }
 
     @Test
diff --git a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
index 01ff35f..a7e0ebd 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -33,7 +33,6 @@
 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.times;
 import static org.mockito.Mockito.when;
 
@@ -83,7 +82,6 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class LocalDisplayAdapterTest {
@@ -126,7 +124,7 @@
 
     private DisplayOffloadSessionImpl mDisplayOffloadSession;
 
-    private DisplayOffloader mDisplayOffloader;
+    @Mock DisplayOffloader mDisplayOffloader;
 
     private TestListener mListener = new TestListener();
 
@@ -1249,24 +1247,8 @@
     }
 
     private void initDisplayOffloadSession() {
-        mDisplayOffloader = spy(new DisplayOffloader() {
-            @Override
-            public boolean startOffload() {
-                return true;
-            }
-
-            @Override
-            public void stopOffload() {}
-
-            @Override
-            public void onBlockingScreenOn(Runnable unblocker) {}
-
-            @Override
-            public boolean allowAutoBrightnessInDoze() {
-                return true;
-            }
-        });
-
+        when(mDisplayOffloader.startOffload()).thenReturn(true);
+        when(mDisplayOffloader.allowAutoBrightnessInDoze()).thenReturn(true);
         mDisplayOffloadSession = new DisplayOffloadSessionImpl(mDisplayOffloader,
                 mMockedDisplayPowerController);
     }
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
index 88d3238..d7936fe 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.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.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.mock;
@@ -255,7 +256,8 @@
     @Test
     public void setBrightnessSetsInBrightnessSetting() {
         float brightnessValue = 0.3f;
-        mDisplayBrightnessController.setBrightness(brightnessValue);
+        float maxBrightnessValue = 0.65f;
+        mDisplayBrightnessController.setBrightness(brightnessValue, maxBrightnessValue);
         verify(mBrightnessSetting).setBrightness(brightnessValue);
     }
 
@@ -266,20 +268,24 @@
 
         // Sets the appropriate value when valid, and not equal to the current brightness
         float brightnessValue = 0.3f;
-        mDisplayBrightnessController.updateScreenBrightnessSetting(brightnessValue);
+        float maxBrightnessValue = 0.65f;
+        mDisplayBrightnessController.updateScreenBrightnessSetting(brightnessValue,
+                maxBrightnessValue);
         assertEquals(mDisplayBrightnessController.getCurrentBrightness(), brightnessValue, 0.0f);
         verify(mBrightnessChangeExecutor).execute(mOnBrightnessChangeRunnable);
         verify(mBrightnessSetting).setBrightness(brightnessValue);
 
         // Does nothing if the value is invalid
-        mDisplayBrightnessController.updateScreenBrightnessSetting(Float.NaN);
+        clearInvocations(mBrightnessSetting);
+        mDisplayBrightnessController.updateScreenBrightnessSetting(Float.NaN, maxBrightnessValue);
         verifyNoMoreInteractions(mBrightnessChangeExecutor, mBrightnessSetting);
 
         // Does nothing if the value is same as the current brightness
         brightnessValue = 0.2f;
         mDisplayBrightnessController.setAndNotifyCurrentScreenBrightness(brightnessValue);
         verify(mBrightnessChangeExecutor, times(2)).execute(mOnBrightnessChangeRunnable);
-        mDisplayBrightnessController.updateScreenBrightnessSetting(brightnessValue);
+        mDisplayBrightnessController.updateScreenBrightnessSetting(brightnessValue,
+                maxBrightnessValue);
         verifyNoMoreInteractions(mBrightnessChangeExecutor, mBrightnessSetting);
     }
 
@@ -366,7 +372,7 @@
         when(mBrightnessSetting.getBrightnessNitsForDefaultDisplay()).thenReturn(nits);
         mDisplayBrightnessController.setAutomaticBrightnessController(
                 automaticBrightnessController);
-        verify(mBrightnessSetting).setBrightness(brightness);
+        verify(mBrightnessSetting).setBrightnessNoNotify(brightness);
         assertEquals(brightness, mDisplayBrightnessController.getCurrentBrightness(), 0.01f);
         clearInvocations(automaticBrightnessController, mBrightnessSetting);
 
@@ -378,7 +384,7 @@
         when(mBrightnessSetting.getBrightness()).thenReturn(brightness);
         mDisplayBrightnessController.setAutomaticBrightnessController(
                 automaticBrightnessController);
-        verify(mBrightnessSetting, never()).setBrightness(brightness);
+        verify(mBrightnessSetting, never()).setBrightnessNoNotify(brightness);
         assertEquals(brightness, mDisplayBrightnessController.getCurrentBrightness(), 0.01f);
         clearInvocations(automaticBrightnessController, mBrightnessSetting);
 
@@ -395,15 +401,73 @@
         assertEquals(brightness, mDisplayBrightnessController.getCurrentBrightness(), 0.01f);
         verifyZeroInteractions(automaticBrightnessController);
         verify(mBrightnessSetting, never()).getBrightnessNitsForDefaultDisplay();
-        verify(mBrightnessSetting, never()).setBrightness(brightness);
+        verify(mBrightnessSetting, never()).setBrightnessNoNotify(brightness);
     }
 
     @Test
+    public void testDoesNotSetBrightnessNits_settingMaxBrightnessAndStoredValueGreater() {
+        float brightnessValue = 0.65f;
+        float maxBrightness = 0.65f;
+        float nits = 200f;
+        float storedNits = 300f;
+
+        when(mBrightnessSetting.getBrightnessNitsForDefaultDisplay()).thenReturn(storedNits);
+        AutomaticBrightnessController automaticBrightnessController = mock(
+                AutomaticBrightnessController.class);
+        when(automaticBrightnessController.convertToNits(brightnessValue)).thenReturn(nits);
+        mDisplayBrightnessController.mAutomaticBrightnessController = automaticBrightnessController;
+
+        mDisplayBrightnessController.setBrightness(brightnessValue, maxBrightness);
+
+        verify(mBrightnessSetting, never()).setBrightnessNitsForDefaultDisplay(anyFloat());
+    }
+
+    @Test
+    public void testSetsBrightnessNits_storedValueLower() {
+        float brightnessValue = 0.65f;
+        float maxBrightness = 0.65f;
+        float nits = 200f;
+        float storedNits = 100f;
+
+        when(mBrightnessSetting.getBrightnessNitsForDefaultDisplay()).thenReturn(storedNits);
+        AutomaticBrightnessController automaticBrightnessController = mock(
+                AutomaticBrightnessController.class);
+        when(automaticBrightnessController.convertToNits(brightnessValue)).thenReturn(nits);
+        mDisplayBrightnessController.mAutomaticBrightnessController = automaticBrightnessController;
+
+        mDisplayBrightnessController.setBrightness(brightnessValue, maxBrightness);
+
+        verify(mBrightnessSetting).setBrightnessNitsForDefaultDisplay(nits);
+    }
+
+    @Test
+    public void testSetsBrightnessNits_lowerThanMax() {
+        float brightnessValue = 0.60f;
+        float maxBrightness = 0.65f;
+        float nits = 200f;
+        float storedNits = 300f;
+
+        when(mBrightnessSetting.getBrightnessNitsForDefaultDisplay()).thenReturn(storedNits);
+        AutomaticBrightnessController automaticBrightnessController = mock(
+                AutomaticBrightnessController.class);
+        when(automaticBrightnessController.convertToNits(brightnessValue)).thenReturn(nits);
+        mDisplayBrightnessController.mAutomaticBrightnessController = automaticBrightnessController;
+
+        mDisplayBrightnessController.setBrightness(brightnessValue, maxBrightness);
+
+        verify(mBrightnessSetting).setBrightnessNitsForDefaultDisplay(nits);
+    }
+
+
+    @Test
     public void testChangeBrightnessNitsWhenUserChanges() {
         float brightnessValue1 = 0.3f;
         float nits1 = 200f;
+        int userSerial1 = 1;
         float brightnessValue2 = 0.5f;
         float nits2 = 300f;
+        int userSerial2 = 2;
+        float maxBrightness = 0.65f;
         AutomaticBrightnessController automaticBrightnessController = mock(
                 AutomaticBrightnessController.class);
         when(automaticBrightnessController.convertToNits(brightnessValue1)).thenReturn(nits1);
@@ -417,13 +481,13 @@
         verify(automaticBrightnessStrategy)
                 .setAutomaticBrightnessController(automaticBrightnessController);
 
-        mDisplayBrightnessController.setBrightness(brightnessValue1, 1 /* user-serial */);
-        verify(mBrightnessSetting).setUserSerial(1);
+        mDisplayBrightnessController.setBrightness(brightnessValue1, userSerial1, maxBrightness);
+        verify(mBrightnessSetting).setUserSerial(userSerial1);
         verify(mBrightnessSetting).setBrightness(brightnessValue1);
         verify(mBrightnessSetting).setBrightnessNitsForDefaultDisplay(nits1);
 
-        mDisplayBrightnessController.setBrightness(brightnessValue2, 2 /* user-serial */);
-        verify(mBrightnessSetting).setUserSerial(2);
+        mDisplayBrightnessController.setBrightness(brightnessValue2, userSerial2, maxBrightness);
+        verify(mBrightnessSetting).setUserSerial(userSerial2);
         verify(mBrightnessSetting).setBrightness(brightnessValue2);
         verify(mBrightnessSetting).setBrightnessNitsForDefaultDisplay(nits2);
     }
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java
index 69043f5..e982153 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java
@@ -16,19 +16,19 @@
 
 package com.android.server.display.brightness.clamper;
 
+import static android.view.Display.STATE_OFF;
 import static android.view.Display.STATE_ON;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
-import android.hardware.Sensor;
-import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
 import android.hardware.display.BrightnessInfo;
 import android.hardware.display.DisplayManagerInternal;
@@ -40,12 +40,10 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
-import com.android.internal.util.test.FakeSettingsProvider;
-import com.android.internal.util.test.FakeSettingsProviderRule;
 import com.android.server.display.DisplayBrightnessState;
 import com.android.server.display.DisplayDeviceConfig;
-import com.android.server.display.TestUtils;
 import com.android.server.display.brightness.BrightnessReason;
+import com.android.server.display.config.SensorData;
 import com.android.server.display.feature.DeviceConfigParameterProvider;
 import com.android.server.display.feature.DisplayManagerFlags;
 import com.android.server.testutils.OffsettableClock;
@@ -63,6 +61,7 @@
 @SmallTest
 public class BrightnessClamperControllerTest {
     private static final float FLOAT_TOLERANCE = 0.001f;
+    private static final int DISPLAY_ID = 2;
 
     private final OffsettableClock mClock = new OffsettableClock();
     private final TestHandler mTestHandler = new TestHandler(null, mClock);
@@ -78,8 +77,12 @@
     @Mock
     private BrightnessClamperController.DisplayDeviceData mMockDisplayDeviceData;
     @Mock
+    private SensorData mMockSensorData;
+    @Mock
     private DeviceConfigParameterProvider mMockDeviceConfigParameterProvider;
     @Mock
+    private LightSensorController mMockLightSensorController;
+    @Mock
     private BrightnessClamper<BrightnessClamperController.DisplayDeviceData> mMockClamper;
     @Mock
     private DisplayManagerFlags mFlags;
@@ -88,23 +91,17 @@
     @Mock
     private DisplayManagerInternal.DisplayPowerRequest mMockRequest;
 
-    Sensor mLightSensor;
-
     @Mock
     private DeviceConfig.Properties mMockProperties;
     private BrightnessClamperController mClamperController;
     private TestInjector mTestInjector;
 
-    @Rule
-    public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
-
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mLightSensor = TestUtils.createSensor(Sensor.TYPE_LIGHT, "Light Sensor");
         mTestInjector = new TestInjector(List.of(mMockClamper), List.of(mMockModifier));
-        when(mSensorManager.getDefaultSensor(anyInt())).thenReturn(mLightSensor);
-        when(mMockModifier.shouldListenToLightSensor()).thenReturn(true);
+        when(mMockDisplayDeviceData.getDisplayId()).thenReturn(DISPLAY_ID);
+        when(mMockDisplayDeviceData.getAmbientLightSensor()).thenReturn(mMockSensorData);
 
         mClamperController = createBrightnessClamperController();
     }
@@ -115,6 +112,25 @@
     }
 
     @Test
+    public void testConstructor_ConfiguresLightSensorController() {
+        verify(mMockLightSensorController).configure(mMockSensorData, DISPLAY_ID);
+    }
+
+    @Test
+    public void testConstructor_doesNotStartsLightSensorController() {
+        verify(mMockLightSensorController, never()).restart();
+    }
+
+    @Test
+    public void testConstructor_startsLightSensorController() {
+        when(mMockModifier.shouldListenToLightSensor()).thenReturn(true);
+
+        mClamperController = createBrightnessClamperController();
+
+        verify(mMockLightSensorController).restart();
+    }
+
+    @Test
     public void testStop_RemovesOnPropertiesChangeListener() {
         ArgumentCaptor<DeviceConfig.OnPropertiesChangedListener> captor = ArgumentCaptor.forClass(
                 DeviceConfig.OnPropertiesChangedListener.class);
@@ -152,6 +168,21 @@
     }
 
     @Test
+    public void testOnDisplayChanged_doesNotRestartLightSensor() {
+        mClamperController.onDisplayChanged(mMockDisplayDeviceData);
+
+        verify(mMockLightSensorController, never()).restart();
+    }
+
+    @Test
+    public void testOnDisplayChanged_restartsLightSensor() {
+        when(mMockModifier.shouldListenToLightSensor()).thenReturn(true);
+        mClamperController.onDisplayChanged(mMockDisplayDeviceData);
+
+        verify(mMockLightSensorController).restart();
+    }
+
+    @Test
     public void testClamp_AppliesModifier() {
         float initialBrightness = 0.2f;
         boolean initialSlowChange = true;
@@ -161,6 +192,26 @@
     }
 
     @Test
+    public void testClamp_restartsLightSensor() {
+        float initialBrightness = 0.2f;
+        boolean initialSlowChange = true;
+        when(mMockModifier.shouldListenToLightSensor()).thenReturn(true);
+        mClamperController.clamp(mMockRequest, initialBrightness, initialSlowChange, STATE_ON);
+
+        verify(mMockLightSensorController).restart();
+    }
+
+    @Test
+    public void testClamp_stopsLightSensor() {
+        float initialBrightness = 0.2f;
+        boolean initialSlowChange = true;
+        clearInvocations(mMockLightSensorController);
+        mClamperController.clamp(mMockRequest, initialBrightness, initialSlowChange, STATE_OFF);
+
+        verify(mMockLightSensorController).stop();
+    }
+
+    @Test
     public void testClamp_inactiveClamperNotApplied() {
         float initialBrightness = 0.8f;
         boolean initialSlowChange = true;
@@ -260,33 +311,17 @@
     }
 
     @Test
-    public void testAmbientLuxChanges() throws Exception {
-        ArgumentCaptor<SensorEventListener> listenerCaptor = ArgumentCaptor.forClass(
-                SensorEventListener.class);
+    public void testAmbientLuxChanges() {
+        mTestInjector.mCapturedLightSensorListener.onAmbientLuxChange(50);
 
-        verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(mLightSensor),
-                anyInt(), any(Handler.class));
-        SensorEventListener listener = listenerCaptor.getValue();
-
-        when(mSensorManager.getSensorList(eq(Sensor.TYPE_ALL))).thenReturn(List.of(mLightSensor));
-
-        float initialBrightness = 0.8f;
-        boolean initialSlowChange = true;
-
-        DisplayBrightnessState state = mClamperController.clamp(mMockRequest, initialBrightness,
-                initialSlowChange, STATE_ON);
-        assertEquals(initialBrightness, state.getBrightness(), FLOAT_TOLERANCE);
-
-        listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 50, mClock.now()));
         verify(mMockModifier).setAmbientLux(50);
-
-        listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 300, mClock.now()));
-        verify(mMockModifier).setAmbientLux(300);
     }
 
     @Test
     public void testStop() {
+        clearInvocations(mMockLightSensorController);
         mClamperController.stop();
+        verify(mMockLightSensorController).stop();
         verify(mMockModifier).stop();
         verify(mMockClamper).stop();
     }
@@ -303,6 +338,7 @@
         private final List<BrightnessStateModifier> mModifiers;
 
         private BrightnessClamperController.ClamperChangeListener mCapturedChangeListener;
+        private LightSensorController.LightSensorListener mCapturedLightSensorListener;
 
         private TestInjector(
                 List<BrightnessClamper<? super BrightnessClamperController.DisplayDeviceData>>
@@ -330,8 +366,15 @@
         @Override
         List<BrightnessStateModifier> getModifiers(DisplayManagerFlags flags, Context context,
                 Handler handler, BrightnessClamperController.ClamperChangeListener listener,
-                DisplayDeviceConfig displayDeviceConfig, SensorManager sensorManager) {
+                DisplayDeviceConfig displayDeviceConfig) {
             return mModifiers;
         }
+
+        @Override
+        LightSensorController getLightSensorController(SensorManager sensorManager, Context context,
+                LightSensorController.LightSensorListener listener, Handler handler) {
+            mCapturedLightSensorListener = listener;
+            return mMockLightSensorController;
+        }
     }
 }
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/LightSensorControllerTest.kt b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/LightSensorControllerTest.kt
new file mode 100644
index 0000000..b742d02
--- /dev/null
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/LightSensorControllerTest.kt
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.clamper
+
+import android.content.res.Resources
+import android.hardware.Sensor
+import android.hardware.SensorEventListener
+import android.hardware.SensorManager
+import android.os.Handler
+import androidx.test.filters.SmallTest
+import com.android.server.display.TestUtils
+import com.android.server.display.brightness.clamper.LightSensorController.Injector
+import com.android.server.display.brightness.clamper.LightSensorController.LightSensorListener
+import com.android.server.display.config.SensorData
+import com.android.server.display.utils.AmbientFilter
+import org.junit.Before
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.inOrder
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.verifyNoMoreInteractions
+import org.mockito.kotlin.whenever
+
+private const val LIGHT_SENSOR_RATE: Int = 10
+private const val DISPLAY_ID: Int = 3
+private const val NOW: Long = 3_000
+
+@SmallTest
+class LightSensorControllerTest {
+
+    private val mockSensorManager: SensorManager = mock()
+    private val mockResources: Resources = mock()
+    private val mockLightSensorListener: LightSensorListener = mock()
+    private val mockHandler: Handler = mock()
+    private val mockAmbientFilter: AmbientFilter = mock()
+
+    private val testInjector = TestInjector()
+    private val dummySensorData = SensorData()
+
+    private lateinit var controller: LightSensorController
+
+    @Before
+    fun setUp() {
+        controller = LightSensorController(mockSensorManager, mockResources,
+            mockLightSensorListener, mockHandler, testInjector)
+    }
+
+    fun `does not register light sensor if is not configured`() {
+        controller.restart()
+
+        verifyNoMoreInteractions(mockSensorManager, mockAmbientFilter, mockLightSensorListener)
+    }
+
+    fun `does not register light sensor if missing`() {
+        controller.configure(dummySensorData, DISPLAY_ID)
+        controller.restart()
+
+        verifyNoMoreInteractions(mockSensorManager, mockAmbientFilter, mockLightSensorListener)
+    }
+
+    fun `register light sensor if configured and present`() {
+        testInjector.lightSensor = TestUtils
+                .createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT)
+        controller.configure(dummySensorData, DISPLAY_ID)
+        controller.restart()
+
+        verify(mockSensorManager).registerListener(any(),
+            testInjector.lightSensor, LIGHT_SENSOR_RATE * 1000, mockHandler)
+        verifyNoMoreInteractions(mockSensorManager, mockAmbientFilter, mockLightSensorListener)
+    }
+
+    fun `register light sensor once if not changed`() {
+        testInjector.lightSensor = TestUtils
+                .createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT)
+        controller.configure(dummySensorData, DISPLAY_ID)
+
+        controller.restart()
+        controller.restart()
+
+        verify(mockSensorManager).registerListener(any(),
+            testInjector.lightSensor, LIGHT_SENSOR_RATE * 1000, mockHandler)
+        verifyNoMoreInteractions(mockSensorManager, mockAmbientFilter, mockLightSensorListener)
+    }
+
+    fun `register new light sensor and unregister old if changed`() {
+        val lightSensor1 = TestUtils
+                .createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT)
+        testInjector.lightSensor = lightSensor1
+        controller.configure(dummySensorData, DISPLAY_ID)
+        controller.restart()
+
+        val lightSensor2 = TestUtils
+                .createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT)
+        testInjector.lightSensor = lightSensor2
+        controller.configure(dummySensorData, DISPLAY_ID)
+        controller.restart()
+
+        inOrder {
+            verify(mockSensorManager).registerListener(any(),
+                lightSensor1, LIGHT_SENSOR_RATE * 1000, mockHandler)
+            verify(mockSensorManager).unregisterListener(any<SensorEventListener>())
+            verify(mockAmbientFilter).clear()
+            verify(mockLightSensorListener).onAmbientLuxChange(LightSensorController.INVALID_LUX)
+            verify(mockSensorManager).registerListener(any(),
+                lightSensor2, LIGHT_SENSOR_RATE * 1000, mockHandler)
+        }
+        verifyNoMoreInteractions(mockSensorManager, mockAmbientFilter, mockLightSensorListener)
+    }
+
+    fun `notifies listener on ambient lux change`() {
+        val expectedLux = 40f
+        val eventLux = 50
+        val eventTime = 60L
+        whenever(mockAmbientFilter.getEstimate(NOW)).thenReturn(expectedLux)
+        val listenerCaptor = argumentCaptor<SensorEventListener>()
+        testInjector.lightSensor = TestUtils
+                .createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT)
+        controller.configure(dummySensorData, DISPLAY_ID)
+        controller.restart()
+        verify(mockSensorManager).registerListener(listenerCaptor.capture(),
+            eq(testInjector.lightSensor), eq(LIGHT_SENSOR_RATE * 1000), eq(mockHandler))
+
+        val listener = listenerCaptor.lastValue
+        listener.onSensorChanged(TestUtils.createSensorEvent(testInjector.lightSensor,
+            eventLux, eventTime * 1_000_000))
+
+        inOrder {
+            verify(mockAmbientFilter).addValue(eventTime, eventLux.toFloat())
+            verify(mockLightSensorListener).onAmbientLuxChange(expectedLux)
+        }
+    }
+
+    private inner class TestInjector : Injector() {
+        var lightSensor: Sensor? = null
+        override fun getLightSensor(sensorManager: SensorManager?,
+            sensorData: SensorData?, fallbackType: Int): Sensor? {
+            return lightSensor
+        }
+
+        override fun getLightSensorRate(resources: Resources?): Int {
+            return LIGHT_SENSOR_RATE
+        }
+
+        override fun getAmbientFilter(resources: Resources?): AmbientFilter {
+            return mockAmbientFilter
+        }
+
+        override fun getTime(): Long {
+            return NOW
+        }
+    }
+}
\ No newline at end of file
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutoBrightnessFallbackStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutoBrightnessFallbackStrategyTest.java
index 4d5ff55..bb24c0f 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutoBrightnessFallbackStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutoBrightnessFallbackStrategyTest.java
@@ -110,7 +110,6 @@
                 new DisplayBrightnessState.Builder()
                         .setBrightness(fallbackBrightness)
                         .setBrightnessReason(brightnessReason)
-                        .setSdrBrightness(fallbackBrightness)
                         .setDisplayBrightnessStrategyName(mAutoBrightnessFallbackStrategy.getName())
                         .build();
         DisplayBrightnessState updatedDisplayBrightnessState =
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2Test.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2Test.java
index 498bffd..4e10b98 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2Test.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2Test.java
@@ -192,7 +192,7 @@
     }
 
     @Test
-    public void testAutoBrightnessState_DisplayIsInDoze_ConfigDoesAllow() {
+    public void testAutoBrightnessState_DeviceIsInDoze_ConfigDoesAllow() {
         mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
         int targetDisplayState = Display.STATE_DOZE;
         boolean allowAutoBrightnessWhileDozing = true;
@@ -218,6 +218,32 @@
     }
 
     @Test
+    public void testAutoBrightnessState_DeviceIsInDoze_ConfigDoesAllow_ScreenOff() {
+        mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
+        int targetDisplayState = Display.STATE_OFF;
+        boolean allowAutoBrightnessWhileDozing = true;
+        int brightnessReason = BrightnessReason.REASON_UNKNOWN;
+        int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
+        float lastUserSetBrightness = 0.2f;
+        boolean userSetBrightnessChanged = true;
+        Settings.System.putFloat(mContext.getContentResolver(),
+                Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.4f);
+        mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments();
+        mAutomaticBrightnessStrategy.setAutoBrightnessState(targetDisplayState,
+                allowAutoBrightnessWhileDozing, brightnessReason, policy, lastUserSetBrightness,
+                userSetBrightnessChanged);
+        verify(mAutomaticBrightnessController)
+                .configure(AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE,
+                        mBrightnessConfiguration,
+                        lastUserSetBrightness,
+                        userSetBrightnessChanged, /* adjustment */ 0.4f,
+                        /* userChangedAutoBrightnessAdjustment= */ true, policy,
+                        targetDisplayState, /* shouldResetShortTermModel */ true);
+        assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessEnabled());
+        assertTrue(mAutomaticBrightnessStrategy.isAutoBrightnessDisabledDueToDisplayOff());
+    }
+
+    @Test
     public void testAutoBrightnessState_DisplayIsOn() {
         mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
         int targetDisplayState = Display.STATE_ON;
@@ -245,6 +271,33 @@
     }
 
     @Test
+    public void testAutoBrightnessState_DisplayIsOn_PolicyIsDoze() {
+        mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
+        int targetDisplayState = Display.STATE_ON;
+        boolean allowAutoBrightnessWhileDozing = false;
+        int brightnessReason = BrightnessReason.REASON_UNKNOWN;
+        float lastUserSetBrightness = 0.2f;
+        boolean userSetBrightnessChanged = true;
+        int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
+        float pendingBrightnessAdjustment = 0.1f;
+        Settings.System.putFloat(mContext.getContentResolver(),
+                Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, pendingBrightnessAdjustment);
+        mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments();
+        mAutomaticBrightnessStrategy.setAutoBrightnessState(targetDisplayState,
+                allowAutoBrightnessWhileDozing, brightnessReason, policy, lastUserSetBrightness,
+                userSetBrightnessChanged);
+        verify(mAutomaticBrightnessController)
+                .configure(AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE,
+                        mBrightnessConfiguration,
+                        lastUserSetBrightness,
+                        userSetBrightnessChanged, pendingBrightnessAdjustment,
+                        /* userChangedAutoBrightnessAdjustment= */ true, policy, targetDisplayState,
+                        /* shouldResetShortTermModel */ true);
+        assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessEnabled());
+        assertTrue(mAutomaticBrightnessStrategy.isAutoBrightnessDisabledDueToDisplayOff());
+    }
+
+    @Test
     public void accommodateUserBrightnessChangesWorksAsExpected() {
         // Verify the state if automaticBrightnessController is configured.
         assertFalse(mAutomaticBrightnessStrategy.isShortTermModelActive());
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
index 1d04baa..93ff9e1 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
@@ -202,7 +202,7 @@
     }
 
     @Test
-    public void testAutoBrightnessState_DisplayIsInDoze_ConfigDoesAllow() {
+    public void testAutoBrightnessState_DeviceIsInDoze_ConfigDoesAllow() {
         mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
         int targetDisplayState = Display.STATE_DOZE;
         boolean allowAutoBrightnessWhileDozing = true;
@@ -228,6 +228,32 @@
     }
 
     @Test
+    public void testAutoBrightnessState_DeviceIsInDoze_ConfigDoesAllow_ScreenOff() {
+        mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
+        int targetDisplayState = Display.STATE_OFF;
+        boolean allowAutoBrightnessWhileDozing = true;
+        int brightnessReason = BrightnessReason.REASON_UNKNOWN;
+        int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
+        float lastUserSetBrightness = 0.2f;
+        boolean userSetBrightnessChanged = true;
+        Settings.System.putFloat(mContext.getContentResolver(),
+                Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.4f);
+        mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments();
+        mAutomaticBrightnessStrategy.setAutoBrightnessState(targetDisplayState,
+                allowAutoBrightnessWhileDozing, brightnessReason, policy, lastUserSetBrightness,
+                userSetBrightnessChanged);
+        verify(mAutomaticBrightnessController)
+                .configure(AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE,
+                        mBrightnessConfiguration,
+                        lastUserSetBrightness,
+                        userSetBrightnessChanged, /* adjustment */ 0.4f,
+                        /* userChangedAutoBrightnessAdjustment= */ true, policy,
+                        targetDisplayState, /* shouldResetShortTermModel */ true);
+        assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessEnabled());
+        assertTrue(mAutomaticBrightnessStrategy.isAutoBrightnessDisabledDueToDisplayOff());
+    }
+
+    @Test
     public void testAutoBrightnessState_DisplayIsOn() {
         mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
         int targetDisplayState = Display.STATE_ON;
@@ -255,6 +281,33 @@
     }
 
     @Test
+    public void testAutoBrightnessState_DisplayIsOn_PolicyIsDoze() {
+        mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
+        int targetDisplayState = Display.STATE_ON;
+        boolean allowAutoBrightnessWhileDozing = false;
+        int brightnessReason = BrightnessReason.REASON_UNKNOWN;
+        float lastUserSetBrightness = 0.2f;
+        boolean userSetBrightnessChanged = true;
+        int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
+        float pendingBrightnessAdjustment = 0.1f;
+        Settings.System.putFloat(mContext.getContentResolver(),
+                Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, pendingBrightnessAdjustment);
+        mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments();
+        mAutomaticBrightnessStrategy.setAutoBrightnessState(targetDisplayState,
+                allowAutoBrightnessWhileDozing, brightnessReason, policy, lastUserSetBrightness,
+                userSetBrightnessChanged);
+        verify(mAutomaticBrightnessController)
+                .configure(AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE,
+                        mBrightnessConfiguration,
+                        lastUserSetBrightness,
+                        userSetBrightnessChanged, pendingBrightnessAdjustment,
+                        /* userChangedAutoBrightnessAdjustment= */ true, policy, targetDisplayState,
+                        /* shouldResetShortTermModel */ true);
+        assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessEnabled());
+        assertTrue(mAutomaticBrightnessStrategy.isAutoBrightnessDisabledDueToDisplayOff());
+    }
+
+    @Test
     public void testAutoBrightnessState_modeSwitch() {
         // Setup the test
         when(mDisplayManagerFlags.areAutoBrightnessModesEnabled()).thenReturn(true);
@@ -506,7 +559,6 @@
                 mock(DisplayManagerInternal.DisplayPowerRequest.class);
         DisplayBrightnessState expectedDisplayBrightnessState = new DisplayBrightnessState.Builder()
                 .setBrightness(brightness)
-                .setSdrBrightness(brightness)
                 .setBrightnessReason(brightnessReason)
                 .setDisplayBrightnessStrategyName(mAutomaticBrightnessStrategy.getName())
                 .setIsSlowChange(false)
@@ -555,7 +607,6 @@
 
         DisplayBrightnessState expectedDisplayBrightnessState = new DisplayBrightnessState.Builder()
                 .setBrightness(brightness)
-                .setSdrBrightness(brightness)
                 .setBrightnessReason(brightnessReason)
                 .setDisplayBrightnessStrategyName(mAutomaticBrightnessStrategy.getName())
                 .setIsSlowChange(false)
@@ -595,7 +646,6 @@
 
         DisplayBrightnessState expectedDisplayBrightnessState = new DisplayBrightnessState.Builder()
                 .setBrightness(brightness)
-                .setSdrBrightness(brightness)
                 .setBrightnessReason(brightnessReason)
                 .setDisplayBrightnessStrategyName(mAutomaticBrightnessStrategy.getName())
                 .setIsSlowChange(true)
@@ -635,7 +685,6 @@
 
         DisplayBrightnessState expectedDisplayBrightnessState = new DisplayBrightnessState.Builder()
                 .setBrightness(brightness)
-                .setSdrBrightness(brightness)
                 .setBrightnessReason(brightnessReason)
                 .setDisplayBrightnessStrategyName(mAutomaticBrightnessStrategy.getName())
                 .setIsSlowChange(false)
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/BoostBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/BoostBrightnessStrategyTest.java
index 3534325..275bb3ef 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/BoostBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/BoostBrightnessStrategyTest.java
@@ -55,7 +55,6 @@
                 new DisplayBrightnessState.Builder()
                         .setBrightness(PowerManager.BRIGHTNESS_MAX)
                         .setBrightnessReason(brightnessReason)
-                        .setSdrBrightness(PowerManager.BRIGHTNESS_MAX)
                         .setDisplayBrightnessStrategyName(mBoostBrightnessStrategy.getName())
                         .build();
         DisplayBrightnessState updatedDisplayBrightnessState =
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/DozeBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/DozeBrightnessStrategyTest.java
index bd6d8be..23e447c 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/DozeBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/DozeBrightnessStrategyTest.java
@@ -52,7 +52,6 @@
                 new DisplayBrightnessState.Builder()
                         .setBrightness(dozeScreenBrightness)
                         .setBrightnessReason(brightnessReason)
-                        .setSdrBrightness(dozeScreenBrightness)
                         .setDisplayBrightnessStrategyName(mDozeBrightnessModeStrategy.getName())
                         .build();
         DisplayBrightnessState updatedDisplayBrightnessState =
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/FallbackBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/FallbackBrightnessStrategyTest.java
index 4cae35d..c4a5790 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/FallbackBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/FallbackBrightnessStrategyTest.java
@@ -54,7 +54,6 @@
                 new DisplayBrightnessState.Builder()
                         .setBrightness(currentBrightness)
                         .setBrightnessReason(brightnessReason)
-                        .setSdrBrightness(currentBrightness)
                         .setDisplayBrightnessStrategyName(mFallbackBrightnessStrategy.getName())
                         .setShouldUpdateScreenBrightnessSetting(true)
                         .setIsUserInitiatedChange(true)
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/FollowerBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/FollowerBrightnessStrategyTest.java
index fdaf8f6..c01f96e 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/FollowerBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/FollowerBrightnessStrategyTest.java
@@ -55,7 +55,6 @@
                 new DisplayBrightnessState.Builder()
                         .setBrightness(brightnessToFollow)
                         .setBrightnessReason(brightnessReason)
-                        .setSdrBrightness(brightnessToFollow)
                         .setDisplayBrightnessStrategyName(mFollowerBrightnessStrategy.getName())
                         .setIsSlowChange(slowChange)
                         .build();
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/OffloadBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/OffloadBrightnessStrategyTest.java
index e3c2760..9fb2afa 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/OffloadBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/OffloadBrightnessStrategyTest.java
@@ -66,7 +66,6 @@
                 new DisplayBrightnessState.Builder()
                         .setBrightness(brightness)
                         .setBrightnessReason(brightnessReason)
-                        .setSdrBrightness(brightness)
                         .setDisplayBrightnessStrategyName(mOffloadBrightnessStrategy.getName())
                         .setShouldUpdateScreenBrightnessSetting(true)
                         .build();
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/OverrideBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/OverrideBrightnessStrategyTest.java
index ebe407b..e8b4c06 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/OverrideBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/OverrideBrightnessStrategyTest.java
@@ -55,7 +55,6 @@
                 new DisplayBrightnessState.Builder()
                         .setBrightness(overrideBrightness)
                         .setBrightnessReason(brightnessReason)
-                        .setSdrBrightness(overrideBrightness)
                         .setDisplayBrightnessStrategyName(mOverrideBrightnessStrategy.getName())
                         .build();
         DisplayBrightnessState updatedDisplayBrightnessState =
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategyTest.java
index 4bad569..38709ec 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategyTest.java
@@ -51,7 +51,6 @@
         DisplayBrightnessState expectedDisplayBrightnessState =
                 new DisplayBrightnessState.Builder()
                         .setBrightness(PowerManager.BRIGHTNESS_OFF_FLOAT)
-                        .setSdrBrightness(PowerManager.BRIGHTNESS_OFF_FLOAT)
                         .setBrightnessReason(brightnessReason)
                         .setDisplayBrightnessStrategyName(mScreenOffBrightnessModeStrategy
                                 .getName())
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategyTest.java
index 5410a20..f523b6a 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategyTest.java
@@ -55,7 +55,6 @@
                 new DisplayBrightnessState.Builder()
                         .setBrightness(temporaryBrightness)
                         .setBrightnessReason(brightnessReason)
-                        .setSdrBrightness(temporaryBrightness)
                         .setDisplayBrightnessStrategyName(mTemporaryBrightnessStrategy.getName())
                         .build();
         DisplayBrightnessState updatedDisplayBrightnessState =
diff --git a/services/tests/dreamservicetests/AndroidManifest.xml b/services/tests/dreamservicetests/AndroidManifest.xml
index 6092ef6..449521b 100644
--- a/services/tests/dreamservicetests/AndroidManifest.xml
+++ b/services/tests/dreamservicetests/AndroidManifest.xml
@@ -53,6 +53,35 @@
                 android:name="android.service.dream"
                 android:resource="@xml/test_dream_metadata_invalid" />
         </service>
+
+        <service
+            android:name="com.android.server.dreams.TestDreamServiceWithNonexistentSettings"
+            android:exported="false"
+            android:label="Test Dream" >
+            <intent-filter>
+                <action android:name="android.service.dreams.DreamService" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data
+                android:name="android.service.dream"
+                android:resource="@xml/test_dream_metadata_nonexistent_settings" />
+        </service>
+
+        <service
+            android:name="com.android.server.dreams.TestDreamServiceNoPackageNonexistentSettings"
+            android:exported="false"
+            android:label="Test Dream" >
+            <intent-filter>
+                <action android:name="android.service.dreams.DreamService" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data
+                android:name="android.service.dream"
+                android:resource="@xml/test_dream_metadata_nopackage_nonexistent_settings" />
+        </service>
+
+        <activity android:name=".TestDreamSettingsActivity">
+        </activity>
     </application>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/services/tests/dreamservicetests/res/xml/test_dream_metadata_nonexistent_settings.xml b/services/tests/dreamservicetests/res/xml/test_dream_metadata_nonexistent_settings.xml
new file mode 100644
index 0000000..f91f058
--- /dev/null
+++ b/services/tests/dreamservicetests/res/xml/test_dream_metadata_nonexistent_settings.xml
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!-- The settings activity does not exist, which is invalid. -->
+<dream xmlns:android="http://schemas.android.com/apk/res/android"
+    android:settingsActivity="com.android.frameworks.dreamservicetests/.TestDreamSettingsActivityNonexistent"
+    android:showClockAndComplications="false"/>
diff --git a/services/tests/dreamservicetests/res/xml/test_dream_metadata_nopackage_nonexistent_settings.xml b/services/tests/dreamservicetests/res/xml/test_dream_metadata_nopackage_nonexistent_settings.xml
new file mode 100644
index 0000000..24032c9
--- /dev/null
+++ b/services/tests/dreamservicetests/res/xml/test_dream_metadata_nopackage_nonexistent_settings.xml
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!-- The settings activity's ComponentName is invalid. -->
+<dream xmlns:android="http://schemas.android.com/apk/res/android"
+    android:settingsActivity="com.android.frameworks.dreamservicetests.TestDreamSettingsActivityNonexistentNoPackage"
+    android:showClockAndComplications="false"/>
diff --git a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
index b98af6b..b4e1abf 100644
--- a/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
+++ b/services/tests/dreamservicetests/src/com/android/server/dreams/DreamServiceTest.java
@@ -91,6 +91,28 @@
     }
 
     @Test
+    public void testMetadataParsing_nonexistentSettingsActivity()
+            throws PackageManager.NameNotFoundException {
+        final String testDreamClassName =
+                "com.android.server.dreams.TestDreamServiceWithNonexistentSettings";
+        final DreamService.DreamMetadata metadata = getDreamMetadata(testDreamClassName);
+
+        assertThat(metadata.settingsActivity).isNull();
+        assertThat(metadata.dreamCategory).isEqualTo(DreamService.DREAM_CATEGORY_DEFAULT);
+    }
+
+    @Test
+    public void testMetadataParsing_noPackage_nonexistentSettingsActivity()
+            throws PackageManager.NameNotFoundException {
+        final String testDreamClassName =
+                "com.android.server.dreams.TestDreamServiceNoPackageNonexistentSettings";
+        final DreamService.DreamMetadata metadata = getDreamMetadata(testDreamClassName);
+
+        assertThat(metadata.settingsActivity).isNull();
+        assertThat(metadata.dreamCategory).isEqualTo(DreamService.DREAM_CATEGORY_DEFAULT);
+    }
+
+    @Test
     public void testMetadataParsing_exceptionReading() {
         final PackageManager packageManager = Mockito.mock(PackageManager.class);
         final ServiceInfo serviceInfo = Mockito.mock(ServiceInfo.class);
diff --git a/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamEnvironment.java b/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamEnvironment.java
index 3d03bf2..e2b93ae 100644
--- a/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamEnvironment.java
+++ b/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamEnvironment.java
@@ -205,7 +205,7 @@
 
         @Override
         public DreamOverlayConnectionHandler createOverlayConnection(
-                ComponentName overlayComponent) {
+                ComponentName overlayComponent, Runnable onDisconnected) {
             return mDreamOverlayConnectionHandler;
         }
 
diff --git a/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamSettingsActivity.java b/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamSettingsActivity.java
new file mode 100644
index 0000000..bb8db8a
--- /dev/null
+++ b/services/tests/dreamservicetests/src/com/android/server/dreams/TestDreamSettingsActivity.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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;
+
+public class TestDreamSettingsActivity {
+}
diff --git a/services/tests/mockingservicestests/src/android/service/dreams/DreamOverlayConnectionHandlerTest.java b/services/tests/mockingservicestests/src/android/service/dreams/DreamOverlayConnectionHandlerTest.java
index 22d7e73..3e65585 100644
--- a/services/tests/mockingservicestests/src/android/service/dreams/DreamOverlayConnectionHandlerTest.java
+++ b/services/tests/mockingservicestests/src/android/service/dreams/DreamOverlayConnectionHandlerTest.java
@@ -49,10 +49,6 @@
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class DreamOverlayConnectionHandlerTest {
-    private static final int MIN_CONNECTION_DURATION_MS = 100;
-    private static final int MAX_RECONNECT_ATTEMPTS = 3;
-    private static final int BASE_RECONNECT_DELAY_MS = 50;
-
     @Mock
     private Context mContext;
     @Mock
@@ -63,6 +59,8 @@
     private IDreamOverlay mOverlayService;
     @Mock
     private IDreamOverlayClient mOverlayClient;
+    @Mock
+    private Runnable mOnDisconnectRunnable;
 
     private TestLooper mTestLooper;
     private DreamOverlayConnectionHandler mDreamOverlayConnectionHandler;
@@ -75,9 +73,7 @@
                 mContext,
                 mTestLooper.getLooper(),
                 mServiceIntent,
-                MIN_CONNECTION_DURATION_MS,
-                MAX_RECONNECT_ATTEMPTS,
-                BASE_RECONNECT_DELAY_MS,
+                mOnDisconnectRunnable,
                 new TestInjector(mConnection));
     }
 
@@ -119,12 +115,14 @@
         mTestLooper.dispatchAll();
         // No client yet, so we shouldn't have executed
         verify(consumer, never()).accept(mOverlayClient);
+        verify(mOnDisconnectRunnable, never()).run();
 
         provideClient();
         // Service disconnected before looper could handle the message.
         disconnectService();
         mTestLooper.dispatchAll();
         verify(consumer, never()).accept(mOverlayClient);
+        verify(mOnDisconnectRunnable).run();
     }
 
     @Test
@@ -237,8 +235,7 @@
 
         @Override
         public PersistentServiceConnection<IDreamOverlay> buildConnection(Context context,
-                Handler handler, Intent serviceIntent, int minConnectionDurationMs,
-                int maxReconnectAttempts, int baseReconnectDelayMs) {
+                Handler handler, Intent serviceIntent) {
             return mConnection;
         }
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/UserWakeupStoreTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/UserWakeupStoreTest.java
index 75e8e68..72883e2 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/UserWakeupStoreTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/UserWakeupStoreTest.java
@@ -134,6 +134,18 @@
     }
 
     @Test
+    public void testOnUserStarting_userIsRemovedFromTheStore() {
+        mUserWakeupStore.addUserWakeup(USER_ID_1, TEST_TIMESTAMP - 19_000);
+        mUserWakeupStore.addUserWakeup(USER_ID_2, TEST_TIMESTAMP - 7_000);
+        mUserWakeupStore.addUserWakeup(USER_ID_3, TEST_TIMESTAMP - 13_000);
+        assertEquals(3, mUserWakeupStore.getUserIdsToWakeup(TEST_TIMESTAMP).length);
+        mUserWakeupStore.onUserStarting(USER_ID_3);
+        // getWakeupTimeForUser returns negative wakeup time if there is no entry for user.
+        assertEquals(-1, mUserWakeupStore.getWakeupTimeForUser(USER_ID_3));
+        assertEquals(2, mUserWakeupStore.getUserIdsToWakeup(TEST_TIMESTAMP).length);
+    }
+
+    @Test
     public void testGetNextUserWakeup() {
         mUserWakeupStore.addUserWakeup(USER_ID_1, TEST_TIMESTAMP - 19_000);
         mUserWakeupStore.addUserWakeup(USER_ID_2, TEST_TIMESTAMP - 3_000);
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 488ce66..6366f24 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -72,14 +72,12 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.AdditionalAnswers.answer;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyBoolean;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doCallRealMethod;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
@@ -486,27 +484,22 @@
                 MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
         WindowProcessController wpc = app.getWindowProcessController();
         doReturn(true).when(wpc).hasActivities();
-        doAnswer(answer(callback -> {
-            Field field = callback.getClass().getDeclaredField("adj");
-            field.set(callback, VISIBLE_APP_ADJ);
-            field = callback.getClass().getDeclaredField("foregroundActivities");
-            field.set(callback, true);
-            field = callback.getClass().getDeclaredField("procState");
-            field.set(callback, PROCESS_STATE_TOP);
-            field = callback.getClass().getDeclaredField("schedGroup");
-            field.set(callback, SCHED_GROUP_TOP_APP);
-            field = callback.getClass().getDeclaredField("mAdjType");
-            field.set(callback, "vis-activity");
-            return 0;
-        })).when(wpc).computeOomAdjFromActivities(
-                any(WindowProcessController.ComputeOomAdjCallback.class));
+        doReturn(WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE)
+                .when(wpc).getActivityStateFlags();
         mService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE);
         updateOomAdj(app);
 
-        assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ, SCHED_GROUP_TOP_APP);
+        assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ, SCHED_GROUP_DEFAULT);
         assertFalse(app.mState.isCached());
         assertFalse(app.mState.isEmpty());
         assertEquals("vis-activity", app.mState.getAdjType());
+
+        doReturn(WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE
+                | WindowProcessController.ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN)
+                .when(wpc).getActivityStateFlags();
+        updateOomAdj(app);
+        assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ, SCHED_GROUP_TOP_APP);
+        assertEquals("resumed-split-screen-activity", app.mState.getAdjType());
     }
 
     @SuppressWarnings("GuardedBy")
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/gnss/GnssLocationProviderTest.java b/services/tests/mockingservicestests/src/com/android/server/location/gnss/GnssLocationProviderTest.java
deleted file mode 100644
index c5e6824..0000000
--- a/services/tests/mockingservicestests/src/com/android/server/location/gnss/GnssLocationProviderTest.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.location.gnss;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-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 android.app.AlarmManager;
-import android.app.AppOpsManager;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.location.GnssCapabilities;
-import android.location.LocationManager;
-import android.location.LocationManagerInternal;
-import android.location.flags.Flags;
-import android.location.provider.ProviderRequest;
-import android.os.PowerManager;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.platform.test.annotations.Presubmit;
-import android.platform.test.flag.junit.SetFlagsRule;
-import android.provider.Settings;
-import android.telephony.TelephonyManager;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.modules.utils.testing.ExtendedMockitoRule;
-import com.android.server.LocalServices;
-import com.android.server.location.gnss.hal.FakeGnssHal;
-import com.android.server.location.gnss.hal.GnssNative;
-import com.android.server.location.injector.Injector;
-import com.android.server.location.injector.TestInjector;
-import com.android.server.timedetector.TimeDetectorInternal;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.quality.Strictness;
-
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.Set;
-
-@Presubmit
-@androidx.test.filters.SmallTest
-@RunWith(AndroidJUnit4.class)
-public class GnssLocationProviderTest {
-
-    @Rule
-    public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
-            .setStrictness(Strictness.WARN)
-            .mockStatic(Settings.Global.class)
-            .build();
-    @Rule
-    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
-    private @Mock Context mContext;
-    private @Mock LocationManagerInternal mLocationManagerInternal;
-    private @Mock LocationManager mLocationManager;
-    private @Mock TimeDetectorInternal mTimeDetectorInternal;
-    private @Mock GnssConfiguration mMockConfiguration;
-    private @Mock GnssMetrics mGnssMetrics;
-    private @Mock PowerManager mPowerManager;
-    private @Mock TelephonyManager mTelephonyManager;
-    private @Mock AppOpsManager mAppOpsManager;
-    private @Mock AlarmManager mAlarmManager;
-    private @Mock PowerManager.WakeLock mWakeLock;
-    private @Mock ContentResolver mContentResolver;
-    private @Mock UserManager mUserManager;
-    private @Mock UserHandle mUserHandle;
-    private Set<UserHandle> mUserHandleSet = new HashSet<>();
-
-    private GnssNative mGnssNative;
-
-    private GnssLocationProvider mTestProvider;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        doReturn("mypackage").when(mContext).getPackageName();
-        doReturn("attribution").when(mContext).getAttributionTag();
-        doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class);
-        doReturn(mPowerManager).when(mContext).getSystemService("power");
-        doReturn(mAppOpsManager).when(mContext).getSystemService(AppOpsManager.class);
-        doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
-        doReturn(mAlarmManager).when(mContext).getSystemService(Context.ALARM_SERVICE);
-        doReturn(mLocationManager).when(mContext).getSystemService(LocationManager.class);
-        doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
-        mUserHandleSet.add(mUserHandle);
-        doReturn(true).when(mLocationManager).isLocationEnabledForUser(eq(mUserHandle));
-        doReturn(mUserHandleSet).when(mUserManager).getVisibleUsers();
-        doReturn(mContentResolver).when(mContext).getContentResolver();
-        doReturn(mWakeLock).when(mPowerManager).newWakeLock(anyInt(), anyString());
-        LocalServices.addService(LocationManagerInternal.class, mLocationManagerInternal);
-        LocalServices.addService(TimeDetectorInternal.class, mTimeDetectorInternal);
-        FakeGnssHal fakeGnssHal = new FakeGnssHal();
-        GnssNative.setGnssHalForTest(fakeGnssHal);
-        Injector injector = new TestInjector(mContext);
-        mGnssNative = spy(Objects.requireNonNull(
-                GnssNative.create(injector, mMockConfiguration)));
-        doReturn(true).when(mGnssNative).init();
-        GnssCapabilities gnssCapabilities = new GnssCapabilities.Builder().setHasScheduling(
-                true).build();
-        doReturn(gnssCapabilities).when(mGnssNative).getCapabilities();
-
-        mTestProvider = new GnssLocationProvider(mContext, mGnssNative, mGnssMetrics);
-        mGnssNative.register();
-    }
-
-    @After
-    public void tearDown() {
-        LocalServices.removeServiceForTest(LocationManagerInternal.class);
-        LocalServices.removeServiceForTest(TimeDetectorInternal.class);
-    }
-
-    @Test
-    public void testStartNavigating() {
-        ProviderRequest providerRequest = new ProviderRequest.Builder().setIntervalMillis(
-                0).build();
-
-        mTestProvider.onSetRequest(providerRequest);
-        verify(mGnssNative).start();
-    }
-
-    @Test
-    public void testUpdateRequirements_sameRequest() {
-        mSetFlagsRule.enableFlags(Flags.FLAG_GNSS_CALL_STOP_BEFORE_SET_POSITION_MODE);
-        ProviderRequest providerRequest = new ProviderRequest.Builder().setIntervalMillis(
-                0).build();
-
-        mTestProvider.onSetRequest(providerRequest);
-        verify(mGnssNative).start();
-
-        // set the same request
-        mTestProvider.onSetRequest(providerRequest);
-        verify(mGnssNative, never()).stop();
-        verify(mGnssNative, times(1)).start();
-    }
-
-    @Test
-    public void testUpdateRequirements_differentRequest() {
-        mSetFlagsRule.enableFlags(Flags.FLAG_GNSS_CALL_STOP_BEFORE_SET_POSITION_MODE);
-        ProviderRequest providerRequest = new ProviderRequest.Builder().setIntervalMillis(
-                0).build();
-
-        mTestProvider.onSetRequest(providerRequest);
-        verify(mGnssNative).start();
-
-        // set a different request
-        providerRequest = new ProviderRequest.Builder().setIntervalMillis(2000).build();
-        mTestProvider.onSetRequest(providerRequest);
-        verify(mGnssNative).stop();
-        verify(mGnssNative, times(2)).start();
-    }
-}
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundUserSoundNotifierTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundUserSoundNotifierTest.java
new file mode 100644
index 0000000..a82658b
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundUserSoundNotifierTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.media.AudioAttributes;
+import android.media.AudioFocusInfo;
+import android.media.AudioManager;
+import android.os.Build;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.ArraySet;
+
+import org.junit.After;
+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.MockitoAnnotations;
+
+@RunWith(JUnit4.class)
+
+public class BackgroundUserSoundNotifierTest {
+    private final Context mRealContext = androidx.test.InstrumentationRegistry.getInstrumentation()
+            .getTargetContext();
+    private Context mSpiedContext;
+    private BackgroundUserSoundNotifier mBackgroundUserSoundNotifier;
+
+    private UserManager mUserManager;
+    private ArraySet<Integer> mUsersToRemove;
+
+    @Mock
+    private NotificationManager mNotificationManager;
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mSpiedContext = spy(mRealContext);
+        mUsersToRemove = new ArraySet<>();
+        mUserManager = UserManager.get(mRealContext);
+        doReturn(mNotificationManager)
+                .when(mSpiedContext).getSystemService(NotificationManager.class);
+        mBackgroundUserSoundNotifier = new BackgroundUserSoundNotifier(mSpiedContext);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mUsersToRemove.stream().toList().forEach(this::removeUser);
+    }
+    @Test
+    public void testAlarmOnBackgroundUser_ForegroundUserNotified() throws RemoteException {
+        AudioAttributes aa = new AudioAttributes.Builder()
+                .setUsage(AudioAttributes.USAGE_ALARM).build();
+        UserInfo user = createUser("User",
+                UserManager.USER_TYPE_FULL_SECONDARY,
+                0);
+        final int fgUserId = mSpiedContext.getUserId();
+        final int bgUserUid = user.id * 100000;
+        doReturn(UserHandle.of(fgUserId)).when(mSpiedContext).getUser();
+        AudioFocusInfo afi = new AudioFocusInfo(aa, bgUserUid, "",
+                /* packageName= */ "com.android.car.audio", AudioManager.AUDIOFOCUS_GAIN,
+                AudioManager.AUDIOFOCUS_NONE, /* flags= */ 0, Build.VERSION.SDK_INT);
+        clearInvocations(mNotificationManager);
+        mBackgroundUserSoundNotifier.notifyForegroundUserAboutSoundIfNecessary(afi, mSpiedContext);
+        verify(mNotificationManager)
+                .notifyAsUser(eq(BackgroundUserSoundNotifier.class.getSimpleName()),
+                        eq(afi.getClientUid()), any(Notification.class),
+                        eq(UserHandle.of(fgUserId)));
+    }
+
+    @Test
+    public void testMediaOnBackgroundUser_ForegroundUserNotNotified() throws RemoteException {
+        AudioAttributes aa = new AudioAttributes.Builder()
+                .setUsage(AudioAttributes.USAGE_MEDIA).build();
+        UserInfo user = createUser("User", UserManager.USER_TYPE_FULL_SECONDARY, 0);
+        final int bgUserUid = mSpiedContext.getUserId() * 100000;
+        AudioFocusInfo afi = new AudioFocusInfo(aa, bgUserUid, "",
+                /* packageName= */ "com.android.car.audio", AudioManager.AUDIOFOCUS_GAIN,
+                AudioManager.AUDIOFOCUS_NONE, /* flags= */ 0, Build.VERSION.SDK_INT);
+        clearInvocations(mNotificationManager);
+        mBackgroundUserSoundNotifier.notifyForegroundUserAboutSoundIfNecessary(afi, mSpiedContext);
+        verifyZeroInteractions(mNotificationManager);
+    }
+
+    @Test
+    public void testAlarmOnForegroundUser_ForegroundUserNotNotified() throws RemoteException {
+        AudioAttributes aa = new AudioAttributes.Builder()
+                .setUsage(AudioAttributes.USAGE_ALARM).build();
+        final int fgUserId = mSpiedContext.getUserId();
+        final int fgUserUid = fgUserId * 100000;
+        doReturn(UserHandle.of(fgUserId)).when(mSpiedContext).getUser();
+        AudioFocusInfo afi = new AudioFocusInfo(aa, fgUserUid, "", /* packageName= */ "",
+                AudioManager.AUDIOFOCUS_GAIN, AudioManager.AUDIOFOCUS_NONE, /* flags= */ 0,
+                Build.VERSION.SDK_INT);
+        clearInvocations(mNotificationManager);
+        mBackgroundUserSoundNotifier.notifyForegroundUserAboutSoundIfNecessary(afi, mSpiedContext);
+        verifyZeroInteractions(mNotificationManager);
+    }
+
+
+    private UserInfo createUser(String name, String userType, int flags) {
+        UserInfo user = mUserManager.createUser(name, userType, flags);
+        if (user != null) {
+            mUsersToRemove.add(user.id);
+        }
+        return user;
+    }
+    private void removeUser(int userId) {
+        mUserManager.removeUser(userId);
+    }
+
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
index 79f1574..37d87c4e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
@@ -683,15 +683,14 @@
         UserInfo privateProfileUser =
                 mSpiedUms.createProfileForUserEvenWhenDisallowedWithThrow(PRIVATE_PROFILE_NAME,
                         USER_TYPE_PROFILE_PRIVATE, 0, mainUser, null);
-        Mockito.doNothing().when(mSpiedUms).scheduleMessageToAutoLockPrivateSpace(
-                eq(privateProfileUser.getUserHandle().getIdentifier()), any(),
-                anyLong());
+        Mockito.doNothing().when(mSpiedUms).scheduleAlarmToAutoLockPrivateSpace(
+                eq(privateProfileUser.getUserHandle().getIdentifier()), anyLong());
 
 
-        mSpiedUms.maybeScheduleMessageToAutoLockPrivateSpace();
+        mSpiedUms.maybeScheduleAlarmToAutoLockPrivateSpace();
 
-        Mockito.verify(mSpiedUms).scheduleMessageToAutoLockPrivateSpace(
-                eq(privateProfileUser.getUserHandle().getIdentifier()), any(), anyLong());
+        Mockito.verify(mSpiedUms).scheduleAlarmToAutoLockPrivateSpace(
+                eq(privateProfileUser.getUserHandle().getIdentifier()), anyLong());
     }
 
     @Test
diff --git a/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java b/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java
index 4460c6a..ce2bb95 100644
--- a/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java
+++ b/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java
@@ -31,6 +31,7 @@
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
+import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.res.Resources;
 import android.hardware.SensorManager;
@@ -41,7 +42,6 @@
 import android.os.Looper;
 import android.os.PowerManager;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.VibrationAttributes;
 import android.os.Vibrator;
 import android.os.test.TestLooper;
@@ -82,8 +82,12 @@
     @Mock private StatusBarManagerInternal mStatusBarManagerInternal;
     @Mock private WakeLockLog mWakeLockLog;
 
+    @Mock private IBatteryStats mBatteryStats;
+
     @Mock private PowerManagerFlags mPowerManagerFlags;
 
+    @Mock private AppOpsManager mAppOpsManager;
+
     private PowerManagerService mService;
     private Context mContextSpy;
     private Resources mResourcesSpy;
@@ -230,7 +234,7 @@
     public void testOnWakeLockListener_RemoteException_NoRethrow() {
         when(mPowerManagerFlags.improveWakelockLatency()).thenReturn(true);
         createNotifier();
-
+        clearInvocations(mWakeLockLog, mBatteryStats, mAppOpsManager);
         IWakeLockCallback exceptingCallback = new IWakeLockCallback.Stub() {
             @Override public void onStateChanged(boolean enabled) throws RemoteException {
                 throw new RemoteException("Just testing");
@@ -245,6 +249,7 @@
         verifyZeroInteractions(mWakeLockLog);
         mTestLooper.dispatchAll();
         verify(mWakeLockLog).onWakeLockReleased("wakelockTag", uid, 1);
+
         mNotifier.onWakeLockAcquired(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag",
                 "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null,
                 exceptingCallback);
@@ -277,6 +282,115 @@
         verify(mWakeLockLog).onWakeLockReleased("wakelockTag", uid, -1);
     }
 
+
+    @Test
+    public void testOnWakeLockListener_FullWakeLock_ProcessesOnHandler() throws RemoteException {
+        when(mPowerManagerFlags.improveWakelockLatency()).thenReturn(true);
+        createNotifier();
+
+        IWakeLockCallback exceptingCallback = new IWakeLockCallback.Stub() {
+            @Override public void onStateChanged(boolean enabled) throws RemoteException {
+                throw new RemoteException("Just testing");
+            }
+        };
+        clearInvocations(mWakeLockLog, mBatteryStats, mAppOpsManager);
+
+        final int uid = 1234;
+        final int pid = 5678;
+
+        // Release the wakelock
+        mNotifier.onWakeLockReleased(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag",
+                "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null,
+                exceptingCallback);
+
+        // No interaction because we expect that to happen in async
+        verifyZeroInteractions(mWakeLockLog, mBatteryStats, mAppOpsManager);
+
+        // Progressing the looper, and validating all the interactions
+        mTestLooper.dispatchAll();
+        verify(mWakeLockLog).onWakeLockReleased("wakelockTag", uid, 1);
+        verify(mBatteryStats).noteStopWakelock(uid, pid, "wakelockTag", /* historyTag= */ null,
+                BatteryStats.WAKE_TYPE_FULL);
+        verify(mAppOpsManager).finishOp(AppOpsManager.OP_WAKE_LOCK, uid,
+                "my.package.name", null);
+
+        clearInvocations(mWakeLockLog, mBatteryStats, mAppOpsManager);
+
+        // Acquire the wakelock
+        mNotifier.onWakeLockAcquired(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag",
+                "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null,
+                exceptingCallback);
+
+        // No interaction because we expect that to happen in async
+        verifyNoMoreInteractions(mWakeLockLog, mBatteryStats, mAppOpsManager);
+
+        // Progressing the looper, and validating all the interactions
+        mTestLooper.dispatchAll();
+        verify(mWakeLockLog).onWakeLockAcquired("wakelockTag", uid,
+                PowerManager.SCREEN_BRIGHT_WAKE_LOCK, 1);
+        verify(mBatteryStats).noteStartWakelock(uid, pid, "wakelockTag", /* historyTag= */ null,
+                BatteryStats.WAKE_TYPE_FULL, false);
+        verify(mAppOpsManager).startOpNoThrow(AppOpsManager.OP_WAKE_LOCK, uid,
+                "my.package.name", false, null, null);
+
+        // Test with improveWakelockLatency flag false, hence the wakelock log will run on the same
+        // thread
+        clearInvocations(mWakeLockLog, mBatteryStats, mAppOpsManager);
+        when(mPowerManagerFlags.improveWakelockLatency()).thenReturn(false);
+
+        mNotifier.onWakeLockAcquired(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag",
+                "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null,
+                exceptingCallback);
+        verify(mWakeLockLog).onWakeLockAcquired("wakelockTag", uid,
+                PowerManager.SCREEN_BRIGHT_WAKE_LOCK, -1);
+
+        mNotifier.onWakeLockReleased(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag",
+                "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null,
+                exceptingCallback);
+        verify(mWakeLockLog).onWakeLockReleased("wakelockTag", uid, -1);
+    }
+
+    @Test
+    public void testOnWakeLockListener_FullWakeLock_ProcessesInSync() throws RemoteException {
+        createNotifier();
+
+        IWakeLockCallback exceptingCallback = new IWakeLockCallback.Stub() {
+            @Override public void onStateChanged(boolean enabled) throws RemoteException {
+                throw new RemoteException("Just testing");
+            }
+        };
+        clearInvocations(mWakeLockLog, mBatteryStats, mAppOpsManager);
+
+        final int uid = 1234;
+        final int pid = 5678;
+
+        // Release the wakelock
+        mNotifier.onWakeLockReleased(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag",
+                "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null,
+                exceptingCallback);
+
+        verify(mWakeLockLog).onWakeLockReleased("wakelockTag", uid, -1);
+        verify(mBatteryStats).noteStopWakelock(uid, pid, "wakelockTag", /* historyTag= */ null,
+                BatteryStats.WAKE_TYPE_FULL);
+        verify(mAppOpsManager).finishOp(AppOpsManager.OP_WAKE_LOCK, uid,
+                "my.package.name", null);
+
+        clearInvocations(mWakeLockLog, mBatteryStats, mAppOpsManager);
+
+        // Acquire the wakelock
+        mNotifier.onWakeLockAcquired(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "wakelockTag",
+                "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null,
+                exceptingCallback);
+
+        mTestLooper.dispatchAll();
+        verify(mWakeLockLog).onWakeLockAcquired("wakelockTag", uid,
+                PowerManager.SCREEN_BRIGHT_WAKE_LOCK, -1);
+        verify(mBatteryStats).noteStartWakelock(uid, pid, "wakelockTag", /* historyTag= */ null,
+                BatteryStats.WAKE_TYPE_FULL, false);
+        verify(mAppOpsManager).startOpNoThrow(AppOpsManager.OP_WAKE_LOCK, uid,
+                "my.package.name", false, null, null);
+    }
+
     private final PowerManagerService.Injector mInjector = new PowerManagerService.Injector() {
         @Override
         Notifier createNotifier(Looper looper, Context context, IBatteryStats batteryStats,
@@ -365,13 +479,17 @@
             public WakeLockLog getWakeLockLog(Context context) {
                 return mWakeLockLog;
             }
+
+            @Override
+            public AppOpsManager getAppOpsManager(Context context) {
+                return mAppOpsManager;
+            }
         };
 
         mNotifier = new Notifier(
                 mTestLooper.getLooper(),
                 mContextSpy,
-                IBatteryStats.Stub.asInterface(ServiceManager.getService(
-                        BatteryStats.SERVICE_NAME)),
+                mBatteryStats,
                 mInjector.createSuspendBlocker(mService, "testBlocker"),
                 null,
                 null,
diff --git a/services/tests/powerservicetests/src/com/android/server/power/ShutdownThreadTest.java b/services/tests/powerservicetests/src/com/android/server/power/ShutdownThreadTest.java
index 62075b8..ab1b0cc 100644
--- a/services/tests/powerservicetests/src/com/android/server/power/ShutdownThreadTest.java
+++ b/services/tests/powerservicetests/src/com/android/server/power/ShutdownThreadTest.java
@@ -17,11 +17,10 @@
 package com.android.server.power;
 
 import static com.android.server.power.ShutdownThread.DEFAULT_SHUTDOWN_VIBRATE_MS;
+
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -42,7 +41,6 @@
 
 import java.io.File;
 import java.io.FileOutputStream;
-import java.io.IOException;
 
 /**
  * Tests for {@link com.android.server.power.ShutdownThread}
@@ -88,6 +86,7 @@
     @Mock private VibratorInfo mVibratorInfoMock;
 
     private String mDefaultShutdownVibrationFilePath;
+    private boolean mShutdownVibrationDisabled;
     private long mLastSleepDurationMs;
 
     private ShutdownThread mShutdownThread;
@@ -168,6 +167,17 @@
                 .vibrate(any(VibrationEffect.class), any(VibrationAttributes.class));
     }
 
+    @Test
+    public void testVibrationDisabled() throws Exception {
+        setShutdownVibrationFileContent(CLICK_VIB_SERIALIZATION);
+        mShutdownVibrationDisabled = true;
+
+        mShutdownThread.playShutdownVibration(mContextMock);
+
+        verify(mVibratorMock, never())
+                .vibrate(any(VibrationEffect.class), any(VibrationAttributes.class));
+    }
+
     private void assertShutdownVibration(VibrationEffect effect, long vibrationSleepDuration)
             throws Exception {
         verify(mVibratorMock).vibrate(
@@ -214,5 +224,10 @@
         public void sleep(long durationMs) {
             mLastSleepDurationMs = durationMs;
         }
+
+        @Override
+        public boolean isShutdownVibrationDisabled(Context context) {
+            return mShutdownVibrationDisabled;
+        }
     }
 }
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/AggregatedPowerStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/AggregatedPowerStatsTest.java
index 9975190..a4688cc 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/AggregatedPowerStatsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/AggregatedPowerStatsTest.java
@@ -42,6 +42,7 @@
 @SmallTest
 public class AggregatedPowerStatsTest {
     private static final int TEST_POWER_COMPONENT = 1077;
+    private static final int CUSTOM_POWER_COMPONENT = 1042;
     private static final int APP_1 = 27;
     private static final int APP_2 = 42;
     private static final int COMPONENT_STATE_0 = 0;
@@ -63,6 +64,20 @@
                         AggregatedPowerStatsConfig.STATE_SCREEN,
                         AggregatedPowerStatsConfig.STATE_PROCESS_STATE);
 
+        mAggregatedPowerStatsConfig.trackCustomPowerComponents(
+                        () -> new PowerStatsProcessor() {
+                            @Override
+                            void finish(PowerComponentAggregatedPowerStats stats,
+                                    long timestampMs) {
+                            }
+                        })
+                .trackDeviceStates(
+                        AggregatedPowerStatsConfig.STATE_POWER,
+                        AggregatedPowerStatsConfig.STATE_SCREEN)
+                .trackUidStates(
+                        AggregatedPowerStatsConfig.STATE_POWER,
+                        AggregatedPowerStatsConfig.STATE_SCREEN,
+                        AggregatedPowerStatsConfig.STATE_PROCESS_STATE);
         SparseArray<String> stateLabels = new SparseArray<>();
         stateLabels.put(COMPONENT_STATE_1, "one");
         mPowerComponentDescriptor = new PowerStats.Descriptor(TEST_POWER_COMPONENT, "fan", 2,
@@ -137,6 +152,13 @@
         ps.uidStats.put(APP_2, new long[]{100, 200, 300});
 
         stats.addPowerStats(ps, 5000);
+
+        PowerStats custom = new PowerStats(
+                new PowerStats.Descriptor(CUSTOM_POWER_COMPONENT, "cu570m", 1, null, 0, 2,
+                        new PersistableBundle()));
+        custom.stats = new long[]{123};
+        custom.uidStats.put(APP_1, new long[]{500, 600});
+        stats.addPowerStats(custom, 6000);
         return stats;
     }
 
@@ -149,12 +171,12 @@
         assertThat(descriptor.uidStatsArrayLength).isEqualTo(3);
         assertThat(descriptor.extras.getString("speed")).isEqualTo("fast");
 
-        assertThat(getDeviceStats(stats,
+        assertThat(getDeviceStats(stats, TEST_POWER_COMPONENT,
                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
                 AggregatedPowerStatsConfig.SCREEN_STATE_ON))
                 .isEqualTo(new long[]{322, 987});
 
-        assertThat(getDeviceStats(stats,
+        assertThat(getDeviceStats(stats, TEST_POWER_COMPONENT,
                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
                 AggregatedPowerStatsConfig.SCREEN_STATE_OTHER))
                 .isEqualTo(new long[]{222, 0});
@@ -185,51 +207,79 @@
                 .isEqualTo(new long[]{4500});
 
         assertThat(getUidDeviceStats(stats,
-                APP_1,
+                TEST_POWER_COMPONENT, APP_1,
                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
                 AggregatedPowerStatsConfig.SCREEN_STATE_ON,
                 BatteryConsumer.PROCESS_STATE_UNSPECIFIED))
                 .isEqualTo(new long[]{259, 0, 492});
 
         assertThat(getUidDeviceStats(stats,
-                APP_1,
+                TEST_POWER_COMPONENT, APP_1,
                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
                 AggregatedPowerStatsConfig.SCREEN_STATE_ON,
                 BatteryConsumer.PROCESS_STATE_CACHED))
                 .isEqualTo(new long[]{129, 0, 446});
 
         assertThat(getUidDeviceStats(stats,
-                APP_1,
+                TEST_POWER_COMPONENT, APP_1,
                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
                 AggregatedPowerStatsConfig.SCREEN_STATE_OTHER,
                 BatteryConsumer.PROCESS_STATE_CACHED))
                 .isEqualTo(new long[]{0, 0, 200});
 
         assertThat(getUidDeviceStats(stats,
-                APP_2,
+                TEST_POWER_COMPONENT, APP_2,
                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
                 AggregatedPowerStatsConfig.SCREEN_STATE_ON,
                 BatteryConsumer.PROCESS_STATE_UNSPECIFIED))
                 .isEqualTo(new long[]{185, 209, 418});
 
         assertThat(getUidDeviceStats(stats,
-                APP_2,
+                TEST_POWER_COMPONENT, APP_2,
                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
                 AggregatedPowerStatsConfig.SCREEN_STATE_ON,
                 BatteryConsumer.PROCESS_STATE_FOREGROUND))
                 .isEqualTo(new long[]{142, 204, 359});
 
         assertThat(getUidDeviceStats(stats,
-                APP_2,
+                TEST_POWER_COMPONENT, APP_2,
                 AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
                 AggregatedPowerStatsConfig.SCREEN_STATE_OTHER,
                 BatteryConsumer.PROCESS_STATE_BACKGROUND))
                 .isEqualTo(new long[]{50, 100, 150});
+
+        descriptor = stats.getPowerComponentStats(CUSTOM_POWER_COMPONENT)
+                .getPowerStatsDescriptor();
+        assertThat(descriptor.powerComponentId).isEqualTo(CUSTOM_POWER_COMPONENT);
+        assertThat(descriptor.statsArrayLength).isEqualTo(1);
+        assertThat(descriptor.uidStatsArrayLength).isEqualTo(2);
+
+        assertThat(getDeviceStats(stats, CUSTOM_POWER_COMPONENT,
+                AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
+                AggregatedPowerStatsConfig.SCREEN_STATE_ON))
+                .isEqualTo(new long[]{61});
+        assertThat(getDeviceStats(stats, CUSTOM_POWER_COMPONENT,
+                AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
+                AggregatedPowerStatsConfig.SCREEN_STATE_OTHER))
+                .isEqualTo(new long[]{61});
+        assertThat(getUidDeviceStats(stats,
+                CUSTOM_POWER_COMPONENT, APP_1,
+                AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
+                AggregatedPowerStatsConfig.SCREEN_STATE_ON,
+                BatteryConsumer.PROCESS_STATE_CACHED))
+                .isEqualTo(new long[]{250, 300});
+        assertThat(getUidDeviceStats(stats,
+                CUSTOM_POWER_COMPONENT, APP_1,
+                AggregatedPowerStatsConfig.POWER_STATE_BATTERY,
+                AggregatedPowerStatsConfig.SCREEN_STATE_OTHER,
+                BatteryConsumer.PROCESS_STATE_CACHED))
+                .isEqualTo(new long[]{250, 300});
     }
 
-    private static long[] getDeviceStats(AggregatedPowerStats stats, int... states) {
+    private static long[] getDeviceStats(AggregatedPowerStats stats, int powerComponentId,
+            int... states) {
         PowerComponentAggregatedPowerStats powerComponentStats =
-                stats.getPowerComponentStats(TEST_POWER_COMPONENT);
+                stats.getPowerComponentStats(powerComponentId);
         long[] out = new long[powerComponentStats.getPowerStatsDescriptor().statsArrayLength];
         powerComponentStats.getDeviceStats(out, states);
         return out;
@@ -243,9 +293,10 @@
         return out;
     }
 
-    private static long[] getUidDeviceStats(AggregatedPowerStats stats, int uid, int... states) {
+    private static long[] getUidDeviceStats(AggregatedPowerStats stats, int powerComponentId,
+            int uid, int... states) {
         PowerComponentAggregatedPowerStats powerComponentStats =
-                stats.getPowerComponentStats(TEST_POWER_COMPONENT);
+                stats.getPowerComponentStats(powerComponentId);
         long[] out = new long[powerComponentStats.getPowerStatsDescriptor().uidStatsArrayLength];
         powerComponentStats.getUidStats(out, uid, states);
         return out;
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerStatsTest.java
index 36deb08..efbd1b7 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerStatsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerStatsTest.java
@@ -30,8 +30,11 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.when;
 
+import android.hardware.power.stats.EnergyConsumerResult;
 import android.hardware.power.stats.EnergyConsumerType;
 import android.os.BatteryConsumer;
 import android.os.BatteryStats;
@@ -116,8 +119,10 @@
 
     @Test
     public void energyConsumerModel() {
-        when(mConsumedEnergyRetriever.getEnergyConsumerIds(EnergyConsumerType.CAMERA, null))
+        when(mConsumedEnergyRetriever
+                .getEnergyConsumerIds(eq((int) EnergyConsumerType.CAMERA), any()))
                 .thenReturn(new int[]{ENERGY_CONSUMER_ID});
+
         CameraPowerStatsProcessor processor = new CameraPowerStatsProcessor(
                 mStatsRule.getPowerProfile(), mUidResolver);
 
@@ -131,8 +136,8 @@
         collector.setEnabled(true);
 
         // Establish a baseline
-        when(mConsumedEnergyRetriever.getConsumedEnergyUws(new int[]{ENERGY_CONSUMER_ID}))
-                .thenReturn(new long[]{uCtoUj(10000)});
+        when(mConsumedEnergyRetriever.getConsumedEnergy(new int[]{ENERGY_CONSUMER_ID}))
+                .thenReturn(createEnergyConsumerResults(ENERGY_CONSUMER_ID, 10000));
         collector.collectAndDeliverStats();
 
         processor.noteStateChange(stats, buildHistoryItem(0, true, APP_UID1));
@@ -144,15 +149,15 @@
 
         processor.noteStateChange(stats, buildHistoryItem(6000, false, APP_UID1));
 
-        when(mConsumedEnergyRetriever.getConsumedEnergyUws(new int[]{ENERGY_CONSUMER_ID}))
-                .thenReturn(new long[]{uCtoUj(2_170_000)});
+        when(mConsumedEnergyRetriever.getConsumedEnergy(new int[]{ENERGY_CONSUMER_ID}))
+                .thenReturn(createEnergyConsumerResults(ENERGY_CONSUMER_ID, 2_170_000));
         collector.collectAndDeliverStats();
 
         processor.noteStateChange(stats, buildHistoryItem(7000, true, APP_UID2));
 
         mStatsRule.setTime(11_000, 11_000);
-        when(mConsumedEnergyRetriever.getConsumedEnergyUws(new int[]{ENERGY_CONSUMER_ID}))
-                .thenReturn(new long[]{uCtoUj(3_610_000)});
+        when(mConsumedEnergyRetriever.getConsumedEnergy(new int[]{ENERGY_CONSUMER_ID}))
+                .thenReturn(createEnergyConsumerResults(ENERGY_CONSUMER_ID, 3_610_000));
         collector.collectAndDeliverStats();
 
         processor.finish(stats, 11_000);
@@ -264,7 +269,10 @@
         return powerComponentStats;
     }
 
-    private static long uCtoUj(long uc) {
-        return (long) (uc * (double) VOLTAGE_MV / 1000);
+    private EnergyConsumerResult[] createEnergyConsumerResults(int id, long energyUWs) {
+        EnergyConsumerResult result = new EnergyConsumerResult();
+        result.id = id;
+        result.energyUWs = (long) (energyUWs * (double) VOLTAGE_MV / 1000);
+        return new EnergyConsumerResult[]{result};
     }
 }
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/CustomEnergyConsumerPowerStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CustomEnergyConsumerPowerStatsTest.java
new file mode 100644
index 0000000..7bec13f6
--- /dev/null
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CustomEnergyConsumerPowerStatsTest.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.power.stats;
+
+import static android.os.BatteryConsumer.PROCESS_STATE_BACKGROUND;
+import static android.os.BatteryConsumer.PROCESS_STATE_CACHED;
+import static android.os.BatteryConsumer.PROCESS_STATE_FOREGROUND;
+import static android.os.BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE;
+
+import static com.android.server.power.stats.AggregatedPowerStatsConfig.POWER_STATE_BATTERY;
+import static com.android.server.power.stats.AggregatedPowerStatsConfig.POWER_STATE_OTHER;
+import static com.android.server.power.stats.AggregatedPowerStatsConfig.SCREEN_STATE_ON;
+import static com.android.server.power.stats.AggregatedPowerStatsConfig.SCREEN_STATE_OTHER;
+import static com.android.server.power.stats.AggregatedPowerStatsConfig.STATE_POWER;
+import static com.android.server.power.stats.AggregatedPowerStatsConfig.STATE_PROCESS_STATE;
+import static com.android.server.power.stats.AggregatedPowerStatsConfig.STATE_SCREEN;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.hardware.power.stats.EnergyConsumerAttribution;
+import android.hardware.power.stats.EnergyConsumerResult;
+import android.hardware.power.stats.EnergyConsumerType;
+import android.os.Handler;
+import android.os.Process;
+import android.platform.test.ravenwood.RavenwoodRule;
+
+import com.android.internal.os.Clock;
+import com.android.internal.os.PowerStats;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+import java.util.function.IntSupplier;
+
+public class CustomEnergyConsumerPowerStatsTest {
+    @Rule(order = 0)
+    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
+            .setProvideMainThread(true)
+            .build();
+
+    @Rule(order = 1)
+    public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule();
+
+    public static final int ENERGY_CONSUMER_ID1 = 77;
+    public static final int ENERGY_CONSUMER_ID2 = 88;
+    private static final int VOLTAGE_MV = 3500;
+    private static final double PRECISION = 0.00001;
+    private static final int APP_UID1 = Process.FIRST_APPLICATION_UID + 42;
+    private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 101;
+    private static final EnergyConsumerPowerStatsLayout POWER_STATS_LAYOUT =
+            new EnergyConsumerPowerStatsLayout();
+
+    @Mock
+    private PowerStatsCollector.ConsumedEnergyRetriever mConsumedEnergyRetriever;
+
+    private final PowerStatsUidResolver mPowerStatsUidResolver = new PowerStatsUidResolver();
+
+    private EnergyConsumerPowerStatsCollector.Injector mInjector =
+            new EnergyConsumerPowerStatsCollector.Injector() {
+                @Override
+                public Handler getHandler() {
+                    return mStatsRule.getHandler();
+                }
+
+                @Override
+                public Clock getClock() {
+                    return mStatsRule.getMockClock();
+                }
+
+                @Override
+                public PowerStatsUidResolver getUidResolver() {
+                    return mPowerStatsUidResolver;
+                }
+
+                @Override
+                public long getPowerStatsCollectionThrottlePeriod(String powerComponentName) {
+                    return 0;
+                }
+
+                @Override
+                public PowerStatsCollector.ConsumedEnergyRetriever getConsumedEnergyRetriever() {
+                    return mConsumedEnergyRetriever;
+                }
+
+                @Override
+                public IntSupplier getVoltageSupplier() {
+                    return () -> VOLTAGE_MV;
+                }
+            };
+
+
+    private CustomEnergyConsumerPowerStatsCollector mCollector;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mCollector = new CustomEnergyConsumerPowerStatsCollector(mInjector);
+        mCollector.setEnabled(true);
+    }
+
+    @Test
+    public void collectStats() throws Exception {
+        // Establish a baseline
+        collectPowerStats(0, 10_000, 30_000,
+                createAttribution(APP_UID1, 10_000),
+                createAttribution(APP_UID2, 15_000));
+
+        List<PowerStats> results = collectPowerStats(12345, 45_000, 100_000,
+                createAttribution(APP_UID1, 24_000),
+                createAttribution(APP_UID2, 36_000));
+
+        assertThat(results).hasSize(2);
+        PowerStats ps1 = results.stream()
+                .filter(ps -> ps.descriptor.name.equals("FOO")).findAny().orElseThrow();
+        assertThat(ps1.durationMs).isEqualTo(12345);
+
+        // Energy (uWs) / (voltage (mV) / 1000) -> charge (uC)
+        assertThat(POWER_STATS_LAYOUT.getConsumedEnergy(ps1.stats, 0))
+                .isEqualTo(10000);
+        assertThat(ps1.uidStats.size()).isEqualTo(0);
+
+        PowerStats ps2 = results.stream()
+                .filter(ps -> ps.descriptor.name.equals("BAR")).findAny().orElseThrow();
+        assertThat(POWER_STATS_LAYOUT.getConsumedEnergy(ps2.stats, 0))
+                .isEqualTo(20000);
+        assertThat(ps2.uidStats.size()).isEqualTo(2);
+        assertThat(POWER_STATS_LAYOUT.getUidConsumedEnergy(ps2.uidStats.get(APP_UID1), 0))
+                .isEqualTo(14000);
+        assertThat(POWER_STATS_LAYOUT.getUidConsumedEnergy(ps2.uidStats.get(APP_UID2), 0))
+                .isEqualTo(21000);
+    }
+
+    @Test
+    public void processStats() throws Exception {
+        AggregatedPowerStats aggregatedPowerStats = createAggregatedPowerStats();
+        aggregatedPowerStats.setDeviceState(STATE_POWER, POWER_STATE_OTHER, 0);
+        aggregatedPowerStats.setDeviceState(STATE_SCREEN, SCREEN_STATE_ON, 0);
+        aggregatedPowerStats.setUidState(APP_UID1, STATE_PROCESS_STATE, PROCESS_STATE_FOREGROUND,
+                0);
+        aggregatedPowerStats.setUidState(APP_UID2, STATE_PROCESS_STATE, PROCESS_STATE_CACHED, 0);
+
+        List<PowerStats> results = collectPowerStats(0, 10_000, 30_000,
+                createAttribution(APP_UID1, 10_000),
+                createAttribution(APP_UID2, 15_000));
+        for (PowerStats powerStats : results) {
+            aggregatedPowerStats.addPowerStats(powerStats, 0);
+        }
+
+        aggregatedPowerStats.setDeviceState(STATE_POWER, POWER_STATE_BATTERY, 10_000);
+        aggregatedPowerStats.setDeviceState(STATE_SCREEN, SCREEN_STATE_OTHER, 10_000);
+        aggregatedPowerStats.setUidState(APP_UID1, STATE_PROCESS_STATE, PROCESS_STATE_BACKGROUND,
+                10_000);
+        aggregatedPowerStats.setUidState(APP_UID2, STATE_PROCESS_STATE,
+                PROCESS_STATE_FOREGROUND_SERVICE, 10_000);
+
+        results = collectPowerStats(12345, 45_000, 100_000,
+                createAttribution(APP_UID1, 24_000),
+                createAttribution(APP_UID2, 36_000));
+        for (PowerStats powerStats : results) {
+            aggregatedPowerStats.addPowerStats(powerStats, 40_000);
+        }
+
+        aggregatedPowerStats.finish(40_0000);
+
+        List<PowerComponentAggregatedPowerStats> powerComponentStats =
+                aggregatedPowerStats.getPowerComponentStats();
+
+        PowerComponentAggregatedPowerStats ps1 = powerComponentStats.stream()
+                .filter(ps -> ps.getPowerStatsDescriptor().name.equals("FOO")).findAny()
+                .orElseThrow();
+        PowerComponentAggregatedPowerStats ps2 = powerComponentStats.stream()
+                .filter(ps -> ps.getPowerStatsDescriptor().name.equals("BAR")).findAny()
+                .orElseThrow();
+
+        long[] deviceStats = new long[ps1.getPowerStatsDescriptor().statsArrayLength];
+        long[] uidStats = new long[ps1.getPowerStatsDescriptor().uidStatsArrayLength];
+
+        // Total estimated power = 10,000 uC = 0.00278 mAh
+        double expectedPower = 0.00278;
+        ps1.getDeviceStats(deviceStats, states(POWER_STATE_OTHER, SCREEN_STATE_ON));
+        assertThat(POWER_STATS_LAYOUT.getDevicePowerEstimate(deviceStats))
+                .isWithin(PRECISION).of(expectedPower * 0.25);
+
+        ps1.getDeviceStats(deviceStats, states(POWER_STATE_BATTERY, SCREEN_STATE_OTHER));
+        assertThat(POWER_STATS_LAYOUT.getDevicePowerEstimate(deviceStats))
+                .isWithin(PRECISION).of(expectedPower * 0.75);
+
+        // UID1: estimated power = 14,000 uC = 0.00388 mAh
+        expectedPower = 0.00388;
+        ps2.getUidStats(uidStats, APP_UID1,
+                states(POWER_STATE_OTHER, SCREEN_STATE_ON, PROCESS_STATE_FOREGROUND));
+        assertThat(POWER_STATS_LAYOUT.getUidPowerEstimate(uidStats))
+                .isWithin(PRECISION).of(expectedPower * 0.25);
+
+        ps2.getUidStats(uidStats, APP_UID1,
+                states(POWER_STATE_BATTERY, SCREEN_STATE_OTHER, PROCESS_STATE_BACKGROUND));
+        assertThat(POWER_STATS_LAYOUT.getUidPowerEstimate(uidStats))
+                .isWithin(PRECISION).of(expectedPower * 0.75);
+
+        // UID2: estimated power = 21,000 uC = 0.00583 mAh
+        expectedPower = 0.00583;
+        ps2.getUidStats(uidStats, APP_UID2,
+                states(POWER_STATE_OTHER, SCREEN_STATE_ON, PROCESS_STATE_CACHED));
+        assertThat(POWER_STATS_LAYOUT.getUidPowerEstimate(uidStats))
+                .isWithin(PRECISION).of(expectedPower * 0.25);
+
+        ps2.getUidStats(uidStats, APP_UID2,
+                states(POWER_STATE_BATTERY, SCREEN_STATE_OTHER, PROCESS_STATE_FOREGROUND_SERVICE));
+        assertThat(POWER_STATS_LAYOUT.getUidPowerEstimate(uidStats))
+                .isWithin(PRECISION).of(expectedPower * 0.75);
+    }
+
+    private List<PowerStats> collectPowerStats(long timestamp, int chargeUc1, int chargeUc2,
+            EnergyConsumerAttribution... attributions2) throws Exception {
+        when(mConsumedEnergyRetriever.getEnergyConsumerIds(EnergyConsumerType.OTHER))
+                .thenReturn(new int[]{ENERGY_CONSUMER_ID1, ENERGY_CONSUMER_ID2});
+        when(mConsumedEnergyRetriever.getEnergyConsumerName(ENERGY_CONSUMER_ID1))
+                .thenReturn("FOO");
+        when(mConsumedEnergyRetriever.getEnergyConsumerName(ENERGY_CONSUMER_ID2))
+                .thenReturn("BAR");
+        when(mConsumedEnergyRetriever.getConsumedEnergy(new int[]{ENERGY_CONSUMER_ID1}))
+                .thenReturn(createEnergyConsumerResults(ENERGY_CONSUMER_ID1, chargeUc1, null));
+        when(mConsumedEnergyRetriever.getConsumedEnergy(new int[]{ENERGY_CONSUMER_ID2}))
+                .thenReturn(
+                        createEnergyConsumerResults(ENERGY_CONSUMER_ID2, chargeUc2, attributions2));
+
+        mStatsRule.setTime(timestamp, timestamp);
+        List<PowerStats> results = new ArrayList<>();
+        CountDownLatch latch = new CountDownLatch(2);
+        Consumer<PowerStats> consumer = powerStats -> {
+            results.add(powerStats);
+            latch.countDown();
+        };
+        mCollector.addConsumer(consumer);
+        mCollector.schedule();
+        assertThat(latch.await(5, TimeUnit.SECONDS)).isTrue();
+        mCollector.removeConsumer(consumer);
+        return results;
+    }
+
+    private static AggregatedPowerStats createAggregatedPowerStats() {
+        AggregatedPowerStatsConfig config = new AggregatedPowerStatsConfig();
+        config.trackCustomPowerComponents(CustomEnergyConsumerPowerStatsProcessor::new)
+                .trackDeviceStates(
+                        STATE_POWER,
+                        STATE_SCREEN)
+                .trackUidStates(
+                        STATE_POWER,
+                        STATE_SCREEN,
+                        STATE_PROCESS_STATE);
+
+        return new AggregatedPowerStats(config);
+    }
+
+    private EnergyConsumerResult[] createEnergyConsumerResults(int id, long energyUws,
+            EnergyConsumerAttribution[] attributions) {
+        EnergyConsumerResult result = new EnergyConsumerResult();
+        result.id = id;
+        result.energyUWs = energyUws;
+        result.attribution = attributions;
+        return new EnergyConsumerResult[]{result};
+    }
+
+    private EnergyConsumerAttribution createAttribution(int uid, long energyUWs) {
+        EnergyConsumerAttribution attribution = new EnergyConsumerAttribution();
+        attribution.uid = uid;
+        attribution.energyUWs = energyUWs;
+        return attribution;
+    }
+
+    private int[] states(int... states) {
+        return states;
+    }
+}
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerStatsTest.java
index 8a391c6..774be89 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerStatsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerStatsTest.java
@@ -30,8 +30,11 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.when;
 
+import android.hardware.power.stats.EnergyConsumerResult;
 import android.hardware.power.stats.EnergyConsumerType;
 import android.location.GnssSignalQuality;
 import android.os.BatteryConsumer;
@@ -119,8 +122,10 @@
     @Test
     public void powerProfileModel() {
         // ODPM unsupported
-        when(mConsumedEnergyRetriever.getEnergyConsumerIds(EnergyConsumerType.GNSS, null))
+        when(mConsumedEnergyRetriever
+                .getEnergyConsumerIds(eq((int) EnergyConsumerType.GNSS), any()))
                 .thenReturn(new int[0]);
+
         GnssPowerStatsProcessor processor = new GnssPowerStatsProcessor(
                 mStatsRule.getPowerProfile(), mUidResolver);
 
@@ -209,7 +214,8 @@
 
     @Test
     public void energyConsumerModel() {
-        when(mConsumedEnergyRetriever.getEnergyConsumerIds(EnergyConsumerType.GNSS, null))
+        when(mConsumedEnergyRetriever
+                .getEnergyConsumerIds(eq((int) EnergyConsumerType.GNSS), any()))
                 .thenReturn(new int[]{ENERGY_CONSUMER_ID});
         GnssPowerStatsProcessor processor = new GnssPowerStatsProcessor(
                 mStatsRule.getPowerProfile(), mUidResolver);
@@ -224,8 +230,8 @@
         collector.setEnabled(true);
 
         // Establish a baseline
-        when(mConsumedEnergyRetriever.getConsumedEnergyUws(new int[]{ENERGY_CONSUMER_ID}))
-                .thenReturn(new long[]{uCtoUj(10000)});
+        when(mConsumedEnergyRetriever.getConsumedEnergy(new int[]{ENERGY_CONSUMER_ID}))
+                .thenReturn(createEnergyConsumerResults(ENERGY_CONSUMER_ID, 10000));
         collector.collectAndDeliverStats();
 
         processor.noteStateChange(stats, buildHistoryItem(0, true, APP_UID1));
@@ -237,8 +243,8 @@
 
         processor.noteStateChange(stats, buildHistoryItem(6000, false, APP_UID1));
 
-        when(mConsumedEnergyRetriever.getConsumedEnergyUws(new int[]{ENERGY_CONSUMER_ID}))
-                .thenReturn(new long[]{uCtoUj(2_170_000)});
+        when(mConsumedEnergyRetriever.getConsumedEnergy(new int[]{ENERGY_CONSUMER_ID}))
+                .thenReturn(createEnergyConsumerResults(ENERGY_CONSUMER_ID, 2_170_000));
         collector.collectAndDeliverStats();
 
         processor.noteStateChange(stats, buildHistoryItem(7000, true, APP_UID2));
@@ -247,8 +253,8 @@
         processor.noteStateChange(stats, buildHistoryItem(8000,
                 GnssSignalQuality.GNSS_SIGNAL_QUALITY_POOR));
         mStatsRule.setTime(11_000, 11_000);
-        when(mConsumedEnergyRetriever.getConsumedEnergyUws(new int[]{ENERGY_CONSUMER_ID}))
-                .thenReturn(new long[]{uCtoUj(3_610_000)});
+        when(mConsumedEnergyRetriever.getConsumedEnergy(new int[]{ENERGY_CONSUMER_ID}))
+                .thenReturn(createEnergyConsumerResults(ENERGY_CONSUMER_ID, 3_610_000));
         collector.collectAndDeliverStats();
 
         processor.finish(stats, 11_000);
@@ -369,7 +375,10 @@
         return powerComponentStats;
     }
 
-    private static long uCtoUj(long uc) {
-        return (long) (uc * (double) VOLTAGE_MV / 1000);
+    private EnergyConsumerResult[] createEnergyConsumerResults(int id, long energyUWs) {
+        EnergyConsumerResult result = new EnergyConsumerResult();
+        result.id = id;
+        result.energyUWs = (long) (energyUWs * (double) VOLTAGE_MV / 1000);
+        return new EnergyConsumerResult[]{result};
     }
 }
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsCollectorTest.java
index 0275319..ef20946 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsCollectorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsCollectorTest.java
@@ -39,6 +39,7 @@
 import android.os.BatteryStats;
 import android.os.Handler;
 import android.os.OutcomeReceiver;
+import android.os.connectivity.CellularBatteryStats;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.ActivityStatsTechSpecificInfo;
@@ -167,6 +168,7 @@
     public void setup() {
         MockitoAnnotations.initMocks(this);
         when(mContext.getPackageManager()).thenReturn(mPackageManager);
+        when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephony);
         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)).thenReturn(true);
         when(mPowerStatsUidResolver.mapUid(anyInt())).thenAnswer(invocation -> {
             int uid = invocation.getArgument(0);
@@ -352,8 +354,48 @@
                 "UID 42: rx-pkts: 100 rx-B: 1000 tx-pkts: 200 tx-B: 2000");
     }
 
+    @Test
+    public void getCellularBatteryStats() throws Throwable {
+        mBatteryStats.setPowerStatsCollectorEnabled(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO,
+                true);
+
+        mockModemActivityInfo(1000, 2000, 3000, 600, new int[]{100, 200, 300, 400, 500});
+        mockNetworkStats(1100,
+                5321, 421, 3234, 223,
+                8000, 80, 4000, 40);
+
+        // This should trigger a baseline sample collection
+        mBatteryStats.onSystemReady(mContext);
+        mStatsRule.waitForBackgroundThread();
+
+        mockModemActivityInfo(20000, 2222, 3333, 666, new int[]{111, 222, 333, 444, 555});
+        mockNetworkStats(21000,
+                6321, 521, 7234, 423,
+                8888, 88, 4444, 44);
+
+        mStatsRule.setTime(30000, 30000);
+        mBatteryStats.getPowerStatsCollector(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)
+                .schedule();
+        mStatsRule.waitForBackgroundThread();
+
+        CellularBatteryStats stats = mBatteryStats.getCellularBatteryStats();
+        assertThat(stats.getSleepTimeMillis()).isEqualTo(222);
+        assertThat(stats.getIdleTimeMillis()).isEqualTo(333);
+        assertThat(stats.getRxTimeMillis()).isEqualTo(66);
+        assertThat(stats.getTxTimeMillis(ModemActivityInfo.TX_POWER_LEVEL_0)).isEqualTo(11);
+        assertThat(stats.getTxTimeMillis(ModemActivityInfo.TX_POWER_LEVEL_1)).isEqualTo(22);
+        assertThat(stats.getTxTimeMillis(ModemActivityInfo.TX_POWER_LEVEL_2)).isEqualTo(33);
+        assertThat(stats.getTxTimeMillis(ModemActivityInfo.TX_POWER_LEVEL_3)).isEqualTo(44);
+        assertThat(stats.getTxTimeMillis(ModemActivityInfo.TX_POWER_LEVEL_4)).isEqualTo(55);
+        assertThat(stats.getNumPacketsRx()).isEqualTo(934);
+        assertThat(stats.getNumBytesRx()).isEqualTo(19967);
+        assertThat(stats.getNumPacketsTx()).isEqualTo(770);
+        assertThat(stats.getNumBytesTx()).isEqualTo(14214);
+    }
+
     private PowerStats collectPowerStats(boolean perNetworkTypeData) throws Throwable {
-        MobileRadioPowerStatsCollector collector = new MobileRadioPowerStatsCollector(mInjector);
+        MobileRadioPowerStatsCollector collector =
+                new MobileRadioPowerStatsCollector(mInjector, null);
         collector.setEnabled(true);
 
         when(mConsumedEnergyRetriever.getEnergyConsumerIds(
@@ -462,6 +504,7 @@
                     .addEntry(new NetworkStats.Entry("mobile", APP_UID3, 0, 0, METERED_NO,
                             ROAMING_NO, DEFAULT_NETWORK_NO, 314, 281, 314, 281, 111));
         }
+        mBatteryStats.setNetworkStats(stats);
         when(mNetworkStatsSupplier.get()).thenReturn(stats);
     }
 
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsProcessorTest.java
index 137c2a6..d7024e5 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsProcessorTest.java
@@ -191,7 +191,8 @@
         aggregatedStats.setUidState(APP_UID, STATE_PROCESS_STATE, PROCESS_STATE_FOREGROUND, 0);
         aggregatedStats.setUidState(APP_UID2, STATE_PROCESS_STATE, PROCESS_STATE_CACHED, 0);
 
-        MobileRadioPowerStatsCollector collector = new MobileRadioPowerStatsCollector(mInjector);
+        MobileRadioPowerStatsCollector collector =
+                new MobileRadioPowerStatsCollector(mInjector, null);
         collector.setEnabled(true);
 
         // Initial empty ModemActivityInfo.
@@ -430,7 +431,8 @@
         aggregatedStats.setUidState(APP_UID, STATE_PROCESS_STATE, PROCESS_STATE_FOREGROUND, 0);
         aggregatedStats.setUidState(APP_UID2, STATE_PROCESS_STATE, PROCESS_STATE_CACHED, 0);
 
-        MobileRadioPowerStatsCollector collector = new MobileRadioPowerStatsCollector(mInjector);
+        MobileRadioPowerStatsCollector collector =
+                new MobileRadioPowerStatsCollector(mInjector, null);
         collector.setEnabled(true);
 
         // Initial empty ModemActivityInfo.
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/PhoneCallPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/PhoneCallPowerStatsProcessorTest.java
index 548d54c..c268110 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/PhoneCallPowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/PhoneCallPowerStatsProcessorTest.java
@@ -180,7 +180,8 @@
         aggregatedPowerStats.setDeviceState(STATE_POWER, POWER_STATE_OTHER, 0);
         aggregatedPowerStats.setDeviceState(STATE_SCREEN, SCREEN_STATE_ON, 0);
 
-        MobileRadioPowerStatsCollector collector = new MobileRadioPowerStatsCollector(mInjector);
+        MobileRadioPowerStatsCollector collector =
+                new MobileRadioPowerStatsCollector(mInjector, null);
         collector.setEnabled(true);
 
         // Initial empty ModemActivityInfo.
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsExporterTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsExporterTest.java
index 412fc88..32bfb2c 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsExporterTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsExporterTest.java
@@ -79,6 +79,8 @@
     private BatteryStatsHistory mHistory;
     private CpuPowerStatsLayout mCpuStatsArrayLayout;
     private PowerStats.Descriptor mPowerStatsDescriptor;
+    private final EnergyConsumerPowerStatsLayout mEnergyConsumerPowerStatsLayout =
+            new EnergyConsumerPowerStatsLayout();
 
     @Before
     public void setup() throws IOException {
@@ -87,14 +89,24 @@
 
         AggregatedPowerStatsConfig config = new AggregatedPowerStatsConfig();
         config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_CPU)
-                .trackDeviceStates(AggregatedPowerStatsConfig.STATE_POWER,
+                .trackDeviceStates(
+                        AggregatedPowerStatsConfig.STATE_POWER,
                         AggregatedPowerStatsConfig.STATE_SCREEN)
-                .trackUidStates(AggregatedPowerStatsConfig.STATE_POWER,
+                .trackUidStates(
+                        AggregatedPowerStatsConfig.STATE_POWER,
                         AggregatedPowerStatsConfig.STATE_SCREEN,
                         AggregatedPowerStatsConfig.STATE_PROCESS_STATE)
                 .setProcessor(
                         new CpuPowerStatsProcessor(mStatsRule.getPowerProfile(),
                                 mStatsRule.getCpuScalingPolicies()));
+        config.trackCustomPowerComponents(CustomEnergyConsumerPowerStatsProcessor::new)
+                .trackDeviceStates(
+                        AggregatedPowerStatsConfig.STATE_POWER,
+                        AggregatedPowerStatsConfig.STATE_SCREEN)
+                .trackUidStates(
+                        AggregatedPowerStatsConfig.STATE_POWER,
+                        AggregatedPowerStatsConfig.STATE_SCREEN,
+                        AggregatedPowerStatsConfig.STATE_PROCESS_STATE);
 
         mPowerStatsStore = new PowerStatsStore(storeDirectory, new TestHandler(), config);
         mHistory = new BatteryStatsHistory(Parcel.obtain(), storeDirectory, 0, 10000,
@@ -120,15 +132,25 @@
     @Test
     public void breakdownByProcState_fullRange() throws Exception {
         BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(
-                new String[0], /* includePowerModels */ false,
+                new String[]{"cu570m"}, /* includePowerModels */ false,
                 /* includeProcessStateData */ true, /* powerThreshold */ 0);
         exportAggregatedPowerStats(builder, 1000, 10000);
 
         BatteryUsageStats actual = builder.build();
         String message = "Actual BatteryUsageStats: " + actual;
 
-        assertDevicePowerEstimate(message, actual, BatteryConsumer.POWER_COMPONENT_CPU, 7.51016);
-        assertAllAppsPowerEstimate(message, actual, BatteryConsumer.POWER_COMPONENT_CPU, 7.51016);
+        assertAggregatedPowerEstimate(message, actual,
+                BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE,
+                BatteryConsumer.POWER_COMPONENT_CPU, 7.51016);
+        assertAggregatedPowerEstimate(message, actual,
+                BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS,
+                BatteryConsumer.POWER_COMPONENT_CPU, 7.51016);
+        assertAggregatedPowerEstimate(message, actual,
+                BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE,
+                BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 3.60);
+        assertAggregatedPowerEstimate(message, actual,
+                BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS,
+                BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 0.360);
 
         assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU,
                 BatteryConsumer.PROCESS_STATE_ANY, 3.97099);
@@ -136,11 +158,17 @@
                 BatteryConsumer.PROCESS_STATE_FOREGROUND, 2.198082);
         assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU,
                 BatteryConsumer.PROCESS_STATE_BACKGROUND, 1.772916);
+        assertUidPowerEstimate(message, actual, APP_UID1,
+                BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID,
+                BatteryConsumer.PROCESS_STATE_ANY, 0.360);
 
         assertUidPowerEstimate(message, actual, APP_UID2, BatteryConsumer.POWER_COMPONENT_CPU,
                 BatteryConsumer.PROCESS_STATE_ANY, 3.538999);
         assertUidPowerEstimate(message, actual, APP_UID2, BatteryConsumer.POWER_COMPONENT_CPU,
                 BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE, 3.538999);
+        assertUidPowerEstimate(message, actual, APP_UID2,
+                BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID,
+                BatteryConsumer.PROCESS_STATE_ANY, 0);
 
         actual.close();
     }
@@ -148,15 +176,19 @@
     @Test
     public void breakdownByProcState_subRange() throws Exception {
         BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(
-                new String[0], /* includePowerModels */ false,
+                new String[]{"cu570m"}, /* includePowerModels */ false,
                 /* includeProcessStateData */ true, /* powerThreshold */ 0);
         exportAggregatedPowerStats(builder, 3700, 6700);
 
         BatteryUsageStats actual = builder.build();
         String message = "Actual BatteryUsageStats: " + actual;
 
-        assertDevicePowerEstimate(message, actual, BatteryConsumer.POWER_COMPONENT_CPU, 4.526749);
-        assertAllAppsPowerEstimate(message, actual, BatteryConsumer.POWER_COMPONENT_CPU, 4.526749);
+        assertAggregatedPowerEstimate(message, actual,
+                BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE,
+                BatteryConsumer.POWER_COMPONENT_CPU, 4.526749);
+        assertAggregatedPowerEstimate(message, actual,
+                BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS,
+                BatteryConsumer.POWER_COMPONENT_CPU, 4.526749);
 
         assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU,
                 BatteryConsumer.PROCESS_STATE_ANY, 1.193332);
@@ -176,15 +208,19 @@
     @Test
     public void combinedProcessStates() throws Exception {
         BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder(
-                new String[0], /* includePowerModels */ false,
+                new String[]{"cu570m"}, /* includePowerModels */ false,
                 /* includeProcessStateData */ false, /* powerThreshold */ 0);
         exportAggregatedPowerStats(builder, 1000, 10000);
 
         BatteryUsageStats actual = builder.build();
         String message = "Actual BatteryUsageStats: " + actual;
 
-        assertDevicePowerEstimate(message, actual, BatteryConsumer.POWER_COMPONENT_CPU, 7.51016);
-        assertAllAppsPowerEstimate(message, actual, BatteryConsumer.POWER_COMPONENT_CPU, 7.51016);
+        assertAggregatedPowerEstimate(message, actual,
+                BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE,
+                BatteryConsumer.POWER_COMPONENT_CPU, 7.51016);
+        assertAggregatedPowerEstimate(message, actual,
+                BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS,
+                BatteryConsumer.POWER_COMPONENT_CPU, 7.51016);
 
         assertUidPowerEstimate(message, actual, APP_UID1, BatteryConsumer.POWER_COMPONENT_CPU,
                 BatteryConsumer.PROCESS_STATE_ANY, 3.97099);
@@ -210,10 +246,19 @@
         long[] uidStats2 = new long[mCpuStatsArrayLayout.getUidStatsArrayLength()];
         powerStats.uidStats.put(APP_UID2, uidStats2);
 
+        PowerStats customPowerStats = new PowerStats(
+                new PowerStats.Descriptor(BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID,
+                        "cu570m", mEnergyConsumerPowerStatsLayout.getDeviceStatsArrayLength(),
+                        null, 0, mEnergyConsumerPowerStatsLayout.getUidStatsArrayLength(),
+                        new PersistableBundle()));
+        long[] customUidStats = new long[mEnergyConsumerPowerStatsLayout.getUidStatsArrayLength()];
+        customPowerStats.uidStats.put(APP_UID1, customUidStats);
+
         mHistory.forceRecordAllHistory();
 
         mHistory.startRecordingHistory(1000, 1000, false);
         mHistory.recordPowerStats(1000, 1000, powerStats);
+        mHistory.recordPowerStats(1000, 1000, customPowerStats);
         mHistory.recordBatteryState(1000, 1000, 70, /* plugged */ false);
         mHistory.recordStateStartEvent(1000, 1000, BatteryStats.HistoryItem.STATE_SCREEN_ON_FLAG);
         mHistory.recordProcessStateChange(1000, 1000, APP_UID1,
@@ -245,6 +290,10 @@
         mCpuStatsArrayLayout.setUidTimeByPowerBracket(uidStats2, 0, 40000);
         mHistory.recordPowerStats(6000, 6000, powerStats);
 
+        mEnergyConsumerPowerStatsLayout.setConsumedEnergy(customPowerStats.stats, 0, 3_600_000);
+        mEnergyConsumerPowerStatsLayout.setUidConsumedEnergy(customUidStats, 0, 360_000);
+        mHistory.recordPowerStats(6010, 6010, customPowerStats);
+
         mPowerStatsAggregator.aggregatePowerStats(3500, 6500, stats -> {
             mPowerStatsStore.storeAggregatedPowerStats(stats);
         });
@@ -271,20 +320,13 @@
         exporter.exportAggregatedPowerStats(builder, monotonicStartTime, monotonicEndTime);
     }
 
-    private void assertDevicePowerEstimate(String message, BatteryUsageStats bus, int componentId,
-            double expected) {
-        AggregateBatteryConsumer consumer = bus.getAggregateBatteryConsumer(
-                BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
-        assertWithMessage(message).that(consumer.getConsumedPower(componentId))
-                .isWithin(TOLERANCE).of(expected);
-    }
-
-    private void assertAllAppsPowerEstimate(String message, BatteryUsageStats bus, int componentId,
-            double expected) {
-        AggregateBatteryConsumer consumer = bus.getAggregateBatteryConsumer(
-                BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS);
-        assertWithMessage(message).that(consumer.getConsumedPower(componentId))
-                .isWithin(TOLERANCE).of(expected);
+    private void assertAggregatedPowerEstimate(String message, BatteryUsageStats bus, int scope,
+            int componentId, double expected) {
+        AggregateBatteryConsumer consumer = bus.getAggregateBatteryConsumer(scope);
+        double actual = componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID
+                ? consumer.getConsumedPower(componentId)
+                : consumer.getConsumedPowerForCustomComponent(componentId);
+        assertWithMessage(message).that(actual).isWithin(TOLERANCE).of(expected);
     }
 
     private void assertUidPowerEstimate(String message, BatteryUsageStats bus, int uid,
@@ -293,9 +335,11 @@
         final UidBatteryConsumer uidScope = uidScopes.stream()
                 .filter(us -> us.getUid() == uid).findFirst().orElse(null);
         assertWithMessage(message).that(uidScope).isNotNull();
-        assertWithMessage(message).that(uidScope.getConsumedPower(
-                new BatteryConsumer.Dimensions(componentId, processState)))
-                .isWithin(TOLERANCE).of(expected);
+        double actual = componentId < BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID
+                ? uidScope.getConsumedPower(
+                        new BatteryConsumer.Dimensions(componentId, processState))
+                : uidScope.getConsumedPowerForCustomComponent(componentId);
+        assertWithMessage(message).that(actual).isWithin(TOLERANCE).of(expected);
     }
 
     private void clearDirectory(File dir) {
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java
index a280cfe..362607b 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java
@@ -40,6 +40,7 @@
 import android.os.Handler;
 import android.os.WorkSource;
 import android.os.connectivity.WifiActivityEnergyInfo;
+import android.os.connectivity.WifiBatteryStats;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.IndentingPrintWriter;
 import android.util.SparseArray;
@@ -186,6 +187,7 @@
                 return uid;
             }
         });
+        when(mContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
         mBatteryStats = mStatsRule.getBatteryStats();
     }
 
@@ -319,10 +321,51 @@
                         + " scan: 234 batched-scan: 345");
     }
 
+    @Test
+    public void getWifiBatteryStats() throws Throwable {
+        when(mWifiManager.isEnhancedPowerReportingSupported()).thenReturn(true);
+        mBatteryStats.setPowerStatsCollectorEnabled(BatteryConsumer.POWER_COMPONENT_WIFI,
+                true);
+
+        mockWifiActivityInfo(1000, 600, 100, 2000, 3000);
+        mockNetworkStats(1000);
+        mockNetworkStatsEntry(APP_UID1, 4321, 321, 1234, 23);
+        mockNetworkStatsEntry(APP_UID2, 4000, 40, 2000, 20);
+        mockWifiScanTimes(APP_UID1, 1000, 2000);
+        mockWifiScanTimes(APP_UID2, 3000, 4000);
+
+        // This should trigger a baseline sample collection
+        mBatteryStats.onSystemReady(mContext);
+        mStatsRule.waitForBackgroundThread();
+
+        mockWifiActivityInfo(1100, 6600, 1100, 2200, 3300);
+        mockNetworkStats(1100);
+        mockNetworkStatsEntry(APP_UID1, 5321, 421, 3234, 223);
+        mockNetworkStatsEntry(APP_UID2, 8000, 80, 4000, 40);
+        mockWifiScanTimes(APP_UID1, 1234, 2345);
+        mockWifiScanTimes(APP_UID2, 3100, 4200);
+
+        mStatsRule.setTime(30000, 30000);
+        mBatteryStats.getPowerStatsCollector(BatteryConsumer.POWER_COMPONENT_WIFI)
+                .schedule();
+        mStatsRule.waitForBackgroundThread();
+
+        WifiBatteryStats stats = mBatteryStats.getWifiBatteryStats();
+        assertThat(stats.getNumPacketsRx()).isEqualTo(501);
+        assertThat(stats.getNumBytesRx()).isEqualTo(13321);
+        assertThat(stats.getNumPacketsTx()).isEqualTo(263);
+        assertThat(stats.getNumBytesTx()).isEqualTo(7234);
+        assertThat(stats.getScanTimeMillis()).isEqualTo(2200);
+        assertThat(stats.getRxTimeMillis()).isEqualTo(6000);
+        assertThat(stats.getTxTimeMillis()).isEqualTo(1000);
+        assertThat(stats.getIdleTimeMillis()).isEqualTo(300);
+        assertThat(stats.getSleepTimeMillis()).isEqualTo(30000 - 6000 - 1000 - 300);
+    }
+
     private PowerStats collectPowerStats(boolean hasPowerReporting) {
         when(mWifiManager.isEnhancedPowerReportingSupported()).thenReturn(hasPowerReporting);
 
-        WifiPowerStatsCollector collector = new WifiPowerStatsCollector(mInjector);
+        WifiPowerStatsCollector collector = new WifiPowerStatsCollector(mInjector, null);
         collector.setEnabled(true);
 
         when(mConsumedEnergyRetriever.getEnergyConsumerIds(EnergyConsumerType.WIFI))
@@ -389,6 +432,7 @@
         } else {
             mNetworkStats = new NetworkStats(elapsedRealtime, 1);
         }
+        mBatteryStats.setNetworkStats(mNetworkStats);
         when(mNetworkStatsSupplier.get()).thenReturn(mNetworkStats);
     }
 
@@ -411,6 +455,7 @@
                     .addEntry(new NetworkStats.Entry("wifi", uid, 0, 0,
                             METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, rxBytes, rxPackets,
                             txBytes, txPackets, 100));
+            mBatteryStats.setNetworkStats(mNetworkStats);
             reset(mNetworkStatsSupplier);
             when(mNetworkStatsSupplier.get()).thenReturn(mNetworkStats);
         }
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsProcessorTest.java
index ff56691..7ddaefd 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsProcessorTest.java
@@ -99,6 +99,8 @@
     @Mock
     private WifiManager mWifiManager;
 
+    private MockBatteryStatsImpl mBatteryStats;
+
     private static class ScanTimes {
         public long scanTimeMs;
         public long batchScanTimeMs;
@@ -185,6 +187,8 @@
         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)).thenReturn(true);
         when(mPowerStatsUidResolver.mapUid(anyInt()))
                 .thenAnswer(invocation -> invocation.getArgument(0));
+
+        mBatteryStats = mStatsRule.getBatteryStats();
     }
 
     @Test
@@ -200,7 +204,7 @@
 
         PowerComponentAggregatedPowerStats aggregatedStats = createAggregatedPowerStats(processor);
 
-        WifiPowerStatsCollector collector = new WifiPowerStatsCollector(mInjector);
+        WifiPowerStatsCollector collector = new WifiPowerStatsCollector(mInjector, null);
         collector.setEnabled(true);
 
         // Initial empty WifiActivityEnergyInfo.
@@ -312,7 +316,7 @@
 
         PowerComponentAggregatedPowerStats aggregatedStats = createAggregatedPowerStats(processor);
 
-        WifiPowerStatsCollector collector = new WifiPowerStatsCollector(mInjector);
+        WifiPowerStatsCollector collector = new WifiPowerStatsCollector(mInjector, null);
         collector.setEnabled(true);
 
         // Initial empty WifiActivityEnergyInfo.
@@ -425,7 +429,7 @@
 
         PowerComponentAggregatedPowerStats aggregatedStats = createAggregatedPowerStats(processor);
 
-        WifiPowerStatsCollector collector = new WifiPowerStatsCollector(mInjector);
+        WifiPowerStatsCollector collector = new WifiPowerStatsCollector(mInjector, null);
         collector.setEnabled(true);
 
         // Establish a baseline
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 4e8c755..20b9592 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -25,6 +25,9 @@
 
 import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.QUICK_SETTINGS;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
 import static com.android.server.accessibility.AccessibilityManagerService.ACTION_LAUNCH_HEARING_DEVICES_DIALOG;
 import static com.android.window.flags.Flags.FLAG_ALWAYS_DRAW_MAGNIFICATION_FULLSCREEN_BORDER;
 
@@ -597,7 +600,7 @@
 
         final AccessibilityUserState userState = mA11yms.mUserStates.get(
                 mA11yms.getCurrentUserIdLocked());
-        userState.mAccessibilityShortcutKeyTargets.add(MAGNIFICATION_CONTROLLER_NAME);
+        userState.updateShortcutTargetsLocked(Set.of(MAGNIFICATION_CONTROLLER_NAME), HARDWARE);
         userState.setMagnificationCapabilitiesLocked(
                 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL);
 
@@ -797,10 +800,11 @@
         final AccessibilityUserState userState = mA11yms.mUserStates.get(
                 mA11yms.getCurrentUserIdLocked());
         mFakePermissionEnforcer.grant(Manifest.permission.MANAGE_ACCESSIBILITY);
-        userState.mAccessibilityShortcutKeyTargets.add(
-                ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString());
+        userState.updateShortcutTargetsLocked(
+                Set.of(ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString()), HARDWARE);
 
         mA11yms.performAccessibilityShortcut(
+                Display.DEFAULT_DISPLAY, HARDWARE,
                 ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString());
         mTestableLooper.processAllMessages();
 
@@ -815,10 +819,11 @@
         final AccessibilityUserState userState = mA11yms.mUserStates.get(
                 mA11yms.getCurrentUserIdLocked());
         mFakePermissionEnforcer.grant(Manifest.permission.MANAGE_ACCESSIBILITY);
-        userState.mAccessibilityShortcutKeyTargets.add(
-                ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString());
+        userState.updateShortcutTargetsLocked(
+                Set.of(ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString()), HARDWARE);
 
         mA11yms.performAccessibilityShortcut(
+                Display.DEFAULT_DISPLAY, HARDWARE,
                 ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString());
         mTestableLooper.processAllMessages();
 
@@ -871,9 +876,10 @@
         userState.mInstalledServices.clear();
         userState.mInstalledServices.add(info_a);
         userState.mInstalledServices.add(info_b);
-        userState.mAccessibilityButtonTargets.clear();
-        userState.mAccessibilityButtonTargets.add(info_a.getComponentName().flattenToString());
-        userState.mAccessibilityButtonTargets.add(info_b.getComponentName().flattenToString());
+        userState.updateShortcutTargetsLocked(Set.of(
+                        info_a.getComponentName().flattenToString(),
+                        info_b.getComponentName().flattenToString()),
+                SOFTWARE);
 
         // despite force stopping both packages, only the first service has the relevant flag,
         // so only the first should be removed.
@@ -887,11 +893,11 @@
 
         //Assert user state change
         userState = mA11yms.getCurrentUserState();
-        assertThat(userState.mAccessibilityButtonTargets).containsExactly(
+        assertThat(userState.getShortcutTargetsLocked(SOFTWARE)).containsExactly(
                 info_b.getComponentName().flattenToString());
         //Assert setting change
         final Set<String> targetsFromSetting = new ArraySet<>();
-        mA11yms.readColonDelimitedSettingToSet(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
+        mA11yms.readColonDelimitedSettingToSet(ShortcutUtils.convertToKey(SOFTWARE),
                 userState.mUserId, str -> str, targetsFromSetting);
         assertThat(targetsFromSetting).containsExactly(info_b.getComponentName().flattenToString());
     }
@@ -992,10 +998,10 @@
         final AccessibilityServiceInfo info_c = mockAccessibilityServiceInfo(
                 new ComponentName("package_c", "class_c"));
         final AccessibilityUserState userState = mA11yms.getCurrentUserState();
-        userState.mAccessibilityButtonTargets.clear();
-        userState.mAccessibilityButtonTargets.add(info_b.getComponentName().flattenToString());
-        userState.mAccessibilityShortcutKeyTargets.clear();
-        userState.mAccessibilityShortcutKeyTargets.add(info_c.getComponentName().flattenToString());
+        userState.updateShortcutTargetsLocked(
+                Set.of(info_b.getComponentName().flattenToString()), SOFTWARE);
+        userState.updateShortcutTargetsLocked(
+                Set.of(info_c.getComponentName().flattenToString()), HARDWARE);
 
         assertThat(mA11yms.isAccessibilityServiceWarningRequired(info_a)).isTrue();
         assertThat(mA11yms.isAccessibilityServiceWarningRequired(info_b)).isFalse();
@@ -1082,7 +1088,7 @@
 
         mA11yms.enableShortcutsForTargets(
                 /* enable= */ true,
-                UserShortcutType.HARDWARE,
+                HARDWARE,
                 List.of(target),
                 mA11yms.getCurrentUserIdLocked());
         mTestableLooper.processAllMessages();
@@ -1346,14 +1352,14 @@
 
         mA11yms.enableShortcutsForTargets(
                 /* enable= */ true,
-                UserShortcutType.HARDWARE,
+                HARDWARE,
                 List.of(TARGET_STANDARD_A11Y_SERVICE.flattenToString()),
                 mA11yms.getCurrentUserIdLocked());
         mTestableLooper.processAllMessages();
 
         assertThat(
                 ShortcutUtils.isComponentIdExistingInSettings(
-                        mTestableContext, ShortcutConstants.UserShortcutType.HARDWARE,
+                        mTestableContext, HARDWARE,
                         TARGET_STANDARD_A11Y_SERVICE.flattenToString())
         ).isTrue();
     }
@@ -1367,7 +1373,7 @@
 
         mA11yms.enableShortcutsForTargets(
                 /* enable= */ false,
-                UserShortcutType.HARDWARE,
+                HARDWARE,
                 List.of(TARGET_STANDARD_A11Y_SERVICE.flattenToString()),
                 mA11yms.getCurrentUserIdLocked());
         mTestableLooper.processAllMessages();
@@ -1375,7 +1381,7 @@
         assertThat(
                         ShortcutUtils.isComponentIdExistingInSettings(
                                 mTestableContext,
-                                ShortcutConstants.UserShortcutType.HARDWARE,
+                                HARDWARE,
                                 TARGET_STANDARD_A11Y_SERVICE.flattenToString()))
                 .isFalse();
     }
@@ -1390,14 +1396,14 @@
 
         mA11yms.enableShortcutsForTargets(
                 /* enable= */ true,
-                UserShortcutType.QUICK_SETTINGS,
+                QUICK_SETTINGS,
                 List.of(TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString()),
                 mA11yms.getCurrentUserIdLocked());
         mTestableLooper.processAllMessages();
 
         assertThat(
                 ShortcutUtils.isComponentIdExistingInSettings(
-                        mTestableContext, UserShortcutType.QUICK_SETTINGS,
+                        mTestableContext, QUICK_SETTINGS,
                         TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString())
         ).isTrue();
         verify(mStatusBarManagerInternal)
@@ -1417,14 +1423,14 @@
 
         mA11yms.enableShortcutsForTargets(
                 /* enable= */ false,
-                UserShortcutType.QUICK_SETTINGS,
+                QUICK_SETTINGS,
                 List.of(TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString()),
                 mA11yms.getCurrentUserIdLocked());
         mTestableLooper.processAllMessages();
 
         assertThat(
                 ShortcutUtils.isComponentIdExistingInSettings(
-                        mTestableContext, UserShortcutType.QUICK_SETTINGS,
+                        mTestableContext, QUICK_SETTINGS,
                         TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString())
         ).isFalse();
         verify(mStatusBarManagerInternal)
@@ -1556,8 +1562,8 @@
         mFakePermissionEnforcer.grant(Manifest.permission.MANAGE_ACCESSIBILITY);
         setupShortcutTargetServices();
         final AccessibilityUserState userState = mA11yms.getCurrentUserState();
-        userState.mAccessibilityButtonTargets.clear();
-        userState.mAccessibilityButtonTargets.add(TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString());
+        userState.updateShortcutTargetsLocked(
+                Set.of(TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString()), SOFTWARE);
         ComponentName tile = new ComponentName(
                 TARGET_ALWAYS_ON_A11Y_SERVICE.getPackageName(),
                 TARGET_ALWAYS_ON_A11Y_SERVICE_TILE_CLASS);
@@ -1614,44 +1620,49 @@
 
     @Test
     @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
-    public void restoreAccessibilityQsTargets_a11yQsTargetsRestored() {
+    public void restoreShortcutTargets_qs_a11yQsTargetsRestored() {
         String daltonizerTile =
                 AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME.flattenToString();
         String colorInversionTile =
                 AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME.flattenToString();
         final AccessibilityUserState userState = new AccessibilityUserState(
                 UserHandle.USER_SYSTEM, mTestableContext, mA11yms);
-        userState.updateA11yQsTargetLocked(Set.of(daltonizerTile));
+        userState.updateShortcutTargetsLocked(Set.of(daltonizerTile), QUICK_SETTINGS);
         mA11yms.mUserStates.put(UserHandle.USER_SYSTEM, userState);
 
         broadcastSettingRestored(
-                Settings.Secure.ACCESSIBILITY_QS_TARGETS,
-                /*previousValue=*/null,
+                ShortcutUtils.convertToKey(QUICK_SETTINGS),
                 /*newValue=*/colorInversionTile);
 
-        assertThat(mA11yms.mUserStates.get(UserHandle.USER_SYSTEM).getA11yQsTargets())
-                .containsExactlyElementsIn(Set.of(daltonizerTile, colorInversionTile));
+        Set<String> expected = Set.of(daltonizerTile, colorInversionTile);
+        assertThat(readStringsFromSetting(ShortcutUtils.convertToKey(QUICK_SETTINGS)))
+                .containsExactlyElementsIn(expected);
+        assertThat(userState.getShortcutTargetsLocked(QUICK_SETTINGS))
+                .containsExactlyElementsIn(expected);
     }
 
     @Test
     @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
-    public void restoreAccessibilityQsTargets_a11yQsTargetsNotRestored() {
+    public void restoreShortcutTargets_qs_a11yQsTargetsNotRestored() {
         String daltonizerTile =
                 AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME.flattenToString();
         String colorInversionTile =
                 AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME.flattenToString();
         final AccessibilityUserState userState = new AccessibilityUserState(
                 UserHandle.USER_SYSTEM, mTestableContext, mA11yms);
-        userState.updateA11yQsTargetLocked(Set.of(daltonizerTile));
+        userState.updateShortcutTargetsLocked(Set.of(daltonizerTile), QUICK_SETTINGS);
+        putShortcutSettingForUser(QUICK_SETTINGS, daltonizerTile, userState.mUserId);
         mA11yms.mUserStates.put(UserHandle.USER_SYSTEM, userState);
 
         broadcastSettingRestored(
-                Settings.Secure.ACCESSIBILITY_QS_TARGETS,
-                /*previousValue=*/null,
+                ShortcutUtils.convertToKey(QUICK_SETTINGS),
                 /*newValue=*/colorInversionTile);
 
-        assertThat(userState.getA11yQsTargets())
-                .containsExactlyElementsIn(Set.of(daltonizerTile));
+        Set<String> expected = Set.of(daltonizerTile);
+        assertThat(readStringsFromSetting(ShortcutUtils.convertToKey(QUICK_SETTINGS)))
+                .containsExactlyElementsIn(expected);
+        assertThat(userState.getShortcutTargetsLocked(QUICK_SETTINGS))
+                .containsExactlyElementsIn(expected);
     }
 
     @Test
@@ -1717,27 +1728,26 @@
 
     @Test
     @EnableFlags(android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SHORTCUT_TARGET_SERVICE)
-    public void restoreA11yShortcutTargetService_targetsMerged() {
+    public void restoreShortcutTargets_hardware_targetsMerged() {
+        mFakePermissionEnforcer.grant(Manifest.permission.MANAGE_ACCESSIBILITY);
         final String servicePrevious = TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString();
         final String otherPrevious = TARGET_MAGNIFICATION;
-        final String combinedPrevious = String.join(":", servicePrevious, otherPrevious);
         final String serviceRestored = TARGET_STANDARD_A11Y_SERVICE.flattenToString();
         final AccessibilityUserState userState = new AccessibilityUserState(
                 UserHandle.USER_SYSTEM, mTestableContext, mA11yms);
         mA11yms.mUserStates.put(UserHandle.USER_SYSTEM, userState);
         setupShortcutTargetServices(userState);
+        mA11yms.enableShortcutsForTargets(
+                true, HARDWARE, List.of(servicePrevious, otherPrevious), userState.mUserId);
 
         broadcastSettingRestored(
-                Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
-                /*previousValue=*/combinedPrevious,
+                ShortcutUtils.convertToKey(HARDWARE),
                 /*newValue=*/serviceRestored);
 
         final Set<String> expected = Set.of(servicePrevious, otherPrevious, serviceRestored);
-        assertThat(readStringsFromSetting(
-                Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE))
+        assertThat(readStringsFromSetting(ShortcutUtils.convertToKey(HARDWARE)))
                 .containsExactlyElementsIn(expected);
-        assertThat(mA11yms.mUserStates.get(UserHandle.USER_SYSTEM)
-                .getShortcutTargetsLocked(UserShortcutType.HARDWARE))
+        assertThat(userState.getShortcutTargetsLocked(HARDWARE))
                 .containsExactlyElementsIn(expected);
     }
 
@@ -1745,7 +1755,7 @@
     @EnableFlags({
             android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SHORTCUT_TARGET_SERVICE,
             Flags.FLAG_CLEAR_DEFAULT_FROM_A11Y_SHORTCUT_TARGET_SERVICE_RESTORE})
-    public void restoreA11yShortcutTargetService_alreadyHadDefaultService_doesNotClear() {
+    public void restoreShortcutTargets_hardware_alreadyHadDefaultService_doesNotClear() {
         final String serviceDefault = TARGET_STANDARD_A11Y_SERVICE.flattenToString();
         mTestableContext.getOrCreateTestableResources().addOverride(
                 R.string.config_defaultAccessibilityService, serviceDefault);
@@ -1754,17 +1764,18 @@
         mA11yms.mUserStates.put(UserHandle.USER_SYSTEM, userState);
         setupShortcutTargetServices(userState);
 
+        // default is present in userState & setting, so it's not cleared
+        putShortcutSettingForUser(HARDWARE, serviceDefault, UserHandle.USER_SYSTEM);
+        userState.updateShortcutTargetsLocked(Set.of(serviceDefault), HARDWARE);
+
         broadcastSettingRestored(
                 Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
-                /*previousValue=*/serviceDefault,
                 /*newValue=*/serviceDefault);
 
         final Set<String> expected = Set.of(serviceDefault);
-        assertThat(readStringsFromSetting(
-                Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE))
+        assertThat(readStringsFromSetting(ShortcutUtils.convertToKey(HARDWARE)))
                 .containsExactlyElementsIn(expected);
-        assertThat(mA11yms.mUserStates.get(UserHandle.USER_SYSTEM)
-                .getShortcutTargetsLocked(UserShortcutType.HARDWARE))
+        assertThat(userState.getShortcutTargetsLocked(HARDWARE))
                 .containsExactlyElementsIn(expected);
     }
 
@@ -1772,7 +1783,7 @@
     @EnableFlags({
             android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SHORTCUT_TARGET_SERVICE,
             Flags.FLAG_CLEAR_DEFAULT_FROM_A11Y_SHORTCUT_TARGET_SERVICE_RESTORE})
-    public void restoreA11yShortcutTargetService_didNotHaveDefaultService_clearsDefaultService() {
+    public void restoreShortcutTargets_hardware_didNotHaveDefaultService_clearsDefaultService() {
         final String serviceDefault = TARGET_STANDARD_A11Y_SERVICE.flattenToString();
         final String serviceRestored = TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString();
         // Restored value from the broadcast contains both default and non-default service.
@@ -1784,18 +1795,45 @@
         mA11yms.mUserStates.put(UserHandle.USER_SYSTEM, userState);
         setupShortcutTargetServices(userState);
 
-        broadcastSettingRestored(
-                Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
-                /*previousValue=*/null,
+        broadcastSettingRestored(ShortcutUtils.convertToKey(HARDWARE),
                 /*newValue=*/combinedRestored);
 
         // The default service is cleared from the final restored value.
         final Set<String> expected = Set.of(serviceRestored);
-        assertThat(readStringsFromSetting(
-                Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE))
+        assertThat(readStringsFromSetting(ShortcutUtils.convertToKey(HARDWARE)))
                 .containsExactlyElementsIn(expected);
-        assertThat(mA11yms.mUserStates.get(UserHandle.USER_SYSTEM)
-                .getShortcutTargetsLocked(UserShortcutType.HARDWARE))
+        assertThat(userState.getShortcutTargetsLocked(HARDWARE))
+                .containsExactlyElementsIn(expected);
+    }
+
+    @Test
+    @EnableFlags({
+            android.view.accessibility.Flags.FLAG_RESTORE_A11Y_SHORTCUT_TARGET_SERVICE,
+            Flags.FLAG_CLEAR_DEFAULT_FROM_A11Y_SHORTCUT_TARGET_SERVICE_RESTORE})
+    public void restoreShortcutTargets_hardware_nullSetting_clearsDefaultService() {
+        final String serviceDefault = TARGET_STANDARD_A11Y_SERVICE.flattenToString();
+        final String serviceRestored = TARGET_ALWAYS_ON_A11Y_SERVICE.flattenToString();
+        // Restored value from the broadcast contains both default and non-default service.
+        final String combinedRestored = String.join(":", serviceDefault, serviceRestored);
+        mTestableContext.getOrCreateTestableResources().addOverride(
+                R.string.config_defaultAccessibilityService, serviceDefault);
+        final AccessibilityUserState userState = new AccessibilityUserState(
+                UserHandle.USER_SYSTEM, mTestableContext, mA11yms);
+        mA11yms.mUserStates.put(UserHandle.USER_SYSTEM, userState);
+        setupShortcutTargetServices(userState);
+
+        // UserState has default, but setting is null (this emulates a typical scenario in SUW).
+        userState.updateShortcutTargetsLocked(Set.of(serviceDefault), HARDWARE);
+        putShortcutSettingForUser(HARDWARE, null, UserHandle.USER_SYSTEM);
+
+        broadcastSettingRestored(ShortcutUtils.convertToKey(HARDWARE),
+                /*newValue=*/combinedRestored);
+
+        // The default service is cleared from the final restored value.
+        final Set<String> expected = Set.of(serviceRestored);
+        assertThat(readStringsFromSetting(ShortcutUtils.convertToKey(HARDWARE)))
+                .containsExactlyElementsIn(expected);
+        assertThat(userState.getShortcutTargetsLocked(HARDWARE))
                 .containsExactlyElementsIn(expected);
     }
 
@@ -1806,11 +1844,10 @@
         return result;
     }
 
-    private void broadcastSettingRestored(String setting, String previousValue, String newValue) {
+    private void broadcastSettingRestored(String setting, String newValue) {
         Intent intent = new Intent(Intent.ACTION_SETTING_RESTORED)
                 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)
                 .putExtra(Intent.EXTRA_SETTING_NAME, setting)
-                .putExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE, previousValue)
                 .putExtra(Intent.EXTRA_SETTING_NEW_VALUE, newValue);
         sendBroadcastToAccessibilityManagerService(intent);
         mTestableLooper.processAllMessages();
@@ -1952,4 +1989,13 @@
     private static boolean isSameCurrentUser(AccessibilityManagerService service, Context context) {
         return service.getCurrentUserIdLocked() == context.getUserId();
     }
+
+    private void putShortcutSettingForUser(@UserShortcutType int shortcutType,
+            String shortcutValue, int userId) {
+        Settings.Secure.putStringForUser(
+                mTestableContext.getContentResolver(),
+                ShortcutUtils.convertToKey(shortcutType),
+                shortcutValue,
+                userId);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java
index b269beb9..ca30551 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityUserStateTest.java
@@ -28,6 +28,10 @@
 import static android.view.accessibility.AccessibilityManager.STATE_FLAG_HIGH_TEXT_CONTRAST_ENABLED;
 import static android.view.accessibility.AccessibilityManager.STATE_FLAG_TOUCH_EXPLORATION_ENABLED;
 
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.QUICK_SETTINGS;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
 import static com.android.server.accessibility.AccessibilityUserState.doesShortcutTargetsStringContain;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -158,8 +162,9 @@
         mUserState.setInteractiveUiTimeoutLocked(30);
         mUserState.mEnabledServices.add(COMPONENT_NAME);
         mUserState.mTouchExplorationGrantedServices.add(COMPONENT_NAME);
-        mUserState.mAccessibilityShortcutKeyTargets.add(COMPONENT_NAME.flattenToString());
-        mUserState.mAccessibilityButtonTargets.add(COMPONENT_NAME.flattenToString());
+        mUserState.updateShortcutTargetsLocked(Set.of(COMPONENT_NAME.flattenToString()), HARDWARE);
+        mUserState.updateShortcutTargetsLocked(Set.of(COMPONENT_NAME.flattenToString()), SOFTWARE);
+        mUserState.updateShortcutTargetsLocked(Set.of(COMPONENT_NAME.flattenToString()), GESTURE);
         mUserState.setTargetAssignedToAccessibilityButton(COMPONENT_NAME.flattenToString());
         mUserState.setTouchExplorationEnabledLocked(true);
         mUserState.setMagnificationSingleFingerTripleTapEnabledLocked(true);
@@ -181,8 +186,9 @@
         assertEquals(0, mUserState.getInteractiveUiTimeoutLocked());
         assertTrue(mUserState.mEnabledServices.isEmpty());
         assertTrue(mUserState.mTouchExplorationGrantedServices.isEmpty());
-        assertTrue(mUserState.mAccessibilityShortcutKeyTargets.isEmpty());
-        assertTrue(mUserState.mAccessibilityButtonTargets.isEmpty());
+        assertTrue(mUserState.getShortcutTargetsLocked(HARDWARE).isEmpty());
+        assertTrue(mUserState.getShortcutTargetsLocked(SOFTWARE).isEmpty());
+        assertTrue(mUserState.getShortcutTargetsLocked(GESTURE).isEmpty());
         assertNull(mUserState.getTargetAssignedToAccessibilityButton());
         assertFalse(mUserState.isTouchExplorationEnabledLocked());
         assertFalse(mUserState.isMagnificationSingleFingerTripleTapEnabledLocked());
@@ -429,20 +435,20 @@
     }
 
     @Test
-    public void updateA11yQsTargetLocked_valueUpdated() {
+    public void updateShortcutTargetsLocked_quickSettings_valueUpdated() {
         Set<String> newTargets = Set.of(
                 AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME.flattenToString(),
                 AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME.flattenToString()
         );
 
-        mUserState.updateA11yQsTargetLocked(newTargets);
+        mUserState.updateShortcutTargetsLocked(newTargets, QUICK_SETTINGS);
 
         assertThat(mUserState.getA11yQsTargets()).isEqualTo(newTargets);
     }
 
     @Test
     public void getA11yQsTargets_returnsCopiedData() {
-        updateA11yQsTargetLocked_valueUpdated();
+        updateShortcutTargetsLocked_quickSettings_valueUpdated();
 
         Set<String> targets = mUserState.getA11yQsTargets();
         targets.clear();
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MouseKeysInterceptorTest.kt b/services/tests/servicestests/src/com/android/server/accessibility/MouseKeysInterceptorTest.kt
new file mode 100644
index 0000000..dc8d239
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MouseKeysInterceptorTest.kt
@@ -0,0 +1,272 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.accessibility
+
+import android.companion.virtual.VirtualDeviceManager
+import android.companion.virtual.VirtualDeviceParams
+import android.content.Context
+import android.hardware.input.IInputManager
+import android.hardware.input.InputManager
+import android.hardware.input.InputManagerGlobal
+import android.hardware.input.VirtualMouse
+import android.hardware.input.VirtualMouseButtonEvent
+import android.hardware.input.VirtualMouseConfig
+import android.hardware.input.VirtualMouseRelativeEvent
+import android.hardware.input.VirtualMouseScrollEvent
+import android.os.RemoteException
+import android.os.test.TestLooper
+import android.platform.test.annotations.Presubmit
+import android.view.KeyEvent
+import androidx.test.core.app.ApplicationProvider
+import com.android.server.companion.virtual.VirtualDeviceManagerInternal
+import com.android.server.LocalServices
+import com.android.server.testutils.OffsettableClock
+import junit.framework.Assert.assertEquals
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.mockito.ArgumentCaptor
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+import java.util.concurrent.TimeUnit
+import java.util.LinkedList
+import java.util.Queue
+import android.util.ArraySet
+
+/**
+ * Tests for {@link MouseKeysInterceptor}
+ *
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:MouseKeysInterceptorTest
+ */
+@Presubmit
+class MouseKeysInterceptorTest {
+    companion object {
+        const val DISPLAY_ID = 1
+        const val DEVICE_ID = 123
+        // This delay is required for key events to be sent and handled correctly.
+        // The handler only performs a move/scroll event if it receives the key event
+        // at INTERVAL_MILLIS (which happens in practice). Hence, we need this delay in the tests.
+        const val KEYBOARD_POST_EVENT_DELAY_MILLIS = 20L
+    }
+
+    private lateinit var mouseKeysInterceptor: MouseKeysInterceptor
+    private val clock = OffsettableClock()
+    private val testLooper = TestLooper { clock.now() }
+    private val nextInterceptor = TrackingInterceptor()
+
+    @Mock
+    private lateinit var mockAms: AccessibilityManagerService
+
+    @Mock
+    private lateinit var iInputManager: IInputManager
+    private lateinit var testSession: InputManagerGlobal.TestSession
+    private lateinit var mockInputManager: InputManager
+
+    @Mock
+    private lateinit var mockVirtualDeviceManagerInternal: VirtualDeviceManagerInternal
+    @Mock
+    private lateinit var mockVirtualDevice: VirtualDeviceManager.VirtualDevice
+    @Mock
+    private lateinit var mockVirtualMouse: VirtualMouse
+
+    @Mock
+    private lateinit var mockTraceManager: AccessibilityTraceManager
+
+    @Before
+    @Throws(RemoteException::class)
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        val context = ApplicationProvider.getApplicationContext<Context>()
+        testSession = InputManagerGlobal.createTestSession(iInputManager)
+        mockInputManager = InputManager(context)
+
+        Mockito.`when`(mockVirtualDeviceManagerInternal.getDeviceIdsForUid(Mockito.anyInt()))
+            .thenReturn(ArraySet(setOf(DEVICE_ID)))
+        LocalServices.removeServiceForTest(VirtualDeviceManagerInternal::class.java)
+        LocalServices.addService<VirtualDeviceManagerInternal>(
+            VirtualDeviceManagerInternal::class.java, mockVirtualDeviceManagerInternal
+        )
+
+        Mockito.`when`(mockVirtualDeviceManagerInternal.createVirtualDevice(
+            Mockito.any(VirtualDeviceParams::class.java)
+        )).thenReturn(mockVirtualDevice)
+        Mockito.`when`(mockVirtualDevice.createVirtualMouse(
+            Mockito.any(VirtualMouseConfig::class.java)
+        )).thenReturn(mockVirtualMouse)
+
+        Mockito.`when`(iInputManager.inputDeviceIds).thenReturn(intArrayOf(DEVICE_ID))
+        Mockito.`when`(mockAms.traceManager).thenReturn(mockTraceManager)
+
+        mouseKeysInterceptor = MouseKeysInterceptor(mockAms, mockInputManager,
+            testLooper.looper, DISPLAY_ID)
+        // VirtualMouse is created on a separate thread.
+        // Wait for VirtualMouse to be created before running tests
+        TimeUnit.MILLISECONDS.sleep(20L)
+        mouseKeysInterceptor.next = nextInterceptor
+    }
+
+    @After
+    fun tearDown() {
+        testLooper.dispatchAll()
+        if (this::testSession.isInitialized) {
+            testSession.close()
+        }
+    }
+
+    @Test
+    fun whenNonMouseKeyEventArrives_eventIsPassedToNextInterceptor() {
+        val downTime = clock.now()
+        val downEvent = KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+            KeyEvent.KEYCODE_Q, 0, 0, DEVICE_ID, 0)
+        mouseKeysInterceptor.onKeyEvent(downEvent, 0)
+        testLooper.dispatchAll()
+
+        assertEquals(1, nextInterceptor.events.size)
+        assertEquals(downEvent, nextInterceptor.events.poll())
+    }
+
+    @Test
+    fun whenMouseDirectionalKeyIsPressed_relativeEventIsSent() {
+        // There should be some delay between the downTime of the key event and calling onKeyEvent
+        val downTime = clock.now() - KEYBOARD_POST_EVENT_DELAY_MILLIS
+        val keyCode = MouseKeysInterceptor.MouseKeyEvent.DOWN_MOVE.getKeyCodeValue()
+        val downEvent = KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+            keyCode, 0, 0, DEVICE_ID, 0)
+
+        mouseKeysInterceptor.onKeyEvent(downEvent, 0)
+        testLooper.dispatchAll()
+
+        // Verify the sendRelativeEvent method is called once and capture the arguments
+        verifyRelativeEvents(arrayOf<Float>(0f), arrayOf<Float>(1.8f))
+    }
+
+    @Test
+    fun whenClickKeyIsPressed_buttonEventIsSent() {
+        // There should be some delay between the downTime of the key event and calling onKeyEvent
+        val downTime = clock.now() - KEYBOARD_POST_EVENT_DELAY_MILLIS
+        val keyCode = MouseKeysInterceptor.MouseKeyEvent.LEFT_CLICK.getKeyCodeValue()
+        val downEvent = KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+            keyCode, 0, 0, DEVICE_ID, 0)
+        mouseKeysInterceptor.onKeyEvent(downEvent, 0)
+        testLooper.dispatchAll()
+
+        val actions = arrayOf<Int>(
+            VirtualMouseButtonEvent.ACTION_BUTTON_PRESS,
+            VirtualMouseButtonEvent.ACTION_BUTTON_RELEASE)
+        val buttons = arrayOf<Int>(
+            VirtualMouseButtonEvent.BUTTON_PRIMARY,
+            VirtualMouseButtonEvent.BUTTON_PRIMARY)
+        // Verify the sendButtonEvent method is called twice and capture the arguments
+        verifyButtonEvents(actions, buttons)
+    }
+
+    @Test
+    fun whenHoldKeyIsPressed_buttonEventIsSent() {
+        val downTime = clock.now() - KEYBOARD_POST_EVENT_DELAY_MILLIS
+        val keyCode = MouseKeysInterceptor.MouseKeyEvent.HOLD.getKeyCodeValue()
+        val downEvent = KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+            keyCode, 0, 0, DEVICE_ID, 0)
+        mouseKeysInterceptor.onKeyEvent(downEvent, 0)
+        testLooper.dispatchAll()
+
+        // Verify the sendButtonEvent method is called once and capture the arguments
+        verifyButtonEvents(
+            arrayOf<Int>( VirtualMouseButtonEvent.ACTION_BUTTON_PRESS),
+            arrayOf<Int>( VirtualMouseButtonEvent.BUTTON_PRIMARY)
+        )
+    }
+
+    @Test
+    fun whenReleaseKeyIsPressed_buttonEventIsSent() {
+        val downTime = clock.now() - KEYBOARD_POST_EVENT_DELAY_MILLIS
+        val keyCode = MouseKeysInterceptor.MouseKeyEvent.RELEASE.getKeyCodeValue()
+        val downEvent = KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+            keyCode, 0, 0, DEVICE_ID, 0)
+        mouseKeysInterceptor.onKeyEvent(downEvent, 0)
+        testLooper.dispatchAll()
+
+        // Verify the sendButtonEvent method is called once and capture the arguments
+        verifyButtonEvents(
+            arrayOf<Int>( VirtualMouseButtonEvent.ACTION_BUTTON_RELEASE),
+            arrayOf<Int>( VirtualMouseButtonEvent.BUTTON_PRIMARY)
+        )
+    }
+
+    @Test
+    fun whenScrollUpKeyIsPressed_scrollEventIsSent() {
+        // There should be some delay between the downTime of the key event and calling onKeyEvent
+        val downTime = clock.now() - KEYBOARD_POST_EVENT_DELAY_MILLIS
+        val keyCode = MouseKeysInterceptor.MouseKeyEvent.SCROLL_UP.getKeyCodeValue()
+        val downEvent = KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN,
+            keyCode, 0, 0, DEVICE_ID, 0)
+
+        mouseKeysInterceptor.onKeyEvent(downEvent, 0)
+        testLooper.dispatchAll()
+
+        // Verify the sendScrollEvent method is called once and capture the arguments
+        verifyScrollEvents(arrayOf<Float>(0f), arrayOf<Float>(1.0f))
+    }
+
+    private fun verifyRelativeEvents(expectedX: Array<Float>, expectedY: Array<Float>) {
+        assertEquals(expectedX.size, expectedY.size)
+        val captor = ArgumentCaptor.forClass(VirtualMouseRelativeEvent::class.java)
+        Mockito.verify(mockVirtualMouse, Mockito.times(expectedX.size))
+            .sendRelativeEvent(captor.capture())
+
+        for (i in expectedX.indices) {
+            val captorEvent = captor.allValues[i]
+            assertEquals(expectedX[i], captorEvent.relativeX)
+            assertEquals(expectedY[i], captorEvent.relativeY)
+        }
+    }
+
+    private fun verifyButtonEvents(actions: Array<Int>, buttons: Array<Int>) {
+        assertEquals(actions.size, buttons.size)
+        val captor = ArgumentCaptor.forClass(VirtualMouseButtonEvent::class.java)
+        Mockito.verify(mockVirtualMouse, Mockito.times(actions.size))
+                .sendButtonEvent(captor.capture())
+
+        for (i in actions.indices) {
+            val captorEvent = captor.allValues[i]
+            assertEquals(actions[i], captorEvent.action)
+            assertEquals(buttons[i], captorEvent.buttonCode)
+        }
+    }
+
+    private fun verifyScrollEvents(xAxisMovements: Array<Float>, yAxisMovements: Array<Float>) {
+        assertEquals(xAxisMovements.size, yAxisMovements.size)
+        val captor = ArgumentCaptor.forClass(VirtualMouseScrollEvent::class.java)
+        Mockito.verify(mockVirtualMouse, Mockito.times(xAxisMovements.size))
+            .sendScrollEvent(captor.capture())
+
+        for (i in xAxisMovements.indices) {
+            val captorEvent = captor.allValues[i]
+            assertEquals(xAxisMovements[i], captorEvent.xAxisMovement)
+            assertEquals(yAxisMovements[i], captorEvent.yAxisMovement)
+        }
+    }
+
+    private class TrackingInterceptor : BaseEventStreamTransformation() {
+        val events: Queue<KeyEvent> = LinkedList()
+
+        override fun onKeyEvent(event: KeyEvent, policyFlags: Int) {
+            events.add(event)
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
index 30e3b18..dbab54b 100644
--- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
@@ -672,6 +672,61 @@
                 new HashSet<>(mUserController.getRunningUsersLU()));
     }
 
+    /** Test scheduling stopping of background users - reschedule if current user is a guest. */
+    @Test
+    public void testScheduleStopOfBackgroundUser_rescheduleWhenGuest() throws Exception {
+        mSetFlagsRule.enableFlags(android.multiuser.Flags.FLAG_SCHEDULE_STOP_OF_BACKGROUND_USER);
+
+        mUserController.setInitialConfig(/* userSwitchUiEnabled= */ true,
+                /* maxRunningUsers= */ 10, /* delayUserDataLocking= */ false,
+                /* backgroundUserScheduledStopTimeSecs= */ 2);
+
+        final int TEST_USER_GUEST = 902;
+        setUpUser(TEST_USER_GUEST, UserInfo.FLAG_GUEST);
+
+        setUpUser(TEST_USER_ID2, NO_USERINFO_FLAGS);
+
+        // Switch to TEST_USER_ID from user 0
+        int numberOfUserSwitches = 0;
+        addForegroundUserAndContinueUserSwitch(TEST_USER_ID, UserHandle.USER_SYSTEM,
+                ++numberOfUserSwitches, false,
+                /* expectScheduleBackgroundUserStopping= */ false);
+        assertEquals(Arrays.asList(SYSTEM_USER_ID, TEST_USER_ID),
+                mUserController.getRunningUsersLU());
+
+        // Switch to TEST_USER_GUEST from TEST_USER_ID
+        addForegroundUserAndContinueUserSwitch(TEST_USER_GUEST, TEST_USER_ID,
+                ++numberOfUserSwitches, false,
+                /* expectScheduleBackgroundUserStopping= */ true);
+        assertEquals(Arrays.asList(SYSTEM_USER_ID, TEST_USER_ID, TEST_USER_GUEST),
+                mUserController.getRunningUsersLU());
+
+        // Allow the post-switch processing to complete.
+        // TEST_USER_ID may be scheduled for stopping, but it shouldn't actually stop since the
+        // current user is a Guest.
+        assertAndProcessScheduledStopBackgroundUser(true, TEST_USER_ID);
+        assertAndProcessScheduledStopBackgroundUser(false, TEST_USER_GUEST);
+        assertEquals(Arrays.asList(SYSTEM_USER_ID, TEST_USER_ID, TEST_USER_GUEST),
+                mUserController.getRunningUsersLU());
+
+        // Switch to TEST_USER_ID2 from TEST_USER_GUEST
+        // Guests are automatically stopped in the background, so it won't be scheduled.
+        addForegroundUserAndContinueUserSwitch(TEST_USER_ID2, TEST_USER_GUEST,
+                ++numberOfUserSwitches, true,
+                /* expectScheduleBackgroundUserStopping= */ false);
+        assertEquals(Arrays.asList(SYSTEM_USER_ID, TEST_USER_ID, TEST_USER_ID2),
+                mUserController.getRunningUsersLU());
+
+        // Allow the post-switch processing to complete.
+        // TEST_USER_ID should *still* be scheduled for stopping, since we skipped stopping it
+        // earlier.
+        assertAndProcessScheduledStopBackgroundUser(true, TEST_USER_ID);
+        assertAndProcessScheduledStopBackgroundUser(false, TEST_USER_GUEST);
+        assertAndProcessScheduledStopBackgroundUser(false, TEST_USER_ID2);
+        assertEquals(Arrays.asList(SYSTEM_USER_ID, TEST_USER_ID2),
+                mUserController.getRunningUsersLU());
+    }
+
     /**
      * Process queued SCHEDULED_STOP_BACKGROUND_USER_MSG message, if expected.
      * @param userId the user we are checking to see whether it is scheduled.
@@ -682,11 +737,11 @@
             boolean expectScheduled, @Nullable Integer userId) {
         TestHandler handler = mInjector.mHandler;
         if (expectScheduled) {
-            assertTrue(handler.hasMessages(SCHEDULED_STOP_BACKGROUND_USER_MSG, userId));
+            assertTrue(handler.hasEqualMessages(SCHEDULED_STOP_BACKGROUND_USER_MSG, userId));
             handler.removeMessages(SCHEDULED_STOP_BACKGROUND_USER_MSG, userId);
             mUserController.processScheduledStopOfBackgroundUser(userId);
         } else {
-            assertFalse(handler.hasMessages(SCHEDULED_STOP_BACKGROUND_USER_MSG, userId));
+            assertFalse(handler.hasEqualMessages(SCHEDULED_STOP_BACKGROUND_USER_MSG, userId));
         }
     }
 
@@ -1534,9 +1589,9 @@
         mInjector.mHandler.clearAllRecordedMessages();
         // Verify that continueUserSwitch worked as expected
         continueAndCompleteUserSwitch(userState, oldUserId, newUserId);
-        assertEquals(mInjector.mHandler
-                        .hasMessages(SCHEDULED_STOP_BACKGROUND_USER_MSG, expectedOldUserId),
-                expectScheduleBackgroundUserStopping);
+        assertEquals(expectScheduleBackgroundUserStopping,
+                mInjector.mHandler
+                        .hasEqualMessages(SCHEDULED_STOP_BACKGROUND_USER_MSG, expectedOldUserId));
         verify(mInjector, times(expectedNumberOfCalls)).dismissUserSwitchingDialog(any());
         continueUserSwitchAssertions(oldUserId, newUserId, expectOldUserStopping,
                 expectScheduleBackgroundUserStopping);
@@ -1810,6 +1865,13 @@
     }
 
     private static class TestHandler extends Handler {
+        /**
+         * Keeps an accessible copy of messages that were queued for us to query.
+         *
+         * WARNING: queued messages get added to this, but processed/removed messages to NOT
+         * automatically get removed. This can lead to confusing bugs. Maybe one day someone will
+         * fix this, but in the meantime, this is your warning.
+         */
         private final List<Message> mMessages = new ArrayList<>();
 
         TestHandler(Looper looper) {
diff --git a/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java b/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java
index 8a7815e..c34e28f 100644
--- a/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java
@@ -47,7 +47,9 @@
 import android.os.Handler;
 import android.os.UserHandle;
 import android.test.InstrumentationTestCase;
+import android.util.ArraySet;
 import android.util.AtomicFile;
+import android.util.SparseArray;
 import android.util.Xml;
 import android.widget.RemoteViews;
 
@@ -67,10 +69,12 @@
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
 import java.util.Random;
+import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 
 /**
@@ -388,6 +392,93 @@
         assertThat(target.previewLayout).isEqualTo(original.previewLayout);
     }
 
+    public void testBackupRestoreControllerStatePersistence() throws IOException {
+        // Setup mock data
+        final Set<String> mockPrunedApps = getMockPrunedApps();
+        final SparseArray<
+                List<AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord>
+                > mockUpdatesByProvider = getMockUpdates();
+        final  SparseArray<
+                List<AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord>
+                > mockUpdatesByHost = getMockUpdates();
+        final AppWidgetServiceImpl.BackupRestoreController.State state =
+                new AppWidgetServiceImpl.BackupRestoreController.State(
+                        mockPrunedApps, mockUpdatesByProvider, mockUpdatesByHost);
+
+        final File file = new File(mTestContext.getDataDir(), "state.xml");
+        saveBackupRestoreControllerState(file, state);
+        final AppWidgetServiceImpl.BackupRestoreController.State target =
+                loadStateLocked(file);
+        assertNotNull(target);
+        final SparseArray<List<AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord>>
+                actualUpdatesByProvider = target.getUpdatesByProvider();
+        assertNotNull(actualUpdatesByProvider);
+        final SparseArray<List<AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord>>
+                actualUpdatesByHost = target.getUpdatesByHost();
+        assertNotNull(actualUpdatesByHost);
+
+        assertEquals(mockPrunedApps, target.getPrunedApps());
+        for (int i = 0; i < mockUpdatesByProvider.size(); i++) {
+            final int key = mockUpdatesByProvider.keyAt(i);
+            verifyRestoreUpdateRecord(
+                    actualUpdatesByProvider.get(key), mockUpdatesByProvider.get(key));
+        }
+        for (int i = 0; i < mockUpdatesByHost.size(); i++) {
+            final int key = mockUpdatesByHost.keyAt(i);
+            verifyRestoreUpdateRecord(
+                    actualUpdatesByHost.get(key), mockUpdatesByHost.get(key));
+        }
+    }
+
+    private void verifyRestoreUpdateRecord(
+            @NonNull final List<AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord>
+                    actualUpdates,
+            @NonNull final List<AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord>
+                    expectedUpdates) {
+        assertEquals(expectedUpdates.size(), actualUpdates.size());
+        for (int i = 0; i < expectedUpdates.size(); i++) {
+            final AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord expected =
+                    expectedUpdates.get(i);
+            final AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord actual =
+                    actualUpdates.get(i);
+            assertEquals(expected.oldId, actual.oldId);
+            assertEquals(expected.newId, actual.newId);
+            assertEquals(expected.notified, actual.notified);
+        }
+    }
+
+    @NonNull
+    private static Set<String> getMockPrunedApps() {
+        final Set<String> mockPrunedApps = new ArraySet<>(10);
+        for (int i = 0; i < 10; i++) {
+            mockPrunedApps.add("com.example.app" + i);
+        }
+        return mockPrunedApps;
+    }
+
+    @NonNull
+    private static SparseArray<
+            List<AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord>
+            > getMockUpdates() {
+        final SparseArray<List<
+                AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord>> ret =
+                new SparseArray<>(4);
+        ret.put(0, new ArrayList<>());
+        for (int i = 0; i < 5; i++) {
+            final AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord record =
+                    new AppWidgetServiceImpl.BackupRestoreController.RestoreUpdateRecord(
+                            5 - i, i);
+            record.notified = (i % 2 == 1);
+            final int key = (i < 3) ? 1 : 2;
+            if (!ret.contains(key)) {
+                ret.put(key, new ArrayList<>());
+            }
+            ret.get(key).add(record);
+        }
+        ret.put(3, new ArrayList<>());
+        return ret;
+    }
+
     private int setupHostAndWidget() {
         List<PendingHostUpdate> updates = mService.startListening(
                 mMockHost, mPkgName, HOST_ID, new int[0]).getList();
@@ -418,6 +509,40 @@
         return mTestContext.getResources().getInteger(resId);
     }
 
+    private static void saveBackupRestoreControllerState(
+            @NonNull final File dst,
+            @Nullable final AppWidgetServiceImpl.BackupRestoreController.State state)
+            throws IOException {
+        Objects.requireNonNull(dst);
+        if (state == null) {
+            return;
+        }
+        final AtomicFile file = new AtomicFile(dst);
+        final FileOutputStream stream = file.startWrite();
+        final TypedXmlSerializer out = Xml.resolveSerializer(stream);
+        out.startDocument(null, true);
+        AppWidgetXmlUtil.writeBackupRestoreControllerState(out, state);
+        out.endDocument();
+        file.finishWrite(stream);
+    }
+
+    private static AppWidgetServiceImpl.BackupRestoreController.State loadStateLocked(
+            @NonNull final File dst) {
+        Objects.requireNonNull(dst);
+        final AtomicFile file = new AtomicFile(dst);
+        try (FileInputStream stream = file.openRead()) {
+            final TypedXmlPullParser parser = Xml.resolvePullParser(stream);
+            int type;
+            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                    && type != XmlPullParser.START_TAG) {
+                // drain whitespace, comments, etc.
+            }
+            return AppWidgetXmlUtil.readBackupRestoreControllerState(parser);
+        } catch (IOException | XmlPullParserException e) {
+            return null;
+        }
+    }
+
     private static void saveWidgetProviderInfoLocked(@NonNull final File dst,
             @Nullable final AppWidgetProviderInfo info)
             throws IOException {
diff --git a/services/tests/servicestests/src/com/android/server/audio/AudioServerPermissionProviderTest.java b/services/tests/servicestests/src/com/android/server/audio/AudioServerPermissionProviderTest.java
index 0f3b0aa..636cbee 100644
--- a/services/tests/servicestests/src/com/android/server/audio/AudioServerPermissionProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/AudioServerPermissionProviderTest.java
@@ -37,6 +37,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
 import com.android.media.permission.INativePermissionController;
+import com.android.media.permission.PermissionEnum;
 import com.android.media.permission.UidPackageState;
 import com.android.server.pm.pkg.PackageState;
 
@@ -353,6 +354,56 @@
     }
 
     @Test
+    public void testSpecialHotwordPermissions() throws Exception {
+        BiPredicate<Integer, String> customPermPred = mock(BiPredicate.class);
+        var initPackageListData =
+                List.of(mMockPackageStateOne_10000_one, mMockPackageStateTwo_10001_two);
+        // expected state
+        // PERM[CAPTURE_AUDIO_HOTWORD]: [10000]
+        // PERM[CAPTURE_AUDIO_OUTPUT]: [10001]
+        // PERM[RECORD_AUDIO]: [10001]
+        // PERM[...]: []
+        when(customPermPred.test(
+                        eq(10000), eq(MONITORED_PERMS[PermissionEnum.CAPTURE_AUDIO_HOTWORD])))
+                .thenReturn(true);
+        when(customPermPred.test(
+                        eq(10001), eq(MONITORED_PERMS[PermissionEnum.CAPTURE_AUDIO_OUTPUT])))
+                .thenReturn(true);
+        when(customPermPred.test(eq(10001), eq(MONITORED_PERMS[PermissionEnum.RECORD_AUDIO])))
+                .thenReturn(true);
+        mPermissionProvider =
+                new AudioServerPermissionProvider(
+                        initPackageListData, customPermPred, () -> new int[] {0});
+        int HDS_UID = 99001;
+        mPermissionProvider.onServiceStart(mMockPc);
+        clearInvocations(mMockPc);
+        mPermissionProvider.setIsolatedServiceUid(HDS_UID, 10000);
+        verify(mMockPc)
+                .populatePermissionState(
+                        eq((byte) PermissionEnum.CAPTURE_AUDIO_HOTWORD),
+                        aryEq(new int[] {10000, HDS_UID}));
+        verify(mMockPc)
+                .populatePermissionState(
+                        eq((byte) PermissionEnum.CAPTURE_AUDIO_OUTPUT),
+                        aryEq(new int[] {10001, HDS_UID}));
+        verify(mMockPc)
+                .populatePermissionState(
+                        eq((byte) PermissionEnum.RECORD_AUDIO), aryEq(new int[] {10001, HDS_UID}));
+
+        clearInvocations(mMockPc);
+        mPermissionProvider.clearIsolatedServiceUid(HDS_UID);
+        verify(mMockPc)
+                .populatePermissionState(
+                        eq((byte) PermissionEnum.CAPTURE_AUDIO_HOTWORD), aryEq(new int[] {10000}));
+        verify(mMockPc)
+                .populatePermissionState(
+                        eq((byte) PermissionEnum.CAPTURE_AUDIO_OUTPUT), aryEq(new int[] {10001}));
+        verify(mMockPc)
+                .populatePermissionState(
+                        eq((byte) PermissionEnum.RECORD_AUDIO), aryEq(new int[] {10001}));
+    }
+
+    @Test
     public void testPermissionsPopulated_onChange() throws Exception {
         var initPackageListData =
                 List.of(mMockPackageStateOne_10000_one, mMockPackageStateTwo_10001_two);
diff --git a/services/tests/servicestests/src/com/android/server/autofill/RequestIdTest.java b/services/tests/servicestests/src/com/android/server/autofill/RequestIdTest.java
index 6d56c41..60c3659 100644
--- a/services/tests/servicestests/src/com/android/server/autofill/RequestIdTest.java
+++ b/services/tests/servicestests/src/com/android/server/autofill/RequestIdTest.java
@@ -17,17 +17,25 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.util.Slog;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
-import java.util.ArrayList;
-import java.util.List;
-
 @RunWith(JUnit4.class)
 public class RequestIdTest {
 
+    private static final int TEST_DATASET_SIZE = 300;
+    private static final int TEST_WRAP_SIZE = 50; // Number of request ids before wrap happens
+    private static final String TAG = "RequestIdTest";
+
     List<Integer> datasetPrimaryNoWrap = new ArrayList<>();
     List<Integer> datasetPrimaryWrap = new ArrayList<>();
     List<Integer> datasetSecondaryNoWrap = new ArrayList<>();
@@ -35,151 +43,200 @@
     List<Integer> datasetMixedNoWrap = new ArrayList<>();
     List<Integer> datasetMixedWrap = new ArrayList<>();
 
-    @Before
-    public void setup() throws Exception {
-      int datasetSize = 300;
+    List<Integer> manualWrapRequestIdList = Arrays.asList(3, 9, 15,
+                                                            RequestId.MAX_SECONDARY_REQUEST_ID - 5,
+                                                            RequestId.MAX_SECONDARY_REQUEST_ID - 3);
+    List<Integer> manualNoWrapRequestIdList =Arrays.asList(2, 6, 10, 14, 18, 22, 26, 30);
 
+    List<Integer> manualOneElementRequestIdList = Arrays.asList(1);
+
+    @Before
+    public void setup() throws IllegalArgumentException {
+        Slog.d(TAG, "setup()");
         { // Generate primary only ids that do not wrap
-            RequestId requestId = new RequestId(0);
-            for (int i = 0; i < datasetSize; i++) {
+            RequestId requestId = new RequestId(RequestId.MIN_PRIMARY_REQUEST_ID);
+            for (int i = 0; i < TEST_DATASET_SIZE; i++) {
                 datasetPrimaryNoWrap.add(requestId.nextId(false));
             }
+            Collections.sort(datasetPrimaryNoWrap);
         }
 
         { // Generate primary only ids that wrap
-            RequestId requestId = new RequestId(0xff00);
-            for (int i = 0; i < datasetSize; i++) {
+            RequestId requestId = new RequestId(RequestId.MAX_PRIMARY_REQUEST_ID -
+                                                    TEST_WRAP_SIZE * 2);
+            for (int i = 0; i < TEST_DATASET_SIZE; i++) {
                 datasetPrimaryWrap.add(requestId.nextId(false));
             }
+            Collections.sort(datasetPrimaryWrap);
         }
 
         { // Generate SECONDARY only ids that do not wrap
-            RequestId requestId = new RequestId(0);
-            for (int i = 0; i < datasetSize; i++) {
+            RequestId requestId = new RequestId(RequestId.MIN_SECONDARY_REQUEST_ID);
+            for (int i = 0; i < TEST_DATASET_SIZE; i++) {
                 datasetSecondaryNoWrap.add(requestId.nextId(true));
             }
+            Collections.sort(datasetSecondaryNoWrap);
         }
 
         { // Generate SECONDARY only ids that wrap
-            RequestId requestId = new RequestId(0xff00);
-            for (int i = 0; i < datasetSize; i++) {
+            RequestId requestId = new RequestId(RequestId.MAX_SECONDARY_REQUEST_ID -
+                                                    TEST_WRAP_SIZE * 2);
+            for (int i = 0; i < TEST_DATASET_SIZE; i++) {
                 datasetSecondaryWrap.add(requestId.nextId(true));
             }
+            Collections.sort(datasetSecondaryWrap);
         }
 
         { // Generate MIXED only ids that do not wrap
-            RequestId requestId = new RequestId(0);
-            for (int i = 0; i < datasetSize; i++) {
+            RequestId requestId = new RequestId(RequestId.MIN_REQUEST_ID);
+            for (int i = 0; i < TEST_DATASET_SIZE; i++) {
                 datasetMixedNoWrap.add(requestId.nextId(i % 2 != 0));
             }
+            Collections.sort(datasetMixedNoWrap);
         }
 
         { // Generate MIXED only ids that wrap
-            RequestId requestId = new RequestId(0xff00);
-            for (int i = 0; i < datasetSize; i++) {
+            RequestId requestId = new RequestId(RequestId.MAX_REQUEST_ID -
+                                                    TEST_WRAP_SIZE);
+            for (int i = 0; i < TEST_DATASET_SIZE; i++) {
                 datasetMixedWrap.add(requestId.nextId(i % 2 != 0));
             }
+            Collections.sort(datasetMixedWrap);
         }
+        Slog.d(TAG, "finishing setup()");
     }
 
     @Test
     public void testRequestIdLists() {
+        Slog.d(TAG, "testRequestIdLists()");
         for (int id : datasetPrimaryNoWrap) {
             assertThat(RequestId.isSecondaryProvider(id)).isFalse();
-            assertThat(id >= 0).isTrue();
-            assertThat(id < 0xffff).isTrue();
+            assertThat(id).isAtLeast(RequestId.MIN_PRIMARY_REQUEST_ID);
+            assertThat(id).isAtMost(RequestId.MAX_PRIMARY_REQUEST_ID);
         }
 
         for (int id : datasetPrimaryWrap) {
             assertThat(RequestId.isSecondaryProvider(id)).isFalse();
-            assertThat(id >= 0).isTrue();
-            assertThat(id < 0xffff).isTrue();
+            assertThat(id).isAtLeast(RequestId.MIN_PRIMARY_REQUEST_ID);
+            assertThat(id).isAtMost(RequestId.MAX_PRIMARY_REQUEST_ID);
         }
 
         for (int id : datasetSecondaryNoWrap) {
             assertThat(RequestId.isSecondaryProvider(id)).isTrue();
-            assertThat(id >= 0).isTrue();
-            assertThat(id < 0xffff).isTrue();
+            assertThat(id).isAtLeast(RequestId.MIN_SECONDARY_REQUEST_ID);
+            assertThat(id).isAtMost(RequestId.MAX_SECONDARY_REQUEST_ID);
         }
 
         for (int id : datasetSecondaryWrap) {
             assertThat(RequestId.isSecondaryProvider(id)).isTrue();
-            assertThat(id >= 0).isTrue();
-            assertThat(id < 0xffff).isTrue();
+            assertThat(id).isAtLeast(RequestId.MIN_SECONDARY_REQUEST_ID);
+            assertThat(id).isAtMost(RequestId.MAX_SECONDARY_REQUEST_ID);
         }
     }
 
     @Test
-    public void testRequestIdGeneration() {
-        RequestId requestId = new RequestId(0);
+    public void testCreateNewRequestId() {
+        Slog.d(TAG, "testCreateNewRequestId()");
+        for (int i = 0; i < 100000; i++) {
+            RequestId requestId = new RequestId();
+            assertThat(requestId.getRequestId()).isAtLeast(RequestId.MIN_REQUEST_ID);
+            assertThat(requestId.getRequestId()).isAtMost(RequestId.MAX_START_ID);
+        }
+    }
 
+    @Test
+    public void testGetNextRequestId() throws IllegalArgumentException{
+        Slog.d(TAG, "testGetNextRequestId()");
+        RequestId requestId = new RequestId();
         // Large Primary
         for (int i = 0; i < 100000; i++) {
             int y = requestId.nextId(false);
             assertThat(RequestId.isSecondaryProvider(y)).isFalse();
-            assertThat(y >= 0).isTrue();
-            assertThat(y < 0xffff).isTrue();
+            assertThat(y).isAtLeast(RequestId.MIN_PRIMARY_REQUEST_ID);
+            assertThat(y).isAtMost(RequestId.MAX_PRIMARY_REQUEST_ID);
         }
 
         // Large Secondary
-        requestId = new RequestId(0);
+        requestId = new RequestId();
         for (int i = 0; i < 100000; i++) {
             int y = requestId.nextId(true);
             assertThat(RequestId.isSecondaryProvider(y)).isTrue();
-            assertThat(y >= 0).isTrue();
-            assertThat(y < 0xffff).isTrue();
+            assertThat(y).isAtLeast(RequestId.MIN_SECONDARY_REQUEST_ID);
+            assertThat(y).isAtMost(RequestId.MAX_SECONDARY_REQUEST_ID);
         }
 
         // Large Mixed
-        requestId = new RequestId(0);
+        requestId = new RequestId();
         for (int i = 0; i < 50000; i++) {
             int y = requestId.nextId(i % 2 != 0);
-            assertThat(RequestId.isSecondaryProvider(y)).isEqualTo(i % 2 == 0);
-            assertThat(y >= 0).isTrue();
-            assertThat(y < 0xffff).isTrue();
+            assertThat(y).isAtLeast(RequestId.MIN_REQUEST_ID);
+            assertThat(y).isAtMost(RequestId.MAX_REQUEST_ID);
         }
     }
 
     @Test
     public void testGetLastRequestId() {
-        // In this test, request ids are generated FIFO, so the last entry is also the last
-        // request
+        Slog.d(TAG, "testGetLastRequestId()");
 
-        { // Primary no wrap
-          int lastIdIndex = datasetPrimaryNoWrap.size() - 1;
-          int lastComputedIdIndex = RequestId.getLastRequestIdIndex(datasetPrimaryNoWrap);
-          assertThat(lastIdIndex).isEqualTo(lastComputedIdIndex);
-        }
-
-        { // Primary wrap
-            int lastIdIndex = datasetPrimaryWrap.size() - 1;
-            int lastComputedIdIndex = RequestId.getLastRequestIdIndex(datasetPrimaryWrap);
+        {   // Primary no wrap
+            int lastIdIndex = datasetPrimaryNoWrap.size() - 1;
+            int lastComputedIdIndex = RequestId.getLastRequestIdIndex(datasetPrimaryNoWrap);
             assertThat(lastIdIndex).isEqualTo(lastComputedIdIndex);
         }
 
-        { // Secondary no wrap
+        {   // Primary wrap
+            // The last index would be the # of request ids left after wrap
+            // minus 1 (index starts at 0)
+            int lastIdIndex = TEST_DATASET_SIZE - TEST_WRAP_SIZE - 1;
+            int lastComputedIdIndex = RequestId.getLastRequestIdIndex(datasetPrimaryWrap);
+            assertThat(lastComputedIdIndex).isEqualTo(lastIdIndex);
+        }
+
+        {   // Secondary no wrap
             int lastIdIndex = datasetSecondaryNoWrap.size() - 1;
             int lastComputedIdIndex = RequestId.getLastRequestIdIndex(datasetSecondaryNoWrap);
             assertThat(lastIdIndex).isEqualTo(lastComputedIdIndex);
         }
 
-        { // Secondary wrap
-            int lastIdIndex = datasetSecondaryWrap.size() - 1;
+        {   // Secondary wrap
+            int lastIdIndex = TEST_DATASET_SIZE - TEST_WRAP_SIZE - 1;
             int lastComputedIdIndex = RequestId.getLastRequestIdIndex(datasetSecondaryWrap);
             assertThat(lastIdIndex).isEqualTo(lastComputedIdIndex);
         }
 
-        { // Mixed no wrap
+        {   // Mixed no wrap
             int lastIdIndex = datasetMixedNoWrap.size() - 1;
             int lastComputedIdIndex = RequestId.getLastRequestIdIndex(datasetMixedNoWrap);
             assertThat(lastIdIndex).isEqualTo(lastComputedIdIndex);
         }
 
-        { // Mixed wrap
-            int lastIdIndex = datasetMixedWrap.size() - 1;
+        {   // Mixed wrap
+            int lastIdIndex = TEST_DATASET_SIZE - TEST_WRAP_SIZE - 1;
             int lastComputedIdIndex = RequestId.getLastRequestIdIndex(datasetMixedWrap);
             assertThat(lastIdIndex).isEqualTo(lastComputedIdIndex);
         }
 
+        {   // Manual wrap
+            int lastIdIndex = 2; // [3, 9, 15,
+                                 // MAX_SECONDARY_REQUEST_ID - 5, MAX_SECONDARY_REQUEST_ID - 3]
+            int lastComputedIdIndex = RequestId.getLastRequestIdIndex(manualWrapRequestIdList);
+            assertThat(lastIdIndex).isEqualTo(lastComputedIdIndex);
+        }
+
+        {   // Manual no wrap
+            int lastIdIndex = manualNoWrapRequestIdList.size() - 1; // [2, 6, 10, 14,
+                                                                    // 18, 22, 26, 30]
+            int lastComputedIdIndex = RequestId.getLastRequestIdIndex(manualNoWrapRequestIdList);
+            assertThat(lastIdIndex).isEqualTo(lastComputedIdIndex);
+
+        }
+
+        {   // Manual one element
+            int lastIdIndex = 0; // [1]
+            int lastComputedIdIndex = RequestId.getLastRequestIdIndex(
+                manualOneElementRequestIdList);
+            assertThat(lastIdIndex).isEqualTo(lastComputedIdIndex);
+
+        }
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index 503ab8e..0f38532 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -79,6 +79,9 @@
 import android.os.RemoteException;
 import android.os.UserManager;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.security.GateKeeper;
 import android.security.KeyStoreAuthorization;
@@ -118,6 +121,8 @@
 
     @Rule
     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
 
     private static final String TEST_PACKAGE_NAME = "test_package";
     private static final long TEST_REQUEST_ID = 44;
@@ -1506,6 +1511,75 @@
     }
 
     @Test
+    @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
+    public void testCanAuthenticate_whenMandatoryBiometricsRequested()
+            throws Exception {
+        mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
+        mBiometricService.onStart();
+
+        when(mTrustManager.isInSignificantPlace()).thenReturn(false);
+        when(mBiometricService.mSettingObserver.getMandatoryBiometricsEnabledForUser(anyInt()))
+                .thenReturn(true);
+
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+
+        assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
+                invokeCanAuthenticate(mBiometricService, Authenticators.MANDATORY_BIOMETRICS));
+
+        when(mTrustManager.isInSignificantPlace()).thenReturn(true);
+
+        assertEquals(BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE,
+                invokeCanAuthenticate(mBiometricService, Authenticators.MANDATORY_BIOMETRICS));
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
+    public void testCanAuthenticate_whenMandatoryBiometricsAndStrongAuthenticatorsRequested()
+            throws Exception {
+        mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
+        mBiometricService.onStart();
+
+        when(mTrustManager.isInSignificantPlace()).thenReturn(false);
+        when(mBiometricService.mSettingObserver.getMandatoryBiometricsEnabledForUser(anyInt()))
+                .thenReturn(true);
+
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+
+        assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
+                invokeCanAuthenticate(mBiometricService, Authenticators.MANDATORY_BIOMETRICS
+                        | Authenticators.BIOMETRIC_STRONG));
+
+        when(mTrustManager.isInSignificantPlace()).thenReturn(true);
+
+        assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
+                invokeCanAuthenticate(mBiometricService, Authenticators.MANDATORY_BIOMETRICS
+                        | Authenticators.BIOMETRIC_STRONG));
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
+    public void testCanAuthenticate_whenMandatoryBiometricsRequestedAndDeviceCredentialAvailable()
+            throws Exception {
+        mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
+        mBiometricService.onStart();
+
+        when(mTrustManager.isInSignificantPlace()).thenReturn(false);
+        when(mBiometricService.mSettingObserver.getMandatoryBiometricsEnabledForUser(anyInt()))
+                .thenReturn(true);
+
+        setupAuthForOnly(TYPE_CREDENTIAL, Authenticators.DEVICE_CREDENTIAL);
+
+        assertEquals(BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE,
+                invokeCanAuthenticate(mBiometricService, Authenticators.MANDATORY_BIOMETRICS));
+
+        when(mTrustManager.isInSignificantPlace()).thenReturn(true);
+
+        assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
+                invokeCanAuthenticate(mBiometricService, Authenticators.MANDATORY_BIOMETRICS
+                        | Authenticators.DEVICE_CREDENTIAL));
+    }
+
+    @Test
     public void testAuthenticatorActualStrength() {
         // Tuple of OEM config, updatedStrength, and expectedStrength
         final int[][] testCases = {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java b/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
index b40d7ee..b831ef5 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
@@ -32,11 +32,16 @@
 import android.app.admin.DevicePolicyManager;
 import android.app.trust.ITrustManager;
 import android.content.Context;
+import android.content.res.Resources;
 import android.hardware.biometrics.BiometricManager;
+import android.hardware.biometrics.Flags;
 import android.hardware.biometrics.IBiometricAuthenticator;
 import android.hardware.biometrics.PromptInfo;
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 
 import androidx.test.filters.SmallTest;
 
@@ -54,6 +59,9 @@
 public class PreAuthInfoTest {
     @Rule
     public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule =
+            DeviceFlagsValueProvider.createCheckFlagsRule();
 
     private static final int SENSOR_ID_FINGERPRINT = 0;
     private static final int SENSOR_ID_FACE = 1;
@@ -66,6 +74,8 @@
     @Mock
     Context mContext;
     @Mock
+    Resources mResources;
+    @Mock
     ITrustManager mTrustManager;
     @Mock
     DevicePolicyManager mDevicePolicyManager;
@@ -80,6 +90,7 @@
         when(mDevicePolicyManager.getKeyguardDisabledFeatures(any(), anyInt()))
                 .thenReturn(KEYGUARD_DISABLE_FEATURES_NONE);
         when(mSettingObserver.getEnabledForApps(anyInt())).thenReturn(true);
+        when(mSettingObserver.getMandatoryBiometricsEnabledForUser(anyInt())).thenReturn(true);
         when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
         when(mFaceAuthenticator.isHardwareDetected(any())).thenReturn(true);
         when(mFaceAuthenticator.getLockoutModeForUser(anyInt()))
@@ -91,6 +102,8 @@
                 .thenReturn(LOCKOUT_NONE);
         when(mBiometricCameraManager.isCameraPrivacyEnabled()).thenReturn(false);
         when(mBiometricCameraManager.isAnyCameraUnavailable()).thenReturn(false);
+        when(mContext.getResources()).thenReturn(mResources);
+        when(mResources.getString(anyInt())).thenReturn(TEST_PACKAGE_NAME);
     }
 
     @Test
@@ -184,6 +197,54 @@
         assertThat(preAuthInfo.eligibleSensors.get(0).modality).isEqualTo(TYPE_FINGERPRINT);
     }
 
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
+    public void testMandatoryBiometricsStatus_whenAllRequirementsSatisfiedAndSensorAvailable()
+            throws Exception {
+        when(mTrustManager.isInSignificantPlace()).thenReturn(false);
+
+        final BiometricSensor sensor = getFaceSensor();
+        final PromptInfo promptInfo = new PromptInfo();
+        promptInfo.setAuthenticators(BiometricManager.Authenticators.MANDATORY_BIOMETRICS);
+        final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager,
+                mSettingObserver, List.of(sensor), 0 /* userId */, promptInfo, TEST_PACKAGE_NAME,
+                false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager);
+
+        assertThat(preAuthInfo.eligibleSensors).hasSize(1);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
+    public void testMandatoryBiometricsStatus_whenAllRequirementsSatisfiedAndSensorUnavailable()
+            throws Exception {
+        when(mTrustManager.isInSignificantPlace()).thenReturn(false);
+
+        final PromptInfo promptInfo = new PromptInfo();
+        promptInfo.setAuthenticators(BiometricManager.Authenticators.MANDATORY_BIOMETRICS);
+        final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager,
+                mSettingObserver, List.of(), 0 /* userId */, promptInfo, TEST_PACKAGE_NAME,
+                false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager);
+
+        assertThat(preAuthInfo.eligibleSensors).hasSize(0);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
+    public void testMandatoryBiometricsStatus_whenRequirementsNotSatisfiedAndSensorAvailable()
+            throws Exception {
+        when(mTrustManager.isInSignificantPlace()).thenReturn(true);
+
+        final BiometricSensor sensor = getFaceSensor();
+        final PromptInfo promptInfo = new PromptInfo();
+        promptInfo.setAuthenticators(BiometricManager.Authenticators.MANDATORY_BIOMETRICS
+                | BiometricManager.Authenticators.BIOMETRIC_STRONG);
+        final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager,
+                mSettingObserver, List.of(sensor), 0 /* userId */, promptInfo, TEST_PACKAGE_NAME,
+                false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager);
+
+        assertThat(preAuthInfo.eligibleSensors).hasSize(1);
+    }
+
     private BiometricSensor getFingerprintSensor() {
         BiometricSensor sensor = new BiometricSensor(mContext, SENSOR_ID_FINGERPRINT,
                 TYPE_FINGERPRINT, BiometricManager.Authenticators.BIOMETRIC_STRONG,
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/UtilsTest.java b/services/tests/servicestests/src/com/android/server/biometrics/UtilsTest.java
index b05a819..cb75e1a 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/UtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/UtilsTest.java
@@ -179,7 +179,8 @@
         // The rest of the bits are not allowed to integrate with the public APIs
         for (int i = 8; i < 32; i++) {
             final int authenticator = 1 << i;
-            if (authenticator == Authenticators.DEVICE_CREDENTIAL) {
+            if (authenticator == Authenticators.DEVICE_CREDENTIAL
+                    || authenticator == Authenticators.MANDATORY_BIOMETRICS) {
                 continue;
             }
             assertFalse(Utils.isValidAuthenticatorConfig(1 << i));
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java
index f6da411..ffc7811 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java
@@ -28,7 +28,6 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertThrows;
 
 import android.hardware.biometrics.BiometricConstants;
 import android.os.Handler;
@@ -88,16 +87,14 @@
     private Handler mHandler;
     private BiometricSchedulerOperation mInterruptableOperation;
     private BiometricSchedulerOperation mNonInterruptableOperation;
-    private boolean mIsDebuggable;
 
     @Before
     public void setUp() {
         mHandler = new Handler(TestableLooper.get(this).getLooper());
-        mIsDebuggable = false;
         mInterruptableOperation = new BiometricSchedulerOperation(mInterruptableClientMonitor,
-                mClientCallback, () -> mIsDebuggable);
+                mClientCallback);
         mNonInterruptableOperation = new BiometricSchedulerOperation(mNonInterruptableClientMonitor,
-                mClientCallback, () -> mIsDebuggable);
+                mClientCallback);
 
         when(mInterruptableClientMonitor.isInterruptable()).thenReturn(true);
         when(mNonInterruptableClientMonitor.isInterruptable()).thenReturn(false);
@@ -143,32 +140,13 @@
     }
 
     @Test
-    public void testSecondStartWithCookieCrashesWhenDebuggable() {
+    public void testSecondStartWithCookieFails() {
         final int cookie = 5;
-        mIsDebuggable = true;
         when(mInterruptableClientMonitor.getCookie()).thenReturn(cookie);
         when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
 
-        final boolean started = mInterruptableOperation.startWithCookie(mOnStartCallback, cookie);
-        assertThat(started).isTrue();
-
-        assertThrows(IllegalStateException.class,
-                () -> mInterruptableOperation.startWithCookie(mOnStartCallback, cookie));
-    }
-
-    @Test
-    public void testSecondStartWithCookieFailsNicelyWhenNotDebuggable() {
-        final int cookie = 5;
-        mIsDebuggable = false;
-        when(mInterruptableClientMonitor.getCookie()).thenReturn(cookie);
-        when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
-
-        final boolean started = mInterruptableOperation.startWithCookie(mOnStartCallback, cookie);
-        assertThat(started).isTrue();
-
-        final boolean startedAgain = mInterruptableOperation.startWithCookie(mOnStartCallback,
-                cookie);
-        assertThat(startedAgain).isFalse();
+        assertThat(mInterruptableOperation.startWithCookie(mOnStartCallback, cookie)).isTrue();
+        assertThat(mInterruptableOperation.startWithCookie(mOnStartCallback, cookie)).isFalse();
     }
 
     @Test
@@ -217,56 +195,23 @@
     }
 
     @Test
-    public void secondStartCrashesWhenDebuggable() {
-        mIsDebuggable = true;
+    public void secondStartFails() {
         when(mInterruptableClientMonitor.getCookie()).thenReturn(0);
         when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
 
-        final boolean started = mInterruptableOperation.start(mOnStartCallback);
-        assertThat(started).isTrue();
-
-        assertThrows(IllegalStateException.class, () -> mInterruptableOperation.start(
-                mOnStartCallback));
-    }
-
-    @Test
-    public void secondStartFailsNicelyWhenNotDebuggable() {
-        mIsDebuggable = false;
-        when(mInterruptableClientMonitor.getCookie()).thenReturn(0);
-        when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
-
-        final boolean started = mInterruptableOperation.start(mOnStartCallback);
-        assertThat(started).isTrue();
-
-        final boolean startedAgain = mInterruptableOperation.start(mOnStartCallback);
-        assertThat(startedAgain).isFalse();
+        assertThat(mInterruptableOperation.start(mOnStartCallback)).isTrue();
+        assertThat(mInterruptableOperation.start(mOnStartCallback)).isFalse();
     }
 
     @Test
     public void doesNotStartWithCookie() {
-        // This class only throws exceptions when debuggable.
-        mIsDebuggable = true;
         when(mInterruptableClientMonitor.getCookie()).thenReturn(9);
-        assertThrows(IllegalStateException.class,
-                () -> mInterruptableOperation.start(mock(ClientMonitorCallback.class)));
+
+        assertThat(mInterruptableOperation.start(mock(ClientMonitorCallback.class))).isFalse();
     }
 
     @Test
-    public void cannotRestart() {
-        // This class only throws exceptions when debuggable.
-        mIsDebuggable = true;
-        when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
-
-        mInterruptableOperation.start(mOnStartCallback);
-
-        assertThrows(IllegalStateException.class,
-                () -> mInterruptableOperation.start(mock(ClientMonitorCallback.class)));
-    }
-
-    @Test
-    public void abortsNotRunning() {
-        // This class only throws exceptions when debuggable.
-        mIsDebuggable = true;
+    public void abortSuccessfulIfOperationNotRunning() {
         when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
 
         mInterruptableOperation.abort();
@@ -274,28 +219,17 @@
         assertThat(mInterruptableOperation.isFinished()).isTrue();
         verify(mInterruptableClientMonitor).unableToStart();
         verify(mInterruptableClientMonitor).destroy();
-        assertThrows(IllegalStateException.class,
-                () -> mInterruptableOperation.start(mock(ClientMonitorCallback.class)));
+        assertThat(mInterruptableOperation.start(mock(ClientMonitorCallback.class))).isFalse();
     }
 
     @Test
-    public void abortCrashesWhenDebuggableIfOperationIsRunning() {
-        mIsDebuggable = true;
+    public void abortFailsIfOperationIsRunning() {
         when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
 
         mInterruptableOperation.start(mOnStartCallback);
-
-        assertThrows(IllegalStateException.class, () -> mInterruptableOperation.abort());
-    }
-
-    @Test
-    public void abortFailsNicelyWhenNotDebuggableIfOperationIsRunning() {
-        mIsDebuggable = false;
-        when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
-
-        mInterruptableOperation.start(mOnStartCallback);
-
         mInterruptableOperation.abort();
+
+        assertThat(mInterruptableOperation.isFinished()).isFalse();
     }
 
     @Test
@@ -344,21 +278,7 @@
     }
 
     @Test
-    public void cancelCrashesWhenDebuggableIfOperationIsFinished() {
-        mIsDebuggable = true;
-        when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
-
-        mInterruptableOperation.abort();
-        assertThat(mInterruptableOperation.isFinished()).isTrue();
-
-        final ClientMonitorCallback cancelCb = mock(ClientMonitorCallback.class);
-        assertThrows(IllegalStateException.class, () -> mInterruptableOperation.cancel(mHandler,
-                cancelCb));
-    }
-
-    @Test
-    public void cancelFailsNicelyWhenNotDebuggableIfOperationIsFinished() {
-        mIsDebuggable = false;
+    public void cancelFailsIfOperationIsFinished() {
         when(mInterruptableClientMonitor.getFreshDaemon()).thenReturn(mHal);
 
         mInterruptableOperation.abort();
@@ -366,6 +286,9 @@
 
         final ClientMonitorCallback cancelCb = mock(ClientMonitorCallback.class);
         mInterruptableOperation.cancel(mHandler, cancelCb);
+
+        verify(mInterruptableClientMonitor, never()).cancel();
+        verify(mInterruptableClientMonitor, never()).cancelWithoutStarting(any());
     }
 
     @Test
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 ecd799f..6ec888c 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
@@ -406,8 +406,6 @@
         mContextInjector.getValue().accept(opContext);
 
         verify(mHal).onContextChanged(same(opContext));
-        verify(mHal, times(2)).setIgnoreDisplayTouches(
-                opContext.operationState.getFingerprintOperationState().isHardwareIgnoringTouches);
 
         client.stopHalOperation();
 
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java
index 0678140..e078238 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java
@@ -92,8 +92,6 @@
     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
 
     @Mock
-    private GenericWindowPolicyController.PipBlockedCallback mPipBlockedCallback;
-    @Mock
     private VirtualDeviceManager.ActivityListener mActivityListener;
     @Mock
     private GenericWindowPolicyController.IntentListenerCallback mIntentListenerCallback;
@@ -140,7 +138,6 @@
         gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false);
 
         assertThat(gwpc.isEnteringPipAllowed(TEST_UID)).isFalse();
-        verify(mPipBlockedCallback, timeout(TIMEOUT_MILLIS)).onEnteringPipBlocked(TEST_UID);
     }
 
     @Test
@@ -151,7 +148,6 @@
                 Arrays.asList(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
                         WindowConfiguration.WINDOWING_MODE_PINNED)));
         assertThat(gwpc.isEnteringPipAllowed(TEST_UID)).isTrue();
-        verify(mPipBlockedCallback, after(TIMEOUT_MILLIS).never()).onEnteringPipBlocked(TEST_UID);
     }
 
     @Test
@@ -746,7 +742,6 @@
                 /* crossTaskNavigationExemptions= */ new ArraySet<>(),
                 /* permissionDialogComponent= */ null,
                 /* activityListener= */ mActivityListener,
-                /* pipBlockedCallback= */ mPipBlockedCallback,
                 /* activityBlockedCallback= */ mActivityBlockedCallback,
                 /* secureWindowCallback= */ mSecureWindowCallback,
                 /* intentListenerCallback= */ mIntentListenerCallback,
@@ -767,7 +762,6 @@
                 /* crossTaskNavigationExemptions= */ new ArraySet<>(),
                 /* permissionDialogComponent= */ null,
                 /* activityListener= */ mActivityListener,
-                /* pipBlockedCallback= */ mPipBlockedCallback,
                 /* activityBlockedCallback= */ mActivityBlockedCallback,
                 /* secureWindowCallback= */ mSecureWindowCallback,
                 /* intentListenerCallback= */ mIntentListenerCallback,
@@ -789,7 +783,6 @@
                 /* crossTaskNavigationExemptions= */ new ArraySet<>(),
                 /* permissionDialogComponent= */ null,
                 /* activityListener= */ mActivityListener,
-                /* pipBlockedCallback= */ mPipBlockedCallback,
                 /* activityBlockedCallback= */ mActivityBlockedCallback,
                 /* secureWindowCallback= */ null,
                 /* intentListenerCallback= */ mIntentListenerCallback,
@@ -811,7 +804,6 @@
                 /* crossTaskNavigationExemptions= */ new ArraySet<>(),
                 /* permissionDialogComponent= */ null,
                 /* activityListener= */ mActivityListener,
-                /* pipBlockedCallback= */ mPipBlockedCallback,
                 /* activityBlockedCallback= */ mActivityBlockedCallback,
                 /* secureWindowCallback= */ null,
                 /* intentListenerCallback= */ mIntentListenerCallback,
@@ -833,7 +825,6 @@
                 /* crossTaskNavigationExemptions= */ new ArraySet<>(),
                 /* permissionDialogComponent= */ null,
                 /* activityListener= */ mActivityListener,
-                /* pipBlockedCallback= */ mPipBlockedCallback,
                 /* activityBlockedCallback= */ mActivityBlockedCallback,
                 /* secureWindowCallback= */ null,
                 /* intentListenerCallback= */ mIntentListenerCallback,
@@ -855,7 +846,6 @@
                 /* crossTaskNavigationExemptions= */ new ArraySet<>(),
                 /* permissionDialogComponent= */ null,
                 /* activityListener= */ mActivityListener,
-                /* pipBlockedCallback= */ mPipBlockedCallback,
                 /* activityBlockedCallback= */ mActivityBlockedCallback,
                 /* secureWindowCallback= */ null,
                 /* intentListenerCallback= */ mIntentListenerCallback,
@@ -877,7 +867,6 @@
                 /* crossTaskNavigationExemptions= */ Collections.singleton(blockedComponent),
                 /* permissionDialogComponent= */ null,
                 /* activityListener= */ mActivityListener,
-                /* pipBlockedCallback= */ mPipBlockedCallback,
                 /* activityBlockedCallback= */ mActivityBlockedCallback,
                 /* secureWindowCallback= */ null,
                 /* intentListenerCallback= */ mIntentListenerCallback,
@@ -899,7 +888,6 @@
                 /* crossTaskNavigationExemptions= */ Collections.singleton(allowedComponent),
                 /* permissionDialogComponent= */ null,
                 /* activityListener= */ mActivityListener,
-                /* pipBlockedCallback= */ mPipBlockedCallback,
                 /* activityBlockedCallback= */ mActivityBlockedCallback,
                 /* secureWindowCallback= */ null,
                 /* intentListenerCallback= */ mIntentListenerCallback,
@@ -922,7 +910,6 @@
                 /* crossTaskNavigationExemptions= */ new ArraySet<>(),
                 /* permissionDialogComponent= */ permissionComponent,
                 /* activityListener= */ mActivityListener,
-                /* pipBlockedCallback= */ mPipBlockedCallback,
                 /* activityBlockedCallback= */ mActivityBlockedCallback,
                 /* secureWindowCallback= */ null,
                 /* intentListenerCallback= */ mIntentListenerCallback,
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
index 52f28b9..b946a43 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
@@ -87,7 +87,6 @@
                         /* crossTaskNavigationExemptions= */ new ArraySet<>(),
                         /* permissionDialogComponent */ null,
                         /* activityListener= */ null,
-                        /* pipBlockedCallback= */ null,
                         /* activityBlockedCallback= */ null,
                         /* secureWindowCallback= */ null,
                         /* intentListenerCallback= */ null,
diff --git a/services/tests/servicestests/src/com/android/server/compat/ApplicationInfoBuilder.java b/services/tests/servicestests/src/com/android/server/compat/ApplicationInfoBuilder.java
index c165c66..d8fd266a 100644
--- a/services/tests/servicestests/src/com/android/server/compat/ApplicationInfoBuilder.java
+++ b/services/tests/servicestests/src/com/android/server/compat/ApplicationInfoBuilder.java
@@ -21,8 +21,10 @@
 class ApplicationInfoBuilder {
     private boolean mIsDebuggable;
     private int mTargetSdk;
+    private int mUid;
     private String mPackageName;
     private long mVersionCode;
+    private boolean mIsSystemApp;
 
     private ApplicationInfoBuilder() {
         mTargetSdk = -1;
@@ -42,6 +44,16 @@
         return this;
     }
 
+    ApplicationInfoBuilder systemApp() {
+        mIsSystemApp = true;
+        return this;
+    }
+
+    ApplicationInfoBuilder withUid(int uid) {
+        mUid = uid;
+        return this;
+    }
+
     ApplicationInfoBuilder withPackageName(String packageName) {
         mPackageName = packageName;
         return this;
@@ -60,6 +72,10 @@
         applicationInfo.packageName = mPackageName;
         applicationInfo.targetSdkVersion = mTargetSdk;
         applicationInfo.longVersionCode = mVersionCode;
+        applicationInfo.uid = mUid;
+        if (mIsSystemApp) {
+            applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+        }
         return applicationInfo;
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
index 9accd49..9df7a36 100644
--- a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
@@ -29,6 +29,7 @@
 
 import android.compat.Compatibility.ChangeConfig;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.os.Build;
@@ -36,6 +37,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.compat.AndroidBuildClassifier;
+import com.android.internal.compat.ChangeReporter;
 import com.android.internal.compat.CompatibilityChangeConfig;
 import com.android.internal.compat.CompatibilityChangeInfo;
 import com.android.server.LocalServices;
@@ -65,6 +67,8 @@
     CompatConfig mCompatConfig;
     @Mock
     private AndroidBuildClassifier mBuildClassifier;
+    @Mock
+    private ChangeReporter mChangeReporter;
 
     @Before
     public void setUp() throws Exception {
@@ -78,7 +82,8 @@
         when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt()))
             .thenThrow(new PackageManager.NameNotFoundException());
         mCompatConfig = new CompatConfig(mBuildClassifier, mContext);
-        mPlatformCompat = new PlatformCompat(mContext, mCompatConfig, mBuildClassifier);
+        mPlatformCompat =
+                new PlatformCompat(mContext, mCompatConfig, mBuildClassifier, mChangeReporter);
         // Assume userdebug/eng non-final build
         mCompatConfig.forceNonDebuggableFinalForTest(false);
         when(mBuildClassifier.isDebuggableBuild()).thenReturn(true);
@@ -100,7 +105,8 @@
                 .addLoggingOnlyChangeWithId(7L)
                 .addDisabledOverridableChangeWithId(8L)
                 .build();
-        mPlatformCompat = new PlatformCompat(mContext, mCompatConfig, mBuildClassifier);
+        mPlatformCompat =
+                new PlatformCompat(mContext, mCompatConfig, mBuildClassifier, mChangeReporter);
         assertThat(mPlatformCompat.listAllChanges()).asList().containsExactly(
                 new CompatibilityChangeInfo(1L, "", -1, -1, false, false, "", false),
                 new CompatibilityChangeInfo(2L, "change2", -1, -1, true, false, "", false),
@@ -128,7 +134,8 @@
                 .addLoggingOnlyChangeWithId(7L)
                 .addEnableSinceSdkChangeWithId(31, 8L)
                 .build();
-        mPlatformCompat = new PlatformCompat(mContext, mCompatConfig, mBuildClassifier);
+        mPlatformCompat =
+                new PlatformCompat(mContext, mCompatConfig, mBuildClassifier, mChangeReporter);
         assertThat(mPlatformCompat.listUIChanges()).asList().containsExactly(
                 new CompatibilityChangeInfo(1L, "", -1, -1, false, false, "", false),
                 new CompatibilityChangeInfo(2L, "change2", -1, -1, true, false, "", false),
@@ -146,7 +153,8 @@
                 .addEnableAfterSdkChangeWithId(Build.VERSION_CODES.O, 3L)
                 .build();
         mCompatConfig.forceNonDebuggableFinalForTest(true);
-        mPlatformCompat = new PlatformCompat(mContext, mCompatConfig, mBuildClassifier);
+        mPlatformCompat =
+                new PlatformCompat(mContext, mCompatConfig, mBuildClassifier, mChangeReporter);
 
         // Before adding overrides.
         assertThat(mPlatformCompat.isChangeEnabledByPackageName(1, PACKAGE_NAME, 0)).isTrue();
@@ -369,4 +377,68 @@
         // Listener not called when a non existing override is removed.
         verify(mListener1, never()).onCompatChange(PACKAGE_NAME);
     }
+
+    @Test
+    public void testReportChange() throws Exception {
+        ApplicationInfo appInfo = ApplicationInfoBuilder.create().withUid(123).build();
+        mPlatformCompat.reportChange(1L, appInfo);
+        verify(mChangeReporter).reportChange(123, 1L, ChangeReporter.STATE_LOGGED, false, true);
+
+        ApplicationInfo systemAppInfo =
+                ApplicationInfoBuilder.create().withUid(123).systemApp().build();
+        mPlatformCompat.reportChange(1L, systemAppInfo);
+        verify(mChangeReporter).reportChange(123, 1L, ChangeReporter.STATE_LOGGED, true, true);
+    }
+
+    @Test
+    public void testReportChangeByPackageName() throws Exception {
+        when(mPackageManagerInternal.getApplicationInfo(
+                        eq(PACKAGE_NAME), eq(0L), anyInt(), anyInt()))
+                .thenReturn(
+                        ApplicationInfoBuilder.create()
+                                .withPackageName(PACKAGE_NAME)
+                                .withUid(123)
+                                .build());
+
+        mPlatformCompat.reportChangeByPackageName(1L, PACKAGE_NAME, 123);
+        verify(mChangeReporter).reportChange(123, 1L, ChangeReporter.STATE_LOGGED, false, true);
+
+        String SYSTEM_PACKAGE_NAME = "my.system.package";
+
+        when(mPackageManagerInternal.getApplicationInfo(
+                        eq(SYSTEM_PACKAGE_NAME), eq(0L), anyInt(), anyInt()))
+                .thenReturn(
+                        ApplicationInfoBuilder.create()
+                                .withPackageName(SYSTEM_PACKAGE_NAME)
+                                .withUid(123)
+                                .systemApp()
+                                .build());
+
+        mPlatformCompat.reportChangeByPackageName(1L, SYSTEM_PACKAGE_NAME, 123);
+        verify(mChangeReporter).reportChange(123, 1L, ChangeReporter.STATE_LOGGED, true, true);
+    }
+
+    @Test
+    public void testIsChangeEnabled() throws Exception {
+        mCompatConfig =
+                CompatConfigBuilder.create(mBuildClassifier, mContext)
+                        .addEnabledChangeWithId(1L)
+                        .addDisabledChangeWithId(2L)
+                        .addEnabledChangeWithId(3L)
+                        .build();
+        mCompatConfig.forceNonDebuggableFinalForTest(true);
+        mPlatformCompat =
+                new PlatformCompat(mContext, mCompatConfig, mBuildClassifier, mChangeReporter);
+
+        ApplicationInfo appInfo = ApplicationInfoBuilder.create().withUid(123).build();
+        assertThat(mPlatformCompat.isChangeEnabled(1L, appInfo)).isTrue();
+        verify(mChangeReporter).reportChange(123, 1L, ChangeReporter.STATE_ENABLED, false, false);
+        assertThat(mPlatformCompat.isChangeEnabled(2L, appInfo)).isFalse();
+        verify(mChangeReporter).reportChange(123, 2L, ChangeReporter.STATE_DISABLED, false, false);
+
+        ApplicationInfo systemAppInfo =
+                ApplicationInfoBuilder.create().withUid(123).systemApp().build();
+        assertThat(mPlatformCompat.isChangeEnabled(3L, systemAppInfo)).isTrue();
+        verify(mChangeReporter).reportChange(123, 3L, ChangeReporter.STATE_ENABLED, true, false);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
index 2a4b797..87b52e6 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -2012,38 +2012,122 @@
     }
 
     @Test
-    public void handleStandby_fromActiveSource_standby() {
-        mPowerManager.setInteractive(true);
-        mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+    public void handleStandby_fromActiveSource_previousActiveSourceSet_standby() {
+        mHdmiCecLocalDeviceTv = new MockTvDevice(mHdmiControlService);
+        HdmiCecMessage activeSourceFromPlayback =
+                HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_1, 0x1000);
+        HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1,
+                ADDR_TV);
         mTestLooper.dispatchAll();
 
+        assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
+                .isFalse();
+        mPowerManager.setInteractive(true);
+        mTestLooper.dispatchAll();
+
+        mHdmiCecLocalDeviceTv.dispatchMessage(activeSourceFromPlayback);
         mHdmiControlService.setActiveSource(ADDR_PLAYBACK_1, 0x1000,
                 "HdmiCecLocalDeviceTvTest");
         mTestLooper.dispatchAll();
 
-        HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1,
-                ADDR_TV);
+        assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
+                .isTrue();
         assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(standbyMessage))
                 .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
 
         assertThat(mPowerManager.isInteractive()).isFalse();
+        assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
+                .isFalse();
     }
 
     @Test
-    public void handleStandby_fromNonActiveSource_noStandby() {
+    public void handleStandby_fromNonActiveSource_previousActiveSourceSet_noStandby() {
+        HdmiCecMessage activeSourceFromPlayback =
+                HdmiCecMessageBuilder.buildActiveSource(ADDR_PLAYBACK_2, 0x2000);
+        HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1,
+                ADDR_TV);
+        mHdmiCecLocalDeviceTv = new MockTvDevice(mHdmiControlService);
+        mTestLooper.dispatchAll();
+
+        assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
+                .isFalse();
         mPowerManager.setInteractive(true);
-        mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+
+        mHdmiCecLocalDeviceTv.dispatchMessage(activeSourceFromPlayback);
         mHdmiControlService.setActiveSource(ADDR_PLAYBACK_2, 0x2000,
                 "HdmiCecLocalDeviceTvTest");
         mTestLooper.dispatchAll();
 
-        HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1,
-                ADDR_TV);
+        assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
+                .isTrue();
         assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(standbyMessage))
                 .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
 
         assertThat(mPowerManager.isInteractive()).isTrue();
     }
+
+    @Test
+    public void handleStandby_fromNonActiveSource_previousActiveSourceNotSet_Standby() {
+        HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(ADDR_PLAYBACK_1,
+                ADDR_TV);
+        mHdmiCecLocalDeviceTv = new MockTvDevice(mHdmiControlService);
+        mTestLooper.dispatchAll();
+
+        assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
+                .isFalse();
+        mPowerManager.setInteractive(true);
+
+        assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
+                .isFalse();
+        assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(standbyMessage))
+                .isEqualTo(Constants.HANDLED);
+        mTestLooper.dispatchAll();
+
+        assertThat(mPowerManager.isInteractive()).isFalse();
+        assertThat(mHdmiCecLocalDeviceTv.getWasActiveSourceSetToConnectedDevice())
+                .isFalse();
+    }
+
+    @Test
+    public void handleReportPhysicalAddress_DeviceDiscoveryActionInProgress_noNewDeviceAction() {
+        mHdmiControlService.getHdmiCecNetwork().clearDeviceList();
+        mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS);
+        mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+        mNativeWrapper.clearResultMessages();
+        mTestLooper.dispatchAll();
+
+        HdmiCecMessage reportPhysicalAddressFromPlayback1 =
+                HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
+                        ADDR_PLAYBACK_1, 0x1000, HdmiDeviceInfo.DEVICE_PLAYBACK);
+        HdmiCecMessage reportPhysicalAddressFromPlayback2 =
+                HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
+                        ADDR_PLAYBACK_2, 0x2000, HdmiDeviceInfo.DEVICE_PLAYBACK);
+        HdmiCecMessage giveOsdName = HdmiCecMessageBuilder.buildGiveOsdNameCommand(
+                ADDR_TV, ADDR_PLAYBACK_2);
+        // Skip state waiting for <Report Physical Address> for DeviceDiscoveryAction s.t. message
+        // can be dispatched to local device TV.
+        mNativeWrapper.onCecMessage(reportPhysicalAddressFromPlayback1);
+        mNativeWrapper.clearResultMessages();
+        mTestLooper.dispatchAll();
+
+        mNativeWrapper.onCecMessage(reportPhysicalAddressFromPlayback2);
+        mTestLooper.dispatchAll();
+
+        // NewDeviceAction did not start and <Give OSD Name> was not sent.
+        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveOsdName);
+    }
+
+    protected static class MockTvDevice extends HdmiCecLocalDeviceTv {
+        MockTvDevice(HdmiControlService service) {
+            super(service);
+        }
+
+        @Override
+        protected int handleActiveSource(HdmiCecMessage message) {
+            setWasActiveSourceSetToConnectedDevice(true);
+            return super.handleActiveSource(message);
+        }
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index 37065fd..02d3b59 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -1424,6 +1424,39 @@
 
     @MediumTest
     @Test
+    public void testSerialNumberAfterUserRemoval() {
+        final UserInfo user = mUserManager.createUser("Test User", 0);
+        assertThat(user).isNotNull();
+
+        final int userId = user.id;
+        assertThat(mUserManager.getUserSerialNumber(userId))
+            .isEqualTo(user.serialNumber);
+        mUsersToRemove.add(userId);
+        removeUser(userId);
+        int serialNumber = mUserManager.getUserSerialNumber(userId);
+        int timeout = REMOVE_USER_TIMEOUT_SECONDS * 5; // called every 200ms
+
+        // Wait for the user to be removed from memory
+        while(serialNumber > 0 && timeout > 0){
+          sleep(200);
+          timeout--;
+          serialNumber = mUserManager.getUserSerialNumber(userId);
+        }
+        assertThat(serialNumber).isEqualTo(-1);
+    }
+
+
+    private void sleep(long millis) {
+        try {
+            Thread.sleep(millis);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    @MediumTest
+    @Test
     public void testMaxUsers() {
         int N = UserManager.getMaxSupportedUsers();
         int count = mUserManager.getUsers().size();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/CountdownConditionProviderTest.java b/services/tests/uiservicestests/src/com/android/server/notification/CountdownConditionProviderTest.java
index ddb9b43..58a1d9c 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/CountdownConditionProviderTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/CountdownConditionProviderTest.java
@@ -16,12 +16,15 @@
 
 package com.android.server.notification;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 
 import android.app.Application;
 import android.app.PendingIntent;
+import android.content.ComponentName;
 import android.content.Intent;
 import android.net.Uri;
 import android.testing.AndroidTestingRunner;
@@ -66,6 +69,12 @@
    }
 
     @Test
+    public void getComponent_returnsComponent() {
+        assertThat(mService.getComponent()).isEqualTo(new ComponentName("android",
+                "com.android.server.notification.CountdownConditionProvider"));
+    }
+
+    @Test
     public void testGetPendingIntent() {
         PendingIntent pi = mService.getPendingIntent(Uri.EMPTY);
         assertEquals(PackageManagerService.PLATFORM_PACKAGE_NAME, pi.getIntent().getPackage());
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/EventConditionProviderTest.java b/services/tests/uiservicestests/src/com/android/server/notification/EventConditionProviderTest.java
index 4c440ca..4af96ef 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/EventConditionProviderTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/EventConditionProviderTest.java
@@ -16,14 +16,16 @@
 
 package com.android.server.notification;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 
 import android.app.Application;
 import android.app.PendingIntent;
+import android.content.ComponentName;
 import android.content.Intent;
-import android.net.Uri;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
 
@@ -63,7 +65,13 @@
         service.onCreate();
         service.onBind(startIntent);
         mService = spy(service);
-   }
+    }
+
+    @Test
+    public void getComponent_returnsComponent() {
+        assertThat(mService.getComponent()).isEqualTo(new ComponentName("android",
+                "com.android.server.notification.EventConditionProvider"));
+    }
 
     @Test
     public void testGetPendingIntent() {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
index 8a7d276..225c1dc 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
@@ -20,13 +20,23 @@
 import static android.app.Notification.FLAG_BUBBLE;
 import static android.app.Notification.FLAG_CAN_COLORIZE;
 import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
+import static android.app.Notification.FLAG_GROUP_SUMMARY;
 import static android.app.Notification.FLAG_NO_CLEAR;
 import static android.app.Notification.FLAG_ONGOING_EVENT;
+import static android.app.Notification.GROUP_ALERT_ALL;
+import static android.app.Notification.GROUP_ALERT_CHILDREN;
+import static android.app.Notification.GROUP_ALERT_SUMMARY;
 import static android.app.Notification.VISIBILITY_PRIVATE;
 import static android.app.Notification.VISIBILITY_PUBLIC;
 import static android.app.Notification.VISIBILITY_SECRET;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING;
 import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
 
+import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
+import static com.android.server.notification.GroupHelper.AGGREGATE_GROUP_KEY;
+import static com.android.server.notification.GroupHelper.AUTOGROUP_KEY;
 import static com.android.server.notification.GroupHelper.BASE_FLAGS;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -41,6 +51,7 @@
 import static org.mockito.Mockito.doReturn;
 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.times;
 import static org.mockito.Mockito.verify;
@@ -49,6 +60,7 @@
 
 import android.annotation.SuppressLint;
 import android.app.Notification;
+import android.app.NotificationChannel;
 import android.content.pm.PackageManager;
 import android.graphics.Color;
 import android.graphics.drawable.AdaptiveIconDrawable;
@@ -66,6 +78,7 @@
 
 import com.android.internal.R;
 import com.android.server.UiServiceTestCase;
+import com.android.server.notification.GroupHelper.CachedSummary;
 import com.android.server.notification.GroupHelper.NotificationAttributes;
 
 import org.junit.Before;
@@ -90,11 +103,15 @@
     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
 
     private final int DEFAULT_VISIBILITY = VISIBILITY_PRIVATE;
+    private final int DEFAULT_GROUP_ALERT = GROUP_ALERT_CHILDREN;
+
+    private final String TEST_CHANNEL_ID = "TEST_CHANNEL_ID";
 
     private @Mock GroupHelper.Callback mCallback;
     private @Mock PackageManager mPackageManager;
 
     private final static int AUTOGROUP_AT_COUNT = 7;
+    private final static int AUTOGROUP_SINGLETONS_AT_COUNT = 2;
     private GroupHelper mGroupHelper;
     private @Mock Icon mSmallIcon;
 
@@ -113,7 +130,7 @@
         MockitoAnnotations.initMocks(this);
 
         mGroupHelper = new GroupHelper(getContext(), mPackageManager, AUTOGROUP_AT_COUNT,
-                mCallback);
+                AUTOGROUP_SINGLETONS_AT_COUNT, mCallback);
 
         NotificationRecord r = mock(NotificationRecord.class);
         StatusBarNotification sbn = getSbn("package", 0, "0", UserHandle.SYSTEM);
@@ -124,7 +141,7 @@
 
     private StatusBarNotification getSbn(String pkg, int id, String tag,
             UserHandle user, String groupKey, Icon smallIcon, int iconColor) {
-        Notification.Builder nb = new Notification.Builder(getContext(), "test_channel_id")
+        Notification.Builder nb = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
                 .setContentTitle("A")
                 .setWhen(1205)
                 .setSmallIcon(smallIcon)
@@ -146,15 +163,54 @@
         return getSbn(pkg, id, tag, user, null);
     }
 
+    private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
+            UserHandle user) {
+        return getNotificationRecord(pkg, id, tag, user, null, false);
+    }
+
+    private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
+            UserHandle user, String groupKey, boolean isSummary) {
+        return getNotificationRecord(pkg, id, tag, user, groupKey, isSummary, IMPORTANCE_DEFAULT);
+    }
+
+    private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
+            UserHandle user, String groupKey, boolean isSummary, int importance) {
+        return getNotificationRecord(pkg, id, tag, user, groupKey, isSummary,
+                new NotificationChannel(TEST_CHANNEL_ID, TEST_CHANNEL_ID, importance));
+    }
+
+    private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
+            UserHandle user, String groupKey, boolean isSummary, NotificationChannel channel) {
+        StatusBarNotification sbn = getSbn(pkg, id, tag, user, groupKey);
+        if (isSummary) {
+            sbn.getNotification().flags |= FLAG_GROUP_SUMMARY;
+        }
+        return new NotificationRecord(getContext(), sbn, channel);
+    }
+
+    private NotificationRecord getNotificationRecord(StatusBarNotification sbn) {
+        return new NotificationRecord(getContext(), sbn,
+            new NotificationChannel(TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT));
+    }
+
     private NotificationAttributes getNotificationAttributes(int flags) {
-        return new NotificationAttributes(flags, mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY);
+        return new NotificationAttributes(flags, mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY,
+                DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
+    }
+
+    private String getExpectedAutogroupKey(final NotificationRecord record) {
+        if (android.service.notification.Flags.notificationForceGrouping()) {
+            return GroupHelper.getFullAggregateGroupKey(record);
+        } else {
+            return AUTOGROUP_KEY;
+        }
     }
 
     @Test
     public void testGetAutogroupSummaryFlags_noChildren() {
         ArrayMap<String, NotificationAttributes> children = new ArrayMap<>();
 
-        assertEquals(BASE_FLAGS, mGroupHelper.getAutogroupSummaryFlags(children));
+        assertEquals(BASE_FLAGS, GroupHelper.getAutogroupSummaryFlags(children));
     }
 
     @Test
@@ -165,7 +221,7 @@
         children.put("c", getNotificationAttributes(FLAG_BUBBLE));
 
         assertEquals(FLAG_ONGOING_EVENT | BASE_FLAGS,
-                mGroupHelper.getAutogroupSummaryFlags(children));
+                GroupHelper.getAutogroupSummaryFlags(children));
     }
 
     @Test
@@ -176,7 +232,7 @@
         children.put("c", getNotificationAttributes(FLAG_BUBBLE));
 
         assertEquals(FLAG_NO_CLEAR | FLAG_ONGOING_EVENT | BASE_FLAGS,
-                mGroupHelper.getAutogroupSummaryFlags(children));
+                GroupHelper.getAutogroupSummaryFlags(children));
     }
 
     @Test
@@ -187,7 +243,7 @@
         children.put("c", getNotificationAttributes(FLAG_BUBBLE));
 
         assertEquals(FLAG_ONGOING_EVENT | BASE_FLAGS,
-                mGroupHelper.getAutogroupSummaryFlags(children));
+                GroupHelper.getAutogroupSummaryFlags(children));
     }
 
     @Test
@@ -199,7 +255,7 @@
         children.put("d", getNotificationAttributes(FLAG_ONGOING_EVENT));
 
         assertEquals(FLAG_ONGOING_EVENT | BASE_FLAGS,
-                mGroupHelper.getAutogroupSummaryFlags(children));
+                GroupHelper.getAutogroupSummaryFlags(children));
     }
 
     @Test
@@ -210,7 +266,7 @@
         children.put("c", getNotificationAttributes(FLAG_BUBBLE));
 
         assertEquals(BASE_FLAGS,
-                mGroupHelper.getAutogroupSummaryFlags(children));
+                GroupHelper.getAutogroupSummaryFlags(children));
     }
 
     @Test
@@ -222,7 +278,7 @@
         children.put("d", getNotificationAttributes(FLAG_AUTO_CANCEL | FLAG_FOREGROUND_SERVICE));
 
         assertEquals(FLAG_AUTO_CANCEL | BASE_FLAGS,
-                mGroupHelper.getAutogroupSummaryFlags(children));
+                GroupHelper.getAutogroupSummaryFlags(children));
     }
 
     @Test
@@ -235,15 +291,16 @@
                 FLAG_AUTO_CANCEL | FLAG_FOREGROUND_SERVICE | FLAG_ONGOING_EVENT));
 
         assertEquals(FLAG_AUTO_CANCEL| FLAG_ONGOING_EVENT | BASE_FLAGS,
-                mGroupHelper.getAutogroupSummaryFlags(children));
+                GroupHelper.getAutogroupSummaryFlags(children));
     }
 
     @Test
     public void testNoGroup_postingUnderLimit() {
         final String pkg = "package";
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
-            mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
-                    false);
+            mGroupHelper.onNotificationPosted(
+                getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
+                false);
         }
         verifyZeroInteractions(mCallback);
     }
@@ -253,11 +310,12 @@
         final String pkg = "package";
         final String pkg2 = "package2";
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
-            mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
-                    false);
+            mGroupHelper.onNotificationPosted(
+                getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
+                false);
         }
         mGroupHelper.onNotificationPosted(
-                getSbn(pkg2, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM), false);
+            getNotificationRecord(pkg2, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM), false);
         verifyZeroInteractions(mCallback);
     }
 
@@ -265,11 +323,12 @@
     public void testNoGroup_multiUser() {
         final String pkg = "package";
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
-            mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
-                    false);
+            mGroupHelper.onNotificationPosted(
+                getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
+                false);
         }
         mGroupHelper.onNotificationPosted(
-                getSbn(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.of(7)), false);
+            getNotificationRecord(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.of(7)), false);
         verifyZeroInteractions(mCallback);
     }
 
@@ -278,10 +337,11 @@
         final String pkg = "package";
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
             mGroupHelper.onNotificationPosted(
-                    getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
+                getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
         }
         mGroupHelper.onNotificationPosted(
-                getSbn(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM, "a"), false);
+            getNotificationRecord(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM, "a", false),
+            false);
         verifyZeroInteractions(mCallback);
     }
 
@@ -289,185 +349,241 @@
     @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary_alwaysAutogroup() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+                getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
             mGroupHelper.onNotificationPosted(
-                    getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
+                getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
         }
         verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+                anyInt(), eq(pkg), anyString(), eq(autogroupKey),
+                anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), eq(autogroupKey),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+                getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
             assertThat(mGroupHelper.onNotificationPosted(
-                    getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false)).isFalse();
+                    getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
+                    false)).isFalse();
         }
         assertThat(mGroupHelper.onNotificationPosted(
-                getSbn(pkg, AUTOGROUP_AT_COUNT - 1, String.valueOf(AUTOGROUP_AT_COUNT - 1),
+            getNotificationRecord(pkg, AUTOGROUP_AT_COUNT - 1, String.valueOf(AUTOGROUP_AT_COUNT - 1),
                         UserHandle.SYSTEM), false)).isTrue();
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(autogroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
     @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary_oneChildOngoing_summaryOngoing_alwaysAutogroup() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+                getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
             if (i == 0) {
-                sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
+                r.getNotification().flags |= FLAG_ONGOING_EVENT;
             }
-            mGroupHelper.onNotificationPosted(sbn, false);
+            mGroupHelper.onNotificationPosted(r, false);
         }
         verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(autogroupKey), anyInt(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_ONGOING_EVENT)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary_oneChildOngoing_summaryOngoing() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+                getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
             if (i == 0) {
-                sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
+                r.getNotification().flags |= FLAG_ONGOING_EVENT;
             }
-            mGroupHelper.onNotificationPosted(sbn, false);
+            mGroupHelper.onNotificationPosted(r, false);
         }
         verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(autogroupKey), anyInt(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_ONGOING_EVENT)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
     @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary_oneChildAutoCancel_summaryNotAutoCancel_alwaysAutogroup() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+            getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
             if (i == 0) {
-                sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
+                r.getNotification().flags |= FLAG_AUTO_CANCEL;
             }
-            mGroupHelper.onNotificationPosted(sbn, false);
+            mGroupHelper.onNotificationPosted(r, false);
         }
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(autogroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary_oneChildAutoCancel_summaryNotAutoCancel() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+                getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
             if (i == 0) {
-                sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
+                r.getNotification().flags |= FLAG_AUTO_CANCEL;
             }
-            mGroupHelper.onNotificationPosted(sbn, false);
+            mGroupHelper.onNotificationPosted(r, false);
         }
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(autogroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(),
+                eq(autogroupKey), anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
     @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary_allChildrenAutoCancel_summaryAutoCancel_alwaysAutogroup() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+                getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_AUTO_CANCEL;
+            mGroupHelper.onNotificationPosted(r, false);
         }
         verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(autogroupKey), anyInt(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_AUTO_CANCEL)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), eq(autogroupKey),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary_allChildrenAutoCancel_summaryAutoCancel() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+                getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_AUTO_CANCEL;
+            mGroupHelper.onNotificationPosted(r, false);
         }
         verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(autogroupKey), anyInt(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_AUTO_CANCEL)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(),
+                eq(autogroupKey), anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
     @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary_summaryAutoCancelNoClear_alwaysAutogroup() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+                getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_AUTO_CANCEL;
             if (i == 0) {
-                sbn.getNotification().flags |= FLAG_NO_CLEAR;
+                r.getNotification().flags |= FLAG_NO_CLEAR;
             }
-            mGroupHelper.onNotificationPosted(sbn, false);
+            mGroupHelper.onNotificationPosted(r, false);
         }
         verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(autogroupKey), anyInt(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_AUTO_CANCEL | FLAG_NO_CLEAR)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), eq(autogroupKey),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAddSummary_summaryAutoCancelNoClear() {
         final String pkg = "package";
+        final String autogroupKey = getExpectedAutogroupKey(
+                getNotificationRecord(pkg, 0, String.valueOf(0), UserHandle.SYSTEM));
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_AUTO_CANCEL;
             if (i == 0) {
-                sbn.getNotification().flags |= FLAG_NO_CLEAR;
+                r.getNotification().flags |= FLAG_NO_CLEAR;
             }
-            mGroupHelper.onNotificationPosted(sbn, false);
+            mGroupHelper.onNotificationPosted(r, false);
         }
         verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(autogroupKey), anyInt(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_AUTO_CANCEL | FLAG_NO_CLEAR)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(),
+                eq(autogroupKey), anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
@@ -475,15 +591,16 @@
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
-            notifications.add(sbn);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_ONGOING_EVENT;
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // One notification is no longer ongoing
@@ -491,7 +608,7 @@
         mGroupHelper.onNotificationPosted(notifications.get(0), true);
 
         // Summary should keep FLAG_ONGOING_EVENT if any child has it
-        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_ONGOING_EVENT)));
     }
 
@@ -500,24 +617,25 @@
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
             if (i == 0) {
-                sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
+                r.getNotification().flags |= FLAG_ONGOING_EVENT;
             }
-            notifications.add(sbn);
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // remove ongoing
         mGroupHelper.onNotificationRemoved(notifications.get(0));
 
         // Summary is no longer ongoing
-        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
                 eq(getNotificationAttributes(BASE_FLAGS)));
     }
 
@@ -526,14 +644,15 @@
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            notifications.add(sbn);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // update to ongoing
@@ -541,7 +660,7 @@
         mGroupHelper.onNotificationPosted(notifications.get(0), true);
 
         // Summary is now ongoing
-        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_ONGOING_EVENT)));
     }
 
@@ -550,23 +669,25 @@
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            notifications.add(sbn);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM);
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // add ongoing
-        StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT + 1, null, UserHandle.SYSTEM);
-        sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
-        mGroupHelper.onNotificationPosted(sbn, true);
+        NotificationRecord r = getNotificationRecord(pkg, AUTOGROUP_AT_COUNT + 1, null,
+                UserHandle.SYSTEM);
+        r.getNotification().flags |= FLAG_ONGOING_EVENT;
+        mGroupHelper.onNotificationPosted(r, true);
 
         // Summary is now ongoing
-        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_ONGOING_EVENT)));
     }
 
@@ -575,51 +696,84 @@
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM);
             if (i == 0) {
-                sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
+                r.getNotification().flags |= FLAG_ONGOING_EVENT;
             }
-            notifications.add(sbn);
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // app group the ongoing child
-        StatusBarNotification sbn = getSbn(pkg, 0, "0", UserHandle.SYSTEM, "app group now");
-        mGroupHelper.onNotificationPosted(sbn, true);
+        NotificationRecord r = getNotificationRecord(pkg, 0, "0", UserHandle.SYSTEM,
+                "app group now", false);
+        mGroupHelper.onNotificationPosted(r, true);
 
         // Summary is no longer ongoing
-        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
                 eq(getNotificationAttributes(BASE_FLAGS)));
     }
 
     @Test
+    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testAutoGrouped_singleOngoing_removeNonOngoingChild() {
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
             if (i == 0) {
-                sbn.getNotification().flags |= FLAG_ONGOING_EVENT;
+                r.getNotification().flags |= FLAG_ONGOING_EVENT;
             }
-            notifications.add(sbn);
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // remove ongoing
         mGroupHelper.onNotificationRemoved(notifications.get(1));
 
         // Summary is still ongoing
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAutoGrouped_singleOngoing_removeNonOngoingChild_forceGrouping() {
+        final String pkg = "package";
+
+        // Post AUTOGROUP_AT_COUNT ongoing notifications
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM);
+            if (i == 0) {
+                r.getNotification().flags |= FLAG_ONGOING_EVENT;
+            }
+            notifications.add(r);
+        }
+
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
+        }
+
+        // remove ongoing
+        mGroupHelper.onNotificationRemoved(notifications.get(1));
+
+        // Summary is still ongoing
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
@@ -627,15 +781,16 @@
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
-            notifications.add(sbn);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_AUTO_CANCEL;
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // One notification is no longer autocancelable
@@ -643,7 +798,7 @@
         mGroupHelper.onNotificationPosted(notifications.get(0), true);
 
         // Summary should no longer be autocancelable
-        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
                 eq(getNotificationAttributes(BASE_FLAGS)));
     }
 
@@ -652,17 +807,18 @@
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
             if (i != 0) {
-                sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
+                r.getNotification().flags |= FLAG_AUTO_CANCEL;
             }
-            notifications.add(sbn);
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // Missing notification is now autocancelable
@@ -670,254 +826,327 @@
         mGroupHelper.onNotificationPosted(notifications.get(0), true);
 
         // Summary should now autocancelable
-        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
                 eq(getNotificationAttributes(BASE_FLAGS | FLAG_AUTO_CANCEL)));
     }
 
     @Test
+    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testAutoGrouped_allAutoCancel_updateChildAppGrouped() {
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
-            notifications.add(sbn);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_AUTO_CANCEL;
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // One notification is now grouped by app
-        StatusBarNotification sbn = getSbn(pkg, 0, "0", UserHandle.SYSTEM, "app group now");
-        mGroupHelper.onNotificationPosted(sbn, true);
+        NotificationRecord r = getNotificationRecord(pkg, 0, "0", UserHandle.SYSTEM,
+                "app group now", false);
+        mGroupHelper.onNotificationPosted(r, true);
 
         // Summary should be still be autocancelable
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
     }
 
     @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAutoGrouped_allAutoCancel_updateChildAppGrouped_forceGrouping() {
+        final String pkg = "package";
+
+        // Post AUTOGROUP_AT_COUNT ongoing notifications
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_AUTO_CANCEL;
+            notifications.add(r);
+        }
+
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
+        }
+
+        // One notification is now grouped by app
+        NotificationRecord r = getNotificationRecord(pkg, 0, "0", UserHandle.SYSTEM,
+            "app group now", false);
+        mGroupHelper.onNotificationPosted(r, true);
+
+        // Summary should be still be autocancelable
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+            any());
+    }
+
+    @Test
+    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testAutoGrouped_allAutoCancel_removeChild() {
         final String pkg = "package";
 
         // Post AUTOGROUP_AT_COUNT ongoing notifications
-        ArrayList<StatusBarNotification>  notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            sbn.getNotification().flags |= FLAG_AUTO_CANCEL;
-            notifications.add(sbn);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_AUTO_CANCEL;
+            notifications.add(r);
         }
 
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         mGroupHelper.onNotificationRemoved(notifications.get(0));
 
         // Summary should still be autocancelable
-        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), any());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAutoGrouped_allAutoCancel_removeChild_forceGrouping() {
+        final String pkg = "package";
+
+        // Post AUTOGROUP_AT_COUNT ongoing notifications
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM);
+            r.getNotification().flags |= FLAG_AUTO_CANCEL;
+            notifications.add(r);
+        }
+
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
+        }
+
+        mGroupHelper.onNotificationRemoved(notifications.get(0));
+
+        // Summary should still be autocancelable
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+            any());
     }
 
     @Test
     @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testDropToZeroRemoveGroup_disableFlag() {
         final String pkg = "package";
-        List<StatusBarNotification> posted = new ArrayList<>();
+        ArrayList<NotificationRecord> posted = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            posted.add(sbn);
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            posted.add(r);
+            mGroupHelper.onNotificationPosted(r, false);
         }
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(), anyString(),
+                anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
             mGroupHelper.onNotificationRemoved(posted.remove(0));
         }
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
         mGroupHelper.onNotificationRemoved(posted.remove(0));
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString(), anyString());
     }
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testDropToZeroRemoveGroup() {
         final String pkg = "package";
-        List<StatusBarNotification> posted = new ArrayList<>();
+        ArrayList<NotificationRecord> posted = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            posted.add(sbn);
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            posted.add(r);
+            mGroupHelper.onNotificationPosted(r, false);
         }
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(), anyString(),
+                anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
             mGroupHelper.onNotificationRemoved(posted.remove(0));
         }
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
         mGroupHelper.onNotificationRemoved(posted.remove(0));
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString(), anyString());
     }
 
     @Test
     @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAppStartsGrouping_disableFlag() {
         final String pkg = "package";
-        List<StatusBarNotification> posted = new ArrayList<>();
+        ArrayList<NotificationRecord> posted = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            posted.add(sbn);
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            posted.add(r);
+            mGroupHelper.onNotificationPosted(r, false);
         }
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                anyString(), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            final StatusBarNotification sbn =
-                    getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
-            sbn.setOverrideGroupKey("autogrouped");
-            mGroupHelper.onNotificationPosted(sbn, true);
-            verify(mCallback, times(1)).removeAutoGroup(sbn.getKey());
+            final NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "app group", false);
+            r.getSbn().setOverrideGroupKey("autogrouped");
+            mGroupHelper.onNotificationPosted(r, true);
+            verify(mCallback, times(1)).removeAutoGroup(r.getKey());
             if (i < AUTOGROUP_AT_COUNT - 1) {
-                verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+                verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(),
+                        anyString());
             }
         }
-        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString(), anyString());
     }
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testAppStartsGrouping() {
         final String pkg = "package";
-        List<StatusBarNotification> posted = new ArrayList<>();
+        ArrayList<NotificationRecord> posted = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            posted.add(sbn);
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM);
+            posted.add(r);
+            mGroupHelper.onNotificationPosted(r, false);
         }
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                anyString(), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            final StatusBarNotification sbn =
-                    getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
-            sbn.setOverrideGroupKey("autogrouped");
-            mGroupHelper.onNotificationPosted(sbn, true);
-            verify(mCallback, times(1)).removeAutoGroup(sbn.getKey());
+            final NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "app group", false);
+            r.getSbn().setOverrideGroupKey("autogrouped");
+            mGroupHelper.onNotificationPosted(r, true);
+            verify(mCallback, times(1)).removeAutoGroup(r.getKey());
             if (i < AUTOGROUP_AT_COUNT - 1) {
-                verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+                verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(),
+                        anyString());
             }
         }
-        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), anyString(), anyString());
     }
 
     @Test
     @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testNewNotificationsAddedToAutogroup_ifOriginalNotificationsCanceled_alwaysGroup() {
         final String pkg = "package";
-        List<StatusBarNotification> posted = new ArrayList<>();
+        ArrayList<NotificationRecord> posted = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            posted.add(sbn);
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM);
+            posted.add(r);
+            mGroupHelper.onNotificationPosted(r, false);
         }
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                anyString(), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
         for (int i = posted.size() - 2; i >= 0; i--) {
             mGroupHelper.onNotificationRemoved(posted.remove(i));
         }
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
-        // only one child remains
-        assertEquals(1, mGroupHelper.getNotGroupedByAppCount(UserHandle.USER_SYSTEM, pkg));
-
         // Add new notification; it should be autogrouped even though the total count is
         // < AUTOGROUP_AT_COUNT
-        final StatusBarNotification sbn = getSbn(pkg, 5, String.valueOf(5), UserHandle.SYSTEM);
-        posted.add(sbn);
-        assertThat(mGroupHelper.onNotificationPosted(sbn, true)).isFalse();
-        verify(mCallback, times(1)).addAutoGroup(sbn.getKey(), true);
+        final NotificationRecord r = getNotificationRecord(pkg, 5, String.valueOf(5),
+                UserHandle.SYSTEM);
+        final String autogroupKey = getExpectedAutogroupKey(r);
+        posted.add(r);
+        assertThat(mGroupHelper.onNotificationPosted(r, true)).isFalse();
+        verify(mCallback, times(1)).addAutoGroup(r.getKey(), autogroupKey, true);
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
                 eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(), any());
+        verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+                anyString(), anyInt(), any());
     }
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
     public void testNewNotificationsAddedToAutogroup_ifOriginalNotificationsCanceled() {
         final String pkg = "package";
-        List<StatusBarNotification> posted = new ArrayList<>();
+        ArrayList<NotificationRecord> posted = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
-            posted.add(sbn);
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM);
+            posted.add(r);
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                anyString(), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
         for (int i = posted.size() - 2; i >= 0; i--) {
             mGroupHelper.onNotificationRemoved(posted.remove(i));
         }
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
         Mockito.reset(mCallback);
 
-        // only one child remains
-        assertEquals(1, mGroupHelper.getNotGroupedByAppCount(UserHandle.USER_SYSTEM, pkg));
-
         // Add new notification; it should be autogrouped even though the total count is
         // < AUTOGROUP_AT_COUNT
-        final StatusBarNotification sbn = getSbn(pkg, 5, String.valueOf(5), UserHandle.SYSTEM);
-        posted.add(sbn);
-        assertThat(mGroupHelper.onNotificationPosted(sbn, true)).isTrue();
+        final NotificationRecord r = getNotificationRecord(pkg, 5, String.valueOf(5),
+                UserHandle.SYSTEM);
+        posted.add(r);
+        assertThat(mGroupHelper.onNotificationPosted(r, true)).isTrue();
         // addAutoGroup not called on sbn, because the autogrouping is expected to be done
         // synchronously.
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
-        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(),
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback).updateAutogroupSummary(anyInt(), anyString(), anyString(),
                 eq(getNotificationAttributes(BASE_FLAGS)));
-        verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(), any());
+        verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+                anyString(), anyInt(), any());
     }
 
     @Test
@@ -929,29 +1158,32 @@
         when(icon.sameAs(icon)).thenReturn(true);
         final int iconColor = Color.BLUE;
         final NotificationAttributes attr = new NotificationAttributes(BASE_FLAGS, icon, iconColor,
-                DEFAULT_VISIBILITY);
+                DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
 
         // Add notifications with same icon and color
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
-                    icon, iconColor);
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(
+                    getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null, icon, iconColor));
+            mGroupHelper.onNotificationPosted(r, false);
         }
         // Check that the summary would have the same icon and color
         verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(attr));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+                anyInt(), eq(pkg), anyString(), anyString(), anyInt(), eq(attr));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
 
         // After auto-grouping, add new notification with the same color
-        StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT,
-                String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor);
-        mGroupHelper.onNotificationPosted(sbn, true);
+        NotificationRecord r = getNotificationRecord(
+                getSbn(pkg, AUTOGROUP_AT_COUNT, String.valueOf(AUTOGROUP_AT_COUNT),
+                    UserHandle.SYSTEM,null, icon, iconColor));
+        mGroupHelper.onNotificationPosted(r, true);
 
         // Check that the summary was updated
         //NotificationAttributes newAttr = new NotificationAttributes(BASE_FLAGS, icon, iconColor);
-        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(attr));
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                eq(attr));
     }
 
     @Test
@@ -963,29 +1195,31 @@
         when(icon.sameAs(icon)).thenReturn(true);
         final int iconColor = Color.BLUE;
         final NotificationAttributes attr = new NotificationAttributes(BASE_FLAGS, icon, iconColor,
-                DEFAULT_VISIBILITY);
+                DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
 
         // Add notifications with same icon and color
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
-                    icon, iconColor);
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(
+                    getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null, icon, iconColor));
+            mGroupHelper.onNotificationPosted(r, false);
         }
         // Check that the summary would have the same icon and color
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(attr));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                anyString(), anyInt(), eq(attr));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
 
         // After auto-grouping, add new notification with the same color
-        StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT,
-                String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor);
-        mGroupHelper.onNotificationPosted(sbn, true);
+        NotificationRecord r = getNotificationRecord(getSbn(pkg, AUTOGROUP_AT_COUNT,
+            String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor));
+        mGroupHelper.onNotificationPosted(r, true);
 
         // Check that the summary was updated
         //NotificationAttributes newAttr = new NotificationAttributes(BASE_FLAGS, icon, iconColor);
-        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(attr));
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                eq(attr));
     }
 
     @Test
@@ -1004,33 +1238,37 @@
         doReturn(monochromeIcon).when(groupHelper).getMonochromeAppIcon(eq(pkg));
 
         final NotificationAttributes initialAttr = new NotificationAttributes(BASE_FLAGS,
-                initialIcon, initialIconColor, DEFAULT_VISIBILITY);
+                initialIcon, initialIconColor, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+                TEST_CHANNEL_ID);
 
         // Add notifications with same icon and color
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
-                    initialIcon, initialIconColor);
-            groupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(
+                getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
+                    initialIcon, initialIconColor));
+            groupHelper.onNotificationPosted(r, false);
         }
         // Check that the summary would have the same icon and color
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(initialAttr));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                anyString(), anyInt(), eq(initialAttr));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
 
         // After auto-grouping, add new notification with a different color
         final Icon newIcon = mock(Icon.class);
         final int newIconColor = Color.YELLOW;
-        StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT,
+        NotificationRecord r = getNotificationRecord(getSbn(pkg, AUTOGROUP_AT_COUNT,
                 String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, newIcon,
-                newIconColor);
-        groupHelper.onNotificationPosted(sbn, true);
+                newIconColor));
+        groupHelper.onNotificationPosted(r, true);
 
         // Summary should be updated to the default color and the icon to the monochrome icon
         NotificationAttributes newAttr = new NotificationAttributes(BASE_FLAGS, monochromeIcon,
-                COLOR_DEFAULT, DEFAULT_VISIBILITY);
-        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(newAttr));
+                COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                eq(newAttr));
     }
 
     @Test
@@ -1049,33 +1287,37 @@
         doReturn(monochromeIcon).when(groupHelper).getMonochromeAppIcon(eq(pkg));
 
         final NotificationAttributes initialAttr = new NotificationAttributes(BASE_FLAGS,
-                initialIcon, initialIconColor, DEFAULT_VISIBILITY);
+                initialIcon, initialIconColor, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+                TEST_CHANNEL_ID);
 
         // Add notifications with same icon and color
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
-                    initialIcon, initialIconColor);
-            groupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(
+                getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
+                    initialIcon, initialIconColor));
+            groupHelper.onNotificationPosted(r, false);
         }
         // Check that the summary would have the same icon and color
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(initialAttr));
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                anyString(), anyInt(), eq(initialAttr));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
 
         // After auto-grouping, add new notification with a different color
         final Icon newIcon = mock(Icon.class);
         final int newIconColor = Color.YELLOW;
-        StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT,
-                String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, newIcon,
-                newIconColor);
-        groupHelper.onNotificationPosted(sbn, true);
+        NotificationRecord r = getNotificationRecord(getSbn(pkg, AUTOGROUP_AT_COUNT,
+            String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, newIcon,
+            newIconColor));
+        groupHelper.onNotificationPosted(r, true);
 
         // Summary should be updated to the default color and the icon to the monochrome icon
         NotificationAttributes newAttr = new NotificationAttributes(BASE_FLAGS, monochromeIcon,
-                COLOR_DEFAULT, DEFAULT_VISIBILITY);
-        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(newAttr));
+                COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                eq(newAttr));
     }
 
     @Test
@@ -1087,32 +1329,35 @@
         when(icon.sameAs(icon)).thenReturn(true);
         final int iconColor = Color.BLUE;
         final NotificationAttributes attr = new NotificationAttributes(BASE_FLAGS, icon, iconColor,
-                VISIBILITY_PRIVATE);
+                VISIBILITY_PRIVATE, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
 
         // Add notifications with same icon and color and default visibility (private)
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
-                    icon, iconColor);
-            mGroupHelper.onNotificationPosted(sbn, false);
+            NotificationRecord r = getNotificationRecord(
+                getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
+                    icon, iconColor));
+            mGroupHelper.onNotificationPosted(r, false);
         }
         // Check that the summary has private visibility
         verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(attr));
+                anyInt(), eq(pkg), anyString(), anyString(), anyInt(), eq(attr));
 
-        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
 
         // After auto-grouping, add new notification with public visibility
-        StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT,
-                String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor);
-        sbn.getNotification().visibility = VISIBILITY_PUBLIC;
-        mGroupHelper.onNotificationPosted(sbn, true);
+        NotificationRecord r = getNotificationRecord(getSbn(pkg, AUTOGROUP_AT_COUNT,
+            String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor));
+        r.getNotification().visibility = VISIBILITY_PUBLIC;
+        mGroupHelper.onNotificationPosted(r, true);
 
         // Check that the summary visibility was updated
         NotificationAttributes newAttr = new NotificationAttributes(BASE_FLAGS, icon, iconColor,
-                VISIBILITY_PUBLIC);
-        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(newAttr));
+                VISIBILITY_PUBLIC, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                eq(newAttr));
     }
 
     @Test
@@ -1124,71 +1369,116 @@
         when(icon.sameAs(icon)).thenReturn(true);
         final int iconColor = Color.BLUE;
         final NotificationAttributes attr = new NotificationAttributes(BASE_FLAGS, icon, iconColor,
-                VISIBILITY_PRIVATE);
+                VISIBILITY_PRIVATE, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
 
         // Add notifications with same icon and color and default visibility (private)
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
-                    icon, iconColor);
-            assertThat(mGroupHelper.onNotificationPosted(sbn, false)).isFalse();
+            NotificationRecord r = getNotificationRecord(
+                getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
+                    icon, iconColor));
+            assertThat(mGroupHelper.onNotificationPosted(r, false)).isFalse();
         }
         // The last notification added will reach the autogroup threshold.
-        StatusBarNotification sbn = getSbn(pkg, AUTOGROUP_AT_COUNT - 1,
-                String.valueOf(AUTOGROUP_AT_COUNT - 1), UserHandle.SYSTEM, null, icon, iconColor);
-        assertThat(mGroupHelper.onNotificationPosted(sbn, false)).isTrue();
+        NotificationRecord r = getNotificationRecord(getSbn(pkg, AUTOGROUP_AT_COUNT - 1,
+            String.valueOf(AUTOGROUP_AT_COUNT - 1), UserHandle.SYSTEM, null, icon, iconColor));
+        assertThat(mGroupHelper.onNotificationPosted(r, false)).isTrue();
 
         // Check that the summary has private visibility
-        verify(mCallback, times(1)).addAutoGroupSummary(
-                anyInt(), eq(pkg), anyString(), eq(attr));
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(), anyString(),
+                anyInt(), eq(attr));
         // The last sbn is expected to be added to autogroup synchronously.
-        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyBoolean());
+        verify(mCallback, times(AUTOGROUP_AT_COUNT - 1)).addAutoGroup(anyString(), anyString(),
+                anyBoolean());
         verify(mCallback, never()).removeAutoGroup(anyString());
-        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
 
         // After auto-grouping, add new notification with public visibility
-        sbn = getSbn(pkg, AUTOGROUP_AT_COUNT,
-                String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor);
-        sbn.getNotification().visibility = VISIBILITY_PUBLIC;
-        assertThat(mGroupHelper.onNotificationPosted(sbn, true)).isTrue();
+        r = getNotificationRecord(getSbn(pkg, AUTOGROUP_AT_COUNT,
+            String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, null, icon, iconColor));
+        r.getNotification().visibility = VISIBILITY_PUBLIC;
+        assertThat(mGroupHelper.onNotificationPosted(r, true)).isTrue();
 
         // Check that the summary visibility was updated
         NotificationAttributes newAttr = new NotificationAttributes(BASE_FLAGS, icon, iconColor,
-                VISIBILITY_PUBLIC);
-        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(newAttr));
+                VISIBILITY_PUBLIC, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                eq(newAttr));
     }
 
     @Test
     @EnableFlags(Flags.FLAG_AUTOGROUP_SUMMARY_ICON_UPDATE)
+    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testAutoGrouped_diffIcon_diffColor_removeChild_updateTo_sameIcon_sameColor() {
         final String pkg = "package";
         final Icon initialIcon = mock(Icon.class);
         when(initialIcon.sameAs(initialIcon)).thenReturn(true);
         final int initialIconColor = Color.BLUE;
         final NotificationAttributes initialAttr = new NotificationAttributes(
-                GroupHelper.FLAG_INVALID, initialIcon, initialIconColor, DEFAULT_VISIBILITY);
+                GroupHelper.FLAG_INVALID, initialIcon, initialIconColor, DEFAULT_VISIBILITY,
+                DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
 
         // Add AUTOGROUP_AT_COUNT-1 notifications with same icon and color
-        ArrayList<StatusBarNotification> notifications = new ArrayList<>();
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
-            StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
-                    initialIcon, initialIconColor);
-            notifications.add(sbn);
+            NotificationRecord r = getNotificationRecord(
+                getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
+                    initialIcon, initialIconColor));
+            notifications.add(r);
         }
         // And an additional notification with different icon and color
         final int lastIdx = AUTOGROUP_AT_COUNT - 1;
-        StatusBarNotification newSbn = getSbn(pkg, lastIdx,
+        NotificationRecord newRec = getNotificationRecord(getSbn(pkg, lastIdx,
                 String.valueOf(lastIdx), UserHandle.SYSTEM, null, mock(Icon.class),
-                Color.YELLOW);
-        notifications.add(newSbn);
-        for (StatusBarNotification sbn: notifications) {
-            mGroupHelper.onNotificationPosted(sbn, false);
+                Color.YELLOW));
+        notifications.add(newRec);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
         }
 
         // Remove last notification (the only one with different icon and color)
         mGroupHelper.onNotificationRemoved(notifications.get(lastIdx));
 
         // Summary should be updated to the common icon and color
-        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), eq(initialAttr));
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                eq(initialAttr));
+    }
+
+    @Test
+    @EnableFlags({Flags.FLAG_AUTOGROUP_SUMMARY_ICON_UPDATE,
+            FLAG_NOTIFICATION_FORCE_GROUPING})
+    public void testAutoGrouped_diffIcon_diffColor_removeChild_updateTo_sameIcon_sameColor_forceGrouping() {
+        final String pkg = "package";
+        final Icon initialIcon = mock(Icon.class);
+        when(initialIcon.sameAs(initialIcon)).thenReturn(true);
+        final int initialIconColor = Color.BLUE;
+        final NotificationAttributes initialAttr = new NotificationAttributes(
+            BASE_FLAGS, initialIcon, initialIconColor, DEFAULT_VISIBILITY,
+            DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID);
+
+        // Add AUTOGROUP_AT_COUNT-1 notifications with same icon and color
+        ArrayList<NotificationRecord> notifications = new ArrayList<>();
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+            NotificationRecord r = getNotificationRecord(
+                getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, null,
+                    initialIcon, initialIconColor));
+            notifications.add(r);
+        }
+        // And an additional notification with different icon and color
+        final int lastIdx = AUTOGROUP_AT_COUNT - 1;
+        NotificationRecord newRec = getNotificationRecord(getSbn(pkg, lastIdx,
+            String.valueOf(lastIdx), UserHandle.SYSTEM, null, mock(Icon.class),
+            Color.YELLOW));
+        notifications.add(newRec);
+        for (NotificationRecord r: notifications) {
+            mGroupHelper.onNotificationPosted(r, false);
+        }
+
+        // Remove last notification (the only one with different icon and color)
+        mGroupHelper.onNotificationRemoved(notifications.get(lastIdx));
+
+        // Summary should be updated to the common icon and color
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+            eq(initialAttr));
     }
 
     @Test
@@ -1202,7 +1492,7 @@
         List<NotificationAttributes> childrenAttr = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
             childrenAttr.add(new NotificationAttributes(0, icon, COLOR_DEFAULT,
-                    DEFAULT_VISIBILITY));
+                    DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
         }
 
         //Check that the generated summary icon is the same as the child notifications'
@@ -1223,7 +1513,7 @@
         List<NotificationAttributes> childrenAttr = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
             childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), COLOR_DEFAULT,
-                    DEFAULT_VISIBILITY));
+                    DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
         }
 
         // Check that the generated summary icon is the monochrome icon
@@ -1240,7 +1530,7 @@
         List<NotificationAttributes> childrenAttr = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
             childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
-                    DEFAULT_VISIBILITY));
+                    DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
         }
 
         // Check that the generated summary icon color is the same as the child notifications'
@@ -1257,7 +1547,7 @@
         List<NotificationAttributes> childrenAttr = new ArrayList<>();
         for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
             childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), i,
-                    DEFAULT_VISIBILITY));
+                    DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
         }
 
         // Check that the generated summary icon color is the default color
@@ -1274,10 +1564,10 @@
         // Create notifications with private and public visibility
         List<NotificationAttributes> childrenAttr = new ArrayList<>();
         childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
-                VISIBILITY_PUBLIC));
+                VISIBILITY_PUBLIC, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
         for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
             childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
-                    VISIBILITY_PRIVATE));
+                    VISIBILITY_PRIVATE, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
         }
 
         // Check that the generated summary visibility is public
@@ -1301,7 +1591,7 @@
                 visibility = VISIBILITY_SECRET;
             }
             childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
-                    visibility));
+                    visibility, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID));
         }
 
         // Check that the generated summary visibility is private
@@ -1311,6 +1601,90 @@
     }
 
     @Test
+    public void testAutobundledSummaryAlertBehavior_oneChildAlertChildren() {
+        final String pkg = "package";
+        final int iconColor = Color.BLUE;
+        // Create notifications with GROUP_ALERT_SUMMARY + one with GROUP_ALERT_CHILDREN
+        List<NotificationAttributes> childrenAttr = new ArrayList<>();
+        childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
+                VISIBILITY_PUBLIC, GROUP_ALERT_CHILDREN, TEST_CHANNEL_ID));
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+            childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
+                VISIBILITY_PRIVATE, GROUP_ALERT_SUMMARY, TEST_CHANNEL_ID));
+        }
+        // Check that the generated summary alert behavior is GROUP_ALERT_CHILDREN
+        int groupAlertBehavior = mGroupHelper.getAutobundledSummaryAttributes(pkg,
+                childrenAttr).groupAlertBehavior;
+        assertThat(groupAlertBehavior).isEqualTo(GROUP_ALERT_CHILDREN);
+    }
+
+    @Test
+    public void testAutobundledSummaryAlertBehavior_oneChildAlertAll() {
+        final String pkg = "package";
+        final int iconColor = Color.BLUE;
+        // Create notifications with GROUP_ALERT_SUMMARY + one with GROUP_ALERT_ALL
+        List<NotificationAttributes> childrenAttr = new ArrayList<>();
+        childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
+                VISIBILITY_PUBLIC, GROUP_ALERT_ALL, TEST_CHANNEL_ID));
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+            childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
+                VISIBILITY_PRIVATE, GROUP_ALERT_SUMMARY, TEST_CHANNEL_ID));
+        }
+        // Check that the generated summary alert behavior is GROUP_ALERT_CHILDREN
+        int groupAlertBehavior = mGroupHelper.getAutobundledSummaryAttributes(pkg,
+                childrenAttr).groupAlertBehavior;
+        assertThat(groupAlertBehavior).isEqualTo(GROUP_ALERT_CHILDREN);
+    }
+
+    @Test
+    public void testAutobundledSummaryAlertBehavior_allChildAlertSummary() {
+        final String pkg = "package";
+        final int iconColor = Color.BLUE;
+        // Create notifications with GROUP_ALERT_SUMMARY
+        List<NotificationAttributes> childrenAttr = new ArrayList<>();
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
+                VISIBILITY_PRIVATE, GROUP_ALERT_SUMMARY, TEST_CHANNEL_ID));
+        }
+
+        // Check that the generated summary alert behavior is GROUP_ALERT_SUMMARY
+        int groupAlertBehavior = mGroupHelper.getAutobundledSummaryAttributes(pkg,
+                childrenAttr).groupAlertBehavior;
+        assertThat(groupAlertBehavior).isEqualTo(GROUP_ALERT_SUMMARY);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_AUTOGROUP_SUMMARY_ICON_UPDATE)
+    public void testAutobundledSummaryChannelId() {
+        final String pkg = "package";
+        final int iconColor = Color.BLUE;
+        final String expectedChannelId = TEST_CHANNEL_ID + "0";
+        // Create notifications with different channelIds
+        List<NotificationAttributes> childrenAttr = new ArrayList<>();
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            childrenAttr.add(new NotificationAttributes(0, mock(Icon.class), iconColor,
+                    DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT, TEST_CHANNEL_ID+i));
+        }
+
+        // Check that the generated summary channelId is the first child in the list
+        String summaryChannelId = mGroupHelper.getAutobundledSummaryAttributes(pkg,
+                childrenAttr).channelId;
+        assertThat(summaryChannelId).isEqualTo(expectedChannelId);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_AUTOGROUP_SUMMARY_ICON_UPDATE)
+    public void testAutobundledSummaryChannelId_noChildren() {
+        final String pkg = "package";
+        // No child notifications
+        List<NotificationAttributes> childrenAttr = new ArrayList<>();
+        // Check that the generated summary channelId is null
+        String summaryChannelId = mGroupHelper.getAutobundledSummaryAttributes(pkg,
+                childrenAttr).channelId;
+        assertThat(summaryChannelId).isNull();
+    }
+
+    @Test
     @EnableFlags(Flags.FLAG_AUTOGROUP_SUMMARY_ICON_UPDATE)
     public void testMonochromeAppIcon_adaptiveIconExists() throws Exception {
         final String pkg = "testPackage";
@@ -1333,4 +1707,855 @@
         assertThat(mGroupHelper.getMonochromeAppIcon(pkg).getResId())
                 .isEqualTo(fallbackIconResId);
     }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testGetAggregateGroupKey() {
+        final String fullAggregateGroupKey = GroupHelper.getFullAggregateGroupKey("pkg",
+                "groupKey", 1234);
+        assertThat(fullAggregateGroupKey).isEqualTo("1234|pkg|g:groupKey");
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testNoGroup_postingUnderLimit_forcedGrouping() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "testGrp " + i, true);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verifyZeroInteractions(mCallback);
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testNoGroup_AutobundledAlready_forcedGrouping() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, null, true);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verifyZeroInteractions(mCallback);
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testNoGroup_isCanceled_forcedGrouping() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "testGrp" + i, true);
+            r.isCanceled = true;
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verifyZeroInteractions(mCallback);
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testNoGroup_isAggregated_forcedGrouping() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            String aggregateGroupKey = AGGREGATE_GROUP_KEY + "AlertingSection";
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, aggregateGroupKey, true);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verifyZeroInteractions(mCallback);
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testNoGroup_multiPackage_forcedGrouping() {
+        final String pkg = "package";
+        final String pkg2 = "package2";
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "testGrp " + i, true);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        NotificationRecord r = getNotificationRecord(pkg2, AUTOGROUP_AT_COUNT,
+                String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, "testGrp", true);
+        notificationList.add(r);
+        mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        verifyZeroInteractions(mCallback);
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testNoGroup_multiUser_forcedGrouping() {
+        final String pkg = "package";
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "testGrp " + i, true);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        NotificationRecord r = getNotificationRecord(pkg, AUTOGROUP_AT_COUNT,
+                String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.of(7), "testGrp", true);
+        notificationList.add(r);
+        mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        verifyZeroInteractions(mCallback);
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testNoGroup_summaryWithChildren_forcedGrouping() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM, "testGrp " + i, true);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        // Next posted summary has 1 child => no forced grouping
+        NotificationRecord summary = getNotificationRecord(pkg, AUTOGROUP_AT_COUNT,
+            String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, "testGrp", true);
+        notificationList.add(summary);
+        NotificationRecord child = getNotificationRecord(pkg, AUTOGROUP_AT_COUNT + 1,
+            String.valueOf(AUTOGROUP_AT_COUNT + 1), UserHandle.SYSTEM, "testGrp", false);
+        notificationList.add(child);
+        mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+        verifyZeroInteractions(mCallback);
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testNoGroup_groupWithSummary_forcedGrouping() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM, "testGrp " + i, true);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        // Next posted notification has summary => no forced grouping
+        NotificationRecord summary = getNotificationRecord(pkg, AUTOGROUP_AT_COUNT,
+            String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, "testGrp", true);
+        notificationList.add(summary);
+        NotificationRecord child = getNotificationRecord(pkg, AUTOGROUP_AT_COUNT + 1,
+            String.valueOf(AUTOGROUP_AT_COUNT + 1), UserHandle.SYSTEM, "testGrp", false);
+        notificationList.add(child);
+        summaryByGroup.put(summary.getGroupKey(), summary);
+        mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+        verifyZeroInteractions(mCallback);
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAddAggregateSummary_summaryNoChildren() {
+        final String pkg = "package";
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+                AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        // Post group summaries without children => force autogroup
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM, "testGrp " + i, true);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+            eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+            eq(expectedGroupKey), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+            any());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAddAggregateSummary_childrenNoSummary() {
+        final String pkg = "package";
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+                AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        // Post group notifications without summaries => force autogroup
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM, "testGrp " + i, false);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAddAggregateSummary_multipleSections() {
+        final String pkg = "package";
+        final String expectedGroupKey_alerting = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final String expectedGroupKey_silent = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "SilentSection", UserHandle.SYSTEM.getIdentifier());
+
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        // Post notifications with different importance values => force group into separate sections
+        NotificationRecord r;
+        for (int i = 0; i < 2 * AUTOGROUP_AT_COUNT; i++) {
+            if (i % 2 == 0) {
+                r = getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM,
+                    "testGrp " + i, true, IMPORTANCE_DEFAULT);
+            } else {
+                r = getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM,
+                    "testGrp " + i, false, IMPORTANCE_LOW);
+            }
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+            eq(expectedGroupKey_alerting), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+            eq(expectedGroupKey_silent), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey_alerting), eq(true));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+            eq(expectedGroupKey_silent), eq(true));
+
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+    }
+
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
+    public void testAddAggregateSummary_mixUngroupedAndAbusive_alwaysAutogroup() {
+        final String pkg = "package";
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        // Post ungrouped notifications => create autogroup
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            mGroupHelper.onNotificationPosted(
+                getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
+        }
+        verify(mCallback, times(1)).addAutoGroupSummary(
+                anyInt(), eq(pkg), anyString(), eq(expectedGroupKey),
+                anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(), eq(expectedGroupKey),
+                anyBoolean());
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+
+        reset(mCallback);
+
+        // Post group notifications without summaries => add to autogroup
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final int id = AUTOGROUP_AT_COUNT;
+        NotificationRecord r = getNotificationRecord(pkg, id, String.valueOf(id),
+                UserHandle.SYSTEM, "testGrp " + id, false);
+        notificationList.add(r);
+        mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+
+        // Check that the new notification was added
+        verify(mCallback, times(1)).addAutoGroup(eq(r.getKey()),
+                eq(expectedGroupKey), eq(true));
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), eq(pkg),
+                eq(expectedGroupKey), any());
+        verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+                anyString(), anyInt(), any());
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    @DisableFlags(android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST)
+    public void testUpdateAggregateSummary_postUngroupedAfterForcedGrouping_alwaysAutogroup() {
+        final String pkg = "package";
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        // Post group notifications without summaries => force autogroup
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM, "testGrp " + i, false);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+            eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+            eq(expectedGroupKey), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+            any());
+
+        reset(mCallback);
+
+        // Post ungrouped notification => update autogroup
+        final int id = AUTOGROUP_AT_COUNT;
+        NotificationRecord r = getNotificationRecord(pkg, id, String.valueOf(id),
+                UserHandle.SYSTEM);
+        mGroupHelper.onNotificationPosted(r, true);
+
+        verify(mCallback, times(1)).addAutoGroup(eq(r.getKey()),
+                eq(expectedGroupKey), eq(true));
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), eq(pkg),
+                eq(expectedGroupKey), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+                anyString(), anyInt(), any());
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+    }
+
+    @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+            android.app.Flags.FLAG_CHECK_AUTOGROUP_BEFORE_POST})
+    public void testUpdateAggregateSummary_postUngroupedAfterForcedGrouping() {
+        final String pkg = "package";
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        // Post group notifications without summaries => force autogroup
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM, "testGrp " + i, false);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+            eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+            eq(expectedGroupKey), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+            any());
+
+        reset(mCallback);
+
+        // Post ungrouped notification => update autogroup
+        final int id = AUTOGROUP_AT_COUNT;
+        NotificationRecord r = getNotificationRecord(pkg, id, String.valueOf(id),
+            UserHandle.SYSTEM);
+        mGroupHelper.onNotificationPosted(r, true);
+
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), eq(pkg),
+            eq(expectedGroupKey), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, never()).addAutoGroup(anyString(), anyString(), anyBoolean());
+        verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+            anyString(), anyInt(), any());
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testUpdateAggregateSummary_postAfterForcedGrouping() {
+        final String pkg = "package";
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        // Post group notifications w/o summaries and summaries w/o children => force autogrouping
+        NotificationRecord r;
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            if (i % 2 == 0) {
+                r = getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM,
+                    "testGrp " + i, true);
+            } else {
+                r = getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM,
+                    "testGrp " + i, false);
+            }
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+
+        // Post another notification after forced grouping
+        final Icon icon = mock(Icon.class);
+        when(icon.sameAs(icon)).thenReturn(true);
+        final int iconColor = Color.BLUE;
+        r = getNotificationRecord(
+                getSbn(pkg, AUTOGROUP_AT_COUNT, String.valueOf(AUTOGROUP_AT_COUNT),
+                    UserHandle.SYSTEM, "testGrp " + AUTOGROUP_AT_COUNT, icon, iconColor));
+
+        notificationList.add(r);
+        mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+            eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT + 1)).addAutoGroup(anyString(),
+            eq(expectedGroupKey), eq(true));
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), eq(pkg),
+            eq(expectedGroupKey), any());
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testRemoveAggregateSummary_removeAllNotifications() {
+        final String pkg = "package";
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        // Post group notifications without summaries => force autogroup
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                UserHandle.SYSTEM, "testGrp " + i, false);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+        Mockito.reset(mCallback);
+
+        // Remove all posted notifications
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "testGrp " + i, false);
+            r.setOverrideGroupKey(expectedGroupKey);
+            mGroupHelper.onNotificationRemoved(r, notificationList);
+        }
+        // Check that the autogroup summary is removed
+        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), eq(pkg),
+                eq(expectedGroupKey));
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testMoveAggregateGroups_updateChannel() {
+        final String pkg = "package";
+        final String expectedGroupKey_alerting = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final NotificationChannel channel = new NotificationChannel(TEST_CHANNEL_ID,
+                TEST_CHANNEL_ID, IMPORTANCE_DEFAULT);
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        // Post group notifications without summaries => force autogroup
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "testGrp " + i, false, channel);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey_alerting), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey_alerting), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+            any());
+        Mockito.reset(mCallback);
+
+        // Update the channel importance for all posted notifications
+        final String expectedGroupKey_silent = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "SilentSection", UserHandle.SYSTEM.getIdentifier());
+        channel.setImportance(IMPORTANCE_LOW);
+        for (NotificationRecord r: notificationList) {
+            r.updateNotificationChannel(channel);
+        }
+        mGroupHelper.onChannelUpdated(UserHandle.SYSTEM.getIdentifier(), pkg, channel,
+                notificationList);
+
+        // Check that all notifications are moved to the silent section group
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey_silent), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey_silent), eq(false));
+
+        // Check that the alerting section group is removed
+        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), eq(pkg),
+                eq(expectedGroupKey_alerting));
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testMoveAggregateGroups_updateChannel_multipleChannels() {
+        final String pkg = "package";
+        final String expectedGroupKey_alerting = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final NotificationChannel channel1 = new NotificationChannel("TEST_CHANNEL_ID1",
+            "TEST_CHANNEL_ID1", IMPORTANCE_DEFAULT);
+        final NotificationChannel channel2 = new NotificationChannel("TEST_CHANNEL_ID2",
+            "TEST_CHANNEL_ID2", IMPORTANCE_DEFAULT);
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        // Post notifications with different channels that autogroup within the same section
+        NotificationRecord r;
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            if (i % 2 == 0) {
+                r = getNotificationRecord(pkg, i, String.valueOf(i),
+                        UserHandle.SYSTEM, "testGrp " + i, false, channel1);
+            } else {
+                r = getNotificationRecord(pkg, i, String.valueOf(i),
+                        UserHandle.SYSTEM, "testGrp " + i, false, channel2);
+            }
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        NotificationAttributes expectedSummaryAttr = new NotificationAttributes(BASE_FLAGS,
+                mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+                "TEST_CHANNEL_ID1");
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey_alerting), anyInt(), eq(expectedSummaryAttr));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey_alerting), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+        Mockito.reset(mCallback);
+
+        // Update channel1's importance
+        final String expectedGroupKey_silent = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "SilentSection", UserHandle.SYSTEM.getIdentifier());
+        channel1.setImportance(IMPORTANCE_LOW);
+        for (NotificationRecord record: notificationList) {
+            if (record.getChannel().getId().equals(channel1.getId())) {
+                record.updateNotificationChannel(channel1);
+            }
+        }
+        mGroupHelper.onChannelUpdated(UserHandle.SYSTEM.getIdentifier(), pkg, channel1,
+                notificationList);
+
+        // Check that channel1's notifications are moved to the silent section group
+        expectedSummaryAttr = new NotificationAttributes(BASE_FLAGS,
+                mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+                "TEST_CHANNEL_ID1");
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey_silent), anyInt(), eq(expectedSummaryAttr));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT/2 + 1)).addAutoGroup(anyString(),
+                eq(expectedGroupKey_silent), eq(false));
+
+        // Check that the alerting section group is not removed, only updated
+        expectedSummaryAttr = new NotificationAttributes(BASE_FLAGS,
+            mSmallIcon, COLOR_DEFAULT, DEFAULT_VISIBILITY, DEFAULT_GROUP_ALERT,
+            "TEST_CHANNEL_ID2");
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), eq(pkg),
+                eq(expectedGroupKey_alerting));
+        verify(mCallback, times(1)).updateAutogroupSummary(anyInt(), eq(pkg),
+                eq(expectedGroupKey_alerting), eq(expectedSummaryAttr));
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testMoveAggregateGroups_updateChannel_groupsUngrouped() {
+        final String pkg = "package";
+        final String expectedGroupKey_silent = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "SilentSection", UserHandle.SYSTEM.getIdentifier());
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+
+        // Post too few group notifications without summaries => do not autogroup
+        final NotificationChannel lowPrioChannel = new NotificationChannel("TEST_CHANNEL_LOW_ID",
+                "TEST_CHANNEL_LOW_ID", IMPORTANCE_LOW);
+        final int numUngrouped = AUTOGROUP_AT_COUNT - 1;
+        int startIdx = 42;
+        for (int i = startIdx; i < startIdx + numUngrouped; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "testGrp " + i, false, lowPrioChannel);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verify(mCallback, never()).addAutoGroup(anyString(), anyString(), anyBoolean());
+        verify(mCallback, never()).addAutoGroupSummary(anyInt(), anyString(), anyString(),
+                anyString(), anyInt(), any());
+
+        reset(mCallback);
+
+        final String expectedGroupKey_alerting = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final NotificationChannel channel = new NotificationChannel(TEST_CHANNEL_ID,
+                TEST_CHANNEL_ID, IMPORTANCE_DEFAULT);
+
+        // Post group notifications without summaries => force autogroup
+        for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
+            NotificationRecord r = getNotificationRecord(pkg, i, String.valueOf(i),
+                    UserHandle.SYSTEM, "testGrp " + i, false, channel);
+            notificationList.add(r);
+            mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
+        }
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey_alerting), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey_alerting), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+        Mockito.reset(mCallback);
+
+        // Update the channel importance for all posted notifications
+        final int numSilentGroupNotifications = AUTOGROUP_AT_COUNT + numUngrouped;
+        channel.setImportance(IMPORTANCE_LOW);
+        for (NotificationRecord r: notificationList) {
+            r.updateNotificationChannel(channel);
+        }
+        mGroupHelper.onChannelUpdated(UserHandle.SYSTEM.getIdentifier(), pkg, channel,
+                notificationList);
+
+        // Check that all notifications are moved to the silent section group
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey_silent), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(numSilentGroupNotifications)).addAutoGroup(anyString(),
+                eq(expectedGroupKey_silent), eq(false));
+
+        // Check that the alerting section group is removed
+        verify(mCallback, times(1)).removeAutoGroupSummary(anyInt(), eq(pkg),
+                eq(expectedGroupKey_alerting));
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+    }
+
+    @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+            Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+    public void testNoGroup_singletonGroup_underLimit() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        // Post singleton groups, under forced group limit
+        for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT - 1; i++) {
+            NotificationRecord summary = getNotificationRecord(pkg, i,
+                    String.valueOf(i), UserHandle.SYSTEM, "testGrp "+i, true);
+            notificationList.add(summary);
+            NotificationRecord child = getNotificationRecord(pkg, i + 42,
+                    String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp "+i, false);
+            notificationList.add(child);
+            summaryByGroup.put(summary.getGroupKey(), summary);
+            mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+            mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+        }
+        verifyZeroInteractions(mCallback);
+    }
+
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    @DisableFlags(Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS)
+    public void testAddAggregateSummary_singletonGroup_disableFlag() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        // Post singleton groups, above forced group limit
+        for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT; i++) {
+            NotificationRecord summary = getNotificationRecord(pkg, i,
+                    String.valueOf(i), UserHandle.SYSTEM, "testGrp "+i, true);
+            notificationList.add(summary);
+            NotificationRecord child = getNotificationRecord(pkg, i + 42,
+                    String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp "+i, false);
+            notificationList.add(child);
+            summaryByGroup.put(summary.getGroupKey(), summary);
+            mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+            mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+        }
+        // FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS is disabled => don't force group
+        verifyZeroInteractions(mCallback);
+    }
+
+    @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+            Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+    public void testAddAggregateSummary_singletonGroups() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        // Post singleton groups, above forced group limit
+        for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT; i++) {
+            NotificationRecord summary = getNotificationRecord(pkg, i,
+                String.valueOf(i), UserHandle.SYSTEM, "testGrp "+i, true);
+            notificationList.add(summary);
+            NotificationRecord child = getNotificationRecord(pkg, i + 42,
+                String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp "+i, false);
+            notificationList.add(child);
+            summaryByGroup.put(summary.getGroupKey(), summary);
+            mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+            summary.isCanceled = true;  // simulate removing the app summary
+            mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+
+        }
+        // Check that notifications are forced grouped
+        verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString(),
+                eq(expectedGroupKey), anyInt(), eq(getNotificationAttributes(BASE_FLAGS)));
+        verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).addAutoGroup(anyString(),
+                eq(expectedGroupKey), eq(true));
+        verify(mCallback, never()).removeAutoGroup(anyString());
+        verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString(), anyString());
+        verify(mCallback, never()).updateAutogroupSummary(anyInt(), anyString(), anyString(),
+                any());
+
+        // Check that summaries are canceled
+        verify(mCallback, times(AUTOGROUP_SINGLETONS_AT_COUNT)).removeAppProvidedSummary(anyString());
+    }
+
+    @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+            Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+    public void testCancelCachedSummary_singletonGroups() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        final int id = 0;
+        // Post singleton groups, above forced group limit
+        for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT; i++) {
+            NotificationRecord summary = getNotificationRecord(pkg, i,
+                    String.valueOf(i), UserHandle.SYSTEM, "testGrp "+i, true);
+            notificationList.add(summary);
+            NotificationRecord child = getNotificationRecord(pkg, i + 42,
+                    String.valueOf(i + 42), UserHandle.SYSTEM, "testGrp "+i, false);
+            notificationList.add(child);
+            summaryByGroup.put(summary.getGroupKey(), summary);
+            mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+            summary.isCanceled = true;  // simulate removing the app summary
+            mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+        }
+        Mockito.reset(mCallback);
+
+        // App cancels the summary of an aggregated group
+        mGroupHelper.maybeCancelGroupChildrenForCanceledSummary(pkg, String.valueOf(id), id,
+                UserHandle.SYSTEM.getIdentifier(), REASON_APP_CANCEL);
+
+        verify(mCallback, times(1)).removeNotificationFromCanceledGroup(
+                eq(UserHandle.SYSTEM.getIdentifier()), eq(pkg), eq("testGrp " + id),
+                eq(REASON_APP_CANCEL));
+        CachedSummary cachedSummary = mGroupHelper.findCanceledSummary(pkg, String.valueOf(id), id,
+                UserHandle.SYSTEM.getIdentifier());
+        assertThat(cachedSummary).isNull();
+    }
+
+    @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+            Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+    public void testRemoveCachedSummary_singletonGroups_removeChildren() {
+        final List<NotificationRecord> notificationList = new ArrayList<>();
+        final ArrayMap<String, NotificationRecord> summaryByGroup = new ArrayMap<>();
+        final String pkg = "package";
+        final String expectedGroupKey = GroupHelper.getFullAggregateGroupKey(pkg,
+            AGGREGATE_GROUP_KEY + "AlertingSection", UserHandle.SYSTEM.getIdentifier());
+        final int id = 0;
+        NotificationRecord childToRemove = null;
+        // Post singleton groups, above forced group limit
+        for (int i = 0; i < AUTOGROUP_SINGLETONS_AT_COUNT; i++) {
+            NotificationRecord summary = getNotificationRecord(pkg, i,
+                    String.valueOf(i), UserHandle.SYSTEM, "testGrp "+i, true);
+            notificationList.add(summary);
+            NotificationRecord child = getNotificationRecord(pkg, i + 42, String.valueOf(i + 42),
+                    UserHandle.SYSTEM, "testGrp " + i, false);
+            if (i == id) {
+                childToRemove = child;
+            }
+            notificationList.add(child);
+            summaryByGroup.put(summary.getGroupKey(), summary);
+            mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
+            summary.isCanceled = true;  // simulate removing the app summary
+            mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
+        }
+        // override group key for child notifications
+        List<NotificationRecord> notificationListAfterGrouping = new ArrayList<>(
+            notificationList.stream().filter(r -> {
+                if (r.getSbn().getNotification().isGroupChild()) {
+                    r.setOverrideGroupKey(expectedGroupKey);
+                    return true;
+                } else {
+                    return false;
+                }
+            }).toList());
+        summaryByGroup.clear();
+        Mockito.reset(mCallback);
+
+        //Cancel child 0 => remove cached summary
+        childToRemove.isCanceled = true;
+        notificationListAfterGrouping.remove(childToRemove);
+        mGroupHelper.onNotificationRemoved(childToRemove, notificationListAfterGrouping);
+        CachedSummary cachedSummary = mGroupHelper.findCanceledSummary(pkg, String.valueOf(id), id,
+                UserHandle.SYSTEM.getIdentifier());
+        assertThat(cachedSummary).isNull();
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testGroupSectioners() {
+        final NotificationRecord notification_alerting = getNotificationRecord(mPkg, 0, "", mUser,
+            "", false, IMPORTANCE_DEFAULT);
+        assertThat(GroupHelper.getSection(notification_alerting).mName).isEqualTo("AlertingSection");
+
+        final NotificationRecord notification_silent = getNotificationRecord(mPkg, 0, "", mUser,
+            "", false, IMPORTANCE_LOW);
+        assertThat(GroupHelper.getSection(notification_silent).mName).isEqualTo("SilentSection");
+
+        NotificationRecord notification_conversation = mock(NotificationRecord.class);
+        when(notification_conversation.isConversation()).thenReturn(true);
+        assertThat(GroupHelper.getSection(notification_conversation)).isNull();
+
+        NotificationRecord notification_call = spy(getNotificationRecord(mPkg, 0, "", mUser,
+                "", false, IMPORTANCE_LOW));
+        Notification n = mock(Notification.class);
+        StatusBarNotification sbn = spy(getSbn("package", 0, "0", UserHandle.SYSTEM));
+        when(notification_call.isConversation()).thenReturn(false);
+        when(notification_call.getNotification()).thenReturn(n);
+        when(notification_call.getSbn()).thenReturn(sbn);
+        when(sbn.getNotification()).thenReturn(n);
+        when(n.isStyle(Notification.CallStyle.class)).thenReturn(true);
+        assertThat(GroupHelper.getSection(notification_call)).isNull();
+
+        NotificationRecord notification_colorFg = spy(getNotificationRecord(mPkg, 0, "", mUser,
+            "", false, IMPORTANCE_LOW));
+        sbn = spy(getSbn("package", 0, "0", UserHandle.SYSTEM));
+        n = mock(Notification.class);
+        when(notification_colorFg.isConversation()).thenReturn(false);
+        when(notification_colorFg.getNotification()).thenReturn(n);
+        when(notification_colorFg.getSbn()).thenReturn(sbn);
+        when(sbn.getNotification()).thenReturn(n);
+        when(n.isForegroundService()).thenReturn(true);
+        when(n.isColorized()).thenReturn(true);
+        when(n.isStyle(Notification.CallStyle.class)).thenReturn(false);
+        assertThat(GroupHelper.getSection(notification_colorFg)).isNull();
+    }
+
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java
index 3da8031..28a5db9 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAttentionHelperTest.java
@@ -84,6 +84,8 @@
 import android.os.VibrationAttributes;
 import android.os.VibrationEffect;
 import android.os.Vibrator;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
@@ -225,6 +227,8 @@
         when(resources.getBoolean(R.bool.config_useAttentionLight)).thenReturn(true);
         when(resources.getBoolean(
                 com.android.internal.R.bool.config_intrusiveNotificationLed)).thenReturn(true);
+        when(resources.getBoolean(R.bool.config_enableNotificationAccessibilityEvents))
+                .thenReturn(true);
         when(getContext().getResources()).thenReturn(resources);
 
         // TODO (b/291907312): remove feature flag
@@ -1221,6 +1225,44 @@
     }
 
     @Test
+    @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
+    public void testSilentNotification_flagSilent() throws Exception {
+        final Notification n = new Builder(getContext(), "test")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .setSilent(true)
+                .build();
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
+                mPid, n, mUser, null, System.currentTimeMillis());
+        NotificationRecord r = new NotificationRecord(getContext(), sbn,
+                new NotificationChannel("test", "test", IMPORTANCE_HIGH));
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyNeverBeep();
+        assertFalse(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+        assertTrue(mAttentionHelper.shouldMuteNotificationLocked(r, DEFAULT_SIGNALS));
+    }
+
+    @Test
+    @DisableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
+    public void testSilentNotification_groupKeySilent() throws Exception {
+        final Notification n = new Builder(getContext(), "test")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .setSilent(true)
+                .build();
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 0, mTag, mUid,
+                mPid, n, mUser, null, System.currentTimeMillis());
+        NotificationRecord r = new NotificationRecord(getContext(), sbn,
+                new NotificationChannel("test", "test", IMPORTANCE_HIGH));
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+        verifyNeverBeep();
+        assertFalse(r.isInterruptive());
+        assertEquals(-1, r.getLastAudiblyAlertedMs());
+        assertTrue(mAttentionHelper.shouldMuteNotificationLocked(r, DEFAULT_SIGNALS));
+    }
+
+    @Test
     public void testHonorAlertOnlyOnceForBuzz() throws Exception {
         NotificationRecord r = getBuzzyNotification();
         NotificationRecord s = getBuzzyOnceNotification();
@@ -2790,6 +2832,34 @@
         assertThat(r.getRankingTimeMs()).isEqualTo(r.getSbn().getPostTime());
     }
 
+    @Test
+    public void testAccessibilityEventsEnabledInConfig() throws Exception {
+        Resources resources = spy(getContext().getResources());
+        when(resources.getBoolean(R.bool.config_enableNotificationAccessibilityEvents))
+                .thenReturn(true);
+        when(getContext().getResources()).thenReturn(resources);
+        initAttentionHelper(mTestFlagResolver);
+        NotificationRecord r = getBeepyNotification();
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verify(mAccessibilityService).sendAccessibilityEvent(any(), anyInt());
+    }
+
+    @Test
+    public void testAccessibilityEventsDisabledInConfig() throws Exception {
+        Resources resources = spy(getContext().getResources());
+        when(resources.getBoolean(R.bool.config_enableNotificationAccessibilityEvents))
+                .thenReturn(false);
+        when(getContext().getResources()).thenReturn(resources);
+        initAttentionHelper(mTestFlagResolver);
+        NotificationRecord r = getBeepyNotification();
+
+        mAttentionHelper.buzzBeepBlinkLocked(r, DEFAULT_SIGNALS);
+
+        verify(mAccessibilityService, never()).sendAccessibilityEvent(any(), anyInt());
+    }
+
     static class VibrateRepeatMatcher implements ArgumentMatcher<VibrationEffect> {
         private final int mRepeatIndex;
 
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 398dc281..c1f5a01 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -39,7 +39,10 @@
 import static android.app.Notification.FLAG_ONGOING_EVENT;
 import static android.app.Notification.FLAG_ONLY_ALERT_ONCE;
 import static android.app.Notification.FLAG_USER_INITIATED_JOB;
+import static android.app.Notification.GROUP_ALERT_CHILDREN;
 import static android.app.Notification.VISIBILITY_PRIVATE;
+import static android.app.NotificationChannel.NEWS_ID;
+import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID;
 import static android.app.NotificationChannel.USER_LOCKED_ALLOW_BUBBLE;
 import static android.app.NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED;
 import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
@@ -86,20 +89,23 @@
 import static android.os.UserManager.USER_TYPE_PROFILE_CLONE;
 import static android.os.UserManager.USER_TYPE_PROFILE_MANAGED;
 import static android.os.UserManager.USER_TYPE_PROFILE_PRIVATE;
-import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
 import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
 import static android.service.notification.Adjustment.KEY_CONTEXTUAL_ACTIONS;
 import static android.service.notification.Adjustment.KEY_IMPORTANCE;
 import static android.service.notification.Adjustment.KEY_TEXT_REPLIES;
+import static android.service.notification.Adjustment.KEY_TYPE;
 import static android.service.notification.Adjustment.KEY_USER_SENTIMENT;
+import static android.service.notification.Adjustment.TYPE_NEWS;
 import static android.service.notification.Condition.SOURCE_CONTEXT;
 import static android.service.notification.Condition.SOURCE_USER_ACTION;
 import static android.service.notification.Condition.STATE_TRUE;
+import static android.service.notification.Flags.FLAG_NOTIFICATION_FORCE_GROUPING;
 import static android.service.notification.Flags.FLAG_REDACT_SENSITIVE_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS;
 import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
 import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
 import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
 import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS;
+import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
 import static android.service.notification.NotificationListenerService.REASON_CANCEL;
 import static android.service.notification.NotificationListenerService.REASON_LOCKDOWN;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
@@ -114,6 +120,7 @@
 import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER;
 import static com.android.server.notification.Flags.FLAG_ALL_NOTIFS_NEED_TTL;
 import static com.android.server.notification.Flags.FLAG_REJECT_OLD_NOTIFICATIONS;
+import static com.android.server.notification.GroupHelper.AUTOGROUP_KEY;
 import static com.android.server.notification.NotificationManagerService.BITMAP_DURATION;
 import static com.android.server.notification.NotificationManagerService.DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE;
 import static com.android.server.notification.NotificationManagerService.NOTIFICATION_TTL;
@@ -366,6 +373,7 @@
     private static final int TOAST_DURATION = 2_000;
     private static final int SECONDARY_DISPLAY_ID = 42;
     private static final int TEST_PROFILE_USERHANDLE = 12;
+    private static final long DELAY_FORCE_REGROUP_TIME = 3000;
 
     private static final String ACTION_NOTIFICATION_TIMEOUT =
             NotificationManagerService.class.getSimpleName() + ".TIMEOUT";
@@ -829,13 +837,7 @@
 
         // Pretend the shortcut exists
         List<ShortcutInfo> shortcutInfos = new ArrayList<>();
-        ShortcutInfo info = mock(ShortcutInfo.class);
-        when(info.getPackage()).thenReturn(mPkg);
-        when(info.getId()).thenReturn(VALID_CONVO_SHORTCUT_ID);
-        when(info.getUserId()).thenReturn(USER_SYSTEM);
-        when(info.isLongLived()).thenReturn(true);
-        when(info.isEnabled()).thenReturn(true);
-        shortcutInfos.add(info);
+        shortcutInfos.add(createMockConvoShortcut());
         when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcutInfos);
         when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(),
                 anyString(), anyInt(), any())).thenReturn(true);
@@ -2484,43 +2486,372 @@
     }
 
     @Test
+    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testAutobundledSummary_notificationAdded() {
         NotificationRecord summary =
-                generateNotificationRecord(mTestNotificationChannel, 0, "pkg", true);
+                generateNotificationRecord(mTestNotificationChannel, 0, AUTOGROUP_KEY, true);
         summary.getNotification().flags |= Notification.FLAG_AUTOGROUP_SUMMARY;
         mService.addNotification(summary);
         mService.mSummaryByGroupKey.put("pkg", summary);
         mService.mAutobundledSummaries.put(0, new ArrayMap<>());
         mService.mAutobundledSummaries.get(0).put("pkg", summary.getKey());
 
-        mService.updateAutobundledSummaryLocked(0, "pkg",
+        mService.updateAutobundledSummaryLocked(0, "pkg", AUTOGROUP_KEY,
                 new NotificationAttributes(GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT,
-                    mock(Icon.class), 0, VISIBILITY_PRIVATE), false);
+                    mock(Icon.class), 0,
+                    VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID), false);
         waitForIdle();
 
         assertTrue(summary.getSbn().isOngoing());
     }
 
     @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAutobundledSummary_notificationAdded_forcedGrouping() {
+        NotificationRecord summary =
+                generateNotificationRecord(mTestNotificationChannel, 0, AUTOGROUP_KEY, true);
+        summary.getNotification().flags |= Notification.FLAG_AUTOGROUP_SUMMARY;
+        mService.addNotification(summary);
+        mService.mSummaryByGroupKey.put("pkg", summary);
+        mService.mAutobundledSummaries.put(0, new ArrayMap<>());
+        mService.mAutobundledSummaries.get(0).put(summary.getGroupKey(), summary.getKey());
+
+        mService.updateAutobundledSummaryLocked(0, "pkg", summary.getGroupKey(),
+                new NotificationAttributes(GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT,
+                    mock(Icon.class), 0,
+                    VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID), false);
+        waitForIdle();
+
+        assertTrue(summary.getSbn().isOngoing());
+    }
+
+    @Test
+    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testAutobundledSummary_notificationRemoved() {
         NotificationRecord summary =
-                generateNotificationRecord(mTestNotificationChannel, 0, "pkg", true);
+                generateNotificationRecord(mTestNotificationChannel, 0, AUTOGROUP_KEY, true);
         summary.getNotification().flags |= Notification.FLAG_AUTOGROUP_SUMMARY;
         summary.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
         mService.addNotification(summary);
         mService.mAutobundledSummaries.put(0, new ArrayMap<>());
         mService.mAutobundledSummaries.get(0).put("pkg", summary.getKey());
-        mService.mSummaryByGroupKey.put("pkg", summary);
+        mService.mSummaryByGroupKey.put(summary.getGroupKey(), summary);
 
-        mService.updateAutobundledSummaryLocked(0, "pkg",
+        mService.updateAutobundledSummaryLocked(0, "pkg", AUTOGROUP_KEY,
                 new NotificationAttributes(GroupHelper.BASE_FLAGS,
-                    mock(Icon.class), 0, VISIBILITY_PRIVATE), false);
+                    mock(Icon.class), 0,
+                    VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID), false);
         waitForIdle();
 
         assertFalse(summary.getSbn().isOngoing());
     }
 
     @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAutobundledSummary_notificationRemoved_forceGrouping() {
+        NotificationRecord summary =
+            generateNotificationRecord(mTestNotificationChannel, 0, AUTOGROUP_KEY, true);
+        summary.getNotification().flags |= Notification.FLAG_AUTOGROUP_SUMMARY;
+        summary.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
+        mService.addNotification(summary);
+        mService.mAutobundledSummaries.put(0, new ArrayMap<>());
+        mService.mAutobundledSummaries.get(0).put(summary.getGroupKey(), summary.getKey());
+
+        mService.updateAutobundledSummaryLocked(0, "pkg", summary.getGroupKey(),
+                new NotificationAttributes(GroupHelper.BASE_FLAGS,
+                    mock(Icon.class), 0,
+                    VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID), false);
+        waitForIdle();
+
+        assertFalse(summary.getSbn().isOngoing());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAggregatedSummary_updateSummaryAttributes() {
+        final String aggregateGroupName = "Aggregate_Test";
+        final String newChannelId = "newChannelId";
+        final NotificationChannel newChannel = new NotificationChannel(
+                newChannelId, newChannelId, IMPORTANCE_DEFAULT);
+        mService.setPreferencesHelper(mPreferencesHelper);
+        final NotificationRecord summary =
+                generateNotificationRecord(mTestNotificationChannel, 0, aggregateGroupName, true);
+        final String groupKey = summary.getGroupKey();
+        summary.getNotification().flags |= Notification.FLAG_AUTOGROUP_SUMMARY;
+        mService.addNotification(summary);
+        mService.mAutobundledSummaries.put(0, new ArrayMap<>());
+        mService.mAutobundledSummaries.get(0).put(groupKey, summary.getKey());
+        when(mPreferencesHelper.getNotificationChannel(eq("pkg"), anyInt(),
+                eq(newChannelId), anyBoolean())).thenReturn(newChannel);
+
+        mService.updateAutobundledSummaryLocked(0, "pkg", groupKey,
+                new NotificationAttributes(GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT,
+                    mock(Icon.class), 0, VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, newChannelId),
+                    false);
+        waitForIdle();
+
+        assertTrue(summary.getSbn().isOngoing());
+        assertThat(summary.getNotification().getGroupAlertBehavior()).isEqualTo(
+                GROUP_ALERT_CHILDREN);
+
+        assertThat(summary.getChannel().getId()).isEqualTo(newChannelId);
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAddAggregateNotification_notifyPostedLocked() throws Exception {
+        final String originalGroupName = "originalGroup";
+        final NotificationRecord r =
+                generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, false);
+        mService.addNotification(r);
+        mService.addAutogroupKeyLocked(r.getKey(), "grpKey", true);
+
+        assertThat(r.getSbn().getOverrideGroupKey()).isEqualTo("grpKey");
+        verify(mRankingHandler, times(1)).requestSort();
+        verify(mListeners, times(1)).notifyPostedLocked(eq(r), eq(r));
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testAddAggregateSummaryNotification_convertSummary() throws Exception {
+        final String originalGroupName = "originalGroup";
+        final NotificationRecord r =
+                generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, true);
+        final String groupKey = r.getGroupKey();
+        mService.addNotification(r);
+        assertThat(mService.mSummaryByGroupKey.containsKey(groupKey)).isTrue();
+        boolean isConverted = mService.convertSummaryToNotificationLocked(r.getKey());
+
+        assertThat(isConverted).isTrue();
+        assertThat(r.getSbn().isGroup()).isTrue();
+        assertThat(r.getNotification().isGroupSummary()).isFalse();
+        assertThat(mService.mSummaryByGroupKey.containsKey(groupKey)).isFalse();
+    }
+
+    @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+            Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+    public void testAggregateGroups_RemoveAppSummary() throws Exception {
+        final String originalGroupName = "originalGroup";
+        final NotificationRecord r =
+                generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, true);
+        mService.addNotification(r);
+        mService.removeAppSummaryLocked(r.getKey());
+
+        assertThat(r.isCanceled).isTrue();
+        waitForIdle();
+        verify(mWorkerHandler, times(1)).scheduleCancelNotification(any(), eq(0));
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testUngroupingAggregateSummary() throws Exception {
+        final String originalGroupName = "originalGroup";
+        final String aggregateGroupName = "Aggregate_Test";
+        final int summaryId = Integer.MAX_VALUE;
+        // Add 2 group notifications without a summary
+        NotificationRecord nr0 =
+                generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, false);
+        NotificationRecord nr1 =
+                generateNotificationRecord(mTestNotificationChannel, 1, originalGroupName, false);
+        mService.addNotification(nr0);
+        mService.addNotification(nr1);
+        mService.mSummaryByGroupKey.remove(nr0.getGroupKey());
+
+        // GroupHelper is a mock, so make the calls it would make
+        // Add aggregate group summary
+        NotificationAttributes attr = new NotificationAttributes(GroupHelper.BASE_FLAGS,
+                mock(Icon.class), 0, VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN,
+                nr0.getChannel().getId());
+        NotificationRecord aggregateSummary = mService.createAutoGroupSummary(nr0.getUserId(),
+                nr0.getSbn().getPackageName(), nr0.getKey(), aggregateGroupName, summaryId, attr);
+        mService.addNotification(aggregateSummary);
+        nr0.setOverrideGroupKey(aggregateGroupName);
+        nr1.setOverrideGroupKey(aggregateGroupName);
+        final String fullAggregateGroupKey = nr0.getGroupKey();
+
+        // Check that the aggregate group summary was created
+        assertThat(aggregateSummary.getNotification().getGroup()).isEqualTo(aggregateGroupName);
+        assertThat(aggregateSummary.getNotification().getChannelId()).isEqualTo(
+                nr0.getChannel().getId());
+        assertThat(mService.mSummaryByGroupKey.containsKey(fullAggregateGroupKey)).isTrue();
+
+        // Cancel both children
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr0.getSbn().getTag(),
+                nr0.getSbn().getId(), nr0.getSbn().getUserId());
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr1.getSbn().getTag(),
+                nr1.getSbn().getId(), nr1.getSbn().getUserId());
+        waitForIdle();
+
+        verify(mGroupHelper, times(1)).onNotificationRemoved(eq(nr0), any());
+        verify(mGroupHelper, times(1)).onNotificationRemoved(eq(nr1), any());
+
+        // GroupHelper would send 'remove summary' event
+        mService.clearAutogroupSummaryLocked(nr1.getUserId(), nr1.getSbn().getPackageName(),
+                fullAggregateGroupKey);
+        waitForIdle();
+
+        // Make sure the summary was removed and not re-posted
+        assertThat(mService.getNotificationRecordCount()).isEqualTo(0);
+    }
+
+    @Test
+    @EnableFlags({FLAG_NOTIFICATION_FORCE_GROUPING,
+            Flags.FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS})
+    public void testCancelGroupChildrenForCanceledSummary_singletonGroup() throws Exception {
+        final String originalGroupName = "originalGroup";
+        final String aggregateGroupName = "Aggregate_Test";
+        final int summaryId = Integer.MAX_VALUE;
+        // Add a "singleton group"
+        NotificationRecord nr0 =
+                generateNotificationRecord(mTestNotificationChannel, 0, originalGroupName, false);
+        NotificationRecord nr1 =
+                generateNotificationRecord(mTestNotificationChannel, 1, originalGroupName, false);
+        final NotificationRecord summary =
+                generateNotificationRecord(mTestNotificationChannel, 2, originalGroupName, true);
+        final String originalGroupKey = summary.getGroupKey();
+        mService.addNotification(nr0);
+        mService.addNotification(nr1);
+        mService.addNotification(summary);
+
+        // GroupHelper is a mock, so make the calls it would make
+        // Remove the app's summary notification
+        mService.removeAppSummaryLocked(summary.getKey());
+        waitForIdle();
+
+        // Add aggregate group summary
+        NotificationAttributes attr = new NotificationAttributes(GroupHelper.BASE_FLAGS,
+                mock(Icon.class), 0, VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN,
+                nr0.getChannel().getId());
+        NotificationRecord aggregateSummary = mService.createAutoGroupSummary(nr0.getUserId(),
+            nr0.getSbn().getPackageName(), nr0.getKey(), aggregateGroupName, summaryId, attr);
+        mService.addNotification(aggregateSummary);
+
+        nr0.setOverrideGroupKey(aggregateGroupName);
+        nr1.setOverrideGroupKey(aggregateGroupName);
+        final String fullAggregateGroupKey = nr0.getGroupKey();
+
+        assertThat(aggregateSummary.getNotification().getGroup()).isEqualTo(aggregateGroupName);
+        assertThat(aggregateSummary.getNotification().getChannelId()).isEqualTo(
+                nr0.getChannel().getId());
+        assertThat(mService.mSummaryByGroupKey.containsKey(fullAggregateGroupKey)).isTrue();
+        assertThat(mService.mSummaryByGroupKey.containsKey(originalGroupKey)).isFalse();
+
+        // Cancel the original app summary (is already removed)
+        mBinderService.cancelNotificationWithTag(summary.getSbn().getPackageName(),
+                summary.getSbn().getPackageName(), summary.getSbn().getTag(),
+                summary.getSbn().getId(), summary.getSbn().getUserId());
+        waitForIdle();
+
+        // Check if NMS.CancelNotificationRunnable calls maybeCancelGroupChildrenForCanceledSummary
+        verify(mGroupHelper, times(1)).maybeCancelGroupChildrenForCanceledSummary(
+                eq(summary.getSbn().getPackageName()), eq(summary.getSbn().getTag()),
+                eq(summary.getSbn().getId()), eq(summary.getSbn().getUserId()),
+                eq(REASON_APP_CANCEL));
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testUpdateChannel_notifyGroupHelper() throws Exception {
+        mService.setPreferencesHelper(mPreferencesHelper);
+        mTestNotificationChannel.setLightColor(Color.CYAN);
+        when(mPreferencesHelper.getNotificationChannel(eq(mPkg), anyInt(),
+                eq(mTestNotificationChannel.getId()), anyBoolean()))
+                .thenReturn(mTestNotificationChannel);
+
+        mBinderService.updateNotificationChannelForPackage(mPkg, mUid, mTestNotificationChannel);
+        mTestableLooper.moveTimeForward(DELAY_FORCE_REGROUP_TIME);
+        waitForIdle();
+
+        verify(mGroupHelper, times(1)).onChannelUpdated(eq(Process.myUserHandle().getIdentifier()),
+                eq(mPkg), eq(mTestNotificationChannel), any());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testSnoozeRunnable_snoozeAggregateGroupChild_summaryNotSnoozed() throws Exception {
+        final String aggregateGroupName = "Aggregate_Test";
+
+        // build autogroup summary notification
+        Notification.Builder nb = new Notification.Builder(mContext,
+                mTestNotificationChannel.getId())
+                .setContentTitle("foo")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .setGroup(aggregateGroupName)
+                .setGroupSummary(true)
+                .setFlag(Notification.FLAG_AUTOGROUP_SUMMARY, true);
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 1,
+                "tag" + System.currentTimeMillis(), mUid, 0, nb.build(),
+                UserHandle.getUserHandleForUid(mUid), null, 0);
+        final NotificationRecord summary = new NotificationRecord(mContext, sbn,
+                mTestNotificationChannel);
+
+        final NotificationRecord child = generateNotificationRecord(
+                mTestNotificationChannel, 2, aggregateGroupName, false);
+        mService.addNotification(summary);
+        mService.addNotification(child);
+        when(mSnoozeHelper.canSnooze(anyInt())).thenReturn(true);
+
+        // snooze child only
+        NotificationManagerService.SnoozeNotificationRunnable snoozeNotificationRunnable =
+                mService.new SnoozeNotificationRunnable(
+                    child.getKey(), 100, null);
+        snoozeNotificationRunnable.run();
+
+        // only child should be snoozed
+        verify(mSnoozeHelper, times(1)).snooze(any(NotificationRecord.class), anyLong());
+
+        // both group summary and child should be cancelled
+        assertNull(mService.getNotificationRecord(summary.getKey()));
+        assertNull(mService.getNotificationRecord(child.getKey()));
+
+        assertEquals(4, mNotificationRecordLogger.numCalls());
+        assertEquals(NotificationRecordLogger.NotificationEvent.NOTIFICATION_SNOOZED,
+                mNotificationRecordLogger.event(0));
+        assertEquals(
+                NotificationRecordLogger.NotificationCancelledEvent.NOTIFICATION_CANCEL_SNOOZED,
+                mNotificationRecordLogger.event(1));
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testOnlyForceGroupIfNeeded_newNotification_notAutogrouped() {
+        NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
+        when(mGroupHelper.onNotificationPosted(any(), anyBoolean())).thenReturn(false);
+        mService.addEnqueuedNotification(r);
+        NotificationManagerService.PostNotificationRunnable runnable =
+                mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
+                    r.getUid(), mPostNotificationTrackerFactory.newTracker(null));
+        runnable.run();
+        waitForIdle();
+
+        mTestableLooper.moveTimeForward(DELAY_FORCE_REGROUP_TIME);
+        waitForIdle();
+
+        verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
+        verify(mGroupHelper, times(1)).onNotificationPostedWithDelay(eq(r), any(), any());
+    }
+
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testOnlyForceGroupIfNeeded_newNotification_wasAutogrouped() {
+        NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, false);
+        when(mGroupHelper.onNotificationPosted(any(), anyBoolean())).thenReturn(true);
+        mService.addEnqueuedNotification(r);
+        NotificationManagerService.PostNotificationRunnable runnable =
+            mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
+                r.getUid(), mPostNotificationTrackerFactory.newTracker(null));
+        runnable.run();
+        waitForIdle();
+
+        mTestableLooper.moveTimeForward(DELAY_FORCE_REGROUP_TIME);
+        waitForIdle();
+
+        verify(mGroupHelper, times(1)).onNotificationPosted(any(), anyBoolean());
+        verify(mGroupHelper, never()).onNotificationPostedWithDelay(eq(r), any(), any());
+    }
+
+    @Test
     public void testCancelAllNotifications_IgnoreForegroundService() throws Exception {
         when(mAmi.applyForegroundServiceNotification(
                 any(), anyString(), anyInt(), anyString(), anyInt())).thenReturn(SHOW_IMMEDIATELY);
@@ -3650,9 +3981,11 @@
         when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
         when(mPermissionHelper.isPermissionFixed(mPkg, temp.getUserId())).thenReturn(true);
 
+        NotificationAttributes attr = new NotificationAttributes(GroupHelper.BASE_FLAGS,
+            mock(Icon.class), 0, VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID);
+
         NotificationRecord r = mService.createAutoGroupSummary(temp.getUserId(),
-                temp.getSbn().getPackageName(), temp.getKey(), 0, mock(Icon.class), 0,
-                VISIBILITY_PRIVATE);
+            temp.getSbn().getPackageName(), temp.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr);
 
         assertThat(r.isImportanceFixed()).isTrue();
     }
@@ -4793,6 +5126,7 @@
     }
 
     @Test
+    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testSnoozeRunnable_snoozeAutoGroupChild_summaryNotSnoozed() throws Exception {
         final NotificationRecord parent = generateNotificationRecord(
                 mTestNotificationChannel, 1, GroupHelper.AUTOGROUP_KEY, true);
@@ -5656,7 +5990,7 @@
     public void testAddAutogroup_requestsSort() throws Exception {
         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
         mService.addNotification(r);
-        mService.addAutogroupKeyLocked(r.getKey(), true);
+        mService.addAutogroupKeyLocked(r.getKey(), "grpKey", true);
 
         verify(mRankingHandler, times(1)).requestSort();
     }
@@ -5676,7 +6010,7 @@
         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
         r.setOverrideGroupKey("TEST");
         mService.addNotification(r);
-        mService.addAutogroupKeyLocked(r.getKey(), true);
+        mService.addAutogroupKeyLocked(r.getKey(), "grpName", true);
 
         verify(mRankingHandler, never()).requestSort();
     }
@@ -5686,7 +6020,7 @@
     public void testAutogroupSuppressSort_noSort() throws Exception {
         final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
         mService.addNotification(r);
-        mService.addAutogroupKeyLocked(r.getKey(), false);
+        mService.addAutogroupKeyLocked(r.getKey(), "grpName", false);
 
         verify(mRankingHandler, never()).requestSort();
     }
@@ -10768,8 +11102,8 @@
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
 
-        ArgumentCaptor<LauncherApps.Callback> launcherAppsCallback =
-                ArgumentCaptor.forClass(LauncherApps.Callback.class);
+        ArgumentCaptor<LauncherApps.ShortcutChangeCallback> shortcutChangeCallback =
+                ArgumentCaptor.forClass(LauncherApps.ShortcutChangeCallback.class);
 
         // Messaging notification with shortcut info
         Notification.BubbleMetadata metadata =
@@ -10790,7 +11124,8 @@
         // Verify:
 
         // Make sure we register the callback for shortcut changes
-        verify(mLauncherApps, times(1)).registerCallback(launcherAppsCallback.capture(), any());
+        verify(mShortcutServiceInternal, times(1)).addShortcutChangeCallback(
+                shortcutChangeCallback.capture());
 
         // yes allowed, yes messaging w/shortcut, yes bubble
         Notification notif = mService.getNotificationRecord(nr.getSbn().getKey()).getNotification();
@@ -10803,14 +11138,17 @@
 
         // Test: Remove the shortcut
         when(mLauncherApps.getShortcuts(any(), any())).thenReturn(null);
-        launcherAppsCallback.getValue().onShortcutsChanged(mPkg, emptyList(),
+        ArrayList<ShortcutInfo> removedShortcuts = new ArrayList<>();
+        removedShortcuts.add(createMockConvoShortcut());
+        shortcutChangeCallback.getValue().onShortcutsRemoved(mPkg, removedShortcuts,
                 UserHandle.getUserHandleForUid(mUid));
         waitForIdle();
 
         // Verify:
 
         // Make sure callback is unregistered
-        verify(mLauncherApps, times(1)).unregisterCallback(launcherAppsCallback.getValue());
+        verify(mShortcutServiceInternal, times(1)).removeShortcutChangeCallback(
+                shortcutChangeCallback.getValue());
 
         // We're no longer a bubble
         NotificationRecord notif2 = mService.getNotificationRecord(
@@ -10828,8 +11166,8 @@
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
 
-        ArgumentCaptor<LauncherApps.Callback> launcherAppsCallback =
-                ArgumentCaptor.forClass(LauncherApps.Callback.class);
+        ArgumentCaptor<LauncherApps.ShortcutChangeCallback> shortcutChangeCallback =
+                ArgumentCaptor.forClass(LauncherApps.ShortcutChangeCallback.class);
 
         // Messaging notification with shortcut info
         Notification.BubbleMetadata metadata = new Notification.BubbleMetadata.Builder(
@@ -10863,7 +11201,8 @@
         // Verify:
 
         // Make sure we register the callback for shortcut changes
-        verify(mLauncherApps, times(1)).registerCallback(launcherAppsCallback.capture(), any());
+        verify(mShortcutServiceInternal, times(1)).addShortcutChangeCallback(
+                shortcutChangeCallback.capture());
 
         // yes allowed, yes messaging w/shortcut, yes bubble
         Notification notif = mService.getNotificationRecord(nr.getSbn().getKey()).getNotification();
@@ -10882,7 +11221,8 @@
         // Verify:
 
         // Make sure callback is unregistered
-        verify(mLauncherApps, times(1)).unregisterCallback(launcherAppsCallback.getValue());
+        verify(mShortcutServiceInternal, times(1)).removeShortcutChangeCallback(
+                shortcutChangeCallback.getValue());
     }
 
     @Test
@@ -12685,6 +13025,7 @@
     }
 
     @Test
+    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testUngroupingOngoingAutoSummary() throws Exception {
         NotificationRecord nr0 =
                 generateNotificationRecord(mTestNotificationChannel, 0);
@@ -12698,10 +13039,12 @@
         // grouphelper is a mock here, so make the calls it would make
 
         // add summary
+        NotificationAttributes attr = new NotificationAttributes(
+                GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT, mock(Icon.class), 0,
+                VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID);
         mService.addNotification(
                 mService.createAutoGroupSummary(nr1.getUserId(), nr1.getSbn().getPackageName(),
-                    nr1.getKey(), GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT, mock(Icon.class), 0,
-                    VISIBILITY_PRIVATE));
+                    nr1.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr));
 
         // cancel both children
         mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr0.getSbn().getTag(),
@@ -12711,7 +13054,8 @@
         waitForIdle();
 
         // group helper would send 'remove summary' event
-        mService.clearAutogroupSummaryLocked(nr1.getUserId(), nr1.getSbn().getPackageName());
+        mService.clearAutogroupSummaryLocked(nr1.getUserId(), nr1.getSbn().getPackageName(),
+                AUTOGROUP_KEY);
         waitForIdle();
 
         // make sure the summary was removed and not re-posted
@@ -12719,6 +13063,45 @@
     }
 
     @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testUngroupingOngoingAutoSummary_forceGrouping() throws Exception {
+        NotificationRecord nr0 =
+            generateNotificationRecord(mTestNotificationChannel, 0);
+        NotificationRecord nr1 =
+            generateNotificationRecord(mTestNotificationChannel, 0);
+        nr1.getSbn().getNotification().flags |= FLAG_ONGOING_EVENT;
+
+        mService.addNotification(nr0);
+        mService.addNotification(nr1);
+
+        // grouphelper is a mock here, so make the calls it would make
+
+        // add summary
+        NotificationAttributes attr = new NotificationAttributes(
+            GroupHelper.BASE_FLAGS | FLAG_ONGOING_EVENT, mock(Icon.class), 0,
+            VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID);
+        mService.addNotification(
+            mService.createAutoGroupSummary(nr1.getUserId(), nr1.getSbn().getPackageName(),
+                nr1.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr));
+
+        // cancel both children
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr0.getSbn().getTag(),
+            nr0.getSbn().getId(), nr0.getSbn().getUserId());
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr1.getSbn().getTag(),
+            nr1.getSbn().getId(), nr1.getSbn().getUserId());
+        waitForIdle();
+
+        // group helper would send 'remove summary' event
+        mService.clearAutogroupSummaryLocked(nr1.getUserId(), nr1.getSbn().getPackageName(),
+            AUTOGROUP_KEY);
+        waitForIdle();
+
+        // make sure the summary was removed and not re-posted
+        assertThat(mService.getNotificationRecordCount()).isEqualTo(0);
+    }
+
+    @Test
+    @DisableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
     public void testUngroupingAutoSummary_differentUsers() throws Exception {
         NotificationRecord nr0 =
                 generateNotificationRecord(mTestNotificationChannel, 0, USER_SYSTEM);
@@ -12726,11 +13109,14 @@
                 generateNotificationRecord(mTestNotificationChannel, 1, USER_SYSTEM);
 
         // add notifications + summary for USER_SYSTEM
+        NotificationAttributes attr = new NotificationAttributes(
+            GroupHelper.BASE_FLAGS, mock(Icon.class), 0,
+            VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID);
         mService.addNotification(nr0);
         mService.addNotification(nr1);
         mService.addNotification(
                 mService.createAutoGroupSummary(nr1.getUserId(), nr1.getSbn().getPackageName(),
-                nr1.getKey(), GroupHelper.BASE_FLAGS, mock(Icon.class), 0, VISIBILITY_PRIVATE));
+                nr1.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr));
 
         // add notifications + summary for USER_ALL
         NotificationRecord nr0_all =
@@ -12743,7 +13129,7 @@
         mService.addNotification(
                 mService.createAutoGroupSummary(nr0_all.getUserId(),
                 nr0_all.getSbn().getPackageName(),
-                nr0_all.getKey(), GroupHelper.BASE_FLAGS, mock(Icon.class), 0, VISIBILITY_PRIVATE));
+                nr0_all.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr));
 
         // cancel both children for USER_ALL
         mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr0_all.getSbn().getTag(),
@@ -12754,7 +13140,7 @@
 
         // group helper would send 'remove summary' event
         mService.clearAutogroupSummaryLocked(UserHandle.USER_ALL,
-                nr0_all.getSbn().getPackageName());
+                nr0_all.getSbn().getPackageName(), AUTOGROUP_KEY);
         waitForIdle();
 
         // make sure the right summary was removed
@@ -12767,6 +13153,58 @@
     }
 
     @Test
+    @EnableFlags(FLAG_NOTIFICATION_FORCE_GROUPING)
+    public void testUngroupingAutoSummary_differentUsers_forceGrouping() throws Exception {
+        NotificationRecord nr0 =
+            generateNotificationRecord(mTestNotificationChannel, 0, USER_SYSTEM);
+        NotificationRecord nr1 =
+            generateNotificationRecord(mTestNotificationChannel, 1, USER_SYSTEM);
+
+        // add notifications + summary for USER_SYSTEM
+        NotificationAttributes attr = new NotificationAttributes(
+            GroupHelper.BASE_FLAGS, mock(Icon.class), 0,
+            VISIBILITY_PRIVATE, GROUP_ALERT_CHILDREN, DEFAULT_CHANNEL_ID);
+        mService.addNotification(nr0);
+        mService.addNotification(nr1);
+        mService.addNotification(
+            mService.createAutoGroupSummary(nr1.getUserId(), nr1.getSbn().getPackageName(),
+                nr1.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr));
+
+        // add notifications + summary for USER_ALL
+        NotificationRecord nr0_all =
+            generateNotificationRecord(mTestNotificationChannel, 2, UserHandle.USER_ALL);
+        NotificationRecord nr1_all =
+            generateNotificationRecord(mTestNotificationChannel, 3, UserHandle.USER_ALL);
+
+        mService.addNotification(nr0_all);
+        mService.addNotification(nr1_all);
+        mService.addNotification(
+            mService.createAutoGroupSummary(nr0_all.getUserId(),
+                nr0_all.getSbn().getPackageName(),
+                nr0_all.getKey(), AUTOGROUP_KEY, Integer.MAX_VALUE, attr));
+
+        // cancel both children for USER_ALL
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr0_all.getSbn().getTag(),
+            nr0_all.getSbn().getId(), UserHandle.USER_ALL);
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr1_all.getSbn().getTag(),
+            nr1_all.getSbn().getId(), UserHandle.USER_ALL);
+        waitForIdle();
+
+        // group helper would send 'remove summary' event
+        mService.clearAutogroupSummaryLocked(UserHandle.USER_ALL,
+            nr0_all.getSbn().getPackageName(), AUTOGROUP_KEY);
+        waitForIdle();
+
+        // make sure the right summary was removed
+        assertThat(mService.getNotificationCount(nr0_all.getSbn().getPackageName(),
+            UserHandle.USER_ALL, 0, null)).isEqualTo(0);
+
+        // the USER_SYSTEM notifications + summary were not removed
+        assertThat(mService.getNotificationCount(nr0.getSbn().getPackageName(),
+            USER_SYSTEM, 0, null)).isEqualTo(3);
+    }
+
+    @Test
     public void testStrongAuthTracker_isInLockDownMode() {
         mStrongAuthTracker.setGetStrongAuthForUserReturnValue(
                 STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
@@ -14332,6 +14770,29 @@
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_SECURE_ALLOWLIST_TOKEN)
+    public void enqueueNotification_directlyThroughRunnable_populatesAllowlistToken() {
+        Notification receivedWithoutParceling = new Notification.Builder(mContext, TEST_CHANNEL_ID)
+                .setContentIntent(createPendingIntent("content"))
+                .build();
+        NotificationRecord record = new NotificationRecord(
+                mContext,
+                new StatusBarNotification(mPkg, mPkg, 1, "tag", mUid, 44, receivedWithoutParceling,
+                        mUser, "groupKey", 0),
+                mTestNotificationChannel);
+        assertThat(record.getNotification().getAllowlistToken()).isNull();
+
+        mWorkerHandler.post(
+                mService.new EnqueueNotificationRunnable(mUserId, record, false, false,
+                mPostNotificationTrackerFactory.newTracker(null)));
+        waitForIdle();
+
+        assertThat(mService.mNotificationList).hasSize(1);
+        assertThat(mService.mNotificationList.get(0).getNotification().getAllowlistToken())
+                .isEqualTo(NotificationManagerService.ALLOWLIST_TOKEN);
+    }
+
+    @Test
+    @EnableFlags(android.app.Flags.FLAG_SECURE_ALLOWLIST_TOKEN)
     public void enqueueNotification_rejectsOtherToken() throws RemoteException {
         Notification sent = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                 .setContentIntent(createPendingIntent("content"))
@@ -15778,4 +16239,37 @@
         when(mPackageManagerInternal.isSameApp(anyString(), anyInt(), anyInt())).thenReturn(false);
         assertThat(mBinderService.getEffectsSuppressor()).isEqualTo(mListener.component);
     }
+
+    @Test
+    @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION)
+    public void testApplyAdjustment_keyType_validType() throws Exception {
+        final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+        mService.addNotification(r);
+        NotificationManagerService.WorkerHandler handler = mock(
+                NotificationManagerService.WorkerHandler.class);
+        mService.setHandler(handler);
+
+        Bundle signals = new Bundle();
+        signals.putInt(KEY_TYPE, TYPE_NEWS);
+        Adjustment adjustment = new Adjustment(
+                r.getSbn().getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
+        when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
+        mBinderService.applyAdjustmentFromAssistant(null, adjustment);
+
+        waitForIdle();
+
+        r.applyAdjustments();
+
+        assertThat(r.getChannel().getId()).isEqualTo(NEWS_ID);
+    }
+
+    private ShortcutInfo createMockConvoShortcut() {
+        ShortcutInfo info = mock(ShortcutInfo.class);
+        when(info.getPackage()).thenReturn(mPkg);
+        when(info.getId()).thenReturn(VALID_CONVO_SHORTCUT_ID);
+        when(info.getUserId()).thenReturn(USER_SYSTEM);
+        when(info.isLongLived()).thenReturn(true);
+        when(info.isEnabled()).thenReturn(true);
+        return info;
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java
index 594d6f2..6a99731 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationVisitUrisTest.java
@@ -37,6 +37,7 @@
 import android.platform.test.annotations.EnableFlags;
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.util.Log;
+import android.util.proto.ProtoOutputStream;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.RemoteViews;
@@ -105,7 +106,7 @@
     private static final ImmutableSet<Class<?>> UNUSABLE_TYPES =
             ImmutableSet.of(Consumer.class, IBinder.class, MediaSession.Token.class, Parcel.class,
                     PrintWriter.class, Resources.Theme.class, View.class,
-                    LayoutInflater.Factory2.class);
+                    LayoutInflater.Factory2.class, ProtoOutputStream.class);
 
     // Maximum number of times we allow generating the same class recursively.
     // E.g. new RemoteViews.addView(new RemoteViews()) but stop there.
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index d1880d2..559c324 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -23,6 +23,10 @@
 import static android.app.NotificationChannel.ALLOW_BUBBLE_ON;
 import static android.app.NotificationChannel.CONVERSATION_CHANNEL_ID_FORMAT;
 import static android.app.NotificationChannel.DEFAULT_ALLOW_BUBBLE;
+import static android.app.NotificationChannel.NEWS_ID;
+import static android.app.NotificationChannel.PROMOTIONS_ID;
+import static android.app.NotificationChannel.RECS_ID;
+import static android.app.NotificationChannel.SOCIAL_MEDIA_ID;
 import static android.app.NotificationChannel.USER_LOCKED_ALLOW_BUBBLE;
 import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
 import static android.app.NotificationChannel.USER_LOCKED_LIGHTS;
@@ -47,6 +51,9 @@
 import static android.os.UserHandle.USER_SYSTEM;
 
 import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
+import static android.service.notification.Flags.FLAG_NOTIFICATION_CLASSIFICATION;
+import static android.service.notification.Flags.notificationClassification;
+
 import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.PROPAGATE_CHANNEL_UPDATES_TO_CONVERSATIONS;
 import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__DENIED;
 import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_PREFERENCES__FSI_STATE__GRANTED;
@@ -113,6 +120,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.permission.PermissionManager;
+import android.platform.test.annotations.DisableFlags;
 import android.platform.test.annotations.EnableFlags;
 import android.platform.test.flag.junit.FlagsParameterization;
 import android.platform.test.flag.junit.SetFlagsRule;
@@ -180,10 +188,12 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ThreadLocalRandom;
 
 @SmallTest
 @RunWith(ParameterizedAndroidJunit4.class)
+@EnableFlags(FLAG_PERSIST_INCOMPLETE_RESTORE_DATA)
 public class PreferencesHelperTest extends UiServiceTestCase {
     private static final int UID_HEADLESS = 1000000;
     private static final UserHandle USER = UserHandle.of(0);
@@ -233,7 +243,7 @@
     @Parameters(name = "{0}")
     public static List<FlagsParameterization> getParams() {
         return FlagsParameterization.allCombinationsOf(
-                FLAG_PERSIST_INCOMPLETE_RESTORE_DATA);
+                FLAG_NOTIFICATION_CLASSIFICATION);
     }
 
     public PreferencesHelperTest(FlagsParameterization flags) {
@@ -480,6 +490,34 @@
         when(mPm.getPackageUidAsUser(eq(packageName), anyInt())).thenReturn(uid);
     }
 
+    private static void testThreadSafety(Runnable operationToTest, int nThreads,
+            int nRunsPerThread) throws Exception {
+        final CountDownLatch startLatch = new CountDownLatch(1);
+        final CountDownLatch doneLatch = new CountDownLatch(nThreads);
+
+        for (int i = 0; i < nThreads; i++) {
+            Runnable threadRunnable = () -> {
+                try {
+                    startLatch.await();
+                    for (int j = 0; j < nRunsPerThread; j++) {
+                        operationToTest.run();
+                    }
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                } finally {
+                    doneLatch.countDown();
+                }
+            };
+            new Thread(threadRunnable, "Test Thread #" + i).start();
+        }
+
+        // Ready set go
+        startLatch.countDown();
+
+        // Wait for all test threads to be done.
+        doneLatch.await();
+    }
+
     @Test
     public void testWriteXml_onlyBackupsTargetUser() throws Exception {
         // Setup package notifications.
@@ -582,6 +620,16 @@
         assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false,
                 UID_N_MR1, false));
 
+        NotificationChannel updateNews = null;
+        if (notificationClassification()) {
+            // change one of the reserved bundle channels to ensure changes are persisted across
+            // boot
+            updateNews = mHelper.getNotificationChannel(
+                    PKG_N_MR1, UID_N_MR1, NEWS_ID, false).copy();
+            updateNews.setImportance(IMPORTANCE_NONE);
+            mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, updateNews, true, 1000, true);
+        }
+
         mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
 
         ByteArrayOutputStream baos = writeXmlAndPurge(PKG_N_MR1, UID_N_MR1, false,
@@ -597,6 +645,12 @@
                 mXmlHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false));
         compareChannels(channel2,
                 mXmlHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2.getId(), false));
+        if (notificationClassification()) {
+            assertThat(mXmlHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, updateNews.getId(),
+                    false)).isNotNull();
+            assertThat(mXmlHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, updateNews.getId(),
+                            false)).isEqualTo(updateNews);
+        }
 
         List<NotificationChannelGroup> actualGroups = mXmlHelper.getNotificationChannelGroups(
                 PKG_N_MR1, UID_N_MR1, false, true, false, true, null).getList();
@@ -1130,9 +1184,22 @@
                 + "app_user_locked_fields=\"0\" sent_invalid_msg=\"false\" "
                 + "sent_valid_msg=\"false\" user_demote_msg_app=\"false\" sent_valid_bubble"
                 + "=\"false\" uid=\"10002\">\n"
+                + (notificationClassification() ? "<channel id=\"android.app.social\" "
+                + "name=\"Social\" importance=\"2\" "
+                + "sound=\"content://settings/system/notification_sound\" "
+                + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "")
                 + "<channel id=\"id\" name=\"name\" importance=\"2\" "
                 + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
                 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" orig_imp=\"2\" />\n"
+                + (notificationClassification() ? "<channel id=\"android.app.news\" name=\"News\" "
+                + "importance=\"2\" sound=\"content://settings/system/notification_sound\" "
+                + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
+                + "<channel id=\"android.app.recs\" name=\"Recommendations\" importance=\"2\" "
+                + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
+                + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
+                + "<channel id=\"android.app.promotions\" name=\"Promotions\" importance=\"2\" "
+                + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
+                + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "")
                 + "</package>\n"
                 + "<package name=\"com.example.n_mr1\" show_badge=\"true\" "
                 + "app_user_locked_fields=\"0\" sent_invalid_msg=\"false\" "
@@ -1140,6 +1207,10 @@
                 + "=\"false\" uid=\"10001\">\n"
                 + "<channelGroup id=\"1\" name=\"bye\" blocked=\"false\" locked=\"0\" />\n"
                 + "<channelGroup id=\"2\" name=\"hello\" blocked=\"false\" locked=\"0\" />\n"
+                + (notificationClassification() ? "<channel id=\"android.app.social\" "
+                + "name=\"Social\" importance=\"2\" "
+                + "sound=\"content://settings/system/notification_sound\" "
+                + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "")
                 + "<channel id=\"id1\" name=\"name1\" importance=\"4\" show_badge=\"true\" "
                 + "orig_imp=\"4\" />\n"
                 + "<channel id=\"id2\" name=\"name2\" desc=\"descriptions for all\" "
@@ -1149,14 +1220,22 @@
                 + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
                 + "content_type=\"4\" flags=\"0\" vibration_enabled=\"true\" show_badge=\"true\" "
                 + "orig_imp=\"4\" />\n"
+                + (notificationClassification() ? "<channel id=\"android.app.news\" name=\"News\" "
+                + "importance=\"2\" sound=\"content://settings/system/notification_sound\" "
+                + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
+                + "<channel id=\"android.app.recs\" name=\"Recommendations\" importance=\"2\" "
+                + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
+                + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
+                + "<channel id=\"android.app.promotions\" name=\"Promotions\" importance=\"2\" "
+                + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
+                + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "")
                 + "<channel id=\"miscellaneous\" name=\"Uncategorized\" "
                 + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
                 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
                 + "</package>\n"
                 + "<package name=\"com.example.p\" show_badge=\"true\" "
                 + "app_user_locked_fields=\"0\" sent_invalid_msg=\"true\" sent_valid_msg=\"true\""
-                + " user_demote_msg_app=\"true\" sent_valid_bubble=\"false\" uid=\"10003\" />\n"
-                + "</ranking>";
+                + " user_demote_msg_app=\"true\" sent_valid_bubble=\"false\" uid=\"10003\"";
         assertThat(baos.toString()).contains(expected);
     }
 
@@ -1216,9 +1295,22 @@
                 + "app_user_locked_fields=\"0\" sent_invalid_msg=\"false\" "
                 + "sent_valid_msg=\"false\" user_demote_msg_app=\"false\" sent_valid_bubble"
                 + "=\"false\">\n"
+                + (notificationClassification() ? "<channel id=\"android.app.social\" "
+                + "name=\"Social\" importance=\"2\" "
+                + "sound=\"content://settings/system/notification_sound\" "
+                + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "")
                 + "<channel id=\"id\" name=\"name\" importance=\"2\" "
                 + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
                 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" orig_imp=\"2\" />\n"
+                + (notificationClassification() ? "<channel id=\"android.app.news\" name=\"News\" "
+                + "importance=\"2\" sound=\"content://settings/system/notification_sound\" "
+                + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
+                + "<channel id=\"android.app.recs\" name=\"Recommendations\" importance=\"2\" "
+                + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
+                + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
+                + "<channel id=\"android.app.promotions\" name=\"Promotions\" importance=\"2\" "
+                + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
+                + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "")
                 + "</package>\n"
                 // Importance default because on in permission helper
                 + "<package name=\"com.example.n_mr1\" importance=\"3\" show_badge=\"true\" "
@@ -1227,6 +1319,10 @@
                 + "=\"false\">\n"
                 + "<channelGroup id=\"1\" name=\"bye\" blocked=\"false\" locked=\"0\" />\n"
                 + "<channelGroup id=\"2\" name=\"hello\" blocked=\"false\" locked=\"0\" />\n"
+                + (notificationClassification() ? "<channel id=\"android.app.social\" "
+                + "name=\"Social\" importance=\"2\" "
+                + "sound=\"content://settings/system/notification_sound\" "
+                + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "")
                 + "<channel id=\"id1\" name=\"name1\" importance=\"4\" show_badge=\"true\" "
                 + "orig_imp=\"4\" />\n"
                 + "<channel id=\"id2\" name=\"name2\" desc=\"descriptions for all\" "
@@ -1236,6 +1332,15 @@
                 + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
                 + "content_type=\"4\" flags=\"0\" vibration_enabled=\"true\" show_badge=\"true\" "
                 + "orig_imp=\"4\" />\n"
+                + (notificationClassification() ? "<channel id=\"android.app.news\" name=\"News\" "
+                + "importance=\"2\" sound=\"content://settings/system/notification_sound\" "
+                + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
+                + "<channel id=\"android.app.recs\" name=\"Recommendations\" importance=\"2\" "
+                + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
+                + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
+                + "<channel id=\"android.app.promotions\" name=\"Promotions\" importance=\"2\" "
+                + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
+                + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "")
                 + "<channel id=\"miscellaneous\" name=\"Uncategorized\" "
                 + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
                 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
@@ -1243,12 +1348,11 @@
                 // Importance default because on in permission helper
                 + "<package name=\"com.example.p\" importance=\"3\" show_badge=\"true\" "
                 + "app_user_locked_fields=\"0\" sent_invalid_msg=\"true\" sent_valid_msg=\"true\""
-                + " user_demote_msg_app=\"true\" sent_valid_bubble=\"false\" />\n"
-                // Packages that exist solely in permissionhelper
-                + "<package name=\"first\" importance=\"3\" />\n"
-                + "<package name=\"third\" importance=\"0\" />\n"
-                + "</ranking>";
+                + " user_demote_msg_app=\"true\" sent_valid_bubble=\"false\"";
         assertThat(baos.toString()).contains(expected);
+        // Packages that exist solely in permissionhelper
+        assertThat(baos.toString()).contains("<package name=\"first\" importance=\"3\"");
+        assertThat(baos.toString()).contains("<package name=\"third\" importance=\"0\"");
     }
 
     @Test
@@ -1303,9 +1407,22 @@
                 + "app_user_locked_fields=\"0\" sent_invalid_msg=\"false\" "
                 + "sent_valid_msg=\"false\" user_demote_msg_app=\"false\" sent_valid_bubble"
                 + "=\"false\">\n"
+                + (notificationClassification() ? "<channel id=\"android.app.social\" "
+                + "name=\"Social\" importance=\"2\" "
+                + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
+                + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "")
                 + "<channel id=\"id\" name=\"name\" importance=\"2\" "
                 + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
                 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" orig_imp=\"2\" />\n"
+                + (notificationClassification() ? "<channel id=\"android.app.news\" name=\"News\" "
+                + "importance=\"2\" sound=\"content://settings/system/notification_sound\" "
+                + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
+                + "<channel id=\"android.app.recs\" name=\"Recommendations\" importance=\"2\" "
+                + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
+                + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
+                + "<channel id=\"android.app.promotions\" name=\"Promotions\" importance=\"2\" "
+                + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
+                + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "")
                 + "</package>\n"
                 // Importance 0 because missing from permission helper
                 + "<package name=\"com.example.n_mr1\" importance=\"0\" show_badge=\"true\" "
@@ -1314,6 +1431,10 @@
                 + "=\"false\">\n"
                 + "<channelGroup id=\"1\" name=\"bye\" blocked=\"false\" locked=\"0\" />\n"
                 + "<channelGroup id=\"2\" name=\"hello\" blocked=\"false\" locked=\"0\" />\n"
+                + (notificationClassification() ? "<channel id=\"android.app.social\" "
+                + "name=\"Social\" importance=\"2\" "
+                + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
+                + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "")
                 + "<channel id=\"id1\" name=\"name1\" importance=\"4\" show_badge=\"true\" "
                 + "orig_imp=\"4\" />\n"
                 + "<channel id=\"id2\" name=\"name2\" desc=\"descriptions for all\" "
@@ -1323,6 +1444,15 @@
                 + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
                 + "content_type=\"4\" flags=\"0\" vibration_enabled=\"true\" show_badge=\"true\" "
                 + "orig_imp=\"4\" />\n"
+                + (notificationClassification() ? "<channel id=\"android.app.news\" name=\"News\" "
+                + "importance=\"2\" sound=\"content://settings/system/notification_sound\" "
+                + "usage=\"5\" content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
+                + "<channel id=\"android.app.recs\" name=\"Recommendations\" importance=\"2\" "
+                + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
+                + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
+                + "<channel id=\"android.app.promotions\" name=\"Promotions\" importance=\"2\" "
+                + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
+                + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n" : "")
                 + "<channel id=\"miscellaneous\" name=\"Uncategorized\" "
                 + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
                 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
@@ -1330,8 +1460,7 @@
                 // Importance default because on in permission helper
                 + "<package name=\"com.example.p\" importance=\"3\" show_badge=\"true\" "
                 + "app_user_locked_fields=\"0\" sent_invalid_msg=\"true\" sent_valid_msg=\"true\""
-                + " user_demote_msg_app=\"true\" sent_valid_bubble=\"false\" />\n"
-                + "</ranking>";
+                + " user_demote_msg_app=\"true\" sent_valid_bubble=\"false\"";
         assertThat(baos.toString()).contains(expected);
     }
 
@@ -1851,8 +1980,8 @@
         parser.nextTag();
         mHelper.readXml(parser, false, UserHandle.USER_ALL);
 
-        final NotificationChannel updated1 =
-            mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
+        final NotificationChannel updated1 = mHelper.getNotificationChannel(
+                PKG_N_MR1, UID_N_MR1, NotificationChannel.DEFAULT_CHANNEL_ID, false);
         assertEquals(NotificationManager.IMPORTANCE_HIGH, updated1.getImportance());
         assertTrue(updated1.canBypassDnd());
         assertEquals(VISIBILITY_SECRET, updated1.getLockscreenVisibility());
@@ -2028,6 +2157,7 @@
     }
 
     @Test
+    @DisableFlags(FLAG_NOTIFICATION_CLASSIFICATION)
     public void testUpdate_preUpgrade_updatesAppFields() throws Exception {
         assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
         assertEquals(Notification.PRIORITY_DEFAULT, mHelper.getPackagePriority(PKG_N_MR1, UID_N_MR1));
@@ -2392,18 +2522,20 @@
         // Returns only non-deleted channels
         List<NotificationChannel> channels =
                 mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList();
-        assertEquals(2, channels.size());   // Default channel + non-deleted channel
+        // Default channel + non-deleted channel + system defaults
+        assertEquals(notificationClassification() ? 6 : 2, channels.size());
         for (NotificationChannel nc : channels) {
-            if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
+            if (channel2.getId().equals(nc.getId())) {
                 compareChannels(channel2, nc);
             }
         }
 
         // Returns deleted channels too
         channels = mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, true).getList();
-        assertEquals(3, channels.size());               // Includes default channel
+        // Includes system channel(s)
+        assertEquals(notificationClassification() ? 7 : 3, channels.size());
         for (NotificationChannel nc : channels) {
-            if (!NotificationChannel.DEFAULT_CHANNEL_ID.equals(nc.getId())) {
+            if (channel2.getId().equals(nc.getId())) {
                 compareChannels(channelMap.get(nc.getId()), nc);
             }
         }
@@ -2806,6 +2938,7 @@
     }
 
     @Test
+    @DisableFlags(FLAG_NOTIFICATION_CLASSIFICATION)
     public void testOnlyHasDefaultChannel() throws Exception {
         assertTrue(mHelper.onlyHasDefaultChannel(PKG_N_MR1, UID_N_MR1));
         assertFalse(mHelper.onlyHasDefaultChannel(PKG_O, UID_O));
@@ -3013,7 +3146,8 @@
 
             final ApplicationInfo legacy = new ApplicationInfo();
             legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
-            when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt())).thenReturn(legacy);
+            when(mPm.getApplicationInfoAsUser(eq(PKG_N_MR1), anyInt(), anyInt()))
+                    .thenReturn(legacy);
 
             // create records with the default channel for all user 0 and user 1 uids
             mHelper.canShowBadge(PKG_N_MR1, user0Uids[i]);
@@ -3024,13 +3158,14 @@
 
         // user 0 records remain
         for (int i = 0; i < user0Uids.length; i++) {
-            assertEquals(1,
-                    mHelper.getNotificationChannels(PKG_N_MR1, user0Uids[i], false).getList().size());
+            assertEquals(notificationClassification() ? 5 : 1,
+                    mHelper.getNotificationChannels(PKG_N_MR1, user0Uids[i], false)
+                            .getList().size());
         }
         // user 1 records are gone
         for (int i = 0; i < user1Uids.length; i++) {
-            assertEquals(0,
-                    mHelper.getNotificationChannels(PKG_N_MR1, user1Uids[i], false).getList().size());
+            assertEquals(0, mHelper.getNotificationChannels(PKG_N_MR1, user1Uids[i], false)
+                    .getList().size());
         }
     }
 
@@ -3054,7 +3189,8 @@
 
         assertFalse(mHelper.onPackagesChanged(false, USER_SYSTEM,
                 new String[]{PKG_N_MR1}, new int[]{UID_N_MR1}));
-        assertEquals(2, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList().size());
+        assertEquals(notificationClassification() ? 6 : 2,
+                mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList().size());
     }
 
     @Test
@@ -3126,7 +3262,8 @@
     @Test
     public void testRecordDefaults() throws Exception {
         assertEquals(true, mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
-        assertEquals(1, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList().size());
+        assertEquals(notificationClassification() ? 5 : 1,
+                mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList().size());
     }
 
     @Test
@@ -3212,7 +3349,7 @@
         assertEquals(3, actual.size());
         for (NotificationChannelGroup group : actual) {
             if (group.getId() == null) {
-                assertEquals(2, group.getChannels().size()); // misc channel too
+                assertEquals(2, group.getChannels().size());
                 assertTrue(channel3.getId().equals(group.getChannels().get(0).getId())
                         || channel3.getId().equals(group.getChannels().get(1).getId()));
             } else if (group.getId().equals(ncg.getId())) {
@@ -3363,6 +3500,9 @@
                         new NotificationChannel("" + j, "a", IMPORTANCE_HIGH), true, false,
                         UID_N_MR1, false);
             }
+            if (notificationClassification()) {
+                numChannels += 4;
+            }
             expectedChannels.put(pkgName, numChannels);
         }
 
@@ -4583,7 +4723,12 @@
 
     @Test
     public void testTooManyChannels() {
-        for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
+        int numToCreate = NOTIFICATION_CHANNEL_COUNT_LIMIT;
+        if (notificationClassification()) {
+            // reserved channels lower limit
+            numToCreate -= 4;
+        }
+        for (int i = 0; i < numToCreate; i++) {
             NotificationChannel channel = new NotificationChannel(String.valueOf(i),
                     String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
             mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true, UID_O, false);
@@ -4602,11 +4747,16 @@
 
     @Test
     public void testTooManyChannels_xml() throws Exception {
+        int numToCreate = NOTIFICATION_CHANNEL_COUNT_LIMIT;
+        if (notificationClassification()) {
+            // reserved channels lower limit
+            numToCreate -= 4;
+        }
         String extraChannel = "EXTRA";
         String extraChannel1 = "EXTRA1";
 
         // create first... many... directly so we don't need a big xml blob in this test
-        for (int i = 0; i < NOTIFICATION_CHANNEL_COUNT_LIMIT; i++) {
+        for (int i = 0; i < numToCreate; i++) {
             NotificationChannel channel = new NotificationChannel(String.valueOf(i),
                     String.valueOf(i), NotificationManager.IMPORTANCE_HIGH);
             mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, true, UID_O, false);
@@ -5619,8 +5769,9 @@
         ArrayList<StatsEvent> events = new ArrayList<>();
         mHelper.pullPackageChannelPreferencesStats(events);
 
-        // number of channels with preferences should be 3 total
-        assertEquals("expected number of events", 3, events.size());
+        assertEquals("expected number of events",
+                notificationClassification() ? 7 : 3,
+                events.size());
         for (StatsEvent ev : events) {
             // all of these events should be of PackageNotificationChannelPreferences type,
             // and therefore we expect the atom to have this field.
@@ -5643,7 +5794,7 @@
             } else if (eventChannelId.equals("a")) {
                 assertEquals("channel name", "a", p.getChannelName());
                 assertEquals("importance", IMPORTANCE_LOW, p.getImportance());
-            } else { // b
+            } else if (eventChannelId.equals("b")){ // b
                 assertEquals("channel name", "b", p.getChannelName());
                 assertEquals("importance", IMPORTANCE_HIGH, p.getImportance());
             }
@@ -5661,11 +5812,17 @@
         mHelper.createNotificationChannel(PKG_O, UID_O, channelC, true, false, UID_O, false);
 
         List<String> channels = new LinkedList<>(Arrays.asList("a", "b", "c"));
+        if (notificationClassification()) {
+            channels.add(NEWS_ID);
+            channels.add(PROMOTIONS_ID);
+            channels.add(SOCIAL_MEDIA_ID);
+            channels.add(RECS_ID);
+        }
 
         ArrayList<StatsEvent> events = new ArrayList<>();
         mHelper.pullPackageChannelPreferencesStats(events);
 
-        assertEquals("total events", 3, events.size());
+        assertEquals("total events", notificationClassification() ? 7 : 3, events.size());
         for (StatsEvent ev : events) {
             AtomsProto.Atom atom = StatsEventTestUtils.convertToAtom(ev);
             assertTrue(atom.hasPackageNotificationChannelPreferences());
@@ -5699,7 +5856,7 @@
         mHelper.pullPackageChannelPreferencesStats(events);
 
         // In this case, we want to check the properties of the conversation channel (not parent)
-        assertEquals("total events", 2, events.size());
+        assertEquals("total events", notificationClassification() ? 6 : 2, events.size());
         for (StatsEvent ev : events) {
             AtomsProto.Atom atom = StatsEventTestUtils.convertToAtom(ev);
             assertTrue(atom.hasPackageNotificationChannelPreferences());
@@ -5731,7 +5888,9 @@
         ArrayList<StatsEvent> events = new ArrayList<>();
         mHelper.pullPackageChannelPreferencesStats(events);
 
-        assertEquals("total events", 2, events.size());
+        assertEquals("total events",
+                notificationClassification() ? 6 : 2,
+                events.size());
         for (StatsEvent ev : events) {
             AtomsProto.Atom atom = StatsEventTestUtils.convertToAtom(ev);
             assertTrue(atom.hasPackageNotificationChannelPreferences());
@@ -5762,7 +5921,9 @@
         ArrayList<StatsEvent> events = new ArrayList<>();
         mHelper.pullPackageChannelPreferencesStats(events);
 
-        assertEquals("total events", 2, events.size());
+        assertEquals("total events",
+                notificationClassification() ? 6 : 2,
+                events.size());
         for (StatsEvent ev : events) {
             AtomsProto.Atom atom = StatsEventTestUtils.convertToAtom(ev);
             assertTrue(atom.hasPackageNotificationChannelPreferences());
@@ -6044,6 +6205,53 @@
         assertEquals(0, actual.getChannels().stream().filter(c -> c.getId().equals("id2")).count());
     }
 
+    @Test
+    @EnableFlags(FLAG_NOTIFICATION_CLASSIFICATION)
+    public void testNotificationBundles() {
+        // do something that triggers settings creation for an app
+        mHelper.setShowBadge(PKG_O, UID_O, true);
+
+        // verify 4 reserved channels are created
+        assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, NEWS_ID, false).getImportance())
+                .isEqualTo(IMPORTANCE_LOW);
+        assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, PROMOTIONS_ID, false)
+                .getImportance()).isEqualTo(IMPORTANCE_LOW);
+        assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, SOCIAL_MEDIA_ID, false)
+                .getImportance()).isEqualTo(IMPORTANCE_LOW);
+        assertThat(mHelper.getNotificationChannel(PKG_O, UID_O, RECS_ID, false).getImportance())
+                .isEqualTo(IMPORTANCE_LOW);
+    }
+
+
+    @Test
+    public void testRestoredWithoutUid_threadSafety() throws Exception {
+        when(mPm.getPackageUidAsUser(anyString(), anyInt())).thenReturn(UNKNOWN_UID);
+        when(mPm.getApplicationInfoAsUser(anyString(), anyInt(), anyInt())).thenThrow(
+                new PackageManager.NameNotFoundException());
+        when(mClock.millis()).thenReturn(System.currentTimeMillis());
+        testThreadSafety(() -> {
+            String id = "id";
+            String xml = "<ranking version=\"1\">\n"
+                    + "<package name=\"" + Thread.currentThread()+ "\" show_badge=\"true\">\n"
+                    + "<channel id=\"" + id + "\" name=\"name\" importance=\"2\" "
+                    + "show_badge=\"true\" />\n"
+                    + "</package>\n"
+                    + "<package name=\"" + PKG_P + "\" show_badge=\"true\">\n"
+                    + "</package>\n"
+                    + "</ranking>\n";
+
+            try {
+                loadByteArrayXml(xml.getBytes(), true, USER_SYSTEM);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+
+            // trigger a removal from the list
+            mXmlHelper.onPackagesChanged(true, USER_SYSTEM, new String[]{PKG_P},
+                    new int[]{UNKNOWN_UID});
+        }, 20, 50);
+    }
+
     private static NotificationChannel cloneChannel(NotificationChannel original) {
         Parcel parcel = Parcel.obtain();
         try {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java
index 7d89d87..fe4ce465e 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ScheduleConditionProviderTest.java
@@ -1,5 +1,7 @@
 package com.android.server.notification;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -8,6 +10,7 @@
 
 import android.app.Application;
 import android.app.PendingIntent;
+import android.content.ComponentName;
 import android.content.Intent;
 import android.net.Uri;
 import android.service.notification.Condition;
@@ -58,6 +61,12 @@
    }
 
     @Test
+    public void getComponent_returnsComponent() {
+        assertThat(mService.getComponent()).isEqualTo(new ComponentName("android",
+                "com.android.server.notification.ScheduleConditionProvider"));
+    }
+
+    @Test
     public void testIsValidConditionId_incomplete() throws Exception {
         Uri badConditionId = Uri.EMPTY;
         assertFalse(mService.isValidConditionId(badConditionId));
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java
index a4fb16d..f008cb6 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java
@@ -22,17 +22,22 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.PendingIntent;
 import android.app.Person;
 import android.content.pm.LauncherApps;
 import android.content.pm.LauncherApps.ShortcutQuery;
 import android.content.pm.ShortcutInfo;
 import android.content.pm.ShortcutQueryWrapper;
 import android.content.pm.ShortcutServiceInternal;
+import android.graphics.drawable.Icon;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.service.notification.StatusBarNotification;
@@ -50,11 +55,9 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 
 @SmallTest
@@ -64,7 +67,6 @@
 
     private static final String SHORTCUT_ID = "shortcut";
     private static final String PKG = "pkg";
-    private static final String KEY = "key";
     private static final Person PERSON = mock(Person.class);
 
     @Mock
@@ -75,19 +77,11 @@
     UserManager mUserManager;
     @Mock
     ShortcutServiceInternal mShortcutServiceInternal;
-    @Mock
-    NotificationRecord mNr;
-    @Mock
-    Notification mNotif;
-    @Mock
-    StatusBarNotification mSbn;
-    @Mock
-    Notification.BubbleMetadata mBubbleMetadata;
-    @Mock
-    ShortcutInfo mShortcutInfo;
 
     @Captor private ArgumentCaptor<ShortcutQuery> mShortcutQueryCaptor;
 
+    NotificationRecord mNr;
+
     ShortcutHelper mShortcutHelper;
 
     @Before
@@ -96,137 +90,186 @@
 
         mShortcutHelper = new ShortcutHelper(
                 mLauncherApps, mShortcutListener, mShortcutServiceInternal, mUserManager);
-        when(mSbn.getPackageName()).thenReturn(PKG);
-        when(mShortcutInfo.getId()).thenReturn(SHORTCUT_ID);
-        when(mNotif.getBubbleMetadata()).thenReturn(mBubbleMetadata);
-        when(mBubbleMetadata.getShortcutId()).thenReturn(SHORTCUT_ID);
         when(mUserManager.isUserUnlocked(any(UserHandle.class))).thenReturn(true);
 
-        setUpMockNotificationRecord(mNr, KEY);
+        mNr = setUpNotificationRecord(SHORTCUT_ID, PKG, UserHandle.of(UserHandle.USER_SYSTEM));
     }
 
-    private void setUpMockNotificationRecord(NotificationRecord mockRecord, String key) {
-        when(mockRecord.getKey()).thenReturn(key);
-        when(mockRecord.getSbn()).thenReturn(mSbn);
-        when(mockRecord.getNotification()).thenReturn(mNotif);
-        when(mockRecord.getShortcutInfo()).thenReturn(mShortcutInfo);
+    private NotificationRecord setUpNotificationRecord(String shortcutId,
+            String pkg,
+            UserHandle user) {
+        ShortcutInfo shortcutInfo = mock(ShortcutInfo.class);
+        when(shortcutInfo.getId()).thenReturn(shortcutId);
+        when(shortcutInfo.getUserHandle()).thenReturn(user);
+        when(shortcutInfo.isLongLived()).thenReturn(true);
+
+        Notification notification = new Notification.Builder(getContext())
+                .setContentTitle("title")
+                .setShortcutId(shortcutId)
+                .setBubbleMetadata(new Notification.BubbleMetadata.Builder(shortcutId).build())
+                .build();
+
+        StatusBarNotification sbn = new StatusBarNotification(pkg, pkg, 0, null,
+                1000, 2000, notification, user, null, System.currentTimeMillis());
+        NotificationRecord record = new NotificationRecord(mContext, sbn,
+                mock(NotificationChannel.class));
+        record.setShortcutInfo(shortcutInfo);
+        return record;
     }
 
-    private LauncherApps.Callback addShortcutBubbleAndVerifyListener() {
-        mShortcutHelper.maybeListenForShortcutChangesForBubbles(mNr,
-                false /* removed */,
-                null /* handler */);
+    private LauncherApps.ShortcutChangeCallback addShortcutBubbleAndVerifyListener(
+            NotificationRecord record) {
+        mShortcutHelper.maybeListenForShortcutChangesForBubbles(record, false /* removed */);
 
-        ArgumentCaptor<LauncherApps.Callback> launcherAppsCallback =
-                ArgumentCaptor.forClass(LauncherApps.Callback.class);
+        ArgumentCaptor<LauncherApps.ShortcutChangeCallback> launcherAppsCallback =
+                ArgumentCaptor.forClass(LauncherApps.ShortcutChangeCallback.class);
 
-        verify(mLauncherApps, times(1)).registerCallback(
-                launcherAppsCallback.capture(), any());
+        verify(mShortcutServiceInternal, times(1)).addShortcutChangeCallback(
+                launcherAppsCallback.capture());
         return launcherAppsCallback.getValue();
     }
 
     @Test
     public void testBubbleAdded_listenedAdded() {
-        addShortcutBubbleAndVerifyListener();
+        addShortcutBubbleAndVerifyListener(mNr);
     }
 
     @Test
+    public void testListenerNotifiedOnShortcutRemoved() {
+        LauncherApps.ShortcutChangeCallback callback = addShortcutBubbleAndVerifyListener(mNr);
+
+        List<ShortcutInfo> removedShortcuts = new ArrayList<>();
+        removedShortcuts.add(mNr.getShortcutInfo());
+
+        callback.onShortcutsRemoved(PKG, removedShortcuts, mNr.getUser());
+        verify(mShortcutListener).onShortcutRemoved(mNr.getKey());
+    }
+
+    @Test
+    public void testListenerNotNotified_notMatchingPackage() {
+        LauncherApps.ShortcutChangeCallback callback = addShortcutBubbleAndVerifyListener(mNr);
+
+        List<ShortcutInfo> removedShortcuts = new ArrayList<>();
+        removedShortcuts.add(mNr.getShortcutInfo());
+
+        callback.onShortcutsRemoved("differentPackage", removedShortcuts, mNr.getUser());
+        verify(mShortcutListener, never()).onShortcutRemoved(anyString());
+    }
+
+    @Test
+    public void testListenerNotNotified_notMatchingUser() {
+        LauncherApps.ShortcutChangeCallback callback = addShortcutBubbleAndVerifyListener(mNr);
+
+        List<ShortcutInfo> removedShortcuts = new ArrayList<>();
+        removedShortcuts.add(mNr.getShortcutInfo());
+
+        callback.onShortcutsRemoved(PKG, removedShortcuts, UserHandle.of(10));
+        verify(mShortcutListener, never()).onShortcutRemoved(anyString());
+    }
+
+    @Test
+    public void testListenerNotifiedDifferentUser() {
+        LauncherApps.ShortcutChangeCallback callback = addShortcutBubbleAndVerifyListener(mNr);
+        NotificationRecord diffUserRecord = setUpNotificationRecord(SHORTCUT_ID, PKG,
+                UserHandle.of(10));
+        mShortcutHelper.maybeListenForShortcutChangesForBubbles(diffUserRecord,
+                false /* removed */);
+
+        List<ShortcutInfo> removedShortcuts = new ArrayList<>();
+        removedShortcuts.add(mNr.getShortcutInfo());
+
+        callback.onShortcutsRemoved(PKG, removedShortcuts, mNr.getUser());
+        verify(mShortcutListener).onShortcutRemoved(mNr.getKey());
+
+        reset(mShortcutListener);
+        removedShortcuts.clear();
+        removedShortcuts.add(diffUserRecord.getShortcutInfo());
+
+        callback.onShortcutsRemoved(PKG, removedShortcuts, diffUserRecord.getUser());
+        verify(mShortcutListener).onShortcutRemoved(diffUserRecord.getKey());
+    }
+
+
+    @Test
     public void testBubbleRemoved_listenerRemoved() {
         // First set it up to listen
-        addShortcutBubbleAndVerifyListener();
+        addShortcutBubbleAndVerifyListener(mNr);
 
         // Then remove the notif
         mShortcutHelper.maybeListenForShortcutChangesForBubbles(mNr,
-                true /* removed */,
-                null /* handler */);
+                true /* removed */);
 
-        verify(mLauncherApps, times(1)).unregisterCallback(any());
+        verify(mShortcutServiceInternal, times(1)).removeShortcutChangeCallback(any());
     }
 
     @Test
     public void testBubbleNoLongerHasBubbleMetadata_listenerRemoved() {
         // First set it up to listen
-        addShortcutBubbleAndVerifyListener();
+        addShortcutBubbleAndVerifyListener(mNr);
 
         // Then make it not a bubble
-        when(mNotif.getBubbleMetadata()).thenReturn(null);
+        mNr.getNotification().setBubbleMetadata(null);
         mShortcutHelper.maybeListenForShortcutChangesForBubbles(mNr,
-                false /* removed */,
-                null /* handler */);
+                false /* removed */);
 
-        verify(mLauncherApps, times(1)).unregisterCallback(any());
+        verify(mShortcutServiceInternal, times(1)).removeShortcutChangeCallback(any());
     }
 
     @Test
     public void testBubbleNoLongerHasShortcutId_listenerRemoved() {
         // First set it up to listen
-        addShortcutBubbleAndVerifyListener();
+        addShortcutBubbleAndVerifyListener(mNr);
 
         // Clear out shortcutId
-        when(mBubbleMetadata.getShortcutId()).thenReturn(null);
+        mNr.getNotification().setBubbleMetadata(new Notification.BubbleMetadata.Builder(
+                mock(PendingIntent.class), mock(Icon.class)).build());
         mShortcutHelper.maybeListenForShortcutChangesForBubbles(mNr,
-                false /* removed */,
-                null /* handler */);
+                false /* removed */);
 
-        verify(mLauncherApps, times(1)).unregisterCallback(any());
+        verify(mShortcutServiceInternal, times(1)).removeShortcutChangeCallback(any());
     }
 
     @Test
     public void testNotifNoLongerHasShortcut_listenerRemoved() {
         // First set it up to listen
-        addShortcutBubbleAndVerifyListener();
+        addShortcutBubbleAndVerifyListener(mNr);
 
-        NotificationRecord validMock1 = Mockito.mock(NotificationRecord.class);
-        setUpMockNotificationRecord(validMock1, "KEY1");
+        NotificationRecord record1 = setUpNotificationRecord(SHORTCUT_ID, PKG,
+                UserHandle.of(UserHandle.USER_SYSTEM));
+        NotificationRecord record2 = setUpNotificationRecord(SHORTCUT_ID, PKG,
+                UserHandle.of(UserHandle.USER_SYSTEM));
+        NotificationRecord record3 = setUpNotificationRecord(SHORTCUT_ID, PKG,
+                UserHandle.of(UserHandle.USER_SYSTEM));
 
-        NotificationRecord validMock2 = Mockito.mock(NotificationRecord.class);
-        setUpMockNotificationRecord(validMock2, "KEY2");
+        mShortcutHelper.maybeListenForShortcutChangesForBubbles(record1,
+                false /* removed */);
 
-        NotificationRecord validMock3 = Mockito.mock(NotificationRecord.class);
-        setUpMockNotificationRecord(validMock3, "KEY3");
+        mShortcutHelper.maybeListenForShortcutChangesForBubbles(record2,
+                false /* removed */);
 
-        mShortcutHelper.maybeListenForShortcutChangesForBubbles(validMock1,
-                false /* removed */,
-                null /* handler */);
+        mShortcutHelper.maybeListenForShortcutChangesForBubbles(record3,
+                false /* removed */);
 
-        mShortcutHelper.maybeListenForShortcutChangesForBubbles(validMock2,
-                false /* removed */,
-                null /* handler */);
-
-        mShortcutHelper.maybeListenForShortcutChangesForBubbles(validMock3,
-                false /* removed */,
-                null /* handler */);
-
-        // Clear out shortcutId of the bubble in the middle, to double check that we don't hit a
+        // Clear out shortcutId of the bubble in the middle, to double-check that we don't hit a
         // concurrent modification exception (removing the last bubble would sidestep that check).
-        when(validMock2.getShortcutInfo()).thenReturn(null);
-        mShortcutHelper.maybeListenForShortcutChangesForBubbles(validMock2,
-                false /* removed */,
-                null /* handler */);
+        record2.setShortcutInfo(null);
+        mShortcutHelper.maybeListenForShortcutChangesForBubbles(record2,
+                false /* removed */);
 
-        verify(mLauncherApps, times(1)).unregisterCallback(any());
+        verify(mShortcutServiceInternal, times(1)).removeShortcutChangeCallback(any());
     }
 
     @Test
     public void testOnShortcutsChanged_listenerRemoved() {
         // First set it up to listen
-        LauncherApps.Callback callback = addShortcutBubbleAndVerifyListener();
+        LauncherApps.ShortcutChangeCallback callback = addShortcutBubbleAndVerifyListener(mNr);
 
         // App shortcuts are removed:
-        callback.onShortcutsChanged(PKG, Collections.emptyList(),  mock(UserHandle.class));
+        List<ShortcutInfo> removedShortcuts = new ArrayList<>();
+        removedShortcuts.add(mNr.getShortcutInfo());
+        callback.onShortcutsRemoved(PKG, removedShortcuts,  mNr.getUser());
 
-        verify(mLauncherApps, times(1)).unregisterCallback(any());
-    }
-
-    @Test
-    public void testListenerNotifiedOnShortcutRemoved() {
-        LauncherApps.Callback callback = addShortcutBubbleAndVerifyListener();
-
-        List<ShortcutInfo> shortcutInfos = new ArrayList<>();
-        when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcutInfos);
-
-        callback.onShortcutsChanged(PKG, shortcutInfos, mock(UserHandle.class));
-        verify(mShortcutListener).onShortcutRemoved(mNr.getKey());
+        verify(mShortcutServiceInternal, times(1)).removeShortcutChangeCallback(any());
     }
 
     @Test
@@ -321,7 +364,6 @@
                 .isSameInstanceAs(si);
     }
 
-
     @Test
     public void testGetValidShortcutInfo_isValidButUserLocked() {
         ShortcutInfo si = mock(ShortcutInfo.class);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
index 9352c12..f7340ab 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
@@ -18,8 +18,10 @@
 
 import static android.app.AutomaticZenRule.TYPE_BEDTIME;
 import static android.app.Flags.FLAG_MODES_UI;
+import static android.app.Flags.modesUi;
 import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
 import static android.provider.Settings.Global.ZEN_MODE_OFF;
+import static android.service.notification.Condition.SOURCE_UNKNOWN;
 import static android.service.notification.Condition.SOURCE_USER_ACTION;
 import static android.service.notification.Condition.STATE_FALSE;
 import static android.service.notification.Condition.STATE_TRUE;
@@ -36,10 +38,18 @@
 import static junit.framework.TestCase.assertNull;
 import static junit.framework.TestCase.assertTrue;
 
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import android.app.AutomaticZenRule;
 import android.app.Flags;
 import android.app.NotificationManager.Policy;
 import android.content.ComponentName;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.Parcel;
 import android.platform.test.annotations.DisableFlags;
@@ -66,6 +76,8 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.BufferedInputStream;
@@ -102,6 +114,9 @@
     private final boolean ENABLED = true;
     private final int CREATION_TIME = 123;
 
+    @Mock
+    PackageManager mPm;
+
     @Rule
     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(
             SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT);
@@ -119,6 +134,8 @@
     @Before
     public final void setUp() {
         mSetFlagsRule.enableFlags(Flags.FLAG_MODES_API);
+        MockitoAnnotations.initMocks(this);
+        mContext.setMockPackageManager(mPm);
     }
 
     @Test
@@ -511,6 +528,9 @@
         rule.iconResName = ICON_RES_NAME;
         rule.triggerDescription = TRIGGER_DESC;
         rule.deletionInstant = Instant.ofEpochMilli(1701790147000L);
+        if (Flags.modesUi()) {
+            rule.disabledOrigin = ZenModeConfig.UPDATE_ORIGIN_USER;
+        }
 
         Parcel parcel = Parcel.obtain();
         rule.writeToParcel(parcel, 0);
@@ -540,6 +560,9 @@
         assertEquals(rule.triggerDescription, parceled.triggerDescription);
         assertEquals(rule.zenPolicy, parceled.zenPolicy);
         assertEquals(rule.deletionInstant, parceled.deletionInstant);
+        if (Flags.modesUi()) {
+            assertEquals(rule.disabledOrigin, parceled.disabledOrigin);
+        }
 
         assertEquals(rule, parceled);
         assertEquals(rule.hashCode(), parceled.hashCode());
@@ -620,6 +643,9 @@
         rule.iconResName = ICON_RES_NAME;
         rule.triggerDescription = TRIGGER_DESC;
         rule.deletionInstant = Instant.ofEpochMilli(1701790147000L);
+        if (Flags.modesUi()) {
+            rule.disabledOrigin = ZenModeConfig.UPDATE_ORIGIN_APP;
+        }
 
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         writeRuleXml(rule, baos);
@@ -653,6 +679,9 @@
         assertEquals(rule.triggerDescription, fromXml.triggerDescription);
         assertEquals(rule.iconResName, fromXml.iconResName);
         assertEquals(rule.deletionInstant, fromXml.deletionInstant);
+        if (Flags.modesUi()) {
+            assertEquals(rule.disabledOrigin, fromXml.disabledOrigin);
+        }
     }
 
     @Test
@@ -955,6 +984,85 @@
         assertThat(fromXml.zenPolicy).isEqualTo(config.getZenPolicy());
     }
 
+    @Test
+    public void testGetDescription_off() {
+        ZenModeConfig config = new ZenModeConfig();
+        if (!modesUi()) {
+            config.manualRule = new ZenModeConfig.ZenRule();
+        }
+        config.manualRule.pkg = "android";
+        assertThat(ZenModeConfig.getDescription(mContext, true, config, false)).isNull();
+    }
+
+    @Test
+    public void testGetDescription_on_manual_endTime() {
+        ZenModeConfig config = new ZenModeConfig();
+        if (!modesUi()) {
+            config.manualRule = new ZenModeConfig.ZenRule();
+        }
+        config.manualRule.conditionId = ZenModeConfig.toCountdownConditionId(
+                System.currentTimeMillis() + 10000, false);
+        config.manualRule.pkg = "android";
+        config.manualRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        config.manualRule.condition = new Condition(Uri.EMPTY, "", STATE_TRUE, SOURCE_UNKNOWN);
+        assertThat(ZenModeConfig.getDescription(mContext, true, config, false))
+                .startsWith("Until");
+    }
+
+    @Test
+    public void getSoundSummary_on_manual_noEnd() {
+        ZenModeConfig config = new ZenModeConfig();
+        if (!modesUi()) {
+            config.manualRule = new ZenModeConfig.ZenRule();
+        }
+        config.manualRule.conditionId = Uri.EMPTY;
+        config.manualRule.pkg = "android";
+        config.manualRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        config.manualRule.condition = new Condition(Uri.EMPTY, "", STATE_TRUE, SOURCE_UNKNOWN);
+        assertThat(ZenModeConfig.getDescription(mContext, true, config, false)).isNull();
+    }
+
+    @Test
+    public void getSoundSummary_on_manual_enabler() throws Exception {
+        ApplicationInfo ai = mock(ApplicationInfo.class);
+        when(ai.loadLabel(any())).thenReturn("app name");
+        when(mPm.getApplicationInfo(anyString(), anyInt())).thenReturn(ai);
+
+        ZenModeConfig config = new ZenModeConfig();
+        if (!modesUi()) {
+            config.manualRule = new ZenModeConfig.ZenRule();
+        }
+        config.manualRule.conditionId = Uri.EMPTY;
+        config.manualRule.pkg = "android";
+        config.manualRule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        config.manualRule.enabler = "app";
+        config.manualRule.condition = new Condition(Uri.EMPTY, "", STATE_TRUE, SOURCE_UNKNOWN);
+        assertThat(ZenModeConfig.getDescription(mContext, true, config, false))
+                .isEqualTo("app name");
+    }
+
+    @Test
+    public void testGetDescription_on_automatic() {
+        ZenModeConfig config = new ZenModeConfig();
+        ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
+        rule.configurationActivity = new ComponentName("a", "a");
+        rule.component = new ComponentName("b", "b");
+        rule.conditionId = new Uri.Builder().scheme("hello").build();
+        rule.condition = new Condition(rule.conditionId, "", Condition.STATE_TRUE);
+        rule.enabled = true;
+        rule.creationTime = 123;
+        rule.id = "id";
+        rule.zenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+        rule.modified = true;
+        rule.name = "name";
+        rule.snoozing = false;
+        rule.pkg = "b";
+        config.automaticRules.put("key", rule);
+
+        assertThat(ZenModeConfig.getDescription(mContext, true, config, false))
+                .isEqualTo("name");
+    }
+
     private ZenModeConfig getMutedRingerConfig() {
         ZenModeConfig config = new ZenModeConfig();
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java
index 26a13cb..57587f7 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeDiffTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.notification;
 
+import static android.app.Flags.FLAG_MODES_API;
 import static android.app.Flags.FLAG_MODES_UI;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -32,6 +33,7 @@
 import android.app.NotificationManager;
 import android.content.ComponentName;
 import android.net.Uri;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.flag.junit.FlagsParameterization;
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.Settings;
@@ -79,16 +81,17 @@
                     : Set.of("version", "manualRule", "automaticRules");
 
     // Differences for flagged fields are only generated if the flag is enabled.
-    // "Metadata" fields (userModifiedFields & co, deletionInstant) are not compared.
+    // "Metadata" fields (userModifiedFields, deletionInstant, disabledOrigin) are not compared.
     private static final Set<String> ZEN_RULE_EXEMPT_FIELDS =
             android.app.Flags.modesApi()
                     ? Set.of("userModifiedFields", "zenPolicyUserModifiedFields",
-                            "zenDeviceEffectsUserModifiedFields", "deletionInstant")
+                            "zenDeviceEffectsUserModifiedFields", "deletionInstant",
+                            "disabledOrigin")
                     : Set.of(RuleDiff.FIELD_TYPE, RuleDiff.FIELD_TRIGGER_DESCRIPTION,
                             RuleDiff.FIELD_ICON_RES, RuleDiff.FIELD_ALLOW_MANUAL,
                             RuleDiff.FIELD_ZEN_DEVICE_EFFECTS, "userModifiedFields",
                             "zenPolicyUserModifiedFields", "zenDeviceEffectsUserModifiedFields",
-                            "deletionInstant");
+                            "deletionInstant", "disabledOrigin");
 
     // allowPriorityChannels is flagged by android.app.modes_api
     public static final Set<String> ZEN_MODE_CONFIG_FLAGGED_FIELDS =
@@ -201,8 +204,8 @@
     }
 
     @Test
+    @EnableFlags(FLAG_MODES_API)
     public void testConfigDiff_fieldDiffs_flagOn() throws Exception {
-        mSetFlagsRule.enableFlags(Flags.FLAG_MODES_API);
         // these two start the same
         ZenModeConfig c1 = new ZenModeConfig();
         ZenModeConfig c2 = new ZenModeConfig();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index 201b286..7bb633e 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -43,7 +43,6 @@
 import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_ANY;
 import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_CONTACTS;
 import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_STARRED;
-import static android.app.NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND;
 import static android.app.NotificationManager.Policy.STATE_PRIORITY_CHANNELS_BLOCKED;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -5013,6 +5012,48 @@
     }
 
     @Test
+    @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
+    public void updateAutomaticZenRule_changeOwnerForSystemRule_allowed() {
+        when(mContext.checkCallingPermission(anyString()))
+                .thenReturn(PackageManager.PERMISSION_GRANTED);
+        AutomaticZenRule original = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
+                .setOwner(new ComponentName("android", "some.old.cps"))
+                .build();
+        String ruleId = mZenModeHelper.addAutomaticZenRule("android", original,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "reason", Process.SYSTEM_UID);
+
+        AutomaticZenRule update = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
+                .setOwner(new ComponentName("android", "brand.new.cps"))
+                .build();
+        mZenModeHelper.updateAutomaticZenRule(ruleId, update, UPDATE_ORIGIN_USER, "reason",
+                Process.SYSTEM_UID);
+
+        AutomaticZenRule result = mZenModeHelper.getAutomaticZenRule(ruleId);
+        assertThat(result).isNotNull();
+        assertThat(result.getOwner().getClassName()).isEqualTo("brand.new.cps");
+    }
+
+    @Test
+    @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
+    public void updateAutomaticZenRule_changeOwnerForAppOwnedRule_ignored() {
+        AutomaticZenRule original = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
+                .setOwner(new ComponentName(mContext.getPackageName(), "old.third.party.cps"))
+                .build();
+        String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), original,
+                UPDATE_ORIGIN_APP, "reason", CUSTOM_PKG_UID);
+
+        AutomaticZenRule update = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
+                .setOwner(new ComponentName(mContext.getPackageName(), "new.third.party.cps"))
+                .build();
+        mZenModeHelper.updateAutomaticZenRule(ruleId, update, UPDATE_ORIGIN_USER, "reason",
+                Process.SYSTEM_UID);
+
+        AutomaticZenRule result = mZenModeHelper.getAutomaticZenRule(ruleId);
+        assertThat(result).isNotNull();
+        assertThat(result.getOwner().getClassName()).isEqualTo("old.third.party.cps");
+    }
+
+    @Test
     @EnableFlags(FLAG_MODES_API)
     public void removeAutomaticZenRule_propagatesOriginToEffectsApplier() {
         mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier);
@@ -6185,6 +6226,101 @@
         assertThat(mZenModeHelper.getConfig().manualRule.zenDeviceEffects).isEqualTo(effects);
     }
 
+    @Test
+    @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
+    public void addAutomaticZenRule_startsDisabled_recordsDisabledOrigin() {
+        AutomaticZenRule startsDisabled = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
+                .setOwner(new ComponentName(mPkg, "SomeProvider"))
+                .setEnabled(false)
+                .build();
+
+        String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, startsDisabled, UPDATE_ORIGIN_APP,
+                "new", CUSTOM_PKG_UID);
+
+        assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo(
+                UPDATE_ORIGIN_APP);
+    }
+
+    @Test
+    @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
+    public void updateAutomaticZenRule_disabling_recordsDisabledOrigin() {
+        AutomaticZenRule startsEnabled = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
+                .setOwner(new ComponentName(mPkg, "SomeProvider"))
+                .setEnabled(true)
+                .build();
+        String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, startsEnabled, UPDATE_ORIGIN_APP,
+                "new", CUSTOM_PKG_UID);
+        assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo(
+                UPDATE_ORIGIN_UNKNOWN);
+
+        AutomaticZenRule nowDisabled = new AutomaticZenRule.Builder(startsEnabled)
+                .setEnabled(false)
+                .build();
+        mZenModeHelper.updateAutomaticZenRule(ruleId, nowDisabled, UPDATE_ORIGIN_USER, "off",
+                Process.SYSTEM_UID);
+
+        assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo(
+                UPDATE_ORIGIN_USER);
+    }
+
+    @Test
+    @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
+    public void updateAutomaticZenRule_keepingDisabled_preservesPreviousDisabledOrigin() {
+        AutomaticZenRule startsEnabled = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
+                .setOwner(new ComponentName(mPkg, "SomeProvider"))
+                .setEnabled(true)
+                .build();
+        String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, startsEnabled, UPDATE_ORIGIN_APP,
+                "new", CUSTOM_PKG_UID);
+        AutomaticZenRule nowDisabled = new AutomaticZenRule.Builder(startsEnabled)
+                .setEnabled(false)
+                .build();
+        mZenModeHelper.updateAutomaticZenRule(ruleId, nowDisabled, UPDATE_ORIGIN_USER, "off",
+                Process.SYSTEM_UID);
+        assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo(
+                UPDATE_ORIGIN_USER);
+
+        // Now update it again, for an unrelated reason with a different origin.
+        AutomaticZenRule nowRenamed = new AutomaticZenRule.Builder(nowDisabled)
+                .setName("Fancy pants rule")
+                .build();
+        mZenModeHelper.updateAutomaticZenRule(ruleId, nowRenamed, UPDATE_ORIGIN_APP, "update",
+                CUSTOM_PKG_UID);
+
+        // Identity of the disabler is preserved.
+        assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo(
+                UPDATE_ORIGIN_USER);
+    }
+
+    @Test
+    @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI})
+    public void updateAutomaticZenRule_enabling_clearsDisabledOrigin() {
+        AutomaticZenRule startsEnabled = new AutomaticZenRule.Builder("Rule", Uri.EMPTY)
+                .setOwner(new ComponentName(mPkg, "SomeProvider"))
+                .setEnabled(true)
+                .build();
+        String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, startsEnabled, UPDATE_ORIGIN_APP,
+                "new", CUSTOM_PKG_UID);
+        AutomaticZenRule nowDisabled = new AutomaticZenRule.Builder(startsEnabled)
+                .setEnabled(false)
+                .build();
+        mZenModeHelper.updateAutomaticZenRule(ruleId, nowDisabled, UPDATE_ORIGIN_USER, "off",
+                Process.SYSTEM_UID);
+        assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo(
+                UPDATE_ORIGIN_USER);
+
+        // Now enable it again
+        AutomaticZenRule nowEnabled = new AutomaticZenRule.Builder(nowDisabled)
+                .setEnabled(true)
+                .build();
+        mZenModeHelper.updateAutomaticZenRule(ruleId, nowEnabled, UPDATE_ORIGIN_APP, "on",
+                CUSTOM_PKG_UID);
+
+        // Identity of the disabler was cleared.
+        assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo(
+                UPDATE_ORIGIN_UNKNOWN);
+    }
+
     private static void addZenRule(ZenModeConfig config, String id, String ownerPkg, int zenMode,
             @Nullable ZenPolicy zenPolicy) {
         ZenRule rule = new ZenRule();
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java
index 88a9483..60d8964 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java
@@ -605,7 +605,7 @@
     public void shouldIgnoreVibration_withKeyboardSettingsOff_shouldIgnoreKeyboardVibration() {
         setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_MEDIUM);
         setUserSetting(Settings.System.KEYBOARD_VIBRATION_ENABLED, 0 /* OFF*/);
-        setHasFixedKeyboardAmplitudeIntensity(true);
+        setKeyboardVibrationSettingsSupported(true);
 
         // Keyboard touch ignored.
         assertVibrationIgnoredForAttributes(
@@ -630,7 +630,7 @@
     public void shouldIgnoreVibration_withKeyboardSettingsOn_shouldNotIgnoreKeyboardVibration() {
         setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_OFF);
         setUserSetting(Settings.System.KEYBOARD_VIBRATION_ENABLED, 1 /* ON */);
-        setHasFixedKeyboardAmplitudeIntensity(true);
+        setKeyboardVibrationSettingsSupported(true);
 
         // General touch ignored.
         assertVibrationIgnoredForUsage(USAGE_TOUCH, Vibration.Status.IGNORED_FOR_SETTINGS);
@@ -645,10 +645,10 @@
 
     @Test
     @RequiresFlagsEnabled(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED)
-    public void shouldIgnoreVibration_noFixedKeyboardAmplitude_ignoresKeyboardTouchVibration() {
+    public void shouldIgnoreVibration_notSupportKeyboardVibration_ignoresKeyboardTouchVibration() {
         setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_OFF);
         setUserSetting(Settings.System.KEYBOARD_VIBRATION_ENABLED, 1 /* ON */);
-        setHasFixedKeyboardAmplitudeIntensity(false);
+        setKeyboardVibrationSettingsSupported(false);
 
         // General touch ignored.
         assertVibrationIgnoredForUsage(USAGE_TOUCH, Vibration.Status.IGNORED_FOR_SETTINGS);
@@ -974,8 +974,8 @@
         when(mVibrationConfigMock.ignoreVibrationsOnWirelessCharger()).thenReturn(ignore);
     }
 
-    private void setHasFixedKeyboardAmplitudeIntensity(boolean hasFixedAmplitude) {
-        when(mVibrationConfigMock.hasFixedKeyboardAmplitude()).thenReturn(hasFixedAmplitude);
+    private void setKeyboardVibrationSettingsSupported(boolean supported) {
+        when(mVibrationConfigMock.isKeyboardVibrationSettingsSupported()).thenReturn(supported);
     }
 
     private void deleteUserSetting(String settingName) {
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
index d6c0fef..1875284 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -781,6 +781,34 @@
     }
 
     @Test
+    @RequiresFlagsEnabled(android.os.vibrator.Flags.FLAG_CANCEL_BY_APPOPS)
+    public void vibrate_thenDeniedAppOps_getsCancelled() throws Throwable {
+        mockVibrators(1);
+        VibratorManagerService service = createSystemReadyService();
+
+        var vib = vibrate(service,
+                VibrationEffect.createWaveform(new long[]{100, 100, 100, 100}, 0), RINGTONE_ATTRS);
+
+        assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
+
+        when(mAppOpsManagerMock.checkAudioOpNoThrow(eq(AppOpsManager.OP_VIBRATE),
+                eq(AudioAttributes.USAGE_NOTIFICATION_RINGTONE), anyInt(), anyString()))
+                .thenReturn(AppOpsManager.MODE_IGNORED);
+
+        service.mAppOpsChangeListener.onOpChanged(AppOpsManager.OP_VIBRATE, null);
+
+        assertTrue(waitUntil(s -> vib.hasEnded(), service, TEST_TIMEOUT_MILLIS));
+
+        var statsInfoCaptor = ArgumentCaptor.forClass(VibrationStats.StatsInfo.class);
+        verify(mVibratorFrameworkStatsLoggerMock, timeout(TEST_TIMEOUT_MILLIS))
+                .writeVibrationReportedAsync(statsInfoCaptor.capture());
+
+        VibrationStats.StatsInfo touchMetrics = statsInfoCaptor.getAllValues().get(0);
+        assertEquals(Vibration.Status.CANCELLED_BY_APP_OPS.getProtoEnumValue(),
+                touchMetrics.status);
+    }
+
+    @Test
     public void vibrate_withVibrationAttributes_usesCorrespondingAudioUsageInAppOpsManager() {
         VibratorManagerService service = createSystemReadyService();
 
diff --git a/services/tests/wmtests/Android.bp b/services/tests/wmtests/Android.bp
index b292294..6ba2c70 100644
--- a/services/tests/wmtests/Android.bp
+++ b/services/tests/wmtests/Android.bp
@@ -28,7 +28,7 @@
     ],
     tools: ["protologtool"],
     cmd: "$(location protologtool) transform-protolog-calls " +
-        "--protolog-class com.android.internal.protolog.common.ProtoLog " +
+        "--protolog-class com.android.internal.protolog.ProtoLog " +
         "--loggroups-class com.android.internal.protolog.ProtoLogGroup " +
         "--loggroups-jar $(location :protolog-groups) " +
         // Used for the ProtoLogIntegrationTest, where don't test decoding or writing to file
diff --git a/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java
index 2480913..07934ea 100644
--- a/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/PhoneWindowManagerTests.java
@@ -131,8 +131,6 @@
 
     @Test
     public void testScreenTurnedOff() {
-        mSetFlagsRule.enableFlags(com.android.window.flags.Flags
-                .FLAG_SKIP_SLEEPING_WHEN_SWITCHING_DISPLAY);
         doNothing().when(mPhoneWindowManager).updateSettings(any());
         doNothing().when(mPhoneWindowManager).initializeHdmiState();
         final boolean[] isScreenTurnedOff = { false };
@@ -159,14 +157,15 @@
         // Skip sleep-token for non-sleep-screen-off.
         clearInvocations(tokenAcquirer);
         mPhoneWindowManager.screenTurnedOff(DEFAULT_DISPLAY, true /* isSwappingDisplay */);
-        verify(tokenAcquirer, never()).acquire(anyInt(), anyBoolean());
+        verify(tokenAcquirer, never()).acquire(anyInt());
         assertThat(isScreenTurnedOff[0]).isTrue();
 
         // Apply sleep-token for sleep-screen-off.
+        isScreenTurnedOff[0] = false;
         mPhoneWindowManager.startedGoingToSleep(DEFAULT_DISPLAY, 0 /* reason */);
         assertThat(mPhoneWindowManager.mIsGoingToSleepDefaultDisplay).isTrue();
         mPhoneWindowManager.screenTurnedOff(DEFAULT_DISPLAY, true /* isSwappingDisplay */);
-        verify(tokenAcquirer).acquire(eq(DEFAULT_DISPLAY), eq(true));
+        verify(tokenAcquirer).acquire(eq(DEFAULT_DISPLAY));
 
         mPhoneWindowManager.finishedGoingToSleep(DEFAULT_DISPLAY, 0 /* reason */);
         assertThat(mPhoneWindowManager.mIsGoingToSleepDefaultDisplay).isFalse();
@@ -176,11 +175,11 @@
         isScreenTurnedOff[0] = false;
         clearInvocations(tokenAcquirer);
         mPhoneWindowManager.screenTurnedOff(DEFAULT_DISPLAY, true /* isSwappingDisplay */);
-        verify(tokenAcquirer, never()).acquire(anyInt(), anyBoolean());
+        verify(tokenAcquirer, never()).acquire(anyInt());
         assertThat(displayPolicy.isScreenOnEarly()).isFalse();
         assertThat(displayPolicy.isScreenOnFully()).isFalse();
         mPhoneWindowManager.startedGoingToSleep(DEFAULT_DISPLAY, 0 /* reason */);
-        verify(tokenAcquirer).acquire(eq(DEFAULT_DISPLAY), eq(false));
+        verify(tokenAcquirer).acquire(eq(DEFAULT_DISPLAY));
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
index 2e571bb..aa28147 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
@@ -132,8 +132,9 @@
                         KeyboardLogEvent.VOLUME_DOWN, KeyEvent.KEYCODE_VOLUME_DOWN, 0},
                 {"VOLUME_MUTE key -> Mute Volume", new int[]{KeyEvent.KEYCODE_VOLUME_MUTE},
                         KeyboardLogEvent.VOLUME_MUTE, KeyEvent.KEYCODE_VOLUME_MUTE, 0},
-                {"ALL_APPS key -> Open App Drawer", new int[]{KeyEvent.KEYCODE_ALL_APPS},
-                        KeyboardLogEvent.ALL_APPS, KeyEvent.KEYCODE_ALL_APPS, 0},
+                {"ALL_APPS key -> Open App Drawer in Accessibility mode",
+                        new int[]{KeyEvent.KEYCODE_ALL_APPS},
+                        KeyboardLogEvent.ACCESSIBILITY_ALL_APPS, KeyEvent.KEYCODE_ALL_APPS, 0},
                 {"SEARCH key -> Launch Search Activity", new int[]{KeyEvent.KEYCODE_SEARCH},
                         KeyboardLogEvent.LAUNCH_SEARCH, KeyEvent.KEYCODE_SEARCH, 0},
                 {"LANGUAGE_SWITCH key -> Switch Keyboard Language",
@@ -259,14 +260,15 @@
                 {"Long press META + H -> Launch assistant",
                         new int[]{META_KEY, KeyEvent.KEYCODE_H}, LONG_PRESS_HOME_ASSIST,
                         KeyboardLogEvent.LAUNCH_ASSISTANT, KeyEvent.KEYCODE_H, META_ON},
-                {"Long press HOME key -> Open App Drawer",
+                {"Long press HOME key -> Open App Drawer in Accessibility mode",
                         new int[]{KeyEvent.KEYCODE_HOME}, LONG_PRESS_HOME_ALL_APPS,
-                        KeyboardLogEvent.ALL_APPS, KeyEvent.KEYCODE_HOME, 0},
-                {"Long press META + ENTER -> Open App Drawer",
+                        KeyboardLogEvent.ACCESSIBILITY_ALL_APPS, KeyEvent.KEYCODE_HOME, 0},
+                {"Long press META + ENTER -> Open App Drawer in Accessibility mode",
                         new int[]{META_KEY, KeyEvent.KEYCODE_ENTER}, LONG_PRESS_HOME_ALL_APPS,
-                        KeyboardLogEvent.ALL_APPS, KeyEvent.KEYCODE_ENTER, META_ON},
-                {"Long press META + H -> Open App Drawer", new int[]{META_KEY, KeyEvent.KEYCODE_H},
-                        LONG_PRESS_HOME_ALL_APPS, KeyboardLogEvent.ALL_APPS,
+                        KeyboardLogEvent.ACCESSIBILITY_ALL_APPS, KeyEvent.KEYCODE_ENTER, META_ON},
+                {"Long press META + H -> Open App Drawer in Accessibility mode",
+                        new int[]{META_KEY, KeyEvent.KEYCODE_H},
+                        LONG_PRESS_HOME_ALL_APPS, KeyboardLogEvent.ACCESSIBILITY_ALL_APPS,
                         KeyEvent.KEYCODE_H, META_ON}};
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index e91fd37..eb8825c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -116,7 +116,6 @@
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.when;
 
 import android.app.ActivityOptions;
 import android.app.AppOpsManager;
@@ -263,16 +262,10 @@
         doAnswer((InvocationOnMock invocationOnMock) -> {
             final ClientTransaction transaction = invocationOnMock.getArgument(0);
             final List<ClientTransactionItem> items = transaction.getTransactionItems();
-            if (items != null) {
-                for (ClientTransactionItem item : items) {
-                    if (item instanceof PauseActivityItem) {
-                        pauseFound.value = true;
-                        break;
-                    }
-                }
-            } else {
-                if (transaction.getLifecycleStateRequest() instanceof PauseActivityItem) {
+            for (ClientTransactionItem item : items) {
+                if (item instanceof PauseActivityItem) {
                     pauseFound.value = true;
+                    break;
                 }
             }
             return null;
@@ -1639,6 +1632,15 @@
         clearInvocations(mDefaultDisplay);
     }
 
+    @Test
+    public void testCompleteResume_updateCompatDisplayInsets() {
+        final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build();
+        doReturn(true).when(activity).shouldCreateCompatDisplayInsets();
+        activity.setState(RESUMED, "test");
+        activity.completeResumeLocked();
+        assertNotNull(activity.getCompatDisplayInsets());
+    }
+
     /**
      * Verify destroy activity request completes successfully.
      */
@@ -2479,10 +2481,10 @@
         assertTrue(activity.mChildren.contains(win4));
 
         // The starting window should be on-top of all other windows.
-        assertEquals(startingWin, activity.mChildren.peekLast());
+        assertEquals(startingWin, activity.getTopChild());
 
         // The base application window should be below all other windows.
-        assertEquals(baseWin, activity.mChildren.peekFirst());
+        assertEquals(baseWin, activity.getBottomChild());
         activity.removeImmediately();
     }
 
@@ -3089,6 +3091,30 @@
     }
 
     @Test
+    public void testOnStartingWindowDrawn() {
+        final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true).build();
+        // The task-has-been-visible should not affect the decision of making transition ready.
+        activity.getTask().setHasBeenVisible(true);
+        activity.detachFromProcess();
+        activity.mStartingData = mock(StartingData.class);
+        registerTestTransitionPlayer();
+        final Transition transition = activity.mTransitionController.requestTransitionIfNeeded(
+                WindowManager.TRANSIT_OPEN, 0 /* flags */, null /* trigger */, mDisplayContent);
+        activity.onStartingWindowDrawn();
+        assertTrue(activity.mStartingData.mIsDisplayed);
+        // The transition can be ready by the starting window of a visible-requested activity
+        // without a running process.
+        assertTrue(transition.allReady());
+
+        // If other event makes the transition unready, the reentrant of onStartingWindowDrawn
+        // should not replace the readiness again.
+        transition.setReady(mDisplayContent, false);
+        activity.onStartingWindowDrawn();
+        assertFalse(transition.allReady());
+    }
+
+
+    @Test
     public void testCloseToSquareFixedOrientation() {
         if (Flags.insetsDecoupledConfiguration()) {
             // No test needed as decor insets no longer affects orientation.
@@ -3324,14 +3350,8 @@
         // to client if the app didn't request IME visible.
         assertFalse(app2.mActivityRecord.mImeInsetsFrozenUntilStartInput);
 
-        if (Flags.bundleClientTransactionFlag()) {
-            verify(app2.getProcess(), atLeastOnce()).scheduleClientTransactionItem(
-                    isA(WindowStateResizeItem.class));
-        } else {
-            verify(app2.mClient, atLeastOnce()).resized(any(), anyBoolean(), any(),
-                    insetsStateCaptor.capture(), anyBoolean(), anyBoolean(), anyInt(), anyInt(),
-                    anyBoolean(), any());
-        }
+        verify(app2.getProcess(), atLeastOnce()).scheduleClientTransactionItem(
+                isA(WindowStateResizeItem.class));
         assertFalse(app2.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
     }
 
@@ -3487,23 +3507,6 @@
     }
 
     @Test
-    public void testIsCameraActive() {
-        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
-        final DisplayRotationCompatPolicy displayRotationCompatPolicy = mock(
-                DisplayRotationCompatPolicy.class);
-        when(mDisplayContent.getDisplayRotationCompatPolicy()).thenReturn(
-                displayRotationCompatPolicy);
-
-        when(displayRotationCompatPolicy.isCameraActive(any(ActivityRecord.class),
-                anyBoolean())).thenReturn(false);
-        assertFalse(app.mActivityRecord.isCameraActive());
-
-        when(displayRotationCompatPolicy.isCameraActive(any(ActivityRecord.class),
-                anyBoolean())).thenReturn(true);
-        assertTrue(app.mActivityRecord.isCameraActive());
-    }
-
-    @Test
     public void testUpdateCameraCompatStateFromUser_clickedOnDismiss() throws RemoteException {
         final ActivityRecord activity = createActivityWithTask();
         // Mock a flag being enabled.
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRefresherTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRefresherTests.java
index 12ab3e1..a3252f8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRefresherTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRefresherTests.java
@@ -103,8 +103,8 @@
     @Test
     public void testShouldRefreshActivity_refreshDisabledForActivity() throws Exception {
         configureActivityAndDisplay();
-        when(mActivity.mLetterboxUiController.shouldRefreshActivityForCameraCompat())
-                .thenReturn(false);
+        when(mActivity.mAppCompatController.getAppCompatCameraOverrides()
+                .shouldRefreshActivityForCameraCompat()).thenReturn(false);
         mActivityRefresher.addEvaluator(mEvaluatorTrue);
 
         mActivityRefresher.onActivityConfigurationChanging(mActivity, mNewConfig, mOldConfig);
@@ -160,8 +160,9 @@
             throws Exception {
         configureActivityAndDisplay();
         mActivityRefresher.addEvaluator(mEvaluatorTrue);
-        doReturn(true).when(mActivity.mLetterboxUiController)
-                .shouldRefreshActivityViaPauseForCameraCompat();
+        doReturn(true)
+                .when(mActivity.mAppCompatController.getAppCompatCameraOverrides())
+                    .shouldRefreshActivityViaPauseForCameraCompat();
 
         mActivityRefresher.onActivityConfigurationChanging(mActivity, mNewConfig, mOldConfig);
 
@@ -172,8 +173,9 @@
     public void testOnActivityRefreshed_setIsRefreshRequestedToFalse() throws Exception {
         configureActivityAndDisplay();
         mActivityRefresher.addEvaluator(mEvaluatorTrue);
-        doReturn(true).when(mActivity.mLetterboxUiController)
-                .shouldRefreshActivityViaPauseForCameraCompat();
+        doReturn(true)
+                .when(mActivity.mAppCompatController.getAppCompatCameraOverrides())
+                    .shouldRefreshActivityViaPauseForCameraCompat();
 
         mActivityRefresher.onActivityRefreshed(mActivity);
 
@@ -186,8 +188,8 @@
 
     private void assertActivityRefreshRequested(boolean refreshRequested,
             boolean cycleThroughStop) throws Exception {
-        verify(mActivity.mLetterboxUiController, times(refreshRequested ? 1 : 0))
-                .setIsRefreshRequested(true);
+        verify(mActivity.mAppCompatController.getAppCompatCameraOverrides(),
+                times(refreshRequested ? 1 : 0)).setIsRefreshRequested(true);
 
         final RefreshCallbackItem refreshCallbackItem = RefreshCallbackItem.obtain(mActivity.token,
                 cycleThroughStop ? ON_STOP : ON_PAUSE);
@@ -211,9 +213,9 @@
                 .getTopMostActivity();
 
         spyOn(mActivity.mLetterboxUiController);
-        doReturn(true).when(
-                mActivity.mLetterboxUiController).shouldRefreshActivityForCameraCompat();
-
+        spyOn(mActivity.mAppCompatController.getAppCompatCameraOverrides());
         doReturn(true).when(mActivity).inFreeformWindowingMode();
+        doReturn(true).when(mActivity.mAppCompatController
+                .getAppCompatCameraOverrides()).shouldRefreshActivityForCameraCompat();
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
new file mode 100644
index 0000000..f79cdc1
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatActivityRobot.java
@@ -0,0 +1,416 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.RESIZE_MODE_RESIZEABLE;
+import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+
+import android.app.WindowConfiguration;
+import android.content.ComponentName;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.view.Surface;
+
+import androidx.annotation.NonNull;
+
+import com.android.server.wm.utils.TestComponentStack;
+
+import org.junit.Assert;
+
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+/**
+ * Robot implementation for {@link ActivityRecord}.
+ */
+class AppCompatActivityRobot {
+
+    private static final int DEFAULT_DISPLAY_WIDTH = 1000;
+    private static final int DEFAULT_DISPLAY_HEIGHT = 2000;
+
+    private static final float DELTA_ASPECT_RATIO_TOLERANCE = 0.0001f;
+    private static final float COMPAT_SCALE_TOLERANCE = 0.0001f;
+
+    private static final String TEST_COMPONENT_NAME = AppCompatActivityRobot.class.getName();
+
+    @NonNull
+    private final ActivityTaskManagerService mAtm;
+    @NonNull
+    private final ActivityTaskSupervisor mSupervisor;
+    @NonNull
+    private final TestComponentStack<ActivityRecord> mActivityStack;
+    @NonNull
+    private final TestComponentStack<Task> mTaskStack;
+
+    private final int mDisplayWidth;
+    private final int mDisplayHeight;
+    private DisplayContent mDisplayContent;
+
+    AppCompatActivityRobot(@NonNull WindowManagerService wm,
+            @NonNull ActivityTaskManagerService atm, @NonNull ActivityTaskSupervisor supervisor,
+            int displayWidth, int displayHeight) {
+        mAtm = atm;
+        mSupervisor = supervisor;
+        mDisplayWidth = displayWidth;
+        mDisplayHeight = displayHeight;
+        mActivityStack = new TestComponentStack<>();
+        mTaskStack = new TestComponentStack<>();
+        createNewDisplay();
+    }
+
+    AppCompatActivityRobot(@NonNull WindowManagerService wm,
+            @NonNull ActivityTaskManagerService atm, @NonNull ActivityTaskSupervisor supervisor) {
+        this(wm, atm, supervisor, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
+    }
+
+    void createActivityWithComponent() {
+        createActivityWithComponentInNewTask(/* inNewTask */ mTaskStack.isEmpty(),
+                /* inNewDisplay */ false);
+    }
+
+    void createActivityWithComponentInNewTask() {
+        createActivityWithComponentInNewTask(/* inNewTask */ true, /* inNewDisplay */ false);
+    }
+
+    void createActivityWithComponentInNewTaskAndDisplay() {
+        createActivityWithComponentInNewTask(/* inNewTask */ true, /* inNewDisplay */ true);
+    }
+
+
+    void configureTopActivity(float minAspect, float maxAspect, int screenOrientation,
+            boolean isUnresizable) {
+        prepareLimitedBounds(mActivityStack.top(), minAspect, maxAspect, screenOrientation,
+                isUnresizable);
+    }
+
+    void configureTopActivityIgnoreOrientationRequest(boolean ignoreOrientationRequest) {
+        mActivityStack.top().mDisplayContent
+                .setIgnoreOrientationRequest(ignoreOrientationRequest);
+    }
+
+    void configureUnresizableTopActivity(@ActivityInfo.ScreenOrientation int screenOrientation) {
+        configureTopActivity(/* minAspect */ -1, /* maxAspect */ -1, screenOrientation,
+                /* isUnresizable */ true);
+    }
+
+    void activateCameraInPolicy(boolean isCameraActive) {
+        doReturn(isCameraActive).when(mDisplayContent.mAppCompatCameraPolicy)
+                .isCameraActive(any(ActivityRecord.class), anyBoolean());
+    }
+
+    @NonNull
+    ActivityRecord top() {
+        return mActivityStack.top();
+    }
+
+    @NonNull
+    DisplayContent displayContent() {
+        return mDisplayContent;
+    }
+
+    @NonNull
+    ActivityRecord getFromTop(int fromTop) {
+        return mActivityStack.getFromTop(fromTop);
+    }
+
+    void setTaskWindowingMode(@WindowConfiguration.WindowingMode int windowingMode) {
+        mTaskStack.top().setWindowingMode(windowingMode);
+    }
+
+    void setLetterboxedForFixedOrientationAndAspectRatio(boolean enabled) {
+        doReturn(enabled).when(mActivityStack.top())
+                .isLetterboxedForFixedOrientationAndAspectRatio();
+    }
+
+    void enableTreatmentForTopActivity(boolean enabled) {
+        doReturn(enabled).when(mDisplayContent.mAppCompatCameraPolicy)
+                .isTreatmentEnabledForActivity(eq(mActivityStack.top()));
+    }
+
+    void setTopActivityCameraActive(boolean enabled) {
+        doReturn(enabled).when(getTopDisplayRotationCompatPolicy())
+                .isCameraActive(eq(mActivityStack.top()), /* mustBeFullscreen= */ eq(true));
+    }
+
+    void setTopActivityEligibleForOrientationOverride(boolean enabled) {
+        doReturn(enabled).when(getTopDisplayRotationCompatPolicy())
+                .isActivityEligibleForOrientationOverride(eq(mActivityStack.top()));
+    }
+
+    void setShouldApplyUserMinAspectRatioOverride(boolean enabled) {
+        doReturn(enabled).when(mActivityStack.top()
+                .mLetterboxUiController).shouldApplyUserMinAspectRatioOverride();
+    }
+
+    void setShouldCreateCompatDisplayInsets(boolean enabled) {
+        doReturn(enabled).when(mActivityStack.top()).shouldCreateCompatDisplayInsets();
+    }
+
+    void setShouldApplyUserFullscreenOverride(boolean enabled) {
+        doReturn(enabled).when(mActivityStack.top()
+                .mLetterboxUiController).shouldApplyUserFullscreenOverride();
+    }
+
+    void setGetUserMinAspectRatioOverrideCode(@PackageManager.UserMinAspectRatio int orientation) {
+        doReturn(orientation).when(mActivityStack.top()
+                .mLetterboxUiController).getUserMinAspectRatioOverrideCode();
+    }
+
+    void setIgnoreOrientationRequest(boolean enabled) {
+        mDisplayContent.setIgnoreOrientationRequest(enabled);
+    }
+
+    void setTopActivityAsEmbedded(boolean embedded) {
+        doReturn(embedded).when(mActivityStack.top()).isEmbedded();
+    }
+
+    void destroyTopActivity() {
+        mActivityStack.top().removeImmediately();
+    }
+
+    void destroyActivity(int fromTop) {
+        mActivityStack.applyTo(/* fromTop */ fromTop, ActivityRecord::removeImmediately);
+    }
+
+    void createNewDisplay() {
+        mDisplayContent = new TestDisplayContent.Builder(mAtm, mDisplayWidth, mDisplayHeight)
+                .build();
+        spyOnAppCompatCameraPolicy();
+    }
+
+    void createNewTask() {
+        final Task newTask = new WindowTestsBase.TaskBuilder(mSupervisor)
+                .setDisplay(mDisplayContent).build();
+        mTaskStack.push(newTask);
+    }
+
+    void createNewTaskWithBaseActivity() {
+        final Task newTask = new WindowTestsBase.TaskBuilder(mSupervisor)
+                .setCreateActivity(true)
+                .setDisplay(mDisplayContent).build();
+        mTaskStack.push(newTask);
+        pushActivity(newTask.getTopNonFinishingActivity());
+    }
+
+    void attachTopActivityToTask() {
+        mTaskStack.top().addChild(mActivityStack.top());
+    }
+
+    void applyToTopActivity(Consumer<ActivityRecord> consumer) {
+        consumer.accept(mActivityStack.top());
+    }
+
+    void applyToActivity(int fromTop, @NonNull Consumer<ActivityRecord> consumer) {
+        mActivityStack.applyTo(fromTop, consumer);
+    }
+
+    void applyToAllActivities(@NonNull Consumer<ActivityRecord> consumer) {
+        mActivityStack.applyToAll(consumer);
+    }
+
+    void rotateDisplayForTopActivity(@Surface.Rotation int rotation) {
+        rotateDisplay(mActivityStack.top().mDisplayContent, rotation);
+    }
+
+    void configureTopActivityFoldablePosture(boolean isHalfFolded, boolean isTabletop) {
+        mActivityStack.applyToTop((topActivity) -> {
+            final DisplayRotation r = topActivity.mDisplayContent.getDisplayRotation();
+            doReturn(isHalfFolded).when(r).isDisplaySeparatingHinge();
+            doReturn(false).when(r)
+                    .isDeviceInPosture(any(DeviceStateController.DeviceState.class),
+                            anyBoolean());
+            if (isHalfFolded) {
+                doReturn(true).when(r)
+                        .isDeviceInPosture(DeviceStateController.DeviceState.HALF_FOLDED,
+                                isTabletop);
+            }
+            topActivity.recomputeConfiguration();
+        });
+    }
+
+    private static void rotateDisplay(@Surface.Rotation DisplayContent display, int rotation) {
+        final Configuration c = new Configuration();
+        display.getDisplayRotation().setRotation(rotation);
+        display.computeScreenConfiguration(c);
+        display.onRequestedOverrideConfigurationChanged(c);
+    }
+
+    void assertTrueOnActivity(int fromTop, Predicate<ActivityRecord> predicate) {
+        mActivityStack.applyTo(fromTop, (activity) -> {
+            Assert.assertTrue(predicate.test(activity));
+        });
+    }
+
+    void assertFalseOnTopActivity(Predicate<ActivityRecord> predicate) {
+        Assert.assertFalse(predicate.test(mActivityStack.top()));
+    }
+
+    void assertFalseOnActivity(int fromTop, Predicate<ActivityRecord> predicate) {
+        mActivityStack.applyTo(fromTop, (activity) -> {
+            Assert.assertFalse(predicate.test(activity));
+        });
+    }
+
+    void assertNotNullOnTopActivity(Function<ActivityRecord, Object> getter) {
+        Assert.assertNotNull(getter.apply(mActivityStack.top()));
+    }
+
+    void assertNullOnTopActivity(Function<ActivityRecord, Object> getter) {
+        Assert.assertNull(getter.apply(mActivityStack.top()));
+    }
+
+    void checkTopActivityRecomputedConfiguration() {
+        verify(mActivityStack.top()).recomputeConfiguration();
+    }
+
+    void checkTopActivityConfigOrientation(@Configuration.Orientation int orientation) {
+        Assert.assertEquals(orientation, mActivityStack.top()
+                .getRequestedConfigurationOrientation());
+    }
+
+    void checkTopActivityAspectRatios(float minAspectRatio, float maxAspectRatio) {
+        final ActivityRecord topActivity = mActivityStack.top();
+        Assert.assertEquals(minAspectRatio, topActivity.getMinAspectRatio(),
+                DELTA_ASPECT_RATIO_TOLERANCE);
+        Assert.assertEquals(maxAspectRatio, topActivity.getMaxAspectRatio(),
+                DELTA_ASPECT_RATIO_TOLERANCE);
+    }
+
+    void checkTopActivityInSizeCompatMode(boolean inScm) {
+        final ActivityRecord topActivity = mActivityStack.top();
+        Assert.assertEquals(inScm, topActivity.inSizeCompatMode());
+        Assert.assertNotEquals(1f, topActivity.getCompatScale(), COMPAT_SCALE_TOLERANCE);
+    }
+
+    void launchActivity(float minAspectRatio, float maxAspectRatio,
+            @ActivityInfo.ScreenOrientation int orientation, boolean transparent,
+            boolean withComponent, boolean addToTask) {
+        final WindowTestsBase.ActivityBuilder
+                activityBuilder = new WindowTestsBase.ActivityBuilder(mAtm)
+                .setScreenOrientation(orientation)
+                .setLaunchedFromUid(0);
+        if (transparent) {
+            activityBuilder.setActivityTheme(android.R.style.Theme_Translucent);
+        }
+        if (withComponent) {
+            // Set the component to be that of the test class in order
+            // to enable compat changes
+            activityBuilder.setComponent(ComponentName.createRelative(mAtm.mContext,
+                    TEST_COMPONENT_NAME));
+        }
+        if (minAspectRatio >= 0) {
+            activityBuilder.setMinAspectRatio(minAspectRatio);
+        }
+        if (maxAspectRatio >= 0) {
+            activityBuilder.setMaxAspectRatio(maxAspectRatio);
+        }
+        final ActivityRecord newActivity = activityBuilder.build();
+        if (addToTask) {
+            if (mTaskStack.isEmpty()) {
+                createNewTask();
+            }
+            mTaskStack.top().addChild(newActivity);
+        }
+        pushActivity(newActivity);
+    }
+
+    private void createActivityWithComponentInNewTask(boolean inNewTask, boolean inNewDisplay) {
+        if (inNewDisplay) {
+            createNewDisplay();
+        }
+        if (inNewTask) {
+            createNewTask();
+        }
+        final ActivityRecord activity = new WindowTestsBase.ActivityBuilder(mAtm)
+                .setOnTop(true)
+                .setTask(mTaskStack.top())
+                // Set the component to be that of the test class in order
+                // to enable compat changes
+                .setComponent(ComponentName.createRelative(mAtm.mContext, TEST_COMPONENT_NAME))
+                .build();
+        pushActivity(activity);
+    }
+
+    /**
+     * Setups activity with restriction on its bounds, such as maxAspect, minAspect,
+     * fixed orientation, and/or whether it is resizable.
+     */
+    private void prepareLimitedBounds(ActivityRecord activity, float minAspect, float maxAspect,
+            @ActivityInfo.ScreenOrientation int screenOrientation, boolean isUnresizable) {
+        activity.info.resizeMode = isUnresizable
+                ? RESIZE_MODE_UNRESIZEABLE
+                : RESIZE_MODE_RESIZEABLE;
+        final Task task = activity.getTask();
+        if (task != null) {
+            // Update the Task resize value as activity will follow the task.
+            task.mResizeMode = activity.info.resizeMode;
+            task.getRootActivity().info.resizeMode = activity.info.resizeMode;
+        }
+        activity.setVisibleRequested(true);
+        if (maxAspect >= 0) {
+            activity.info.setMaxAspectRatio(maxAspect);
+        }
+        if (minAspect >= 0) {
+            activity.info.setMinAspectRatio(minAspect);
+        }
+        if (screenOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
+            activity.info.screenOrientation = screenOrientation;
+            activity.setRequestedOrientation(screenOrientation);
+        }
+        // Make sure to use the provided configuration to construct the size compat fields.
+        activity.clearSizeCompatMode();
+        activity.ensureActivityConfiguration();
+        // Make sure the display configuration reflects the change of activity.
+        if (activity.mDisplayContent.updateOrientation()) {
+            activity.mDisplayContent.sendNewConfiguration();
+        }
+    }
+
+    private DisplayRotationCompatPolicy getTopDisplayRotationCompatPolicy() {
+        return mActivityStack.top().mDisplayContent
+                .mAppCompatCameraPolicy.mDisplayRotationCompatPolicy;
+    }
+
+    // We add the activity to the stack and spyOn() on its properties.
+    private void pushActivity(@NonNull ActivityRecord activity) {
+        mActivityStack.push(activity);
+        spyOn(activity);
+        spyOn(activity.mAppCompatController.getTransparentPolicy());
+        spyOn(activity.mLetterboxUiController);
+    }
+
+    private void spyOnAppCompatCameraPolicy() {
+        spyOn(mDisplayContent.mAppCompatCameraPolicy);
+        if (mDisplayContent.mAppCompatCameraPolicy.hasDisplayRotationCompatPolicy()) {
+            spyOn(mDisplayContent.mAppCompatCameraPolicy.mDisplayRotationCompatPolicy);
+        }
+        if (mDisplayContent.mAppCompatCameraPolicy.hasCameraCompatFreeformPolicy()) {
+            spyOn(mDisplayContent.mAppCompatCameraPolicy.mCameraCompatFreeformPolicy);
+        }
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java
new file mode 100644
index 0000000..2d94b34
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraOverridesTest.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
+import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA;
+import static android.content.pm.ActivityInfo.OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH;
+import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.window.flags.Flags.FLAG_CAMERA_COMPAT_FOR_FREEFORM;
+
+import android.compat.testing.PlatformCompatChangeRule;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.annotation.NonNull;
+
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.testng.Assert;
+
+import java.util.function.Consumer;
+
+/**
+ * Test class for {@link AppCompatCameraOverrides}.
+ * <p>
+ * Build/Install/Run:
+ * atest WmTests:AppCompatCameraOverridesTest
+ */
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class AppCompatCameraOverridesTest extends WindowTestsBase {
+
+    @Rule
+    public TestRule compatChangeRule = new PlatformCompatChangeRule();
+
+    @Test
+    public void testShouldRefreshActivityForCameraCompat_flagIsDisabled_returnsFalse() {
+        runTestScenario((robot) -> {
+            robot.conf().enableCameraCompatTreatment(false);
+            robot.activity().createActivityWithComponentInNewTask();
+
+            robot.checkShouldRefreshActivityForCameraCompat(false);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
+    public void testShouldRefreshActivityForCameraCompat_overrideEnabled_returnsFalse() {
+        runTestScenario((robot) -> {
+            robot.conf().enableCameraCompatTreatment(true);
+            robot.activity().createActivityWithComponentInNewTask();
+
+            robot.checkShouldRefreshActivityForCameraCompat(false);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
+    public void testShouldRefreshActivityForCameraCompat_propertyIsTrueAndOverride_returnsFalse() {
+        runTestScenario((robot) -> {
+            robot.conf().enableCameraCompatTreatment(true);
+            robot.prop().enable(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH);
+            robot.activity().createActivityWithComponentInNewTask();
+
+            robot.checkShouldRefreshActivityForCameraCompat(false);
+        });
+    }
+
+    @Test
+    public void testShouldRefreshActivityForCameraCompat_propertyIsFalse_returnsFalse() {
+        runTestScenario((robot) -> {
+            robot.conf().enableCameraCompatTreatment(true);
+            robot.prop().disable(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH);
+            robot.activity().createActivityWithComponentInNewTask();
+
+            robot.checkShouldRefreshActivityForCameraCompat(false);
+        });
+    }
+
+    @Test
+    public void testShouldRefreshActivityForCameraCompat_propertyIsTrue_returnsTrue() {
+        runTestScenario((robot) -> {
+            robot.conf().enableCameraCompatTreatment(true);
+            robot.prop().enable(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH);
+            robot.activity().createActivityWithComponentInNewTask();
+
+            robot.checkShouldRefreshActivityForCameraCompat(true);
+        });
+    }
+
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
+    public void testShouldRefreshActivityViaPauseForCameraCompat_flagIsDisabled_returnsFalse() {
+        runTestScenario((robot) -> {
+            robot.conf().enableCameraCompatTreatment(false);
+            robot.activity().createActivityWithComponentInNewTask();
+
+            robot.checkShouldRefreshActivityViaPauseForCameraCompat(false);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
+    public void testShouldRefreshActivityViaPauseForCameraCompat_overrideEnabled_returnsTrue() {
+        runTestScenario((robot) -> {
+            robot.conf().enableCameraCompatTreatment(true);
+            robot.activity().createActivityWithComponentInNewTask();
+
+            robot.checkShouldRefreshActivityViaPauseForCameraCompat(true);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
+    public void testShouldRefreshActivityViaPauseForCameraCompat_propertyFalseAndOverrideFalse() {
+        runTestScenario((robot) -> {
+            robot.conf().enableCameraCompatTreatment(true);
+            robot.prop().disable(PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE);
+            robot.activity().createActivityWithComponentInNewTask();
+
+            robot.checkShouldRefreshActivityViaPauseForCameraCompat(false);
+        });
+    }
+
+    @Test
+    public void testShouldRefreshActivityViaPauseForCameraCompat_propertyIsTrue_returnsTrue() {
+        runTestScenario((robot) -> {
+            robot.conf().enableCameraCompatTreatment(true);
+            robot.prop().enable(PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE);
+            robot.activity().createActivityWithComponentInNewTask();
+
+            robot.checkShouldRefreshActivityViaPauseForCameraCompat(true);
+        });
+    }
+
+    @Test
+    public void testShouldForceRotateForCameraCompat_flagIsDisabled_returnsFalse() {
+        runTestScenario((robot) -> {
+            robot.conf().enableCameraCompatTreatment(false);
+            robot.activity().createActivityWithComponentInNewTask();
+
+            robot.checkShouldForceRotateForCameraCompat(false);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION})
+    public void testShouldForceRotateForCameraCompat_overrideEnabled_returnsFalse() {
+        runTestScenario((robot) -> {
+            robot.conf().enableCameraCompatTreatment(true);
+            robot.activity().createActivityWithComponentInNewTask();
+
+            robot.checkShouldForceRotateForCameraCompat(false);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION})
+    public void testShouldForceRotateForCameraCompat_propertyIsTrueAndOverride_returnsFalse() {
+        runTestScenario((robot) -> {
+            robot.conf().enableCameraCompatTreatment(true);
+            robot.prop().enable(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION);
+            robot.activity().createActivityWithComponentInNewTask();
+
+            robot.checkShouldForceRotateForCameraCompat(false);
+        });
+    }
+
+    @Test
+    public void testShouldForceRotateForCameraCompat_propertyIsFalse_returnsFalse() {
+        runTestScenario((robot) -> {
+            robot.conf().enableCameraCompatTreatment(true);
+            robot.prop().disable(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION);
+            robot.activity().createActivityWithComponentInNewTask();
+
+            robot.checkShouldForceRotateForCameraCompat(false);
+        });
+    }
+
+    @Test
+    public void testShouldForceRotateForCameraCompat_propertyIsTrue_returnsTrue() {
+        runTestScenario((robot) -> {
+            robot.conf().enableCameraCompatTreatment(true);
+            robot.prop().enable(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION);
+            robot.activity().createActivityWithComponentInNewTask();
+
+            robot.checkShouldForceRotateForCameraCompat(true);
+        });
+    }
+
+    @Test
+    @DisableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
+    public void testShouldApplyCameraCompatFreeformTreatment_flagIsDisabled_returnsFalse() {
+        runTestScenario((robot) -> {
+            robot.activity().createActivityWithComponentInNewTask();
+
+            robot.checkShouldApplyFreeformTreatmentForCameraCompat(false);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT})
+    @EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
+    public void testShouldApplyCameraCompatFreeformTreatment_overrideEnabled_returnsFalse() {
+        runTestScenario((robot) -> {
+            robot.activity().createActivityWithComponentInNewTask();
+
+            robot.checkShouldApplyFreeformTreatmentForCameraCompat(false);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT})
+    @EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
+    public void testShouldApplyCameraCompatFreeformTreatment_disabledByOverride_returnsFalse() {
+        runTestScenario((robot) -> {
+            robot.activity().createActivityWithComponentInNewTask();
+
+            robot.checkShouldApplyFreeformTreatmentForCameraCompat(false);
+        });
+    }
+
+    @Test
+    @EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
+    public void testShouldApplyCameraCompatFreeformTreatment_notDisabledByOverride_returnsTrue() {
+        runTestScenario((robot) -> {
+            robot.activity().createActivityWithComponentInNewTask();
+
+            robot.checkShouldApplyFreeformTreatmentForCameraCompat(true);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA,
+            OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA})
+    public void testShouldRecomputeConfigurationForCameraCompat() {
+        runTestScenario((robot) -> {
+            robot.conf().enableCameraCompatSplitScreenAspectRatio(true);
+            robot.applyOnActivity((a) -> {
+                a.createActivityWithComponentInNewTask();
+                a.activateCameraInPolicy(true);
+                a.setShouldCreateCompatDisplayInsets(false);
+            });
+
+            robot.checkShouldApplyFreeformTreatmentForCameraCompat(true);
+        });
+    }
+
+    @Test
+    public void testIsCameraActive() {
+        runTestScenario((robot) -> {
+            robot.applyOnActivity((a) -> {
+                a.createActivityWithComponent();
+                a.activateCameraInPolicy(/* isCameraActive */ false);
+                robot.checkIsCameraActive(/* active */ false);
+                a.activateCameraInPolicy(/* isCameraActive */ true);
+                robot.checkIsCameraActive(/* active */ true);
+            });
+        });
+    }
+
+    /**
+     * Runs a test scenario providing a Robot.
+     */
+    void runTestScenario(@NonNull Consumer<CameraOverridesRobotTest> consumer) {
+        spyOn(mWm.mLetterboxConfiguration);
+        final CameraOverridesRobotTest robot = new CameraOverridesRobotTest(mWm, mAtm, mSupervisor);
+        consumer.accept(robot);
+    }
+
+    private static class CameraOverridesRobotTest extends AppCompatRobotBase {
+
+        CameraOverridesRobotTest(@NonNull WindowManagerService wm,
+                @NonNull ActivityTaskManagerService atm,
+                @NonNull ActivityTaskSupervisor supervisor) {
+            super(wm, atm, supervisor);
+        }
+
+        void checkShouldRefreshActivityForCameraCompat(boolean expected) {
+            Assert.assertEquals(getAppCompatCameraOverrides()
+                    .shouldRefreshActivityForCameraCompat(), expected);
+        }
+
+        void checkShouldRefreshActivityViaPauseForCameraCompat(boolean expected) {
+            Assert.assertEquals(getAppCompatCameraOverrides()
+                    .shouldRefreshActivityViaPauseForCameraCompat(), expected);
+        }
+
+        void checkShouldForceRotateForCameraCompat(boolean expected) {
+            Assert.assertEquals(getAppCompatCameraOverrides()
+                    .shouldForceRotateForCameraCompat(), expected);
+        }
+
+        void checkShouldApplyFreeformTreatmentForCameraCompat(boolean expected) {
+            Assert.assertEquals(getAppCompatCameraOverrides()
+                    .shouldApplyFreeformTreatmentForCameraCompat(), expected);
+        }
+
+        void checkIsCameraActive(boolean active) {
+            Assert.assertEquals(getAppCompatCameraOverrides().isCameraActive(), active);
+        }
+
+        private AppCompatCameraOverrides getAppCompatCameraOverrides() {
+            return activity().top().mAppCompatController.getAppCompatCameraOverrides();
+        }
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraPolicyTest.java
new file mode 100644
index 0000000..006b370
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatCameraPolicyTest.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.window.flags.Flags.FLAG_CAMERA_COMPAT_FOR_FREEFORM;
+
+import static org.mockito.ArgumentMatchers.any;
+
+import android.compat.testing.PlatformCompatChangeRule;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.annotation.NonNull;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+
+import java.util.function.Consumer;
+
+/**
+ * Test class for {@link AppCompatCameraPolicy}.
+ * <p>
+ * Build/Install/Run:
+ * atest WmTests:AppCompatCameraPolicyTest
+ */
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class AppCompatCameraPolicyTest extends WindowTestsBase {
+
+    @Rule
+    public TestRule compatChangeRule = new PlatformCompatChangeRule();
+
+    @Test
+    public void testDisplayRotationCompatPolicy_presentWhenEnabled() {
+        runTestScenario((robot) -> {
+            robot.conf().enableCameraCompatTreatmentAtBuildTime(true);
+            robot.activity().createActivityWithComponentInNewTaskAndDisplay();
+            robot.checkTopActivityHasDisplayRotationCompatPolicy(true);
+        });
+    }
+
+    @Test
+    public void testDisplayRotationCompatPolicy_notPresentWhenDisabled() {
+        runTestScenario((robot) -> {
+            robot.conf().enableCameraCompatTreatmentAtBuildTime(false);
+            robot.activity().createActivityWithComponentInNewTaskAndDisplay();
+            robot.checkTopActivityHasDisplayRotationCompatPolicy(false);
+        });
+    }
+
+    @Test
+    @EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
+    public void testCameraCompatFreeformPolicy_presentWhenEnabledAndDW() {
+        runTestScenario((robot) -> {
+            robot.allowEnterDesktopMode(true);
+            robot.activity().createActivityWithComponentInNewTaskAndDisplay();
+            robot.checkTopActivityHasCameraCompatFreeformPolicy(true);
+        });
+    }
+
+    @Test
+    @EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
+    public void testCameraCompatFreeformPolicy_notPresentWhenNoDW() {
+        runTestScenario((robot) -> {
+            robot.allowEnterDesktopMode(false);
+            robot.activity().createActivityWithComponentInNewTaskAndDisplay();
+            robot.checkTopActivityHasCameraCompatFreeformPolicy(false);
+        });
+    }
+
+    @Test
+    @DisableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
+    public void testCameraCompatFreeformPolicy_notPresentWhenNoFlag() {
+        runTestScenario((robot) -> {
+            robot.allowEnterDesktopMode(true);
+            robot.activity().createActivityWithComponentInNewTaskAndDisplay();
+            robot.checkTopActivityHasCameraCompatFreeformPolicy(false);
+        });
+    }
+
+    @Test
+    @EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
+    public void testCameraCompatFreeformPolicy_notPresentWhenNoFlagAndNoDW() {
+        runTestScenario((robot) -> {
+            robot.allowEnterDesktopMode(false);
+            robot.activity().createActivityWithComponentInNewTaskAndDisplay();
+            robot.checkTopActivityHasCameraCompatFreeformPolicy(false);
+        });
+    }
+
+    /**
+     * Runs a test scenario providing a Robot.
+     */
+    void runTestScenario(@NonNull Consumer<DisplayRotationPolicyRobotTest> consumer) {
+        spyOn(mWm.mLetterboxConfiguration);
+        final DisplayRotationPolicyRobotTest robot =
+                new DisplayRotationPolicyRobotTest(mWm, mAtm, mSupervisor);
+        consumer.accept(robot);
+    }
+
+    @Test
+    public void testIsCameraCompatTreatmentActive_whenTreatmentForTopActivityIsEnabled() {
+        runTestScenario((robot) -> {
+            robot.applyOnActivity((a)-> {
+                a.createActivityWithComponent();
+                a.enableTreatmentForTopActivity(/* enabled */ true);
+            });
+
+            robot.checkIsCameraCompatTreatmentActiveForTopActivity(/* active */ true);
+        });
+    }
+
+    @Test
+    public void testIsCameraCompatTreatmentNotActive_whenTreatmentForTopActivityIsDisabled() {
+        runTestScenario((robot) -> {
+            robot.applyOnActivity((a)-> {
+                a.createActivityWithComponent();
+                a.enableTreatmentForTopActivity(/* enabled */ false);
+            });
+
+            robot.checkIsCameraCompatTreatmentActiveForTopActivity(/* active */ false);
+        });
+    }
+
+    private static class DisplayRotationPolicyRobotTest extends AppCompatRobotBase {
+
+        DisplayRotationPolicyRobotTest(@NonNull WindowManagerService wm,
+                @NonNull ActivityTaskManagerService atm,
+                @NonNull ActivityTaskSupervisor supervisor) {
+            super(wm, atm, supervisor);
+        }
+
+        void checkTopActivityHasDisplayRotationCompatPolicy(boolean exists) {
+            Assert.assertEquals(exists, activity().top().mDisplayContent
+                    .mAppCompatCameraPolicy.hasDisplayRotationCompatPolicy());
+        }
+
+        void checkTopActivityHasCameraCompatFreeformPolicy(boolean exists) {
+            Assert.assertEquals(exists, activity().top().mDisplayContent
+                    .mAppCompatCameraPolicy.hasCameraCompatFreeformPolicy());
+        }
+
+        void checkIsCameraCompatTreatmentActiveForTopActivity(boolean active) {
+            Assert.assertEquals(getTopAppCompatCameraPolicy()
+                    .isTreatmentEnabledForActivity(activity().top()), active);
+        }
+
+        // TODO(b/350460645): Create Desktop Windowing Robot to reuse common functionalities.
+        void allowEnterDesktopMode(boolean isAllowed) {
+            doReturn(isAllowed).when(() ->
+                    DesktopModeLaunchParamsModifier.canEnterDesktopMode(any()));
+        }
+
+        private AppCompatCameraPolicy getTopAppCompatCameraPolicy() {
+            return activity().top().mDisplayContent.mAppCompatCameraPolicy;
+        }
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatComponentPropRobot.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatComponentPropRobot.java
new file mode 100644
index 0000000..d568eec
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatComponentPropRobot.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+
+import android.content.pm.PackageManager;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Robot class for optIn/optOut properties.
+ */
+class AppCompatComponentPropRobot {
+    @NonNull
+    private final WindowManagerService mWm;
+
+    AppCompatComponentPropRobot(@NonNull WindowManagerService wm) {
+        mWm = wm;
+    }
+
+    void enable(@NonNull String propertyName) {
+        setPropertyValue(propertyName, /* enabled */ true);
+    }
+
+    void disable(@NonNull String propertyName) {
+        setPropertyValue(propertyName, /* enabled */ false);
+    }
+
+    private void setPropertyValue(@NonNull String propertyName, boolean enabled) {
+        final PackageManager.Property property = new PackageManager.Property(propertyName,
+                /* value */ enabled, /* packageName */ "", /* className */ "");
+        final PackageManager pm = mWm.mContext.getPackageManager();
+        spyOn(pm);
+        try {
+            doReturn(property).when(pm).getProperty(eq(propertyName), anyString());
+        } catch (PackageManager.NameNotFoundException e) {
+            fail(e.getLocalizedMessage());
+        }
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxConfigurationRobot.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxConfigurationRobot.java
new file mode 100644
index 0000000..e1da913
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatLetterboxConfigurationRobot.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+
+import static org.mockito.Mockito.when;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Robot implementation for {@link LetterboxConfiguration}.
+ */
+class AppCompatLetterboxConfigurationRobot {
+
+    @NonNull
+    private final LetterboxConfiguration mLetterboxConfiguration;
+
+    AppCompatLetterboxConfigurationRobot(@NonNull LetterboxConfiguration letterboxConfiguration) {
+        mLetterboxConfiguration = letterboxConfiguration;
+        spyOn(mLetterboxConfiguration);
+    }
+
+    void enableTranslucentPolicy(boolean enabled) {
+        when(mLetterboxConfiguration.isTranslucentLetterboxingEnabled()).thenReturn(enabled);
+    }
+
+    void enablePolicyForIgnoringRequestedOrientation(boolean enabled) {
+        doReturn(enabled).when(mLetterboxConfiguration)
+                .isPolicyForIgnoringRequestedOrientationEnabled();
+    }
+
+    void enableCameraCompatTreatment(boolean enabled) {
+        doReturn(enabled).when(mLetterboxConfiguration).isCameraCompatTreatmentEnabled();
+    }
+
+    void enableCameraCompatTreatmentAtBuildTime(boolean enabled) {
+        doReturn(enabled).when(mLetterboxConfiguration)
+                .isCameraCompatTreatmentEnabledAtBuildTime();
+    }
+
+    void enableUserAppAspectRatioFullscreen(boolean enabled) {
+        doReturn(enabled).when(mLetterboxConfiguration).isUserAppAspectRatioFullscreenEnabled();
+    }
+
+    void enableUserAppAspectRatioSettings(boolean enabled) {
+        doReturn(enabled).when(mLetterboxConfiguration).isUserAppAspectRatioSettingsEnabled();
+    }
+
+    void enableCameraCompatSplitScreenAspectRatio(boolean enabled) {
+        doReturn(enabled).when(mLetterboxConfiguration)
+                .isCameraCompatSplitScreenAspectRatioEnabled();
+    }
+
+
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationOverridesTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationOverridesTest.java
new file mode 100644
index 0000000..35c2ee0
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationOverridesTest.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.server.wm.AppCompatOrientationOverrides.OrientationOverridesState.MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP;
+import static com.android.server.wm.AppCompatOrientationOverrides.OrientationOverridesState.SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.compat.testing.PlatformCompatChangeRule;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.annotation.NonNull;
+
+import com.android.server.wm.utils.CurrentTimeMillisSupplierFake;
+
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+
+import java.util.function.Consumer;
+import java.util.function.IntConsumer;
+
+/**
+ * Test class for {@link AppCompatOrientationOverrides}.
+ * <p>
+ * Build/Install/Run:
+ * atest WmTests:AppCompatOrientationOverridesTest
+ */
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class AppCompatOrientationOverridesTest extends WindowTestsBase {
+
+    @Rule
+    public TestRule compatChangeRule = new PlatformCompatChangeRule();
+
+    @Test
+    public void testShouldIgnoreOrientationRequestLoop_overrideDisabled_returnsFalse() {
+        runTestScenario((robot) -> {
+            robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+            robot.applyOnActivity((a) -> {
+                a.createActivityWithComponent();
+                a.setLetterboxedForFixedOrientationAndAspectRatio(false);
+            });
+            robot.checkRequestLoopExtended((i) -> {
+                robot.checkShouldNotIgnoreOrientationLoop();
+                robot.checkExpectedLoopCount(/* expectedCount */ 0);
+            });
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
+    public void testShouldIgnoreOrientationRequestLoop_propertyIsFalseAndOverride_returnsFalse() {
+        runTestScenario((robot) -> {
+            robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+            robot.prop().disable(
+                    PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED);
+            robot.applyOnActivity((a) -> {
+                a.createActivityWithComponent();
+                a.setLetterboxedForFixedOrientationAndAspectRatio(false);
+            });
+            robot.checkRequestLoopExtended((i) -> {
+                robot.checkShouldNotIgnoreOrientationLoop();
+                robot.checkExpectedLoopCount(/* expectedCount */ 0);
+            });
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
+    public void testShouldIgnoreOrientationRequestLoop_isLetterboxed_returnsFalse() {
+        runTestScenario((robot) -> {
+            robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+            robot.applyOnActivity((a) -> {
+                a.createActivityWithComponent();
+                a.setLetterboxedForFixedOrientationAndAspectRatio(true);
+            });
+            robot.checkRequestLoopExtended((i) -> {
+                robot.checkShouldNotIgnoreOrientationLoop();
+                robot.checkExpectedLoopCount(/* expectedCount */ i);
+            });
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
+    public void testShouldIgnoreOrientationRequestLoop_noLoop_returnsFalse() {
+        runTestScenario((robot) -> {
+            robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+            robot.applyOnActivity((a) -> {
+                a.createActivityWithComponent();
+                a.setLetterboxedForFixedOrientationAndAspectRatio(false);
+            });
+
+            robot.checkShouldNotIgnoreOrientationLoop();
+            robot.checkExpectedLoopCount(/* expectedCount */ 0);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
+    public void testShouldIgnoreOrientationRequestLoop_timeout_returnsFalse() {
+        runTestScenario((robot) -> {
+            robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+            robot.applyOnActivity((a) -> {
+                a.createActivityWithComponent();
+                a.setLetterboxedForFixedOrientationAndAspectRatio(false);
+            });
+
+            robot.prepareMockedTime();
+            robot.checkRequestLoopExtended((i) -> {
+                robot.checkShouldNotIgnoreOrientationLoop();
+                robot.checkExpectedLoopCount(/* expectedCount */ 0);
+                robot.delay();
+            });
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
+    public void testShouldIgnoreOrientationRequestLoop_returnsTrue() {
+        runTestScenario((robot) -> {
+            robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+            robot.applyOnActivity((a) -> {
+                a.createActivityWithComponent();
+                a.setLetterboxedForFixedOrientationAndAspectRatio(false);
+            });
+
+            robot.checkRequestLoop((i) -> {
+                robot.checkShouldNotIgnoreOrientationLoop();
+                robot.checkExpectedLoopCount(/* expectedCount */ i);
+            });
+            robot.checkShouldIgnoreOrientationLoop();
+            robot.checkExpectedLoopCount(/* expectedCount */ MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP);
+        });
+    }
+
+    /**
+     * Runs a test scenario providing a Robot.
+     */
+    void runTestScenario(@NonNull Consumer<OrientationOverridesRobotTest> consumer) {
+        spyOn(mWm.mLetterboxConfiguration);
+        final OrientationOverridesRobotTest robot =
+                new OrientationOverridesRobotTest(mWm, mAtm, mSupervisor);
+        consumer.accept(robot);
+    }
+
+    private static class OrientationOverridesRobotTest extends AppCompatRobotBase {
+
+        @NonNull
+        private final CurrentTimeMillisSupplierFake mTestCurrentTimeMillisSupplier;
+
+        OrientationOverridesRobotTest(@NonNull WindowManagerService wm,
+                @NonNull ActivityTaskManagerService atm,
+                @NonNull ActivityTaskSupervisor supervisor) {
+            super(wm, atm, supervisor);
+            mTestCurrentTimeMillisSupplier = new CurrentTimeMillisSupplierFake();
+        }
+
+        // Useful to reduce timeout during tests
+        void prepareMockedTime() {
+            getTopOrientationOverrides().mOrientationOverridesState.mCurrentTimeMillisSupplier =
+                    mTestCurrentTimeMillisSupplier;
+        }
+
+        void delay() {
+            mTestCurrentTimeMillisSupplier.delay(SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS);
+        }
+
+        void checkExpectedLoopCount(int expectedCount) {
+            assertEquals(expectedCount, getTopOrientationOverrides()
+                    .getSetOrientationRequestCounter());
+        }
+
+        void checkShouldNotIgnoreOrientationLoop() {
+            assertFalse(getTopOrientationOverrides().shouldIgnoreOrientationRequestLoop());
+        }
+
+        void checkShouldIgnoreOrientationLoop() {
+            assertTrue(getTopOrientationOverrides().shouldIgnoreOrientationRequestLoop());
+        }
+
+        void checkRequestLoop(IntConsumer consumer) {
+            for (int i = 0; i < MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
+                consumer.accept(i);
+            }
+        }
+
+        void checkRequestLoopExtended(IntConsumer consumer) {
+            for (int i = 0; i <= MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
+                consumer.accept(i);
+            }
+        }
+
+        private AppCompatOrientationOverrides getTopOrientationOverrides() {
+            return activity().top().mAppCompatController.getAppCompatOverrides()
+                    .getAppCompatOrientationOverrides();
+        }
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java
new file mode 100644
index 0000000..aa520e9
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatOrientationPolicyTest.java
@@ -0,0 +1,577 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.OVERRIDE_ANY_ORIENTATION;
+import static android.content.pm.ActivityInfo.OVERRIDE_ANY_ORIENTATION_TO_USER;
+import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
+import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION;
+import static android.content.pm.ActivityInfo.OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE;
+import static android.content.pm.ActivityInfo.OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA;
+import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR;
+import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2;
+import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE;
+import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE;
+import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.verify;
+
+import android.compat.testing.PlatformCompatChangeRule;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.annotation.NonNull;
+
+import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+
+import java.util.function.Consumer;
+
+/**
+ * Test class for {@link AppCompatOrientationPolicy}.
+ * <p>
+ * Build/Install/Run:
+ * atest WmTests:AppCompatOrientationPolicyTest
+ */
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class AppCompatOrientationPolicyTest extends WindowTestsBase {
+
+    @Rule
+    public TestRule compatChangeRule = new PlatformCompatChangeRule();
+
+    @Test
+    public void testOverrideOrientationIfNeeded_mapInvokedOnRequest() {
+        runTestScenarioWithActivity((robot) -> {
+            robot.overrideOrientationIfNeeded(SCREEN_ORIENTATION_PORTRAIT);
+            robot.checkOrientationRequestMapped();
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_ANY_ORIENTATION_TO_USER})
+    public void testOverrideOrientationIfNeeded_fullscreenOverrideEnabled_returnsUser() {
+        runTestScenarioWithActivity((robot) -> {
+            robot.activity().setIgnoreOrientationRequest(true);
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
+                    /* expected */ SCREEN_ORIENTATION_USER);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_ANY_ORIENTATION_TO_USER})
+    public void testOverrideOrientationIfNeeded_fullscreenOverrideEnabled_optOut_isUnchanged() {
+        runTestScenario((robot) -> {
+            robot.prop().disable(PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE);
+            robot.applyOnActivity((a) -> {
+                a.createActivityWithComponent();
+                a.setIgnoreOrientationRequest(true);
+            });
+
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
+                    /* expected */ SCREEN_ORIENTATION_PORTRAIT);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_ANY_ORIENTATION_TO_USER})
+    public void testOverrideOrientationIfNeeded_fullscreenOverrides_optOutSystem_returnsUser() {
+        runTestScenario((robot) -> {
+            robot.prop().disable(PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE);
+            robot.conf().enableUserAppAspectRatioFullscreen(true);
+            robot.applyOnActivity((a) -> {
+                a.createActivityWithComponent();
+                a.setIgnoreOrientationRequest(true);
+                a.setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_FULLSCREEN);
+            });
+
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
+                    /* expected */ SCREEN_ORIENTATION_USER);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_ANY_ORIENTATION_TO_USER})
+    public void testOverrideOrientationIfNeeded_fullscreenOverrides_optOutUser_returnsUser() {
+        runTestScenario((robot) -> {
+            robot.prop().disable(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE);
+            robot.conf().enableUserAppAspectRatioFullscreen(true);
+            robot.applyOnActivity((a) -> {
+                a.createActivityWithComponent();
+                a.setIgnoreOrientationRequest(true);
+                a.setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_FULLSCREEN);
+            });
+
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
+                    /* expected */ SCREEN_ORIENTATION_USER);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_ANY_ORIENTATION_TO_USER})
+    public void testOverrideOrientationIfNeeded_fullscreenOverrideEnabled_returnsUnchanged()
+            throws Exception {
+        runTestScenarioWithActivity((robot) -> {
+            robot.activity().setIgnoreOrientationRequest(false);
+
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
+                    /* expected */ SCREEN_ORIENTATION_PORTRAIT);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_ANY_ORIENTATION_TO_USER})
+    public void testOverrideOrientationIfNeeded_fullscreenAndUserOverrideEnabled_isUnchanged() {
+        runTestScenario((robot) -> {
+            robot.conf().enableUserAppAspectRatioSettings(true);
+
+            robot.applyOnActivity((a) -> {
+                a.createActivityWithComponent();
+                a.setIgnoreOrientationRequest(true);
+                a.setGetUserMinAspectRatioOverrideCode(USER_MIN_ASPECT_RATIO_3_2);
+            });
+
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
+                    /* expected */ SCREEN_ORIENTATION_PORTRAIT);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT})
+    public void testOverrideOrientationIfNeeded_portraitOverrideEnabled_returnsPortrait() {
+        runTestScenarioWithActivity((robot) -> {
+            robot.checkOverrideOrientation(
+                    /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED,
+                    /* expected */ SCREEN_ORIENTATION_PORTRAIT);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR})
+    public void testOverrideOrientationIfNeeded_portraitOverrideEnabled_returnsNosensor() {
+        runTestScenarioWithActivity((robot) -> {
+            robot.checkOverrideOrientation(
+                    /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED,
+                    /* expected */ SCREEN_ORIENTATION_NOSENSOR);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR})
+    public void testOverrideOrientationIfNeeded_nosensorOverride_orientationFixed_isUnchanged() {
+        runTestScenarioWithActivity((robot) -> {
+            robot.checkOverrideOrientation(
+                    /* candidate */ SCREEN_ORIENTATION_PORTRAIT,
+                    /* expected */ SCREEN_ORIENTATION_PORTRAIT);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE})
+    public void testOverrideOrientationIfNeeded_reverseLandscape_portraitOrUndefined_isUnchanged() {
+        runTestScenarioWithActivity((robot) -> {
+            robot.checkOverrideOrientation(
+                    /* candidate */ SCREEN_ORIENTATION_PORTRAIT,
+                    /* expected */ SCREEN_ORIENTATION_PORTRAIT);
+            robot.checkOverrideOrientation(
+                    /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED,
+                    /* expected */ SCREEN_ORIENTATION_UNSPECIFIED);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE})
+    public void testOverrideOrientationIfNeeded_reverseLandscape_Landscape_getsReverseLandscape() {
+        runTestScenarioWithActivity((robot) -> {
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_LANDSCAPE,
+                    /* expected */ SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT})
+    public void testOverrideOrientationIfNeeded_portraitOverride_orientationFixed_IsUnchanged() {
+        runTestScenarioWithActivity((robot) -> {
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_NOSENSOR,
+                    /* expected */ SCREEN_ORIENTATION_NOSENSOR);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT, OVERRIDE_ANY_ORIENTATION})
+    public void testOverrideOrientationIfNeeded_portraitAndIgnoreFixedOverrides_returnsPortrait() {
+        runTestScenarioWithActivity((robot) -> {
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_NOSENSOR,
+                    /* expected */ SCREEN_ORIENTATION_PORTRAIT);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR, OVERRIDE_ANY_ORIENTATION})
+    public void testOverrideOrientationIfNeeded_noSensorAndIgnoreFixedOverrides_returnsNosensor() {
+        runTestScenarioWithActivity((robot) -> {
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
+                    /* expected */ SCREEN_ORIENTATION_NOSENSOR);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT})
+    public void testOverrideOrientationIfNeeded_propertyIsFalse_isUnchanged()
+            throws Exception {
+        runTestScenario((robot) -> {
+            robot.prop().disable(PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE);
+
+            robot.activity().createActivityWithComponent();
+
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_UNSPECIFIED,
+                    /* expected */ SCREEN_ORIENTATION_UNSPECIFIED);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT,
+            OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA})
+    public void testOverrideOrientationIfNeeded_whenCameraNotActive_isUnchanged() {
+        runTestScenario((robot) -> {
+            robot.applyOnConf((c)-> {
+                c.enableCameraCompatTreatment(true);
+                c.enableCameraCompatTreatmentAtBuildTime(true);
+            });
+            robot.applyOnActivity((a) -> {
+                a.createActivityWithComponentInNewTaskAndDisplay();
+                a.setTopActivityEligibleForOrientationOverride(false);
+            });
+
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_UNSPECIFIED,
+                    /* expected */ SCREEN_ORIENTATION_UNSPECIFIED);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT,
+            OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA})
+    public void testOverrideOrientationIfNeeded_whenCameraActive_returnsPortrait() {
+        runTestScenario((robot) -> {
+            robot.applyOnConf((c) -> {
+                c.enableCameraCompatTreatment(true);
+                c.enableCameraCompatTreatmentAtBuildTime(true);
+            });
+            robot.applyOnActivity((a) -> {
+                a.createActivityWithComponentInNewTaskAndDisplay();
+                a.setTopActivityEligibleForOrientationOverride(true);
+            });
+
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_UNSPECIFIED,
+                    /* expected */ SCREEN_ORIENTATION_PORTRAIT);
+        });
+    }
+
+    @Test
+    public void testOverrideOrientationIfNeeded_userFullscreenOverride_returnsUser() {
+        runTestScenarioWithActivity((robot) -> {
+            robot.applyOnActivity((a) -> {
+                a.setShouldApplyUserFullscreenOverride(true);
+                a.setIgnoreOrientationRequest(true);
+            });
+
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_UNSPECIFIED,
+                    /* expected */ SCREEN_ORIENTATION_USER);
+        });
+    }
+
+    @Test
+    public void testOverrideOrientationIfNeeded_fullscreenOverride_cameraActivity_unchanged() {
+        runTestScenario((robot) -> {
+            robot.applyOnConf((c) -> {
+                c.enableCameraCompatTreatment(true);
+                c.enableCameraCompatTreatmentAtBuildTime(true);
+            });
+            robot.applyOnActivity((a) -> {
+                a.createActivityWithComponentInNewTaskAndDisplay();
+                a.setTopActivityCameraActive(false);
+            });
+
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
+                    /* expected */ SCREEN_ORIENTATION_PORTRAIT);
+        });
+    }
+
+    @Test
+    public void testOverrideOrientationIfNeeded_respectOrientationRequestOverUserFullScreen() {
+        runTestScenarioWithActivity((robot) -> {
+            robot.applyOnActivity((a) -> {
+                a.setShouldApplyUserFullscreenOverride(true);
+                a.setIgnoreOrientationRequest(false);
+            });
+
+            robot.checkOverrideOrientationIsNot(/* candidate */ SCREEN_ORIENTATION_UNSPECIFIED,
+                    /* notExpected */ SCREEN_ORIENTATION_USER);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT, OVERRIDE_ANY_ORIENTATION})
+    public void testOverrideOrientationIfNeeded_userFullScreenOverrideOverSystem_returnsUser() {
+        runTestScenarioWithActivity((robot) -> {
+            robot.applyOnActivity((a) -> {
+                a.setShouldApplyUserFullscreenOverride(true);
+                a.setIgnoreOrientationRequest(true);
+            });
+
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
+                    /* expected */ SCREEN_ORIENTATION_USER);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT, OVERRIDE_ANY_ORIENTATION})
+    public void testOverrideOrientationIfNeeded_respectOrientationReqOverUserFullScreenAndSystem() {
+        runTestScenarioWithActivity((robot) -> {
+            robot.applyOnActivity((a) -> {
+                a.setShouldApplyUserFullscreenOverride(true);
+                a.setIgnoreOrientationRequest(false);
+            });
+            robot.checkOverrideOrientationIsNot(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
+                    /* notExpected */ SCREEN_ORIENTATION_USER);
+        });
+    }
+
+    @Test
+    public void testOverrideOrientationIfNeeded_userFullScreenOverrideDisabled_returnsUnchanged() {
+        runTestScenarioWithActivity((robot) -> {
+            robot.activity().setShouldApplyUserFullscreenOverride(false);
+
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_PORTRAIT,
+                    /* expected */ SCREEN_ORIENTATION_PORTRAIT);
+        });
+    }
+
+    @Test
+    public void testOverrideOrientationIfNeeded_userAspectRatioApplied_unspecifiedOverridden() {
+        runTestScenarioWithActivity((robot) -> {
+            robot.activity().setShouldApplyUserMinAspectRatioOverride(true);
+
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_UNSPECIFIED,
+                    /* expected */ SCREEN_ORIENTATION_PORTRAIT);
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_LOCKED,
+                    /* expected */ SCREEN_ORIENTATION_PORTRAIT);
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_LANDSCAPE,
+                    /* expected */ SCREEN_ORIENTATION_LANDSCAPE);
+        });
+    }
+
+    @Test
+    public void testOverrideOrientationIfNeeded_userAspectRatioNotApplied_isUnchanged() {
+        runTestScenarioWithActivity((robot) -> {
+            robot.activity().setShouldApplyUserFullscreenOverride(false);
+
+            robot.checkOverrideOrientation(/* candidate */ SCREEN_ORIENTATION_UNSPECIFIED,
+                    /* expected */ SCREEN_ORIENTATION_UNSPECIFIED);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
+    public void testShouldIgnoreRequestedOrientation_activityRelaunching_returnsTrue() {
+        runTestScenario((robot) -> {
+            robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+            robot.activity().createActivityWithComponent();
+            robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
+
+            robot.checkShouldIgnoreRequestedOrientation(/* expected */ true,
+                    /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
+    public void testShouldIgnoreRequestedOrientation_cameraCompatTreatment_returnsTrue() {
+        runTestScenario((robot) -> {
+            robot.applyOnConf((c) -> {
+                c.enableCameraCompatTreatment(true);
+                c.enableCameraCompatTreatmentAtBuildTime(true);
+                c.enablePolicyForIgnoringRequestedOrientation(true);
+            });
+            robot.applyOnActivity((a) -> {
+                a.createActivityWithComponentInNewTask();
+                a.enableTreatmentForTopActivity(true);
+            });
+            robot.prepareRelaunchingAfterRequestedOrientationChanged(false);
+
+            robot.checkShouldIgnoreRequestedOrientation(/* expected */ true,
+                    /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
+        });
+    }
+
+    @Test
+    public void testShouldIgnoreRequestedOrientation_overrideDisabled_returnsFalse() {
+        runTestScenario((robot) -> {
+            robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+
+            robot.activity().createActivityWithComponent();
+            robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
+
+            robot.checkShouldIgnoreRequestedOrientation(/* expected */ false,
+                    /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
+        });
+    }
+
+    @Test
+    public void testShouldIgnoreRequestedOrientation_propertyIsTrue_returnsTrue() {
+        runTestScenario((robot) -> {
+            robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+            robot.prop().enable(PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION);
+
+            robot.activity().createActivityWithComponent();
+            robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
+
+            robot.checkShouldIgnoreRequestedOrientation(/* expected */ true,
+                    /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
+    public void testShouldIgnoreRequestedOrientation_propertyIsFalseAndOverride_returnsFalse()
+            throws Exception {
+        runTestScenario((robot) -> {
+            robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+            robot.prop().disable(PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION);
+
+            robot.activity().createActivityWithComponent();
+            robot.prepareRelaunchingAfterRequestedOrientationChanged(true);
+
+            robot.checkShouldIgnoreRequestedOrientation(/* expected */ false,
+                    /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
+        });
+    }
+
+    @Test
+    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
+    public void testShouldIgnoreRequestedOrientation_flagIsDisabled_returnsFalse() {
+        runTestScenario((robot) -> {
+            robot.conf().enablePolicyForIgnoringRequestedOrientation(true);
+            robot.applyOnActivity((a) -> {
+                a.createActivityWithComponent();
+                a.setLetterboxedForFixedOrientationAndAspectRatio(false);
+            });
+
+            robot.checkShouldIgnoreRequestedOrientation(/* expected */ false,
+                    /* requestedOrientation */ SCREEN_ORIENTATION_UNSPECIFIED);
+        });
+    }
+
+
+    /**
+     * Runs a test scenario with an existing activity providing a Robot.
+     */
+    void runTestScenarioWithActivity(@NonNull Consumer<OrientationPolicyRobotTest> consumer) {
+        runTestScenario(/* withActivity */ true, consumer);
+    }
+
+    /**
+     * Runs a test scenario without an existing activity providing a Robot.
+     */
+    void runTestScenario(@NonNull Consumer<OrientationPolicyRobotTest> consumer) {
+        runTestScenario(/* withActivity */ false, consumer);
+    }
+
+    /**
+     * Runs a test scenario providing a Robot.
+     */
+    void runTestScenario(boolean withActivity,
+                         @NonNull Consumer<OrientationPolicyRobotTest> consumer) {
+        spyOn(mWm.mLetterboxConfiguration);
+        final OrientationPolicyRobotTest robot =
+                new OrientationPolicyRobotTest(mWm, mAtm, mSupervisor, withActivity);
+        consumer.accept(robot);
+    }
+
+    private static class OrientationPolicyRobotTest extends AppCompatRobotBase{
+
+        private final WindowManagerService mWm;
+
+        OrientationPolicyRobotTest(@NonNull WindowManagerService wm,
+                                   @NonNull ActivityTaskManagerService atm,
+                                   @NonNull ActivityTaskSupervisor supervisor,
+                                   boolean withActivity) {
+            super(wm, atm, supervisor);
+            mWm = wm;
+            spyOn(mWm);
+            if (withActivity) {
+                activity().createActivityWithComponent();
+            }
+        }
+
+        void prepareRelaunchingAfterRequestedOrientationChanged(boolean enabled) {
+            getTopOrientationOverrides().setRelaunchingAfterRequestedOrientationChanged(enabled);
+        }
+
+        int overrideOrientationIfNeeded(@ActivityInfo.ScreenOrientation int candidate) {
+            return activity().top().mAppCompatController.getOrientationPolicy()
+                    .overrideOrientationIfNeeded(candidate);
+        }
+
+        void checkOrientationRequestMapped() {
+            verify(mWm).mapOrientationRequest(SCREEN_ORIENTATION_PORTRAIT);
+        }
+
+        void checkOverrideOrientation(@ActivityInfo.ScreenOrientation int candidate,
+                                      @ActivityInfo.ScreenOrientation int expected) {
+            assertEquals(expected, overrideOrientationIfNeeded(candidate));
+        }
+
+        void checkOverrideOrientationIsNot(@ActivityInfo.ScreenOrientation int candidate,
+                                           @ActivityInfo.ScreenOrientation int notExpected) {
+            Assert.assertNotEquals(notExpected, overrideOrientationIfNeeded(candidate));
+        }
+
+        void checkShouldIgnoreRequestedOrientation(boolean expected,
+                @Configuration.Orientation int requestedOrientation) {
+            assertEquals(expected, getTopAppCompatOrientationPolicy()
+                    .shouldIgnoreRequestedOrientation(requestedOrientation));
+        }
+
+        private AppCompatOrientationOverrides getTopOrientationOverrides() {
+            return activity().top().mAppCompatController.getAppCompatOverrides()
+                    .getAppCompatOrientationOverrides();
+        }
+
+        private AppCompatOrientationPolicy getTopAppCompatOrientationPolicy() {
+            return activity().top().mAppCompatController.getOrientationPolicy();
+        }
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatRobotBase.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatRobotBase.java
new file mode 100644
index 0000000..de16e38
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatRobotBase.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 androidx.annotation.NonNull;
+
+import java.util.function.Consumer;
+
+/**
+ * Base class for the Robots related to App Compat tests.
+ */
+abstract class AppCompatRobotBase {
+
+    private static final int DEFAULT_DISPLAY_WIDTH = 1000;
+    private static final int DEFAULT_DISPLAY_HEIGHT = 2000;
+
+    @NonNull
+    private final AppCompatActivityRobot mActivityRobot;
+    @NonNull
+    private final AppCompatLetterboxConfigurationRobot mConfigurationRobot;
+    @NonNull
+    private final AppCompatComponentPropRobot mOptPropRobot;
+
+    AppCompatRobotBase(@NonNull WindowManagerService wm,
+            @NonNull ActivityTaskManagerService atm,
+            @NonNull ActivityTaskSupervisor supervisor,
+            int displayWidth, int displayHeight) {
+        mActivityRobot = new AppCompatActivityRobot(wm, atm, supervisor,
+                displayWidth, displayHeight);
+        mConfigurationRobot =
+                new AppCompatLetterboxConfigurationRobot(wm.mLetterboxConfiguration);
+        mOptPropRobot = new AppCompatComponentPropRobot(wm);
+    }
+
+    AppCompatRobotBase(@NonNull WindowManagerService wm,
+            @NonNull ActivityTaskManagerService atm,
+            @NonNull ActivityTaskSupervisor supervisor) {
+        this(wm, atm, supervisor, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
+    }
+
+    @NonNull
+    AppCompatLetterboxConfigurationRobot conf() {
+        return mConfigurationRobot;
+    }
+
+    @NonNull
+    void applyOnConf(@NonNull Consumer<AppCompatLetterboxConfigurationRobot> consumer) {
+        consumer.accept(mConfigurationRobot);
+    }
+
+    @NonNull
+    AppCompatActivityRobot activity() {
+        return mActivityRobot;
+    }
+
+    @NonNull
+    void applyOnActivity(@NonNull Consumer<AppCompatActivityRobot> consumer) {
+        consumer.accept(mActivityRobot);
+    }
+
+    @NonNull
+    AppCompatComponentPropRobot prop() {
+        return mOptPropRobot;
+    }
+
+    @NonNull
+    void applyOnProp(@NonNull Consumer<AppCompatComponentPropRobot> consumer) {
+        consumer.accept(mOptPropRobot);
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppCompatTransparentActivityRobot.java b/services/tests/wmtests/src/com/android/server/wm/AppCompatTransparentActivityRobot.java
new file mode 100644
index 0000000..3cfbb9e
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppCompatTransparentActivityRobot.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.app.WindowConfiguration;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import org.junit.Assert;
+
+import java.util.function.Consumer;
+
+/**
+ * Robot implementation for {@link ActivityRecord} when dealing with transparent activities.
+ */
+class AppCompatTransparentActivityRobot {
+
+    @Nullable
+    private WindowConfiguration mTopActivityWindowConfiguration;
+
+    @NonNull
+    private final AppCompatActivityRobot mActivityRobot;
+
+    AppCompatTransparentActivityRobot(@NonNull AppCompatActivityRobot activityRobot) {
+        mActivityRobot = activityRobot;
+    }
+
+    @NonNull
+    AppCompatActivityRobot activity() {
+        return mActivityRobot;
+    }
+
+    @NonNull
+    void applyOnActivity(@NonNull Consumer<AppCompatActivityRobot> consumer) {
+        consumer.accept(mActivityRobot);
+    }
+
+    void launchTransparentActivity() {
+        mActivityRobot.launchActivity(/*minAspectRatio */ -1, /* maxAspectRatio */ -1,
+                SCREEN_ORIENTATION_PORTRAIT, /* transparent */ true,
+                /* withComponent */ false, /* addToTask */ false);
+    }
+
+    void launchTransparentActivityInTask() {
+        mActivityRobot.launchActivity(/*minAspectRatio */ -1,
+                /* maxAspectRatio */ -1, SCREEN_ORIENTATION_PORTRAIT, /* transparent */ true,
+                /* withComponent */ false, /* addToTask */true);
+    }
+
+    void launchOpaqueActivityInTask() {
+        mActivityRobot.launchActivity(/*minAspectRatio */ -1,
+                /* maxAspectRatio */ -1, SCREEN_ORIENTATION_PORTRAIT, /* transparent */ false,
+                /* withComponent */ false, /* addToTask */true);
+    }
+
+    void forceChangeInTopActivityConfiguration() {
+        activity().applyToTopActivity((topActivity) -> {
+            final Configuration requestedConfig =
+                    topActivity.getRequestedOverrideConfiguration();
+            mTopActivityWindowConfiguration = requestedConfig.windowConfiguration;
+            mTopActivityWindowConfiguration.setActivityType(ACTIVITY_TYPE_STANDARD);
+            mTopActivityWindowConfiguration.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+            mTopActivityWindowConfiguration.setAlwaysOnTop(true);
+            topActivity.onRequestedOverrideConfigurationChanged(requestedConfig);
+        });
+    }
+
+    void checkTopActivityConfigurationConfiguration() {
+        activity().applyToTopActivity((topActivity) -> {
+            // The original override of WindowConfiguration should keep.
+            assertEquals(ACTIVITY_TYPE_STANDARD, topActivity.getActivityType());
+            assertEquals(WINDOWING_MODE_MULTI_WINDOW,
+                    mTopActivityWindowConfiguration.getWindowingMode());
+            assertTrue(mTopActivityWindowConfiguration.isAlwaysOnTop());
+            // Unless display is going to be rotated, it should always inherit from parent.
+            assertEquals(ROTATION_UNDEFINED,
+                    mTopActivityWindowConfiguration.getDisplayRotation());
+        });
+    }
+
+    void checkTopActivityTransparentPolicyStateIsRunning(boolean running) {
+        assertEquals(running,
+                activity().top().mAppCompatController.getTransparentPolicy().isRunning());
+    }
+
+    void checkTopActivityTransparentPolicyStartInvoked() {
+        activity().applyToTopActivity((topActivity) -> {
+            verify(topActivity.mAppCompatController.getTransparentPolicy()).start();
+        });
+    }
+
+    void checkTopActivityTransparentPolicyStartNotInvoked() {
+        verify(activity().top().mAppCompatController.getTransparentPolicy(), never()).start();
+    }
+
+    void checkTopActivityTransparentPolicyStopInvoked() {
+        verify(activity().top().mAppCompatController.getTransparentPolicy()).stop();
+    }
+
+    void checkTopActivityTransparentPolicyStopNotInvoked() {
+        verify(activity().top().mAppCompatController.getTransparentPolicy(), never()).stop();
+    }
+
+    void checkTopActivityHasInheritedBoundsFrom(int fromTop) {
+        final ActivityRecord topActivity = activity().top();
+        final ActivityRecord otherActivity = activity().getFromTop(/* fromTop */ fromTop);
+        final Rect opaqueBounds = otherActivity.getConfiguration().windowConfiguration
+                .getBounds();
+        final Rect translucentRequestedBounds = topActivity.getRequestedOverrideBounds();
+        Assert.assertEquals(opaqueBounds, translucentRequestedBounds);
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
index a39a1a8..63c14b9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -30,6 +30,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.ActivityRecord.State.STOPPED;
 
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
@@ -158,7 +159,7 @@
 
         // reset drawing status to test translucent activity
         backNavigationInfo.onBackNavigationFinished(false);
-        mBackNavigationController.clearBackAnimations();
+        mBackNavigationController.clearBackAnimations(true);
         final ActivityRecord topActivity = topTask.getTopMostActivity();
         makeWindowVisibleAndDrawn(topActivity.findMainWindow());
         // simulate translucent
@@ -169,7 +170,8 @@
 
         // reset drawing status to test if previous task is translucent activity
         backNavigationInfo.onBackNavigationFinished(false);
-        mBackNavigationController.clearBackAnimations();
+        mBackNavigationController.clearBackAnimations(true);
+        makeWindowVisibleAndDrawn(topActivity.findMainWindow());
         // simulate translucent
         recordA.setOccludesParent(false);
         backNavigationInfo = startBackNavigation();
@@ -180,7 +182,7 @@
         topActivity.setOccludesParent(true);
         recordA.setOccludesParent(true);
         backNavigationInfo.onBackNavigationFinished(false);
-        mBackNavigationController.clearBackAnimations();
+        mBackNavigationController.clearBackAnimations(true);
         makeWindowVisibleAndDrawn(topActivity.findMainWindow());
         setupKeyguardOccluded();
         backNavigationInfo = startBackNavigation();
@@ -188,7 +190,7 @@
                 .isEqualTo(typeToString(BackNavigationInfo.TYPE_CALLBACK));
 
         backNavigationInfo.onBackNavigationFinished(false);
-        mBackNavigationController.clearBackAnimations();
+        mBackNavigationController.clearBackAnimations(true);
         doReturn(true).when(recordA).canShowWhenLocked();
         backNavigationInfo = startBackNavigation();
         assertThat(typeToString(backNavigationInfo.getType()))
@@ -245,8 +247,9 @@
         assertTrue("Animation scheduled", backNavigationInfo.isPrepareRemoteAnimation());
 
         // reset drawing status
+        testCase.recordBack.setState(STOPPED, "stopped");
         backNavigationInfo.onBackNavigationFinished(false);
-        mBackNavigationController.clearBackAnimations();
+        mBackNavigationController.clearBackAnimations(true);
         makeWindowVisibleAndDrawn(testCase.recordFront.findMainWindow());
         setupKeyguardOccluded();
         backNavigationInfo = startBackNavigation();
@@ -255,7 +258,7 @@
 
         // reset drawing status, test if top activity is translucent
         backNavigationInfo.onBackNavigationFinished(false);
-        mBackNavigationController.clearBackAnimations();
+        mBackNavigationController.clearBackAnimations(true);
         makeWindowVisibleAndDrawn(testCase.recordFront.findMainWindow());
         // simulate translucent
         testCase.recordFront.setOccludesParent(false);
@@ -266,7 +269,7 @@
 
         // reset drawing status, test if bottom activity is translucent
         backNavigationInfo.onBackNavigationFinished(false);
-        mBackNavigationController.clearBackAnimations();
+        mBackNavigationController.clearBackAnimations(true);
         makeWindowVisibleAndDrawn(testCase.recordBack.findMainWindow());
         // simulate translucent
         testCase.recordBack.setOccludesParent(false);
@@ -277,7 +280,7 @@
 
         // reset drawing status, test canShowWhenLocked
         backNavigationInfo.onBackNavigationFinished(false);
-        mBackNavigationController.clearBackAnimations();
+        mBackNavigationController.clearBackAnimations(true);
         doReturn(true).when(testCase.recordBack).canShowWhenLocked();
         backNavigationInfo = startBackNavigation();
         assertThat(typeToString(backNavigationInfo.getType()))
@@ -480,7 +483,10 @@
                 .isEqualTo(typeToString(BackNavigationInfo.TYPE_RETURN_TO_HOME));
 
         backNavigationInfo.onBackNavigationFinished(false);
-        mBackNavigationController.clearBackAnimations();
+        mBackNavigationController.clearBackAnimations(true);
+
+        final WindowState window = topTask.getTopVisibleAppMainWindow();
+        makeWindowVisibleAndDrawn(window);
         setupKeyguardOccluded();
         backNavigationInfo = startBackNavigation();
         assertThat(typeToString(backNavigationInfo.getType()))
@@ -550,7 +556,7 @@
         }).when(appWindow.mSession).setOnBackInvokedCallbackInfo(eq(appWindow.mClient), any());
 
         addToWindowMap(appWindow, true);
-        dispatcher.attachToWindow(appWindow.mSession, appWindow.mClient, null);
+        dispatcher.attachToWindow(appWindow.mSession, appWindow.mClient, null, null);
 
 
         OnBackInvokedCallback appCallback = createBackCallback(appLatch);
@@ -840,7 +846,7 @@
         toHomeBuilder.build();
         verify(mAtm.mTaskOrganizerController, never()).addWindowlessStartingSurface(
                 any(), any(), any(), any(), any(), any());
-        animationHandler.clearBackAnimateTarget();
+        animationHandler.clearBackAnimateTarget(true);
         openActivities.clear();
 
         // Back to ACTIVITY and TASK have the same logic, just with different target.
@@ -937,6 +943,7 @@
         testCase.recordFront = record2;
         testCase.windowBack = window1;
         testCase.windowFront = window2;
+        record1.setState(STOPPED, "stopped");
         return testCase;
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java
index b3f1502..564c29f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java
@@ -245,8 +245,8 @@
             throws Exception {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
 
-        doReturn(false).when(
-                mActivity.mLetterboxUiController).shouldRefreshActivityForCameraCompat();
+        doReturn(false).when(mActivity.mAppCompatController.getAppCompatCameraOverrides())
+                .shouldRefreshActivityForCameraCompat();
 
         mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
         callOnActivityConfigurationChanging(mActivity);
@@ -271,7 +271,7 @@
     public void testOnActivityConfigurationChanging_cycleThroughStopDisabledForApp()
             throws Exception {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
-        doReturn(true).when(mActivity.mLetterboxUiController)
+        doReturn(true).when(mActivity.mAppCompatController.getAppCompatCameraOverrides())
                 .shouldRefreshActivityViaPauseForCameraCompat();
 
         mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
@@ -305,6 +305,7 @@
                 .build();
 
         spyOn(mActivity.mLetterboxUiController);
+        spyOn(mActivity.mAppCompatController.getAppCompatCameraOverrides());
         spyOn(mActivity.info);
 
         doReturn(mActivity).when(mDisplayContent).topRunningActivity(anyBoolean());
@@ -315,12 +316,14 @@
 
     private void assertInCameraCompatMode() {
         assertNotEquals(CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE,
-                mActivity.mLetterboxUiController.getFreeformCameraCompatMode());
+                mActivity.mAppCompatController.getAppCompatCameraOverrides()
+                        .getFreeformCameraCompatMode());
     }
 
     private void assertNotInCameraCompatMode() {
         assertEquals(CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE,
-                mActivity.mLetterboxUiController.getFreeformCameraCompatMode());
+                mActivity.mAppCompatController.getAppCompatCameraOverrides()
+                        .getFreeformCameraCompatMode());
     }
 
     private void assertActivityRefreshRequested(boolean refreshRequested) throws Exception {
@@ -329,8 +332,8 @@
 
     private void assertActivityRefreshRequested(boolean refreshRequested,
             boolean cycleThroughStop) throws Exception {
-        verify(mActivity.mLetterboxUiController, times(refreshRequested ? 1 : 0))
-                .setIsRefreshRequested(true);
+        verify(mActivity.mAppCompatController.getAppCompatCameraOverrides(),
+                times(refreshRequested ? 1 : 0)).setIsRefreshRequested(true);
 
         final RefreshCallbackItem refreshCallbackItem = RefreshCallbackItem.obtain(mActivity.token,
                 cycleThroughStop ? ON_STOP : ON_PAUSE);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java b/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java
index b21eca7..2bda950 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ClientLifecycleManagerTests.java
@@ -19,7 +19,6 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
-import static com.android.window.flags.Flags.FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
@@ -106,31 +105,7 @@
     }
 
     @Test
-    public void testScheduleTransactionItem_notBundle() throws RemoteException {
-        mSetFlagsRule.disableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
-        // Use non binder client to get non-recycled ClientTransaction.
-        mLifecycleManager.scheduleTransactionItem(mNonBinderClient, mTransactionItem);
-
-        verify(mLifecycleManager).scheduleTransaction(mTransactionCaptor.capture());
-        ClientTransaction transaction = mTransactionCaptor.getValue();
-        assertEquals(1, transaction.getCallbacks().size());
-        assertEquals(mTransactionItem, transaction.getCallbacks().get(0));
-        assertNull(transaction.getLifecycleStateRequest());
-        assertNull(transaction.getTransactionItems());
-
-        clearInvocations(mLifecycleManager);
-        mLifecycleManager.scheduleTransactionItem(mNonBinderClient, mLifecycleItem);
-
-        verify(mLifecycleManager).scheduleTransaction(mTransactionCaptor.capture());
-        transaction = mTransactionCaptor.getValue();
-        assertNull(transaction.getCallbacks());
-        assertEquals(mLifecycleItem, transaction.getLifecycleStateRequest());
-    }
-
-    @Test
     public void testScheduleTransactionItem() throws RemoteException {
-        mSetFlagsRule.enableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
         spyOn(mWms.mWindowPlacerLocked);
         doReturn(true).when(mWms.mWindowPlacerLocked).isTraversalScheduled();
 
@@ -176,23 +151,7 @@
     }
 
     @Test
-    public void testScheduleTransactionAndLifecycleItems_notBundle() throws RemoteException {
-        mSetFlagsRule.disableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
-        // Use non binder client to get non-recycled ClientTransaction.
-        mLifecycleManager.scheduleTransactionAndLifecycleItems(mNonBinderClient, mTransactionItem,
-                mLifecycleItem);
-
-        verify(mLifecycleManager).scheduleTransaction(mTransactionCaptor.capture());
-        final ClientTransaction transaction = mTransactionCaptor.getValue();
-        assertEquals(1, transaction.getCallbacks().size());
-        assertEquals(mTransactionItem, transaction.getCallbacks().get(0));
-        assertEquals(mLifecycleItem, transaction.getLifecycleStateRequest());
-    }
-
-    @Test
     public void testScheduleTransactionAndLifecycleItems() throws RemoteException {
-        mSetFlagsRule.enableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
         spyOn(mWms.mWindowPlacerLocked);
         doReturn(true).when(mWms.mWindowPlacerLocked).isTraversalScheduled();
 
@@ -216,7 +175,6 @@
     @Test
     public void testScheduleTransactionAndLifecycleItems_shouldDispatchImmediately()
             throws RemoteException {
-        mSetFlagsRule.enableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
         spyOn(mWms.mWindowPlacerLocked);
         doReturn(true).when(mWms.mWindowPlacerLocked).isTraversalScheduled();
 
@@ -230,8 +188,6 @@
 
     @Test
     public void testDispatchPendingTransactions() throws RemoteException {
-        mSetFlagsRule.enableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
         mLifecycleManager.mPendingTransactions.put(mClientBinder, mTransaction);
 
         mLifecycleManager.dispatchPendingTransactions();
@@ -243,7 +199,6 @@
 
     @Test
     public void testLayoutDeferred() throws RemoteException {
-        mSetFlagsRule.enableFlags(FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
         spyOn(mWms.mWindowPlacerLocked);
         doReturn(false).when(mWms.mWindowPlacerLocked).isInLayout();
         doReturn(false).when(mWms.mWindowPlacerLocked).isTraversalScheduled();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java
index 5125594..36861fa 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DeviceStateControllerTests.java
@@ -16,6 +16,15 @@
 
 package com.android.server.wm;
 
+import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FEATURE_REAR_DISPLAY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN;
+import static android.hardware.devicestate.DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN;
+import static android.hardware.devicestate.feature.flags.Flags.FLAG_DEVICE_STATE_PROPERTY_MIGRATION;
+
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
 
@@ -24,8 +33,11 @@
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.hardware.devicestate.DeviceState;
 import android.hardware.devicestate.DeviceStateManager;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.util.Pair;
 
 import androidx.test.filters.SmallTest;
@@ -37,6 +49,8 @@
 import org.junit.Before;
 import org.junit.Test;
 
+import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
@@ -79,39 +93,67 @@
     @Test
     public void testInitialization() {
         initialize(true /* supportFold */, true /* supportHalfFolded */);
-        mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
+        mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates.get(0).getIdentifier());
         assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
     }
 
     @Test
     public void testInitializationWithNoFoldSupport() {
         initialize(false /* supportFold */, false /* supportHalfFolded */);
-        mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates[0]);
+        mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates.get(0).getIdentifier());
         // Note that the folded state is ignored.
         assertEquals(DeviceStateController.DeviceState.UNKNOWN, mCurrentState);
     }
 
     @Test
-    public void testWithFoldSupported() {
+    @RequiresFlagsDisabled(FLAG_DEVICE_STATE_PROPERTY_MIGRATION)
+    public void testWithFoldSupported_withOverlayConfigValues() {
         initialize(true /* supportFold */, false /* supportHalfFolded */);
-        mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
+        mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates.get(0).getIdentifier());
         assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
-        mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates[0]);
+        mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates.get(0).getIdentifier());
         assertEquals(DeviceStateController.DeviceState.FOLDED, mCurrentState);
-        mTarget.onDeviceStateReceivedByDisplayManager(mHalfFoldedStates[0]);
+        mTarget.onDeviceStateReceivedByDisplayManager(mHalfFoldedStates.get(0).getIdentifier());
         assertEquals(DeviceStateController.DeviceState.UNKNOWN, mCurrentState); // Ignored
     }
 
     @Test
-    public void testWithHalfFoldSupported() {
-        initialize(true /* supportFold */, true /* supportHalfFolded */);
-        mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
+    @RequiresFlagsEnabled(FLAG_DEVICE_STATE_PROPERTY_MIGRATION)
+    public void testWithFoldSupported_withDeviceStateManagerPropertyAPI() {
+        initialize(true /* supportFold */, false /* supportHalfFolded */);
+        mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates.get(0).getIdentifier());
         assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
-        mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates[0]);
+        mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates.get(0).getIdentifier());
         assertEquals(DeviceStateController.DeviceState.FOLDED, mCurrentState);
-        mTarget.onDeviceStateReceivedByDisplayManager(mHalfFoldedStates[0]);
+        mTarget.onDeviceStateReceivedByDisplayManager(mHalfFoldedStates.get(0).getIdentifier());
+        assertEquals(DeviceStateController.DeviceState.UNKNOWN, mCurrentState); // Ignored
+    }
+
+    @Test
+    @RequiresFlagsDisabled(FLAG_DEVICE_STATE_PROPERTY_MIGRATION)
+    public void testWithHalfFoldSupported_withOverlayConfigValue() {
+        initialize(true /* supportFold */, true /* supportHalfFolded */);
+        mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates.get(0).getIdentifier());
+        assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
+        mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates.get(0).getIdentifier());
+        assertEquals(DeviceStateController.DeviceState.FOLDED, mCurrentState);
+        mTarget.onDeviceStateReceivedByDisplayManager(mHalfFoldedStates.get(0).getIdentifier());
         assertEquals(DeviceStateController.DeviceState.HALF_FOLDED, mCurrentState);
-        mTarget.onDeviceStateReceivedByDisplayManager(mConcurrentDisplayState);
+        mTarget.onDeviceStateReceivedByDisplayManager(mConcurrentDisplayState.getIdentifier());
+        assertEquals(DeviceStateController.DeviceState.CONCURRENT, mCurrentState);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(FLAG_DEVICE_STATE_PROPERTY_MIGRATION)
+    public void testWithHalfFoldSupported_withDeviceStateManagerPropertyApi() {
+        initialize(true /* supportFold */, true /* supportHalfFolded */);
+        mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates.get(0).getIdentifier());
+        assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
+        mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates.get(0).getIdentifier());
+        assertEquals(DeviceStateController.DeviceState.FOLDED, mCurrentState);
+        mTarget.onDeviceStateReceivedByDisplayManager(mHalfFoldedStates.get(0).getIdentifier());
+        assertEquals(DeviceStateController.DeviceState.HALF_FOLDED, mCurrentState);
+        mTarget.onDeviceStateReceivedByDisplayManager(mConcurrentDisplayState.getIdentifier());
         assertEquals(DeviceStateController.DeviceState.CONCURRENT, mCurrentState);
     }
 
@@ -121,16 +163,18 @@
         assertEquals(1, mTarget.mDeviceStateCallbacks.size());
         assertTrue(mTarget.mDeviceStateCallbacks.containsKey(mDelegate));
 
-        mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
+        mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates.get(0).getIdentifier());
         assertEquals(DeviceStateController.DeviceState.OPEN, mCurrentState);
-        mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates[0]);
+        mTarget.onDeviceStateReceivedByDisplayManager(mFoldedStates.get(0).getIdentifier());
         assertEquals(DeviceStateController.DeviceState.FOLDED, mCurrentState);
 
         // The callback should not receive state change when it is unregistered.
         mTarget.unregisterDeviceStateCallback(mDelegate);
         assertTrue(mTarget.mDeviceStateCallbacks.isEmpty());
-        mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates[0]);
-        assertEquals(DeviceStateController.DeviceState.FOLDED /* unchanged */, mCurrentState);
+
+        mTarget.onDeviceStateReceivedByDisplayManager(mOpenDeviceStates.get(0).getIdentifier());
+        assertEquals(DeviceStateController.DeviceState.FOLDED /* unchanged */,
+                mCurrentState);
     }
 
     @Test
@@ -151,16 +195,50 @@
         assertEquals(mExecutor, entries.get(0).second);
     }
 
-    private final int[] mFoldedStates = {0};
-    private final int[] mOpenDeviceStates = {1};
-    private final int[] mHalfFoldedStates = {2};
-    private final int[] mRearDisplayStates = {3};
-    private final int mConcurrentDisplayState = 4;
+    private final List<DeviceState> mFoldedStates = new ArrayList<>(
+            List.of(new DeviceState(new DeviceState.Configuration.Builder(0,
+                    "folded").setSystemProperties(new HashSet<>(
+                    List.of(PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY)))
+                    .setPhysicalProperties(new HashSet<>(
+                            List.of(PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED)))
+                    .build())));
+    private final List<DeviceState> mOpenDeviceStates = new ArrayList<>(
+            List.of(new DeviceState(new DeviceState.Configuration.Builder(1,
+                    "open").setSystemProperties(new HashSet<>(
+                            List.of(PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY)))
+                    .setPhysicalProperties(new HashSet<>(
+                            List.of(PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN)))
+                    .build())));
+    private final List<DeviceState> mHalfFoldedStates = new ArrayList<>(
+            List.of(new DeviceState(new DeviceState.Configuration.Builder(2,
+                    "half_folded").setSystemProperties(new HashSet<>(
+                            List.of(PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY)))
+                    .setPhysicalProperties(new HashSet<>(
+                            List.of(PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN)))
+                    .build())));
+    private final List<DeviceState> mRearDisplayStates = new ArrayList<>(
+            List.of(new DeviceState(new DeviceState.Configuration.Builder(3,
+                    "rear_display").setSystemProperties(new HashSet<>(
+                            List.of(PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY,
+                                    PROPERTY_FEATURE_REAR_DISPLAY)))
+                    .setPhysicalProperties(new HashSet<>(
+                            List.of(PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN)))
+                    .build())));
+    private final DeviceState mConcurrentDisplayState = new DeviceState(
+            new DeviceState.Configuration.Builder(4, "concurrent_display")
+                    .setSystemProperties(new HashSet<>(List.of(
+                            PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY,
+                            PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT)))
+                    .setPhysicalProperties(new HashSet<>(List.of(
+                            PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN)))
+                    .build());
 
     private class DeviceStateControllerBuilder {
         private boolean mSupportFold = false;
         private boolean mSupportHalfFold = false;
+
         private Consumer<DeviceStateController.DeviceState> mDelegate;
+        private final List<DeviceState> mDeviceStateList = new ArrayList<>();
 
         DeviceStateControllerBuilder setSupportFold(
                 boolean supportFold, boolean supportHalfFold) {
@@ -179,13 +257,17 @@
             if (enableFold || enableHalfFold) {
                 when(mMockContext.getResources()
                         .getIntArray(R.array.config_openDeviceStates))
-                        .thenReturn(mOpenDeviceStates);
+                        .thenReturn(mapDeviceStateListToIdentifierArray(mOpenDeviceStates));
                 when(mMockContext.getResources()
                         .getIntArray(R.array.config_rearDisplayDeviceStates))
-                        .thenReturn(mRearDisplayStates);
+                        .thenReturn(mapDeviceStateListToIdentifierArray(mRearDisplayStates));
                 when(mMockContext.getResources()
                         .getInteger(R.integer.config_deviceStateConcurrentRearDisplay))
-                        .thenReturn(mConcurrentDisplayState);
+                        .thenReturn(mConcurrentDisplayState.getIdentifier());
+
+                mDeviceStateList.addAll(mOpenDeviceStates);
+                mDeviceStateList.addAll(mRearDisplayStates);
+                mDeviceStateList.add(mConcurrentDisplayState);
             } else {
                 // Match the default value in framework resources
                 when(mMockContext.getResources()
@@ -196,12 +278,14 @@
             if (enableFold) {
                 when(mMockContext.getResources()
                         .getIntArray(R.array.config_foldedDeviceStates))
-                        .thenReturn(mFoldedStates);
+                        .thenReturn(mapDeviceStateListToIdentifierArray(mFoldedStates));
+                mDeviceStateList.addAll(mFoldedStates);
             }
             if (enableHalfFold) {
                 when(mMockContext.getResources()
                         .getIntArray(R.array.config_halfFoldedDeviceStates))
-                        .thenReturn(mHalfFoldedStates);
+                        .thenReturn(mapDeviceStateListToIdentifierArray(mHalfFoldedStates));
+                mDeviceStateList.addAll(mHalfFoldedStates);
             }
         }
 
@@ -210,11 +294,20 @@
             mMockDeviceStateManager = mock(DeviceStateManager.class);
             when(mMockContext.getSystemService(DeviceStateManager.class))
                     .thenReturn(mMockDeviceStateManager);
+            when(mMockDeviceStateManager.getSupportedDeviceStates()).thenReturn(mDeviceStateList);
             Resources mockRes = mock(Resources.class);
             when(mMockContext.getResources()).thenReturn((mockRes));
             mockFold(mSupportFold, mSupportHalfFold);
             mTarget = new DeviceStateController(mMockContext, new WindowManagerGlobalLock());
             mTarget.registerDeviceStateCallback(mDelegate, mExecutor);
         }
+
+        private int[] mapDeviceStateListToIdentifierArray(List<DeviceState> deviceStates) {
+            int[] identifiers = new int[deviceStates.size()];
+            for (int i = 0; i < deviceStates.size(); i++) {
+                identifiers[i] = deviceStates.get(i).getIdentifier();
+            }
+            return identifiers;
+        }
     }
 }
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 6957502..65aaf60 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -117,8 +117,8 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.Presubmit;
 import android.util.ArraySet;
 import android.view.Display;
@@ -1871,6 +1871,46 @@
         assertFalse(recentsActivity.hasFixedRotationTransform());
     }
 
+    @EnableFlags(com.android.window.flags.Flags.FLAG_RESPECT_NON_TOP_VISIBLE_FIXED_ORIENTATION)
+    @Test
+    public void testRespectNonTopVisibleFixedOrientation() {
+        spyOn(mWm.mLetterboxConfiguration);
+        doReturn(false).when(mWm.mLetterboxConfiguration).isTranslucentLetterboxingEnabled();
+        makeDisplayPortrait(mDisplayContent);
+        final ActivityRecord nonTopVisible = new ActivityBuilder(mAtm)
+                .setScreenOrientation(SCREEN_ORIENTATION_PORTRAIT)
+                .setCreateTask(true).build();
+        final ActivityRecord translucentTop = new ActivityBuilder(mAtm)
+                .setScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE)
+                .setTask(nonTopVisible.getTask()).setVisible(false)
+                .setActivityTheme(android.R.style.Theme_Translucent).build();
+        final TestTransitionPlayer player = registerTestTransitionPlayer();
+        mDisplayContent.requestTransitionAndLegacyPrepare(WindowManager.TRANSIT_OPEN, 0);
+        translucentTop.setVisibility(true);
+        mDisplayContent.updateOrientation();
+        assertEquals("Non-top visible activity must be portrait",
+                Configuration.ORIENTATION_PORTRAIT, nonTopVisible.getConfiguration().orientation);
+        assertEquals("Top translucent activity must be landscape",
+                Configuration.ORIENTATION_LANDSCAPE, translucentTop.getConfiguration().orientation);
+
+        player.start();
+        player.finish();
+        assertEquals("Display must be landscape after the transition is finished",
+                Configuration.ORIENTATION_LANDSCAPE,
+                mDisplayContent.getConfiguration().orientation);
+        assertEquals("Non-top visible activity must still be portrait",
+                Configuration.ORIENTATION_PORTRAIT,
+                nonTopVisible.getConfiguration().orientation);
+
+        translucentTop.finishIfPossible("test", false /* oomAdj */);
+        mDisplayContent.updateOrientation();
+        player.start();
+        player.finish();
+        assertEquals("Display must be portrait after closing the translucent activity",
+                Configuration.ORIENTATION_PORTRAIT,
+                mDisplayContent.getConfiguration().orientation);
+    }
+
     @Test
     public void testSecondaryInternalDisplayRotationFollowsDefaultDisplay() {
         // Skip freezing so the unrelated conditions in updateRotationUnchecked won't disturb.
@@ -2832,7 +2872,7 @@
         doReturn(true).when(() ->
                 DesktopModeLaunchParamsModifier.canEnterDesktopMode(any()));
 
-        assertNotNull(createNewDisplay().mCameraCompatFreeformPolicy);
+        assertTrue(createNewDisplay().mAppCompatCameraPolicy.hasCameraCompatFreeformPolicy());
     }
 
     @DisableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
@@ -2841,14 +2881,14 @@
         doReturn(true).when(() ->
                 DesktopModeLaunchParamsModifier.canEnterDesktopMode(any()));
 
-        assertNull(createNewDisplay().mCameraCompatFreeformPolicy);
+        assertFalse(createNewDisplay().mAppCompatCameraPolicy.hasCameraCompatFreeformPolicy());
     }
 
     @EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
     @DisableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
     @Test
     public void desktopWindowingFlagNotEnabled_cameraCompatFreeformPolicyIsNull() {
-        assertNull(createNewDisplay().mCameraCompatFreeformPolicy);
+        assertFalse(createNewDisplay().mAppCompatCameraPolicy.hasCameraCompatFreeformPolicy());
     }
 
     private void removeRootTaskTests(Runnable runnable) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java
index c65371f..d7814ac 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java
@@ -266,7 +266,7 @@
     public void testTreatmentDisabledPerApp_noForceRotationOrRefresh()
             throws Exception {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
-        doReturn(false).when(mActivity.mLetterboxUiController)
+        doReturn(false).when(mActivity.mAppCompatController.getAppCompatCameraOverrides())
                 .shouldForceRotateForCameraCompat();
 
         mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
@@ -468,8 +468,8 @@
             throws Exception {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
 
-        doReturn(false).when(
-                mActivity.mLetterboxUiController).shouldRefreshActivityForCameraCompat();
+        doReturn(false).when(mActivity.mAppCompatController.getAppCompatCameraOverrides())
+                .shouldRefreshActivityForCameraCompat();
 
         mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
         callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ true);
@@ -494,8 +494,9 @@
     public void testOnActivityConfigurationChanging_displayRotationNotChanging_noRefresh()
             throws Exception {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
-        doReturn(false).when(mActivity.mLetterboxUiController)
-                .isCameraCompatSplitScreenAspectRatioAllowed();
+        doReturn(false).when(mActivity
+                        .mAppCompatController.getAppCompatCameraOverrides())
+                            .isCameraCompatSplitScreenAspectRatioAllowed();
 
         mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
         callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ false);
@@ -507,7 +508,7 @@
     public void testOnActivityConfigurationChanging_splitScreenAspectRatioAllowed_refresh()
             throws Exception {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
-        doReturn(true).when(mActivity.mLetterboxUiController)
+        doReturn(true).when(mActivity.mAppCompatController.getAppCompatCameraOverrides())
                 .isCameraCompatSplitScreenAspectRatioAllowed();
 
         mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
@@ -533,7 +534,7 @@
     public void testOnActivityConfigurationChanging_cycleThroughStopDisabledForApp()
             throws Exception {
         configureActivity(SCREEN_ORIENTATION_PORTRAIT);
-        doReturn(true).when(mActivity.mLetterboxUiController)
+        doReturn(true).when(mActivity.mAppCompatController.getAppCompatCameraOverrides())
                 .shouldRefreshActivityViaPauseForCameraCompat();
 
         mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
@@ -597,6 +598,7 @@
 
         spyOn(mActivity.mAtmService.getLifecycleManager());
         spyOn(mActivity.mLetterboxUiController);
+        spyOn(mActivity.mAppCompatController.getAppCompatCameraOverrides());
 
         doReturn(mActivity).when(mDisplayContent).topRunningActivity(anyBoolean());
         doReturn(naturalOrientation).when(mDisplayContent).getNaturalOrientation();
@@ -608,8 +610,8 @@
 
     private void assertActivityRefreshRequested(boolean refreshRequested,
                 boolean cycleThroughStop) throws Exception {
-        verify(mActivity.mLetterboxUiController, times(refreshRequested ? 1 : 0))
-                .setIsRefreshRequested(true);
+        verify(mActivity.mAppCompatController.getAppCompatCameraOverrides(),
+                times(refreshRequested ? 1 : 0)).setIsRefreshRequested(true);
 
         final RefreshCallbackItem refreshCallbackItem = RefreshCallbackItem.obtain(mActivity.token,
                 cycleThroughStop ? ON_STOP : ON_PAUSE);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
index e3a8542..2e488d8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
@@ -1607,6 +1607,7 @@
                     .thenReturn(mMockDeviceStateManager);
 
             mDeviceStateController = mock(DeviceStateController.class);
+            mMockDisplayContent.mAppCompatCameraPolicy = mock(AppCompatCameraPolicy.class);
             mTarget = new TestDisplayRotation(mMockDisplayContent, mMockDisplayAddress,
                     mMockDisplayPolicy, mMockDisplayWindowSettings, mMockContext,
                     mDeviceStateController);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
index 7d9fdd5..3fcf304 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
@@ -24,9 +24,12 @@
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
 import static org.testng.Assert.assertFalse;
 
 import android.annotation.Nullable;
@@ -55,6 +58,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.charset.StandardCharsets;
+import java.util.function.Consumer;
 
 /**
  * Tests for the {@link DisplayWindowSettingsProvider} class.
@@ -128,9 +132,8 @@
         // Update settings with new value, should trigger write to injector.
         DisplayWindowSettingsProvider provider = new DisplayWindowSettingsProvider(
                 mDefaultVendorSettingsStorage, mOverrideSettingsStorage);
-        SettingsEntry overrideSettings = provider.getOverrideSettings(mPrimaryDisplayInfo);
-        overrideSettings.mForcedDensity = 200;
-        provider.updateOverrideSettings(mPrimaryDisplayInfo, overrideSettings);
+        updateOverrideSettings(provider, mPrimaryDisplayInfo,
+                overrideSettings -> overrideSettings.mForcedDensity = 200);
         assertTrue(mOverrideSettingsStorage.wasWriteSuccessful());
 
         // Verify that display identifier was updated.
@@ -167,7 +170,7 @@
     }
 
     @Test
-    public void testReadingDisplaySettingsFromStorage_secondayVendorDisplaySettingsLocation() {
+    public void testReadingDisplaySettingsFromStorage_secondaryVendorDisplaySettingsLocation() {
         final String displayIdentifier = mSecondaryDisplay.getDisplayInfo().uniqueId;
         prepareSecondaryDisplaySettings(displayIdentifier);
 
@@ -216,11 +219,11 @@
         // Write some settings to storage.
         DisplayWindowSettingsProvider provider = new DisplayWindowSettingsProvider(
                 mDefaultVendorSettingsStorage, mOverrideSettingsStorage);
-        SettingsEntry overrideSettings = provider.getOverrideSettings(secondaryDisplayInfo);
-        overrideSettings.mShouldShowSystemDecors = true;
-        overrideSettings.mImePolicy = DISPLAY_IME_POLICY_LOCAL;
-        overrideSettings.mDontMoveToTop = true;
-        provider.updateOverrideSettings(secondaryDisplayInfo, overrideSettings);
+        updateOverrideSettings(provider, secondaryDisplayInfo, overrideSettings -> {
+            overrideSettings.mShouldShowSystemDecors = true;
+            overrideSettings.mImePolicy = DISPLAY_IME_POLICY_LOCAL;
+            overrideSettings.mDontMoveToTop = true;
+        });
         assertTrue(mOverrideSettingsStorage.wasWriteSuccessful());
 
         // Verify that settings were stored correctly.
@@ -235,6 +238,29 @@
     }
 
     @Test
+    public void testWritingDisplaySettingsToStorage_secondaryUserDisplaySettingsLocation() {
+        final DisplayWindowSettingsProvider provider = new DisplayWindowSettingsProvider(
+                mDefaultVendorSettingsStorage, mOverrideSettingsStorage);
+        final DisplayInfo displayInfo = mPrimaryDisplay.getDisplayInfo();
+        final TestStorage secondaryUserOverrideSettingsStorage = new TestStorage();
+        final SettingsEntry expectedSettings = new SettingsEntry();
+        expectedSettings.mForcedDensity = 356;
+
+        // Write some settings to storage from default user.
+        updateOverrideSettings(provider, displayInfo, settings -> settings.mForcedDensity = 356);
+        assertThat(mOverrideSettingsStorage.wasWriteSuccessful()).isTrue();
+
+        // Now switch to secondary user override settings and write some settings.
+        provider.setOverrideSettingsStorage(secondaryUserOverrideSettingsStorage);
+        updateOverrideSettings(provider, displayInfo, settings -> settings.mForcedDensity = 420);
+        assertThat(secondaryUserOverrideSettingsStorage.wasWriteSuccessful()).isTrue();
+
+        // Switch back to primary and assert default user settings remain unchanged.
+        provider.setOverrideSettingsStorage(mOverrideSettingsStorage);
+        assertThat(provider.getOverrideSettings(displayInfo)).isEqualTo(expectedSettings);
+    }
+
+    @Test
     public void testDoNotWriteVirtualDisplaySettingsToStorage() throws Exception {
         final DisplayInfo secondaryDisplayInfo = mSecondaryDisplay.getDisplayInfo();
         secondaryDisplayInfo.type = TYPE_VIRTUAL;
@@ -242,11 +268,11 @@
         // No write to storage on virtual display change.
         final DisplayWindowSettingsProvider provider = new DisplayWindowSettingsProvider(
                 mDefaultVendorSettingsStorage, mOverrideSettingsStorage);
-        final SettingsEntry virtualSettings = provider.getOverrideSettings(secondaryDisplayInfo);
-        virtualSettings.mShouldShowSystemDecors = true;
-        virtualSettings.mImePolicy = DISPLAY_IME_POLICY_LOCAL;
-        virtualSettings.mDontMoveToTop = true;
-        provider.updateOverrideSettings(secondaryDisplayInfo, virtualSettings);
+        updateOverrideSettings(provider, secondaryDisplayInfo, virtualSettings -> {
+            virtualSettings.mShouldShowSystemDecors = true;
+            virtualSettings.mImePolicy = DISPLAY_IME_POLICY_LOCAL;
+            virtualSettings.mDontMoveToTop = true;
+        });
         assertFalse(mOverrideSettingsStorage.wasWriteSuccessful());
     }
 
@@ -263,10 +289,10 @@
         // Write some settings to storage.
         DisplayWindowSettingsProvider provider = new DisplayWindowSettingsProvider(
                 mDefaultVendorSettingsStorage, mOverrideSettingsStorage);
-        SettingsEntry overrideSettings = provider.getOverrideSettings(secondaryDisplayInfo);
-        overrideSettings.mShouldShowSystemDecors = true;
-        overrideSettings.mImePolicy = DISPLAY_IME_POLICY_LOCAL;
-        provider.updateOverrideSettings(secondaryDisplayInfo, overrideSettings);
+        updateOverrideSettings(provider, secondaryDisplayInfo, overrideSettings -> {
+            overrideSettings.mShouldShowSystemDecors = true;
+            overrideSettings.mImePolicy = DISPLAY_IME_POLICY_LOCAL;
+        });
         assertTrue(mOverrideSettingsStorage.wasWriteSuccessful());
 
         // Verify that settings were stored correctly.
@@ -283,16 +309,16 @@
         final DisplayWindowSettingsProvider provider = new DisplayWindowSettingsProvider(
                 mDefaultVendorSettingsStorage, mOverrideSettingsStorage);
         final int initialSize = provider.getOverrideSettingsSize();
-
-        // Size + 1 when query for a new display.
         final DisplayInfo secondaryDisplayInfo = mSecondaryDisplay.getDisplayInfo();
-        final SettingsEntry overrideSettings = provider.getOverrideSettings(secondaryDisplayInfo);
 
-        assertEquals(initialSize + 1, provider.getOverrideSettingsSize());
+        updateOverrideSettings(provider, secondaryDisplayInfo, overrideSettings -> {
+            // Size + 1 when query for a new display.
+            assertEquals(initialSize + 1, provider.getOverrideSettingsSize());
 
-        // When a display is removed, its override Settings is not removed if there is any override.
-        overrideSettings.mShouldShowSystemDecors = true;
-        provider.updateOverrideSettings(secondaryDisplayInfo, overrideSettings);
+            // When a display is removed, its override Settings is not removed if there is any
+            // override.
+            overrideSettings.mShouldShowSystemDecors = true;
+        });
         provider.onDisplayRemoved(secondaryDisplayInfo);
 
         assertEquals(initialSize + 1, provider.getOverrideSettingsSize());
@@ -309,23 +335,53 @@
         final DisplayWindowSettingsProvider provider = new DisplayWindowSettingsProvider(
                 mDefaultVendorSettingsStorage, mOverrideSettingsStorage);
         final int initialSize = provider.getOverrideSettingsSize();
-
-        // Size + 1 when query for a new display.
         final DisplayInfo secondaryDisplayInfo = mSecondaryDisplay.getDisplayInfo();
         secondaryDisplayInfo.type = TYPE_VIRTUAL;
-        final SettingsEntry overrideSettings = provider.getOverrideSettings(secondaryDisplayInfo);
 
-        assertEquals(initialSize + 1, provider.getOverrideSettingsSize());
+        updateOverrideSettings(provider, secondaryDisplayInfo, overrideSettings -> {
+            // Size + 1 when query for a new display.
+            assertEquals(initialSize + 1, provider.getOverrideSettingsSize());
 
-        // When a virtual display is removed, its override Settings is removed even if it has
-        // override.
-        overrideSettings.mShouldShowSystemDecors = true;
-        provider.updateOverrideSettings(secondaryDisplayInfo, overrideSettings);
+            // When a virtual display is removed, its override Settings is removed
+            // even if it has override.
+            overrideSettings.mShouldShowSystemDecors = true;
+        });
         provider.onDisplayRemoved(secondaryDisplayInfo);
 
         assertEquals(initialSize, provider.getOverrideSettingsSize());
     }
 
+    @Test
+    public void testRemovesStaleDisplaySettings() {
+        assumeTrue(com.android.window.flags.Flags.perUserDisplayWindowSettings());
+
+        final DisplayWindowSettingsProvider provider =
+                new DisplayWindowSettingsProvider(mDefaultVendorSettingsStorage,
+                        mOverrideSettingsStorage);
+        final DisplayInfo displayInfo = mSecondaryDisplay.getDisplayInfo();
+        updateOverrideSettings(provider, displayInfo, settings -> settings.mForcedDensity = 356);
+        mRootWindowContainer.removeChild(mSecondaryDisplay);
+
+        provider.removeStaleDisplaySettings(mRootWindowContainer);
+
+        assertThat(mOverrideSettingsStorage.wasWriteSuccessful()).isTrue();
+        assertThat(provider.getOverrideSettingsSize()).isEqualTo(0);
+    }
+
+    /**
+     * Updates the override settings for a specific display.
+     *
+     * @param provider the provider to obtain and update the settings from.
+     * @param displayInfo the information about the display to be updated.
+     * @param modifier a function that modifies the settings for the display.
+     */
+    private static void updateOverrideSettings(DisplayWindowSettingsProvider provider,
+            DisplayInfo displayInfo, Consumer<SettingsEntry> modifier) {
+        final SettingsEntry settings = provider.getOverrideSettings(displayInfo);
+        modifier.accept(settings);
+        provider.updateOverrideSettings(displayInfo, settings);
+    }
+
     /**
      * Prepares display settings and stores in {@link #mOverrideSettingsStorage}. Uses provided
      * display identifier and stores windowingMode=WINDOWING_MODE_PINNED.
diff --git a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
index 7faf2aa..8cdb574 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
@@ -497,7 +497,8 @@
     public void testValidateFlags() {
         final Session session = getTestSession();
         try {
-            session.validateDragFlags(View.DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION);
+            session.validateDragFlags(View.DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION,
+                    0 /* callingUid */);
             fail("Expected failure without permission");
         } catch (SecurityException e) {
             // Expected failure
@@ -510,7 +511,8 @@
                 .checkCallingOrSelfPermission(eq(START_TASKS_FROM_RECENTS));
         final Session session = createTestSession(mAtm);
         try {
-            session.validateDragFlags(View.DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION);
+            session.validateDragFlags(View.DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION,
+                    0 /* callingUid */);
             // Expected pass
         } catch (SecurityException e) {
             fail("Expected no failure with permission");
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
index d2494ff..fbc4c7b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
@@ -172,14 +172,14 @@
     @Test
     public void testSurfaceOrigin_applied() {
         mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000));
-        mLetterbox.applySurfaceChanges(mTransaction);
+        applySurfaceChanges();
         verify(mTransaction).setPosition(mSurfaces.top, -1000, -2000);
     }
 
     @Test
     public void testApplySurfaceChanges_setColor() {
         mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000));
-        mLetterbox.applySurfaceChanges(mTransaction);
+        applySurfaceChanges();
 
         verify(mTransaction).setColor(mSurfaces.top, new float[]{0, 0, 0});
 
@@ -187,7 +187,7 @@
 
         assertTrue(mLetterbox.needsApplySurfaceChanges());
 
-        mLetterbox.applySurfaceChanges(mTransaction);
+        applySurfaceChanges();
 
         verify(mTransaction).setColor(mSurfaces.top, new float[]{0, 1, 0});
     }
@@ -195,7 +195,7 @@
     @Test
     public void testNeedsApplySurfaceChanges_wallpaperBackgroundRequested() {
         mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000));
-        mLetterbox.applySurfaceChanges(mTransaction);
+        applySurfaceChanges();
 
         verify(mTransaction).setAlpha(mSurfaces.top, 1.0f);
         assertFalse(mLetterbox.needsApplySurfaceChanges());
@@ -204,14 +204,14 @@
 
         assertTrue(mLetterbox.needsApplySurfaceChanges());
 
-        mLetterbox.applySurfaceChanges(mTransaction);
+        applySurfaceChanges();
         verify(mTransaction).setAlpha(mSurfaces.fullWindowSurface, mDarkScrimAlpha);
     }
 
     @Test
     public void testNeedsApplySurfaceChanges_setParentSurface() {
         mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000));
-        mLetterbox.applySurfaceChanges(mTransaction);
+        applySurfaceChanges();
 
         verify(mTransaction).reparent(mSurfaces.top, mParentSurface);
         assertFalse(mLetterbox.needsApplySurfaceChanges());
@@ -220,14 +220,14 @@
 
         assertTrue(mLetterbox.needsApplySurfaceChanges());
 
-        mLetterbox.applySurfaceChanges(mTransaction);
+        applySurfaceChanges();
         verify(mTransaction).reparent(mSurfaces.top, mParentSurface);
     }
 
     @Test
     public void testApplySurfaceChanges_cornersNotRounded_surfaceFullWindowSurfaceNotCreated() {
         mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000));
-        mLetterbox.applySurfaceChanges(mTransaction);
+        applySurfaceChanges();
 
         assertNull(mSurfaces.fullWindowSurface);
     }
@@ -236,7 +236,7 @@
     public void testApplySurfaceChanges_cornersRounded_surfaceFullWindowSurfaceCreated() {
         mAreCornersRounded = true;
         mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000));
-        mLetterbox.applySurfaceChanges(mTransaction);
+        applySurfaceChanges();
 
         assertNotNull(mSurfaces.fullWindowSurface);
     }
@@ -245,7 +245,7 @@
     public void testApplySurfaceChanges_wallpaperBackground_surfaceFullWindowSurfaceCreated() {
         mHasWallpaperBackground = true;
         mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000));
-        mLetterbox.applySurfaceChanges(mTransaction);
+        applySurfaceChanges();
 
         assertNotNull(mSurfaces.fullWindowSurface);
     }
@@ -254,7 +254,7 @@
     public void testNotIntersectsOrFullyContains_cornersRounded() {
         mAreCornersRounded = true;
         mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(0, 0));
-        mLetterbox.applySurfaceChanges(mTransaction);
+        applySurfaceChanges();
 
         assertTrue(mLetterbox.notIntersectsOrFullyContains(new Rect(1, 2, 9, 9)));
     }
@@ -262,14 +262,19 @@
     @Test
     public void testSurfaceOrigin_changeCausesReapply() {
         mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(1000, 2000));
-        mLetterbox.applySurfaceChanges(mTransaction);
+        applySurfaceChanges();
         clearInvocations(mTransaction);
         mLetterbox.layout(new Rect(0, 0, 10, 10), new Rect(0, 1, 10, 10), new Point(0, 0));
         assertTrue(mLetterbox.needsApplySurfaceChanges());
-        mLetterbox.applySurfaceChanges(mTransaction);
+        applySurfaceChanges();
         verify(mTransaction).setPosition(mSurfaces.top, 0, 0);
     }
 
+    private void applySurfaceChanges() {
+        mLetterbox.applySurfaceChanges(/* syncTransaction */ mTransaction,
+                /* pendingTransaction */ mTransaction);
+    }
+
     class SurfaceControlMocker implements Supplier<SurfaceControl.Builder> {
         private SurfaceControl.Builder mLeftBuilder;
         public SurfaceControl left;
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
index cd19449..51b3c48 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
@@ -18,54 +18,26 @@
 
 import static android.content.pm.ActivityInfo.FORCE_NON_RESIZE_APP;
 import static android.content.pm.ActivityInfo.FORCE_RESIZE_APP;
-import static android.content.pm.ActivityInfo.OVERRIDE_ANY_ORIENTATION;
-import static android.content.pm.ActivityInfo.OVERRIDE_ANY_ORIENTATION_TO_USER;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
-import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
 import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_FAKE_FOCUS;
-import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
-import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION;
-import static android.content.pm.ActivityInfo.OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE;
 import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO;
 import static android.content.pm.ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA;
-import static android.content.pm.ActivityInfo.OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA;
-import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR;
-import static android.content.pm.ActivityInfo.OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT;
 import static android.content.pm.ActivityInfo.OVERRIDE_USE_DISPLAY_LANDSCAPE_NATURAL_ORIENTATION;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER;
 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2;
 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_FULLSCREEN;
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 import static android.view.InsetsSource.FLAG_INSETS_ROUNDED_CORNER;
-import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION;
-import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH;
-import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
 import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED;
 import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE;
-import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE;
 import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES;
 import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE;
 import static android.view.WindowManager.PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE;
 import static android.view.WindowManager.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS;
-import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-import static com.android.server.wm.LetterboxUiController.MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP;
-import static com.android.server.wm.LetterboxUiController.SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS;
-import static com.android.window.flags.Flags.FLAG_CAMERA_COMPAT_FOR_FREEFORM;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -74,8 +46,6 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -149,369 +119,7 @@
         mController = new LetterboxUiController(mWm, mActivity);
     }
 
-    // shouldIgnoreRequestedOrientation
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
-    public void testShouldIgnoreRequestedOrientation_activityRelaunching_returnsTrue() {
-        prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
-
-        assertTrue(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
-    public void testShouldIgnoreRequestedOrientation_cameraCompatTreatment_returnsTrue() {
-        doReturn(true).when(mLetterboxConfiguration).isCameraCompatTreatmentEnabled();
-        doReturn(true).when(mLetterboxConfiguration)
-                .isCameraCompatTreatmentEnabledAtBuildTime();
-
-        // Recreate DisplayContent with DisplayRotationCompatPolicy
-        mActivity = setUpActivityWithComponent();
-        mController = new LetterboxUiController(mWm, mActivity);
-        prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
-        mController.setRelaunchingAfterRequestedOrientationChanged(false);
-
-        spyOn(mDisplayContent.mDisplayRotationCompatPolicy);
-        doReturn(true).when(mDisplayContent.mDisplayRotationCompatPolicy)
-                .isTreatmentEnabledForActivity(eq(mActivity));
-
-        assertTrue(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
-    }
-
-    @Test
-    public void testShouldIgnoreRequestedOrientation_overrideDisabled_returnsFalse() {
-        prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
-
-        assertFalse(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
-    }
-
-    @Test
-    public void testShouldIgnoreRequestedOrientation_propertyIsTrue_returnsTrue()
-            throws Exception {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isPolicyForIgnoringRequestedOrientationEnabled();
-        mockThatProperty(PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION, /* value */ true);
-        mController = new LetterboxUiController(mWm, mActivity);
-        prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
-
-        assertTrue(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
-    public void testShouldIgnoreRequestedOrientation_propertyIsFalseAndOverride_returnsFalse()
-            throws Exception {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isPolicyForIgnoringRequestedOrientationEnabled();
-        mockThatProperty(PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION, /* value */ false);
-
-        mController = new LetterboxUiController(mWm, mActivity);
-        prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
-
-        assertFalse(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
-    }
-
-    @Test
-    public void testShouldIgnoreOrientationRequestLoop_overrideDisabled_returnsFalse() {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isPolicyForIgnoringRequestedOrientationEnabled();
-        doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
-        // Request 3 times to simulate orientation request loop
-        for (int i = 0; i <= MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
-            assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
-                    /* expectedCount */ 0);
-        }
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
-    public void testShouldIgnoreOrientationRequestLoop_propertyIsFalseAndOverride_returnsFalse()
-            throws Exception {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isPolicyForIgnoringRequestedOrientationEnabled();
-        mockThatProperty(PROPERTY_COMPAT_ALLOW_IGNORING_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED,
-                /* value */ false);
-        doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
-
-        mController = new LetterboxUiController(mWm, mActivity);
-
-        // Request 3 times to simulate orientation request loop
-        for (int i = 0; i <= MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
-            assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
-                    /* expectedCount */ 0);
-        }
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
-    public void testShouldIgnoreOrientationRequestLoop_isLetterboxed_returnsFalse() {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isPolicyForIgnoringRequestedOrientationEnabled();
-        doReturn(true).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
-
-        // Request 3 times to simulate orientation request loop
-        for (int i = 0; i <= MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
-            assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
-                    /* expectedCount */ i);
-        }
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
-    public void testShouldIgnoreOrientationRequestLoop_noLoop_returnsFalse() {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isPolicyForIgnoringRequestedOrientationEnabled();
-        doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
-
-        // No orientation request loop
-        assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
-                /* expectedCount */ 0);
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
-    public void testShouldIgnoreOrientationRequestLoop_timeout_returnsFalse()
-            throws InterruptedException {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isPolicyForIgnoringRequestedOrientationEnabled();
-        doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
-
-        for (int i = MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i > 0; i--) {
-            assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
-                    /* expectedCount */ 0);
-            Thread.sleep(SET_ORIENTATION_REQUEST_COUNTER_TIMEOUT_MS);
-        }
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_ORIENTATION_REQUEST_WHEN_LOOP_DETECTED})
-    public void testShouldIgnoreOrientationRequestLoop_returnsTrue() {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isPolicyForIgnoringRequestedOrientationEnabled();
-        doReturn(false).when(mActivity).isLetterboxedForFixedOrientationAndAspectRatio();
-
-        for (int i = 0; i < MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP; i++) {
-            assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ false,
-                    /* expectedCount */ i);
-        }
-        assertShouldIgnoreOrientationRequestLoop(/* shouldIgnore */ true,
-                /* expectedCount */ MIN_COUNT_TO_IGNORE_REQUEST_IN_LOOP);
-    }
-
-    private void assertShouldIgnoreOrientationRequestLoop(boolean shouldIgnore, int expectedCount) {
-        if (shouldIgnore) {
-            assertTrue(mController.shouldIgnoreOrientationRequestLoop());
-        } else {
-            assertFalse(mController.shouldIgnoreOrientationRequestLoop());
-        }
-        assertEquals(expectedCount, mController.getSetOrientationRequestCounter());
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
-    public void testShouldIgnoreRequestedOrientation_flagIsDisabled_returnsFalse() {
-        prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
-        doReturn(false).when(mLetterboxConfiguration)
-                .isPolicyForIgnoringRequestedOrientationEnabled();
-
-        assertFalse(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
-    }
-
-    // shouldRefreshActivityForCameraCompat
-
-    @Test
-    public void testShouldRefreshActivityForCameraCompat_flagIsDisabled_returnsFalse() {
-        doReturn(false).when(mLetterboxConfiguration)
-                .isCameraCompatTreatmentEnabled();
-
-        assertFalse(mController.shouldRefreshActivityForCameraCompat());
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
-    public void testShouldRefreshActivityForCameraCompat_overrideEnabled_returnsFalse() {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isCameraCompatTreatmentEnabled();
-
-        assertFalse(mController.shouldRefreshActivityForCameraCompat());
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
-    public void testShouldRefreshActivityForCameraCompat_propertyIsTrueAndOverride_returnsFalse()
-            throws Exception {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isCameraCompatTreatmentEnabled();
-        mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH, /* value */ true);
-
-        mController = new LetterboxUiController(mWm, mActivity);
-
-        assertFalse(mController.shouldRefreshActivityForCameraCompat());
-    }
-
-    @Test
-    public void testShouldRefreshActivityForCameraCompat_propertyIsFalse_returnsFalse()
-            throws Exception {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isCameraCompatTreatmentEnabled();
-        mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH, /* value */ false);
-
-        mController = new LetterboxUiController(mWm, mActivity);
-
-        assertFalse(mController.shouldRefreshActivityForCameraCompat());
-    }
-
-    @Test
-    public void testShouldRefreshActivityForCameraCompat_propertyIsTrue_returnsTrue()
-            throws Exception {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isCameraCompatTreatmentEnabled();
-        mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH, /* value */ true);
-
-        mController = new LetterboxUiController(mWm, mActivity);
-
-        assertTrue(mController.shouldRefreshActivityForCameraCompat());
-    }
-
-    // shouldRefreshActivityViaPauseForCameraCompat
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
-    public void testShouldRefreshActivityViaPauseForCameraCompat_flagIsDisabled_returnsFalse() {
-        doReturn(false).when(mLetterboxConfiguration)
-                .isCameraCompatTreatmentEnabled();
-
-        assertFalse(mController.shouldRefreshActivityViaPauseForCameraCompat());
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
-    public void testShouldRefreshActivityViaPauseForCameraCompat_overrideEnabled_returnsTrue() {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isCameraCompatTreatmentEnabled();
-
-        assertTrue(mController.shouldRefreshActivityViaPauseForCameraCompat());
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
-    public void testShouldRefreshActivityViaPauseForCameraCompat_propertyIsFalseAndOverride_returnFalse()
-            throws Exception {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isCameraCompatTreatmentEnabled();
-        mockThatProperty(PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE, /* value */ false);
-
-        mController = new LetterboxUiController(mWm, mActivity);
-
-        assertFalse(mController.shouldRefreshActivityViaPauseForCameraCompat());
-    }
-
-    @Test
-    public void testShouldRefreshActivityViaPauseForCameraCompat_propertyIsTrue_returnsTrue()
-            throws Exception {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isCameraCompatTreatmentEnabled();
-        mockThatProperty(PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE, /* value */ true);
-
-        mController = new LetterboxUiController(mWm, mActivity);
-
-        assertTrue(mController.shouldRefreshActivityViaPauseForCameraCompat());
-    }
-
-    // shouldForceRotateForCameraCompat
-
-    @Test
-    public void testShouldForceRotateForCameraCompat_flagIsDisabled_returnsFalse() {
-        doReturn(false).when(mLetterboxConfiguration)
-                .isCameraCompatTreatmentEnabled();
-
-        assertFalse(mController.shouldForceRotateForCameraCompat());
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION})
-    public void testShouldForceRotateForCameraCompat_overrideEnabled_returnsFalse() {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isCameraCompatTreatmentEnabled();
-
-        assertFalse(mController.shouldForceRotateForCameraCompat());
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION})
-    public void testShouldForceRotateForCameraCompat_propertyIsTrueAndOverride_returnsFalse()
-            throws Exception {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isCameraCompatTreatmentEnabled();
-        mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION, /* value */ true);
-
-        mController = new LetterboxUiController(mWm, mActivity);
-
-        assertFalse(mController.shouldForceRotateForCameraCompat());
-    }
-
-    @Test
-    public void testShouldForceRotateForCameraCompat_propertyIsFalse_returnsFalse()
-            throws Exception {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isCameraCompatTreatmentEnabled();
-        mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION, /* value */ false);
-
-        mController = new LetterboxUiController(mWm, mActivity);
-
-        assertFalse(mController.shouldForceRotateForCameraCompat());
-    }
-
-    @Test
-    public void testShouldForceRotateForCameraCompat_propertyIsTrue_returnsTrue()
-            throws Exception {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isCameraCompatTreatmentEnabled();
-        mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION, /* value */ true);
-
-        mController = new LetterboxUiController(mWm, mActivity);
-
-        assertTrue(mController.shouldForceRotateForCameraCompat());
-    }
-
-    // shouldApplyFreeformTreatmentForCameraCompat
-
-    @Test
-    public void testShouldApplyCameraCompatFreeformTreatment_flagIsDisabled_returnsFalse() {
-        mSetFlagsRule.disableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM);
-
-        assertFalse(mController.shouldApplyFreeformTreatmentForCameraCompat());
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT})
-    public void testShouldApplyCameraCompatFreeformTreatment_overrideEnabled_returnsFalse() {
-        mSetFlagsRule.enableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM);
-
-        assertFalse(mController.shouldApplyFreeformTreatmentForCameraCompat());
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT})
-    public void testShouldApplyCameraCompatFreeformTreatment_disabledByOverride_returnsFalse()
-            throws Exception {
-        mSetFlagsRule.enableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM);
-
-        mController = new LetterboxUiController(mWm, mActivity);
-
-        assertFalse(mController.shouldApplyFreeformTreatmentForCameraCompat());
-    }
-
-    @Test
-    public void testShouldApplyCameraCompatFreeformTreatment_notDisabledByOverride_returnsTrue()
-            throws Exception {
-        mSetFlagsRule.enableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM);
-
-        mController = new LetterboxUiController(mWm, mActivity);
 
-        assertTrue(mController.shouldApplyFreeformTreatmentForCameraCompat());
-    }
 
     @Test
     public void testGetCropBoundsIfNeeded_handleCropForTransparentActivityBasedOnOpaqueBounds() {
@@ -522,8 +130,9 @@
         final Rect opaqueBounds = new Rect(0, 0, 500, 300);
         doReturn(opaqueBounds).when(mActivity).getBounds();
         // Activity is translucent
-        spyOn(mActivity.mTransparentPolicy);
-        when(mActivity.mTransparentPolicy.isRunning()).thenReturn(true);
+        spyOn(mActivity.mAppCompatController.getTransparentPolicy());
+        when(mActivity.mAppCompatController.getTransparentPolicy()
+                .isRunning()).thenReturn(true);
 
         // Makes requested sizes different
         mainWindow.mRequestedWidth = opaqueBounds.width() - 1;
@@ -709,311 +318,6 @@
         return mainWindow;
     }
 
-    // overrideOrientationIfNeeded
-
-    @Test
-    public void testOverrideOrientationIfNeeded_mapInvokedOnRequest() throws Exception {
-        mController = new LetterboxUiController(mWm, mActivity);
-        spyOn(mWm);
-
-        mController.overrideOrientationIfNeeded(SCREEN_ORIENTATION_PORTRAIT);
-
-        verify(mWm).mapOrientationRequest(SCREEN_ORIENTATION_PORTRAIT);
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_ANY_ORIENTATION_TO_USER})
-    public void testOverrideOrientationIfNeeded_fullscreenOverrideEnabled_returnsUser()
-            throws Exception {
-        mDisplayContent.setIgnoreOrientationRequest(true);
-        assertEquals(SCREEN_ORIENTATION_USER, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_PORTRAIT));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_ANY_ORIENTATION_TO_USER})
-    public void testOverrideOrientationIfNeeded_fullscreenOverrideEnabled_optOut_returnsUnchanged()
-            throws Exception {
-        mockThatProperty(PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE, /* value */ false);
-
-        mController = new LetterboxUiController(mWm, mActivity);
-        mDisplayContent.setIgnoreOrientationRequest(true);
-
-        assertEquals(SCREEN_ORIENTATION_PORTRAIT, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_PORTRAIT));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_ANY_ORIENTATION_TO_USER})
-    public void testOverrideOrientationIfNeeded_fullscreenOverrides_optOutSystem_returnsUser()
-            throws Exception {
-        mockThatProperty(PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE, /* value */ false);
-        prepareActivityThatShouldApplyUserFullscreenOverride();
-
-        // fullscreen override still applied
-        assertEquals(SCREEN_ORIENTATION_USER, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_PORTRAIT));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_ANY_ORIENTATION_TO_USER})
-    public void testOverrideOrientationIfNeeded_fullscreenOverrides_optOutUser_returnsUser()
-            throws Exception {
-        mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_FULLSCREEN_OVERRIDE,
-                /* value */ false);
-        prepareActivityThatShouldApplyUserFullscreenOverride();
-
-        // fullscreen override still applied
-        assertEquals(SCREEN_ORIENTATION_USER, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_PORTRAIT));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_ANY_ORIENTATION_TO_USER})
-    public void testOverrideOrientationIfNeeded_fullscreenOverrideEnabled_returnsUnchanged()
-            throws Exception {
-        mDisplayContent.setIgnoreOrientationRequest(false);
-        assertEquals(SCREEN_ORIENTATION_PORTRAIT, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_PORTRAIT));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_ANY_ORIENTATION_TO_USER})
-    public void testOverrideOrientationIfNeeded_fullscreenAndUserOverrideEnabled_returnsUnchanged()
-            throws Exception {
-        prepareActivityThatShouldApplyUserMinAspectRatioOverride();
-
-        assertEquals(SCREEN_ORIENTATION_PORTRAIT, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_PORTRAIT));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT})
-    public void testOverrideOrientationIfNeeded_portraitOverrideEnabled_returnsPortrait()
-            throws Exception {
-        assertEquals(SCREEN_ORIENTATION_PORTRAIT, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR})
-    public void testOverrideOrientationIfNeeded_portraitOverrideEnabled_returnsNosensor() {
-        assertEquals(SCREEN_ORIENTATION_NOSENSOR, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR})
-    public void testOverrideOrientationIfNeeded_nosensorOverride_orientationFixed_returnsUnchanged() {
-        assertEquals(SCREEN_ORIENTATION_PORTRAIT, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_PORTRAIT));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE})
-    public void testOverrideOrientationIfNeeded_reverseLandscapeOverride_orientationPortraitOrUndefined_returnsUnchanged() {
-        assertEquals(SCREEN_ORIENTATION_PORTRAIT, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_PORTRAIT));
-        assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_LANDSCAPE_ORIENTATION_TO_REVERSE_LANDSCAPE})
-    public void testOverrideOrientationIfNeeded_reverseLandscapeOverride_orientationLandscape_returnsReverseLandscape() {
-        assertEquals(SCREEN_ORIENTATION_REVERSE_LANDSCAPE, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_LANDSCAPE));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT})
-    public void testOverrideOrientationIfNeeded_portraitOverride_orientationFixed_returnsUnchanged() {
-        assertEquals(SCREEN_ORIENTATION_NOSENSOR, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_NOSENSOR));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT, OVERRIDE_ANY_ORIENTATION})
-    public void testOverrideOrientationIfNeeded_portraitAndIgnoreFixedOverrides_returnsPortrait() {
-        assertEquals(SCREEN_ORIENTATION_PORTRAIT, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_NOSENSOR));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_NOSENSOR, OVERRIDE_ANY_ORIENTATION})
-    public void testOverrideOrientationIfNeeded_noSensorAndIgnoreFixedOverrides_returnsNosensor() {
-        assertEquals(SCREEN_ORIENTATION_NOSENSOR, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_PORTRAIT));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT})
-    public void testOverrideOrientationIfNeeded_propertyIsFalse_returnsUnchanged()
-            throws Exception {
-        mockThatProperty(PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE, /* value */ false);
-
-        mController = new LetterboxUiController(mWm, mActivity);
-
-        assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT,
-            OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA})
-    public void testOverrideOrientationIfNeeded_whenCameraNotActive_returnsUnchanged() {
-        doReturn(true).when(mLetterboxConfiguration).isCameraCompatTreatmentEnabled();
-        doReturn(true).when(mLetterboxConfiguration)
-                .isCameraCompatTreatmentEnabledAtBuildTime();
-
-        // Recreate DisplayContent with DisplayRotationCompatPolicy
-        mActivity = setUpActivityWithComponent();
-        mController = new LetterboxUiController(mWm, mActivity);
-
-        spyOn(mDisplayContent.mDisplayRotationCompatPolicy);
-        doReturn(false).when(mDisplayContent.mDisplayRotationCompatPolicy)
-                .isActivityEligibleForOrientationOverride(eq(mActivity));
-
-        assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT,
-            OVERRIDE_ORIENTATION_ONLY_FOR_CAMERA})
-    public void testOverrideOrientationIfNeeded_whenCameraActive_returnsPortrait() {
-        doReturn(true).when(mLetterboxConfiguration).isCameraCompatTreatmentEnabled();
-        doReturn(true).when(mLetterboxConfiguration)
-                .isCameraCompatTreatmentEnabledAtBuildTime();
-
-        // Recreate DisplayContent with DisplayRotationCompatPolicy
-        mActivity = setUpActivityWithComponent();
-        mController = new LetterboxUiController(mWm, mActivity);
-
-        spyOn(mDisplayContent.mDisplayRotationCompatPolicy);
-        doReturn(true).when(mDisplayContent.mDisplayRotationCompatPolicy)
-                .isActivityEligibleForOrientationOverride(eq(mActivity));
-
-        assertEquals(SCREEN_ORIENTATION_PORTRAIT, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED));
-    }
-
-    @Test
-    public void testOverrideOrientationIfNeeded_userFullscreenOverride_returnsUser() {
-        spyOn(mController);
-        doReturn(true).when(mController).shouldApplyUserFullscreenOverride();
-        mDisplayContent.setIgnoreOrientationRequest(true);
-
-        assertEquals(SCREEN_ORIENTATION_USER, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED));
-    }
-
-    @Test
-    public void testOverrideOrientationIfNeeded_userFullscreenOverride_cameraActivity_noChange() {
-        doReturn(true).when(mLetterboxConfiguration).isCameraCompatTreatmentEnabled();
-        doReturn(true).when(mLetterboxConfiguration)
-                .isCameraCompatTreatmentEnabledAtBuildTime();
-
-        // Recreate DisplayContent with DisplayRotationCompatPolicy
-        mActivity = setUpActivityWithComponent();
-        mController = new LetterboxUiController(mWm, mActivity);
-        spyOn(mController);
-        doReturn(true).when(mController).shouldApplyUserFullscreenOverride();
-
-        spyOn(mDisplayContent.mDisplayRotationCompatPolicy);
-        doReturn(true).when(mDisplayContent.mDisplayRotationCompatPolicy)
-                .isCameraActive(mActivity, /* mustBeFullscreen= */ true);
-
-        assertEquals(SCREEN_ORIENTATION_PORTRAIT, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_PORTRAIT));
-    }
-
-    @Test
-    public void testOverrideOrientationIfNeeded_systemFullscreenOverride_cameraActivity_noChange() {
-        doReturn(true).when(mLetterboxConfiguration).isCameraCompatTreatmentEnabled();
-        doReturn(true).when(mLetterboxConfiguration)
-                .isCameraCompatTreatmentEnabledAtBuildTime();
-
-        // Recreate DisplayContent with DisplayRotationCompatPolicy
-        mActivity = setUpActivityWithComponent();
-        mController = new LetterboxUiController(mWm, mActivity);
-        spyOn(mController);
-        doReturn(true).when(mController).isSystemOverrideToFullscreenEnabled();
-
-        spyOn(mDisplayContent.mDisplayRotationCompatPolicy);
-        doReturn(true).when(mDisplayContent.mDisplayRotationCompatPolicy)
-                .isCameraActive(mActivity, /* mustBeFullscreen= */ true);
-
-        assertEquals(SCREEN_ORIENTATION_PORTRAIT, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_PORTRAIT));
-    }
-
-    @Test
-    public void testOverrideOrientationIfNeeded_respectOrientationRequestOverUserFullScreen() {
-        spyOn(mController);
-        doReturn(true).when(mController).shouldApplyUserFullscreenOverride();
-        mDisplayContent.setIgnoreOrientationRequest(false);
-
-        assertNotEquals(SCREEN_ORIENTATION_USER, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT, OVERRIDE_ANY_ORIENTATION})
-    public void testOverrideOrientationIfNeeded_userFullScreenOverrideOverSystem_returnsUser() {
-        spyOn(mController);
-        doReturn(true).when(mController).shouldApplyUserFullscreenOverride();
-        mDisplayContent.setIgnoreOrientationRequest(true);
-
-        assertEquals(SCREEN_ORIENTATION_USER, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_PORTRAIT));
-    }
-
-    @Test
-    @EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT, OVERRIDE_ANY_ORIENTATION})
-    public void testOverrideOrientationIfNeeded_respectOrientationReqOverUserFullScreenAndSystem() {
-        spyOn(mController);
-        doReturn(true).when(mController).shouldApplyUserFullscreenOverride();
-        mDisplayContent.setIgnoreOrientationRequest(false);
-
-        assertNotEquals(SCREEN_ORIENTATION_USER, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_PORTRAIT));
-    }
-
-    @Test
-    public void testOverrideOrientationIfNeeded_userFullScreenOverrideDisabled_returnsUnchanged() {
-        spyOn(mController);
-        doReturn(false).when(mController).shouldApplyUserFullscreenOverride();
-
-        assertEquals(SCREEN_ORIENTATION_PORTRAIT, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_PORTRAIT));
-    }
-
-    @Test
-    public void testOverrideOrientationIfNeeded_userAspectRatioApplied_unspecifiedOverridden() {
-        spyOn(mController);
-        doReturn(true).when(mController).shouldApplyUserMinAspectRatioOverride();
-
-        assertEquals(SCREEN_ORIENTATION_PORTRAIT, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED));
-
-        assertEquals(SCREEN_ORIENTATION_PORTRAIT, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_LOCKED));
-
-        // unchanged if orientation is specified
-        assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_LANDSCAPE));
-    }
-
-    @Test
-    public void testOverrideOrientationIfNeeded_userAspectRatioNotApplied_returnsUnchanged() {
-        spyOn(mController);
-        doReturn(false).when(mController).shouldApplyUserMinAspectRatioOverride();
-
-        assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, mController.overrideOrientationIfNeeded(
-                /* candidate */ SCREEN_ORIENTATION_UNSPECIFIED));
-    }
-
     // shouldApplyUser...Override
     @Test
     public void testShouldApplyUserFullscreenOverride_trueProperty_returnsFalse() throws Exception {
@@ -1062,6 +366,7 @@
         prepareActivityThatShouldApplyUserMinAspectRatioOverride();
         mockThatProperty(PROPERTY_COMPAT_ALLOW_USER_ASPECT_RATIO_OVERRIDE, /* value */ false);
 
+        mActivity = setUpActivityWithComponent();
         mController = new LetterboxUiController(mWm, mActivity);
 
         assertFalse(mController.shouldEnableUserAspectRatioSettings());
@@ -1133,39 +438,6 @@
         assertFalse(mController.shouldApplyUserMinAspectRatioOverride());
     }
 
-    @Test
-    public void testRecomputeConfigurationForCameraCompatIfNeeded() {
-        spyOn(mController);
-        doReturn(false).when(mController).isOverrideOrientationOnlyForCameraEnabled();
-        doReturn(false).when(mController).isCameraCompatSplitScreenAspectRatioAllowed();
-        doReturn(false).when(mController).shouldOverrideMinAspectRatioForCamera();
-        clearInvocations(mActivity);
-
-        mController.recomputeConfigurationForCameraCompatIfNeeded();
-
-        verify(mActivity, never()).recomputeConfiguration();
-
-        // isOverrideOrientationOnlyForCameraEnabled
-        doReturn(true).when(mController).isOverrideOrientationOnlyForCameraEnabled();
-        clearInvocations(mActivity);
-        mController.recomputeConfigurationForCameraCompatIfNeeded();
-        verify(mActivity).recomputeConfiguration();
-
-        // isCameraCompatSplitScreenAspectRatioAllowed
-        doReturn(false).when(mController).isOverrideOrientationOnlyForCameraEnabled();
-        doReturn(true).when(mController).isCameraCompatSplitScreenAspectRatioAllowed();
-        clearInvocations(mActivity);
-        mController.recomputeConfigurationForCameraCompatIfNeeded();
-        verify(mActivity).recomputeConfiguration();
-
-        // shouldOverrideMinAspectRatioForCamera
-        doReturn(false).when(mController).isCameraCompatSplitScreenAspectRatioAllowed();
-        doReturn(true).when(mController).shouldOverrideMinAspectRatioForCamera();
-        clearInvocations(mActivity);
-        mController.recomputeConfigurationForCameraCompatIfNeeded();
-        verify(mActivity).recomputeConfiguration();
-    }
-
     private void prepareActivityForShouldApplyUserMinAspectRatioOverride(
             boolean orientationRequest) {
         spyOn(mController);
@@ -1344,6 +616,8 @@
     public void testshouldOverrideMinAspectRatio_propertyFalse_overrideEnabled_returnsFalse()
             throws Exception {
         mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ false);
+
+        mActivity = setUpActivityWithComponent();
         mController = new LetterboxUiController(mWm, mActivity);
 
         assertFalse(mController.shouldOverrideMinAspectRatio());
@@ -1362,52 +636,62 @@
     @Test
     @EnableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA})
     public void shouldOverrideMinAspectRatioForCamera_overrideEnabled_returnsTrue() {
-        doReturn(true).when(mActivity).isCameraActive();
-        mController = new LetterboxUiController(mWm, mActivity);
+        mActivity = setUpActivityWithComponent();
+        doReturn(true).when(mActivity.mAppCompatController
+                .getAppCompatCameraOverrides()).isCameraActive();
 
-        assertTrue(mController.shouldOverrideMinAspectRatioForCamera());
+        assertTrue(mActivity.mAppCompatController.getAppCompatCameraOverrides()
+                .shouldOverrideMinAspectRatioForCamera());
     }
 
     @Test
     @EnableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA})
     public void shouldOverrideMinAspectRatioForCamera_propertyTrue_overrideEnabled_returnsTrue()
             throws Exception {
-        doReturn(true).when(mActivity).isCameraActive();
         mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ true);
-        mController = new LetterboxUiController(mWm, mActivity);
+        mActivity = setUpActivityWithComponent();
+        doReturn(true).when(mActivity.mAppCompatController
+                .getAppCompatCameraOverrides()).isCameraActive();
 
-        assertTrue(mController.shouldOverrideMinAspectRatioForCamera());
+        assertTrue(mActivity.mAppCompatController.getAppCompatCameraOverrides()
+                .shouldOverrideMinAspectRatioForCamera());
     }
 
     @Test
     @EnableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA})
     public void shouldOverrideMinAspectRatioForCamera_propertyTrue_overrideEnabled_returnsFalse()
             throws Exception {
-        doReturn(false).when(mActivity).isCameraActive();
         mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ true);
-        mController = new LetterboxUiController(mWm, mActivity);
+        mActivity = setUpActivityWithComponent();
+        doReturn(false).when(mActivity.mAppCompatController
+                .getAppCompatCameraOverrides()).isCameraActive();
 
-        assertFalse(mController.shouldOverrideMinAspectRatioForCamera());
+        assertFalse(mActivity.mAppCompatController.getAppCompatCameraOverrides()
+                .shouldOverrideMinAspectRatioForCamera());
     }
 
     @Test
     @DisableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA})
     public void shouldOverrideMinAspectRatioForCamera_propertyTrue_overrideDisabled_returnsFalse()
             throws Exception {
-        doReturn(true).when(mActivity).isCameraActive();
         mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ true);
-        mController = new LetterboxUiController(mWm, mActivity);
+        mActivity = setUpActivityWithComponent();
+        doReturn(true).when(mActivity.mAppCompatController
+                .getAppCompatCameraOverrides()).isCameraActive();
 
-        assertFalse(mController.shouldOverrideMinAspectRatioForCamera());
+        assertFalse(mActivity.mAppCompatController.getAppCompatCameraOverrides()
+                .shouldOverrideMinAspectRatioForCamera());
     }
 
     @Test
     @DisableCompatChanges({OVERRIDE_MIN_ASPECT_RATIO_ONLY_FOR_CAMERA})
     public void shouldOverrideMinAspectRatioForCamera_overrideDisabled_returnsFalse() {
-        doReturn(true).when(mActivity).isCameraActive();
-        mController = new LetterboxUiController(mWm, mActivity);
+        mActivity = setUpActivityWithComponent();
+        doReturn(true).when(mActivity.mAppCompatController
+                .getAppCompatCameraOverrides()).isCameraActive();
 
-        assertFalse(mController.shouldOverrideMinAspectRatioForCamera());
+        assertFalse(mActivity.mAppCompatController.getAppCompatCameraOverrides()
+                .shouldOverrideMinAspectRatioForCamera());
     }
 
     @Test
@@ -1415,9 +699,10 @@
     public void shouldOverrideMinAspectRatioForCamera_propertyFalse_overrideEnabled_returnsFalse()
             throws Exception {
         mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ false);
-        mController = new LetterboxUiController(mWm, mActivity);
+        mActivity = setUpActivityWithComponent();
 
-        assertFalse(mController.shouldOverrideMinAspectRatioForCamera());
+        assertFalse(mActivity.mAppCompatController.getAppCompatCameraOverrides()
+                .shouldOverrideMinAspectRatioForCamera());
     }
 
     @Test
@@ -1425,10 +710,14 @@
     public void shouldOverrideMinAspectRatioForCamera_propertyFalse_noOverride_returnsFalse()
             throws Exception {
         mockThatProperty(PROPERTY_COMPAT_ALLOW_MIN_ASPECT_RATIO_OVERRIDE, /* value */ false);
-        doReturn(true).when(mActivity).isCameraActive();
-        mController = new LetterboxUiController(mWm, mActivity);
 
-        assertFalse(mController.shouldOverrideMinAspectRatioForCamera());
+        mActivity = setUpActivityWithComponent();
+
+        doReturn(true).when(mActivity.mAppCompatController
+                .getAppCompatCameraOverrides()).isCameraActive();
+
+        assertFalse(mActivity.mAppCompatController.getAppCompatCameraOverrides()
+                .shouldOverrideMinAspectRatioForCamera());
     }
 
     @Test
@@ -1472,6 +761,8 @@
     public void testshouldOverrideForceResizeApp_propertyFalse_overrideEnabled_returnsFalse()
             throws Exception {
         mockThatProperty(PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES, /* value */ false);
+
+        mActivity = setUpActivityWithComponent();
         mController = new LetterboxUiController(mWm, mActivity);
 
         assertFalse(mController.shouldOverrideForceResizeApp());
@@ -1528,6 +819,8 @@
     public void testshouldOverrideForceNonResizeApp_propertyFalse_overrideEnabled_returnsFalse()
             throws Exception {
         mockThatProperty(PROPERTY_COMPAT_ALLOW_RESIZEABLE_ACTIVITY_OVERRIDES, /* value */ false);
+
+        mActivity = setUpActivityWithComponent();
         mController = new LetterboxUiController(mWm, mActivity);
 
         assertFalse(mController.shouldOverrideForceNonResizeApp());
@@ -1563,8 +856,8 @@
         assertEquals(1.5f, mController.getFixedOrientationLetterboxAspectRatio(
                 mActivity.getParent().getConfiguration()), /* delta */ 0.01);
 
-        spyOn(mDisplayContent.mDisplayRotationCompatPolicy);
-        doReturn(true).when(mDisplayContent.mDisplayRotationCompatPolicy)
+        spyOn(mDisplayContent.mAppCompatCameraPolicy);
+        doReturn(true).when(mDisplayContent.mAppCompatCameraPolicy)
                 .isTreatmentEnabledForActivity(eq(mActivity));
 
         assertEquals(mController.getSplitScreenAspectRatio(),
@@ -1684,12 +977,6 @@
         mDisplayContent.setIgnoreOrientationRequest(true);
     }
 
-    private void prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch() {
-        doReturn(true).when(mLetterboxConfiguration)
-                .isPolicyForIgnoringRequestedOrientationEnabled();
-        mController.setRelaunchingAfterRequestedOrientationChanged(true);
-    }
-
     private ActivityRecord setUpActivityWithComponent() {
         mDisplayContent = new TestDisplayContent
                 .Builder(mAtm, /* dw */ 1000, /* dh */ 2000).build();
@@ -1701,6 +988,7 @@
                 .setComponent(ComponentName.createRelative(mContext,
                         com.android.server.wm.LetterboxUiControllerTest.class.getName()))
                 .build();
+        spyOn(activity.mAppCompatController.getAppCompatCameraOverrides());
         return activity;
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java b/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java
index c5bf78b..35cff7a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ProtoLogIntegrationTest.java
@@ -25,11 +25,11 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.internal.protolog.ProtoLog;
 import com.android.internal.protolog.ProtoLogGroup;
 import com.android.internal.protolog.ProtoLogImpl;
 import com.android.internal.protolog.common.IProtoLog;
 import com.android.internal.protolog.common.LogLevel;
-import com.android.internal.protolog.common.ProtoLog;
 
 import org.junit.After;
 import org.junit.Ignore;
@@ -53,9 +53,6 @@
         runWith(mockedProtoLog, this::testProtoLog);
         verify(mockedProtoLog).log(eq(LogLevel.ERROR), eq(ProtoLogGroup.TEST_GROUP),
                 anyInt(), eq(0b0010010111),
-                eq(com.android.internal.protolog.ProtoLogGroup.TEST_GROUP.isLogToLogcat()
-                        ? "Test completed successfully: %b %d %x %f %% %s"
-                        : null),
                 eq(new Object[]{true, 1L, 2L, 0.3, "ok"}));
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 6ec1429..33f7035 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -653,6 +653,34 @@
     }
 
     @Test
+    public void testTrimNonTrimmableTask_isTrimmable_returnsFalse() {
+        Task nonTrimmableTask = createTaskBuilder(".NonTrimmableTask").setFlags(
+                FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS).build();
+        nonTrimmableTask.mIsTrimmableFromRecents = false;
+
+        // Move home to front so the task can satisfy the condition in RecentTasks#isTrimmable.
+        mRootWindowContainer.getDefaultTaskDisplayArea().getRootHomeTask().moveToFront("test");
+
+        assertThat(mRecentTasks.isTrimmable(nonTrimmableTask)).isFalse();
+    }
+
+    @Test
+    public void testTrimNonTrimmableTask_taskNotTrimmed() {
+        Task nonTrimmableTask = createTaskBuilder(".NonTrimmableTask").setFlags(
+                FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS).build();
+        nonTrimmableTask.mIsTrimmableFromRecents = false;
+
+        // Move home to front so the task can satisfy the condition in RecentTasks#isTrimmable.
+        mRootWindowContainer.getDefaultTaskDisplayArea().getRootHomeTask().moveToFront("test");
+
+        mRecentTasks.add(mTasks.get(0));
+        mRecentTasks.add(nonTrimmableTask);
+        mRecentTasks.add(mTasks.get(1));
+
+        triggerTrimAndAssertNoTasksTrimmed();
+    }
+
+    @Test
     public void testSessionDuration() {
         mRecentTasks.setOnlyTestVisibleRange();
         mRecentTasks.setParameters(-1 /* min */, -1 /* max */, 50 /* ms */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index eb79118..3078df0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -392,6 +392,8 @@
         assertEquals(newPipTask, mDisplayContent.getDefaultTaskDisplayArea().getRootPinnedTask());
         assertNotEquals(newPipTask, activity1.getTask());
         assertFalse("Created PiP task must not be in recents", newPipTask.inRecents);
+        assertThat(newPipTask.autoRemoveRecents).isTrue();
+        assertThat(activity1.getTask().autoRemoveRecents).isFalse();
     }
 
     /**
@@ -427,6 +429,7 @@
         bounds.scale(0.5f);
         task.setBounds(bounds);
         assertFalse(activity.isLetterboxedForFixedOrientationAndAspectRatio());
+        assertThat(task.autoRemoveRecents).isFalse();
     }
 
     /**
@@ -451,6 +454,7 @@
         // Ensure a task has moved over.
         ensureTaskPlacement(task, activity);
         assertTrue(task.inPinnedWindowingMode());
+        assertThat(task.autoRemoveRecents).isFalse();
     }
 
     /**
@@ -480,6 +484,8 @@
         ensureTaskPlacement(fullscreenTask, secondActivity);
         assertTrue(pinnedRootTask.inPinnedWindowingMode());
         assertEquals(WINDOWING_MODE_FULLSCREEN, fullscreenTask.getWindowingMode());
+        assertThat(pinnedRootTask.autoRemoveRecents).isTrue();
+        assertThat(secondActivity.getTask().autoRemoveRecents).isFalse();
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index ac1aa20..64527cb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -1315,6 +1315,47 @@
 
     @Test
     @EnableCompatChanges({ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO,
+            ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_SMALL})
+    public void testOverrideMinAspectRatioSmall_overridden() {
+        final int dh = 1200;
+        final int dw = 1000;
+        setUpDisplaySizeWithApp(dw, dh);
+
+        // Create a size compat activity on the same task.
+        final ActivityRecord activity = getActivityBuilderOnSameTask()
+                .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
+                .build();
+
+        final Rect bounds = activity.getBounds();
+        assertEquals(dh, bounds.height());
+        assertEquals(dh / ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_SMALL_VALUE,
+                bounds.width(), 0.5f);
+    }
+
+    @Test
+    @EnableCompatChanges({ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO,
+            ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_SMALL})
+    public void testOverrideMinAspectRatioSmall_notOverridden() {
+        final int dh = 1200;
+        final int dw = 1000;
+        setUpDisplaySizeWithApp(dw, dh);
+
+        // Create a size compat activity on the same task.
+        final ActivityRecord activity = getActivityBuilderOnSameTask()
+                .setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
+                .setMinAspectRatio(OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE)
+                .build();
+
+        // Activity's requested aspect ratio is larger than OVERRIDE_MIN_ASPECT_RATIO_SMALL,
+        // so OVERRIDE_MIN_ASPECT_RATIO_SMALL is ignored.
+        final Rect bounds = activity.getBounds();
+        assertEquals(dh, bounds.height());
+        assertEquals(dh / OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE,
+                bounds.width(), 0.5f);
+    }
+
+    @Test
+    @EnableCompatChanges({ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO,
             ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_MEDIUM})
     public void testOverrideMinAspectRatioMedium() {
         setUpDisplaySizeWithApp(1000, 1200);
@@ -4271,6 +4312,27 @@
 
     }
 
+    @Test
+    public void testInsetOverrideNotAppliedInFreeform() {
+        final int notchHeight = 100;
+        final DisplayContent display = new TestDisplayContent.Builder(mAtm, 1000, 2800)
+                .setNotch(notchHeight)
+                .build();
+        setUpApp(display);
+
+        // Simulate inset override for legacy app bound behaviour
+        mActivity.mResolveConfigHint.mUseOverrideInsetsForConfig = true;
+        // Set task as freeform
+        mTask.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM);
+        prepareUnresizable(mActivity,  SCREEN_ORIENTATION_PORTRAIT);
+
+        Rect bounds = new Rect(mActivity.getWindowConfiguration().getBounds());
+        Rect appBounds = new Rect(mActivity.getWindowConfiguration().getAppBounds());
+        // App bounds should not include insets and should match bounds when in freeform.
+        assertEquals(new Rect(0, 0, 1000, 2800), appBounds);
+        assertEquals(new Rect(0, 0, 1000, 2800), bounds);
+    }
+
     private void assertVerticalPositionForDifferentDisplayConfigsForLandscapeActivity(
             float letterboxVerticalPositionMultiplier, Rect fixedOrientationLetterbox,
             Rect sizeCompatUnscaled, Rect sizeCompatScaled) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java b/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java
index 6c5f975..1c32980 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SyncEngineTests.java
@@ -33,6 +33,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -417,6 +418,22 @@
     }
 
     @Test
+    public void testSkipPrepareSync() {
+        final TestWindowContainer wc = new TestWindowContainer(mWm, true /* waiter */);
+        wc.mSkipPrepareSync = true;
+        final BLASTSyncEngine bse = createTestBLASTSyncEngine();
+        final BLASTSyncEngine.SyncGroup syncGroup = bse.prepareSyncSet(
+                mock(BLASTSyncEngine.TransactionReadyListener.class), "test");
+        bse.startSyncSet(syncGroup);
+        bse.addToSyncSet(syncGroup.mSyncId, wc);
+        assertEquals(SYNC_STATE_NONE, wc.mSyncState);
+        // If the implementation of prepareSync doesn't set sync state, the sync group should also
+        // be empty.
+        assertNull(wc.mSyncGroup);
+        assertTrue(wc.isSyncFinished(syncGroup));
+    }
+
+    @Test
     public void testNonBlastMethod() {
         mAppWindow = createWindow(null, TYPE_BASE_APPLICATION, "mAppWindow");
 
@@ -694,6 +711,7 @@
         final boolean mWaiter;
         boolean mVisibleRequested = true;
         boolean mFillsParent = false;
+        boolean mSkipPrepareSync = false;
 
         TestWindowContainer(WindowManagerService wms, boolean waiter) {
             super(wms);
@@ -703,6 +721,9 @@
 
         @Override
         boolean prepareSync() {
+            if (mSkipPrepareSync) {
+                return false;
+            }
             if (!super.prepareSync()) {
                 return false;
             }
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index c962a3f..4220f31 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -442,15 +442,7 @@
                 dc.getDisplayPolicy().release();
                 // Unregister SensorEventListener (foldable device may register for hinge angle).
                 dc.getDisplayRotation().onDisplayRemoved();
-                if (dc.mDisplayRotationCompatPolicy != null) {
-                    dc.mDisplayRotationCompatPolicy.dispose();
-                }
-                if (dc.mCameraCompatFreeformPolicy != null) {
-                    dc.mCameraCompatFreeformPolicy.dispose();
-                }
-                if (dc.mCameraStateMonitor != null) {
-                    dc.mCameraStateMonitor.dispose();
-                }
+                dc.mAppCompatCameraPolicy.dispose();
             }
         }
 
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 9670a9a..a71b81e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -26,8 +26,8 @@
 import static android.view.WindowManager.TRANSIT_CLOSE;
 import static android.view.WindowManager.TRANSIT_NONE;
 import static android.view.WindowManager.TRANSIT_OPEN;
-import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_TASK_FRAGMENT;
 import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_OR_MOVE_TASK_FRAGMENT_DECOR_SURFACE;
+import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_TASK_FRAGMENT;
 import static android.window.TaskFragmentOperation.OP_TYPE_DELETE_TASK_FRAGMENT;
 import static android.window.TaskFragmentOperation.OP_TYPE_REMOVE_TASK_FRAGMENT_DECOR_SURFACE;
 import static android.window.TaskFragmentOperation.OP_TYPE_REORDER_TO_BOTTOM_OF_TASK;
@@ -220,30 +220,7 @@
     }
 
     @Test
-    public void testOnTaskFragmentAppeared_throughTaskFragmentOrganizer() throws RemoteException {
-        mSetFlagsRule.disableFlags(Flags.FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
-
-        // No-op when the TaskFragment is not attached.
-        mController.onTaskFragmentAppeared(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
-        mController.dispatchPendingEvents();
-
-        verify(mOrganizer, never()).onTransactionReady(any());
-        verify(mAppThread, never()).scheduleTaskFragmentTransaction(any(), any());
-
-        // Send callback when the TaskFragment is attached.
-        setupMockParent(mTaskFragment, mTask);
-
-        mController.onTaskFragmentAppeared(mTaskFragment.getTaskFragmentOrganizer(), mTaskFragment);
-        mController.dispatchPendingEvents();
-
-        assertTaskFragmentParentInfoChangedTransaction(mTask);
-        assertTaskFragmentAppearedTransaction(false /* hasSurfaceControl */);
-        verify(mAppThread, never()).scheduleTaskFragmentTransaction(any(), any());
-    }
-
-    @Test
     public void testOnTaskFragmentAppeared_throughApplicationThread() throws RemoteException  {
-        mSetFlagsRule.enableFlags(Flags.FLAG_BUNDLE_CLIENT_TRANSACTION_FLAG);
         // Re-register the organizer in case the flag was disabled during setup.
         mController.unregisterOrganizer(mIOrganizer);
         registerTaskFragmentOrganizer(mIOrganizer);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
index f94e5e3..35b6b70 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentTest.java
@@ -499,8 +499,8 @@
                 .build();
         final ActivityRecord activity0 = organizedTf.getBottomMostActivity();
         final ActivityRecord activity1 = organizedTf.getTopMostActivity();
-        // Bottom activity is untrusted embedding. Top activity is trusted embedded.
-        // Activity0 has overlay over untrusted mode embedded.
+        // Bottom activity is untrusted embedding. Top activity is trusted embedded and occludes
+        // the bottom activity. Activity0 has overlay over untrusted mode embedded.
         activity0.info.applicationInfo.uid = DEFAULT_TASK_FRAGMENT_ORGANIZER_UID + 1;
         activity1.info.applicationInfo.uid = DEFAULT_TASK_FRAGMENT_ORGANIZER_UID;
         doReturn(true).when(organizedTf).isAllowedToEmbedActivityInUntrustedMode(activity0);
@@ -537,6 +537,48 @@
     }
 
     @Test
+    public void testActivityHasOverlayOverUntrustedModeEmbeddedWithAdjacentTaskFragments() {
+        final Task rootTask = createTask(mDisplayContent, WINDOWING_MODE_MULTI_WINDOW,
+                ACTIVITY_TYPE_STANDARD);
+        final Rect taskBounds = rootTask.getBounds();
+        final TaskFragment organizedTf0 = new TaskFragmentBuilder(mAtm)
+                .createActivityCount(1)
+                .setParentTask(rootTask)
+                .setFragmentToken(new Binder())
+                .setOrganizer(mOrganizer)
+                .setBounds(new Rect(taskBounds.left, taskBounds.top,
+                        taskBounds.left + taskBounds.width() / 2, taskBounds.bottom))
+                .build();
+        final TaskFragment organizedTf1 = new TaskFragmentBuilder(mAtm)
+                .createActivityCount(1)
+                .setParentTask(rootTask)
+                .setFragmentToken(new Binder())
+                .setOrganizer(mOrganizer)
+                .setBounds(new Rect(taskBounds.left + taskBounds.width() / 2, taskBounds.top,
+                        taskBounds.right, taskBounds.bottom))
+                .build();
+        final ActivityRecord activity0 = organizedTf0.getTopMostActivity();
+        final ActivityRecord activity1 = organizedTf1.getTopMostActivity();
+
+        activity0.info.applicationInfo.uid = DEFAULT_TASK_FRAGMENT_ORGANIZER_UID + 1;
+        activity1.info.applicationInfo.uid = DEFAULT_TASK_FRAGMENT_ORGANIZER_UID;
+        doReturn(true).when(organizedTf0).isAllowedToEmbedActivityInUntrustedMode(activity0);
+
+        assertFalse("Activity0 doesn't have overlay because it's not occluded by activity1",
+                activity0.hasOverlayOverUntrustedModeEmbedded());
+        assertFalse(activity1.hasOverlayOverUntrustedModeEmbedded());
+
+        // Expand organizedTf1 bounds slightly.
+        final Rect tfBounds1 = organizedTf1.getBounds();
+        organizedTf1.setBounds(tfBounds1.left - 5, tfBounds1.top, taskBounds.right + 5,
+                tfBounds1.bottom);
+
+        assertTrue("Activity0 has overlay because it's occluded partially by activity1",
+                activity0.hasOverlayOverUntrustedModeEmbedded());
+        assertFalse(activity1.hasOverlayOverUntrustedModeEmbedded());
+    }
+
+    @Test
     public void testIsAllowedToBeEmbeddedInTrustedMode() {
         final TaskFragment taskFragment = new TaskFragmentBuilder(mAtm)
                 .setCreateParentTask()
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 e01cea3..4bc87b1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -42,6 +42,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.server.policy.WindowManagerPolicy.USER_ROTATION_FREE;
+import static com.android.server.wm.ActivityRecord.State.RESUMED;
 import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG;
 import static com.android.server.wm.TaskFragment.EMBEDDED_DIM_AREA_PARENT_TASK;
 import static com.android.server.wm.TaskFragment.TASK_FRAGMENT_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
@@ -222,6 +223,27 @@
     }
 
     @Test
+    public void testReparentPinnedActivityBackToOriginalTask() {
+        final ActivityRecord activityMain = new ActivityBuilder(mAtm).setCreateTask(true).build();
+        final Task originalTask = activityMain.getTask();
+        final ActivityRecord activityPip = new ActivityBuilder(mAtm).setTask(originalTask).build();
+        activityPip.setState(RESUMED, "test");
+        mAtm.mRootWindowContainer.moveActivityToPinnedRootTask(activityPip,
+                null /* launchIntoPipHostActivity */, "test");
+        final Task pinnedActivityTask = activityPip.getTask();
+
+        // Simulate pinnedActivityTask unintentionally added to recent during top activity resume.
+        mAtm.getRecentTasks().getRawTasks().add(pinnedActivityTask);
+
+        // Reparent the activity back to its original task when exiting PIP mode.
+        pinnedActivityTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+
+        assertThat(activityPip.getTask()).isEqualTo(originalTask);
+        assertThat(originalTask.autoRemoveRecents).isFalse();
+        assertThat(mAtm.getRecentTasks().getRawTasks()).containsExactly(originalTask);
+    }
+
+    @Test
     public void testReparent_BetweenDisplays() {
         // Create first task on primary display.
         final Task rootTask1 = createTask(mDisplayContent);
@@ -1991,7 +2013,7 @@
     public void getTaskInfoPropagatesCameraCompatMode() {
         final Task task = new TaskBuilder(mSupervisor).setCreateActivity(true).build();
         final ActivityRecord activity = task.getTopMostActivity();
-        activity.mLetterboxUiController
+        activity.mAppCompatController.getAppCompatCameraOverrides()
                 .setFreeformCameraCompatMode(CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT);
 
         assertEquals(CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT,
diff --git a/services/tests/wmtests/src/com/android/server/wm/TransparentPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/TransparentPolicyTest.java
index 1d6e307..f07b402 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransparentPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransparentPolicyTest.java
@@ -16,45 +16,22 @@
 
 package com.android.server.wm;
 
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
-import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
-import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.view.Surface.ROTATION_0;
 import static android.view.Surface.ROTATION_90;
 
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
-import android.app.WindowConfiguration;
-import android.content.res.Configuration;
-import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 
-import org.junit.Assert;
+import androidx.annotation.NonNull;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.ArrayList;
-import java.util.List;
 import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.Predicate;
 
 /**
  * Test class for {@link TransparentPolicy}.
@@ -69,199 +46,238 @@
     @Test
     public void testNotStartingWhenDisabled() {
         runTestScenario((robot) -> {
-            robot.launchTransparentActivityInTask();
+            robot.transparentActivity((ta) -> {
+                ta.launchTransparentActivityInTask();
 
-            robot.checkTopActivityPolicyStateIsNotRunning();
+                ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ false);
+            });
         }, /* policyEnabled */ false);
     }
 
     @Test
     public void testNotStartingWithoutTask() {
         runTestScenario((robot) -> {
-            robot.launchTransparentActivity();
+            robot.transparentActivity((ta) -> {
+                ta.launchTransparentActivity();
 
-            robot.checkTopActivityPolicyStartNotInvoked();
-            robot.checkTopActivityPolicyStateIsNotRunning();
+                ta.checkTopActivityTransparentPolicyStartNotInvoked();
+                ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ false);
+            });
         });
     }
 
     @Test
     public void testPolicyRunningWhenTransparentIsUsed() {
         runTestScenario((robot) -> {
-            robot.launchTransparentActivityInTask();
+            robot.transparentActivity((ta) -> {
+                ta.launchTransparentActivityInTask();
 
-            robot.checkTopActivityPolicyStartNotInvoked();
-            robot.checkTopActivityPolicyStateIsRunning();
+                ta.checkTopActivityTransparentPolicyStartNotInvoked();
+                ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ true);
+            });
         });
     }
 
     @Test
     public void testCleanLetterboxConfigListenerWhenTranslucentIsDestroyed() {
         runTestScenario((robot) -> {
-            robot.launchTransparentActivityInTask();
-            robot.checkTopActivityPolicyStartNotInvoked();
-            robot.checkTopActivityPolicyStateIsRunning();
+            robot.transparentActivity((ta) -> {
+                ta.launchTransparentActivityInTask();
+                ta.checkTopActivityTransparentPolicyStartNotInvoked();
+                ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ true);
 
-            robot.clearInteractions();
-            robot.destroyTopActivity();
+                robot.clearInteractions();
+                ta.activity().destroyTopActivity();
 
-            robot.checkTopActivityPolicyStopInvoked();
-            robot.checkTopActivityPolicyStateIsNotRunning();
+                ta.checkTopActivityTransparentPolicyStopInvoked();
+                ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ false);
+            });
         });
     }
 
     @Test
     public void testApplyStrategyAgainWhenOpaqueIsDestroyed() {
         runTestScenario((robot) -> {
-            robot.launchOpaqueActivityInTask();
-            robot.checkTopActivityPolicyStateIsNotRunning();
+            robot.transparentActivity((ta) -> {
+                ta.launchOpaqueActivityInTask();
+                ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ false);
 
-            robot.launchTransparentActivityInTask();
-            robot.checkTopActivityPolicyStateIsRunning();
+                ta.launchTransparentActivityInTask();
+                ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ true);
 
-            robot.destroyActivity(/* fromTop */ 1);
-            robot.checkTopActivityPolicyStartInvoked();
+                ta.activity().destroyActivity(/* fromTop */ 1);
+                ta.checkTopActivityTransparentPolicyStartInvoked();
+            });
         });
     }
 
     @Test
     public void testResetOpaqueReferenceWhenOpaqueIsDestroyed() {
         runTestScenario((robot) -> {
-            robot.launchTransparentActivityInTask();
+            robot.transparentActivity((ta) -> {
+                ta.launchTransparentActivityInTask();
 
-            robot.clearInteractions();
-            robot.destroyActivity(/* fromTop */ 1);
+                robot.clearInteractions();
+                ta.activity().destroyActivity(/* fromTop */ 1);
 
-            robot.checkTopActivityPolicyStartInvoked();
-            robot.checkTopActivityPolicyStateIsNotRunning();
+                ta.checkTopActivityTransparentPolicyStartInvoked();
+                ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ false);
+            });
         });
     }
 
     @Test
     public void testNotApplyStrategyAgainWhenOpaqueIsNotDestroyed() {
         runTestScenario((robot) -> {
-            robot.launchOpaqueActivityInTask();
-            robot.checkTopActivityPolicyStateIsNotRunning();
+            robot.transparentActivity((ta) -> {
+                ta.launchOpaqueActivityInTask();
+                ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ false);
 
-            robot.launchTransparentActivityInTask();
-            robot.checkTopActivityPolicyStateIsRunning();
+                ta.launchTransparentActivityInTask();
+                ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ true);
 
-            robot.clearInteractions();
-            robot.checkTopActivityPolicyStopNotInvoked();
+                robot.clearInteractions();
+                ta.checkTopActivityTransparentPolicyStopNotInvoked();
+            });
         });
     }
 
     @Test
     public void testApplyStrategyToTranslucentActivities() {
         runTestScenario((robot) -> {
-            robot.configureTopActivity(/* minAspect */ 1.2f, /* maxAspect */ 1.5f,
-                    SCREEN_ORIENTATION_PORTRAIT, /* isUnresizable */ true);
-            robot.configureTopActivityIgnoreOrientationRequest(true);
-            robot.launchActivity(/* minAspect */ 1.1f, /* maxAspect */ 3f,
-                    SCREEN_ORIENTATION_LANDSCAPE, /* transparent */true, /* addToTask */true);
-            robot.checkTopActivityPolicyStateIsRunning();
-            robot.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
-            robot.checkTopOrientation(SCREEN_ORIENTATION_PORTRAIT);
-            robot.checkTopAspectRatios(/* minAspectRatio */ 1.2f, /* maxAspectRatio */ 1.5f);
+            robot.transparentActivity((ta) -> {
+                ta.applyOnActivity((a) -> {
+                    a.configureTopActivity(/* minAspect */ 1.2f, /* maxAspect */ 1.5f,
+                            SCREEN_ORIENTATION_PORTRAIT, /* isUnresizable */ true);
+                    a.configureTopActivityIgnoreOrientationRequest(true);
+                    a.launchActivity(/* minAspect */ 1.1f, /* maxAspect */ 3f,
+                            SCREEN_ORIENTATION_LANDSCAPE, /* transparent */true,
+                            /* withComponent */ false, /* addToTask */true);
+                });
+                ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ true);
+                ta.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
+                ta.applyOnActivity((a) -> {
+                    a.checkTopActivityConfigOrientation(SCREEN_ORIENTATION_PORTRAIT);
+                    a.checkTopActivityAspectRatios(/* minAspectRatio */ 1.2f,
+                            /* maxAspectRatio */ 1.5f);
+                });
+            });
         });
     }
 
     @Test
     public void testApplyStrategyToTransparentActivitiesRetainsWindowConfigurationProperties() {
         runTestScenario((robot) -> {
-            robot.launchTransparentActivity();
+            robot.transparentActivity((ta) -> {
+                ta.launchTransparentActivity();
 
-            robot.forceChangeInTopActivityConfiguration();
-            robot.attachTopActivityToTask();
+                ta.forceChangeInTopActivityConfiguration();
+                ta.activity().attachTopActivityToTask();
 
-            robot.checkTopActivityConfigurationConfiguration();
+                ta.checkTopActivityConfigurationConfiguration();
+            });
         });
     }
 
     @Test
     public void testApplyStrategyToMultipleTranslucentActivities() {
         runTestScenario((robot) -> {
-            robot.launchTransparentActivityInTask();
-            robot.checkTopActivityPolicyStateIsRunning();
-            robot.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
+            robot.transparentActivity((ta) -> {
+                ta.launchTransparentActivityInTask();
+                ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ true);
+                ta.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
 
-            robot.launchTransparentActivityInTask();
-            robot.checkTopActivityPolicyStateIsRunning();
-            robot.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 2);
+                ta.launchTransparentActivityInTask();
+                ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ true);
+                ta.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 2);
+            });
         });
     }
 
     @Test
     public void testNotApplyStrategyToTranslucentActivitiesOverEmbeddedActivities() {
         runTestScenario((robot) -> {
-            robot.configureTopActivityAsEmbedded();
-            robot.launchTransparentActivityInTask();
+            robot.transparentActivity((ta) -> {
+                ta.activity().setTopActivityAsEmbedded(true);
+                ta.launchTransparentActivityInTask();
 
-            robot.checkTopActivityPolicyStartNotInvoked();
-            robot.checkTopActivityPolicyStateIsNotRunning();
+                ta.checkTopActivityTransparentPolicyStartNotInvoked();
+                ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ false);
+            });
         });
     }
 
     @Test
     public void testTranslucentActivitiesDontGoInSizeCompatMode() {
         runTestScenario((robot) -> {
-            robot.configureTopActivityIgnoreOrientationRequest(true);
-            robot.configureUnresizableTopActivity(SCREEN_ORIENTATION_PORTRAIT);
-            robot.rotateDisplayForTopActivity(ROTATION_90);
-            robot.checkTopActivitySizeCompatMode(/* inScm */ true);
-            robot.rotateDisplayForTopActivity(ROTATION_0);
-            robot.checkTopActivitySizeCompatMode(/* inScm */ false);
+            robot.transparentActivity((ta) -> {
+                ta.applyOnActivity((a) -> {
+                    a.configureTopActivityIgnoreOrientationRequest(true);
+                    a.configureUnresizableTopActivity(SCREEN_ORIENTATION_PORTRAIT);
+                    a.rotateDisplayForTopActivity(ROTATION_90);
+                    a.checkTopActivityInSizeCompatMode(/* inScm */ true);
+                    a.rotateDisplayForTopActivity(ROTATION_0);
+                    a.checkTopActivityInSizeCompatMode(/* inScm */ false);
 
-            robot.launchTransparentActivityInTask();
-            robot.checkTopActivitySizeCompatMode(/* inScm */ false);
-            robot.rotateDisplayForTopActivity(ROTATION_90);
-            robot.checkTopActivitySizeCompatMode(/* inScm */ false);
+                    ta.launchTransparentActivityInTask();
+
+                    a.checkTopActivityInSizeCompatMode(/* inScm */ false);
+                    a.rotateDisplayForTopActivity(ROTATION_90);
+                    a.checkTopActivityInSizeCompatMode(/* inScm */ false);
+                });
+            });
         }, /* displayWidth */ 2800,  /* displayHeight */ 1400);
     }
 
     @Test
     public void testCheckOpaqueIsLetterboxedWhenStrategyIsApplied() {
         runTestScenario((robot) -> {
-            robot.configureUnresizableTopActivity(SCREEN_ORIENTATION_PORTRAIT);
-            robot.configureTopActivityIgnoreOrientationRequest(true);
-            robot.launchTransparentActivity();
+            robot.transparentActivity((ta) -> {
+                ta.applyOnActivity((a) -> {
+                    a.configureUnresizableTopActivity(SCREEN_ORIENTATION_PORTRAIT);
+                    a.configureTopActivityIgnoreOrientationRequest(true);
+                    ta.launchTransparentActivity();
 
-            robot.assertFalseOnTopActivity(ActivityRecord::fillsParent);
-            robot.assertTrueOnActivity(/* fromTop */ 1, ActivityRecord::fillsParent);
-            robot.applyTo(/* fromTop */ 1, (activity) -> {
-                activity.finishing = true;
+                    a.assertFalseOnTopActivity(ActivityRecord::fillsParent);
+                    a.assertTrueOnActivity(/* fromTop */ 1, ActivityRecord::fillsParent);
+                    a.applyToActivity(/* fromTop */ 1, (activity) -> {
+                        activity.finishing = true;
+                    });
+                    a.assertFalseOnActivity(/* fromTop */ 1, ActivityRecord::occludesParent);
+                    a.attachTopActivityToTask();
+
+                    ta.checkTopActivityTransparentPolicyStateIsRunning(/* running */ false);
+                });
             });
-            robot.assertFalseOnActivity(/* fromTop */ 1, ActivityRecord::occludesParent);
-            robot.attachTopActivityToTask();
-
-            robot.checkTopActivityPolicyStateIsNotRunning();
         });
     }
 
     @Test
     public void testTranslucentActivitiesWhenUnfolding() {
         runTestScenario((robot) -> {
-            robot.applyToTop((activity) -> {
-                activity.mWmService.mLetterboxConfiguration
-                        .setLetterboxHorizontalPositionMultiplier(1.0f);
+            robot.transparentActivity((ta) -> {
+                ta.applyOnActivity((a) -> {
+                    a.applyToTopActivity((topActivity) -> {
+                        topActivity.mWmService.mLetterboxConfiguration
+                                .setLetterboxHorizontalPositionMultiplier(1.0f);
+                    });
+                    a.configureUnresizableTopActivity(SCREEN_ORIENTATION_PORTRAIT);
+                    a.configureTopActivityIgnoreOrientationRequest(true);
+                    ta.launchTransparentActivityInTask();
+                    ta.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
+
+                    a.setTaskWindowingMode(WINDOWING_MODE_FULLSCREEN);
+                    a.configureTopActivityFoldablePosture(/* isHalfFolded */ true,
+                            /* isTabletop */ false);
+                    a.checkTopActivityRecomputedConfiguration();
+                    ta.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
+                    robot.clearInteractions();
+                    a.configureTopActivityFoldablePosture(/* isHalfFolded */ false,
+                            /* isTabletop */ false);
+                    a.checkTopActivityRecomputedConfiguration();
+                    ta.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
+                });
             });
-            robot.configureUnresizableTopActivity(SCREEN_ORIENTATION_PORTRAIT);
-            robot.configureTopActivityIgnoreOrientationRequest(true);
-            robot.launchTransparentActivityInTask();
-            robot.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
-
-            robot.configureTaskWindowingMode(WINDOWING_MODE_FULLSCREEN);
-
-            robot.configureTopActivityFoldablePosture(/* isHalfFolded */ true,
-                    /* isTabletop */ false);
-            robot.checkTopActivityRecomputedConfiguration();
-            robot.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
-            robot.clearInteractions();
-
-            robot.configureTopActivityFoldablePosture(/* isHalfFolded */ false,
-                    /* isTabletop */ false);
-            robot.checkTopActivityRecomputedConfiguration();
-            robot.checkTopActivityHasInheritedBoundsFrom(/* fromTop */ 1);
         }, /* displayWidth */ 2800,  /* displayHeight */ 1400);
     }
 
@@ -269,31 +285,28 @@
     @Test
     public void testTranslucentActivity_clearSizeCompatMode_inheritedCompatDisplayInsetsCleared() {
         runTestScenario((robot) -> {
-            robot.configureTopActivityIgnoreOrientationRequest(true);
-            robot.configureUnresizableTopActivity(SCREEN_ORIENTATION_PORTRAIT);
-            // Rotate to put activity in size compat mode.
-            robot.rotateDisplayForTopActivity(ROTATION_90);
-            robot.checkTopActivitySizeCompatMode(/* inScm */ true);
+            robot.transparentActivity((ta) -> {
+                ta.applyOnActivity((a) -> {
+                    a.configureTopActivityIgnoreOrientationRequest(true);
+                    a.configureUnresizableTopActivity(SCREEN_ORIENTATION_PORTRAIT);
+                    // Rotate to put activity in size compat mode.
+                    a.rotateDisplayForTopActivity(ROTATION_90);
+                    a.checkTopActivityInSizeCompatMode(/* inScm */ true);
 
-            robot.launchTransparentActivityInTask();
-            robot.assertNotNullOnTopActivity(ActivityRecord::getCompatDisplayInsets);
-            robot.applyToTop(ActivityRecord::clearSizeCompatMode);
-            robot.assertNullOnTopActivity(ActivityRecord::getCompatDisplayInsets);
+                    ta.launchTransparentActivityInTask();
+                    a.assertNotNullOnTopActivity(ActivityRecord::getCompatDisplayInsets);
+                    a.applyToTopActivity(ActivityRecord::clearSizeCompatMode);
+                    a.assertNullOnTopActivity(ActivityRecord::getCompatDisplayInsets);
+                });
+            });
         });
     }
 
     private void runTestScenario(Consumer<TransparentPolicyRobotTest> consumer,
                                  boolean policyEnabled, int displayWidth, int displayHeight) {
-        spyOn(mWm.mLetterboxConfiguration);
-        when(mWm.mLetterboxConfiguration.isTranslucentLetterboxingEnabled())
-                .thenReturn(policyEnabled);
-        final TestDisplayContent.Builder builder = new TestDisplayContent.Builder(mAtm,
-                displayWidth, displayHeight);
-        final Task task = new TaskBuilder(mSupervisor).setDisplay(builder.build())
-                .setCreateActivity(true).build();
-        final ActivityRecord opaqueActivity = task.getTopNonFinishingActivity();
-        final TransparentPolicyRobotTest robot = new TransparentPolicyRobotTest(mAtm, task,
-                opaqueActivity);
+        final TransparentPolicyRobotTest robot =
+                new TransparentPolicyRobotTest(mWm, mAtm, mSupervisor, displayWidth, displayHeight);
+        robot.conf().enableTranslucentPolicy(policyEnabled);
         consumer.accept(robot);
     }
 
@@ -314,324 +327,31 @@
 
     /**
      * Robot pattern implementation for TransparentPolicy
-     * TODO(b/344587983): Extract Robot to be reused in different test classes.
      */
-    private static class TransparentPolicyRobotTest {
+    private static class TransparentPolicyRobotTest extends AppCompatRobotBase {
 
-        private final ActivityTaskManagerService mAtm;
+        @NonNull
+        private final AppCompatTransparentActivityRobot mTransparentActivityRobot;
 
-        private final Task mTask;
-
-        private final ActivityStackTest mActivityStack;
-
-        private WindowConfiguration mTopActivityWindowConfiguration;
-
-        private TransparentPolicyRobotTest(ActivityTaskManagerService atm, Task task,
-                                           ActivityRecord opaqueActivity) {
-            mAtm = atm;
-            mTask = task;
-            mActivityStack = new ActivityStackTest();
-            mActivityStack.pushActivity(opaqueActivity);
-            spyOn(opaqueActivity.mTransparentPolicy);
+        private TransparentPolicyRobotTest(@NonNull WindowManagerService wm,
+                @NonNull ActivityTaskManagerService atm,
+                @NonNull ActivityTaskSupervisor supervisor,
+                int displayWidth, int displayHeight) {
+            super(wm, atm, supervisor, displayWidth, displayHeight);
+            mTransparentActivityRobot = new AppCompatTransparentActivityRobot(activity());
+            // We always create at least an opaque activity in a Task
+            activity().createNewTaskWithBaseActivity();
         }
 
-        void configureTopActivityAsEmbedded() {
-            final ActivityRecord topActivity = mActivityStack.top();
-            spyOn(topActivity);
-            doReturn(true).when(topActivity).isEmbedded();
-        }
-
-        private void launchActivity(float minAspectRatio, float maxAspectRatio,
-                                    @Configuration.Orientation int orientation, boolean transparent,
-                                    boolean addToTask) {
-            final ActivityBuilder activityBuilder = new ActivityBuilder(mAtm)
-                    .setScreenOrientation(orientation)
-                    .setLaunchedFromUid(mActivityStack.base().getUid());
-            if (transparent) {
-                activityBuilder.setActivityTheme(android.R.style.Theme_Translucent);
-            }
-            if (minAspectRatio >= 0) {
-                activityBuilder.setMinAspectRatio(minAspectRatio);
-            }
-            if (maxAspectRatio >= 0) {
-                activityBuilder.setMaxAspectRatio(maxAspectRatio);
-            }
-            final ActivityRecord newActivity = activityBuilder.build();
-            if (addToTask) {
-                mTask.addChild(newActivity);
-            }
-            spyOn(newActivity.mTransparentPolicy);
-            mActivityStack.pushActivity(newActivity);
-        }
-
-        void attachTopActivityToTask() {
-            mTask.addChild(mActivityStack.top());
-        }
-
-        void launchTransparentActivity() {
-            launchActivity(/*minAspectRatio */ -1, /* maxAspectRatio */ -1,
-                    SCREEN_ORIENTATION_PORTRAIT, /* transparent */ true,
-                    /* addToTask */ false);
-        }
-
-        void launchTransparentActivityInTask() {
-            launchActivity(/*minAspectRatio */ -1, /* maxAspectRatio */ -1,
-                    SCREEN_ORIENTATION_PORTRAIT, /* transparent */ true,
-                    /* addToTask */true);
-        }
-
-        void launchOpaqueActivityInTask() {
-            launchActivity(/*minAspectRatio */ -1, /* maxAspectRatio */ -1,
-                    SCREEN_ORIENTATION_PORTRAIT, /* transparent */ false,
-                    /* addToTask */true);
-        }
-
-        void destroyTopActivity() {
-            mActivityStack.top().removeImmediately();
-        }
-
-        void destroyActivity(int fromTop) {
-            mActivityStack.applyTo(/* fromTop */ fromTop, ActivityRecord::removeImmediately);
-        }
-
-        void forceChangeInTopActivityConfiguration() {
-            mActivityStack.applyToTop((activity) -> {
-                final Configuration requestedConfig = activity.getRequestedOverrideConfiguration();
-                mTopActivityWindowConfiguration = requestedConfig.windowConfiguration;
-                mTopActivityWindowConfiguration.setActivityType(ACTIVITY_TYPE_STANDARD);
-                mTopActivityWindowConfiguration.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
-                mTopActivityWindowConfiguration.setAlwaysOnTop(true);
-                activity.onRequestedOverrideConfigurationChanged(requestedConfig);
-            });
-        }
-
-        void checkTopActivityPolicyStateIsRunning() {
-            assertTrue(mActivityStack.top().mTransparentPolicy.isRunning());
-        }
-
-        void checkTopActivityPolicyStateIsNotRunning() {
-            assertFalse(mActivityStack.top().mTransparentPolicy.isRunning());
-        }
-
-        void checkTopActivityPolicyStopInvoked() {
-            verify(mActivityStack.top().mTransparentPolicy).stop();
-        }
-
-        void checkTopActivityPolicyStopNotInvoked() {
-            mActivityStack.applyToTop((activity) -> {
-                verify(activity.mTransparentPolicy, never()).stop();
-            });
-        }
-
-        void checkTopActivityPolicyStartInvoked() {
-            mActivityStack.applyToTop((activity) -> {
-                verify(activity.mTransparentPolicy).start();
-            });
-        }
-
-        void checkTopActivityPolicyStartNotInvoked() {
-            verify(mActivityStack.top().mTransparentPolicy, never()).start();
-        }
-
-        void assertTrueOnActivity(int fromTop, Predicate<ActivityRecord> predicate) {
-            mActivityStack.applyTo(fromTop, (activity) -> {
-                Assert.assertTrue(predicate.test(activity));
-            });
-        }
-
-        void assertFalseOnTopActivity(Predicate<ActivityRecord> predicate) {
-            Assert.assertFalse(predicate.test(mActivityStack.top()));
-        }
-
-        void assertFalseOnActivity(int fromTop, Predicate<ActivityRecord> predicate) {
-            mActivityStack.applyTo(fromTop, (activity) -> {
-                Assert.assertFalse(predicate.test(activity));
-            });
-        }
-
-        void assertNotNullOnTopActivity(Function<ActivityRecord, Object> getter) {
-            Assert.assertNotNull(getter.apply(mActivityStack.top()));
-        }
-
-        void assertNullOnTopActivity(Function<ActivityRecord, Object> getter) {
-            Assert.assertNull(getter.apply(mActivityStack.top()));
-        }
-
-        void checkTopActivityConfigurationConfiguration() {
-            mActivityStack.applyToTop((activity) -> {
-                // The original override of WindowConfiguration should keep.
-                assertEquals(ACTIVITY_TYPE_STANDARD, activity.getActivityType());
-                assertEquals(WINDOWING_MODE_MULTI_WINDOW,
-                        mTopActivityWindowConfiguration.getWindowingMode());
-                assertTrue(mTopActivityWindowConfiguration.isAlwaysOnTop());
-                // Unless display is going to be rotated, it should always inherit from parent.
-                assertEquals(ROTATION_UNDEFINED,
-                        mTopActivityWindowConfiguration.getDisplayRotation());
-            });
-        }
-
-        void checkTopActivityHasInheritedBoundsFrom(int fromTop) {
-            final ActivityRecord topActivity = mActivityStack.top();
-            final ActivityRecord otherActivity = mActivityStack.getFromTop(/* fromTop */ fromTop);
-            final Rect opaqueBounds = otherActivity.getConfiguration().windowConfiguration
-                    .getBounds();
-            final Rect translucentRequestedBounds = topActivity.getRequestedOverrideBounds();
-            Assert.assertEquals(opaqueBounds, translucentRequestedBounds);
-        }
-
-        void checkTopActivityRecomputedConfiguration() {
-            verify(mActivityStack.top()).recomputeConfiguration();
-        }
-
-        void checkTopOrientation(int orientation) {
-            Assert.assertEquals(orientation, mActivityStack.top()
-                    .getRequestedConfigurationOrientation());
-        }
-
-        void configureTaskWindowingMode(int windowingMode) {
-            mTask.setWindowingMode(windowingMode);
-        }
-
-        void checkTopAspectRatios(float minAspectRatio, float maxAspectRatio) {
-            final ActivityRecord topActivity = mActivityStack.top();
-            Assert.assertEquals(minAspectRatio, topActivity.getMinAspectRatio(), 0.0001);
-            Assert.assertEquals(maxAspectRatio, topActivity.getMaxAspectRatio(), 0.0001);
-        }
-
-        void checkTopActivitySizeCompatMode(boolean inScm) {
-            Assert.assertEquals(inScm, mActivityStack.top().inSizeCompatMode());
+        void transparentActivity(@NonNull Consumer<AppCompatTransparentActivityRobot> consumer) {
+            consumer.accept(mTransparentActivityRobot);
         }
 
         void clearInteractions() {
-            mActivityStack.applyToAll((activity) -> {
+            activity().applyToAllActivities((activity) -> {
                 clearInvocations(activity);
-                clearInvocations(activity.mTransparentPolicy);
+                clearInvocations(activity.mAppCompatController.getTransparentPolicy());
             });
         }
-
-        void configureTopActivity(float minAspect, float maxAspect, int screenOrientation,
-                                  boolean isUnresizable) {
-            prepareLimitedBounds(mActivityStack.top(), minAspect, maxAspect, screenOrientation,
-                    isUnresizable);
-        }
-
-        void configureTopActivityIgnoreOrientationRequest(boolean ignoreOrientationRequest) {
-            mActivityStack.top().mDisplayContent
-                    .setIgnoreOrientationRequest(ignoreOrientationRequest);
-        }
-
-        void configureUnresizableTopActivity(int screenOrientation) {
-            configureTopActivity(-1, -1, screenOrientation, true);
-        }
-
-        void applyToTop(Consumer<ActivityRecord> consumer) {
-            consumer.accept(mActivityStack.top());
-        }
-
-        void applyTo(int fromTop, Consumer<ActivityRecord> consumer) {
-            mActivityStack.applyTo(fromTop, consumer);
-        }
-
-        void rotateDisplayForTopActivity(int rotation) {
-            rotateDisplay(mActivityStack.top().mDisplayContent, rotation);
-        }
-
-        /**
-         * Setups activity with restriction on its bounds, such as maxAspect, minAspect,
-         * fixed orientation, and/or whether it is resizable.
-         */
-        void prepareLimitedBounds(ActivityRecord activity, float minAspect, float maxAspect,
-                                  int screenOrientation, boolean isUnresizable) {
-            activity.info.resizeMode = isUnresizable
-                    ? RESIZE_MODE_UNRESIZEABLE
-                    : RESIZE_MODE_RESIZEABLE;
-            final Task task = activity.getTask();
-            if (task != null) {
-                // Update the Task resize value as activity will follow the task.
-                task.mResizeMode = activity.info.resizeMode;
-                task.getRootActivity().info.resizeMode = activity.info.resizeMode;
-            }
-            activity.setVisibleRequested(true);
-            if (maxAspect >= 0) {
-                activity.info.setMaxAspectRatio(maxAspect);
-            }
-            if (minAspect >= 0) {
-                activity.info.setMinAspectRatio(minAspect);
-            }
-            if (screenOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
-                activity.info.screenOrientation = screenOrientation;
-                activity.setRequestedOrientation(screenOrientation);
-            }
-            // Make sure to use the provided configuration to construct the size compat fields.
-            activity.clearSizeCompatMode();
-            activity.ensureActivityConfiguration();
-            // Make sure the display configuration reflects the change of activity.
-            if (activity.mDisplayContent.updateOrientation()) {
-                activity.mDisplayContent.sendNewConfiguration();
-            }
-        }
-
-        void configureTopActivityFoldablePosture(boolean isHalfFolded, boolean isTabletop) {
-            mActivityStack.applyToTop((activity) -> {
-                final DisplayRotation r = activity.mDisplayContent.getDisplayRotation();
-                doReturn(isHalfFolded).when(r).isDisplaySeparatingHinge();
-                doReturn(false).when(r)
-                        .isDeviceInPosture(any(DeviceStateController.DeviceState.class),
-                                anyBoolean());
-                if (isHalfFolded) {
-                    doReturn(true).when(r)
-                            .isDeviceInPosture(DeviceStateController.DeviceState.HALF_FOLDED,
-                                    isTabletop);
-                }
-                activity.recomputeConfiguration();
-            });
-        }
-
-        private static void rotateDisplay(DisplayContent display, int rotation) {
-            final Configuration c = new Configuration();
-            display.getDisplayRotation().setRotation(rotation);
-            display.computeScreenConfiguration(c);
-            display.onRequestedOverrideConfigurationChanged(c);
-        }
-
-        /**
-         * Contains all the ActivityRecord launched in the test. This is different from what's in
-         * the Task because activities are added here even if not added to tasks.
-         */
-        private static class ActivityStackTest {
-            private final List<ActivityRecord> mActivities = new ArrayList<>();
-
-            void pushActivity(ActivityRecord activityRecord) {
-                mActivities.add(activityRecord);
-            }
-
-            void applyToTop(Consumer<ActivityRecord> consumer) {
-                consumer.accept(top());
-            }
-
-            ActivityRecord getFromTop(int fromTop) {
-                return mActivities.get(mActivities.size() - fromTop - 1);
-            }
-
-            ActivityRecord base() {
-                return mActivities.get(0);
-            }
-
-            ActivityRecord top() {
-                return mActivities.get(mActivities.size() - 1);
-            }
-
-            // Allows access to the activity at position beforeLast from the top.
-            // If fromTop = 0 the activity used is the top one.
-            void applyTo(int fromTop, Consumer<ActivityRecord> consumer) {
-                consumer.accept(getFromTop(fromTop));
-            }
-
-            void applyToAll(Consumer<ActivityRecord> consumer) {
-                for (int i = mActivities.size() - 1; i >= 0; i--) {
-                    consumer.accept(mActivities.get(i));
-                }
-            }
-        }
     }
 }
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 4ebbf49..a94b586 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -163,7 +163,7 @@
     @Test
     public void testAddChildSetsSurfacePosition() {
         reset(mTransaction);
-        try (MockSurfaceBuildingContainer top = new MockSurfaceBuildingContainer(mWm)) {
+        try (MockSurfaceBuildingContainer top = new MockSurfaceBuildingContainer(mDisplayContent)) {
             WindowContainer child = new WindowContainer(mWm);
             child.setBounds(1, 1, 10, 10);
 
@@ -266,7 +266,7 @@
     @Test
     public void testRemoveImmediatelyClearsLastSurfacePosition() {
         reset(mTransaction);
-        try (MockSurfaceBuildingContainer top = new MockSurfaceBuildingContainer(mWm)) {
+        try (MockSurfaceBuildingContainer top = new MockSurfaceBuildingContainer(mDisplayContent)) {
             final WindowContainer<WindowContainer> child1 = new WindowContainer(mWm);
             child1.setBounds(1, 1, 10, 10);
 
@@ -1827,8 +1827,9 @@
             implements AutoCloseable {
         private final SurfaceSession mSession = new SurfaceSession();
 
-        MockSurfaceBuildingContainer(WindowManagerService wm) {
-            super(wm);
+        MockSurfaceBuildingContainer(DisplayContent dc) {
+            super(dc.mWmService);
+            onDisplayChanged(dc);
         }
 
         static class MockSurfaceBuilder extends SurfaceControl.Builder {
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 24ebad6..fcf7a3f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -78,7 +78,6 @@
 import android.content.pm.ActivityInfo;
 import android.graphics.Rect;
 import android.os.Binder;
-import android.os.Bundle;
 import android.os.IBinder;
 import android.os.InputConfig;
 import android.os.Process;
@@ -94,7 +93,6 @@
 import android.util.MergedConfiguration;
 import android.view.ContentRecordingSession;
 import android.view.IWindow;
-import android.view.IWindowSession;
 import android.view.InputChannel;
 import android.view.InsetsSourceControl;
 import android.view.InsetsState;
@@ -265,69 +263,7 @@
     }
 
     @Test
-    public void testRelayoutExitingWindow_legacy() {
-        mSetFlagsRule.disableFlags(Flags.FLAG_WINDOW_SESSION_RELAYOUT_INFO);
-
-        final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, "appWin");
-        final WindowSurfaceController surfaceController = mock(WindowSurfaceController.class);
-        win.mWinAnimator.mSurfaceController = surfaceController;
-        win.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN;
-        doReturn(true).when(surfaceController).hasSurface();
-        spyOn(win.mTransitionController);
-        doReturn(true).when(win.mTransitionController).isShellTransitionsEnabled();
-        doReturn(true).when(win.mTransitionController).inTransition(
-                eq(win.mActivityRecord));
-        win.mViewVisibility = View.VISIBLE;
-        win.mHasSurface = true;
-        win.mActivityRecord.mAppStopped = true;
-        mWm.mWindowMap.put(win.mClient.asBinder(), win);
-        spyOn(mWm.mWindowPlacerLocked);
-        // Skip unnecessary operations of relayout.
-        doNothing().when(mWm.mWindowPlacerLocked).performSurfacePlacement(anyBoolean());
-        final int w = 100;
-        final int h = 200;
-        final ClientWindowFrames outFrames = new ClientWindowFrames();
-        final MergedConfiguration outConfig = new MergedConfiguration();
-        final SurfaceControl outSurfaceControl = new SurfaceControl();
-        final InsetsState outInsetsState = new InsetsState();
-        final InsetsSourceControl.Array outControls = new InsetsSourceControl.Array();
-        final Bundle outBundle = new Bundle();
-        mWm.relayoutWindow(win.mSession, win.mClient, win.mAttrs, w, h, View.GONE, 0, 0, 0,
-                outFrames, outConfig, outSurfaceControl, outInsetsState, outControls, outBundle);
-        // The window is in transition, so its destruction is deferred.
-        assertTrue(win.mAnimatingExit);
-        assertFalse(win.mDestroying);
-        assertTrue(win.mTransitionController.mAnimatingExitWindows.contains(win));
-
-        win.mAnimatingExit = false;
-        win.mViewVisibility = View.VISIBLE;
-        win.mActivityRecord.setVisibleRequested(false);
-        win.mActivityRecord.setVisible(false);
-        mWm.relayoutWindow(win.mSession, win.mClient, win.mAttrs, w, h, View.GONE, 0, 0, 0,
-                outFrames, outConfig, outSurfaceControl, outInsetsState, outControls, outBundle);
-        // Because the window is already invisible, it doesn't need to apply exiting animation
-        // and WMS#tryStartExitingAnimation() will destroy the surface directly.
-        assertFalse(win.mAnimatingExit);
-        assertFalse(win.mHasSurface);
-        assertNull(win.mWinAnimator.mSurfaceController);
-
-        // Invisible requested activity should not get the last config even if its view is visible.
-        mWm.relayoutWindow(win.mSession, win.mClient, win.mAttrs, w, h, View.VISIBLE, 0, 0, 0,
-                outFrames, outConfig, outSurfaceControl, outInsetsState, outControls, outBundle);
-        assertEquals(0, outConfig.getMergedConfiguration().densityDpi);
-        // Non activity window can still get the last config.
-        win.mActivityRecord = null;
-        win.fillClientWindowFramesAndConfiguration(outFrames, outConfig,
-                null /* outActivityWindowInfo*/, false /* useLatestConfig */,
-                true /* relayoutVisible */);
-        assertEquals(win.getConfiguration().densityDpi,
-                outConfig.getMergedConfiguration().densityDpi);
-    }
-
-    @Test
     public void testRelayoutExitingWindow() {
-        mSetFlagsRule.enableFlags(Flags.FLAG_WINDOW_SESSION_RELAYOUT_INFO);
-
         final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, "appWin");
         final WindowSurfaceController surfaceController = mock(WindowSurfaceController.class);
         win.mWinAnimator.mSurfaceController = surfaceController;
@@ -483,15 +419,8 @@
             win.mRelayoutSeq = 1;
             seq = 2;
         }
-        if (Flags.windowSessionRelayoutInfo()) {
-            mWm.relayoutWindow(win.mSession, win.mClient, newParams, 100, 200, View.VISIBLE, 0, seq,
-                    0, new WindowRelayoutResult());
-        } else {
-            mWm.relayoutWindow(win.mSession, win.mClient, newParams, 100, 200, View.VISIBLE, 0, seq,
-                    0, new ClientWindowFrames(), new MergedConfiguration(),
-                    new SurfaceControl(), new InsetsState(), new InsetsSourceControl.Array(),
-                    new Bundle());
-        }
+        mWm.relayoutWindow(win.mSession, win.mClient, newParams, 100, 200, View.VISIBLE, 0, seq,
+                0, new WindowRelayoutResult());
 
         ArgumentCaptor<Integer> changedFlags = ArgumentCaptor.forClass(Integer.class);
         ArgumentCaptor<Integer> changedPrivateFlags = ArgumentCaptor.forClass(Integer.class);
@@ -1364,70 +1293,8 @@
     }
 
     @Test
-    public void testRelayout_appWindowSendActivityWindowInfo_legacy() {
-        mSetFlagsRule.enableFlags(Flags.FLAG_ACTIVITY_WINDOW_INFO_FLAG);
-        mSetFlagsRule.disableFlags(Flags.FLAG_WINDOW_SESSION_RELAYOUT_INFO);
-
-        // Skip unnecessary operations of relayout.
-        spyOn(mWm.mWindowPlacerLocked);
-        doNothing().when(mWm.mWindowPlacerLocked).performSurfacePlacement(anyBoolean());
-
-        final Task task = createTask(mDisplayContent);
-        final WindowState win = createAppWindow(task, ACTIVITY_TYPE_STANDARD, "appWindow");
-        mWm.mWindowMap.put(win.mClient.asBinder(), win);
-
-        final int w = 100;
-        final int h = 200;
-        final ClientWindowFrames outFrames = new ClientWindowFrames();
-        final MergedConfiguration outConfig = new MergedConfiguration();
-        final SurfaceControl outSurfaceControl = new SurfaceControl();
-        final InsetsState outInsetsState = new InsetsState();
-        final InsetsSourceControl.Array outControls = new InsetsSourceControl.Array();
-        final Bundle outBundle = new Bundle();
-
-        final ActivityRecord activity = win.mActivityRecord;
-        final ActivityWindowInfo expectedInfo = new ActivityWindowInfo();
-        expectedInfo.set(true, new Rect(0, 0, 1000, 2000), new Rect(0, 0, 500, 2000));
-        doReturn(expectedInfo).when(activity).getActivityWindowInfo();
-        activity.setVisibleRequested(false);
-        activity.setVisible(false);
-
-        mWm.relayoutWindow(win.mSession, win.mClient, win.mAttrs, w, h, View.VISIBLE, 0, 0, 0,
-                outFrames, outConfig, outSurfaceControl, outInsetsState, outControls, outBundle);
-
-        // No latest reported value, so return empty when activity is invisible
-        final ActivityWindowInfo activityWindowInfo = outBundle.getParcelable(
-                IWindowSession.KEY_RELAYOUT_BUNDLE_ACTIVITY_WINDOW_INFO, ActivityWindowInfo.class);
-        assertEquals(new ActivityWindowInfo(), activityWindowInfo);
-
-        activity.setVisibleRequested(true);
-        activity.setVisible(true);
-
-        mWm.relayoutWindow(win.mSession, win.mClient, win.mAttrs, w, h, View.VISIBLE, 0, 0, 0,
-                outFrames, outConfig, outSurfaceControl, outInsetsState, outControls, outBundle);
-
-        // Report the latest when activity is visible.
-        final ActivityWindowInfo activityWindowInfo2 = outBundle.getParcelable(
-                IWindowSession.KEY_RELAYOUT_BUNDLE_ACTIVITY_WINDOW_INFO, ActivityWindowInfo.class);
-        assertEquals(expectedInfo, activityWindowInfo2);
-
-        expectedInfo.set(false, new Rect(0, 0, 1000, 2000), new Rect(0, 0, 1000, 2000));
-        activity.setVisibleRequested(false);
-        activity.setVisible(false);
-
-        mWm.relayoutWindow(win.mSession, win.mClient, win.mAttrs, w, h, View.VISIBLE, 0, 0, 0,
-                outFrames, outConfig, outSurfaceControl, outInsetsState, outControls, outBundle);
-
-        // Report the last reported value when activity is invisible.
-        final ActivityWindowInfo activityWindowInfo3 = outBundle.getParcelable(
-                IWindowSession.KEY_RELAYOUT_BUNDLE_ACTIVITY_WINDOW_INFO, ActivityWindowInfo.class);
-        assertEquals(activityWindowInfo2, activityWindowInfo3);
-    }
-
-    @Test
     public void testRelayout_appWindowSendActivityWindowInfo() {
         mSetFlagsRule.enableFlags(Flags.FLAG_ACTIVITY_WINDOW_INFO_FLAG);
-        mSetFlagsRule.enableFlags(Flags.FLAG_WINDOW_SESSION_RELAYOUT_INFO);
 
         // Skip unnecessary operations of relayout.
         spyOn(mWm.mWindowPlacerLocked);
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 ab4deca..d3504cc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -1725,26 +1725,41 @@
         assertTrue(optionsCaptor.getValue().getOriginalOptions().getTransientLaunch());
     }
 
+    @SuppressWarnings("GuardedBy")
     @Test
     public void testResumeTopsWhenLeavingPinned() {
-        final ActivityRecord record = makePipableActivity();
-        final Task rootTask = record.getRootTask();
+        final ActivityRecord home = new ActivityBuilder(mAtm).setTask(
+                mRootWindowContainer.getDefaultTaskDisplayArea().getRootHomeTask()).build();
+        final Task homeTask = home.getTask();
+        final ActivityRecord pipActivity = makePipableActivity();
 
-        clearInvocations(mWm.mAtmService.mRootWindowContainer);
         final WindowContainerTransaction t = new WindowContainerTransaction();
-        WindowContainerToken wct = rootTask.mRemoteToken.toWindowContainerToken();
-        t.setWindowingMode(wct, WINDOWING_MODE_PINNED);
+        t.setWindowingMode(pipActivity.getTask().mRemoteToken.toWindowContainerToken(),
+                WINDOWING_MODE_PINNED);
+        clearInvocations(homeTask);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
-        verify(mWm.mAtmService.mRootWindowContainer).resumeFocusedTasksTopActivities();
+        if (WindowOrganizerController.shouldApplyLifecycleEffectOnPipChange()) {
+            verify(homeTask).resumeTopActivityUncheckedLocked(any(), any(), anyBoolean());
+        } else {
+            verify(homeTask, never()).resumeTopActivityUncheckedLocked(any(), any(), anyBoolean());
+        }
 
-        clearInvocations(mWm.mAtmService.mRootWindowContainer);
+        // Undo the effect of legacy logic in RootWindowContainer#moveActivityToPinnedRootTask.
+        if (pipActivity.mWaitForEnteringPinnedMode) {
+            pipActivity.mWaitForEnteringPinnedMode = false;
+            pipActivity.setWindowingMode(WINDOWING_MODE_UNDEFINED);
+        }
+        assertFalse(pipActivity.isFocusable());
+
         // The token for the PIP root task may have changed when the task entered PIP mode, so do
         // not reuse the one from above.
-        final WindowContainerToken newToken =
-                record.getRootTask().mRemoteToken.toWindowContainerToken();
+        final Task pipTask = pipActivity.getTask();
+        final WindowContainerToken newToken = pipTask.mRemoteToken.toWindowContainerToken();
         t.setWindowingMode(newToken, WINDOWING_MODE_FULLSCREEN);
+        clearInvocations(pipTask);
         mWm.mAtmService.mWindowOrganizerController.applyTransaction(t);
-        verify(mWm.mAtmService.mRootWindowContainer).resumeFocusedTasksTopActivities();
+        assertTrue(pipActivity.isFocusable());
+        verify(pipTask).resumeTopActivityUncheckedLocked(any(), any(), anyBoolean());
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
index 059fed20..e6648da 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -340,54 +340,33 @@
     public void testComputeOomAdjFromActivities() {
         final ActivityRecord activity = createActivityRecord(mWpc);
         activity.setVisibleRequested(true);
-        final int[] callbackResult = { 0 };
-        final int visible = 1;
-        final int paused = 2;
-        final int stopping = 4;
-        final int other = 8;
-        final WindowProcessController.ComputeOomAdjCallback callback =
-                new WindowProcessController.ComputeOomAdjCallback() {
-            @Override
-            public void onVisibleActivity() {
-                callbackResult[0] |= visible;
-            }
-
-            @Override
-            public void onPausedActivity() {
-                callbackResult[0] |= paused;
-            }
-
-            @Override
-            public void onStoppingActivity(boolean finishing) {
-                callbackResult[0] |= stopping;
-            }
-
-            @Override
-            public void onOtherActivity() {
-                callbackResult[0] |= other;
-            }
-        };
 
         // onStartActivity should refresh the state immediately.
         mWpc.onStartActivity(0 /* topProcessState */, activity.info);
-        assertEquals(1 /* minTaskLayer */, mWpc.computeOomAdjFromActivities(callback));
-        assertEquals(visible, callbackResult[0]);
+        int flags = mWpc.getActivityStateFlags();
+        assertEquals(1 /* minTaskLayer */,
+                flags & WindowProcessController.ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER);
+        final int visibleFlags = WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE
+                | WindowProcessController.ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE
+                | WindowProcessController.ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK;
+        assertEquals(visibleFlags,
+                flags & ~WindowProcessController.ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER);
 
-        callbackResult[0] = 0;
         activity.setVisibleRequested(false);
         activity.setState(PAUSED, "test");
-        mWpc.computeOomAdjFromActivities(callback);
-        assertEquals(paused, callbackResult[0]);
+        final int exclusiveFlags = WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE
+                | WindowProcessController.ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED
+                | WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING;
+        flags = mWpc.getActivityStateFlags() & exclusiveFlags;
+        assertEquals(WindowProcessController.ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED, flags);
 
-        callbackResult[0] = 0;
         activity.setState(STOPPING, "test");
-        mWpc.computeOomAdjFromActivities(callback);
-        assertEquals(stopping, callbackResult[0]);
+        flags = mWpc.getActivityStateFlags() & exclusiveFlags;
+        assertEquals(WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING, flags);
 
-        callbackResult[0] = 0;
         activity.setState(STOPPED, "test");
-        mWpc.computeOomAdjFromActivities(callback);
-        assertEquals(other, callbackResult[0]);
+        flags = mWpc.getActivityStateFlags() & exclusiveFlags;
+        assertEquals(0, flags);
     }
 
     @Test
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 b152c3e..e13376b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -86,7 +86,6 @@
 import android.graphics.Matrix;
 import android.graphics.Point;
 import android.graphics.Rect;
-import android.os.Bundle;
 import android.os.IBinder;
 import android.os.InputConfig;
 import android.os.RemoteException;
@@ -114,7 +113,6 @@
 
 import com.android.server.testutils.StubTransaction;
 import com.android.server.wm.SensitiveContentPackages.PackageInfo;
-import com.android.window.flags.Flags;
 
 import org.junit.After;
 import org.junit.Test;
@@ -1369,67 +1367,7 @@
 
     @SetupWindows(addWindows = {W_INPUT_METHOD})
     @Test
-    public void testImeTargetChangeListener_OnImeTargetOverlayVisibilityChanged_legacy() {
-        mSetFlagsRule.disableFlags(Flags.FLAG_WINDOW_SESSION_RELAYOUT_INFO);
-
-        final TestImeTargetChangeListener listener = new TestImeTargetChangeListener();
-        mWm.mImeTargetChangeListener = listener;
-
-        // Scenario 1: test addWindow/relayoutWindow to add Ime layering overlay window as visible.
-        final WindowToken windowToken = createTestWindowToken(TYPE_APPLICATION_OVERLAY,
-                mDisplayContent);
-        final IWindow client = new TestIWindow();
-        final Session session = getTestSession();
-        final ClientWindowFrames outFrames = new ClientWindowFrames();
-        final MergedConfiguration outConfig = new MergedConfiguration();
-        final SurfaceControl outSurfaceControl = new SurfaceControl();
-        final InsetsState outInsetsState = new InsetsState();
-        final InsetsSourceControl.Array outControls = new InsetsSourceControl.Array();
-        final Bundle outBundle = new Bundle();
-        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
-                TYPE_APPLICATION_OVERLAY);
-        params.setTitle("imeLayeringTargetOverlay");
-        params.token = windowToken.token;
-        params.flags = FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM;
-
-        mWm.addWindow(session, client, params, View.VISIBLE, DEFAULT_DISPLAY,
-                0 /* userUd */, WindowInsets.Type.defaultVisible(), null, new InsetsState(),
-                new InsetsSourceControl.Array(), new Rect(), new float[1]);
-        mWm.relayoutWindow(session, client, params, 100, 200, View.VISIBLE, 0, 0, 0,
-                outFrames, outConfig, outSurfaceControl, outInsetsState, outControls, outBundle);
-        waitHandlerIdle(mWm.mH);
-
-        final WindowState imeLayeringTargetOverlay = mDisplayContent.getWindow(
-                w -> w.mClient.asBinder() == client.asBinder());
-        assertThat(imeLayeringTargetOverlay.isVisible()).isTrue();
-        assertThat(listener.mImeTargetToken).isEqualTo(client.asBinder());
-        assertThat(listener.mIsRemoved).isFalse();
-        assertThat(listener.mIsVisibleForImeTargetOverlay).isTrue();
-
-        // Scenario 2: test relayoutWindow to let the Ime layering target overlay window invisible.
-        mWm.relayoutWindow(session, client, params, 100, 200, View.GONE, 0, 0, 0,
-                outFrames, outConfig, outSurfaceControl, outInsetsState, outControls, outBundle);
-        waitHandlerIdle(mWm.mH);
-
-        assertThat(imeLayeringTargetOverlay.isVisible()).isFalse();
-        assertThat(listener.mImeTargetToken).isEqualTo(client.asBinder());
-        assertThat(listener.mIsRemoved).isFalse();
-        assertThat(listener.mIsVisibleForImeTargetOverlay).isFalse();
-
-        // Scenario 3: test removeWindow to remove the Ime layering target overlay window.
-        mWm.removeClientToken(session, client.asBinder());
-        waitHandlerIdle(mWm.mH);
-
-        assertThat(listener.mImeTargetToken).isEqualTo(client.asBinder());
-        assertThat(listener.mIsRemoved).isTrue();
-        assertThat(listener.mIsVisibleForImeTargetOverlay).isFalse();
-    }
-
-    @SetupWindows(addWindows = {W_INPUT_METHOD})
-    @Test
     public void testImeTargetChangeListener_OnImeTargetOverlayVisibilityChanged() {
-        mSetFlagsRule.enableFlags(Flags.FLAG_WINDOW_SESSION_RELAYOUT_INFO);
-
         final TestImeTargetChangeListener listener = new TestImeTargetChangeListener();
         mWm.mImeTargetChangeListener = listener;
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/CurrentTimeMillisSupplierFake.java b/services/tests/wmtests/src/com/android/server/wm/utils/CurrentTimeMillisSupplierFake.java
new file mode 100644
index 0000000..f4b2adb
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/utils/CurrentTimeMillisSupplierFake.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.utils;
+
+import java.util.function.LongSupplier;
+
+/**
+ * Fake {@link LongSupplier} implementation used in tests.
+ */
+public class CurrentTimeMillisSupplierFake implements LongSupplier {
+
+    private long mCurrenTimeMillis = System.currentTimeMillis();
+
+    /**
+     * @return The currentTimeMilles used in test
+     */
+    @Override
+    public long getAsLong() {
+        return mCurrenTimeMillis;
+    }
+
+    /**
+     * Simulate some time passed.
+     * @param delayInMillis The delay in milliseconds,
+     */
+    public void delay(long delayInMillis) {
+        mCurrenTimeMillis += delayInMillis;
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/TestComponentStack.java b/services/tests/wmtests/src/com/android/server/wm/utils/TestComponentStack.java
new file mode 100644
index 0000000..a06c0a2
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/utils/TestComponentStack.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.utils;
+
+import androidx.annotation.NonNull;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+
+/**
+ * Contains all the component created in the test.
+ */
+public class TestComponentStack<T> {
+
+    @NonNull
+    private final List<T> mItems = new ArrayList<>();
+
+    /**
+     * Adds an item to the stack.
+     *
+     * @param item The item to add.
+     */
+    public void push(@NonNull T item) {
+        mItems.add(item);
+    }
+
+    /**
+     * Consumes the top element of the stack.
+     *
+     * @param consumer Consumer for the optional top element.
+     * @throws IndexOutOfBoundsException In case that stack is empty.
+     */
+    public void applyToTop(@NonNull Consumer<T> consumer) {
+        consumer.accept(top());
+    }
+
+    /**
+     * Returns the item at fromTop position from the top one if present or it throws an
+     * exception if not present.
+     *
+     * @param fromTop The position from the top of the item to return.
+     * @return The returned item.
+     * @throws IndexOutOfBoundsException In case that position doesn't exist.
+     */
+    @NonNull
+    public T getFromTop(int fromTop) {
+        return mItems.get(mItems.size() - fromTop - 1);
+    }
+
+    /**
+     * @return The item at the base of the stack if present.
+     * @throws IndexOutOfBoundsException In case that stack is empty.
+     */
+    @NonNull
+    public T base() {
+        return mItems.get(0);
+    }
+
+    /**
+     * @return The item at the top of the stack if present.
+     * @throws IndexOutOfBoundsException In case that stack is empty.
+     */
+    @NonNull
+    public T top() {
+        return mItems.get(mItems.size() - 1);
+    }
+
+    /**
+     * @return {@code true} if the stack is empty.
+     */
+    public boolean isEmpty() {
+        return mItems.isEmpty();
+    }
+
+    /**
+     * Allows access to the item at position beforeLast from the top.
+     *
+     * @param fromTop  The position from the top of the item to return.
+     * @param consumer Consumer for the optional returned element.
+     */
+    public void applyTo(int fromTop, @NonNull Consumer<T> consumer) {
+        consumer.accept(getFromTop(fromTop));
+    }
+
+    /**
+     * Invoked the consumer iterating over all the elements in the stack.
+     *
+     * @param consumer Consumer for the elements.
+     */
+    public void applyToAll(@NonNull Consumer<T> consumer) {
+        for (int i = mItems.size() - 1; i >= 0; i--) {
+            consumer.accept(mItems.get(i));
+        }
+    }
+}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 27c383c..bf46154 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -113,6 +113,7 @@
 import com.android.server.IoThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.pm.UserManagerInternal;
 import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
 import com.android.server.utils.AlarmQueue;
 
@@ -1063,6 +1064,18 @@
         synchronized (mReportedEvents) {
             LinkedList<Event> events = mReportedEvents.get(userId);
             if (events == null) {
+                // TODO (b/347644400): callers of this API should verify that the userId passed to
+                // this method exists - there is currently a known case where USER_ALL is passed
+                // here and it would be added to the queue, never to be flushed correctly. The logic
+                // below should only remain as a last-resort catch-all fix.
+                final UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
+                if (umi == null || (umi != null && !umi.exists(userId))) {
+                    // The userId passed is a non-existent user so don't report the event.
+                    Slog.wtf(TAG, "Attempted to report event for non-existent user " + userId
+                            + " (" + event.mPackage + "/" + event.mClass
+                            + " eventType:" + event.mEventType + ")");
+                    return;
+                }
                 events = new LinkedList<>();
                 mReportedEvents.put(userId, events);
             }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index cfcc04b..89b9850 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -1165,7 +1165,7 @@
                 LocalServices.getService(PermissionManagerServiceInternal.class)
                         .setHotwordDetectionServiceProvider(() -> uid);
                 mIdentity = new HotwordDetectionServiceIdentity(uid, mVoiceInteractionServiceUid);
-                addServiceUidForAudioPolicy(uid);
+                addServiceUidForAudioPolicy(uid, mVoiceInteractionServiceUid);
             }
         }));
     }
@@ -1187,23 +1187,17 @@
         });
     }
 
-    private void addServiceUidForAudioPolicy(int uid) {
-        mScheduledExecutorService.execute(() -> {
-            AudioManagerInternal audioManager =
-                    LocalServices.getService(AudioManagerInternal.class);
-            if (audioManager != null) {
-                audioManager.addAssistantServiceUid(uid);
-            }
-        });
+    private void addServiceUidForAudioPolicy(int isolatedUid, int owningUid) {
+        AudioManagerInternal audioManager = LocalServices.getService(AudioManagerInternal.class);
+        if (audioManager != null) {
+            audioManager.addAssistantServiceUid(isolatedUid, owningUid);
+        }
     }
 
     private void removeServiceUidForAudioPolicy(int uid) {
-        mScheduledExecutorService.execute(() -> {
-            AudioManagerInternal audioManager =
-                    LocalServices.getService(AudioManagerInternal.class);
-            if (audioManager != null) {
-                audioManager.removeAssistantServiceUid(uid);
-            }
-        });
+        AudioManagerInternal audioManager = LocalServices.getService(AudioManagerInternal.class);
+        if (audioManager != null) {
+            audioManager.removeAssistantServiceUid(uid);
+        }
     }
 }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 1d01420..7e7a531 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -1055,15 +1055,22 @@
                 if (sessionArgs != null && sessionArgs.containsKey(csKey)) {
                     if (sessionArgs.getBoolean(csEnabledKey, true)) {
                         // If Contextual Search is enabled, try to follow that path.
-                        Intent launchIntent = getContextualSearchIntent(sessionArgs);
+                        Intent launchIntent;
+                        final long getSearchIntentCaller = Binder.clearCallingIdentity();
+                        try {
+                            launchIntent = getContextualSearchIntent(sessionArgs);
+                        } finally {
+                            Binder.restoreCallingIdentity(getSearchIntentCaller);
+                        }
                         if (launchIntent != null) {
                             // Hand over to contextual search helper.
                             Slog.d(TAG, "Handed over to contextual search helper.");
-                            final long caller = Binder.clearCallingIdentity();
+                            final int userId = Binder.getCallingUserHandle().getIdentifier();
+                            final long startSearchCaller = Binder.clearCallingIdentity();
                             try {
-                                return startContextualSearch(launchIntent);
+                                return startContextualSearch(launchIntent, userId);
                             } finally {
-                                Binder.restoreCallingIdentity(caller);
+                                Binder.restoreCallingIdentity(startSearchCaller);
                             }
                         }
                     }
@@ -2761,7 +2768,7 @@
         }
 
         @RequiresPermission(android.Manifest.permission.START_TASKS_FROM_RECENTS)
-        private boolean startContextualSearch(Intent launchIntent) {
+        private boolean startContextualSearch(Intent launchIntent, final int userId) {
             // Contextual search starts with a frozen screen - so we launch without
             // any system animations or starting window.
             final ActivityOptions opts = ActivityOptions.makeCustomTaskAnimation(mContext,
@@ -2769,7 +2776,7 @@
             opts.setDisableStartingWindow(true);
             int resultCode = mAtmInternal.startActivityWithScreenshot(launchIntent,
                     mContext.getPackageName(), Binder.getCallingUid(), Binder.getCallingPid(), null,
-                    opts.toBundle(), Binder.getCallingUserHandle().getIdentifier());
+                    opts.toBundle(), userId);
             return resultCode == ActivityManager.START_SUCCESS;
         }
 
diff --git a/telephony/common/android/telephony/LocationAccessPolicy.java b/telephony/common/android/telephony/LocationAccessPolicy.java
index d4b6c91..feea55b 100644
--- a/telephony/common/android/telephony/LocationAccessPolicy.java
+++ b/telephony/common/android/telephony/LocationAccessPolicy.java
@@ -32,6 +32,8 @@
 import android.util.Log;
 import android.widget.Toast;
 
+import com.android.internal.telephony.TelephonyPermissions;
+import com.android.internal.telephony.flags.Flags;
 import com.android.internal.telephony.util.TelephonyUtils;
 
 /**
@@ -310,10 +312,18 @@
         // This avoid breaking legacy code that rely on public-facing APIs to access cell location,
         // and it doesn't create an info leak risk because the cell location is stored in the phone
         // process anyway, and the system server already has location access.
-        if (query.callingUid == Process.PHONE_UID || query.callingUid == Process.SYSTEM_UID
-                || query.callingUid == Process.NETWORK_STACK_UID
-                || query.callingUid == Process.ROOT_UID) {
-            return LocationPermissionResult.ALLOWED;
+        if (Flags.supportPhoneUidCheckForMultiuser()) {
+            if (TelephonyPermissions.isSystemOrPhone(query.callingUid)
+                    || UserHandle.isSameApp(query.callingUid, Process.NETWORK_STACK_UID)
+                    || UserHandle.isSameApp(query.callingUid, Process.ROOT_UID)) {
+                return LocationPermissionResult.ALLOWED;
+            }
+        } else {
+            if (query.callingUid == Process.PHONE_UID || query.callingUid == Process.SYSTEM_UID
+                    || query.callingUid == Process.NETWORK_STACK_UID
+                    || query.callingUid == Process.ROOT_UID) {
+                return LocationPermissionResult.ALLOWED;
+            }
         }
 
         // Check the system-wide requirements. If the location main switch is off and the caller is
diff --git a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
index 0ddc38a..7ed26fb 100644
--- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
@@ -35,6 +35,7 @@
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.flags.Flags;
 
 import java.util.HashMap;
 import java.util.HashSet;
@@ -716,14 +717,15 @@
     }
 
     private static int getCarrierPrivilegeStatus(Context context, int subId, int uid) {
-        if (uid == Process.SYSTEM_UID || uid == Process.PHONE_UID) {
+        if (isSystemOrPhone(uid)) {
             // Skip the check if it's one of these special uids
             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
         }
+
         final long identity = Binder.clearCallingIdentity();
         try {
             TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(
-                Context.TELEPHONY_SERVICE);
+                    Context.TELEPHONY_SERVICE);
             return telephonyManager.createForSubscriptionId(subId).getCarrierPrivilegeStatus(uid);
         } finally {
             Binder.restoreCallingIdentity(identity);
@@ -926,4 +928,30 @@
                 || checkCallingOrSelfReadPhoneNumber(context, subId, callingPackage,
                 callingFeatureId, message));
     }
+
+    /**
+     * @return true if the specified {@code uid} is for a system or phone process, no matter if runs
+     * as system user or not.
+     */
+    public static boolean isSystemOrPhone(int uid) {
+        if (Flags.supportPhoneUidCheckForMultiuser()) {
+            return UserHandle.isSameApp(uid, Process.SYSTEM_UID) || UserHandle.isSameApp(uid,
+                    Process.PHONE_UID);
+        } else {
+            return uid == Process.SYSTEM_UID || uid == Process.PHONE_UID;
+        }
+    }
+
+    /**
+     * @return true if the specified {@code uid} is for a ROOT or SHELL process, no matter if runs
+     * as system user or not.
+     */
+    public static boolean isRootOrShell(int uid) {
+        if (Flags.supportPhoneUidCheckForMultiuser()) {
+            return UserHandle.isSameApp(uid, Process.ROOT_UID) || UserHandle.isSameApp(uid,
+                    Process.SHELL_UID);
+        } else {
+            return uid == Process.ROOT_UID || uid == Process.SHELL_UID;
+        }
+    }
 }
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 09cb464..61698db 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -9981,6 +9981,18 @@
             "carrier_roaming_satellite_default_services_int_array";
 
     /**
+     * Indicate whether carrier roaming to satellite is using ESOS (Emergency SOS) which connects
+     * to an emergency provider instead of PSAP (Public Safety Answering Point) for emergency
+     * messaging.
+     *
+     * This will need agreement with carriers before enabling this flag.
+     *
+     * The default value is false.
+     */
+    @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+    public static final String KEY_SATELLITE_ESOS_SUPPORTED_BOOL = "satellite_esos_supported_bool";
+
+    /**
      * Indicating whether DUN APN should be disabled when the device is roaming. In that case,
      * the default APN (i.e. internet) will be used for tethering.
      *
@@ -11137,6 +11149,7 @@
         sDefaults.putBoolean(KEY_EMERGENCY_MESSAGING_SUPPORTED_BOOL, false);
         sDefaults.putInt(KEY_EMERGENCY_CALL_TO_SATELLITE_T911_HANDOVER_TIMEOUT_MILLIS_INT,
                 (int) TimeUnit.SECONDS.toMillis(30));
+        sDefaults.putBoolean(KEY_SATELLITE_ESOS_SUPPORTED_BOOL, false);
         sDefaults.putString(KEY_DEFAULT_PREFERRED_APN_NAME_STRING, "");
         sDefaults.putBoolean(KEY_SUPPORTS_CALL_COMPOSER_BOOL, false);
         sDefaults.putBoolean(KEY_SUPPORTS_BUSINESS_CALL_COMPOSER_BOOL, false);
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 0ecafc7..019fb7b 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -49,6 +49,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
 import java.util.Locale;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -1285,6 +1286,13 @@
 
     private static final String SINGAPORE_ISO_COUNTRY_CODE = "SG";
 
+    private static final String[] COUNTRY_CODES_TO_FORMAT_NATIONALLY = new String[] {
+            "KR", // Korea
+            "JP", // Japan
+            "SG", // Singapore
+            "TW", // Taiwan
+    };
+
     /**
      * Breaks the given number down and formats it according to the rules
      * for the country the number is from.
@@ -1647,45 +1655,58 @@
             defaultCountryIso = defaultCountryIso.toUpperCase(Locale.ROOT);
         }
 
+        Rlog.v(LOG_TAG, "formatNumber: defaultCountryIso: " + defaultCountryIso);
+
         PhoneNumberUtil util = PhoneNumberUtil.getInstance();
         String result = null;
         try {
             PhoneNumber pn = util.parseAndKeepRawInput(phoneNumber, defaultCountryIso);
 
-            if (KOREA_ISO_COUNTRY_CODE.equalsIgnoreCase(defaultCountryIso) &&
-                    (pn.getCountryCode() == util.getCountryCodeForRegion(KOREA_ISO_COUNTRY_CODE)) &&
-                    (pn.getCountryCodeSource() ==
-                            PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN)) {
-                /**
-                 * Need to reformat any local Korean phone numbers (when the user is in Korea) with
-                 * country code to corresponding national format which would replace the leading
-                 * +82 with 0.
-                 */
-                result = util.format(pn, PhoneNumberUtil.PhoneNumberFormat.NATIONAL);
-            } else if (JAPAN_ISO_COUNTRY_CODE.equalsIgnoreCase(defaultCountryIso) &&
-                    pn.getCountryCode() == util.getCountryCodeForRegion(JAPAN_ISO_COUNTRY_CODE) &&
-                    (pn.getCountryCodeSource() ==
-                            PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN)) {
-                /**
-                 * Need to reformat Japanese phone numbers (when user is in Japan) with the national
-                 * dialing format.
-                 */
-                result = util.format(pn, PhoneNumberUtil.PhoneNumberFormat.NATIONAL);
-            } else if (Flags.removeCountryCodeFromLocalSingaporeCalls() &&
-                    (SINGAPORE_ISO_COUNTRY_CODE.equalsIgnoreCase(defaultCountryIso) &&
-                            pn.getCountryCode() ==
-                                    util.getCountryCodeForRegion(SINGAPORE_ISO_COUNTRY_CODE) &&
-                            (pn.getCountryCodeSource() ==
-                                    PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN))) {
-                /*
-                 * Need to reformat Singaporean phone numbers (when the user is in Singapore)
-                 * with the country code (+65) removed to comply with Singaporean regulations.
-                 */
-                result = util.format(pn, PhoneNumberUtil.PhoneNumberFormat.NATIONAL);
+            if (Flags.nationalCountryCodeFormattingForLocalCalls()) {
+                if (Arrays.asList(COUNTRY_CODES_TO_FORMAT_NATIONALLY).contains(defaultCountryIso)
+                        && pn.getCountryCode() == util.getCountryCodeForRegion(defaultCountryIso)
+                        && pn.getCountryCodeSource()
+                        == PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN) {
+                    return util.format(pn, PhoneNumberUtil.PhoneNumberFormat.NATIONAL);
+                } else {
+                    return util.formatInOriginalFormat(pn, defaultCountryIso);
+                }
             } else {
-                result = util.formatInOriginalFormat(pn, defaultCountryIso);
+                if (KOREA_ISO_COUNTRY_CODE.equalsIgnoreCase(defaultCountryIso) && (
+                        pn.getCountryCode() == util.getCountryCodeForRegion(KOREA_ISO_COUNTRY_CODE))
+                        && (pn.getCountryCodeSource()
+                        == PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN)) {
+                    /**
+                     * Need to reformat any local Korean phone numbers (when the user is in
+                     * Korea) with country code to corresponding national format which would
+                     * replace the leading +82 with 0.
+                     */
+                    result = util.format(pn, PhoneNumberUtil.PhoneNumberFormat.NATIONAL);
+                } else if (JAPAN_ISO_COUNTRY_CODE.equalsIgnoreCase(defaultCountryIso)
+                        && pn.getCountryCode() == util.getCountryCodeForRegion(
+                        JAPAN_ISO_COUNTRY_CODE) && (pn.getCountryCodeSource()
+                        == PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN)) {
+                    /**
+                     * Need to reformat Japanese phone numbers (when user is in Japan) with the
+                     * national dialing format.
+                     */
+                    result = util.format(pn, PhoneNumberUtil.PhoneNumberFormat.NATIONAL);
+                } else if (Flags.removeCountryCodeFromLocalSingaporeCalls() && (
+                        SINGAPORE_ISO_COUNTRY_CODE.equalsIgnoreCase(defaultCountryIso)
+                                && pn.getCountryCode() == util.getCountryCodeForRegion(
+                                SINGAPORE_ISO_COUNTRY_CODE) && (pn.getCountryCodeSource()
+                                == PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN))) {
+                    /*
+                     * Need to reformat Singaporean phone numbers (when the user is in Singapore)
+                     * with the country code (+65) removed to comply with Singaporean regulations.
+                     */
+                    result = util.format(pn, PhoneNumberUtil.PhoneNumberFormat.NATIONAL);
+                } else {
+                    result = util.formatInOriginalFormat(pn, defaultCountryIso);
+                }
             }
         } catch (NumberParseException e) {
+            if (DBG) log("formatNumber: NumberParseException caught " + e);
         }
         return result;
     }
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index 58488d1..1089602 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -274,6 +274,11 @@
     private final int mServiceCapabilities;
 
     /**
+     * Whether the carrier roaming to satellite is using ESOS for emergency messaging.
+     */
+    private final boolean mIsSatelliteESOSSupported;
+
+    /**
      * @hide
      *
      * @deprecated Use {@link SubscriptionInfo.Builder}.
@@ -400,6 +405,7 @@
         this.mIsOnlyNonTerrestrialNetwork = false;
         this.mServiceCapabilities = 0;
         this.mTransferStatus = 0;
+        this.mIsSatelliteESOSSupported = false;
     }
 
     /**
@@ -441,6 +447,7 @@
         this.mIsOnlyNonTerrestrialNetwork = builder.mIsOnlyNonTerrestrialNetwork;
         this.mServiceCapabilities = builder.mServiceCapabilities;
         this.mTransferStatus = builder.mTransferStatus;
+        this.mIsSatelliteESOSSupported = builder.mIsSatelliteESOSSupported;
     }
 
     /**
@@ -898,6 +905,19 @@
         return mIsOnlyNonTerrestrialNetwork;
     }
 
+
+    /**
+     * Checks if the subscription is supported ESOS over Carrier Roaming NB-IOT Satellite.
+     *
+     * @return {@code true} if the subscription supports ESOS over Carrier Roaming NB-IOT Satellite,
+     * {@code false} otherwise.
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+    public boolean isSatelliteESOSSupported() {
+        return mIsSatelliteESOSSupported;
+    }
+
     // TODO(b/316183370): replace @code with @link in javadoc after feature is released
     /**
      * Retrieves the service capabilities for the current subscription.
@@ -989,6 +1009,7 @@
                     .setServiceCapabilities(
                             SubscriptionManager.getServiceCapabilitiesSet(source.readInt()))
                     .setTransferStatus(source.readInt())
+                    .setSatelliteESOSSupported(source.readBoolean())
                     .build();
         }
 
@@ -1033,6 +1054,7 @@
         dest.writeBoolean(mIsOnlyNonTerrestrialNetwork);
         dest.writeInt(mServiceCapabilities);
         dest.writeInt(mTransferStatus);
+        dest.writeBoolean(mIsSatelliteESOSSupported);
     }
 
     @Override
@@ -1099,6 +1121,7 @@
                 + " serviceCapabilities=" + SubscriptionManager.getServiceCapabilitiesSet(
                 mServiceCapabilities).toString()
                 + " transferStatus=" + mTransferStatus
+                + " isSatelliteESOSSupported=" + mIsSatelliteESOSSupported
                 + "]";
     }
 
@@ -1126,7 +1149,8 @@
                 && mCountryIso.equals(that.mCountryIso) && mGroupOwner.equals(that.mGroupOwner)
                 && mIsOnlyNonTerrestrialNetwork == that.mIsOnlyNonTerrestrialNetwork
                 && mServiceCapabilities == that.mServiceCapabilities
-                && mTransferStatus == that.mTransferStatus;
+                && mTransferStatus == that.mTransferStatus
+                && mIsSatelliteESOSSupported == that.mIsSatelliteESOSSupported;
     }
 
     @Override
@@ -1136,7 +1160,7 @@
                 mCardString, mIsOpportunistic, mGroupUuid, mCountryIso, mCarrierId, mProfileClass,
                 mType, mGroupOwner, mAreUiccApplicationsEnabled, mPortIndex, mUsageSetting, mCardId,
                 mIsGroupDisabled, mIsOnlyNonTerrestrialNetwork, mServiceCapabilities,
-                mTransferStatus);
+                mTransferStatus, mIsSatelliteESOSSupported);
         result = 31 * result + Arrays.hashCode(mEhplmns);
         result = 31 * result + Arrays.hashCode(mHplmns);
         result = 31 * result + Arrays.hashCode(mNativeAccessRules);
@@ -1346,6 +1370,11 @@
          * Service capabilities bitmasks the subscription supports.
          */
         private int mServiceCapabilities = 0;
+        /**
+         * {@code true} if the subscription supports ESOS over Carrier Roaming NB-IOT Satellite.
+         * {@code false} otherwise.
+         */
+        private boolean mIsSatelliteESOSSupported = false;
 
         /**
          * Default constructor.
@@ -1392,6 +1421,7 @@
             mIsOnlyNonTerrestrialNetwork = info.mIsOnlyNonTerrestrialNetwork;
             mServiceCapabilities = info.mServiceCapabilities;
             mTransferStatus = info.mTransferStatus;
+            mIsSatelliteESOSSupported = info.mIsSatelliteESOSSupported;
         }
 
         /**
@@ -1828,6 +1858,21 @@
         }
 
         /**
+         * Set whether the subscription is supported ESOS over Carrier Roaming NB-IOT Satellite or
+         * not.
+         *
+         * @param isSatelliteESOSSupported {@code true} if the subscription supports ESOS over
+         * Carrier Roaming NB-IOT Satellite, {@code false} otherwise.
+         * @return The builder.
+         */
+        @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+        @NonNull
+        public Builder setSatelliteESOSSupported(boolean isSatelliteESOSSupported) {
+            mIsSatelliteESOSSupported = isSatelliteESOSSupported;
+            return this;
+        }
+
+        /**
          * Build the {@link SubscriptionInfo}.
          *
          * @return The {@link SubscriptionInfo} instance.
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 76b4e005..dea10b70 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1127,7 +1127,7 @@
      * <P>Type: INTEGER (int)</P>
      * @hide
      */
-    public static final String IS_NTN = SimInfo.COLUMN_IS_NTN;
+    public static final String IS_ONLY_NTN = SimInfo.COLUMN_IS_ONLY_NTN;
 
     /**
      * TelephonyProvider column name to identify service capabilities.
@@ -1167,6 +1167,16 @@
     public static final String SATELLITE_ENTITLEMENT_PLMNS =
             SimInfo.COLUMN_SATELLITE_ENTITLEMENT_PLMNS;
 
+    /**
+     * TelephonyProvider column name to indicate the satellite ESOS supported. The value of this
+     * column is set based on {@link CarrierConfigManager#KEY_SATELLITE_ESOS_SUPPORTED_BOOL}.
+     * By default, it's disabled.
+     * <P>Type: INTEGER (int)</P>
+     *
+     * @hide
+     */
+    public static final String SATELLITE_ESOS_SUPPORTED = SimInfo.COLUMN_SATELLITE_ESOS_SUPPORTED;
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = {"USAGE_SETTING_"},
@@ -2783,17 +2793,17 @@
         return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getActiveModemCount();
     }
 
-    /** @hide */
+    /**
+     * Puts phone ID and subscription ID into the {@code intent}.
+     *
+     * <p>If the subscription ID is not valid, only puts phone ID into the {@code intent}.
+     *
+     * @hide
+     */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId) {
         int subId = SubscriptionManager.getSubscriptionId(phoneId);
-        if (isValidSubscriptionId(subId)) {
-            putPhoneIdAndSubIdExtra(intent, phoneId, subId);
-        } else {
-            logd("putPhoneIdAndSubIdExtra: no valid subs");
-            intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
-            intent.putExtra(EXTRA_SLOT_INDEX, phoneId);
-        }
+        putPhoneIdAndMaybeSubIdExtra(intent, phoneId, subId);
     }
 
     /** @hide */
@@ -2806,6 +2816,23 @@
     }
 
     /**
+     * Puts phone ID and subscription ID into the {@code intent}.
+     *
+     * <p>If the subscription ID is not valid, only puts phone ID into the {@code intent}.
+     *
+     * @hide
+     */
+    public static void putPhoneIdAndMaybeSubIdExtra(Intent intent, int phoneId, int subId) {
+        if (isValidSubscriptionId(subId)) {
+            putPhoneIdAndSubIdExtra(intent, phoneId, subId);
+        } else {
+            if (VDBG) logd("putPhoneIdAndMaybeSubIdExtra: invalid subId");
+            intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
+            intent.putExtra(EXTRA_SLOT_INDEX, phoneId);
+        }
+    }
+
+    /**
      * Get visible subscription Id(s) of the currently active SIM(s).
      *
      * @return the list of subId's that are active,
diff --git a/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java b/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java
index eadb726..2b515c9 100644
--- a/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java
+++ b/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java
@@ -64,6 +64,14 @@
      * @hide
      */
     public static final int DEFAULT_DESTINATION_PORT = DESTINATION_PORT_ANY;
+    /**
+     * @hide
+     */
+    public static final int MAX_STRING_LENGTH = 256;
+    /**
+     * @hide
+     */
+    public static final int MAX_LIST_SIZE = 100;
 
     /**
      * Builder class for {@link VisualVoicemailSmsFilterSettings} objects.
@@ -82,11 +90,16 @@
         /**
          * Sets the client prefix for the visual voicemail SMS filter. The client prefix will appear
          * at the start of a visual voicemail SMS message, followed by a colon(:).
+         * @throws IllegalArgumentException if the string length is greater than 256 characters
          */
         public Builder setClientPrefix(String clientPrefix) {
             if (clientPrefix == null) {
                 throw new IllegalArgumentException("Client prefix cannot be null");
             }
+            if (clientPrefix.length() > MAX_STRING_LENGTH) {
+                throw new IllegalArgumentException("Client prefix cannot be greater than "
+                        + MAX_STRING_LENGTH + " characters");
+            }
             mClientPrefix = clientPrefix;
             return this;
         }
@@ -95,11 +108,25 @@
          * Sets the originating number allow list for the visual voicemail SMS filter. If the list
          * is not null only the SMS messages from a number in the list can be considered as a visual
          * voicemail SMS. Otherwise, messages from any address will be considered.
+         * @throws IllegalArgumentException if the size of the originatingNumbers list is greater
+         * than 100 elements
+         * @throws IllegalArgumentException if an element within the originatingNumbers list has
+         * a string length greater than 256
          */
         public Builder setOriginatingNumbers(List<String> originatingNumbers) {
             if (originatingNumbers == null) {
                 throw new IllegalArgumentException("Originating numbers cannot be null");
             }
+            if (originatingNumbers.size() > MAX_LIST_SIZE) {
+                throw new IllegalArgumentException("The originatingNumbers list size cannot be"
+                        + " greater than " + MAX_STRING_LENGTH + " elements");
+            }
+            for (String num : originatingNumbers) {
+                if (num != null && num.length() > MAX_STRING_LENGTH) {
+                    throw new IllegalArgumentException("Numbers within the originatingNumbers list"
+                            + " cannot be greater than" + MAX_STRING_LENGTH + " characters");
+                }
+            }
             mOriginatingNumbers = originatingNumbers;
             return this;
         }
diff --git a/telephony/java/android/telephony/satellite/ProvisionSubscriberId.aidl b/telephony/java/android/telephony/satellite/ProvisionSubscriberId.aidl
new file mode 100644
index 0000000..fe46db8
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/ProvisionSubscriberId.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2024, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.telephony.satellite;
+
+parcelable ProvisionSubscriberId;
diff --git a/telephony/java/android/telephony/satellite/ProvisionSubscriberId.java b/telephony/java/android/telephony/satellite/ProvisionSubscriberId.java
new file mode 100644
index 0000000..3e6f743
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/ProvisionSubscriberId.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.telephony.satellite;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.telephony.flags.Flags;
+
+import java.util.Objects;
+
+/**
+ * ProvisionSubscriberId
+ *
+ * Satellite Gateway client will use these subscriber ids to register with satellite gateway service
+ * which identify user subscription with unique subscriber ids. These subscriber ids can be any
+ * unique value like iccid, imsi or msisdn which is decided based upon carrier requirements.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+public final class ProvisionSubscriberId implements Parcelable {
+    /** provision subscriberId */
+    @NonNull
+    private String mSubscriberId;
+
+    /** carrier id */
+    private int mCarrierId;
+
+    /** apn */
+    private String mNiddApn;
+
+    /**
+     * @hide
+     */
+    public ProvisionSubscriberId(@NonNull String subscriberId, @NonNull int carrierId,
+            @NonNull String niddApn) {
+        this.mCarrierId = carrierId;
+        this.mSubscriberId = subscriberId;
+        this.mNiddApn = niddApn;
+    }
+
+    private ProvisionSubscriberId(Parcel in) {
+        readFromParcel(in);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeString(mSubscriberId);
+        out.writeInt(mCarrierId);
+        out.writeString(mNiddApn);
+    }
+
+    @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+    public static final @android.annotation.NonNull Creator<ProvisionSubscriberId> CREATOR =
+            new Creator<ProvisionSubscriberId>() {
+                @Override
+                public ProvisionSubscriberId createFromParcel(Parcel in) {
+                    return new ProvisionSubscriberId(in);
+                }
+
+                @Override
+                public ProvisionSubscriberId[] newArray(int size) {
+                    return new ProvisionSubscriberId[size];
+                }
+            };
+
+    /**
+     * @hide
+     */
+    @Override
+    @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * @return provision subscriberId.
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+    public String getSubscriberId() {
+        return mSubscriberId;
+    }
+
+    /**
+     * @return carrierId.
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+    public int getCarrierId() {
+        return mCarrierId;
+    }
+
+    /**
+     * @return niddApn.
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+    public String getNiddApn() {
+        return mNiddApn;
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append("SubscriberId:");
+        sb.append(mSubscriberId);
+        sb.append(",");
+
+        sb.append("CarrierId:");
+        sb.append(mCarrierId);
+        sb.append(",");
+
+        sb.append("NiddApn:");
+        sb.append(mNiddApn);
+        return sb.toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mSubscriberId, mCarrierId, mNiddApn);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ProvisionSubscriberId that = (ProvisionSubscriberId) o;
+        return mSubscriberId.equals(that.mSubscriberId) && mCarrierId
+                == that.mCarrierId && mNiddApn.equals(that.mNiddApn);
+    }
+
+    private void readFromParcel(Parcel in) {
+        mSubscriberId = in.readString();
+        mCarrierId = in.readInt();
+        mNiddApn = in.readString();
+    }
+}
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index 2a359cd..b518c60d 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -50,6 +50,7 @@
 import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
@@ -233,6 +234,29 @@
     public static final String KEY_NTN_SIGNAL_STRENGTH = "ntn_signal_strength";
 
     /**
+     * Bundle key to get the response from
+     * {@link #requestProvisionSubscriberIds(Executor, OutcomeReceiver)}.
+     * @hide
+     */
+    public static final String KEY_REQUEST_PROVISION_SUBSCRIBER_ID_TOKEN =
+            "request_provision_subscriber_id";
+
+    /**
+     * Bundle key to get the response from
+     * {@link #requestIsProvisioned(String, Executor, OutcomeReceiver)}.
+     * @hide
+     */
+    public static final String KEY_IS_SATELLITE_PROVISIONED = "request_is_satellite_provisioned";
+
+    /**
+     * Bundle key to get the response from
+     * {@link #provisionSatellite(List, Executor, OutcomeReceiver)}.
+     * @hide
+     */
+    public static final String KEY_PROVISION_SATELLITE_TOKENS = "provision_satellite";
+
+
+    /**
      * The request was successfully processed.
      */
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
@@ -371,6 +395,24 @@
     @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
     public static final int SATELLITE_RESULT_MODEM_TIMEOUT = 24;
 
+    /**
+     * Telephony framework needs to access the current location of the device to perform the
+     * request. However, location in the settings is disabled by users.
+     *
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+    public static final int SATELLITE_RESULT_LOCATION_DISABLED = 25;
+
+    /**
+     * Telephony framework needs to access the current location of the device to perform the
+     * request. However, Telephony fails to fetch the current location from location service.
+     *
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+    public static final int SATELLITE_RESULT_LOCATION_NOT_AVAILABLE = 26;
+
     /** @hide */
     @IntDef(prefix = {"SATELLITE_RESULT_"}, value = {
             SATELLITE_RESULT_SUCCESS,
@@ -397,7 +439,9 @@
             SATELLITE_RESULT_REQUEST_IN_PROGRESS,
             SATELLITE_RESULT_MODEM_BUSY,
             SATELLITE_RESULT_ILLEGAL_STATE,
-            SATELLITE_RESULT_MODEM_TIMEOUT
+            SATELLITE_RESULT_MODEM_TIMEOUT,
+            SATELLITE_RESULT_LOCATION_DISABLED,
+            SATELLITE_RESULT_LOCATION_NOT_AVAILABLE
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface SatelliteResult {}
@@ -2560,6 +2604,179 @@
         }
     }
 
+    /**
+     * Request to get list of prioritized satellite subscriber ids to be used for provision.
+     *
+     * Satellite Gateway client will use these subscriber ids to register with satellite gateway
+     * service which identify user subscription with unique subscriber ids. These subscriber ids
+     * can be any unique value like iccid, imsi or msisdn which is decided based upon carrier
+     * requirements.
+     *
+     * @param executor The executor on which the callback will be called.
+     * @param callback The callback object to which the result will be delivered.
+     * If successful, the callback returns a list of tokens sorted in ascending priority order index
+     * 0 has the highest priority. Otherwise, it returns an error with a SatelliteException.
+     *
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+    @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+    public void requestProvisionSubscriberIds(@NonNull @CallbackExecutor Executor executor,
+            @NonNull OutcomeReceiver<List<ProvisionSubscriberId>, SatelliteException> callback) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(callback);
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                ResultReceiver receiver = new ResultReceiver(null) {
+                    @Override
+                    protected void onReceiveResult(int resultCode, Bundle resultData) {
+                        if (resultCode == SATELLITE_RESULT_SUCCESS) {
+                            if (resultData.containsKey(KEY_REQUEST_PROVISION_SUBSCRIBER_ID_TOKEN)) {
+                                List<ProvisionSubscriberId> list =
+                                        Collections.singletonList(resultData.getParcelable(
+                                                KEY_REQUEST_PROVISION_SUBSCRIBER_ID_TOKEN,
+                                                ProvisionSubscriberId.class));
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onResult(list)));
+                            } else {
+                                loge("KEY_REQUEST_PROVISION_SUBSCRIBER_ID_TOKEN does not exist.");
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onError(new SatelliteException(
+                                                SATELLITE_RESULT_REQUEST_FAILED))));
+                            }
+                        } else {
+                            executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                    callback.onError(new SatelliteException(resultCode))));
+                        }
+                    }
+                };
+                telephony.requestProvisionSubscriberIds(receiver);
+            } else {
+                loge("requestProvisionSubscriberIds() invalid telephony");
+                executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+                        new SatelliteException(SATELLITE_RESULT_ILLEGAL_STATE))));
+            }
+        } catch (RemoteException ex) {
+            loge("requestProvisionSubscriberIds() RemoteException: " + ex);
+            executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+                    new SatelliteException(SATELLITE_RESULT_ILLEGAL_STATE))));
+        }
+    }
+
+    /**
+     * Request to get provisioned status for given a satellite subscriber id.
+     *
+     * @param satelliteSubscriberId Satellite subscriber id requiring provisioned status check.
+     * @param executor The executor on which the callback will be called.
+     * @param callback callback.
+     *
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+    @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+    public void requestIsProvisioned(@NonNull String satelliteSubscriberId,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
+        Objects.requireNonNull(satelliteSubscriberId);
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(callback);
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                ResultReceiver receiver = new ResultReceiver(null) {
+                    @Override
+                    protected void onReceiveResult(int resultCode, Bundle resultData) {
+                        if (resultCode == SATELLITE_RESULT_SUCCESS) {
+                            if (resultData.containsKey(KEY_SATELLITE_PROVISIONED)) {
+                                boolean isIsProvisioned =
+                                        resultData.getBoolean(KEY_SATELLITE_PROVISIONED);
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onResult(isIsProvisioned)));
+                            } else {
+                                loge("KEY_REQUEST_PROVISION_TOKENS does not exist.");
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onError(new SatelliteException(
+                                                SATELLITE_RESULT_REQUEST_FAILED))));
+                            }
+                        } else {
+                            executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                    callback.onError(new SatelliteException(resultCode))));
+                        }
+                    }
+                };
+                telephony.requestIsProvisioned(satelliteSubscriberId, receiver);
+            } else {
+                loge("requestIsSatelliteProvisioned() invalid telephony");
+                executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+                        new SatelliteException(SATELLITE_RESULT_ILLEGAL_STATE))));
+            }
+        } catch (RemoteException ex) {
+            loge("requestIsSatelliteProvisioned() RemoteException: " + ex);
+            executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+                    new SatelliteException(SATELLITE_RESULT_ILLEGAL_STATE))));
+        }
+    }
+
+    /**
+     * Deliver the list of provisioned satellite subscriber ids.
+     *
+     * @param list List of ProvisionSubscriberId.
+     * @param executor The executor on which the callback will be called.
+     * @param callback The callback object to which the result will be delivered.
+     *
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+    @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+    public void provisionSatellite(@NonNull List<ProvisionSubscriberId> list,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(callback);
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                ResultReceiver receiver = new ResultReceiver(null) {
+                    @Override
+                    protected void onReceiveResult(int resultCode, Bundle resultData) {
+                        if (resultCode == SATELLITE_RESULT_SUCCESS) {
+                            if (resultData.containsKey(KEY_PROVISION_SATELLITE_TOKENS)) {
+                                boolean isUpdated =
+                                        resultData.getBoolean(KEY_PROVISION_SATELLITE_TOKENS);
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onResult(isUpdated)));
+                            } else {
+                                loge("KEY_REQUEST_PROVISION_TOKENS does not exist.");
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onError(new SatelliteException(
+                                                SATELLITE_RESULT_REQUEST_FAILED))));
+                            }
+                        } else {
+                            executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                    callback.onError(new SatelliteException(resultCode))));
+                        }
+                    }
+                };
+                telephony.provisionSatellite(list, receiver);
+            } else {
+                loge("provisionSatellite() invalid telephony");
+                executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+                        new SatelliteException(SATELLITE_RESULT_ILLEGAL_STATE))));
+            }
+        } catch (RemoteException ex) {
+            loge("provisionSatellite() RemoteException: " + ex);
+            executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+                    new SatelliteException(SATELLITE_RESULT_ILLEGAL_STATE))));
+        }
+    }
+
     @Nullable
     private static ITelephony getITelephony() {
         ITelephony binder = ITelephony.Stub.asInterface(TelephonyFrameworkInitializer
diff --git a/telephony/java/android/telephony/satellite/stub/ProvisionSubscriberId.aidl b/telephony/java/android/telephony/satellite/stub/ProvisionSubscriberId.aidl
new file mode 100644
index 0000000..2dc8ffb
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/stub/ProvisionSubscriberId.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.telephony.satellite.stub;
+
+/**
+ * {@hide}
+ */
+parcelable ProvisionSubscriberId {
+    /** provision subscriberId */
+    String subscriberId;
+
+    /** carrier id */
+    int mCarrierId;
+}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 9b01b71..7be52ea 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -78,6 +78,7 @@
 import android.telephony.satellite.NtnSignalStrength;
 import android.telephony.satellite.SatelliteCapabilities;
 import android.telephony.satellite.SatelliteDatagram;
+import android.telephony.satellite.ProvisionSubscriberId;
 import com.android.ims.internal.IImsServiceFeatureCallback;
 import com.android.internal.telephony.CellNetworkScanResult;
 import com.android.internal.telephony.IBooleanConsumer;
@@ -3400,4 +3401,38 @@
      * @hide
      */
     void requestSatelliteSessionStats(int subId, in ResultReceiver receiver);
+
+    /**
+     * Request to get list of prioritized satellite subscriber ids to be used for provision.
+     *
+     * @param result The result receiver, which returns the list of prioritized satellite tokens
+     * to be used for provision if the request is successful or an error code if the request failed.
+     * @hide
+     */
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    void requestProvisionSubscriberIds(in ResultReceiver receiver);
+
+    /**
+     * Request to get provisioned status for given a satellite subscriber id.
+     *
+     * @param satelliteSubscriberId Satellite subscriber id requiring provisioned status check.
+     * @param result The result receiver, which returns the provisioned status of the token if the
+     * request is successful or an error code if the request failed.
+     * @hide
+     */
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    void requestIsProvisioned(in String satelliteSubscriberId, in ResultReceiver result);
+
+    /**
+     * Deliver the list of provisioned satellite subscriber ids.
+     *
+     * @param list List of provisioned satellite subscriber ids.
+     * @param result The result receiver that returns whether deliver success or fail.
+     * @hide
+     */
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    void provisionSatellite(in List<ProvisionSubscriberId> list, in ResultReceiver result);
 }
diff --git a/test-mock/Android.bp b/test-mock/Android.bp
index e29d321..5976657 100644
--- a/test-mock/Android.bp
+++ b/test-mock/Android.bp
@@ -51,10 +51,8 @@
 
 java_library {
     name: "android.test.mock.ravenwood",
+    defaults: ["ravenwood-internal-only-visibility-java"],
     srcs: [":android-test-mock-sources"],
-    visibility: [
-        "//frameworks/base",
-    ],
 }
 
 android_ravenwood_test {
diff --git a/tests/Input/assets/testPointerStrokeStyle.png b/tests/Input/assets/testPointerStrokeStyle.png
new file mode 100644
index 0000000..4ddde70
--- /dev/null
+++ b/tests/Input/assets/testPointerStrokeStyle.png
Binary files differ
diff --git a/tests/Input/res/drawable/test_key_drawable.xml b/tests/Input/res/drawable/test_key_drawable.xml
new file mode 100644
index 0000000..2addf8f
--- /dev/null
+++ b/tests/Input/res/drawable/test_key_drawable.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <corners android:radius="4dp" />
+    <solid android:color="#ffffffff"/>
+</shape>
\ No newline at end of file
diff --git a/tests/Input/res/drawable/test_modifier_drawable.xml b/tests/Input/res/drawable/test_modifier_drawable.xml
new file mode 100644
index 0000000..2addf8f
--- /dev/null
+++ b/tests/Input/res/drawable/test_modifier_drawable.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <corners android:radius="4dp" />
+    <solid android:color="#ffffffff"/>
+</shape>
\ No newline at end of file
diff --git a/tests/Input/res/xml/keyboard_glyph_maps.xml b/tests/Input/res/xml/keyboard_glyph_maps.xml
new file mode 100644
index 0000000..d0616ff
--- /dev/null
+++ b/tests/Input/res/xml/keyboard_glyph_maps.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<keyboard-glyph-maps xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+    <keyboard-glyph-map
+        androidprv:glyphMap="@xml/test_glyph_map"
+        androidprv:vendorId="0x1234"
+        androidprv:productId="0x3456" />
+</keyboard-glyph-maps>
\ No newline at end of file
diff --git a/tests/Input/res/xml/test_glyph_map.xml b/tests/Input/res/xml/test_glyph_map.xml
new file mode 100644
index 0000000..7a7c1ac
--- /dev/null
+++ b/tests/Input/res/xml/test_glyph_map.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<keyboard-glyph-map xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+    <key-glyph
+        androidprv:keycode="KEYCODE_BACK"
+        androidprv:glyphDrawable="@drawable/test_key_drawable" />
+    <modifier-glyph
+        androidprv:modifier="META"
+        androidprv:glyphDrawable="@drawable/test_modifier_drawable" />
+    <function-row-key androidprv:keycode="KEYCODE_EMOJI_PICKER" />
+    <hardware-defined-shortcut
+        androidprv:keycode="KEYCODE_1"
+        androidprv:modifierState="FUNCTION"
+        androidprv:outKeycode="KEYCODE_BACK" />
+    <hardware-defined-shortcut
+        androidprv:keycode="KEYCODE_2"
+        androidprv:modifierState="FUNCTION|META"
+        androidprv:outKeycode="KEYCODE_HOME" />
+</keyboard-glyph-map>
\ No newline at end of file
diff --git a/tests/Input/src/com/android/server/input/KeyboardGlyphManagerTests.kt b/tests/Input/src/com/android/server/input/KeyboardGlyphManagerTests.kt
new file mode 100644
index 0000000..c073c7a
--- /dev/null
+++ b/tests/Input/src/com/android/server/input/KeyboardGlyphManagerTests.kt
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.input
+
+import android.content.Context
+import android.content.ContextWrapper
+import android.content.pm.ActivityInfo
+import android.content.pm.ApplicationInfo
+import android.content.pm.PackageManager
+import android.content.pm.ResolveInfo
+import android.content.pm.ServiceInfo
+import android.hardware.input.IInputManager
+import android.hardware.input.InputManager
+import android.hardware.input.InputManagerGlobal
+import android.hardware.input.KeyGlyphMap.KeyCombination
+import android.os.Bundle
+import android.os.test.TestLooper
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.annotations.Presubmit
+import android.platform.test.flag.junit.SetFlagsRule
+import android.view.InputDevice
+import android.view.KeyEvent
+import androidx.test.core.app.ApplicationProvider
+import com.android.hardware.input.Flags
+import com.android.test.input.R
+import org.junit.After
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertNull
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.junit.MockitoJUnit
+
+/**
+ * Tests for custom keyboard glyph map configuration.
+ *
+ * Build/Install/Run:
+ * atest InputTests:KeyboardGlyphManagerTests
+ */
+@Presubmit
+class KeyboardGlyphManagerTests {
+
+    companion object {
+        const val DEVICE_ID = 1
+        const val VENDOR_ID = 0x1234
+        const val PRODUCT_ID = 0x3456
+        const val PACKAGE_NAME = "KeyboardLayoutManagerTests"
+        const val RECEIVER_NAME = "DummyReceiver"
+    }
+
+    @JvmField
+    @Rule(order = 0)
+    val setFlagsRule = SetFlagsRule()
+
+    @JvmField
+    @Rule(order = 1)
+    val mockitoRule = MockitoJUnit.rule()!!
+
+    @Mock
+    private lateinit var packageManager: PackageManager
+
+    @Mock
+    private lateinit var iInputManager: IInputManager
+
+    private lateinit var keyboardGlyphManager: KeyboardGlyphManager
+    private lateinit var context: Context
+    private lateinit var testLooper: TestLooper
+    private lateinit var inputManagerGlobalSession: InputManagerGlobal.TestSession
+    private lateinit var keyboardDevice: InputDevice
+
+    @Before
+    fun setup() {
+        context = Mockito.spy(ContextWrapper(ApplicationProvider.getApplicationContext()))
+        inputManagerGlobalSession = InputManagerGlobal.createTestSession(iInputManager)
+        testLooper = TestLooper()
+        keyboardGlyphManager = KeyboardGlyphManager(context, testLooper.looper)
+
+        setupInputDevices()
+        setupBroadcastReceiver()
+        keyboardGlyphManager.systemRunning()
+        testLooper.dispatchAll()
+    }
+
+    @After
+    fun tearDown() {
+        if (this::inputManagerGlobalSession.isInitialized) {
+            inputManagerGlobalSession.close()
+        }
+    }
+
+    private fun setupInputDevices() {
+        val inputManager = InputManager(context)
+        Mockito.`when`(context.getSystemService(Mockito.eq(Context.INPUT_SERVICE)))
+            .thenReturn(inputManager)
+
+        keyboardDevice = createKeyboard(DEVICE_ID, VENDOR_ID, PRODUCT_ID, 0, "", "")
+        Mockito.`when`(iInputManager.inputDeviceIds).thenReturn(intArrayOf(DEVICE_ID))
+        Mockito.`when`(iInputManager.getInputDevice(DEVICE_ID)).thenReturn(keyboardDevice)
+    }
+
+    private fun setupBroadcastReceiver() {
+        Mockito.`when`(context.packageManager).thenReturn(packageManager)
+
+        val info = createMockReceiver()
+        Mockito.`when`(packageManager.queryBroadcastReceiversAsUser(Mockito.any(), Mockito.anyInt(),
+            Mockito.anyInt())).thenReturn(listOf(info))
+        Mockito.`when`(packageManager.getReceiverInfo(Mockito.any(), Mockito.anyInt()))
+            .thenReturn(info.activityInfo)
+
+        val resources = context.resources
+        Mockito.`when`(
+            packageManager.getResourcesForApplication(
+                Mockito.any(
+                    ApplicationInfo::class.java
+                )
+            )
+        ).thenReturn(resources)
+    }
+
+    private fun createMockReceiver(): ResolveInfo {
+        val info = ResolveInfo()
+        info.activityInfo = ActivityInfo()
+        info.activityInfo.packageName = PACKAGE_NAME
+        info.activityInfo.name = RECEIVER_NAME
+        info.activityInfo.applicationInfo = ApplicationInfo()
+        info.activityInfo.metaData = Bundle()
+        info.activityInfo.metaData.putInt(
+            InputManager.META_DATA_KEYBOARD_GLYPH_MAPS,
+            R.xml.keyboard_glyph_maps
+        )
+        info.serviceInfo = ServiceInfo()
+        info.serviceInfo.packageName = PACKAGE_NAME
+        info.serviceInfo.name = RECEIVER_NAME
+        return info
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_KEYBOARD_GLYPH_MAP)
+    fun testGlyphMapsLoaded() {
+        assertNotNull(
+            "Glyph map for test keyboard(deviceId=$DEVICE_ID) must exist",
+            keyboardGlyphManager.getKeyGlyphMap(DEVICE_ID)
+        )
+        assertNull(
+            "Glyph map for non-existing keyboard must be null",
+            keyboardGlyphManager.getKeyGlyphMap(-2)
+        )
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_KEYBOARD_GLYPH_MAP)
+    fun testGlyphMapCorrectlyLoaded() {
+        val glyphMap = keyboardGlyphManager.getKeyGlyphMap(DEVICE_ID)
+        // Test glyph map used in this test: {@see test_glyph_map.xml}
+        assertNotNull(glyphMap!!.getDrawableForKeycode(context, KeyEvent.KEYCODE_BACK))
+
+        assertNotNull(glyphMap.getDrawableForModifier(context, KeyEvent.KEYCODE_META_LEFT))
+        assertNotNull(glyphMap.getDrawableForModifier(context, KeyEvent.KEYCODE_META_RIGHT))
+
+        val functionRowKeys = glyphMap.functionRowKeys
+        assertEquals(1, functionRowKeys.size)
+        assertEquals(KeyEvent.KEYCODE_EMOJI_PICKER, functionRowKeys[0])
+
+        val hardwareShortcuts = glyphMap.hardwareShortcuts
+        assertEquals(2, hardwareShortcuts.size)
+        assertEquals(
+            KeyEvent.KEYCODE_BACK,
+            hardwareShortcuts[KeyCombination(KeyEvent.META_FUNCTION_ON, KeyEvent.KEYCODE_1)]
+        )
+        assertEquals(
+            KeyEvent.KEYCODE_HOME,
+            hardwareShortcuts[
+                KeyCombination(
+                    KeyEvent.META_FUNCTION_ON or KeyEvent.META_META_ON,
+                    KeyEvent.KEYCODE_2
+                )
+            ]
+        )
+    }
+}
diff --git a/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt b/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
index 93f97cb..301c0e6 100644
--- a/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
@@ -58,7 +58,7 @@
 import java.io.IOException
 import java.io.InputStream
 
-private fun createKeyboard(
+fun createKeyboard(
     deviceId: Int,
     vendorId: Int,
     productId: Int,
diff --git a/tests/Input/src/com/android/test/input/PointerIconLoadingTest.kt b/tests/Input/src/com/android/test/input/PointerIconLoadingTest.kt
index d196b85..e0f8c6d 100644
--- a/tests/Input/src/com/android/test/input/PointerIconLoadingTest.kt
+++ b/tests/Input/src/com/android/test/input/PointerIconLoadingTest.kt
@@ -88,6 +88,35 @@
         theme.applyStyle(
             PointerIcon.vectorFillStyleToResource(PointerIcon.POINTER_ICON_VECTOR_STYLE_FILL_GREEN),
             /* force= */ true)
+        theme.applyStyle(PointerIcon.vectorStrokeStyleToResource(
+            PointerIcon.POINTER_ICON_VECTOR_STYLE_STROKE_WHITE), /* force= */ true)
+
+        val pointerIcon =
+            PointerIcon.getLoadedSystemIcon(
+                ContextThemeWrapper(context, theme),
+                PointerIcon.TYPE_ARROW,
+                /* useLargeIcons= */ false,
+                /* pointerScale= */ 1f)
+
+        pointerIcon.getBitmap().assertAgainstGolden(
+            screenshotRule,
+            testName.methodName,
+            exactScreenshotMatcher
+        )
+    }
+
+    @Test
+    fun testPointerStrokeStyle() {
+        assumeTrue(enableVectorCursors())
+        assumeTrue(enableVectorCursorA11ySettings())
+
+        val theme: Resources.Theme = context.getResources().newTheme()
+        theme.setTo(context.getTheme())
+        theme.applyStyle(
+            PointerIcon.vectorFillStyleToResource(PointerIcon.POINTER_ICON_VECTOR_STYLE_FILL_BLACK),
+            /* force= */ true)
+        theme.applyStyle(PointerIcon.vectorStrokeStyleToResource(
+            PointerIcon.POINTER_ICON_VECTOR_STYLE_STROKE_BLACK), /* force= */ true)
 
         val pointerIcon =
             PointerIcon.getLoadedSystemIcon(
diff --git a/tests/Input/src/com/android/test/input/UnresponsiveGestureMonitorActivity.kt b/tests/Input/src/com/android/test/input/UnresponsiveGestureMonitorActivity.kt
index 63782f1..1842f0a 100644
--- a/tests/Input/src/com/android/test/input/UnresponsiveGestureMonitorActivity.kt
+++ b/tests/Input/src/com/android/test/input/UnresponsiveGestureMonitorActivity.kt
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+// InputMonitor is deprecated, but we still need to test it.
+@file:Suppress("DEPRECATION")
+
 package com.android.test.input
 
 import android.app.Activity
@@ -43,6 +46,7 @@
     }
     private lateinit var mInputEventReceiver: InputEventReceiver
     private lateinit var mInputMonitor: InputMonitor
+
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         val inputManager = checkNotNull(getSystemService(InputManager::class.java))
diff --git a/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java b/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
index 5a27593..5a48327 100644
--- a/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
@@ -59,7 +59,6 @@
 import java.io.InputStream;
 import java.io.PrintWriter;
 import java.util.LinkedList;
-import java.util.TreeMap;
 
 /**
  * Test class for {@link ProtoLogImpl}.
@@ -90,7 +89,7 @@
         //noinspection ResultOfMethodCallIgnored
         mFile.delete();
         mProtoLog = new LegacyProtoLogImpl(mFile, mViewerConfigFilename,
-                1024 * 1024, mReader, 1024, new TreeMap<>(), () -> {});
+                1024 * 1024, mReader, 1024, () -> {});
     }
 
     @After
@@ -142,7 +141,7 @@
         TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
 
         implSpy.log(
-                LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, null,
+                LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321,
                 new Object[]{true, 10000, 30000, "test", 0.000003});
 
         verify(implSpy).passToLogcat(eq(TestProtoLogGroup.TEST_GROUP.getTag()), eq(
@@ -159,7 +158,7 @@
         TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
 
         implSpy.log(
-                LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, null,
+                LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321,
                 new Object[]{true, 10000, 0.0001, 0.00002, "test"});
 
         verify(implSpy).passToLogcat(eq(TestProtoLogGroup.TEST_GROUP.getTag()), eq(
@@ -176,7 +175,7 @@
         TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
 
         implSpy.log(
-                LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, "test %d",
+                LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321,
                 new Object[]{5});
 
         verify(implSpy).passToLogcat(eq(TestProtoLogGroup.TEST_GROUP.getTag()), eq(
@@ -192,7 +191,7 @@
         TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
 
         implSpy.log(
-                LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, null,
+                LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321,
                 new Object[]{5});
 
         verify(implSpy).passToLogcat(eq(TestProtoLogGroup.TEST_GROUP.getTag()), eq(
@@ -208,7 +207,7 @@
         TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
 
         implSpy.log(
-                LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, "test %d",
+                LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321,
                 new Object[]{5});
 
         verify(implSpy, never()).passToLogcat(any(), any(), any());
@@ -277,7 +276,7 @@
         long before = SystemClock.elapsedRealtimeNanos();
         mProtoLog.log(
                 LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234,
-                0b1110101001010100, null,
+                0b1110101001010100,
                 new Object[]{"test", 1, 2, 3, 0.4, 0.5, 0.6, true});
         long after = SystemClock.elapsedRealtimeNanos();
         mProtoLog.stopProtoLog(mock(PrintWriter.class), true);
@@ -302,7 +301,7 @@
         long before = SystemClock.elapsedRealtimeNanos();
         mProtoLog.log(
                 LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234,
-                0b01100100, null,
+                0b01100100,
                 new Object[]{"test", 1, 0.1, true});
         long after = SystemClock.elapsedRealtimeNanos();
         mProtoLog.stopProtoLog(mock(PrintWriter.class), true);
@@ -326,7 +325,7 @@
         TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
         mProtoLog.startProtoLog(mock(PrintWriter.class));
         mProtoLog.log(LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234,
-                0b11, null, new Object[]{true});
+                0b11, new Object[]{true});
         mProtoLog.stopProtoLog(mock(PrintWriter.class), true);
         try (InputStream is = new FileInputStream(mFile)) {
             ProtoInputStream ip = new ProtoInputStream(is);
diff --git a/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java b/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
index 1d7b6b3..b6672a0 100644
--- a/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
@@ -60,6 +60,9 @@
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
+import perfetto.protos.Protolog;
+import perfetto.protos.ProtologCommon;
+
 import java.io.File;
 import java.io.IOException;
 import java.util.List;
@@ -67,9 +70,6 @@
 import java.util.TreeMap;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import perfetto.protos.Protolog;
-import perfetto.protos.ProtologCommon;
-
 /**
  * Test class for {@link ProtoLogImpl}.
  */
@@ -111,6 +111,9 @@
         //noinspection ResultOfMethodCallIgnored
         mFile.delete();
 
+        TestProtoLogGroup.TEST_GROUP.setLogToLogcat(false);
+        TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
+
         mViewerConfigBuilder = Protolog.ProtoLogViewerConfig.newBuilder()
                 .addGroups(
                         Protolog.ProtoLogViewerConfig.Group.newBuilder()
@@ -157,8 +160,9 @@
         mCacheUpdater = () -> {};
         mReader = Mockito.spy(new ProtoLogViewerConfigReader(viewerConfigInputStreamProvider));
         mProtoLog = new PerfettoProtoLogImpl(
-                viewerConfigInputStreamProvider, mReader, new TreeMap<>(),
+                viewerConfigInputStreamProvider, mReader,
                 () -> mCacheUpdater.run());
+        mProtoLog.registerGroups(TestProtoLogGroup.values());
     }
 
     @After
@@ -210,15 +214,15 @@
             // Shouldn't be logging anything except WTF unless explicitly requested in the group
             // override.
             mProtoLog.log(LogLevel.DEBUG, TestProtoLogGroup.TEST_GROUP, 1,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
             mProtoLog.log(LogLevel.VERBOSE, TestProtoLogGroup.TEST_GROUP, 2,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
             mProtoLog.log(LogLevel.WARN, TestProtoLogGroup.TEST_GROUP, 3,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
             mProtoLog.log(LogLevel.ERROR, TestProtoLogGroup.TEST_GROUP, 4,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
             mProtoLog.log(LogLevel.WTF, TestProtoLogGroup.TEST_GROUP, 5,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
         } finally {
             traceMonitor.stop(mWriter);
         }
@@ -240,15 +244,15 @@
         try {
             traceMonitor.start();
             mProtoLog.log(LogLevel.DEBUG, TestProtoLogGroup.TEST_GROUP, 1,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
             mProtoLog.log(LogLevel.VERBOSE, TestProtoLogGroup.TEST_GROUP, 2,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
             mProtoLog.log(LogLevel.WARN, TestProtoLogGroup.TEST_GROUP, 3,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
             mProtoLog.log(LogLevel.ERROR, TestProtoLogGroup.TEST_GROUP, 4,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
             mProtoLog.log(LogLevel.WTF, TestProtoLogGroup.TEST_GROUP, 5,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
         } finally {
             traceMonitor.stop(mWriter);
         }
@@ -274,15 +278,15 @@
         try {
             traceMonitor.start();
             mProtoLog.log(LogLevel.DEBUG, TestProtoLogGroup.TEST_GROUP, 1,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
             mProtoLog.log(LogLevel.VERBOSE, TestProtoLogGroup.TEST_GROUP, 2,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
             mProtoLog.log(LogLevel.WARN, TestProtoLogGroup.TEST_GROUP, 3,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
             mProtoLog.log(LogLevel.ERROR, TestProtoLogGroup.TEST_GROUP, 4,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
             mProtoLog.log(LogLevel.WTF, TestProtoLogGroup.TEST_GROUP, 5,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
         } finally {
             traceMonitor.stop(mWriter);
         }
@@ -304,15 +308,15 @@
         try {
             traceMonitor.start();
             mProtoLog.log(LogLevel.DEBUG, TestProtoLogGroup.TEST_GROUP, 1,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
             mProtoLog.log(LogLevel.VERBOSE, TestProtoLogGroup.TEST_GROUP, 2,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
             mProtoLog.log(LogLevel.WARN, TestProtoLogGroup.TEST_GROUP, 3,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
             mProtoLog.log(LogLevel.ERROR, TestProtoLogGroup.TEST_GROUP, 4,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
             mProtoLog.log(LogLevel.WTF, TestProtoLogGroup.TEST_GROUP, 5,
-                    LogDataType.BOOLEAN, null, new Object[]{true});
+                    LogDataType.BOOLEAN, new Object[]{true});
         } finally {
             traceMonitor.stop(mWriter);
         }
@@ -329,14 +333,14 @@
     }
 
     @Test
-    public void log_logcatEnabledExternalMessage() {
+    public void log_logcatEnabled() {
         when(mReader.getViewerString(anyLong())).thenReturn("test %b %d %% 0x%x %s %f");
         PerfettoProtoLogImpl implSpy = Mockito.spy(mProtoLog);
         TestProtoLogGroup.TEST_GROUP.setLogToLogcat(true);
         TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
 
         implSpy.log(
-                LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, null,
+                LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321,
                 new Object[]{true, 10000, 30000, "test", 0.000003});
 
         verify(implSpy).passToLogcat(eq(TestProtoLogGroup.TEST_GROUP.getTag()), eq(
@@ -353,32 +357,17 @@
         TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
 
         implSpy.log(
-                LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, null,
+                LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321,
                 new Object[]{true, 10000, 0.0001, 0.00002, "test"});
 
         verify(implSpy).passToLogcat(eq(TestProtoLogGroup.TEST_GROUP.getTag()), eq(
                 LogLevel.INFO),
-                eq("UNKNOWN MESSAGE (1234) true 10000 1.0E-4 2.0E-5 test"));
+                eq("FORMAT_ERROR \"test %b %d %% %x %s %f\", "
+                        + "args=(true, 10000, 1.0E-4, 2.0E-5, test)"));
         verify(mReader).getViewerString(eq(1234L));
     }
 
     @Test
-    public void log_logcatEnabledInlineMessage() {
-        when(mReader.getViewerString(anyLong())).thenReturn("test %d");
-        PerfettoProtoLogImpl implSpy = Mockito.spy(mProtoLog);
-        TestProtoLogGroup.TEST_GROUP.setLogToLogcat(true);
-        TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
-
-        implSpy.log(
-                LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, "test %d",
-                new Object[]{5});
-
-        verify(implSpy).passToLogcat(eq(TestProtoLogGroup.TEST_GROUP.getTag()), eq(
-                LogLevel.INFO), eq("test 5"));
-        verify(mReader, never()).getViewerString(anyLong());
-    }
-
-    @Test
     public void log_logcatEnabledNoMessage() {
         when(mReader.getViewerString(anyLong())).thenReturn(null);
         PerfettoProtoLogImpl implSpy = Mockito.spy(mProtoLog);
@@ -386,11 +375,11 @@
         TestProtoLogGroup.TEST_GROUP.setLogToProto(false);
 
         implSpy.log(
-                LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, null,
+                LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321,
                 new Object[]{5});
 
         verify(implSpy).passToLogcat(eq(TestProtoLogGroup.TEST_GROUP.getTag()), eq(
-                LogLevel.INFO), eq("UNKNOWN MESSAGE (1234) 5"));
+                LogLevel.INFO), eq("UNKNOWN MESSAGE#1234 (5)"));
         verify(mReader).getViewerString(eq(1234L));
     }
 
@@ -401,7 +390,7 @@
         TestProtoLogGroup.TEST_GROUP.setLogToLogcat(false);
 
         implSpy.log(
-                LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321, "test %d",
+                LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, 1234, 4321,
                 new Object[]{5});
 
         verify(implSpy, never()).passToLogcat(any(), any(), any());
@@ -425,7 +414,7 @@
             before = SystemClock.elapsedRealtimeNanos();
             mProtoLog.log(
                     LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, messageHash,
-                    0b1110101001010100, null,
+                    0b1110101001010100,
                     new Object[]{"test", 1, 2, 3, 0.4, 0.5, 0.6, true});
             after = SystemClock.elapsedRealtimeNanos();
         } finally {
@@ -444,6 +433,38 @@
                 .isEqualTo("My test message :: test, 2, 4, 6, 0.400000, 5.000000e-01, 0.6, true");
     }
 
+    @Test
+    public void log_noProcessing() throws IOException {
+        PerfettoTraceMonitor traceMonitor =
+                PerfettoTraceMonitor.newBuilder().enableProtoLog().build();
+        long before;
+        long after;
+        try {
+            traceMonitor.start();
+            assertTrue(mProtoLog.isProtoEnabled());
+
+            before = SystemClock.elapsedRealtimeNanos();
+            mProtoLog.log(
+                    LogLevel.INFO, TestProtoLogGroup.TEST_GROUP,
+                    "My test message :: %s, %d, %o, %x, %f, %b",
+                    "test", 1, 2, 3, 0.4, true);
+            after = SystemClock.elapsedRealtimeNanos();
+        } finally {
+            traceMonitor.stop(mWriter);
+        }
+
+        final ResultReader reader = new ResultReader(mWriter.write(), mTraceConfig);
+        final ProtoLogTrace protolog = reader.readProtoLogTrace();
+
+        Truth.assertThat(protolog.messages).hasSize(1);
+        Truth.assertThat(protolog.messages.getFirst().getTimestamp().getElapsedNanos())
+                .isAtLeast(before);
+        Truth.assertThat(protolog.messages.getFirst().getTimestamp().getElapsedNanos())
+                .isAtMost(after);
+        Truth.assertThat(protolog.messages.getFirst().getMessage())
+                .isEqualTo("My test message :: test, 2, 4, 6, 0.400000, true");
+    }
+
     private long addMessageToConfig(ProtologCommon.ProtoLogLevel logLevel, String message) {
         final long messageId = new Random().nextLong();
         mViewerConfigBuilder.addMessages(Protolog.ProtoLogViewerConfig.MessageData.newBuilder()
@@ -470,7 +491,7 @@
             before = SystemClock.elapsedRealtimeNanos();
             mProtoLog.log(
                     LogLevel.INFO, TestProtoLogGroup.TEST_GROUP, messageHash,
-                    0b01100100, null,
+                    0b01100100,
                     new Object[]{"test", 1, 0.1, true});
             after = SystemClock.elapsedRealtimeNanos();
         } finally {
@@ -488,7 +509,7 @@
         try {
             traceMonitor.start();
             mProtoLog.log(LogLevel.DEBUG, TestProtoLogGroup.TEST_GROUP, 1,
-                    0b11, null, new Object[]{true});
+                    0b11, new Object[]{true});
         } finally {
             traceMonitor.stop(mWriter);
         }
@@ -512,7 +533,7 @@
 
             ProtoLogImpl.setSingleInstance(mProtoLog);
             ProtoLogImpl.d(TestProtoLogGroup.TEST_GROUP, 1,
-                    0b11, null, true);
+                    0b11, true);
         } finally {
             traceMonitor.stop(mWriter);
         }
@@ -586,7 +607,7 @@
                 .isFalse();
         Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.ERROR))
                 .isFalse();
-        Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WTF)).isTrue();
+        Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WTF)).isFalse();
 
         PerfettoTraceMonitor traceMonitor1 =
                 PerfettoTraceMonitor.newBuilder().enableProtoLog(true,
@@ -664,7 +685,53 @@
         Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.ERROR))
                 .isFalse();
         Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WTF))
-                .isTrue();
+                .isFalse();
+    }
+
+    @Test
+    public void supportsNullString() throws IOException {
+        PerfettoTraceMonitor traceMonitor =
+                PerfettoTraceMonitor.newBuilder().enableProtoLog(true)
+                        .build();
+
+        try {
+            traceMonitor.start();
+
+            mProtoLog.log(LogLevel.DEBUG, TestProtoLogGroup.TEST_GROUP,
+                    "My test null string: %s", null);
+        } finally {
+            traceMonitor.stop(mWriter);
+        }
+
+        final ResultReader reader = new ResultReader(mWriter.write(), mTraceConfig);
+        final ProtoLogTrace protolog = reader.readProtoLogTrace();
+
+        Truth.assertThat(protolog.messages).hasSize(1);
+        Truth.assertThat(protolog.messages.get(0).getMessage())
+                .isEqualTo("My test null string: null");
+    }
+
+    @Test
+    public void supportNullParams() throws IOException {
+        PerfettoTraceMonitor traceMonitor =
+                PerfettoTraceMonitor.newBuilder().enableProtoLog(true)
+                        .build();
+
+        try {
+            traceMonitor.start();
+
+            mProtoLog.log(LogLevel.DEBUG, TestProtoLogGroup.TEST_GROUP,
+                    "My null args: %d, %f, %b", null, null, null);
+        } finally {
+            traceMonitor.stop(mWriter);
+        }
+
+        final ResultReader reader = new ResultReader(mWriter.write(), mTraceConfig);
+        final ProtoLogTrace protolog = reader.readProtoLogTrace();
+
+        Truth.assertThat(protolog.messages).hasSize(1);
+        Truth.assertThat(protolog.messages.get(0).getMessage())
+                .isEqualTo("My null args: 0, 0, false");
     }
 
     private enum TestProtoLogGroup implements IProtoLogGroup {
diff --git a/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java b/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java
index 60456f9..0496240 100644
--- a/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/ProtoLogImplTest.java
@@ -58,51 +58,50 @@
     public void d_logCalled() {
         IProtoLog mockedProtoLog = mock(IProtoLog.class);
         ProtoLogImpl.setSingleInstance(mockedProtoLog);
-        ProtoLogImpl.d(TestProtoLogGroup.TEST_GROUP, 1234, 4321, "test %d");
+        ProtoLogImpl.d(TestProtoLogGroup.TEST_GROUP, 1234, 4321);
         verify(mockedProtoLog).log(eq(LogLevel.DEBUG), eq(
                 TestProtoLogGroup.TEST_GROUP),
-                eq(1234L), eq(4321), eq("test %d"), eq(new Object[]{}));
+                eq(1234L), eq(4321), eq(new Object[]{}));
     }
 
     @Test
     public void v_logCalled() {
         IProtoLog mockedProtoLog = mock(IProtoLog.class);
         ProtoLogImpl.setSingleInstance(mockedProtoLog);
-        ProtoLogImpl.v(TestProtoLogGroup.TEST_GROUP, 1234, 4321, "test %d");
+        ProtoLogImpl.v(TestProtoLogGroup.TEST_GROUP, 1234, 4321);
         verify(mockedProtoLog).log(eq(LogLevel.VERBOSE), eq(
                 TestProtoLogGroup.TEST_GROUP),
-                eq(1234L), eq(4321), eq("test %d"), eq(new Object[]{}));
+                eq(1234L), eq(4321), eq(new Object[]{}));
     }
 
     @Test
     public void i_logCalled() {
         IProtoLog mockedProtoLog = mock(IProtoLog.class);
         ProtoLogImpl.setSingleInstance(mockedProtoLog);
-        ProtoLogImpl.i(TestProtoLogGroup.TEST_GROUP, 1234, 4321, "test %d");
+        ProtoLogImpl.i(TestProtoLogGroup.TEST_GROUP, 1234, 4321);
         verify(mockedProtoLog).log(eq(LogLevel.INFO), eq(
                 TestProtoLogGroup.TEST_GROUP),
-                eq(1234L), eq(4321), eq("test %d"), eq(new Object[]{}));
+                eq(1234L), eq(4321), eq(new Object[]{}));
     }
 
     @Test
     public void w_logCalled() {
         IProtoLog mockedProtoLog = mock(IProtoLog.class);
         ProtoLogImpl.setSingleInstance(mockedProtoLog);
-        ProtoLogImpl.w(TestProtoLogGroup.TEST_GROUP, 1234,
-                4321, "test %d");
+        ProtoLogImpl.w(TestProtoLogGroup.TEST_GROUP, 1234, 4321);
         verify(mockedProtoLog).log(eq(LogLevel.WARN), eq(
                 TestProtoLogGroup.TEST_GROUP),
-                eq(1234L), eq(4321), eq("test %d"), eq(new Object[]{}));
+                eq(1234L), eq(4321), eq(new Object[]{}));
     }
 
     @Test
     public void e_logCalled() {
         IProtoLog mockedProtoLog = mock(IProtoLog.class);
         ProtoLogImpl.setSingleInstance(mockedProtoLog);
-        ProtoLogImpl.e(TestProtoLogGroup.TEST_GROUP, 1234, 4321, "test %d");
+        ProtoLogImpl.e(TestProtoLogGroup.TEST_GROUP, 1234, 4321);
         verify(mockedProtoLog).log(eq(LogLevel.ERROR), eq(
                 TestProtoLogGroup.TEST_GROUP),
-                eq(1234L), eq(4321), eq("test %d"), eq(new Object[]{}));
+                eq(1234L), eq(4321), eq(new Object[]{}));
     }
 
     @Test
@@ -110,10 +109,10 @@
         IProtoLog mockedProtoLog = mock(IProtoLog.class);
         ProtoLogImpl.setSingleInstance(mockedProtoLog);
         ProtoLogImpl.wtf(TestProtoLogGroup.TEST_GROUP,
-                1234, 4321, "test %d");
+                1234, 4321);
         verify(mockedProtoLog).log(eq(LogLevel.WTF), eq(
                 TestProtoLogGroup.TEST_GROUP),
-                eq(1234L), eq(4321), eq("test %d"), eq(new Object[]{}));
+                eq(1234L), eq(4321), eq(new Object[]{}));
     }
 
     private enum TestProtoLogGroup implements IProtoLogGroup {
diff --git a/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/ConcurrentMultiUserTest.java b/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/ConcurrentMultiUserTest.java
index fff1dd1..df23745 100644
--- a/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/ConcurrentMultiUserTest.java
+++ b/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/ConcurrentMultiUserTest.java
@@ -16,36 +16,52 @@
 
 package com.android.server.inputmethod.multisessiontest;
 
+import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
 import static com.android.compatibility.common.util.concurrentuser.ConcurrentUserActivityUtils.getResponderUserId;
 import static com.android.compatibility.common.util.concurrentuser.ConcurrentUserActivityUtils.launchActivityAsUserSync;
 import static com.android.compatibility.common.util.concurrentuser.ConcurrentUserActivityUtils.sendBundleAndWaitForReply;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_DISPLAY_ID;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_EDITTEXT_CENTER;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_IME_SHOWN;
 import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_REQUEST_CODE;
-import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_RESULT_CODE;
-import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REPLY_IME_HIDDEN;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_DISPLAY_ID;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_EDITTEXT_POSITION;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_HIDE_IME;
 import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_IME_STATUS;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_SHOW_IME;
 
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import static org.junit.Assume.assumeTrue;
+
+import android.app.UiAutomation;
 import android.content.ComponentName;
+import android.content.Context;
 import android.os.Bundle;
+import android.os.UserHandle;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
 
 import androidx.test.core.app.ActivityScenario;
 
 import com.android.bedstead.harrier.BedsteadJUnit4;
 import com.android.bedstead.harrier.DeviceState;
+import com.android.compatibility.common.util.SystemUtil;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.ClassRule;
-import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.io.IOException;
+import java.util.List;
+
 @RunWith(BedsteadJUnit4.class)
-@Ignore("b/345557347")
 public final class ConcurrentMultiUserTest {
 
     @ClassRule
@@ -55,6 +71,11 @@
     private static final ComponentName TEST_ACTIVITY = new ComponentName(
             getInstrumentation().getTargetContext().getPackageName(),
             MainActivity.class.getName());
+    private static final long WAIT_TIME_MS = 3000L;
+    private final Context mContext = getInstrumentation().getTargetContext();
+    private final InputMethodManager mInputMethodManager =
+            mContext.getSystemService(InputMethodManager.class);
+    private final UiAutomation mUiAutomation = getInstrumentation().getUiAutomation();
 
     private ActivityScenario<MainActivity> mActivityScenario;
     private MainActivity mActivity;
@@ -69,17 +90,19 @@
         // Launch driver activity.
         mActivityScenario = ActivityScenario.launch(MainActivity.class);
         mActivityScenario.onActivity(activity -> mActivity = activity);
+        mUiAutomation.adoptShellPermissionIdentity(INTERACT_ACROSS_USERS_FULL);
     }
 
     @After
     public void tearDown() {
+        mUiAutomation.dropShellPermissionIdentity();
         if (mActivityScenario != null) {
             mActivityScenario.close();
         }
     }
 
     @Test
-    public void driverShowImeNotAffectPassenger() {
+    public void driverShowImeNotAffectPassenger() throws Exception {
         assertDriverImeHidden();
         assertPassengerImeHidden();
 
@@ -87,6 +110,90 @@
         assertPassengerImeHidden();
     }
 
+    @Test
+    public void passengerShowImeNotAffectDriver() throws Exception {
+        assertDriverImeHidden();
+        assertPassengerImeHidden();
+
+        showPassengerImeAndAssert();
+        assertDriverImeHidden();
+    }
+
+    @Test
+    public void driverHideImeNotAffectPassenger() throws Exception {
+        showDriverImeAndAssert();
+        showPassengerImeAndAssert();
+
+        hideDriverImeAndAssert();
+        assertPassengerImeShown();
+    }
+
+    @Test
+    public void passengerHideImeNotAffectDriver() throws Exception {
+        showDriverImeAndAssert();
+        showPassengerImeAndAssert();
+
+        hidePassengerImeAndAssert();
+        assertDriverImeShown();
+    }
+
+    @Test
+    public void imeListNotEmpty() {
+        List<InputMethodInfo> driverImeList = mInputMethodManager.getInputMethodList();
+        assertWithMessage("Driver IME list shouldn't be empty")
+                .that(driverImeList.isEmpty()).isFalse();
+
+        List<InputMethodInfo> passengerImeList =
+                mInputMethodManager.getInputMethodListAsUser(mPeerUserId);
+        assertWithMessage("Passenger IME list shouldn't be empty")
+                .that(passengerImeList.isEmpty()).isFalse();
+    }
+
+    @Test
+    public void enabledImeListNotEmpty() {
+        List<InputMethodInfo> driverEnabledImeList =
+                mInputMethodManager.getEnabledInputMethodList();
+        assertWithMessage("Driver enabled IME list shouldn't be empty")
+                .that(driverEnabledImeList.isEmpty()).isFalse();
+
+        List<InputMethodInfo> passengerEnabledImeList =
+                mInputMethodManager.getEnabledInputMethodListAsUser(UserHandle.of(mPeerUserId));
+        assertWithMessage("Passenger enabled IME list shouldn't be empty")
+                .that(passengerEnabledImeList.isEmpty()).isFalse();
+    }
+
+    @Test
+    public void currentImeNotNull() {
+        InputMethodInfo driverIme = mInputMethodManager.getCurrentInputMethodInfo();
+        assertWithMessage("Driver IME shouldn't be null").that(driverIme).isNotNull();
+
+        InputMethodInfo passengerIme =
+                mInputMethodManager.getCurrentInputMethodInfoAsUser(UserHandle.of(mPeerUserId));
+        assertWithMessage("Passenger IME shouldn't be null")
+                .that(passengerIme).isNotNull();
+    }
+
+    @Test
+    public void enableDisableImePerUser() throws IOException {
+        UserHandle driver = UserHandle.of(mContext.getUserId());
+        UserHandle passenger = UserHandle.of(mPeerUserId);
+        enableDisableImeForUser(driver, passenger);
+        enableDisableImeForUser(passenger, driver);
+    }
+
+    @Test
+    public void setImePerUser() throws IOException {
+        UserHandle driver = UserHandle.of(mContext.getUserId());
+        UserHandle passenger = UserHandle.of(mPeerUserId);
+        setImeForUser(driver, passenger);
+        setImeForUser(passenger, driver);
+    }
+
+    private void assertDriverImeShown() {
+        assertWithMessage("Driver IME should be shown")
+                .that(mActivity.isMyImeVisible()).isTrue();
+    }
+
     private void assertDriverImeHidden() {
         assertWithMessage("Driver IME should be hidden")
                 .that(mActivity.isMyImeVisible()).isFalse();
@@ -98,10 +205,161 @@
         Bundle receivedBundle = sendBundleAndWaitForReply(TEST_ACTIVITY.getPackageName(),
                 mPeerUserId, bundleToSend);
         assertWithMessage("Passenger IME should be hidden")
-                .that(receivedBundle.getInt(KEY_RESULT_CODE)).isEqualTo(REPLY_IME_HIDDEN);
+                .that(receivedBundle.getBoolean(KEY_IME_SHOWN, /* defaultValue= */ true)).isFalse();
     }
 
-    private void showDriverImeAndAssert() {
+    private void assertPassengerImeShown() {
+        final Bundle bundleToSend = new Bundle();
+        bundleToSend.putInt(KEY_REQUEST_CODE, REQUEST_IME_STATUS);
+        Bundle receivedBundle = sendBundleAndWaitForReply(TEST_ACTIVITY.getPackageName(),
+                mPeerUserId, bundleToSend);
+        assertWithMessage("Passenger IME should be shown")
+                .that(receivedBundle.getBoolean(KEY_IME_SHOWN)).isTrue();
+    }
+
+    private void showDriverImeAndAssert() throws Exception {
+        //  WindowManagerInternal only allows the top focused display to show IME, so this method
+        //  taps the driver display in case it is not the top focused display.
+        moveDriverDisplayToTop();
+
         mActivity.showMyImeAndWait();
     }
+
+    private void hideDriverImeAndAssert() {
+        mActivity.hideMyImeAndWait();
+    }
+
+    private void showPassengerImeAndAssert() throws Exception {
+        // WindowManagerInternal only allows the top focused display to show IME, so this method
+        // taps the passenger display in case it is not the top focused display.
+        movePassengerDisplayToTop();
+
+        Bundle bundleToSend = new Bundle();
+        bundleToSend.putInt(KEY_REQUEST_CODE, REQUEST_SHOW_IME);
+        Bundle receivedBundle = sendBundleAndWaitForReply(TEST_ACTIVITY.getPackageName(),
+                mPeerUserId, bundleToSend);
+
+        assertWithMessage("Passenger IME should be shown")
+                .that(receivedBundle.getBoolean(KEY_IME_SHOWN)).isTrue();
+    }
+
+    private void hidePassengerImeAndAssert() {
+        Bundle bundleToSend = new Bundle();
+        bundleToSend.putInt(KEY_REQUEST_CODE, REQUEST_HIDE_IME);
+        Bundle receivedBundle = sendBundleAndWaitForReply(TEST_ACTIVITY.getPackageName(),
+                mPeerUserId, bundleToSend);
+
+        assertWithMessage("Passenger IME should be hidden")
+                .that(receivedBundle.getBoolean(KEY_IME_SHOWN, /* defaultValue= */ true)).isFalse();
+    }
+
+    private void moveDriverDisplayToTop() throws Exception {
+        float[] driverEditTextCenter = mActivity.getEditTextCenter();
+        SystemUtil.runShellCommand(mUiAutomation, String.format("input tap %f %f",
+                driverEditTextCenter[0], driverEditTextCenter[1]));
+        // TODO(b/350562427): get rid of Thread.sleep().
+        Thread.sleep(WAIT_TIME_MS);
+    }
+
+    private void movePassengerDisplayToTop() throws Exception {
+        final Bundle bundleToSend = new Bundle();
+        bundleToSend.putInt(KEY_REQUEST_CODE, REQUEST_EDITTEXT_POSITION);
+        Bundle receivedBundle = sendBundleAndWaitForReply(TEST_ACTIVITY.getPackageName(),
+                mPeerUserId, bundleToSend);
+        final float[] passengerEditTextCenter = receivedBundle.getFloatArray(KEY_EDITTEXT_CENTER);
+
+        bundleToSend.putInt(KEY_REQUEST_CODE, REQUEST_DISPLAY_ID);
+        receivedBundle = sendBundleAndWaitForReply(TEST_ACTIVITY.getPackageName(),
+                mPeerUserId, bundleToSend);
+        final int passengerDisplayId = receivedBundle.getInt(KEY_DISPLAY_ID);
+        SystemUtil.runShellCommand(mUiAutomation, String.format("input -d %d tap %f %f",
+                passengerDisplayId, passengerEditTextCenter[0], passengerEditTextCenter[1]));
+        // TODO(b/350562427): get rid of Thread.sleep().
+        Thread.sleep(WAIT_TIME_MS);
+    }
+
+    /**
+     * Disables/enables IME for {@code user1}, then verifies that the IME settings for {@code user1}
+     * has changed as expected and {@code user2} stays the same.
+     */
+    private void enableDisableImeForUser(UserHandle user1, UserHandle user2) throws IOException {
+        List<InputMethodInfo> user1EnabledImeList =
+                mInputMethodManager.getEnabledInputMethodListAsUser(user1);
+        List<InputMethodInfo> user2EnabledImeList =
+                mInputMethodManager.getEnabledInputMethodListAsUser(user2);
+
+        // Disable an IME for user1.
+        InputMethodInfo imeToDisable = user1EnabledImeList.get(0);
+        SystemUtil.runShellCommand(mUiAutomation,
+                "ime disable --user " + user1.getIdentifier() + " " + imeToDisable.getId());
+        List<InputMethodInfo> user1EnabledImeList2 =
+                mInputMethodManager.getEnabledInputMethodListAsUser(user1);
+        List<InputMethodInfo> user2EnabledImeList2 =
+                mInputMethodManager.getEnabledInputMethodListAsUser(user2);
+        assertWithMessage("User " + user1.getIdentifier() + " IME " + imeToDisable.getId()
+                + " should be disabled")
+                .that(user1EnabledImeList2.contains(imeToDisable)).isFalse();
+        assertWithMessage("Disabling user " + user1.getIdentifier()
+                + " IME shouldn't affect user " + user2.getIdentifier())
+                .that(user2EnabledImeList2.containsAll(user2EnabledImeList)
+                        && user2EnabledImeList.containsAll(user2EnabledImeList2))
+                .isTrue();
+
+        // Enable the IME.
+        SystemUtil.runShellCommand(mUiAutomation,
+                "ime enable --user " + user1.getIdentifier() + " " + imeToDisable.getId());
+        List<InputMethodInfo> user1EnabledImeList3 =
+                mInputMethodManager.getEnabledInputMethodListAsUser(user1);
+        List<InputMethodInfo> user2EnabledImeList3 =
+                mInputMethodManager.getEnabledInputMethodListAsUser(user2);
+        assertWithMessage("User " + user1.getIdentifier() + " IME " + imeToDisable.getId()
+                + " should be enabled").that(user1EnabledImeList3.contains(imeToDisable)).isTrue();
+        assertWithMessage("Enabling user " + user1.getIdentifier()
+                + " IME shouldn't affect user " + user2.getIdentifier())
+                .that(user2EnabledImeList2.containsAll(user2EnabledImeList3)
+                        && user2EnabledImeList3.containsAll(user2EnabledImeList2))
+                .isTrue();
+    }
+
+    /**
+     * Sets/resets IME for {@code user1}, then verifies that the IME settings for {@code user1}
+     * has changed as expected and {@code user2} stays the same.
+     */
+    private void setImeForUser(UserHandle user1, UserHandle user2) throws IOException {
+        // Reset IME for user1.
+        SystemUtil.runShellCommand(mUiAutomation,
+                "ime reset --user " + user1.getIdentifier());
+
+        List<InputMethodInfo> user1EnabledImeList =
+                mInputMethodManager.getEnabledInputMethodListAsUser(user1);
+        assumeTrue("There must be at least two IME to test", user1EnabledImeList.size() >= 2);
+        InputMethodInfo user1Ime = mInputMethodManager.getCurrentInputMethodInfoAsUser(user1);
+        InputMethodInfo user2Ime = mInputMethodManager.getCurrentInputMethodInfoAsUser(user2);
+
+        // Set to another IME for user1.
+        InputMethodInfo anotherIme = null;
+        for (InputMethodInfo info : user1EnabledImeList) {
+            if (!info.equals(user1Ime)) {
+                anotherIme = info;
+            }
+        }
+        SystemUtil.runShellCommand(mUiAutomation,
+                "ime set --user " + user1.getIdentifier() + " " + anotherIme.getId());
+        InputMethodInfo user1Ime2 = mInputMethodManager.getCurrentInputMethodInfoAsUser(user1);
+        InputMethodInfo user2Ime2 = mInputMethodManager.getCurrentInputMethodInfoAsUser(user2);
+        assertWithMessage("The current IME for user " + user1.getIdentifier() + " is wrong")
+                .that(user1Ime2).isEqualTo(anotherIme);
+        assertWithMessage("The current IME for user " + user2.getIdentifier() + " shouldn't change")
+                .that(user2Ime2).isEqualTo(user2Ime);
+
+        // Reset IME for user1.
+        SystemUtil.runShellCommand(mUiAutomation,
+                "ime reset --user " + user1.getIdentifier());
+        InputMethodInfo user1Ime3 = mInputMethodManager.getCurrentInputMethodInfoAsUser(user1);
+        InputMethodInfo user2Ime3 = mInputMethodManager.getCurrentInputMethodInfoAsUser(user2);
+        assertWithMessage("The current IME for user " + user1.getIdentifier() + " is wrong")
+                .that(user1Ime3).isEqualTo(user1Ime);
+        assertWithMessage("The current IME for user " + user2.getIdentifier() + " shouldn't change")
+                .that(user2Ime3).isEqualTo(user2Ime);
+    }
 }
diff --git a/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/MainActivity.java b/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/MainActivity.java
index f126000..fa0aa19 100644
--- a/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/MainActivity.java
+++ b/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/MainActivity.java
@@ -16,20 +16,25 @@
 
 package com.android.server.inputmethod.multisessiontest;
 
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_DISPLAY_ID;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_EDITTEXT_CENTER;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_IME_SHOWN;
 import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_REQUEST_CODE;
-import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.KEY_RESULT_CODE;
-import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REPLY_IME_HIDDEN;
-import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REPLY_IME_SHOWN;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_DISPLAY_ID;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_EDITTEXT_POSITION;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_HIDE_IME;
 import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_IME_STATUS;
+import static com.android.server.inputmethod.multisessiontest.TestRequestConstants.REQUEST_SHOW_IME;
 
 import android.app.Activity;
 import android.os.Bundle;
 import android.os.Process;
 import android.util.Log;
-import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
 
+import androidx.annotation.WorkerThread;
 import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowCompat;
 import androidx.core.view.WindowInsetsCompat;
 
 import com.android.compatibility.common.util.PollingCheck;
@@ -43,7 +48,6 @@
     private static final long WAIT_IME_TIMEOUT_MS = 3000;
 
     private EditText mEditor;
-    private InputMethodManager mImm;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -52,19 +56,56 @@
                 + Process.myUserHandle().getIdentifier() + " on display "
                 + getDisplay().getDisplayId());
         setContentView(R.layout.main_activity);
-        mImm = getSystemService(InputMethodManager.class);
         mEditor = requireViewById(R.id.edit_text);
     }
 
     @Override
+    protected void onResume() {
+        super.onResume();
+        Log.v(TAG, "onResume");
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        Log.v(TAG, "onPause");
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        Log.v(TAG, "onResume");
+    }
+
+    @Override
+    public void onWindowFocusChanged(boolean hasFocus) {
+        super.onWindowFocusChanged(hasFocus);
+        Log.v(TAG, "onWindowFocusChanged " + hasFocus);
+    }
+
+    @Override
+    @WorkerThread
     protected Bundle onBundleReceived(Bundle receivedBundle) {
         final int requestCode = receivedBundle.getInt(KEY_REQUEST_CODE);
         Log.v(TAG, "onBundleReceived() with request code:" + requestCode);
         final Bundle replyBundle = new Bundle();
         switch (requestCode) {
             case REQUEST_IME_STATUS:
-                replyBundle.putInt(KEY_RESULT_CODE,
-                        isMyImeVisible() ? REPLY_IME_SHOWN : REPLY_IME_HIDDEN);
+                replyBundle.putBoolean(KEY_IME_SHOWN, isMyImeVisible());
+                break;
+            case REQUEST_SHOW_IME:
+                showMyImeAndWait();
+                replyBundle.putBoolean(KEY_IME_SHOWN, isMyImeVisible());
+                break;
+            case REQUEST_HIDE_IME:
+                hideMyImeAndWait();
+                replyBundle.putBoolean(KEY_IME_SHOWN, isMyImeVisible());
+                break;
+            case REQUEST_EDITTEXT_POSITION:
+                replyBundle.putFloatArray(KEY_EDITTEXT_CENTER, getEditTextCenter());
+                break;
+            case REQUEST_DISPLAY_ID:
+                replyBundle.putInt(KEY_DISPLAY_ID, getDisplay().getDisplayId());
                 break;
             default:
                 throw new RuntimeException("Received undefined request code:" + requestCode);
@@ -77,21 +118,41 @@
         return insets == null ? false : insets.isVisible(WindowInsetsCompat.Type.ime());
     }
 
+    float[] getEditTextCenter() {
+        final float editTextCenterX = mEditor.getX() + 0.5f * mEditor.getWidth();
+        final float editTextCenterY = mEditor.getY() + 0.5f * mEditor.getHeight();
+        return new float[]{editTextCenterX, editTextCenterY};
+    }
+
+    @WorkerThread
     void showMyImeAndWait() {
-        Log.v(TAG, "showSoftInput");
         runOnUiThread(() -> {
-            // requestFocus() must run on UI thread.
+            // View#requestFocus() and WindowInsetsControllerCompat#show() must run on UI thread.
             if (!mEditor.requestFocus()) {
                 Log.e(TAG, "Failed to focus on mEditor");
                 return;
             }
-            if (!mImm.showSoftInput(mEditor, /* flags= */ 0)) {
-                Log.e(TAG, String.format("Failed to show my IME as user %d, "
-                                + "mEditor:focused=%b,hasWindowFocus=%b", getUserId(),
-                        mEditor.isFocused(), mEditor.hasWindowFocus()));
-            }
+            // Compared to mImm.showSoftInput(), the call below is the recommended way to show the
+            // keyboard because it is guaranteed to be scheduled after the window is focused.
+            Log.v(TAG, "showSoftInput");
+            WindowCompat.getInsetsController(getWindow(), mEditor).show(
+                    WindowInsetsCompat.Type.ime());
         });
         PollingCheck.waitFor(WAIT_IME_TIMEOUT_MS, () -> isMyImeVisible(),
-                String.format("My IME (user %d) didn't show up", getUserId()));
+                String.format("%s: My IME (user %d) didn't show up", TAG,
+                        Process.myUserHandle().getIdentifier()));
+    }
+
+    @WorkerThread
+    void hideMyImeAndWait() {
+        runOnUiThread(() -> {
+            Log.v(TAG, "hideSoftInput");
+            // WindowInsetsControllerCompat#hide() must run on UI thread.
+            WindowCompat.getInsetsController(getWindow(), mEditor)
+                    .hide(WindowInsetsCompat.Type.ime());
+        });
+        PollingCheck.waitFor(WAIT_IME_TIMEOUT_MS, () -> !isMyImeVisible(),
+                String.format("%s: My IME (user %d) is still shown", TAG,
+                        Process.myUserHandle().getIdentifier()));
     }
 }
diff --git a/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/TestRequestConstants.java b/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/TestRequestConstants.java
index 1501bfb..68c9d54 100644
--- a/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/TestRequestConstants.java
+++ b/tests/inputmethod/ConcurrentMultiSessionImeTest/src/com/android/server/inputmethod/multisessiontest/TestRequestConstants.java
@@ -21,9 +21,13 @@
     }
 
     public static final String KEY_REQUEST_CODE = "key_request_code";
-    public static final String KEY_RESULT_CODE = "key_result_code";
+    public static final String KEY_EDITTEXT_CENTER = "key_edittext_center";
+    public static final String KEY_DISPLAY_ID = "key_display_id";
+    public static final String KEY_IME_SHOWN = "key_ime_shown";
 
     public static final int REQUEST_IME_STATUS = 1;
-    public static final int REPLY_IME_SHOWN = 2;
-    public static final int REPLY_IME_HIDDEN = 3;
+    public static final int REQUEST_SHOW_IME = 2;
+    public static final int REQUEST_HIDE_IME = 3;
+    public static final int REQUEST_EDITTEXT_POSITION = 4;
+    public static final int REQUEST_DISPLAY_ID = 5;
 }
diff --git a/packages/SystemUI/tests/utils/src/android/animation/AnimatorTestRule.java b/tests/testables/src/android/animation/AnimatorTestRule.java
similarity index 100%
rename from packages/SystemUI/tests/utils/src/android/animation/AnimatorTestRule.java
rename to tests/testables/src/android/animation/AnimatorTestRule.java
diff --git a/tests/testables/tests/Android.bp b/tests/testables/tests/Android.bp
index 06449e0..d6a4754 100644
--- a/tests/testables/tests/Android.bp
+++ b/tests/testables/tests/Android.bp
@@ -26,14 +26,18 @@
     platform_apis: true,
     srcs: [
         "src/**/*.java",
+        "src/**/*.kt",
         "src/**/I*.aidl",
     ],
     resource_dirs: ["res"],
     static_libs: [
+        "androidx.core_core-animation",
+        "androidx.core_core-ktx",
         "androidx.test.rules",
         "hamcrest-library",
         "mockito-target-inline-minus-junit4",
         "testables",
+        "truth",
     ],
     compile_multilib: "both",
     jni_libs: [
diff --git a/tests/testables/tests/src/android/animation/AnimatorTestRuleIsolationTest.kt b/tests/testables/tests/src/android/animation/AnimatorTestRuleIsolationTest.kt
new file mode 100644
index 0000000..5abebee
--- /dev/null
+++ b/tests/testables/tests/src/android/animation/AnimatorTestRuleIsolationTest.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.animation
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import androidx.core.animation.doOnEnd
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/**
+ * This test class validates that two tests' animators are isolated from each other when using the
+ * same animator test rule. This is a test to prevent future instances of b/275602127.
+ */
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+@RunWithLooper
+class AnimatorTestRuleIsolationTest {
+
+    @get:Rule val animatorTestRule = AnimatorTestRule(this)
+
+    @Test
+    fun testA() {
+        // GIVEN global state is reset at the start of the test
+        didTouchA = false
+        didTouchB = false
+        // WHEN starting 2 animations of different durations, and setting didTouch{A,B} at the end
+        ObjectAnimator.ofFloat(0f, 1f).apply {
+            duration = 100
+            doOnEnd { didTouchA = true }
+            start()
+        }
+        ObjectAnimator.ofFloat(0f, 1f).apply {
+            duration = 150
+            doOnEnd { didTouchB = true }
+            start()
+        }
+        // WHEN when you advance time so that only one of the animations has ended
+        animatorTestRule.advanceTimeBy(100)
+        // VERIFY we did indeed end the current animation
+        assertThat(didTouchA).isTrue()
+        // VERIFY advancing the animator did NOT cause testB's animator to end
+        assertThat(didTouchB).isFalse()
+    }
+
+    @Test
+    fun testB() {
+        // GIVEN global state is reset at the start of the test
+        didTouchA = false
+        didTouchB = false
+        // WHEN starting 2 animations of different durations, and setting didTouch{A,B} at the end
+        ObjectAnimator.ofFloat(0f, 1f).apply {
+            duration = 100
+            doOnEnd { didTouchB = true }
+            start()
+        }
+        ObjectAnimator.ofFloat(0f, 1f).apply {
+            duration = 150
+            doOnEnd { didTouchA = true }
+            start()
+        }
+        animatorTestRule.advanceTimeBy(100)
+        // VERIFY advancing the animator did NOT cause testA's animator to end
+        assertThat(didTouchA).isFalse()
+        // VERIFY we did indeed end the current animation
+        assertThat(didTouchB).isTrue()
+    }
+
+    companion object {
+        var didTouchA = false
+        var didTouchB = false
+    }
+}
diff --git a/tests/testables/tests/src/android/animation/AnimatorTestRulePrecisionTest.kt b/tests/testables/tests/src/android/animation/AnimatorTestRulePrecisionTest.kt
new file mode 100644
index 0000000..9eeaad5
--- /dev/null
+++ b/tests/testables/tests/src/android/animation/AnimatorTestRulePrecisionTest.kt
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.animation
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import android.view.animation.LinearInterpolator
+import androidx.core.animation.doOnEnd
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+@RunWithLooper
+class AnimatorTestRulePrecisionTest {
+
+    @get:Rule val animatorTestRule = AnimatorTestRule(this)
+
+    var value1: Float = -1f
+    var value2: Float = -1f
+
+    private inline fun animateThis(
+        propertyName: String,
+        duration: Long,
+        startDelay: Long = 0,
+        crossinline onEndAction: (animator: Animator) -> Unit,
+    ) {
+        ObjectAnimator.ofFloat(this, propertyName, 0f, 1f).also {
+            it.interpolator = LINEAR_INTERPOLATOR
+            it.duration = duration
+            it.startDelay = startDelay
+            it.doOnEnd(onEndAction)
+            it.start()
+        }
+    }
+
+    @Test
+    fun testSingleAnimator() {
+        var ended = false
+        animateThis("value1", duration = 100) { ended = true }
+
+        assertThat(value1).isEqualTo(0f)
+        assertThat(ended).isFalse()
+        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
+
+        animatorTestRule.advanceTimeBy(50)
+        assertThat(value1).isEqualTo(0.5f)
+        assertThat(ended).isFalse()
+        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
+
+        animatorTestRule.advanceTimeBy(49)
+        assertThat(value1).isEqualTo(0.99f)
+        assertThat(ended).isFalse()
+        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
+
+        animatorTestRule.advanceTimeBy(1)
+        assertThat(value1).isEqualTo(1f)
+        assertThat(ended).isTrue()
+        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(0)
+    }
+
+    @Test
+    fun testDelayedAnimator() {
+        var ended = false
+        animateThis("value1", duration = 100, startDelay = 50) { ended = true }
+
+        assertThat(value1).isEqualTo(-1f)
+        assertThat(ended).isFalse()
+        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
+
+        animatorTestRule.advanceTimeBy(49)
+        assertThat(value1).isEqualTo(-1f)
+        assertThat(ended).isFalse()
+        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
+
+        animatorTestRule.advanceTimeBy(1)
+        assertThat(value1).isEqualTo(0f)
+        assertThat(ended).isFalse()
+        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
+
+        animatorTestRule.advanceTimeBy(99)
+        assertThat(value1).isEqualTo(0.99f)
+        assertThat(ended).isFalse()
+        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
+
+        animatorTestRule.advanceTimeBy(1)
+        assertThat(value1).isEqualTo(1f)
+        assertThat(ended).isTrue()
+        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(0)
+    }
+
+    @Test
+    fun testTwoAnimators() {
+        var ended1 = false
+        var ended2 = false
+        animateThis("value1", duration = 100) { ended1 = true }
+        animateThis("value2", duration = 200) { ended2 = true }
+        assertThat(value1).isEqualTo(0f)
+        assertThat(value2).isEqualTo(0f)
+        assertThat(ended1).isFalse()
+        assertThat(ended2).isFalse()
+        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(2)
+
+        animatorTestRule.advanceTimeBy(99)
+        assertThat(value1).isEqualTo(0.99f)
+        assertThat(value2).isEqualTo(0.495f)
+        assertThat(ended1).isFalse()
+        assertThat(ended2).isFalse()
+        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(2)
+
+        animatorTestRule.advanceTimeBy(1)
+        assertThat(value1).isEqualTo(1f)
+        assertThat(value2).isEqualTo(0.5f)
+        assertThat(ended1).isTrue()
+        assertThat(ended2).isFalse()
+        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
+
+        animatorTestRule.advanceTimeBy(99)
+        assertThat(value1).isEqualTo(1f)
+        assertThat(value2).isEqualTo(0.995f)
+        assertThat(ended1).isTrue()
+        assertThat(ended2).isFalse()
+        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
+
+        animatorTestRule.advanceTimeBy(1)
+        assertThat(value1).isEqualTo(1f)
+        assertThat(value2).isEqualTo(1f)
+        assertThat(ended1).isTrue()
+        assertThat(ended2).isTrue()
+        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(0)
+    }
+
+    @Test
+    fun testChainedAnimators() {
+        var ended1 = false
+        var ended2 = false
+        animateThis("value1", duration = 100) {
+            ended1 = true
+            animateThis("value2", duration = 100) { ended2 = true }
+        }
+
+        assertThat(value1).isEqualTo(0f)
+        assertThat(value2).isEqualTo(-1f)
+        assertThat(ended1).isFalse()
+        assertThat(ended2).isFalse()
+        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
+
+        animatorTestRule.advanceTimeBy(99)
+        assertThat(value1).isEqualTo(0.99f)
+        assertThat(value2).isEqualTo(-1f)
+        assertThat(ended1).isFalse()
+        assertThat(ended2).isFalse()
+        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
+
+        animatorTestRule.advanceTimeBy(1)
+        assertThat(value1).isEqualTo(1f)
+        assertThat(value2).isEqualTo(0f)
+        assertThat(ended1).isTrue()
+        assertThat(ended2).isFalse()
+        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
+
+        animatorTestRule.advanceTimeBy(99)
+        assertThat(value1).isEqualTo(1f)
+        assertThat(value2).isEqualTo(0.99f)
+        assertThat(ended1).isTrue()
+        assertThat(ended2).isFalse()
+        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(1)
+
+        animatorTestRule.advanceTimeBy(1)
+        assertThat(value1).isEqualTo(1f)
+        assertThat(value2).isEqualTo(1f)
+        assertThat(ended1).isTrue()
+        assertThat(ended2).isTrue()
+        assertThat(AnimationHandler.getAnimationCount()).isEqualTo(0)
+    }
+
+    private companion object {
+        private val LINEAR_INTERPOLATOR = LinearInterpolator()
+    }
+}
diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp
index 6a17ef8..df1d51e 100644
--- a/tools/aapt2/Debug.cpp
+++ b/tools/aapt2/Debug.cpp
@@ -763,10 +763,35 @@
     pool->setTo(chunk, android::util::DeviceToHost32(
                            (reinterpret_cast<const ResChunk_header*>(chunk))->size));
 
-    printer_->Print("\n");
+    printer_->Print(StringPrintf(" strings: %zd styles %zd flags: %s|%s\n", pool->size(),
+                                 pool->styleCount(), pool->isUTF8() ? "UTF-8" : "UTF-16",
+                                 pool->isSorted() ? "SORTED" : "NON-SORTED"));
 
     for (size_t i = 0; i < pool->size(); i++) {
       printer_->Print(StringPrintf("#%zd : %s\n", i, android::util::GetString(*pool, i).c_str()));
+      if (i < pool->styleCount()) {
+        printer_->Print(" [Style] ");
+        auto maybe_style = pool->styleAt(i);
+        if (!maybe_style) {
+          printer_->Print("??? missing\n");
+        } else {
+          std::vector<const ResStringPool_span*> spans;
+          for (auto style = maybe_style.value().unsafe_ptr();
+               style->name.index != android::ResStringPool_span::END; ++style) {
+            spans.push_back(style);
+          }
+          printer_->Print(StringPrintf("(%zd)", spans.size()));
+          if (!spans.empty()) {
+            printer_->Print(" :");
+            for (const auto& span : spans) {
+              printer_->Print(StringPrintf(
+                  " %s:%u,%u", android::util::GetString(*pool, span->name.index).c_str(),
+                  span->firstChar, span->lastChar));
+            }
+            printer_->Print("\n");
+          }
+        }
+      }
     }
   }
 
diff --git a/tools/aapt2/ResourceValues_test.cpp b/tools/aapt2/ResourceValues_test.cpp
index d788e3f..b30348d 100644
--- a/tools/aapt2/ResourceValues_test.cpp
+++ b/tools/aapt2/ResourceValues_test.cpp
@@ -184,6 +184,35 @@
   EXPECT_THAT(pool_b.strings()[0]->value, StrEq("hello"));
 }
 
+TEST(ResourcesValuesTest, StringEquals) {
+  android::StringPool pool;
+
+  String str(pool.MakeRef("hello", android::StringPool::Context(test::ParseConfigOrDie("en"))));
+  String str2(pool.MakeRef("hello"));
+  EXPECT_TRUE(str.Equals(&str2));
+  EXPECT_TRUE(str2.Equals(&str));
+
+  String str3(pool.MakeRef("how are you"));
+  EXPECT_FALSE(str.Equals(&str3));
+}
+
+TEST(ResourcesValuesTest, StyledStringEquals) {
+  android::StringPool pool;
+
+  StyledString ss(pool.MakeRef(android::StyleString{"hello", {{"b", 0, 1}, {"u", 2, 4}}}));
+  StyledString ss2(pool.MakeRef(android::StyleString{"hello", {{"b", 0, 1}, {"u", 2, 4}}}));
+  StyledString ss3(pool.MakeRef(android::StyleString{"hi", {{"b", 0, 1}, {"u", 2, 4}}}));
+  StyledString ss4(pool.MakeRef(android::StyleString{"hello", {{"b", 0, 1}}}));
+  StyledString ss5(pool.MakeRef(android::StyleString{"hello", {{"b", 0, 1}, {"u", 3, 4}}}));
+  StyledString ss6(pool.MakeRef(android::StyleString{"hello", {{"b", 0, 1}, {"s", 2, 4}}}));
+  EXPECT_TRUE(ss.Equals(&ss2));
+  EXPECT_TRUE(ss2.Equals(&ss));
+  EXPECT_FALSE(ss.Equals(&ss3));
+  EXPECT_FALSE(ss.Equals(&ss4));
+  EXPECT_FALSE(ss.Equals(&ss5));
+  EXPECT_FALSE(ss.Equals(&ss6));
+}
+
 TEST(ResourceValuesTest, StyleMerges) {
   android::StringPool pool_a;
   android::StringPool pool_b;
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index 031dd5b..9b8c3b3 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -836,6 +836,28 @@
     return 1;
   }
 
+  // Parse the feature flag values. An argument that starts with '@' points to a file to read flag
+  // values from.
+  std::vector<std::string> all_feature_flags_args;
+  for (const std::string& arg : feature_flags_args_) {
+    if (util::StartsWith(arg, "@")) {
+      const std::string path = arg.substr(1, arg.size() - 1);
+      std::string error;
+      if (!file::AppendArgsFromFile(path, &all_feature_flags_args, &error)) {
+        context.GetDiagnostics()->Error(android::DiagMessage(path) << error);
+        return 1;
+      }
+    } else {
+      all_feature_flags_args.push_back(arg);
+    }
+  }
+
+  for (const std::string& arg : all_feature_flags_args) {
+    if (!ParseFeatureFlagsParameter(arg, context.GetDiagnostics(), &options_.feature_flag_values)) {
+      return 1;
+    }
+  }
+
   return Compile(&context, file_collection.get(), archive_writer.get(), options_);
 }
 
diff --git a/tools/aapt2/cmd/Compile.h b/tools/aapt2/cmd/Compile.h
index 61c5b60..70c8791 100644
--- a/tools/aapt2/cmd/Compile.h
+++ b/tools/aapt2/cmd/Compile.h
@@ -24,6 +24,7 @@
 #include "Command.h"
 #include "ResourceTable.h"
 #include "androidfw/IDiagnostics.h"
+#include "cmd/Util.h"
 #include "format/Archive.h"
 #include "process/IResourceTableConsumer.h"
 
@@ -45,6 +46,7 @@
   bool preserve_visibility_of_styleables = false;
   bool verbose = false;
   std::optional<std::string> product_;
+  FeatureFlagValues feature_flag_values;
 };
 
 /** Parses flags and compiles resources to be used in linking.  */
@@ -92,6 +94,12 @@
                     "Leave only resources specific to the given product. All "
                     "other resources (including defaults) are removed.",
                     &options_.product_);
+    AddOptionalFlagList("--feature-flags",
+                        "Specify the values of feature flags. The pairs in the argument\n"
+                        "are separated by ',' the name is separated from the value by '='.\n"
+                        "The name can have a suffix of ':ro' to indicate it is read only."
+                        "Example: \"flag1=true,flag2:ro=false,flag3=\" (flag3 has no given value).",
+                        &feature_flags_args_);
   }
 
   int Action(const std::vector<std::string>& args) override;
@@ -101,6 +109,7 @@
   CompileOptions options_;
   std::optional<std::string> visibility_;
   std::optional<std::string> trace_folder_;
+  std::vector<std::string> feature_flags_args_;
 };
 
 int Compile(IAaptContext* context, io::IFileCollection* inputs, IArchiveWriter* output_writer,
diff --git a/tools/aapt2/cmd/Diff.cpp b/tools/aapt2/cmd/Diff.cpp
index 5bfc732..6da3176 100644
--- a/tools/aapt2/cmd/Diff.cpp
+++ b/tools/aapt2/cmd/Diff.cpp
@@ -106,7 +106,7 @@
   if (!value_a->Equals(value_b)) {
     std::stringstream str_stream;
     str_stream << "value " << pkg_a.name << ":" << type_a.named_type << "/" << entry_a.name
-               << " config=" << config_value_a->config << " does not match:\n";
+               << " config='" << config_value_a->config << "' does not match:\n";
     value_a->Print(&str_stream);
     str_stream << "\n vs \n";
     value_b->Print(&str_stream);
diff --git a/tools/aapt2/cmd/Link.h b/tools/aapt2/cmd/Link.h
index 8fe414f..2f17853 100644
--- a/tools/aapt2/cmd/Link.h
+++ b/tools/aapt2/cmd/Link.h
@@ -332,8 +332,9 @@
     AddOptionalSwitch("-v", "Enables verbose logging.", &verbose_);
     AddOptionalFlagList("--feature-flags",
                         "Specify the values of feature flags. The pairs in the argument\n"
-                        "are separated by ',' and the name is separated from the value by '='.\n"
-                        "Example: \"flag1=true,flag2=false,flag3=\" (flag3 has no given value).",
+                        "are separated by ',' the name is separated from the value by '='.\n"
+                        "The name can have a suffix of ':ro' to indicate it is read only."
+                        "Example: \"flag1=true,flag2:ro=false,flag3=\" (flag3 has no given value).",
                         &feature_flags_args_);
     AddOptionalSwitch("--non-updatable-system",
                       "Mark the app as a non-updatable system app. This inserts\n"
diff --git a/tools/aapt2/cmd/Util.cpp b/tools/aapt2/cmd/Util.cpp
index 678d846..e839fc1 100644
--- a/tools/aapt2/cmd/Util.cpp
+++ b/tools/aapt2/cmd/Util.cpp
@@ -128,7 +128,7 @@
     if (parts.size() > 2) {
       diag->Error(android::DiagMessage()
                   << "Invalid feature flag and optional value '" << flag_and_value
-                  << "'. Must be in the format 'flag_name[=true|false]");
+                  << "'. Must be in the format 'flag_name[:ro][=true|false]");
       return false;
     }
 
@@ -137,6 +137,25 @@
       diag->Error(android::DiagMessage() << "No name given for one or more flags in: " << arg);
       return false;
     }
+    std::vector<std::string> name_parts = util::Split(flag_name, ':');
+    if (name_parts.size() > 2) {
+      diag->Error(android::DiagMessage()
+                  << "Invalid feature flag and optional value '" << flag_and_value
+                  << "'. Must be in the format 'flag_name[:ro][=true|false]");
+      return false;
+    }
+    flag_name = name_parts[0];
+    bool read_only = false;
+    if (name_parts.size() == 2) {
+      if (name_parts[1] == "ro") {
+        read_only = true;
+      } else {
+        diag->Error(android::DiagMessage()
+                    << "Invalid feature flag and optional value '" << flag_and_value
+                    << "'. Must be in the format 'flag_name[:ro][=true|false]");
+        return false;
+      }
+    }
 
     std::optional<bool> flag_value = {};
     if (parts.size() == 2) {
@@ -151,13 +170,13 @@
       }
     }
 
-    if (auto [it, inserted] =
-            out_feature_flag_values->try_emplace(std::string(flag_name), flag_value);
+    auto ffp = FeatureFlagProperties{read_only, flag_value};
+    if (auto [it, inserted] = out_feature_flag_values->try_emplace(std::string(flag_name), ffp);
         !inserted) {
       // We are allowing the same flag to appear multiple times, last value wins.
       diag->Note(android::DiagMessage()
                  << "Value for feature flag '" << flag_name << "' was given more than once");
-      it->second = flag_value;
+      it->second = ffp;
     }
   }
   return true;
diff --git a/tools/aapt2/cmd/Util.h b/tools/aapt2/cmd/Util.h
index 9ece5dd..6b8813b 100644
--- a/tools/aapt2/cmd/Util.h
+++ b/tools/aapt2/cmd/Util.h
@@ -37,7 +37,17 @@
 
 namespace aapt {
 
-using FeatureFlagValues = std::map<std::string, std::optional<bool>, std::less<>>;
+struct FeatureFlagProperties {
+  bool read_only;
+  std::optional<bool> enabled;
+
+  FeatureFlagProperties(bool ro, std::optional<bool> e) : read_only(ro), enabled(e) {
+  }
+
+  bool operator==(const FeatureFlagProperties&) const = default;
+};
+
+using FeatureFlagValues = std::map<std::string, FeatureFlagProperties, std::less<>>;
 
 // Parses a configuration density (ex. hdpi, xxhdpi, 234dpi, anydpi, etc).
 // Returns Nothing and logs a human friendly error message if the string was not legal.
diff --git a/tools/aapt2/cmd/Util_test.cpp b/tools/aapt2/cmd/Util_test.cpp
index 723d87e..35bc637 100644
--- a/tools/aapt2/cmd/Util_test.cpp
+++ b/tools/aapt2/cmd/Util_test.cpp
@@ -383,21 +383,25 @@
 TEST(UtilTest, ParseFeatureFlagsParameter_DuplicateFlag) {
   auto diagnostics = test::ContextBuilder().Build()->GetDiagnostics();
   FeatureFlagValues feature_flag_values;
-  ASSERT_TRUE(
-      ParseFeatureFlagsParameter("foo=true,bar=true,foo=false", diagnostics, &feature_flag_values));
-  EXPECT_THAT(feature_flag_values, UnorderedElementsAre(Pair("foo", std::optional<bool>(false)),
-                                                        Pair("bar", std::optional<bool>(true))));
+  ASSERT_TRUE(ParseFeatureFlagsParameter("foo=true,bar=true,foo:ro=false", diagnostics,
+                                         &feature_flag_values));
+  EXPECT_THAT(
+      feature_flag_values,
+      UnorderedElementsAre(Pair("foo", FeatureFlagProperties{true, std::optional<bool>(false)}),
+                           Pair("bar", FeatureFlagProperties{false, std::optional<bool>(true)})));
 }
 
 TEST(UtilTest, ParseFeatureFlagsParameter_Valid) {
   auto diagnostics = test::ContextBuilder().Build()->GetDiagnostics();
   FeatureFlagValues feature_flag_values;
-  ASSERT_TRUE(ParseFeatureFlagsParameter("foo= true, bar =FALSE,baz=, quux", diagnostics,
+  ASSERT_TRUE(ParseFeatureFlagsParameter("foo= true, bar:ro =FALSE,baz=, quux", diagnostics,
                                          &feature_flag_values));
-  EXPECT_THAT(feature_flag_values,
-              UnorderedElementsAre(Pair("foo", std::optional<bool>(true)),
-                                   Pair("bar", std::optional<bool>(false)),
-                                   Pair("baz", std::nullopt), Pair("quux", std::nullopt)));
+  EXPECT_THAT(
+      feature_flag_values,
+      UnorderedElementsAre(Pair("foo", FeatureFlagProperties{false, std::optional<bool>(true)}),
+                           Pair("bar", FeatureFlagProperties{true, std::optional<bool>(false)}),
+                           Pair("baz", FeatureFlagProperties{false, std::nullopt}),
+                           Pair("quux", FeatureFlagProperties{false, std::nullopt})));
 }
 
 TEST (UtilTest, AdjustSplitConstraintsForMinSdk) {
diff --git a/tools/aapt2/link/FeatureFlagsFilter.cpp b/tools/aapt2/link/FeatureFlagsFilter.cpp
index fdf3f74..9d40db5 100644
--- a/tools/aapt2/link/FeatureFlagsFilter.cpp
+++ b/tools/aapt2/link/FeatureFlagsFilter.cpp
@@ -63,12 +63,11 @@
         flag_name = flag_name.substr(1);
       }
 
-      if (auto it = feature_flag_values_.find(std::string(flag_name));
-          it != feature_flag_values_.end()) {
-        if (it->second.has_value()) {
+      if (auto it = feature_flag_values_.find(flag_name); it != feature_flag_values_.end()) {
+        if (it->second.enabled.has_value()) {
           if (options_.remove_disabled_elements) {
             // Remove if flag==true && attr=="!flag" (negated) OR flag==false && attr=="flag"
-            return *it->second == negated;
+            return *it->second.enabled == negated;
           }
         } else if (options_.flags_must_have_value) {
           diagnostics_->Error(android::DiagMessage(node->line_number)
diff --git a/tools/aapt2/link/FeatureFlagsFilter_test.cpp b/tools/aapt2/link/FeatureFlagsFilter_test.cpp
index 53086cc..2db2899 100644
--- a/tools/aapt2/link/FeatureFlagsFilter_test.cpp
+++ b/tools/aapt2/link/FeatureFlagsFilter_test.cpp
@@ -48,7 +48,7 @@
     <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
       <permission android:name="FOO" />
     </manifest>)EOF",
-                    {{"flag", false}});
+                    {{"flag", FeatureFlagProperties{false, false}}});
   ASSERT_THAT(doc, NotNull());
   auto root = doc->root.get();
   ASSERT_THAT(root, NotNull());
@@ -60,7 +60,7 @@
     <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
       <permission android:name="FOO" android:featureFlag="flag" />
     </manifest>)EOF",
-                    {{"flag", false}});
+                    {{"flag", FeatureFlagProperties{false, false}}});
   ASSERT_THAT(doc, NotNull());
   auto root = doc->root.get();
   ASSERT_THAT(root, NotNull());
@@ -73,7 +73,7 @@
     <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
       <permission android:name="FOO" android:featureFlag="!flag" />
     </manifest>)EOF",
-                    {{"flag", true}});
+                    {{"flag", FeatureFlagProperties{false, true}}});
   ASSERT_THAT(doc, NotNull());
   auto root = doc->root.get();
   ASSERT_THAT(root, NotNull());
@@ -86,7 +86,7 @@
     <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
       <permission android:name="FOO" android:featureFlag="flag" />
     </manifest>)EOF",
-                    {{"flag", true}});
+                    {{"flag", FeatureFlagProperties{false, true}}});
   ASSERT_THAT(doc, NotNull());
   auto root = doc->root.get();
   ASSERT_THAT(root, NotNull());
@@ -102,7 +102,7 @@
       <permission android:name="FOO" android:featureFlag="flag"
                   android:protectionLevel="dangerous" />
     </manifest>)EOF",
-                    {{"flag", true}});
+                    {{"flag", FeatureFlagProperties{false, true}}});
   ASSERT_THAT(doc, NotNull());
   auto root = doc->root.get();
   ASSERT_THAT(root, NotNull());
@@ -123,7 +123,7 @@
         </activity>
       </application>
     </manifest>)EOF",
-                    {{"flag", true}});
+                    {{"flag", FeatureFlagProperties{false, true}}});
   ASSERT_THAT(doc, NotNull());
   auto root = doc->root.get();
   ASSERT_THAT(root, NotNull());
@@ -145,7 +145,7 @@
         </activity>
       </application>
     </manifest>)EOF",
-                    {{"flag", true}});
+                    {{"flag", FeatureFlagProperties{false, true}}});
   ASSERT_THAT(doc, NotNull());
   auto root = doc->root.get();
   ASSERT_THAT(root, NotNull());
@@ -162,7 +162,7 @@
     <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
       <permission android:name="FOO" android:featureFlag=" " />
     </manifest>)EOF",
-                    {{"flag", false}});
+                    {{"flag", FeatureFlagProperties{false, false}}});
   ASSERT_THAT(doc, IsNull());
 }
 
@@ -171,7 +171,7 @@
     <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
       <permission android:name="FOO" android:featureFlag="flag" />
     </manifest>)EOF",
-                    {{"flag", std::nullopt}});
+                    {{"flag", FeatureFlagProperties{false, std::nullopt}}});
   ASSERT_THAT(doc, IsNull());
 }
 
@@ -180,7 +180,7 @@
     <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
       <permission android:name="FOO" android:featureFlag="unrecognized" />
     </manifest>)EOF",
-                    {{"flag", true}});
+                    {{"flag", FeatureFlagProperties{false, true}}});
   ASSERT_THAT(doc, IsNull());
 }
 
@@ -190,7 +190,7 @@
       <permission android:name="FOO" android:featureFlag="bar" />
       <permission android:name="FOO" android:featureFlag="unrecognized" />
     </manifest>)EOF",
-                    {{"flag", std::nullopt}});
+                    {{"flag", FeatureFlagProperties{false, std::nullopt}}});
   ASSERT_THAT(doc, IsNull());
 }
 
@@ -199,7 +199,8 @@
     <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
       <permission android:name="FOO" android:featureFlag="flag" />
     </manifest>)EOF",
-                               {{"flag", false}}, {.remove_disabled_elements = false});
+                               {{"flag", FeatureFlagProperties{false, false}}},
+                               {.remove_disabled_elements = false});
   ASSERT_THAT(doc, NotNull());
   auto root = doc->root.get();
   ASSERT_THAT(root, NotNull());
@@ -212,7 +213,8 @@
     <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
       <permission android:name="FOO" android:featureFlag="flag" />
     </manifest>)EOF",
-                               {{"flag", std::nullopt}}, {.flags_must_have_value = false});
+                               {{"flag", FeatureFlagProperties{false, std::nullopt}}},
+                               {.flags_must_have_value = false});
   ASSERT_THAT(doc, NotNull());
   auto root = doc->root.get();
   ASSERT_THAT(root, NotNull());
@@ -225,7 +227,8 @@
     <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android">
       <permission android:name="FOO" android:featureFlag="unrecognized" />
     </manifest>)EOF",
-                               {{"flag", true}}, {.fail_on_unrecognized_flags = false});
+                               {{"flag", FeatureFlagProperties{false, true}}},
+                               {.fail_on_unrecognized_flags = false});
   ASSERT_THAT(doc, NotNull());
   auto root = doc->root.get();
   ASSERT_THAT(root, NotNull());
diff --git a/tools/aapt2/test/Fixture.h b/tools/aapt2/test/Fixture.h
index ba4a734..14298d16 100644
--- a/tools/aapt2/test/Fixture.h
+++ b/tools/aapt2/test/Fixture.h
@@ -127,4 +127,4 @@
 
 } // namespace aapt
 
-#endif  // AAPT_TEST_FIXTURE_H
\ No newline at end of file
+#endif  // AAPT_TEST_FIXTURE_H
diff --git a/tools/aapt2/xml/XmlPullParser.cpp b/tools/aapt2/xml/XmlPullParser.cpp
index 203832d..8abc26d 100644
--- a/tools/aapt2/xml/XmlPullParser.cpp
+++ b/tools/aapt2/xml/XmlPullParser.cpp
@@ -14,11 +14,13 @@
  * limitations under the License.
  */
 
-#include <iostream>
+#include "xml/XmlPullParser.h"
+
+#include <algorithm>
 #include <string>
+#include <tuple>
 
 #include "util/Util.h"
-#include "xml/XmlPullParser.h"
 #include "xml/XmlUtil.h"
 
 using ::android::InputStream;
@@ -325,5 +327,18 @@
   return {};
 }
 
+XmlPullParser::const_iterator XmlPullParser::FindAttribute(android::StringPiece namespace_uri,
+                                                           android::StringPiece name) const {
+  const auto end_iter = end_attributes();
+  const auto iter = std::lower_bound(begin_attributes(), end_iter, std::tuple(namespace_uri, name),
+                                     [](const Attribute& attr, const auto& rhs) {
+                                       return std::tie(attr.namespace_uri, attr.name) < rhs;
+                                     });
+  if (iter != end_iter && namespace_uri == iter->namespace_uri && name == iter->name) {
+    return iter;
+  }
+  return end_iter;
+}
+
 }  // namespace xml
 }  // namespace aapt
diff --git a/tools/aapt2/xml/XmlPullParser.h b/tools/aapt2/xml/XmlPullParser.h
index 655e6dc..64274d0 100644
--- a/tools/aapt2/xml/XmlPullParser.h
+++ b/tools/aapt2/xml/XmlPullParser.h
@@ -19,8 +19,7 @@
 
 #include <expat.h>
 
-#include <algorithm>
-#include <istream>
+#include <optional>
 #include <ostream>
 #include <queue>
 #include <stack>
@@ -302,31 +301,6 @@
   return compare(rhs) != 0;
 }
 
-inline XmlPullParser::const_iterator XmlPullParser::FindAttribute(
-    android::StringPiece namespace_uri, android::StringPiece name) const {
-  const auto end_iter = end_attributes();
-  const auto iter = std::lower_bound(
-      begin_attributes(), end_iter,
-      std::pair<android::StringPiece, android::StringPiece>(namespace_uri, name),
-      [](const Attribute& attr,
-         const std::pair<android::StringPiece, android::StringPiece>& rhs) -> bool {
-        int cmp = attr.namespace_uri.compare(
-            0, attr.namespace_uri.size(), rhs.first.data(), rhs.first.size());
-        if (cmp < 0) return true;
-        if (cmp > 0) return false;
-        cmp = attr.name.compare(0, attr.name.size(), rhs.second.data(),
-                                rhs.second.size());
-        if (cmp < 0) return true;
-        return false;
-      });
-
-  if (iter != end_iter && namespace_uri == iter->namespace_uri &&
-      name == iter->name) {
-    return iter;
-  }
-  return end_iter;
-}
-
 }  // namespace xml
 }  // namespace aapt
 
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfo.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfo.java
index 129733e..f397225 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfo.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfo.java
@@ -25,99 +25,42 @@
 
 /** AppInfo representation */
 public class AppInfo implements AslMarshallable {
-    private final String mTitle;
-    private final String mDescription;
-    private final Boolean mContainsAds;
-    private final Boolean mObeyAps;
-    private final Boolean mAdsFingerprinting;
-    private final Boolean mSecurityFingerprinting;
+    private final Boolean mApsCompliant;
     private final String mPrivacyPolicy;
-    private final List<String> mSecurityEndpoints;
     private final List<String> mFirstPartyEndpoints;
     private final List<String> mServiceProviderEndpoints;
-    private final String mCategory;
-    private final String mEmail;
-    private final String mWebsite;
 
     public AppInfo(
-            String title,
-            String description,
-            Boolean containsAds,
-            Boolean obeyAps,
-            Boolean adsFingerprinting,
-            Boolean securityFingerprinting,
+            Boolean apsCompliant,
             String privacyPolicy,
-            List<String> securityEndpoints,
             List<String> firstPartyEndpoints,
-            List<String> serviceProviderEndpoints,
-            String category,
-            String email,
-            String website) {
-        this.mTitle = title;
-        this.mDescription = description;
-        this.mContainsAds = containsAds;
-        this.mObeyAps = obeyAps;
-        this.mAdsFingerprinting = adsFingerprinting;
-        this.mSecurityFingerprinting = securityFingerprinting;
+            List<String> serviceProviderEndpoints) {
+        this.mApsCompliant = apsCompliant;
         this.mPrivacyPolicy = privacyPolicy;
-        this.mSecurityEndpoints = securityEndpoints;
         this.mFirstPartyEndpoints = firstPartyEndpoints;
         this.mServiceProviderEndpoints = serviceProviderEndpoints;
-        this.mCategory = category;
-        this.mEmail = email;
-        this.mWebsite = website;
     }
 
     /** Creates an on-device DOM element from the {@link SafetyLabels}. */
     @Override
     public List<Element> toOdDomElements(Document doc) {
         Element appInfoEle = XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_APP_INFO);
-        if (this.mTitle != null) {
-            appInfoEle.appendChild(XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_TITLE, mTitle));
-        }
-        if (this.mDescription != null) {
-            appInfoEle.appendChild(
-                    XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_DESCRIPTION, mDescription));
-        }
-        if (this.mContainsAds != null) {
-            appInfoEle.appendChild(
-                    XmlUtils.createOdBooleanEle(doc, XmlUtils.OD_NAME_CONTAINS_ADS, mContainsAds));
-        }
-        if (this.mObeyAps != null) {
-            appInfoEle.appendChild(
-                    XmlUtils.createOdBooleanEle(doc, XmlUtils.OD_NAME_OBEY_APS, mObeyAps));
-        }
-        if (this.mAdsFingerprinting != null) {
+        if (this.mApsCompliant != null) {
             appInfoEle.appendChild(
                     XmlUtils.createOdBooleanEle(
-                            doc, XmlUtils.OD_NAME_ADS_FINGERPRINTING, mAdsFingerprinting));
-        }
-        if (this.mSecurityFingerprinting != null) {
-            appInfoEle.appendChild(
-                    XmlUtils.createOdBooleanEle(
-                            doc,
-                            XmlUtils.OD_NAME_SECURITY_FINGERPRINTING,
-                            mSecurityFingerprinting));
+                            doc, XmlUtils.OD_NAME_APS_COMPLIANT, mApsCompliant));
         }
         if (this.mPrivacyPolicy != null) {
             appInfoEle.appendChild(
                     XmlUtils.createOdStringEle(
                             doc, XmlUtils.OD_NAME_PRIVACY_POLICY, mPrivacyPolicy));
         }
-        if (this.mSecurityEndpoints != null) {
-            appInfoEle.appendChild(
-                    XmlUtils.createOdArray(
-                            doc,
-                            XmlUtils.OD_TAG_STRING_ARRAY,
-                            XmlUtils.OD_NAME_SECURITY_ENDPOINT,
-                            mSecurityEndpoints));
-        }
         if (this.mFirstPartyEndpoints != null) {
             appInfoEle.appendChild(
                     XmlUtils.createOdArray(
                             doc,
                             XmlUtils.OD_TAG_STRING_ARRAY,
-                            XmlUtils.OD_NAME_FIRST_PARTY_ENDPOINT,
+                            XmlUtils.OD_NAME_FIRST_PARTY_ENDPOINTS,
                             mFirstPartyEndpoints));
         }
         if (this.mServiceProviderEndpoints != null) {
@@ -125,21 +68,9 @@
                     XmlUtils.createOdArray(
                             doc,
                             XmlUtils.OD_TAG_STRING_ARRAY,
-                            XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINT,
+                            XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINTS,
                             mServiceProviderEndpoints));
         }
-        if (this.mCategory != null) {
-            appInfoEle.appendChild(
-                    XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_CATEGORY, this.mCategory));
-        }
-        if (this.mEmail != null) {
-            appInfoEle.appendChild(
-                    XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_EMAIL, this.mEmail));
-        }
-        if (this.mWebsite != null) {
-            appInfoEle.appendChild(
-                    XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_WEBSITE, this.mWebsite));
-        }
         return XmlUtils.listOf(appInfoEle);
     }
 
@@ -147,54 +78,28 @@
     @Override
     public List<Element> toHrDomElements(Document doc) {
         Element appInfoEle = doc.createElement(XmlUtils.HR_TAG_APP_INFO);
-        if (this.mTitle != null) {
-            appInfoEle.setAttribute(XmlUtils.HR_ATTR_TITLE, this.mTitle);
-        }
-        if (this.mDescription != null) {
-            appInfoEle.setAttribute(XmlUtils.HR_ATTR_DESCRIPTION, this.mDescription);
-        }
-        if (this.mContainsAds != null) {
+        if (this.mApsCompliant != null) {
             appInfoEle.setAttribute(
-                    XmlUtils.HR_ATTR_CONTAINS_ADS, String.valueOf(this.mContainsAds));
-        }
-        if (this.mObeyAps != null) {
-            appInfoEle.setAttribute(XmlUtils.HR_ATTR_OBEY_APS, String.valueOf(this.mObeyAps));
-        }
-        if (this.mAdsFingerprinting != null) {
-            appInfoEle.setAttribute(
-                    XmlUtils.HR_ATTR_ADS_FINGERPRINTING, String.valueOf(this.mAdsFingerprinting));
-        }
-        if (this.mSecurityFingerprinting != null) {
-            appInfoEle.setAttribute(
-                    XmlUtils.HR_ATTR_SECURITY_FINGERPRINTING,
-                    String.valueOf(this.mSecurityFingerprinting));
+                    XmlUtils.HR_ATTR_APS_COMPLIANT, String.valueOf(this.mApsCompliant));
         }
         if (this.mPrivacyPolicy != null) {
             appInfoEle.setAttribute(XmlUtils.HR_ATTR_PRIVACY_POLICY, this.mPrivacyPolicy);
         }
-        if (this.mSecurityEndpoints != null) {
-            appInfoEle.setAttribute(
-                    XmlUtils.HR_ATTR_SECURITY_ENDPOINTS, String.join("|", this.mSecurityEndpoints));
-        }
+
         if (this.mFirstPartyEndpoints != null) {
-            appInfoEle.setAttribute(
-                    XmlUtils.HR_ATTR_FIRST_PARTY_ENDPOINTS,
-                    String.join("|", this.mFirstPartyEndpoints));
+            appInfoEle.appendChild(
+                    XmlUtils.createHrArray(
+                            doc, XmlUtils.HR_TAG_FIRST_PARTY_ENDPOINTS, mFirstPartyEndpoints));
         }
+
         if (this.mServiceProviderEndpoints != null) {
-            appInfoEle.setAttribute(
-                    XmlUtils.HR_ATTR_SERVICE_PROVIDER_ENDPOINTS,
-                    String.join("|", this.mServiceProviderEndpoints));
+            appInfoEle.appendChild(
+                    XmlUtils.createHrArray(
+                            doc,
+                            XmlUtils.HR_TAG_SERVICE_PROVIDER_ENDPOINTS,
+                            mServiceProviderEndpoints));
         }
-        if (this.mCategory != null) {
-            appInfoEle.setAttribute(XmlUtils.HR_ATTR_CATEGORY, this.mCategory);
-        }
-        if (this.mEmail != null) {
-            appInfoEle.setAttribute(XmlUtils.HR_ATTR_EMAIL, this.mEmail);
-        }
-        if (this.mWebsite != null) {
-            appInfoEle.setAttribute(XmlUtils.HR_ATTR_WEBSITE, this.mWebsite);
-        }
+
         return XmlUtils.listOf(appInfoEle);
     }
 }
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfoFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfoFactory.java
index c506961..6ad2027 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfoFactory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfoFactory.java
@@ -35,43 +35,19 @@
             return null;
         }
 
-        String title = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_TITLE, true);
-        String description = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_DESCRIPTION, true);
-        Boolean containsAds = XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_CONTAINS_ADS, true);
-        Boolean obeyAps = XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_OBEY_APS, true);
-        Boolean adsFingerprinting =
-                XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_ADS_FINGERPRINTING, true);
-        Boolean securityFingerprinting =
-                XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_SECURITY_FINGERPRINTING, true);
+        Boolean apsCompliant =
+                XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_APS_COMPLIANT, true);
         String privacyPolicy =
                 XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_PRIVACY_POLICY, true);
-        List<String> securityEndpoints =
-                XmlUtils.getPipelineSplitAttr(
-                        appInfoEle, XmlUtils.HR_ATTR_SECURITY_ENDPOINTS, true);
         List<String> firstPartyEndpoints =
-                XmlUtils.getPipelineSplitAttr(
-                        appInfoEle, XmlUtils.HR_ATTR_FIRST_PARTY_ENDPOINTS, true);
+                XmlUtils.getHrItemsAsStrings(
+                        appInfoEle, XmlUtils.HR_TAG_FIRST_PARTY_ENDPOINTS, true);
         List<String> serviceProviderEndpoints =
-                XmlUtils.getPipelineSplitAttr(
-                        appInfoEle, XmlUtils.HR_ATTR_SERVICE_PROVIDER_ENDPOINTS, true);
-        String category = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_CATEGORY, true);
-        String email = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_EMAIL, true);
-        String website = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_WEBSITE, false);
+                XmlUtils.getHrItemsAsStrings(
+                        appInfoEle, XmlUtils.HR_TAG_SERVICE_PROVIDER_ENDPOINTS, true);
 
         return new AppInfo(
-                title,
-                description,
-                containsAds,
-                obeyAps,
-                adsFingerprinting,
-                securityFingerprinting,
-                privacyPolicy,
-                securityEndpoints,
-                firstPartyEndpoints,
-                serviceProviderEndpoints,
-                category,
-                email,
-                website);
+                apsCompliant, privacyPolicy, firstPartyEndpoints, serviceProviderEndpoints);
     }
 
     /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */
@@ -83,42 +59,17 @@
             return null;
         }
 
-        String title = XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_TITLE, true);
-        String description =
-                XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_DESCRIPTION, true);
-        Boolean containsAds =
-                XmlUtils.getOdBoolEle(appInfoEle, XmlUtils.OD_NAME_CONTAINS_ADS, true);
-        Boolean obeyAps = XmlUtils.getOdBoolEle(appInfoEle, XmlUtils.OD_NAME_OBEY_APS, true);
-        Boolean adsFingerprinting =
-                XmlUtils.getOdBoolEle(appInfoEle, XmlUtils.OD_NAME_ADS_FINGERPRINTING, true);
-        Boolean securityFingerprinting =
-                XmlUtils.getOdBoolEle(appInfoEle, XmlUtils.OD_NAME_SECURITY_FINGERPRINTING, true);
+        Boolean apsCompliant =
+                XmlUtils.getOdBoolEle(appInfoEle, XmlUtils.OD_NAME_APS_COMPLIANT, true);
         String privacyPolicy =
                 XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_PRIVACY_POLICY, true);
-        List<String> securityEndpoints =
-                XmlUtils.getOdStringArray(appInfoEle, XmlUtils.OD_NAME_SECURITY_ENDPOINT, true);
         List<String> firstPartyEndpoints =
-                XmlUtils.getOdStringArray(appInfoEle, XmlUtils.OD_NAME_FIRST_PARTY_ENDPOINT, true);
+                XmlUtils.getOdStringArray(appInfoEle, XmlUtils.OD_NAME_FIRST_PARTY_ENDPOINTS, true);
         List<String> serviceProviderEndpoints =
                 XmlUtils.getOdStringArray(
-                        appInfoEle, XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINT, true);
-        String category = XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_CATEGORY, true);
-        String email = XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_EMAIL, true);
-        String website = XmlUtils.getOdStringEle(appInfoEle, XmlUtils.OD_NAME_WEBSITE, false);
+                        appInfoEle, XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINTS, true);
 
         return new AppInfo(
-                title,
-                description,
-                containsAds,
-                obeyAps,
-                adsFingerprinting,
-                securityFingerprinting,
-                privacyPolicy,
-                securityEndpoints,
-                firstPartyEndpoints,
-                serviceProviderEndpoints,
-                category,
-                email,
-                website);
+                apsCompliant, privacyPolicy, firstPartyEndpoints, serviceProviderEndpoints);
     }
 }
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabels.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabels.java
index ba0e3db..3c93c88 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabels.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabels.java
@@ -24,6 +24,7 @@
 
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * Data label representation with data shared and data collected maps containing zero or more {@link
@@ -138,7 +139,7 @@
                                 "|",
                                 dataType.getPurposes().stream()
                                         .map(DataType.Purpose::toString)
-                                        .toList()));
+                                        .collect(Collectors.toList())));
                 dataLabelsEle.appendChild(hrDataTypeEle);
             }
         }
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java
index d2326d1..284a4b8 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java
@@ -25,6 +25,7 @@
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * Data usage type representation. Types are specific to a {@link DataCategory} and contains
@@ -182,7 +183,7 @@
                             XmlUtils.OD_NAME_PURPOSES,
                             this.getPurposes().stream()
                                     .map(p -> String.valueOf(p.getValue()))
-                                    .toList()));
+                                    .collect(Collectors.toList())));
         }
 
         maybeAddBoolToOdElement(
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfo.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfo.java
deleted file mode 100644
index 94fad96..0000000
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfo.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.asllib.marshallable;
-
-import com.android.asllib.util.XmlUtils;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-import java.util.List;
-
-/** DeveloperInfo representation */
-public class DeveloperInfo implements AslMarshallable {
-    public enum DeveloperRelationship {
-        OEM(0),
-        ODM(1),
-        SOC(2),
-        OTA(3),
-        CARRIER(4),
-        AOSP(5),
-        OTHER(6);
-
-        private final int mValue;
-
-        DeveloperRelationship(int value) {
-            this.mValue = value;
-        }
-
-        /** Get the int value associated with the DeveloperRelationship. */
-        public int getValue() {
-            return mValue;
-        }
-
-        /** Get the DeveloperRelationship associated with the int value. */
-        public static DeveloperInfo.DeveloperRelationship forValue(int value) {
-            for (DeveloperInfo.DeveloperRelationship e : values()) {
-                if (e.getValue() == value) {
-                    return e;
-                }
-            }
-            throw new IllegalArgumentException("No DeveloperRelationship enum for value: " + value);
-        }
-
-        /** Get the DeveloperRelationship associated with the human-readable String. */
-        public static DeveloperInfo.DeveloperRelationship forString(String s) {
-            for (DeveloperInfo.DeveloperRelationship e : values()) {
-                if (e.toString().equals(s)) {
-                    return e;
-                }
-            }
-            throw new IllegalArgumentException("No DeveloperRelationship enum for str: " + s);
-        }
-
-        /** Human-readable String representation of DeveloperRelationship. */
-        public String toString() {
-            return this.name().toLowerCase();
-        }
-    }
-
-    private final String mName;
-    private final String mEmail;
-    private final String mAddress;
-    private final String mCountryRegion;
-    private final DeveloperRelationship mDeveloperRelationship;
-    private final String mWebsite;
-    private final String mAppDeveloperRegistryId;
-
-    public DeveloperInfo(
-            String name,
-            String email,
-            String address,
-            String countryRegion,
-            DeveloperRelationship developerRelationship,
-            String website,
-            String appDeveloperRegistryId) {
-        this.mName = name;
-        this.mEmail = email;
-        this.mAddress = address;
-        this.mCountryRegion = countryRegion;
-        this.mDeveloperRelationship = developerRelationship;
-        this.mWebsite = website;
-        this.mAppDeveloperRegistryId = appDeveloperRegistryId;
-    }
-
-    /** Creates an on-device DOM element from the {@link SafetyLabels}. */
-    @Override
-    public List<Element> toOdDomElements(Document doc) {
-        Element developerInfoEle =
-                XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_DEVELOPER_INFO);
-        if (mName != null) {
-            developerInfoEle.appendChild(
-                    XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_NAME, mName));
-        }
-        if (mEmail != null) {
-            developerInfoEle.appendChild(
-                    XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_EMAIL, mEmail));
-        }
-        if (mAddress != null) {
-            developerInfoEle.appendChild(
-                    XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_ADDRESS, mAddress));
-        }
-        if (mCountryRegion != null) {
-            developerInfoEle.appendChild(
-                    XmlUtils.createOdStringEle(
-                            doc, XmlUtils.OD_NAME_COUNTRY_REGION, mCountryRegion));
-        }
-        if (mDeveloperRelationship != null) {
-            developerInfoEle.appendChild(
-                    XmlUtils.createOdLongEle(
-                            doc,
-                            XmlUtils.OD_NAME_DEVELOPER_RELATIONSHIP,
-                            mDeveloperRelationship.getValue()));
-        }
-        if (mWebsite != null) {
-            developerInfoEle.appendChild(
-                    XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_WEBSITE, mWebsite));
-        }
-        if (mAppDeveloperRegistryId != null) {
-            developerInfoEle.appendChild(
-                    XmlUtils.createOdStringEle(
-                            doc,
-                            XmlUtils.OD_NAME_APP_DEVELOPER_REGISTRY_ID,
-                            mAppDeveloperRegistryId));
-        }
-
-        return XmlUtils.listOf(developerInfoEle);
-    }
-
-    /** Creates the human-readable DOM elements from the AslMarshallable Java Object. */
-    @Override
-    public List<Element> toHrDomElements(Document doc) {
-        Element developerInfoEle = doc.createElement(XmlUtils.HR_TAG_DEVELOPER_INFO);
-        if (mName != null) {
-            developerInfoEle.setAttribute(XmlUtils.HR_ATTR_NAME, mName);
-        }
-        if (mEmail != null) {
-            developerInfoEle.setAttribute(XmlUtils.HR_ATTR_EMAIL, mEmail);
-        }
-        if (mAddress != null) {
-            developerInfoEle.setAttribute(XmlUtils.HR_ATTR_ADDRESS, mAddress);
-        }
-        if (mCountryRegion != null) {
-            developerInfoEle.setAttribute(XmlUtils.HR_ATTR_COUNTRY_REGION, mCountryRegion);
-        }
-        if (mDeveloperRelationship != null) {
-            developerInfoEle.setAttribute(
-                    XmlUtils.HR_ATTR_DEVELOPER_RELATIONSHIP, mDeveloperRelationship.toString());
-        }
-        if (mWebsite != null) {
-            developerInfoEle.setAttribute(XmlUtils.HR_ATTR_WEBSITE, mWebsite);
-        }
-        if (mAppDeveloperRegistryId != null) {
-            developerInfoEle.setAttribute(
-                    XmlUtils.HR_ATTR_APP_DEVELOPER_REGISTRY_ID, mAppDeveloperRegistryId);
-        }
-
-        return XmlUtils.listOf(developerInfoEle);
-    }
-}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfoFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfoFactory.java
deleted file mode 100644
index 0f3b41c..0000000
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfoFactory.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.asllib.marshallable;
-
-import com.android.asllib.util.AslgenUtil;
-import com.android.asllib.util.MalformedXmlException;
-import com.android.asllib.util.XmlUtils;
-
-import org.w3c.dom.Element;
-
-import java.util.List;
-
-public class DeveloperInfoFactory implements AslMarshallableFactory<DeveloperInfo> {
-
-    /** Creates a {@link DeveloperInfo} from the human-readable DOM element. */
-    @Override
-    public DeveloperInfo createFromHrElements(List<Element> elements) throws MalformedXmlException {
-        Element developerInfoEle = XmlUtils.getSingleElement(elements);
-        if (developerInfoEle == null) {
-            AslgenUtil.logI("No DeveloperInfo found in hr format.");
-            return null;
-        }
-        String name = XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_NAME, true);
-        String email = XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_EMAIL, true);
-        String address = XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_ADDRESS, true);
-        String countryRegion =
-                XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_COUNTRY_REGION, true);
-        DeveloperInfo.DeveloperRelationship developerRelationship =
-                DeveloperInfo.DeveloperRelationship.forString(
-                        XmlUtils.getStringAttr(
-                                developerInfoEle, XmlUtils.HR_ATTR_DEVELOPER_RELATIONSHIP, true));
-        String website = XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_WEBSITE, false);
-        String appDeveloperRegistryId =
-                XmlUtils.getStringAttr(
-                        developerInfoEle, XmlUtils.HR_ATTR_APP_DEVELOPER_REGISTRY_ID, false);
-
-        return new DeveloperInfo(
-                name,
-                email,
-                address,
-                countryRegion,
-                developerRelationship,
-                website,
-                appDeveloperRegistryId);
-    }
-
-    /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */
-    @Override
-    public DeveloperInfo createFromOdElements(List<Element> elements) throws MalformedXmlException {
-        Element developerInfoEle = XmlUtils.getSingleElement(elements);
-        if (developerInfoEle == null) {
-            AslgenUtil.logI("No DeveloperInfo found in od format.");
-            return null;
-        }
-        String name = XmlUtils.getOdStringEle(developerInfoEle, XmlUtils.OD_NAME_NAME, true);
-        String email = XmlUtils.getOdStringEle(developerInfoEle, XmlUtils.OD_NAME_EMAIL, true);
-        String address = XmlUtils.getOdStringEle(developerInfoEle, XmlUtils.OD_NAME_ADDRESS, true);
-        String countryRegion =
-                XmlUtils.getOdStringEle(developerInfoEle, XmlUtils.OD_NAME_COUNTRY_REGION, true);
-        DeveloperInfo.DeveloperRelationship developerRelationship =
-                DeveloperInfo.DeveloperRelationship.forValue(
-                        (int)
-                                (long)
-                                        XmlUtils.getOdLongEle(
-                                                developerInfoEle,
-                                                XmlUtils.OD_NAME_DEVELOPER_RELATIONSHIP,
-                                                true));
-        String website = XmlUtils.getOdStringEle(developerInfoEle, XmlUtils.OD_NAME_WEBSITE, false);
-        String appDeveloperRegistryId =
-                XmlUtils.getOdStringEle(
-                        developerInfoEle, XmlUtils.OD_NAME_APP_DEVELOPER_REGISTRY_ID, false);
-
-        return new DeveloperInfo(
-                name,
-                email,
-                address,
-                countryRegion,
-                developerRelationship,
-                website,
-                appDeveloperRegistryId);
-    }
-}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java
index 6af8071..2a4e130 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java
@@ -25,21 +25,10 @@
 
 /** Safety Label representation containing zero or more {@link DataCategory} for data shared */
 public class SafetyLabels implements AslMarshallable {
-
-    private final Long mVersion;
     private final DataLabels mDataLabels;
-    private final SecurityLabels mSecurityLabels;
-    private final ThirdPartyVerification mThirdPartyVerification;
 
-    public SafetyLabels(
-            Long version,
-            DataLabels dataLabels,
-            SecurityLabels securityLabels,
-            ThirdPartyVerification thirdPartyVerification) {
-        this.mVersion = version;
+    public SafetyLabels(DataLabels dataLabels) {
         this.mDataLabels = dataLabels;
-        this.mSecurityLabels = securityLabels;
-        this.mThirdPartyVerification = thirdPartyVerification;
     }
 
     /** Returns the data label for the safety label */
@@ -47,27 +36,14 @@
         return mDataLabels;
     }
 
-    /** Gets the version of the {@link SafetyLabels}. */
-    public Long getVersion() {
-        return mVersion;
-    }
-
     /** Creates an on-device DOM element from the {@link SafetyLabels}. */
     @Override
     public List<Element> toOdDomElements(Document doc) {
         Element safetyLabelsEle =
                 XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_SAFETY_LABELS);
-        safetyLabelsEle.appendChild(
-                XmlUtils.createOdLongEle(doc, XmlUtils.OD_NAME_VERSION, mVersion));
         if (mDataLabels != null) {
             XmlUtils.appendChildren(safetyLabelsEle, mDataLabels.toOdDomElements(doc));
         }
-        if (mSecurityLabels != null) {
-            XmlUtils.appendChildren(safetyLabelsEle, mSecurityLabels.toOdDomElements(doc));
-        }
-        if (mThirdPartyVerification != null) {
-            XmlUtils.appendChildren(safetyLabelsEle, mThirdPartyVerification.toOdDomElements(doc));
-        }
         return XmlUtils.listOf(safetyLabelsEle);
     }
 
@@ -75,17 +51,10 @@
     @Override
     public List<Element> toHrDomElements(Document doc) {
         Element safetyLabelsEle = doc.createElement(XmlUtils.HR_TAG_SAFETY_LABELS);
-        safetyLabelsEle.setAttribute(XmlUtils.HR_ATTR_VERSION, String.valueOf(mVersion));
 
         if (mDataLabels != null) {
             XmlUtils.appendChildren(safetyLabelsEle, mDataLabels.toHrDomElements(doc));
         }
-        if (mSecurityLabels != null) {
-            XmlUtils.appendChildren(safetyLabelsEle, mSecurityLabels.toHrDomElements(doc));
-        }
-        if (mThirdPartyVerification != null) {
-            XmlUtils.appendChildren(safetyLabelsEle, mThirdPartyVerification.toHrDomElements(doc));
-        }
         return XmlUtils.listOf(safetyLabelsEle);
     }
 }
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java
index 2644b43..2738337 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java
@@ -34,7 +34,6 @@
             AslgenUtil.logI("No SafetyLabels found in hr format.");
             return null;
         }
-        long version = XmlUtils.tryGetVersion(safetyLabelsEle);
 
         DataLabels dataLabels =
                 new DataLabelsFactory()
@@ -44,23 +43,7 @@
                                                 safetyLabelsEle,
                                                 XmlUtils.HR_TAG_DATA_LABELS,
                                                 false)));
-        SecurityLabels securityLabels =
-                new SecurityLabelsFactory()
-                        .createFromHrElements(
-                                XmlUtils.listOf(
-                                        XmlUtils.getSingleChildElement(
-                                                safetyLabelsEle,
-                                                XmlUtils.HR_TAG_SECURITY_LABELS,
-                                                false)));
-        ThirdPartyVerification thirdPartyVerification =
-                new ThirdPartyVerificationFactory()
-                        .createFromHrElements(
-                                XmlUtils.listOf(
-                                        XmlUtils.getSingleChildElement(
-                                                safetyLabelsEle,
-                                                XmlUtils.HR_TAG_THIRD_PARTY_VERIFICATION,
-                                                false)));
-        return new SafetyLabels(version, dataLabels, securityLabels, thirdPartyVerification);
+        return new SafetyLabels(dataLabels);
     }
 
     /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */
@@ -71,7 +54,6 @@
             AslgenUtil.logI("No SafetyLabels found in od format.");
             return null;
         }
-        Long version = XmlUtils.getOdLongEle(safetyLabelsEle, XmlUtils.OD_NAME_VERSION, true);
 
         DataLabels dataLabels =
                 new DataLabelsFactory()
@@ -81,22 +63,7 @@
                                                 safetyLabelsEle,
                                                 XmlUtils.OD_NAME_DATA_LABELS,
                                                 false)));
-        SecurityLabels securityLabels =
-                new SecurityLabelsFactory()
-                        .createFromOdElements(
-                                XmlUtils.listOf(
-                                        XmlUtils.getOdPbundleWithName(
-                                                safetyLabelsEle,
-                                                XmlUtils.OD_NAME_SECURITY_LABELS,
-                                                false)));
-        ThirdPartyVerification thirdPartyVerification =
-                new ThirdPartyVerificationFactory()
-                        .createFromOdElements(
-                                XmlUtils.listOf(
-                                        XmlUtils.getOdPbundleWithName(
-                                                safetyLabelsEle,
-                                                XmlUtils.OD_NAME_THIRD_PARTY_VERIFICATION,
-                                                false)));
-        return new SafetyLabels(version, dataLabels, securityLabels, thirdPartyVerification);
+
+        return new SafetyLabels(dataLabels);
     }
 }
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfo.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfo.java
index 6a8700a..9f789f0 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfo.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfo.java
@@ -23,22 +23,14 @@
 
 import java.util.List;
 
-/** TransparencyInfo representation containing {@link DeveloperInfo} and {@link AppInfo} */
+/** TransparencyInfo representation containing {@link AppInfo} */
 public class TransparencyInfo implements AslMarshallable {
-
-    private final DeveloperInfo mDeveloperInfo;
     private final AppInfo mAppInfo;
 
-    public TransparencyInfo(DeveloperInfo developerInfo, AppInfo appInfo) {
-        this.mDeveloperInfo = developerInfo;
+    public TransparencyInfo(AppInfo appInfo) {
         this.mAppInfo = appInfo;
     }
 
-    /** Gets the {@link DeveloperInfo} of the {@link TransparencyInfo}. */
-    public DeveloperInfo getDeveloperInfo() {
-        return mDeveloperInfo;
-    }
-
     /** Gets the {@link AppInfo} of the {@link TransparencyInfo}. */
     public AppInfo getAppInfo() {
         return mAppInfo;
@@ -49,9 +41,6 @@
     public List<Element> toOdDomElements(Document doc) {
         Element transparencyInfoEle =
                 XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_TRANSPARENCY_INFO);
-        if (mDeveloperInfo != null) {
-            XmlUtils.appendChildren(transparencyInfoEle, mDeveloperInfo.toOdDomElements(doc));
-        }
         if (mAppInfo != null) {
             XmlUtils.appendChildren(transparencyInfoEle, mAppInfo.toOdDomElements(doc));
         }
@@ -62,9 +51,6 @@
     @Override
     public List<Element> toHrDomElements(Document doc) {
         Element transparencyInfoEle = doc.createElement(XmlUtils.HR_TAG_TRANSPARENCY_INFO);
-        if (mDeveloperInfo != null) {
-            XmlUtils.appendChildren(transparencyInfoEle, mDeveloperInfo.toHrDomElements(doc));
-        }
         if (mAppInfo != null) {
             XmlUtils.appendChildren(transparencyInfoEle, mAppInfo.toHrDomElements(doc));
         }
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfoFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfoFactory.java
index 94c5640..40f2872 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfoFactory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfoFactory.java
@@ -36,18 +36,11 @@
             return null;
         }
 
-        Element developerInfoEle =
-                XmlUtils.getSingleChildElement(
-                        transparencyInfoEle, XmlUtils.HR_TAG_DEVELOPER_INFO, false);
-        DeveloperInfo developerInfo =
-                new DeveloperInfoFactory().createFromHrElements(XmlUtils.listOf(developerInfoEle));
-
         Element appInfoEle =
-                XmlUtils.getSingleChildElement(
-                        transparencyInfoEle, XmlUtils.HR_TAG_APP_INFO, false);
+                XmlUtils.getSingleChildElement(transparencyInfoEle, XmlUtils.HR_TAG_APP_INFO, true);
         AppInfo appInfo = new AppInfoFactory().createFromHrElements(XmlUtils.listOf(appInfoEle));
 
-        return new TransparencyInfo(developerInfo, appInfo);
+        return new TransparencyInfo(appInfo);
     }
 
     /** Creates an {@link AslMarshallableFactory} from on-device DOM elements */
@@ -60,17 +53,10 @@
             return null;
         }
 
-        Element developerInfoEle =
-                XmlUtils.getOdPbundleWithName(
-                        transparencyInfoEle, XmlUtils.OD_NAME_DEVELOPER_INFO, false);
-        DeveloperInfo developerInfo =
-                new DeveloperInfoFactory().createFromOdElements(XmlUtils.listOf(developerInfoEle));
-
         Element appInfoEle =
-                XmlUtils.getOdPbundleWithName(
-                        transparencyInfoEle, XmlUtils.OD_NAME_APP_INFO, false);
+                XmlUtils.getOdPbundleWithName(transparencyInfoEle, XmlUtils.OD_NAME_APP_INFO, true);
         AppInfo appInfo = new AppInfoFactory().createFromOdElements(XmlUtils.listOf(appInfoEle));
 
-        return new TransparencyInfo(developerInfo, appInfo);
+        return new TransparencyInfo(appInfo);
     }
 }
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java
index 97cbc39..2c1517b 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java
@@ -25,6 +25,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.stream.Collectors;
 
 public class XmlUtils {
     public static final String DATA_TYPE_SEPARATOR = "_data_type_";
@@ -42,6 +43,7 @@
     public static final String HR_TAG_DATA_COLLECTED = "data-collected";
     public static final String HR_TAG_DATA_COLLECTED_EPHEMERAL = "data-collected-ephemeral";
     public static final String HR_TAG_DATA_SHARED = "data-shared";
+    public static final String HR_TAG_ITEM = "item";
     public static final String HR_ATTR_NAME = "name";
     public static final String HR_ATTR_EMAIL = "email";
     public static final String HR_ATTR_ADDRESS = "address";
@@ -64,12 +66,13 @@
     public static final String HR_ATTR_DESCRIPTION = "description";
     public static final String HR_ATTR_CONTAINS_ADS = "containsAds";
     public static final String HR_ATTR_OBEY_APS = "obeyAps";
+    public static final String HR_ATTR_APS_COMPLIANT = "apsCompliant";
     public static final String HR_ATTR_ADS_FINGERPRINTING = "adsFingerprinting";
     public static final String HR_ATTR_SECURITY_FINGERPRINTING = "securityFingerprinting";
     public static final String HR_ATTR_PRIVACY_POLICY = "privacyPolicy";
     public static final String HR_ATTR_SECURITY_ENDPOINTS = "securityEndpoints";
-    public static final String HR_ATTR_FIRST_PARTY_ENDPOINTS = "firstPartyEndpoints";
-    public static final String HR_ATTR_SERVICE_PROVIDER_ENDPOINTS = "serviceProviderEndpoints";
+    public static final String HR_TAG_FIRST_PARTY_ENDPOINTS = "first-party-endpoints";
+    public static final String HR_TAG_SERVICE_PROVIDER_ENDPOINTS = "service-provider-endpoints";
     public static final String HR_ATTR_CATEGORY = "category";
 
     public static final String OD_TAG_BUNDLE = "bundle";
@@ -98,12 +101,13 @@
     public static final String OD_NAME_DESCRIPTION = "description";
     public static final String OD_NAME_CONTAINS_ADS = "contains_ads";
     public static final String OD_NAME_OBEY_APS = "obey_aps";
+    public static final String OD_NAME_APS_COMPLIANT = "aps_compliant";
     public static final String OD_NAME_ADS_FINGERPRINTING = "ads_fingerprinting";
     public static final String OD_NAME_SECURITY_FINGERPRINTING = "security_fingerprinting";
     public static final String OD_NAME_PRIVACY_POLICY = "privacy_policy";
-    public static final String OD_NAME_SECURITY_ENDPOINT = "security_endpoint";
-    public static final String OD_NAME_FIRST_PARTY_ENDPOINT = "first_party_endpoint";
-    public static final String OD_NAME_SERVICE_PROVIDER_ENDPOINT = "service_provider_endpoint";
+    public static final String OD_NAME_SECURITY_ENDPOINT = "security_endpoints";
+    public static final String OD_NAME_FIRST_PARTY_ENDPOINTS = "first_party_endpoints";
+    public static final String OD_NAME_SERVICE_PROVIDER_ENDPOINTS = "service_provider_endpoints";
     public static final String OD_NAME_CATEGORY = "category";
     public static final String OD_NAME_VERSION = "version";
     public static final String OD_NAME_URL = "url";
@@ -128,7 +132,9 @@
     /** Gets the top-level children with the tag name.. */
     public static List<Element> getChildrenByTagName(Node parentEle, String tagName) {
         var elements = XmlUtils.asElementList(parentEle.getChildNodes());
-        return elements.stream().filter(e -> e.getTagName().equals(tagName)).toList();
+        return elements.stream()
+                .filter(e -> e.getTagName().equals(tagName))
+                .collect(Collectors.toList());
     }
 
     /**
@@ -237,7 +243,18 @@
         return ele;
     }
 
-    /** Create OD style array DOM Element, which can represent any time but is stored as Strings. */
+    /** Create HR style array DOM Element. */
+    public static Element createHrArray(Document doc, String arrayTagName, List<String> arrayVals) {
+        Element arrEle = doc.createElement(arrayTagName);
+        for (String s : arrayVals) {
+            Element itemEle = doc.createElement(XmlUtils.HR_TAG_ITEM);
+            itemEle.setTextContent(s);
+            arrEle.appendChild(itemEle);
+        }
+        return arrEle;
+    }
+
+    /** Create OD style array DOM Element, which can represent any type but is stored as Strings. */
     public static Element createOdArray(
             Document doc, String arrayTag, String arrayName, List<String> arrayVals) {
         Element arrEle = doc.createElement(arrayTag);
@@ -272,7 +289,8 @@
     /** Gets a pipeline-split attribute. */
     public static List<String> getPipelineSplitAttr(Element ele, String attrName, boolean required)
             throws MalformedXmlException {
-        List<String> list = Arrays.stream(ele.getAttribute(attrName).split("\\|")).toList();
+        List<String> list =
+                Arrays.stream(ele.getAttribute(attrName).split("\\|")).collect(Collectors.toList());
         if ((list.isEmpty() || list.get(0).isEmpty()) && required) {
             throw new MalformedXmlException(
                     String.format(
@@ -301,7 +319,7 @@
         List<Element> boolEles =
                 XmlUtils.getChildrenByTagName(ele, XmlUtils.OD_TAG_BOOLEAN).stream()
                         .filter(e -> e.getAttribute(XmlUtils.OD_ATTR_NAME).equals(nameName))
-                        .toList();
+                        .collect(Collectors.toList());
         if (boolEles.size() > 1) {
             throw new MalformedXmlException(
                     String.format(
@@ -332,7 +350,7 @@
         List<Element> longEles =
                 XmlUtils.getChildrenByTagName(ele, XmlUtils.OD_TAG_LONG).stream()
                         .filter(e -> e.getAttribute(XmlUtils.OD_ATTR_NAME).equals(nameName))
-                        .toList();
+                        .collect(Collectors.toList());
         if (longEles.size() > 1) {
             throw new MalformedXmlException(
                     String.format(
@@ -363,7 +381,7 @@
         List<Element> eles =
                 XmlUtils.getChildrenByTagName(ele, XmlUtils.OD_TAG_STRING).stream()
                         .filter(e -> e.getAttribute(XmlUtils.OD_ATTR_NAME).equals(nameName))
-                        .toList();
+                        .collect(Collectors.toList());
         if (eles.size() > 1) {
             throw new MalformedXmlException(
                     String.format(
@@ -391,7 +409,7 @@
         List<Element> eles =
                 XmlUtils.getChildrenByTagName(ele, XmlUtils.OD_TAG_PBUNDLE_AS_MAP).stream()
                         .filter(e -> e.getAttribute(XmlUtils.OD_ATTR_NAME).equals(nameName))
-                        .toList();
+                        .collect(Collectors.toList());
         if (eles.size() > 1) {
             throw new MalformedXmlException(
                     String.format(
@@ -435,7 +453,7 @@
         List<Element> intArrayEles =
                 XmlUtils.getChildrenByTagName(ele, XmlUtils.OD_TAG_INT_ARRAY).stream()
                         .filter(e -> e.getAttribute(XmlUtils.OD_ATTR_NAME).equals(nameName))
-                        .toList();
+                        .collect(Collectors.toList());
         if (intArrayEles.size() > 1) {
             throw new MalformedXmlException(
                     String.format("Found more than one %s in %s.", nameName, ele.getTagName()));
@@ -456,13 +474,39 @@
         return ints;
     }
 
+    /** Gets human-readable style String array. */
+    public static List<String> getHrItemsAsStrings(
+            Element parent, String elementName, boolean required) throws MalformedXmlException {
+
+        List<Element> arrayEles = XmlUtils.getChildrenByTagName(parent, elementName);
+        if (arrayEles.size() > 1) {
+            throw new MalformedXmlException(
+                    String.format(
+                            "Found more than one %s in %s.", elementName, parent.getTagName()));
+        }
+        if (arrayEles.isEmpty()) {
+            if (required) {
+                throw new MalformedXmlException(
+                        String.format("Found no %s in %s.", elementName, parent.getTagName()));
+            }
+            return null;
+        }
+        Element arrayEle = arrayEles.get(0);
+        List<Element> itemEles = XmlUtils.getChildrenByTagName(arrayEle, XmlUtils.HR_TAG_ITEM);
+        List<String> strs = new ArrayList<String>();
+        for (Element itemEle : itemEles) {
+            strs.add(itemEle.getTextContent());
+        }
+        return strs;
+    }
+
     /** Gets on-device style String array. */
     public static List<String> getOdStringArray(Element ele, String nameName, boolean required)
             throws MalformedXmlException {
         List<Element> arrayEles =
                 XmlUtils.getChildrenByTagName(ele, XmlUtils.OD_TAG_STRING_ARRAY).stream()
                         .filter(e -> e.getAttribute(XmlUtils.OD_ATTR_NAME).equals(nameName))
-                        .toList();
+                        .collect(Collectors.toList());
         if (arrayEles.size() > 1) {
             throw new MalformedXmlException(
                     String.format(
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/AllTests.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/AllTests.java
index dbeeb49..14e65e5 100644
--- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/AllTests.java
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/AllTests.java
@@ -20,11 +20,8 @@
 import com.android.asllib.marshallable.AppInfoTest;
 import com.android.asllib.marshallable.DataLabelsTest;
 import com.android.asllib.marshallable.DataTypeEqualityTest;
-import com.android.asllib.marshallable.DeveloperInfoTest;
 import com.android.asllib.marshallable.SafetyLabelsTest;
-import com.android.asllib.marshallable.SecurityLabelsTest;
 import com.android.asllib.marshallable.SystemAppSafetyLabelTest;
-import com.android.asllib.marshallable.ThirdPartyVerificationTest;
 import com.android.asllib.marshallable.TransparencyInfoTest;
 
 import org.junit.runner.RunWith;
@@ -35,14 +32,10 @@
     AslgenTests.class,
     AndroidSafetyLabelTest.class,
     AppInfoTest.class,
-    // DataCategoryTest.class,
     DataLabelsTest.class,
     DataTypeEqualityTest.class,
-    DeveloperInfoTest.class,
     SafetyLabelsTest.class,
-    SecurityLabelsTest.class,
     SystemAppSafetyLabelTest.class,
-    ThirdPartyVerificationTest.class,
     TransparencyInfoTest.class
 })
 public class AllTests {}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AppInfoTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AppInfoTest.java
index 9e91c6f..d823c48 100644
--- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AppInfoTest.java
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AppInfoTest.java
@@ -20,6 +20,7 @@
 
 import com.android.asllib.testutils.TestUtils;
 import com.android.asllib.util.MalformedXmlException;
+import com.android.asllib.util.XmlUtils;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -34,35 +35,15 @@
     private static final String APP_INFO_HR_PATH = "com/android/asllib/appinfo/hr";
     private static final String APP_INFO_OD_PATH = "com/android/asllib/appinfo/od";
     public static final List<String> REQUIRED_FIELD_NAMES =
-            List.of(
-                    "title",
-                    "description",
-                    "containsAds",
-                    "obeyAps",
-                    "adsFingerprinting",
-                    "securityFingerprinting",
-                    "privacyPolicy",
-                    "securityEndpoints",
-                    "firstPartyEndpoints",
-                    "serviceProviderEndpoints",
-                    "category",
-                    "email");
+            List.of("apsCompliant", "privacyPolicy");
     public static final List<String> REQUIRED_FIELD_NAMES_OD =
-            List.of(
-                    "title",
-                    "description",
-                    "contains_ads",
-                    "obey_aps",
-                    "ads_fingerprinting",
-                    "security_fingerprinting",
-                    "privacy_policy",
-                    "security_endpoint",
-                    "first_party_endpoint",
-                    "service_provider_endpoint",
-                    "category",
-                    "email");
-    public static final List<String> OPTIONAL_FIELD_NAMES = List.of("website");
-    public static final List<String> OPTIONAL_FIELD_NAMES_OD = List.of("website");
+            List.of("aps_compliant", "privacy_policy");
+    public static final List<String> REQUIRED_CHILD_NAMES =
+            List.of("first-party-endpoints", "service-provider-endpoints");
+    public static final List<String> REQUIRED_CHILD_NAMES_OD =
+            List.of("first_party_endpoints", "service_provider_endpoints");
+    public static final List<String> OPTIONAL_FIELD_NAMES = List.of();
+    public static final List<String> OPTIONAL_FIELD_NAMES_OD = List.of();
 
     private static final String ALL_FIELDS_VALID_FILE_NAME = "all-fields-valid.xml";
 
@@ -110,6 +91,34 @@
         }
     }
 
+    /** Tests missing required child fails. */
+    @Test
+    public void testMissingRequiredChild() throws Exception {
+        System.out.println("Starting testMissingRequiredFields");
+        for (String reqChildName : REQUIRED_CHILD_NAMES) {
+            System.out.println("testing missing required child hr: " + reqChildName);
+            var appInfoEle =
+                    TestUtils.getElementsFromResource(
+                            Paths.get(APP_INFO_HR_PATH, ALL_FIELDS_VALID_FILE_NAME));
+            var child = XmlUtils.getChildrenByTagName(appInfoEle.get(0), reqChildName).get(0);
+            appInfoEle.get(0).removeChild(child);
+            assertThrows(
+                    MalformedXmlException.class,
+                    () -> new AppInfoFactory().createFromHrElements(appInfoEle));
+        }
+
+        for (String reqField : REQUIRED_CHILD_NAMES_OD) {
+            System.out.println("testing missing required child od: " + reqField);
+            var appInfoEle =
+                    TestUtils.getElementsFromResource(
+                            Paths.get(APP_INFO_OD_PATH, ALL_FIELDS_VALID_FILE_NAME));
+            TestUtils.removeOdChildEleWithName(appInfoEle.get(0), reqField);
+            assertThrows(
+                    MalformedXmlException.class,
+                    () -> new AppInfoFactory().createFromOdElements(appInfoEle));
+        }
+    }
+
     /** Tests missing optional fields passes. */
     @Test
     public void testMissingOptionalFields() throws Exception {
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DeveloperInfoTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DeveloperInfoTest.java
deleted file mode 100644
index 72e8d65..0000000
--- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DeveloperInfoTest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.asllib.marshallable;
-
-import static org.junit.Assert.assertThrows;
-
-import com.android.asllib.testutils.TestUtils;
-import com.android.asllib.util.MalformedXmlException;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.nio.file.Paths;
-import java.util.List;
-
-@RunWith(JUnit4.class)
-public class DeveloperInfoTest {
-    private static final String DEVELOPER_INFO_HR_PATH = "com/android/asllib/developerinfo/hr";
-    private static final String DEVELOPER_INFO_OD_PATH = "com/android/asllib/developerinfo/od";
-    public static final List<String> REQUIRED_FIELD_NAMES =
-            List.of("address", "countryRegion", "email", "name", "relationship");
-    public static final List<String> REQUIRED_FIELD_NAMES_OD =
-            List.of("address", "country_region", "email", "name", "relationship");
-    public static final List<String> OPTIONAL_FIELD_NAMES = List.of("website", "registryId");
-    public static final List<String> OPTIONAL_FIELD_NAMES_OD =
-            List.of("website", "app_developer_registry_id");
-
-    private static final String ALL_FIELDS_VALID_FILE_NAME = "all-fields-valid.xml";
-
-    /** Logic for setting up tests (empty if not yet needed). */
-    public static void main(String[] params) throws Exception {}
-
-    @Before
-    public void setUp() throws Exception {
-        System.out.println("set up.");
-    }
-
-    /** Test for all fields valid. */
-    @Test
-    public void testAllFieldsValid() throws Exception {
-        System.out.println("starting testAllFieldsValid.");
-        testHrToOdDeveloperInfo(ALL_FIELDS_VALID_FILE_NAME);
-        testOdToHrDeveloperInfo(ALL_FIELDS_VALID_FILE_NAME);
-    }
-
-    /** Tests missing required fields fails. */
-    @Test
-    public void testMissingRequiredFields() throws Exception {
-        System.out.println("Starting testMissingRequiredFields");
-        for (String reqField : REQUIRED_FIELD_NAMES) {
-            System.out.println("testing missing required field: " + reqField);
-            var developerInfoEle =
-                    TestUtils.getElementsFromResource(
-                            Paths.get(DEVELOPER_INFO_HR_PATH, ALL_FIELDS_VALID_FILE_NAME));
-            developerInfoEle.get(0).removeAttribute(reqField);
-
-            assertThrows(
-                    MalformedXmlException.class,
-                    () -> new DeveloperInfoFactory().createFromHrElements(developerInfoEle));
-        }
-
-        for (String reqField : REQUIRED_FIELD_NAMES_OD) {
-            System.out.println("testing missing required field od: " + reqField);
-            var developerInfoEle =
-                    TestUtils.getElementsFromResource(
-                            Paths.get(DEVELOPER_INFO_OD_PATH, ALL_FIELDS_VALID_FILE_NAME));
-            TestUtils.removeOdChildEleWithName(developerInfoEle.get(0), reqField);
-
-            assertThrows(
-                    MalformedXmlException.class,
-                    () -> new DeveloperInfoFactory().createFromOdElements(developerInfoEle));
-        }
-    }
-
-    /** Tests missing optional fields passes. */
-    @Test
-    public void testMissingOptionalFields() throws Exception {
-        for (String optField : OPTIONAL_FIELD_NAMES) {
-            var developerInfoEle =
-                    TestUtils.getElementsFromResource(
-                            Paths.get(DEVELOPER_INFO_HR_PATH, ALL_FIELDS_VALID_FILE_NAME));
-            developerInfoEle.get(0).removeAttribute(optField);
-            DeveloperInfo developerInfo =
-                    new DeveloperInfoFactory().createFromHrElements(developerInfoEle);
-            developerInfo.toOdDomElements(TestUtils.document());
-        }
-
-        for (String optField : OPTIONAL_FIELD_NAMES_OD) {
-            var developerInfoEle =
-                    TestUtils.getElementsFromResource(
-                            Paths.get(DEVELOPER_INFO_OD_PATH, ALL_FIELDS_VALID_FILE_NAME));
-            TestUtils.removeOdChildEleWithName(developerInfoEle.get(0), optField);
-            DeveloperInfo developerInfo =
-                    new DeveloperInfoFactory().createFromOdElements(developerInfoEle);
-            developerInfo.toHrDomElements(TestUtils.document());
-        }
-    }
-
-    private void testHrToOdDeveloperInfo(String fileName) throws Exception {
-        TestUtils.testHrToOd(
-                TestUtils.document(),
-                new DeveloperInfoFactory(),
-                DEVELOPER_INFO_HR_PATH,
-                DEVELOPER_INFO_OD_PATH,
-                fileName);
-    }
-
-    private void testOdToHrDeveloperInfo(String fileName) throws Exception {
-        TestUtils.testOdToHr(
-                TestUtils.document(),
-                new DeveloperInfoFactory(),
-                DEVELOPER_INFO_OD_PATH,
-                DEVELOPER_INFO_HR_PATH,
-                fileName);
-    }
-}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java
index bba6b54..19d1626 100644
--- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java
@@ -28,26 +28,14 @@
     private static final String SAFETY_LABELS_HR_PATH = "com/android/asllib/safetylabels/hr";
     private static final String SAFETY_LABELS_OD_PATH = "com/android/asllib/safetylabels/od";
 
-    private static final String MISSING_VERSION_FILE_NAME = "missing-version.xml";
     private static final String VALID_EMPTY_FILE_NAME = "valid-empty.xml";
     private static final String WITH_DATA_LABELS_FILE_NAME = "with-data-labels.xml";
-    private static final String WITH_SECURITY_LABELS_FILE_NAME = "with-security-labels.xml";
-    private static final String WITH_THIRD_PARTY_VERIFICATION_FILE_NAME =
-            "with-third-party-verification.xml";
 
     @Before
     public void setUp() throws Exception {
         System.out.println("set up.");
     }
 
-    /** Test for safety labels missing version. */
-    @Test
-    public void testSafetyLabelsMissingVersion() throws Exception {
-        System.out.println("starting testSafetyLabelsMissingVersion.");
-        hrToOdExpectException(MISSING_VERSION_FILE_NAME);
-        odToHrExpectException(MISSING_VERSION_FILE_NAME);
-    }
-
     /** Test for safety labels valid empty. */
     @Test
     public void testSafetyLabelsValidEmptyFile() throws Exception {
@@ -64,22 +52,6 @@
         testOdToHrSafetyLabels(WITH_DATA_LABELS_FILE_NAME);
     }
 
-    /** Test for safety labels with security labels. */
-    @Test
-    public void testSafetyLabelsWithSecurityLabels() throws Exception {
-        System.out.println("starting testSafetyLabelsWithSecurityLabels.");
-        testHrToOdSafetyLabels(WITH_SECURITY_LABELS_FILE_NAME);
-        testOdToHrSafetyLabels(WITH_SECURITY_LABELS_FILE_NAME);
-    }
-
-    /** Test for safety labels with third party verification. */
-    @Test
-    public void testSafetyLabelsWithThirdPartyVerification() throws Exception {
-        System.out.println("starting testSafetyLabelsWithThirdPartyVerification.");
-        testHrToOdSafetyLabels(WITH_THIRD_PARTY_VERIFICATION_FILE_NAME);
-        testOdToHrSafetyLabels(WITH_THIRD_PARTY_VERIFICATION_FILE_NAME);
-    }
-
     private void hrToOdExpectException(String fileName) {
         TestUtils.hrToOdExpectException(new SafetyLabelsFactory(), SAFETY_LABELS_HR_PATH, fileName);
     }
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SecurityLabelsTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SecurityLabelsTest.java
deleted file mode 100644
index a940bc6..0000000
--- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SecurityLabelsTest.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.asllib.marshallable;
-
-
-import com.android.asllib.testutils.TestUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.nio.file.Paths;
-import java.util.List;
-
-@RunWith(JUnit4.class)
-public class SecurityLabelsTest {
-    private static final String SECURITY_LABELS_HR_PATH = "com/android/asllib/securitylabels/hr";
-    private static final String SECURITY_LABELS_OD_PATH = "com/android/asllib/securitylabels/od";
-
-    public static final List<String> OPTIONAL_FIELD_NAMES =
-            List.of("isDataDeletable", "isDataEncrypted");
-    public static final List<String> OPTIONAL_FIELD_NAMES_OD =
-            List.of("is_data_deletable", "is_data_encrypted");
-
-    private static final String ALL_FIELDS_VALID_FILE_NAME = "all-fields-valid.xml";
-
-    /** Logic for setting up tests (empty if not yet needed). */
-    public static void main(String[] params) throws Exception {}
-
-    @Before
-    public void setUp() throws Exception {
-        System.out.println("set up.");
-    }
-
-    /** Test for all fields valid. */
-    @Test
-    public void testAllFieldsValid() throws Exception {
-        System.out.println("starting testAllFieldsValid.");
-        testHrToOdSecurityLabels(ALL_FIELDS_VALID_FILE_NAME);
-        testOdToHrSecurityLabels(ALL_FIELDS_VALID_FILE_NAME);
-    }
-
-    /** Tests missing optional fields passes. */
-    @Test
-    public void testMissingOptionalFields() throws Exception {
-        for (String optField : OPTIONAL_FIELD_NAMES) {
-            var ele =
-                    TestUtils.getElementsFromResource(
-                            Paths.get(SECURITY_LABELS_HR_PATH, ALL_FIELDS_VALID_FILE_NAME));
-            ele.get(0).removeAttribute(optField);
-            SecurityLabels securityLabels = new SecurityLabelsFactory().createFromHrElements(ele);
-            securityLabels.toOdDomElements(TestUtils.document());
-        }
-        for (String optField : OPTIONAL_FIELD_NAMES_OD) {
-            var ele =
-                    TestUtils.getElementsFromResource(
-                            Paths.get(SECURITY_LABELS_OD_PATH, ALL_FIELDS_VALID_FILE_NAME));
-            TestUtils.removeOdChildEleWithName(ele.get(0), optField);
-            SecurityLabels securityLabels = new SecurityLabelsFactory().createFromOdElements(ele);
-            securityLabels.toHrDomElements(TestUtils.document());
-        }
-    }
-
-    private void testHrToOdSecurityLabels(String fileName) throws Exception {
-        TestUtils.testHrToOd(
-                TestUtils.document(),
-                new SecurityLabelsFactory(),
-                SECURITY_LABELS_HR_PATH,
-                SECURITY_LABELS_OD_PATH,
-                fileName);
-    }
-
-    private void testOdToHrSecurityLabels(String fileName) throws Exception {
-        TestUtils.testOdToHr(
-                TestUtils.document(),
-                new SecurityLabelsFactory(),
-                SECURITY_LABELS_OD_PATH,
-                SECURITY_LABELS_HR_PATH,
-                fileName);
-    }
-}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/ThirdPartyVerificationTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/ThirdPartyVerificationTest.java
deleted file mode 100644
index ec86d0f..0000000
--- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/ThirdPartyVerificationTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.asllib.marshallable;
-
-import com.android.asllib.testutils.TestUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class ThirdPartyVerificationTest {
-    private static final String THIRD_PARTY_VERIFICATION_HR_PATH =
-            "com/android/asllib/thirdpartyverification/hr";
-    private static final String THIRD_PARTY_VERIFICATION_OD_PATH =
-            "com/android/asllib/thirdpartyverification/od";
-
-    private static final String VALID_FILE_NAME = "valid.xml";
-    private static final String MISSING_URL_FILE_NAME = "missing-url.xml";
-
-    /** Logic for setting up tests (empty if not yet needed). */
-    public static void main(String[] params) throws Exception {}
-
-    @Before
-    public void setUp() throws Exception {
-        System.out.println("set up.");
-    }
-
-    /** Test for valid. */
-    @Test
-    public void testValid() throws Exception {
-        System.out.println("starting testValid.");
-        testHrToOdThirdPartyVerification(VALID_FILE_NAME);
-        testOdToHrThirdPartyVerification(VALID_FILE_NAME);
-    }
-
-    /** Tests missing url. */
-    @Test
-    public void testMissingUrl() throws Exception {
-        System.out.println("starting testMissingUrl.");
-        hrToOdExpectException(MISSING_URL_FILE_NAME);
-        odToHrExpectException(MISSING_URL_FILE_NAME);
-    }
-
-    private void hrToOdExpectException(String fileName) {
-        TestUtils.hrToOdExpectException(
-                new ThirdPartyVerificationFactory(), THIRD_PARTY_VERIFICATION_HR_PATH, fileName);
-    }
-
-    private void odToHrExpectException(String fileName) {
-        TestUtils.odToHrExpectException(
-                new ThirdPartyVerificationFactory(), THIRD_PARTY_VERIFICATION_OD_PATH, fileName);
-    }
-
-    private void testHrToOdThirdPartyVerification(String fileName) throws Exception {
-        TestUtils.testHrToOd(
-                TestUtils.document(),
-                new ThirdPartyVerificationFactory(),
-                THIRD_PARTY_VERIFICATION_HR_PATH,
-                THIRD_PARTY_VERIFICATION_OD_PATH,
-                fileName);
-    }
-
-    private void testOdToHrThirdPartyVerification(String fileName) throws Exception {
-        TestUtils.testOdToHr(
-                TestUtils.document(),
-                new ThirdPartyVerificationFactory(),
-                THIRD_PARTY_VERIFICATION_OD_PATH,
-                THIRD_PARTY_VERIFICATION_HR_PATH,
-                fileName);
-    }
-}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/TransparencyInfoTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/TransparencyInfoTest.java
index f494240..8a0b35e 100644
--- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/TransparencyInfoTest.java
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/TransparencyInfoTest.java
@@ -29,9 +29,6 @@
             "com/android/asllib/transparencyinfo/hr";
     private static final String TRANSPARENCY_INFO_OD_PATH =
             "com/android/asllib/transparencyinfo/od";
-
-    private static final String VALID_EMPTY_FILE_NAME = "valid-empty.xml";
-    private static final String WITH_DEVELOPER_INFO_FILE_NAME = "with-developer-info.xml";
     private static final String WITH_APP_INFO_FILE_NAME = "with-app-info.xml";
 
     @Before
@@ -39,22 +36,6 @@
         System.out.println("set up.");
     }
 
-    /** Test for transparency info valid empty. */
-    @Test
-    public void testTransparencyInfoValidEmptyFile() throws Exception {
-        System.out.println("starting testTransparencyInfoValidEmptyFile.");
-        testHrToOdTransparencyInfo(VALID_EMPTY_FILE_NAME);
-        testOdToHrTransparencyInfo(VALID_EMPTY_FILE_NAME);
-    }
-
-    /** Test for transparency info with developer info. */
-    @Test
-    public void testTransparencyInfoWithDeveloperInfo() throws Exception {
-        System.out.println("starting testTransparencyInfoWithDeveloperInfo.");
-        testHrToOdTransparencyInfo(WITH_DEVELOPER_INFO_FILE_NAME);
-        testOdToHrTransparencyInfo(WITH_DEVELOPER_INFO_FILE_NAME);
-    }
-
     /** Test for transparency info with app info. */
     @Test
     public void testTransparencyInfoWithAppInfo() throws Exception {
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-safety-labels.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-safety-labels.xml
index 53794a1..03e71d2 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-safety-labels.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-safety-labels.xml
@@ -1,4 +1,4 @@
 <app-metadata-bundles version="123456">
-    <safety-labels version="12345">
+    <safety-labels>
     </safety-labels>
 </app-metadata-bundles>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-transparency-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-transparency-info.xml
index 00bcfa8..a00ef65 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-transparency-info.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-transparency-info.xml
@@ -1,4 +1,15 @@
 <app-metadata-bundles version="123456">
-<transparency-info>
-</transparency-info>
+    <transparency-info>
+        <app-info
+            apsCompliant="false"
+            privacyPolicy="www.example.com">
+            <first-party-endpoints>
+                <item>url1</item>
+            </first-party-endpoints>
+            <service-provider-endpoints>
+                <item>url55</item>
+                <item>url56</item>
+            </service-provider-endpoints>
+        </app-info>
+    </transparency-info>
 </app-metadata-bundles>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-safety-labels.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-safety-labels.xml
index 74644ed..f00fb26 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-safety-labels.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-safety-labels.xml
@@ -1,6 +1,5 @@
 <bundle>
     <long name="version" value="123456"/>
     <pbundle_as_map name="safety_labels">
-        <long name="version" value="12345"/>
     </pbundle_as_map>
 </bundle>
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-transparency-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-transparency-info.xml
index 63c5094..d0c8668 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-transparency-info.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-transparency-info.xml
@@ -1,4 +1,16 @@
 <bundle>
     <long name="version" value="123456"/>
-    <pbundle_as_map name="transparency_info"/>
+    <pbundle_as_map name="transparency_info">
+        <pbundle_as_map name="app_info">
+            <boolean name="aps_compliant" value="false"/>
+            <string name="privacy_policy" value="www.example.com"/>
+            <string-array name="first_party_endpoints" num="1">
+                <item value="url1"/>
+            </string-array>
+            <string-array name="service_provider_endpoints" num="2">
+                <item value="url55"/>
+                <item value="url56"/>
+            </string-array>
+        </pbundle_as_map>
+    </pbundle_as_map>
 </bundle>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/hr/all-fields-valid.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/hr/all-fields-valid.xml
index 883170a2..0d15efc 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/hr/all-fields-valid.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/hr/all-fields-valid.xml
@@ -1,14 +1,11 @@
 <app-info
-    title="beervision"
-    description="a beer app"
-    containsAds="true"
-    obeyAps="false"
-    adsFingerprinting="false"
-    securityFingerprinting="false"
-    privacyPolicy="www.example.com"
-    securityEndpoints="url1|url2|url3"
-    firstPartyEndpoints="url1"
-    serviceProviderEndpoints="url55|url56"
-    category="Food and drink"
-    email="max@maxloh.com"
-    website="www.example.com" />
\ No newline at end of file
+    apsCompliant="false"
+    privacyPolicy="www.example.com">
+    <first-party-endpoints>
+        <item>url1</item>
+    </first-party-endpoints>
+    <service-provider-endpoints>
+        <item>url55</item>
+        <item>url56</item>
+    </service-provider-endpoints>
+</app-info>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid.xml
index 6e976a3..bce5179 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid.xml
@@ -1,25 +1,12 @@
 
 <pbundle_as_map name="app_info">
-    <string name="title" value="beervision"/>
-    <string name="description" value="a beer app"/>
-    <boolean name="contains_ads" value="true"/>
-    <boolean name="obey_aps" value="false"/>
-    <boolean name="ads_fingerprinting" value="false"/>
-    <boolean name="security_fingerprinting" value="false"/>
+    <boolean name="aps_compliant" value="false"/>
     <string name="privacy_policy" value="www.example.com"/>
-    <string-array name="security_endpoint" num="3">
-        <item value="url1"/>
-        <item value="url2"/>
-        <item value="url3"/>
-    </string-array>
-    <string-array name="first_party_endpoint" num="1">
+    <string-array name="first_party_endpoints" num="1">
         <item value="url1"/>
     </string-array>
-    <string-array name="service_provider_endpoint" num="2">
+    <string-array name="service_provider_endpoints" num="2">
         <item value="url55"/>
         <item value="url56"/>
     </string-array>
-    <string name="category" value="Food and drink"/>
-    <string name="email" value="max@maxloh.com"/>
-    <string name="website" value="www.example.com"/>
 </pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/missing-version.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/missing-version.xml
deleted file mode 100644
index 762f3bd..0000000
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/missing-version.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<safety-labels>
-</safety-labels>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/valid-empty.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/valid-empty.xml
index 7decfd4..92d10ca 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/valid-empty.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/valid-empty.xml
@@ -1 +1 @@
-<safety-labels version="12345"></safety-labels>
\ No newline at end of file
+<safety-labels></safety-labels>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-data-labels.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-data-labels.xml
index 84456da..ca3d9f0 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-data-labels.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-data-labels.xml
@@ -1,4 +1,4 @@
-<safety-labels version="12345">
+<safety-labels>
     <data-labels>
         <data-shared dataType="location_data_type_approx_location"
             isSharingOptional="false"
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-security-labels.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-security-labels.xml
index 940e48a..c962785 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-security-labels.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-security-labels.xml
@@ -1,4 +1,4 @@
-<safety-labels version="12345">
+<safety-labels>
     <security-labels
         isDataDeletable="true"
         isDataEncrypted="false"
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-third-party-verification.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-third-party-verification.xml
index bfbc5ae..0805290 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-third-party-verification.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-third-party-verification.xml
@@ -1,4 +1,4 @@
-<safety-labels version="12345">
+<safety-labels>
 <third-party-verification url="www.example.com">
     </third-party-verification>
 </safety-labels>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/missing-version.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/missing-version.xml
deleted file mode 100644
index 3fbe359..0000000
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/missing-version.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<pbundle_as_map name="safety_labels">
-</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/valid-empty.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/valid-empty.xml
index 4f03d88..3fbe359 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/valid-empty.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/valid-empty.xml
@@ -1,3 +1,2 @@
 <pbundle_as_map name="safety_labels">
-    <long name="version" value="12345"/>
 </pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-data-labels.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-data-labels.xml
index fa2a3f8..db92e02 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-data-labels.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-data-labels.xml
@@ -1,5 +1,4 @@
 <pbundle_as_map name="safety_labels">
-    <long name="version" value="12345"/>
     <pbundle_as_map name="data_labels">
         <pbundle_as_map name="data_shared">
             <pbundle_as_map name="location">
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-security-labels.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-security-labels.xml
index b39c562b..9246180 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-security-labels.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-security-labels.xml
@@ -1,5 +1,4 @@
 <pbundle_as_map name="safety_labels">
-    <long name="version" value="12345"/>
     <pbundle_as_map name="security_labels">
         <boolean name="is_data_deletable" value="true" />
         <boolean name="is_data_encrypted" value="false" />
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-third-party-verification.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-third-party-verification.xml
index 10653ff..fd435c5 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-third-party-verification.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-third-party-verification.xml
@@ -1,5 +1,4 @@
 <pbundle_as_map name="safety_labels">
-    <long name="version" value="12345"/>
     <pbundle_as_map name="third_party_verification">
         <string name="url" value="www.example.com"/>
     </pbundle_as_map>
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-app-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-app-info.xml
index a7c48fc..2512ca4 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-app-info.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-app-info.xml
@@ -1,4 +1,14 @@
 
 <transparency-info>
-    <app-info title="beervision" description="a beer app" containsAds="true" obeyAps="false" adsFingerprinting="false" securityFingerprinting="false" privacyPolicy="www.example.com" securityEndpoints="url1|url2|url3" firstPartyEndpoints="url1" serviceProviderEndpoints="url55|url56" category="Food and drink" email="max@maxloh.com" />
+    <app-info
+        apsCompliant="false"
+        privacyPolicy="www.example.com">
+        <first-party-endpoints>
+            <item>url1</item>
+        </first-party-endpoints>
+        <service-provider-endpoints>
+            <item>url55</item>
+            <item>url56</item>
+        </service-provider-endpoints>
+    </app-info>
 </transparency-info>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-app-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-app-info.xml
index b813641..c7bdd97 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-app-info.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-app-info.xml
@@ -1,26 +1,14 @@
 
 <pbundle_as_map name="transparency_info">
     <pbundle_as_map name="app_info">
-        <string name="title" value="beervision"/>
-        <string name="description" value="a beer app"/>
-        <boolean name="contains_ads" value="true"/>
-        <boolean name="obey_aps" value="false"/>
-        <boolean name="ads_fingerprinting" value="false"/>
-        <boolean name="security_fingerprinting" value="false"/>
+        <boolean name="aps_compliant" value="false"/>
         <string name="privacy_policy" value="www.example.com"/>
-        <string-array name="security_endpoint" num="3">
-            <item value="url1"/>
-            <item value="url2"/>
-            <item value="url3"/>
-        </string-array>
-        <string-array name="first_party_endpoint" num="1">
+        <string-array name="first_party_endpoints" num="1">
             <item value="url1"/>
         </string-array>
-        <string-array name="service_provider_endpoint" num="2">
+        <string-array name="service_provider_endpoints" num="2">
             <item value="url55"/>
             <item value="url56"/>
         </string-array>
-        <string name="category" value="Food and drink"/>
-        <string name="email" value="max@maxloh.com"/>
     </pbundle_as_map>
 </pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/contacts/hr.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/contacts/hr.xml
index b2ff449..cadf213 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/contacts/hr.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/contacts/hr.xml
@@ -1,5 +1,5 @@
 <app-metadata-bundles version="123">
-    <safety-labels version="12345">
+    <safety-labels>
         <data-labels>
             <data-shared dataCategory="contacts"
                 dataType="contacts"
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/contacts/od.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/contacts/od.xml
index 81277bf..7aafd23 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/contacts/od.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/contacts/od.xml
@@ -1,7 +1,6 @@
 <bundle>
     <long name="version" value="123"/>
     <pbundle_as_map name="safety_labels">
-        <long name="version" value="12345"/>
         <pbundle_as_map name="data_labels">
             <pbundle_as_map name="data_shared">
                 <pbundle_as_map name="contacts">
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/hr.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/hr.xml
index 41b32b5..5923079 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/hr.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/hr.xml
@@ -1,5 +1,5 @@
 <app-metadata-bundles version="123">
-    <safety-labels version="12345">
+    <safety-labels>
         <data-labels>
             <data-shared
                 dataType="location_data_type_approx_location"
@@ -10,24 +10,18 @@
                 isSharingOptional="true"
                 purposes="app_functionality|analytics" />
         </data-labels>
-        <security-labels
-            isDataDeletable="true"
-            isDataEncrypted="false"
-        />
-        <third-party-verification url="www.example.com">
-        </third-party-verification>
     </safety-labels>
     <system-app-safety-label declaration="true">
     </system-app-safety-label>
     <transparency-info>
-        <developer-info
-            name="max"
-            email="max@example.com"
-            address="111 blah lane"
-            countryRegion="US"
-            relationship="aosp"
-            website="example.com"
-            registryId="registry_id" />
-        <app-info title="beervision" description="a beer app" containsAds="true" obeyAps="false" adsFingerprinting="false" securityFingerprinting="false" privacyPolicy="www.example.com" securityEndpoints="url1|url2|url3" firstPartyEndpoints="url1" serviceProviderEndpoints="url55|url56" category="Food and drink" email="max@maxloh.com" />
+        <app-info apsCompliant="false" privacyPolicy="www.example.com">
+            <first-party-endpoints>
+                <item>url1</item>
+            </first-party-endpoints>
+            <service-provider-endpoints>
+                <item>url55</item>
+                <item>url56</item>
+            </service-provider-endpoints>
+        </app-info>
     </transparency-info>
 </app-metadata-bundles>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/od.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/od.xml
index c11ac43..c24087e 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/od.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/od.xml
@@ -1,7 +1,6 @@
 <bundle>
     <long name="version" value="123"/>
     <pbundle_as_map name="safety_labels">
-        <long name="version" value="12345"/>
         <pbundle_as_map name="data_labels">
             <pbundle_as_map name="data_shared">
                 <pbundle_as_map name="location">
@@ -21,49 +20,21 @@
                 </pbundle_as_map>
             </pbundle_as_map>
         </pbundle_as_map>
-        <pbundle_as_map name="security_labels">
-            <boolean name="is_data_deletable" value="true"/>
-            <boolean name="is_data_encrypted" value="false"/>
-        </pbundle_as_map>
-        <pbundle_as_map name="third_party_verification">
-            <string name="url" value="www.example.com"/>
-        </pbundle_as_map>
     </pbundle_as_map>
     <pbundle_as_map name="system_app_safety_label">
         <boolean name="declaration" value="true"/>
     </pbundle_as_map>
     <pbundle_as_map name="transparency_info">
-        <pbundle_as_map name="developer_info">
-            <string name="name" value="max"/>
-            <string name="email" value="max@example.com"/>
-            <string name="address" value="111 blah lane"/>
-            <string name="country_region" value="US"/>
-            <long name="relationship" value="5"/>
-            <string name="website" value="example.com"/>
-            <string name="app_developer_registry_id" value="registry_id"/>
-        </pbundle_as_map>
         <pbundle_as_map name="app_info">
-            <string name="title" value="beervision"/>
-            <string name="description" value="a beer app"/>
-            <boolean name="contains_ads" value="true"/>
-            <boolean name="obey_aps" value="false"/>
-            <boolean name="ads_fingerprinting" value="false"/>
-            <boolean name="security_fingerprinting" value="false"/>
+            <boolean name="aps_compliant" value="false"/>
             <string name="privacy_policy" value="www.example.com"/>
-            <string-array name="security_endpoint" num="3">
-                <item value="url1"/>
-                <item value="url2"/>
-                <item value="url3"/>
-            </string-array>
-            <string-array name="first_party_endpoint" num="1">
+            <string-array name="first_party_endpoints" num="1">
                 <item value="url1"/>
             </string-array>
-            <string-array name="service_provider_endpoint" num="2">
+            <string-array name="service_provider_endpoints" num="2">
                 <item value="url55"/>
                 <item value="url56"/>
             </string-array>
-            <string name="category" value="Food and drink"/>
-            <string name="email" value="max@maxloh.com"/>
         </pbundle_as_map>
     </pbundle_as_map>
 </bundle>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/location/hr.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/location/hr.xml
index ac844b3..a4242d0 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/location/hr.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/location/hr.xml
@@ -1,5 +1,5 @@
 <app-metadata-bundles version="123">
-    <safety-labels version="12345">
+    <safety-labels>
         <data-labels>
             <data-shared dataCategory="location"
                 dataType="precise_location"
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/location/od.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/location/od.xml
index d0a3bfa..79afaf7 100644
--- a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/location/od.xml
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/location/od.xml
@@ -1,7 +1,6 @@
 <bundle>
     <long name="version" value="123"/>
     <pbundle_as_map name="safety_labels">
-        <long name="version" value="12345"/>
         <pbundle_as_map name="data_labels">
             <pbundle_as_map name="data_shared">
                 <pbundle_as_map name="location">
diff --git a/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
index 624a198..5c64697 100644
--- a/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
+++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
@@ -41,6 +41,7 @@
         PermissionAnnotationDetector.ISSUE_MISSING_PERMISSION_ANNOTATION,
         PermissionMethodDetector.ISSUE_PERMISSION_METHOD_USAGE,
         PermissionMethodDetector.ISSUE_CAN_BE_PERMISSION_METHOD,
+        FeatureAutomotiveDetector.ISSUE,
     )
 
     override val api: Int
diff --git a/tools/lint/framework/checks/src/main/java/com/google/android/lint/FeatureAutomotiveDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/FeatureAutomotiveDetector.kt
new file mode 100644
index 0000000..972b0c9
--- /dev/null
+++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/FeatureAutomotiveDetector.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.google.android.lint
+
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.ConstantEvaluator
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.SourceCodeScanner
+import com.intellij.psi.PsiMethod
+import java.util.EnumSet
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.ULiteralExpression
+import org.jetbrains.uast.UReferenceExpression
+
+/**
+ * A detector to check the usage of PackageManager.hasSystemFeature("
+ * android.hardware.type.automotive") in CTS tests.
+ */
+class FeatureAutomotiveDetector : Detector(), SourceCodeScanner {
+
+    companion object {
+
+        val EXPLANATION =
+            """
+            This class uses PackageManager.hasSystemFeature(\"android.hardware.type.automotive\") \
+            or other equivalent methods. \
+            If it is used to make a CTS test behave differently on AAOS, you should use \
+            @RequireAutomotive or @RequireNotAutomotive instead; otherwise, please ignore this \
+            warning. See https://g3doc.corp.google.com/wireless/android/partner/compatibility/\
+            g3doc/dev/write-a-test/index.md#write-a-test-that-behaves-differently-on-aaos
+            """
+
+        val ISSUE: Issue =
+            Issue.create(
+                id = "UsingFeatureAutomotiveInCTS",
+                briefDescription =
+                    "PackageManager.hasSystemFeature(\"" +
+                        " android.hardware.type.automotive\") is used in CTS tests",
+                explanation = EXPLANATION,
+                category = Category.TESTING,
+                priority = 8,
+                severity = Severity.WARNING,
+                implementation =
+                    Implementation(
+                        FeatureAutomotiveDetector::class.java,
+                        EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES)
+                    )
+            )
+    }
+
+    override fun getApplicableMethodNames() =
+        listOf("hasSystemFeature", "hasFeature", "hasDeviceFeature", "bypassTestForFeatures")
+
+    override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
+        node.valueArguments.forEach {
+            val value =
+                when (it) {
+                    is ULiteralExpression -> it.value
+                    is UReferenceExpression -> ConstantEvaluator.evaluate(context, it)
+                    else -> null
+                }
+            if (value is String && value == "android.hardware.type.automotive") {
+                context.report(
+                    issue = ISSUE,
+                    location = context.getNameLocation(method),
+                    message = EXPLANATION
+                )
+            }
+        }
+    }
+}
diff --git a/tools/lint/framework/checks/src/test/java/com/google/android/lint/FeatureAutomotiveDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/FeatureAutomotiveDetectorTest.kt
new file mode 100644
index 0000000..b5e2c00
--- /dev/null
+++ b/tools/lint/framework/checks/src/test/java/com/google/android/lint/FeatureAutomotiveDetectorTest.kt
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.google.android.lint
+
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.checks.infrastructure.TestFile
+import com.android.tools.lint.checks.infrastructure.TestLintTask
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+import org.junit.Test
+
+@Suppress("UnstableApiUsage")
+class FeatureAutomotiveDetectorTest : LintDetectorTest() {
+    val explanation =
+        FeatureAutomotiveDetector.EXPLANATION.replace("\\", "").replace("\n            ", "") +
+            " [UsingFeatureAutomotiveInCTS]"
+
+    override fun getDetector(): Detector = FeatureAutomotiveDetector()
+    override fun getIssues(): List<Issue> = listOf(FeatureAutomotiveDetector.ISSUE)
+    override fun lint(): TestLintTask = super.lint().allowMissingSdk(true)
+
+    @Test
+    fun testWarning1() {
+        lint()
+            .files(
+                java(
+                        """
+                import android.content.pm.PackageManager;
+
+                public class Foo {
+
+                    private void fun() {
+                        PackageManager.getInstance().hasSystemFeature(
+                            "android.hardware.type.automotive");
+                    }
+                }
+                """
+                    )
+                    .indented(),
+                *stubs
+            )
+            .issues(FeatureAutomotiveDetector.ISSUE)
+            .run()
+            .expect(
+                """
+                            src/android/content/pm/PackageManager.java:13: Warning: $explanation
+                public boolean hasSystemFeature(String feature) {
+                               ~~~~~~~~~~~~~~~~
+    0 errors, 1 warnings
+                            """
+            )
+    }
+
+    @Test
+    fun testWarning2() {
+        lint()
+            .files(
+                java(
+                        """
+                import android.content.pm.PackageManager;
+
+                public class Foo {
+
+                    private void fun() {
+                        String featureName = "android.hardware.type.automotive";
+                        PackageManager.getInstance().hasSystemFeature(featureName);
+                    }
+                }
+                """
+                    )
+                    .indented(),
+                *stubs
+            )
+            .issues(FeatureAutomotiveDetector.ISSUE)
+            .run()
+            .expect(
+                """
+                            src/android/content/pm/PackageManager.java:13: Warning: $explanation
+                public boolean hasSystemFeature(String feature) {
+                               ~~~~~~~~~~~~~~~~
+    0 errors, 1 warnings
+                            """
+            )
+    }
+
+    @Test
+    fun testWarning3() {
+        lint()
+            .files(
+                java(
+                        """
+                import android.content.pm.PackageManager;
+
+                public class Foo {
+
+                    private void fun() {
+                        PackageManager.getInstance().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+                    }
+                }
+                """
+                    )
+                    .indented(),
+                *stubs
+            )
+            .issues(FeatureAutomotiveDetector.ISSUE)
+            .run()
+            .expect(
+                """
+                            src/android/content/pm/PackageManager.java:13: Warning: $explanation
+                public boolean hasSystemFeature(String feature) {
+                               ~~~~~~~~~~~~~~~~
+    0 errors, 1 warnings
+                            """
+            )
+    }
+
+    @Test
+    fun testWarning4() {
+        lint()
+            .files(
+                java(
+                        """
+                import android.content.pm.PackageManager;
+
+                public class Foo {
+
+                    private void fun() {
+                        String featureName = PackageManager.FEATURE_AUTOMOTIVE;
+                        PackageManager.getInstance().hasSystemFeature(featureName);
+                    }
+                }
+                """
+                    )
+                    .indented(),
+                *stubs
+            )
+            .issues(FeatureAutomotiveDetector.ISSUE)
+            .run()
+            .expect(
+                """
+                            src/android/content/pm/PackageManager.java:13: Warning: $explanation
+                public boolean hasSystemFeature(String feature) {
+                               ~~~~~~~~~~~~~~~~
+    0 errors, 1 warnings
+                            """
+            )
+    }
+
+    @Test
+    fun testWarning5() {
+        lint()
+            .files(
+                java(
+                        """
+                import com.android.example.Utils;
+
+                public class Foo {
+
+                    private void fun() {
+                        Utils.hasFeature("android.hardware.type.automotive");
+                    }
+                }
+                """
+                    )
+                    .indented(),
+                *stubs
+            )
+            .issues(FeatureAutomotiveDetector.ISSUE)
+            .run()
+            .expect(
+                """
+                    src/com/android/example/Utils.java:7: Warning: $explanation
+                public static boolean hasFeature(String feature) {
+                                      ~~~~~~~~~~
+    0 errors, 1 warnings
+                            """
+            )
+    }
+
+    @Test
+    fun testWarning6() {
+        lint()
+            .files(
+                java(
+                        """
+                import com.android.example.Utils;
+
+                public class Foo {
+
+                    private void fun() {
+                        Utils.hasDeviceFeature("android.hardware.type.automotive");
+                    }
+                }
+                """
+                    )
+                    .indented(),
+                *stubs
+            )
+            .issues(FeatureAutomotiveDetector.ISSUE)
+            .run()
+            .expect(
+                """
+                    src/com/android/example/Utils.java:11: Warning: $explanation
+                public static boolean hasDeviceFeature(String feature) {
+                                      ~~~~~~~~~~~~~~~~
+    0 errors, 1 warnings
+                            """
+            )
+    }
+
+    @Test
+    fun testWarning7() {
+        lint()
+            .files(
+                java(
+                        """
+                import com.android.example.Utils;
+
+                public class Foo {
+
+                    private void fun() {
+                        Utils.hasFeature(new Object(), "android.hardware.type.automotive");
+                    }
+                }
+                """
+                    )
+                    .indented(),
+                *stubs
+            )
+            .issues(FeatureAutomotiveDetector.ISSUE)
+            .run()
+            .expect(
+                """
+                    src/com/android/example/Utils.java:15: Warning: $explanation
+                public static boolean hasFeature(Object object, String feature) {
+                                      ~~~~~~~~~~
+    0 errors, 1 warnings
+                            """
+            )
+    }
+
+    @Test
+    fun testWarning8() {
+        lint()
+            .files(
+                java(
+                        """
+                import com.android.example.Utils;
+
+                public class Foo {
+
+                    private void fun() {
+                        Utils.bypassTestForFeatures("android.hardware.type.automotive");
+                    }
+                }
+                """
+                    )
+                    .indented(),
+                *stubs
+            )
+            .issues(FeatureAutomotiveDetector.ISSUE)
+            .run()
+            .expect(
+                """
+                    src/com/android/example/Utils.java:19: Warning: $explanation
+                public static boolean bypassTestForFeatures(String feature) {
+                                      ~~~~~~~~~~~~~~~~~~~~~
+    0 errors, 1 warnings
+                            """
+            )
+    }
+
+    @Test
+    fun testNoWarning() {
+        lint()
+            .files(
+                java(
+                        """
+                import android.content.pm.PackageManager;
+
+                public class Foo {
+                    private void fun() {
+                        String featureName1 = "android.hardware.type.automotive";
+                        String featureName2 = PackageManager.FEATURE_AUTOMOTIVE;
+                        String notFeatureName = "FEATURE_AUTOMOTIVE";
+                        PackageManager.getInstance().hasSystemFeature(notFeatureName);
+                        /*
+                        PackageManager.getInstance().hasSystemFeature(
+                            "android.hardware.type.automotive");
+                         */
+                    }
+                }
+                """
+                    )
+                    .indented(),
+                *stubs
+            )
+            .issues(FeatureAutomotiveDetector.ISSUE)
+            .run()
+            .expectClean()
+    }
+
+    private val pmStub: TestFile =
+        java(
+            """
+        package android.content.pm;
+
+        import java.lang.String;
+
+        public class PackageManager {
+            public static final String FEATURE_AUTOMOTIVE = "android.hardware.type.automotive";
+
+            public static PackageManager getInstance() {
+                return new PackageManager();
+            }
+
+            public boolean hasSystemFeature(String feature) {
+                return true;
+            }
+        }
+        """
+        )
+
+    private val exampleStub: TestFile =
+        java(
+            """
+        package com.android.example;
+
+        import java.lang.String;
+
+        public class Utils {
+            public static boolean hasFeature(String feature) {
+                return true;
+            }
+
+            public static boolean hasDeviceFeature(String feature) {
+                return true;
+            }
+
+            public static boolean hasFeature(Object object, String feature) {
+                return true;
+            }
+
+            public static boolean bypassTestForFeatures(String feature) {
+                return true;
+            }
+        }
+        """
+        )
+
+    private val stubs = arrayOf(pmStub, exampleStub)
+}
diff --git a/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt b/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt
index 1087ae6..3c99e68 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ProtoLogCallProcessorImpl.kt
@@ -120,6 +120,8 @@
 
                         logCallVisitor?.processCall(call, messageString, getLevelForMethodName(
                             call.name.toString(), call, context), groupMap.getValue(groupName))
+                    } else if (call.name.id == "initialize") {
+                        // No processing
                     } else {
                         // Process non-log message calls
                         otherCallVisitor?.processCall(call)
diff --git a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
index 0f1373c..aa53005 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
@@ -17,7 +17,6 @@
 package com.android.protolog.tool
 
 import com.android.internal.protolog.common.LogLevel
-import com.android.internal.protolog.common.ProtoLog
 import com.android.internal.protolog.common.ProtoLogToolInjected
 import com.android.protolog.tool.CommandOptions.Companion.USAGE
 import com.github.javaparser.ParseProblemException
@@ -61,6 +60,8 @@
     const val PROTOLOG_IMPL_SRC_PATH =
         "frameworks/base/core/java/com/android/internal/protolog/ProtoLogImpl.java"
 
+    private const val PROTOLOG_CLASS_NAME = "ProtoLog"; // ProtoLog::class.java.simpleName
+
     data class LogCall(
         val messageString: String,
         val logLevel: LogLevel,
@@ -124,7 +125,7 @@
                     val text = injector.readText(file)
                     val outSrc = try {
                         val code = tryParse(text, path)
-                        if (containsProtoLogText(text, ProtoLog::class.java.simpleName)) {
+                        if (containsProtoLogText(text, PROTOLOG_CLASS_NAME)) {
                             transformer.processClass(text, path, packagePath(file, code), code)
                         } else {
                             text
@@ -442,10 +443,10 @@
             val command = CommandOptions(args)
             invoke(command)
         } catch (ex: InvalidCommandException) {
-            println("\n${ex.message}\n")
+            println("InvalidCommandException: \n${ex.message}\n")
             showHelpAndExit()
         } catch (ex: CodeProcessingException) {
-            println("\n${ex.message}\n")
+            println("CodeProcessingException: \n${ex.message}\n")
             exitProcess(1)
         }
     }
diff --git a/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt b/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
index 6a8a071..c478f58 100644
--- a/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
@@ -130,28 +130,27 @@
         val hash = CodeUtils.hash(packagePath, messageString, level, group)
 
         val newCall = call.clone()
-        if (!group.textEnabled) {
-            // Remove message string if text logging is not enabled by default.
-            // Out: ProtoLog.e(GROUP, null, arg)
-            newCall.arguments[1].replace(NameExpr("null"))
-        }
+        // Remove message string.
+        // Out: ProtoLog.e(GROUP, args)
+        newCall.arguments.removeAt(1)
         // Insert message string hash as a second argument.
-        // Out: ProtoLog.e(GROUP, 1234, null, arg)
+        // Out: ProtoLog.e(GROUP, 1234, args)
         newCall.arguments.add(1, LongLiteralExpr("" + hash + "L"))
         val argTypes = LogDataType.parseFormatString(messageString)
         val typeMask = LogDataType.logDataTypesToBitMask(argTypes)
         // Insert bitmap representing which Number parameters are to be considered as
         // floating point numbers.
-        // Out: ProtoLog.e(GROUP, 1234, 0, null, arg)
+        // Out: ProtoLog.e(GROUP, 1234, 0, args)
         newCall.arguments.add(2, IntegerLiteralExpr(typeMask))
         // Replace call to a stub method with an actual implementation.
-        // Out: ProtoLogImpl.e(GROUP, 1234, null, arg)
+        // Out: ProtoLogImpl.e(GROUP, 1234, 0, args)
         newCall.setScope(protoLogImplClassNode)
         if (argTypes.size != call.arguments.size - 2) {
             throw InvalidProtoLogCallException(
                 "Number of arguments (${argTypes.size} does not match format" +
                         " string in: $call", ParsingContext(path, call))
         }
+        val argsOffset = 3
         val blockStmt = BlockStmt()
         if (argTypes.isNotEmpty()) {
             // Assign every argument to a variable to check its type in compile time
@@ -160,9 +159,9 @@
             argTypes.forEachIndexed { idx, type ->
                 val varName = "protoLogParam$idx"
                 val declaration = VariableDeclarator(getASTTypeForDataType(type), varName,
-                    getConversionForType(type)(newCall.arguments[idx + 4].clone()))
+                    getConversionForType(type)(newCall.arguments[idx + argsOffset].clone()))
                 blockStmt.addStatement(ExpressionStmt(VariableDeclarationExpr(declaration)))
-                newCall.setArgument(idx + 4, NameExpr(SimpleName(varName)))
+                newCall.setArgument(idx + argsOffset, NameExpr(SimpleName(varName)))
             }
         } else {
             // Assign (Object[])null as the vararg parameter to prevent allocating an empty
diff --git a/tools/protologtool/tests/com/android/protolog/tool/EndToEndTest.kt b/tools/protologtool/tests/com/android/protolog/tool/EndToEndTest.kt
index 822118c..0cbbd48 100644
--- a/tools/protologtool/tests/com/android/protolog/tool/EndToEndTest.kt
+++ b/tools/protologtool/tests/com/android/protolog/tool/EndToEndTest.kt
@@ -35,7 +35,7 @@
         val output = run(
                 srcs = mapOf("frameworks/base/org/example/Example.java" to """
                     package org.example;
-                    import com.android.internal.protolog.common.ProtoLog;
+                    import com.android.internal.protolog.ProtoLog;
                     import static com.android.internal.protolog.ProtoLogGroup.GROUP;
 
                     class Example {
@@ -48,7 +48,7 @@
                 """.trimIndent()),
                 logGroup = LogGroup("GROUP", true, false, "TAG_GROUP"),
                 commandOptions = CommandOptions(arrayOf("transform-protolog-calls",
-                        "--protolog-class", "com.android.internal.protolog.common.ProtoLog",
+                        "--protolog-class", "com.android.internal.protolog.ProtoLog",
                         "--loggroups-class", "com.android.internal.protolog.ProtoLogGroup",
                         "--loggroups-jar", "not_required.jar",
                         "--viewer-config-file-path", "not_required.pb",
@@ -60,7 +60,7 @@
                 .containsMatch(Pattern.compile("\\{ String protoLogParam0 = " +
                         "String\\.valueOf\\(argString\\); long protoLogParam1 = argInt; " +
                         "com\\.android\\.internal\\.protolog.ProtoLogImpl_.*\\.d\\(" +
-                        "GROUP, -6872339441335321086L, 4, null, protoLogParam0, protoLogParam1" +
+                        "GROUP, -6872339441335321086L, 4, protoLogParam0, protoLogParam1" +
                         "\\); \\}"))
     }
 
@@ -69,7 +69,7 @@
         val output = run(
                 srcs = mapOf("frameworks/base/org/example/Example.java" to """
                     package org.example;
-                    import com.android.internal.protolog.common.ProtoLog;
+                    import com.android.internal.protolog.ProtoLog;
                     import static com.android.internal.protolog.ProtoLogGroup.GROUP;
 
                     class Example {
@@ -82,7 +82,7 @@
                 """.trimIndent()),
                 logGroup = LogGroup("GROUP", true, false, "TAG_GROUP"),
                 commandOptions = CommandOptions(arrayOf("generate-viewer-config",
-                        "--protolog-class", "com.android.internal.protolog.common.ProtoLog",
+                        "--protolog-class", "com.android.internal.protolog.ProtoLog",
                         "--loggroups-class", "com.android.internal.protolog.ProtoLogGroup",
                         "--loggroups-jar", "not_required.jar",
                         "--viewer-config-type", "json",
diff --git a/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt b/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
index 82aa93d..6cde7a7 100644
--- a/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
+++ b/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
@@ -76,7 +76,7 @@
 
             class Test {
                 void test() {
-                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); }
+                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, protoLogParam0, protoLogParam1); }
                 }
             }
             """.trimIndent()
@@ -86,7 +86,7 @@
 
             class Test {
                 void test() {
-                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, -4447034859795564700L, 9, "test %d %f " + "abc %s\n test", protoLogParam0, protoLogParam1, protoLogParam2); 
+                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, -4447034859795564700L, 9, protoLogParam0, protoLogParam1, protoLogParam2); 
             
             }
                 }
@@ -98,8 +98,8 @@
 
             class Test {
                 void test() {
-                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); } /* ProtoLog.w(TEST_GROUP, "test %d %f", 100, 0.1); */ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); }
-                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); }
+                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, protoLogParam0, protoLogParam1); } /* ProtoLog.w(TEST_GROUP, "test %d %f", 100, 0.1); */ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, protoLogParam0, protoLogParam1); }
+                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, protoLogParam0, protoLogParam1); }
                 }
             }
             """.trimIndent()
@@ -109,7 +109,7 @@
 
             class Test {
                 void test() {
-                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { org.example.ProtoLogImpl.w(TEST_GROUP, 3218600869538902408L, 0, "test", (Object[]) null); }
+                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { org.example.ProtoLogImpl.w(TEST_GROUP, 3218600869538902408L, 0, (Object[]) null); }
                 }
             }
             """.trimIndent()
@@ -119,7 +119,7 @@
 
             class Test {
                 void test() {
-                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, null, protoLogParam0, protoLogParam1); }
+                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, protoLogParam0, protoLogParam1); }
                 }
             }
             """.trimIndent()
@@ -129,7 +129,7 @@
 
             class Test {
                 void test() {
-                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, -4447034859795564700L, 9, null, protoLogParam0, protoLogParam1, protoLogParam2); 
+                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, -4447034859795564700L, 9, protoLogParam0, protoLogParam1, protoLogParam2); 
             
             }
                 }
@@ -172,13 +172,12 @@
         Truth.assertThat(protoLogCalls).hasSize(1)
         val methodCall = protoLogCalls[0] as MethodCallExpr
         assertEquals("w", methodCall.name.asString())
-        assertEquals(6, methodCall.arguments.size)
+        assertEquals(5, methodCall.arguments.size)
         assertEquals("TEST_GROUP", methodCall.arguments[0].toString())
         assertEquals("-1473209266730422156L", methodCall.arguments[1].toString())
         assertEquals(0b1001.toString(), methodCall.arguments[2].toString())
-        assertEquals("\"test %d %f\"", methodCall.arguments[3].toString())
-        assertEquals("protoLogParam0", methodCall.arguments[4].toString())
-        assertEquals("protoLogParam1", methodCall.arguments[5].toString())
+        assertEquals("protoLogParam0", methodCall.arguments[3].toString())
+        assertEquals("protoLogParam1", methodCall.arguments[4].toString())
         assertEquals(TRANSFORMED_CODE_TEXT_ENABLED, out)
     }
 
@@ -214,13 +213,12 @@
         Truth.assertThat(protoLogCalls).hasSize(3)
         val methodCall = protoLogCalls[0] as MethodCallExpr
         assertEquals("w", methodCall.name.asString())
-        assertEquals(6, methodCall.arguments.size)
+        assertEquals(5, methodCall.arguments.size)
         assertEquals("TEST_GROUP", methodCall.arguments[0].toString())
         assertEquals("-1473209266730422156L", methodCall.arguments[1].toString())
         assertEquals(0b1001.toString(), methodCall.arguments[2].toString())
-        assertEquals("\"test %d %f\"", methodCall.arguments[3].toString())
-        assertEquals("protoLogParam0", methodCall.arguments[4].toString())
-        assertEquals("protoLogParam1", methodCall.arguments[5].toString())
+        assertEquals("protoLogParam0", methodCall.arguments[3].toString())
+        assertEquals("protoLogParam1", methodCall.arguments[4].toString())
         assertEquals(TRANSFORMED_CODE_MULTICALL_TEXT, out)
     }
 
@@ -252,13 +250,13 @@
         Truth.assertThat(protoLogCalls).hasSize(1)
         val methodCall = protoLogCalls[0] as MethodCallExpr
         assertEquals("w", methodCall.name.asString())
-        assertEquals(7, methodCall.arguments.size)
+        assertEquals(6, methodCall.arguments.size)
         assertEquals("TEST_GROUP", methodCall.arguments[0].toString())
         assertEquals("-4447034859795564700L", methodCall.arguments[1].toString())
         assertEquals(0b001001.toString(), methodCall.arguments[2].toString())
-        assertEquals("protoLogParam0", methodCall.arguments[4].toString())
-        assertEquals("protoLogParam1", methodCall.arguments[5].toString())
-        assertEquals("protoLogParam2", methodCall.arguments[6].toString())
+        assertEquals("protoLogParam0", methodCall.arguments[3].toString())
+        assertEquals("protoLogParam1", methodCall.arguments[4].toString())
+        assertEquals("protoLogParam2", methodCall.arguments[5].toString())
         assertEquals(TRANSFORMED_CODE_MULTILINE_TEXT_ENABLED, out)
     }
 
@@ -289,7 +287,7 @@
         Truth.assertThat(protoLogCalls).hasSize(1)
         val methodCall = protoLogCalls[0] as MethodCallExpr
         assertEquals("w", methodCall.name.asString())
-        assertEquals(5, methodCall.arguments.size)
+        assertEquals(4, methodCall.arguments.size)
         assertEquals("TEST_GROUP", methodCall.arguments[0].toString())
         assertEquals("3218600869538902408L", methodCall.arguments[1].toString())
         assertEquals(0.toString(), methodCall.arguments[2].toString())
@@ -323,13 +321,12 @@
         Truth.assertThat(protoLogCalls).hasSize(1)
         val methodCall = protoLogCalls[0] as MethodCallExpr
         assertEquals("w", methodCall.name.asString())
-        assertEquals(6, methodCall.arguments.size)
+        assertEquals(5, methodCall.arguments.size)
         assertEquals("TEST_GROUP", methodCall.arguments[0].toString())
         assertEquals("-1473209266730422156L", methodCall.arguments[1].toString())
         assertEquals(0b1001.toString(), methodCall.arguments[2].toString())
-        assertEquals("null", methodCall.arguments[3].toString())
-        assertEquals("protoLogParam0", methodCall.arguments[4].toString())
-        assertEquals("protoLogParam1", methodCall.arguments[5].toString())
+        assertEquals("protoLogParam0", methodCall.arguments[3].toString())
+        assertEquals("protoLogParam1", methodCall.arguments[4].toString())
         assertEquals(TRANSFORMED_CODE_TEXT_DISABLED, out)
     }
 
@@ -361,14 +358,13 @@
         Truth.assertThat(protoLogCalls).hasSize(1)
         val methodCall = protoLogCalls[0] as MethodCallExpr
         assertEquals("w", methodCall.name.asString())
-        assertEquals(7, methodCall.arguments.size)
+        assertEquals(6, methodCall.arguments.size)
         assertEquals("TEST_GROUP", methodCall.arguments[0].toString())
         assertEquals("-4447034859795564700L", methodCall.arguments[1].toString())
         assertEquals(0b001001.toString(), methodCall.arguments[2].toString())
-        assertEquals("null", methodCall.arguments[3].toString())
-        assertEquals("protoLogParam0", methodCall.arguments[4].toString())
-        assertEquals("protoLogParam1", methodCall.arguments[5].toString())
-        assertEquals("protoLogParam2", methodCall.arguments[6].toString())
+        assertEquals("protoLogParam0", methodCall.arguments[3].toString())
+        assertEquals("protoLogParam1", methodCall.arguments[4].toString())
+        assertEquals("protoLogParam2", methodCall.arguments[5].toString())
         assertEquals(TRANSFORMED_CODE_MULTILINE_TEXT_DISABLED, out)
     }
 }
diff --git a/wifi/java/src/android/net/wifi/WifiMigration.java b/wifi/java/src/android/net/wifi/WifiMigration.java
index 4fabc0b..1a20a12 100644
--- a/wifi/java/src/android/net/wifi/WifiMigration.java
+++ b/wifi/java/src/android/net/wifi/WifiMigration.java
@@ -19,16 +19,23 @@
 import static android.os.Environment.getDataMiscCeDirectory;
 import static android.os.Environment.getDataMiscDirectory;
 
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.content.Context;
+import android.net.wifi.flags.Flags;
+import android.os.Binder;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.Process;
+import android.os.ServiceSpecificException;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.security.legacykeystore.ILegacyKeystore;
 import android.util.AtomicFile;
+import android.util.Log;
 import android.util.SparseArray;
 
 import java.io.File;
@@ -36,7 +43,11 @@
 import java.io.InputStream;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 /**
  * Class used to provide one time hooks for existing OEM devices to migrate their config store
@@ -45,6 +56,8 @@
  */
 @SystemApi
 public final class WifiMigration {
+    private static final String TAG = "WifiMigration";
+
     /**
      * Directory to read the wifi config store files from under.
      */
@@ -555,4 +568,49 @@
         return data;
 
     }
+
+    /**
+     * Migrate any certificates in Legacy Keystore to the newer WifiBlobstore database.
+     *
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_LEGACY_KEYSTORE_TO_WIFI_BLOBSTORE_MIGRATION)
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static void migrateLegacyKeystoreToWifiBlobstore() {
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            ILegacyKeystore legacyKeystore = WifiBlobStore.getLegacyKeystore();
+            String[] legacyAliases = legacyKeystore.list("", Process.WIFI_UID);
+            if (legacyAliases == null || legacyAliases.length == 0) {
+                Log.i(TAG, "No aliases need to be migrated");
+                return;
+            }
+
+            WifiBlobStore wifiBlobStore = WifiBlobStore.getInstance();
+            List<String> blobstoreAliasList = Arrays.asList(wifiBlobStore.list(""));
+            Set<String> blobstoreAliases = new HashSet<>();
+            blobstoreAliases.addAll(blobstoreAliasList);
+
+            for (String legacyAlias : legacyAliases) {
+                // Only migrate if the alias is not already in WifiBlobstore,
+                // since WifiBlobstore should already contain the latest value.
+                if (!blobstoreAliases.contains(legacyAlias)) {
+                    byte[] value = legacyKeystore.get(legacyAlias, Process.WIFI_UID);
+                    wifiBlobStore.put(legacyAlias, value);
+                }
+                legacyKeystore.remove(legacyAlias, Process.WIFI_UID);
+            }
+            Log.i(TAG, "Successfully migrated aliases from Legacy Keystore");
+        } catch (ServiceSpecificException e) {
+            if (e.errorCode == ILegacyKeystore.ERROR_SYSTEM_ERROR) {
+                Log.i(TAG, "Legacy Keystore service has been deprecated");
+            } else {
+                Log.e(TAG, "Encountered an exception while migrating aliases. " + e);
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "Encountered an exception while migrating aliases. " + e);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
 }
diff --git a/wifi/tests/src/android/net/wifi/WifiMigrationTest.java b/wifi/tests/src/android/net/wifi/WifiMigrationTest.java
new file mode 100644
index 0000000..8a5912f
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/WifiMigrationTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.net.wifi;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.validateMockitoUsage;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
+
+import android.security.legacykeystore.ILegacyKeystore;
+
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoSession;
+
+/**
+ * Unit tests for {@link WifiMigration}.
+ */
+public class WifiMigrationTest {
+    public static final String TEST_ALIAS = "someAliasString";
+    public static final byte[] TEST_VALUE = new byte[]{10, 11, 12};
+
+    @Mock private ILegacyKeystore mLegacyKeystore;
+    @Mock private WifiBlobStore mWifiBlobStore;
+
+    private MockitoSession mSession;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mSession = ExtendedMockito.mockitoSession()
+                .mockStatic(WifiBlobStore.class, withSettings().lenient())
+                .startMocking();
+        when(WifiBlobStore.getLegacyKeystore()).thenReturn(mLegacyKeystore);
+        when(WifiBlobStore.getInstance()).thenReturn(mWifiBlobStore);
+        when(mLegacyKeystore.get(anyString(), anyInt())).thenReturn(TEST_VALUE);
+    }
+
+    @After
+    public void cleanup() {
+        validateMockitoUsage();
+        if (mSession != null) {
+            mSession.finishMocking();
+        }
+    }
+
+    /**
+     * Verify that the Keystore migration method returns immediately if no aliases
+     * are found in Legacy Keystore.
+     */
+    @Test
+    public void testKeystoreMigrationNoLegacyAliases() throws Exception {
+        when(mLegacyKeystore.list(anyString(), anyInt())).thenReturn(new String[0]);
+        WifiMigration.migrateLegacyKeystoreToWifiBlobstore();
+        verify(mLegacyKeystore).list(anyString(), anyInt());
+        verifyNoMoreInteractions(mLegacyKeystore, mWifiBlobStore);
+    }
+
+    /**
+     * Verify that if all aliases in Legacy Keystore are unique to that database,
+     * all aliases are migrated to WifiBlobstore.
+     */
+    @Test
+    public void testKeystoreMigrationUniqueLegacyAliases() throws Exception {
+        String[] legacyAliases = new String[]{TEST_ALIAS + "1", TEST_ALIAS + "2"};
+        String[] blobstoreAliases = new String[0];
+        when(mLegacyKeystore.list(anyString(), anyInt())).thenReturn(legacyAliases);
+        when(mWifiBlobStore.list(anyString())).thenReturn(blobstoreAliases);
+
+        WifiMigration.migrateLegacyKeystoreToWifiBlobstore();
+        verify(mWifiBlobStore, times(legacyAliases.length)).put(anyString(), any(byte[].class));
+    }
+
+    /**
+     * Verify that if some aliases are shared between Legacy Keystore and WifiBlobstore,
+     * only the ones unique to Legacy Keystore are migrated.
+     */
+    @Test
+    public void testKeystoreMigrationDuplicateLegacyAliases() throws Exception {
+        String uniqueLegacyAlias = TEST_ALIAS + "1";
+        String[] blobstoreAliases = new String[]{TEST_ALIAS + "2", TEST_ALIAS + "3"};
+        String[] legacyAliases =
+                new String[]{blobstoreAliases[0], blobstoreAliases[1], uniqueLegacyAlias};
+        when(mLegacyKeystore.list(anyString(), anyInt())).thenReturn(legacyAliases);
+        when(mWifiBlobStore.list(anyString())).thenReturn(blobstoreAliases);
+
+        // Expect that only the unique legacy alias is migrated to the blobstore
+        WifiMigration.migrateLegacyKeystoreToWifiBlobstore();
+        verify(mWifiBlobStore).list(anyString());
+        verify(mWifiBlobStore).put(eq(uniqueLegacyAlias), any(byte[].class));
+        verifyNoMoreInteractions(mWifiBlobStore);
+    }
+}
diff --git a/wifi/wifi.aconfig b/wifi/wifi.aconfig
index c5bc039..c1effe1 100644
--- a/wifi/wifi.aconfig
+++ b/wifi/wifi.aconfig
@@ -17,3 +17,11 @@
     description: "Control the API that allows setting / reading the NetworkProviderInfo's battery charging status"
     bug: "305067231"
 }
+
+flag {
+    name: "legacy_keystore_to_wifi_blobstore_migration"
+    is_exported: true
+    namespace: "wifi"
+    description: "Add API to migrate all values from Legacy Keystore to the new Wifi Blobstore database"
+    bug: "332560152"
+}